aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrobot-piglet <robot-piglet@yandex-team.com>2023-10-03 15:02:38 +0300
committerrobot-piglet <robot-piglet@yandex-team.com>2023-10-03 16:04:35 +0300
commit5478b8f55cc7055a4861c4030e0c401b5c72714c (patch)
tree3d003e5b4c1800297fcc491faffc9a006d174289
parentca778ad9bfb31839b0f05a4995753bc61db648ad (diff)
downloadydb-5478b8f55cc7055a4861c4030e0c401b5c72714c.tar.gz
Intermediate changes
-rw-r--r--.mapping.json1
-rw-r--r--build/external_resources/gdb/resources.json18
-rw-r--r--build/external_resources/yexport/public.resources.json13
-rw-r--r--build/external_resources/ytexec/resources.json7
-rw-r--r--build/platform/python/ymake_python2/resources.json22
-rw-r--r--build/ya.conf.json (renamed from devtools/ya/opensource/ya.conf.json)0
-rw-r--r--contrib/libs/blake2/COPYING117
-rw-r--r--contrib/libs/blake2/README.md14
-rw-r--r--contrib/libs/blake2/include/blake2.h1
-rw-r--r--contrib/libs/blake2/src/blake2-config.h71
-rw-r--r--contrib/libs/blake2/src/blake2-dispatch.c577
-rw-r--r--contrib/libs/blake2/src/blake2-impl.h160
-rw-r--r--contrib/libs/blake2/src/blake2.h182
-rw-r--r--contrib/libs/blake2/src/blake2b-load-sse2.h68
-rw-r--r--contrib/libs/blake2/src/blake2b-load-sse41.h402
-rw-r--r--contrib/libs/blake2/src/blake2b-ref.c386
-rw-r--r--contrib/libs/blake2/src/blake2b-round.h160
-rw-r--r--contrib/libs/blake2/src/blake2b.c443
-rw-r--r--contrib/libs/blake2/src/blake2bp.c274
-rw-r--r--contrib/libs/blake2/src/blake2s-load-sse2.h59
-rw-r--r--contrib/libs/blake2/src/blake2s-load-sse41.h229
-rw-r--r--contrib/libs/blake2/src/blake2s-load-xop.h189
-rw-r--r--contrib/libs/blake2/src/blake2s-ref.c375
-rw-r--r--contrib/libs/blake2/src/blake2s-round.h91
-rw-r--r--contrib/libs/blake2/src/blake2s.c422
-rw-r--r--contrib/libs/blake2/src/blake2sp.c274
-rw-r--r--contrib/libs/blake2/src/config.h157
-rw-r--r--contrib/libs/blake2/ya.make49
-rw-r--r--contrib/libs/libarchive/CONTRIBUTING.md98
-rw-r--r--contrib/libs/libarchive/COPYING65
-rw-r--r--contrib/libs/libarchive/INSTALL35
-rw-r--r--contrib/libs/libarchive/NEWS755
-rw-r--r--contrib/libs/libarchive/README.md244
-rw-r--r--contrib/libs/libarchive/SECURITY.md19
-rw-r--r--contrib/libs/libarchive/config-linux.h1396
-rw-r--r--contrib/libs/libarchive/config-osx.h42
-rw-r--r--contrib/libs/libarchive/config-win.h121
-rw-r--r--contrib/libs/libarchive/config.h9
-rw-r--r--contrib/libs/libarchive/libarchive/archive.h1212
-rw-r--r--contrib/libs/libarchive/libarchive/archive_acl.c2097
-rw-r--r--contrib/libs/libarchive/libarchive/archive_acl_private.h83
-rw-r--r--contrib/libs/libarchive/libarchive/archive_check_magic.c175
-rw-r--r--contrib/libs/libarchive/libarchive/archive_cmdline.c227
-rw-r--r--contrib/libs/libarchive/libarchive/archive_cmdline_private.h47
-rw-r--r--contrib/libs/libarchive/libarchive/archive_cryptor.c534
-rw-r--r--contrib/libs/libarchive/libarchive/archive_cryptor_private.h188
-rw-r--r--contrib/libs/libarchive/libarchive/archive_digest.c1565
-rw-r--r--contrib/libs/libarchive/libarchive/archive_digest_private.h426
-rw-r--r--contrib/libs/libarchive/libarchive/archive_endian.h195
-rw-r--r--contrib/libs/libarchive/libarchive/archive_entry.c2149
-rw-r--r--contrib/libs/libarchive/libarchive/archive_entry.h723
-rw-r--r--contrib/libs/libarchive/libarchive/archive_entry_copy_bhfi.c75
-rw-r--r--contrib/libs/libarchive/libarchive/archive_entry_copy_stat.c83
-rw-r--r--contrib/libs/libarchive/libarchive/archive_entry_link_resolver.c447
-rw-r--r--contrib/libs/libarchive/libarchive/archive_entry_locale.h92
-rw-r--r--contrib/libs/libarchive/libarchive/archive_entry_private.h200
-rw-r--r--contrib/libs/libarchive/libarchive/archive_entry_sparse.c156
-rw-r--r--contrib/libs/libarchive/libarchive/archive_entry_stat.c118
-rw-r--r--contrib/libs/libarchive/libarchive/archive_entry_strmode.c87
-rw-r--r--contrib/libs/libarchive/libarchive/archive_entry_xattr.c156
-rw-r--r--contrib/libs/libarchive/libarchive/archive_getdate.c1104
-rw-r--r--contrib/libs/libarchive/libarchive/archive_getdate.h39
-rw-r--r--contrib/libs/libarchive/libarchive/archive_hmac.c339
-rw-r--r--contrib/libs/libarchive/libarchive/archive_hmac_private.h119
-rw-r--r--contrib/libs/libarchive/libarchive/archive_match.c1875
-rw-r--r--contrib/libs/libarchive/libarchive/archive_openssl_evp_private.h54
-rw-r--r--contrib/libs/libarchive/libarchive/archive_openssl_hmac_private.h54
-rw-r--r--contrib/libs/libarchive/libarchive/archive_options.c218
-rw-r--r--contrib/libs/libarchive/libarchive/archive_options_private.h51
-rw-r--r--contrib/libs/libarchive/libarchive/archive_pack_dev.c337
-rw-r--r--contrib/libs/libarchive/libarchive/archive_pack_dev.h49
-rw-r--r--contrib/libs/libarchive/libarchive/archive_pathmatch.c463
-rw-r--r--contrib/libs/libarchive/libarchive/archive_pathmatch.h52
-rw-r--r--contrib/libs/libarchive/libarchive/archive_platform.h233
-rw-r--r--contrib/libs/libarchive/libarchive/archive_platform_acl.h55
-rw-r--r--contrib/libs/libarchive/libarchive/archive_ppmd7.c1168
-rw-r--r--contrib/libs/libarchive/libarchive/archive_ppmd7_private.h119
-rw-r--r--contrib/libs/libarchive/libarchive/archive_ppmd8.c1287
-rw-r--r--contrib/libs/libarchive/libarchive/archive_ppmd8_private.h148
-rw-r--r--contrib/libs/libarchive/libarchive/archive_ppmd_private.h151
-rw-r--r--contrib/libs/libarchive/libarchive/archive_private.h180
-rw-r--r--contrib/libs/libarchive/libarchive/archive_random.c301
-rw-r--r--contrib/libs/libarchive/libarchive/archive_random_private.h36
-rw-r--r--contrib/libs/libarchive/libarchive/archive_rb.c709
-rw-r--r--contrib/libs/libarchive/libarchive/archive_rb.h113
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read.c1756
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_add_passphrase.c190
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_append_filter.c204
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_data_into_fd.c144
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_disk_entry_from_file.c1086
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_disk_posix.c2760
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_disk_private.h98
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_disk_set_standard_lookup.c313
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_disk_windows.c2547
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_extract.c60
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_extract2.c155
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_open_fd.c211
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_open_file.c180
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_open_filename.c586
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_open_memory.c186
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_private.h267
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_set_format.c117
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_set_options.c133
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_filter_all.c85
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_filter_by_code.c83
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_filter_bzip2.c365
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_filter_compress.c452
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_filter_grzip.c112
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_filter_gzip.c536
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_filter_lrzip.c122
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_filter_lz4.c742
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_filter_lzop.c499
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_filter_none.c52
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_filter_program.c496
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_filter_rpm.c287
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_filter_uu.c683
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_filter_xz.c793
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_filter_zstd.c297
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_format_7zip.c4074
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_format_all.c89
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_format_ar.c638
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_format_by_code.c92
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_format_cab.c3228
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_format_cpio.c1104
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_format_empty.c96
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_format_iso9660.c3279
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_format_lha.c2919
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_format_mtree.c2156
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_format_rar.c3788
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_format_rar5.c4251
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_format_raw.c192
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_format_tar.c2946
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_format_warc.c848
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_format_xar.c3332
-rw-r--r--contrib/libs/libarchive/libarchive/archive_read_support_format_zip.c4270
-rw-r--r--contrib/libs/libarchive/libarchive/archive_string.c4244
-rw-r--r--contrib/libs/libarchive/libarchive/archive_string.h243
-rw-r--r--contrib/libs/libarchive/libarchive/archive_string_composition.h2292
-rw-r--r--contrib/libs/libarchive/libarchive/archive_string_sprintf.c192
-rw-r--r--contrib/libs/libarchive/libarchive/archive_util.c704
-rw-r--r--contrib/libs/libarchive/libarchive/archive_version_details.c151
-rw-r--r--contrib/libs/libarchive/libarchive/archive_virtual.c163
-rw-r--r--contrib/libs/libarchive/libarchive/archive_windows.c938
-rw-r--r--contrib/libs/libarchive/libarchive/archive_windows.h315
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write.c859
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_add_filter.c72
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_add_filter_b64encode.c304
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_add_filter_by_name.c77
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_add_filter_bzip2.c401
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_add_filter_compress.c447
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_add_filter_grzip.c135
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_add_filter_gzip.c442
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_add_filter_lrzip.c197
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_add_filter_lz4.c700
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_add_filter_lzop.c478
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_add_filter_none.c43
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_add_filter_program.c391
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_add_filter_uuencode.c295
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_add_filter_xz.c545
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_add_filter_zstd.c467
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_disk_posix.c4759
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_disk_private.h45
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_disk_set_standard_lookup.c263
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_disk_windows.c2911
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_open_fd.c146
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_open_file.c111
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_open_filename.c270
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_open_memory.c115
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_private.h166
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_format.c125
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_format_7zip.c2322
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_format_ar.c570
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_format_by_name.c94
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_format_cpio.c11
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_format_cpio_binary.c610
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_format_cpio_newc.c457
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_format_cpio_odc.c500
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_format_filter_by_ext.c142
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_format_gnutar.c755
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_format_iso9660.c8161
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_format_mtree.c2217
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_format_pax.c2063
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_format_private.h42
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_format_raw.c125
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_format_shar.c641
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_format_ustar.c758
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_format_v7tar.c638
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_format_warc.c444
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_format_xar.c3255
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_format_zip.c1693
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_options.c130
-rw-r--r--contrib/libs/libarchive/libarchive/archive_write_set_passphrase.c95
-rw-r--r--contrib/libs/libarchive/libarchive/archive_xxhash.h48
-rw-r--r--contrib/libs/libarchive/libarchive/filter_fork.h46
-rw-r--r--contrib/libs/libarchive/libarchive/filter_fork_posix.c240
-rw-r--r--contrib/libs/libarchive/libarchive/filter_fork_windows.c245
-rw-r--r--contrib/libs/libarchive/libarchive/xxhash.c529
-rw-r--r--contrib/libs/libarchive/ya.make183
-rw-r--r--contrib/libs/linux-headers/linux/fiemap.h70
-rw-r--r--contrib/libs/pcre2/AUTHORS36
-rw-r--r--contrib/libs/pcre2/COPYING5
-rw-r--r--contrib/libs/pcre2/ChangeLog2827
-rw-r--r--contrib/libs/pcre2/INSTALL368
-rw-r--r--contrib/libs/pcre2/NEWS436
-rw-r--r--contrib/libs/pcre2/README924
-rw-r--r--contrib/libs/pcre2/README.md56
-rw-r--r--contrib/libs/pcre2/pcre2.h993
-rw-r--r--contrib/libs/pcre2/src/pcre2_auto_possess.c1365
-rw-r--r--contrib/libs/pcre2/src/pcre2_chartables.c202
-rw-r--r--contrib/libs/pcre2/src/pcre2_compile.c10631
-rw-r--r--contrib/libs/pcre2/src/pcre2_config.c252
-rw-r--r--contrib/libs/pcre2/src/pcre2_config.h446
-rw-r--r--contrib/libs/pcre2/src/pcre2_context.c494
-rw-r--r--contrib/libs/pcre2/src/pcre2_convert.c1181
-rw-r--r--contrib/libs/pcre2/src/pcre2_dfa_match.c4066
-rw-r--r--contrib/libs/pcre2/src/pcre2_error.c341
-rw-r--r--contrib/libs/pcre2/src/pcre2_extuni.c148
-rw-r--r--contrib/libs/pcre2/src/pcre2_find_bracket.c219
-rw-r--r--contrib/libs/pcre2/src/pcre2_internal.h2047
-rw-r--r--contrib/libs/pcre2/src/pcre2_intmodedep.h934
-rw-r--r--contrib/libs/pcre2/src/pcre2_jit_compile.c14507
-rw-r--r--contrib/libs/pcre2/src/pcre2_jit_match.c186
-rw-r--r--contrib/libs/pcre2/src/pcre2_jit_misc.c234
-rw-r--r--contrib/libs/pcre2/src/pcre2_jit_simd_inc.h1858
-rw-r--r--contrib/libs/pcre2/src/pcre2_maketables.c163
-rw-r--r--contrib/libs/pcre2/src/pcre2_match.c7544
-rw-r--r--contrib/libs/pcre2/src/pcre2_match_data.c173
-rw-r--r--contrib/libs/pcre2/src/pcre2_newline.c243
-rw-r--r--contrib/libs/pcre2/src/pcre2_ord2utf.c120
-rw-r--r--contrib/libs/pcre2/src/pcre2_pattern_info.c432
-rw-r--r--contrib/libs/pcre2/src/pcre2_script_run.c344
-rw-r--r--contrib/libs/pcre2/src/pcre2_serialize.c286
-rw-r--r--contrib/libs/pcre2/src/pcre2_string_utils.c237
-rw-r--r--contrib/libs/pcre2/src/pcre2_study.c1825
-rw-r--r--contrib/libs/pcre2/src/pcre2_substitute.c1009
-rw-r--r--contrib/libs/pcre2/src/pcre2_substring.c547
-rw-r--r--contrib/libs/pcre2/src/pcre2_tables.c234
-rw-r--r--contrib/libs/pcre2/src/pcre2_ucd.c5396
-rw-r--r--contrib/libs/pcre2/src/pcre2_ucp.h394
-rw-r--r--contrib/libs/pcre2/src/pcre2_ucptables.c1524
-rw-r--r--contrib/libs/pcre2/src/pcre2_valid_utf.c398
-rw-r--r--contrib/libs/pcre2/src/pcre2_xclass.c289
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitConfig.h162
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitConfigInternal.h851
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitExecAllocator.c411
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitLir.c3136
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitLir.h1823
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitNativeARM_32.c3700
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitNativeARM_64.c2417
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitNativeARM_T2_32.c3150
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitNativeMIPS_32.c314
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitNativeMIPS_64.c319
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitNativeMIPS_common.c3720
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitNativePPC_32.c340
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitNativePPC_64.c579
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitNativePPC_common.c2851
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitNativeRISCV_32.c73
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitNativeRISCV_64.c183
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitNativeRISCV_common.c2762
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitNativeS390X.c3747
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitNativeX86_32.c1298
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitNativeX86_64.c1092
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitNativeX86_common.c3422
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitProtExecAllocator.c474
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitUtils.c344
-rw-r--r--contrib/libs/pcre2/src/sljit/sljitWXExecAllocator.c204
-rw-r--r--contrib/libs/pcre2/ya.make70
-rw-r--r--contrib/python/distro/py2/.dist-info/METADATA169
-rw-r--r--contrib/python/distro/py2/.dist-info/entry_points.txt3
-rw-r--r--contrib/python/distro/py2/.dist-info/top_level.txt1
-rw-r--r--contrib/python/distro/py2/LICENSE202
-rw-r--r--contrib/python/distro/py2/README.md135
-rw-r--r--contrib/python/distro/py2/distro.py1386
-rw-r--r--contrib/python/distro/py2/ya.make31
-rw-r--r--contrib/python/distro/py3/LICENSE202
-rw-r--r--contrib/python/distro/py3/README.md152
-rw-r--r--contrib/python/distro/ya.make18
-rw-r--r--contrib/python/portalocker/py2/.dist-info/METADATA136
-rw-r--r--contrib/python/portalocker/py2/.dist-info/top_level.txt1
-rw-r--r--contrib/python/portalocker/py2/LICENSE48
-rw-r--r--contrib/python/portalocker/py2/README.rst106
-rw-r--r--contrib/python/portalocker/py2/portalocker/__about__.py7
-rw-r--r--contrib/python/portalocker/py2/portalocker/__init__.py67
-rw-r--r--contrib/python/portalocker/py2/portalocker/constants.py39
-rw-r--r--contrib/python/portalocker/py2/portalocker/exceptions.py19
-rw-r--r--contrib/python/portalocker/py2/portalocker/portalocker.py148
-rw-r--r--contrib/python/portalocker/py2/portalocker/utils.py256
-rw-r--r--contrib/python/portalocker/py2/ya.make31
-rw-r--r--contrib/python/portalocker/py3/LICENSE11
-rw-r--r--contrib/python/portalocker/py3/README.rst193
-rw-r--r--contrib/python/portalocker/ya.make18
-rw-r--r--contrib/python/python-libarchive/libarchive/__init__.py800
-rw-r--r--contrib/python/python-libarchive/libarchive/_libarchive.swg339
-rw-r--r--contrib/python/python-libarchive/libarchive/tar.py135
-rw-r--r--contrib/python/python-libarchive/libarchive/zip.py151
-rw-r--r--contrib/python/python-libarchive/ya.make28
-rw-r--r--contrib/python/simplejson/.dist-info/METADATA68
-rw-r--r--contrib/python/simplejson/.dist-info/top_level.txt1
-rw-r--r--contrib/python/simplejson/LICENSE.txt79
-rw-r--r--contrib/python/simplejson/README.rst34
-rw-r--r--contrib/python/simplejson/simplejson/__init__.py584
-rw-r--r--contrib/python/simplejson/simplejson/_speedups.c3402
-rw-r--r--contrib/python/simplejson/simplejson/compat.py34
-rw-r--r--contrib/python/simplejson/simplejson/decoder.py402
-rw-r--r--contrib/python/simplejson/simplejson/encoder.py740
-rw-r--r--contrib/python/simplejson/simplejson/errors.py53
-rw-r--r--contrib/python/simplejson/simplejson/ordered_dict.py103
-rw-r--r--contrib/python/simplejson/simplejson/raw_json.py9
-rw-r--r--contrib/python/simplejson/simplejson/scanner.py85
-rw-r--r--contrib/python/simplejson/simplejson/tool.py42
-rw-r--r--contrib/python/simplejson/ya.make48
-rw-r--r--contrib/python/toolz/py2/.dist-info/METADATA159
-rw-r--r--contrib/python/toolz/py2/.dist-info/top_level.txt2
-rw-r--r--contrib/python/toolz/py2/LICENSE.txt28
-rw-r--r--contrib/python/toolz/py2/README.rst132
-rw-r--r--contrib/python/toolz/py2/tlz/__init__.py9
-rw-r--r--contrib/python/toolz/py2/tlz/_build_tlz.py100
-rw-r--r--contrib/python/toolz/py2/toolz/__init__.py22
-rw-r--r--contrib/python/toolz/py2/toolz/_signatures.py832
-rw-r--r--contrib/python/toolz/py2/toolz/compatibility.py34
-rw-r--r--contrib/python/toolz/py2/toolz/curried/__init__.py103
-rw-r--r--contrib/python/toolz/py2/toolz/curried/exceptions.py18
-rw-r--r--contrib/python/toolz/py2/toolz/curried/operator.py23
-rw-r--r--contrib/python/toolz/py2/toolz/dicttoolz.py337
-rw-r--r--contrib/python/toolz/py2/toolz/functoolz.py1152
-rw-r--r--contrib/python/toolz/py2/toolz/itertoolz.py1056
-rw-r--r--contrib/python/toolz/py2/toolz/recipes.py47
-rw-r--r--contrib/python/toolz/py2/toolz/sandbox/__init__.py2
-rw-r--r--contrib/python/toolz/py2/toolz/sandbox/core.py133
-rw-r--r--contrib/python/toolz/py2/toolz/sandbox/parallel.py76
-rw-r--r--contrib/python/toolz/py2/toolz/utils.py9
-rw-r--r--contrib/python/toolz/py2/ya.make41
-rw-r--r--contrib/python/toolz/py3/AUTHORS.md33
-rw-r--r--contrib/python/toolz/py3/LICENSE.txt28
-rw-r--r--contrib/python/toolz/py3/README.rst132
-rw-r--r--contrib/python/toolz/ya.make18
-rw-r--r--contrib/python/ujson/py2/lib/ultrajson.h333
-rw-r--r--contrib/python/ujson/py2/lib/ultrajsondec.c907
-rw-r--r--contrib/python/ujson/py2/lib/ultrajsonenc.c1029
-rw-r--r--contrib/python/ujson/py2/python/JSONtoObj.c252
-rw-r--r--contrib/python/ujson/py2/python/objToJSON.c1168
-rw-r--r--contrib/python/ujson/py2/python/py_defines.h53
-rw-r--r--contrib/python/ujson/py2/python/ujson.c113
-rw-r--r--contrib/python/ujson/py2/python/version.h39
-rw-r--r--contrib/python/ujson/py2/ya.make30
-rw-r--r--contrib/python/ujson/ya.make18
-rw-r--r--contrib/tools/swig/CHANGES27992
-rw-r--r--contrib/tools/swig/CHANGES.current79
-rw-r--r--contrib/tools/swig/COPYRIGHT113
-rw-r--r--contrib/tools/swig/INSTALL226
-rw-r--r--contrib/tools/swig/LICENSE22
-rw-r--r--contrib/tools/swig/LICENSE-GPL674
-rw-r--r--contrib/tools/swig/LICENSE-UNIVERSITIES95
-rw-r--r--contrib/tools/swig/Lib/go/go.swg744
-rw-r--r--contrib/tools/swig/Lib/go/gokw.swg33
-rw-r--r--contrib/tools/swig/Lib/go/goruntime.swg217
-rw-r--r--contrib/tools/swig/Lib/go/gostring.swg29
-rw-r--r--contrib/tools/swig/Lib/go/typemaps.i298
-rw-r--r--contrib/tools/swig/Lib/java/enumtypesafe.swg117
-rw-r--r--contrib/tools/swig/Lib/java/java.swg1458
-rw-r--r--contrib/tools/swig/Lib/java/javahead.swg91
-rw-r--r--contrib/tools/swig/Lib/java/javakw.swg70
-rw-r--r--contrib/tools/swig/Lib/java/typemaps.i529
-rw-r--r--contrib/tools/swig/Lib/perl5/extra-install.list2
-rw-r--r--contrib/tools/swig/Lib/perl5/perl5.swg42
-rw-r--r--contrib/tools/swig/Lib/perl5/perlfragments.swg23
-rw-r--r--contrib/tools/swig/Lib/perl5/perlinit.swg78
-rw-r--r--contrib/tools/swig/Lib/perl5/perlkw.swg251
-rw-r--r--contrib/tools/swig/Lib/perl5/perlmacros.swg2
-rw-r--r--contrib/tools/swig/Lib/perl5/perlopers.swg54
-rw-r--r--contrib/tools/swig/Lib/perl5/perlprimtypes.swg364
-rw-r--r--contrib/tools/swig/Lib/perl5/perlruntime.swg8
-rw-r--r--contrib/tools/swig/Lib/perl5/perlstrings.swg59
-rw-r--r--contrib/tools/swig/Lib/perl5/perltypemaps.swg104
-rw-r--r--contrib/tools/swig/Lib/perl5/perluserdir.swg2
-rw-r--r--contrib/tools/swig/Lib/perl5/reference.i261
-rw-r--r--contrib/tools/swig/Lib/perl5/typemaps.i371
-rw-r--r--contrib/tools/swig/Lib/python/README103
-rw-r--r--contrib/tools/swig/Lib/python/builtin.swg764
-rw-r--r--contrib/tools/swig/Lib/python/pyapi.swg30
-rw-r--r--contrib/tools/swig/Lib/python/pybackward.swg45
-rw-r--r--contrib/tools/swig/Lib/python/pyclasses.swg157
-rw-r--r--contrib/tools/swig/Lib/python/pydocs.swg45
-rw-r--r--contrib/tools/swig/Lib/python/pyerrors.swg107
-rw-r--r--contrib/tools/swig/Lib/python/pyfragments.swg23
-rw-r--r--contrib/tools/swig/Lib/python/pyhead.swg75
-rw-r--r--contrib/tools/swig/Lib/python/pyinit.swg325
-rw-r--r--contrib/tools/swig/Lib/python/pymacros.swg4
-rw-r--r--contrib/tools/swig/Lib/python/pyopers.swg264
-rw-r--r--contrib/tools/swig/Lib/python/pyprimtypes.swg353
-rw-r--r--contrib/tools/swig/Lib/python/pyrun.swg1913
-rw-r--r--contrib/tools/swig/Lib/python/pyruntime.swg49
-rw-r--r--contrib/tools/swig/Lib/python/pystrings.swg139
-rw-r--r--contrib/tools/swig/Lib/python/python.swg59
-rw-r--r--contrib/tools/swig/Lib/python/pythonkw.swg140
-rw-r--r--contrib/tools/swig/Lib/python/pythreads.swg68
-rw-r--r--contrib/tools/swig/Lib/python/pytypemaps.swg105
-rw-r--r--contrib/tools/swig/Lib/python/pyuserdir.swg242
-rw-r--r--contrib/tools/swig/Lib/python/typemaps.i148
-rw-r--r--contrib/tools/swig/Lib/python/ya.make22
-rw-r--r--contrib/tools/swig/Lib/std/README22
-rw-r--r--contrib/tools/swig/Lib/swig.swg729
-rw-r--r--contrib/tools/swig/Lib/swigerrors.swg15
-rw-r--r--contrib/tools/swig/Lib/swigfragments.swg90
-rw-r--r--contrib/tools/swig/Lib/swiginit.swg233
-rw-r--r--contrib/tools/swig/Lib/swiglabels.swg123
-rw-r--r--contrib/tools/swig/Lib/swigrun.swg581
-rw-r--r--contrib/tools/swig/Lib/swigwarn.swg300
-rw-r--r--contrib/tools/swig/Lib/swigwarnings.swg131
-rw-r--r--contrib/tools/swig/Lib/typemaps/README54
-rw-r--r--contrib/tools/swig/Lib/typemaps/enumint.swg39
-rw-r--r--contrib/tools/swig/Lib/typemaps/exception.swg87
-rw-r--r--contrib/tools/swig/Lib/typemaps/fragments.swg231
-rw-r--r--contrib/tools/swig/Lib/typemaps/inoutlist.swg296
-rw-r--r--contrib/tools/swig/Lib/typemaps/misctypes.swg21
-rw-r--r--contrib/tools/swig/Lib/typemaps/primtypes.swg367
-rw-r--r--contrib/tools/swig/Lib/typemaps/ptrtypes.swg208
-rw-r--r--contrib/tools/swig/Lib/typemaps/string.swg36
-rw-r--r--contrib/tools/swig/Lib/typemaps/strings.swg658
-rw-r--r--contrib/tools/swig/Lib/typemaps/swigmacros.swg228
-rw-r--r--contrib/tools/swig/Lib/typemaps/swigobject.swg37
-rw-r--r--contrib/tools/swig/Lib/typemaps/swigtype.swg710
-rw-r--r--contrib/tools/swig/Lib/typemaps/swigtypemaps.swg168
-rw-r--r--contrib/tools/swig/Lib/typemaps/typemaps.swg157
-rw-r--r--contrib/tools/swig/Lib/typemaps/valtypes.swg215
-rw-r--r--contrib/tools/swig/Lib/typemaps/void.swg84
-rw-r--r--contrib/tools/swig/README139
-rw-r--r--contrib/tools/swig/RELEASENOTES494
-rw-r--r--contrib/tools/swig/Source/CParse/cparse.h85
-rw-r--r--contrib/tools/swig/Source/CParse/cscanner.c1088
-rw-r--r--contrib/tools/swig/Source/CParse/parser.y7499
-rw-r--r--contrib/tools/swig/Source/CParse/templ.c976
-rw-r--r--contrib/tools/swig/Source/CParse/util.c126
-rw-r--r--contrib/tools/swig/Source/DOH/README124
-rw-r--r--contrib/tools/swig/Source/DOH/base.c937
-rw-r--r--contrib/tools/swig/Source/DOH/doh.h507
-rw-r--r--contrib/tools/swig/Source/DOH/dohint.h131
-rw-r--r--contrib/tools/swig/Source/DOH/file.c342
-rw-r--r--contrib/tools/swig/Source/DOH/fio.c599
-rw-r--r--contrib/tools/swig/Source/DOH/hash.c583
-rw-r--r--contrib/tools/swig/Source/DOH/list.c371
-rw-r--r--contrib/tools/swig/Source/DOH/memory.c292
-rw-r--r--contrib/tools/swig/Source/DOH/string.c1286
-rw-r--r--contrib/tools/swig/Source/DOH/void.c96
-rw-r--r--contrib/tools/swig/Source/Doxygen/doxycommands.h174
-rw-r--r--contrib/tools/swig/Source/Doxygen/doxyentity.cxx69
-rw-r--r--contrib/tools/swig/Source/Doxygen/doxyentity.h45
-rw-r--r--contrib/tools/swig/Source/Doxygen/doxyparser.cxx1494
-rw-r--r--contrib/tools/swig/Source/Doxygen/doxyparser.h377
-rw-r--r--contrib/tools/swig/Source/Doxygen/doxytranslator.cxx69
-rw-r--r--contrib/tools/swig/Source/Doxygen/doxytranslator.h90
-rw-r--r--contrib/tools/swig/Source/Doxygen/javadoc.cxx849
-rw-r--r--contrib/tools/swig/Source/Doxygen/javadoc.h169
-rw-r--r--contrib/tools/swig/Source/Doxygen/pydoc.cxx993
-rw-r--r--contrib/tools/swig/Source/Doxygen/pydoc.h208
-rw-r--r--contrib/tools/swig/Source/Include/swigconfig.h105
-rw-r--r--contrib/tools/swig/Source/Include/swigwarn.h327
-rw-r--r--contrib/tools/swig/Source/Modules/README9
-rw-r--r--contrib/tools/swig/Source/Modules/allocate.cxx971
-rw-r--r--contrib/tools/swig/Source/Modules/contract.cxx358
-rw-r--r--contrib/tools/swig/Source/Modules/csharp.cxx4616
-rw-r--r--contrib/tools/swig/Source/Modules/d.cxx4649
-rw-r--r--contrib/tools/swig/Source/Modules/directors.cxx270
-rw-r--r--contrib/tools/swig/Source/Modules/emit.cxx556
-rw-r--r--contrib/tools/swig/Source/Modules/go.cxx5708
-rw-r--r--contrib/tools/swig/Source/Modules/guile.cxx1662
-rw-r--r--contrib/tools/swig/Source/Modules/interface.cxx210
-rw-r--r--contrib/tools/swig/Source/Modules/java.cxx4979
-rw-r--r--contrib/tools/swig/Source/Modules/javascript.cxx2490
-rw-r--r--contrib/tools/swig/Source/Modules/lang.cxx3902
-rw-r--r--contrib/tools/swig/Source/Modules/lua.cxx2240
-rw-r--r--contrib/tools/swig/Source/Modules/main.cxx1407
-rw-r--r--contrib/tools/swig/Source/Modules/mzscheme.cxx802
-rw-r--r--contrib/tools/swig/Source/Modules/nested.cxx453
-rw-r--r--contrib/tools/swig/Source/Modules/ocaml.cxx1848
-rw-r--r--contrib/tools/swig/Source/Modules/octave.cxx1572
-rw-r--r--contrib/tools/swig/Source/Modules/overload.cxx866
-rw-r--r--contrib/tools/swig/Source/Modules/perl5.cxx2502
-rw-r--r--contrib/tools/swig/Source/Modules/php.cxx2702
-rw-r--r--contrib/tools/swig/Source/Modules/python.cxx5768
-rw-r--r--contrib/tools/swig/Source/Modules/r.cxx2889
-rw-r--r--contrib/tools/swig/Source/Modules/ruby.cxx3470
-rw-r--r--contrib/tools/swig/Source/Modules/scilab.cxx1167
-rw-r--r--contrib/tools/swig/Source/Modules/swigmain.cxx265
-rw-r--r--contrib/tools/swig/Source/Modules/swigmod.h463
-rw-r--r--contrib/tools/swig/Source/Modules/tcl8.cxx1291
-rw-r--r--contrib/tools/swig/Source/Modules/typepass.cxx1322
-rw-r--r--contrib/tools/swig/Source/Modules/utils.cxx218
-rw-r--r--contrib/tools/swig/Source/Modules/xml.cxx326
-rw-r--r--contrib/tools/swig/Source/Preprocessor/cpp.c2111
-rw-r--r--contrib/tools/swig/Source/Preprocessor/expr.c496
-rw-r--r--contrib/tools/swig/Source/Preprocessor/preprocessor.h40
-rw-r--r--contrib/tools/swig/Source/README15
-rw-r--r--contrib/tools/swig/Source/Swig/cwrap.c1661
-rw-r--r--contrib/tools/swig/Source/Swig/deprecate.c107
-rw-r--r--contrib/tools/swig/Source/Swig/error.c351
-rw-r--r--contrib/tools/swig/Source/Swig/extend.c141
-rw-r--r--contrib/tools/swig/Source/Swig/fragment.c188
-rw-r--r--contrib/tools/swig/Source/Swig/getopt.c104
-rw-r--r--contrib/tools/swig/Source/Swig/include.c377
-rw-r--r--contrib/tools/swig/Source/Swig/misc.c1569
-rw-r--r--contrib/tools/swig/Source/Swig/naming.c1771
-rw-r--r--contrib/tools/swig/Source/Swig/parms.c272
-rw-r--r--contrib/tools/swig/Source/Swig/scanner.c1898
-rw-r--r--contrib/tools/swig/Source/Swig/stype.c1422
-rw-r--r--contrib/tools/swig/Source/Swig/swig.h451
-rw-r--r--contrib/tools/swig/Source/Swig/swigfile.h41
-rw-r--r--contrib/tools/swig/Source/Swig/swigopt.h18
-rw-r--r--contrib/tools/swig/Source/Swig/swigparm.h35
-rw-r--r--contrib/tools/swig/Source/Swig/swigscan.h119
-rw-r--r--contrib/tools/swig/Source/Swig/swigtree.h54
-rw-r--r--contrib/tools/swig/Source/Swig/swigwrap.h31
-rw-r--r--contrib/tools/swig/Source/Swig/symbol.c2128
-rw-r--r--contrib/tools/swig/Source/Swig/tree.c426
-rw-r--r--contrib/tools/swig/Source/Swig/typemap.c2210
-rw-r--r--contrib/tools/swig/Source/Swig/typeobj.c1367
-rw-r--r--contrib/tools/swig/Source/Swig/typesys.c2309
-rw-r--r--contrib/tools/swig/Source/Swig/wrapfunc.c520
-rw-r--r--contrib/tools/swig/swig_lib.cpp28
-rw-r--r--contrib/tools/swig/ya.make120
-rw-r--r--library/cpp/pybind/attr.h412
-rw-r--r--library/cpp/pybind/cast.cpp324
-rw-r--r--library/cpp/pybind/cast.h373
-rw-r--r--library/cpp/pybind/embedding.cpp63
-rw-r--r--library/cpp/pybind/embedding.h10
-rw-r--r--library/cpp/pybind/empty.cpp2
-rw-r--r--library/cpp/pybind/exceptions.cpp147
-rw-r--r--library/cpp/pybind/exceptions.h143
-rw-r--r--library/cpp/pybind/init.h25
-rw-r--r--library/cpp/pybind/method.h439
-rw-r--r--library/cpp/pybind/module.cpp72
-rw-r--r--library/cpp/pybind/module.h176
-rw-r--r--library/cpp/pybind/pod.cpp18
-rw-r--r--library/cpp/pybind/pod.h53
-rw-r--r--library/cpp/pybind/ptr.h51
-rw-r--r--library/cpp/pybind/typeattrs.h368
-rw-r--r--library/cpp/pybind/typedesc.cpp79
-rw-r--r--library/cpp/pybind/typedesc.h545
-rw-r--r--library/cpp/pybind/v2.cpp43
-rw-r--r--library/cpp/pybind/v2.h514
-rw-r--r--library/cpp/pybind/ya.make14
-rw-r--r--library/python/archive/__init__.py266
-rw-r--r--library/python/archive/ya.make19
-rw-r--r--library/python/cityhash/cityhash.pyx75
-rw-r--r--library/python/cityhash/hash.cpp32
-rw-r--r--library/python/cityhash/hash.h6
-rw-r--r--library/python/cityhash/ya.make16
-rw-r--r--library/python/codecs/__codecs.pyx61
-rw-r--r--library/python/codecs/__init__.py1
-rw-r--r--library/python/codecs/ya.make16
-rw-r--r--library/python/compress/__init__.py147
-rw-r--r--library/python/compress/ya.make16
-rw-r--r--library/python/json/__init__.py44
-rw-r--r--library/python/json/loads.cpp246
-rw-r--r--library/python/json/loads.h5
-rw-r--r--library/python/json/loads.pyx14
-rw-r--r--library/python/json/ya.make17
-rw-r--r--library/python/par_apply/__init__.py114
-rw-r--r--library/python/par_apply/ya.make11
-rw-r--r--library/python/retry/__init__.py250
-rw-r--r--library/python/retry/ya.make11
-rw-r--r--library/python/testing/yatest_common/ut/test.py17
-rw-r--r--library/python/testing/yatest_common/ut/ya.make17
-rw-r--r--library/python/testing/yatest_common/ya.make4
564 files changed, 1 insertions, 410821 deletions
diff --git a/.mapping.json b/.mapping.json
index 7c0ee71c47..bcd78fb563 100644
--- a/.mapping.json
+++ b/.mapping.json
@@ -54,6 +54,7 @@
"build/scripts/export_script_gen.py":"",
"build/scripts/generate_vcs_info.py":"",
"build/scripts/split_unittest.py":"",
+ "build/ya.conf.json":"devtools/ya/opensource/ya.conf.json",
"certs/CMakeLists.darwin-x86_64.txt":"",
"certs/CMakeLists.linux-aarch64.txt":"",
"certs/CMakeLists.linux-x86_64.txt":"",
diff --git a/build/external_resources/gdb/resources.json b/build/external_resources/gdb/resources.json
deleted file mode 100644
index ea5ab20b7e..0000000000
--- a/build/external_resources/gdb/resources.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "by_platform": {
- "darwin-x86_64": {
- "uri": "sbr:3833498694"
- },
- "darwin-arm64": {
- "uri": "sbr:2319130389"
- },
- "linux-x86_64": {
- "uri": "sbr:4940633745"
- },
- "linux-aarch64": {
- "uri": "sbr:4940640829"
- }
- },
- "platform_replacements": {},
- "match": "GDB"
-}
diff --git a/build/external_resources/yexport/public.resources.json b/build/external_resources/yexport/public.resources.json
deleted file mode 100644
index b9e118e88d..0000000000
--- a/build/external_resources/yexport/public.resources.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "by_platform": {
- "darwin": {
- "uri": "sbr:5111996178"
- },
- "darwin-arm64": {
- "uri": "sbr:5111987261"
- },
- "linux": {
- "uri": "sbr:5111998098"
- }
- }
-}
diff --git a/build/external_resources/ytexec/resources.json b/build/external_resources/ytexec/resources.json
deleted file mode 100644
index 115c1cbf9b..0000000000
--- a/build/external_resources/ytexec/resources.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "by_platform": {
- "linux-x86_64": {
- "uri": "sbr:2980468199"
- }
- }
-}
diff --git a/build/platform/python/ymake_python2/resources.json b/build/platform/python/ymake_python2/resources.json
deleted file mode 100644
index 880a39a053..0000000000
--- a/build/platform/python/ymake_python2/resources.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "by_platform": {
- "darwin-arm64": {
- "uri": "sbr:2989596911"
- },
- "darwin-x86_64": {
- "uri": "sbr:2989597929"
- },
- "linux-x86_64": {
- "uri": "sbr:2989598506"
- },
- "linux-ppc64le": {
- "uri": "sbr:2989596149"
- },
- "win32-x86_64": {
- "uri": "sbr:2989597467"
- },
- "linux-aarch64": {
- "uri": "sbr:3864777619"
- }
- }
-}
diff --git a/devtools/ya/opensource/ya.conf.json b/build/ya.conf.json
index 0b8b28b91f..0b8b28b91f 100644
--- a/devtools/ya/opensource/ya.conf.json
+++ b/build/ya.conf.json
diff --git a/contrib/libs/blake2/COPYING b/contrib/libs/blake2/COPYING
deleted file mode 100644
index 2c4afabdb6..0000000000
--- a/contrib/libs/blake2/COPYING
+++ /dev/null
@@ -1,117 +0,0 @@
-CC0 1.0 Universal
-
-Statement of Purpose
-
-The laws of most jurisdictions throughout the world automatically confer
-exclusive Copyright and Related Rights (defined below) upon the creator and
-subsequent owner(s) (each and all, an "owner") of an original work of
-authorship and/or a database (each, a "Work").
-
-Certain owners wish to permanently relinquish those rights to a Work for the
-purpose of contributing to a commons of creative, cultural and scientific
-works ("Commons") that the public can reliably and without fear of later
-claims of infringement build upon, modify, incorporate in other works, reuse
-and redistribute as freely as possible in any form whatsoever and for any
-purposes, including without limitation commercial purposes. These owners may
-contribute to the Commons to promote the ideal of a free culture and the
-further production of creative, cultural and scientific works, or to gain
-reputation or greater distribution for their Work in part through the use and
-efforts of others.
-
-For these and/or other purposes and motivations, and without any expectation
-of additional consideration or compensation, the person associating CC0 with a
-Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
-and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
-and publicly distribute the Work under its terms, with knowledge of his or her
-Copyright and Related Rights in the Work and the meaning and intended legal
-effect of CC0 on those rights.
-
-1. Copyright and Related Rights. A Work made available under CC0 may be
-protected by copyright and related or neighboring rights ("Copyright and
-Related Rights"). Copyright and Related Rights include, but are not limited
-to, the following:
-
- i. the right to reproduce, adapt, distribute, perform, display, communicate,
- and translate a Work;
-
- ii. moral rights retained by the original author(s) and/or performer(s);
-
- iii. publicity and privacy rights pertaining to a person's image or likeness
- depicted in a Work;
-
- iv. rights protecting against unfair competition in regards to a Work,
- subject to the limitations in paragraph 4(a), below;
-
- v. rights protecting the extraction, dissemination, use and reuse of data in
- a Work;
-
- vi. database rights (such as those arising under Directive 96/9/EC of the
- European Parliament and of the Council of 11 March 1996 on the legal
- protection of databases, and under any national implementation thereof,
- including any amended or successor version of such directive); and
-
- vii. other similar, equivalent or corresponding rights throughout the world
- based on applicable law or treaty, and any national implementations thereof.
-
-2. Waiver. To the greatest extent permitted by, but not in contravention of,
-applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
-unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
-and Related Rights and associated claims and causes of action, whether now
-known or unknown (including existing as well as future claims and causes of
-action), in the Work (i) in all territories worldwide, (ii) for the maximum
-duration provided by applicable law or treaty (including future time
-extensions), (iii) in any current or future medium and for any number of
-copies, and (iv) for any purpose whatsoever, including without limitation
-commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
-the Waiver for the benefit of each member of the public at large and to the
-detriment of Affirmer's heirs and successors, fully intending that such Waiver
-shall not be subject to revocation, rescission, cancellation, termination, or
-any other legal or equitable action to disrupt the quiet enjoyment of the Work
-by the public as contemplated by Affirmer's express Statement of Purpose.
-
-3. Public License Fallback. Should any part of the Waiver for any reason be
-judged legally invalid or ineffective under applicable law, then the Waiver
-shall be preserved to the maximum extent permitted taking into account
-Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
-is so judged Affirmer hereby grants to each affected person a royalty-free,
-non transferable, non sublicensable, non exclusive, irrevocable and
-unconditional license to exercise Affirmer's Copyright and Related Rights in
-the Work (i) in all territories worldwide, (ii) for the maximum duration
-provided by applicable law or treaty (including future time extensions), (iii)
-in any current or future medium and for any number of copies, and (iv) for any
-purpose whatsoever, including without limitation commercial, advertising or
-promotional purposes (the "License"). The License shall be deemed effective as
-of the date CC0 was applied by Affirmer to the Work. Should any part of the
-License for any reason be judged legally invalid or ineffective under
-applicable law, such partial invalidity or ineffectiveness shall not
-invalidate the remainder of the License, and in such case Affirmer hereby
-affirms that he or she will not (i) exercise any of his or her remaining
-Copyright and Related Rights in the Work or (ii) assert any associated claims
-and causes of action with respect to the Work, in either case contrary to
-Affirmer's express Statement of Purpose.
-
-4. Limitations and Disclaimers.
-
- a. No trademark or patent rights held by Affirmer are waived, abandoned,
- surrendered, licensed or otherwise affected by this document.
-
- b. Affirmer offers the Work as-is and makes no representations or warranties
- of any kind concerning the Work, express, implied, statutory or otherwise,
- including without limitation warranties of title, merchantability, fitness
- for a particular purpose, non infringement, or the absence of latent or
- other defects, accuracy, or the present or absence of errors, whether or not
- discoverable, all to the greatest extent permissible under applicable law.
-
- c. Affirmer disclaims responsibility for clearing rights of other persons
- that may apply to the Work or any use thereof, including without limitation
- any person's Copyright and Related Rights in the Work. Further, Affirmer
- disclaims responsibility for obtaining any necessary consents, permissions
- or other rights required for any use of the Work.
-
- d. Affirmer understands and acknowledges that Creative Commons is not a
- party to this document and has no duty or obligation with respect to this
- CC0 or use of the Work.
-
-For more information, please see
-<http://creativecommons.org/publicdomain/zero/1.0/>
-
diff --git a/contrib/libs/blake2/README.md b/contrib/libs/blake2/README.md
deleted file mode 100644
index 17faa8f4d5..0000000000
--- a/contrib/libs/blake2/README.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# libb2
-
-C library providing BLAKE2b, BLAKE2s, BLAKE2bp, BLAKE2sp
-
-Installation:
-
-```
-$ ./autogen.sh
-$ ./configure
-$ make
-$ sudo make install
-```
-
-Contact: contact@blake2.net
diff --git a/contrib/libs/blake2/include/blake2.h b/contrib/libs/blake2/include/blake2.h
deleted file mode 100644
index 731ebdc993..0000000000
--- a/contrib/libs/blake2/include/blake2.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../src/blake2.h" /* inclink generated by yamaker */
diff --git a/contrib/libs/blake2/src/blake2-config.h b/contrib/libs/blake2/src/blake2-config.h
deleted file mode 100644
index c09cb4bcf0..0000000000
--- a/contrib/libs/blake2/src/blake2-config.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- BLAKE2 reference source code package - optimized C implementations
-
- Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
-
- To the extent possible under law, the author(s) have dedicated all copyright
- and related and neighboring rights to this software to the public domain
- worldwide. This software is distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along with
- this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
-*/
-#pragma once
-#ifndef __BLAKE2_CONFIG_H__
-#define __BLAKE2_CONFIG_H__
-
-#if defined(__SSE2__)
-#define HAVE_SSE2
-#endif
-
-#if defined(__SSSE3__)
-#define HAVE_SSSE3
-#endif
-
-#if defined(__SSE4_1__)
-#define HAVE_SSE4_1
-#endif
-
-#if defined(__AVX__)
-#define HAVE_AVX
-#endif
-
-#if defined(__XOP__)
-#define HAVE_XOP
-#endif
-
-
-#ifdef HAVE_AVX2
-#ifndef HAVE_AVX
-#define HAVE_AVX
-#endif
-#endif
-
-#ifdef HAVE_XOP
-#ifndef HAVE_AVX
-#define HAVE_AVX
-#endif
-#endif
-
-#ifdef HAVE_AVX
-#ifndef HAVE_SSE4_1
-#define HAVE_SSE4_1
-#endif
-#endif
-
-#ifdef HAVE_SSE4_1
-#ifndef HAVE_SSSE3
-#define HAVE_SSSE3
-#endif
-#endif
-
-#ifdef HAVE_SSSE3
-#define HAVE_SSE2
-#endif
-
-#if !defined(HAVE_SSE2)
-#error "This code requires at least SSE2."
-#endif
-
-#endif
-
diff --git a/contrib/libs/blake2/src/blake2-dispatch.c b/contrib/libs/blake2/src/blake2-dispatch.c
deleted file mode 100644
index 96bb3408bb..0000000000
--- a/contrib/libs/blake2/src/blake2-dispatch.c
+++ /dev/null
@@ -1,577 +0,0 @@
-/*
- BLAKE2 reference source code package - optimized C implementations
-
- Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
-
- To the extent possible under law, the author(s) have dedicated all copyright
- and related and neighboring rights to this software to the public domain
- worldwide. This software is distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along with
- this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
-*/
-#include <stdio.h>
-#if defined(WIN32)
-#include <windows.h>
-#endif
-#include "blake2.h"
-
-#if defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || defined(_M_X64)
-#define HAVE_X86
-#endif
-
-typedef enum
-{
- NONE = 0,
-#if defined(HAVE_X86)
- SSE2 = 1,
- SSSE3 = 2,
- SSE41 = 3,
- AVX = 4,
- XOP = 5,
- /* AVX2 = 6, */
-#endif
-} cpu_feature_t;
-
-static const char feature_names[][8] =
-{
- "none",
-#if defined(HAVE_X86)
- "sse2",
- "ssse3",
- "sse41",
- "avx",
- "xop",
- /* "avx2" */
-#endif
-};
-
-#if defined(HAVE_X86)
-
-#if defined(__GNUC__)
-static inline void cpuid( uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx )
-{
- __asm__ __volatile__(
-#if defined(__i386__) /* This is needed for -fPIC to work on i386 */
- "movl %%ebx, %%esi\n\t"
-#endif
- "cpuid\n\t"
-#if defined(__i386__)
- "xchgl %%ebx, %%esi\n\t"
- : "=a"( *eax ), "=S"( *ebx ), "=c"( *ecx ), "=d"( *edx ) : "a"( *eax ) );
-#else
- : "=a"( *eax ), "=b"( *ebx ), "=c"( *ecx ), "=d"( *edx ) : "a"( *eax ) );
-#endif
-}
-
-static inline uint64_t xgetbv(uint32_t xcr)
-{
- uint32_t a, d;
- __asm__ __volatile__(
- "xgetbv"
- : "=a"(a),"=d"(d)
- : "c"(xcr)
- );
- return ((uint64_t)d << 32) | a;
-}
-
-#elif defined(_MSC_VER)
-#include <intrin.h>
-static inline void cpuid( uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx )
-{
- int regs[4];
- __cpuid( regs, *eax );
- *eax = regs[0];
- *ebx = regs[1];
- *ecx = regs[2];
- *edx = regs[3];
-}
-#else
-#error "Don't know how to call cpuid on this compiler!"
-#endif
-
-#endif /* HAVE_X86 */
-
-static inline cpu_feature_t get_cpu_features( void )
-{
-#if defined(HAVE_X86)
- static volatile int initialized = 0;
- static cpu_feature_t feature = NONE; // Safe default
- uint32_t eax, ecx, edx, ebx;
-
- if( initialized )
- return feature;
-
- eax = 1;
- cpuid( &eax, &ebx, &ecx, &edx );
-
- if( 1 & ( edx >> 26 ) )
- feature = SSE2;
-
- if( 1 & ( ecx >> 9 ) )
- feature = SSSE3;
-
- if( 1 & ( ecx >> 19 ) )
- feature = SSE41;
-
-#if defined(WIN32) /* Work around the fact that Windows <7 does NOT support AVX... */
- if( IsProcessorFeaturePresent(17) ) /* Some environments don't know about PF_XSAVE_ENABLED */
-#endif
- {
- /* check for AVX and OSXSAVE bits */
- if( 1 & ( ecx >> 28 ) & (ecx >> 27) ) {
-#if !defined(WIN32) /* Already checked for this in WIN32 */
- if( (xgetbv(0) & 6) == 6 ) /* XCR0 */
-#endif
- feature = AVX;
- }
-
-
- eax = 0x80000001;
- cpuid( &eax, &ebx, &ecx, &edx );
-
- if( 1 & ( ecx >> 11 ) )
- feature = XOP;
- }
-
- /* For future architectures */
- /*
- eax = 7; ecx = 0;
- cpuid(&eax, &ebx, &ecx, &edx);
-
- if(1&(ebx >> 5))
- feature = AVX2;
- */
- /* fprintf( stderr, "Using %s engine\n", feature_names[feature] ); */
- initialized = 1;
- return feature;
-#else
- return NONE;
-#endif
-}
-
-
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
- int blake2b_init_ref( blake2b_state *S, size_t outlen );
- int blake2b_init_key_ref( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
- int blake2b_init_param_ref( blake2b_state *S, const blake2b_param *P );
- int blake2b_update_ref( blake2b_state *S, const uint8_t *in, size_t inlen );
- int blake2b_final_ref( blake2b_state *S, uint8_t *out, size_t outlen );
- int blake2b_ref( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
-
-#if defined(HAVE_X86)
-
- int blake2b_init_sse2( blake2b_state *S, size_t outlen );
- int blake2b_init_key_sse2( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
- int blake2b_init_param_sse2( blake2b_state *S, const blake2b_param *P );
- int blake2b_update_sse2( blake2b_state *S, const uint8_t *in, size_t inlen );
- int blake2b_final_sse2( blake2b_state *S, uint8_t *out, size_t outlen );
- int blake2b_sse2( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
-
- int blake2b_init_ssse3( blake2b_state *S, size_t outlen );
- int blake2b_init_key_ssse3( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
- int blake2b_init_param_ssse3( blake2b_state *S, const blake2b_param *P );
- int blake2b_update_ssse3( blake2b_state *S, const uint8_t *in, size_t inlen );
- int blake2b_final_ssse3( blake2b_state *S, uint8_t *out, size_t outlen );
- int blake2b_ssse3( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
-
- int blake2b_init_sse41( blake2b_state *S, size_t outlen );
- int blake2b_init_key_sse41( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
- int blake2b_init_param_sse41( blake2b_state *S, const blake2b_param *P );
- int blake2b_update_sse41( blake2b_state *S, const uint8_t *in, size_t inlen );
- int blake2b_final_sse41( blake2b_state *S, uint8_t *out, size_t outlen );
- int blake2b_sse41( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
-
- int blake2b_init_avx( blake2b_state *S, size_t outlen );
- int blake2b_init_key_avx( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
- int blake2b_init_param_avx( blake2b_state *S, const blake2b_param *P );
- int blake2b_update_avx( blake2b_state *S, const uint8_t *in, size_t inlen );
- int blake2b_final_avx( blake2b_state *S, uint8_t *out, size_t outlen );
- int blake2b_avx( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
-
- int blake2b_init_xop( blake2b_state *S, size_t outlen );
- int blake2b_init_key_xop( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
- int blake2b_init_param_xop( blake2b_state *S, const blake2b_param *P );
- int blake2b_update_xop( blake2b_state *S, const uint8_t *in, size_t inlen );
- int blake2b_final_xop( blake2b_state *S, uint8_t *out, size_t outlen );
- int blake2b_xop( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
-
-#endif /* HAVE_X86 */
-
- int blake2s_init_ref( blake2s_state *S, size_t outlen );
- int blake2s_init_key_ref( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
- int blake2s_init_param_ref( blake2s_state *S, const blake2s_param *P );
- int blake2s_update_ref( blake2s_state *S, const uint8_t *in, size_t inlen );
- int blake2s_final_ref( blake2s_state *S, uint8_t *out, size_t outlen );
- int blake2s_ref( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
-
-#if defined(HAVE_X86)
-
- int blake2s_init_sse2( blake2s_state *S, size_t outlen );
- int blake2s_init_key_sse2( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
- int blake2s_init_param_sse2( blake2s_state *S, const blake2s_param *P );
- int blake2s_update_sse2( blake2s_state *S, const uint8_t *in, size_t inlen );
- int blake2s_final_sse2( blake2s_state *S, uint8_t *out, size_t outlen );
- int blake2s_sse2( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
-
- int blake2s_init_ssse3( blake2s_state *S, size_t outlen );
- int blake2s_init_key_ssse3( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
- int blake2s_init_param_ssse3( blake2s_state *S, const blake2s_param *P );
- int blake2s_update_ssse3( blake2s_state *S, const uint8_t *in, size_t inlen );
- int blake2s_final_ssse3( blake2s_state *S, uint8_t *out, size_t outlen );
- int blake2s_ssse3( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
-
- int blake2s_init_sse41( blake2s_state *S, size_t outlen );
- int blake2s_init_key_sse41( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
- int blake2s_init_param_sse41( blake2s_state *S, const blake2s_param *P );
- int blake2s_update_sse41( blake2s_state *S, const uint8_t *in, size_t inlen );
- int blake2s_final_sse41( blake2s_state *S, uint8_t *out, size_t outlen );
- int blake2s_sse41( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
-
- int blake2s_init_avx( blake2s_state *S, size_t outlen );
- int blake2s_init_key_avx( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
- int blake2s_init_param_avx( blake2s_state *S, const blake2s_param *P );
- int blake2s_update_avx( blake2s_state *S, const uint8_t *in, size_t inlen );
- int blake2s_final_avx( blake2s_state *S, uint8_t *out, size_t outlen );
- int blake2s_avx( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
-
- int blake2s_init_xop( blake2s_state *S, size_t outlen );
- int blake2s_init_key_xop( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
- int blake2s_init_param_xop( blake2s_state *S, const blake2s_param *P );
- int blake2s_update_xop( blake2s_state *S, const uint8_t *in, size_t inlen );
- int blake2s_final_xop( blake2s_state *S, uint8_t *out, size_t outlen );
- int blake2s_xop( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
-
-#endif /* HAVE_X86 */
-
-#if defined(__cplusplus)
-}
-#endif
-
-typedef int ( *blake2b_init_fn )( blake2b_state *, size_t );
-typedef int ( *blake2b_init_key_fn )( blake2b_state *, size_t, const void *, size_t );
-typedef int ( *blake2b_init_param_fn )( blake2b_state *, const blake2b_param * );
-typedef int ( *blake2b_update_fn )( blake2b_state *, const uint8_t *, size_t );
-typedef int ( *blake2b_final_fn )( blake2b_state *, uint8_t *, size_t );
-typedef int ( *blake2b_fn )( uint8_t *, const void *, const void *, size_t, size_t, size_t );
-
-typedef int ( *blake2s_init_fn )( blake2s_state *, size_t );
-typedef int ( *blake2s_init_key_fn )( blake2s_state *, size_t, const void *, size_t );
-typedef int ( *blake2s_init_param_fn )( blake2s_state *, const blake2s_param * );
-typedef int ( *blake2s_update_fn )( blake2s_state *, const uint8_t *, size_t );
-typedef int ( *blake2s_final_fn )( blake2s_state *, uint8_t *, size_t );
-typedef int ( *blake2s_fn )( uint8_t *, const void *, const void *, size_t, size_t, size_t );
-
-static const blake2b_init_fn blake2b_init_table[] =
-{
- blake2b_init_ref,
-#if defined(HAVE_X86)
- blake2b_init_sse2,
- blake2b_init_ssse3,
- blake2b_init_sse41,
- blake2b_init_avx,
- blake2b_init_xop
-#endif
-};
-
-static const blake2b_init_key_fn blake2b_init_key_table[] =
-{
- blake2b_init_key_ref,
-#if defined(HAVE_X86)
- blake2b_init_key_sse2,
- blake2b_init_key_ssse3,
- blake2b_init_key_sse41,
- blake2b_init_key_avx,
- blake2b_init_key_xop
-#endif
-};
-
-static const blake2b_init_param_fn blake2b_init_param_table[] =
-{
- blake2b_init_param_ref,
-#if defined(HAVE_X86)
- blake2b_init_param_sse2,
- blake2b_init_param_ssse3,
- blake2b_init_param_sse41,
- blake2b_init_param_avx,
- blake2b_init_param_xop
-#endif
-};
-
-static const blake2b_update_fn blake2b_update_table[] =
-{
- blake2b_update_ref,
-#if defined(HAVE_X86)
- blake2b_update_sse2,
- blake2b_update_ssse3,
- blake2b_update_sse41,
- blake2b_update_avx,
- blake2b_update_xop
-#endif
-};
-
-static const blake2b_final_fn blake2b_final_table[] =
-{
- blake2b_final_ref,
-#if defined(HAVE_X86)
- blake2b_final_sse2,
- blake2b_final_ssse3,
- blake2b_final_sse41,
- blake2b_final_avx,
- blake2b_final_xop
-#endif
-};
-
-static const blake2b_fn blake2b_table[] =
-{
- blake2b_ref,
-#if defined(HAVE_X86)
- blake2b_sse2,
- blake2b_ssse3,
- blake2b_sse41,
- blake2b_avx,
- blake2b_xop
-#endif
-};
-
-static const blake2s_init_fn blake2s_init_table[] =
-{
- blake2s_init_ref,
-#if defined(HAVE_X86)
- blake2s_init_sse2,
- blake2s_init_ssse3,
- blake2s_init_sse41,
- blake2s_init_avx,
- blake2s_init_xop
-#endif
-};
-
-static const blake2s_init_key_fn blake2s_init_key_table[] =
-{
- blake2s_init_key_ref,
-#if defined(HAVE_X86)
- blake2s_init_key_sse2,
- blake2s_init_key_ssse3,
- blake2s_init_key_sse41,
- blake2s_init_key_avx,
- blake2s_init_key_xop
-#endif
-};
-
-static const blake2s_init_param_fn blake2s_init_param_table[] =
-{
- blake2s_init_param_ref,
-#if defined(HAVE_X86)
- blake2s_init_param_sse2,
- blake2s_init_param_ssse3,
- blake2s_init_param_sse41,
- blake2s_init_param_avx,
- blake2s_init_param_xop
-#endif
-};
-
-static const blake2s_update_fn blake2s_update_table[] =
-{
- blake2s_update_ref,
-#if defined(HAVE_X86)
- blake2s_update_sse2,
- blake2s_update_ssse3,
- blake2s_update_sse41,
- blake2s_update_avx,
- blake2s_update_xop
-#endif
-};
-
-static const blake2s_final_fn blake2s_final_table[] =
-{
- blake2s_final_ref,
-#if defined(HAVE_X86)
- blake2s_final_sse2,
- blake2s_final_ssse3,
- blake2s_final_sse41,
- blake2s_final_avx,
- blake2s_final_xop
-#endif
-};
-
-static const blake2s_fn blake2s_table[] =
-{
- blake2s_ref,
-#if defined(HAVE_X86)
- blake2s_sse2,
- blake2s_ssse3,
- blake2s_sse41,
- blake2s_avx,
- blake2s_xop
-#endif
-};
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
- int blake2b_init_dispatch( blake2b_state *S, size_t outlen );
- int blake2b_init_key_dispatch( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
- int blake2b_init_param_dispatch( blake2b_state *S, const blake2b_param *P );
- int blake2b_update_dispatch( blake2b_state *S, const uint8_t *in, size_t inlen );
- int blake2b_final_dispatch( blake2b_state *S, uint8_t *out, size_t outlen );
- int blake2b_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
-
- int blake2s_init_dispatch( blake2s_state *S, size_t outlen );
- int blake2s_init_key_dispatch( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
- int blake2s_init_param_dispatch( blake2s_state *S, const blake2s_param *P );
- int blake2s_update_dispatch( blake2s_state *S, const uint8_t *in, size_t inlen );
- int blake2s_final_dispatch( blake2s_state *S, uint8_t *out, size_t outlen );
- int blake2s_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
-#if defined(__cplusplus)
-}
-#endif
-
-static blake2b_init_fn blake2b_init_ptr = blake2b_init_dispatch;
-static blake2b_init_key_fn blake2b_init_key_ptr = blake2b_init_key_dispatch;
-static blake2b_init_param_fn blake2b_init_param_ptr = blake2b_init_param_dispatch;
-static blake2b_update_fn blake2b_update_ptr = blake2b_update_dispatch;
-static blake2b_final_fn blake2b_final_ptr = blake2b_final_dispatch;
-static blake2b_fn blake2b_ptr = blake2b_dispatch;
-
-static blake2s_init_fn blake2s_init_ptr = blake2s_init_dispatch;
-static blake2s_init_key_fn blake2s_init_key_ptr = blake2s_init_key_dispatch;
-static blake2s_init_param_fn blake2s_init_param_ptr = blake2s_init_param_dispatch;
-static blake2s_update_fn blake2s_update_ptr = blake2s_update_dispatch;
-static blake2s_final_fn blake2s_final_ptr = blake2s_final_dispatch;
-static blake2s_fn blake2s_ptr = blake2s_dispatch;
-
-int blake2b_init_dispatch( blake2b_state *S, size_t outlen )
-{
- blake2b_init_ptr = blake2b_init_table[get_cpu_features()];
- return blake2b_init_ptr( S, outlen );
-}
-
-int blake2b_init_key_dispatch( blake2b_state *S, size_t outlen, const void *key, size_t keylen )
-{
- blake2b_init_key_ptr = blake2b_init_key_table[get_cpu_features()];
- return blake2b_init_key_ptr( S, outlen, key, keylen );
-}
-
-int blake2b_init_param_dispatch( blake2b_state *S, const blake2b_param *P )
-{
- blake2b_init_param_ptr = blake2b_init_param_table[get_cpu_features()];
- return blake2b_init_param_ptr( S, P );
-}
-
-int blake2b_update_dispatch( blake2b_state *S, const uint8_t *in, size_t inlen )
-{
- blake2b_update_ptr = blake2b_update_table[get_cpu_features()];
- return blake2b_update_ptr( S, in, inlen );
-}
-
-int blake2b_final_dispatch( blake2b_state *S, uint8_t *out, size_t outlen )
-{
- blake2b_final_ptr = blake2b_final_table[get_cpu_features()];
- return blake2b_final_ptr( S, out, outlen );
-}
-
-int blake2b_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
-{
- blake2b_ptr = blake2b_table[get_cpu_features()];
- return blake2b_ptr( out, in, key, outlen, inlen, keylen );
-}
-
-BLAKE2_API int blake2b_init( blake2b_state *S, size_t outlen )
-{
- return blake2b_init_ptr( S, outlen );
-}
-
-BLAKE2_API int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen )
-{
- return blake2b_init_key_ptr( S, outlen, key, keylen );
-}
-
-BLAKE2_API int blake2b_init_param( blake2b_state *S, const blake2b_param *P )
-{
- return blake2b_init_param_ptr( S, P );
-}
-
-BLAKE2_API int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen )
-{
- return blake2b_update_ptr( S, in, inlen );
-}
-
-BLAKE2_API int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen )
-{
- return blake2b_final_ptr( S, out, outlen );
-}
-
-BLAKE2_API int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
-{
- return blake2b_ptr( out, in, key, outlen, inlen, keylen );
-}
-
-int blake2s_init_dispatch( blake2s_state *S, size_t outlen )
-{
- blake2s_init_ptr = blake2s_init_table[get_cpu_features()];
- return blake2s_init_ptr( S, outlen );
-}
-
-int blake2s_init_key_dispatch( blake2s_state *S, size_t outlen, const void *key, size_t keylen )
-{
- blake2s_init_key_ptr = blake2s_init_key_table[get_cpu_features()];
- return blake2s_init_key_ptr( S, outlen, key, keylen );
-}
-
-int blake2s_init_param_dispatch( blake2s_state *S, const blake2s_param *P )
-{
- blake2s_init_param_ptr = blake2s_init_param_table[get_cpu_features()];
- return blake2s_init_param_ptr( S, P );
-}
-
-int blake2s_update_dispatch( blake2s_state *S, const uint8_t *in, size_t inlen )
-{
- blake2s_update_ptr = blake2s_update_table[get_cpu_features()];
- return blake2s_update_ptr( S, in, inlen );
-}
-
-int blake2s_final_dispatch( blake2s_state *S, uint8_t *out, size_t outlen )
-{
- blake2s_final_ptr = blake2s_final_table[get_cpu_features()];
- return blake2s_final_ptr( S, out, outlen );
-}
-
-int blake2s_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
-{
- blake2s_ptr = blake2s_table[get_cpu_features()];
- return blake2s_ptr( out, in, key, outlen, inlen, keylen );
-}
-
-BLAKE2_API int blake2s_init( blake2s_state *S, size_t outlen )
-{
- return blake2s_init_ptr( S, outlen );
-}
-
-BLAKE2_API int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen )
-{
- return blake2s_init_key_ptr( S, outlen, key, keylen );
-}
-
-BLAKE2_API int blake2s_init_param( blake2s_state *S, const blake2s_param *P )
-{
- return blake2s_init_param_ptr( S, P );
-}
-
-BLAKE2_API int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen )
-{
- return blake2s_update_ptr( S, in, inlen );
-}
-
-BLAKE2_API int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen )
-{
- return blake2s_final_ptr( S, out, outlen );
-}
-
-BLAKE2_API int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
-{
- return blake2s_ptr( out, in, key, outlen, inlen, keylen );
-}
-
diff --git a/contrib/libs/blake2/src/blake2-impl.h b/contrib/libs/blake2/src/blake2-impl.h
deleted file mode 100644
index 801f1ae7b7..0000000000
--- a/contrib/libs/blake2/src/blake2-impl.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- BLAKE2 reference source code package - optimized C implementations
-
- Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
-
- To the extent possible under law, the author(s) have dedicated all copyright
- and related and neighboring rights to this software to the public domain
- worldwide. This software is distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along with
- this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
-*/
-#pragma once
-#ifndef __BLAKE2_IMPL_H__
-#define __BLAKE2_IMPL_H__
-
-#if defined(_WIN32) || defined(WIN32)
-#include <windows.h>
-#endif
-
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-#include "config.h"
-
-#define BLAKE2_IMPL_CAT(x,y) x ## y
-#define BLAKE2_IMPL_EVAL(x,y) BLAKE2_IMPL_CAT(x,y)
-#define BLAKE2_IMPL_NAME(fun) BLAKE2_IMPL_EVAL(fun, SUFFIX)
-
-static inline uint32_t load32( const void *src )
-{
-#if defined(NATIVE_LITTLE_ENDIAN)
- uint32_t w;
- memcpy( &w, src, sizeof( w ) );
- return w;
-#else
- const uint8_t *p = ( uint8_t * )src;
- uint32_t w = *p++;
- w |= ( uint32_t )( *p++ ) << 8;
- w |= ( uint32_t )( *p++ ) << 16;
- w |= ( uint32_t )( *p++ ) << 24;
- return w;
-#endif
-}
-
-static inline uint64_t load64( const void *src )
-{
-#if defined(NATIVE_LITTLE_ENDIAN)
- uint64_t w;
- memcpy( &w, src, sizeof( w ) );
- return w;
-#else
- const uint8_t *p = ( uint8_t * )src;
- uint64_t w = *p++;
- w |= ( uint64_t )( *p++ ) << 8;
- w |= ( uint64_t )( *p++ ) << 16;
- w |= ( uint64_t )( *p++ ) << 24;
- w |= ( uint64_t )( *p++ ) << 32;
- w |= ( uint64_t )( *p++ ) << 40;
- w |= ( uint64_t )( *p++ ) << 48;
- w |= ( uint64_t )( *p++ ) << 56;
- return w;
-#endif
-}
-
-static inline void store32( void *dst, uint32_t w )
-{
-#if defined(NATIVE_LITTLE_ENDIAN)
- memcpy( dst, &w, sizeof( w ) );
-#else
- uint8_t *p = ( uint8_t * )dst;
- *p++ = ( uint8_t )w; w >>= 8;
- *p++ = ( uint8_t )w; w >>= 8;
- *p++ = ( uint8_t )w; w >>= 8;
- *p++ = ( uint8_t )w;
-#endif
-}
-
-static inline void store64( void *dst, uint64_t w )
-{
-#if defined(NATIVE_LITTLE_ENDIAN)
- memcpy( dst, &w, sizeof( w ) );
-#else
- uint8_t *p = ( uint8_t * )dst;
- *p++ = ( uint8_t )w; w >>= 8;
- *p++ = ( uint8_t )w; w >>= 8;
- *p++ = ( uint8_t )w; w >>= 8;
- *p++ = ( uint8_t )w; w >>= 8;
- *p++ = ( uint8_t )w; w >>= 8;
- *p++ = ( uint8_t )w; w >>= 8;
- *p++ = ( uint8_t )w; w >>= 8;
- *p++ = ( uint8_t )w;
-#endif
-}
-
-static inline uint64_t load48( const void *src )
-{
- const uint8_t *p = ( const uint8_t * )src;
- uint64_t w = *p++;
- w |= ( uint64_t )( *p++ ) << 8;
- w |= ( uint64_t )( *p++ ) << 16;
- w |= ( uint64_t )( *p++ ) << 24;
- w |= ( uint64_t )( *p++ ) << 32;
- w |= ( uint64_t )( *p++ ) << 40;
- return w;
-}
-
-static inline void store48( void *dst, uint64_t w )
-{
- uint8_t *p = ( uint8_t * )dst;
- *p++ = ( uint8_t )w; w >>= 8;
- *p++ = ( uint8_t )w; w >>= 8;
- *p++ = ( uint8_t )w; w >>= 8;
- *p++ = ( uint8_t )w; w >>= 8;
- *p++ = ( uint8_t )w; w >>= 8;
- *p++ = ( uint8_t )w;
-}
-
-static inline uint32_t rotl32( const uint32_t w, const unsigned c )
-{
- return ( w << c ) | ( w >> ( 32 - c ) );
-}
-
-static inline uint64_t rotl64( const uint64_t w, const unsigned c )
-{
- return ( w << c ) | ( w >> ( 64 - c ) );
-}
-
-static inline uint32_t rotr32( const uint32_t w, const unsigned c )
-{
- return ( w >> c ) | ( w << ( 32 - c ) );
-}
-
-static inline uint64_t rotr64( const uint64_t w, const unsigned c )
-{
- return ( w >> c ) | ( w << ( 64 - c ) );
-}
-
-/* prevents compiler optimizing out memset() */
-static inline void secure_zero_memory(void *v, size_t n)
-{
-#if defined(_WIN32) || defined(WIN32)
- SecureZeroMemory(v, n);
-#else
-// prioritize first the general C11 call
-#if defined(HAVE_MEMSET_S)
- memset_s(v, n, 0, n);
-#elif defined(HAVE_EXPLICIT_BZERO)
- explicit_bzero(v, n);
-#elif defined(HAVE_EXPLICIT_MEMSET)
- explicit_memset(v, 0, n);
-#else
- memset(v, 0, n);
- __asm__ __volatile__("" :: "r"(v) : "memory");
-#endif
-#endif
-}
-
-#endif
-
diff --git a/contrib/libs/blake2/src/blake2.h b/contrib/libs/blake2/src/blake2.h
deleted file mode 100644
index 5ca17f6107..0000000000
--- a/contrib/libs/blake2/src/blake2.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- BLAKE2 reference source code package - optimized C implementations
-
- Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
-
- To the extent possible under law, the author(s) have dedicated all copyright
- and related and neighboring rights to this software to the public domain
- worldwide. This software is distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along with
- this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
-*/
-#pragma once
-#ifndef __BLAKE2_H__
-#define __BLAKE2_H__
-
-#include <stddef.h>
-#include <stdint.h>
-
-#if defined(_WIN32) || defined(__CYGWIN__)
- #define BLAKE2_DLL_IMPORT __declspec(dllimport)
- #define BLAKE2_DLL_EXPORT __declspec(dllexport)
- #define BLAKE2_DLL_PRIVATE
-#elif __GNUC__ >= 4
- #define BLAKE2_DLL_IMPORT __attribute__ ((visibility ("default")))
- #define BLAKE2_DLL_EXPORT __attribute__ ((visibility ("default")))
- #define BLAKE2_DLL_PRIVATE __attribute__ ((visibility ("hidden")))
-#else
- #define BLAKE2_DLL_IMPORT
- #define BLAKE2_DLL_EXPORT
- #define BLAKE2_DLL_PRIVATE
-#endif
-
-#if defined(BLAKE2_DLL)
- #if defined(BLAKE2_DLL_EXPORTS) // defined if we are building the DLL
- #define BLAKE2_API BLAKE2_DLL_EXPORT
- #else
- #define BLAKE2_API BLAKE2_DLL_IMPORT
- #endif
- #define BLAKE2_PRIVATE BLAKE2_DLL_PRIVATE // must only be used by hidden logic
-#else
- #define BLAKE2_API
- #define BLAKE2_PRIVATE
-#endif
-
-#if defined(__cplusplus)
-extern "C" {
-#elif defined(_MSC_VER) && !defined(inline)
-#define inline __inline
-#endif
-
- enum blake2s_constant
- {
- BLAKE2S_BLOCKBYTES = 64,
- BLAKE2S_OUTBYTES = 32,
- BLAKE2S_KEYBYTES = 32,
- BLAKE2S_SALTBYTES = 8,
- BLAKE2S_PERSONALBYTES = 8
- };
-
- enum blake2b_constant
- {
- BLAKE2B_BLOCKBYTES = 128,
- BLAKE2B_OUTBYTES = 64,
- BLAKE2B_KEYBYTES = 64,
- BLAKE2B_SALTBYTES = 16,
- BLAKE2B_PERSONALBYTES = 16
- };
-
-#pragma pack(push, 1)
- typedef struct __blake2s_param
- {
- uint8_t digest_length; // 1
- uint8_t key_length; // 2
- uint8_t fanout; // 3
- uint8_t depth; // 4
- uint32_t leaf_length; // 8
- uint8_t node_offset[6];// 14
- uint8_t node_depth; // 15
- uint8_t inner_length; // 16
- // uint8_t reserved[0];
- uint8_t salt[BLAKE2S_SALTBYTES]; // 24
- uint8_t personal[BLAKE2S_PERSONALBYTES]; // 32
- } blake2s_param;
-
- typedef struct __blake2s_state
- {
- uint32_t h[8];
- uint32_t t[2];
- uint32_t f[2];
- uint8_t buf[2 * BLAKE2S_BLOCKBYTES];
- uint32_t buflen;
- uint8_t outlen;
- uint8_t last_node;
- } blake2s_state;
-
- typedef struct __blake2b_param
- {
- uint8_t digest_length; // 1
- uint8_t key_length; // 2
- uint8_t fanout; // 3
- uint8_t depth; // 4
- uint32_t leaf_length; // 8
- uint64_t node_offset; // 16
- uint8_t node_depth; // 17
- uint8_t inner_length; // 18
- uint8_t reserved[14]; // 32
- uint8_t salt[BLAKE2B_SALTBYTES]; // 48
- uint8_t personal[BLAKE2B_PERSONALBYTES]; // 64
- } blake2b_param;
-
- typedef struct __blake2b_state
- {
- uint64_t h[8];
- uint64_t t[2];
- uint64_t f[2];
- uint8_t buf[2 * BLAKE2B_BLOCKBYTES];
- uint32_t buflen;
- uint8_t outlen;
- uint8_t last_node;
- } blake2b_state;
-
- typedef struct __blake2sp_state
- {
- blake2s_state S[8][1];
- blake2s_state R[1];
- uint8_t buf[8 * BLAKE2S_BLOCKBYTES];
- uint32_t buflen;
- uint8_t outlen;
- } blake2sp_state;
-
- typedef struct __blake2bp_state
- {
- blake2b_state S[4][1];
- blake2b_state R[1];
- uint8_t buf[4 * BLAKE2B_BLOCKBYTES];
- uint32_t buflen;
- uint8_t outlen;
- } blake2bp_state;
-#pragma pack(pop)
-
- // Streaming API
- BLAKE2_API int blake2s_init( blake2s_state *S, size_t outlen );
- BLAKE2_API int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
- BLAKE2_API int blake2s_init_param( blake2s_state *S, const blake2s_param *P );
- BLAKE2_API int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen );
- BLAKE2_API int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen );
-
- BLAKE2_API int blake2b_init( blake2b_state *S, size_t outlen );
- BLAKE2_API int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
- BLAKE2_API int blake2b_init_param( blake2b_state *S, const blake2b_param *P );
- BLAKE2_API int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen );
- BLAKE2_API int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen );
-
- BLAKE2_API int blake2sp_init( blake2sp_state *S, size_t outlen );
- BLAKE2_API int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen );
- BLAKE2_API int blake2sp_update( blake2sp_state *S, const uint8_t *in, size_t inlen );
- BLAKE2_API int blake2sp_final( blake2sp_state *S, uint8_t *out, size_t outlen );
-
- BLAKE2_API int blake2bp_init( blake2bp_state *S, size_t outlen );
- BLAKE2_API int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen );
- BLAKE2_API int blake2bp_update( blake2bp_state *S, const uint8_t *in, size_t inlen );
- BLAKE2_API int blake2bp_final( blake2bp_state *S, uint8_t *out, size_t outlen );
-
- // Simple API
- BLAKE2_API int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
- BLAKE2_API int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
-
- BLAKE2_API int blake2sp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
- BLAKE2_API int blake2bp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
-
- static inline int blake2( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
- {
- return blake2b( out, in, key, outlen, inlen, keylen );
- }
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif
-
diff --git a/contrib/libs/blake2/src/blake2b-load-sse2.h b/contrib/libs/blake2/src/blake2b-load-sse2.h
deleted file mode 100644
index 1ba153c87d..0000000000
--- a/contrib/libs/blake2/src/blake2b-load-sse2.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- BLAKE2 reference source code package - optimized C implementations
-
- Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
-
- To the extent possible under law, the author(s) have dedicated all copyright
- and related and neighboring rights to this software to the public domain
- worldwide. This software is distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along with
- this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
-*/
-#pragma once
-#ifndef __BLAKE2B_LOAD_SSE2_H__
-#define __BLAKE2B_LOAD_SSE2_H__
-
-#define LOAD_MSG_0_1(b0, b1) b0 = _mm_set_epi64x(m2, m0); b1 = _mm_set_epi64x(m6, m4)
-#define LOAD_MSG_0_2(b0, b1) b0 = _mm_set_epi64x(m3, m1); b1 = _mm_set_epi64x(m7, m5)
-#define LOAD_MSG_0_3(b0, b1) b0 = _mm_set_epi64x(m10, m8); b1 = _mm_set_epi64x(m14, m12)
-#define LOAD_MSG_0_4(b0, b1) b0 = _mm_set_epi64x(m11, m9); b1 = _mm_set_epi64x(m15, m13)
-#define LOAD_MSG_1_1(b0, b1) b0 = _mm_set_epi64x(m4, m14); b1 = _mm_set_epi64x(m13, m9)
-#define LOAD_MSG_1_2(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m6, m15)
-#define LOAD_MSG_1_3(b0, b1) b0 = _mm_set_epi64x(m0, m1); b1 = _mm_set_epi64x(m5, m11)
-#define LOAD_MSG_1_4(b0, b1) b0 = _mm_set_epi64x(m2, m12); b1 = _mm_set_epi64x(m3, m7)
-#define LOAD_MSG_2_1(b0, b1) b0 = _mm_set_epi64x(m12, m11); b1 = _mm_set_epi64x(m15, m5)
-#define LOAD_MSG_2_2(b0, b1) b0 = _mm_set_epi64x(m0, m8); b1 = _mm_set_epi64x(m13, m2)
-#define LOAD_MSG_2_3(b0, b1) b0 = _mm_set_epi64x(m3, m10); b1 = _mm_set_epi64x(m9, m7)
-#define LOAD_MSG_2_4(b0, b1) b0 = _mm_set_epi64x(m6, m14); b1 = _mm_set_epi64x(m4, m1)
-#define LOAD_MSG_3_1(b0, b1) b0 = _mm_set_epi64x(m3, m7); b1 = _mm_set_epi64x(m11, m13)
-#define LOAD_MSG_3_2(b0, b1) b0 = _mm_set_epi64x(m1, m9); b1 = _mm_set_epi64x(m14, m12)
-#define LOAD_MSG_3_3(b0, b1) b0 = _mm_set_epi64x(m5, m2); b1 = _mm_set_epi64x(m15, m4)
-#define LOAD_MSG_3_4(b0, b1) b0 = _mm_set_epi64x(m10, m6); b1 = _mm_set_epi64x(m8, m0)
-#define LOAD_MSG_4_1(b0, b1) b0 = _mm_set_epi64x(m5, m9); b1 = _mm_set_epi64x(m10, m2)
-#define LOAD_MSG_4_2(b0, b1) b0 = _mm_set_epi64x(m7, m0); b1 = _mm_set_epi64x(m15, m4)
-#define LOAD_MSG_4_3(b0, b1) b0 = _mm_set_epi64x(m11, m14); b1 = _mm_set_epi64x(m3, m6)
-#define LOAD_MSG_4_4(b0, b1) b0 = _mm_set_epi64x(m12, m1); b1 = _mm_set_epi64x(m13, m8)
-#define LOAD_MSG_5_1(b0, b1) b0 = _mm_set_epi64x(m6, m2); b1 = _mm_set_epi64x(m8, m0)
-#define LOAD_MSG_5_2(b0, b1) b0 = _mm_set_epi64x(m10, m12); b1 = _mm_set_epi64x(m3, m11)
-#define LOAD_MSG_5_3(b0, b1) b0 = _mm_set_epi64x(m7, m4); b1 = _mm_set_epi64x(m1, m15)
-#define LOAD_MSG_5_4(b0, b1) b0 = _mm_set_epi64x(m5, m13); b1 = _mm_set_epi64x(m9, m14)
-#define LOAD_MSG_6_1(b0, b1) b0 = _mm_set_epi64x(m1, m12); b1 = _mm_set_epi64x(m4, m14)
-#define LOAD_MSG_6_2(b0, b1) b0 = _mm_set_epi64x(m15, m5); b1 = _mm_set_epi64x(m10, m13)
-#define LOAD_MSG_6_3(b0, b1) b0 = _mm_set_epi64x(m6, m0); b1 = _mm_set_epi64x(m8, m9)
-#define LOAD_MSG_6_4(b0, b1) b0 = _mm_set_epi64x(m3, m7); b1 = _mm_set_epi64x(m11, m2)
-#define LOAD_MSG_7_1(b0, b1) b0 = _mm_set_epi64x(m7, m13); b1 = _mm_set_epi64x(m3, m12)
-#define LOAD_MSG_7_2(b0, b1) b0 = _mm_set_epi64x(m14, m11); b1 = _mm_set_epi64x(m9, m1)
-#define LOAD_MSG_7_3(b0, b1) b0 = _mm_set_epi64x(m15, m5); b1 = _mm_set_epi64x(m2, m8)
-#define LOAD_MSG_7_4(b0, b1) b0 = _mm_set_epi64x(m4, m0); b1 = _mm_set_epi64x(m10, m6)
-#define LOAD_MSG_8_1(b0, b1) b0 = _mm_set_epi64x(m14, m6); b1 = _mm_set_epi64x(m0, m11)
-#define LOAD_MSG_8_2(b0, b1) b0 = _mm_set_epi64x(m9, m15); b1 = _mm_set_epi64x(m8, m3)
-#define LOAD_MSG_8_3(b0, b1) b0 = _mm_set_epi64x(m13, m12); b1 = _mm_set_epi64x(m10, m1)
-#define LOAD_MSG_8_4(b0, b1) b0 = _mm_set_epi64x(m7, m2); b1 = _mm_set_epi64x(m5, m4)
-#define LOAD_MSG_9_1(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m1, m7)
-#define LOAD_MSG_9_2(b0, b1) b0 = _mm_set_epi64x(m4, m2); b1 = _mm_set_epi64x(m5, m6)
-#define LOAD_MSG_9_3(b0, b1) b0 = _mm_set_epi64x(m9, m15); b1 = _mm_set_epi64x(m13, m3)
-#define LOAD_MSG_9_4(b0, b1) b0 = _mm_set_epi64x(m14, m11); b1 = _mm_set_epi64x(m0, m12)
-#define LOAD_MSG_10_1(b0, b1) b0 = _mm_set_epi64x(m2, m0); b1 = _mm_set_epi64x(m6, m4)
-#define LOAD_MSG_10_2(b0, b1) b0 = _mm_set_epi64x(m3, m1); b1 = _mm_set_epi64x(m7, m5)
-#define LOAD_MSG_10_3(b0, b1) b0 = _mm_set_epi64x(m10, m8); b1 = _mm_set_epi64x(m14, m12)
-#define LOAD_MSG_10_4(b0, b1) b0 = _mm_set_epi64x(m11, m9); b1 = _mm_set_epi64x(m15, m13)
-#define LOAD_MSG_11_1(b0, b1) b0 = _mm_set_epi64x(m4, m14); b1 = _mm_set_epi64x(m13, m9)
-#define LOAD_MSG_11_2(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m6, m15)
-#define LOAD_MSG_11_3(b0, b1) b0 = _mm_set_epi64x(m0, m1); b1 = _mm_set_epi64x(m5, m11)
-#define LOAD_MSG_11_4(b0, b1) b0 = _mm_set_epi64x(m2, m12); b1 = _mm_set_epi64x(m3, m7)
-
-
-#endif
-
diff --git a/contrib/libs/blake2/src/blake2b-load-sse41.h b/contrib/libs/blake2/src/blake2b-load-sse41.h
deleted file mode 100644
index f6c1bc8393..0000000000
--- a/contrib/libs/blake2/src/blake2b-load-sse41.h
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- BLAKE2 reference source code package - optimized C implementations
-
- Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
-
- To the extent possible under law, the author(s) have dedicated all copyright
- and related and neighboring rights to this software to the public domain
- worldwide. This software is distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along with
- this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
-*/
-#pragma once
-#ifndef __BLAKE2B_LOAD_SSE41_H__
-#define __BLAKE2B_LOAD_SSE41_H__
-
-#define LOAD_MSG_0_1(b0, b1) \
-do \
-{ \
-b0 = _mm_unpacklo_epi64(m0, m1); \
-b1 = _mm_unpacklo_epi64(m2, m3); \
-} while(0)
-
-
-#define LOAD_MSG_0_2(b0, b1) \
-do \
-{ \
-b0 = _mm_unpackhi_epi64(m0, m1); \
-b1 = _mm_unpackhi_epi64(m2, m3); \
-} while(0)
-
-
-#define LOAD_MSG_0_3(b0, b1) \
-do \
-{ \
-b0 = _mm_unpacklo_epi64(m4, m5); \
-b1 = _mm_unpacklo_epi64(m6, m7); \
-} while(0)
-
-
-#define LOAD_MSG_0_4(b0, b1) \
-do \
-{ \
-b0 = _mm_unpackhi_epi64(m4, m5); \
-b1 = _mm_unpackhi_epi64(m6, m7); \
-} while(0)
-
-
-#define LOAD_MSG_1_1(b0, b1) \
-do \
-{ \
-b0 = _mm_unpacklo_epi64(m7, m2); \
-b1 = _mm_unpackhi_epi64(m4, m6); \
-} while(0)
-
-
-#define LOAD_MSG_1_2(b0, b1) \
-do \
-{ \
-b0 = _mm_unpacklo_epi64(m5, m4); \
-b1 = _mm_alignr_epi8(m3, m7, 8); \
-} while(0)
-
-
-#define LOAD_MSG_1_3(b0, b1) \
-do \
-{ \
-b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1,0,3,2)); \
-b1 = _mm_unpackhi_epi64(m5, m2); \
-} while(0)
-
-
-#define LOAD_MSG_1_4(b0, b1) \
-do \
-{ \
-b0 = _mm_unpacklo_epi64(m6, m1); \
-b1 = _mm_unpackhi_epi64(m3, m1); \
-} while(0)
-
-
-#define LOAD_MSG_2_1(b0, b1) \
-do \
-{ \
-b0 = _mm_alignr_epi8(m6, m5, 8); \
-b1 = _mm_unpackhi_epi64(m2, m7); \
-} while(0)
-
-
-#define LOAD_MSG_2_2(b0, b1) \
-do \
-{ \
-b0 = _mm_unpacklo_epi64(m4, m0); \
-b1 = _mm_blend_epi16(m1, m6, 0xF0); \
-} while(0)
-
-
-#define LOAD_MSG_2_3(b0, b1) \
-do \
-{ \
-b0 = _mm_blend_epi16(m5, m1, 0xF0); \
-b1 = _mm_unpackhi_epi64(m3, m4); \
-} while(0)
-
-
-#define LOAD_MSG_2_4(b0, b1) \
-do \
-{ \
-b0 = _mm_unpacklo_epi64(m7, m3); \
-b1 = _mm_alignr_epi8(m2, m0, 8); \
-} while(0)
-
-
-#define LOAD_MSG_3_1(b0, b1) \
-do \
-{ \
-b0 = _mm_unpackhi_epi64(m3, m1); \
-b1 = _mm_unpackhi_epi64(m6, m5); \
-} while(0)
-
-
-#define LOAD_MSG_3_2(b0, b1) \
-do \
-{ \
-b0 = _mm_unpackhi_epi64(m4, m0); \
-b1 = _mm_unpacklo_epi64(m6, m7); \
-} while(0)
-
-
-#define LOAD_MSG_3_3(b0, b1) \
-do \
-{ \
-b0 = _mm_blend_epi16(m1, m2, 0xF0); \
-b1 = _mm_blend_epi16(m2, m7, 0xF0); \
-} while(0)
-
-
-#define LOAD_MSG_3_4(b0, b1) \
-do \
-{ \
-b0 = _mm_unpacklo_epi64(m3, m5); \
-b1 = _mm_unpacklo_epi64(m0, m4); \
-} while(0)
-
-
-#define LOAD_MSG_4_1(b0, b1) \
-do \
-{ \
-b0 = _mm_unpackhi_epi64(m4, m2); \
-b1 = _mm_unpacklo_epi64(m1, m5); \
-} while(0)
-
-
-#define LOAD_MSG_4_2(b0, b1) \
-do \
-{ \
-b0 = _mm_blend_epi16(m0, m3, 0xF0); \
-b1 = _mm_blend_epi16(m2, m7, 0xF0); \
-} while(0)
-
-
-#define LOAD_MSG_4_3(b0, b1) \
-do \
-{ \
-b0 = _mm_blend_epi16(m7, m5, 0xF0); \
-b1 = _mm_blend_epi16(m3, m1, 0xF0); \
-} while(0)
-
-
-#define LOAD_MSG_4_4(b0, b1) \
-do \
-{ \
-b0 = _mm_alignr_epi8(m6, m0, 8); \
-b1 = _mm_blend_epi16(m4, m6, 0xF0); \
-} while(0)
-
-
-#define LOAD_MSG_5_1(b0, b1) \
-do \
-{ \
-b0 = _mm_unpacklo_epi64(m1, m3); \
-b1 = _mm_unpacklo_epi64(m0, m4); \
-} while(0)
-
-
-#define LOAD_MSG_5_2(b0, b1) \
-do \
-{ \
-b0 = _mm_unpacklo_epi64(m6, m5); \
-b1 = _mm_unpackhi_epi64(m5, m1); \
-} while(0)
-
-
-#define LOAD_MSG_5_3(b0, b1) \
-do \
-{ \
-b0 = _mm_blend_epi16(m2, m3, 0xF0); \
-b1 = _mm_unpackhi_epi64(m7, m0); \
-} while(0)
-
-
-#define LOAD_MSG_5_4(b0, b1) \
-do \
-{ \
-b0 = _mm_unpackhi_epi64(m6, m2); \
-b1 = _mm_blend_epi16(m7, m4, 0xF0); \
-} while(0)
-
-
-#define LOAD_MSG_6_1(b0, b1) \
-do \
-{ \
-b0 = _mm_blend_epi16(m6, m0, 0xF0); \
-b1 = _mm_unpacklo_epi64(m7, m2); \
-} while(0)
-
-
-#define LOAD_MSG_6_2(b0, b1) \
-do \
-{ \
-b0 = _mm_unpackhi_epi64(m2, m7); \
-b1 = _mm_alignr_epi8(m5, m6, 8); \
-} while(0)
-
-
-#define LOAD_MSG_6_3(b0, b1) \
-do \
-{ \
-b0 = _mm_unpacklo_epi64(m0, m3); \
-b1 = _mm_shuffle_epi32(m4, _MM_SHUFFLE(1,0,3,2)); \
-} while(0)
-
-
-#define LOAD_MSG_6_4(b0, b1) \
-do \
-{ \
-b0 = _mm_unpackhi_epi64(m3, m1); \
-b1 = _mm_blend_epi16(m1, m5, 0xF0); \
-} while(0)
-
-
-#define LOAD_MSG_7_1(b0, b1) \
-do \
-{ \
-b0 = _mm_unpackhi_epi64(m6, m3); \
-b1 = _mm_blend_epi16(m6, m1, 0xF0); \
-} while(0)
-
-
-#define LOAD_MSG_7_2(b0, b1) \
-do \
-{ \
-b0 = _mm_alignr_epi8(m7, m5, 8); \
-b1 = _mm_unpackhi_epi64(m0, m4); \
-} while(0)
-
-
-#define LOAD_MSG_7_3(b0, b1) \
-do \
-{ \
-b0 = _mm_unpackhi_epi64(m2, m7); \
-b1 = _mm_unpacklo_epi64(m4, m1); \
-} while(0)
-
-
-#define LOAD_MSG_7_4(b0, b1) \
-do \
-{ \
-b0 = _mm_unpacklo_epi64(m0, m2); \
-b1 = _mm_unpacklo_epi64(m3, m5); \
-} while(0)
-
-
-#define LOAD_MSG_8_1(b0, b1) \
-do \
-{ \
-b0 = _mm_unpacklo_epi64(m3, m7); \
-b1 = _mm_alignr_epi8(m0, m5, 8); \
-} while(0)
-
-
-#define LOAD_MSG_8_2(b0, b1) \
-do \
-{ \
-b0 = _mm_unpackhi_epi64(m7, m4); \
-b1 = _mm_alignr_epi8(m4, m1, 8); \
-} while(0)
-
-
-#define LOAD_MSG_8_3(b0, b1) \
-do \
-{ \
-b0 = m6; \
-b1 = _mm_alignr_epi8(m5, m0, 8); \
-} while(0)
-
-
-#define LOAD_MSG_8_4(b0, b1) \
-do \
-{ \
-b0 = _mm_blend_epi16(m1, m3, 0xF0); \
-b1 = m2; \
-} while(0)
-
-
-#define LOAD_MSG_9_1(b0, b1) \
-do \
-{ \
-b0 = _mm_unpacklo_epi64(m5, m4); \
-b1 = _mm_unpackhi_epi64(m3, m0); \
-} while(0)
-
-
-#define LOAD_MSG_9_2(b0, b1) \
-do \
-{ \
-b0 = _mm_unpacklo_epi64(m1, m2); \
-b1 = _mm_blend_epi16(m3, m2, 0xF0); \
-} while(0)
-
-
-#define LOAD_MSG_9_3(b0, b1) \
-do \
-{ \
-b0 = _mm_unpackhi_epi64(m7, m4); \
-b1 = _mm_unpackhi_epi64(m1, m6); \
-} while(0)
-
-
-#define LOAD_MSG_9_4(b0, b1) \
-do \
-{ \
-b0 = _mm_alignr_epi8(m7, m5, 8); \
-b1 = _mm_unpacklo_epi64(m6, m0); \
-} while(0)
-
-
-#define LOAD_MSG_10_1(b0, b1) \
-do \
-{ \
-b0 = _mm_unpacklo_epi64(m0, m1); \
-b1 = _mm_unpacklo_epi64(m2, m3); \
-} while(0)
-
-
-#define LOAD_MSG_10_2(b0, b1) \
-do \
-{ \
-b0 = _mm_unpackhi_epi64(m0, m1); \
-b1 = _mm_unpackhi_epi64(m2, m3); \
-} while(0)
-
-
-#define LOAD_MSG_10_3(b0, b1) \
-do \
-{ \
-b0 = _mm_unpacklo_epi64(m4, m5); \
-b1 = _mm_unpacklo_epi64(m6, m7); \
-} while(0)
-
-
-#define LOAD_MSG_10_4(b0, b1) \
-do \
-{ \
-b0 = _mm_unpackhi_epi64(m4, m5); \
-b1 = _mm_unpackhi_epi64(m6, m7); \
-} while(0)
-
-
-#define LOAD_MSG_11_1(b0, b1) \
-do \
-{ \
-b0 = _mm_unpacklo_epi64(m7, m2); \
-b1 = _mm_unpackhi_epi64(m4, m6); \
-} while(0)
-
-
-#define LOAD_MSG_11_2(b0, b1) \
-do \
-{ \
-b0 = _mm_unpacklo_epi64(m5, m4); \
-b1 = _mm_alignr_epi8(m3, m7, 8); \
-} while(0)
-
-
-#define LOAD_MSG_11_3(b0, b1) \
-do \
-{ \
-b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1,0,3,2)); \
-b1 = _mm_unpackhi_epi64(m5, m2); \
-} while(0)
-
-
-#define LOAD_MSG_11_4(b0, b1) \
-do \
-{ \
-b0 = _mm_unpacklo_epi64(m6, m1); \
-b1 = _mm_unpackhi_epi64(m3, m1); \
-} while(0)
-
-
-#endif
-
diff --git a/contrib/libs/blake2/src/blake2b-ref.c b/contrib/libs/blake2/src/blake2b-ref.c
deleted file mode 100644
index 4d40764d0e..0000000000
--- a/contrib/libs/blake2/src/blake2b-ref.c
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- BLAKE2 reference source code package - reference C implementations
-
- Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
-
- To the extent possible under law, the author(s) have dedicated all copyright
- and related and neighboring rights to this software to the public domain
- worldwide. This software is distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along with
- this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
-*/
-
-#include <stdint.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "blake2.h"
-#include "blake2-impl.h"
-
-static const uint64_t blake2b_IV[8] =
-{
- 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
- 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
- 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
- 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
-};
-
-static const uint8_t blake2b_sigma[12][16] =
-{
- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
- { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
- { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
- { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
- { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
- { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
- { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
- { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
- { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
- { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
- { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
-};
-
-
-static inline int blake2b_set_lastnode( blake2b_state *S )
-{
- S->f[1] = ~0ULL;
- return 0;
-}
-
-static inline int blake2b_clear_lastnode( blake2b_state *S )
-{
- S->f[1] = 0ULL;
- return 0;
-}
-
-/* Some helper functions, not necessarily useful */
-static inline int blake2b_set_lastblock( blake2b_state *S )
-{
- if( S->last_node ) blake2b_set_lastnode( S );
-
- S->f[0] = ~0ULL;
- return 0;
-}
-
-static inline int blake2b_clear_lastblock( blake2b_state *S )
-{
- if( S->last_node ) blake2b_clear_lastnode( S );
-
- S->f[0] = 0ULL;
- return 0;
-}
-
-static inline int blake2b_increment_counter( blake2b_state *S, const uint64_t inc )
-{
- S->t[0] += inc;
- S->t[1] += ( S->t[0] < inc );
- return 0;
-}
-
-
-
-// Parameter-related functions
-static inline int blake2b_param_set_digest_length( blake2b_param *P, const uint8_t digest_length )
-{
- P->digest_length = digest_length;
- return 0;
-}
-
-static inline int blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout )
-{
- P->fanout = fanout;
- return 0;
-}
-
-static inline int blake2b_param_set_max_depth( blake2b_param *P, const uint8_t depth )
-{
- P->depth = depth;
- return 0;
-}
-
-static inline int blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length )
-{
- store32( &P->leaf_length, leaf_length );
- return 0;
-}
-
-static inline int blake2b_param_set_node_offset( blake2b_param *P, const uint64_t node_offset )
-{
- store64( &P->node_offset, node_offset );
- return 0;
-}
-
-static inline int blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth )
-{
- P->node_depth = node_depth;
- return 0;
-}
-
-static inline int blake2b_param_set_inner_length( blake2b_param *P, const uint8_t inner_length )
-{
- P->inner_length = inner_length;
- return 0;
-}
-
-static inline int blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] )
-{
- memcpy( P->salt, salt, BLAKE2B_SALTBYTES );
- return 0;
-}
-
-static inline int blake2b_param_set_personal( blake2b_param *P, const uint8_t personal[BLAKE2B_PERSONALBYTES] )
-{
- memcpy( P->personal, personal, BLAKE2B_PERSONALBYTES );
- return 0;
-}
-
-static inline int blake2b_init0( blake2b_state *S )
-{
- memset( S, 0, sizeof( blake2b_state ) );
-
- for( int i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
-
- return 0;
-}
-
-#define blake2b_init BLAKE2_IMPL_NAME(blake2b_init)
-#define blake2b_init_param BLAKE2_IMPL_NAME(blake2b_init_param)
-#define blake2b_init_key BLAKE2_IMPL_NAME(blake2b_init_key)
-#define blake2b_update BLAKE2_IMPL_NAME(blake2b_update)
-#define blake2b_final BLAKE2_IMPL_NAME(blake2b_final)
-#define blake2b BLAKE2_IMPL_NAME(blake2b)
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
- int blake2b_init( blake2b_state *S, size_t outlen );
- int blake2b_init_param( blake2b_state *S, const blake2b_param *P );
- int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
- int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen );
- int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen );
- int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
-#if defined(__cplusplus)
-}
-#endif
-
-/* init xors IV with input parameter block */
-int blake2b_init_param( blake2b_state *S, const blake2b_param *P )
-{
- blake2b_init0( S );
- uint8_t *p = ( uint8_t * )( P );
-
- /* IV XOR ParamBlock */
- for( size_t i = 0; i < 8; ++i )
- S->h[i] ^= load64( p + sizeof( S->h[i] ) * i );
-
- S->outlen = P->digest_length;
- return 0;
-}
-
-
-
-int blake2b_init( blake2b_state *S, size_t outlen )
-{
- blake2b_param P[1];
-
- if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
-
- P->digest_length = ( uint8_t ) outlen;
- P->key_length = 0;
- P->fanout = 1;
- P->depth = 1;
- store32( &P->leaf_length, 0 );
- store64( &P->node_offset, 0 );
- P->node_depth = 0;
- P->inner_length = 0;
- memset( P->reserved, 0, sizeof( P->reserved ) );
- memset( P->salt, 0, sizeof( P->salt ) );
- memset( P->personal, 0, sizeof( P->personal ) );
- return blake2b_init_param( S, P );
-}
-
-
-int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen )
-{
- blake2b_param P[1];
-
- if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
-
- if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;
-
- P->digest_length = ( uint8_t ) outlen;
- P->key_length = ( uint8_t ) keylen;
- P->fanout = 1;
- P->depth = 1;
- store32( &P->leaf_length, 0 );
- store64( &P->node_offset, 0 );
- P->node_depth = 0;
- P->inner_length = 0;
- memset( P->reserved, 0, sizeof( P->reserved ) );
- memset( P->salt, 0, sizeof( P->salt ) );
- memset( P->personal, 0, sizeof( P->personal ) );
-
- if( blake2b_init_param( S, P ) < 0 ) return -1;
-
- {
- uint8_t block[BLAKE2B_BLOCKBYTES];
- memset( block, 0, BLAKE2B_BLOCKBYTES );
- memcpy( block, key, keylen );
- blake2b_update( S, block, BLAKE2B_BLOCKBYTES );
- secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
- }
- return 0;
-}
-
-static int blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] )
-{
- uint64_t m[16];
- uint64_t v[16];
- size_t i;
-
- for( i = 0; i < 16; ++i )
- m[i] = load64( block + i * sizeof( m[i] ) );
-
- for( i = 0; i < 8; ++i )
- v[i] = S->h[i];
-
- v[ 8] = blake2b_IV[0];
- v[ 9] = blake2b_IV[1];
- v[10] = blake2b_IV[2];
- v[11] = blake2b_IV[3];
- v[12] = S->t[0] ^ blake2b_IV[4];
- v[13] = S->t[1] ^ blake2b_IV[5];
- v[14] = S->f[0] ^ blake2b_IV[6];
- v[15] = S->f[1] ^ blake2b_IV[7];
-#define G(r,i,a,b,c,d) \
- do { \
- a = a + b + m[blake2b_sigma[r][2*i+0]]; \
- d = rotr64(d ^ a, 32); \
- c = c + d; \
- b = rotr64(b ^ c, 24); \
- a = a + b + m[blake2b_sigma[r][2*i+1]]; \
- d = rotr64(d ^ a, 16); \
- c = c + d; \
- b = rotr64(b ^ c, 63); \
- } while(0)
-#define ROUND(r) \
- do { \
- G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
- G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
- G(r,2,v[ 2],v[ 6],v[10],v[14]); \
- G(r,3,v[ 3],v[ 7],v[11],v[15]); \
- G(r,4,v[ 0],v[ 5],v[10],v[15]); \
- G(r,5,v[ 1],v[ 6],v[11],v[12]); \
- G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
- G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
- } while(0)
- ROUND( 0 );
- ROUND( 1 );
- ROUND( 2 );
- ROUND( 3 );
- ROUND( 4 );
- ROUND( 5 );
- ROUND( 6 );
- ROUND( 7 );
- ROUND( 8 );
- ROUND( 9 );
- ROUND( 10 );
- ROUND( 11 );
-
- for( i = 0; i < 8; ++i )
- S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
-
-#undef G
-#undef ROUND
- return 0;
-}
-
-
-int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen )
-{
- while( inlen > 0 )
- {
- uint32_t left = S->buflen;
- uint32_t fill = 2 * BLAKE2B_BLOCKBYTES - left;
-
- if( inlen > fill )
- {
- memcpy( S->buf + left, in, fill ); // Fill buffer
- S->buflen += fill;
- blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
- blake2b_compress( S, S->buf ); // Compress
- memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); // Shift buffer left
- S->buflen -= BLAKE2B_BLOCKBYTES;
- in += fill;
- inlen -= fill;
- }
- else // inlen <= fill
- {
- memcpy( S->buf + left, in, inlen );
- S->buflen += ( uint32_t ) inlen; // Be lazy, do not compress
- in += inlen;
- inlen -= inlen;
- }
- }
-
- return 0;
-}
-
-int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen )
-{
- uint8_t buffer[BLAKE2B_OUTBYTES];
- size_t i;
-
- if(S->outlen != outlen) return -1;
-
- if( S->buflen > BLAKE2B_BLOCKBYTES )
- {
- blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
- blake2b_compress( S, S->buf );
- S->buflen -= BLAKE2B_BLOCKBYTES;
- memmove( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen );
- }
-
- blake2b_increment_counter( S, S->buflen );
- blake2b_set_lastblock( S );
- memset( S->buf + S->buflen, 0, 2 * BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */
- blake2b_compress( S, S->buf );
-
- for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
- store64( buffer + sizeof( S->h[i] ) * i, S->h[i] );
-
- memcpy( out, buffer, outlen );
- return 0;
-}
-
-int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
-{
- blake2b_state S[1];
-
- /* Verify parameters */
- if ( NULL == in && inlen > 0 ) return -1;
-
- if ( NULL == out ) return -1;
-
- if( NULL == key && keylen > 0 ) return -1;
-
- if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;
-
- if( keylen > BLAKE2B_KEYBYTES ) return -1;
-
- if( keylen > 0 )
- {
- if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1;
- }
- else
- {
- if( blake2b_init( S, outlen ) < 0 ) return -1;
- }
-
- if( blake2b_update( S, ( uint8_t * )in, inlen ) < 0 ) return -1;
- return blake2b_final( S, out, outlen );
-}
-
-
diff --git a/contrib/libs/blake2/src/blake2b-round.h b/contrib/libs/blake2/src/blake2b-round.h
deleted file mode 100644
index cebc22550d..0000000000
--- a/contrib/libs/blake2/src/blake2b-round.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- BLAKE2 reference source code package - optimized C implementations
-
- Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
-
- To the extent possible under law, the author(s) have dedicated all copyright
- and related and neighboring rights to this software to the public domain
- worldwide. This software is distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along with
- this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
-*/
-#pragma once
-#ifndef __BLAKE2B_ROUND_H__
-#define __BLAKE2B_ROUND_H__
-
-#define LOAD(p) _mm_load_si128( (__m128i *)(p) )
-#define STORE(p,r) _mm_store_si128((__m128i *)(p), r)
-
-#define LOADU(p) _mm_loadu_si128( (__m128i *)(p) )
-#define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r)
-
-#define TOF(reg) _mm_castsi128_ps((reg))
-#define TOI(reg) _mm_castps_si128((reg))
-
-#define LIKELY(x) __builtin_expect((x),1)
-
-
-/* Microarchitecture-specific macros */
-#ifndef HAVE_XOP
-#ifdef HAVE_SSSE3
-#define _mm_roti_epi64(x, c) \
- (-(c) == 32) ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2,3,0,1)) \
- : (-(c) == 24) ? _mm_shuffle_epi8((x), r24) \
- : (-(c) == 16) ? _mm_shuffle_epi8((x), r16) \
- : (-(c) == 63) ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_add_epi64((x), (x))) \
- : _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_slli_epi64((x), 64-(-(c))))
-#else
-#define _mm_roti_epi64(r, c) _mm_xor_si128(_mm_srli_epi64( (r), -(c) ),_mm_slli_epi64( (r), 64-(-(c)) ))
-#endif
-#else
-/* ... */
-#endif
-
-
-
-#define G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \
- row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \
- row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \
- \
- row4l = _mm_xor_si128(row4l, row1l); \
- row4h = _mm_xor_si128(row4h, row1h); \
- \
- row4l = _mm_roti_epi64(row4l, -32); \
- row4h = _mm_roti_epi64(row4h, -32); \
- \
- row3l = _mm_add_epi64(row3l, row4l); \
- row3h = _mm_add_epi64(row3h, row4h); \
- \
- row2l = _mm_xor_si128(row2l, row3l); \
- row2h = _mm_xor_si128(row2h, row3h); \
- \
- row2l = _mm_roti_epi64(row2l, -24); \
- row2h = _mm_roti_epi64(row2h, -24); \
-
-#define G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \
- row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \
- row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \
- \
- row4l = _mm_xor_si128(row4l, row1l); \
- row4h = _mm_xor_si128(row4h, row1h); \
- \
- row4l = _mm_roti_epi64(row4l, -16); \
- row4h = _mm_roti_epi64(row4h, -16); \
- \
- row3l = _mm_add_epi64(row3l, row4l); \
- row3h = _mm_add_epi64(row3h, row4h); \
- \
- row2l = _mm_xor_si128(row2l, row3l); \
- row2h = _mm_xor_si128(row2h, row3h); \
- \
- row2l = _mm_roti_epi64(row2l, -63); \
- row2h = _mm_roti_epi64(row2h, -63); \
-
-#if defined(HAVE_SSSE3)
-#define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
- t0 = _mm_alignr_epi8(row2h, row2l, 8); \
- t1 = _mm_alignr_epi8(row2l, row2h, 8); \
- row2l = t0; \
- row2h = t1; \
- \
- t0 = row3l; \
- row3l = row3h; \
- row3h = t0; \
- \
- t0 = _mm_alignr_epi8(row4h, row4l, 8); \
- t1 = _mm_alignr_epi8(row4l, row4h, 8); \
- row4l = t1; \
- row4h = t0;
-
-#define UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
- t0 = _mm_alignr_epi8(row2l, row2h, 8); \
- t1 = _mm_alignr_epi8(row2h, row2l, 8); \
- row2l = t0; \
- row2h = t1; \
- \
- t0 = row3l; \
- row3l = row3h; \
- row3h = t0; \
- \
- t0 = _mm_alignr_epi8(row4l, row4h, 8); \
- t1 = _mm_alignr_epi8(row4h, row4l, 8); \
- row4l = t1; \
- row4h = t0;
-#else
-
-#define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
- t0 = row4l;\
- t1 = row2l;\
- row4l = row3l;\
- row3l = row3h;\
- row3h = row4l;\
- row4l = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t0, t0)); \
- row4h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row4h, row4h)); \
- row2l = _mm_unpackhi_epi64(row2l, _mm_unpacklo_epi64(row2h, row2h)); \
- row2h = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(t1, t1))
-
-#define UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
- t0 = row3l;\
- row3l = row3h;\
- row3h = t0;\
- t0 = row2l;\
- t1 = row4l;\
- row2l = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(row2l, row2l)); \
- row2h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row2h, row2h)); \
- row4l = _mm_unpackhi_epi64(row4l, _mm_unpacklo_epi64(row4h, row4h)); \
- row4h = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t1, t1))
-
-#endif
-
-#if defined(HAVE_SSE4_1)
-#include "blake2b-load-sse41.h"
-#else
-#include "blake2b-load-sse2.h"
-#endif
-
-#define ROUND(r) \
- LOAD_MSG_ ##r ##_1(b0, b1); \
- G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \
- LOAD_MSG_ ##r ##_2(b0, b1); \
- G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \
- DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \
- LOAD_MSG_ ##r ##_3(b0, b1); \
- G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \
- LOAD_MSG_ ##r ##_4(b0, b1); \
- G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \
- UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h);
-
-#endif
-
diff --git a/contrib/libs/blake2/src/blake2b.c b/contrib/libs/blake2/src/blake2b.c
deleted file mode 100644
index 6ac57f24c0..0000000000
--- a/contrib/libs/blake2/src/blake2b.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- BLAKE2 reference source code package - optimized C implementations
-
- Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
-
- To the extent possible under law, the author(s) have dedicated all copyright
- and related and neighboring rights to this software to the public domain
- worldwide. This software is distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along with
- this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
-*/
-
-#include <stdint.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "blake2.h"
-#include "blake2-impl.h"
-
-#include "blake2-config.h"
-
-#if defined(_MSC_VER)
-#include <intrin.h>
-#endif
-
-#if defined(HAVE_SSE2)
-#include <emmintrin.h>
-// MSVC only defines _mm_set_epi64x for x86_64...
-#if defined(_MSC_VER) && !defined(_M_X64) && !defined(__clang__)
-static inline __m128i _mm_set_epi64x( const uint64_t u1, const uint64_t u0 )
-{
- return _mm_set_epi32( u1 >> 32, u1, u0 >> 32, u0 );
-}
-#endif
-#endif
-
-#if defined(HAVE_SSSE3)
-#include <tmmintrin.h>
-#endif
-#if defined(HAVE_SSE4_1)
-#include <smmintrin.h>
-#endif
-#if defined(HAVE_AVX)
-#include <immintrin.h>
-#endif
-#if defined(HAVE_XOP) && !defined(_MSC_VER)
-#include <x86intrin.h>
-#endif
-
-
-
-#include "blake2b-round.h"
-
-static const uint64_t blake2b_IV[8] =
-{
- 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
- 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
- 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
- 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
-};
-
-static const uint8_t blake2b_sigma[12][16] =
-{
- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
- { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
- { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
- { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
- { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
- { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
- { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
- { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
- { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
- { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
- { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
-};
-
-
-/* Some helper functions, not necessarily useful */
-static inline int blake2b_set_lastnode( blake2b_state *S )
-{
- S->f[1] = ~0ULL;
- return 0;
-}
-
-static inline int blake2b_clear_lastnode( blake2b_state *S )
-{
- S->f[1] = 0ULL;
- return 0;
-}
-
-static inline int blake2b_set_lastblock( blake2b_state *S )
-{
- if( S->last_node ) blake2b_set_lastnode( S );
-
- S->f[0] = ~0ULL;
- return 0;
-}
-
-static inline int blake2b_clear_lastblock( blake2b_state *S )
-{
- if( S->last_node ) blake2b_clear_lastnode( S );
-
- S->f[0] = 0ULL;
- return 0;
-}
-
-
-static inline int blake2b_increment_counter( blake2b_state *S, const uint64_t inc )
-{
-#if defined(__x86_64__) && (defined(__GNUC__) || defined(__clang__))
- // ADD/ADC chain
- __uint128_t t = ( ( __uint128_t )S->t[1] << 64 ) | S->t[0];
- t += inc;
- S->t[0] = ( uint64_t )( t >> 0 );
- S->t[1] = ( uint64_t )( t >> 64 );
-#else
- S->t[0] += inc;
- S->t[1] += ( S->t[0] < inc );
-#endif
- return 0;
-}
-
-
-// Parameter-related functions
-static inline int blake2b_param_set_digest_length( blake2b_param *P, const uint8_t digest_length )
-{
- P->digest_length = digest_length;
- return 0;
-}
-
-static inline int blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout )
-{
- P->fanout = fanout;
- return 0;
-}
-
-static inline int blake2b_param_set_max_depth( blake2b_param *P, const uint8_t depth )
-{
- P->depth = depth;
- return 0;
-}
-
-static inline int blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length )
-{
- P->leaf_length = leaf_length;
- return 0;
-}
-
-static inline int blake2b_param_set_node_offset( blake2b_param *P, const uint64_t node_offset )
-{
- P->node_offset = node_offset;
- return 0;
-}
-
-static inline int blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth )
-{
- P->node_depth = node_depth;
- return 0;
-}
-
-static inline int blake2b_param_set_inner_length( blake2b_param *P, const uint8_t inner_length )
-{
- P->inner_length = inner_length;
- return 0;
-}
-
-static inline int blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] )
-{
- memcpy( P->salt, salt, BLAKE2B_SALTBYTES );
- return 0;
-}
-
-static inline int blake2b_param_set_personal( blake2b_param *P, const uint8_t personal[BLAKE2B_PERSONALBYTES] )
-{
- memcpy( P->personal, personal, BLAKE2B_PERSONALBYTES );
- return 0;
-}
-
-static inline int blake2b_init0( blake2b_state *S )
-{
- memset( S, 0, sizeof( blake2b_state ) );
-
- for( int i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
-
- return 0;
-}
-
-
-
-#define blake2b_init BLAKE2_IMPL_NAME(blake2b_init)
-#define blake2b_init_param BLAKE2_IMPL_NAME(blake2b_init_param)
-#define blake2b_init_key BLAKE2_IMPL_NAME(blake2b_init_key)
-#define blake2b_update BLAKE2_IMPL_NAME(blake2b_update)
-#define blake2b_final BLAKE2_IMPL_NAME(blake2b_final)
-#define blake2b BLAKE2_IMPL_NAME(blake2b)
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
- int blake2b_init( blake2b_state *S, size_t outlen );
- int blake2b_init_param( blake2b_state *S, const blake2b_param *P );
- int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
- int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen );
- int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen );
- int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
-#if defined(__cplusplus)
-}
-#endif
-
-/* init xors IV with input parameter block */
-int blake2b_init_param( blake2b_state *S, const blake2b_param *P )
-{
- uint8_t *p, *h, *v;
- //blake2b_init0( S );
- v = ( uint8_t * )( blake2b_IV );
- h = ( uint8_t * )( S->h );
- p = ( uint8_t * )( P );
- /* IV XOR ParamBlock */
- memset( S, 0, sizeof( blake2b_state ) );
-
- for( int i = 0; i < BLAKE2B_OUTBYTES; ++i ) h[i] = v[i] ^ p[i];
-
- S->outlen = P->digest_length;
- return 0;
-}
-
-
-/* Some sort of default parameter block initialization, for sequential blake2b */
-
-int blake2b_init( blake2b_state *S, size_t outlen )
-{
- if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
-
- const blake2b_param P =
- {
- ( uint8_t ) outlen,
- 0,
- 1,
- 1,
- 0,
- 0,
- 0,
- 0,
- {0},
- {0},
- {0}
- };
- return blake2b_init_param( S, &P );
-}
-
-int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen )
-{
- if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
-
- if ( ( !keylen ) || keylen > BLAKE2B_KEYBYTES ) return -1;
-
- const blake2b_param P =
- {
- ( uint8_t ) outlen,
- ( uint8_t ) keylen,
- 1,
- 1,
- 0,
- 0,
- 0,
- 0,
- {0},
- {0},
- {0}
- };
-
- if( blake2b_init_param( S, &P ) < 0 )
- return 0;
-
- {
- uint8_t block[BLAKE2B_BLOCKBYTES];
- memset( block, 0, BLAKE2B_BLOCKBYTES );
- memcpy( block, key, keylen );
- blake2b_update( S, block, BLAKE2B_BLOCKBYTES );
- secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
- }
- return 0;
-}
-
-static inline int blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] )
-{
- __m128i row1l, row1h;
- __m128i row2l, row2h;
- __m128i row3l, row3h;
- __m128i row4l, row4h;
- __m128i b0, b1;
- __m128i t0, t1;
-#if defined(HAVE_SSSE3) && !defined(HAVE_XOP)
- const __m128i r16 = _mm_setr_epi8( 2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9 );
- const __m128i r24 = _mm_setr_epi8( 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10 );
-#endif
-#if defined(HAVE_SSE4_1)
- const __m128i m0 = LOADU( block + 00 );
- const __m128i m1 = LOADU( block + 16 );
- const __m128i m2 = LOADU( block + 32 );
- const __m128i m3 = LOADU( block + 48 );
- const __m128i m4 = LOADU( block + 64 );
- const __m128i m5 = LOADU( block + 80 );
- const __m128i m6 = LOADU( block + 96 );
- const __m128i m7 = LOADU( block + 112 );
-#else
- const uint64_t m0 = ( ( uint64_t * )block )[ 0];
- const uint64_t m1 = ( ( uint64_t * )block )[ 1];
- const uint64_t m2 = ( ( uint64_t * )block )[ 2];
- const uint64_t m3 = ( ( uint64_t * )block )[ 3];
- const uint64_t m4 = ( ( uint64_t * )block )[ 4];
- const uint64_t m5 = ( ( uint64_t * )block )[ 5];
- const uint64_t m6 = ( ( uint64_t * )block )[ 6];
- const uint64_t m7 = ( ( uint64_t * )block )[ 7];
- const uint64_t m8 = ( ( uint64_t * )block )[ 8];
- const uint64_t m9 = ( ( uint64_t * )block )[ 9];
- const uint64_t m10 = ( ( uint64_t * )block )[10];
- const uint64_t m11 = ( ( uint64_t * )block )[11];
- const uint64_t m12 = ( ( uint64_t * )block )[12];
- const uint64_t m13 = ( ( uint64_t * )block )[13];
- const uint64_t m14 = ( ( uint64_t * )block )[14];
- const uint64_t m15 = ( ( uint64_t * )block )[15];
-#endif
- row1l = LOADU( &S->h[0] );
- row1h = LOADU( &S->h[2] );
- row2l = LOADU( &S->h[4] );
- row2h = LOADU( &S->h[6] );
- row3l = LOADU( &blake2b_IV[0] );
- row3h = LOADU( &blake2b_IV[2] );
- row4l = _mm_xor_si128( LOADU( &blake2b_IV[4] ), LOADU( &S->t[0] ) );
- row4h = _mm_xor_si128( LOADU( &blake2b_IV[6] ), LOADU( &S->f[0] ) );
- ROUND( 0 );
- ROUND( 1 );
- ROUND( 2 );
- ROUND( 3 );
- ROUND( 4 );
- ROUND( 5 );
- ROUND( 6 );
- ROUND( 7 );
- ROUND( 8 );
- ROUND( 9 );
- ROUND( 10 );
- ROUND( 11 );
- row1l = _mm_xor_si128( row3l, row1l );
- row1h = _mm_xor_si128( row3h, row1h );
- STOREU( &S->h[0], _mm_xor_si128( LOADU( &S->h[0] ), row1l ) );
- STOREU( &S->h[2], _mm_xor_si128( LOADU( &S->h[2] ), row1h ) );
- row2l = _mm_xor_si128( row4l, row2l );
- row2h = _mm_xor_si128( row4h, row2h );
- STOREU( &S->h[4], _mm_xor_si128( LOADU( &S->h[4] ), row2l ) );
- STOREU( &S->h[6], _mm_xor_si128( LOADU( &S->h[6] ), row2h ) );
- return 0;
-}
-
-
-int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen )
-{
- while( inlen > 0 )
- {
- uint32_t left = S->buflen;
- uint32_t fill = 2 * BLAKE2B_BLOCKBYTES - left;
-
- if( inlen > fill )
- {
- memcpy( S->buf + left, in, fill ); // Fill buffer
- S->buflen += fill;
- blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
- blake2b_compress( S, S->buf ); // Compress
- memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); // Shift buffer left
- S->buflen -= BLAKE2B_BLOCKBYTES;
- in += fill;
- inlen -= fill;
- }
- else // inlen <= fill
- {
- memcpy( S->buf + left, in, inlen );
- S->buflen += ( uint32_t ) inlen; // Be lazy, do not compress
- in += inlen;
- inlen -= inlen;
- }
- }
-
- return 0;
-}
-
-
-int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen )
-{
- if(S->outlen != outlen) return -1;
-
- if( S->buflen > BLAKE2B_BLOCKBYTES )
- {
- blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
- blake2b_compress( S, S->buf );
- S->buflen -= BLAKE2B_BLOCKBYTES;
- memmove( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen );
- }
-
- blake2b_increment_counter( S, S->buflen );
- blake2b_set_lastblock( S );
- memset( S->buf + S->buflen, 0, 2 * BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */
- blake2b_compress( S, S->buf );
- memcpy( out, &S->h[0], outlen );
- return 0;
-}
-
-
-int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
-{
- blake2b_state S[1];
-
- /* Verify parameters */
- if ( NULL == in && inlen > 0 ) return -1;
-
- if ( NULL == out ) return -1;
-
- if( NULL == key && keylen > 0 ) return -1;
-
- if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;
-
- if( keylen > BLAKE2B_KEYBYTES ) return -1;
-
- if( keylen )
- {
- if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1;
- }
- else
- {
- if( blake2b_init( S, outlen ) < 0 ) return -1;
- }
-
- if( blake2b_update( S, ( uint8_t * )in, inlen ) < 0) return -1;
- return blake2b_final( S, out, outlen );
-}
-
-#if defined(SUPERCOP)
-int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )
-{
- return blake2b( out, in, NULL, BLAKE2B_OUTBYTES, inlen, 0 );
-}
-#endif
diff --git a/contrib/libs/blake2/src/blake2bp.c b/contrib/libs/blake2/src/blake2bp.c
deleted file mode 100644
index 4522161171..0000000000
--- a/contrib/libs/blake2/src/blake2bp.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- BLAKE2 reference source code package - optimized C implementations
-
- Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
-
- To the extent possible under law, the author(s) have dedicated all copyright
- and related and neighboring rights to this software to the public domain
- worldwide. This software is distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along with
- this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-
-#if defined(_OPENMP)
-#include <omp.h>
-#endif
-
-#include "blake2.h"
-#include "blake2-impl.h"
-
-#define PARALLELISM_DEGREE 4
-
-static int blake2bp_init_leaf( blake2b_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset )
-{
- blake2b_param P[1];
- P->digest_length = outlen;
- P->key_length = keylen;
- P->fanout = PARALLELISM_DEGREE;
- P->depth = 2;
- store32(&P->leaf_length, 0);
- store64(&P->node_offset, offset);
- P->node_depth = 0;
- P->inner_length = BLAKE2B_OUTBYTES;
- memset( P->reserved, 0, sizeof( P->reserved ) );
- memset( P->salt, 0, sizeof( P->salt ) );
- memset( P->personal, 0, sizeof( P->personal ) );
- blake2b_init_param( S, P );
- S->outlen = P->inner_length;
- return 0;
-}
-
-static int blake2bp_init_root( blake2b_state *S, uint8_t outlen, uint8_t keylen )
-{
- blake2b_param P[1];
- P->digest_length = outlen;
- P->key_length = keylen;
- P->fanout = PARALLELISM_DEGREE;
- P->depth = 2;
- store32(&P->leaf_length, 0);
- store64(&P->node_offset, 0);
- P->node_depth = 1;
- P->inner_length = BLAKE2B_OUTBYTES;
- memset( P->reserved, 0, sizeof( P->reserved ) );
- memset( P->salt, 0, sizeof( P->salt ) );
- memset( P->personal, 0, sizeof( P->personal ) );
- blake2b_init_param( S, P );
- S->outlen = P->digest_length;
- return 0;
-}
-
-
-int blake2bp_init( blake2bp_state *S, size_t outlen )
-{
- if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;
-
- memset( S->buf, 0, sizeof( S->buf ) );
- S->buflen = 0;
-
- if( blake2bp_init_root( S->R, ( uint8_t ) outlen, 0 ) < 0 )
- return -1;
-
- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
- if( blake2bp_init_leaf( S->S[i], ( uint8_t ) outlen, 0, i ) < 0 ) return -1;
-
- S->R->last_node = 1;
- S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
- S->outlen = ( uint8_t ) outlen;
- return 0;
-}
-
-int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen )
-{
- if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;
-
- if( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;
-
- memset( S->buf, 0, sizeof( S->buf ) );
- S->buflen = 0;
-
- if( blake2bp_init_root( S->R, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 )
- return -1;
-
- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
- if( blake2bp_init_leaf( S->S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 )
- return -1;
-
- S->R->last_node = 1;
- S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
- S->outlen = ( uint8_t ) outlen;
- {
- uint8_t block[BLAKE2B_BLOCKBYTES];
- memset( block, 0, BLAKE2B_BLOCKBYTES );
- memcpy( block, key, keylen );
-
- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
- blake2b_update( S->S[i], block, BLAKE2B_BLOCKBYTES );
-
- secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
- }
- return 0;
-}
-
-
-int blake2bp_update( blake2bp_state *S, const uint8_t *in, size_t inlen )
-{
- size_t left = S->buflen;
- size_t fill = sizeof( S->buf ) - left;
-
- if( left && inlen >= fill )
- {
- memcpy( S->buf + left, in, fill );
-
- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
- blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES );
-
- in += fill;
- inlen -= fill;
- left = 0;
- }
-
-#if defined(_OPENMP)
- omp_set_num_threads(PARALLELISM_DEGREE);
- #pragma omp parallel shared(S)
-#else
- for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
-#endif
- {
-#if defined(_OPENMP)
- size_t id__ = ( size_t ) omp_get_thread_num();
-#endif
- size_t inlen__ = inlen;
- const uint8_t *in__ = ( const uint8_t * )in;
- in__ += id__ * BLAKE2B_BLOCKBYTES;
-
- while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES )
- {
- blake2b_update( S->S[id__], in__, BLAKE2B_BLOCKBYTES );
- in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
- inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
- }
- }
-
- in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES );
- inlen %= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
-
- if( inlen > 0 )
- memcpy( S->buf + left, in, inlen );
-
- S->buflen = ( uint32_t ) left + ( uint32_t ) inlen;
- return 0;
-}
-
-
-
-int blake2bp_final( blake2bp_state *S, uint8_t *out, size_t outlen )
-{
- uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES];
-
- if(S->outlen != outlen) return -1;
-
- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
- {
- if( S->buflen > i * BLAKE2B_BLOCKBYTES )
- {
- size_t left = S->buflen - i * BLAKE2B_BLOCKBYTES;
-
- if( left > BLAKE2B_BLOCKBYTES ) left = BLAKE2B_BLOCKBYTES;
-
- blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, left );
- }
-
- blake2b_final( S->S[i], hash[i], BLAKE2B_OUTBYTES );
- }
-
- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
- blake2b_update( S->R, hash[i], BLAKE2B_OUTBYTES );
-
- return blake2b_final( S->R, out, outlen );
-}
-
-int blake2bp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
-{
- uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES];
- blake2b_state S[PARALLELISM_DEGREE][1];
- blake2b_state FS[1];
-
- /* Verify parameters */
- if ( NULL == in && inlen > 0 ) return -1;
-
- if ( NULL == out ) return -1;
-
- if ( NULL == key && keylen > 0) return -1;
-
- if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;
-
- if( keylen > BLAKE2B_KEYBYTES ) return -1;
-
- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
- if( blake2bp_init_leaf( S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 )
- return -1;
-
- S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node
-
- if( keylen > 0 )
- {
- uint8_t block[BLAKE2B_BLOCKBYTES];
- memset( block, 0, BLAKE2B_BLOCKBYTES );
- memcpy( block, key, keylen );
-
- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
- blake2b_update( S[i], block, BLAKE2B_BLOCKBYTES );
-
- secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
- }
-
-#if defined(_OPENMP)
- omp_set_num_threads(PARALLELISM_DEGREE);
- #pragma omp parallel shared(S,hash)
-#else
- for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
-#endif
- {
-#if defined(_OPENMP)
- size_t id__ = ( size_t ) omp_get_thread_num();
-#endif
- size_t inlen__ = inlen;
- const uint8_t *in__ = ( const uint8_t * )in;
- in__ += id__ * BLAKE2B_BLOCKBYTES;
-
- while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES )
- {
- blake2b_update( S[id__], in__, BLAKE2B_BLOCKBYTES );
- in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
- inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
- }
-
- if( inlen__ > id__ * BLAKE2B_BLOCKBYTES )
- {
- const size_t left = inlen__ - id__ * BLAKE2B_BLOCKBYTES;
- const size_t len = left <= BLAKE2B_BLOCKBYTES ? left : BLAKE2B_BLOCKBYTES;
- blake2b_update( S[id__], in__, len );
- }
-
- blake2b_final( S[id__], hash[id__], BLAKE2B_OUTBYTES );
- }
-
- if( blake2bp_init_root( FS, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 )
- return -1;
-
- FS->last_node = 1; // Mark as last node
-
- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
- blake2b_update( FS, hash[i], BLAKE2B_OUTBYTES );
-
- return blake2b_final( FS, out, outlen );
-}
-
-
-
diff --git a/contrib/libs/blake2/src/blake2s-load-sse2.h b/contrib/libs/blake2/src/blake2s-load-sse2.h
deleted file mode 100644
index b24483cf93..0000000000
--- a/contrib/libs/blake2/src/blake2s-load-sse2.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- BLAKE2 reference source code package - optimized C implementations
-
- Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
-
- To the extent possible under law, the author(s) have dedicated all copyright
- and related and neighboring rights to this software to the public domain
- worldwide. This software is distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along with
- this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
-*/
-#pragma once
-#ifndef __BLAKE2S_LOAD_SSE2_H__
-#define __BLAKE2S_LOAD_SSE2_H__
-
-#define LOAD_MSG_0_1(buf) buf = _mm_set_epi32(m6,m4,m2,m0)
-#define LOAD_MSG_0_2(buf) buf = _mm_set_epi32(m7,m5,m3,m1)
-#define LOAD_MSG_0_3(buf) buf = _mm_set_epi32(m14,m12,m10,m8)
-#define LOAD_MSG_0_4(buf) buf = _mm_set_epi32(m15,m13,m11,m9)
-#define LOAD_MSG_1_1(buf) buf = _mm_set_epi32(m13,m9,m4,m14)
-#define LOAD_MSG_1_2(buf) buf = _mm_set_epi32(m6,m15,m8,m10)
-#define LOAD_MSG_1_3(buf) buf = _mm_set_epi32(m5,m11,m0,m1)
-#define LOAD_MSG_1_4(buf) buf = _mm_set_epi32(m3,m7,m2,m12)
-#define LOAD_MSG_2_1(buf) buf = _mm_set_epi32(m15,m5,m12,m11)
-#define LOAD_MSG_2_2(buf) buf = _mm_set_epi32(m13,m2,m0,m8)
-#define LOAD_MSG_2_3(buf) buf = _mm_set_epi32(m9,m7,m3,m10)
-#define LOAD_MSG_2_4(buf) buf = _mm_set_epi32(m4,m1,m6,m14)
-#define LOAD_MSG_3_1(buf) buf = _mm_set_epi32(m11,m13,m3,m7)
-#define LOAD_MSG_3_2(buf) buf = _mm_set_epi32(m14,m12,m1,m9)
-#define LOAD_MSG_3_3(buf) buf = _mm_set_epi32(m15,m4,m5,m2)
-#define LOAD_MSG_3_4(buf) buf = _mm_set_epi32(m8,m0,m10,m6)
-#define LOAD_MSG_4_1(buf) buf = _mm_set_epi32(m10,m2,m5,m9)
-#define LOAD_MSG_4_2(buf) buf = _mm_set_epi32(m15,m4,m7,m0)
-#define LOAD_MSG_4_3(buf) buf = _mm_set_epi32(m3,m6,m11,m14)
-#define LOAD_MSG_4_4(buf) buf = _mm_set_epi32(m13,m8,m12,m1)
-#define LOAD_MSG_5_1(buf) buf = _mm_set_epi32(m8,m0,m6,m2)
-#define LOAD_MSG_5_2(buf) buf = _mm_set_epi32(m3,m11,m10,m12)
-#define LOAD_MSG_5_3(buf) buf = _mm_set_epi32(m1,m15,m7,m4)
-#define LOAD_MSG_5_4(buf) buf = _mm_set_epi32(m9,m14,m5,m13)
-#define LOAD_MSG_6_1(buf) buf = _mm_set_epi32(m4,m14,m1,m12)
-#define LOAD_MSG_6_2(buf) buf = _mm_set_epi32(m10,m13,m15,m5)
-#define LOAD_MSG_6_3(buf) buf = _mm_set_epi32(m8,m9,m6,m0)
-#define LOAD_MSG_6_4(buf) buf = _mm_set_epi32(m11,m2,m3,m7)
-#define LOAD_MSG_7_1(buf) buf = _mm_set_epi32(m3,m12,m7,m13)
-#define LOAD_MSG_7_2(buf) buf = _mm_set_epi32(m9,m1,m14,m11)
-#define LOAD_MSG_7_3(buf) buf = _mm_set_epi32(m2,m8,m15,m5)
-#define LOAD_MSG_7_4(buf) buf = _mm_set_epi32(m10,m6,m4,m0)
-#define LOAD_MSG_8_1(buf) buf = _mm_set_epi32(m0,m11,m14,m6)
-#define LOAD_MSG_8_2(buf) buf = _mm_set_epi32(m8,m3,m9,m15)
-#define LOAD_MSG_8_3(buf) buf = _mm_set_epi32(m10,m1,m13,m12)
-#define LOAD_MSG_8_4(buf) buf = _mm_set_epi32(m5,m4,m7,m2)
-#define LOAD_MSG_9_1(buf) buf = _mm_set_epi32(m1,m7,m8,m10)
-#define LOAD_MSG_9_2(buf) buf = _mm_set_epi32(m5,m6,m4,m2)
-#define LOAD_MSG_9_3(buf) buf = _mm_set_epi32(m13,m3,m9,m15)
-#define LOAD_MSG_9_4(buf) buf = _mm_set_epi32(m0,m12,m14,m11)
-
-
-#endif
diff --git a/contrib/libs/blake2/src/blake2s-load-sse41.h b/contrib/libs/blake2/src/blake2s-load-sse41.h
deleted file mode 100644
index 3ac12eb6f5..0000000000
--- a/contrib/libs/blake2/src/blake2s-load-sse41.h
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- BLAKE2 reference source code package - optimized C implementations
-
- Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
-
- To the extent possible under law, the author(s) have dedicated all copyright
- and related and neighboring rights to this software to the public domain
- worldwide. This software is distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along with
- this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
-*/
-#pragma once
-#ifndef __BLAKE2S_LOAD_SSE41_H__
-#define __BLAKE2S_LOAD_SSE41_H__
-
-#define LOAD_MSG_0_1(buf) \
-buf = TOI(_mm_shuffle_ps(TOF(m0), TOF(m1), _MM_SHUFFLE(2,0,2,0)));
-
-#define LOAD_MSG_0_2(buf) \
-buf = TOI(_mm_shuffle_ps(TOF(m0), TOF(m1), _MM_SHUFFLE(3,1,3,1)));
-
-#define LOAD_MSG_0_3(buf) \
-buf = TOI(_mm_shuffle_ps(TOF(m2), TOF(m3), _MM_SHUFFLE(2,0,2,0)));
-
-#define LOAD_MSG_0_4(buf) \
-buf = TOI(_mm_shuffle_ps(TOF(m2), TOF(m3), _MM_SHUFFLE(3,1,3,1)));
-
-#define LOAD_MSG_1_1(buf) \
-t0 = _mm_blend_epi16(m1, m2, 0x0C); \
-t1 = _mm_slli_si128(m3, 4); \
-t2 = _mm_blend_epi16(t0, t1, 0xF0); \
-buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,0,3));
-
-#define LOAD_MSG_1_2(buf) \
-t0 = _mm_shuffle_epi32(m2,_MM_SHUFFLE(0,0,2,0)); \
-t1 = _mm_blend_epi16(m1,m3,0xC0); \
-t2 = _mm_blend_epi16(t0, t1, 0xF0); \
-buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1));
-
-#define LOAD_MSG_1_3(buf) \
-t0 = _mm_slli_si128(m1, 4); \
-t1 = _mm_blend_epi16(m2, t0, 0x30); \
-t2 = _mm_blend_epi16(m0, t1, 0xF0); \
-buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1));
-
-#define LOAD_MSG_1_4(buf) \
-t0 = _mm_unpackhi_epi32(m0,m1); \
-t1 = _mm_slli_si128(m3, 4); \
-t2 = _mm_blend_epi16(t0, t1, 0x0C); \
-buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1));
-
-#define LOAD_MSG_2_1(buf) \
-t0 = _mm_unpackhi_epi32(m2,m3); \
-t1 = _mm_blend_epi16(m3,m1,0x0C); \
-t2 = _mm_blend_epi16(t0, t1, 0x0F); \
-buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,1,0,2));
-
-#define LOAD_MSG_2_2(buf) \
-t0 = _mm_unpacklo_epi32(m2,m0); \
-t1 = _mm_blend_epi16(t0, m0, 0xF0); \
-t2 = _mm_slli_si128(m3, 8); \
-buf = _mm_blend_epi16(t1, t2, 0xC0);
-
-#define LOAD_MSG_2_3(buf) \
-t0 = _mm_blend_epi16(m0, m2, 0x3C); \
-t1 = _mm_srli_si128(m1, 12); \
-t2 = _mm_blend_epi16(t0,t1,0x03); \
-buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,0,3,2));
-
-#define LOAD_MSG_2_4(buf) \
-t0 = _mm_slli_si128(m3, 4); \
-t1 = _mm_blend_epi16(m0, m1, 0x33); \
-t2 = _mm_blend_epi16(t1, t0, 0xC0); \
-buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(0,1,2,3));
-
-#define LOAD_MSG_3_1(buf) \
-t0 = _mm_unpackhi_epi32(m0,m1); \
-t1 = _mm_unpackhi_epi32(t0, m2); \
-t2 = _mm_blend_epi16(t1, m3, 0x0C); \
-buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,1,0,2));
-
-#define LOAD_MSG_3_2(buf) \
-t0 = _mm_slli_si128(m2, 8); \
-t1 = _mm_blend_epi16(m3,m0,0x0C); \
-t2 = _mm_blend_epi16(t1, t0, 0xC0); \
-buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,0,1,3));
-
-#define LOAD_MSG_3_3(buf) \
-t0 = _mm_blend_epi16(m0,m1,0x0F); \
-t1 = _mm_blend_epi16(t0, m3, 0xC0); \
-buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE(3,0,1,2));
-
-#define LOAD_MSG_3_4(buf) \
-t0 = _mm_unpacklo_epi32(m0,m2); \
-t1 = _mm_unpackhi_epi32(m1,m2); \
-buf = _mm_unpacklo_epi64(t1,t0);
-
-#define LOAD_MSG_4_1(buf) \
-t0 = _mm_unpacklo_epi64(m1,m2); \
-t1 = _mm_unpackhi_epi64(m0,m2); \
-t2 = _mm_blend_epi16(t0,t1,0x33); \
-buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,0,1,3));
-
-#define LOAD_MSG_4_2(buf) \
-t0 = _mm_unpackhi_epi64(m1,m3); \
-t1 = _mm_unpacklo_epi64(m0,m1); \
-buf = _mm_blend_epi16(t0,t1,0x33);
-
-#define LOAD_MSG_4_3(buf) \
-t0 = _mm_unpackhi_epi64(m3,m1); \
-t1 = _mm_unpackhi_epi64(m2,m0); \
-buf = _mm_blend_epi16(t1,t0,0x33);
-
-#define LOAD_MSG_4_4(buf) \
-t0 = _mm_blend_epi16(m0,m2,0x03); \
-t1 = _mm_slli_si128(t0, 8); \
-t2 = _mm_blend_epi16(t1,m3,0x0F); \
-buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,2,0,3));
-
-#define LOAD_MSG_5_1(buf) \
-t0 = _mm_unpackhi_epi32(m0,m1); \
-t1 = _mm_unpacklo_epi32(m0,m2); \
-buf = _mm_unpacklo_epi64(t0,t1);
-
-#define LOAD_MSG_5_2(buf) \
-t0 = _mm_srli_si128(m2, 4); \
-t1 = _mm_blend_epi16(m0,m3,0x03); \
-buf = _mm_blend_epi16(t1,t0,0x3C);
-
-#define LOAD_MSG_5_3(buf) \
-t0 = _mm_blend_epi16(m1,m0,0x0C); \
-t1 = _mm_srli_si128(m3, 4); \
-t2 = _mm_blend_epi16(t0,t1,0x30); \
-buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,2,3,0));
-
-#define LOAD_MSG_5_4(buf) \
-t0 = _mm_unpacklo_epi64(m1,m2); \
-t1= _mm_shuffle_epi32(m3, _MM_SHUFFLE(0,2,0,1)); \
-buf = _mm_blend_epi16(t0,t1,0x33);
-
-#define LOAD_MSG_6_1(buf) \
-t0 = _mm_slli_si128(m1, 12); \
-t1 = _mm_blend_epi16(m0,m3,0x33); \
-buf = _mm_blend_epi16(t1,t0,0xC0);
-
-#define LOAD_MSG_6_2(buf) \
-t0 = _mm_blend_epi16(m3,m2,0x30); \
-t1 = _mm_srli_si128(m1, 4); \
-t2 = _mm_blend_epi16(t0,t1,0x03); \
-buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,3,0));
-
-#define LOAD_MSG_6_3(buf) \
-t0 = _mm_unpacklo_epi64(m0,m2); \
-t1 = _mm_srli_si128(m1, 4); \
-buf = _mm_shuffle_epi32(_mm_blend_epi16(t0,t1,0x0C), _MM_SHUFFLE(2,3,1,0));
-
-#define LOAD_MSG_6_4(buf) \
-t0 = _mm_unpackhi_epi32(m1,m2); \
-t1 = _mm_unpackhi_epi64(m0,t0); \
-buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE(3,0,1,2));
-
-#define LOAD_MSG_7_1(buf) \
-t0 = _mm_unpackhi_epi32(m0,m1); \
-t1 = _mm_blend_epi16(t0,m3,0x0F); \
-buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(2,0,3,1));
-
-#define LOAD_MSG_7_2(buf) \
-t0 = _mm_blend_epi16(m2,m3,0x30); \
-t1 = _mm_srli_si128(m0,4); \
-t2 = _mm_blend_epi16(t0,t1,0x03); \
-buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,0,2,3));
-
-#define LOAD_MSG_7_3(buf) \
-t0 = _mm_unpackhi_epi64(m0,m3); \
-t1 = _mm_unpacklo_epi64(m1,m2); \
-t2 = _mm_blend_epi16(t0,t1,0x3C); \
-buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(0,2,3,1));
-
-#define LOAD_MSG_7_4(buf) \
-t0 = _mm_unpacklo_epi32(m0,m1); \
-t1 = _mm_unpackhi_epi32(m1,m2); \
-buf = _mm_unpacklo_epi64(t0,t1);
-
-#define LOAD_MSG_8_1(buf) \
-t0 = _mm_unpackhi_epi32(m1,m3); \
-t1 = _mm_unpacklo_epi64(t0,m0); \
-t2 = _mm_blend_epi16(t1,m2,0xC0); \
-buf = _mm_shufflehi_epi16(t2,_MM_SHUFFLE(1,0,3,2));
-
-#define LOAD_MSG_8_2(buf) \
-t0 = _mm_unpackhi_epi32(m0,m3); \
-t1 = _mm_blend_epi16(m2,t0,0xF0); \
-buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(0,2,1,3));
-
-#define LOAD_MSG_8_3(buf) \
-t0 = _mm_blend_epi16(m2,m0,0x0C); \
-t1 = _mm_slli_si128(t0,4); \
-buf = _mm_blend_epi16(t1,m3,0x0F);
-
-#define LOAD_MSG_8_4(buf) \
-t0 = _mm_blend_epi16(m1,m0,0x30); \
-buf = _mm_shuffle_epi32(t0,_MM_SHUFFLE(1,0,3,2));
-
-#define LOAD_MSG_9_1(buf) \
-t0 = _mm_blend_epi16(m0,m2,0x03); \
-t1 = _mm_blend_epi16(m1,m2,0x30); \
-t2 = _mm_blend_epi16(t1,t0,0x0F); \
-buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(1,3,0,2));
-
-#define LOAD_MSG_9_2(buf) \
-t0 = _mm_slli_si128(m0,4); \
-t1 = _mm_blend_epi16(m1,t0,0xC0); \
-buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(1,2,0,3));
-
-#define LOAD_MSG_9_3(buf) \
-t0 = _mm_unpackhi_epi32(m0,m3); \
-t1 = _mm_unpacklo_epi32(m2,m3); \
-t2 = _mm_unpackhi_epi64(t0,t1); \
-buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(3,0,2,1));
-
-#define LOAD_MSG_9_4(buf) \
-t0 = _mm_blend_epi16(m3,m2,0xC0); \
-t1 = _mm_unpacklo_epi32(m0,m3); \
-t2 = _mm_blend_epi16(t0,t1,0x0F); \
-buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(0,1,2,3));
-
-#endif
-
diff --git a/contrib/libs/blake2/src/blake2s-load-xop.h b/contrib/libs/blake2/src/blake2s-load-xop.h
deleted file mode 100644
index ac591a77d1..0000000000
--- a/contrib/libs/blake2/src/blake2s-load-xop.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- BLAKE2 reference source code package - optimized C implementations
-
- Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
-
- To the extent possible under law, the author(s) have dedicated all copyright
- and related and neighboring rights to this software to the public domain
- worldwide. This software is distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along with
- this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
-*/
-#pragma once
-#ifndef __BLAKE2S_LOAD_XOP_H__
-#define __BLAKE2S_LOAD_XOP_H__
-
-#define TOB(x) ((x)*4*0x01010101 + 0x03020100) // ..or not TOB
-
-/* Basic VPPERM emulation, for testing purposes */
-/*static __m128i _mm_perm_epi8(const __m128i src1, const __m128i src2, const __m128i sel)
-{
- const __m128i sixteen = _mm_set1_epi8(16);
- const __m128i t0 = _mm_shuffle_epi8(src1, sel);
- const __m128i s1 = _mm_shuffle_epi8(src2, _mm_sub_epi8(sel, sixteen));
- const __m128i mask = _mm_or_si128(_mm_cmpeq_epi8(sel, sixteen),
- _mm_cmpgt_epi8(sel, sixteen)); // (>=16) = 0xff : 00
- return _mm_blendv_epi8(t0, s1, mask);
-}*/
-
-#define LOAD_MSG_0_1(buf) \
-buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(6),TOB(4),TOB(2),TOB(0)) );
-
-#define LOAD_MSG_0_2(buf) \
-buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(7),TOB(5),TOB(3),TOB(1)) );
-
-#define LOAD_MSG_0_3(buf) \
-buf = _mm_perm_epi8(m2, m3, _mm_set_epi32(TOB(6),TOB(4),TOB(2),TOB(0)) );
-
-#define LOAD_MSG_0_4(buf) \
-buf = _mm_perm_epi8(m2, m3, _mm_set_epi32(TOB(7),TOB(5),TOB(3),TOB(1)) );
-
-#define LOAD_MSG_1_1(buf) \
-t0 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(0),TOB(5),TOB(0),TOB(0)) ); \
-buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(6)) );
-
-#define LOAD_MSG_1_2(buf) \
-t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(2),TOB(0),TOB(4),TOB(6)) ); \
-buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) );
-
-#define LOAD_MSG_1_3(buf) \
-t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(0),TOB(0),TOB(1)) ); \
-buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) );
-
-#define LOAD_MSG_1_4(buf) \
-t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(7),TOB(2),TOB(0)) ); \
-buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(4)) );
-
-#define LOAD_MSG_2_1(buf) \
-t0 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(0),TOB(1),TOB(0),TOB(7)) ); \
-buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(4),TOB(0)) );
-
-#define LOAD_MSG_2_2(buf) \
-t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(2),TOB(0),TOB(4)) ); \
-buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(0)) );
-
-#define LOAD_MSG_2_3(buf) \
-t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(7),TOB(3),TOB(0)) ); \
-buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(6)) );
-
-#define LOAD_MSG_2_4(buf) \
-t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(4),TOB(1),TOB(6),TOB(0)) ); \
-buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(6)) );
-
-#define LOAD_MSG_3_1(buf) \
-t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(3),TOB(7)) ); \
-t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); \
-buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(5),TOB(1),TOB(0)) );
-
-#define LOAD_MSG_3_2(buf) \
-t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(0),TOB(1),TOB(5)) ); \
-buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(6),TOB(4),TOB(1),TOB(0)) );
-
-#define LOAD_MSG_3_3(buf) \
-t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(4),TOB(5),TOB(2)) ); \
-buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) );
-
-#define LOAD_MSG_3_4(buf) \
-t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(6)) ); \
-buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(4),TOB(2),TOB(6),TOB(0)) );
-
-#define LOAD_MSG_4_1(buf) \
-t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(2),TOB(5),TOB(0)) ); \
-buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(6),TOB(2),TOB(1),TOB(5)) );
-
-#define LOAD_MSG_4_2(buf) \
-t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(4),TOB(7),TOB(0)) ); \
-buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) );
-
-#define LOAD_MSG_4_3(buf) \
-t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(6),TOB(0),TOB(0)) ); \
-t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(2),TOB(7),TOB(0)) ); \
-buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(6)) );
-
-#define LOAD_MSG_4_4(buf) \
-t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(4),TOB(0),TOB(1)) ); \
-buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(4),TOB(0)) );
-
-#define LOAD_MSG_5_1(buf) \
-t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(6),TOB(2)) ); \
-buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(4),TOB(2),TOB(1),TOB(0)) );
-
-#define LOAD_MSG_5_2(buf) \
-t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(6),TOB(0)) ); \
-buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(4)) );
-
-#define LOAD_MSG_5_3(buf) \
-t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(1),TOB(0),TOB(7),TOB(4)) ); \
-buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) );
-
-#define LOAD_MSG_5_4(buf) \
-t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(5),TOB(0),TOB(1),TOB(0)) ); \
-buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(6),TOB(1),TOB(5)) );
-
-#define LOAD_MSG_6_1(buf) \
-t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(4),TOB(0),TOB(1),TOB(0)) ); \
-buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(6),TOB(1),TOB(4)) );
-
-#define LOAD_MSG_6_2(buf) \
-t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(6),TOB(0),TOB(0),TOB(1)) ); \
-buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(5),TOB(7),TOB(0)) );
-
-#define LOAD_MSG_6_3(buf) \
-t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(6),TOB(0)) ); \
-buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(4),TOB(5),TOB(1),TOB(0)) );
-
-#define LOAD_MSG_6_4(buf) \
-t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(2),TOB(3),TOB(7)) ); \
-buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) );
-
-#define LOAD_MSG_7_1(buf) \
-t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(0),TOB(7),TOB(0)) ); \
-buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(4),TOB(1),TOB(5)) );
-
-#define LOAD_MSG_7_2(buf) \
-t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(5),TOB(1),TOB(0),TOB(7)) ); \
-buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(6),TOB(0)) );
-
-#define LOAD_MSG_7_3(buf) \
-t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(2),TOB(0),TOB(0),TOB(5)) ); \
-t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(4),TOB(1),TOB(0)) ); \
-buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(7),TOB(0)) );
-
-#define LOAD_MSG_7_4(buf) \
-t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(6),TOB(4),TOB(0)) ); \
-buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(6),TOB(2),TOB(1),TOB(0)) );
-
-#define LOAD_MSG_8_1(buf) \
-t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(6)) ); \
-t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); \
-buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(6),TOB(0)) );
-
-#define LOAD_MSG_8_2(buf) \
-t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(4),TOB(3),TOB(5),TOB(0)) ); \
-buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(7)) );
-
-#define LOAD_MSG_8_3(buf) \
-t0 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(6),TOB(1),TOB(0),TOB(0)) ); \
-buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(5),TOB(4)) ); \
-
-#define LOAD_MSG_8_4(buf) \
-buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(4),TOB(7),TOB(2)) );
-
-#define LOAD_MSG_9_1(buf) \
-t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(1),TOB(7),TOB(0),TOB(0)) ); \
-buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(2),TOB(4),TOB(6)) );
-
-#define LOAD_MSG_9_2(buf) \
-buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(6),TOB(4),TOB(2)) );
-
-#define LOAD_MSG_9_3(buf) \
-t0 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(3),TOB(5),TOB(0)) ); \
-buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(7)) );
-
-#define LOAD_MSG_9_4(buf) \
-t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(7)) ); \
-buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(4),TOB(6),TOB(0)) );
-
-#endif
-
diff --git a/contrib/libs/blake2/src/blake2s-ref.c b/contrib/libs/blake2/src/blake2s-ref.c
deleted file mode 100644
index db7390f925..0000000000
--- a/contrib/libs/blake2/src/blake2s-ref.c
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- BLAKE2 reference source code package - reference C implementations
-
- Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
-
- To the extent possible under law, the author(s) have dedicated all copyright
- and related and neighboring rights to this software to the public domain
- worldwide. This software is distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along with
- this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
-*/
-
-#include <stdint.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "blake2.h"
-#include "blake2-impl.h"
-
-static const uint32_t blake2s_IV[8] =
-{
- 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
- 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
-};
-
-static const uint8_t blake2s_sigma[10][16] =
-{
- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
- { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
- { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
- { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
- { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
- { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
- { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
- { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
- { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
- { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
-};
-
-static inline int blake2s_set_lastnode( blake2s_state *S )
-{
- S->f[1] = ~0U;
- return 0;
-}
-
-static inline int blake2s_clear_lastnode( blake2s_state *S )
-{
- S->f[1] = 0U;
- return 0;
-}
-
-/* Some helper functions, not necessarily useful */
-static inline int blake2s_set_lastblock( blake2s_state *S )
-{
- if( S->last_node ) blake2s_set_lastnode( S );
-
- S->f[0] = ~0U;
- return 0;
-}
-
-static inline int blake2s_clear_lastblock( blake2s_state *S )
-{
- if( S->last_node ) blake2s_clear_lastnode( S );
-
- S->f[0] = 0U;
- return 0;
-}
-
-static inline int blake2s_increment_counter( blake2s_state *S, const uint32_t inc )
-{
- S->t[0] += inc;
- S->t[1] += ( S->t[0] < inc );
- return 0;
-}
-
-// Parameter-related functions
-static inline int blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length )
-{
- P->digest_length = digest_length;
- return 0;
-}
-
-static inline int blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout )
-{
- P->fanout = fanout;
- return 0;
-}
-
-static inline int blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth )
-{
- P->depth = depth;
- return 0;
-}
-
-static inline int blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length )
-{
- store32( &P->leaf_length, leaf_length );
- return 0;
-}
-
-static inline int blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset )
-{
- store48( P->node_offset, node_offset );
- return 0;
-}
-
-static inline int blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth )
-{
- P->node_depth = node_depth;
- return 0;
-}
-
-static inline int blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length )
-{
- P->inner_length = inner_length;
- return 0;
-}
-
-static inline int blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] )
-{
- memcpy( P->salt, salt, BLAKE2S_SALTBYTES );
- return 0;
-}
-
-static inline int blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] )
-{
- memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES );
- return 0;
-}
-
-static inline int blake2s_init0( blake2s_state *S )
-{
- memset( S, 0, sizeof( blake2s_state ) );
-
- for( int i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];
-
- return 0;
-}
-
-#define blake2s_init BLAKE2_IMPL_NAME(blake2s_init)
-#define blake2s_init_param BLAKE2_IMPL_NAME(blake2s_init_param)
-#define blake2s_init_key BLAKE2_IMPL_NAME(blake2s_init_key)
-#define blake2s_update BLAKE2_IMPL_NAME(blake2s_update)
-#define blake2s_final BLAKE2_IMPL_NAME(blake2s_final)
-#define blake2s BLAKE2_IMPL_NAME(blake2s)
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
- int blake2s_init( blake2s_state *S, size_t outlen );
- int blake2s_init_param( blake2s_state *S, const blake2s_param *P );
- int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
- int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen );
- int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen );
- int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
-#if defined(__cplusplus)
-}
-#endif
-
-/* init2 xors IV with input parameter block */
-int blake2s_init_param( blake2s_state *S, const blake2s_param *P )
-{
- blake2s_init0( S );
- uint32_t *p = ( uint32_t * )( P );
-
- /* IV XOR ParamBlock */
- for( size_t i = 0; i < 8; ++i )
- S->h[i] ^= load32( &p[i] );
-
- S->outlen = P->digest_length;
- return 0;
-}
-
-
-// Sequential blake2s initialization
-int blake2s_init( blake2s_state *S, size_t outlen )
-{
- blake2s_param P[1];
-
- /* Move interval verification here? */
- if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
-
- P->digest_length = ( uint8_t) outlen;
- P->key_length = 0;
- P->fanout = 1;
- P->depth = 1;
- store32( &P->leaf_length, 0 );
- store48( &P->node_offset, 0 );
- P->node_depth = 0;
- P->inner_length = 0;
- // memset(P->reserved, 0, sizeof(P->reserved) );
- memset( P->salt, 0, sizeof( P->salt ) );
- memset( P->personal, 0, sizeof( P->personal ) );
- return blake2s_init_param( S, P );
-}
-
-int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen )
-{
- blake2s_param P[1];
-
- if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
-
- if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;
-
- P->digest_length = ( uint8_t ) outlen;
- P->key_length = ( uint8_t ) keylen;
- P->fanout = 1;
- P->depth = 1;
- store32( &P->leaf_length, 0 );
- store48( &P->node_offset, 0 );
- P->node_depth = 0;
- P->inner_length = 0;
- // memset(P->reserved, 0, sizeof(P->reserved) );
- memset( P->salt, 0, sizeof( P->salt ) );
- memset( P->personal, 0, sizeof( P->personal ) );
-
- if( blake2s_init_param( S, P ) < 0 ) return -1;
-
- {
- uint8_t block[BLAKE2S_BLOCKBYTES];
- memset( block, 0, BLAKE2S_BLOCKBYTES );
- memcpy( block, key, keylen );
- blake2s_update( S, block, BLAKE2S_BLOCKBYTES );
- secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
- }
- return 0;
-}
-
-static int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] )
-{
- uint32_t m[16];
- uint32_t v[16];
-
- for( size_t i = 0; i < 16; ++i )
- m[i] = load32( block + i * sizeof( m[i] ) );
-
- for( size_t i = 0; i < 8; ++i )
- v[i] = S->h[i];
-
- v[ 8] = blake2s_IV[0];
- v[ 9] = blake2s_IV[1];
- v[10] = blake2s_IV[2];
- v[11] = blake2s_IV[3];
- v[12] = S->t[0] ^ blake2s_IV[4];
- v[13] = S->t[1] ^ blake2s_IV[5];
- v[14] = S->f[0] ^ blake2s_IV[6];
- v[15] = S->f[1] ^ blake2s_IV[7];
-#define G(r,i,a,b,c,d) \
- do { \
- a = a + b + m[blake2s_sigma[r][2*i+0]]; \
- d = rotr32(d ^ a, 16); \
- c = c + d; \
- b = rotr32(b ^ c, 12); \
- a = a + b + m[blake2s_sigma[r][2*i+1]]; \
- d = rotr32(d ^ a, 8); \
- c = c + d; \
- b = rotr32(b ^ c, 7); \
- } while(0)
-#define ROUND(r) \
- do { \
- G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
- G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
- G(r,2,v[ 2],v[ 6],v[10],v[14]); \
- G(r,3,v[ 3],v[ 7],v[11],v[15]); \
- G(r,4,v[ 0],v[ 5],v[10],v[15]); \
- G(r,5,v[ 1],v[ 6],v[11],v[12]); \
- G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
- G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
- } while(0)
- ROUND( 0 );
- ROUND( 1 );
- ROUND( 2 );
- ROUND( 3 );
- ROUND( 4 );
- ROUND( 5 );
- ROUND( 6 );
- ROUND( 7 );
- ROUND( 8 );
- ROUND( 9 );
-
- for( size_t i = 0; i < 8; ++i )
- S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
-
-#undef G
-#undef ROUND
- return 0;
-}
-
-
-int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen )
-{
- while( inlen > 0 )
- {
- uint32_t left = S->buflen;
- uint32_t fill = 2 * BLAKE2S_BLOCKBYTES - left;
-
- if( inlen > fill )
- {
- memcpy( S->buf + left, in, fill ); // Fill buffer
- S->buflen += fill;
- blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
- blake2s_compress( S, S->buf ); // Compress
- memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); // Shift buffer left
- S->buflen -= BLAKE2S_BLOCKBYTES;
- in += fill;
- inlen -= fill;
- }
- else // inlen <= fill
- {
- memcpy( S->buf + left, in, inlen );
- S->buflen += ( uint32_t ) inlen; // Be lazy, do not compress
- in += inlen;
- inlen -= inlen;
- }
- }
-
- return 0;
-}
-
-int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen )
-{
- uint8_t buffer[BLAKE2S_OUTBYTES];
- size_t i;
-
- if(S->outlen != outlen) return -1;
-
- if( S->buflen > BLAKE2S_BLOCKBYTES )
- {
- blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
- blake2s_compress( S, S->buf );
- S->buflen -= BLAKE2S_BLOCKBYTES;
- memmove( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen );
- }
-
- blake2s_increment_counter( S, ( uint32_t )S->buflen );
- blake2s_set_lastblock( S );
- memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */
- blake2s_compress( S, S->buf );
-
- for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
- store32( buffer + sizeof( S->h[i] ) * i, S->h[i] );
-
- memcpy( out, buffer, outlen );
- return 0;
-}
-
-int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
-{
- blake2s_state S[1];
-
- /* Verify parameters */
- if ( NULL == in && inlen > 0 ) return -1;
-
- if ( NULL == out ) return -1;
-
- if ( NULL == key && keylen > 0 ) return -1;
-
- if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
-
- if( keylen > BLAKE2S_KEYBYTES ) return -1;
-
- if( keylen > 0 )
- {
- if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1;
- }
- else
- {
- if( blake2s_init( S, outlen ) < 0 ) return -1;
- }
-
- if( blake2s_update( S, ( uint8_t * )in, inlen ) < 0) return -1;
- return blake2s_final( S, out, outlen );
-}
-
diff --git a/contrib/libs/blake2/src/blake2s-round.h b/contrib/libs/blake2/src/blake2s-round.h
deleted file mode 100644
index 1e2f2b7f59..0000000000
--- a/contrib/libs/blake2/src/blake2s-round.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- BLAKE2 reference source code package - optimized C implementations
-
- Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
-
- To the extent possible under law, the author(s) have dedicated all copyright
- and related and neighboring rights to this software to the public domain
- worldwide. This software is distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along with
- this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
-*/
-#pragma once
-#ifndef __BLAKE2S_ROUND_H__
-#define __BLAKE2S_ROUND_H__
-
-#define LOAD(p) _mm_load_si128( (__m128i *)(p) )
-#define STORE(p,r) _mm_store_si128((__m128i *)(p), r)
-
-#define LOADU(p) _mm_loadu_si128( (__m128i *)(p) )
-#define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r)
-
-#define TOF(reg) _mm_castsi128_ps((reg))
-#define TOI(reg) _mm_castps_si128((reg))
-
-#define LIKELY(x) __builtin_expect((x),1)
-
-
-/* Microarchitecture-specific macros */
-#ifndef HAVE_XOP
-#ifdef HAVE_SSSE3
-#define _mm_roti_epi32(r, c) ( \
- (8==-(c)) ? _mm_shuffle_epi8(r,r8) \
- : (16==-(c)) ? _mm_shuffle_epi8(r,r16) \
- : _mm_xor_si128(_mm_srli_epi32( (r), -(c) ),_mm_slli_epi32( (r), 32-(-(c)) )) )
-#else
-#define _mm_roti_epi32(r, c) _mm_xor_si128(_mm_srli_epi32( (r), -(c) ),_mm_slli_epi32( (r), 32-(-(c)) ))
-#endif
-#else
-/* ... */
-#endif
-
-
-#define G1(row1,row2,row3,row4,buf) \
- row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \
- row4 = _mm_xor_si128( row4, row1 ); \
- row4 = _mm_roti_epi32(row4, -16); \
- row3 = _mm_add_epi32( row3, row4 ); \
- row2 = _mm_xor_si128( row2, row3 ); \
- row2 = _mm_roti_epi32(row2, -12);
-
-#define G2(row1,row2,row3,row4,buf) \
- row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \
- row4 = _mm_xor_si128( row4, row1 ); \
- row4 = _mm_roti_epi32(row4, -8); \
- row3 = _mm_add_epi32( row3, row4 ); \
- row2 = _mm_xor_si128( row2, row3 ); \
- row2 = _mm_roti_epi32(row2, -7);
-
-#define DIAGONALIZE(row1,row2,row3,row4) \
- row4 = _mm_shuffle_epi32( row4, _MM_SHUFFLE(2,1,0,3) ); \
- row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(1,0,3,2) ); \
- row2 = _mm_shuffle_epi32( row2, _MM_SHUFFLE(0,3,2,1) );
-
-#define UNDIAGONALIZE(row1,row2,row3,row4) \
- row4 = _mm_shuffle_epi32( row4, _MM_SHUFFLE(0,3,2,1) ); \
- row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(1,0,3,2) ); \
- row2 = _mm_shuffle_epi32( row2, _MM_SHUFFLE(2,1,0,3) );
-
-#if defined(HAVE_XOP)
-#include "blake2s-load-xop.h"
-#elif defined(HAVE_SSE4_1)
-#include "blake2s-load-sse41.h"
-#else
-#include "blake2s-load-sse2.h"
-#endif
-
-#define ROUND(r) \
- LOAD_MSG_ ##r ##_1(buf1); \
- G1(row1,row2,row3,row4,buf1); \
- LOAD_MSG_ ##r ##_2(buf2); \
- G2(row1,row2,row3,row4,buf2); \
- DIAGONALIZE(row1,row2,row3,row4); \
- LOAD_MSG_ ##r ##_3(buf3); \
- G1(row1,row2,row3,row4,buf3); \
- LOAD_MSG_ ##r ##_4(buf4); \
- G2(row1,row2,row3,row4,buf4); \
- UNDIAGONALIZE(row1,row2,row3,row4); \
-
-#endif
-
diff --git a/contrib/libs/blake2/src/blake2s.c b/contrib/libs/blake2/src/blake2s.c
deleted file mode 100644
index db97974895..0000000000
--- a/contrib/libs/blake2/src/blake2s.c
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- BLAKE2 reference source code package - optimized C implementations
-
- Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
-
- To the extent possible under law, the author(s) have dedicated all copyright
- and related and neighboring rights to this software to the public domain
- worldwide. This software is distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along with
- this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
-*/
-
-#include <stdint.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "blake2.h"
-#include "blake2-impl.h"
-
-#include "blake2-config.h"
-
-#if defined(_MSC_VER)
-#include <intrin.h>
-#endif
-
-#if defined(HAVE_SSE2)
-#include <emmintrin.h>
-// MSVC only defines _mm_set_epi64x for x86_64...
-#if defined(_MSC_VER) && !defined(_M_X64) && !defined(__clang__)
-static inline __m128i _mm_set_epi64x( const uint64_t u1, const uint64_t u0 )
-{
- return _mm_set_epi32( u1 >> 32, u1, u0 >> 32, u0 );
-}
-#endif
-#endif
-
-
-#if defined(HAVE_SSSE3)
-#include <tmmintrin.h>
-#endif
-#if defined(HAVE_SSE4_1)
-#include <smmintrin.h>
-#endif
-#if defined(HAVE_AVX)
-#include <immintrin.h>
-#endif
-#if defined(HAVE_XOP) && !defined(_MSC_VER)
-#include <x86intrin.h>
-#endif
-
-#include "blake2s-round.h"
-
-static const uint32_t blake2s_IV[8] =
-{
- 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
- 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
-};
-
-static const uint8_t blake2s_sigma[10][16] =
-{
- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
- { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
- { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
- { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
- { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
- { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
- { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
- { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
- { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
- { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
-};
-
-
-/* Some helper functions, not necessarily useful */
-static inline int blake2s_set_lastnode( blake2s_state *S )
-{
- S->f[1] = ~0U;
- return 0;
-}
-
-static inline int blake2s_clear_lastnode( blake2s_state *S )
-{
- S->f[1] = 0U;
- return 0;
-}
-
-static inline int blake2s_set_lastblock( blake2s_state *S )
-{
- if( S->last_node ) blake2s_set_lastnode( S );
-
- S->f[0] = ~0U;
- return 0;
-}
-
-static inline int blake2s_clear_lastblock( blake2s_state *S )
-{
- if( S->last_node ) blake2s_clear_lastnode( S );
-
- S->f[0] = 0U;
- return 0;
-}
-
-static inline int blake2s_increment_counter( blake2s_state *S, const uint32_t inc )
-{
- uint64_t t = ( ( uint64_t )S->t[1] << 32 ) | S->t[0];
- t += inc;
- S->t[0] = ( uint32_t )( t >> 0 );
- S->t[1] = ( uint32_t )( t >> 32 );
- return 0;
-}
-
-
-// Parameter-related functions
-static inline int blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length )
-{
- P->digest_length = digest_length;
- return 0;
-}
-
-static inline int blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout )
-{
- P->fanout = fanout;
- return 0;
-}
-
-static inline int blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth )
-{
- P->depth = depth;
- return 0;
-}
-
-static inline int blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length )
-{
- P->leaf_length = leaf_length;
- return 0;
-}
-
-static inline int blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset )
-{
- store48( P->node_offset, node_offset );
- return 0;
-}
-
-static inline int blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth )
-{
- P->node_depth = node_depth;
- return 0;
-}
-
-static inline int blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length )
-{
- P->inner_length = inner_length;
- return 0;
-}
-
-static inline int blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] )
-{
- memcpy( P->salt, salt, BLAKE2S_SALTBYTES );
- return 0;
-}
-
-static inline int blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] )
-{
- memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES );
- return 0;
-}
-
-static inline int blake2s_init0( blake2s_state *S )
-{
- memset( S, 0, sizeof( blake2s_state ) );
-
- for( int i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];
-
- return 0;
-}
-
-#define blake2s_init BLAKE2_IMPL_NAME(blake2s_init)
-#define blake2s_init_param BLAKE2_IMPL_NAME(blake2s_init_param)
-#define blake2s_init_key BLAKE2_IMPL_NAME(blake2s_init_key)
-#define blake2s_update BLAKE2_IMPL_NAME(blake2s_update)
-#define blake2s_final BLAKE2_IMPL_NAME(blake2s_final)
-#define blake2s BLAKE2_IMPL_NAME(blake2s)
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
- int blake2s_init( blake2s_state *S, size_t outlen );
- int blake2s_init_param( blake2s_state *S, const blake2s_param *P );
- int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
- int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen );
- int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen );
- int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
-#if defined(__cplusplus)
-}
-#endif
-
-
-/* init2 xors IV with input parameter block */
-int blake2s_init_param( blake2s_state *S, const blake2s_param *P )
-{
- uint8_t *p, *h, *v;
- //blake2s_init0( S );
- v = ( uint8_t * )( blake2s_IV );
- h = ( uint8_t * )( S->h );
- p = ( uint8_t * )( P );
- /* IV XOR ParamBlock */
- memset( S, 0, sizeof( blake2s_state ) );
-
- for( int i = 0; i < BLAKE2S_OUTBYTES; ++i ) h[i] = v[i] ^ p[i];
-
- S->outlen = P->digest_length;
- return 0;
-}
-
-
-/* Some sort of default parameter block initialization, for sequential blake2s */
-int blake2s_init( blake2s_state *S, size_t outlen )
-{
- if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
-
- const blake2s_param P =
- {
- outlen,
- 0,
- 1,
- 1,
- 0,
- {0},
- 0,
- 0,
- {0},
- {0}
- };
- return blake2s_init_param( S, &P );
-}
-
-
-int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen )
-{
- if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
-
- if ( ( !key ) || ( !keylen ) || keylen > BLAKE2S_KEYBYTES ) return -1;
-
- const blake2s_param P =
- {
- outlen,
- keylen,
- 1,
- 1,
- 0,
- {0},
- 0,
- 0,
- {0},
- {0}
- };
-
- if( blake2s_init_param( S, &P ) < 0 )
- return -1;
-
- {
- uint8_t block[BLAKE2S_BLOCKBYTES];
- memset( block, 0, BLAKE2S_BLOCKBYTES );
- memcpy( block, key, keylen );
- blake2s_update( S, block, BLAKE2S_BLOCKBYTES );
- secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
- }
- return 0;
-}
-
-
-static inline int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] )
-{
- __m128i row1, row2, row3, row4;
- __m128i buf1, buf2, buf3, buf4;
-#if defined(HAVE_SSE4_1)
- __m128i t0, t1;
-#if !defined(HAVE_XOP)
- __m128i t2;
-#endif
-#endif
- __m128i ff0, ff1;
-#if defined(HAVE_SSSE3) && !defined(HAVE_XOP)
- const __m128i r8 = _mm_set_epi8( 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1 );
- const __m128i r16 = _mm_set_epi8( 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2 );
-#endif
-#if defined(HAVE_SSE4_1)
- const __m128i m0 = LOADU( block + 00 );
- const __m128i m1 = LOADU( block + 16 );
- const __m128i m2 = LOADU( block + 32 );
- const __m128i m3 = LOADU( block + 48 );
-#else
- const uint32_t m0 = ( ( uint32_t * )block )[ 0];
- const uint32_t m1 = ( ( uint32_t * )block )[ 1];
- const uint32_t m2 = ( ( uint32_t * )block )[ 2];
- const uint32_t m3 = ( ( uint32_t * )block )[ 3];
- const uint32_t m4 = ( ( uint32_t * )block )[ 4];
- const uint32_t m5 = ( ( uint32_t * )block )[ 5];
- const uint32_t m6 = ( ( uint32_t * )block )[ 6];
- const uint32_t m7 = ( ( uint32_t * )block )[ 7];
- const uint32_t m8 = ( ( uint32_t * )block )[ 8];
- const uint32_t m9 = ( ( uint32_t * )block )[ 9];
- const uint32_t m10 = ( ( uint32_t * )block )[10];
- const uint32_t m11 = ( ( uint32_t * )block )[11];
- const uint32_t m12 = ( ( uint32_t * )block )[12];
- const uint32_t m13 = ( ( uint32_t * )block )[13];
- const uint32_t m14 = ( ( uint32_t * )block )[14];
- const uint32_t m15 = ( ( uint32_t * )block )[15];
-#endif
- row1 = ff0 = LOADU( &S->h[0] );
- row2 = ff1 = LOADU( &S->h[4] );
- row3 = _mm_setr_epi32( 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A );
- row4 = _mm_xor_si128( _mm_setr_epi32( 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 ), LOADU( &S->t[0] ) );
- ROUND( 0 );
- ROUND( 1 );
- ROUND( 2 );
- ROUND( 3 );
- ROUND( 4 );
- ROUND( 5 );
- ROUND( 6 );
- ROUND( 7 );
- ROUND( 8 );
- ROUND( 9 );
- STOREU( &S->h[0], _mm_xor_si128( ff0, _mm_xor_si128( row1, row3 ) ) );
- STOREU( &S->h[4], _mm_xor_si128( ff1, _mm_xor_si128( row2, row4 ) ) );
- return 0;
-}
-
-
-int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen )
-{
- while( inlen > 0 )
- {
- size_t left = S->buflen;
- size_t fill = 2 * BLAKE2S_BLOCKBYTES - left;
-
- if( inlen > fill )
- {
- memcpy( S->buf + left, in, fill ); // Fill buffer
- S->buflen += fill;
- blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
- blake2s_compress( S, S->buf ); // Compress
- memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); // Shift buffer left
- S->buflen -= BLAKE2S_BLOCKBYTES;
- in += fill;
- inlen -= fill;
- }
- else /* inlen <= fill */
- {
- memcpy( S->buf + left, in, inlen );
- S->buflen += inlen; // Be lazy, do not compress
- in += inlen;
- inlen -= inlen;
- }
- }
-
- return 0;
-}
-
-
-int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen )
-{
- uint8_t buffer[BLAKE2S_OUTBYTES];
-
- if(outlen != S->outlen ) return -1;
-
- if( S->buflen > BLAKE2S_BLOCKBYTES )
- {
- blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
- blake2s_compress( S, S->buf );
- S->buflen -= BLAKE2S_BLOCKBYTES;
- memmove( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen );
- }
-
- blake2s_increment_counter( S, ( uint32_t )S->buflen );
- blake2s_set_lastblock( S );
- memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */
- blake2s_compress( S, S->buf );
-
- for( int i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
- store32( buffer + sizeof( S->h[i] ) * i, S->h[i] );
-
- memcpy( out, buffer, outlen );
- return 0;
-}
-
-int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
-{
- blake2s_state S[1];
-
- /* Verify parameters */
- if ( NULL == in && inlen > 0 ) return -1;
-
- if ( NULL == out ) return -1;
-
- if ( NULL == key && keylen > 0) return -1;
-
- if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
-
- if( keylen > BLAKE2S_KEYBYTES ) return -1;
-
- if( keylen > 0 )
- {
- if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1;
- }
- else
- {
- if( blake2s_init( S, outlen ) < 0 ) return -1;
- }
-
- if( blake2s_update( S, ( uint8_t * )in, inlen ) < 0) return -1;
- return blake2s_final( S, out, outlen );
-}
-
-#if defined(SUPERCOP)
-int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )
-{
- return blake2s( out, in, NULL, BLAKE2S_OUTBYTES, (size_t)inlen, 0 );
-}
-#endif
-
diff --git a/contrib/libs/blake2/src/blake2sp.c b/contrib/libs/blake2/src/blake2sp.c
deleted file mode 100644
index 2f32bf3a22..0000000000
--- a/contrib/libs/blake2/src/blake2sp.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- BLAKE2 reference source code package - optimized C implementations
-
- Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
-
- To the extent possible under law, the author(s) have dedicated all copyright
- and related and neighboring rights to this software to the public domain
- worldwide. This software is distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along with
- this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
-*/
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#if defined(_OPENMP)
-#include <omp.h>
-#endif
-
-#include "blake2.h"
-#include "blake2-impl.h"
-
-#define PARALLELISM_DEGREE 8
-
-static int blake2sp_init_leaf( blake2s_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset )
-{
- blake2s_param P[1];
- P->digest_length = outlen;
- P->key_length = keylen;
- P->fanout = PARALLELISM_DEGREE;
- P->depth = 2;
- P->leaf_length = 0;
- store48( P->node_offset, offset );
- P->node_depth = 0;
- P->inner_length = BLAKE2S_OUTBYTES;
- memset( P->salt, 0, sizeof( P->salt ) );
- memset( P->personal, 0, sizeof( P->personal ) );
- blake2s_init_param( S, P );
- S->outlen = P->inner_length;
- return 0;
-}
-
-static int blake2sp_init_root( blake2s_state *S, uint8_t outlen, uint8_t keylen )
-{
- blake2s_param P[1];
- P->digest_length = outlen;
- P->key_length = keylen;
- P->fanout = PARALLELISM_DEGREE;
- P->depth = 2;
- P->leaf_length = 0;
- store48( P->node_offset, 0ULL );
- P->node_depth = 1;
- P->inner_length = BLAKE2S_OUTBYTES;
- memset( P->salt, 0, sizeof( P->salt ) );
- memset( P->personal, 0, sizeof( P->personal ) );
- blake2s_init_param( S, P );
- S->outlen = P->digest_length;
- return 0;
-}
-
-
-int blake2sp_init( blake2sp_state *S, size_t outlen )
-{
- if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
-
- memset( S->buf, 0, sizeof( S->buf ) );
- S->buflen = 0;
-
- if( blake2sp_init_root( S->R, ( uint8_t ) outlen, 0 ) < 0 )
- return -1;
-
- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
- if( blake2sp_init_leaf( S->S[i], ( uint8_t ) outlen, 0, i ) < 0 ) return -1;
-
- S->R->last_node = 1;
- S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
- S->outlen = ( uint8_t ) outlen;
- return 0;
-}
-
-int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen )
-{
- if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
-
- if( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;
-
- memset( S->buf, 0, sizeof( S->buf ) );
- S->buflen = 0;
-
- if( blake2sp_init_root( S->R, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 )
- return -1;
-
- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
- if( blake2sp_init_leaf( S->S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 )
- return -1;
-
- S->R->last_node = 1;
- S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
- S->outlen = ( uint8_t ) outlen;
- {
- uint8_t block[BLAKE2S_BLOCKBYTES];
- memset( block, 0, BLAKE2S_BLOCKBYTES );
- memcpy( block, key, keylen );
-
- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
- blake2s_update( S->S[i], block, BLAKE2S_BLOCKBYTES );
-
- secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
- }
- return 0;
-}
-
-
-int blake2sp_update( blake2sp_state *S, const uint8_t *in, size_t inlen )
-{
- size_t left = S->buflen;
- size_t fill = sizeof( S->buf ) - left;
-
- if( left && inlen >= fill )
- {
- memcpy( S->buf + left, in, fill );
-
- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
- blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES );
-
- in += fill;
- inlen -= fill;
- left = 0;
- }
-
-#if defined(_OPENMP)
- omp_set_num_threads(PARALLELISM_DEGREE);
- #pragma omp parallel shared(S)
-#else
- for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
-#endif
- {
-#if defined(_OPENMP)
- size_t id__ = ( size_t ) omp_get_thread_num();
-#endif
- size_t inlen__ = inlen;
- const uint8_t *in__ = ( const uint8_t * )in;
- in__ += id__ * BLAKE2S_BLOCKBYTES;
-
- while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )
- {
- blake2s_update( S->S[id__], in__, BLAKE2S_BLOCKBYTES );
- in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
- inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
- }
- }
-
- in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES );
- inlen %= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
-
- if( inlen > 0 )
- memcpy( S->buf + left, in, inlen );
-
- S->buflen = ( uint32_t ) left + ( uint32_t ) inlen;
- return 0;
-}
-
-
-int blake2sp_final( blake2sp_state *S, uint8_t *out, size_t outlen )
-{
- uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
-
- if(S->outlen != outlen) return -1;
-
- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
- {
- if( S->buflen > i * BLAKE2S_BLOCKBYTES )
- {
- size_t left = S->buflen - i * BLAKE2S_BLOCKBYTES;
-
- if( left > BLAKE2S_BLOCKBYTES ) left = BLAKE2S_BLOCKBYTES;
-
- blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, left );
- }
-
- blake2s_final( S->S[i], hash[i], BLAKE2S_OUTBYTES );
- }
-
- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
- blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES );
-
- blake2s_final( S->R, out, outlen );
- return 0;
-}
-
-
-int blake2sp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
-{
- uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
- blake2s_state S[PARALLELISM_DEGREE][1];
- blake2s_state FS[1];
-
- /* Verify parameters */
- if ( NULL == in && inlen > 0 ) return -1;
-
- if ( NULL == out ) return -1;
-
- if ( NULL == key && keylen > 0 ) return -1;
-
- if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
-
- if( keylen > BLAKE2S_KEYBYTES ) return -1;
-
- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
- if( blake2sp_init_leaf( S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 )
- return -1;
-
- S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node
-
- if( keylen > 0 )
- {
- uint8_t block[BLAKE2S_BLOCKBYTES];
- memset( block, 0, BLAKE2S_BLOCKBYTES );
- memcpy( block, key, keylen );
-
- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
- blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES );
-
- secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
- }
-
-#if defined(_OPENMP)
- omp_set_num_threads(PARALLELISM_DEGREE);
- #pragma omp parallel shared(S,hash)
-#else
-
- for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
-#endif
- {
-#if defined(_OPENMP)
- size_t id__ = ( size_t ) omp_get_thread_num();
-#endif
- size_t inlen__ = inlen;
- const uint8_t *in__ = ( const uint8_t * )in;
- in__ += id__ * BLAKE2S_BLOCKBYTES;
-
- while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )
- {
- blake2s_update( S[id__], in__, BLAKE2S_BLOCKBYTES );
- in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
- inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
- }
-
- if( inlen__ > id__ * BLAKE2S_BLOCKBYTES )
- {
- const size_t left = inlen__ - id__ * BLAKE2S_BLOCKBYTES;
- const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES;
- blake2s_update( S[id__], in__, len );
- }
-
- blake2s_final( S[id__], hash[id__], BLAKE2S_OUTBYTES );
- }
-
- if( blake2sp_init_root( FS, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 )
- return -1;
-
- FS->last_node = 1;
-
- for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
- blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES );
-
- return blake2s_final( FS, out, outlen );
-}
-
-
-
-
diff --git a/contrib/libs/blake2/src/config.h b/contrib/libs/blake2/src/config.h
deleted file mode 100644
index fd863ba01a..0000000000
--- a/contrib/libs/blake2/src/config.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/* src/config.h. Generated from config.h.in by configure. */
-/* src/config.h.in. Generated from configure.ac by autoheader. */
-
-/* Support Altivec instructions */
-/* #undef HAVE_ALTIVEC */
-
-/* Support AVX (Advanced Vector Extensions) instructions */
-/* #undef HAVE_AVX */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the `explicit_bzero' function. */
-#define HAVE_EXPLICIT_BZERO 1
-
-/* Define to 1 if you have the `explicit_memset' function. */
-/* #undef HAVE_EXPLICIT_MEMSET */
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the `memset' function. */
-#define HAVE_MEMSET 1
-
-/* Define to 1 if you have the `memset_s' function. */
-/* #undef HAVE_MEMSET_S */
-
-/* Support mmx instructions */
-/* #undef HAVE_MMX */
-
-/* Support SSE (Streaming SIMD Extensions) instructions */
-/* #undef HAVE_SSE */
-
-/* Support SSE2 (Streaming SIMD Extensions 2) instructions */
-/* #undef HAVE_SSE2 */
-
-/* Support SSE3 (Streaming SIMD Extensions 3) instructions */
-/* #undef HAVE_SSE3 */
-
-/* Support SSSE4.1 (Streaming SIMD Extensions 4.1) instructions */
-/* #undef HAVE_SSE4_1 */
-
-/* Support SSSE4.2 (Streaming SIMD Extensions 4.2) instructions */
-/* #undef HAVE_SSE4_2 */
-
-/* Support SSSE3 (Supplemental Streaming SIMD Extensions 3) instructions */
-/* #undef HAVE_SSSE3 */
-
-/* Define to 1 if you have the <stddef.h> header file. */
-#define HAVE_STDDEF_H 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdio.h> header file. */
-#define HAVE_STDIO_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to the sub-directory where libtool stores uninstalled libraries. */
-#define LT_OBJDIR ".libs/"
-
-/* machine is little-endian */
-#define NATIVE_LITTLE_ENDIAN 1
-
-/* Name of package */
-#define PACKAGE "libb2"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "contact@blake2.net"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "libb2"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "libb2 0.98.1"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "libb2"
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL "https://blake2.net"
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "0.98.1"
-
-/* Define to 1 if all of the C90 standard headers exist (not just the ones
- required in a freestanding environment). This macro is provided for
- backward compatibility; new code need not use it. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "0.98.1"
-
-/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
- significant byte first (like Motorola and SPARC, unlike Intel). */
-#if defined AC_APPLE_UNIVERSAL_BUILD
-# if defined __BIG_ENDIAN__
-# define WORDS_BIGENDIAN 1
-# endif
-#else
-# ifndef WORDS_BIGENDIAN
-/* # undef WORDS_BIGENDIAN */
-# endif
-#endif
-
-/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
- <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
- #define below would cause a syntax error. */
-/* #undef _UINT32_T */
-
-/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
- <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
- #define below would cause a syntax error. */
-/* #undef _UINT64_T */
-
-/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
- <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
- #define below would cause a syntax error. */
-/* #undef _UINT8_T */
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
- calls it, or to nothing if 'inline' is not supported under any name. */
-#ifndef __cplusplus
-/* #undef inline */
-#endif
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-/* #undef size_t */
-
-/* Define to the type of an unsigned integer type of width exactly 32 bits if
- such a type exists and the standard includes do not define it. */
-/* #undef uint32_t */
-
-/* Define to the type of an unsigned integer type of width exactly 64 bits if
- such a type exists and the standard includes do not define it. */
-/* #undef uint64_t */
-
-/* Define to the type of an unsigned integer type of width exactly 8 bits if
- such a type exists and the standard includes do not define it. */
-/* #undef uint8_t */
diff --git a/contrib/libs/blake2/ya.make b/contrib/libs/blake2/ya.make
deleted file mode 100644
index 82158e6ab3..0000000000
--- a/contrib/libs/blake2/ya.make
+++ /dev/null
@@ -1,49 +0,0 @@
-# Generated by devtools/yamaker from nixpkgs 22.11.
-
-LIBRARY()
-
-LICENSE(CC0-1.0)
-
-LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-
-VERSION(0.98.1)
-
-ORIGINAL_SOURCE(https://github.com/BLAKE2/libb2/archive/v0.98.1.tar.gz)
-
-ADDINCL(
- contrib/libs/blake2/src
-)
-
-NO_COMPILER_WARNINGS()
-
-NO_RUNTIME()
-
-CFLAGS(
- -DHAVE_CONFIG_H
- -DSUFFIX=
-)
-
-SRCS(
- src/blake2-dispatch.c
- src/blake2bp.c
- src/blake2sp.c
-)
-
-SRC(src/blake2b-ref.c -DSUFFIX=_ref)
-
-SRC(src/blake2s-ref.c -DSUFFIX=_ref)
-
-IF (ARCH_X86_64)
- SRC_C_AVX(src/blake2b.c -DSUFFIX=_avx)
- SRC_C_SSE2(src/blake2b.c -DSUFFIX=_sse2)
- SRC_C_SSE41(src/blake2b.c -DSUFFIX=_sse41)
- SRC_C_SSSE3(src/blake2b.c -DSUFFIX=_ssse3)
- SRC_C_XOP(src/blake2b.c -DSUFFIX=_xop)
- SRC_C_AVX(src/blake2s.c -DSUFFIX=_avx)
- SRC_C_SSE2(src/blake2s.c -DSUFFIX=_sse2)
- SRC_C_SSE41(src/blake2s.c -DSUFFIX=_sse41)
- SRC_C_SSSE3(src/blake2s.c -DSUFFIX=_ssse3)
- SRC_C_XOP(src/blake2s.c -DSUFFIX=_xop)
-ENDIF()
-
-END()
diff --git a/contrib/libs/libarchive/CONTRIBUTING.md b/contrib/libs/libarchive/CONTRIBUTING.md
deleted file mode 100644
index 9ccc45c3d1..0000000000
--- a/contrib/libs/libarchive/CONTRIBUTING.md
+++ /dev/null
@@ -1,98 +0,0 @@
-Thank you for helping us improve libarchive.
-The following guidelines will help ensure your contribution gets prompt attention.
-
-# Bugs and other Issues
-
-If you encounter any problems with libarchive,
-[please file an issue on our issue tracker](https://github.com/libarchive/libarchive/issues).
-
-All bug reports should include the following information. You can copy the text below directly into the issue tracker to get started:
-
-```
-Basic Information
- Version of libarchive:
- How you obtained it: (build from source, pre-packaged binary, etc)
- Operating system and version:
- What compiler and/or IDE you are using (include version):
-
-If you are using a pre-packaged binary
- Exact package name and version:
- Repository you obtained it from:
-
-Description of the problem you are seeing:
- What did you do?
- What did you expect to happen?
- What actually happened?
- What log files or error messages were produced?
-
-How the libarchive developers can reproduce your problem:
- What other software was involved?
- What other files were involved?
- How can we obtain any of the above?
-```
-
-Depending on the specific type of issue, other information will be helpful:
-
-## Test Failures
-
-If you see any test failures, please include the information above and also:
-
-* Names of the tests that failed.
-
-* Look for the .log files in the /tmp/libarchive_test_*date-and-time* directories. (On Mac OS, look in $TMPDIR which is different than /tmp.)
-
-Please paste the .log files you will find there directly into your report.
-
-
-## Problems using libarchive in a program
-
-If you are trying to write a program using libarchive, please include the information above and also:
-
-* It will help us if we can actually run the program. This is easiest if you can provide source to a short program that illustrates your problem.
-
-* If you have a sufficiently short program that shows the problem, you can either paste it into the report or [put it into a gist](https://gist.github.com).
-
-
-## Libarchive produced incorrect output
-
-Please tell us what program you ran, any command-line arguments you provided, and details of the input files (`ls -l` output is helpful here). If the problem involved a command-line program, please copy the full terminal text into the report, including the command line and any error messages.
-
-Please try to make the output file available to us. Unless it is very large, you can upload it into a fresh github repository and provide a link in your issue report.
-
-
-## Libarchive could not read a particular input file
-
-Note: If you can provide a **very small** input file that reproduces the problem, we can add that to our test suite. This will ensure that the bug does not reappear in the future.
-
-A link to the relevant file is usually sufficient.
-
-If you cannot provide the input file or a link to the file, please let us know if there is some other way to obtain it.
-
-
-## Documentation improvements
-
-We are always interested in improving the libarchive documentation. Please tell us about any errors you find, including:
-
-* Typos or errors in the manpages provided with libarchive source.
-
-* Mistakes in the [libarchive Wiki](https://github.com/libarchive/libarchive/wiki)
-
-* Problems with the PDF or Wiki files that are automatically generated from the manpages.
-
-
-# Code Submissions
-
-We welcome all code submissions. But of course, some code submissions are easier for us to respond to than others. The best code submissions:
-
-* Address a single issue. There have been many cases where a simple fix to an obvious problem did not get handled for months because the patch that was provided also included an unrelated change affecting an especially complex area of the code.
-
-* Follow existing libarchive code style and conventions. Libarchive generally follows [BSD KNF](https://www.freebsd.org/cgi/man.cgi?query=style&sektion=9) for formatting code.
-
-* Do not make unnecessary changes to existing whitespace, capitalization, or spelling.
-
-* Include detailed instructions for reproducing the problem you're fixing. We do try to verify that a submission actually fixes a real problem. If we can't reproduce the problem, it will take us longer to evaluate the fix. For this reason, we encourage you to file an issue report first with details on reproducing the problem, then refer to that issue in your pull request.
-
-* Includes a test case. The libarchive Wiki has [detailed documentation for adding new test cases](https://github.com/libarchive/libarchive/wiki/LibarchiveAddingTest).
-
-* Are provided via Github pull requests. We welcome patches in almost any format, but github's pull request management makes it significantly easier for us to evaluate and test changes.
-
diff --git a/contrib/libs/libarchive/COPYING b/contrib/libs/libarchive/COPYING
deleted file mode 100644
index 1b9723574a..0000000000
--- a/contrib/libs/libarchive/COPYING
+++ /dev/null
@@ -1,65 +0,0 @@
-The libarchive distribution as a whole is Copyright by Tim Kientzle
-and is subject to the copyright notice reproduced at the bottom of
-this file.
-
-Each individual file in this distribution should have a clear
-copyright/licensing statement at the beginning of the file. If any do
-not, please let me know and I will rectify it. The following is
-intended to summarize the copyright status of the individual files;
-the actual statements in the files are controlling.
-
-* Except as listed below, all C sources (including .c and .h files)
- and documentation files are subject to the copyright notice reproduced
- at the bottom of this file.
-
-* The following source files are also subject in whole or in part to
- a 3-clause UC Regents copyright; please read the individual source
- files for details:
- libarchive/archive_read_support_filter_compress.c
- libarchive/archive_write_add_filter_compress.c
- libarchive/mtree.5
-
-* The following source files are in the public domain:
- libarchive/archive_getdate.c
-
-* The following source files are triple-licensed with the ability to choose
- from CC0 1.0 Universal, OpenSSL or Apache 2.0 licenses:
- libarchive/archive_blake2.h
- libarchive/archive_blake2_impl.h
- libarchive/archive_blake2s_ref.c
- libarchive/archive_blake2sp_ref.c
-
-* The build files---including Makefiles, configure scripts,
- and auxiliary scripts used as part of the compile process---have
- widely varying licensing terms. Please check individual files before
- distributing them to see if those restrictions apply to you.
-
-I intend for all new source code to use the license below and hope over
-time to replace code with other licenses with new implementations that
-do use the license below. The varying licensing of the build scripts
-seems to be an unavoidable mess.
-
-
-Copyright (c) 2003-2018 <author(s)>
-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
- in this position and unchanged.
-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(S) ``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(S) 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.
diff --git a/contrib/libs/libarchive/INSTALL b/contrib/libs/libarchive/INSTALL
deleted file mode 100644
index 2fafbd5046..0000000000
--- a/contrib/libs/libarchive/INSTALL
+++ /dev/null
@@ -1,35 +0,0 @@
-More complete build documentation is available on the libarchive
-Wiki: https://github.com/libarchive/libarchive/wiki
-
-On most Unix-like systems, you should be able to install libarchive,
-bsdtar, and bsdcpio using the following common steps:
- ./configure
- make
- make install
-
-If you need to customize the target directories or otherwise adjust
-the build setting, use
- ./configure --help
-to list the configure options.
-
-If you are developing libarchive and need to update the
-configure script and other build files:
- /bin/sh build/autogen.sh
-
-To create a distribution, please use the 'distcheck' target:
- /bin/sh build/autogen.sh && ./configure && make distcheck
-
-On Unix-like and non-Unix-like systems, use the "cmake" utility (available from
-http://cmake.org/) to generate suitable build files for your platform.
-Cmake requires the name of the directory containing CmakeLists.txt and
-the "generator" to use for your build environment. For example, to
-build with Xcode on Mac OS, you can use the following command:
- cmake -G "Xcode" ~/libarchive-download-dir/
-The result will be appropriate makefiles, solution files, or project
-files that can be used with the corresponding development tool.
-The default on Unix-like systems is to generate Makefiles, so you
-can also use cmake instead of the configure script:
- cmake ~/libarchive-download-dir/
- make
- make install
-See the libarchive Wiki or the cmake site for further documentation.
diff --git a/contrib/libs/libarchive/NEWS b/contrib/libs/libarchive/NEWS
deleted file mode 100644
index 7509c9ce5f..0000000000
--- a/contrib/libs/libarchive/NEWS
+++ /dev/null
@@ -1,755 +0,0 @@
-Jul 29, 2023: libarchive 3.7.1 released
-
-Jul 18, 2023: libarchive 3.7.0 released
-
-Jul 14, 2023: bsdunzip port from FreeBSD
-
-Dec 07, 2022: libarchive 3.6.2 released
-
-Apr 08, 2022: libarchive 3.6.1 released
-
-Feb 09, 2022: libarchive 3.6.0 released
-
-Feb 08, 2022: libarchive 3.5.3 released
-
-Aug 22, 2021: libarchive 3.5.2 released
-
-Dec 26, 2020: libarchive 3.5.1 released
-
-Dec 01, 2020: libarchive 3.5.0 released
-
-Oct 14, 2020: Support for system extended attributes
-
-May 20, 2020: libarchive 3.4.3 released
-
-Apr 30, 2020: Support for pzstd compressed files
-
-Apr 16, 2020: Support for RHT.security.selinux tar extended attribute
-
-Feb 11, 2020: libarchive 3.4.2 released
-
-Jan 23, 2020: Important fixes for writing XAR archives
-
-Jan 20, 2020: New tar option: --safe-writes (atomical file extraction)
-
-Jan 03, 2020: Support mbed TLS (PolarSSL) as optional crypto provider
-
-Dec 30, 2019: libarchive 3.4.1 released
-
-Dec 11, 2019: New pax write option "xattrhdr"
-
-Nov 17, 2019: Unicode filename support for reading lha/lzh archives
-
-Jun 11, 2019: libarchive 3.4.0 released
-
-May 18, 2019: Fixes for reading Android APK and JAR archives
-
-Apr 16, 2019: Support for non-recursive list and extract
-
-Apr 14, 2019: New tar option: --exclude-vcs
-
-Mar 27, 2019: Support for file and directory symlinks on Windows
-
-Mar 12, 2019: Important fixes for storing file attributes and flags
-
-Jan 20, 2019: Support for xz, lzma, ppmd8 and bzip2 decompression in ZIP files
-
-Oct 06, 2018: RAR 5.0 reader
-
-Sep 03, 2018: libarchive 3.3.3 released
-
-Jul 19, 2018: Avoid super-linear slowdown on malformed mtree files
-
-Jan 27, 2018: Many fixes for building with Visual Studio
-
-Oct 19, 2017: NO_OVERWRITE doesn't change existing directory attributes
-
-Aug 12, 2017: New support for Zstandard read and write filters
-
-Jul 09, 2017: libarchive 3.3.2 released
-
-Mar 16, 2017: NFSv4 ACL support for Linux (librichacl)
-
-Feb 26, 2017: libarchive 3.3.1 released
- Security & Feature release
-
-Feb 19, 2017: libarchive 3.3.0 released
- Security & Feature release
-
-Jan 29, 2017: Limited NFSv4 ACL support for Mac OS (Darwin)
-
-Jan 10, 2017: POSIX.1e and NFSv4 ACL support for Solaris and derivates
-
-Dec 27, 2016: NFSv4 ACL read and write support for pax
- Deprecated functions: archive_entry_acl_text(), archive_entry_acl_text_w()
-
-Nov, 2016: libarchive is now being tested by the OSS-Fuzz project
-
-Oct 26, 2016: Remove liblzmadec support
-
-Oct 23, 2016: libarchive 3.2.2 released
- Security release
-
-Jun 20, 2016: libarchive 3.2.1 released
- This fixes a handful of security and other critical issues with 3.2.0
-
-May 01, 2016: libarchive 3.2.0 released
-
-Apr 09, 2016: libarchive 3.1.901a released
- Another test release in preparation for 3.2.0
-
-Feb 13, 2016: libarchive 3.1.900a released
- This is a test release in preparation for 3.2.0
-
-Oct 21, 2015: Preliminary port to OSF
-
-Apr 11, 2015: libarchive's issue tracker is now hosted at GitHub.
- https://github.com/libarchive/libarchive/issues
-
-Early 2015: Many fixes to crash and overflow bugs thanks to Hanno Boeck
-
-Oct 13, 2014: Zip encryption and decryption support
-
-Aug 13, 2014: Add support for lz4 compression.
-
-Jun 10, 2014: Add warc format support
-
-May 3, 2014: Add experimental Zip streaming extension
-
-Apr 6, 2014: Add bsdcat command-line tool
-
-Jan 12, 2014: Add Zip64 support
-
-Dec 1, 2013: Rewrite Zip write logic
-
-Jul 1, 2013: Add ability to detect encrypted entries for many formats
- (This does not add the ability to *decrypt* those entries, however)
-
-Feb 23, 2013: "raw" write support added
-
-Feb 09, 2013: libarchive 3.1.2 released
-
-Jan 28, 2013: libarchive's new website moved to http://www.libarchive.org.
-
-Jan 13, 2013: libarchive 3.1.1 released
-
-Jan 13, 2013: libarchive 3.1.0 released
-
-Dec 07, 2012: Implement functions to manually set the format and filters used.
-
-Nov 11, 2012: Add support for __MACOSX directory in Zip archives, which resource
- forks are stored in.
-
-Oct 20, 2012: Add support for writing v7 tar format.
-
-Oct 09, 2012: Add support for grzip compression.
-
-Oct 07, 2012: Introduce b64encode filter.
-Oct 07, 2012: Introduce uuencode filter.
-
-Oct 06, 2012: Add support for lzop.
-
-Sep 27, 2012: Implement function used to seek within data blocks.
- (Currently only supported for uncompressed RAR archives).
-
-Apr 22, 2012: Add basic archive read and write filter support for lrzip.
-
-Mar 27, 2012: libarchive 3.0.4 released
-
-Feb 05, 2012: libarchive development now hosted at GitHub.
- http://libarchive.github.com/
-Feb 05, 2012: libarchive's issue tracker remains at Google Code.
- http://code.google.com/p/libarchive/issues/list
-Feb 05, 2012: libarchive's mailing lists remain at Google Groups.
-
-Dec 24, 2011: libarchive 3.0.2 released
-Dec 23, 2011: Various fixes merged from FreeBSD
-Dec 23, 2011: Symlink support in Zip reader and writer
-Dec 23, 2011: Robustness fixes to 7Zip reader
-
-Nov 27, 2011: libarchive 3.0.1b released
-
-Nov 26, 2011: 7Zip reader
-Nov 26, 2011: Small fixes to ISO and Zip to improve robustness with corrupted input
-Nov 24, 2011: Improve streaming Zip reader's support for uncompressed entries
-Nov 20, 2011: New seeking Zip reader supports SFX Zip archives
-Nov 20, 2011: Build fixes on Windows
-
-Nov 13, 2011: libarchive 3.0.0a released
-
-Nov 06, 2011: Update shared-library version calculations for libarchive 3.x
-Sep 04, 2011: Fix tar -s; follow GNU tar for controlling hardlink/symlink substitutions
-Aug 18, 2011: Fix reading ISO images built by NetBSD's mkisofs
-Aug 15, 2011: Old archive_read_support_compression_XXX functions are deprecated and
- will disappear in libarchive 4.0.
-Jun 26, 2011: RAR reader
-Jun 16, 2011: Add tar:compat-2x option to emulate broken libarchive 2.x
- handling of pax UTF-8 headers
-Apr 25, 2011: Refactor read_open() into a collection of single-item setters;
- support the old interfaces as wrappers
-Apr 12, 2011: Split disk writer into separate POSIX and Windows implementations
-Apr 10, 2011: Improvements to character translations on Windows.
-Mar 30, 2011: More work to return errors instead of calling abort()
-Mar 23, 2011: Add charset option to many writers to control MBCS filenames
-Mar 17, 2011: Overhauled support for per-format extension options
-Mar 17, 2011: Track character set used for mbcs strings, support
- translating to/from user-specified locale
-Mar 09, 2011: Recognize mtree files without requiring a signature
-Mar 06, 2011: Use iconv to convert to/from Unicode instead of making bad
- assumptions about the C90 character set translation functions
-Feb 17, 2011: Fixes for AIX, TRU64, and other platforms
-Dec 22, 2010: CAB reader
-Dec 20, 2010: LHA/LZH reader
-Jul 03, 2010: minitar example demonstrates archive_read_disk directory traversal
-Jun 29, 2010: Many improvements to ISO reader compatibility
-Jun 26, 2010: Use larger buffers when copy files into an archive
-Jun 18, 2010: Reimplement Mac OS extensions in libarchive
-Jun 09, 2010: archive_read_disk now supports traversals
-May 28, 2010: XAR writer
-May 16, 2010: Fix ^T handling; don't exit on interrupted reads and writes
-May 09, 2010: Improved detection of platform-specific crypto support
-May 04, 2010: lzip read and write filters
-May 01, 2010: New options: tar --gid --gname --uid --uname
-Apr 28, 2010: Use Red-black tree for ISO reader/writer to improve performance
-Apr 17, 2010: Minimal writer for legacy GNU tar format
-Mar 12, 2010: Don't dereference symlinks on Linux when reading ACLs.
-Mar 06, 2010: Fix build when an older libarchive is already installed
-Feb 28, 2010: Relax handling of state failures; misuse by clients now generally
- results in a sticky ARCHIVE_FATAL rather than a visit to abort()
-Feb 25, 2010: ISO writer
-Feb 21, 2010: Split many man pages into smaller chunks.
-Feb 21, 2010: Performance: Cheat on block sizes when reading archives from disk.
-Feb 21, 2010: Use int64_t instead of off_t, dev_t, ino_t, uid_t, and gid_t
-Feb 20, 2010: Document new ACL functions.
-Feb 19, 2010: Support multiple write filters
-Feb 07, 2010: Remove some legacy libarchive 1.x APIs
-Feb 04, 2010: Read afio headers
-Feb 02, 2010: Archive sparse files compatibly with GNU tar
-Feb 01, 2010: Integrate Apple extensions for Mac OS extended attributes into bsdtar
-Jan 31, 2010: Support cpio -V
-
-Feb 04, 2010: libarchive 2.8.0 released
-Jan 17, 2010: Fix error handling for 'echo nonexistent | cpio -o'
-Jan 17, 2010: Don't use futimes() on Cygwin
-
-Jan 02, 2010: libarchive 2.7.902a released (test release for 2.8)
-Jan 02, 2010: Fix tar/test/test_windows on MinGW
-Jan 02, 2010: Fix memory leaks in libarchive tests
-Jan 01, 2010: Fix memory leak when filter startup fails
-
-Dec 27, 2009: libarchive 2.7.901a released (test release for 2.8)
-
-Aug 04, 2009: libarchive 2.7.1 released
-Jul 20, 2009: Suppress bogus warning about unxz
-Jul 19, 2009: Support Cygwin 1.7
-Jun 11, 2009: Support lzma/xz files compressed with larger buffer sizes.
-May 24, 2009: Handle gzip files signed with OpenBSD "gzsig" program.
-May 07, 2009: Avoid false failures when reading from pipe.
-
-Apr 16, 2009: libarchive 2.7.0 released
-
-Apr 10, 2009: libarchive 2.6.992a released
-Apr 09, 2009: Fix SIGPIPE issue building with MSVC.
-Apr 09, 2009: Fix several minor memory leaks in libarchive and libarchive_test
-
-Apr 08, 2009: libarchive 2.6.991a released
-Apr 07, 2009: Additional tests added to bsdcpio_test
-
-Apr 01, 2009: libarchive 2.6.990a released
-Apr 01, 2009: Use command-line gunzip, bunzip2, unxz, unlzma for
- decompression if the library is built without suitable
- libraries. The setup functions return ARCHIVE_WARN
- in this case so clients can adapt if necessary.
-Apr 01, 2009: Use getpw*_r and getgr*_r functions for thread-safety.
-Mar 24, 2009: Add archive_read_next_header2(), which is up to 25%
- more efficient for some clients; from Brian Harring.
-Mar 22, 2009: PDF versions of manpages are now included in the distribution.
-Mar, 2009: Major work to improve Cygwin build by Charles Wilson.
-Feb/Mar, 2009: Major work on cmake build support, mostly by Michihiro NAKAJIMA.
-Feb/Mar, 2009: Major work on Visual Studio support by Michihiro NAKAJIMA.
- All tests now pass.
-Feb 25, 2009: Fix Debian Bug #516577
-Feb 21, 2009: Yacc is no longer needed to build; date parser rewritten in C.
-Jan/Feb, 2009: Mtree work by Michihiro.
-Feb, 2009: Joliet support by Andreas Henriksson.
-Jan/Feb, 2009: New options framework by Michihiro.
-Feb, 2009: High-res timestamps on Tru64, AIX, and GNU Hurd, by Björn Jacke.
-Jan 18, 2009: Extended attributes work on FreeBSD and Linux now with pax format.
-Jan 07, 2009: New archive_read_disk_entry_from_file() knows about ACLs,
- extended attributes, etc so that bsdtar and bsdcpio don't require
- such system-specific knowledge.
-Jan 03, 2009: Read filter system extensively refactored. In particular,
- read filter pipelines are now built out automatically and individual
- filters should be much easier to implement. Documentation on the
- Googlecode Wiki explains how to implement new filters.
-Dec 28, 2008: Many Windows/Visual Studio fixes from Michihiro NAKAJIMA.
-
-Dec 28, 2008: Main libarchive development moved from FreeBSD Perforce
- server to Google Code. This should make it easier for more
- people to participate in libarchive development.
-
-Dec 28, 2008: libarchive 2.6.0 released
-Dec 25, 2008: libarchive 2.5.905a released
-Dec 10, 2008: libarchive 2.5.904a released
-Dec 04, 2008: libarchive 2.5.903a released
-Nov 09, 2008: libarchive 2.5.902a released
-Nov 08, 2008: libarchive 2.5.901a released
-Nov 08, 2008: Start of pre-release testing for libarchive 2.6
-
-Nov 07, 2008: Read filter refactor: The decompression routines just
- consume and produce arbitrarily-sized blocks. The reblocking
- from read_support_compression_none() has been pulled into the
- read core. Also, the decompression bid now makes multiple
- passes and stacks read filters.
-Oct 21, 2008: bsdcpio: New command-line parser.
-Oct 19, 2008: Internal read_ahead change: short reads are now an error
-Oct 06, 2008: bsdtar: option parser no longer uses getopt_long(),
- gives consistent option parsing on all platforms.
-Sep 19, 2008: Jaakko Heinonen: shar utility built on libarchive
-Sep 17, 2008: Pedro Giffuni: birthtime support
-Sep 17, 2008: Miklos Vajna: lzma reader and test. Note: I still have
- some concerns about the auto-detection (LZMA file format
- doesn't support auto-detection well), so this is not yet
- enabled under archive_read_support_compression_all(). For
- now, you must call archive_read_support_compression_lzma() if
- you want LZMA read support.
-Sep 11, 2008: Ivailo Petrov: Many fixes to Windows build, new solution files
-Jul 26, 2008: archive_entry now tracks which values have not been set.
- This helps zip extraction (file size is often "unknown") and
- time restores (tar usually doesn't know atime).
-Jul 26, 2008: Joerg Sonnenberger: Performance improvements to shar writer
-Jul 25, 2008: Joerg Sonnenberger: mtree write support
-
-Jul 02, 2008: libarchive 2.5.5 released
-
-Jul 02, 2008: libarchive 2.5.5b released
-Jul 01, 2008: bsdcpio is being used by enough people, we can call it 1.0.0 now
-Jun 20, 2008: bsdcpio: If a -l link fails with EXDEV, copy the file instead
-Jun 19, 2008: bsdcpio: additional long options for better GNU cpio compat
-Jun 15, 2008: Many small portability and bugfixes since 2.5.4b.
-
-May 25, 2008: libarchive 2.5.4b released
-May 21, 2008: Joerg Sonnenberger: fix bsdtar hardlink handling for newc format
-
-May 21, 2008: More progress on Windows building. Thanks to "Scott"
- for the Windows makefiles, thanks to Kees Zeelenberg for
- code contributions.
-
-May 21, 2008: Fix a number of non-exploitable integer and buffer overflows,
- thanks to David Remahl at Apple for pointing these out.
-
-May 21, 2008: Colin Percival: SIGINFO or SIGUSR1 to bsdtar prints progress info
-
-May 16, 2008: bsdtar's test harness no longer depends on file ordering.
- This was causing spurious test failures on a lot of systems.
- Thanks to Bernhard R. Link for the diagnosis.
-
-May 14, 2008: Joerg Sonnenberger: -s substitution support for bsdtar
-
-May 13, 2008: Joerg Sonnenberger: Many mtree improvements
-
-May 11, 2008: Joerg Sonnenberger: fix hardlink extraction when
- hardlinks have different permissions from original file
-
-April 30, 2008: Primary libarchive work has been moved into the FreeBSD
- project's Perforce repository: http://perforce.freebsd.org/
- The libarchive project can be browsed at
- //depot/user/kientzle/libarchive-portable
- Direct link: http://preview.tinyurl.com/46mdgr
-
-May 04, 2008: libarchive 2.5.3b released
- * libarchive: Several fixes to link resolver to address bsdcpio crashes
- * bsdcpio: -p hardlink handling fixes
- * tar/pax: Ensure ustar dirnames end in '/'; be more careful about
- measuring filenames when deciding what pathname fields to use
- * libarchive: Mark which entry strings are set; be accurate about
- distinguishing empty strings ("") from unset ones (NULL)
- * tar: Don't crash reading entries with empty filenames
- * libarchive_test, bsdtar_test, bsdcpio_test: Better defaults:
- run all tests, delete temp dirs, summarize repeated failures
- * -no-undefined to libtool for Cygwin
- * libarchive_test: Skip large file tests on systems with 32-bit off_t
- * iso9660: Don't bother trying to find the body of an empty file;
- this works around strange behavior from some ISO9660 writers
- * tar: allow -r -T to be used together
- * tar: allow --format with -r or -u
- * libarchive: Don't build archive.h
-
-May 04, 2008: Simplified building: archive.h is no longer constructed
- This may require additional #if conditionals on some platforms.
-
-Mar 30, 2008: libarchive 2.5.1b released
-
-Mar 15, 2008: libarchive 2.5.0b released
-Mar 15, 2008: bsdcpio now seems to correctly write hardlinks into newc,
- ustar, and old cpio archives. Just a little more testing before
- bsdcpio 1.0 becomes a reality.
-Mar 15, 2008: I think the new linkify() interface is finally handling
- all known hardlink strategies.
-Mar 15, 2008: Mtree read fixes from Joerg Sonnenberger.
-Mar 15, 2008: Many new bsdtar and bsdcpio options from Joerg Sonnenberger.
-Mar 15, 2008: test harnesses no longer require uudecode; they
- now have built-in decoding logic that decodes the reference
- files as they are needed.
-
-Mar 14, 2008: libarchive 2.4.14 released; identical to 2.4.13 except for
- a point fix for gname/uname mixup in pax format that was introduced
- with the UTF-8 fixes.
-
-Feb 26, 2008: libarchive 2.4.13 released
-Feb 25, 2008: Handle path, linkname, gname, or uname that can't be converted
- to/from UTF-8. Implement "hdrcharset" attribute from SUS-2008.
-Feb 25, 2008: Fix name clash on NetBSD.
-Feb 18, 2008: Fix writing empty 'ar' archives, per Kai Wang
-Feb 18, 2008: [bsdtar] Permit appending on block devices.
-Feb 09, 2008: New "linkify" resolver to help with newc hardlink writing;
- bsdcpio still needs to be converted to use this.
-Feb 02, 2008: Windows compatibility fixes from Ivailo Petrov, Kees Zeelenberg
-Jan 30, 2008: Ignore hardlink size for non-POSIX tar archives.
-
-Jan 22, 2008: libarchive 2.4.12 released
-Jan 22, 2008: Fix bad padding when writing symlinks to newc cpio archives.
-Jan 22, 2008: Verify bsdcpio_test by getting it to work against GNU cpio 2.9.
- bsdcpio_test complains about missing options (-y and -z), format
- of informational messages (--version, --help), and a minor formatting
- issue in odc format output. After this update, bsdcpio_test uncovered
- several more cosmetic issues in bsdcpio, all now fixed.
-Jan 22, 2008: Experimental support for self-extracting Zip archives.
-Jan 22, 2008: Extend hardlink restore strategy to work correctly with
- hardlinks extracted from newc cpio files. (Which store the body
- only with the last occurrence of a link.)
-
-Dec 30, 2007: libarchive 2.4.11 released
-Dec 30, 2007: Fixed a compile error in bsdcpio on some systems.
-
-Dec 29, 2007: libarchive 2.4.10 released
-Dec 29, 2007: bsdcpio 0.9.0 is ready for wider use.
-Dec 29, 2007: Completed initial test harness for bsdcpio.
-
-Dec 22, 2007: libarchive 2.4.9 released
-Dec 22, 2007: Implement the remaining options for bsdcpio: -a, -q, -L, -f,
- pattern selection for -i and -it.
-
-Dec 13, 2007: libarchive 2.4.8 released
-Dec 13, 2007: gzip and bzip2 compression now handle zero-byte writes correctly,
- Thanks to Damien Golding for bringing this to my attention.
-
-Dec 12, 2007: libarchive 2.4.7 released
-
-Dec 10, 2007: libarchive 2.4.6 released
-Dec 09, 2007: tar/test/test_copy.c verifies "tar -c | tar -x" copy pipeline
-Dec 07, 2007: Fix a couple of minor memory leaks.
-
-Dec 04, 2007: libarchive 2.4.5 released
-Dec 04, 2007: Fix cpio/test/test_write_odc by setting the umask first.
-
-Dec 03, 2007: libarchive 2.4.4 released
-Dec 03, 2007: New configure options --disable-xattr and --disable-acl,
- thanks to Samuli Suominen.
-
-Dec 03, 2007: libarchive 2.4.3 released
-Dec 03, 2007: Thanks to Lapo Luchini for sending me a ZIP file that
- libarchive couldn't handle. Fixed a bug in handling of
- "length at end" flags in ZIP files.
-Dec 03, 2007: Fixed bsdcpio -help, bsdtar -help tests.
-Dec 02, 2007: First cut at real bsdtar test harness.
-
-Dec 02, 2007: libarchive 2.4.2 released
-
-Dec 02, 2007: libarchive 2.4.1 released
-Dec 02, 2007: Minor fixes, rough cut of mdoc-to-man conversion for
- man pages.
-
-Oct 30, 2007: libarchive 2.4.0 released
-Oct 30, 2007: Minor compile fix thanks to Joerg Schilling.
-Oct 30, 2007: Only run the format auction once at the beginning of the
- archive. This is simpler and supports better error recovery.
-Oct 29, 2007: Test support for very large entries in tar archives:
- libarchive_test now exercises entries from 2GB up to 1TB.
-
-Oct 27, 2007: libarchive 2.3.5 released
-Oct 27, 2007: Correct some unnecessary internal data copying in the
- "compression none" reader and writer; this reduces user time
- by up to 2/3 in some tests. (Thanks to Jan Psota for
- publishing his performance test results to GNU tar's bug-tar
- mailing list; those results pointed me towards this problem.)
-Oct 27, 2007: Fix for skipping archive entries that are exactly
- a multiple of 4G on 32-bit platforms.
-Oct 25, 2007: Fix for reading very large (>8G) tar archives; this was
- broken when I put in support for new GNU tar sparse formats.
-Oct 20, 2007: Initial work on new pattern-matching code for cpio; I
- hope this eventually replaces the code currently in bsdtar.
-
-Oct 08, 2007: libarchive 2.3.4 released
-Oct 05, 2007: Continuing work on bsdcpio test suite.
-Oct 05, 2007: New cpio.5 manpage, updates to "History" of bsdcpio.1 and
- bsdtar.1 manpages.
-Oct 05, 2007: Fix zip reader to immediately return EOF if you try
- to read body of non-regular file. In particular, this fixes
- bsdtar extraction of zip archives.
-
-Sep 30, 2007: libarchive 2.3.3 released
-Sep 26, 2007: Rework Makefile.am so that the enable/disable options
- actually do the right things.
-Sep 26, 2007: cpio-odc and cpio-newc archives no longer write bodies
- for non-regular files.
-Sep 26, 2007: Test harness for bsdcpio is in place, needs more tests written.
- This is much nicer than the ragtag collection of test scripts
- that bsdtar has.
-
-Sep 20, 2007: libarchive 2.3.2 released
-Sep 20, 2007: libarchive 2.3.1 broke bsdtar because the archive_write_data()
- fix was implemented incorrectly.
-
-Sep 16, 2007: libarchive 2.3.1 released
-Sep 16, 2007: Many fixes to bsdcpio 0.3: handle hardlinks with -p, recognize
- block size on writing, fix a couple of segfaults.
-Sep 16, 2007: Fixed return value from archive_write_data() when used
- with archive_write_disk() to match the documentation and other
- instances of this same function.
-Sep 15, 2007: Add archive_entry_link_resolver, archive_entry_strmode
-
-Sep 11, 2007: libarchive 2.2.8 released
-Sep 09, 2007: bsdcpio 0.2 supports most (not yet all) of the old POSIX spec.
-
-Sep 01, 2007: libarchive 2.2.7 released
-Aug 31, 2007: Support for reading mtree files, including an mtree.5 manpage
- (A little experimental still.)
-Aug 18, 2007: Read gtar 1.17 --posix --sparse entries.
-Aug 13, 2007: Refined suid/sgid restore handling; it is no longer
- an error if suid/sgid bits are dropped when you request
- perm restore but don't request owner restore.
-Aug 06, 2007: Use --enable-bsdcpio if you want to try bsdcpio
-
-Aug 05, 2007: libarchive 2.2.6 released
-Aug 05, 2007: New configure option --disable-bsdtar, thanks to Joerg
- Sonnenberger.
-Aug 05, 2007: Several bug fixes from FreeBSD CVS repo.
-
-Jul 13, 2007: libarchive 2.2.5 released
-
-Jul 12, 2007: libarchive 2.2.4 released
-Jul 12, 2007: Thanks to Colin Percival's help in diagnosing and
- fixing several critical security bugs. Details available at
- http://security.freebsd.org/advisories/FreeBSD-SA-07:05.libarchive.asc
-
-May 26, 2007: libarchive 2.2.3 released
-May 26, 2007: Fix memory leaks in ZIP reader and shar writer, add some
- missing system headers to archive_entry.h, dead code cleanup
- from Colin Percival, more tests for gzip/bzip2, fix an
- EOF anomaly in bzip2 decompression.
-
-May 12, 2007: libarchive 2.2.2 released
-May 12, 2007: Fix archive_write_disk permission restore by cloning
- entry passed into write_header so that permission info is
- still available at finish_entry time. (archive_read_extract()
- worked okay because it held onto the passed-in entry, but
- direct consumers of archive_write_disk would break). This
- required fixing archive_entry_clone(), which now works and has
- a reasonably complete test case.
-May 10, 2007: Skeletal cpio implementation.
-
-May 06, 2007: libarchive 2.2.1 released
-May 06, 2007: Flesh out a lot more of test_entry.c so as to catch
- problems such as the device node breakage before releasing <sigh>.
-May 05, 2007: Fix a bad bug introduced in 2.1.9 that broke device
- node entries in tar archives.
-May 03, 2007: Move 'struct stat' out of archive_entry core as well.
- This removes some portability headaches and fixes a bunch
- of corner cases that arise when manipulating archives on
- dissimilar systems.
-
-Apr 30, 2007: libarchive 2.1.10 released
-Apr 31, 2007: Minor code cleanup.
-
-Apr 24, 2007: libarchive 2.1.9 released
-Apr 24, 2007: Fix some recently-introduced problems with libraries
- (Just let automake handle it and it all works much better.)
- Finish isolating major()/minor()/makedev() in archive_entry.c.
-
-Apr 23, 2007: libarchive 2.1.8 released
-Apr 23, 2007: Minor fixes found from building on MacOS X
-
-Apr 22, 2007: libarchive 2.1.7 released
-Apr 22, 2007: Eliminated all uses of 'struct stat' from the
- format readers/writers. This should improve portability;
- 'struct stat' is now only used in archive_entry and in
- code that actually touches the disk.
-
-Apr 17, 2007: libarchive 2.1.6 released
- Libarchive now compiles and passes all tests on Interix.
-
-Apr 16, 2007: libarchive 2.1.5 released
-
-Apr 15, 2007: libarchive 2.1b2 released
-Apr 15, 2007: New libarchive_internals.3 documentation of internal APIs.
- Not complete, but should prove helpful.
-Apr 15, 2007: Experimental "read_compress_program" and "write_compress_program"
- for using libarchive with external compression. Not yet
- well tested, and likely has portability issues. Feedback
- appreciated.
-
-Apr 14, 2007: libarchive 2.0.31 released
-Apr 14, 2007: More fixes for Interix, more 'ar' work
-
-Apr 14, 2007: libarchive 2.0.30 released
-Apr 13, 2007: libarchive now enforces trailing '/' on dirs
- written to tar archives
-
-Apr 11, 2007: libarchive 2.0.29 released
-Apr 11, 2007: Make it easier to statically configure for different platforms.
-Apr 11, 2007: Updated config.guess, config.sub, libtool
-
-Apr 06, 2007: libarchive 2.0.28 released
-Apr 06, 2007: 'ar' format read/write support thanks to Kai Wang.
-
-Apr 01, 2007: libarchive 2.0.27 released
-Mar 31, 2007: Several minor fixes from Colin Percival and Joerg Sonnenberger.
-
-Mar 12, 2007: libarchive 2.0.25 released
-Mar 12, 2007: Fix broken --unlink flag.
-
-Mar 11, 2007: libarchive 2.0.24 released
-Mar 10, 2007: Correct an ACL blunder that causes any ACL with an entry
- that refers to a non-existent user or group to not be restored correctly.
- The fix both makes the parser more tolerant (so that archives created
- with the buggy ACLs can be read now) and corrects the ACL formatter.
-Mar 10, 2007: More work on test portability to Linux.
-
-Mar 10, 2007: libarchive 2.0.22 released
-Mar 10, 2007: Header cleanups; added linux/fs.h, removed
- some unnecessary headers, added #include guards in bsdtar.
- If you see any obvious compile failures from this, let me know.
-Mar 10, 2007: Work on bsdtar test scripts: not yet robust enough
- to enable as part of "make check", but getting better.
-Mar 10, 2007: libarchive now returns ARCHIVE_FAILED when
- a header write fails in a way that only affects this item.
- Less bad than ARCHIVE_FATAL, but worse than ARCHIVE_WARN.
-
-Mar 07, 2007: libarchive 2.0.21 released
-Mar 07, 2007: Add some ACL tests (only for the system-independent
- portion of the ACL support for now).
-Mar 07, 2007: tar's ability to read ACLs off disk got
- turned off for FreeBSD; re-enable it. (ACL restores and
- libarchive support for storing/reading ACLs from pax
- archives was unaffected.)
-
-Mar 02, 2007: libarchive 2.0.20 released
-Mar 2, 2007: It's not perfect, but it's pretty good.
- Libarchive 2.0 is officially out of beta.
-
-Feb 28, 2007: libarchive 2.0b17 released
-Feb 27, 2007: Make the GID restore checks more robust by checking
- whether the current user has too few or too many privileges.
-
-Feb 26, 2007: libarchive 2.0b15 released
-Feb 26, 2007: Don't lose symlinks when extracting from ISOs.
- Thanks to Diego "Flameeyes" Pettenò for telling me about the
- broken testcase on Gentoo that (finally!) led me to the cause
- of this long-standing bug.
-
-Feb 26, 2007: libarchive 2.0b14 released
-Feb 26, 2007: Fix a broken test on platforms that lack lchmod().
-
-Feb 25, 2007: libarchive 2.0b13 released
-Feb 25, 2007: Empty archives were being written as empty files,
- without a proper end-of-archive marker. Fixed.
-
-Feb 23, 2007: libarchive 2.0b12 released
-Feb 22, 2007: Basic security checks added: _EXTRACT_SECURE_NODOTDOT
- and _EXTRACT_SECURE_SYMLINK. These checks used to be in bsdtar,
- but they belong down in libarchive where they can be used by
- other tools and where they can be better optimized.
-
-Feb 11, 2007: libarchive 2.0b11 released
-Feb 10, 2007: Fixed a bunch of errors in libarchive's handling
- of EXTRACT_PERM and EXTRACT_OWNER, especially relating
- to SUID and SGID bits.
-
-Jan 31, 2007: libarchive 2.0b9 released
-Jan 31, 2007: Added read support for "empty" archives as a
- distinct archive format. Bsdtar uses this to handle, e.g.,
- "touch foo.tar; tar -rf foo.tar"
-
-Jan 22, 2007: libarchive 2.0b6 released
-Jan 22, 2007: archive_write_disk API is now in place. It provides
- a finer-grained interface than archive_read_extract. In particular,
- you can use it to create objects on disk without having an archive
- around (just feed it archive_entry objects describing what you
- want to create), you can override the uname/gname-to-uid/gid lookups
- (minitar uses this to avoid getpwXXX() and getgrXXX() bloat).
-
-Jan 09, 2007: libarchive 2.0a3 released
-Jan 9, 2007: archive_extract is now much better; it handles the
- most common cases with a minimal number of system calls.
- Some features still need a lot of testing, especially corner
- cases involving objects that already exist on disk. I expect
- the next round of API overhaul will simplify building test cases.
-Jan 9, 2007: a number of fixes thanks to Colin Percival, especially
- corrections to the skip() framework and handling of large files.
-Jan 9, 2007: Fixes for large ISOs. The code should correctly handle
- very large ISOs with entries up to 4G. Thanks to Robert Sciuk
- for pointing out these issues.
-
-Sep 05, 2006: libarchive 1.3.1 released
-Sep 5, 2006: Bump version to 1.3 for new I/O wrappers.
-Sep 4, 2006: New memory and FILE read/write wrappers.
-Sep 4, 2006: libarchive test harness is now minimally functional;
- it's located a few minor bugs in error-handling logic
-
-Aug 17, 2006: libarchive 1.2.54 released
-Aug 17, 2006: Outline ABI changes for libarchive 2.0; these
- are protected behind #ifdef's until I think I've found everything
- that needs to change.
-Aug 17, 2006: Fix error-handling in archive_read/write_close()
- They weren't returning any errors before.
-Aug 17, 2006: Fix recursive-add logic to not trigger if it's not set
- Fixes a bug adding files when writing archive to pipe or when
- using archive_write_open() directly.
-Jul 2006: New "skip" handling improves performance extracting
- single files from large uncompressed archives.
-
-Mar 21, 2006: 1.2.52 released
-Mar 21, 2006: Fix -p on platforms that don't have platform-specific
- extended attribute code.
-Mar 20, 2006: Add NEWS file; fill in some older history from other
- files. I'll try to keep this file up-to-date from now on.
-
-OLDER NEWS SUMMARIES
-
-Mar 19, 2006: libarchive 1.2.51 released
-Mar 18, 2006: Many fixes to extended attribute support, including a redesign
- of the storage format to simplify debugging.
-Mar 12, 2006: Remove 'tp' support; it was a fun idea, but not worth
- spending much time on.
-Mar 11, 2006: Incorporated Jaakko Heinonen's still-experimental support
- for extended attributes (Currently Linux-only.).
-Mar 11, 2006: Reorganized distribution package: There is now one tar.gz
- file that builds both libarchive and bsdtar.
-Feb 13, 2006: Minor bug fixes: correctly read cpio device entries, write
- Pax attribute entry names.
-Nov 7, 2005: Experimental 'tp' format support in libarchive. Feedback
- appreciated; this is not enabled by archive_read_support_format_all()
- yet as I'm not quite content with the format detection heuristics.
-Nov 7, 2005: Some more portability improvements thanks to Darin Broady,
- minor bugfixes.
-Oct 12, 2005: Use GNU libtool to build shared libraries on many systems.
-Aug 9, 2005: Correctly detect that MacOS X does not have POSIX ACLs.
-Apr 17, 2005: Kees Zeelenberg has ported libarchive and bsdtar to Windows:
- http://gnuwin32.sourceforge.net/
-Apr 11, 2005: Extended Zip/Zip64 support thanks to Dan Nelson. -L/-h
- fix from Jaakko Heinonen.
-Mar 12, 2005: archive_read_extract can now handle very long
- pathnames (I've tested with pathnames up to 1MB).
-Mar 12, 2005: Marcus Geiger has written an article about libarchive
- http://xsnil.antbear.org/2005/02/05/archive-mit-libarchive-verarbeiten/
- including examples of using it from Objective-C. His MoinX
- http://moinx.antbear.org/ desktop Wiki uses
- libarchive for archiving and restoring Wiki pages.
-Jan 22, 2005: Preliminary ZIP extraction support,
- new directory-walking code for bsdtar.
-Jan 16, 2005: ISO9660 extraction code added; manpage corrections.
-May 22, 2004: Many gtar-compatible long options have been added; almost
- all FreeBSD ports extract correctly with bsdtar.
-May 18, 2004: bsdtar can read Solaris, HP-UX, Unixware, star, gtar,
- and pdtar archives.
diff --git a/contrib/libs/libarchive/README.md b/contrib/libs/libarchive/README.md
deleted file mode 100644
index 727ed49856..0000000000
--- a/contrib/libs/libarchive/README.md
+++ /dev/null
@@ -1,244 +0,0 @@
-# Welcome to libarchive!
-
-The libarchive project develops a portable, efficient C library that
-can read and write streaming archives in a variety of formats. It
-also includes implementations of the common `tar`, `cpio`, and `zcat`
-command-line tools that use the libarchive library.
-
-## Questions? Issues?
-
-* https://www.libarchive.org is the home for ongoing
- libarchive development, including documentation,
- and links to the libarchive mailing lists.
-* To report an issue, use the issue tracker at
- https://github.com/libarchive/libarchive/issues
-* To submit an enhancement to libarchive, please
- submit a pull request via GitHub: https://github.com/libarchive/libarchive/pulls
-
-## Contents of the Distribution
-
-This distribution bundle includes the following major components:
-
-* **libarchive**: a library for reading and writing streaming archives
-* **tar**: the 'bsdtar' program is a full-featured 'tar' implementation built on libarchive
-* **cpio**: the 'bsdcpio' program is a different interface to essentially the same functionality
-* **cat**: the 'bsdcat' program is a simple replacement tool for zcat, bzcat, xzcat, and such
-* **unzip**: the 'bsdunzip' program is a simple replacement tool for Info-ZIP's unzip
-* **examples**: Some small example programs that you may find useful.
-* **examples/minitar**: a compact sample demonstrating use of libarchive.
-* **contrib**: Various items sent to me by third parties; please contact the authors with any questions.
-
-The top-level directory contains the following information files:
-
-* **NEWS** - highlights of recent changes
-* **COPYING** - what you can do with this
-* **INSTALL** - installation instructions
-* **README** - this file
-* **CMakeLists.txt** - input for "cmake" build tool, see INSTALL
-* **configure** - configuration script, see INSTALL for details. If your copy of the source lacks a `configure` script, you can try to construct it by running the script in `build/autogen.sh` (or use `cmake`).
-
-The following files in the top-level directory are used by the 'configure' script:
-
-* `Makefile.am`, `aclocal.m4`, `configure.ac` - used to build this distribution, only needed by maintainers
-* `Makefile.in`, `config.h.in` - templates used by configure script
-
-## Documentation
-
-In addition to the informational articles and documentation
-in the online [libarchive Wiki](https://github.com/libarchive/libarchive/wiki),
-the distribution also includes a number of manual pages:
-
- * bsdtar.1 explains the use of the bsdtar program
- * bsdcpio.1 explains the use of the bsdcpio program
- * bsdcat.1 explains the use of the bsdcat program
- * libarchive.3 gives an overview of the library as a whole
- * archive_read.3, archive_write.3, archive_write_disk.3, and
- archive_read_disk.3 provide detailed calling sequences for the read
- and write APIs
- * archive_entry.3 details the "struct archive_entry" utility class
- * archive_internals.3 provides some insight into libarchive's
- internal structure and operation.
- * libarchive-formats.5 documents the file formats supported by the library
- * cpio.5, mtree.5, and tar.5 provide detailed information about these
- popular archive formats, including hard-to-find details about
- modern cpio and tar variants.
-
-The manual pages above are provided in the 'doc' directory in
-a number of different formats.
-
-You should also read the copious comments in `archive.h` and the
-source code for the sample programs for more details. Please let us
-know about any errors or omissions you find.
-
-## Supported Formats
-
-Currently, the library automatically detects and reads the following formats:
-
- * Old V7 tar archives
- * POSIX ustar
- * GNU tar format (including GNU long filenames, long link names, and sparse files)
- * Solaris 9 extended tar format (including ACLs)
- * POSIX pax interchange format
- * POSIX octet-oriented cpio
- * SVR4 ASCII cpio
- * Binary cpio (big-endian or little-endian)
- * PWB binary cpio
- * ISO9660 CD-ROM images (with optional Rockridge or Joliet extensions)
- * ZIP archives (with uncompressed or "deflate" compressed entries, including support for encrypted Zip archives)
- * ZIPX archives (with support for bzip2, ppmd8, lzma and xz compressed entries)
- * GNU and BSD 'ar' archives
- * 'mtree' format
- * 7-Zip archives (including archives that use zstandard compression)
- * Microsoft CAB format
- * LHA and LZH archives
- * RAR and RAR 5.0 archives (with some limitations due to RAR's proprietary status)
- * XAR archives
-
-The library also detects and handles any of the following before evaluating the archive:
-
- * uuencoded files
- * files with RPM wrapper
- * gzip compression
- * bzip2 compression
- * compress/LZW compression
- * lzma, lzip, and xz compression
- * lz4 compression
- * lzop compression
- * zstandard compression
-
-The library can create archives in any of the following formats:
-
- * POSIX ustar
- * POSIX pax interchange format
- * "restricted" pax format, which will create ustar archives except for
- entries that require pax extensions (for long filenames, ACLs, etc).
- * Old GNU tar format
- * Old V7 tar format
- * POSIX octet-oriented cpio
- * SVR4 "newc" cpio
- * Binary cpio (little-endian)
- * PWB binary cpio
- * shar archives
- * ZIP archives (with uncompressed or "deflate" compressed entries)
- * GNU and BSD 'ar' archives
- * 'mtree' format
- * ISO9660 format
- * 7-Zip archives
- * XAR archives
-
-When creating archives, the result can be filtered with any of the following:
-
- * uuencode
- * gzip compression
- * bzip2 compression
- * compress/LZW compression
- * lzma, lzip, and xz compression
- * lz4 compression
- * lzop compression
- * zstandard compression
-
-## Notes about the Library Design
-
-The following notes address many of the most common
-questions we are asked about libarchive:
-
-* This is a heavily stream-oriented system. That means that
- it is optimized to read or write the archive in a single
- pass from beginning to end. For example, this allows
- libarchive to process archives too large to store on disk
- by processing them on-the-fly as they are read from or
- written to a network or tape drive. This also makes
- libarchive useful for tools that need to produce
- archives on-the-fly (such as webservers that provide
- archived contents of a users account).
-
-* In-place modification and random access to the contents
- of an archive are not directly supported. For some formats,
- this is not an issue: For example, tar.gz archives are not
- designed for random access. In some other cases, libarchive
- can re-open an archive and scan it from the beginning quickly
- enough to provide the needed abilities even without true
- random access. Of course, some applications do require true
- random access; those applications should consider alternatives
- to libarchive.
-
-* The library is designed to be extended with new compression and
- archive formats. The only requirement is that the format be
- readable or writable as a stream and that each archive entry be
- independent. There are articles on the libarchive Wiki explaining
- how to extend libarchive.
-
-* On read, compression and format are always detected automatically.
-
-* The same API is used for all formats; it should be very
- easy for software using libarchive to transparently handle
- any of libarchive's archiving formats.
-
-* Libarchive's automatic support for decompression can be used
- without archiving by explicitly selecting the "raw" and "empty"
- formats.
-
-* I've attempted to minimize static link pollution. If you don't
- explicitly invoke a particular feature (such as support for a
- particular compression or format), it won't get pulled in to
- statically-linked programs. In particular, if you don't explicitly
- enable a particular compression or decompression support, you won't
- need to link against the corresponding compression or decompression
- libraries. This also reduces the size of statically-linked
- binaries in environments where that matters.
-
-* The library is generally _thread safe_ depending on the platform:
- it does not define any global variables of its own. However, some
- platforms do not provide fully thread-safe versions of key C library
- functions. On those platforms, libarchive will use the non-thread-safe
- functions. Patches to improve this are of great interest to us.
-
-* The function `archive_write_disk_header()` is _not_ thread safe on
- POSIX machines and could lead to security issue resulting in world
- writeable directories. Thus it must be mutexed by the calling code.
- This is due to calling `umask(oldumask = umask(0))`, which sets the
- umask for the whole process to 0 for a short time frame.
- In case other thread calls the same function in parallel, it might
- get interrupted by it and cause the executable to use umask=0 for the
- remaining execution.
- This will then lead to implicitely created directories to have 777
- permissions without sticky bit.
-
-* In particular, libarchive's modules to read or write a directory
- tree do use `chdir()` to optimize the directory traversals. This
- can cause problems for programs that expect to do disk access from
- multiple threads. Of course, those modules are completely
- optional and you can use the rest of libarchive without them.
-
-* The library is _not_ thread aware, however. It does no locking
- or thread management of any kind. If you create a libarchive
- object and need to access it from multiple threads, you will
- need to provide your own locking.
-
-* On read, the library accepts whatever blocks you hand it.
- Your read callback is free to pass the library a byte at a time
- or mmap the entire archive and give it to the library at once.
- On write, the library always produces correctly-blocked output.
-
-* The object-style approach allows you to have multiple archive streams
- open at once. bsdtar uses this in its "@archive" extension.
-
-* The archive itself is read/written using callback functions.
- You can read an archive directly from an in-memory buffer or
- write it to a socket, if you wish. There are some utility
- functions to provide easy-to-use "open file," etc, capabilities.
-
-* The read/write APIs are designed to allow individual entries
- to be read or written to any data source: You can create
- a block of data in memory and add it to a tar archive without
- first writing a temporary file. You can also read an entry from
- an archive and write the data directly to a socket. If you want
- to read/write entries to disk, there are convenience functions to
- make this especially easy.
-
-* Note: The "pax interchange format" is a POSIX standard extended tar
- format that should be used when the older _ustar_ format is not
- appropriate. It has many advantages over other tar formats
- (including the legacy GNU tar format) and is widely supported by
- current tar implementations.
-
diff --git a/contrib/libs/libarchive/SECURITY.md b/contrib/libs/libarchive/SECURITY.md
deleted file mode 100644
index 6ca188b603..0000000000
--- a/contrib/libs/libarchive/SECURITY.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# Security Policy
-
-If you have discovered a security vulnerability in this project, please report it
-privately. **Do not disclose it as a public issue.** This gives us time to work with you
-to fix the issue before public exposure, reducing the chance that the exploit will be
-used before a patch is released.
-
-You may submit the report in the following ways:
-
-- send an email to security@libarchive.de; and/or
-- send us a [private vulnerability report](https://github.com/libarchive/libarchive/security/advisories/new)
-
-Please provide the following information in your report:
-
-- A description of the vulnerability and its impact
-- How to reproduce the issue
-
-This project is maintained by volunteers on a reasonable-effort basis. As such, we ask
-that you give me 90 days to work on a fix before public exposure.
diff --git a/contrib/libs/libarchive/config-linux.h b/contrib/libs/libarchive/config-linux.h
deleted file mode 100644
index 50d5a3fc66..0000000000
--- a/contrib/libs/libarchive/config-linux.h
+++ /dev/null
@@ -1,1396 +0,0 @@
-/* config.h. Generated from build/cmake/config.h.in by cmake configure */
-#define __LIBARCHIVE_CONFIG_H_INCLUDED 1
-
-/*
- * Ensure we have C99-style int64_t, etc, all defined.
- */
-
-/* First, we need to know if the system has already defined them. */
-#define HAVE_INT16_T
-#define HAVE_INT32_T
-#define HAVE_INT64_T
-#define HAVE_INTMAX_T
-
-#define HAVE_UINT8_T
-#define HAVE_UINT16_T
-#define HAVE_UINT32_T
-#define HAVE_UINT64_T
-#define HAVE_UINTMAX_T
-
-/* We might have the types we want under other spellings. */
-/* #undef HAVE___INT64 */
-/* #undef HAVE_U_INT64_T */
-/* #undef HAVE_UNSIGNED___INT64 */
-
-/* The sizes of various standard integer types. */
-#define SIZEOF_SHORT 2
-#define SIZEOF_INT 4
-#define SIZEOF_LONG 8
-#define SIZEOF_LONG_LONG 8
-#define SIZEOF_UNSIGNED_SHORT 2
-#define SIZEOF_UNSIGNED 4
-#define SIZEOF_UNSIGNED_LONG 8
-#define SIZEOF_UNSIGNED_LONG_LONG 8
-
-/*
- * If we lack int64_t, define it to the first of __int64, int, long, and long long
- * that exists and is the right size.
- */
-#if !defined(HAVE_INT64_T) && defined(HAVE___INT64)
-typedef __int64 int64_t;
-#define HAVE_INT64_T
-#endif
-
-#if !defined(HAVE_INT64_T) && SIZEOF_INT == 8
-typedef int int64_t;
-#define HAVE_INT64_T
-#endif
-
-#if !defined(HAVE_INT64_T) && SIZEOF_LONG == 8
-typedef long int64_t;
-#define HAVE_INT64_T
-#endif
-
-#if !defined(HAVE_INT64_T) && SIZEOF_LONG_LONG == 8
-typedef long long int64_t;
-#define HAVE_INT64_T
-#endif
-
-#if !defined(HAVE_INT64_T)
-#error No 64-bit integer type was found.
-#endif
-
-/*
- * Similarly for int32_t
- */
-#if !defined(HAVE_INT32_T) && SIZEOF_INT == 4
-typedef int int32_t;
-#define HAVE_INT32_T
-#endif
-
-#if !defined(HAVE_INT32_T) && SIZEOF_LONG == 4
-typedef long int32_t;
-#define HAVE_INT32_T
-#endif
-
-#if !defined(HAVE_INT32_T)
-#error No 32-bit integer type was found.
-#endif
-
-/*
- * Similarly for int16_t
- */
-#if !defined(HAVE_INT16_T) && SIZEOF_INT == 2
-typedef int int16_t;
-#define HAVE_INT16_T
-#endif
-
-#if !defined(HAVE_INT16_T) && SIZEOF_SHORT == 2
-typedef short int16_t;
-#define HAVE_INT16_T
-#endif
-
-#if !defined(HAVE_INT16_T)
-#error No 16-bit integer type was found.
-#endif
-
-/*
- * Similarly for uint64_t
- */
-#if !defined(HAVE_UINT64_T) && defined(HAVE_UNSIGNED___INT64)
-typedef unsigned __int64 uint64_t;
-#define HAVE_UINT64_T
-#endif
-
-#if !defined(HAVE_UINT64_T) && SIZEOF_UNSIGNED == 8
-typedef unsigned uint64_t;
-#define HAVE_UINT64_T
-#endif
-
-#if !defined(HAVE_UINT64_T) && SIZEOF_UNSIGNED_LONG == 8
-typedef unsigned long uint64_t;
-#define HAVE_UINT64_T
-#endif
-
-#if !defined(HAVE_UINT64_T) && SIZEOF_UNSIGNED_LONG_LONG == 8
-typedef unsigned long long uint64_t;
-#define HAVE_UINT64_T
-#endif
-
-#if !defined(HAVE_UINT64_T)
-#error No 64-bit unsigned integer type was found.
-#endif
-
-
-/*
- * Similarly for uint32_t
- */
-#if !defined(HAVE_UINT32_T) && SIZEOF_UNSIGNED == 4
-typedef unsigned uint32_t;
-#define HAVE_UINT32_T
-#endif
-
-#if !defined(HAVE_UINT32_T) && SIZEOF_UNSIGNED_LONG == 4
-typedef unsigned long uint32_t;
-#define HAVE_UINT32_T
-#endif
-
-#if !defined(HAVE_UINT32_T)
-#error No 32-bit unsigned integer type was found.
-#endif
-
-/*
- * Similarly for uint16_t
- */
-#if !defined(HAVE_UINT16_T) && SIZEOF_UNSIGNED == 2
-typedef unsigned uint16_t;
-#define HAVE_UINT16_T
-#endif
-
-#if !defined(HAVE_UINT16_T) && SIZEOF_UNSIGNED_SHORT == 2
-typedef unsigned short uint16_t;
-#define HAVE_UINT16_T
-#endif
-
-#if !defined(HAVE_UINT16_T)
-#error No 16-bit unsigned integer type was found.
-#endif
-
-/*
- * Similarly for uint8_t
- */
-#if !defined(HAVE_UINT8_T)
-typedef unsigned char uint8_t;
-#define HAVE_UINT8_T
-#endif
-
-#if !defined(HAVE_UINT8_T)
-#error No 8-bit unsigned integer type was found.
-#endif
-
-/* Define intmax_t and uintmax_t if they are not already defined. */
-#if !defined(HAVE_INTMAX_T)
-typedef int64_t intmax_t;
-#endif
-
-#if !defined(HAVE_UINTMAX_T)
-typedef uint64_t uintmax_t;
-#endif
-
-/* Define ZLIB_WINAPI if zlib was built on Visual Studio. */
-/* #undef ZLIB_WINAPI */
-
-/* Darwin ACL support */
-/* #undef ARCHIVE_ACL_DARWIN */
-
-/* FreeBSD ACL support */
-/* #undef ARCHIVE_ACL_FREEBSD */
-
-/* FreeBSD NFSv4 ACL support */
-/* #undef ARCHIVE_ACL_FREEBSD_NFS4 */
-
-/* Linux POSIX.1e ACL support via libacl */
-/* #undef ARCHIVE_ACL_LIBACL */
-
-/* Linux NFSv4 ACL support via librichacl */
-/* #undef ARCHIVE_ACL_LIBRICHACL */
-
-/* Solaris ACL support */
-/* #undef ARCHIVE_ACL_SUNOS */
-
-/* Solaris NFSv4 ACL support */
-/* #undef ARCHIVE_ACL_SUNOS_NFS4 */
-
-/* MD5 via ARCHIVE_CRYPTO_MD5_LIBC supported. */
-/* #undef ARCHIVE_CRYPTO_MD5_LIBC */
-
-/* MD5 via ARCHIVE_CRYPTO_MD5_LIBSYSTEM supported. */
-/* #undef ARCHIVE_CRYPTO_MD5_LIBSYSTEM */
-
-/* MD5 via ARCHIVE_CRYPTO_MD5_MBEDTLS supported. */
-/* #undef ARCHIVE_CRYPTO_MD5_MBEDTLS */
-
-/* MD5 via ARCHIVE_CRYPTO_MD5_NETTLE supported. */
-/* #undef ARCHIVE_CRYPTO_MD5_NETTLE */
-
-/* MD5 via ARCHIVE_CRYPTO_MD5_OPENSSL supported. */
-#define ARCHIVE_CRYPTO_MD5_OPENSSL 1
-
-/* MD5 via ARCHIVE_CRYPTO_MD5_WIN supported. */
-/* #undef ARCHIVE_CRYPTO_MD5_WIN */
-
-/* RMD160 via ARCHIVE_CRYPTO_RMD160_LIBC supported. */
-/* #undef ARCHIVE_CRYPTO_RMD160_LIBC */
-
-/* RMD160 via ARCHIVE_CRYPTO_RMD160_NETTLE supported. */
-/* #undef ARCHIVE_CRYPTO_RMD160_NETTLE */
-
-/* RMD160 via ARCHIVE_CRYPTO_RMD160_MBEDTLS supported. */
-/* #undef ARCHIVE_CRYPTO_RMD160_MBEDTLS */
-
-/* RMD160 via ARCHIVE_CRYPTO_RMD160_OPENSSL supported. */
-#define ARCHIVE_CRYPTO_RMD160_OPENSSL 1
-
-/* SHA1 via ARCHIVE_CRYPTO_SHA1_LIBC supported. */
-/* #undef ARCHIVE_CRYPTO_SHA1_LIBC */
-
-/* SHA1 via ARCHIVE_CRYPTO_SHA1_LIBSYSTEM supported. */
-/* #undef ARCHIVE_CRYPTO_SHA1_LIBSYSTEM */
-
-/* SHA1 via ARCHIVE_CRYPTO_SHA1_MBEDTLS supported. */
-/* #undef ARCHIVE_CRYPTO_SHA1_MBEDTLS */
-
-/* SHA1 via ARCHIVE_CRYPTO_SHA1_NETTLE supported. */
-/* #undef ARCHIVE_CRYPTO_SHA1_NETTLE */
-
-/* SHA1 via ARCHIVE_CRYPTO_SHA1_OPENSSL supported. */
-#define ARCHIVE_CRYPTO_SHA1_OPENSSL 1
-
-/* SHA1 via ARCHIVE_CRYPTO_SHA1_WIN supported. */
-/* #undef ARCHIVE_CRYPTO_SHA1_WIN */
-
-/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC supported. */
-/* #undef ARCHIVE_CRYPTO_SHA256_LIBC */
-
-/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC2 supported. */
-/* #undef ARCHIVE_CRYPTO_SHA256_LIBC2 */
-
-/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC3 supported. */
-/* #undef ARCHIVE_CRYPTO_SHA256_LIBC3 */
-
-/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBSYSTEM supported. */
-/* #undef ARCHIVE_CRYPTO_SHA256_LIBSYSTEM */
-
-/* SHA256 via ARCHIVE_CRYPTO_SHA256_MBEDTLS supported. */
-/* #undef ARCHIVE_CRYPTO_SHA256_MBEDTLS */
-
-/* SHA256 via ARCHIVE_CRYPTO_SHA256_NETTLE supported. */
-/* #undef ARCHIVE_CRYPTO_SHA256_NETTLE */
-
-/* SHA256 via ARCHIVE_CRYPTO_SHA256_OPENSSL supported. */
-#define ARCHIVE_CRYPTO_SHA256_OPENSSL 1
-
-/* SHA256 via ARCHIVE_CRYPTO_SHA256_WIN supported. */
-/* #undef ARCHIVE_CRYPTO_SHA256_WIN */
-
-/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC supported. */
-/* #undef ARCHIVE_CRYPTO_SHA384_LIBC */
-
-/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC2 supported. */
-/* #undef ARCHIVE_CRYPTO_SHA384_LIBC2 */
-
-/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC3 supported. */
-/* #undef ARCHIVE_CRYPTO_SHA384_LIBC3 */
-
-/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBSYSTEM supported. */
-/* #undef ARCHIVE_CRYPTO_SHA384_LIBSYSTEM */
-
-/* SHA384 via ARCHIVE_CRYPTO_SHA384_MBEDTLS supported. */
-/* #undef ARCHIVE_CRYPTO_SHA384_MBEDTLS */
-
-/* SHA384 via ARCHIVE_CRYPTO_SHA384_NETTLE supported. */
-/* #undef ARCHIVE_CRYPTO_SHA384_NETTLE */
-
-/* SHA384 via ARCHIVE_CRYPTO_SHA384_OPENSSL supported. */
-#define ARCHIVE_CRYPTO_SHA384_OPENSSL 1
-
-/* SHA384 via ARCHIVE_CRYPTO_SHA384_WIN supported. */
-/* #undef ARCHIVE_CRYPTO_SHA384_WIN */
-
-/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC supported. */
-/* #undef ARCHIVE_CRYPTO_SHA512_LIBC */
-
-/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC2 supported. */
-/* #undef ARCHIVE_CRYPTO_SHA512_LIBC2 */
-
-/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC3 supported. */
-/* #undef ARCHIVE_CRYPTO_SHA512_LIBC3 */
-
-/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBSYSTEM supported. */
-/* #undef ARCHIVE_CRYPTO_SHA512_LIBSYSTEM */
-
-/* SHA512 via ARCHIVE_CRYPTO_SHA512_MBEDTLS supported. */
-/* #undef ARCHIVE_CRYPTO_SHA512_MBEDTLS */
-
-/* SHA512 via ARCHIVE_CRYPTO_SHA512_NETTLE supported. */
-/* #undef ARCHIVE_CRYPTO_SHA512_NETTLE */
-
-/* SHA512 via ARCHIVE_CRYPTO_SHA512_OPENSSL supported. */
-#define ARCHIVE_CRYPTO_SHA512_OPENSSL 1
-
-/* SHA512 via ARCHIVE_CRYPTO_SHA512_WIN supported. */
-/* #undef ARCHIVE_CRYPTO_SHA512_WIN */
-
-/* AIX xattr support */
-/* #undef ARCHIVE_XATTR_AIX */
-
-/* Darwin xattr support */
-/* #undef ARCHIVE_XATTR_DARWIN */
-
-/* FreeBSD xattr support */
-/* #undef ARCHIVE_XATTR_FREEBSD */
-
-/* Linux xattr support */
-/* #undef ARCHIVE_XATTR_LINUX */
-
-/* Version number of bsdcpio */
-#define BSDCPIO_VERSION_STRING "3.7.1"
-
-/* Version number of bsdtar */
-#define BSDTAR_VERSION_STRING "3.7.1"
-
-/* Version number of bsdcat */
-#define BSDCAT_VERSION_STRING "3.7.1"
-
-/* Define to 1 if you have the `acl_create_entry' function. */
-/* #undef HAVE_ACL_CREATE_ENTRY */
-
-/* Define to 1 if you have the `acl_get_fd_np' function. */
-/* #undef HAVE_ACL_GET_FD_NP */
-
-/* Define to 1 if you have the `acl_get_link' function. */
-/* #undef HAVE_ACL_GET_LINK */
-
-/* Define to 1 if you have the `acl_get_link_np' function. */
-/* #undef HAVE_ACL_GET_LINK_NP */
-
-/* Define to 1 if you have the `acl_get_perm' function. */
-/* #undef HAVE_ACL_GET_PERM */
-
-/* Define to 1 if you have the `acl_get_perm_np' function. */
-/* #undef HAVE_ACL_GET_PERM_NP */
-
-/* Define to 1 if you have the `acl_init' function. */
-/* #undef HAVE_ACL_INIT */
-
-/* Define to 1 if you have the <acl/libacl.h> header file. */
-/* #undef HAVE_ACL_LIBACL_H */
-
-/* Define to 1 if the system has the type `acl_permset_t'. */
-/* #undef HAVE_ACL_PERMSET_T */
-
-/* Define to 1 if you have the `acl_set_fd' function. */
-/* #undef HAVE_ACL_SET_FD */
-
-/* Define to 1 if you have the `acl_set_fd_np' function. */
-/* #undef HAVE_ACL_SET_FD_NP */
-
-/* Define to 1 if you have the `acl_set_file' function. */
-/* #undef HAVE_ACL_SET_FILE */
-
-/* Define to 1 if you have the `arc4random_buf' function. */
-/* #undef HAVE_ARC4RANDOM_BUF */
-
-/* Define to 1 if you have the <attr/xattr.h> header file. */
-/* #undef HAVE_ATTR_XATTR_H */
-
-/* Define to 1 if you have the <bcrypt.h> header file. */
-/* #undef HAVE_BCRYPT_H */
-
-/* Define to 1 if you have the <bsdxml.h> header file. */
-/* #undef HAVE_BSDXML_H */
-
-/* Define to 1 if you have the <bzlib.h> header file. */
-#define HAVE_BZLIB_H 1
-
-/* Define to 1 if you have the `chflags' function. */
-/* #undef HAVE_CHFLAGS */
-
-/* Define to 1 if you have the `chown' function. */
-#define HAVE_CHOWN 1
-
-/* Define to 1 if you have the `chroot' function. */
-#define HAVE_CHROOT 1
-
-/* Define to 1 if you have the <copyfile.h> header file. */
-/* #undef HAVE_COPYFILE_H */
-
-/* Define to 1 if you have the `ctime_r' function. */
-#define HAVE_CTIME_R 1
-
-/* Define to 1 if you have the <ctype.h> header file. */
-#define HAVE_CTYPE_H 1
-
-/* Define to 1 if you have the `cygwin_conv_path' function. */
-/* #undef HAVE_CYGWIN_CONV_PATH */
-
-/* Define to 1 if you have the declaration of `ACE_GETACL', and to 0 if you
- don't. */
-/* #undef HAVE_DECL_ACE_GETACL */
-
-/* Define to 1 if you have the declaration of `ACE_GETACLCNT', and to 0 if you
- don't. */
-/* #undef HAVE_DECL_ACE_GETACLCNT */
-
-/* Define to 1 if you have the declaration of `ACE_SETACL', and to 0 if you
- don't. */
-/* #undef HAVE_DECL_ACE_SETACL */
-
-/* Define to 1 if you have the declaration of `ACL_SYNCHRONIZE', and to 0 if
- you don't. */
-/* #undef HAVE_DECL_ACL_SYNCHRONIZE */
-
-/* Define to 1 if you have the declaration of `ACL_TYPE_EXTENDED', and to 0 if
- you don't. */
-/* #undef HAVE_DECL_ACL_TYPE_EXTENDED */
-
-/* Define to 1 if you have the declaration of `ACL_TYPE_NFS4', and to 0 if you
- don't. */
-/* #undef HAVE_DECL_ACL_TYPE_NFS4 */
-
-/* Define to 1 if you have the declaration of `ACL_USER', and to 0 if you
- don't. */
-/* #undef HAVE_DECL_ACL_USER */
-
-/* Define to 1 if you have the declaration of `INT32_MAX', and to 0 if you
- don't. */
-#define HAVE_DECL_INT32_MAX 1
-
-/* Define to 1 if you have the declaration of `INT32_MIN', and to 0 if you
- don't. */
-#define HAVE_DECL_INT32_MIN 1
-
-/* Define to 1 if you have the declaration of `INT64_MAX', and to 0 if you
- don't. */
-#define HAVE_DECL_INT64_MAX 1
-
-/* Define to 1 if you have the declaration of `INT64_MIN', and to 0 if you
- don't. */
-#define HAVE_DECL_INT64_MIN 1
-
-/* Define to 1 if you have the declaration of `INTMAX_MAX', and to 0 if you
- don't. */
-#define HAVE_DECL_INTMAX_MAX 1
-
-/* Define to 1 if you have the declaration of `INTMAX_MIN', and to 0 if you
- don't. */
-#define HAVE_DECL_INTMAX_MIN 1
-
-/* Define to 1 if you have the declaration of `SETACL', and to 0 if you don't.
- */
-/* #undef HAVE_DECL_SETACL */
-
-/* Define to 1 if you have the declaration of `SIZE_MAX', and to 0 if you
- don't. */
-#define HAVE_DECL_SIZE_MAX 1
-
-/* Define to 1 if you have the declaration of `SSIZE_MAX', and to 0 if you
- don't. */
-#define HAVE_DECL_SSIZE_MAX 1
-
-/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you
- don't. */
-#define HAVE_DECL_STRERROR_R 1
-
-/* Define to 1 if you have the declaration of `UINT32_MAX', and to 0 if you
- don't. */
-#define HAVE_DECL_UINT32_MAX 1
-
-/* Define to 1 if you have the declaration of `UINT64_MAX', and to 0 if you
- don't. */
-#define HAVE_DECL_UINT64_MAX 1
-
-/* Define to 1 if you have the declaration of `UINTMAX_MAX', and to 0 if you
- don't. */
-#define HAVE_DECL_UINTMAX_MAX 1
-
-/* Define to 1 if you have the declaration of `XATTR_NOFOLLOW', and to 0 if
- you don't. */
-/* #undef HAVE_DECL_XATTR_NOFOLLOW */
-
-/* Define to 1 if you have the <direct.h> header file. */
-/* #undef HAVE_DIRECT_H */
-
-/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
- */
-#define HAVE_DIRENT_H 1
-
-/* Define to 1 if you have the `dirfd' function. */
-#define HAVE_DIRFD 1
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
-/* #undef HAVE_DOPRNT */
-
-/* Define to 1 if nl_langinfo supports D_MD_ORDER */
-/* #undef HAVE_D_MD_ORDER */
-
-/* A possible errno value for invalid file format errors */
-/* #undef HAVE_EFTYPE */
-
-/* A possible errno value for invalid file format errors */
-#define HAVE_EILSEQ 1
-
-/* Define to 1 if you have the <errno.h> header file. */
-#define HAVE_ERRNO_H 1
-
-/* Define to 1 if you have the <expat.h> header file. */
-/* #undef HAVE_EXPAT_H */
-
-/* Define to 1 if you have the <ext2fs/ext2_fs.h> header file. */
-/* #undef HAVE_EXT2FS_EXT2_FS_H */
-
-/* Define to 1 if you have the `extattr_get_file' function. */
-/* #undef HAVE_EXTATTR_GET_FILE */
-
-/* Define to 1 if you have the `extattr_list_file' function. */
-/* #undef HAVE_EXTATTR_LIST_FILE */
-
-/* Define to 1 if you have the `extattr_set_fd' function. */
-/* #undef HAVE_EXTATTR_SET_FD */
-
-/* Define to 1 if you have the `extattr_set_file' function. */
-/* #undef HAVE_EXTATTR_SET_FILE */
-
-/* Define to 1 if EXTATTR_NAMESPACE_USER is defined in sys/extattr.h. */
-/* #undef HAVE_DECL_EXTATTR_NAMESPACE_USER */
-
-/* Define to 1 if you have the declaration of `GETACL', and to 0 if you don't.
- */
-/* #undef HAVE_DECL_GETACL */
-
-/* Define to 1 if you have the declaration of `GETACLCNT', and to 0 if you
- don't. */
-/* #undef HAVE_DECL_GETACLCNT */
-
-/* Define to 1 if you have the `fchdir' function. */
-#define HAVE_FCHDIR 1
-
-/* Define to 1 if you have the `fchflags' function. */
-/* #undef HAVE_FCHFLAGS */
-
-/* Define to 1 if you have the `fchmod' function. */
-#define HAVE_FCHMOD 1
-
-/* Define to 1 if you have the `fchown' function. */
-#define HAVE_FCHOWN 1
-
-/* Define to 1 if you have the `fcntl' function. */
-#define HAVE_FCNTL 1
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define to 1 if you have the `fdopendir' function. */
-#define HAVE_FDOPENDIR 1
-
-/* Define to 1 if you have the `fgetea' function. */
-/* #undef HAVE_FGETEA */
-
-/* Define to 1 if you have the `fgetxattr' function. */
-/* #undef HAVE_FGETXATTR */
-
-/* Define to 1 if you have the `flistea' function. */
-/* #undef HAVE_FLISTEA */
-
-/* Define to 1 if you have the `flistxattr' function. */
-/* #undef HAVE_FLISTXATTR */
-
-/* Define to 1 if you have the `fnmatch' function. */
-#define HAVE_FNMATCH 1
-
-/* Define to 1 if you have the <fnmatch.h> header file. */
-#define HAVE_FNMATCH_H 1
-
-/* Define to 1 if you have the `fork' function. */
-#define HAVE_FORK 1
-
-/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
-#define HAVE_FSEEKO 1
-
-/* Define to 1 if you have the `fsetea' function. */
-/* #undef HAVE_FSETEA */
-
-/* Define to 1 if you have the `fsetxattr' function. */
-/* #undef HAVE_FSETXATTR */
-
-/* Define to 1 if you have the `fstat' function. */
-#define HAVE_FSTAT 1
-
-/* Define to 1 if you have the `fstatat' function. */
-#define HAVE_FSTATAT 1
-
-/* Define to 1 if you have the `fstatfs' function. */
-#define HAVE_FSTATFS 1
-
-/* Define to 1 if you have the `fstatvfs' function. */
-/* #undef HAVE_FSTATVFS */
-
-/* Define to 1 if you have the `ftruncate' function. */
-#define HAVE_FTRUNCATE 1
-
-/* Define to 1 if you have the `futimens' function. */
-#define HAVE_FUTIMENS 1
-
-/* Define to 1 if you have the `futimes' function. */
-#define HAVE_FUTIMES 1
-
-/* Define to 1 if you have the `futimesat' function. */
-#define HAVE_FUTIMESAT 1
-
-/* Define to 1 if you have the `getea' function. */
-/* #undef HAVE_GETEA */
-
-/* Define to 1 if you have the `geteuid' function. */
-#define HAVE_GETEUID 1
-
-/* Define to 1 if you have the `getgrgid_r' function. */
-#define HAVE_GETGRGID_R 1
-
-/* Define to 1 if you have the `getgrnam_r' function. */
-#define HAVE_GETGRNAM_R 1
-
-/* Define to 1 if you have the `getline' function. */
-#define HAVE_GETLINE 1
-
-/* Define to 1 if platform uses `optreset` to reset `getopt` */
-/* #undef HAVE_GETOPT_OPTRESET */
-
-/* Define to 1 if you have the `getpid' function. */
-#define HAVE_GETPID 1
-
-/* Define to 1 if you have the `getpwnam_r' function. */
-#define HAVE_GETPWNAM_R 1
-
-/* Define to 1 if you have the `getpwuid_r' function. */
-#define HAVE_GETPWUID_R 1
-
-/* Define to 1 if you have the `getvfsbyname' function. */
-/* #undef HAVE_GETVFSBYNAME */
-
-/* Define to 1 if you have the `getxattr' function. */
-/* #undef HAVE_GETXATTR */
-
-/* Define to 1 if you have the `gmtime_r' function. */
-#define HAVE_GMTIME_R 1
-
-/* Define to 1 if you have the <grp.h> header file. */
-#define HAVE_GRP_H 1
-
-/* Define to 1 if you have the `iconv' function. */
-/* #undef HAVE_ICONV */
-
-/* Define to 1 if you have the <iconv.h> header file. */
-/* #undef HAVE_ICONV_H */
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the <io.h> header file. */
-/* #undef HAVE_IO_H */
-
-/* Define to 1 if you have the <langinfo.h> header file. */
-#define HAVE_LANGINFO_H 1
-
-/* Define to 1 if you have the `lchflags' function. */
-/* #undef HAVE_LCHFLAGS */
-
-/* Define to 1 if you have the `lchmod' function. */
-#define HAVE_LCHMOD 1
-
-/* Define to 1 if you have the `lchown' function. */
-#define HAVE_LCHOWN 1
-
-/* Define to 1 if you have the `lgetea' function. */
-/* #undef HAVE_LGETEA */
-
-/* Define to 1 if you have the `lgetxattr' function. */
-/* #undef HAVE_LGETXATTR */
-
-/* Define to 1 if you have the `acl' library (-lacl). */
-/* #undef HAVE_LIBACL */
-
-/* Define to 1 if you have the `attr' library (-lattr). */
-/* #undef HAVE_LIBATTR */
-
-/* Define to 1 if you have the `bsdxml' library (-lbsdxml). */
-/* #undef HAVE_LIBBSDXML */
-
-/* Define to 1 if you have the `bz2' library (-lbz2). */
-#define HAVE_LIBBZ2 1
-
-/* Define to 1 if you have the `b2' library (-lb2). */
-#define HAVE_LIBB2 1
-
-/* Define to 1 if you have the <blake2.h> header file. */
-#define HAVE_BLAKE2_H 1
-
-/* Define to 1 if you have the `charset' library (-lcharset). */
-/* #undef HAVE_LIBCHARSET */
-
-/* Define to 1 if you have the `crypto' library (-lcrypto). */
-#define HAVE_LIBCRYPTO 1
-
-/* Define to 1 if you have the `expat' library (-lexpat). */
-/* #undef HAVE_LIBEXPAT */
-
-/* Define to 1 if you have the `gcc' library (-lgcc). */
-/* #undef HAVE_LIBGCC */
-
-/* Define to 1 if you have the `lz4' library (-llz4). */
-#define HAVE_LIBLZ4 1
-
-/* Define to 1 if you have the `lzma' library (-llzma). */
-/* #undef HAVE_LIBLZMA */
-
-/* Define to 1 if you have the `lzmadec' library (-llzmadec). */
-/* #undef HAVE_LIBLZMADEC */
-
-/* Define to 1 if you have the `lzo2' library (-llzo2). */
-/* #undef HAVE_LIBLZO2 */
-
-/* Define to 1 if you have the `mbedcrypto' library (-lmbedcrypto). */
-/* #undef HAVE_LIBMBEDCRYPTO */
-
-/* Define to 1 if you have the `nettle' library (-lnettle). */
-/* #undef HAVE_LIBNETTLE */
-
-/* Define to 1 if you have the `pcre' library (-lpcre). */
-/* #undef HAVE_LIBPCRE */
-
-/* Define to 1 if you have the `pcreposix' library (-lpcreposix). */
-/* #undef HAVE_LIBPCREPOSIX */
-
-/* Define to 1 if you have the `xml2' library (-lxml2). */
-/* #undef HAVE_LIBXML2 */
-
-/* Define to 1 if you have the <libxml/xmlreader.h> header file. */
-/* #undef HAVE_LIBXML_XMLREADER_H */
-
-/* Define to 1 if you have the <libxml/xmlwriter.h> header file. */
-/* #undef HAVE_LIBXML_XMLWRITER_H */
-
-/* Define to 1 if you have the `z' library (-lz). */
-#define HAVE_LIBZ 1
-
-/* Define to 1 if you have the `zstd' library (-lzstd). */
-#define HAVE_LIBZSTD 1
-
-/* Define to 1 if you have the `zstd' library (-lzstd) with compression
- support. */
-#define HAVE_LIBZSTD_COMPRESSOR 1
-
-/* Define to 1 if you have the <limits.h> header file. */
-#define HAVE_LIMITS_H 1
-
-/* Define to 1 if you have the `link' function. */
-#define HAVE_LINK 1
-
-/* Define to 1 if you have the `linkat' function. */
-#define HAVE_LINKAT 1
-
-/* Define to 1 if you have the <linux/fiemap.h> header file. */
-#define HAVE_LINUX_FIEMAP_H 1
-
-/* Define to 1 if you have the <linux/fs.h> header file. */
-#define HAVE_LINUX_FS_H 1
-
-/* Define to 1 if you have the <linux/magic.h> header file. */
-#define HAVE_LINUX_MAGIC_H 1
-
-/* Define to 1 if you have the <linux/types.h> header file. */
-#define HAVE_LINUX_TYPES_H 1
-
-/* Define to 1 if you have the `listea' function. */
-/* #undef HAVE_LISTEA */
-
-/* Define to 1 if you have the `listxattr' function. */
-/* #undef HAVE_LISTXATTR */
-
-/* Define to 1 if you have the `llistea' function. */
-/* #undef HAVE_LLISTEA */
-
-/* Define to 1 if you have the `llistxattr' function. */
-/* #undef HAVE_LLISTXATTR */
-
-/* Define to 1 if you have the <localcharset.h> header file. */
-/* #undef HAVE_LOCALCHARSET_H */
-
-/* Define to 1 if you have the `locale_charset' function. */
-/* #undef HAVE_LOCALE_CHARSET */
-
-/* Define to 1 if you have the <locale.h> header file. */
-#define HAVE_LOCALE_H 1
-
-/* Define to 1 if you have the `localtime_r' function. */
-#define HAVE_LOCALTIME_R 1
-
-/* Define to 1 if the system has the type `long long int'. */
-/* #undef HAVE_LONG_LONG_INT */
-
-/* Define to 1 if you have the `lsetea' function. */
-/* #undef HAVE_LSETEA */
-
-/* Define to 1 if you have the `lsetxattr' function. */
-/* #undef HAVE_LSETXATTR */
-
-/* Define to 1 if you have the `lstat' function. */
-#define HAVE_LSTAT 1
-
-/* Define to 1 if `lstat' has the bug that it succeeds when given the
- zero-length file name argument. */
-/* #undef HAVE_LSTAT_EMPTY_STRING_BUG */
-
-/* Define to 1 if you have the `lutimes' function. */
-#define HAVE_LUTIMES 1
-
-/* Define to 1 if you have the <lz4hc.h> header file. */
-#define HAVE_LZ4HC_H 1
-
-/* Define to 1 if you have the <lz4.h> header file. */
-#define HAVE_LZ4_H 1
-
-/* Define to 1 if you have the <lzmadec.h> header file. */
-/* #undef HAVE_LZMADEC_H */
-
-/* Define to 1 if you have the <lzma.h> header file. */
-/* #undef HAVE_LZMA_H */
-
-/* Define to 1 if you have a working `lzma_stream_encoder_mt' function. */
-/* #undef HAVE_LZMA_STREAM_ENCODER_MT */
-
-/* Define to 1 if you have the <lzo/lzo1x.h> header file. */
-/* #undef HAVE_LZO_LZO1X_H */
-
-/* Define to 1 if you have the <lzo/lzoconf.h> header file. */
-/* #undef HAVE_LZO_LZOCONF_H */
-
-/* Define to 1 if you have the <mbedtls/aes.h> header file. */
-/* #undef HAVE_MBEDTLS_AES_H */
-
-/* Define to 1 if you have the <mbedtls/md.h> header file. */
-/* #undef HAVE_MBEDTLS_MD_H */
-
-/* Define to 1 if you have the <mbedtls/pkcs5.h> header file. */
-/* #undef HAVE_MBEDTLS_PKCS5_H */
-
-/* Define to 1 if you have the `mbrtowc' function. */
-#define HAVE_MBRTOWC 1
-
-/* Define to 1 if you have the <membership.h> header file. */
-/* #undef HAVE_MEMBERSHIP_H */
-
-/* Define to 1 if you have the `memmove' function. */
-#define HAVE_MEMMOVE 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `mkdir' function. */
-#define HAVE_MKDIR 1
-
-/* Define to 1 if you have the `mkfifo' function. */
-#define HAVE_MKFIFO 1
-
-/* Define to 1 if you have the `mknod' function. */
-#define HAVE_MKNOD 1
-
-/* Define to 1 if you have the `mkstemp' function. */
-#define HAVE_MKSTEMP 1
-
-/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
-/* #undef HAVE_NDIR_H */
-
-/* Define to 1 if you have the <nettle/aes.h> header file. */
-/* #undef HAVE_NETTLE_AES_H */
-
-/* Define to 1 if you have the <nettle/hmac.h> header file. */
-/* #undef HAVE_NETTLE_HMAC_H */
-
-/* Define to 1 if you have the <nettle/md5.h> header file. */
-/* #undef HAVE_NETTLE_MD5_H */
-
-/* Define to 1 if you have the <nettle/pbkdf2.h> header file. */
-/* #undef HAVE_NETTLE_PBKDF2_H */
-
-/* Define to 1 if you have the <nettle/ripemd160.h> header file. */
-/* #undef HAVE_NETTLE_RIPEMD160_H */
-
-/* Define to 1 if you have the <nettle/sha.h> header file. */
-/* #undef HAVE_NETTLE_SHA_H */
-
-/* Define to 1 if you have the `nl_langinfo' function. */
-#define HAVE_NL_LANGINFO 1
-
-/* Define to 1 if you have the `openat' function. */
-#define HAVE_OPENAT 1
-
-/* Define to 1 if you have the <openssl/evp.h> header file. */
-#define HAVE_OPENSSL_EVP_H 1
-
-/* Define to 1 if you have the <paths.h> header file. */
-#define HAVE_PATHS_H 1
-
-/* Define to 1 if you have the <pcreposix.h> header file. */
-/* #undef HAVE_PCREPOSIX_H */
-
-/* Define to 1 if you have the `pipe' function. */
-#define HAVE_PIPE 1
-
-/* Define to 1 if you have the `PKCS5_PBKDF2_HMAC_SHA1' function. */
-#define HAVE_PKCS5_PBKDF2_HMAC_SHA1 1
-
-/* Define to 1 if you have the `poll' function. */
-#define HAVE_POLL 1
-
-/* Define to 1 if you have the <poll.h> header file. */
-#define HAVE_POLL_H 1
-
-/* Define to 1 if you have the `posix_spawnp' function. */
-#define HAVE_POSIX_SPAWNP 0
-
-/* Define to 1 if you have the <process.h> header file. */
-/* #undef HAVE_PROCESS_H */
-
-/* Define to 1 if you have the <pthread.h> header file. */
-#define HAVE_PTHREAD_H 1
-
-/* Define to 1 if you have the <pwd.h> header file. */
-#define HAVE_PWD_H 1
-
-/* Define to 1 if you have the `readdir_r' function. */
-#define HAVE_READDIR_R 1
-
-/* Define to 1 if you have the `readlink' function. */
-#define HAVE_READLINK 1
-
-/* Define to 1 if you have the `readlinkat' function. */
-#define HAVE_READLINKAT 1
-
-/* Define to 1 if you have the `readpassphrase' function. */
-/* #undef HAVE_READPASSPHRASE */
-
-/* Define to 1 if you have the <readpassphrase.h> header file. */
-/* #undef HAVE_READPASSPHRASE_H */
-
-/* Define to 1 if you have the <regex.h> header file. */
-#define HAVE_REGEX_H 1
-
-/* Define to 1 if you have the `select' function. */
-#define HAVE_SELECT 1
-
-/* Define to 1 if you have the `setenv' function. */
-#define HAVE_SETENV 1
-
-/* Define to 1 if you have the `setlocale' function. */
-#define HAVE_SETLOCALE 1
-
-/* Define to 1 if you have the `sigaction' function. */
-#define HAVE_SIGACTION 1
-
-/* Define to 1 if you have the <signal.h> header file. */
-#define HAVE_SIGNAL_H 1
-
-/* Define to 1 if you have the <spawn.h> header file. */
-#define HAVE_SPAWN_H 1
-
-/* Define to 1 if you have the `statfs' function. */
-#define HAVE_STATFS 1
-
-/* Define to 1 if you have the `statvfs' function. */
-/* #undef HAVE_STATVFS */
-
-/* Define to 1 if `stat' has the bug that it succeeds when given the
- zero-length file name argument. */
-/* #undef HAVE_STAT_EMPTY_STRING_BUG */
-
-/* Define to 1 if you have the <stdarg.h> header file. */
-#define HAVE_STDARG_H 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the `strchr' function. */
-#define HAVE_STRCHR 1
-
-/* Define to 1 if you have the `strnlen' function. */
-#define HAVE_STRNLEN 1
-
-/* Define to 1 if you have the `strdup' function. */
-#define HAVE_STRDUP 1
-
-/* Define to 1 if you have the `strerror' function. */
-#define HAVE_STRERROR 1
-
-/* Define to 1 if you have the `strerror_r' function. */
-#define HAVE_STRERROR_R 1
-
-/* Define to 1 if you have the `strftime' function. */
-#define HAVE_STRFTIME 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the `strrchr' function. */
-#define HAVE_STRRCHR 1
-
-/* Define to 1 if `f_namemax' is a member of `struct statfs'. */
-/* #undef HAVE_STRUCT_STATFS_F_NAMEMAX */
-
-/* Define to 1 if `f_iosize' is a member of `struct statvfs'. */
-/* #undef HAVE_STRUCT_STATVFS_F_IOSIZE */
-
-/* Define to 1 if `st_birthtime' is a member of `struct stat'. */
-/* #undef HAVE_STRUCT_STAT_ST_BIRTHTIME */
-
-/* Define to 1 if `st_birthtimespec.tv_nsec' is a member of `struct stat'. */
-/* #undef HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC */
-
-/* Define to 1 if `st_blksize' is a member of `struct stat'. */
-#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
-
-/* Define to 1 if `st_flags' is a member of `struct stat'. */
-/* #undef HAVE_STRUCT_STAT_ST_FLAGS */
-
-/* Define to 1 if `st_mtimespec.tv_nsec' is a member of `struct stat'. */
-/* #undef HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC */
-
-/* Define to 1 if `st_mtime_n' is a member of `struct stat'. */
-/* #undef HAVE_STRUCT_STAT_ST_MTIME_N */
-
-/* Define to 1 if `st_mtime_usec' is a member of `struct stat'. */
-/* #undef HAVE_STRUCT_STAT_ST_MTIME_USEC */
-
-/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */
-#define HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 1
-
-/* Define to 1 if `st_umtime' is a member of `struct stat'. */
-/* #undef HAVE_STRUCT_STAT_ST_UMTIME */
-
-/* Define to 1 if `tm_gmtoff' is a member of `struct tm'. */
-#define HAVE_STRUCT_TM_TM_GMTOFF 1
-
-/* Define to 1 if `__tm_gmtoff' is a member of `struct tm'. */
-/* #undef HAVE_STRUCT_TM___TM_GMTOFF */
-
-/* Define to 1 if you have `struct vfsconf'. */
-/* #undef HAVE_STRUCT_VFSCONF */
-
-/* Define to 1 if you have `struct xvfsconf'. */
-/* #undef HAVE_STRUCT_XVFSCONF */
-
-/* Define to 1 if you have the `symlink' function. */
-#define HAVE_SYMLINK 1
-
-/* Define to 1 if you have the <sys/acl.h> header file. */
-/* #undef HAVE_SYS_ACL_H */
-
-/* Define to 1 if you have the <sys/cdefs.h> header file. */
-#define HAVE_SYS_CDEFS_H 1
-
-/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
- */
-/* #undef HAVE_SYS_DIR_H */
-
-/* Define to 1 if you have the <sys/ea.h> header file. */
-/* #undef HAVE_SYS_EA_H */
-
-/* Define to 1 if you have the <sys/extattr.h> header file. */
-/* #undef HAVE_SYS_EXTATTR_H */
-
-/* Define to 1 if you have the <sys/ioctl.h> header file. */
-#define HAVE_SYS_IOCTL_H 1
-
-/* Define to 1 if you have the <sys/mkdev.h> header file. */
-/* #undef HAVE_SYS_MKDEV_H */
-
-/* Define to 1 if you have the <sys/mount.h> header file. */
-/* #undef HAVE_SYS_MOUNT_H */
-
-/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
- */
-/* #undef HAVE_SYS_NDIR_H */
-
-/* Define to 1 if you have the <sys/param.h> header file. */
-#define HAVE_SYS_PARAM_H 1
-
-/* Define to 1 if you have the <sys/poll.h> header file. */
-#define HAVE_SYS_POLL_H 1
-
-/* Define to 1 if you have the <sys/queue.h> header file. */
-#define HAVE_SYS_QUEUE_H 1
-
-/* Define to 1 if you have the <sys/richacl.h> header file. */
-/* #undef HAVE_SYS_RICHACL_H */
-
-/* Define to 1 if you have the <sys/select.h> header file. */
-#define HAVE_SYS_SELECT_H 1
-
-/* Define to 1 if you have the <sys/statfs.h> header file. */
-#define HAVE_SYS_STATFS_H 1
-
-/* Define to 1 if you have the <sys/statvfs.h> header file. */
-#define HAVE_SYS_STATVFS_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-
-/* Define to 1 if you have the <sys/sysmacros.h> header file. */
-#define HAVE_SYS_SYSMACROS_H 1
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#define HAVE_SYS_TIME_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <sys/utime.h> header file. */
-/* #undef HAVE_SYS_UTIME_H */
-
-/* Define to 1 if you have the <sys/utsname.h> header file. */
-#define HAVE_SYS_UTSNAME_H 1
-
-/* Define to 1 if you have the <sys/vfs.h> header file. */
-#define HAVE_SYS_VFS_H 1
-
-/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
-#define HAVE_SYS_WAIT_H 1
-
-/* Define to 1 if you have the <sys/xattr.h> header file. */
-#define HAVE_SYS_XATTR_H 1
-
-/* Define to 1 if you have the `timegm' function. */
-#define HAVE_TIMEGM 1
-
-/* Define to 1 if you have the <time.h> header file. */
-#define HAVE_TIME_H 1
-
-/* Define to 1 if you have the `tzset' function. */
-#define HAVE_TZSET 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to 1 if you have the `unlinkat' function. */
-#define HAVE_UNLINKAT 1
-
-/* Define to 1 if you have the `unsetenv' function. */
-#define HAVE_UNSETENV 1
-
-/* Define to 1 if the system has the type `unsigned long long'. */
-/* #undef HAVE_UNSIGNED_LONG_LONG */
-
-/* Define to 1 if the system has the type `unsigned long long int'. */
-/* #undef HAVE_UNSIGNED_LONG_LONG_INT */
-
-/* Define to 1 if you have the `utime' function. */
-#define HAVE_UTIME 1
-
-/* Define to 1 if you have the `utimensat' function. */
-#define HAVE_UTIMENSAT 1
-
-/* Define to 1 if you have the `utimes' function. */
-#define HAVE_UTIMES 1
-
-/* Define to 1 if you have the <utime.h> header file. */
-#define HAVE_UTIME_H 1
-
-/* Define to 1 if you have the `vfork' function. */
-#define HAVE_VFORK 1
-
-/* Define to 1 if you have the `vprintf' function. */
-#define HAVE_VPRINTF 1
-
-/* Define to 1 if you have the <wchar.h> header file. */
-#define HAVE_WCHAR_H 1
-
-/* Define to 1 if the system has the type `wchar_t'. */
-#define HAVE_WCHAR_T 1
-
-/* Define to 1 if you have the `wcrtomb' function. */
-#define HAVE_WCRTOMB 1
-
-/* Define to 1 if you have the `wcscmp' function. */
-#define HAVE_WCSCMP 1
-
-/* Define to 1 if you have the `wcscpy' function. */
-#define HAVE_WCSCPY 1
-
-/* Define to 1 if you have the `wcslen' function. */
-#define HAVE_WCSLEN 1
-
-/* Define to 1 if you have the `wctomb' function. */
-#define HAVE_WCTOMB 1
-
-/* Define to 1 if you have the <wctype.h> header file. */
-#define HAVE_WCTYPE_H 1
-
-/* Define to 1 if you have the <wincrypt.h> header file. */
-/* #undef HAVE_WINCRYPT_H */
-
-/* Define to 1 if you have the <windows.h> header file. */
-/* #undef HAVE_WINDOWS_H */
-
-/* Define to 1 if you have the <winioctl.h> header file. */
-/* #undef HAVE_WINIOCTL_H */
-
-/* Define to 1 if you have _CrtSetReportMode in <crtdbg.h> */
-/* #undef HAVE__CrtSetReportMode */
-
-/* Define to 1 if you have the `wmemcmp' function. */
-#define HAVE_WMEMCMP 1
-
-/* Define to 1 if you have the `wmemcpy' function. */
-#define HAVE_WMEMCPY 1
-
-/* Define to 1 if you have the `wmemmove' function. */
-#define HAVE_WMEMMOVE 1
-
-/* Define to 1 if you have a working EXT2_IOC_GETFLAGS */
-/* #undef HAVE_WORKING_EXT2_IOC_GETFLAGS */
-
-/* Define to 1 if you have a working FS_IOC_GETFLAGS */
-#define HAVE_WORKING_FS_IOC_GETFLAGS 1
-
-/* Define to 1 if you have the <zlib.h> header file. */
-#define HAVE_ZLIB_H 1
-
-/* Define to 1 if you have the <zstd.h> header file. */
-#define HAVE_ZSTD_H 1
-
-/* Define to 1 if you have the `ctime_s' function. */
-/* #undef HAVE_CTIME_S */
-
-/* Define to 1 if you have the `_fseeki64' function. */
-/* #undef HAVE__FSEEKI64 */
-
-/* Define to 1 if you have the `_get_timezone' function. */
-/* #undef HAVE__GET_TIMEZONE */
-
-/* Define to 1 if you have the `gmtime_s' function. */
-/* #undef HAVE_GMTIME_S */
-
-/* Define to 1 if you have the `localtime_s' function. */
-/* #undef HAVE_LOCALTIME_S */
-
-/* Define to 1 if you have the `_mkgmtime' function. */
-/* #undef HAVE__MKGMTIME */
-
-/* Define as const if the declaration of iconv() needs const. */
-#define ICONV_CONST
-
-/* Version number of libarchive as a single integer */
-#define LIBARCHIVE_VERSION_NUMBER "3007001"
-
-/* Version number of libarchive */
-#define LIBARCHIVE_VERSION_STRING "3.7.1"
-
-/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
- slash. */
-/* #undef LSTAT_FOLLOWS_SLASHED_SYMLINK */
-
-/* Define to 1 if `major', `minor', and `makedev' are declared in <mkdev.h>.
- */
-/* #undef MAJOR_IN_MKDEV */
-
-/* Define to 1 if `major', `minor', and `makedev' are declared in
- <sysmacros.h>. */
-#define MAJOR_IN_SYSMACROS 1
-
-/* Define to 1 if your C compiler doesn't accept -c and -o together. */
-/* #undef NO_MINUS_C_MINUS_O */
-
-/* The size of `wchar_t', as computed by sizeof. */
-#define SIZEOF_WCHAR_T 4
-
-/* Define to 1 if strerror_r returns char *. */
-/* #undef STRERROR_R_CHAR_P */
-
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
-/* #undef TIME_WITH_SYS_TIME */
-
-/*
- * Some platform requires a macro to use extension functions.
- */
-#define SAFE_TO_DEFINE_EXTENSIONS 1
-#ifdef SAFE_TO_DEFINE_EXTENSIONS
-/* Enable extensions on AIX 3, Interix. */
-#ifndef _ALL_SOURCE
-# define _ALL_SOURCE 1
-#endif
-/* Enable GNU extensions on systems that have them. */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE 1
-#endif
-/* Enable threading extensions on Solaris. */
-#ifndef _POSIX_PTHREAD_SEMANTICS
-# define _POSIX_PTHREAD_SEMANTICS 1
-#endif
-/* Enable extensions on HP NonStop. */
-#ifndef _TANDEM_SOURCE
-# define _TANDEM_SOURCE 1
-#endif
-/* Enable general extensions on Solaris. */
-#ifndef __EXTENSIONS__
-# define __EXTENSIONS__ 1
-#endif
-#endif /* SAFE_TO_DEFINE_EXTENSIONS */
-
-/* Version number of package */
-#define VERSION "3.7.1"
-
-/* Number of bits in a file offset, on hosts where this is settable. */
-/* #undef _FILE_OFFSET_BITS */
-
-/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
-/* #undef _LARGEFILE_SOURCE */
-
-/* Define for large files, on AIX-style hosts. */
-/* #undef _LARGE_FILES */
-
-/* Define to control Windows SDK version */
-#ifndef NTDDI_VERSION
-/* #undef NTDDI_VERSION */
-#endif // NTDDI_VERSION
-
-#ifndef _WIN32_WINNT
-/* #undef _WIN32_WINNT */
-#endif // _WIN32_WINNT
-
-#ifndef WINVER
-/* #undef WINVER */
-#endif // WINVER
-
-/* Define to empty if `const' does not conform to ANSI C. */
-/* #undef const */
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-/* #undef gid_t */
-
-/* Define to `unsigned long' if <sys/types.h> does not define. */
-/* #undef id_t */
-
-/* Define to `int' if <sys/types.h> does not define. */
-/* #undef mode_t */
-
-/* Define to `long long' if <sys/types.h> does not define. */
-/* #undef off_t */
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-/* #undef pid_t */
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-/* #undef size_t */
-
-/* Define to `int' if <sys/types.h> does not define. */
-/* #undef ssize_t */
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-/* #undef uid_t */
-
-/* Define to `int' if <sys/types.h> does not define. */
-/* #undef intptr_t */
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-/* #undef uintptr_t */
-
-#define HAVE_STRUCT_STATFS
diff --git a/contrib/libs/libarchive/config-osx.h b/contrib/libs/libarchive/config-osx.h
deleted file mode 100644
index be6d950a9e..0000000000
--- a/contrib/libs/libarchive/config-osx.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#include "config-linux.h"
-
-#define ARCHIVE_CRYPTO_MD5_LIBSYSTEM 1
-#define ARCHIVE_CRYPTO_SHA1_LIBSYSTEM 1
-#define ARCHIVE_CRYPTO_SHA256_LIBSYSTEM 1
-#define ARCHIVE_CRYPTO_SHA384_LIBSYSTEM 1
-#define ARCHIVE_CRYPTO_SHA512_LIBSYSTEM 1
-
-#define HAVE_ARC4RANDOM_BUF 1
-#define HAVE_CHFLAGS 1
-#define HAVE_COPYFILE_H 1
-#define HAVE_D_MD_ORDER 1
-#define HAVE_EFTYPE 1
-#define HAVE_FCHFLAGS 1
-#define HAVE_GETVFSBYNAME 1
-#define HAVE_LCHFLAGS 1
-#define HAVE_READPASSPHRASE 1
-#define HAVE_READPASSPHRASE_H 1
-#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1
-#define HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC 1
-#define HAVE_STRUCT_STAT_ST_FLAGS 1
-#define HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1
-#define HAVE_STRUCT_VFSCONF 1
-
-#undef HAVE_FUTIMENS
-#undef HAVE_FUTIMESAT
-#undef HAVE_LINUX_FIEMAP_H
-#undef HAVE_LINUX_FS_H
-#undef HAVE_LINUX_MAGIC_H
-#undef HAVE_LINUX_TYPES_H
-#undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
-#undef HAVE_SYS_STATFS_H
-#undef HAVE_SYS_SYSMACROS_H
-#undef HAVE_SYS_VFS_H
-#undef HAVE_SYS_XATTR_H
-#undef HAVE_UTIMENSAT
-#undef MAJOR_IN_SYSMACROS
-
-#undef HAVE_POSIX_SPAWNP
-#define HAVE_POSIX_SPAWNP 1
-
-#undef HAVE_STRUCT_STATFS
diff --git a/contrib/libs/libarchive/config-win.h b/contrib/libs/libarchive/config-win.h
deleted file mode 100644
index 794a9c46a6..0000000000
--- a/contrib/libs/libarchive/config-win.h
+++ /dev/null
@@ -1,121 +0,0 @@
-#include "config-linux.h"
-
-#define HAVE___INT64
-#define HAVE_UNSIGNED___INT64
-
-#undef SIZEOF_LONG
-#define SIZEOF_LONG 4
-
-#undef SIZEOF_UNSIGNED_LONG
-#define SIZEOF_UNSIGNED_LONG 4
-
-#define ARCHIVE_CRYPTO_MD5_WIN 1
-#define ARCHIVE_CRYPTO_SHA1_WIN 1
-#define ARCHIVE_CRYPTO_SHA256_WIN 1
-#define ARCHIVE_CRYPTO_SHA384_WIN 1
-#define ARCHIVE_CRYPTO_SHA512_WIN 1
-
-#define HAVE_BCRYPT_H 1
-#define HAVE_DIRECT_H 1
-#define HAVE__GET_TIMEZONE 1
-#define HAVE_IO_H 1
-#define HAVE_PROCESS_H 1
-#define HAVE_SYS_UTIME_H 1
-#define HAVE_WINCRYPT_H 1
-
-#undef HAVE_CHOWN
-#undef HAVE_CHROOT
-#undef HAVE_CTIME_R
-#undef HAVE_DECL_SSIZE_MAX
-#undef HAVE_DECL_STRERROR_R
-#undef HAVE_DIRENT_H
-#undef HAVE_DIRFD
-#undef HAVE_DLFCN_H
-#undef HAVE_FCHDIR
-#undef HAVE_FCHMOD
-#undef HAVE_FCHOWN
-#undef HAVE_FCNTL
-#undef HAVE_FDOPENDIR
-#undef HAVE_FORK
-#undef HAVE_FSEEK
-#undef HAVE_FSTATAT
-#undef HAVE_FSTATFS
-#undef HAVE_FSTATVFS
-#undef HAVE_FTRUNCATE
-#undef HAVE_FUTIMENS
-#undef HAVE_FUTIMES
-#undef HAVE_FUTIMESAT
-#undef HAVE_GETEUID
-#undef HAVE_GETGRGID_R
-#undef HAVE_GETGRNAM_R
-#undef HAVE_GETPWNAM_R
-#undef HAVE_GETPWUID_R
-#undef HAVE_GMTIME_R
-#undef HAVE_GRP_H
-#undef HAVE_LANGINFO_H
-#undef HAVE_LCHMOD
-#undef HAVE_LCHOW
-#undef HAVE_LINK
-#undef HAVE_LINUX_FIEMAP_H
-#undef HAVE_LINUX_FS_H
-#undef HAVE_LINUX_MAGIC_H
-#undef HAVE_LINUX_TYPES_H
-#undef HAVE_LOCALTIME_R
-#undef HAVE_LSTAT
-#undef HAVE_LUTIMES
-#undef HAVE_MKFIFO
-#undef HAVE_MKNOD
-#undef HAVE_MKSTEMP
-#undef HAVE_NL_LANGINFO
-#undef HAVE_OPENAT
-#undef HAVE_PATHS_H
-#undef HAVE_PIPE
-#undef HAVE_POLL
-#undef HAVE_POLL_H
-#undef HAVE_POSIX_SPAWN
-#undef HAVE_PTHREAD_H
-#undef HAVE_PWD_H
-#undef HAVE_READDIR_R
-#undef HAVE_READLINK
-#undef HAVE_READLINKAT
-#undef HAVE_REGEX_H
-#undef HAVE_SELECT
-#undef HAVE_SETENV
-#undef HAVE_SIGACTION
-#undef HAVE_SPAWN_H
-#undef HAVE_STATFS
-#undef HAVE_STATVFS
-#undef HAVE_STRERROR_R
-#undef HAVE_STRINGS_H
-#undef HAVE_STRUCT_STAT_ST_BLKSIZE
-#undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
-#undef HAVE_STRUCT_TM_TM_GMTOFF
-#undef HAVE_SYMLINK
-#undef HAVE_SYS_CDEFS_H
-#undef HAVE_SYS_IOCTL_H
-#undef HAVE_SYS_PARAM_H
-#undef HAVE_SYS_POLL_H
-#undef HAVE_SYS_SELECT_H
-#undef HAVE_SYS_STATFS_H
-#undef HAVE_SYS_STATVFS_H
-#undef HAVE_SYS_SYSMACROS_H
-#undef HAVE_SYS_TIME_H
-#undef HAVE_SYS_UTSNAME_H
-#undef HAVE_SYS_VFS_H
-#undef HAVE_SYS_VFS_H
-#undef HAVE_SYS_WAIT_H
-#undef HAVE_SYS_XATTR_H
-#undef HAVE_TIMEGM
-#undef HAVE_UNISTD_H
-#undef HAVE_UNSETENV
-#undef HAVE_UTIMENSAT
-#undef HAVE_UTIMES
-#undef HAVE_UTIME_H
-#undef MAJOR_IN_SYSMACROS
-
-typedef __int64 ssize_t;
-typedef int pid_t;
-typedef short uid_t;
-typedef short gid_t;
-typedef short id_t;
-typedef unsigned short mode_t;
diff --git a/contrib/libs/libarchive/config.h b/contrib/libs/libarchive/config.h
deleted file mode 100644
index 1614a4f2b6..0000000000
--- a/contrib/libs/libarchive/config.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#pragma once
-
-#if defined(__APPLE__)
-# include "config-osx.h"
-#elif defined(_MSC_VER)
-# include "config-win.h"
-#else
-# include "config-linux.h"
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive.h b/contrib/libs/libarchive/libarchive/archive.h
deleted file mode 100644
index cdb4f3ad8c..0000000000
--- a/contrib/libs/libarchive/libarchive/archive.h
+++ /dev/null
@@ -1,1212 +0,0 @@
-/*-
- * Copyright (c) 2003-2010 Tim Kientzle
- * 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(S) ``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(S) 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.
- *
- * $FreeBSD: src/lib/libarchive/archive.h.in,v 1.50 2008/05/26 17:00:22 kientzle Exp $
- */
-
-#ifndef ARCHIVE_H_INCLUDED
-#define ARCHIVE_H_INCLUDED
-
-/*
- * The version number is expressed as a single integer that makes it
- * easy to compare versions at build time: for version a.b.c, the
- * version number is printf("%d%03d%03d",a,b,c). For example, if you
- * know your application requires version 2.12.108 or later, you can
- * assert that ARCHIVE_VERSION_NUMBER >= 2012108.
- */
-/* Note: Compiler will complain if this does not match archive_entry.h! */
-#define ARCHIVE_VERSION_NUMBER 3007001
-
-#include <sys/stat.h>
-#include <stddef.h> /* for wchar_t */
-#include <stdio.h> /* For FILE * */
-#include <time.h> /* For time_t */
-
-/*
- * Note: archive.h is for use outside of libarchive; the configuration
- * headers (config.h, archive_platform.h, etc.) are purely internal.
- * Do NOT use HAVE_XXX configuration macros to control the behavior of
- * this header! If you must conditionalize, use predefined compiler and/or
- * platform macros.
- */
-#if defined(__BORLANDC__) && __BORLANDC__ >= 0x560
-# include <stdint.h>
-#elif !defined(__WATCOMC__) && !defined(_MSC_VER) && !defined(__INTERIX) && !defined(__BORLANDC__) && !defined(_SCO_DS) && !defined(__osf__) && !defined(__CLANG_INTTYPES_H)
-# include <inttypes.h>
-#endif
-
-/* Get appropriate definitions of 64-bit integer */
-#if !defined(__LA_INT64_T_DEFINED)
-/* Older code relied on the __LA_INT64_T macro; after 4.0 we'll switch to the typedef exclusively. */
-# if ARCHIVE_VERSION_NUMBER < 4000000
-#define __LA_INT64_T la_int64_t
-# endif
-#define __LA_INT64_T_DEFINED
-# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
-typedef __int64 la_int64_t;
-# else
-# include <unistd.h> /* ssize_t */
-# if defined(_SCO_DS) || defined(__osf__)
-typedef long long la_int64_t;
-# else
-typedef int64_t la_int64_t;
-# endif
-# endif
-#endif
-
-/* The la_ssize_t should match the type used in 'struct stat' */
-#if !defined(__LA_SSIZE_T_DEFINED)
-/* Older code relied on the __LA_SSIZE_T macro; after 4.0 we'll switch to the typedef exclusively. */
-# if ARCHIVE_VERSION_NUMBER < 4000000
-#define __LA_SSIZE_T la_ssize_t
-# endif
-#define __LA_SSIZE_T_DEFINED
-# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
-# if defined(_SSIZE_T_DEFINED) || defined(_SSIZE_T_)
-typedef ssize_t la_ssize_t;
-# elif defined(_WIN64)
-typedef __int64 la_ssize_t;
-# else
-typedef long la_ssize_t;
-# endif
-# else
-# include <unistd.h> /* ssize_t */
-typedef ssize_t la_ssize_t;
-# endif
-#endif
-
-/* Large file support for Android */
-#if defined(__LIBARCHIVE_BUILD) && defined(__ANDROID__)
-#error #include "android_lf.h"
-#endif
-
-/*
- * On Windows, define LIBARCHIVE_STATIC if you're building or using a
- * .lib. The default here assumes you're building a DLL. Only
- * libarchive source should ever define __LIBARCHIVE_BUILD.
- */
-#if ((defined __WIN32__) || (defined _WIN32) || defined(__CYGWIN__)) && (!defined LIBARCHIVE_STATIC)
-# ifdef __LIBARCHIVE_BUILD
-# ifdef __GNUC__
-# define __LA_DECL __attribute__((dllexport)) extern
-# else
-# define __LA_DECL __declspec(dllexport)
-# endif
-# else
-# ifdef __GNUC__
-# define __LA_DECL
-# else
-# define __LA_DECL __declspec(dllimport)
-# endif
-# endif
-#elif defined __LIBARCHIVE_ENABLE_VISIBILITY
-# define __LA_DECL __attribute__((visibility("default")))
-#else
-/* Static libraries or non-Windows needs no special declaration. */
-# define __LA_DECL
-#endif
-
-#if defined(__GNUC__) && __GNUC__ >= 3 && !defined(__MINGW32__)
-#define __LA_PRINTF(fmtarg, firstvararg) \
- __attribute__((__format__ (__printf__, fmtarg, firstvararg)))
-#else
-#define __LA_PRINTF(fmtarg, firstvararg) /* nothing */
-#endif
-
-#if defined(__GNUC__) && __GNUC__ >= 3 && __GNUC_MINOR__ >= 1
-# define __LA_DEPRECATED __attribute__((deprecated))
-#else
-# define __LA_DEPRECATED
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * The version number is provided as both a macro and a function.
- * The macro identifies the installed header; the function identifies
- * the library version (which may not be the same if you're using a
- * dynamically-linked version of the library). Of course, if the
- * header and library are very different, you should expect some
- * strangeness. Don't do that.
- */
-__LA_DECL int archive_version_number(void);
-
-/*
- * Textual name/version of the library, useful for version displays.
- */
-#define ARCHIVE_VERSION_ONLY_STRING "3.7.1"
-#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
-__LA_DECL const char * archive_version_string(void);
-
-/*
- * Detailed textual name/version of the library and its dependencies.
- * This has the form:
- * "libarchive x.y.z zlib/a.b.c liblzma/d.e.f ... etc ..."
- * the list of libraries described here will vary depending on how
- * libarchive was compiled.
- */
-__LA_DECL const char * archive_version_details(void);
-
-/*
- * Returns NULL if libarchive was compiled without the associated library.
- * Otherwise, returns the version number that libarchive was compiled
- * against.
- */
-__LA_DECL const char * archive_zlib_version(void);
-__LA_DECL const char * archive_liblzma_version(void);
-__LA_DECL const char * archive_bzlib_version(void);
-__LA_DECL const char * archive_liblz4_version(void);
-__LA_DECL const char * archive_libzstd_version(void);
-
-/* Declare our basic types. */
-struct archive;
-struct archive_entry;
-
-/*
- * Error codes: Use archive_errno() and archive_error_string()
- * to retrieve details. Unless specified otherwise, all functions
- * that return 'int' use these codes.
- */
-#define ARCHIVE_EOF 1 /* Found end of archive. */
-#define ARCHIVE_OK 0 /* Operation was successful. */
-#define ARCHIVE_RETRY (-10) /* Retry might succeed. */
-#define ARCHIVE_WARN (-20) /* Partial success. */
-/* For example, if write_header "fails", then you can't push data. */
-#define ARCHIVE_FAILED (-25) /* Current operation cannot complete. */
-/* But if write_header is "fatal," then this archive is dead and useless. */
-#define ARCHIVE_FATAL (-30) /* No more operations are possible. */
-
-/*
- * As far as possible, archive_errno returns standard platform errno codes.
- * Of course, the details vary by platform, so the actual definitions
- * here are stored in "archive_platform.h". The symbols are listed here
- * for reference; as a rule, clients should not need to know the exact
- * platform-dependent error code.
- */
-/* Unrecognized or invalid file format. */
-/* #define ARCHIVE_ERRNO_FILE_FORMAT */
-/* Illegal usage of the library. */
-/* #define ARCHIVE_ERRNO_PROGRAMMER_ERROR */
-/* Unknown or unclassified error. */
-/* #define ARCHIVE_ERRNO_MISC */
-
-/*
- * Callbacks are invoked to automatically read/skip/write/open/close the
- * archive. You can provide your own for complex tasks (like breaking
- * archives across multiple tapes) or use standard ones built into the
- * library.
- */
-
-/* Returns pointer and size of next block of data from archive. */
-typedef la_ssize_t archive_read_callback(struct archive *,
- void *_client_data, const void **_buffer);
-
-/* Skips at most request bytes from archive and returns the skipped amount.
- * This may skip fewer bytes than requested; it may even skip zero bytes.
- * If you do skip fewer bytes than requested, libarchive will invoke your
- * read callback and discard data as necessary to make up the full skip.
- */
-typedef la_int64_t archive_skip_callback(struct archive *,
- void *_client_data, la_int64_t request);
-
-/* Seeks to specified location in the file and returns the position.
- * Whence values are SEEK_SET, SEEK_CUR, SEEK_END from stdio.h.
- * Return ARCHIVE_FATAL if the seek fails for any reason.
- */
-typedef la_int64_t archive_seek_callback(struct archive *,
- void *_client_data, la_int64_t offset, int whence);
-
-/* Returns size actually written, zero on EOF, -1 on error. */
-typedef la_ssize_t archive_write_callback(struct archive *,
- void *_client_data,
- const void *_buffer, size_t _length);
-
-typedef int archive_open_callback(struct archive *, void *_client_data);
-
-typedef int archive_close_callback(struct archive *, void *_client_data);
-
-typedef int archive_free_callback(struct archive *, void *_client_data);
-
-/* Switches from one client data object to the next/prev client data object.
- * This is useful for reading from different data blocks such as a set of files
- * that make up one large file.
- */
-typedef int archive_switch_callback(struct archive *, void *_client_data1,
- void *_client_data2);
-
-/*
- * Returns a passphrase used for encryption or decryption, NULL on nothing
- * to do and give it up.
- */
-typedef const char *archive_passphrase_callback(struct archive *,
- void *_client_data);
-
-/*
- * Codes to identify various stream filters.
- */
-#define ARCHIVE_FILTER_NONE 0
-#define ARCHIVE_FILTER_GZIP 1
-#define ARCHIVE_FILTER_BZIP2 2
-#define ARCHIVE_FILTER_COMPRESS 3
-#define ARCHIVE_FILTER_PROGRAM 4
-#define ARCHIVE_FILTER_LZMA 5
-#define ARCHIVE_FILTER_XZ 6
-#define ARCHIVE_FILTER_UU 7
-#define ARCHIVE_FILTER_RPM 8
-#define ARCHIVE_FILTER_LZIP 9
-#define ARCHIVE_FILTER_LRZIP 10
-#define ARCHIVE_FILTER_LZOP 11
-#define ARCHIVE_FILTER_GRZIP 12
-#define ARCHIVE_FILTER_LZ4 13
-#define ARCHIVE_FILTER_ZSTD 14
-
-#if ARCHIVE_VERSION_NUMBER < 4000000
-#define ARCHIVE_COMPRESSION_NONE ARCHIVE_FILTER_NONE
-#define ARCHIVE_COMPRESSION_GZIP ARCHIVE_FILTER_GZIP
-#define ARCHIVE_COMPRESSION_BZIP2 ARCHIVE_FILTER_BZIP2
-#define ARCHIVE_COMPRESSION_COMPRESS ARCHIVE_FILTER_COMPRESS
-#define ARCHIVE_COMPRESSION_PROGRAM ARCHIVE_FILTER_PROGRAM
-#define ARCHIVE_COMPRESSION_LZMA ARCHIVE_FILTER_LZMA
-#define ARCHIVE_COMPRESSION_XZ ARCHIVE_FILTER_XZ
-#define ARCHIVE_COMPRESSION_UU ARCHIVE_FILTER_UU
-#define ARCHIVE_COMPRESSION_RPM ARCHIVE_FILTER_RPM
-#define ARCHIVE_COMPRESSION_LZIP ARCHIVE_FILTER_LZIP
-#define ARCHIVE_COMPRESSION_LRZIP ARCHIVE_FILTER_LRZIP
-#endif
-
-/*
- * Codes returned by archive_format.
- *
- * Top 16 bits identifies the format family (e.g., "tar"); lower
- * 16 bits indicate the variant. This is updated by read_next_header.
- * Note that the lower 16 bits will often vary from entry to entry.
- * In some cases, this variation occurs as libarchive learns more about
- * the archive (for example, later entries might utilize extensions that
- * weren't necessary earlier in the archive; in this case, libarchive
- * will change the format code to indicate the extended format that
- * was used). In other cases, it's because different tools have
- * modified the archive and so different parts of the archive
- * actually have slightly different formats. (Both tar and cpio store
- * format codes in each entry, so it is quite possible for each
- * entry to be in a different format.)
- */
-#define ARCHIVE_FORMAT_BASE_MASK 0xff0000
-#define ARCHIVE_FORMAT_CPIO 0x10000
-#define ARCHIVE_FORMAT_CPIO_POSIX (ARCHIVE_FORMAT_CPIO | 1)
-#define ARCHIVE_FORMAT_CPIO_BIN_LE (ARCHIVE_FORMAT_CPIO | 2)
-#define ARCHIVE_FORMAT_CPIO_BIN_BE (ARCHIVE_FORMAT_CPIO | 3)
-#define ARCHIVE_FORMAT_CPIO_SVR4_NOCRC (ARCHIVE_FORMAT_CPIO | 4)
-#define ARCHIVE_FORMAT_CPIO_SVR4_CRC (ARCHIVE_FORMAT_CPIO | 5)
-#define ARCHIVE_FORMAT_CPIO_AFIO_LARGE (ARCHIVE_FORMAT_CPIO | 6)
-#define ARCHIVE_FORMAT_CPIO_PWB (ARCHIVE_FORMAT_CPIO | 7)
-#define ARCHIVE_FORMAT_SHAR 0x20000
-#define ARCHIVE_FORMAT_SHAR_BASE (ARCHIVE_FORMAT_SHAR | 1)
-#define ARCHIVE_FORMAT_SHAR_DUMP (ARCHIVE_FORMAT_SHAR | 2)
-#define ARCHIVE_FORMAT_TAR 0x30000
-#define ARCHIVE_FORMAT_TAR_USTAR (ARCHIVE_FORMAT_TAR | 1)
-#define ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE (ARCHIVE_FORMAT_TAR | 2)
-#define ARCHIVE_FORMAT_TAR_PAX_RESTRICTED (ARCHIVE_FORMAT_TAR | 3)
-#define ARCHIVE_FORMAT_TAR_GNUTAR (ARCHIVE_FORMAT_TAR | 4)
-#define ARCHIVE_FORMAT_ISO9660 0x40000
-#define ARCHIVE_FORMAT_ISO9660_ROCKRIDGE (ARCHIVE_FORMAT_ISO9660 | 1)
-#define ARCHIVE_FORMAT_ZIP 0x50000
-#define ARCHIVE_FORMAT_EMPTY 0x60000
-#define ARCHIVE_FORMAT_AR 0x70000
-#define ARCHIVE_FORMAT_AR_GNU (ARCHIVE_FORMAT_AR | 1)
-#define ARCHIVE_FORMAT_AR_BSD (ARCHIVE_FORMAT_AR | 2)
-#define ARCHIVE_FORMAT_MTREE 0x80000
-#define ARCHIVE_FORMAT_RAW 0x90000
-#define ARCHIVE_FORMAT_XAR 0xA0000
-#define ARCHIVE_FORMAT_LHA 0xB0000
-#define ARCHIVE_FORMAT_CAB 0xC0000
-#define ARCHIVE_FORMAT_RAR 0xD0000
-#define ARCHIVE_FORMAT_7ZIP 0xE0000
-#define ARCHIVE_FORMAT_WARC 0xF0000
-#define ARCHIVE_FORMAT_RAR_V5 0x100000
-
-/*
- * Codes returned by archive_read_format_capabilities().
- *
- * This list can be extended with values between 0 and 0xffff.
- * The original purpose of this list was to let different archive
- * format readers expose their general capabilities in terms of
- * encryption.
- */
-#define ARCHIVE_READ_FORMAT_CAPS_NONE (0) /* no special capabilities */
-#define ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA (1<<0) /* reader can detect encrypted data */
-#define ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA (1<<1) /* reader can detect encryptable metadata (pathname, mtime, etc.) */
-
-/*
- * Codes returned by archive_read_has_encrypted_entries().
- *
- * In case the archive does not support encryption detection at all
- * ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED is returned. If the reader
- * for some other reason (e.g. not enough bytes read) cannot say if
- * there are encrypted entries, ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW
- * is returned.
- */
-#define ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED -2
-#define ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW -1
-
-/*-
- * Basic outline for reading an archive:
- * 1) Ask archive_read_new for an archive reader object.
- * 2) Update any global properties as appropriate.
- * In particular, you'll certainly want to call appropriate
- * archive_read_support_XXX functions.
- * 3) Call archive_read_open_XXX to open the archive
- * 4) Repeatedly call archive_read_next_header to get information about
- * successive archive entries. Call archive_read_data to extract
- * data for entries of interest.
- * 5) Call archive_read_free to end processing.
- */
-__LA_DECL struct archive *archive_read_new(void);
-
-/*
- * The archive_read_support_XXX calls enable auto-detect for this
- * archive handle. They also link in the necessary support code.
- * For example, if you don't want bzlib linked in, don't invoke
- * support_compression_bzip2(). The "all" functions provide the
- * obvious shorthand.
- */
-
-#if ARCHIVE_VERSION_NUMBER < 4000000
-__LA_DECL int archive_read_support_compression_all(struct archive *)
- __LA_DEPRECATED;
-__LA_DECL int archive_read_support_compression_bzip2(struct archive *)
- __LA_DEPRECATED;
-__LA_DECL int archive_read_support_compression_compress(struct archive *)
- __LA_DEPRECATED;
-__LA_DECL int archive_read_support_compression_gzip(struct archive *)
- __LA_DEPRECATED;
-__LA_DECL int archive_read_support_compression_lzip(struct archive *)
- __LA_DEPRECATED;
-__LA_DECL int archive_read_support_compression_lzma(struct archive *)
- __LA_DEPRECATED;
-__LA_DECL int archive_read_support_compression_none(struct archive *)
- __LA_DEPRECATED;
-__LA_DECL int archive_read_support_compression_program(struct archive *,
- const char *command) __LA_DEPRECATED;
-__LA_DECL int archive_read_support_compression_program_signature
- (struct archive *, const char *,
- const void * /* match */, size_t) __LA_DEPRECATED;
-
-__LA_DECL int archive_read_support_compression_rpm(struct archive *)
- __LA_DEPRECATED;
-__LA_DECL int archive_read_support_compression_uu(struct archive *)
- __LA_DEPRECATED;
-__LA_DECL int archive_read_support_compression_xz(struct archive *)
- __LA_DEPRECATED;
-#endif
-
-__LA_DECL int archive_read_support_filter_all(struct archive *);
-__LA_DECL int archive_read_support_filter_by_code(struct archive *, int);
-__LA_DECL int archive_read_support_filter_bzip2(struct archive *);
-__LA_DECL int archive_read_support_filter_compress(struct archive *);
-__LA_DECL int archive_read_support_filter_gzip(struct archive *);
-__LA_DECL int archive_read_support_filter_grzip(struct archive *);
-__LA_DECL int archive_read_support_filter_lrzip(struct archive *);
-__LA_DECL int archive_read_support_filter_lz4(struct archive *);
-__LA_DECL int archive_read_support_filter_lzip(struct archive *);
-__LA_DECL int archive_read_support_filter_lzma(struct archive *);
-__LA_DECL int archive_read_support_filter_lzop(struct archive *);
-__LA_DECL int archive_read_support_filter_none(struct archive *);
-__LA_DECL int archive_read_support_filter_program(struct archive *,
- const char *command);
-__LA_DECL int archive_read_support_filter_program_signature
- (struct archive *, const char * /* cmd */,
- const void * /* match */, size_t);
-__LA_DECL int archive_read_support_filter_rpm(struct archive *);
-__LA_DECL int archive_read_support_filter_uu(struct archive *);
-__LA_DECL int archive_read_support_filter_xz(struct archive *);
-__LA_DECL int archive_read_support_filter_zstd(struct archive *);
-
-__LA_DECL int archive_read_support_format_7zip(struct archive *);
-__LA_DECL int archive_read_support_format_all(struct archive *);
-__LA_DECL int archive_read_support_format_ar(struct archive *);
-__LA_DECL int archive_read_support_format_by_code(struct archive *, int);
-__LA_DECL int archive_read_support_format_cab(struct archive *);
-__LA_DECL int archive_read_support_format_cpio(struct archive *);
-__LA_DECL int archive_read_support_format_empty(struct archive *);
-__LA_DECL int archive_read_support_format_gnutar(struct archive *);
-__LA_DECL int archive_read_support_format_iso9660(struct archive *);
-__LA_DECL int archive_read_support_format_lha(struct archive *);
-__LA_DECL int archive_read_support_format_mtree(struct archive *);
-__LA_DECL int archive_read_support_format_rar(struct archive *);
-__LA_DECL int archive_read_support_format_rar5(struct archive *);
-__LA_DECL int archive_read_support_format_raw(struct archive *);
-__LA_DECL int archive_read_support_format_tar(struct archive *);
-__LA_DECL int archive_read_support_format_warc(struct archive *);
-__LA_DECL int archive_read_support_format_xar(struct archive *);
-/* archive_read_support_format_zip() enables both streamable and seekable
- * zip readers. */
-__LA_DECL int archive_read_support_format_zip(struct archive *);
-/* Reads Zip archives as stream from beginning to end. Doesn't
- * correctly handle SFX ZIP files or ZIP archives that have been modified
- * in-place. */
-__LA_DECL int archive_read_support_format_zip_streamable(struct archive *);
-/* Reads starting from central directory; requires seekable input. */
-__LA_DECL int archive_read_support_format_zip_seekable(struct archive *);
-
-/* Functions to manually set the format and filters to be used. This is
- * useful to bypass the bidding process when the format and filters to use
- * is known in advance.
- */
-__LA_DECL int archive_read_set_format(struct archive *, int);
-__LA_DECL int archive_read_append_filter(struct archive *, int);
-__LA_DECL int archive_read_append_filter_program(struct archive *,
- const char *);
-__LA_DECL int archive_read_append_filter_program_signature
- (struct archive *, const char *, const void * /* match */, size_t);
-
-/* Set various callbacks. */
-__LA_DECL int archive_read_set_open_callback(struct archive *,
- archive_open_callback *);
-__LA_DECL int archive_read_set_read_callback(struct archive *,
- archive_read_callback *);
-__LA_DECL int archive_read_set_seek_callback(struct archive *,
- archive_seek_callback *);
-__LA_DECL int archive_read_set_skip_callback(struct archive *,
- archive_skip_callback *);
-__LA_DECL int archive_read_set_close_callback(struct archive *,
- archive_close_callback *);
-/* Callback used to switch between one data object to the next */
-__LA_DECL int archive_read_set_switch_callback(struct archive *,
- archive_switch_callback *);
-
-/* This sets the first data object. */
-__LA_DECL int archive_read_set_callback_data(struct archive *, void *);
-/* This sets data object at specified index */
-__LA_DECL int archive_read_set_callback_data2(struct archive *, void *,
- unsigned int);
-/* This adds a data object at the specified index. */
-__LA_DECL int archive_read_add_callback_data(struct archive *, void *,
- unsigned int);
-/* This appends a data object to the end of list */
-__LA_DECL int archive_read_append_callback_data(struct archive *, void *);
-/* This prepends a data object to the beginning of list */
-__LA_DECL int archive_read_prepend_callback_data(struct archive *, void *);
-
-/* Opening freezes the callbacks. */
-__LA_DECL int archive_read_open1(struct archive *);
-
-/* Convenience wrappers around the above. */
-__LA_DECL int archive_read_open(struct archive *, void *_client_data,
- archive_open_callback *, archive_read_callback *,
- archive_close_callback *);
-__LA_DECL int archive_read_open2(struct archive *, void *_client_data,
- archive_open_callback *, archive_read_callback *,
- archive_skip_callback *, archive_close_callback *);
-
-/*
- * A variety of shortcuts that invoke archive_read_open() with
- * canned callbacks suitable for common situations. The ones that
- * accept a block size handle tape blocking correctly.
- */
-/* Use this if you know the filename. Note: NULL indicates stdin. */
-__LA_DECL int archive_read_open_filename(struct archive *,
- const char *_filename, size_t _block_size);
-/* Use this for reading multivolume files by filenames.
- * NOTE: Must be NULL terminated. Sorting is NOT done. */
-__LA_DECL int archive_read_open_filenames(struct archive *,
- const char **_filenames, size_t _block_size);
-__LA_DECL int archive_read_open_filename_w(struct archive *,
- const wchar_t *_filename, size_t _block_size);
-/* archive_read_open_file() is a deprecated synonym for ..._open_filename(). */
-__LA_DECL int archive_read_open_file(struct archive *,
- const char *_filename, size_t _block_size) __LA_DEPRECATED;
-/* Read an archive that's stored in memory. */
-__LA_DECL int archive_read_open_memory(struct archive *,
- const void * buff, size_t size);
-/* A more involved version that is only used for internal testing. */
-__LA_DECL int archive_read_open_memory2(struct archive *a, const void *buff,
- size_t size, size_t read_size);
-/* Read an archive that's already open, using the file descriptor. */
-__LA_DECL int archive_read_open_fd(struct archive *, int _fd,
- size_t _block_size);
-/* Read an archive that's already open, using a FILE *. */
-/* Note: DO NOT use this with tape drives. */
-__LA_DECL int archive_read_open_FILE(struct archive *, FILE *_file);
-
-/* Parses and returns next entry header. */
-__LA_DECL int archive_read_next_header(struct archive *,
- struct archive_entry **);
-
-/* Parses and returns next entry header using the archive_entry passed in */
-__LA_DECL int archive_read_next_header2(struct archive *,
- struct archive_entry *);
-
-/*
- * Retrieve the byte offset in UNCOMPRESSED data where last-read
- * header started.
- */
-__LA_DECL la_int64_t archive_read_header_position(struct archive *);
-
-/*
- * Returns 1 if the archive contains at least one encrypted entry.
- * If the archive format not support encryption at all
- * ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED is returned.
- * If for any other reason (e.g. not enough data read so far)
- * we cannot say whether there are encrypted entries, then
- * ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW is returned.
- * In general, this function will return values below zero when the
- * reader is uncertain or totally incapable of encryption support.
- * When this function returns 0 you can be sure that the reader
- * supports encryption detection but no encrypted entries have
- * been found yet.
- *
- * NOTE: If the metadata/header of an archive is also encrypted, you
- * cannot rely on the number of encrypted entries. That is why this
- * function does not return the number of encrypted entries but#
- * just shows that there are some.
- */
-__LA_DECL int archive_read_has_encrypted_entries(struct archive *);
-
-/*
- * Returns a bitmask of capabilities that are supported by the archive format reader.
- * If the reader has no special capabilities, ARCHIVE_READ_FORMAT_CAPS_NONE is returned.
- */
-__LA_DECL int archive_read_format_capabilities(struct archive *);
-
-/* Read data from the body of an entry. Similar to read(2). */
-__LA_DECL la_ssize_t archive_read_data(struct archive *,
- void *, size_t);
-
-/* Seek within the body of an entry. Similar to lseek(2). */
-__LA_DECL la_int64_t archive_seek_data(struct archive *, la_int64_t, int);
-
-/*
- * A zero-copy version of archive_read_data that also exposes the file offset
- * of each returned block. Note that the client has no way to specify
- * the desired size of the block. The API does guarantee that offsets will
- * be strictly increasing and that returned blocks will not overlap.
- */
-__LA_DECL int archive_read_data_block(struct archive *a,
- const void **buff, size_t *size, la_int64_t *offset);
-
-/*-
- * Some convenience functions that are built on archive_read_data:
- * 'skip': skips entire entry
- * 'into_buffer': writes data into memory buffer that you provide
- * 'into_fd': writes data to specified filedes
- */
-__LA_DECL int archive_read_data_skip(struct archive *);
-__LA_DECL int archive_read_data_into_fd(struct archive *, int fd);
-
-/*
- * Set read options.
- */
-/* Apply option to the format only. */
-__LA_DECL int archive_read_set_format_option(struct archive *_a,
- const char *m, const char *o,
- const char *v);
-/* Apply option to the filter only. */
-__LA_DECL int archive_read_set_filter_option(struct archive *_a,
- const char *m, const char *o,
- const char *v);
-/* Apply option to both the format and the filter. */
-__LA_DECL int archive_read_set_option(struct archive *_a,
- const char *m, const char *o,
- const char *v);
-/* Apply option string to both the format and the filter. */
-__LA_DECL int archive_read_set_options(struct archive *_a,
- const char *opts);
-
-/*
- * Add a decryption passphrase.
- */
-__LA_DECL int archive_read_add_passphrase(struct archive *, const char *);
-__LA_DECL int archive_read_set_passphrase_callback(struct archive *,
- void *client_data, archive_passphrase_callback *);
-
-
-/*-
- * Convenience function to recreate the current entry (whose header
- * has just been read) on disk.
- *
- * This does quite a bit more than just copy data to disk. It also:
- * - Creates intermediate directories as required.
- * - Manages directory permissions: non-writable directories will
- * be initially created with write permission enabled; when the
- * archive is closed, dir permissions are edited to the values specified
- * in the archive.
- * - Checks hardlinks: hardlinks will not be extracted unless the
- * linked-to file was also extracted within the same session. (TODO)
- */
-
-/* The "flags" argument selects optional behavior, 'OR' the flags you want. */
-
-/* Default: Do not try to set owner/group. */
-#define ARCHIVE_EXTRACT_OWNER (0x0001)
-/* Default: Do obey umask, do not restore SUID/SGID/SVTX bits. */
-#define ARCHIVE_EXTRACT_PERM (0x0002)
-/* Default: Do not restore mtime/atime. */
-#define ARCHIVE_EXTRACT_TIME (0x0004)
-/* Default: Replace existing files. */
-#define ARCHIVE_EXTRACT_NO_OVERWRITE (0x0008)
-/* Default: Try create first, unlink only if create fails with EEXIST. */
-#define ARCHIVE_EXTRACT_UNLINK (0x0010)
-/* Default: Do not restore ACLs. */
-#define ARCHIVE_EXTRACT_ACL (0x0020)
-/* Default: Do not restore fflags. */
-#define ARCHIVE_EXTRACT_FFLAGS (0x0040)
-/* Default: Do not restore xattrs. */
-#define ARCHIVE_EXTRACT_XATTR (0x0080)
-/* Default: Do not try to guard against extracts redirected by symlinks. */
-/* Note: With ARCHIVE_EXTRACT_UNLINK, will remove any intermediate symlink. */
-#define ARCHIVE_EXTRACT_SECURE_SYMLINKS (0x0100)
-/* Default: Do not reject entries with '..' as path elements. */
-#define ARCHIVE_EXTRACT_SECURE_NODOTDOT (0x0200)
-/* Default: Create parent directories as needed. */
-#define ARCHIVE_EXTRACT_NO_AUTODIR (0x0400)
-/* Default: Overwrite files, even if one on disk is newer. */
-#define ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER (0x0800)
-/* Detect blocks of 0 and write holes instead. */
-#define ARCHIVE_EXTRACT_SPARSE (0x1000)
-/* Default: Do not restore Mac extended metadata. */
-/* This has no effect except on Mac OS. */
-#define ARCHIVE_EXTRACT_MAC_METADATA (0x2000)
-/* Default: Use HFS+ compression if it was compressed. */
-/* This has no effect except on Mac OS v10.6 or later. */
-#define ARCHIVE_EXTRACT_NO_HFS_COMPRESSION (0x4000)
-/* Default: Do not use HFS+ compression if it was not compressed. */
-/* This has no effect except on Mac OS v10.6 or later. */
-#define ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED (0x8000)
-/* Default: Do not reject entries with absolute paths */
-#define ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS (0x10000)
-/* Default: Do not clear no-change flags when unlinking object */
-#define ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS (0x20000)
-/* Default: Do not extract atomically (using rename) */
-#define ARCHIVE_EXTRACT_SAFE_WRITES (0x40000)
-
-__LA_DECL int archive_read_extract(struct archive *, struct archive_entry *,
- int flags);
-__LA_DECL int archive_read_extract2(struct archive *, struct archive_entry *,
- struct archive * /* dest */);
-__LA_DECL void archive_read_extract_set_progress_callback(struct archive *,
- void (*_progress_func)(void *), void *_user_data);
-
-/* Record the dev/ino of a file that will not be written. This is
- * generally set to the dev/ino of the archive being read. */
-__LA_DECL void archive_read_extract_set_skip_file(struct archive *,
- la_int64_t, la_int64_t);
-
-/* Close the file and release most resources. */
-__LA_DECL int archive_read_close(struct archive *);
-/* Release all resources and destroy the object. */
-/* Note that archive_read_free will call archive_read_close for you. */
-__LA_DECL int archive_read_free(struct archive *);
-#if ARCHIVE_VERSION_NUMBER < 4000000
-/* Synonym for archive_read_free() for backwards compatibility. */
-__LA_DECL int archive_read_finish(struct archive *) __LA_DEPRECATED;
-#endif
-
-/*-
- * To create an archive:
- * 1) Ask archive_write_new for an archive writer object.
- * 2) Set any global properties. In particular, you should set
- * the compression and format to use.
- * 3) Call archive_write_open to open the file (most people
- * will use archive_write_open_file or archive_write_open_fd,
- * which provide convenient canned I/O callbacks for you).
- * 4) For each entry:
- * - construct an appropriate struct archive_entry structure
- * - archive_write_header to write the header
- * - archive_write_data to write the entry data
- * 5) archive_write_close to close the output
- * 6) archive_write_free to cleanup the writer and release resources
- */
-__LA_DECL struct archive *archive_write_new(void);
-__LA_DECL int archive_write_set_bytes_per_block(struct archive *,
- int bytes_per_block);
-__LA_DECL int archive_write_get_bytes_per_block(struct archive *);
-/* XXX This is badly misnamed; suggestions appreciated. XXX */
-__LA_DECL int archive_write_set_bytes_in_last_block(struct archive *,
- int bytes_in_last_block);
-__LA_DECL int archive_write_get_bytes_in_last_block(struct archive *);
-
-/* The dev/ino of a file that won't be archived. This is used
- * to avoid recursively adding an archive to itself. */
-__LA_DECL int archive_write_set_skip_file(struct archive *,
- la_int64_t, la_int64_t);
-
-#if ARCHIVE_VERSION_NUMBER < 4000000
-__LA_DECL int archive_write_set_compression_bzip2(struct archive *)
- __LA_DEPRECATED;
-__LA_DECL int archive_write_set_compression_compress(struct archive *)
- __LA_DEPRECATED;
-__LA_DECL int archive_write_set_compression_gzip(struct archive *)
- __LA_DEPRECATED;
-__LA_DECL int archive_write_set_compression_lzip(struct archive *)
- __LA_DEPRECATED;
-__LA_DECL int archive_write_set_compression_lzma(struct archive *)
- __LA_DEPRECATED;
-__LA_DECL int archive_write_set_compression_none(struct archive *)
- __LA_DEPRECATED;
-__LA_DECL int archive_write_set_compression_program(struct archive *,
- const char *cmd) __LA_DEPRECATED;
-__LA_DECL int archive_write_set_compression_xz(struct archive *)
- __LA_DEPRECATED;
-#endif
-
-/* A convenience function to set the filter based on the code. */
-__LA_DECL int archive_write_add_filter(struct archive *, int filter_code);
-__LA_DECL int archive_write_add_filter_by_name(struct archive *,
- const char *name);
-__LA_DECL int archive_write_add_filter_b64encode(struct archive *);
-__LA_DECL int archive_write_add_filter_bzip2(struct archive *);
-__LA_DECL int archive_write_add_filter_compress(struct archive *);
-__LA_DECL int archive_write_add_filter_grzip(struct archive *);
-__LA_DECL int archive_write_add_filter_gzip(struct archive *);
-__LA_DECL int archive_write_add_filter_lrzip(struct archive *);
-__LA_DECL int archive_write_add_filter_lz4(struct archive *);
-__LA_DECL int archive_write_add_filter_lzip(struct archive *);
-__LA_DECL int archive_write_add_filter_lzma(struct archive *);
-__LA_DECL int archive_write_add_filter_lzop(struct archive *);
-__LA_DECL int archive_write_add_filter_none(struct archive *);
-__LA_DECL int archive_write_add_filter_program(struct archive *,
- const char *cmd);
-__LA_DECL int archive_write_add_filter_uuencode(struct archive *);
-__LA_DECL int archive_write_add_filter_xz(struct archive *);
-__LA_DECL int archive_write_add_filter_zstd(struct archive *);
-
-
-/* A convenience function to set the format based on the code or name. */
-__LA_DECL int archive_write_set_format(struct archive *, int format_code);
-__LA_DECL int archive_write_set_format_by_name(struct archive *,
- const char *name);
-/* To minimize link pollution, use one or more of the following. */
-__LA_DECL int archive_write_set_format_7zip(struct archive *);
-__LA_DECL int archive_write_set_format_ar_bsd(struct archive *);
-__LA_DECL int archive_write_set_format_ar_svr4(struct archive *);
-__LA_DECL int archive_write_set_format_cpio(struct archive *);
-__LA_DECL int archive_write_set_format_cpio_bin(struct archive *);
-__LA_DECL int archive_write_set_format_cpio_newc(struct archive *);
-__LA_DECL int archive_write_set_format_cpio_odc(struct archive *);
-__LA_DECL int archive_write_set_format_cpio_pwb(struct archive *);
-__LA_DECL int archive_write_set_format_gnutar(struct archive *);
-__LA_DECL int archive_write_set_format_iso9660(struct archive *);
-__LA_DECL int archive_write_set_format_mtree(struct archive *);
-__LA_DECL int archive_write_set_format_mtree_classic(struct archive *);
-/* TODO: int archive_write_set_format_old_tar(struct archive *); */
-__LA_DECL int archive_write_set_format_pax(struct archive *);
-__LA_DECL int archive_write_set_format_pax_restricted(struct archive *);
-__LA_DECL int archive_write_set_format_raw(struct archive *);
-__LA_DECL int archive_write_set_format_shar(struct archive *);
-__LA_DECL int archive_write_set_format_shar_dump(struct archive *);
-__LA_DECL int archive_write_set_format_ustar(struct archive *);
-__LA_DECL int archive_write_set_format_v7tar(struct archive *);
-__LA_DECL int archive_write_set_format_warc(struct archive *);
-__LA_DECL int archive_write_set_format_xar(struct archive *);
-__LA_DECL int archive_write_set_format_zip(struct archive *);
-__LA_DECL int archive_write_set_format_filter_by_ext(struct archive *a, const char *filename);
-__LA_DECL int archive_write_set_format_filter_by_ext_def(struct archive *a, const char *filename, const char * def_ext);
-__LA_DECL int archive_write_zip_set_compression_deflate(struct archive *);
-__LA_DECL int archive_write_zip_set_compression_store(struct archive *);
-/* Deprecated; use archive_write_open2 instead */
-__LA_DECL int archive_write_open(struct archive *, void *,
- archive_open_callback *, archive_write_callback *,
- archive_close_callback *);
-__LA_DECL int archive_write_open2(struct archive *, void *,
- archive_open_callback *, archive_write_callback *,
- archive_close_callback *, archive_free_callback *);
-__LA_DECL int archive_write_open_fd(struct archive *, int _fd);
-__LA_DECL int archive_write_open_filename(struct archive *, const char *_file);
-__LA_DECL int archive_write_open_filename_w(struct archive *,
- const wchar_t *_file);
-/* A deprecated synonym for archive_write_open_filename() */
-__LA_DECL int archive_write_open_file(struct archive *, const char *_file)
- __LA_DEPRECATED;
-__LA_DECL int archive_write_open_FILE(struct archive *, FILE *);
-/* _buffSize is the size of the buffer, _used refers to a variable that
- * will be updated after each write into the buffer. */
-__LA_DECL int archive_write_open_memory(struct archive *,
- void *_buffer, size_t _buffSize, size_t *_used);
-
-/*
- * Note that the library will truncate writes beyond the size provided
- * to archive_write_header or pad if the provided data is short.
- */
-__LA_DECL int archive_write_header(struct archive *,
- struct archive_entry *);
-__LA_DECL la_ssize_t archive_write_data(struct archive *,
- const void *, size_t);
-
-/* This interface is currently only available for archive_write_disk handles. */
-__LA_DECL la_ssize_t archive_write_data_block(struct archive *,
- const void *, size_t, la_int64_t);
-
-__LA_DECL int archive_write_finish_entry(struct archive *);
-__LA_DECL int archive_write_close(struct archive *);
-/* Marks the archive as FATAL so that a subsequent free() operation
- * won't try to close() cleanly. Provides a fast abort capability
- * when the client discovers that things have gone wrong. */
-__LA_DECL int archive_write_fail(struct archive *);
-/* This can fail if the archive wasn't already closed, in which case
- * archive_write_free() will implicitly call archive_write_close(). */
-__LA_DECL int archive_write_free(struct archive *);
-#if ARCHIVE_VERSION_NUMBER < 4000000
-/* Synonym for archive_write_free() for backwards compatibility. */
-__LA_DECL int archive_write_finish(struct archive *) __LA_DEPRECATED;
-#endif
-
-/*
- * Set write options.
- */
-/* Apply option to the format only. */
-__LA_DECL int archive_write_set_format_option(struct archive *_a,
- const char *m, const char *o,
- const char *v);
-/* Apply option to the filter only. */
-__LA_DECL int archive_write_set_filter_option(struct archive *_a,
- const char *m, const char *o,
- const char *v);
-/* Apply option to both the format and the filter. */
-__LA_DECL int archive_write_set_option(struct archive *_a,
- const char *m, const char *o,
- const char *v);
-/* Apply option string to both the format and the filter. */
-__LA_DECL int archive_write_set_options(struct archive *_a,
- const char *opts);
-
-/*
- * Set a encryption passphrase.
- */
-__LA_DECL int archive_write_set_passphrase(struct archive *_a, const char *p);
-__LA_DECL int archive_write_set_passphrase_callback(struct archive *,
- void *client_data, archive_passphrase_callback *);
-
-/*-
- * ARCHIVE_WRITE_DISK API
- *
- * To create objects on disk:
- * 1) Ask archive_write_disk_new for a new archive_write_disk object.
- * 2) Set any global properties. In particular, you probably
- * want to set the options.
- * 3) For each entry:
- * - construct an appropriate struct archive_entry structure
- * - archive_write_header to create the file/dir/etc on disk
- * - archive_write_data to write the entry data
- * 4) archive_write_free to cleanup the writer and release resources
- *
- * In particular, you can use this in conjunction with archive_read()
- * to pull entries out of an archive and create them on disk.
- */
-__LA_DECL struct archive *archive_write_disk_new(void);
-/* This file will not be overwritten. */
-__LA_DECL int archive_write_disk_set_skip_file(struct archive *,
- la_int64_t, la_int64_t);
-/* Set flags to control how the next item gets created.
- * This accepts a bitmask of ARCHIVE_EXTRACT_XXX flags defined above. */
-__LA_DECL int archive_write_disk_set_options(struct archive *,
- int flags);
-/*
- * The lookup functions are given uname/uid (or gname/gid) pairs and
- * return a uid (gid) suitable for this system. These are used for
- * restoring ownership and for setting ACLs. The default functions
- * are naive, they just return the uid/gid. These are small, so reasonable
- * for applications that don't need to preserve ownership; they
- * are probably also appropriate for applications that are doing
- * same-system backup and restore.
- */
-/*
- * The "standard" lookup functions use common system calls to lookup
- * the uname/gname, falling back to the uid/gid if the names can't be
- * found. They cache lookups and are reasonably fast, but can be very
- * large, so they are not used unless you ask for them. In
- * particular, these match the specifications of POSIX "pax" and old
- * POSIX "tar".
- */
-__LA_DECL int archive_write_disk_set_standard_lookup(struct archive *);
-/*
- * If neither the default (naive) nor the standard (big) functions suit
- * your needs, you can write your own and register them. Be sure to
- * include a cleanup function if you have allocated private data.
- */
-__LA_DECL int archive_write_disk_set_group_lookup(struct archive *,
- void * /* private_data */,
- la_int64_t (*)(void *, const char *, la_int64_t),
- void (* /* cleanup */)(void *));
-__LA_DECL int archive_write_disk_set_user_lookup(struct archive *,
- void * /* private_data */,
- la_int64_t (*)(void *, const char *, la_int64_t),
- void (* /* cleanup */)(void *));
-__LA_DECL la_int64_t archive_write_disk_gid(struct archive *, const char *, la_int64_t);
-__LA_DECL la_int64_t archive_write_disk_uid(struct archive *, const char *, la_int64_t);
-
-/*
- * ARCHIVE_READ_DISK API
- *
- * This is still evolving and somewhat experimental.
- */
-__LA_DECL struct archive *archive_read_disk_new(void);
-/* The names for symlink modes here correspond to an old BSD
- * command-line argument convention: -L, -P, -H */
-/* Follow all symlinks. */
-__LA_DECL int archive_read_disk_set_symlink_logical(struct archive *);
-/* Follow no symlinks. */
-__LA_DECL int archive_read_disk_set_symlink_physical(struct archive *);
-/* Follow symlink initially, then not. */
-__LA_DECL int archive_read_disk_set_symlink_hybrid(struct archive *);
-/* TODO: Handle Linux stat32/stat64 ugliness. <sigh> */
-__LA_DECL int archive_read_disk_entry_from_file(struct archive *,
- struct archive_entry *, int /* fd */, const struct stat *);
-/* Look up gname for gid or uname for uid. */
-/* Default implementations are very, very stupid. */
-__LA_DECL const char *archive_read_disk_gname(struct archive *, la_int64_t);
-__LA_DECL const char *archive_read_disk_uname(struct archive *, la_int64_t);
-/* "Standard" implementation uses getpwuid_r, getgrgid_r and caches the
- * results for performance. */
-__LA_DECL int archive_read_disk_set_standard_lookup(struct archive *);
-/* You can install your own lookups if you like. */
-__LA_DECL int archive_read_disk_set_gname_lookup(struct archive *,
- void * /* private_data */,
- const char *(* /* lookup_fn */)(void *, la_int64_t),
- void (* /* cleanup_fn */)(void *));
-__LA_DECL int archive_read_disk_set_uname_lookup(struct archive *,
- void * /* private_data */,
- const char *(* /* lookup_fn */)(void *, la_int64_t),
- void (* /* cleanup_fn */)(void *));
-/* Start traversal. */
-__LA_DECL int archive_read_disk_open(struct archive *, const char *);
-__LA_DECL int archive_read_disk_open_w(struct archive *, const wchar_t *);
-/*
- * Request that current entry be visited. If you invoke it on every
- * directory, you'll get a physical traversal. This is ignored if the
- * current entry isn't a directory or a link to a directory. So, if
- * you invoke this on every returned path, you'll get a full logical
- * traversal.
- */
-__LA_DECL int archive_read_disk_descend(struct archive *);
-__LA_DECL int archive_read_disk_can_descend(struct archive *);
-__LA_DECL int archive_read_disk_current_filesystem(struct archive *);
-__LA_DECL int archive_read_disk_current_filesystem_is_synthetic(struct archive *);
-__LA_DECL int archive_read_disk_current_filesystem_is_remote(struct archive *);
-/* Request that the access time of the entry visited by traversal be restored. */
-__LA_DECL int archive_read_disk_set_atime_restored(struct archive *);
-/*
- * Set behavior. The "flags" argument selects optional behavior.
- */
-/* Request that the access time of the entry visited by traversal be restored.
- * This is the same as archive_read_disk_set_atime_restored. */
-#define ARCHIVE_READDISK_RESTORE_ATIME (0x0001)
-/* Default: Do not skip an entry which has nodump flags. */
-#define ARCHIVE_READDISK_HONOR_NODUMP (0x0002)
-/* Default: Skip a mac resource fork file whose prefix is "._" because of
- * using copyfile. */
-#define ARCHIVE_READDISK_MAC_COPYFILE (0x0004)
-/* Default: Traverse mount points. */
-#define ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS (0x0008)
-/* Default: Xattrs are read from disk. */
-#define ARCHIVE_READDISK_NO_XATTR (0x0010)
-/* Default: ACLs are read from disk. */
-#define ARCHIVE_READDISK_NO_ACL (0x0020)
-/* Default: File flags are read from disk. */
-#define ARCHIVE_READDISK_NO_FFLAGS (0x0040)
-/* Default: Sparse file information is read from disk. */
-#define ARCHIVE_READDISK_NO_SPARSE (0x0080)
-
-__LA_DECL int archive_read_disk_set_behavior(struct archive *,
- int flags);
-
-/*
- * Set archive_match object that will be used in archive_read_disk to
- * know whether an entry should be skipped. The callback function
- * _excluded_func will be invoked when an entry is skipped by the result
- * of archive_match.
- */
-__LA_DECL int archive_read_disk_set_matching(struct archive *,
- struct archive *_matching, void (*_excluded_func)
- (struct archive *, void *, struct archive_entry *),
- void *_client_data);
-__LA_DECL int archive_read_disk_set_metadata_filter_callback(struct archive *,
- int (*_metadata_filter_func)(struct archive *, void *,
- struct archive_entry *), void *_client_data);
-
-/* Simplified cleanup interface;
- * This calls archive_read_free() or archive_write_free() as needed. */
-__LA_DECL int archive_free(struct archive *);
-
-/*
- * Accessor functions to read/set various information in
- * the struct archive object:
- */
-
-/* Number of filters in the current filter pipeline. */
-/* Filter #0 is the one closest to the format, -1 is a synonym for the
- * last filter, which is always the pseudo-filter that wraps the
- * client callbacks. */
-__LA_DECL int archive_filter_count(struct archive *);
-__LA_DECL la_int64_t archive_filter_bytes(struct archive *, int);
-__LA_DECL int archive_filter_code(struct archive *, int);
-__LA_DECL const char * archive_filter_name(struct archive *, int);
-
-#if ARCHIVE_VERSION_NUMBER < 4000000
-/* These don't properly handle multiple filters, so are deprecated and
- * will eventually be removed. */
-/* As of libarchive 3.0, this is an alias for archive_filter_bytes(a, -1); */
-__LA_DECL la_int64_t archive_position_compressed(struct archive *)
- __LA_DEPRECATED;
-/* As of libarchive 3.0, this is an alias for archive_filter_bytes(a, 0); */
-__LA_DECL la_int64_t archive_position_uncompressed(struct archive *)
- __LA_DEPRECATED;
-/* As of libarchive 3.0, this is an alias for archive_filter_name(a, 0); */
-__LA_DECL const char *archive_compression_name(struct archive *)
- __LA_DEPRECATED;
-/* As of libarchive 3.0, this is an alias for archive_filter_code(a, 0); */
-__LA_DECL int archive_compression(struct archive *)
- __LA_DEPRECATED;
-#endif
-
-__LA_DECL int archive_errno(struct archive *);
-__LA_DECL const char *archive_error_string(struct archive *);
-__LA_DECL const char *archive_format_name(struct archive *);
-__LA_DECL int archive_format(struct archive *);
-__LA_DECL void archive_clear_error(struct archive *);
-__LA_DECL void archive_set_error(struct archive *, int _err,
- const char *fmt, ...) __LA_PRINTF(3, 4);
-__LA_DECL void archive_copy_error(struct archive *dest,
- struct archive *src);
-__LA_DECL int archive_file_count(struct archive *);
-
-/*
- * ARCHIVE_MATCH API
- */
-__LA_DECL struct archive *archive_match_new(void);
-__LA_DECL int archive_match_free(struct archive *);
-
-/*
- * Test if archive_entry is excluded.
- * This is a convenience function. This is the same as calling all
- * archive_match_path_excluded, archive_match_time_excluded
- * and archive_match_owner_excluded.
- */
-__LA_DECL int archive_match_excluded(struct archive *,
- struct archive_entry *);
-
-/*
- * Test if pathname is excluded. The conditions are set by following functions.
- */
-__LA_DECL int archive_match_path_excluded(struct archive *,
- struct archive_entry *);
-/* Control recursive inclusion of directory content when directory is included. Default on. */
-__LA_DECL int archive_match_set_inclusion_recursion(struct archive *, int);
-/* Add exclusion pathname pattern. */
-__LA_DECL int archive_match_exclude_pattern(struct archive *, const char *);
-__LA_DECL int archive_match_exclude_pattern_w(struct archive *,
- const wchar_t *);
-/* Add exclusion pathname pattern from file. */
-__LA_DECL int archive_match_exclude_pattern_from_file(struct archive *,
- const char *, int _nullSeparator);
-__LA_DECL int archive_match_exclude_pattern_from_file_w(struct archive *,
- const wchar_t *, int _nullSeparator);
-/* Add inclusion pathname pattern. */
-__LA_DECL int archive_match_include_pattern(struct archive *, const char *);
-__LA_DECL int archive_match_include_pattern_w(struct archive *,
- const wchar_t *);
-/* Add inclusion pathname pattern from file. */
-__LA_DECL int archive_match_include_pattern_from_file(struct archive *,
- const char *, int _nullSeparator);
-__LA_DECL int archive_match_include_pattern_from_file_w(struct archive *,
- const wchar_t *, int _nullSeparator);
-/*
- * How to get statistic information for inclusion patterns.
- */
-/* Return the amount number of unmatched inclusion patterns. */
-__LA_DECL int archive_match_path_unmatched_inclusions(struct archive *);
-/* Return the pattern of unmatched inclusion with ARCHIVE_OK.
- * Return ARCHIVE_EOF if there is no inclusion pattern. */
-__LA_DECL int archive_match_path_unmatched_inclusions_next(
- struct archive *, const char **);
-__LA_DECL int archive_match_path_unmatched_inclusions_next_w(
- struct archive *, const wchar_t **);
-
-/*
- * Test if a file is excluded by its time stamp.
- * The conditions are set by following functions.
- */
-__LA_DECL int archive_match_time_excluded(struct archive *,
- struct archive_entry *);
-
-/*
- * Flags to tell a matching type of time stamps. These are used for
- * following functions.
- */
-/* Time flag: mtime to be tested. */
-#define ARCHIVE_MATCH_MTIME (0x0100)
-/* Time flag: ctime to be tested. */
-#define ARCHIVE_MATCH_CTIME (0x0200)
-/* Comparison flag: Match the time if it is newer than. */
-#define ARCHIVE_MATCH_NEWER (0x0001)
-/* Comparison flag: Match the time if it is older than. */
-#define ARCHIVE_MATCH_OLDER (0x0002)
-/* Comparison flag: Match the time if it is equal to. */
-#define ARCHIVE_MATCH_EQUAL (0x0010)
-/* Set inclusion time. */
-__LA_DECL int archive_match_include_time(struct archive *, int _flag,
- time_t _sec, long _nsec);
-/* Set inclusion time by a date string. */
-__LA_DECL int archive_match_include_date(struct archive *, int _flag,
- const char *_datestr);
-__LA_DECL int archive_match_include_date_w(struct archive *, int _flag,
- const wchar_t *_datestr);
-/* Set inclusion time by a particular file. */
-__LA_DECL int archive_match_include_file_time(struct archive *,
- int _flag, const char *_pathname);
-__LA_DECL int archive_match_include_file_time_w(struct archive *,
- int _flag, const wchar_t *_pathname);
-/* Add exclusion entry. */
-__LA_DECL int archive_match_exclude_entry(struct archive *,
- int _flag, struct archive_entry *);
-
-/*
- * Test if a file is excluded by its uid ,gid, uname or gname.
- * The conditions are set by following functions.
- */
-__LA_DECL int archive_match_owner_excluded(struct archive *,
- struct archive_entry *);
-/* Add inclusion uid, gid, uname and gname. */
-__LA_DECL int archive_match_include_uid(struct archive *, la_int64_t);
-__LA_DECL int archive_match_include_gid(struct archive *, la_int64_t);
-__LA_DECL int archive_match_include_uname(struct archive *, const char *);
-__LA_DECL int archive_match_include_uname_w(struct archive *,
- const wchar_t *);
-__LA_DECL int archive_match_include_gname(struct archive *, const char *);
-__LA_DECL int archive_match_include_gname_w(struct archive *,
- const wchar_t *);
-
-/* Utility functions */
-/* Convenience function to sort a NULL terminated list of strings */
-__LA_DECL int archive_utility_string_sort(char **);
-
-#ifdef __cplusplus
-}
-#endif
-
-/* These are meaningless outside of this header. */
-#undef __LA_DECL
-
-#endif /* !ARCHIVE_H_INCLUDED */
diff --git a/contrib/libs/libarchive/libarchive/archive_acl.c b/contrib/libs/libarchive/libarchive/archive_acl.c
deleted file mode 100644
index ead7e36e49..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_acl.c
+++ /dev/null
@@ -1,2097 +0,0 @@
-/*-
- * Copyright (c) 2003-2010 Tim Kientzle
- * Copyright (c) 2016 Martin Matuska
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-#ifdef HAVE_WCHAR_H
-#include <wchar.h>
-#endif
-
-#include "archive_acl_private.h"
-#include "archive_entry.h"
-#include "archive_private.h"
-
-#undef max
-#define max(a, b) ((a)>(b)?(a):(b))
-
-#ifndef HAVE_WMEMCMP
-/* Good enough for simple equality testing, but not for sorting. */
-#define wmemcmp(a,b,i) memcmp((a), (b), (i) * sizeof(wchar_t))
-#endif
-
-static int acl_special(struct archive_acl *acl,
- int type, int permset, int tag);
-static struct archive_acl_entry *acl_new_entry(struct archive_acl *acl,
- int type, int permset, int tag, int id);
-static int archive_acl_add_entry_len_l(struct archive_acl *acl,
- int type, int permset, int tag, int id, const char *name,
- size_t len, struct archive_string_conv *sc);
-static int archive_acl_text_want_type(struct archive_acl *acl, int flags);
-static ssize_t archive_acl_text_len(struct archive_acl *acl, int want_type,
- int flags, int wide, struct archive *a,
- struct archive_string_conv *sc);
-static int isint_w(const wchar_t *start, const wchar_t *end, int *result);
-static int ismode_w(const wchar_t *start, const wchar_t *end, int *result);
-static int is_nfs4_flags_w(const wchar_t *start, const wchar_t *end,
- int *result);
-static int is_nfs4_perms_w(const wchar_t *start, const wchar_t *end,
- int *result);
-static void next_field_w(const wchar_t **wp, const wchar_t **start,
- const wchar_t **end, wchar_t *sep);
-static void append_entry_w(wchar_t **wp, const wchar_t *prefix, int type,
- int tag, int flags, const wchar_t *wname, int perm, int id);
-static void append_id_w(wchar_t **wp, int id);
-static int isint(const char *start, const char *end, int *result);
-static int ismode(const char *start, const char *end, int *result);
-static int is_nfs4_flags(const char *start, const char *end,
- int *result);
-static int is_nfs4_perms(const char *start, const char *end,
- int *result);
-static void next_field(const char **p, const char **start,
- const char **end, char *sep);
-static void append_entry(char **p, const char *prefix, int type,
- int tag, int flags, const char *name, int perm, int id);
-static void append_id(char **p, int id);
-
-static const struct {
- const int perm;
- const char c;
- const wchar_t wc;
-} nfsv4_acl_perm_map[] = {
- { ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, 'r',
- L'r' },
- { ARCHIVE_ENTRY_ACL_WRITE_DATA | ARCHIVE_ENTRY_ACL_ADD_FILE, 'w',
- L'w' },
- { ARCHIVE_ENTRY_ACL_EXECUTE, 'x', L'x' },
- { ARCHIVE_ENTRY_ACL_APPEND_DATA | ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY,
- 'p', L'p' },
- { ARCHIVE_ENTRY_ACL_DELETE, 'd', L'd' },
- { ARCHIVE_ENTRY_ACL_DELETE_CHILD, 'D', L'D' },
- { ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, 'a', L'a' },
- { ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, 'A', L'A' },
- { ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, 'R', L'R' },
- { ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, 'W', L'W' },
- { ARCHIVE_ENTRY_ACL_READ_ACL, 'c', L'c' },
- { ARCHIVE_ENTRY_ACL_WRITE_ACL, 'C', L'C' },
- { ARCHIVE_ENTRY_ACL_WRITE_OWNER, 'o', L'o' },
- { ARCHIVE_ENTRY_ACL_SYNCHRONIZE, 's', L's' }
-};
-
-static const int nfsv4_acl_perm_map_size = (int)(sizeof(nfsv4_acl_perm_map) /
- sizeof(nfsv4_acl_perm_map[0]));
-
-static const struct {
- const int perm;
- const char c;
- const wchar_t wc;
-} nfsv4_acl_flag_map[] = {
- { ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, 'f', L'f' },
- { ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, 'd', L'd' },
- { ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, 'i', L'i' },
- { ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, 'n', L'n' },
- { ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, 'S', L'S' },
- { ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, 'F', L'F' },
- { ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, 'I', L'I' }
-};
-
-static const int nfsv4_acl_flag_map_size = (int)(sizeof(nfsv4_acl_flag_map) /
- sizeof(nfsv4_acl_flag_map[0]));
-
-void
-archive_acl_clear(struct archive_acl *acl)
-{
- struct archive_acl_entry *ap;
-
- while (acl->acl_head != NULL) {
- ap = acl->acl_head->next;
- archive_mstring_clean(&acl->acl_head->name);
- free(acl->acl_head);
- acl->acl_head = ap;
- }
- free(acl->acl_text_w);
- acl->acl_text_w = NULL;
- free(acl->acl_text);
- acl->acl_text = NULL;
- acl->acl_p = NULL;
- acl->acl_types = 0;
- acl->acl_state = 0; /* Not counting. */
-}
-
-void
-archive_acl_copy(struct archive_acl *dest, struct archive_acl *src)
-{
- struct archive_acl_entry *ap, *ap2;
-
- archive_acl_clear(dest);
-
- dest->mode = src->mode;
- ap = src->acl_head;
- while (ap != NULL) {
- ap2 = acl_new_entry(dest,
- ap->type, ap->permset, ap->tag, ap->id);
- if (ap2 != NULL)
- archive_mstring_copy(&ap2->name, &ap->name);
- ap = ap->next;
- }
-}
-
-int
-archive_acl_add_entry(struct archive_acl *acl,
- int type, int permset, int tag, int id, const char *name)
-{
- struct archive_acl_entry *ap;
-
- if (acl_special(acl, type, permset, tag) == 0)
- return ARCHIVE_OK;
- ap = acl_new_entry(acl, type, permset, tag, id);
- if (ap == NULL) {
- /* XXX Error XXX */
- return ARCHIVE_FAILED;
- }
- if (name != NULL && *name != '\0')
- archive_mstring_copy_mbs(&ap->name, name);
- else
- archive_mstring_clean(&ap->name);
- return ARCHIVE_OK;
-}
-
-int
-archive_acl_add_entry_w_len(struct archive_acl *acl,
- int type, int permset, int tag, int id, const wchar_t *name, size_t len)
-{
- struct archive_acl_entry *ap;
-
- if (acl_special(acl, type, permset, tag) == 0)
- return ARCHIVE_OK;
- ap = acl_new_entry(acl, type, permset, tag, id);
- if (ap == NULL) {
- /* XXX Error XXX */
- return ARCHIVE_FAILED;
- }
- if (name != NULL && *name != L'\0' && len > 0)
- archive_mstring_copy_wcs_len(&ap->name, name, len);
- else
- archive_mstring_clean(&ap->name);
- return ARCHIVE_OK;
-}
-
-static int
-archive_acl_add_entry_len_l(struct archive_acl *acl,
- int type, int permset, int tag, int id, const char *name, size_t len,
- struct archive_string_conv *sc)
-{
- struct archive_acl_entry *ap;
- int r;
-
- if (acl_special(acl, type, permset, tag) == 0)
- return ARCHIVE_OK;
- ap = acl_new_entry(acl, type, permset, tag, id);
- if (ap == NULL) {
- /* XXX Error XXX */
- return ARCHIVE_FAILED;
- }
- if (name != NULL && *name != '\0' && len > 0) {
- r = archive_mstring_copy_mbs_len_l(&ap->name, name, len, sc);
- } else {
- r = 0;
- archive_mstring_clean(&ap->name);
- }
- if (r == 0)
- return (ARCHIVE_OK);
- else if (errno == ENOMEM)
- return (ARCHIVE_FATAL);
- else
- return (ARCHIVE_WARN);
-}
-
-/*
- * If this ACL entry is part of the standard POSIX permissions set,
- * store the permissions in the stat structure and return zero.
- */
-static int
-acl_special(struct archive_acl *acl, int type, int permset, int tag)
-{
- if (type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS
- && ((permset & ~007) == 0)) {
- switch (tag) {
- case ARCHIVE_ENTRY_ACL_USER_OBJ:
- acl->mode &= ~0700;
- acl->mode |= (permset & 7) << 6;
- return (0);
- case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
- acl->mode &= ~0070;
- acl->mode |= (permset & 7) << 3;
- return (0);
- case ARCHIVE_ENTRY_ACL_OTHER:
- acl->mode &= ~0007;
- acl->mode |= permset & 7;
- return (0);
- }
- }
- return (1);
-}
-
-/*
- * Allocate and populate a new ACL entry with everything but the
- * name.
- */
-static struct archive_acl_entry *
-acl_new_entry(struct archive_acl *acl,
- int type, int permset, int tag, int id)
-{
- struct archive_acl_entry *ap, *aq;
-
- /* Type argument must be a valid NFS4 or POSIX.1e type.
- * The type must agree with anything already set and
- * the permset must be compatible. */
- if (type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
- if (acl->acl_types & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
- return (NULL);
- }
- if (permset &
- ~(ARCHIVE_ENTRY_ACL_PERMS_NFS4
- | ARCHIVE_ENTRY_ACL_INHERITANCE_NFS4)) {
- return (NULL);
- }
- } else if (type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) {
- if (acl->acl_types & ~ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) {
- return (NULL);
- }
- if (permset & ~ARCHIVE_ENTRY_ACL_PERMS_POSIX1E) {
- return (NULL);
- }
- } else {
- return (NULL);
- }
-
- /* Verify the tag is valid and compatible with NFS4 or POSIX.1e. */
- switch (tag) {
- case ARCHIVE_ENTRY_ACL_USER:
- case ARCHIVE_ENTRY_ACL_USER_OBJ:
- case ARCHIVE_ENTRY_ACL_GROUP:
- case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
- /* Tags valid in both NFS4 and POSIX.1e */
- break;
- case ARCHIVE_ENTRY_ACL_MASK:
- case ARCHIVE_ENTRY_ACL_OTHER:
- /* Tags valid only in POSIX.1e. */
- if (type & ~ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) {
- return (NULL);
- }
- break;
- case ARCHIVE_ENTRY_ACL_EVERYONE:
- /* Tags valid only in NFS4. */
- if (type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
- return (NULL);
- }
- break;
- default:
- /* No other values are valid. */
- return (NULL);
- }
-
- free(acl->acl_text_w);
- acl->acl_text_w = NULL;
- free(acl->acl_text);
- acl->acl_text = NULL;
-
- /*
- * If there's a matching entry already in the list, overwrite it.
- * NFSv4 entries may be repeated and are not overwritten.
- *
- * TODO: compare names of no id is provided (needs more rework)
- */
- ap = acl->acl_head;
- aq = NULL;
- while (ap != NULL) {
- if (((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) == 0) &&
- ap->type == type && ap->tag == tag && ap->id == id) {
- if (id != -1 || (tag != ARCHIVE_ENTRY_ACL_USER &&
- tag != ARCHIVE_ENTRY_ACL_GROUP)) {
- ap->permset = permset;
- return (ap);
- }
- }
- aq = ap;
- ap = ap->next;
- }
-
- /* Add a new entry to the end of the list. */
- ap = (struct archive_acl_entry *)calloc(1, sizeof(*ap));
- if (ap == NULL)
- return (NULL);
- if (aq == NULL)
- acl->acl_head = ap;
- else
- aq->next = ap;
- ap->type = type;
- ap->tag = tag;
- ap->id = id;
- ap->permset = permset;
- acl->acl_types |= type;
- return (ap);
-}
-
-/*
- * Return a count of entries matching "want_type".
- */
-int
-archive_acl_count(struct archive_acl *acl, int want_type)
-{
- int count;
- struct archive_acl_entry *ap;
-
- count = 0;
- ap = acl->acl_head;
- while (ap != NULL) {
- if ((ap->type & want_type) != 0)
- count++;
- ap = ap->next;
- }
-
- if (count > 0 && ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0))
- count += 3;
- return (count);
-}
-
-/*
- * Return a bitmask of stored ACL types in an ACL list
- */
-int
-archive_acl_types(struct archive_acl *acl)
-{
- return (acl->acl_types);
-}
-
-/*
- * Prepare for reading entries from the ACL data. Returns a count
- * of entries matching "want_type", or zero if there are no
- * non-extended ACL entries of that type.
- */
-int
-archive_acl_reset(struct archive_acl *acl, int want_type)
-{
- int count, cutoff;
-
- count = archive_acl_count(acl, want_type);
-
- /*
- * If the only entries are the three standard ones,
- * then don't return any ACL data. (In this case,
- * client can just use chmod(2) to set permissions.)
- */
- if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0)
- cutoff = 3;
- else
- cutoff = 0;
-
- if (count > cutoff)
- acl->acl_state = ARCHIVE_ENTRY_ACL_USER_OBJ;
- else
- acl->acl_state = 0;
- acl->acl_p = acl->acl_head;
- return (count);
-}
-
-
-/*
- * Return the next ACL entry in the list. Fake entries for the
- * standard permissions and include them in the returned list.
- */
-int
-archive_acl_next(struct archive *a, struct archive_acl *acl, int want_type,
- int *type, int *permset, int *tag, int *id, const char **name)
-{
- *name = NULL;
- *id = -1;
-
- /*
- * The acl_state is either zero (no entries available), -1
- * (reading from list), or an entry type (retrieve that type
- * from ae_stat.aest_mode).
- */
- if (acl->acl_state == 0)
- return (ARCHIVE_WARN);
-
- /* The first three access entries are special. */
- if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
- switch (acl->acl_state) {
- case ARCHIVE_ENTRY_ACL_USER_OBJ:
- *permset = (acl->mode >> 6) & 7;
- *type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
- *tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
- acl->acl_state = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
- return (ARCHIVE_OK);
- case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
- *permset = (acl->mode >> 3) & 7;
- *type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
- *tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
- acl->acl_state = ARCHIVE_ENTRY_ACL_OTHER;
- return (ARCHIVE_OK);
- case ARCHIVE_ENTRY_ACL_OTHER:
- *permset = acl->mode & 7;
- *type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
- *tag = ARCHIVE_ENTRY_ACL_OTHER;
- acl->acl_state = -1;
- acl->acl_p = acl->acl_head;
- return (ARCHIVE_OK);
- default:
- break;
- }
- }
-
- while (acl->acl_p != NULL && (acl->acl_p->type & want_type) == 0)
- acl->acl_p = acl->acl_p->next;
- if (acl->acl_p == NULL) {
- acl->acl_state = 0;
- *type = 0;
- *permset = 0;
- *tag = 0;
- *id = -1;
- *name = NULL;
- return (ARCHIVE_EOF); /* End of ACL entries. */
- }
- *type = acl->acl_p->type;
- *permset = acl->acl_p->permset;
- *tag = acl->acl_p->tag;
- *id = acl->acl_p->id;
- if (archive_mstring_get_mbs(a, &acl->acl_p->name, name) != 0) {
- if (errno == ENOMEM)
- return (ARCHIVE_FATAL);
- *name = NULL;
- }
- acl->acl_p = acl->acl_p->next;
- return (ARCHIVE_OK);
-}
-
-/*
- * Determine what type of ACL do we want
- */
-static int
-archive_acl_text_want_type(struct archive_acl *acl, int flags)
-{
- int want_type;
-
- /* Check if ACL is NFSv4 */
- if ((acl->acl_types & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
- /* NFSv4 should never mix with POSIX.1e */
- if ((acl->acl_types & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0)
- return (0);
- else
- return (ARCHIVE_ENTRY_ACL_TYPE_NFS4);
- }
-
- /* Now deal with POSIX.1e ACLs */
-
- want_type = 0;
- if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0)
- want_type |= ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
- if ((flags & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
- want_type |= ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
-
- /* By default we want both access and default ACLs */
- if (want_type == 0)
- return (ARCHIVE_ENTRY_ACL_TYPE_POSIX1E);
-
- return (want_type);
-}
-
-/*
- * Calculate ACL text string length
- */
-static ssize_t
-archive_acl_text_len(struct archive_acl *acl, int want_type, int flags,
- int wide, struct archive *a, struct archive_string_conv *sc) {
- struct archive_acl_entry *ap;
- const char *name;
- const wchar_t *wname;
- int count, idlen, tmp, r;
- ssize_t length;
- size_t len;
-
- count = 0;
- length = 0;
- for (ap = acl->acl_head; ap != NULL; ap = ap->next) {
- if ((ap->type & want_type) == 0)
- continue;
- /*
- * Filemode-mapping ACL entries are stored exclusively in
- * ap->mode so they should not be in the list
- */
- if ((ap->type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS)
- && (ap->tag == ARCHIVE_ENTRY_ACL_USER_OBJ
- || ap->tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ
- || ap->tag == ARCHIVE_ENTRY_ACL_OTHER))
- continue;
- count++;
- if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0
- && (ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
- length += 8; /* "default:" */
- switch (ap->tag) {
- case ARCHIVE_ENTRY_ACL_USER_OBJ:
- if (want_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
- length += 6; /* "owner@" */
- break;
- }
- /* FALLTHROUGH */
- case ARCHIVE_ENTRY_ACL_USER:
- case ARCHIVE_ENTRY_ACL_MASK:
- length += 4; /* "user", "mask" */
- break;
- case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
- if (want_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
- length += 6; /* "group@" */
- break;
- }
- /* FALLTHROUGH */
- case ARCHIVE_ENTRY_ACL_GROUP:
- case ARCHIVE_ENTRY_ACL_OTHER:
- length += 5; /* "group", "other" */
- break;
- case ARCHIVE_ENTRY_ACL_EVERYONE:
- length += 9; /* "everyone@" */
- break;
- }
- length += 1; /* colon after tag */
- if (ap->tag == ARCHIVE_ENTRY_ACL_USER ||
- ap->tag == ARCHIVE_ENTRY_ACL_GROUP) {
- if (wide) {
- r = archive_mstring_get_wcs(a, &ap->name,
- &wname);
- if (r == 0 && wname != NULL)
- length += wcslen(wname);
- else if (r < 0 && errno == ENOMEM)
- return (0);
- else
- length += sizeof(uid_t) * 3 + 1;
- } else {
- r = archive_mstring_get_mbs_l(a, &ap->name, &name,
- &len, sc);
- if (r != 0)
- return (0);
- if (len > 0 && name != NULL)
- length += len;
- else
- length += sizeof(uid_t) * 3 + 1;
- }
- length += 1; /* colon after user or group name */
- } else if (want_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4)
- length += 1; /* 2nd colon empty user,group or other */
-
- if (((flags & ARCHIVE_ENTRY_ACL_STYLE_SOLARIS) != 0)
- && ((want_type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0)
- && (ap->tag == ARCHIVE_ENTRY_ACL_OTHER
- || ap->tag == ARCHIVE_ENTRY_ACL_MASK)) {
- /* Solaris has no colon after other: and mask: */
- length = length - 1;
- }
-
- if (want_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
- /* rwxpdDaARWcCos:fdinSFI:deny */
- length += 27;
- if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_DENY) == 0)
- length += 1; /* allow, alarm, audit */
- } else
- length += 3; /* rwx */
-
- if ((ap->tag == ARCHIVE_ENTRY_ACL_USER ||
- ap->tag == ARCHIVE_ENTRY_ACL_GROUP) &&
- (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID) != 0) {
- length += 1; /* colon */
- /* ID digit count */
- idlen = 1;
- tmp = ap->id;
- while (tmp > 9) {
- tmp = tmp / 10;
- idlen++;
- }
- length += idlen;
- }
- length ++; /* entry separator */
- }
-
- /* Add filemode-mapping access entries to the length */
- if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
- if ((flags & ARCHIVE_ENTRY_ACL_STYLE_SOLARIS) != 0) {
- /* "user::rwx\ngroup::rwx\nother:rwx\n" */
- length += 31;
- } else {
- /* "user::rwx\ngroup::rwx\nother::rwx\n" */
- length += 32;
- }
- } else if (count == 0)
- return (0);
-
- /* The terminating character is included in count */
- return (length);
-}
-
-/*
- * Generate a wide text version of the ACL. The flags parameter controls
- * the type and style of the generated ACL.
- */
-wchar_t *
-archive_acl_to_text_w(struct archive_acl *acl, ssize_t *text_len, int flags,
- struct archive *a)
-{
- int count;
- ssize_t length;
- size_t len;
- const wchar_t *wname;
- const wchar_t *prefix;
- wchar_t separator;
- struct archive_acl_entry *ap;
- int id, r, want_type;
- wchar_t *wp, *ws;
-
- want_type = archive_acl_text_want_type(acl, flags);
-
- /* Both NFSv4 and POSIX.1 types found */
- if (want_type == 0)
- return (NULL);
-
- if (want_type == ARCHIVE_ENTRY_ACL_TYPE_POSIX1E)
- flags |= ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT;
-
- length = archive_acl_text_len(acl, want_type, flags, 1, a, NULL);
-
- if (length == 0)
- return (NULL);
-
- if (flags & ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA)
- separator = L',';
- else
- separator = L'\n';
-
- /* Now, allocate the string and actually populate it. */
- wp = ws = (wchar_t *)malloc(length * sizeof(wchar_t));
- if (wp == NULL) {
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (NULL);
- }
- count = 0;
-
- if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
- append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
- ARCHIVE_ENTRY_ACL_USER_OBJ, flags, NULL,
- acl->mode & 0700, -1);
- *wp++ = separator;
- append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
- ARCHIVE_ENTRY_ACL_GROUP_OBJ, flags, NULL,
- acl->mode & 0070, -1);
- *wp++ = separator;
- append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
- ARCHIVE_ENTRY_ACL_OTHER, flags, NULL,
- acl->mode & 0007, -1);
- count += 3;
- }
-
- for (ap = acl->acl_head; ap != NULL; ap = ap->next) {
- if ((ap->type & want_type) == 0)
- continue;
- /*
- * Filemode-mapping ACL entries are stored exclusively in
- * ap->mode so they should not be in the list
- */
- if ((ap->type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS)
- && (ap->tag == ARCHIVE_ENTRY_ACL_USER_OBJ
- || ap->tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ
- || ap->tag == ARCHIVE_ENTRY_ACL_OTHER))
- continue;
- if (ap->type == ARCHIVE_ENTRY_ACL_TYPE_DEFAULT &&
- (flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) != 0)
- prefix = L"default:";
- else
- prefix = NULL;
- r = archive_mstring_get_wcs(a, &ap->name, &wname);
- if (r == 0) {
- if (count > 0)
- *wp++ = separator;
- if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
- id = ap->id;
- else
- id = -1;
- append_entry_w(&wp, prefix, ap->type, ap->tag, flags,
- wname, ap->permset, id);
- count++;
- } else if (r < 0 && errno == ENOMEM) {
- free(ws);
- return (NULL);
- }
- }
-
- /* Add terminating character */
- *wp++ = L'\0';
-
- len = wcslen(ws);
-
- if ((ssize_t)len > (length - 1))
- __archive_errx(1, "Buffer overrun");
-
- if (text_len != NULL)
- *text_len = len;
-
- return (ws);
-}
-
-static void
-append_id_w(wchar_t **wp, int id)
-{
- if (id < 0)
- id = 0;
- if (id > 9)
- append_id_w(wp, id / 10);
- *(*wp)++ = L"0123456789"[id % 10];
-}
-
-static void
-append_entry_w(wchar_t **wp, const wchar_t *prefix, int type,
- int tag, int flags, const wchar_t *wname, int perm, int id)
-{
- int i;
-
- if (prefix != NULL) {
- wcscpy(*wp, prefix);
- *wp += wcslen(*wp);
- }
- switch (tag) {
- case ARCHIVE_ENTRY_ACL_USER_OBJ:
- wname = NULL;
- id = -1;
- if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
- wcscpy(*wp, L"owner@");
- break;
- }
- /* FALLTHROUGH */
- case ARCHIVE_ENTRY_ACL_USER:
- wcscpy(*wp, L"user");
- break;
- case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
- wname = NULL;
- id = -1;
- if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
- wcscpy(*wp, L"group@");
- break;
- }
- /* FALLTHROUGH */
- case ARCHIVE_ENTRY_ACL_GROUP:
- wcscpy(*wp, L"group");
- break;
- case ARCHIVE_ENTRY_ACL_MASK:
- wcscpy(*wp, L"mask");
- wname = NULL;
- id = -1;
- break;
- case ARCHIVE_ENTRY_ACL_OTHER:
- wcscpy(*wp, L"other");
- wname = NULL;
- id = -1;
- break;
- case ARCHIVE_ENTRY_ACL_EVERYONE:
- wcscpy(*wp, L"everyone@");
- wname = NULL;
- id = -1;
- break;
- }
- *wp += wcslen(*wp);
- *(*wp)++ = L':';
- if (((type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) ||
- tag == ARCHIVE_ENTRY_ACL_USER ||
- tag == ARCHIVE_ENTRY_ACL_GROUP) {
- if (wname != NULL) {
- wcscpy(*wp, wname);
- *wp += wcslen(*wp);
- } else if (tag == ARCHIVE_ENTRY_ACL_USER
- || tag == ARCHIVE_ENTRY_ACL_GROUP) {
- append_id_w(wp, id);
- if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) == 0)
- id = -1;
- }
- /* Solaris style has no second colon after other and mask */
- if (((flags & ARCHIVE_ENTRY_ACL_STYLE_SOLARIS) == 0)
- || (tag != ARCHIVE_ENTRY_ACL_OTHER
- && tag != ARCHIVE_ENTRY_ACL_MASK))
- *(*wp)++ = L':';
- }
- if ((type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
- /* POSIX.1e ACL perms */
- *(*wp)++ = (perm & 0444) ? L'r' : L'-';
- *(*wp)++ = (perm & 0222) ? L'w' : L'-';
- *(*wp)++ = (perm & 0111) ? L'x' : L'-';
- } else {
- /* NFSv4 ACL perms */
- for (i = 0; i < nfsv4_acl_perm_map_size; i++) {
- if (perm & nfsv4_acl_perm_map[i].perm)
- *(*wp)++ = nfsv4_acl_perm_map[i].wc;
- else if ((flags & ARCHIVE_ENTRY_ACL_STYLE_COMPACT) == 0)
- *(*wp)++ = L'-';
- }
- *(*wp)++ = L':';
- for (i = 0; i < nfsv4_acl_flag_map_size; i++) {
- if (perm & nfsv4_acl_flag_map[i].perm)
- *(*wp)++ = nfsv4_acl_flag_map[i].wc;
- else if ((flags & ARCHIVE_ENTRY_ACL_STYLE_COMPACT) == 0)
- *(*wp)++ = L'-';
- }
- *(*wp)++ = L':';
- switch (type) {
- case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
- wcscpy(*wp, L"allow");
- break;
- case ARCHIVE_ENTRY_ACL_TYPE_DENY:
- wcscpy(*wp, L"deny");
- break;
- case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
- wcscpy(*wp, L"audit");
- break;
- case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
- wcscpy(*wp, L"alarm");
- break;
- default:
- break;
- }
- *wp += wcslen(*wp);
- }
- if (id != -1) {
- *(*wp)++ = L':';
- append_id_w(wp, id);
- }
-}
-
-/*
- * Generate a text version of the ACL. The flags parameter controls
- * the type and style of the generated ACL.
- */
-char *
-archive_acl_to_text_l(struct archive_acl *acl, ssize_t *text_len, int flags,
- struct archive_string_conv *sc)
-{
- int count;
- ssize_t length;
- size_t len;
- const char *name;
- const char *prefix;
- char separator;
- struct archive_acl_entry *ap;
- int id, r, want_type;
- char *p, *s;
-
- want_type = archive_acl_text_want_type(acl, flags);
-
- /* Both NFSv4 and POSIX.1 types found */
- if (want_type == 0)
- return (NULL);
-
- if (want_type == ARCHIVE_ENTRY_ACL_TYPE_POSIX1E)
- flags |= ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT;
-
- length = archive_acl_text_len(acl, want_type, flags, 0, NULL, sc);
-
- if (length == 0)
- return (NULL);
-
- if (flags & ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA)
- separator = ',';
- else
- separator = '\n';
-
- /* Now, allocate the string and actually populate it. */
- p = s = (char *)malloc(length * sizeof(char));
- if (p == NULL) {
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (NULL);
- }
- count = 0;
-
- if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
- append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
- ARCHIVE_ENTRY_ACL_USER_OBJ, flags, NULL,
- acl->mode & 0700, -1);
- *p++ = separator;
- append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
- ARCHIVE_ENTRY_ACL_GROUP_OBJ, flags, NULL,
- acl->mode & 0070, -1);
- *p++ = separator;
- append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
- ARCHIVE_ENTRY_ACL_OTHER, flags, NULL,
- acl->mode & 0007, -1);
- count += 3;
- }
-
- for (ap = acl->acl_head; ap != NULL; ap = ap->next) {
- if ((ap->type & want_type) == 0)
- continue;
- /*
- * Filemode-mapping ACL entries are stored exclusively in
- * ap->mode so they should not be in the list
- */
- if ((ap->type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS)
- && (ap->tag == ARCHIVE_ENTRY_ACL_USER_OBJ
- || ap->tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ
- || ap->tag == ARCHIVE_ENTRY_ACL_OTHER))
- continue;
- if (ap->type == ARCHIVE_ENTRY_ACL_TYPE_DEFAULT &&
- (flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) != 0)
- prefix = "default:";
- else
- prefix = NULL;
- r = archive_mstring_get_mbs_l(
- NULL, &ap->name, &name, &len, sc);
- if (r != 0) {
- free(s);
- return (NULL);
- }
- if (count > 0)
- *p++ = separator;
- if (name == NULL ||
- (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)) {
- id = ap->id;
- } else {
- id = -1;
- }
- append_entry(&p, prefix, ap->type, ap->tag, flags, name,
- ap->permset, id);
- count++;
- }
-
- /* Add terminating character */
- *p++ = '\0';
-
- len = strlen(s);
-
- if ((ssize_t)len > (length - 1))
- __archive_errx(1, "Buffer overrun");
-
- if (text_len != NULL)
- *text_len = len;
-
- return (s);
-}
-
-static void
-append_id(char **p, int id)
-{
- if (id < 0)
- id = 0;
- if (id > 9)
- append_id(p, id / 10);
- *(*p)++ = "0123456789"[id % 10];
-}
-
-static void
-append_entry(char **p, const char *prefix, int type,
- int tag, int flags, const char *name, int perm, int id)
-{
- int i;
-
- if (prefix != NULL) {
- strcpy(*p, prefix);
- *p += strlen(*p);
- }
- switch (tag) {
- case ARCHIVE_ENTRY_ACL_USER_OBJ:
- name = NULL;
- id = -1;
- if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
- strcpy(*p, "owner@");
- break;
- }
- /* FALLTHROUGH */
- case ARCHIVE_ENTRY_ACL_USER:
- strcpy(*p, "user");
- break;
- case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
- name = NULL;
- id = -1;
- if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
- strcpy(*p, "group@");
- break;
- }
- /* FALLTHROUGH */
- case ARCHIVE_ENTRY_ACL_GROUP:
- strcpy(*p, "group");
- break;
- case ARCHIVE_ENTRY_ACL_MASK:
- strcpy(*p, "mask");
- name = NULL;
- id = -1;
- break;
- case ARCHIVE_ENTRY_ACL_OTHER:
- strcpy(*p, "other");
- name = NULL;
- id = -1;
- break;
- case ARCHIVE_ENTRY_ACL_EVERYONE:
- strcpy(*p, "everyone@");
- name = NULL;
- id = -1;
- break;
- }
- *p += strlen(*p);
- *(*p)++ = ':';
- if (((type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) ||
- tag == ARCHIVE_ENTRY_ACL_USER ||
- tag == ARCHIVE_ENTRY_ACL_GROUP) {
- if (name != NULL) {
- strcpy(*p, name);
- *p += strlen(*p);
- } else if (tag == ARCHIVE_ENTRY_ACL_USER
- || tag == ARCHIVE_ENTRY_ACL_GROUP) {
- append_id(p, id);
- if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) == 0)
- id = -1;
- }
- /* Solaris style has no second colon after other and mask */
- if (((flags & ARCHIVE_ENTRY_ACL_STYLE_SOLARIS) == 0)
- || (tag != ARCHIVE_ENTRY_ACL_OTHER
- && tag != ARCHIVE_ENTRY_ACL_MASK))
- *(*p)++ = ':';
- }
- if ((type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
- /* POSIX.1e ACL perms */
- *(*p)++ = (perm & 0444) ? 'r' : '-';
- *(*p)++ = (perm & 0222) ? 'w' : '-';
- *(*p)++ = (perm & 0111) ? 'x' : '-';
- } else {
- /* NFSv4 ACL perms */
- for (i = 0; i < nfsv4_acl_perm_map_size; i++) {
- if (perm & nfsv4_acl_perm_map[i].perm)
- *(*p)++ = nfsv4_acl_perm_map[i].c;
- else if ((flags & ARCHIVE_ENTRY_ACL_STYLE_COMPACT) == 0)
- *(*p)++ = '-';
- }
- *(*p)++ = ':';
- for (i = 0; i < nfsv4_acl_flag_map_size; i++) {
- if (perm & nfsv4_acl_flag_map[i].perm)
- *(*p)++ = nfsv4_acl_flag_map[i].c;
- else if ((flags & ARCHIVE_ENTRY_ACL_STYLE_COMPACT) == 0)
- *(*p)++ = '-';
- }
- *(*p)++ = ':';
- switch (type) {
- case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
- strcpy(*p, "allow");
- break;
- case ARCHIVE_ENTRY_ACL_TYPE_DENY:
- strcpy(*p, "deny");
- break;
- case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
- strcpy(*p, "audit");
- break;
- case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
- strcpy(*p, "alarm");
- break;
- }
- *p += strlen(*p);
- }
- if (id != -1) {
- *(*p)++ = ':';
- append_id(p, id);
- }
-}
-
-/*
- * Parse a wide ACL text string.
- *
- * The want_type argument may be one of the following:
- * ARCHIVE_ENTRY_ACL_TYPE_ACCESS - text is a POSIX.1e ACL of type ACCESS
- * ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - text is a POSIX.1e ACL of type DEFAULT
- * ARCHIVE_ENTRY_ACL_TYPE_NFS4 - text is as a NFSv4 ACL
- *
- * POSIX.1e ACL entries prefixed with "default:" are treated as
- * ARCHIVE_ENTRY_ACL_TYPE_DEFAULT unless type is ARCHIVE_ENTRY_ACL_TYPE_NFS4
- */
-int
-archive_acl_from_text_w(struct archive_acl *acl, const wchar_t *text,
- int want_type)
-{
- struct {
- const wchar_t *start;
- const wchar_t *end;
- } field[6], name;
-
- const wchar_t *s, *st;
-
- int numfields, fields, n, r, sol, ret;
- int type, types, tag, permset, id;
- size_t len;
- wchar_t sep;
-
- ret = ARCHIVE_OK;
- types = 0;
-
- switch (want_type) {
- case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E:
- want_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
- __LA_FALLTHROUGH;
- case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
- case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
- numfields = 5;
- break;
- case ARCHIVE_ENTRY_ACL_TYPE_NFS4:
- numfields = 6;
- break;
- default:
- return (ARCHIVE_FATAL);
- }
-
- while (text != NULL && *text != L'\0') {
- /*
- * Parse the fields out of the next entry,
- * advance 'text' to start of next entry.
- */
- fields = 0;
- do {
- const wchar_t *start, *end;
- next_field_w(&text, &start, &end, &sep);
- if (fields < numfields) {
- field[fields].start = start;
- field[fields].end = end;
- }
- ++fields;
- } while (sep == L':');
-
- /* Set remaining fields to blank. */
- for (n = fields; n < numfields; ++n)
- field[n].start = field[n].end = NULL;
-
- if (field[0].start != NULL && *(field[0].start) == L'#') {
- /* Comment, skip entry */
- continue;
- }
-
- n = 0;
- sol = 0;
- id = -1;
- permset = 0;
- name.start = name.end = NULL;
-
- if (want_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
- /* POSIX.1e ACLs */
- /*
- * Default keyword "default:user::rwx"
- * if found, we have one more field
- *
- * We also support old Solaris extension:
- * "defaultuser::rwx" is the default ACL corresponding
- * to "user::rwx", etc. valid only for first field
- */
- s = field[0].start;
- len = field[0].end - field[0].start;
- if (*s == L'd' && (len == 1 || (len >= 7
- && wmemcmp((s + 1), L"efault", 6) == 0))) {
- type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
- if (len > 7)
- field[0].start += 7;
- else
- n = 1;
- } else
- type = want_type;
-
- /* Check for a numeric ID in field n+1 or n+3. */
- isint_w(field[n + 1].start, field[n + 1].end, &id);
- /* Field n+3 is optional. */
- if (id == -1 && fields > n+3)
- isint_w(field[n + 3].start, field[n + 3].end,
- &id);
-
- tag = 0;
- s = field[n].start;
- st = field[n].start + 1;
- len = field[n].end - field[n].start;
-
- switch (*s) {
- case L'u':
- if (len == 1 || (len == 4
- && wmemcmp(st, L"ser", 3) == 0))
- tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
- break;
- case L'g':
- if (len == 1 || (len == 5
- && wmemcmp(st, L"roup", 4) == 0))
- tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
- break;
- case L'o':
- if (len == 1 || (len == 5
- && wmemcmp(st, L"ther", 4) == 0))
- tag = ARCHIVE_ENTRY_ACL_OTHER;
- break;
- case L'm':
- if (len == 1 || (len == 4
- && wmemcmp(st, L"ask", 3) == 0))
- tag = ARCHIVE_ENTRY_ACL_MASK;
- break;
- default:
- break;
- }
-
- switch (tag) {
- case ARCHIVE_ENTRY_ACL_OTHER:
- case ARCHIVE_ENTRY_ACL_MASK:
- if (fields == (n + 2)
- && field[n + 1].start < field[n + 1].end
- && ismode_w(field[n + 1].start,
- field[n + 1].end, &permset)) {
- /* This is Solaris-style "other:rwx" */
- sol = 1;
- } else if (fields == (n + 3) &&
- field[n + 1].start < field[n + 1].end) {
- /* Invalid mask or other field */
- ret = ARCHIVE_WARN;
- continue;
- }
- break;
- case ARCHIVE_ENTRY_ACL_USER_OBJ:
- case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
- if (id != -1 ||
- field[n + 1].start < field[n + 1].end) {
- name = field[n + 1];
- if (tag == ARCHIVE_ENTRY_ACL_USER_OBJ)
- tag = ARCHIVE_ENTRY_ACL_USER;
- else
- tag = ARCHIVE_ENTRY_ACL_GROUP;
- }
- break;
- default:
- /* Invalid tag, skip entry */
- ret = ARCHIVE_WARN;
- continue;
- }
-
- /*
- * Without "default:" we expect mode in field 2
- * Exception: Solaris other and mask fields
- */
- if (permset == 0 && !ismode_w(field[n + 2 - sol].start,
- field[n + 2 - sol].end, &permset)) {
- /* Invalid mode, skip entry */
- ret = ARCHIVE_WARN;
- continue;
- }
- } else {
- /* NFS4 ACLs */
- s = field[0].start;
- len = field[0].end - field[0].start;
- tag = 0;
-
- switch (len) {
- case 4:
- if (wmemcmp(s, L"user", 4) == 0)
- tag = ARCHIVE_ENTRY_ACL_USER;
- break;
- case 5:
- if (wmemcmp(s, L"group", 5) == 0)
- tag = ARCHIVE_ENTRY_ACL_GROUP;
- break;
- case 6:
- if (wmemcmp(s, L"owner@", 6) == 0)
- tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
- else if (wmemcmp(s, L"group@", len) == 0)
- tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
- break;
- case 9:
- if (wmemcmp(s, L"everyone@", 9) == 0)
- tag = ARCHIVE_ENTRY_ACL_EVERYONE;
- default:
- break;
- }
-
- if (tag == 0) {
- /* Invalid tag, skip entry */
- ret = ARCHIVE_WARN;
- continue;
- } else if (tag == ARCHIVE_ENTRY_ACL_USER ||
- tag == ARCHIVE_ENTRY_ACL_GROUP) {
- n = 1;
- name = field[1];
- isint_w(name.start, name.end, &id);
- } else
- n = 0;
-
- if (!is_nfs4_perms_w(field[1 + n].start,
- field[1 + n].end, &permset)) {
- /* Invalid NFSv4 perms, skip entry */
- ret = ARCHIVE_WARN;
- continue;
- }
- if (!is_nfs4_flags_w(field[2 + n].start,
- field[2 + n].end, &permset)) {
- /* Invalid NFSv4 flags, skip entry */
- ret = ARCHIVE_WARN;
- continue;
- }
- s = field[3 + n].start;
- len = field[3 + n].end - field[3 + n].start;
- type = 0;
- if (len == 4) {
- if (wmemcmp(s, L"deny", 4) == 0)
- type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
- } else if (len == 5) {
- if (wmemcmp(s, L"allow", 5) == 0)
- type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
- else if (wmemcmp(s, L"audit", 5) == 0)
- type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT;
- else if (wmemcmp(s, L"alarm", 5) == 0)
- type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
- }
- if (type == 0) {
- /* Invalid entry type, skip entry */
- ret = ARCHIVE_WARN;
- continue;
- }
- isint_w(field[4 + n].start, field[4 + n].end, &id);
- }
-
- /* Add entry to the internal list. */
- r = archive_acl_add_entry_w_len(acl, type, permset,
- tag, id, name.start, name.end - name.start);
- if (r < ARCHIVE_WARN)
- return (r);
- if (r != ARCHIVE_OK)
- ret = ARCHIVE_WARN;
- types |= type;
- }
-
- /* Reset ACL */
- archive_acl_reset(acl, types);
-
- return (ret);
-}
-
-/*
- * Parse a string to a positive decimal integer. Returns true if
- * the string is non-empty and consists only of decimal digits,
- * false otherwise.
- */
-static int
-isint_w(const wchar_t *start, const wchar_t *end, int *result)
-{
- int n = 0;
- if (start >= end)
- return (0);
- while (start < end) {
- if (*start < L'0' || *start > L'9')
- return (0);
- if (n > (INT_MAX / 10) ||
- (n == INT_MAX / 10 && (*start - L'0') > INT_MAX % 10)) {
- n = INT_MAX;
- } else {
- n *= 10;
- n += *start - L'0';
- }
- start++;
- }
- *result = n;
- return (1);
-}
-
-/*
- * Parse a string as a mode field. Returns true if
- * the string is non-empty and consists only of mode characters,
- * false otherwise.
- */
-static int
-ismode_w(const wchar_t *start, const wchar_t *end, int *permset)
-{
- const wchar_t *p;
-
- if (start >= end)
- return (0);
- p = start;
- *permset = 0;
- while (p < end) {
- switch (*p++) {
- case L'r': case L'R':
- *permset |= ARCHIVE_ENTRY_ACL_READ;
- break;
- case L'w': case L'W':
- *permset |= ARCHIVE_ENTRY_ACL_WRITE;
- break;
- case L'x': case L'X':
- *permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
- break;
- case L'-':
- break;
- default:
- return (0);
- }
- }
- return (1);
-}
-
-/*
- * Parse a string as a NFS4 ACL permission field.
- * Returns true if the string is non-empty and consists only of NFS4 ACL
- * permission characters, false otherwise
- */
-static int
-is_nfs4_perms_w(const wchar_t *start, const wchar_t *end, int *permset)
-{
- const wchar_t *p = start;
-
- while (p < end) {
- switch (*p++) {
- case L'r':
- *permset |= ARCHIVE_ENTRY_ACL_READ_DATA;
- break;
- case L'w':
- *permset |= ARCHIVE_ENTRY_ACL_WRITE_DATA;
- break;
- case L'x':
- *permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
- break;
- case L'p':
- *permset |= ARCHIVE_ENTRY_ACL_APPEND_DATA;
- break;
- case L'D':
- *permset |= ARCHIVE_ENTRY_ACL_DELETE_CHILD;
- break;
- case L'd':
- *permset |= ARCHIVE_ENTRY_ACL_DELETE;
- break;
- case L'a':
- *permset |= ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES;
- break;
- case L'A':
- *permset |= ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES;
- break;
- case L'R':
- *permset |= ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS;
- break;
- case L'W':
- *permset |= ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS;
- break;
- case L'c':
- *permset |= ARCHIVE_ENTRY_ACL_READ_ACL;
- break;
- case L'C':
- *permset |= ARCHIVE_ENTRY_ACL_WRITE_ACL;
- break;
- case L'o':
- *permset |= ARCHIVE_ENTRY_ACL_WRITE_OWNER;
- break;
- case L's':
- *permset |= ARCHIVE_ENTRY_ACL_SYNCHRONIZE;
- break;
- case L'-':
- break;
- default:
- return(0);
- }
- }
- return (1);
-}
-
-/*
- * Parse a string as a NFS4 ACL flags field.
- * Returns true if the string is non-empty and consists only of NFS4 ACL
- * flag characters, false otherwise
- */
-static int
-is_nfs4_flags_w(const wchar_t *start, const wchar_t *end, int *permset)
-{
- const wchar_t *p = start;
-
- while (p < end) {
- switch(*p++) {
- case L'f':
- *permset |= ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT;
- break;
- case L'd':
- *permset |= ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT;
- break;
- case L'i':
- *permset |= ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY;
- break;
- case L'n':
- *permset |=
- ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT;
- break;
- case L'S':
- *permset |= ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS;
- break;
- case L'F':
- *permset |= ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS;
- break;
- case L'I':
- *permset |= ARCHIVE_ENTRY_ACL_ENTRY_INHERITED;
- break;
- case L'-':
- break;
- default:
- return (0);
- }
- }
- return (1);
-}
-
-/*
- * Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]". *wp is updated
- * to point to just after the separator. *start points to the first
- * character of the matched text and *end just after the last
- * character of the matched identifier. In particular *end - *start
- * is the length of the field body, not including leading or trailing
- * whitespace.
- */
-static void
-next_field_w(const wchar_t **wp, const wchar_t **start,
- const wchar_t **end, wchar_t *sep)
-{
- /* Skip leading whitespace to find start of field. */
- while (**wp == L' ' || **wp == L'\t' || **wp == L'\n') {
- (*wp)++;
- }
- *start = *wp;
-
- /* Scan for the separator. */
- while (**wp != L'\0' && **wp != L',' && **wp != L':' &&
- **wp != L'\n' && **wp != L'#') {
- (*wp)++;
- }
- *sep = **wp;
-
- /* Locate end of field, trim trailing whitespace if necessary */
- if (*wp == *start) {
- *end = *wp;
- } else {
- *end = *wp - 1;
- while (**end == L' ' || **end == L'\t' || **end == L'\n') {
- (*end)--;
- }
- (*end)++;
- }
-
- /* Handle in-field comments */
- if (*sep == L'#') {
- while (**wp != L'\0' && **wp != L',' && **wp != L'\n') {
- (*wp)++;
- }
- *sep = **wp;
- }
-
- /* Adjust scanner location. */
- if (**wp != L'\0')
- (*wp)++;
-}
-
-/*
- * Parse an ACL text string.
- *
- * The want_type argument may be one of the following:
- * ARCHIVE_ENTRY_ACL_TYPE_ACCESS - text is a POSIX.1e ACL of type ACCESS
- * ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - text is a POSIX.1e ACL of type DEFAULT
- * ARCHIVE_ENTRY_ACL_TYPE_NFS4 - text is as a NFSv4 ACL
- *
- * POSIX.1e ACL entries prefixed with "default:" are treated as
- * ARCHIVE_ENTRY_ACL_TYPE_DEFAULT unless type is ARCHIVE_ENTRY_ACL_TYPE_NFS4
- */
-int
-archive_acl_from_text_l(struct archive_acl *acl, const char *text,
- int want_type, struct archive_string_conv *sc)
-{
- struct {
- const char *start;
- const char *end;
- } field[6], name;
-
- const char *s, *st;
- int numfields, fields, n, r, sol, ret;
- int type, types, tag, permset, id;
- size_t len;
- char sep;
-
- switch (want_type) {
- case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E:
- want_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
- __LA_FALLTHROUGH;
- case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
- case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
- numfields = 5;
- break;
- case ARCHIVE_ENTRY_ACL_TYPE_NFS4:
- numfields = 6;
- break;
- default:
- return (ARCHIVE_FATAL);
- }
-
- ret = ARCHIVE_OK;
- types = 0;
-
- while (text != NULL && *text != '\0') {
- /*
- * Parse the fields out of the next entry,
- * advance 'text' to start of next entry.
- */
- fields = 0;
- do {
- const char *start, *end;
- next_field(&text, &start, &end, &sep);
- if (fields < numfields) {
- field[fields].start = start;
- field[fields].end = end;
- }
- ++fields;
- } while (sep == ':');
-
- /* Set remaining fields to blank. */
- for (n = fields; n < numfields; ++n)
- field[n].start = field[n].end = NULL;
-
- if (field[0].start != NULL && *(field[0].start) == '#') {
- /* Comment, skip entry */
- continue;
- }
-
- n = 0;
- sol = 0;
- id = -1;
- permset = 0;
- name.start = name.end = NULL;
-
- if (want_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
- /* POSIX.1e ACLs */
- /*
- * Default keyword "default:user::rwx"
- * if found, we have one more field
- *
- * We also support old Solaris extension:
- * "defaultuser::rwx" is the default ACL corresponding
- * to "user::rwx", etc. valid only for first field
- */
- s = field[0].start;
- len = field[0].end - field[0].start;
- if (*s == 'd' && (len == 1 || (len >= 7
- && memcmp((s + 1), "efault", 6) == 0))) {
- type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
- if (len > 7)
- field[0].start += 7;
- else
- n = 1;
- } else
- type = want_type;
-
- /* Check for a numeric ID in field n+1 or n+3. */
- isint(field[n + 1].start, field[n + 1].end, &id);
- /* Field n+3 is optional. */
- if (id == -1 && fields > (n + 3))
- isint(field[n + 3].start, field[n + 3].end,
- &id);
-
- tag = 0;
- s = field[n].start;
- st = field[n].start + 1;
- len = field[n].end - field[n].start;
-
- if (len == 0) {
- ret = ARCHIVE_WARN;
- continue;
- }
-
- switch (*s) {
- case 'u':
- if (len == 1 || (len == 4
- && memcmp(st, "ser", 3) == 0))
- tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
- break;
- case 'g':
- if (len == 1 || (len == 5
- && memcmp(st, "roup", 4) == 0))
- tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
- break;
- case 'o':
- if (len == 1 || (len == 5
- && memcmp(st, "ther", 4) == 0))
- tag = ARCHIVE_ENTRY_ACL_OTHER;
- break;
- case 'm':
- if (len == 1 || (len == 4
- && memcmp(st, "ask", 3) == 0))
- tag = ARCHIVE_ENTRY_ACL_MASK;
- break;
- default:
- break;
- }
-
- switch (tag) {
- case ARCHIVE_ENTRY_ACL_OTHER:
- case ARCHIVE_ENTRY_ACL_MASK:
- if (fields == (n + 2)
- && field[n + 1].start < field[n + 1].end
- && ismode(field[n + 1].start,
- field[n + 1].end, &permset)) {
- /* This is Solaris-style "other:rwx" */
- sol = 1;
- } else if (fields == (n + 3) &&
- field[n + 1].start < field[n + 1].end) {
- /* Invalid mask or other field */
- ret = ARCHIVE_WARN;
- continue;
- }
- break;
- case ARCHIVE_ENTRY_ACL_USER_OBJ:
- case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
- if (id != -1 ||
- field[n + 1].start < field[n + 1].end) {
- name = field[n + 1];
- if (tag == ARCHIVE_ENTRY_ACL_USER_OBJ)
- tag = ARCHIVE_ENTRY_ACL_USER;
- else
- tag = ARCHIVE_ENTRY_ACL_GROUP;
- }
- break;
- default:
- /* Invalid tag, skip entry */
- ret = ARCHIVE_WARN;
- continue;
- }
-
- /*
- * Without "default:" we expect mode in field 3
- * Exception: Solaris other and mask fields
- */
- if (permset == 0 && !ismode(field[n + 2 - sol].start,
- field[n + 2 - sol].end, &permset)) {
- /* Invalid mode, skip entry */
- ret = ARCHIVE_WARN;
- continue;
- }
- } else {
- /* NFS4 ACLs */
- s = field[0].start;
- len = field[0].end - field[0].start;
- tag = 0;
-
- switch (len) {
- case 4:
- if (memcmp(s, "user", 4) == 0)
- tag = ARCHIVE_ENTRY_ACL_USER;
- break;
- case 5:
- if (memcmp(s, "group", 5) == 0)
- tag = ARCHIVE_ENTRY_ACL_GROUP;
- break;
- case 6:
- if (memcmp(s, "owner@", 6) == 0)
- tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
- else if (memcmp(s, "group@", 6) == 0)
- tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
- break;
- case 9:
- if (memcmp(s, "everyone@", 9) == 0)
- tag = ARCHIVE_ENTRY_ACL_EVERYONE;
- break;
- default:
- break;
- }
-
- if (tag == 0) {
- /* Invalid tag, skip entry */
- ret = ARCHIVE_WARN;
- continue;
- } else if (tag == ARCHIVE_ENTRY_ACL_USER ||
- tag == ARCHIVE_ENTRY_ACL_GROUP) {
- n = 1;
- name = field[1];
- isint(name.start, name.end, &id);
- } else
- n = 0;
-
- if (!is_nfs4_perms(field[1 + n].start,
- field[1 + n].end, &permset)) {
- /* Invalid NFSv4 perms, skip entry */
- ret = ARCHIVE_WARN;
- continue;
- }
- if (!is_nfs4_flags(field[2 + n].start,
- field[2 + n].end, &permset)) {
- /* Invalid NFSv4 flags, skip entry */
- ret = ARCHIVE_WARN;
- continue;
- }
- s = field[3 + n].start;
- len = field[3 + n].end - field[3 + n].start;
- type = 0;
- if (len == 4) {
- if (memcmp(s, "deny", 4) == 0)
- type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
- } else if (len == 5) {
- if (memcmp(s, "allow", 5) == 0)
- type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
- else if (memcmp(s, "audit", 5) == 0)
- type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT;
- else if (memcmp(s, "alarm", 5) == 0)
- type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
- }
- if (type == 0) {
- /* Invalid entry type, skip entry */
- ret = ARCHIVE_WARN;
- continue;
- }
- isint(field[4 + n].start, field[4 + n].end,
- &id);
- }
-
- /* Add entry to the internal list. */
- r = archive_acl_add_entry_len_l(acl, type, permset,
- tag, id, name.start, name.end - name.start, sc);
- if (r < ARCHIVE_WARN)
- return (r);
- if (r != ARCHIVE_OK)
- ret = ARCHIVE_WARN;
- types |= type;
- }
-
- /* Reset ACL */
- archive_acl_reset(acl, types);
-
- return (ret);
-}
-
-/*
- * Parse a string to a positive decimal integer. Returns true if
- * the string is non-empty and consists only of decimal digits,
- * false otherwise.
- */
-static int
-isint(const char *start, const char *end, int *result)
-{
- int n = 0;
- if (start >= end)
- return (0);
- while (start < end) {
- if (*start < '0' || *start > '9')
- return (0);
- if (n > (INT_MAX / 10) ||
- (n == INT_MAX / 10 && (*start - '0') > INT_MAX % 10)) {
- n = INT_MAX;
- } else {
- n *= 10;
- n += *start - '0';
- }
- start++;
- }
- *result = n;
- return (1);
-}
-
-/*
- * Parse a string as a mode field. Returns true if
- * the string is non-empty and consists only of mode characters,
- * false otherwise.
- */
-static int
-ismode(const char *start, const char *end, int *permset)
-{
- const char *p;
-
- if (start >= end)
- return (0);
- p = start;
- *permset = 0;
- while (p < end) {
- switch (*p++) {
- case 'r': case 'R':
- *permset |= ARCHIVE_ENTRY_ACL_READ;
- break;
- case 'w': case 'W':
- *permset |= ARCHIVE_ENTRY_ACL_WRITE;
- break;
- case 'x': case 'X':
- *permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
- break;
- case '-':
- break;
- default:
- return (0);
- }
- }
- return (1);
-}
-
-/*
- * Parse a string as a NFS4 ACL permission field.
- * Returns true if the string is non-empty and consists only of NFS4 ACL
- * permission characters, false otherwise
- */
-static int
-is_nfs4_perms(const char *start, const char *end, int *permset)
-{
- const char *p = start;
-
- while (p < end) {
- switch (*p++) {
- case 'r':
- *permset |= ARCHIVE_ENTRY_ACL_READ_DATA;
- break;
- case 'w':
- *permset |= ARCHIVE_ENTRY_ACL_WRITE_DATA;
- break;
- case 'x':
- *permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
- break;
- case 'p':
- *permset |= ARCHIVE_ENTRY_ACL_APPEND_DATA;
- break;
- case 'D':
- *permset |= ARCHIVE_ENTRY_ACL_DELETE_CHILD;
- break;
- case 'd':
- *permset |= ARCHIVE_ENTRY_ACL_DELETE;
- break;
- case 'a':
- *permset |= ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES;
- break;
- case 'A':
- *permset |= ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES;
- break;
- case 'R':
- *permset |= ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS;
- break;
- case 'W':
- *permset |= ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS;
- break;
- case 'c':
- *permset |= ARCHIVE_ENTRY_ACL_READ_ACL;
- break;
- case 'C':
- *permset |= ARCHIVE_ENTRY_ACL_WRITE_ACL;
- break;
- case 'o':
- *permset |= ARCHIVE_ENTRY_ACL_WRITE_OWNER;
- break;
- case 's':
- *permset |= ARCHIVE_ENTRY_ACL_SYNCHRONIZE;
- break;
- case '-':
- break;
- default:
- return(0);
- }
- }
- return (1);
-}
-
-/*
- * Parse a string as a NFS4 ACL flags field.
- * Returns true if the string is non-empty and consists only of NFS4 ACL
- * flag characters, false otherwise
- */
-static int
-is_nfs4_flags(const char *start, const char *end, int *permset)
-{
- const char *p = start;
-
- while (p < end) {
- switch(*p++) {
- case 'f':
- *permset |= ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT;
- break;
- case 'd':
- *permset |= ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT;
- break;
- case 'i':
- *permset |= ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY;
- break;
- case 'n':
- *permset |=
- ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT;
- break;
- case 'S':
- *permset |= ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS;
- break;
- case 'F':
- *permset |= ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS;
- break;
- case 'I':
- *permset |= ARCHIVE_ENTRY_ACL_ENTRY_INHERITED;
- break;
- case '-':
- break;
- default:
- return (0);
- }
- }
- return (1);
-}
-
-/*
- * Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]". *wp is updated
- * to point to just after the separator. *start points to the first
- * character of the matched text and *end just after the last
- * character of the matched identifier. In particular *end - *start
- * is the length of the field body, not including leading or trailing
- * whitespace.
- */
-static void
-next_field(const char **p, const char **start,
- const char **end, char *sep)
-{
- /* Skip leading whitespace to find start of field. */
- while (**p == ' ' || **p == '\t' || **p == '\n') {
- (*p)++;
- }
- *start = *p;
-
- /* Scan for the separator. */
- while (**p != '\0' && **p != ',' && **p != ':' && **p != '\n' &&
- **p != '#') {
- (*p)++;
- }
- *sep = **p;
-
- /* Locate end of field, trim trailing whitespace if necessary */
- if (*p == *start) {
- *end = *p;
- } else {
- *end = *p - 1;
- while (**end == ' ' || **end == '\t' || **end == '\n') {
- (*end)--;
- }
- (*end)++;
- }
-
- /* Handle in-field comments */
- if (*sep == '#') {
- while (**p != '\0' && **p != ',' && **p != '\n') {
- (*p)++;
- }
- *sep = **p;
- }
-
- /* Adjust scanner location. */
- if (**p != '\0')
- (*p)++;
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_acl_private.h b/contrib/libs/libarchive/libarchive/archive_acl_private.h
deleted file mode 100644
index af108162c6..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_acl_private.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*-
- * Copyright (c) 2003-2010 Tim Kientzle
- * 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(S) ``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(S) 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.
- *
- * $FreeBSD$
- */
-
-#ifndef ARCHIVE_ACL_PRIVATE_H_INCLUDED
-#define ARCHIVE_ACL_PRIVATE_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
-#include "archive_string.h"
-
-struct archive_acl_entry {
- struct archive_acl_entry *next;
- int type; /* E.g., access or default */
- int tag; /* E.g., user/group/other/mask */
- int permset; /* r/w/x bits */
- int id; /* uid/gid for user/group */
- struct archive_mstring name; /* uname/gname */
-};
-
-struct archive_acl {
- mode_t mode;
- struct archive_acl_entry *acl_head;
- struct archive_acl_entry *acl_p;
- int acl_state; /* See acl_next for details. */
- wchar_t *acl_text_w;
- char *acl_text;
- int acl_types;
-};
-
-void archive_acl_clear(struct archive_acl *);
-void archive_acl_copy(struct archive_acl *, struct archive_acl *);
-int archive_acl_count(struct archive_acl *, int);
-int archive_acl_types(struct archive_acl *);
-int archive_acl_reset(struct archive_acl *, int);
-int archive_acl_next(struct archive *, struct archive_acl *, int,
- int *, int *, int *, int *, const char **);
-
-int archive_acl_add_entry(struct archive_acl *, int, int, int, int, const char *);
-int archive_acl_add_entry_w_len(struct archive_acl *,
- int, int, int, int, const wchar_t *, size_t);
-int archive_acl_add_entry_len(struct archive_acl *,
- int, int, int, int, const char *, size_t);
-
-wchar_t *archive_acl_to_text_w(struct archive_acl *, ssize_t *, int,
- struct archive *);
-char *archive_acl_to_text_l(struct archive_acl *, ssize_t *, int,
- struct archive_string_conv *);
-
-/*
- * ACL text parser.
- */
-int archive_acl_from_text_w(struct archive_acl *, const wchar_t * /* wtext */,
- int /* type */);
-int archive_acl_from_text_l(struct archive_acl *, const char * /* text */,
- int /* type */, struct archive_string_conv *);
-
-#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */
diff --git a/contrib/libs/libarchive/libarchive/archive_check_magic.c b/contrib/libs/libarchive/libarchive/archive_check_magic.c
deleted file mode 100644
index 1f40072f81..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_check_magic.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*-
- * Copyright (c) 2003-2010 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_check_magic.c 201089 2009-12-28 02:20:23Z kientzle $");
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#include <windows.h>
-#include <winbase.h>
-#endif
-
-#include "archive_private.h"
-
-static void
-errmsg(const char *m)
-{
- size_t s = strlen(m);
- ssize_t written;
-
- while (s > 0) {
- written = write(2, m, s);
- if (written <= 0)
- return;
- m += written;
- s -= written;
- }
-}
-
-static __LA_DEAD void
-diediedie(void)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
- /* Cause a breakpoint exception */
- DebugBreak();
-#endif
- abort(); /* Terminate the program abnormally. */
-}
-
-static const char *
-state_name(unsigned s)
-{
- switch (s) {
- case ARCHIVE_STATE_NEW: return ("new");
- case ARCHIVE_STATE_HEADER: return ("header");
- case ARCHIVE_STATE_DATA: return ("data");
- case ARCHIVE_STATE_EOF: return ("eof");
- case ARCHIVE_STATE_CLOSED: return ("closed");
- case ARCHIVE_STATE_FATAL: return ("fatal");
- default: return ("??");
- }
-}
-
-static const char *
-archive_handle_type_name(unsigned m)
-{
- switch (m) {
- case ARCHIVE_WRITE_MAGIC: return ("archive_write");
- case ARCHIVE_READ_MAGIC: return ("archive_read");
- case ARCHIVE_WRITE_DISK_MAGIC: return ("archive_write_disk");
- case ARCHIVE_READ_DISK_MAGIC: return ("archive_read_disk");
- case ARCHIVE_MATCH_MAGIC: return ("archive_match");
- default: return NULL;
- }
-}
-
-
-static char *
-write_all_states(char *buff, unsigned int states)
-{
- unsigned int lowbit;
-
- buff[0] = '\0';
-
- /* A trick for computing the lowest set bit. */
- while ((lowbit = states & (1 + ~states)) != 0) {
- states &= ~lowbit; /* Clear the low bit. */
- strcat(buff, state_name(lowbit));
- if (states != 0)
- strcat(buff, "/");
- }
- return buff;
-}
-
-/*
- * Check magic value and current state.
- * Magic value mismatches are fatal and result in calls to abort().
- * State mismatches return ARCHIVE_FATAL.
- * Otherwise, returns ARCHIVE_OK.
- *
- * This is designed to catch serious programming errors that violate
- * the libarchive API.
- */
-int
-__archive_check_magic(struct archive *a, unsigned int magic,
- unsigned int state, const char *function)
-{
- char states1[64];
- char states2[64];
- const char *handle_type;
-
- /*
- * If this isn't some form of archive handle,
- * then the library user has screwed up so bad that
- * we don't even have a reliable way to report an error.
- */
- handle_type = archive_handle_type_name(a->magic);
-
- if (!handle_type) {
- errmsg("PROGRAMMER ERROR: Function ");
- errmsg(function);
- errmsg(" invoked with invalid archive handle.\n");
- diediedie();
- }
-
- if (a->magic != magic) {
- archive_set_error(a, -1,
- "PROGRAMMER ERROR: Function '%s' invoked"
- " on '%s' archive object, which is not supported.",
- function,
- handle_type);
- a->state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- }
-
- if ((a->state & state) == 0) {
- /* If we're already FATAL, don't overwrite the error. */
- if (a->state != ARCHIVE_STATE_FATAL)
- archive_set_error(a, -1,
- "INTERNAL ERROR: Function '%s' invoked with"
- " archive structure in state '%s',"
- " should be in state '%s'",
- function,
- write_all_states(states1, a->state),
- write_all_states(states2, state));
- a->state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- }
- return ARCHIVE_OK;
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_cmdline.c b/contrib/libs/libarchive/libarchive/archive_cmdline.c
deleted file mode 100644
index 5c519cd17f..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_cmdline.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*-
- * Copyright (c) 2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_STRING_H
-# include <string.h>
-#endif
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-
-#include "archive.h"
-#include "archive_cmdline_private.h"
-#include "archive_string.h"
-
-static int cmdline_set_path(struct archive_cmdline *, const char *);
-static int cmdline_add_arg(struct archive_cmdline *, const char *);
-
-static ssize_t
-extract_quotation(struct archive_string *as, const char *p)
-{
- const char *s;
-
- for (s = p + 1; *s;) {
- if (*s == '\\') {
- if (s[1] != '\0') {
- archive_strappend_char(as, s[1]);
- s += 2;
- } else
- s++;
- } else if (*s == '"')
- break;
- else {
- archive_strappend_char(as, s[0]);
- s++;
- }
- }
- if (*s != '"')
- return (ARCHIVE_FAILED);/* Invalid sequence. */
- return ((ssize_t)(s + 1 - p));
-}
-
-static ssize_t
-get_argument(struct archive_string *as, const char *p)
-{
- const char *s = p;
-
- archive_string_empty(as);
-
- /* Skip beginning space characters. */
- while (*s != '\0' && *s == ' ')
- s++;
- /* Copy non-space characters. */
- while (*s != '\0' && *s != ' ') {
- if (*s == '\\') {
- if (s[1] != '\0') {
- archive_strappend_char(as, s[1]);
- s += 2;
- } else {
- s++;/* Ignore this character.*/
- break;
- }
- } else if (*s == '"') {
- ssize_t q = extract_quotation(as, s);
- if (q < 0)
- return (ARCHIVE_FAILED);/* Invalid sequence. */
- s += q;
- } else {
- archive_strappend_char(as, s[0]);
- s++;
- }
- }
- return ((ssize_t)(s - p));
-}
-
-/*
- * Set up command line arguments.
- * Returns ARCHIVE_OK if everything okey.
- * Returns ARCHIVE_FAILED if there is a lack of the `"' terminator or an
- * empty command line.
- * Returns ARCHIVE_FATAL if no memory.
- */
-int
-__archive_cmdline_parse(struct archive_cmdline *data, const char *cmd)
-{
- struct archive_string as;
- const char *p;
- ssize_t al;
- int r;
-
- archive_string_init(&as);
-
- /* Get first argument as a command path. */
- al = get_argument(&as, cmd);
- if (al < 0) {
- r = ARCHIVE_FAILED;/* Invalid sequence. */
- goto exit_function;
- }
- if (archive_strlen(&as) == 0) {
- r = ARCHIVE_FAILED;/* An empty command path. */
- goto exit_function;
- }
- r = cmdline_set_path(data, as.s);
- if (r != ARCHIVE_OK)
- goto exit_function;
- p = strrchr(as.s, '/');
- if (p == NULL)
- p = as.s;
- else
- p++;
- r = cmdline_add_arg(data, p);
- if (r != ARCHIVE_OK)
- goto exit_function;
- cmd += al;
-
- for (;;) {
- al = get_argument(&as, cmd);
- if (al < 0) {
- r = ARCHIVE_FAILED;/* Invalid sequence. */
- goto exit_function;
- }
- if (al == 0)
- break;
- cmd += al;
- if (archive_strlen(&as) == 0 && *cmd == '\0')
- break;
- r = cmdline_add_arg(data, as.s);
- if (r != ARCHIVE_OK)
- goto exit_function;
- }
- r = ARCHIVE_OK;
-exit_function:
- archive_string_free(&as);
- return (r);
-}
-
-/*
- * Set the program path.
- */
-static int
-cmdline_set_path(struct archive_cmdline *data, const char *path)
-{
- char *newptr;
-
- newptr = realloc(data->path, strlen(path) + 1);
- if (newptr == NULL)
- return (ARCHIVE_FATAL);
- data->path = newptr;
- strcpy(data->path, path);
- return (ARCHIVE_OK);
-}
-
-/*
- * Add a argument for the program.
- */
-static int
-cmdline_add_arg(struct archive_cmdline *data, const char *arg)
-{
- char **newargv;
-
- if (data->path == NULL)
- return (ARCHIVE_FAILED);
-
- newargv = realloc(data->argv, (data->argc + 2) * sizeof(char *));
- if (newargv == NULL)
- return (ARCHIVE_FATAL);
- data->argv = newargv;
- data->argv[data->argc] = strdup(arg);
- if (data->argv[data->argc] == NULL)
- return (ARCHIVE_FATAL);
- /* Set the terminator of argv. */
- data->argv[++data->argc] = NULL;
- return (ARCHIVE_OK);
-}
-
-struct archive_cmdline *
-__archive_cmdline_allocate(void)
-{
- return (struct archive_cmdline *)
- calloc(1, sizeof(struct archive_cmdline));
-}
-
-/*
- * Release the resources.
- */
-int
-__archive_cmdline_free(struct archive_cmdline *data)
-{
-
- if (data) {
- free(data->path);
- if (data->argv != NULL) {
- int i;
- for (i = 0; data->argv[i] != NULL; i++)
- free(data->argv[i]);
- free(data->argv);
- }
- free(data);
- }
- return (ARCHIVE_OK);
-}
-
diff --git a/contrib/libs/libarchive/libarchive/archive_cmdline_private.h b/contrib/libs/libarchive/libarchive/archive_cmdline_private.h
deleted file mode 100644
index 57a19494fd..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_cmdline_private.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*-
- * Copyright (c) 2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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.
- *
- * $FreeBSD$
- */
-
-#ifndef ARCHIVE_CMDLINE_PRIVATE_H
-#define ARCHIVE_CMDLINE_PRIVATE_H
-
-#ifndef __LIBARCHIVE_BUILD
-#ifndef __LIBARCHIVE_TEST
-#error This header is only to be used internally to libarchive.
-#endif
-#endif
-
-struct archive_cmdline {
- char *path;
- char **argv;
- int argc;
-};
-
-struct archive_cmdline *__archive_cmdline_allocate(void);
-int __archive_cmdline_parse(struct archive_cmdline *, const char *);
-int __archive_cmdline_free(struct archive_cmdline *);
-
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_cryptor.c b/contrib/libs/libarchive/libarchive/archive_cryptor.c
deleted file mode 100644
index 112baf1613..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_cryptor.c
+++ /dev/null
@@ -1,534 +0,0 @@
-/*-
-* Copyright (c) 2014 Michihiro NAKAJIMA
-* 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(S) ``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(S) 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 "archive_platform.h"
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#include "archive.h"
-#include "archive_cryptor_private.h"
-
-/*
- * On systems that do not support any recognized crypto libraries,
- * this file will normally define no usable symbols.
- *
- * But some compilers and linkers choke on empty object files, so
- * define a public symbol that will always exist. This could
- * be removed someday if this file gains another always-present
- * symbol definition.
- */
-int __libarchive_cryptor_build_hack(void) {
- return 0;
-}
-
-#ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto
-
-static int
-pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
- size_t salt_len, unsigned rounds, uint8_t *derived_key,
- size_t derived_key_len)
-{
- CCKeyDerivationPBKDF(kCCPBKDF2, (const char *)pw,
- pw_len, salt, salt_len, kCCPRFHmacAlgSHA1, rounds,
- derived_key, derived_key_len);
- return 0;
-}
-
-#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
-#ifdef _MSC_VER
-#pragma comment(lib, "Bcrypt.lib")
-#endif
-
-static int
-pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
- size_t salt_len, unsigned rounds, uint8_t *derived_key,
- size_t derived_key_len)
-{
- NTSTATUS status;
- BCRYPT_ALG_HANDLE hAlg;
-
- status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA1_ALGORITHM,
- MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
- if (!BCRYPT_SUCCESS(status))
- return -1;
-
- status = BCryptDeriveKeyPBKDF2(hAlg,
- (PUCHAR)(uintptr_t)pw, (ULONG)pw_len,
- (PUCHAR)(uintptr_t)salt, (ULONG)salt_len, rounds,
- (PUCHAR)derived_key, (ULONG)derived_key_len, 0);
-
- BCryptCloseAlgorithmProvider(hAlg, 0);
-
- return (BCRYPT_SUCCESS(status)) ? 0: -1;
-}
-
-#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_PKCS5_H)
-
-static int
-pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
- size_t salt_len, unsigned rounds, uint8_t *derived_key,
- size_t derived_key_len)
-{
- mbedtls_md_context_t ctx;
- const mbedtls_md_info_t *info;
- int ret;
-
- mbedtls_md_init(&ctx);
- info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
- if (info == NULL) {
- mbedtls_md_free(&ctx);
- return (-1);
- }
- ret = mbedtls_md_setup(&ctx, info, 1);
- if (ret != 0) {
- mbedtls_md_free(&ctx);
- return (-1);
- }
- ret = mbedtls_pkcs5_pbkdf2_hmac(&ctx, (const unsigned char *)pw,
- pw_len, salt, salt_len, rounds, derived_key_len, derived_key);
-
- mbedtls_md_free(&ctx);
- return (ret);
-}
-
-#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_PBKDF2_H)
-
-static int
-pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
- size_t salt_len, unsigned rounds, uint8_t *derived_key,
- size_t derived_key_len) {
- pbkdf2_hmac_sha1((unsigned)pw_len, (const uint8_t *)pw, rounds,
- salt_len, salt, derived_key_len, derived_key);
- return 0;
-}
-
-#elif defined(HAVE_LIBCRYPTO) && defined(HAVE_PKCS5_PBKDF2_HMAC_SHA1)
-
-static int
-pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
- size_t salt_len, unsigned rounds, uint8_t *derived_key,
- size_t derived_key_len) {
-
- PKCS5_PBKDF2_HMAC_SHA1(pw, pw_len, salt, salt_len, rounds,
- derived_key_len, derived_key);
- return 0;
-}
-
-#else
-
-/* Stub */
-static int
-pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
- size_t salt_len, unsigned rounds, uint8_t *derived_key,
- size_t derived_key_len) {
- (void)pw; /* UNUSED */
- (void)pw_len; /* UNUSED */
- (void)salt; /* UNUSED */
- (void)salt_len; /* UNUSED */
- (void)rounds; /* UNUSED */
- (void)derived_key; /* UNUSED */
- (void)derived_key_len; /* UNUSED */
- return -1; /* UNSUPPORTED */
-}
-
-#endif
-
-#ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto
-# if MAC_OS_X_VERSION_MAX_ALLOWED < 1090
-# define kCCAlgorithmAES kCCAlgorithmAES128
-# endif
-
-static int
-aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
-{
- CCCryptorStatus r;
-
- ctx->key_len = key_len;
- memcpy(ctx->key, key, key_len);
- memset(ctx->nonce, 0, sizeof(ctx->nonce));
- ctx->encr_pos = AES_BLOCK_SIZE;
- r = CCCryptorCreateWithMode(kCCEncrypt, kCCModeECB, kCCAlgorithmAES,
- ccNoPadding, NULL, key, key_len, NULL, 0, 0, 0, &ctx->ctx);
- return (r == kCCSuccess)? 0: -1;
-}
-
-static int
-aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
-{
- CCCryptorRef ref = ctx->ctx;
- CCCryptorStatus r;
-
- r = CCCryptorReset(ref, NULL);
- if (r != kCCSuccess && r != kCCUnimplemented)
- return -1;
- r = CCCryptorUpdate(ref, ctx->nonce, AES_BLOCK_SIZE, ctx->encr_buf,
- AES_BLOCK_SIZE, NULL);
- return (r == kCCSuccess)? 0: -1;
-}
-
-static int
-aes_ctr_release(archive_crypto_ctx *ctx)
-{
- memset(ctx->key, 0, ctx->key_len);
- memset(ctx->nonce, 0, sizeof(ctx->nonce));
- return 0;
-}
-
-#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
-
-static int
-aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
-{
- BCRYPT_ALG_HANDLE hAlg;
- BCRYPT_KEY_HANDLE hKey;
- DWORD keyObj_len, aes_key_len;
- PBYTE keyObj;
- ULONG result;
- NTSTATUS status;
- BCRYPT_KEY_LENGTHS_STRUCT key_lengths;
-
- ctx->hAlg = NULL;
- ctx->hKey = NULL;
- ctx->keyObj = NULL;
- switch (key_len) {
- case 16: aes_key_len = 128; break;
- case 24: aes_key_len = 192; break;
- case 32: aes_key_len = 256; break;
- default: return -1;
- }
- status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_AES_ALGORITHM,
- MS_PRIMITIVE_PROVIDER, 0);
- if (!BCRYPT_SUCCESS(status))
- return -1;
- status = BCryptGetProperty(hAlg, BCRYPT_KEY_LENGTHS, (PUCHAR)&key_lengths,
- sizeof(key_lengths), &result, 0);
- if (!BCRYPT_SUCCESS(status)) {
- BCryptCloseAlgorithmProvider(hAlg, 0);
- return -1;
- }
- if (key_lengths.dwMinLength > aes_key_len
- || key_lengths.dwMaxLength < aes_key_len) {
- BCryptCloseAlgorithmProvider(hAlg, 0);
- return -1;
- }
- status = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (PUCHAR)&keyObj_len,
- sizeof(keyObj_len), &result, 0);
- if (!BCRYPT_SUCCESS(status)) {
- BCryptCloseAlgorithmProvider(hAlg, 0);
- return -1;
- }
- keyObj = (PBYTE)HeapAlloc(GetProcessHeap(), 0, keyObj_len);
- if (keyObj == NULL) {
- BCryptCloseAlgorithmProvider(hAlg, 0);
- return -1;
- }
- status = BCryptSetProperty(hAlg, BCRYPT_CHAINING_MODE,
- (PUCHAR)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0);
- if (!BCRYPT_SUCCESS(status)) {
- BCryptCloseAlgorithmProvider(hAlg, 0);
- HeapFree(GetProcessHeap(), 0, keyObj);
- return -1;
- }
- status = BCryptGenerateSymmetricKey(hAlg, &hKey,
- keyObj, keyObj_len,
- (PUCHAR)(uintptr_t)key, (ULONG)key_len, 0);
- if (!BCRYPT_SUCCESS(status)) {
- BCryptCloseAlgorithmProvider(hAlg, 0);
- HeapFree(GetProcessHeap(), 0, keyObj);
- return -1;
- }
-
- ctx->hAlg = hAlg;
- ctx->hKey = hKey;
- ctx->keyObj = keyObj;
- ctx->keyObj_len = keyObj_len;
- ctx->encr_pos = AES_BLOCK_SIZE;
-
- return 0;
-}
-
-static int
-aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
-{
- NTSTATUS status;
- ULONG result;
-
- status = BCryptEncrypt(ctx->hKey, (PUCHAR)ctx->nonce, AES_BLOCK_SIZE,
- NULL, NULL, 0, (PUCHAR)ctx->encr_buf, AES_BLOCK_SIZE,
- &result, 0);
- return BCRYPT_SUCCESS(status) ? 0 : -1;
-}
-
-static int
-aes_ctr_release(archive_crypto_ctx *ctx)
-{
-
- if (ctx->hAlg != NULL) {
- BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
- ctx->hAlg = NULL;
- BCryptDestroyKey(ctx->hKey);
- ctx->hKey = NULL;
- HeapFree(GetProcessHeap(), 0, ctx->keyObj);
- ctx->keyObj = NULL;
- }
- memset(ctx, 0, sizeof(*ctx));
- return 0;
-}
-
-#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_AES_H)
-
-static int
-aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
-{
- mbedtls_aes_init(&ctx->ctx);
- ctx->key_len = key_len;
- memcpy(ctx->key, key, key_len);
- memset(ctx->nonce, 0, sizeof(ctx->nonce));
- ctx->encr_pos = AES_BLOCK_SIZE;
- return 0;
-}
-
-static int
-aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
-{
- if (mbedtls_aes_setkey_enc(&ctx->ctx, ctx->key,
- ctx->key_len * 8) != 0)
- return (-1);
- if (mbedtls_aes_crypt_ecb(&ctx->ctx, MBEDTLS_AES_ENCRYPT, ctx->nonce,
- ctx->encr_buf) != 0)
- return (-1);
- return 0;
-}
-
-static int
-aes_ctr_release(archive_crypto_ctx *ctx)
-{
- mbedtls_aes_free(&ctx->ctx);
- memset(ctx, 0, sizeof(*ctx));
- return 0;
-}
-
-#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_AES_H)
-
-static int
-aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
-{
- ctx->key_len = key_len;
- memcpy(ctx->key, key, key_len);
- memset(ctx->nonce, 0, sizeof(ctx->nonce));
- ctx->encr_pos = AES_BLOCK_SIZE;
- memset(&ctx->ctx, 0, sizeof(ctx->ctx));
- return 0;
-}
-
-static int
-aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
-{
-#if NETTLE_VERSION_MAJOR < 3
- aes_set_encrypt_key(&ctx->ctx, ctx->key_len, ctx->key);
- aes_encrypt(&ctx->ctx, AES_BLOCK_SIZE, ctx->encr_buf, ctx->nonce);
-#else
- switch(ctx->key_len) {
- case AES128_KEY_SIZE:
- aes128_set_encrypt_key(&ctx->ctx.c128, ctx->key);
- aes128_encrypt(&ctx->ctx.c128, AES_BLOCK_SIZE, ctx->encr_buf,
- ctx->nonce);
- break;
- case AES192_KEY_SIZE:
- aes192_set_encrypt_key(&ctx->ctx.c192, ctx->key);
- aes192_encrypt(&ctx->ctx.c192, AES_BLOCK_SIZE, ctx->encr_buf,
- ctx->nonce);
- break;
- case AES256_KEY_SIZE:
- aes256_set_encrypt_key(&ctx->ctx.c256, ctx->key);
- aes256_encrypt(&ctx->ctx.c256, AES_BLOCK_SIZE, ctx->encr_buf,
- ctx->nonce);
- break;
- default:
- return -1;
- break;
- }
-#endif
- return 0;
-}
-
-static int
-aes_ctr_release(archive_crypto_ctx *ctx)
-{
- memset(ctx, 0, sizeof(*ctx));
- return 0;
-}
-
-#elif defined(HAVE_LIBCRYPTO)
-
-static int
-aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
-{
- if ((ctx->ctx = EVP_CIPHER_CTX_new()) == NULL)
- return -1;
-
- switch (key_len) {
- case 16: ctx->type = EVP_aes_128_ecb(); break;
- case 24: ctx->type = EVP_aes_192_ecb(); break;
- case 32: ctx->type = EVP_aes_256_ecb(); break;
- default: ctx->type = NULL; return -1;
- }
-
- ctx->key_len = key_len;
- memcpy(ctx->key, key, key_len);
- memset(ctx->nonce, 0, sizeof(ctx->nonce));
- ctx->encr_pos = AES_BLOCK_SIZE;
- return 0;
-}
-
-static int
-aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
-{
- int outl = 0;
- int r;
-
- r = EVP_EncryptInit_ex(ctx->ctx, ctx->type, NULL, ctx->key, NULL);
- if (r == 0)
- return -1;
- r = EVP_EncryptUpdate(ctx->ctx, ctx->encr_buf, &outl, ctx->nonce,
- AES_BLOCK_SIZE);
- if (r == 0 || outl != AES_BLOCK_SIZE)
- return -1;
- return 0;
-}
-
-static int
-aes_ctr_release(archive_crypto_ctx *ctx)
-{
- EVP_CIPHER_CTX_free(ctx->ctx);
- memset(ctx->key, 0, ctx->key_len);
- memset(ctx->nonce, 0, sizeof(ctx->nonce));
- return 0;
-}
-
-#else
-
-#define ARCHIVE_CRYPTOR_STUB
-/* Stub */
-static int
-aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
-{
- (void)ctx; /* UNUSED */
- (void)key; /* UNUSED */
- (void)key_len; /* UNUSED */
- return -1;
-}
-
-static int
-aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
-{
- (void)ctx; /* UNUSED */
- return -1;
-}
-
-static int
-aes_ctr_release(archive_crypto_ctx *ctx)
-{
- (void)ctx; /* UNUSED */
- return 0;
-}
-
-#endif
-
-#ifdef ARCHIVE_CRYPTOR_STUB
-static int
-aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in,
- size_t in_len, uint8_t * const out, size_t *out_len)
-{
- (void)ctx; /* UNUSED */
- (void)in; /* UNUSED */
- (void)in_len; /* UNUSED */
- (void)out; /* UNUSED */
- (void)out_len; /* UNUSED */
- aes_ctr_encrypt_counter(ctx); /* UNUSED */ /* Fix unused function warning */
- return -1;
-}
-
-#else
-static void
-aes_ctr_increase_counter(archive_crypto_ctx *ctx)
-{
- uint8_t *const nonce = ctx->nonce;
- int j;
-
- for (j = 0; j < 8; j++) {
- if (++nonce[j])
- break;
- }
-}
-
-static int
-aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in,
- size_t in_len, uint8_t * const out, size_t *out_len)
-{
- uint8_t *const ebuf = ctx->encr_buf;
- unsigned pos = ctx->encr_pos;
- unsigned max = (unsigned)((in_len < *out_len)? in_len: *out_len);
- unsigned i;
-
- for (i = 0; i < max; ) {
- if (pos == AES_BLOCK_SIZE) {
- aes_ctr_increase_counter(ctx);
- if (aes_ctr_encrypt_counter(ctx) != 0)
- return -1;
- while (max -i >= AES_BLOCK_SIZE) {
- for (pos = 0; pos < AES_BLOCK_SIZE; pos++)
- out[i+pos] = in[i+pos] ^ ebuf[pos];
- i += AES_BLOCK_SIZE;
- aes_ctr_increase_counter(ctx);
- if (aes_ctr_encrypt_counter(ctx) != 0)
- return -1;
- }
- pos = 0;
- if (i >= max)
- break;
- }
- out[i] = in[i] ^ ebuf[pos++];
- i++;
- }
- ctx->encr_pos = pos;
- *out_len = i;
-
- return 0;
-}
-#endif /* ARCHIVE_CRYPTOR_STUB */
-
-
-const struct archive_cryptor __archive_cryptor =
-{
- &pbkdf2_sha1,
- &aes_ctr_init,
- &aes_ctr_update,
- &aes_ctr_release,
- &aes_ctr_init,
- &aes_ctr_update,
- &aes_ctr_release,
-};
diff --git a/contrib/libs/libarchive/libarchive/archive_cryptor_private.h b/contrib/libs/libarchive/libarchive/archive_cryptor_private.h
deleted file mode 100644
index 82591e6128..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_cryptor_private.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/*-
-* Copyright (c) 2014 Michihiro NAKAJIMA
-* 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(S) ``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(S) 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.
-*/
-
-#ifndef ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED
-#define ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-/*
- * On systems that do not support any recognized crypto libraries,
- * the archive_cryptor.c file will normally define no usable symbols.
- *
- * But some compilers and linkers choke on empty object files, so
- * define a public symbol that will always exist. This could
- * be removed someday if this file gains another always-present
- * symbol definition.
- */
-int __libarchive_cryptor_build_hack(void);
-
-#ifdef __APPLE__
-# include <AvailabilityMacros.h>
-# if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
-# define ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto
-# endif
-#endif
-
-#ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto
-#include <CommonCrypto/CommonCryptor.h>
-#include <CommonCrypto/CommonKeyDerivation.h>
-#define AES_BLOCK_SIZE 16
-#define AES_MAX_KEY_SIZE kCCKeySizeAES256
-
-typedef struct {
- CCCryptorRef ctx;
- uint8_t key[AES_MAX_KEY_SIZE];
- unsigned key_len;
- uint8_t nonce[AES_BLOCK_SIZE];
- uint8_t encr_buf[AES_BLOCK_SIZE];
- unsigned encr_pos;
-} archive_crypto_ctx;
-
-#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
-#include <bcrypt.h>
-
-/* Common in other bcrypt implementations, but missing from VS2008. */
-#ifndef BCRYPT_SUCCESS
-#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
-#endif
-
-#define AES_MAX_KEY_SIZE 32
-#define AES_BLOCK_SIZE 16
-typedef struct {
- BCRYPT_ALG_HANDLE hAlg;
- BCRYPT_KEY_HANDLE hKey;
- PBYTE keyObj;
- DWORD keyObj_len;
- uint8_t nonce[AES_BLOCK_SIZE];
- uint8_t encr_buf[AES_BLOCK_SIZE];
- unsigned encr_pos;
-} archive_crypto_ctx;
-
-#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_AES_H)
-#error #include <mbedtls/aes.h>
-#error #include <mbedtls/md.h>
-#error #include <mbedtls/pkcs5.h>
-
-#define AES_MAX_KEY_SIZE 32
-#define AES_BLOCK_SIZE 16
-
-typedef struct {
- mbedtls_aes_context ctx;
- uint8_t key[AES_MAX_KEY_SIZE];
- unsigned key_len;
- uint8_t nonce[AES_BLOCK_SIZE];
- uint8_t encr_buf[AES_BLOCK_SIZE];
- unsigned encr_pos;
-} archive_crypto_ctx;
-
-#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_AES_H)
-#if defined(HAVE_NETTLE_PBKDF2_H)
-#error #include <nettle/pbkdf2.h>
-#endif
-#error #include <nettle/aes.h>
-#error #include <nettle/version.h>
-
-typedef struct {
-#if NETTLE_VERSION_MAJOR < 3
- struct aes_ctx ctx;
-#else
- union {
- struct aes128_ctx c128;
- struct aes192_ctx c192;
- struct aes256_ctx c256;
- } ctx;
-#endif
- uint8_t key[AES_MAX_KEY_SIZE];
- unsigned key_len;
- uint8_t nonce[AES_BLOCK_SIZE];
- uint8_t encr_buf[AES_BLOCK_SIZE];
- unsigned encr_pos;
-} archive_crypto_ctx;
-
-#elif defined(HAVE_LIBCRYPTO)
-#include "archive_openssl_evp_private.h"
-#define AES_BLOCK_SIZE 16
-#define AES_MAX_KEY_SIZE 32
-
-typedef struct {
- EVP_CIPHER_CTX *ctx;
- const EVP_CIPHER *type;
- uint8_t key[AES_MAX_KEY_SIZE];
- unsigned key_len;
- uint8_t nonce[AES_BLOCK_SIZE];
- uint8_t encr_buf[AES_BLOCK_SIZE];
- unsigned encr_pos;
-} archive_crypto_ctx;
-
-#else
-
-#define AES_BLOCK_SIZE 16
-#define AES_MAX_KEY_SIZE 32
-typedef int archive_crypto_ctx;
-
-#endif
-
-/* defines */
-#define archive_pbkdf2_sha1(pw, pw_len, salt, salt_len, rounds, dk, dk_len)\
- __archive_cryptor.pbkdf2sha1(pw, pw_len, salt, salt_len, rounds, dk, dk_len)
-
-#define archive_decrypto_aes_ctr_init(ctx, key, key_len) \
- __archive_cryptor.decrypto_aes_ctr_init(ctx, key, key_len)
-#define archive_decrypto_aes_ctr_update(ctx, in, in_len, out, out_len) \
- __archive_cryptor.decrypto_aes_ctr_update(ctx, in, in_len, out, out_len)
-#define archive_decrypto_aes_ctr_release(ctx) \
- __archive_cryptor.decrypto_aes_ctr_release(ctx)
-
-#define archive_encrypto_aes_ctr_init(ctx, key, key_len) \
- __archive_cryptor.encrypto_aes_ctr_init(ctx, key, key_len)
-#define archive_encrypto_aes_ctr_update(ctx, in, in_len, out, out_len) \
- __archive_cryptor.encrypto_aes_ctr_update(ctx, in, in_len, out, out_len)
-#define archive_encrypto_aes_ctr_release(ctx) \
- __archive_cryptor.encrypto_aes_ctr_release(ctx)
-
-/* Minimal interface to cryptographic functionality for internal use in
- * libarchive */
-struct archive_cryptor
-{
- /* PKCS5 PBKDF2 HMAC-SHA1 */
- int (*pbkdf2sha1)(const char *pw, size_t pw_len, const uint8_t *salt,
- size_t salt_len, unsigned rounds, uint8_t *derived_key,
- size_t derived_key_len);
- /* AES CTR mode(little endian version) */
- int (*decrypto_aes_ctr_init)(archive_crypto_ctx *, const uint8_t *, size_t);
- int (*decrypto_aes_ctr_update)(archive_crypto_ctx *, const uint8_t *,
- size_t, uint8_t *, size_t *);
- int (*decrypto_aes_ctr_release)(archive_crypto_ctx *);
- int (*encrypto_aes_ctr_init)(archive_crypto_ctx *, const uint8_t *, size_t);
- int (*encrypto_aes_ctr_update)(archive_crypto_ctx *, const uint8_t *,
- size_t, uint8_t *, size_t *);
- int (*encrypto_aes_ctr_release)(archive_crypto_ctx *);
-};
-
-extern const struct archive_cryptor __archive_cryptor;
-
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_digest.c b/contrib/libs/libarchive/libarchive/archive_digest.c
deleted file mode 100644
index 08a9aeb023..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_digest.c
+++ /dev/null
@@ -1,1565 +0,0 @@
-/*-
-* Copyright (c) 2003-2007 Tim Kientzle
-* Copyright (c) 2011 Andres Mejia
-* Copyright (c) 2011 Michihiro NAKAJIMA
-* 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(S) ``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(S) 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 "archive_platform.h"
-
-#include "archive.h"
-#include "archive_digest_private.h"
-
-/* In particular, force the configure probe to break if it tries
- * to test a combination of OpenSSL and libmd. */
-#if defined(ARCHIVE_CRYPTO_OPENSSL) && defined(ARCHIVE_CRYPTO_LIBMD)
-#error Cannot use both OpenSSL and libmd.
-#endif
-
-/* Common in other bcrypt implementations, but missing from VS2008. */
-#ifndef BCRYPT_SUCCESS
-#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
-#endif
-
-/*
- * Message digest functions for Windows platform.
- */
-#if defined(ARCHIVE_CRYPTO_MD5_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA1_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA512_WIN)
-
-/*
- * Initialize a Message digest.
- */
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
-static int
-win_crypto_init(Digest_CTX *ctx, const WCHAR *algo)
-{
- NTSTATUS status;
- ctx->valid = 0;
-
- status = BCryptOpenAlgorithmProvider(&ctx->hAlg, algo, NULL, 0);
- if (!BCRYPT_SUCCESS(status))
- return (ARCHIVE_FAILED);
- status = BCryptCreateHash(ctx->hAlg, &ctx->hHash, NULL, 0, NULL, 0, 0);
- if (!BCRYPT_SUCCESS(status)) {
- BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
- return (ARCHIVE_FAILED);
- }
-
- ctx->valid = 1;
- return (ARCHIVE_OK);
-}
-#else
-static int
-win_crypto_init(Digest_CTX *ctx, DWORD prov, ALG_ID algId)
-{
-
- ctx->valid = 0;
- if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
- prov, CRYPT_VERIFYCONTEXT)) {
- if (GetLastError() != (DWORD)NTE_BAD_KEYSET)
- return (ARCHIVE_FAILED);
- if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
- prov, CRYPT_NEWKEYSET))
- return (ARCHIVE_FAILED);
- }
-
- if (!CryptCreateHash(ctx->cryptProv, algId, 0, 0, &ctx->hash)) {
- CryptReleaseContext(ctx->cryptProv, 0);
- return (ARCHIVE_FAILED);
- }
-
- ctx->valid = 1;
- return (ARCHIVE_OK);
-}
-#endif
-
-/*
- * Update a Message digest.
- */
-static int
-win_crypto_Update(Digest_CTX *ctx, const unsigned char *buf, size_t len)
-{
-
- if (!ctx->valid)
- return (ARCHIVE_FAILED);
-
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
- BCryptHashData(ctx->hHash,
- (PUCHAR)(uintptr_t)buf,
- len, 0);
-#else
- CryptHashData(ctx->hash,
- (unsigned char *)(uintptr_t)buf,
- (DWORD)len, 0);
-#endif
- return (ARCHIVE_OK);
-}
-
-static int
-win_crypto_Final(unsigned char *buf, size_t bufsize, Digest_CTX *ctx)
-{
-#if !(defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA)
- DWORD siglen = (DWORD)bufsize;
-#endif
-
- if (!ctx->valid)
- return (ARCHIVE_FAILED);
-
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
- BCryptFinishHash(ctx->hHash, buf, (ULONG)bufsize, 0);
- BCryptDestroyHash(ctx->hHash);
- BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
-#else
- CryptGetHashParam(ctx->hash, HP_HASHVAL, buf, &siglen, 0);
- CryptDestroyHash(ctx->hash);
- CryptReleaseContext(ctx->cryptProv, 0);
-#endif
- ctx->valid = 0;
- return (ARCHIVE_OK);
-}
-
-#endif /* defined(ARCHIVE_CRYPTO_*_WIN) */
-
-
-/* MD5 implementations */
-#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
-
-static int
-__archive_md5init(archive_md5_ctx *ctx)
-{
- MD5Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_md5update(archive_md5_ctx *ctx, const void *indata,
- size_t insize)
-{
- MD5Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_md5final(archive_md5_ctx *ctx, void *md)
-{
- MD5Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_MD5_LIBMD)
-
-static int
-__archive_md5init(archive_md5_ctx *ctx)
-{
- MD5Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_md5update(archive_md5_ctx *ctx, const void *indata,
- size_t insize)
-{
- MD5Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_md5final(archive_md5_ctx *ctx, void *md)
-{
- MD5Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM)
-
-static int
-__archive_md5init(archive_md5_ctx *ctx)
-{
- CC_MD5_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_md5update(archive_md5_ctx *ctx, const void *indata,
- size_t insize)
-{
- CC_MD5_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_md5final(archive_md5_ctx *ctx, void *md)
-{
- CC_MD5_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_MD5_MBEDTLS)
-
-static int
-__archive_md5init(archive_md5_ctx *ctx)
-{
- mbedtls_md5_init(ctx);
- if (mbedtls_md5_starts_ret(ctx) == 0)
- return (ARCHIVE_OK);
- else
- return (ARCHIVE_FATAL);
-}
-
-static int
-__archive_md5update(archive_md5_ctx *ctx, const void *indata,
- size_t insize)
-{
- if (mbedtls_md5_update_ret(ctx, indata, insize) == 0)
- return (ARCHIVE_OK);
- else
- return (ARCHIVE_FATAL);
-}
-
-static int
-__archive_md5final(archive_md5_ctx *ctx, void *md)
-{
- if (mbedtls_md5_finish_ret(ctx, md) == 0) {
- mbedtls_md5_free(ctx);
- return (ARCHIVE_OK);
- } else {
- mbedtls_md5_free(ctx);
- return (ARCHIVE_FATAL);
- }
-}
-
-#elif defined(ARCHIVE_CRYPTO_MD5_NETTLE)
-
-static int
-__archive_md5init(archive_md5_ctx *ctx)
-{
- md5_init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_md5update(archive_md5_ctx *ctx, const void *indata,
- size_t insize)
-{
- md5_update(ctx, insize, indata);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_md5final(archive_md5_ctx *ctx, void *md)
-{
- md5_digest(ctx, MD5_DIGEST_SIZE, md);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL)
-
-static int
-__archive_md5init(archive_md5_ctx *ctx)
-{
- if ((*ctx = EVP_MD_CTX_new()) == NULL)
- return (ARCHIVE_FAILED);
- if (!EVP_DigestInit(*ctx, EVP_md5()))
- return (ARCHIVE_FAILED);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_md5update(archive_md5_ctx *ctx, const void *indata,
- size_t insize)
-{
- EVP_DigestUpdate(*ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_md5final(archive_md5_ctx *ctx, void *md)
-{
- /* HACK: archive_write_set_format_xar.c is finalizing empty contexts, so
- * this is meant to cope with that. Real fix is probably to fix
- * archive_write_set_format_xar.c
- */
- if (*ctx) {
- EVP_DigestFinal(*ctx, md, NULL);
- EVP_MD_CTX_free(*ctx);
- *ctx = NULL;
- }
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_MD5_WIN)
-
-static int
-__archive_md5init(archive_md5_ctx *ctx)
-{
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
- return (win_crypto_init(ctx, BCRYPT_MD5_ALGORITHM));
-#else
- return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_MD5));
-#endif
-}
-
-static int
-__archive_md5update(archive_md5_ctx *ctx, const void *indata,
- size_t insize)
-{
- return (win_crypto_Update(ctx, indata, insize));
-}
-
-static int
-__archive_md5final(archive_md5_ctx *ctx, void *md)
-{
- return (win_crypto_Final(md, 16, ctx));
-}
-
-#else
-
-static int
-__archive_md5init(archive_md5_ctx *ctx)
-{
- (void)ctx; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_md5update(archive_md5_ctx *ctx, const void *indata,
- size_t insize)
-{
- (void)ctx; /* UNUSED */
- (void)indata; /* UNUSED */
- (void)insize; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_md5final(archive_md5_ctx *ctx, void *md)
-{
- (void)ctx; /* UNUSED */
- (void)md; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-#endif
-
-/* RIPEMD160 implementations */
-#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
-
-static int
-__archive_ripemd160init(archive_rmd160_ctx *ctx)
-{
- RMD160Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
- size_t insize)
-{
- RMD160Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_ripemd160final(archive_rmd160_ctx *ctx, void *md)
-{
- RMD160Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
-
-static int
-__archive_ripemd160init(archive_rmd160_ctx *ctx)
-{
- RIPEMD160_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
- size_t insize)
-{
- RIPEMD160_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_ripemd160final(archive_rmd160_ctx *ctx, void *md)
-{
- RIPEMD160_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS)
-
-static int
-__archive_ripemd160init(archive_rmd160_ctx *ctx)
-{
- mbedtls_ripemd160_init(ctx);
- if (mbedtls_ripemd160_starts_ret(ctx) == 0)
- return (ARCHIVE_OK);
- else
- return (ARCHIVE_FATAL);
-}
-
-static int
-__archive_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
- size_t insize)
-{
- if (mbedtls_ripemd160_update_ret(ctx, indata, insize) == 0)
- return (ARCHIVE_OK);
- else
- return (ARCHIVE_FATAL);
-}
-
-static int
-__archive_ripemd160final(archive_rmd160_ctx *ctx, void *md)
-{
- if (mbedtls_ripemd160_finish_ret(ctx, md) == 0) {
- mbedtls_ripemd160_free(ctx);
- return (ARCHIVE_OK);
- } else {
- mbedtls_ripemd160_free(ctx);
- return (ARCHIVE_FATAL);
- }
-}
-
-#elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
-
-static int
-__archive_ripemd160init(archive_rmd160_ctx *ctx)
-{
- ripemd160_init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
- size_t insize)
-{
- ripemd160_update(ctx, insize, indata);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_ripemd160final(archive_rmd160_ctx *ctx, void *md)
-{
- ripemd160_digest(ctx, RIPEMD160_DIGEST_SIZE, md);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
-
-static int
-__archive_ripemd160init(archive_rmd160_ctx *ctx)
-{
- if ((*ctx = EVP_MD_CTX_new()) == NULL)
- return (ARCHIVE_FAILED);
- if (!EVP_DigestInit(*ctx, EVP_ripemd160()))
- return (ARCHIVE_FAILED);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
- size_t insize)
-{
- EVP_DigestUpdate(*ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_ripemd160final(archive_rmd160_ctx *ctx, void *md)
-{
- if (*ctx) {
- EVP_DigestFinal(*ctx, md, NULL);
- EVP_MD_CTX_free(*ctx);
- *ctx = NULL;
- }
- return (ARCHIVE_OK);
-}
-
-#else
-
-static int
-__archive_ripemd160init(archive_rmd160_ctx *ctx)
-{
- (void)ctx; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
- size_t insize)
-{
- (void)ctx; /* UNUSED */
- (void)indata; /* UNUSED */
- (void)insize; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_ripemd160final(archive_rmd160_ctx *ctx, void *md)
-{
- (void)ctx; /* UNUSED */
- (void)md; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-#endif
-
-/* SHA1 implementations */
-#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
-
-static int
-__archive_sha1init(archive_sha1_ctx *ctx)
-{
- SHA1Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha1update(archive_sha1_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA1Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha1final(archive_sha1_ctx *ctx, void *md)
-{
- SHA1Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
-
-static int
-__archive_sha1init(archive_sha1_ctx *ctx)
-{
- SHA1_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha1update(archive_sha1_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA1_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha1final(archive_sha1_ctx *ctx, void *md)
-{
- SHA1_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM)
-
-static int
-__archive_sha1init(archive_sha1_ctx *ctx)
-{
- CC_SHA1_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha1update(archive_sha1_ctx *ctx, const void *indata,
- size_t insize)
-{
- CC_SHA1_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha1final(archive_sha1_ctx *ctx, void *md)
-{
- CC_SHA1_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS)
-
-static int
-__archive_sha1init(archive_sha1_ctx *ctx)
-{
- mbedtls_sha1_init(ctx);
- if (mbedtls_sha1_starts_ret(ctx) == 0)
- return (ARCHIVE_OK);
- else
- return (ARCHIVE_FATAL);
-}
-
-static int
-__archive_sha1update(archive_sha1_ctx *ctx, const void *indata,
- size_t insize)
-{
- if (mbedtls_sha1_update_ret(ctx, indata, insize) == 0)
- return (ARCHIVE_OK);
- else
- return (ARCHIVE_FATAL);
-}
-
-static int
-__archive_sha1final(archive_sha1_ctx *ctx, void *md)
-{
- if (mbedtls_sha1_finish_ret(ctx, md) == 0) {
- mbedtls_sha1_free(ctx);
- return (ARCHIVE_OK);
- } else {
- mbedtls_sha1_free(ctx);
- return (ARCHIVE_FATAL);
- }
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE)
-
-static int
-__archive_sha1init(archive_sha1_ctx *ctx)
-{
- sha1_init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha1update(archive_sha1_ctx *ctx, const void *indata,
- size_t insize)
-{
- sha1_update(ctx, insize, indata);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha1final(archive_sha1_ctx *ctx, void *md)
-{
- sha1_digest(ctx, SHA1_DIGEST_SIZE, md);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL)
-
-static int
-__archive_sha1init(archive_sha1_ctx *ctx)
-{
- if ((*ctx = EVP_MD_CTX_new()) == NULL)
- return (ARCHIVE_FAILED);
- if (!EVP_DigestInit(*ctx, EVP_sha1()))
- return (ARCHIVE_FAILED);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha1update(archive_sha1_ctx *ctx, const void *indata,
- size_t insize)
-{
- EVP_DigestUpdate(*ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha1final(archive_sha1_ctx *ctx, void *md)
-{
- /* HACK: archive_write_set_format_xar.c is finalizing empty contexts, so
- * this is meant to cope with that. Real fix is probably to fix
- * archive_write_set_format_xar.c
- */
- if (*ctx) {
- EVP_DigestFinal(*ctx, md, NULL);
- EVP_MD_CTX_free(*ctx);
- *ctx = NULL;
- }
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA1_WIN)
-
-static int
-__archive_sha1init(archive_sha1_ctx *ctx)
-{
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
- return (win_crypto_init(ctx, BCRYPT_SHA1_ALGORITHM));
-#else
- return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_SHA1));
-#endif
-}
-
-static int
-__archive_sha1update(archive_sha1_ctx *ctx, const void *indata,
- size_t insize)
-{
- return (win_crypto_Update(ctx, indata, insize));
-}
-
-static int
-__archive_sha1final(archive_sha1_ctx *ctx, void *md)
-{
- return (win_crypto_Final(md, 20, ctx));
-}
-
-#else
-
-static int
-__archive_sha1init(archive_sha1_ctx *ctx)
-{
- (void)ctx; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_sha1update(archive_sha1_ctx *ctx, const void *indata,
- size_t insize)
-{
- (void)ctx; /* UNUSED */
- (void)indata; /* UNUSED */
- (void)insize; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_sha1final(archive_sha1_ctx *ctx, void *md)
-{
- (void)ctx; /* UNUSED */
- (void)md; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-#endif
-
-/* SHA256 implementations */
-#if defined(ARCHIVE_CRYPTO_SHA256_LIBC)
-
-static int
-__archive_sha256init(archive_sha256_ctx *ctx)
-{
- SHA256_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha256update(archive_sha256_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA256_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha256final(archive_sha256_ctx *ctx, void *md)
-{
- SHA256_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC2)
-
-static int
-__archive_sha256init(archive_sha256_ctx *ctx)
-{
- SHA256Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha256update(archive_sha256_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA256Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha256final(archive_sha256_ctx *ctx, void *md)
-{
- SHA256Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC3)
-
-static int
-__archive_sha256init(archive_sha256_ctx *ctx)
-{
- SHA256Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha256update(archive_sha256_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA256Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha256final(archive_sha256_ctx *ctx, void *md)
-{
- SHA256Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
-
-static int
-__archive_sha256init(archive_sha256_ctx *ctx)
-{
- SHA256_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha256update(archive_sha256_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA256_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha256final(archive_sha256_ctx *ctx, void *md)
-{
- SHA256_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM)
-
-static int
-__archive_sha256init(archive_sha256_ctx *ctx)
-{
- CC_SHA256_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha256update(archive_sha256_ctx *ctx, const void *indata,
- size_t insize)
-{
- CC_SHA256_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha256final(archive_sha256_ctx *ctx, void *md)
-{
- CC_SHA256_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS)
-
-static int
-__archive_sha256init(archive_sha256_ctx *ctx)
-{
- mbedtls_sha256_init(ctx);
- if (mbedtls_sha256_starts_ret(ctx, 0) == 0)
- return (ARCHIVE_OK);
- else
- return (ARCHIVE_FATAL);
-}
-
-static int
-__archive_sha256update(archive_sha256_ctx *ctx, const void *indata,
- size_t insize)
-{
- if (mbedtls_sha256_update_ret(ctx, indata, insize) == 0)
- return (ARCHIVE_OK);
- else
- return (ARCHIVE_FATAL);
-}
-
-static int
-__archive_sha256final(archive_sha256_ctx *ctx, void *md)
-{
- if (mbedtls_sha256_finish_ret(ctx, md) == 0) {
- mbedtls_sha256_free(ctx);
- return (ARCHIVE_OK);
- } else {
- mbedtls_sha256_free(ctx);
- return (ARCHIVE_FATAL);
- }
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE)
-
-static int
-__archive_sha256init(archive_sha256_ctx *ctx)
-{
- sha256_init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha256update(archive_sha256_ctx *ctx, const void *indata,
- size_t insize)
-{
- sha256_update(ctx, insize, indata);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha256final(archive_sha256_ctx *ctx, void *md)
-{
- sha256_digest(ctx, SHA256_DIGEST_SIZE, md);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL)
-
-static int
-__archive_sha256init(archive_sha256_ctx *ctx)
-{
- if ((*ctx = EVP_MD_CTX_new()) == NULL)
- return (ARCHIVE_FAILED);
- if (!EVP_DigestInit(*ctx, EVP_sha256()))
- return (ARCHIVE_FAILED);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha256update(archive_sha256_ctx *ctx, const void *indata,
- size_t insize)
-{
- EVP_DigestUpdate(*ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha256final(archive_sha256_ctx *ctx, void *md)
-{
- if (*ctx) {
- EVP_DigestFinal(*ctx, md, NULL);
- EVP_MD_CTX_free(*ctx);
- *ctx = NULL;
- }
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA256_WIN)
-
-static int
-__archive_sha256init(archive_sha256_ctx *ctx)
-{
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
- return (win_crypto_init(ctx, BCRYPT_SHA256_ALGORITHM));
-#else
- return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_256));
-#endif
-}
-
-static int
-__archive_sha256update(archive_sha256_ctx *ctx, const void *indata,
- size_t insize)
-{
- return (win_crypto_Update(ctx, indata, insize));
-}
-
-static int
-__archive_sha256final(archive_sha256_ctx *ctx, void *md)
-{
- return (win_crypto_Final(md, 32, ctx));
-}
-
-#else
-
-static int
-__archive_sha256init(archive_sha256_ctx *ctx)
-{
- (void)ctx; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_sha256update(archive_sha256_ctx *ctx, const void *indata,
- size_t insize)
-{
- (void)ctx; /* UNUSED */
- (void)indata; /* UNUSED */
- (void)insize; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_sha256final(archive_sha256_ctx *ctx, void *md)
-{
- (void)ctx; /* UNUSED */
- (void)md; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-#endif
-
-/* SHA384 implementations */
-#if defined(ARCHIVE_CRYPTO_SHA384_LIBC)
-
-static int
-__archive_sha384init(archive_sha384_ctx *ctx)
-{
- SHA384_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha384update(archive_sha384_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA384_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha384final(archive_sha384_ctx *ctx, void *md)
-{
- SHA384_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC2)
-
-static int
-__archive_sha384init(archive_sha384_ctx *ctx)
-{
- SHA384Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha384update(archive_sha384_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA384Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha384final(archive_sha384_ctx *ctx, void *md)
-{
- SHA384Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC3)
-
-static int
-__archive_sha384init(archive_sha384_ctx *ctx)
-{
- SHA384Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha384update(archive_sha384_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA384Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha384final(archive_sha384_ctx *ctx, void *md)
-{
- SHA384Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM)
-
-static int
-__archive_sha384init(archive_sha384_ctx *ctx)
-{
- CC_SHA384_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha384update(archive_sha384_ctx *ctx, const void *indata,
- size_t insize)
-{
- CC_SHA384_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha384final(archive_sha384_ctx *ctx, void *md)
-{
- CC_SHA384_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS)
-
-static int
-__archive_sha384init(archive_sha384_ctx *ctx)
-{
- mbedtls_sha512_init(ctx);
- if (mbedtls_sha512_starts_ret(ctx, 1) == 0)
- return (ARCHIVE_OK);
- else
- return (ARCHIVE_FATAL);
-}
-
-static int
-__archive_sha384update(archive_sha384_ctx *ctx, const void *indata,
- size_t insize)
-{
- if (mbedtls_sha512_update_ret(ctx, indata, insize) == 0)
- return (ARCHIVE_OK);
- else
- return (ARCHIVE_FATAL);
-}
-
-static int
-__archive_sha384final(archive_sha384_ctx *ctx, void *md)
-{
- if (mbedtls_sha512_finish_ret(ctx, md) == 0) {
- mbedtls_sha512_free(ctx);
- return (ARCHIVE_OK);
- } else {
- mbedtls_sha512_free(ctx);
- return (ARCHIVE_FATAL);
- }
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE)
-
-static int
-__archive_sha384init(archive_sha384_ctx *ctx)
-{
- sha384_init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha384update(archive_sha384_ctx *ctx, const void *indata,
- size_t insize)
-{
- sha384_update(ctx, insize, indata);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha384final(archive_sha384_ctx *ctx, void *md)
-{
- sha384_digest(ctx, SHA384_DIGEST_SIZE, md);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL)
-
-static int
-__archive_sha384init(archive_sha384_ctx *ctx)
-{
- if ((*ctx = EVP_MD_CTX_new()) == NULL)
- return (ARCHIVE_FAILED);
- if (!EVP_DigestInit(*ctx, EVP_sha384()))
- return (ARCHIVE_FAILED);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha384update(archive_sha384_ctx *ctx, const void *indata,
- size_t insize)
-{
- EVP_DigestUpdate(*ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha384final(archive_sha384_ctx *ctx, void *md)
-{
- if (*ctx) {
- EVP_DigestFinal(*ctx, md, NULL);
- EVP_MD_CTX_free(*ctx);
- *ctx = NULL;
- }
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA384_WIN)
-
-static int
-__archive_sha384init(archive_sha384_ctx *ctx)
-{
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
- return (win_crypto_init(ctx, BCRYPT_SHA384_ALGORITHM));
-#else
- return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_384));
-#endif
-}
-
-static int
-__archive_sha384update(archive_sha384_ctx *ctx, const void *indata,
- size_t insize)
-{
- return (win_crypto_Update(ctx, indata, insize));
-}
-
-static int
-__archive_sha384final(archive_sha384_ctx *ctx, void *md)
-{
- return (win_crypto_Final(md, 48, ctx));
-}
-
-#else
-
-static int
-__archive_sha384init(archive_sha384_ctx *ctx)
-{
- (void)ctx; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_sha384update(archive_sha384_ctx *ctx, const void *indata,
- size_t insize)
-{
- (void)ctx; /* UNUSED */
- (void)indata; /* UNUSED */
- (void)insize; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_sha384final(archive_sha384_ctx *ctx, void *md)
-{
- (void)ctx; /* UNUSED */
- (void)md; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-#endif
-
-/* SHA512 implementations */
-#if defined(ARCHIVE_CRYPTO_SHA512_LIBC)
-
-static int
-__archive_sha512init(archive_sha512_ctx *ctx)
-{
- SHA512_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha512update(archive_sha512_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA512_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha512final(archive_sha512_ctx *ctx, void *md)
-{
- SHA512_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC2)
-
-static int
-__archive_sha512init(archive_sha512_ctx *ctx)
-{
- SHA512Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha512update(archive_sha512_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA512Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha512final(archive_sha512_ctx *ctx, void *md)
-{
- SHA512Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
-
-static int
-__archive_sha512init(archive_sha512_ctx *ctx)
-{
- SHA512Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha512update(archive_sha512_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA512Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha512final(archive_sha512_ctx *ctx, void *md)
-{
- SHA512Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
-
-static int
-__archive_sha512init(archive_sha512_ctx *ctx)
-{
- SHA512_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha512update(archive_sha512_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA512_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha512final(archive_sha512_ctx *ctx, void *md)
-{
- SHA512_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
-
-static int
-__archive_sha512init(archive_sha512_ctx *ctx)
-{
- CC_SHA512_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha512update(archive_sha512_ctx *ctx, const void *indata,
- size_t insize)
-{
- CC_SHA512_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha512final(archive_sha512_ctx *ctx, void *md)
-{
- CC_SHA512_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS)
-
-static int
-__archive_sha512init(archive_sha512_ctx *ctx)
-{
- mbedtls_sha512_init(ctx);
- if (mbedtls_sha512_starts_ret(ctx, 0) == 0)
- return (ARCHIVE_OK);
- else
- return (ARCHIVE_FATAL);
-}
-
-static int
-__archive_sha512update(archive_sha512_ctx *ctx, const void *indata,
- size_t insize)
-{
- if (mbedtls_sha512_update_ret(ctx, indata, insize) == 0)
- return (ARCHIVE_OK);
- else
- return (ARCHIVE_FATAL);
-}
-
-static int
-__archive_sha512final(archive_sha512_ctx *ctx, void *md)
-{
- if (mbedtls_sha512_finish_ret(ctx, md) == 0) {
- mbedtls_sha512_free(ctx);
- return (ARCHIVE_OK);
- } else {
- mbedtls_sha512_free(ctx);
- return (ARCHIVE_FATAL);
- }
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
-
-static int
-__archive_sha512init(archive_sha512_ctx *ctx)
-{
- sha512_init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha512update(archive_sha512_ctx *ctx, const void *indata,
- size_t insize)
-{
- sha512_update(ctx, insize, indata);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha512final(archive_sha512_ctx *ctx, void *md)
-{
- sha512_digest(ctx, SHA512_DIGEST_SIZE, md);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
-
-static int
-__archive_sha512init(archive_sha512_ctx *ctx)
-{
- if ((*ctx = EVP_MD_CTX_new()) == NULL)
- return (ARCHIVE_FAILED);
- if (!EVP_DigestInit(*ctx, EVP_sha512()))
- return (ARCHIVE_FAILED);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha512update(archive_sha512_ctx *ctx, const void *indata,
- size_t insize)
-{
- EVP_DigestUpdate(*ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_sha512final(archive_sha512_ctx *ctx, void *md)
-{
- if (*ctx) {
- EVP_DigestFinal(*ctx, md, NULL);
- EVP_MD_CTX_free(*ctx);
- *ctx = NULL;
- }
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA512_WIN)
-
-static int
-__archive_sha512init(archive_sha512_ctx *ctx)
-{
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
- return (win_crypto_init(ctx, BCRYPT_SHA512_ALGORITHM));
-#else
- return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_512));
-#endif
-}
-
-static int
-__archive_sha512update(archive_sha512_ctx *ctx, const void *indata,
- size_t insize)
-{
- return (win_crypto_Update(ctx, indata, insize));
-}
-
-static int
-__archive_sha512final(archive_sha512_ctx *ctx, void *md)
-{
- return (win_crypto_Final(md, 64, ctx));
-}
-
-#else
-
-static int
-__archive_sha512init(archive_sha512_ctx *ctx)
-{
- (void)ctx; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_sha512update(archive_sha512_ctx *ctx, const void *indata,
- size_t insize)
-{
- (void)ctx; /* UNUSED */
- (void)indata; /* UNUSED */
- (void)insize; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_sha512final(archive_sha512_ctx *ctx, void *md)
-{
- (void)ctx; /* UNUSED */
- (void)md; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-#endif
-
-/* NOTE: Message Digest functions are set based on availability and by the
- * following order of preference.
- * 1. libc
- * 2. libc2
- * 3. libc3
- * 4. libSystem
- * 5. Nettle
- * 6. OpenSSL
- * 7. libmd
- * 8. Windows API
- */
-const struct archive_digest __archive_digest =
-{
-/* MD5 */
- &__archive_md5init,
- &__archive_md5update,
- &__archive_md5final,
-
-/* RIPEMD160 */
- &__archive_ripemd160init,
- &__archive_ripemd160update,
- &__archive_ripemd160final,
-
-/* SHA1 */
- &__archive_sha1init,
- &__archive_sha1update,
- &__archive_sha1final,
-
-/* SHA256 */
- &__archive_sha256init,
- &__archive_sha256update,
- &__archive_sha256final,
-
-/* SHA384 */
- &__archive_sha384init,
- &__archive_sha384update,
- &__archive_sha384final,
-
-/* SHA512 */
- &__archive_sha512init,
- &__archive_sha512update,
- &__archive_sha512final
-};
diff --git a/contrib/libs/libarchive/libarchive/archive_digest_private.h b/contrib/libs/libarchive/libarchive/archive_digest_private.h
deleted file mode 100644
index 05367c22f4..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_digest_private.h
+++ /dev/null
@@ -1,426 +0,0 @@
-/*-
-* Copyright (c) 2003-2007 Tim Kientzle
-* Copyright (c) 2011 Andres Mejia
-* 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(S) ``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(S) 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.
-*/
-
-#ifndef ARCHIVE_DIGEST_PRIVATE_H_INCLUDED
-#define ARCHIVE_DIGEST_PRIVATE_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-#ifndef __LIBARCHIVE_CONFIG_H_INCLUDED
-#error "Should have include config.h first!"
-#endif
-
-/*
- * Crypto support in various Operating Systems:
- *
- * NetBSD:
- * - MD5 and SHA1 in libc: without _ after algorithm name
- * - SHA2 in libc: with _ after algorithm name
- *
- * OpenBSD:
- * - MD5, SHA1 and SHA2 in libc: without _ after algorithm name
- * - OpenBSD 4.4 and earlier have SHA2 in libc with _ after algorithm name
- *
- * DragonFly and FreeBSD:
- * - MD5 libmd: without _ after algorithm name
- * - SHA1, SHA256 and SHA512 in libmd: with _ after algorithm name
- *
- * Mac OS X (10.4 and later):
- * - MD5, SHA1 and SHA2 in libSystem: with CC_ prefix and _ after algorithm name
- *
- * OpenSSL:
- * - MD5, SHA1 and SHA2 in libcrypto: with _ after algorithm name
- *
- * Windows:
- * - MD5, SHA1 and SHA2 in archive_crypto.c using Windows crypto API
- */
-
-/* libc crypto headers */
-#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
-#error #include <md5.h>
-#endif
-#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
-#error #include <rmd160.h>
-#endif
-#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
-#error #include <sha1.h>
-#endif
-#if defined(ARCHIVE_CRYPTO_SHA256_LIBC) ||\
- defined(ARCHIVE_CRYPTO_SHA256_LIBC2) ||\
- defined(ARCHIVE_CRYPTO_SHA256_LIBC3) ||\
- defined(ARCHIVE_CRYPTO_SHA384_LIBC) ||\
- defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\
- defined(ARCHIVE_CRYPTO_SHA384_LIBC3) ||\
- defined(ARCHIVE_CRYPTO_SHA512_LIBC) ||\
- defined(ARCHIVE_CRYPTO_SHA512_LIBC2) ||\
- defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
-#error #include <sha2.h>
-#endif
-
-/* libmd crypto headers */
-#if defined(ARCHIVE_CRYPTO_MD5_LIBMD) ||\
- defined(ARCHIVE_CRYPTO_RMD160_LIBMD) ||\
- defined(ARCHIVE_CRYPTO_SHA1_LIBMD) ||\
- defined(ARCHIVE_CRYPTO_SHA256_LIBMD) ||\
- defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
-#define ARCHIVE_CRYPTO_LIBMD 1
-#endif
-
-#if defined(ARCHIVE_CRYPTO_MD5_LIBMD)
-#error #include <md5.h>
-#endif
-#if defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
-#include <ripemd.h>
-#endif
-#if defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
-#error #include <sha.h>
-#endif
-#if defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
-#error #include <sha256.h>
-#endif
-#if defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
-#error #include <sha512.h>
-#endif
-
-/* libSystem crypto headers */
-#if defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) ||\
- defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) ||\
- defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) ||\
- defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) ||\
- defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
-#include <CommonCrypto/CommonDigest.h>
-#endif
-
-/* mbed TLS crypto headers */
-#if defined(ARCHIVE_CRYPTO_MD5_MBEDTLS)
-#error #include <mbedtls/md5.h>
-#endif
-#if defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS)
-#error #include <mbedtls/ripemd160.h>
-#endif
-#if defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS)
-#error #include <mbedtls/sha1.h>
-#endif
-#if defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS)
-#error #include <mbedtls/sha256.h>
-#endif
-#if defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS) ||\
- defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS)
-#error #include <mbedtls/sha512.h>
-#endif
-
-/* Nettle crypto headers */
-#if defined(ARCHIVE_CRYPTO_MD5_NETTLE)
-#error #include <nettle/md5.h>
-#endif
-#if defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
-#error #include <nettle/ripemd160.h>
-#endif
-#if defined(ARCHIVE_CRYPTO_SHA1_NETTLE) ||\
- defined(ARCHIVE_CRYPTO_SHA256_NETTLE) ||\
- defined(ARCHIVE_CRYPTO_SHA384_NETTLE) ||\
- defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
-#error #include <nettle/sha.h>
-#endif
-
-/* OpenSSL crypto headers */
-#if defined(ARCHIVE_CRYPTO_MD5_OPENSSL) ||\
- defined(ARCHIVE_CRYPTO_RMD160_OPENSSL) ||\
- defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) ||\
- defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) ||\
- defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) ||\
- defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
-#define ARCHIVE_CRYPTO_OPENSSL 1
-#include "archive_openssl_evp_private.h"
-#endif
-
-/* Windows crypto headers */
-#if defined(ARCHIVE_CRYPTO_MD5_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA1_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA512_WIN)
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
-/* don't use bcrypt when XP needs to be supported */
-#include <bcrypt.h>
-typedef struct {
- int valid;
- BCRYPT_ALG_HANDLE hAlg;
- BCRYPT_HASH_HANDLE hHash;
-} Digest_CTX;
-#else
-#include <windows.h>
-#include <wincrypt.h>
-typedef struct {
- int valid;
- HCRYPTPROV cryptProv;
- HCRYPTHASH hash;
-} Digest_CTX;
-#endif
-#endif
-
-/* typedefs */
-#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
-typedef MD5_CTX archive_md5_ctx;
-#elif defined(ARCHIVE_CRYPTO_MD5_LIBMD)
-typedef MD5_CTX archive_md5_ctx;
-#elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM)
-typedef CC_MD5_CTX archive_md5_ctx;
-#elif defined(ARCHIVE_CRYPTO_MD5_MBEDTLS)
-typedef mbedtls_md5_context archive_md5_ctx;
-#elif defined(ARCHIVE_CRYPTO_MD5_NETTLE)
-typedef struct md5_ctx archive_md5_ctx;
-#elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL)
-typedef EVP_MD_CTX *archive_md5_ctx;
-#elif defined(ARCHIVE_CRYPTO_MD5_WIN)
-typedef Digest_CTX archive_md5_ctx;
-#else
-typedef unsigned char archive_md5_ctx;
-#endif
-
-#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
-typedef RMD160_CTX archive_rmd160_ctx;
-#elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
-typedef RIPEMD160_CTX archive_rmd160_ctx;
-#elif defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS)
-typedef mbedtls_ripemd160_context archive_rmd160_ctx;
-#elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
-typedef struct ripemd160_ctx archive_rmd160_ctx;
-#elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
-typedef EVP_MD_CTX *archive_rmd160_ctx;
-#else
-typedef unsigned char archive_rmd160_ctx;
-#endif
-
-#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
-typedef SHA1_CTX archive_sha1_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
-typedef SHA1_CTX archive_sha1_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM)
-typedef CC_SHA1_CTX archive_sha1_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS)
-typedef mbedtls_sha1_context archive_sha1_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE)
-typedef struct sha1_ctx archive_sha1_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL)
-typedef EVP_MD_CTX *archive_sha1_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA1_WIN)
-typedef Digest_CTX archive_sha1_ctx;
-#else
-typedef unsigned char archive_sha1_ctx;
-#endif
-
-#if defined(ARCHIVE_CRYPTO_SHA256_LIBC)
-typedef SHA256_CTX archive_sha256_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC2)
-typedef SHA256_CTX archive_sha256_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC3)
-typedef SHA2_CTX archive_sha256_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
-typedef SHA256_CTX archive_sha256_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM)
-typedef CC_SHA256_CTX archive_sha256_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS)
-typedef mbedtls_sha256_context archive_sha256_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE)
-typedef struct sha256_ctx archive_sha256_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL)
-typedef EVP_MD_CTX *archive_sha256_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA256_WIN)
-typedef Digest_CTX archive_sha256_ctx;
-#else
-typedef unsigned char archive_sha256_ctx;
-#endif
-
-#if defined(ARCHIVE_CRYPTO_SHA384_LIBC)
-typedef SHA384_CTX archive_sha384_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC2)
-typedef SHA384_CTX archive_sha384_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC3)
-typedef SHA2_CTX archive_sha384_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM)
-typedef CC_SHA512_CTX archive_sha384_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS)
-typedef mbedtls_sha512_context archive_sha384_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE)
-typedef struct sha384_ctx archive_sha384_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL)
-typedef EVP_MD_CTX *archive_sha384_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA384_WIN)
-typedef Digest_CTX archive_sha384_ctx;
-#else
-typedef unsigned char archive_sha384_ctx;
-#endif
-
-#if defined(ARCHIVE_CRYPTO_SHA512_LIBC)
-typedef SHA512_CTX archive_sha512_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC2)
-typedef SHA512_CTX archive_sha512_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
-typedef SHA2_CTX archive_sha512_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
-typedef SHA512_CTX archive_sha512_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
-typedef CC_SHA512_CTX archive_sha512_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS)
-typedef mbedtls_sha512_context archive_sha512_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
-typedef struct sha512_ctx archive_sha512_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
-typedef EVP_MD_CTX *archive_sha512_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA512_WIN)
-typedef Digest_CTX archive_sha512_ctx;
-#else
-typedef unsigned char archive_sha512_ctx;
-#endif
-
-/* defines */
-#if defined(ARCHIVE_CRYPTO_MD5_LIBC) ||\
- defined(ARCHIVE_CRYPTO_MD5_LIBMD) || \
- defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) ||\
- defined(ARCHIVE_CRYPTO_MD5_MBEDTLS) ||\
- defined(ARCHIVE_CRYPTO_MD5_NETTLE) ||\
- defined(ARCHIVE_CRYPTO_MD5_OPENSSL) ||\
- defined(ARCHIVE_CRYPTO_MD5_WIN)
-#define ARCHIVE_HAS_MD5
-#endif
-#define archive_md5_init(ctx)\
- __archive_digest.md5init(ctx)
-#define archive_md5_final(ctx, md)\
- __archive_digest.md5final(ctx, md)
-#define archive_md5_update(ctx, buf, n)\
- __archive_digest.md5update(ctx, buf, n)
-
-#if defined(ARCHIVE_CRYPTO_RMD160_LIBC) ||\
- defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS) ||\
- defined(ARCHIVE_CRYPTO_RMD160_NETTLE) ||\
- defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
-#define ARCHIVE_HAS_RMD160
-#endif
-#define archive_rmd160_init(ctx)\
- __archive_digest.rmd160init(ctx)
-#define archive_rmd160_final(ctx, md)\
- __archive_digest.rmd160final(ctx, md)
-#define archive_rmd160_update(ctx, buf, n)\
- __archive_digest.rmd160update(ctx, buf, n)
-
-#if defined(ARCHIVE_CRYPTO_SHA1_LIBC) ||\
- defined(ARCHIVE_CRYPTO_SHA1_LIBMD) || \
- defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) ||\
- defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS) ||\
- defined(ARCHIVE_CRYPTO_SHA1_NETTLE) ||\
- defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) ||\
- defined(ARCHIVE_CRYPTO_SHA1_WIN)
-#define ARCHIVE_HAS_SHA1
-#endif
-#define archive_sha1_init(ctx)\
- __archive_digest.sha1init(ctx)
-#define archive_sha1_final(ctx, md)\
- __archive_digest.sha1final(ctx, md)
-#define archive_sha1_update(ctx, buf, n)\
- __archive_digest.sha1update(ctx, buf, n)
-
-#if defined(ARCHIVE_CRYPTO_SHA256_LIBC) ||\
- defined(ARCHIVE_CRYPTO_SHA256_LIBC2) ||\
- defined(ARCHIVE_CRYPTO_SHA256_LIBC3) ||\
- defined(ARCHIVE_CRYPTO_SHA256_LIBMD) ||\
- defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) ||\
- defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS) ||\
- defined(ARCHIVE_CRYPTO_SHA256_NETTLE) ||\
- defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) ||\
- defined(ARCHIVE_CRYPTO_SHA256_WIN)
-#define ARCHIVE_HAS_SHA256
-#endif
-#define archive_sha256_init(ctx)\
- __archive_digest.sha256init(ctx)
-#define archive_sha256_final(ctx, md)\
- __archive_digest.sha256final(ctx, md)
-#define archive_sha256_update(ctx, buf, n)\
- __archive_digest.sha256update(ctx, buf, n)
-
-#if defined(ARCHIVE_CRYPTO_SHA384_LIBC) ||\
- defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\
- defined(ARCHIVE_CRYPTO_SHA384_LIBC3) ||\
- defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) ||\
- defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS) ||\
- defined(ARCHIVE_CRYPTO_SHA384_NETTLE) ||\
- defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) ||\
- defined(ARCHIVE_CRYPTO_SHA384_WIN)
-#define ARCHIVE_HAS_SHA384
-#endif
-#define archive_sha384_init(ctx)\
- __archive_digest.sha384init(ctx)
-#define archive_sha384_final(ctx, md)\
- __archive_digest.sha384final(ctx, md)
-#define archive_sha384_update(ctx, buf, n)\
- __archive_digest.sha384update(ctx, buf, n)
-
-#if defined(ARCHIVE_CRYPTO_SHA512_LIBC) ||\
- defined(ARCHIVE_CRYPTO_SHA512_LIBC2) ||\
- defined(ARCHIVE_CRYPTO_SHA512_LIBC3) ||\
- defined(ARCHIVE_CRYPTO_SHA512_LIBMD) ||\
- defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM) ||\
- defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS) ||\
- defined(ARCHIVE_CRYPTO_SHA512_NETTLE) ||\
- defined(ARCHIVE_CRYPTO_SHA512_OPENSSL) ||\
- defined(ARCHIVE_CRYPTO_SHA512_WIN)
-#define ARCHIVE_HAS_SHA512
-#endif
-#define archive_sha512_init(ctx)\
- __archive_digest.sha512init(ctx)
-#define archive_sha512_final(ctx, md)\
- __archive_digest.sha512final(ctx, md)
-#define archive_sha512_update(ctx, buf, n)\
- __archive_digest.sha512update(ctx, buf, n)
-
-/* Minimal interface to digest functionality for internal use in libarchive */
-struct archive_digest
-{
- /* Message Digest */
- int (*md5init)(archive_md5_ctx *ctx);
- int (*md5update)(archive_md5_ctx *, const void *, size_t);
- int (*md5final)(archive_md5_ctx *, void *);
- int (*rmd160init)(archive_rmd160_ctx *);
- int (*rmd160update)(archive_rmd160_ctx *, const void *, size_t);
- int (*rmd160final)(archive_rmd160_ctx *, void *);
- int (*sha1init)(archive_sha1_ctx *);
- int (*sha1update)(archive_sha1_ctx *, const void *, size_t);
- int (*sha1final)(archive_sha1_ctx *, void *);
- int (*sha256init)(archive_sha256_ctx *);
- int (*sha256update)(archive_sha256_ctx *, const void *, size_t);
- int (*sha256final)(archive_sha256_ctx *, void *);
- int (*sha384init)(archive_sha384_ctx *);
- int (*sha384update)(archive_sha384_ctx *, const void *, size_t);
- int (*sha384final)(archive_sha384_ctx *, void *);
- int (*sha512init)(archive_sha512_ctx *);
- int (*sha512update)(archive_sha512_ctx *, const void *, size_t);
- int (*sha512final)(archive_sha512_ctx *, void *);
-};
-
-extern const struct archive_digest __archive_digest;
-
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_endian.h b/contrib/libs/libarchive/libarchive/archive_endian.h
deleted file mode 100644
index e6d3f2ce5e..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_endian.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/*-
- * Copyright (c) 2002 Thomas Moestl <tmm@FreeBSD.org>
- * 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.
- *
- * $FreeBSD: head/lib/libarchive/archive_endian.h 201085 2009-12-28 02:17:15Z kientzle $
- *
- * Borrowed from FreeBSD's <sys/endian.h>
- */
-
-#ifndef ARCHIVE_ENDIAN_H_INCLUDED
-#define ARCHIVE_ENDIAN_H_INCLUDED
-
-/* Note: This is a purely internal header! */
-/* Do not use this outside of libarchive internal code! */
-
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
-/*
- * Disabling inline keyword for compilers known to choke on it:
- * - Watcom C++ in C code. (For any version?)
- * - SGI MIPSpro
- * - Microsoft Visual C++ 6.0 (supposedly newer versions too)
- * - IBM VisualAge 6 (XL v6)
- * - Sun WorkShop C (SunPro) before 5.9
- */
-#if defined(__WATCOMC__) || defined(__sgi) || defined(__hpux) || defined(__BORLANDC__)
-#define inline
-#elif defined(__IBMC__) && __IBMC__ < 700
-#define inline
-#elif defined(__SUNPRO_C) && __SUNPRO_C < 0x590
-#define inline
-#elif defined(_MSC_VER) || defined(__osf__)
-#define inline __inline
-#endif
-
-/* Alignment-agnostic encode/decode bytestream to/from little/big endian. */
-
-static inline uint16_t
-archive_be16dec(const void *pp)
-{
- unsigned char const *p = (unsigned char const *)pp;
-
- /* Store into unsigned temporaries before left shifting, to avoid
- promotion to signed int and then left shifting into the sign bit,
- which is undefined behaviour. */
- unsigned int p1 = p[1];
- unsigned int p0 = p[0];
-
- return ((p0 << 8) | p1);
-}
-
-static inline uint32_t
-archive_be32dec(const void *pp)
-{
- unsigned char const *p = (unsigned char const *)pp;
-
- /* Store into unsigned temporaries before left shifting, to avoid
- promotion to signed int and then left shifting into the sign bit,
- which is undefined behaviour. */
- unsigned int p3 = p[3];
- unsigned int p2 = p[2];
- unsigned int p1 = p[1];
- unsigned int p0 = p[0];
-
- return ((p0 << 24) | (p1 << 16) | (p2 << 8) | p3);
-}
-
-static inline uint64_t
-archive_be64dec(const void *pp)
-{
- unsigned char const *p = (unsigned char const *)pp;
-
- return (((uint64_t)archive_be32dec(p) << 32) | archive_be32dec(p + 4));
-}
-
-static inline uint16_t
-archive_le16dec(const void *pp)
-{
- unsigned char const *p = (unsigned char const *)pp;
-
- /* Store into unsigned temporaries before left shifting, to avoid
- promotion to signed int and then left shifting into the sign bit,
- which is undefined behaviour. */
- unsigned int p1 = p[1];
- unsigned int p0 = p[0];
-
- return ((p1 << 8) | p0);
-}
-
-static inline uint32_t
-archive_le32dec(const void *pp)
-{
- unsigned char const *p = (unsigned char const *)pp;
-
- /* Store into unsigned temporaries before left shifting, to avoid
- promotion to signed int and then left shifting into the sign bit,
- which is undefined behaviour. */
- unsigned int p3 = p[3];
- unsigned int p2 = p[2];
- unsigned int p1 = p[1];
- unsigned int p0 = p[0];
-
- return ((p3 << 24) | (p2 << 16) | (p1 << 8) | p0);
-}
-
-static inline uint64_t
-archive_le64dec(const void *pp)
-{
- unsigned char const *p = (unsigned char const *)pp;
-
- return (((uint64_t)archive_le32dec(p + 4) << 32) | archive_le32dec(p));
-}
-
-static inline void
-archive_be16enc(void *pp, uint16_t u)
-{
- unsigned char *p = (unsigned char *)pp;
-
- p[0] = (u >> 8) & 0xff;
- p[1] = u & 0xff;
-}
-
-static inline void
-archive_be32enc(void *pp, uint32_t u)
-{
- unsigned char *p = (unsigned char *)pp;
-
- p[0] = (u >> 24) & 0xff;
- p[1] = (u >> 16) & 0xff;
- p[2] = (u >> 8) & 0xff;
- p[3] = u & 0xff;
-}
-
-static inline void
-archive_be64enc(void *pp, uint64_t u)
-{
- unsigned char *p = (unsigned char *)pp;
-
- archive_be32enc(p, (uint32_t)(u >> 32));
- archive_be32enc(p + 4, (uint32_t)(u & 0xffffffff));
-}
-
-static inline void
-archive_le16enc(void *pp, uint16_t u)
-{
- unsigned char *p = (unsigned char *)pp;
-
- p[0] = u & 0xff;
- p[1] = (u >> 8) & 0xff;
-}
-
-static inline void
-archive_le32enc(void *pp, uint32_t u)
-{
- unsigned char *p = (unsigned char *)pp;
-
- p[0] = u & 0xff;
- p[1] = (u >> 8) & 0xff;
- p[2] = (u >> 16) & 0xff;
- p[3] = (u >> 24) & 0xff;
-}
-
-static inline void
-archive_le64enc(void *pp, uint64_t u)
-{
- unsigned char *p = (unsigned char *)pp;
-
- archive_le32enc(p, (uint32_t)(u & 0xffffffff));
- archive_le32enc(p + 4, (uint32_t)(u >> 32));
-}
-
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_entry.c b/contrib/libs/libarchive/libarchive/archive_entry.c
deleted file mode 100644
index a938fd7176..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_entry.c
+++ /dev/null
@@ -1,2149 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * Copyright (c) 2016 Martin Matuska
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry.c 201096 2009-12-28 02:41:27Z kientzle $");
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#if MAJOR_IN_MKDEV
-#include <sys/mkdev.h>
-#define HAVE_MAJOR
-#elif MAJOR_IN_SYSMACROS
-#include <sys/sysmacros.h>
-#define HAVE_MAJOR
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-#ifdef HAVE_LINUX_FS_H
-#include <linux/fs.h> /* for Linux file flags */
-#endif
-/*
- * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
- * As the include guards don't agree, the order of include is important.
- */
-#ifdef HAVE_LINUX_EXT2_FS_H
-#error #include <linux/ext2_fs.h> /* for Linux file flags */
-#endif
-#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
-#error #include <ext2fs/ext2_fs.h> /* for Linux file flags */
-#endif
-#include <stddef.h>
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_WCHAR_H
-#include <wchar.h>
-#endif
-
-#include "archive.h"
-#include "archive_acl_private.h"
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_private.h"
-#include "archive_entry_private.h"
-
-#if !defined(HAVE_MAJOR) && !defined(major)
-/* Replacement for major/minor/makedev. */
-#define major(x) ((int)(0x00ff & ((x) >> 8)))
-#define minor(x) ((int)(0xffff00ff & (x)))
-#define makedev(maj,min) ((0xff00 & ((maj)<<8)) | (0xffff00ff & (min)))
-#endif
-
-/* Play games to come up with a suitable makedev() definition. */
-#ifdef __QNXNTO__
-/* QNX. <sigh> */
-#error #include <sys/netmgr.h>
-#define ae_makedev(maj, min) makedev(ND_LOCAL_NODE, (maj), (min))
-#elif defined makedev
-/* There's a "makedev" macro. */
-#define ae_makedev(maj, min) makedev((maj), (min))
-#elif defined mkdev || ((defined _WIN32 || defined __WIN32__) && !defined(__CYGWIN__))
-/* Windows. <sigh> */
-#define ae_makedev(maj, min) mkdev((maj), (min))
-#else
-/* There's a "makedev" function. */
-#define ae_makedev(maj, min) makedev((maj), (min))
-#endif
-
-/*
- * This adjustment is needed to support the following idiom for adding
- * 1000ns to the stored time:
- * archive_entry_set_atime(archive_entry_atime(),
- * archive_entry_atime_nsec() + 1000)
- * The additional if() here compensates for ambiguity in the C standard,
- * which permits two possible interpretations of a % b when a is negative.
- */
-#define FIX_NS(t,ns) \
- do { \
- t += ns / 1000000000; \
- ns %= 1000000000; \
- if (ns < 0) { --t; ns += 1000000000; } \
- } while (0)
-
-static char * ae_fflagstostr(unsigned long bitset, unsigned long bitclear);
-static const wchar_t *ae_wcstofflags(const wchar_t *stringp,
- unsigned long *setp, unsigned long *clrp);
-static const char *ae_strtofflags(const char *stringp,
- unsigned long *setp, unsigned long *clrp);
-
-#ifndef HAVE_WCSCPY
-static wchar_t * wcscpy(wchar_t *s1, const wchar_t *s2)
-{
- wchar_t *dest = s1;
- while ((*s1 = *s2) != L'\0')
- ++s1, ++s2;
- return dest;
-}
-#endif
-#ifndef HAVE_WCSLEN
-static size_t wcslen(const wchar_t *s)
-{
- const wchar_t *p = s;
- while (*p != L'\0')
- ++p;
- return p - s;
-}
-#endif
-#ifndef HAVE_WMEMCMP
-/* Good enough for simple equality testing, but not for sorting. */
-#define wmemcmp(a,b,i) memcmp((a), (b), (i) * sizeof(wchar_t))
-#endif
-
-/****************************************************************************
- *
- * Public Interface
- *
- ****************************************************************************/
-
-struct archive_entry *
-archive_entry_clear(struct archive_entry *entry)
-{
- if (entry == NULL)
- return (NULL);
- archive_mstring_clean(&entry->ae_fflags_text);
- archive_mstring_clean(&entry->ae_gname);
- archive_mstring_clean(&entry->ae_hardlink);
- archive_mstring_clean(&entry->ae_pathname);
- archive_mstring_clean(&entry->ae_sourcepath);
- archive_mstring_clean(&entry->ae_symlink);
- archive_mstring_clean(&entry->ae_uname);
- archive_entry_copy_mac_metadata(entry, NULL, 0);
- archive_acl_clear(&entry->acl);
- archive_entry_xattr_clear(entry);
- archive_entry_sparse_clear(entry);
- free(entry->stat);
- entry->ae_symlink_type = AE_SYMLINK_TYPE_UNDEFINED;
- memset(entry, 0, sizeof(*entry));
- return entry;
-}
-
-struct archive_entry *
-archive_entry_clone(struct archive_entry *entry)
-{
- struct archive_entry *entry2;
- struct ae_xattr *xp;
- struct ae_sparse *sp;
- size_t s;
- const void *p;
-
- /* Allocate new structure and copy over all of the fields. */
- /* TODO: Should we copy the archive over? Or require a new archive
- * as an argument? */
- entry2 = archive_entry_new2(entry->archive);
- if (entry2 == NULL)
- return (NULL);
- entry2->ae_stat = entry->ae_stat;
- entry2->ae_fflags_set = entry->ae_fflags_set;
- entry2->ae_fflags_clear = entry->ae_fflags_clear;
-
- /* TODO: XXX If clone can have a different archive, what do we do here if
- * character sets are different? XXX */
- archive_mstring_copy(&entry2->ae_fflags_text, &entry->ae_fflags_text);
- archive_mstring_copy(&entry2->ae_gname, &entry->ae_gname);
- archive_mstring_copy(&entry2->ae_hardlink, &entry->ae_hardlink);
- archive_mstring_copy(&entry2->ae_pathname, &entry->ae_pathname);
- archive_mstring_copy(&entry2->ae_sourcepath, &entry->ae_sourcepath);
- archive_mstring_copy(&entry2->ae_symlink, &entry->ae_symlink);
- entry2->ae_set = entry->ae_set;
- archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname);
-
- /* Copy symlink type */
- entry2->ae_symlink_type = entry->ae_symlink_type;
-
- /* Copy encryption status */
- entry2->encryption = entry->encryption;
-
- /* Copy digests */
-#define copy_digest(_e2, _e, _t) \
- memcpy(_e2->digest._t, _e->digest._t, sizeof(_e2->digest._t))
-
- copy_digest(entry2, entry, md5);
- copy_digest(entry2, entry, rmd160);
- copy_digest(entry2, entry, sha1);
- copy_digest(entry2, entry, sha256);
- copy_digest(entry2, entry, sha384);
- copy_digest(entry2, entry, sha512);
-
-#undef copy_digest
-
- /* Copy ACL data over. */
- archive_acl_copy(&entry2->acl, &entry->acl);
-
- /* Copy Mac OS metadata. */
- p = archive_entry_mac_metadata(entry, &s);
- archive_entry_copy_mac_metadata(entry2, p, s);
-
- /* Copy xattr data over. */
- xp = entry->xattr_head;
- while (xp != NULL) {
- archive_entry_xattr_add_entry(entry2,
- xp->name, xp->value, xp->size);
- xp = xp->next;
- }
-
- /* Copy sparse data over. */
- sp = entry->sparse_head;
- while (sp != NULL) {
- archive_entry_sparse_add_entry(entry2,
- sp->offset, sp->length);
- sp = sp->next;
- }
-
- return (entry2);
-}
-
-void
-archive_entry_free(struct archive_entry *entry)
-{
- archive_entry_clear(entry);
- free(entry);
-}
-
-struct archive_entry *
-archive_entry_new(void)
-{
- return archive_entry_new2(NULL);
-}
-
-struct archive_entry *
-archive_entry_new2(struct archive *a)
-{
- struct archive_entry *entry;
-
- entry = (struct archive_entry *)calloc(1, sizeof(*entry));
- if (entry == NULL)
- return (NULL);
- entry->archive = a;
- entry->ae_symlink_type = AE_SYMLINK_TYPE_UNDEFINED;
- return (entry);
-}
-
-/*
- * Functions for reading fields from an archive_entry.
- */
-
-time_t
-archive_entry_atime(struct archive_entry *entry)
-{
- return (entry->ae_stat.aest_atime);
-}
-
-long
-archive_entry_atime_nsec(struct archive_entry *entry)
-{
- return (entry->ae_stat.aest_atime_nsec);
-}
-
-int
-archive_entry_atime_is_set(struct archive_entry *entry)
-{
- return (entry->ae_set & AE_SET_ATIME);
-}
-
-time_t
-archive_entry_birthtime(struct archive_entry *entry)
-{
- return (entry->ae_stat.aest_birthtime);
-}
-
-long
-archive_entry_birthtime_nsec(struct archive_entry *entry)
-{
- return (entry->ae_stat.aest_birthtime_nsec);
-}
-
-int
-archive_entry_birthtime_is_set(struct archive_entry *entry)
-{
- return (entry->ae_set & AE_SET_BIRTHTIME);
-}
-
-time_t
-archive_entry_ctime(struct archive_entry *entry)
-{
- return (entry->ae_stat.aest_ctime);
-}
-
-int
-archive_entry_ctime_is_set(struct archive_entry *entry)
-{
- return (entry->ae_set & AE_SET_CTIME);
-}
-
-long
-archive_entry_ctime_nsec(struct archive_entry *entry)
-{
- return (entry->ae_stat.aest_ctime_nsec);
-}
-
-dev_t
-archive_entry_dev(struct archive_entry *entry)
-{
- if (entry->ae_stat.aest_dev_is_broken_down)
- return ae_makedev(entry->ae_stat.aest_devmajor,
- entry->ae_stat.aest_devminor);
- else
- return (entry->ae_stat.aest_dev);
-}
-
-int
-archive_entry_dev_is_set(struct archive_entry *entry)
-{
- return (entry->ae_set & AE_SET_DEV);
-}
-
-dev_t
-archive_entry_devmajor(struct archive_entry *entry)
-{
- if (entry->ae_stat.aest_dev_is_broken_down)
- return (entry->ae_stat.aest_devmajor);
- else
- return major(entry->ae_stat.aest_dev);
-}
-
-dev_t
-archive_entry_devminor(struct archive_entry *entry)
-{
- if (entry->ae_stat.aest_dev_is_broken_down)
- return (entry->ae_stat.aest_devminor);
- else
- return minor(entry->ae_stat.aest_dev);
-}
-
-__LA_MODE_T
-archive_entry_filetype(struct archive_entry *entry)
-{
- return (AE_IFMT & entry->acl.mode);
-}
-
-void
-archive_entry_fflags(struct archive_entry *entry,
- unsigned long *set, unsigned long *clear)
-{
- *set = entry->ae_fflags_set;
- *clear = entry->ae_fflags_clear;
-}
-
-/*
- * Note: if text was provided, this just returns that text. If you
- * really need the text to be rebuilt in a canonical form, set the
- * text, ask for the bitmaps, then set the bitmaps. (Setting the
- * bitmaps clears any stored text.) This design is deliberate: if
- * we're editing archives, we don't want to discard flags just because
- * they aren't supported on the current system. The bitmap<->text
- * conversions are platform-specific (see below).
- */
-const char *
-archive_entry_fflags_text(struct archive_entry *entry)
-{
- const char *f;
- char *p;
-
- if (archive_mstring_get_mbs(entry->archive,
- &entry->ae_fflags_text, &f) == 0) {
- if (f != NULL)
- return (f);
- } else if (errno == ENOMEM)
- __archive_errx(1, "No memory");
-
- if (entry->ae_fflags_set == 0 && entry->ae_fflags_clear == 0)
- return (NULL);
-
- p = ae_fflagstostr(entry->ae_fflags_set, entry->ae_fflags_clear);
- if (p == NULL)
- return (NULL);
-
- archive_mstring_copy_mbs(&entry->ae_fflags_text, p);
- free(p);
- if (archive_mstring_get_mbs(entry->archive,
- &entry->ae_fflags_text, &f) == 0)
- return (f);
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (NULL);
-}
-
-la_int64_t
-archive_entry_gid(struct archive_entry *entry)
-{
- return (entry->ae_stat.aest_gid);
-}
-
-const char *
-archive_entry_gname(struct archive_entry *entry)
-{
- const char *p;
- if (archive_mstring_get_mbs(entry->archive, &entry->ae_gname, &p) == 0)
- return (p);
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (NULL);
-}
-
-const char *
-archive_entry_gname_utf8(struct archive_entry *entry)
-{
- const char *p;
- if (archive_mstring_get_utf8(entry->archive, &entry->ae_gname, &p) == 0)
- return (p);
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (NULL);
-}
-
-
-const wchar_t *
-archive_entry_gname_w(struct archive_entry *entry)
-{
- const wchar_t *p;
- if (archive_mstring_get_wcs(entry->archive, &entry->ae_gname, &p) == 0)
- return (p);
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (NULL);
-}
-
-int
-_archive_entry_gname_l(struct archive_entry *entry,
- const char **p, size_t *len, struct archive_string_conv *sc)
-{
- return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_gname, p, len, sc));
-}
-
-const char *
-archive_entry_hardlink(struct archive_entry *entry)
-{
- const char *p;
- if ((entry->ae_set & AE_SET_HARDLINK) == 0)
- return (NULL);
- if (archive_mstring_get_mbs(
- entry->archive, &entry->ae_hardlink, &p) == 0)
- return (p);
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (NULL);
-}
-
-const char *
-archive_entry_hardlink_utf8(struct archive_entry *entry)
-{
- const char *p;
- if ((entry->ae_set & AE_SET_HARDLINK) == 0)
- return (NULL);
- if (archive_mstring_get_utf8(
- entry->archive, &entry->ae_hardlink, &p) == 0)
- return (p);
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (NULL);
-}
-
-const wchar_t *
-archive_entry_hardlink_w(struct archive_entry *entry)
-{
- const wchar_t *p;
- if ((entry->ae_set & AE_SET_HARDLINK) == 0)
- return (NULL);
- if (archive_mstring_get_wcs(
- entry->archive, &entry->ae_hardlink, &p) == 0)
- return (p);
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (NULL);
-}
-
-int
-_archive_entry_hardlink_l(struct archive_entry *entry,
- const char **p, size_t *len, struct archive_string_conv *sc)
-{
- if ((entry->ae_set & AE_SET_HARDLINK) == 0) {
- *p = NULL;
- *len = 0;
- return (0);
- }
- return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_hardlink, p, len, sc));
-}
-
-la_int64_t
-archive_entry_ino(struct archive_entry *entry)
-{
- return (entry->ae_stat.aest_ino);
-}
-
-int
-archive_entry_ino_is_set(struct archive_entry *entry)
-{
- return (entry->ae_set & AE_SET_INO);
-}
-
-la_int64_t
-archive_entry_ino64(struct archive_entry *entry)
-{
- return (entry->ae_stat.aest_ino);
-}
-
-__LA_MODE_T
-archive_entry_mode(struct archive_entry *entry)
-{
- return (entry->acl.mode);
-}
-
-time_t
-archive_entry_mtime(struct archive_entry *entry)
-{
- return (entry->ae_stat.aest_mtime);
-}
-
-long
-archive_entry_mtime_nsec(struct archive_entry *entry)
-{
- return (entry->ae_stat.aest_mtime_nsec);
-}
-
-int
-archive_entry_mtime_is_set(struct archive_entry *entry)
-{
- return (entry->ae_set & AE_SET_MTIME);
-}
-
-unsigned int
-archive_entry_nlink(struct archive_entry *entry)
-{
- return (entry->ae_stat.aest_nlink);
-}
-
-/* Instead, our caller could have chosen a specific encoding
- * (archive_mstring_get_mbs, archive_mstring_get_utf8,
- * archive_mstring_get_wcs). So we should try multiple
- * encodings. Try mbs first because of history, even though
- * utf8 might be better for pathname portability.
- * Also omit wcs because of type mismatch (char * versus wchar *)
- */
-const char *
-archive_entry_pathname(struct archive_entry *entry)
-{
- const char *p;
- if (archive_mstring_get_mbs(
- entry->archive, &entry->ae_pathname, &p) == 0)
- return (p);
-#if HAVE_EILSEQ /*{*/
- if (errno == EILSEQ) {
- if (archive_mstring_get_utf8(
- entry->archive, &entry->ae_pathname, &p) == 0)
- return (p);
- }
-#endif /*}*/
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (NULL);
-}
-
-const char *
-archive_entry_pathname_utf8(struct archive_entry *entry)
-{
- const char *p;
- if (archive_mstring_get_utf8(
- entry->archive, &entry->ae_pathname, &p) == 0)
- return (p);
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (NULL);
-}
-
-const wchar_t *
-archive_entry_pathname_w(struct archive_entry *entry)
-{
- const wchar_t *p;
- if (archive_mstring_get_wcs(
- entry->archive, &entry->ae_pathname, &p) == 0)
- return (p);
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (NULL);
-}
-
-int
-_archive_entry_pathname_l(struct archive_entry *entry,
- const char **p, size_t *len, struct archive_string_conv *sc)
-{
- return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_pathname, p, len, sc));
-}
-
-__LA_MODE_T
-archive_entry_perm(struct archive_entry *entry)
-{
- return (~AE_IFMT & entry->acl.mode);
-}
-
-dev_t
-archive_entry_rdev(struct archive_entry *entry)
-{
- if (entry->ae_stat.aest_rdev_is_broken_down)
- return ae_makedev(entry->ae_stat.aest_rdevmajor,
- entry->ae_stat.aest_rdevminor);
- else
- return (entry->ae_stat.aest_rdev);
-}
-
-dev_t
-archive_entry_rdevmajor(struct archive_entry *entry)
-{
- if (entry->ae_stat.aest_rdev_is_broken_down)
- return (entry->ae_stat.aest_rdevmajor);
- else
- return major(entry->ae_stat.aest_rdev);
-}
-
-dev_t
-archive_entry_rdevminor(struct archive_entry *entry)
-{
- if (entry->ae_stat.aest_rdev_is_broken_down)
- return (entry->ae_stat.aest_rdevminor);
- else
- return minor(entry->ae_stat.aest_rdev);
-}
-
-la_int64_t
-archive_entry_size(struct archive_entry *entry)
-{
- return (entry->ae_stat.aest_size);
-}
-
-int
-archive_entry_size_is_set(struct archive_entry *entry)
-{
- return (entry->ae_set & AE_SET_SIZE);
-}
-
-const char *
-archive_entry_sourcepath(struct archive_entry *entry)
-{
- const char *p;
- if (archive_mstring_get_mbs(
- entry->archive, &entry->ae_sourcepath, &p) == 0)
- return (p);
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (NULL);
-}
-
-const wchar_t *
-archive_entry_sourcepath_w(struct archive_entry *entry)
-{
- const wchar_t *p;
- if (archive_mstring_get_wcs(
- entry->archive, &entry->ae_sourcepath, &p) == 0)
- return (p);
- return (NULL);
-}
-
-const char *
-archive_entry_symlink(struct archive_entry *entry)
-{
- const char *p;
- if ((entry->ae_set & AE_SET_SYMLINK) == 0)
- return (NULL);
- if (archive_mstring_get_mbs(
- entry->archive, &entry->ae_symlink, &p) == 0)
- return (p);
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (NULL);
-}
-
-int
-archive_entry_symlink_type(struct archive_entry *entry)
-{
- return (entry->ae_symlink_type);
-}
-
-const char *
-archive_entry_symlink_utf8(struct archive_entry *entry)
-{
- const char *p;
- if ((entry->ae_set & AE_SET_SYMLINK) == 0)
- return (NULL);
- if (archive_mstring_get_utf8(
- entry->archive, &entry->ae_symlink, &p) == 0)
- return (p);
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (NULL);
-}
-
-const wchar_t *
-archive_entry_symlink_w(struct archive_entry *entry)
-{
- const wchar_t *p;
- if ((entry->ae_set & AE_SET_SYMLINK) == 0)
- return (NULL);
- if (archive_mstring_get_wcs(
- entry->archive, &entry->ae_symlink, &p) == 0)
- return (p);
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (NULL);
-}
-
-int
-_archive_entry_symlink_l(struct archive_entry *entry,
- const char **p, size_t *len, struct archive_string_conv *sc)
-{
- if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
- *p = NULL;
- *len = 0;
- return (0);
- }
- return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_symlink, p, len, sc));
-}
-
-la_int64_t
-archive_entry_uid(struct archive_entry *entry)
-{
- return (entry->ae_stat.aest_uid);
-}
-
-const char *
-archive_entry_uname(struct archive_entry *entry)
-{
- const char *p;
- if (archive_mstring_get_mbs(entry->archive, &entry->ae_uname, &p) == 0)
- return (p);
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (NULL);
-}
-
-const char *
-archive_entry_uname_utf8(struct archive_entry *entry)
-{
- const char *p;
- if (archive_mstring_get_utf8(entry->archive, &entry->ae_uname, &p) == 0)
- return (p);
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (NULL);
-}
-
-const wchar_t *
-archive_entry_uname_w(struct archive_entry *entry)
-{
- const wchar_t *p;
- if (archive_mstring_get_wcs(entry->archive, &entry->ae_uname, &p) == 0)
- return (p);
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (NULL);
-}
-
-int
-_archive_entry_uname_l(struct archive_entry *entry,
- const char **p, size_t *len, struct archive_string_conv *sc)
-{
- return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_uname, p, len, sc));
-}
-
-int
-archive_entry_is_data_encrypted(struct archive_entry *entry)
-{
- return ((entry->encryption & AE_ENCRYPTION_DATA) == AE_ENCRYPTION_DATA);
-}
-
-int
-archive_entry_is_metadata_encrypted(struct archive_entry *entry)
-{
- return ((entry->encryption & AE_ENCRYPTION_METADATA) == AE_ENCRYPTION_METADATA);
-}
-
-int
-archive_entry_is_encrypted(struct archive_entry *entry)
-{
- return (entry->encryption & (AE_ENCRYPTION_DATA|AE_ENCRYPTION_METADATA));
-}
-
-/*
- * Functions to set archive_entry properties.
- */
-
-void
-archive_entry_set_filetype(struct archive_entry *entry, unsigned int type)
-{
- entry->stat_valid = 0;
- entry->acl.mode &= ~AE_IFMT;
- entry->acl.mode |= AE_IFMT & type;
-}
-
-void
-archive_entry_set_fflags(struct archive_entry *entry,
- unsigned long set, unsigned long clear)
-{
- archive_mstring_clean(&entry->ae_fflags_text);
- entry->ae_fflags_set = set;
- entry->ae_fflags_clear = clear;
-}
-
-const char *
-archive_entry_copy_fflags_text(struct archive_entry *entry,
- const char *flags)
-{
- archive_mstring_copy_mbs(&entry->ae_fflags_text, flags);
- return (ae_strtofflags(flags,
- &entry->ae_fflags_set, &entry->ae_fflags_clear));
-}
-
-const wchar_t *
-archive_entry_copy_fflags_text_w(struct archive_entry *entry,
- const wchar_t *flags)
-{
- archive_mstring_copy_wcs(&entry->ae_fflags_text, flags);
- return (ae_wcstofflags(flags,
- &entry->ae_fflags_set, &entry->ae_fflags_clear));
-}
-
-void
-archive_entry_set_gid(struct archive_entry *entry, la_int64_t g)
-{
- entry->stat_valid = 0;
- entry->ae_stat.aest_gid = g;
-}
-
-void
-archive_entry_set_gname(struct archive_entry *entry, const char *name)
-{
- archive_mstring_copy_mbs(&entry->ae_gname, name);
-}
-
-void
-archive_entry_set_gname_utf8(struct archive_entry *entry, const char *name)
-{
- archive_mstring_copy_utf8(&entry->ae_gname, name);
-}
-
-void
-archive_entry_copy_gname(struct archive_entry *entry, const char *name)
-{
- archive_mstring_copy_mbs(&entry->ae_gname, name);
-}
-
-void
-archive_entry_copy_gname_w(struct archive_entry *entry, const wchar_t *name)
-{
- archive_mstring_copy_wcs(&entry->ae_gname, name);
-}
-
-int
-archive_entry_update_gname_utf8(struct archive_entry *entry, const char *name)
-{
- if (archive_mstring_update_utf8(entry->archive,
- &entry->ae_gname, name) == 0)
- return (1);
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (0);
-}
-
-int
-_archive_entry_copy_gname_l(struct archive_entry *entry,
- const char *name, size_t len, struct archive_string_conv *sc)
-{
- return (archive_mstring_copy_mbs_len_l(&entry->ae_gname, name, len, sc));
-}
-
-void
-archive_entry_set_ino(struct archive_entry *entry, la_int64_t ino)
-{
- entry->stat_valid = 0;
- entry->ae_set |= AE_SET_INO;
- entry->ae_stat.aest_ino = ino;
-}
-
-void
-archive_entry_set_ino64(struct archive_entry *entry, la_int64_t ino)
-{
- entry->stat_valid = 0;
- entry->ae_set |= AE_SET_INO;
- entry->ae_stat.aest_ino = ino;
-}
-
-void
-archive_entry_set_hardlink(struct archive_entry *entry, const char *target)
-{
- archive_mstring_copy_mbs(&entry->ae_hardlink, target);
- if (target != NULL)
- entry->ae_set |= AE_SET_HARDLINK;
- else
- entry->ae_set &= ~AE_SET_HARDLINK;
-}
-
-void
-archive_entry_set_hardlink_utf8(struct archive_entry *entry, const char *target)
-{
- archive_mstring_copy_utf8(&entry->ae_hardlink, target);
- if (target != NULL)
- entry->ae_set |= AE_SET_HARDLINK;
- else
- entry->ae_set &= ~AE_SET_HARDLINK;
-}
-
-void
-archive_entry_copy_hardlink(struct archive_entry *entry, const char *target)
-{
- archive_mstring_copy_mbs(&entry->ae_hardlink, target);
- if (target != NULL)
- entry->ae_set |= AE_SET_HARDLINK;
- else
- entry->ae_set &= ~AE_SET_HARDLINK;
-}
-
-void
-archive_entry_copy_hardlink_w(struct archive_entry *entry, const wchar_t *target)
-{
- archive_mstring_copy_wcs(&entry->ae_hardlink, target);
- if (target != NULL)
- entry->ae_set |= AE_SET_HARDLINK;
- else
- entry->ae_set &= ~AE_SET_HARDLINK;
-}
-
-int
-archive_entry_update_hardlink_utf8(struct archive_entry *entry, const char *target)
-{
- if (target != NULL)
- entry->ae_set |= AE_SET_HARDLINK;
- else
- entry->ae_set &= ~AE_SET_HARDLINK;
- if (archive_mstring_update_utf8(entry->archive,
- &entry->ae_hardlink, target) == 0)
- return (1);
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (0);
-}
-
-int
-_archive_entry_copy_hardlink_l(struct archive_entry *entry,
- const char *target, size_t len, struct archive_string_conv *sc)
-{
- int r;
-
- r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink,
- target, len, sc);
- if (target != NULL && r == 0)
- entry->ae_set |= AE_SET_HARDLINK;
- else
- entry->ae_set &= ~AE_SET_HARDLINK;
- return (r);
-}
-
-void
-archive_entry_set_atime(struct archive_entry *entry, time_t t, long ns)
-{
- FIX_NS(t, ns);
- entry->stat_valid = 0;
- entry->ae_set |= AE_SET_ATIME;
- entry->ae_stat.aest_atime = t;
- entry->ae_stat.aest_atime_nsec = ns;
-}
-
-void
-archive_entry_unset_atime(struct archive_entry *entry)
-{
- archive_entry_set_atime(entry, 0, 0);
- entry->ae_set &= ~AE_SET_ATIME;
-}
-
-void
-archive_entry_set_birthtime(struct archive_entry *entry, time_t t, long ns)
-{
- FIX_NS(t, ns);
- entry->stat_valid = 0;
- entry->ae_set |= AE_SET_BIRTHTIME;
- entry->ae_stat.aest_birthtime = t;
- entry->ae_stat.aest_birthtime_nsec = ns;
-}
-
-void
-archive_entry_unset_birthtime(struct archive_entry *entry)
-{
- archive_entry_set_birthtime(entry, 0, 0);
- entry->ae_set &= ~AE_SET_BIRTHTIME;
-}
-
-void
-archive_entry_set_ctime(struct archive_entry *entry, time_t t, long ns)
-{
- FIX_NS(t, ns);
- entry->stat_valid = 0;
- entry->ae_set |= AE_SET_CTIME;
- entry->ae_stat.aest_ctime = t;
- entry->ae_stat.aest_ctime_nsec = ns;
-}
-
-void
-archive_entry_unset_ctime(struct archive_entry *entry)
-{
- archive_entry_set_ctime(entry, 0, 0);
- entry->ae_set &= ~AE_SET_CTIME;
-}
-
-void
-archive_entry_set_dev(struct archive_entry *entry, dev_t d)
-{
- entry->stat_valid = 0;
- entry->ae_set |= AE_SET_DEV;
- entry->ae_stat.aest_dev_is_broken_down = 0;
- entry->ae_stat.aest_dev = d;
-}
-
-void
-archive_entry_set_devmajor(struct archive_entry *entry, dev_t m)
-{
- entry->stat_valid = 0;
- entry->ae_set |= AE_SET_DEV;
- entry->ae_stat.aest_dev_is_broken_down = 1;
- entry->ae_stat.aest_devmajor = m;
-}
-
-void
-archive_entry_set_devminor(struct archive_entry *entry, dev_t m)
-{
- entry->stat_valid = 0;
- entry->ae_set |= AE_SET_DEV;
- entry->ae_stat.aest_dev_is_broken_down = 1;
- entry->ae_stat.aest_devminor = m;
-}
-
-/* Set symlink if symlink is already set, else set hardlink. */
-void
-archive_entry_set_link(struct archive_entry *entry, const char *target)
-{
- if (entry->ae_set & AE_SET_SYMLINK)
- archive_mstring_copy_mbs(&entry->ae_symlink, target);
- else
- archive_mstring_copy_mbs(&entry->ae_hardlink, target);
-}
-
-void
-archive_entry_set_link_utf8(struct archive_entry *entry, const char *target)
-{
- if (entry->ae_set & AE_SET_SYMLINK)
- archive_mstring_copy_utf8(&entry->ae_symlink, target);
- else
- archive_mstring_copy_utf8(&entry->ae_hardlink, target);
-}
-
-/* Set symlink if symlink is already set, else set hardlink. */
-void
-archive_entry_copy_link(struct archive_entry *entry, const char *target)
-{
- if (entry->ae_set & AE_SET_SYMLINK)
- archive_mstring_copy_mbs(&entry->ae_symlink, target);
- else
- archive_mstring_copy_mbs(&entry->ae_hardlink, target);
-}
-
-/* Set symlink if symlink is already set, else set hardlink. */
-void
-archive_entry_copy_link_w(struct archive_entry *entry, const wchar_t *target)
-{
- if (entry->ae_set & AE_SET_SYMLINK)
- archive_mstring_copy_wcs(&entry->ae_symlink, target);
- else
- archive_mstring_copy_wcs(&entry->ae_hardlink, target);
-}
-
-int
-archive_entry_update_link_utf8(struct archive_entry *entry, const char *target)
-{
- int r;
- if (entry->ae_set & AE_SET_SYMLINK)
- r = archive_mstring_update_utf8(entry->archive,
- &entry->ae_symlink, target);
- else
- r = archive_mstring_update_utf8(entry->archive,
- &entry->ae_hardlink, target);
- if (r == 0)
- return (1);
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (0);
-}
-
-int
-_archive_entry_copy_link_l(struct archive_entry *entry,
- const char *target, size_t len, struct archive_string_conv *sc)
-{
- int r;
-
- if (entry->ae_set & AE_SET_SYMLINK)
- r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink,
- target, len, sc);
- else
- r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink,
- target, len, sc);
- return (r);
-}
-
-void
-archive_entry_set_mode(struct archive_entry *entry, mode_t m)
-{
- entry->stat_valid = 0;
- entry->acl.mode = m;
-}
-
-void
-archive_entry_set_mtime(struct archive_entry *entry, time_t t, long ns)
-{
- FIX_NS(t, ns);
- entry->stat_valid = 0;
- entry->ae_set |= AE_SET_MTIME;
- entry->ae_stat.aest_mtime = t;
- entry->ae_stat.aest_mtime_nsec = ns;
-}
-
-void
-archive_entry_unset_mtime(struct archive_entry *entry)
-{
- archive_entry_set_mtime(entry, 0, 0);
- entry->ae_set &= ~AE_SET_MTIME;
-}
-
-void
-archive_entry_set_nlink(struct archive_entry *entry, unsigned int nlink)
-{
- entry->stat_valid = 0;
- entry->ae_stat.aest_nlink = nlink;
-}
-
-void
-archive_entry_set_pathname(struct archive_entry *entry, const char *name)
-{
- archive_mstring_copy_mbs(&entry->ae_pathname, name);
-}
-
-void
-archive_entry_set_pathname_utf8(struct archive_entry *entry, const char *name)
-{
- archive_mstring_copy_utf8(&entry->ae_pathname, name);
-}
-
-void
-archive_entry_copy_pathname(struct archive_entry *entry, const char *name)
-{
- archive_mstring_copy_mbs(&entry->ae_pathname, name);
-}
-
-void
-archive_entry_copy_pathname_w(struct archive_entry *entry, const wchar_t *name)
-{
- archive_mstring_copy_wcs(&entry->ae_pathname, name);
-}
-
-int
-archive_entry_update_pathname_utf8(struct archive_entry *entry, const char *name)
-{
- if (archive_mstring_update_utf8(entry->archive,
- &entry->ae_pathname, name) == 0)
- return (1);
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (0);
-}
-
-int
-_archive_entry_copy_pathname_l(struct archive_entry *entry,
- const char *name, size_t len, struct archive_string_conv *sc)
-{
- return (archive_mstring_copy_mbs_len_l(&entry->ae_pathname,
- name, len, sc));
-}
-
-void
-archive_entry_set_perm(struct archive_entry *entry, mode_t p)
-{
- entry->stat_valid = 0;
- entry->acl.mode &= AE_IFMT;
- entry->acl.mode |= ~AE_IFMT & p;
-}
-
-void
-archive_entry_set_rdev(struct archive_entry *entry, dev_t m)
-{
- entry->stat_valid = 0;
- entry->ae_stat.aest_rdev = m;
- entry->ae_stat.aest_rdev_is_broken_down = 0;
-}
-
-void
-archive_entry_set_rdevmajor(struct archive_entry *entry, dev_t m)
-{
- entry->stat_valid = 0;
- entry->ae_stat.aest_rdev_is_broken_down = 1;
- entry->ae_stat.aest_rdevmajor = m;
-}
-
-void
-archive_entry_set_rdevminor(struct archive_entry *entry, dev_t m)
-{
- entry->stat_valid = 0;
- entry->ae_stat.aest_rdev_is_broken_down = 1;
- entry->ae_stat.aest_rdevminor = m;
-}
-
-void
-archive_entry_set_size(struct archive_entry *entry, la_int64_t s)
-{
- entry->stat_valid = 0;
- entry->ae_stat.aest_size = s;
- entry->ae_set |= AE_SET_SIZE;
-}
-
-void
-archive_entry_unset_size(struct archive_entry *entry)
-{
- archive_entry_set_size(entry, 0);
- entry->ae_set &= ~AE_SET_SIZE;
-}
-
-void
-archive_entry_copy_sourcepath(struct archive_entry *entry, const char *path)
-{
- archive_mstring_copy_mbs(&entry->ae_sourcepath, path);
-}
-
-void
-archive_entry_copy_sourcepath_w(struct archive_entry *entry, const wchar_t *path)
-{
- archive_mstring_copy_wcs(&entry->ae_sourcepath, path);
-}
-
-void
-archive_entry_set_symlink(struct archive_entry *entry, const char *linkname)
-{
- archive_mstring_copy_mbs(&entry->ae_symlink, linkname);
- if (linkname != NULL)
- entry->ae_set |= AE_SET_SYMLINK;
- else
- entry->ae_set &= ~AE_SET_SYMLINK;
-}
-
-void
-archive_entry_set_symlink_type(struct archive_entry *entry, int type)
-{
- entry->ae_symlink_type = type;
-}
-
-void
-archive_entry_set_symlink_utf8(struct archive_entry *entry, const char *linkname)
-{
- archive_mstring_copy_utf8(&entry->ae_symlink, linkname);
- if (linkname != NULL)
- entry->ae_set |= AE_SET_SYMLINK;
- else
- entry->ae_set &= ~AE_SET_SYMLINK;
-}
-
-void
-archive_entry_copy_symlink(struct archive_entry *entry, const char *linkname)
-{
- archive_mstring_copy_mbs(&entry->ae_symlink, linkname);
- if (linkname != NULL)
- entry->ae_set |= AE_SET_SYMLINK;
- else
- entry->ae_set &= ~AE_SET_SYMLINK;
-}
-
-void
-archive_entry_copy_symlink_w(struct archive_entry *entry, const wchar_t *linkname)
-{
- archive_mstring_copy_wcs(&entry->ae_symlink, linkname);
- if (linkname != NULL)
- entry->ae_set |= AE_SET_SYMLINK;
- else
- entry->ae_set &= ~AE_SET_SYMLINK;
-}
-
-int
-archive_entry_update_symlink_utf8(struct archive_entry *entry, const char *linkname)
-{
- if (linkname != NULL)
- entry->ae_set |= AE_SET_SYMLINK;
- else
- entry->ae_set &= ~AE_SET_SYMLINK;
- if (archive_mstring_update_utf8(entry->archive,
- &entry->ae_symlink, linkname) == 0)
- return (1);
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (0);
-}
-
-int
-_archive_entry_copy_symlink_l(struct archive_entry *entry,
- const char *linkname, size_t len, struct archive_string_conv *sc)
-{
- int r;
-
- r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink,
- linkname, len, sc);
- if (linkname != NULL && r == 0)
- entry->ae_set |= AE_SET_SYMLINK;
- else
- entry->ae_set &= ~AE_SET_SYMLINK;
- return (r);
-}
-
-void
-archive_entry_set_uid(struct archive_entry *entry, la_int64_t u)
-{
- entry->stat_valid = 0;
- entry->ae_stat.aest_uid = u;
-}
-
-void
-archive_entry_set_uname(struct archive_entry *entry, const char *name)
-{
- archive_mstring_copy_mbs(&entry->ae_uname, name);
-}
-
-void
-archive_entry_set_uname_utf8(struct archive_entry *entry, const char *name)
-{
- archive_mstring_copy_utf8(&entry->ae_uname, name);
-}
-
-void
-archive_entry_copy_uname(struct archive_entry *entry, const char *name)
-{
- archive_mstring_copy_mbs(&entry->ae_uname, name);
-}
-
-void
-archive_entry_copy_uname_w(struct archive_entry *entry, const wchar_t *name)
-{
- archive_mstring_copy_wcs(&entry->ae_uname, name);
-}
-
-int
-archive_entry_update_uname_utf8(struct archive_entry *entry, const char *name)
-{
- if (archive_mstring_update_utf8(entry->archive,
- &entry->ae_uname, name) == 0)
- return (1);
- if (errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (0);
-}
-
-void
-archive_entry_set_is_data_encrypted(struct archive_entry *entry, char is_encrypted)
-{
- if (is_encrypted) {
- entry->encryption |= AE_ENCRYPTION_DATA;
- } else {
- entry->encryption &= ~AE_ENCRYPTION_DATA;
- }
-}
-
-void
-archive_entry_set_is_metadata_encrypted(struct archive_entry *entry, char is_encrypted)
-{
- if (is_encrypted) {
- entry->encryption |= AE_ENCRYPTION_METADATA;
- } else {
- entry->encryption &= ~AE_ENCRYPTION_METADATA;
- }
-}
-
-int
-_archive_entry_copy_uname_l(struct archive_entry *entry,
- const char *name, size_t len, struct archive_string_conv *sc)
-{
- return (archive_mstring_copy_mbs_len_l(&entry->ae_uname,
- name, len, sc));
-}
-
-const void *
-archive_entry_mac_metadata(struct archive_entry *entry, size_t *s)
-{
- *s = entry->mac_metadata_size;
- return entry->mac_metadata;
-}
-
-void
-archive_entry_copy_mac_metadata(struct archive_entry *entry,
- const void *p, size_t s)
-{
- free(entry->mac_metadata);
- if (p == NULL || s == 0) {
- entry->mac_metadata = NULL;
- entry->mac_metadata_size = 0;
- } else {
- entry->mac_metadata_size = s;
- entry->mac_metadata = malloc(s);
- if (entry->mac_metadata == NULL)
- abort();
- memcpy(entry->mac_metadata, p, s);
- }
-}
-
-/* Digest handling */
-const unsigned char *
-archive_entry_digest(struct archive_entry *entry, int type)
-{
- switch (type) {
- case ARCHIVE_ENTRY_DIGEST_MD5:
- return entry->digest.md5;
- case ARCHIVE_ENTRY_DIGEST_RMD160:
- return entry->digest.rmd160;
- case ARCHIVE_ENTRY_DIGEST_SHA1:
- return entry->digest.sha1;
- case ARCHIVE_ENTRY_DIGEST_SHA256:
- return entry->digest.sha256;
- case ARCHIVE_ENTRY_DIGEST_SHA384:
- return entry->digest.sha384;
- case ARCHIVE_ENTRY_DIGEST_SHA512:
- return entry->digest.sha512;
- default:
- return NULL;
- }
-}
-
-int
-archive_entry_set_digest(struct archive_entry *entry, int type,
- const unsigned char *digest)
-{
-#define copy_digest(_e, _t, _d)\
- memcpy(_e->digest._t, _d, sizeof(_e->digest._t))
-
- switch (type) {
- case ARCHIVE_ENTRY_DIGEST_MD5:
- copy_digest(entry, md5, digest);
- break;
- case ARCHIVE_ENTRY_DIGEST_RMD160:
- copy_digest(entry, rmd160, digest);
- break;
- case ARCHIVE_ENTRY_DIGEST_SHA1:
- copy_digest(entry, sha1, digest);
- break;
- case ARCHIVE_ENTRY_DIGEST_SHA256:
- copy_digest(entry, sha256, digest);
- break;
- case ARCHIVE_ENTRY_DIGEST_SHA384:
- copy_digest(entry, sha384, digest);
- break;
- case ARCHIVE_ENTRY_DIGEST_SHA512:
- copy_digest(entry, sha512, digest);
- break;
- default:
- return ARCHIVE_WARN;
- }
-
- return ARCHIVE_OK;
-#undef copy_digest
-}
-
-/*
- * ACL management. The following would, of course, be a lot simpler
- * if: 1) the last draft of POSIX.1e were a really thorough and
- * complete standard that addressed the needs of ACL archiving and 2)
- * everyone followed it faithfully. Alas, neither is true, so the
- * following is a lot more complex than might seem necessary to the
- * uninitiated.
- */
-
-struct archive_acl *
-archive_entry_acl(struct archive_entry *entry)
-{
- return &entry->acl;
-}
-
-void
-archive_entry_acl_clear(struct archive_entry *entry)
-{
- archive_acl_clear(&entry->acl);
-}
-
-/*
- * Add a single ACL entry to the internal list of ACL data.
- */
-int
-archive_entry_acl_add_entry(struct archive_entry *entry,
- int type, int permset, int tag, int id, const char *name)
-{
- return archive_acl_add_entry(&entry->acl, type, permset, tag, id, name);
-}
-
-/*
- * As above, but with a wide-character name.
- */
-int
-archive_entry_acl_add_entry_w(struct archive_entry *entry,
- int type, int permset, int tag, int id, const wchar_t *name)
-{
- return archive_acl_add_entry_w_len(&entry->acl,
- type, permset, tag, id, name, wcslen(name));
-}
-
-/*
- * Return a bitmask of ACL types in an archive entry ACL list
- */
-int
-archive_entry_acl_types(struct archive_entry *entry)
-{
- return (archive_acl_types(&entry->acl));
-}
-
-/*
- * Return a count of entries matching "want_type".
- */
-int
-archive_entry_acl_count(struct archive_entry *entry, int want_type)
-{
- return archive_acl_count(&entry->acl, want_type);
-}
-
-/*
- * Prepare for reading entries from the ACL data. Returns a count
- * of entries matching "want_type", or zero if there are no
- * non-extended ACL entries of that type.
- */
-int
-archive_entry_acl_reset(struct archive_entry *entry, int want_type)
-{
- return archive_acl_reset(&entry->acl, want_type);
-}
-
-/*
- * Return the next ACL entry in the list. Fake entries for the
- * standard permissions and include them in the returned list.
- */
-int
-archive_entry_acl_next(struct archive_entry *entry, int want_type, int *type,
- int *permset, int *tag, int *id, const char **name)
-{
- int r;
- r = archive_acl_next(entry->archive, &entry->acl, want_type, type,
- permset, tag, id, name);
- if (r == ARCHIVE_FATAL && errno == ENOMEM)
- __archive_errx(1, "No memory");
- return (r);
-}
-
-/*
- * Generate a text version of the ACL. The flags parameter controls
- * the style of the generated ACL.
- */
-wchar_t *
-archive_entry_acl_to_text_w(struct archive_entry *entry, la_ssize_t *len,
- int flags)
-{
- return (archive_acl_to_text_w(&entry->acl, len, flags,
- entry->archive));
-}
-
-char *
-archive_entry_acl_to_text(struct archive_entry *entry, la_ssize_t *len,
- int flags)
-{
- return (archive_acl_to_text_l(&entry->acl, len, flags, NULL));
-}
-
-char *
-_archive_entry_acl_to_text_l(struct archive_entry *entry, ssize_t *len,
- int flags, struct archive_string_conv *sc)
-{
- return (archive_acl_to_text_l(&entry->acl, len, flags, sc));
-}
-
-/*
- * ACL text parser.
- */
-int
-archive_entry_acl_from_text_w(struct archive_entry *entry,
- const wchar_t *wtext, int type)
-{
- return (archive_acl_from_text_w(&entry->acl, wtext, type));
-}
-
-int
-archive_entry_acl_from_text(struct archive_entry *entry,
- const char *text, int type)
-{
- return (archive_acl_from_text_l(&entry->acl, text, type, NULL));
-}
-
-int
-_archive_entry_acl_from_text_l(struct archive_entry *entry, const char *text,
- int type, struct archive_string_conv *sc)
-{
- return (archive_acl_from_text_l(&entry->acl, text, type, sc));
-}
-
-/* Deprecated */
-static int
-archive_entry_acl_text_compat(int *flags)
-{
- if ((*flags & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) == 0)
- return (1);
-
- /* ABI compat with old ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID */
- if ((*flags & OLD_ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID) != 0)
- *flags |= ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID;
-
- /* ABI compat with old ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT */
- if ((*flags & OLD_ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) != 0)
- *flags |= ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT;
-
- *flags |= ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA;
-
- return (0);
-}
-
-/* Deprecated */
-const wchar_t *
-archive_entry_acl_text_w(struct archive_entry *entry, int flags)
-{
- free(entry->acl.acl_text_w);
- entry->acl.acl_text_w = NULL;
- if (archive_entry_acl_text_compat(&flags) == 0)
- entry->acl.acl_text_w = archive_acl_to_text_w(&entry->acl,
- NULL, flags, entry->archive);
- return (entry->acl.acl_text_w);
-}
-
-/* Deprecated */
-const char *
-archive_entry_acl_text(struct archive_entry *entry, int flags)
-{
- free(entry->acl.acl_text);
- entry->acl.acl_text = NULL;
- if (archive_entry_acl_text_compat(&flags) == 0)
- entry->acl.acl_text = archive_acl_to_text_l(&entry->acl, NULL,
- flags, NULL);
-
- return (entry->acl.acl_text);
-}
-
-/* Deprecated */
-int
-_archive_entry_acl_text_l(struct archive_entry *entry, int flags,
- const char **acl_text, size_t *len, struct archive_string_conv *sc)
-{
- free(entry->acl.acl_text);
- entry->acl.acl_text = NULL;
-
- if (archive_entry_acl_text_compat(&flags) == 0)
- entry->acl.acl_text = archive_acl_to_text_l(&entry->acl,
- (ssize_t *)len, flags, sc);
-
- *acl_text = entry->acl.acl_text;
-
- return (0);
-}
-
-/*
- * Following code is modified from UC Berkeley sources, and
- * is subject to the following copyright notice.
- */
-
-/*-
- * Copyright (c) 1993
- * The Regents of the University of California. 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.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
- */
-
-/*
- * Supported file flags on FreeBSD and Mac OS:
- * sappnd,sappend SF_APPEND
- * arch,archived SF_ARCHIVED
- * schg,schange,simmutable SF_IMMUTABLE
- * sunlnk,sunlink SF_NOUNLINK (FreeBSD only)
- * uappnd,uappend UF_APPEND
- * compressed UF_COMPRESSED (Mac OS only)
- * hidden,uhidden UF_HIDDEN
- * uchg,uchange,uimmutable UF_IMMUTABLE
- * nodump UF_NODUMP
- * uunlnk,uunlink UF_NOUNLINK (FreeBSD only)
- * offline,uoffline UF_OFFLINE (FreeBSD only)
- * opaque UF_OPAQUE
- * rdonly,urdonly,readonly UF_READONLY (FreeBSD only)
- * reparse,ureparse UF_REPARSE (FreeBSD only)
- * sparse,usparse UF_SPARSE (FreeBSD only)
- * system,usystem UF_SYSTEM (FreeBSD only)
- *
- * See chflags(2) for more information
- *
- * Supported file attributes on Linux:
- * a append only FS_APPEND_FL sappnd
- * A no atime updates FS_NOATIME_FL atime
- * c compress FS_COMPR_FL compress
- * C no copy on write FS_NOCOW_FL cow
- * d no dump FS_NODUMP_FL dump
- * D synchronous directory updates FS_DIRSYNC_FL dirsync
- * i immutable FS_IMMUTABLE_FL schg
- * j data journalling FS_JOURNAL_DATA_FL journal
- * P project hierarchy FS_PROJINHERIT_FL projinherit
- * s secure deletion FS_SECRM_FL securedeletion
- * S synchronous updates FS_SYNC_FL sync
- * t no tail-merging FS_NOTAIL_FL tail
- * T top of directory hierarchy FS_TOPDIR_FL topdir
- * u undeletable FS_UNRM_FL undel
- *
- * See ioctl_iflags(2) for more information
- *
- * Equivalent file flags supported on FreeBSD / Mac OS and Linux:
- * SF_APPEND FS_APPEND_FL sappnd
- * SF_IMMUTABLE FS_IMMUTABLE_FL schg
- * UF_NODUMP FS_NODUMP_FL nodump
- */
-
-static const struct flag {
- const char *name;
- const wchar_t *wname;
- unsigned long set;
- unsigned long clear;
-} fileflags[] = {
- /* Preferred (shorter) names per flag first, all prefixed by "no" */
-#ifdef SF_APPEND
- { "nosappnd", L"nosappnd", SF_APPEND, 0},
- { "nosappend", L"nosappend", SF_APPEND, 0},
-#endif
-#if defined(FS_APPEND_FL) /* 'a' */
- { "nosappnd", L"nosappnd", FS_APPEND_FL, 0},
- { "nosappend", L"nosappend", FS_APPEND_FL, 0},
-#elif defined(EXT2_APPEND_FL) /* 'a' */
- { "nosappnd", L"nosappnd", EXT2_APPEND_FL, 0},
- { "nosappend", L"nosappend", EXT2_APPEND_FL, 0},
-#endif
-#ifdef SF_ARCHIVED
- { "noarch", L"noarch", SF_ARCHIVED, 0},
- { "noarchived", L"noarchived", SF_ARCHIVED, 0},
-#endif
-#ifdef SF_IMMUTABLE
- { "noschg", L"noschg", SF_IMMUTABLE, 0},
- { "noschange", L"noschange", SF_IMMUTABLE, 0},
- { "nosimmutable", L"nosimmutable", SF_IMMUTABLE, 0},
-#endif
-#if defined(FS_IMMUTABLE_FL) /* 'i' */
- { "noschg", L"noschg", FS_IMMUTABLE_FL, 0},
- { "noschange", L"noschange", FS_IMMUTABLE_FL, 0},
- { "nosimmutable", L"nosimmutable", FS_IMMUTABLE_FL, 0},
-#elif defined(EXT2_IMMUTABLE_FL) /* 'i' */
- { "noschg", L"noschg", EXT2_IMMUTABLE_FL, 0},
- { "noschange", L"noschange", EXT2_IMMUTABLE_FL, 0},
- { "nosimmutable", L"nosimmutable", EXT2_IMMUTABLE_FL, 0},
-#endif
-#ifdef SF_NOUNLINK
- { "nosunlnk", L"nosunlnk", SF_NOUNLINK, 0},
- { "nosunlink", L"nosunlink", SF_NOUNLINK, 0},
-#endif
-#ifdef UF_APPEND
- { "nouappnd", L"nouappnd", UF_APPEND, 0},
- { "nouappend", L"nouappend", UF_APPEND, 0},
-#endif
-#ifdef UF_IMMUTABLE
- { "nouchg", L"nouchg", UF_IMMUTABLE, 0},
- { "nouchange", L"nouchange", UF_IMMUTABLE, 0},
- { "nouimmutable", L"nouimmutable", UF_IMMUTABLE, 0},
-#endif
-#ifdef UF_NODUMP
- { "nodump", L"nodump", 0, UF_NODUMP},
-#endif
-#if defined(FS_NODUMP_FL) /* 'd' */
- { "nodump", L"nodump", 0, FS_NODUMP_FL},
-#elif defined(EXT2_NODUMP_FL)
- { "nodump", L"nodump", 0, EXT2_NODUMP_FL},
-#endif
-#ifdef UF_OPAQUE
- { "noopaque", L"noopaque", UF_OPAQUE, 0},
-#endif
-#ifdef UF_NOUNLINK
- { "nouunlnk", L"nouunlnk", UF_NOUNLINK, 0},
- { "nouunlink", L"nouunlink", UF_NOUNLINK, 0},
-#endif
-#ifdef UF_COMPRESSED
- /* Mac OS */
- { "nocompressed", L"nocompressed", UF_COMPRESSED, 0},
-#endif
-#ifdef UF_HIDDEN
- { "nohidden", L"nohidden", UF_HIDDEN, 0},
- { "nouhidden", L"nouhidden", UF_HIDDEN, 0},
-#endif
-#ifdef FILE_ATTRIBUTE_HIDDEN
- { "nohidden", L"nohidden", FILE_ATTRIBUTE_HIDDEN, 0},
- { "nouhidden", L"nouhidden", FILE_ATTRIBUTE_HIDDEN, 0},
-#endif
-#ifdef UF_OFFLINE
- { "nooffline", L"nooffline", UF_OFFLINE, 0},
- { "nouoffline", L"nouoffline", UF_OFFLINE, 0},
-#endif
-#ifdef UF_READONLY
- { "nordonly", L"nordonly", UF_READONLY, 0},
- { "nourdonly", L"nourdonly", UF_READONLY, 0},
- { "noreadonly", L"noreadonly", UF_READONLY, 0},
-#endif
-#ifdef FILE_ATTRIBUTE_READONLY
- { "nordonly", L"nordonly", FILE_ATTRIBUTE_READONLY, 0},
- { "nourdonly", L"nourdonly", FILE_ATTRIBUTE_READONLY, 0},
- { "noreadonly", L"noreadonly", FILE_ATTRIBUTE_READONLY, 0},
-#endif
-#ifdef UF_SPARSE
- { "nosparse", L"nosparse", UF_SPARSE, 0},
- { "nousparse", L"nousparse", UF_SPARSE, 0},
-#endif
-#ifdef UF_REPARSE
- { "noreparse", L"noreparse", UF_REPARSE, 0},
- { "noureparse", L"noureparse", UF_REPARSE, 0},
-#endif
-#ifdef UF_SYSTEM
- { "nosystem", L"nosystem", UF_SYSTEM, 0},
- { "nousystem", L"nousystem", UF_SYSTEM, 0},
-#endif
-#ifdef FILE_ATTRIBUTE_SYSTEM
- { "nosystem", L"nosystem", FILE_ATTRIBUTE_SYSTEM, 0},
- { "nousystem", L"nousystem", FILE_ATTRIBUTE_SYSTEM, 0},
-#endif
-#if defined(FS_UNRM_FL) /* 'u' */
- { "noundel", L"noundel", FS_UNRM_FL, 0},
-#elif defined(EXT2_UNRM_FL)
- { "noundel", L"noundel", EXT2_UNRM_FL, 0},
-#endif
-
-#if defined(FS_COMPR_FL) /* 'c' */
- { "nocompress", L"nocompress", FS_COMPR_FL, 0},
-#elif defined(EXT2_COMPR_FL)
- { "nocompress", L"nocompress", EXT2_COMPR_FL, 0},
-#endif
-
-#if defined(FS_NOATIME_FL) /* 'A' */
- { "noatime", L"noatime", 0, FS_NOATIME_FL},
-#elif defined(EXT2_NOATIME_FL)
- { "noatime", L"noatime", 0, EXT2_NOATIME_FL},
-#endif
-#if defined(FS_DIRSYNC_FL) /* 'D' */
- { "nodirsync", L"nodirsync", FS_DIRSYNC_FL, 0},
-#elif defined(EXT2_DIRSYNC_FL)
- { "nodirsync", L"nodirsync", EXT2_DIRSYNC_FL, 0},
-#endif
-#if defined(FS_JOURNAL_DATA_FL) /* 'j' */
- { "nojournal-data",L"nojournal-data", FS_JOURNAL_DATA_FL, 0},
- { "nojournal", L"nojournal", FS_JOURNAL_DATA_FL, 0},
-#elif defined(EXT3_JOURNAL_DATA_FL)
- { "nojournal-data",L"nojournal-data", EXT3_JOURNAL_DATA_FL, 0},
- { "nojournal", L"nojournal", EXT3_JOURNAL_DATA_FL, 0},
-#endif
-#if defined(FS_SECRM_FL) /* 's' */
- { "nosecdel", L"nosecdel", FS_SECRM_FL, 0},
- { "nosecuredeletion",L"nosecuredeletion",FS_SECRM_FL, 0},
-#elif defined(EXT2_SECRM_FL)
- { "nosecdel", L"nosecdel", EXT2_SECRM_FL, 0},
- { "nosecuredeletion",L"nosecuredeletion",EXT2_SECRM_FL, 0},
-#endif
-#if defined(FS_SYNC_FL) /* 'S' */
- { "nosync", L"nosync", FS_SYNC_FL, 0},
-#elif defined(EXT2_SYNC_FL)
- { "nosync", L"nosync", EXT2_SYNC_FL, 0},
-#endif
-#if defined(FS_NOTAIL_FL) /* 't' */
- { "notail", L"notail", 0, FS_NOTAIL_FL},
-#elif defined(EXT2_NOTAIL_FL)
- { "notail", L"notail", 0, EXT2_NOTAIL_FL},
-#endif
-#if defined(FS_TOPDIR_FL) /* 'T' */
- { "notopdir", L"notopdir", FS_TOPDIR_FL, 0},
-#elif defined(EXT2_TOPDIR_FL)
- { "notopdir", L"notopdir", EXT2_TOPDIR_FL, 0},
-#endif
-#ifdef FS_NOCOW_FL /* 'C' */
- { "nocow", L"nocow", 0, FS_NOCOW_FL},
-#endif
-#ifdef FS_PROJINHERIT_FL /* 'P' */
- { "noprojinherit",L"noprojinherit", FS_PROJINHERIT_FL, 0},
-#endif
- { NULL, NULL, 0, 0}
-};
-
-/*
- * fflagstostr --
- * Convert file flags to a comma-separated string. If no flags
- * are set, return the empty string.
- */
-static char *
-ae_fflagstostr(unsigned long bitset, unsigned long bitclear)
-{
- char *string, *dp;
- const char *sp;
- unsigned long bits;
- const struct flag *flag;
- size_t length;
-
- bits = bitset | bitclear;
- length = 0;
- for (flag = fileflags; flag->name != NULL; flag++)
- if (bits & (flag->set | flag->clear)) {
- length += strlen(flag->name) + 1;
- bits &= ~(flag->set | flag->clear);
- }
-
- if (length == 0)
- return (NULL);
- string = (char *)malloc(length);
- if (string == NULL)
- return (NULL);
-
- dp = string;
- for (flag = fileflags; flag->name != NULL; flag++) {
- if (bitset & flag->set || bitclear & flag->clear) {
- sp = flag->name + 2;
- } else if (bitset & flag->clear || bitclear & flag->set) {
- sp = flag->name;
- } else
- continue;
- bitset &= ~(flag->set | flag->clear);
- bitclear &= ~(flag->set | flag->clear);
- if (dp > string)
- *dp++ = ',';
- while ((*dp++ = *sp++) != '\0')
- ;
- dp--;
- }
-
- *dp = '\0';
- return (string);
-}
-
-/*
- * strtofflags --
- * Take string of arguments and return file flags. This
- * version works a little differently than strtofflags(3).
- * In particular, it always tests every token, skipping any
- * unrecognized tokens. It returns a pointer to the first
- * unrecognized token, or NULL if every token was recognized.
- * This version is also const-correct and does not modify the
- * provided string.
- */
-static const char *
-ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
-{
- const char *start, *end;
- const struct flag *flag;
- unsigned long set, clear;
- const char *failed;
-
- set = clear = 0;
- start = s;
- failed = NULL;
- /* Find start of first token. */
- while (*start == '\t' || *start == ' ' || *start == ',')
- start++;
- while (*start != '\0') {
- size_t length;
- /* Locate end of token. */
- end = start;
- while (*end != '\0' && *end != '\t' &&
- *end != ' ' && *end != ',')
- end++;
- length = end - start;
- for (flag = fileflags; flag->name != NULL; flag++) {
- size_t flag_length = strlen(flag->name);
- if (length == flag_length
- && memcmp(start, flag->name, length) == 0) {
- /* Matched "noXXXX", so reverse the sense. */
- clear |= flag->set;
- set |= flag->clear;
- break;
- } else if (length == flag_length - 2
- && memcmp(start, flag->name + 2, length) == 0) {
- /* Matched "XXXX", so don't reverse. */
- set |= flag->set;
- clear |= flag->clear;
- break;
- }
- }
- /* Ignore unknown flag names. */
- if (flag->name == NULL && failed == NULL)
- failed = start;
-
- /* Find start of next token. */
- start = end;
- while (*start == '\t' || *start == ' ' || *start == ',')
- start++;
-
- }
-
- if (setp)
- *setp = set;
- if (clrp)
- *clrp = clear;
-
- /* Return location of first failure. */
- return (failed);
-}
-
-/*
- * wcstofflags --
- * Take string of arguments and return file flags. This
- * version works a little differently than strtofflags(3).
- * In particular, it always tests every token, skipping any
- * unrecognized tokens. It returns a pointer to the first
- * unrecognized token, or NULL if every token was recognized.
- * This version is also const-correct and does not modify the
- * provided string.
- */
-static const wchar_t *
-ae_wcstofflags(const wchar_t *s, unsigned long *setp, unsigned long *clrp)
-{
- const wchar_t *start, *end;
- const struct flag *flag;
- unsigned long set, clear;
- const wchar_t *failed;
-
- set = clear = 0;
- start = s;
- failed = NULL;
- /* Find start of first token. */
- while (*start == L'\t' || *start == L' ' || *start == L',')
- start++;
- while (*start != L'\0') {
- size_t length;
- /* Locate end of token. */
- end = start;
- while (*end != L'\0' && *end != L'\t' &&
- *end != L' ' && *end != L',')
- end++;
- length = end - start;
- for (flag = fileflags; flag->wname != NULL; flag++) {
- size_t flag_length = wcslen(flag->wname);
- if (length == flag_length
- && wmemcmp(start, flag->wname, length) == 0) {
- /* Matched "noXXXX", so reverse the sense. */
- clear |= flag->set;
- set |= flag->clear;
- break;
- } else if (length == flag_length - 2
- && wmemcmp(start, flag->wname + 2, length) == 0) {
- /* Matched "XXXX", so don't reverse. */
- set |= flag->set;
- clear |= flag->clear;
- break;
- }
- }
- /* Ignore unknown flag names. */
- if (flag->wname == NULL && failed == NULL)
- failed = start;
-
- /* Find start of next token. */
- start = end;
- while (*start == L'\t' || *start == L' ' || *start == L',')
- start++;
-
- }
-
- if (setp)
- *setp = set;
- if (clrp)
- *clrp = clear;
-
- /* Return location of first failure. */
- return (failed);
-}
-
-
-#ifdef TEST
-#include <stdio.h>
-int
-main(int argc, char **argv)
-{
- struct archive_entry *entry = archive_entry_new();
- unsigned long set, clear;
- const wchar_t *remainder;
-
- remainder = archive_entry_copy_fflags_text_w(entry, L"nosappnd dump archive,,,,,,,");
- archive_entry_fflags(entry, &set, &clear);
-
- wprintf(L"set=0x%lX clear=0x%lX remainder='%ls'\n", set, clear, remainder);
-
- wprintf(L"new flags='%s'\n", archive_entry_fflags_text(entry));
- return (0);
-}
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_entry.h b/contrib/libs/libarchive/libarchive/archive_entry.h
deleted file mode 100644
index 890cf2f3f1..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_entry.h
+++ /dev/null
@@ -1,723 +0,0 @@
-/*-
- * Copyright (c) 2003-2008 Tim Kientzle
- * Copyright (c) 2016 Martin Matuska
- * 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(S) ``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(S) 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.
- *
- * $FreeBSD: head/lib/libarchive/archive_entry.h 201096 2009-12-28 02:41:27Z kientzle $
- */
-
-#ifndef ARCHIVE_ENTRY_H_INCLUDED
-#define ARCHIVE_ENTRY_H_INCLUDED
-
-/* Note: Compiler will complain if this does not match archive.h! */
-#define ARCHIVE_VERSION_NUMBER 3007001
-
-/*
- * Note: archive_entry.h is for use outside of libarchive; the
- * configuration headers (config.h, archive_platform.h, etc.) are
- * purely internal. Do NOT use HAVE_XXX configuration macros to
- * control the behavior of this header! If you must conditionalize,
- * use predefined compiler and/or platform macros.
- */
-
-#include <sys/types.h>
-#include <stddef.h> /* for wchar_t */
-#include <stdint.h>
-#include <time.h>
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#include <windows.h>
-#endif
-
-/* Get a suitable 64-bit integer type. */
-#if !defined(__LA_INT64_T_DEFINED)
-# if ARCHIVE_VERSION_NUMBER < 4000000
-#define __LA_INT64_T la_int64_t
-# endif
-#define __LA_INT64_T_DEFINED
-# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
-typedef __int64 la_int64_t;
-# else
-#include <unistd.h>
-# if defined(_SCO_DS) || defined(__osf__)
-typedef long long la_int64_t;
-# else
-typedef int64_t la_int64_t;
-# endif
-# endif
-#endif
-
-/* The la_ssize_t should match the type used in 'struct stat' */
-#if !defined(__LA_SSIZE_T_DEFINED)
-/* Older code relied on the __LA_SSIZE_T macro; after 4.0 we'll switch to the typedef exclusively. */
-# if ARCHIVE_VERSION_NUMBER < 4000000
-#define __LA_SSIZE_T la_ssize_t
-# endif
-#define __LA_SSIZE_T_DEFINED
-# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
-# if defined(_SSIZE_T_DEFINED) || defined(_SSIZE_T_)
-typedef ssize_t la_ssize_t;
-# elif defined(_WIN64)
-typedef __int64 la_ssize_t;
-# else
-typedef long la_ssize_t;
-# endif
-# else
-# include <unistd.h> /* ssize_t */
-typedef ssize_t la_ssize_t;
-# endif
-#endif
-
-/* Get a suitable definition for mode_t */
-#if ARCHIVE_VERSION_NUMBER >= 3999000
-/* Switch to plain 'int' for libarchive 4.0. It's less broken than 'mode_t' */
-# define __LA_MODE_T int
-#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__) && !defined(__WATCOMC__)
-# define __LA_MODE_T unsigned short
-#else
-# define __LA_MODE_T mode_t
-#endif
-
-/* Large file support for Android */
-#if defined(__LIBARCHIVE_BUILD) && defined(__ANDROID__)
-#error #include "android_lf.h"
-#endif
-
-/*
- * On Windows, define LIBARCHIVE_STATIC if you're building or using a
- * .lib. The default here assumes you're building a DLL. Only
- * libarchive source should ever define __LIBARCHIVE_BUILD.
- */
-#if ((defined __WIN32__) || (defined _WIN32) || defined(__CYGWIN__)) && (!defined LIBARCHIVE_STATIC)
-# ifdef __LIBARCHIVE_BUILD
-# ifdef __GNUC__
-# define __LA_DECL __attribute__((dllexport)) extern
-# else
-# define __LA_DECL __declspec(dllexport)
-# endif
-# else
-# ifdef __GNUC__
-# define __LA_DECL
-# else
-# define __LA_DECL __declspec(dllimport)
-# endif
-# endif
-#elif defined __LIBARCHIVE_ENABLE_VISIBILITY
-# define __LA_DECL __attribute__((visibility("default")))
-#else
-/* Static libraries on all platforms and shared libraries on non-Windows. */
-# define __LA_DECL
-#endif
-
-#if defined(__GNUC__) && __GNUC__ >= 3 && __GNUC_MINOR__ >= 1
-# define __LA_DEPRECATED __attribute__((deprecated))
-#else
-# define __LA_DEPRECATED
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Description of an archive entry.
- *
- * You can think of this as "struct stat" with some text fields added in.
- *
- * TODO: Add "comment", "charset", and possibly other entries that are
- * supported by "pax interchange" format. However, GNU, ustar, cpio,
- * and other variants don't support these features, so they're not an
- * excruciatingly high priority right now.
- *
- * TODO: "pax interchange" format allows essentially arbitrary
- * key/value attributes to be attached to any entry. Supporting
- * such extensions may make this library useful for special
- * applications (e.g., a package manager could attach special
- * package-management attributes to each entry).
- */
-struct archive;
-struct archive_entry;
-
-/*
- * File-type constants. These are returned from archive_entry_filetype()
- * and passed to archive_entry_set_filetype().
- *
- * These values match S_XXX defines on every platform I've checked,
- * including Windows, AIX, Linux, Solaris, and BSD. They're
- * (re)defined here because platforms generally don't define the ones
- * they don't support. For example, Windows doesn't define S_IFLNK or
- * S_IFBLK. Instead of having a mass of conditional logic and system
- * checks to define any S_XXX values that aren't supported locally,
- * I've just defined a new set of such constants so that
- * libarchive-based applications can manipulate and identify archive
- * entries properly even if the hosting platform can't store them on
- * disk.
- *
- * These values are also used directly within some portable formats,
- * such as cpio. If you find a platform that varies from these, the
- * correct solution is to leave these alone and translate from these
- * portable values to platform-native values when entries are read from
- * or written to disk.
- */
-/*
- * In libarchive 4.0, we can drop the casts here.
- * They're needed to work around Borland C's broken mode_t.
- */
-#define AE_IFMT ((__LA_MODE_T)0170000)
-#define AE_IFREG ((__LA_MODE_T)0100000)
-#define AE_IFLNK ((__LA_MODE_T)0120000)
-#define AE_IFSOCK ((__LA_MODE_T)0140000)
-#define AE_IFCHR ((__LA_MODE_T)0020000)
-#define AE_IFBLK ((__LA_MODE_T)0060000)
-#define AE_IFDIR ((__LA_MODE_T)0040000)
-#define AE_IFIFO ((__LA_MODE_T)0010000)
-
-/*
- * Symlink types
- */
-#define AE_SYMLINK_TYPE_UNDEFINED 0
-#define AE_SYMLINK_TYPE_FILE 1
-#define AE_SYMLINK_TYPE_DIRECTORY 2
-
-/*
- * Basic object manipulation
- */
-
-__LA_DECL struct archive_entry *archive_entry_clear(struct archive_entry *);
-/* The 'clone' function does a deep copy; all of the strings are copied too. */
-__LA_DECL struct archive_entry *archive_entry_clone(struct archive_entry *);
-__LA_DECL void archive_entry_free(struct archive_entry *);
-__LA_DECL struct archive_entry *archive_entry_new(void);
-
-/*
- * This form of archive_entry_new2() will pull character-set
- * conversion information from the specified archive handle. The
- * older archive_entry_new(void) form is equivalent to calling
- * archive_entry_new2(NULL) and will result in the use of an internal
- * default character-set conversion.
- */
-__LA_DECL struct archive_entry *archive_entry_new2(struct archive *);
-
-/*
- * Retrieve fields from an archive_entry.
- *
- * There are a number of implicit conversions among these fields. For
- * example, if a regular string field is set and you read the _w wide
- * character field, the entry will implicitly convert narrow-to-wide
- * using the current locale. Similarly, dev values are automatically
- * updated when you write devmajor or devminor and vice versa.
- *
- * In addition, fields can be "set" or "unset." Unset string fields
- * return NULL, non-string fields have _is_set() functions to test
- * whether they've been set. You can "unset" a string field by
- * assigning NULL; non-string fields have _unset() functions to
- * unset them.
- *
- * Note: There is one ambiguity in the above; string fields will
- * also return NULL when implicit character set conversions fail.
- * This is usually what you want.
- */
-__LA_DECL time_t archive_entry_atime(struct archive_entry *);
-__LA_DECL long archive_entry_atime_nsec(struct archive_entry *);
-__LA_DECL int archive_entry_atime_is_set(struct archive_entry *);
-__LA_DECL time_t archive_entry_birthtime(struct archive_entry *);
-__LA_DECL long archive_entry_birthtime_nsec(struct archive_entry *);
-__LA_DECL int archive_entry_birthtime_is_set(struct archive_entry *);
-__LA_DECL time_t archive_entry_ctime(struct archive_entry *);
-__LA_DECL long archive_entry_ctime_nsec(struct archive_entry *);
-__LA_DECL int archive_entry_ctime_is_set(struct archive_entry *);
-__LA_DECL dev_t archive_entry_dev(struct archive_entry *);
-__LA_DECL int archive_entry_dev_is_set(struct archive_entry *);
-__LA_DECL dev_t archive_entry_devmajor(struct archive_entry *);
-__LA_DECL dev_t archive_entry_devminor(struct archive_entry *);
-__LA_DECL __LA_MODE_T archive_entry_filetype(struct archive_entry *);
-__LA_DECL void archive_entry_fflags(struct archive_entry *,
- unsigned long * /* set */,
- unsigned long * /* clear */);
-__LA_DECL const char *archive_entry_fflags_text(struct archive_entry *);
-__LA_DECL la_int64_t archive_entry_gid(struct archive_entry *);
-__LA_DECL const char *archive_entry_gname(struct archive_entry *);
-__LA_DECL const char *archive_entry_gname_utf8(struct archive_entry *);
-__LA_DECL const wchar_t *archive_entry_gname_w(struct archive_entry *);
-__LA_DECL const char *archive_entry_hardlink(struct archive_entry *);
-__LA_DECL const char *archive_entry_hardlink_utf8(struct archive_entry *);
-__LA_DECL const wchar_t *archive_entry_hardlink_w(struct archive_entry *);
-__LA_DECL la_int64_t archive_entry_ino(struct archive_entry *);
-__LA_DECL la_int64_t archive_entry_ino64(struct archive_entry *);
-__LA_DECL int archive_entry_ino_is_set(struct archive_entry *);
-__LA_DECL __LA_MODE_T archive_entry_mode(struct archive_entry *);
-__LA_DECL time_t archive_entry_mtime(struct archive_entry *);
-__LA_DECL long archive_entry_mtime_nsec(struct archive_entry *);
-__LA_DECL int archive_entry_mtime_is_set(struct archive_entry *);
-__LA_DECL unsigned int archive_entry_nlink(struct archive_entry *);
-__LA_DECL const char *archive_entry_pathname(struct archive_entry *);
-__LA_DECL const char *archive_entry_pathname_utf8(struct archive_entry *);
-__LA_DECL const wchar_t *archive_entry_pathname_w(struct archive_entry *);
-__LA_DECL __LA_MODE_T archive_entry_perm(struct archive_entry *);
-__LA_DECL dev_t archive_entry_rdev(struct archive_entry *);
-__LA_DECL dev_t archive_entry_rdevmajor(struct archive_entry *);
-__LA_DECL dev_t archive_entry_rdevminor(struct archive_entry *);
-__LA_DECL const char *archive_entry_sourcepath(struct archive_entry *);
-__LA_DECL const wchar_t *archive_entry_sourcepath_w(struct archive_entry *);
-__LA_DECL la_int64_t archive_entry_size(struct archive_entry *);
-__LA_DECL int archive_entry_size_is_set(struct archive_entry *);
-__LA_DECL const char *archive_entry_strmode(struct archive_entry *);
-__LA_DECL const char *archive_entry_symlink(struct archive_entry *);
-__LA_DECL const char *archive_entry_symlink_utf8(struct archive_entry *);
-__LA_DECL int archive_entry_symlink_type(struct archive_entry *);
-__LA_DECL const wchar_t *archive_entry_symlink_w(struct archive_entry *);
-__LA_DECL la_int64_t archive_entry_uid(struct archive_entry *);
-__LA_DECL const char *archive_entry_uname(struct archive_entry *);
-__LA_DECL const char *archive_entry_uname_utf8(struct archive_entry *);
-__LA_DECL const wchar_t *archive_entry_uname_w(struct archive_entry *);
-__LA_DECL int archive_entry_is_data_encrypted(struct archive_entry *);
-__LA_DECL int archive_entry_is_metadata_encrypted(struct archive_entry *);
-__LA_DECL int archive_entry_is_encrypted(struct archive_entry *);
-
-/*
- * Set fields in an archive_entry.
- *
- * Note: Before libarchive 2.4, there were 'set' and 'copy' versions
- * of the string setters. 'copy' copied the actual string, 'set' just
- * stored the pointer. In libarchive 2.4 and later, strings are
- * always copied.
- */
-
-__LA_DECL void archive_entry_set_atime(struct archive_entry *, time_t, long);
-__LA_DECL void archive_entry_unset_atime(struct archive_entry *);
-#if defined(_WIN32) && !defined(__CYGWIN__)
-__LA_DECL void archive_entry_copy_bhfi(struct archive_entry *, BY_HANDLE_FILE_INFORMATION *);
-#endif
-__LA_DECL void archive_entry_set_birthtime(struct archive_entry *, time_t, long);
-__LA_DECL void archive_entry_unset_birthtime(struct archive_entry *);
-__LA_DECL void archive_entry_set_ctime(struct archive_entry *, time_t, long);
-__LA_DECL void archive_entry_unset_ctime(struct archive_entry *);
-__LA_DECL void archive_entry_set_dev(struct archive_entry *, dev_t);
-__LA_DECL void archive_entry_set_devmajor(struct archive_entry *, dev_t);
-__LA_DECL void archive_entry_set_devminor(struct archive_entry *, dev_t);
-__LA_DECL void archive_entry_set_filetype(struct archive_entry *, unsigned int);
-__LA_DECL void archive_entry_set_fflags(struct archive_entry *,
- unsigned long /* set */, unsigned long /* clear */);
-/* Returns pointer to start of first invalid token, or NULL if none. */
-/* Note that all recognized tokens are processed, regardless. */
-__LA_DECL const char *archive_entry_copy_fflags_text(struct archive_entry *,
- const char *);
-__LA_DECL const wchar_t *archive_entry_copy_fflags_text_w(struct archive_entry *,
- const wchar_t *);
-__LA_DECL void archive_entry_set_gid(struct archive_entry *, la_int64_t);
-__LA_DECL void archive_entry_set_gname(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_set_gname_utf8(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_copy_gname(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_copy_gname_w(struct archive_entry *, const wchar_t *);
-__LA_DECL int archive_entry_update_gname_utf8(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_set_hardlink(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_set_hardlink_utf8(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_copy_hardlink(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_copy_hardlink_w(struct archive_entry *, const wchar_t *);
-__LA_DECL int archive_entry_update_hardlink_utf8(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_set_ino(struct archive_entry *, la_int64_t);
-__LA_DECL void archive_entry_set_ino64(struct archive_entry *, la_int64_t);
-__LA_DECL void archive_entry_set_link(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_set_link_utf8(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_copy_link(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_copy_link_w(struct archive_entry *, const wchar_t *);
-__LA_DECL int archive_entry_update_link_utf8(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_set_mode(struct archive_entry *, __LA_MODE_T);
-__LA_DECL void archive_entry_set_mtime(struct archive_entry *, time_t, long);
-__LA_DECL void archive_entry_unset_mtime(struct archive_entry *);
-__LA_DECL void archive_entry_set_nlink(struct archive_entry *, unsigned int);
-__LA_DECL void archive_entry_set_pathname(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_set_pathname_utf8(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_copy_pathname(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_copy_pathname_w(struct archive_entry *, const wchar_t *);
-__LA_DECL int archive_entry_update_pathname_utf8(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_set_perm(struct archive_entry *, __LA_MODE_T);
-__LA_DECL void archive_entry_set_rdev(struct archive_entry *, dev_t);
-__LA_DECL void archive_entry_set_rdevmajor(struct archive_entry *, dev_t);
-__LA_DECL void archive_entry_set_rdevminor(struct archive_entry *, dev_t);
-__LA_DECL void archive_entry_set_size(struct archive_entry *, la_int64_t);
-__LA_DECL void archive_entry_unset_size(struct archive_entry *);
-__LA_DECL void archive_entry_copy_sourcepath(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_copy_sourcepath_w(struct archive_entry *, const wchar_t *);
-__LA_DECL void archive_entry_set_symlink(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_set_symlink_type(struct archive_entry *, int);
-__LA_DECL void archive_entry_set_symlink_utf8(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_copy_symlink(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_copy_symlink_w(struct archive_entry *, const wchar_t *);
-__LA_DECL int archive_entry_update_symlink_utf8(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_set_uid(struct archive_entry *, la_int64_t);
-__LA_DECL void archive_entry_set_uname(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_set_uname_utf8(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_copy_uname(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_copy_uname_w(struct archive_entry *, const wchar_t *);
-__LA_DECL int archive_entry_update_uname_utf8(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_set_is_data_encrypted(struct archive_entry *, char is_encrypted);
-__LA_DECL void archive_entry_set_is_metadata_encrypted(struct archive_entry *, char is_encrypted);
-/*
- * Routines to bulk copy fields to/from a platform-native "struct
- * stat." Libarchive used to just store a struct stat inside of each
- * archive_entry object, but this created issues when trying to
- * manipulate archives on systems different than the ones they were
- * created on.
- *
- * TODO: On Linux and other LFS systems, provide both stat32 and
- * stat64 versions of these functions and all of the macro glue so
- * that archive_entry_stat is magically defined to
- * archive_entry_stat32 or archive_entry_stat64 as appropriate.
- */
-__LA_DECL const struct stat *archive_entry_stat(struct archive_entry *);
-__LA_DECL void archive_entry_copy_stat(struct archive_entry *, const struct stat *);
-
-/*
- * Storage for Mac OS-specific AppleDouble metadata information.
- * Apple-format tar files store a separate binary blob containing
- * encoded metadata with ACL, extended attributes, etc.
- * This provides a place to store that blob.
- */
-
-__LA_DECL const void * archive_entry_mac_metadata(struct archive_entry *, size_t *);
-__LA_DECL void archive_entry_copy_mac_metadata(struct archive_entry *, const void *, size_t);
-
-/*
- * Digest routine. This is used to query the raw hex digest for the
- * given entry. The type of digest is provided as an argument.
- */
-#define ARCHIVE_ENTRY_DIGEST_MD5 0x00000001
-#define ARCHIVE_ENTRY_DIGEST_RMD160 0x00000002
-#define ARCHIVE_ENTRY_DIGEST_SHA1 0x00000003
-#define ARCHIVE_ENTRY_DIGEST_SHA256 0x00000004
-#define ARCHIVE_ENTRY_DIGEST_SHA384 0x00000005
-#define ARCHIVE_ENTRY_DIGEST_SHA512 0x00000006
-
-__LA_DECL const unsigned char * archive_entry_digest(struct archive_entry *, int /* type */);
-
-/*
- * ACL routines. This used to simply store and return text-format ACL
- * strings, but that proved insufficient for a number of reasons:
- * = clients need control over uname/uid and gname/gid mappings
- * = there are many different ACL text formats
- * = would like to be able to read/convert archives containing ACLs
- * on platforms that lack ACL libraries
- *
- * This last point, in particular, forces me to implement a reasonably
- * complete set of ACL support routines.
- */
-
-/*
- * Permission bits.
- */
-#define ARCHIVE_ENTRY_ACL_EXECUTE 0x00000001
-#define ARCHIVE_ENTRY_ACL_WRITE 0x00000002
-#define ARCHIVE_ENTRY_ACL_READ 0x00000004
-#define ARCHIVE_ENTRY_ACL_READ_DATA 0x00000008
-#define ARCHIVE_ENTRY_ACL_LIST_DIRECTORY 0x00000008
-#define ARCHIVE_ENTRY_ACL_WRITE_DATA 0x00000010
-#define ARCHIVE_ENTRY_ACL_ADD_FILE 0x00000010
-#define ARCHIVE_ENTRY_ACL_APPEND_DATA 0x00000020
-#define ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY 0x00000020
-#define ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS 0x00000040
-#define ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS 0x00000080
-#define ARCHIVE_ENTRY_ACL_DELETE_CHILD 0x00000100
-#define ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES 0x00000200
-#define ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES 0x00000400
-#define ARCHIVE_ENTRY_ACL_DELETE 0x00000800
-#define ARCHIVE_ENTRY_ACL_READ_ACL 0x00001000
-#define ARCHIVE_ENTRY_ACL_WRITE_ACL 0x00002000
-#define ARCHIVE_ENTRY_ACL_WRITE_OWNER 0x00004000
-#define ARCHIVE_ENTRY_ACL_SYNCHRONIZE 0x00008000
-
-#define ARCHIVE_ENTRY_ACL_PERMS_POSIX1E \
- (ARCHIVE_ENTRY_ACL_EXECUTE \
- | ARCHIVE_ENTRY_ACL_WRITE \
- | ARCHIVE_ENTRY_ACL_READ)
-
-#define ARCHIVE_ENTRY_ACL_PERMS_NFS4 \
- (ARCHIVE_ENTRY_ACL_EXECUTE \
- | ARCHIVE_ENTRY_ACL_READ_DATA \
- | ARCHIVE_ENTRY_ACL_LIST_DIRECTORY \
- | ARCHIVE_ENTRY_ACL_WRITE_DATA \
- | ARCHIVE_ENTRY_ACL_ADD_FILE \
- | ARCHIVE_ENTRY_ACL_APPEND_DATA \
- | ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY \
- | ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS \
- | ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS \
- | ARCHIVE_ENTRY_ACL_DELETE_CHILD \
- | ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES \
- | ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES \
- | ARCHIVE_ENTRY_ACL_DELETE \
- | ARCHIVE_ENTRY_ACL_READ_ACL \
- | ARCHIVE_ENTRY_ACL_WRITE_ACL \
- | ARCHIVE_ENTRY_ACL_WRITE_OWNER \
- | ARCHIVE_ENTRY_ACL_SYNCHRONIZE)
-
-/*
- * Inheritance values (NFS4 ACLs only); included in permset.
- */
-#define ARCHIVE_ENTRY_ACL_ENTRY_INHERITED 0x01000000
-#define ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT 0x02000000
-#define ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT 0x04000000
-#define ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT 0x08000000
-#define ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY 0x10000000
-#define ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS 0x20000000
-#define ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS 0x40000000
-
-#define ARCHIVE_ENTRY_ACL_INHERITANCE_NFS4 \
- (ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT \
- | ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT \
- | ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT \
- | ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY \
- | ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS \
- | ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS \
- | ARCHIVE_ENTRY_ACL_ENTRY_INHERITED)
-
-/* We need to be able to specify combinations of these. */
-#define ARCHIVE_ENTRY_ACL_TYPE_ACCESS 0x00000100 /* POSIX.1e only */
-#define ARCHIVE_ENTRY_ACL_TYPE_DEFAULT 0x00000200 /* POSIX.1e only */
-#define ARCHIVE_ENTRY_ACL_TYPE_ALLOW 0x00000400 /* NFS4 only */
-#define ARCHIVE_ENTRY_ACL_TYPE_DENY 0x00000800 /* NFS4 only */
-#define ARCHIVE_ENTRY_ACL_TYPE_AUDIT 0x00001000 /* NFS4 only */
-#define ARCHIVE_ENTRY_ACL_TYPE_ALARM 0x00002000 /* NFS4 only */
-#define ARCHIVE_ENTRY_ACL_TYPE_POSIX1E (ARCHIVE_ENTRY_ACL_TYPE_ACCESS \
- | ARCHIVE_ENTRY_ACL_TYPE_DEFAULT)
-#define ARCHIVE_ENTRY_ACL_TYPE_NFS4 (ARCHIVE_ENTRY_ACL_TYPE_ALLOW \
- | ARCHIVE_ENTRY_ACL_TYPE_DENY \
- | ARCHIVE_ENTRY_ACL_TYPE_AUDIT \
- | ARCHIVE_ENTRY_ACL_TYPE_ALARM)
-
-/* Tag values mimic POSIX.1e */
-#define ARCHIVE_ENTRY_ACL_USER 10001 /* Specified user. */
-#define ARCHIVE_ENTRY_ACL_USER_OBJ 10002 /* User who owns the file. */
-#define ARCHIVE_ENTRY_ACL_GROUP 10003 /* Specified group. */
-#define ARCHIVE_ENTRY_ACL_GROUP_OBJ 10004 /* Group who owns the file. */
-#define ARCHIVE_ENTRY_ACL_MASK 10005 /* Modify group access (POSIX.1e only) */
-#define ARCHIVE_ENTRY_ACL_OTHER 10006 /* Public (POSIX.1e only) */
-#define ARCHIVE_ENTRY_ACL_EVERYONE 10107 /* Everyone (NFS4 only) */
-
-/*
- * Set the ACL by clearing it and adding entries one at a time.
- * Unlike the POSIX.1e ACL routines, you must specify the type
- * (access/default) for each entry. Internally, the ACL data is just
- * a soup of entries. API calls here allow you to retrieve just the
- * entries of interest. This design (which goes against the spirit of
- * POSIX.1e) is useful for handling archive formats that combine
- * default and access information in a single ACL list.
- */
-__LA_DECL void archive_entry_acl_clear(struct archive_entry *);
-__LA_DECL int archive_entry_acl_add_entry(struct archive_entry *,
- int /* type */, int /* permset */, int /* tag */,
- int /* qual */, const char * /* name */);
-__LA_DECL int archive_entry_acl_add_entry_w(struct archive_entry *,
- int /* type */, int /* permset */, int /* tag */,
- int /* qual */, const wchar_t * /* name */);
-
-/*
- * To retrieve the ACL, first "reset", then repeatedly ask for the
- * "next" entry. The want_type parameter allows you to request only
- * certain types of entries.
- */
-__LA_DECL int archive_entry_acl_reset(struct archive_entry *, int /* want_type */);
-__LA_DECL int archive_entry_acl_next(struct archive_entry *, int /* want_type */,
- int * /* type */, int * /* permset */, int * /* tag */,
- int * /* qual */, const char ** /* name */);
-
-/*
- * Construct a text-format ACL. The flags argument is a bitmask that
- * can include any of the following:
- *
- * Flags only for archive entries with POSIX.1e ACL:
- * ARCHIVE_ENTRY_ACL_TYPE_ACCESS - Include POSIX.1e "access" entries.
- * ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - Include POSIX.1e "default" entries.
- * ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT - Include "default:" before each
- * default ACL entry.
- * ARCHIVE_ENTRY_ACL_STYLE_SOLARIS - Output only one colon after "other" and
- * "mask" entries.
- *
- * Flags only for archive entries with NFSv4 ACL:
- * ARCHIVE_ENTRY_ACL_STYLE_COMPACT - Do not output the minus character for
- * unset permissions and flags in NFSv4 ACL permission and flag fields
- *
- * Flags for for archive entries with POSIX.1e ACL or NFSv4 ACL:
- * ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID - Include extra numeric ID field in
- * each ACL entry.
- * ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA - Separate entries with comma
- * instead of newline.
- */
-#define ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID 0x00000001
-#define ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 0x00000002
-#define ARCHIVE_ENTRY_ACL_STYLE_SOLARIS 0x00000004
-#define ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA 0x00000008
-#define ARCHIVE_ENTRY_ACL_STYLE_COMPACT 0x00000010
-
-__LA_DECL wchar_t *archive_entry_acl_to_text_w(struct archive_entry *,
- la_ssize_t * /* len */, int /* flags */);
-__LA_DECL char *archive_entry_acl_to_text(struct archive_entry *,
- la_ssize_t * /* len */, int /* flags */);
-__LA_DECL int archive_entry_acl_from_text_w(struct archive_entry *,
- const wchar_t * /* wtext */, int /* type */);
-__LA_DECL int archive_entry_acl_from_text(struct archive_entry *,
- const char * /* text */, int /* type */);
-
-/* Deprecated constants */
-#define OLD_ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID 1024
-#define OLD_ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 2048
-
-/* Deprecated functions */
-__LA_DECL const wchar_t *archive_entry_acl_text_w(struct archive_entry *,
- int /* flags */) __LA_DEPRECATED;
-__LA_DECL const char *archive_entry_acl_text(struct archive_entry *,
- int /* flags */) __LA_DEPRECATED;
-
-/* Return bitmask of ACL types in an archive entry */
-__LA_DECL int archive_entry_acl_types(struct archive_entry *);
-
-/* Return a count of entries matching 'want_type' */
-__LA_DECL int archive_entry_acl_count(struct archive_entry *, int /* want_type */);
-
-/* Return an opaque ACL object. */
-/* There's not yet anything clients can actually do with this... */
-struct archive_acl;
-__LA_DECL struct archive_acl *archive_entry_acl(struct archive_entry *);
-
-/*
- * extended attributes
- */
-
-__LA_DECL void archive_entry_xattr_clear(struct archive_entry *);
-__LA_DECL void archive_entry_xattr_add_entry(struct archive_entry *,
- const char * /* name */, const void * /* value */,
- size_t /* size */);
-
-/*
- * To retrieve the xattr list, first "reset", then repeatedly ask for the
- * "next" entry.
- */
-
-__LA_DECL int archive_entry_xattr_count(struct archive_entry *);
-__LA_DECL int archive_entry_xattr_reset(struct archive_entry *);
-__LA_DECL int archive_entry_xattr_next(struct archive_entry *,
- const char ** /* name */, const void ** /* value */, size_t *);
-
-/*
- * sparse
- */
-
-__LA_DECL void archive_entry_sparse_clear(struct archive_entry *);
-__LA_DECL void archive_entry_sparse_add_entry(struct archive_entry *,
- la_int64_t /* offset */, la_int64_t /* length */);
-
-/*
- * To retrieve the xattr list, first "reset", then repeatedly ask for the
- * "next" entry.
- */
-
-__LA_DECL int archive_entry_sparse_count(struct archive_entry *);
-__LA_DECL int archive_entry_sparse_reset(struct archive_entry *);
-__LA_DECL int archive_entry_sparse_next(struct archive_entry *,
- la_int64_t * /* offset */, la_int64_t * /* length */);
-
-/*
- * Utility to match up hardlinks.
- *
- * The 'struct archive_entry_linkresolver' is a cache of archive entries
- * for files with multiple links. Here's how to use it:
- * 1. Create a lookup object with archive_entry_linkresolver_new()
- * 2. Tell it the archive format you're using.
- * 3. Hand each archive_entry to archive_entry_linkify().
- * That function will return 0, 1, or 2 entries that should
- * be written.
- * 4. Call archive_entry_linkify(resolver, NULL) until
- * no more entries are returned.
- * 5. Call archive_entry_linkresolver_free(resolver) to free resources.
- *
- * The entries returned have their hardlink and size fields updated
- * appropriately. If an entry is passed in that does not refer to
- * a file with multiple links, it is returned unchanged. The intention
- * is that you should be able to simply filter all entries through
- * this machine.
- *
- * To make things more efficient, be sure that each entry has a valid
- * nlinks value. The hardlink cache uses this to track when all links
- * have been found. If the nlinks value is zero, it will keep every
- * name in the cache indefinitely, which can use a lot of memory.
- *
- * Note that archive_entry_size() is reset to zero if the file
- * body should not be written to the archive. Pay attention!
- */
-struct archive_entry_linkresolver;
-
-/*
- * There are three different strategies for marking hardlinks.
- * The descriptions below name them after the best-known
- * formats that rely on each strategy:
- *
- * "Old cpio" is the simplest, it always returns any entry unmodified.
- * As far as I know, only cpio formats use this. Old cpio archives
- * store every link with the full body; the onus is on the dearchiver
- * to detect and properly link the files as they are restored.
- * "tar" is also pretty simple; it caches a copy the first time it sees
- * any link. Subsequent appearances are modified to be hardlink
- * references to the first one without any body. Used by all tar
- * formats, although the newest tar formats permit the "old cpio" strategy
- * as well. This strategy is very simple for the dearchiver,
- * and reasonably straightforward for the archiver.
- * "new cpio" is trickier. It stores the body only with the last
- * occurrence. The complication is that we might not
- * see every link to a particular file in a single session, so
- * there's no easy way to know when we've seen the last occurrence.
- * The solution here is to queue one link until we see the next.
- * At the end of the session, you can enumerate any remaining
- * entries by calling archive_entry_linkify(NULL) and store those
- * bodies. If you have a file with three links l1, l2, and l3,
- * you'll get the following behavior if you see all three links:
- * linkify(l1) => NULL (the resolver stores l1 internally)
- * linkify(l2) => l1 (resolver stores l2, you write l1)
- * linkify(l3) => l2, l3 (all links seen, you can write both).
- * If you only see l1 and l2, you'll get this behavior:
- * linkify(l1) => NULL
- * linkify(l2) => l1
- * linkify(NULL) => l2 (at end, you retrieve remaining links)
- * As the name suggests, this strategy is used by newer cpio variants.
- * It's noticeably more complex for the archiver, slightly more complex
- * for the dearchiver than the tar strategy, but makes it straightforward
- * to restore a file using any link by simply continuing to scan until
- * you see a link that is stored with a body. In contrast, the tar
- * strategy requires you to rescan the archive from the beginning to
- * correctly extract an arbitrary link.
- */
-
-__LA_DECL struct archive_entry_linkresolver *archive_entry_linkresolver_new(void);
-__LA_DECL void archive_entry_linkresolver_set_strategy(
- struct archive_entry_linkresolver *, int /* format_code */);
-__LA_DECL void archive_entry_linkresolver_free(struct archive_entry_linkresolver *);
-__LA_DECL void archive_entry_linkify(struct archive_entry_linkresolver *,
- struct archive_entry **, struct archive_entry **);
-__LA_DECL struct archive_entry *archive_entry_partial_links(
- struct archive_entry_linkresolver *res, unsigned int *links);
-#ifdef __cplusplus
-}
-#endif
-
-/* This is meaningless outside of this header. */
-#undef __LA_DECL
-
-#endif /* !ARCHIVE_ENTRY_H_INCLUDED */
diff --git a/contrib/libs/libarchive/libarchive/archive_entry_copy_bhfi.c b/contrib/libs/libarchive/libarchive/archive_entry_copy_bhfi.c
deleted file mode 100644
index 77bf38e450..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_entry_copy_bhfi.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#include "archive_private.h"
-#include "archive_entry.h"
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-
-#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
-
-__inline static void
-fileTimeToUtc(const FILETIME *filetime, time_t *t, long *ns)
-{
- ULARGE_INTEGER utc;
-
- utc.HighPart = filetime->dwHighDateTime;
- utc.LowPart = filetime->dwLowDateTime;
- if (utc.QuadPart >= EPOC_TIME) {
- utc.QuadPart -= EPOC_TIME;
- *t = (time_t)(utc.QuadPart / 10000000); /* milli seconds base */
- *ns = (long)(utc.QuadPart % 10000000) * 100;/* nano seconds base */
- } else {
- *t = 0;
- *ns = 0;
- }
-}
-
-void
-archive_entry_copy_bhfi(struct archive_entry *entry,
- BY_HANDLE_FILE_INFORMATION *bhfi)
-{
- time_t secs;
- long nsecs;
-
- fileTimeToUtc(&bhfi->ftLastAccessTime, &secs, &nsecs);
- archive_entry_set_atime(entry, secs, nsecs);
- fileTimeToUtc(&bhfi->ftLastWriteTime, &secs, &nsecs);
- archive_entry_set_mtime(entry, secs, nsecs);
- fileTimeToUtc(&bhfi->ftCreationTime, &secs, &nsecs);
- archive_entry_set_birthtime(entry, secs, nsecs);
- archive_entry_set_ctime(entry, secs, nsecs);
- archive_entry_set_dev(entry, bhfi->dwVolumeSerialNumber);
- archive_entry_set_ino64(entry, (((int64_t)bhfi->nFileIndexHigh) << 32)
- + bhfi->nFileIndexLow);
- archive_entry_set_nlink(entry, bhfi->nNumberOfLinks);
- archive_entry_set_size(entry, (((int64_t)bhfi->nFileSizeHigh) << 32)
- + bhfi->nFileSizeLow);
- /* archive_entry_set_mode(entry, st->st_mode); */
-}
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_entry_copy_stat.c b/contrib/libs/libarchive/libarchive/archive_entry_copy_stat.c
deleted file mode 100644
index ac83868e8f..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_entry_copy_stat.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_copy_stat.c 189466 2009-03-07 00:52:02Z kientzle $");
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-
-void
-archive_entry_copy_stat(struct archive_entry *entry, const struct stat *st)
-{
-#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
- archive_entry_set_atime(entry, st->st_atime, st->st_atimespec.tv_nsec);
- archive_entry_set_ctime(entry, st->st_ctime, st->st_ctimespec.tv_nsec);
- archive_entry_set_mtime(entry, st->st_mtime, st->st_mtimespec.tv_nsec);
-#elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
- archive_entry_set_atime(entry, st->st_atime, st->st_atim.tv_nsec);
- archive_entry_set_ctime(entry, st->st_ctime, st->st_ctim.tv_nsec);
- archive_entry_set_mtime(entry, st->st_mtime, st->st_mtim.tv_nsec);
-#elif HAVE_STRUCT_STAT_ST_MTIME_NSEC
- archive_entry_set_atime(entry, st->st_atime, st->st_atime_nsec);
- archive_entry_set_ctime(entry, st->st_ctime, st->st_ctime_nsec);
- archive_entry_set_mtime(entry, st->st_mtime, st->st_mtime_nsec);
-#elif HAVE_STRUCT_STAT_ST_MTIME_N
- archive_entry_set_atime(entry, st->st_atime, st->st_atime_n);
- archive_entry_set_ctime(entry, st->st_ctime, st->st_ctime_n);
- archive_entry_set_mtime(entry, st->st_mtime, st->st_mtime_n);
-#elif HAVE_STRUCT_STAT_ST_UMTIME
- archive_entry_set_atime(entry, st->st_atime, st->st_uatime * 1000);
- archive_entry_set_ctime(entry, st->st_ctime, st->st_uctime * 1000);
- archive_entry_set_mtime(entry, st->st_mtime, st->st_umtime * 1000);
-#elif HAVE_STRUCT_STAT_ST_MTIME_USEC
- archive_entry_set_atime(entry, st->st_atime, st->st_atime_usec * 1000);
- archive_entry_set_ctime(entry, st->st_ctime, st->st_ctime_usec * 1000);
- archive_entry_set_mtime(entry, st->st_mtime, st->st_mtime_usec * 1000);
-#else
- archive_entry_set_atime(entry, st->st_atime, 0);
- archive_entry_set_ctime(entry, st->st_ctime, 0);
- archive_entry_set_mtime(entry, st->st_mtime, 0);
-#endif
-#if HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC
- archive_entry_set_birthtime(entry, st->st_birthtime, st->st_birthtimespec.tv_nsec);
-#elif HAVE_STRUCT_STAT_ST_BIRTHTIME
- archive_entry_set_birthtime(entry, st->st_birthtime, 0);
-#else
- archive_entry_unset_birthtime(entry);
-#endif
- archive_entry_set_dev(entry, st->st_dev);
- archive_entry_set_gid(entry, st->st_gid);
- archive_entry_set_uid(entry, st->st_uid);
- archive_entry_set_ino(entry, st->st_ino);
- archive_entry_set_nlink(entry, st->st_nlink);
- archive_entry_set_rdev(entry, st->st_rdev);
- archive_entry_set_size(entry, st->st_size);
- archive_entry_set_mode(entry, st->st_mode);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_entry_link_resolver.c b/contrib/libs/libarchive/libarchive/archive_entry_link_resolver.c
deleted file mode 100644
index c7d59497a7..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_entry_link_resolver.c
+++ /dev/null
@@ -1,447 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_link_resolver.c 201100 2009-12-28 03:05:31Z kientzle $");
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-
-/*
- * This is mostly a pretty straightforward hash table implementation.
- * The only interesting bit is the different strategies used to
- * match up links. These strategies match those used by various
- * archiving formats:
- * tar - content stored with first link, remainder refer back to it.
- * This requires us to match each subsequent link up with the
- * first appearance.
- * cpio - Old cpio just stored body with each link, match-ups were
- * implicit. This is trivial.
- * new cpio - New cpio only stores body with last link, match-ups
- * are implicit. This is actually quite tricky; see the notes
- * below.
- */
-
-/* Users pass us a format code, we translate that into a strategy here. */
-#define ARCHIVE_ENTRY_LINKIFY_LIKE_TAR 0
-#define ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE 1
-#define ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO 2
-#define ARCHIVE_ENTRY_LINKIFY_LIKE_NEW_CPIO 3
-
-/* Initial size of link cache. */
-#define links_cache_initial_size 1024
-
-struct links_entry {
- struct links_entry *next;
- struct links_entry *previous;
- struct archive_entry *canonical;
- struct archive_entry *entry;
- size_t hash;
- unsigned int links; /* # links not yet seen */
-};
-
-struct archive_entry_linkresolver {
- struct links_entry **buckets;
- struct links_entry *spare;
- unsigned long number_entries;
- size_t number_buckets;
- int strategy;
-};
-
-#define NEXT_ENTRY_DEFERRED 1
-#define NEXT_ENTRY_PARTIAL 2
-#define NEXT_ENTRY_ALL (NEXT_ENTRY_DEFERRED | NEXT_ENTRY_PARTIAL)
-
-static struct links_entry *find_entry(struct archive_entry_linkresolver *,
- struct archive_entry *);
-static void grow_hash(struct archive_entry_linkresolver *);
-static struct links_entry *insert_entry(struct archive_entry_linkresolver *,
- struct archive_entry *);
-static struct links_entry *next_entry(struct archive_entry_linkresolver *,
- int);
-
-struct archive_entry_linkresolver *
-archive_entry_linkresolver_new(void)
-{
- struct archive_entry_linkresolver *res;
-
- /* Check for positive power-of-two */
- if (links_cache_initial_size == 0 ||
- (links_cache_initial_size & (links_cache_initial_size - 1)) != 0)
- return (NULL);
-
- res = calloc(1, sizeof(struct archive_entry_linkresolver));
- if (res == NULL)
- return (NULL);
- res->number_buckets = links_cache_initial_size;
- res->buckets = calloc(res->number_buckets, sizeof(res->buckets[0]));
- if (res->buckets == NULL) {
- free(res);
- return (NULL);
- }
- return (res);
-}
-
-void
-archive_entry_linkresolver_set_strategy(struct archive_entry_linkresolver *res,
- int fmt)
-{
- int fmtbase = fmt & ARCHIVE_FORMAT_BASE_MASK;
-
- switch (fmtbase) {
- case ARCHIVE_FORMAT_7ZIP:
- case ARCHIVE_FORMAT_AR:
- case ARCHIVE_FORMAT_ZIP:
- res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO;
- break;
- case ARCHIVE_FORMAT_CPIO:
- switch (fmt) {
- case ARCHIVE_FORMAT_CPIO_SVR4_NOCRC:
- case ARCHIVE_FORMAT_CPIO_SVR4_CRC:
- res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_NEW_CPIO;
- break;
- default:
- res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO;
- break;
- }
- break;
- case ARCHIVE_FORMAT_MTREE:
- res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE;
- break;
- case ARCHIVE_FORMAT_ISO9660:
- case ARCHIVE_FORMAT_SHAR:
- case ARCHIVE_FORMAT_TAR:
- case ARCHIVE_FORMAT_XAR:
- res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_TAR;
- break;
- default:
- res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO;
- break;
- }
-}
-
-void
-archive_entry_linkresolver_free(struct archive_entry_linkresolver *res)
-{
- struct links_entry *le;
-
- if (res == NULL)
- return;
-
- while ((le = next_entry(res, NEXT_ENTRY_ALL)) != NULL)
- archive_entry_free(le->entry);
- free(res->buckets);
- free(res);
-}
-
-void
-archive_entry_linkify(struct archive_entry_linkresolver *res,
- struct archive_entry **e, struct archive_entry **f)
-{
- struct links_entry *le;
- struct archive_entry *t;
-
- *f = NULL; /* Default: Don't return a second entry. */
-
- if (*e == NULL) {
- le = next_entry(res, NEXT_ENTRY_DEFERRED);
- if (le != NULL) {
- *e = le->entry;
- le->entry = NULL;
- }
- return;
- }
-
- /* If it has only one link, then we're done. */
- if (archive_entry_nlink(*e) == 1)
- return;
- /* Directories, devices never have hardlinks. */
- if (archive_entry_filetype(*e) == AE_IFDIR
- || archive_entry_filetype(*e) == AE_IFBLK
- || archive_entry_filetype(*e) == AE_IFCHR)
- return;
-
- switch (res->strategy) {
- case ARCHIVE_ENTRY_LINKIFY_LIKE_TAR:
- le = find_entry(res, *e);
- if (le != NULL) {
- archive_entry_unset_size(*e);
- archive_entry_copy_hardlink(*e,
- archive_entry_pathname(le->canonical));
- } else
- insert_entry(res, *e);
- return;
- case ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE:
- le = find_entry(res, *e);
- if (le != NULL) {
- archive_entry_copy_hardlink(*e,
- archive_entry_pathname(le->canonical));
- } else
- insert_entry(res, *e);
- return;
- case ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO:
- /* This one is trivial. */
- return;
- case ARCHIVE_ENTRY_LINKIFY_LIKE_NEW_CPIO:
- le = find_entry(res, *e);
- if (le != NULL) {
- /*
- * Put the new entry in le, return the
- * old entry from le.
- */
- t = *e;
- *e = le->entry;
- le->entry = t;
- /* Make the old entry into a hardlink. */
- archive_entry_unset_size(*e);
- archive_entry_copy_hardlink(*e,
- archive_entry_pathname(le->canonical));
- /* If we ran out of links, return the
- * final entry as well. */
- if (le->links == 0) {
- *f = le->entry;
- le->entry = NULL;
- }
- } else {
- /*
- * If we haven't seen it, tuck it away
- * for future use.
- */
- le = insert_entry(res, *e);
- if (le == NULL)
- /* XXX We should return an error code XXX */
- return;
- le->entry = *e;
- *e = NULL;
- }
- return;
- default:
- break;
- }
- return;
-}
-
-static struct links_entry *
-find_entry(struct archive_entry_linkresolver *res,
- struct archive_entry *entry)
-{
- struct links_entry *le;
- size_t hash, bucket;
- dev_t dev;
- int64_t ino;
-
- /* Free a held entry. */
- if (res->spare != NULL) {
- archive_entry_free(res->spare->canonical);
- archive_entry_free(res->spare->entry);
- free(res->spare);
- res->spare = NULL;
- }
-
- dev = archive_entry_dev(entry);
- ino = archive_entry_ino64(entry);
- hash = (size_t)(dev ^ ino);
-
- /* Try to locate this entry in the links cache. */
- bucket = hash & (res->number_buckets - 1);
- for (le = res->buckets[bucket]; le != NULL; le = le->next) {
- if (le->hash == hash
- && dev == archive_entry_dev(le->canonical)
- && ino == archive_entry_ino64(le->canonical)) {
- /*
- * Decrement link count each time and release
- * the entry if it hits zero. This saves
- * memory and is necessary for detecting
- * missed links.
- */
- --le->links;
- if (le->links > 0)
- return (le);
- /* Remove it from this hash bucket. */
- if (le->previous != NULL)
- le->previous->next = le->next;
- if (le->next != NULL)
- le->next->previous = le->previous;
- if (res->buckets[bucket] == le)
- res->buckets[bucket] = le->next;
- res->number_entries--;
- /* Defer freeing this entry. */
- res->spare = le;
- return (le);
- }
- }
- return (NULL);
-}
-
-static struct links_entry *
-next_entry(struct archive_entry_linkresolver *res, int mode)
-{
- struct links_entry *le;
- size_t bucket;
-
- /* Free a held entry. */
- if (res->spare != NULL) {
- archive_entry_free(res->spare->canonical);
- archive_entry_free(res->spare->entry);
- free(res->spare);
- res->spare = NULL;
- }
-
- /* Look for next non-empty bucket in the links cache. */
- for (bucket = 0; bucket < res->number_buckets; bucket++) {
- for (le = res->buckets[bucket]; le != NULL; le = le->next) {
- if (le->entry != NULL &&
- (mode & NEXT_ENTRY_DEFERRED) == 0)
- continue;
- if (le->entry == NULL &&
- (mode & NEXT_ENTRY_PARTIAL) == 0)
- continue;
- /* Remove it from this hash bucket. */
- if (le->next != NULL)
- le->next->previous = le->previous;
- if (le->previous != NULL)
- le->previous->next = le->next;
- else
- res->buckets[bucket] = le->next;
- res->number_entries--;
- /* Defer freeing this entry. */
- res->spare = le;
- return (le);
- }
- }
- return (NULL);
-}
-
-static struct links_entry *
-insert_entry(struct archive_entry_linkresolver *res,
- struct archive_entry *entry)
-{
- struct links_entry *le;
- size_t hash, bucket;
-
- /* Add this entry to the links cache. */
- le = calloc(1, sizeof(struct links_entry));
- if (le == NULL)
- return (NULL);
- le->canonical = archive_entry_clone(entry);
-
- /* If the links cache is getting too full, enlarge the hash table. */
- if (res->number_entries > res->number_buckets * 2)
- grow_hash(res);
-
- hash = (size_t)(archive_entry_dev(entry) ^ archive_entry_ino64(entry));
- bucket = hash & (res->number_buckets - 1);
-
- /* If we could allocate the entry, record it. */
- if (res->buckets[bucket] != NULL)
- res->buckets[bucket]->previous = le;
- res->number_entries++;
- le->next = res->buckets[bucket];
- le->previous = NULL;
- res->buckets[bucket] = le;
- le->hash = hash;
- le->links = archive_entry_nlink(entry) - 1;
- return (le);
-}
-
-static void
-grow_hash(struct archive_entry_linkresolver *res)
-{
- struct links_entry *le, **new_buckets;
- size_t new_size;
- size_t i, bucket;
-
- /* Try to enlarge the bucket list. */
- new_size = res->number_buckets * 2;
- if (new_size < res->number_buckets)
- return;
- new_buckets = calloc(new_size, sizeof(struct links_entry *));
-
- if (new_buckets == NULL)
- return;
-
- for (i = 0; i < res->number_buckets; i++) {
- while (res->buckets[i] != NULL) {
- /* Remove entry from old bucket. */
- le = res->buckets[i];
- res->buckets[i] = le->next;
-
- /* Add entry to new bucket. */
- bucket = le->hash & (new_size - 1);
-
- if (new_buckets[bucket] != NULL)
- new_buckets[bucket]->previous = le;
- le->next = new_buckets[bucket];
- le->previous = NULL;
- new_buckets[bucket] = le;
- }
- }
- free(res->buckets);
- res->buckets = new_buckets;
- res->number_buckets = new_size;
-}
-
-struct archive_entry *
-archive_entry_partial_links(struct archive_entry_linkresolver *res,
- unsigned int *links)
-{
- struct archive_entry *e;
- struct links_entry *le;
-
- /* Free a held entry. */
- if (res->spare != NULL) {
- archive_entry_free(res->spare->canonical);
- archive_entry_free(res->spare->entry);
- free(res->spare);
- res->spare = NULL;
- }
-
- le = next_entry(res, NEXT_ENTRY_PARTIAL);
- if (le != NULL) {
- e = le->canonical;
- if (links != NULL)
- *links = le->links;
- le->canonical = NULL;
- } else {
- e = NULL;
- if (links != NULL)
- *links = 0;
- }
- return (e);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_entry_locale.h b/contrib/libs/libarchive/libarchive/archive_entry_locale.h
deleted file mode 100644
index 803c0368bb..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_entry_locale.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*-
- * Copyright (c) 2011 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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.
- *
- * $FreeBSD$
- */
-
-#ifndef ARCHIVE_ENTRY_LOCALE_H_INCLUDED
-#define ARCHIVE_ENTRY_LOCALE_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
-struct archive_entry;
-struct archive_string_conv;
-
-/*
- * Utility functions to set and get entry attributes by translating
- * character-set. These are designed for use in format readers and writers.
- *
- * The return code and interface of these are quite different from other
- * functions for archive_entry defined in archive_entry.h.
- * Common return code are:
- * Return 0 if the string conversion succeeded.
- * Return -1 if the string conversion failed.
- */
-
-#define archive_entry_gname_l _archive_entry_gname_l
-int _archive_entry_gname_l(struct archive_entry *,
- const char **, size_t *, struct archive_string_conv *);
-#define archive_entry_hardlink_l _archive_entry_hardlink_l
-int _archive_entry_hardlink_l(struct archive_entry *,
- const char **, size_t *, struct archive_string_conv *);
-#define archive_entry_pathname_l _archive_entry_pathname_l
-int _archive_entry_pathname_l(struct archive_entry *,
- const char **, size_t *, struct archive_string_conv *);
-#define archive_entry_symlink_l _archive_entry_symlink_l
-int _archive_entry_symlink_l(struct archive_entry *,
- const char **, size_t *, struct archive_string_conv *);
-#define archive_entry_uname_l _archive_entry_uname_l
-int _archive_entry_uname_l(struct archive_entry *,
- const char **, size_t *, struct archive_string_conv *);
-#define archive_entry_acl_text_l _archive_entry_acl_text_l
-int _archive_entry_acl_text_l(struct archive_entry *, int,
-const char **, size_t *, struct archive_string_conv *) __LA_DEPRECATED;
-#define archive_entry_acl_to_text_l _archive_entry_acl_to_text_l
-char *_archive_entry_acl_to_text_l(struct archive_entry *, ssize_t *, int,
- struct archive_string_conv *);
-#define archive_entry_acl_from_text_l _archive_entry_acl_from_text_l
-int _archive_entry_acl_from_text_l(struct archive_entry *, const char* text,
- int type, struct archive_string_conv *);
-#define archive_entry_copy_gname_l _archive_entry_copy_gname_l
-int _archive_entry_copy_gname_l(struct archive_entry *,
- const char *, size_t, struct archive_string_conv *);
-#define archive_entry_copy_hardlink_l _archive_entry_copy_hardlink_l
-int _archive_entry_copy_hardlink_l(struct archive_entry *,
- const char *, size_t, struct archive_string_conv *);
-#define archive_entry_copy_link_l _archive_entry_copy_link_l
-int _archive_entry_copy_link_l(struct archive_entry *,
- const char *, size_t, struct archive_string_conv *);
-#define archive_entry_copy_pathname_l _archive_entry_copy_pathname_l
-int _archive_entry_copy_pathname_l(struct archive_entry *,
- const char *, size_t, struct archive_string_conv *);
-#define archive_entry_copy_symlink_l _archive_entry_copy_symlink_l
-int _archive_entry_copy_symlink_l(struct archive_entry *,
- const char *, size_t, struct archive_string_conv *);
-#define archive_entry_copy_uname_l _archive_entry_copy_uname_l
-int _archive_entry_copy_uname_l(struct archive_entry *,
- const char *, size_t, struct archive_string_conv *);
-
-#endif /* ARCHIVE_ENTRY_LOCALE_H_INCLUDED */
diff --git a/contrib/libs/libarchive/libarchive/archive_entry_private.h b/contrib/libs/libarchive/libarchive/archive_entry_private.h
deleted file mode 100644
index cf4deb24ec..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_entry_private.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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.
- *
- * $FreeBSD: head/lib/libarchive/archive_entry_private.h 201096 2009-12-28 02:41:27Z kientzle $
- */
-
-#ifndef ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
-#define ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
-#include "archive_acl_private.h"
-#include "archive_string.h"
-
-struct ae_xattr {
- struct ae_xattr *next;
-
- char *name;
- void *value;
- size_t size;
-};
-
-struct ae_sparse {
- struct ae_sparse *next;
-
- int64_t offset;
- int64_t length;
-};
-
-struct ae_digest {
- unsigned char md5[16];
- unsigned char rmd160[20];
- unsigned char sha1[20];
- unsigned char sha256[32];
- unsigned char sha384[48];
- unsigned char sha512[64];
-};
-
-/*
- * Description of an archive entry.
- *
- * Basically, this is a "struct stat" with a few text fields added in.
- *
- * TODO: Add "comment", "charset", and possibly other entries
- * that are supported by "pax interchange" format. However, GNU, ustar,
- * cpio, and other variants don't support these features, so they're not an
- * excruciatingly high priority right now.
- *
- * TODO: "pax interchange" format allows essentially arbitrary
- * key/value attributes to be attached to any entry. Supporting
- * such extensions may make this library useful for special
- * applications (e.g., a package manager could attach special
- * package-management attributes to each entry). There are tricky
- * API issues involved, so this is not going to happen until
- * there's a real demand for it.
- *
- * TODO: Design a good API for handling sparse files.
- */
-struct archive_entry {
- struct archive *archive;
-
- /*
- * Note that ae_stat.st_mode & AE_IFMT can be 0!
- *
- * This occurs when the actual file type of the object is not
- * in the archive. For example, 'tar' archives store
- * hardlinks without marking the type of the underlying
- * object.
- */
-
- /*
- * We have a "struct aest" for holding file metadata rather than just
- * a "struct stat" because on some platforms the "struct stat" has
- * fields which are too narrow to hold the range of possible values;
- * we don't want to lose information if we read an archive and write
- * out another (e.g., in "tar -cf new.tar @old.tar").
- *
- * The "stat" pointer points to some form of platform-specific struct
- * stat; it is declared as a void * rather than a struct stat * as
- * some platforms have multiple varieties of stat structures.
- */
- void *stat;
- int stat_valid; /* Set to 0 whenever a field in aest changes. */
-
- struct aest {
- int64_t aest_atime;
- uint32_t aest_atime_nsec;
- int64_t aest_ctime;
- uint32_t aest_ctime_nsec;
- int64_t aest_mtime;
- uint32_t aest_mtime_nsec;
- int64_t aest_birthtime;
- uint32_t aest_birthtime_nsec;
- int64_t aest_gid;
- int64_t aest_ino;
- uint32_t aest_nlink;
- uint64_t aest_size;
- int64_t aest_uid;
- /*
- * Because converting between device codes and
- * major/minor values is platform-specific and
- * inherently a bit risky, we only do that conversion
- * lazily. That way, we will do a better job of
- * preserving information in those cases where no
- * conversion is actually required.
- */
- int aest_dev_is_broken_down;
- dev_t aest_dev;
- dev_t aest_devmajor;
- dev_t aest_devminor;
- int aest_rdev_is_broken_down;
- dev_t aest_rdev;
- dev_t aest_rdevmajor;
- dev_t aest_rdevminor;
- } ae_stat;
-
- int ae_set; /* bitmap of fields that are currently set */
-#define AE_SET_HARDLINK 1
-#define AE_SET_SYMLINK 2
-#define AE_SET_ATIME 4
-#define AE_SET_CTIME 8
-#define AE_SET_MTIME 16
-#define AE_SET_BIRTHTIME 32
-#define AE_SET_SIZE 64
-#define AE_SET_INO 128
-#define AE_SET_DEV 256
-
- /*
- * Use aes here so that we get transparent mbs<->wcs conversions.
- */
- struct archive_mstring ae_fflags_text; /* Text fflags per fflagstostr(3) */
- unsigned long ae_fflags_set; /* Bitmap fflags */
- unsigned long ae_fflags_clear;
- struct archive_mstring ae_gname; /* Name of owning group */
- struct archive_mstring ae_hardlink; /* Name of target for hardlink */
- struct archive_mstring ae_pathname; /* Name of entry */
- struct archive_mstring ae_symlink; /* symlink contents */
- struct archive_mstring ae_uname; /* Name of owner */
-
- /* Not used within libarchive; useful for some clients. */
- struct archive_mstring ae_sourcepath; /* Path this entry is sourced from. */
-
-#define AE_ENCRYPTION_NONE 0
-#define AE_ENCRYPTION_DATA 1
-#define AE_ENCRYPTION_METADATA 2
- char encryption;
-
- void *mac_metadata;
- size_t mac_metadata_size;
-
- /* Digest support. */
- struct ae_digest digest;
-
- /* ACL support. */
- struct archive_acl acl;
-
- /* extattr support. */
- struct ae_xattr *xattr_head;
- struct ae_xattr *xattr_p;
-
- /* sparse support. */
- struct ae_sparse *sparse_head;
- struct ae_sparse *sparse_tail;
- struct ae_sparse *sparse_p;
-
- /* Miscellaneous. */
- char strmode[12];
-
- /* Symlink type support */
- int ae_symlink_type;
-};
-
-int
-archive_entry_set_digest(struct archive_entry *entry, int type,
- const unsigned char *digest);
-
-#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */
diff --git a/contrib/libs/libarchive/libarchive/archive_entry_sparse.c b/contrib/libs/libarchive/libarchive/archive_entry_sparse.c
deleted file mode 100644
index 74917b37b8..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_entry_sparse.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * Copyright (c) 2010-2011 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_private.h"
-#include "archive_entry_private.h"
-
-/*
- * sparse handling
- */
-
-void
-archive_entry_sparse_clear(struct archive_entry *entry)
-{
- struct ae_sparse *sp;
-
- while (entry->sparse_head != NULL) {
- sp = entry->sparse_head->next;
- free(entry->sparse_head);
- entry->sparse_head = sp;
- }
- entry->sparse_tail = NULL;
-}
-
-void
-archive_entry_sparse_add_entry(struct archive_entry *entry,
- la_int64_t offset, la_int64_t length)
-{
- struct ae_sparse *sp;
-
- if (offset < 0 || length < 0)
- /* Invalid value */
- return;
- if (offset > INT64_MAX - length ||
- offset + length > archive_entry_size(entry))
- /* A value of "length" parameter is too large. */
- return;
- if ((sp = entry->sparse_tail) != NULL) {
- if (sp->offset + sp->length > offset)
- /* Invalid value. */
- return;
- if (sp->offset + sp->length == offset) {
- if (sp->offset + sp->length + length < 0)
- /* A value of "length" parameter is
- * too large. */
- return;
- /* Expand existing sparse block size. */
- sp->length += length;
- return;
- }
- }
-
- if ((sp = (struct ae_sparse *)malloc(sizeof(*sp))) == NULL)
- /* XXX Error XXX */
- return;
-
- sp->offset = offset;
- sp->length = length;
- sp->next = NULL;
-
- if (entry->sparse_head == NULL)
- entry->sparse_head = entry->sparse_tail = sp;
- else {
- /* Add a new sparse block to the tail of list. */
- if (entry->sparse_tail != NULL)
- entry->sparse_tail->next = sp;
- entry->sparse_tail = sp;
- }
-}
-
-
-/*
- * returns number of the sparse entries
- */
-int
-archive_entry_sparse_count(struct archive_entry *entry)
-{
- struct ae_sparse *sp;
- int count = 0;
-
- for (sp = entry->sparse_head; sp != NULL; sp = sp->next)
- count++;
-
- /*
- * Sanity check if this entry is exactly sparse.
- * If amount of sparse blocks is just one and it indicates the whole
- * file data, we should remove it and return zero.
- */
- if (count == 1) {
- sp = entry->sparse_head;
- if (sp->offset == 0 &&
- sp->length >= archive_entry_size(entry)) {
- count = 0;
- archive_entry_sparse_clear(entry);
- }
- }
-
- return (count);
-}
-
-int
-archive_entry_sparse_reset(struct archive_entry * entry)
-{
- entry->sparse_p = entry->sparse_head;
-
- return archive_entry_sparse_count(entry);
-}
-
-int
-archive_entry_sparse_next(struct archive_entry * entry,
- la_int64_t *offset, la_int64_t *length)
-{
- if (entry->sparse_p) {
- *offset = entry->sparse_p->offset;
- *length = entry->sparse_p->length;
-
- entry->sparse_p = entry->sparse_p->next;
-
- return (ARCHIVE_OK);
- } else {
- *offset = 0;
- *length = 0;
- return (ARCHIVE_WARN);
- }
-}
-
-/*
- * end of sparse handling
- */
diff --git a/contrib/libs/libarchive/libarchive/archive_entry_stat.c b/contrib/libs/libarchive/libarchive/archive_entry_stat.c
deleted file mode 100644
index 71a407b1f8..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_entry_stat.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_stat.c 201100 2009-12-28 03:05:31Z kientzle $");
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#include "archive_entry.h"
-#include "archive_entry_private.h"
-
-const struct stat *
-archive_entry_stat(struct archive_entry *entry)
-{
- struct stat *st;
- if (entry->stat == NULL) {
- entry->stat = calloc(1, sizeof(*st));
- if (entry->stat == NULL)
- return (NULL);
- entry->stat_valid = 0;
- }
-
- /*
- * If none of the underlying fields have been changed, we
- * don't need to regenerate. In theory, we could use a bitmap
- * here to flag only those items that have changed, but the
- * extra complexity probably isn't worth it. It will be very
- * rare for anyone to change just one field then request a new
- * stat structure.
- */
- if (entry->stat_valid)
- return (entry->stat);
-
- st = entry->stat;
- /*
- * Use the public interfaces to extract items, so that
- * the appropriate conversions get invoked.
- */
- st->st_atime = archive_entry_atime(entry);
-#if HAVE_STRUCT_STAT_ST_BIRTHTIME
- st->st_birthtime = archive_entry_birthtime(entry);
-#endif
- st->st_ctime = archive_entry_ctime(entry);
- st->st_mtime = archive_entry_mtime(entry);
- st->st_dev = archive_entry_dev(entry);
- st->st_gid = (gid_t)archive_entry_gid(entry);
- st->st_uid = (uid_t)archive_entry_uid(entry);
- st->st_ino = (ino_t)archive_entry_ino64(entry);
- st->st_nlink = archive_entry_nlink(entry);
- st->st_rdev = archive_entry_rdev(entry);
- st->st_size = (off_t)archive_entry_size(entry);
- st->st_mode = archive_entry_mode(entry);
-
- /*
- * On systems that support high-res timestamps, copy that
- * information into struct stat.
- */
-#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
- st->st_atimespec.tv_nsec = archive_entry_atime_nsec(entry);
- st->st_ctimespec.tv_nsec = archive_entry_ctime_nsec(entry);
- st->st_mtimespec.tv_nsec = archive_entry_mtime_nsec(entry);
-#elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
- st->st_atim.tv_nsec = archive_entry_atime_nsec(entry);
- st->st_ctim.tv_nsec = archive_entry_ctime_nsec(entry);
- st->st_mtim.tv_nsec = archive_entry_mtime_nsec(entry);
-#elif HAVE_STRUCT_STAT_ST_MTIME_N
- st->st_atime_n = archive_entry_atime_nsec(entry);
- st->st_ctime_n = archive_entry_ctime_nsec(entry);
- st->st_mtime_n = archive_entry_mtime_nsec(entry);
-#elif HAVE_STRUCT_STAT_ST_UMTIME
- st->st_uatime = archive_entry_atime_nsec(entry) / 1000;
- st->st_uctime = archive_entry_ctime_nsec(entry) / 1000;
- st->st_umtime = archive_entry_mtime_nsec(entry) / 1000;
-#elif HAVE_STRUCT_STAT_ST_MTIME_USEC
- st->st_atime_usec = archive_entry_atime_nsec(entry) / 1000;
- st->st_ctime_usec = archive_entry_ctime_nsec(entry) / 1000;
- st->st_mtime_usec = archive_entry_mtime_nsec(entry) / 1000;
-#endif
-#if HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC
- st->st_birthtimespec.tv_nsec = archive_entry_birthtime_nsec(entry);
-#endif
-
- /*
- * TODO: On Linux, store 32 or 64 here depending on whether
- * the cached stat structure is a stat32 or a stat64. This
- * will allow us to support both variants interchangeably.
- */
- entry->stat_valid = 1;
-
- return (st);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_entry_strmode.c b/contrib/libs/libarchive/libarchive/archive_entry_strmode.c
deleted file mode 100644
index af2517a321..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_entry_strmode.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_entry_strmode.c,v 1.4 2008/06/15 05:14:01 kientzle Exp $");
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive_entry.h"
-#include "archive_entry_private.h"
-
-const char *
-archive_entry_strmode(struct archive_entry *entry)
-{
- static const mode_t permbits[] =
- { 0400, 0200, 0100, 0040, 0020, 0010, 0004, 0002, 0001 };
- char *bp = entry->strmode;
- mode_t mode;
- int i;
-
- /* Fill in a default string, then selectively override. */
- strcpy(bp, "?rwxrwxrwx ");
-
- mode = archive_entry_mode(entry);
- switch (archive_entry_filetype(entry)) {
- case AE_IFREG: bp[0] = '-'; break;
- case AE_IFBLK: bp[0] = 'b'; break;
- case AE_IFCHR: bp[0] = 'c'; break;
- case AE_IFDIR: bp[0] = 'd'; break;
- case AE_IFLNK: bp[0] = 'l'; break;
- case AE_IFSOCK: bp[0] = 's'; break;
- case AE_IFIFO: bp[0] = 'p'; break;
- default:
- if (archive_entry_hardlink(entry) != NULL) {
- bp[0] = 'h';
- break;
- }
- }
-
- for (i = 0; i < 9; i++)
- if (!(mode & permbits[i]))
- bp[i+1] = '-';
-
- if (mode & S_ISUID) {
- if (mode & 0100) bp[3] = 's';
- else bp[3] = 'S';
- }
- if (mode & S_ISGID) {
- if (mode & 0010) bp[6] = 's';
- else bp[6] = 'S';
- }
- if (mode & S_ISVTX) {
- if (mode & 0001) bp[9] = 't';
- else bp[9] = 'T';
- }
- if (archive_entry_acl_types(entry) != 0)
- bp[10] = '+';
-
- return (bp);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_entry_xattr.c b/contrib/libs/libarchive/libarchive/archive_entry_xattr.c
deleted file mode 100644
index e28e515aa8..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_entry_xattr.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_xattr.c 201096 2009-12-28 02:41:27Z kientzle $");
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-#ifdef HAVE_LINUX_FS_H
-#include <linux/fs.h> /* for Linux file flags */
-#endif
-/*
- * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
- * As the include guards don't agree, the order of include is important.
- */
-#ifdef HAVE_LINUX_EXT2_FS_H
-#error #include <linux/ext2_fs.h> /* for Linux file flags */
-#endif
-#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
-#error #include <ext2fs/ext2_fs.h> /* for Linux file flags */
-#endif
-#include <stddef.h>
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_WCHAR_H
-#include <wchar.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_private.h"
-#include "archive_entry_private.h"
-
-/*
- * extended attribute handling
- */
-
-void
-archive_entry_xattr_clear(struct archive_entry *entry)
-{
- struct ae_xattr *xp;
-
- while (entry->xattr_head != NULL) {
- xp = entry->xattr_head->next;
- free(entry->xattr_head->name);
- free(entry->xattr_head->value);
- free(entry->xattr_head);
- entry->xattr_head = xp;
- }
-
- entry->xattr_head = NULL;
-}
-
-void
-archive_entry_xattr_add_entry(struct archive_entry *entry,
- const char *name, const void *value, size_t size)
-{
- struct ae_xattr *xp;
-
- if ((xp = (struct ae_xattr *)malloc(sizeof(struct ae_xattr))) == NULL)
- __archive_errx(1, "Out of memory");
-
- if ((xp->name = strdup(name)) == NULL)
- __archive_errx(1, "Out of memory");
-
- if ((xp->value = malloc(size)) != NULL) {
- memcpy(xp->value, value, size);
- xp->size = size;
- } else
- xp->size = 0;
-
- xp->next = entry->xattr_head;
- entry->xattr_head = xp;
-}
-
-
-/*
- * returns number of the extended attribute entries
- */
-int
-archive_entry_xattr_count(struct archive_entry *entry)
-{
- struct ae_xattr *xp;
- int count = 0;
-
- for (xp = entry->xattr_head; xp != NULL; xp = xp->next)
- count++;
-
- return count;
-}
-
-int
-archive_entry_xattr_reset(struct archive_entry * entry)
-{
- entry->xattr_p = entry->xattr_head;
-
- return archive_entry_xattr_count(entry);
-}
-
-int
-archive_entry_xattr_next(struct archive_entry * entry,
- const char **name, const void **value, size_t *size)
-{
- if (entry->xattr_p) {
- *name = entry->xattr_p->name;
- *value = entry->xattr_p->value;
- *size = entry->xattr_p->size;
-
- entry->xattr_p = entry->xattr_p->next;
-
- return (ARCHIVE_OK);
- } else {
- *name = NULL;
- *value = NULL;
- *size = (size_t)0;
- return (ARCHIVE_WARN);
- }
-}
-
-/*
- * end of xattr handling
- */
diff --git a/contrib/libs/libarchive/libarchive/archive_getdate.c b/contrib/libs/libarchive/libarchive/archive_getdate.c
deleted file mode 100644
index 20ab1b1588..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_getdate.c
+++ /dev/null
@@ -1,1104 +0,0 @@
-/*
- * This code is in the public domain and has no copyright.
- *
- * This is a plain C recursive-descent translation of an old
- * public-domain YACC grammar that has been used for parsing dates in
- * very many open-source projects.
- *
- * Since the original authors were generous enough to donate their
- * work to the public domain, I feel compelled to match their
- * generosity.
- *
- * Tim Kientzle, February 2009.
- */
-
-/*
- * Header comment from original getdate.y:
- */
-
-/*
-** Originally written by Steven M. Bellovin <smb@research.att.com> while
-** at the University of North Carolina at Chapel Hill. Later tweaked by
-** a couple of people on Usenet. Completely overhauled by Rich $alz
-** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
-**
-** This grammar has 10 shift/reduce conflicts.
-**
-** This code is in the public domain and has no copyright.
-*/
-
-#include "archive_platform.h"
-#ifdef __FreeBSD__
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-#endif
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#define __LIBARCHIVE_BUILD 1
-#include "archive_getdate.h"
-
-/* Basic time units. */
-#define EPOCH 1970
-#define MINUTE (60L)
-#define HOUR (60L * MINUTE)
-#define DAY (24L * HOUR)
-
-/* Daylight-savings mode: on, off, or not yet known. */
-enum DSTMODE { DSTon, DSToff, DSTmaybe };
-/* Meridian: am or pm. */
-enum { tAM, tPM };
-/* Token types returned by nexttoken() */
-enum { tAGO = 260, tDAY, tDAYZONE, tAMPM, tMONTH, tMONTH_UNIT, tSEC_UNIT,
- tUNUMBER, tZONE, tDST };
-struct token { int token; time_t value; };
-
-/*
- * Parser state.
- */
-struct gdstate {
- struct token *tokenp; /* Pointer to next token. */
- /* HaveXxxx counts how many of this kind of phrase we've seen;
- * it's a fatal error to have more than one time, zone, day,
- * or date phrase. */
- int HaveYear;
- int HaveMonth;
- int HaveDay;
- int HaveWeekDay; /* Day of week */
- int HaveTime; /* Hour/minute/second */
- int HaveZone; /* timezone and/or DST info */
- int HaveRel; /* time offset; we can have more than one */
- /* Absolute time values. */
- time_t Timezone; /* Seconds offset from GMT */
- time_t Day;
- time_t Hour;
- time_t Minutes;
- time_t Month;
- time_t Seconds;
- time_t Year;
- /* DST selection */
- enum DSTMODE DSTmode;
- /* Day of week accounting, e.g., "3rd Tuesday" */
- time_t DayOrdinal; /* "3" in "3rd Tuesday" */
- time_t DayNumber; /* "Tuesday" in "3rd Tuesday" */
- /* Relative time values: hour/day/week offsets are measured in
- * seconds, month/year are counted in months. */
- time_t RelMonth;
- time_t RelSeconds;
-};
-
-/*
- * A series of functions that recognize certain common time phrases.
- * Each function returns 1 if it managed to make sense of some of the
- * tokens, zero otherwise.
- */
-
-/*
- * hour:minute or hour:minute:second with optional AM, PM, or numeric
- * timezone offset
- */
-static int
-timephrase(struct gdstate *gds)
-{
- if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == ':'
- && gds->tokenp[2].token == tUNUMBER
- && gds->tokenp[3].token == ':'
- && gds->tokenp[4].token == tUNUMBER) {
- /* "12:14:18" or "22:08:07" */
- ++gds->HaveTime;
- gds->Hour = gds->tokenp[0].value;
- gds->Minutes = gds->tokenp[2].value;
- gds->Seconds = gds->tokenp[4].value;
- gds->tokenp += 5;
- }
- else if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == ':'
- && gds->tokenp[2].token == tUNUMBER) {
- /* "12:14" or "22:08" */
- ++gds->HaveTime;
- gds->Hour = gds->tokenp[0].value;
- gds->Minutes = gds->tokenp[2].value;
- gds->Seconds = 0;
- gds->tokenp += 3;
- }
- else if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == tAMPM) {
- /* "7" is a time if it's followed by "am" or "pm" */
- ++gds->HaveTime;
- gds->Hour = gds->tokenp[0].value;
- gds->Minutes = gds->Seconds = 0;
- /* We'll handle the AM/PM below. */
- gds->tokenp += 1;
- } else {
- /* We can't handle this. */
- return 0;
- }
-
- if (gds->tokenp[0].token == tAMPM) {
- /* "7:12pm", "12:20:13am" */
- if (gds->Hour == 12)
- gds->Hour = 0;
- if (gds->tokenp[0].value == tPM)
- gds->Hour += 12;
- gds->tokenp += 1;
- }
- if (gds->tokenp[0].token == '+'
- && gds->tokenp[1].token == tUNUMBER) {
- /* "7:14+0700" */
- gds->HaveZone++;
- gds->DSTmode = DSToff;
- gds->Timezone = - ((gds->tokenp[1].value / 100) * HOUR
- + (gds->tokenp[1].value % 100) * MINUTE);
- gds->tokenp += 2;
- }
- if (gds->tokenp[0].token == '-'
- && gds->tokenp[1].token == tUNUMBER) {
- /* "19:14:12-0530" */
- gds->HaveZone++;
- gds->DSTmode = DSToff;
- gds->Timezone = + ((gds->tokenp[1].value / 100) * HOUR
- + (gds->tokenp[1].value % 100) * MINUTE);
- gds->tokenp += 2;
- }
- return 1;
-}
-
-/*
- * Timezone name, possibly including DST.
- */
-static int
-zonephrase(struct gdstate *gds)
-{
- if (gds->tokenp[0].token == tZONE
- && gds->tokenp[1].token == tDST) {
- gds->HaveZone++;
- gds->Timezone = gds->tokenp[0].value;
- gds->DSTmode = DSTon;
- gds->tokenp += 1;
- return 1;
- }
-
- if (gds->tokenp[0].token == tZONE) {
- gds->HaveZone++;
- gds->Timezone = gds->tokenp[0].value;
- gds->DSTmode = DSToff;
- gds->tokenp += 1;
- return 1;
- }
-
- if (gds->tokenp[0].token == tDAYZONE) {
- gds->HaveZone++;
- gds->Timezone = gds->tokenp[0].value;
- gds->DSTmode = DSTon;
- gds->tokenp += 1;
- return 1;
- }
- return 0;
-}
-
-/*
- * Year/month/day in various combinations.
- */
-static int
-datephrase(struct gdstate *gds)
-{
- if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == '/'
- && gds->tokenp[2].token == tUNUMBER
- && gds->tokenp[3].token == '/'
- && gds->tokenp[4].token == tUNUMBER) {
- gds->HaveYear++;
- gds->HaveMonth++;
- gds->HaveDay++;
- if (gds->tokenp[0].value >= 13) {
- /* First number is big: 2004/01/29, 99/02/17 */
- gds->Year = gds->tokenp[0].value;
- gds->Month = gds->tokenp[2].value;
- gds->Day = gds->tokenp[4].value;
- } else if ((gds->tokenp[4].value >= 13)
- || (gds->tokenp[2].value >= 13)) {
- /* Last number is big: 01/07/98 */
- /* Middle number is big: 01/29/04 */
- gds->Month = gds->tokenp[0].value;
- gds->Day = gds->tokenp[2].value;
- gds->Year = gds->tokenp[4].value;
- } else {
- /* No significant clues: 02/03/04 */
- gds->Month = gds->tokenp[0].value;
- gds->Day = gds->tokenp[2].value;
- gds->Year = gds->tokenp[4].value;
- }
- gds->tokenp += 5;
- return 1;
- }
-
- if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == '/'
- && gds->tokenp[2].token == tUNUMBER) {
- /* "1/15" */
- gds->HaveMonth++;
- gds->HaveDay++;
- gds->Month = gds->tokenp[0].value;
- gds->Day = gds->tokenp[2].value;
- gds->tokenp += 3;
- return 1;
- }
-
- if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == '-'
- && gds->tokenp[2].token == tUNUMBER
- && gds->tokenp[3].token == '-'
- && gds->tokenp[4].token == tUNUMBER) {
- /* ISO 8601 format. yyyy-mm-dd. */
- gds->HaveYear++;
- gds->HaveMonth++;
- gds->HaveDay++;
- gds->Year = gds->tokenp[0].value;
- gds->Month = gds->tokenp[2].value;
- gds->Day = gds->tokenp[4].value;
- gds->tokenp += 5;
- return 1;
- }
-
- if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == '-'
- && gds->tokenp[2].token == tMONTH
- && gds->tokenp[3].token == '-'
- && gds->tokenp[4].token == tUNUMBER) {
- gds->HaveYear++;
- gds->HaveMonth++;
- gds->HaveDay++;
- if (gds->tokenp[0].value > 31) {
- /* e.g. 1992-Jun-17 */
- gds->Year = gds->tokenp[0].value;
- gds->Month = gds->tokenp[2].value;
- gds->Day = gds->tokenp[4].value;
- } else {
- /* e.g. 17-JUN-1992. */
- gds->Day = gds->tokenp[0].value;
- gds->Month = gds->tokenp[2].value;
- gds->Year = gds->tokenp[4].value;
- }
- gds->tokenp += 5;
- return 1;
- }
-
- if (gds->tokenp[0].token == tMONTH
- && gds->tokenp[1].token == tUNUMBER
- && gds->tokenp[2].token == ','
- && gds->tokenp[3].token == tUNUMBER) {
- /* "June 17, 2001" */
- gds->HaveYear++;
- gds->HaveMonth++;
- gds->HaveDay++;
- gds->Month = gds->tokenp[0].value;
- gds->Day = gds->tokenp[1].value;
- gds->Year = gds->tokenp[3].value;
- gds->tokenp += 4;
- return 1;
- }
-
- if (gds->tokenp[0].token == tMONTH
- && gds->tokenp[1].token == tUNUMBER) {
- /* "May 3" */
- gds->HaveMonth++;
- gds->HaveDay++;
- gds->Month = gds->tokenp[0].value;
- gds->Day = gds->tokenp[1].value;
- gds->tokenp += 2;
- return 1;
- }
-
- if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == tMONTH
- && gds->tokenp[2].token == tUNUMBER) {
- /* "12 Sept 1997" */
- gds->HaveYear++;
- gds->HaveMonth++;
- gds->HaveDay++;
- gds->Day = gds->tokenp[0].value;
- gds->Month = gds->tokenp[1].value;
- gds->Year = gds->tokenp[2].value;
- gds->tokenp += 3;
- return 1;
- }
-
- if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == tMONTH) {
- /* "12 Sept" */
- gds->HaveMonth++;
- gds->HaveDay++;
- gds->Day = gds->tokenp[0].value;
- gds->Month = gds->tokenp[1].value;
- gds->tokenp += 2;
- return 1;
- }
-
- return 0;
-}
-
-/*
- * Relative time phrase: "tomorrow", "yesterday", "+1 hour", etc.
- */
-static int
-relunitphrase(struct gdstate *gds)
-{
- if (gds->tokenp[0].token == '-'
- && gds->tokenp[1].token == tUNUMBER
- && gds->tokenp[2].token == tSEC_UNIT) {
- /* "-3 hours" */
- gds->HaveRel++;
- gds->RelSeconds -= gds->tokenp[1].value * gds->tokenp[2].value;
- gds->tokenp += 3;
- return 1;
- }
- if (gds->tokenp[0].token == '+'
- && gds->tokenp[1].token == tUNUMBER
- && gds->tokenp[2].token == tSEC_UNIT) {
- /* "+1 minute" */
- gds->HaveRel++;
- gds->RelSeconds += gds->tokenp[1].value * gds->tokenp[2].value;
- gds->tokenp += 3;
- return 1;
- }
- if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == tSEC_UNIT) {
- /* "1 day" */
- gds->HaveRel++;
- gds->RelSeconds += gds->tokenp[0].value * gds->tokenp[1].value;
- gds->tokenp += 2;
- return 1;
- }
- if (gds->tokenp[0].token == '-'
- && gds->tokenp[1].token == tUNUMBER
- && gds->tokenp[2].token == tMONTH_UNIT) {
- /* "-3 months" */
- gds->HaveRel++;
- gds->RelMonth -= gds->tokenp[1].value * gds->tokenp[2].value;
- gds->tokenp += 3;
- return 1;
- }
- if (gds->tokenp[0].token == '+'
- && gds->tokenp[1].token == tUNUMBER
- && gds->tokenp[2].token == tMONTH_UNIT) {
- /* "+5 years" */
- gds->HaveRel++;
- gds->RelMonth += gds->tokenp[1].value * gds->tokenp[2].value;
- gds->tokenp += 3;
- return 1;
- }
- if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == tMONTH_UNIT) {
- /* "2 years" */
- gds->HaveRel++;
- gds->RelMonth += gds->tokenp[0].value * gds->tokenp[1].value;
- gds->tokenp += 2;
- return 1;
- }
- if (gds->tokenp[0].token == tSEC_UNIT) {
- /* "now", "tomorrow" */
- gds->HaveRel++;
- gds->RelSeconds += gds->tokenp[0].value;
- gds->tokenp += 1;
- return 1;
- }
- if (gds->tokenp[0].token == tMONTH_UNIT) {
- /* "month" */
- gds->HaveRel++;
- gds->RelMonth += gds->tokenp[0].value;
- gds->tokenp += 1;
- return 1;
- }
- return 0;
-}
-
-/*
- * Day of the week specification.
- */
-static int
-dayphrase(struct gdstate *gds)
-{
- if (gds->tokenp[0].token == tDAY) {
- /* "tues", "wednesday," */
- gds->HaveWeekDay++;
- gds->DayOrdinal = 1;
- gds->DayNumber = gds->tokenp[0].value;
- gds->tokenp += 1;
- if (gds->tokenp[0].token == ',')
- gds->tokenp += 1;
- return 1;
- }
- if (gds->tokenp[0].token == tUNUMBER
- && gds->tokenp[1].token == tDAY) {
- /* "second tues" "3 wed" */
- gds->HaveWeekDay++;
- gds->DayOrdinal = gds->tokenp[0].value;
- gds->DayNumber = gds->tokenp[1].value;
- gds->tokenp += 2;
- return 1;
- }
- return 0;
-}
-
-/*
- * Try to match a phrase using one of the above functions.
- * This layer also deals with a couple of generic issues.
- */
-static int
-phrase(struct gdstate *gds)
-{
- if (timephrase(gds))
- return 1;
- if (zonephrase(gds))
- return 1;
- if (datephrase(gds))
- return 1;
- if (dayphrase(gds))
- return 1;
- if (relunitphrase(gds)) {
- if (gds->tokenp[0].token == tAGO) {
- gds->RelSeconds = -gds->RelSeconds;
- gds->RelMonth = -gds->RelMonth;
- gds->tokenp += 1;
- }
- return 1;
- }
-
- /* Bare numbers sometimes have meaning. */
- if (gds->tokenp[0].token == tUNUMBER) {
- if (gds->HaveTime && !gds->HaveYear && !gds->HaveRel) {
- gds->HaveYear++;
- gds->Year = gds->tokenp[0].value;
- gds->tokenp += 1;
- return 1;
- }
-
- if(gds->tokenp[0].value > 10000) {
- /* "20040301" */
- gds->HaveYear++;
- gds->HaveMonth++;
- gds->HaveDay++;
- gds->Day= (gds->tokenp[0].value)%100;
- gds->Month= (gds->tokenp[0].value/100)%100;
- gds->Year = gds->tokenp[0].value/10000;
- gds->tokenp += 1;
- return 1;
- }
-
- if (gds->tokenp[0].value < 24) {
- gds->HaveTime++;
- gds->Hour = gds->tokenp[0].value;
- gds->Minutes = 0;
- gds->Seconds = 0;
- gds->tokenp += 1;
- return 1;
- }
-
- if ((gds->tokenp[0].value / 100 < 24)
- && (gds->tokenp[0].value % 100 < 60)) {
- /* "513" is same as "5:13" */
- gds->Hour = gds->tokenp[0].value / 100;
- gds->Minutes = gds->tokenp[0].value % 100;
- gds->Seconds = 0;
- gds->tokenp += 1;
- return 1;
- }
- }
-
- return 0;
-}
-
-/*
- * A dictionary of time words.
- */
-static struct LEXICON {
- size_t abbrev;
- const char *name;
- int type;
- time_t value;
-} const TimeWords[] = {
- /* am/pm */
- { 0, "am", tAMPM, tAM },
- { 0, "pm", tAMPM, tPM },
-
- /* Month names. */
- { 3, "january", tMONTH, 1 },
- { 3, "february", tMONTH, 2 },
- { 3, "march", tMONTH, 3 },
- { 3, "april", tMONTH, 4 },
- { 3, "may", tMONTH, 5 },
- { 3, "june", tMONTH, 6 },
- { 3, "july", tMONTH, 7 },
- { 3, "august", tMONTH, 8 },
- { 3, "september", tMONTH, 9 },
- { 3, "october", tMONTH, 10 },
- { 3, "november", tMONTH, 11 },
- { 3, "december", tMONTH, 12 },
-
- /* Days of the week. */
- { 2, "sunday", tDAY, 0 },
- { 3, "monday", tDAY, 1 },
- { 2, "tuesday", tDAY, 2 },
- { 3, "wednesday", tDAY, 3 },
- { 2, "thursday", tDAY, 4 },
- { 2, "friday", tDAY, 5 },
- { 2, "saturday", tDAY, 6 },
-
- /* Timezones: Offsets are in seconds. */
- { 0, "gmt", tZONE, 0*HOUR }, /* Greenwich Mean */
- { 0, "ut", tZONE, 0*HOUR }, /* Universal (Coordinated) */
- { 0, "utc", tZONE, 0*HOUR },
- { 0, "wet", tZONE, 0*HOUR }, /* Western European */
- { 0, "bst", tDAYZONE, 0*HOUR }, /* British Summer */
- { 0, "wat", tZONE, 1*HOUR }, /* West Africa */
- { 0, "at", tZONE, 2*HOUR }, /* Azores */
- /* { 0, "bst", tZONE, 3*HOUR }, */ /* Brazil Standard: Conflict */
- /* { 0, "gst", tZONE, 3*HOUR }, */ /* Greenland Standard: Conflict*/
- { 0, "nft", tZONE, 3*HOUR+30*MINUTE }, /* Newfoundland */
- { 0, "nst", tZONE, 3*HOUR+30*MINUTE }, /* Newfoundland Standard */
- { 0, "ndt", tDAYZONE, 3*HOUR+30*MINUTE }, /* Newfoundland Daylight */
- { 0, "ast", tZONE, 4*HOUR }, /* Atlantic Standard */
- { 0, "adt", tDAYZONE, 4*HOUR }, /* Atlantic Daylight */
- { 0, "est", tZONE, 5*HOUR }, /* Eastern Standard */
- { 0, "edt", tDAYZONE, 5*HOUR }, /* Eastern Daylight */
- { 0, "cst", tZONE, 6*HOUR }, /* Central Standard */
- { 0, "cdt", tDAYZONE, 6*HOUR }, /* Central Daylight */
- { 0, "mst", tZONE, 7*HOUR }, /* Mountain Standard */
- { 0, "mdt", tDAYZONE, 7*HOUR }, /* Mountain Daylight */
- { 0, "pst", tZONE, 8*HOUR }, /* Pacific Standard */
- { 0, "pdt", tDAYZONE, 8*HOUR }, /* Pacific Daylight */
- { 0, "yst", tZONE, 9*HOUR }, /* Yukon Standard */
- { 0, "ydt", tDAYZONE, 9*HOUR }, /* Yukon Daylight */
- { 0, "hst", tZONE, 10*HOUR }, /* Hawaii Standard */
- { 0, "hdt", tDAYZONE, 10*HOUR }, /* Hawaii Daylight */
- { 0, "cat", tZONE, 10*HOUR }, /* Central Alaska */
- { 0, "ahst", tZONE, 10*HOUR }, /* Alaska-Hawaii Standard */
- { 0, "nt", tZONE, 11*HOUR }, /* Nome */
- { 0, "idlw", tZONE, 12*HOUR }, /* Intl Date Line West */
- { 0, "cet", tZONE, -1*HOUR }, /* Central European */
- { 0, "met", tZONE, -1*HOUR }, /* Middle European */
- { 0, "mewt", tZONE, -1*HOUR }, /* Middle European Winter */
- { 0, "mest", tDAYZONE, -1*HOUR }, /* Middle European Summer */
- { 0, "swt", tZONE, -1*HOUR }, /* Swedish Winter */
- { 0, "sst", tDAYZONE, -1*HOUR }, /* Swedish Summer */
- { 0, "fwt", tZONE, -1*HOUR }, /* French Winter */
- { 0, "fst", tDAYZONE, -1*HOUR }, /* French Summer */
- { 0, "eet", tZONE, -2*HOUR }, /* Eastern Eur, USSR Zone 1 */
- { 0, "bt", tZONE, -3*HOUR }, /* Baghdad, USSR Zone 2 */
- { 0, "it", tZONE, -3*HOUR-30*MINUTE },/* Iran */
- { 0, "zp4", tZONE, -4*HOUR }, /* USSR Zone 3 */
- { 0, "zp5", tZONE, -5*HOUR }, /* USSR Zone 4 */
- { 0, "ist", tZONE, -5*HOUR-30*MINUTE },/* Indian Standard */
- { 0, "zp6", tZONE, -6*HOUR }, /* USSR Zone 5 */
- /* { 0, "nst", tZONE, -6.5*HOUR }, */ /* North Sumatra: Conflict */
- /* { 0, "sst", tZONE, -7*HOUR }, */ /* So Sumatra, USSR 6: Conflict */
- { 0, "wast", tZONE, -7*HOUR }, /* West Australian Standard */
- { 0, "wadt", tDAYZONE, -7*HOUR }, /* West Australian Daylight */
- { 0, "jt", tZONE, -7*HOUR-30*MINUTE },/* Java (3pm in Cronusland!)*/
- { 0, "cct", tZONE, -8*HOUR }, /* China Coast, USSR Zone 7 */
- { 0, "jst", tZONE, -9*HOUR }, /* Japan Std, USSR Zone 8 */
- { 0, "cast", tZONE, -9*HOUR-30*MINUTE },/* Ctrl Australian Std */
- { 0, "cadt", tDAYZONE, -9*HOUR-30*MINUTE },/* Ctrl Australian Daylt */
- { 0, "east", tZONE, -10*HOUR }, /* Eastern Australian Std */
- { 0, "eadt", tDAYZONE, -10*HOUR }, /* Eastern Australian Daylt */
- { 0, "gst", tZONE, -10*HOUR }, /* Guam Std, USSR Zone 9 */
- { 0, "nzt", tZONE, -12*HOUR }, /* New Zealand */
- { 0, "nzst", tZONE, -12*HOUR }, /* New Zealand Standard */
- { 0, "nzdt", tDAYZONE, -12*HOUR }, /* New Zealand Daylight */
- { 0, "idle", tZONE, -12*HOUR }, /* Intl Date Line East */
-
- { 0, "dst", tDST, 0 },
-
- /* Time units. */
- { 4, "years", tMONTH_UNIT, 12 },
- { 5, "months", tMONTH_UNIT, 1 },
- { 9, "fortnights", tSEC_UNIT, 14 * DAY },
- { 4, "weeks", tSEC_UNIT, 7 * DAY },
- { 3, "days", tSEC_UNIT, DAY },
- { 4, "hours", tSEC_UNIT, HOUR },
- { 3, "minutes", tSEC_UNIT, MINUTE },
- { 3, "seconds", tSEC_UNIT, 1 },
-
- /* Relative-time words. */
- { 0, "tomorrow", tSEC_UNIT, DAY },
- { 0, "yesterday", tSEC_UNIT, -DAY },
- { 0, "today", tSEC_UNIT, 0 },
- { 0, "now", tSEC_UNIT, 0 },
- { 0, "last", tUNUMBER, -1 },
- { 0, "this", tSEC_UNIT, 0 },
- { 0, "next", tUNUMBER, 2 },
- { 0, "first", tUNUMBER, 1 },
- { 0, "1st", tUNUMBER, 1 },
-/* { 0, "second", tUNUMBER, 2 }, */
- { 0, "2nd", tUNUMBER, 2 },
- { 0, "third", tUNUMBER, 3 },
- { 0, "3rd", tUNUMBER, 3 },
- { 0, "fourth", tUNUMBER, 4 },
- { 0, "4th", tUNUMBER, 4 },
- { 0, "fifth", tUNUMBER, 5 },
- { 0, "5th", tUNUMBER, 5 },
- { 0, "sixth", tUNUMBER, 6 },
- { 0, "seventh", tUNUMBER, 7 },
- { 0, "eighth", tUNUMBER, 8 },
- { 0, "ninth", tUNUMBER, 9 },
- { 0, "tenth", tUNUMBER, 10 },
- { 0, "eleventh", tUNUMBER, 11 },
- { 0, "twelfth", tUNUMBER, 12 },
- { 0, "ago", tAGO, 1 },
-
- /* Military timezones. */
- { 0, "a", tZONE, 1*HOUR },
- { 0, "b", tZONE, 2*HOUR },
- { 0, "c", tZONE, 3*HOUR },
- { 0, "d", tZONE, 4*HOUR },
- { 0, "e", tZONE, 5*HOUR },
- { 0, "f", tZONE, 6*HOUR },
- { 0, "g", tZONE, 7*HOUR },
- { 0, "h", tZONE, 8*HOUR },
- { 0, "i", tZONE, 9*HOUR },
- { 0, "k", tZONE, 10*HOUR },
- { 0, "l", tZONE, 11*HOUR },
- { 0, "m", tZONE, 12*HOUR },
- { 0, "n", tZONE, -1*HOUR },
- { 0, "o", tZONE, -2*HOUR },
- { 0, "p", tZONE, -3*HOUR },
- { 0, "q", tZONE, -4*HOUR },
- { 0, "r", tZONE, -5*HOUR },
- { 0, "s", tZONE, -6*HOUR },
- { 0, "t", tZONE, -7*HOUR },
- { 0, "u", tZONE, -8*HOUR },
- { 0, "v", tZONE, -9*HOUR },
- { 0, "w", tZONE, -10*HOUR },
- { 0, "x", tZONE, -11*HOUR },
- { 0, "y", tZONE, -12*HOUR },
- { 0, "z", tZONE, 0*HOUR },
-
- /* End of table. */
- { 0, NULL, 0, 0 }
-};
-
-/*
- * Year is either:
- * = A number from 0 to 99, which means a year from 1970 to 2069, or
- * = The actual year (>=100).
- */
-static time_t
-Convert(time_t Month, time_t Day, time_t Year,
- time_t Hours, time_t Minutes, time_t Seconds,
- time_t Timezone, enum DSTMODE DSTmode)
-{
- signed char DaysInMonth[12] = {
- 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
- };
- time_t Julian;
- int i;
- struct tm *ltime;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
- struct tm tmbuf;
-#endif
-
- if (Year < 69)
- Year += 2000;
- else if (Year < 100)
- Year += 1900;
- DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
- ? 29 : 28;
- /* Checking for 2038 bogusly assumes that time_t is 32 bits. But
- I'm too lazy to try to check for time_t overflow in another way. */
- if (Year < EPOCH || Year >= 2038
- || Month < 1 || Month > 12
- /* Lint fluff: "conversion from long may lose accuracy" */
- || Day < 1 || Day > DaysInMonth[(int)--Month]
- || Hours < 0 || Hours > 23
- || Minutes < 0 || Minutes > 59
- || Seconds < 0 || Seconds > 59)
- return -1;
-
- Julian = Day - 1;
- for (i = 0; i < Month; i++)
- Julian += DaysInMonth[i];
- for (i = EPOCH; i < Year; i++)
- Julian += 365 + (i % 4 == 0);
- Julian *= DAY;
- Julian += Timezone;
- Julian += Hours * HOUR + Minutes * MINUTE + Seconds;
-#if defined(HAVE_LOCALTIME_S)
- ltime = localtime_s(&tmbuf, &Julian) ? NULL : &tmbuf;
-#elif defined(HAVE_LOCALTIME_R)
- ltime = localtime_r(&Julian, &tmbuf);
-#else
- ltime = localtime(&Julian);
-#endif
- if (DSTmode == DSTon
- || (DSTmode == DSTmaybe && ltime->tm_isdst))
- Julian -= HOUR;
- return Julian;
-}
-
-static time_t
-DSTcorrect(time_t Start, time_t Future)
-{
- time_t StartDay;
- time_t FutureDay;
- struct tm *ltime;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
- struct tm tmbuf;
-#endif
-#if defined(HAVE_LOCALTIME_S)
- ltime = localtime_s(&tmbuf, &Start) ? NULL : &tmbuf;
-#elif defined(HAVE_LOCALTIME_R)
- ltime = localtime_r(&Start, &tmbuf);
-#else
- ltime = localtime(&Start);
-#endif
- StartDay = (ltime->tm_hour + 1) % 24;
-#if defined(HAVE_LOCALTIME_S)
- ltime = localtime_s(&tmbuf, &Future) ? NULL : &tmbuf;
-#elif defined(HAVE_LOCALTIME_R)
- ltime = localtime_r(&Future, &tmbuf);
-#else
- ltime = localtime(&Future);
-#endif
- FutureDay = (ltime->tm_hour + 1) % 24;
- return (Future - Start) + (StartDay - FutureDay) * HOUR;
-}
-
-
-static time_t
-RelativeDate(time_t Start, time_t zone, int dstmode,
- time_t DayOrdinal, time_t DayNumber)
-{
- struct tm *tm;
- time_t t, now;
-#if defined(HAVE_GMTIME_R) || defined(HAVE_GMTIME_S)
- struct tm tmbuf;
-#endif
-
- t = Start - zone;
-#if defined(HAVE_GMTIME_S)
- tm = gmtime_s(&tmbuf, &t) ? NULL : &tmbuf;
-#elif defined(HAVE_GMTIME_R)
- tm = gmtime_r(&t, &tmbuf);
-#else
- tm = gmtime(&t);
-#endif
- now = Start;
- now += DAY * ((DayNumber - tm->tm_wday + 7) % 7);
- now += 7 * DAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
- if (dstmode == DSTmaybe)
- return DSTcorrect(Start, now);
- return now - Start;
-}
-
-
-static time_t
-RelativeMonth(time_t Start, time_t Timezone, time_t RelMonth)
-{
- struct tm *tm;
- time_t Month;
- time_t Year;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
- struct tm tmbuf;
-#endif
-
- if (RelMonth == 0)
- return 0;
-#if defined(HAVE_LOCALTIME_S)
- tm = localtime_s(&tmbuf, &Start) ? NULL : &tmbuf;
-#elif defined(HAVE_LOCALTIME_R)
- tm = localtime_r(&Start, &tmbuf);
-#else
- tm = localtime(&Start);
-#endif
- Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth;
- Year = Month / 12;
- Month = Month % 12 + 1;
- return DSTcorrect(Start,
- Convert(Month, (time_t)tm->tm_mday, Year,
- (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
- Timezone, DSTmaybe));
-}
-
-/*
- * Tokenizer.
- */
-static int
-nexttoken(const char **in, time_t *value)
-{
- char c;
- char buff[64];
-
- for ( ; ; ) {
- while (isspace((unsigned char)**in))
- ++*in;
-
- /* Skip parenthesized comments. */
- if (**in == '(') {
- int Count = 0;
- do {
- c = *(*in)++;
- if (c == '\0')
- return c;
- if (c == '(')
- Count++;
- else if (c == ')')
- Count--;
- } while (Count > 0);
- continue;
- }
-
- /* Try the next token in the word table first. */
- /* This allows us to match "2nd", for example. */
- {
- const char *src = *in;
- const struct LEXICON *tp;
- unsigned i = 0;
-
- /* Force to lowercase and strip '.' characters. */
- while (*src != '\0'
- && (isalnum((unsigned char)*src) || *src == '.')
- && i < sizeof(buff)-1) {
- if (*src != '.') {
- if (isupper((unsigned char)*src))
- buff[i++] = tolower((unsigned char)*src);
- else
- buff[i++] = *src;
- }
- src++;
- }
- buff[i] = '\0';
-
- /*
- * Find the first match. If the word can be
- * abbreviated, make sure we match at least
- * the minimum abbreviation.
- */
- for (tp = TimeWords; tp->name; tp++) {
- size_t abbrev = tp->abbrev;
- if (abbrev == 0)
- abbrev = strlen(tp->name);
- if (strlen(buff) >= abbrev
- && strncmp(tp->name, buff, strlen(buff))
- == 0) {
- /* Skip over token. */
- *in = src;
- /* Return the match. */
- *value = tp->value;
- return tp->type;
- }
- }
- }
-
- /*
- * Not in the word table, maybe it's a number. Note:
- * Because '-' and '+' have other special meanings, I
- * don't deal with signed numbers here.
- */
- if (isdigit((unsigned char)(c = **in))) {
- for (*value = 0; isdigit((unsigned char)(c = *(*in)++)); )
- *value = 10 * *value + c - '0';
- (*in)--;
- return (tUNUMBER);
- }
-
- return *(*in)++;
- }
-}
-
-#define TM_YEAR_ORIGIN 1900
-
-/* Yield A - B, measured in seconds. */
-static long
-difftm (struct tm *a, struct tm *b)
-{
- int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
- int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
- int days = (
- /* difference in day of year */
- a->tm_yday - b->tm_yday
- /* + intervening leap days */
- + ((ay >> 2) - (by >> 2))
- - (ay/100 - by/100)
- + ((ay/100 >> 2) - (by/100 >> 2))
- /* + difference in years * 365 */
- + (long)(ay-by) * 365
- );
- return (days * DAY + (a->tm_hour - b->tm_hour) * HOUR
- + (a->tm_min - b->tm_min) * MINUTE
- + (a->tm_sec - b->tm_sec));
-}
-
-/*
- *
- * The public function.
- *
- * TODO: tokens[] array should be dynamically sized.
- */
-time_t
-__archive_get_date(time_t now, const char *p)
-{
- struct token tokens[256];
- struct gdstate _gds;
- struct token *lasttoken;
- struct gdstate *gds;
- struct tm local, *tm;
- struct tm gmt, *gmt_ptr;
- time_t Start;
- time_t tod;
- long tzone;
-
- /* Clear out the parsed token array. */
- memset(tokens, 0, sizeof(tokens));
- /* Initialize the parser state. */
- memset(&_gds, 0, sizeof(_gds));
- gds = &_gds;
-
- /* Look up the current time. */
-#if defined(HAVE_LOCALTIME_S)
- tm = localtime_s(&local, &now) ? NULL : &local;
-#elif defined(HAVE_LOCALTIME_R)
- tm = localtime_r(&now, &local);
-#else
- memset(&local, 0, sizeof(local));
- tm = localtime(&now);
-#endif
- if (tm == NULL)
- return -1;
-#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S)
- local = *tm;
-#endif
-
- /* Look up UTC if we can and use that to determine the current
- * timezone offset. */
-#if defined(HAVE_GMTIME_S)
- gmt_ptr = gmtime_s(&gmt, &now) ? NULL : &gmt;
-#elif defined(HAVE_GMTIME_R)
- gmt_ptr = gmtime_r(&now, &gmt);
-#else
- memset(&gmt, 0, sizeof(gmt));
- gmt_ptr = gmtime(&now);
- if (gmt_ptr != NULL) {
- /* Copy, in case localtime and gmtime use the same buffer. */
- gmt = *gmt_ptr;
- }
-#endif
- if (gmt_ptr != NULL)
- tzone = difftm (&gmt, &local);
- else
- /* This system doesn't understand timezones; fake it. */
- tzone = 0;
- if(local.tm_isdst)
- tzone += HOUR;
-
- /* Tokenize the input string. */
- lasttoken = tokens;
- while ((lasttoken->token = nexttoken(&p, &lasttoken->value)) != 0) {
- ++lasttoken;
- if (lasttoken > tokens + 255)
- return -1;
- }
- gds->tokenp = tokens;
-
- /* Match phrases until we run out of input tokens. */
- while (gds->tokenp < lasttoken) {
- if (!phrase(gds))
- return -1;
- }
-
- /* Use current local timezone if none was specified. */
- if (!gds->HaveZone) {
- gds->Timezone = tzone;
- gds->DSTmode = DSTmaybe;
- }
-
- /* If a timezone was specified, use that for generating the default
- * time components instead of the local timezone. */
- if (gds->HaveZone && gmt_ptr != NULL) {
- now -= gds->Timezone;
-#if defined(HAVE_GMTIME_S)
- gmt_ptr = gmtime_s(&gmt, &now) ? NULL : &gmt;
-#elif defined(HAVE_GMTIME_R)
- gmt_ptr = gmtime_r(&now, &gmt);
-#else
- gmt_ptr = gmtime(&now);
-#endif
- if (gmt_ptr != NULL)
- local = *gmt_ptr;
- now += gds->Timezone;
- }
-
- if (!gds->HaveYear)
- gds->Year = local.tm_year + 1900;
- if (!gds->HaveMonth)
- gds->Month = local.tm_mon + 1;
- if (!gds->HaveDay)
- gds->Day = local.tm_mday;
- /* Note: No default for hour/min/sec; a specifier that just
- * gives date always refers to 00:00 on that date. */
-
- /* If we saw more than one time, timezone, weekday, year, month,
- * or day, then give up. */
- if (gds->HaveTime > 1 || gds->HaveZone > 1 || gds->HaveWeekDay > 1
- || gds->HaveYear > 1 || gds->HaveMonth > 1 || gds->HaveDay > 1)
- return -1;
-
- /* Compute an absolute time based on whatever absolute information
- * we collected. */
- if (gds->HaveYear || gds->HaveMonth || gds->HaveDay
- || gds->HaveTime || gds->HaveWeekDay) {
- Start = Convert(gds->Month, gds->Day, gds->Year,
- gds->Hour, gds->Minutes, gds->Seconds,
- gds->Timezone, gds->DSTmode);
- if (Start < 0)
- return -1;
- } else {
- Start = now;
- if (!gds->HaveRel)
- Start -= local.tm_hour * HOUR + local.tm_min * MINUTE
- + local.tm_sec;
- }
-
- /* Add the relative offset. */
- Start += gds->RelSeconds;
- Start += RelativeMonth(Start, gds->Timezone, gds->RelMonth);
-
- /* Adjust for day-of-week offsets. */
- if (gds->HaveWeekDay
- && !(gds->HaveYear || gds->HaveMonth || gds->HaveDay)) {
- tod = RelativeDate(Start, gds->Timezone,
- gds->DSTmode, gds->DayOrdinal, gds->DayNumber);
- Start += tod;
- }
-
- /* -1 is an error indicator, so return 0 instead of -1 if
- * that's the actual time. */
- return Start == -1 ? 0 : Start;
-}
-
-
-#if defined(TEST)
-
-/* ARGSUSED */
-int
-main(int argc, char **argv)
-{
- time_t d;
- time_t now = time(NULL);
-
- while (*++argv != NULL) {
- (void)printf("Input: %s\n", *argv);
- d = get_date(now, *argv);
- if (d == -1)
- (void)printf("Bad format - couldn't convert.\n");
- else
- (void)printf("Output: %s\n", ctime(&d));
- }
- exit(0);
- /* NOTREACHED */
-}
-#endif /* defined(TEST) */
diff --git a/contrib/libs/libarchive/libarchive/archive_getdate.h b/contrib/libs/libarchive/libarchive/archive_getdate.h
deleted file mode 100644
index 900a8f692e..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_getdate.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*-
- * Copyright (c) 2003-2015 Tim Kientzle
- * 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(S) ``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(S) 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.
- *
- * $FreeBSD$
- */
-
-#ifndef ARCHIVE_GETDATE_H_INCLUDED
-#define ARCHIVE_GETDATE_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
-#include <time.h>
-
-time_t __archive_get_date(time_t now, const char *);
-
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_hmac.c b/contrib/libs/libarchive/libarchive/archive_hmac.c
deleted file mode 100644
index edb3bf5abd..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_hmac.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/*-
-* Copyright (c) 2014 Michihiro NAKAJIMA
-* 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(S) ``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(S) 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 "archive_platform.h"
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#include "archive.h"
-#include "archive_hmac_private.h"
-
-/*
- * On systems that do not support any recognized crypto libraries,
- * the archive_hmac.c file is expected to define no usable symbols.
- *
- * But some compilers and linkers choke on empty object files, so
- * define a public symbol that will always exist. This could
- * be removed someday if this file gains another always-present
- * symbol definition.
- */
-int __libarchive_hmac_build_hack(void) {
- return 0;
-}
-
-
-#ifdef ARCHIVE_HMAC_USE_Apple_CommonCrypto
-
-static int
-__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
-{
- CCHmacInit(ctx, kCCHmacAlgSHA1, key, key_len);
- return 0;
-}
-
-static void
-__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
- size_t data_len)
-{
- CCHmacUpdate(ctx, data, data_len);
-}
-
-static void
-__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
-{
- CCHmacFinal(ctx, out);
- *out_len = 20;
-}
-
-static void
-__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
-{
- memset(ctx, 0, sizeof(*ctx));
-}
-
-#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
-
-#ifndef BCRYPT_HASH_REUSABLE_FLAG
-# define BCRYPT_HASH_REUSABLE_FLAG 0x00000020
-#endif
-
-static int
-__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
-{
-#ifdef __GNUC__
-#pragma GCC diagnostic ignored "-Wcast-qual"
-#endif
- BCRYPT_ALG_HANDLE hAlg;
- BCRYPT_HASH_HANDLE hHash;
- DWORD hash_len;
- PBYTE hash;
- ULONG result;
- NTSTATUS status;
-
- ctx->hAlg = NULL;
- status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA1_ALGORITHM,
- MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
- if (!BCRYPT_SUCCESS(status))
- return -1;
- status = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, (PUCHAR)&hash_len,
- sizeof(hash_len), &result, 0);
- if (!BCRYPT_SUCCESS(status)) {
- BCryptCloseAlgorithmProvider(hAlg, 0);
- return -1;
- }
- hash = (PBYTE)HeapAlloc(GetProcessHeap(), 0, hash_len);
- if (hash == NULL) {
- BCryptCloseAlgorithmProvider(hAlg, 0);
- return -1;
- }
- status = BCryptCreateHash(hAlg, &hHash, NULL, 0,
- (PUCHAR)key, (ULONG)key_len, BCRYPT_HASH_REUSABLE_FLAG);
- if (!BCRYPT_SUCCESS(status)) {
- BCryptCloseAlgorithmProvider(hAlg, 0);
- HeapFree(GetProcessHeap(), 0, hash);
- return -1;
- }
-
- ctx->hAlg = hAlg;
- ctx->hHash = hHash;
- ctx->hash_len = hash_len;
- ctx->hash = hash;
-
- return 0;
-}
-
-static void
-__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
- size_t data_len)
-{
- BCryptHashData(ctx->hHash, (PUCHAR)(uintptr_t)data, (ULONG)data_len, 0);
-}
-
-static void
-__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
-{
- BCryptFinishHash(ctx->hHash, ctx->hash, ctx->hash_len, 0);
- if (ctx->hash_len == *out_len)
- memcpy(out, ctx->hash, *out_len);
-}
-
-static void
-__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
-{
- if (ctx->hAlg != NULL) {
- BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
- HeapFree(GetProcessHeap(), 0, ctx->hash);
- ctx->hAlg = NULL;
- }
-}
-
-#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_MD_H)
-
-static int
-__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
-{
- const mbedtls_md_info_t *info;
- int ret;
-
- mbedtls_md_init(ctx);
- info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
- if (info == NULL) {
- mbedtls_md_free(ctx);
- return (-1);
- }
- ret = mbedtls_md_setup(ctx, info, 1);
- if (ret != 0) {
- mbedtls_md_free(ctx);
- return (-1);
- }
- ret = mbedtls_md_hmac_starts(ctx, key, key_len);
- if (ret != 0) {
- mbedtls_md_free(ctx);
- return (-1);
- }
- return 0;
-}
-
-static void
-__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
- size_t data_len)
-{
- mbedtls_md_hmac_update(ctx, data, data_len);
-}
-
-static void __hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
-{
- (void)out_len; /* UNUSED */
-
- mbedtls_md_hmac_finish(ctx, out);
-}
-
-static void __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
-{
- mbedtls_md_free(ctx);
- memset(ctx, 0, sizeof(*ctx));
-}
-
-#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H)
-
-static int
-__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
-{
- hmac_sha1_set_key(ctx, key_len, key);
- return 0;
-}
-
-static void
-__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
- size_t data_len)
-{
- hmac_sha1_update(ctx, data_len, data);
-}
-
-static void
-__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
-{
- hmac_sha1_digest(ctx, (unsigned)*out_len, out);
-}
-
-static void
-__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
-{
- memset(ctx, 0, sizeof(*ctx));
-}
-
-#elif defined(HAVE_LIBCRYPTO)
-
-static int
-__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
-{
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
- EVP_MAC *mac;
-
- char sha1[] = "SHA1";
- OSSL_PARAM params[] = {
- OSSL_PARAM_utf8_string("digest", sha1, sizeof(sha1) - 1),
- OSSL_PARAM_END
- };
-
- mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
- *ctx = EVP_MAC_CTX_new(mac);
- EVP_MAC_free(mac);
- if (*ctx == NULL)
- return -1;
-
- EVP_MAC_init(*ctx, key, key_len, params);
-#else
- *ctx = HMAC_CTX_new();
- if (*ctx == NULL)
- return -1;
- HMAC_Init_ex(*ctx, key, key_len, EVP_sha1(), NULL);
-#endif
- return 0;
-}
-
-static void
-__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
- size_t data_len)
-{
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
- EVP_MAC_update(*ctx, data, data_len);
-#else
- HMAC_Update(*ctx, data, data_len);
-#endif
-}
-
-static void
-__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
-{
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
- size_t len = *out_len;
-#else
- unsigned int len = (unsigned int)*out_len;
-#endif
-
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
- EVP_MAC_final(*ctx, out, &len, *out_len);
-#else
- HMAC_Final(*ctx, out, &len);
-#endif
- *out_len = len;
-}
-
-static void
-__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
-{
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
- EVP_MAC_CTX_free(*ctx);
-#else
- HMAC_CTX_free(*ctx);
-#endif
- *ctx = NULL;
-}
-
-#else
-
-/* Stub */
-static int
-__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
-{
- (void)ctx;/* UNUSED */
- (void)key;/* UNUSED */
- (void)key_len;/* UNUSED */
- return -1;
-}
-
-static void
-__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
- size_t data_len)
-{
- (void)ctx;/* UNUSED */
- (void)data;/* UNUSED */
- (void)data_len;/* UNUSED */
-}
-
-static void
-__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
-{
- (void)ctx;/* UNUSED */
- (void)out;/* UNUSED */
- (void)out_len;/* UNUSED */
-}
-
-static void
-__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
-{
- (void)ctx;/* UNUSED */
-}
-
-#endif
-
-const struct archive_hmac __archive_hmac = {
- &__hmac_sha1_init,
- &__hmac_sha1_update,
- &__hmac_sha1_final,
- &__hmac_sha1_cleanup,
-};
diff --git a/contrib/libs/libarchive/libarchive/archive_hmac_private.h b/contrib/libs/libarchive/libarchive/archive_hmac_private.h
deleted file mode 100644
index 8d13b0fd72..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_hmac_private.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*-
-* Copyright (c) 2014 Michihiro NAKAJIMA
-* 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(S) ``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(S) 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.
-*/
-
-#ifndef ARCHIVE_HMAC_PRIVATE_H_INCLUDED
-#define ARCHIVE_HMAC_PRIVATE_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-/*
- * On systems that do not support any recognized crypto libraries,
- * the archive_hmac.c file is expected to define no usable symbols.
- *
- * But some compilers and linkers choke on empty object files, so
- * define a public symbol that will always exist. This could
- * be removed someday if this file gains another always-present
- * symbol definition.
- */
-int __libarchive_hmac_build_hack(void);
-
-#ifdef __APPLE__
-# include <AvailabilityMacros.h>
-# if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
-# define ARCHIVE_HMAC_USE_Apple_CommonCrypto
-# endif
-#endif
-
-#ifdef ARCHIVE_HMAC_USE_Apple_CommonCrypto
-#include <CommonCrypto/CommonHMAC.h>
-
-typedef CCHmacContext archive_hmac_sha1_ctx;
-
-#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
-#include <bcrypt.h>
-
-typedef struct {
- BCRYPT_ALG_HANDLE hAlg;
- BCRYPT_HASH_HANDLE hHash;
- DWORD hash_len;
- PBYTE hash;
-
-} archive_hmac_sha1_ctx;
-
-#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_MD_H)
-#error #include <mbedtls/md.h>
-
-typedef mbedtls_md_context_t archive_hmac_sha1_ctx;
-
-#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H)
-#error #include <nettle/hmac.h>
-
-typedef struct hmac_sha1_ctx archive_hmac_sha1_ctx;
-
-#elif defined(HAVE_LIBCRYPTO)
-#include <openssl/opensslv.h>
-#include <openssl/hmac.h>
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-#error #include <openssl/params.h>
-
-typedef EVP_MAC_CTX *archive_hmac_sha1_ctx;
-
-#else
-#include "archive_openssl_hmac_private.h"
-
-typedef HMAC_CTX* archive_hmac_sha1_ctx;
-#endif
-
-#else
-
-typedef int archive_hmac_sha1_ctx;
-
-#endif
-
-
-/* HMAC */
-#define archive_hmac_sha1_init(ctx, key, key_len)\
- __archive_hmac.__hmac_sha1_init(ctx, key, key_len)
-#define archive_hmac_sha1_update(ctx, data, data_len)\
- __archive_hmac.__hmac_sha1_update(ctx, data, data_len)
-#define archive_hmac_sha1_final(ctx, out, out_len)\
- __archive_hmac.__hmac_sha1_final(ctx, out, out_len)
-#define archive_hmac_sha1_cleanup(ctx)\
- __archive_hmac.__hmac_sha1_cleanup(ctx)
-
-
-struct archive_hmac {
- /* HMAC */
- int (*__hmac_sha1_init)(archive_hmac_sha1_ctx *, const uint8_t *,
- size_t);
- void (*__hmac_sha1_update)(archive_hmac_sha1_ctx *, const uint8_t *,
- size_t);
- void (*__hmac_sha1_final)(archive_hmac_sha1_ctx *, uint8_t *, size_t *);
- void (*__hmac_sha1_cleanup)(archive_hmac_sha1_ctx *);
-};
-
-extern const struct archive_hmac __archive_hmac;
-#endif /* ARCHIVE_HMAC_PRIVATE_H_INCLUDED */
diff --git a/contrib/libs/libarchive/libarchive/archive_match.c b/contrib/libs/libarchive/libarchive/archive_match.c
deleted file mode 100644
index 04747b1f66..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_match.c
+++ /dev/null
@@ -1,1875 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * Copyright (c) 2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_entry.h"
-#include "archive_getdate.h"
-#include "archive_pathmatch.h"
-#include "archive_rb.h"
-#include "archive_string.h"
-
-struct match {
- struct match *next;
- int matches;
- struct archive_mstring pattern;
-};
-
-struct match_list {
- struct match *first;
- struct match **last;
- int count;
- int unmatched_count;
- struct match *unmatched_next;
- int unmatched_eof;
-};
-
-struct match_file {
- struct archive_rb_node node;
- struct match_file *next;
- struct archive_mstring pathname;
- int flag;
- time_t mtime_sec;
- long mtime_nsec;
- time_t ctime_sec;
- long ctime_nsec;
-};
-
-struct entry_list {
- struct match_file *first;
- struct match_file **last;
- int count;
-};
-
-struct id_array {
- size_t size;/* Allocated size */
- size_t count;
- int64_t *ids;
-};
-
-#define PATTERN_IS_SET 1
-#define TIME_IS_SET 2
-#define ID_IS_SET 4
-
-struct archive_match {
- struct archive archive;
-
- /* exclusion/inclusion set flag. */
- int setflag;
-
- /* Recursively include directory content? */
- int recursive_include;
-
- /*
- * Matching filename patterns.
- */
- struct match_list exclusions;
- struct match_list inclusions;
-
- /*
- * Matching time stamps.
- */
- time_t now;
- int newer_mtime_filter;
- time_t newer_mtime_sec;
- long newer_mtime_nsec;
- int newer_ctime_filter;
- time_t newer_ctime_sec;
- long newer_ctime_nsec;
- int older_mtime_filter;
- time_t older_mtime_sec;
- long older_mtime_nsec;
- int older_ctime_filter;
- time_t older_ctime_sec;
- long older_ctime_nsec;
- /*
- * Matching time stamps with its filename.
- */
- struct archive_rb_tree exclusion_tree;
- struct entry_list exclusion_entry_list;
-
- /*
- * Matching file owners.
- */
- struct id_array inclusion_uids;
- struct id_array inclusion_gids;
- struct match_list inclusion_unames;
- struct match_list inclusion_gnames;
-};
-
-static int add_pattern_from_file(struct archive_match *,
- struct match_list *, int, const void *, int);
-static int add_entry(struct archive_match *, int,
- struct archive_entry *);
-static int add_owner_id(struct archive_match *, struct id_array *,
- int64_t);
-static int add_owner_name(struct archive_match *, struct match_list *,
- int, const void *);
-static int add_pattern_mbs(struct archive_match *, struct match_list *,
- const char *);
-static int add_pattern_wcs(struct archive_match *, struct match_list *,
- const wchar_t *);
-static int cmp_key_mbs(const struct archive_rb_node *, const void *);
-static int cmp_key_wcs(const struct archive_rb_node *, const void *);
-static int cmp_node_mbs(const struct archive_rb_node *,
- const struct archive_rb_node *);
-static int cmp_node_wcs(const struct archive_rb_node *,
- const struct archive_rb_node *);
-static void entry_list_add(struct entry_list *, struct match_file *);
-static void entry_list_free(struct entry_list *);
-static void entry_list_init(struct entry_list *);
-static int error_nomem(struct archive_match *);
-static void match_list_add(struct match_list *, struct match *);
-static void match_list_free(struct match_list *);
-static void match_list_init(struct match_list *);
-static int match_list_unmatched_inclusions_next(struct archive_match *,
- struct match_list *, int, const void **);
-static int match_owner_id(struct id_array *, int64_t);
-#if !defined(_WIN32) || defined(__CYGWIN__)
-static int match_owner_name_mbs(struct archive_match *,
- struct match_list *, const char *);
-#else
-static int match_owner_name_wcs(struct archive_match *,
- struct match_list *, const wchar_t *);
-#endif
-static int match_path_exclusion(struct archive_match *,
- struct match *, int, const void *);
-static int match_path_inclusion(struct archive_match *,
- struct match *, int, const void *);
-static int owner_excluded(struct archive_match *,
- struct archive_entry *);
-static int path_excluded(struct archive_match *, int, const void *);
-static int set_timefilter(struct archive_match *, int, time_t, long,
- time_t, long);
-static int set_timefilter_pathname_mbs(struct archive_match *,
- int, const char *);
-static int set_timefilter_pathname_wcs(struct archive_match *,
- int, const wchar_t *);
-static int set_timefilter_date(struct archive_match *, int, const char *);
-static int set_timefilter_date_w(struct archive_match *, int,
- const wchar_t *);
-static int time_excluded(struct archive_match *,
- struct archive_entry *);
-static int validate_time_flag(struct archive *, int, const char *);
-
-#define get_date __archive_get_date
-
-static const struct archive_rb_tree_ops rb_ops_mbs = {
- cmp_node_mbs, cmp_key_mbs
-};
-
-static const struct archive_rb_tree_ops rb_ops_wcs = {
- cmp_node_wcs, cmp_key_wcs
-};
-
-/*
- * The matching logic here needs to be re-thought. I started out to
- * try to mimic gtar's matching logic, but it's not entirely
- * consistent. In particular 'tar -t' and 'tar -x' interpret patterns
- * on the command line as anchored, but --exclude doesn't.
- */
-
-static int
-error_nomem(struct archive_match *a)
-{
- archive_set_error(&(a->archive), ENOMEM, "No memory");
- a->archive.state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
-}
-
-/*
- * Create an ARCHIVE_MATCH object.
- */
-struct archive *
-archive_match_new(void)
-{
- struct archive_match *a;
-
- a = (struct archive_match *)calloc(1, sizeof(*a));
- if (a == NULL)
- return (NULL);
- a->archive.magic = ARCHIVE_MATCH_MAGIC;
- a->archive.state = ARCHIVE_STATE_NEW;
- a->recursive_include = 1;
- match_list_init(&(a->inclusions));
- match_list_init(&(a->exclusions));
- __archive_rb_tree_init(&(a->exclusion_tree), &rb_ops_mbs);
- entry_list_init(&(a->exclusion_entry_list));
- match_list_init(&(a->inclusion_unames));
- match_list_init(&(a->inclusion_gnames));
- time(&a->now);
- return (&(a->archive));
-}
-
-/*
- * Free an ARCHIVE_MATCH object.
- */
-int
-archive_match_free(struct archive *_a)
-{
- struct archive_match *a;
-
- if (_a == NULL)
- return (ARCHIVE_OK);
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_match_free");
- a = (struct archive_match *)_a;
- match_list_free(&(a->inclusions));
- match_list_free(&(a->exclusions));
- entry_list_free(&(a->exclusion_entry_list));
- free(a->inclusion_uids.ids);
- free(a->inclusion_gids.ids);
- match_list_free(&(a->inclusion_unames));
- match_list_free(&(a->inclusion_gnames));
- free(a);
- return (ARCHIVE_OK);
-}
-
-/*
- * Convenience function to perform all exclusion tests.
- *
- * Returns 1 if archive entry is excluded.
- * Returns 0 if archive entry is not excluded.
- * Returns <0 if something error happened.
- */
-int
-archive_match_excluded(struct archive *_a, struct archive_entry *entry)
-{
- struct archive_match *a;
- int r;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_excluded_ae");
-
- a = (struct archive_match *)_a;
- if (entry == NULL) {
- archive_set_error(&(a->archive), EINVAL, "entry is NULL");
- return (ARCHIVE_FAILED);
- }
-
- r = 0;
- if (a->setflag & PATTERN_IS_SET) {
-#if defined(_WIN32) && !defined(__CYGWIN__)
- r = path_excluded(a, 0, archive_entry_pathname_w(entry));
-#else
- r = path_excluded(a, 1, archive_entry_pathname(entry));
-#endif
- if (r != 0)
- return (r);
- }
-
- if (a->setflag & TIME_IS_SET) {
- r = time_excluded(a, entry);
- if (r != 0)
- return (r);
- }
-
- if (a->setflag & ID_IS_SET)
- r = owner_excluded(a, entry);
- return (r);
-}
-
-/*
- * Utility functions to manage exclusion/inclusion patterns
- */
-
-int
-archive_match_exclude_pattern(struct archive *_a, const char *pattern)
-{
- struct archive_match *a;
- int r;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_exclude_pattern");
- a = (struct archive_match *)_a;
-
- if (pattern == NULL || *pattern == '\0') {
- archive_set_error(&(a->archive), EINVAL, "pattern is empty");
- return (ARCHIVE_FAILED);
- }
- if ((r = add_pattern_mbs(a, &(a->exclusions), pattern)) != ARCHIVE_OK)
- return (r);
- return (ARCHIVE_OK);
-}
-
-int
-archive_match_exclude_pattern_w(struct archive *_a, const wchar_t *pattern)
-{
- struct archive_match *a;
- int r;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_exclude_pattern_w");
- a = (struct archive_match *)_a;
-
- if (pattern == NULL || *pattern == L'\0') {
- archive_set_error(&(a->archive), EINVAL, "pattern is empty");
- return (ARCHIVE_FAILED);
- }
- if ((r = add_pattern_wcs(a, &(a->exclusions), pattern)) != ARCHIVE_OK)
- return (r);
- return (ARCHIVE_OK);
-}
-
-int
-archive_match_exclude_pattern_from_file(struct archive *_a,
- const char *pathname, int nullSeparator)
-{
- struct archive_match *a;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_exclude_pattern_from_file");
- a = (struct archive_match *)_a;
-
- return add_pattern_from_file(a, &(a->exclusions), 1, pathname,
- nullSeparator);
-}
-
-int
-archive_match_exclude_pattern_from_file_w(struct archive *_a,
- const wchar_t *pathname, int nullSeparator)
-{
- struct archive_match *a;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_exclude_pattern_from_file_w");
- a = (struct archive_match *)_a;
-
- return add_pattern_from_file(a, &(a->exclusions), 0, pathname,
- nullSeparator);
-}
-
-int
-archive_match_include_pattern(struct archive *_a, const char *pattern)
-{
- struct archive_match *a;
- int r;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_include_pattern");
- a = (struct archive_match *)_a;
-
- if (pattern == NULL || *pattern == '\0') {
- archive_set_error(&(a->archive), EINVAL, "pattern is empty");
- return (ARCHIVE_FAILED);
- }
- if ((r = add_pattern_mbs(a, &(a->inclusions), pattern)) != ARCHIVE_OK)
- return (r);
- return (ARCHIVE_OK);
-}
-
-int
-archive_match_include_pattern_w(struct archive *_a, const wchar_t *pattern)
-{
- struct archive_match *a;
- int r;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_include_pattern_w");
- a = (struct archive_match *)_a;
-
- if (pattern == NULL || *pattern == L'\0') {
- archive_set_error(&(a->archive), EINVAL, "pattern is empty");
- return (ARCHIVE_FAILED);
- }
- if ((r = add_pattern_wcs(a, &(a->inclusions), pattern)) != ARCHIVE_OK)
- return (r);
- return (ARCHIVE_OK);
-}
-
-int
-archive_match_include_pattern_from_file(struct archive *_a,
- const char *pathname, int nullSeparator)
-{
- struct archive_match *a;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_include_pattern_from_file");
- a = (struct archive_match *)_a;
-
- return add_pattern_from_file(a, &(a->inclusions), 1, pathname,
- nullSeparator);
-}
-
-int
-archive_match_include_pattern_from_file_w(struct archive *_a,
- const wchar_t *pathname, int nullSeparator)
-{
- struct archive_match *a;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_include_pattern_from_file_w");
- a = (struct archive_match *)_a;
-
- return add_pattern_from_file(a, &(a->inclusions), 0, pathname,
- nullSeparator);
-}
-
-/*
- * Test functions for pathname patterns.
- *
- * Returns 1 if archive entry is excluded.
- * Returns 0 if archive entry is not excluded.
- * Returns <0 if something error happened.
- */
-int
-archive_match_path_excluded(struct archive *_a,
- struct archive_entry *entry)
-{
- struct archive_match *a;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_path_excluded");
-
- a = (struct archive_match *)_a;
- if (entry == NULL) {
- archive_set_error(&(a->archive), EINVAL, "entry is NULL");
- return (ARCHIVE_FAILED);
- }
-
- /* If we don't have exclusion/inclusion pattern set at all,
- * the entry is always not excluded. */
- if ((a->setflag & PATTERN_IS_SET) == 0)
- return (0);
-#if defined(_WIN32) && !defined(__CYGWIN__)
- return (path_excluded(a, 0, archive_entry_pathname_w(entry)));
-#else
- return (path_excluded(a, 1, archive_entry_pathname(entry)));
-#endif
-}
-
-/*
- * When recursive inclusion of directory content is enabled,
- * an inclusion pattern that matches a directory will also
- * include everything beneath that directory. Enabled by default.
- *
- * For compatibility with GNU tar, exclusion patterns always
- * match if a subset of the full patch matches (i.e., they are
- * are not rooted at the beginning of the path) and thus there
- * is no corresponding non-recursive exclusion mode.
- */
-int
-archive_match_set_inclusion_recursion(struct archive *_a, int enabled)
-{
- struct archive_match *a;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_set_inclusion_recursion");
- a = (struct archive_match *)_a;
- a->recursive_include = enabled;
- return (ARCHIVE_OK);
-}
-
-/*
- * Utility functions to get statistic information for inclusion patterns.
- */
-int
-archive_match_path_unmatched_inclusions(struct archive *_a)
-{
- struct archive_match *a;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_unmatched_inclusions");
- a = (struct archive_match *)_a;
-
- return (a->inclusions.unmatched_count);
-}
-
-int
-archive_match_path_unmatched_inclusions_next(struct archive *_a,
- const char **_p)
-{
- struct archive_match *a;
- const void *v;
- int r;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_unmatched_inclusions_next");
- a = (struct archive_match *)_a;
-
- r = match_list_unmatched_inclusions_next(a, &(a->inclusions), 1, &v);
- *_p = (const char *)v;
- return (r);
-}
-
-int
-archive_match_path_unmatched_inclusions_next_w(struct archive *_a,
- const wchar_t **_p)
-{
- struct archive_match *a;
- const void *v;
- int r;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_unmatched_inclusions_next_w");
- a = (struct archive_match *)_a;
-
- r = match_list_unmatched_inclusions_next(a, &(a->inclusions), 0, &v);
- *_p = (const wchar_t *)v;
- return (r);
-}
-
-/*
- * Add inclusion/exclusion patterns.
- */
-static int
-add_pattern_mbs(struct archive_match *a, struct match_list *list,
- const char *pattern)
-{
- struct match *match;
- size_t len;
-
- match = calloc(1, sizeof(*match));
- if (match == NULL)
- return (error_nomem(a));
- /* Both "foo/" and "foo" should match "foo/bar". */
- len = strlen(pattern);
- if (len && pattern[len - 1] == '/')
- --len;
- archive_mstring_copy_mbs_len(&(match->pattern), pattern, len);
- match_list_add(list, match);
- a->setflag |= PATTERN_IS_SET;
- return (ARCHIVE_OK);
-}
-
-static int
-add_pattern_wcs(struct archive_match *a, struct match_list *list,
- const wchar_t *pattern)
-{
- struct match *match;
- size_t len;
-
- match = calloc(1, sizeof(*match));
- if (match == NULL)
- return (error_nomem(a));
- /* Both "foo/" and "foo" should match "foo/bar". */
- len = wcslen(pattern);
- if (len && pattern[len - 1] == L'/')
- --len;
- archive_mstring_copy_wcs_len(&(match->pattern), pattern, len);
- match_list_add(list, match);
- a->setflag |= PATTERN_IS_SET;
- return (ARCHIVE_OK);
-}
-
-static int
-add_pattern_from_file(struct archive_match *a, struct match_list *mlist,
- int mbs, const void *pathname, int nullSeparator)
-{
- struct archive *ar;
- struct archive_entry *ae;
- struct archive_string as;
- const void *buff;
- size_t size;
- int64_t offset;
- int r;
-
- ar = archive_read_new();
- if (ar == NULL) {
- archive_set_error(&(a->archive), ENOMEM, "No memory");
- return (ARCHIVE_FATAL);
- }
- r = archive_read_support_format_raw(ar);
- r = archive_read_support_format_empty(ar);
- if (r != ARCHIVE_OK) {
- archive_copy_error(&(a->archive), ar);
- archive_read_free(ar);
- return (r);
- }
- if (mbs)
- r = archive_read_open_filename(ar, pathname, 512*20);
- else
- r = archive_read_open_filename_w(ar, pathname, 512*20);
- if (r != ARCHIVE_OK) {
- archive_copy_error(&(a->archive), ar);
- archive_read_free(ar);
- return (r);
- }
- r = archive_read_next_header(ar, &ae);
- if (r != ARCHIVE_OK) {
- archive_read_free(ar);
- if (r == ARCHIVE_EOF) {
- return (ARCHIVE_OK);
- } else {
- archive_copy_error(&(a->archive), ar);
- return (r);
- }
- }
-
- archive_string_init(&as);
-
- while ((r = archive_read_data_block(ar, &buff, &size, &offset))
- == ARCHIVE_OK) {
- const char *b = (const char *)buff;
-
- while (size) {
- const char *s = (const char *)b;
- size_t length = 0;
- int found_separator = 0;
-
- while (length < size) {
- if (nullSeparator) {
- if (*b == '\0') {
- found_separator = 1;
- break;
- }
- } else {
- if (*b == 0x0d || *b == 0x0a) {
- found_separator = 1;
- break;
- }
- }
- b++;
- length++;
- }
- if (!found_separator) {
- archive_strncat(&as, s, length);
- /* Read next data block. */
- break;
- }
- b++;
- size -= length + 1;
- archive_strncat(&as, s, length);
-
- /* If the line is not empty, add the pattern. */
- if (archive_strlen(&as) > 0) {
- /* Add pattern. */
- r = add_pattern_mbs(a, mlist, as.s);
- if (r != ARCHIVE_OK) {
- archive_read_free(ar);
- archive_string_free(&as);
- return (r);
- }
- archive_string_empty(&as);
- }
- }
- }
-
- /* If an error occurred, report it immediately. */
- if (r < ARCHIVE_OK) {
- archive_copy_error(&(a->archive), ar);
- archive_read_free(ar);
- archive_string_free(&as);
- return (r);
- }
-
- /* If the line is not empty, add the pattern. */
- if (r == ARCHIVE_EOF && archive_strlen(&as) > 0) {
- /* Add pattern. */
- r = add_pattern_mbs(a, mlist, as.s);
- if (r != ARCHIVE_OK) {
- archive_read_free(ar);
- archive_string_free(&as);
- return (r);
- }
- }
- archive_read_free(ar);
- archive_string_free(&as);
- return (ARCHIVE_OK);
-}
-
-/*
- * Test if pathname is excluded by inclusion/exclusion patterns.
- */
-static int
-path_excluded(struct archive_match *a, int mbs, const void *pathname)
-{
- struct match *match;
- struct match *matched;
- int r;
-
- if (a == NULL)
- return (0);
-
- /* Mark off any unmatched inclusions. */
- /* In particular, if a filename does appear in the archive and
- * is explicitly included and excluded, then we don't report
- * it as missing even though we don't extract it.
- */
- matched = NULL;
- for (match = a->inclusions.first; match != NULL;
- match = match->next){
- if (match->matches == 0 &&
- (r = match_path_inclusion(a, match, mbs, pathname)) != 0) {
- if (r < 0)
- return (r);
- a->inclusions.unmatched_count--;
- match->matches++;
- matched = match;
- }
- }
-
- /* Exclusions take priority */
- for (match = a->exclusions.first; match != NULL;
- match = match->next){
- r = match_path_exclusion(a, match, mbs, pathname);
- if (r)
- return (r);
- }
-
- /* It's not excluded and we found an inclusion above, so it's
- * included. */
- if (matched != NULL)
- return (0);
-
-
- /* We didn't find an unmatched inclusion, check the remaining ones. */
- for (match = a->inclusions.first; match != NULL;
- match = match->next){
- /* We looked at previously-unmatched inclusions already. */
- if (match->matches > 0 &&
- (r = match_path_inclusion(a, match, mbs, pathname)) != 0) {
- if (r < 0)
- return (r);
- match->matches++;
- return (0);
- }
- }
-
- /* If there were inclusions, default is to exclude. */
- if (a->inclusions.first != NULL)
- return (1);
-
- /* No explicit inclusions, default is to match. */
- return (0);
-}
-
-/*
- * This is a little odd, but it matches the default behavior of
- * gtar. In particular, 'a*b' will match 'foo/a1111/222b/bar'
- *
- */
-static int
-match_path_exclusion(struct archive_match *a, struct match *m,
- int mbs, const void *pn)
-{
- int flag = PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END;
- int r;
-
- if (mbs) {
- const char *p;
- r = archive_mstring_get_mbs(&(a->archive), &(m->pattern), &p);
- if (r == 0)
- return (archive_pathmatch(p, (const char *)pn, flag));
- } else {
- const wchar_t *p;
- r = archive_mstring_get_wcs(&(a->archive), &(m->pattern), &p);
- if (r == 0)
- return (archive_pathmatch_w(p, (const wchar_t *)pn,
- flag));
- }
- if (errno == ENOMEM)
- return (error_nomem(a));
- return (0);
-}
-
-/*
- * Again, mimic gtar: inclusions are always anchored (have to match
- * the beginning of the path) even though exclusions are not anchored.
- */
-static int
-match_path_inclusion(struct archive_match *a, struct match *m,
- int mbs, const void *pn)
-{
- /* Recursive operation requires only a prefix match. */
- int flag = a->recursive_include ?
- PATHMATCH_NO_ANCHOR_END :
- 0;
- int r;
-
- if (mbs) {
- const char *p;
- r = archive_mstring_get_mbs(&(a->archive), &(m->pattern), &p);
- if (r == 0)
- return (archive_pathmatch(p, (const char *)pn, flag));
- } else {
- const wchar_t *p;
- r = archive_mstring_get_wcs(&(a->archive), &(m->pattern), &p);
- if (r == 0)
- return (archive_pathmatch_w(p, (const wchar_t *)pn,
- flag));
- }
- if (errno == ENOMEM)
- return (error_nomem(a));
- return (0);
-}
-
-static void
-match_list_init(struct match_list *list)
-{
- list->first = NULL;
- list->last = &(list->first);
- list->count = 0;
-}
-
-static void
-match_list_free(struct match_list *list)
-{
- struct match *p, *q;
-
- for (p = list->first; p != NULL; ) {
- q = p;
- p = p->next;
- archive_mstring_clean(&(q->pattern));
- free(q);
- }
-}
-
-static void
-match_list_add(struct match_list *list, struct match *m)
-{
- *list->last = m;
- list->last = &(m->next);
- list->count++;
- list->unmatched_count++;
-}
-
-static int
-match_list_unmatched_inclusions_next(struct archive_match *a,
- struct match_list *list, int mbs, const void **vp)
-{
- struct match *m;
-
- *vp = NULL;
- if (list->unmatched_eof) {
- list->unmatched_eof = 0;
- return (ARCHIVE_EOF);
- }
- if (list->unmatched_next == NULL) {
- if (list->unmatched_count == 0)
- return (ARCHIVE_EOF);
- list->unmatched_next = list->first;
- }
-
- for (m = list->unmatched_next; m != NULL; m = m->next) {
- int r;
-
- if (m->matches)
- continue;
- if (mbs) {
- const char *p;
- r = archive_mstring_get_mbs(&(a->archive),
- &(m->pattern), &p);
- if (r < 0 && errno == ENOMEM)
- return (error_nomem(a));
- if (p == NULL)
- p = "";
- *vp = p;
- } else {
- const wchar_t *p;
- r = archive_mstring_get_wcs(&(a->archive),
- &(m->pattern), &p);
- if (r < 0 && errno == ENOMEM)
- return (error_nomem(a));
- if (p == NULL)
- p = L"";
- *vp = p;
- }
- list->unmatched_next = m->next;
- if (list->unmatched_next == NULL)
- /* To return EOF next time. */
- list->unmatched_eof = 1;
- return (ARCHIVE_OK);
- }
- list->unmatched_next = NULL;
- return (ARCHIVE_EOF);
-}
-
-/*
- * Utility functions to manage inclusion timestamps.
- */
-int
-archive_match_include_time(struct archive *_a, int flag, time_t sec,
- long nsec)
-{
- int r;
-
- r = validate_time_flag(_a, flag, "archive_match_include_time");
- if (r != ARCHIVE_OK)
- return (r);
- return set_timefilter((struct archive_match *)_a, flag,
- sec, nsec, sec, nsec);
-}
-
-int
-archive_match_include_date(struct archive *_a, int flag,
- const char *datestr)
-{
- int r;
-
- r = validate_time_flag(_a, flag, "archive_match_include_date");
- if (r != ARCHIVE_OK)
- return (r);
- return set_timefilter_date((struct archive_match *)_a, flag, datestr);
-}
-
-int
-archive_match_include_date_w(struct archive *_a, int flag,
- const wchar_t *datestr)
-{
- int r;
-
- r = validate_time_flag(_a, flag, "archive_match_include_date_w");
- if (r != ARCHIVE_OK)
- return (r);
-
- return set_timefilter_date_w((struct archive_match *)_a, flag, datestr);
-}
-
-int
-archive_match_include_file_time(struct archive *_a, int flag,
- const char *pathname)
-{
- int r;
-
- r = validate_time_flag(_a, flag, "archive_match_include_file_time");
- if (r != ARCHIVE_OK)
- return (r);
- return set_timefilter_pathname_mbs((struct archive_match *)_a,
- flag, pathname);
-}
-
-int
-archive_match_include_file_time_w(struct archive *_a, int flag,
- const wchar_t *pathname)
-{
- int r;
-
- r = validate_time_flag(_a, flag, "archive_match_include_file_time_w");
- if (r != ARCHIVE_OK)
- return (r);
- return set_timefilter_pathname_wcs((struct archive_match *)_a,
- flag, pathname);
-}
-
-int
-archive_match_exclude_entry(struct archive *_a, int flag,
- struct archive_entry *entry)
-{
- struct archive_match *a;
- int r;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_time_include_entry");
- a = (struct archive_match *)_a;
-
- if (entry == NULL) {
- archive_set_error(&(a->archive), EINVAL, "entry is NULL");
- return (ARCHIVE_FAILED);
- }
- r = validate_time_flag(_a, flag, "archive_match_exclude_entry");
- if (r != ARCHIVE_OK)
- return (r);
- return (add_entry(a, flag, entry));
-}
-
-/*
- * Test function for time stamps.
- *
- * Returns 1 if archive entry is excluded.
- * Returns 0 if archive entry is not excluded.
- * Returns <0 if something error happened.
- */
-int
-archive_match_time_excluded(struct archive *_a,
- struct archive_entry *entry)
-{
- struct archive_match *a;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_time_excluded_ae");
-
- a = (struct archive_match *)_a;
- if (entry == NULL) {
- archive_set_error(&(a->archive), EINVAL, "entry is NULL");
- return (ARCHIVE_FAILED);
- }
-
- /* If we don't have inclusion time set at all, the entry is always
- * not excluded. */
- if ((a->setflag & TIME_IS_SET) == 0)
- return (0);
- return (time_excluded(a, entry));
-}
-
-static int
-validate_time_flag(struct archive *_a, int flag, const char *_fn)
-{
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, _fn);
-
- /* Check a type of time. */
- if (flag &
- ((~(ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME)) & 0xff00)) {
- archive_set_error(_a, EINVAL, "Invalid time flag");
- return (ARCHIVE_FAILED);
- }
- if ((flag & (ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME)) == 0) {
- archive_set_error(_a, EINVAL, "No time flag");
- return (ARCHIVE_FAILED);
- }
-
- /* Check a type of comparison. */
- if (flag &
- ((~(ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_OLDER
- | ARCHIVE_MATCH_EQUAL)) & 0x00ff)) {
- archive_set_error(_a, EINVAL, "Invalid comparison flag");
- return (ARCHIVE_FAILED);
- }
- if ((flag & (ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_OLDER
- | ARCHIVE_MATCH_EQUAL)) == 0) {
- archive_set_error(_a, EINVAL, "No comparison flag");
- return (ARCHIVE_FAILED);
- }
-
- return (ARCHIVE_OK);
-}
-
-#define JUST_EQUAL(t) (((t) & (ARCHIVE_MATCH_EQUAL |\
- ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_OLDER)) == ARCHIVE_MATCH_EQUAL)
-static int
-set_timefilter(struct archive_match *a, int timetype,
- time_t mtime_sec, long mtime_nsec, time_t ctime_sec, long ctime_nsec)
-{
- if (timetype & ARCHIVE_MATCH_MTIME) {
- if ((timetype & ARCHIVE_MATCH_NEWER) || JUST_EQUAL(timetype)) {
- a->newer_mtime_filter = timetype;
- a->newer_mtime_sec = mtime_sec;
- a->newer_mtime_nsec = mtime_nsec;
- a->setflag |= TIME_IS_SET;
- }
- if ((timetype & ARCHIVE_MATCH_OLDER) || JUST_EQUAL(timetype)) {
- a->older_mtime_filter = timetype;
- a->older_mtime_sec = mtime_sec;
- a->older_mtime_nsec = mtime_nsec;
- a->setflag |= TIME_IS_SET;
- }
- }
- if (timetype & ARCHIVE_MATCH_CTIME) {
- if ((timetype & ARCHIVE_MATCH_NEWER) || JUST_EQUAL(timetype)) {
- a->newer_ctime_filter = timetype;
- a->newer_ctime_sec = ctime_sec;
- a->newer_ctime_nsec = ctime_nsec;
- a->setflag |= TIME_IS_SET;
- }
- if ((timetype & ARCHIVE_MATCH_OLDER) || JUST_EQUAL(timetype)) {
- a->older_ctime_filter = timetype;
- a->older_ctime_sec = ctime_sec;
- a->older_ctime_nsec = ctime_nsec;
- a->setflag |= TIME_IS_SET;
- }
- }
- return (ARCHIVE_OK);
-}
-
-static int
-set_timefilter_date(struct archive_match *a, int timetype, const char *datestr)
-{
- time_t t;
-
- if (datestr == NULL || *datestr == '\0') {
- archive_set_error(&(a->archive), EINVAL, "date is empty");
- return (ARCHIVE_FAILED);
- }
- t = get_date(a->now, datestr);
- if (t == (time_t)-1) {
- archive_set_error(&(a->archive), EINVAL, "invalid date string");
- return (ARCHIVE_FAILED);
- }
- return set_timefilter(a, timetype, t, 0, t, 0);
-}
-
-static int
-set_timefilter_date_w(struct archive_match *a, int timetype,
- const wchar_t *datestr)
-{
- struct archive_string as;
- time_t t;
-
- if (datestr == NULL || *datestr == L'\0') {
- archive_set_error(&(a->archive), EINVAL, "date is empty");
- return (ARCHIVE_FAILED);
- }
-
- archive_string_init(&as);
- if (archive_string_append_from_wcs(&as, datestr, wcslen(datestr)) < 0) {
- archive_string_free(&as);
- if (errno == ENOMEM)
- return (error_nomem(a));
- archive_set_error(&(a->archive), -1,
- "Failed to convert WCS to MBS");
- return (ARCHIVE_FAILED);
- }
- t = get_date(a->now, as.s);
- archive_string_free(&as);
- if (t == (time_t)-1) {
- archive_set_error(&(a->archive), EINVAL, "invalid date string");
- return (ARCHIVE_FAILED);
- }
- return set_timefilter(a, timetype, t, 0, t, 0);
-}
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
-static int
-set_timefilter_find_data(struct archive_match *a, int timetype,
- DWORD ftLastWriteTime_dwHighDateTime, DWORD ftLastWriteTime_dwLowDateTime,
- DWORD ftCreationTime_dwHighDateTime, DWORD ftCreationTime_dwLowDateTime)
-{
- ULARGE_INTEGER utc;
- time_t ctime_sec, mtime_sec;
- long ctime_ns, mtime_ns;
-
- utc.HighPart = ftCreationTime_dwHighDateTime;
- utc.LowPart = ftCreationTime_dwLowDateTime;
- if (utc.QuadPart >= EPOC_TIME) {
- utc.QuadPart -= EPOC_TIME;
- ctime_sec = (time_t)(utc.QuadPart / 10000000);
- ctime_ns = (long)(utc.QuadPart % 10000000) * 100;
- } else {
- ctime_sec = 0;
- ctime_ns = 0;
- }
- utc.HighPart = ftLastWriteTime_dwHighDateTime;
- utc.LowPart = ftLastWriteTime_dwLowDateTime;
- if (utc.QuadPart >= EPOC_TIME) {
- utc.QuadPart -= EPOC_TIME;
- mtime_sec = (time_t)(utc.QuadPart / 10000000);
- mtime_ns = (long)(utc.QuadPart % 10000000) * 100;
- } else {
- mtime_sec = 0;
- mtime_ns = 0;
- }
- return set_timefilter(a, timetype,
- mtime_sec, mtime_ns, ctime_sec, ctime_ns);
-}
-
-static int
-set_timefilter_pathname_mbs(struct archive_match *a, int timetype,
- const char *path)
-{
- /* NOTE: stat() on Windows cannot handle nano seconds. */
- HANDLE h;
- WIN32_FIND_DATAA d;
-
- if (path == NULL || *path == '\0') {
- archive_set_error(&(a->archive), EINVAL, "pathname is empty");
- return (ARCHIVE_FAILED);
- }
- h = FindFirstFileA(path, &d);
- if (h == INVALID_HANDLE_VALUE) {
- la_dosmaperr(GetLastError());
- archive_set_error(&(a->archive), errno,
- "Failed to FindFirstFileA");
- return (ARCHIVE_FAILED);
- }
- FindClose(h);
- return set_timefilter_find_data(a, timetype,
- d.ftLastWriteTime.dwHighDateTime, d.ftLastWriteTime.dwLowDateTime,
- d.ftCreationTime.dwHighDateTime, d.ftCreationTime.dwLowDateTime);
-}
-
-static int
-set_timefilter_pathname_wcs(struct archive_match *a, int timetype,
- const wchar_t *path)
-{
- HANDLE h;
- WIN32_FIND_DATAW d;
-
- if (path == NULL || *path == L'\0') {
- archive_set_error(&(a->archive), EINVAL, "pathname is empty");
- return (ARCHIVE_FAILED);
- }
- h = FindFirstFileW(path, &d);
- if (h == INVALID_HANDLE_VALUE) {
- la_dosmaperr(GetLastError());
- archive_set_error(&(a->archive), errno,
- "Failed to FindFirstFile");
- return (ARCHIVE_FAILED);
- }
- FindClose(h);
- return set_timefilter_find_data(a, timetype,
- d.ftLastWriteTime.dwHighDateTime, d.ftLastWriteTime.dwLowDateTime,
- d.ftCreationTime.dwHighDateTime, d.ftCreationTime.dwLowDateTime);
-}
-
-#else /* _WIN32 && !__CYGWIN__ */
-
-static int
-set_timefilter_stat(struct archive_match *a, int timetype, struct stat *st)
-{
- struct archive_entry *ae;
- time_t ctime_sec, mtime_sec;
- long ctime_ns, mtime_ns;
-
- ae = archive_entry_new();
- if (ae == NULL)
- return (error_nomem(a));
- archive_entry_copy_stat(ae, st);
- ctime_sec = archive_entry_ctime(ae);
- ctime_ns = archive_entry_ctime_nsec(ae);
- mtime_sec = archive_entry_mtime(ae);
- mtime_ns = archive_entry_mtime_nsec(ae);
- archive_entry_free(ae);
- return set_timefilter(a, timetype, mtime_sec, mtime_ns,
- ctime_sec, ctime_ns);
-}
-
-static int
-set_timefilter_pathname_mbs(struct archive_match *a, int timetype,
- const char *path)
-{
- struct stat st;
-
- if (path == NULL || *path == '\0') {
- archive_set_error(&(a->archive), EINVAL, "pathname is empty");
- return (ARCHIVE_FAILED);
- }
- if (la_stat(path, &st) != 0) {
- archive_set_error(&(a->archive), errno, "Failed to stat()");
- return (ARCHIVE_FAILED);
- }
- return (set_timefilter_stat(a, timetype, &st));
-}
-
-static int
-set_timefilter_pathname_wcs(struct archive_match *a, int timetype,
- const wchar_t *path)
-{
- struct archive_string as;
- int r;
-
- if (path == NULL || *path == L'\0') {
- archive_set_error(&(a->archive), EINVAL, "pathname is empty");
- return (ARCHIVE_FAILED);
- }
-
- /* Convert WCS filename to MBS filename. */
- archive_string_init(&as);
- if (archive_string_append_from_wcs(&as, path, wcslen(path)) < 0) {
- archive_string_free(&as);
- if (errno == ENOMEM)
- return (error_nomem(a));
- archive_set_error(&(a->archive), -1,
- "Failed to convert WCS to MBS");
- return (ARCHIVE_FAILED);
- }
-
- r = set_timefilter_pathname_mbs(a, timetype, as.s);
- archive_string_free(&as);
-
- return (r);
-}
-#endif /* _WIN32 && !__CYGWIN__ */
-
-/*
- * Call back functions for archive_rb.
- */
-static int
-cmp_node_mbs(const struct archive_rb_node *n1,
- const struct archive_rb_node *n2)
-{
- struct match_file *f1 = (struct match_file *)(uintptr_t)n1;
- struct match_file *f2 = (struct match_file *)(uintptr_t)n2;
- const char *p1, *p2;
-
- archive_mstring_get_mbs(NULL, &(f1->pathname), &p1);
- archive_mstring_get_mbs(NULL, &(f2->pathname), &p2);
- if (p1 == NULL)
- return (1);
- if (p2 == NULL)
- return (-1);
- return (strcmp(p1, p2));
-}
-
-static int
-cmp_key_mbs(const struct archive_rb_node *n, const void *key)
-{
- struct match_file *f = (struct match_file *)(uintptr_t)n;
- const char *p;
-
- archive_mstring_get_mbs(NULL, &(f->pathname), &p);
- if (p == NULL)
- return (-1);
- return (strcmp(p, (const char *)key));
-}
-
-static int
-cmp_node_wcs(const struct archive_rb_node *n1,
- const struct archive_rb_node *n2)
-{
- struct match_file *f1 = (struct match_file *)(uintptr_t)n1;
- struct match_file *f2 = (struct match_file *)(uintptr_t)n2;
- const wchar_t *p1, *p2;
-
- archive_mstring_get_wcs(NULL, &(f1->pathname), &p1);
- archive_mstring_get_wcs(NULL, &(f2->pathname), &p2);
- if (p1 == NULL)
- return (1);
- if (p2 == NULL)
- return (-1);
- return (wcscmp(p1, p2));
-}
-
-static int
-cmp_key_wcs(const struct archive_rb_node *n, const void *key)
-{
- struct match_file *f = (struct match_file *)(uintptr_t)n;
- const wchar_t *p;
-
- archive_mstring_get_wcs(NULL, &(f->pathname), &p);
- if (p == NULL)
- return (-1);
- return (wcscmp(p, (const wchar_t *)key));
-}
-
-static void
-entry_list_init(struct entry_list *list)
-{
- list->first = NULL;
- list->last = &(list->first);
- list->count = 0;
-}
-
-static void
-entry_list_free(struct entry_list *list)
-{
- struct match_file *p, *q;
-
- for (p = list->first; p != NULL; ) {
- q = p;
- p = p->next;
- archive_mstring_clean(&(q->pathname));
- free(q);
- }
-}
-
-static void
-entry_list_add(struct entry_list *list, struct match_file *file)
-{
- *list->last = file;
- list->last = &(file->next);
- list->count++;
-}
-
-static int
-add_entry(struct archive_match *a, int flag,
- struct archive_entry *entry)
-{
- struct match_file *f;
- const void *pathname;
- int r;
-
- f = calloc(1, sizeof(*f));
- if (f == NULL)
- return (error_nomem(a));
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- pathname = archive_entry_pathname_w(entry);
- if (pathname == NULL) {
- free(f);
- archive_set_error(&(a->archive), EINVAL, "pathname is NULL");
- return (ARCHIVE_FAILED);
- }
- archive_mstring_copy_wcs(&(f->pathname), pathname);
- a->exclusion_tree.rbt_ops = &rb_ops_wcs;
-#else
- (void)rb_ops_wcs;
- pathname = archive_entry_pathname(entry);
- if (pathname == NULL) {
- free(f);
- archive_set_error(&(a->archive), EINVAL, "pathname is NULL");
- return (ARCHIVE_FAILED);
- }
- archive_mstring_copy_mbs(&(f->pathname), pathname);
- a->exclusion_tree.rbt_ops = &rb_ops_mbs;
-#endif
- f->flag = flag;
- f->mtime_sec = archive_entry_mtime(entry);
- f->mtime_nsec = archive_entry_mtime_nsec(entry);
- f->ctime_sec = archive_entry_ctime(entry);
- f->ctime_nsec = archive_entry_ctime_nsec(entry);
- r = __archive_rb_tree_insert_node(&(a->exclusion_tree), &(f->node));
- if (!r) {
- struct match_file *f2;
-
- /* Get the duplicated file. */
- f2 = (struct match_file *)__archive_rb_tree_find_node(
- &(a->exclusion_tree), pathname);
-
- /*
- * We always overwrite comparison condition.
- * If you do not want to overwrite it, you should not
- * call archive_match_exclude_entry(). We cannot know
- * what behavior you really expect since overwriting
- * condition might be different with the flag.
- */
- if (f2 != NULL) {
- f2->flag = f->flag;
- f2->mtime_sec = f->mtime_sec;
- f2->mtime_nsec = f->mtime_nsec;
- f2->ctime_sec = f->ctime_sec;
- f2->ctime_nsec = f->ctime_nsec;
- }
- /* Release the duplicated file. */
- archive_mstring_clean(&(f->pathname));
- free(f);
- return (ARCHIVE_OK);
- }
- entry_list_add(&(a->exclusion_entry_list), f);
- a->setflag |= TIME_IS_SET;
- return (ARCHIVE_OK);
-}
-
-/*
- * Test if entry is excluded by its timestamp.
- */
-static int
-time_excluded(struct archive_match *a, struct archive_entry *entry)
-{
- struct match_file *f;
- const void *pathname;
- time_t sec;
- long nsec;
-
- /*
- * If this file/dir is excluded by a time comparison, skip it.
- */
- if (a->newer_ctime_filter) {
- /* If ctime is not set, use mtime instead. */
- if (archive_entry_ctime_is_set(entry))
- sec = archive_entry_ctime(entry);
- else
- sec = archive_entry_mtime(entry);
- if (sec < a->newer_ctime_sec)
- return (1); /* Too old, skip it. */
- if (sec == a->newer_ctime_sec) {
- if (archive_entry_ctime_is_set(entry))
- nsec = archive_entry_ctime_nsec(entry);
- else
- nsec = archive_entry_mtime_nsec(entry);
- if (nsec < a->newer_ctime_nsec)
- return (1); /* Too old, skip it. */
- if (nsec == a->newer_ctime_nsec &&
- (a->newer_ctime_filter & ARCHIVE_MATCH_EQUAL)
- == 0)
- return (1); /* Equal, skip it. */
- }
- }
- if (a->older_ctime_filter) {
- /* If ctime is not set, use mtime instead. */
- if (archive_entry_ctime_is_set(entry))
- sec = archive_entry_ctime(entry);
- else
- sec = archive_entry_mtime(entry);
- if (sec > a->older_ctime_sec)
- return (1); /* Too new, skip it. */
- if (sec == a->older_ctime_sec) {
- if (archive_entry_ctime_is_set(entry))
- nsec = archive_entry_ctime_nsec(entry);
- else
- nsec = archive_entry_mtime_nsec(entry);
- if (nsec > a->older_ctime_nsec)
- return (1); /* Too new, skip it. */
- if (nsec == a->older_ctime_nsec &&
- (a->older_ctime_filter & ARCHIVE_MATCH_EQUAL)
- == 0)
- return (1); /* Equal, skip it. */
- }
- }
- if (a->newer_mtime_filter) {
- sec = archive_entry_mtime(entry);
- if (sec < a->newer_mtime_sec)
- return (1); /* Too old, skip it. */
- if (sec == a->newer_mtime_sec) {
- nsec = archive_entry_mtime_nsec(entry);
- if (nsec < a->newer_mtime_nsec)
- return (1); /* Too old, skip it. */
- if (nsec == a->newer_mtime_nsec &&
- (a->newer_mtime_filter & ARCHIVE_MATCH_EQUAL)
- == 0)
- return (1); /* Equal, skip it. */
- }
- }
- if (a->older_mtime_filter) {
- sec = archive_entry_mtime(entry);
- if (sec > a->older_mtime_sec)
- return (1); /* Too new, skip it. */
- nsec = archive_entry_mtime_nsec(entry);
- if (sec == a->older_mtime_sec) {
- if (nsec > a->older_mtime_nsec)
- return (1); /* Too new, skip it. */
- if (nsec == a->older_mtime_nsec &&
- (a->older_mtime_filter & ARCHIVE_MATCH_EQUAL)
- == 0)
- return (1); /* Equal, skip it. */
- }
- }
-
- /* If there is no exclusion list, include the file. */
- if (a->exclusion_entry_list.count == 0)
- return (0);
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- pathname = archive_entry_pathname_w(entry);
- a->exclusion_tree.rbt_ops = &rb_ops_wcs;
-#else
- (void)rb_ops_wcs;
- pathname = archive_entry_pathname(entry);
- a->exclusion_tree.rbt_ops = &rb_ops_mbs;
-#endif
- if (pathname == NULL)
- return (0);
-
- f = (struct match_file *)__archive_rb_tree_find_node(
- &(a->exclusion_tree), pathname);
- /* If the file wasn't rejected, include it. */
- if (f == NULL)
- return (0);
-
- if (f->flag & ARCHIVE_MATCH_CTIME) {
- sec = archive_entry_ctime(entry);
- if (f->ctime_sec > sec) {
- if (f->flag & ARCHIVE_MATCH_OLDER)
- return (1);
- } else if (f->ctime_sec < sec) {
- if (f->flag & ARCHIVE_MATCH_NEWER)
- return (1);
- } else {
- nsec = archive_entry_ctime_nsec(entry);
- if (f->ctime_nsec > nsec) {
- if (f->flag & ARCHIVE_MATCH_OLDER)
- return (1);
- } else if (f->ctime_nsec < nsec) {
- if (f->flag & ARCHIVE_MATCH_NEWER)
- return (1);
- } else if (f->flag & ARCHIVE_MATCH_EQUAL)
- return (1);
- }
- }
- if (f->flag & ARCHIVE_MATCH_MTIME) {
- sec = archive_entry_mtime(entry);
- if (f->mtime_sec > sec) {
- if (f->flag & ARCHIVE_MATCH_OLDER)
- return (1);
- } else if (f->mtime_sec < sec) {
- if (f->flag & ARCHIVE_MATCH_NEWER)
- return (1);
- } else {
- nsec = archive_entry_mtime_nsec(entry);
- if (f->mtime_nsec > nsec) {
- if (f->flag & ARCHIVE_MATCH_OLDER)
- return (1);
- } else if (f->mtime_nsec < nsec) {
- if (f->flag & ARCHIVE_MATCH_NEWER)
- return (1);
- } else if (f->flag & ARCHIVE_MATCH_EQUAL)
- return (1);
- }
- }
- return (0);
-}
-
-/*
- * Utility functions to manage inclusion owners
- */
-
-int
-archive_match_include_uid(struct archive *_a, la_int64_t uid)
-{
- struct archive_match *a;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_include_uid");
- a = (struct archive_match *)_a;
- return (add_owner_id(a, &(a->inclusion_uids), uid));
-}
-
-int
-archive_match_include_gid(struct archive *_a, la_int64_t gid)
-{
- struct archive_match *a;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_include_gid");
- a = (struct archive_match *)_a;
- return (add_owner_id(a, &(a->inclusion_gids), gid));
-}
-
-int
-archive_match_include_uname(struct archive *_a, const char *uname)
-{
- struct archive_match *a;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_include_uname");
- a = (struct archive_match *)_a;
- return (add_owner_name(a, &(a->inclusion_unames), 1, uname));
-}
-
-int
-archive_match_include_uname_w(struct archive *_a, const wchar_t *uname)
-{
- struct archive_match *a;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_include_uname_w");
- a = (struct archive_match *)_a;
- return (add_owner_name(a, &(a->inclusion_unames), 0, uname));
-}
-
-int
-archive_match_include_gname(struct archive *_a, const char *gname)
-{
- struct archive_match *a;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_include_gname");
- a = (struct archive_match *)_a;
- return (add_owner_name(a, &(a->inclusion_gnames), 1, gname));
-}
-
-int
-archive_match_include_gname_w(struct archive *_a, const wchar_t *gname)
-{
- struct archive_match *a;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_include_gname_w");
- a = (struct archive_match *)_a;
- return (add_owner_name(a, &(a->inclusion_gnames), 0, gname));
-}
-
-/*
- * Test function for owner(uid, gid, uname, gname).
- *
- * Returns 1 if archive entry is excluded.
- * Returns 0 if archive entry is not excluded.
- * Returns <0 if something error happened.
- */
-int
-archive_match_owner_excluded(struct archive *_a,
- struct archive_entry *entry)
-{
- struct archive_match *a;
-
- archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
- ARCHIVE_STATE_NEW, "archive_match_id_excluded_ae");
-
- a = (struct archive_match *)_a;
- if (entry == NULL) {
- archive_set_error(&(a->archive), EINVAL, "entry is NULL");
- return (ARCHIVE_FAILED);
- }
-
- /* If we don't have inclusion id set at all, the entry is always
- * not excluded. */
- if ((a->setflag & ID_IS_SET) == 0)
- return (0);
- return (owner_excluded(a, entry));
-}
-
-static int
-add_owner_id(struct archive_match *a, struct id_array *ids, int64_t id)
-{
- unsigned i;
-
- if (ids->count + 1 >= ids->size) {
- void *p;
-
- if (ids->size == 0)
- ids->size = 8;
- else
- ids->size *= 2;
- p = realloc(ids->ids, sizeof(*ids->ids) * ids->size);
- if (p == NULL)
- return (error_nomem(a));
- ids->ids = (int64_t *)p;
- }
-
- /* Find an insert point. */
- for (i = 0; i < ids->count; i++) {
- if (ids->ids[i] >= id)
- break;
- }
-
- /* Add owner id. */
- if (i == ids->count)
- ids->ids[ids->count++] = id;
- else if (ids->ids[i] != id) {
- memmove(&(ids->ids[i+1]), &(ids->ids[i]),
- (ids->count - i) * sizeof(ids->ids[0]));
- ids->ids[i] = id;
- ids->count++;
- }
- a->setflag |= ID_IS_SET;
- return (ARCHIVE_OK);
-}
-
-static int
-match_owner_id(struct id_array *ids, int64_t id)
-{
- unsigned b, m, t;
-
- t = 0;
- b = (unsigned)ids->count;
- while (t < b) {
- m = (t + b)>>1;
- if (ids->ids[m] == id)
- return (1);
- if (ids->ids[m] < id)
- t = m + 1;
- else
- b = m;
- }
- return (0);
-}
-
-static int
-add_owner_name(struct archive_match *a, struct match_list *list,
- int mbs, const void *name)
-{
- struct match *match;
-
- match = calloc(1, sizeof(*match));
- if (match == NULL)
- return (error_nomem(a));
- if (mbs)
- archive_mstring_copy_mbs(&(match->pattern), name);
- else
- archive_mstring_copy_wcs(&(match->pattern), name);
- match_list_add(list, match);
- a->setflag |= ID_IS_SET;
- return (ARCHIVE_OK);
-}
-
-#if !defined(_WIN32) || defined(__CYGWIN__)
-static int
-match_owner_name_mbs(struct archive_match *a, struct match_list *list,
- const char *name)
-{
- struct match *m;
- const char *p;
-
- if (name == NULL || *name == '\0')
- return (0);
- for (m = list->first; m; m = m->next) {
- if (archive_mstring_get_mbs(&(a->archive), &(m->pattern), &p)
- < 0 && errno == ENOMEM)
- return (error_nomem(a));
- if (p != NULL && strcmp(p, name) == 0) {
- m->matches++;
- return (1);
- }
- }
- return (0);
-}
-#else
-static int
-match_owner_name_wcs(struct archive_match *a, struct match_list *list,
- const wchar_t *name)
-{
- struct match *m;
- const wchar_t *p;
-
- if (name == NULL || *name == L'\0')
- return (0);
- for (m = list->first; m; m = m->next) {
- if (archive_mstring_get_wcs(&(a->archive), &(m->pattern), &p)
- < 0 && errno == ENOMEM)
- return (error_nomem(a));
- if (p != NULL && wcscmp(p, name) == 0) {
- m->matches++;
- return (1);
- }
- }
- return (0);
-}
-#endif
-
-/*
- * Test if entry is excluded by uid, gid, uname or gname.
- */
-static int
-owner_excluded(struct archive_match *a, struct archive_entry *entry)
-{
- int r;
-
- if (a->inclusion_uids.count) {
- if (!match_owner_id(&(a->inclusion_uids),
- archive_entry_uid(entry)))
- return (1);
- }
-
- if (a->inclusion_gids.count) {
- if (!match_owner_id(&(a->inclusion_gids),
- archive_entry_gid(entry)))
- return (1);
- }
-
- if (a->inclusion_unames.count) {
-#if defined(_WIN32) && !defined(__CYGWIN__)
- r = match_owner_name_wcs(a, &(a->inclusion_unames),
- archive_entry_uname_w(entry));
-#else
- r = match_owner_name_mbs(a, &(a->inclusion_unames),
- archive_entry_uname(entry));
-#endif
- if (!r)
- return (1);
- else if (r < 0)
- return (r);
- }
-
- if (a->inclusion_gnames.count) {
-#if defined(_WIN32) && !defined(__CYGWIN__)
- r = match_owner_name_wcs(a, &(a->inclusion_gnames),
- archive_entry_gname_w(entry));
-#else
- r = match_owner_name_mbs(a, &(a->inclusion_gnames),
- archive_entry_gname(entry));
-#endif
- if (!r)
- return (1);
- else if (r < 0)
- return (r);
- }
- return (0);
-}
-
diff --git a/contrib/libs/libarchive/libarchive/archive_openssl_evp_private.h b/contrib/libs/libarchive/libarchive/archive_openssl_evp_private.h
deleted file mode 100644
index 8ac4772808..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_openssl_evp_private.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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.
- */
-
-#ifndef ARCHIVE_OPENSSL_EVP_PRIVATE_H_INCLUDED
-#define ARCHIVE_OPENSSL_EVP_PRIVATE_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
-#include <openssl/evp.h>
-#include <openssl/opensslv.h>
-
-#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
- (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
-#include <stdlib.h> /* malloc, free */
-#include <string.h> /* memset */
-static inline EVP_MD_CTX *EVP_MD_CTX_new(void)
-{
- EVP_MD_CTX *ctx = (EVP_MD_CTX *)calloc(1, sizeof(EVP_MD_CTX));
- return ctx;
-}
-
-static inline void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
-{
- EVP_MD_CTX_cleanup(ctx);
- memset(ctx, 0, sizeof(*ctx));
- free(ctx);
-}
-#endif
-
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_openssl_hmac_private.h b/contrib/libs/libarchive/libarchive/archive_openssl_hmac_private.h
deleted file mode 100644
index 25c8dda654..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_openssl_hmac_private.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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.
- */
-
-#ifndef ARCHIVE_OPENSSL_HMAC_PRIVATE_H_INCLUDED
-#define ARCHIVE_OPENSSL_HMAC_PRIVATE_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
-#include <openssl/hmac.h>
-#include <openssl/opensslv.h>
-
-#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
- (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)
-#include <stdlib.h> /* malloc, free */
-#include <string.h> /* memset */
-static inline HMAC_CTX *HMAC_CTX_new(void)
-{
- HMAC_CTX *ctx = (HMAC_CTX *)calloc(1, sizeof(HMAC_CTX));
- return ctx;
-}
-
-static inline void HMAC_CTX_free(HMAC_CTX *ctx)
-{
- HMAC_CTX_cleanup(ctx);
- memset(ctx, 0, sizeof(*ctx));
- free(ctx);
-}
-#endif
-
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_options.c b/contrib/libs/libarchive/libarchive/archive_options.c
deleted file mode 100644
index 6496025a5f..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_options.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/*-
- * Copyright (c) 2011 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
-#include "archive_options_private.h"
-
-static const char *
-parse_option(const char **str,
- const char **mod, const char **opt, const char **val);
-
-int
-_archive_set_option(struct archive *a,
- const char *m, const char *o, const char *v,
- int magic, const char *fn, option_handler use_option)
-{
- const char *mp, *op, *vp;
- int r;
-
- archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
-
- mp = (m != NULL && m[0] != '\0') ? m : NULL;
- op = (o != NULL && o[0] != '\0') ? o : NULL;
- vp = (v != NULL && v[0] != '\0') ? v : NULL;
-
- if (op == NULL && vp == NULL)
- return (ARCHIVE_OK);
- if (op == NULL) {
- archive_set_error(a, ARCHIVE_ERRNO_MISC, "Empty option");
- return (ARCHIVE_FAILED);
- }
-
- r = use_option(a, mp, op, vp);
- if (r == ARCHIVE_WARN - 1) {
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Unknown module name: `%s'", mp);
- return (ARCHIVE_FAILED);
- }
- if (r == ARCHIVE_WARN) {
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Undefined option: `%s%s%s%s%s%s'",
- vp?"":"!", mp?mp:"", mp?":":"", op, vp?"=":"", vp?vp:"");
- return (ARCHIVE_FAILED);
- }
- return (r);
-}
-
-int
-_archive_set_either_option(struct archive *a, const char *m, const char *o, const char *v,
- option_handler use_format_option, option_handler use_filter_option)
-{
- int r1, r2;
-
- if (o == NULL && v == NULL)
- return (ARCHIVE_OK);
- if (o == NULL)
- return (ARCHIVE_FAILED);
-
- r1 = use_format_option(a, m, o, v);
- if (r1 == ARCHIVE_FATAL)
- return (ARCHIVE_FATAL);
-
- r2 = use_filter_option(a, m, o, v);
- if (r2 == ARCHIVE_FATAL)
- return (ARCHIVE_FATAL);
-
- if (r2 == ARCHIVE_WARN - 1)
- return r1;
- return r1 > r2 ? r1 : r2;
-}
-
-int
-_archive_set_options(struct archive *a, const char *options,
- int magic, const char *fn, option_handler use_option)
-{
- int allok = 1, anyok = 0, ignore_mod_err = 0, r;
- char *data;
- const char *s, *mod, *opt, *val;
-
- archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
-
- if (options == NULL || options[0] == '\0')
- return ARCHIVE_OK;
-
- if ((data = strdup(options)) == NULL) {
- archive_set_error(a,
- ENOMEM, "Out of memory adding file to list");
- return (ARCHIVE_FATAL);
- }
- s = (const char *)data;
-
- do {
- mod = opt = val = NULL;
-
- parse_option(&s, &mod, &opt, &val);
- if (mod == NULL && opt != NULL &&
- strcmp("__ignore_wrong_module_name__", opt) == 0) {
- /* Ignore module name error */
- if (val != NULL) {
- ignore_mod_err = 1;
- anyok = 1;
- }
- continue;
- }
-
- r = use_option(a, mod, opt, val);
- if (r == ARCHIVE_FATAL) {
- free(data);
- return (ARCHIVE_FATAL);
- }
- if (r == ARCHIVE_FAILED && mod != NULL) {
- free(data);
- return (ARCHIVE_FAILED);
- }
- if (r == ARCHIVE_WARN - 1) {
- if (ignore_mod_err)
- continue;
- /* The module name is wrong. */
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Unknown module name: `%s'", mod);
- free(data);
- return (ARCHIVE_FAILED);
- }
- if (r == ARCHIVE_WARN) {
- /* The option name is wrong. No-one used this. */
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Undefined option: `%s%s%s'",
- mod?mod:"", mod?":":"", opt);
- free(data);
- return (ARCHIVE_FAILED);
- }
- if (r == ARCHIVE_OK)
- anyok = 1;
- else
- allok = 0;
- } while (s != NULL);
-
- free(data);
- return allok ? ARCHIVE_OK : anyok ? ARCHIVE_WARN : ARCHIVE_FAILED;
-}
-
-static const char *
-parse_option(const char **s, const char **m, const char **o, const char **v)
-{
- const char *end, *mod, *opt, *val;
- char *p;
-
- end = NULL;
- mod = NULL;
- opt = *s;
- val = "1";
-
- p = strchr(opt, ',');
-
- if (p != NULL) {
- *p = '\0';
- end = ((const char *)p) + 1;
- }
-
- if (0 == strlen(opt)) {
- *s = end;
- *m = NULL;
- *o = NULL;
- *v = NULL;
- return end;
- }
-
- p = strchr(opt, ':');
- if (p != NULL) {
- *p = '\0';
- mod = opt;
- opt = ++p;
- }
-
- p = strchr(opt, '=');
- if (p != NULL) {
- *p = '\0';
- val = ++p;
- } else if (opt[0] == '!') {
- ++opt;
- val = NULL;
- }
-
- *s = end;
- *m = mod;
- *o = opt;
- *v = val;
-
- return end;
-}
-
diff --git a/contrib/libs/libarchive/libarchive/archive_options_private.h b/contrib/libs/libarchive/libarchive/archive_options_private.h
deleted file mode 100644
index 9a7f8080d2..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_options_private.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*-
- * Copyright (c) 2011 Tim Kientzle
- * 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(S) ``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(S) 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.
- */
-
-#ifndef ARCHIVE_OPTIONS_PRIVATE_H_INCLUDED
-#define ARCHIVE_OPTIONS_PRIVATE_H_INCLUDED
-
-#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#include "archive_private.h"
-
-typedef int (*option_handler)(struct archive *a,
- const char *mod, const char *opt, const char *val);
-
-int
-_archive_set_option(struct archive *a,
- const char *mod, const char *opt, const char *val,
- int magic, const char *fn, option_handler use_option);
-
-int
-_archive_set_options(struct archive *a, const char *options,
- int magic, const char *fn, option_handler use_option);
-
-int
-_archive_set_either_option(struct archive *a,
- const char *m, const char *o, const char *v,
- option_handler use_format_option, option_handler use_filter_option);
-
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_pack_dev.c b/contrib/libs/libarchive/libarchive/archive_pack_dev.c
deleted file mode 100644
index 23dc934bc7..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_pack_dev.c
+++ /dev/null
@@ -1,337 +0,0 @@
-/* $NetBSD: pack_dev.c,v 1.12 2013/06/14 16:28:20 tsutsui Exp $ */
-
-/*-
- * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Charles M. Hannum.
- *
- * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
- */
-
-/* Originally from NetBSD's mknod(8) source. */
-
-#include "archive_platform.h"
-
-#if HAVE_SYS_CDEFS_H
-#include <sys/cdefs.h>
-#endif
-#if !defined(lint)
-__RCSID("$NetBSD$");
-#endif /* not lint */
-
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#if MAJOR_IN_MKDEV
-#include <sys/mkdev.h>
-#define HAVE_MAJOR
-#elif MAJOR_IN_SYSMACROS
-#include <sys/sysmacros.h>
-#define HAVE_MAJOR
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "archive_pack_dev.h"
-
-static pack_t pack_netbsd;
-static pack_t pack_freebsd;
-static pack_t pack_8_8;
-static pack_t pack_12_20;
-static pack_t pack_14_18;
-static pack_t pack_8_24;
-static pack_t pack_bsdos;
-static int __LA_LIBC_CC compare_format(const void *, const void *);
-
-static const char iMajorError[] = "invalid major number";
-static const char iMinorError[] = "invalid minor number";
-static const char tooManyFields[] = "too many fields for format";
-
-/* This is blatantly stolen from libarchive/archive_entry.c,
- * in an attempt to get this to play nice on MinGW... */
-#if !defined(HAVE_MAJOR) && !defined(major)
-/* Replacement for major/minor/makedev. */
-#define major(x) ((int)(0x00ff & ((x) >> 8)))
-#define minor(x) ((int)(0xffff00ff & (x)))
-#define makedev(maj,min) ((0xff00 & ((maj)<<8)) | (0xffff00ff & (min)))
-#endif
-
-/* Play games to come up with a suitable makedev() definition. */
-#ifdef __QNXNTO__
-/* QNX. <sigh> */
-#error #include <sys/netmgr.h>
-#define apd_makedev(maj, min) makedev(ND_LOCAL_NODE, (maj), (min))
-#elif defined makedev
-/* There's a "makedev" macro. */
-#define apd_makedev(maj, min) makedev((maj), (min))
-#elif defined mkdev || ((defined _WIN32 || defined __WIN32__) && !defined(__CYGWIN__))
-/* Windows. <sigh> */
-#define apd_makedev(maj, min) mkdev((maj), (min))
-#else
-/* There's a "makedev" function. */
-#define apd_makedev(maj, min) makedev((maj), (min))
-#endif
-
-/* exported */
-dev_t
-pack_native(int n, unsigned long numbers[], const char **error)
-{
- dev_t dev = 0;
-
- if (n == 2) {
- dev = apd_makedev(numbers[0], numbers[1]);
- if ((unsigned long)major(dev) != numbers[0])
- *error = iMajorError;
- else if ((unsigned long)minor(dev) != numbers[1])
- *error = iMinorError;
- } else
- *error = tooManyFields;
- return (dev);
-}
-
-
-static dev_t
-pack_netbsd(int n, unsigned long numbers[], const char **error)
-{
- dev_t dev = 0;
-
- if (n == 2) {
- dev = makedev_netbsd(numbers[0], numbers[1]);
- if ((unsigned long)major_netbsd(dev) != numbers[0])
- *error = iMajorError;
- else if ((unsigned long)minor_netbsd(dev) != numbers[1])
- *error = iMinorError;
- } else
- *error = tooManyFields;
- return (dev);
-}
-
-
-#define major_freebsd(x) ((int32_t)(((x) & 0x0000ff00) >> 8))
-#define minor_freebsd(x) ((int32_t)(((x) & 0xffff00ff) >> 0))
-#define makedev_freebsd(x,y) ((dev_t)((((x) << 8) & 0x0000ff00) | \
- (((y) << 0) & 0xffff00ff)))
-
-static dev_t
-pack_freebsd(int n, unsigned long numbers[], const char **error)
-{
- dev_t dev = 0;
-
- if (n == 2) {
- dev = makedev_freebsd(numbers[0], numbers[1]);
- if ((unsigned long)major_freebsd(dev) != numbers[0])
- *error = iMajorError;
- if ((unsigned long)minor_freebsd(dev) != numbers[1])
- *error = iMinorError;
- } else
- *error = tooManyFields;
- return (dev);
-}
-
-
-#define major_8_8(x) ((int32_t)(((x) & 0x0000ff00) >> 8))
-#define minor_8_8(x) ((int32_t)(((x) & 0x000000ff) >> 0))
-#define makedev_8_8(x,y) ((dev_t)((((x) << 8) & 0x0000ff00) | \
- (((y) << 0) & 0x000000ff)))
-
-static dev_t
-pack_8_8(int n, unsigned long numbers[], const char **error)
-{
- dev_t dev = 0;
-
- if (n == 2) {
- dev = makedev_8_8(numbers[0], numbers[1]);
- if ((unsigned long)major_8_8(dev) != numbers[0])
- *error = iMajorError;
- if ((unsigned long)minor_8_8(dev) != numbers[1])
- *error = iMinorError;
- } else
- *error = tooManyFields;
- return (dev);
-}
-
-
-#define major_12_20(x) ((int32_t)(((x) & 0xfff00000) >> 20))
-#define minor_12_20(x) ((int32_t)(((x) & 0x000fffff) >> 0))
-#define makedev_12_20(x,y) ((dev_t)((((x) << 20) & 0xfff00000) | \
- (((y) << 0) & 0x000fffff)))
-
-static dev_t
-pack_12_20(int n, unsigned long numbers[], const char **error)
-{
- dev_t dev = 0;
-
- if (n == 2) {
- dev = makedev_12_20(numbers[0], numbers[1]);
- if ((unsigned long)major_12_20(dev) != numbers[0])
- *error = iMajorError;
- if ((unsigned long)minor_12_20(dev) != numbers[1])
- *error = iMinorError;
- } else
- *error = tooManyFields;
- return (dev);
-}
-
-
-#define major_14_18(x) ((int32_t)(((x) & 0xfffc0000) >> 18))
-#define minor_14_18(x) ((int32_t)(((x) & 0x0003ffff) >> 0))
-#define makedev_14_18(x,y) ((dev_t)((((x) << 18) & 0xfffc0000) | \
- (((y) << 0) & 0x0003ffff)))
-
-static dev_t
-pack_14_18(int n, unsigned long numbers[], const char **error)
-{
- dev_t dev = 0;
-
- if (n == 2) {
- dev = makedev_14_18(numbers[0], numbers[1]);
- if ((unsigned long)major_14_18(dev) != numbers[0])
- *error = iMajorError;
- if ((unsigned long)minor_14_18(dev) != numbers[1])
- *error = iMinorError;
- } else
- *error = tooManyFields;
- return (dev);
-}
-
-
-#define major_8_24(x) ((int32_t)(((x) & 0xff000000) >> 24))
-#define minor_8_24(x) ((int32_t)(((x) & 0x00ffffff) >> 0))
-#define makedev_8_24(x,y) ((dev_t)((((x) << 24) & 0xff000000) | \
- (((y) << 0) & 0x00ffffff)))
-
-static dev_t
-pack_8_24(int n, unsigned long numbers[], const char **error)
-{
- dev_t dev = 0;
-
- if (n == 2) {
- dev = makedev_8_24(numbers[0], numbers[1]);
- if ((unsigned long)major_8_24(dev) != numbers[0])
- *error = iMajorError;
- if ((unsigned long)minor_8_24(dev) != numbers[1])
- *error = iMinorError;
- } else
- *error = tooManyFields;
- return (dev);
-}
-
-
-#define major_12_12_8(x) ((int32_t)(((x) & 0xfff00000) >> 20))
-#define unit_12_12_8(x) ((int32_t)(((x) & 0x000fff00) >> 8))
-#define subunit_12_12_8(x) ((int32_t)(((x) & 0x000000ff) >> 0))
-#define makedev_12_12_8(x,y,z) ((dev_t)((((x) << 20) & 0xfff00000) | \
- (((y) << 8) & 0x000fff00) | \
- (((z) << 0) & 0x000000ff)))
-
-static dev_t
-pack_bsdos(int n, unsigned long numbers[], const char **error)
-{
- dev_t dev = 0;
-
- if (n == 2) {
- dev = makedev_12_20(numbers[0], numbers[1]);
- if ((unsigned long)major_12_20(dev) != numbers[0])
- *error = iMajorError;
- if ((unsigned long)minor_12_20(dev) != numbers[1])
- *error = iMinorError;
- } else if (n == 3) {
- dev = makedev_12_12_8(numbers[0], numbers[1], numbers[2]);
- if ((unsigned long)major_12_12_8(dev) != numbers[0])
- *error = iMajorError;
- if ((unsigned long)unit_12_12_8(dev) != numbers[1])
- *error = "invalid unit number";
- if ((unsigned long)subunit_12_12_8(dev) != numbers[2])
- *error = "invalid subunit number";
- } else
- *error = tooManyFields;
- return (dev);
-}
-
-
- /* list of formats and pack functions */
- /* this list must be sorted lexically */
-static const struct format {
- const char *name;
- pack_t *pack;
-} formats[] = {
- {"386bsd", pack_8_8},
- {"4bsd", pack_8_8},
- {"bsdos", pack_bsdos},
- {"freebsd", pack_freebsd},
- {"hpux", pack_8_24},
- {"isc", pack_8_8},
- {"linux", pack_8_8},
- {"native", pack_native},
- {"netbsd", pack_netbsd},
- {"osf1", pack_12_20},
- {"sco", pack_8_8},
- {"solaris", pack_14_18},
- {"sunos", pack_8_8},
- {"svr3", pack_8_8},
- {"svr4", pack_14_18},
- {"ultrix", pack_8_8},
-};
-
-static int
-__LA_LIBC_CC
-compare_format(const void *key, const void *element)
-{
- const char *name;
- const struct format *format;
-
- name = key;
- format = element;
-
- return (strcmp(name, format->name));
-}
-
-
-pack_t *
-pack_find(const char *name)
-{
- struct format *format;
-
- format = bsearch(name, formats,
- sizeof(formats)/sizeof(formats[0]),
- sizeof(formats[0]), compare_format);
- if (format == 0)
- return (NULL);
- return (format->pack);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_pack_dev.h b/contrib/libs/libarchive/libarchive/archive_pack_dev.h
deleted file mode 100644
index eaf23e3883..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_pack_dev.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* $NetBSD: pack_dev.h,v 1.8 2013/06/14 16:28:20 tsutsui Exp $ */
-
-/*-
- * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Charles M. Hannum.
- *
- * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
- */
-
-/* Originally from NetBSD's mknod(8) source. */
-
-#ifndef ARCHIVE_PACK_DEV_H
-#define ARCHIVE_PACK_DEV_H
-
-typedef dev_t pack_t(int, unsigned long [], const char **);
-
-pack_t *pack_find(const char *);
-pack_t pack_native;
-
-#define major_netbsd(x) ((int32_t)((((x) & 0x000fff00) >> 8)))
-#define minor_netbsd(x) ((int32_t)((((x) & 0xfff00000) >> 12) | \
- (((x) & 0x000000ff) >> 0)))
-#define makedev_netbsd(x,y) ((dev_t)((((x) << 8) & 0x000fff00) | \
- (((y) << 12) & 0xfff00000) | \
- (((y) << 0) & 0x000000ff)))
-
-#endif /* ARCHIVE_PACK_DEV_H */
diff --git a/contrib/libs/libarchive/libarchive/archive_pathmatch.c b/contrib/libs/libarchive/libarchive/archive_pathmatch.c
deleted file mode 100644
index 0867a268ee..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_pathmatch.c
+++ /dev/null
@@ -1,463 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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
- * in this position and unchanged.
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_WCHAR_H
-#include <wchar.h>
-#endif
-
-#include "archive_pathmatch.h"
-
-/*
- * Check whether a character 'c' is matched by a list specification [...]:
- * * Leading '!' or '^' negates the class.
- * * <char>-<char> is a range of characters
- * * \<char> removes any special meaning for <char>
- *
- * Some interesting boundary cases:
- * a-d-e is one range (a-d) followed by two single characters - and e.
- * \a-\d is same as a-d
- * a\-d is three single characters: a, d, -
- * Trailing - is not special (so [a-] is two characters a and -).
- * Initial - is not special ([a-] is same as [-a] is same as [\\-a])
- * This function never sees a trailing \.
- * [] always fails
- * [!] always succeeds
- */
-static int
-pm_list(const char *start, const char *end, const char c, int flags)
-{
- const char *p = start;
- char rangeStart = '\0', nextRangeStart;
- int match = 1, nomatch = 0;
-
- /* This will be used soon... */
- (void)flags; /* UNUSED */
-
- /* If this is a negated class, return success for nomatch. */
- if ((*p == '!' || *p == '^') && p < end) {
- match = 0;
- nomatch = 1;
- ++p;
- }
-
- while (p < end) {
- nextRangeStart = '\0';
- switch (*p) {
- case '-':
- /* Trailing or initial '-' is not special. */
- if ((rangeStart == '\0') || (p == end - 1)) {
- if (*p == c)
- return (match);
- } else {
- char rangeEnd = *++p;
- if (rangeEnd == '\\')
- rangeEnd = *++p;
- if ((rangeStart <= c) && (c <= rangeEnd))
- return (match);
- }
- break;
- case '\\':
- ++p;
- /* Fall through */
- default:
- if (*p == c)
- return (match);
- nextRangeStart = *p; /* Possible start of range. */
- }
- rangeStart = nextRangeStart;
- ++p;
- }
- return (nomatch);
-}
-
-static int
-pm_list_w(const wchar_t *start, const wchar_t *end, const wchar_t c, int flags)
-{
- const wchar_t *p = start;
- wchar_t rangeStart = L'\0', nextRangeStart;
- int match = 1, nomatch = 0;
-
- /* This will be used soon... */
- (void)flags; /* UNUSED */
-
- /* If this is a negated class, return success for nomatch. */
- if ((*p == L'!' || *p == L'^') && p < end) {
- match = 0;
- nomatch = 1;
- ++p;
- }
-
- while (p < end) {
- nextRangeStart = L'\0';
- switch (*p) {
- case L'-':
- /* Trailing or initial '-' is not special. */
- if ((rangeStart == L'\0') || (p == end - 1)) {
- if (*p == c)
- return (match);
- } else {
- wchar_t rangeEnd = *++p;
- if (rangeEnd == L'\\')
- rangeEnd = *++p;
- if ((rangeStart <= c) && (c <= rangeEnd))
- return (match);
- }
- break;
- case L'\\':
- ++p;
- /* Fall through */
- default:
- if (*p == c)
- return (match);
- nextRangeStart = *p; /* Possible start of range. */
- }
- rangeStart = nextRangeStart;
- ++p;
- }
- return (nomatch);
-}
-
-/*
- * If s is pointing to "./", ".//", "./././" or the like, skip it.
- */
-static const char *
-pm_slashskip(const char *s) {
- while ((*s == '/')
- || (s[0] == '.' && s[1] == '/')
- || (s[0] == '.' && s[1] == '\0'))
- ++s;
- return (s);
-}
-
-static const wchar_t *
-pm_slashskip_w(const wchar_t *s) {
- while ((*s == L'/')
- || (s[0] == L'.' && s[1] == L'/')
- || (s[0] == L'.' && s[1] == L'\0'))
- ++s;
- return (s);
-}
-
-static int
-pm(const char *p, const char *s, int flags)
-{
- const char *end;
-
- /*
- * Ignore leading './', './/', '././', etc.
- */
- if (s[0] == '.' && s[1] == '/')
- s = pm_slashskip(s + 1);
- if (p[0] == '.' && p[1] == '/')
- p = pm_slashskip(p + 1);
-
- for (;;) {
- switch (*p) {
- case '\0':
- if (s[0] == '/') {
- if (flags & PATHMATCH_NO_ANCHOR_END)
- return (1);
- /* "dir" == "dir/" == "dir/." */
- s = pm_slashskip(s);
- }
- return (*s == '\0');
- case '?':
- /* ? always succeeds, unless we hit end of 's' */
- if (*s == '\0')
- return (0);
- break;
- case '*':
- /* "*" == "**" == "***" ... */
- while (*p == '*')
- ++p;
- /* Trailing '*' always succeeds. */
- if (*p == '\0')
- return (1);
- while (*s) {
- if (archive_pathmatch(p, s, flags))
- return (1);
- ++s;
- }
- return (0);
- case '[':
- /*
- * Find the end of the [...] character class,
- * ignoring \] that might occur within the class.
- */
- end = p + 1;
- while (*end != '\0' && *end != ']') {
- if (*end == '\\' && end[1] != '\0')
- ++end;
- ++end;
- }
- if (*end == ']') {
- /* We found [...], try to match it. */
- if (!pm_list(p + 1, end, *s, flags))
- return (0);
- p = end; /* Jump to trailing ']' char. */
- break;
- } else
- /* No final ']', so just match '['. */
- if (*p != *s)
- return (0);
- break;
- case '\\':
- /* Trailing '\\' matches itself. */
- if (p[1] == '\0') {
- if (*s != '\\')
- return (0);
- } else {
- ++p;
- if (*p != *s)
- return (0);
- }
- break;
- case '/':
- if (*s != '/' && *s != '\0')
- return (0);
- /* Note: pattern "/\./" won't match "/";
- * pm_slashskip() correctly stops at backslash. */
- p = pm_slashskip(p);
- s = pm_slashskip(s);
- if (*p == '\0' && (flags & PATHMATCH_NO_ANCHOR_END))
- return (1);
- --p; /* Counteract the increment below. */
- --s;
- break;
- case '$':
- /* '$' is special only at end of pattern and only
- * if PATHMATCH_NO_ANCHOR_END is specified. */
- if (p[1] == '\0' && (flags & PATHMATCH_NO_ANCHOR_END)){
- /* "dir" == "dir/" == "dir/." */
- return (*pm_slashskip(s) == '\0');
- }
- /* Otherwise, '$' is not special. */
- /* FALL THROUGH */
- default:
- if (*p != *s)
- return (0);
- break;
- }
- ++p;
- ++s;
- }
-}
-
-static int
-pm_w(const wchar_t *p, const wchar_t *s, int flags)
-{
- const wchar_t *end;
-
- /*
- * Ignore leading './', './/', '././', etc.
- */
- if (s[0] == L'.' && s[1] == L'/')
- s = pm_slashskip_w(s + 1);
- if (p[0] == L'.' && p[1] == L'/')
- p = pm_slashskip_w(p + 1);
-
- for (;;) {
- switch (*p) {
- case L'\0':
- if (s[0] == L'/') {
- if (flags & PATHMATCH_NO_ANCHOR_END)
- return (1);
- /* "dir" == "dir/" == "dir/." */
- s = pm_slashskip_w(s);
- }
- return (*s == L'\0');
- case L'?':
- /* ? always succeeds, unless we hit end of 's' */
- if (*s == L'\0')
- return (0);
- break;
- case L'*':
- /* "*" == "**" == "***" ... */
- while (*p == L'*')
- ++p;
- /* Trailing '*' always succeeds. */
- if (*p == L'\0')
- return (1);
- while (*s) {
- if (archive_pathmatch_w(p, s, flags))
- return (1);
- ++s;
- }
- return (0);
- case L'[':
- /*
- * Find the end of the [...] character class,
- * ignoring \] that might occur within the class.
- */
- end = p + 1;
- while (*end != L'\0' && *end != L']') {
- if (*end == L'\\' && end[1] != L'\0')
- ++end;
- ++end;
- }
- if (*end == L']') {
- /* We found [...], try to match it. */
- if (!pm_list_w(p + 1, end, *s, flags))
- return (0);
- p = end; /* Jump to trailing ']' char. */
- break;
- } else
- /* No final ']', so just match '['. */
- if (*p != *s)
- return (0);
- break;
- case L'\\':
- /* Trailing '\\' matches itself. */
- if (p[1] == L'\0') {
- if (*s != L'\\')
- return (0);
- } else {
- ++p;
- if (*p != *s)
- return (0);
- }
- break;
- case L'/':
- if (*s != L'/' && *s != L'\0')
- return (0);
- /* Note: pattern "/\./" won't match "/";
- * pm_slashskip() correctly stops at backslash. */
- p = pm_slashskip_w(p);
- s = pm_slashskip_w(s);
- if (*p == L'\0' && (flags & PATHMATCH_NO_ANCHOR_END))
- return (1);
- --p; /* Counteract the increment below. */
- --s;
- break;
- case L'$':
- /* '$' is special only at end of pattern and only
- * if PATHMATCH_NO_ANCHOR_END is specified. */
- if (p[1] == L'\0' && (flags & PATHMATCH_NO_ANCHOR_END)){
- /* "dir" == "dir/" == "dir/." */
- return (*pm_slashskip_w(s) == L'\0');
- }
- /* Otherwise, '$' is not special. */
- /* FALL THROUGH */
- default:
- if (*p != *s)
- return (0);
- break;
- }
- ++p;
- ++s;
- }
-}
-
-/* Main entry point. */
-int
-__archive_pathmatch(const char *p, const char *s, int flags)
-{
- /* Empty pattern only matches the empty string. */
- if (p == NULL || *p == '\0')
- return (s == NULL || *s == '\0');
- else if (s == NULL)
- return (0);
-
- /* Leading '^' anchors the start of the pattern. */
- if (*p == '^') {
- ++p;
- flags &= ~PATHMATCH_NO_ANCHOR_START;
- }
-
- if (*p == '/' && *s != '/')
- return (0);
-
- /* Certain patterns anchor implicitly. */
- if (*p == '*' || *p == '/') {
- while (*p == '/')
- ++p;
- while (*s == '/')
- ++s;
- return (pm(p, s, flags));
- }
-
- /* If start is unanchored, try to match start of each path element. */
- if (flags & PATHMATCH_NO_ANCHOR_START) {
- for ( ; s != NULL; s = strchr(s, '/')) {
- if (*s == '/')
- s++;
- if (pm(p, s, flags))
- return (1);
- }
- return (0);
- }
-
- /* Default: Match from beginning. */
- return (pm(p, s, flags));
-}
-
-int
-__archive_pathmatch_w(const wchar_t *p, const wchar_t *s, int flags)
-{
- /* Empty pattern only matches the empty string. */
- if (p == NULL || *p == L'\0')
- return (s == NULL || *s == L'\0');
- else if (s == NULL)
- return (0);
-
- /* Leading '^' anchors the start of the pattern. */
- if (*p == L'^') {
- ++p;
- flags &= ~PATHMATCH_NO_ANCHOR_START;
- }
-
- if (*p == L'/' && *s != L'/')
- return (0);
-
- /* Certain patterns anchor implicitly. */
- if (*p == L'*' || *p == L'/') {
- while (*p == L'/')
- ++p;
- while (*s == L'/')
- ++s;
- return (pm_w(p, s, flags));
- }
-
- /* If start is unanchored, try to match start of each path element. */
- if (flags & PATHMATCH_NO_ANCHOR_START) {
- for ( ; s != NULL; s = wcschr(s, L'/')) {
- if (*s == L'/')
- s++;
- if (pm_w(p, s, flags))
- return (1);
- }
- return (0);
- }
-
- /* Default: Match from beginning. */
- return (pm_w(p, s, flags));
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_pathmatch.h b/contrib/libs/libarchive/libarchive/archive_pathmatch.h
deleted file mode 100644
index 9995142921..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_pathmatch.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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
- * in this position and unchanged.
- * 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(S) ``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(S) 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.
- *
- * $FreeBSD$
- */
-
-#ifndef ARCHIVE_PATHMATCH_H
-#define ARCHIVE_PATHMATCH_H
-
-#ifndef __LIBARCHIVE_BUILD
-#ifndef __LIBARCHIVE_TEST
-#error This header is only to be used internally to libarchive.
-#endif
-#endif
-
-/* Don't anchor at beginning unless the pattern starts with "^" */
-#define PATHMATCH_NO_ANCHOR_START 1
-/* Don't anchor at end unless the pattern ends with "$" */
-#define PATHMATCH_NO_ANCHOR_END 2
-
-/* Note that "^" and "$" are not special unless you set the corresponding
- * flag above. */
-
-int __archive_pathmatch(const char *p, const char *s, int flags);
-int __archive_pathmatch_w(const wchar_t *p, const wchar_t *s, int flags);
-
-#define archive_pathmatch(p, s, f) __archive_pathmatch(p, s, f)
-#define archive_pathmatch_w(p, s, f) __archive_pathmatch_w(p, s, f)
-
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_platform.h b/contrib/libs/libarchive/libarchive/archive_platform.h
deleted file mode 100644
index 2f13414766..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_platform.h
+++ /dev/null
@@ -1,233 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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.
- *
- * $FreeBSD: head/lib/libarchive/archive_platform.h 201090 2009-12-28 02:22:04Z kientzle $
- */
-
-/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */
-
-/*
- * This header is the first thing included in any of the libarchive
- * source files. As far as possible, platform-specific issues should
- * be dealt with here and not within individual source files. I'm
- * actively trying to minimize #if blocks within the main source,
- * since they obfuscate the code.
- */
-
-#ifndef ARCHIVE_PLATFORM_H_INCLUDED
-#define ARCHIVE_PLATFORM_H_INCLUDED
-
-/* archive.h and archive_entry.h require this. */
-#define __LIBARCHIVE_BUILD 1
-
-#if defined(PLATFORM_CONFIG_H)
-/* Use hand-built config.h in environments that need it. */
-#error #include PLATFORM_CONFIG_H
-#elif defined(HAVE_CONFIG_H)
-/* Most POSIX platforms use the 'configure' script to build config.h */
-#include "config.h"
-#else
-/* Warn if the library hasn't been (automatically or manually) configured. */
-#error Oops: No config.h and no pre-built configuration in archive_platform.h.
-#endif
-
-/* On macOS check for some symbols based on the deployment target version. */
-#if defined(__APPLE__)
-# undef HAVE_FUTIMENS
-# undef HAVE_UTIMENSAT
-# include <AvailabilityMacros.h>
-# if MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
-# define HAVE_FUTIMENS 1
-# define HAVE_UTIMENSAT 1
-# endif
-#endif
-
-/* It should be possible to get rid of this by extending the feature-test
- * macros to cover Windows API functions, probably along with non-trivial
- * refactoring of code to find structures that sit more cleanly on top of
- * either Windows or Posix APIs. */
-#if (defined(__WIN32__) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__)
-#include "archive_windows.h"
-/* The C library on Windows specifies a calling convention for callback
- * functions and exports; when we interact with them (capture pointers,
- * call and pass function pointers) we need to match their calling
- * convention.
- * This only matters when libarchive is built with /Gr, /Gz or /Gv
- * (which change the default calling convention.) */
-#define __LA_LIBC_CC __cdecl
-#else
-#define la_stat(path,stref) stat(path,stref)
-#define __LA_LIBC_CC
-#endif
-
-/*
- * The config files define a lot of feature macros. The following
- * uses those macros to select/define replacements and include key
- * headers as required.
- */
-
-/* Get a real definition for __FBSDID or __RCSID if we can */
-#if HAVE_SYS_CDEFS_H
-#include <sys/cdefs.h>
-#endif
-
-/* If not, define them so as to avoid dangling semicolons. */
-#ifndef __FBSDID
-#define __FBSDID(a) struct _undefined_hack
-#endif
-#ifndef __RCSID
-#define __RCSID(a) struct _undefined_hack
-#endif
-
-/* Try to get standard C99-style integer type definitions. */
-#if HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
-/* Borland warns about its own constants! */
-#if defined(__BORLANDC__)
-# if HAVE_DECL_UINT64_MAX
-# undef UINT64_MAX
-# undef HAVE_DECL_UINT64_MAX
-# endif
-# if HAVE_DECL_UINT64_MIN
-# undef UINT64_MIN
-# undef HAVE_DECL_UINT64_MIN
-# endif
-# if HAVE_DECL_INT64_MAX
-# undef INT64_MAX
-# undef HAVE_DECL_INT64_MAX
-# endif
-# if HAVE_DECL_INT64_MIN
-# undef INT64_MIN
-# undef HAVE_DECL_INT64_MIN
-# endif
-#endif
-
-/* Some platforms lack the standard *_MAX definitions. */
-#if !HAVE_DECL_SIZE_MAX
-#define SIZE_MAX (~(size_t)0)
-#endif
-#if !HAVE_DECL_SSIZE_MAX
-#define SSIZE_MAX ((ssize_t)(SIZE_MAX >> 1))
-#endif
-#if !HAVE_DECL_UINT32_MAX
-#define UINT32_MAX (~(uint32_t)0)
-#endif
-#if !HAVE_DECL_INT32_MAX
-#define INT32_MAX ((int32_t)(UINT32_MAX >> 1))
-#endif
-#if !HAVE_DECL_INT32_MIN
-#define INT32_MIN ((int32_t)(~INT32_MAX))
-#endif
-#if !HAVE_DECL_UINT64_MAX
-#define UINT64_MAX (~(uint64_t)0)
-#endif
-#if !HAVE_DECL_INT64_MAX
-#define INT64_MAX ((int64_t)(UINT64_MAX >> 1))
-#endif
-#if !HAVE_DECL_INT64_MIN
-#define INT64_MIN ((int64_t)(~INT64_MAX))
-#endif
-#if !HAVE_DECL_UINTMAX_MAX
-#define UINTMAX_MAX (~(uintmax_t)0)
-#endif
-#if !HAVE_DECL_INTMAX_MAX
-#define INTMAX_MAX ((intmax_t)(UINTMAX_MAX >> 1))
-#endif
-#if !HAVE_DECL_INTMAX_MIN
-#define INTMAX_MIN ((intmax_t)(~INTMAX_MAX))
-#endif
-
-/* Some platforms lack the standard PRIxN/PRIdN definitions. */
-#if !HAVE_INTTYPES_H || !defined(PRIx32) || !defined(PRId32)
-#ifndef PRIx32
-#if SIZEOF_INT == 4
-#define PRIx32 "x"
-#elif SIZEOF_LONG == 4
-#define PRIx32 "lx"
-#else
-#error No suitable 32-bit unsigned integer type found for this platform
-#endif
-#endif // PRIx32
-#ifndef PRId32
-#if SIZEOF_INT == 4
-#define PRId32 "d"
-#elif SIZEOF_LONG == 4
-#define PRId32 "ld"
-#else
-#error No suitable 32-bit signed integer type found for this platform
-#endif
-#endif // PRId32
-#endif // !HAVE_INTTYPES_H || !defined(PRIx32) || !defined(PRId32)
-
-/*
- * If we can't restore metadata using a file descriptor, then
- * for compatibility's sake, close files before trying to restore metadata.
- */
-#if defined(HAVE_FCHMOD) || defined(HAVE_FUTIMES) || defined(HAVE_ACL_SET_FD) || defined(HAVE_ACL_SET_FD_NP) || defined(HAVE_FCHOWN)
-#define CAN_RESTORE_METADATA_FD
-#endif
-
-/*
- * glibc 2.24 deprecates readdir_r
- * bionic c deprecates readdir_r too
- */
-#if defined(HAVE_READDIR_R) && (!defined(__GLIBC__) || !defined(__GLIBC_MINOR__) || __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 24)) && (!defined(__ANDROID__))
-#define USE_READDIR_R 1
-#else
-#undef USE_READDIR_R
-#endif
-
-/* Set up defaults for internal error codes. */
-#ifndef ARCHIVE_ERRNO_FILE_FORMAT
-#if HAVE_EFTYPE
-#define ARCHIVE_ERRNO_FILE_FORMAT EFTYPE
-#else
-#if HAVE_EILSEQ
-#define ARCHIVE_ERRNO_FILE_FORMAT EILSEQ
-#else
-#define ARCHIVE_ERRNO_FILE_FORMAT EINVAL
-#endif
-#endif
-#endif
-
-#ifndef ARCHIVE_ERRNO_PROGRAMMER
-#define ARCHIVE_ERRNO_PROGRAMMER EINVAL
-#endif
-
-#ifndef ARCHIVE_ERRNO_MISC
-#define ARCHIVE_ERRNO_MISC (-1)
-#endif
-
-#if defined(__GNUC__) && (__GNUC__ >= 7)
-#define __LA_FALLTHROUGH __attribute__((fallthrough))
-#else
-#define __LA_FALLTHROUGH
-#endif
-
-#endif /* !ARCHIVE_PLATFORM_H_INCLUDED */
diff --git a/contrib/libs/libarchive/libarchive/archive_platform_acl.h b/contrib/libs/libarchive/libarchive/archive_platform_acl.h
deleted file mode 100644
index 264e6de375..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_platform_acl.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*-
- * Copyright (c) 2017 Martin Matuska
- * 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(S) ``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(S) 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.
- *
- * $FreeBSD$
- */
-
-/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */
-
-#ifndef ARCHIVE_PLATFORM_ACL_H_INCLUDED
-#define ARCHIVE_PLATFORM_ACL_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#ifndef __LIBARCHIVE_TEST_COMMON
-#error This header is only to be used internally to libarchive.
-#endif
-#endif
-
-/*
- * Determine what ACL types are supported
- */
-#if ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_SUNOS || ARCHIVE_ACL_LIBACL
-#define ARCHIVE_ACL_POSIX1E 1
-#endif
-
-#if ARCHIVE_ACL_FREEBSD_NFS4 || ARCHIVE_ACL_SUNOS_NFS4 || \
- ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_LIBRICHACL
-#define ARCHIVE_ACL_NFS4 1
-#endif
-
-#if ARCHIVE_ACL_POSIX1E || ARCHIVE_ACL_NFS4
-#define ARCHIVE_ACL_SUPPORT 1
-#endif
-
-#endif /* ARCHIVE_PLATFORM_ACL_H_INCLUDED */
diff --git a/contrib/libs/libarchive/libarchive/archive_ppmd7.c b/contrib/libs/libarchive/libarchive/archive_ppmd7.c
deleted file mode 100644
index cc3f778203..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_ppmd7.c
+++ /dev/null
@@ -1,1168 +0,0 @@
-/* Ppmd7.c -- PPMdH codec
-2010-03-12 : Igor Pavlov : Public domain
-This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
-
-#include "archive_platform.h"
-
-#include <stdlib.h>
-
-#include "archive_ppmd7_private.h"
-
-#ifdef PPMD_32BIT
- #define Ppmd7_GetPtr(p, ptr) (ptr)
- #define Ppmd7_GetContext(p, ptr) (ptr)
- #define Ppmd7_GetStats(p, ctx) ((ctx)->Stats)
-#else
- #define Ppmd7_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
- #define Ppmd7_GetContext(p, offs) ((CPpmd7_Context *)Ppmd7_GetPtr((p), (offs)))
- #define Ppmd7_GetStats(p, ctx) ((CPpmd_State *)Ppmd7_GetPtr((p), ((ctx)->Stats)))
-#endif
-
-#define Ppmd7_GetBinSumm(p) \
- &p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
- p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
- (p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
- 2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \
- ((p->RunLength >> 26) & 0x20)]
-
-#define kTopValue (1 << 24)
-#define MAX_FREQ 124
-#define UNIT_SIZE 12
-
-#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
-#define U2I(nu) (p->Units2Indx[(nu) - 1])
-#define I2U(indx) (p->Indx2Units[indx])
-
-#ifdef PPMD_32BIT
- #define REF(ptr) (ptr)
-#else
- #define REF(ptr) ((UInt32)((Byte *)(ptr) - (p)->Base))
-#endif
-
-#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr))
-
-#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref))
-#define STATS(ctx) Ppmd7_GetStats(p, ctx)
-#define ONE_STATE(ctx) Ppmd7Context_OneState(ctx)
-#define SUFFIX(ctx) CTX((ctx)->Suffix)
-
-static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051};
-static const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
-
-typedef CPpmd7_Context * CTX_PTR;
-
-struct CPpmd7_Node_;
-
-typedef
- #ifdef PPMD_32BIT
- struct CPpmd7_Node_ *
- #else
- UInt32
- #endif
- CPpmd7_Node_Ref;
-
-typedef struct CPpmd7_Node_
-{
- UInt16 Stamp; /* must be at offset 0 as CPpmd7_Context::NumStats. Stamp=0 means free */
- UInt16 NU;
- CPpmd7_Node_Ref Next; /* must be at offset >= 4 */
- CPpmd7_Node_Ref Prev;
-} CPpmd7_Node;
-
-#ifdef PPMD_32BIT
- #define NODE(ptr) (ptr)
-#else
- #define NODE(offs) ((CPpmd7_Node *)(p->Base + (offs)))
-#endif
-
-static void Ppmd7_Update1(CPpmd7 *p);
-static void Ppmd7_Update1_0(CPpmd7 *p);
-static void Ppmd7_Update2(CPpmd7 *p);
-static void Ppmd7_UpdateBin(CPpmd7 *p);
-static CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked,
- UInt32 *scale);
-
-/* ----------- Base ----------- */
-
-static void Ppmd7_Construct(CPpmd7 *p)
-{
- unsigned i, k, m;
-
- p->Base = 0;
-
- for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
- {
- unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
- do { p->Units2Indx[k++] = (Byte)i; } while(--step);
- p->Indx2Units[i] = (Byte)k;
- }
-
- p->NS2BSIndx[0] = (0 << 1);
- p->NS2BSIndx[1] = (1 << 1);
- memset(p->NS2BSIndx + 2, (2 << 1), 9);
- memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11);
-
- for (i = 0; i < 3; i++)
- p->NS2Indx[i] = (Byte)i;
- for (m = i, k = 1; i < 256; i++)
- {
- p->NS2Indx[i] = (Byte)m;
- if (--k == 0)
- k = (++m) - 2;
- }
-
- memset(p->HB2Flag, 0, 0x40);
- memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40);
-}
-
-static void Ppmd7_Free(CPpmd7 *p)
-{
- free(p->Base);
- p->Size = 0;
- p->Base = 0;
-}
-
-static Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size)
-{
- if (p->Base == 0 || p->Size != size)
- {
- /* RestartModel() below assumes that p->Size >= UNIT_SIZE
- (see the calculation of m->MinContext). */
- if (size < UNIT_SIZE) {
- return False;
- }
- Ppmd7_Free(p);
- p->AlignOffset =
- #ifdef PPMD_32BIT
- (4 - size) & 3;
- #else
- 4 - (size & 3);
- #endif
- if ((p->Base = (Byte *)malloc(p->AlignOffset + size
- #ifndef PPMD_32BIT
- + UNIT_SIZE
- #endif
- )) == 0)
- return False;
- p->Size = size;
- }
- return True;
-}
-
-static void InsertNode(CPpmd7 *p, void *node, unsigned indx)
-{
- *((CPpmd_Void_Ref *)node) = p->FreeList[indx];
- p->FreeList[indx] = REF(node);
-}
-
-static void *RemoveNode(CPpmd7 *p, unsigned indx)
-{
- CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p->FreeList[indx]);
- p->FreeList[indx] = *node;
- return node;
-}
-
-static void SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx)
-{
- unsigned i, nu = I2U(oldIndx) - I2U(newIndx);
- ptr = (Byte *)ptr + U2B(I2U(newIndx));
- if (I2U(i = U2I(nu)) != nu)
- {
- unsigned k = I2U(--i);
- InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1);
- }
- InsertNode(p, ptr, i);
-}
-
-static void GlueFreeBlocks(CPpmd7 *p)
-{
- #ifdef PPMD_32BIT
- CPpmd7_Node headItem;
- CPpmd7_Node_Ref head = &headItem;
- #else
- CPpmd7_Node_Ref head = p->AlignOffset + p->Size;
- #endif
-
- CPpmd7_Node_Ref n = head;
- unsigned i;
-
- p->GlueCount = 255;
-
- /* create doubly-linked list of free blocks */
- for (i = 0; i < PPMD_NUM_INDEXES; i++)
- {
- UInt16 nu = I2U(i);
- CPpmd7_Node_Ref next = (CPpmd7_Node_Ref)p->FreeList[i];
- p->FreeList[i] = 0;
- while (next != 0)
- {
- CPpmd7_Node *node = NODE(next);
- node->Next = n;
- n = NODE(n)->Prev = next;
- next = *(const CPpmd7_Node_Ref *)node;
- node->Stamp = 0;
- node->NU = (UInt16)nu;
- }
- }
- NODE(head)->Stamp = 1;
- NODE(head)->Next = n;
- NODE(n)->Prev = head;
- if (p->LoUnit != p->HiUnit)
- ((CPpmd7_Node *)p->LoUnit)->Stamp = 1;
-
- /* Glue free blocks */
- while (n != head)
- {
- CPpmd7_Node *node = NODE(n);
- UInt32 nu = (UInt32)node->NU;
- for (;;)
- {
- CPpmd7_Node *node2 = NODE(n) + nu;
- nu += node2->NU;
- if (node2->Stamp != 0 || nu >= 0x10000)
- break;
- NODE(node2->Prev)->Next = node2->Next;
- NODE(node2->Next)->Prev = node2->Prev;
- node->NU = (UInt16)nu;
- }
- n = node->Next;
- }
-
- /* Fill lists of free blocks */
- for (n = NODE(head)->Next; n != head;)
- {
- CPpmd7_Node *node = NODE(n);
- unsigned nu;
- CPpmd7_Node_Ref next = node->Next;
- for (nu = node->NU; nu > 128; nu -= 128, node += 128)
- InsertNode(p, node, PPMD_NUM_INDEXES - 1);
- if (I2U(i = U2I(nu)) != nu)
- {
- unsigned k = I2U(--i);
- InsertNode(p, node + k, nu - k - 1);
- }
- InsertNode(p, node, i);
- n = next;
- }
-}
-
-static void *AllocUnitsRare(CPpmd7 *p, unsigned indx)
-{
- unsigned i;
- void *retVal;
- if (p->GlueCount == 0)
- {
- GlueFreeBlocks(p);
- if (p->FreeList[indx] != 0)
- return RemoveNode(p, indx);
- }
- i = indx;
- do
- {
- if (++i == PPMD_NUM_INDEXES)
- {
- UInt32 numBytes = U2B(I2U(indx));
- p->GlueCount--;
- return ((UInt32)(p->UnitsStart - p->Text) > numBytes) ? (p->UnitsStart -= numBytes) : (NULL);
- }
- }
- while (p->FreeList[i] == 0);
- retVal = RemoveNode(p, i);
- SplitBlock(p, retVal, i, indx);
- return retVal;
-}
-
-static void *AllocUnits(CPpmd7 *p, unsigned indx)
-{
- UInt32 numBytes;
- if (p->FreeList[indx] != 0)
- return RemoveNode(p, indx);
- numBytes = U2B(I2U(indx));
- if (numBytes <= (UInt32)(p->HiUnit - p->LoUnit))
- {
- void *retVal = p->LoUnit;
- p->LoUnit += numBytes;
- return retVal;
- }
- return AllocUnitsRare(p, indx);
-}
-
-#define MyMem12Cpy(dest, src, num) \
- { UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
- do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); }
-
-static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
-{
- unsigned i0 = U2I(oldNU);
- unsigned i1 = U2I(newNU);
- if (i0 == i1)
- return oldPtr;
- if (p->FreeList[i1] != 0)
- {
- void *ptr = RemoveNode(p, i1);
- MyMem12Cpy(ptr, oldPtr, newNU);
- InsertNode(p, oldPtr, i0);
- return ptr;
- }
- SplitBlock(p, oldPtr, i0, i1);
- return oldPtr;
-}
-
-#define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16)))
-
-static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v)
-{
- (p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF);
- (p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF);
-}
-
-static void RestartModel(CPpmd7 *p)
-{
- unsigned i, k, m;
-
- memset(p->FreeList, 0, sizeof(p->FreeList));
- p->Text = p->Base + p->AlignOffset;
- p->HiUnit = p->Text + p->Size;
- p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE;
- p->GlueCount = 0;
-
- p->OrderFall = p->MaxOrder;
- p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1;
- p->PrevSuccess = 0;
-
- p->MinContext = p->MaxContext = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */
- p->MinContext->Suffix = 0;
- p->MinContext->NumStats = 256;
- p->MinContext->SummFreq = 256 + 1;
- p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */
- p->LoUnit += U2B(256 / 2);
- p->MinContext->Stats = REF(p->FoundState);
- for (i = 0; i < 256; i++)
- {
- CPpmd_State *s = &p->FoundState[i];
- s->Symbol = (Byte)i;
- s->Freq = 1;
- SetSuccessor(s, 0);
- }
-
- for (i = 0; i < 128; i++)
- for (k = 0; k < 8; k++)
- {
- UInt16 *dest = p->BinSumm[i] + k;
- UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2));
- for (m = 0; m < 64; m += 8)
- dest[m] = val;
- }
-
- for (i = 0; i < 25; i++)
- for (k = 0; k < 16; k++)
- {
- CPpmd_See *s = &p->See[i][k];
- s->Summ = (UInt16)((5 * i + 10) << (s->Shift = PPMD_PERIOD_BITS - 4));
- s->Count = 4;
- }
-}
-
-static void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder)
-{
- p->MaxOrder = maxOrder;
- RestartModel(p);
- p->DummySee.Shift = PPMD_PERIOD_BITS;
- p->DummySee.Summ = 0; /* unused */
- p->DummySee.Count = 64; /* unused */
-}
-
-static CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip)
-{
- CPpmd_State upState;
- CTX_PTR c = p->MinContext;
- CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState);
- CPpmd_State *ps[PPMD7_MAX_ORDER];
- unsigned numPs = 0;
-
- if (!skip)
- ps[numPs++] = p->FoundState;
-
- while (c->Suffix)
- {
- CPpmd_Void_Ref successor;
- CPpmd_State *s;
- c = SUFFIX(c);
- if (c->NumStats != 1)
- {
- for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++);
- }
- else
- s = ONE_STATE(c);
- successor = SUCCESSOR(s);
- if (successor != upBranch)
- {
- c = CTX(successor);
- if (numPs == 0)
- return c;
- break;
- }
- ps[numPs++] = s;
- }
-
- upState.Symbol = *(const Byte *)Ppmd7_GetPtr(p, upBranch);
- SetSuccessor(&upState, upBranch + 1);
-
- if (c->NumStats == 1)
- upState.Freq = ONE_STATE(c)->Freq;
- else
- {
- UInt32 cf, s0;
- CPpmd_State *s;
- for (s = STATS(c); s->Symbol != upState.Symbol; s++);
- cf = s->Freq - 1;
- s0 = c->SummFreq - c->NumStats - cf;
- upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((2 * cf + 3 * s0 - 1) / (2 * s0))));
- }
-
- while (numPs != 0)
- {
- /* Create Child */
- CTX_PTR c1; /* = AllocContext(p); */
- if (p->HiUnit != p->LoUnit)
- c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE);
- else if (p->FreeList[0] != 0)
- c1 = (CTX_PTR)RemoveNode(p, 0);
- else
- {
- c1 = (CTX_PTR)AllocUnitsRare(p, 0);
- if (!c1)
- return NULL;
- }
- c1->NumStats = 1;
- *ONE_STATE(c1) = upState;
- c1->Suffix = REF(c);
- SetSuccessor(ps[--numPs], REF(c1));
- c = c1;
- }
-
- return c;
-}
-
-static void SwapStates(CPpmd_State *t1, CPpmd_State *t2)
-{
- CPpmd_State tmp = *t1;
- *t1 = *t2;
- *t2 = tmp;
-}
-
-static void UpdateModel(CPpmd7 *p)
-{
- CPpmd_Void_Ref successor, fSuccessor = SUCCESSOR(p->FoundState);
- CTX_PTR c;
- unsigned s0, ns;
-
- if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0)
- {
- c = SUFFIX(p->MinContext);
-
- if (c->NumStats == 1)
- {
- CPpmd_State *s = ONE_STATE(c);
- if (s->Freq < 32)
- s->Freq++;
- }
- else
- {
- CPpmd_State *s = STATS(c);
- if (s->Symbol != p->FoundState->Symbol)
- {
- do { s++; } while (s->Symbol != p->FoundState->Symbol);
- if (s[0].Freq >= s[-1].Freq)
- {
- SwapStates(&s[0], &s[-1]);
- s--;
- }
- }
- if (s->Freq < MAX_FREQ - 9)
- {
- s->Freq += 2;
- c->SummFreq += 2;
- }
- }
- }
-
- if (p->OrderFall == 0)
- {
- p->MinContext = p->MaxContext = CreateSuccessors(p, True);
- if (p->MinContext == 0)
- {
- RestartModel(p);
- return;
- }
- SetSuccessor(p->FoundState, REF(p->MinContext));
- return;
- }
-
- *p->Text++ = p->FoundState->Symbol;
- successor = REF(p->Text);
- if (p->Text >= p->UnitsStart)
- {
- RestartModel(p);
- return;
- }
-
- if (fSuccessor)
- {
- if (fSuccessor <= successor)
- {
- CTX_PTR cs = CreateSuccessors(p, False);
- if (cs == NULL)
- {
- RestartModel(p);
- return;
- }
- fSuccessor = REF(cs);
- }
- if (--p->OrderFall == 0)
- {
- successor = fSuccessor;
- p->Text -= (p->MaxContext != p->MinContext);
- }
- }
- else
- {
- SetSuccessor(p->FoundState, successor);
- fSuccessor = REF(p->MinContext);
- }
-
- s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - (p->FoundState->Freq - 1);
-
- for (c = p->MaxContext; c != p->MinContext; c = SUFFIX(c))
- {
- unsigned ns1;
- UInt32 cf, sf;
- if ((ns1 = c->NumStats) != 1)
- {
- if ((ns1 & 1) == 0)
- {
- /* Expand for one UNIT */
- unsigned oldNU = ns1 >> 1;
- unsigned i = U2I(oldNU);
- if (i != U2I(oldNU + 1))
- {
- void *ptr = AllocUnits(p, i + 1);
- void *oldPtr;
- if (!ptr)
- {
- RestartModel(p);
- return;
- }
- oldPtr = STATS(c);
- MyMem12Cpy(ptr, oldPtr, oldNU);
- InsertNode(p, oldPtr, i);
- c->Stats = STATS_REF(ptr);
- }
- }
- c->SummFreq = (UInt16)(c->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & (c->SummFreq <= 8 * ns1)));
- }
- else
- {
- CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0);
- if (!s)
- {
- RestartModel(p);
- return;
- }
- *s = *ONE_STATE(c);
- c->Stats = REF(s);
- if (s->Freq < MAX_FREQ / 4 - 1)
- s->Freq <<= 1;
- else
- s->Freq = MAX_FREQ - 4;
- c->SummFreq = (UInt16)(s->Freq + p->InitEsc + (ns > 3));
- }
- cf = 2 * (UInt32)p->FoundState->Freq * (c->SummFreq + 6);
- sf = (UInt32)s0 + c->SummFreq;
- if (cf < 6 * sf)
- {
- cf = 1 + (cf > sf) + (cf >= 4 * sf);
- c->SummFreq += 3;
- }
- else
- {
- cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf);
- c->SummFreq = (UInt16)(c->SummFreq + cf);
- }
- {
- CPpmd_State *s = STATS(c) + ns1;
- SetSuccessor(s, successor);
- s->Symbol = p->FoundState->Symbol;
- s->Freq = (Byte)cf;
- c->NumStats = (UInt16)(ns1 + 1);
- }
- }
- p->MaxContext = p->MinContext = CTX(fSuccessor);
-}
-
-static void Rescale(CPpmd7 *p)
-{
- unsigned i, adder, sumFreq, escFreq;
- CPpmd_State *stats = STATS(p->MinContext);
- CPpmd_State *s = p->FoundState;
- {
- CPpmd_State tmp = *s;
- for (; s != stats; s--)
- s[0] = s[-1];
- *s = tmp;
- }
- escFreq = p->MinContext->SummFreq - s->Freq;
- s->Freq += 4;
- adder = (p->OrderFall != 0);
- s->Freq = (Byte)((s->Freq + adder) >> 1);
- sumFreq = s->Freq;
-
- i = p->MinContext->NumStats - 1;
- do
- {
- escFreq -= (++s)->Freq;
- s->Freq = (Byte)((s->Freq + adder) >> 1);
- sumFreq += s->Freq;
- if (s[0].Freq > s[-1].Freq)
- {
- CPpmd_State *s1 = s;
- CPpmd_State tmp = *s1;
- do
- s1[0] = s1[-1];
- while (--s1 != stats && tmp.Freq > s1[-1].Freq);
- *s1 = tmp;
- }
- }
- while (--i);
-
- if (s->Freq == 0)
- {
- unsigned numStats = p->MinContext->NumStats;
- unsigned n0, n1;
- do { i++; } while ((--s)->Freq == 0);
- escFreq += i;
- p->MinContext->NumStats = (UInt16)(p->MinContext->NumStats - i);
- if (p->MinContext->NumStats == 1)
- {
- CPpmd_State tmp = *stats;
- do
- {
- tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1));
- escFreq >>= 1;
- }
- while (escFreq > 1);
- InsertNode(p, stats, U2I(((numStats + 1) >> 1)));
- *(p->FoundState = ONE_STATE(p->MinContext)) = tmp;
- return;
- }
- n0 = (numStats + 1) >> 1;
- n1 = (p->MinContext->NumStats + 1) >> 1;
- if (n0 != n1)
- p->MinContext->Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1));
- }
- p->MinContext->SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1));
- p->FoundState = STATS(p->MinContext);
-}
-
-static CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq)
-{
- CPpmd_See *see;
- unsigned nonMasked = p->MinContext->NumStats - numMasked;
- if (p->MinContext->NumStats != 256)
- {
- see = p->See[p->NS2Indx[nonMasked - 1]] +
- (nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) +
- 2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
- 4 * (numMasked > nonMasked) +
- p->HiBitsFlag;
- {
- unsigned r = (see->Summ >> see->Shift);
- see->Summ = (UInt16)(see->Summ - r);
- *escFreq = r + (r == 0);
- }
- }
- else
- {
- see = &p->DummySee;
- *escFreq = 1;
- }
- return see;
-}
-
-static void NextContext(CPpmd7 *p)
-{
- CTX_PTR c = CTX(SUCCESSOR(p->FoundState));
- if (p->OrderFall == 0 && (Byte *)c > p->Text)
- p->MinContext = p->MaxContext = c;
- else
- UpdateModel(p);
-}
-
-static void Ppmd7_Update1(CPpmd7 *p)
-{
- CPpmd_State *s = p->FoundState;
- s->Freq += 4;
- p->MinContext->SummFreq += 4;
- if (s[0].Freq > s[-1].Freq)
- {
- SwapStates(&s[0], &s[-1]);
- p->FoundState = --s;
- if (s->Freq > MAX_FREQ)
- Rescale(p);
- }
- NextContext(p);
-}
-
-static void Ppmd7_Update1_0(CPpmd7 *p)
-{
- p->PrevSuccess = (2 * p->FoundState->Freq > p->MinContext->SummFreq);
- p->RunLength += p->PrevSuccess;
- p->MinContext->SummFreq += 4;
- if ((p->FoundState->Freq += 4) > MAX_FREQ)
- Rescale(p);
- NextContext(p);
-}
-
-static void Ppmd7_UpdateBin(CPpmd7 *p)
-{
- p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 128 ? 1: 0));
- p->PrevSuccess = 1;
- p->RunLength++;
- NextContext(p);
-}
-
-static void Ppmd7_Update2(CPpmd7 *p)
-{
- p->MinContext->SummFreq += 4;
- if ((p->FoundState->Freq += 4) > MAX_FREQ)
- Rescale(p);
- p->RunLength = p->InitRL;
- UpdateModel(p);
-}
-
-/* ---------- Decode ---------- */
-
-static Bool Ppmd_RangeDec_Init(CPpmd7z_RangeDec *p)
-{
- unsigned i;
- p->Low = p->Bottom = 0;
- p->Range = 0xFFFFFFFF;
- for (i = 0; i < 4; i++)
- p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
- return (p->Code < 0xFFFFFFFF);
-}
-
-static Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p)
-{
- if (p->Stream->Read((void *)p->Stream) != 0)
- return False;
- return Ppmd_RangeDec_Init(p);
-}
-
-static Bool PpmdRAR_RangeDec_Init(CPpmd7z_RangeDec *p)
-{
- if (!Ppmd_RangeDec_Init(p))
- return False;
- p->Bottom = 0x8000;
- return True;
-}
-
-static UInt32 Range_GetThreshold(void *pp, UInt32 total)
-{
- CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
- return (p->Code - p->Low) / (p->Range /= total);
-}
-
-static void Range_Normalize(CPpmd7z_RangeDec *p)
-{
- while (1)
- {
- if((p->Low ^ (p->Low + p->Range)) >= kTopValue)
- {
- if(p->Range >= p->Bottom)
- break;
- else
- p->Range = ((uint32_t)(-(int32_t)p->Low)) & (p->Bottom - 1);
- }
- p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
- p->Range <<= 8;
- p->Low <<= 8;
- }
-}
-
-static void Range_Decode_7z(void *pp, UInt32 start, UInt32 size)
-{
- CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
- p->Code -= start * p->Range;
- p->Range *= size;
- Range_Normalize(p);
-}
-
-static void Range_Decode_RAR(void *pp, UInt32 start, UInt32 size)
-{
- CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
- p->Low += start * p->Range;
- p->Range *= size;
- Range_Normalize(p);
-}
-
-static UInt32 Range_DecodeBit_7z(void *pp, UInt32 size0)
-{
- CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
- UInt32 newBound = (p->Range >> 14) * size0;
- UInt32 symbol;
- if (p->Code < newBound)
- {
- symbol = 0;
- p->Range = newBound;
- }
- else
- {
- symbol = 1;
- p->Code -= newBound;
- p->Range -= newBound;
- }
- Range_Normalize(p);
- return symbol;
-}
-
-static UInt32 Range_DecodeBit_RAR(void *pp, UInt32 size0)
-{
- CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
- UInt32 bit, value = p->p.GetThreshold(p, PPMD_BIN_SCALE);
- if(value < size0)
- {
- bit = 0;
- p->p.Decode(p, 0, size0);
- }
- else
- {
- bit = 1;
- p->p.Decode(p, size0, PPMD_BIN_SCALE - size0);
- }
- return bit;
-}
-
-static void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
-{
- p->p.GetThreshold = Range_GetThreshold;
- p->p.Decode = Range_Decode_7z;
- p->p.DecodeBit = Range_DecodeBit_7z;
-}
-
-static void PpmdRAR_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
-{
- p->p.GetThreshold = Range_GetThreshold;
- p->p.Decode = Range_Decode_RAR;
- p->p.DecodeBit = Range_DecodeBit_RAR;
-}
-
-#define MASK(sym) ((signed char *)charMask)[sym]
-
-static int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc)
-{
- size_t charMask[256 / sizeof(size_t)];
- if (p->MinContext->NumStats != 1)
- {
- CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
- unsigned i;
- UInt32 count, hiCnt;
- if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq))
- {
- Byte symbol;
- rc->Decode(rc, 0, s->Freq);
- p->FoundState = s;
- symbol = s->Symbol;
- Ppmd7_Update1_0(p);
- return symbol;
- }
- p->PrevSuccess = 0;
- i = p->MinContext->NumStats - 1;
- do
- {
- if ((hiCnt += (++s)->Freq) > count)
- {
- Byte symbol;
- rc->Decode(rc, hiCnt - s->Freq, s->Freq);
- p->FoundState = s;
- symbol = s->Symbol;
- Ppmd7_Update1(p);
- return symbol;
- }
- }
- while (--i);
- if (count >= p->MinContext->SummFreq)
- return -2;
- p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];
- rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt);
- PPMD_SetAllBitsIn256Bytes(charMask);
- MASK(s->Symbol) = 0;
- i = p->MinContext->NumStats - 1;
- do { MASK((--s)->Symbol) = 0; } while (--i);
- }
- else
- {
- UInt16 *prob = Ppmd7_GetBinSumm(p);
- if (rc->DecodeBit(rc, *prob) == 0)
- {
- Byte symbol;
- *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
- symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol;
- Ppmd7_UpdateBin(p);
- return symbol;
- }
- *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
- p->InitEsc = PPMD7_kExpEscape[*prob >> 10];
- PPMD_SetAllBitsIn256Bytes(charMask);
- MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0;
- p->PrevSuccess = 0;
- }
- for (;;)
- {
- CPpmd_State *ps[256], *s;
- UInt32 freqSum, count, hiCnt;
- CPpmd_See *see;
- unsigned i, num, numMasked = p->MinContext->NumStats;
- do
- {
- p->OrderFall++;
- if (!p->MinContext->Suffix)
- return -1;
- p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);
- }
- while (p->MinContext->NumStats == numMasked);
- hiCnt = 0;
- s = Ppmd7_GetStats(p, p->MinContext);
- i = 0;
- num = p->MinContext->NumStats - numMasked;
- do
- {
- int k = (int)(MASK(s->Symbol));
- hiCnt += (s->Freq & k);
- ps[i] = s++;
- i -= k;
- }
- while (i != num);
-
- see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum);
- freqSum += hiCnt;
- count = rc->GetThreshold(rc, freqSum);
-
- if (count < hiCnt)
- {
- Byte symbol;
- CPpmd_State **pps = ps;
- for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++);
- s = *pps;
- rc->Decode(rc, hiCnt - s->Freq, s->Freq);
- Ppmd_See_Update(see);
- p->FoundState = s;
- symbol = s->Symbol;
- Ppmd7_Update2(p);
- return symbol;
- }
- if (count >= freqSum)
- return -2;
- rc->Decode(rc, hiCnt, freqSum - hiCnt);
- see->Summ = (UInt16)(see->Summ + freqSum);
- do { MASK(ps[--i]->Symbol) = 0; } while (i != 0);
- }
-}
-
-/* ---------- Encode ---------- Ppmd7Enc.c */
-
-#define kTopValue (1 << 24)
-
-static void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p)
-{
- p->Low = 0;
- p->Range = 0xFFFFFFFF;
- p->Cache = 0;
- p->CacheSize = 1;
-}
-
-static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p)
-{
- if ((UInt32)p->Low < (UInt32)0xFF000000 || (unsigned)(p->Low >> 32) != 0)
- {
- Byte temp = p->Cache;
- do
- {
- p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32)));
- temp = 0xFF;
- }
- while(--p->CacheSize != 0);
- p->Cache = (Byte)((UInt32)p->Low >> 24);
- }
- p->CacheSize++;
- p->Low = ((UInt32)p->Low << 8) & 0xFFFFFFFF;
-}
-
-static void RangeEnc_Encode(CPpmd7z_RangeEnc *p, UInt32 start, UInt32 size, UInt32 total)
-{
- p->Low += (UInt64)start * (UInt64)(p->Range /= total);
- p->Range *= size;
- while (p->Range < kTopValue)
- {
- p->Range <<= 8;
- RangeEnc_ShiftLow(p);
- }
-}
-
-static void RangeEnc_EncodeBit_0(CPpmd7z_RangeEnc *p, UInt32 size0)
-{
- p->Range = (p->Range >> 14) * size0;
- while (p->Range < kTopValue)
- {
- p->Range <<= 8;
- RangeEnc_ShiftLow(p);
- }
-}
-
-static void RangeEnc_EncodeBit_1(CPpmd7z_RangeEnc *p, UInt32 size0)
-{
- UInt32 newBound = (p->Range >> 14) * size0;
- p->Low += newBound;
- p->Range -= newBound;
- while (p->Range < kTopValue)
- {
- p->Range <<= 8;
- RangeEnc_ShiftLow(p);
- }
-}
-
-static void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p)
-{
- unsigned i;
- for (i = 0; i < 5; i++)
- RangeEnc_ShiftLow(p);
-}
-
-
-#define MASK(sym) ((signed char *)charMask)[sym]
-
-static void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol)
-{
- size_t charMask[256 / sizeof(size_t)];
- if (p->MinContext->NumStats != 1)
- {
- CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
- UInt32 sum;
- unsigned i;
- if (s->Symbol == symbol)
- {
- RangeEnc_Encode(rc, 0, s->Freq, p->MinContext->SummFreq);
- p->FoundState = s;
- Ppmd7_Update1_0(p);
- return;
- }
- p->PrevSuccess = 0;
- sum = s->Freq;
- i = p->MinContext->NumStats - 1;
- do
- {
- if ((++s)->Symbol == symbol)
- {
- RangeEnc_Encode(rc, sum, s->Freq, p->MinContext->SummFreq);
- p->FoundState = s;
- Ppmd7_Update1(p);
- return;
- }
- sum += s->Freq;
- }
- while (--i);
-
- p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];
- PPMD_SetAllBitsIn256Bytes(charMask);
- MASK(s->Symbol) = 0;
- i = p->MinContext->NumStats - 1;
- do { MASK((--s)->Symbol) = 0; } while (--i);
- RangeEnc_Encode(rc, sum, p->MinContext->SummFreq - sum, p->MinContext->SummFreq);
- }
- else
- {
- UInt16 *prob = Ppmd7_GetBinSumm(p);
- CPpmd_State *s = Ppmd7Context_OneState(p->MinContext);
- if (s->Symbol == symbol)
- {
- RangeEnc_EncodeBit_0(rc, *prob);
- *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
- p->FoundState = s;
- Ppmd7_UpdateBin(p);
- return;
- }
- else
- {
- RangeEnc_EncodeBit_1(rc, *prob);
- *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
- p->InitEsc = PPMD7_kExpEscape[*prob >> 10];
- PPMD_SetAllBitsIn256Bytes(charMask);
- MASK(s->Symbol) = 0;
- p->PrevSuccess = 0;
- }
- }
- for (;;)
- {
- UInt32 escFreq;
- CPpmd_See *see;
- CPpmd_State *s;
- UInt32 sum;
- unsigned i, numMasked = p->MinContext->NumStats;
- do
- {
- p->OrderFall++;
- if (!p->MinContext->Suffix)
- return; /* EndMarker (symbol = -1) */
- p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);
- }
- while (p->MinContext->NumStats == numMasked);
-
- see = Ppmd7_MakeEscFreq(p, numMasked, &escFreq);
- s = Ppmd7_GetStats(p, p->MinContext);
- sum = 0;
- i = p->MinContext->NumStats;
- do
- {
- int cur = s->Symbol;
- if (cur == symbol)
- {
- UInt32 low = sum;
- CPpmd_State *s1 = s;
- do
- {
- sum += (s->Freq & (int)(MASK(s->Symbol)));
- s++;
- }
- while (--i);
- RangeEnc_Encode(rc, low, s1->Freq, sum + escFreq);
- Ppmd_See_Update(see);
- p->FoundState = s1;
- Ppmd7_Update2(p);
- return;
- }
- sum += (s->Freq & (int)(MASK(cur)));
- MASK(cur) = 0;
- s++;
- }
- while (--i);
-
- RangeEnc_Encode(rc, sum, escFreq, sum + escFreq);
- see->Summ = (UInt16)(see->Summ + sum + escFreq);
- }
-}
-
-const IPpmd7 __archive_ppmd7_functions =
-{
- &Ppmd7_Construct,
- &Ppmd7_Alloc,
- &Ppmd7_Free,
- &Ppmd7_Init,
- &Ppmd7z_RangeDec_CreateVTable,
- &PpmdRAR_RangeDec_CreateVTable,
- &Ppmd7z_RangeDec_Init,
- &PpmdRAR_RangeDec_Init,
- &Ppmd7_DecodeSymbol,
- &Ppmd7z_RangeEnc_Init,
- &Ppmd7z_RangeEnc_FlushData,
- &Ppmd7_EncodeSymbol
-};
diff --git a/contrib/libs/libarchive/libarchive/archive_ppmd7_private.h b/contrib/libs/libarchive/libarchive/archive_ppmd7_private.h
deleted file mode 100644
index 71b954458c..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_ppmd7_private.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* Ppmd7.h -- PPMdH compression codec
-2010-03-12 : Igor Pavlov : Public domain
-This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
-
-/* This code supports virtual RangeDecoder and includes the implementation
-of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H.
-If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */
-
-#ifndef ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
-#define ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
-#include "archive_ppmd_private.h"
-
-#define PPMD7_MIN_ORDER 2
-#define PPMD7_MAX_ORDER 64
-
-#define PPMD7_MIN_MEM_SIZE (1 << 11)
-#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFFu - 12 * 3)
-
-struct CPpmd7_Context_;
-
-typedef
- #ifdef PPMD_32BIT
- struct CPpmd7_Context_ *
- #else
- UInt32
- #endif
- CPpmd7_Context_Ref;
-
-typedef struct CPpmd7_Context_
-{
- UInt16 NumStats;
- UInt16 SummFreq;
- CPpmd_State_Ref Stats;
- CPpmd7_Context_Ref Suffix;
-} CPpmd7_Context;
-
-#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
-
-typedef struct
-{
- CPpmd7_Context *MinContext, *MaxContext;
- CPpmd_State *FoundState;
- unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag;
- Int32 RunLength, InitRL; /* must be 32-bit at least */
-
- UInt32 Size;
- UInt32 GlueCount;
- Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
- UInt32 AlignOffset;
-
- Byte Indx2Units[PPMD_NUM_INDEXES];
- Byte Units2Indx[128];
- CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
- Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
- CPpmd_See DummySee, See[25][16];
- UInt16 BinSumm[128][64];
-} CPpmd7;
-
-/* ---------- Decode ---------- */
-
-typedef struct
-{
- UInt32 (*GetThreshold)(void *p, UInt32 total);
- void (*Decode)(void *p, UInt32 start, UInt32 size);
- UInt32 (*DecodeBit)(void *p, UInt32 size0);
-} IPpmd7_RangeDec;
-
-typedef struct
-{
- IPpmd7_RangeDec p;
- UInt32 Range;
- UInt32 Code;
- UInt32 Low;
- UInt32 Bottom;
- IByteIn *Stream;
-} CPpmd7z_RangeDec;
-
-/* ---------- Encode ---------- */
-
-typedef struct
-{
- UInt64 Low;
- UInt32 Range;
- Byte Cache;
- UInt64 CacheSize;
- IByteOut *Stream;
-} CPpmd7z_RangeEnc;
-
-typedef struct
-{
- /* Base Functions */
- void (*Ppmd7_Construct)(CPpmd7 *p);
- Bool (*Ppmd7_Alloc)(CPpmd7 *p, UInt32 size);
- void (*Ppmd7_Free)(CPpmd7 *p);
- void (*Ppmd7_Init)(CPpmd7 *p, unsigned maxOrder);
- #define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
-
- /* Decode Functions */
- void (*Ppmd7z_RangeDec_CreateVTable)(CPpmd7z_RangeDec *p);
- void (*PpmdRAR_RangeDec_CreateVTable)(CPpmd7z_RangeDec *p);
- Bool (*Ppmd7z_RangeDec_Init)(CPpmd7z_RangeDec *p);
- Bool (*PpmdRAR_RangeDec_Init)(CPpmd7z_RangeDec *p);
- #define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
- int (*Ppmd7_DecodeSymbol)(CPpmd7 *p, IPpmd7_RangeDec *rc);
-
- /* Encode Functions */
- void (*Ppmd7z_RangeEnc_Init)(CPpmd7z_RangeEnc *p);
- void (*Ppmd7z_RangeEnc_FlushData)(CPpmd7z_RangeEnc *p);
-
- void (*Ppmd7_EncodeSymbol)(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol);
-} IPpmd7;
-
-extern const IPpmd7 __archive_ppmd7_functions;
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_ppmd8.c b/contrib/libs/libarchive/libarchive/archive_ppmd8.c
deleted file mode 100644
index d1779395da..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_ppmd8.c
+++ /dev/null
@@ -1,1287 +0,0 @@
-/* Ppmd8.c -- PPMdI codec
-2016-05-21 : Igor Pavlov : Public domain
-This code is based on PPMd var.I (2002): Dmitry Shkarin : Public domain */
-
-#include "archive_platform.h"
-
-#include <string.h>
-
-#include "archive_ppmd8_private.h"
-
-const Byte PPMD8_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
-static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051};
-
-#define MAX_FREQ 124
-#define UNIT_SIZE 12
-
-#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
-#define U2I(nu) (p->Units2Indx[(nu) - 1])
-#define I2U(indx) (p->Indx2Units[indx])
-
-#ifdef PPMD_32BIT
- #define REF(ptr) (ptr)
-#else
- #define REF(ptr) ((UInt32)((Byte *)(ptr) - (p)->Base))
-#endif
-
-#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr))
-
-#define CTX(ref) ((CPpmd8_Context *)Ppmd8_GetContext(p, ref))
-#define STATS(ctx) Ppmd8_GetStats(p, ctx)
-#define ONE_STATE(ctx) Ppmd8Context_OneState(ctx)
-#define SUFFIX(ctx) CTX((ctx)->Suffix)
-
-#define kTop (1 << 24)
-#define kBot (1 << 15)
-
-typedef CPpmd8_Context * CTX_PTR;
-
-struct CPpmd8_Node_;
-
-typedef
- #ifdef PPMD_32BIT
- struct CPpmd8_Node_ *
- #else
- UInt32
- #endif
- CPpmd8_Node_Ref;
-
-typedef struct CPpmd8_Node_
-{
- UInt32 Stamp;
- CPpmd8_Node_Ref Next;
- UInt32 NU;
-} CPpmd8_Node;
-
-#ifdef PPMD_32BIT
- #define NODE(ptr) (ptr)
-#else
- #define NODE(offs) ((CPpmd8_Node *)(p->Base + (offs)))
-#endif
-
-#define EMPTY_NODE 0xFFFFFFFF
-
-void Ppmd8_Construct(CPpmd8 *p)
-{
- unsigned i, k, m;
-
- p->Base = 0;
-
- for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
- {
- unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
- do { p->Units2Indx[k++] = (Byte)i; } while (--step);
- p->Indx2Units[i] = (Byte)k;
- }
-
- p->NS2BSIndx[0] = (0 << 1);
- p->NS2BSIndx[1] = (1 << 1);
- memset(p->NS2BSIndx + 2, (2 << 1), 9);
- memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11);
-
- for (i = 0; i < 5; i++)
- p->NS2Indx[i] = (Byte)i;
- for (m = i, k = 1; i < 260; i++)
- {
- p->NS2Indx[i] = (Byte)m;
- if (--k == 0)
- k = (++m) - 4;
- }
-}
-
-void Ppmd8_Free(CPpmd8 *p)
-{
- free(p->Base);
- p->Size = 0;
- p->Base = 0;
-}
-
-Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size)
-{
- if (p->Base == 0 || p->Size != size)
- {
- Ppmd8_Free(p);
- p->AlignOffset =
- #ifdef PPMD_32BIT
- (4 - size) & 3;
- #else
- 4 - (size & 3);
- #endif
- if ((p->Base = (Byte *)malloc(p->AlignOffset + size)) == 0)
- return False;
- p->Size = size;
- }
- return True;
-}
-
-static void InsertNode(CPpmd8 *p, void *node, unsigned indx)
-{
- ((CPpmd8_Node *)node)->Stamp = EMPTY_NODE;
- ((CPpmd8_Node *)node)->Next = (CPpmd8_Node_Ref)p->FreeList[indx];
- ((CPpmd8_Node *)node)->NU = I2U(indx);
- p->FreeList[indx] = REF(node);
- p->Stamps[indx]++;
-}
-
-static void *RemoveNode(CPpmd8 *p, unsigned indx)
-{
- CPpmd8_Node *node = NODE((CPpmd8_Node_Ref)p->FreeList[indx]);
- p->FreeList[indx] = node->Next;
- p->Stamps[indx]--;
- return node;
-}
-
-static void SplitBlock(CPpmd8 *p, void *ptr, unsigned oldIndx, unsigned newIndx)
-{
- unsigned i, nu = I2U(oldIndx) - I2U(newIndx);
- ptr = (Byte *)ptr + U2B(I2U(newIndx));
- if (I2U(i = U2I(nu)) != nu)
- {
- unsigned k = I2U(--i);
- InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1);
- }
- InsertNode(p, ptr, i);
-}
-
-static void GlueFreeBlocks(CPpmd8 *p)
-{
- CPpmd8_Node_Ref head = 0;
- CPpmd8_Node_Ref *prev = &head;
- unsigned i;
-
- p->GlueCount = 1 << 13;
- memset(p->Stamps, 0, sizeof(p->Stamps));
-
- /* Order-0 context is always at top UNIT, so we don't need guard NODE at the end.
- All blocks up to p->LoUnit can be free, so we need guard NODE at LoUnit. */
- if (p->LoUnit != p->HiUnit)
- ((CPpmd8_Node *)p->LoUnit)->Stamp = 0;
-
- /* Glue free blocks */
- for (i = 0; i < PPMD_NUM_INDEXES; i++)
- {
- CPpmd8_Node_Ref next = (CPpmd8_Node_Ref)p->FreeList[i];
- p->FreeList[i] = 0;
- while (next != 0)
- {
- CPpmd8_Node *node = NODE(next);
- if (node->NU != 0)
- {
- CPpmd8_Node *node2;
- *prev = next;
- prev = &(node->Next);
- while ((node2 = node + node->NU)->Stamp == EMPTY_NODE)
- {
- node->NU += node2->NU;
- node2->NU = 0;
- }
- }
- next = node->Next;
- }
- }
- *prev = 0;
-
- /* Fill lists of free blocks */
- while (head != 0)
- {
- CPpmd8_Node *node = NODE(head);
- unsigned nu;
- head = node->Next;
- nu = node->NU;
- if (nu == 0)
- continue;
- for (; nu > 128; nu -= 128, node += 128)
- InsertNode(p, node, PPMD_NUM_INDEXES - 1);
- if (I2U(i = U2I(nu)) != nu)
- {
- unsigned k = I2U(--i);
- InsertNode(p, node + k, nu - k - 1);
- }
- InsertNode(p, node, i);
- }
-}
-
-static void *AllocUnitsRare(CPpmd8 *p, unsigned indx)
-{
- unsigned i;
- void *retVal;
- if (p->GlueCount == 0)
- {
- GlueFreeBlocks(p);
- if (p->FreeList[indx] != 0)
- return RemoveNode(p, indx);
- }
- i = indx;
- do
- {
- if (++i == PPMD_NUM_INDEXES)
- {
- UInt32 numBytes = U2B(I2U(indx));
- p->GlueCount--;
- return ((UInt32)(p->UnitsStart - p->Text) > numBytes) ? (p->UnitsStart -= numBytes) : (NULL);
- }
- }
- while (p->FreeList[i] == 0);
- retVal = RemoveNode(p, i);
- SplitBlock(p, retVal, i, indx);
- return retVal;
-}
-
-static void *AllocUnits(CPpmd8 *p, unsigned indx)
-{
- UInt32 numBytes;
- if (p->FreeList[indx] != 0)
- return RemoveNode(p, indx);
- numBytes = U2B(I2U(indx));
- if (numBytes <= (UInt32)(p->HiUnit - p->LoUnit))
- {
- void *retVal = p->LoUnit;
- p->LoUnit += numBytes;
- return retVal;
- }
- return AllocUnitsRare(p, indx);
-}
-
-#define MyMem12Cpy(dest, src, num) \
- { UInt32 *d = (UInt32 *)dest; const UInt32 *z = (const UInt32 *)src; UInt32 n = num; \
- do { d[0] = z[0]; d[1] = z[1]; d[2] = z[2]; z += 3; d += 3; } while (--n); }
-
-static void *ShrinkUnits(CPpmd8 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
-{
- unsigned i0 = U2I(oldNU);
- unsigned i1 = U2I(newNU);
- if (i0 == i1)
- return oldPtr;
- if (p->FreeList[i1] != 0)
- {
- void *ptr = RemoveNode(p, i1);
- MyMem12Cpy(ptr, oldPtr, newNU);
- InsertNode(p, oldPtr, i0);
- return ptr;
- }
- SplitBlock(p, oldPtr, i0, i1);
- return oldPtr;
-}
-
-static void FreeUnits(CPpmd8 *p, void *ptr, unsigned nu)
-{
- InsertNode(p, ptr, U2I(nu));
-}
-
-static void SpecialFreeUnit(CPpmd8 *p, void *ptr)
-{
- if ((Byte *)ptr != p->UnitsStart)
- InsertNode(p, ptr, 0);
- else
- {
- #ifdef PPMD8_FREEZE_SUPPORT
- *(UInt32 *)ptr = EMPTY_NODE; /* it's used for (Flags == 0xFF) check in RemoveBinContexts */
- #endif
- p->UnitsStart += UNIT_SIZE;
- }
-}
-
-static void *MoveUnitsUp(CPpmd8 *p, void *oldPtr, unsigned nu)
-{
- unsigned indx = U2I(nu);
- void *ptr;
- if ((Byte *)oldPtr > p->UnitsStart + 16 * 1024 || REF(oldPtr) > p->FreeList[indx])
- return oldPtr;
- ptr = RemoveNode(p, indx);
- MyMem12Cpy(ptr, oldPtr, nu);
- if ((Byte*)oldPtr != p->UnitsStart)
- InsertNode(p, oldPtr, indx);
- else
- p->UnitsStart += U2B(I2U(indx));
- return ptr;
-}
-
-static void ExpandTextArea(CPpmd8 *p)
-{
- UInt32 count[PPMD_NUM_INDEXES];
- unsigned i;
- memset(count, 0, sizeof(count));
- if (p->LoUnit != p->HiUnit)
- ((CPpmd8_Node *)p->LoUnit)->Stamp = 0;
-
- {
- CPpmd8_Node *node = (CPpmd8_Node *)p->UnitsStart;
- for (; node->Stamp == EMPTY_NODE; node += node->NU)
- {
- node->Stamp = 0;
- count[U2I(node->NU)]++;
- }
- p->UnitsStart = (Byte *)node;
- }
-
- for (i = 0; i < PPMD_NUM_INDEXES; i++)
- {
- CPpmd8_Node_Ref *next = (CPpmd8_Node_Ref *)&p->FreeList[i];
- while (count[i] != 0)
- {
- CPpmd8_Node *node = NODE(*next);
- while (node->Stamp == 0)
- {
- *next = node->Next;
- node = NODE(*next);
- p->Stamps[i]--;
- if (--count[i] == 0)
- break;
- }
- next = &node->Next;
- }
- }
-}
-
-#define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16)))
-
-static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v)
-{
- (p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF);
- (p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF);
-}
-
-#define RESET_TEXT(offs) { p->Text = p->Base + p->AlignOffset + (offs); }
-
-static void RestartModel(CPpmd8 *p)
-{
- unsigned i, k, m, r;
-
- memset(p->FreeList, 0, sizeof(p->FreeList));
- memset(p->Stamps, 0, sizeof(p->Stamps));
- RESET_TEXT(0);
- p->HiUnit = p->Text + p->Size;
- p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE;
- p->GlueCount = 0;
-
- p->OrderFall = p->MaxOrder;
- p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1;
- p->PrevSuccess = 0;
-
- p->MinContext = p->MaxContext = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */
- p->MinContext->Suffix = 0;
- p->MinContext->NumStats = 255;
- p->MinContext->Flags = 0;
- p->MinContext->SummFreq = 256 + 1;
- p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */
- p->LoUnit += U2B(256 / 2);
- p->MinContext->Stats = REF(p->FoundState);
- for (i = 0; i < 256; i++)
- {
- CPpmd_State *s = &p->FoundState[i];
- s->Symbol = (Byte)i;
- s->Freq = 1;
- SetSuccessor(s, 0);
- }
-
- for (i = m = 0; m < 25; m++)
- {
- while (p->NS2Indx[i] == m)
- i++;
- for (k = 0; k < 8; k++)
- {
- UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 1));
- UInt16 *dest = p->BinSumm[m] + k;
- for (r = 0; r < 64; r += 8)
- dest[r] = val;
- }
- }
-
- for (i = m = 0; m < 24; m++)
- {
- while (p->NS2Indx[i + 3] == m + 3)
- i++;
- for (k = 0; k < 32; k++)
- {
- CPpmd_See *s = &p->See[m][k];
- s->Summ = (UInt16)((2 * i + 5) << (s->Shift = PPMD_PERIOD_BITS - 4));
- s->Count = 7;
- }
- }
-}
-
-void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod)
-{
- p->MaxOrder = maxOrder;
- p->RestoreMethod = restoreMethod;
- RestartModel(p);
- p->DummySee.Shift = PPMD_PERIOD_BITS;
- p->DummySee.Summ = 0; /* unused */
- p->DummySee.Count = 64; /* unused */
-}
-
-static void Refresh(CPpmd8 *p, CTX_PTR ctx, unsigned oldNU, unsigned scale)
-{
- unsigned i = ctx->NumStats, escFreq, sumFreq, flags;
- CPpmd_State *s = (CPpmd_State *)ShrinkUnits(p, STATS(ctx), oldNU, (i + 2) >> 1);
- ctx->Stats = REF(s);
- #ifdef PPMD8_FREEZE_SUPPORT
- /* fixed over Shkarin's code. Fixed code is not compatible with original code for some files in FREEZE mode. */
- scale |= (ctx->SummFreq >= ((UInt32)1 << 15));
- #endif
- flags = (ctx->Flags & (0x10 + 0x04 * scale)) + 0x08 * (s->Symbol >= 0x40);
- escFreq = ctx->SummFreq - s->Freq;
- sumFreq = (s->Freq = (Byte)((s->Freq + scale) >> scale));
- do
- {
- escFreq -= (++s)->Freq;
- sumFreq += (s->Freq = (Byte)((s->Freq + scale) >> scale));
- flags |= 0x08 * (s->Symbol >= 0x40);
- }
- while (--i);
- ctx->SummFreq = (UInt16)(sumFreq + ((escFreq + scale) >> scale));
- ctx->Flags = (Byte)flags;
-}
-
-static void SwapStates(CPpmd_State *t1, CPpmd_State *t2)
-{
- CPpmd_State tmp = *t1;
- *t1 = *t2;
- *t2 = tmp;
-}
-
-static CPpmd_Void_Ref CutOff(CPpmd8 *p, CTX_PTR ctx, unsigned order)
-{
- int i;
- unsigned tmp;
- CPpmd_State *s;
-
- if (!ctx->NumStats)
- {
- s = ONE_STATE(ctx);
- if ((Byte *)Ppmd8_GetPtr(p, SUCCESSOR(s)) >= p->UnitsStart)
- {
- if (order < p->MaxOrder)
- SetSuccessor(s, CutOff(p, CTX(SUCCESSOR(s)), order + 1));
- else
- SetSuccessor(s, 0);
- if (SUCCESSOR(s) || order <= 9) /* O_BOUND */
- return REF(ctx);
- }
- SpecialFreeUnit(p, ctx);
- return 0;
- }
-
- ctx->Stats = STATS_REF(MoveUnitsUp(p, STATS(ctx), tmp = ((unsigned)ctx->NumStats + 2) >> 1));
-
- for (s = STATS(ctx) + (i = ctx->NumStats); s >= STATS(ctx); s--)
- if ((Byte *)Ppmd8_GetPtr(p, SUCCESSOR(s)) < p->UnitsStart)
- {
- CPpmd_State *s2 = STATS(ctx) + (i--);
- SetSuccessor(s, 0);
- SwapStates(s, s2);
- }
- else if (order < p->MaxOrder)
- SetSuccessor(s, CutOff(p, CTX(SUCCESSOR(s)), order + 1));
- else
- SetSuccessor(s, 0);
-
- if (i != ctx->NumStats && order)
- {
- ctx->NumStats = (Byte)i;
- s = STATS(ctx);
- if (i < 0)
- {
- FreeUnits(p, s, tmp);
- SpecialFreeUnit(p, ctx);
- return 0;
- }
- if (i == 0)
- {
- ctx->Flags = (Byte)((ctx->Flags & 0x10) + 0x08 * (s->Symbol >= 0x40));
- *ONE_STATE(ctx) = *s;
- FreeUnits(p, s, tmp);
- /* 9.31: the code was fixed. It's was not BUG, if Freq <= MAX_FREQ = 124 */
- ONE_STATE(ctx)->Freq = (Byte)(((unsigned)ONE_STATE(ctx)->Freq + 11) >> 3);
- }
- else
- Refresh(p, ctx, tmp, ctx->SummFreq > 16 * i);
- }
- return REF(ctx);
-}
-
-#ifdef PPMD8_FREEZE_SUPPORT
-static CPpmd_Void_Ref RemoveBinContexts(CPpmd8 *p, CTX_PTR ctx, unsigned order)
-{
- CPpmd_State *s;
- if (!ctx->NumStats)
- {
- s = ONE_STATE(ctx);
- if ((Byte *)Ppmd8_GetPtr(p, SUCCESSOR(s)) >= p->UnitsStart && order < p->MaxOrder)
- SetSuccessor(s, RemoveBinContexts(p, CTX(SUCCESSOR(s)), order + 1));
- else
- SetSuccessor(s, 0);
- /* Suffix context can be removed already, since different (high-order)
- Successors may refer to same context. So we check Flags == 0xFF (Stamp == EMPTY_NODE) */
- if (!SUCCESSOR(s) && (!SUFFIX(ctx)->NumStats || SUFFIX(ctx)->Flags == 0xFF))
- {
- FreeUnits(p, ctx, 1);
- return 0;
- }
- else
- return REF(ctx);
- }
-
- for (s = STATS(ctx) + ctx->NumStats; s >= STATS(ctx); s--)
- if ((Byte *)Ppmd8_GetPtr(p, SUCCESSOR(s)) >= p->UnitsStart && order < p->MaxOrder)
- SetSuccessor(s, RemoveBinContexts(p, CTX(SUCCESSOR(s)), order + 1));
- else
- SetSuccessor(s, 0);
-
- return REF(ctx);
-}
-#endif
-
-static UInt32 GetUsedMemory(const CPpmd8 *p)
-{
- UInt32 v = 0;
- unsigned i;
- for (i = 0; i < PPMD_NUM_INDEXES; i++)
- v += p->Stamps[i] * I2U(i);
- return p->Size - (UInt32)(p->HiUnit - p->LoUnit) - (UInt32)(p->UnitsStart - p->Text) - U2B(v);
-}
-
-#ifdef PPMD8_FREEZE_SUPPORT
- #define RESTORE_MODEL(c1, fSuccessor) RestoreModel(p, c1, fSuccessor)
-#else
- #define RESTORE_MODEL(c1, fSuccessor) RestoreModel(p, c1)
-#endif
-
-static void RestoreModel(CPpmd8 *p, CTX_PTR c1
- #ifdef PPMD8_FREEZE_SUPPORT
- , CTX_PTR fSuccessor
- #endif
- )
-{
- CTX_PTR c;
- CPpmd_State *s;
- RESET_TEXT(0);
- for (c = p->MaxContext; c != c1; c = SUFFIX(c))
- if (--(c->NumStats) == 0)
- {
- s = STATS(c);
- c->Flags = (Byte)((c->Flags & 0x10) + 0x08 * (s->Symbol >= 0x40));
- *ONE_STATE(c) = *s;
- SpecialFreeUnit(p, s);
- ONE_STATE(c)->Freq = (Byte)(((unsigned)ONE_STATE(c)->Freq + 11) >> 3);
- }
- else
- Refresh(p, c, (c->NumStats+3) >> 1, 0);
-
- for (; c != p->MinContext; c = SUFFIX(c))
- if (!c->NumStats)
- ONE_STATE(c)->Freq = (Byte)(ONE_STATE(c)->Freq - (ONE_STATE(c)->Freq >> 1));
- else if ((c->SummFreq += 4) > 128 + 4 * c->NumStats)
- Refresh(p, c, (c->NumStats + 2) >> 1, 1);
-
- #ifdef PPMD8_FREEZE_SUPPORT
- if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE)
- {
- p->MaxContext = fSuccessor;
- p->GlueCount += !(p->Stamps[1] & 1);
- }
- else if (p->RestoreMethod == PPMD8_RESTORE_METHOD_FREEZE)
- {
- while (p->MaxContext->Suffix)
- p->MaxContext = SUFFIX(p->MaxContext);
- RemoveBinContexts(p, p->MaxContext, 0);
- p->RestoreMethod++;
- p->GlueCount = 0;
- p->OrderFall = p->MaxOrder;
- }
- else
- #endif
- if (p->RestoreMethod == PPMD8_RESTORE_METHOD_RESTART || GetUsedMemory(p) < (p->Size >> 1))
- RestartModel(p);
- else
- {
- while (p->MaxContext->Suffix)
- p->MaxContext = SUFFIX(p->MaxContext);
- do
- {
- CutOff(p, p->MaxContext, 0);
- ExpandTextArea(p);
- }
- while (GetUsedMemory(p) > 3 * (p->Size >> 2));
- p->GlueCount = 0;
- p->OrderFall = p->MaxOrder;
- }
-}
-
-static CTX_PTR CreateSuccessors(CPpmd8 *p, Bool skip, CPpmd_State *s1, CTX_PTR c)
-{
- CPpmd_State upState;
- Byte flags;
- CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState);
- /* fixed over Shkarin's code. Maybe it could work without + 1 too. */
- CPpmd_State *ps[PPMD8_MAX_ORDER + 1];
- unsigned numPs = 0;
-
- if (!skip)
- ps[numPs++] = p->FoundState;
-
- while (c->Suffix)
- {
- CPpmd_Void_Ref successor;
- CPpmd_State *s;
- c = SUFFIX(c);
- if (s1)
- {
- s = s1;
- s1 = NULL;
- }
- else if (c->NumStats != 0)
- {
- for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++);
- if (s->Freq < MAX_FREQ - 9)
- {
- s->Freq++;
- c->SummFreq++;
- }
- }
- else
- {
- s = ONE_STATE(c);
- s->Freq = (Byte)(s->Freq + (!SUFFIX(c)->NumStats & (s->Freq < 24)));
- }
- successor = SUCCESSOR(s);
- if (successor != upBranch)
- {
- c = CTX(successor);
- if (numPs == 0)
- return c;
- break;
- }
- ps[numPs++] = s;
- }
-
- upState.Symbol = *(const Byte *)Ppmd8_GetPtr(p, upBranch);
- SetSuccessor(&upState, upBranch + 1);
- flags = (Byte)(0x10 * (p->FoundState->Symbol >= 0x40) + 0x08 * (upState.Symbol >= 0x40));
-
- if (c->NumStats == 0)
- upState.Freq = ONE_STATE(c)->Freq;
- else
- {
- UInt32 cf, s0;
- CPpmd_State *s;
- for (s = STATS(c); s->Symbol != upState.Symbol; s++);
- cf = s->Freq - 1;
- s0 = c->SummFreq - c->NumStats - cf;
- upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((cf + 2 * s0 - 3) / s0)));
- }
-
- do
- {
- /* Create Child */
- CTX_PTR c1; /* = AllocContext(p); */
- if (p->HiUnit != p->LoUnit)
- c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE);
- else if (p->FreeList[0] != 0)
- c1 = (CTX_PTR)RemoveNode(p, 0);
- else
- {
- c1 = (CTX_PTR)AllocUnitsRare(p, 0);
- if (!c1)
- return NULL;
- }
- c1->NumStats = 0;
- c1->Flags = flags;
- *ONE_STATE(c1) = upState;
- c1->Suffix = REF(c);
- SetSuccessor(ps[--numPs], REF(c1));
- c = c1;
- }
- while (numPs != 0);
-
- return c;
-}
-
-static CTX_PTR ReduceOrder(CPpmd8 *p, CPpmd_State *s1, CTX_PTR c)
-{
- CPpmd_State *s = NULL;
- CTX_PTR c1 = c;
- CPpmd_Void_Ref upBranch = REF(p->Text);
-
- #ifdef PPMD8_FREEZE_SUPPORT
- /* The BUG in Shkarin's code was fixed: ps could overflow in CUT_OFF mode. */
- CPpmd_State *ps[PPMD8_MAX_ORDER + 1];
- unsigned numPs = 0;
- ps[numPs++] = p->FoundState;
- #endif
-
- SetSuccessor(p->FoundState, upBranch);
- p->OrderFall++;
-
- for (;;)
- {
- if (s1)
- {
- c = SUFFIX(c);
- s = s1;
- s1 = NULL;
- }
- else
- {
- if (!c->Suffix)
- {
- #ifdef PPMD8_FREEZE_SUPPORT
- if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE)
- {
- do { SetSuccessor(ps[--numPs], REF(c)); } while (numPs);
- RESET_TEXT(1);
- p->OrderFall = 1;
- }
- #endif
- return c;
- }
- c = SUFFIX(c);
- if (c->NumStats)
- {
- if ((s = STATS(c))->Symbol != p->FoundState->Symbol)
- do { s++; } while (s->Symbol != p->FoundState->Symbol);
- if (s->Freq < MAX_FREQ - 9)
- {
- s->Freq += 2;
- c->SummFreq += 2;
- }
- }
- else
- {
- s = ONE_STATE(c);
- s->Freq = (Byte)(s->Freq + (s->Freq < 32));
- }
- }
- if (SUCCESSOR(s))
- break;
- #ifdef PPMD8_FREEZE_SUPPORT
- ps[numPs++] = s;
- #endif
- SetSuccessor(s, upBranch);
- p->OrderFall++;
- }
-
- #ifdef PPMD8_FREEZE_SUPPORT
- if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE)
- {
- c = CTX(SUCCESSOR(s));
- do { SetSuccessor(ps[--numPs], REF(c)); } while (numPs);
- RESET_TEXT(1);
- p->OrderFall = 1;
- return c;
- }
- else
- #endif
- if (SUCCESSOR(s) <= upBranch)
- {
- CTX_PTR successor;
- CPpmd_State *s2 = p->FoundState;
- p->FoundState = s;
-
- successor = CreateSuccessors(p, False, NULL, c);
- if (successor == NULL)
- SetSuccessor(s, 0);
- else
- SetSuccessor(s, REF(successor));
- p->FoundState = s2;
- }
-
- if (p->OrderFall == 1 && c1 == p->MaxContext)
- {
- SetSuccessor(p->FoundState, SUCCESSOR(s));
- p->Text--;
- }
- if (SUCCESSOR(s) == 0)
- return NULL;
- return CTX(SUCCESSOR(s));
-}
-
-static void UpdateModel(CPpmd8 *p)
-{
- CPpmd_Void_Ref successor, fSuccessor = SUCCESSOR(p->FoundState);
- CTX_PTR c;
- unsigned s0, ns, fFreq = p->FoundState->Freq;
- Byte flag, fSymbol = p->FoundState->Symbol;
- CPpmd_State *s = NULL;
-
- if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0)
- {
- c = SUFFIX(p->MinContext);
-
- if (c->NumStats == 0)
- {
- s = ONE_STATE(c);
- if (s->Freq < 32)
- s->Freq++;
- }
- else
- {
- s = STATS(c);
- if (s->Symbol != p->FoundState->Symbol)
- {
- do { s++; } while (s->Symbol != p->FoundState->Symbol);
- if (s[0].Freq >= s[-1].Freq)
- {
- SwapStates(&s[0], &s[-1]);
- s--;
- }
- }
- if (s->Freq < MAX_FREQ - 9)
- {
- s->Freq += 2;
- c->SummFreq += 2;
- }
- }
- }
-
- c = p->MaxContext;
- if (p->OrderFall == 0 && fSuccessor)
- {
- CTX_PTR cs = CreateSuccessors(p, True, s, p->MinContext);
- if (cs == 0)
- {
- SetSuccessor(p->FoundState, 0);
- RESTORE_MODEL(c, CTX(fSuccessor));
- }
- else
- {
- SetSuccessor(p->FoundState, REF(cs));
- p->MaxContext = cs;
- }
- return;
- }
-
- *p->Text++ = p->FoundState->Symbol;
- successor = REF(p->Text);
- if (p->Text >= p->UnitsStart)
- {
- RESTORE_MODEL(c, CTX(fSuccessor)); /* check it */
- return;
- }
-
- if (!fSuccessor)
- {
- CTX_PTR cs = ReduceOrder(p, s, p->MinContext);
- if (cs == NULL)
- {
- RESTORE_MODEL(c, 0);
- return;
- }
- fSuccessor = REF(cs);
- }
- else if ((Byte *)Ppmd8_GetPtr(p, fSuccessor) < p->UnitsStart)
- {
- CTX_PTR cs = CreateSuccessors(p, False, s, p->MinContext);
- if (cs == NULL)
- {
- RESTORE_MODEL(c, 0);
- return;
- }
- fSuccessor = REF(cs);
- }
-
- if (--p->OrderFall == 0)
- {
- successor = fSuccessor;
- p->Text -= (p->MaxContext != p->MinContext);
- }
- #ifdef PPMD8_FREEZE_SUPPORT
- else if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE)
- {
- successor = fSuccessor;
- RESET_TEXT(0);
- p->OrderFall = 0;
- }
- #endif
-
- s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - fFreq;
- flag = (Byte)(0x08 * (fSymbol >= 0x40));
-
- for (; c != p->MinContext; c = SUFFIX(c))
- {
- unsigned ns1;
- UInt32 cf, sf;
- if ((ns1 = c->NumStats) != 0)
- {
- if ((ns1 & 1) != 0)
- {
- /* Expand for one UNIT */
- unsigned oldNU = (ns1 + 1) >> 1;
- unsigned i = U2I(oldNU);
- if (i != U2I(oldNU + 1))
- {
- void *ptr = AllocUnits(p, i + 1);
- void *oldPtr;
- if (!ptr)
- {
- RESTORE_MODEL(c, CTX(fSuccessor));
- return;
- }
- oldPtr = STATS(c);
- MyMem12Cpy(ptr, oldPtr, oldNU);
- InsertNode(p, oldPtr, i);
- c->Stats = STATS_REF(ptr);
- }
- }
- c->SummFreq = (UInt16)(c->SummFreq + (3 * ns1 + 1 < ns));
- }
- else
- {
- CPpmd_State *s2 = (CPpmd_State*)AllocUnits(p, 0);
- if (!s2)
- {
- RESTORE_MODEL(c, CTX(fSuccessor));
- return;
- }
- *s2 = *ONE_STATE(c);
- c->Stats = REF(s2);
- if (s2->Freq < MAX_FREQ / 4 - 1)
- s2->Freq <<= 1;
- else
- s2->Freq = MAX_FREQ - 4;
- c->SummFreq = (UInt16)(s2->Freq + p->InitEsc + (ns > 2));
- }
- cf = 2 * fFreq * (c->SummFreq + 6);
- sf = (UInt32)s0 + c->SummFreq;
- if (cf < 6 * sf)
- {
- cf = 1 + (cf > sf) + (cf >= 4 * sf);
- c->SummFreq += 4;
- }
- else
- {
- cf = 4 + (cf > 9 * sf) + (cf > 12 * sf) + (cf > 15 * sf);
- c->SummFreq = (UInt16)(c->SummFreq + cf);
- }
- {
- CPpmd_State *s2 = STATS(c) + ns1 + 1;
- SetSuccessor(s2, successor);
- s2->Symbol = fSymbol;
- s2->Freq = (Byte)cf;
- c->Flags |= flag;
- c->NumStats = (Byte)(ns1 + 1);
- }
- }
- p->MaxContext = p->MinContext = CTX(fSuccessor);
-}
-
-static void Rescale(CPpmd8 *p)
-{
- unsigned i, adder, sumFreq, escFreq;
- CPpmd_State *stats = STATS(p->MinContext);
- CPpmd_State *s = p->FoundState;
- {
- CPpmd_State tmp = *s;
- for (; s != stats; s--)
- s[0] = s[-1];
- *s = tmp;
- }
- escFreq = p->MinContext->SummFreq - s->Freq;
- s->Freq += 4;
- adder = (p->OrderFall != 0
- #ifdef PPMD8_FREEZE_SUPPORT
- || p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE
- #endif
- );
- s->Freq = (Byte)((s->Freq + adder) >> 1);
- sumFreq = s->Freq;
-
- i = p->MinContext->NumStats;
- do
- {
- escFreq -= (++s)->Freq;
- s->Freq = (Byte)((s->Freq + adder) >> 1);
- sumFreq += s->Freq;
- if (s[0].Freq > s[-1].Freq)
- {
- CPpmd_State *s1 = s;
- CPpmd_State tmp = *s1;
- do
- s1[0] = s1[-1];
- while (--s1 != stats && tmp.Freq > s1[-1].Freq);
- *s1 = tmp;
- }
- }
- while (--i);
-
- if (s->Freq == 0)
- {
- unsigned numStats = p->MinContext->NumStats;
- unsigned n0, n1;
- do { i++; } while ((--s)->Freq == 0);
- escFreq += i;
- p->MinContext->NumStats = (Byte)(p->MinContext->NumStats - i);
- if (p->MinContext->NumStats == 0)
- {
- CPpmd_State tmp = *stats;
- tmp.Freq = (Byte)((2 * tmp.Freq + escFreq - 1) / escFreq);
- if (tmp.Freq > MAX_FREQ / 3)
- tmp.Freq = MAX_FREQ / 3;
- InsertNode(p, stats, U2I((numStats + 2) >> 1));
- p->MinContext->Flags = (Byte)((p->MinContext->Flags & 0x10) + 0x08 * (tmp.Symbol >= 0x40));
- *(p->FoundState = ONE_STATE(p->MinContext)) = tmp;
- return;
- }
- n0 = (numStats + 2) >> 1;
- n1 = (p->MinContext->NumStats + 2) >> 1;
- if (n0 != n1)
- p->MinContext->Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1));
- p->MinContext->Flags &= ~0x08;
- p->MinContext->Flags |= 0x08 * ((s = STATS(p->MinContext))->Symbol >= 0x40);
- i = p->MinContext->NumStats;
- do { p->MinContext->Flags |= 0x08*((++s)->Symbol >= 0x40); } while (--i);
- }
- p->MinContext->SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1));
- p->MinContext->Flags |= 0x4;
- p->FoundState = STATS(p->MinContext);
-}
-
-CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked1, UInt32 *escFreq)
-{
- CPpmd_See *see;
- if (p->MinContext->NumStats != 0xFF)
- {
- see = p->See[(unsigned)p->NS2Indx[(unsigned)p->MinContext->NumStats + 2] - 3] +
- (p->MinContext->SummFreq > 11 * ((unsigned)p->MinContext->NumStats + 1)) +
- 2 * (unsigned)(2 * (unsigned)p->MinContext->NumStats <
- ((unsigned)SUFFIX(p->MinContext)->NumStats + numMasked1)) +
- p->MinContext->Flags;
- {
- unsigned r = (see->Summ >> see->Shift);
- see->Summ = (UInt16)(see->Summ - r);
- *escFreq = r + (r == 0);
- }
- }
- else
- {
- see = &p->DummySee;
- *escFreq = 1;
- }
- return see;
-}
-
-static void NextContext(CPpmd8 *p)
-{
- CTX_PTR c = CTX(SUCCESSOR(p->FoundState));
- if (p->OrderFall == 0 && (Byte *)c >= p->UnitsStart)
- p->MinContext = p->MaxContext = c;
- else
- {
- UpdateModel(p);
- p->MinContext = p->MaxContext;
- }
-}
-
-void Ppmd8_Update1(CPpmd8 *p)
-{
- CPpmd_State *s = p->FoundState;
- s->Freq += 4;
- p->MinContext->SummFreq += 4;
- if (s[0].Freq > s[-1].Freq)
- {
- SwapStates(&s[0], &s[-1]);
- p->FoundState = --s;
- if (s->Freq > MAX_FREQ)
- Rescale(p);
- }
- NextContext(p);
-}
-
-void Ppmd8_Update1_0(CPpmd8 *p)
-{
- p->PrevSuccess = (2 * p->FoundState->Freq >= p->MinContext->SummFreq);
- p->RunLength += p->PrevSuccess;
- p->MinContext->SummFreq += 4;
- if ((p->FoundState->Freq += 4) > MAX_FREQ)
- Rescale(p);
- NextContext(p);
-}
-
-void Ppmd8_UpdateBin(CPpmd8 *p)
-{
- p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 196));
- p->PrevSuccess = 1;
- p->RunLength++;
- NextContext(p);
-}
-
-void Ppmd8_Update2(CPpmd8 *p)
-{
- p->MinContext->SummFreq += 4;
- if ((p->FoundState->Freq += 4) > MAX_FREQ)
- Rescale(p);
- p->RunLength = p->InitRL;
- UpdateModel(p);
- p->MinContext = p->MaxContext;
-}
-
-/* Ppmd8Dec.c -- PPMdI Decoder
-2010-04-16 : Igor Pavlov : Public domain
-This code is based on:
- PPMd var.I (2002): Dmitry Shkarin : Public domain
- Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
-
-Bool Ppmd8_RangeDec_Init(CPpmd8 *p)
-{
- unsigned i;
- p->Low = 0;
- p->Range = 0xFFFFFFFF;
- p->Code = 0;
- for (i = 0; i < 4; i++)
- p->Code = (p->Code << 8) | p->Stream.In->Read(p->Stream.In);
- return (p->Code < 0xFFFFFFFF);
-}
-
-static UInt32 RangeDec_GetThreshold(CPpmd8 *p, UInt32 total)
-{
- return p->Code / (p->Range /= total);
-}
-
-static void RangeDec_Decode(CPpmd8 *p, UInt32 start, UInt32 size)
-{
- start *= p->Range;
- p->Low += start;
- p->Code -= start;
- p->Range *= size;
-
- while ((p->Low ^ (p->Low + p->Range)) < kTop ||
- (p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1)))
- {
- p->Code = (p->Code << 8) | p->Stream.In->Read(p->Stream.In);
- p->Range <<= 8;
- p->Low <<= 8;
- }
-}
-
-#define MASK(sym) ((signed char *)charMask)[sym]
-
-int Ppmd8_DecodeSymbol(CPpmd8 *p)
-{
- size_t charMask[256 / sizeof(size_t)];
- if (p->MinContext->NumStats != 0)
- {
- CPpmd_State *s = Ppmd8_GetStats(p, p->MinContext);
- unsigned i;
- UInt32 count, hiCnt;
- if ((count = RangeDec_GetThreshold(p, p->MinContext->SummFreq)) < (hiCnt = s->Freq))
- {
- Byte symbol;
- RangeDec_Decode(p, 0, s->Freq);
- p->FoundState = s;
- symbol = s->Symbol;
- Ppmd8_Update1_0(p);
- return symbol;
- }
- p->PrevSuccess = 0;
- i = p->MinContext->NumStats;
- do
- {
- if ((hiCnt += (++s)->Freq) > count)
- {
- Byte symbol;
- RangeDec_Decode(p, hiCnt - s->Freq, s->Freq);
- p->FoundState = s;
- symbol = s->Symbol;
- Ppmd8_Update1(p);
- return symbol;
- }
- }
- while (--i);
- if (count >= p->MinContext->SummFreq)
- return -2;
- RangeDec_Decode(p, hiCnt, p->MinContext->SummFreq - hiCnt);
- PPMD_SetAllBitsIn256Bytes(charMask);
- MASK(s->Symbol) = 0;
- i = p->MinContext->NumStats;
- do { MASK((--s)->Symbol) = 0; } while (--i);
- }
- else
- {
- UInt16 *prob = Ppmd8_GetBinSumm(p);
- if (((p->Code / (p->Range >>= 14)) < *prob))
- {
- Byte symbol;
- RangeDec_Decode(p, 0, *prob);
- *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
- symbol = (p->FoundState = Ppmd8Context_OneState(p->MinContext))->Symbol;
- Ppmd8_UpdateBin(p);
- return symbol;
- }
- RangeDec_Decode(p, *prob, (1 << 14) - *prob);
- *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
- p->InitEsc = PPMD8_kExpEscape[*prob >> 10];
- PPMD_SetAllBitsIn256Bytes(charMask);
- MASK(Ppmd8Context_OneState(p->MinContext)->Symbol) = 0;
- p->PrevSuccess = 0;
- }
- for (;;)
- {
- CPpmd_State *ps[256], *s;
- UInt32 freqSum, count, hiCnt;
- CPpmd_See *see;
- unsigned i, num, numMasked = p->MinContext->NumStats;
- do
- {
- p->OrderFall++;
- if (!p->MinContext->Suffix)
- return -1;
- p->MinContext = Ppmd8_GetContext(p, p->MinContext->Suffix);
- }
- while (p->MinContext->NumStats == numMasked);
- hiCnt = 0;
- s = Ppmd8_GetStats(p, p->MinContext);
- i = 0;
- num = p->MinContext->NumStats - numMasked;
- do
- {
- int k = (int)(MASK(s->Symbol));
- hiCnt += (s->Freq & k);
- ps[i] = s++;
- i -= k;
- }
- while (i != num);
-
- see = Ppmd8_MakeEscFreq(p, numMasked, &freqSum);
- freqSum += hiCnt;
- count = RangeDec_GetThreshold(p, freqSum);
-
- if (count < hiCnt)
- {
- Byte symbol;
- CPpmd_State **pps = ps;
- for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++);
- s = *pps;
- RangeDec_Decode(p, hiCnt - s->Freq, s->Freq);
- Ppmd_See_Update(see);
- p->FoundState = s;
- symbol = s->Symbol;
- Ppmd8_Update2(p);
- return symbol;
- }
- if (count >= freqSum)
- return -2;
- RangeDec_Decode(p, hiCnt, freqSum - hiCnt);
- see->Summ = (UInt16)(see->Summ + freqSum);
- do { MASK(ps[--i]->Symbol) = 0; } while (i != 0);
- }
-}
-
-/* H->I changes:
- NS2Indx
- GlewCount, and Glue method
- BinSum
- See / EscFreq
- CreateSuccessors updates more suffix contexts
- UpdateModel consts.
- PrevSuccess Update
-*/
-
-const IPpmd8 __archive_ppmd8_functions =
-{
- &Ppmd8_Construct,
- &Ppmd8_Alloc,
- &Ppmd8_Free,
- &Ppmd8_Init,
- &Ppmd8_RangeDec_Init,
- &Ppmd8_DecodeSymbol,
-};
diff --git a/contrib/libs/libarchive/libarchive/archive_ppmd8_private.h b/contrib/libs/libarchive/libarchive/archive_ppmd8_private.h
deleted file mode 100644
index 454b75f41f..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_ppmd8_private.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/* Ppmd8.h -- PPMdI codec
-2011-01-27 : Igor Pavlov : Public domain
-This code is based on:
- PPMd var.I (2002): Dmitry Shkarin : Public domain
- Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
-
-#ifndef ARCHIVE_PPMD8_PRIVATE_H_INCLUDED
-#define ARCHIVE_PPMD8_PRIVATE_H_INCLUDED
-
-#include "archive_ppmd_private.h"
-
-#define PPMD8_MIN_ORDER 2
-#define PPMD8_MAX_ORDER 16
-
-struct CPpmd8_Context_;
-
-typedef
- #ifdef PPMD_32BIT
- struct CPpmd8_Context_ *
- #else
- UInt32
- #endif
- CPpmd8_Context_Ref;
-
-#pragma pack(push, 1)
-
-typedef struct CPpmd8_Context_
-{
- Byte NumStats;
- Byte Flags;
- UInt16 SummFreq;
- CPpmd_State_Ref Stats;
- CPpmd8_Context_Ref Suffix;
-} CPpmd8_Context;
-
-#pragma pack(pop)
-
-#define Ppmd8Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
-
-/* The BUG in Shkarin's code for FREEZE mode was fixed, but that fixed
- code is not compatible with original code for some files compressed
- in FREEZE mode. So we disable FREEZE mode support. */
-
-enum
-{
- PPMD8_RESTORE_METHOD_RESTART,
- PPMD8_RESTORE_METHOD_CUT_OFF
- #ifdef PPMD8_FREEZE_SUPPORT
- , PPMD8_RESTORE_METHOD_FREEZE
- #endif
-};
-
-typedef struct
-{
- CPpmd8_Context *MinContext, *MaxContext;
- CPpmd_State *FoundState;
- unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder;
- Int32 RunLength, InitRL; /* must be 32-bit at least */
-
- UInt32 Size;
- UInt32 GlueCount;
- Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
- UInt32 AlignOffset;
- unsigned RestoreMethod;
-
- /* Range Coder */
- UInt32 Range;
- UInt32 Code;
- UInt32 Low;
- union
- {
- IByteIn *In;
- IByteOut *Out;
- } Stream;
-
- Byte Indx2Units[PPMD_NUM_INDEXES];
- Byte Units2Indx[128];
- CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
- UInt32 Stamps[PPMD_NUM_INDEXES];
-
- Byte NS2BSIndx[256], NS2Indx[260];
- CPpmd_See DummySee, See[24][32];
- UInt16 BinSumm[25][64];
-} CPpmd8;
-
-void Ppmd8_Construct(CPpmd8 *p);
-Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size);
-void Ppmd8_Free(CPpmd8 *p);
-void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod);
-#define Ppmd8_WasAllocated(p) ((p)->Base != NULL)
-
-
-/* ---------- Internal Functions ---------- */
-
-extern const Byte PPMD8_kExpEscape[16];
-
-#ifdef PPMD_32BIT
- #define Ppmd8_GetPtr(p, ptr) (ptr)
- #define Ppmd8_GetContext(p, ptr) (ptr)
- #define Ppmd8_GetStats(p, ctx) ((ctx)->Stats)
-#else
- #define Ppmd8_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
- #define Ppmd8_GetContext(p, offs) ((CPpmd8_Context *)Ppmd8_GetPtr((p), (offs)))
- #define Ppmd8_GetStats(p, ctx) ((CPpmd_State *)Ppmd8_GetPtr((p), ((ctx)->Stats)))
-#endif
-
-void Ppmd8_Update1(CPpmd8 *p);
-void Ppmd8_Update1_0(CPpmd8 *p);
-void Ppmd8_Update2(CPpmd8 *p);
-void Ppmd8_UpdateBin(CPpmd8 *p);
-
-#define Ppmd8_GetBinSumm(p) \
- &p->BinSumm[p->NS2Indx[Ppmd8Context_OneState(p->MinContext)->Freq - 1]][ \
- p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \
- p->PrevSuccess + p->MinContext->Flags + ((p->RunLength >> 26) & 0x20)]
-
-CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked, UInt32 *scale);
-
-
-/* ---------- Decode ---------- */
-
-Bool Ppmd8_RangeDec_Init(CPpmd8 *p);
-#define Ppmd8_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
-int Ppmd8_DecodeSymbol(CPpmd8 *p); /* returns: -1 as EndMarker, -2 as DataError */
-
-/* ---------- Encode ---------- */
-
-#define Ppmd8_RangeEnc_Init(p) { (p)->Low = 0; (p)->Range = 0xFFFFFFFF; }
-void Ppmd8_RangeEnc_FlushData(CPpmd8 *p);
-void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol); /* symbol = -1 means EndMarker */
-
-typedef struct
-{
- /* Base Functions */
- void (*Ppmd8_Construct)(CPpmd8 *p);
- Bool (*Ppmd8_Alloc)(CPpmd8 *p, UInt32 size);
- void (*Ppmd8_Free)(CPpmd8 *p);
- void (*Ppmd8_Init)(CPpmd8 *p, unsigned max_order, unsigned restore_method);
- #define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
-
- /* Decode Functions */
- int (*Ppmd8_RangeDec_Init)(CPpmd8 *p);
- int (*Ppmd8_DecodeSymbol)(CPpmd8 *p);
-} IPpmd8;
-
-extern const IPpmd8 __archive_ppmd8_functions;
-
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_ppmd_private.h b/contrib/libs/libarchive/libarchive/archive_ppmd_private.h
deleted file mode 100644
index 582803e5fd..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_ppmd_private.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/* Ppmd.h -- PPMD codec common code
-2010-03-12 : Igor Pavlov : Public domain
-This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
-
-#ifndef ARCHIVE_PPMD_PRIVATE_H_INCLUDED
-#define ARCHIVE_PPMD_PRIVATE_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
-#include <stddef.h>
-
-#include "archive_read_private.h"
-
-/*** Begin defined in Types.h ***/
-
-#if !defined(ZCONF_H)
-typedef unsigned char Byte;
-#endif
-typedef short Int16;
-typedef unsigned short UInt16;
-
-#ifdef _LZMA_UINT32_IS_ULONG
-typedef long Int32;
-typedef unsigned long UInt32;
-#else
-typedef int Int32;
-typedef unsigned int UInt32;
-#endif
-
-#ifdef _SZ_NO_INT_64
-
-/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
- NOTES: Some code will work incorrectly in that case! */
-
-typedef long Int64;
-typedef unsigned long UInt64;
-
-#else
-
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-typedef __int64 Int64;
-typedef unsigned __int64 UInt64;
-#define UINT64_CONST(n) n
-#else
-typedef long long int Int64;
-typedef unsigned long long int UInt64;
-#define UINT64_CONST(n) n ## ULL
-#endif
-
-#endif
-
-typedef int Bool;
-#define True 1
-#define False 0
-
-/* The following interfaces use first parameter as pointer to structure */
-
-typedef struct
-{
- struct archive_read *a;
- Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
-} IByteIn;
-
-typedef struct
-{
- struct archive_write *a;
- void (*Write)(void *p, Byte b);
-} IByteOut;
-
-/*** End defined in Types.h ***/
-/*** Begin defined in CpuArch.h ***/
-
-#if defined(_M_IX86) || defined(__i386__)
-#define MY_CPU_X86
-#endif
-
-#if defined(MY_CPU_X86) || defined(_M_ARM)
-#define MY_CPU_32BIT
-#endif
-
-#ifdef MY_CPU_32BIT
-#define PPMD_32BIT
-#endif
-
-/*** End defined in CpuArch.h ***/
-
-#define PPMD_INT_BITS 7
-#define PPMD_PERIOD_BITS 7
-#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS))
-
-#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift))
-#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2)
-#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob))
-#define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob))
-
-#define PPMD_N1 4
-#define PPMD_N2 4
-#define PPMD_N3 4
-#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4)
-#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4)
-
-/* SEE-contexts for PPM-contexts with masked symbols */
-typedef struct
-{
- UInt16 Summ; /* Freq */
- Byte Shift; /* Speed of Freq change; low Shift is for fast change */
- Byte Count; /* Count to next change of Shift */
-} CPpmd_See;
-
-#define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \
- { (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); }
-
-typedef struct
-{
- Byte Symbol;
- Byte Freq;
- UInt16 SuccessorLow;
- UInt16 SuccessorHigh;
-} CPpmd_State;
-
-typedef
- #ifdef PPMD_32BIT
- CPpmd_State *
- #else
- UInt32
- #endif
- CPpmd_State_Ref;
-
-typedef
- #ifdef PPMD_32BIT
- void *
- #else
- UInt32
- #endif
- CPpmd_Void_Ref;
-
-typedef
- #ifdef PPMD_32BIT
- Byte *
- #else
- UInt32
- #endif
- CPpmd_Byte_Ref;
-
-#define PPMD_SetAllBitsIn256Bytes(p) \
- { unsigned j; for (j = 0; j < 256 / sizeof(p[0]); j += 8) { \
- p[j+7] = p[j+6] = p[j+5] = p[j+4] = p[j+3] = p[j+2] = p[j+1] = p[j+0] = ~(size_t)0; }}
-
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_private.h b/contrib/libs/libarchive/libarchive/archive_private.h
deleted file mode 100644
index b2a2cda250..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_private.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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.
- *
- * $FreeBSD: head/lib/libarchive/archive_private.h 201098 2009-12-28 02:58:14Z kientzle $
- */
-
-#ifndef ARCHIVE_PRIVATE_H_INCLUDED
-#define ARCHIVE_PRIVATE_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
-#if HAVE_ICONV_H
-#include <iconv.h>
-#endif
-
-#include "archive.h"
-#include "archive_string.h"
-
-#if defined(__GNUC__) && (__GNUC__ > 2 || \
- (__GNUC__ == 2 && __GNUC_MINOR__ >= 5))
-#define __LA_DEAD __attribute__((__noreturn__))
-#else
-#define __LA_DEAD
-#endif
-
-#if defined(__GNUC__) && (__GNUC__ > 2 || \
- (__GNUC__ == 2 && __GNUC_MINOR__ >= 7))
-#define __LA_UNUSED __attribute__((__unused__))
-#else
-#define __LA_UNUSED
-#endif
-
-#define ARCHIVE_WRITE_MAGIC (0xb0c5c0deU)
-#define ARCHIVE_READ_MAGIC (0xdeb0c5U)
-#define ARCHIVE_WRITE_DISK_MAGIC (0xc001b0c5U)
-#define ARCHIVE_READ_DISK_MAGIC (0xbadb0c5U)
-#define ARCHIVE_MATCH_MAGIC (0xcad11c9U)
-
-#define ARCHIVE_STATE_NEW 1U
-#define ARCHIVE_STATE_HEADER 2U
-#define ARCHIVE_STATE_DATA 4U
-#define ARCHIVE_STATE_EOF 0x10U
-#define ARCHIVE_STATE_CLOSED 0x20U
-#define ARCHIVE_STATE_FATAL 0x8000U
-#define ARCHIVE_STATE_ANY (0xFFFFU & ~ARCHIVE_STATE_FATAL)
-
-struct archive_vtable {
- int (*archive_close)(struct archive *);
- int (*archive_free)(struct archive *);
- int (*archive_write_header)(struct archive *,
- struct archive_entry *);
- int (*archive_write_finish_entry)(struct archive *);
- ssize_t (*archive_write_data)(struct archive *,
- const void *, size_t);
- ssize_t (*archive_write_data_block)(struct archive *,
- const void *, size_t, int64_t);
-
- int (*archive_read_next_header)(struct archive *,
- struct archive_entry **);
- int (*archive_read_next_header2)(struct archive *,
- struct archive_entry *);
- int (*archive_read_data_block)(struct archive *,
- const void **, size_t *, int64_t *);
-
- int (*archive_filter_count)(struct archive *);
- int64_t (*archive_filter_bytes)(struct archive *, int);
- int (*archive_filter_code)(struct archive *, int);
- const char * (*archive_filter_name)(struct archive *, int);
-};
-
-struct archive_string_conv;
-
-struct archive {
- /*
- * The magic/state values are used to sanity-check the
- * client's usage. If an API function is called at a
- * ridiculous time, or the client passes us an invalid
- * pointer, these values allow me to catch that.
- */
- unsigned int magic;
- unsigned int state;
-
- /*
- * Some public API functions depend on the "real" type of the
- * archive object.
- */
- const struct archive_vtable *vtable;
-
- int archive_format;
- const char *archive_format_name;
-
- /* Number of file entries processed. */
- int file_count;
-
- int archive_error_number;
- const char *error;
- struct archive_string error_string;
-
- char *current_code;
- unsigned current_codepage; /* Current ACP(ANSI CodePage). */
- unsigned current_oemcp; /* Current OEMCP(OEM CodePage). */
- struct archive_string_conv *sconv;
-
- /*
- * Used by archive_read_data() to track blocks and copy
- * data to client buffers, filling gaps with zero bytes.
- */
- const char *read_data_block;
- int64_t read_data_offset;
- int64_t read_data_output_offset;
- size_t read_data_remaining;
-
- /*
- * Used by formats/filters to determine the amount of data
- * requested from a call to archive_read_data(). This is only
- * useful when the format/filter has seek support.
- */
- char read_data_is_posix_read;
- size_t read_data_requested;
-};
-
-/* Check magic value and state; return(ARCHIVE_FATAL) if it isn't valid. */
-int __archive_check_magic(struct archive *, unsigned int magic,
- unsigned int state, const char *func);
-#define archive_check_magic(a, expected_magic, allowed_states, function_name) \
- do { \
- int magic_test = __archive_check_magic((a), (expected_magic), \
- (allowed_states), (function_name)); \
- if (magic_test == ARCHIVE_FATAL) \
- return ARCHIVE_FATAL; \
- } while (0)
-
-void __archive_errx(int retvalue, const char *msg) __LA_DEAD;
-
-void __archive_ensure_cloexec_flag(int fd);
-int __archive_mktemp(const char *tmpdir);
-#if defined(_WIN32) && !defined(__CYGWIN__)
-int __archive_mkstemp(wchar_t *template);
-#else
-int __archive_mkstemp(char *template);
-#endif
-
-int __archive_clean(struct archive *);
-
-void __archive_reset_read_data(struct archive *);
-
-#define err_combine(a,b) ((a) < (b) ? (a) : (b))
-
-#if defined(__BORLANDC__) || (defined(_MSC_VER) && _MSC_VER <= 1300)
-# define ARCHIVE_LITERAL_LL(x) x##i64
-# define ARCHIVE_LITERAL_ULL(x) x##ui64
-#else
-# define ARCHIVE_LITERAL_LL(x) x##ll
-# define ARCHIVE_LITERAL_ULL(x) x##ull
-#endif
-
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_random.c b/contrib/libs/libarchive/libarchive/archive_random.c
deleted file mode 100644
index 301765acd8..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_random.c
+++ /dev/null
@@ -1,301 +0,0 @@
-/*-
- * Copyright (c) 2014 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#if !defined(HAVE_ARC4RANDOM_BUF) && (!defined(_WIN32) || defined(__CYGWIN__))
-
-#ifdef HAVE_FCNTL
-#include <fcntl.h>
-#endif
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
-
-static void la_arc4random_buf(void *, size_t);
-
-#endif /* HAVE_ARC4RANDOM_BUF */
-
-#include "archive.h"
-#include "archive_random_private.h"
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
-/* don't use bcrypt when XP needs to be supported */
-#include <bcrypt.h>
-
-/* Common in other bcrypt implementations, but missing from VS2008. */
-#ifndef BCRYPT_SUCCESS
-#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
-#endif
-
-#elif defined(HAVE_WINCRYPT_H)
-#include <wincrypt.h>
-#endif
-#endif
-
-#ifndef O_CLOEXEC
-#define O_CLOEXEC 0
-#endif
-
-/*
- * Random number generator function.
- * This simply calls arc4random_buf function if the platform provides it.
- */
-
-int
-archive_random(void *buf, size_t nbytes)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
-# if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
- NTSTATUS status;
- BCRYPT_ALG_HANDLE hAlg;
-
- status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM, NULL, 0);
- if (!BCRYPT_SUCCESS(status))
- return ARCHIVE_FAILED;
- status = BCryptGenRandom(hAlg, buf, nbytes, 0);
- BCryptCloseAlgorithmProvider(hAlg, 0);
- if (!BCRYPT_SUCCESS(status))
- return ARCHIVE_FAILED;
-
- return ARCHIVE_OK;
-# else
- HCRYPTPROV hProv;
- BOOL success;
-
- success = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT);
- if (!success && GetLastError() == (DWORD)NTE_BAD_KEYSET) {
- success = CryptAcquireContext(&hProv, NULL, NULL,
- PROV_RSA_FULL, CRYPT_NEWKEYSET);
- }
- if (success) {
- success = CryptGenRandom(hProv, (DWORD)nbytes, (BYTE*)buf);
- CryptReleaseContext(hProv, 0);
- if (success)
- return ARCHIVE_OK;
- }
- /* TODO: Does this case really happen? */
- return ARCHIVE_FAILED;
-# endif
-#elif !defined(HAVE_ARC4RANDOM_BUF) && (!defined(_WIN32) || defined(__CYGWIN__))
- la_arc4random_buf(buf, nbytes);
- return ARCHIVE_OK;
-#else
- arc4random_buf(buf, nbytes);
- return ARCHIVE_OK;
-#endif
-}
-
-#if !defined(HAVE_ARC4RANDOM_BUF) && (!defined(_WIN32) || defined(__CYGWIN__))
-
-/* $OpenBSD: arc4random.c,v 1.24 2013/06/11 16:59:50 deraadt Exp $ */
-/*
- * Copyright (c) 1996, David Mazieres <dm@uun.org>
- * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * Arc4 random number generator for OpenBSD.
- *
- * This code is derived from section 17.1 of Applied Cryptography,
- * second edition, which describes a stream cipher allegedly
- * compatible with RSA Labs "RC4" cipher (the actual description of
- * which is a trade secret). The same algorithm is used as a stream
- * cipher called "arcfour" in Tatu Ylonen's ssh package.
- *
- * RC4 is a registered trademark of RSA Laboratories.
- */
-
-#ifdef __GNUC__
-#define inline __inline
-#else /* !__GNUC__ */
-#define inline
-#endif /* !__GNUC__ */
-
-struct arc4_stream {
- uint8_t i;
- uint8_t j;
- uint8_t s[256];
-};
-
-#define RANDOMDEV "/dev/urandom"
-#define KEYSIZE 128
-#ifdef HAVE_PTHREAD_H
-static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
-#define _ARC4_LOCK() pthread_mutex_lock(&arc4random_mtx);
-#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx);
-#else
-#define _ARC4_LOCK()
-#define _ARC4_UNLOCK()
-#endif
-
-static int rs_initialized;
-static struct arc4_stream rs;
-static pid_t arc4_stir_pid;
-static int arc4_count;
-
-static inline uint8_t arc4_getbyte(void);
-static void arc4_stir(void);
-
-static inline void
-arc4_init(void)
-{
- int n;
-
- for (n = 0; n < 256; n++)
- rs.s[n] = n;
- rs.i = 0;
- rs.j = 0;
-}
-
-static inline void
-arc4_addrandom(uint8_t *dat, int datlen)
-{
- int n;
- uint8_t si;
-
- rs.i--;
- for (n = 0; n < 256; n++) {
- rs.i = (rs.i + 1);
- si = rs.s[rs.i];
- rs.j = (rs.j + si + dat[n % datlen]);
- rs.s[rs.i] = rs.s[rs.j];
- rs.s[rs.j] = si;
- }
- rs.j = rs.i;
-}
-
-static void
-arc4_stir(void)
-{
- int done, fd, i;
- struct {
- struct timeval tv;
- pid_t pid;
- uint8_t rnd[KEYSIZE];
- } rdat;
-
- if (!rs_initialized) {
- arc4_init();
- rs_initialized = 1;
- }
- done = 0;
- fd = open(RANDOMDEV, O_RDONLY | O_CLOEXEC, 0);
- if (fd >= 0) {
- if (read(fd, &rdat, KEYSIZE) == KEYSIZE)
- done = 1;
- (void)close(fd);
- }
- if (!done) {
- (void)gettimeofday(&rdat.tv, NULL);
- rdat.pid = getpid();
- /* We'll just take whatever was on the stack too... */
- }
-
- arc4_addrandom((uint8_t *)&rdat, KEYSIZE);
-
- /*
- * Discard early keystream, as per recommendations in:
- * "(Not So) Random Shuffles of RC4" by Ilya Mironov.
- * As per the Network Operations Division, cryptographic requirements
- * published on wikileaks on March 2017.
- */
-
- for (i = 0; i < 3072; i++)
- (void)arc4_getbyte();
- arc4_count = 1600000;
-}
-
-static void
-arc4_stir_if_needed(void)
-{
- pid_t pid = getpid();
-
- if (arc4_count <= 0 || !rs_initialized || arc4_stir_pid != pid) {
- arc4_stir_pid = pid;
- arc4_stir();
- }
-}
-
-static inline uint8_t
-arc4_getbyte(void)
-{
- uint8_t si, sj;
-
- rs.i = (rs.i + 1);
- si = rs.s[rs.i];
- rs.j = (rs.j + si);
- sj = rs.s[rs.j];
- rs.s[rs.i] = sj;
- rs.s[rs.j] = si;
- return (rs.s[(si + sj) & 0xff]);
-}
-
-static void
-la_arc4random_buf(void *_buf, size_t n)
-{
- uint8_t *buf = (uint8_t *)_buf;
- _ARC4_LOCK();
- arc4_stir_if_needed();
- while (n--) {
- if (--arc4_count <= 0)
- arc4_stir();
- buf[n] = arc4_getbyte();
- }
- _ARC4_UNLOCK();
-}
-
-#endif /* !HAVE_ARC4RANDOM_BUF */
diff --git a/contrib/libs/libarchive/libarchive/archive_random_private.h b/contrib/libs/libarchive/libarchive/archive_random_private.h
deleted file mode 100644
index 08b91b3b7a..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_random_private.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*-
- * Copyright (c) 2014 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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.
- */
-
-#ifndef ARCHIVE_RANDOM_PRIVATE_H_INCLUDED
-#define ARCHIVE_RANDOM_PRIVATE_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
-/* Random number generator. */
-int archive_random(void *buf, size_t nbytes);
-
-#endif /* ARCHIVE_RANDOM_PRIVATE_H_INCLUDED */
diff --git a/contrib/libs/libarchive/libarchive/archive_rb.c b/contrib/libs/libarchive/libarchive/archive_rb.c
deleted file mode 100644
index cf58ac3354..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_rb.c
+++ /dev/null
@@ -1,709 +0,0 @@
-/*-
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Matt Thomas <matt@3am-software.com>.
- *
- * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
- *
- * Based on: NetBSD: rb.c,v 1.6 2010/04/30 13:58:09 joerg Exp
- */
-
-#include "archive_platform.h"
-
-#include <stddef.h>
-
-#include "archive_rb.h"
-
-/* Keep in sync with archive_rb.h */
-#define RB_DIR_LEFT 0
-#define RB_DIR_RIGHT 1
-#define RB_DIR_OTHER 1
-#define rb_left rb_nodes[RB_DIR_LEFT]
-#define rb_right rb_nodes[RB_DIR_RIGHT]
-
-#define RB_FLAG_POSITION 0x2
-#define RB_FLAG_RED 0x1
-#define RB_FLAG_MASK (RB_FLAG_POSITION|RB_FLAG_RED)
-#define RB_FATHER(rb) \
- ((struct archive_rb_node *)((rb)->rb_info & ~RB_FLAG_MASK))
-#define RB_SET_FATHER(rb, father) \
- ((void)((rb)->rb_info = (uintptr_t)(father)|((rb)->rb_info & RB_FLAG_MASK)))
-
-#define RB_SENTINEL_P(rb) ((rb) == NULL)
-#define RB_LEFT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_left)
-#define RB_RIGHT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_right)
-#define RB_FATHER_SENTINEL_P(rb) RB_SENTINEL_P(RB_FATHER((rb)))
-#define RB_CHILDLESS_P(rb) \
- (RB_SENTINEL_P(rb) || (RB_LEFT_SENTINEL_P(rb) && RB_RIGHT_SENTINEL_P(rb)))
-#define RB_TWOCHILDREN_P(rb) \
- (!RB_SENTINEL_P(rb) && !RB_LEFT_SENTINEL_P(rb) && !RB_RIGHT_SENTINEL_P(rb))
-
-#define RB_POSITION(rb) \
- (((rb)->rb_info & RB_FLAG_POSITION) ? RB_DIR_RIGHT : RB_DIR_LEFT)
-#define RB_RIGHT_P(rb) (RB_POSITION(rb) == RB_DIR_RIGHT)
-#define RB_LEFT_P(rb) (RB_POSITION(rb) == RB_DIR_LEFT)
-#define RB_RED_P(rb) (!RB_SENTINEL_P(rb) && ((rb)->rb_info & RB_FLAG_RED) != 0)
-#define RB_BLACK_P(rb) (RB_SENTINEL_P(rb) || ((rb)->rb_info & RB_FLAG_RED) == 0)
-#define RB_MARK_RED(rb) ((void)((rb)->rb_info |= RB_FLAG_RED))
-#define RB_MARK_BLACK(rb) ((void)((rb)->rb_info &= ~RB_FLAG_RED))
-#define RB_INVERT_COLOR(rb) ((void)((rb)->rb_info ^= RB_FLAG_RED))
-#define RB_ROOT_P(rbt, rb) ((rbt)->rbt_root == (rb))
-#define RB_SET_POSITION(rb, position) \
- ((void)((position) ? ((rb)->rb_info |= RB_FLAG_POSITION) : \
- ((rb)->rb_info &= ~RB_FLAG_POSITION)))
-#define RB_ZERO_PROPERTIES(rb) ((void)((rb)->rb_info &= ~RB_FLAG_MASK))
-#define RB_COPY_PROPERTIES(dst, src) \
- ((void)((dst)->rb_info ^= ((dst)->rb_info ^ (src)->rb_info) & RB_FLAG_MASK))
-#define RB_SWAP_PROPERTIES(a, b) do { \
- uintptr_t xorinfo = ((a)->rb_info ^ (b)->rb_info) & RB_FLAG_MASK; \
- (a)->rb_info ^= xorinfo; \
- (b)->rb_info ^= xorinfo; \
- } while (/*CONSTCOND*/ 0)
-
-static void __archive_rb_tree_insert_rebalance(struct archive_rb_tree *,
- struct archive_rb_node *);
-static void __archive_rb_tree_removal_rebalance(struct archive_rb_tree *,
- struct archive_rb_node *, unsigned int);
-
-#define RB_SENTINEL_NODE NULL
-
-#define T 1
-#define F 0
-
-void
-__archive_rb_tree_init(struct archive_rb_tree *rbt,
- const struct archive_rb_tree_ops *ops)
-{
- rbt->rbt_ops = ops;
- *((struct archive_rb_node **)&rbt->rbt_root) = RB_SENTINEL_NODE;
-}
-
-struct archive_rb_node *
-__archive_rb_tree_find_node(struct archive_rb_tree *rbt, const void *key)
-{
- archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key;
- struct archive_rb_node *parent = rbt->rbt_root;
-
- while (!RB_SENTINEL_P(parent)) {
- const signed int diff = (*compare_key)(parent, key);
- if (diff == 0)
- return parent;
- parent = parent->rb_nodes[diff > 0];
- }
-
- return NULL;
-}
-
-struct archive_rb_node *
-__archive_rb_tree_find_node_geq(struct archive_rb_tree *rbt, const void *key)
-{
- archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key;
- struct archive_rb_node *parent = rbt->rbt_root;
- struct archive_rb_node *last = NULL;
-
- while (!RB_SENTINEL_P(parent)) {
- const signed int diff = (*compare_key)(parent, key);
- if (diff == 0)
- return parent;
- if (diff < 0)
- last = parent;
- parent = parent->rb_nodes[diff > 0];
- }
-
- return last;
-}
-
-struct archive_rb_node *
-__archive_rb_tree_find_node_leq(struct archive_rb_tree *rbt, const void *key)
-{
- archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key;
- struct archive_rb_node *parent = rbt->rbt_root;
- struct archive_rb_node *last = NULL;
-
- while (!RB_SENTINEL_P(parent)) {
- const signed int diff = (*compare_key)(parent, key);
- if (diff == 0)
- return parent;
- if (diff > 0)
- last = parent;
- parent = parent->rb_nodes[diff > 0];
- }
-
- return last;
-}
-
-int
-__archive_rb_tree_insert_node(struct archive_rb_tree *rbt,
- struct archive_rb_node *self)
-{
- archive_rbto_compare_nodes_fn compare_nodes = rbt->rbt_ops->rbto_compare_nodes;
- struct archive_rb_node *parent, *tmp;
- unsigned int position;
- int rebalance;
-
- tmp = rbt->rbt_root;
- /*
- * This is a hack. Because rbt->rbt_root is just a
- * struct archive_rb_node *, just like rb_node->rb_nodes[RB_DIR_LEFT],
- * we can use this fact to avoid a lot of tests for root and know
- * that even at root, updating
- * RB_FATHER(rb_node)->rb_nodes[RB_POSITION(rb_node)] will
- * update rbt->rbt_root.
- */
- parent = (struct archive_rb_node *)(void *)&rbt->rbt_root;
- position = RB_DIR_LEFT;
-
- /*
- * Find out where to place this new leaf.
- */
- while (!RB_SENTINEL_P(tmp)) {
- const signed int diff = (*compare_nodes)(tmp, self);
- if (diff == 0) {
- /*
- * Node already exists; don't insert.
- */
- return F;
- }
- parent = tmp;
- position = (diff > 0);
- tmp = parent->rb_nodes[position];
- }
-
- /*
- * Initialize the node and insert as a leaf into the tree.
- */
- RB_SET_FATHER(self, parent);
- RB_SET_POSITION(self, position);
- if (parent == (struct archive_rb_node *)(void *)&rbt->rbt_root) {
- RB_MARK_BLACK(self); /* root is always black */
- rebalance = F;
- } else {
- /*
- * All new nodes are colored red. We only need to rebalance
- * if our parent is also red.
- */
- RB_MARK_RED(self);
- rebalance = RB_RED_P(parent);
- }
- self->rb_left = parent->rb_nodes[position];
- self->rb_right = parent->rb_nodes[position];
- parent->rb_nodes[position] = self;
-
- /*
- * Rebalance tree after insertion
- */
- if (rebalance)
- __archive_rb_tree_insert_rebalance(rbt, self);
-
- return T;
-}
-
-/*
- * Swap the location and colors of 'self' and its child @ which. The child
- * can not be a sentinel node. This is our rotation function. However,
- * since it preserves coloring, it great simplifies both insertion and
- * removal since rotation almost always involves the exchanging of colors
- * as a separate step.
- */
-/*ARGSUSED*/
-static void
-__archive_rb_tree_reparent_nodes(
- struct archive_rb_node *old_father, const unsigned int which)
-{
- const unsigned int other = which ^ RB_DIR_OTHER;
- struct archive_rb_node * const grandpa = RB_FATHER(old_father);
- struct archive_rb_node * const old_child = old_father->rb_nodes[which];
- struct archive_rb_node * const new_father = old_child;
- struct archive_rb_node * const new_child = old_father;
-
- if (new_father == NULL)
- return;
- /*
- * Exchange descendant linkages.
- */
- grandpa->rb_nodes[RB_POSITION(old_father)] = new_father;
- new_child->rb_nodes[which] = old_child->rb_nodes[other];
- new_father->rb_nodes[other] = new_child;
-
- /*
- * Update ancestor linkages
- */
- RB_SET_FATHER(new_father, grandpa);
- RB_SET_FATHER(new_child, new_father);
-
- /*
- * Exchange properties between new_father and new_child. The only
- * change is that new_child's position is now on the other side.
- */
- RB_SWAP_PROPERTIES(new_father, new_child);
- RB_SET_POSITION(new_child, other);
-
- /*
- * Make sure to reparent the new child to ourself.
- */
- if (!RB_SENTINEL_P(new_child->rb_nodes[which])) {
- RB_SET_FATHER(new_child->rb_nodes[which], new_child);
- RB_SET_POSITION(new_child->rb_nodes[which], which);
- }
-
-}
-
-static void
-__archive_rb_tree_insert_rebalance(struct archive_rb_tree *rbt,
- struct archive_rb_node *self)
-{
- struct archive_rb_node * father = RB_FATHER(self);
- struct archive_rb_node * grandpa;
- struct archive_rb_node * uncle;
- unsigned int which;
- unsigned int other;
-
- for (;;) {
- /*
- * We are red and our parent is red, therefore we must have a
- * grandfather and he must be black.
- */
- grandpa = RB_FATHER(father);
- which = (father == grandpa->rb_right);
- other = which ^ RB_DIR_OTHER;
- uncle = grandpa->rb_nodes[other];
-
- if (RB_BLACK_P(uncle))
- break;
-
- /*
- * Case 1: our uncle is red
- * Simply invert the colors of our parent and
- * uncle and make our grandparent red. And
- * then solve the problem up at his level.
- */
- RB_MARK_BLACK(uncle);
- RB_MARK_BLACK(father);
- if (RB_ROOT_P(rbt, grandpa)) {
- /*
- * If our grandpa is root, don't bother
- * setting him to red, just return.
- */
- return;
- }
- RB_MARK_RED(grandpa);
- self = grandpa;
- father = RB_FATHER(self);
- if (RB_BLACK_P(father)) {
- /*
- * If our great-grandpa is black, we're done.
- */
- return;
- }
- }
-
- /*
- * Case 2&3: our uncle is black.
- */
- if (self == father->rb_nodes[other]) {
- /*
- * Case 2: we are on the same side as our uncle
- * Swap ourselves with our parent so this case
- * becomes case 3. Basically our parent becomes our
- * child.
- */
- __archive_rb_tree_reparent_nodes(father, other);
- }
- /*
- * Case 3: we are opposite a child of a black uncle.
- * Swap our parent and grandparent. Since our grandfather
- * is black, our father will become black and our new sibling
- * (former grandparent) will become red.
- */
- __archive_rb_tree_reparent_nodes(grandpa, which);
-
- /*
- * Final step: Set the root to black.
- */
- RB_MARK_BLACK(rbt->rbt_root);
-}
-
-static void
-__archive_rb_tree_prune_node(struct archive_rb_tree *rbt,
- struct archive_rb_node *self, int rebalance)
-{
- const unsigned int which = RB_POSITION(self);
- struct archive_rb_node *father = RB_FATHER(self);
-
- /*
- * Since we are childless, we know that self->rb_left is pointing
- * to the sentinel node.
- */
- father->rb_nodes[which] = self->rb_left;
-
- /*
- * Rebalance if requested.
- */
- if (rebalance)
- __archive_rb_tree_removal_rebalance(rbt, father, which);
-}
-
-/*
- * When deleting an interior node
- */
-static void
-__archive_rb_tree_swap_prune_and_rebalance(struct archive_rb_tree *rbt,
- struct archive_rb_node *self, struct archive_rb_node *standin)
-{
- const unsigned int standin_which = RB_POSITION(standin);
- unsigned int standin_other = standin_which ^ RB_DIR_OTHER;
- struct archive_rb_node *standin_son;
- struct archive_rb_node *standin_father = RB_FATHER(standin);
- int rebalance = RB_BLACK_P(standin);
-
- if (standin_father == self) {
- /*
- * As a child of self, any children would be opposite of
- * our parent.
- */
- standin_son = standin->rb_nodes[standin_which];
- } else {
- /*
- * Since we aren't a child of self, any children would be
- * on the same side as our parent.
- */
- standin_son = standin->rb_nodes[standin_other];
- }
-
- if (RB_RED_P(standin_son)) {
- /*
- * We know we have a red child so if we flip it to black
- * we don't have to rebalance.
- */
- RB_MARK_BLACK(standin_son);
- rebalance = F;
-
- if (standin_father != self) {
- /*
- * Change the son's parentage to point to his grandpa.
- */
- RB_SET_FATHER(standin_son, standin_father);
- RB_SET_POSITION(standin_son, standin_which);
- }
- }
-
- if (standin_father == self) {
- /*
- * If we are about to delete the standin's father, then when
- * we call rebalance, we need to use ourselves as our father.
- * Otherwise remember our original father. Also, since we are
- * our standin's father we only need to reparent the standin's
- * brother.
- *
- * | R --> S |
- * | Q S --> Q T |
- * | t --> |
- *
- * Have our son/standin adopt his brother as his new son.
- */
- standin_father = standin;
- } else {
- /*
- * | R --> S . |
- * | / \ | T --> / \ | / |
- * | ..... | S --> ..... | T |
- *
- * Sever standin's connection to his father.
- */
- standin_father->rb_nodes[standin_which] = standin_son;
- /*
- * Adopt the far son.
- */
- standin->rb_nodes[standin_other] = self->rb_nodes[standin_other];
- RB_SET_FATHER(standin->rb_nodes[standin_other], standin);
- /*
- * Use standin_other because we need to preserve standin_which
- * for the removal_rebalance.
- */
- standin_other = standin_which;
- }
-
- /*
- * Move the only remaining son to our standin. If our standin is our
- * son, this will be the only son needed to be moved.
- */
- standin->rb_nodes[standin_other] = self->rb_nodes[standin_other];
- RB_SET_FATHER(standin->rb_nodes[standin_other], standin);
-
- /*
- * Now copy the result of self to standin and then replace
- * self with standin in the tree.
- */
- RB_COPY_PROPERTIES(standin, self);
- RB_SET_FATHER(standin, RB_FATHER(self));
- RB_FATHER(standin)->rb_nodes[RB_POSITION(standin)] = standin;
-
- if (rebalance)
- __archive_rb_tree_removal_rebalance(rbt, standin_father, standin_which);
-}
-
-/*
- * We could do this by doing
- * __archive_rb_tree_node_swap(rbt, self, which);
- * __archive_rb_tree_prune_node(rbt, self, F);
- *
- * But it's more efficient to just evaluate and recolor the child.
- */
-static void
-__archive_rb_tree_prune_blackred_branch(
- struct archive_rb_node *self, unsigned int which)
-{
- struct archive_rb_node *father = RB_FATHER(self);
- struct archive_rb_node *son = self->rb_nodes[which];
-
- /*
- * Remove ourselves from the tree and give our former child our
- * properties (position, color, root).
- */
- RB_COPY_PROPERTIES(son, self);
- father->rb_nodes[RB_POSITION(son)] = son;
- RB_SET_FATHER(son, father);
-}
-/*
- *
- */
-void
-__archive_rb_tree_remove_node(struct archive_rb_tree *rbt,
- struct archive_rb_node *self)
-{
- struct archive_rb_node *standin;
- unsigned int which;
-
- /*
- * In the following diagrams, we (the node to be removed) are S. Red
- * nodes are lowercase. T could be either red or black.
- *
- * Remember the major axiom of the red-black tree: the number of
- * black nodes from the root to each leaf is constant across all
- * leaves, only the number of red nodes varies.
- *
- * Thus removing a red leaf doesn't require any other changes to a
- * red-black tree. So if we must remove a node, attempt to rearrange
- * the tree so we can remove a red node.
- *
- * The simplest case is a childless red node or a childless root node:
- *
- * | T --> T | or | R --> * |
- * | s --> * |
- */
- if (RB_CHILDLESS_P(self)) {
- const int rebalance = RB_BLACK_P(self) && !RB_ROOT_P(rbt, self);
- __archive_rb_tree_prune_node(rbt, self, rebalance);
- return;
- }
- if (!RB_TWOCHILDREN_P(self)) {
- /*
- * The next simplest case is the node we are deleting is
- * black and has one red child.
- *
- * | T --> T --> T |
- * | S --> R --> R |
- * | r --> s --> * |
- */
- which = RB_LEFT_SENTINEL_P(self) ? RB_DIR_RIGHT : RB_DIR_LEFT;
- __archive_rb_tree_prune_blackred_branch(self, which);
- return;
- }
-
- /*
- * We invert these because we prefer to remove from the inside of
- * the tree.
- */
- which = RB_POSITION(self) ^ RB_DIR_OTHER;
-
- /*
- * Let's find the node closes to us opposite of our parent
- * Now swap it with ourself, "prune" it, and rebalance, if needed.
- */
- standin = __archive_rb_tree_iterate(rbt, self, which);
- __archive_rb_tree_swap_prune_and_rebalance(rbt, self, standin);
-}
-
-static void
-__archive_rb_tree_removal_rebalance(struct archive_rb_tree *rbt,
- struct archive_rb_node *parent, unsigned int which)
-{
-
- while (RB_BLACK_P(parent->rb_nodes[which])) {
- unsigned int other = which ^ RB_DIR_OTHER;
- struct archive_rb_node *brother = parent->rb_nodes[other];
-
- if (brother == NULL)
- return;/* The tree may be broken. */
- /*
- * For cases 1, 2a, and 2b, our brother's children must
- * be black and our father must be black
- */
- if (RB_BLACK_P(parent)
- && RB_BLACK_P(brother->rb_left)
- && RB_BLACK_P(brother->rb_right)) {
- if (RB_RED_P(brother)) {
- /*
- * Case 1: Our brother is red, swap its
- * position (and colors) with our parent.
- * This should now be case 2b (unless C or E
- * has a red child which is case 3; thus no
- * explicit branch to case 2b).
- *
- * B -> D
- * A d -> b E
- * C E -> A C
- */
- __archive_rb_tree_reparent_nodes(parent, other);
- brother = parent->rb_nodes[other];
- if (brother == NULL)
- return;/* The tree may be broken. */
- } else {
- /*
- * Both our parent and brother are black.
- * Change our brother to red, advance up rank
- * and go through the loop again.
- *
- * B -> *B
- * *A D -> A d
- * C E -> C E
- */
- RB_MARK_RED(brother);
- if (RB_ROOT_P(rbt, parent))
- return; /* root == parent == black */
- which = RB_POSITION(parent);
- parent = RB_FATHER(parent);
- continue;
- }
- }
- /*
- * Avoid an else here so that case 2a above can hit either
- * case 2b, 3, or 4.
- */
- if (RB_RED_P(parent)
- && RB_BLACK_P(brother)
- && RB_BLACK_P(brother->rb_left)
- && RB_BLACK_P(brother->rb_right)) {
- /*
- * We are black, our father is red, our brother and
- * both nephews are black. Simply invert/exchange the
- * colors of our father and brother (to black and red
- * respectively).
- *
- * | f --> F |
- * | * B --> * b |
- * | N N --> N N |
- */
- RB_MARK_BLACK(parent);
- RB_MARK_RED(brother);
- break; /* We're done! */
- } else {
- /*
- * Our brother must be black and have at least one
- * red child (it may have two).
- */
- if (RB_BLACK_P(brother->rb_nodes[other])) {
- /*
- * Case 3: our brother is black, our near
- * nephew is red, and our far nephew is black.
- * Swap our brother with our near nephew.
- * This result in a tree that matches case 4.
- * (Our father could be red or black).
- *
- * | F --> F |
- * | x B --> x B |
- * | n --> n |
- */
- __archive_rb_tree_reparent_nodes(brother, which);
- brother = parent->rb_nodes[other];
- }
- /*
- * Case 4: our brother is black and our far nephew
- * is red. Swap our father and brother locations and
- * change our far nephew to black. (these can be
- * done in either order so we change the color first).
- * The result is a valid red-black tree and is a
- * terminal case. (again we don't care about the
- * father's color)
- *
- * If the father is red, we will get a red-black-black
- * tree:
- * | f -> f --> b |
- * | B -> B --> F N |
- * | n -> N --> |
- *
- * If the father is black, we will get an all black
- * tree:
- * | F -> F --> B |
- * | B -> B --> F N |
- * | n -> N --> |
- *
- * If we had two red nephews, then after the swap,
- * our former father would have a red grandson.
- */
- if (brother->rb_nodes[other] == NULL)
- return;/* The tree may be broken. */
- RB_MARK_BLACK(brother->rb_nodes[other]);
- __archive_rb_tree_reparent_nodes(parent, other);
- break; /* We're done! */
- }
- }
-}
-
-struct archive_rb_node *
-__archive_rb_tree_iterate(struct archive_rb_tree *rbt,
- struct archive_rb_node *self, const unsigned int direction)
-{
- const unsigned int other = direction ^ RB_DIR_OTHER;
-
- if (self == NULL) {
- self = rbt->rbt_root;
- if (RB_SENTINEL_P(self))
- return NULL;
- while (!RB_SENTINEL_P(self->rb_nodes[direction]))
- self = self->rb_nodes[direction];
- return self;
- }
- /*
- * We can't go any further in this direction. We proceed up in the
- * opposite direction until our parent is in direction we want to go.
- */
- if (RB_SENTINEL_P(self->rb_nodes[direction])) {
- while (!RB_ROOT_P(rbt, self)) {
- if (other == (unsigned int)RB_POSITION(self))
- return RB_FATHER(self);
- self = RB_FATHER(self);
- }
- return NULL;
- }
-
- /*
- * Advance down one in current direction and go down as far as possible
- * in the opposite direction.
- */
- self = self->rb_nodes[direction];
- while (!RB_SENTINEL_P(self->rb_nodes[other]))
- self = self->rb_nodes[other];
- return self;
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_rb.h b/contrib/libs/libarchive/libarchive/archive_rb.h
deleted file mode 100644
index 8851f10818..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_rb.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*-
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Matt Thomas <matt@3am-software.com>.
- *
- * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
- *
- * Based on NetBSD: rb.h,v 1.13 2009/08/16 10:57:01 yamt Exp
- */
-
-#ifndef ARCHIVE_RB_H_INCLUDED
-#define ARCHIVE_RB_H_INCLUDED
-
-struct archive_rb_node {
- struct archive_rb_node *rb_nodes[2];
- /*
- * rb_info contains the two flags and the parent back pointer.
- * We put the two flags in the low two bits since we know that
- * rb_node will have an alignment of 4 or 8 bytes.
- */
- uintptr_t rb_info;
-};
-
-#define ARCHIVE_RB_DIR_LEFT 0
-#define ARCHIVE_RB_DIR_RIGHT 1
-
-#define ARCHIVE_RB_TREE_MIN(T) \
- __archive_rb_tree_iterate((T), NULL, ARCHIVE_RB_DIR_LEFT)
-#define ARCHIVE_RB_TREE_MAX(T) \
- __archive_rb_tree_iterate((T), NULL, ARCHIVE_RB_DIR_RIGHT)
-#define ARCHIVE_RB_TREE_NEXT(T, N) \
- __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_RIGHT)
-#define ARCHIVE_RB_TREE_PREV(T, N) \
- __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_LEFT)
-#define ARCHIVE_RB_TREE_FOREACH(N, T) \
- for ((N) = ARCHIVE_RB_TREE_MIN(T); (N); \
- (N) = ARCHIVE_RB_TREE_NEXT((T), (N)))
-#define ARCHIVE_RB_TREE_FOREACH_REVERSE(N, T) \
- for ((N) = ARCHIVE_RB_TREE_MAX(T); (N); \
- (N) = ARCHIVE_RB_TREE_PREV((T), (N)))
-#define ARCHIVE_RB_TREE_FOREACH_SAFE(N, T, S) \
- for ((N) = ARCHIVE_RB_TREE_MIN(T); \
- (N) && ((S) = ARCHIVE_RB_TREE_NEXT((T), (N)), 1); \
- (N) = (S))
-#define ARCHIVE_RB_TREE_FOREACH_REVERSE_SAFE(N, T, S) \
- for ((N) = ARCHIVE_RB_TREE_MAX(T); \
- (N) && ((S) = ARCHIVE_RB_TREE_PREV((T), (N)), 1); \
- (N) = (S))
-
-/*
- * archive_rbto_compare_nodes_fn:
- * return a positive value if the first node < the second node.
- * return a negative value if the first node > the second node.
- * return 0 if they are considered same.
- *
- * archive_rbto_compare_key_fn:
- * return a positive value if the node < the key.
- * return a negative value if the node > the key.
- * return 0 if they are considered same.
- */
-
-typedef signed int (*const archive_rbto_compare_nodes_fn)(const struct archive_rb_node *,
- const struct archive_rb_node *);
-typedef signed int (*const archive_rbto_compare_key_fn)(const struct archive_rb_node *,
- const void *);
-
-struct archive_rb_tree_ops {
- archive_rbto_compare_nodes_fn rbto_compare_nodes;
- archive_rbto_compare_key_fn rbto_compare_key;
-};
-
-struct archive_rb_tree {
- struct archive_rb_node *rbt_root;
- const struct archive_rb_tree_ops *rbt_ops;
-};
-
-void __archive_rb_tree_init(struct archive_rb_tree *,
- const struct archive_rb_tree_ops *);
-int __archive_rb_tree_insert_node(struct archive_rb_tree *,
- struct archive_rb_node *);
-struct archive_rb_node *
- __archive_rb_tree_find_node(struct archive_rb_tree *, const void *);
-struct archive_rb_node *
- __archive_rb_tree_find_node_geq(struct archive_rb_tree *, const void *);
-struct archive_rb_node *
- __archive_rb_tree_find_node_leq(struct archive_rb_tree *, const void *);
-void __archive_rb_tree_remove_node(struct archive_rb_tree *, struct archive_rb_node *);
-struct archive_rb_node *
- __archive_rb_tree_iterate(struct archive_rb_tree *,
- struct archive_rb_node *, const unsigned int);
-
-#endif /* ARCHIVE_RB_H_*/
diff --git a/contrib/libs/libarchive/libarchive/archive_read.c b/contrib/libs/libarchive/libarchive/archive_read.c
deleted file mode 100644
index 45a38aed02..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read.c
+++ /dev/null
@@ -1,1756 +0,0 @@
-/*-
- * Copyright (c) 2003-2011 Tim Kientzle
- * 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(S) ``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(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * This file contains the "essential" portions of the read API, that
- * is, stuff that will probably always be used by any client that
- * actually needs to read an archive. Optional pieces have been, as
- * far as possible, separated out into separate files to avoid
- * needlessly bloating statically-linked clients.
- */
-
-#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read.c 201157 2009-12-29 05:30:23Z kientzle $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-#define minimum(a, b) (a < b ? a : b)
-
-static int choose_filters(struct archive_read *);
-static int choose_format(struct archive_read *);
-static int close_filters(struct archive_read *);
-static int64_t _archive_filter_bytes(struct archive *, int);
-static int _archive_filter_code(struct archive *, int);
-static const char *_archive_filter_name(struct archive *, int);
-static int _archive_filter_count(struct archive *);
-static int _archive_read_close(struct archive *);
-static int _archive_read_data_block(struct archive *,
- const void **, size_t *, int64_t *);
-static int _archive_read_free(struct archive *);
-static int _archive_read_next_header(struct archive *,
- struct archive_entry **);
-static int _archive_read_next_header2(struct archive *,
- struct archive_entry *);
-static int64_t advance_file_pointer(struct archive_read_filter *, int64_t);
-
-static const struct archive_vtable
-archive_read_vtable = {
- .archive_filter_bytes = _archive_filter_bytes,
- .archive_filter_code = _archive_filter_code,
- .archive_filter_name = _archive_filter_name,
- .archive_filter_count = _archive_filter_count,
- .archive_read_data_block = _archive_read_data_block,
- .archive_read_next_header = _archive_read_next_header,
- .archive_read_next_header2 = _archive_read_next_header2,
- .archive_free = _archive_read_free,
- .archive_close = _archive_read_close,
-};
-
-/*
- * Allocate, initialize and return a struct archive object.
- */
-struct archive *
-archive_read_new(void)
-{
- struct archive_read *a;
-
- a = (struct archive_read *)calloc(1, sizeof(*a));
- if (a == NULL)
- return (NULL);
- a->archive.magic = ARCHIVE_READ_MAGIC;
-
- a->archive.state = ARCHIVE_STATE_NEW;
- a->entry = archive_entry_new2(&a->archive);
- a->archive.vtable = &archive_read_vtable;
-
- a->passphrases.last = &a->passphrases.first;
-
- return (&a->archive);
-}
-
-/*
- * Record the do-not-extract-to file. This belongs in archive_read_extract.c.
- */
-void
-archive_read_extract_set_skip_file(struct archive *_a, la_int64_t d,
- la_int64_t i)
-{
- struct archive_read *a = (struct archive_read *)_a;
-
- if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_extract_set_skip_file"))
- return;
- a->skip_file_set = 1;
- a->skip_file_dev = d;
- a->skip_file_ino = i;
-}
-
-/*
- * Open the archive
- */
-int
-archive_read_open(struct archive *a, void *client_data,
- archive_open_callback *client_opener, archive_read_callback *client_reader,
- archive_close_callback *client_closer)
-{
- /* Old archive_read_open() is just a thin shell around
- * archive_read_open1. */
- archive_read_set_open_callback(a, client_opener);
- archive_read_set_read_callback(a, client_reader);
- archive_read_set_close_callback(a, client_closer);
- archive_read_set_callback_data(a, client_data);
- return archive_read_open1(a);
-}
-
-
-int
-archive_read_open2(struct archive *a, void *client_data,
- archive_open_callback *client_opener,
- archive_read_callback *client_reader,
- archive_skip_callback *client_skipper,
- archive_close_callback *client_closer)
-{
- /* Old archive_read_open2() is just a thin shell around
- * archive_read_open1. */
- archive_read_set_callback_data(a, client_data);
- archive_read_set_open_callback(a, client_opener);
- archive_read_set_read_callback(a, client_reader);
- archive_read_set_skip_callback(a, client_skipper);
- archive_read_set_close_callback(a, client_closer);
- return archive_read_open1(a);
-}
-
-static ssize_t
-client_read_proxy(struct archive_read_filter *self, const void **buff)
-{
- ssize_t r;
- r = (self->archive->client.reader)(&self->archive->archive,
- self->data, buff);
- return (r);
-}
-
-static int64_t
-client_skip_proxy(struct archive_read_filter *self, int64_t request)
-{
- if (request < 0)
- __archive_errx(1, "Negative skip requested.");
- if (request == 0)
- return 0;
-
- if (self->archive->client.skipper != NULL) {
- /* Seek requests over 1GiB are broken down into
- * multiple seeks. This avoids overflows when the
- * requests get passed through 32-bit arguments. */
- int64_t skip_limit = (int64_t)1 << 30;
- int64_t total = 0;
- for (;;) {
- int64_t get, ask = request;
- if (ask > skip_limit)
- ask = skip_limit;
- get = (self->archive->client.skipper)
- (&self->archive->archive, self->data, ask);
- total += get;
- if (get == 0 || get == request)
- return (total);
- if (get > request)
- return ARCHIVE_FATAL;
- request -= get;
- }
- } else if (self->archive->client.seeker != NULL
- && request > 64 * 1024) {
- /* If the client provided a seeker but not a skipper,
- * we can use the seeker to skip forward.
- *
- * Note: This isn't always a good idea. The client
- * skipper is allowed to skip by less than requested
- * if it needs to maintain block alignment. The
- * seeker is not allowed to play such games, so using
- * the seeker here may be a performance loss compared
- * to just reading and discarding. That's why we
- * only do this for skips of over 64k.
- */
- int64_t before = self->position;
- int64_t after = (self->archive->client.seeker)
- (&self->archive->archive, self->data, request, SEEK_CUR);
- if (after != before + request)
- return ARCHIVE_FATAL;
- return after - before;
- }
- return 0;
-}
-
-static int64_t
-client_seek_proxy(struct archive_read_filter *self, int64_t offset, int whence)
-{
- /* DO NOT use the skipper here! If we transparently handled
- * forward seek here by using the skipper, that will break
- * other libarchive code that assumes a successful forward
- * seek means it can also seek backwards.
- */
- if (self->archive->client.seeker == NULL) {
- archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
- "Current client reader does not support seeking a device");
- return (ARCHIVE_FAILED);
- }
- return (self->archive->client.seeker)(&self->archive->archive,
- self->data, offset, whence);
-}
-
-static int
-read_client_close_proxy(struct archive_read *a)
-{
- int r = ARCHIVE_OK, r2;
- unsigned int i;
-
- if (a->client.closer == NULL)
- return (r);
- for (i = 0; i < a->client.nodes; i++)
- {
- r2 = (a->client.closer)
- ((struct archive *)a, a->client.dataset[i].data);
- if (r > r2)
- r = r2;
- }
- return (r);
-}
-
-static int
-client_close_proxy(struct archive_read_filter *self)
-{
- return read_client_close_proxy(self->archive);
-}
-
-static int
-client_open_proxy(struct archive_read_filter *self)
-{
- int r = ARCHIVE_OK;
- if (self->archive->client.opener != NULL)
- r = (self->archive->client.opener)(
- (struct archive *)self->archive, self->data);
- return (r);
-}
-
-static int
-client_switch_proxy(struct archive_read_filter *self, unsigned int iindex)
-{
- int r1 = ARCHIVE_OK, r2 = ARCHIVE_OK;
- void *data2 = NULL;
-
- /* Don't do anything if already in the specified data node */
- if (self->archive->client.cursor == iindex)
- return (ARCHIVE_OK);
-
- self->archive->client.cursor = iindex;
- data2 = self->archive->client.dataset[self->archive->client.cursor].data;
- if (self->archive->client.switcher != NULL)
- {
- r1 = r2 = (self->archive->client.switcher)
- ((struct archive *)self->archive, self->data, data2);
- self->data = data2;
- }
- else
- {
- /* Attempt to call close and open instead */
- if (self->archive->client.closer != NULL)
- r1 = (self->archive->client.closer)
- ((struct archive *)self->archive, self->data);
- self->data = data2;
- r2 = client_open_proxy(self);
- }
- return (r1 < r2) ? r1 : r2;
-}
-
-int
-archive_read_set_open_callback(struct archive *_a,
- archive_open_callback *client_opener)
-{
- struct archive_read *a = (struct archive_read *)_a;
- archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
- "archive_read_set_open_callback");
- a->client.opener = client_opener;
- return ARCHIVE_OK;
-}
-
-int
-archive_read_set_read_callback(struct archive *_a,
- archive_read_callback *client_reader)
-{
- struct archive_read *a = (struct archive_read *)_a;
- archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
- "archive_read_set_read_callback");
- a->client.reader = client_reader;
- return ARCHIVE_OK;
-}
-
-int
-archive_read_set_skip_callback(struct archive *_a,
- archive_skip_callback *client_skipper)
-{
- struct archive_read *a = (struct archive_read *)_a;
- archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
- "archive_read_set_skip_callback");
- a->client.skipper = client_skipper;
- return ARCHIVE_OK;
-}
-
-int
-archive_read_set_seek_callback(struct archive *_a,
- archive_seek_callback *client_seeker)
-{
- struct archive_read *a = (struct archive_read *)_a;
- archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
- "archive_read_set_seek_callback");
- a->client.seeker = client_seeker;
- return ARCHIVE_OK;
-}
-
-int
-archive_read_set_close_callback(struct archive *_a,
- archive_close_callback *client_closer)
-{
- struct archive_read *a = (struct archive_read *)_a;
- archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
- "archive_read_set_close_callback");
- a->client.closer = client_closer;
- return ARCHIVE_OK;
-}
-
-int
-archive_read_set_switch_callback(struct archive *_a,
- archive_switch_callback *client_switcher)
-{
- struct archive_read *a = (struct archive_read *)_a;
- archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
- "archive_read_set_switch_callback");
- a->client.switcher = client_switcher;
- return ARCHIVE_OK;
-}
-
-int
-archive_read_set_callback_data(struct archive *_a, void *client_data)
-{
- return archive_read_set_callback_data2(_a, client_data, 0);
-}
-
-int
-archive_read_set_callback_data2(struct archive *_a, void *client_data,
- unsigned int iindex)
-{
- struct archive_read *a = (struct archive_read *)_a;
- archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
- "archive_read_set_callback_data2");
-
- if (a->client.nodes == 0)
- {
- a->client.dataset = (struct archive_read_data_node *)
- calloc(1, sizeof(*a->client.dataset));
- if (a->client.dataset == NULL)
- {
- archive_set_error(&a->archive, ENOMEM,
- "No memory.");
- return ARCHIVE_FATAL;
- }
- a->client.nodes = 1;
- }
-
- if (iindex > a->client.nodes - 1)
- {
- archive_set_error(&a->archive, EINVAL,
- "Invalid index specified.");
- return ARCHIVE_FATAL;
- }
- a->client.dataset[iindex].data = client_data;
- a->client.dataset[iindex].begin_position = -1;
- a->client.dataset[iindex].total_size = -1;
- return ARCHIVE_OK;
-}
-
-int
-archive_read_add_callback_data(struct archive *_a, void *client_data,
- unsigned int iindex)
-{
- struct archive_read *a = (struct archive_read *)_a;
- void *p;
- unsigned int i;
-
- archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
- "archive_read_add_callback_data");
- if (iindex > a->client.nodes) {
- archive_set_error(&a->archive, EINVAL,
- "Invalid index specified.");
- return ARCHIVE_FATAL;
- }
- p = realloc(a->client.dataset, sizeof(*a->client.dataset)
- * (++(a->client.nodes)));
- if (p == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory.");
- return ARCHIVE_FATAL;
- }
- a->client.dataset = (struct archive_read_data_node *)p;
- for (i = a->client.nodes - 1; i > iindex; i--) {
- a->client.dataset[i].data = a->client.dataset[i-1].data;
- a->client.dataset[i].begin_position = -1;
- a->client.dataset[i].total_size = -1;
- }
- a->client.dataset[iindex].data = client_data;
- a->client.dataset[iindex].begin_position = -1;
- a->client.dataset[iindex].total_size = -1;
- return ARCHIVE_OK;
-}
-
-int
-archive_read_append_callback_data(struct archive *_a, void *client_data)
-{
- struct archive_read *a = (struct archive_read *)_a;
- return archive_read_add_callback_data(_a, client_data, a->client.nodes);
-}
-
-int
-archive_read_prepend_callback_data(struct archive *_a, void *client_data)
-{
- return archive_read_add_callback_data(_a, client_data, 0);
-}
-
-static const struct archive_read_filter_vtable
-none_reader_vtable = {
- .read = client_read_proxy,
- .close = client_close_proxy,
-};
-
-int
-archive_read_open1(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- struct archive_read_filter *filter, *tmp;
- int slot, e = ARCHIVE_OK;
-
- archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
- "archive_read_open");
- archive_clear_error(&a->archive);
-
- if (a->client.reader == NULL) {
- archive_set_error(&a->archive, EINVAL,
- "No reader function provided to archive_read_open");
- a->archive.state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- }
-
- /* Open data source. */
- if (a->client.opener != NULL) {
- e = (a->client.opener)(&a->archive, a->client.dataset[0].data);
- if (e != 0) {
- /* If the open failed, call the closer to clean up. */
- read_client_close_proxy(a);
- return (e);
- }
- }
-
- filter = calloc(1, sizeof(*filter));
- if (filter == NULL)
- return (ARCHIVE_FATAL);
- filter->bidder = NULL;
- filter->upstream = NULL;
- filter->archive = a;
- filter->data = a->client.dataset[0].data;
- filter->vtable = &none_reader_vtable;
- filter->name = "none";
- filter->code = ARCHIVE_FILTER_NONE;
- filter->can_skip = 1;
- filter->can_seek = 1;
-
- a->client.dataset[0].begin_position = 0;
- if (!a->filter || !a->bypass_filter_bidding)
- {
- a->filter = filter;
- /* Build out the input pipeline. */
- e = choose_filters(a);
- if (e < ARCHIVE_WARN) {
- a->archive.state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- }
- }
- else
- {
- /* Need to add "NONE" type filter at the end of the filter chain */
- tmp = a->filter;
- while (tmp->upstream)
- tmp = tmp->upstream;
- tmp->upstream = filter;
- }
-
- if (!a->format)
- {
- slot = choose_format(a);
- if (slot < 0) {
- close_filters(a);
- a->archive.state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- }
- a->format = &(a->formats[slot]);
- }
-
- a->archive.state = ARCHIVE_STATE_HEADER;
-
- /* Ensure libarchive starts from the first node in a multivolume set */
- client_switch_proxy(a->filter, 0);
- return (e);
-}
-
-/*
- * Allow each registered stream transform to bid on whether
- * it wants to handle this stream. Repeat until we've finished
- * building the pipeline.
- */
-
-/* We won't build a filter pipeline with more stages than this. */
-#define MAX_NUMBER_FILTERS 25
-
-static int
-choose_filters(struct archive_read *a)
-{
- int number_bidders, i, bid, best_bid, number_filters;
- struct archive_read_filter_bidder *bidder, *best_bidder;
- struct archive_read_filter *filter;
- ssize_t avail;
- int r;
-
- for (number_filters = 0; number_filters < MAX_NUMBER_FILTERS; ++number_filters) {
- number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
-
- best_bid = 0;
- best_bidder = NULL;
-
- bidder = a->bidders;
- for (i = 0; i < number_bidders; i++, bidder++) {
- if (bidder->vtable == NULL)
- continue;
- bid = (bidder->vtable->bid)(bidder, a->filter);
- if (bid > best_bid) {
- best_bid = bid;
- best_bidder = bidder;
- }
- }
-
- /* If no bidder, we're done. */
- if (best_bidder == NULL) {
- /* Verify the filter by asking it for some data. */
- __archive_read_filter_ahead(a->filter, 1, &avail);
- if (avail < 0) {
- __archive_read_free_filters(a);
- return (ARCHIVE_FATAL);
- }
- return (ARCHIVE_OK);
- }
-
- filter
- = (struct archive_read_filter *)calloc(1, sizeof(*filter));
- if (filter == NULL)
- return (ARCHIVE_FATAL);
- filter->bidder = best_bidder;
- filter->archive = a;
- filter->upstream = a->filter;
- a->filter = filter;
- r = (best_bidder->vtable->init)(a->filter);
- if (r != ARCHIVE_OK) {
- __archive_read_free_filters(a);
- return (ARCHIVE_FATAL);
- }
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Input requires too many filters for decoding");
- return (ARCHIVE_FATAL);
-}
-
-int
-__archive_read_header(struct archive_read *a, struct archive_entry *entry)
-{
- if (!a->filter->vtable->read_header)
- return (ARCHIVE_OK);
- return a->filter->vtable->read_header(a->filter, entry);
-}
-
-/*
- * Read header of next entry.
- */
-static int
-_archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
-{
- struct archive_read *a = (struct archive_read *)_a;
- int r1 = ARCHIVE_OK, r2;
-
- archive_check_magic(_a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
- "archive_read_next_header");
-
- archive_entry_clear(entry);
- archive_clear_error(&a->archive);
-
- /*
- * If client didn't consume entire data, skip any remainder
- * (This is especially important for GNU incremental directories.)
- */
- if (a->archive.state == ARCHIVE_STATE_DATA) {
- r1 = archive_read_data_skip(&a->archive);
- if (r1 == ARCHIVE_EOF)
- archive_set_error(&a->archive, EIO,
- "Premature end-of-file.");
- if (r1 == ARCHIVE_EOF || r1 == ARCHIVE_FATAL) {
- a->archive.state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- }
- }
-
- /* Record start-of-header offset in uncompressed stream. */
- a->header_position = a->filter->position;
-
- ++_a->file_count;
- r2 = (a->format->read_header)(a, entry);
-
- /*
- * EOF and FATAL are persistent at this layer. By
- * modifying the state, we guarantee that future calls to
- * read a header or read data will fail.
- */
- switch (r2) {
- case ARCHIVE_EOF:
- a->archive.state = ARCHIVE_STATE_EOF;
- --_a->file_count;/* Revert a file counter. */
- break;
- case ARCHIVE_OK:
- a->archive.state = ARCHIVE_STATE_DATA;
- break;
- case ARCHIVE_WARN:
- a->archive.state = ARCHIVE_STATE_DATA;
- break;
- case ARCHIVE_RETRY:
- break;
- case ARCHIVE_FATAL:
- a->archive.state = ARCHIVE_STATE_FATAL;
- break;
- }
-
- __archive_reset_read_data(&a->archive);
-
- a->data_start_node = a->client.cursor;
- /* EOF always wins; otherwise return the worst error. */
- return (r2 < r1 || r2 == ARCHIVE_EOF) ? r2 : r1;
-}
-
-static int
-_archive_read_next_header(struct archive *_a, struct archive_entry **entryp)
-{
- int ret;
- struct archive_read *a = (struct archive_read *)_a;
- *entryp = NULL;
- ret = _archive_read_next_header2(_a, a->entry);
- *entryp = a->entry;
- return ret;
-}
-
-/*
- * Allow each registered format to bid on whether it wants to handle
- * the next entry. Return index of winning bidder.
- */
-static int
-choose_format(struct archive_read *a)
-{
- int slots;
- int i;
- int bid, best_bid;
- int best_bid_slot;
-
- slots = sizeof(a->formats) / sizeof(a->formats[0]);
- best_bid = -1;
- best_bid_slot = -1;
-
- /* Set up a->format for convenience of bidders. */
- a->format = &(a->formats[0]);
- for (i = 0; i < slots; i++, a->format++) {
- if (a->format->bid) {
- bid = (a->format->bid)(a, best_bid);
- if (bid == ARCHIVE_FATAL)
- return (ARCHIVE_FATAL);
- if (a->filter->position != 0)
- __archive_read_seek(a, 0, SEEK_SET);
- if ((bid > best_bid) || (best_bid_slot < 0)) {
- best_bid = bid;
- best_bid_slot = i;
- }
- }
- }
-
- /*
- * There were no bidders; this is a serious programmer error
- * and demands a quick and definitive abort.
- */
- if (best_bid_slot < 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "No formats registered");
- return (ARCHIVE_FATAL);
- }
-
- /*
- * There were bidders, but no non-zero bids; this means we
- * can't support this stream.
- */
- if (best_bid < 1) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unrecognized archive format");
- return (ARCHIVE_FATAL);
- }
-
- return (best_bid_slot);
-}
-
-/*
- * Return the file offset (within the uncompressed data stream) where
- * the last header started.
- */
-la_int64_t
-archive_read_header_position(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- archive_check_magic(_a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_header_position");
- return (a->header_position);
-}
-
-/*
- * Returns 1 if the archive contains at least one encrypted entry.
- * If the archive format not support encryption at all
- * ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED is returned.
- * If for any other reason (e.g. not enough data read so far)
- * we cannot say whether there are encrypted entries, then
- * ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW is returned.
- * In general, this function will return values below zero when the
- * reader is uncertain or totally incapable of encryption support.
- * When this function returns 0 you can be sure that the reader
- * supports encryption detection but no encrypted entries have
- * been found yet.
- *
- * NOTE: If the metadata/header of an archive is also encrypted, you
- * cannot rely on the number of encrypted entries. That is why this
- * function does not return the number of encrypted entries but#
- * just shows that there are some.
- */
-int
-archive_read_has_encrypted_entries(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- int format_supports_encryption = archive_read_format_capabilities(_a)
- & (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA | ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA);
-
- if (!_a || !format_supports_encryption) {
- /* Format in general doesn't support encryption */
- return ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED;
- }
-
- /* A reader potentially has read enough data now. */
- if (a->format && a->format->has_encrypted_entries) {
- return (a->format->has_encrypted_entries)(a);
- }
-
- /* For any other reason we cannot say how many entries are there. */
- return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
-}
-
-/*
- * Returns a bitmask of capabilities that are supported by the archive format reader.
- * If the reader has no special capabilities, ARCHIVE_READ_FORMAT_CAPS_NONE is returned.
- */
-int
-archive_read_format_capabilities(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- if (a && a->format && a->format->format_capabilties) {
- return (a->format->format_capabilties)(a);
- }
- return ARCHIVE_READ_FORMAT_CAPS_NONE;
-}
-
-/*
- * Read data from an archive entry, using a read(2)-style interface.
- * This is a convenience routine that just calls
- * archive_read_data_block and copies the results into the client
- * buffer, filling any gaps with zero bytes. Clients using this
- * API can be completely ignorant of sparse-file issues; sparse files
- * will simply be padded with nulls.
- *
- * DO NOT intermingle calls to this function and archive_read_data_block
- * to read a single entry body.
- */
-la_ssize_t
-archive_read_data(struct archive *_a, void *buff, size_t s)
-{
- struct archive *a = (struct archive *)_a;
- char *dest;
- const void *read_buf;
- size_t bytes_read;
- size_t len;
- int r;
-
- bytes_read = 0;
- dest = (char *)buff;
-
- while (s > 0) {
- if (a->read_data_offset == a->read_data_output_offset &&
- a->read_data_remaining == 0) {
- read_buf = a->read_data_block;
- a->read_data_is_posix_read = 1;
- a->read_data_requested = s;
- r = archive_read_data_block(a, &read_buf,
- &a->read_data_remaining, &a->read_data_offset);
- a->read_data_block = read_buf;
- if (r == ARCHIVE_EOF)
- return (bytes_read);
- /*
- * Error codes are all negative, so the status
- * return here cannot be confused with a valid
- * byte count. (ARCHIVE_OK is zero.)
- */
- if (r < ARCHIVE_OK)
- return (r);
- }
-
- if (a->read_data_offset < a->read_data_output_offset) {
- archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
- "Encountered out-of-order sparse blocks");
- return (ARCHIVE_RETRY);
- }
-
- /* Compute the amount of zero padding needed. */
- if (a->read_data_output_offset + (int64_t)s <
- a->read_data_offset) {
- len = s;
- } else if (a->read_data_output_offset <
- a->read_data_offset) {
- len = (size_t)(a->read_data_offset -
- a->read_data_output_offset);
- } else
- len = 0;
-
- /* Add zeroes. */
- memset(dest, 0, len);
- s -= len;
- a->read_data_output_offset += len;
- dest += len;
- bytes_read += len;
-
- /* Copy data if there is any space left. */
- if (s > 0) {
- len = a->read_data_remaining;
- if (len > s)
- len = s;
- if (len) {
- memcpy(dest, a->read_data_block, len);
- s -= len;
- a->read_data_block += len;
- a->read_data_remaining -= len;
- a->read_data_output_offset += len;
- a->read_data_offset += len;
- dest += len;
- bytes_read += len;
- }
- }
- }
- a->read_data_is_posix_read = 0;
- a->read_data_requested = 0;
- return (bytes_read);
-}
-
-/*
- * Reset the read_data_* variables, used for starting a new entry.
- */
-void __archive_reset_read_data(struct archive * a)
-{
- a->read_data_output_offset = 0;
- a->read_data_remaining = 0;
- a->read_data_is_posix_read = 0;
- a->read_data_requested = 0;
-
- /* extra resets, from rar.c */
- a->read_data_block = NULL;
- a->read_data_offset = 0;
-}
-
-/*
- * Skip over all remaining data in this entry.
- */
-int
-archive_read_data_skip(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- int r;
- const void *buff;
- size_t size;
- int64_t offset;
-
- archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
- "archive_read_data_skip");
-
- if (a->format->read_data_skip != NULL)
- r = (a->format->read_data_skip)(a);
- else {
- while ((r = archive_read_data_block(&a->archive,
- &buff, &size, &offset))
- == ARCHIVE_OK)
- ;
- }
-
- if (r == ARCHIVE_EOF)
- r = ARCHIVE_OK;
-
- a->archive.state = ARCHIVE_STATE_HEADER;
- return (r);
-}
-
-la_int64_t
-archive_seek_data(struct archive *_a, int64_t offset, int whence)
-{
- struct archive_read *a = (struct archive_read *)_a;
- archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
- "archive_seek_data_block");
-
- if (a->format->seek_data == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Internal error: "
- "No format_seek_data_block function registered");
- return (ARCHIVE_FATAL);
- }
-
- return (a->format->seek_data)(a, offset, whence);
-}
-
-/*
- * Read the next block of entry data from the archive.
- * This is a zero-copy interface; the client receives a pointer,
- * size, and file offset of the next available block of data.
- *
- * Returns ARCHIVE_OK if the operation is successful, ARCHIVE_EOF if
- * the end of entry is encountered.
- */
-static int
-_archive_read_data_block(struct archive *_a,
- const void **buff, size_t *size, int64_t *offset)
-{
- struct archive_read *a = (struct archive_read *)_a;
- archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
- "archive_read_data_block");
-
- if (a->format->read_data == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Internal error: "
- "No format->read_data function registered");
- return (ARCHIVE_FATAL);
- }
-
- return (a->format->read_data)(a, buff, size, offset);
-}
-
-static int
-close_filters(struct archive_read *a)
-{
- struct archive_read_filter *f = a->filter;
- int r = ARCHIVE_OK;
- /* Close each filter in the pipeline. */
- while (f != NULL) {
- struct archive_read_filter *t = f->upstream;
- if (!f->closed && f->vtable != NULL) {
- int r1 = (f->vtable->close)(f);
- f->closed = 1;
- if (r1 < r)
- r = r1;
- }
- free(f->buffer);
- f->buffer = NULL;
- f = t;
- }
- return r;
-}
-
-void
-__archive_read_free_filters(struct archive_read *a)
-{
- /* Make sure filters are closed and their buffers are freed */
- close_filters(a);
-
- while (a->filter != NULL) {
- struct archive_read_filter *t = a->filter->upstream;
- free(a->filter);
- a->filter = t;
- }
-}
-
-/*
- * return the count of # of filters in use
- */
-static int
-_archive_filter_count(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- struct archive_read_filter *p = a->filter;
- int count = 0;
- while(p) {
- count++;
- p = p->upstream;
- }
- return count;
-}
-
-/*
- * Close the file and all I/O.
- */
-static int
-_archive_read_close(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- int r = ARCHIVE_OK, r1 = ARCHIVE_OK;
-
- archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close");
- if (a->archive.state == ARCHIVE_STATE_CLOSED)
- return (ARCHIVE_OK);
- archive_clear_error(&a->archive);
- a->archive.state = ARCHIVE_STATE_CLOSED;
-
- /* TODO: Clean up the formatters. */
-
- /* Release the filter objects. */
- r1 = close_filters(a);
- if (r1 < r)
- r = r1;
-
- return (r);
-}
-
-/*
- * Release memory and other resources.
- */
-static int
-_archive_read_free(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- struct archive_read_passphrase *p;
- int i, n;
- int slots;
- int r = ARCHIVE_OK;
-
- if (_a == NULL)
- return (ARCHIVE_OK);
- archive_check_magic(_a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free");
- if (a->archive.state != ARCHIVE_STATE_CLOSED
- && a->archive.state != ARCHIVE_STATE_FATAL)
- r = archive_read_close(&a->archive);
-
- /* Call cleanup functions registered by optional components. */
- if (a->cleanup_archive_extract != NULL)
- r = (a->cleanup_archive_extract)(a);
-
- /* Cleanup format-specific data. */
- slots = sizeof(a->formats) / sizeof(a->formats[0]);
- for (i = 0; i < slots; i++) {
- a->format = &(a->formats[i]);
- if (a->formats[i].cleanup)
- (a->formats[i].cleanup)(a);
- }
-
- /* Free the filters */
- __archive_read_free_filters(a);
-
- /* Release the bidder objects. */
- n = sizeof(a->bidders)/sizeof(a->bidders[0]);
- for (i = 0; i < n; i++) {
- if (a->bidders[i].vtable == NULL ||
- a->bidders[i].vtable->free == NULL)
- continue;
- (a->bidders[i].vtable->free)(&a->bidders[i]);
- }
-
- /* Release passphrase list. */
- p = a->passphrases.first;
- while (p != NULL) {
- struct archive_read_passphrase *np = p->next;
-
- /* A passphrase should be cleaned. */
- memset(p->passphrase, 0, strlen(p->passphrase));
- free(p->passphrase);
- free(p);
- p = np;
- }
-
- archive_string_free(&a->archive.error_string);
- archive_entry_free(a->entry);
- a->archive.magic = 0;
- __archive_clean(&a->archive);
- free(a->client.dataset);
- free(a);
- return (r);
-}
-
-static struct archive_read_filter *
-get_filter(struct archive *_a, int n)
-{
- struct archive_read *a = (struct archive_read *)_a;
- struct archive_read_filter *f = a->filter;
- /* We use n == -1 for 'the last filter', which is always the
- * client proxy. */
- if (n == -1 && f != NULL) {
- struct archive_read_filter *last = f;
- f = f->upstream;
- while (f != NULL) {
- last = f;
- f = f->upstream;
- }
- return (last);
- }
- if (n < 0)
- return NULL;
- while (n > 0 && f != NULL) {
- f = f->upstream;
- --n;
- }
- return (f);
-}
-
-static int
-_archive_filter_code(struct archive *_a, int n)
-{
- struct archive_read_filter *f = get_filter(_a, n);
- return f == NULL ? -1 : f->code;
-}
-
-static const char *
-_archive_filter_name(struct archive *_a, int n)
-{
- struct archive_read_filter *f = get_filter(_a, n);
- return f != NULL ? f->name : NULL;
-}
-
-static int64_t
-_archive_filter_bytes(struct archive *_a, int n)
-{
- struct archive_read_filter *f = get_filter(_a, n);
- return f == NULL ? -1 : f->position;
-}
-
-/*
- * Used internally by read format handlers to register their bid and
- * initialization functions.
- */
-int
-__archive_read_register_format(struct archive_read *a,
- void *format_data,
- const char *name,
- int (*bid)(struct archive_read *, int),
- int (*options)(struct archive_read *, const char *, const char *),
- int (*read_header)(struct archive_read *, struct archive_entry *),
- int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
- int (*read_data_skip)(struct archive_read *),
- int64_t (*seek_data)(struct archive_read *, int64_t, int),
- int (*cleanup)(struct archive_read *),
- int (*format_capabilities)(struct archive_read *),
- int (*has_encrypted_entries)(struct archive_read *))
-{
- int i, number_slots;
-
- archive_check_magic(&a->archive,
- ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
- "__archive_read_register_format");
-
- number_slots = sizeof(a->formats) / sizeof(a->formats[0]);
-
- for (i = 0; i < number_slots; i++) {
- if (a->formats[i].bid == bid)
- return (ARCHIVE_WARN); /* We've already installed */
- if (a->formats[i].bid == NULL) {
- a->formats[i].bid = bid;
- a->formats[i].options = options;
- a->formats[i].read_header = read_header;
- a->formats[i].read_data = read_data;
- a->formats[i].read_data_skip = read_data_skip;
- a->formats[i].seek_data = seek_data;
- a->formats[i].cleanup = cleanup;
- a->formats[i].data = format_data;
- a->formats[i].name = name;
- a->formats[i].format_capabilties = format_capabilities;
- a->formats[i].has_encrypted_entries = has_encrypted_entries;
- return (ARCHIVE_OK);
- }
- }
-
- archive_set_error(&a->archive, ENOMEM,
- "Not enough slots for format registration");
- return (ARCHIVE_FATAL);
-}
-
-/*
- * Used internally by decompression routines to register their bid and
- * initialization functions.
- */
-int
-__archive_read_register_bidder(struct archive_read *a,
- void *bidder_data,
- const char *name,
- const struct archive_read_filter_bidder_vtable *vtable)
-{
- struct archive_read_filter_bidder *bidder;
- int i, number_slots;
-
- archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "__archive_read_register_bidder");
-
- number_slots = sizeof(a->bidders) / sizeof(a->bidders[0]);
-
- for (i = 0; i < number_slots; i++) {
- if (a->bidders[i].vtable != NULL)
- continue;
- memset(a->bidders + i, 0, sizeof(a->bidders[0]));
- bidder = (a->bidders + i);
- bidder->data = bidder_data;
- bidder->name = name;
- bidder->vtable = vtable;
- if (bidder->vtable->bid == NULL || bidder->vtable->init == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Internal error: "
- "no bid/init for filter bidder");
- return (ARCHIVE_FATAL);
- }
-
- return (ARCHIVE_OK);
- }
-
- archive_set_error(&a->archive, ENOMEM,
- "Not enough slots for filter registration");
- return (ARCHIVE_FATAL);
-}
-
-/*
- * The next section implements the peek/consume internal I/O
- * system used by archive readers. This system allows simple
- * read-ahead for consumers while preserving zero-copy operation
- * most of the time.
- *
- * The two key operations:
- * * The read-ahead function returns a pointer to a block of data
- * that satisfies a minimum request.
- * * The consume function advances the file pointer.
- *
- * In the ideal case, filters generate blocks of data
- * and __archive_read_ahead() just returns pointers directly into
- * those blocks. Then __archive_read_consume() just bumps those
- * pointers. Only if your request would span blocks does the I/O
- * layer use a copy buffer to provide you with a contiguous block of
- * data.
- *
- * A couple of useful idioms:
- * * "I just want some data." Ask for 1 byte and pay attention to
- * the "number of bytes available" from __archive_read_ahead().
- * Consume whatever you actually use.
- * * "I want to output a large block of data." As above, ask for 1 byte,
- * emit all that's available (up to whatever limit you have), consume
- * it all, then repeat until you're done. This effectively means that
- * you're passing along the blocks that came from your provider.
- * * "I want to peek ahead by a large amount." Ask for 4k or so, then
- * double and repeat until you get an error or have enough. Note
- * that the I/O layer will likely end up expanding its copy buffer
- * to fit your request, so use this technique cautiously. This
- * technique is used, for example, by some of the format tasting
- * code that has uncertain look-ahead needs.
- */
-
-/*
- * Looks ahead in the input stream:
- * * If 'avail' pointer is provided, that returns number of bytes available
- * in the current buffer, which may be much larger than requested.
- * * If end-of-file, *avail gets set to zero.
- * * If error, *avail gets error code.
- * * If request can be met, returns pointer to data.
- * * If minimum request cannot be met, returns NULL.
- *
- * Note: If you just want "some data", ask for 1 byte and pay attention
- * to *avail, which will have the actual amount available. If you
- * know exactly how many bytes you need, just ask for that and treat
- * a NULL return as an error.
- *
- * Important: This does NOT move the file pointer. See
- * __archive_read_consume() below.
- */
-const void *
-__archive_read_ahead(struct archive_read *a, size_t min, ssize_t *avail)
-{
- return (__archive_read_filter_ahead(a->filter, min, avail));
-}
-
-const void *
-__archive_read_filter_ahead(struct archive_read_filter *filter,
- size_t min, ssize_t *avail)
-{
- ssize_t bytes_read;
- size_t tocopy;
-
- if (filter->fatal) {
- if (avail)
- *avail = ARCHIVE_FATAL;
- return (NULL);
- }
-
- /*
- * Keep pulling more data until we can satisfy the request.
- */
- for (;;) {
-
- /*
- * If we can satisfy from the copy buffer (and the
- * copy buffer isn't empty), we're done. In particular,
- * note that min == 0 is a perfectly well-defined
- * request.
- */
- if (filter->avail >= min && filter->avail > 0) {
- if (avail != NULL)
- *avail = filter->avail;
- return (filter->next);
- }
-
- /*
- * We can satisfy directly from client buffer if everything
- * currently in the copy buffer is still in the client buffer.
- */
- if (filter->client_total >= filter->client_avail + filter->avail
- && filter->client_avail + filter->avail >= min) {
- /* "Roll back" to client buffer. */
- filter->client_avail += filter->avail;
- filter->client_next -= filter->avail;
- /* Copy buffer is now empty. */
- filter->avail = 0;
- filter->next = filter->buffer;
- /* Return data from client buffer. */
- if (avail != NULL)
- *avail = filter->client_avail;
- return (filter->client_next);
- }
-
- /* Move data forward in copy buffer if necessary. */
- if (filter->next > filter->buffer &&
- filter->next + min > filter->buffer + filter->buffer_size) {
- if (filter->avail > 0)
- memmove(filter->buffer, filter->next,
- filter->avail);
- filter->next = filter->buffer;
- }
-
- /* If we've used up the client data, get more. */
- if (filter->client_avail <= 0) {
- if (filter->end_of_file) {
- if (avail != NULL)
- *avail = 0;
- return (NULL);
- }
- bytes_read = (filter->vtable->read)(filter,
- &filter->client_buff);
- if (bytes_read < 0) { /* Read error. */
- filter->client_total = filter->client_avail = 0;
- filter->client_next =
- filter->client_buff = NULL;
- filter->fatal = 1;
- if (avail != NULL)
- *avail = ARCHIVE_FATAL;
- return (NULL);
- }
- if (bytes_read == 0) {
- /* Check for another client object first */
- if (filter->archive->client.cursor !=
- filter->archive->client.nodes - 1) {
- if (client_switch_proxy(filter,
- filter->archive->client.cursor + 1)
- == ARCHIVE_OK)
- continue;
- }
- /* Premature end-of-file. */
- filter->client_total = filter->client_avail = 0;
- filter->client_next =
- filter->client_buff = NULL;
- filter->end_of_file = 1;
- /* Return whatever we do have. */
- if (avail != NULL)
- *avail = filter->avail;
- return (NULL);
- }
- filter->client_total = bytes_read;
- filter->client_avail = filter->client_total;
- filter->client_next = filter->client_buff;
- } else {
- /*
- * We can't satisfy the request from the copy
- * buffer or the existing client data, so we
- * need to copy more client data over to the
- * copy buffer.
- */
-
- /* Ensure the buffer is big enough. */
- if (min > filter->buffer_size) {
- size_t s, t;
- char *p;
-
- /* Double the buffer; watch for overflow. */
- s = t = filter->buffer_size;
- if (s == 0)
- s = min;
- while (s < min) {
- t *= 2;
- if (t <= s) { /* Integer overflow! */
- archive_set_error(
- &filter->archive->archive,
- ENOMEM,
- "Unable to allocate copy"
- " buffer");
- filter->fatal = 1;
- if (avail != NULL)
- *avail = ARCHIVE_FATAL;
- return (NULL);
- }
- s = t;
- }
- /* Now s >= min, so allocate a new buffer. */
- p = (char *)malloc(s);
- if (p == NULL) {
- archive_set_error(
- &filter->archive->archive,
- ENOMEM,
- "Unable to allocate copy buffer");
- filter->fatal = 1;
- if (avail != NULL)
- *avail = ARCHIVE_FATAL;
- return (NULL);
- }
- /* Move data into newly-enlarged buffer. */
- if (filter->avail > 0)
- memmove(p, filter->next, filter->avail);
- free(filter->buffer);
- filter->next = filter->buffer = p;
- filter->buffer_size = s;
- }
-
- /* We can add client data to copy buffer. */
- /* First estimate: copy to fill rest of buffer. */
- tocopy = (filter->buffer + filter->buffer_size)
- - (filter->next + filter->avail);
- /* Don't waste time buffering more than we need to. */
- if (tocopy + filter->avail > min)
- tocopy = min - filter->avail;
- /* Don't copy more than is available. */
- if (tocopy > filter->client_avail)
- tocopy = filter->client_avail;
-
- memcpy(filter->next + filter->avail,
- filter->client_next, tocopy);
- /* Remove this data from client buffer. */
- filter->client_next += tocopy;
- filter->client_avail -= tocopy;
- /* add it to copy buffer. */
- filter->avail += tocopy;
- }
- }
-}
-
-/*
- * Move the file pointer forward.
- */
-int64_t
-__archive_read_consume(struct archive_read *a, int64_t request)
-{
- return (__archive_read_filter_consume(a->filter, request));
-}
-
-int64_t
-__archive_read_filter_consume(struct archive_read_filter * filter,
- int64_t request)
-{
- int64_t skipped;
-
- if (request < 0)
- return ARCHIVE_FATAL;
- if (request == 0)
- return 0;
-
- skipped = advance_file_pointer(filter, request);
- if (skipped == request)
- return (skipped);
- /* We hit EOF before we satisfied the skip request. */
- if (skipped < 0) /* Map error code to 0 for error message below. */
- skipped = 0;
- archive_set_error(&filter->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Truncated input file (needed %jd bytes, only %jd available)",
- (intmax_t)request, (intmax_t)skipped);
- return (ARCHIVE_FATAL);
-}
-
-/*
- * Advance the file pointer by the amount requested.
- * Returns the amount actually advanced, which may be less than the
- * request if EOF is encountered first.
- * Returns a negative value if there's an I/O error.
- */
-static int64_t
-advance_file_pointer(struct archive_read_filter *filter, int64_t request)
-{
- int64_t bytes_skipped, total_bytes_skipped = 0;
- ssize_t bytes_read;
- size_t min;
-
- if (filter->fatal)
- return (-1);
-
- /* Use up the copy buffer first. */
- if (filter->avail > 0) {
- min = (size_t)minimum(request, (int64_t)filter->avail);
- filter->next += min;
- filter->avail -= min;
- request -= min;
- filter->position += min;
- total_bytes_skipped += min;
- }
-
- /* Then use up the client buffer. */
- if (filter->client_avail > 0) {
- min = (size_t)minimum(request, (int64_t)filter->client_avail);
- filter->client_next += min;
- filter->client_avail -= min;
- request -= min;
- filter->position += min;
- total_bytes_skipped += min;
- }
- if (request == 0)
- return (total_bytes_skipped);
-
- /* If there's an optimized skip function, use it. */
- if (filter->can_skip != 0) {
- bytes_skipped = client_skip_proxy(filter, request);
- if (bytes_skipped < 0) { /* error */
- filter->fatal = 1;
- return (bytes_skipped);
- }
- filter->position += bytes_skipped;
- total_bytes_skipped += bytes_skipped;
- request -= bytes_skipped;
- if (request == 0)
- return (total_bytes_skipped);
- }
-
- /* Use ordinary reads as necessary to complete the request. */
- for (;;) {
- bytes_read = (filter->vtable->read)(filter, &filter->client_buff);
- if (bytes_read < 0) {
- filter->client_buff = NULL;
- filter->fatal = 1;
- return (bytes_read);
- }
-
- if (bytes_read == 0) {
- if (filter->archive->client.cursor !=
- filter->archive->client.nodes - 1) {
- if (client_switch_proxy(filter,
- filter->archive->client.cursor + 1)
- == ARCHIVE_OK)
- continue;
- }
- filter->client_buff = NULL;
- filter->end_of_file = 1;
- return (total_bytes_skipped);
- }
-
- if (bytes_read >= request) {
- filter->client_next =
- ((const char *)filter->client_buff) + request;
- filter->client_avail = (size_t)(bytes_read - request);
- filter->client_total = bytes_read;
- total_bytes_skipped += request;
- filter->position += request;
- return (total_bytes_skipped);
- }
-
- filter->position += bytes_read;
- total_bytes_skipped += bytes_read;
- request -= bytes_read;
- }
-}
-
-/**
- * Returns ARCHIVE_FAILED if seeking isn't supported.
- */
-int64_t
-__archive_read_seek(struct archive_read *a, int64_t offset, int whence)
-{
- return __archive_read_filter_seek(a->filter, offset, whence);
-}
-
-int64_t
-__archive_read_filter_seek(struct archive_read_filter *filter, int64_t offset,
- int whence)
-{
- struct archive_read_client *client;
- int64_t r;
- unsigned int cursor;
-
- if (filter->closed || filter->fatal)
- return (ARCHIVE_FATAL);
- if (filter->can_seek == 0)
- return (ARCHIVE_FAILED);
-
- client = &(filter->archive->client);
- switch (whence) {
- case SEEK_CUR:
- /* Adjust the offset and use SEEK_SET instead */
- offset += filter->position;
- __LA_FALLTHROUGH;
- case SEEK_SET:
- cursor = 0;
- while (1)
- {
- if (client->dataset[cursor].begin_position < 0 ||
- client->dataset[cursor].total_size < 0 ||
- client->dataset[cursor].begin_position +
- client->dataset[cursor].total_size - 1 > offset ||
- cursor + 1 >= client->nodes)
- break;
- r = client->dataset[cursor].begin_position +
- client->dataset[cursor].total_size;
- client->dataset[++cursor].begin_position = r;
- }
- while (1) {
- r = client_switch_proxy(filter, cursor);
- if (r != ARCHIVE_OK)
- return r;
- if ((r = client_seek_proxy(filter, 0, SEEK_END)) < 0)
- return r;
- client->dataset[cursor].total_size = r;
- if (client->dataset[cursor].begin_position +
- client->dataset[cursor].total_size - 1 > offset ||
- cursor + 1 >= client->nodes)
- break;
- r = client->dataset[cursor].begin_position +
- client->dataset[cursor].total_size;
- client->dataset[++cursor].begin_position = r;
- }
- offset -= client->dataset[cursor].begin_position;
- if (offset < 0
- || offset > client->dataset[cursor].total_size)
- return ARCHIVE_FATAL;
- if ((r = client_seek_proxy(filter, offset, SEEK_SET)) < 0)
- return r;
- break;
-
- case SEEK_END:
- cursor = 0;
- while (1) {
- if (client->dataset[cursor].begin_position < 0 ||
- client->dataset[cursor].total_size < 0 ||
- cursor + 1 >= client->nodes)
- break;
- r = client->dataset[cursor].begin_position +
- client->dataset[cursor].total_size;
- client->dataset[++cursor].begin_position = r;
- }
- while (1) {
- r = client_switch_proxy(filter, cursor);
- if (r != ARCHIVE_OK)
- return r;
- if ((r = client_seek_proxy(filter, 0, SEEK_END)) < 0)
- return r;
- client->dataset[cursor].total_size = r;
- r = client->dataset[cursor].begin_position +
- client->dataset[cursor].total_size;
- if (cursor + 1 >= client->nodes)
- break;
- client->dataset[++cursor].begin_position = r;
- }
- while (1) {
- if (r + offset >=
- client->dataset[cursor].begin_position)
- break;
- offset += client->dataset[cursor].total_size;
- if (cursor == 0)
- break;
- cursor--;
- r = client->dataset[cursor].begin_position +
- client->dataset[cursor].total_size;
- }
- offset = (r + offset) - client->dataset[cursor].begin_position;
- if ((r = client_switch_proxy(filter, cursor)) != ARCHIVE_OK)
- return r;
- r = client_seek_proxy(filter, offset, SEEK_SET);
- if (r < ARCHIVE_OK)
- return r;
- break;
-
- default:
- return (ARCHIVE_FATAL);
- }
- r += client->dataset[cursor].begin_position;
-
- if (r >= 0) {
- /*
- * Ouch. Clearing the buffer like this hurts, especially
- * at bid time. A lot of our efficiency at bid time comes
- * from having bidders reuse the data we've already read.
- *
- * TODO: If the seek request is in data we already
- * have, then don't call the seek callback.
- *
- * TODO: Zip seeks to end-of-file at bid time. If
- * other formats also start doing this, we may need to
- * find a way for clients to fudge the seek offset to
- * a block boundary.
- *
- * Hmmm... If whence was SEEK_END, we know the file
- * size is (r - offset). Can we use that to simplify
- * the TODO items above?
- */
- filter->avail = filter->client_avail = 0;
- filter->next = filter->buffer;
- filter->position = r;
- filter->end_of_file = 0;
- }
- return r;
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_add_passphrase.c b/contrib/libs/libarchive/libarchive/archive_read_add_passphrase.c
deleted file mode 100644
index f0b1ab9330..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_add_passphrase.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*-
- * Copyright (c) 2014 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include "archive_read_private.h"
-
-static void
-add_passphrase_to_tail(struct archive_read *a,
- struct archive_read_passphrase *p)
-{
- *a->passphrases.last = p;
- a->passphrases.last = &p->next;
- p->next = NULL;
-}
-
-static struct archive_read_passphrase *
-remove_passphrases_from_head(struct archive_read *a)
-{
- struct archive_read_passphrase *p;
-
- p = a->passphrases.first;
- if (p != NULL)
- a->passphrases.first = p->next;
- return (p);
-}
-
-static void
-insert_passphrase_to_head(struct archive_read *a,
- struct archive_read_passphrase *p)
-{
- p->next = a->passphrases.first;
- a->passphrases.first = p;
- if (&a->passphrases.first == a->passphrases.last) {
- a->passphrases.last = &p->next;
- p->next = NULL;
- }
-}
-
-static struct archive_read_passphrase *
-new_read_passphrase(struct archive_read *a, const char *passphrase)
-{
- struct archive_read_passphrase *p;
-
- p = malloc(sizeof(*p));
- if (p == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (NULL);
- }
- p->passphrase = strdup(passphrase);
- if (p->passphrase == NULL) {
- free(p);
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (NULL);
- }
- return (p);
-}
-
-int
-archive_read_add_passphrase(struct archive *_a, const char *passphrase)
-{
- struct archive_read *a = (struct archive_read *)_a;
- struct archive_read_passphrase *p;
-
- archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
- "archive_read_add_passphrase");
-
- if (passphrase == NULL || passphrase[0] == '\0') {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Empty passphrase is unacceptable");
- return (ARCHIVE_FAILED);
- }
-
- p = new_read_passphrase(a, passphrase);
- if (p == NULL)
- return (ARCHIVE_FATAL);
- add_passphrase_to_tail(a, p);
-
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_set_passphrase_callback(struct archive *_a, void *client_data,
- archive_passphrase_callback *cb)
-{
- struct archive_read *a = (struct archive_read *)_a;
-
- archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
- "archive_read_set_passphrase_callback");
-
- a->passphrases.callback = cb;
- a->passphrases.client_data = client_data;
- return (ARCHIVE_OK);
-}
-
-/*
- * Call this in advance when you start to get a passphrase for decryption
- * for a entry.
- */
-void
-__archive_read_reset_passphrase(struct archive_read *a)
-{
-
- a->passphrases.candidate = -1;
-}
-
-/*
- * Get a passphrase for decryption.
- */
-const char *
-__archive_read_next_passphrase(struct archive_read *a)
-{
- struct archive_read_passphrase *p;
- const char *passphrase;
-
- if (a->passphrases.candidate < 0) {
- /* Count out how many passphrases we have. */
- int cnt = 0;
-
- for (p = a->passphrases.first; p != NULL; p = p->next)
- cnt++;
- a->passphrases.candidate = cnt;
- p = a->passphrases.first;
- } else if (a->passphrases.candidate > 1) {
- /* Rotate a passphrase list. */
- a->passphrases.candidate--;
- p = remove_passphrases_from_head(a);
- add_passphrase_to_tail(a, p);
- /* Pick a new passphrase candidate up. */
- p = a->passphrases.first;
- } else if (a->passphrases.candidate == 1) {
- /* This case is that all candidates failed to decrypt. */
- a->passphrases.candidate = 0;
- if (a->passphrases.first->next != NULL) {
- /* Rotate a passphrase list. */
- p = remove_passphrases_from_head(a);
- add_passphrase_to_tail(a, p);
- }
- p = NULL;
- } else /* There is no passphrase candidate. */
- p = NULL;
-
- if (p != NULL)
- passphrase = p->passphrase;
- else if (a->passphrases.callback != NULL) {
- /* Get a passphrase through a call-back function
- * since we tried all passphrases out or we don't
- * have it. */
- passphrase = a->passphrases.callback(&a->archive,
- a->passphrases.client_data);
- if (passphrase != NULL) {
- p = new_read_passphrase(a, passphrase);
- if (p == NULL)
- return (NULL);
- insert_passphrase_to_head(a, p);
- a->passphrases.candidate = 1;
- }
- } else
- passphrase = NULL;
-
- return (passphrase);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_append_filter.c b/contrib/libs/libarchive/libarchive/archive_read_append_filter.c
deleted file mode 100644
index 25dc4b2a2b..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_append_filter.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*-
- * Copyright (c) 2003-2012 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-int
-archive_read_append_filter(struct archive *_a, int code)
-{
- int r1, r2, number_bidders, i;
- char str[20];
- struct archive_read_filter_bidder *bidder;
- struct archive_read_filter *filter;
- struct archive_read *a = (struct archive_read *)_a;
-
- r2 = (ARCHIVE_OK);
- switch (code)
- {
- case ARCHIVE_FILTER_NONE:
- /* No filter to add, so do nothing.
- * NOTE: An initial "NONE" type filter is always set at the end of the
- * filter chain.
- */
- r1 = (ARCHIVE_OK);
- break;
- case ARCHIVE_FILTER_GZIP:
- strcpy(str, "gzip");
- r1 = archive_read_support_filter_gzip(_a);
- break;
- case ARCHIVE_FILTER_BZIP2:
- strcpy(str, "bzip2");
- r1 = archive_read_support_filter_bzip2(_a);
- break;
- case ARCHIVE_FILTER_COMPRESS:
- strcpy(str, "compress (.Z)");
- r1 = archive_read_support_filter_compress(_a);
- break;
- case ARCHIVE_FILTER_PROGRAM:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Cannot append program filter using archive_read_append_filter");
- return (ARCHIVE_FATAL);
- case ARCHIVE_FILTER_LZMA:
- strcpy(str, "lzma");
- r1 = archive_read_support_filter_lzma(_a);
- break;
- case ARCHIVE_FILTER_XZ:
- strcpy(str, "xz");
- r1 = archive_read_support_filter_xz(_a);
- break;
- case ARCHIVE_FILTER_UU:
- strcpy(str, "uu");
- r1 = archive_read_support_filter_uu(_a);
- break;
- case ARCHIVE_FILTER_RPM:
- strcpy(str, "rpm");
- r1 = archive_read_support_filter_rpm(_a);
- break;
- case ARCHIVE_FILTER_LZ4:
- strcpy(str, "lz4");
- r1 = archive_read_support_filter_lz4(_a);
- break;
- case ARCHIVE_FILTER_ZSTD:
- strcpy(str, "zstd");
- r1 = archive_read_support_filter_zstd(_a);
- break;
- case ARCHIVE_FILTER_LZIP:
- strcpy(str, "lzip");
- r1 = archive_read_support_filter_lzip(_a);
- break;
- case ARCHIVE_FILTER_LRZIP:
- strcpy(str, "lrzip");
- r1 = archive_read_support_filter_lrzip(_a);
- break;
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Invalid filter code specified");
- return (ARCHIVE_FATAL);
- }
-
- if (code != ARCHIVE_FILTER_NONE)
- {
- number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
-
- bidder = a->bidders;
- for (i = 0; i < number_bidders; i++, bidder++)
- {
- if (!bidder->name || !strcmp(bidder->name, str))
- break;
- }
- if (!bidder->name || strcmp(bidder->name, str))
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Internal error: Unable to append filter");
- return (ARCHIVE_FATAL);
- }
-
- filter
- = (struct archive_read_filter *)calloc(1, sizeof(*filter));
- if (filter == NULL)
- {
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- filter->bidder = bidder;
- filter->archive = a;
- filter->upstream = a->filter;
- a->filter = filter;
- r2 = (bidder->vtable->init)(a->filter);
- if (r2 != ARCHIVE_OK) {
- __archive_read_free_filters(a);
- return (ARCHIVE_FATAL);
- }
- }
-
- a->bypass_filter_bidding = 1;
- return (r1 < r2) ? r1 : r2;
-}
-
-int
-archive_read_append_filter_program(struct archive *_a, const char *cmd)
-{
- return (archive_read_append_filter_program_signature(_a, cmd, NULL, 0));
-}
-
-int
-archive_read_append_filter_program_signature(struct archive *_a,
- const char *cmd, const void *signature, size_t signature_len)
-{
- int r, number_bidders, i;
- struct archive_read_filter_bidder *bidder;
- struct archive_read_filter *filter;
- struct archive_read *a = (struct archive_read *)_a;
-
- if (archive_read_support_filter_program_signature(_a, cmd, signature,
- signature_len) != (ARCHIVE_OK))
- return (ARCHIVE_FATAL);
-
- number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
-
- bidder = a->bidders;
- for (i = 0; i < number_bidders; i++, bidder++)
- {
- /* Program bidder name set to filter name after initialization */
- if (bidder->data && !bidder->name)
- break;
- }
- if (!bidder->data)
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Internal error: Unable to append program filter");
- return (ARCHIVE_FATAL);
- }
-
- filter
- = (struct archive_read_filter *)calloc(1, sizeof(*filter));
- if (filter == NULL)
- {
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- filter->bidder = bidder;
- filter->archive = a;
- filter->upstream = a->filter;
- a->filter = filter;
- r = (bidder->vtable->init)(a->filter);
- if (r != ARCHIVE_OK) {
- __archive_read_free_filters(a);
- return (ARCHIVE_FATAL);
- }
- bidder->name = a->filter->name;
-
- a->bypass_filter_bidding = 1;
- return r;
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_data_into_fd.c b/contrib/libs/libarchive/libarchive/archive_read_data_into_fd.c
deleted file mode 100644
index f16ca5c82b..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_data_into_fd.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_data_into_fd.c,v 1.16 2008/05/23 05:01:29 cperciva Exp $");
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-
-/* Maximum amount of data to write at one time. */
-#define MAX_WRITE (1024 * 1024)
-
-/*
- * This implementation minimizes copying of data and is sparse-file aware.
- */
-static int
-pad_to(struct archive *a, int fd, int can_lseek,
- size_t nulls_size, const char *nulls,
- int64_t target_offset, int64_t actual_offset)
-{
- size_t to_write;
- ssize_t bytes_written;
-
- if (can_lseek) {
- actual_offset = lseek(fd,
- target_offset - actual_offset, SEEK_CUR);
- if (actual_offset != target_offset) {
- archive_set_error(a, errno, "Seek error");
- return (ARCHIVE_FATAL);
- }
- return (ARCHIVE_OK);
- }
- while (target_offset > actual_offset) {
- to_write = nulls_size;
- if (target_offset < actual_offset + (int64_t)nulls_size)
- to_write = (size_t)(target_offset - actual_offset);
- bytes_written = write(fd, nulls, to_write);
- if (bytes_written < 0) {
- archive_set_error(a, errno, "Write error");
- return (ARCHIVE_FATAL);
- }
- actual_offset += bytes_written;
- }
- return (ARCHIVE_OK);
-}
-
-
-int
-archive_read_data_into_fd(struct archive *a, int fd)
-{
- struct stat st;
- int r, r2;
- const void *buff;
- size_t size, bytes_to_write;
- ssize_t bytes_written;
- int64_t target_offset;
- int64_t actual_offset = 0;
- int can_lseek;
- char *nulls = NULL;
- size_t nulls_size = 16384;
-
- archive_check_magic(a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
- "archive_read_data_into_fd");
-
- can_lseek = (fstat(fd, &st) == 0) && S_ISREG(st.st_mode);
- if (!can_lseek) {
- nulls = calloc(1, nulls_size);
- if (!nulls) {
- r = ARCHIVE_FATAL;
- goto cleanup;
- }
- }
-
- while ((r = archive_read_data_block(a, &buff, &size, &target_offset)) ==
- ARCHIVE_OK) {
- const char *p = buff;
- if (target_offset > actual_offset) {
- r = pad_to(a, fd, can_lseek, nulls_size, nulls,
- target_offset, actual_offset);
- if (r != ARCHIVE_OK)
- break;
- actual_offset = target_offset;
- }
- while (size > 0) {
- bytes_to_write = size;
- if (bytes_to_write > MAX_WRITE)
- bytes_to_write = MAX_WRITE;
- bytes_written = write(fd, p, bytes_to_write);
- if (bytes_written < 0) {
- archive_set_error(a, errno, "Write error");
- r = ARCHIVE_FATAL;
- goto cleanup;
- }
- actual_offset += bytes_written;
- p += bytes_written;
- size -= bytes_written;
- }
- }
-
- if (r == ARCHIVE_EOF && target_offset > actual_offset) {
- r2 = pad_to(a, fd, can_lseek, nulls_size, nulls,
- target_offset, actual_offset);
- if (r2 != ARCHIVE_OK)
- r = r2;
- }
-
-cleanup:
- free(nulls);
- if (r != ARCHIVE_EOF)
- return (r);
- return (ARCHIVE_OK);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_disk_entry_from_file.c b/contrib/libs/libarchive/libarchive/archive_read_disk_entry_from_file.c
deleted file mode 100644
index bff25b627c..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_disk_entry_from_file.c
+++ /dev/null
@@ -1,1086 +0,0 @@
-/*-
- * Copyright (c) 2003-2009 Tim Kientzle
- * Copyright (c) 2010-2012 Michihiro NAKAJIMA
- * Copyright (c) 2016 Martin Matuska
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD");
-
-/* This is the tree-walking code for POSIX systems. */
-#if !defined(_WIN32) || defined(__CYGWIN__)
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_EXTATTR_H
-#include <sys/extattr.h>
-#endif
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#if defined(HAVE_SYS_XATTR_H)
-#include <sys/xattr.h>
-#elif defined(HAVE_ATTR_XATTR_H)
-#include <attr/xattr.h>
-#endif
-#ifdef HAVE_SYS_EA_H
-#error #include <sys/ea.h>
-#endif
-#ifdef HAVE_COPYFILE_H
-#include <copyfile.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-#ifdef HAVE_LINUX_TYPES_H
-#include <linux/types.h>
-#endif
-#ifdef HAVE_LINUX_FIEMAP_H
-#include <linux/fiemap.h>
-#endif
-#ifdef HAVE_LINUX_FS_H
-#include <linux/fs.h>
-#endif
-/*
- * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
- * As the include guards don't agree, the order of include is important.
- */
-#ifdef HAVE_LINUX_EXT2_FS_H
-#error #include <linux/ext2_fs.h> /* for Linux file flags */
-#endif
-#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
-#error #include <ext2fs/ext2_fs.h> /* Linux file flags, broken on Cygwin */
-#endif
-#ifdef HAVE_PATHS_H
-#include <paths.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_private.h"
-#include "archive_read_disk_private.h"
-
-#ifndef O_CLOEXEC
-#define O_CLOEXEC 0
-#endif
-
-static int setup_mac_metadata(struct archive_read_disk *,
- struct archive_entry *, int *fd);
-#ifdef ARCHIVE_XATTR_FREEBSD
-static int setup_xattrs_namespace(struct archive_read_disk *,
- struct archive_entry *, int *, int);
-#endif
-static int setup_xattrs(struct archive_read_disk *,
- struct archive_entry *, int *fd);
-static int setup_sparse(struct archive_read_disk *,
- struct archive_entry *, int *fd);
-#if defined(HAVE_LINUX_FIEMAP_H)
-static int setup_sparse_fiemap(struct archive_read_disk *,
- struct archive_entry *, int *fd);
-#endif
-
-#if !ARCHIVE_ACL_SUPPORT
-int
-archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
- struct archive_entry *entry, int *fd)
-{
- (void)a; /* UNUSED */
- (void)entry; /* UNUSED */
- (void)fd; /* UNUSED */
- return (ARCHIVE_OK);
-}
-#endif
-
-/*
- * Enter working directory and return working pathname of archive_entry.
- * If a pointer to an integer is provided and its value is below zero
- * open a file descriptor on this pathname.
- */
-const char *
-archive_read_disk_entry_setup_path(struct archive_read_disk *a,
- struct archive_entry *entry, int *fd)
-{
- const char *path;
-
- path = archive_entry_sourcepath(entry);
-
- if (path == NULL || (a->tree != NULL &&
- a->tree_enter_working_dir(a->tree) != 0))
- path = archive_entry_pathname(entry);
- if (path == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Couldn't determine path");
- } else if (fd != NULL && *fd < 0 && a->tree != NULL &&
- (a->follow_symlinks || archive_entry_filetype(entry) != AE_IFLNK)) {
- *fd = a->open_on_current_dir(a->tree, path,
- O_RDONLY | O_NONBLOCK);
- }
- return (path);
-}
-
-int
-archive_read_disk_entry_from_file(struct archive *_a,
- struct archive_entry *entry,
- int fd,
- const struct stat *st)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- const char *path, *name;
- struct stat s;
- int initial_fd = fd;
- int r, r1;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_ANY,
- "archive_read_disk_entry_from_file");
-
- archive_clear_error(_a);
- path = archive_entry_sourcepath(entry);
- if (path == NULL)
- path = archive_entry_pathname(entry);
-
- if (a->tree == NULL) {
- if (st == NULL) {
-#if HAVE_FSTAT
- if (fd >= 0) {
- if (fstat(fd, &s) != 0) {
- archive_set_error(&a->archive, errno,
- "Can't fstat");
- return (ARCHIVE_FAILED);
- }
- } else
-#endif
-#if HAVE_LSTAT
- if (!a->follow_symlinks) {
- if (lstat(path, &s) != 0) {
- archive_set_error(&a->archive, errno,
- "Can't lstat %s", path);
- return (ARCHIVE_FAILED);
- }
- } else
-#endif
- if (la_stat(path, &s) != 0) {
- archive_set_error(&a->archive, errno,
- "Can't stat %s", path);
- return (ARCHIVE_FAILED);
- }
- st = &s;
- }
- archive_entry_copy_stat(entry, st);
- }
-
- /* Lookup uname/gname */
- name = archive_read_disk_uname(_a, archive_entry_uid(entry));
- if (name != NULL)
- archive_entry_copy_uname(entry, name);
- name = archive_read_disk_gname(_a, archive_entry_gid(entry));
- if (name != NULL)
- archive_entry_copy_gname(entry, name);
-
-#ifdef HAVE_STRUCT_STAT_ST_FLAGS
- /* On FreeBSD, we get flags for free with the stat. */
- /* TODO: Does this belong in copy_stat()? */
- if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0 && st->st_flags != 0)
- archive_entry_set_fflags(entry, st->st_flags, 0);
-#endif
-
-#if (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \
- (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS))
- /* Linux requires an extra ioctl to pull the flags. Although
- * this is an extra step, it has a nice side-effect: We get an
- * open file descriptor which we can use in the subsequent lookups. */
- if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0 &&
- (S_ISREG(st->st_mode) || S_ISDIR(st->st_mode))) {
- if (fd < 0) {
- if (a->tree != NULL)
- fd = a->open_on_current_dir(a->tree, path,
- O_RDONLY | O_NONBLOCK | O_CLOEXEC);
- else
- fd = open(path, O_RDONLY | O_NONBLOCK |
- O_CLOEXEC);
- __archive_ensure_cloexec_flag(fd);
- }
- if (fd >= 0) {
- int stflags;
- r = ioctl(fd,
-#if defined(FS_IOC_GETFLAGS)
- FS_IOC_GETFLAGS,
-#else
- EXT2_IOC_GETFLAGS,
-#endif
- &stflags);
- if (r == 0 && stflags != 0)
- archive_entry_set_fflags(entry, stflags, 0);
- }
- }
-#endif
-
-#if defined(HAVE_READLINK) || defined(HAVE_READLINKAT)
- if (S_ISLNK(st->st_mode)) {
- size_t linkbuffer_len = st->st_size;
- char *linkbuffer;
- int lnklen;
-
- linkbuffer = malloc(linkbuffer_len + 1);
- if (linkbuffer == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Couldn't read link data");
- return (ARCHIVE_FAILED);
- }
- if (a->tree != NULL) {
-#ifdef HAVE_READLINKAT
- lnklen = readlinkat(a->tree_current_dir_fd(a->tree),
- path, linkbuffer, linkbuffer_len);
-#else
- if (a->tree_enter_working_dir(a->tree) != 0) {
- archive_set_error(&a->archive, errno,
- "Couldn't read link data");
- free(linkbuffer);
- return (ARCHIVE_FAILED);
- }
- lnklen = readlink(path, linkbuffer, linkbuffer_len);
-#endif /* HAVE_READLINKAT */
- } else
- lnklen = readlink(path, linkbuffer, linkbuffer_len);
- if (lnklen < 0) {
- archive_set_error(&a->archive, errno,
- "Couldn't read link data");
- free(linkbuffer);
- return (ARCHIVE_FAILED);
- }
- linkbuffer[lnklen] = '\0';
- archive_entry_set_symlink(entry, linkbuffer);
- free(linkbuffer);
- }
-#endif /* HAVE_READLINK || HAVE_READLINKAT */
-
- r = 0;
- if ((a->flags & ARCHIVE_READDISK_NO_ACL) == 0)
- r = archive_read_disk_entry_setup_acls(a, entry, &fd);
- if ((a->flags & ARCHIVE_READDISK_NO_XATTR) == 0) {
- r1 = setup_xattrs(a, entry, &fd);
- if (r1 < r)
- r = r1;
- }
- if (a->flags & ARCHIVE_READDISK_MAC_COPYFILE) {
- r1 = setup_mac_metadata(a, entry, &fd);
- if (r1 < r)
- r = r1;
- }
- if ((a->flags & ARCHIVE_READDISK_NO_SPARSE) == 0) {
- r1 = setup_sparse(a, entry, &fd);
- if (r1 < r)
- r = r1;
- }
-
- /* If we opened the file earlier in this function, close it. */
- if (initial_fd != fd)
- close(fd);
- return (r);
-}
-
-#if defined(__APPLE__) && defined(HAVE_COPYFILE_H)
-/*
- * The Mac OS "copyfile()" API copies the extended metadata for a
- * file into a separate file in AppleDouble format (see RFC 1740).
- *
- * Mac OS tar and cpio implementations store this extended
- * metadata as a separate entry just before the regular entry
- * with a "._" prefix added to the filename.
- *
- * Note that this is currently done unconditionally; the tar program has
- * an option to discard this information before the archive is written.
- *
- * TODO: If there's a failure, report it and return ARCHIVE_WARN.
- */
-static int
-setup_mac_metadata(struct archive_read_disk *a,
- struct archive_entry *entry, int *fd)
-{
- int tempfd = -1;
- int copyfile_flags = COPYFILE_NOFOLLOW | COPYFILE_ACL | COPYFILE_XATTR;
- struct stat copyfile_stat;
- int ret = ARCHIVE_OK;
- void *buff = NULL;
- int have_attrs;
- const char *name, *tempdir;
- struct archive_string tempfile;
-
- (void)fd; /* UNUSED */
-
- name = archive_read_disk_entry_setup_path(a, entry, NULL);
- if (name == NULL)
- return (ARCHIVE_WARN);
-
- /* Short-circuit if there's nothing to do. */
- have_attrs = copyfile(name, NULL, 0, copyfile_flags | COPYFILE_CHECK);
- if (have_attrs == -1) {
- archive_set_error(&a->archive, errno,
- "Could not check extended attributes");
- return (ARCHIVE_WARN);
- }
- if (have_attrs == 0)
- return (ARCHIVE_OK);
-
- tempdir = NULL;
- if (issetugid() == 0)
- tempdir = getenv("TMPDIR");
- if (tempdir == NULL)
- tempdir = _PATH_TMP;
- archive_string_init(&tempfile);
- archive_strcpy(&tempfile, tempdir);
- archive_strcat(&tempfile, "tar.md.XXXXXX");
- tempfd = mkstemp(tempfile.s);
- if (tempfd < 0) {
- archive_set_error(&a->archive, errno,
- "Could not open extended attribute file");
- ret = ARCHIVE_WARN;
- goto cleanup;
- }
- __archive_ensure_cloexec_flag(tempfd);
-
- /* XXX I wish copyfile() could pack directly to a memory
- * buffer; that would avoid the temp file here. For that
- * matter, it would be nice if fcopyfile() actually worked,
- * that would reduce the many open/close races here. */
- if (copyfile(name, tempfile.s, 0, copyfile_flags | COPYFILE_PACK)) {
- archive_set_error(&a->archive, errno,
- "Could not pack extended attributes");
- ret = ARCHIVE_WARN;
- goto cleanup;
- }
- if (fstat(tempfd, &copyfile_stat)) {
- archive_set_error(&a->archive, errno,
- "Could not check size of extended attributes");
- ret = ARCHIVE_WARN;
- goto cleanup;
- }
- buff = malloc(copyfile_stat.st_size);
- if (buff == NULL) {
- archive_set_error(&a->archive, errno,
- "Could not allocate memory for extended attributes");
- ret = ARCHIVE_WARN;
- goto cleanup;
- }
- if (copyfile_stat.st_size != read(tempfd, buff, copyfile_stat.st_size)) {
- archive_set_error(&a->archive, errno,
- "Could not read extended attributes into memory");
- ret = ARCHIVE_WARN;
- goto cleanup;
- }
- archive_entry_copy_mac_metadata(entry, buff, copyfile_stat.st_size);
-
-cleanup:
- if (tempfd >= 0) {
- close(tempfd);
- unlink(tempfile.s);
- }
- archive_string_free(&tempfile);
- free(buff);
- return (ret);
-}
-
-#else
-
-/*
- * Stub implementation for non-Mac systems.
- */
-static int
-setup_mac_metadata(struct archive_read_disk *a,
- struct archive_entry *entry, int *fd)
-{
- (void)a; /* UNUSED */
- (void)entry; /* UNUSED */
- (void)fd; /* UNUSED */
- return (ARCHIVE_OK);
-}
-#endif
-
-#if ARCHIVE_XATTR_LINUX || ARCHIVE_XATTR_DARWIN || ARCHIVE_XATTR_AIX
-
-/*
- * Linux, Darwin and AIX extended attribute support.
- *
- * TODO: By using a stack-allocated buffer for the first
- * call to getxattr(), we might be able to avoid the second
- * call entirely. We only need the second call if the
- * stack-allocated buffer is too small. But a modest buffer
- * of 1024 bytes or so will often be big enough. Same applies
- * to listxattr().
- */
-
-
-static int
-setup_xattr(struct archive_read_disk *a,
- struct archive_entry *entry, const char *name, int fd, const char *accpath)
-{
- ssize_t size;
- void *value = NULL;
-
-
- if (fd >= 0) {
-#if ARCHIVE_XATTR_LINUX
- size = fgetxattr(fd, name, NULL, 0);
-#elif ARCHIVE_XATTR_DARWIN
- size = fgetxattr(fd, name, NULL, 0, 0, 0);
-#elif ARCHIVE_XATTR_AIX
- size = fgetea(fd, name, NULL, 0);
-#endif
- } else if (!a->follow_symlinks) {
-#if ARCHIVE_XATTR_LINUX
- size = lgetxattr(accpath, name, NULL, 0);
-#elif ARCHIVE_XATTR_DARWIN
- size = getxattr(accpath, name, NULL, 0, 0, XATTR_NOFOLLOW);
-#elif ARCHIVE_XATTR_AIX
- size = lgetea(accpath, name, NULL, 0);
-#endif
- } else {
-#if ARCHIVE_XATTR_LINUX
- size = getxattr(accpath, name, NULL, 0);
-#elif ARCHIVE_XATTR_DARWIN
- size = getxattr(accpath, name, NULL, 0, 0, 0);
-#elif ARCHIVE_XATTR_AIX
- size = getea(accpath, name, NULL, 0);
-#endif
- }
-
- if (size == -1) {
- archive_set_error(&a->archive, errno,
- "Couldn't query extended attribute");
- return (ARCHIVE_WARN);
- }
-
- if (size > 0 && (value = malloc(size)) == NULL) {
- archive_set_error(&a->archive, errno, "Out of memory");
- return (ARCHIVE_FATAL);
- }
-
-
- if (fd >= 0) {
-#if ARCHIVE_XATTR_LINUX
- size = fgetxattr(fd, name, value, size);
-#elif ARCHIVE_XATTR_DARWIN
- size = fgetxattr(fd, name, value, size, 0, 0);
-#elif ARCHIVE_XATTR_AIX
- size = fgetea(fd, name, value, size);
-#endif
- } else if (!a->follow_symlinks) {
-#if ARCHIVE_XATTR_LINUX
- size = lgetxattr(accpath, name, value, size);
-#elif ARCHIVE_XATTR_DARWIN
- size = getxattr(accpath, name, value, size, 0, XATTR_NOFOLLOW);
-#elif ARCHIVE_XATTR_AIX
- size = lgetea(accpath, name, value, size);
-#endif
- } else {
-#if ARCHIVE_XATTR_LINUX
- size = getxattr(accpath, name, value, size);
-#elif ARCHIVE_XATTR_DARWIN
- size = getxattr(accpath, name, value, size, 0, 0);
-#elif ARCHIVE_XATTR_AIX
- size = getea(accpath, name, value, size);
-#endif
- }
-
- if (size == -1) {
- archive_set_error(&a->archive, errno,
- "Couldn't read extended attribute");
- return (ARCHIVE_WARN);
- }
-
- archive_entry_xattr_add_entry(entry, name, value, size);
-
- free(value);
- return (ARCHIVE_OK);
-}
-
-static int
-setup_xattrs(struct archive_read_disk *a,
- struct archive_entry *entry, int *fd)
-{
- char *list, *p;
- const char *path;
- ssize_t list_size;
-
- path = NULL;
-
- if (*fd < 0) {
- path = archive_read_disk_entry_setup_path(a, entry, fd);
- if (path == NULL)
- return (ARCHIVE_WARN);
- }
-
- if (*fd >= 0) {
-#if ARCHIVE_XATTR_LINUX
- list_size = flistxattr(*fd, NULL, 0);
-#elif ARCHIVE_XATTR_DARWIN
- list_size = flistxattr(*fd, NULL, 0, 0);
-#elif ARCHIVE_XATTR_AIX
- list_size = flistea(*fd, NULL, 0);
-#endif
- } else if (!a->follow_symlinks) {
-#if ARCHIVE_XATTR_LINUX
- list_size = llistxattr(path, NULL, 0);
-#elif ARCHIVE_XATTR_DARWIN
- list_size = listxattr(path, NULL, 0, XATTR_NOFOLLOW);
-#elif ARCHIVE_XATTR_AIX
- list_size = llistea(path, NULL, 0);
-#endif
- } else {
-#if ARCHIVE_XATTR_LINUX
- list_size = listxattr(path, NULL, 0);
-#elif ARCHIVE_XATTR_DARWIN
- list_size = listxattr(path, NULL, 0, 0);
-#elif ARCHIVE_XATTR_AIX
- list_size = listea(path, NULL, 0);
-#endif
- }
-
- if (list_size == -1) {
- if (errno == ENOTSUP || errno == ENOSYS)
- return (ARCHIVE_OK);
- archive_set_error(&a->archive, errno,
- "Couldn't list extended attributes");
- return (ARCHIVE_WARN);
- }
-
- if (list_size == 0)
- return (ARCHIVE_OK);
-
- if ((list = malloc(list_size)) == NULL) {
- archive_set_error(&a->archive, errno, "Out of memory");
- return (ARCHIVE_FATAL);
- }
-
- if (*fd >= 0) {
-#if ARCHIVE_XATTR_LINUX
- list_size = flistxattr(*fd, list, list_size);
-#elif ARCHIVE_XATTR_DARWIN
- list_size = flistxattr(*fd, list, list_size, 0);
-#elif ARCHIVE_XATTR_AIX
- list_size = flistea(*fd, list, list_size);
-#endif
- } else if (!a->follow_symlinks) {
-#if ARCHIVE_XATTR_LINUX
- list_size = llistxattr(path, list, list_size);
-#elif ARCHIVE_XATTR_DARWIN
- list_size = listxattr(path, list, list_size, XATTR_NOFOLLOW);
-#elif ARCHIVE_XATTR_AIX
- list_size = llistea(path, list, list_size);
-#endif
- } else {
-#if ARCHIVE_XATTR_LINUX
- list_size = listxattr(path, list, list_size);
-#elif ARCHIVE_XATTR_DARWIN
- list_size = listxattr(path, list, list_size, 0);
-#elif ARCHIVE_XATTR_AIX
- list_size = listea(path, list, list_size);
-#endif
- }
-
- if (list_size == -1) {
- archive_set_error(&a->archive, errno,
- "Couldn't retrieve extended attributes");
- free(list);
- return (ARCHIVE_WARN);
- }
-
- for (p = list; (p - list) < list_size; p += strlen(p) + 1) {
-#if ARCHIVE_XATTR_LINUX
- /* Linux: skip POSIX.1e ACL extended attributes */
- if (strncmp(p, "system.", 7) == 0 &&
- (strcmp(p + 7, "posix_acl_access") == 0 ||
- strcmp(p + 7, "posix_acl_default") == 0))
- continue;
- if (strncmp(p, "trusted.SGI_", 12) == 0 &&
- (strcmp(p + 12, "ACL_DEFAULT") == 0 ||
- strcmp(p + 12, "ACL_FILE") == 0))
- continue;
-
- /* Linux: xfsroot namespace is obsolete and unsupported */
- if (strncmp(p, "xfsroot.", 8) == 0)
- continue;
-#endif
- setup_xattr(a, entry, p, *fd, path);
- }
-
- free(list);
- return (ARCHIVE_OK);
-}
-
-#elif ARCHIVE_XATTR_FREEBSD
-
-/*
- * FreeBSD extattr interface.
- */
-
-/* TODO: Implement this. Follow the Linux model above, but
- * with FreeBSD-specific system calls, of course. Be careful
- * to not include the system extattrs that hold ACLs; we handle
- * those separately.
- */
-static int
-setup_xattr(struct archive_read_disk *a, struct archive_entry *entry,
- int namespace, const char *name, const char *fullname, int fd,
- const char *path);
-
-static int
-setup_xattr(struct archive_read_disk *a, struct archive_entry *entry,
- int namespace, const char *name, const char *fullname, int fd,
- const char *accpath)
-{
- ssize_t size;
- void *value = NULL;
-
- if (fd >= 0)
- size = extattr_get_fd(fd, namespace, name, NULL, 0);
- else if (!a->follow_symlinks)
- size = extattr_get_link(accpath, namespace, name, NULL, 0);
- else
- size = extattr_get_file(accpath, namespace, name, NULL, 0);
-
- if (size == -1) {
- archive_set_error(&a->archive, errno,
- "Couldn't query extended attribute");
- return (ARCHIVE_WARN);
- }
-
- if (size > 0 && (value = malloc(size)) == NULL) {
- archive_set_error(&a->archive, errno, "Out of memory");
- return (ARCHIVE_FATAL);
- }
-
- if (fd >= 0)
- size = extattr_get_fd(fd, namespace, name, value, size);
- else if (!a->follow_symlinks)
- size = extattr_get_link(accpath, namespace, name, value, size);
- else
- size = extattr_get_file(accpath, namespace, name, value, size);
-
- if (size == -1) {
- free(value);
- archive_set_error(&a->archive, errno,
- "Couldn't read extended attribute");
- return (ARCHIVE_WARN);
- }
-
- archive_entry_xattr_add_entry(entry, fullname, value, size);
-
- free(value);
- return (ARCHIVE_OK);
-}
-
-static int
-setup_xattrs_namespace(struct archive_read_disk *a,
- struct archive_entry *entry, int *fd, int namespace)
-{
- char buff[512];
- char *list, *p;
- ssize_t list_size;
- const char *path;
-
- path = NULL;
-
- if (*fd < 0) {
- path = archive_read_disk_entry_setup_path(a, entry, fd);
- if (path == NULL)
- return (ARCHIVE_WARN);
- }
-
- if (*fd >= 0)
- list_size = extattr_list_fd(*fd, namespace, NULL, 0);
- else if (!a->follow_symlinks)
- list_size = extattr_list_link(path, namespace, NULL, 0);
- else
- list_size = extattr_list_file(path, namespace, NULL, 0);
-
- if (list_size == -1 && errno == EOPNOTSUPP)
- return (ARCHIVE_OK);
- if (list_size == -1 && errno == EPERM)
- return (ARCHIVE_OK);
- if (list_size == -1) {
- archive_set_error(&a->archive, errno,
- "Couldn't list extended attributes");
- return (ARCHIVE_WARN);
- }
-
- if (list_size == 0)
- return (ARCHIVE_OK);
-
- if ((list = malloc(list_size)) == NULL) {
- archive_set_error(&a->archive, errno, "Out of memory");
- return (ARCHIVE_FATAL);
- }
-
- if (*fd >= 0)
- list_size = extattr_list_fd(*fd, namespace, list, list_size);
- else if (!a->follow_symlinks)
- list_size = extattr_list_link(path, namespace, list, list_size);
- else
- list_size = extattr_list_file(path, namespace, list, list_size);
-
- if (list_size == -1) {
- archive_set_error(&a->archive, errno,
- "Couldn't retrieve extended attributes");
- free(list);
- return (ARCHIVE_WARN);
- }
-
- p = list;
- while ((p - list) < list_size) {
- size_t len = 255 & (int)*p;
- char *name;
-
- if (namespace == EXTATTR_NAMESPACE_SYSTEM) {
- if (!strcmp(p + 1, "nfs4.acl") ||
- !strcmp(p + 1, "posix1e.acl_access") ||
- !strcmp(p + 1, "posix1e.acl_default")) {
- p += 1 + len;
- continue;
- }
- strcpy(buff, "system.");
- } else {
- strcpy(buff, "user.");
- }
- name = buff + strlen(buff);
- memcpy(name, p + 1, len);
- name[len] = '\0';
- setup_xattr(a, entry, namespace, name, buff, *fd, path);
- p += 1 + len;
- }
-
- free(list);
- return (ARCHIVE_OK);
-}
-
-static int
-setup_xattrs(struct archive_read_disk *a,
- struct archive_entry *entry, int *fd)
-{
- int namespaces[2];
- int i, res;
-
- namespaces[0] = EXTATTR_NAMESPACE_USER;
- namespaces[1] = EXTATTR_NAMESPACE_SYSTEM;
-
- for (i = 0; i < 2; i++) {
- res = setup_xattrs_namespace(a, entry, fd,
- namespaces[i]);
- switch (res) {
- case (ARCHIVE_OK):
- case (ARCHIVE_WARN):
- break;
- default:
- return (res);
- }
- }
-
- return (ARCHIVE_OK);
-}
-
-#else
-
-/*
- * Generic (stub) extended attribute support.
- */
-static int
-setup_xattrs(struct archive_read_disk *a,
- struct archive_entry *entry, int *fd)
-{
- (void)a; /* UNUSED */
- (void)entry; /* UNUSED */
- (void)fd; /* UNUSED */
- return (ARCHIVE_OK);
-}
-
-#endif
-
-#if defined(HAVE_LINUX_FIEMAP_H)
-
-/*
- * Linux FIEMAP sparse interface.
- *
- * The FIEMAP ioctl returns an "extent" for each physical allocation
- * on disk. We need to process those to generate a more compact list
- * of logical file blocks. We also need to be very careful to use
- * FIEMAP_FLAG_SYNC here, since there are reports that Linux sometimes
- * does not report allocations for newly-written data that hasn't
- * been synced to disk.
- *
- * It's important to return a minimal sparse file list because we want
- * to not trigger sparse file extensions if we don't have to, since
- * not all readers support them.
- */
-
-static int
-setup_sparse_fiemap(struct archive_read_disk *a,
- struct archive_entry *entry, int *fd)
-{
- char buff[4096];
- struct fiemap *fm;
- struct fiemap_extent *fe;
- int64_t size;
- int count, do_fiemap, iters;
- int exit_sts = ARCHIVE_OK;
- const char *path;
-
- if (archive_entry_filetype(entry) != AE_IFREG
- || archive_entry_size(entry) <= 0
- || archive_entry_hardlink(entry) != NULL)
- return (ARCHIVE_OK);
-
- if (*fd < 0) {
- path = archive_read_disk_entry_setup_path(a, entry, NULL);
- if (path == NULL)
- return (ARCHIVE_FAILED);
-
- if (a->tree != NULL)
- *fd = a->open_on_current_dir(a->tree, path,
- O_RDONLY | O_NONBLOCK | O_CLOEXEC);
- else
- *fd = open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
- if (*fd < 0) {
- archive_set_error(&a->archive, errno,
- "Can't open `%s'", path);
- return (ARCHIVE_FAILED);
- }
- __archive_ensure_cloexec_flag(*fd);
- }
-
- /* Initialize buffer to avoid the error valgrind complains about. */
- memset(buff, 0, sizeof(buff));
- count = (sizeof(buff) - sizeof(*fm))/sizeof(*fe);
- fm = (struct fiemap *)buff;
- fm->fm_start = 0;
- fm->fm_length = ~0ULL;;
- fm->fm_flags = FIEMAP_FLAG_SYNC;
- fm->fm_extent_count = count;
- do_fiemap = 1;
- size = archive_entry_size(entry);
- for (iters = 0; ; ++iters) {
- int i, r;
-
- r = ioctl(*fd, FS_IOC_FIEMAP, fm);
- if (r < 0) {
- /* When something error happens, it is better we
- * should return ARCHIVE_OK because an earlier
- * version(<2.6.28) cannot perform FS_IOC_FIEMAP. */
- goto exit_setup_sparse_fiemap;
- }
- if (fm->fm_mapped_extents == 0) {
- if (iters == 0) {
- /* Fully sparse file; insert a zero-length "data" entry */
- archive_entry_sparse_add_entry(entry, 0, 0);
- }
- break;
- }
- fe = fm->fm_extents;
- for (i = 0; i < (int)fm->fm_mapped_extents; i++, fe++) {
- if (!(fe->fe_flags & FIEMAP_EXTENT_UNWRITTEN)) {
- /* The fe_length of the last block does not
- * adjust itself to its size files. */
- int64_t length = fe->fe_length;
- if (fe->fe_logical + length > (uint64_t)size)
- length -= fe->fe_logical + length - size;
- if (fe->fe_logical == 0 && length == size) {
- /* This is not sparse. */
- do_fiemap = 0;
- break;
- }
- if (length > 0)
- archive_entry_sparse_add_entry(entry,
- fe->fe_logical, length);
- }
- if (fe->fe_flags & FIEMAP_EXTENT_LAST)
- do_fiemap = 0;
- }
- if (do_fiemap) {
- fe = fm->fm_extents + fm->fm_mapped_extents -1;
- fm->fm_start = fe->fe_logical + fe->fe_length;
- } else
- break;
- }
-exit_setup_sparse_fiemap:
- return (exit_sts);
-}
-
-#if !defined(SEEK_HOLE) || !defined(SEEK_DATA)
-static int
-setup_sparse(struct archive_read_disk *a,
- struct archive_entry *entry, int *fd)
-{
- return setup_sparse_fiemap(a, entry, fd);
-}
-#endif
-#endif /* defined(HAVE_LINUX_FIEMAP_H) */
-
-#if defined(SEEK_HOLE) && defined(SEEK_DATA)
-
-/*
- * SEEK_HOLE sparse interface (FreeBSD, Linux, Solaris)
- */
-
-static int
-setup_sparse(struct archive_read_disk *a,
- struct archive_entry *entry, int *fd)
-{
- int64_t size;
- off_t initial_off;
- off_t off_s, off_e;
- int exit_sts = ARCHIVE_OK;
- int check_fully_sparse = 0;
- const char *path;
-
- if (archive_entry_filetype(entry) != AE_IFREG
- || archive_entry_size(entry) <= 0
- || archive_entry_hardlink(entry) != NULL)
- return (ARCHIVE_OK);
-
- /* Does filesystem support the reporting of hole ? */
- if (*fd < 0)
- path = archive_read_disk_entry_setup_path(a, entry, fd);
- else
- path = NULL;
-
- if (*fd >= 0) {
-#ifdef _PC_MIN_HOLE_SIZE
- if (fpathconf(*fd, _PC_MIN_HOLE_SIZE) <= 0)
- return (ARCHIVE_OK);
-#endif
- initial_off = lseek(*fd, 0, SEEK_CUR);
- if (initial_off != 0)
- lseek(*fd, 0, SEEK_SET);
- } else {
- if (path == NULL)
- return (ARCHIVE_FAILED);
-#ifdef _PC_MIN_HOLE_SIZE
- if (pathconf(path, _PC_MIN_HOLE_SIZE) <= 0)
- return (ARCHIVE_OK);
-#endif
- *fd = open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
- if (*fd < 0) {
- archive_set_error(&a->archive, errno,
- "Can't open `%s'", path);
- return (ARCHIVE_FAILED);
- }
- __archive_ensure_cloexec_flag(*fd);
- initial_off = 0;
- }
-
-#ifndef _PC_MIN_HOLE_SIZE
- /* Check if the underlying filesystem supports seek hole */
- off_s = lseek(*fd, 0, SEEK_HOLE);
- if (off_s < 0)
-#if defined(HAVE_LINUX_FIEMAP_H)
- return setup_sparse_fiemap(a, entry, fd);
-#else
- goto exit_setup_sparse;
-#endif
- else if (off_s > 0)
- lseek(*fd, 0, SEEK_SET);
-#endif
-
- off_s = 0;
- size = archive_entry_size(entry);
- while (off_s < size) {
- off_s = lseek(*fd, off_s, SEEK_DATA);
- if (off_s == (off_t)-1) {
- if (errno == ENXIO) {
- /* no more hole */
- if (archive_entry_sparse_count(entry) == 0) {
- /* Potentially a fully-sparse file. */
- check_fully_sparse = 1;
- }
- break;
- }
- archive_set_error(&a->archive, errno,
- "lseek(SEEK_HOLE) failed");
- exit_sts = ARCHIVE_FAILED;
- goto exit_setup_sparse;
- }
- off_e = lseek(*fd, off_s, SEEK_HOLE);
- if (off_e == (off_t)-1) {
- if (errno == ENXIO) {
- off_e = lseek(*fd, 0, SEEK_END);
- if (off_e != (off_t)-1)
- break;/* no more data */
- }
- archive_set_error(&a->archive, errno,
- "lseek(SEEK_DATA) failed");
- exit_sts = ARCHIVE_FAILED;
- goto exit_setup_sparse;
- }
- if (off_s == 0 && off_e == size)
- break;/* This is not sparse. */
- archive_entry_sparse_add_entry(entry, off_s,
- off_e - off_s);
- off_s = off_e;
- }
-
- if (check_fully_sparse) {
- if (lseek(*fd, 0, SEEK_HOLE) == 0 &&
- lseek(*fd, 0, SEEK_END) == size) {
- /* Fully sparse file; insert a zero-length "data" entry */
- archive_entry_sparse_add_entry(entry, 0, 0);
- }
- }
-exit_setup_sparse:
- lseek(*fd, initial_off, SEEK_SET);
- return (exit_sts);
-}
-
-#elif !defined(HAVE_LINUX_FIEMAP_H)
-
-/*
- * Generic (stub) sparse support.
- */
-static int
-setup_sparse(struct archive_read_disk *a,
- struct archive_entry *entry, int *fd)
-{
- (void)a; /* UNUSED */
- (void)entry; /* UNUSED */
- (void)fd; /* UNUSED */
- return (ARCHIVE_OK);
-}
-
-#endif
-
-#endif /* !defined(_WIN32) || defined(__CYGWIN__) */
-
diff --git a/contrib/libs/libarchive/libarchive/archive_read_disk_posix.c b/contrib/libs/libarchive/libarchive/archive_read_disk_posix.c
deleted file mode 100644
index fbed06adf2..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_disk_posix.c
+++ /dev/null
@@ -1,2760 +0,0 @@
-/*-
- * Copyright (c) 2003-2009 Tim Kientzle
- * Copyright (c) 2010-2012 Michihiro NAKAJIMA
- * 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
- * in this position and unchanged.
- * 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(S) ``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(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* This is the tree-walking code for POSIX systems. */
-#if !defined(_WIN32) || defined(__CYGWIN__)
-
-#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_SYS_STATFS_H
-#include <sys/statfs.h>
-#endif
-#ifdef HAVE_SYS_STATVFS_H
-#include <sys/statvfs.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_LINUX_MAGIC_H
-#include <linux/magic.h>
-#endif
-#ifdef HAVE_LINUX_FS_H
-#include <linux/fs.h>
-#elif HAVE_SYS_MOUNT_H
-#include <sys/mount.h>
-#endif
-/*
- * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
- * As the include guards don't agree, the order of include is important.
- */
-#ifdef HAVE_LINUX_EXT2_FS_H
-#error #include <linux/ext2_fs.h> /* for Linux file flags */
-#endif
-#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
-#error #include <ext2fs/ext2_fs.h> /* Linux file flags, broken on Cygwin */
-#endif
-#ifdef HAVE_DIRECT_H
-#include <direct.h>
-#endif
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-
-#include "archive.h"
-#include "archive_string.h"
-#include "archive_entry.h"
-#include "archive_private.h"
-#include "archive_read_disk_private.h"
-
-#ifndef HAVE_FCHDIR
-#error fchdir function required.
-#endif
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-#ifndef O_CLOEXEC
-#define O_CLOEXEC 0
-#endif
-
-#if defined(__hpux) && !defined(HAVE_DIRFD)
-#define dirfd(x) ((x)->__dd_fd)
-#define HAVE_DIRFD
-#endif
-
-/*-
- * This is a new directory-walking system that addresses a number
- * of problems I've had with fts(3). In particular, it has no
- * pathname-length limits (other than the size of 'int'), handles
- * deep logical traversals, uses considerably less memory, and has
- * an opaque interface (easier to modify in the future).
- *
- * Internally, it keeps a single list of "tree_entry" items that
- * represent filesystem objects that require further attention.
- * Non-directories are not kept in memory: they are pulled from
- * readdir(), returned to the client, then freed as soon as possible.
- * Any directory entry to be traversed gets pushed onto the stack.
- *
- * There is surprisingly little information that needs to be kept for
- * each item on the stack. Just the name, depth (represented here as the
- * string length of the parent directory's pathname), and some markers
- * indicating how to get back to the parent (via chdir("..") for a
- * regular dir or via fchdir(2) for a symlink).
- */
-/*
- * TODO:
- * 1) Loop checking.
- * 3) Arbitrary logical traversals by closing/reopening intermediate fds.
- */
-
-struct restore_time {
- const char *name;
- time_t mtime;
- long mtime_nsec;
- time_t atime;
- long atime_nsec;
- mode_t filetype;
- int noatime;
-};
-
-struct tree_entry {
- int depth;
- struct tree_entry *next;
- struct tree_entry *parent;
- struct archive_string name;
- size_t dirname_length;
- int64_t dev;
- int64_t ino;
- int flags;
- int filesystem_id;
- /* How to return back to the parent of a symlink. */
- int symlink_parent_fd;
- /* How to restore time of a directory. */
- struct restore_time restore_time;
-};
-
-struct filesystem {
- int64_t dev;
- int synthetic;
- int remote;
- int noatime;
-#if defined(USE_READDIR_R)
- size_t name_max;
-#endif
- long incr_xfer_size;
- long max_xfer_size;
- long min_xfer_size;
- long xfer_align;
-
- /*
- * Buffer used for reading file contents.
- */
- /* Exactly allocated memory pointer. */
- unsigned char *allocation_ptr;
- /* Pointer adjusted to the filesystem alignment . */
- unsigned char *buff;
- size_t buff_size;
-};
-
-/* Definitions for tree_entry.flags bitmap. */
-#define isDir 1 /* This entry is a regular directory. */
-#define isDirLink 2 /* This entry is a symbolic link to a directory. */
-#define needsFirstVisit 4 /* This is an initial entry. */
-#define needsDescent 8 /* This entry needs to be previsited. */
-#define needsOpen 16 /* This is a directory that needs to be opened. */
-#define needsAscent 32 /* This entry needs to be postvisited. */
-
-/*
- * Local data for this package.
- */
-struct tree {
- struct tree_entry *stack;
- struct tree_entry *current;
- DIR *d;
-#define INVALID_DIR_HANDLE NULL
- struct dirent *de;
-#if defined(USE_READDIR_R)
- struct dirent *dirent;
- size_t dirent_allocated;
-#endif
- int flags;
- int visit_type;
- /* Error code from last failed operation. */
- int tree_errno;
-
- /* Dynamically-sized buffer for holding path */
- struct archive_string path;
-
- /* Last path element */
- const char *basename;
- /* Leading dir length */
- size_t dirname_length;
-
- int depth;
- int openCount;
- int maxOpenCount;
- int initial_dir_fd;
- int working_dir_fd;
-
- struct stat lst;
- struct stat st;
- int descend;
- int nlink;
- /* How to restore time of a file. */
- struct restore_time restore_time;
-
- struct entry_sparse {
- int64_t length;
- int64_t offset;
- } *sparse_list, *current_sparse;
- int sparse_count;
- int sparse_list_size;
-
- char initial_symlink_mode;
- char symlink_mode;
- struct filesystem *current_filesystem;
- struct filesystem *filesystem_table;
- int initial_filesystem_id;
- int current_filesystem_id;
- int max_filesystem_id;
- int allocated_filesystem;
-
- int entry_fd;
- int entry_eof;
- int64_t entry_remaining_bytes;
- int64_t entry_total;
- unsigned char *entry_buff;
- size_t entry_buff_size;
-};
-
-/* Definitions for tree.flags bitmap. */
-#define hasStat 16 /* The st entry is valid. */
-#define hasLstat 32 /* The lst entry is valid. */
-#define onWorkingDir 64 /* We are on the working dir where we are
- * reading directory entry at this time. */
-#define needsRestoreTimes 128
-#define onInitialDir 256 /* We are on the initial dir. */
-
-static int
-tree_dir_next_posix(struct tree *t);
-
-#ifdef HAVE_DIRENT_D_NAMLEN
-/* BSD extension; avoids need for a strlen() call. */
-#define D_NAMELEN(dp) (dp)->d_namlen
-#else
-#define D_NAMELEN(dp) (strlen((dp)->d_name))
-#endif
-
-/* Initiate/terminate a tree traversal. */
-static struct tree *tree_open(const char *, int, int);
-static struct tree *tree_reopen(struct tree *, const char *, int);
-static void tree_close(struct tree *);
-static void tree_free(struct tree *);
-static void tree_push(struct tree *, const char *, int, int64_t, int64_t,
- struct restore_time *);
-static int tree_enter_initial_dir(struct tree *);
-static int tree_enter_working_dir(struct tree *);
-static int tree_current_dir_fd(struct tree *);
-
-/*
- * tree_next() returns Zero if there is no next entry, non-zero if
- * there is. Note that directories are visited three times.
- * Directories are always visited first as part of enumerating their
- * parent; that is a "regular" visit. If tree_descend() is invoked at
- * that time, the directory is added to a work list and will
- * subsequently be visited two more times: once just after descending
- * into the directory ("postdescent") and again just after ascending
- * back to the parent ("postascent").
- *
- * TREE_ERROR_DIR is returned if the descent failed (because the
- * directory couldn't be opened, for instance). This is returned
- * instead of TREE_POSTDESCENT/TREE_POSTASCENT. TREE_ERROR_DIR is not a
- * fatal error, but it does imply that the relevant subtree won't be
- * visited. TREE_ERROR_FATAL is returned for an error that left the
- * traversal completely hosed. Right now, this is only returned for
- * chdir() failures during ascent.
- */
-#define TREE_REGULAR 1
-#define TREE_POSTDESCENT 2
-#define TREE_POSTASCENT 3
-#define TREE_ERROR_DIR -1
-#define TREE_ERROR_FATAL -2
-
-static int tree_next(struct tree *);
-
-/*
- * Return information about the current entry.
- */
-
-/*
- * The current full pathname, length of the full pathname, and a name
- * that can be used to access the file. Because tree does use chdir
- * extensively, the access path is almost never the same as the full
- * current path.
- *
- * TODO: On platforms that support it, use openat()-style operations
- * to eliminate the chdir() operations entirely while still supporting
- * arbitrarily deep traversals. This makes access_path troublesome to
- * support, of course, which means we'll need a rich enough interface
- * that clients can function without it. (In particular, we'll need
- * tree_current_open() that returns an open file descriptor.)
- *
- */
-static const char *tree_current_path(struct tree *);
-static const char *tree_current_access_path(struct tree *);
-
-/*
- * Request the lstat() or stat() data for the current path. Since the
- * tree package needs to do some of this anyway, and caches the
- * results, you should take advantage of it here if you need it rather
- * than make a redundant stat() or lstat() call of your own.
- */
-static const struct stat *tree_current_stat(struct tree *);
-static const struct stat *tree_current_lstat(struct tree *);
-static int tree_current_is_symblic_link_target(struct tree *);
-
-/* The following functions use tricks to avoid a certain number of
- * stat()/lstat() calls. */
-/* "is_physical_dir" is equivalent to S_ISDIR(tree_current_lstat()->st_mode) */
-static int tree_current_is_physical_dir(struct tree *);
-/* "is_dir" is equivalent to S_ISDIR(tree_current_stat()->st_mode) */
-static int tree_current_is_dir(struct tree *);
-static int update_current_filesystem(struct archive_read_disk *a,
- int64_t dev);
-static int setup_current_filesystem(struct archive_read_disk *);
-static int tree_target_is_same_as_parent(struct tree *, const struct stat *);
-
-static int _archive_read_disk_open(struct archive *, const char *);
-static int _archive_read_free(struct archive *);
-static int _archive_read_close(struct archive *);
-static int _archive_read_data_block(struct archive *,
- const void **, size_t *, int64_t *);
-static int _archive_read_next_header(struct archive *,
- struct archive_entry **);
-static int _archive_read_next_header2(struct archive *,
- struct archive_entry *);
-static const char *trivial_lookup_gname(void *, int64_t gid);
-static const char *trivial_lookup_uname(void *, int64_t uid);
-static int setup_sparse(struct archive_read_disk *, struct archive_entry *);
-static int close_and_restore_time(int fd, struct tree *,
- struct restore_time *);
-static int open_on_current_dir(struct tree *, const char *, int);
-static int tree_dup(int);
-
-
-static const struct archive_vtable
-archive_read_disk_vtable = {
- .archive_free = _archive_read_free,
- .archive_close = _archive_read_close,
- .archive_read_data_block = _archive_read_data_block,
- .archive_read_next_header = _archive_read_next_header,
- .archive_read_next_header2 = _archive_read_next_header2,
-};
-
-const char *
-archive_read_disk_gname(struct archive *_a, la_int64_t gid)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_disk_gname"))
- return (NULL);
- if (a->lookup_gname == NULL)
- return (NULL);
- return ((*a->lookup_gname)(a->lookup_gname_data, gid));
-}
-
-const char *
-archive_read_disk_uname(struct archive *_a, la_int64_t uid)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_disk_uname"))
- return (NULL);
- if (a->lookup_uname == NULL)
- return (NULL);
- return ((*a->lookup_uname)(a->lookup_uname_data, uid));
-}
-
-int
-archive_read_disk_set_gname_lookup(struct archive *_a,
- void *private_data,
- const char * (*lookup_gname)(void *private, la_int64_t gid),
- void (*cleanup_gname)(void *private))
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_disk_set_gname_lookup");
-
- if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
- (a->cleanup_gname)(a->lookup_gname_data);
-
- a->lookup_gname = lookup_gname;
- a->cleanup_gname = cleanup_gname;
- a->lookup_gname_data = private_data;
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_disk_set_uname_lookup(struct archive *_a,
- void *private_data,
- const char * (*lookup_uname)(void *private, la_int64_t uid),
- void (*cleanup_uname)(void *private))
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_disk_set_uname_lookup");
-
- if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
- (a->cleanup_uname)(a->lookup_uname_data);
-
- a->lookup_uname = lookup_uname;
- a->cleanup_uname = cleanup_uname;
- a->lookup_uname_data = private_data;
- return (ARCHIVE_OK);
-}
-
-/*
- * Create a new archive_read_disk object and initialize it with global state.
- */
-struct archive *
-archive_read_disk_new(void)
-{
- struct archive_read_disk *a;
-
- a = (struct archive_read_disk *)calloc(1, sizeof(*a));
- if (a == NULL)
- return (NULL);
- a->archive.magic = ARCHIVE_READ_DISK_MAGIC;
- a->archive.state = ARCHIVE_STATE_NEW;
- a->archive.vtable = &archive_read_disk_vtable;
- a->entry = archive_entry_new2(&a->archive);
- a->lookup_uname = trivial_lookup_uname;
- a->lookup_gname = trivial_lookup_gname;
- a->flags = ARCHIVE_READDISK_MAC_COPYFILE;
- a->open_on_current_dir = open_on_current_dir;
- a->tree_current_dir_fd = tree_current_dir_fd;
- a->tree_enter_working_dir = tree_enter_working_dir;
- return (&a->archive);
-}
-
-static int
-_archive_read_free(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- int r;
-
- if (_a == NULL)
- return (ARCHIVE_OK);
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free");
-
- if (a->archive.state != ARCHIVE_STATE_CLOSED)
- r = _archive_read_close(&a->archive);
- else
- r = ARCHIVE_OK;
-
- tree_free(a->tree);
- if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
- (a->cleanup_gname)(a->lookup_gname_data);
- if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
- (a->cleanup_uname)(a->lookup_uname_data);
- archive_string_free(&a->archive.error_string);
- archive_entry_free(a->entry);
- a->archive.magic = 0;
- __archive_clean(&a->archive);
- free(a);
- return (r);
-}
-
-static int
-_archive_read_close(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close");
-
- if (a->archive.state != ARCHIVE_STATE_FATAL)
- a->archive.state = ARCHIVE_STATE_CLOSED;
-
- tree_close(a->tree);
-
- return (ARCHIVE_OK);
-}
-
-static void
-setup_symlink_mode(struct archive_read_disk *a, char symlink_mode,
- int follow_symlinks)
-{
- a->symlink_mode = symlink_mode;
- a->follow_symlinks = follow_symlinks;
- if (a->tree != NULL) {
- a->tree->initial_symlink_mode = a->symlink_mode;
- a->tree->symlink_mode = a->symlink_mode;
- }
-}
-
-int
-archive_read_disk_set_symlink_logical(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_logical");
- setup_symlink_mode(a, 'L', 1);
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_disk_set_symlink_physical(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_physical");
- setup_symlink_mode(a, 'P', 0);
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_disk_set_symlink_hybrid(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_hybrid");
- setup_symlink_mode(a, 'H', 1);/* Follow symlinks initially. */
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_disk_set_atime_restored(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_disk_restore_atime");
-#ifdef HAVE_UTIMES
- a->flags |= ARCHIVE_READDISK_RESTORE_ATIME;
- if (a->tree != NULL)
- a->tree->flags |= needsRestoreTimes;
- return (ARCHIVE_OK);
-#else
- /* Display warning and unset flag */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Cannot restore access time on this system");
- a->flags &= ~ARCHIVE_READDISK_RESTORE_ATIME;
- return (ARCHIVE_WARN);
-#endif
-}
-
-int
-archive_read_disk_set_behavior(struct archive *_a, int flags)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- int r = ARCHIVE_OK;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_disk_honor_nodump");
-
- a->flags = flags;
-
- if (flags & ARCHIVE_READDISK_RESTORE_ATIME)
- r = archive_read_disk_set_atime_restored(_a);
- else {
- if (a->tree != NULL)
- a->tree->flags &= ~needsRestoreTimes;
- }
- return (r);
-}
-
-/*
- * Trivial implementations of gname/uname lookup functions.
- * These are normally overridden by the client, but these stub
- * versions ensure that we always have something that works.
- */
-static const char *
-trivial_lookup_gname(void *private_data, int64_t gid)
-{
- (void)private_data; /* UNUSED */
- (void)gid; /* UNUSED */
- return (NULL);
-}
-
-static const char *
-trivial_lookup_uname(void *private_data, int64_t uid)
-{
- (void)private_data; /* UNUSED */
- (void)uid; /* UNUSED */
- return (NULL);
-}
-
-/*
- * Allocate memory for the reading buffer adjusted to the filesystem
- * alignment.
- */
-static int
-setup_suitable_read_buffer(struct archive_read_disk *a)
-{
- struct tree *t = a->tree;
- struct filesystem *cf = t->current_filesystem;
- size_t asize;
- size_t s;
-
- if (cf->allocation_ptr == NULL) {
- /* If we couldn't get a filesystem alignment,
- * we use 4096 as default value but we won't use
- * O_DIRECT to open() and openat() operations. */
- long xfer_align = (cf->xfer_align == -1)?4096:cf->xfer_align;
-
- if (cf->max_xfer_size != -1)
- asize = cf->max_xfer_size + xfer_align;
- else {
- long incr = cf->incr_xfer_size;
- /* Some platform does not set a proper value to
- * incr_xfer_size.*/
- if (incr < 0)
- incr = cf->min_xfer_size;
- if (cf->min_xfer_size < 0) {
- incr = xfer_align;
- asize = xfer_align;
- } else
- asize = cf->min_xfer_size;
-
- /* Increase a buffer size up to 64K bytes in
- * a proper increment size. */
- while (asize < 1024*64)
- asize += incr;
- /* Take a margin to adjust to the filesystem
- * alignment. */
- asize += xfer_align;
- }
- cf->allocation_ptr = malloc(asize);
- if (cf->allocation_ptr == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Couldn't allocate memory");
- a->archive.state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- }
-
- /*
- * Calculate proper address for the filesystem.
- */
- s = (uintptr_t)cf->allocation_ptr;
- s %= xfer_align;
- if (s > 0)
- s = xfer_align - s;
-
- /*
- * Set a read buffer pointer in the proper alignment of
- * the current filesystem.
- */
- cf->buff = cf->allocation_ptr + s;
- cf->buff_size = asize - xfer_align;
- }
- return (ARCHIVE_OK);
-}
-
-static int
-_archive_read_data_block(struct archive *_a, const void **buff,
- size_t *size, int64_t *offset)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- struct tree *t = a->tree;
- int r;
- ssize_t bytes;
- int64_t sparse_bytes;
- size_t buffbytes;
- int empty_sparse_region = 0;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
- "archive_read_data_block");
-
- if (t->entry_eof || t->entry_remaining_bytes <= 0) {
- r = ARCHIVE_EOF;
- goto abort_read_data;
- }
-
- /*
- * Open the current file.
- */
- if (t->entry_fd < 0) {
- int flags = O_RDONLY | O_BINARY | O_CLOEXEC;
-
- /*
- * Eliminate or reduce cache effects if we can.
- *
- * Carefully consider this to be enabled.
- */
-#if defined(O_DIRECT) && 0/* Disabled for now */
- if (t->current_filesystem->xfer_align != -1 &&
- t->nlink == 1)
- flags |= O_DIRECT;
-#endif
-#if defined(O_NOATIME)
- /*
- * Linux has O_NOATIME flag; use it if we need.
- */
- if ((t->flags & needsRestoreTimes) != 0 &&
- t->restore_time.noatime == 0)
- flags |= O_NOATIME;
-#endif
- t->entry_fd = open_on_current_dir(t,
- tree_current_access_path(t), flags);
- __archive_ensure_cloexec_flag(t->entry_fd);
-#if defined(O_NOATIME)
- /*
- * When we did open the file with O_NOATIME flag,
- * if successful, set 1 to t->restore_time.noatime
- * not to restore an atime of the file later.
- * if failed by EPERM, retry it without O_NOATIME flag.
- */
- if (flags & O_NOATIME) {
- if (t->entry_fd >= 0)
- t->restore_time.noatime = 1;
- else if (errno == EPERM)
- flags &= ~O_NOATIME;
- }
-#endif
- if (t->entry_fd < 0) {
- archive_set_error(&a->archive, errno,
- "Couldn't open %s", tree_current_path(t));
- r = ARCHIVE_FAILED;
- tree_enter_initial_dir(t);
- goto abort_read_data;
- }
- tree_enter_initial_dir(t);
- }
-
- /*
- * Allocate read buffer if not allocated.
- */
- if (t->current_filesystem->allocation_ptr == NULL) {
- r = setup_suitable_read_buffer(a);
- if (r != ARCHIVE_OK) {
- a->archive.state = ARCHIVE_STATE_FATAL;
- goto abort_read_data;
- }
- }
- t->entry_buff = t->current_filesystem->buff;
- t->entry_buff_size = t->current_filesystem->buff_size;
-
- buffbytes = t->entry_buff_size;
- if ((int64_t)buffbytes > t->current_sparse->length)
- buffbytes = t->current_sparse->length;
-
- if (t->current_sparse->length == 0)
- empty_sparse_region = 1;
-
- /*
- * Skip hole.
- * TODO: Should we consider t->current_filesystem->xfer_align?
- */
- if (t->current_sparse->offset > t->entry_total) {
- if (lseek(t->entry_fd,
- (off_t)t->current_sparse->offset, SEEK_SET) < 0) {
- archive_set_error(&a->archive, errno, "Seek error");
- r = ARCHIVE_FATAL;
- a->archive.state = ARCHIVE_STATE_FATAL;
- goto abort_read_data;
- }
- sparse_bytes = t->current_sparse->offset - t->entry_total;
- t->entry_remaining_bytes -= sparse_bytes;
- t->entry_total += sparse_bytes;
- }
-
- /*
- * Read file contents.
- */
- if (buffbytes > 0) {
- bytes = read(t->entry_fd, t->entry_buff, buffbytes);
- if (bytes < 0) {
- archive_set_error(&a->archive, errno, "Read error");
- r = ARCHIVE_FATAL;
- a->archive.state = ARCHIVE_STATE_FATAL;
- goto abort_read_data;
- }
- } else
- bytes = 0;
- /*
- * Return an EOF unless we've read a leading empty sparse region, which
- * is used to represent fully-sparse files.
- */
- if (bytes == 0 && !empty_sparse_region) {
- /* Get EOF */
- t->entry_eof = 1;
- r = ARCHIVE_EOF;
- goto abort_read_data;
- }
- *buff = t->entry_buff;
- *size = bytes;
- *offset = t->entry_total;
- t->entry_total += bytes;
- t->entry_remaining_bytes -= bytes;
- if (t->entry_remaining_bytes == 0) {
- /* Close the current file descriptor */
- close_and_restore_time(t->entry_fd, t, &t->restore_time);
- t->entry_fd = -1;
- t->entry_eof = 1;
- }
- t->current_sparse->offset += bytes;
- t->current_sparse->length -= bytes;
- if (t->current_sparse->length == 0 && !t->entry_eof)
- t->current_sparse++;
- return (ARCHIVE_OK);
-
-abort_read_data:
- *buff = NULL;
- *size = 0;
- *offset = t->entry_total;
- if (t->entry_fd >= 0) {
- /* Close the current file descriptor */
- close_and_restore_time(t->entry_fd, t, &t->restore_time);
- t->entry_fd = -1;
- }
- return (r);
-}
-
-static int
-next_entry(struct archive_read_disk *a, struct tree *t,
- struct archive_entry *entry)
-{
- const struct stat *st; /* info to use for this entry */
- const struct stat *lst;/* lstat() information */
- const char *name;
- int delayed, delayed_errno, descend, r;
- struct archive_string delayed_str;
-
- delayed = ARCHIVE_OK;
- delayed_errno = 0;
- archive_string_init(&delayed_str);
-
- st = NULL;
- lst = NULL;
- t->descend = 0;
- do {
- switch (tree_next(t)) {
- case TREE_ERROR_FATAL:
- archive_set_error(&a->archive, t->tree_errno,
- "%s: Unable to continue traversing directory tree",
- tree_current_path(t));
- a->archive.state = ARCHIVE_STATE_FATAL;
- tree_enter_initial_dir(t);
- return (ARCHIVE_FATAL);
- case TREE_ERROR_DIR:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "%s: Couldn't visit directory",
- tree_current_path(t));
- tree_enter_initial_dir(t);
- return (ARCHIVE_FAILED);
- case 0:
- tree_enter_initial_dir(t);
- return (ARCHIVE_EOF);
- case TREE_POSTDESCENT:
- case TREE_POSTASCENT:
- break;
- case TREE_REGULAR:
- lst = tree_current_lstat(t);
- if (lst == NULL) {
- if (errno == ENOENT && t->depth > 0) {
- delayed = ARCHIVE_WARN;
- delayed_errno = errno;
- if (delayed_str.length == 0) {
- archive_string_sprintf(&delayed_str,
- "%s", tree_current_path(t));
- } else {
- archive_string_sprintf(&delayed_str,
- " %s", tree_current_path(t));
- }
- } else {
- archive_set_error(&a->archive, errno,
- "%s: Cannot stat",
- tree_current_path(t));
- tree_enter_initial_dir(t);
- return (ARCHIVE_FAILED);
- }
- }
- break;
- }
- } while (lst == NULL);
-
-#ifdef __APPLE__
- if (a->flags & ARCHIVE_READDISK_MAC_COPYFILE) {
- /* If we're using copyfile(), ignore "._XXX" files. */
- const char *bname = strrchr(tree_current_path(t), '/');
- if (bname == NULL)
- bname = tree_current_path(t);
- else
- ++bname;
- if (bname[0] == '.' && bname[1] == '_')
- return (ARCHIVE_RETRY);
- }
-#endif
-
- archive_entry_copy_pathname(entry, tree_current_path(t));
- /*
- * Perform path matching.
- */
- if (a->matching) {
- r = archive_match_path_excluded(a->matching, entry);
- if (r < 0) {
- archive_set_error(&(a->archive), errno,
- "Failed : %s", archive_error_string(a->matching));
- return (r);
- }
- if (r) {
- if (a->excluded_cb_func)
- a->excluded_cb_func(&(a->archive),
- a->excluded_cb_data, entry);
- return (ARCHIVE_RETRY);
- }
- }
-
- /*
- * Distinguish 'L'/'P'/'H' symlink following.
- */
- switch(t->symlink_mode) {
- case 'H':
- /* 'H': After the first item, rest like 'P'. */
- t->symlink_mode = 'P';
- /* 'H': First item (from command line) like 'L'. */
- /* FALLTHROUGH */
- case 'L':
- /* 'L': Do descend through a symlink to dir. */
- descend = tree_current_is_dir(t);
- /* 'L': Follow symlinks to files. */
- a->symlink_mode = 'L';
- a->follow_symlinks = 1;
- /* 'L': Archive symlinks as targets, if we can. */
- st = tree_current_stat(t);
- if (st != NULL && !tree_target_is_same_as_parent(t, st))
- break;
- /* If stat fails, we have a broken symlink;
- * in that case, don't follow the link. */
- /* FALLTHROUGH */
- default:
- /* 'P': Don't descend through a symlink to dir. */
- descend = tree_current_is_physical_dir(t);
- /* 'P': Don't follow symlinks to files. */
- a->symlink_mode = 'P';
- a->follow_symlinks = 0;
- /* 'P': Archive symlinks as symlinks. */
- st = lst;
- break;
- }
-
- if (update_current_filesystem(a, st->st_dev) != ARCHIVE_OK) {
- a->archive.state = ARCHIVE_STATE_FATAL;
- tree_enter_initial_dir(t);
- return (ARCHIVE_FATAL);
- }
- if (t->initial_filesystem_id == -1)
- t->initial_filesystem_id = t->current_filesystem_id;
- if (a->flags & ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS) {
- if (t->initial_filesystem_id != t->current_filesystem_id)
- descend = 0;
- }
- t->descend = descend;
-
- /*
- * Honor nodump flag.
- * If the file is marked with nodump flag, do not return this entry.
- */
- if (a->flags & ARCHIVE_READDISK_HONOR_NODUMP) {
-#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
- if (st->st_flags & UF_NODUMP)
- return (ARCHIVE_RETRY);
-#elif (defined(FS_IOC_GETFLAGS) && defined(FS_NODUMP_FL) && \
- defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \
- (defined(EXT2_IOC_GETFLAGS) && defined(EXT2_NODUMP_FL) && \
- defined(HAVE_WORKING_EXT2_IOC_GETFLAGS))
- if (S_ISREG(st->st_mode) || S_ISDIR(st->st_mode)) {
- int stflags;
-
- t->entry_fd = open_on_current_dir(t,
- tree_current_access_path(t),
- O_RDONLY | O_NONBLOCK | O_CLOEXEC);
- __archive_ensure_cloexec_flag(t->entry_fd);
- if (t->entry_fd >= 0) {
- r = ioctl(t->entry_fd,
-#ifdef FS_IOC_GETFLAGS
- FS_IOC_GETFLAGS,
-#else
- EXT2_IOC_GETFLAGS,
-#endif
- &stflags);
-#ifdef FS_NODUMP_FL
- if (r == 0 && (stflags & FS_NODUMP_FL) != 0)
-#else
- if (r == 0 && (stflags & EXT2_NODUMP_FL) != 0)
-#endif
- return (ARCHIVE_RETRY);
- }
- }
-#endif
- }
-
- archive_entry_copy_stat(entry, st);
-
- /* Save the times to be restored. This must be in before
- * calling archive_read_disk_descend() or any chance of it,
- * especially, invoking a callback. */
- t->restore_time.mtime = archive_entry_mtime(entry);
- t->restore_time.mtime_nsec = archive_entry_mtime_nsec(entry);
- t->restore_time.atime = archive_entry_atime(entry);
- t->restore_time.atime_nsec = archive_entry_atime_nsec(entry);
- t->restore_time.filetype = archive_entry_filetype(entry);
- t->restore_time.noatime = t->current_filesystem->noatime;
-
- /*
- * Perform time matching.
- */
- if (a->matching) {
- r = archive_match_time_excluded(a->matching, entry);
- if (r < 0) {
- archive_set_error(&(a->archive), errno,
- "Failed : %s", archive_error_string(a->matching));
- return (r);
- }
- if (r) {
- if (a->excluded_cb_func)
- a->excluded_cb_func(&(a->archive),
- a->excluded_cb_data, entry);
- return (ARCHIVE_RETRY);
- }
- }
-
- /* Lookup uname/gname */
- name = archive_read_disk_uname(&(a->archive), archive_entry_uid(entry));
- if (name != NULL)
- archive_entry_copy_uname(entry, name);
- name = archive_read_disk_gname(&(a->archive), archive_entry_gid(entry));
- if (name != NULL)
- archive_entry_copy_gname(entry, name);
-
- /*
- * Perform owner matching.
- */
- if (a->matching) {
- r = archive_match_owner_excluded(a->matching, entry);
- if (r < 0) {
- archive_set_error(&(a->archive), errno,
- "Failed : %s", archive_error_string(a->matching));
- return (r);
- }
- if (r) {
- if (a->excluded_cb_func)
- a->excluded_cb_func(&(a->archive),
- a->excluded_cb_data, entry);
- return (ARCHIVE_RETRY);
- }
- }
-
- /*
- * Invoke a meta data filter callback.
- */
- if (a->metadata_filter_func) {
- if (!a->metadata_filter_func(&(a->archive),
- a->metadata_filter_data, entry))
- return (ARCHIVE_RETRY);
- }
-
- /*
- * Populate the archive_entry with metadata from the disk.
- */
- archive_entry_copy_sourcepath(entry, tree_current_access_path(t));
- r = archive_read_disk_entry_from_file(&(a->archive), entry,
- t->entry_fd, st);
-
- if (r == ARCHIVE_OK) {
- r = delayed;
- if (r != ARCHIVE_OK) {
- archive_string_sprintf(&delayed_str, ": %s",
- "File removed before we read it");
- archive_set_error(&(a->archive), delayed_errno,
- "%s", delayed_str.s);
- }
- }
- archive_string_free(&delayed_str);
-
- return (r);
-}
-
-static int
-_archive_read_next_header(struct archive *_a, struct archive_entry **entryp)
-{
- int ret;
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- *entryp = NULL;
- ret = _archive_read_next_header2(_a, a->entry);
- *entryp = a->entry;
- return ret;
-}
-
-static int
-_archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- struct tree *t;
- int r;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
- "archive_read_next_header2");
-
- t = a->tree;
- if (t->entry_fd >= 0) {
- close_and_restore_time(t->entry_fd, t, &t->restore_time);
- t->entry_fd = -1;
- }
-
- archive_entry_clear(entry);
-
- for (;;) {
- r = next_entry(a, t, entry);
- if (t->entry_fd >= 0) {
- close(t->entry_fd);
- t->entry_fd = -1;
- }
-
- if (r == ARCHIVE_RETRY) {
- archive_entry_clear(entry);
- continue;
- }
- break;
- }
-
- /* Return to the initial directory. */
- tree_enter_initial_dir(t);
-
- /*
- * EOF and FATAL are persistent at this layer. By
- * modifying the state, we guarantee that future calls to
- * read a header or read data will fail.
- */
- switch (r) {
- case ARCHIVE_EOF:
- a->archive.state = ARCHIVE_STATE_EOF;
- break;
- case ARCHIVE_OK:
- case ARCHIVE_WARN:
- /* Overwrite the sourcepath based on the initial directory. */
- archive_entry_copy_sourcepath(entry, tree_current_path(t));
- t->entry_total = 0;
- if (archive_entry_filetype(entry) == AE_IFREG) {
- t->nlink = archive_entry_nlink(entry);
- t->entry_remaining_bytes = archive_entry_size(entry);
- t->entry_eof = (t->entry_remaining_bytes == 0)? 1: 0;
- if (!t->entry_eof &&
- setup_sparse(a, entry) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- } else {
- t->entry_remaining_bytes = 0;
- t->entry_eof = 1;
- }
- a->archive.state = ARCHIVE_STATE_DATA;
- break;
- case ARCHIVE_RETRY:
- break;
- case ARCHIVE_FATAL:
- a->archive.state = ARCHIVE_STATE_FATAL;
- break;
- }
-
- __archive_reset_read_data(&a->archive);
- return (r);
-}
-
-static int
-setup_sparse(struct archive_read_disk *a, struct archive_entry *entry)
-{
- struct tree *t = a->tree;
- int64_t length, offset;
- int i;
-
- t->sparse_count = archive_entry_sparse_reset(entry);
- if (t->sparse_count+1 > t->sparse_list_size) {
- free(t->sparse_list);
- t->sparse_list_size = t->sparse_count + 1;
- t->sparse_list = malloc(sizeof(t->sparse_list[0]) *
- t->sparse_list_size);
- if (t->sparse_list == NULL) {
- t->sparse_list_size = 0;
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate data");
- a->archive.state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- }
- }
- for (i = 0; i < t->sparse_count; i++) {
- archive_entry_sparse_next(entry, &offset, &length);
- t->sparse_list[i].offset = offset;
- t->sparse_list[i].length = length;
- }
- if (i == 0) {
- t->sparse_list[i].offset = 0;
- t->sparse_list[i].length = archive_entry_size(entry);
- } else {
- t->sparse_list[i].offset = archive_entry_size(entry);
- t->sparse_list[i].length = 0;
- }
- t->current_sparse = t->sparse_list;
-
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_disk_set_matching(struct archive *_a, struct archive *_ma,
- void (*_excluded_func)(struct archive *, void *, struct archive_entry *),
- void *_client_data)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_disk_set_matching");
- a->matching = _ma;
- a->excluded_cb_func = _excluded_func;
- a->excluded_cb_data = _client_data;
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_disk_set_metadata_filter_callback(struct archive *_a,
- int (*_metadata_filter_func)(struct archive *, void *,
- struct archive_entry *), void *_client_data)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_ANY,
- "archive_read_disk_set_metadata_filter_callback");
-
- a->metadata_filter_func = _metadata_filter_func;
- a->metadata_filter_data = _client_data;
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_disk_can_descend(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- struct tree *t = a->tree;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
- "archive_read_disk_can_descend");
-
- return (t->visit_type == TREE_REGULAR && t->descend);
-}
-
-/*
- * Called by the client to mark the directory just returned from
- * tree_next() as needing to be visited.
- */
-int
-archive_read_disk_descend(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- struct tree *t = a->tree;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
- "archive_read_disk_descend");
-
- if (!archive_read_disk_can_descend(_a))
- return (ARCHIVE_OK);
-
- /*
- * We must not treat the initial specified path as a physical dir,
- * because if we do then we will try and ascend out of it by opening
- * ".." which is (a) wrong and (b) causes spurious permissions errors
- * if ".." is not readable by us. Instead, treat it as if it were a
- * symlink. (This uses an extra fd, but it can only happen once at the
- * top level of a traverse.) But we can't necessarily assume t->st is
- * valid here (though t->lst is), which complicates the logic a
- * little.
- */
- if (tree_current_is_physical_dir(t)) {
- tree_push(t, t->basename, t->current_filesystem_id,
- t->lst.st_dev, t->lst.st_ino, &t->restore_time);
- if (t->stack->parent->parent != NULL)
- t->stack->flags |= isDir;
- else
- t->stack->flags |= isDirLink;
- } else if (tree_current_is_dir(t)) {
- tree_push(t, t->basename, t->current_filesystem_id,
- t->st.st_dev, t->st.st_ino, &t->restore_time);
- t->stack->flags |= isDirLink;
- }
- t->descend = 0;
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_disk_open(struct archive *_a, const char *pathname)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED,
- "archive_read_disk_open");
- archive_clear_error(&a->archive);
-
- return (_archive_read_disk_open(_a, pathname));
-}
-
-int
-archive_read_disk_open_w(struct archive *_a, const wchar_t *pathname)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- struct archive_string path;
- int ret;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED,
- "archive_read_disk_open_w");
- archive_clear_error(&a->archive);
-
- /* Make a char string from a wchar_t string. */
- archive_string_init(&path);
- if (archive_string_append_from_wcs(&path, pathname,
- wcslen(pathname)) != 0) {
- if (errno == ENOMEM)
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- else
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Can't convert a path to a char string");
- a->archive.state = ARCHIVE_STATE_FATAL;
- ret = ARCHIVE_FATAL;
- } else
- ret = _archive_read_disk_open(_a, path.s);
-
- archive_string_free(&path);
- return (ret);
-}
-
-static int
-_archive_read_disk_open(struct archive *_a, const char *pathname)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
-
- if (a->tree != NULL)
- a->tree = tree_reopen(a->tree, pathname,
- a->flags & ARCHIVE_READDISK_RESTORE_ATIME);
- else
- a->tree = tree_open(pathname, a->symlink_mode,
- a->flags & ARCHIVE_READDISK_RESTORE_ATIME);
- if (a->tree == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate tar data");
- a->archive.state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- }
- a->archive.state = ARCHIVE_STATE_HEADER;
-
- return (ARCHIVE_OK);
-}
-
-/*
- * Return a current filesystem ID which is index of the filesystem entry
- * you've visited through archive_read_disk.
- */
-int
-archive_read_disk_current_filesystem(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
- "archive_read_disk_current_filesystem");
-
- return (a->tree->current_filesystem_id);
-}
-
-static int
-update_current_filesystem(struct archive_read_disk *a, int64_t dev)
-{
- struct tree *t = a->tree;
- int i, fid;
-
- if (t->current_filesystem != NULL &&
- t->current_filesystem->dev == dev)
- return (ARCHIVE_OK);
-
- for (i = 0; i < t->max_filesystem_id; i++) {
- if (t->filesystem_table[i].dev == dev) {
- /* There is the filesystem ID we've already generated. */
- t->current_filesystem_id = i;
- t->current_filesystem = &(t->filesystem_table[i]);
- return (ARCHIVE_OK);
- }
- }
-
- /*
- * This is the new filesystem which we have to generate a new ID for.
- */
- fid = t->max_filesystem_id++;
- if (t->max_filesystem_id > t->allocated_filesystem) {
- size_t s;
- void *p;
-
- s = t->max_filesystem_id * 2;
- p = realloc(t->filesystem_table,
- s * sizeof(*t->filesystem_table));
- if (p == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate tar data");
- return (ARCHIVE_FATAL);
- }
- t->filesystem_table = (struct filesystem *)p;
- t->allocated_filesystem = s;
- }
- t->current_filesystem_id = fid;
- t->current_filesystem = &(t->filesystem_table[fid]);
- t->current_filesystem->dev = dev;
- t->current_filesystem->allocation_ptr = NULL;
- t->current_filesystem->buff = NULL;
-
- /* Setup the current filesystem properties which depend on
- * platform specific. */
- return (setup_current_filesystem(a));
-}
-
-/*
- * Returns 1 if current filesystem is generated filesystem, 0 if it is not
- * or -1 if it is unknown.
- */
-int
-archive_read_disk_current_filesystem_is_synthetic(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
- "archive_read_disk_current_filesystem");
-
- return (a->tree->current_filesystem->synthetic);
-}
-
-/*
- * Returns 1 if current filesystem is remote filesystem, 0 if it is not
- * or -1 if it is unknown.
- */
-int
-archive_read_disk_current_filesystem_is_remote(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
- "archive_read_disk_current_filesystem");
-
- return (a->tree->current_filesystem->remote);
-}
-
-#if defined(_PC_REC_INCR_XFER_SIZE) && defined(_PC_REC_MAX_XFER_SIZE) &&\
- defined(_PC_REC_MIN_XFER_SIZE) && defined(_PC_REC_XFER_ALIGN)
-static int
-get_xfer_size(struct tree *t, int fd, const char *path)
-{
- t->current_filesystem->xfer_align = -1;
- errno = 0;
- if (fd >= 0) {
- t->current_filesystem->incr_xfer_size =
- fpathconf(fd, _PC_REC_INCR_XFER_SIZE);
- t->current_filesystem->max_xfer_size =
- fpathconf(fd, _PC_REC_MAX_XFER_SIZE);
- t->current_filesystem->min_xfer_size =
- fpathconf(fd, _PC_REC_MIN_XFER_SIZE);
- t->current_filesystem->xfer_align =
- fpathconf(fd, _PC_REC_XFER_ALIGN);
- } else if (path != NULL) {
- t->current_filesystem->incr_xfer_size =
- pathconf(path, _PC_REC_INCR_XFER_SIZE);
- t->current_filesystem->max_xfer_size =
- pathconf(path, _PC_REC_MAX_XFER_SIZE);
- t->current_filesystem->min_xfer_size =
- pathconf(path, _PC_REC_MIN_XFER_SIZE);
- t->current_filesystem->xfer_align =
- pathconf(path, _PC_REC_XFER_ALIGN);
- }
- /* At least we need an alignment size. */
- if (t->current_filesystem->xfer_align == -1)
- return ((errno == EINVAL)?1:-1);
- else
- return (0);
-}
-#else
-static int
-get_xfer_size(struct tree *t, int fd, const char *path)
-{
- (void)t; /* UNUSED */
- (void)fd; /* UNUSED */
- (void)path; /* UNUSED */
- return (1);/* Not supported */
-}
-#endif
-
-#if defined(HAVE_STATVFS)
-static inline __LA_UNUSED void
-set_statvfs_transfer_size(struct filesystem *fs, const struct statvfs *sfs)
-{
- fs->xfer_align = sfs->f_frsize > 0 ? (long)sfs->f_frsize : -1;
- fs->max_xfer_size = -1;
-#if defined(HAVE_STRUCT_STATVFS_F_IOSIZE)
- fs->min_xfer_size = sfs->f_iosize > 0 ? (long)sfs->f_iosize : -1;
- fs->incr_xfer_size = sfs->f_iosize > 0 ? (long)sfs->f_iosize : -1;
-#else
- fs->min_xfer_size = sfs->f_bsize > 0 ? (long)sfs->f_bsize : -1;
- fs->incr_xfer_size = sfs->f_bsize > 0 ? (long)sfs->f_bsize : -1;
-#endif
-}
-#endif
-
-#if defined(HAVE_STRUCT_STATFS)
-static inline __LA_UNUSED void
-set_statfs_transfer_size(struct filesystem *fs, const struct statfs *sfs)
-{
- fs->xfer_align = sfs->f_bsize > 0 ? (long)sfs->f_bsize : -1;
- fs->max_xfer_size = -1;
-#if defined(HAVE_STRUCT_STATFS_F_IOSIZE)
- fs->min_xfer_size = sfs->f_iosize > 0 ? (long)sfs->f_iosize : -1;
- fs->incr_xfer_size = sfs->f_iosize > 0 ? (long)sfs->f_iosize : -1;
-#else
- fs->min_xfer_size = sfs->f_bsize > 0 ? (long)sfs->f_bsize : -1;
- fs->incr_xfer_size = sfs->f_bsize > 0 ? (long)sfs->f_bsize : -1;
-#endif
-}
-#endif
-
-#if defined(HAVE_STRUCT_STATFS) && defined(HAVE_STATFS) && \
- defined(HAVE_FSTATFS) && defined(MNT_LOCAL) && !defined(ST_LOCAL)
-
-/*
- * Gather current filesystem properties on FreeBSD, OpenBSD and Mac OS X.
- */
-static int
-setup_current_filesystem(struct archive_read_disk *a)
-{
- struct tree *t = a->tree;
- struct statfs sfs;
-#if defined(HAVE_GETVFSBYNAME) && defined(VFCF_SYNTHETIC)
-/* TODO: configure should set GETVFSBYNAME_ARG_TYPE to make
- * this accurate; some platforms have both and we need the one that's
- * used by getvfsbyname()
- *
- * Then the following would become:
- * #if defined(GETVFSBYNAME_ARG_TYPE)
- * GETVFSBYNAME_ARG_TYPE vfc;
- * #endif
- */
-# if defined(HAVE_STRUCT_XVFSCONF)
- struct xvfsconf vfc;
-# else
- struct vfsconf vfc;
-# endif
-#endif
- int r, xr = 0;
-#if !defined(HAVE_STRUCT_STATFS_F_NAMEMAX)
- long nm;
-#endif
-
- t->current_filesystem->synthetic = -1;
- t->current_filesystem->remote = -1;
- if (tree_current_is_symblic_link_target(t)) {
-#if defined(HAVE_OPENAT)
- /*
- * Get file system statistics on any directory
- * where current is.
- */
- int fd = openat(tree_current_dir_fd(t),
- tree_current_access_path(t), O_RDONLY | O_CLOEXEC);
- __archive_ensure_cloexec_flag(fd);
- if (fd < 0) {
- archive_set_error(&a->archive, errno,
- "openat failed");
- return (ARCHIVE_FAILED);
- }
- r = fstatfs(fd, &sfs);
- if (r == 0)
- xr = get_xfer_size(t, fd, NULL);
- close(fd);
-#else
- if (tree_enter_working_dir(t) != 0) {
- archive_set_error(&a->archive, errno, "fchdir failed");
- return (ARCHIVE_FAILED);
- }
- r = statfs(tree_current_access_path(t), &sfs);
- if (r == 0)
- xr = get_xfer_size(t, -1, tree_current_access_path(t));
-#endif
- } else {
- r = fstatfs(tree_current_dir_fd(t), &sfs);
- if (r == 0)
- xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
- }
- if (r == -1 || xr == -1) {
- archive_set_error(&a->archive, errno, "statfs failed");
- return (ARCHIVE_FAILED);
- } else if (xr == 1) {
- /* pathconf(_PC_REX_*) operations are not supported. */
- set_statfs_transfer_size(t->current_filesystem, &sfs);
- }
- if (sfs.f_flags & MNT_LOCAL)
- t->current_filesystem->remote = 0;
- else
- t->current_filesystem->remote = 1;
-
-#if defined(HAVE_GETVFSBYNAME) && defined(VFCF_SYNTHETIC)
- r = getvfsbyname(sfs.f_fstypename, &vfc);
- if (r == -1) {
- archive_set_error(&a->archive, errno, "getvfsbyname failed");
- return (ARCHIVE_FAILED);
- }
- if (vfc.vfc_flags & VFCF_SYNTHETIC)
- t->current_filesystem->synthetic = 1;
- else
- t->current_filesystem->synthetic = 0;
-#endif
-
-#if defined(MNT_NOATIME)
- if (sfs.f_flags & MNT_NOATIME)
- t->current_filesystem->noatime = 1;
- else
-#endif
- t->current_filesystem->noatime = 0;
-
-#if defined(USE_READDIR_R)
- /* Set maximum filename length. */
-#if defined(HAVE_STRUCT_STATFS_F_NAMEMAX)
- t->current_filesystem->name_max = sfs.f_namemax;
-#else
-# if defined(_PC_NAME_MAX)
- /* Mac OS X does not have f_namemax in struct statfs. */
- if (tree_current_is_symblic_link_target(t)) {
- if (tree_enter_working_dir(t) != 0) {
- archive_set_error(&a->archive, errno, "fchdir failed");
- return (ARCHIVE_FAILED);
- }
- nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
- } else
- nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
-# else
- nm = -1;
-# endif
- if (nm == -1)
- t->current_filesystem->name_max = NAME_MAX;
- else
- t->current_filesystem->name_max = nm;
-#endif
- if (t->current_filesystem->name_max == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Cannot determine name_max");
- return (ARCHIVE_FAILED);
- }
-#endif /* USE_READDIR_R */
- return (ARCHIVE_OK);
-}
-
-#elif (defined(HAVE_STATVFS) || defined(HAVE_FSTATVFS)) && defined(ST_LOCAL)
-
-/*
- * Gather current filesystem properties on NetBSD
- */
-static int
-setup_current_filesystem(struct archive_read_disk *a)
-{
- struct tree *t = a->tree;
- struct statvfs svfs;
- int r, xr = 0;
-
- t->current_filesystem->synthetic = -1;
- if (tree_enter_working_dir(t) != 0) {
- archive_set_error(&a->archive, errno, "fchdir failed");
- return (ARCHIVE_FAILED);
- }
- if (tree_current_is_symblic_link_target(t)) {
- r = statvfs(tree_current_access_path(t), &svfs);
- if (r == 0)
- xr = get_xfer_size(t, -1, tree_current_access_path(t));
- } else {
-#ifdef HAVE_FSTATVFS
- r = fstatvfs(tree_current_dir_fd(t), &svfs);
- if (r == 0)
- xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
-#else
- r = statvfs(".", &svfs);
- if (r == 0)
- xr = get_xfer_size(t, -1, ".");
-#endif
- }
- if (r == -1 || xr == -1) {
- t->current_filesystem->remote = -1;
- archive_set_error(&a->archive, errno, "statvfs failed");
- return (ARCHIVE_FAILED);
- } else if (xr == 1) {
- /* Usually come here unless NetBSD supports _PC_REC_XFER_ALIGN
- * for pathconf() function. */
- set_statvfs_transfer_size(t->current_filesystem, &svfs);
- }
- if (svfs.f_flag & ST_LOCAL)
- t->current_filesystem->remote = 0;
- else
- t->current_filesystem->remote = 1;
-
-#if defined(ST_NOATIME)
- if (svfs.f_flag & ST_NOATIME)
- t->current_filesystem->noatime = 1;
- else
-#endif
- t->current_filesystem->noatime = 0;
-
- /* Set maximum filename length. */
- t->current_filesystem->name_max = svfs.f_namemax;
- return (ARCHIVE_OK);
-}
-
-#elif defined(HAVE_SYS_STATFS_H) && defined(HAVE_LINUX_MAGIC_H) &&\
- defined(HAVE_STATFS) && defined(HAVE_FSTATFS)
-/*
- * Note: statfs is deprecated since LSB 3.2
- */
-
-#ifndef CIFS_SUPER_MAGIC
-#define CIFS_SUPER_MAGIC 0xFF534D42
-#endif
-#ifndef DEVFS_SUPER_MAGIC
-#define DEVFS_SUPER_MAGIC 0x1373
-#endif
-
-/*
- * Gather current filesystem properties on Linux
- */
-static int
-setup_current_filesystem(struct archive_read_disk *a)
-{
- struct tree *t = a->tree;
- struct statfs sfs;
-#if defined(HAVE_STATVFS)
- struct statvfs svfs;
-#endif
- int r, vr = 0, xr = 0;
-
- if (tree_current_is_symblic_link_target(t)) {
-#if defined(HAVE_OPENAT)
- /*
- * Get file system statistics on any directory
- * where current is.
- */
- int fd = openat(tree_current_dir_fd(t),
- tree_current_access_path(t), O_RDONLY | O_CLOEXEC);
- __archive_ensure_cloexec_flag(fd);
- if (fd < 0) {
- archive_set_error(&a->archive, errno,
- "openat failed");
- return (ARCHIVE_FAILED);
- }
-#if defined(HAVE_FSTATVFS)
- vr = fstatvfs(fd, &svfs);/* for f_flag, mount flags */
-#endif
- r = fstatfs(fd, &sfs);
- if (r == 0)
- xr = get_xfer_size(t, fd, NULL);
- close(fd);
-#else
- if (tree_enter_working_dir(t) != 0) {
- archive_set_error(&a->archive, errno, "fchdir failed");
- return (ARCHIVE_FAILED);
- }
-#if defined(HAVE_STATVFS)
- vr = statvfs(tree_current_access_path(t), &svfs);
-#endif
- r = statfs(tree_current_access_path(t), &sfs);
- if (r == 0)
- xr = get_xfer_size(t, -1, tree_current_access_path(t));
-#endif
- } else {
-#ifdef HAVE_FSTATFS
-#if defined(HAVE_FSTATVFS)
- vr = fstatvfs(tree_current_dir_fd(t), &svfs);
-#endif
- r = fstatfs(tree_current_dir_fd(t), &sfs);
- if (r == 0)
- xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
-#else
- if (tree_enter_working_dir(t) != 0) {
- archive_set_error(&a->archive, errno, "fchdir failed");
- return (ARCHIVE_FAILED);
- }
-#if defined(HAVE_STATVFS)
- vr = statvfs(".", &svfs);
-#endif
- r = statfs(".", &sfs);
- if (r == 0)
- xr = get_xfer_size(t, -1, ".");
-#endif
- }
- if (r == -1 || xr == -1 || vr == -1) {
- t->current_filesystem->synthetic = -1;
- t->current_filesystem->remote = -1;
- archive_set_error(&a->archive, errno, "statfs failed");
- return (ARCHIVE_FAILED);
- } else if (xr == 1) {
- /* pathconf(_PC_REX_*) operations are not supported. */
-#if defined(HAVE_STATVFS)
- set_statvfs_transfer_size(t->current_filesystem, &svfs);
-#else
- set_statfs_transfer_size(t->current_filesystem, &sfs);
-#endif
- }
- switch (sfs.f_type) {
- case AFS_SUPER_MAGIC:
- case CIFS_SUPER_MAGIC:
- case CODA_SUPER_MAGIC:
- case NCP_SUPER_MAGIC:/* NetWare */
- case NFS_SUPER_MAGIC:
- case SMB_SUPER_MAGIC:
- t->current_filesystem->remote = 1;
- t->current_filesystem->synthetic = 0;
- break;
- case DEVFS_SUPER_MAGIC:
- case PROC_SUPER_MAGIC:
- case USBDEVICE_SUPER_MAGIC:
- t->current_filesystem->remote = 0;
- t->current_filesystem->synthetic = 1;
- break;
- default:
- t->current_filesystem->remote = 0;
- t->current_filesystem->synthetic = 0;
- break;
- }
-
-#if defined(ST_NOATIME)
-#if defined(HAVE_STATVFS)
- if (svfs.f_flag & ST_NOATIME)
-#else
- if (sfs.f_flags & ST_NOATIME)
-#endif
- t->current_filesystem->noatime = 1;
- else
-#endif
- t->current_filesystem->noatime = 0;
-
-#if defined(USE_READDIR_R)
- /* Set maximum filename length. */
-#if defined(HAVE_STATVFS)
- t->current_filesystem->name_max = svfs.f_namemax;
-#else
- t->current_filesystem->name_max = sfs.f_namelen;
-#endif
- if (t->current_filesystem->name_max == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Cannot determine name_max");
- return (ARCHIVE_FAILED);
- }
-#endif
- return (ARCHIVE_OK);
-}
-
-#elif defined(HAVE_SYS_STATVFS_H) &&\
- (defined(HAVE_STATVFS) || defined(HAVE_FSTATVFS))
-
-/*
- * Gather current filesystem properties on other posix platform.
- */
-static int
-setup_current_filesystem(struct archive_read_disk *a)
-{
- struct tree *t = a->tree;
- struct statvfs svfs;
- int r, xr = 0;
-
- t->current_filesystem->synthetic = -1;/* Not supported */
- t->current_filesystem->remote = -1;/* Not supported */
- if (tree_current_is_symblic_link_target(t)) {
-#if defined(HAVE_OPENAT)
- /*
- * Get file system statistics on any directory
- * where current is.
- */
- int fd = openat(tree_current_dir_fd(t),
- tree_current_access_path(t), O_RDONLY | O_CLOEXEC);
- __archive_ensure_cloexec_flag(fd);
- if (fd < 0) {
- archive_set_error(&a->archive, errno,
- "openat failed");
- return (ARCHIVE_FAILED);
- }
- r = fstatvfs(fd, &svfs);
- if (r == 0)
- xr = get_xfer_size(t, fd, NULL);
- close(fd);
-#else
- if (tree_enter_working_dir(t) != 0) {
- archive_set_error(&a->archive, errno, "fchdir failed");
- return (ARCHIVE_FAILED);
- }
- r = statvfs(tree_current_access_path(t), &svfs);
- if (r == 0)
- xr = get_xfer_size(t, -1, tree_current_access_path(t));
-#endif
- } else {
-#ifdef HAVE_FSTATVFS
- r = fstatvfs(tree_current_dir_fd(t), &svfs);
- if (r == 0)
- xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
-#else
- if (tree_enter_working_dir(t) != 0) {
- archive_set_error(&a->archive, errno, "fchdir failed");
- return (ARCHIVE_FAILED);
- }
- r = statvfs(".", &svfs);
- if (r == 0)
- xr = get_xfer_size(t, -1, ".");
-#endif
- }
- if (r == -1 || xr == -1) {
- t->current_filesystem->synthetic = -1;
- t->current_filesystem->remote = -1;
- archive_set_error(&a->archive, errno, "statvfs failed");
- return (ARCHIVE_FAILED);
- } else if (xr == 1) {
- /* pathconf(_PC_REX_*) operations are not supported. */
- set_statvfs_transfer_size(t->current_filesystem, &svfs);
- }
-
-#if defined(ST_NOATIME)
- if (svfs.f_flag & ST_NOATIME)
- t->current_filesystem->noatime = 1;
- else
-#endif
- t->current_filesystem->noatime = 0;
-
-#if defined(USE_READDIR_R)
- /* Set maximum filename length. */
- t->current_filesystem->name_max = svfs.f_namemax;
- if (t->current_filesystem->name_max == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Cannot determine name_max");
- return (ARCHIVE_FAILED);
- }
-#endif
- return (ARCHIVE_OK);
-}
-
-#else
-
-/*
- * Generic: Gather current filesystem properties.
- * TODO: Is this generic function really needed?
- */
-static int
-setup_current_filesystem(struct archive_read_disk *a)
-{
- struct tree *t = a->tree;
-#if defined(_PC_NAME_MAX) && defined(USE_READDIR_R)
- long nm;
-#endif
- t->current_filesystem->synthetic = -1;/* Not supported */
- t->current_filesystem->remote = -1;/* Not supported */
- t->current_filesystem->noatime = 0;
- (void)get_xfer_size(t, -1, ".");/* Dummy call to avoid build error. */
- t->current_filesystem->xfer_align = -1;/* Unknown */
- t->current_filesystem->max_xfer_size = -1;
- t->current_filesystem->min_xfer_size = -1;
- t->current_filesystem->incr_xfer_size = -1;
-
-#if defined(USE_READDIR_R)
- /* Set maximum filename length. */
-# if defined(_PC_NAME_MAX)
- if (tree_current_is_symblic_link_target(t)) {
- if (tree_enter_working_dir(t) != 0) {
- archive_set_error(&a->archive, errno, "fchdir failed");
- return (ARCHIVE_FAILED);
- }
- nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
- } else
- nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
- if (nm == -1)
-# endif /* _PC_NAME_MAX */
- /*
- * Some systems (HP-UX or others?) incorrectly defined
- * NAME_MAX macro to be a smaller value.
- */
-# if defined(NAME_MAX) && NAME_MAX >= 255
- t->current_filesystem->name_max = NAME_MAX;
-# else
- /* No way to get a trusted value of maximum filename
- * length. */
- t->current_filesystem->name_max = PATH_MAX;
-# endif /* NAME_MAX */
-# if defined(_PC_NAME_MAX)
- else
- t->current_filesystem->name_max = nm;
-# endif /* _PC_NAME_MAX */
- if (t->current_filesystem->name_max == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Cannot determine name_max");
- return (ARCHIVE_FAILED);
- }
-#endif /* USE_READDIR_R */
- return (ARCHIVE_OK);
-}
-
-#endif
-
-static int
-close_and_restore_time(int fd, struct tree *t, struct restore_time *rt)
-{
-#ifndef HAVE_UTIMES
- (void)t; /* UNUSED */
- (void)rt; /* UNUSED */
- return (close(fd));
-#else
-#if defined(HAVE_FUTIMENS) && !defined(__CYGWIN__)
- struct timespec timespecs[2];
-#endif
- struct timeval times[2];
-
- if ((t->flags & needsRestoreTimes) == 0 || rt->noatime) {
- if (fd >= 0)
- return (close(fd));
- else
- return (0);
- }
-
-#if defined(HAVE_FUTIMENS) && !defined(__CYGWIN__)
- timespecs[1].tv_sec = rt->mtime;
- timespecs[1].tv_nsec = rt->mtime_nsec;
-
- timespecs[0].tv_sec = rt->atime;
- timespecs[0].tv_nsec = rt->atime_nsec;
- /* futimens() is defined in POSIX.1-2008. */
- if (futimens(fd, timespecs) == 0)
- return (close(fd));
-#endif
-
- times[1].tv_sec = rt->mtime;
- times[1].tv_usec = rt->mtime_nsec / 1000;
-
- times[0].tv_sec = rt->atime;
- times[0].tv_usec = rt->atime_nsec / 1000;
-
-#if !defined(HAVE_FUTIMENS) && defined(HAVE_FUTIMES) && !defined(__CYGWIN__)
- if (futimes(fd, times) == 0)
- return (close(fd));
-#endif
- close(fd);
-#if defined(HAVE_FUTIMESAT)
- if (futimesat(tree_current_dir_fd(t), rt->name, times) == 0)
- return (0);
-#endif
-#ifdef HAVE_LUTIMES
- if (lutimes(rt->name, times) != 0)
-#else
- if (AE_IFLNK != rt->filetype && utimes(rt->name, times) != 0)
-#endif
- return (-1);
-#endif
- return (0);
-}
-
-static int
-open_on_current_dir(struct tree *t, const char *path, int flags)
-{
-#ifdef HAVE_OPENAT
- return (openat(tree_current_dir_fd(t), path, flags));
-#else
- if (tree_enter_working_dir(t) != 0)
- return (-1);
- return (open(path, flags));
-#endif
-}
-
-static int
-tree_dup(int fd)
-{
- int new_fd;
-#ifdef F_DUPFD_CLOEXEC
- static volatile int can_dupfd_cloexec = 1;
-
- if (can_dupfd_cloexec) {
- new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
- if (new_fd != -1)
- return (new_fd);
- /* Linux 2.6.18 - 2.6.23 declare F_DUPFD_CLOEXEC,
- * but it cannot be used. So we have to try dup(). */
- /* We won't try F_DUPFD_CLOEXEC. */
- can_dupfd_cloexec = 0;
- }
-#endif /* F_DUPFD_CLOEXEC */
- new_fd = dup(fd);
- __archive_ensure_cloexec_flag(new_fd);
- return (new_fd);
-}
-
-/*
- * Add a directory path to the current stack.
- */
-static void
-tree_push(struct tree *t, const char *path, int filesystem_id,
- int64_t dev, int64_t ino, struct restore_time *rt)
-{
- struct tree_entry *te;
-
- te = calloc(1, sizeof(*te));
- if (te == NULL)
- __archive_errx(1, "Out of memory");
- te->next = t->stack;
- te->parent = t->current;
- if (te->parent)
- te->depth = te->parent->depth + 1;
- t->stack = te;
- archive_string_init(&te->name);
- te->symlink_parent_fd = -1;
- archive_strcpy(&te->name, path);
- te->flags = needsDescent | needsOpen | needsAscent;
- te->filesystem_id = filesystem_id;
- te->dev = dev;
- te->ino = ino;
- te->dirname_length = t->dirname_length;
- te->restore_time.name = te->name.s;
- if (rt != NULL) {
- te->restore_time.mtime = rt->mtime;
- te->restore_time.mtime_nsec = rt->mtime_nsec;
- te->restore_time.atime = rt->atime;
- te->restore_time.atime_nsec = rt->atime_nsec;
- te->restore_time.filetype = rt->filetype;
- te->restore_time.noatime = rt->noatime;
- }
-}
-
-/*
- * Append a name to the current dir path.
- */
-static void
-tree_append(struct tree *t, const char *name, size_t name_length)
-{
- size_t size_needed;
-
- t->path.s[t->dirname_length] = '\0';
- t->path.length = t->dirname_length;
- /* Strip trailing '/' from name, unless entire name is "/". */
- while (name_length > 1 && name[name_length - 1] == '/')
- name_length--;
-
- /* Resize pathname buffer as needed. */
- size_needed = name_length + t->dirname_length + 2;
- archive_string_ensure(&t->path, size_needed);
- /* Add a separating '/' if it's needed. */
- if (t->dirname_length > 0 && t->path.s[archive_strlen(&t->path)-1] != '/')
- archive_strappend_char(&t->path, '/');
- t->basename = t->path.s + archive_strlen(&t->path);
- archive_strncat(&t->path, name, name_length);
- t->restore_time.name = t->basename;
-}
-
-/*
- * Open a directory tree for traversal.
- */
-static struct tree *
-tree_open(const char *path, int symlink_mode, int restore_time)
-{
- struct tree *t;
-
- if ((t = calloc(1, sizeof(*t))) == NULL)
- return (NULL);
- archive_string_init(&t->path);
- archive_string_ensure(&t->path, 31);
- t->initial_symlink_mode = symlink_mode;
- return (tree_reopen(t, path, restore_time));
-}
-
-static struct tree *
-tree_reopen(struct tree *t, const char *path, int restore_time)
-{
-#if defined(O_PATH)
- /* Linux */
- const int o_flag = O_PATH;
-#elif defined(O_SEARCH)
- /* SunOS */
- const int o_flag = O_SEARCH;
-#elif defined(__FreeBSD__) && defined(O_EXEC)
- /* FreeBSD */
- const int o_flag = O_EXEC;
-#endif
-
- t->flags = (restore_time != 0)?needsRestoreTimes:0;
- t->flags |= onInitialDir;
- t->visit_type = 0;
- t->tree_errno = 0;
- t->dirname_length = 0;
- t->depth = 0;
- t->descend = 0;
- t->current = NULL;
- t->d = INVALID_DIR_HANDLE;
- t->symlink_mode = t->initial_symlink_mode;
- archive_string_empty(&t->path);
- t->entry_fd = -1;
- t->entry_eof = 0;
- t->entry_remaining_bytes = 0;
- t->initial_filesystem_id = -1;
-
- /* First item is set up a lot like a symlink traversal. */
- tree_push(t, path, 0, 0, 0, NULL);
- t->stack->flags = needsFirstVisit;
- t->maxOpenCount = t->openCount = 1;
- t->initial_dir_fd = open(".", O_RDONLY | O_CLOEXEC);
-#if defined(O_PATH) || defined(O_SEARCH) || \
- (defined(__FreeBSD__) && defined(O_EXEC))
- /*
- * Most likely reason to fail opening "." is that it's not readable,
- * so try again for execute. The consequences of not opening this are
- * unhelpful and unnecessary errors later.
- */
- if (t->initial_dir_fd < 0)
- t->initial_dir_fd = open(".", o_flag | O_CLOEXEC);
-#endif
- __archive_ensure_cloexec_flag(t->initial_dir_fd);
- t->working_dir_fd = tree_dup(t->initial_dir_fd);
- return (t);
-}
-
-static int
-tree_descent(struct tree *t)
-{
- int flag, new_fd, r = 0;
-
- t->dirname_length = archive_strlen(&t->path);
- flag = O_RDONLY | O_CLOEXEC;
-#if defined(O_DIRECTORY)
- flag |= O_DIRECTORY;
-#endif
- new_fd = open_on_current_dir(t, t->stack->name.s, flag);
- __archive_ensure_cloexec_flag(new_fd);
- if (new_fd < 0) {
- t->tree_errno = errno;
- r = TREE_ERROR_DIR;
- } else {
- t->depth++;
- /* If it is a link, set up fd for the ascent. */
- if (t->stack->flags & isDirLink) {
- t->stack->symlink_parent_fd = t->working_dir_fd;
- t->openCount++;
- if (t->openCount > t->maxOpenCount)
- t->maxOpenCount = t->openCount;
- } else
- close(t->working_dir_fd);
- /* Renew the current working directory. */
- t->working_dir_fd = new_fd;
- t->flags &= ~onWorkingDir;
- }
- return (r);
-}
-
-/*
- * We've finished a directory; ascend back to the parent.
- */
-static int
-tree_ascend(struct tree *t)
-{
- struct tree_entry *te;
- int new_fd, r = 0, prev_dir_fd;
-
- te = t->stack;
- prev_dir_fd = t->working_dir_fd;
- if (te->flags & isDirLink)
- new_fd = te->symlink_parent_fd;
- else {
- new_fd = open_on_current_dir(t, "..", O_RDONLY | O_CLOEXEC);
- __archive_ensure_cloexec_flag(new_fd);
- }
- if (new_fd < 0) {
- t->tree_errno = errno;
- r = TREE_ERROR_FATAL;
- } else {
- /* Renew the current working directory. */
- t->working_dir_fd = new_fd;
- t->flags &= ~onWorkingDir;
- /* Current directory has been changed, we should
- * close an fd of previous working directory. */
- close_and_restore_time(prev_dir_fd, t, &te->restore_time);
- if (te->flags & isDirLink) {
- t->openCount--;
- te->symlink_parent_fd = -1;
- }
- t->depth--;
- }
- return (r);
-}
-
-/*
- * Return to the initial directory where tree_open() was performed.
- */
-static int
-tree_enter_initial_dir(struct tree *t)
-{
- int r = 0;
-
- if ((t->flags & onInitialDir) == 0) {
- r = fchdir(t->initial_dir_fd);
- if (r == 0) {
- t->flags &= ~onWorkingDir;
- t->flags |= onInitialDir;
- }
- }
- return (r);
-}
-
-/*
- * Restore working directory of directory traversals.
- */
-static int
-tree_enter_working_dir(struct tree *t)
-{
- int r = 0;
-
- /*
- * Change the current directory if really needed.
- * Sometimes this is unneeded when we did not do
- * descent.
- */
- if (t->depth > 0 && (t->flags & onWorkingDir) == 0) {
- r = fchdir(t->working_dir_fd);
- if (r == 0) {
- t->flags &= ~onInitialDir;
- t->flags |= onWorkingDir;
- }
- }
- return (r);
-}
-
-static int
-tree_current_dir_fd(struct tree *t)
-{
- return (t->working_dir_fd);
-}
-
-/*
- * Pop the working stack.
- */
-static void
-tree_pop(struct tree *t)
-{
- struct tree_entry *te;
-
- t->path.s[t->dirname_length] = '\0';
- t->path.length = t->dirname_length;
- if (t->stack == t->current && t->current != NULL)
- t->current = t->current->parent;
- te = t->stack;
- t->stack = te->next;
- t->dirname_length = te->dirname_length;
- t->basename = t->path.s + t->dirname_length;
- while (t->basename[0] == '/')
- t->basename++;
- archive_string_free(&te->name);
- free(te);
-}
-
-/*
- * Get the next item in the tree traversal.
- */
-static int
-tree_next(struct tree *t)
-{
- int r;
-
- while (t->stack != NULL) {
- /* If there's an open dir, get the next entry from there. */
- if (t->d != INVALID_DIR_HANDLE) {
- r = tree_dir_next_posix(t);
- if (r == 0)
- continue;
- return (r);
- }
-
- if (t->stack->flags & needsFirstVisit) {
- /* Top stack item needs a regular visit. */
- t->current = t->stack;
- tree_append(t, t->stack->name.s,
- archive_strlen(&(t->stack->name)));
- /* t->dirname_length = t->path_length; */
- /* tree_pop(t); */
- t->stack->flags &= ~needsFirstVisit;
- return (t->visit_type = TREE_REGULAR);
- } else if (t->stack->flags & needsDescent) {
- /* Top stack item is dir to descend into. */
- t->current = t->stack;
- tree_append(t, t->stack->name.s,
- archive_strlen(&(t->stack->name)));
- t->stack->flags &= ~needsDescent;
- r = tree_descent(t);
- if (r != 0) {
- tree_pop(t);
- t->visit_type = r;
- } else
- t->visit_type = TREE_POSTDESCENT;
- return (t->visit_type);
- } else if (t->stack->flags & needsOpen) {
- t->stack->flags &= ~needsOpen;
- r = tree_dir_next_posix(t);
- if (r == 0)
- continue;
- return (r);
- } else if (t->stack->flags & needsAscent) {
- /* Top stack item is dir and we're done with it. */
- r = tree_ascend(t);
- tree_pop(t);
- t->visit_type = r != 0 ? r : TREE_POSTASCENT;
- return (t->visit_type);
- } else {
- /* Top item on stack is dead. */
- tree_pop(t);
- t->flags &= ~hasLstat;
- t->flags &= ~hasStat;
- }
- }
- return (t->visit_type = 0);
-}
-
-static int
-tree_dir_next_posix(struct tree *t)
-{
- int r;
- const char *name;
- size_t namelen;
-
- if (t->d == NULL) {
-#if defined(USE_READDIR_R)
- size_t dirent_size;
-#endif
-
-#if defined(HAVE_FDOPENDIR)
- t->d = fdopendir(tree_dup(t->working_dir_fd));
-#else /* HAVE_FDOPENDIR */
- if (tree_enter_working_dir(t) == 0) {
- t->d = opendir(".");
-#ifdef HAVE_DIRFD
- __archive_ensure_cloexec_flag(dirfd(t->d));
-#endif
- }
-#endif /* HAVE_FDOPENDIR */
- if (t->d == NULL) {
- r = tree_ascend(t); /* Undo "chdir" */
- tree_pop(t);
- t->tree_errno = errno;
- t->visit_type = r != 0 ? r : TREE_ERROR_DIR;
- return (t->visit_type);
- }
-#if defined(USE_READDIR_R)
- dirent_size = offsetof(struct dirent, d_name) +
- t->filesystem_table[t->current->filesystem_id].name_max + 1;
- if (t->dirent == NULL || t->dirent_allocated < dirent_size) {
- free(t->dirent);
- t->dirent = malloc(dirent_size);
- if (t->dirent == NULL) {
- closedir(t->d);
- t->d = INVALID_DIR_HANDLE;
- (void)tree_ascend(t);
- tree_pop(t);
- t->tree_errno = ENOMEM;
- t->visit_type = TREE_ERROR_DIR;
- return (t->visit_type);
- }
- t->dirent_allocated = dirent_size;
- }
-#endif /* USE_READDIR_R */
- }
- for (;;) {
- errno = 0;
-#if defined(USE_READDIR_R)
- r = readdir_r(t->d, t->dirent, &t->de);
-#ifdef _AIX
- /* Note: According to the man page, return value 9 indicates
- * that the readdir_r was not successful and the error code
- * is set to the global errno variable. And then if the end
- * of directory entries was reached, the return value is 9
- * and the third parameter is set to NULL and errno is
- * unchanged. */
- if (r == 9)
- r = errno;
-#endif /* _AIX */
- if (r != 0 || t->de == NULL) {
-#else
- t->de = readdir(t->d);
- if (t->de == NULL) {
- r = errno;
-#endif
- closedir(t->d);
- t->d = INVALID_DIR_HANDLE;
- if (r != 0) {
- t->tree_errno = r;
- t->visit_type = TREE_ERROR_DIR;
- return (t->visit_type);
- } else
- return (0);
- }
- name = t->de->d_name;
- namelen = D_NAMELEN(t->de);
- t->flags &= ~hasLstat;
- t->flags &= ~hasStat;
- if (name[0] == '.' && name[1] == '\0')
- continue;
- if (name[0] == '.' && name[1] == '.' && name[2] == '\0')
- continue;
- tree_append(t, name, namelen);
- return (t->visit_type = TREE_REGULAR);
- }
-}
-
-
-/*
- * Get the stat() data for the entry just returned from tree_next().
- */
-static const struct stat *
-tree_current_stat(struct tree *t)
-{
- if (!(t->flags & hasStat)) {
-#ifdef HAVE_FSTATAT
- if (fstatat(tree_current_dir_fd(t),
- tree_current_access_path(t), &t->st, 0) != 0)
-#else
- if (tree_enter_working_dir(t) != 0)
- return NULL;
- if (la_stat(tree_current_access_path(t), &t->st) != 0)
-#endif
- return NULL;
- t->flags |= hasStat;
- }
- return (&t->st);
-}
-
-/*
- * Get the lstat() data for the entry just returned from tree_next().
- */
-static const struct stat *
-tree_current_lstat(struct tree *t)
-{
- if (!(t->flags & hasLstat)) {
-#ifdef HAVE_FSTATAT
- if (fstatat(tree_current_dir_fd(t),
- tree_current_access_path(t), &t->lst,
- AT_SYMLINK_NOFOLLOW) != 0)
-#else
- if (tree_enter_working_dir(t) != 0)
- return NULL;
-#ifdef HAVE_LSTAT
- if (lstat(tree_current_access_path(t), &t->lst) != 0)
-#else
- if (la_stat(tree_current_access_path(t), &t->lst) != 0)
-#endif
-#endif
- return NULL;
- t->flags |= hasLstat;
- }
- return (&t->lst);
-}
-
-/*
- * Test whether current entry is a dir or link to a dir.
- */
-static int
-tree_current_is_dir(struct tree *t)
-{
- const struct stat *st;
- /*
- * If we already have lstat() info, then try some
- * cheap tests to determine if this is a dir.
- */
- if (t->flags & hasLstat) {
- /* If lstat() says it's a dir, it must be a dir. */
- st = tree_current_lstat(t);
- if (st == NULL)
- return 0;
- if (S_ISDIR(st->st_mode))
- return 1;
- /* Not a dir; might be a link to a dir. */
- /* If it's not a link, then it's not a link to a dir. */
- if (!S_ISLNK(st->st_mode))
- return 0;
- /*
- * It's a link, but we don't know what it's a link to,
- * so we'll have to use stat().
- */
- }
-
- st = tree_current_stat(t);
- /* If we can't stat it, it's not a dir. */
- if (st == NULL)
- return 0;
- /* Use the definitive test. Hopefully this is cached. */
- return (S_ISDIR(st->st_mode));
-}
-
-/*
- * Test whether current entry is a physical directory. Usually, we
- * already have at least one of stat() or lstat() in memory, so we
- * use tricks to try to avoid an extra trip to the disk.
- */
-static int
-tree_current_is_physical_dir(struct tree *t)
-{
- const struct stat *st;
-
- /*
- * If stat() says it isn't a dir, then it's not a dir.
- * If stat() data is cached, this check is free, so do it first.
- */
- if (t->flags & hasStat) {
- st = tree_current_stat(t);
- if (st == NULL)
- return (0);
- if (!S_ISDIR(st->st_mode))
- return (0);
- }
-
- /*
- * Either stat() said it was a dir (in which case, we have
- * to determine whether it's really a link to a dir) or
- * stat() info wasn't available. So we use lstat(), which
- * hopefully is already cached.
- */
-
- st = tree_current_lstat(t);
- /* If we can't stat it, it's not a dir. */
- if (st == NULL)
- return 0;
- /* Use the definitive test. Hopefully this is cached. */
- return (S_ISDIR(st->st_mode));
-}
-
-/*
- * Test whether the same file has been in the tree as its parent.
- */
-static int
-tree_target_is_same_as_parent(struct tree *t, const struct stat *st)
-{
- struct tree_entry *te;
-
- for (te = t->current->parent; te != NULL; te = te->parent) {
- if (te->dev == (int64_t)st->st_dev &&
- te->ino == (int64_t)st->st_ino)
- return (1);
- }
- return (0);
-}
-
-/*
- * Test whether the current file is symbolic link target and
- * on the other filesystem.
- */
-static int
-tree_current_is_symblic_link_target(struct tree *t)
-{
- static const struct stat *lst, *st;
-
- lst = tree_current_lstat(t);
- st = tree_current_stat(t);
- return (st != NULL && lst != NULL &&
- (int64_t)st->st_dev == t->current_filesystem->dev &&
- st->st_dev != lst->st_dev);
-}
-
-/*
- * Return the access path for the entry just returned from tree_next().
- */
-static const char *
-tree_current_access_path(struct tree *t)
-{
- return (t->basename);
-}
-
-/*
- * Return the full path for the entry just returned from tree_next().
- */
-static const char *
-tree_current_path(struct tree *t)
-{
- return (t->path.s);
-}
-
-/*
- * Terminate the traversal.
- */
-static void
-tree_close(struct tree *t)
-{
-
- if (t == NULL)
- return;
- if (t->entry_fd >= 0) {
- close_and_restore_time(t->entry_fd, t, &t->restore_time);
- t->entry_fd = -1;
- }
- /* Close the handle of readdir(). */
- if (t->d != INVALID_DIR_HANDLE) {
- closedir(t->d);
- t->d = INVALID_DIR_HANDLE;
- }
- /* Release anything remaining in the stack. */
- while (t->stack != NULL) {
- if (t->stack->flags & isDirLink)
- close(t->stack->symlink_parent_fd);
- tree_pop(t);
- }
- if (t->working_dir_fd >= 0) {
- close(t->working_dir_fd);
- t->working_dir_fd = -1;
- }
- if (t->initial_dir_fd >= 0) {
- close(t->initial_dir_fd);
- t->initial_dir_fd = -1;
- }
-}
-
-/*
- * Release any resources.
- */
-static void
-tree_free(struct tree *t)
-{
- int i;
-
- if (t == NULL)
- return;
- archive_string_free(&t->path);
-#if defined(USE_READDIR_R)
- free(t->dirent);
-#endif
- free(t->sparse_list);
- for (i = 0; i < t->max_filesystem_id; i++)
- free(t->filesystem_table[i].allocation_ptr);
- free(t->filesystem_table);
- free(t);
-}
-
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_read_disk_private.h b/contrib/libs/libarchive/libarchive/archive_read_disk_private.h
deleted file mode 100644
index bc8abc15d1..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_disk_private.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*-
- * Copyright (c) 2003-2009 Tim Kientzle
- * 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
- * in this position and unchanged.
- * 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(S) ``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(S) 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.
- *
- * $FreeBSD: head/lib/libarchive/archive_read_disk_private.h 201105 2009-12-28 03:20:54Z kientzle $
- */
-
-#ifndef ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
-#define ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
-#include "archive_platform_acl.h"
-
-struct tree;
-struct archive_entry;
-
-struct archive_read_disk {
- struct archive archive;
-
- /* Reused by archive_read_next_header() */
- struct archive_entry *entry;
-
- /*
- * Symlink mode is one of 'L'ogical, 'P'hysical, or 'H'ybrid,
- * following an old BSD convention. 'L' follows all symlinks,
- * 'P' follows none, 'H' follows symlinks only for the first
- * item.
- */
- char symlink_mode;
-
- /*
- * Since symlink interaction changes, we need to track whether
- * we're following symlinks for the current item. 'L' mode above
- * sets this true, 'P' sets it false, 'H' changes it as we traverse.
- */
- char follow_symlinks; /* Either 'L' or 'P'. */
-
- /* Directory traversals. */
- struct tree *tree;
- int (*open_on_current_dir)(struct tree*, const char *, int);
- int (*tree_current_dir_fd)(struct tree*);
- int (*tree_enter_working_dir)(struct tree*);
-
- /* Bitfield with ARCHIVE_READDISK_* tunables */
- int flags;
-
- const char * (*lookup_gname)(void *private, int64_t gid);
- void (*cleanup_gname)(void *private);
- void *lookup_gname_data;
- const char * (*lookup_uname)(void *private, int64_t uid);
- void (*cleanup_uname)(void *private);
- void *lookup_uname_data;
-
- int (*metadata_filter_func)(struct archive *, void *,
- struct archive_entry *);
- void *metadata_filter_data;
-
- /* ARCHIVE_MATCH object. */
- struct archive *matching;
- /* Callback function, this will be invoked when ARCHIVE_MATCH
- * archive_match_*_excluded_ae return true. */
- void (*excluded_cb_func)(struct archive *, void *,
- struct archive_entry *);
- void *excluded_cb_data;
-};
-
-const char *
-archive_read_disk_entry_setup_path(struct archive_read_disk *,
- struct archive_entry *, int *);
-
-int
-archive_read_disk_entry_setup_acls(struct archive_read_disk *,
- struct archive_entry *, int *);
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_read_disk_set_standard_lookup.c b/contrib/libs/libarchive/libarchive/archive_read_disk_set_standard_lookup.c
deleted file mode 100644
index c7fd2471ec..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_disk_set_standard_lookup.c
+++ /dev/null
@@ -1,313 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_set_standard_lookup.c 201109 2009-12-28 03:30:31Z kientzle $");
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_GRP_H
-#include <grp.h>
-#endif
-#ifdef HAVE_PWD_H
-#include <pwd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-int
-archive_read_disk_set_standard_lookup(struct archive *a)
-{
- archive_set_error(a, -1, "Standard lookups not available on Windows");
- return (ARCHIVE_FATAL);
-}
-#else /* ! (_WIN32 && !__CYGWIN__) */
-#define name_cache_size 127
-
-static const char * const NO_NAME = "(noname)";
-
-struct name_cache {
- struct archive *archive;
- char *buff;
- size_t buff_size;
- int probes;
- int hits;
- size_t size;
- struct {
- id_t id;
- const char *name;
- } cache[name_cache_size];
-};
-
-static const char * lookup_gname(void *, int64_t);
-static const char * lookup_uname(void *, int64_t);
-static void cleanup(void *);
-static const char * lookup_gname_helper(struct name_cache *, id_t gid);
-static const char * lookup_uname_helper(struct name_cache *, id_t uid);
-
-/*
- * Installs functions that use getpwuid()/getgrgid()---along with
- * a simple cache to accelerate such lookups---into the archive_read_disk
- * object. This is in a separate file because getpwuid()/getgrgid()
- * can pull in a LOT of library code (including NIS/LDAP functions, which
- * pull in DNS resolvers, etc). This can easily top 500kB, which makes
- * it inappropriate for some space-constrained applications.
- *
- * Applications that are size-sensitive may want to just use the
- * real default functions (defined in archive_read_disk.c) that just
- * use the uid/gid without the lookup. Or define your own custom functions
- * if you prefer.
- */
-int
-archive_read_disk_set_standard_lookup(struct archive *a)
-{
- struct name_cache *ucache = malloc(sizeof(struct name_cache));
- struct name_cache *gcache = malloc(sizeof(struct name_cache));
-
- if (ucache == NULL || gcache == NULL) {
- archive_set_error(a, ENOMEM,
- "Can't allocate uname/gname lookup cache");
- free(ucache);
- free(gcache);
- return (ARCHIVE_FATAL);
- }
-
- memset(ucache, 0, sizeof(*ucache));
- ucache->archive = a;
- ucache->size = name_cache_size;
- memset(gcache, 0, sizeof(*gcache));
- gcache->archive = a;
- gcache->size = name_cache_size;
-
- archive_read_disk_set_gname_lookup(a, gcache, lookup_gname, cleanup);
- archive_read_disk_set_uname_lookup(a, ucache, lookup_uname, cleanup);
-
- return (ARCHIVE_OK);
-}
-
-static void
-cleanup(void *data)
-{
- struct name_cache *cache = (struct name_cache *)data;
- size_t i;
-
- if (cache != NULL) {
- for (i = 0; i < cache->size; i++) {
- if (cache->cache[i].name != NULL &&
- cache->cache[i].name != NO_NAME)
- free((void *)(uintptr_t)cache->cache[i].name);
- }
- free(cache->buff);
- free(cache);
- }
-}
-
-/*
- * Lookup uid/gid from uname/gname, return NULL if no match.
- */
-static const char *
-lookup_name(struct name_cache *cache,
- const char * (*lookup_fn)(struct name_cache *, id_t), id_t id)
-{
- const char *name;
- int slot;
-
-
- cache->probes++;
-
- slot = id % cache->size;
- if (cache->cache[slot].name != NULL) {
- if (cache->cache[slot].id == id) {
- cache->hits++;
- if (cache->cache[slot].name == NO_NAME)
- return (NULL);
- return (cache->cache[slot].name);
- }
- if (cache->cache[slot].name != NO_NAME)
- free((void *)(uintptr_t)cache->cache[slot].name);
- cache->cache[slot].name = NULL;
- }
-
- name = (lookup_fn)(cache, id);
- if (name == NULL) {
- /* Cache and return the negative response. */
- cache->cache[slot].name = NO_NAME;
- cache->cache[slot].id = id;
- return (NULL);
- }
-
- cache->cache[slot].name = name;
- cache->cache[slot].id = id;
- return (cache->cache[slot].name);
-}
-
-static const char *
-lookup_uname(void *data, int64_t uid)
-{
- struct name_cache *uname_cache = (struct name_cache *)data;
- return (lookup_name(uname_cache,
- &lookup_uname_helper, (id_t)uid));
-}
-
-#if HAVE_GETPWUID_R
-static const char *
-lookup_uname_helper(struct name_cache *cache, id_t id)
-{
- struct passwd pwent, *result;
- char * nbuff;
- size_t nbuff_size;
- int r;
-
- if (cache->buff_size == 0) {
- cache->buff_size = 256;
- cache->buff = malloc(cache->buff_size);
- }
- if (cache->buff == NULL)
- return (NULL);
- for (;;) {
- result = &pwent; /* Old getpwuid_r ignores last arg. */
- r = getpwuid_r((uid_t)id, &pwent,
- cache->buff, cache->buff_size, &result);
- if (r == 0)
- break;
- if (r != ERANGE)
- break;
- /* ERANGE means our buffer was too small, but POSIX
- * doesn't tell us how big the buffer should be, so
- * we just double it and try again. Because the buffer
- * is kept around in the cache object, we shouldn't
- * have to do this very often. */
- nbuff_size = cache->buff_size * 2;
- nbuff = realloc(cache->buff, nbuff_size);
- if (nbuff == NULL)
- break;
- cache->buff = nbuff;
- cache->buff_size = nbuff_size;
- }
- if (r != 0) {
- archive_set_error(cache->archive, errno,
- "Can't lookup user for id %d", (int)id);
- return (NULL);
- }
- if (result == NULL)
- return (NULL);
-
- return strdup(result->pw_name);
-}
-#else
-static const char *
-lookup_uname_helper(struct name_cache *cache, id_t id)
-{
- struct passwd *result;
- (void)cache; /* UNUSED */
-
- result = getpwuid((uid_t)id);
-
- if (result == NULL)
- return (NULL);
-
- return strdup(result->pw_name);
-}
-#endif
-
-static const char *
-lookup_gname(void *data, int64_t gid)
-{
- struct name_cache *gname_cache = (struct name_cache *)data;
- return (lookup_name(gname_cache,
- &lookup_gname_helper, (id_t)gid));
-}
-
-#if HAVE_GETGRGID_R
-static const char *
-lookup_gname_helper(struct name_cache *cache, id_t id)
-{
- struct group grent, *result;
- char * nbuff;
- size_t nbuff_size;
- int r;
-
- if (cache->buff_size == 0) {
- cache->buff_size = 256;
- cache->buff = malloc(cache->buff_size);
- }
- if (cache->buff == NULL)
- return (NULL);
- for (;;) {
- result = &grent; /* Old getgrgid_r ignores last arg. */
- r = getgrgid_r((gid_t)id, &grent,
- cache->buff, cache->buff_size, &result);
- if (r == 0)
- break;
- if (r != ERANGE)
- break;
- /* ERANGE means our buffer was too small, but POSIX
- * doesn't tell us how big the buffer should be, so
- * we just double it and try again. */
- nbuff_size = cache->buff_size * 2;
- nbuff = realloc(cache->buff, nbuff_size);
- if (nbuff == NULL)
- break;
- cache->buff = nbuff;
- cache->buff_size = nbuff_size;
- }
- if (r != 0) {
- archive_set_error(cache->archive, errno,
- "Can't lookup group for id %d", (int)id);
- return (NULL);
- }
- if (result == NULL)
- return (NULL);
-
- return strdup(result->gr_name);
-}
-#else
-static const char *
-lookup_gname_helper(struct name_cache *cache, id_t id)
-{
- struct group *result;
- (void)cache; /* UNUSED */
-
- result = getgrgid((gid_t)id);
-
- if (result == NULL)
- return (NULL);
-
- return strdup(result->gr_name);
-}
-#endif
-
-#endif /* ! (_WIN32 && !__CYGWIN__) */
diff --git a/contrib/libs/libarchive/libarchive/archive_read_disk_windows.c b/contrib/libs/libarchive/libarchive/archive_read_disk_windows.c
deleted file mode 100644
index f92a78a21e..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_disk_windows.c
+++ /dev/null
@@ -1,2547 +0,0 @@
-/*-
- * Copyright (c) 2003-2009 Tim Kientzle
- * Copyright (c) 2010-2012 Michihiro NAKAJIMA
- * 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
- * in this position and unchanged.
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#include <winioctl.h>
-
-#include "archive.h"
-#include "archive_string.h"
-#include "archive_entry.h"
-#include "archive_private.h"
-#include "archive_read_disk_private.h"
-
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-#ifndef IO_REPARSE_TAG_SYMLINK
-/* Old SDKs do not provide IO_REPARSE_TAG_SYMLINK */
-#define IO_REPARSE_TAG_SYMLINK 0xA000000CL
-#endif
-
-/*-
- * This is a new directory-walking system that addresses a number
- * of problems I've had with fts(3). In particular, it has no
- * pathname-length limits (other than the size of 'int'), handles
- * deep logical traversals, uses considerably less memory, and has
- * an opaque interface (easier to modify in the future).
- *
- * Internally, it keeps a single list of "tree_entry" items that
- * represent filesystem objects that require further attention.
- * Non-directories are not kept in memory: they are pulled from
- * readdir(), returned to the client, then freed as soon as possible.
- * Any directory entry to be traversed gets pushed onto the stack.
- *
- * There is surprisingly little information that needs to be kept for
- * each item on the stack. Just the name, depth (represented here as the
- * string length of the parent directory's pathname), and some markers
- * indicating how to get back to the parent (via chdir("..") for a
- * regular dir or via fchdir(2) for a symlink).
- */
-
-struct restore_time {
- const wchar_t *full_path;
- FILETIME lastWriteTime;
- FILETIME lastAccessTime;
- mode_t filetype;
-};
-
-struct tree_entry {
- int depth;
- struct tree_entry *next;
- struct tree_entry *parent;
- size_t full_path_dir_length;
- struct archive_wstring name;
- struct archive_wstring full_path;
- size_t dirname_length;
- int64_t dev;
- int64_t ino;
- int flags;
- int filesystem_id;
- /* How to restore time of a directory. */
- struct restore_time restore_time;
-};
-
-struct filesystem {
- int64_t dev;
- int synthetic;
- int remote;
- DWORD bytesPerSector;
-};
-
-/* Definitions for tree_entry.flags bitmap. */
-#define isDir 1 /* This entry is a regular directory. */
-#define isDirLink 2 /* This entry is a symbolic link to a directory. */
-#define needsFirstVisit 4 /* This is an initial entry. */
-#define needsDescent 8 /* This entry needs to be previsited. */
-#define needsOpen 16 /* This is a directory that needs to be opened. */
-#define needsAscent 32 /* This entry needs to be postvisited. */
-
-/*
- * On Windows, "first visit" is handled as a pattern to be handed to
- * _findfirst(). This is consistent with Windows conventions that
- * file patterns are handled within the application. On Posix,
- * "first visit" is just returned to the client.
- */
-
-#define MAX_OVERLAPPED 8
-#define READ_BUFFER_SIZE (1024 * 64) /* Default to 64KB per https://technet.microsoft.com/en-us/library/cc938632.aspx */
-#define DIRECT_IO 0/* Disabled */
-#define ASYNC_IO 1/* Enabled */
-
-/*
- * Local data for this package.
- */
-struct tree {
- struct tree_entry *stack;
- struct tree_entry *current;
- HANDLE d;
- WIN32_FIND_DATAW _findData;
- WIN32_FIND_DATAW *findData;
- int flags;
- int visit_type;
- /* Error code from last failed operation. */
- int tree_errno;
-
- /* A full path with "\\?\" prefix. */
- struct archive_wstring full_path;
- size_t full_path_dir_length;
- /* Dynamically-sized buffer for holding path */
- struct archive_wstring path;
-
- /* Last path element */
- const wchar_t *basename;
- /* Leading dir length */
- size_t dirname_length;
-
- int depth;
-
- BY_HANDLE_FILE_INFORMATION lst;
- BY_HANDLE_FILE_INFORMATION st;
- int descend;
- /* How to restore time of a file. */
- struct restore_time restore_time;
-
- struct entry_sparse {
- int64_t length;
- int64_t offset;
- } *sparse_list, *current_sparse;
- int sparse_count;
- int sparse_list_size;
-
- char initial_symlink_mode;
- char symlink_mode;
- struct filesystem *current_filesystem;
- struct filesystem *filesystem_table;
- int initial_filesystem_id;
- int current_filesystem_id;
- int max_filesystem_id;
- int allocated_filesystem;
-
- HANDLE entry_fh;
- int entry_eof;
- int64_t entry_remaining_bytes;
- int64_t entry_total;
-
- int ol_idx_doing;
- int ol_idx_done;
- int ol_num_doing;
- int ol_num_done;
- int64_t ol_remaining_bytes;
- int64_t ol_total;
- struct la_overlapped {
- OVERLAPPED ol;
- struct archive * _a;
- unsigned char *buff;
- size_t buff_size;
- int64_t offset;
- size_t bytes_expected;
- size_t bytes_transferred;
- } ol[MAX_OVERLAPPED];
- int direct_io;
- int async_io;
-};
-
-#define bhfi_dev(bhfi) ((bhfi)->dwVolumeSerialNumber)
-/* Treat FileIndex as i-node. We should remove a sequence number
- * which is high-16-bits of nFileIndexHigh. */
-#define bhfi_ino(bhfi) \
- ((((int64_t)((bhfi)->nFileIndexHigh & 0x0000FFFFUL)) << 32) \
- + (bhfi)->nFileIndexLow)
-
-/* Definitions for tree.flags bitmap. */
-#define hasStat 16 /* The st entry is valid. */
-#define hasLstat 32 /* The lst entry is valid. */
-#define needsRestoreTimes 128
-
-static int
-tree_dir_next_windows(struct tree *t, const wchar_t *pattern);
-
-/* Initiate/terminate a tree traversal. */
-static struct tree *tree_open(const wchar_t *, int, int);
-static struct tree *tree_reopen(struct tree *, const wchar_t *, int);
-static void tree_close(struct tree *);
-static void tree_free(struct tree *);
-static void tree_push(struct tree *, const wchar_t *, const wchar_t *,
- int, int64_t, int64_t, struct restore_time *);
-
-/*
- * tree_next() returns Zero if there is no next entry, non-zero if
- * there is. Note that directories are visited three times.
- * Directories are always visited first as part of enumerating their
- * parent; that is a "regular" visit. If tree_descend() is invoked at
- * that time, the directory is added to a work list and will
- * subsequently be visited two more times: once just after descending
- * into the directory ("postdescent") and again just after ascending
- * back to the parent ("postascent").
- *
- * TREE_ERROR_DIR is returned if the descent failed (because the
- * directory couldn't be opened, for instance). This is returned
- * instead of TREE_POSTDESCENT/TREE_POSTASCENT. TREE_ERROR_DIR is not a
- * fatal error, but it does imply that the relevant subtree won't be
- * visited. TREE_ERROR_FATAL is returned for an error that left the
- * traversal completely hosed. Right now, this is only returned for
- * chdir() failures during ascent.
- */
-#define TREE_REGULAR 1
-#define TREE_POSTDESCENT 2
-#define TREE_POSTASCENT 3
-#define TREE_ERROR_DIR -1
-#define TREE_ERROR_FATAL -2
-
-static int tree_next(struct tree *);
-
-/*
- * Return information about the current entry.
- */
-
-/*
- * The current full pathname, length of the full pathname, and a name
- * that can be used to access the file. Because tree does use chdir
- * extensively, the access path is almost never the same as the full
- * current path.
- *
- */
-static const wchar_t *tree_current_path(struct tree *);
-static const wchar_t *tree_current_access_path(struct tree *);
-
-/*
- * Request the lstat() or stat() data for the current path. Since the
- * tree package needs to do some of this anyway, and caches the
- * results, you should take advantage of it here if you need it rather
- * than make a redundant stat() or lstat() call of your own.
- */
-static const BY_HANDLE_FILE_INFORMATION *tree_current_stat(struct tree *);
-static const BY_HANDLE_FILE_INFORMATION *tree_current_lstat(struct tree *);
-
-/* The following functions use tricks to avoid a certain number of
- * stat()/lstat() calls. */
-/* "is_physical_dir" is equivalent to S_ISDIR(tree_current_lstat()->st_mode) */
-static int tree_current_is_physical_dir(struct tree *);
-/* "is_physical_link" is equivalent to S_ISLNK(tree_current_lstat()->st_mode) */
-static int tree_current_is_physical_link(struct tree *);
-/* Instead of archive_entry_copy_stat for BY_HANDLE_FILE_INFORMATION */
-static void tree_archive_entry_copy_bhfi(struct archive_entry *,
- struct tree *, const BY_HANDLE_FILE_INFORMATION *);
-/* "is_dir" is equivalent to S_ISDIR(tree_current_stat()->st_mode) */
-static int tree_current_is_dir(struct tree *);
-static int update_current_filesystem(struct archive_read_disk *a,
- int64_t dev);
-static int setup_current_filesystem(struct archive_read_disk *);
-static int tree_target_is_same_as_parent(struct tree *,
- const BY_HANDLE_FILE_INFORMATION *);
-
-static int _archive_read_disk_open_w(struct archive *, const wchar_t *);
-static int _archive_read_free(struct archive *);
-static int _archive_read_close(struct archive *);
-static int _archive_read_data_block(struct archive *,
- const void **, size_t *, int64_t *);
-static int _archive_read_next_header(struct archive *,
- struct archive_entry **);
-static int _archive_read_next_header2(struct archive *,
- struct archive_entry *);
-static const char *trivial_lookup_gname(void *, int64_t gid);
-static const char *trivial_lookup_uname(void *, int64_t uid);
-static int setup_sparse(struct archive_read_disk *, struct archive_entry *);
-static int close_and_restore_time(HANDLE, struct tree *,
- struct restore_time *);
-static int setup_sparse_from_disk(struct archive_read_disk *,
- struct archive_entry *, HANDLE);
-static int la_linkname_from_handle(HANDLE, wchar_t **, int *);
-static int la_linkname_from_pathw(const wchar_t *, wchar_t **, int *);
-static void entry_symlink_from_pathw(struct archive_entry *,
- const wchar_t *path);
-
-typedef struct _REPARSE_DATA_BUFFER {
- ULONG ReparseTag;
- USHORT ReparseDataLength;
- USHORT Reserved;
- union {
- struct {
- USHORT SubstituteNameOffset;
- USHORT SubstituteNameLength;
- USHORT PrintNameOffset;
- USHORT PrintNameLength;
- ULONG Flags;
- WCHAR PathBuffer[1];
- } SymbolicLinkReparseBuffer;
- struct {
- USHORT SubstituteNameOffset;
- USHORT SubstituteNameLength;
- USHORT PrintNameOffset;
- USHORT PrintNameLength;
- WCHAR PathBuffer[1];
- } MountPointReparseBuffer;
- struct {
- UCHAR DataBuffer[1];
- } GenericReparseBuffer;
- } DUMMYUNIONNAME;
-} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
-
-/*
- * Reads the target of a symbolic link
- *
- * Returns 0 on success and -1 on failure
- * outbuf is allocated in the function
- */
-static int
-la_linkname_from_handle(HANDLE h, wchar_t **linkname, int *linktype)
-{
- DWORD inbytes;
- REPARSE_DATA_BUFFER *buf;
- BY_HANDLE_FILE_INFORMATION st;
- size_t len;
- BOOL ret;
- BYTE *indata;
- wchar_t *tbuf;
-
- ret = GetFileInformationByHandle(h, &st);
- if (ret == 0 ||
- (st.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0) {
- return (-1);
- }
-
- indata = malloc(MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
- ret = DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, NULL, 0, indata,
- 1024, &inbytes, NULL);
- if (ret == 0) {
- la_dosmaperr(GetLastError());
- free(indata);
- return (-1);
- }
-
- buf = (REPARSE_DATA_BUFFER *) indata;
- if (buf->ReparseTag != IO_REPARSE_TAG_SYMLINK) {
- free(indata);
- /* File is not a symbolic link */
- errno = EINVAL;
- return (-1);
- }
-
- len = buf->SymbolicLinkReparseBuffer.SubstituteNameLength;
- if (len <= 0) {
- free(indata);
- return (-1);
- }
-
- tbuf = malloc(len + 1 * sizeof(wchar_t));
- if (tbuf == NULL) {
- free(indata);
- return (-1);
- }
-
- memcpy(tbuf, &((BYTE *)buf->SymbolicLinkReparseBuffer.PathBuffer)
- [buf->SymbolicLinkReparseBuffer.SubstituteNameOffset], len);
- free(indata);
-
- tbuf[len / sizeof(wchar_t)] = L'\0';
-
- *linkname = tbuf;
-
- /*
- * Translate backslashes to slashes for libarchive internal use
- */
- while(*tbuf != L'\0') {
- if (*tbuf == L'\\')
- *tbuf = L'/';
- tbuf++;
- }
-
- if ((st.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
- *linktype = AE_SYMLINK_TYPE_FILE;
- else
- *linktype = AE_SYMLINK_TYPE_DIRECTORY;
-
- return (0);
-}
-
-/*
- * Returns AE_SYMLINK_TYPE_FILE, AE_SYMLINK_TYPE_DIRECTORY or -1 on error
- */
-static int
-la_linkname_from_pathw(const wchar_t *path, wchar_t **outbuf, int *linktype)
-{
- HANDLE h;
- const DWORD flag = FILE_FLAG_BACKUP_SEMANTICS |
- FILE_FLAG_OPEN_REPARSE_POINT;
- int ret;
-
-# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- CREATEFILE2_EXTENDED_PARAMETERS createExParams;
- ZeroMemory(&createExParams, sizeof(createExParams));
- createExParams.dwSize = sizeof(createExParams);
- createExParams.dwFileFlags = flag;
- h = CreateFile2(path, 0,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- OPEN_EXISTING, &createExParams);
-#else
- h = CreateFileW(path, 0,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
- OPEN_EXISTING, flag, NULL);
-#endif
- if (h == INVALID_HANDLE_VALUE) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
-
- ret = la_linkname_from_handle(h, outbuf, linktype);
- CloseHandle(h);
-
- return (ret);
-}
-
-static void
-entry_symlink_from_pathw(struct archive_entry *entry, const wchar_t *path)
-{
- wchar_t *linkname = NULL;
- int ret, linktype;
-
- ret = la_linkname_from_pathw(path, &linkname, &linktype);
- if (ret != 0)
- return;
- if (linktype >= 0) {
- archive_entry_copy_symlink_w(entry, linkname);
- archive_entry_set_symlink_type(entry, linktype);
- }
- free(linkname);
-
- return;
-}
-
-static const struct archive_vtable
-archive_read_disk_vtable = {
- .archive_free = _archive_read_free,
- .archive_close = _archive_read_close,
- .archive_read_data_block = _archive_read_data_block,
- .archive_read_next_header = _archive_read_next_header,
- .archive_read_next_header2 = _archive_read_next_header2,
-};
-
-const char *
-archive_read_disk_gname(struct archive *_a, la_int64_t gid)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_disk_gname"))
- return (NULL);
- if (a->lookup_gname == NULL)
- return (NULL);
- return ((*a->lookup_gname)(a->lookup_gname_data, gid));
-}
-
-const char *
-archive_read_disk_uname(struct archive *_a, la_int64_t uid)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_disk_uname"))
- return (NULL);
- if (a->lookup_uname == NULL)
- return (NULL);
- return ((*a->lookup_uname)(a->lookup_uname_data, uid));
-}
-
-int
-archive_read_disk_set_gname_lookup(struct archive *_a,
- void *private_data,
- const char * (*lookup_gname)(void *private, la_int64_t gid),
- void (*cleanup_gname)(void *private))
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_disk_set_gname_lookup");
-
- if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
- (a->cleanup_gname)(a->lookup_gname_data);
-
- a->lookup_gname = lookup_gname;
- a->cleanup_gname = cleanup_gname;
- a->lookup_gname_data = private_data;
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_disk_set_uname_lookup(struct archive *_a,
- void *private_data,
- const char * (*lookup_uname)(void *private, int64_t uid),
- void (*cleanup_uname)(void *private))
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_disk_set_uname_lookup");
-
- if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
- (a->cleanup_uname)(a->lookup_uname_data);
-
- a->lookup_uname = lookup_uname;
- a->cleanup_uname = cleanup_uname;
- a->lookup_uname_data = private_data;
- return (ARCHIVE_OK);
-}
-
-/*
- * Create a new archive_read_disk object and initialize it with global state.
- */
-struct archive *
-archive_read_disk_new(void)
-{
- struct archive_read_disk *a;
-
- a = (struct archive_read_disk *)calloc(1, sizeof(*a));
- if (a == NULL)
- return (NULL);
- a->archive.magic = ARCHIVE_READ_DISK_MAGIC;
- a->archive.state = ARCHIVE_STATE_NEW;
- a->archive.vtable = &archive_read_disk_vtable;
- a->entry = archive_entry_new2(&a->archive);
- a->lookup_uname = trivial_lookup_uname;
- a->lookup_gname = trivial_lookup_gname;
- a->flags = ARCHIVE_READDISK_MAC_COPYFILE;
- return (&a->archive);
-}
-
-static int
-_archive_read_free(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- int r;
-
- if (_a == NULL)
- return (ARCHIVE_OK);
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free");
-
- if (a->archive.state != ARCHIVE_STATE_CLOSED)
- r = _archive_read_close(&a->archive);
- else
- r = ARCHIVE_OK;
-
- tree_free(a->tree);
- if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
- (a->cleanup_gname)(a->lookup_gname_data);
- if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
- (a->cleanup_uname)(a->lookup_uname_data);
- archive_string_free(&a->archive.error_string);
- archive_entry_free(a->entry);
- a->archive.magic = 0;
- free(a);
- return (r);
-}
-
-static int
-_archive_read_close(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close");
-
- if (a->archive.state != ARCHIVE_STATE_FATAL)
- a->archive.state = ARCHIVE_STATE_CLOSED;
-
- tree_close(a->tree);
-
- return (ARCHIVE_OK);
-}
-
-static void
-setup_symlink_mode(struct archive_read_disk *a, char symlink_mode,
- int follow_symlinks)
-{
- a->symlink_mode = symlink_mode;
- a->follow_symlinks = follow_symlinks;
- if (a->tree != NULL) {
- a->tree->initial_symlink_mode = a->symlink_mode;
- a->tree->symlink_mode = a->symlink_mode;
- }
-}
-
-int
-archive_read_disk_set_symlink_logical(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_logical");
- setup_symlink_mode(a, 'L', 1);
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_disk_set_symlink_physical(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_physical");
- setup_symlink_mode(a, 'P', 0);
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_disk_set_symlink_hybrid(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_hybrid");
- setup_symlink_mode(a, 'H', 1);/* Follow symlinks initially. */
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_disk_set_atime_restored(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_disk_restore_atime");
- a->flags |= ARCHIVE_READDISK_RESTORE_ATIME;
- if (a->tree != NULL)
- a->tree->flags |= needsRestoreTimes;
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_disk_set_behavior(struct archive *_a, int flags)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- int r = ARCHIVE_OK;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_disk_honor_nodump");
-
- a->flags = flags;
-
- if (flags & ARCHIVE_READDISK_RESTORE_ATIME)
- r = archive_read_disk_set_atime_restored(_a);
- else {
- if (a->tree != NULL)
- a->tree->flags &= ~needsRestoreTimes;
- }
- return (r);
-}
-
-/*
- * Trivial implementations of gname/uname lookup functions.
- * These are normally overridden by the client, but these stub
- * versions ensure that we always have something that works.
- */
-static const char *
-trivial_lookup_gname(void *private_data, int64_t gid)
-{
- (void)private_data; /* UNUSED */
- (void)gid; /* UNUSED */
- return (NULL);
-}
-
-static const char *
-trivial_lookup_uname(void *private_data, int64_t uid)
-{
- (void)private_data; /* UNUSED */
- (void)uid; /* UNUSED */
- return (NULL);
-}
-
-static int64_t
-align_num_per_sector(struct tree *t, int64_t size)
-{
- int64_t surplus;
-
- size += t->current_filesystem->bytesPerSector -1;
- surplus = size % t->current_filesystem->bytesPerSector;
- size -= surplus;
- return (size);
-}
-
-static int
-start_next_async_read(struct archive_read_disk *a, struct tree *t)
-{
- struct la_overlapped *olp;
- DWORD buffbytes, rbytes;
-
- if (t->ol_remaining_bytes == 0)
- return (ARCHIVE_EOF);
-
- olp = &(t->ol[t->ol_idx_doing]);
- t->ol_idx_doing = (t->ol_idx_doing + 1) % MAX_OVERLAPPED;
-
- /* Allocate read buffer. */
- if (olp->buff == NULL) {
- void *p;
- size_t s = (size_t)align_num_per_sector(t, READ_BUFFER_SIZE);
- p = VirtualAlloc(NULL, s, MEM_COMMIT, PAGE_READWRITE);
- if (p == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Couldn't allocate memory");
- a->archive.state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- }
- olp->buff = p;
- olp->buff_size = s;
- olp->_a = &a->archive;
- olp->ol.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
- if (olp->ol.hEvent == NULL) {
- la_dosmaperr(GetLastError());
- archive_set_error(&a->archive, errno,
- "CreateEvent failed");
- a->archive.state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- }
- } else
- ResetEvent(olp->ol.hEvent);
-
- buffbytes = (DWORD)olp->buff_size;
- if (buffbytes > t->current_sparse->length)
- buffbytes = (DWORD)t->current_sparse->length;
-
- /* Skip hole. */
- if (t->current_sparse->offset > t->ol_total) {
- t->ol_remaining_bytes -=
- t->current_sparse->offset - t->ol_total;
- }
-
- olp->offset = t->current_sparse->offset;
- olp->ol.Offset = (DWORD)(olp->offset & 0xffffffff);
- olp->ol.OffsetHigh = (DWORD)(olp->offset >> 32);
-
- if (t->ol_remaining_bytes > buffbytes) {
- olp->bytes_expected = buffbytes;
- t->ol_remaining_bytes -= buffbytes;
- } else {
- olp->bytes_expected = (size_t)t->ol_remaining_bytes;
- t->ol_remaining_bytes = 0;
- }
- olp->bytes_transferred = 0;
- t->current_sparse->offset += buffbytes;
- t->current_sparse->length -= buffbytes;
- t->ol_total = t->current_sparse->offset;
- if (t->current_sparse->length == 0 && t->ol_remaining_bytes > 0)
- t->current_sparse++;
-
- if (!ReadFile(t->entry_fh, olp->buff, buffbytes, &rbytes, &(olp->ol))) {
- DWORD lasterr;
-
- lasterr = GetLastError();
- if (lasterr == ERROR_HANDLE_EOF) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Reading file truncated");
- a->archive.state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- } else if (lasterr != ERROR_IO_PENDING) {
- if (lasterr == ERROR_NO_DATA)
- errno = EAGAIN;
- else if (lasterr == ERROR_ACCESS_DENIED)
- errno = EBADF;
- else
- la_dosmaperr(lasterr);
- archive_set_error(&a->archive, errno, "Read error");
- a->archive.state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- }
- } else
- olp->bytes_transferred = rbytes;
- t->ol_num_doing++;
-
- return (t->ol_remaining_bytes == 0)? ARCHIVE_EOF: ARCHIVE_OK;
-}
-
-static void
-cancel_async(struct tree *t)
-{
- if (t->ol_num_doing != t->ol_num_done) {
- CancelIo(t->entry_fh);
- t->ol_num_doing = t->ol_num_done = 0;
- }
-}
-
-static int
-_archive_read_data_block(struct archive *_a, const void **buff,
- size_t *size, int64_t *offset)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- struct tree *t = a->tree;
- struct la_overlapped *olp;
- DWORD bytes_transferred;
- int r = ARCHIVE_FATAL;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
- "archive_read_data_block");
-
- if (t->entry_eof || t->entry_remaining_bytes <= 0) {
- r = ARCHIVE_EOF;
- goto abort_read_data;
- }
-
- /*
- * Make a request to read the file in asynchronous.
- */
- if (t->ol_num_doing == 0) {
- do {
- r = start_next_async_read(a, t);
- if (r == ARCHIVE_FATAL)
- goto abort_read_data;
- if (!t->async_io)
- break;
- } while (r == ARCHIVE_OK && t->ol_num_doing < MAX_OVERLAPPED);
- } else {
- if ((r = start_next_async_read(a, t)) == ARCHIVE_FATAL)
- goto abort_read_data;
- }
-
- olp = &(t->ol[t->ol_idx_done]);
- t->ol_idx_done = (t->ol_idx_done + 1) % MAX_OVERLAPPED;
- if (olp->bytes_transferred)
- bytes_transferred = (DWORD)olp->bytes_transferred;
- else if (!GetOverlappedResult(t->entry_fh, &(olp->ol),
- &bytes_transferred, TRUE)) {
- la_dosmaperr(GetLastError());
- archive_set_error(&a->archive, errno,
- "GetOverlappedResult failed");
- a->archive.state = ARCHIVE_STATE_FATAL;
- r = ARCHIVE_FATAL;
- goto abort_read_data;
- }
- t->ol_num_done++;
-
- if (bytes_transferred == 0 ||
- olp->bytes_expected != bytes_transferred) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Reading file truncated");
- a->archive.state = ARCHIVE_STATE_FATAL;
- r = ARCHIVE_FATAL;
- goto abort_read_data;
- }
-
- *buff = olp->buff;
- *size = bytes_transferred;
- *offset = olp->offset;
- if (olp->offset > t->entry_total)
- t->entry_remaining_bytes -= olp->offset - t->entry_total;
- t->entry_total = olp->offset + *size;
- t->entry_remaining_bytes -= *size;
- if (t->entry_remaining_bytes == 0) {
- /* Close the current file descriptor */
- close_and_restore_time(t->entry_fh, t, &t->restore_time);
- t->entry_fh = INVALID_HANDLE_VALUE;
- t->entry_eof = 1;
- }
- return (ARCHIVE_OK);
-
-abort_read_data:
- *buff = NULL;
- *size = 0;
- *offset = t->entry_total;
- if (t->entry_fh != INVALID_HANDLE_VALUE) {
- cancel_async(t);
- /* Close the current file descriptor */
- close_and_restore_time(t->entry_fh, t, &t->restore_time);
- t->entry_fh = INVALID_HANDLE_VALUE;
- }
- return (r);
-}
-
-static int
-next_entry(struct archive_read_disk *a, struct tree *t,
- struct archive_entry *entry)
-{
- const BY_HANDLE_FILE_INFORMATION *st;
- const BY_HANDLE_FILE_INFORMATION *lst;
- const char*name;
- int descend, r;
-
- st = NULL;
- lst = NULL;
- t->descend = 0;
- do {
- switch (tree_next(t)) {
- case TREE_ERROR_FATAL:
- archive_set_error(&a->archive, t->tree_errno,
- "%ls: Unable to continue traversing directory tree",
- tree_current_path(t));
- a->archive.state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- case TREE_ERROR_DIR:
- archive_set_error(&a->archive, t->tree_errno,
- "%ls: Couldn't visit directory",
- tree_current_path(t));
- return (ARCHIVE_FAILED);
- case 0:
- return (ARCHIVE_EOF);
- case TREE_POSTDESCENT:
- case TREE_POSTASCENT:
- break;
- case TREE_REGULAR:
- lst = tree_current_lstat(t);
- if (lst == NULL) {
- archive_set_error(&a->archive, t->tree_errno,
- "%ls: Cannot stat",
- tree_current_path(t));
- return (ARCHIVE_FAILED);
- }
- break;
- }
- } while (lst == NULL);
-
- archive_entry_copy_pathname_w(entry, tree_current_path(t));
-
- /*
- * Perform path matching.
- */
- if (a->matching) {
- r = archive_match_path_excluded(a->matching, entry);
- if (r < 0) {
- archive_set_error(&(a->archive), errno,
- "Failed : %s", archive_error_string(a->matching));
- return (r);
- }
- if (r) {
- if (a->excluded_cb_func)
- a->excluded_cb_func(&(a->archive),
- a->excluded_cb_data, entry);
- return (ARCHIVE_RETRY);
- }
- }
-
- /*
- * Distinguish 'L'/'P'/'H' symlink following.
- */
- switch(t->symlink_mode) {
- case 'H':
- /* 'H': After the first item, rest like 'P'. */
- t->symlink_mode = 'P';
- /* 'H': First item (from command line) like 'L'. */
- /* FALLTHROUGH */
- case 'L':
- /* 'L': Do descend through a symlink to dir. */
- descend = tree_current_is_dir(t);
- /* 'L': Follow symlinks to files. */
- a->symlink_mode = 'L';
- a->follow_symlinks = 1;
- /* 'L': Archive symlinks as targets, if we can. */
- st = tree_current_stat(t);
- if (st != NULL && !tree_target_is_same_as_parent(t, st))
- break;
- /* If stat fails, we have a broken symlink;
- * in that case, don't follow the link. */
- /* FALLTHROUGH */
- default:
- /* 'P': Don't descend through a symlink to dir. */
- descend = tree_current_is_physical_dir(t);
- /* 'P': Don't follow symlinks to files. */
- a->symlink_mode = 'P';
- a->follow_symlinks = 0;
- /* 'P': Archive symlinks as symlinks. */
- st = lst;
- break;
- }
-
- if (update_current_filesystem(a, bhfi_dev(st)) != ARCHIVE_OK) {
- a->archive.state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- }
- if (t->initial_filesystem_id == -1)
- t->initial_filesystem_id = t->current_filesystem_id;
- if (a->flags & ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS) {
- if (t->initial_filesystem_id != t->current_filesystem_id)
- return (ARCHIVE_RETRY);
- }
- t->descend = descend;
-
- tree_archive_entry_copy_bhfi(entry, t, st);
-
- /* Save the times to be restored. This must be in before
- * calling archive_read_disk_descend() or any chance of it,
- * especially, invoking a callback. */
- t->restore_time.lastWriteTime = st->ftLastWriteTime;
- t->restore_time.lastAccessTime = st->ftLastAccessTime;
- t->restore_time.filetype = archive_entry_filetype(entry);
-
- /*
- * Perform time matching.
- */
- if (a->matching) {
- r = archive_match_time_excluded(a->matching, entry);
- if (r < 0) {
- archive_set_error(&(a->archive), errno,
- "Failed : %s", archive_error_string(a->matching));
- return (r);
- }
- if (r) {
- if (a->excluded_cb_func)
- a->excluded_cb_func(&(a->archive),
- a->excluded_cb_data, entry);
- return (ARCHIVE_RETRY);
- }
- }
-
- /* Lookup uname/gname */
- name = archive_read_disk_uname(&(a->archive), archive_entry_uid(entry));
- if (name != NULL)
- archive_entry_copy_uname(entry, name);
- name = archive_read_disk_gname(&(a->archive), archive_entry_gid(entry));
- if (name != NULL)
- archive_entry_copy_gname(entry, name);
-
- /*
- * Perform owner matching.
- */
- if (a->matching) {
- r = archive_match_owner_excluded(a->matching, entry);
- if (r < 0) {
- archive_set_error(&(a->archive), errno,
- "Failed : %s", archive_error_string(a->matching));
- return (r);
- }
- if (r) {
- if (a->excluded_cb_func)
- a->excluded_cb_func(&(a->archive),
- a->excluded_cb_data, entry);
- return (ARCHIVE_RETRY);
- }
- }
-
- /*
- * File attributes
- */
- if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0) {
- const int supported_attrs =
- FILE_ATTRIBUTE_READONLY |
- FILE_ATTRIBUTE_HIDDEN |
- FILE_ATTRIBUTE_SYSTEM;
- DWORD file_attrs = st->dwFileAttributes & supported_attrs;
- if (file_attrs != 0)
- archive_entry_set_fflags(entry, file_attrs, 0);
- }
-
- /*
- * Invoke a meta data filter callback.
- */
- if (a->metadata_filter_func) {
- if (!a->metadata_filter_func(&(a->archive),
- a->metadata_filter_data, entry))
- return (ARCHIVE_RETRY);
- }
-
- archive_entry_copy_sourcepath_w(entry, tree_current_access_path(t));
-
- r = ARCHIVE_OK;
- if (archive_entry_filetype(entry) == AE_IFREG &&
- archive_entry_size(entry) > 0) {
- DWORD flags = FILE_FLAG_BACKUP_SEMANTICS;
-#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- CREATEFILE2_EXTENDED_PARAMETERS createExParams;
-#endif
- if (t->async_io)
- flags |= FILE_FLAG_OVERLAPPED;
- if (t->direct_io)
- flags |= FILE_FLAG_NO_BUFFERING;
- else
- flags |= FILE_FLAG_SEQUENTIAL_SCAN;
-#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- ZeroMemory(&createExParams, sizeof(createExParams));
- createExParams.dwSize = sizeof(createExParams);
- createExParams.dwFileFlags = flags;
- t->entry_fh = CreateFile2(tree_current_access_path(t),
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- OPEN_EXISTING, &createExParams);
-#else
- t->entry_fh = CreateFileW(tree_current_access_path(t),
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL, OPEN_EXISTING, flags, NULL);
-#endif
- if (t->entry_fh == INVALID_HANDLE_VALUE) {
- la_dosmaperr(GetLastError());
- archive_set_error(&a->archive, errno,
- "Couldn't open %ls", tree_current_path(a->tree));
- return (ARCHIVE_FAILED);
- }
-
- /* Find sparse data from the disk. */
- if ((a->flags & ARCHIVE_READDISK_NO_SPARSE) == 0) {
- if (archive_entry_hardlink(entry) == NULL &&
- (st->dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) != 0)
- r = setup_sparse_from_disk(a, entry, t->entry_fh);
- }
- }
- return (r);
-}
-
-static int
-_archive_read_next_header(struct archive *_a, struct archive_entry **entryp)
-{
- int ret;
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- *entryp = NULL;
- ret = _archive_read_next_header2(_a, a->entry);
- *entryp = a->entry;
- return ret;
-}
-
-static int
-_archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- struct tree *t;
- int r;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
- "archive_read_next_header2");
-
- t = a->tree;
- if (t->entry_fh != INVALID_HANDLE_VALUE) {
- cancel_async(t);
- close_and_restore_time(t->entry_fh, t, &t->restore_time);
- t->entry_fh = INVALID_HANDLE_VALUE;
- }
-
- archive_entry_clear(entry);
-
- while ((r = next_entry(a, t, entry)) == ARCHIVE_RETRY)
- archive_entry_clear(entry);
-
- /*
- * EOF and FATAL are persistent at this layer. By
- * modifying the state, we guarantee that future calls to
- * read a header or read data will fail.
- */
- switch (r) {
- case ARCHIVE_EOF:
- a->archive.state = ARCHIVE_STATE_EOF;
- break;
- case ARCHIVE_OK:
- case ARCHIVE_WARN:
- t->entry_total = 0;
- if (archive_entry_filetype(entry) == AE_IFREG) {
- t->entry_remaining_bytes = archive_entry_size(entry);
- t->entry_eof = (t->entry_remaining_bytes == 0)? 1: 0;
- if (!t->entry_eof &&
- setup_sparse(a, entry) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- } else {
- t->entry_remaining_bytes = 0;
- t->entry_eof = 1;
- }
- t->ol_idx_doing = t->ol_idx_done = 0;
- t->ol_num_doing = t->ol_num_done = 0;
- t->ol_remaining_bytes = t->entry_remaining_bytes;
- t->ol_total = 0;
- a->archive.state = ARCHIVE_STATE_DATA;
- break;
- case ARCHIVE_RETRY:
- break;
- case ARCHIVE_FATAL:
- a->archive.state = ARCHIVE_STATE_FATAL;
- break;
- }
-
- __archive_reset_read_data(&a->archive);
- return (r);
-}
-
-static int
-setup_sparse(struct archive_read_disk *a, struct archive_entry *entry)
-{
- struct tree *t = a->tree;
- int64_t aligned, length, offset;
- int i;
-
- t->sparse_count = archive_entry_sparse_reset(entry);
- if (t->sparse_count+1 > t->sparse_list_size) {
- free(t->sparse_list);
- t->sparse_list_size = t->sparse_count + 1;
- t->sparse_list = malloc(sizeof(t->sparse_list[0]) *
- t->sparse_list_size);
- if (t->sparse_list == NULL) {
- t->sparse_list_size = 0;
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate data");
- a->archive.state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- }
- }
- /*
- * Get sparse list and make sure those offsets and lengths are
- * aligned by a sector size.
- */
- for (i = 0; i < t->sparse_count; i++) {
- archive_entry_sparse_next(entry, &offset, &length);
- aligned = align_num_per_sector(t, offset);
- if (aligned != offset) {
- aligned -= t->current_filesystem->bytesPerSector;
- length += offset - aligned;
- }
- t->sparse_list[i].offset = aligned;
- aligned = align_num_per_sector(t, length);
- t->sparse_list[i].length = aligned;
- }
-
- aligned = align_num_per_sector(t, archive_entry_size(entry));
- if (i == 0) {
- t->sparse_list[i].offset = 0;
- t->sparse_list[i].length = aligned;
- } else {
- int j, last = i;
-
- t->sparse_list[i].offset = aligned;
- t->sparse_list[i].length = 0;
- for (i = 0; i < last; i++) {
- if ((t->sparse_list[i].offset +
- t->sparse_list[i].length) <=
- t->sparse_list[i+1].offset)
- continue;
- /*
- * Now sparse_list[i+1] is overlapped by sparse_list[i].
- * Merge those two.
- */
- length = t->sparse_list[i+1].offset -
- t->sparse_list[i].offset;
- t->sparse_list[i+1].offset = t->sparse_list[i].offset;
- t->sparse_list[i+1].length += length;
- /* Remove sparse_list[i]. */
- for (j = i; j < last; j++) {
- t->sparse_list[j].offset =
- t->sparse_list[j+1].offset;
- t->sparse_list[j].length =
- t->sparse_list[j+1].length;
- }
- last--;
- }
- }
- t->current_sparse = t->sparse_list;
-
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_disk_set_matching(struct archive *_a, struct archive *_ma,
- void (*_excluded_func)(struct archive *, void *, struct archive_entry *),
- void *_client_data)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_disk_set_matching");
- a->matching = _ma;
- a->excluded_cb_func = _excluded_func;
- a->excluded_cb_data = _client_data;
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_disk_set_metadata_filter_callback(struct archive *_a,
- int (*_metadata_filter_func)(struct archive *, void *,
- struct archive_entry *), void *_client_data)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_ANY,
- "archive_read_disk_set_metadata_filter_callback");
-
- a->metadata_filter_func = _metadata_filter_func;
- a->metadata_filter_data = _client_data;
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_disk_can_descend(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- struct tree *t = a->tree;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
- "archive_read_disk_can_descend");
-
- return (t->visit_type == TREE_REGULAR && t->descend);
-}
-
-/*
- * Called by the client to mark the directory just returned from
- * tree_next() as needing to be visited.
- */
-int
-archive_read_disk_descend(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- struct tree *t = a->tree;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
- "archive_read_disk_descend");
-
- if (!archive_read_disk_can_descend(_a))
- return (ARCHIVE_OK);
-
- if (tree_current_is_physical_dir(t)) {
- tree_push(t, t->basename, t->full_path.s,
- t->current_filesystem_id,
- bhfi_dev(&(t->lst)), bhfi_ino(&(t->lst)),
- &t->restore_time);
- t->stack->flags |= isDir;
- } else if (tree_current_is_dir(t)) {
- tree_push(t, t->basename, t->full_path.s,
- t->current_filesystem_id,
- bhfi_dev(&(t->st)), bhfi_ino(&(t->st)),
- &t->restore_time);
- t->stack->flags |= isDirLink;
- }
- t->descend = 0;
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_disk_open(struct archive *_a, const char *pathname)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- struct archive_wstring wpath;
- int ret;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED,
- "archive_read_disk_open");
- archive_clear_error(&a->archive);
-
- /* Make a wchar_t string from a char string. */
- archive_string_init(&wpath);
- if (archive_wstring_append_from_mbs(&wpath, pathname,
- strlen(pathname)) != 0) {
- if (errno == ENOMEM)
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- else
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Can't convert a path to a wchar_t string");
- a->archive.state = ARCHIVE_STATE_FATAL;
- ret = ARCHIVE_FATAL;
- } else
- ret = _archive_read_disk_open_w(_a, wpath.s);
-
- archive_wstring_free(&wpath);
- return (ret);
-}
-
-int
-archive_read_disk_open_w(struct archive *_a, const wchar_t *pathname)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED,
- "archive_read_disk_open_w");
- archive_clear_error(&a->archive);
-
- return (_archive_read_disk_open_w(_a, pathname));
-}
-
-static int
-_archive_read_disk_open_w(struct archive *_a, const wchar_t *pathname)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
-
- if (a->tree != NULL)
- a->tree = tree_reopen(a->tree, pathname,
- a->flags & ARCHIVE_READDISK_RESTORE_ATIME);
- else
- a->tree = tree_open(pathname, a->symlink_mode,
- a->flags & ARCHIVE_READDISK_RESTORE_ATIME);
- if (a->tree == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate directory traversal data");
- a->archive.state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- }
- a->archive.state = ARCHIVE_STATE_HEADER;
-
- return (ARCHIVE_OK);
-}
-
-/*
- * Return a current filesystem ID which is index of the filesystem entry
- * you've visited through archive_read_disk.
- */
-int
-archive_read_disk_current_filesystem(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
- "archive_read_disk_current_filesystem");
-
- return (a->tree->current_filesystem_id);
-}
-
-static int
-update_current_filesystem(struct archive_read_disk *a, int64_t dev)
-{
- struct tree *t = a->tree;
- int i, fid;
-
- if (t->current_filesystem != NULL &&
- t->current_filesystem->dev == dev)
- return (ARCHIVE_OK);
-
- for (i = 0; i < t->max_filesystem_id; i++) {
- if (t->filesystem_table[i].dev == dev) {
- /* There is the filesystem ID we've already generated. */
- t->current_filesystem_id = i;
- t->current_filesystem = &(t->filesystem_table[i]);
- return (ARCHIVE_OK);
- }
- }
-
- /*
- * There is a new filesystem, we generate a new ID for.
- */
- fid = t->max_filesystem_id++;
- if (t->max_filesystem_id > t->allocated_filesystem) {
- size_t s;
- void *p;
-
- s = t->max_filesystem_id * 2;
- p = realloc(t->filesystem_table,
- s * sizeof(*t->filesystem_table));
- if (p == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate tar data");
- return (ARCHIVE_FATAL);
- }
- t->filesystem_table = (struct filesystem *)p;
- t->allocated_filesystem = (int)s;
- }
- t->current_filesystem_id = fid;
- t->current_filesystem = &(t->filesystem_table[fid]);
- t->current_filesystem->dev = dev;
-
- return (setup_current_filesystem(a));
-}
-
-/*
- * Returns 1 if current filesystem is generated filesystem, 0 if it is not
- * or -1 if it is unknown.
- */
-int
-archive_read_disk_current_filesystem_is_synthetic(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
- "archive_read_disk_current_filesystem");
-
- return (a->tree->current_filesystem->synthetic);
-}
-
-/*
- * Returns 1 if current filesystem is remote filesystem, 0 if it is not
- * or -1 if it is unknown.
- */
-int
-archive_read_disk_current_filesystem_is_remote(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
- "archive_read_disk_current_filesystem");
-
- return (a->tree->current_filesystem->remote);
-}
-
-/*
- * If symlink is broken, statfs or statvfs will fail.
- * Use its directory path instead.
- */
-static wchar_t *
-safe_path_for_statfs(struct tree *t)
-{
- const wchar_t *path;
- wchar_t *cp, *p = NULL;
-
- path = tree_current_access_path(t);
- if (tree_current_stat(t) == NULL) {
- p = _wcsdup(path);
- cp = wcsrchr(p, '/');
- if (cp != NULL && wcslen(cp) >= 2) {
- cp[1] = '.';
- cp[2] = '\0';
- path = p;
- }
- } else
- p = _wcsdup(path);
- return (p);
-}
-
-/*
- * Get conditions of synthetic and remote on Windows
- */
-static int
-setup_current_filesystem(struct archive_read_disk *a)
-{
- struct tree *t = a->tree;
- wchar_t vol[256];
- wchar_t *path;
-
- t->current_filesystem->synthetic = -1;/* Not supported */
- path = safe_path_for_statfs(t);
- if (!GetVolumePathNameW(path, vol, sizeof(vol)/sizeof(vol[0]))) {
- free(path);
- t->current_filesystem->remote = -1;
- t->current_filesystem->bytesPerSector = 0;
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "GetVolumePathName failed: %d", (int)GetLastError());
- return (ARCHIVE_FAILED);
- }
- free(path);
- switch (GetDriveTypeW(vol)) {
- case DRIVE_UNKNOWN:
- case DRIVE_NO_ROOT_DIR:
- t->current_filesystem->remote = -1;
- break;
- case DRIVE_REMOTE:
- t->current_filesystem->remote = 1;
- break;
- default:
- t->current_filesystem->remote = 0;
- break;
- }
-
- if (!GetDiskFreeSpaceW(vol, NULL,
- &(t->current_filesystem->bytesPerSector), NULL, NULL)) {
- t->current_filesystem->bytesPerSector = 0;
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "GetDiskFreeSpace failed: %d", (int)GetLastError());
- return (ARCHIVE_FAILED);
- }
-
- return (ARCHIVE_OK);
-}
-
-static int
-close_and_restore_time(HANDLE h, struct tree *t, struct restore_time *rt)
-{
- HANDLE handle;
- int r = 0;
-#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- CREATEFILE2_EXTENDED_PARAMETERS createExParams;
-#endif
-
- if (h == INVALID_HANDLE_VALUE && AE_IFLNK == rt->filetype)
- return (0);
-
- /* Close a file descriptor.
- * It will not be used for SetFileTime() because it has been opened
- * by a read only mode.
- */
- if (h != INVALID_HANDLE_VALUE)
- CloseHandle(h);
- if ((t->flags & needsRestoreTimes) == 0)
- return (r);
-
-#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- ZeroMemory(&createExParams, sizeof(createExParams));
- createExParams.dwSize = sizeof(createExParams);
- createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
- handle = CreateFile2(rt->full_path, FILE_WRITE_ATTRIBUTES,
- 0, OPEN_EXISTING, &createExParams);
-#else
- handle = CreateFileW(rt->full_path, FILE_WRITE_ATTRIBUTES,
- 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
-#endif
- if (handle == INVALID_HANDLE_VALUE) {
- errno = EINVAL;
- return (-1);
- }
-
- if (SetFileTime(handle, NULL, &rt->lastAccessTime,
- &rt->lastWriteTime) == 0) {
- errno = EINVAL;
- r = -1;
- } else
- r = 0;
- CloseHandle(handle);
- return (r);
-}
-
-/*
- * Add a directory path to the current stack.
- */
-static void
-tree_push(struct tree *t, const wchar_t *path, const wchar_t *full_path,
- int filesystem_id, int64_t dev, int64_t ino, struct restore_time *rt)
-{
- struct tree_entry *te;
-
- te = calloc(1, sizeof(*te));
- te->next = t->stack;
- te->parent = t->current;
- if (te->parent)
- te->depth = te->parent->depth + 1;
- t->stack = te;
- archive_string_init(&te->name);
- archive_wstrcpy(&te->name, path);
- archive_string_init(&te->full_path);
- archive_wstrcpy(&te->full_path, full_path);
- te->flags = needsDescent | needsOpen | needsAscent;
- te->filesystem_id = filesystem_id;
- te->dev = dev;
- te->ino = ino;
- te->dirname_length = t->dirname_length;
- te->full_path_dir_length = t->full_path_dir_length;
- te->restore_time.full_path = te->full_path.s;
- if (rt != NULL) {
- te->restore_time.lastWriteTime = rt->lastWriteTime;
- te->restore_time.lastAccessTime = rt->lastAccessTime;
- te->restore_time.filetype = rt->filetype;
- }
-}
-
-/*
- * Append a name to the current dir path.
- */
-static void
-tree_append(struct tree *t, const wchar_t *name, size_t name_length)
-{
- size_t size_needed;
-
- t->path.s[t->dirname_length] = L'\0';
- t->path.length = t->dirname_length;
- /* Strip trailing '/' from name, unless entire name is "/". */
- while (name_length > 1 && name[name_length - 1] == L'/')
- name_length--;
-
- /* Resize pathname buffer as needed. */
- size_needed = name_length + t->dirname_length + 2;
- archive_wstring_ensure(&t->path, size_needed);
- /* Add a separating '/' if it's needed. */
- if (t->dirname_length > 0 &&
- t->path.s[archive_strlen(&t->path)-1] != L'/')
- archive_wstrappend_wchar(&t->path, L'/');
- t->basename = t->path.s + archive_strlen(&t->path);
- archive_wstrncat(&t->path, name, name_length);
- t->restore_time.full_path = t->basename;
- if (t->full_path_dir_length > 0) {
- t->full_path.s[t->full_path_dir_length] = L'\0';
- t->full_path.length = t->full_path_dir_length;
- size_needed = name_length + t->full_path_dir_length + 2;
- archive_wstring_ensure(&t->full_path, size_needed);
- /* Add a separating '\' if it's needed. */
- if (t->full_path.s[archive_strlen(&t->full_path)-1] != L'\\')
- archive_wstrappend_wchar(&t->full_path, L'\\');
- archive_wstrncat(&t->full_path, name, name_length);
- t->restore_time.full_path = t->full_path.s;
- }
-}
-
-/*
- * Open a directory tree for traversal.
- */
-static struct tree *
-tree_open(const wchar_t *path, int symlink_mode, int restore_time)
-{
- struct tree *t;
-
- t = calloc(1, sizeof(*t));
- archive_string_init(&(t->full_path));
- archive_string_init(&t->path);
- archive_wstring_ensure(&t->path, 15);
- t->initial_symlink_mode = symlink_mode;
- return (tree_reopen(t, path, restore_time));
-}
-
-static struct tree *
-tree_reopen(struct tree *t, const wchar_t *path, int restore_time)
-{
- struct archive_wstring ws;
- wchar_t *pathname, *p, *base;
-
- t->flags = (restore_time != 0)?needsRestoreTimes:0;
- t->visit_type = 0;
- t->tree_errno = 0;
- t->full_path_dir_length = 0;
- t->dirname_length = 0;
- t->depth = 0;
- t->descend = 0;
- t->current = NULL;
- t->d = INVALID_HANDLE_VALUE;
- t->symlink_mode = t->initial_symlink_mode;
- archive_string_empty(&(t->full_path));
- archive_string_empty(&t->path);
- t->entry_fh = INVALID_HANDLE_VALUE;
- t->entry_eof = 0;
- t->entry_remaining_bytes = 0;
- t->initial_filesystem_id = -1;
-
- /* Get wchar_t strings from char strings. */
- archive_string_init(&ws);
- archive_wstrcpy(&ws, path);
- pathname = ws.s;
- /* Get a full-path-name. */
- p = __la_win_permissive_name_w(pathname);
- if (p == NULL)
- goto failed;
- archive_wstrcpy(&(t->full_path), p);
- free(p);
-
- /* Convert path separators from '\' to '/' */
- for (p = pathname; *p != L'\0'; ++p) {
- if (*p == L'\\')
- *p = L'/';
- }
- base = pathname;
-
- /* First item is set up a lot like a symlink traversal. */
- /* printf("Looking for wildcard in %s\n", path); */
- if ((base[0] == L'/' && base[1] == L'/' &&
- base[2] == L'?' && base[3] == L'/' &&
- (wcschr(base+4, L'*') || wcschr(base+4, L'?'))) ||
- (!(base[0] == L'/' && base[1] == L'/' &&
- base[2] == L'?' && base[3] == L'/') &&
- (wcschr(base, L'*') || wcschr(base, L'?')))) {
- // It has a wildcard in it...
- // Separate the last element.
- p = wcsrchr(base, L'/');
- if (p != NULL) {
- *p = L'\0';
- tree_append(t, base, p - base);
- t->dirname_length = archive_strlen(&t->path);
- base = p + 1;
- }
- p = wcsrchr(t->full_path.s, L'\\');
- if (p != NULL) {
- *p = L'\0';
- t->full_path.length = wcslen(t->full_path.s);
- t->full_path_dir_length = archive_strlen(&t->full_path);
- }
- }
- tree_push(t, base, t->full_path.s, 0, 0, 0, NULL);
- archive_wstring_free(&ws);
- t->stack->flags = needsFirstVisit;
- /*
- * Debug flag for Direct IO(No buffering) or Async IO.
- * Those dependent on environment variable switches
- * will be removed until next release.
- */
- {
- const char *e;
- if ((e = getenv("LIBARCHIVE_DIRECT_IO")) != NULL) {
- if (e[0] == '0')
- t->direct_io = 0;
- else
- t->direct_io = 1;
- fprintf(stderr, "LIBARCHIVE_DIRECT_IO=%s\n",
- (t->direct_io)?"Enabled":"Disabled");
- } else
- t->direct_io = DIRECT_IO;
- if ((e = getenv("LIBARCHIVE_ASYNC_IO")) != NULL) {
- if (e[0] == '0')
- t->async_io = 0;
- else
- t->async_io = 1;
- fprintf(stderr, "LIBARCHIVE_ASYNC_IO=%s\n",
- (t->async_io)?"Enabled":"Disabled");
- } else
- t->async_io = ASYNC_IO;
- }
- return (t);
-failed:
- archive_wstring_free(&ws);
- tree_free(t);
- return (NULL);
-}
-
-static int
-tree_descent(struct tree *t)
-{
- t->dirname_length = archive_strlen(&t->path);
- t->full_path_dir_length = archive_strlen(&t->full_path);
- t->depth++;
- return (0);
-}
-
-/*
- * We've finished a directory; ascend back to the parent.
- */
-static int
-tree_ascend(struct tree *t)
-{
- struct tree_entry *te;
-
- te = t->stack;
- t->depth--;
- close_and_restore_time(INVALID_HANDLE_VALUE, t, &te->restore_time);
- return (0);
-}
-
-/*
- * Pop the working stack.
- */
-static void
-tree_pop(struct tree *t)
-{
- struct tree_entry *te;
-
- t->full_path.s[t->full_path_dir_length] = L'\0';
- t->full_path.length = t->full_path_dir_length;
- t->path.s[t->dirname_length] = L'\0';
- t->path.length = t->dirname_length;
- if (t->stack == t->current && t->current != NULL)
- t->current = t->current->parent;
- te = t->stack;
- t->stack = te->next;
- t->dirname_length = te->dirname_length;
- t->basename = t->path.s + t->dirname_length;
- t->full_path_dir_length = te->full_path_dir_length;
- while (t->basename[0] == L'/')
- t->basename++;
- archive_wstring_free(&te->name);
- archive_wstring_free(&te->full_path);
- free(te);
-}
-
-/*
- * Get the next item in the tree traversal.
- */
-static int
-tree_next(struct tree *t)
-{
- int r;
-
- while (t->stack != NULL) {
- /* If there's an open dir, get the next entry from there. */
- if (t->d != INVALID_HANDLE_VALUE) {
- r = tree_dir_next_windows(t, NULL);
- if (r == 0)
- continue;
- return (r);
- }
-
- if (t->stack->flags & needsFirstVisit) {
- wchar_t *d = t->stack->name.s;
- t->stack->flags &= ~needsFirstVisit;
- if (!(d[0] == L'/' && d[1] == L'/' &&
- d[2] == L'?' && d[3] == L'/') &&
- (wcschr(d, L'*') || wcschr(d, L'?'))) {
- r = tree_dir_next_windows(t, d);
- if (r == 0)
- continue;
- return (r);
- } else {
- HANDLE h = FindFirstFileW(t->stack->full_path.s, &t->_findData);
- if (h == INVALID_HANDLE_VALUE) {
- la_dosmaperr(GetLastError());
- t->tree_errno = errno;
- t->visit_type = TREE_ERROR_DIR;
- return (t->visit_type);
- }
- t->findData = &t->_findData;
- FindClose(h);
- }
- /* Top stack item needs a regular visit. */
- t->current = t->stack;
- tree_append(t, t->stack->name.s,
- archive_strlen(&(t->stack->name)));
- //t->dirname_length = t->path_length;
- //tree_pop(t);
- t->stack->flags &= ~needsFirstVisit;
- return (t->visit_type = TREE_REGULAR);
- } else if (t->stack->flags & needsDescent) {
- /* Top stack item is dir to descend into. */
- t->current = t->stack;
- tree_append(t, t->stack->name.s,
- archive_strlen(&(t->stack->name)));
- t->stack->flags &= ~needsDescent;
- r = tree_descent(t);
- if (r != 0) {
- tree_pop(t);
- t->visit_type = r;
- } else
- t->visit_type = TREE_POSTDESCENT;
- return (t->visit_type);
- } else if (t->stack->flags & needsOpen) {
- t->stack->flags &= ~needsOpen;
- r = tree_dir_next_windows(t, L"*");
- if (r == 0)
- continue;
- return (r);
- } else if (t->stack->flags & needsAscent) {
- /* Top stack item is dir and we're done with it. */
- r = tree_ascend(t);
- tree_pop(t);
- t->visit_type = r != 0 ? r : TREE_POSTASCENT;
- return (t->visit_type);
- } else {
- /* Top item on stack is dead. */
- tree_pop(t);
- t->flags &= ~hasLstat;
- t->flags &= ~hasStat;
- }
- }
- return (t->visit_type = 0);
-}
-
-static int
-tree_dir_next_windows(struct tree *t, const wchar_t *pattern)
-{
- const wchar_t *name;
- size_t namelen;
- int r;
-
- for (;;) {
- if (pattern != NULL) {
- struct archive_wstring pt;
-
- archive_string_init(&pt);
- archive_wstring_ensure(&pt,
- archive_strlen(&(t->full_path))
- + 2 + wcslen(pattern));
- archive_wstring_copy(&pt, &(t->full_path));
- archive_wstrappend_wchar(&pt, L'\\');
- archive_wstrcat(&pt, pattern);
- t->d = FindFirstFileW(pt.s, &t->_findData);
- archive_wstring_free(&pt);
- if (t->d == INVALID_HANDLE_VALUE) {
- la_dosmaperr(GetLastError());
- t->tree_errno = errno;
- r = tree_ascend(t); /* Undo "chdir" */
- tree_pop(t);
- t->visit_type = r != 0 ? r : TREE_ERROR_DIR;
- return (t->visit_type);
- }
- t->findData = &t->_findData;
- pattern = NULL;
- } else if (!FindNextFileW(t->d, &t->_findData)) {
- FindClose(t->d);
- t->d = INVALID_HANDLE_VALUE;
- t->findData = NULL;
- return (0);
- }
- name = t->findData->cFileName;
- namelen = wcslen(name);
- t->flags &= ~hasLstat;
- t->flags &= ~hasStat;
- if (name[0] == L'.' && name[1] == L'\0')
- continue;
- if (name[0] == L'.' && name[1] == L'.' && name[2] == L'\0')
- continue;
- tree_append(t, name, namelen);
- return (t->visit_type = TREE_REGULAR);
- }
-}
-
-#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
-static void
-fileTimeToUtc(const FILETIME *filetime, time_t *t, long *ns)
-{
- ULARGE_INTEGER utc;
-
- utc.HighPart = filetime->dwHighDateTime;
- utc.LowPart = filetime->dwLowDateTime;
- if (utc.QuadPart >= EPOC_TIME) {
- utc.QuadPart -= EPOC_TIME;
- /* milli seconds base */
- *t = (time_t)(utc.QuadPart / 10000000);
- /* nano seconds base */
- *ns = (long)(utc.QuadPart % 10000000) * 100;
- } else {
- *t = 0;
- *ns = 0;
- }
-}
-
-static void
-entry_copy_bhfi(struct archive_entry *entry, const wchar_t *path,
- const WIN32_FIND_DATAW *findData,
- const BY_HANDLE_FILE_INFORMATION *bhfi)
-{
- time_t secs;
- long nsecs;
- mode_t mode;
-
- fileTimeToUtc(&bhfi->ftLastAccessTime, &secs, &nsecs);
- archive_entry_set_atime(entry, secs, nsecs);
- fileTimeToUtc(&bhfi->ftLastWriteTime, &secs, &nsecs);
- archive_entry_set_mtime(entry, secs, nsecs);
- fileTimeToUtc(&bhfi->ftCreationTime, &secs, &nsecs);
- archive_entry_set_birthtime(entry, secs, nsecs);
- archive_entry_set_ctime(entry, secs, nsecs);
- archive_entry_set_dev(entry, bhfi_dev(bhfi));
- archive_entry_set_ino64(entry, bhfi_ino(bhfi));
- if (bhfi->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- archive_entry_set_nlink(entry, bhfi->nNumberOfLinks + 1);
- else
- archive_entry_set_nlink(entry, bhfi->nNumberOfLinks);
- archive_entry_set_size(entry,
- (((int64_t)bhfi->nFileSizeHigh) << 32)
- + bhfi->nFileSizeLow);
- archive_entry_set_uid(entry, 0);
- archive_entry_set_gid(entry, 0);
- archive_entry_set_rdev(entry, 0);
-
- mode = S_IRUSR | S_IRGRP | S_IROTH;
- if ((bhfi->dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
- mode |= S_IWUSR | S_IWGRP | S_IWOTH;
- if ((bhfi->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
- findData != NULL &&
- findData->dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
- mode |= S_IFLNK;
- entry_symlink_from_pathw(entry, path);
- } else if (bhfi->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
- else {
- const wchar_t *p;
-
- mode |= S_IFREG;
- p = wcsrchr(path, L'.');
- if (p != NULL && wcslen(p) == 4) {
- switch (p[1]) {
- case L'B': case L'b':
- if ((p[2] == L'A' || p[2] == L'a' ) &&
- (p[3] == L'T' || p[3] == L't' ))
- mode |= S_IXUSR | S_IXGRP | S_IXOTH;
- break;
- case L'C': case L'c':
- if (((p[2] == L'M' || p[2] == L'm' ) &&
- (p[3] == L'D' || p[3] == L'd' )))
- mode |= S_IXUSR | S_IXGRP | S_IXOTH;
- break;
- case L'E': case L'e':
- if ((p[2] == L'X' || p[2] == L'x' ) &&
- (p[3] == L'E' || p[3] == L'e' ))
- mode |= S_IXUSR | S_IXGRP | S_IXOTH;
- break;
- default:
- break;
- }
- }
- }
- archive_entry_set_mode(entry, mode);
-}
-
-static void
-tree_archive_entry_copy_bhfi(struct archive_entry *entry, struct tree *t,
- const BY_HANDLE_FILE_INFORMATION *bhfi)
-{
- entry_copy_bhfi(entry, tree_current_path(t), t->findData, bhfi);
-}
-
-static int
-tree_current_file_information(struct tree *t, BY_HANDLE_FILE_INFORMATION *st,
- int sim_lstat)
-{
- HANDLE h;
- int r;
- DWORD flag = FILE_FLAG_BACKUP_SEMANTICS;
-# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- CREATEFILE2_EXTENDED_PARAMETERS createExParams;
-#endif
-
- if (sim_lstat && tree_current_is_physical_link(t))
- flag |= FILE_FLAG_OPEN_REPARSE_POINT;
-# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- ZeroMemory(&createExParams, sizeof(createExParams));
- createExParams.dwSize = sizeof(createExParams);
- createExParams.dwFileFlags = flag;
- h = CreateFile2(tree_current_access_path(t), 0,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- OPEN_EXISTING, &createExParams);
-#else
- h = CreateFileW(tree_current_access_path(t), 0,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
- OPEN_EXISTING, flag, NULL);
-#endif
- if (h == INVALID_HANDLE_VALUE) {
- la_dosmaperr(GetLastError());
- t->tree_errno = errno;
- return (0);
- }
- r = GetFileInformationByHandle(h, st);
- CloseHandle(h);
- return (r);
-}
-
-/*
- * Get the stat() data for the entry just returned from tree_next().
- */
-static const BY_HANDLE_FILE_INFORMATION *
-tree_current_stat(struct tree *t)
-{
- if (!(t->flags & hasStat)) {
- if (!tree_current_file_information(t, &t->st, 0))
- return NULL;
- t->flags |= hasStat;
- }
- return (&t->st);
-}
-
-/*
- * Get the lstat() data for the entry just returned from tree_next().
- */
-static const BY_HANDLE_FILE_INFORMATION *
-tree_current_lstat(struct tree *t)
-{
- if (!(t->flags & hasLstat)) {
- if (!tree_current_file_information(t, &t->lst, 1))
- return NULL;
- t->flags |= hasLstat;
- }
- return (&t->lst);
-}
-
-/*
- * Test whether current entry is a dir or link to a dir.
- */
-static int
-tree_current_is_dir(struct tree *t)
-{
- if (t->findData)
- return (t->findData->dwFileAttributes
- & FILE_ATTRIBUTE_DIRECTORY);
- return (0);
-}
-
-/*
- * Test whether current entry is a physical directory. Usually, we
- * already have at least one of stat() or lstat() in memory, so we
- * use tricks to try to avoid an extra trip to the disk.
- */
-static int
-tree_current_is_physical_dir(struct tree *t)
-{
- if (tree_current_is_physical_link(t))
- return (0);
- return (tree_current_is_dir(t));
-}
-
-/*
- * Test whether current entry is a symbolic link.
- */
-static int
-tree_current_is_physical_link(struct tree *t)
-{
- if (t->findData)
- return ((t->findData->dwFileAttributes
- & FILE_ATTRIBUTE_REPARSE_POINT) &&
- (t->findData->dwReserved0
- == IO_REPARSE_TAG_SYMLINK));
- return (0);
-}
-
-/*
- * Test whether the same file has been in the tree as its parent.
- */
-static int
-tree_target_is_same_as_parent(struct tree *t,
- const BY_HANDLE_FILE_INFORMATION *st)
-{
- struct tree_entry *te;
- int64_t dev = bhfi_dev(st);
- int64_t ino = bhfi_ino(st);
-
- for (te = t->current->parent; te != NULL; te = te->parent) {
- if (te->dev == dev && te->ino == ino)
- return (1);
- }
- return (0);
-}
-
-/*
- * Return the access path for the entry just returned from tree_next().
- */
-static const wchar_t *
-tree_current_access_path(struct tree *t)
-{
- return (t->full_path.s);
-}
-
-/*
- * Return the full path for the entry just returned from tree_next().
- */
-static const wchar_t *
-tree_current_path(struct tree *t)
-{
- return (t->path.s);
-}
-
-/*
- * Terminate the traversal.
- */
-static void
-tree_close(struct tree *t)
-{
-
- if (t == NULL)
- return;
- if (t->entry_fh != INVALID_HANDLE_VALUE) {
- cancel_async(t);
- close_and_restore_time(t->entry_fh, t, &t->restore_time);
- t->entry_fh = INVALID_HANDLE_VALUE;
- }
- /* Close the handle of FindFirstFileW */
- if (t->d != INVALID_HANDLE_VALUE) {
- FindClose(t->d);
- t->d = INVALID_HANDLE_VALUE;
- t->findData = NULL;
- }
- /* Release anything remaining in the stack. */
- while (t->stack != NULL)
- tree_pop(t);
-}
-
-/*
- * Release any resources.
- */
-static void
-tree_free(struct tree *t)
-{
- int i;
-
- if (t == NULL)
- return;
- archive_wstring_free(&t->path);
- archive_wstring_free(&t->full_path);
- free(t->sparse_list);
- free(t->filesystem_table);
- for (i = 0; i < MAX_OVERLAPPED; i++) {
- if (t->ol[i].buff)
- VirtualFree(t->ol[i].buff, 0, MEM_RELEASE);
- CloseHandle(t->ol[i].ol.hEvent);
- }
- free(t);
-}
-
-
-/*
- * Populate the archive_entry with metadata from the disk.
- */
-int
-archive_read_disk_entry_from_file(struct archive *_a,
- struct archive_entry *entry, int fd, const struct stat *st)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- const wchar_t *path;
- const wchar_t *wname;
- const char *name;
- HANDLE h;
- BY_HANDLE_FILE_INFORMATION bhfi;
- DWORD fileAttributes = 0;
- int r;
-
- archive_clear_error(_a);
- wname = archive_entry_sourcepath_w(entry);
- if (wname == NULL)
- wname = archive_entry_pathname_w(entry);
- if (wname == NULL) {
- archive_set_error(&a->archive, EINVAL,
- "Can't get a wide character version of the path");
- return (ARCHIVE_FAILED);
- }
- path = __la_win_permissive_name_w(wname);
-
- if (st == NULL) {
- /*
- * Get metadata through GetFileInformationByHandle().
- */
- if (fd >= 0) {
- h = (HANDLE)_get_osfhandle(fd);
- r = GetFileInformationByHandle(h, &bhfi);
- if (r == 0) {
- la_dosmaperr(GetLastError());
- archive_set_error(&a->archive, errno,
- "Can't GetFileInformationByHandle");
- return (ARCHIVE_FAILED);
- }
- entry_copy_bhfi(entry, path, NULL, &bhfi);
- } else {
- WIN32_FIND_DATAW findData;
- DWORD flag, desiredAccess;
-# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- CREATEFILE2_EXTENDED_PARAMETERS createExParams;
-#endif
-
- h = FindFirstFileW(path, &findData);
- if (h == INVALID_HANDLE_VALUE) {
- la_dosmaperr(GetLastError());
- archive_set_error(&a->archive, errno,
- "Can't FindFirstFileW");
- return (ARCHIVE_FAILED);
- }
- FindClose(h);
-
- flag = FILE_FLAG_BACKUP_SEMANTICS;
- if (!a->follow_symlinks &&
- (findData.dwFileAttributes
- & FILE_ATTRIBUTE_REPARSE_POINT) &&
- (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) {
- flag |= FILE_FLAG_OPEN_REPARSE_POINT;
- desiredAccess = 0;
- } else if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- desiredAccess = 0;
- } else
- desiredAccess = GENERIC_READ;
-
-# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- ZeroMemory(&createExParams, sizeof(createExParams));
- createExParams.dwSize = sizeof(createExParams);
- createExParams.dwFileFlags = flag;
- h = CreateFile2(path, desiredAccess,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- OPEN_EXISTING, &createExParams);
-#else
- h = CreateFileW(path, desiredAccess,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
- OPEN_EXISTING, flag, NULL);
-#endif
- if (h == INVALID_HANDLE_VALUE) {
- la_dosmaperr(GetLastError());
- archive_set_error(&a->archive, errno,
- "Can't CreateFileW");
- return (ARCHIVE_FAILED);
- }
- r = GetFileInformationByHandle(h, &bhfi);
- if (r == 0) {
- la_dosmaperr(GetLastError());
- archive_set_error(&a->archive, errno,
- "Can't GetFileInformationByHandle");
- CloseHandle(h);
- return (ARCHIVE_FAILED);
- }
- entry_copy_bhfi(entry, path, &findData, &bhfi);
- }
- fileAttributes = bhfi.dwFileAttributes;
- } else {
- archive_entry_copy_stat(entry, st);
- if (st->st_mode & S_IFLNK)
- entry_symlink_from_pathw(entry, path);
- h = INVALID_HANDLE_VALUE;
- }
-
- /* Lookup uname/gname */
- name = archive_read_disk_uname(_a, archive_entry_uid(entry));
- if (name != NULL)
- archive_entry_copy_uname(entry, name);
- name = archive_read_disk_gname(_a, archive_entry_gid(entry));
- if (name != NULL)
- archive_entry_copy_gname(entry, name);
-
- /*
- * File attributes
- */
- if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0) {
- const int supported_attrs =
- FILE_ATTRIBUTE_READONLY |
- FILE_ATTRIBUTE_HIDDEN |
- FILE_ATTRIBUTE_SYSTEM;
- DWORD file_attrs = fileAttributes & supported_attrs;
- if (file_attrs != 0)
- archive_entry_set_fflags(entry, file_attrs, 0);
- }
-
- /*
- * Can this file be sparse file ?
- */
- if (archive_entry_filetype(entry) != AE_IFREG
- || archive_entry_size(entry) <= 0
- || archive_entry_hardlink(entry) != NULL) {
- if (h != INVALID_HANDLE_VALUE && fd < 0)
- CloseHandle(h);
- return (ARCHIVE_OK);
- }
-
- if (h == INVALID_HANDLE_VALUE) {
- if (fd >= 0) {
- h = (HANDLE)_get_osfhandle(fd);
- } else {
-# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- CREATEFILE2_EXTENDED_PARAMETERS createExParams;
- ZeroMemory(&createExParams, sizeof(createExParams));
- createExParams.dwSize = sizeof(createExParams);
- createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
- h = CreateFile2(path, GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- OPEN_EXISTING, &createExParams);
-#else
- h = CreateFileW(path, GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
- OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
-#endif
- if (h == INVALID_HANDLE_VALUE) {
- la_dosmaperr(GetLastError());
- archive_set_error(&a->archive, errno,
- "Can't CreateFileW");
- return (ARCHIVE_FAILED);
- }
- }
- r = GetFileInformationByHandle(h, &bhfi);
- if (r == 0) {
- la_dosmaperr(GetLastError());
- archive_set_error(&a->archive, errno,
- "Can't GetFileInformationByHandle");
- if (h != INVALID_HANDLE_VALUE && fd < 0)
- CloseHandle(h);
- return (ARCHIVE_FAILED);
- }
- fileAttributes = bhfi.dwFileAttributes;
- }
-
- /* Sparse file must be set a mark, FILE_ATTRIBUTE_SPARSE_FILE */
- if ((fileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) == 0) {
- if (fd < 0)
- CloseHandle(h);
- return (ARCHIVE_OK);
- }
-
- if ((a->flags & ARCHIVE_READDISK_NO_SPARSE) == 0) {
- r = setup_sparse_from_disk(a, entry, h);
- if (fd < 0)
- CloseHandle(h);
- }
-
- return (r);
-}
-
-/*
- * Windows sparse interface.
- */
-#if defined(__MINGW32__) && !defined(FSCTL_QUERY_ALLOCATED_RANGES)
-#define FSCTL_QUERY_ALLOCATED_RANGES 0x940CF
-typedef struct {
- LARGE_INTEGER FileOffset;
- LARGE_INTEGER Length;
-} FILE_ALLOCATED_RANGE_BUFFER;
-#endif
-
-static int
-setup_sparse_from_disk(struct archive_read_disk *a,
- struct archive_entry *entry, HANDLE handle)
-{
- FILE_ALLOCATED_RANGE_BUFFER range, *outranges = NULL;
- size_t outranges_size;
- int64_t entry_size = archive_entry_size(entry);
- int exit_sts = ARCHIVE_OK;
-
- range.FileOffset.QuadPart = 0;
- range.Length.QuadPart = entry_size;
- outranges_size = 2048;
- outranges = (FILE_ALLOCATED_RANGE_BUFFER *)malloc(outranges_size);
- if (outranges == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Couldn't allocate memory");
- exit_sts = ARCHIVE_FATAL;
- goto exit_setup_sparse;
- }
-
- for (;;) {
- DWORD retbytes;
- BOOL ret;
-
- for (;;) {
- ret = DeviceIoControl(handle,
- FSCTL_QUERY_ALLOCATED_RANGES,
- &range, sizeof(range), outranges,
- (DWORD)outranges_size, &retbytes, NULL);
- if (ret == 0 && GetLastError() == ERROR_MORE_DATA) {
- free(outranges);
- outranges_size *= 2;
- outranges = (FILE_ALLOCATED_RANGE_BUFFER *)
- malloc(outranges_size);
- if (outranges == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Couldn't allocate memory");
- exit_sts = ARCHIVE_FATAL;
- goto exit_setup_sparse;
- }
- continue;
- } else
- break;
- }
- if (ret != 0) {
- if (retbytes > 0) {
- DWORD i, n;
-
- n = retbytes / sizeof(outranges[0]);
- if (n == 1 &&
- outranges[0].FileOffset.QuadPart == 0 &&
- outranges[0].Length.QuadPart == entry_size)
- break;/* This is not sparse. */
- for (i = 0; i < n; i++)
- archive_entry_sparse_add_entry(entry,
- outranges[i].FileOffset.QuadPart,
- outranges[i].Length.QuadPart);
- range.FileOffset.QuadPart =
- outranges[n-1].FileOffset.QuadPart
- + outranges[n-1].Length.QuadPart;
- range.Length.QuadPart =
- entry_size - range.FileOffset.QuadPart;
- if (range.Length.QuadPart > 0)
- continue;
- } else {
- /* The entire file is a hole. Add one data block of size 0 at the end. */
- archive_entry_sparse_add_entry(entry,
- entry_size,
- 0);
- }
- break;
- } else {
- la_dosmaperr(GetLastError());
- archive_set_error(&a->archive, errno,
- "DeviceIoControl Failed: %lu", GetLastError());
- exit_sts = ARCHIVE_FAILED;
- goto exit_setup_sparse;
- }
- }
-exit_setup_sparse:
- free(outranges);
-
- return (exit_sts);
-}
-
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_read_extract.c b/contrib/libs/libarchive/libarchive/archive_read_extract.c
deleted file mode 100644
index b7973fa8e0..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_extract.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_extract.c,v 1.61 2008/05/26 17:00:22 kientzle Exp $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-int
-archive_read_extract(struct archive *_a, struct archive_entry *entry, int flags)
-{
- struct archive_read_extract *extract;
- struct archive_read * a = (struct archive_read *)_a;
-
- extract = __archive_read_get_extract(a);
- if (extract == NULL)
- return (ARCHIVE_FATAL);
-
- /* If we haven't initialized the archive_write_disk object, do it now. */
- if (extract->ad == NULL) {
- extract->ad = archive_write_disk_new();
- if (extract->ad == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Can't extract");
- return (ARCHIVE_FATAL);
- }
- archive_write_disk_set_standard_lookup(extract->ad);
- }
-
- archive_write_disk_set_options(extract->ad, flags);
- return (archive_read_extract2(&a->archive, entry, extract->ad));
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_extract2.c b/contrib/libs/libarchive/libarchive/archive_read_extract2.c
deleted file mode 100644
index 4febd8ce05..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_extract2.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_extract.c,v 1.61 2008/05/26 17:00:22 kientzle Exp $");
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-static int copy_data(struct archive *ar, struct archive *aw);
-static int archive_read_extract_cleanup(struct archive_read *);
-
-
-/* Retrieve an extract object without initialising the associated
- * archive_write_disk object.
- */
-struct archive_read_extract *
-__archive_read_get_extract(struct archive_read *a)
-{
- if (a->extract == NULL) {
- a->extract = (struct archive_read_extract *)calloc(1, sizeof(*a->extract));
- if (a->extract == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Can't extract");
- return (NULL);
- }
- a->cleanup_archive_extract = archive_read_extract_cleanup;
- }
- return (a->extract);
-}
-
-/*
- * Cleanup function for archive_extract.
- */
-static int
-archive_read_extract_cleanup(struct archive_read *a)
-{
- int ret = ARCHIVE_OK;
-
- if (a->extract->ad != NULL) {
- ret = archive_write_free(a->extract->ad);
- }
- free(a->extract);
- a->extract = NULL;
- return (ret);
-}
-
-int
-archive_read_extract2(struct archive *_a, struct archive_entry *entry,
- struct archive *ad)
-{
- struct archive_read *a = (struct archive_read *)_a;
- int r, r2;
-
- /* Set up for this particular entry. */
- if (a->skip_file_set)
- archive_write_disk_set_skip_file(ad,
- a->skip_file_dev, a->skip_file_ino);
- r = archive_write_header(ad, entry);
- if (r < ARCHIVE_WARN)
- r = ARCHIVE_WARN;
- if (r != ARCHIVE_OK)
- /* If _write_header failed, copy the error. */
- archive_copy_error(&a->archive, ad);
- else if (!archive_entry_size_is_set(entry) || archive_entry_size(entry) > 0)
- /* Otherwise, pour data into the entry. */
- r = copy_data(_a, ad);
- r2 = archive_write_finish_entry(ad);
- if (r2 < ARCHIVE_WARN)
- r2 = ARCHIVE_WARN;
- /* Use the first message. */
- if (r2 != ARCHIVE_OK && r == ARCHIVE_OK)
- archive_copy_error(&a->archive, ad);
- /* Use the worst error return. */
- if (r2 < r)
- r = r2;
- return (r);
-}
-
-void
-archive_read_extract_set_progress_callback(struct archive *_a,
- void (*progress_func)(void *), void *user_data)
-{
- struct archive_read *a = (struct archive_read *)_a;
- struct archive_read_extract *extract = __archive_read_get_extract(a);
- if (extract != NULL) {
- extract->extract_progress = progress_func;
- extract->extract_progress_user_data = user_data;
- }
-}
-
-static int
-copy_data(struct archive *ar, struct archive *aw)
-{
- int64_t offset;
- const void *buff;
- struct archive_read_extract *extract;
- size_t size;
- int r;
-
- extract = __archive_read_get_extract((struct archive_read *)ar);
- if (extract == NULL)
- return (ARCHIVE_FATAL);
- for (;;) {
- r = archive_read_data_block(ar, &buff, &size, &offset);
- if (r == ARCHIVE_EOF)
- return (ARCHIVE_OK);
- if (r != ARCHIVE_OK)
- return (r);
- r = (int)archive_write_data_block(aw, buff, size, offset);
- if (r < ARCHIVE_WARN)
- r = ARCHIVE_WARN;
- if (r < ARCHIVE_OK) {
- archive_set_error(ar, archive_errno(aw),
- "%s", archive_error_string(aw));
- return (r);
- }
- if (extract->extract_progress)
- (extract->extract_progress)
- (extract->extract_progress_user_data);
- }
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_open_fd.c b/contrib/libs/libarchive/libarchive/archive_read_open_fd.c
deleted file mode 100644
index f59cd07fe6..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_open_fd.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_fd.c 201103 2009-12-28 03:13:49Z kientzle $");
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_IO_H
-#include <io.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "archive.h"
-
-struct read_fd_data {
- int fd;
- size_t block_size;
- char use_lseek;
- void *buffer;
-};
-
-static int file_close(struct archive *, void *);
-static ssize_t file_read(struct archive *, void *, const void **buff);
-static int64_t file_seek(struct archive *, void *, int64_t request, int);
-static int64_t file_skip(struct archive *, void *, int64_t request);
-
-int
-archive_read_open_fd(struct archive *a, int fd, size_t block_size)
-{
- struct stat st;
- struct read_fd_data *mine;
- void *b;
-
- archive_clear_error(a);
- if (fstat(fd, &st) != 0) {
- archive_set_error(a, errno, "Can't stat fd %d", fd);
- return (ARCHIVE_FATAL);
- }
-
- mine = (struct read_fd_data *)calloc(1, sizeof(*mine));
- b = malloc(block_size);
- if (mine == NULL || b == NULL) {
- archive_set_error(a, ENOMEM, "No memory");
- free(mine);
- free(b);
- return (ARCHIVE_FATAL);
- }
- mine->block_size = block_size;
- mine->buffer = b;
- mine->fd = fd;
- /*
- * Skip support is a performance optimization for anything
- * that supports lseek(). On FreeBSD, only regular files and
- * raw disk devices support lseek() and there's no portable
- * way to determine if a device is a raw disk device, so we
- * only enable this optimization for regular files.
- */
- if (S_ISREG(st.st_mode)) {
- archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
- mine->use_lseek = 1;
- }
-#if defined(__CYGWIN__) || defined(_WIN32)
- setmode(mine->fd, O_BINARY);
-#endif
-
- archive_read_set_read_callback(a, file_read);
- archive_read_set_skip_callback(a, file_skip);
- archive_read_set_seek_callback(a, file_seek);
- archive_read_set_close_callback(a, file_close);
- archive_read_set_callback_data(a, mine);
- return (archive_read_open1(a));
-}
-
-static ssize_t
-file_read(struct archive *a, void *client_data, const void **buff)
-{
- struct read_fd_data *mine = (struct read_fd_data *)client_data;
- ssize_t bytes_read;
-
- *buff = mine->buffer;
- for (;;) {
- bytes_read = read(mine->fd, mine->buffer, mine->block_size);
- if (bytes_read < 0) {
- if (errno == EINTR)
- continue;
- archive_set_error(a, errno, "Error reading fd %d",
- mine->fd);
- }
- return (bytes_read);
- }
-}
-
-static int64_t
-file_skip(struct archive *a, void *client_data, int64_t request)
-{
- struct read_fd_data *mine = (struct read_fd_data *)client_data;
- int64_t skip = request;
- int64_t old_offset, new_offset;
- int skip_bits = sizeof(skip) * 8 - 1; /* off_t is a signed type. */
-
- if (!mine->use_lseek)
- return (0);
-
- /* Reduce a request that would overflow the 'skip' variable. */
- if (sizeof(request) > sizeof(skip)) {
- int64_t max_skip =
- (((int64_t)1 << (skip_bits - 1)) - 1) * 2 + 1;
- if (request > max_skip)
- skip = max_skip;
- }
-
- /* Reduce request to the next smallest multiple of block_size */
- request = (request / mine->block_size) * mine->block_size;
- if (request == 0)
- return (0);
-
- if (((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0) &&
- ((new_offset = lseek(mine->fd, skip, SEEK_CUR)) >= 0))
- return (new_offset - old_offset);
-
- /* If seek failed once, it will probably fail again. */
- mine->use_lseek = 0;
-
- /* Let libarchive recover with read+discard. */
- if (errno == ESPIPE)
- return (0);
-
- /*
- * There's been an error other than ESPIPE. This is most
- * likely caused by a programmer error (too large request)
- * or a corrupted archive file.
- */
- archive_set_error(a, errno, "Error seeking");
- return (-1);
-}
-
-/*
- * TODO: Store the offset and use it in the read callback.
- */
-static int64_t
-file_seek(struct archive *a, void *client_data, int64_t request, int whence)
-{
- struct read_fd_data *mine = (struct read_fd_data *)client_data;
- int64_t r;
-
- /* We use off_t here because lseek() is declared that way. */
- /* See above for notes about when off_t is less than 64 bits. */
- r = lseek(mine->fd, request, whence);
- if (r >= 0)
- return r;
-
- if (errno == ESPIPE) {
- archive_set_error(a, errno,
- "A file descriptor(%d) is not seekable(PIPE)", mine->fd);
- return (ARCHIVE_FAILED);
- } else {
- /* If the input is corrupted or truncated, fail. */
- archive_set_error(a, errno,
- "Error seeking in a file descriptor(%d)", mine->fd);
- return (ARCHIVE_FATAL);
- }
-}
-
-static int
-file_close(struct archive *a, void *client_data)
-{
- struct read_fd_data *mine = (struct read_fd_data *)client_data;
-
- (void)a; /* UNUSED */
- free(mine->buffer);
- free(mine);
- return (ARCHIVE_OK);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_open_file.c b/contrib/libs/libarchive/libarchive/archive_read_open_file.c
deleted file mode 100644
index 03719e8bff..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_open_file.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_file.c 201093 2009-12-28 02:28:44Z kientzle $");
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_IO_H
-#include <io.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "archive.h"
-
-struct read_FILE_data {
- FILE *f;
- size_t block_size;
- void *buffer;
- char can_skip;
-};
-
-static int file_close(struct archive *, void *);
-static ssize_t file_read(struct archive *, void *, const void **buff);
-static int64_t file_skip(struct archive *, void *, int64_t request);
-
-int
-archive_read_open_FILE(struct archive *a, FILE *f)
-{
- struct stat st;
- struct read_FILE_data *mine;
- size_t block_size = 128 * 1024;
- void *b;
-
- archive_clear_error(a);
- mine = (struct read_FILE_data *)malloc(sizeof(*mine));
- b = malloc(block_size);
- if (mine == NULL || b == NULL) {
- archive_set_error(a, ENOMEM, "No memory");
- free(mine);
- free(b);
- return (ARCHIVE_FATAL);
- }
- mine->block_size = block_size;
- mine->buffer = b;
- mine->f = f;
- /*
- * If we can't fstat() the file, it may just be that it's not
- * a file. (On some platforms, FILE * objects can wrap I/O
- * streams that don't support fileno()). As a result, fileno()
- * should be used cautiously.)
- */
- if (fstat(fileno(mine->f), &st) == 0 && S_ISREG(st.st_mode)) {
- archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
- /* Enable the seek optimization only for regular files. */
- mine->can_skip = 1;
- } else
- mine->can_skip = 0;
-
-#if defined(__CYGWIN__) || defined(_WIN32)
- setmode(fileno(mine->f), O_BINARY);
-#endif
-
- archive_read_set_read_callback(a, file_read);
- archive_read_set_skip_callback(a, file_skip);
- archive_read_set_close_callback(a, file_close);
- archive_read_set_callback_data(a, mine);
- return (archive_read_open1(a));
-}
-
-static ssize_t
-file_read(struct archive *a, void *client_data, const void **buff)
-{
- struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
- size_t bytes_read;
-
- *buff = mine->buffer;
- bytes_read = fread(mine->buffer, 1, mine->block_size, mine->f);
- if (bytes_read < mine->block_size && ferror(mine->f)) {
- archive_set_error(a, errno, "Error reading file");
- }
- return (bytes_read);
-}
-
-static int64_t
-file_skip(struct archive *a, void *client_data, int64_t request)
-{
- struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
-#if HAVE_FSEEKO
- off_t skip = (off_t)request;
-#elif HAVE__FSEEKI64
- int64_t skip = request;
-#else
- long skip = (long)request;
-#endif
- int skip_bits = sizeof(skip) * 8 - 1;
-
- (void)a; /* UNUSED */
-
- /*
- * If we can't skip, return 0 as the amount we did step and
- * the caller will work around by reading and discarding.
- */
- if (!mine->can_skip)
- return (0);
- if (request == 0)
- return (0);
-
- /* If request is too big for a long or an off_t, reduce it. */
- if (sizeof(request) > sizeof(skip)) {
- int64_t max_skip =
- (((int64_t)1 << (skip_bits - 1)) - 1) * 2 + 1;
- if (request > max_skip)
- skip = max_skip;
- }
-
-#ifdef __ANDROID__
- /* fileno() isn't safe on all platforms ... see above. */
- if (lseek(fileno(mine->f), skip, SEEK_CUR) < 0)
-#elif HAVE__FSEEKI64
- if (_fseeki64(mine->f, skip, SEEK_CUR) != 0)
-#elif HAVE_FSEEKO
- if (fseeko(mine->f, skip, SEEK_CUR) != 0)
-#else
- if (fseek(mine->f, skip, SEEK_CUR) != 0)
-#endif
- {
- mine->can_skip = 0;
- return (0);
- }
- return (request);
-}
-
-static int
-file_close(struct archive *a, void *client_data)
-{
- struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
-
- (void)a; /* UNUSED */
- free(mine->buffer);
- free(mine);
- return (ARCHIVE_OK);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_open_filename.c b/contrib/libs/libarchive/libarchive/archive_read_open_filename.c
deleted file mode 100644
index f3b8d09f70..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_open_filename.c
+++ /dev/null
@@ -1,586 +0,0 @@
-/*-
- * Copyright (c) 2003-2010 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_filename.c 201093 2009-12-28 02:28:44Z kientzle $");
-
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_IO_H
-#include <io.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-#include <sys/disk.h>
-#elif defined(__NetBSD__) || defined(__OpenBSD__)
-#include <sys/disklabel.h>
-#error #include <sys/dkio.h>
-#elif defined(__DragonFly__)
-#error #include <sys/diskslice.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_string.h"
-
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-#ifndef O_CLOEXEC
-#define O_CLOEXEC 0
-#endif
-
-struct read_file_data {
- int fd;
- size_t block_size;
- void *buffer;
- mode_t st_mode; /* Mode bits for opened file. */
- char use_lseek;
- enum fnt_e { FNT_STDIN, FNT_MBS, FNT_WCS } filename_type;
- union {
- char m[1];/* MBS filename. */
- wchar_t w[1];/* WCS filename. */
- } filename; /* Must be last! */
-};
-
-static int file_open(struct archive *, void *);
-static int file_close(struct archive *, void *);
-static int file_close2(struct archive *, void *);
-static int file_switch(struct archive *, void *, void *);
-static ssize_t file_read(struct archive *, void *, const void **buff);
-static int64_t file_seek(struct archive *, void *, int64_t request, int);
-static int64_t file_skip(struct archive *, void *, int64_t request);
-static int64_t file_skip_lseek(struct archive *, void *, int64_t request);
-
-int
-archive_read_open_file(struct archive *a, const char *filename,
- size_t block_size)
-{
- return (archive_read_open_filename(a, filename, block_size));
-}
-
-int
-archive_read_open_filename(struct archive *a, const char *filename,
- size_t block_size)
-{
- const char *filenames[2];
- filenames[0] = filename;
- filenames[1] = NULL;
- return archive_read_open_filenames(a, filenames, block_size);
-}
-
-int
-archive_read_open_filenames(struct archive *a, const char **filenames,
- size_t block_size)
-{
- struct read_file_data *mine;
- const char *filename = NULL;
- if (filenames)
- filename = *(filenames++);
-
- archive_clear_error(a);
- do
- {
- if (filename == NULL)
- filename = "";
- mine = (struct read_file_data *)calloc(1,
- sizeof(*mine) + strlen(filename));
- if (mine == NULL)
- goto no_memory;
- strcpy(mine->filename.m, filename);
- mine->block_size = block_size;
- mine->fd = -1;
- mine->buffer = NULL;
- mine->st_mode = mine->use_lseek = 0;
- if (filename == NULL || filename[0] == '\0') {
- mine->filename_type = FNT_STDIN;
- } else
- mine->filename_type = FNT_MBS;
- if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK))
- return (ARCHIVE_FATAL);
- if (filenames == NULL)
- break;
- filename = *(filenames++);
- } while (filename != NULL && filename[0] != '\0');
- archive_read_set_open_callback(a, file_open);
- archive_read_set_read_callback(a, file_read);
- archive_read_set_skip_callback(a, file_skip);
- archive_read_set_close_callback(a, file_close);
- archive_read_set_switch_callback(a, file_switch);
- archive_read_set_seek_callback(a, file_seek);
-
- return (archive_read_open1(a));
-no_memory:
- archive_set_error(a, ENOMEM, "No memory");
- return (ARCHIVE_FATAL);
-}
-
-int
-archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename,
- size_t block_size)
-{
- struct read_file_data *mine = (struct read_file_data *)calloc(1,
- sizeof(*mine) + wcslen(wfilename) * sizeof(wchar_t));
- if (!mine)
- {
- archive_set_error(a, ENOMEM, "No memory");
- return (ARCHIVE_FATAL);
- }
- mine->fd = -1;
- mine->block_size = block_size;
-
- if (wfilename == NULL || wfilename[0] == L'\0') {
- mine->filename_type = FNT_STDIN;
- } else {
-#if defined(_WIN32) && !defined(__CYGWIN__)
- mine->filename_type = FNT_WCS;
- wcscpy(mine->filename.w, wfilename);
-#else
- /*
- * POSIX system does not support a wchar_t interface for
- * open() system call, so we have to translate a wchar_t
- * filename to multi-byte one and use it.
- */
- struct archive_string fn;
-
- archive_string_init(&fn);
- if (archive_string_append_from_wcs(&fn, wfilename,
- wcslen(wfilename)) != 0) {
- if (errno == ENOMEM)
- archive_set_error(a, errno,
- "Can't allocate memory");
- else
- archive_set_error(a, EINVAL,
- "Failed to convert a wide-character"
- " filename to a multi-byte filename");
- archive_string_free(&fn);
- free(mine);
- return (ARCHIVE_FATAL);
- }
- mine->filename_type = FNT_MBS;
- strcpy(mine->filename.m, fn.s);
- archive_string_free(&fn);
-#endif
- }
- if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK))
- return (ARCHIVE_FATAL);
- archive_read_set_open_callback(a, file_open);
- archive_read_set_read_callback(a, file_read);
- archive_read_set_skip_callback(a, file_skip);
- archive_read_set_close_callback(a, file_close);
- archive_read_set_switch_callback(a, file_switch);
- archive_read_set_seek_callback(a, file_seek);
-
- return (archive_read_open1(a));
-}
-
-static int
-file_open(struct archive *a, void *client_data)
-{
- struct stat st;
- struct read_file_data *mine = (struct read_file_data *)client_data;
- void *buffer;
- const char *filename = NULL;
-#if defined(_WIN32) && !defined(__CYGWIN__)
- const wchar_t *wfilename = NULL;
-#endif
- int fd = -1;
- int is_disk_like = 0;
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
- off_t mediasize = 0; /* FreeBSD-specific, so off_t okay here. */
-#elif defined(__NetBSD__) || defined(__OpenBSD__)
- struct disklabel dl;
-#elif defined(__DragonFly__)
- struct partinfo pi;
-#endif
-
- archive_clear_error(a);
- if (mine->filename_type == FNT_STDIN) {
- /* We used to delegate stdin support by
- * directly calling archive_read_open_fd(a,0,block_size)
- * here, but that doesn't (and shouldn't) handle the
- * end-of-file flush when reading stdout from a pipe.
- * Basically, read_open_fd() is intended for folks who
- * are willing to handle such details themselves. This
- * API is intended to be a little smarter for folks who
- * want easy handling of the common case.
- */
- fd = 0;
-#if defined(__CYGWIN__) || defined(_WIN32)
- setmode(0, O_BINARY);
-#endif
- filename = "";
- } else if (mine->filename_type == FNT_MBS) {
- filename = mine->filename.m;
- fd = open(filename, O_RDONLY | O_BINARY | O_CLOEXEC);
- __archive_ensure_cloexec_flag(fd);
- if (fd < 0) {
- archive_set_error(a, errno,
- "Failed to open '%s'", filename);
- return (ARCHIVE_FATAL);
- }
- } else {
-#if defined(_WIN32) && !defined(__CYGWIN__)
- wfilename = mine->filename.w;
- fd = _wopen(wfilename, O_RDONLY | O_BINARY);
- if (fd < 0 && errno == ENOENT) {
- wchar_t *fullpath;
- fullpath = __la_win_permissive_name_w(wfilename);
- if (fullpath != NULL) {
- fd = _wopen(fullpath, O_RDONLY | O_BINARY);
- free(fullpath);
- }
- }
- if (fd < 0) {
- archive_set_error(a, errno,
- "Failed to open '%S'", wfilename);
- return (ARCHIVE_FATAL);
- }
-#else
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Unexpedted operation in archive_read_open_filename");
- goto fail;
-#endif
- }
- if (fstat(fd, &st) != 0) {
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if (mine->filename_type == FNT_WCS)
- archive_set_error(a, errno, "Can't stat '%S'",
- wfilename);
- else
-#endif
- archive_set_error(a, errno, "Can't stat '%s'",
- filename);
- goto fail;
- }
-
- /*
- * Determine whether the input looks like a disk device or a
- * tape device. The results are used below to select an I/O
- * strategy:
- * = "disk-like" devices support arbitrary lseek() and will
- * support I/O requests of any size. So we get easy skipping
- * and can cheat on block sizes to get better performance.
- * = "tape-like" devices require strict blocking and use
- * specialized ioctls for seeking.
- * = "socket-like" devices cannot seek at all but can improve
- * performance by using nonblocking I/O to read "whatever is
- * available right now".
- *
- * Right now, we only specially recognize disk-like devices,
- * but it should be straightforward to add probes and strategy
- * here for tape-like and socket-like devices.
- */
- if (S_ISREG(st.st_mode)) {
- /* Safety: Tell the extractor not to overwrite the input. */
- archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
- /* Regular files act like disks. */
- is_disk_like = 1;
- }
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
- /* FreeBSD: if it supports DIOCGMEDIASIZE ioctl, it's disk-like. */
- else if (S_ISCHR(st.st_mode) &&
- ioctl(fd, DIOCGMEDIASIZE, &mediasize) == 0 &&
- mediasize > 0) {
- is_disk_like = 1;
- }
-#elif defined(__NetBSD__) || defined(__OpenBSD__)
- /* Net/OpenBSD: if it supports DIOCGDINFO ioctl, it's disk-like. */
- else if ((S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) &&
- ioctl(fd, DIOCGDINFO, &dl) == 0 &&
- dl.d_partitions[DISKPART(st.st_rdev)].p_size > 0) {
- is_disk_like = 1;
- }
-#elif defined(__DragonFly__)
- /* DragonFly BSD: if it supports DIOCGPART ioctl, it's disk-like. */
- else if (S_ISCHR(st.st_mode) &&
- ioctl(fd, DIOCGPART, &pi) == 0 &&
- pi.media_size > 0) {
- is_disk_like = 1;
- }
-#elif defined(__linux__)
- /* Linux: All block devices are disk-like. */
- else if (S_ISBLK(st.st_mode) &&
- lseek(fd, 0, SEEK_CUR) == 0 &&
- lseek(fd, 0, SEEK_SET) == 0 &&
- lseek(fd, 0, SEEK_END) > 0 &&
- lseek(fd, 0, SEEK_SET) == 0) {
- is_disk_like = 1;
- }
-#endif
- /* TODO: Add an "is_tape_like" variable and appropriate tests. */
-
- /* Disk-like devices prefer power-of-two block sizes. */
- /* Use provided block_size as a guide so users have some control. */
- if (is_disk_like) {
- size_t new_block_size = 64 * 1024;
- while (new_block_size < mine->block_size
- && new_block_size < 64 * 1024 * 1024)
- new_block_size *= 2;
- mine->block_size = new_block_size;
- }
- buffer = malloc(mine->block_size);
- if (buffer == NULL) {
- archive_set_error(a, ENOMEM, "No memory");
- goto fail;
- }
- mine->buffer = buffer;
- mine->fd = fd;
- /* Remember mode so close can decide whether to flush. */
- mine->st_mode = st.st_mode;
-
- /* Disk-like inputs can use lseek(). */
- if (is_disk_like)
- mine->use_lseek = 1;
-
- return (ARCHIVE_OK);
-fail:
- /*
- * Don't close file descriptors not opened or ones pointing referring
- * to `FNT_STDIN`.
- */
- if (fd != -1 && fd != 0)
- close(fd);
- return (ARCHIVE_FATAL);
-}
-
-static ssize_t
-file_read(struct archive *a, void *client_data, const void **buff)
-{
- struct read_file_data *mine = (struct read_file_data *)client_data;
- ssize_t bytes_read;
-
- /* TODO: If a recent lseek() operation has left us
- * mis-aligned, read and return a short block to try to get
- * us back in alignment. */
-
- /* TODO: Someday, try mmap() here; if that succeeds, give
- * the entire file to libarchive as a single block. That
- * could be a lot faster than block-by-block manual I/O. */
-
- /* TODO: We might be able to improve performance on pipes and
- * sockets by setting non-blocking I/O and just accepting
- * whatever we get here instead of waiting for a full block
- * worth of data. */
-
- *buff = mine->buffer;
- for (;;) {
- bytes_read = read(mine->fd, mine->buffer, mine->block_size);
- if (bytes_read < 0) {
- if (errno == EINTR)
- continue;
- else if (mine->filename_type == FNT_STDIN)
- archive_set_error(a, errno,
- "Error reading stdin");
- else if (mine->filename_type == FNT_MBS)
- archive_set_error(a, errno,
- "Error reading '%s'", mine->filename.m);
- else
- archive_set_error(a, errno,
- "Error reading '%S'", mine->filename.w);
- }
- return (bytes_read);
- }
-}
-
-/*
- * Regular files and disk-like block devices can use simple lseek
- * without needing to round the request to the block size.
- *
- * TODO: This can leave future reads mis-aligned. Since we know the
- * offset here, we should store it and use it in file_read() above
- * to determine whether we should perform a short read to get back
- * into alignment. Long series of mis-aligned reads can negatively
- * impact disk throughput. (Of course, the performance impact should
- * be carefully tested; extra code complexity is only worthwhile if
- * it does provide measurable improvement.)
- *
- * TODO: Be lazy about the actual seek. There are a few pathological
- * cases where libarchive makes a bunch of seek requests in a row
- * without any intervening reads. This isn't a huge performance
- * problem, since the kernel handles seeks lazily already, but
- * it would be very slightly faster if we simply remembered the
- * seek request here and then actually performed the seek at the
- * top of the read callback above.
- */
-static int64_t
-file_skip_lseek(struct archive *a, void *client_data, int64_t request)
-{
- struct read_file_data *mine = (struct read_file_data *)client_data;
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* We use _lseeki64() on Windows. */
- int64_t old_offset, new_offset;
-#else
- off_t old_offset, new_offset;
-#endif
-
- /* We use off_t here because lseek() is declared that way. */
-
- /* TODO: Deal with case where off_t isn't 64 bits.
- * This shouldn't be a problem on Linux or other POSIX
- * systems, since the configuration logic for libarchive
- * tries to obtain a 64-bit off_t.
- */
- if ((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0 &&
- (new_offset = lseek(mine->fd, request, SEEK_CUR)) >= 0)
- return (new_offset - old_offset);
-
- /* If lseek() fails, don't bother trying again. */
- mine->use_lseek = 0;
-
- /* Let libarchive recover with read+discard */
- if (errno == ESPIPE)
- return (0);
-
- /* If the input is corrupted or truncated, fail. */
- if (mine->filename_type == FNT_STDIN)
- archive_set_error(a, errno, "Error seeking in stdin");
- else if (mine->filename_type == FNT_MBS)
- archive_set_error(a, errno, "Error seeking in '%s'",
- mine->filename.m);
- else
- archive_set_error(a, errno, "Error seeking in '%S'",
- mine->filename.w);
- return (-1);
-}
-
-
-/*
- * TODO: Implement another file_skip_XXXX that uses MTIO ioctls to
- * accelerate operation on tape drives.
- */
-
-static int64_t
-file_skip(struct archive *a, void *client_data, int64_t request)
-{
- struct read_file_data *mine = (struct read_file_data *)client_data;
-
- /* Delegate skip requests. */
- if (mine->use_lseek)
- return (file_skip_lseek(a, client_data, request));
-
- /* If we can't skip, return 0; libarchive will read+discard instead. */
- return (0);
-}
-
-/*
- * TODO: Store the offset and use it in the read callback.
- */
-static int64_t
-file_seek(struct archive *a, void *client_data, int64_t request, int whence)
-{
- struct read_file_data *mine = (struct read_file_data *)client_data;
- int64_t r;
-
- /* We use off_t here because lseek() is declared that way. */
- /* See above for notes about when off_t is less than 64 bits. */
- r = lseek(mine->fd, request, whence);
- if (r >= 0)
- return r;
-
- /* If the input is corrupted or truncated, fail. */
- if (mine->filename_type == FNT_STDIN)
- archive_set_error(a, errno, "Error seeking in stdin");
- else if (mine->filename_type == FNT_MBS)
- archive_set_error(a, errno, "Error seeking in '%s'",
- mine->filename.m);
- else
- archive_set_error(a, errno, "Error seeking in '%S'",
- mine->filename.w);
- return (ARCHIVE_FATAL);
-}
-
-static int
-file_close2(struct archive *a, void *client_data)
-{
- struct read_file_data *mine = (struct read_file_data *)client_data;
-
- (void)a; /* UNUSED */
-
- /* Only flush and close if open succeeded. */
- if (mine->fd >= 0) {
- /*
- * Sometimes, we should flush the input before closing.
- * Regular files: faster to just close without flush.
- * Disk-like devices: Ditto.
- * Tapes: must not flush (user might need to
- * read the "next" item on a non-rewind device).
- * Pipes and sockets: must flush (otherwise, the
- * program feeding the pipe or socket may complain).
- * Here, I flush everything except for regular files and
- * device nodes.
- */
- if (!S_ISREG(mine->st_mode)
- && !S_ISCHR(mine->st_mode)
- && !S_ISBLK(mine->st_mode)) {
- ssize_t bytesRead;
- do {
- bytesRead = read(mine->fd, mine->buffer,
- mine->block_size);
- } while (bytesRead > 0);
- }
- /* If a named file was opened, then it needs to be closed. */
- if (mine->filename_type != FNT_STDIN)
- close(mine->fd);
- }
- free(mine->buffer);
- mine->buffer = NULL;
- mine->fd = -1;
- return (ARCHIVE_OK);
-}
-
-static int
-file_close(struct archive *a, void *client_data)
-{
- struct read_file_data *mine = (struct read_file_data *)client_data;
- file_close2(a, client_data);
- free(mine);
- return (ARCHIVE_OK);
-}
-
-static int
-file_switch(struct archive *a, void *client_data1, void *client_data2)
-{
- file_close2(a, client_data1);
- return file_open(a, client_data2);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_open_memory.c b/contrib/libs/libarchive/libarchive/archive_read_open_memory.c
deleted file mode 100644
index 311be47046..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_open_memory.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_open_memory.c,v 1.6 2007/07/06 15:51:59 kientzle Exp $");
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "archive.h"
-
-/*
- * Glue to read an archive from a block of memory.
- *
- * This is mostly a huge help in building test harnesses;
- * test programs can build archives in memory and read them
- * back again without having to mess with files on disk.
- */
-
-struct read_memory_data {
- const unsigned char *start;
- const unsigned char *p;
- const unsigned char *end;
- ssize_t read_size;
-};
-
-static int memory_read_close(struct archive *, void *);
-static int memory_read_open(struct archive *, void *);
-static int64_t memory_read_seek(struct archive *, void *, int64_t offset, int whence);
-static int64_t memory_read_skip(struct archive *, void *, int64_t request);
-static ssize_t memory_read(struct archive *, void *, const void **buff);
-
-int
-archive_read_open_memory(struct archive *a, const void *buff, size_t size)
-{
- return archive_read_open_memory2(a, buff, size, size);
-}
-
-/*
- * Don't use _open_memory2() in production code; the archive_read_open_memory()
- * version is the one you really want. This is just here so that
- * test harnesses can exercise block operations inside the library.
- */
-int
-archive_read_open_memory2(struct archive *a, const void *buff,
- size_t size, size_t read_size)
-{
- struct read_memory_data *mine;
-
- mine = (struct read_memory_data *)calloc(1, sizeof(*mine));
- if (mine == NULL) {
- archive_set_error(a, ENOMEM, "No memory");
- return (ARCHIVE_FATAL);
- }
- mine->start = mine->p = (const unsigned char *)buff;
- mine->end = mine->start + size;
- mine->read_size = read_size;
- archive_read_set_open_callback(a, memory_read_open);
- archive_read_set_read_callback(a, memory_read);
- archive_read_set_seek_callback(a, memory_read_seek);
- archive_read_set_skip_callback(a, memory_read_skip);
- archive_read_set_close_callback(a, memory_read_close);
- archive_read_set_callback_data(a, mine);
- return (archive_read_open1(a));
-}
-
-/*
- * There's nothing to open.
- */
-static int
-memory_read_open(struct archive *a, void *client_data)
-{
- (void)a; /* UNUSED */
- (void)client_data; /* UNUSED */
- return (ARCHIVE_OK);
-}
-
-/*
- * This is scary simple: Just advance a pointer. Limiting
- * to read_size is not technically necessary, but it exercises
- * more of the internal logic when used with a small block size
- * in a test harness. Production use should not specify a block
- * size; then this is much faster.
- */
-static ssize_t
-memory_read(struct archive *a, void *client_data, const void **buff)
-{
- struct read_memory_data *mine = (struct read_memory_data *)client_data;
- ssize_t size;
-
- (void)a; /* UNUSED */
- *buff = mine->p;
- size = mine->end - mine->p;
- if (size > mine->read_size)
- size = mine->read_size;
- mine->p += size;
- return (size);
-}
-
-/*
- * Advancing is just as simple. Again, this is doing more than
- * necessary in order to better exercise internal code when used
- * as a test harness.
- */
-static int64_t
-memory_read_skip(struct archive *a, void *client_data, int64_t skip)
-{
- struct read_memory_data *mine = (struct read_memory_data *)client_data;
-
- (void)a; /* UNUSED */
- if ((int64_t)skip > (int64_t)(mine->end - mine->p))
- skip = mine->end - mine->p;
- /* Round down to block size. */
- skip /= mine->read_size;
- skip *= mine->read_size;
- mine->p += skip;
- return (skip);
-}
-
-/*
- * Seeking.
- */
-static int64_t
-memory_read_seek(struct archive *a, void *client_data, int64_t offset, int whence)
-{
- struct read_memory_data *mine = (struct read_memory_data *)client_data;
-
- (void)a; /* UNUSED */
- switch (whence) {
- case SEEK_SET:
- mine->p = mine->start + offset;
- break;
- case SEEK_CUR:
- mine->p += offset;
- break;
- case SEEK_END:
- mine->p = mine->end + offset;
- break;
- default:
- return ARCHIVE_FATAL;
- }
- if (mine->p < mine->start) {
- mine->p = mine->start;
- return ARCHIVE_FAILED;
- }
- if (mine->p > mine->end) {
- mine->p = mine->end;
- return ARCHIVE_FAILED;
- }
- return (mine->p - mine->start);
-}
-
-/*
- * Close is just cleaning up our one small bit of data.
- */
-static int
-memory_read_close(struct archive *a, void *client_data)
-{
- struct read_memory_data *mine = (struct read_memory_data *)client_data;
- (void)a; /* UNUSED */
- free(mine);
- return (ARCHIVE_OK);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_private.h b/contrib/libs/libarchive/libarchive/archive_read_private.h
deleted file mode 100644
index 383405d529..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_private.h
+++ /dev/null
@@ -1,267 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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.
- *
- * $FreeBSD: head/lib/libarchive/archive_read_private.h 201088 2009-12-28 02:18:55Z kientzle $
- */
-
-#ifndef ARCHIVE_READ_PRIVATE_H_INCLUDED
-#define ARCHIVE_READ_PRIVATE_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#ifndef __LIBARCHIVE_TEST
-#error This header is only to be used internally to libarchive.
-#endif
-#endif
-
-#include "archive.h"
-#include "archive_string.h"
-#include "archive_private.h"
-
-struct archive_read;
-struct archive_read_filter_bidder;
-struct archive_read_filter;
-
-struct archive_read_filter_bidder_vtable {
- /* Taste the upstream filter to see if we handle this. */
- int (*bid)(struct archive_read_filter_bidder *,
- struct archive_read_filter *);
- /* Initialize a newly-created filter. */
- int (*init)(struct archive_read_filter *);
- /* Release the bidder's configuration data. */
- void (*free)(struct archive_read_filter_bidder *);
-};
-
-/*
- * How bidding works for filters:
- * * The bid manager initializes the client-provided reader as the
- * first filter.
- * * It invokes the bidder for each registered filter with the
- * current head filter.
- * * The bidders can use archive_read_filter_ahead() to peek ahead
- * at the incoming data to compose their bids.
- * * The bid manager creates a new filter structure for the winning
- * bidder and gives the winning bidder a chance to initialize it.
- * * The new filter becomes the new top filter and we repeat the
- * process.
- * This ends only when no bidder provides a non-zero bid. Then
- * we perform a similar dance with the registered format handlers.
- */
-struct archive_read_filter_bidder {
- /* Configuration data for the bidder. */
- void *data;
- /* Name of the filter */
- const char *name;
- const struct archive_read_filter_bidder_vtable *vtable;
-};
-
-struct archive_read_filter_vtable {
- /* Return next block. */
- ssize_t (*read)(struct archive_read_filter *, const void **);
- /* Close (just this filter) and free(self). */
- int (*close)(struct archive_read_filter *self);
- /* Read any header metadata if available. */
- int (*read_header)(struct archive_read_filter *self, struct archive_entry *entry);
-};
-
-/*
- * This structure is allocated within the archive_read core
- * and initialized by archive_read and the init() method of the
- * corresponding bidder above.
- */
-struct archive_read_filter {
- int64_t position;
- /* Essentially all filters will need these values, so
- * just declare them here. */
- struct archive_read_filter_bidder *bidder; /* My bidder. */
- struct archive_read_filter *upstream; /* Who I read from. */
- struct archive_read *archive; /* Associated archive. */
- const struct archive_read_filter_vtable *vtable;
- /* My private data. */
- void *data;
-
- const char *name;
- int code;
- int can_skip;
- int can_seek;
-
- /* Used by reblocking logic. */
- char *buffer;
- size_t buffer_size;
- char *next; /* Current read location. */
- size_t avail; /* Bytes in my buffer. */
- const void *client_buff; /* Client buffer information. */
- size_t client_total;
- const char *client_next;
- size_t client_avail;
- char end_of_file;
- char closed;
- char fatal;
-};
-
-/*
- * The client looks a lot like a filter, so we just wrap it here.
- *
- * TODO: Make archive_read_filter and archive_read_client identical so
- * that users of the library can easily register their own
- * transformation filters. This will probably break the API/ABI and
- * so should be deferred at least until libarchive 3.0.
- */
-struct archive_read_data_node {
- int64_t begin_position;
- int64_t total_size;
- void *data;
-};
-struct archive_read_client {
- archive_open_callback *opener;
- archive_read_callback *reader;
- archive_skip_callback *skipper;
- archive_seek_callback *seeker;
- archive_close_callback *closer;
- archive_switch_callback *switcher;
- unsigned int nodes;
- unsigned int cursor;
- int64_t position;
- struct archive_read_data_node *dataset;
-};
-struct archive_read_passphrase {
- char *passphrase;
- struct archive_read_passphrase *next;
-};
-
-struct archive_read_extract {
- struct archive *ad; /* archive_write_disk object */
-
- /* Progress function invoked during extract. */
- void (*extract_progress)(void *);
- void *extract_progress_user_data;
-};
-
-struct archive_read {
- struct archive archive;
-
- struct archive_entry *entry;
-
- /* Dev/ino of the archive being read/written. */
- int skip_file_set;
- int64_t skip_file_dev;
- int64_t skip_file_ino;
-
- /* Callbacks to open/read/write/close client archive streams. */
- struct archive_read_client client;
-
- /* Registered filter bidders. */
- struct archive_read_filter_bidder bidders[16];
-
- /* Last filter in chain */
- struct archive_read_filter *filter;
-
- /* Whether to bypass filter bidding process */
- int bypass_filter_bidding;
-
- /* File offset of beginning of most recently-read header. */
- int64_t header_position;
-
- /* Nodes and offsets of compressed data block */
- unsigned int data_start_node;
- unsigned int data_end_node;
-
- /*
- * Format detection is mostly the same as compression
- * detection, with one significant difference: The bidders
- * use the read_ahead calls above to examine the stream rather
- * than having the supervisor hand them a block of data to
- * examine.
- */
-
- struct archive_format_descriptor {
- void *data;
- const char *name;
- int (*bid)(struct archive_read *, int best_bid);
- int (*options)(struct archive_read *, const char *key,
- const char *value);
- int (*read_header)(struct archive_read *, struct archive_entry *);
- int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *);
- int (*read_data_skip)(struct archive_read *);
- int64_t (*seek_data)(struct archive_read *, int64_t, int);
- int (*cleanup)(struct archive_read *);
- int (*format_capabilties)(struct archive_read *);
- int (*has_encrypted_entries)(struct archive_read *);
- } formats[16];
- struct archive_format_descriptor *format; /* Active format. */
-
- /*
- * Various information needed by archive_extract.
- */
- struct archive_read_extract *extract;
- int (*cleanup_archive_extract)(struct archive_read *);
-
- /*
- * Decryption passphrase.
- */
- struct {
- struct archive_read_passphrase *first;
- struct archive_read_passphrase **last;
- int candidate;
- archive_passphrase_callback *callback;
- void *client_data;
- } passphrases;
-};
-
-int __archive_read_register_format(struct archive_read *a,
- void *format_data,
- const char *name,
- int (*bid)(struct archive_read *, int),
- int (*options)(struct archive_read *, const char *, const char *),
- int (*read_header)(struct archive_read *, struct archive_entry *),
- int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
- int (*read_data_skip)(struct archive_read *),
- int64_t (*seek_data)(struct archive_read *, int64_t, int),
- int (*cleanup)(struct archive_read *),
- int (*format_capabilities)(struct archive_read *),
- int (*has_encrypted_entries)(struct archive_read *));
-
-int __archive_read_register_bidder(struct archive_read *a,
- void *bidder_data,
- const char *name,
- const struct archive_read_filter_bidder_vtable *vtable);
-
-const void *__archive_read_ahead(struct archive_read *, size_t, ssize_t *);
-const void *__archive_read_filter_ahead(struct archive_read_filter *,
- size_t, ssize_t *);
-int64_t __archive_read_seek(struct archive_read*, int64_t, int);
-int64_t __archive_read_filter_seek(struct archive_read_filter *, int64_t, int);
-int64_t __archive_read_consume(struct archive_read *, int64_t);
-int64_t __archive_read_filter_consume(struct archive_read_filter *, int64_t);
-int __archive_read_header(struct archive_read *, struct archive_entry *);
-int __archive_read_program(struct archive_read_filter *, const char *);
-void __archive_read_free_filters(struct archive_read *);
-struct archive_read_extract *__archive_read_get_extract(struct archive_read *);
-
-
-/*
- * Get a decryption passphrase.
- */
-void __archive_read_reset_passphrase(struct archive_read *a);
-const char * __archive_read_next_passphrase(struct archive_read *a);
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_read_set_format.c b/contrib/libs/libarchive/libarchive/archive_read_set_format.c
deleted file mode 100644
index 796dcdcced..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_set_format.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*-
- * Copyright (c) 2003-2012 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-int
-archive_read_set_format(struct archive *_a, int code)
-{
- int r1, r2, slots, i;
- char str[10];
- struct archive_read *a = (struct archive_read *)_a;
-
- if ((r1 = archive_read_support_format_by_code(_a, code)) < (ARCHIVE_OK))
- return r1;
-
- r1 = r2 = (ARCHIVE_OK);
- if (a->format)
- r2 = (ARCHIVE_WARN);
- switch (code & ARCHIVE_FORMAT_BASE_MASK)
- {
- case ARCHIVE_FORMAT_7ZIP:
- strcpy(str, "7zip");
- break;
- case ARCHIVE_FORMAT_AR:
- strcpy(str, "ar");
- break;
- case ARCHIVE_FORMAT_CAB:
- strcpy(str, "cab");
- break;
- case ARCHIVE_FORMAT_CPIO:
- strcpy(str, "cpio");
- break;
- case ARCHIVE_FORMAT_EMPTY:
- strcpy(str, "empty");
- break;
- case ARCHIVE_FORMAT_ISO9660:
- strcpy(str, "iso9660");
- break;
- case ARCHIVE_FORMAT_LHA:
- strcpy(str, "lha");
- break;
- case ARCHIVE_FORMAT_MTREE:
- strcpy(str, "mtree");
- break;
- case ARCHIVE_FORMAT_RAR:
- strcpy(str, "rar");
- break;
- case ARCHIVE_FORMAT_RAR_V5:
- strcpy(str, "rar5");
- break;
- case ARCHIVE_FORMAT_RAW:
- strcpy(str, "raw");
- break;
- case ARCHIVE_FORMAT_TAR:
- strcpy(str, "tar");
- break;
- case ARCHIVE_FORMAT_WARC:
- strcpy(str, "warc");
- break;
- case ARCHIVE_FORMAT_XAR:
- strcpy(str, "xar");
- break;
- case ARCHIVE_FORMAT_ZIP:
- strcpy(str, "zip");
- break;
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Invalid format code specified");
- return (ARCHIVE_FATAL);
- }
-
- slots = sizeof(a->formats) / sizeof(a->formats[0]);
- a->format = &(a->formats[0]);
- for (i = 0; i < slots; i++, a->format++) {
- if (!a->format->name || !strcmp(a->format->name, str))
- break;
- }
- if (!a->format->name || strcmp(a->format->name, str))
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Internal error: Unable to set format");
- r1 = (ARCHIVE_FATAL);
- }
-
- return (r1 < r2) ? r1 : r2;
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_set_options.c b/contrib/libs/libarchive/libarchive/archive_read_set_options.c
deleted file mode 100644
index 2bd9b811ea..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_set_options.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*-
- * Copyright (c) 2011 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#include "archive_read_private.h"
-#include "archive_options_private.h"
-
-static int archive_set_format_option(struct archive *a,
- const char *m, const char *o, const char *v);
-static int archive_set_filter_option(struct archive *a,
- const char *m, const char *o, const char *v);
-static int archive_set_option(struct archive *a,
- const char *m, const char *o, const char *v);
-
-int
-archive_read_set_format_option(struct archive *a, const char *m, const char *o,
- const char *v)
-{
- return _archive_set_option(a, m, o, v,
- ARCHIVE_READ_MAGIC, "archive_read_set_format_option",
- archive_set_format_option);
-}
-
-int
-archive_read_set_filter_option(struct archive *a, const char *m, const char *o,
- const char *v)
-{
- return _archive_set_option(a, m, o, v,
- ARCHIVE_READ_MAGIC, "archive_read_set_filter_option",
- archive_set_filter_option);
-}
-
-int
-archive_read_set_option(struct archive *a, const char *m, const char *o,
- const char *v)
-{
- return _archive_set_option(a, m, o, v,
- ARCHIVE_READ_MAGIC, "archive_read_set_option",
- archive_set_option);
-}
-
-int
-archive_read_set_options(struct archive *a, const char *options)
-{
- return _archive_set_options(a, options,
- ARCHIVE_READ_MAGIC, "archive_read_set_options",
- archive_set_option);
-}
-
-static int
-archive_set_format_option(struct archive *_a, const char *m, const char *o,
- const char *v)
-{
- struct archive_read *a = (struct archive_read *)_a;
- size_t i;
- int r, rv = ARCHIVE_WARN, matched_modules = 0;
-
- for (i = 0; i < sizeof(a->formats)/sizeof(a->formats[0]); i++) {
- struct archive_format_descriptor *format = &a->formats[i];
-
- if (format->options == NULL || format->name == NULL)
- /* This format does not support option. */
- continue;
- if (m != NULL) {
- if (strcmp(format->name, m) != 0)
- continue;
- ++matched_modules;
- }
-
- a->format = format;
- r = format->options(a, o, v);
- a->format = NULL;
-
- if (r == ARCHIVE_FATAL)
- return (ARCHIVE_FATAL);
-
- if (r == ARCHIVE_OK)
- rv = ARCHIVE_OK;
- }
- /* If the format name didn't match, return a special code for
- * _archive_set_option[s]. */
- if (m != NULL && matched_modules == 0)
- return ARCHIVE_WARN - 1;
- return (rv);
-}
-
-static int
-archive_set_filter_option(struct archive *_a, const char *m, const char *o,
- const char *v)
-{
- (void)_a; /* UNUSED */
- (void)o; /* UNUSED */
- (void)v; /* UNUSED */
-
- /* If the filter name didn't match, return a special code for
- * _archive_set_option[s]. */
- if (m != NULL)
- return ARCHIVE_WARN - 1;
- return ARCHIVE_WARN;
-}
-
-static int
-archive_set_option(struct archive *a, const char *m, const char *o,
- const char *v)
-{
- return _archive_set_either_option(a, m, o, v,
- archive_set_format_option,
- archive_set_filter_option);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_filter_all.c b/contrib/libs/libarchive/libarchive/archive_read_support_filter_all.c
deleted file mode 100644
index edb508c1df..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_filter_all.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*-
- * Copyright (c) 2003-2011 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#include "archive.h"
-#include "archive_private.h"
-
-#if ARCHIVE_VERSION_NUMBER < 4000000
-/* Deprecated; remove in libarchive 4.0 */
-int
-archive_read_support_compression_all(struct archive *a)
-{
- return archive_read_support_filter_all(a);
-}
-#endif
-
-int
-archive_read_support_filter_all(struct archive *a)
-{
- archive_check_magic(a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_filter_all");
-
- /* Bzip falls back to "bunzip2" command-line */
- archive_read_support_filter_bzip2(a);
- /* The decompress code doesn't use an outside library. */
- archive_read_support_filter_compress(a);
- /* Gzip decompress falls back to "gzip -d" command-line. */
- archive_read_support_filter_gzip(a);
- /* Lzip falls back to "unlzip" command-line program. */
- archive_read_support_filter_lzip(a);
- /* The LZMA file format has a very weak signature, so it
- * may not be feasible to keep this here, but we'll try.
- * This will come back out if there are problems. */
- /* Lzma falls back to "unlzma" command-line program. */
- archive_read_support_filter_lzma(a);
- /* Xz falls back to "unxz" command-line program. */
- archive_read_support_filter_xz(a);
- /* The decode code doesn't use an outside library. */
- archive_read_support_filter_uu(a);
- /* The decode code doesn't use an outside library. */
- archive_read_support_filter_rpm(a);
- /* The decode code always uses "lrzip -q -d" command-line. */
- archive_read_support_filter_lrzip(a);
- /* Lzop decompress falls back to "lzop -d" command-line. */
- archive_read_support_filter_lzop(a);
- /* The decode code always uses "grzip -d" command-line. */
- archive_read_support_filter_grzip(a);
- /* Lz4 falls back to "lz4 -d" command-line program. */
- archive_read_support_filter_lz4(a);
- /* Zstd falls back to "zstd -d" command-line program. */
- archive_read_support_filter_zstd(a);
-
- /* Note: We always return ARCHIVE_OK here, even if some of the
- * above return ARCHIVE_WARN. The intent here is to enable
- * "as much as possible." Clients who need specific
- * compression should enable those individually so they can
- * verify the level of support. */
- /* Clear any warning messages set by the above functions. */
- archive_clear_error(a);
- return (ARCHIVE_OK);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_filter_by_code.c b/contrib/libs/libarchive/libarchive/archive_read_support_filter_by_code.c
deleted file mode 100644
index 94c4af695f..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_filter_by_code.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*-
- * Copyright (c) 2020 Martin Matuska
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#include "archive.h"
-#include "archive_private.h"
-
-int
-archive_read_support_filter_by_code(struct archive *a, int filter_code)
-{
- archive_check_magic(a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_filter_by_code");
-
- switch (filter_code) {
- case ARCHIVE_FILTER_NONE:
- return archive_read_support_filter_none(a);
- break;
- case ARCHIVE_FILTER_GZIP:
- return archive_read_support_filter_gzip(a);
- break;
- case ARCHIVE_FILTER_BZIP2:
- return archive_read_support_filter_bzip2(a);
- break;
- case ARCHIVE_FILTER_COMPRESS:
- return archive_read_support_filter_compress(a);
- break;
- case ARCHIVE_FILTER_LZMA:
- return archive_read_support_filter_lzma(a);
- break;
- case ARCHIVE_FILTER_XZ:
- return archive_read_support_filter_xz(a);
- break;
- case ARCHIVE_FILTER_UU:
- return archive_read_support_filter_uu(a);
- break;
- case ARCHIVE_FILTER_RPM:
- return archive_read_support_filter_rpm(a);
- break;
- case ARCHIVE_FILTER_LZIP:
- return archive_read_support_filter_lzip(a);
- break;
- case ARCHIVE_FILTER_LRZIP:
- return archive_read_support_filter_lrzip(a);
- break;
- case ARCHIVE_FILTER_LZOP:
- return archive_read_support_filter_lzop(a);
- break;
- case ARCHIVE_FILTER_GRZIP:
- return archive_read_support_filter_grzip(a);
- break;
- case ARCHIVE_FILTER_LZ4:
- return archive_read_support_filter_lz4(a);
- break;
- case ARCHIVE_FILTER_ZSTD:
- return archive_read_support_filter_zstd(a);
- break;
- }
- return (ARCHIVE_FATAL);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_filter_bzip2.c b/contrib/libs/libarchive/libarchive/archive_read_support_filter_bzip2.c
deleted file mode 100644
index 9158e668eb..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_filter_bzip2.c
+++ /dev/null
@@ -1,365 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_BZLIB_H
-#include <bzlib.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
-struct private_data {
- bz_stream stream;
- char *out_block;
- size_t out_block_size;
- char valid; /* True = decompressor is initialized */
- char eof; /* True = found end of compressed data. */
-};
-
-/* Bzip2 filter */
-static ssize_t bzip2_filter_read(struct archive_read_filter *, const void **);
-static int bzip2_filter_close(struct archive_read_filter *);
-#endif
-
-/*
- * Note that we can detect bzip2 archives even if we can't decompress
- * them. (In fact, we like detecting them because we can give better
- * error messages.) So the bid framework here gets compiled even
- * if bzlib is unavailable.
- */
-static int bzip2_reader_bid(struct archive_read_filter_bidder *, struct archive_read_filter *);
-static int bzip2_reader_init(struct archive_read_filter *);
-
-#if ARCHIVE_VERSION_NUMBER < 4000000
-/* Deprecated; remove in libarchive 4.0 */
-int
-archive_read_support_compression_bzip2(struct archive *a)
-{
- return archive_read_support_filter_bzip2(a);
-}
-#endif
-
-static const struct archive_read_filter_bidder_vtable
-bzip2_bidder_vtable = {
- .bid = bzip2_reader_bid,
- .init = bzip2_reader_init,
-};
-
-int
-archive_read_support_filter_bzip2(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
-
- if (__archive_read_register_bidder(a, NULL, "bzip2",
- &bzip2_bidder_vtable) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
-#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
- return (ARCHIVE_OK);
-#else
- archive_set_error(_a, ARCHIVE_ERRNO_MISC,
- "Using external bzip2 program");
- return (ARCHIVE_WARN);
-#endif
-}
-
-/*
- * Test whether we can handle this data.
- *
- * This logic returns zero if any part of the signature fails. It
- * also tries to Do The Right Thing if a very short buffer prevents us
- * from verifying as much as we would like.
- */
-static int
-bzip2_reader_bid(struct archive_read_filter_bidder *self, struct archive_read_filter *filter)
-{
- const unsigned char *buffer;
- ssize_t avail;
- int bits_checked;
-
- (void)self; /* UNUSED */
-
- /* Minimal bzip2 archive is 14 bytes. */
- buffer = __archive_read_filter_ahead(filter, 14, &avail);
- if (buffer == NULL)
- return (0);
-
- /* First three bytes must be "BZh" */
- bits_checked = 0;
- if (memcmp(buffer, "BZh", 3) != 0)
- return (0);
- bits_checked += 24;
-
- /* Next follows a compression flag which must be an ASCII digit. */
- if (buffer[3] < '1' || buffer[3] > '9')
- return (0);
- bits_checked += 5;
-
- /* After BZh[1-9], there must be either a data block
- * which begins with 0x314159265359 or an end-of-data
- * marker of 0x177245385090. */
- if (memcmp(buffer + 4, "\x31\x41\x59\x26\x53\x59", 6) == 0)
- bits_checked += 48;
- else if (memcmp(buffer + 4, "\x17\x72\x45\x38\x50\x90", 6) == 0)
- bits_checked += 48;
- else
- return (0);
-
- return (bits_checked);
-}
-
-#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR)
-
-/*
- * If we don't have the library on this system, we can't actually do the
- * decompression. We can, however, still detect compressed archives
- * and emit a useful message.
- */
-static int
-bzip2_reader_init(struct archive_read_filter *self)
-{
- int r;
-
- r = __archive_read_program(self, "bzip2 -d");
- /* Note: We set the format here even if __archive_read_program()
- * above fails. We do, after all, know what the format is
- * even if we weren't able to read it. */
- self->code = ARCHIVE_FILTER_BZIP2;
- self->name = "bzip2";
- return (r);
-}
-
-
-#else
-
-static const struct archive_read_filter_vtable
-bzip2_reader_vtable = {
- .read = bzip2_filter_read,
- .close = bzip2_filter_close,
-};
-
-/*
- * Setup the callbacks.
- */
-static int
-bzip2_reader_init(struct archive_read_filter *self)
-{
- static const size_t out_block_size = 64 * 1024;
- void *out_block;
- struct private_data *state;
-
- self->code = ARCHIVE_FILTER_BZIP2;
- self->name = "bzip2";
-
- state = (struct private_data *)calloc(sizeof(*state), 1);
- out_block = (unsigned char *)malloc(out_block_size);
- if (state == NULL || out_block == NULL) {
- archive_set_error(&self->archive->archive, ENOMEM,
- "Can't allocate data for bzip2 decompression");
- free(out_block);
- free(state);
- return (ARCHIVE_FATAL);
- }
-
- self->data = state;
- state->out_block_size = out_block_size;
- state->out_block = out_block;
- self->vtable = &bzip2_reader_vtable;
-
- return (ARCHIVE_OK);
-}
-
-/*
- * Return the next block of decompressed data.
- */
-static ssize_t
-bzip2_filter_read(struct archive_read_filter *self, const void **p)
-{
- struct private_data *state;
- size_t decompressed;
- const char *read_buf;
- ssize_t ret;
-
- state = (struct private_data *)self->data;
-
- if (state->eof) {
- *p = NULL;
- return (0);
- }
-
- /* Empty our output buffer. */
- state->stream.next_out = state->out_block;
- state->stream.avail_out = (uint32_t)state->out_block_size;
-
- /* Try to fill the output buffer. */
- for (;;) {
- if (!state->valid) {
- if (bzip2_reader_bid(self->bidder, self->upstream) == 0) {
- state->eof = 1;
- *p = state->out_block;
- decompressed = state->stream.next_out
- - state->out_block;
- return (decompressed);
- }
- /* Initialize compression library. */
- ret = BZ2_bzDecompressInit(&(state->stream),
- 0 /* library verbosity */,
- 0 /* don't use low-mem algorithm */);
-
- /* If init fails, try low-memory algorithm instead. */
- if (ret == BZ_MEM_ERROR)
- ret = BZ2_bzDecompressInit(&(state->stream),
- 0 /* library verbosity */,
- 1 /* do use low-mem algo */);
-
- if (ret != BZ_OK) {
- const char *detail = NULL;
- int err = ARCHIVE_ERRNO_MISC;
- switch (ret) {
- case BZ_PARAM_ERROR:
- detail = "invalid setup parameter";
- break;
- case BZ_MEM_ERROR:
- err = ENOMEM;
- detail = "out of memory";
- break;
- case BZ_CONFIG_ERROR:
- detail = "mis-compiled library";
- break;
- }
- archive_set_error(&self->archive->archive, err,
- "Internal error initializing decompressor%s%s",
- detail == NULL ? "" : ": ",
- detail);
- return (ARCHIVE_FATAL);
- }
- state->valid = 1;
- }
-
- /* stream.next_in is really const, but bzlib
- * doesn't declare it so. <sigh> */
- read_buf =
- __archive_read_filter_ahead(self->upstream, 1, &ret);
- if (read_buf == NULL) {
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "truncated bzip2 input");
- return (ARCHIVE_FATAL);
- }
- state->stream.next_in = (char *)(uintptr_t)read_buf;
- state->stream.avail_in = (uint32_t)ret;
- /* There is no more data, return whatever we have. */
- if (ret == 0) {
- state->eof = 1;
- *p = state->out_block;
- decompressed = state->stream.next_out
- - state->out_block;
- return (decompressed);
- }
-
- /* Decompress as much as we can in one pass. */
- ret = BZ2_bzDecompress(&(state->stream));
- __archive_read_filter_consume(self->upstream,
- state->stream.next_in - read_buf);
-
- switch (ret) {
- case BZ_STREAM_END: /* Found end of stream. */
- switch (BZ2_bzDecompressEnd(&(state->stream))) {
- case BZ_OK:
- break;
- default:
- archive_set_error(&(self->archive->archive),
- ARCHIVE_ERRNO_MISC,
- "Failed to clean up decompressor");
- return (ARCHIVE_FATAL);
- }
- state->valid = 0;
- /* FALLTHROUGH */
- case BZ_OK: /* Decompressor made some progress. */
- /* If we filled our buffer, update stats and return. */
- if (state->stream.avail_out == 0) {
- *p = state->out_block;
- decompressed = state->stream.next_out
- - state->out_block;
- return (decompressed);
- }
- break;
- default: /* Return an error. */
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC, "bzip decompression failed");
- return (ARCHIVE_FATAL);
- }
- }
-}
-
-/*
- * Clean up the decompressor.
- */
-static int
-bzip2_filter_close(struct archive_read_filter *self)
-{
- struct private_data *state;
- int ret = ARCHIVE_OK;
-
- state = (struct private_data *)self->data;
-
- if (state->valid) {
- switch (BZ2_bzDecompressEnd(&state->stream)) {
- case BZ_OK:
- break;
- default:
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Failed to clean up decompressor");
- ret = ARCHIVE_FATAL;
- }
- state->valid = 0;
- }
-
- free(state->out_block);
- free(state);
- return (ret);
-}
-
-#endif /* HAVE_BZLIB_H && BZ_CONFIG_ERROR */
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_filter_compress.c b/contrib/libs/libarchive/libarchive/archive_read_support_filter_compress.c
deleted file mode 100644
index 05b80a576a..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_filter_compress.c
+++ /dev/null
@@ -1,452 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * This code borrows heavily from "compress" source code, which is
- * protected by the following copyright. (Clause 3 dropped by request
- * of the Regents.)
- */
-
-/*-
- * Copyright (c) 1985, 1986, 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Diomidis Spinellis and James A. Woods, derived from original
- * work by Spencer Thomas and Joseph Orost.
- *
- * 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.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-/*
- * Because LZW decompression is pretty simple, I've just implemented
- * the whole decompressor here (cribbing from "compress" source code,
- * of course), rather than relying on an external library. I have
- * made an effort to clarify and simplify the algorithm, so the
- * names and structure here don't exactly match those used by compress.
- */
-
-struct private_data {
- /* Input variables. */
- const unsigned char *next_in;
- size_t avail_in;
- size_t consume_unnotified;
- int bit_buffer;
- int bits_avail;
- size_t bytes_in_section;
-
- /* Output variables. */
- size_t out_block_size;
- void *out_block;
-
- /* Decompression status variables. */
- int use_reset_code;
- int end_of_stream; /* EOF status. */
- int maxcode; /* Largest code. */
- int maxcode_bits; /* Length of largest code. */
- int section_end_code; /* When to increase bits. */
- int bits; /* Current code length. */
- int oldcode; /* Previous code. */
- int finbyte; /* Last byte of prev code. */
-
- /* Dictionary. */
- int free_ent; /* Next dictionary entry. */
- unsigned char suffix[65536];
- uint16_t prefix[65536];
-
- /*
- * Scratch area for expanding dictionary entries. Note:
- * "worst" case here comes from compressing /dev/zero: the
- * last code in the dictionary will code a sequence of
- * 65536-256 zero bytes. Thus, we need stack space to expand
- * a 65280-byte dictionary entry. (Of course, 32640:1
- * compression could also be considered the "best" case. ;-)
- */
- unsigned char *stackp;
- unsigned char stack[65300];
-};
-
-static int compress_bidder_bid(struct archive_read_filter_bidder *, struct archive_read_filter *);
-static int compress_bidder_init(struct archive_read_filter *);
-
-static ssize_t compress_filter_read(struct archive_read_filter *, const void **);
-static int compress_filter_close(struct archive_read_filter *);
-
-static int getbits(struct archive_read_filter *, int n);
-static int next_code(struct archive_read_filter *);
-
-#if ARCHIVE_VERSION_NUMBER < 4000000
-/* Deprecated; remove in libarchive 4.0 */
-int
-archive_read_support_compression_compress(struct archive *a)
-{
- return archive_read_support_filter_compress(a);
-}
-#endif
-
-static const struct archive_read_filter_bidder_vtable
-compress_bidder_vtable = {
- .bid = compress_bidder_bid,
- .init = compress_bidder_init,
-};
-
-int
-archive_read_support_filter_compress(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
-
- return __archive_read_register_bidder(a, NULL, "compress (.Z)",
- &compress_bidder_vtable);
-}
-
-/*
- * Test whether we can handle this data.
- * This logic returns zero if any part of the signature fails.
- */
-static int
-compress_bidder_bid(struct archive_read_filter_bidder *self,
- struct archive_read_filter *filter)
-{
- const unsigned char *buffer;
- ssize_t avail;
- int bits_checked;
-
- (void)self; /* UNUSED */
-
- /* Shortest valid compress file is 3 bytes. */
- buffer = __archive_read_filter_ahead(filter, 3, &avail);
-
- if (buffer == NULL)
- return (0);
-
- bits_checked = 0;
- /* First two bytes are the magic value */
- if (buffer[0] != 0x1F || buffer[1] != 0x9D)
- return (0);
- /* Third byte holds compression parameters. */
- if (buffer[2] & 0x20) /* Reserved bit, must be zero. */
- return (0);
- if (buffer[2] & 0x40) /* Reserved bit, must be zero. */
- return (0);
- bits_checked += 18;
-
- return (bits_checked);
-}
-
-static const struct archive_read_filter_vtable
-compress_reader_vtable = {
- .read = compress_filter_read,
- .close = compress_filter_close,
-};
-
-/*
- * Setup the callbacks.
- */
-static int
-compress_bidder_init(struct archive_read_filter *self)
-{
- struct private_data *state;
- static const size_t out_block_size = 64 * 1024;
- void *out_block;
- int code;
-
- self->code = ARCHIVE_FILTER_COMPRESS;
- self->name = "compress (.Z)";
-
- state = (struct private_data *)calloc(sizeof(*state), 1);
- out_block = malloc(out_block_size);
- if (state == NULL || out_block == NULL) {
- free(out_block);
- free(state);
- archive_set_error(&self->archive->archive, ENOMEM,
- "Can't allocate data for %s decompression",
- self->name);
- return (ARCHIVE_FATAL);
- }
-
- self->data = state;
- state->out_block_size = out_block_size;
- state->out_block = out_block;
- self->vtable = &compress_reader_vtable;
-
- /* XXX MOVE THE FOLLOWING OUT OF INIT() XXX */
-
- (void)getbits(self, 8); /* Skip first signature byte. */
- (void)getbits(self, 8); /* Skip second signature byte. */
-
- /* Get compression parameters. */
- code = getbits(self, 8);
- if ((code & 0x1f) > 16) {
- archive_set_error(&self->archive->archive, -1,
- "Invalid compressed data");
- return (ARCHIVE_FATAL);
- }
- state->maxcode_bits = code & 0x1f;
- state->maxcode = (1 << state->maxcode_bits);
- state->use_reset_code = code & 0x80;
-
- /* Initialize decompressor. */
- state->free_ent = 256;
- state->stackp = state->stack;
- if (state->use_reset_code)
- state->free_ent++;
- state->bits = 9;
- state->section_end_code = (1<<state->bits) - 1;
- state->oldcode = -1;
- for (code = 255; code >= 0; code--) {
- state->prefix[code] = 0;
- state->suffix[code] = code;
- }
- next_code(self);
-
- return (ARCHIVE_OK);
-}
-
-/*
- * Return a block of data from the decompression buffer. Decompress more
- * as necessary.
- */
-static ssize_t
-compress_filter_read(struct archive_read_filter *self, const void **pblock)
-{
- struct private_data *state;
- unsigned char *p, *start, *end;
- int ret;
-
- state = (struct private_data *)self->data;
- if (state->end_of_stream) {
- *pblock = NULL;
- return (0);
- }
- p = start = (unsigned char *)state->out_block;
- end = start + state->out_block_size;
-
- while (p < end && !state->end_of_stream) {
- if (state->stackp > state->stack) {
- *p++ = *--state->stackp;
- } else {
- ret = next_code(self);
- if (ret == -1)
- state->end_of_stream = ret;
- else if (ret != ARCHIVE_OK)
- return (ret);
- }
- }
-
- *pblock = start;
- return (p - start);
-}
-
-/*
- * Close and release the filter.
- */
-static int
-compress_filter_close(struct archive_read_filter *self)
-{
- struct private_data *state = (struct private_data *)self->data;
-
- free(state->out_block);
- free(state);
- return (ARCHIVE_OK);
-}
-
-/*
- * Process the next code and fill the stack with the expansion
- * of the code. Returns ARCHIVE_FATAL if there is a fatal I/O or
- * format error, ARCHIVE_EOF if we hit end of data, ARCHIVE_OK otherwise.
- */
-static int
-next_code(struct archive_read_filter *self)
-{
- struct private_data *state = (struct private_data *)self->data;
- int code, newcode;
-
- static int debug_buff[1024];
- static unsigned debug_index;
-
- code = newcode = getbits(self, state->bits);
- if (code < 0)
- return (code);
-
- debug_buff[debug_index++] = code;
- if (debug_index >= sizeof(debug_buff)/sizeof(debug_buff[0]))
- debug_index = 0;
-
- /* If it's a reset code, reset the dictionary. */
- if ((code == 256) && state->use_reset_code) {
- /*
- * The original 'compress' implementation blocked its
- * I/O in a manner that resulted in junk bytes being
- * inserted after every reset. The next section skips
- * this junk. (Yes, the number of *bytes* to skip is
- * a function of the current *bit* length.)
- */
- int skip_bytes = state->bits -
- (state->bytes_in_section % state->bits);
- skip_bytes %= state->bits;
- state->bits_avail = 0; /* Discard rest of this byte. */
- while (skip_bytes-- > 0) {
- code = getbits(self, 8);
- if (code < 0)
- return (code);
- }
- /* Now, actually do the reset. */
- state->bytes_in_section = 0;
- state->bits = 9;
- state->section_end_code = (1 << state->bits) - 1;
- state->free_ent = 257;
- state->oldcode = -1;
- return (next_code(self));
- }
-
- if (code > state->free_ent
- || (code == state->free_ent && state->oldcode < 0)) {
- /* An invalid code is a fatal error. */
- archive_set_error(&(self->archive->archive), -1,
- "Invalid compressed data");
- return (ARCHIVE_FATAL);
- }
-
- /* Special case for KwKwK string. */
- if (code >= state->free_ent) {
- *state->stackp++ = state->finbyte;
- code = state->oldcode;
- }
-
- /* Generate output characters in reverse order. */
- while (code >= 256) {
- *state->stackp++ = state->suffix[code];
- code = state->prefix[code];
- }
- *state->stackp++ = state->finbyte = code;
-
- /* Generate the new entry. */
- code = state->free_ent;
- if (code < state->maxcode && state->oldcode >= 0) {
- state->prefix[code] = state->oldcode;
- state->suffix[code] = state->finbyte;
- ++state->free_ent;
- }
- if (state->free_ent > state->section_end_code) {
- state->bits++;
- state->bytes_in_section = 0;
- if (state->bits == state->maxcode_bits)
- state->section_end_code = state->maxcode;
- else
- state->section_end_code = (1 << state->bits) - 1;
- }
-
- /* Remember previous code. */
- state->oldcode = newcode;
- return (ARCHIVE_OK);
-}
-
-/*
- * Return next 'n' bits from stream.
- *
- * -1 indicates end of available data.
- */
-static int
-getbits(struct archive_read_filter *self, int n)
-{
- struct private_data *state = (struct private_data *)self->data;
- int code;
- ssize_t ret;
- static const int mask[] = {
- 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff,
- 0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff, 0x3fff, 0x7fff, 0xffff
- };
-
- while (state->bits_avail < n) {
- if (state->avail_in <= 0) {
- if (state->consume_unnotified) {
- __archive_read_filter_consume(self->upstream,
- state->consume_unnotified);
- state->consume_unnotified = 0;
- }
- state->next_in
- = __archive_read_filter_ahead(self->upstream,
- 1, &ret);
- if (ret == 0)
- return (-1);
- if (ret < 0 || state->next_in == NULL)
- return (ARCHIVE_FATAL);
- state->consume_unnotified = state->avail_in = ret;
- }
- state->bit_buffer |= *state->next_in++ << state->bits_avail;
- state->avail_in--;
- state->bits_avail += 8;
- state->bytes_in_section++;
- }
-
- code = state->bit_buffer;
- state->bit_buffer >>= n;
- state->bits_avail -= n;
-
- return (code & mask[n]);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_filter_grzip.c b/contrib/libs/libarchive/libarchive/archive_read_support_filter_grzip.c
deleted file mode 100644
index d4d1737cd9..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_filter_grzip.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/*-
- * Copyright (c) 2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-__FBSDID("$FreeBSD$");
-
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-static const unsigned char grzip_magic[] = {
- 0x47, 0x52, 0x5a, 0x69, 0x70, 0x49, 0x49, 0x00,
- 0x02, 0x04, 0x3a, 0x29 };
-
-static int grzip_bidder_bid(struct archive_read_filter_bidder *,
- struct archive_read_filter *);
-static int grzip_bidder_init(struct archive_read_filter *);
-
-
-static const struct archive_read_filter_bidder_vtable
-grzip_bidder_vtable = {
- .bid = grzip_bidder_bid,
- .init = grzip_bidder_init,
-};
-
-int
-archive_read_support_filter_grzip(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
-
- if (__archive_read_register_bidder(a, NULL, NULL,
- &grzip_bidder_vtable) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /* This filter always uses an external program. */
- archive_set_error(_a, ARCHIVE_ERRNO_MISC,
- "Using external grzip program for grzip decompression");
- return (ARCHIVE_WARN);
-}
-
-/*
- * Bidder just verifies the header and returns the number of verified bits.
- */
-static int
-grzip_bidder_bid(struct archive_read_filter_bidder *self,
- struct archive_read_filter *filter)
-{
- const unsigned char *p;
- ssize_t avail;
-
- (void)self; /* UNUSED */
-
- p = __archive_read_filter_ahead(filter, sizeof(grzip_magic), &avail);
- if (p == NULL || avail == 0)
- return (0);
-
- if (memcmp(p, grzip_magic, sizeof(grzip_magic)))
- return (0);
-
- return (sizeof(grzip_magic) * 8);
-}
-
-static int
-grzip_bidder_init(struct archive_read_filter *self)
-{
- int r;
-
- r = __archive_read_program(self, "grzip -d");
- /* Note: We set the format here even if __archive_read_program()
- * above fails. We do, after all, know what the format is
- * even if we weren't able to read it. */
- self->code = ARCHIVE_FILTER_GRZIP;
- self->name = "grzip";
- return (r);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_filter_gzip.c b/contrib/libs/libarchive/libarchive/archive_read_support_filter_gzip.c
deleted file mode 100644
index 4135a63618..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_filter_gzip.c
+++ /dev/null
@@ -1,536 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-__FBSDID("$FreeBSD$");
-
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_endian.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-#ifdef HAVE_ZLIB_H
-struct private_data {
- z_stream stream;
- char in_stream;
- unsigned char *out_block;
- size_t out_block_size;
- int64_t total_out;
- unsigned long crc;
- uint32_t mtime;
- char *name;
- char eof; /* True = found end of compressed data. */
-};
-
-/* Gzip Filter. */
-static ssize_t gzip_filter_read(struct archive_read_filter *, const void **);
-static int gzip_filter_close(struct archive_read_filter *);
-#endif
-
-/*
- * Note that we can detect gzip archives even if we can't decompress
- * them. (In fact, we like detecting them because we can give better
- * error messages.) So the bid framework here gets compiled even
- * if zlib is unavailable.
- *
- * TODO: If zlib is unavailable, gzip_bidder_init() should
- * use the compress_program framework to try to fire up an external
- * gzip program.
- */
-static int gzip_bidder_bid(struct archive_read_filter_bidder *,
- struct archive_read_filter *);
-static int gzip_bidder_init(struct archive_read_filter *);
-
-#if ARCHIVE_VERSION_NUMBER < 4000000
-/* Deprecated; remove in libarchive 4.0 */
-int
-archive_read_support_compression_gzip(struct archive *a)
-{
- return archive_read_support_filter_gzip(a);
-}
-#endif
-
-static const struct archive_read_filter_bidder_vtable
-gzip_bidder_vtable = {
- .bid = gzip_bidder_bid,
- .init = gzip_bidder_init,
-};
-
-int
-archive_read_support_filter_gzip(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
-
- if (__archive_read_register_bidder(a, NULL, "gzip",
- &gzip_bidder_vtable) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /* Signal the extent of gzip support with the return value here. */
-#if HAVE_ZLIB_H
- return (ARCHIVE_OK);
-#else
- archive_set_error(_a, ARCHIVE_ERRNO_MISC,
- "Using external gzip program");
- return (ARCHIVE_WARN);
-#endif
-}
-
-/*
- * Read and verify the header.
- *
- * Returns zero if the header couldn't be validated, else returns
- * number of bytes in header. If pbits is non-NULL, it receives a
- * count of bits verified, suitable for use by bidder.
- */
-static ssize_t
-peek_at_header(struct archive_read_filter *filter, int *pbits,
-#ifdef HAVE_ZLIB_H
- struct private_data *state
-#else
- void *state
-#endif
- )
-{
- const unsigned char *p;
- ssize_t avail, len;
- int bits = 0;
- int header_flags;
-#ifndef HAVE_ZLIB_H
- (void)state; /* UNUSED */
-#endif
-
- /* Start by looking at the first ten bytes of the header, which
- * is all fixed layout. */
- len = 10;
- p = __archive_read_filter_ahead(filter, len, &avail);
- if (p == NULL || avail == 0)
- return (0);
- /* We only support deflation- third byte must be 0x08. */
- if (memcmp(p, "\x1F\x8B\x08", 3) != 0)
- return (0);
- bits += 24;
- if ((p[3] & 0xE0)!= 0) /* No reserved flags set. */
- return (0);
- bits += 3;
- header_flags = p[3];
- /* Bytes 4-7 are mod time in little endian. */
-#ifdef HAVE_ZLIB_H
- if (state)
- state->mtime = archive_le32dec(p + 4);
-#endif
- /* Byte 8 is deflate flags. */
- /* XXXX TODO: return deflate flags back to consume_header for use
- in initializing the decompressor. */
- /* Byte 9 is OS. */
-
- /* Optional extra data: 2 byte length plus variable body. */
- if (header_flags & 4) {
- p = __archive_read_filter_ahead(filter, len + 2, &avail);
- if (p == NULL)
- return (0);
- len += ((int)p[len + 1] << 8) | (int)p[len];
- len += 2;
- }
-
- /* Null-terminated optional filename. */
- if (header_flags & 8) {
-#ifdef HAVE_ZLIB_H
- ssize_t file_start = len;
-#endif
- do {
- ++len;
- if (avail < len)
- p = __archive_read_filter_ahead(filter,
- len, &avail);
- if (p == NULL)
- return (0);
- } while (p[len - 1] != 0);
-
-#ifdef HAVE_ZLIB_H
- if (state) {
- /* Reset the name in case of repeat header reads. */
- free(state->name);
- state->name = strdup((const char *)&p[file_start]);
- }
-#endif
- }
-
- /* Null-terminated optional comment. */
- if (header_flags & 16) {
- do {
- ++len;
- if (avail < len)
- p = __archive_read_filter_ahead(filter,
- len, &avail);
- if (p == NULL)
- return (0);
- } while (p[len - 1] != 0);
- }
-
- /* Optional header CRC */
- if ((header_flags & 2)) {
- p = __archive_read_filter_ahead(filter, len + 2, &avail);
- if (p == NULL)
- return (0);
-#if 0
- int hcrc = ((int)p[len + 1] << 8) | (int)p[len];
- int crc = /* XXX TODO: Compute header CRC. */;
- if (crc != hcrc)
- return (0);
- bits += 16;
-#endif
- len += 2;
- }
-
- if (pbits != NULL)
- *pbits = bits;
- return (len);
-}
-
-/*
- * Bidder just verifies the header and returns the number of verified bits.
- */
-static int
-gzip_bidder_bid(struct archive_read_filter_bidder *self,
- struct archive_read_filter *filter)
-{
- int bits_checked;
-
- (void)self; /* UNUSED */
-
- if (peek_at_header(filter, &bits_checked, NULL))
- return (bits_checked);
- return (0);
-}
-
-#ifndef HAVE_ZLIB_H
-
-/*
- * If we don't have the library on this system, we can't do the
- * decompression directly. We can, however, try to run "gzip -d"
- * in case that's available.
- */
-static int
-gzip_bidder_init(struct archive_read_filter *self)
-{
- int r;
-
- r = __archive_read_program(self, "gzip -d");
- /* Note: We set the format here even if __archive_read_program()
- * above fails. We do, after all, know what the format is
- * even if we weren't able to read it. */
- self->code = ARCHIVE_FILTER_GZIP;
- self->name = "gzip";
- return (r);
-}
-
-#else
-
-static int
-gzip_read_header(struct archive_read_filter *self, struct archive_entry *entry)
-{
- struct private_data *state;
-
- state = (struct private_data *)self->data;
-
- /* A mtime of 0 is considered invalid/missing. */
- if (state->mtime != 0)
- archive_entry_set_mtime(entry, state->mtime, 0);
-
- /* If the name is available, extract it. */
- if (state->name)
- archive_entry_set_pathname(entry, state->name);
-
- return (ARCHIVE_OK);
-}
-
-static const struct archive_read_filter_vtable
-gzip_reader_vtable = {
- .read = gzip_filter_read,
- .close = gzip_filter_close,
-#ifdef HAVE_ZLIB_H
- .read_header = gzip_read_header,
-#endif
-};
-
-/*
- * Initialize the filter object.
- */
-static int
-gzip_bidder_init(struct archive_read_filter *self)
-{
- struct private_data *state;
- static const size_t out_block_size = 64 * 1024;
- void *out_block;
-
- self->code = ARCHIVE_FILTER_GZIP;
- self->name = "gzip";
-
- state = (struct private_data *)calloc(sizeof(*state), 1);
- out_block = (unsigned char *)malloc(out_block_size);
- if (state == NULL || out_block == NULL) {
- free(out_block);
- free(state);
- archive_set_error(&self->archive->archive, ENOMEM,
- "Can't allocate data for gzip decompression");
- return (ARCHIVE_FATAL);
- }
-
- self->data = state;
- state->out_block_size = out_block_size;
- state->out_block = out_block;
- self->vtable = &gzip_reader_vtable;
-
- state->in_stream = 0; /* We're not actually within a stream yet. */
-
- return (ARCHIVE_OK);
-}
-
-static int
-consume_header(struct archive_read_filter *self)
-{
- struct private_data *state;
- ssize_t avail;
- size_t len;
- int ret;
-
- state = (struct private_data *)self->data;
-
- /* If this is a real header, consume it. */
- len = peek_at_header(self->upstream, NULL, state);
- if (len == 0)
- return (ARCHIVE_EOF);
- __archive_read_filter_consume(self->upstream, len);
-
- /* Initialize CRC accumulator. */
- state->crc = crc32(0L, NULL, 0);
-
- /* Initialize compression library. */
- state->stream.next_in = (unsigned char *)(uintptr_t)
- __archive_read_filter_ahead(self->upstream, 1, &avail);
- state->stream.avail_in = (uInt)avail;
- ret = inflateInit2(&(state->stream),
- -15 /* Don't check for zlib header */);
-
- /* Decipher the error code. */
- switch (ret) {
- case Z_OK:
- state->in_stream = 1;
- return (ARCHIVE_OK);
- case Z_STREAM_ERROR:
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library: "
- "invalid setup parameter");
- break;
- case Z_MEM_ERROR:
- archive_set_error(&self->archive->archive, ENOMEM,
- "Internal error initializing compression library: "
- "out of memory");
- break;
- case Z_VERSION_ERROR:
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library: "
- "invalid library version");
- break;
- default:
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library: "
- " Zlib error %d", ret);
- break;
- }
- return (ARCHIVE_FATAL);
-}
-
-static int
-consume_trailer(struct archive_read_filter *self)
-{
- struct private_data *state;
- const unsigned char *p;
- ssize_t avail;
-
- state = (struct private_data *)self->data;
-
- state->in_stream = 0;
- switch (inflateEnd(&(state->stream))) {
- case Z_OK:
- break;
- default:
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Failed to clean up gzip decompressor");
- return (ARCHIVE_FATAL);
- }
-
- /* GZip trailer is a fixed 8 byte structure. */
- p = __archive_read_filter_ahead(self->upstream, 8, &avail);
- if (p == NULL || avail == 0)
- return (ARCHIVE_FATAL);
-
- /* XXX TODO: Verify the length and CRC. */
-
- /* We've verified the trailer, so consume it now. */
- __archive_read_filter_consume(self->upstream, 8);
-
- return (ARCHIVE_OK);
-}
-
-static ssize_t
-gzip_filter_read(struct archive_read_filter *self, const void **p)
-{
- struct private_data *state;
- size_t decompressed;
- ssize_t avail_in, max_in;
- int ret;
-
- state = (struct private_data *)self->data;
-
- /* Empty our output buffer. */
- state->stream.next_out = state->out_block;
- state->stream.avail_out = (uInt)state->out_block_size;
-
- /* Try to fill the output buffer. */
- while (state->stream.avail_out > 0 && !state->eof) {
- /* If we're not in a stream, read a header
- * and initialize the decompression library. */
- if (!state->in_stream) {
- ret = consume_header(self);
- if (ret == ARCHIVE_EOF) {
- state->eof = 1;
- break;
- }
- if (ret < ARCHIVE_OK)
- return (ret);
- }
-
- /* Peek at the next available data. */
- /* ZLib treats stream.next_in as const but doesn't declare
- * it so, hence this ugly cast. */
- state->stream.next_in = (unsigned char *)(uintptr_t)
- __archive_read_filter_ahead(self->upstream, 1, &avail_in);
- if (state->stream.next_in == NULL) {
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "truncated gzip input");
- return (ARCHIVE_FATAL);
- }
- if (UINT_MAX >= SSIZE_MAX)
- max_in = SSIZE_MAX;
- else
- max_in = UINT_MAX;
- if (avail_in > max_in)
- avail_in = max_in;
- state->stream.avail_in = (uInt)avail_in;
-
- /* Decompress and consume some of that data. */
- ret = inflate(&(state->stream), 0);
- switch (ret) {
- case Z_OK: /* Decompressor made some progress. */
- __archive_read_filter_consume(self->upstream,
- avail_in - state->stream.avail_in);
- break;
- case Z_STREAM_END: /* Found end of stream. */
- __archive_read_filter_consume(self->upstream,
- avail_in - state->stream.avail_in);
- /* Consume the stream trailer; release the
- * decompression library. */
- ret = consume_trailer(self);
- if (ret < ARCHIVE_OK)
- return (ret);
- break;
- default:
- /* Return an error. */
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "gzip decompression failed");
- return (ARCHIVE_FATAL);
- }
- }
-
- /* We've read as much as we can. */
- decompressed = state->stream.next_out - state->out_block;
- state->total_out += decompressed;
- if (decompressed == 0)
- *p = NULL;
- else
- *p = state->out_block;
- return (decompressed);
-}
-
-/*
- * Clean up the decompressor.
- */
-static int
-gzip_filter_close(struct archive_read_filter *self)
-{
- struct private_data *state;
- int ret;
-
- state = (struct private_data *)self->data;
- ret = ARCHIVE_OK;
-
- if (state->in_stream) {
- switch (inflateEnd(&(state->stream))) {
- case Z_OK:
- break;
- default:
- archive_set_error(&(self->archive->archive),
- ARCHIVE_ERRNO_MISC,
- "Failed to clean up gzip compressor");
- ret = ARCHIVE_FATAL;
- }
- }
-
- free(state->name);
- free(state->out_block);
- free(state);
- return (ret);
-}
-
-#endif /* HAVE_ZLIB_H */
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_filter_lrzip.c b/contrib/libs/libarchive/libarchive/archive_read_support_filter_lrzip.c
deleted file mode 100644
index a2389894f1..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_filter_lrzip.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-__FBSDID("$FreeBSD$");
-
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-#define LRZIP_HEADER_MAGIC "LRZI"
-#define LRZIP_HEADER_MAGIC_LEN 4
-
-static int lrzip_bidder_bid(struct archive_read_filter_bidder *,
- struct archive_read_filter *);
-static int lrzip_bidder_init(struct archive_read_filter *);
-
-
-static const struct archive_read_filter_bidder_vtable
-lrzip_bidder_vtable = {
- .bid = lrzip_bidder_bid,
- .init = lrzip_bidder_init,
-};
-
-int
-archive_read_support_filter_lrzip(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
-
- if (__archive_read_register_bidder(a, NULL, "lrzip",
- &lrzip_bidder_vtable) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /* This filter always uses an external program. */
- archive_set_error(_a, ARCHIVE_ERRNO_MISC,
- "Using external lrzip program for lrzip decompression");
- return (ARCHIVE_WARN);
-}
-
-/*
- * Bidder just verifies the header and returns the number of verified bits.
- */
-static int
-lrzip_bidder_bid(struct archive_read_filter_bidder *self,
- struct archive_read_filter *filter)
-{
- const unsigned char *p;
- ssize_t avail, len;
- int i;
-
- (void)self; /* UNUSED */
- /* Start by looking at the first six bytes of the header, which
- * is all fixed layout. */
- len = 6;
- p = __archive_read_filter_ahead(filter, len, &avail);
- if (p == NULL || avail == 0)
- return (0);
-
- if (memcmp(p, LRZIP_HEADER_MAGIC, LRZIP_HEADER_MAGIC_LEN))
- return (0);
-
- /* current major version is always 0, verify this */
- if (p[LRZIP_HEADER_MAGIC_LEN])
- return 0;
- /* support only v0.6+ lrzip for sanity */
- i = p[LRZIP_HEADER_MAGIC_LEN + 1];
- if ((i < 6) || (i > 10))
- return 0;
-
- return (int)len;
-}
-
-static int
-lrzip_bidder_init(struct archive_read_filter *self)
-{
- int r;
-
- r = __archive_read_program(self, "lrzip -d -q");
- /* Note: We set the format here even if __archive_read_program()
- * above fails. We do, after all, know what the format is
- * even if we weren't able to read it. */
- self->code = ARCHIVE_FILTER_LRZIP;
- self->name = "lrzip";
- return (r);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_filter_lz4.c b/contrib/libs/libarchive/libarchive/archive_read_support_filter_lz4.c
deleted file mode 100644
index d0fc1a83e4..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_filter_lz4.c
+++ /dev/null
@@ -1,742 +0,0 @@
-/*-
- * Copyright (c) 2014 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_LZ4_H
-#include <lz4.h>
-#endif
-
-#include "archive.h"
-#include "archive_endian.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-#include "archive_xxhash.h"
-
-#define LZ4_MAGICNUMBER 0x184d2204
-#define LZ4_SKIPPABLED 0x184d2a50
-#define LZ4_LEGACY 0x184c2102
-
-#if defined(HAVE_LIBLZ4)
-struct private_data {
- enum { SELECT_STREAM,
- READ_DEFAULT_STREAM,
- READ_DEFAULT_BLOCK,
- READ_LEGACY_STREAM,
- READ_LEGACY_BLOCK,
- } stage;
- struct {
- unsigned block_independence:1;
- unsigned block_checksum:3;
- unsigned stream_size:1;
- unsigned stream_checksum:1;
- unsigned preset_dictionary:1;
- int block_maximum_size;
- } flags;
- int64_t stream_size;
- uint32_t dict_id;
- char *out_block;
- size_t out_block_size;
-
- /* Bytes read but not yet consumed via __archive_read_consume() */
- size_t unconsumed;
- size_t decoded_size;
- void *xxh32_state;
-
- char valid; /* True = decompressor is initialized */
- char eof; /* True = found end of compressed data. */
-};
-
-#define LEGACY_BLOCK_SIZE (8 * 1024 * 1024)
-
-/* Lz4 filter */
-static ssize_t lz4_filter_read(struct archive_read_filter *, const void **);
-static int lz4_filter_close(struct archive_read_filter *);
-#endif
-
-/*
- * Note that we can detect lz4 archives even if we can't decompress
- * them. (In fact, we like detecting them because we can give better
- * error messages.) So the bid framework here gets compiled even
- * if liblz4 is unavailable.
- */
-static int lz4_reader_bid(struct archive_read_filter_bidder *, struct archive_read_filter *);
-static int lz4_reader_init(struct archive_read_filter *);
-#if defined(HAVE_LIBLZ4)
-static ssize_t lz4_filter_read_default_stream(struct archive_read_filter *,
- const void **);
-static ssize_t lz4_filter_read_legacy_stream(struct archive_read_filter *,
- const void **);
-#endif
-
-static const struct archive_read_filter_bidder_vtable
-lz4_bidder_vtable = {
- .bid = lz4_reader_bid,
- .init = lz4_reader_init,
-};
-
-int
-archive_read_support_filter_lz4(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
-
- if (__archive_read_register_bidder(a, NULL, "lz4",
- &lz4_bidder_vtable) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
-#if defined(HAVE_LIBLZ4)
- return (ARCHIVE_OK);
-#else
- archive_set_error(_a, ARCHIVE_ERRNO_MISC,
- "Using external lz4 program");
- return (ARCHIVE_WARN);
-#endif
-}
-
-/*
- * Test whether we can handle this data.
- *
- * This logic returns zero if any part of the signature fails. It
- * also tries to Do The Right Thing if a very short buffer prevents us
- * from verifying as much as we would like.
- */
-static int
-lz4_reader_bid(struct archive_read_filter_bidder *self,
- struct archive_read_filter *filter)
-{
- const unsigned char *buffer;
- ssize_t avail;
- int bits_checked;
- uint32_t number;
-
- (void)self; /* UNUSED */
-
- /* Minimal lz4 archive is 11 bytes. */
- buffer = __archive_read_filter_ahead(filter, 11, &avail);
- if (buffer == NULL)
- return (0);
-
- /* First four bytes must be LZ4 magic numbers. */
- bits_checked = 0;
- if ((number = archive_le32dec(buffer)) == LZ4_MAGICNUMBER) {
- unsigned char flag, BD;
-
- bits_checked += 32;
- /* Next follows a stream descriptor. */
- /* Descriptor Flags. */
- flag = buffer[4];
- /* A version number must be "01". */
- if (((flag & 0xc0) >> 6) != 1)
- return (0);
- /* A reserved bit must be "0". */
- if (flag & 2)
- return (0);
- bits_checked += 8;
- BD = buffer[5];
- /* A block maximum size should be more than 3. */
- if (((BD & 0x70) >> 4) < 4)
- return (0);
- /* Reserved bits must be "0". */
- if (BD & ~0x70)
- return (0);
- bits_checked += 8;
- } else if (number == LZ4_LEGACY) {
- bits_checked += 32;
- }
-
- return (bits_checked);
-}
-
-#if !defined(HAVE_LIBLZ4)
-
-/*
- * If we don't have the library on this system, we can't actually do the
- * decompression. We can, however, still detect compressed archives
- * and emit a useful message.
- */
-static int
-lz4_reader_init(struct archive_read_filter *self)
-{
- int r;
-
- r = __archive_read_program(self, "lz4 -d -q");
- /* Note: We set the format here even if __archive_read_program()
- * above fails. We do, after all, know what the format is
- * even if we weren't able to read it. */
- self->code = ARCHIVE_FILTER_LZ4;
- self->name = "lz4";
- return (r);
-}
-
-
-#else
-
-static const struct archive_read_filter_vtable
-lz4_reader_vtable = {
- .read = lz4_filter_read,
- .close = lz4_filter_close,
-};
-
-/*
- * Setup the callbacks.
- */
-static int
-lz4_reader_init(struct archive_read_filter *self)
-{
- struct private_data *state;
-
- self->code = ARCHIVE_FILTER_LZ4;
- self->name = "lz4";
-
- state = (struct private_data *)calloc(sizeof(*state), 1);
- if (state == NULL) {
- archive_set_error(&self->archive->archive, ENOMEM,
- "Can't allocate data for lz4 decompression");
- return (ARCHIVE_FATAL);
- }
-
- self->data = state;
- state->stage = SELECT_STREAM;
- self->vtable = &lz4_reader_vtable;
-
- return (ARCHIVE_OK);
-}
-
-static int
-lz4_allocate_out_block(struct archive_read_filter *self)
-{
- struct private_data *state = (struct private_data *)self->data;
- size_t out_block_size = state->flags.block_maximum_size;
- void *out_block;
-
- if (!state->flags.block_independence)
- out_block_size += 64 * 1024;
- if (state->out_block_size < out_block_size) {
- free(state->out_block);
- out_block = (unsigned char *)malloc(out_block_size);
- state->out_block_size = out_block_size;
- if (out_block == NULL) {
- archive_set_error(&self->archive->archive, ENOMEM,
- "Can't allocate data for lz4 decompression");
- return (ARCHIVE_FATAL);
- }
- state->out_block = out_block;
- }
- if (!state->flags.block_independence)
- memset(state->out_block, 0, 64 * 1024);
- return (ARCHIVE_OK);
-}
-
-static int
-lz4_allocate_out_block_for_legacy(struct archive_read_filter *self)
-{
- struct private_data *state = (struct private_data *)self->data;
- size_t out_block_size = LEGACY_BLOCK_SIZE;
- void *out_block;
-
- if (state->out_block_size < out_block_size) {
- free(state->out_block);
- out_block = (unsigned char *)malloc(out_block_size);
- state->out_block_size = out_block_size;
- if (out_block == NULL) {
- archive_set_error(&self->archive->archive, ENOMEM,
- "Can't allocate data for lz4 decompression");
- return (ARCHIVE_FATAL);
- }
- state->out_block = out_block;
- }
- return (ARCHIVE_OK);
-}
-
-/*
- * Return the next block of decompressed data.
- */
-static ssize_t
-lz4_filter_read(struct archive_read_filter *self, const void **p)
-{
- struct private_data *state = (struct private_data *)self->data;
- ssize_t ret;
-
- if (state->eof) {
- *p = NULL;
- return (0);
- }
-
- __archive_read_filter_consume(self->upstream, state->unconsumed);
- state->unconsumed = 0;
-
- switch (state->stage) {
- case SELECT_STREAM:
- break;
- case READ_DEFAULT_STREAM:
- case READ_LEGACY_STREAM:
- /* Reading a lz4 stream already failed. */
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC, "Invalid sequence.");
- return (ARCHIVE_FATAL);
- case READ_DEFAULT_BLOCK:
- ret = lz4_filter_read_default_stream(self, p);
- if (ret != 0 || state->stage != SELECT_STREAM)
- return ret;
- break;
- case READ_LEGACY_BLOCK:
- ret = lz4_filter_read_legacy_stream(self, p);
- if (ret != 0 || state->stage != SELECT_STREAM)
- return ret;
- break;
- default:
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC, "Program error.");
- return (ARCHIVE_FATAL);
- break;
- }
-
- while (state->stage == SELECT_STREAM) {
- const char *read_buf;
-
- /* Read a magic number. */
- read_buf = __archive_read_filter_ahead(self->upstream, 4,
- NULL);
- if (read_buf == NULL) {
- state->eof = 1;
- *p = NULL;
- return (0);
- }
- uint32_t number = archive_le32dec(read_buf);
- __archive_read_filter_consume(self->upstream, 4);
- if (number == LZ4_MAGICNUMBER)
- return lz4_filter_read_default_stream(self, p);
- else if (number == LZ4_LEGACY)
- return lz4_filter_read_legacy_stream(self, p);
- else if ((number & ~0xF) == LZ4_SKIPPABLED) {
- read_buf = __archive_read_filter_ahead(
- self->upstream, 4, NULL);
- if (read_buf == NULL) {
- archive_set_error(
- &self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Malformed lz4 data");
- return (ARCHIVE_FATAL);
- }
- uint32_t skip_bytes = archive_le32dec(read_buf);
- __archive_read_filter_consume(self->upstream,
- 4 + skip_bytes);
- } else {
- /* Ignore following unrecognized data. */
- state->eof = 1;
- *p = NULL;
- return (0);
- }
- }
- state->eof = 1;
- *p = NULL;
- return (0);
-}
-
-static int
-lz4_filter_read_descriptor(struct archive_read_filter *self)
-{
- struct private_data *state = (struct private_data *)self->data;
- const char *read_buf;
- ssize_t bytes_remaining;
- ssize_t descriptor_bytes;
- unsigned char flag, bd;
- unsigned int chsum, chsum_verifier;
-
- /* Make sure we have 2 bytes for flags. */
- read_buf = __archive_read_filter_ahead(self->upstream, 2,
- &bytes_remaining);
- if (read_buf == NULL) {
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "truncated lz4 input");
- return (ARCHIVE_FATAL);
- }
-
- /*
- Parse flags.
- */
- flag = (unsigned char)read_buf[0];
- /* Verify version number. */
- if ((flag & 0xc0) != 1<<6)
- goto malformed_error;
- /* A reserved bit must be zero. */
- if (flag & 0x02)
- goto malformed_error;
- state->flags.block_independence = (flag & 0x20) != 0;
- state->flags.block_checksum = (flag & 0x10)?4:0;
- state->flags.stream_size = (flag & 0x08) != 0;
- state->flags.stream_checksum = (flag & 0x04) != 0;
- state->flags.preset_dictionary = (flag & 0x01) != 0;
-
- /* BD */
- bd = (unsigned char)read_buf[1];
- /* Reserved bits must be zero. */
- if (bd & 0x8f)
- goto malformed_error;
- /* Get a maximum block size. */
- switch (read_buf[1] >> 4) {
- case 4: /* 64 KB */
- state->flags.block_maximum_size = 64 * 1024;
- break;
- case 5: /* 256 KB */
- state->flags.block_maximum_size = 256 * 1024;
- break;
- case 6: /* 1 MB */
- state->flags.block_maximum_size = 1024 * 1024;
- break;
- case 7: /* 4 MB */
- state->flags.block_maximum_size = 4 * 1024 * 1024;
- break;
- default:
- goto malformed_error;
- }
-
- /* Read the whole descriptor in a stream block. */
- descriptor_bytes = 3;
- if (state->flags.stream_size)
- descriptor_bytes += 8;
- if (state->flags.preset_dictionary)
- descriptor_bytes += 4;
- if (bytes_remaining < descriptor_bytes) {
- read_buf = __archive_read_filter_ahead(self->upstream,
- descriptor_bytes, &bytes_remaining);
- if (read_buf == NULL) {
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "truncated lz4 input");
- return (ARCHIVE_FATAL);
- }
- }
- /* Check if a descriptor is corrupted */
- chsum = __archive_xxhash.XXH32(read_buf, (int)descriptor_bytes -1, 0);
- chsum = (chsum >> 8) & 0xff;
- chsum_verifier = read_buf[descriptor_bytes-1] & 0xff;
- if (chsum != chsum_verifier)
-#ifndef DONT_FAIL_ON_CRC_ERROR
- goto malformed_error;
-#endif
-
- __archive_read_filter_consume(self->upstream, descriptor_bytes);
-
- /* Make sure we have a large enough buffer for uncompressed data. */
- if (lz4_allocate_out_block(self) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- if (state->flags.stream_checksum)
- state->xxh32_state = __archive_xxhash.XXH32_init(0);
-
- state->decoded_size = 0;
- /* Success */
- return (ARCHIVE_OK);
-malformed_error:
- archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
- "malformed lz4 data");
- return (ARCHIVE_FATAL);
-}
-
-static ssize_t
-lz4_filter_read_data_block(struct archive_read_filter *self, const void **p)
-{
- struct private_data *state = (struct private_data *)self->data;
- ssize_t compressed_size;
- const char *read_buf;
- ssize_t bytes_remaining;
- int checksum_size;
- ssize_t uncompressed_size;
- size_t prefix64k;
-
- *p = NULL;
-
- /* Make sure we have 4 bytes for a block size. */
- read_buf = __archive_read_filter_ahead(self->upstream, 4,
- &bytes_remaining);
- if (read_buf == NULL)
- goto truncated_error;
- compressed_size = archive_le32dec(read_buf);
- if ((compressed_size & 0x7fffffff) > state->flags.block_maximum_size)
- goto malformed_error;
- /* A compressed size == 0 means the end of stream blocks. */
- if (compressed_size == 0) {
- __archive_read_filter_consume(self->upstream, 4);
- return 0;
- }
-
- checksum_size = state->flags.block_checksum;
- /* Check if the block is uncompressed. */
- if (compressed_size & 0x80000000U) {
- compressed_size &= 0x7fffffff;
- uncompressed_size = compressed_size;
- } else
- uncompressed_size = 0;/* Unknown yet. */
-
- /*
- Unfortunately, lz4 decompression API requires a whole block
- for its decompression speed, so we read a whole block and allocate
- a huge buffer used for decoded data.
- */
- read_buf = __archive_read_filter_ahead(self->upstream,
- 4 + compressed_size + checksum_size, &bytes_remaining);
- if (read_buf == NULL)
- goto truncated_error;
-
- /* Optional processing, checking a block sum. */
- if (checksum_size) {
- unsigned int chsum = __archive_xxhash.XXH32(
- read_buf + 4, (int)compressed_size, 0);
- unsigned int chsum_block =
- archive_le32dec(read_buf + 4 + compressed_size);
- if (chsum != chsum_block)
-#ifndef DONT_FAIL_ON_CRC_ERROR
- goto malformed_error;
-#endif
- }
-
-
- /* If the block is uncompressed, there is nothing to do. */
- if (uncompressed_size) {
- /* Prepare a prefix 64k block for next block. */
- if (!state->flags.block_independence) {
- prefix64k = 64 * 1024;
- if (uncompressed_size < (ssize_t)prefix64k) {
- memcpy(state->out_block
- + prefix64k - uncompressed_size,
- read_buf + 4,
- uncompressed_size);
- memset(state->out_block, 0,
- prefix64k - uncompressed_size);
- } else {
- memcpy(state->out_block,
- read_buf + 4
- + uncompressed_size - prefix64k,
- prefix64k);
- }
- state->decoded_size = 0;
- }
- state->unconsumed = 4 + uncompressed_size + checksum_size;
- *p = read_buf + 4;
- return uncompressed_size;
- }
-
- /*
- Decompress a block data.
- */
- if (state->flags.block_independence) {
- prefix64k = 0;
- uncompressed_size = LZ4_decompress_safe(read_buf + 4,
- state->out_block, (int)compressed_size,
- state->flags.block_maximum_size);
- } else {
- prefix64k = 64 * 1024;
- if (state->decoded_size) {
- if (state->decoded_size < prefix64k) {
- memmove(state->out_block
- + prefix64k - state->decoded_size,
- state->out_block + prefix64k,
- state->decoded_size);
- memset(state->out_block, 0,
- prefix64k - state->decoded_size);
- } else {
- memmove(state->out_block,
- state->out_block + state->decoded_size,
- prefix64k);
- }
- }
-#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7
- uncompressed_size = LZ4_decompress_safe_usingDict(
- read_buf + 4,
- state->out_block + prefix64k, (int)compressed_size,
- state->flags.block_maximum_size,
- state->out_block,
- (int)prefix64k);
-#else
- uncompressed_size = LZ4_decompress_safe_withPrefix64k(
- read_buf + 4,
- state->out_block + prefix64k, (int)compressed_size,
- state->flags.block_maximum_size);
-#endif
- }
-
- /* Check if an error occurred in the decompression process. */
- if (uncompressed_size < 0) {
- archive_set_error(&(self->archive->archive),
- ARCHIVE_ERRNO_MISC, "lz4 decompression failed");
- return (ARCHIVE_FATAL);
- }
-
- state->unconsumed = 4 + compressed_size + checksum_size;
- *p = state->out_block + prefix64k;
- state->decoded_size = uncompressed_size;
- return uncompressed_size;
-
-malformed_error:
- archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
- "malformed lz4 data");
- return (ARCHIVE_FATAL);
-truncated_error:
- archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
- "truncated lz4 input");
- return (ARCHIVE_FATAL);
-}
-
-static ssize_t
-lz4_filter_read_default_stream(struct archive_read_filter *self, const void **p)
-{
- struct private_data *state = (struct private_data *)self->data;
- const char *read_buf;
- ssize_t bytes_remaining;
- ssize_t ret;
-
- if (state->stage == SELECT_STREAM) {
- state->stage = READ_DEFAULT_STREAM;
- /* First, read a descriptor. */
- if((ret = lz4_filter_read_descriptor(self)) != ARCHIVE_OK)
- return (ret);
- state->stage = READ_DEFAULT_BLOCK;
- }
- /* Decompress a block. */
- ret = lz4_filter_read_data_block(self, p);
-
- /* If the end of block is detected, change the filter status
- to read next stream. */
- if (ret == 0 && *p == NULL)
- state->stage = SELECT_STREAM;
-
- /* Optional processing, checking a stream sum. */
- if (state->flags.stream_checksum) {
- if (state->stage == SELECT_STREAM) {
- unsigned int checksum;
- unsigned int checksum_stream;
- read_buf = __archive_read_filter_ahead(self->upstream,
- 4, &bytes_remaining);
- if (read_buf == NULL) {
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC, "truncated lz4 input");
- return (ARCHIVE_FATAL);
- }
- checksum = archive_le32dec(read_buf);
- __archive_read_filter_consume(self->upstream, 4);
- checksum_stream = __archive_xxhash.XXH32_digest(
- state->xxh32_state);
- state->xxh32_state = NULL;
- if (checksum != checksum_stream) {
-#ifndef DONT_FAIL_ON_CRC_ERROR
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "lz4 stream checksum error");
- return (ARCHIVE_FATAL);
-#endif
- }
- } else if (ret > 0)
- __archive_xxhash.XXH32_update(state->xxh32_state,
- *p, (int)ret);
- }
- return (ret);
-}
-
-static ssize_t
-lz4_filter_read_legacy_stream(struct archive_read_filter *self, const void **p)
-{
- struct private_data *state = (struct private_data *)self->data;
- uint32_t compressed;
- const char *read_buf;
- ssize_t ret;
-
- *p = NULL;
- ret = lz4_allocate_out_block_for_legacy(self);
- if (ret != ARCHIVE_OK)
- return ret;
-
- /* Make sure we have 4 bytes for a block size. */
- read_buf = __archive_read_filter_ahead(self->upstream, 4, NULL);
- if (read_buf == NULL) {
- if (state->stage == SELECT_STREAM) {
- state->stage = READ_LEGACY_STREAM;
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "truncated lz4 input");
- return (ARCHIVE_FATAL);
- }
- state->stage = SELECT_STREAM;
- return 0;
- }
- state->stage = READ_LEGACY_BLOCK;
- compressed = archive_le32dec(read_buf);
- if (compressed > LZ4_COMPRESSBOUND(LEGACY_BLOCK_SIZE)) {
- state->stage = SELECT_STREAM;
- return 0;
- }
-
- /* Make sure we have a whole block. */
- read_buf = __archive_read_filter_ahead(self->upstream,
- 4 + compressed, NULL);
- if (read_buf == NULL) {
- archive_set_error(&(self->archive->archive),
- ARCHIVE_ERRNO_MISC, "truncated lz4 input");
- return (ARCHIVE_FATAL);
- }
- ret = LZ4_decompress_safe(read_buf + 4, state->out_block,
- compressed, (int)state->out_block_size);
- if (ret < 0) {
- archive_set_error(&(self->archive->archive),
- ARCHIVE_ERRNO_MISC, "lz4 decompression failed");
- return (ARCHIVE_FATAL);
- }
- *p = state->out_block;
- state->unconsumed = 4 + compressed;
- return ret;
-}
-
-/*
- * Clean up the decompressor.
- */
-static int
-lz4_filter_close(struct archive_read_filter *self)
-{
- struct private_data *state;
- int ret = ARCHIVE_OK;
-
- state = (struct private_data *)self->data;
- free(state->xxh32_state);
- free(state->out_block);
- free(state);
- return (ret);
-}
-
-#endif /* HAVE_LIBLZ4 */
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_filter_lzop.c b/contrib/libs/libarchive/libarchive/archive_read_support_filter_lzop.c
deleted file mode 100644
index 54e6e198c9..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_filter_lzop.c
+++ /dev/null
@@ -1,499 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * Copyright (c) 2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_LZO_LZOCONF_H
-#error #include <lzo/lzoconf.h>
-#endif
-#ifdef HAVE_LZO_LZO1X_H
-#error #include <lzo/lzo1x.h>
-#endif
-#ifdef HAVE_ZLIB_H
-#include <zlib.h> /* for crc32 and adler32 */
-#endif
-
-#include "archive.h"
-#if !defined(HAVE_ZLIB_H) &&\
- defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H)
-#error #include "archive_crc32.h"
-#endif
-#include "archive_endian.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-#ifndef HAVE_ZLIB_H
-#define adler32 lzo_adler32
-#endif
-
-#define LZOP_HEADER_MAGIC "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a"
-#define LZOP_HEADER_MAGIC_LEN 9
-
-#if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H)
-struct read_lzop {
- unsigned char *out_block;
- size_t out_block_size;
- int64_t total_out;
- int flags;
- uint32_t compressed_cksum;
- uint32_t uncompressed_cksum;
- size_t compressed_size;
- size_t uncompressed_size;
- size_t unconsumed_bytes;
- char in_stream;
- char eof; /* True = found end of compressed data. */
-};
-
-#define FILTER 0x0800
-#define CRC32_HEADER 0x1000
-#define EXTRA_FIELD 0x0040
-#define ADLER32_UNCOMPRESSED 0x0001
-#define ADLER32_COMPRESSED 0x0002
-#define CRC32_UNCOMPRESSED 0x0100
-#define CRC32_COMPRESSED 0x0200
-#define MAX_BLOCK_SIZE (64 * 1024 * 1024)
-
-static ssize_t lzop_filter_read(struct archive_read_filter *, const void **);
-static int lzop_filter_close(struct archive_read_filter *);
-#endif
-
-static int lzop_bidder_bid(struct archive_read_filter_bidder *,
- struct archive_read_filter *);
-static int lzop_bidder_init(struct archive_read_filter *);
-
-static const struct archive_read_filter_bidder_vtable
-lzop_bidder_vtable = {
- .bid = lzop_bidder_bid,
- .init = lzop_bidder_init,
-};
-
-int
-archive_read_support_filter_lzop(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
-
- if (__archive_read_register_bidder(a, NULL, NULL,
- &lzop_bidder_vtable) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /* Signal the extent of lzop support with the return value here. */
-#if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H)
- return (ARCHIVE_OK);
-#else
- /* Return ARCHIVE_WARN since this always uses an external program. */
- archive_set_error(_a, ARCHIVE_ERRNO_MISC,
- "Using external lzop program for lzop decompression");
- return (ARCHIVE_WARN);
-#endif
-}
-
-/*
- * Bidder just verifies the header and returns the number of verified bits.
- */
-static int
-lzop_bidder_bid(struct archive_read_filter_bidder *self,
- struct archive_read_filter *filter)
-{
- const unsigned char *p;
- ssize_t avail;
-
- (void)self; /* UNUSED */
-
- p = __archive_read_filter_ahead(filter, LZOP_HEADER_MAGIC_LEN, &avail);
- if (p == NULL || avail == 0)
- return (0);
-
- if (memcmp(p, LZOP_HEADER_MAGIC, LZOP_HEADER_MAGIC_LEN))
- return (0);
-
- return (LZOP_HEADER_MAGIC_LEN * 8);
-}
-
-#if !defined(HAVE_LZO_LZOCONF_H) || !defined(HAVE_LZO_LZO1X_H)
-/*
- * If we don't have the library on this system, we can't do the
- * decompression directly. We can, however, try to run "lzop -d"
- * in case that's available.
- */
-static int
-lzop_bidder_init(struct archive_read_filter *self)
-{
- int r;
-
- r = __archive_read_program(self, "lzop -d");
- /* Note: We set the format here even if __archive_read_program()
- * above fails. We do, after all, know what the format is
- * even if we weren't able to read it. */
- self->code = ARCHIVE_FILTER_LZOP;
- self->name = "lzop";
- return (r);
-}
-#else
-
-static const struct archive_read_filter_vtable
-lzop_reader_vtable = {
- .read = lzop_filter_read,
- .close = lzop_filter_close
-};
-
-/*
- * Initialize the filter object.
- */
-static int
-lzop_bidder_init(struct archive_read_filter *self)
-{
- struct read_lzop *state;
-
- self->code = ARCHIVE_FILTER_LZOP;
- self->name = "lzop";
-
- state = (struct read_lzop *)calloc(sizeof(*state), 1);
- if (state == NULL) {
- archive_set_error(&self->archive->archive, ENOMEM,
- "Can't allocate data for lzop decompression");
- return (ARCHIVE_FATAL);
- }
-
- self->data = state;
- self->vtable = &lzop_reader_vtable;
-
- return (ARCHIVE_OK);
-}
-
-static int
-consume_header(struct archive_read_filter *self)
-{
- struct read_lzop *state = (struct read_lzop *)self->data;
- const unsigned char *p, *_p;
- unsigned checksum, flags, len, method, version;
-
- /*
- * Check LZOP magic code.
- */
- p = __archive_read_filter_ahead(self->upstream,
- LZOP_HEADER_MAGIC_LEN, NULL);
- if (p == NULL)
- return (ARCHIVE_EOF);
-
- if (memcmp(p, LZOP_HEADER_MAGIC, LZOP_HEADER_MAGIC_LEN))
- return (ARCHIVE_EOF);
- __archive_read_filter_consume(self->upstream,
- LZOP_HEADER_MAGIC_LEN);
-
- p = __archive_read_filter_ahead(self->upstream, 29, NULL);
- if (p == NULL)
- goto truncated;
- _p = p;
- version = archive_be16dec(p);
- p += 4;/* version(2 bytes) + library version(2 bytes) */
-
- if (version >= 0x940) {
- unsigned reqversion = archive_be16dec(p); p += 2;
- if (reqversion < 0x900) {
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC, "Invalid required version");
- return (ARCHIVE_FAILED);
- }
- }
-
- method = *p++;
- if (method < 1 || method > 3) {
- archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
- "Unsupported method");
- return (ARCHIVE_FAILED);
- }
-
- if (version >= 0x940) {
- unsigned level = *p++;
-#if 0
- unsigned default_level[] = {0, 3, 1, 9};
-#endif
- if (level == 0)
- /* Method is 1..3 here due to check above. */
-#if 0 /* Avoid an error Clang Static Analyzer claims
- "Value stored to 'level' is never read". */
- level = default_level[method];
-#else
- ;/* NOP */
-#endif
- else if (level > 9) {
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC, "Invalid level");
- return (ARCHIVE_FAILED);
- }
- }
-
- flags = archive_be32dec(p); p += 4;
-
- if (flags & FILTER)
- p += 4; /* Skip filter */
- p += 4; /* Skip mode */
- if (version >= 0x940)
- p += 8; /* Skip mtime */
- else
- p += 4; /* Skip mtime */
- len = *p++; /* Read filename length */
- len += p - _p;
- /* Make sure we have all bytes we need to calculate checksum. */
- p = __archive_read_filter_ahead(self->upstream, len + 4, NULL);
- if (p == NULL)
- goto truncated;
- if (flags & CRC32_HEADER)
- checksum = crc32(crc32(0, NULL, 0), p, len);
- else
- checksum = adler32(adler32(0, NULL, 0), p, len);
- if (archive_be32dec(p + len) != checksum)
-#ifndef DONT_FAIL_ON_CRC_ERROR
- goto corrupted;
-#endif
- __archive_read_filter_consume(self->upstream, len + 4);
- if (flags & EXTRA_FIELD) {
- /* Skip extra field */
- p = __archive_read_filter_ahead(self->upstream, 4, NULL);
- if (p == NULL)
- goto truncated;
- len = archive_be32dec(p);
- __archive_read_filter_consume(self->upstream, len + 4 + 4);
- }
- state->flags = flags;
- state->in_stream = 1;
- return (ARCHIVE_OK);
-truncated:
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_FILE_FORMAT, "Truncated lzop data");
- return (ARCHIVE_FAILED);
-corrupted:
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_FILE_FORMAT, "Corrupted lzop header");
- return (ARCHIVE_FAILED);
-}
-
-static int
-consume_block_info(struct archive_read_filter *self)
-{
- struct read_lzop *state = (struct read_lzop *)self->data;
- const unsigned char *p;
- unsigned flags = state->flags;
-
- p = __archive_read_filter_ahead(self->upstream, 4, NULL);
- if (p == NULL)
- goto truncated;
- state->uncompressed_size = archive_be32dec(p);
- __archive_read_filter_consume(self->upstream, 4);
- if (state->uncompressed_size == 0)
- return (ARCHIVE_EOF);
- if (state->uncompressed_size > MAX_BLOCK_SIZE)
- goto corrupted;
-
- p = __archive_read_filter_ahead(self->upstream, 4, NULL);
- if (p == NULL)
- goto truncated;
- state->compressed_size = archive_be32dec(p);
- __archive_read_filter_consume(self->upstream, 4);
- if (state->compressed_size > state->uncompressed_size)
- goto corrupted;
-
- if (flags & (CRC32_UNCOMPRESSED | ADLER32_UNCOMPRESSED)) {
- p = __archive_read_filter_ahead(self->upstream, 4, NULL);
- if (p == NULL)
- goto truncated;
- state->compressed_cksum = state->uncompressed_cksum =
- archive_be32dec(p);
- __archive_read_filter_consume(self->upstream, 4);
- }
- if ((flags & (CRC32_COMPRESSED | ADLER32_COMPRESSED)) &&
- state->compressed_size < state->uncompressed_size) {
- p = __archive_read_filter_ahead(self->upstream, 4, NULL);
- if (p == NULL)
- goto truncated;
- state->compressed_cksum = archive_be32dec(p);
- __archive_read_filter_consume(self->upstream, 4);
- }
- return (ARCHIVE_OK);
-truncated:
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_FILE_FORMAT, "Truncated lzop data");
- return (ARCHIVE_FAILED);
-corrupted:
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_FILE_FORMAT, "Corrupted lzop header");
- return (ARCHIVE_FAILED);
-}
-
-static ssize_t
-lzop_filter_read(struct archive_read_filter *self, const void **p)
-{
- struct read_lzop *state = (struct read_lzop *)self->data;
- const void *b;
- lzo_uint out_size;
- uint32_t cksum;
- int ret, r;
-
- if (state->unconsumed_bytes) {
- __archive_read_filter_consume(self->upstream,
- state->unconsumed_bytes);
- state->unconsumed_bytes = 0;
- }
- if (state->eof)
- return (0);
-
- for (;;) {
- if (!state->in_stream) {
- ret = consume_header(self);
- if (ret < ARCHIVE_OK)
- return (ret);
- if (ret == ARCHIVE_EOF) {
- state->eof = 1;
- return (0);
- }
- }
- ret = consume_block_info(self);
- if (ret < ARCHIVE_OK)
- return (ret);
- if (ret == ARCHIVE_EOF)
- state->in_stream = 0;
- else
- break;
- }
-
- if (state->out_block == NULL ||
- state->out_block_size < state->uncompressed_size) {
- void *new_block;
-
- new_block = realloc(state->out_block, state->uncompressed_size);
- if (new_block == NULL) {
- archive_set_error(&self->archive->archive, ENOMEM,
- "Can't allocate data for lzop decompression");
- return (ARCHIVE_FATAL);
- }
- state->out_block = new_block;
- state->out_block_size = state->uncompressed_size;
- }
-
- b = __archive_read_filter_ahead(self->upstream,
- state->compressed_size, NULL);
- if (b == NULL) {
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_FILE_FORMAT, "Truncated lzop data");
- return (ARCHIVE_FATAL);
- }
- if (state->flags & CRC32_COMPRESSED)
- cksum = crc32(crc32(0, NULL, 0), b, state->compressed_size);
- else if (state->flags & ADLER32_COMPRESSED)
- cksum = adler32(adler32(0, NULL, 0), b, state->compressed_size);
- else
- cksum = state->compressed_cksum;
- if (cksum != state->compressed_cksum) {
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC, "Corrupted data");
- return (ARCHIVE_FATAL);
- }
-
- /*
- * If the both uncompressed size and compressed size are the same,
- * we do not decompress this block.
- */
- if (state->uncompressed_size == state->compressed_size) {
- *p = b;
- state->total_out += state->compressed_size;
- state->unconsumed_bytes = state->compressed_size;
- return ((ssize_t)state->uncompressed_size);
- }
-
- /*
- * Drive lzo uncompression.
- */
- out_size = (lzo_uint)state->uncompressed_size;
- r = lzo1x_decompress_safe(b, (lzo_uint)state->compressed_size,
- state->out_block, &out_size, NULL);
- switch (r) {
- case LZO_E_OK:
- if (out_size == state->uncompressed_size)
- break;
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC, "Corrupted data");
- return (ARCHIVE_FATAL);
- case LZO_E_OUT_OF_MEMORY:
- archive_set_error(&self->archive->archive, ENOMEM,
- "lzop decompression failed: out of memory");
- return (ARCHIVE_FATAL);
- default:
- archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
- "lzop decompression failed: %d", r);
- return (ARCHIVE_FATAL);
- }
-
- if (state->flags & CRC32_UNCOMPRESSED)
- cksum = crc32(crc32(0, NULL, 0), state->out_block,
- state->uncompressed_size);
- else if (state->flags & ADLER32_UNCOMPRESSED)
- cksum = adler32(adler32(0, NULL, 0), state->out_block,
- state->uncompressed_size);
- else
- cksum = state->uncompressed_cksum;
- if (cksum != state->uncompressed_cksum) {
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC, "Corrupted data");
- return (ARCHIVE_FATAL);
- }
-
- __archive_read_filter_consume(self->upstream, state->compressed_size);
- *p = state->out_block;
- state->total_out += out_size;
- return ((ssize_t)out_size);
-}
-
-/*
- * Clean up the decompressor.
- */
-static int
-lzop_filter_close(struct archive_read_filter *self)
-{
- struct read_lzop *state = (struct read_lzop *)self->data;
-
- free(state->out_block);
- free(state);
- return (ARCHIVE_OK);
-}
-
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_filter_none.c b/contrib/libs/libarchive/libarchive/archive_read_support_filter_none.c
deleted file mode 100644
index 95e5cfdb15..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_filter_none.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#include "archive.h"
-#include "archive_private.h"
-
-#if ARCHIVE_VERSION_NUMBER < 4000000
-/* Deprecated; remove in libarchive 4.0 */
-int
-archive_read_support_compression_none(struct archive *a)
-{
- return archive_read_support_filter_none(a);
-}
-#endif
-
-/*
- * Uncompressed streams are handled implicitly by the read core,
- * so this is now a no-op.
- */
-int
-archive_read_support_filter_none(struct archive *a)
-{
- archive_check_magic(a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_filter_none");
-
- return (ARCHIVE_OK);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_filter_program.c b/contrib/libs/libarchive/libarchive/archive_read_support_filter_program.c
deleted file mode 100644
index 885b2c2056..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_filter_program.c
+++ /dev/null
@@ -1,496 +0,0 @@
-/*-
- * Copyright (c) 2007 Joerg Sonnenberger
- * Copyright (c) 2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-#ifdef HAVE_ERRNO_H
-# include <errno.h>
-#endif
-#ifdef HAVE_FCNTL_H
-# include <fcntl.h>
-#endif
-#ifdef HAVE_LIMITS_H
-# include <limits.h>
-#endif
-#ifdef HAVE_SIGNAL_H
-# include <signal.h>
-#endif
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-# include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_string.h"
-#include "archive_read_private.h"
-#include "filter_fork.h"
-
-
-#if ARCHIVE_VERSION_NUMBER < 4000000
-/* Deprecated; remove in libarchive 4.0 */
-int
-archive_read_support_compression_program(struct archive *a, const char *cmd)
-{
- return archive_read_support_filter_program(a, cmd);
-}
-
-int
-archive_read_support_compression_program_signature(struct archive *a,
- const char *cmd, const void *signature, size_t signature_len)
-{
- return archive_read_support_filter_program_signature(a,
- cmd, signature, signature_len);
-}
-#endif
-
-int
-archive_read_support_filter_program(struct archive *a, const char *cmd)
-{
- return (archive_read_support_filter_program_signature(a, cmd, NULL, 0));
-}
-
-/*
- * The bidder object stores the command and the signature to watch for.
- * The 'inhibit' entry here is used to ensure that unchecked filters never
- * bid twice in the same pipeline.
- */
-struct program_bidder {
- char *description;
- char *cmd;
- void *signature;
- size_t signature_len;
- int inhibit;
-};
-
-static int program_bidder_bid(struct archive_read_filter_bidder *,
- struct archive_read_filter *upstream);
-static int program_bidder_init(struct archive_read_filter *);
-static void program_bidder_free(struct archive_read_filter_bidder *);
-
-/*
- * The actual filter needs to track input and output data.
- */
-struct program_filter {
- struct archive_string description;
-#if defined(_WIN32) && !defined(__CYGWIN__)
- HANDLE child;
-#else
- pid_t child;
-#endif
- int exit_status;
- int waitpid_return;
- int child_stdin, child_stdout;
-
- char *out_buf;
- size_t out_buf_len;
-};
-
-static ssize_t program_filter_read(struct archive_read_filter *,
- const void **);
-static int program_filter_close(struct archive_read_filter *);
-static void free_state(struct program_bidder *);
-
-static const struct archive_read_filter_bidder_vtable
-program_bidder_vtable = {
- .bid = program_bidder_bid,
- .init = program_bidder_init,
- .free = program_bidder_free,
-};
-
-int
-archive_read_support_filter_program_signature(struct archive *_a,
- const char *cmd, const void *signature, size_t signature_len)
-{
- struct archive_read *a = (struct archive_read *)_a;
- struct program_bidder *state;
-
- /*
- * Allocate our private state.
- */
- state = (struct program_bidder *)calloc(1, sizeof (*state));
- if (state == NULL)
- goto memerr;
- state->cmd = strdup(cmd);
- if (state->cmd == NULL)
- goto memerr;
-
- if (signature != NULL && signature_len > 0) {
- state->signature_len = signature_len;
- state->signature = malloc(signature_len);
- memcpy(state->signature, signature, signature_len);
- }
-
- if (__archive_read_register_bidder(a, state, NULL,
- &program_bidder_vtable) != ARCHIVE_OK) {
- free_state(state);
- return (ARCHIVE_FATAL);
- }
- return (ARCHIVE_OK);
-
-memerr:
- free_state(state);
- archive_set_error(_a, ENOMEM, "Can't allocate memory");
- return (ARCHIVE_FATAL);
-}
-
-static void
-program_bidder_free(struct archive_read_filter_bidder *self)
-{
- struct program_bidder *state = (struct program_bidder *)self->data;
-
- free_state(state);
-}
-
-static void
-free_state(struct program_bidder *state)
-{
-
- if (state) {
- free(state->cmd);
- free(state->signature);
- free(state);
- }
-}
-
-/*
- * If we do have a signature, bid only if that matches.
- *
- * If there's no signature, we bid INT_MAX the first time
- * we're called, then never bid again.
- */
-static int
-program_bidder_bid(struct archive_read_filter_bidder *self,
- struct archive_read_filter *upstream)
-{
- struct program_bidder *state = self->data;
- const char *p;
-
- /* If we have a signature, use that to match. */
- if (state->signature_len > 0) {
- p = __archive_read_filter_ahead(upstream,
- state->signature_len, NULL);
- if (p == NULL)
- return (0);
- /* No match, so don't bid. */
- if (memcmp(p, state->signature, state->signature_len) != 0)
- return (0);
- return ((int)state->signature_len * 8);
- }
-
- /* Otherwise, bid once and then never bid again. */
- if (state->inhibit)
- return (0);
- state->inhibit = 1;
- return (INT_MAX);
-}
-
-/*
- * Shut down the child, return ARCHIVE_OK if it exited normally.
- *
- * Note that the return value is sticky; if we're called again,
- * we won't reap the child again, but we will return the same status
- * (including error message if the child came to a bad end).
- */
-static int
-child_stop(struct archive_read_filter *self, struct program_filter *state)
-{
- /* Close our side of the I/O with the child. */
- if (state->child_stdin != -1) {
- close(state->child_stdin);
- state->child_stdin = -1;
- }
- if (state->child_stdout != -1) {
- close(state->child_stdout);
- state->child_stdout = -1;
- }
-
- if (state->child != 0) {
- /* Reap the child. */
- do {
- state->waitpid_return
- = waitpid(state->child, &state->exit_status, 0);
- } while (state->waitpid_return == -1 && errno == EINTR);
-#if defined(_WIN32) && !defined(__CYGWIN__)
- CloseHandle(state->child);
-#endif
- state->child = 0;
- }
-
- if (state->waitpid_return < 0) {
- /* waitpid() failed? This is ugly. */
- archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
- "Child process exited badly");
- return (ARCHIVE_WARN);
- }
-
-#if !defined(_WIN32) || defined(__CYGWIN__)
- if (WIFSIGNALED(state->exit_status)) {
-#ifdef SIGPIPE
- /* If the child died because we stopped reading before
- * it was done, that's okay. Some archive formats
- * have padding at the end that we routinely ignore. */
- /* The alternative to this would be to add a step
- * before close(child_stdout) above to read from the
- * child until the child has no more to write. */
- if (WTERMSIG(state->exit_status) == SIGPIPE)
- return (ARCHIVE_OK);
-#endif
- archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
- "Child process exited with signal %d",
- WTERMSIG(state->exit_status));
- return (ARCHIVE_WARN);
- }
-#endif /* !_WIN32 || __CYGWIN__ */
-
- if (WIFEXITED(state->exit_status)) {
- if (WEXITSTATUS(state->exit_status) == 0)
- return (ARCHIVE_OK);
-
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Child process exited with status %d",
- WEXITSTATUS(state->exit_status));
- return (ARCHIVE_WARN);
- }
-
- return (ARCHIVE_WARN);
-}
-
-/*
- * Use select() to decide whether the child is ready for read or write.
- */
-static ssize_t
-child_read(struct archive_read_filter *self, char *buf, size_t buf_len)
-{
- struct program_filter *state = self->data;
- ssize_t ret, requested, avail;
- const char *p;
-#if defined(_WIN32) && !defined(__CYGWIN__)
- HANDLE handle = (HANDLE)_get_osfhandle(state->child_stdout);
-#endif
-
- requested = buf_len > SSIZE_MAX ? SSIZE_MAX : buf_len;
-
- for (;;) {
- do {
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Avoid infinity wait.
- * Note: If there is no data in the pipe, ReadFile()
- * called in read() never returns and so we won't
- * write remaining encoded data to the pipe.
- * Note: This way may cause performance problem.
- * we are looking forward to great code to resolve
- * this. */
- DWORD pipe_avail = -1;
- int cnt = 2;
-
- while (PeekNamedPipe(handle, NULL, 0, NULL,
- &pipe_avail, NULL) != 0 && pipe_avail == 0 &&
- cnt--)
- Sleep(5);
- if (pipe_avail == 0) {
- ret = -1;
- errno = EAGAIN;
- break;
- }
-#endif
- ret = read(state->child_stdout, buf, requested);
- } while (ret == -1 && errno == EINTR);
-
- if (ret > 0)
- return (ret);
- if (ret == 0 || (ret == -1 && errno == EPIPE))
- /* Child has closed its output; reap the child
- * and return the status. */
- return (child_stop(self, state));
- if (ret == -1 && errno != EAGAIN)
- return (-1);
-
- if (state->child_stdin == -1) {
- /* Block until child has some I/O ready. */
- __archive_check_child(state->child_stdin,
- state->child_stdout);
- continue;
- }
-
- /* Get some more data from upstream. */
- p = __archive_read_filter_ahead(self->upstream, 1, &avail);
- if (p == NULL) {
- close(state->child_stdin);
- state->child_stdin = -1;
- fcntl(state->child_stdout, F_SETFL, 0);
- if (avail < 0)
- return (avail);
- continue;
- }
-
- do {
- ret = write(state->child_stdin, p, avail);
- } while (ret == -1 && errno == EINTR);
-
- if (ret > 0) {
- /* Consume whatever we managed to write. */
- __archive_read_filter_consume(self->upstream, ret);
- } else if (ret == -1 && errno == EAGAIN) {
- /* Block until child has some I/O ready. */
- __archive_check_child(state->child_stdin,
- state->child_stdout);
- } else {
- /* Write failed. */
- close(state->child_stdin);
- state->child_stdin = -1;
- fcntl(state->child_stdout, F_SETFL, 0);
- /* If it was a bad error, we're done; otherwise
- * it was EPIPE or EOF, and we can still read
- * from the child. */
- if (ret == -1 && errno != EPIPE)
- return (-1);
- }
- }
-}
-
-static const struct archive_read_filter_vtable
-program_reader_vtable = {
- .read = program_filter_read,
- .close = program_filter_close,
-};
-
-int
-__archive_read_program(struct archive_read_filter *self, const char *cmd)
-{
- struct program_filter *state;
- static const size_t out_buf_len = 65536;
- char *out_buf;
- const char *prefix = "Program: ";
- int ret;
- size_t l;
-
- l = strlen(prefix) + strlen(cmd) + 1;
- state = (struct program_filter *)calloc(1, sizeof(*state));
- out_buf = (char *)malloc(out_buf_len);
- if (state == NULL || out_buf == NULL ||
- archive_string_ensure(&state->description, l) == NULL) {
- archive_set_error(&self->archive->archive, ENOMEM,
- "Can't allocate input data");
- if (state != NULL) {
- archive_string_free(&state->description);
- free(state);
- }
- free(out_buf);
- return (ARCHIVE_FATAL);
- }
- archive_strcpy(&state->description, prefix);
- archive_strcat(&state->description, cmd);
-
- self->code = ARCHIVE_FILTER_PROGRAM;
- self->name = state->description.s;
-
- state->out_buf = out_buf;
- state->out_buf_len = out_buf_len;
-
- ret = __archive_create_child(cmd, &state->child_stdin,
- &state->child_stdout, &state->child);
- if (ret != ARCHIVE_OK) {
- free(state->out_buf);
- archive_string_free(&state->description);
- free(state);
- archive_set_error(&self->archive->archive, EINVAL,
- "Can't initialize filter; unable to run program \"%s\"",
- cmd);
- return (ARCHIVE_FATAL);
- }
-
- self->data = state;
- self->vtable = &program_reader_vtable;
-
- /* XXX Check that we can read at least one byte? */
- return (ARCHIVE_OK);
-}
-
-static int
-program_bidder_init(struct archive_read_filter *self)
-{
- struct program_bidder *bidder_state;
-
- bidder_state = (struct program_bidder *)self->bidder->data;
- return (__archive_read_program(self, bidder_state->cmd));
-}
-
-static ssize_t
-program_filter_read(struct archive_read_filter *self, const void **buff)
-{
- struct program_filter *state;
- ssize_t bytes;
- size_t total;
- char *p;
-
- state = (struct program_filter *)self->data;
-
- total = 0;
- p = state->out_buf;
- while (state->child_stdout != -1 && total < state->out_buf_len) {
- bytes = child_read(self, p, state->out_buf_len - total);
- if (bytes < 0)
- /* No recovery is possible if we can no longer
- * read from the child. */
- return (ARCHIVE_FATAL);
- if (bytes == 0)
- /* We got EOF from the child. */
- break;
- total += bytes;
- p += bytes;
- }
-
- *buff = state->out_buf;
- return (total);
-}
-
-static int
-program_filter_close(struct archive_read_filter *self)
-{
- struct program_filter *state;
- int e;
-
- state = (struct program_filter *)self->data;
- e = child_stop(self, state);
-
- /* Release our private data. */
- free(state->out_buf);
- archive_string_free(&state->description);
- free(state);
-
- return (e);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_filter_rpm.c b/contrib/libs/libarchive/libarchive/archive_read_support_filter_rpm.c
deleted file mode 100644
index 67a979cd78..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_filter_rpm.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/*-
- * Copyright (c) 2009 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#include "archive.h"
-#include "archive_endian.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-struct rpm {
- int64_t total_in;
- size_t hpos;
- size_t hlen;
- unsigned char header[16];
- enum {
- ST_LEAD, /* Skipping 'Lead' section. */
- ST_HEADER, /* Reading 'Header' section;
- * first 16 bytes. */
- ST_HEADER_DATA, /* Skipping 'Header' section. */
- ST_PADDING, /* Skipping padding data after the
- * 'Header' section. */
- ST_ARCHIVE /* Reading 'Archive' section. */
- } state;
- int first_header;
-};
-#define RPM_LEAD_SIZE 96 /* Size of 'Lead' section. */
-
-static int rpm_bidder_bid(struct archive_read_filter_bidder *,
- struct archive_read_filter *);
-static int rpm_bidder_init(struct archive_read_filter *);
-
-static ssize_t rpm_filter_read(struct archive_read_filter *,
- const void **);
-static int rpm_filter_close(struct archive_read_filter *);
-
-#if ARCHIVE_VERSION_NUMBER < 4000000
-/* Deprecated; remove in libarchive 4.0 */
-int
-archive_read_support_compression_rpm(struct archive *a)
-{
- return archive_read_support_filter_rpm(a);
-}
-#endif
-
-static const struct archive_read_filter_bidder_vtable
-rpm_bidder_vtable = {
- .bid = rpm_bidder_bid,
- .init = rpm_bidder_init,
-};
-
-int
-archive_read_support_filter_rpm(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
-
- return __archive_read_register_bidder(a, NULL, "rpm",
- &rpm_bidder_vtable);
-}
-
-static int
-rpm_bidder_bid(struct archive_read_filter_bidder *self,
- struct archive_read_filter *filter)
-{
- const unsigned char *b;
- ssize_t avail;
- int bits_checked;
-
- (void)self; /* UNUSED */
-
- b = __archive_read_filter_ahead(filter, 8, &avail);
- if (b == NULL)
- return (0);
-
- bits_checked = 0;
- /*
- * Verify Header Magic Bytes : 0XED 0XAB 0XEE 0XDB
- */
- if (memcmp(b, "\xED\xAB\xEE\xDB", 4) != 0)
- return (0);
- bits_checked += 32;
- /*
- * Check major version.
- */
- if (b[4] != 3 && b[4] != 4)
- return (0);
- bits_checked += 8;
- /*
- * Check package type; binary or source.
- */
- if (b[6] != 0)
- return (0);
- bits_checked += 8;
- if (b[7] != 0 && b[7] != 1)
- return (0);
- bits_checked += 8;
-
- return (bits_checked);
-}
-
-static const struct archive_read_filter_vtable
-rpm_reader_vtable = {
- .read = rpm_filter_read,
- .close = rpm_filter_close,
-};
-
-static int
-rpm_bidder_init(struct archive_read_filter *self)
-{
- struct rpm *rpm;
-
- self->code = ARCHIVE_FILTER_RPM;
- self->name = "rpm";
-
- rpm = (struct rpm *)calloc(sizeof(*rpm), 1);
- if (rpm == NULL) {
- archive_set_error(&self->archive->archive, ENOMEM,
- "Can't allocate data for rpm");
- return (ARCHIVE_FATAL);
- }
-
- self->data = rpm;
- rpm->state = ST_LEAD;
- self->vtable = &rpm_reader_vtable;
-
- return (ARCHIVE_OK);
-}
-
-static ssize_t
-rpm_filter_read(struct archive_read_filter *self, const void **buff)
-{
- struct rpm *rpm;
- const unsigned char *b;
- ssize_t avail_in, total;
- size_t used, n;
- uint32_t section;
- uint32_t bytes;
-
- rpm = (struct rpm *)self->data;
- *buff = NULL;
- total = avail_in = 0;
- b = NULL;
- used = 0;
- do {
- if (b == NULL) {
- b = __archive_read_filter_ahead(self->upstream, 1,
- &avail_in);
- if (b == NULL) {
- if (avail_in < 0)
- return (ARCHIVE_FATAL);
- else
- break;
- }
- }
-
- switch (rpm->state) {
- case ST_LEAD:
- if (rpm->total_in + avail_in < RPM_LEAD_SIZE)
- used += avail_in;
- else {
- n = (size_t)(RPM_LEAD_SIZE - rpm->total_in);
- used += n;
- b += n;
- rpm->state = ST_HEADER;
- rpm->hpos = 0;
- rpm->hlen = 0;
- rpm->first_header = 1;
- }
- break;
- case ST_HEADER:
- n = 16 - rpm->hpos;
- if (n > avail_in - used)
- n = avail_in - used;
- memcpy(rpm->header+rpm->hpos, b, n);
- b += n;
- used += n;
- rpm->hpos += n;
-
- if (rpm->hpos == 16) {
- if (rpm->header[0] != 0x8e ||
- rpm->header[1] != 0xad ||
- rpm->header[2] != 0xe8 ||
- rpm->header[3] != 0x01) {
- if (rpm->first_header) {
- archive_set_error(
- &self->archive->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Unrecognized rpm header");
- return (ARCHIVE_FATAL);
- }
- rpm->state = ST_ARCHIVE;
- *buff = rpm->header;
- total = rpm->hpos;
- break;
- }
- /* Calculate 'Header' length. */
- section = archive_be32dec(rpm->header+8);
- bytes = archive_be32dec(rpm->header+12);
- rpm->hlen = 16 + section * 16 + bytes;
- rpm->state = ST_HEADER_DATA;
- rpm->first_header = 0;
- }
- break;
- case ST_HEADER_DATA:
- n = rpm->hlen - rpm->hpos;
- if (n > avail_in - used)
- n = avail_in - used;
- b += n;
- used += n;
- rpm->hpos += n;
- if (rpm->hpos == rpm->hlen)
- rpm->state = ST_PADDING;
- break;
- case ST_PADDING:
- while (used < (size_t)avail_in) {
- if (*b != 0) {
- /* Read next header. */
- rpm->state = ST_HEADER;
- rpm->hpos = 0;
- rpm->hlen = 0;
- break;
- }
- b++;
- used++;
- }
- break;
- case ST_ARCHIVE:
- *buff = b;
- total = avail_in;
- used = avail_in;
- break;
- }
- if (used == (size_t)avail_in) {
- rpm->total_in += used;
- __archive_read_filter_consume(self->upstream, used);
- b = NULL;
- used = 0;
- }
- } while (total == 0 && avail_in > 0);
-
- if (used > 0 && b != NULL) {
- rpm->total_in += used;
- __archive_read_filter_consume(self->upstream, used);
- }
- return (total);
-}
-
-static int
-rpm_filter_close(struct archive_read_filter *self)
-{
- struct rpm *rpm;
-
- rpm = (struct rpm *)self->data;
- free(rpm);
-
- return (ARCHIVE_OK);
-}
-
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_filter_uu.c b/contrib/libs/libarchive/libarchive/archive_read_support_filter_uu.c
deleted file mode 100644
index 209b2a1593..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_filter_uu.c
+++ /dev/null
@@ -1,683 +0,0 @@
-/*-
- * Copyright (c) 2009-2011 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-/* Maximum lookahead during bid phase */
-#define UUENCODE_BID_MAX_READ 128*1024 /* in bytes */
-
-struct uudecode {
- int64_t total;
- unsigned char *in_buff;
-#define IN_BUFF_SIZE (1024)
- int in_cnt;
- size_t in_allocated;
- unsigned char *out_buff;
-#define OUT_BUFF_SIZE (64 * 1024)
- int state;
-#define ST_FIND_HEAD 0
-#define ST_READ_UU 1
-#define ST_UUEND 2
-#define ST_READ_BASE64 3
-#define ST_IGNORE 4
-};
-
-static int uudecode_bidder_bid(struct archive_read_filter_bidder *,
- struct archive_read_filter *filter);
-static int uudecode_bidder_init(struct archive_read_filter *);
-
-static ssize_t uudecode_filter_read(struct archive_read_filter *,
- const void **);
-static int uudecode_filter_close(struct archive_read_filter *);
-
-#if ARCHIVE_VERSION_NUMBER < 4000000
-/* Deprecated; remove in libarchive 4.0 */
-int
-archive_read_support_compression_uu(struct archive *a)
-{
- return archive_read_support_filter_uu(a);
-}
-#endif
-
-static const struct archive_read_filter_bidder_vtable
-uudecode_bidder_vtable = {
- .bid = uudecode_bidder_bid,
- .init = uudecode_bidder_init,
-};
-
-int
-archive_read_support_filter_uu(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
-
- return __archive_read_register_bidder(a, NULL, "uu",
- &uudecode_bidder_vtable);
-}
-
-static const unsigned char ascii[256] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\n', 0, 0, '\r', 0, 0, /* 00 - 0F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 - 3F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* 70 - 7F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */
-};
-
-static const unsigned char uuchar[256] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 - 3F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 6F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 70 - 7F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */
-};
-
-static const unsigned char base64[256] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, /* 20 - 2F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, /* 30 - 3F */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 50 - 5F */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 70 - 7F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */
-};
-
-static const int base64num[128] = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 62, 0, 0, 0, 63, /* 20 - 2F */
- 52, 53, 54, 55, 56, 57, 58, 59,
- 60, 61, 0, 0, 0, 0, 0, 0, /* 30 - 3F */
- 0, 0, 1, 2, 3, 4, 5, 6,
- 7, 8, 9, 10, 11, 12, 13, 14, /* 40 - 4F */
- 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, 0, 0, 0, 0, 0, /* 50 - 5F */
- 0, 26, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, 38, 39, 40, /* 60 - 6F */
- 41, 42, 43, 44, 45, 46, 47, 48,
- 49, 50, 51, 0, 0, 0, 0, 0, /* 70 - 7F */
-};
-
-static ssize_t
-get_line(const unsigned char *b, ssize_t avail, ssize_t *nlsize)
-{
- ssize_t len;
-
- len = 0;
- while (len < avail) {
- switch (ascii[*b]) {
- case 0: /* Non-ascii character or control character. */
- if (nlsize != NULL)
- *nlsize = 0;
- return (-1);
- case '\r':
- if (avail-len > 1 && b[1] == '\n') {
- if (nlsize != NULL)
- *nlsize = 2;
- return (len+2);
- }
- /* FALL THROUGH */
- case '\n':
- if (nlsize != NULL)
- *nlsize = 1;
- return (len+1);
- case 1:
- b++;
- len++;
- break;
- }
- }
- if (nlsize != NULL)
- *nlsize = 0;
- return (avail);
-}
-
-static ssize_t
-bid_get_line(struct archive_read_filter *filter,
- const unsigned char **b, ssize_t *avail, ssize_t *ravail,
- ssize_t *nl, size_t* nbytes_read)
-{
- ssize_t len;
- int quit;
-
- quit = 0;
- if (*avail == 0) {
- *nl = 0;
- len = 0;
- } else
- len = get_line(*b, *avail, nl);
-
- /*
- * Read bytes more while it does not reach the end of line.
- */
- while (*nl == 0 && len == *avail && !quit &&
- *nbytes_read < UUENCODE_BID_MAX_READ) {
- ssize_t diff = *ravail - *avail;
- size_t nbytes_req = (*ravail+1023) & ~1023U;
- ssize_t tested;
-
- /* Increase reading bytes if it is not enough to at least
- * new two lines. */
- if (nbytes_req < (size_t)*ravail + 160)
- nbytes_req <<= 1;
-
- *b = __archive_read_filter_ahead(filter, nbytes_req, avail);
- if (*b == NULL) {
- if (*ravail >= *avail)
- return (0);
- /* Reading bytes reaches the end of a stream. */
- *b = __archive_read_filter_ahead(filter, *avail, avail);
- quit = 1;
- }
- *nbytes_read = *avail;
- *ravail = *avail;
- *b += diff;
- *avail -= diff;
- tested = len;/* Skip some bytes we already determined. */
- len = get_line(*b + tested, *avail - tested, nl);
- if (len >= 0)
- len += tested;
- }
- return (len);
-}
-
-#define UUDECODE(c) (((c) - 0x20) & 0x3f)
-
-static int
-uudecode_bidder_bid(struct archive_read_filter_bidder *self,
- struct archive_read_filter *filter)
-{
- const unsigned char *b;
- ssize_t avail, ravail;
- ssize_t len, nl;
- int l;
- int firstline;
- size_t nbytes_read;
-
- (void)self; /* UNUSED */
-
- b = __archive_read_filter_ahead(filter, 1, &avail);
- if (b == NULL)
- return (0);
-
- firstline = 20;
- ravail = avail;
- nbytes_read = avail;
- for (;;) {
- len = bid_get_line(filter, &b, &avail, &ravail, &nl, &nbytes_read);
- if (len < 0 || nl == 0)
- return (0); /* No match found. */
- if (len - nl >= 11 && memcmp(b, "begin ", 6) == 0)
- l = 6;
- else if (len -nl >= 18 && memcmp(b, "begin-base64 ", 13) == 0)
- l = 13;
- else
- l = 0;
-
- if (l > 0 && (b[l] < '0' || b[l] > '7' ||
- b[l+1] < '0' || b[l+1] > '7' ||
- b[l+2] < '0' || b[l+2] > '7' || b[l+3] != ' '))
- l = 0;
-
- b += len;
- avail -= len;
- if (l)
- break;
- firstline = 0;
-
- /* Do not read more than UUENCODE_BID_MAX_READ bytes */
- if (nbytes_read >= UUENCODE_BID_MAX_READ)
- return (0);
- }
- if (!avail)
- return (0);
- len = bid_get_line(filter, &b, &avail, &ravail, &nl, &nbytes_read);
- if (len < 0 || nl == 0)
- return (0);/* There are non-ascii characters. */
- avail -= len;
-
- if (l == 6) {
- /* "begin " */
- if (!uuchar[*b])
- return (0);
- /* Get a length of decoded bytes. */
- l = UUDECODE(*b++); len--;
- if (l > 45)
- /* Normally, maximum length is 45(character 'M'). */
- return (0);
- if (l > len - nl)
- return (0); /* Line too short. */
- while (l) {
- if (!uuchar[*b++])
- return (0);
- --len;
- --l;
- }
- if (len-nl == 1 &&
- (uuchar[*b] || /* Check sum. */
- (*b >= 'a' && *b <= 'z'))) {/* Padding data(MINIX). */
- ++b;
- --len;
- }
- b += nl;
- if (avail && uuchar[*b])
- return (firstline+30);
- } else if (l == 13) {
- /* "begin-base64 " */
- while (len-nl > 0) {
- if (!base64[*b++])
- return (0);
- --len;
- }
- b += nl;
-
- if (avail >= 5 && memcmp(b, "====\n", 5) == 0)
- return (firstline+40);
- if (avail >= 6 && memcmp(b, "====\r\n", 6) == 0)
- return (firstline+40);
- if (avail > 0 && base64[*b])
- return (firstline+30);
- }
-
- return (0);
-}
-
-static const struct archive_read_filter_vtable
-uudecode_reader_vtable = {
- .read = uudecode_filter_read,
- .close = uudecode_filter_close,
-};
-
-static int
-uudecode_bidder_init(struct archive_read_filter *self)
-{
- struct uudecode *uudecode;
- void *out_buff;
- void *in_buff;
-
- self->code = ARCHIVE_FILTER_UU;
- self->name = "uu";
-
- uudecode = (struct uudecode *)calloc(sizeof(*uudecode), 1);
- out_buff = malloc(OUT_BUFF_SIZE);
- in_buff = malloc(IN_BUFF_SIZE);
- if (uudecode == NULL || out_buff == NULL || in_buff == NULL) {
- archive_set_error(&self->archive->archive, ENOMEM,
- "Can't allocate data for uudecode");
- free(uudecode);
- free(out_buff);
- free(in_buff);
- return (ARCHIVE_FATAL);
- }
-
- self->data = uudecode;
- uudecode->in_buff = in_buff;
- uudecode->in_cnt = 0;
- uudecode->in_allocated = IN_BUFF_SIZE;
- uudecode->out_buff = out_buff;
- uudecode->state = ST_FIND_HEAD;
- self->vtable = &uudecode_reader_vtable;
-
- return (ARCHIVE_OK);
-}
-
-static int
-ensure_in_buff_size(struct archive_read_filter *self,
- struct uudecode *uudecode, size_t size)
-{
-
- if (size > uudecode->in_allocated) {
- unsigned char *ptr;
- size_t newsize;
-
- /*
- * Calculate a new buffer size for in_buff.
- * Increase its value until it has enough size we need.
- */
- newsize = uudecode->in_allocated;
- do {
- if (newsize < IN_BUFF_SIZE*32)
- newsize <<= 1;
- else
- newsize += IN_BUFF_SIZE;
- } while (size > newsize);
- /* Allocate the new buffer. */
- ptr = malloc(newsize);
- if (ptr == NULL) {
- free(ptr);
- archive_set_error(&self->archive->archive,
- ENOMEM,
- "Can't allocate data for uudecode");
- return (ARCHIVE_FATAL);
- }
- /* Move the remaining data in in_buff into the new buffer. */
- if (uudecode->in_cnt)
- memmove(ptr, uudecode->in_buff, uudecode->in_cnt);
- /* Replace in_buff with the new buffer. */
- free(uudecode->in_buff);
- uudecode->in_buff = ptr;
- uudecode->in_allocated = newsize;
- }
- return (ARCHIVE_OK);
-}
-
-static ssize_t
-uudecode_filter_read(struct archive_read_filter *self, const void **buff)
-{
- struct uudecode *uudecode;
- const unsigned char *b, *d;
- unsigned char *out;
- ssize_t avail_in, ravail;
- ssize_t used;
- ssize_t total;
- ssize_t len, llen, nl;
-
- uudecode = (struct uudecode *)self->data;
-
-read_more:
- d = __archive_read_filter_ahead(self->upstream, 1, &avail_in);
- if (d == NULL && avail_in < 0)
- return (ARCHIVE_FATAL);
- /* Quiet a code analyzer; make sure avail_in must be zero
- * when d is NULL. */
- if (d == NULL)
- avail_in = 0;
- used = 0;
- total = 0;
- out = uudecode->out_buff;
- ravail = avail_in;
- if (uudecode->state == ST_IGNORE) {
- used = avail_in;
- goto finish;
- }
- if (uudecode->in_cnt) {
- /*
- * If there is remaining data which is saved by
- * previous calling, use it first.
- */
- if (ensure_in_buff_size(self, uudecode,
- avail_in + uudecode->in_cnt) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- memcpy(uudecode->in_buff + uudecode->in_cnt,
- d, avail_in);
- d = uudecode->in_buff;
- avail_in += uudecode->in_cnt;
- uudecode->in_cnt = 0;
- }
- for (;used < avail_in; d += llen, used += llen) {
- int64_t l, body;
-
- b = d;
- len = get_line(b, avail_in - used, &nl);
- if (len < 0) {
- /* Non-ascii character is found. */
- if (uudecode->state == ST_FIND_HEAD &&
- (uudecode->total > 0 || total > 0)) {
- uudecode->state = ST_IGNORE;
- used = avail_in;
- goto finish;
- }
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Insufficient compressed data");
- return (ARCHIVE_FATAL);
- }
- llen = len;
- if ((nl == 0) && (uudecode->state != ST_UUEND)) {
- if (total == 0 && ravail <= 0) {
- /* There is nothing more to read, fail */
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Missing format data");
- return (ARCHIVE_FATAL);
- }
- /*
- * Save remaining data which does not contain
- * NL('\n','\r').
- */
- if (ensure_in_buff_size(self, uudecode, len)
- != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- if (uudecode->in_buff != b)
- memmove(uudecode->in_buff, b, len);
- uudecode->in_cnt = (int)len;
- if (total == 0) {
- /* Do not return 0; it means end-of-file.
- * We should try to read bytes more. */
- __archive_read_filter_consume(
- self->upstream, ravail);
- goto read_more;
- }
- used += len;
- break;
- }
- switch (uudecode->state) {
- default:
- case ST_FIND_HEAD:
- /* Do not read more than UUENCODE_BID_MAX_READ bytes */
- if (total + len >= UUENCODE_BID_MAX_READ) {
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid format data");
- return (ARCHIVE_FATAL);
- }
- if (len - nl >= 11 && memcmp(b, "begin ", 6) == 0)
- l = 6;
- else if (len - nl >= 18 &&
- memcmp(b, "begin-base64 ", 13) == 0)
- l = 13;
- else
- l = 0;
- if (l != 0 && b[l] >= '0' && b[l] <= '7' &&
- b[l+1] >= '0' && b[l+1] <= '7' &&
- b[l+2] >= '0' && b[l+2] <= '7' && b[l+3] == ' ') {
- if (l == 6)
- uudecode->state = ST_READ_UU;
- else
- uudecode->state = ST_READ_BASE64;
- }
- break;
- case ST_READ_UU:
- if (total + len * 2 > OUT_BUFF_SIZE)
- goto finish;
- body = len - nl;
- if (!uuchar[*b] || body <= 0) {
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Insufficient compressed data");
- return (ARCHIVE_FATAL);
- }
- /* Get length of undecoded bytes of current line. */
- l = UUDECODE(*b++);
- body--;
- if (l > body) {
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Insufficient compressed data");
- return (ARCHIVE_FATAL);
- }
- if (l == 0) {
- uudecode->state = ST_UUEND;
- break;
- }
- while (l > 0) {
- int n = 0;
-
- if (!uuchar[b[0]] || !uuchar[b[1]])
- break;
- n = UUDECODE(*b++) << 18;
- n |= UUDECODE(*b++) << 12;
- *out++ = n >> 16; total++;
- --l;
-
- if (l > 0) {
- if (!uuchar[b[0]])
- break;
- n |= UUDECODE(*b++) << 6;
- *out++ = (n >> 8) & 0xFF; total++;
- --l;
- }
- if (l > 0) {
- if (!uuchar[b[0]])
- break;
- n |= UUDECODE(*b++);
- *out++ = n & 0xFF; total++;
- --l;
- }
- }
- if (l) {
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Insufficient compressed data");
- return (ARCHIVE_FATAL);
- }
- break;
- case ST_UUEND:
- if (len - nl == 3 && memcmp(b, "end ", 3) == 0)
- uudecode->state = ST_FIND_HEAD;
- else {
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Insufficient compressed data");
- return (ARCHIVE_FATAL);
- }
- break;
- case ST_READ_BASE64:
- if (total + len * 2 > OUT_BUFF_SIZE)
- goto finish;
- l = len - nl;
- if (l >= 3 && b[0] == '=' && b[1] == '=' &&
- b[2] == '=') {
- uudecode->state = ST_FIND_HEAD;
- break;
- }
- while (l > 0) {
- int n = 0;
-
- if (!base64[b[0]] || !base64[b[1]])
- break;
- n = base64num[*b++] << 18;
- n |= base64num[*b++] << 12;
- *out++ = n >> 16; total++;
- l -= 2;
-
- if (l > 0) {
- if (*b == '=')
- break;
- if (!base64[*b])
- break;
- n |= base64num[*b++] << 6;
- *out++ = (n >> 8) & 0xFF; total++;
- --l;
- }
- if (l > 0) {
- if (*b == '=')
- break;
- if (!base64[*b])
- break;
- n |= base64num[*b++];
- *out++ = n & 0xFF; total++;
- --l;
- }
- }
- if (l && *b != '=') {
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Insufficient compressed data");
- return (ARCHIVE_FATAL);
- }
- break;
- }
- }
-finish:
- if (ravail < avail_in)
- used -= avail_in - ravail;
- __archive_read_filter_consume(self->upstream, used);
-
- *buff = uudecode->out_buff;
- uudecode->total += total;
- return (total);
-}
-
-static int
-uudecode_filter_close(struct archive_read_filter *self)
-{
- struct uudecode *uudecode;
-
- uudecode = (struct uudecode *)self->data;
- free(uudecode->in_buff);
- free(uudecode->out_buff);
- free(uudecode);
-
- return (ARCHIVE_OK);
-}
-
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_filter_xz.c b/contrib/libs/libarchive/libarchive/archive_read_support_filter_xz.c
deleted file mode 100644
index 13d4ebd7e3..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_filter_xz.c
+++ /dev/null
@@ -1,793 +0,0 @@
-/*-
- * Copyright (c) 2009-2011 Michihiro NAKAJIMA
- * Copyright (c) 2003-2008 Tim Kientzle and Miklos Vajna
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#if HAVE_LZMA_H
-#error #include <lzma.h>
-#endif
-
-#include "archive.h"
-#include "archive_endian.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-#if HAVE_LZMA_H && HAVE_LIBLZMA
-
-struct private_data {
- lzma_stream stream;
- unsigned char *out_block;
- size_t out_block_size;
- int64_t total_out;
- char eof; /* True = found end of compressed data. */
- char in_stream;
-
- /* Following variables are used for lzip only. */
- char lzip_ver;
- uint32_t crc32;
- int64_t member_in;
- int64_t member_out;
-};
-
-#if LZMA_VERSION_MAJOR >= 5
-/* Effectively disable the limiter. */
-#define LZMA_MEMLIMIT UINT64_MAX
-#else
-/* NOTE: This needs to check memory size which running system has. */
-#define LZMA_MEMLIMIT (1U << 30)
-#endif
-
-/* Combined lzip/lzma/xz filter */
-static ssize_t xz_filter_read(struct archive_read_filter *, const void **);
-static int xz_filter_close(struct archive_read_filter *);
-static int xz_lzma_bidder_init(struct archive_read_filter *);
-
-#endif
-
-/*
- * Note that we can detect xz and lzma compressed files even if we
- * can't decompress them. (In fact, we like detecting them because we
- * can give better error messages.) So the bid framework here gets
- * compiled even if no lzma library is available.
- */
-static int xz_bidder_bid(struct archive_read_filter_bidder *,
- struct archive_read_filter *);
-static int xz_bidder_init(struct archive_read_filter *);
-static int lzma_bidder_bid(struct archive_read_filter_bidder *,
- struct archive_read_filter *);
-static int lzma_bidder_init(struct archive_read_filter *);
-static int lzip_has_member(struct archive_read_filter *);
-static int lzip_bidder_bid(struct archive_read_filter_bidder *,
- struct archive_read_filter *);
-static int lzip_bidder_init(struct archive_read_filter *);
-
-#if ARCHIVE_VERSION_NUMBER < 4000000
-/* Deprecated; remove in libarchive 4.0 */
-int
-archive_read_support_compression_xz(struct archive *a)
-{
- return archive_read_support_filter_xz(a);
-}
-#endif
-
-static const struct archive_read_filter_bidder_vtable
-xz_bidder_vtable = {
- .bid = xz_bidder_bid,
- .init = xz_bidder_init,
-};
-
-int
-archive_read_support_filter_xz(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
-
- if (__archive_read_register_bidder(a, NULL, "xz",
- &xz_bidder_vtable) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
-#if HAVE_LZMA_H && HAVE_LIBLZMA
- return (ARCHIVE_OK);
-#else
- archive_set_error(_a, ARCHIVE_ERRNO_MISC,
- "Using external xz program for xz decompression");
- return (ARCHIVE_WARN);
-#endif
-}
-
-#if ARCHIVE_VERSION_NUMBER < 4000000
-int
-archive_read_support_compression_lzma(struct archive *a)
-{
- return archive_read_support_filter_lzma(a);
-}
-#endif
-
-static const struct archive_read_filter_bidder_vtable
-lzma_bidder_vtable = {
- .bid = lzma_bidder_bid,
- .init = lzma_bidder_init,
-};
-
-int
-archive_read_support_filter_lzma(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
-
- if (__archive_read_register_bidder(a, NULL, "lzma",
- &lzma_bidder_vtable) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
-#if HAVE_LZMA_H && HAVE_LIBLZMA
- return (ARCHIVE_OK);
-#else
- archive_set_error(_a, ARCHIVE_ERRNO_MISC,
- "Using external lzma program for lzma decompression");
- return (ARCHIVE_WARN);
-#endif
-}
-
-
-#if ARCHIVE_VERSION_NUMBER < 4000000
-int
-archive_read_support_compression_lzip(struct archive *a)
-{
- return archive_read_support_filter_lzip(a);
-}
-#endif
-
-static const struct archive_read_filter_bidder_vtable
-lzip_bidder_vtable = {
- .bid = lzip_bidder_bid,
- .init = lzip_bidder_init,
-};
-
-int
-archive_read_support_filter_lzip(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
-
- if (__archive_read_register_bidder(a, NULL, "lzip",
- &lzip_bidder_vtable) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
-#if HAVE_LZMA_H && HAVE_LIBLZMA
- return (ARCHIVE_OK);
-#else
- archive_set_error(_a, ARCHIVE_ERRNO_MISC,
- "Using external lzip program for lzip decompression");
- return (ARCHIVE_WARN);
-#endif
-}
-
-/*
- * Test whether we can handle this data.
- */
-static int
-xz_bidder_bid(struct archive_read_filter_bidder *self,
- struct archive_read_filter *filter)
-{
- const unsigned char *buffer;
- ssize_t avail;
-
- (void)self; /* UNUSED */
-
- buffer = __archive_read_filter_ahead(filter, 6, &avail);
- if (buffer == NULL)
- return (0);
-
- /*
- * Verify Header Magic Bytes : FD 37 7A 58 5A 00
- */
- if (memcmp(buffer, "\xFD\x37\x7A\x58\x5A\x00", 6) != 0)
- return (0);
-
- return (48);
-}
-
-/*
- * Test whether we can handle this data.
- *
- * <sigh> LZMA has a rather poor file signature. Zeros do not
- * make good signature bytes as a rule, and the only non-zero byte
- * here is an ASCII character. For example, an uncompressed tar
- * archive whose first file is ']' would satisfy this check. It may
- * be necessary to exclude LZMA from compression_all() because of
- * this. Clients of libarchive would then have to explicitly enable
- * LZMA checking instead of (or in addition to) compression_all() when
- * they have other evidence (file name, command-line option) to go on.
- */
-static int
-lzma_bidder_bid(struct archive_read_filter_bidder *self,
- struct archive_read_filter *filter)
-{
- const unsigned char *buffer;
- ssize_t avail;
- uint32_t dicsize;
- uint64_t uncompressed_size;
- int bits_checked;
-
- (void)self; /* UNUSED */
-
- buffer = __archive_read_filter_ahead(filter, 14, &avail);
- if (buffer == NULL)
- return (0);
-
- /* First byte of raw LZMA stream is commonly 0x5d.
- * The first byte is a special number, which consists of
- * three parameters of LZMA compression, a number of literal
- * context bits(which is from 0 to 8, default is 3), a number
- * of literal pos bits(which is from 0 to 4, default is 0),
- * a number of pos bits(which is from 0 to 4, default is 2).
- * The first byte is made by
- * (pos bits * 5 + literal pos bit) * 9 + * literal contest bit,
- * and so the default value in this field is
- * (2 * 5 + 0) * 9 + 3 = 0x5d.
- * lzma of LZMA SDK has options to change those parameters.
- * It means a range of this field is from 0 to 224. And lzma of
- * XZ Utils with option -e records 0x5e in this field. */
- /* NOTE: If this checking of the first byte increases false
- * recognition, we should allow only 0x5d and 0x5e for the first
- * byte of LZMA stream. */
- bits_checked = 0;
- if (buffer[0] > (4 * 5 + 4) * 9 + 8)
- return (0);
- /* Most likely value in the first byte of LZMA stream. */
- if (buffer[0] == 0x5d || buffer[0] == 0x5e)
- bits_checked += 8;
-
- /* Sixth through fourteenth bytes are uncompressed size,
- * stored in little-endian order. `-1' means uncompressed
- * size is unknown and lzma of XZ Utils always records `-1'
- * in this field. */
- uncompressed_size = archive_le64dec(buffer+5);
- if (uncompressed_size == (uint64_t)ARCHIVE_LITERAL_LL(-1))
- bits_checked += 64;
-
- /* Second through fifth bytes are dictionary size, stored in
- * little-endian order. The minimum dictionary size is
- * 1 << 12(4KiB) which the lzma of LZMA SDK uses with option
- * -d12 and the maximum dictionary size is 1 << 29(512MiB)
- * which the one uses with option -d29.
- * NOTE: A comment of LZMA SDK source code says this dictionary
- * range is from 1 << 12 to 1 << 30. */
- dicsize = archive_le32dec(buffer+1);
- switch (dicsize) {
- case 0x00001000:/* lzma of LZMA SDK option -d12. */
- case 0x00002000:/* lzma of LZMA SDK option -d13. */
- case 0x00004000:/* lzma of LZMA SDK option -d14. */
- case 0x00008000:/* lzma of LZMA SDK option -d15. */
- case 0x00010000:/* lzma of XZ Utils option -0 and -1.
- * lzma of LZMA SDK option -d16. */
- case 0x00020000:/* lzma of LZMA SDK option -d17. */
- case 0x00040000:/* lzma of LZMA SDK option -d18. */
- case 0x00080000:/* lzma of XZ Utils option -2.
- * lzma of LZMA SDK option -d19. */
- case 0x00100000:/* lzma of XZ Utils option -3.
- * lzma of LZMA SDK option -d20. */
- case 0x00200000:/* lzma of XZ Utils option -4.
- * lzma of LZMA SDK option -d21. */
- case 0x00400000:/* lzma of XZ Utils option -5.
- * lzma of LZMA SDK option -d22. */
- case 0x00800000:/* lzma of XZ Utils option -6.
- * lzma of LZMA SDK option -d23. */
- case 0x01000000:/* lzma of XZ Utils option -7.
- * lzma of LZMA SDK option -d24. */
- case 0x02000000:/* lzma of XZ Utils option -8.
- * lzma of LZMA SDK option -d25. */
- case 0x04000000:/* lzma of XZ Utils option -9.
- * lzma of LZMA SDK option -d26. */
- case 0x08000000:/* lzma of LZMA SDK option -d27. */
- bits_checked += 32;
- break;
- default:
- /* If a memory usage for encoding was not enough on
- * the platform where LZMA stream was made, lzma of
- * XZ Utils automatically decreased the dictionary
- * size to enough memory for encoding by 1Mi bytes
- * (1 << 20).*/
- if (dicsize <= 0x03F00000 && dicsize >= 0x00300000 &&
- (dicsize & ((1 << 20)-1)) == 0 &&
- bits_checked == 8 + 64) {
- bits_checked += 32;
- break;
- }
- /* Otherwise dictionary size is unlikely. But it is
- * possible that someone makes lzma stream with
- * liblzma/LZMA SDK in one's dictionary size. */
- return (0);
- }
-
- /* TODO: The above test is still very weak. It would be
- * good to do better. */
-
- return (bits_checked);
-}
-
-static int
-lzip_has_member(struct archive_read_filter *filter)
-{
- const unsigned char *buffer;
- ssize_t avail;
- int bits_checked;
- int log2dic;
-
- buffer = __archive_read_filter_ahead(filter, 6, &avail);
- if (buffer == NULL)
- return (0);
-
- /*
- * Verify Header Magic Bytes : 4C 5A 49 50 (`LZIP')
- */
- bits_checked = 0;
- if (memcmp(buffer, "LZIP", 4) != 0)
- return (0);
- bits_checked += 32;
-
- /* A version number must be 0 or 1 */
- if (buffer[4] != 0 && buffer[4] != 1)
- return (0);
- bits_checked += 8;
-
- /* Dictionary size. */
- log2dic = buffer[5] & 0x1f;
- if (log2dic < 12 || log2dic > 29)
- return (0);
- bits_checked += 8;
-
- return (bits_checked);
-}
-
-static int
-lzip_bidder_bid(struct archive_read_filter_bidder *self,
- struct archive_read_filter *filter)
-{
-
- (void)self; /* UNUSED */
- return (lzip_has_member(filter));
-}
-
-#if HAVE_LZMA_H && HAVE_LIBLZMA
-
-/*
- * liblzma 4.999.7 and later support both lzma and xz streams.
- */
-static int
-xz_bidder_init(struct archive_read_filter *self)
-{
- self->code = ARCHIVE_FILTER_XZ;
- self->name = "xz";
- return (xz_lzma_bidder_init(self));
-}
-
-static int
-lzma_bidder_init(struct archive_read_filter *self)
-{
- self->code = ARCHIVE_FILTER_LZMA;
- self->name = "lzma";
- return (xz_lzma_bidder_init(self));
-}
-
-static int
-lzip_bidder_init(struct archive_read_filter *self)
-{
- self->code = ARCHIVE_FILTER_LZIP;
- self->name = "lzip";
- return (xz_lzma_bidder_init(self));
-}
-
-/*
- * Set an error code and choose an error message
- */
-static void
-set_error(struct archive_read_filter *self, int ret)
-{
-
- switch (ret) {
- case LZMA_STREAM_END: /* Found end of stream. */
- case LZMA_OK: /* Decompressor made some progress. */
- break;
- case LZMA_MEM_ERROR:
- archive_set_error(&self->archive->archive, ENOMEM,
- "Lzma library error: Cannot allocate memory");
- break;
- case LZMA_MEMLIMIT_ERROR:
- archive_set_error(&self->archive->archive, ENOMEM,
- "Lzma library error: Out of memory");
- break;
- case LZMA_FORMAT_ERROR:
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Lzma library error: format not recognized");
- break;
- case LZMA_OPTIONS_ERROR:
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Lzma library error: Invalid options");
- break;
- case LZMA_DATA_ERROR:
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Lzma library error: Corrupted input data");
- break;
- case LZMA_BUF_ERROR:
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Lzma library error: No progress is possible");
- break;
- default:
- /* Return an error. */
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Lzma decompression failed: Unknown error");
- break;
- }
-}
-
-static const struct archive_read_filter_vtable
-xz_lzma_reader_vtable = {
- .read = xz_filter_read,
- .close = xz_filter_close,
-};
-
-/*
- * Setup the callbacks.
- */
-static int
-xz_lzma_bidder_init(struct archive_read_filter *self)
-{
- static const size_t out_block_size = 64 * 1024;
- void *out_block;
- struct private_data *state;
- int ret;
-
- state = (struct private_data *)calloc(sizeof(*state), 1);
- out_block = (unsigned char *)malloc(out_block_size);
- if (state == NULL || out_block == NULL) {
- archive_set_error(&self->archive->archive, ENOMEM,
- "Can't allocate data for xz decompression");
- free(out_block);
- free(state);
- return (ARCHIVE_FATAL);
- }
-
- self->data = state;
- state->out_block_size = out_block_size;
- state->out_block = out_block;
- self->vtable = &xz_lzma_reader_vtable;
-
- state->stream.avail_in = 0;
-
- state->stream.next_out = state->out_block;
- state->stream.avail_out = state->out_block_size;
-
- state->crc32 = 0;
- if (self->code == ARCHIVE_FILTER_LZIP) {
- /*
- * We have to read a lzip header and use it to initialize
- * compression library, thus we cannot initialize the
- * library for lzip here.
- */
- state->in_stream = 0;
- return (ARCHIVE_OK);
- } else
- state->in_stream = 1;
-
- /* Initialize compression library. */
- if (self->code == ARCHIVE_FILTER_XZ)
- ret = lzma_stream_decoder(&(state->stream),
- LZMA_MEMLIMIT,/* memlimit */
- LZMA_CONCATENATED);
- else
- ret = lzma_alone_decoder(&(state->stream),
- LZMA_MEMLIMIT);/* memlimit */
-
- if (ret == LZMA_OK)
- return (ARCHIVE_OK);
-
- /* Library setup failed: Choose an error message and clean up. */
- set_error(self, ret);
-
- free(state->out_block);
- free(state);
- self->data = NULL;
- return (ARCHIVE_FATAL);
-}
-
-static int
-lzip_init(struct archive_read_filter *self)
-{
- struct private_data *state;
- const unsigned char *h;
- lzma_filter filters[2];
- unsigned char props[5];
- ssize_t avail_in;
- uint32_t dicsize;
- int log2dic, ret;
-
- state = (struct private_data *)self->data;
- h = __archive_read_filter_ahead(self->upstream, 6, &avail_in);
- if (h == NULL)
- return (ARCHIVE_FATAL);
-
- /* Get a version number. */
- state->lzip_ver = h[4];
-
- /*
- * Setup lzma property.
- */
- props[0] = 0x5d;
-
- /* Get dictionary size. */
- log2dic = h[5] & 0x1f;
- if (log2dic < 12 || log2dic > 29)
- return (ARCHIVE_FATAL);
- dicsize = 1U << log2dic;
- if (log2dic > 12)
- dicsize -= (dicsize / 16) * (h[5] >> 5);
- archive_le32enc(props+1, dicsize);
-
- /* Consume lzip header. */
- __archive_read_filter_consume(self->upstream, 6);
- state->member_in = 6;
-
- filters[0].id = LZMA_FILTER_LZMA1;
- filters[0].options = NULL;
- filters[1].id = LZMA_VLI_UNKNOWN;
- filters[1].options = NULL;
-
- ret = lzma_properties_decode(&filters[0], NULL, props, sizeof(props));
- if (ret != LZMA_OK) {
- set_error(self, ret);
- return (ARCHIVE_FATAL);
- }
- ret = lzma_raw_decoder(&(state->stream), filters);
- free(filters[0].options);
- if (ret != LZMA_OK) {
- set_error(self, ret);
- return (ARCHIVE_FATAL);
- }
- return (ARCHIVE_OK);
-}
-
-static int
-lzip_tail(struct archive_read_filter *self)
-{
- struct private_data *state;
- const unsigned char *f;
- ssize_t avail_in;
- int tail;
-
- state = (struct private_data *)self->data;
- if (state->lzip_ver == 0)
- tail = 12;
- else
- tail = 20;
- f = __archive_read_filter_ahead(self->upstream, tail, &avail_in);
- if (f == NULL && avail_in < 0)
- return (ARCHIVE_FATAL);
- if (f == NULL || avail_in < tail) {
- archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
- "Lzip: Remaining data is less bytes");
- return (ARCHIVE_FAILED);
- }
-
- /* Check the crc32 value of the uncompressed data of the current
- * member */
- if (state->crc32 != archive_le32dec(f)) {
-#ifndef DONT_FAIL_ON_CRC_ERROR
- archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
- "Lzip: CRC32 error");
- return (ARCHIVE_FAILED);
-#endif
- }
-
- /* Check the uncompressed size of the current member */
- if ((uint64_t)state->member_out != archive_le64dec(f + 4)) {
- archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
- "Lzip: Uncompressed size error");
- return (ARCHIVE_FAILED);
- }
-
- /* Check the total size of the current member */
- if (state->lzip_ver == 1 &&
- (uint64_t)state->member_in + tail != archive_le64dec(f + 12)) {
- archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
- "Lzip: Member size error");
- return (ARCHIVE_FAILED);
- }
- __archive_read_filter_consume(self->upstream, tail);
-
- /* If current lzip data consists of multi member, try decompressing
- * a next member. */
- if (lzip_has_member(self->upstream) != 0) {
- state->in_stream = 0;
- state->crc32 = 0;
- state->member_out = 0;
- state->member_in = 0;
- state->eof = 0;
- }
- return (ARCHIVE_OK);
-}
-
-/*
- * Return the next block of decompressed data.
- */
-static ssize_t
-xz_filter_read(struct archive_read_filter *self, const void **p)
-{
- struct private_data *state;
- size_t decompressed;
- ssize_t avail_in;
- int ret;
-
- state = (struct private_data *)self->data;
-
- /* Empty our output buffer. */
- state->stream.next_out = state->out_block;
- state->stream.avail_out = state->out_block_size;
-
- /* Try to fill the output buffer. */
- while (state->stream.avail_out > 0 && !state->eof) {
- if (!state->in_stream) {
- /*
- * Initialize liblzma for lzip
- */
- ret = lzip_init(self);
- if (ret != ARCHIVE_OK)
- return (ret);
- state->in_stream = 1;
- }
- state->stream.next_in =
- __archive_read_filter_ahead(self->upstream, 1, &avail_in);
- if (state->stream.next_in == NULL && avail_in < 0) {
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "truncated input");
- return (ARCHIVE_FATAL);
- }
- state->stream.avail_in = avail_in;
-
- /* Decompress as much as we can in one pass. */
- ret = lzma_code(&(state->stream),
- (state->stream.avail_in == 0)? LZMA_FINISH: LZMA_RUN);
- switch (ret) {
- case LZMA_STREAM_END: /* Found end of stream. */
- state->eof = 1;
- /* FALL THROUGH */
- case LZMA_OK: /* Decompressor made some progress. */
- __archive_read_filter_consume(self->upstream,
- avail_in - state->stream.avail_in);
- state->member_in +=
- avail_in - state->stream.avail_in;
- break;
- default:
- set_error(self, ret);
- return (ARCHIVE_FATAL);
- }
- }
-
- decompressed = state->stream.next_out - state->out_block;
- state->total_out += decompressed;
- state->member_out += decompressed;
- if (decompressed == 0)
- *p = NULL;
- else {
- *p = state->out_block;
- if (self->code == ARCHIVE_FILTER_LZIP) {
- state->crc32 = lzma_crc32(state->out_block,
- decompressed, state->crc32);
- if (state->eof) {
- ret = lzip_tail(self);
- if (ret != ARCHIVE_OK)
- return (ret);
- }
- }
- }
- return (decompressed);
-}
-
-/*
- * Clean up the decompressor.
- */
-static int
-xz_filter_close(struct archive_read_filter *self)
-{
- struct private_data *state;
-
- state = (struct private_data *)self->data;
- lzma_end(&(state->stream));
- free(state->out_block);
- free(state);
- return (ARCHIVE_OK);
-}
-
-#else
-
-/*
- *
- * If we have no suitable library on this system, we can't actually do
- * the decompression. We can, however, still detect compressed
- * archives and emit a useful message.
- *
- */
-static int
-lzma_bidder_init(struct archive_read_filter *self)
-{
- int r;
-
- r = __archive_read_program(self, "lzma -d -qq");
- /* Note: We set the format here even if __archive_read_program()
- * above fails. We do, after all, know what the format is
- * even if we weren't able to read it. */
- self->code = ARCHIVE_FILTER_LZMA;
- self->name = "lzma";
- return (r);
-}
-
-static int
-xz_bidder_init(struct archive_read_filter *self)
-{
- int r;
-
- r = __archive_read_program(self, "xz -d -qq");
- /* Note: We set the format here even if __archive_read_program()
- * above fails. We do, after all, know what the format is
- * even if we weren't able to read it. */
- self->code = ARCHIVE_FILTER_XZ;
- self->name = "xz";
- return (r);
-}
-
-static int
-lzip_bidder_init(struct archive_read_filter *self)
-{
- int r;
-
- r = __archive_read_program(self, "lzip -d -q");
- /* Note: We set the format here even if __archive_read_program()
- * above fails. We do, after all, know what the format is
- * even if we weren't able to read it. */
- self->code = ARCHIVE_FILTER_LZIP;
- self->name = "lzip";
- return (r);
-}
-
-#endif /* HAVE_LZMA_H */
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_filter_zstd.c b/contrib/libs/libarchive/libarchive/archive_read_support_filter_zstd.c
deleted file mode 100644
index 1959b5ac39..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_filter_zstd.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*-
- * Copyright (c) 2009-2011 Sean Purcell
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#if HAVE_ZSTD_H
-#include <zstd.h>
-#endif
-
-#include "archive.h"
-#include "archive_endian.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-#if HAVE_ZSTD_H && HAVE_LIBZSTD
-
-struct private_data {
- ZSTD_DStream *dstream;
- unsigned char *out_block;
- size_t out_block_size;
- int64_t total_out;
- char in_frame; /* True = in the middle of a zstd frame. */
- char eof; /* True = found end of compressed data. */
-};
-
-/* Zstd Filter. */
-static ssize_t zstd_filter_read(struct archive_read_filter *, const void**);
-static int zstd_filter_close(struct archive_read_filter *);
-#endif
-
-/*
- * Note that we can detect zstd compressed files even if we can't decompress
- * them. (In fact, we like detecting them because we can give better error
- * messages.) So the bid framework here gets compiled even if no zstd library
- * is available.
- */
-static int zstd_bidder_bid(struct archive_read_filter_bidder *,
- struct archive_read_filter *);
-static int zstd_bidder_init(struct archive_read_filter *);
-
-static const struct archive_read_filter_bidder_vtable
-zstd_bidder_vtable = {
- .bid = zstd_bidder_bid,
- .init = zstd_bidder_init,
-};
-
-int
-archive_read_support_filter_zstd(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
-
- if (__archive_read_register_bidder(a, NULL, "zstd",
- &zstd_bidder_vtable) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
-#if HAVE_ZSTD_H && HAVE_LIBZSTD
- return (ARCHIVE_OK);
-#else
- archive_set_error(_a, ARCHIVE_ERRNO_MISC,
- "Using external zstd program for zstd decompression");
- return (ARCHIVE_WARN);
-#endif
-}
-
-/*
- * Test whether we can handle this data.
- */
-static int
-zstd_bidder_bid(struct archive_read_filter_bidder *self,
- struct archive_read_filter *filter)
-{
- const unsigned char *buffer;
- ssize_t avail;
- unsigned prefix;
-
- /* Zstd frame magic values */
- unsigned zstd_magic = 0xFD2FB528U;
- unsigned zstd_magic_skippable_start = 0x184D2A50U;
- unsigned zstd_magic_skippable_mask = 0xFFFFFFF0;
-
- (void) self; /* UNUSED */
-
- buffer = __archive_read_filter_ahead(filter, 4, &avail);
- if (buffer == NULL)
- return (0);
-
- prefix = archive_le32dec(buffer);
- if (prefix == zstd_magic)
- return (32);
- if ((prefix & zstd_magic_skippable_mask) == zstd_magic_skippable_start)
- return (32);
-
- return (0);
-}
-
-#if !(HAVE_ZSTD_H && HAVE_LIBZSTD)
-
-/*
- * If we don't have the library on this system, we can't do the
- * decompression directly. We can, however, try to run "zstd -d"
- * in case that's available.
- */
-static int
-zstd_bidder_init(struct archive_read_filter *self)
-{
- int r;
-
- r = __archive_read_program(self, "zstd -d -qq");
- /* Note: We set the format here even if __archive_read_program()
- * above fails. We do, after all, know what the format is
- * even if we weren't able to read it. */
- self->code = ARCHIVE_FILTER_ZSTD;
- self->name = "zstd";
- return (r);
-}
-
-#else
-
-static const struct archive_read_filter_vtable
-zstd_reader_vtable = {
- .read = zstd_filter_read,
- .close = zstd_filter_close,
-};
-
-/*
- * Initialize the filter object
- */
-static int
-zstd_bidder_init(struct archive_read_filter *self)
-{
- struct private_data *state;
- size_t out_block_size = ZSTD_DStreamOutSize();
- void *out_block;
- ZSTD_DStream *dstream;
-
- self->code = ARCHIVE_FILTER_ZSTD;
- self->name = "zstd";
-
- state = (struct private_data *)calloc(sizeof(*state), 1);
- out_block = (unsigned char *)malloc(out_block_size);
- dstream = ZSTD_createDStream();
-
- if (state == NULL || out_block == NULL || dstream == NULL) {
- free(out_block);
- free(state);
- ZSTD_freeDStream(dstream); /* supports free on NULL */
- archive_set_error(&self->archive->archive, ENOMEM,
- "Can't allocate data for zstd decompression");
- return (ARCHIVE_FATAL);
- }
-
- self->data = state;
-
- state->out_block_size = out_block_size;
- state->out_block = out_block;
- state->dstream = dstream;
- self->vtable = &zstd_reader_vtable;
-
- state->eof = 0;
- state->in_frame = 0;
-
- return (ARCHIVE_OK);
-}
-
-static ssize_t
-zstd_filter_read(struct archive_read_filter *self, const void **p)
-{
- struct private_data *state;
- size_t decompressed;
- ssize_t avail_in;
- ZSTD_outBuffer out;
- ZSTD_inBuffer in;
- size_t ret;
-
- state = (struct private_data *)self->data;
-
- out = (ZSTD_outBuffer) { state->out_block, state->out_block_size, 0 };
-
- /* Try to fill the output buffer. */
- while (out.pos < out.size && !state->eof) {
- if (!state->in_frame) {
- ret = ZSTD_initDStream(state->dstream);
- if (ZSTD_isError(ret)) {
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Error initializing zstd decompressor: %s",
- ZSTD_getErrorName(ret));
- return (ARCHIVE_FATAL);
- }
- }
- in.src = __archive_read_filter_ahead(self->upstream, 1,
- &avail_in);
- if (avail_in < 0) {
- return avail_in;
- }
- if (in.src == NULL && avail_in == 0) {
- if (!state->in_frame) {
- /* end of stream */
- state->eof = 1;
- break;
- } else {
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Truncated zstd input");
- return (ARCHIVE_FATAL);
- }
- }
- in.size = avail_in;
- in.pos = 0;
-
- {
- ret = ZSTD_decompressStream(state->dstream, &out, &in);
-
- if (ZSTD_isError(ret)) {
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Zstd decompression failed: %s",
- ZSTD_getErrorName(ret));
- return (ARCHIVE_FATAL);
- }
-
- /* Decompressor made some progress */
- __archive_read_filter_consume(self->upstream, in.pos);
-
- /* ret guaranteed to be > 0 if frame isn't done yet */
- state->in_frame = (ret != 0);
- }
- }
-
- decompressed = out.pos;
- state->total_out += decompressed;
- if (decompressed == 0)
- *p = NULL;
- else
- *p = state->out_block;
- return (decompressed);
-}
-
-/*
- * Clean up the decompressor.
- */
-static int
-zstd_filter_close(struct archive_read_filter *self)
-{
- struct private_data *state;
-
- state = (struct private_data *)self->data;
-
- ZSTD_freeDStream(state->dstream);
- free(state->out_block);
- free(state);
-
- return (ARCHIVE_OK);
-}
-
-#endif /* HAVE_ZLIB_H && HAVE_LIBZSTD */
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_format_7zip.c b/contrib/libs/libarchive/libarchive/archive_read_support_format_7zip.c
deleted file mode 100644
index 87dd540ba1..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_format_7zip.c
+++ /dev/null
@@ -1,4074 +0,0 @@
-/*-
- * Copyright (c) 2011 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_BZLIB_H
-#include <bzlib.h>
-#endif
-#ifdef HAVE_LZMA_H
-#error #include <lzma.h>
-#endif
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-#ifdef HAVE_ZSTD_H
-#include <zstd.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_ppmd7_private.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-#include "archive_endian.h"
-
-#ifndef HAVE_ZLIB_H
-#error #include "archive_crc32.h"
-#endif
-
-#define _7ZIP_SIGNATURE "7z\xBC\xAF\x27\x1C"
-#define SFX_MIN_ADDR 0x27000
-#define SFX_MAX_ADDR 0x60000
-
-
-/*
- * Codec ID
- */
-#define _7Z_COPY 0
-#define _7Z_LZMA 0x030101
-#define _7Z_LZMA2 0x21
-#define _7Z_DEFLATE 0x040108
-#define _7Z_BZ2 0x040202
-#define _7Z_PPMD 0x030401
-#define _7Z_DELTA 0x03
-#define _7Z_CRYPTO_MAIN_ZIP 0x06F10101 /* Main Zip crypto algo */
-#define _7Z_CRYPTO_RAR_29 0x06F10303 /* Rar29 AES-128 + (modified SHA-1) */
-#define _7Z_CRYPTO_AES_256_SHA_256 0x06F10701 /* AES-256 + SHA-256 */
-
-
-#define _7Z_X86 0x03030103
-#define _7Z_X86_BCJ2 0x0303011B
-#define _7Z_POWERPC 0x03030205
-#define _7Z_IA64 0x03030401
-#define _7Z_ARM 0x03030501
-#define _7Z_ARMTHUMB 0x03030701
-#define _7Z_ARM64 0xa
-#define _7Z_SPARC 0x03030805
-
-#define _7Z_ZSTD 0x4F71101 /* Copied from https://github.com/mcmilk/7-Zip-zstd.git */
-
-/*
- * 7-Zip header property IDs.
- */
-#define kEnd 0x00
-#define kHeader 0x01
-#define kArchiveProperties 0x02
-#define kAdditionalStreamsInfo 0x03
-#define kMainStreamsInfo 0x04
-#define kFilesInfo 0x05
-#define kPackInfo 0x06
-#define kUnPackInfo 0x07
-#define kSubStreamsInfo 0x08
-#define kSize 0x09
-#define kCRC 0x0A
-#define kFolder 0x0B
-#define kCodersUnPackSize 0x0C
-#define kNumUnPackStream 0x0D
-#define kEmptyStream 0x0E
-#define kEmptyFile 0x0F
-#define kAnti 0x10
-#define kName 0x11
-#define kCTime 0x12
-#define kATime 0x13
-#define kMTime 0x14
-#define kAttributes 0x15
-#define kEncodedHeader 0x17
-#define kDummy 0x19
-
-struct _7z_digests {
- unsigned char *defineds;
- uint32_t *digests;
-};
-
-
-struct _7z_folder {
- uint64_t numCoders;
- struct _7z_coder {
- unsigned long codec;
- uint64_t numInStreams;
- uint64_t numOutStreams;
- uint64_t propertiesSize;
- unsigned char *properties;
- } *coders;
- uint64_t numBindPairs;
- struct {
- uint64_t inIndex;
- uint64_t outIndex;
- } *bindPairs;
- uint64_t numPackedStreams;
- uint64_t *packedStreams;
- uint64_t numInStreams;
- uint64_t numOutStreams;
- uint64_t *unPackSize;
- unsigned char digest_defined;
- uint32_t digest;
- uint64_t numUnpackStreams;
- uint32_t packIndex;
- /* Unoperated bytes. */
- uint64_t skipped_bytes;
-};
-
-struct _7z_coders_info {
- uint64_t numFolders;
- struct _7z_folder *folders;
- uint64_t dataStreamIndex;
-};
-
-struct _7z_pack_info {
- uint64_t pos;
- uint64_t numPackStreams;
- uint64_t *sizes;
- struct _7z_digests digest;
- /* Calculated from pos and numPackStreams. */
- uint64_t *positions;
-};
-
-struct _7z_substream_info {
- size_t unpack_streams;
- uint64_t *unpackSizes;
- unsigned char *digestsDefined;
- uint32_t *digests;
-};
-
-struct _7z_stream_info {
- struct _7z_pack_info pi;
- struct _7z_coders_info ci;
- struct _7z_substream_info ss;
-};
-
-struct _7z_header_info {
- uint64_t dataIndex;
-
- unsigned char *emptyStreamBools;
- unsigned char *emptyFileBools;
- unsigned char *antiBools;
- unsigned char *attrBools;
-};
-
-struct _7zip_entry {
- size_t name_len;
- unsigned char *utf16name;
-#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
- const wchar_t *wname;
-#endif
- uint32_t folderIndex;
- uint32_t ssIndex;
- unsigned flg;
-#define MTIME_IS_SET (1<<0)
-#define ATIME_IS_SET (1<<1)
-#define CTIME_IS_SET (1<<2)
-#define CRC32_IS_SET (1<<3)
-#define HAS_STREAM (1<<4)
-
- time_t mtime;
- time_t atime;
- time_t ctime;
- long mtime_ns;
- long atime_ns;
- long ctime_ns;
- uint32_t mode;
- uint32_t attr;
-};
-
-struct _7zip {
- /* Structural information about the archive. */
- struct _7z_stream_info si;
-
- int header_is_being_read;
- int header_is_encoded;
- uint64_t header_bytes_remaining;
- unsigned long header_crc32;
- /* Header offset to check that reading points of the file contents
- * will not exceed the header. */
- uint64_t header_offset;
- /* Base offset of the archive file for a seek in case reading SFX. */
- uint64_t seek_base;
-
- /* List of entries */
- size_t entries_remaining;
- uint64_t numFiles;
- struct _7zip_entry *entries;
- struct _7zip_entry *entry;
- unsigned char *entry_names;
-
- /* entry_bytes_remaining is the number of bytes we expect. */
- int64_t entry_offset;
- uint64_t entry_bytes_remaining;
-
- /* Running CRC32 of the decompressed data */
- unsigned long entry_crc32;
-
- /* Flags to mark progress of decompression. */
- char end_of_entry;
-
- /* Uncompressed buffer control. */
-#define UBUFF_SIZE (64 * 1024)
- unsigned char *uncompressed_buffer;
- unsigned char *uncompressed_buffer_pointer;
- size_t uncompressed_buffer_size;
- size_t uncompressed_buffer_bytes_remaining;
-
- /* Offset of the compressed data. */
- int64_t stream_offset;
-
- /*
- * Decompressing control data.
- */
- unsigned folder_index;
- uint64_t folder_outbytes_remaining;
- unsigned pack_stream_index;
- unsigned pack_stream_remaining;
- uint64_t pack_stream_inbytes_remaining;
- size_t pack_stream_bytes_unconsumed;
-
- /* The codec information of a folder. */
- unsigned long codec;
- unsigned long codec2;
-
- /*
- * Decompressor controllers.
- */
- /* Decoding LZMA1 and LZMA2 data. */
-#ifdef HAVE_LZMA_H
- lzma_stream lzstream;
- int lzstream_valid;
-#endif
- /* Decoding bzip2 data. */
-#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
- bz_stream bzstream;
- int bzstream_valid;
-#endif
- /* Decoding deflate data. */
-#ifdef HAVE_ZLIB_H
- z_stream stream;
- int stream_valid;
-#endif
- /* Decoding Zstandard data. */
-#if HAVE_ZSTD_H
- ZSTD_DStream *zstd_dstream;
- int zstdstream_valid;
-#endif
- /* Decoding PPMd data. */
- int ppmd7_stat;
- CPpmd7 ppmd7_context;
- CPpmd7z_RangeDec range_dec;
- IByteIn bytein;
- struct {
- const unsigned char *next_in;
- int64_t avail_in;
- int64_t total_in;
- int64_t stream_in;
- unsigned char *next_out;
- int64_t avail_out;
- int64_t total_out;
- int overconsumed;
- } ppstream;
- int ppmd7_valid;
-
- /* Decoding BCJ and BCJ2 data. */
- uint32_t bcj_state;
- size_t odd_bcj_size;
- unsigned char odd_bcj[4];
- /* Decoding BCJ data. */
- size_t bcj_prevPosT;
- uint32_t bcj_prevMask;
- uint32_t bcj_ip;
-
- /* Decoding BCJ2 data. */
- size_t main_stream_bytes_remaining;
- unsigned char *sub_stream_buff[3];
- size_t sub_stream_size[3];
- size_t sub_stream_bytes_remaining[3];
- unsigned char *tmp_stream_buff;
- size_t tmp_stream_buff_size;
- size_t tmp_stream_bytes_avail;
- size_t tmp_stream_bytes_remaining;
-#ifdef _LZMA_PROB32
-#define CProb uint32_t
-#else
-#define CProb uint16_t
-#endif
- CProb bcj2_p[256 + 2];
- uint8_t bcj2_prevByte;
- uint32_t bcj2_range;
- uint32_t bcj2_code;
- uint64_t bcj2_outPos;
-
- /* Filename character-set conversion data. */
- struct archive_string_conv *sconv;
-
- char format_name[64];
-
- /* Custom value that is non-zero if this archive contains encrypted entries. */
- int has_encrypted_entries;
-};
-
-/* Maximum entry size. This limitation prevents reading intentional
- * corrupted 7-zip files on assuming there are not so many entries in
- * the files. */
-#define UMAX_ENTRY ARCHIVE_LITERAL_ULL(100000000)
-
-static int archive_read_format_7zip_has_encrypted_entries(struct archive_read *);
-static int archive_read_support_format_7zip_capabilities(struct archive_read *a);
-static int archive_read_format_7zip_bid(struct archive_read *, int);
-static int archive_read_format_7zip_cleanup(struct archive_read *);
-static int archive_read_format_7zip_read_data(struct archive_read *,
- const void **, size_t *, int64_t *);
-static int archive_read_format_7zip_read_data_skip(struct archive_read *);
-static int archive_read_format_7zip_read_header(struct archive_read *,
- struct archive_entry *);
-static int check_7zip_header_in_sfx(const char *);
-static unsigned long decode_codec_id(const unsigned char *, size_t);
-static int decode_encoded_header_info(struct archive_read *,
- struct _7z_stream_info *);
-static int decompress(struct archive_read *, struct _7zip *,
- void *, size_t *, const void *, size_t *);
-static ssize_t extract_pack_stream(struct archive_read *, size_t);
-static void fileTimeToUtc(uint64_t, time_t *, long *);
-static uint64_t folder_uncompressed_size(struct _7z_folder *);
-static void free_CodersInfo(struct _7z_coders_info *);
-static void free_Digest(struct _7z_digests *);
-static void free_Folder(struct _7z_folder *);
-static void free_Header(struct _7z_header_info *);
-static void free_PackInfo(struct _7z_pack_info *);
-static void free_StreamsInfo(struct _7z_stream_info *);
-static void free_SubStreamsInfo(struct _7z_substream_info *);
-static int free_decompression(struct archive_read *, struct _7zip *);
-static ssize_t get_uncompressed_data(struct archive_read *, const void **,
- size_t, size_t);
-static const unsigned char * header_bytes(struct archive_read *, size_t);
-static int init_decompression(struct archive_read *, struct _7zip *,
- const struct _7z_coder *, const struct _7z_coder *);
-static int parse_7zip_uint64(struct archive_read *, uint64_t *);
-static int read_Bools(struct archive_read *, unsigned char *, size_t);
-static int read_CodersInfo(struct archive_read *,
- struct _7z_coders_info *);
-static int read_Digests(struct archive_read *, struct _7z_digests *,
- size_t);
-static int read_Folder(struct archive_read *, struct _7z_folder *);
-static int read_Header(struct archive_read *, struct _7z_header_info *,
- int);
-static int read_PackInfo(struct archive_read *, struct _7z_pack_info *);
-static int read_StreamsInfo(struct archive_read *,
- struct _7z_stream_info *);
-static int read_SubStreamsInfo(struct archive_read *,
- struct _7z_substream_info *, struct _7z_folder *, size_t);
-static int read_Times(struct archive_read *, struct _7z_header_info *,
- int);
-static void read_consume(struct archive_read *);
-static ssize_t read_stream(struct archive_read *, const void **, size_t,
- size_t);
-static int seek_pack(struct archive_read *);
-static int64_t skip_stream(struct archive_read *, size_t);
-static int skip_sfx(struct archive_read *, ssize_t);
-static int slurp_central_directory(struct archive_read *, struct _7zip *,
- struct _7z_header_info *);
-static int setup_decode_folder(struct archive_read *, struct _7z_folder *,
- int);
-static void x86_Init(struct _7zip *);
-static size_t x86_Convert(struct _7zip *, uint8_t *, size_t);
-static void arm_Init(struct _7zip *);
-static size_t arm_Convert(struct _7zip *, uint8_t *, size_t);
-static size_t arm64_Convert(struct _7zip *, uint8_t *, size_t);
-static ssize_t Bcj2_Decode(struct _7zip *, uint8_t *, size_t);
-
-
-int
-archive_read_support_format_7zip(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- struct _7zip *zip;
- int r;
-
- archive_check_magic(_a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_format_7zip");
-
- zip = calloc(1, sizeof(*zip));
- if (zip == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate 7zip data");
- return (ARCHIVE_FATAL);
- }
-
- /*
- * Until enough data has been read, we cannot tell about
- * any encrypted entries yet.
- */
- zip->has_encrypted_entries = ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
-
-
- r = __archive_read_register_format(a,
- zip,
- "7zip",
- archive_read_format_7zip_bid,
- NULL,
- archive_read_format_7zip_read_header,
- archive_read_format_7zip_read_data,
- archive_read_format_7zip_read_data_skip,
- NULL,
- archive_read_format_7zip_cleanup,
- archive_read_support_format_7zip_capabilities,
- archive_read_format_7zip_has_encrypted_entries);
-
- if (r != ARCHIVE_OK)
- free(zip);
- return (ARCHIVE_OK);
-}
-
-static int
-archive_read_support_format_7zip_capabilities(struct archive_read * a)
-{
- (void)a; /* UNUSED */
- return (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA |
- ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA);
-}
-
-
-static int
-archive_read_format_7zip_has_encrypted_entries(struct archive_read *_a)
-{
- if (_a && _a->format) {
- struct _7zip * zip = (struct _7zip *)_a->format->data;
- if (zip) {
- return zip->has_encrypted_entries;
- }
- }
- return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
-}
-
-static int
-archive_read_format_7zip_bid(struct archive_read *a, int best_bid)
-{
- const char *p;
-
- /* If someone has already bid more than 32, then avoid
- trashing the look-ahead buffers with a seek. */
- if (best_bid > 32)
- return (-1);
-
- if ((p = __archive_read_ahead(a, 6, NULL)) == NULL)
- return (0);
-
- /* If first six bytes are the 7-Zip signature,
- * return the bid right now. */
- if (memcmp(p, _7ZIP_SIGNATURE, 6) == 0)
- return (48);
-
- /*
- * It may a 7-Zip SFX archive file. If first two bytes are
- * 'M' and 'Z' available on Windows or first four bytes are
- * "\x7F\x45LF" available on posix like system, seek the 7-Zip
- * signature. Although we will perform a seek when reading
- * a header, what we do not use __archive_read_seek() here is
- * due to a bidding performance.
- */
- if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) {
- ssize_t offset = SFX_MIN_ADDR;
- ssize_t window = 4096;
- ssize_t bytes_avail;
- while (offset + window <= (SFX_MAX_ADDR)) {
- const char *buff = __archive_read_ahead(a,
- offset + window, &bytes_avail);
- if (buff == NULL) {
- /* Remaining bytes are less than window. */
- window >>= 1;
- if (window < 0x40)
- return (0);
- continue;
- }
- p = buff + offset;
- while (p + 32 < buff + bytes_avail) {
- int step = check_7zip_header_in_sfx(p);
- if (step == 0)
- return (48);
- p += step;
- }
- offset = p - buff;
- }
- }
- return (0);
-}
-
-static int
-check_7zip_header_in_sfx(const char *p)
-{
- switch ((unsigned char)p[5]) {
- case 0x1C:
- if (memcmp(p, _7ZIP_SIGNATURE, 6) != 0)
- return (6);
- /*
- * Test the CRC because its extraction code has 7-Zip
- * Magic Code, so we should do this in order not to
- * make a mis-detection.
- */
- if (crc32(0, (const unsigned char *)p + 12, 20)
- != archive_le32dec(p + 8))
- return (6);
- /* Hit the header! */
- return (0);
- case 0x37: return (5);
- case 0x7A: return (4);
- case 0xBC: return (3);
- case 0xAF: return (2);
- case 0x27: return (1);
- default: return (6);
- }
-}
-
-static int
-skip_sfx(struct archive_read *a, ssize_t bytes_avail)
-{
- const void *h;
- const char *p, *q;
- size_t skip, offset;
- ssize_t bytes, window;
-
- /*
- * If bytes_avail > SFX_MIN_ADDR we do not have to call
- * __archive_read_seek() at this time since we have
- * already had enough data.
- */
- if (bytes_avail > SFX_MIN_ADDR)
- __archive_read_consume(a, SFX_MIN_ADDR);
- else if (__archive_read_seek(a, SFX_MIN_ADDR, SEEK_SET) < 0)
- return (ARCHIVE_FATAL);
-
- offset = 0;
- window = 1;
- while (offset + window <= SFX_MAX_ADDR - SFX_MIN_ADDR) {
- h = __archive_read_ahead(a, window, &bytes);
- if (h == NULL) {
- /* Remaining bytes are less than window. */
- window >>= 1;
- if (window < 0x40)
- goto fatal;
- continue;
- }
- if (bytes < 6) {
- /* This case might happen when window == 1. */
- window = 4096;
- continue;
- }
- p = (const char *)h;
- q = p + bytes;
-
- /*
- * Scan ahead until we find something that looks
- * like the 7-Zip header.
- */
- while (p + 32 < q) {
- int step = check_7zip_header_in_sfx(p);
- if (step == 0) {
- struct _7zip *zip =
- (struct _7zip *)a->format->data;
- skip = p - (const char *)h;
- __archive_read_consume(a, skip);
- zip->seek_base = SFX_MIN_ADDR + offset + skip;
- return (ARCHIVE_OK);
- }
- p += step;
- }
- skip = p - (const char *)h;
- __archive_read_consume(a, skip);
- offset += skip;
- if (window == 1)
- window = 4096;
- }
-fatal:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Couldn't find out 7-Zip header");
- return (ARCHIVE_FATAL);
-}
-
-static int
-archive_read_format_7zip_read_header(struct archive_read *a,
- struct archive_entry *entry)
-{
- struct _7zip *zip = (struct _7zip *)a->format->data;
- struct _7zip_entry *zip_entry;
- int r, ret = ARCHIVE_OK;
- struct _7z_folder *folder = 0;
- uint64_t fidx = 0;
-
- /*
- * It should be sufficient to call archive_read_next_header() for
- * a reader to determine if an entry is encrypted or not. If the
- * encryption of an entry is only detectable when calling
- * archive_read_data(), so be it. We'll do the same check there
- * as well.
- */
- if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
- zip->has_encrypted_entries = 0;
- }
-
- a->archive.archive_format = ARCHIVE_FORMAT_7ZIP;
- if (a->archive.archive_format_name == NULL)
- a->archive.archive_format_name = "7-Zip";
-
- if (zip->entries == NULL) {
- struct _7z_header_info header;
-
- memset(&header, 0, sizeof(header));
- r = slurp_central_directory(a, zip, &header);
- free_Header(&header);
- if (r != ARCHIVE_OK)
- return (r);
- zip->entries_remaining = (size_t)zip->numFiles;
- zip->entry = zip->entries;
- } else {
- ++zip->entry;
- }
- zip_entry = zip->entry;
-
- if (zip->entries_remaining <= 0 || zip_entry == NULL)
- return ARCHIVE_EOF;
- --zip->entries_remaining;
-
- zip->entry_offset = 0;
- zip->end_of_entry = 0;
- zip->entry_crc32 = crc32(0, NULL, 0);
-
- /* Setup a string conversion for a filename. */
- if (zip->sconv == NULL) {
- zip->sconv = archive_string_conversion_from_charset(
- &a->archive, "UTF-16LE", 1);
- if (zip->sconv == NULL)
- return (ARCHIVE_FATAL);
- }
-
- /* Figure out if the entry is encrypted by looking at the folder
- that is associated to the current 7zip entry. If the folder
- has a coder with a _7Z_CRYPTO codec then the folder is encrypted.
- Hence the entry must also be encrypted. */
- if (zip_entry && zip_entry->folderIndex < zip->si.ci.numFolders) {
- folder = &(zip->si.ci.folders[zip_entry->folderIndex]);
- for (fidx=0; folder && fidx<folder->numCoders; fidx++) {
- switch(folder->coders[fidx].codec) {
- case _7Z_CRYPTO_MAIN_ZIP:
- case _7Z_CRYPTO_RAR_29:
- case _7Z_CRYPTO_AES_256_SHA_256: {
- archive_entry_set_is_data_encrypted(entry, 1);
- zip->has_encrypted_entries = 1;
- break;
- }
- }
- }
- }
-
- /* Now that we've checked for encryption, if there were still no
- * encrypted entries found we can say for sure that there are none.
- */
- if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
- zip->has_encrypted_entries = 0;
- }
-
- if (archive_entry_copy_pathname_l(entry,
- (const char *)zip_entry->utf16name,
- zip_entry->name_len, zip->sconv) != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Pathname cannot be converted "
- "from %s to current locale.",
- archive_string_conversion_charset_name(zip->sconv));
- ret = ARCHIVE_WARN;
- }
-
- /* Populate some additional entry fields: */
- archive_entry_set_mode(entry, zip_entry->mode);
- if (zip_entry->flg & MTIME_IS_SET)
- archive_entry_set_mtime(entry, zip_entry->mtime,
- zip_entry->mtime_ns);
- if (zip_entry->flg & CTIME_IS_SET)
- archive_entry_set_ctime(entry, zip_entry->ctime,
- zip_entry->ctime_ns);
- if (zip_entry->flg & ATIME_IS_SET)
- archive_entry_set_atime(entry, zip_entry->atime,
- zip_entry->atime_ns);
- if (zip_entry->ssIndex != (uint32_t)-1) {
- zip->entry_bytes_remaining =
- zip->si.ss.unpackSizes[zip_entry->ssIndex];
- archive_entry_set_size(entry, zip->entry_bytes_remaining);
- } else {
- zip->entry_bytes_remaining = 0;
- archive_entry_set_size(entry, 0);
- }
-
- /* If there's no body, force read_data() to return EOF immediately. */
- if (zip->entry_bytes_remaining < 1)
- zip->end_of_entry = 1;
-
- if ((zip_entry->mode & AE_IFMT) == AE_IFLNK) {
- unsigned char *symname = NULL;
- size_t symsize = 0;
-
- /*
- * Symbolic-name is recorded as its contents. We have to
- * read the contents at this time.
- */
- while (zip->entry_bytes_remaining > 0) {
- const void *buff;
- unsigned char *mem;
- size_t size;
- int64_t offset;
-
- r = archive_read_format_7zip_read_data(a, &buff,
- &size, &offset);
- if (r < ARCHIVE_WARN) {
- free(symname);
- return (r);
- }
- mem = realloc(symname, symsize + size + 1);
- if (mem == NULL) {
- free(symname);
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Symname");
- return (ARCHIVE_FATAL);
- }
- symname = mem;
- memcpy(symname+symsize, buff, size);
- symsize += size;
- }
- if (symsize == 0) {
- /* If there is no symname, handle it as a regular
- * file. */
- zip_entry->mode &= ~AE_IFMT;
- zip_entry->mode |= AE_IFREG;
- archive_entry_set_mode(entry, zip_entry->mode);
- } else {
- symname[symsize] = '\0';
- archive_entry_copy_symlink(entry,
- (const char *)symname);
- }
- free(symname);
- archive_entry_set_size(entry, 0);
- }
-
- /* Set up a more descriptive format name. */
- snprintf(zip->format_name, sizeof(zip->format_name), "7-Zip");
- a->archive.archive_format_name = zip->format_name;
-
- return (ret);
-}
-
-static int
-archive_read_format_7zip_read_data(struct archive_read *a,
- const void **buff, size_t *size, int64_t *offset)
-{
- struct _7zip *zip;
- ssize_t bytes;
- int ret = ARCHIVE_OK;
-
- zip = (struct _7zip *)(a->format->data);
-
- if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
- zip->has_encrypted_entries = 0;
- }
-
- if (zip->pack_stream_bytes_unconsumed)
- read_consume(a);
-
- *offset = zip->entry_offset;
- *size = 0;
- *buff = NULL;
- /*
- * If we hit end-of-entry last time, clean up and return
- * ARCHIVE_EOF this time.
- */
- if (zip->end_of_entry)
- return (ARCHIVE_EOF);
-
- const uint64_t max_read_size = 16 * 1024 * 1024; // Don't try to read more than 16 MB at a time
- size_t bytes_to_read = max_read_size;
- if ((uint64_t)bytes_to_read > zip->entry_bytes_remaining) {
- bytes_to_read = zip->entry_bytes_remaining;
- }
- bytes = read_stream(a, buff, bytes_to_read, 0);
- if (bytes < 0)
- return ((int)bytes);
- if (bytes == 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated 7-Zip file body");
- return (ARCHIVE_FATAL);
- }
- zip->entry_bytes_remaining -= bytes;
- if (zip->entry_bytes_remaining == 0)
- zip->end_of_entry = 1;
-
- /* Update checksum */
- if ((zip->entry->flg & CRC32_IS_SET) && bytes)
- zip->entry_crc32 = crc32(zip->entry_crc32, *buff,
- (unsigned)bytes);
-
- /* If we hit the end, swallow any end-of-data marker. */
- if (zip->end_of_entry) {
- /* Check computed CRC against file contents. */
- if ((zip->entry->flg & CRC32_IS_SET) &&
- zip->si.ss.digests[zip->entry->ssIndex] !=
- zip->entry_crc32) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "7-Zip bad CRC: 0x%lx should be 0x%lx",
- (unsigned long)zip->entry_crc32,
- (unsigned long)zip->si.ss.digests[
- zip->entry->ssIndex]);
- ret = ARCHIVE_WARN;
- }
- }
-
- *size = bytes;
- *offset = zip->entry_offset;
- zip->entry_offset += bytes;
-
- return (ret);
-}
-
-static int
-archive_read_format_7zip_read_data_skip(struct archive_read *a)
-{
- struct _7zip *zip;
- int64_t bytes_skipped;
-
- zip = (struct _7zip *)(a->format->data);
-
- if (zip->pack_stream_bytes_unconsumed)
- read_consume(a);
-
- /* If we've already read to end of data, we're done. */
- if (zip->end_of_entry)
- return (ARCHIVE_OK);
-
- /*
- * If the length is at the beginning, we can skip the
- * compressed data much more quickly.
- */
- bytes_skipped = skip_stream(a, (size_t)zip->entry_bytes_remaining);
- if (bytes_skipped < 0)
- return (ARCHIVE_FATAL);
- zip->entry_bytes_remaining = 0;
-
- /* This entry is finished and done. */
- zip->end_of_entry = 1;
- return (ARCHIVE_OK);
-}
-
-static int
-archive_read_format_7zip_cleanup(struct archive_read *a)
-{
- struct _7zip *zip;
-
- zip = (struct _7zip *)(a->format->data);
- free_StreamsInfo(&(zip->si));
- free(zip->entries);
- free(zip->entry_names);
- free_decompression(a, zip);
- free(zip->uncompressed_buffer);
- free(zip->sub_stream_buff[0]);
- free(zip->sub_stream_buff[1]);
- free(zip->sub_stream_buff[2]);
- free(zip->tmp_stream_buff);
- free(zip);
- (a->format->data) = NULL;
- return (ARCHIVE_OK);
-}
-
-static void
-read_consume(struct archive_read *a)
-{
- struct _7zip *zip = (struct _7zip *)a->format->data;
-
- if (zip->pack_stream_bytes_unconsumed) {
- __archive_read_consume(a, zip->pack_stream_bytes_unconsumed);
- zip->stream_offset += zip->pack_stream_bytes_unconsumed;
- zip->pack_stream_bytes_unconsumed = 0;
- }
-}
-
-#ifdef HAVE_LZMA_H
-
-/*
- * Set an error code and choose an error message for liblzma.
- */
-static void
-set_error(struct archive_read *a, int ret)
-{
-
- switch (ret) {
- case LZMA_STREAM_END: /* Found end of stream. */
- case LZMA_OK: /* Decompressor made some progress. */
- break;
- case LZMA_MEM_ERROR:
- archive_set_error(&a->archive, ENOMEM,
- "Lzma library error: Cannot allocate memory");
- break;
- case LZMA_MEMLIMIT_ERROR:
- archive_set_error(&a->archive, ENOMEM,
- "Lzma library error: Out of memory");
- break;
- case LZMA_FORMAT_ERROR:
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Lzma library error: format not recognized");
- break;
- case LZMA_OPTIONS_ERROR:
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Lzma library error: Invalid options");
- break;
- case LZMA_DATA_ERROR:
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Lzma library error: Corrupted input data");
- break;
- case LZMA_BUF_ERROR:
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Lzma library error: No progress is possible");
- break;
- default:
- /* Return an error. */
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Lzma decompression failed: Unknown error");
- break;
- }
-}
-
-#endif
-
-static unsigned long
-decode_codec_id(const unsigned char *codecId, size_t id_size)
-{
- unsigned i;
- unsigned long id = 0;
-
- for (i = 0; i < id_size; i++) {
- id <<= 8;
- id += codecId[i];
- }
- return (id);
-}
-
-static Byte
-ppmd_read(void *p)
-{
- struct archive_read *a = ((IByteIn*)p)->a;
- struct _7zip *zip = (struct _7zip *)(a->format->data);
- Byte b;
-
- if (zip->ppstream.avail_in <= 0) {
- /*
- * Ppmd7_DecodeSymbol might require reading multiple bytes
- * and we are on boundary;
- * last resort to read using __archive_read_ahead.
- */
- ssize_t bytes_avail = 0;
- const uint8_t* data = __archive_read_ahead(a,
- zip->ppstream.stream_in+1, &bytes_avail);
- if(bytes_avail < zip->ppstream.stream_in+1) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated 7z file data");
- zip->ppstream.overconsumed = 1;
- return (0);
- }
- zip->ppstream.next_in++;
- b = data[zip->ppstream.stream_in];
- } else {
- b = *zip->ppstream.next_in++;
- }
- zip->ppstream.avail_in--;
- zip->ppstream.total_in++;
- zip->ppstream.stream_in++;
- return (b);
-}
-
-static int
-init_decompression(struct archive_read *a, struct _7zip *zip,
- const struct _7z_coder *coder1, const struct _7z_coder *coder2)
-{
- int r;
-
- zip->codec = coder1->codec;
- zip->codec2 = -1;
-
- switch (zip->codec) {
- case _7Z_COPY:
- case _7Z_BZ2:
- case _7Z_DEFLATE:
- case _7Z_ZSTD:
- case _7Z_PPMD:
- if (coder2 != NULL) {
- if (coder2->codec != _7Z_X86 &&
- coder2->codec != _7Z_X86_BCJ2 &&
- coder2->codec != _7Z_ARM &&
- coder2->codec != _7Z_ARM64) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Unsupported filter %lx for %lx",
- coder2->codec, coder1->codec);
- return (ARCHIVE_FAILED);
- }
- zip->codec2 = coder2->codec;
- zip->bcj_state = 0;
- if (coder2->codec == _7Z_X86)
- x86_Init(zip);
- else if (coder2->codec == _7Z_ARM)
- arm_Init(zip);
- }
- break;
- default:
- break;
- }
-
- switch (zip->codec) {
- case _7Z_COPY:
- break;
-
- case _7Z_LZMA: case _7Z_LZMA2:
-#ifdef HAVE_LZMA_H
-#if LZMA_VERSION_MAJOR >= 5
-/* Effectively disable the limiter. */
-#define LZMA_MEMLIMIT UINT64_MAX
-#else
-/* NOTE: This needs to check memory size which running system has. */
-#define LZMA_MEMLIMIT (1U << 30)
-#endif
- {
- lzma_options_delta delta_opt;
- lzma_filter filters[LZMA_FILTERS_MAX], *ff;
- int fi = 0;
-
- if (zip->lzstream_valid) {
- lzma_end(&(zip->lzstream));
- zip->lzstream_valid = 0;
- }
-
- /*
- * NOTE: liblzma incompletely handle the BCJ+LZMA compressed
- * data made by 7-Zip because 7-Zip does not add End-Of-
- * Payload Marker(EOPM) at the end of LZMA compressed data,
- * and so liblzma cannot know the end of the compressed data
- * without EOPM. So consequently liblzma will not return last
- * three or four bytes of uncompressed data because
- * LZMA_FILTER_X86 filter does not handle input data if its
- * data size is less than five bytes. If liblzma detect EOPM
- * or know the uncompressed data size, liblzma will flush out
- * the remaining that three or four bytes of uncompressed
- * data. That is why we have to use our converting program
- * for BCJ+LZMA. If we were able to tell the uncompressed
- * size to liblzma when using lzma_raw_decoder() liblzma
- * could correctly deal with BCJ+LZMA. But unfortunately
- * there is no way to do that.
- * Discussion about this can be found at XZ Utils forum.
- */
- if (coder2 != NULL) {
- zip->codec2 = coder2->codec;
-
- filters[fi].options = NULL;
- switch (zip->codec2) {
- case _7Z_X86:
- if (zip->codec == _7Z_LZMA2) {
- filters[fi].id = LZMA_FILTER_X86;
- fi++;
- } else
- /* Use our filter. */
- x86_Init(zip);
- break;
- case _7Z_X86_BCJ2:
- /* Use our filter. */
- zip->bcj_state = 0;
- break;
- case _7Z_DELTA:
- if (coder2->propertiesSize != 1) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Invalid Delta parameter");
- return (ARCHIVE_FAILED);
- }
- filters[fi].id = LZMA_FILTER_DELTA;
- memset(&delta_opt, 0, sizeof(delta_opt));
- delta_opt.type = LZMA_DELTA_TYPE_BYTE;
- delta_opt.dist =
- (uint32_t)coder2->properties[0] + 1;
- filters[fi].options = &delta_opt;
- fi++;
- break;
- /* Following filters have not been tested yet. */
- case _7Z_POWERPC:
- filters[fi].id = LZMA_FILTER_POWERPC;
- fi++;
- break;
- case _7Z_IA64:
- filters[fi].id = LZMA_FILTER_IA64;
- fi++;
- break;
- case _7Z_ARM:
- filters[fi].id = LZMA_FILTER_ARM;
- fi++;
- break;
- case _7Z_ARMTHUMB:
- filters[fi].id = LZMA_FILTER_ARMTHUMB;
- fi++;
- break;
-#ifdef LZMA_FILTER_ARM64
- case _7Z_ARM64:
- filters[fi].id = LZMA_FILTER_ARM64;
- fi++;
- break;
-#endif
- case _7Z_SPARC:
- filters[fi].id = LZMA_FILTER_SPARC;
- fi++;
- break;
- default:
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Unexpected codec ID: %lX", zip->codec2);
- return (ARCHIVE_FAILED);
- }
- }
-
- if (zip->codec == _7Z_LZMA2)
- filters[fi].id = LZMA_FILTER_LZMA2;
- else
- filters[fi].id = LZMA_FILTER_LZMA1;
- filters[fi].options = NULL;
- ff = &filters[fi];
- r = lzma_properties_decode(&filters[fi], NULL,
- coder1->properties, (size_t)coder1->propertiesSize);
- if (r != LZMA_OK) {
- set_error(a, r);
- return (ARCHIVE_FAILED);
- }
- fi++;
-
- filters[fi].id = LZMA_VLI_UNKNOWN;
- filters[fi].options = NULL;
- r = lzma_raw_decoder(&(zip->lzstream), filters);
- free(ff->options);
- if (r != LZMA_OK) {
- set_error(a, r);
- return (ARCHIVE_FAILED);
- }
- zip->lzstream_valid = 1;
- zip->lzstream.total_in = 0;
- zip->lzstream.total_out = 0;
- break;
- }
-#else
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "LZMA codec is unsupported");
- return (ARCHIVE_FAILED);
-#endif
- case _7Z_BZ2:
-#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
- if (zip->bzstream_valid) {
- BZ2_bzDecompressEnd(&(zip->bzstream));
- zip->bzstream_valid = 0;
- }
- r = BZ2_bzDecompressInit(&(zip->bzstream), 0, 0);
- if (r == BZ_MEM_ERROR)
- r = BZ2_bzDecompressInit(&(zip->bzstream), 0, 1);
- if (r != BZ_OK) {
- int err = ARCHIVE_ERRNO_MISC;
- const char *detail = NULL;
- switch (r) {
- case BZ_PARAM_ERROR:
- detail = "invalid setup parameter";
- break;
- case BZ_MEM_ERROR:
- err = ENOMEM;
- detail = "out of memory";
- break;
- case BZ_CONFIG_ERROR:
- detail = "mis-compiled library";
- break;
- }
- archive_set_error(&a->archive, err,
- "Internal error initializing decompressor: %s",
- detail != NULL ? detail : "??");
- zip->bzstream_valid = 0;
- return (ARCHIVE_FAILED);
- }
- zip->bzstream_valid = 1;
- zip->bzstream.total_in_lo32 = 0;
- zip->bzstream.total_in_hi32 = 0;
- zip->bzstream.total_out_lo32 = 0;
- zip->bzstream.total_out_hi32 = 0;
- break;
-#else
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "BZ2 codec is unsupported");
- return (ARCHIVE_FAILED);
-#endif
- case _7Z_ZSTD:
- {
-#if defined(HAVE_ZSTD_H)
- if (zip->zstdstream_valid) {
- ZSTD_freeDStream(zip->zstd_dstream);
- zip->zstdstream_valid = 0;
- }
- zip->zstd_dstream = ZSTD_createDStream();
- zip->zstdstream_valid = 1;
- break;
-#else
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "ZSTD codec is unsupported");
- return (ARCHIVE_FAILED);
-#endif
- }
- case _7Z_DEFLATE:
-#ifdef HAVE_ZLIB_H
- if (zip->stream_valid)
- r = inflateReset(&(zip->stream));
- else
- r = inflateInit2(&(zip->stream),
- -15 /* Don't check for zlib header */);
- if (r != Z_OK) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Couldn't initialize zlib stream.");
- return (ARCHIVE_FAILED);
- }
- zip->stream_valid = 1;
- zip->stream.total_in = 0;
- zip->stream.total_out = 0;
- break;
-#else
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "DEFLATE codec is unsupported");
- return (ARCHIVE_FAILED);
-#endif
- case _7Z_PPMD:
- {
- unsigned order;
- uint32_t msize;
-
- if (zip->ppmd7_valid) {
- __archive_ppmd7_functions.Ppmd7_Free(
- &zip->ppmd7_context);
- zip->ppmd7_valid = 0;
- }
-
- if (coder1->propertiesSize < 5) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Malformed PPMd parameter");
- return (ARCHIVE_FAILED);
- }
- order = coder1->properties[0];
- msize = archive_le32dec(&(coder1->properties[1]));
- if (order < PPMD7_MIN_ORDER || order > PPMD7_MAX_ORDER ||
- msize < PPMD7_MIN_MEM_SIZE || msize > PPMD7_MAX_MEM_SIZE) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Malformed PPMd parameter");
- return (ARCHIVE_FAILED);
- }
- __archive_ppmd7_functions.Ppmd7_Construct(&zip->ppmd7_context);
- r = __archive_ppmd7_functions.Ppmd7_Alloc(
- &zip->ppmd7_context, msize);
- if (r == 0) {
- archive_set_error(&a->archive, ENOMEM,
- "Coludn't allocate memory for PPMd");
- return (ARCHIVE_FATAL);
- }
- __archive_ppmd7_functions.Ppmd7_Init(
- &zip->ppmd7_context, order);
- __archive_ppmd7_functions.Ppmd7z_RangeDec_CreateVTable(
- &zip->range_dec);
- zip->ppmd7_valid = 1;
- zip->ppmd7_stat = 0;
- zip->ppstream.overconsumed = 0;
- zip->ppstream.total_in = 0;
- zip->ppstream.total_out = 0;
- break;
- }
- case _7Z_X86:
- case _7Z_X86_BCJ2:
- case _7Z_POWERPC:
- case _7Z_IA64:
- case _7Z_ARM:
- case _7Z_ARMTHUMB:
- case _7Z_SPARC:
- case _7Z_DELTA:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Unexpected codec ID: %lX", zip->codec);
- return (ARCHIVE_FAILED);
- case _7Z_CRYPTO_MAIN_ZIP:
- case _7Z_CRYPTO_RAR_29:
- case _7Z_CRYPTO_AES_256_SHA_256:
- if (a->entry) {
- archive_entry_set_is_metadata_encrypted(a->entry, 1);
- archive_entry_set_is_data_encrypted(a->entry, 1);
- zip->has_encrypted_entries = 1;
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Crypto codec not supported yet (ID: 0x%lX)", zip->codec);
- return (ARCHIVE_FAILED);
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Unknown codec ID: %lX", zip->codec);
- return (ARCHIVE_FAILED);
- }
-
- return (ARCHIVE_OK);
-}
-
-static int
-decompress(struct archive_read *a, struct _7zip *zip,
- void *buff, size_t *outbytes, const void *b, size_t *used)
-{
- const uint8_t *t_next_in;
- uint8_t *t_next_out;
- size_t o_avail_in, o_avail_out;
- size_t t_avail_in, t_avail_out;
- uint8_t *bcj2_next_out;
- size_t bcj2_avail_out;
- int r, ret = ARCHIVE_OK;
-
- t_avail_in = o_avail_in = *used;
- t_avail_out = o_avail_out = *outbytes;
- t_next_in = b;
- t_next_out = buff;
-
- if (zip->codec != _7Z_LZMA2 && zip->codec2 == _7Z_X86) {
- int i;
-
- /* Do not copy out the BCJ remaining bytes when the output
- * buffer size is less than five bytes. */
- if (o_avail_in != 0 && t_avail_out < 5 && zip->odd_bcj_size) {
- *used = 0;
- *outbytes = 0;
- return (ret);
- }
- for (i = 0; zip->odd_bcj_size > 0 && t_avail_out; i++) {
- *t_next_out++ = zip->odd_bcj[i];
- t_avail_out--;
- zip->odd_bcj_size--;
- }
- if (o_avail_in == 0 || t_avail_out == 0) {
- *used = o_avail_in - t_avail_in;
- *outbytes = o_avail_out - t_avail_out;
- if (o_avail_in == 0)
- ret = ARCHIVE_EOF;
- return (ret);
- }
- }
-
- bcj2_next_out = t_next_out;
- bcj2_avail_out = t_avail_out;
- if (zip->codec2 == _7Z_X86_BCJ2) {
- /*
- * Decord a remaining decompressed main stream for BCJ2.
- */
- if (zip->tmp_stream_bytes_remaining) {
- ssize_t bytes;
- size_t remaining = zip->tmp_stream_bytes_remaining;
- bytes = Bcj2_Decode(zip, t_next_out, t_avail_out);
- if (bytes < 0) {
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "BCJ2 conversion Failed");
- return (ARCHIVE_FAILED);
- }
- zip->main_stream_bytes_remaining -=
- remaining - zip->tmp_stream_bytes_remaining;
- t_avail_out -= bytes;
- if (o_avail_in == 0 || t_avail_out == 0) {
- *used = 0;
- *outbytes = o_avail_out - t_avail_out;
- if (o_avail_in == 0 &&
- zip->tmp_stream_bytes_remaining)
- ret = ARCHIVE_EOF;
- return (ret);
- }
- t_next_out += bytes;
- bcj2_next_out = t_next_out;
- bcj2_avail_out = t_avail_out;
- }
- t_next_out = zip->tmp_stream_buff;
- t_avail_out = zip->tmp_stream_buff_size;
- }
-
- switch (zip->codec) {
- case _7Z_COPY:
- {
- size_t bytes =
- (t_avail_in > t_avail_out)?t_avail_out:t_avail_in;
-
- memcpy(t_next_out, t_next_in, bytes);
- t_avail_in -= bytes;
- t_avail_out -= bytes;
- if (o_avail_in == 0)
- ret = ARCHIVE_EOF;
- break;
- }
-#ifdef HAVE_LZMA_H
- case _7Z_LZMA: case _7Z_LZMA2:
- zip->lzstream.next_in = t_next_in;
- zip->lzstream.avail_in = t_avail_in;
- zip->lzstream.next_out = t_next_out;
- zip->lzstream.avail_out = t_avail_out;
-
- r = lzma_code(&(zip->lzstream), LZMA_RUN);
- switch (r) {
- case LZMA_STREAM_END: /* Found end of stream. */
- lzma_end(&(zip->lzstream));
- zip->lzstream_valid = 0;
- ret = ARCHIVE_EOF;
- break;
- case LZMA_OK: /* Decompressor made some progress. */
- break;
- default:
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "Decompression failed(%d)",
- r);
- return (ARCHIVE_FAILED);
- }
- t_avail_in = zip->lzstream.avail_in;
- t_avail_out = zip->lzstream.avail_out;
- break;
-#endif
-#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
- case _7Z_BZ2:
- zip->bzstream.next_in = (char *)(uintptr_t)t_next_in;
- zip->bzstream.avail_in = (uint32_t)t_avail_in;
- zip->bzstream.next_out = (char *)(uintptr_t)t_next_out;
- zip->bzstream.avail_out = (uint32_t)t_avail_out;
- r = BZ2_bzDecompress(&(zip->bzstream));
- switch (r) {
- case BZ_STREAM_END: /* Found end of stream. */
- switch (BZ2_bzDecompressEnd(&(zip->bzstream))) {
- case BZ_OK:
- break;
- default:
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "Failed to clean up decompressor");
- return (ARCHIVE_FAILED);
- }
- zip->bzstream_valid = 0;
- ret = ARCHIVE_EOF;
- break;
- case BZ_OK: /* Decompressor made some progress. */
- break;
- default:
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "bzip decompression failed");
- return (ARCHIVE_FAILED);
- }
- t_avail_in = zip->bzstream.avail_in;
- t_avail_out = zip->bzstream.avail_out;
- break;
-#endif
-#ifdef HAVE_ZLIB_H
- case _7Z_DEFLATE:
- zip->stream.next_in = (Bytef *)(uintptr_t)t_next_in;
- zip->stream.avail_in = (uInt)t_avail_in;
- zip->stream.next_out = t_next_out;
- zip->stream.avail_out = (uInt)t_avail_out;
- r = inflate(&(zip->stream), 0);
- switch (r) {
- case Z_STREAM_END: /* Found end of stream. */
- ret = ARCHIVE_EOF;
- break;
- case Z_OK: /* Decompressor made some progress.*/
- break;
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "File decompression failed (%d)", r);
- return (ARCHIVE_FAILED);
- }
- t_avail_in = zip->stream.avail_in;
- t_avail_out = zip->stream.avail_out;
- break;
-#endif
-#ifdef HAVE_ZSTD_H
- case _7Z_ZSTD:
- {
- ZSTD_inBuffer input = { t_next_in, t_avail_in, 0 }; // src, size, pos
- ZSTD_outBuffer output = { t_next_out, t_avail_out, 0 }; // dst, size, pos
-
- size_t const zret = ZSTD_decompressStream(zip->zstd_dstream, &output, &input);
- if (ZSTD_isError(zret)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Zstd decompression failed: %s", ZSTD_getErrorName(zret));
- return ARCHIVE_FAILED;
- }
- t_avail_in -= input.pos;
- t_avail_out -= output.pos;
- break;
- }
-#endif
- case _7Z_PPMD:
- {
- uint64_t flush_bytes;
-
- if (!zip->ppmd7_valid || zip->ppmd7_stat < 0 ||
- t_avail_out <= 0) {
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "Decompression internal error");
- return (ARCHIVE_FAILED);
- }
- zip->ppstream.next_in = t_next_in;
- zip->ppstream.avail_in = t_avail_in;
- zip->ppstream.stream_in = 0;
- zip->ppstream.next_out = t_next_out;
- zip->ppstream.avail_out = t_avail_out;
- if (zip->ppmd7_stat == 0) {
- zip->bytein.a = a;
- zip->bytein.Read = &ppmd_read;
- zip->range_dec.Stream = &zip->bytein;
- r = __archive_ppmd7_functions.Ppmd7z_RangeDec_Init(
- &(zip->range_dec));
- if (r == 0) {
- zip->ppmd7_stat = -1;
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Failed to initialize PPMd range decoder");
- return (ARCHIVE_FAILED);
- }
- if (zip->ppstream.overconsumed) {
- zip->ppmd7_stat = -1;
- return (ARCHIVE_FAILED);
- }
- zip->ppmd7_stat = 1;
- }
-
- if (t_avail_in == 0)
- /* XXX Flush out remaining decoded data XXX */
- flush_bytes = zip->folder_outbytes_remaining;
- else
- flush_bytes = 0;
-
- do {
- int sym;
-
- sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
- &(zip->ppmd7_context), &(zip->range_dec.p));
- if (sym < 0) {
- zip->ppmd7_stat = -1;
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Failed to decode PPMd");
- return (ARCHIVE_FAILED);
- }
- if (zip->ppstream.overconsumed) {
- zip->ppmd7_stat = -1;
- return (ARCHIVE_FAILED);
- }
- *zip->ppstream.next_out++ = (unsigned char)sym;
- zip->ppstream.avail_out--;
- zip->ppstream.total_out++;
- if (flush_bytes)
- flush_bytes--;
- } while (zip->ppstream.avail_out &&
- (zip->ppstream.avail_in || flush_bytes));
-
- t_avail_in = (size_t)zip->ppstream.avail_in;
- t_avail_out = (size_t)zip->ppstream.avail_out;
- break;
- }
- default:
- archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
- "Decompression internal error");
- return (ARCHIVE_FAILED);
- }
- if (ret != ARCHIVE_OK && ret != ARCHIVE_EOF)
- return (ret);
-
- *used = o_avail_in - t_avail_in;
- *outbytes = o_avail_out - t_avail_out;
-
- /*
- * Decord BCJ.
- */
- if (zip->codec != _7Z_LZMA2) {
- if (zip->codec2 == _7Z_X86) {
- size_t l = x86_Convert(zip, buff, *outbytes);
-
- zip->odd_bcj_size = *outbytes - l;
- if (zip->odd_bcj_size > 0 && zip->odd_bcj_size <= 4 &&
- o_avail_in && ret != ARCHIVE_EOF) {
- memcpy(zip->odd_bcj, ((unsigned char *)buff) + l,
- zip->odd_bcj_size);
- *outbytes = l;
- } else
- zip->odd_bcj_size = 0;
- } else if (zip->codec2 == _7Z_ARM) {
- *outbytes = arm_Convert(zip, buff, *outbytes);
- } else if (zip->codec2 == _7Z_ARM64) {
- *outbytes = arm64_Convert(zip, buff, *outbytes);
- }
- }
-
- /*
- * Decord BCJ2 with a decompressed main stream.
- */
- if (zip->codec2 == _7Z_X86_BCJ2) {
- ssize_t bytes;
-
- zip->tmp_stream_bytes_avail =
- zip->tmp_stream_buff_size - t_avail_out;
- if (zip->tmp_stream_bytes_avail >
- zip->main_stream_bytes_remaining)
- zip->tmp_stream_bytes_avail =
- zip->main_stream_bytes_remaining;
- zip->tmp_stream_bytes_remaining = zip->tmp_stream_bytes_avail;
- bytes = Bcj2_Decode(zip, bcj2_next_out, bcj2_avail_out);
- if (bytes < 0) {
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC, "BCJ2 conversion Failed");
- return (ARCHIVE_FAILED);
- }
- zip->main_stream_bytes_remaining -=
- zip->tmp_stream_bytes_avail
- - zip->tmp_stream_bytes_remaining;
- bcj2_avail_out -= bytes;
- *outbytes = o_avail_out - bcj2_avail_out;
- }
-
- return (ret);
-}
-
-static int
-free_decompression(struct archive_read *a, struct _7zip *zip)
-{
- int r = ARCHIVE_OK;
-
-#if !defined(HAVE_ZLIB_H) &&\
- !(defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR))
- (void)a;/* UNUSED */
-#endif
-#ifdef HAVE_LZMA_H
- if (zip->lzstream_valid)
- lzma_end(&(zip->lzstream));
-#endif
-#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
- if (zip->bzstream_valid) {
- if (BZ2_bzDecompressEnd(&(zip->bzstream)) != BZ_OK) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Failed to clean up bzip2 decompressor");
- r = ARCHIVE_FATAL;
- }
- zip->bzstream_valid = 0;
- }
-#endif
-#ifdef HAVE_ZLIB_H
- if (zip->stream_valid) {
- if (inflateEnd(&(zip->stream)) != Z_OK) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Failed to clean up zlib decompressor");
- r = ARCHIVE_FATAL;
- }
- zip->stream_valid = 0;
- }
-#endif
- if (zip->ppmd7_valid) {
- __archive_ppmd7_functions.Ppmd7_Free(
- &zip->ppmd7_context);
- zip->ppmd7_valid = 0;
- }
- return (r);
-}
-
-static int
-parse_7zip_uint64(struct archive_read *a, uint64_t *val)
-{
- const unsigned char *p;
- unsigned char avail, mask;
- int i;
-
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- avail = *p;
- mask = 0x80;
- *val = 0;
- for (i = 0; i < 8; i++) {
- if (avail & mask) {
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- *val |= ((uint64_t)*p) << (8 * i);
- mask >>= 1;
- continue;
- }
- *val += ((uint64_t)(avail & (mask -1))) << (8 * i);
- break;
- }
- return (0);
-}
-
-static int
-read_Bools(struct archive_read *a, unsigned char *data, size_t num)
-{
- const unsigned char *p;
- unsigned i, mask = 0, avail = 0;
-
- for (i = 0; i < num; i++) {
- if (mask == 0) {
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- avail = *p;
- mask = 0x80;
- }
- data[i] = (avail & mask)?1:0;
- mask >>= 1;
- }
- return (0);
-}
-
-static void
-free_Digest(struct _7z_digests *d)
-{
- free(d->defineds);
- free(d->digests);
-}
-
-static int
-read_Digests(struct archive_read *a, struct _7z_digests *d, size_t num)
-{
- const unsigned char *p;
- unsigned i;
-
- if (num == 0)
- return (-1);
- memset(d, 0, sizeof(*d));
-
- d->defineds = malloc(num);
- if (d->defineds == NULL)
- return (-1);
- /*
- * Read Bools.
- */
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- if (*p == 0) {
- if (read_Bools(a, d->defineds, num) < 0)
- return (-1);
- } else
- /* All are defined */
- memset(d->defineds, 1, num);
-
- d->digests = calloc(num, sizeof(*d->digests));
- if (d->digests == NULL)
- return (-1);
- for (i = 0; i < num; i++) {
- if (d->defineds[i]) {
- if ((p = header_bytes(a, 4)) == NULL)
- return (-1);
- d->digests[i] = archive_le32dec(p);
- }
- }
-
- return (0);
-}
-
-static void
-free_PackInfo(struct _7z_pack_info *pi)
-{
- free(pi->sizes);
- free(pi->positions);
- free_Digest(&(pi->digest));
-}
-
-static int
-read_PackInfo(struct archive_read *a, struct _7z_pack_info *pi)
-{
- const unsigned char *p;
- unsigned i;
-
- memset(pi, 0, sizeof(*pi));
-
- /*
- * Read PackPos.
- */
- if (parse_7zip_uint64(a, &(pi->pos)) < 0)
- return (-1);
-
- /*
- * Read NumPackStreams.
- */
- if (parse_7zip_uint64(a, &(pi->numPackStreams)) < 0)
- return (-1);
- if (pi->numPackStreams == 0)
- return (-1);
- if (UMAX_ENTRY < pi->numPackStreams)
- return (-1);
-
- /*
- * Read PackSizes[num]
- */
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- if (*p == kEnd)
- /* PackSizes[num] are not present. */
- return (0);
- if (*p != kSize)
- return (-1);
- pi->sizes = calloc((size_t)pi->numPackStreams, sizeof(uint64_t));
- pi->positions = calloc((size_t)pi->numPackStreams, sizeof(uint64_t));
- if (pi->sizes == NULL || pi->positions == NULL)
- return (-1);
-
- for (i = 0; i < pi->numPackStreams; i++) {
- if (parse_7zip_uint64(a, &(pi->sizes[i])) < 0)
- return (-1);
- }
-
- /*
- * Read PackStreamDigests[num]
- */
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- if (*p == kEnd) {
- /* PackStreamDigests[num] are not present. */
- pi->digest.defineds =
- calloc((size_t)pi->numPackStreams, sizeof(*pi->digest.defineds));
- pi->digest.digests =
- calloc((size_t)pi->numPackStreams, sizeof(*pi->digest.digests));
- if (pi->digest.defineds == NULL || pi->digest.digests == NULL)
- return (-1);
- return (0);
- }
-
- if (*p != kCRC)
- return (-1);
-
- if (read_Digests(a, &(pi->digest), (size_t)pi->numPackStreams) < 0)
- return (-1);
-
- /*
- * Must be marked by kEnd.
- */
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- if (*p != kEnd)
- return (-1);
- return (0);
-}
-
-static void
-free_Folder(struct _7z_folder *f)
-{
- unsigned i;
-
- if (f->coders) {
- for (i = 0; i< f->numCoders; i++) {
- free(f->coders[i].properties);
- }
- free(f->coders);
- }
- free(f->bindPairs);
- free(f->packedStreams);
- free(f->unPackSize);
-}
-
-static int
-read_Folder(struct archive_read *a, struct _7z_folder *f)
-{
- struct _7zip *zip = (struct _7zip *)a->format->data;
- const unsigned char *p;
- uint64_t numInStreamsTotal = 0;
- uint64_t numOutStreamsTotal = 0;
- unsigned i;
-
- memset(f, 0, sizeof(*f));
-
- /*
- * Read NumCoders.
- */
- if (parse_7zip_uint64(a, &(f->numCoders)) < 0)
- return (-1);
- if (f->numCoders > 4)
- /* Too many coders. */
- return (-1);
-
- f->coders = calloc((size_t)f->numCoders, sizeof(*f->coders));
- if (f->coders == NULL)
- return (-1);
- for (i = 0; i< f->numCoders; i++) {
- size_t codec_size;
- int simple, attr;
-
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- /*
- * 0:3 CodecIdSize
- * 4: 0 - IsSimple
- * 1 - Is not Simple
- * 5: 0 - No Attributes
- * 1 - There are Attributes;
- * 7: Must be zero.
- */
- codec_size = *p & 0xf;
- simple = (*p & 0x10)?0:1;
- attr = *p & 0x20;
- if (*p & 0x80)
- return (-1);/* Not supported. */
-
- /*
- * Read Decompression Method IDs.
- */
- if ((p = header_bytes(a, codec_size)) == NULL)
- return (-1);
-
- f->coders[i].codec = decode_codec_id(p, codec_size);
-
- if (simple) {
- f->coders[i].numInStreams = 1;
- f->coders[i].numOutStreams = 1;
- } else {
- if (parse_7zip_uint64(
- a, &(f->coders[i].numInStreams)) < 0)
- return (-1);
- if (UMAX_ENTRY < f->coders[i].numInStreams)
- return (-1);
- if (parse_7zip_uint64(
- a, &(f->coders[i].numOutStreams)) < 0)
- return (-1);
- if (UMAX_ENTRY < f->coders[i].numOutStreams)
- return (-1);
- }
-
- if (attr) {
- if (parse_7zip_uint64(
- a, &(f->coders[i].propertiesSize)) < 0)
- return (-1);
- if ((p = header_bytes(
- a, (size_t)f->coders[i].propertiesSize)) == NULL)
- return (-1);
- f->coders[i].properties =
- malloc((size_t)f->coders[i].propertiesSize);
- if (f->coders[i].properties == NULL)
- return (-1);
- memcpy(f->coders[i].properties, p,
- (size_t)f->coders[i].propertiesSize);
- }
-
- numInStreamsTotal += f->coders[i].numInStreams;
- numOutStreamsTotal += f->coders[i].numOutStreams;
- }
-
- if (numOutStreamsTotal == 0 ||
- numInStreamsTotal < numOutStreamsTotal-1)
- return (-1);
-
- f->numBindPairs = numOutStreamsTotal - 1;
- if (zip->header_bytes_remaining < f->numBindPairs)
- return (-1);
- if (f->numBindPairs > 0) {
- f->bindPairs =
- calloc((size_t)f->numBindPairs, sizeof(*f->bindPairs));
- if (f->bindPairs == NULL)
- return (-1);
- } else
- f->bindPairs = NULL;
- for (i = 0; i < f->numBindPairs; i++) {
- if (parse_7zip_uint64(a, &(f->bindPairs[i].inIndex)) < 0)
- return (-1);
- if (UMAX_ENTRY < f->bindPairs[i].inIndex)
- return (-1);
- if (parse_7zip_uint64(a, &(f->bindPairs[i].outIndex)) < 0)
- return (-1);
- if (UMAX_ENTRY < f->bindPairs[i].outIndex)
- return (-1);
- }
-
- f->numPackedStreams = numInStreamsTotal - f->numBindPairs;
- f->packedStreams =
- calloc((size_t)f->numPackedStreams, sizeof(*f->packedStreams));
- if (f->packedStreams == NULL)
- return (-1);
- if (f->numPackedStreams == 1) {
- for (i = 0; i < numInStreamsTotal; i++) {
- unsigned j;
- for (j = 0; j < f->numBindPairs; j++) {
- if (f->bindPairs[j].inIndex == i)
- break;
- }
- if (j == f->numBindPairs)
- break;
- }
- if (i == numInStreamsTotal)
- return (-1);
- f->packedStreams[0] = i;
- } else {
- for (i = 0; i < f->numPackedStreams; i++) {
- if (parse_7zip_uint64(a, &(f->packedStreams[i])) < 0)
- return (-1);
- if (UMAX_ENTRY < f->packedStreams[i])
- return (-1);
- }
- }
- f->numInStreams = numInStreamsTotal;
- f->numOutStreams = numOutStreamsTotal;
-
- return (0);
-}
-
-static void
-free_CodersInfo(struct _7z_coders_info *ci)
-{
- unsigned i;
-
- if (ci->folders) {
- for (i = 0; i < ci->numFolders; i++)
- free_Folder(&(ci->folders[i]));
- free(ci->folders);
- }
-}
-
-static int
-read_CodersInfo(struct archive_read *a, struct _7z_coders_info *ci)
-{
- const unsigned char *p;
- struct _7z_digests digest;
- unsigned i;
-
- memset(ci, 0, sizeof(*ci));
- memset(&digest, 0, sizeof(digest));
-
- if ((p = header_bytes(a, 1)) == NULL)
- goto failed;
- if (*p != kFolder)
- goto failed;
-
- /*
- * Read NumFolders.
- */
- if (parse_7zip_uint64(a, &(ci->numFolders)) < 0)
- goto failed;
- if (UMAX_ENTRY < ci->numFolders)
- return (-1);
-
- /*
- * Read External.
- */
- if ((p = header_bytes(a, 1)) == NULL)
- goto failed;
- switch (*p) {
- case 0:
- ci->folders =
- calloc((size_t)ci->numFolders, sizeof(*ci->folders));
- if (ci->folders == NULL)
- return (-1);
- for (i = 0; i < ci->numFolders; i++) {
- if (read_Folder(a, &(ci->folders[i])) < 0)
- goto failed;
- }
- break;
- case 1:
- if (parse_7zip_uint64(a, &(ci->dataStreamIndex)) < 0)
- return (-1);
- if (UMAX_ENTRY < ci->dataStreamIndex)
- return (-1);
- if (ci->numFolders > 0) {
- archive_set_error(&a->archive, -1,
- "Malformed 7-Zip archive");
- goto failed;
- }
- break;
- default:
- archive_set_error(&a->archive, -1,
- "Malformed 7-Zip archive");
- goto failed;
- }
-
- if ((p = header_bytes(a, 1)) == NULL)
- goto failed;
- if (*p != kCodersUnPackSize)
- goto failed;
-
- for (i = 0; i < ci->numFolders; i++) {
- struct _7z_folder *folder = &(ci->folders[i]);
- unsigned j;
-
- folder->unPackSize =
- calloc((size_t)folder->numOutStreams, sizeof(*folder->unPackSize));
- if (folder->unPackSize == NULL)
- goto failed;
- for (j = 0; j < folder->numOutStreams; j++) {
- if (parse_7zip_uint64(a, &(folder->unPackSize[j])) < 0)
- goto failed;
- }
- }
-
- /*
- * Read CRCs.
- */
- if ((p = header_bytes(a, 1)) == NULL)
- goto failed;
- if (*p == kEnd)
- return (0);
- if (*p != kCRC)
- goto failed;
- if (read_Digests(a, &digest, (size_t)ci->numFolders) < 0)
- goto failed;
- for (i = 0; i < ci->numFolders; i++) {
- ci->folders[i].digest_defined = digest.defineds[i];
- ci->folders[i].digest = digest.digests[i];
- }
-
- /*
- * Must be kEnd.
- */
- if ((p = header_bytes(a, 1)) == NULL)
- goto failed;
- if (*p != kEnd)
- goto failed;
- free_Digest(&digest);
- return (0);
-failed:
- free_Digest(&digest);
- return (-1);
-}
-
-static uint64_t
-folder_uncompressed_size(struct _7z_folder *f)
-{
- int n = (int)f->numOutStreams;
- unsigned pairs = (unsigned)f->numBindPairs;
-
- while (--n >= 0) {
- unsigned i;
- for (i = 0; i < pairs; i++) {
- if (f->bindPairs[i].outIndex == (uint64_t)n)
- break;
- }
- if (i >= pairs)
- return (f->unPackSize[n]);
- }
- return (0);
-}
-
-static void
-free_SubStreamsInfo(struct _7z_substream_info *ss)
-{
- free(ss->unpackSizes);
- free(ss->digestsDefined);
- free(ss->digests);
-}
-
-static int
-read_SubStreamsInfo(struct archive_read *a, struct _7z_substream_info *ss,
- struct _7z_folder *f, size_t numFolders)
-{
- const unsigned char *p;
- uint64_t *usizes;
- size_t unpack_streams;
- int type;
- unsigned i;
- uint32_t numDigests;
-
- memset(ss, 0, sizeof(*ss));
-
- for (i = 0; i < numFolders; i++)
- f[i].numUnpackStreams = 1;
-
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- type = *p;
-
- if (type == kNumUnPackStream) {
- unpack_streams = 0;
- for (i = 0; i < numFolders; i++) {
- if (parse_7zip_uint64(a, &(f[i].numUnpackStreams)) < 0)
- return (-1);
- if (UMAX_ENTRY < f[i].numUnpackStreams)
- return (-1);
- if (unpack_streams > SIZE_MAX - UMAX_ENTRY) {
- return (-1);
- }
- unpack_streams += (size_t)f[i].numUnpackStreams;
- }
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- type = *p;
- } else
- unpack_streams = numFolders;
-
- ss->unpack_streams = unpack_streams;
- if (unpack_streams) {
- ss->unpackSizes = calloc(unpack_streams,
- sizeof(*ss->unpackSizes));
- ss->digestsDefined = calloc(unpack_streams,
- sizeof(*ss->digestsDefined));
- ss->digests = calloc(unpack_streams,
- sizeof(*ss->digests));
- if (ss->unpackSizes == NULL || ss->digestsDefined == NULL ||
- ss->digests == NULL)
- return (-1);
- }
-
- usizes = ss->unpackSizes;
- for (i = 0; i < numFolders; i++) {
- unsigned pack;
- uint64_t sum;
-
- if (f[i].numUnpackStreams == 0)
- continue;
-
- sum = 0;
- if (type == kSize) {
- for (pack = 1; pack < f[i].numUnpackStreams; pack++) {
- if (parse_7zip_uint64(a, usizes) < 0)
- return (-1);
- sum += *usizes++;
- }
- }
- *usizes++ = folder_uncompressed_size(&f[i]) - sum;
- }
-
- if (type == kSize) {
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- type = *p;
- }
-
- for (i = 0; i < unpack_streams; i++) {
- ss->digestsDefined[i] = 0;
- ss->digests[i] = 0;
- }
-
- numDigests = 0;
- for (i = 0; i < numFolders; i++) {
- if (f[i].numUnpackStreams != 1 || !f[i].digest_defined)
- numDigests += (uint32_t)f[i].numUnpackStreams;
- }
-
- if (type == kCRC) {
- struct _7z_digests tmpDigests;
- unsigned char *digestsDefined = ss->digestsDefined;
- uint32_t * digests = ss->digests;
- int di = 0;
-
- memset(&tmpDigests, 0, sizeof(tmpDigests));
- if (read_Digests(a, &(tmpDigests), numDigests) < 0) {
- free_Digest(&tmpDigests);
- return (-1);
- }
- for (i = 0; i < numFolders; i++) {
- if (f[i].numUnpackStreams == 1 && f[i].digest_defined) {
- *digestsDefined++ = 1;
- *digests++ = f[i].digest;
- } else {
- unsigned j;
-
- for (j = 0; j < f[i].numUnpackStreams;
- j++, di++) {
- *digestsDefined++ =
- tmpDigests.defineds[di];
- *digests++ =
- tmpDigests.digests[di];
- }
- }
- }
- free_Digest(&tmpDigests);
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- type = *p;
- }
-
- /*
- * Must be kEnd.
- */
- if (type != kEnd)
- return (-1);
- return (0);
-}
-
-static void
-free_StreamsInfo(struct _7z_stream_info *si)
-{
- free_PackInfo(&(si->pi));
- free_CodersInfo(&(si->ci));
- free_SubStreamsInfo(&(si->ss));
-}
-
-static int
-read_StreamsInfo(struct archive_read *a, struct _7z_stream_info *si)
-{
- struct _7zip *zip = (struct _7zip *)a->format->data;
- const unsigned char *p;
- unsigned i;
-
- memset(si, 0, sizeof(*si));
-
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- if (*p == kPackInfo) {
- uint64_t packPos;
-
- if (read_PackInfo(a, &(si->pi)) < 0)
- return (-1);
-
- if (si->pi.positions == NULL || si->pi.sizes == NULL)
- return (-1);
- /*
- * Calculate packed stream positions.
- */
- packPos = si->pi.pos;
- for (i = 0; i < si->pi.numPackStreams; i++) {
- si->pi.positions[i] = packPos;
- packPos += si->pi.sizes[i];
- if (packPos > zip->header_offset)
- return (-1);
- }
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- }
- if (*p == kUnPackInfo) {
- uint32_t packIndex;
- struct _7z_folder *f;
-
- if (read_CodersInfo(a, &(si->ci)) < 0)
- return (-1);
-
- /*
- * Calculate packed stream indexes.
- */
- packIndex = 0;
- f = si->ci.folders;
- for (i = 0; i < si->ci.numFolders; i++) {
- f[i].packIndex = packIndex;
- packIndex += (uint32_t)f[i].numPackedStreams;
- if (packIndex > si->pi.numPackStreams)
- return (-1);
- }
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- }
-
- if (*p == kSubStreamsInfo) {
- if (read_SubStreamsInfo(a, &(si->ss),
- si->ci.folders, (size_t)si->ci.numFolders) < 0)
- return (-1);
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- }
-
- /*
- * Must be kEnd.
- */
- if (*p != kEnd)
- return (-1);
- return (0);
-}
-
-static void
-free_Header(struct _7z_header_info *h)
-{
- free(h->emptyStreamBools);
- free(h->emptyFileBools);
- free(h->antiBools);
- free(h->attrBools);
-}
-
-static int
-read_Header(struct archive_read *a, struct _7z_header_info *h,
- int check_header_id)
-{
- struct _7zip *zip = (struct _7zip *)a->format->data;
- const unsigned char *p;
- struct _7z_folder *folders;
- struct _7z_stream_info *si = &(zip->si);
- struct _7zip_entry *entries;
- uint32_t folderIndex, indexInFolder;
- unsigned i;
- int eindex, empty_streams, sindex;
-
- if (check_header_id) {
- /*
- * Read Header.
- */
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- if (*p != kHeader)
- return (-1);
- }
-
- /*
- * Read ArchiveProperties.
- */
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- if (*p == kArchiveProperties) {
- for (;;) {
- uint64_t size;
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- if (*p == 0)
- break;
- if (parse_7zip_uint64(a, &size) < 0)
- return (-1);
- }
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- }
-
- /*
- * Read MainStreamsInfo.
- */
- if (*p == kMainStreamsInfo) {
- if (read_StreamsInfo(a, &(zip->si)) < 0)
- return (-1);
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- }
- if (*p == kEnd)
- return (0);
-
- /*
- * Read FilesInfo.
- */
- if (*p != kFilesInfo)
- return (-1);
-
- if (parse_7zip_uint64(a, &(zip->numFiles)) < 0)
- return (-1);
- if (UMAX_ENTRY < zip->numFiles)
- return (-1);
-
- zip->entries = calloc((size_t)zip->numFiles, sizeof(*zip->entries));
- if (zip->entries == NULL)
- return (-1);
- entries = zip->entries;
-
- empty_streams = 0;
- for (;;) {
- int type;
- uint64_t size;
- size_t ll;
-
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- type = *p;
- if (type == kEnd)
- break;
-
- if (parse_7zip_uint64(a, &size) < 0)
- return (-1);
- if (zip->header_bytes_remaining < size)
- return (-1);
- ll = (size_t)size;
-
- switch (type) {
- case kEmptyStream:
- if (h->emptyStreamBools != NULL)
- return (-1);
- h->emptyStreamBools = calloc((size_t)zip->numFiles,
- sizeof(*h->emptyStreamBools));
- if (h->emptyStreamBools == NULL)
- return (-1);
- if (read_Bools(
- a, h->emptyStreamBools, (size_t)zip->numFiles) < 0)
- return (-1);
- empty_streams = 0;
- for (i = 0; i < zip->numFiles; i++) {
- if (h->emptyStreamBools[i])
- empty_streams++;
- }
- break;
- case kEmptyFile:
- if (empty_streams <= 0) {
- /* Unexcepted sequence. Skip this. */
- if (header_bytes(a, ll) == NULL)
- return (-1);
- break;
- }
- if (h->emptyFileBools != NULL)
- return (-1);
- h->emptyFileBools = calloc(empty_streams,
- sizeof(*h->emptyFileBools));
- if (h->emptyFileBools == NULL)
- return (-1);
- if (read_Bools(a, h->emptyFileBools, empty_streams) < 0)
- return (-1);
- break;
- case kAnti:
- if (empty_streams <= 0) {
- /* Unexcepted sequence. Skip this. */
- if (header_bytes(a, ll) == NULL)
- return (-1);
- break;
- }
- if (h->antiBools != NULL)
- return (-1);
- h->antiBools = calloc(empty_streams,
- sizeof(*h->antiBools));
- if (h->antiBools == NULL)
- return (-1);
- if (read_Bools(a, h->antiBools, empty_streams) < 0)
- return (-1);
- break;
- case kCTime:
- case kATime:
- case kMTime:
- if (read_Times(a, h, type) < 0)
- return (-1);
- break;
- case kName:
- {
- unsigned char *np;
- size_t nl, nb;
-
- /* Skip one byte. */
- if ((p = header_bytes(a, 1)) == NULL)
- return (-1);
- ll--;
-
- if ((ll & 1) || ll < zip->numFiles * 4)
- return (-1);
-
- if (zip->entry_names != NULL)
- return (-1);
- zip->entry_names = malloc(ll);
- if (zip->entry_names == NULL)
- return (-1);
- np = zip->entry_names;
- nb = ll;
- /*
- * Copy whole file names.
- * NOTE: This loop prevents from expanding
- * the uncompressed buffer in order not to
- * use extra memory resource.
- */
- while (nb) {
- size_t b;
- if (nb > UBUFF_SIZE)
- b = UBUFF_SIZE;
- else
- b = nb;
- if ((p = header_bytes(a, b)) == NULL)
- return (-1);
- memcpy(np, p, b);
- np += b;
- nb -= b;
- }
- np = zip->entry_names;
- nl = ll;
-
- for (i = 0; i < zip->numFiles; i++) {
- entries[i].utf16name = np;
-#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
- entries[i].wname = (wchar_t *)np;
-#endif
-
- /* Find a terminator. */
- while (nl >= 2 && (np[0] || np[1])) {
- np += 2;
- nl -= 2;
- }
- if (nl < 2)
- return (-1);/* Terminator not found */
- entries[i].name_len = np - entries[i].utf16name;
- np += 2;
- nl -= 2;
- }
- break;
- }
- case kAttributes:
- {
- int allAreDefined;
-
- if ((p = header_bytes(a, 2)) == NULL)
- return (-1);
- allAreDefined = *p;
- if (h->attrBools != NULL)
- return (-1);
- h->attrBools = calloc((size_t)zip->numFiles,
- sizeof(*h->attrBools));
- if (h->attrBools == NULL)
- return (-1);
- if (allAreDefined)
- memset(h->attrBools, 1, (size_t)zip->numFiles);
- else {
- if (read_Bools(a, h->attrBools,
- (size_t)zip->numFiles) < 0)
- return (-1);
- }
- for (i = 0; i < zip->numFiles; i++) {
- if (h->attrBools[i]) {
- if ((p = header_bytes(a, 4)) == NULL)
- return (-1);
- entries[i].attr = archive_le32dec(p);
- }
- }
- break;
- }
- case kDummy:
- if (ll == 0)
- break;
- __LA_FALLTHROUGH;
- default:
- if (header_bytes(a, ll) == NULL)
- return (-1);
- break;
- }
- }
-
- /*
- * Set up entry's attributes.
- */
- folders = si->ci.folders;
- eindex = sindex = 0;
- folderIndex = indexInFolder = 0;
- for (i = 0; i < zip->numFiles; i++) {
- if (h->emptyStreamBools == NULL || h->emptyStreamBools[i] == 0)
- entries[i].flg |= HAS_STREAM;
- /* The high 16 bits of attributes is a posix file mode. */
- entries[i].mode = entries[i].attr >> 16;
- if (entries[i].flg & HAS_STREAM) {
- if ((size_t)sindex >= si->ss.unpack_streams)
- return (-1);
- if (entries[i].mode == 0)
- entries[i].mode = AE_IFREG | 0666;
- if (si->ss.digestsDefined[sindex])
- entries[i].flg |= CRC32_IS_SET;
- entries[i].ssIndex = sindex;
- sindex++;
- } else {
- int dir;
- if (h->emptyFileBools == NULL)
- dir = 1;
- else {
- if (h->emptyFileBools[eindex])
- dir = 0;
- else
- dir = 1;
- eindex++;
- }
- if (entries[i].mode == 0) {
- if (dir)
- entries[i].mode = AE_IFDIR | 0777;
- else
- entries[i].mode = AE_IFREG | 0666;
- } else if (dir &&
- (entries[i].mode & AE_IFMT) != AE_IFDIR) {
- entries[i].mode &= ~AE_IFMT;
- entries[i].mode |= AE_IFDIR;
- }
- if ((entries[i].mode & AE_IFMT) == AE_IFDIR &&
- entries[i].name_len >= 2 &&
- (entries[i].utf16name[entries[i].name_len-2] != '/' ||
- entries[i].utf16name[entries[i].name_len-1] != 0)) {
- entries[i].utf16name[entries[i].name_len] = '/';
- entries[i].utf16name[entries[i].name_len+1] = 0;
- entries[i].name_len += 2;
- }
- entries[i].ssIndex = -1;
- }
- if (entries[i].attr & 0x01)
- entries[i].mode &= ~0222;/* Read only. */
-
- if ((entries[i].flg & HAS_STREAM) == 0 && indexInFolder == 0) {
- /*
- * The entry is an empty file or a directory file,
- * those both have no contents.
- */
- entries[i].folderIndex = -1;
- continue;
- }
- if (indexInFolder == 0) {
- for (;;) {
- if (folderIndex >= si->ci.numFolders)
- return (-1);
- if (folders[folderIndex].numUnpackStreams)
- break;
- folderIndex++;
- }
- }
- entries[i].folderIndex = folderIndex;
- if ((entries[i].flg & HAS_STREAM) == 0)
- continue;
- indexInFolder++;
- if (indexInFolder >= folders[folderIndex].numUnpackStreams) {
- folderIndex++;
- indexInFolder = 0;
- }
- }
-
- return (0);
-}
-
-#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
-static void
-fileTimeToUtc(uint64_t fileTime, time_t *timep, long *ns)
-{
-
- if (fileTime >= EPOC_TIME) {
- fileTime -= EPOC_TIME;
- /* milli seconds base */
- *timep = (time_t)(fileTime / 10000000);
- /* nano seconds base */
- *ns = (long)(fileTime % 10000000) * 100;
- } else {
- *timep = 0;
- *ns = 0;
- }
-}
-
-static int
-read_Times(struct archive_read *a, struct _7z_header_info *h, int type)
-{
- struct _7zip *zip = (struct _7zip *)a->format->data;
- const unsigned char *p;
- struct _7zip_entry *entries = zip->entries;
- unsigned char *timeBools;
- int allAreDefined;
- unsigned i;
-
- timeBools = calloc((size_t)zip->numFiles, sizeof(*timeBools));
- if (timeBools == NULL)
- return (-1);
-
- /* Read allAreDefined. */
- if ((p = header_bytes(a, 1)) == NULL)
- goto failed;
- allAreDefined = *p;
- if (allAreDefined)
- memset(timeBools, 1, (size_t)zip->numFiles);
- else {
- if (read_Bools(a, timeBools, (size_t)zip->numFiles) < 0)
- goto failed;
- }
-
- /* Read external. */
- if ((p = header_bytes(a, 1)) == NULL)
- goto failed;
- if (*p) {
- if (parse_7zip_uint64(a, &(h->dataIndex)) < 0)
- goto failed;
- if (UMAX_ENTRY < h->dataIndex)
- goto failed;
- }
-
- for (i = 0; i < zip->numFiles; i++) {
- if (!timeBools[i])
- continue;
- if ((p = header_bytes(a, 8)) == NULL)
- goto failed;
- switch (type) {
- case kCTime:
- fileTimeToUtc(archive_le64dec(p),
- &(entries[i].ctime),
- &(entries[i].ctime_ns));
- entries[i].flg |= CTIME_IS_SET;
- break;
- case kATime:
- fileTimeToUtc(archive_le64dec(p),
- &(entries[i].atime),
- &(entries[i].atime_ns));
- entries[i].flg |= ATIME_IS_SET;
- break;
- case kMTime:
- fileTimeToUtc(archive_le64dec(p),
- &(entries[i].mtime),
- &(entries[i].mtime_ns));
- entries[i].flg |= MTIME_IS_SET;
- break;
- }
- }
-
- free(timeBools);
- return (0);
-failed:
- free(timeBools);
- return (-1);
-}
-
-static int
-decode_encoded_header_info(struct archive_read *a, struct _7z_stream_info *si)
-{
- struct _7zip *zip = (struct _7zip *)a->format->data;
-
- errno = 0;
- if (read_StreamsInfo(a, si) < 0) {
- if (errno == ENOMEM)
- archive_set_error(&a->archive, -1,
- "Couldn't allocate memory");
- else
- archive_set_error(&a->archive, -1,
- "Malformed 7-Zip archive");
- return (ARCHIVE_FATAL);
- }
-
- if (si->pi.numPackStreams == 0 || si->ci.numFolders == 0) {
- archive_set_error(&a->archive, -1, "Malformed 7-Zip archive");
- return (ARCHIVE_FATAL);
- }
-
- if (zip->header_offset < si->pi.pos + si->pi.sizes[0] ||
- (int64_t)(si->pi.pos + si->pi.sizes[0]) < 0 ||
- si->pi.sizes[0] == 0 || (int64_t)si->pi.pos < 0) {
- archive_set_error(&a->archive, -1, "Malformed Header offset");
- return (ARCHIVE_FATAL);
- }
-
- return (ARCHIVE_OK);
-}
-
-static const unsigned char *
-header_bytes(struct archive_read *a, size_t rbytes)
-{
- struct _7zip *zip = (struct _7zip *)a->format->data;
- const unsigned char *p;
-
- if (zip->header_bytes_remaining < rbytes)
- return (NULL);
- if (zip->pack_stream_bytes_unconsumed)
- read_consume(a);
-
- if (zip->header_is_encoded == 0) {
- p = __archive_read_ahead(a, rbytes, NULL);
- if (p == NULL)
- return (NULL);
- zip->header_bytes_remaining -= rbytes;
- zip->pack_stream_bytes_unconsumed = rbytes;
- } else {
- const void *buff;
- ssize_t bytes;
-
- bytes = read_stream(a, &buff, rbytes, rbytes);
- if (bytes <= 0)
- return (NULL);
- zip->header_bytes_remaining -= bytes;
- p = buff;
- }
-
- /* Update checksum */
- zip->header_crc32 = crc32(zip->header_crc32, p, (unsigned)rbytes);
- return (p);
-}
-
-static int
-slurp_central_directory(struct archive_read *a, struct _7zip *zip,
- struct _7z_header_info *header)
-{
- const unsigned char *p;
- uint64_t next_header_offset;
- uint64_t next_header_size;
- uint32_t next_header_crc;
- ssize_t bytes_avail;
- int check_header_crc, r;
-
- if ((p = __archive_read_ahead(a, 32, &bytes_avail)) == NULL)
- return (ARCHIVE_FATAL);
-
- if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) {
- /* This is an executable ? Must be self-extracting... */
- r = skip_sfx(a, bytes_avail);
- if (r < ARCHIVE_WARN)
- return (r);
- if ((p = __archive_read_ahead(a, 32, &bytes_avail)) == NULL)
- return (ARCHIVE_FATAL);
- }
- zip->seek_base += 32;
-
- if (memcmp(p, _7ZIP_SIGNATURE, 6) != 0) {
- archive_set_error(&a->archive, -1, "Not 7-Zip archive file");
- return (ARCHIVE_FATAL);
- }
-
- /* CRC check. */
- if (crc32(0, (const unsigned char *)p + 12, 20)
- != archive_le32dec(p + 8)) {
-#ifdef DONT_FAIL_ON_CRC_ERROR
- archive_set_error(&a->archive, -1, "Header CRC error");
- return (ARCHIVE_FATAL);
-#endif
- }
-
- next_header_offset = archive_le64dec(p + 12);
- next_header_size = archive_le64dec(p + 20);
- next_header_crc = archive_le32dec(p + 28);
-
- if (next_header_size == 0)
- /* There is no entry in an archive file. */
- return (ARCHIVE_EOF);
-
- if (((int64_t)next_header_offset) < 0) {
- archive_set_error(&a->archive, -1, "Malformed 7-Zip archive");
- return (ARCHIVE_FATAL);
- }
- __archive_read_consume(a, 32);
- if (next_header_offset != 0) {
- if (bytes_avail >= (ssize_t)next_header_offset)
- __archive_read_consume(a, next_header_offset);
- else if (__archive_read_seek(a,
- next_header_offset + zip->seek_base, SEEK_SET) < 0)
- return (ARCHIVE_FATAL);
- }
- zip->stream_offset = next_header_offset;
- zip->header_offset = next_header_offset;
- zip->header_bytes_remaining = next_header_size;
- zip->header_crc32 = 0;
- zip->header_is_encoded = 0;
- zip->header_is_being_read = 1;
- zip->has_encrypted_entries = 0;
- check_header_crc = 1;
-
- if ((p = header_bytes(a, 1)) == NULL) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated 7-Zip file body");
- return (ARCHIVE_FATAL);
- }
- /* Parse ArchiveProperties. */
- switch (p[0]) {
- case kEncodedHeader:
- /*
- * The archive has an encoded header and we have to decode it
- * in order to parse the header correctly.
- */
- r = decode_encoded_header_info(a, &(zip->si));
-
- /* Check the EncodedHeader CRC.*/
- if (r == 0 && zip->header_crc32 != next_header_crc) {
- archive_set_error(&a->archive, -1,
-#ifndef DONT_FAIL_ON_CRC_ERROR
- "Damaged 7-Zip archive");
- r = -1;
-#endif
- }
- if (r == 0) {
- if (zip->si.ci.folders[0].digest_defined)
- next_header_crc = zip->si.ci.folders[0].digest;
- else
- check_header_crc = 0;
- if (zip->pack_stream_bytes_unconsumed)
- read_consume(a);
- r = setup_decode_folder(a, zip->si.ci.folders, 1);
- if (r == 0) {
- zip->header_bytes_remaining =
- zip->folder_outbytes_remaining;
- r = seek_pack(a);
- }
- }
- /* Clean up StreamsInfo. */
- free_StreamsInfo(&(zip->si));
- memset(&(zip->si), 0, sizeof(zip->si));
- if (r < 0)
- return (ARCHIVE_FATAL);
- zip->header_is_encoded = 1;
- zip->header_crc32 = 0;
- /* FALL THROUGH */
- case kHeader:
- /*
- * Parse the header.
- */
- errno = 0;
- r = read_Header(a, header, zip->header_is_encoded);
- if (r < 0) {
- if (errno == ENOMEM)
- archive_set_error(&a->archive, -1,
- "Couldn't allocate memory");
- else
- archive_set_error(&a->archive, -1,
- "Damaged 7-Zip archive");
- return (ARCHIVE_FATAL);
- }
-
- /*
- * Must be kEnd.
- */
- if ((p = header_bytes(a, 1)) == NULL ||*p != kEnd) {
- archive_set_error(&a->archive, -1,
- "Malformed 7-Zip archive");
- return (ARCHIVE_FATAL);
- }
-
- /* Check the Header CRC.*/
- if (check_header_crc && zip->header_crc32 != next_header_crc) {
-#ifndef DONT_FAIL_ON_CRC_ERROR
- archive_set_error(&a->archive, -1,
- "Malformed 7-Zip archive");
- return (ARCHIVE_FATAL);
-#endif
- }
- break;
- default:
- archive_set_error(&a->archive, -1,
- "Unexpected Property ID = %X", p[0]);
- return (ARCHIVE_FATAL);
- }
-
- /* Clean up variables be used for decoding the archive header */
- zip->pack_stream_remaining = 0;
- zip->pack_stream_index = 0;
- zip->folder_outbytes_remaining = 0;
- zip->uncompressed_buffer_bytes_remaining = 0;
- zip->pack_stream_bytes_unconsumed = 0;
- zip->header_is_being_read = 0;
-
- return (ARCHIVE_OK);
-}
-
-static ssize_t
-get_uncompressed_data(struct archive_read *a, const void **buff, size_t size,
- size_t minimum)
-{
- struct _7zip *zip = (struct _7zip *)a->format->data;
- ssize_t bytes_avail;
-
- if (zip->codec == _7Z_COPY && zip->codec2 == (unsigned long)-1) {
- /* Copy mode. */
-
- *buff = __archive_read_ahead(a, minimum, &bytes_avail);
- if (bytes_avail <= 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated 7-Zip file data");
- return (ARCHIVE_FATAL);
- }
- if ((size_t)bytes_avail >
- zip->uncompressed_buffer_bytes_remaining)
- bytes_avail = (ssize_t)
- zip->uncompressed_buffer_bytes_remaining;
- if ((size_t)bytes_avail > size)
- bytes_avail = (ssize_t)size;
-
- zip->pack_stream_bytes_unconsumed = bytes_avail;
- } else if (zip->uncompressed_buffer_pointer == NULL) {
- /* Decompression has failed. */
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive");
- return (ARCHIVE_FATAL);
- } else {
- /* Packed mode. */
- if (minimum > zip->uncompressed_buffer_bytes_remaining) {
- /*
- * If remaining uncompressed data size is less than
- * the minimum size, fill the buffer up to the
- * minimum size.
- */
- if (extract_pack_stream(a, minimum) < 0)
- return (ARCHIVE_FATAL);
- }
- if (size > zip->uncompressed_buffer_bytes_remaining)
- bytes_avail = (ssize_t)
- zip->uncompressed_buffer_bytes_remaining;
- else
- bytes_avail = (ssize_t)size;
- *buff = zip->uncompressed_buffer_pointer;
- zip->uncompressed_buffer_pointer += bytes_avail;
- }
- zip->uncompressed_buffer_bytes_remaining -= bytes_avail;
- return (bytes_avail);
-}
-
-static ssize_t
-extract_pack_stream(struct archive_read *a, size_t minimum)
-{
- struct _7zip *zip = (struct _7zip *)a->format->data;
- ssize_t bytes_avail;
- int r;
-
- if (zip->codec == _7Z_COPY && zip->codec2 == (unsigned long)-1) {
- if (minimum == 0)
- minimum = 1;
- if (__archive_read_ahead(a, minimum, &bytes_avail) == NULL
- || bytes_avail <= 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated 7-Zip file body");
- return (ARCHIVE_FATAL);
- }
- if ((uint64_t)bytes_avail > zip->pack_stream_inbytes_remaining)
- bytes_avail = (ssize_t)zip->pack_stream_inbytes_remaining;
- zip->pack_stream_inbytes_remaining -= bytes_avail;
- if ((uint64_t)bytes_avail > zip->folder_outbytes_remaining)
- bytes_avail = (ssize_t)zip->folder_outbytes_remaining;
- zip->folder_outbytes_remaining -= bytes_avail;
- zip->uncompressed_buffer_bytes_remaining = bytes_avail;
- return (ARCHIVE_OK);
- }
-
- /* If the buffer hasn't been allocated, allocate it now. */
- if (zip->uncompressed_buffer == NULL) {
- zip->uncompressed_buffer_size = UBUFF_SIZE;
- if (zip->uncompressed_buffer_size < minimum) {
- zip->uncompressed_buffer_size = minimum + 1023;
- zip->uncompressed_buffer_size &= ~0x3ff;
- }
- zip->uncompressed_buffer =
- malloc(zip->uncompressed_buffer_size);
- if (zip->uncompressed_buffer == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for 7-Zip decompression");
- return (ARCHIVE_FATAL);
- }
- zip->uncompressed_buffer_bytes_remaining = 0;
- } else if (zip->uncompressed_buffer_size < minimum ||
- zip->uncompressed_buffer_bytes_remaining < minimum) {
- /*
- * Make sure the uncompressed buffer can have bytes
- * at least `minimum' bytes.
- * NOTE: This case happen when reading the header.
- */
- size_t used;
- if (zip->uncompressed_buffer_pointer != 0)
- used = zip->uncompressed_buffer_pointer -
- zip->uncompressed_buffer;
- else
- used = 0;
- if (zip->uncompressed_buffer_size < minimum) {
- /*
- * Expand the uncompressed buffer up to
- * the minimum size.
- */
- void *p;
- size_t new_size;
-
- new_size = minimum + 1023;
- new_size &= ~0x3ff;
- p = realloc(zip->uncompressed_buffer, new_size);
- if (p == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for 7-Zip decompression");
- return (ARCHIVE_FATAL);
- }
- zip->uncompressed_buffer = (unsigned char *)p;
- zip->uncompressed_buffer_size = new_size;
- }
- /*
- * Move unconsumed bytes to the head.
- */
- if (used) {
- memmove(zip->uncompressed_buffer,
- zip->uncompressed_buffer + used,
- zip->uncompressed_buffer_bytes_remaining);
- }
- } else
- zip->uncompressed_buffer_bytes_remaining = 0;
- zip->uncompressed_buffer_pointer = NULL;
- for (;;) {
- size_t bytes_in, bytes_out;
- const void *buff_in;
- unsigned char *buff_out;
- int end_of_data;
-
- /*
- * Note: '1' here is a performance optimization.
- * Recall that the decompression layer returns a count of
- * available bytes; asking for more than that forces the
- * decompressor to combine reads by copying data.
- */
- buff_in = __archive_read_ahead(a, 1, &bytes_avail);
- if (bytes_avail <= 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated 7-Zip file body");
- return (ARCHIVE_FATAL);
- }
-
- buff_out = zip->uncompressed_buffer
- + zip->uncompressed_buffer_bytes_remaining;
- bytes_out = zip->uncompressed_buffer_size
- - zip->uncompressed_buffer_bytes_remaining;
- bytes_in = bytes_avail;
- if (bytes_in > zip->pack_stream_inbytes_remaining)
- bytes_in = (size_t)zip->pack_stream_inbytes_remaining;
- /* Drive decompression. */
- r = decompress(a, zip, buff_out, &bytes_out,
- buff_in, &bytes_in);
- switch (r) {
- case ARCHIVE_OK:
- end_of_data = 0;
- break;
- case ARCHIVE_EOF:
- end_of_data = 1;
- break;
- default:
- return (ARCHIVE_FATAL);
- }
- zip->pack_stream_inbytes_remaining -= bytes_in;
- if (bytes_out > zip->folder_outbytes_remaining)
- bytes_out = (size_t)zip->folder_outbytes_remaining;
- zip->folder_outbytes_remaining -= bytes_out;
- zip->uncompressed_buffer_bytes_remaining += bytes_out;
- zip->pack_stream_bytes_unconsumed = bytes_in;
-
- /*
- * Continue decompression until uncompressed_buffer is full.
- */
- if (zip->uncompressed_buffer_bytes_remaining ==
- zip->uncompressed_buffer_size)
- break;
- if (zip->codec2 == _7Z_X86 && zip->odd_bcj_size &&
- zip->uncompressed_buffer_bytes_remaining + 5 >
- zip->uncompressed_buffer_size)
- break;
- if (zip->pack_stream_inbytes_remaining == 0 &&
- zip->folder_outbytes_remaining == 0)
- break;
- if (end_of_data || (bytes_in == 0 && bytes_out == 0)) {
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive");
- return (ARCHIVE_FATAL);
- }
- read_consume(a);
- }
- if (zip->uncompressed_buffer_bytes_remaining < minimum) {
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive");
- return (ARCHIVE_FATAL);
- }
- zip->uncompressed_buffer_pointer = zip->uncompressed_buffer;
- return (ARCHIVE_OK);
-}
-
-static int
-seek_pack(struct archive_read *a)
-{
- struct _7zip *zip = (struct _7zip *)a->format->data;
- int64_t pack_offset;
-
- if (zip->pack_stream_remaining <= 0) {
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive");
- return (ARCHIVE_FATAL);
- }
- zip->pack_stream_inbytes_remaining =
- zip->si.pi.sizes[zip->pack_stream_index];
- pack_offset = zip->si.pi.positions[zip->pack_stream_index];
- if (zip->stream_offset != pack_offset) {
- if (0 > __archive_read_seek(a, pack_offset + zip->seek_base,
- SEEK_SET))
- return (ARCHIVE_FATAL);
- zip->stream_offset = pack_offset;
- }
- zip->pack_stream_index++;
- zip->pack_stream_remaining--;
- return (ARCHIVE_OK);
-}
-
-static ssize_t
-read_stream(struct archive_read *a, const void **buff, size_t size,
- size_t minimum)
-{
- struct _7zip *zip = (struct _7zip *)a->format->data;
- uint64_t skip_bytes = 0;
- ssize_t r;
-
- if (zip->uncompressed_buffer_bytes_remaining == 0) {
- if (zip->pack_stream_inbytes_remaining > 0) {
- r = extract_pack_stream(a, 0);
- if (r < 0)
- return (r);
- return (get_uncompressed_data(a, buff, size, minimum));
- } else if (zip->folder_outbytes_remaining > 0) {
- /* Extract a remaining pack stream. */
- r = extract_pack_stream(a, 0);
- if (r < 0)
- return (r);
- return (get_uncompressed_data(a, buff, size, minimum));
- }
- } else
- return (get_uncompressed_data(a, buff, size, minimum));
-
- /*
- * Current pack stream has been consumed.
- */
- if (zip->pack_stream_remaining == 0) {
- if (zip->header_is_being_read) {
- /* Invalid sequence. This might happen when
- * reading a malformed archive. */
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC, "Malformed 7-Zip archive");
- return (ARCHIVE_FATAL);
- }
-
- /*
- * All current folder's pack streams have been
- * consumed. Switch to next folder.
- */
- if (zip->folder_index == 0 &&
- (zip->si.ci.folders[zip->entry->folderIndex].skipped_bytes
- || zip->folder_index != zip->entry->folderIndex)) {
- zip->folder_index = zip->entry->folderIndex;
- skip_bytes =
- zip->si.ci.folders[zip->folder_index].skipped_bytes;
- }
-
- if (zip->folder_index >= zip->si.ci.numFolders) {
- /*
- * We have consumed all folders and its pack streams.
- */
- *buff = NULL;
- return (0);
- }
- r = setup_decode_folder(a,
- &(zip->si.ci.folders[zip->folder_index]), 0);
- if (r != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- zip->folder_index++;
- }
-
- /*
- * Switch to next pack stream.
- */
- r = seek_pack(a);
- if (r < 0)
- return (r);
-
- /* Extract a new pack stream. */
- r = extract_pack_stream(a, 0);
- if (r < 0)
- return (r);
-
- /*
- * Skip the bytes we already has skipped in skip_stream().
- */
- while (skip_bytes) {
- ssize_t skipped;
-
- if (zip->uncompressed_buffer_bytes_remaining == 0) {
- if (zip->pack_stream_inbytes_remaining > 0) {
- r = extract_pack_stream(a, 0);
- if (r < 0)
- return (r);
- } else if (zip->folder_outbytes_remaining > 0) {
- /* Extract a remaining pack stream. */
- r = extract_pack_stream(a, 0);
- if (r < 0)
- return (r);
- } else {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated 7-Zip file body");
- return (ARCHIVE_FATAL);
- }
- }
- skipped = get_uncompressed_data(
- a, buff, (size_t)skip_bytes, 0);
- if (skipped < 0)
- return (skipped);
- skip_bytes -= skipped;
- if (zip->pack_stream_bytes_unconsumed)
- read_consume(a);
- }
-
- return (get_uncompressed_data(a, buff, size, minimum));
-}
-
-static int
-setup_decode_folder(struct archive_read *a, struct _7z_folder *folder,
- int header)
-{
- struct _7zip *zip = (struct _7zip *)a->format->data;
- const struct _7z_coder *coder1, *coder2;
- const char *cname = (header)?"archive header":"file content";
- unsigned i;
- int r, found_bcj2 = 0;
-
- /*
- * Release the memory which the previous folder used for BCJ2.
- */
- for (i = 0; i < 3; i++) {
- free(zip->sub_stream_buff[i]);
- zip->sub_stream_buff[i] = NULL;
- }
-
- /*
- * Initialize a stream reader.
- */
- zip->pack_stream_remaining = (unsigned)folder->numPackedStreams;
- zip->pack_stream_index = (unsigned)folder->packIndex;
- zip->folder_outbytes_remaining = folder_uncompressed_size(folder);
- zip->uncompressed_buffer_bytes_remaining = 0;
-
- /*
- * Check coder types.
- */
- for (i = 0; i < folder->numCoders; i++) {
- switch(folder->coders[i].codec) {
- case _7Z_CRYPTO_MAIN_ZIP:
- case _7Z_CRYPTO_RAR_29:
- case _7Z_CRYPTO_AES_256_SHA_256: {
- /* For entry that is associated with this folder, mark
- it as encrypted (data+metadata). */
- zip->has_encrypted_entries = 1;
- if (a->entry) {
- archive_entry_set_is_data_encrypted(a->entry, 1);
- archive_entry_set_is_metadata_encrypted(a->entry, 1);
- }
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "The %s is encrypted, "
- "but currently not supported", cname);
- return (ARCHIVE_FATAL);
- }
- case _7Z_X86_BCJ2: {
- found_bcj2++;
- break;
- }
- }
- }
- /* Now that we've checked for encryption, if there were still no
- * encrypted entries found we can say for sure that there are none.
- */
- if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
- zip->has_encrypted_entries = 0;
- }
-
- if ((folder->numCoders > 2 && !found_bcj2) || found_bcj2 > 1) {
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "The %s is encoded with many filters, "
- "but currently not supported", cname);
- return (ARCHIVE_FATAL);
- }
- coder1 = &(folder->coders[0]);
- if (folder->numCoders == 2)
- coder2 = &(folder->coders[1]);
- else
- coder2 = NULL;
-
- if (found_bcj2) {
- /*
- * Preparation to decode BCJ2.
- * Decoding BCJ2 requires four sources. Those are at least,
- * as far as I know, two types of the storage form.
- */
- const struct _7z_coder *fc = folder->coders;
- static const struct _7z_coder coder_copy = {0, 1, 1, 0, NULL};
- const struct _7z_coder *scoder[3] =
- {&coder_copy, &coder_copy, &coder_copy};
- const void *buff;
- ssize_t bytes;
- unsigned char *b[3] = {NULL, NULL, NULL};
- uint64_t sunpack[3] ={-1, -1, -1};
- size_t s[3] = {0, 0, 0};
- int idx[3] = {0, 1, 2};
-
- if (folder->numCoders == 4 && fc[3].codec == _7Z_X86_BCJ2 &&
- folder->numInStreams == 7 && folder->numOutStreams == 4 &&
- zip->pack_stream_remaining == 4) {
- /* Source type 1 made by 7zr or 7z with -m options. */
- if (folder->bindPairs[0].inIndex == 5) {
- /* The form made by 7zr */
- idx[0] = 1; idx[1] = 2; idx[2] = 0;
- scoder[1] = &(fc[1]);
- scoder[2] = &(fc[0]);
- sunpack[1] = folder->unPackSize[1];
- sunpack[2] = folder->unPackSize[0];
- coder1 = &(fc[2]);
- } else {
- /*
- * NOTE: Some patterns do not work.
- * work:
- * 7z a -m0=BCJ2 -m1=COPY -m2=COPY
- * -m3=(any)
- * 7z a -m0=BCJ2 -m1=COPY -m2=(any)
- * -m3=COPY
- * 7z a -m0=BCJ2 -m1=(any) -m2=COPY
- * -m3=COPY
- * not work:
- * other patterns.
- *
- * We have to handle this like `pipe' or
- * our libarchive7s filter frame work,
- * decoding the BCJ2 main stream sequentially,
- * m3 -> m2 -> m1 -> BCJ2.
- *
- */
- if (fc[0].codec == _7Z_COPY &&
- fc[1].codec == _7Z_COPY)
- coder1 = &(folder->coders[2]);
- else if (fc[0].codec == _7Z_COPY &&
- fc[2].codec == _7Z_COPY)
- coder1 = &(folder->coders[1]);
- else if (fc[1].codec == _7Z_COPY &&
- fc[2].codec == _7Z_COPY)
- coder1 = &(folder->coders[0]);
- else {
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "Unsupported form of "
- "BCJ2 streams");
- return (ARCHIVE_FATAL);
- }
- }
- coder2 = &(fc[3]);
- zip->main_stream_bytes_remaining =
- (size_t)folder->unPackSize[2];
- } else if (coder2 != NULL && coder2->codec == _7Z_X86_BCJ2 &&
- zip->pack_stream_remaining == 4 &&
- folder->numInStreams == 5 && folder->numOutStreams == 2) {
- /* Source type 0 made by 7z */
- zip->main_stream_bytes_remaining =
- (size_t)folder->unPackSize[0];
- } else {
- /* We got an unexpected form. */
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "Unsupported form of BCJ2 streams");
- return (ARCHIVE_FATAL);
- }
-
- /* Skip the main stream at this time. */
- if ((r = seek_pack(a)) < 0)
- return (r);
- zip->pack_stream_bytes_unconsumed =
- (size_t)zip->pack_stream_inbytes_remaining;
- read_consume(a);
-
- /* Read following three sub streams. */
- for (i = 0; i < 3; i++) {
- const struct _7z_coder *coder = scoder[i];
-
- if ((r = seek_pack(a)) < 0) {
- free(b[0]); free(b[1]); free(b[2]);
- return (r);
- }
-
- if (sunpack[i] == (uint64_t)-1)
- zip->folder_outbytes_remaining =
- zip->pack_stream_inbytes_remaining;
- else
- zip->folder_outbytes_remaining = sunpack[i];
-
- r = init_decompression(a, zip, coder, NULL);
- if (r != ARCHIVE_OK) {
- free(b[0]); free(b[1]); free(b[2]);
- return (ARCHIVE_FATAL);
- }
-
- /* Allocate memory for the decoded data of a sub
- * stream. */
- b[i] = malloc((size_t)zip->folder_outbytes_remaining);
- if (b[i] == NULL) {
- free(b[0]); free(b[1]); free(b[2]);
- archive_set_error(&a->archive, ENOMEM,
- "No memory for 7-Zip decompression");
- return (ARCHIVE_FATAL);
- }
-
- /* Extract a sub stream. */
- while (zip->pack_stream_inbytes_remaining > 0) {
- r = (int)extract_pack_stream(a, 0);
- if (r < 0) {
- free(b[0]); free(b[1]); free(b[2]);
- return (r);
- }
- bytes = get_uncompressed_data(a, &buff,
- zip->uncompressed_buffer_bytes_remaining,
- 0);
- if (bytes < 0) {
- free(b[0]); free(b[1]); free(b[2]);
- return ((int)bytes);
- }
- memcpy(b[i]+s[i], buff, bytes);
- s[i] += bytes;
- if (zip->pack_stream_bytes_unconsumed)
- read_consume(a);
- }
- }
-
- /* Set the sub streams to the right place. */
- for (i = 0; i < 3; i++) {
- zip->sub_stream_buff[i] = b[idx[i]];
- zip->sub_stream_size[i] = s[idx[i]];
- zip->sub_stream_bytes_remaining[i] = s[idx[i]];
- }
-
- /* Allocate memory used for decoded main stream bytes. */
- if (zip->tmp_stream_buff == NULL) {
- zip->tmp_stream_buff_size = 32 * 1024;
- zip->tmp_stream_buff =
- malloc(zip->tmp_stream_buff_size);
- if (zip->tmp_stream_buff == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for 7-Zip decompression");
- return (ARCHIVE_FATAL);
- }
- }
- zip->tmp_stream_bytes_avail = 0;
- zip->tmp_stream_bytes_remaining = 0;
- zip->odd_bcj_size = 0;
- zip->bcj2_outPos = 0;
-
- /*
- * Reset a stream reader in order to read the main stream
- * of BCJ2.
- */
- zip->pack_stream_remaining = 1;
- zip->pack_stream_index = (unsigned)folder->packIndex;
- zip->folder_outbytes_remaining =
- folder_uncompressed_size(folder);
- zip->uncompressed_buffer_bytes_remaining = 0;
- }
-
- /*
- * Initialize the decompressor for the new folder's pack streams.
- */
- r = init_decompression(a, zip, coder1, coder2);
- if (r != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- return (ARCHIVE_OK);
-}
-
-static int64_t
-skip_stream(struct archive_read *a, size_t skip_bytes)
-{
- struct _7zip *zip = (struct _7zip *)a->format->data;
- const void *p;
- int64_t skipped_bytes;
- size_t bytes = skip_bytes;
-
- if (zip->folder_index == 0) {
- /*
- * Optimization for a list mode.
- * Avoid unnecessary decoding operations.
- */
- zip->si.ci.folders[zip->entry->folderIndex].skipped_bytes
- += skip_bytes;
- return (skip_bytes);
- }
-
- while (bytes) {
- skipped_bytes = read_stream(a, &p, bytes, 0);
- if (skipped_bytes < 0)
- return (skipped_bytes);
- if (skipped_bytes == 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated 7-Zip file body");
- return (ARCHIVE_FATAL);
- }
- bytes -= (size_t)skipped_bytes;
- if (zip->pack_stream_bytes_unconsumed)
- read_consume(a);
- }
- return (skip_bytes);
-}
-
-/*
- * Brought from LZMA SDK.
- *
- * Bra86.c -- Converter for x86 code (BCJ)
- * 2008-10-04 : Igor Pavlov : Public domain
- *
- */
-
-#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
-
-static void
-x86_Init(struct _7zip *zip)
-{
- zip->bcj_state = 0;
- zip->bcj_prevPosT = (size_t)0 - 1;
- zip->bcj_prevMask = 0;
- zip->bcj_ip = 5;
-}
-
-static size_t
-x86_Convert(struct _7zip *zip, uint8_t *data, size_t size)
-{
- static const uint8_t kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
- static const uint8_t kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
- size_t bufferPos, prevPosT;
- uint32_t ip, prevMask;
-
- if (size < 5)
- return 0;
-
- bufferPos = 0;
- prevPosT = zip->bcj_prevPosT;
- prevMask = zip->bcj_prevMask;
- ip = zip->bcj_ip;
-
- for (;;) {
- uint8_t *p = data + bufferPos;
- uint8_t *limit = data + size - 4;
-
- for (; p < limit; p++)
- if ((*p & 0xFE) == 0xE8)
- break;
- bufferPos = (size_t)(p - data);
- if (p >= limit)
- break;
- prevPosT = bufferPos - prevPosT;
- if (prevPosT > 3)
- prevMask = 0;
- else {
- prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
- if (prevMask != 0) {
- unsigned char b =
- p[4 - kMaskToBitNumber[prevMask]];
- if (!kMaskToAllowedStatus[prevMask] ||
- Test86MSByte(b)) {
- prevPosT = bufferPos;
- prevMask = ((prevMask << 1) & 0x7) | 1;
- bufferPos++;
- continue;
- }
- }
- }
- prevPosT = bufferPos;
-
- if (Test86MSByte(p[4])) {
- uint32_t src = ((uint32_t)p[4] << 24) |
- ((uint32_t)p[3] << 16) | ((uint32_t)p[2] << 8) |
- ((uint32_t)p[1]);
- uint32_t dest;
- for (;;) {
- uint8_t b;
- int b_index;
-
- dest = src - (ip + (uint32_t)bufferPos);
- if (prevMask == 0)
- break;
- b_index = kMaskToBitNumber[prevMask] * 8;
- b = (uint8_t)(dest >> (24 - b_index));
- if (!Test86MSByte(b))
- break;
- src = dest ^ ((1 << (32 - b_index)) - 1);
- }
- p[4] = (uint8_t)(~(((dest >> 24) & 1) - 1));
- p[3] = (uint8_t)(dest >> 16);
- p[2] = (uint8_t)(dest >> 8);
- p[1] = (uint8_t)dest;
- bufferPos += 5;
- } else {
- prevMask = ((prevMask << 1) & 0x7) | 1;
- bufferPos++;
- }
- }
- zip->bcj_prevPosT = prevPosT;
- zip->bcj_prevMask = prevMask;
- zip->bcj_ip += (uint32_t)bufferPos;
- return (bufferPos);
-}
-
-static void
-arm_Init(struct _7zip *zip)
-{
- zip->bcj_ip = 8;
-}
-
-static size_t
-arm_Convert(struct _7zip *zip, uint8_t *buf, size_t size)
-{
- // This function was adapted from
- // static size_t bcj_arm(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
- // in https://git.tukaani.org/xz-embedded.git
-
- /*
- * Branch/Call/Jump (BCJ) filter decoders
- *
- * Authors: Lasse Collin <lasse.collin@tukaani.org>
- * Igor Pavlov <https://7-zip.org/>
- *
- * This file has been put into the public domain.
- * You can do whatever you want with this file.
- */
-
- size_t i;
- uint32_t addr;
-
- for (i = 0; i + 4 <= size; i += 4) {
- if (buf[i + 3] == 0xEB) {
- // Calculate the transformed addr.
- addr = (uint32_t)buf[i] | ((uint32_t)buf[i + 1] << 8)
- | ((uint32_t)buf[i + 2] << 16);
- addr <<= 2;
- addr -= zip->bcj_ip + (uint32_t)i;
- addr >>= 2;
-
- // Store the transformed addr in buf.
- buf[i] = (uint8_t)addr;
- buf[i + 1] = (uint8_t)(addr >> 8);
- buf[i + 2] = (uint8_t)(addr >> 16);
- }
- }
-
- zip->bcj_ip += (uint32_t)i;
-
- return i;
-}
-
-static size_t
-arm64_Convert(struct _7zip *zip, uint8_t *buf, size_t size)
-{
- // This function was adapted from
- // static size_t bcj_arm64(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
- // in https://git.tukaani.org/xz-embedded.git
-
- /*
- * Branch/Call/Jump (BCJ) filter decoders
- *
- * Authors: Lasse Collin <lasse.collin@tukaani.org>
- * Igor Pavlov <https://7-zip.org/>
- *
- * This file has been put into the public domain.
- * You can do whatever you want with this file.
- */
-
- size_t i;
- uint32_t instr;
- uint32_t addr;
-
- for (i = 0; i + 4 <= size; i += 4) {
- instr = (uint32_t)buf[i]
- | ((uint32_t)buf[i+1] << 8)
- | ((uint32_t)buf[i+2] << 16)
- | ((uint32_t)buf[i+3] << 24);
-
- if ((instr >> 26) == 0x25) {
- /* BL instruction */
- addr = instr - ((zip->bcj_ip + (uint32_t)i) >> 2);
- instr = 0x94000000 | (addr & 0x03FFFFFF);
-
- buf[i] = (uint8_t)instr;
- buf[i+1] = (uint8_t)(instr >> 8);
- buf[i+2] = (uint8_t)(instr >> 16);
- buf[i+3] = (uint8_t)(instr >> 24);
- } else if ((instr & 0x9F000000) == 0x90000000) {
- /* ADRP instruction */
- addr = ((instr >> 29) & 3) | ((instr >> 3) & 0x1FFFFC);
-
- /* Only convert values in the range +/-512 MiB. */
- if ((addr + 0x020000) & 0x1C0000)
- continue;
-
- addr -= (zip->bcj_ip + (uint32_t)i) >> 12;
-
- instr &= 0x9000001F;
- instr |= (addr & 3) << 29;
- instr |= (addr & 0x03FFFC) << 3;
- instr |= (0U - (addr & 0x020000)) & 0xE00000;
-
- buf[i] = (uint8_t)instr;
- buf[i+1] = (uint8_t)(instr >> 8);
- buf[i+2] = (uint8_t)(instr >> 16);
- buf[i+3] = (uint8_t)(instr >> 24);
- }
- }
-
- zip->bcj_ip += (uint32_t)i;
-
- return i;
-}
-
-/*
- * Brought from LZMA SDK.
- *
- * Bcj2.c -- Converter for x86 code (BCJ2)
- * 2008-10-04 : Igor Pavlov : Public domain
- *
- */
-
-#define SZ_ERROR_DATA ARCHIVE_FAILED
-
-#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
-#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
-
-#define kNumTopBits 24
-#define kTopValue ((uint32_t)1 << kNumTopBits)
-
-#define kNumBitModelTotalBits 11
-#define kBitModelTotal (1 << kNumBitModelTotalBits)
-#define kNumMoveBits 5
-
-#define RC_READ_BYTE (*buffer++)
-#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; }
-#define RC_INIT2 zip->bcj2_code = 0; zip->bcj2_range = 0xFFFFFFFF; \
- { int ii; for (ii = 0; ii < 5; ii++) { RC_TEST; zip->bcj2_code = (zip->bcj2_code << 8) | RC_READ_BYTE; }}
-
-#define NORMALIZE if (zip->bcj2_range < kTopValue) { RC_TEST; zip->bcj2_range <<= 8; zip->bcj2_code = (zip->bcj2_code << 8) | RC_READ_BYTE; }
-
-#define IF_BIT_0(p) ttt = *(p); bound = (zip->bcj2_range >> kNumBitModelTotalBits) * ttt; if (zip->bcj2_code < bound)
-#define UPDATE_0(p) zip->bcj2_range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;
-#define UPDATE_1(p) zip->bcj2_range -= bound; zip->bcj2_code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;
-
-static ssize_t
-Bcj2_Decode(struct _7zip *zip, uint8_t *outBuf, size_t outSize)
-{
- size_t inPos = 0, outPos = 0;
- const uint8_t *buf0, *buf1, *buf2, *buf3;
- size_t size0, size1, size2, size3;
- const uint8_t *buffer, *bufferLim;
- unsigned int i, j;
-
- size0 = zip->tmp_stream_bytes_remaining;
- buf0 = zip->tmp_stream_buff + zip->tmp_stream_bytes_avail - size0;
- size1 = zip->sub_stream_bytes_remaining[0];
- buf1 = zip->sub_stream_buff[0] + zip->sub_stream_size[0] - size1;
- size2 = zip->sub_stream_bytes_remaining[1];
- buf2 = zip->sub_stream_buff[1] + zip->sub_stream_size[1] - size2;
- size3 = zip->sub_stream_bytes_remaining[2];
- buf3 = zip->sub_stream_buff[2] + zip->sub_stream_size[2] - size3;
-
- buffer = buf3;
- bufferLim = buffer + size3;
-
- if (zip->bcj_state == 0) {
- /*
- * Initialize.
- */
- zip->bcj2_prevByte = 0;
- for (i = 0;
- i < sizeof(zip->bcj2_p) / sizeof(zip->bcj2_p[0]); i++)
- zip->bcj2_p[i] = kBitModelTotal >> 1;
- RC_INIT2;
- zip->bcj_state = 1;
- }
-
- /*
- * Gather the odd bytes of a previous call.
- */
- for (i = 0; zip->odd_bcj_size > 0 && outPos < outSize; i++) {
- outBuf[outPos++] = zip->odd_bcj[i];
- zip->odd_bcj_size--;
- }
-
- if (outSize == 0) {
- zip->bcj2_outPos += outPos;
- return (outPos);
- }
-
- for (;;) {
- uint8_t b;
- CProb *prob;
- uint32_t bound;
- uint32_t ttt;
-
- size_t limit = size0 - inPos;
- if (outSize - outPos < limit)
- limit = outSize - outPos;
-
- if (zip->bcj_state == 1) {
- while (limit != 0) {
- uint8_t bb = buf0[inPos];
- outBuf[outPos++] = bb;
- if (IsJ(zip->bcj2_prevByte, bb)) {
- zip->bcj_state = 2;
- break;
- }
- inPos++;
- zip->bcj2_prevByte = bb;
- limit--;
- }
- }
-
- if (limit == 0 || outPos == outSize)
- break;
- zip->bcj_state = 1;
-
- b = buf0[inPos++];
-
- if (b == 0xE8)
- prob = zip->bcj2_p + zip->bcj2_prevByte;
- else if (b == 0xE9)
- prob = zip->bcj2_p + 256;
- else
- prob = zip->bcj2_p + 257;
-
- IF_BIT_0(prob) {
- UPDATE_0(prob)
- zip->bcj2_prevByte = b;
- } else {
- uint32_t dest;
- const uint8_t *v;
- uint8_t out[4];
-
- UPDATE_1(prob)
- if (b == 0xE8) {
- v = buf1;
- if (size1 < 4)
- return SZ_ERROR_DATA;
- buf1 += 4;
- size1 -= 4;
- } else {
- v = buf2;
- if (size2 < 4)
- return SZ_ERROR_DATA;
- buf2 += 4;
- size2 -= 4;
- }
- dest = (((uint32_t)v[0] << 24) |
- ((uint32_t)v[1] << 16) |
- ((uint32_t)v[2] << 8) |
- ((uint32_t)v[3])) -
- ((uint32_t)zip->bcj2_outPos + (uint32_t)outPos + 4);
- out[0] = (uint8_t)dest;
- out[1] = (uint8_t)(dest >> 8);
- out[2] = (uint8_t)(dest >> 16);
- out[3] = zip->bcj2_prevByte = (uint8_t)(dest >> 24);
-
- for (i = 0; i < 4 && outPos < outSize; i++)
- outBuf[outPos++] = out[i];
- if (i < 4) {
- /*
- * Save odd bytes which we could not add into
- * the output buffer because of out of space.
- */
- zip->odd_bcj_size = 4 -i;
- for (; i < 4; i++) {
- j = i - 4 + (unsigned)zip->odd_bcj_size;
- zip->odd_bcj[j] = out[i];
- }
- break;
- }
- }
- }
- zip->tmp_stream_bytes_remaining -= inPos;
- zip->sub_stream_bytes_remaining[0] = size1;
- zip->sub_stream_bytes_remaining[1] = size2;
- zip->sub_stream_bytes_remaining[2] = bufferLim - buffer;
- zip->bcj2_outPos += outPos;
-
- return ((ssize_t)outPos);
-}
-
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_format_all.c b/contrib/libs/libarchive/libarchive/archive_read_support_format_all.c
deleted file mode 100644
index dea558bbfc..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_format_all.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*-
- * Copyright (c) 2003-2011 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_all.c 174991 2007-12-30 04:58:22Z kientzle $");
-
-#include "archive.h"
-#include "archive_private.h"
-
-int
-archive_read_support_format_all(struct archive *a)
-{
- archive_check_magic(a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_format_all");
-
- /* TODO: It would be nice to compute the ordering
- * here automatically so that people who enable just
- * a few formats can still get the benefits. That
- * may just require the format registration to include
- * a "maximum read-ahead" value (anything that uses seek
- * would be essentially infinite read-ahead). The core
- * bid management can then sort the bidders before calling
- * them.
- *
- * If you implement the above, please return the list below
- * to alphabetic order.
- */
-
- /*
- * These bidders are all pretty cheap; they just examine a
- * small initial part of the archive. If one of these bids
- * high, we can maybe avoid running any of the more expensive
- * bidders below.
- */
- archive_read_support_format_ar(a);
- archive_read_support_format_cpio(a);
- archive_read_support_format_empty(a);
- archive_read_support_format_lha(a);
- archive_read_support_format_mtree(a);
- archive_read_support_format_tar(a);
- archive_read_support_format_xar(a);
- archive_read_support_format_warc(a);
-
- /*
- * Install expensive bidders last. By doing them last, we
- * increase the chance that a high bid from someone else will
- * make it unnecessary for these to do anything at all.
- */
- /* These three have potentially large look-ahead. */
- archive_read_support_format_7zip(a);
- archive_read_support_format_cab(a);
- archive_read_support_format_rar(a);
- archive_read_support_format_rar5(a);
- archive_read_support_format_iso9660(a);
- /* Seek is really bad, since it forces the read-ahead
- * logic to discard buffered data. */
- archive_read_support_format_zip(a);
-
- /* Note: We always return ARCHIVE_OK here, even if some of the
- * above return ARCHIVE_WARN. The intent here is to enable
- * "as much as possible." Clients who need specific
- * compression should enable those individually so they can
- * verify the level of support. */
- /* Clear any warning messages set by the above functions. */
- archive_clear_error(a);
- return (ARCHIVE_OK);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_format_ar.c b/contrib/libs/libarchive/libarchive/archive_read_support_format_ar.c
deleted file mode 100644
index 296b7db041..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_format_ar.c
+++ /dev/null
@@ -1,638 +0,0 @@
-/*-
- * Copyright (c) 2007 Kai Wang
- * Copyright (c) 2007 Tim Kientzle
- * 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
- * in this position and unchanged.
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_ar.c 201101 2009-12-28 03:06:27Z kientzle $");
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-struct ar {
- int64_t entry_bytes_remaining;
- /* unconsumed is purely to track data we've gotten from readahead,
- * but haven't yet marked as consumed. Must be paired with
- * entry_bytes_remaining usage/modification.
- */
- size_t entry_bytes_unconsumed;
- int64_t entry_offset;
- int64_t entry_padding;
- char *strtab;
- size_t strtab_size;
- char read_global_header;
-};
-
-/*
- * Define structure of the "ar" header.
- */
-#define AR_name_offset 0
-#define AR_name_size 16
-#define AR_date_offset 16
-#define AR_date_size 12
-#define AR_uid_offset 28
-#define AR_uid_size 6
-#define AR_gid_offset 34
-#define AR_gid_size 6
-#define AR_mode_offset 40
-#define AR_mode_size 8
-#define AR_size_offset 48
-#define AR_size_size 10
-#define AR_fmag_offset 58
-#define AR_fmag_size 2
-
-static int archive_read_format_ar_bid(struct archive_read *a, int);
-static int archive_read_format_ar_cleanup(struct archive_read *a);
-static int archive_read_format_ar_read_data(struct archive_read *a,
- const void **buff, size_t *size, int64_t *offset);
-static int archive_read_format_ar_skip(struct archive_read *a);
-static int archive_read_format_ar_read_header(struct archive_read *a,
- struct archive_entry *e);
-static uint64_t ar_atol8(const char *p, unsigned char_cnt);
-static uint64_t ar_atol10(const char *p, unsigned char_cnt);
-static int ar_parse_gnu_filename_table(struct archive_read *a);
-static int ar_parse_common_header(struct ar *ar, struct archive_entry *,
- const char *h);
-
-int
-archive_read_support_format_ar(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- struct ar *ar;
- int r;
-
- archive_check_magic(_a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_format_ar");
-
- ar = (struct ar *)calloc(1, sizeof(*ar));
- if (ar == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate ar data");
- return (ARCHIVE_FATAL);
- }
- ar->strtab = NULL;
-
- r = __archive_read_register_format(a,
- ar,
- "ar",
- archive_read_format_ar_bid,
- NULL,
- archive_read_format_ar_read_header,
- archive_read_format_ar_read_data,
- archive_read_format_ar_skip,
- NULL,
- archive_read_format_ar_cleanup,
- NULL,
- NULL);
-
- if (r != ARCHIVE_OK) {
- free(ar);
- return (r);
- }
- return (ARCHIVE_OK);
-}
-
-static int
-archive_read_format_ar_cleanup(struct archive_read *a)
-{
- struct ar *ar;
-
- ar = (struct ar *)(a->format->data);
- free(ar->strtab);
- free(ar);
- (a->format->data) = NULL;
- return (ARCHIVE_OK);
-}
-
-static int
-archive_read_format_ar_bid(struct archive_read *a, int best_bid)
-{
- const void *h;
-
- (void)best_bid; /* UNUSED */
-
- /*
- * Verify the 8-byte file signature.
- * TODO: Do we need to check more than this?
- */
- if ((h = __archive_read_ahead(a, 8, NULL)) == NULL)
- return (-1);
- if (memcmp(h, "!<arch>\n", 8) == 0) {
- return (64);
- }
- return (-1);
-}
-
-static int
-_ar_read_header(struct archive_read *a, struct archive_entry *entry,
- struct ar *ar, const char *h, size_t *unconsumed)
-{
- char filename[AR_name_size + 1];
- uint64_t number; /* Used to hold parsed numbers before validation. */
- size_t bsd_name_length, entry_size;
- char *p, *st;
- const void *b;
- int r;
-
- /* Verify the magic signature on the file header. */
- if (strncmp(h + AR_fmag_offset, "`\n", 2) != 0) {
- archive_set_error(&a->archive, EINVAL,
- "Incorrect file header signature");
- return (ARCHIVE_FATAL);
- }
-
- /* Copy filename into work buffer. */
- strncpy(filename, h + AR_name_offset, AR_name_size);
- filename[AR_name_size] = '\0';
-
- /*
- * Guess the format variant based on the filename.
- */
- if (a->archive.archive_format == ARCHIVE_FORMAT_AR) {
- /* We don't already know the variant, so let's guess. */
- /*
- * Biggest clue is presence of '/': GNU starts special
- * filenames with '/', appends '/' as terminator to
- * non-special names, so anything with '/' should be
- * GNU except for BSD long filenames.
- */
- if (strncmp(filename, "#1/", 3) == 0)
- a->archive.archive_format = ARCHIVE_FORMAT_AR_BSD;
- else if (strchr(filename, '/') != NULL)
- a->archive.archive_format = ARCHIVE_FORMAT_AR_GNU;
- else if (strncmp(filename, "__.SYMDEF", 9) == 0)
- a->archive.archive_format = ARCHIVE_FORMAT_AR_BSD;
- /*
- * XXX Do GNU/SVR4 'ar' programs ever omit trailing '/'
- * if name exactly fills 16-byte field? If so, we
- * can't assume entries without '/' are BSD. XXX
- */
- }
-
- /* Update format name from the code. */
- if (a->archive.archive_format == ARCHIVE_FORMAT_AR_GNU)
- a->archive.archive_format_name = "ar (GNU/SVR4)";
- else if (a->archive.archive_format == ARCHIVE_FORMAT_AR_BSD)
- a->archive.archive_format_name = "ar (BSD)";
- else
- a->archive.archive_format_name = "ar";
-
- /*
- * Remove trailing spaces from the filename. GNU and BSD
- * variants both pad filename area out with spaces.
- * This will only be wrong if GNU/SVR4 'ar' implementations
- * omit trailing '/' for 16-char filenames and we have
- * a 16-char filename that ends in ' '.
- */
- p = filename + AR_name_size - 1;
- while (p >= filename && *p == ' ') {
- *p = '\0';
- p--;
- }
-
- /*
- * Remove trailing slash unless first character is '/'.
- * (BSD entries never end in '/', so this will only trim
- * GNU-format entries. GNU special entries start with '/'
- * and are not terminated in '/', so we don't trim anything
- * that starts with '/'.)
- */
- if (filename[0] != '/' && p > filename && *p == '/') {
- *p = '\0';
- }
-
- if (p < filename) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Found entry with empty filename");
- return (ARCHIVE_FATAL);
- }
-
- /*
- * '//' is the GNU filename table.
- * Later entries can refer to names in this table.
- */
- if (strcmp(filename, "//") == 0) {
- /* This must come before any call to _read_ahead. */
- ar_parse_common_header(ar, entry, h);
- archive_entry_copy_pathname(entry, filename);
- archive_entry_set_filetype(entry, AE_IFREG);
- /* Get the size of the filename table. */
- number = ar_atol10(h + AR_size_offset, AR_size_size);
- if (number > SIZE_MAX || number > 1024 * 1024 * 1024) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Filename table too large");
- return (ARCHIVE_FATAL);
- }
- entry_size = (size_t)number;
- if (entry_size == 0) {
- archive_set_error(&a->archive, EINVAL,
- "Invalid string table");
- return (ARCHIVE_FATAL);
- }
- if (ar->strtab != NULL) {
- archive_set_error(&a->archive, EINVAL,
- "More than one string tables exist");
- return (ARCHIVE_FATAL);
- }
-
- /* Read the filename table into memory. */
- st = malloc(entry_size);
- if (st == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate filename table buffer");
- return (ARCHIVE_FATAL);
- }
- ar->strtab = st;
- ar->strtab_size = entry_size;
-
- if (*unconsumed) {
- __archive_read_consume(a, *unconsumed);
- *unconsumed = 0;
- }
-
- if ((b = __archive_read_ahead(a, entry_size, NULL)) == NULL)
- return (ARCHIVE_FATAL);
- memcpy(st, b, entry_size);
- __archive_read_consume(a, entry_size);
- /* All contents are consumed. */
- ar->entry_bytes_remaining = 0;
- archive_entry_set_size(entry, ar->entry_bytes_remaining);
-
- /* Parse the filename table. */
- return (ar_parse_gnu_filename_table(a));
- }
-
- /*
- * GNU variant handles long filenames by storing /<number>
- * to indicate a name stored in the filename table.
- * XXX TODO: Verify that it's all digits... Don't be fooled
- * by "/9xyz" XXX
- */
- if (filename[0] == '/' && filename[1] >= '0' && filename[1] <= '9') {
- number = ar_atol10(h + AR_name_offset + 1, AR_name_size - 1);
- /*
- * If we can't look up the real name, warn and return
- * the entry with the wrong name.
- */
- if (ar->strtab == NULL || number >= ar->strtab_size) {
- archive_set_error(&a->archive, EINVAL,
- "Can't find long filename for GNU/SVR4 archive entry");
- archive_entry_copy_pathname(entry, filename);
- /* Parse the time, owner, mode, size fields. */
- ar_parse_common_header(ar, entry, h);
- return (ARCHIVE_FATAL);
- }
-
- archive_entry_copy_pathname(entry, &ar->strtab[(size_t)number]);
- /* Parse the time, owner, mode, size fields. */
- return (ar_parse_common_header(ar, entry, h));
- }
-
- /*
- * BSD handles long filenames by storing "#1/" followed by the
- * length of filename as a decimal number, then prepends the
- * the filename to the file contents.
- */
- if (strncmp(filename, "#1/", 3) == 0) {
- /* Parse the time, owner, mode, size fields. */
- /* This must occur before _read_ahead is called again. */
- ar_parse_common_header(ar, entry, h);
-
- /* Parse the size of the name, adjust the file size. */
- number = ar_atol10(h + AR_name_offset + 3, AR_name_size - 3);
- /* Sanity check the filename length:
- * = Must be <= SIZE_MAX - 1
- * = Must be <= 1MB
- * = Cannot be bigger than the entire entry
- */
- if (number > SIZE_MAX - 1
- || number > 1024 * 1024
- || (int64_t)number > ar->entry_bytes_remaining) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Bad input file size");
- return (ARCHIVE_FATAL);
- }
- bsd_name_length = (size_t)number;
- ar->entry_bytes_remaining -= bsd_name_length;
- /* Adjust file size reported to client. */
- archive_entry_set_size(entry, ar->entry_bytes_remaining);
-
- if (*unconsumed) {
- __archive_read_consume(a, *unconsumed);
- *unconsumed = 0;
- }
-
- /* Read the long name into memory. */
- if ((b = __archive_read_ahead(a, bsd_name_length, NULL)) == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Truncated input file");
- return (ARCHIVE_FATAL);
- }
- /* Store it in the entry. */
- p = (char *)malloc(bsd_name_length + 1);
- if (p == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate fname buffer");
- return (ARCHIVE_FATAL);
- }
- strncpy(p, b, bsd_name_length);
- p[bsd_name_length] = '\0';
-
- __archive_read_consume(a, bsd_name_length);
-
- archive_entry_copy_pathname(entry, p);
- free(p);
- return (ARCHIVE_OK);
- }
-
- /*
- * "/" is the SVR4/GNU archive symbol table.
- * "/SYM64/" is the SVR4/GNU 64-bit variant archive symbol table.
- */
- if (strcmp(filename, "/") == 0 || strcmp(filename, "/SYM64/") == 0) {
- archive_entry_copy_pathname(entry, filename);
- /* Parse the time, owner, mode, size fields. */
- r = ar_parse_common_header(ar, entry, h);
- /* Force the file type to a regular file. */
- archive_entry_set_filetype(entry, AE_IFREG);
- return (r);
- }
-
- /*
- * "__.SYMDEF" is a BSD archive symbol table.
- */
- if (strcmp(filename, "__.SYMDEF") == 0) {
- archive_entry_copy_pathname(entry, filename);
- /* Parse the time, owner, mode, size fields. */
- return (ar_parse_common_header(ar, entry, h));
- }
-
- /*
- * Otherwise, this is a standard entry. The filename
- * has already been trimmed as much as possible, based
- * on our current knowledge of the format.
- */
- archive_entry_copy_pathname(entry, filename);
- return (ar_parse_common_header(ar, entry, h));
-}
-
-static int
-archive_read_format_ar_read_header(struct archive_read *a,
- struct archive_entry *entry)
-{
- struct ar *ar = (struct ar*)(a->format->data);
- size_t unconsumed;
- const void *header_data;
- int ret;
-
- if (!ar->read_global_header) {
- /*
- * We are now at the beginning of the archive,
- * so we need first consume the ar global header.
- */
- __archive_read_consume(a, 8);
- ar->read_global_header = 1;
- /* Set a default format code for now. */
- a->archive.archive_format = ARCHIVE_FORMAT_AR;
- }
-
- /* Read the header for the next file entry. */
- if ((header_data = __archive_read_ahead(a, 60, NULL)) == NULL)
- /* Broken header. */
- return (ARCHIVE_EOF);
-
- unconsumed = 60;
-
- ret = _ar_read_header(a, entry, ar, (const char *)header_data, &unconsumed);
-
- if (unconsumed)
- __archive_read_consume(a, unconsumed);
-
- return ret;
-}
-
-
-static int
-ar_parse_common_header(struct ar *ar, struct archive_entry *entry,
- const char *h)
-{
- uint64_t n;
-
- /* Copy remaining header */
- archive_entry_set_filetype(entry, AE_IFREG);
- archive_entry_set_mtime(entry,
- (time_t)ar_atol10(h + AR_date_offset, AR_date_size), 0L);
- archive_entry_set_uid(entry,
- (uid_t)ar_atol10(h + AR_uid_offset, AR_uid_size));
- archive_entry_set_gid(entry,
- (gid_t)ar_atol10(h + AR_gid_offset, AR_gid_size));
- archive_entry_set_mode(entry,
- (mode_t)ar_atol8(h + AR_mode_offset, AR_mode_size));
- n = ar_atol10(h + AR_size_offset, AR_size_size);
-
- ar->entry_offset = 0;
- ar->entry_padding = n % 2;
- archive_entry_set_size(entry, n);
- ar->entry_bytes_remaining = n;
- return (ARCHIVE_OK);
-}
-
-static int
-archive_read_format_ar_read_data(struct archive_read *a,
- const void **buff, size_t *size, int64_t *offset)
-{
- ssize_t bytes_read;
- struct ar *ar;
-
- ar = (struct ar *)(a->format->data);
-
- if (ar->entry_bytes_unconsumed) {
- __archive_read_consume(a, ar->entry_bytes_unconsumed);
- ar->entry_bytes_unconsumed = 0;
- }
-
- if (ar->entry_bytes_remaining > 0) {
- *buff = __archive_read_ahead(a, 1, &bytes_read);
- if (bytes_read == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Truncated ar archive");
- return (ARCHIVE_FATAL);
- }
- if (bytes_read < 0)
- return (ARCHIVE_FATAL);
- if (bytes_read > ar->entry_bytes_remaining)
- bytes_read = (ssize_t)ar->entry_bytes_remaining;
- *size = bytes_read;
- ar->entry_bytes_unconsumed = bytes_read;
- *offset = ar->entry_offset;
- ar->entry_offset += bytes_read;
- ar->entry_bytes_remaining -= bytes_read;
- return (ARCHIVE_OK);
- } else {
- int64_t skipped = __archive_read_consume(a, ar->entry_padding);
- if (skipped >= 0) {
- ar->entry_padding -= skipped;
- }
- if (ar->entry_padding) {
- if (skipped >= 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Truncated ar archive- failed consuming padding");
- }
- return (ARCHIVE_FATAL);
- }
- *buff = NULL;
- *size = 0;
- *offset = ar->entry_offset;
- return (ARCHIVE_EOF);
- }
-}
-
-static int
-archive_read_format_ar_skip(struct archive_read *a)
-{
- int64_t bytes_skipped;
- struct ar* ar;
-
- ar = (struct ar *)(a->format->data);
-
- bytes_skipped = __archive_read_consume(a,
- ar->entry_bytes_remaining + ar->entry_padding
- + ar->entry_bytes_unconsumed);
- if (bytes_skipped < 0)
- return (ARCHIVE_FATAL);
-
- ar->entry_bytes_remaining = 0;
- ar->entry_bytes_unconsumed = 0;
- ar->entry_padding = 0;
-
- return (ARCHIVE_OK);
-}
-
-static int
-ar_parse_gnu_filename_table(struct archive_read *a)
-{
- struct ar *ar;
- char *p;
- size_t size;
-
- ar = (struct ar*)(a->format->data);
- size = ar->strtab_size;
-
- for (p = ar->strtab; p < ar->strtab + size - 1; ++p) {
- if (*p == '/') {
- *p++ = '\0';
- if (*p != '\n')
- goto bad_string_table;
- *p = '\0';
- }
- }
- /*
- * GNU ar always pads the table to an even size.
- * The pad character is either '\n' or '`'.
- */
- if (p != ar->strtab + size && *p != '\n' && *p != '`')
- goto bad_string_table;
-
- /* Enforce zero termination. */
- ar->strtab[size - 1] = '\0';
-
- return (ARCHIVE_OK);
-
-bad_string_table:
- archive_set_error(&a->archive, EINVAL,
- "Invalid string table");
- free(ar->strtab);
- ar->strtab = NULL;
- return (ARCHIVE_FATAL);
-}
-
-static uint64_t
-ar_atol8(const char *p, unsigned char_cnt)
-{
- uint64_t l, limit, last_digit_limit;
- unsigned int digit, base;
-
- base = 8;
- limit = UINT64_MAX / base;
- last_digit_limit = UINT64_MAX % base;
-
- while ((*p == ' ' || *p == '\t') && char_cnt-- > 0)
- p++;
-
- l = 0;
- digit = *p - '0';
- while (*p >= '0' && digit < base && char_cnt-- > 0) {
- if (l>limit || (l == limit && digit > last_digit_limit)) {
- l = UINT64_MAX; /* Truncate on overflow. */
- break;
- }
- l = (l * base) + digit;
- digit = *++p - '0';
- }
- return (l);
-}
-
-static uint64_t
-ar_atol10(const char *p, unsigned char_cnt)
-{
- uint64_t l, limit, last_digit_limit;
- unsigned int base, digit;
-
- base = 10;
- limit = UINT64_MAX / base;
- last_digit_limit = UINT64_MAX % base;
-
- while ((*p == ' ' || *p == '\t') && char_cnt-- > 0)
- p++;
- l = 0;
- digit = *p - '0';
- while (*p >= '0' && digit < base && char_cnt-- > 0) {
- if (l > limit || (l == limit && digit > last_digit_limit)) {
- l = UINT64_MAX; /* Truncate on overflow. */
- break;
- }
- l = (l * base) + digit;
- digit = *++p - '0';
- }
- return (l);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_format_by_code.c b/contrib/libs/libarchive/libarchive/archive_read_support_format_by_code.c
deleted file mode 100644
index 89e96f1f59..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_format_by_code.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*-
- * Copyright (c) 2003-2011 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-
-int
-archive_read_support_format_by_code(struct archive *a, int format_code)
-{
- archive_check_magic(a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_format_by_code");
-
- switch (format_code & ARCHIVE_FORMAT_BASE_MASK) {
- case ARCHIVE_FORMAT_7ZIP:
- return archive_read_support_format_7zip(a);
- break;
- case ARCHIVE_FORMAT_AR:
- return archive_read_support_format_ar(a);
- break;
- case ARCHIVE_FORMAT_CAB:
- return archive_read_support_format_cab(a);
- break;
- case ARCHIVE_FORMAT_CPIO:
- return archive_read_support_format_cpio(a);
- break;
- case ARCHIVE_FORMAT_EMPTY:
- return archive_read_support_format_empty(a);
- break;
- case ARCHIVE_FORMAT_ISO9660:
- return archive_read_support_format_iso9660(a);
- break;
- case ARCHIVE_FORMAT_LHA:
- return archive_read_support_format_lha(a);
- break;
- case ARCHIVE_FORMAT_MTREE:
- return archive_read_support_format_mtree(a);
- break;
- case ARCHIVE_FORMAT_RAR:
- return archive_read_support_format_rar(a);
- break;
- case ARCHIVE_FORMAT_RAR_V5:
- return archive_read_support_format_rar5(a);
- break;
- case ARCHIVE_FORMAT_RAW:
- return archive_read_support_format_raw(a);
- break;
- case ARCHIVE_FORMAT_TAR:
- return archive_read_support_format_tar(a);
- break;
- case ARCHIVE_FORMAT_WARC:
- return archive_read_support_format_warc(a);
- break;
- case ARCHIVE_FORMAT_XAR:
- return archive_read_support_format_xar(a);
- break;
- case ARCHIVE_FORMAT_ZIP:
- return archive_read_support_format_zip(a);
- break;
- }
- archive_set_error(a, ARCHIVE_ERRNO_PROGRAMMER,
- "Invalid format code specified");
- return (ARCHIVE_FATAL);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_format_cab.c b/contrib/libs/libarchive/libarchive/archive_read_support_format_cab.c
deleted file mode 100644
index 3b552a84de..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_format_cab.c
+++ /dev/null
@@ -1,3228 +0,0 @@
-/*-
- * Copyright (c) 2010-2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-#include "archive_endian.h"
-
-
-struct lzx_dec {
- /* Decoding status. */
- int state;
-
- /*
- * Window to see last decoded data, from 32KBi to 2MBi.
- */
- int w_size;
- int w_mask;
- /* Window buffer, which is a loop buffer. */
- unsigned char *w_buff;
- /* The insert position to the window. */
- int w_pos;
- /* The position where we can copy decoded code from the window. */
- int copy_pos;
- /* The length how many bytes we can copy decoded code from
- * the window. */
- int copy_len;
- /* Translation reversal for x86 processor CALL byte sequence(E8).
- * This is used for LZX only. */
- uint32_t translation_size;
- char translation;
- char block_type;
-#define VERBATIM_BLOCK 1
-#define ALIGNED_OFFSET_BLOCK 2
-#define UNCOMPRESSED_BLOCK 3
- size_t block_size;
- size_t block_bytes_avail;
- /* Repeated offset. */
- int r0, r1, r2;
- unsigned char rbytes[4];
- int rbytes_avail;
- int length_header;
- int position_slot;
- int offset_bits;
-
- struct lzx_pos_tbl {
- int base;
- int footer_bits;
- } *pos_tbl;
- /*
- * Bit stream reader.
- */
- struct lzx_br {
-#define CACHE_TYPE uint64_t
-#define CACHE_BITS (8 * sizeof(CACHE_TYPE))
- /* Cache buffer. */
- CACHE_TYPE cache_buffer;
- /* Indicates how many bits avail in cache_buffer. */
- int cache_avail;
- unsigned char odd;
- char have_odd;
- } br;
-
- /*
- * Huffman coding.
- */
- struct huffman {
- int len_size;
- int freq[17];
- unsigned char *bitlen;
-
- /*
- * Use a index table. It's faster than searching a huffman
- * coding tree, which is a binary tree. But a use of a large
- * index table causes L1 cache read miss many times.
- */
- int max_bits;
- int tbl_bits;
- int tree_used;
- /* Direct access table. */
- uint16_t *tbl;
- } at, lt, mt, pt;
-
- int loop;
- int error;
-};
-
-static const int slots[] = {
- 30, 32, 34, 36, 38, 42, 50, 66, 98, 162, 290
-};
-#define SLOT_BASE 15
-#define SLOT_MAX 21/*->25*/
-
-struct lzx_stream {
- const unsigned char *next_in;
- int64_t avail_in;
- int64_t total_in;
- unsigned char *next_out;
- int64_t avail_out;
- int64_t total_out;
- struct lzx_dec *ds;
-};
-
-/*
- * Cabinet file definitions.
- */
-/* CFHEADER offset */
-#define CFHEADER_signature 0
-#define CFHEADER_cbCabinet 8
-#define CFHEADER_coffFiles 16
-#define CFHEADER_versionMinor 24
-#define CFHEADER_versionMajor 25
-#define CFHEADER_cFolders 26
-#define CFHEADER_cFiles 28
-#define CFHEADER_flags 30
-#define CFHEADER_setID 32
-#define CFHEADER_iCabinet 34
-#define CFHEADER_cbCFHeader 36
-#define CFHEADER_cbCFFolder 38
-#define CFHEADER_cbCFData 39
-
-/* CFFOLDER offset */
-#define CFFOLDER_coffCabStart 0
-#define CFFOLDER_cCFData 4
-#define CFFOLDER_typeCompress 6
-#define CFFOLDER_abReserve 8
-
-/* CFFILE offset */
-#define CFFILE_cbFile 0
-#define CFFILE_uoffFolderStart 4
-#define CFFILE_iFolder 8
-#define CFFILE_date_time 10
-#define CFFILE_attribs 14
-
-/* CFDATA offset */
-#define CFDATA_csum 0
-#define CFDATA_cbData 4
-#define CFDATA_cbUncomp 6
-
-static const char * const compression_name[] = {
- "NONE",
- "MSZIP",
- "Quantum",
- "LZX",
-};
-
-struct cfdata {
- /* Sum value of this CFDATA. */
- uint32_t sum;
- uint16_t compressed_size;
- uint16_t compressed_bytes_remaining;
- uint16_t uncompressed_size;
- uint16_t uncompressed_bytes_remaining;
- /* To know how many bytes we have decompressed. */
- uint16_t uncompressed_avail;
- /* Offset from the beginning of compressed data of this CFDATA */
- uint16_t read_offset;
- int64_t unconsumed;
- /* To keep memory image of this CFDATA to compute the sum. */
- size_t memimage_size;
- unsigned char *memimage;
- /* Result of calculation of sum. */
- uint32_t sum_calculated;
- unsigned char sum_extra[4];
- int sum_extra_avail;
- const void *sum_ptr;
-};
-
-struct cffolder {
- uint32_t cfdata_offset_in_cab;
- uint16_t cfdata_count;
- uint16_t comptype;
-#define COMPTYPE_NONE 0x0000
-#define COMPTYPE_MSZIP 0x0001
-#define COMPTYPE_QUANTUM 0x0002
-#define COMPTYPE_LZX 0x0003
- uint16_t compdata;
- const char *compname;
- /* At the time reading CFDATA */
- struct cfdata cfdata;
- int cfdata_index;
- /* Flags to mark progress of decompression. */
- char decompress_init;
-};
-
-struct cffile {
- uint32_t uncompressed_size;
- uint32_t offset;
- time_t mtime;
- uint16_t folder;
-#define iFoldCONTINUED_FROM_PREV 0xFFFD
-#define iFoldCONTINUED_TO_NEXT 0xFFFE
-#define iFoldCONTINUED_PREV_AND_NEXT 0xFFFF
- unsigned char attr;
-#define ATTR_RDONLY 0x01
-#define ATTR_NAME_IS_UTF 0x80
- struct archive_string pathname;
-};
-
-struct cfheader {
- /* Total bytes of all file size in a Cabinet. */
- uint32_t total_bytes;
- uint32_t files_offset;
- uint16_t folder_count;
- uint16_t file_count;
- uint16_t flags;
-#define PREV_CABINET 0x0001
-#define NEXT_CABINET 0x0002
-#define RESERVE_PRESENT 0x0004
- uint16_t setid;
- uint16_t cabinet;
- /* Version number. */
- unsigned char major;
- unsigned char minor;
- unsigned char cffolder;
- unsigned char cfdata;
- /* All folders in a cabinet. */
- struct cffolder *folder_array;
- /* All files in a cabinet. */
- struct cffile *file_array;
- int file_index;
-};
-
-struct cab {
- /* entry_bytes_remaining is the number of bytes we expect. */
- int64_t entry_offset;
- int64_t entry_bytes_remaining;
- int64_t entry_unconsumed;
- int64_t entry_compressed_bytes_read;
- int64_t entry_uncompressed_bytes_read;
- struct cffolder *entry_cffolder;
- struct cffile *entry_cffile;
- struct cfdata *entry_cfdata;
-
- /* Offset from beginning of a cabinet file. */
- int64_t cab_offset;
- struct cfheader cfheader;
- struct archive_wstring ws;
-
- /* Flag to mark progress that an archive was read their first header.*/
- char found_header;
- char end_of_archive;
- char end_of_entry;
- char end_of_entry_cleanup;
- char read_data_invoked;
- int64_t bytes_skipped;
-
- unsigned char *uncompressed_buffer;
- size_t uncompressed_buffer_size;
-
- int init_default_conversion;
- struct archive_string_conv *sconv;
- struct archive_string_conv *sconv_default;
- struct archive_string_conv *sconv_utf8;
- char format_name[64];
-
-#ifdef HAVE_ZLIB_H
- z_stream stream;
- char stream_valid;
-#endif
- struct lzx_stream xstrm;
-};
-
-static int archive_read_format_cab_bid(struct archive_read *, int);
-static int archive_read_format_cab_options(struct archive_read *,
- const char *, const char *);
-static int archive_read_format_cab_read_header(struct archive_read *,
- struct archive_entry *);
-static int archive_read_format_cab_read_data(struct archive_read *,
- const void **, size_t *, int64_t *);
-static int archive_read_format_cab_read_data_skip(struct archive_read *);
-static int archive_read_format_cab_cleanup(struct archive_read *);
-
-static int cab_skip_sfx(struct archive_read *);
-static time_t cab_dos_time(const unsigned char *);
-static int cab_read_data(struct archive_read *, const void **,
- size_t *, int64_t *);
-static int cab_read_header(struct archive_read *);
-static uint32_t cab_checksum_cfdata_4(const void *, size_t bytes, uint32_t);
-static uint32_t cab_checksum_cfdata(const void *, size_t bytes, uint32_t);
-static void cab_checksum_update(struct archive_read *, size_t);
-static int cab_checksum_finish(struct archive_read *);
-static int cab_next_cfdata(struct archive_read *);
-static const void *cab_read_ahead_cfdata(struct archive_read *, ssize_t *);
-static const void *cab_read_ahead_cfdata_none(struct archive_read *, ssize_t *);
-static const void *cab_read_ahead_cfdata_deflate(struct archive_read *,
- ssize_t *);
-static const void *cab_read_ahead_cfdata_lzx(struct archive_read *,
- ssize_t *);
-static int64_t cab_consume_cfdata(struct archive_read *, int64_t);
-static int64_t cab_minimum_consume_cfdata(struct archive_read *, int64_t);
-static int lzx_decode_init(struct lzx_stream *, int);
-static int lzx_read_blocks(struct lzx_stream *, int);
-static int lzx_decode_blocks(struct lzx_stream *, int);
-static void lzx_decode_free(struct lzx_stream *);
-static void lzx_translation(struct lzx_stream *, void *, size_t, uint32_t);
-static void lzx_cleanup_bitstream(struct lzx_stream *);
-static int lzx_decode(struct lzx_stream *, int);
-static int lzx_read_pre_tree(struct lzx_stream *);
-static int lzx_read_bitlen(struct lzx_stream *, struct huffman *, int);
-static int lzx_huffman_init(struct huffman *, size_t, int);
-static void lzx_huffman_free(struct huffman *);
-static int lzx_make_huffman_table(struct huffman *);
-static inline int lzx_decode_huffman(struct huffman *, unsigned);
-
-
-int
-archive_read_support_format_cab(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- struct cab *cab;
- int r;
-
- archive_check_magic(_a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_format_cab");
-
- cab = (struct cab *)calloc(1, sizeof(*cab));
- if (cab == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate CAB data");
- return (ARCHIVE_FATAL);
- }
- archive_string_init(&cab->ws);
- archive_wstring_ensure(&cab->ws, 256);
-
- r = __archive_read_register_format(a,
- cab,
- "cab",
- archive_read_format_cab_bid,
- archive_read_format_cab_options,
- archive_read_format_cab_read_header,
- archive_read_format_cab_read_data,
- archive_read_format_cab_read_data_skip,
- NULL,
- archive_read_format_cab_cleanup,
- NULL,
- NULL);
-
- if (r != ARCHIVE_OK)
- free(cab);
- return (ARCHIVE_OK);
-}
-
-static int
-find_cab_magic(const char *p)
-{
- switch (p[4]) {
- case 0:
- /*
- * Note: Self-Extraction program has 'MSCF' string in their
- * program. If we were finding 'MSCF' string only, we got
- * wrong place for Cabinet header, thus, we have to check
- * following four bytes which are reserved and must be set
- * to zero.
- */
- if (memcmp(p, "MSCF\0\0\0\0", 8) == 0)
- return 0;
- return 5;
- case 'F': return 1;
- case 'C': return 2;
- case 'S': return 3;
- case 'M': return 4;
- default: return 5;
- }
-}
-
-static int
-archive_read_format_cab_bid(struct archive_read *a, int best_bid)
-{
- const char *p;
- ssize_t bytes_avail, offset, window;
-
- /* If there's already a better bid than we can ever
- make, don't bother testing. */
- if (best_bid > 64)
- return (-1);
-
- if ((p = __archive_read_ahead(a, 8, NULL)) == NULL)
- return (-1);
-
- if (memcmp(p, "MSCF\0\0\0\0", 8) == 0)
- return (64);
-
- /*
- * Attempt to handle self-extracting archives
- * by noting a PE header and searching forward
- * up to 128k for a 'MSCF' marker.
- */
- if (p[0] == 'M' && p[1] == 'Z') {
- offset = 0;
- window = 4096;
- while (offset < (1024 * 128)) {
- const char *h = __archive_read_ahead(a, offset + window,
- &bytes_avail);
- if (h == NULL) {
- /* Remaining bytes are less than window. */
- window >>= 1;
- if (window < 128)
- return (0);
- continue;
- }
- p = h + offset;
- while (p + 8 < h + bytes_avail) {
- int next;
- if ((next = find_cab_magic(p)) == 0)
- return (64);
- p += next;
- }
- offset = p - h;
- }
- }
- return (0);
-}
-
-static int
-archive_read_format_cab_options(struct archive_read *a,
- const char *key, const char *val)
-{
- struct cab *cab;
- int ret = ARCHIVE_FAILED;
-
- cab = (struct cab *)(a->format->data);
- if (strcmp(key, "hdrcharset") == 0) {
- if (val == NULL || val[0] == 0)
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "cab: hdrcharset option needs a character-set name");
- else {
- cab->sconv = archive_string_conversion_from_charset(
- &a->archive, val, 0);
- if (cab->sconv != NULL)
- ret = ARCHIVE_OK;
- else
- ret = ARCHIVE_FATAL;
- }
- return (ret);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-static int
-cab_skip_sfx(struct archive_read *a)
-{
- const char *p, *q;
- size_t skip;
- ssize_t bytes, window;
-
- window = 4096;
- for (;;) {
- const char *h = __archive_read_ahead(a, window, &bytes);
- if (h == NULL) {
- /* Remaining size are less than window. */
- window >>= 1;
- if (window < 128) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Couldn't find out CAB header");
- return (ARCHIVE_FATAL);
- }
- continue;
- }
- p = h;
- q = p + bytes;
-
- /*
- * Scan ahead until we find something that looks
- * like the cab header.
- */
- while (p + 8 < q) {
- int next;
- if ((next = find_cab_magic(p)) == 0) {
- skip = p - h;
- __archive_read_consume(a, skip);
- return (ARCHIVE_OK);
- }
- p += next;
- }
- skip = p - h;
- __archive_read_consume(a, skip);
- }
-}
-
-static int
-truncated_error(struct archive_read *a)
-{
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated CAB header");
- return (ARCHIVE_FATAL);
-}
-
-static ssize_t
-cab_strnlen(const unsigned char *p, size_t maxlen)
-{
- size_t i;
-
- for (i = 0; i <= maxlen; i++) {
- if (p[i] == 0)
- break;
- }
- if (i > maxlen)
- return (-1);/* invalid */
- return ((ssize_t)i);
-}
-
-/* Read bytes as much as remaining. */
-static const void *
-cab_read_ahead_remaining(struct archive_read *a, size_t min, ssize_t *avail)
-{
- const void *p;
-
- while (min > 0) {
- p = __archive_read_ahead(a, min, avail);
- if (p != NULL)
- return (p);
- min--;
- }
- return (NULL);
-}
-
-/* Convert a path separator '\' -> '/' */
-static int
-cab_convert_path_separator_1(struct archive_string *fn, unsigned char attr)
-{
- size_t i;
- int mb;
-
- /* Easy check if we have '\' in multi-byte string. */
- mb = 0;
- for (i = 0; i < archive_strlen(fn); i++) {
- if (fn->s[i] == '\\') {
- if (mb) {
- /* This may be second byte of multi-byte
- * character. */
- break;
- }
- fn->s[i] = '/';
- mb = 0;
- } else if ((fn->s[i] & 0x80) && !(attr & ATTR_NAME_IS_UTF))
- mb = 1;
- else
- mb = 0;
- }
- if (i == archive_strlen(fn))
- return (0);
- return (-1);
-}
-
-/*
- * Replace a character '\' with '/' in wide character.
- */
-static void
-cab_convert_path_separator_2(struct cab *cab, struct archive_entry *entry)
-{
- const wchar_t *wp;
- size_t i;
-
- /* If a conversion to wide character failed, force the replacement. */
- if ((wp = archive_entry_pathname_w(entry)) != NULL) {
- archive_wstrcpy(&(cab->ws), wp);
- for (i = 0; i < archive_strlen(&(cab->ws)); i++) {
- if (cab->ws.s[i] == L'\\')
- cab->ws.s[i] = L'/';
- }
- archive_entry_copy_pathname_w(entry, cab->ws.s);
- }
-}
-
-/*
- * Read CFHEADER, CFFOLDER and CFFILE.
- */
-static int
-cab_read_header(struct archive_read *a)
-{
- const unsigned char *p;
- struct cab *cab;
- struct cfheader *hd;
- size_t bytes, used;
- ssize_t len;
- int64_t skip;
- int err, i;
- int cur_folder, prev_folder;
- uint32_t offset32;
-
- a->archive.archive_format = ARCHIVE_FORMAT_CAB;
- if (a->archive.archive_format_name == NULL)
- a->archive.archive_format_name = "CAB";
-
- if ((p = __archive_read_ahead(a, 42, NULL)) == NULL)
- return (truncated_error(a));
-
- cab = (struct cab *)(a->format->data);
- if (cab->found_header == 0 &&
- p[0] == 'M' && p[1] == 'Z') {
- /* This is an executable? Must be self-extracting... */
- err = cab_skip_sfx(a);
- if (err < ARCHIVE_WARN)
- return (err);
-
- /* Re-read header after processing the SFX. */
- if ((p = __archive_read_ahead(a, 42, NULL)) == NULL)
- return (truncated_error(a));
- }
-
- cab->cab_offset = 0;
- /*
- * Read CFHEADER.
- */
- hd = &cab->cfheader;
- if (p[CFHEADER_signature+0] != 'M' || p[CFHEADER_signature+1] != 'S' ||
- p[CFHEADER_signature+2] != 'C' || p[CFHEADER_signature+3] != 'F') {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Couldn't find out CAB header");
- return (ARCHIVE_FATAL);
- }
- hd->total_bytes = archive_le32dec(p + CFHEADER_cbCabinet);
- hd->files_offset = archive_le32dec(p + CFHEADER_coffFiles);
- hd->minor = p[CFHEADER_versionMinor];
- hd->major = p[CFHEADER_versionMajor];
- hd->folder_count = archive_le16dec(p + CFHEADER_cFolders);
- if (hd->folder_count == 0)
- goto invalid;
- hd->file_count = archive_le16dec(p + CFHEADER_cFiles);
- if (hd->file_count == 0)
- goto invalid;
- hd->flags = archive_le16dec(p + CFHEADER_flags);
- hd->setid = archive_le16dec(p + CFHEADER_setID);
- hd->cabinet = archive_le16dec(p + CFHEADER_iCabinet);
- used = CFHEADER_iCabinet + 2;
- if (hd->flags & RESERVE_PRESENT) {
- uint16_t cfheader;
- cfheader = archive_le16dec(p + CFHEADER_cbCFHeader);
- if (cfheader > 60000U)
- goto invalid;
- hd->cffolder = p[CFHEADER_cbCFFolder];
- hd->cfdata = p[CFHEADER_cbCFData];
- used += 4;/* cbCFHeader, cbCFFolder and cbCFData */
- used += cfheader;/* abReserve */
- } else
- hd->cffolder = 0;/* Avoid compiling warning. */
- if (hd->flags & PREV_CABINET) {
- /* How many bytes are used for szCabinetPrev. */
- if ((p = __archive_read_ahead(a, used+256, NULL)) == NULL)
- return (truncated_error(a));
- if ((len = cab_strnlen(p + used, 255)) <= 0)
- goto invalid;
- used += len + 1;
- /* How many bytes are used for szDiskPrev. */
- if ((p = __archive_read_ahead(a, used+256, NULL)) == NULL)
- return (truncated_error(a));
- if ((len = cab_strnlen(p + used, 255)) <= 0)
- goto invalid;
- used += len + 1;
- }
- if (hd->flags & NEXT_CABINET) {
- /* How many bytes are used for szCabinetNext. */
- if ((p = __archive_read_ahead(a, used+256, NULL)) == NULL)
- return (truncated_error(a));
- if ((len = cab_strnlen(p + used, 255)) <= 0)
- goto invalid;
- used += len + 1;
- /* How many bytes are used for szDiskNext. */
- if ((p = __archive_read_ahead(a, used+256, NULL)) == NULL)
- return (truncated_error(a));
- if ((len = cab_strnlen(p + used, 255)) <= 0)
- goto invalid;
- used += len + 1;
- }
- __archive_read_consume(a, used);
- cab->cab_offset += used;
- used = 0;
-
- /*
- * Read CFFOLDER.
- */
- hd->folder_array = (struct cffolder *)calloc(
- hd->folder_count, sizeof(struct cffolder));
- if (hd->folder_array == NULL)
- goto nomem;
-
- bytes = 8;
- if (hd->flags & RESERVE_PRESENT)
- bytes += hd->cffolder;
- bytes *= hd->folder_count;
- if ((p = __archive_read_ahead(a, bytes, NULL)) == NULL)
- return (truncated_error(a));
- offset32 = 0;
- for (i = 0; i < hd->folder_count; i++) {
- struct cffolder *folder = &(hd->folder_array[i]);
- folder->cfdata_offset_in_cab =
- archive_le32dec(p + CFFOLDER_coffCabStart);
- folder->cfdata_count = archive_le16dec(p+CFFOLDER_cCFData);
- folder->comptype =
- archive_le16dec(p+CFFOLDER_typeCompress) & 0x0F;
- folder->compdata =
- archive_le16dec(p+CFFOLDER_typeCompress) >> 8;
- /* Get a compression name. */
- if (folder->comptype <
- sizeof(compression_name) / sizeof(compression_name[0]))
- folder->compname = compression_name[folder->comptype];
- else
- folder->compname = "UNKNOWN";
- p += 8;
- used += 8;
- if (hd->flags & RESERVE_PRESENT) {
- p += hd->cffolder;/* abReserve */
- used += hd->cffolder;
- }
- /*
- * Sanity check if each data is acceptable.
- */
- if (offset32 >= folder->cfdata_offset_in_cab)
- goto invalid;
- offset32 = folder->cfdata_offset_in_cab;
-
- /* Set a request to initialize zlib for the CFDATA of
- * this folder. */
- folder->decompress_init = 0;
- }
- __archive_read_consume(a, used);
- cab->cab_offset += used;
-
- /*
- * Read CFFILE.
- */
- /* Seek read pointer to the offset of CFFILE if needed. */
- skip = (int64_t)hd->files_offset - cab->cab_offset;
- if (skip < 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Invalid offset of CFFILE %jd < %jd",
- (intmax_t)hd->files_offset, (intmax_t)cab->cab_offset);
- return (ARCHIVE_FATAL);
- }
- if (skip) {
- __archive_read_consume(a, skip);
- cab->cab_offset += skip;
- }
- /* Allocate memory for CFDATA */
- hd->file_array = (struct cffile *)calloc(
- hd->file_count, sizeof(struct cffile));
- if (hd->file_array == NULL)
- goto nomem;
-
- prev_folder = -1;
- for (i = 0; i < hd->file_count; i++) {
- struct cffile *file = &(hd->file_array[i]);
- ssize_t avail;
-
- if ((p = __archive_read_ahead(a, 16, NULL)) == NULL)
- return (truncated_error(a));
- file->uncompressed_size = archive_le32dec(p + CFFILE_cbFile);
- file->offset = archive_le32dec(p + CFFILE_uoffFolderStart);
- file->folder = archive_le16dec(p + CFFILE_iFolder);
- file->mtime = cab_dos_time(p + CFFILE_date_time);
- file->attr = (uint8_t)archive_le16dec(p + CFFILE_attribs);
- __archive_read_consume(a, 16);
-
- cab->cab_offset += 16;
- if ((p = cab_read_ahead_remaining(a, 256, &avail)) == NULL)
- return (truncated_error(a));
- if ((len = cab_strnlen(p, avail-1)) <= 0)
- goto invalid;
-
- /* Copy a pathname. */
- archive_string_init(&(file->pathname));
- archive_strncpy(&(file->pathname), p, len);
- __archive_read_consume(a, len + 1);
- cab->cab_offset += len + 1;
-
- /*
- * Sanity check if each data is acceptable.
- */
- if (file->uncompressed_size > 0x7FFF8000)
- goto invalid;/* Too large */
- if ((int64_t)file->offset + (int64_t)file->uncompressed_size
- > ARCHIVE_LITERAL_LL(0x7FFF8000))
- goto invalid;/* Too large */
- switch (file->folder) {
- case iFoldCONTINUED_TO_NEXT:
- /* This must be last file in a folder. */
- if (i != hd->file_count -1)
- goto invalid;
- cur_folder = hd->folder_count -1;
- break;
- case iFoldCONTINUED_PREV_AND_NEXT:
- /* This must be only one file in a folder. */
- if (hd->file_count != 1)
- goto invalid;
- /* FALL THROUGH */
- case iFoldCONTINUED_FROM_PREV:
- /* This must be first file in a folder. */
- if (i != 0)
- goto invalid;
- prev_folder = cur_folder = 0;
- offset32 = file->offset;
- break;
- default:
- if (file->folder >= hd->folder_count)
- goto invalid;
- cur_folder = file->folder;
- break;
- }
- /* Dot not back track. */
- if (cur_folder < prev_folder)
- goto invalid;
- if (cur_folder != prev_folder)
- offset32 = 0;
- prev_folder = cur_folder;
-
- /* Make sure there are not any blanks from last file
- * contents. */
- if (offset32 != file->offset)
- goto invalid;
- offset32 += file->uncompressed_size;
-
- /* CFDATA is available for file contents. */
- if (file->uncompressed_size > 0 &&
- hd->folder_array[cur_folder].cfdata_count == 0)
- goto invalid;
- }
-
- if (hd->cabinet != 0 || hd->flags & (PREV_CABINET | NEXT_CABINET)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Multivolume cabinet file is unsupported");
- return (ARCHIVE_WARN);
- }
- return (ARCHIVE_OK);
-invalid:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid CAB header");
- return (ARCHIVE_FATAL);
-nomem:
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for CAB data");
- return (ARCHIVE_FATAL);
-}
-
-static int
-archive_read_format_cab_read_header(struct archive_read *a,
- struct archive_entry *entry)
-{
- struct cab *cab;
- struct cfheader *hd;
- struct cffolder *prev_folder;
- struct cffile *file;
- struct archive_string_conv *sconv;
- int err = ARCHIVE_OK, r;
-
- cab = (struct cab *)(a->format->data);
- if (cab->found_header == 0) {
- err = cab_read_header(a);
- if (err < ARCHIVE_WARN)
- return (err);
- /* We've found the header. */
- cab->found_header = 1;
- }
- hd = &cab->cfheader;
-
- if (hd->file_index >= hd->file_count) {
- cab->end_of_archive = 1;
- return (ARCHIVE_EOF);
- }
- file = &hd->file_array[hd->file_index++];
-
- cab->end_of_entry = 0;
- cab->end_of_entry_cleanup = 0;
- cab->entry_compressed_bytes_read = 0;
- cab->entry_uncompressed_bytes_read = 0;
- cab->entry_unconsumed = 0;
- cab->entry_cffile = file;
-
- /*
- * Choose a proper folder.
- */
- prev_folder = cab->entry_cffolder;
- switch (file->folder) {
- case iFoldCONTINUED_FROM_PREV:
- case iFoldCONTINUED_PREV_AND_NEXT:
- cab->entry_cffolder = &hd->folder_array[0];
- break;
- case iFoldCONTINUED_TO_NEXT:
- cab->entry_cffolder = &hd->folder_array[hd->folder_count-1];
- break;
- default:
- cab->entry_cffolder = &hd->folder_array[file->folder];
- break;
- }
- /* If a cffolder of this file is changed, reset a cfdata to read
- * file contents from next cfdata. */
- if (prev_folder != cab->entry_cffolder)
- cab->entry_cfdata = NULL;
-
- /* If a pathname is UTF-8, prepare a string conversion object
- * for UTF-8 and use it. */
- if (file->attr & ATTR_NAME_IS_UTF) {
- if (cab->sconv_utf8 == NULL) {
- cab->sconv_utf8 =
- archive_string_conversion_from_charset(
- &(a->archive), "UTF-8", 1);
- if (cab->sconv_utf8 == NULL)
- return (ARCHIVE_FATAL);
- }
- sconv = cab->sconv_utf8;
- } else if (cab->sconv != NULL) {
- /* Choose the conversion specified by the option. */
- sconv = cab->sconv;
- } else {
- /* Choose the default conversion. */
- if (!cab->init_default_conversion) {
- cab->sconv_default =
- archive_string_default_conversion_for_read(
- &(a->archive));
- cab->init_default_conversion = 1;
- }
- sconv = cab->sconv_default;
- }
-
- /*
- * Set a default value and common data
- */
- r = cab_convert_path_separator_1(&(file->pathname), file->attr);
- if (archive_entry_copy_pathname_l(entry, file->pathname.s,
- archive_strlen(&(file->pathname)), sconv) != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Pathname cannot be converted "
- "from %s to current locale.",
- archive_string_conversion_charset_name(sconv));
- err = ARCHIVE_WARN;
- }
- if (r < 0) {
- /* Convert a path separator '\' -> '/' */
- cab_convert_path_separator_2(cab, entry);
- }
-
- archive_entry_set_size(entry, file->uncompressed_size);
- if (file->attr & ATTR_RDONLY)
- archive_entry_set_mode(entry, AE_IFREG | 0555);
- else
- archive_entry_set_mode(entry, AE_IFREG | 0666);
- archive_entry_set_mtime(entry, file->mtime, 0);
-
- cab->entry_bytes_remaining = file->uncompressed_size;
- cab->entry_offset = 0;
- /* We don't need compress data. */
- if (file->uncompressed_size == 0)
- cab->end_of_entry_cleanup = cab->end_of_entry = 1;
-
- /* Set up a more descriptive format name. */
- snprintf(cab->format_name, sizeof(cab->format_name), "CAB %d.%d (%s)",
- hd->major, hd->minor, cab->entry_cffolder->compname);
- a->archive.archive_format_name = cab->format_name;
-
- return (err);
-}
-
-static int
-archive_read_format_cab_read_data(struct archive_read *a,
- const void **buff, size_t *size, int64_t *offset)
-{
- struct cab *cab = (struct cab *)(a->format->data);
- int r;
-
- switch (cab->entry_cffile->folder) {
- case iFoldCONTINUED_FROM_PREV:
- case iFoldCONTINUED_TO_NEXT:
- case iFoldCONTINUED_PREV_AND_NEXT:
- *buff = NULL;
- *size = 0;
- *offset = 0;
- archive_clear_error(&a->archive);
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Cannot restore this file split in multivolume.");
- return (ARCHIVE_FAILED);
- default:
- break;
- }
- if (cab->read_data_invoked == 0) {
- if (cab->bytes_skipped) {
- if (cab->entry_cfdata == NULL) {
- r = cab_next_cfdata(a);
- if (r < 0)
- return (r);
- }
- if (cab_consume_cfdata(a, cab->bytes_skipped) < 0)
- return (ARCHIVE_FATAL);
- cab->bytes_skipped = 0;
- }
- cab->read_data_invoked = 1;
- }
- if (cab->entry_unconsumed) {
- /* Consume as much as the compressor actually used. */
- r = (int)cab_consume_cfdata(a, cab->entry_unconsumed);
- cab->entry_unconsumed = 0;
- if (r < 0)
- return (r);
- }
- if (cab->end_of_archive || cab->end_of_entry) {
- if (!cab->end_of_entry_cleanup) {
- /* End-of-entry cleanup done. */
- cab->end_of_entry_cleanup = 1;
- }
- *offset = cab->entry_offset;
- *size = 0;
- *buff = NULL;
- return (ARCHIVE_EOF);
- }
-
- return (cab_read_data(a, buff, size, offset));
-}
-
-static uint32_t
-cab_checksum_cfdata_4(const void *p, size_t bytes, uint32_t seed)
-{
- const unsigned char *b;
- unsigned u32num;
- uint32_t sum;
-
- u32num = (unsigned)bytes / 4;
- sum = seed;
- b = p;
- for (;u32num > 0; --u32num) {
- sum ^= archive_le32dec(b);
- b += 4;
- }
- return (sum);
-}
-
-static uint32_t
-cab_checksum_cfdata(const void *p, size_t bytes, uint32_t seed)
-{
- const unsigned char *b;
- uint32_t sum;
- uint32_t t;
-
- sum = cab_checksum_cfdata_4(p, bytes, seed);
- b = p;
- b += bytes & ~3;
- t = 0;
- switch (bytes & 3) {
- case 3:
- t |= ((uint32_t)(*b++)) << 16;
- /* FALL THROUGH */
- case 2:
- t |= ((uint32_t)(*b++)) << 8;
- /* FALL THROUGH */
- case 1:
- t |= *b;
- /* FALL THROUGH */
- default:
- break;
- }
- sum ^= t;
-
- return (sum);
-}
-
-static void
-cab_checksum_update(struct archive_read *a, size_t bytes)
-{
- struct cab *cab = (struct cab *)(a->format->data);
- struct cfdata *cfdata = cab->entry_cfdata;
- const unsigned char *p;
- size_t sumbytes;
-
- if (cfdata->sum == 0 || cfdata->sum_ptr == NULL)
- return;
- /*
- * Calculate the sum of this CFDATA.
- * Make sure CFDATA must be calculated in four bytes.
- */
- p = cfdata->sum_ptr;
- sumbytes = bytes;
- if (cfdata->sum_extra_avail) {
- while (cfdata->sum_extra_avail < 4 && sumbytes > 0) {
- cfdata->sum_extra[
- cfdata->sum_extra_avail++] = *p++;
- sumbytes--;
- }
- if (cfdata->sum_extra_avail == 4) {
- cfdata->sum_calculated = cab_checksum_cfdata_4(
- cfdata->sum_extra, 4, cfdata->sum_calculated);
- cfdata->sum_extra_avail = 0;
- }
- }
- if (sumbytes) {
- int odd = sumbytes & 3;
- if ((int)(sumbytes - odd) > 0)
- cfdata->sum_calculated = cab_checksum_cfdata_4(
- p, sumbytes - odd, cfdata->sum_calculated);
- if (odd)
- memcpy(cfdata->sum_extra, p + sumbytes - odd, odd);
- cfdata->sum_extra_avail = odd;
- }
- cfdata->sum_ptr = NULL;
-}
-
-static int
-cab_checksum_finish(struct archive_read *a)
-{
- struct cab *cab = (struct cab *)(a->format->data);
- struct cfdata *cfdata = cab->entry_cfdata;
- int l;
-
- /* Do not need to compute a sum. */
- if (cfdata->sum == 0)
- return (ARCHIVE_OK);
-
- /*
- * Calculate the sum of remaining CFDATA.
- */
- if (cfdata->sum_extra_avail) {
- cfdata->sum_calculated =
- cab_checksum_cfdata(cfdata->sum_extra,
- cfdata->sum_extra_avail, cfdata->sum_calculated);
- cfdata->sum_extra_avail = 0;
- }
-
- l = 4;
- if (cab->cfheader.flags & RESERVE_PRESENT)
- l += cab->cfheader.cfdata;
- cfdata->sum_calculated = cab_checksum_cfdata(
- cfdata->memimage + CFDATA_cbData, l, cfdata->sum_calculated);
- if (cfdata->sum_calculated != cfdata->sum) {
-#ifndef DONT_FAIL_ON_CRC_ERROR
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Checksum error CFDATA[%d] %" PRIx32 ":%" PRIx32 " in %d bytes",
- cab->entry_cffolder->cfdata_index -1,
- cfdata->sum, cfdata->sum_calculated,
- cfdata->compressed_size);
- return (ARCHIVE_FAILED);
-#endif
- }
- return (ARCHIVE_OK);
-}
-
-/*
- * Read CFDATA if needed.
- */
-static int
-cab_next_cfdata(struct archive_read *a)
-{
- struct cab *cab = (struct cab *)(a->format->data);
- struct cfdata *cfdata = cab->entry_cfdata;
-
- /* There are remaining bytes in current CFDATA, use it first. */
- if (cfdata != NULL && cfdata->uncompressed_bytes_remaining > 0)
- return (ARCHIVE_OK);
-
- if (cfdata == NULL) {
- int64_t skip;
-
- cab->entry_cffolder->cfdata_index = 0;
-
- /* Seek read pointer to the offset of CFDATA if needed. */
- skip = cab->entry_cffolder->cfdata_offset_in_cab
- - cab->cab_offset;
- if (skip < 0) {
- int folder_index;
- switch (cab->entry_cffile->folder) {
- case iFoldCONTINUED_FROM_PREV:
- case iFoldCONTINUED_PREV_AND_NEXT:
- folder_index = 0;
- break;
- case iFoldCONTINUED_TO_NEXT:
- folder_index = cab->cfheader.folder_count-1;
- break;
- default:
- folder_index = cab->entry_cffile->folder;
- break;
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Invalid offset of CFDATA in folder(%d) %jd < %jd",
- folder_index,
- (intmax_t)cab->entry_cffolder->cfdata_offset_in_cab,
- (intmax_t)cab->cab_offset);
- return (ARCHIVE_FATAL);
- }
- if (skip > 0) {
- if (__archive_read_consume(a, skip) < 0)
- return (ARCHIVE_FATAL);
- cab->cab_offset =
- cab->entry_cffolder->cfdata_offset_in_cab;
- }
- }
-
- /*
- * Read a CFDATA.
- */
- if (cab->entry_cffolder->cfdata_index <
- cab->entry_cffolder->cfdata_count) {
- const unsigned char *p;
- int l;
-
- cfdata = &(cab->entry_cffolder->cfdata);
- cab->entry_cffolder->cfdata_index++;
- cab->entry_cfdata = cfdata;
- cfdata->sum_calculated = 0;
- cfdata->sum_extra_avail = 0;
- cfdata->sum_ptr = NULL;
- l = 8;
- if (cab->cfheader.flags & RESERVE_PRESENT)
- l += cab->cfheader.cfdata;
- if ((p = __archive_read_ahead(a, l, NULL)) == NULL)
- return (truncated_error(a));
- cfdata->sum = archive_le32dec(p + CFDATA_csum);
- cfdata->compressed_size = archive_le16dec(p + CFDATA_cbData);
- cfdata->compressed_bytes_remaining = cfdata->compressed_size;
- cfdata->uncompressed_size =
- archive_le16dec(p + CFDATA_cbUncomp);
- cfdata->uncompressed_bytes_remaining =
- cfdata->uncompressed_size;
- cfdata->uncompressed_avail = 0;
- cfdata->read_offset = 0;
- cfdata->unconsumed = 0;
-
- /*
- * Sanity check if data size is acceptable.
- */
- if (cfdata->compressed_size == 0 ||
- cfdata->compressed_size > (0x8000+6144))
- goto invalid;
- if (cfdata->uncompressed_size > 0x8000)
- goto invalid;
- if (cfdata->uncompressed_size == 0) {
- switch (cab->entry_cffile->folder) {
- case iFoldCONTINUED_PREV_AND_NEXT:
- case iFoldCONTINUED_TO_NEXT:
- break;
- case iFoldCONTINUED_FROM_PREV:
- default:
- goto invalid;
- }
- }
- /* If CFDATA is not last in a folder, an uncompressed
- * size must be 0x8000(32KBi) */
- if ((cab->entry_cffolder->cfdata_index <
- cab->entry_cffolder->cfdata_count) &&
- cfdata->uncompressed_size != 0x8000)
- goto invalid;
-
- /* A compressed data size and an uncompressed data size must
- * be the same in no compression mode. */
- if (cab->entry_cffolder->comptype == COMPTYPE_NONE &&
- cfdata->compressed_size != cfdata->uncompressed_size)
- goto invalid;
-
- /*
- * Save CFDATA image for sum check.
- */
- if (cfdata->memimage_size < (size_t)l) {
- free(cfdata->memimage);
- cfdata->memimage = malloc(l);
- if (cfdata->memimage == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for CAB data");
- return (ARCHIVE_FATAL);
- }
- cfdata->memimage_size = l;
- }
- memcpy(cfdata->memimage, p, l);
-
- /* Consume bytes as much as we used. */
- __archive_read_consume(a, l);
- cab->cab_offset += l;
- } else if (cab->entry_cffolder->cfdata_count > 0) {
- /* Run out of all CFDATA in a folder. */
- cfdata->compressed_size = 0;
- cfdata->uncompressed_size = 0;
- cfdata->compressed_bytes_remaining = 0;
- cfdata->uncompressed_bytes_remaining = 0;
- } else {
- /* Current folder does not have any CFDATA. */
- cfdata = &(cab->entry_cffolder->cfdata);
- cab->entry_cfdata = cfdata;
- memset(cfdata, 0, sizeof(*cfdata));
- }
- return (ARCHIVE_OK);
-invalid:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid CFDATA");
- return (ARCHIVE_FATAL);
-}
-
-/*
- * Read ahead CFDATA.
- */
-static const void *
-cab_read_ahead_cfdata(struct archive_read *a, ssize_t *avail)
-{
- struct cab *cab = (struct cab *)(a->format->data);
- int err;
-
- err = cab_next_cfdata(a);
- if (err < ARCHIVE_OK) {
- *avail = err;
- return (NULL);
- }
-
- switch (cab->entry_cffolder->comptype) {
- case COMPTYPE_NONE:
- return (cab_read_ahead_cfdata_none(a, avail));
- case COMPTYPE_MSZIP:
- return (cab_read_ahead_cfdata_deflate(a, avail));
- case COMPTYPE_LZX:
- return (cab_read_ahead_cfdata_lzx(a, avail));
- default: /* Unsupported compression. */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unsupported CAB compression : %s",
- cab->entry_cffolder->compname);
- *avail = ARCHIVE_FAILED;
- return (NULL);
- }
-}
-
-/*
- * Read ahead CFDATA as uncompressed data.
- */
-static const void *
-cab_read_ahead_cfdata_none(struct archive_read *a, ssize_t *avail)
-{
- struct cab *cab = (struct cab *)(a->format->data);
- struct cfdata *cfdata;
- const void *d;
-
- cfdata = cab->entry_cfdata;
-
- /*
- * Note: '1' here is a performance optimization.
- * Recall that the decompression layer returns a count of
- * available bytes; asking for more than that forces the
- * decompressor to combine reads by copying data.
- */
- d = __archive_read_ahead(a, 1, avail);
- if (*avail <= 0) {
- *avail = truncated_error(a);
- return (NULL);
- }
- if (*avail > cfdata->uncompressed_bytes_remaining)
- *avail = cfdata->uncompressed_bytes_remaining;
- cfdata->uncompressed_avail = cfdata->uncompressed_size;
- cfdata->unconsumed = *avail;
- cfdata->sum_ptr = d;
- return (d);
-}
-
-/*
- * Read ahead CFDATA as deflate data.
- */
-#ifdef HAVE_ZLIB_H
-static const void *
-cab_read_ahead_cfdata_deflate(struct archive_read *a, ssize_t *avail)
-{
- struct cab *cab = (struct cab *)(a->format->data);
- struct cfdata *cfdata;
- const void *d;
- int r, mszip;
- uint16_t uavail;
- char eod = 0;
-
- cfdata = cab->entry_cfdata;
- /* If the buffer hasn't been allocated, allocate it now. */
- if (cab->uncompressed_buffer == NULL) {
- cab->uncompressed_buffer_size = 0x8000;
- cab->uncompressed_buffer
- = (unsigned char *)malloc(cab->uncompressed_buffer_size);
- if (cab->uncompressed_buffer == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for CAB reader");
- *avail = ARCHIVE_FATAL;
- return (NULL);
- }
- }
-
- uavail = cfdata->uncompressed_avail;
- if (uavail == cfdata->uncompressed_size) {
- d = cab->uncompressed_buffer + cfdata->read_offset;
- *avail = uavail - cfdata->read_offset;
- return (d);
- }
-
- if (!cab->entry_cffolder->decompress_init) {
- cab->stream.next_in = NULL;
- cab->stream.avail_in = 0;
- cab->stream.total_in = 0;
- cab->stream.next_out = NULL;
- cab->stream.avail_out = 0;
- cab->stream.total_out = 0;
- if (cab->stream_valid)
- r = inflateReset(&cab->stream);
- else
- r = inflateInit2(&cab->stream,
- -15 /* Don't check for zlib header */);
- if (r != Z_OK) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Can't initialize deflate decompression.");
- *avail = ARCHIVE_FATAL;
- return (NULL);
- }
- /* Stream structure has been set up. */
- cab->stream_valid = 1;
- /* We've initialized decompression for this stream. */
- cab->entry_cffolder->decompress_init = 1;
- }
-
- if (cfdata->compressed_bytes_remaining == cfdata->compressed_size)
- mszip = 2;
- else
- mszip = 0;
- eod = 0;
- cab->stream.total_out = uavail;
- /*
- * We always uncompress all data in current CFDATA.
- */
- while (!eod && cab->stream.total_out < cfdata->uncompressed_size) {
- ssize_t bytes_avail;
-
- cab->stream.next_out =
- cab->uncompressed_buffer + cab->stream.total_out;
- cab->stream.avail_out =
- cfdata->uncompressed_size - cab->stream.total_out;
-
- d = __archive_read_ahead(a, 1, &bytes_avail);
- if (bytes_avail <= 0) {
- *avail = truncated_error(a);
- return (NULL);
- }
- if (bytes_avail > cfdata->compressed_bytes_remaining)
- bytes_avail = cfdata->compressed_bytes_remaining;
- /*
- * A bug in zlib.h: stream.next_in should be marked 'const'
- * but isn't (the library never alters data through the
- * next_in pointer, only reads it). The result: this ugly
- * cast to remove 'const'.
- */
- cab->stream.next_in = (Bytef *)(uintptr_t)d;
- cab->stream.avail_in = (uInt)bytes_avail;
- cab->stream.total_in = 0;
-
- /* Cut out a tow-byte MSZIP signature(0x43, 0x4b). */
- if (mszip > 0) {
- if (bytes_avail <= 0)
- goto nomszip;
- if (bytes_avail <= mszip) {
- if (mszip == 2) {
- if (cab->stream.next_in[0] != 0x43)
- goto nomszip;
- if (bytes_avail > 1 &&
- cab->stream.next_in[1] != 0x4b)
- goto nomszip;
- } else if (cab->stream.next_in[0] != 0x4b)
- goto nomszip;
- cfdata->unconsumed = bytes_avail;
- cfdata->sum_ptr = d;
- if (cab_minimum_consume_cfdata(
- a, cfdata->unconsumed) < 0) {
- *avail = ARCHIVE_FATAL;
- return (NULL);
- }
- mszip -= (int)bytes_avail;
- continue;
- }
- if (mszip == 1 && cab->stream.next_in[0] != 0x4b)
- goto nomszip;
- else if (mszip == 2 && (cab->stream.next_in[0] != 0x43 ||
- cab->stream.next_in[1] != 0x4b))
- goto nomszip;
- cab->stream.next_in += mszip;
- cab->stream.avail_in -= mszip;
- cab->stream.total_in += mszip;
- mszip = 0;
- }
-
- r = inflate(&cab->stream, 0);
- switch (r) {
- case Z_OK:
- break;
- case Z_STREAM_END:
- eod = 1;
- break;
- default:
- goto zlibfailed;
- }
- cfdata->unconsumed = cab->stream.total_in;
- cfdata->sum_ptr = d;
- if (cab_minimum_consume_cfdata(a, cfdata->unconsumed) < 0) {
- *avail = ARCHIVE_FATAL;
- return (NULL);
- }
- }
- uavail = (uint16_t)cab->stream.total_out;
-
- if (uavail < cfdata->uncompressed_size) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Invalid uncompressed size (%d < %d)",
- uavail, cfdata->uncompressed_size);
- *avail = ARCHIVE_FATAL;
- return (NULL);
- }
-
- /*
- * Note: I suspect there is a bug in makecab.exe because, in rare
- * case, compressed bytes are still remaining regardless we have
- * gotten all uncompressed bytes, which size is recorded in CFDATA,
- * as much as we need, and we have to use the garbage so as to
- * correctly compute the sum of CFDATA accordingly.
- */
- if (cfdata->compressed_bytes_remaining > 0) {
- ssize_t bytes_avail;
-
- d = __archive_read_ahead(a, cfdata->compressed_bytes_remaining,
- &bytes_avail);
- if (bytes_avail <= 0) {
- *avail = truncated_error(a);
- return (NULL);
- }
- cfdata->unconsumed = cfdata->compressed_bytes_remaining;
- cfdata->sum_ptr = d;
- if (cab_minimum_consume_cfdata(a, cfdata->unconsumed) < 0) {
- *avail = ARCHIVE_FATAL;
- return (NULL);
- }
- }
-
- /*
- * Set dictionary data for decompressing of next CFDATA, which
- * in the same folder. This is why we always do decompress CFDATA
- * even if beginning CFDATA or some of CFDATA are not used in
- * skipping file data.
- */
- if (cab->entry_cffolder->cfdata_index <
- cab->entry_cffolder->cfdata_count) {
- r = inflateReset(&cab->stream);
- if (r != Z_OK)
- goto zlibfailed;
- r = inflateSetDictionary(&cab->stream,
- cab->uncompressed_buffer, cfdata->uncompressed_size);
- if (r != Z_OK)
- goto zlibfailed;
- }
-
- d = cab->uncompressed_buffer + cfdata->read_offset;
- *avail = uavail - cfdata->read_offset;
- cfdata->uncompressed_avail = uavail;
-
- return (d);
-
-zlibfailed:
- switch (r) {
- case Z_MEM_ERROR:
- archive_set_error(&a->archive, ENOMEM,
- "Out of memory for deflate decompression");
- break;
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Deflate decompression failed (%d)", r);
- break;
- }
- *avail = ARCHIVE_FATAL;
- return (NULL);
-nomszip:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "CFDATA incorrect(no MSZIP signature)");
- *avail = ARCHIVE_FATAL;
- return (NULL);
-}
-
-#else /* HAVE_ZLIB_H */
-
-static const void *
-cab_read_ahead_cfdata_deflate(struct archive_read *a, ssize_t *avail)
-{
- *avail = ARCHIVE_FATAL;
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "libarchive compiled without deflate support (no libz)");
- return (NULL);
-}
-
-#endif /* HAVE_ZLIB_H */
-
-static const void *
-cab_read_ahead_cfdata_lzx(struct archive_read *a, ssize_t *avail)
-{
- struct cab *cab = (struct cab *)(a->format->data);
- struct cfdata *cfdata;
- const void *d;
- int r;
- uint16_t uavail;
-
- cfdata = cab->entry_cfdata;
- /* If the buffer hasn't been allocated, allocate it now. */
- if (cab->uncompressed_buffer == NULL) {
- cab->uncompressed_buffer_size = 0x8000;
- cab->uncompressed_buffer
- = (unsigned char *)malloc(cab->uncompressed_buffer_size);
- if (cab->uncompressed_buffer == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for CAB reader");
- *avail = ARCHIVE_FATAL;
- return (NULL);
- }
- }
-
- uavail = cfdata->uncompressed_avail;
- if (uavail == cfdata->uncompressed_size) {
- d = cab->uncompressed_buffer + cfdata->read_offset;
- *avail = uavail - cfdata->read_offset;
- return (d);
- }
-
- if (!cab->entry_cffolder->decompress_init) {
- r = lzx_decode_init(&cab->xstrm,
- cab->entry_cffolder->compdata);
- if (r != ARCHIVE_OK) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Can't initialize LZX decompression.");
- *avail = ARCHIVE_FATAL;
- return (NULL);
- }
- /* We've initialized decompression for this stream. */
- cab->entry_cffolder->decompress_init = 1;
- }
-
- /* Clean up remaining bits of previous CFDATA. */
- lzx_cleanup_bitstream(&cab->xstrm);
- cab->xstrm.total_out = uavail;
- while (cab->xstrm.total_out < cfdata->uncompressed_size) {
- ssize_t bytes_avail;
-
- cab->xstrm.next_out =
- cab->uncompressed_buffer + cab->xstrm.total_out;
- cab->xstrm.avail_out =
- cfdata->uncompressed_size - cab->xstrm.total_out;
-
- d = __archive_read_ahead(a, 1, &bytes_avail);
- if (bytes_avail <= 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated CAB file data");
- *avail = ARCHIVE_FATAL;
- return (NULL);
- }
- if (bytes_avail > cfdata->compressed_bytes_remaining)
- bytes_avail = cfdata->compressed_bytes_remaining;
-
- cab->xstrm.next_in = d;
- cab->xstrm.avail_in = bytes_avail;
- cab->xstrm.total_in = 0;
- r = lzx_decode(&cab->xstrm,
- cfdata->compressed_bytes_remaining == bytes_avail);
- switch (r) {
- case ARCHIVE_OK:
- case ARCHIVE_EOF:
- break;
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "LZX decompression failed (%d)", r);
- *avail = ARCHIVE_FATAL;
- return (NULL);
- }
- cfdata->unconsumed = cab->xstrm.total_in;
- cfdata->sum_ptr = d;
- if (cab_minimum_consume_cfdata(a, cfdata->unconsumed) < 0) {
- *avail = ARCHIVE_FATAL;
- return (NULL);
- }
- }
-
- uavail = (uint16_t)cab->xstrm.total_out;
- /*
- * Make sure a read pointer advances to next CFDATA.
- */
- if (cfdata->compressed_bytes_remaining > 0) {
- ssize_t bytes_avail;
-
- d = __archive_read_ahead(a, cfdata->compressed_bytes_remaining,
- &bytes_avail);
- if (bytes_avail <= 0) {
- *avail = truncated_error(a);
- return (NULL);
- }
- cfdata->unconsumed = cfdata->compressed_bytes_remaining;
- cfdata->sum_ptr = d;
- if (cab_minimum_consume_cfdata(a, cfdata->unconsumed) < 0) {
- *avail = ARCHIVE_FATAL;
- return (NULL);
- }
- }
-
- /*
- * Translation reversal of x86 processor CALL byte sequence(E8).
- */
- lzx_translation(&cab->xstrm, cab->uncompressed_buffer,
- cfdata->uncompressed_size,
- (cab->entry_cffolder->cfdata_index-1) * 0x8000);
-
- d = cab->uncompressed_buffer + cfdata->read_offset;
- *avail = uavail - cfdata->read_offset;
- cfdata->uncompressed_avail = uavail;
-
- return (d);
-}
-
-/*
- * Consume CFDATA.
- * We always decompress CFDATA to consume CFDATA as much as we need
- * in uncompressed bytes because all CFDATA in a folder are related
- * so we do not skip any CFDATA without decompressing.
- * Note: If the folder of a CFFILE is iFoldCONTINUED_PREV_AND_NEXT or
- * iFoldCONTINUED_FROM_PREV, we won't decompress because a CFDATA for
- * the CFFILE is remaining bytes of previous Multivolume CAB file.
- */
-static int64_t
-cab_consume_cfdata(struct archive_read *a, int64_t consumed_bytes)
-{
- struct cab *cab = (struct cab *)(a->format->data);
- struct cfdata *cfdata;
- int64_t cbytes, rbytes;
- int err;
-
- rbytes = cab_minimum_consume_cfdata(a, consumed_bytes);
- if (rbytes < 0)
- return (ARCHIVE_FATAL);
-
- cfdata = cab->entry_cfdata;
- while (rbytes > 0) {
- ssize_t avail;
-
- if (cfdata->compressed_size == 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid CFDATA");
- return (ARCHIVE_FATAL);
- }
- cbytes = cfdata->uncompressed_bytes_remaining;
- if (cbytes > rbytes)
- cbytes = rbytes;
- rbytes -= cbytes;
-
- if (cfdata->uncompressed_avail == 0 &&
- (cab->entry_cffile->folder == iFoldCONTINUED_PREV_AND_NEXT ||
- cab->entry_cffile->folder == iFoldCONTINUED_FROM_PREV)) {
- /* We have not read any data yet. */
- if (cbytes == cfdata->uncompressed_bytes_remaining) {
- /* Skip whole current CFDATA. */
- __archive_read_consume(a,
- cfdata->compressed_size);
- cab->cab_offset += cfdata->compressed_size;
- cfdata->compressed_bytes_remaining = 0;
- cfdata->uncompressed_bytes_remaining = 0;
- err = cab_next_cfdata(a);
- if (err < 0)
- return (err);
- cfdata = cab->entry_cfdata;
- if (cfdata->uncompressed_size == 0) {
- switch (cab->entry_cffile->folder) {
- case iFoldCONTINUED_PREV_AND_NEXT:
- case iFoldCONTINUED_TO_NEXT:
- case iFoldCONTINUED_FROM_PREV:
- rbytes = 0;
- break;
- default:
- break;
- }
- }
- continue;
- }
- cfdata->read_offset += (uint16_t)cbytes;
- cfdata->uncompressed_bytes_remaining -= (uint16_t)cbytes;
- break;
- } else if (cbytes == 0) {
- err = cab_next_cfdata(a);
- if (err < 0)
- return (err);
- cfdata = cab->entry_cfdata;
- if (cfdata->uncompressed_size == 0) {
- switch (cab->entry_cffile->folder) {
- case iFoldCONTINUED_PREV_AND_NEXT:
- case iFoldCONTINUED_TO_NEXT:
- case iFoldCONTINUED_FROM_PREV:
- return (ARCHIVE_FATAL);
- default:
- break;
- }
- }
- continue;
- }
- while (cbytes > 0) {
- (void)cab_read_ahead_cfdata(a, &avail);
- if (avail <= 0)
- return (ARCHIVE_FATAL);
- if (avail > cbytes)
- avail = (ssize_t)cbytes;
- if (cab_minimum_consume_cfdata(a, avail) < 0)
- return (ARCHIVE_FATAL);
- cbytes -= avail;
- }
- }
- return (consumed_bytes);
-}
-
-/*
- * Consume CFDATA as much as we have already gotten and
- * compute the sum of CFDATA.
- */
-static int64_t
-cab_minimum_consume_cfdata(struct archive_read *a, int64_t consumed_bytes)
-{
- struct cab *cab = (struct cab *)(a->format->data);
- struct cfdata *cfdata;
- int64_t cbytes, rbytes;
- int err;
-
- cfdata = cab->entry_cfdata;
- rbytes = consumed_bytes;
- if (cab->entry_cffolder->comptype == COMPTYPE_NONE) {
- if (consumed_bytes < cfdata->unconsumed)
- cbytes = consumed_bytes;
- else
- cbytes = cfdata->unconsumed;
- rbytes -= cbytes;
- cfdata->read_offset += (uint16_t)cbytes;
- cfdata->uncompressed_bytes_remaining -= (uint16_t)cbytes;
- cfdata->unconsumed -= cbytes;
- } else {
- cbytes = cfdata->uncompressed_avail - cfdata->read_offset;
- if (cbytes > 0) {
- if (consumed_bytes < cbytes)
- cbytes = consumed_bytes;
- rbytes -= cbytes;
- cfdata->read_offset += (uint16_t)cbytes;
- cfdata->uncompressed_bytes_remaining -= (uint16_t)cbytes;
- }
-
- if (cfdata->unconsumed) {
- cbytes = cfdata->unconsumed;
- cfdata->unconsumed = 0;
- } else
- cbytes = 0;
- }
- if (cbytes) {
- /* Compute the sum. */
- cab_checksum_update(a, (size_t)cbytes);
-
- /* Consume as much as the compressor actually used. */
- __archive_read_consume(a, cbytes);
- cab->cab_offset += cbytes;
- cfdata->compressed_bytes_remaining -= (uint16_t)cbytes;
- if (cfdata->compressed_bytes_remaining == 0) {
- err = cab_checksum_finish(a);
- if (err < 0)
- return (err);
- }
- }
- return (rbytes);
-}
-
-/*
- * Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets
- * cab->end_of_entry if it consumes all of the data.
- */
-static int
-cab_read_data(struct archive_read *a, const void **buff,
- size_t *size, int64_t *offset)
-{
- struct cab *cab = (struct cab *)(a->format->data);
- ssize_t bytes_avail;
-
- if (cab->entry_bytes_remaining == 0) {
- *buff = NULL;
- *size = 0;
- *offset = cab->entry_offset;
- cab->end_of_entry = 1;
- return (ARCHIVE_OK);
- }
-
- *buff = cab_read_ahead_cfdata(a, &bytes_avail);
- if (bytes_avail <= 0) {
- *buff = NULL;
- *size = 0;
- *offset = 0;
- if (bytes_avail == 0 &&
- cab->entry_cfdata->uncompressed_size == 0) {
- /* All of CFDATA in a folder has been handled. */
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT, "Invalid CFDATA");
- return (ARCHIVE_FATAL);
- } else
- return ((int)bytes_avail);
- }
- if (bytes_avail > cab->entry_bytes_remaining)
- bytes_avail = (ssize_t)cab->entry_bytes_remaining;
-
- *size = bytes_avail;
- *offset = cab->entry_offset;
- cab->entry_offset += bytes_avail;
- cab->entry_bytes_remaining -= bytes_avail;
- if (cab->entry_bytes_remaining == 0)
- cab->end_of_entry = 1;
- cab->entry_unconsumed = bytes_avail;
- if (cab->entry_cffolder->comptype == COMPTYPE_NONE) {
- /* Don't consume more than current entry used. */
- if (cab->entry_cfdata->unconsumed > cab->entry_unconsumed)
- cab->entry_cfdata->unconsumed = cab->entry_unconsumed;
- }
- return (ARCHIVE_OK);
-}
-
-static int
-archive_read_format_cab_read_data_skip(struct archive_read *a)
-{
- struct cab *cab;
- int64_t bytes_skipped;
- int r;
-
- cab = (struct cab *)(a->format->data);
-
- if (cab->end_of_archive)
- return (ARCHIVE_EOF);
-
- if (!cab->read_data_invoked) {
- cab->bytes_skipped += cab->entry_bytes_remaining;
- cab->entry_bytes_remaining = 0;
- /* This entry is finished and done. */
- cab->end_of_entry_cleanup = cab->end_of_entry = 1;
- return (ARCHIVE_OK);
- }
-
- if (cab->entry_unconsumed) {
- /* Consume as much as the compressor actually used. */
- r = (int)cab_consume_cfdata(a, cab->entry_unconsumed);
- cab->entry_unconsumed = 0;
- if (r < 0)
- return (r);
- } else if (cab->entry_cfdata == NULL) {
- r = cab_next_cfdata(a);
- if (r < 0)
- return (r);
- }
-
- /* if we've already read to end of data, we're done. */
- if (cab->end_of_entry_cleanup)
- return (ARCHIVE_OK);
-
- /*
- * If the length is at the beginning, we can skip the
- * compressed data much more quickly.
- */
- bytes_skipped = cab_consume_cfdata(a, cab->entry_bytes_remaining);
- if (bytes_skipped < 0)
- return (ARCHIVE_FATAL);
-
- /* If the compression type is none(uncompressed), we've already
- * consumed data as much as the current entry size. */
- if (cab->entry_cffolder->comptype == COMPTYPE_NONE &&
- cab->entry_cfdata != NULL)
- cab->entry_cfdata->unconsumed = 0;
-
- /* This entry is finished and done. */
- cab->end_of_entry_cleanup = cab->end_of_entry = 1;
- return (ARCHIVE_OK);
-}
-
-static int
-archive_read_format_cab_cleanup(struct archive_read *a)
-{
- struct cab *cab = (struct cab *)(a->format->data);
- struct cfheader *hd = &cab->cfheader;
- int i;
-
- if (hd->folder_array != NULL) {
- for (i = 0; i < hd->folder_count; i++)
- free(hd->folder_array[i].cfdata.memimage);
- free(hd->folder_array);
- }
- if (hd->file_array != NULL) {
- for (i = 0; i < cab->cfheader.file_count; i++)
- archive_string_free(&(hd->file_array[i].pathname));
- free(hd->file_array);
- }
-#ifdef HAVE_ZLIB_H
- if (cab->stream_valid)
- inflateEnd(&cab->stream);
-#endif
- lzx_decode_free(&cab->xstrm);
- archive_wstring_free(&cab->ws);
- free(cab->uncompressed_buffer);
- free(cab);
- (a->format->data) = NULL;
- return (ARCHIVE_OK);
-}
-
-/* Convert an MSDOS-style date/time into Unix-style time. */
-static time_t
-cab_dos_time(const unsigned char *p)
-{
- int msTime, msDate;
- struct tm ts;
-
- msDate = archive_le16dec(p);
- msTime = archive_le16dec(p+2);
-
- memset(&ts, 0, sizeof(ts));
- ts.tm_year = ((msDate >> 9) & 0x7f) + 80; /* Years since 1900. */
- ts.tm_mon = ((msDate >> 5) & 0x0f) - 1; /* Month number. */
- ts.tm_mday = msDate & 0x1f; /* Day of month. */
- ts.tm_hour = (msTime >> 11) & 0x1f;
- ts.tm_min = (msTime >> 5) & 0x3f;
- ts.tm_sec = (msTime << 1) & 0x3e;
- ts.tm_isdst = -1;
- return (mktime(&ts));
-}
-
-/*****************************************************************
- *
- * LZX decompression code.
- *
- *****************************************************************/
-
-/*
- * Initialize LZX decoder.
- *
- * Returns ARCHIVE_OK if initialization was successful.
- * Returns ARCHIVE_FAILED if w_bits has unsupported value.
- * Returns ARCHIVE_FATAL if initialization failed; memory allocation
- * error occurred.
- */
-static int
-lzx_decode_init(struct lzx_stream *strm, int w_bits)
-{
- struct lzx_dec *ds;
- int slot, w_size, w_slot;
- int base, footer;
- int base_inc[18];
-
- if (strm->ds == NULL) {
- strm->ds = calloc(1, sizeof(*strm->ds));
- if (strm->ds == NULL)
- return (ARCHIVE_FATAL);
- }
- ds = strm->ds;
- ds->error = ARCHIVE_FAILED;
-
- /* Allow bits from 15(32KBi) up to 21(2MBi) */
- if (w_bits < SLOT_BASE || w_bits > SLOT_MAX)
- return (ARCHIVE_FAILED);
-
- ds->error = ARCHIVE_FATAL;
-
- /*
- * Alloc window
- */
- w_size = ds->w_size;
- w_slot = slots[w_bits - SLOT_BASE];
- ds->w_size = 1U << w_bits;
- ds->w_mask = ds->w_size -1;
- if (ds->w_buff == NULL || w_size != ds->w_size) {
- free(ds->w_buff);
- ds->w_buff = malloc(ds->w_size);
- if (ds->w_buff == NULL)
- return (ARCHIVE_FATAL);
- free(ds->pos_tbl);
- ds->pos_tbl = malloc(sizeof(ds->pos_tbl[0]) * w_slot);
- if (ds->pos_tbl == NULL)
- return (ARCHIVE_FATAL);
- }
-
- for (footer = 0; footer < 18; footer++)
- base_inc[footer] = 1 << footer;
- base = footer = 0;
- for (slot = 0; slot < w_slot; slot++) {
- int n;
- if (footer == 0)
- base = slot;
- else
- base += base_inc[footer];
- if (footer < 17) {
- footer = -2;
- for (n = base; n; n >>= 1)
- footer++;
- if (footer <= 0)
- footer = 0;
- }
- ds->pos_tbl[slot].base = base;
- ds->pos_tbl[slot].footer_bits = footer;
- }
-
- ds->w_pos = 0;
- ds->state = 0;
- ds->br.cache_buffer = 0;
- ds->br.cache_avail = 0;
- ds->r0 = ds->r1 = ds->r2 = 1;
-
- /* Initialize aligned offset tree. */
- if (lzx_huffman_init(&(ds->at), 8, 8) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /* Initialize pre-tree. */
- if (lzx_huffman_init(&(ds->pt), 20, 10) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /* Initialize Main tree. */
- if (lzx_huffman_init(&(ds->mt), 256+(w_slot<<3), 16)
- != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /* Initialize Length tree. */
- if (lzx_huffman_init(&(ds->lt), 249, 16) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- ds->error = 0;
-
- return (ARCHIVE_OK);
-}
-
-/*
- * Release LZX decoder.
- */
-static void
-lzx_decode_free(struct lzx_stream *strm)
-{
-
- if (strm->ds == NULL)
- return;
- free(strm->ds->w_buff);
- free(strm->ds->pos_tbl);
- lzx_huffman_free(&(strm->ds->at));
- lzx_huffman_free(&(strm->ds->pt));
- lzx_huffman_free(&(strm->ds->mt));
- lzx_huffman_free(&(strm->ds->lt));
- free(strm->ds);
- strm->ds = NULL;
-}
-
-/*
- * E8 Call Translation reversal.
- */
-static void
-lzx_translation(struct lzx_stream *strm, void *p, size_t size, uint32_t offset)
-{
- struct lzx_dec *ds = strm->ds;
- unsigned char *b, *end;
-
- if (!ds->translation || size <= 10)
- return;
- b = p;
- end = b + size - 10;
- while (b < end && (b = memchr(b, 0xE8, end - b)) != NULL) {
- size_t i = b - (unsigned char *)p;
- int32_t cp, displacement, value;
-
- cp = (int32_t)(offset + (uint32_t)i);
- value = archive_le32dec(&b[1]);
- if (value >= -cp && value < (int32_t)ds->translation_size) {
- if (value >= 0)
- displacement = value - cp;
- else
- displacement = value + ds->translation_size;
- archive_le32enc(&b[1], (uint32_t)displacement);
- }
- b += 5;
- }
-}
-
-/*
- * Bit stream reader.
- */
-/* Check that the cache buffer has enough bits. */
-#define lzx_br_has(br, n) ((br)->cache_avail >= n)
-/* Get compressed data by bit. */
-#define lzx_br_bits(br, n) \
- (((uint32_t)((br)->cache_buffer >> \
- ((br)->cache_avail - (n)))) & cache_masks[n])
-#define lzx_br_bits_forced(br, n) \
- (((uint32_t)((br)->cache_buffer << \
- ((n) - (br)->cache_avail))) & cache_masks[n])
-/* Read ahead to make sure the cache buffer has enough compressed data we
- * will use.
- * True : completed, there is enough data in the cache buffer.
- * False : we met that strm->next_in is empty, we have to get following
- * bytes. */
-#define lzx_br_read_ahead_0(strm, br, n) \
- (lzx_br_has((br), (n)) || lzx_br_fillup(strm, br))
-/* True : the cache buffer has some bits as much as we need.
- * False : there are no enough bits in the cache buffer to be used,
- * we have to get following bytes if we could. */
-#define lzx_br_read_ahead(strm, br, n) \
- (lzx_br_read_ahead_0((strm), (br), (n)) || lzx_br_has((br), (n)))
-
-/* Notify how many bits we consumed. */
-#define lzx_br_consume(br, n) ((br)->cache_avail -= (n))
-#define lzx_br_consume_unaligned_bits(br) ((br)->cache_avail &= ~0x0f)
-
-#define lzx_br_is_unaligned(br) ((br)->cache_avail & 0x0f)
-
-static const uint32_t cache_masks[] = {
- 0x00000000, 0x00000001, 0x00000003, 0x00000007,
- 0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F,
- 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF,
- 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF,
- 0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF,
- 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF,
- 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF,
- 0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
-};
-
-/*
- * Shift away used bits in the cache data and fill it up with following bits.
- * Call this when cache buffer does not have enough bits you need.
- *
- * Returns 1 if the cache buffer is full.
- * Returns 0 if the cache buffer is not full; input buffer is empty.
- */
-static int
-lzx_br_fillup(struct lzx_stream *strm, struct lzx_br *br)
-{
-/*
- * x86 processor family can read misaligned data without an access error.
- */
- int n = CACHE_BITS - br->cache_avail;
-
- for (;;) {
- switch (n >> 4) {
- case 4:
- if (strm->avail_in >= 8) {
- br->cache_buffer =
- ((uint64_t)strm->next_in[1]) << 56 |
- ((uint64_t)strm->next_in[0]) << 48 |
- ((uint64_t)strm->next_in[3]) << 40 |
- ((uint64_t)strm->next_in[2]) << 32 |
- ((uint32_t)strm->next_in[5]) << 24 |
- ((uint32_t)strm->next_in[4]) << 16 |
- ((uint32_t)strm->next_in[7]) << 8 |
- (uint32_t)strm->next_in[6];
- strm->next_in += 8;
- strm->avail_in -= 8;
- br->cache_avail += 8 * 8;
- return (1);
- }
- break;
- case 3:
- if (strm->avail_in >= 6) {
- br->cache_buffer =
- (br->cache_buffer << 48) |
- ((uint64_t)strm->next_in[1]) << 40 |
- ((uint64_t)strm->next_in[0]) << 32 |
- ((uint64_t)strm->next_in[3]) << 24 |
- ((uint64_t)strm->next_in[2]) << 16 |
- ((uint64_t)strm->next_in[5]) << 8 |
- (uint64_t)strm->next_in[4];
- strm->next_in += 6;
- strm->avail_in -= 6;
- br->cache_avail += 6 * 8;
- return (1);
- }
- break;
- case 0:
- /* We have enough compressed data in
- * the cache buffer.*/
- return (1);
- default:
- break;
- }
- if (strm->avail_in < 2) {
- /* There is not enough compressed data to
- * fill up the cache buffer. */
- if (strm->avail_in == 1) {
- br->odd = *strm->next_in++;
- strm->avail_in--;
- br->have_odd = 1;
- }
- return (0);
- }
- br->cache_buffer =
- (br->cache_buffer << 16) |
- archive_le16dec(strm->next_in);
- strm->next_in += 2;
- strm->avail_in -= 2;
- br->cache_avail += 16;
- n -= 16;
- }
-}
-
-static void
-lzx_br_fixup(struct lzx_stream *strm, struct lzx_br *br)
-{
- int n = CACHE_BITS - br->cache_avail;
-
- if (br->have_odd && n >= 16 && strm->avail_in > 0) {
- br->cache_buffer =
- (br->cache_buffer << 16) |
- ((uint16_t)(*strm->next_in)) << 8 | br->odd;
- strm->next_in++;
- strm->avail_in--;
- br->cache_avail += 16;
- br->have_odd = 0;
- }
-}
-
-static void
-lzx_cleanup_bitstream(struct lzx_stream *strm)
-{
- strm->ds->br.cache_avail = 0;
- strm->ds->br.have_odd = 0;
-}
-
-/*
- * Decode LZX.
- *
- * 1. Returns ARCHIVE_OK if output buffer or input buffer are empty.
- * Please set available buffer and call this function again.
- * 2. Returns ARCHIVE_EOF if decompression has been completed.
- * 3. Returns ARCHIVE_FAILED if an error occurred; compressed data
- * is broken or you do not set 'last' flag properly.
- */
-#define ST_RD_TRANSLATION 0
-#define ST_RD_TRANSLATION_SIZE 1
-#define ST_RD_BLOCK_TYPE 2
-#define ST_RD_BLOCK_SIZE 3
-#define ST_RD_ALIGNMENT 4
-#define ST_RD_R0 5
-#define ST_RD_R1 6
-#define ST_RD_R2 7
-#define ST_COPY_UNCOMP1 8
-#define ST_COPY_UNCOMP2 9
-#define ST_RD_ALIGNED_OFFSET 10
-#define ST_RD_VERBATIM 11
-#define ST_RD_PRE_MAIN_TREE_256 12
-#define ST_MAIN_TREE_256 13
-#define ST_RD_PRE_MAIN_TREE_REM 14
-#define ST_MAIN_TREE_REM 15
-#define ST_RD_PRE_LENGTH_TREE 16
-#define ST_LENGTH_TREE 17
-#define ST_MAIN 18
-#define ST_LENGTH 19
-#define ST_OFFSET 20
-#define ST_REAL_POS 21
-#define ST_COPY 22
-
-static int
-lzx_decode(struct lzx_stream *strm, int last)
-{
- struct lzx_dec *ds = strm->ds;
- int64_t avail_in;
- int r;
-
- if (ds->error)
- return (ds->error);
-
- avail_in = strm->avail_in;
- lzx_br_fixup(strm, &(ds->br));
- do {
- if (ds->state < ST_MAIN)
- r = lzx_read_blocks(strm, last);
- else {
- int64_t bytes_written = strm->avail_out;
- r = lzx_decode_blocks(strm, last);
- bytes_written -= strm->avail_out;
- strm->next_out += bytes_written;
- strm->total_out += bytes_written;
- }
- } while (r == 100);
- strm->total_in += avail_in - strm->avail_in;
- return (r);
-}
-
-static int
-lzx_read_blocks(struct lzx_stream *strm, int last)
-{
- struct lzx_dec *ds = strm->ds;
- struct lzx_br *br = &(ds->br);
- int i, r;
-
- for (;;) {
- switch (ds->state) {
- case ST_RD_TRANSLATION:
- if (!lzx_br_read_ahead(strm, br, 1)) {
- ds->state = ST_RD_TRANSLATION;
- if (last)
- goto failed;
- return (ARCHIVE_OK);
- }
- ds->translation = lzx_br_bits(br, 1);
- lzx_br_consume(br, 1);
- /* FALL THROUGH */
- case ST_RD_TRANSLATION_SIZE:
- if (ds->translation) {
- if (!lzx_br_read_ahead(strm, br, 32)) {
- ds->state = ST_RD_TRANSLATION_SIZE;
- if (last)
- goto failed;
- return (ARCHIVE_OK);
- }
- ds->translation_size = lzx_br_bits(br, 16);
- lzx_br_consume(br, 16);
- ds->translation_size <<= 16;
- ds->translation_size |= lzx_br_bits(br, 16);
- lzx_br_consume(br, 16);
- }
- /* FALL THROUGH */
- case ST_RD_BLOCK_TYPE:
- if (!lzx_br_read_ahead(strm, br, 3)) {
- ds->state = ST_RD_BLOCK_TYPE;
- if (last)
- goto failed;
- return (ARCHIVE_OK);
- }
- ds->block_type = lzx_br_bits(br, 3);
- lzx_br_consume(br, 3);
- /* Check a block type. */
- switch (ds->block_type) {
- case VERBATIM_BLOCK:
- case ALIGNED_OFFSET_BLOCK:
- case UNCOMPRESSED_BLOCK:
- break;
- default:
- goto failed;/* Invalid */
- }
- /* FALL THROUGH */
- case ST_RD_BLOCK_SIZE:
- if (!lzx_br_read_ahead(strm, br, 24)) {
- ds->state = ST_RD_BLOCK_SIZE;
- if (last)
- goto failed;
- return (ARCHIVE_OK);
- }
- ds->block_size = lzx_br_bits(br, 8);
- lzx_br_consume(br, 8);
- ds->block_size <<= 16;
- ds->block_size |= lzx_br_bits(br, 16);
- lzx_br_consume(br, 16);
- if (ds->block_size == 0)
- goto failed;
- ds->block_bytes_avail = ds->block_size;
- if (ds->block_type != UNCOMPRESSED_BLOCK) {
- if (ds->block_type == VERBATIM_BLOCK)
- ds->state = ST_RD_VERBATIM;
- else
- ds->state = ST_RD_ALIGNED_OFFSET;
- break;
- }
- /* FALL THROUGH */
- case ST_RD_ALIGNMENT:
- /*
- * Handle an Uncompressed Block.
- */
- /* Skip padding to align following field on
- * 16-bit boundary. */
- if (lzx_br_is_unaligned(br))
- lzx_br_consume_unaligned_bits(br);
- else {
- if (lzx_br_read_ahead(strm, br, 16))
- lzx_br_consume(br, 16);
- else {
- ds->state = ST_RD_ALIGNMENT;
- if (last)
- goto failed;
- return (ARCHIVE_OK);
- }
- }
- /* Preparation to read repeated offsets R0,R1 and R2. */
- ds->rbytes_avail = 0;
- ds->state = ST_RD_R0;
- /* FALL THROUGH */
- case ST_RD_R0:
- case ST_RD_R1:
- case ST_RD_R2:
- do {
- uint16_t u16;
- /* Drain bits in the cache buffer of
- * bit-stream. */
- if (lzx_br_has(br, 32)) {
- u16 = lzx_br_bits(br, 16);
- lzx_br_consume(br, 16);
- archive_le16enc(ds->rbytes, u16);
- u16 = lzx_br_bits(br, 16);
- lzx_br_consume(br, 16);
- archive_le16enc(ds->rbytes+2, u16);
- ds->rbytes_avail = 4;
- } else if (lzx_br_has(br, 16)) {
- u16 = lzx_br_bits(br, 16);
- lzx_br_consume(br, 16);
- archive_le16enc(ds->rbytes, u16);
- ds->rbytes_avail = 2;
- }
- if (ds->rbytes_avail < 4 && ds->br.have_odd) {
- ds->rbytes[ds->rbytes_avail++] =
- ds->br.odd;
- ds->br.have_odd = 0;
- }
- while (ds->rbytes_avail < 4) {
- if (strm->avail_in <= 0) {
- if (last)
- goto failed;
- return (ARCHIVE_OK);
- }
- ds->rbytes[ds->rbytes_avail++] =
- *strm->next_in++;
- strm->avail_in--;
- }
- ds->rbytes_avail = 0;
- if (ds->state == ST_RD_R0) {
- ds->r0 = archive_le32dec(ds->rbytes);
- if (ds->r0 < 0)
- goto failed;
- ds->state = ST_RD_R1;
- } else if (ds->state == ST_RD_R1) {
- ds->r1 = archive_le32dec(ds->rbytes);
- if (ds->r1 < 0)
- goto failed;
- ds->state = ST_RD_R2;
- } else if (ds->state == ST_RD_R2) {
- ds->r2 = archive_le32dec(ds->rbytes);
- if (ds->r2 < 0)
- goto failed;
- /* We've gotten all repeated offsets. */
- ds->state = ST_COPY_UNCOMP1;
- }
- } while (ds->state != ST_COPY_UNCOMP1);
- /* FALL THROUGH */
- case ST_COPY_UNCOMP1:
- /*
- * Copy bytes form next_in to next_out directly.
- */
- while (ds->block_bytes_avail) {
- int l;
-
- if (strm->avail_out <= 0)
- /* Output buffer is empty. */
- return (ARCHIVE_OK);
- if (strm->avail_in <= 0) {
- /* Input buffer is empty. */
- if (last)
- goto failed;
- return (ARCHIVE_OK);
- }
- l = (int)ds->block_bytes_avail;
- if (l > ds->w_size - ds->w_pos)
- l = ds->w_size - ds->w_pos;
- if (l > strm->avail_out)
- l = (int)strm->avail_out;
- if (l > strm->avail_in)
- l = (int)strm->avail_in;
- memcpy(strm->next_out, strm->next_in, l);
- memcpy(&(ds->w_buff[ds->w_pos]),
- strm->next_in, l);
- strm->next_in += l;
- strm->avail_in -= l;
- strm->next_out += l;
- strm->avail_out -= l;
- strm->total_out += l;
- ds->w_pos = (ds->w_pos + l) & ds->w_mask;
- ds->block_bytes_avail -= l;
- }
- /* FALL THROUGH */
- case ST_COPY_UNCOMP2:
- /* Re-align; skip padding byte. */
- if (ds->block_size & 1) {
- if (strm->avail_in <= 0) {
- /* Input buffer is empty. */
- ds->state = ST_COPY_UNCOMP2;
- if (last)
- goto failed;
- return (ARCHIVE_OK);
- }
- strm->next_in++;
- strm->avail_in --;
- }
- /* This block ended. */
- ds->state = ST_RD_BLOCK_TYPE;
- return (ARCHIVE_EOF);
- /********************/
- case ST_RD_ALIGNED_OFFSET:
- /*
- * Read Aligned offset tree.
- */
- if (!lzx_br_read_ahead(strm, br, 3 * ds->at.len_size)) {
- ds->state = ST_RD_ALIGNED_OFFSET;
- if (last)
- goto failed;
- return (ARCHIVE_OK);
- }
- memset(ds->at.freq, 0, sizeof(ds->at.freq));
- for (i = 0; i < ds->at.len_size; i++) {
- ds->at.bitlen[i] = lzx_br_bits(br, 3);
- ds->at.freq[ds->at.bitlen[i]]++;
- lzx_br_consume(br, 3);
- }
- if (!lzx_make_huffman_table(&ds->at))
- goto failed;
- /* FALL THROUGH */
- case ST_RD_VERBATIM:
- ds->loop = 0;
- /* FALL THROUGH */
- case ST_RD_PRE_MAIN_TREE_256:
- /*
- * Read Pre-tree for first 256 elements of main tree.
- */
- if (!lzx_read_pre_tree(strm)) {
- ds->state = ST_RD_PRE_MAIN_TREE_256;
- if (last)
- goto failed;
- return (ARCHIVE_OK);
- }
- if (!lzx_make_huffman_table(&ds->pt))
- goto failed;
- ds->loop = 0;
- /* FALL THROUGH */
- case ST_MAIN_TREE_256:
- /*
- * Get path lengths of first 256 elements of main tree.
- */
- r = lzx_read_bitlen(strm, &ds->mt, 256);
- if (r < 0)
- goto failed;
- else if (!r) {
- ds->state = ST_MAIN_TREE_256;
- if (last)
- goto failed;
- return (ARCHIVE_OK);
- }
- ds->loop = 0;
- /* FALL THROUGH */
- case ST_RD_PRE_MAIN_TREE_REM:
- /*
- * Read Pre-tree for remaining elements of main tree.
- */
- if (!lzx_read_pre_tree(strm)) {
- ds->state = ST_RD_PRE_MAIN_TREE_REM;
- if (last)
- goto failed;
- return (ARCHIVE_OK);
- }
- if (!lzx_make_huffman_table(&ds->pt))
- goto failed;
- ds->loop = 256;
- /* FALL THROUGH */
- case ST_MAIN_TREE_REM:
- /*
- * Get path lengths of remaining elements of main tree.
- */
- r = lzx_read_bitlen(strm, &ds->mt, -1);
- if (r < 0)
- goto failed;
- else if (!r) {
- ds->state = ST_MAIN_TREE_REM;
- if (last)
- goto failed;
- return (ARCHIVE_OK);
- }
- if (!lzx_make_huffman_table(&ds->mt))
- goto failed;
- ds->loop = 0;
- /* FALL THROUGH */
- case ST_RD_PRE_LENGTH_TREE:
- /*
- * Read Pre-tree for remaining elements of main tree.
- */
- if (!lzx_read_pre_tree(strm)) {
- ds->state = ST_RD_PRE_LENGTH_TREE;
- if (last)
- goto failed;
- return (ARCHIVE_OK);
- }
- if (!lzx_make_huffman_table(&ds->pt))
- goto failed;
- ds->loop = 0;
- /* FALL THROUGH */
- case ST_LENGTH_TREE:
- /*
- * Get path lengths of remaining elements of main tree.
- */
- r = lzx_read_bitlen(strm, &ds->lt, -1);
- if (r < 0)
- goto failed;
- else if (!r) {
- ds->state = ST_LENGTH_TREE;
- if (last)
- goto failed;
- return (ARCHIVE_OK);
- }
- if (!lzx_make_huffman_table(&ds->lt))
- goto failed;
- ds->state = ST_MAIN;
- return (100);
- }
- }
-failed:
- return (ds->error = ARCHIVE_FAILED);
-}
-
-static int
-lzx_decode_blocks(struct lzx_stream *strm, int last)
-{
- struct lzx_dec *ds = strm->ds;
- struct lzx_br bre = ds->br;
- struct huffman *at = &(ds->at), *lt = &(ds->lt), *mt = &(ds->mt);
- const struct lzx_pos_tbl *pos_tbl = ds->pos_tbl;
- unsigned char *noutp = strm->next_out;
- unsigned char *endp = noutp + strm->avail_out;
- unsigned char *w_buff = ds->w_buff;
- unsigned char *at_bitlen = at->bitlen;
- unsigned char *lt_bitlen = lt->bitlen;
- unsigned char *mt_bitlen = mt->bitlen;
- size_t block_bytes_avail = ds->block_bytes_avail;
- int at_max_bits = at->max_bits;
- int lt_max_bits = lt->max_bits;
- int mt_max_bits = mt->max_bits;
- int c, copy_len = ds->copy_len, copy_pos = ds->copy_pos;
- int w_pos = ds->w_pos, w_mask = ds->w_mask, w_size = ds->w_size;
- int length_header = ds->length_header;
- int offset_bits = ds->offset_bits;
- int position_slot = ds->position_slot;
- int r0 = ds->r0, r1 = ds->r1, r2 = ds->r2;
- int state = ds->state;
- char block_type = ds->block_type;
-
- for (;;) {
- switch (state) {
- case ST_MAIN:
- for (;;) {
- if (block_bytes_avail == 0) {
- /* This block ended. */
- ds->state = ST_RD_BLOCK_TYPE;
- ds->br = bre;
- ds->block_bytes_avail =
- block_bytes_avail;
- ds->copy_len = copy_len;
- ds->copy_pos = copy_pos;
- ds->length_header = length_header;
- ds->position_slot = position_slot;
- ds->r0 = r0; ds->r1 = r1; ds->r2 = r2;
- ds->w_pos = w_pos;
- strm->avail_out = endp - noutp;
- return (ARCHIVE_EOF);
- }
- if (noutp >= endp)
- /* Output buffer is empty. */
- goto next_data;
-
- if (!lzx_br_read_ahead(strm, &bre,
- mt_max_bits)) {
- if (!last)
- goto next_data;
- /* Remaining bits are less than
- * maximum bits(mt.max_bits) but maybe
- * it still remains as much as we need,
- * so we should try to use it with
- * dummy bits. */
- c = lzx_decode_huffman(mt,
- lzx_br_bits_forced(
- &bre, mt_max_bits));
- lzx_br_consume(&bre, mt_bitlen[c]);
- if (!lzx_br_has(&bre, 0))
- goto failed;/* Over read. */
- } else {
- c = lzx_decode_huffman(mt,
- lzx_br_bits(&bre, mt_max_bits));
- lzx_br_consume(&bre, mt_bitlen[c]);
- }
- if (c > UCHAR_MAX)
- break;
- /*
- * 'c' is exactly literal code.
- */
- /* Save a decoded code to reference it
- * afterward. */
- w_buff[w_pos] = c;
- w_pos = (w_pos + 1) & w_mask;
- /* Store the decoded code to output buffer. */
- *noutp++ = c;
- block_bytes_avail--;
- }
- /*
- * Get a match code, its length and offset.
- */
- c -= UCHAR_MAX + 1;
- length_header = c & 7;
- position_slot = c >> 3;
- /* FALL THROUGH */
- case ST_LENGTH:
- /*
- * Get a length.
- */
- if (length_header == 7) {
- if (!lzx_br_read_ahead(strm, &bre,
- lt_max_bits)) {
- if (!last) {
- state = ST_LENGTH;
- goto next_data;
- }
- c = lzx_decode_huffman(lt,
- lzx_br_bits_forced(
- &bre, lt_max_bits));
- lzx_br_consume(&bre, lt_bitlen[c]);
- if (!lzx_br_has(&bre, 0))
- goto failed;/* Over read. */
- } else {
- c = lzx_decode_huffman(lt,
- lzx_br_bits(&bre, lt_max_bits));
- lzx_br_consume(&bre, lt_bitlen[c]);
- }
- copy_len = c + 7 + 2;
- } else
- copy_len = length_header + 2;
- if ((size_t)copy_len > block_bytes_avail)
- goto failed;
- /*
- * Get an offset.
- */
- switch (position_slot) {
- case 0: /* Use repeated offset 0. */
- copy_pos = r0;
- state = ST_REAL_POS;
- continue;
- case 1: /* Use repeated offset 1. */
- copy_pos = r1;
- /* Swap repeated offset. */
- r1 = r0;
- r0 = copy_pos;
- state = ST_REAL_POS;
- continue;
- case 2: /* Use repeated offset 2. */
- copy_pos = r2;
- /* Swap repeated offset. */
- r2 = r0;
- r0 = copy_pos;
- state = ST_REAL_POS;
- continue;
- default:
- offset_bits =
- pos_tbl[position_slot].footer_bits;
- break;
- }
- /* FALL THROUGH */
- case ST_OFFSET:
- /*
- * Get the offset, which is a distance from
- * current window position.
- */
- if (block_type == ALIGNED_OFFSET_BLOCK &&
- offset_bits >= 3) {
- int offbits = offset_bits - 3;
-
- if (!lzx_br_read_ahead(strm, &bre, offbits)) {
- state = ST_OFFSET;
- if (last)
- goto failed;
- goto next_data;
- }
- copy_pos = lzx_br_bits(&bre, offbits) << 3;
-
- /* Get an aligned number. */
- if (!lzx_br_read_ahead(strm, &bre,
- offbits + at_max_bits)) {
- if (!last) {
- state = ST_OFFSET;
- goto next_data;
- }
- lzx_br_consume(&bre, offbits);
- c = lzx_decode_huffman(at,
- lzx_br_bits_forced(&bre,
- at_max_bits));
- lzx_br_consume(&bre, at_bitlen[c]);
- if (!lzx_br_has(&bre, 0))
- goto failed;/* Over read. */
- } else {
- lzx_br_consume(&bre, offbits);
- c = lzx_decode_huffman(at,
- lzx_br_bits(&bre, at_max_bits));
- lzx_br_consume(&bre, at_bitlen[c]);
- }
- /* Add an aligned number. */
- copy_pos += c;
- } else {
- if (!lzx_br_read_ahead(strm, &bre,
- offset_bits)) {
- state = ST_OFFSET;
- if (last)
- goto failed;
- goto next_data;
- }
- copy_pos = lzx_br_bits(&bre, offset_bits);
- lzx_br_consume(&bre, offset_bits);
- }
- copy_pos += pos_tbl[position_slot].base -2;
-
- /* Update repeated offset LRU queue. */
- r2 = r1;
- r1 = r0;
- r0 = copy_pos;
- /* FALL THROUGH */
- case ST_REAL_POS:
- /*
- * Compute a real position in window.
- */
- copy_pos = (w_pos - copy_pos) & w_mask;
- /* FALL THROUGH */
- case ST_COPY:
- /*
- * Copy several bytes as extracted data from the window
- * into the output buffer.
- */
- for (;;) {
- const unsigned char *s;
- int l;
-
- l = copy_len;
- if (copy_pos > w_pos) {
- if (l > w_size - copy_pos)
- l = w_size - copy_pos;
- } else {
- if (l > w_size - w_pos)
- l = w_size - w_pos;
- }
- if (noutp + l >= endp)
- l = (int)(endp - noutp);
- s = w_buff + copy_pos;
- if (l >= 8 && ((copy_pos + l < w_pos)
- || (w_pos + l < copy_pos))) {
- memcpy(w_buff + w_pos, s, l);
- memcpy(noutp, s, l);
- } else {
- unsigned char *d;
- int li;
-
- d = w_buff + w_pos;
- for (li = 0; li < l; li++)
- noutp[li] = d[li] = s[li];
- }
- noutp += l;
- copy_pos = (copy_pos + l) & w_mask;
- w_pos = (w_pos + l) & w_mask;
- block_bytes_avail -= l;
- if (copy_len <= l)
- /* A copy of current pattern ended. */
- break;
- copy_len -= l;
- if (noutp >= endp) {
- /* Output buffer is empty. */
- state = ST_COPY;
- goto next_data;
- }
- }
- state = ST_MAIN;
- break;
- }
- }
-failed:
- return (ds->error = ARCHIVE_FAILED);
-next_data:
- ds->br = bre;
- ds->block_bytes_avail = block_bytes_avail;
- ds->copy_len = copy_len;
- ds->copy_pos = copy_pos;
- ds->length_header = length_header;
- ds->offset_bits = offset_bits;
- ds->position_slot = position_slot;
- ds->r0 = r0; ds->r1 = r1; ds->r2 = r2;
- ds->state = state;
- ds->w_pos = w_pos;
- strm->avail_out = endp - noutp;
- return (ARCHIVE_OK);
-}
-
-static int
-lzx_read_pre_tree(struct lzx_stream *strm)
-{
- struct lzx_dec *ds = strm->ds;
- struct lzx_br *br = &(ds->br);
- int i;
-
- if (ds->loop == 0)
- memset(ds->pt.freq, 0, sizeof(ds->pt.freq));
- for (i = ds->loop; i < ds->pt.len_size; i++) {
- if (!lzx_br_read_ahead(strm, br, 4)) {
- ds->loop = i;
- return (0);
- }
- ds->pt.bitlen[i] = lzx_br_bits(br, 4);
- ds->pt.freq[ds->pt.bitlen[i]]++;
- lzx_br_consume(br, 4);
- }
- ds->loop = i;
- return (1);
-}
-
-/*
- * Read a bunch of bit-lengths from pre-tree.
- */
-static int
-lzx_read_bitlen(struct lzx_stream *strm, struct huffman *d, int end)
-{
- struct lzx_dec *ds = strm->ds;
- struct lzx_br *br = &(ds->br);
- int c, i, j, ret, same;
- unsigned rbits;
-
- i = ds->loop;
- if (i == 0)
- memset(d->freq, 0, sizeof(d->freq));
- ret = 0;
- if (end < 0)
- end = d->len_size;
- while (i < end) {
- ds->loop = i;
- if (!lzx_br_read_ahead(strm, br, ds->pt.max_bits))
- goto getdata;
- rbits = lzx_br_bits(br, ds->pt.max_bits);
- c = lzx_decode_huffman(&(ds->pt), rbits);
- switch (c) {
- case 17:/* several zero lengths, from 4 to 19. */
- if (!lzx_br_read_ahead(strm, br, ds->pt.bitlen[c]+4))
- goto getdata;
- lzx_br_consume(br, ds->pt.bitlen[c]);
- same = lzx_br_bits(br, 4) + 4;
- if (i + same > end)
- return (-1);/* Invalid */
- lzx_br_consume(br, 4);
- for (j = 0; j < same; j++)
- d->bitlen[i++] = 0;
- break;
- case 18:/* many zero lengths, from 20 to 51. */
- if (!lzx_br_read_ahead(strm, br, ds->pt.bitlen[c]+5))
- goto getdata;
- lzx_br_consume(br, ds->pt.bitlen[c]);
- same = lzx_br_bits(br, 5) + 20;
- if (i + same > end)
- return (-1);/* Invalid */
- lzx_br_consume(br, 5);
- memset(d->bitlen + i, 0, same);
- i += same;
- break;
- case 19:/* a few same lengths. */
- if (!lzx_br_read_ahead(strm, br,
- ds->pt.bitlen[c]+1+ds->pt.max_bits))
- goto getdata;
- lzx_br_consume(br, ds->pt.bitlen[c]);
- same = lzx_br_bits(br, 1) + 4;
- if (i + same > end)
- return (-1);
- lzx_br_consume(br, 1);
- rbits = lzx_br_bits(br, ds->pt.max_bits);
- c = lzx_decode_huffman(&(ds->pt), rbits);
- lzx_br_consume(br, ds->pt.bitlen[c]);
- c = (d->bitlen[i] - c + 17) % 17;
- if (c < 0)
- return (-1);/* Invalid */
- for (j = 0; j < same; j++)
- d->bitlen[i++] = c;
- d->freq[c] += same;
- break;
- default:
- lzx_br_consume(br, ds->pt.bitlen[c]);
- c = (d->bitlen[i] - c + 17) % 17;
- if (c < 0)
- return (-1);/* Invalid */
- d->freq[c]++;
- d->bitlen[i++] = c;
- break;
- }
- }
- ret = 1;
-getdata:
- ds->loop = i;
- return (ret);
-}
-
-static int
-lzx_huffman_init(struct huffman *hf, size_t len_size, int tbl_bits)
-{
-
- if (hf->bitlen == NULL || hf->len_size != (int)len_size) {
- free(hf->bitlen);
- hf->bitlen = calloc(len_size, sizeof(hf->bitlen[0]));
- if (hf->bitlen == NULL)
- return (ARCHIVE_FATAL);
- hf->len_size = (int)len_size;
- } else
- memset(hf->bitlen, 0, len_size * sizeof(hf->bitlen[0]));
- if (hf->tbl == NULL) {
- hf->tbl = malloc(((size_t)1 << tbl_bits) * sizeof(hf->tbl[0]));
- if (hf->tbl == NULL)
- return (ARCHIVE_FATAL);
- hf->tbl_bits = tbl_bits;
- }
- return (ARCHIVE_OK);
-}
-
-static void
-lzx_huffman_free(struct huffman *hf)
-{
- free(hf->bitlen);
- free(hf->tbl);
-}
-
-/*
- * Make a huffman coding table.
- */
-static int
-lzx_make_huffman_table(struct huffman *hf)
-{
- uint16_t *tbl;
- const unsigned char *bitlen;
- int bitptn[17], weight[17];
- int i, maxbits = 0, ptn, tbl_size, w;
- int len_avail;
-
- /*
- * Initialize bit patterns.
- */
- ptn = 0;
- for (i = 1, w = 1 << 15; i <= 16; i++, w >>= 1) {
- bitptn[i] = ptn;
- weight[i] = w;
- if (hf->freq[i]) {
- ptn += hf->freq[i] * w;
- maxbits = i;
- }
- }
- if ((ptn & 0xffff) != 0 || maxbits > hf->tbl_bits)
- return (0);/* Invalid */
-
- hf->max_bits = maxbits;
-
- /*
- * Cut out extra bits which we won't house in the table.
- * This preparation reduces the same calculation in the for-loop
- * making the table.
- */
- if (maxbits < 16) {
- int ebits = 16 - maxbits;
- for (i = 1; i <= maxbits; i++) {
- bitptn[i] >>= ebits;
- weight[i] >>= ebits;
- }
- }
-
- /*
- * Make the table.
- */
- tbl_size = 1 << hf->tbl_bits;
- tbl = hf->tbl;
- bitlen = hf->bitlen;
- len_avail = hf->len_size;
- hf->tree_used = 0;
- for (i = 0; i < len_avail; i++) {
- uint16_t *p;
- int len, cnt;
-
- if (bitlen[i] == 0)
- continue;
- /* Get a bit pattern */
- len = bitlen[i];
- if (len > tbl_size)
- return (0);
- ptn = bitptn[len];
- cnt = weight[len];
- /* Calculate next bit pattern */
- if ((bitptn[len] = ptn + cnt) > tbl_size)
- return (0);/* Invalid */
- /* Update the table */
- p = &(tbl[ptn]);
- while (--cnt >= 0)
- p[cnt] = (uint16_t)i;
- }
- return (1);
-}
-
-static inline int
-lzx_decode_huffman(struct huffman *hf, unsigned rbits)
-{
- int c;
- c = hf->tbl[rbits];
- if (c < hf->len_size)
- return (c);
- return (0);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_format_cpio.c b/contrib/libs/libarchive/libarchive/archive_read_support_format_cpio.c
deleted file mode 100644
index 9adcfd335b..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_format_cpio.c
+++ /dev/null
@@ -1,1104 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * Copyright (c) 2010-2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_cpio.c 201163 2009-12-29 05:50:34Z kientzle $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-/* #include <stdint.h> */ /* See archive_platform.h */
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-#define bin_magic_offset 0
-#define bin_magic_size 2
-#define bin_dev_offset 2
-#define bin_dev_size 2
-#define bin_ino_offset 4
-#define bin_ino_size 2
-#define bin_mode_offset 6
-#define bin_mode_size 2
-#define bin_uid_offset 8
-#define bin_uid_size 2
-#define bin_gid_offset 10
-#define bin_gid_size 2
-#define bin_nlink_offset 12
-#define bin_nlink_size 2
-#define bin_rdev_offset 14
-#define bin_rdev_size 2
-#define bin_mtime_offset 16
-#define bin_mtime_size 4
-#define bin_namesize_offset 20
-#define bin_namesize_size 2
-#define bin_filesize_offset 22
-#define bin_filesize_size 4
-#define bin_header_size 26
-
-#define odc_magic_offset 0
-#define odc_magic_size 6
-#define odc_dev_offset 6
-#define odc_dev_size 6
-#define odc_ino_offset 12
-#define odc_ino_size 6
-#define odc_mode_offset 18
-#define odc_mode_size 6
-#define odc_uid_offset 24
-#define odc_uid_size 6
-#define odc_gid_offset 30
-#define odc_gid_size 6
-#define odc_nlink_offset 36
-#define odc_nlink_size 6
-#define odc_rdev_offset 42
-#define odc_rdev_size 6
-#define odc_mtime_offset 48
-#define odc_mtime_size 11
-#define odc_namesize_offset 59
-#define odc_namesize_size 6
-#define odc_filesize_offset 65
-#define odc_filesize_size 11
-#define odc_header_size 76
-
-#define newc_magic_offset 0
-#define newc_magic_size 6
-#define newc_ino_offset 6
-#define newc_ino_size 8
-#define newc_mode_offset 14
-#define newc_mode_size 8
-#define newc_uid_offset 22
-#define newc_uid_size 8
-#define newc_gid_offset 30
-#define newc_gid_size 8
-#define newc_nlink_offset 38
-#define newc_nlink_size 8
-#define newc_mtime_offset 46
-#define newc_mtime_size 8
-#define newc_filesize_offset 54
-#define newc_filesize_size 8
-#define newc_devmajor_offset 62
-#define newc_devmajor_size 8
-#define newc_devminor_offset 70
-#define newc_devminor_size 8
-#define newc_rdevmajor_offset 78
-#define newc_rdevmajor_size 8
-#define newc_rdevminor_offset 86
-#define newc_rdevminor_size 8
-#define newc_namesize_offset 94
-#define newc_namesize_size 8
-#define newc_checksum_offset 102
-#define newc_checksum_size 8
-#define newc_header_size 110
-
-/*
- * An afio large ASCII header, which they named itself.
- * afio utility uses this header, if a file size is larger than 2G bytes
- * or inode/uid/gid is bigger than 65535(0xFFFF) or mtime is bigger than
- * 0x7fffffff, which we cannot record to odc header because of its limit.
- * If not, uses odc header.
- */
-#define afiol_magic_offset 0
-#define afiol_magic_size 6
-#define afiol_dev_offset 6
-#define afiol_dev_size 8 /* hex */
-#define afiol_ino_offset 14
-#define afiol_ino_size 16 /* hex */
-#define afiol_ino_m_offset 30 /* 'm' */
-#define afiol_mode_offset 31
-#define afiol_mode_size 6 /* oct */
-#define afiol_uid_offset 37
-#define afiol_uid_size 8 /* hex */
-#define afiol_gid_offset 45
-#define afiol_gid_size 8 /* hex */
-#define afiol_nlink_offset 53
-#define afiol_nlink_size 8 /* hex */
-#define afiol_rdev_offset 61
-#define afiol_rdev_size 8 /* hex */
-#define afiol_mtime_offset 69
-#define afiol_mtime_size 16 /* hex */
-#define afiol_mtime_n_offset 85 /* 'n' */
-#define afiol_namesize_offset 86
-#define afiol_namesize_size 4 /* hex */
-#define afiol_flag_offset 90
-#define afiol_flag_size 4 /* hex */
-#define afiol_xsize_offset 94
-#define afiol_xsize_size 4 /* hex */
-#define afiol_xsize_s_offset 98 /* 's' */
-#define afiol_filesize_offset 99
-#define afiol_filesize_size 16 /* hex */
-#define afiol_filesize_c_offset 115 /* ':' */
-#define afiol_header_size 116
-
-
-struct links_entry {
- struct links_entry *next;
- struct links_entry *previous;
- unsigned int links;
- dev_t dev;
- int64_t ino;
- char *name;
-};
-
-#define CPIO_MAGIC 0x13141516
-struct cpio {
- int magic;
- int (*read_header)(struct archive_read *, struct cpio *,
- struct archive_entry *, size_t *, size_t *);
- struct links_entry *links_head;
- int64_t entry_bytes_remaining;
- int64_t entry_bytes_unconsumed;
- int64_t entry_offset;
- int64_t entry_padding;
-
- struct archive_string_conv *opt_sconv;
- struct archive_string_conv *sconv_default;
- int init_default_conversion;
-
- int option_pwb;
-};
-
-static int64_t atol16(const char *, unsigned);
-static int64_t atol8(const char *, unsigned);
-static int archive_read_format_cpio_bid(struct archive_read *, int);
-static int archive_read_format_cpio_options(struct archive_read *,
- const char *, const char *);
-static int archive_read_format_cpio_cleanup(struct archive_read *);
-static int archive_read_format_cpio_read_data(struct archive_read *,
- const void **, size_t *, int64_t *);
-static int archive_read_format_cpio_read_header(struct archive_read *,
- struct archive_entry *);
-static int archive_read_format_cpio_skip(struct archive_read *);
-static int64_t be4(const unsigned char *);
-static int find_odc_header(struct archive_read *);
-static int find_newc_header(struct archive_read *);
-static int header_bin_be(struct archive_read *, struct cpio *,
- struct archive_entry *, size_t *, size_t *);
-static int header_bin_le(struct archive_read *, struct cpio *,
- struct archive_entry *, size_t *, size_t *);
-static int header_newc(struct archive_read *, struct cpio *,
- struct archive_entry *, size_t *, size_t *);
-static int header_odc(struct archive_read *, struct cpio *,
- struct archive_entry *, size_t *, size_t *);
-static int header_afiol(struct archive_read *, struct cpio *,
- struct archive_entry *, size_t *, size_t *);
-static int is_octal(const char *, size_t);
-static int is_hex(const char *, size_t);
-static int64_t le4(const unsigned char *);
-static int record_hardlink(struct archive_read *a,
- struct cpio *cpio, struct archive_entry *entry);
-
-int
-archive_read_support_format_cpio(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- struct cpio *cpio;
- int r;
-
- archive_check_magic(_a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_format_cpio");
-
- cpio = (struct cpio *)calloc(1, sizeof(*cpio));
- if (cpio == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data");
- return (ARCHIVE_FATAL);
- }
- cpio->magic = CPIO_MAGIC;
-
- r = __archive_read_register_format(a,
- cpio,
- "cpio",
- archive_read_format_cpio_bid,
- archive_read_format_cpio_options,
- archive_read_format_cpio_read_header,
- archive_read_format_cpio_read_data,
- archive_read_format_cpio_skip,
- NULL,
- archive_read_format_cpio_cleanup,
- NULL,
- NULL);
-
- if (r != ARCHIVE_OK)
- free(cpio);
- return (ARCHIVE_OK);
-}
-
-
-static int
-archive_read_format_cpio_bid(struct archive_read *a, int best_bid)
-{
- const unsigned char *p;
- struct cpio *cpio;
- int bid;
-
- (void)best_bid; /* UNUSED */
-
- cpio = (struct cpio *)(a->format->data);
-
- if ((p = __archive_read_ahead(a, 6, NULL)) == NULL)
- return (-1);
-
- bid = 0;
- if (memcmp(p, "070707", 6) == 0) {
- /* ASCII cpio archive (odc, POSIX.1) */
- cpio->read_header = header_odc;
- bid += 48;
- /*
- * XXX TODO: More verification; Could check that only octal
- * digits appear in appropriate header locations. XXX
- */
- } else if (memcmp(p, "070727", 6) == 0) {
- /* afio large ASCII cpio archive */
- cpio->read_header = header_odc;
- bid += 48;
- /*
- * XXX TODO: More verification; Could check that almost hex
- * digits appear in appropriate header locations. XXX
- */
- } else if (memcmp(p, "070701", 6) == 0) {
- /* ASCII cpio archive (SVR4 without CRC) */
- cpio->read_header = header_newc;
- bid += 48;
- /*
- * XXX TODO: More verification; Could check that only hex
- * digits appear in appropriate header locations. XXX
- */
- } else if (memcmp(p, "070702", 6) == 0) {
- /* ASCII cpio archive (SVR4 with CRC) */
- /* XXX TODO: Flag that we should check the CRC. XXX */
- cpio->read_header = header_newc;
- bid += 48;
- /*
- * XXX TODO: More verification; Could check that only hex
- * digits appear in appropriate header locations. XXX
- */
- } else if (p[0] * 256 + p[1] == 070707) {
- /* big-endian binary cpio archives */
- cpio->read_header = header_bin_be;
- bid += 16;
- /* Is more verification possible here? */
- } else if (p[0] + p[1] * 256 == 070707) {
- /* little-endian binary cpio archives */
- cpio->read_header = header_bin_le;
- bid += 16;
- /* Is more verification possible here? */
- } else
- return (ARCHIVE_WARN);
-
- return (bid);
-}
-
-static int
-archive_read_format_cpio_options(struct archive_read *a,
- const char *key, const char *val)
-{
- struct cpio *cpio;
- int ret = ARCHIVE_FAILED;
-
- cpio = (struct cpio *)(a->format->data);
- if (strcmp(key, "compat-2x") == 0) {
- /* Handle filenames as libarchive 2.x */
- cpio->init_default_conversion = (val != NULL)?1:0;
- return (ARCHIVE_OK);
- } else if (strcmp(key, "hdrcharset") == 0) {
- if (val == NULL || val[0] == 0)
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "cpio: hdrcharset option needs a character-set name");
- else {
- cpio->opt_sconv =
- archive_string_conversion_from_charset(
- &a->archive, val, 0);
- if (cpio->opt_sconv != NULL)
- ret = ARCHIVE_OK;
- else
- ret = ARCHIVE_FATAL;
- }
- return (ret);
- } else if (strcmp(key, "pwb") == 0) {
- if (val != NULL && val[0] != 0)
- cpio->option_pwb = 1;
- return (ARCHIVE_OK);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-static int
-archive_read_format_cpio_read_header(struct archive_read *a,
- struct archive_entry *entry)
-{
- struct cpio *cpio;
- const void *h, *hl;
- struct archive_string_conv *sconv;
- size_t namelength;
- size_t name_pad;
- int r;
-
- cpio = (struct cpio *)(a->format->data);
- sconv = cpio->opt_sconv;
- if (sconv == NULL) {
- if (!cpio->init_default_conversion) {
- cpio->sconv_default =
- archive_string_default_conversion_for_read(
- &(a->archive));
- cpio->init_default_conversion = 1;
- }
- sconv = cpio->sconv_default;
- }
-
- r = (cpio->read_header(a, cpio, entry, &namelength, &name_pad));
-
- if (r < ARCHIVE_WARN)
- return (r);
-
- /* Read name from buffer. */
- h = __archive_read_ahead(a, namelength + name_pad, NULL);
- if (h == NULL)
- return (ARCHIVE_FATAL);
- if (archive_entry_copy_pathname_l(entry,
- (const char *)h, namelength, sconv) != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Pathname can't be converted from %s to current locale.",
- archive_string_conversion_charset_name(sconv));
- r = ARCHIVE_WARN;
- }
- cpio->entry_offset = 0;
-
- __archive_read_consume(a, namelength + name_pad);
-
- /* If this is a symlink, read the link contents. */
- if (archive_entry_filetype(entry) == AE_IFLNK) {
- if (cpio->entry_bytes_remaining > 1024 * 1024) {
- archive_set_error(&a->archive, ENOMEM,
- "Rejecting malformed cpio archive: symlink contents exceed 1 megabyte");
- return (ARCHIVE_FATAL);
- }
- hl = __archive_read_ahead(a,
- (size_t)cpio->entry_bytes_remaining, NULL);
- if (hl == NULL)
- return (ARCHIVE_FATAL);
- if (archive_entry_copy_symlink_l(entry, (const char *)hl,
- (size_t)cpio->entry_bytes_remaining, sconv) != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Linkname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Linkname can't be converted from %s to "
- "current locale.",
- archive_string_conversion_charset_name(sconv));
- r = ARCHIVE_WARN;
- }
- __archive_read_consume(a, cpio->entry_bytes_remaining);
- cpio->entry_bytes_remaining = 0;
- }
-
- /* XXX TODO: If the full mode is 0160200, then this is a Solaris
- * ACL description for the following entry. Read this body
- * and parse it as a Solaris-style ACL, then read the next
- * header. XXX */
-
- /* Compare name to "TRAILER!!!" to test for end-of-archive. */
- if (namelength == 11 && strncmp((const char *)h, "TRAILER!!!",
- 10) == 0) {
- /* TODO: Store file location of start of block. */
- archive_clear_error(&a->archive);
- return (ARCHIVE_EOF);
- }
-
- /* Detect and record hardlinks to previously-extracted entries. */
- if (record_hardlink(a, cpio, entry) != ARCHIVE_OK) {
- return (ARCHIVE_FATAL);
- }
-
- return (r);
-}
-
-static int
-archive_read_format_cpio_read_data(struct archive_read *a,
- const void **buff, size_t *size, int64_t *offset)
-{
- ssize_t bytes_read;
- struct cpio *cpio;
-
- cpio = (struct cpio *)(a->format->data);
-
- if (cpio->entry_bytes_unconsumed) {
- __archive_read_consume(a, cpio->entry_bytes_unconsumed);
- cpio->entry_bytes_unconsumed = 0;
- }
-
- if (cpio->entry_bytes_remaining > 0) {
- *buff = __archive_read_ahead(a, 1, &bytes_read);
- if (bytes_read <= 0)
- return (ARCHIVE_FATAL);
- if (bytes_read > cpio->entry_bytes_remaining)
- bytes_read = (ssize_t)cpio->entry_bytes_remaining;
- *size = bytes_read;
- cpio->entry_bytes_unconsumed = bytes_read;
- *offset = cpio->entry_offset;
- cpio->entry_offset += bytes_read;
- cpio->entry_bytes_remaining -= bytes_read;
- return (ARCHIVE_OK);
- } else {
- if (cpio->entry_padding !=
- __archive_read_consume(a, cpio->entry_padding)) {
- return (ARCHIVE_FATAL);
- }
- cpio->entry_padding = 0;
- *buff = NULL;
- *size = 0;
- *offset = cpio->entry_offset;
- return (ARCHIVE_EOF);
- }
-}
-
-static int
-archive_read_format_cpio_skip(struct archive_read *a)
-{
- struct cpio *cpio = (struct cpio *)(a->format->data);
- int64_t to_skip = cpio->entry_bytes_remaining + cpio->entry_padding +
- cpio->entry_bytes_unconsumed;
-
- if (to_skip != __archive_read_consume(a, to_skip)) {
- return (ARCHIVE_FATAL);
- }
- cpio->entry_bytes_remaining = 0;
- cpio->entry_padding = 0;
- cpio->entry_bytes_unconsumed = 0;
- return (ARCHIVE_OK);
-}
-
-/*
- * Skip forward to the next cpio newc header by searching for the
- * 07070[12] string. This should be generalized and merged with
- * find_odc_header below.
- */
-static int
-is_hex(const char *p, size_t len)
-{
- while (len-- > 0) {
- if ((*p >= '0' && *p <= '9')
- || (*p >= 'a' && *p <= 'f')
- || (*p >= 'A' && *p <= 'F'))
- ++p;
- else
- return (0);
- }
- return (1);
-}
-
-static int
-find_newc_header(struct archive_read *a)
-{
- const void *h;
- const char *p, *q;
- size_t skip, skipped = 0;
- ssize_t bytes;
-
- for (;;) {
- h = __archive_read_ahead(a, newc_header_size, &bytes);
- if (h == NULL)
- return (ARCHIVE_FATAL);
- p = h;
- q = p + bytes;
-
- /* Try the typical case first, then go into the slow search.*/
- if (memcmp("07070", p, 5) == 0
- && (p[5] == '1' || p[5] == '2')
- && is_hex(p, newc_header_size))
- return (ARCHIVE_OK);
-
- /*
- * Scan ahead until we find something that looks
- * like a newc header.
- */
- while (p + newc_header_size <= q) {
- switch (p[5]) {
- case '1':
- case '2':
- if (memcmp("07070", p, 5) == 0
- && is_hex(p, newc_header_size)) {
- skip = p - (const char *)h;
- __archive_read_consume(a, skip);
- skipped += skip;
- if (skipped > 0) {
- archive_set_error(&a->archive,
- 0,
- "Skipped %d bytes before "
- "finding valid header",
- (int)skipped);
- return (ARCHIVE_WARN);
- }
- return (ARCHIVE_OK);
- }
- p += 2;
- break;
- case '0':
- p++;
- break;
- default:
- p += 6;
- break;
- }
- }
- skip = p - (const char *)h;
- __archive_read_consume(a, skip);
- skipped += skip;
- }
-}
-
-static int
-header_newc(struct archive_read *a, struct cpio *cpio,
- struct archive_entry *entry, size_t *namelength, size_t *name_pad)
-{
- const void *h;
- const char *header;
- int r;
-
- r = find_newc_header(a);
- if (r < ARCHIVE_WARN)
- return (r);
-
- /* Read fixed-size portion of header. */
- h = __archive_read_ahead(a, newc_header_size, NULL);
- if (h == NULL)
- return (ARCHIVE_FATAL);
-
- /* Parse out hex fields. */
- header = (const char *)h;
-
- if (memcmp(header + newc_magic_offset, "070701", 6) == 0) {
- a->archive.archive_format = ARCHIVE_FORMAT_CPIO_SVR4_NOCRC;
- a->archive.archive_format_name = "ASCII cpio (SVR4 with no CRC)";
- } else if (memcmp(header + newc_magic_offset, "070702", 6) == 0) {
- a->archive.archive_format = ARCHIVE_FORMAT_CPIO_SVR4_CRC;
- a->archive.archive_format_name = "ASCII cpio (SVR4 with CRC)";
- } else {
- /* TODO: Abort here? */
- }
-
- archive_entry_set_devmajor(entry,
- (dev_t)atol16(header + newc_devmajor_offset, newc_devmajor_size));
- archive_entry_set_devminor(entry,
- (dev_t)atol16(header + newc_devminor_offset, newc_devminor_size));
- archive_entry_set_ino(entry, atol16(header + newc_ino_offset, newc_ino_size));
- archive_entry_set_mode(entry,
- (mode_t)atol16(header + newc_mode_offset, newc_mode_size));
- archive_entry_set_uid(entry, atol16(header + newc_uid_offset, newc_uid_size));
- archive_entry_set_gid(entry, atol16(header + newc_gid_offset, newc_gid_size));
- archive_entry_set_nlink(entry,
- (unsigned int)atol16(header + newc_nlink_offset, newc_nlink_size));
- archive_entry_set_rdevmajor(entry,
- (dev_t)atol16(header + newc_rdevmajor_offset, newc_rdevmajor_size));
- archive_entry_set_rdevminor(entry,
- (dev_t)atol16(header + newc_rdevminor_offset, newc_rdevminor_size));
- archive_entry_set_mtime(entry, atol16(header + newc_mtime_offset, newc_mtime_size), 0);
- *namelength = (size_t)atol16(header + newc_namesize_offset, newc_namesize_size);
- /* Pad name to 2 more than a multiple of 4. */
- *name_pad = (2 - *namelength) & 3;
-
- /* Make sure that the padded name length fits into size_t. */
- if (*name_pad > SIZE_MAX - *namelength) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "cpio archive has invalid namelength");
- return (ARCHIVE_FATAL);
- }
-
- /*
- * Note: entry_bytes_remaining is at least 64 bits and
- * therefore guaranteed to be big enough for a 33-bit file
- * size.
- */
- cpio->entry_bytes_remaining =
- atol16(header + newc_filesize_offset, newc_filesize_size);
- archive_entry_set_size(entry, cpio->entry_bytes_remaining);
- /* Pad file contents to a multiple of 4. */
- cpio->entry_padding = 3 & -cpio->entry_bytes_remaining;
- __archive_read_consume(a, newc_header_size);
- return (r);
-}
-
-/*
- * Skip forward to the next cpio odc header by searching for the
- * 070707 string. This is a hand-optimized search that could
- * probably be easily generalized to handle all character-based
- * cpio variants.
- */
-static int
-is_octal(const char *p, size_t len)
-{
- while (len-- > 0) {
- if (*p < '0' || *p > '7')
- return (0);
- ++p;
- }
- return (1);
-}
-
-static int
-is_afio_large(const char *h, size_t len)
-{
- if (len < afiol_header_size)
- return (0);
- if (h[afiol_ino_m_offset] != 'm'
- || h[afiol_mtime_n_offset] != 'n'
- || h[afiol_xsize_s_offset] != 's'
- || h[afiol_filesize_c_offset] != ':')
- return (0);
- if (!is_hex(h + afiol_dev_offset, afiol_ino_m_offset - afiol_dev_offset))
- return (0);
- if (!is_hex(h + afiol_mode_offset, afiol_mtime_n_offset - afiol_mode_offset))
- return (0);
- if (!is_hex(h + afiol_namesize_offset, afiol_xsize_s_offset - afiol_namesize_offset))
- return (0);
- if (!is_hex(h + afiol_filesize_offset, afiol_filesize_size))
- return (0);
- return (1);
-}
-
-static int
-find_odc_header(struct archive_read *a)
-{
- const void *h;
- const char *p, *q;
- size_t skip, skipped = 0;
- ssize_t bytes;
-
- for (;;) {
- h = __archive_read_ahead(a, odc_header_size, &bytes);
- if (h == NULL)
- return (ARCHIVE_FATAL);
- p = h;
- q = p + bytes;
-
- /* Try the typical case first, then go into the slow search.*/
- if (memcmp("070707", p, 6) == 0 && is_octal(p, odc_header_size))
- return (ARCHIVE_OK);
- if (memcmp("070727", p, 6) == 0 && is_afio_large(p, bytes)) {
- a->archive.archive_format = ARCHIVE_FORMAT_CPIO_AFIO_LARGE;
- return (ARCHIVE_OK);
- }
-
- /*
- * Scan ahead until we find something that looks
- * like an odc header.
- */
- while (p + odc_header_size <= q) {
- switch (p[5]) {
- case '7':
- if ((memcmp("070707", p, 6) == 0
- && is_octal(p, odc_header_size))
- || (memcmp("070727", p, 6) == 0
- && is_afio_large(p, q - p))) {
- skip = p - (const char *)h;
- __archive_read_consume(a, skip);
- skipped += skip;
- if (p[4] == '2')
- a->archive.archive_format =
- ARCHIVE_FORMAT_CPIO_AFIO_LARGE;
- if (skipped > 0) {
- archive_set_error(&a->archive,
- 0,
- "Skipped %d bytes before "
- "finding valid header",
- (int)skipped);
- return (ARCHIVE_WARN);
- }
- return (ARCHIVE_OK);
- }
- p += 2;
- break;
- case '0':
- p++;
- break;
- default:
- p += 6;
- break;
- }
- }
- skip = p - (const char *)h;
- __archive_read_consume(a, skip);
- skipped += skip;
- }
-}
-
-static int
-header_odc(struct archive_read *a, struct cpio *cpio,
- struct archive_entry *entry, size_t *namelength, size_t *name_pad)
-{
- const void *h;
- int r;
- const char *header;
-
- a->archive.archive_format = ARCHIVE_FORMAT_CPIO_POSIX;
- a->archive.archive_format_name = "POSIX octet-oriented cpio";
-
- /* Find the start of the next header. */
- r = find_odc_header(a);
- if (r < ARCHIVE_WARN)
- return (r);
-
- if (a->archive.archive_format == ARCHIVE_FORMAT_CPIO_AFIO_LARGE) {
- int r2 = (header_afiol(a, cpio, entry, namelength, name_pad));
- if (r2 == ARCHIVE_OK)
- return (r);
- else
- return (r2);
- }
-
- /* Read fixed-size portion of header. */
- h = __archive_read_ahead(a, odc_header_size, NULL);
- if (h == NULL)
- return (ARCHIVE_FATAL);
-
- /* Parse out octal fields. */
- header = (const char *)h;
-
- archive_entry_set_dev(entry,
- (dev_t)atol8(header + odc_dev_offset, odc_dev_size));
- archive_entry_set_ino(entry, atol8(header + odc_ino_offset, odc_ino_size));
- archive_entry_set_mode(entry,
- (mode_t)atol8(header + odc_mode_offset, odc_mode_size));
- archive_entry_set_uid(entry, atol8(header + odc_uid_offset, odc_uid_size));
- archive_entry_set_gid(entry, atol8(header + odc_gid_offset, odc_gid_size));
- archive_entry_set_nlink(entry,
- (unsigned int)atol8(header + odc_nlink_offset, odc_nlink_size));
- archive_entry_set_rdev(entry,
- (dev_t)atol8(header + odc_rdev_offset, odc_rdev_size));
- archive_entry_set_mtime(entry, atol8(header + odc_mtime_offset, odc_mtime_size), 0);
- *namelength = (size_t)atol8(header + odc_namesize_offset, odc_namesize_size);
- *name_pad = 0; /* No padding of filename. */
-
- /*
- * Note: entry_bytes_remaining is at least 64 bits and
- * therefore guaranteed to be big enough for a 33-bit file
- * size.
- */
- cpio->entry_bytes_remaining =
- atol8(header + odc_filesize_offset, odc_filesize_size);
- archive_entry_set_size(entry, cpio->entry_bytes_remaining);
- cpio->entry_padding = 0;
- __archive_read_consume(a, odc_header_size);
- return (r);
-}
-
-/*
- * NOTE: if a filename suffix is ".z", it is the file gziped by afio.
- * it would be nice that we can show uncompressed file size and we can
- * uncompressed file contents automatically, unfortunately we have nothing
- * to get a uncompressed file size while reading each header. It means
- * we also cannot uncompress file contents under our framework.
- */
-static int
-header_afiol(struct archive_read *a, struct cpio *cpio,
- struct archive_entry *entry, size_t *namelength, size_t *name_pad)
-{
- const void *h;
- const char *header;
-
- a->archive.archive_format = ARCHIVE_FORMAT_CPIO_AFIO_LARGE;
- a->archive.archive_format_name = "afio large ASCII";
-
- /* Read fixed-size portion of header. */
- h = __archive_read_ahead(a, afiol_header_size, NULL);
- if (h == NULL)
- return (ARCHIVE_FATAL);
-
- /* Parse out octal fields. */
- header = (const char *)h;
-
- archive_entry_set_dev(entry,
- (dev_t)atol16(header + afiol_dev_offset, afiol_dev_size));
- archive_entry_set_ino(entry, atol16(header + afiol_ino_offset, afiol_ino_size));
- archive_entry_set_mode(entry,
- (mode_t)atol8(header + afiol_mode_offset, afiol_mode_size));
- archive_entry_set_uid(entry, atol16(header + afiol_uid_offset, afiol_uid_size));
- archive_entry_set_gid(entry, atol16(header + afiol_gid_offset, afiol_gid_size));
- archive_entry_set_nlink(entry,
- (unsigned int)atol16(header + afiol_nlink_offset, afiol_nlink_size));
- archive_entry_set_rdev(entry,
- (dev_t)atol16(header + afiol_rdev_offset, afiol_rdev_size));
- archive_entry_set_mtime(entry, atol16(header + afiol_mtime_offset, afiol_mtime_size), 0);
- *namelength = (size_t)atol16(header + afiol_namesize_offset, afiol_namesize_size);
- *name_pad = 0; /* No padding of filename. */
-
- cpio->entry_bytes_remaining =
- atol16(header + afiol_filesize_offset, afiol_filesize_size);
- archive_entry_set_size(entry, cpio->entry_bytes_remaining);
- cpio->entry_padding = 0;
- __archive_read_consume(a, afiol_header_size);
- return (ARCHIVE_OK);
-}
-
-
-static int
-header_bin_le(struct archive_read *a, struct cpio *cpio,
- struct archive_entry *entry, size_t *namelength, size_t *name_pad)
-{
- const void *h;
- const unsigned char *header;
-
- a->archive.archive_format = ARCHIVE_FORMAT_CPIO_BIN_LE;
- a->archive.archive_format_name = "cpio (little-endian binary)";
-
- /* Read fixed-size portion of header. */
- h = __archive_read_ahead(a, bin_header_size, NULL);
- if (h == NULL) {
- archive_set_error(&a->archive, 0,
- "End of file trying to read next cpio header");
- return (ARCHIVE_FATAL);
- }
-
- /* Parse out binary fields. */
- header = (const unsigned char *)h;
-
- archive_entry_set_dev(entry, header[bin_dev_offset] + header[bin_dev_offset + 1] * 256);
- archive_entry_set_ino(entry, header[bin_ino_offset] + header[bin_ino_offset + 1] * 256);
- archive_entry_set_mode(entry, header[bin_mode_offset] + header[bin_mode_offset + 1] * 256);
- if (cpio->option_pwb) {
- /* turn off random bits left over from V6 inode */
- archive_entry_set_mode(entry, archive_entry_mode(entry) & 067777);
- if ((archive_entry_mode(entry) & AE_IFMT) == 0)
- archive_entry_set_mode(entry, archive_entry_mode(entry) | AE_IFREG);
- }
- archive_entry_set_uid(entry, header[bin_uid_offset] + header[bin_uid_offset + 1] * 256);
- archive_entry_set_gid(entry, header[bin_gid_offset] + header[bin_gid_offset + 1] * 256);
- archive_entry_set_nlink(entry, header[bin_nlink_offset] + header[bin_nlink_offset + 1] * 256);
- archive_entry_set_rdev(entry, header[bin_rdev_offset] + header[bin_rdev_offset + 1] * 256);
- archive_entry_set_mtime(entry, le4(header + bin_mtime_offset), 0);
- *namelength = header[bin_namesize_offset] + header[bin_namesize_offset + 1] * 256;
- *name_pad = *namelength & 1; /* Pad to even. */
-
- cpio->entry_bytes_remaining = le4(header + bin_filesize_offset);
- archive_entry_set_size(entry, cpio->entry_bytes_remaining);
- cpio->entry_padding = cpio->entry_bytes_remaining & 1; /* Pad to even. */
- __archive_read_consume(a, bin_header_size);
- return (ARCHIVE_OK);
-}
-
-static int
-header_bin_be(struct archive_read *a, struct cpio *cpio,
- struct archive_entry *entry, size_t *namelength, size_t *name_pad)
-{
- const void *h;
- const unsigned char *header;
-
- a->archive.archive_format = ARCHIVE_FORMAT_CPIO_BIN_BE;
- a->archive.archive_format_name = "cpio (big-endian binary)";
-
- /* Read fixed-size portion of header. */
- h = __archive_read_ahead(a, bin_header_size, NULL);
- if (h == NULL) {
- archive_set_error(&a->archive, 0,
- "End of file trying to read next cpio header");
- return (ARCHIVE_FATAL);
- }
-
- /* Parse out binary fields. */
- header = (const unsigned char *)h;
-
- archive_entry_set_dev(entry, header[bin_dev_offset] * 256 + header[bin_dev_offset + 1]);
- archive_entry_set_ino(entry, header[bin_ino_offset] * 256 + header[bin_ino_offset + 1]);
- archive_entry_set_mode(entry, header[bin_mode_offset] * 256 + header[bin_mode_offset + 1]);
- if (cpio->option_pwb) {
- /* turn off random bits left over from V6 inode */
- archive_entry_set_mode(entry, archive_entry_mode(entry) & 067777);
- if ((archive_entry_mode(entry) & AE_IFMT) == 0)
- archive_entry_set_mode(entry, archive_entry_mode(entry) | AE_IFREG);
- }
- archive_entry_set_uid(entry, header[bin_uid_offset] * 256 + header[bin_uid_offset + 1]);
- archive_entry_set_gid(entry, header[bin_gid_offset] * 256 + header[bin_gid_offset + 1]);
- archive_entry_set_nlink(entry, header[bin_nlink_offset] * 256 + header[bin_nlink_offset + 1]);
- archive_entry_set_rdev(entry, header[bin_rdev_offset] * 256 + header[bin_rdev_offset + 1]);
- archive_entry_set_mtime(entry, be4(header + bin_mtime_offset), 0);
- *namelength = header[bin_namesize_offset] * 256 + header[bin_namesize_offset + 1];
- *name_pad = *namelength & 1; /* Pad to even. */
-
- cpio->entry_bytes_remaining = be4(header + bin_filesize_offset);
- archive_entry_set_size(entry, cpio->entry_bytes_remaining);
- cpio->entry_padding = cpio->entry_bytes_remaining & 1; /* Pad to even. */
- __archive_read_consume(a, bin_header_size);
- return (ARCHIVE_OK);
-}
-
-static int
-archive_read_format_cpio_cleanup(struct archive_read *a)
-{
- struct cpio *cpio;
-
- cpio = (struct cpio *)(a->format->data);
- /* Free inode->name map */
- while (cpio->links_head != NULL) {
- struct links_entry *lp = cpio->links_head->next;
-
- free(cpio->links_head->name);
- free(cpio->links_head);
- cpio->links_head = lp;
- }
- free(cpio);
- (a->format->data) = NULL;
- return (ARCHIVE_OK);
-}
-
-static int64_t
-le4(const unsigned char *p)
-{
- return ((p[0] << 16) | (((int64_t)p[1]) << 24) | (p[2] << 0) | (p[3] << 8));
-}
-
-
-static int64_t
-be4(const unsigned char *p)
-{
- return ((((int64_t)p[0]) << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]));
-}
-
-/*
- * Note that this implementation does not (and should not!) obey
- * locale settings; you cannot simply substitute strtol here, since
- * it does obey locale.
- */
-static int64_t
-atol8(const char *p, unsigned char_cnt)
-{
- int64_t l;
- int digit;
-
- l = 0;
- while (char_cnt-- > 0) {
- if (*p >= '0' && *p <= '7')
- digit = *p - '0';
- else
- return (l);
- p++;
- l <<= 3;
- l |= digit;
- }
- return (l);
-}
-
-static int64_t
-atol16(const char *p, unsigned char_cnt)
-{
- int64_t l;
- int digit;
-
- l = 0;
- while (char_cnt-- > 0) {
- if (*p >= 'a' && *p <= 'f')
- digit = *p - 'a' + 10;
- else if (*p >= 'A' && *p <= 'F')
- digit = *p - 'A' + 10;
- else if (*p >= '0' && *p <= '9')
- digit = *p - '0';
- else
- return (l);
- p++;
- l <<= 4;
- l |= digit;
- }
- return (l);
-}
-
-static int
-record_hardlink(struct archive_read *a,
- struct cpio *cpio, struct archive_entry *entry)
-{
- struct links_entry *le;
- dev_t dev;
- int64_t ino;
-
- if (archive_entry_nlink(entry) <= 1)
- return (ARCHIVE_OK);
-
- dev = archive_entry_dev(entry);
- ino = archive_entry_ino64(entry);
-
- /*
- * First look in the list of multiply-linked files. If we've
- * already dumped it, convert this entry to a hard link entry.
- */
- for (le = cpio->links_head; le; le = le->next) {
- if (le->dev == dev && le->ino == ino) {
- archive_entry_copy_hardlink(entry, le->name);
-
- if (--le->links <= 0) {
- if (le->previous != NULL)
- le->previous->next = le->next;
- if (le->next != NULL)
- le->next->previous = le->previous;
- if (cpio->links_head == le)
- cpio->links_head = le->next;
- free(le->name);
- free(le);
- }
-
- return (ARCHIVE_OK);
- }
- }
-
- le = (struct links_entry *)malloc(sizeof(struct links_entry));
- if (le == NULL) {
- archive_set_error(&a->archive,
- ENOMEM, "Out of memory adding file to list");
- return (ARCHIVE_FATAL);
- }
- if (cpio->links_head != NULL)
- cpio->links_head->previous = le;
- le->next = cpio->links_head;
- le->previous = NULL;
- cpio->links_head = le;
- le->dev = dev;
- le->ino = ino;
- le->links = archive_entry_nlink(entry) - 1;
- le->name = strdup(archive_entry_pathname(entry));
- if (le->name == NULL) {
- archive_set_error(&a->archive,
- ENOMEM, "Out of memory adding file to list");
- return (ARCHIVE_FATAL);
- }
-
- return (ARCHIVE_OK);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_format_empty.c b/contrib/libs/libarchive/libarchive/archive_read_support_format_empty.c
deleted file mode 100644
index 53fb6cc474..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_format_empty.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_empty.c 191524 2009-04-26 18:24:14Z kientzle $");
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-static int archive_read_format_empty_bid(struct archive_read *, int);
-static int archive_read_format_empty_read_data(struct archive_read *,
- const void **, size_t *, int64_t *);
-static int archive_read_format_empty_read_header(struct archive_read *,
- struct archive_entry *);
-int
-archive_read_support_format_empty(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- int r;
-
- archive_check_magic(_a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_format_empty");
-
- r = __archive_read_register_format(a,
- NULL,
- "empty",
- archive_read_format_empty_bid,
- NULL,
- archive_read_format_empty_read_header,
- archive_read_format_empty_read_data,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL);
-
- return (r);
-}
-
-
-static int
-archive_read_format_empty_bid(struct archive_read *a, int best_bid)
-{
- if (best_bid < 1 && __archive_read_ahead(a, 1, NULL) == NULL)
- return (1);
- return (-1);
-}
-
-static int
-archive_read_format_empty_read_header(struct archive_read *a,
- struct archive_entry *entry)
-{
- (void)a; /* UNUSED */
- (void)entry; /* UNUSED */
-
- a->archive.archive_format = ARCHIVE_FORMAT_EMPTY;
- a->archive.archive_format_name = "Empty file";
-
- return (ARCHIVE_EOF);
-}
-
-static int
-archive_read_format_empty_read_data(struct archive_read *a,
- const void **buff, size_t *size, int64_t *offset)
-{
- (void)a; /* UNUSED */
- (void)buff; /* UNUSED */
- (void)size; /* UNUSED */
- (void)offset; /* UNUSED */
-
- return (ARCHIVE_EOF);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_format_iso9660.c b/contrib/libs/libarchive/libarchive/archive_read_support_format_iso9660.c
deleted file mode 100644
index f5414be2a5..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_format_iso9660.c
+++ /dev/null
@@ -1,3279 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * Copyright (c) 2009 Andreas Henriksson <andreas@fatal.se>
- * Copyright (c) 2009-2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_iso9660.c 201246 2009-12-30 05:30:35Z kientzle $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-/* #include <stdint.h> */ /* See archive_platform.h */
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#include <time.h>
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-
-#include "archive.h"
-#include "archive_endian.h"
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-#include "archive_string.h"
-
-/*
- * An overview of ISO 9660 format:
- *
- * Each disk is laid out as follows:
- * * 32k reserved for private use
- * * Volume descriptor table. Each volume descriptor
- * is 2k and specifies basic format information.
- * The "Primary Volume Descriptor" (PVD) is defined by the
- * standard and should always be present; other volume
- * descriptors include various vendor-specific extensions.
- * * Files and directories. Each file/dir is specified by
- * an "extent" (starting sector and length in bytes).
- * Dirs are just files with directory records packed one
- * after another. The PVD contains a single dir entry
- * specifying the location of the root directory. Everything
- * else follows from there.
- *
- * This module works by first reading the volume descriptors, then
- * building a list of directory entries, sorted by starting
- * sector. At each step, I look for the earliest dir entry that
- * hasn't yet been read, seek forward to that location and read
- * that entry. If it's a dir, I slurp in the new dir entries and
- * add them to the heap; if it's a regular file, I return the
- * corresponding archive_entry and wait for the client to request
- * the file body. This strategy allows us to read most compliant
- * CDs with a single pass through the data, as required by libarchive.
- */
-#define LOGICAL_BLOCK_SIZE 2048
-#define SYSTEM_AREA_BLOCK 16
-
-/* Structure of on-disk primary volume descriptor. */
-#define PVD_type_offset 0
-#define PVD_type_size 1
-#define PVD_id_offset (PVD_type_offset + PVD_type_size)
-#define PVD_id_size 5
-#define PVD_version_offset (PVD_id_offset + PVD_id_size)
-#define PVD_version_size 1
-#define PVD_reserved1_offset (PVD_version_offset + PVD_version_size)
-#define PVD_reserved1_size 1
-#define PVD_system_id_offset (PVD_reserved1_offset + PVD_reserved1_size)
-#define PVD_system_id_size 32
-#define PVD_volume_id_offset (PVD_system_id_offset + PVD_system_id_size)
-#define PVD_volume_id_size 32
-#define PVD_reserved2_offset (PVD_volume_id_offset + PVD_volume_id_size)
-#define PVD_reserved2_size 8
-#define PVD_volume_space_size_offset (PVD_reserved2_offset + PVD_reserved2_size)
-#define PVD_volume_space_size_size 8
-#define PVD_reserved3_offset (PVD_volume_space_size_offset + PVD_volume_space_size_size)
-#define PVD_reserved3_size 32
-#define PVD_volume_set_size_offset (PVD_reserved3_offset + PVD_reserved3_size)
-#define PVD_volume_set_size_size 4
-#define PVD_volume_sequence_number_offset (PVD_volume_set_size_offset + PVD_volume_set_size_size)
-#define PVD_volume_sequence_number_size 4
-#define PVD_logical_block_size_offset (PVD_volume_sequence_number_offset + PVD_volume_sequence_number_size)
-#define PVD_logical_block_size_size 4
-#define PVD_path_table_size_offset (PVD_logical_block_size_offset + PVD_logical_block_size_size)
-#define PVD_path_table_size_size 8
-#define PVD_type_1_path_table_offset (PVD_path_table_size_offset + PVD_path_table_size_size)
-#define PVD_type_1_path_table_size 4
-#define PVD_opt_type_1_path_table_offset (PVD_type_1_path_table_offset + PVD_type_1_path_table_size)
-#define PVD_opt_type_1_path_table_size 4
-#define PVD_type_m_path_table_offset (PVD_opt_type_1_path_table_offset + PVD_opt_type_1_path_table_size)
-#define PVD_type_m_path_table_size 4
-#define PVD_opt_type_m_path_table_offset (PVD_type_m_path_table_offset + PVD_type_m_path_table_size)
-#define PVD_opt_type_m_path_table_size 4
-#define PVD_root_directory_record_offset (PVD_opt_type_m_path_table_offset + PVD_opt_type_m_path_table_size)
-#define PVD_root_directory_record_size 34
-#define PVD_volume_set_id_offset (PVD_root_directory_record_offset + PVD_root_directory_record_size)
-#define PVD_volume_set_id_size 128
-#define PVD_publisher_id_offset (PVD_volume_set_id_offset + PVD_volume_set_id_size)
-#define PVD_publisher_id_size 128
-#define PVD_preparer_id_offset (PVD_publisher_id_offset + PVD_publisher_id_size)
-#define PVD_preparer_id_size 128
-#define PVD_application_id_offset (PVD_preparer_id_offset + PVD_preparer_id_size)
-#define PVD_application_id_size 128
-#define PVD_copyright_file_id_offset (PVD_application_id_offset + PVD_application_id_size)
-#define PVD_copyright_file_id_size 37
-#define PVD_abstract_file_id_offset (PVD_copyright_file_id_offset + PVD_copyright_file_id_size)
-#define PVD_abstract_file_id_size 37
-#define PVD_bibliographic_file_id_offset (PVD_abstract_file_id_offset + PVD_abstract_file_id_size)
-#define PVD_bibliographic_file_id_size 37
-#define PVD_creation_date_offset (PVD_bibliographic_file_id_offset + PVD_bibliographic_file_id_size)
-#define PVD_creation_date_size 17
-#define PVD_modification_date_offset (PVD_creation_date_offset + PVD_creation_date_size)
-#define PVD_modification_date_size 17
-#define PVD_expiration_date_offset (PVD_modification_date_offset + PVD_modification_date_size)
-#define PVD_expiration_date_size 17
-#define PVD_effective_date_offset (PVD_expiration_date_offset + PVD_expiration_date_size)
-#define PVD_effective_date_size 17
-#define PVD_file_structure_version_offset (PVD_effective_date_offset + PVD_effective_date_size)
-#define PVD_file_structure_version_size 1
-#define PVD_reserved4_offset (PVD_file_structure_version_offset + PVD_file_structure_version_size)
-#define PVD_reserved4_size 1
-#define PVD_application_data_offset (PVD_reserved4_offset + PVD_reserved4_size)
-#define PVD_application_data_size 512
-#define PVD_reserved5_offset (PVD_application_data_offset + PVD_application_data_size)
-#define PVD_reserved5_size (2048 - PVD_reserved5_offset)
-
-/* TODO: It would make future maintenance easier to just hardcode the
- * above values. In particular, ECMA119 states the offsets as part of
- * the standard. That would eliminate the need for the following check.*/
-#if PVD_reserved5_offset != 1395
-#error PVD offset and size definitions are wrong.
-#endif
-
-
-/* Structure of optional on-disk supplementary volume descriptor. */
-#define SVD_type_offset 0
-#define SVD_type_size 1
-#define SVD_id_offset (SVD_type_offset + SVD_type_size)
-#define SVD_id_size 5
-#define SVD_version_offset (SVD_id_offset + SVD_id_size)
-#define SVD_version_size 1
-/* ... */
-#define SVD_reserved1_offset 72
-#define SVD_reserved1_size 8
-#define SVD_volume_space_size_offset 80
-#define SVD_volume_space_size_size 8
-#define SVD_escape_sequences_offset (SVD_volume_space_size_offset + SVD_volume_space_size_size)
-#define SVD_escape_sequences_size 32
-/* ... */
-#define SVD_logical_block_size_offset 128
-#define SVD_logical_block_size_size 4
-#define SVD_type_L_path_table_offset 140
-#define SVD_type_M_path_table_offset 148
-/* ... */
-#define SVD_root_directory_record_offset 156
-#define SVD_root_directory_record_size 34
-#define SVD_file_structure_version_offset 881
-#define SVD_reserved2_offset 882
-#define SVD_reserved2_size 1
-#define SVD_reserved3_offset 1395
-#define SVD_reserved3_size 653
-/* ... */
-/* FIXME: validate correctness of last SVD entry offset. */
-
-/* Structure of an on-disk directory record. */
-/* Note: ISO9660 stores each multi-byte integer twice, once in
- * each byte order. The sizes here are the size of just one
- * of the two integers. (This is why the offset of a field isn't
- * the same as the offset+size of the previous field.) */
-#define DR_length_offset 0
-#define DR_length_size 1
-#define DR_ext_attr_length_offset 1
-#define DR_ext_attr_length_size 1
-#define DR_extent_offset 2
-#define DR_extent_size 4
-#define DR_size_offset 10
-#define DR_size_size 4
-#define DR_date_offset 18
-#define DR_date_size 7
-#define DR_flags_offset 25
-#define DR_flags_size 1
-#define DR_file_unit_size_offset 26
-#define DR_file_unit_size_size 1
-#define DR_interleave_offset 27
-#define DR_interleave_size 1
-#define DR_volume_sequence_number_offset 28
-#define DR_volume_sequence_number_size 2
-#define DR_name_len_offset 32
-#define DR_name_len_size 1
-#define DR_name_offset 33
-
-#ifdef HAVE_ZLIB_H
-static const unsigned char zisofs_magic[8] = {
- 0x37, 0xE4, 0x53, 0x96, 0xC9, 0xDB, 0xD6, 0x07
-};
-
-struct zisofs {
- /* Set 1 if this file compressed by paged zlib */
- int pz;
- int pz_log2_bs; /* Log2 of block size */
- uint64_t pz_uncompressed_size;
-
- int initialized;
- unsigned char *uncompressed_buffer;
- size_t uncompressed_buffer_size;
-
- uint32_t pz_offset;
- unsigned char header[16];
- size_t header_avail;
- int header_passed;
- unsigned char *block_pointers;
- size_t block_pointers_alloc;
- size_t block_pointers_size;
- size_t block_pointers_avail;
- size_t block_off;
- uint32_t block_avail;
-
- z_stream stream;
- int stream_valid;
-};
-#else
-struct zisofs {
- /* Set 1 if this file compressed by paged zlib */
- int pz;
-};
-#endif
-
-struct content {
- uint64_t offset;/* Offset on disk. */
- uint64_t size; /* File size in bytes. */
- struct content *next;
-};
-
-/* In-memory storage for a directory record. */
-struct file_info {
- struct file_info *use_next;
- struct file_info *parent;
- struct file_info *next;
- struct file_info *re_next;
- int subdirs;
- uint64_t key; /* Heap Key. */
- uint64_t offset; /* Offset on disk. */
- uint64_t size; /* File size in bytes. */
- uint32_t ce_offset; /* Offset of CE. */
- uint32_t ce_size; /* Size of CE. */
- char rr_moved; /* Flag to rr_moved. */
- char rr_moved_has_re_only;
- char re; /* Having RRIP "RE" extension. */
- char re_descendant;
- uint64_t cl_offset; /* Having RRIP "CL" extension. */
- int birthtime_is_set;
- time_t birthtime; /* File created time. */
- time_t mtime; /* File last modified time. */
- time_t atime; /* File last accessed time. */
- time_t ctime; /* File attribute change time. */
- uint64_t rdev; /* Device number. */
- mode_t mode;
- uid_t uid;
- gid_t gid;
- int64_t number;
- int nlinks;
- struct archive_string name; /* Pathname */
- unsigned char *utf16be_name;
- size_t utf16be_bytes;
- char name_continues; /* Non-zero if name continues */
- struct archive_string symlink;
- char symlink_continues; /* Non-zero if link continues */
- /* Set 1 if this file compressed by paged zlib(zisofs) */
- int pz;
- int pz_log2_bs; /* Log2 of block size */
- uint64_t pz_uncompressed_size;
- /* Set 1 if this file is multi extent. */
- int multi_extent;
- struct {
- struct content *first;
- struct content **last;
- } contents;
- struct {
- struct file_info *first;
- struct file_info **last;
- } rede_files;
-};
-
-struct heap_queue {
- struct file_info **files;
- int allocated;
- int used;
-};
-
-struct iso9660 {
- int magic;
-#define ISO9660_MAGIC 0x96609660
-
- int opt_support_joliet;
- int opt_support_rockridge;
-
- struct archive_string pathname;
- char seenRockridge; /* Set true if RR extensions are used. */
- char seenSUSP; /* Set true if SUSP is being used. */
- char seenJoliet;
-
- unsigned char suspOffset;
- struct file_info *rr_moved;
- struct read_ce_queue {
- struct read_ce_req {
- uint64_t offset;/* Offset of CE on disk. */
- struct file_info *file;
- } *reqs;
- int cnt;
- int allocated;
- } read_ce_req;
-
- int64_t previous_number;
- struct archive_string previous_pathname;
-
- struct file_info *use_files;
- struct heap_queue pending_files;
- struct {
- struct file_info *first;
- struct file_info **last;
- } cache_files;
- struct {
- struct file_info *first;
- struct file_info **last;
- } re_files;
-
- uint64_t current_position;
- ssize_t logical_block_size;
- uint64_t volume_size; /* Total size of volume in bytes. */
- int32_t volume_block;/* Total size of volume in logical blocks. */
-
- struct vd {
- int location; /* Location of Extent. */
- uint32_t size;
- } primary, joliet;
-
- int64_t entry_sparse_offset;
- int64_t entry_bytes_remaining;
- size_t entry_bytes_unconsumed;
- struct zisofs entry_zisofs;
- struct content *entry_content;
- struct archive_string_conv *sconv_utf16be;
- /*
- * Buffers for a full pathname in UTF-16BE in Joliet extensions.
- */
-#define UTF16_NAME_MAX 1024
- unsigned char *utf16be_path;
- size_t utf16be_path_len;
- unsigned char *utf16be_previous_path;
- size_t utf16be_previous_path_len;
- /* Null buffer used in bidder to improve its performance. */
- unsigned char null[2048];
-};
-
-static int archive_read_format_iso9660_bid(struct archive_read *, int);
-static int archive_read_format_iso9660_options(struct archive_read *,
- const char *, const char *);
-static int archive_read_format_iso9660_cleanup(struct archive_read *);
-static int archive_read_format_iso9660_read_data(struct archive_read *,
- const void **, size_t *, int64_t *);
-static int archive_read_format_iso9660_read_data_skip(struct archive_read *);
-static int archive_read_format_iso9660_read_header(struct archive_read *,
- struct archive_entry *);
-static const char *build_pathname(struct archive_string *, struct file_info *, int);
-static int build_pathname_utf16be(unsigned char *, size_t, size_t *,
- struct file_info *);
-#if DEBUG
-static void dump_isodirrec(FILE *, const unsigned char *isodirrec);
-#endif
-static time_t time_from_tm(struct tm *);
-static time_t isodate17(const unsigned char *);
-static time_t isodate7(const unsigned char *);
-static int isBootRecord(struct iso9660 *, const unsigned char *);
-static int isVolumePartition(struct iso9660 *, const unsigned char *);
-static int isVDSetTerminator(struct iso9660 *, const unsigned char *);
-static int isJolietSVD(struct iso9660 *, const unsigned char *);
-static int isSVD(struct iso9660 *, const unsigned char *);
-static int isEVD(struct iso9660 *, const unsigned char *);
-static int isPVD(struct iso9660 *, const unsigned char *);
-static int next_cache_entry(struct archive_read *, struct iso9660 *,
- struct file_info **);
-static int next_entry_seek(struct archive_read *, struct iso9660 *,
- struct file_info **);
-static struct file_info *
- parse_file_info(struct archive_read *a,
- struct file_info *parent, const unsigned char *isodirrec,
- size_t reclen);
-static int parse_rockridge(struct archive_read *a,
- struct file_info *file, const unsigned char *start,
- const unsigned char *end);
-static int register_CE(struct archive_read *a, int32_t location,
- struct file_info *file);
-static int read_CE(struct archive_read *a, struct iso9660 *iso9660);
-static void parse_rockridge_NM1(struct file_info *,
- const unsigned char *, int);
-static void parse_rockridge_SL1(struct file_info *,
- const unsigned char *, int);
-static void parse_rockridge_TF1(struct file_info *,
- const unsigned char *, int);
-static void parse_rockridge_ZF1(struct file_info *,
- const unsigned char *, int);
-static void register_file(struct iso9660 *, struct file_info *);
-static void release_files(struct iso9660 *);
-static unsigned toi(const void *p, int n);
-static inline void re_add_entry(struct iso9660 *, struct file_info *);
-static inline struct file_info * re_get_entry(struct iso9660 *);
-static inline int rede_add_entry(struct file_info *);
-static inline struct file_info * rede_get_entry(struct file_info *);
-static inline void cache_add_entry(struct iso9660 *iso9660,
- struct file_info *file);
-static inline struct file_info *cache_get_entry(struct iso9660 *iso9660);
-static int heap_add_entry(struct archive_read *a, struct heap_queue *heap,
- struct file_info *file, uint64_t key);
-static struct file_info *heap_get_entry(struct heap_queue *heap);
-
-#define add_entry(arch, iso9660, file) \
- heap_add_entry(arch, &((iso9660)->pending_files), file, file->offset)
-#define next_entry(iso9660) \
- heap_get_entry(&((iso9660)->pending_files))
-
-int
-archive_read_support_format_iso9660(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- struct iso9660 *iso9660;
- int r;
-
- archive_check_magic(_a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_format_iso9660");
-
- iso9660 = (struct iso9660 *)calloc(1, sizeof(*iso9660));
- if (iso9660 == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate iso9660 data");
- return (ARCHIVE_FATAL);
- }
- iso9660->magic = ISO9660_MAGIC;
- iso9660->cache_files.first = NULL;
- iso9660->cache_files.last = &(iso9660->cache_files.first);
- iso9660->re_files.first = NULL;
- iso9660->re_files.last = &(iso9660->re_files.first);
- /* Enable to support Joliet extensions by default. */
- iso9660->opt_support_joliet = 1;
- /* Enable to support Rock Ridge extensions by default. */
- iso9660->opt_support_rockridge = 1;
-
- r = __archive_read_register_format(a,
- iso9660,
- "iso9660",
- archive_read_format_iso9660_bid,
- archive_read_format_iso9660_options,
- archive_read_format_iso9660_read_header,
- archive_read_format_iso9660_read_data,
- archive_read_format_iso9660_read_data_skip,
- NULL,
- archive_read_format_iso9660_cleanup,
- NULL,
- NULL);
-
- if (r != ARCHIVE_OK) {
- free(iso9660);
- return (r);
- }
- return (ARCHIVE_OK);
-}
-
-
-static int
-archive_read_format_iso9660_bid(struct archive_read *a, int best_bid)
-{
- struct iso9660 *iso9660;
- ssize_t bytes_read;
- const unsigned char *p;
- int seenTerminator;
-
- /* If there's already a better bid than we can ever
- make, don't bother testing. */
- if (best_bid > 48)
- return (-1);
-
- iso9660 = (struct iso9660 *)(a->format->data);
-
- /*
- * Skip the first 32k (reserved area) and get the first
- * 8 sectors of the volume descriptor table. Of course,
- * if the I/O layer gives us more, we'll take it.
- */
-#define RESERVED_AREA (SYSTEM_AREA_BLOCK * LOGICAL_BLOCK_SIZE)
- p = __archive_read_ahead(a,
- RESERVED_AREA + 8 * LOGICAL_BLOCK_SIZE,
- &bytes_read);
- if (p == NULL)
- return (-1);
-
- /* Skip the reserved area. */
- bytes_read -= RESERVED_AREA;
- p += RESERVED_AREA;
-
- /* Check each volume descriptor. */
- seenTerminator = 0;
- for (; bytes_read > LOGICAL_BLOCK_SIZE;
- bytes_read -= LOGICAL_BLOCK_SIZE, p += LOGICAL_BLOCK_SIZE) {
- /* Do not handle undefined Volume Descriptor Type. */
- if (p[0] >= 4 && p[0] <= 254)
- return (0);
- /* Standard Identifier must be "CD001" */
- if (memcmp(p + 1, "CD001", 5) != 0)
- return (0);
- if (isPVD(iso9660, p))
- continue;
- if (!iso9660->joliet.location) {
- if (isJolietSVD(iso9660, p))
- continue;
- }
- if (isBootRecord(iso9660, p))
- continue;
- if (isEVD(iso9660, p))
- continue;
- if (isSVD(iso9660, p))
- continue;
- if (isVolumePartition(iso9660, p))
- continue;
- if (isVDSetTerminator(iso9660, p)) {
- seenTerminator = 1;
- break;
- }
- return (0);
- }
- /*
- * ISO 9660 format must have Primary Volume Descriptor and
- * Volume Descriptor Set Terminator.
- */
- if (seenTerminator && iso9660->primary.location > 16)
- return (48);
-
- /* We didn't find a valid PVD; return a bid of zero. */
- return (0);
-}
-
-static int
-archive_read_format_iso9660_options(struct archive_read *a,
- const char *key, const char *val)
-{
- struct iso9660 *iso9660;
-
- iso9660 = (struct iso9660 *)(a->format->data);
-
- if (strcmp(key, "joliet") == 0) {
- if (val == NULL || strcmp(val, "off") == 0 ||
- strcmp(val, "ignore") == 0 ||
- strcmp(val, "disable") == 0 ||
- strcmp(val, "0") == 0)
- iso9660->opt_support_joliet = 0;
- else
- iso9660->opt_support_joliet = 1;
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "rockridge") == 0 ||
- strcmp(key, "Rockridge") == 0) {
- iso9660->opt_support_rockridge = val != NULL;
- return (ARCHIVE_OK);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-static int
-isNull(struct iso9660 *iso9660, const unsigned char *h, unsigned offset,
-unsigned bytes)
-{
-
- while (bytes >= sizeof(iso9660->null)) {
- if (!memcmp(iso9660->null, h + offset, sizeof(iso9660->null)))
- return (0);
- offset += sizeof(iso9660->null);
- bytes -= sizeof(iso9660->null);
- }
- if (bytes)
- return memcmp(iso9660->null, h + offset, bytes) == 0;
- else
- return (1);
-}
-
-static int
-isBootRecord(struct iso9660 *iso9660, const unsigned char *h)
-{
- (void)iso9660; /* UNUSED */
-
- /* Type of the Volume Descriptor Boot Record must be 0. */
- if (h[0] != 0)
- return (0);
-
- /* Volume Descriptor Version must be 1. */
- if (h[6] != 1)
- return (0);
-
- return (1);
-}
-
-static int
-isVolumePartition(struct iso9660 *iso9660, const unsigned char *h)
-{
- int32_t location;
-
- /* Type of the Volume Partition Descriptor must be 3. */
- if (h[0] != 3)
- return (0);
-
- /* Volume Descriptor Version must be 1. */
- if (h[6] != 1)
- return (0);
- /* Unused Field */
- if (h[7] != 0)
- return (0);
-
- location = archive_le32dec(h + 72);
- if (location <= SYSTEM_AREA_BLOCK ||
- location >= iso9660->volume_block)
- return (0);
- if ((uint32_t)location != archive_be32dec(h + 76))
- return (0);
-
- return (1);
-}
-
-static int
-isVDSetTerminator(struct iso9660 *iso9660, const unsigned char *h)
-{
- (void)iso9660; /* UNUSED */
-
- /* Type of the Volume Descriptor Set Terminator must be 255. */
- if (h[0] != 255)
- return (0);
-
- /* Volume Descriptor Version must be 1. */
- if (h[6] != 1)
- return (0);
-
- /* Reserved field must be 0. */
- if (!isNull(iso9660, h, 7, 2048-7))
- return (0);
-
- return (1);
-}
-
-static int
-isJolietSVD(struct iso9660 *iso9660, const unsigned char *h)
-{
- const unsigned char *p;
- ssize_t logical_block_size;
- int32_t volume_block;
-
- /* Check if current sector is a kind of Supplementary Volume
- * Descriptor. */
- if (!isSVD(iso9660, h))
- return (0);
-
- /* FIXME: do more validations according to joliet spec. */
-
- /* check if this SVD contains joliet extension! */
- p = h + SVD_escape_sequences_offset;
- /* N.B. Joliet spec says p[1] == '\\', but.... */
- if (p[0] == '%' && p[1] == '/') {
- int level = 0;
-
- if (p[2] == '@')
- level = 1;
- else if (p[2] == 'C')
- level = 2;
- else if (p[2] == 'E')
- level = 3;
- else /* not joliet */
- return (0);
-
- iso9660->seenJoliet = level;
-
- } else /* not joliet */
- return (0);
-
- logical_block_size =
- archive_le16dec(h + SVD_logical_block_size_offset);
- volume_block = archive_le32dec(h + SVD_volume_space_size_offset);
-
- iso9660->logical_block_size = logical_block_size;
- iso9660->volume_block = volume_block;
- iso9660->volume_size = logical_block_size * (uint64_t)volume_block;
- /* Read Root Directory Record in Volume Descriptor. */
- p = h + SVD_root_directory_record_offset;
- iso9660->joliet.location = archive_le32dec(p + DR_extent_offset);
- iso9660->joliet.size = archive_le32dec(p + DR_size_offset);
-
- return (48);
-}
-
-static int
-isSVD(struct iso9660 *iso9660, const unsigned char *h)
-{
- const unsigned char *p;
- ssize_t logical_block_size;
- int32_t volume_block;
- int32_t location;
-
- (void)iso9660; /* UNUSED */
-
- /* Type 2 means it's a SVD. */
- if (h[SVD_type_offset] != 2)
- return (0);
-
- /* Reserved field must be 0. */
- if (!isNull(iso9660, h, SVD_reserved1_offset, SVD_reserved1_size))
- return (0);
- if (!isNull(iso9660, h, SVD_reserved2_offset, SVD_reserved2_size))
- return (0);
- if (!isNull(iso9660, h, SVD_reserved3_offset, SVD_reserved3_size))
- return (0);
-
- /* File structure version must be 1 for ISO9660/ECMA119. */
- if (h[SVD_file_structure_version_offset] != 1)
- return (0);
-
- logical_block_size =
- archive_le16dec(h + SVD_logical_block_size_offset);
- if (logical_block_size <= 0)
- return (0);
-
- volume_block = archive_le32dec(h + SVD_volume_space_size_offset);
- if (volume_block <= SYSTEM_AREA_BLOCK+4)
- return (0);
-
- /* Location of Occurrence of Type L Path Table must be
- * available location,
- * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
- location = archive_le32dec(h+SVD_type_L_path_table_offset);
- if (location < SYSTEM_AREA_BLOCK+2 || location >= volume_block)
- return (0);
-
- /* The Type M Path Table must be at a valid location (WinISO
- * and probably other programs omit this, so we allow zero)
- *
- * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
- location = archive_be32dec(h+SVD_type_M_path_table_offset);
- if ((location > 0 && location < SYSTEM_AREA_BLOCK+2)
- || location >= volume_block)
- return (0);
-
- /* Read Root Directory Record in Volume Descriptor. */
- p = h + SVD_root_directory_record_offset;
- if (p[DR_length_offset] != 34)
- return (0);
-
- return (48);
-}
-
-static int
-isEVD(struct iso9660 *iso9660, const unsigned char *h)
-{
- const unsigned char *p;
- ssize_t logical_block_size;
- int32_t volume_block;
- int32_t location;
-
- (void)iso9660; /* UNUSED */
-
- /* Type of the Enhanced Volume Descriptor must be 2. */
- if (h[PVD_type_offset] != 2)
- return (0);
-
- /* EVD version must be 2. */
- if (h[PVD_version_offset] != 2)
- return (0);
-
- /* Reserved field must be 0. */
- if (h[PVD_reserved1_offset] != 0)
- return (0);
-
- /* Reserved field must be 0. */
- if (!isNull(iso9660, h, PVD_reserved2_offset, PVD_reserved2_size))
- return (0);
-
- /* Reserved field must be 0. */
- if (!isNull(iso9660, h, PVD_reserved3_offset, PVD_reserved3_size))
- return (0);
-
- /* Logical block size must be > 0. */
- /* I've looked at Ecma 119 and can't find any stronger
- * restriction on this field. */
- logical_block_size =
- archive_le16dec(h + PVD_logical_block_size_offset);
- if (logical_block_size <= 0)
- return (0);
-
- volume_block =
- archive_le32dec(h + PVD_volume_space_size_offset);
- if (volume_block <= SYSTEM_AREA_BLOCK+4)
- return (0);
-
- /* File structure version must be 2 for ISO9660:1999. */
- if (h[PVD_file_structure_version_offset] != 2)
- return (0);
-
- /* Location of Occurrence of Type L Path Table must be
- * available location,
- * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
- location = archive_le32dec(h+PVD_type_1_path_table_offset);
- if (location < SYSTEM_AREA_BLOCK+2 || location >= volume_block)
- return (0);
-
- /* Location of Occurrence of Type M Path Table must be
- * available location,
- * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
- location = archive_be32dec(h+PVD_type_m_path_table_offset);
- if ((location > 0 && location < SYSTEM_AREA_BLOCK+2)
- || location >= volume_block)
- return (0);
-
- /* Reserved field must be 0. */
- if (!isNull(iso9660, h, PVD_reserved4_offset, PVD_reserved4_size))
- return (0);
-
- /* Reserved field must be 0. */
- if (!isNull(iso9660, h, PVD_reserved5_offset, PVD_reserved5_size))
- return (0);
-
- /* Read Root Directory Record in Volume Descriptor. */
- p = h + PVD_root_directory_record_offset;
- if (p[DR_length_offset] != 34)
- return (0);
-
- return (48);
-}
-
-static int
-isPVD(struct iso9660 *iso9660, const unsigned char *h)
-{
- const unsigned char *p;
- ssize_t logical_block_size;
- int32_t volume_block;
- int32_t location;
- int i;
-
- /* Type of the Primary Volume Descriptor must be 1. */
- if (h[PVD_type_offset] != 1)
- return (0);
-
- /* PVD version must be 1. */
- if (h[PVD_version_offset] != 1)
- return (0);
-
- /* Reserved field must be 0. */
- if (h[PVD_reserved1_offset] != 0)
- return (0);
-
- /* Reserved field must be 0. */
- if (!isNull(iso9660, h, PVD_reserved2_offset, PVD_reserved2_size))
- return (0);
-
- /* Reserved field must be 0. */
- if (!isNull(iso9660, h, PVD_reserved3_offset, PVD_reserved3_size))
- return (0);
-
- /* Logical block size must be > 0. */
- /* I've looked at Ecma 119 and can't find any stronger
- * restriction on this field. */
- logical_block_size =
- archive_le16dec(h + PVD_logical_block_size_offset);
- if (logical_block_size <= 0)
- return (0);
-
- volume_block = archive_le32dec(h + PVD_volume_space_size_offset);
- if (volume_block <= SYSTEM_AREA_BLOCK+4)
- return (0);
-
- /* File structure version must be 1 for ISO9660/ECMA119. */
- if (h[PVD_file_structure_version_offset] != 1)
- return (0);
-
- /* Location of Occurrence of Type L Path Table must be
- * available location,
- * > SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
- location = archive_le32dec(h+PVD_type_1_path_table_offset);
- if (location < SYSTEM_AREA_BLOCK+2 || location >= volume_block)
- return (0);
-
- /* The Type M Path Table must also be at a valid location
- * (although ECMA 119 requires a Type M Path Table, WinISO and
- * probably other programs omit it, so we permit a zero here)
- *
- * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
- location = archive_be32dec(h+PVD_type_m_path_table_offset);
- if ((location > 0 && location < SYSTEM_AREA_BLOCK+2)
- || location >= volume_block)
- return (0);
-
- /* Reserved field must be 0. */
- /* But accept NetBSD/FreeBSD "makefs" images with 0x20 here. */
- for (i = 0; i < PVD_reserved4_size; ++i)
- if (h[PVD_reserved4_offset + i] != 0
- && h[PVD_reserved4_offset + i] != 0x20)
- return (0);
-
- /* Reserved field must be 0. */
- if (!isNull(iso9660, h, PVD_reserved5_offset, PVD_reserved5_size))
- return (0);
-
- /* XXX TODO: Check other values for sanity; reject more
- * malformed PVDs. XXX */
-
- /* Read Root Directory Record in Volume Descriptor. */
- p = h + PVD_root_directory_record_offset;
- if (p[DR_length_offset] != 34)
- return (0);
-
- if (!iso9660->primary.location) {
- iso9660->logical_block_size = logical_block_size;
- iso9660->volume_block = volume_block;
- iso9660->volume_size =
- logical_block_size * (uint64_t)volume_block;
- iso9660->primary.location =
- archive_le32dec(p + DR_extent_offset);
- iso9660->primary.size = archive_le32dec(p + DR_size_offset);
- }
-
- return (48);
-}
-
-static int
-read_children(struct archive_read *a, struct file_info *parent)
-{
- struct iso9660 *iso9660;
- const unsigned char *b, *p;
- struct file_info *multi;
- size_t step, skip_size;
-
- iso9660 = (struct iso9660 *)(a->format->data);
- /* flush any remaining bytes from the last round to ensure
- * we're positioned */
- if (iso9660->entry_bytes_unconsumed) {
- __archive_read_consume(a, iso9660->entry_bytes_unconsumed);
- iso9660->entry_bytes_unconsumed = 0;
- }
- if (iso9660->current_position > parent->offset) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Ignoring out-of-order directory (%s) %jd > %jd",
- parent->name.s,
- (intmax_t)iso9660->current_position,
- (intmax_t)parent->offset);
- return (ARCHIVE_WARN);
- }
- if (parent->offset + parent->size > iso9660->volume_size) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Directory is beyond end-of-media: %s",
- parent->name.s);
- return (ARCHIVE_WARN);
- }
- if (iso9660->current_position < parent->offset) {
- int64_t skipsize;
-
- skipsize = parent->offset - iso9660->current_position;
- skipsize = __archive_read_consume(a, skipsize);
- if (skipsize < 0)
- return ((int)skipsize);
- iso9660->current_position = parent->offset;
- }
-
- step = (size_t)(((parent->size + iso9660->logical_block_size -1) /
- iso9660->logical_block_size) * iso9660->logical_block_size);
- b = __archive_read_ahead(a, step, NULL);
- if (b == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Failed to read full block when scanning "
- "ISO9660 directory list");
- return (ARCHIVE_FATAL);
- }
- iso9660->current_position += step;
- multi = NULL;
- skip_size = step;
- while (step) {
- p = b;
- b += iso9660->logical_block_size;
- step -= iso9660->logical_block_size;
- for (; *p != 0 && p + DR_name_offset < b && p + *p <= b;
- p += *p) {
- struct file_info *child;
-
- /* N.B.: these special directory identifiers
- * are 8 bit "values" even on a
- * Joliet CD with UCS-2 (16bit) encoding.
- */
-
- /* Skip '.' entry. */
- if (*(p + DR_name_len_offset) == 1
- && *(p + DR_name_offset) == '\0')
- continue;
- /* Skip '..' entry. */
- if (*(p + DR_name_len_offset) == 1
- && *(p + DR_name_offset) == '\001')
- continue;
- child = parse_file_info(a, parent, p, b - p);
- if (child == NULL) {
- __archive_read_consume(a, skip_size);
- return (ARCHIVE_FATAL);
- }
- if (child->cl_offset == 0 &&
- (child->multi_extent || multi != NULL)) {
- struct content *con;
-
- if (multi == NULL) {
- multi = child;
- multi->contents.first = NULL;
- multi->contents.last =
- &(multi->contents.first);
- }
- con = malloc(sizeof(struct content));
- if (con == NULL) {
- archive_set_error(
- &a->archive, ENOMEM,
- "No memory for multi extent");
- __archive_read_consume(a, skip_size);
- return (ARCHIVE_FATAL);
- }
- con->offset = child->offset;
- con->size = child->size;
- con->next = NULL;
- *multi->contents.last = con;
- multi->contents.last = &(con->next);
- if (multi == child) {
- if (add_entry(a, iso9660, child)
- != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- } else {
- multi->size += child->size;
- if (!child->multi_extent)
- multi = NULL;
- }
- } else
- if (add_entry(a, iso9660, child) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- }
- }
-
- __archive_read_consume(a, skip_size);
-
- /* Read data which recorded by RRIP "CE" extension. */
- if (read_CE(a, iso9660) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- return (ARCHIVE_OK);
-}
-
-static int
-choose_volume(struct archive_read *a, struct iso9660 *iso9660)
-{
- struct file_info *file;
- int64_t skipsize;
- struct vd *vd;
- const void *block;
- char seenJoliet;
-
- vd = &(iso9660->primary);
- if (!iso9660->opt_support_joliet)
- iso9660->seenJoliet = 0;
- if (iso9660->seenJoliet &&
- vd->location > iso9660->joliet.location)
- /* This condition is unlikely; by way of caution. */
- vd = &(iso9660->joliet);
-
- skipsize = LOGICAL_BLOCK_SIZE * (int64_t)vd->location;
- skipsize = __archive_read_consume(a, skipsize);
- if (skipsize < 0)
- return ((int)skipsize);
- iso9660->current_position = skipsize;
-
- block = __archive_read_ahead(a, vd->size, NULL);
- if (block == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Failed to read full block when scanning "
- "ISO9660 directory list");
- return (ARCHIVE_FATAL);
- }
-
- /*
- * While reading Root Directory, flag seenJoliet must be zero to
- * avoid converting special name 0x00(Current Directory) and
- * next byte to UCS2.
- */
- seenJoliet = iso9660->seenJoliet;/* Save flag. */
- iso9660->seenJoliet = 0;
- file = parse_file_info(a, NULL, block, vd->size);
- if (file == NULL)
- return (ARCHIVE_FATAL);
- iso9660->seenJoliet = seenJoliet;
-
- /*
- * If the iso image has both RockRidge and Joliet, we preferentially
- * use RockRidge Extensions rather than Joliet ones.
- */
- if (vd == &(iso9660->primary) && iso9660->seenRockridge
- && iso9660->seenJoliet)
- iso9660->seenJoliet = 0;
-
- if (vd == &(iso9660->primary) && !iso9660->seenRockridge
- && iso9660->seenJoliet) {
- /* Switch reading data from primary to joliet. */
- vd = &(iso9660->joliet);
- skipsize = LOGICAL_BLOCK_SIZE * (int64_t)vd->location;
- skipsize -= iso9660->current_position;
- skipsize = __archive_read_consume(a, skipsize);
- if (skipsize < 0)
- return ((int)skipsize);
- iso9660->current_position += skipsize;
-
- block = __archive_read_ahead(a, vd->size, NULL);
- if (block == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Failed to read full block when scanning "
- "ISO9660 directory list");
- return (ARCHIVE_FATAL);
- }
- iso9660->seenJoliet = 0;
- file = parse_file_info(a, NULL, block, vd->size);
- if (file == NULL)
- return (ARCHIVE_FATAL);
- iso9660->seenJoliet = seenJoliet;
- }
-
- /* Store the root directory in the pending list. */
- if (add_entry(a, iso9660, file) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- if (iso9660->seenRockridge) {
- a->archive.archive_format = ARCHIVE_FORMAT_ISO9660_ROCKRIDGE;
- a->archive.archive_format_name =
- "ISO9660 with Rockridge extensions";
- }
-
- return (ARCHIVE_OK);
-}
-
-static int
-archive_read_format_iso9660_read_header(struct archive_read *a,
- struct archive_entry *entry)
-{
- struct iso9660 *iso9660;
- struct file_info *file;
- int r, rd_r = ARCHIVE_OK;
-
- iso9660 = (struct iso9660 *)(a->format->data);
-
- if (!a->archive.archive_format) {
- a->archive.archive_format = ARCHIVE_FORMAT_ISO9660;
- a->archive.archive_format_name = "ISO9660";
- }
-
- if (iso9660->current_position == 0) {
- r = choose_volume(a, iso9660);
- if (r != ARCHIVE_OK)
- return (r);
- }
-
- file = NULL;/* Eliminate a warning. */
- /* Get the next entry that appears after the current offset. */
- r = next_entry_seek(a, iso9660, &file);
- if (r != ARCHIVE_OK)
- return (r);
-
- if (iso9660->seenJoliet) {
- /*
- * Convert UTF-16BE of a filename to local locale MBS
- * and store the result into a filename field.
- */
- if (iso9660->sconv_utf16be == NULL) {
- iso9660->sconv_utf16be =
- archive_string_conversion_from_charset(
- &(a->archive), "UTF-16BE", 1);
- if (iso9660->sconv_utf16be == NULL)
- /* Couldn't allocate memory */
- return (ARCHIVE_FATAL);
- }
- if (iso9660->utf16be_path == NULL) {
- iso9660->utf16be_path = malloc(UTF16_NAME_MAX);
- if (iso9660->utf16be_path == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory");
- return (ARCHIVE_FATAL);
- }
- }
- if (iso9660->utf16be_previous_path == NULL) {
- iso9660->utf16be_previous_path = malloc(UTF16_NAME_MAX);
- if (iso9660->utf16be_previous_path == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory");
- return (ARCHIVE_FATAL);
- }
- }
-
- iso9660->utf16be_path_len = 0;
- if (build_pathname_utf16be(iso9660->utf16be_path,
- UTF16_NAME_MAX, &(iso9660->utf16be_path_len), file) != 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Pathname is too long");
- return (ARCHIVE_FATAL);
- }
-
- r = archive_entry_copy_pathname_l(entry,
- (const char *)iso9660->utf16be_path,
- iso9660->utf16be_path_len,
- iso9660->sconv_utf16be);
- if (r != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for Pathname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Pathname cannot be converted "
- "from %s to current locale.",
- archive_string_conversion_charset_name(
- iso9660->sconv_utf16be));
-
- rd_r = ARCHIVE_WARN;
- }
- } else {
- const char *path = build_pathname(&iso9660->pathname, file, 0);
- if (path == NULL) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Pathname is too long");
- return (ARCHIVE_FATAL);
- } else {
- archive_string_empty(&iso9660->pathname);
- archive_entry_set_pathname(entry, path);
- }
- }
-
- iso9660->entry_bytes_remaining = file->size;
- /* Offset for sparse-file-aware clients. */
- iso9660->entry_sparse_offset = 0;
-
- if (file->offset + file->size > iso9660->volume_size) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "File is beyond end-of-media: %s",
- archive_entry_pathname(entry));
- iso9660->entry_bytes_remaining = 0;
- return (ARCHIVE_WARN);
- }
-
- /* Set up the entry structure with information about this entry. */
- archive_entry_set_mode(entry, file->mode);
- archive_entry_set_uid(entry, file->uid);
- archive_entry_set_gid(entry, file->gid);
- archive_entry_set_nlink(entry, file->nlinks);
- if (file->birthtime_is_set)
- archive_entry_set_birthtime(entry, file->birthtime, 0);
- else
- archive_entry_unset_birthtime(entry);
- archive_entry_set_mtime(entry, file->mtime, 0);
- archive_entry_set_ctime(entry, file->ctime, 0);
- archive_entry_set_atime(entry, file->atime, 0);
- /* N.B.: Rock Ridge supports 64-bit device numbers. */
- archive_entry_set_rdev(entry, (dev_t)file->rdev);
- archive_entry_set_size(entry, iso9660->entry_bytes_remaining);
- if (file->symlink.s != NULL)
- archive_entry_copy_symlink(entry, file->symlink.s);
-
- /* Note: If the input isn't seekable, we can't rewind to
- * return the same body again, so if the next entry refers to
- * the same data, we have to return it as a hardlink to the
- * original entry. */
- if (file->number != -1 &&
- file->number == iso9660->previous_number) {
- if (iso9660->seenJoliet) {
- r = archive_entry_copy_hardlink_l(entry,
- (const char *)iso9660->utf16be_previous_path,
- iso9660->utf16be_previous_path_len,
- iso9660->sconv_utf16be);
- if (r != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for Linkname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Linkname cannot be converted "
- "from %s to current locale.",
- archive_string_conversion_charset_name(
- iso9660->sconv_utf16be));
- rd_r = ARCHIVE_WARN;
- }
- } else
- archive_entry_set_hardlink(entry,
- iso9660->previous_pathname.s);
- archive_entry_unset_size(entry);
- iso9660->entry_bytes_remaining = 0;
- return (rd_r);
- }
-
- if ((file->mode & AE_IFMT) != AE_IFDIR &&
- file->offset < iso9660->current_position) {
- int64_t r64;
-
- r64 = __archive_read_seek(a, file->offset, SEEK_SET);
- if (r64 != (int64_t)file->offset) {
- /* We can't seek backwards to extract it, so issue
- * a warning. Note that this can only happen if
- * this entry was added to the heap after we passed
- * this offset, that is, only if the directory
- * mentioning this entry is later than the body of
- * the entry. Such layouts are very unusual; most
- * ISO9660 writers lay out and record all directory
- * information first, then store all file bodies. */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Ignoring out-of-order file @%jx (%s) %jd < %jd",
- (intmax_t)file->number,
- iso9660->pathname.s,
- (intmax_t)file->offset,
- (intmax_t)iso9660->current_position);
- iso9660->entry_bytes_remaining = 0;
- return (ARCHIVE_WARN);
- }
- iso9660->current_position = (uint64_t)r64;
- }
-
- /* Initialize zisofs variables. */
- iso9660->entry_zisofs.pz = file->pz;
- if (file->pz) {
-#ifdef HAVE_ZLIB_H
- struct zisofs *zisofs;
-
- zisofs = &iso9660->entry_zisofs;
- zisofs->initialized = 0;
- zisofs->pz_log2_bs = file->pz_log2_bs;
- zisofs->pz_uncompressed_size = file->pz_uncompressed_size;
- zisofs->pz_offset = 0;
- zisofs->header_avail = 0;
- zisofs->header_passed = 0;
- zisofs->block_pointers_avail = 0;
-#endif
- archive_entry_set_size(entry, file->pz_uncompressed_size);
- }
-
- iso9660->previous_number = file->number;
- if (iso9660->seenJoliet) {
- memcpy(iso9660->utf16be_previous_path, iso9660->utf16be_path,
- iso9660->utf16be_path_len);
- iso9660->utf16be_previous_path_len = iso9660->utf16be_path_len;
- } else
- archive_strcpy(
- &iso9660->previous_pathname, iso9660->pathname.s);
-
- /* Reset entry_bytes_remaining if the file is multi extent. */
- iso9660->entry_content = file->contents.first;
- if (iso9660->entry_content != NULL)
- iso9660->entry_bytes_remaining = iso9660->entry_content->size;
-
- if (archive_entry_filetype(entry) == AE_IFDIR) {
- /* Overwrite nlinks by proper link number which is
- * calculated from number of sub directories. */
- archive_entry_set_nlink(entry, 2 + file->subdirs);
- /* Directory data has been read completely. */
- iso9660->entry_bytes_remaining = 0;
- }
-
- if (rd_r != ARCHIVE_OK)
- return (rd_r);
- return (ARCHIVE_OK);
-}
-
-static int
-archive_read_format_iso9660_read_data_skip(struct archive_read *a)
-{
- /* Because read_next_header always does an explicit skip
- * to the next entry, we don't need to do anything here. */
- (void)a; /* UNUSED */
- return (ARCHIVE_OK);
-}
-
-#ifdef HAVE_ZLIB_H
-
-static int
-zisofs_read_data(struct archive_read *a,
- const void **buff, size_t *size, int64_t *offset)
-{
- struct iso9660 *iso9660;
- struct zisofs *zisofs;
- const unsigned char *p;
- size_t avail;
- ssize_t bytes_read;
- size_t uncompressed_size;
- int r;
-
- iso9660 = (struct iso9660 *)(a->format->data);
- zisofs = &iso9660->entry_zisofs;
-
- p = __archive_read_ahead(a, 1, &bytes_read);
- if (bytes_read <= 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated zisofs file body");
- return (ARCHIVE_FATAL);
- }
- if (bytes_read > iso9660->entry_bytes_remaining)
- bytes_read = (ssize_t)iso9660->entry_bytes_remaining;
- avail = bytes_read;
- uncompressed_size = 0;
-
- if (!zisofs->initialized) {
- size_t ceil, xsize;
-
- /* Allocate block pointers buffer. */
- ceil = (size_t)((zisofs->pz_uncompressed_size +
- (((int64_t)1) << zisofs->pz_log2_bs) - 1)
- >> zisofs->pz_log2_bs);
- xsize = (ceil + 1) * 4;
- if (zisofs->block_pointers_alloc < xsize) {
- size_t alloc;
-
- if (zisofs->block_pointers != NULL)
- free(zisofs->block_pointers);
- alloc = ((xsize >> 10) + 1) << 10;
- zisofs->block_pointers = malloc(alloc);
- if (zisofs->block_pointers == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for zisofs decompression");
- return (ARCHIVE_FATAL);
- }
- zisofs->block_pointers_alloc = alloc;
- }
- zisofs->block_pointers_size = xsize;
-
- /* Allocate uncompressed data buffer. */
- xsize = (size_t)1UL << zisofs->pz_log2_bs;
- if (zisofs->uncompressed_buffer_size < xsize) {
- if (zisofs->uncompressed_buffer != NULL)
- free(zisofs->uncompressed_buffer);
- zisofs->uncompressed_buffer = malloc(xsize);
- if (zisofs->uncompressed_buffer == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for zisofs decompression");
- return (ARCHIVE_FATAL);
- }
- }
- zisofs->uncompressed_buffer_size = xsize;
-
- /*
- * Read the file header, and check the magic code of zisofs.
- */
- if (zisofs->header_avail < sizeof(zisofs->header)) {
- xsize = sizeof(zisofs->header) - zisofs->header_avail;
- if (avail < xsize)
- xsize = avail;
- memcpy(zisofs->header + zisofs->header_avail, p, xsize);
- zisofs->header_avail += xsize;
- avail -= xsize;
- p += xsize;
- }
- if (!zisofs->header_passed &&
- zisofs->header_avail == sizeof(zisofs->header)) {
- int err = 0;
-
- if (memcmp(zisofs->header, zisofs_magic,
- sizeof(zisofs_magic)) != 0)
- err = 1;
- if (archive_le32dec(zisofs->header + 8)
- != zisofs->pz_uncompressed_size)
- err = 1;
- if (zisofs->header[12] != 4)
- err = 1;
- if (zisofs->header[13] != zisofs->pz_log2_bs)
- err = 1;
- if (err) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Illegal zisofs file body");
- return (ARCHIVE_FATAL);
- }
- zisofs->header_passed = 1;
- }
- /*
- * Read block pointers.
- */
- if (zisofs->header_passed &&
- zisofs->block_pointers_avail < zisofs->block_pointers_size) {
- xsize = zisofs->block_pointers_size
- - zisofs->block_pointers_avail;
- if (avail < xsize)
- xsize = avail;
- memcpy(zisofs->block_pointers
- + zisofs->block_pointers_avail, p, xsize);
- zisofs->block_pointers_avail += xsize;
- avail -= xsize;
- p += xsize;
- if (zisofs->block_pointers_avail
- == zisofs->block_pointers_size) {
- /* We've got all block pointers and initialize
- * related variables. */
- zisofs->block_off = 0;
- zisofs->block_avail = 0;
- /* Complete a initialization */
- zisofs->initialized = 1;
- }
- }
-
- if (!zisofs->initialized)
- goto next_data; /* We need more data. */
- }
-
- /*
- * Get block offsets from block pointers.
- */
- if (zisofs->block_avail == 0) {
- uint32_t bst, bed;
-
- if (zisofs->block_off + 4 >= zisofs->block_pointers_size) {
- /* There isn't a pair of offsets. */
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Illegal zisofs block pointers");
- return (ARCHIVE_FATAL);
- }
- bst = archive_le32dec(
- zisofs->block_pointers + zisofs->block_off);
- if (bst != zisofs->pz_offset + (bytes_read - avail)) {
- /* TODO: Should we seek offset of current file
- * by bst ? */
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Illegal zisofs block pointers(cannot seek)");
- return (ARCHIVE_FATAL);
- }
- bed = archive_le32dec(
- zisofs->block_pointers + zisofs->block_off + 4);
- if (bed < bst) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Illegal zisofs block pointers");
- return (ARCHIVE_FATAL);
- }
- zisofs->block_avail = bed - bst;
- zisofs->block_off += 4;
-
- /* Initialize compression library for new block. */
- if (zisofs->stream_valid)
- r = inflateReset(&zisofs->stream);
- else
- r = inflateInit(&zisofs->stream);
- if (r != Z_OK) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Can't initialize zisofs decompression.");
- return (ARCHIVE_FATAL);
- }
- zisofs->stream_valid = 1;
- zisofs->stream.total_in = 0;
- zisofs->stream.total_out = 0;
- }
-
- /*
- * Make uncompressed data.
- */
- if (zisofs->block_avail == 0) {
- memset(zisofs->uncompressed_buffer, 0,
- zisofs->uncompressed_buffer_size);
- uncompressed_size = zisofs->uncompressed_buffer_size;
- } else {
- zisofs->stream.next_in = (Bytef *)(uintptr_t)(const void *)p;
- if (avail > zisofs->block_avail)
- zisofs->stream.avail_in = zisofs->block_avail;
- else
- zisofs->stream.avail_in = (uInt)avail;
- zisofs->stream.next_out = zisofs->uncompressed_buffer;
- zisofs->stream.avail_out =
- (uInt)zisofs->uncompressed_buffer_size;
-
- r = inflate(&zisofs->stream, 0);
- switch (r) {
- case Z_OK: /* Decompressor made some progress.*/
- case Z_STREAM_END: /* Found end of stream. */
- break;
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "zisofs decompression failed (%d)", r);
- return (ARCHIVE_FATAL);
- }
- uncompressed_size =
- zisofs->uncompressed_buffer_size - zisofs->stream.avail_out;
- avail -= zisofs->stream.next_in - p;
- zisofs->block_avail -= (uint32_t)(zisofs->stream.next_in - p);
- }
-next_data:
- bytes_read -= avail;
- *buff = zisofs->uncompressed_buffer;
- *size = uncompressed_size;
- *offset = iso9660->entry_sparse_offset;
- iso9660->entry_sparse_offset += uncompressed_size;
- iso9660->entry_bytes_remaining -= bytes_read;
- iso9660->current_position += bytes_read;
- zisofs->pz_offset += (uint32_t)bytes_read;
- iso9660->entry_bytes_unconsumed += bytes_read;
-
- return (ARCHIVE_OK);
-}
-
-#else /* HAVE_ZLIB_H */
-
-static int
-zisofs_read_data(struct archive_read *a,
- const void **buff, size_t *size, int64_t *offset)
-{
-
- (void)buff;/* UNUSED */
- (void)size;/* UNUSED */
- (void)offset;/* UNUSED */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "zisofs is not supported on this platform.");
- return (ARCHIVE_FAILED);
-}
-
-#endif /* HAVE_ZLIB_H */
-
-static int
-archive_read_format_iso9660_read_data(struct archive_read *a,
- const void **buff, size_t *size, int64_t *offset)
-{
- ssize_t bytes_read;
- struct iso9660 *iso9660;
-
- iso9660 = (struct iso9660 *)(a->format->data);
-
- if (iso9660->entry_bytes_unconsumed) {
- __archive_read_consume(a, iso9660->entry_bytes_unconsumed);
- iso9660->entry_bytes_unconsumed = 0;
- }
-
- if (iso9660->entry_bytes_remaining <= 0) {
- if (iso9660->entry_content != NULL)
- iso9660->entry_content = iso9660->entry_content->next;
- if (iso9660->entry_content == NULL) {
- *buff = NULL;
- *size = 0;
- *offset = iso9660->entry_sparse_offset;
- return (ARCHIVE_EOF);
- }
- /* Seek forward to the start of the entry. */
- if (iso9660->current_position < iso9660->entry_content->offset) {
- int64_t step;
-
- step = iso9660->entry_content->offset -
- iso9660->current_position;
- step = __archive_read_consume(a, step);
- if (step < 0)
- return ((int)step);
- iso9660->current_position =
- iso9660->entry_content->offset;
- }
- if (iso9660->entry_content->offset < iso9660->current_position) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Ignoring out-of-order file (%s) %jd < %jd",
- iso9660->pathname.s,
- (intmax_t)iso9660->entry_content->offset,
- (intmax_t)iso9660->current_position);
- *buff = NULL;
- *size = 0;
- *offset = iso9660->entry_sparse_offset;
- return (ARCHIVE_WARN);
- }
- iso9660->entry_bytes_remaining = iso9660->entry_content->size;
- }
- if (iso9660->entry_zisofs.pz)
- return (zisofs_read_data(a, buff, size, offset));
-
- *buff = __archive_read_ahead(a, 1, &bytes_read);
- if (bytes_read == 0)
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Truncated input file");
- if (*buff == NULL)
- return (ARCHIVE_FATAL);
- if (bytes_read > iso9660->entry_bytes_remaining)
- bytes_read = (ssize_t)iso9660->entry_bytes_remaining;
- *size = bytes_read;
- *offset = iso9660->entry_sparse_offset;
- iso9660->entry_sparse_offset += bytes_read;
- iso9660->entry_bytes_remaining -= bytes_read;
- iso9660->entry_bytes_unconsumed = bytes_read;
- iso9660->current_position += bytes_read;
- return (ARCHIVE_OK);
-}
-
-static int
-archive_read_format_iso9660_cleanup(struct archive_read *a)
-{
- struct iso9660 *iso9660;
- int r = ARCHIVE_OK;
-
- iso9660 = (struct iso9660 *)(a->format->data);
- release_files(iso9660);
- free(iso9660->read_ce_req.reqs);
- archive_string_free(&iso9660->pathname);
- archive_string_free(&iso9660->previous_pathname);
- free(iso9660->pending_files.files);
-#ifdef HAVE_ZLIB_H
- free(iso9660->entry_zisofs.uncompressed_buffer);
- free(iso9660->entry_zisofs.block_pointers);
- if (iso9660->entry_zisofs.stream_valid) {
- if (inflateEnd(&iso9660->entry_zisofs.stream) != Z_OK) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Failed to clean up zlib decompressor");
- r = ARCHIVE_FATAL;
- }
- }
-#endif
- free(iso9660->utf16be_path);
- free(iso9660->utf16be_previous_path);
- free(iso9660);
- (a->format->data) = NULL;
- return (r);
-}
-
-/*
- * This routine parses a single ISO directory record, makes sense
- * of any extensions, and stores the result in memory.
- */
-static struct file_info *
-parse_file_info(struct archive_read *a, struct file_info *parent,
- const unsigned char *isodirrec, size_t reclen)
-{
- struct iso9660 *iso9660;
- struct file_info *file, *filep;
- size_t name_len;
- const unsigned char *rr_start, *rr_end;
- const unsigned char *p;
- size_t dr_len = 0;
- uint64_t fsize, offset;
- int32_t location;
- int flags;
-
- iso9660 = (struct iso9660 *)(a->format->data);
-
- if (reclen != 0)
- dr_len = (size_t)isodirrec[DR_length_offset];
- /*
- * Sanity check that reclen is not zero and dr_len is greater than
- * reclen but at least 34
- */
- if (reclen == 0 || reclen < dr_len || dr_len < 34) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Invalid length of directory record");
- return (NULL);
- }
- name_len = (size_t)isodirrec[DR_name_len_offset];
- location = archive_le32dec(isodirrec + DR_extent_offset);
- fsize = toi(isodirrec + DR_size_offset, DR_size_size);
- /* Sanity check that name_len doesn't exceed dr_len. */
- if (dr_len - 33 < name_len || name_len == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Invalid length of file identifier");
- return (NULL);
- }
- /* Sanity check that location doesn't exceed volume block.
- * Don't check lower limit of location; it's possibility
- * the location has negative value when file type is symbolic
- * link or file size is zero. As far as I know latest mkisofs
- * do that.
- */
- if (location > 0 &&
- (location + ((fsize + iso9660->logical_block_size -1)
- / iso9660->logical_block_size))
- > (uint32_t)iso9660->volume_block) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Invalid location of extent of file");
- return (NULL);
- }
- /* Sanity check that location doesn't have a negative value
- * when the file is not empty. it's too large. */
- if (fsize != 0 && location < 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Invalid location of extent of file");
- return (NULL);
- }
-
- /* Sanity check that this entry does not create a cycle. */
- offset = iso9660->logical_block_size * (uint64_t)location;
- for (filep = parent; filep != NULL; filep = filep->parent) {
- if (filep->offset == offset) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Directory structure contains loop");
- return (NULL);
- }
- }
-
- /* Create a new file entry and copy data from the ISO dir record. */
- file = (struct file_info *)calloc(1, sizeof(*file));
- if (file == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for file entry");
- return (NULL);
- }
- file->parent = parent;
- file->offset = offset;
- file->size = fsize;
- file->mtime = isodate7(isodirrec + DR_date_offset);
- file->ctime = file->atime = file->mtime;
- file->rede_files.first = NULL;
- file->rede_files.last = &(file->rede_files.first);
-
- p = isodirrec + DR_name_offset;
- /* Rockridge extensions (if any) follow name. Compute this
- * before fidgeting the name_len below. */
- rr_start = p + name_len + (name_len & 1 ? 0 : 1);
- rr_end = isodirrec + dr_len;
-
- if (iso9660->seenJoliet) {
- /* Joliet names are max 64 chars (128 bytes) according to spec,
- * but genisoimage/mkisofs allows recording longer Joliet
- * names which are 103 UCS2 characters(206 bytes) by their
- * option '-joliet-long'.
- */
- if (name_len > 206)
- name_len = 206;
- name_len &= ~1;
-
- /* trim trailing first version and dot from filename.
- *
- * Remember we were in UTF-16BE land!
- * SEPARATOR 1 (.) and SEPARATOR 2 (;) are both
- * 16 bits big endian characters on Joliet.
- *
- * TODO: sanitize filename?
- * Joliet allows any UCS-2 char except:
- * *, /, :, ;, ? and \.
- */
- /* Chop off trailing ';1' from files. */
- if (name_len > 4 && p[name_len-4] == 0 && p[name_len-3] == ';'
- && p[name_len-2] == 0 && p[name_len-1] == '1')
- name_len -= 4;
-#if 0 /* XXX: this somehow manages to strip of single-character file extensions, like '.c'. */
- /* Chop off trailing '.' from filenames. */
- if (name_len > 2 && p[name_len-2] == 0 && p[name_len-1] == '.')
- name_len -= 2;
-#endif
- if ((file->utf16be_name = malloc(name_len)) == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for file name");
- goto fail;
- }
- memcpy(file->utf16be_name, p, name_len);
- file->utf16be_bytes = name_len;
- } else {
- /* Chop off trailing ';1' from files. */
- if (name_len > 2 && p[name_len - 2] == ';' &&
- p[name_len - 1] == '1')
- name_len -= 2;
- /* Chop off trailing '.' from filenames. */
- if (name_len > 1 && p[name_len - 1] == '.')
- --name_len;
-
- archive_strncpy(&file->name, (const char *)p, name_len);
- }
-
- flags = isodirrec[DR_flags_offset];
- if (flags & 0x02)
- file->mode = AE_IFDIR | 0700;
- else
- file->mode = AE_IFREG | 0400;
- if (flags & 0x80)
- file->multi_extent = 1;
- else
- file->multi_extent = 0;
- /*
- * Use a location for the file number, which is treated as an inode
- * number to find out hardlink target. If Rockridge extensions is
- * being used, the file number will be overwritten by FILE SERIAL
- * NUMBER of RRIP "PX" extension.
- * Note: Old mkisofs did not record that FILE SERIAL NUMBER
- * in ISO images.
- * Note2: xorriso set 0 to the location of a symlink file.
- */
- if (file->size == 0 && location >= 0) {
- /* If file->size is zero, its location points wrong place,
- * and so we should not use it for the file number.
- * When the location has negative value, it can be used
- * for the file number.
- */
- file->number = -1;
- /* Do not appear before any directory entries. */
- file->offset = -1;
- } else
- file->number = (int64_t)(uint32_t)location;
-
- /* Rockridge extensions overwrite information from above. */
- if (iso9660->opt_support_rockridge) {
- if (parent == NULL && rr_end - rr_start >= 7) {
- p = rr_start;
- if (memcmp(p, "SP\x07\x01\xbe\xef", 6) == 0) {
- /*
- * SP extension stores the suspOffset
- * (Number of bytes to skip between
- * filename and SUSP records.)
- * It is mandatory by the SUSP standard
- * (IEEE 1281).
- *
- * It allows SUSP to coexist with
- * non-SUSP uses of the System
- * Use Area by placing non-SUSP data
- * before SUSP data.
- *
- * SP extension must be in the root
- * directory entry, disable all SUSP
- * processing if not found.
- */
- iso9660->suspOffset = p[6];
- iso9660->seenSUSP = 1;
- rr_start += 7;
- }
- }
- if (iso9660->seenSUSP) {
- int r;
-
- file->name_continues = 0;
- file->symlink_continues = 0;
- rr_start += iso9660->suspOffset;
- r = parse_rockridge(a, file, rr_start, rr_end);
- if (r != ARCHIVE_OK)
- goto fail;
- /*
- * A file size of symbolic link files in ISO images
- * made by makefs is not zero and its location is
- * the same as those of next regular file. That is
- * the same as hard like file and it causes unexpected
- * error.
- */
- if (file->size > 0 &&
- (file->mode & AE_IFMT) == AE_IFLNK) {
- file->size = 0;
- file->number = -1;
- file->offset = -1;
- }
- } else
- /* If there isn't SUSP, disable parsing
- * rock ridge extensions. */
- iso9660->opt_support_rockridge = 0;
- }
-
- file->nlinks = 1;/* Reset nlink. we'll calculate it later. */
- /* Tell file's parent how many children that parent has. */
- if (parent != NULL && (flags & 0x02))
- parent->subdirs++;
-
- if (iso9660->seenRockridge) {
- if (parent != NULL && parent->parent == NULL &&
- (flags & 0x02) && iso9660->rr_moved == NULL &&
- file->name.s &&
- (strcmp(file->name.s, "rr_moved") == 0 ||
- strcmp(file->name.s, ".rr_moved") == 0)) {
- iso9660->rr_moved = file;
- file->rr_moved = 1;
- file->rr_moved_has_re_only = 1;
- file->re = 0;
- parent->subdirs--;
- } else if (file->re) {
- /*
- * Sanity check: file's parent is rr_moved.
- */
- if (parent == NULL || parent->rr_moved == 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Invalid Rockridge RE");
- goto fail;
- }
- /*
- * Sanity check: file does not have "CL" extension.
- */
- if (file->cl_offset) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Invalid Rockridge RE and CL");
- goto fail;
- }
- /*
- * Sanity check: The file type must be a directory.
- */
- if ((flags & 0x02) == 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Invalid Rockridge RE");
- goto fail;
- }
- } else if (parent != NULL && parent->rr_moved)
- file->rr_moved_has_re_only = 0;
- else if (parent != NULL && (flags & 0x02) &&
- (parent->re || parent->re_descendant))
- file->re_descendant = 1;
- if (file->cl_offset) {
- struct file_info *r;
-
- if (parent == NULL || parent->parent == NULL) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Invalid Rockridge CL");
- goto fail;
- }
- /*
- * Sanity check: The file type must be a regular file.
- */
- if ((flags & 0x02) != 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Invalid Rockridge CL");
- goto fail;
- }
- parent->subdirs++;
- /* Overwrite an offset and a number of this "CL" entry
- * to appear before other dirs. "+1" to those is to
- * make sure to appear after "RE" entry which this
- * "CL" entry should be connected with. */
- file->offset = file->number = file->cl_offset + 1;
-
- /*
- * Sanity check: cl_offset does not point at its
- * the parents or itself.
- */
- for (r = parent; r; r = r->parent) {
- if (r->offset == file->cl_offset) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Invalid Rockridge CL");
- goto fail;
- }
- }
- if (file->cl_offset == file->offset ||
- parent->rr_moved) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Invalid Rockridge CL");
- goto fail;
- }
- }
- }
-
-#if DEBUG
- /* DEBUGGING: Warn about attributes I don't yet fully support. */
- if ((flags & ~0x02) != 0) {
- fprintf(stderr, "\n ** Unrecognized flag: ");
- dump_isodirrec(stderr, isodirrec);
- fprintf(stderr, "\n");
- } else if (toi(isodirrec + DR_volume_sequence_number_offset, 2) != 1) {
- fprintf(stderr, "\n ** Unrecognized sequence number: ");
- dump_isodirrec(stderr, isodirrec);
- fprintf(stderr, "\n");
- } else if (*(isodirrec + DR_file_unit_size_offset) != 0) {
- fprintf(stderr, "\n ** Unexpected file unit size: ");
- dump_isodirrec(stderr, isodirrec);
- fprintf(stderr, "\n");
- } else if (*(isodirrec + DR_interleave_offset) != 0) {
- fprintf(stderr, "\n ** Unexpected interleave: ");
- dump_isodirrec(stderr, isodirrec);
- fprintf(stderr, "\n");
- } else if (*(isodirrec + DR_ext_attr_length_offset) != 0) {
- fprintf(stderr, "\n ** Unexpected extended attribute length: ");
- dump_isodirrec(stderr, isodirrec);
- fprintf(stderr, "\n");
- }
-#endif
- register_file(iso9660, file);
- return (file);
-fail:
- archive_string_free(&file->name);
- free(file);
- return (NULL);
-}
-
-static int
-parse_rockridge(struct archive_read *a, struct file_info *file,
- const unsigned char *p, const unsigned char *end)
-{
- struct iso9660 *iso9660;
- int entry_seen = 0;
-
- iso9660 = (struct iso9660 *)(a->format->data);
-
- while (p + 4 <= end /* Enough space for another entry. */
- && p[0] >= 'A' && p[0] <= 'Z' /* Sanity-check 1st char of name. */
- && p[1] >= 'A' && p[1] <= 'Z' /* Sanity-check 2nd char of name. */
- && p[2] >= 4 /* Sanity-check length. */
- && p + p[2] <= end) { /* Sanity-check length. */
- const unsigned char *data = p + 4;
- int data_length = p[2] - 4;
- int version = p[3];
-
- switch(p[0]) {
- case 'C':
- if (p[1] == 'E') {
- if (version == 1 && data_length == 24) {
- /*
- * CE extension comprises:
- * 8 byte sector containing extension
- * 8 byte offset w/in above sector
- * 8 byte length of continuation
- */
- int32_t location =
- archive_le32dec(data);
- file->ce_offset =
- archive_le32dec(data+8);
- file->ce_size =
- archive_le32dec(data+16);
- if (register_CE(a, location, file)
- != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- }
- }
- else if (p[1] == 'L') {
- if (version == 1 && data_length == 8) {
- file->cl_offset = (uint64_t)
- iso9660->logical_block_size *
- (uint64_t)archive_le32dec(data);
- iso9660->seenRockridge = 1;
- }
- }
- break;
- case 'N':
- if (p[1] == 'M') {
- if (version == 1) {
- parse_rockridge_NM1(file,
- data, data_length);
- iso9660->seenRockridge = 1;
- }
- }
- break;
- case 'P':
- /*
- * PD extension is padding;
- * contents are always ignored.
- *
- * PL extension won't appear;
- * contents are always ignored.
- */
- if (p[1] == 'N') {
- if (version == 1 && data_length == 16) {
- file->rdev = toi(data,4);
- file->rdev <<= 32;
- file->rdev |= toi(data + 8, 4);
- iso9660->seenRockridge = 1;
- }
- }
- else if (p[1] == 'X') {
- /*
- * PX extension comprises:
- * 8 bytes for mode,
- * 8 bytes for nlinks,
- * 8 bytes for uid,
- * 8 bytes for gid,
- * 8 bytes for inode.
- */
- if (version == 1) {
- if (data_length >= 8)
- file->mode
- = toi(data, 4);
- if (data_length >= 16)
- file->nlinks
- = toi(data + 8, 4);
- if (data_length >= 24)
- file->uid
- = toi(data + 16, 4);
- if (data_length >= 32)
- file->gid
- = toi(data + 24, 4);
- if (data_length >= 40)
- file->number
- = toi(data + 32, 4);
- iso9660->seenRockridge = 1;
- }
- }
- break;
- case 'R':
- if (p[1] == 'E' && version == 1) {
- file->re = 1;
- iso9660->seenRockridge = 1;
- }
- else if (p[1] == 'R' && version == 1) {
- /*
- * RR extension comprises:
- * one byte flag value
- * This extension is obsolete,
- * so contents are always ignored.
- */
- }
- break;
- case 'S':
- if (p[1] == 'L') {
- if (version == 1) {
- parse_rockridge_SL1(file,
- data, data_length);
- iso9660->seenRockridge = 1;
- }
- }
- else if (p[1] == 'T'
- && data_length == 0 && version == 1) {
- /*
- * ST extension marks end of this
- * block of SUSP entries.
- *
- * It allows SUSP to coexist with
- * non-SUSP uses of the System
- * Use Area by placing non-SUSP data
- * after SUSP data.
- */
- iso9660->seenSUSP = 0;
- iso9660->seenRockridge = 0;
- return (ARCHIVE_OK);
- }
- break;
- case 'T':
- if (p[1] == 'F') {
- if (version == 1) {
- parse_rockridge_TF1(file,
- data, data_length);
- iso9660->seenRockridge = 1;
- }
- }
- break;
- case 'Z':
- if (p[1] == 'F') {
- if (version == 1)
- parse_rockridge_ZF1(file,
- data, data_length);
- }
- break;
- default:
- break;
- }
-
- p += p[2];
- entry_seen = 1;
- }
-
- if (entry_seen)
- return (ARCHIVE_OK);
- else {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Tried to parse Rockridge extensions, but none found");
- return (ARCHIVE_WARN);
- }
-}
-
-static int
-register_CE(struct archive_read *a, int32_t location,
- struct file_info *file)
-{
- struct iso9660 *iso9660;
- struct read_ce_queue *heap;
- struct read_ce_req *p;
- uint64_t offset, parent_offset;
- int hole, parent;
-
- iso9660 = (struct iso9660 *)(a->format->data);
- offset = ((uint64_t)location) * (uint64_t)iso9660->logical_block_size;
- if (((file->mode & AE_IFMT) == AE_IFREG &&
- offset >= file->offset) ||
- offset < iso9660->current_position ||
- (((uint64_t)file->ce_offset) + file->ce_size)
- > (uint64_t)iso9660->logical_block_size ||
- offset + file->ce_offset + file->ce_size
- > iso9660->volume_size) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Invalid parameter in SUSP \"CE\" extension");
- return (ARCHIVE_FATAL);
- }
-
- /* Expand our CE list as necessary. */
- heap = &(iso9660->read_ce_req);
- if (heap->cnt >= heap->allocated) {
- int new_size;
-
- if (heap->allocated < 16)
- new_size = 16;
- else
- new_size = heap->allocated * 2;
- /* Overflow might keep us from growing the list. */
- if (new_size <= heap->allocated) {
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- p = calloc(new_size, sizeof(p[0]));
- if (p == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- if (heap->reqs != NULL) {
- memcpy(p, heap->reqs, heap->cnt * sizeof(*p));
- free(heap->reqs);
- }
- heap->reqs = p;
- heap->allocated = new_size;
- }
-
- /*
- * Start with hole at end, walk it up tree to find insertion point.
- */
- hole = heap->cnt++;
- while (hole > 0) {
- parent = (hole - 1)/2;
- parent_offset = heap->reqs[parent].offset;
- if (offset >= parent_offset) {
- heap->reqs[hole].offset = offset;
- heap->reqs[hole].file = file;
- return (ARCHIVE_OK);
- }
- /* Move parent into hole <==> move hole up tree. */
- heap->reqs[hole] = heap->reqs[parent];
- hole = parent;
- }
- heap->reqs[0].offset = offset;
- heap->reqs[0].file = file;
- return (ARCHIVE_OK);
-}
-
-static void
-next_CE(struct read_ce_queue *heap)
-{
- uint64_t a_offset, b_offset, c_offset;
- int a, b, c;
- struct read_ce_req tmp;
-
- if (heap->cnt < 1)
- return;
-
- /*
- * Move the last item in the heap to the root of the tree
- */
- heap->reqs[0] = heap->reqs[--(heap->cnt)];
-
- /*
- * Rebalance the heap.
- */
- a = 0; /* Starting element and its offset */
- a_offset = heap->reqs[a].offset;
- for (;;) {
- b = a + a + 1; /* First child */
- if (b >= heap->cnt)
- return;
- b_offset = heap->reqs[b].offset;
- c = b + 1; /* Use second child if it is smaller. */
- if (c < heap->cnt) {
- c_offset = heap->reqs[c].offset;
- if (c_offset < b_offset) {
- b = c;
- b_offset = c_offset;
- }
- }
- if (a_offset <= b_offset)
- return;
- tmp = heap->reqs[a];
- heap->reqs[a] = heap->reqs[b];
- heap->reqs[b] = tmp;
- a = b;
- }
-}
-
-
-static int
-read_CE(struct archive_read *a, struct iso9660 *iso9660)
-{
- struct read_ce_queue *heap;
- const unsigned char *b, *p, *end;
- struct file_info *file;
- size_t step;
- int r;
-
- /* Read data which RRIP "CE" extension points. */
- heap = &(iso9660->read_ce_req);
- step = iso9660->logical_block_size;
- while (heap->cnt &&
- heap->reqs[0].offset == iso9660->current_position) {
- b = __archive_read_ahead(a, step, NULL);
- if (b == NULL) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Failed to read full block when scanning "
- "ISO9660 directory list");
- return (ARCHIVE_FATAL);
- }
- do {
- file = heap->reqs[0].file;
- if (file->ce_offset + file->ce_size > step) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Malformed CE information");
- return (ARCHIVE_FATAL);
- }
- p = b + file->ce_offset;
- end = p + file->ce_size;
- next_CE(heap);
- r = parse_rockridge(a, file, p, end);
- if (r != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- } while (heap->cnt &&
- heap->reqs[0].offset == iso9660->current_position);
- /* NOTE: Do not move this consume's code to front of
- * do-while loop. Registration of nested CE extension
- * might cause error because of current position. */
- __archive_read_consume(a, step);
- iso9660->current_position += step;
- }
- return (ARCHIVE_OK);
-}
-
-static void
-parse_rockridge_NM1(struct file_info *file,
- const unsigned char *data, int data_length)
-{
- if (!file->name_continues)
- archive_string_empty(&file->name);
- file->name_continues = 0;
- if (data_length < 1)
- return;
- /*
- * NM version 1 extension comprises:
- * 1 byte flag, value is one of:
- * = 0: remainder is name
- * = 1: remainder is name, next NM entry continues name
- * = 2: "."
- * = 4: ".."
- * = 32: Implementation specific
- * All other values are reserved.
- */
- switch(data[0]) {
- case 0:
- if (data_length < 2)
- return;
- archive_strncat(&file->name,
- (const char *)data + 1, data_length - 1);
- break;
- case 1:
- if (data_length < 2)
- return;
- archive_strncat(&file->name,
- (const char *)data + 1, data_length - 1);
- file->name_continues = 1;
- break;
- case 2:
- archive_strcat(&file->name, ".");
- break;
- case 4:
- archive_strcat(&file->name, "..");
- break;
- default:
- return;
- }
-
-}
-
-static void
-parse_rockridge_TF1(struct file_info *file, const unsigned char *data,
- int data_length)
-{
- char flag;
- /*
- * TF extension comprises:
- * one byte flag
- * create time (optional)
- * modify time (optional)
- * access time (optional)
- * attribute time (optional)
- * Time format and presence of fields
- * is controlled by flag bits.
- */
- if (data_length < 1)
- return;
- flag = data[0];
- ++data;
- --data_length;
- if (flag & 0x80) {
- /* Use 17-byte time format. */
- if ((flag & 1) && data_length >= 17) {
- /* Create time. */
- file->birthtime_is_set = 1;
- file->birthtime = isodate17(data);
- data += 17;
- data_length -= 17;
- }
- if ((flag & 2) && data_length >= 17) {
- /* Modify time. */
- file->mtime = isodate17(data);
- data += 17;
- data_length -= 17;
- }
- if ((flag & 4) && data_length >= 17) {
- /* Access time. */
- file->atime = isodate17(data);
- data += 17;
- data_length -= 17;
- }
- if ((flag & 8) && data_length >= 17) {
- /* Attribute change time. */
- file->ctime = isodate17(data);
- }
- } else {
- /* Use 7-byte time format. */
- if ((flag & 1) && data_length >= 7) {
- /* Create time. */
- file->birthtime_is_set = 1;
- file->birthtime = isodate7(data);
- data += 7;
- data_length -= 7;
- }
- if ((flag & 2) && data_length >= 7) {
- /* Modify time. */
- file->mtime = isodate7(data);
- data += 7;
- data_length -= 7;
- }
- if ((flag & 4) && data_length >= 7) {
- /* Access time. */
- file->atime = isodate7(data);
- data += 7;
- data_length -= 7;
- }
- if ((flag & 8) && data_length >= 7) {
- /* Attribute change time. */
- file->ctime = isodate7(data);
- }
- }
-}
-
-static void
-parse_rockridge_SL1(struct file_info *file, const unsigned char *data,
- int data_length)
-{
- const char *separator = "";
-
- if (!file->symlink_continues || file->symlink.length < 1)
- archive_string_empty(&file->symlink);
- file->symlink_continues = 0;
-
- /*
- * Defined flag values:
- * 0: This is the last SL record for this symbolic link
- * 1: this symbolic link field continues in next SL entry
- * All other values are reserved.
- */
- if (data_length < 1)
- return;
- switch(*data) {
- case 0:
- break;
- case 1:
- file->symlink_continues = 1;
- break;
- default:
- return;
- }
- ++data; /* Skip flag byte. */
- --data_length;
-
- /*
- * SL extension body stores "components".
- * Basically, this is a complicated way of storing
- * a POSIX path. It also interferes with using
- * symlinks for storing non-path data. <sigh>
- *
- * Each component is 2 bytes (flag and length)
- * possibly followed by name data.
- */
- while (data_length >= 2) {
- unsigned char flag = *data++;
- unsigned char nlen = *data++;
- data_length -= 2;
-
- archive_strcat(&file->symlink, separator);
- separator = "/";
-
- switch(flag) {
- case 0: /* Usual case, this is text. */
- if (data_length < nlen)
- return;
- archive_strncat(&file->symlink,
- (const char *)data, nlen);
- break;
- case 0x01: /* Text continues in next component. */
- if (data_length < nlen)
- return;
- archive_strncat(&file->symlink,
- (const char *)data, nlen);
- separator = "";
- break;
- case 0x02: /* Current dir. */
- archive_strcat(&file->symlink, ".");
- break;
- case 0x04: /* Parent dir. */
- archive_strcat(&file->symlink, "..");
- break;
- case 0x08: /* Root of filesystem. */
- archive_strcat(&file->symlink, "/");
- separator = "";
- break;
- case 0x10: /* Undefined (historically "volume root" */
- archive_string_empty(&file->symlink);
- archive_strcat(&file->symlink, "ROOT");
- break;
- case 0x20: /* Undefined (historically "hostname") */
- archive_strcat(&file->symlink, "hostname");
- break;
- default:
- /* TODO: issue a warning ? */
- return;
- }
- data += nlen;
- data_length -= nlen;
- }
-}
-
-static void
-parse_rockridge_ZF1(struct file_info *file, const unsigned char *data,
- int data_length)
-{
-
- if (data[0] == 0x70 && data[1] == 0x7a && data_length == 12) {
- /* paged zlib */
- file->pz = 1;
- file->pz_log2_bs = data[3];
- file->pz_uncompressed_size = archive_le32dec(&data[4]);
- }
-}
-
-static void
-register_file(struct iso9660 *iso9660, struct file_info *file)
-{
-
- file->use_next = iso9660->use_files;
- iso9660->use_files = file;
-}
-
-static void
-release_files(struct iso9660 *iso9660)
-{
- struct content *con, *connext;
- struct file_info *file;
-
- file = iso9660->use_files;
- while (file != NULL) {
- struct file_info *next = file->use_next;
-
- archive_string_free(&file->name);
- archive_string_free(&file->symlink);
- free(file->utf16be_name);
- con = file->contents.first;
- while (con != NULL) {
- connext = con->next;
- free(con);
- con = connext;
- }
- free(file);
- file = next;
- }
-}
-
-static int
-next_entry_seek(struct archive_read *a, struct iso9660 *iso9660,
- struct file_info **pfile)
-{
- struct file_info *file;
- int r;
-
- r = next_cache_entry(a, iso9660, pfile);
- if (r != ARCHIVE_OK)
- return (r);
- file = *pfile;
-
- /* Don't waste time seeking for zero-length bodies. */
- if (file->size == 0)
- file->offset = iso9660->current_position;
-
- /* flush any remaining bytes from the last round to ensure
- * we're positioned */
- if (iso9660->entry_bytes_unconsumed) {
- __archive_read_consume(a, iso9660->entry_bytes_unconsumed);
- iso9660->entry_bytes_unconsumed = 0;
- }
-
- /* Seek forward to the start of the entry. */
- if (iso9660->current_position < file->offset) {
- int64_t step;
-
- step = file->offset - iso9660->current_position;
- step = __archive_read_consume(a, step);
- if (step < 0)
- return ((int)step);
- iso9660->current_position = file->offset;
- }
-
- /* We found body of file; handle it now. */
- return (ARCHIVE_OK);
-}
-
-static int
-next_cache_entry(struct archive_read *a, struct iso9660 *iso9660,
- struct file_info **pfile)
-{
- struct file_info *file;
- struct {
- struct file_info *first;
- struct file_info **last;
- } empty_files;
- int64_t number;
- int count;
-
- file = cache_get_entry(iso9660);
- if (file != NULL) {
- *pfile = file;
- return (ARCHIVE_OK);
- }
-
- for (;;) {
- struct file_info *re, *d;
-
- *pfile = file = next_entry(iso9660);
- if (file == NULL) {
- /*
- * If directory entries all which are descendant of
- * rr_moved are still remaining, expose their.
- */
- if (iso9660->re_files.first != NULL &&
- iso9660->rr_moved != NULL &&
- iso9660->rr_moved->rr_moved_has_re_only)
- /* Expose "rr_moved" entry. */
- cache_add_entry(iso9660, iso9660->rr_moved);
- while ((re = re_get_entry(iso9660)) != NULL) {
- /* Expose its descendant dirs. */
- while ((d = rede_get_entry(re)) != NULL)
- cache_add_entry(iso9660, d);
- }
- if (iso9660->cache_files.first != NULL)
- return (next_cache_entry(a, iso9660, pfile));
- return (ARCHIVE_EOF);
- }
-
- if (file->cl_offset) {
- struct file_info *first_re = NULL;
- int nexted_re = 0;
-
- /*
- * Find "RE" dir for the current file, which
- * has "CL" flag.
- */
- while ((re = re_get_entry(iso9660))
- != first_re) {
- if (first_re == NULL)
- first_re = re;
- if (re->offset == file->cl_offset) {
- re->parent->subdirs--;
- re->parent = file->parent;
- re->re = 0;
- if (re->parent->re_descendant) {
- nexted_re = 1;
- re->re_descendant = 1;
- if (rede_add_entry(re) < 0)
- goto fatal_rr;
- /* Move a list of descendants
- * to a new ancestor. */
- while ((d = rede_get_entry(
- re)) != NULL)
- if (rede_add_entry(d)
- < 0)
- goto fatal_rr;
- break;
- }
- /* Replace the current file
- * with "RE" dir */
- *pfile = file = re;
- /* Expose its descendant */
- while ((d = rede_get_entry(
- file)) != NULL)
- cache_add_entry(
- iso9660, d);
- break;
- } else
- re_add_entry(iso9660, re);
- }
- if (nexted_re) {
- /*
- * Do not expose this at this time
- * because we have not gotten its full-path
- * name yet.
- */
- continue;
- }
- } else if ((file->mode & AE_IFMT) == AE_IFDIR) {
- int r;
-
- /* Read file entries in this dir. */
- r = read_children(a, file);
- if (r != ARCHIVE_OK)
- return (r);
-
- /*
- * Handle a special dir of Rockridge extensions,
- * "rr_moved".
- */
- if (file->rr_moved) {
- /*
- * If this has only the subdirectories which
- * have "RE" flags, do not expose at this time.
- */
- if (file->rr_moved_has_re_only)
- continue;
- /* Otherwise expose "rr_moved" entry. */
- } else if (file->re) {
- /*
- * Do not expose this at this time
- * because we have not gotten its full-path
- * name yet.
- */
- re_add_entry(iso9660, file);
- continue;
- } else if (file->re_descendant) {
- /*
- * If the top level "RE" entry of this entry
- * is not exposed, we, accordingly, should not
- * expose this entry at this time because
- * we cannot make its proper full-path name.
- */
- if (rede_add_entry(file) == 0)
- continue;
- /* Otherwise we can expose this entry because
- * it seems its top level "RE" has already been
- * exposed. */
- }
- }
- break;
- }
-
- if ((file->mode & AE_IFMT) != AE_IFREG || file->number == -1)
- return (ARCHIVE_OK);
-
- count = 0;
- number = file->number;
- iso9660->cache_files.first = NULL;
- iso9660->cache_files.last = &(iso9660->cache_files.first);
- empty_files.first = NULL;
- empty_files.last = &empty_files.first;
- /* Collect files which has the same file serial number.
- * Peek pending_files so that file which number is different
- * is not put back. */
- while (iso9660->pending_files.used > 0 &&
- (iso9660->pending_files.files[0]->number == -1 ||
- iso9660->pending_files.files[0]->number == number)) {
- if (file->number == -1) {
- /* This file has the same offset
- * but it's wrong offset which empty files
- * and symlink files have.
- * NOTE: This wrong offset was recorded by
- * old mkisofs utility. If ISO images is
- * created by latest mkisofs, this does not
- * happen.
- */
- file->next = NULL;
- *empty_files.last = file;
- empty_files.last = &(file->next);
- } else {
- count++;
- cache_add_entry(iso9660, file);
- }
- file = next_entry(iso9660);
- }
-
- if (count == 0) {
- *pfile = file;
- return ((file == NULL)?ARCHIVE_EOF:ARCHIVE_OK);
- }
- if (file->number == -1) {
- file->next = NULL;
- *empty_files.last = file;
- empty_files.last = &(file->next);
- } else {
- count++;
- cache_add_entry(iso9660, file);
- }
-
- if (count > 1) {
- /* The count is the same as number of hardlink,
- * so much so that each nlinks of files in cache_file
- * is overwritten by value of the count.
- */
- for (file = iso9660->cache_files.first;
- file != NULL; file = file->next)
- file->nlinks = count;
- }
- /* If there are empty files, that files are added
- * to the tail of the cache_files. */
- if (empty_files.first != NULL) {
- *iso9660->cache_files.last = empty_files.first;
- iso9660->cache_files.last = empty_files.last;
- }
- *pfile = cache_get_entry(iso9660);
- return ((*pfile == NULL)?ARCHIVE_EOF:ARCHIVE_OK);
-
-fatal_rr:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Failed to connect 'CL' pointer to 'RE' rr_moved pointer of "
- "Rockridge extensions: current position = %jd, CL offset = %jd",
- (intmax_t)iso9660->current_position, (intmax_t)file->cl_offset);
- return (ARCHIVE_FATAL);
-}
-
-static inline void
-re_add_entry(struct iso9660 *iso9660, struct file_info *file)
-{
- file->re_next = NULL;
- *iso9660->re_files.last = file;
- iso9660->re_files.last = &(file->re_next);
-}
-
-static inline struct file_info *
-re_get_entry(struct iso9660 *iso9660)
-{
- struct file_info *file;
-
- if ((file = iso9660->re_files.first) != NULL) {
- iso9660->re_files.first = file->re_next;
- if (iso9660->re_files.first == NULL)
- iso9660->re_files.last =
- &(iso9660->re_files.first);
- }
- return (file);
-}
-
-static inline int
-rede_add_entry(struct file_info *file)
-{
- struct file_info *re;
-
- /*
- * Find "RE" entry.
- */
- re = file->parent;
- while (re != NULL && !re->re)
- re = re->parent;
- if (re == NULL)
- return (-1);
-
- file->re_next = NULL;
- *re->rede_files.last = file;
- re->rede_files.last = &(file->re_next);
- return (0);
-}
-
-static inline struct file_info *
-rede_get_entry(struct file_info *re)
-{
- struct file_info *file;
-
- if ((file = re->rede_files.first) != NULL) {
- re->rede_files.first = file->re_next;
- if (re->rede_files.first == NULL)
- re->rede_files.last =
- &(re->rede_files.first);
- }
- return (file);
-}
-
-static inline void
-cache_add_entry(struct iso9660 *iso9660, struct file_info *file)
-{
- file->next = NULL;
- *iso9660->cache_files.last = file;
- iso9660->cache_files.last = &(file->next);
-}
-
-static inline struct file_info *
-cache_get_entry(struct iso9660 *iso9660)
-{
- struct file_info *file;
-
- if ((file = iso9660->cache_files.first) != NULL) {
- iso9660->cache_files.first = file->next;
- if (iso9660->cache_files.first == NULL)
- iso9660->cache_files.last =
- &(iso9660->cache_files.first);
- }
- return (file);
-}
-
-static int
-heap_add_entry(struct archive_read *a, struct heap_queue *heap,
- struct file_info *file, uint64_t key)
-{
- uint64_t file_key, parent_key;
- int hole, parent;
-
- /* Expand our pending files list as necessary. */
- if (heap->used >= heap->allocated) {
- struct file_info **new_pending_files;
- int new_size = heap->allocated * 2;
-
- if (heap->allocated < 1024)
- new_size = 1024;
- /* Overflow might keep us from growing the list. */
- if (new_size <= heap->allocated) {
- archive_set_error(&a->archive,
- ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- new_pending_files = (struct file_info **)
- malloc(new_size * sizeof(new_pending_files[0]));
- if (new_pending_files == NULL) {
- archive_set_error(&a->archive,
- ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- if (heap->allocated)
- memcpy(new_pending_files, heap->files,
- heap->allocated * sizeof(new_pending_files[0]));
- free(heap->files);
- heap->files = new_pending_files;
- heap->allocated = new_size;
- }
-
- file_key = file->key = key;
-
- /*
- * Start with hole at end, walk it up tree to find insertion point.
- */
- hole = heap->used++;
- while (hole > 0) {
- parent = (hole - 1)/2;
- parent_key = heap->files[parent]->key;
- if (file_key >= parent_key) {
- heap->files[hole] = file;
- return (ARCHIVE_OK);
- }
- /* Move parent into hole <==> move hole up tree. */
- heap->files[hole] = heap->files[parent];
- hole = parent;
- }
- heap->files[0] = file;
-
- return (ARCHIVE_OK);
-}
-
-static struct file_info *
-heap_get_entry(struct heap_queue *heap)
-{
- uint64_t a_key, b_key, c_key;
- int a, b, c;
- struct file_info *r, *tmp;
-
- if (heap->used < 1)
- return (NULL);
-
- /*
- * The first file in the list is the earliest; we'll return this.
- */
- r = heap->files[0];
-
- /*
- * Move the last item in the heap to the root of the tree
- */
- heap->files[0] = heap->files[--(heap->used)];
-
- /*
- * Rebalance the heap.
- */
- a = 0; /* Starting element and its heap key */
- a_key = heap->files[a]->key;
- for (;;) {
- b = a + a + 1; /* First child */
- if (b >= heap->used)
- return (r);
- b_key = heap->files[b]->key;
- c = b + 1; /* Use second child if it is smaller. */
- if (c < heap->used) {
- c_key = heap->files[c]->key;
- if (c_key < b_key) {
- b = c;
- b_key = c_key;
- }
- }
- if (a_key <= b_key)
- return (r);
- tmp = heap->files[a];
- heap->files[a] = heap->files[b];
- heap->files[b] = tmp;
- a = b;
- }
-}
-
-static unsigned int
-toi(const void *p, int n)
-{
- const unsigned char *v = (const unsigned char *)p;
- if (n > 1)
- return v[0] + 256 * toi(v + 1, n - 1);
- if (n == 1)
- return v[0];
- return (0);
-}
-
-static time_t
-isodate7(const unsigned char *v)
-{
- struct tm tm;
- int offset;
- time_t t;
-
- memset(&tm, 0, sizeof(tm));
- tm.tm_year = v[0];
- tm.tm_mon = v[1] - 1;
- tm.tm_mday = v[2];
- tm.tm_hour = v[3];
- tm.tm_min = v[4];
- tm.tm_sec = v[5];
- /* v[6] is the signed timezone offset, in 1/4-hour increments. */
- offset = ((const signed char *)v)[6];
- if (offset > -48 && offset < 52) {
- tm.tm_hour -= offset / 4;
- tm.tm_min -= (offset % 4) * 15;
- }
- t = time_from_tm(&tm);
- if (t == (time_t)-1)
- return ((time_t)0);
- return (t);
-}
-
-static time_t
-isodate17(const unsigned char *v)
-{
- struct tm tm;
- int offset;
- time_t t;
-
- memset(&tm, 0, sizeof(tm));
- tm.tm_year = (v[0] - '0') * 1000 + (v[1] - '0') * 100
- + (v[2] - '0') * 10 + (v[3] - '0')
- - 1900;
- tm.tm_mon = (v[4] - '0') * 10 + (v[5] - '0');
- tm.tm_mday = (v[6] - '0') * 10 + (v[7] - '0');
- tm.tm_hour = (v[8] - '0') * 10 + (v[9] - '0');
- tm.tm_min = (v[10] - '0') * 10 + (v[11] - '0');
- tm.tm_sec = (v[12] - '0') * 10 + (v[13] - '0');
- /* v[16] is the signed timezone offset, in 1/4-hour increments. */
- offset = ((const signed char *)v)[16];
- if (offset > -48 && offset < 52) {
- tm.tm_hour -= offset / 4;
- tm.tm_min -= (offset % 4) * 15;
- }
- t = time_from_tm(&tm);
- if (t == (time_t)-1)
- return ((time_t)0);
- return (t);
-}
-
-static time_t
-time_from_tm(struct tm *t)
-{
-#if HAVE__MKGMTIME
- return _mkgmtime(t);
-#elif HAVE_TIMEGM
- /* Use platform timegm() if available. */
- return (timegm(t));
-#else
- /* Else use direct calculation using POSIX assumptions. */
- /* First, fix up tm_yday based on the year/month/day. */
- if (mktime(t) == (time_t)-1)
- return ((time_t)-1);
- /* Then we can compute timegm() from first principles. */
- return (t->tm_sec
- + t->tm_min * 60
- + t->tm_hour * 3600
- + t->tm_yday * 86400
- + (t->tm_year - 70) * 31536000
- + ((t->tm_year - 69) / 4) * 86400
- - ((t->tm_year - 1) / 100) * 86400
- + ((t->tm_year + 299) / 400) * 86400);
-#endif
-}
-
-static const char *
-build_pathname(struct archive_string *as, struct file_info *file, int depth)
-{
- // Plain ISO9660 only allows 8 dir levels; if we get
- // to 1000, then something is very, very wrong.
- if (depth > 1000) {
- return NULL;
- }
- if (file->parent != NULL && archive_strlen(&file->parent->name) > 0) {
- if (build_pathname(as, file->parent, depth + 1) == NULL) {
- return NULL;
- }
- archive_strcat(as, "/");
- }
- if (archive_strlen(&file->name) == 0)
- archive_strcat(as, ".");
- else
- archive_string_concat(as, &file->name);
- return (as->s);
-}
-
-static int
-build_pathname_utf16be(unsigned char *p, size_t max, size_t *len,
- struct file_info *file)
-{
- if (file->parent != NULL && file->parent->utf16be_bytes > 0) {
- if (build_pathname_utf16be(p, max, len, file->parent) != 0)
- return (-1);
- p[*len] = 0;
- p[*len + 1] = '/';
- *len += 2;
- }
- if (file->utf16be_bytes == 0) {
- if (*len + 2 > max)
- return (-1);/* Path is too long! */
- p[*len] = 0;
- p[*len + 1] = '.';
- *len += 2;
- } else {
- if (*len + file->utf16be_bytes > max)
- return (-1);/* Path is too long! */
- memcpy(p + *len, file->utf16be_name, file->utf16be_bytes);
- *len += file->utf16be_bytes;
- }
- return (0);
-}
-
-#if DEBUG
-static void
-dump_isodirrec(FILE *out, const unsigned char *isodirrec)
-{
- fprintf(out, " l %d,",
- toi(isodirrec + DR_length_offset, DR_length_size));
- fprintf(out, " a %d,",
- toi(isodirrec + DR_ext_attr_length_offset, DR_ext_attr_length_size));
- fprintf(out, " ext 0x%x,",
- toi(isodirrec + DR_extent_offset, DR_extent_size));
- fprintf(out, " s %d,",
- toi(isodirrec + DR_size_offset, DR_extent_size));
- fprintf(out, " f 0x%x,",
- toi(isodirrec + DR_flags_offset, DR_flags_size));
- fprintf(out, " u %d,",
- toi(isodirrec + DR_file_unit_size_offset, DR_file_unit_size_size));
- fprintf(out, " ilv %d,",
- toi(isodirrec + DR_interleave_offset, DR_interleave_size));
- fprintf(out, " seq %d,",
- toi(isodirrec + DR_volume_sequence_number_offset,
- DR_volume_sequence_number_size));
- fprintf(out, " nl %d:",
- toi(isodirrec + DR_name_len_offset, DR_name_len_size));
- fprintf(out, " `%.*s'",
- toi(isodirrec + DR_name_len_offset, DR_name_len_size),
- isodirrec + DR_name_offset);
-}
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_format_lha.c b/contrib/libs/libarchive/libarchive/archive_read_support_format_lha.c
deleted file mode 100644
index 1c64b2900b..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_format_lha.c
+++ /dev/null
@@ -1,2919 +0,0 @@
-/*-
- * Copyright (c) 2008-2014 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-#include "archive_endian.h"
-
-
-#define MAXMATCH 256 /* Maximum match length. */
-#define MINMATCH 3 /* Minimum match length. */
-/*
- * Literal table format:
- * +0 +256 +510
- * +---------------+-------------------------+
- * | literal code | match length |
- * | 0 ... 255 | MINMATCH ... MAXMATCH |
- * +---------------+-------------------------+
- * <--- LT_BITLEN_SIZE --->
- */
-/* Literal table size. */
-#define LT_BITLEN_SIZE (UCHAR_MAX + 1 + MAXMATCH - MINMATCH + 1)
-/* Position table size.
- * Note: this used for both position table and pre literal table.*/
-#define PT_BITLEN_SIZE (3 + 16)
-
-struct lzh_dec {
- /* Decoding status. */
- int state;
-
- /*
- * Window to see last 8Ki(lh5),32Ki(lh6),64Ki(lh7) bytes of decoded
- * data.
- */
- int w_size;
- int w_mask;
- /* Window buffer, which is a loop buffer. */
- unsigned char *w_buff;
- /* The insert position to the window. */
- int w_pos;
- /* The position where we can copy decoded code from the window. */
- int copy_pos;
- /* The length how many bytes we can copy decoded code from
- * the window. */
- int copy_len;
-
- /*
- * Bit stream reader.
- */
- struct lzh_br {
-#define CACHE_TYPE uint64_t
-#define CACHE_BITS (8 * sizeof(CACHE_TYPE))
- /* Cache buffer. */
- CACHE_TYPE cache_buffer;
- /* Indicates how many bits avail in cache_buffer. */
- int cache_avail;
- } br;
-
- /*
- * Huffman coding.
- */
- struct huffman {
- int len_size;
- int len_avail;
- int len_bits;
- int freq[17];
- unsigned char *bitlen;
-
- /*
- * Use a index table. It's faster than searching a huffman
- * coding tree, which is a binary tree. But a use of a large
- * index table causes L1 cache read miss many times.
- */
-#define HTBL_BITS 10
- int max_bits;
- int shift_bits;
- int tbl_bits;
- int tree_used;
- int tree_avail;
- /* Direct access table. */
- uint16_t *tbl;
- /* Binary tree table for extra bits over the direct access. */
- struct htree_t {
- uint16_t left;
- uint16_t right;
- } *tree;
- } lt, pt;
-
- int blocks_avail;
- int pos_pt_len_size;
- int pos_pt_len_bits;
- int literal_pt_len_size;
- int literal_pt_len_bits;
- int reading_position;
- int loop;
- int error;
-};
-
-struct lzh_stream {
- const unsigned char *next_in;
- int avail_in;
- int64_t total_in;
- const unsigned char *ref_ptr;
- int avail_out;
- int64_t total_out;
- struct lzh_dec *ds;
-};
-
-struct lha {
- /* entry_bytes_remaining is the number of bytes we expect. */
- int64_t entry_offset;
- int64_t entry_bytes_remaining;
- int64_t entry_unconsumed;
- uint16_t entry_crc_calculated;
-
- size_t header_size; /* header size */
- unsigned char level; /* header level */
- char method[3]; /* compress type */
- int64_t compsize; /* compressed data size */
- int64_t origsize; /* original file size */
- int setflag;
-#define BIRTHTIME_IS_SET 1
-#define ATIME_IS_SET 2
-#define UNIX_MODE_IS_SET 4
-#define CRC_IS_SET 8
- time_t birthtime;
- long birthtime_tv_nsec;
- time_t mtime;
- long mtime_tv_nsec;
- time_t atime;
- long atime_tv_nsec;
- mode_t mode;
- int64_t uid;
- int64_t gid;
- struct archive_string uname;
- struct archive_string gname;
- uint16_t header_crc;
- uint16_t crc;
- /* dirname and filename could be in different codepages */
- struct archive_string_conv *sconv_dir;
- struct archive_string_conv *sconv_fname;
- struct archive_string_conv *opt_sconv;
-
- struct archive_string dirname;
- struct archive_string filename;
- struct archive_wstring ws;
-
- unsigned char dos_attr;
-
- /* Flag to mark progress that an archive was read their first header.*/
- char found_first_header;
- /* Flag to mark that indicates an empty directory. */
- char directory;
-
- /* Flags to mark progress of decompression. */
- char decompress_init;
- char end_of_entry;
- char end_of_entry_cleanup;
- char entry_is_compressed;
-
- char format_name[64];
-
- struct lzh_stream strm;
-};
-
-/*
- * LHA header common member offset.
- */
-#define H_METHOD_OFFSET 2 /* Compress type. */
-#define H_ATTR_OFFSET 19 /* DOS attribute. */
-#define H_LEVEL_OFFSET 20 /* Header Level. */
-#define H_SIZE 22 /* Minimum header size. */
-
-static int archive_read_format_lha_bid(struct archive_read *, int);
-static int archive_read_format_lha_options(struct archive_read *,
- const char *, const char *);
-static int archive_read_format_lha_read_header(struct archive_read *,
- struct archive_entry *);
-static int archive_read_format_lha_read_data(struct archive_read *,
- const void **, size_t *, int64_t *);
-static int archive_read_format_lha_read_data_skip(struct archive_read *);
-static int archive_read_format_lha_cleanup(struct archive_read *);
-
-static void lha_replace_path_separator(struct lha *,
- struct archive_entry *);
-static int lha_read_file_header_0(struct archive_read *, struct lha *);
-static int lha_read_file_header_1(struct archive_read *, struct lha *);
-static int lha_read_file_header_2(struct archive_read *, struct lha *);
-static int lha_read_file_header_3(struct archive_read *, struct lha *);
-static int lha_read_file_extended_header(struct archive_read *,
- struct lha *, uint16_t *, int, size_t, size_t *);
-static size_t lha_check_header_format(const void *);
-static int lha_skip_sfx(struct archive_read *);
-static time_t lha_dos_time(const unsigned char *);
-static time_t lha_win_time(uint64_t, long *);
-static unsigned char lha_calcsum(unsigned char, const void *,
- int, size_t);
-static int lha_parse_linkname(struct archive_wstring *,
- struct archive_wstring *);
-static int lha_read_data_none(struct archive_read *, const void **,
- size_t *, int64_t *);
-static int lha_read_data_lzh(struct archive_read *, const void **,
- size_t *, int64_t *);
-static void lha_crc16_init(void);
-static uint16_t lha_crc16(uint16_t, const void *, size_t);
-static int lzh_decode_init(struct lzh_stream *, const char *);
-static void lzh_decode_free(struct lzh_stream *);
-static int lzh_decode(struct lzh_stream *, int);
-static int lzh_br_fillup(struct lzh_stream *, struct lzh_br *);
-static int lzh_huffman_init(struct huffman *, size_t, int);
-static void lzh_huffman_free(struct huffman *);
-static int lzh_read_pt_bitlen(struct lzh_stream *, int start, int end);
-static int lzh_make_fake_table(struct huffman *, uint16_t);
-static int lzh_make_huffman_table(struct huffman *);
-static inline int lzh_decode_huffman(struct huffman *, unsigned);
-static int lzh_decode_huffman_tree(struct huffman *, unsigned, int);
-
-
-int
-archive_read_support_format_lha(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- struct lha *lha;
- int r;
-
- archive_check_magic(_a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_format_lha");
-
- lha = (struct lha *)calloc(1, sizeof(*lha));
- if (lha == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate lha data");
- return (ARCHIVE_FATAL);
- }
- archive_string_init(&lha->ws);
-
- r = __archive_read_register_format(a,
- lha,
- "lha",
- archive_read_format_lha_bid,
- archive_read_format_lha_options,
- archive_read_format_lha_read_header,
- archive_read_format_lha_read_data,
- archive_read_format_lha_read_data_skip,
- NULL,
- archive_read_format_lha_cleanup,
- NULL,
- NULL);
-
- if (r != ARCHIVE_OK)
- free(lha);
- return (ARCHIVE_OK);
-}
-
-static size_t
-lha_check_header_format(const void *h)
-{
- const unsigned char *p = h;
- size_t next_skip_bytes;
-
- switch (p[H_METHOD_OFFSET+3]) {
- /*
- * "-lh0-" ... "-lh7-" "-lhd-"
- * "-lzs-" "-lz5-"
- */
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- case 'd':
- case 's':
- next_skip_bytes = 4;
-
- /* b0 == 0 means the end of an LHa archive file. */
- if (p[0] == 0)
- break;
- if (p[H_METHOD_OFFSET] != '-' || p[H_METHOD_OFFSET+1] != 'l'
- || p[H_METHOD_OFFSET+4] != '-')
- break;
-
- if (p[H_METHOD_OFFSET+2] == 'h') {
- /* "-lh?-" */
- if (p[H_METHOD_OFFSET+3] == 's')
- break;
- if (p[H_LEVEL_OFFSET] == 0)
- return (0);
- if (p[H_LEVEL_OFFSET] <= 3 && p[H_ATTR_OFFSET] == 0x20)
- return (0);
- }
- if (p[H_METHOD_OFFSET+2] == 'z') {
- /* LArc extensions: -lzs-,-lz4- and -lz5- */
- if (p[H_LEVEL_OFFSET] != 0)
- break;
- if (p[H_METHOD_OFFSET+3] == 's'
- || p[H_METHOD_OFFSET+3] == '4'
- || p[H_METHOD_OFFSET+3] == '5')
- return (0);
- }
- break;
- case 'h': next_skip_bytes = 1; break;
- case 'z': next_skip_bytes = 1; break;
- case 'l': next_skip_bytes = 2; break;
- case '-': next_skip_bytes = 3; break;
- default : next_skip_bytes = 4; break;
- }
-
- return (next_skip_bytes);
-}
-
-static int
-archive_read_format_lha_bid(struct archive_read *a, int best_bid)
-{
- const char *p;
- const void *buff;
- ssize_t bytes_avail, offset, window;
- size_t next;
-
- /* If there's already a better bid than we can ever
- make, don't bother testing. */
- if (best_bid > 30)
- return (-1);
-
- if ((p = __archive_read_ahead(a, H_SIZE, NULL)) == NULL)
- return (-1);
-
- if (lha_check_header_format(p) == 0)
- return (30);
-
- if (p[0] == 'M' && p[1] == 'Z') {
- /* PE file */
- offset = 0;
- window = 4096;
- while (offset < (1024 * 20)) {
- buff = __archive_read_ahead(a, offset + window,
- &bytes_avail);
- if (buff == NULL) {
- /* Remaining bytes are less than window. */
- window >>= 1;
- if (window < (H_SIZE + 3))
- return (0);
- continue;
- }
- p = (const char *)buff + offset;
- while (p + H_SIZE < (const char *)buff + bytes_avail) {
- if ((next = lha_check_header_format(p)) == 0)
- return (30);
- p += next;
- }
- offset = p - (const char *)buff;
- }
- }
- return (0);
-}
-
-static int
-archive_read_format_lha_options(struct archive_read *a,
- const char *key, const char *val)
-{
- struct lha *lha;
- int ret = ARCHIVE_FAILED;
-
- lha = (struct lha *)(a->format->data);
- if (strcmp(key, "hdrcharset") == 0) {
- if (val == NULL || val[0] == 0)
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "lha: hdrcharset option needs a character-set name");
- else {
- lha->opt_sconv =
- archive_string_conversion_from_charset(
- &a->archive, val, 0);
- if (lha->opt_sconv != NULL)
- ret = ARCHIVE_OK;
- else
- ret = ARCHIVE_FATAL;
- }
- return (ret);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-static int
-lha_skip_sfx(struct archive_read *a)
-{
- const void *h;
- const char *p, *q;
- size_t next, skip;
- ssize_t bytes, window;
-
- window = 4096;
- for (;;) {
- h = __archive_read_ahead(a, window, &bytes);
- if (h == NULL) {
- /* Remaining bytes are less than window. */
- window >>= 1;
- if (window < (H_SIZE + 3))
- goto fatal;
- continue;
- }
- if (bytes < H_SIZE)
- goto fatal;
- p = h;
- q = p + bytes;
-
- /*
- * Scan ahead until we find something that looks
- * like the lha header.
- */
- while (p + H_SIZE < q) {
- if ((next = lha_check_header_format(p)) == 0) {
- skip = p - (const char *)h;
- __archive_read_consume(a, skip);
- return (ARCHIVE_OK);
- }
- p += next;
- }
- skip = p - (const char *)h;
- __archive_read_consume(a, skip);
- }
-fatal:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Couldn't find out LHa header");
- return (ARCHIVE_FATAL);
-}
-
-static int
-truncated_error(struct archive_read *a)
-{
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated LHa header");
- return (ARCHIVE_FATAL);
-}
-
-static int
-archive_read_format_lha_read_header(struct archive_read *a,
- struct archive_entry *entry)
-{
- struct archive_wstring linkname;
- struct archive_wstring pathname;
- struct lha *lha;
- const unsigned char *p;
- const char *signature;
- int err;
- struct archive_mstring conv_buffer;
- const wchar_t *conv_buffer_p;
-
- lha_crc16_init();
-
- a->archive.archive_format = ARCHIVE_FORMAT_LHA;
- if (a->archive.archive_format_name == NULL)
- a->archive.archive_format_name = "lha";
-
- lha = (struct lha *)(a->format->data);
- lha->decompress_init = 0;
- lha->end_of_entry = 0;
- lha->end_of_entry_cleanup = 0;
- lha->entry_unconsumed = 0;
-
- if ((p = __archive_read_ahead(a, H_SIZE, NULL)) == NULL) {
- /*
- * LHa archiver added 0 to the tail of its archive file as
- * the mark of the end of the archive.
- */
- signature = __archive_read_ahead(a, sizeof(signature[0]), NULL);
- if (signature == NULL || signature[0] == 0)
- return (ARCHIVE_EOF);
- return (truncated_error(a));
- }
-
- signature = (const char *)p;
- if (lha->found_first_header == 0 &&
- signature[0] == 'M' && signature[1] == 'Z') {
- /* This is an executable? Must be self-extracting... */
- err = lha_skip_sfx(a);
- if (err < ARCHIVE_WARN)
- return (err);
-
- if ((p = __archive_read_ahead(a, sizeof(*p), NULL)) == NULL)
- return (truncated_error(a));
- signature = (const char *)p;
- }
- /* signature[0] == 0 means the end of an LHa archive file. */
- if (signature[0] == 0)
- return (ARCHIVE_EOF);
-
- /*
- * Check the header format and method type.
- */
- if (lha_check_header_format(p) != 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Bad LHa file");
- return (ARCHIVE_FATAL);
- }
-
- /* We've found the first header. */
- lha->found_first_header = 1;
- /* Set a default value and common data */
- lha->header_size = 0;
- lha->level = p[H_LEVEL_OFFSET];
- lha->method[0] = p[H_METHOD_OFFSET+1];
- lha->method[1] = p[H_METHOD_OFFSET+2];
- lha->method[2] = p[H_METHOD_OFFSET+3];
- if (memcmp(lha->method, "lhd", 3) == 0)
- lha->directory = 1;
- else
- lha->directory = 0;
- if (memcmp(lha->method, "lh0", 3) == 0 ||
- memcmp(lha->method, "lz4", 3) == 0)
- lha->entry_is_compressed = 0;
- else
- lha->entry_is_compressed = 1;
-
- lha->compsize = 0;
- lha->origsize = 0;
- lha->setflag = 0;
- lha->birthtime = 0;
- lha->birthtime_tv_nsec = 0;
- lha->mtime = 0;
- lha->mtime_tv_nsec = 0;
- lha->atime = 0;
- lha->atime_tv_nsec = 0;
- lha->mode = (lha->directory)? 0777 : 0666;
- lha->uid = 0;
- lha->gid = 0;
- archive_string_empty(&lha->dirname);
- archive_string_empty(&lha->filename);
- lha->dos_attr = 0;
- if (lha->opt_sconv != NULL) {
- lha->sconv_dir = lha->opt_sconv;
- lha->sconv_fname = lha->opt_sconv;
- } else {
- lha->sconv_dir = NULL;
- lha->sconv_fname = NULL;
- }
-
- switch (p[H_LEVEL_OFFSET]) {
- case 0:
- err = lha_read_file_header_0(a, lha);
- break;
- case 1:
- err = lha_read_file_header_1(a, lha);
- break;
- case 2:
- err = lha_read_file_header_2(a, lha);
- break;
- case 3:
- err = lha_read_file_header_3(a, lha);
- break;
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unsupported LHa header level %d", p[H_LEVEL_OFFSET]);
- err = ARCHIVE_FATAL;
- break;
- }
- if (err < ARCHIVE_WARN)
- return (err);
-
-
- if (!lha->directory && archive_strlen(&lha->filename) == 0)
- /* The filename has not been set */
- return (truncated_error(a));
-
- /*
- * Make a pathname from a dirname and a filename, after converting to Unicode.
- * This is because codepages might differ between dirname and filename.
- */
- archive_string_init(&pathname);
- archive_string_init(&linkname);
- archive_string_init(&conv_buffer.aes_mbs);
- archive_string_init(&conv_buffer.aes_mbs_in_locale);
- archive_string_init(&conv_buffer.aes_utf8);
- archive_string_init(&conv_buffer.aes_wcs);
- if (0 != archive_mstring_copy_mbs_len_l(&conv_buffer, lha->dirname.s, lha->dirname.length, lha->sconv_dir)) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Pathname cannot be converted "
- "from %s to Unicode.",
- archive_string_conversion_charset_name(lha->sconv_dir));
- err = ARCHIVE_FATAL;
- } else if (0 != archive_mstring_get_wcs(&a->archive, &conv_buffer, &conv_buffer_p))
- err = ARCHIVE_FATAL;
- if (err == ARCHIVE_FATAL) {
- archive_mstring_clean(&conv_buffer);
- archive_wstring_free(&pathname);
- archive_wstring_free(&linkname);
- return (err);
- }
- archive_wstring_copy(&pathname, &conv_buffer.aes_wcs);
-
- archive_string_empty(&conv_buffer.aes_mbs);
- archive_string_empty(&conv_buffer.aes_mbs_in_locale);
- archive_string_empty(&conv_buffer.aes_utf8);
- archive_wstring_empty(&conv_buffer.aes_wcs);
- if (0 != archive_mstring_copy_mbs_len_l(&conv_buffer, lha->filename.s, lha->filename.length, lha->sconv_fname)) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Pathname cannot be converted "
- "from %s to Unicode.",
- archive_string_conversion_charset_name(lha->sconv_fname));
- err = ARCHIVE_FATAL;
- }
- else if (0 != archive_mstring_get_wcs(&a->archive, &conv_buffer, &conv_buffer_p))
- err = ARCHIVE_FATAL;
- if (err == ARCHIVE_FATAL) {
- archive_mstring_clean(&conv_buffer);
- archive_wstring_free(&pathname);
- archive_wstring_free(&linkname);
- return (err);
- }
- archive_wstring_concat(&pathname, &conv_buffer.aes_wcs);
- archive_mstring_clean(&conv_buffer);
-
- if ((lha->mode & AE_IFMT) == AE_IFLNK) {
- /*
- * Extract the symlink-name if it's included in the pathname.
- */
- if (!lha_parse_linkname(&linkname, &pathname)) {
- /* We couldn't get the symlink-name. */
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Unknown symlink-name");
- archive_wstring_free(&pathname);
- archive_wstring_free(&linkname);
- return (ARCHIVE_FAILED);
- }
- } else {
- /*
- * Make sure a file-type is set.
- * The mode has been overridden if it is in the extended data.
- */
- lha->mode = (lha->mode & ~AE_IFMT) |
- ((lha->directory)? AE_IFDIR: AE_IFREG);
- }
- if ((lha->setflag & UNIX_MODE_IS_SET) == 0 &&
- (lha->dos_attr & 1) != 0)
- lha->mode &= ~(0222);/* read only. */
-
- /*
- * Set basic file parameters.
- */
- archive_entry_copy_pathname_w(entry, pathname.s);
- archive_wstring_free(&pathname);
- if (archive_strlen(&linkname) > 0) {
- archive_entry_copy_symlink_w(entry, linkname.s);
- } else
- archive_entry_set_symlink(entry, NULL);
- archive_wstring_free(&linkname);
- /*
- * When a header level is 0, there is a possibility that
- * a pathname and a symlink has '\' character, a directory
- * separator in DOS/Windows. So we should convert it to '/'.
- */
- if (p[H_LEVEL_OFFSET] == 0)
- lha_replace_path_separator(lha, entry);
-
- archive_entry_set_mode(entry, lha->mode);
- archive_entry_set_uid(entry, lha->uid);
- archive_entry_set_gid(entry, lha->gid);
- if (archive_strlen(&lha->uname) > 0)
- archive_entry_set_uname(entry, lha->uname.s);
- if (archive_strlen(&lha->gname) > 0)
- archive_entry_set_gname(entry, lha->gname.s);
- if (lha->setflag & BIRTHTIME_IS_SET) {
- archive_entry_set_birthtime(entry, lha->birthtime,
- lha->birthtime_tv_nsec);
- archive_entry_set_ctime(entry, lha->birthtime,
- lha->birthtime_tv_nsec);
- } else {
- archive_entry_unset_birthtime(entry);
- archive_entry_unset_ctime(entry);
- }
- archive_entry_set_mtime(entry, lha->mtime, lha->mtime_tv_nsec);
- if (lha->setflag & ATIME_IS_SET)
- archive_entry_set_atime(entry, lha->atime,
- lha->atime_tv_nsec);
- else
- archive_entry_unset_atime(entry);
- if (lha->directory || archive_entry_symlink(entry) != NULL)
- archive_entry_unset_size(entry);
- else
- archive_entry_set_size(entry, lha->origsize);
-
- /*
- * Prepare variables used to read a file content.
- */
- lha->entry_bytes_remaining = lha->compsize;
- if (lha->entry_bytes_remaining < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid LHa entry size");
- return (ARCHIVE_FATAL);
- }
- lha->entry_offset = 0;
- lha->entry_crc_calculated = 0;
-
- /*
- * This file does not have a content.
- */
- if (lha->directory || lha->compsize == 0)
- lha->end_of_entry = 1;
-
- snprintf(lha->format_name, sizeof(lha->format_name), "lha -%c%c%c-",
- lha->method[0], lha->method[1], lha->method[2]);
- a->archive.archive_format_name = lha->format_name;
-
- return (err);
-}
-
-/*
- * Replace a DOS path separator '\' by a character '/'.
- * Some multi-byte character set have a character '\' in its second byte.
- */
-static void
-lha_replace_path_separator(struct lha *lha, struct archive_entry *entry)
-{
- const wchar_t *wp;
- size_t i;
-
- if ((wp = archive_entry_pathname_w(entry)) != NULL) {
- archive_wstrcpy(&(lha->ws), wp);
- for (i = 0; i < archive_strlen(&(lha->ws)); i++) {
- if (lha->ws.s[i] == L'\\')
- lha->ws.s[i] = L'/';
- }
- archive_entry_copy_pathname_w(entry, lha->ws.s);
- }
-
- if ((wp = archive_entry_symlink_w(entry)) != NULL) {
- archive_wstrcpy(&(lha->ws), wp);
- for (i = 0; i < archive_strlen(&(lha->ws)); i++) {
- if (lha->ws.s[i] == L'\\')
- lha->ws.s[i] = L'/';
- }
- archive_entry_copy_symlink_w(entry, lha->ws.s);
- }
-}
-
-/*
- * Header 0 format
- *
- * +0 +1 +2 +7 +11
- * +---------------+----------+----------------+-------------------+
- * |header size(*1)|header sum|compression type|compressed size(*2)|
- * +---------------+----------+----------------+-------------------+
- * <---------------------(*1)----------*
- *
- * +11 +15 +17 +19 +20 +21
- * +-----------------+---------+---------+--------------+----------------+
- * |uncompressed size|time(DOS)|date(DOS)|attribute(DOS)|header level(=0)|
- * +-----------------+---------+---------+--------------+----------------+
- * *--------------------------------(*1)---------------------------------*
- *
- * +21 +22 +22+(*3) +22+(*3)+2 +22+(*3)+2+(*4)
- * +---------------+---------+----------+----------------+------------------+
- * |name length(*3)|file name|file CRC16|extra header(*4)| compressed data |
- * +---------------+---------+----------+----------------+------------------+
- * <--(*3)-> <------(*2)------>
- * *----------------------(*1)-------------------------->
- *
- */
-#define H0_HEADER_SIZE_OFFSET 0
-#define H0_HEADER_SUM_OFFSET 1
-#define H0_COMP_SIZE_OFFSET 7
-#define H0_ORIG_SIZE_OFFSET 11
-#define H0_DOS_TIME_OFFSET 15
-#define H0_NAME_LEN_OFFSET 21
-#define H0_FILE_NAME_OFFSET 22
-#define H0_FIXED_SIZE 24
-static int
-lha_read_file_header_0(struct archive_read *a, struct lha *lha)
-{
- const unsigned char *p;
- int extdsize, namelen;
- unsigned char headersum, sum_calculated;
-
- if ((p = __archive_read_ahead(a, H0_FIXED_SIZE, NULL)) == NULL)
- return (truncated_error(a));
- lha->header_size = p[H0_HEADER_SIZE_OFFSET] + 2;
- headersum = p[H0_HEADER_SUM_OFFSET];
- lha->compsize = archive_le32dec(p + H0_COMP_SIZE_OFFSET);
- lha->origsize = archive_le32dec(p + H0_ORIG_SIZE_OFFSET);
- lha->mtime = lha_dos_time(p + H0_DOS_TIME_OFFSET);
- namelen = p[H0_NAME_LEN_OFFSET];
- extdsize = (int)lha->header_size - H0_FIXED_SIZE - namelen;
- if ((namelen > 221 || extdsize < 0) && extdsize != -2) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid LHa header");
- return (ARCHIVE_FATAL);
- }
- if ((p = __archive_read_ahead(a, lha->header_size, NULL)) == NULL)
- return (truncated_error(a));
-
- archive_strncpy(&lha->filename, p + H0_FILE_NAME_OFFSET, namelen);
- /* When extdsize == -2, A CRC16 value is not present in the header. */
- if (extdsize >= 0) {
- lha->crc = archive_le16dec(p + H0_FILE_NAME_OFFSET + namelen);
- lha->setflag |= CRC_IS_SET;
- }
- sum_calculated = lha_calcsum(0, p, 2, lha->header_size - 2);
-
- /* Read an extended header */
- if (extdsize > 0) {
- /* This extended data is set by 'LHa for UNIX' only.
- * Maybe fixed size.
- */
- p += H0_FILE_NAME_OFFSET + namelen + 2;
- if (p[0] == 'U' && extdsize == 12) {
- /* p[1] is a minor version. */
- lha->mtime = archive_le32dec(&p[2]);
- lha->mode = archive_le16dec(&p[6]);
- lha->uid = archive_le16dec(&p[8]);
- lha->gid = archive_le16dec(&p[10]);
- lha->setflag |= UNIX_MODE_IS_SET;
- }
- }
- __archive_read_consume(a, lha->header_size);
-
- if (sum_calculated != headersum) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "LHa header sum error");
- return (ARCHIVE_FATAL);
- }
-
- return (ARCHIVE_OK);
-}
-
-/*
- * Header 1 format
- *
- * +0 +1 +2 +7 +11
- * +---------------+----------+----------------+-------------+
- * |header size(*1)|header sum|compression type|skip size(*2)|
- * +---------------+----------+----------------+-------------+
- * <---------------(*1)----------*
- *
- * +11 +15 +17 +19 +20 +21
- * +-----------------+---------+---------+--------------+----------------+
- * |uncompressed size|time(DOS)|date(DOS)|attribute(DOS)|header level(=1)|
- * +-----------------+---------+---------+--------------+----------------+
- * *-------------------------------(*1)----------------------------------*
- *
- * +21 +22 +22+(*3) +22+(*3)+2 +22+(*3)+3 +22+(*3)+3+(*4)
- * +---------------+---------+----------+-----------+-----------+
- * |name length(*3)|file name|file CRC16| creator |padding(*4)|
- * +---------------+---------+----------+-----------+-----------+
- * <--(*3)->
- * *----------------------------(*1)----------------------------*
- *
- * +22+(*3)+3+(*4) +22+(*3)+3+(*4)+2 +22+(*3)+3+(*4)+2+(*5)
- * +----------------+---------------------+------------------------+
- * |next header size| extended header(*5) | compressed data |
- * +----------------+---------------------+------------------------+
- * *------(*1)-----> <--------------------(*2)-------------------->
- */
-#define H1_HEADER_SIZE_OFFSET 0
-#define H1_HEADER_SUM_OFFSET 1
-#define H1_COMP_SIZE_OFFSET 7
-#define H1_ORIG_SIZE_OFFSET 11
-#define H1_DOS_TIME_OFFSET 15
-#define H1_NAME_LEN_OFFSET 21
-#define H1_FILE_NAME_OFFSET 22
-#define H1_FIXED_SIZE 27
-static int
-lha_read_file_header_1(struct archive_read *a, struct lha *lha)
-{
- const unsigned char *p;
- size_t extdsize;
- int i, err, err2;
- int namelen, padding;
- unsigned char headersum, sum_calculated;
-
- err = ARCHIVE_OK;
-
- if ((p = __archive_read_ahead(a, H1_FIXED_SIZE, NULL)) == NULL)
- return (truncated_error(a));
-
- lha->header_size = p[H1_HEADER_SIZE_OFFSET] + 2;
- headersum = p[H1_HEADER_SUM_OFFSET];
- /* Note: An extended header size is included in a compsize. */
- lha->compsize = archive_le32dec(p + H1_COMP_SIZE_OFFSET);
- lha->origsize = archive_le32dec(p + H1_ORIG_SIZE_OFFSET);
- lha->mtime = lha_dos_time(p + H1_DOS_TIME_OFFSET);
- namelen = p[H1_NAME_LEN_OFFSET];
- /* Calculate a padding size. The result will be normally 0 only(?) */
- padding = ((int)lha->header_size) - H1_FIXED_SIZE - namelen;
-
- if (namelen > 230 || padding < 0)
- goto invalid;
-
- if ((p = __archive_read_ahead(a, lha->header_size, NULL)) == NULL)
- return (truncated_error(a));
-
- for (i = 0; i < namelen; i++) {
- if (p[i + H1_FILE_NAME_OFFSET] == 0xff)
- goto invalid;/* Invalid filename. */
- }
- archive_strncpy(&lha->filename, p + H1_FILE_NAME_OFFSET, namelen);
- lha->crc = archive_le16dec(p + H1_FILE_NAME_OFFSET + namelen);
- lha->setflag |= CRC_IS_SET;
-
- sum_calculated = lha_calcsum(0, p, 2, lha->header_size - 2);
- /* Consume used bytes but not include `next header size' data
- * since it will be consumed in lha_read_file_extended_header(). */
- __archive_read_consume(a, lha->header_size - 2);
-
- /* Read extended headers */
- err2 = lha_read_file_extended_header(a, lha, NULL, 2,
- (size_t)(lha->compsize + 2), &extdsize);
- if (err2 < ARCHIVE_WARN)
- return (err2);
- if (err2 < err)
- err = err2;
- /* Get a real compressed file size. */
- lha->compsize -= extdsize - 2;
-
- if (lha->compsize < 0)
- goto invalid; /* Invalid compressed file size */
-
- if (sum_calculated != headersum) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "LHa header sum error");
- return (ARCHIVE_FATAL);
- }
- return (err);
-invalid:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid LHa header");
- return (ARCHIVE_FATAL);
-}
-
-/*
- * Header 2 format
- *
- * +0 +2 +7 +11 +15
- * +---------------+----------------+-------------------+-----------------+
- * |header size(*1)|compression type|compressed size(*2)|uncompressed size|
- * +---------------+----------------+-------------------+-----------------+
- * <--------------------------------(*1)---------------------------------*
- *
- * +15 +19 +20 +21 +23 +24
- * +-----------------+------------+----------------+----------+-----------+
- * |data/time(time_t)| 0x20 fixed |header level(=2)|file CRC16| creator |
- * +-----------------+------------+----------------+----------+-----------+
- * *---------------------------------(*1)---------------------------------*
- *
- * +24 +26 +26+(*3) +26+(*3)+(*4)
- * +----------------+-------------------+-------------+-------------------+
- * |next header size|extended header(*3)| padding(*4) | compressed data |
- * +----------------+-------------------+-------------+-------------------+
- * *--------------------------(*1)-------------------> <------(*2)------->
- *
- */
-#define H2_HEADER_SIZE_OFFSET 0
-#define H2_COMP_SIZE_OFFSET 7
-#define H2_ORIG_SIZE_OFFSET 11
-#define H2_TIME_OFFSET 15
-#define H2_CRC_OFFSET 21
-#define H2_FIXED_SIZE 24
-static int
-lha_read_file_header_2(struct archive_read *a, struct lha *lha)
-{
- const unsigned char *p;
- size_t extdsize;
- int err, padding;
- uint16_t header_crc;
-
- if ((p = __archive_read_ahead(a, H2_FIXED_SIZE, NULL)) == NULL)
- return (truncated_error(a));
-
- lha->header_size =archive_le16dec(p + H2_HEADER_SIZE_OFFSET);
- lha->compsize = archive_le32dec(p + H2_COMP_SIZE_OFFSET);
- lha->origsize = archive_le32dec(p + H2_ORIG_SIZE_OFFSET);
- lha->mtime = archive_le32dec(p + H2_TIME_OFFSET);
- lha->crc = archive_le16dec(p + H2_CRC_OFFSET);
- lha->setflag |= CRC_IS_SET;
-
- if (lha->header_size < H2_FIXED_SIZE) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid LHa header size");
- return (ARCHIVE_FATAL);
- }
-
- header_crc = lha_crc16(0, p, H2_FIXED_SIZE);
- __archive_read_consume(a, H2_FIXED_SIZE);
-
- /* Read extended headers */
- err = lha_read_file_extended_header(a, lha, &header_crc, 2,
- lha->header_size - H2_FIXED_SIZE, &extdsize);
- if (err < ARCHIVE_WARN)
- return (err);
-
- /* Calculate a padding size. The result will be normally 0 or 1. */
- padding = (int)lha->header_size - (int)(H2_FIXED_SIZE + extdsize);
- if (padding > 0) {
- if ((p = __archive_read_ahead(a, padding, NULL)) == NULL)
- return (truncated_error(a));
- header_crc = lha_crc16(header_crc, p, padding);
- __archive_read_consume(a, padding);
- }
-
- if (header_crc != lha->header_crc) {
-#ifndef DONT_FAIL_ON_CRC_ERROR
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "LHa header CRC error");
- return (ARCHIVE_FATAL);
-#endif
- }
- return (err);
-}
-
-/*
- * Header 3 format
- *
- * +0 +2 +7 +11 +15
- * +------------+----------------+-------------------+-----------------+
- * | 0x04 fixed |compression type|compressed size(*2)|uncompressed size|
- * +------------+----------------+-------------------+-----------------+
- * <-------------------------------(*1)-------------------------------*
- *
- * +15 +19 +20 +21 +23 +24
- * +-----------------+------------+----------------+----------+-----------+
- * |date/time(time_t)| 0x20 fixed |header level(=3)|file CRC16| creator |
- * +-----------------+------------+----------------+----------+-----------+
- * *--------------------------------(*1)----------------------------------*
- *
- * +24 +28 +32 +32+(*3)
- * +---------------+----------------+-------------------+-----------------+
- * |header size(*1)|next header size|extended header(*3)| compressed data |
- * +---------------+----------------+-------------------+-----------------+
- * *------------------------(*1)-----------------------> <------(*2)----->
- *
- */
-#define H3_FIELD_LEN_OFFSET 0
-#define H3_COMP_SIZE_OFFSET 7
-#define H3_ORIG_SIZE_OFFSET 11
-#define H3_TIME_OFFSET 15
-#define H3_CRC_OFFSET 21
-#define H3_HEADER_SIZE_OFFSET 24
-#define H3_FIXED_SIZE 28
-static int
-lha_read_file_header_3(struct archive_read *a, struct lha *lha)
-{
- const unsigned char *p;
- size_t extdsize;
- int err;
- uint16_t header_crc;
-
- if ((p = __archive_read_ahead(a, H3_FIXED_SIZE, NULL)) == NULL)
- return (truncated_error(a));
-
- if (archive_le16dec(p + H3_FIELD_LEN_OFFSET) != 4)
- goto invalid;
- lha->header_size =archive_le32dec(p + H3_HEADER_SIZE_OFFSET);
- lha->compsize = archive_le32dec(p + H3_COMP_SIZE_OFFSET);
- lha->origsize = archive_le32dec(p + H3_ORIG_SIZE_OFFSET);
- lha->mtime = archive_le32dec(p + H3_TIME_OFFSET);
- lha->crc = archive_le16dec(p + H3_CRC_OFFSET);
- lha->setflag |= CRC_IS_SET;
-
- if (lha->header_size < H3_FIXED_SIZE + 4)
- goto invalid;
- header_crc = lha_crc16(0, p, H3_FIXED_SIZE);
- __archive_read_consume(a, H3_FIXED_SIZE);
-
- /* Read extended headers */
- err = lha_read_file_extended_header(a, lha, &header_crc, 4,
- lha->header_size - H3_FIXED_SIZE, &extdsize);
- if (err < ARCHIVE_WARN)
- return (err);
-
- if (header_crc != lha->header_crc) {
-#ifndef DONT_FAIL_ON_CRC_ERROR
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "LHa header CRC error");
- return (ARCHIVE_FATAL);
-#endif
- }
- return (err);
-invalid:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid LHa header");
- return (ARCHIVE_FATAL);
-}
-
-/*
- * Extended header format
- *
- * +0 +2 +3 -- used in header 1 and 2
- * +0 +4 +5 -- used in header 3
- * +--------------+---------+-------------------+--------------+--
- * |ex-header size|header id| data |ex-header size| .......
- * +--------------+---------+-------------------+--------------+--
- * <-------------( ex-header size)------------> <-- next extended header --*
- *
- * If the ex-header size is zero, it is the make of the end of extended
- * headers.
- *
- */
-static int
-lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
- uint16_t *crc, int sizefield_length, size_t limitsize, size_t *total_size)
-{
- const void *h;
- const unsigned char *extdheader;
- size_t extdsize;
- size_t datasize;
- unsigned int i;
- unsigned char extdtype;
-
-#define EXT_HEADER_CRC 0x00 /* Header CRC and information*/
-#define EXT_FILENAME 0x01 /* Filename */
-#define EXT_DIRECTORY 0x02 /* Directory name */
-#define EXT_DOS_ATTR 0x40 /* MS-DOS attribute */
-#define EXT_TIMESTAMP 0x41 /* Windows time stamp */
-#define EXT_FILESIZE 0x42 /* Large file size */
-#define EXT_TIMEZONE 0x43 /* Time zone */
-#define EXT_UTF16_FILENAME 0x44 /* UTF-16 filename */
-#define EXT_UTF16_DIRECTORY 0x45 /* UTF-16 directory name */
-#define EXT_CODEPAGE 0x46 /* Codepage */
-#define EXT_UNIX_MODE 0x50 /* File permission */
-#define EXT_UNIX_GID_UID 0x51 /* gid,uid */
-#define EXT_UNIX_GNAME 0x52 /* Group name */
-#define EXT_UNIX_UNAME 0x53 /* User name */
-#define EXT_UNIX_MTIME 0x54 /* Modified time */
-#define EXT_OS2_NEW_ATTR 0x7f /* new attribute(OS/2 only) */
-#define EXT_NEW_ATTR 0xff /* new attribute */
-
- *total_size = sizefield_length;
-
- for (;;) {
- /* Read an extended header size. */
- if ((h =
- __archive_read_ahead(a, sizefield_length, NULL)) == NULL)
- return (truncated_error(a));
- /* Check if the size is the zero indicates the end of the
- * extended header. */
- if (sizefield_length == sizeof(uint16_t))
- extdsize = archive_le16dec(h);
- else
- extdsize = archive_le32dec(h);
- if (extdsize == 0) {
- /* End of extended header */
- if (crc != NULL)
- *crc = lha_crc16(*crc, h, sizefield_length);
- __archive_read_consume(a, sizefield_length);
- return (ARCHIVE_OK);
- }
-
- /* Sanity check to the extended header size. */
- if (((uint64_t)*total_size + extdsize) >
- (uint64_t)limitsize ||
- extdsize <= (size_t)sizefield_length)
- goto invalid;
-
- /* Read the extended header. */
- if ((h = __archive_read_ahead(a, extdsize, NULL)) == NULL)
- return (truncated_error(a));
- *total_size += extdsize;
-
- extdheader = (const unsigned char *)h;
- /* Get the extended header type. */
- extdtype = extdheader[sizefield_length];
- /* Calculate an extended data size. */
- datasize = extdsize - (1 + sizefield_length);
- /* Skip an extended header size field and type field. */
- extdheader += sizefield_length + 1;
-
- if (crc != NULL && extdtype != EXT_HEADER_CRC)
- *crc = lha_crc16(*crc, h, extdsize);
- switch (extdtype) {
- case EXT_HEADER_CRC:
- /* We only use a header CRC. Following data will not
- * be used. */
- if (datasize >= 2) {
- lha->header_crc = archive_le16dec(extdheader);
- if (crc != NULL) {
- static const char zeros[2] = {0, 0};
- *crc = lha_crc16(*crc, h,
- extdsize - datasize);
- /* CRC value itself as zero */
- *crc = lha_crc16(*crc, zeros, 2);
- *crc = lha_crc16(*crc,
- extdheader+2, datasize - 2);
- }
- }
- break;
- case EXT_FILENAME:
- if (datasize == 0) {
- /* maybe directory header */
- archive_string_empty(&lha->filename);
- break;
- }
- if (extdheader[0] == '\0')
- goto invalid;
- archive_strncpy(&lha->filename,
- (const char *)extdheader, datasize);
- break;
- case EXT_UTF16_FILENAME:
- if (datasize == 0) {
- /* maybe directory header */
- archive_string_empty(&lha->filename);
- break;
- } else if (datasize & 1) {
- /* UTF-16 characters take always 2 or 4 bytes */
- goto invalid;
- }
- if (extdheader[0] == '\0')
- goto invalid;
- archive_string_empty(&lha->filename);
- archive_array_append(&lha->filename,
- (const char *)extdheader, datasize);
- /* Setup a string conversion for a filename. */
- lha->sconv_fname =
- archive_string_conversion_from_charset(&a->archive,
- "UTF-16LE", 1);
- if (lha->sconv_fname == NULL)
- return (ARCHIVE_FATAL);
- break;
- case EXT_DIRECTORY:
- if (datasize == 0 || extdheader[0] == '\0')
- /* no directory name data. exit this case. */
- goto invalid;
-
- archive_strncpy(&lha->dirname,
- (const char *)extdheader, datasize);
- /*
- * Convert directory delimiter from 0xFF
- * to '/' for local system.
- */
- for (i = 0; i < lha->dirname.length; i++) {
- if ((unsigned char)lha->dirname.s[i] == 0xFF)
- lha->dirname.s[i] = '/';
- }
- /* Is last character directory separator? */
- if (lha->dirname.s[lha->dirname.length-1] != '/')
- /* invalid directory data */
- goto invalid;
- break;
- case EXT_UTF16_DIRECTORY:
- /* UTF-16 characters take always 2 or 4 bytes */
- if (datasize == 0 || (datasize & 1) ||
- extdheader[0] == '\0') {
- /* no directory name data. exit this case. */
- goto invalid;
- }
-
- archive_string_empty(&lha->dirname);
- archive_array_append(&lha->dirname,
- (const char *)extdheader, datasize);
- lha->sconv_dir =
- archive_string_conversion_from_charset(&a->archive,
- "UTF-16LE", 1);
- if (lha->sconv_dir == NULL)
- return (ARCHIVE_FATAL);
- else {
- /*
- * Convert directory delimiter from 0xFFFF
- * to '/' for local system.
- */
- uint16_t dirSep;
- uint16_t d = 1;
- if (archive_be16dec(&d) == 1)
- dirSep = 0x2F00;
- else
- dirSep = 0x002F;
-
- /* UTF-16LE character */
- uint16_t *utf16name =
- (uint16_t *)lha->dirname.s;
- for (i = 0; i < lha->dirname.length / 2; i++) {
- if (utf16name[i] == 0xFFFF) {
- utf16name[i] = dirSep;
- }
- }
- /* Is last character directory separator? */
- if (utf16name[lha->dirname.length / 2 - 1] !=
- dirSep) {
- /* invalid directory data */
- goto invalid;
- }
- }
- break;
- case EXT_DOS_ATTR:
- if (datasize == 2)
- lha->dos_attr = (unsigned char)
- (archive_le16dec(extdheader) & 0xff);
- break;
- case EXT_TIMESTAMP:
- if (datasize == (sizeof(uint64_t) * 3)) {
- lha->birthtime = lha_win_time(
- archive_le64dec(extdheader),
- &lha->birthtime_tv_nsec);
- extdheader += sizeof(uint64_t);
- lha->mtime = lha_win_time(
- archive_le64dec(extdheader),
- &lha->mtime_tv_nsec);
- extdheader += sizeof(uint64_t);
- lha->atime = lha_win_time(
- archive_le64dec(extdheader),
- &lha->atime_tv_nsec);
- lha->setflag |= BIRTHTIME_IS_SET |
- ATIME_IS_SET;
- }
- break;
- case EXT_FILESIZE:
- if (datasize == sizeof(uint64_t) * 2) {
- lha->compsize = archive_le64dec(extdheader);
- extdheader += sizeof(uint64_t);
- lha->origsize = archive_le64dec(extdheader);
- }
- break;
- case EXT_CODEPAGE:
- /* Get an archived filename charset from codepage.
- * This overwrites the charset specified by
- * hdrcharset option. */
- if (datasize == sizeof(uint32_t)) {
- struct archive_string cp;
- const char *charset;
-
- archive_string_init(&cp);
- switch (archive_le32dec(extdheader)) {
- case 65001: /* UTF-8 */
- charset = "UTF-8";
- break;
- default:
- archive_string_sprintf(&cp, "CP%d",
- (int)archive_le32dec(extdheader));
- charset = cp.s;
- break;
- }
- lha->sconv_dir =
- archive_string_conversion_from_charset(
- &(a->archive), charset, 1);
- lha->sconv_fname =
- archive_string_conversion_from_charset(
- &(a->archive), charset, 1);
- archive_string_free(&cp);
- if (lha->sconv_dir == NULL)
- return (ARCHIVE_FATAL);
- if (lha->sconv_fname == NULL)
- return (ARCHIVE_FATAL);
- }
- break;
- case EXT_UNIX_MODE:
- if (datasize == sizeof(uint16_t)) {
- lha->mode = archive_le16dec(extdheader);
- lha->setflag |= UNIX_MODE_IS_SET;
- }
- break;
- case EXT_UNIX_GID_UID:
- if (datasize == (sizeof(uint16_t) * 2)) {
- lha->gid = archive_le16dec(extdheader);
- lha->uid = archive_le16dec(extdheader+2);
- }
- break;
- case EXT_UNIX_GNAME:
- if (datasize > 0)
- archive_strncpy(&lha->gname,
- (const char *)extdheader, datasize);
- break;
- case EXT_UNIX_UNAME:
- if (datasize > 0)
- archive_strncpy(&lha->uname,
- (const char *)extdheader, datasize);
- break;
- case EXT_UNIX_MTIME:
- if (datasize == sizeof(uint32_t))
- lha->mtime = archive_le32dec(extdheader);
- break;
- case EXT_OS2_NEW_ATTR:
- /* This extended header is OS/2 depend. */
- if (datasize == 16) {
- lha->dos_attr = (unsigned char)
- (archive_le16dec(extdheader) & 0xff);
- lha->mode = archive_le16dec(extdheader+2);
- lha->gid = archive_le16dec(extdheader+4);
- lha->uid = archive_le16dec(extdheader+6);
- lha->birthtime = archive_le32dec(extdheader+8);
- lha->atime = archive_le32dec(extdheader+12);
- lha->setflag |= UNIX_MODE_IS_SET
- | BIRTHTIME_IS_SET | ATIME_IS_SET;
- }
- break;
- case EXT_NEW_ATTR:
- if (datasize == 20) {
- lha->mode = (mode_t)archive_le32dec(extdheader);
- lha->gid = archive_le32dec(extdheader+4);
- lha->uid = archive_le32dec(extdheader+8);
- lha->birthtime = archive_le32dec(extdheader+12);
- lha->atime = archive_le32dec(extdheader+16);
- lha->setflag |= UNIX_MODE_IS_SET
- | BIRTHTIME_IS_SET | ATIME_IS_SET;
- }
- break;
- case EXT_TIMEZONE: /* Not supported */
- break;
- default:
- break;
- }
-
- __archive_read_consume(a, extdsize);
- }
-invalid:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid extended LHa header");
- return (ARCHIVE_FATAL);
-}
-
-static int
-lha_end_of_entry(struct archive_read *a)
-{
- struct lha *lha = (struct lha *)(a->format->data);
- int r = ARCHIVE_EOF;
-
- if (!lha->end_of_entry_cleanup) {
- if ((lha->setflag & CRC_IS_SET) &&
- lha->crc != lha->entry_crc_calculated) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "LHa data CRC error");
- r = ARCHIVE_WARN;
- }
-
- /* End-of-entry cleanup done. */
- lha->end_of_entry_cleanup = 1;
- }
- return (r);
-}
-
-static int
-archive_read_format_lha_read_data(struct archive_read *a,
- const void **buff, size_t *size, int64_t *offset)
-{
- struct lha *lha = (struct lha *)(a->format->data);
- int r;
-
- if (lha->entry_unconsumed) {
- /* Consume as much as the decompressor actually used. */
- __archive_read_consume(a, lha->entry_unconsumed);
- lha->entry_unconsumed = 0;
- }
- if (lha->end_of_entry) {
- *offset = lha->entry_offset;
- *size = 0;
- *buff = NULL;
- return (lha_end_of_entry(a));
- }
-
- if (lha->entry_is_compressed)
- r = lha_read_data_lzh(a, buff, size, offset);
- else
- /* No compression. */
- r = lha_read_data_none(a, buff, size, offset);
- return (r);
-}
-
-/*
- * Read a file content in no compression.
- *
- * Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets
- * lha->end_of_entry if it consumes all of the data.
- */
-static int
-lha_read_data_none(struct archive_read *a, const void **buff,
- size_t *size, int64_t *offset)
-{
- struct lha *lha = (struct lha *)(a->format->data);
- ssize_t bytes_avail;
-
- if (lha->entry_bytes_remaining == 0) {
- *buff = NULL;
- *size = 0;
- *offset = lha->entry_offset;
- lha->end_of_entry = 1;
- return (ARCHIVE_OK);
- }
- /*
- * Note: '1' here is a performance optimization.
- * Recall that the decompression layer returns a count of
- * available bytes; asking for more than that forces the
- * decompressor to combine reads by copying data.
- */
- *buff = __archive_read_ahead(a, 1, &bytes_avail);
- if (bytes_avail <= 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated LHa file data");
- return (ARCHIVE_FATAL);
- }
- if (bytes_avail > lha->entry_bytes_remaining)
- bytes_avail = (ssize_t)lha->entry_bytes_remaining;
- lha->entry_crc_calculated =
- lha_crc16(lha->entry_crc_calculated, *buff, bytes_avail);
- *size = bytes_avail;
- *offset = lha->entry_offset;
- lha->entry_offset += bytes_avail;
- lha->entry_bytes_remaining -= bytes_avail;
- if (lha->entry_bytes_remaining == 0)
- lha->end_of_entry = 1;
- lha->entry_unconsumed = bytes_avail;
- return (ARCHIVE_OK);
-}
-
-/*
- * Read a file content in LZHUFF encoding.
- *
- * Returns ARCHIVE_OK if successful, returns ARCHIVE_WARN if compression is
- * unsupported, ARCHIVE_FATAL otherwise, sets lha->end_of_entry if it consumes
- * all of the data.
- */
-static int
-lha_read_data_lzh(struct archive_read *a, const void **buff,
- size_t *size, int64_t *offset)
-{
- struct lha *lha = (struct lha *)(a->format->data);
- ssize_t bytes_avail;
- int r;
-
- /* If we haven't yet read any data, initialize the decompressor. */
- if (!lha->decompress_init) {
- r = lzh_decode_init(&(lha->strm), lha->method);
- switch (r) {
- case ARCHIVE_OK:
- break;
- case ARCHIVE_FAILED:
- /* Unsupported compression. */
- *buff = NULL;
- *size = 0;
- *offset = 0;
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Unsupported lzh compression method -%c%c%c-",
- lha->method[0], lha->method[1], lha->method[2]);
- /* We know compressed size; just skip it. */
- archive_read_format_lha_read_data_skip(a);
- return (ARCHIVE_WARN);
- default:
- archive_set_error(&a->archive, ENOMEM,
- "Couldn't allocate memory "
- "for lzh decompression");
- return (ARCHIVE_FATAL);
- }
- /* We've initialized decompression for this stream. */
- lha->decompress_init = 1;
- lha->strm.avail_out = 0;
- lha->strm.total_out = 0;
- }
-
- /*
- * Note: '1' here is a performance optimization.
- * Recall that the decompression layer returns a count of
- * available bytes; asking for more than that forces the
- * decompressor to combine reads by copying data.
- */
- lha->strm.next_in = __archive_read_ahead(a, 1, &bytes_avail);
- if (bytes_avail <= 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated LHa file body");
- return (ARCHIVE_FATAL);
- }
- if (bytes_avail > lha->entry_bytes_remaining)
- bytes_avail = (ssize_t)lha->entry_bytes_remaining;
-
- lha->strm.avail_in = (int)bytes_avail;
- lha->strm.total_in = 0;
- lha->strm.avail_out = 0;
-
- r = lzh_decode(&(lha->strm), bytes_avail == lha->entry_bytes_remaining);
- switch (r) {
- case ARCHIVE_OK:
- break;
- case ARCHIVE_EOF:
- lha->end_of_entry = 1;
- break;
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Bad lzh data");
- return (ARCHIVE_FAILED);
- }
- lha->entry_unconsumed = lha->strm.total_in;
- lha->entry_bytes_remaining -= lha->strm.total_in;
-
- if (lha->strm.avail_out) {
- *offset = lha->entry_offset;
- *size = lha->strm.avail_out;
- *buff = lha->strm.ref_ptr;
- lha->entry_crc_calculated =
- lha_crc16(lha->entry_crc_calculated, *buff, *size);
- lha->entry_offset += *size;
- } else {
- *offset = lha->entry_offset;
- *size = 0;
- *buff = NULL;
- if (lha->end_of_entry)
- return (lha_end_of_entry(a));
- }
- return (ARCHIVE_OK);
-}
-
-/*
- * Skip a file content.
- */
-static int
-archive_read_format_lha_read_data_skip(struct archive_read *a)
-{
- struct lha *lha;
- int64_t bytes_skipped;
-
- lha = (struct lha *)(a->format->data);
-
- if (lha->entry_unconsumed) {
- /* Consume as much as the decompressor actually used. */
- __archive_read_consume(a, lha->entry_unconsumed);
- lha->entry_unconsumed = 0;
- }
-
- /* if we've already read to end of data, we're done. */
- if (lha->end_of_entry_cleanup)
- return (ARCHIVE_OK);
-
- /*
- * If the length is at the beginning, we can skip the
- * compressed data much more quickly.
- */
- bytes_skipped = __archive_read_consume(a, lha->entry_bytes_remaining);
- if (bytes_skipped < 0)
- return (ARCHIVE_FATAL);
-
- /* This entry is finished and done. */
- lha->end_of_entry_cleanup = lha->end_of_entry = 1;
- return (ARCHIVE_OK);
-}
-
-static int
-archive_read_format_lha_cleanup(struct archive_read *a)
-{
- struct lha *lha = (struct lha *)(a->format->data);
-
- lzh_decode_free(&(lha->strm));
- archive_string_free(&(lha->dirname));
- archive_string_free(&(lha->filename));
- archive_string_free(&(lha->uname));
- archive_string_free(&(lha->gname));
- archive_wstring_free(&(lha->ws));
- free(lha);
- (a->format->data) = NULL;
- return (ARCHIVE_OK);
-}
-
-/*
- * 'LHa for UNIX' utility has archived a symbolic-link name after
- * a pathname with '|' character.
- * This function extracts the symbolic-link name from the pathname.
- *
- * example.
- * 1. a symbolic-name is 'aaa/bb/cc'
- * 2. a filename is 'xxx/bbb'
- * then a archived pathname is 'xxx/bbb|aaa/bb/cc'
- */
-static int
-lha_parse_linkname(struct archive_wstring *linkname,
- struct archive_wstring *pathname)
-{
- wchar_t * linkptr;
- size_t symlen;
-
- linkptr = wcschr(pathname->s, L'|');
- if (linkptr != NULL) {
- symlen = wcslen(linkptr + 1);
- archive_wstrncpy(linkname, linkptr+1, symlen);
-
- *linkptr = 0;
- pathname->length = wcslen(pathname->s);
-
- return (1);
- }
- return (0);
-}
-
-/* Convert an MSDOS-style date/time into Unix-style time. */
-static time_t
-lha_dos_time(const unsigned char *p)
-{
- int msTime, msDate;
- struct tm ts;
-
- msTime = archive_le16dec(p);
- msDate = archive_le16dec(p+2);
-
- memset(&ts, 0, sizeof(ts));
- ts.tm_year = ((msDate >> 9) & 0x7f) + 80; /* Years since 1900. */
- ts.tm_mon = ((msDate >> 5) & 0x0f) - 1; /* Month number. */
- ts.tm_mday = msDate & 0x1f; /* Day of month. */
- ts.tm_hour = (msTime >> 11) & 0x1f;
- ts.tm_min = (msTime >> 5) & 0x3f;
- ts.tm_sec = (msTime << 1) & 0x3e;
- ts.tm_isdst = -1;
- return (mktime(&ts));
-}
-
-/* Convert an MS-Windows-style date/time into Unix-style time. */
-static time_t
-lha_win_time(uint64_t wintime, long *ns)
-{
-#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
-
- if (wintime >= EPOC_TIME) {
- wintime -= EPOC_TIME; /* 1970-01-01 00:00:00 (UTC) */
- if (ns != NULL)
- *ns = (long)(wintime % 10000000) * 100;
- return (wintime / 10000000);
- } else {
- if (ns != NULL)
- *ns = 0;
- return (0);
- }
-}
-
-static unsigned char
-lha_calcsum(unsigned char sum, const void *pp, int offset, size_t size)
-{
- unsigned char const *p = (unsigned char const *)pp;
-
- p += offset;
- for (;size > 0; --size)
- sum += *p++;
- return (sum);
-}
-
-static uint16_t crc16tbl[2][256];
-static void
-lha_crc16_init(void)
-{
- unsigned int i;
- static int crc16init = 0;
-
- if (crc16init)
- return;
- crc16init = 1;
-
- for (i = 0; i < 256; i++) {
- unsigned int j;
- uint16_t crc = (uint16_t)i;
- for (j = 8; j; j--)
- crc = (crc >> 1) ^ ((crc & 1) * 0xA001);
- crc16tbl[0][i] = crc;
- }
-
- for (i = 0; i < 256; i++) {
- crc16tbl[1][i] = (crc16tbl[0][i] >> 8)
- ^ crc16tbl[0][crc16tbl[0][i] & 0xff];
- }
-}
-
-static uint16_t
-lha_crc16(uint16_t crc, const void *pp, size_t len)
-{
- const unsigned char *p = (const unsigned char *)pp;
- const uint16_t *buff;
- const union {
- uint32_t i;
- char c[4];
- } u = { 0x01020304 };
-
- if (len == 0)
- return crc;
-
- /* Process unaligned address. */
- if (((uintptr_t)p) & (uintptr_t)0x1) {
- crc = (crc >> 8) ^ crc16tbl[0][(crc ^ *p++) & 0xff];
- len--;
- }
- buff = (const uint16_t *)p;
- /*
- * Modern C compiler such as GCC does not unroll automatically yet
- * without unrolling pragma, and Clang is so. So we should
- * unroll this loop for its performance.
- */
- for (;len >= 8; len -= 8) {
- /* This if statement expects compiler optimization will
- * remove the statement which will not be executed. */
-#undef bswap16
-#ifndef __has_builtin
-#define __has_builtin(x) 0
-#endif
-#if defined(_MSC_VER) && _MSC_VER >= 1400 /* Visual Studio */
-# define bswap16(x) _byteswap_ushort(x)
-#elif defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || __GNUC__ > 4)
-/* GCC 4.8 and later has __builtin_bswap16() */
-# define bswap16(x) __builtin_bswap16(x)
-#elif defined(__clang__) && __has_builtin(__builtin_bswap16)
-/* Newer clang versions have __builtin_bswap16() */
-# define bswap16(x) __builtin_bswap16(x)
-#else
-# define bswap16(x) ((((x) >> 8) & 0xff) | ((x) << 8))
-#endif
-#define CRC16W do { \
- if(u.c[0] == 1) { /* Big endian */ \
- crc ^= bswap16(*buff); buff++; \
- } else \
- crc ^= *buff++; \
- crc = crc16tbl[1][crc & 0xff] ^ crc16tbl[0][crc >> 8];\
-} while (0)
- CRC16W;
- CRC16W;
- CRC16W;
- CRC16W;
-#undef CRC16W
-#undef bswap16
- }
-
- p = (const unsigned char *)buff;
- for (;len; len--) {
- crc = (crc >> 8) ^ crc16tbl[0][(crc ^ *p++) & 0xff];
- }
- return crc;
-}
-
-/*
- * Initialize LZHUF decoder.
- *
- * Returns ARCHIVE_OK if initialization was successful.
- * Returns ARCHIVE_FAILED if method is unsupported.
- * Returns ARCHIVE_FATAL if initialization failed; memory allocation
- * error occurred.
- */
-static int
-lzh_decode_init(struct lzh_stream *strm, const char *method)
-{
- struct lzh_dec *ds;
- int w_bits, w_size;
-
- if (strm->ds == NULL) {
- strm->ds = calloc(1, sizeof(*strm->ds));
- if (strm->ds == NULL)
- return (ARCHIVE_FATAL);
- }
- ds = strm->ds;
- ds->error = ARCHIVE_FAILED;
- if (method == NULL || method[0] != 'l' || method[1] != 'h')
- return (ARCHIVE_FAILED);
- switch (method[2]) {
- case '5':
- w_bits = 13;/* 8KiB for window */
- break;
- case '6':
- w_bits = 15;/* 32KiB for window */
- break;
- case '7':
- w_bits = 16;/* 64KiB for window */
- break;
- default:
- return (ARCHIVE_FAILED);/* Not supported. */
- }
- ds->error = ARCHIVE_FATAL;
- /* Expand a window size up to 128 KiB for decompressing process
- * performance whatever its original window size is. */
- ds->w_size = 1U << 17;
- ds->w_mask = ds->w_size -1;
- if (ds->w_buff == NULL) {
- ds->w_buff = malloc(ds->w_size);
- if (ds->w_buff == NULL)
- return (ARCHIVE_FATAL);
- }
- w_size = 1U << w_bits;
- memset(ds->w_buff + ds->w_size - w_size, 0x20, w_size);
- ds->w_pos = 0;
- ds->state = 0;
- ds->pos_pt_len_size = w_bits + 1;
- ds->pos_pt_len_bits = (w_bits == 15 || w_bits == 16)? 5: 4;
- ds->literal_pt_len_size = PT_BITLEN_SIZE;
- ds->literal_pt_len_bits = 5;
- ds->br.cache_buffer = 0;
- ds->br.cache_avail = 0;
-
- if (lzh_huffman_init(&(ds->lt), LT_BITLEN_SIZE, 16)
- != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- ds->lt.len_bits = 9;
- if (lzh_huffman_init(&(ds->pt), PT_BITLEN_SIZE, 16)
- != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- ds->error = 0;
-
- return (ARCHIVE_OK);
-}
-
-/*
- * Release LZHUF decoder.
- */
-static void
-lzh_decode_free(struct lzh_stream *strm)
-{
-
- if (strm->ds == NULL)
- return;
- free(strm->ds->w_buff);
- lzh_huffman_free(&(strm->ds->lt));
- lzh_huffman_free(&(strm->ds->pt));
- free(strm->ds);
- strm->ds = NULL;
-}
-
-/*
- * Bit stream reader.
- */
-/* Check that the cache buffer has enough bits. */
-#define lzh_br_has(br, n) ((br)->cache_avail >= n)
-/* Get compressed data by bit. */
-#define lzh_br_bits(br, n) \
- (((uint16_t)((br)->cache_buffer >> \
- ((br)->cache_avail - (n)))) & cache_masks[n])
-#define lzh_br_bits_forced(br, n) \
- (((uint16_t)((br)->cache_buffer << \
- ((n) - (br)->cache_avail))) & cache_masks[n])
-/* Read ahead to make sure the cache buffer has enough compressed data we
- * will use.
- * True : completed, there is enough data in the cache buffer.
- * False : we met that strm->next_in is empty, we have to get following
- * bytes. */
-#define lzh_br_read_ahead_0(strm, br, n) \
- (lzh_br_has(br, (n)) || lzh_br_fillup(strm, br))
-/* True : the cache buffer has some bits as much as we need.
- * False : there are no enough bits in the cache buffer to be used,
- * we have to get following bytes if we could. */
-#define lzh_br_read_ahead(strm, br, n) \
- (lzh_br_read_ahead_0((strm), (br), (n)) || lzh_br_has((br), (n)))
-
-/* Notify how many bits we consumed. */
-#define lzh_br_consume(br, n) ((br)->cache_avail -= (n))
-#define lzh_br_unconsume(br, n) ((br)->cache_avail += (n))
-
-static const uint16_t cache_masks[] = {
- 0x0000, 0x0001, 0x0003, 0x0007,
- 0x000F, 0x001F, 0x003F, 0x007F,
- 0x00FF, 0x01FF, 0x03FF, 0x07FF,
- 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF,
- 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF
-};
-
-/*
- * Shift away used bits in the cache data and fill it up with following bits.
- * Call this when cache buffer does not have enough bits you need.
- *
- * Returns 1 if the cache buffer is full.
- * Returns 0 if the cache buffer is not full; input buffer is empty.
- */
-static int
-lzh_br_fillup(struct lzh_stream *strm, struct lzh_br *br)
-{
- int n = CACHE_BITS - br->cache_avail;
-
- for (;;) {
- const int x = n >> 3;
- if (strm->avail_in >= x) {
- switch (x) {
- case 8:
- br->cache_buffer =
- ((uint64_t)strm->next_in[0]) << 56 |
- ((uint64_t)strm->next_in[1]) << 48 |
- ((uint64_t)strm->next_in[2]) << 40 |
- ((uint64_t)strm->next_in[3]) << 32 |
- ((uint32_t)strm->next_in[4]) << 24 |
- ((uint32_t)strm->next_in[5]) << 16 |
- ((uint32_t)strm->next_in[6]) << 8 |
- (uint32_t)strm->next_in[7];
- strm->next_in += 8;
- strm->avail_in -= 8;
- br->cache_avail += 8 * 8;
- return (1);
- case 7:
- br->cache_buffer =
- (br->cache_buffer << 56) |
- ((uint64_t)strm->next_in[0]) << 48 |
- ((uint64_t)strm->next_in[1]) << 40 |
- ((uint64_t)strm->next_in[2]) << 32 |
- ((uint64_t)strm->next_in[3]) << 24 |
- ((uint64_t)strm->next_in[4]) << 16 |
- ((uint64_t)strm->next_in[5]) << 8 |
- (uint64_t)strm->next_in[6];
- strm->next_in += 7;
- strm->avail_in -= 7;
- br->cache_avail += 7 * 8;
- return (1);
- case 6:
- br->cache_buffer =
- (br->cache_buffer << 48) |
- ((uint64_t)strm->next_in[0]) << 40 |
- ((uint64_t)strm->next_in[1]) << 32 |
- ((uint64_t)strm->next_in[2]) << 24 |
- ((uint64_t)strm->next_in[3]) << 16 |
- ((uint64_t)strm->next_in[4]) << 8 |
- (uint64_t)strm->next_in[5];
- strm->next_in += 6;
- strm->avail_in -= 6;
- br->cache_avail += 6 * 8;
- return (1);
- case 0:
- /* We have enough compressed data in
- * the cache buffer.*/
- return (1);
- default:
- break;
- }
- }
- if (strm->avail_in == 0) {
- /* There is not enough compressed data to fill up the
- * cache buffer. */
- return (0);
- }
- br->cache_buffer =
- (br->cache_buffer << 8) | *strm->next_in++;
- strm->avail_in--;
- br->cache_avail += 8;
- n -= 8;
- }
-}
-
-/*
- * Decode LZHUF.
- *
- * 1. Returns ARCHIVE_OK if output buffer or input buffer are empty.
- * Please set available buffer and call this function again.
- * 2. Returns ARCHIVE_EOF if decompression has been completed.
- * 3. Returns ARCHIVE_FAILED if an error occurred; compressed data
- * is broken or you do not set 'last' flag properly.
- * 4. 'last' flag is very important, you must set 1 to the flag if there
- * is no input data. The lha compressed data format does not provide how
- * to know the compressed data is really finished.
- * Note: lha command utility check if the total size of output bytes is
- * reached the uncompressed size recorded in its header. it does not mind
- * that the decoding process is properly finished.
- * GNU ZIP can decompress another compressed file made by SCO LZH compress.
- * it handles EOF as null to fill read buffer with zero until the decoding
- * process meet 2 bytes of zeros at reading a size of a next chunk, so the
- * zeros are treated as the mark of the end of the data although the zeros
- * is dummy, not the file data.
- */
-static int lzh_read_blocks(struct lzh_stream *, int);
-static int lzh_decode_blocks(struct lzh_stream *, int);
-#define ST_RD_BLOCK 0
-#define ST_RD_PT_1 1
-#define ST_RD_PT_2 2
-#define ST_RD_PT_3 3
-#define ST_RD_PT_4 4
-#define ST_RD_LITERAL_1 5
-#define ST_RD_LITERAL_2 6
-#define ST_RD_LITERAL_3 7
-#define ST_RD_POS_DATA_1 8
-#define ST_GET_LITERAL 9
-#define ST_GET_POS_1 10
-#define ST_GET_POS_2 11
-#define ST_COPY_DATA 12
-
-static int
-lzh_decode(struct lzh_stream *strm, int last)
-{
- struct lzh_dec *ds = strm->ds;
- int avail_in;
- int r;
-
- if (ds->error)
- return (ds->error);
-
- avail_in = strm->avail_in;
- do {
- if (ds->state < ST_GET_LITERAL)
- r = lzh_read_blocks(strm, last);
- else
- r = lzh_decode_blocks(strm, last);
- } while (r == 100);
- strm->total_in += avail_in - strm->avail_in;
- return (r);
-}
-
-static void
-lzh_emit_window(struct lzh_stream *strm, size_t s)
-{
- strm->ref_ptr = strm->ds->w_buff;
- strm->avail_out = (int)s;
- strm->total_out += s;
-}
-
-static int
-lzh_read_blocks(struct lzh_stream *strm, int last)
-{
- struct lzh_dec *ds = strm->ds;
- struct lzh_br *br = &(ds->br);
- int c = 0, i;
- unsigned rbits;
-
- for (;;) {
- switch (ds->state) {
- case ST_RD_BLOCK:
- /*
- * Read a block number indicates how many blocks
- * we will handle. The block is composed of a
- * literal and a match, sometimes a literal only
- * in particular, there are no reference data at
- * the beginning of the decompression.
- */
- if (!lzh_br_read_ahead_0(strm, br, 16)) {
- if (!last)
- /* We need following data. */
- return (ARCHIVE_OK);
- if (lzh_br_has(br, 8)) {
- /*
- * It seems there are extra bits.
- * 1. Compressed data is broken.
- * 2. `last' flag does not properly
- * set.
- */
- goto failed;
- }
- if (ds->w_pos > 0) {
- lzh_emit_window(strm, ds->w_pos);
- ds->w_pos = 0;
- return (ARCHIVE_OK);
- }
- /* End of compressed data; we have completely
- * handled all compressed data. */
- return (ARCHIVE_EOF);
- }
- ds->blocks_avail = lzh_br_bits(br, 16);
- if (ds->blocks_avail == 0)
- goto failed;
- lzh_br_consume(br, 16);
- /*
- * Read a literal table compressed in huffman
- * coding.
- */
- ds->pt.len_size = ds->literal_pt_len_size;
- ds->pt.len_bits = ds->literal_pt_len_bits;
- ds->reading_position = 0;
- /* FALL THROUGH */
- case ST_RD_PT_1:
- /* Note: ST_RD_PT_1, ST_RD_PT_2 and ST_RD_PT_4 are
- * used in reading both a literal table and a
- * position table. */
- if (!lzh_br_read_ahead(strm, br, ds->pt.len_bits)) {
- if (last)
- goto failed;/* Truncated data. */
- ds->state = ST_RD_PT_1;
- return (ARCHIVE_OK);
- }
- ds->pt.len_avail = lzh_br_bits(br, ds->pt.len_bits);
- lzh_br_consume(br, ds->pt.len_bits);
- /* FALL THROUGH */
- case ST_RD_PT_2:
- if (ds->pt.len_avail == 0) {
- /* There is no bitlen. */
- if (!lzh_br_read_ahead(strm, br,
- ds->pt.len_bits)) {
- if (last)
- goto failed;/* Truncated data.*/
- ds->state = ST_RD_PT_2;
- return (ARCHIVE_OK);
- }
- if (!lzh_make_fake_table(&(ds->pt),
- lzh_br_bits(br, ds->pt.len_bits)))
- goto failed;/* Invalid data. */
- lzh_br_consume(br, ds->pt.len_bits);
- if (ds->reading_position)
- ds->state = ST_GET_LITERAL;
- else
- ds->state = ST_RD_LITERAL_1;
- break;
- } else if (ds->pt.len_avail > ds->pt.len_size)
- goto failed;/* Invalid data. */
- ds->loop = 0;
- memset(ds->pt.freq, 0, sizeof(ds->pt.freq));
- if (ds->pt.len_avail < 3 ||
- ds->pt.len_size == ds->pos_pt_len_size) {
- ds->state = ST_RD_PT_4;
- break;
- }
- /* FALL THROUGH */
- case ST_RD_PT_3:
- ds->loop = lzh_read_pt_bitlen(strm, ds->loop, 3);
- if (ds->loop < 3) {
- if (ds->loop < 0 || last)
- goto failed;/* Invalid data. */
- /* Not completed, get following data. */
- ds->state = ST_RD_PT_3;
- return (ARCHIVE_OK);
- }
- /* There are some null in bitlen of the literal. */
- if (!lzh_br_read_ahead(strm, br, 2)) {
- if (last)
- goto failed;/* Truncated data. */
- ds->state = ST_RD_PT_3;
- return (ARCHIVE_OK);
- }
- c = lzh_br_bits(br, 2);
- lzh_br_consume(br, 2);
- if (c > ds->pt.len_avail - 3)
- goto failed;/* Invalid data. */
- for (i = 3; c-- > 0 ;)
- ds->pt.bitlen[i++] = 0;
- ds->loop = i;
- /* FALL THROUGH */
- case ST_RD_PT_4:
- ds->loop = lzh_read_pt_bitlen(strm, ds->loop,
- ds->pt.len_avail);
- if (ds->loop < ds->pt.len_avail) {
- if (ds->loop < 0 || last)
- goto failed;/* Invalid data. */
- /* Not completed, get following data. */
- ds->state = ST_RD_PT_4;
- return (ARCHIVE_OK);
- }
- if (!lzh_make_huffman_table(&(ds->pt)))
- goto failed;/* Invalid data */
- if (ds->reading_position) {
- ds->state = ST_GET_LITERAL;
- break;
- }
- /* FALL THROUGH */
- case ST_RD_LITERAL_1:
- if (!lzh_br_read_ahead(strm, br, ds->lt.len_bits)) {
- if (last)
- goto failed;/* Truncated data. */
- ds->state = ST_RD_LITERAL_1;
- return (ARCHIVE_OK);
- }
- ds->lt.len_avail = lzh_br_bits(br, ds->lt.len_bits);
- lzh_br_consume(br, ds->lt.len_bits);
- /* FALL THROUGH */
- case ST_RD_LITERAL_2:
- if (ds->lt.len_avail == 0) {
- /* There is no bitlen. */
- if (!lzh_br_read_ahead(strm, br,
- ds->lt.len_bits)) {
- if (last)
- goto failed;/* Truncated data.*/
- ds->state = ST_RD_LITERAL_2;
- return (ARCHIVE_OK);
- }
- if (!lzh_make_fake_table(&(ds->lt),
- lzh_br_bits(br, ds->lt.len_bits)))
- goto failed;/* Invalid data */
- lzh_br_consume(br, ds->lt.len_bits);
- ds->state = ST_RD_POS_DATA_1;
- break;
- } else if (ds->lt.len_avail > ds->lt.len_size)
- goto failed;/* Invalid data */
- ds->loop = 0;
- memset(ds->lt.freq, 0, sizeof(ds->lt.freq));
- /* FALL THROUGH */
- case ST_RD_LITERAL_3:
- i = ds->loop;
- while (i < ds->lt.len_avail) {
- if (!lzh_br_read_ahead(strm, br,
- ds->pt.max_bits)) {
- if (last)
- goto failed;/* Truncated data.*/
- ds->loop = i;
- ds->state = ST_RD_LITERAL_3;
- return (ARCHIVE_OK);
- }
- rbits = lzh_br_bits(br, ds->pt.max_bits);
- c = lzh_decode_huffman(&(ds->pt), rbits);
- if (c > 2) {
- /* Note: 'c' will never be more than
- * eighteen since it's limited by
- * PT_BITLEN_SIZE, which is being set
- * to ds->pt.len_size through
- * ds->literal_pt_len_size. */
- lzh_br_consume(br, ds->pt.bitlen[c]);
- c -= 2;
- ds->lt.freq[c]++;
- ds->lt.bitlen[i++] = c;
- } else if (c == 0) {
- lzh_br_consume(br, ds->pt.bitlen[c]);
- ds->lt.bitlen[i++] = 0;
- } else {
- /* c == 1 or c == 2 */
- int n = (c == 1)?4:9;
- if (!lzh_br_read_ahead(strm, br,
- ds->pt.bitlen[c] + n)) {
- if (last) /* Truncated data. */
- goto failed;
- ds->loop = i;
- ds->state = ST_RD_LITERAL_3;
- return (ARCHIVE_OK);
- }
- lzh_br_consume(br, ds->pt.bitlen[c]);
- c = lzh_br_bits(br, n);
- lzh_br_consume(br, n);
- c += (n == 4)?3:20;
- if (i + c > ds->lt.len_avail)
- goto failed;/* Invalid data */
- memset(&(ds->lt.bitlen[i]), 0, c);
- i += c;
- }
- }
- if (i > ds->lt.len_avail ||
- !lzh_make_huffman_table(&(ds->lt)))
- goto failed;/* Invalid data */
- /* FALL THROUGH */
- case ST_RD_POS_DATA_1:
- /*
- * Read a position table compressed in huffman
- * coding.
- */
- ds->pt.len_size = ds->pos_pt_len_size;
- ds->pt.len_bits = ds->pos_pt_len_bits;
- ds->reading_position = 1;
- ds->state = ST_RD_PT_1;
- break;
- case ST_GET_LITERAL:
- return (100);
- }
- }
-failed:
- return (ds->error = ARCHIVE_FAILED);
-}
-
-static int
-lzh_decode_blocks(struct lzh_stream *strm, int last)
-{
- struct lzh_dec *ds = strm->ds;
- struct lzh_br bre = ds->br;
- struct huffman *lt = &(ds->lt);
- struct huffman *pt = &(ds->pt);
- unsigned char *w_buff = ds->w_buff;
- unsigned char *lt_bitlen = lt->bitlen;
- unsigned char *pt_bitlen = pt->bitlen;
- int blocks_avail = ds->blocks_avail, c = 0;
- int copy_len = ds->copy_len, copy_pos = ds->copy_pos;
- int w_pos = ds->w_pos, w_mask = ds->w_mask, w_size = ds->w_size;
- int lt_max_bits = lt->max_bits, pt_max_bits = pt->max_bits;
- int state = ds->state;
-
- for (;;) {
- switch (state) {
- case ST_GET_LITERAL:
- for (;;) {
- if (blocks_avail == 0) {
- /* We have decoded all blocks.
- * Let's handle next blocks. */
- ds->state = ST_RD_BLOCK;
- ds->br = bre;
- ds->blocks_avail = 0;
- ds->w_pos = w_pos;
- ds->copy_pos = 0;
- return (100);
- }
-
- /* lzh_br_read_ahead() always try to fill the
- * cache buffer up. In specific situation we
- * are close to the end of the data, the cache
- * buffer will not be full and thus we have to
- * determine if the cache buffer has some bits
- * as much as we need after lzh_br_read_ahead()
- * failed. */
- if (!lzh_br_read_ahead(strm, &bre,
- lt_max_bits)) {
- if (!last)
- goto next_data;
- /* Remaining bits are less than
- * maximum bits(lt.max_bits) but maybe
- * it still remains as much as we need,
- * so we should try to use it with
- * dummy bits. */
- c = lzh_decode_huffman(lt,
- lzh_br_bits_forced(&bre,
- lt_max_bits));
- lzh_br_consume(&bre, lt_bitlen[c]);
- if (!lzh_br_has(&bre, 0))
- goto failed;/* Over read. */
- } else {
- c = lzh_decode_huffman(lt,
- lzh_br_bits(&bre, lt_max_bits));
- lzh_br_consume(&bre, lt_bitlen[c]);
- }
- blocks_avail--;
- if (c > UCHAR_MAX)
- /* Current block is a match data. */
- break;
- /*
- * 'c' is exactly a literal code.
- */
- /* Save a decoded code to reference it
- * afterward. */
- w_buff[w_pos] = c;
- if (++w_pos >= w_size) {
- w_pos = 0;
- lzh_emit_window(strm, w_size);
- goto next_data;
- }
- }
- /* 'c' is the length of a match pattern we have
- * already extracted, which has be stored in
- * window(ds->w_buff). */
- copy_len = c - (UCHAR_MAX + 1) + MINMATCH;
- /* FALL THROUGH */
- case ST_GET_POS_1:
- /*
- * Get a reference position.
- */
- if (!lzh_br_read_ahead(strm, &bre, pt_max_bits)) {
- if (!last) {
- state = ST_GET_POS_1;
- ds->copy_len = copy_len;
- goto next_data;
- }
- copy_pos = lzh_decode_huffman(pt,
- lzh_br_bits_forced(&bre, pt_max_bits));
- lzh_br_consume(&bre, pt_bitlen[copy_pos]);
- if (!lzh_br_has(&bre, 0))
- goto failed;/* Over read. */
- } else {
- copy_pos = lzh_decode_huffman(pt,
- lzh_br_bits(&bre, pt_max_bits));
- lzh_br_consume(&bre, pt_bitlen[copy_pos]);
- }
- /* FALL THROUGH */
- case ST_GET_POS_2:
- if (copy_pos > 1) {
- /* We need an additional adjustment number to
- * the position. */
- int p = copy_pos - 1;
- if (!lzh_br_read_ahead(strm, &bre, p)) {
- if (last)
- goto failed;/* Truncated data.*/
- state = ST_GET_POS_2;
- ds->copy_len = copy_len;
- ds->copy_pos = copy_pos;
- goto next_data;
- }
- copy_pos = (1 << p) + lzh_br_bits(&bre, p);
- lzh_br_consume(&bre, p);
- }
- /* The position is actually a distance from the last
- * code we had extracted and thus we have to convert
- * it to a position of the window. */
- copy_pos = (w_pos - copy_pos - 1) & w_mask;
- /* FALL THROUGH */
- case ST_COPY_DATA:
- /*
- * Copy `copy_len' bytes as extracted data from
- * the window into the output buffer.
- */
- for (;;) {
- int l;
-
- l = copy_len;
- if (copy_pos > w_pos) {
- if (l > w_size - copy_pos)
- l = w_size - copy_pos;
- } else {
- if (l > w_size - w_pos)
- l = w_size - w_pos;
- }
- if ((copy_pos + l < w_pos)
- || (w_pos + l < copy_pos)) {
- /* No overlap. */
- memcpy(w_buff + w_pos,
- w_buff + copy_pos, l);
- } else {
- const unsigned char *s;
- unsigned char *d;
- int li;
-
- d = w_buff + w_pos;
- s = w_buff + copy_pos;
- for (li = 0; li < l-1;) {
- d[li] = s[li];li++;
- d[li] = s[li];li++;
- }
- if (li < l)
- d[li] = s[li];
- }
- w_pos += l;
- if (w_pos == w_size) {
- w_pos = 0;
- lzh_emit_window(strm, w_size);
- if (copy_len <= l)
- state = ST_GET_LITERAL;
- else {
- state = ST_COPY_DATA;
- ds->copy_len = copy_len - l;
- ds->copy_pos =
- (copy_pos + l) & w_mask;
- }
- goto next_data;
- }
- if (copy_len <= l)
- /* A copy of current pattern ended. */
- break;
- copy_len -= l;
- copy_pos = (copy_pos + l) & w_mask;
- }
- state = ST_GET_LITERAL;
- break;
- }
- }
-failed:
- return (ds->error = ARCHIVE_FAILED);
-next_data:
- ds->br = bre;
- ds->blocks_avail = blocks_avail;
- ds->state = state;
- ds->w_pos = w_pos;
- return (ARCHIVE_OK);
-}
-
-static int
-lzh_huffman_init(struct huffman *hf, size_t len_size, int tbl_bits)
-{
- int bits;
-
- if (hf->bitlen == NULL) {
- hf->bitlen = malloc(len_size * sizeof(hf->bitlen[0]));
- if (hf->bitlen == NULL)
- return (ARCHIVE_FATAL);
- }
- if (hf->tbl == NULL) {
- if (tbl_bits < HTBL_BITS)
- bits = tbl_bits;
- else
- bits = HTBL_BITS;
- hf->tbl = malloc(((size_t)1 << bits) * sizeof(hf->tbl[0]));
- if (hf->tbl == NULL)
- return (ARCHIVE_FATAL);
- }
- if (hf->tree == NULL && tbl_bits > HTBL_BITS) {
- hf->tree_avail = 1 << (tbl_bits - HTBL_BITS + 4);
- hf->tree = malloc(hf->tree_avail * sizeof(hf->tree[0]));
- if (hf->tree == NULL)
- return (ARCHIVE_FATAL);
- }
- hf->len_size = (int)len_size;
- hf->tbl_bits = tbl_bits;
- return (ARCHIVE_OK);
-}
-
-static void
-lzh_huffman_free(struct huffman *hf)
-{
- free(hf->bitlen);
- free(hf->tbl);
- free(hf->tree);
-}
-
-static const char bitlen_tbl[0x400] = {
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
- 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
- 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
- 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 16, 0
-};
-static int
-lzh_read_pt_bitlen(struct lzh_stream *strm, int start, int end)
-{
- struct lzh_dec *ds = strm->ds;
- struct lzh_br *br = &(ds->br);
- int c, i;
-
- for (i = start; i < end; ) {
- /*
- * bit pattern the number we need
- * 000 -> 0
- * 001 -> 1
- * 010 -> 2
- * ...
- * 110 -> 6
- * 1110 -> 7
- * 11110 -> 8
- * ...
- * 1111111111110 -> 16
- */
- if (!lzh_br_read_ahead(strm, br, 3))
- return (i);
- if ((c = lzh_br_bits(br, 3)) == 7) {
- if (!lzh_br_read_ahead(strm, br, 13))
- return (i);
- c = bitlen_tbl[lzh_br_bits(br, 13) & 0x3FF];
- if (c)
- lzh_br_consume(br, c - 3);
- else
- return (-1);/* Invalid data. */
- } else
- lzh_br_consume(br, 3);
- ds->pt.bitlen[i++] = c;
- ds->pt.freq[c]++;
- }
- return (i);
-}
-
-static int
-lzh_make_fake_table(struct huffman *hf, uint16_t c)
-{
- if (c >= hf->len_size)
- return (0);
- hf->tbl[0] = c;
- hf->max_bits = 0;
- hf->shift_bits = 0;
- hf->bitlen[hf->tbl[0]] = 0;
- return (1);
-}
-
-/*
- * Make a huffman coding table.
- */
-static int
-lzh_make_huffman_table(struct huffman *hf)
-{
- uint16_t *tbl;
- const unsigned char *bitlen;
- int bitptn[17], weight[17];
- int i, maxbits = 0, ptn, tbl_size, w;
- int diffbits, len_avail;
-
- /*
- * Initialize bit patterns.
- */
- ptn = 0;
- for (i = 1, w = 1 << 15; i <= 16; i++, w >>= 1) {
- bitptn[i] = ptn;
- weight[i] = w;
- if (hf->freq[i]) {
- ptn += hf->freq[i] * w;
- maxbits = i;
- }
- }
- if (ptn != 0x10000 || maxbits > hf->tbl_bits)
- return (0);/* Invalid */
-
- hf->max_bits = maxbits;
-
- /*
- * Cut out extra bits which we won't house in the table.
- * This preparation reduces the same calculation in the for-loop
- * making the table.
- */
- if (maxbits < 16) {
- int ebits = 16 - maxbits;
- for (i = 1; i <= maxbits; i++) {
- bitptn[i] >>= ebits;
- weight[i] >>= ebits;
- }
- }
- if (maxbits > HTBL_BITS) {
- unsigned htbl_max;
- uint16_t *p;
-
- diffbits = maxbits - HTBL_BITS;
- for (i = 1; i <= HTBL_BITS; i++) {
- bitptn[i] >>= diffbits;
- weight[i] >>= diffbits;
- }
- htbl_max = bitptn[HTBL_BITS] +
- weight[HTBL_BITS] * hf->freq[HTBL_BITS];
- p = &(hf->tbl[htbl_max]);
- while (p < &hf->tbl[1U<<HTBL_BITS])
- *p++ = 0;
- } else
- diffbits = 0;
- hf->shift_bits = diffbits;
-
- /*
- * Make the table.
- */
- tbl_size = 1 << HTBL_BITS;
- tbl = hf->tbl;
- bitlen = hf->bitlen;
- len_avail = hf->len_avail;
- hf->tree_used = 0;
- for (i = 0; i < len_avail; i++) {
- uint16_t *p;
- int len, cnt;
- uint16_t bit;
- int extlen;
- struct htree_t *ht;
-
- if (bitlen[i] == 0)
- continue;
- /* Get a bit pattern */
- len = bitlen[i];
- ptn = bitptn[len];
- cnt = weight[len];
- if (len <= HTBL_BITS) {
- /* Calculate next bit pattern */
- if ((bitptn[len] = ptn + cnt) > tbl_size)
- return (0);/* Invalid */
- /* Update the table */
- p = &(tbl[ptn]);
- if (cnt > 7) {
- uint16_t *pc;
-
- cnt -= 8;
- pc = &p[cnt];
- pc[0] = (uint16_t)i;
- pc[1] = (uint16_t)i;
- pc[2] = (uint16_t)i;
- pc[3] = (uint16_t)i;
- pc[4] = (uint16_t)i;
- pc[5] = (uint16_t)i;
- pc[6] = (uint16_t)i;
- pc[7] = (uint16_t)i;
- if (cnt > 7) {
- cnt -= 8;
- memcpy(&p[cnt], pc,
- 8 * sizeof(uint16_t));
- pc = &p[cnt];
- while (cnt > 15) {
- cnt -= 16;
- memcpy(&p[cnt], pc,
- 16 * sizeof(uint16_t));
- }
- }
- if (cnt)
- memcpy(p, pc, cnt * sizeof(uint16_t));
- } else {
- while (cnt > 1) {
- p[--cnt] = (uint16_t)i;
- p[--cnt] = (uint16_t)i;
- }
- if (cnt)
- p[--cnt] = (uint16_t)i;
- }
- continue;
- }
-
- /*
- * A bit length is too big to be housed to a direct table,
- * so we use a tree model for its extra bits.
- */
- bitptn[len] = ptn + cnt;
- bit = 1U << (diffbits -1);
- extlen = len - HTBL_BITS;
-
- p = &(tbl[ptn >> diffbits]);
- if (*p == 0) {
- *p = len_avail + hf->tree_used;
- ht = &(hf->tree[hf->tree_used++]);
- if (hf->tree_used > hf->tree_avail)
- return (0);/* Invalid */
- ht->left = 0;
- ht->right = 0;
- } else {
- if (*p < len_avail ||
- *p >= (len_avail + hf->tree_used))
- return (0);/* Invalid */
- ht = &(hf->tree[*p - len_avail]);
- }
- while (--extlen > 0) {
- if (ptn & bit) {
- if (ht->left < len_avail) {
- ht->left = len_avail + hf->tree_used;
- ht = &(hf->tree[hf->tree_used++]);
- if (hf->tree_used > hf->tree_avail)
- return (0);/* Invalid */
- ht->left = 0;
- ht->right = 0;
- } else {
- ht = &(hf->tree[ht->left - len_avail]);
- }
- } else {
- if (ht->right < len_avail) {
- ht->right = len_avail + hf->tree_used;
- ht = &(hf->tree[hf->tree_used++]);
- if (hf->tree_used > hf->tree_avail)
- return (0);/* Invalid */
- ht->left = 0;
- ht->right = 0;
- } else {
- ht = &(hf->tree[ht->right - len_avail]);
- }
- }
- bit >>= 1;
- }
- if (ptn & bit) {
- if (ht->left != 0)
- return (0);/* Invalid */
- ht->left = (uint16_t)i;
- } else {
- if (ht->right != 0)
- return (0);/* Invalid */
- ht->right = (uint16_t)i;
- }
- }
- return (1);
-}
-
-static int
-lzh_decode_huffman_tree(struct huffman *hf, unsigned rbits, int c)
-{
- struct htree_t *ht;
- int extlen;
-
- ht = hf->tree;
- extlen = hf->shift_bits;
- while (c >= hf->len_avail) {
- c -= hf->len_avail;
- if (extlen-- <= 0 || c >= hf->tree_used)
- return (0);
- if (rbits & (1U << extlen))
- c = ht[c].left;
- else
- c = ht[c].right;
- }
- return (c);
-}
-
-static inline int
-lzh_decode_huffman(struct huffman *hf, unsigned rbits)
-{
- int c;
- /*
- * At first search an index table for a bit pattern.
- * If it fails, search a huffman tree for.
- */
- c = hf->tbl[rbits >> hf->shift_bits];
- if (c < hf->len_avail || hf->len_avail == 0)
- return (c);
- /* This bit pattern needs to be found out at a huffman tree. */
- return (lzh_decode_huffman_tree(hf, rbits, c));
-}
-
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_format_mtree.c b/contrib/libs/libarchive/libarchive/archive_read_support_format_mtree.c
deleted file mode 100644
index a5fa30e3c2..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_format_mtree.c
+++ /dev/null
@@ -1,2156 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * Copyright (c) 2008 Joerg Sonnenberger
- * Copyright (c) 2011-2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 201165 2009-12-29 05:52:13Z kientzle $");
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#include <stddef.h>
-/* #include <stdint.h> */ /* See archive_platform.h */
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_CTYPE_H
-#include <ctype.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_entry_private.h"
-#include "archive_private.h"
-#include "archive_rb.h"
-#include "archive_read_private.h"
-#include "archive_string.h"
-#include "archive_pack_dev.h"
-
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-#ifndef O_CLOEXEC
-#define O_CLOEXEC 0
-#endif
-
-#define MTREE_HAS_DEVICE 0x0001
-#define MTREE_HAS_FFLAGS 0x0002
-#define MTREE_HAS_GID 0x0004
-#define MTREE_HAS_GNAME 0x0008
-#define MTREE_HAS_MTIME 0x0010
-#define MTREE_HAS_NLINK 0x0020
-#define MTREE_HAS_PERM 0x0040
-#define MTREE_HAS_SIZE 0x0080
-#define MTREE_HAS_TYPE 0x0100
-#define MTREE_HAS_UID 0x0200
-#define MTREE_HAS_UNAME 0x0400
-
-#define MTREE_HAS_OPTIONAL 0x0800
-#define MTREE_HAS_NOCHANGE 0x1000 /* FreeBSD specific */
-
-#define MAX_LINE_LEN (1024 * 1024)
-
-struct mtree_option {
- struct mtree_option *next;
- char *value;
-};
-
-struct mtree_entry {
- struct archive_rb_node rbnode;
- struct mtree_entry *next_dup;
- struct mtree_entry *next;
- struct mtree_option *options;
- char *name;
- char full;
- char used;
-};
-
-struct mtree {
- struct archive_string line;
- size_t buffsize;
- char *buff;
- int64_t offset;
- int fd;
- int archive_format;
- const char *archive_format_name;
- struct mtree_entry *entries;
- struct mtree_entry *this_entry;
- struct archive_rb_tree entry_rbtree;
- struct archive_string current_dir;
- struct archive_string contents_name;
-
- struct archive_entry_linkresolver *resolver;
- struct archive_rb_tree rbtree;
-
- int64_t cur_size;
- char checkfs;
-};
-
-static int bid_keycmp(const char *, const char *, ssize_t);
-static int cleanup(struct archive_read *);
-static int detect_form(struct archive_read *, int *);
-static int mtree_bid(struct archive_read *, int);
-static int parse_file(struct archive_read *, struct archive_entry *,
- struct mtree *, struct mtree_entry *, int *);
-static void parse_escapes(char *, struct mtree_entry *);
-static int parse_line(struct archive_read *, struct archive_entry *,
- struct mtree *, struct mtree_entry *, int *);
-static int parse_keyword(struct archive_read *, struct mtree *,
- struct archive_entry *, struct mtree_option *, int *);
-static int read_data(struct archive_read *a,
- const void **buff, size_t *size, int64_t *offset);
-static ssize_t readline(struct archive_read *, struct mtree *, char **, ssize_t);
-static int skip(struct archive_read *a);
-static int read_header(struct archive_read *,
- struct archive_entry *);
-static int64_t mtree_atol(char **, int base);
-#ifndef HAVE_STRNLEN
-static size_t mtree_strnlen(const char *, size_t);
-#endif
-
-/*
- * There's no standard for TIME_T_MAX/TIME_T_MIN. So we compute them
- * here. TODO: Move this to configure time, but be careful
- * about cross-compile environments.
- */
-static int64_t
-get_time_t_max(void)
-{
-#if defined(TIME_T_MAX)
- return TIME_T_MAX;
-#else
- /* ISO C allows time_t to be a floating-point type,
- but POSIX requires an integer type. The following
- should work on any system that follows the POSIX
- conventions. */
- if (((time_t)0) < ((time_t)-1)) {
- /* Time_t is unsigned */
- return (~(time_t)0);
- } else {
- /* Time_t is signed. */
- /* Assume it's the same as int64_t or int32_t */
- if (sizeof(time_t) == sizeof(int64_t)) {
- return (time_t)INT64_MAX;
- } else {
- return (time_t)INT32_MAX;
- }
- }
-#endif
-}
-
-static int64_t
-get_time_t_min(void)
-{
-#if defined(TIME_T_MIN)
- return TIME_T_MIN;
-#else
- if (((time_t)0) < ((time_t)-1)) {
- /* Time_t is unsigned */
- return (time_t)0;
- } else {
- /* Time_t is signed. */
- if (sizeof(time_t) == sizeof(int64_t)) {
- return (time_t)INT64_MIN;
- } else {
- return (time_t)INT32_MIN;
- }
- }
-#endif
-}
-
-#ifdef HAVE_STRNLEN
-#define mtree_strnlen(a,b) strnlen(a,b)
-#else
-static size_t
-mtree_strnlen(const char *p, size_t maxlen)
-{
- size_t i;
-
- for (i = 0; i <= maxlen; i++) {
- if (p[i] == 0)
- break;
- }
- if (i > maxlen)
- return (-1);/* invalid */
- return (i);
-}
-#endif
-
-static int
-archive_read_format_mtree_options(struct archive_read *a,
- const char *key, const char *val)
-{
- struct mtree *mtree;
-
- mtree = (struct mtree *)(a->format->data);
- if (strcmp(key, "checkfs") == 0) {
- /* Allows to read information missing from the mtree from the file system */
- if (val == NULL || val[0] == 0) {
- mtree->checkfs = 0;
- } else {
- mtree->checkfs = 1;
- }
- return (ARCHIVE_OK);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-static void
-free_options(struct mtree_option *head)
-{
- struct mtree_option *next;
-
- for (; head != NULL; head = next) {
- next = head->next;
- free(head->value);
- free(head);
- }
-}
-
-static int
-mtree_cmp_node(const struct archive_rb_node *n1,
- const struct archive_rb_node *n2)
-{
- const struct mtree_entry *e1 = (const struct mtree_entry *)n1;
- const struct mtree_entry *e2 = (const struct mtree_entry *)n2;
-
- return (strcmp(e1->name, e2->name));
-}
-
-static int
-mtree_cmp_key(const struct archive_rb_node *n, const void *key)
-{
- const struct mtree_entry *e = (const struct mtree_entry *)n;
-
- return (strcmp(e->name, key));
-}
-
-int
-archive_read_support_format_mtree(struct archive *_a)
-{
- static const struct archive_rb_tree_ops rb_ops = {
- mtree_cmp_node, mtree_cmp_key,
- };
- struct archive_read *a = (struct archive_read *)_a;
- struct mtree *mtree;
- int r;
-
- archive_check_magic(_a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_format_mtree");
-
- mtree = (struct mtree *)calloc(1, sizeof(*mtree));
- if (mtree == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate mtree data");
- return (ARCHIVE_FATAL);
- }
- mtree->checkfs = 0;
- mtree->fd = -1;
-
- __archive_rb_tree_init(&mtree->rbtree, &rb_ops);
-
- r = __archive_read_register_format(a, mtree, "mtree",
- mtree_bid, archive_read_format_mtree_options, read_header, read_data, skip, NULL, cleanup, NULL, NULL);
-
- if (r != ARCHIVE_OK)
- free(mtree);
- return (ARCHIVE_OK);
-}
-
-static int
-cleanup(struct archive_read *a)
-{
- struct mtree *mtree;
- struct mtree_entry *p, *q;
-
- mtree = (struct mtree *)(a->format->data);
-
- p = mtree->entries;
- while (p != NULL) {
- q = p->next;
- free(p->name);
- free_options(p->options);
- free(p);
- p = q;
- }
- archive_string_free(&mtree->line);
- archive_string_free(&mtree->current_dir);
- archive_string_free(&mtree->contents_name);
- archive_entry_linkresolver_free(mtree->resolver);
-
- free(mtree->buff);
- free(mtree);
- (a->format->data) = NULL;
- return (ARCHIVE_OK);
-}
-
-static ssize_t
-get_line_size(const char *b, ssize_t avail, ssize_t *nlsize)
-{
- ssize_t len;
-
- len = 0;
- while (len < avail) {
- switch (*b) {
- case '\0':/* Non-ascii character or control character. */
- if (nlsize != NULL)
- *nlsize = 0;
- return (-1);
- case '\r':
- if (avail-len > 1 && b[1] == '\n') {
- if (nlsize != NULL)
- *nlsize = 2;
- return (len+2);
- }
- /* FALL THROUGH */
- case '\n':
- if (nlsize != NULL)
- *nlsize = 1;
- return (len+1);
- default:
- b++;
- len++;
- break;
- }
- }
- if (nlsize != NULL)
- *nlsize = 0;
- return (avail);
-}
-
-/*
- * <---------------- ravail --------------------->
- * <-- diff ------> <--- avail ----------------->
- * <---- len ----------->
- * | Previous lines | line being parsed nl extra |
- * ^
- * b
- *
- */
-static ssize_t
-next_line(struct archive_read *a,
- const char **b, ssize_t *avail, ssize_t *ravail, ssize_t *nl)
-{
- ssize_t len;
- int quit;
-
- quit = 0;
- if (*avail == 0) {
- *nl = 0;
- len = 0;
- } else
- len = get_line_size(*b, *avail, nl);
- /*
- * Read bytes more while it does not reach the end of line.
- */
- while (*nl == 0 && len == *avail && !quit) {
- ssize_t diff = *ravail - *avail;
- size_t nbytes_req = (*ravail+1023) & ~1023U;
- ssize_t tested;
-
- /*
- * Place an arbitrary limit on the line length.
- * mtree is almost free-form input and without line length limits,
- * it can consume a lot of memory.
- */
- if (len >= MAX_LINE_LEN)
- return (-1);
-
- /* Increase reading bytes if it is not enough to at least
- * new two lines. */
- if (nbytes_req < (size_t)*ravail + 160)
- nbytes_req <<= 1;
-
- *b = __archive_read_ahead(a, nbytes_req, avail);
- if (*b == NULL) {
- if (*ravail >= *avail)
- return (0);
- /* Reading bytes reaches the end of file. */
- *b = __archive_read_ahead(a, *avail, avail);
- quit = 1;
- }
- *ravail = *avail;
- *b += diff;
- *avail -= diff;
- tested = len;/* Skip some bytes we already determined. */
- len = get_line_size(*b + len, *avail - len, nl);
- if (len >= 0)
- len += tested;
- }
- return (len);
-}
-
-/*
- * Compare characters with a mtree keyword.
- * Returns the length of a mtree keyword if matched.
- * Returns 0 if not matched.
- */
-static int
-bid_keycmp(const char *p, const char *key, ssize_t len)
-{
- int match_len = 0;
-
- while (len > 0 && *p && *key) {
- if (*p == *key) {
- --len;
- ++p;
- ++key;
- ++match_len;
- continue;
- }
- return (0);/* Not match */
- }
- if (*key != '\0')
- return (0);/* Not match */
-
- /* A following character should be specified characters */
- if (p[0] == '=' || p[0] == ' ' || p[0] == '\t' ||
- p[0] == '\n' || p[0] == '\r' ||
- (p[0] == '\\' && (p[1] == '\n' || p[1] == '\r')))
- return (match_len);
- return (0);/* Not match */
-}
-
-/*
- * Test whether the characters 'p' has is mtree keyword.
- * Returns the length of a detected keyword.
- * Returns 0 if any keywords were not found.
- */
-static int
-bid_keyword(const char *p, ssize_t len)
-{
- static const char * const keys_c[] = {
- "content", "contents", "cksum", NULL
- };
- static const char * const keys_df[] = {
- "device", "flags", NULL
- };
- static const char * const keys_g[] = {
- "gid", "gname", NULL
- };
- static const char * const keys_il[] = {
- "ignore", "inode", "link", NULL
- };
- static const char * const keys_m[] = {
- "md5", "md5digest", "mode", NULL
- };
- static const char * const keys_no[] = {
- "nlink", "nochange", "optional", NULL
- };
- static const char * const keys_r[] = {
- "resdevice", "rmd160", "rmd160digest", NULL
- };
- static const char * const keys_s[] = {
- "sha1", "sha1digest",
- "sha256", "sha256digest",
- "sha384", "sha384digest",
- "sha512", "sha512digest",
- "size", NULL
- };
- static const char * const keys_t[] = {
- "tags", "time", "type", NULL
- };
- static const char * const keys_u[] = {
- "uid", "uname", NULL
- };
- const char * const *keys;
- int i;
-
- switch (*p) {
- case 'c': keys = keys_c; break;
- case 'd': case 'f': keys = keys_df; break;
- case 'g': keys = keys_g; break;
- case 'i': case 'l': keys = keys_il; break;
- case 'm': keys = keys_m; break;
- case 'n': case 'o': keys = keys_no; break;
- case 'r': keys = keys_r; break;
- case 's': keys = keys_s; break;
- case 't': keys = keys_t; break;
- case 'u': keys = keys_u; break;
- default: return (0);/* Unknown key */
- }
-
- for (i = 0; keys[i] != NULL; i++) {
- int l = bid_keycmp(p, keys[i], len);
- if (l > 0)
- return (l);
- }
- return (0);/* Unknown key */
-}
-
-/*
- * Test whether there is a set of mtree keywords.
- * Returns the number of keyword.
- * Returns -1 if we got incorrect sequence.
- * This function expects a set of "<space characters>keyword=value".
- * When "unset" is specified, expects a set of "<space characters>keyword".
- */
-static int
-bid_keyword_list(const char *p, ssize_t len, int unset, int last_is_path)
-{
- int l;
- int keycnt = 0;
-
- while (len > 0 && *p) {
- int blank = 0;
-
- /* Test whether there are blank characters in the line. */
- while (len >0 && (*p == ' ' || *p == '\t')) {
- ++p;
- --len;
- blank = 1;
- }
- if (*p == '\n' || *p == '\r')
- break;
- if (p[0] == '\\' && (p[1] == '\n' || p[1] == '\r'))
- break;
- if (!blank && !last_is_path) /* No blank character. */
- return (-1);
- if (last_is_path && len == 0)
- return (keycnt);
-
- if (unset) {
- l = bid_keycmp(p, "all", len);
- if (l > 0)
- return (1);
- }
- /* Test whether there is a correct key in the line. */
- l = bid_keyword(p, len);
- if (l == 0)
- return (-1);/* Unknown keyword was found. */
- p += l;
- len -= l;
- keycnt++;
-
- /* Skip value */
- if (*p == '=') {
- int value = 0;
- ++p;
- --len;
- while (len > 0 && *p != ' ' && *p != '\t') {
- ++p;
- --len;
- value = 1;
- }
- /* A keyword should have a its value unless
- * "/unset" operation. */
- if (!unset && value == 0)
- return (-1);
- }
- }
- return (keycnt);
-}
-
-static int
-bid_entry(const char *p, ssize_t len, ssize_t nl, int *last_is_path)
-{
- int f = 0;
- static const unsigned char safe_char[256] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */
- /* !"$%&'()*+,-./ EXCLUSION:( )(#) */
- 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */
- /* 0123456789:;<>? EXCLUSION:(=) */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, /* 30 - 3F */
- /* @ABCDEFGHIJKLMNO */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */
- /* PQRSTUVWXYZ[\]^_ */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */
- /* `abcdefghijklmno */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */
- /* pqrstuvwxyz{|}~ */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* 70 - 7F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */
- };
- ssize_t ll;
- const char *pp = p;
- const char * const pp_end = pp + len;
-
- *last_is_path = 0;
- /*
- * Skip the path-name which is quoted.
- */
- for (;pp < pp_end; ++pp) {
- if (!safe_char[*(const unsigned char *)pp]) {
- if (*pp != ' ' && *pp != '\t' && *pp != '\r'
- && *pp != '\n')
- f = 0;
- break;
- }
- f = 1;
- }
- ll = pp_end - pp;
-
- /* If a path-name was not found at the first, try to check
- * a mtree format(a.k.a form D) ``NetBSD's mtree -D'' creates,
- * which places the path-name at the last. */
- if (f == 0) {
- const char *pb = p + len - nl;
- int name_len = 0;
- int slash;
-
- /* The form D accepts only a single line for an entry. */
- if (pb-2 >= p &&
- pb[-1] == '\\' && (pb[-2] == ' ' || pb[-2] == '\t'))
- return (-1);
- if (pb-1 >= p && pb[-1] == '\\')
- return (-1);
-
- slash = 0;
- while (p <= --pb && *pb != ' ' && *pb != '\t') {
- if (!safe_char[*(const unsigned char *)pb])
- return (-1);
- name_len++;
- /* The pathname should have a slash in this
- * format. */
- if (*pb == '/')
- slash = 1;
- }
- if (name_len == 0 || slash == 0)
- return (-1);
- /* If '/' is placed at the first in this field, this is not
- * a valid filename. */
- if (pb[1] == '/')
- return (-1);
- ll = len - nl - name_len;
- pp = p;
- *last_is_path = 1;
- }
-
- return (bid_keyword_list(pp, ll, 0, *last_is_path));
-}
-
-#define MAX_BID_ENTRY 3
-
-static int
-mtree_bid(struct archive_read *a, int best_bid)
-{
- const char *signature = "#mtree";
- const char *p;
-
- (void)best_bid; /* UNUSED */
-
- /* Now let's look at the actual header and see if it matches. */
- p = __archive_read_ahead(a, strlen(signature), NULL);
- if (p == NULL)
- return (-1);
-
- if (memcmp(p, signature, strlen(signature)) == 0)
- return (8 * (int)strlen(signature));
-
- /*
- * There is not a mtree signature. Let's try to detect mtree format.
- */
- return (detect_form(a, NULL));
-}
-
-static int
-detect_form(struct archive_read *a, int *is_form_d)
-{
- const char *p;
- ssize_t avail, ravail;
- ssize_t len, nl;
- int entry_cnt = 0, multiline = 0;
- int form_D = 0;/* The archive is generated by `NetBSD mtree -D'
- * (In this source we call it `form D') . */
-
- if (is_form_d != NULL)
- *is_form_d = 0;
- p = __archive_read_ahead(a, 1, &avail);
- if (p == NULL)
- return (-1);
- ravail = avail;
- for (;;) {
- len = next_line(a, &p, &avail, &ravail, &nl);
- /* The terminal character of the line should be
- * a new line character, '\r\n' or '\n'. */
- if (len <= 0 || nl == 0)
- break;
- if (!multiline) {
- /* Leading whitespace is never significant,
- * ignore it. */
- while (len > 0 && (*p == ' ' || *p == '\t')) {
- ++p;
- --avail;
- --len;
- }
- /* Skip comment or empty line. */
- if (p[0] == '#' || p[0] == '\n' || p[0] == '\r') {
- p += len;
- avail -= len;
- continue;
- }
- } else {
- /* A continuance line; the terminal
- * character of previous line was '\' character. */
- if (bid_keyword_list(p, len, 0, 0) <= 0)
- break;
- if (p[len-nl-1] != '\\') {
- if (multiline == 1 &&
- ++entry_cnt >= MAX_BID_ENTRY)
- break;
- multiline = 0;
- }
- p += len;
- avail -= len;
- continue;
- }
- if (p[0] != '/') {
- int last_is_path, keywords;
-
- keywords = bid_entry(p, len, nl, &last_is_path);
- if (keywords >= 0) {
- if (form_D == 0) {
- if (last_is_path)
- form_D = 1;
- else if (keywords > 0)
- /* This line is not `form D'. */
- form_D = -1;
- } else if (form_D == 1) {
- if (!last_is_path && keywords > 0)
- /* This this is not `form D'
- * and We cannot accept mixed
- * format. */
- break;
- }
- if (!last_is_path && p[len-nl-1] == '\\')
- /* This line continues. */
- multiline = 1;
- else {
- /* We've got plenty of correct lines
- * to assume that this file is a mtree
- * format. */
- if (++entry_cnt >= MAX_BID_ENTRY)
- break;
- }
- } else
- break;
- } else if (len > 4 && strncmp(p, "/set", 4) == 0) {
- if (bid_keyword_list(p+4, len-4, 0, 0) <= 0)
- break;
- /* This line continues. */
- if (p[len-nl-1] == '\\')
- multiline = 2;
- } else if (len > 6 && strncmp(p, "/unset", 6) == 0) {
- if (bid_keyword_list(p+6, len-6, 1, 0) <= 0)
- break;
- /* This line continues. */
- if (p[len-nl-1] == '\\')
- multiline = 2;
- } else
- break;
-
- /* Test next line. */
- p += len;
- avail -= len;
- }
- if (entry_cnt >= MAX_BID_ENTRY || (entry_cnt > 0 && len == 0)) {
- if (is_form_d != NULL) {
- if (form_D == 1)
- *is_form_d = 1;
- }
- return (32);
- }
-
- return (0);
-}
-
-/*
- * The extended mtree format permits multiple lines specifying
- * attributes for each file. For those entries, only the last line
- * is actually used. Practically speaking, that means we have
- * to read the entire mtree file into memory up front.
- *
- * The parsing is done in two steps. First, it is decided if a line
- * changes the global defaults and if it is, processed accordingly.
- * Otherwise, the options of the line are merged with the current
- * global options.
- */
-static int
-add_option(struct archive_read *a, struct mtree_option **global,
- const char *value, size_t len)
-{
- struct mtree_option *opt;
-
- if ((opt = malloc(sizeof(*opt))) == NULL) {
- archive_set_error(&a->archive, errno, "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- if ((opt->value = malloc(len + 1)) == NULL) {
- free(opt);
- archive_set_error(&a->archive, errno, "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- memcpy(opt->value, value, len);
- opt->value[len] = '\0';
- opt->next = *global;
- *global = opt;
- return (ARCHIVE_OK);
-}
-
-static void
-remove_option(struct mtree_option **global, const char *value, size_t len)
-{
- struct mtree_option *iter, *last;
-
- last = NULL;
- for (iter = *global; iter != NULL; last = iter, iter = iter->next) {
- if (strncmp(iter->value, value, len) == 0 &&
- (iter->value[len] == '\0' ||
- iter->value[len] == '='))
- break;
- }
- if (iter == NULL)
- return;
- if (last == NULL)
- *global = iter->next;
- else
- last->next = iter->next;
-
- free(iter->value);
- free(iter);
-}
-
-static int
-process_global_set(struct archive_read *a,
- struct mtree_option **global, const char *line)
-{
- const char *next, *eq;
- size_t len;
- int r;
-
- line += 4;
- for (;;) {
- next = line + strspn(line, " \t\r\n");
- if (*next == '\0')
- return (ARCHIVE_OK);
- line = next;
- next = line + strcspn(line, " \t\r\n");
- eq = strchr(line, '=');
- if (eq > next)
- len = next - line;
- else
- len = eq - line;
-
- remove_option(global, line, len);
- r = add_option(a, global, line, next - line);
- if (r != ARCHIVE_OK)
- return (r);
- line = next;
- }
-}
-
-static int
-process_global_unset(struct archive_read *a,
- struct mtree_option **global, const char *line)
-{
- const char *next;
- size_t len;
-
- line += 6;
- if (strchr(line, '=') != NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "/unset shall not contain `='");
- return ARCHIVE_FATAL;
- }
-
- for (;;) {
- next = line + strspn(line, " \t\r\n");
- if (*next == '\0')
- return (ARCHIVE_OK);
- line = next;
- len = strcspn(line, " \t\r\n");
-
- if (len == 3 && strncmp(line, "all", 3) == 0) {
- free_options(*global);
- *global = NULL;
- } else {
- remove_option(global, line, len);
- }
-
- line += len;
- }
-}
-
-static int
-process_add_entry(struct archive_read *a, struct mtree *mtree,
- struct mtree_option **global, const char *line, ssize_t line_len,
- struct mtree_entry **last_entry, int is_form_d)
-{
- struct mtree_entry *entry;
- struct mtree_option *iter;
- const char *next, *eq, *name, *end;
- size_t name_len, len;
- int r, i;
-
- if ((entry = malloc(sizeof(*entry))) == NULL) {
- archive_set_error(&a->archive, errno, "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- entry->next = NULL;
- entry->options = NULL;
- entry->name = NULL;
- entry->used = 0;
- entry->full = 0;
-
- /* Add this entry to list. */
- if (*last_entry == NULL)
- mtree->entries = entry;
- else
- (*last_entry)->next = entry;
- *last_entry = entry;
-
- if (is_form_d) {
- /* Filename is last item on line. */
- /* Adjust line_len to trim trailing whitespace */
- while (line_len > 0) {
- char last_character = line[line_len - 1];
- if (last_character == '\r'
- || last_character == '\n'
- || last_character == '\t'
- || last_character == ' ') {
- line_len--;
- } else {
- break;
- }
- }
- /* Name starts after the last whitespace separator */
- name = line;
- for (i = 0; i < line_len; i++) {
- if (line[i] == '\r'
- || line[i] == '\n'
- || line[i] == '\t'
- || line[i] == ' ') {
- name = line + i + 1;
- }
- }
- name_len = line + line_len - name;
- end = name;
- } else {
- /* Filename is first item on line */
- name_len = strcspn(line, " \t\r\n");
- name = line;
- line += name_len;
- end = line + line_len;
- }
- /* name/name_len is the name within the line. */
- /* line..end brackets the entire line except the name */
-
- if ((entry->name = malloc(name_len + 1)) == NULL) {
- archive_set_error(&a->archive, errno, "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
-
- memcpy(entry->name, name, name_len);
- entry->name[name_len] = '\0';
- parse_escapes(entry->name, entry);
-
- entry->next_dup = NULL;
- if (entry->full) {
- if (!__archive_rb_tree_insert_node(&mtree->rbtree, &entry->rbnode)) {
- struct mtree_entry *alt;
- alt = (struct mtree_entry *)__archive_rb_tree_find_node(
- &mtree->rbtree, entry->name);
- if (alt != NULL) {
- while (alt->next_dup)
- alt = alt->next_dup;
- alt->next_dup = entry;
- }
- }
- }
-
- for (iter = *global; iter != NULL; iter = iter->next) {
- r = add_option(a, &entry->options, iter->value,
- strlen(iter->value));
- if (r != ARCHIVE_OK)
- return (r);
- }
-
- for (;;) {
- next = line + strspn(line, " \t\r\n");
- if (*next == '\0')
- return (ARCHIVE_OK);
- if (next >= end)
- return (ARCHIVE_OK);
- line = next;
- next = line + strcspn(line, " \t\r\n");
- eq = strchr(line, '=');
- if (eq == NULL || eq > next)
- len = next - line;
- else
- len = eq - line;
-
- remove_option(&entry->options, line, len);
- r = add_option(a, &entry->options, line, next - line);
- if (r != ARCHIVE_OK)
- return (r);
- line = next;
- }
-}
-
-static int
-read_mtree(struct archive_read *a, struct mtree *mtree)
-{
- ssize_t len;
- uintmax_t counter;
- char *p, *s;
- struct mtree_option *global;
- struct mtree_entry *last_entry;
- int r, is_form_d;
-
- mtree->archive_format = ARCHIVE_FORMAT_MTREE;
- mtree->archive_format_name = "mtree";
-
- global = NULL;
- last_entry = NULL;
-
- (void)detect_form(a, &is_form_d);
-
- for (counter = 1; ; ++counter) {
- r = ARCHIVE_OK;
- len = readline(a, mtree, &p, 65536);
- if (len == 0) {
- mtree->this_entry = mtree->entries;
- free_options(global);
- return (ARCHIVE_OK);
- }
- if (len < 0) {
- free_options(global);
- return ((int)len);
- }
- /* Leading whitespace is never significant, ignore it. */
- while (*p == ' ' || *p == '\t') {
- ++p;
- --len;
- }
- /* Skip content lines and blank lines. */
- if (*p == '#')
- continue;
- if (*p == '\r' || *p == '\n' || *p == '\0')
- continue;
- /* Non-printable characters are not allowed */
- for (s = p;s < p + len - 1; s++) {
- if (!isprint((unsigned char)*s) && *s != '\t') {
- r = ARCHIVE_FATAL;
- break;
- }
- }
- if (r != ARCHIVE_OK)
- break;
- if (*p != '/') {
- r = process_add_entry(a, mtree, &global, p, len,
- &last_entry, is_form_d);
- } else if (len > 4 && strncmp(p, "/set", 4) == 0) {
- if (p[4] != ' ' && p[4] != '\t')
- break;
- r = process_global_set(a, &global, p);
- } else if (len > 6 && strncmp(p, "/unset", 6) == 0) {
- if (p[6] != ' ' && p[6] != '\t')
- break;
- r = process_global_unset(a, &global, p);
- } else
- break;
-
- if (r != ARCHIVE_OK) {
- free_options(global);
- return r;
- }
- }
-
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't parse line %ju", counter);
- free_options(global);
- return (ARCHIVE_FATAL);
-}
-
-/*
- * Read in the entire mtree file into memory on the first request.
- * Then use the next unused file to satisfy each header request.
- */
-static int
-read_header(struct archive_read *a, struct archive_entry *entry)
-{
- struct mtree *mtree;
- char *p;
- int r, use_next;
-
- mtree = (struct mtree *)(a->format->data);
-
- if (mtree->fd >= 0) {
- close(mtree->fd);
- mtree->fd = -1;
- }
-
- if (mtree->entries == NULL) {
- mtree->resolver = archive_entry_linkresolver_new();
- if (mtree->resolver == NULL)
- return ARCHIVE_FATAL;
- archive_entry_linkresolver_set_strategy(mtree->resolver,
- ARCHIVE_FORMAT_MTREE);
- r = read_mtree(a, mtree);
- if (r != ARCHIVE_OK)
- return (r);
- }
-
- a->archive.archive_format = mtree->archive_format;
- a->archive.archive_format_name = mtree->archive_format_name;
-
- for (;;) {
- if (mtree->this_entry == NULL)
- return (ARCHIVE_EOF);
- if (strcmp(mtree->this_entry->name, "..") == 0) {
- mtree->this_entry->used = 1;
- if (archive_strlen(&mtree->current_dir) > 0) {
- /* Roll back current path. */
- p = mtree->current_dir.s
- + mtree->current_dir.length - 1;
- while (p >= mtree->current_dir.s && *p != '/')
- --p;
- if (p >= mtree->current_dir.s)
- --p;
- mtree->current_dir.length
- = p - mtree->current_dir.s + 1;
- }
- }
- if (!mtree->this_entry->used) {
- use_next = 0;
- r = parse_file(a, entry, mtree, mtree->this_entry,
- &use_next);
- if (use_next == 0)
- return (r);
- }
- mtree->this_entry = mtree->this_entry->next;
- }
-}
-
-/*
- * A single file can have multiple lines contribute specifications.
- * Parse as many lines as necessary, then pull additional information
- * from a backing file on disk as necessary.
- */
-static int
-parse_file(struct archive_read *a, struct archive_entry *entry,
- struct mtree *mtree, struct mtree_entry *mentry, int *use_next)
-{
- const char *path;
- struct stat st_storage, *st;
- struct mtree_entry *mp;
- struct archive_entry *sparse_entry;
- int r = ARCHIVE_OK, r1, parsed_kws;
-
- mentry->used = 1;
-
- /* Initialize reasonable defaults. */
- archive_entry_set_filetype(entry, AE_IFREG);
- archive_entry_set_size(entry, 0);
- archive_string_empty(&mtree->contents_name);
-
- /* Parse options from this line. */
- parsed_kws = 0;
- r = parse_line(a, entry, mtree, mentry, &parsed_kws);
-
- if (mentry->full) {
- archive_entry_copy_pathname(entry, mentry->name);
- /*
- * "Full" entries are allowed to have multiple lines
- * and those lines aren't required to be adjacent. We
- * don't support multiple lines for "relative" entries
- * nor do we make any attempt to merge data from
- * separate "relative" and "full" entries. (Merging
- * "relative" and "full" entries would require dealing
- * with pathname canonicalization, which is a very
- * tricky subject.)
- */
- mp = (struct mtree_entry *)__archive_rb_tree_find_node(
- &mtree->rbtree, mentry->name);
- for (; mp; mp = mp->next_dup) {
- if (mp->full && !mp->used) {
- /* Later lines override earlier ones. */
- mp->used = 1;
- r1 = parse_line(a, entry, mtree, mp, &parsed_kws);
- if (r1 < r)
- r = r1;
- }
- }
- } else {
- /*
- * Relative entries require us to construct
- * the full path and possibly update the
- * current directory.
- */
- size_t n = archive_strlen(&mtree->current_dir);
- if (n > 0)
- archive_strcat(&mtree->current_dir, "/");
- archive_strcat(&mtree->current_dir, mentry->name);
- archive_entry_copy_pathname(entry, mtree->current_dir.s);
- if (archive_entry_filetype(entry) != AE_IFDIR)
- mtree->current_dir.length = n;
- }
-
- if (mtree->checkfs) {
- /*
- * Try to open and stat the file to get the real size
- * and other file info. It would be nice to avoid
- * this here so that getting a listing of an mtree
- * wouldn't require opening every referenced contents
- * file. But then we wouldn't know the actual
- * contents size, so I don't see a really viable way
- * around this. (Also, we may want to someday pull
- * other unspecified info from the contents file on
- * disk.)
- */
- mtree->fd = -1;
- if (archive_strlen(&mtree->contents_name) > 0)
- path = mtree->contents_name.s;
- else
- path = archive_entry_pathname(entry);
-
- if (archive_entry_filetype(entry) == AE_IFREG ||
- archive_entry_filetype(entry) == AE_IFDIR) {
- mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC);
- __archive_ensure_cloexec_flag(mtree->fd);
- if (mtree->fd == -1 && (
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /*
- * On Windows, attempting to open a file with an
- * invalid name result in EINVAL (Error 22)
- */
- (errno != ENOENT && errno != EINVAL)
-#else
- errno != ENOENT
-#endif
- || archive_strlen(&mtree->contents_name) > 0)) {
- archive_set_error(&a->archive, errno,
- "Can't open %s", path);
- r = ARCHIVE_WARN;
- }
- }
-
- st = &st_storage;
- if (mtree->fd >= 0) {
- if (fstat(mtree->fd, st) == -1) {
- archive_set_error(&a->archive, errno,
- "Could not fstat %s", path);
- r = ARCHIVE_WARN;
- /* If we can't stat it, don't keep it open. */
- close(mtree->fd);
- mtree->fd = -1;
- st = NULL;
- }
- }
-#ifdef HAVE_LSTAT
- else if (lstat(path, st) == -1)
-#else
- else if (la_stat(path, st) == -1)
-#endif
- {
- st = NULL;
- }
-
- /*
- * Check for a mismatch between the type in the specification
- * and the type of the contents object on disk.
- */
- if (st != NULL) {
- if (((st->st_mode & S_IFMT) == S_IFREG &&
- archive_entry_filetype(entry) == AE_IFREG)
-#ifdef S_IFLNK
- ||((st->st_mode & S_IFMT) == S_IFLNK &&
- archive_entry_filetype(entry) == AE_IFLNK)
-#endif
-#ifdef S_IFSOCK
- ||((st->st_mode & S_IFSOCK) == S_IFSOCK &&
- archive_entry_filetype(entry) == AE_IFSOCK)
-#endif
-#ifdef S_IFCHR
- ||((st->st_mode & S_IFMT) == S_IFCHR &&
- archive_entry_filetype(entry) == AE_IFCHR)
-#endif
-#ifdef S_IFBLK
- ||((st->st_mode & S_IFMT) == S_IFBLK &&
- archive_entry_filetype(entry) == AE_IFBLK)
-#endif
- ||((st->st_mode & S_IFMT) == S_IFDIR &&
- archive_entry_filetype(entry) == AE_IFDIR)
-#ifdef S_IFIFO
- ||((st->st_mode & S_IFMT) == S_IFIFO &&
- archive_entry_filetype(entry) == AE_IFIFO)
-#endif
- ) {
- /* Types match. */
- } else {
- /* Types don't match; bail out gracefully. */
- if (mtree->fd >= 0)
- close(mtree->fd);
- mtree->fd = -1;
- if (parsed_kws & MTREE_HAS_OPTIONAL) {
- /* It's not an error for an optional
- * entry to not match disk. */
- *use_next = 1;
- } else if (r == ARCHIVE_OK) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "mtree specification has different"
- " type for %s",
- archive_entry_pathname(entry));
- r = ARCHIVE_WARN;
- }
- return (r);
- }
- }
-
- /*
- * If there is a contents file on disk, pick some of the
- * metadata from that file. For most of these, we only
- * set it from the contents if it wasn't already parsed
- * from the specification.
- */
- if (st != NULL) {
- if (((parsed_kws & MTREE_HAS_DEVICE) == 0 ||
- (parsed_kws & MTREE_HAS_NOCHANGE) != 0) &&
- (archive_entry_filetype(entry) == AE_IFCHR ||
- archive_entry_filetype(entry) == AE_IFBLK))
- archive_entry_set_rdev(entry, st->st_rdev);
- if ((parsed_kws & (MTREE_HAS_GID | MTREE_HAS_GNAME))
- == 0 ||
- (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
- archive_entry_set_gid(entry, st->st_gid);
- if ((parsed_kws & (MTREE_HAS_UID | MTREE_HAS_UNAME))
- == 0 ||
- (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
- archive_entry_set_uid(entry, st->st_uid);
- if ((parsed_kws & MTREE_HAS_MTIME) == 0 ||
- (parsed_kws & MTREE_HAS_NOCHANGE) != 0) {
-#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
- archive_entry_set_mtime(entry, st->st_mtime,
- st->st_mtimespec.tv_nsec);
-#elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
- archive_entry_set_mtime(entry, st->st_mtime,
- st->st_mtim.tv_nsec);
-#elif HAVE_STRUCT_STAT_ST_MTIME_N
- archive_entry_set_mtime(entry, st->st_mtime,
- st->st_mtime_n);
-#elif HAVE_STRUCT_STAT_ST_UMTIME
- archive_entry_set_mtime(entry, st->st_mtime,
- st->st_umtime*1000);
-#elif HAVE_STRUCT_STAT_ST_MTIME_USEC
- archive_entry_set_mtime(entry, st->st_mtime,
- st->st_mtime_usec*1000);
-#else
- archive_entry_set_mtime(entry, st->st_mtime, 0);
-#endif
- }
- if ((parsed_kws & MTREE_HAS_NLINK) == 0 ||
- (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
- archive_entry_set_nlink(entry, st->st_nlink);
- if ((parsed_kws & MTREE_HAS_PERM) == 0 ||
- (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
- archive_entry_set_perm(entry, st->st_mode);
- if ((parsed_kws & MTREE_HAS_SIZE) == 0 ||
- (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
- archive_entry_set_size(entry, st->st_size);
- archive_entry_set_ino(entry, st->st_ino);
- archive_entry_set_dev(entry, st->st_dev);
-
- archive_entry_linkify(mtree->resolver, &entry,
- &sparse_entry);
- } else if (parsed_kws & MTREE_HAS_OPTIONAL) {
- /*
- * Couldn't open the entry, stat it or the on-disk type
- * didn't match. If this entry is optional, just
- * ignore it and read the next header entry.
- */
- *use_next = 1;
- return ARCHIVE_OK;
- }
- }
-
- mtree->cur_size = archive_entry_size(entry);
- mtree->offset = 0;
-
- return r;
-}
-
-/*
- * Each line contains a sequence of keywords.
- */
-static int
-parse_line(struct archive_read *a, struct archive_entry *entry,
- struct mtree *mtree, struct mtree_entry *mp, int *parsed_kws)
-{
- struct mtree_option *iter;
- int r = ARCHIVE_OK, r1;
-
- for (iter = mp->options; iter != NULL; iter = iter->next) {
- r1 = parse_keyword(a, mtree, entry, iter, parsed_kws);
- if (r1 < r)
- r = r1;
- }
- if (r == ARCHIVE_OK && (*parsed_kws & MTREE_HAS_TYPE) == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Missing type keyword in mtree specification");
- return (ARCHIVE_WARN);
- }
- return (r);
-}
-
-/*
- * Device entries have one of the following forms:
- * - raw dev_t
- * - format,major,minor[,subdevice]
- * When parsing succeeded, `pdev' will contain the appropriate dev_t value.
- */
-
-/* strsep() is not in C90, but strcspn() is. */
-/* Taken from http://unixpapa.com/incnote/string.html */
-static char *
-la_strsep(char **sp, const char *sep)
-{
- char *p, *s;
- if (sp == NULL || *sp == NULL || **sp == '\0')
- return(NULL);
- s = *sp;
- p = s + strcspn(s, sep);
- if (*p != '\0')
- *p++ = '\0';
- *sp = p;
- return(s);
-}
-
-static int
-parse_device(dev_t *pdev, struct archive *a, char *val)
-{
-#define MAX_PACK_ARGS 3
- unsigned long numbers[MAX_PACK_ARGS];
- char *p, *dev;
- int argc;
- pack_t *pack;
- dev_t result;
- const char *error = NULL;
-
- memset(pdev, 0, sizeof(*pdev));
- if ((dev = strchr(val, ',')) != NULL) {
- /*
- * Device's major/minor are given in a specified format.
- * Decode and pack it accordingly.
- */
- *dev++ = '\0';
- if ((pack = pack_find(val)) == NULL) {
- archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unknown format `%s'", val);
- return ARCHIVE_WARN;
- }
- argc = 0;
- while ((p = la_strsep(&dev, ",")) != NULL) {
- if (*p == '\0') {
- archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
- "Missing number");
- return ARCHIVE_WARN;
- }
- if (argc >= MAX_PACK_ARGS) {
- archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
- "Too many arguments");
- return ARCHIVE_WARN;
- }
- numbers[argc++] = (unsigned long)mtree_atol(&p, 0);
- }
- if (argc < 2) {
- archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
- "Not enough arguments");
- return ARCHIVE_WARN;
- }
- result = (*pack)(argc, numbers, &error);
- if (error != NULL) {
- archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
- "%s", error);
- return ARCHIVE_WARN;
- }
- } else {
- /* file system raw value. */
- result = (dev_t)mtree_atol(&val, 0);
- }
- *pdev = result;
- return ARCHIVE_OK;
-#undef MAX_PACK_ARGS
-}
-
-static int
-parse_hex_nibble(char c)
-{
- if (c >= '0' && c <= '9')
- return c - '0';
- if (c >= 'a' && c <= 'f')
- return 10 + c - 'a';
-#if 0
- /* XXX: Is uppercase something we should support? */
- if (c >= 'A' && c <= 'F')
- return 10 + c - 'A';
-#endif
-
- return -1;
-}
-
-static int
-parse_digest(struct archive_read *a, struct archive_entry *entry,
- const char *digest, int type)
-{
- unsigned char digest_buf[64];
- int high, low;
- size_t i, j, len;
-
- switch (type) {
- case ARCHIVE_ENTRY_DIGEST_MD5:
- len = sizeof(entry->digest.md5);
- break;
- case ARCHIVE_ENTRY_DIGEST_RMD160:
- len = sizeof(entry->digest.rmd160);
- break;
- case ARCHIVE_ENTRY_DIGEST_SHA1:
- len = sizeof(entry->digest.sha1);
- break;
- case ARCHIVE_ENTRY_DIGEST_SHA256:
- len = sizeof(entry->digest.sha256);
- break;
- case ARCHIVE_ENTRY_DIGEST_SHA384:
- len = sizeof(entry->digest.sha384);
- break;
- case ARCHIVE_ENTRY_DIGEST_SHA512:
- len = sizeof(entry->digest.sha512);
- break;
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Internal error: Unknown digest type");
- return ARCHIVE_FATAL;
- }
-
- if (len > sizeof(digest_buf)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Internal error: Digest storage too large");
- return ARCHIVE_FATAL;
- }
-
- len *= 2;
-
- if (mtree_strnlen(digest, len+1) != len) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "incorrect digest length, ignoring");
- return ARCHIVE_WARN;
- }
-
- for (i = 0, j = 0; i < len; i += 2, j++) {
- high = parse_hex_nibble(digest[i]);
- low = parse_hex_nibble(digest[i+1]);
- if (high == -1 || low == -1) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "invalid digest data, ignoring");
- return ARCHIVE_WARN;
- }
-
- digest_buf[j] = high << 4 | low;
- }
-
- return archive_entry_set_digest(entry, type, digest_buf);
-}
-
-/*
- * Parse a single keyword and its value.
- */
-static int
-parse_keyword(struct archive_read *a, struct mtree *mtree,
- struct archive_entry *entry, struct mtree_option *opt, int *parsed_kws)
-{
- char *val, *key;
-
- key = opt->value;
-
- if (*key == '\0')
- return (ARCHIVE_OK);
-
- if (strcmp(key, "nochange") == 0) {
- *parsed_kws |= MTREE_HAS_NOCHANGE;
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "optional") == 0) {
- *parsed_kws |= MTREE_HAS_OPTIONAL;
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "ignore") == 0) {
- /*
- * The mtree processing is not recursive, so
- * recursion will only happen for explicitly listed
- * entries.
- */
- return (ARCHIVE_OK);
- }
-
- val = strchr(key, '=');
- if (val == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Malformed attribute \"%s\" (%d)", key, key[0]);
- return (ARCHIVE_WARN);
- }
-
- *val = '\0';
- ++val;
-
- switch (key[0]) {
- case 'c':
- if (strcmp(key, "content") == 0
- || strcmp(key, "contents") == 0) {
- parse_escapes(val, NULL);
- archive_strcpy(&mtree->contents_name, val);
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "cksum") == 0)
- return (ARCHIVE_OK);
- break;
- case 'd':
- if (strcmp(key, "device") == 0) {
- /* stat(2) st_rdev field, e.g. the major/minor IDs
- * of a char/block special file */
- int r;
- dev_t dev;
-
- *parsed_kws |= MTREE_HAS_DEVICE;
- r = parse_device(&dev, &a->archive, val);
- if (r == ARCHIVE_OK)
- archive_entry_set_rdev(entry, dev);
- return r;
- }
- break;
- case 'f':
- if (strcmp(key, "flags") == 0) {
- *parsed_kws |= MTREE_HAS_FFLAGS;
- archive_entry_copy_fflags_text(entry, val);
- return (ARCHIVE_OK);
- }
- break;
- case 'g':
- if (strcmp(key, "gid") == 0) {
- *parsed_kws |= MTREE_HAS_GID;
- archive_entry_set_gid(entry, mtree_atol(&val, 10));
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "gname") == 0) {
- *parsed_kws |= MTREE_HAS_GNAME;
- archive_entry_copy_gname(entry, val);
- return (ARCHIVE_OK);
- }
- break;
- case 'i':
- if (strcmp(key, "inode") == 0) {
- archive_entry_set_ino(entry, mtree_atol(&val, 10));
- return (ARCHIVE_OK);
- }
- break;
- case 'l':
- if (strcmp(key, "link") == 0) {
- parse_escapes(val, NULL);
- archive_entry_copy_symlink(entry, val);
- return (ARCHIVE_OK);
- }
- break;
- case 'm':
- if (strcmp(key, "md5") == 0 || strcmp(key, "md5digest") == 0) {
- return parse_digest(a, entry, val,
- ARCHIVE_ENTRY_DIGEST_MD5);
- }
- if (strcmp(key, "mode") == 0) {
- if (val[0] < '0' || val[0] > '7') {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Symbolic or non-octal mode \"%s\" unsupported", val);
- return (ARCHIVE_WARN);
- }
- *parsed_kws |= MTREE_HAS_PERM;
- archive_entry_set_perm(entry, (mode_t)mtree_atol(&val, 8));
- return (ARCHIVE_OK);
- }
- break;
- case 'n':
- if (strcmp(key, "nlink") == 0) {
- *parsed_kws |= MTREE_HAS_NLINK;
- archive_entry_set_nlink(entry,
- (unsigned int)mtree_atol(&val, 10));
- return (ARCHIVE_OK);
- }
- break;
- case 'r':
- if (strcmp(key, "resdevice") == 0) {
- /* stat(2) st_dev field, e.g. the device ID where the
- * inode resides */
- int r;
- dev_t dev;
-
- r = parse_device(&dev, &a->archive, val);
- if (r == ARCHIVE_OK)
- archive_entry_set_dev(entry, dev);
- return r;
- }
- if (strcmp(key, "rmd160") == 0 ||
- strcmp(key, "rmd160digest") == 0) {
- return parse_digest(a, entry, val,
- ARCHIVE_ENTRY_DIGEST_RMD160);
- }
- break;
- case 's':
- if (strcmp(key, "sha1") == 0 ||
- strcmp(key, "sha1digest") == 0) {
- return parse_digest(a, entry, val,
- ARCHIVE_ENTRY_DIGEST_SHA1);
- }
- if (strcmp(key, "sha256") == 0 ||
- strcmp(key, "sha256digest") == 0) {
- return parse_digest(a, entry, val,
- ARCHIVE_ENTRY_DIGEST_SHA256);
- }
- if (strcmp(key, "sha384") == 0 ||
- strcmp(key, "sha384digest") == 0) {
- return parse_digest(a, entry, val,
- ARCHIVE_ENTRY_DIGEST_SHA384);
- }
- if (strcmp(key, "sha512") == 0 ||
- strcmp(key, "sha512digest") == 0) {
- return parse_digest(a, entry, val,
- ARCHIVE_ENTRY_DIGEST_SHA512);
- }
- if (strcmp(key, "size") == 0) {
- archive_entry_set_size(entry, mtree_atol(&val, 10));
- return (ARCHIVE_OK);
- }
- break;
- case 't':
- if (strcmp(key, "tags") == 0) {
- /*
- * Comma delimited list of tags.
- * Ignore the tags for now, but the interface
- * should be extended to allow inclusion/exclusion.
- */
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "time") == 0) {
- int64_t m;
- int64_t my_time_t_max = get_time_t_max();
- int64_t my_time_t_min = get_time_t_min();
- long ns = 0;
-
- *parsed_kws |= MTREE_HAS_MTIME;
- m = mtree_atol(&val, 10);
- /* Replicate an old mtree bug:
- * 123456789.1 represents 123456789
- * seconds and 1 nanosecond. */
- if (*val == '.') {
- ++val;
- ns = (long)mtree_atol(&val, 10);
- if (ns < 0)
- ns = 0;
- else if (ns > 999999999)
- ns = 999999999;
- }
- if (m > my_time_t_max)
- m = my_time_t_max;
- else if (m < my_time_t_min)
- m = my_time_t_min;
- archive_entry_set_mtime(entry, (time_t)m, ns);
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "type") == 0) {
- switch (val[0]) {
- case 'b':
- if (strcmp(val, "block") == 0) {
- *parsed_kws |= MTREE_HAS_TYPE;
- archive_entry_set_filetype(entry,
- AE_IFBLK);
- return (ARCHIVE_OK);
- }
- break;
- case 'c':
- if (strcmp(val, "char") == 0) {
- *parsed_kws |= MTREE_HAS_TYPE;
- archive_entry_set_filetype(entry,
- AE_IFCHR);
- return (ARCHIVE_OK);
- }
- break;
- case 'd':
- if (strcmp(val, "dir") == 0) {
- *parsed_kws |= MTREE_HAS_TYPE;
- archive_entry_set_filetype(entry,
- AE_IFDIR);
- return (ARCHIVE_OK);
- }
- break;
- case 'f':
- if (strcmp(val, "fifo") == 0) {
- *parsed_kws |= MTREE_HAS_TYPE;
- archive_entry_set_filetype(entry,
- AE_IFIFO);
- return (ARCHIVE_OK);
- }
- if (strcmp(val, "file") == 0) {
- *parsed_kws |= MTREE_HAS_TYPE;
- archive_entry_set_filetype(entry,
- AE_IFREG);
- return (ARCHIVE_OK);
- }
- break;
- case 'l':
- if (strcmp(val, "link") == 0) {
- *parsed_kws |= MTREE_HAS_TYPE;
- archive_entry_set_filetype(entry,
- AE_IFLNK);
- return (ARCHIVE_OK);
- }
- break;
- default:
- break;
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Unrecognized file type \"%s\"; "
- "assuming \"file\"", val);
- archive_entry_set_filetype(entry, AE_IFREG);
- return (ARCHIVE_WARN);
- }
- break;
- case 'u':
- if (strcmp(key, "uid") == 0) {
- *parsed_kws |= MTREE_HAS_UID;
- archive_entry_set_uid(entry, mtree_atol(&val, 10));
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "uname") == 0) {
- *parsed_kws |= MTREE_HAS_UNAME;
- archive_entry_copy_uname(entry, val);
- return (ARCHIVE_OK);
- }
- break;
- default:
- break;
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unrecognized key %s=%s", key, val);
- return (ARCHIVE_WARN);
-}
-
-static int
-read_data(struct archive_read *a, const void **buff, size_t *size,
- int64_t *offset)
-{
- size_t bytes_to_read;
- ssize_t bytes_read;
- struct mtree *mtree;
-
- mtree = (struct mtree *)(a->format->data);
- if (mtree->fd < 0) {
- *buff = NULL;
- *offset = 0;
- *size = 0;
- return (ARCHIVE_EOF);
- }
- if (mtree->buff == NULL) {
- mtree->buffsize = 64 * 1024;
- mtree->buff = malloc(mtree->buffsize);
- if (mtree->buff == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- }
-
- *buff = mtree->buff;
- *offset = mtree->offset;
- if ((int64_t)mtree->buffsize > mtree->cur_size - mtree->offset)
- bytes_to_read = (size_t)(mtree->cur_size - mtree->offset);
- else
- bytes_to_read = mtree->buffsize;
- bytes_read = read(mtree->fd, mtree->buff, bytes_to_read);
- if (bytes_read < 0) {
- archive_set_error(&a->archive, errno, "Can't read");
- return (ARCHIVE_WARN);
- }
- if (bytes_read == 0) {
- *size = 0;
- return (ARCHIVE_EOF);
- }
- mtree->offset += bytes_read;
- *size = bytes_read;
- return (ARCHIVE_OK);
-}
-
-/* Skip does nothing except possibly close the contents file. */
-static int
-skip(struct archive_read *a)
-{
- struct mtree *mtree;
-
- mtree = (struct mtree *)(a->format->data);
- if (mtree->fd >= 0) {
- close(mtree->fd);
- mtree->fd = -1;
- }
- return (ARCHIVE_OK);
-}
-
-/*
- * Since parsing backslash sequences always makes strings shorter,
- * we can always do this conversion in-place.
- */
-static void
-parse_escapes(char *src, struct mtree_entry *mentry)
-{
- char *dest = src;
- char c;
-
- if (mentry != NULL && strcmp(src, ".") == 0)
- mentry->full = 1;
-
- while (*src != '\0') {
- c = *src++;
- if (c == '/' && mentry != NULL)
- mentry->full = 1;
- if (c == '\\') {
- switch (src[0]) {
- case '0':
- if (src[1] < '0' || src[1] > '7') {
- c = 0;
- ++src;
- break;
- }
- /* FALLTHROUGH */
- case '1':
- case '2':
- case '3':
- if (src[1] >= '0' && src[1] <= '7' &&
- src[2] >= '0' && src[2] <= '7') {
- c = (src[0] - '0') << 6;
- c |= (src[1] - '0') << 3;
- c |= (src[2] - '0');
- src += 3;
- }
- break;
- case 'a':
- c = '\a';
- ++src;
- break;
- case 'b':
- c = '\b';
- ++src;
- break;
- case 'f':
- c = '\f';
- ++src;
- break;
- case 'n':
- c = '\n';
- ++src;
- break;
- case 'r':
- c = '\r';
- ++src;
- break;
- case 's':
- c = ' ';
- ++src;
- break;
- case 't':
- c = '\t';
- ++src;
- break;
- case 'v':
- c = '\v';
- ++src;
- break;
- case '\\':
- c = '\\';
- ++src;
- break;
- }
- }
- *dest++ = c;
- }
- *dest = '\0';
-}
-
-/* Parse a hex digit. */
-static int
-parsedigit(char c)
-{
- if (c >= '0' && c <= '9')
- return c - '0';
- else if (c >= 'a' && c <= 'f')
- return c - 'a';
- else if (c >= 'A' && c <= 'F')
- return c - 'A';
- else
- return -1;
-}
-
-/*
- * Note that this implementation does not (and should not!) obey
- * locale settings; you cannot simply substitute strtol here, since
- * it does obey locale.
- */
-static int64_t
-mtree_atol(char **p, int base)
-{
- int64_t l, limit;
- int digit, last_digit_limit;
-
- if (base == 0) {
- if (**p != '0')
- base = 10;
- else if ((*p)[1] == 'x' || (*p)[1] == 'X') {
- *p += 2;
- base = 16;
- } else {
- base = 8;
- }
- }
-
- if (**p == '-') {
- limit = INT64_MIN / base;
- last_digit_limit = -(INT64_MIN % base);
- ++(*p);
-
- l = 0;
- digit = parsedigit(**p);
- while (digit >= 0 && digit < base) {
- if (l < limit || (l == limit && digit >= last_digit_limit))
- return INT64_MIN;
- l = (l * base) - digit;
- digit = parsedigit(*++(*p));
- }
- return l;
- } else {
- limit = INT64_MAX / base;
- last_digit_limit = INT64_MAX % base;
-
- l = 0;
- digit = parsedigit(**p);
- while (digit >= 0 && digit < base) {
- if (l > limit || (l == limit && digit > last_digit_limit))
- return INT64_MAX;
- l = (l * base) + digit;
- digit = parsedigit(*++(*p));
- }
- return l;
- }
-}
-
-/*
- * Returns length of line (including trailing newline)
- * or negative on error. 'start' argument is updated to
- * point to first character of line.
- */
-static ssize_t
-readline(struct archive_read *a, struct mtree *mtree, char **start,
- ssize_t limit)
-{
- ssize_t bytes_read;
- ssize_t total_size = 0;
- ssize_t find_off = 0;
- const void *t;
- void *nl;
- char *u;
-
- /* Accumulate line in a line buffer. */
- for (;;) {
- /* Read some more. */
- t = __archive_read_ahead(a, 1, &bytes_read);
- if (t == NULL)
- return (0);
- if (bytes_read < 0)
- return (ARCHIVE_FATAL);
- nl = memchr(t, '\n', bytes_read);
- /* If we found '\n', trim the read to end exactly there. */
- if (nl != NULL) {
- bytes_read = ((const char *)nl) - ((const char *)t) + 1;
- }
- if (total_size + bytes_read + 1 > limit) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Line too long");
- return (ARCHIVE_FATAL);
- }
- if (archive_string_ensure(&mtree->line,
- total_size + bytes_read + 1) == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate working buffer");
- return (ARCHIVE_FATAL);
- }
- /* Append new bytes to string. */
- memcpy(mtree->line.s + total_size, t, bytes_read);
- __archive_read_consume(a, bytes_read);
- total_size += bytes_read;
- mtree->line.s[total_size] = '\0';
-
- for (u = mtree->line.s + find_off; *u; ++u) {
- if (u[0] == '\n') {
- /* Ends with unescaped newline. */
- *start = mtree->line.s;
- return total_size;
- } else if (u[0] == '#') {
- /* Ends with comment sequence #...\n */
- if (nl == NULL) {
- /* But we've not found the \n yet */
- break;
- }
- } else if (u[0] == '\\') {
- if (u[1] == '\n') {
- /* Trim escaped newline. */
- total_size -= 2;
- mtree->line.s[total_size] = '\0';
- break;
- } else if (u[1] != '\0') {
- /* Skip the two-char escape sequence */
- ++u;
- }
- }
- }
- find_off = u - mtree->line.s;
- }
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_format_rar.c b/contrib/libs/libarchive/libarchive/archive_read_support_format_rar.c
deleted file mode 100644
index 6452f5b5d6..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_format_rar.c
+++ /dev/null
@@ -1,3788 +0,0 @@
-/*-
-* Copyright (c) 2003-2007 Tim Kientzle
-* Copyright (c) 2011 Andres Mejia
-* 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(S) ``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(S) 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 "archive_platform.h"
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <time.h>
-#include <limits.h>
-#ifdef HAVE_ZLIB_H
-#include <zlib.h> /* crc32 */
-#endif
-
-#include "archive.h"
-#ifndef HAVE_ZLIB_H
-#error #include "archive_crc32.h"
-#endif
-#include "archive_endian.h"
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_ppmd7_private.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-/* RAR signature, also known as the mark header */
-#define RAR_SIGNATURE "\x52\x61\x72\x21\x1A\x07\x00"
-
-/* Header types */
-#define MARK_HEAD 0x72
-#define MAIN_HEAD 0x73
-#define FILE_HEAD 0x74
-#define COMM_HEAD 0x75
-#define AV_HEAD 0x76
-#define SUB_HEAD 0x77
-#define PROTECT_HEAD 0x78
-#define SIGN_HEAD 0x79
-#define NEWSUB_HEAD 0x7a
-#define ENDARC_HEAD 0x7b
-
-/* Main Header Flags */
-#define MHD_VOLUME 0x0001
-#define MHD_COMMENT 0x0002
-#define MHD_LOCK 0x0004
-#define MHD_SOLID 0x0008
-#define MHD_NEWNUMBERING 0x0010
-#define MHD_AV 0x0020
-#define MHD_PROTECT 0x0040
-#define MHD_PASSWORD 0x0080
-#define MHD_FIRSTVOLUME 0x0100
-#define MHD_ENCRYPTVER 0x0200
-
-/* Flags common to all headers */
-#define HD_MARKDELETION 0x4000
-#define HD_ADD_SIZE_PRESENT 0x8000
-
-/* File Header Flags */
-#define FHD_SPLIT_BEFORE 0x0001
-#define FHD_SPLIT_AFTER 0x0002
-#define FHD_PASSWORD 0x0004
-#define FHD_COMMENT 0x0008
-#define FHD_SOLID 0x0010
-#define FHD_LARGE 0x0100
-#define FHD_UNICODE 0x0200
-#define FHD_SALT 0x0400
-#define FHD_VERSION 0x0800
-#define FHD_EXTTIME 0x1000
-#define FHD_EXTFLAGS 0x2000
-
-/* File dictionary sizes */
-#define DICTIONARY_SIZE_64 0x00
-#define DICTIONARY_SIZE_128 0x20
-#define DICTIONARY_SIZE_256 0x40
-#define DICTIONARY_SIZE_512 0x60
-#define DICTIONARY_SIZE_1024 0x80
-#define DICTIONARY_SIZE_2048 0xA0
-#define DICTIONARY_SIZE_4096 0xC0
-#define FILE_IS_DIRECTORY 0xE0
-#define DICTIONARY_MASK FILE_IS_DIRECTORY
-
-/* OS Flags */
-#define OS_MSDOS 0
-#define OS_OS2 1
-#define OS_WIN32 2
-#define OS_UNIX 3
-#define OS_MAC_OS 4
-#define OS_BEOS 5
-
-/* Compression Methods */
-#define COMPRESS_METHOD_STORE 0x30
-/* LZSS */
-#define COMPRESS_METHOD_FASTEST 0x31
-#define COMPRESS_METHOD_FAST 0x32
-#define COMPRESS_METHOD_NORMAL 0x33
-/* PPMd Variant H */
-#define COMPRESS_METHOD_GOOD 0x34
-#define COMPRESS_METHOD_BEST 0x35
-
-#define CRC_POLYNOMIAL 0xEDB88320
-
-#define NS_UNIT 10000000
-
-#define DICTIONARY_MAX_SIZE 0x400000
-
-#define MAINCODE_SIZE 299
-#define OFFSETCODE_SIZE 60
-#define LOWOFFSETCODE_SIZE 17
-#define LENGTHCODE_SIZE 28
-#define HUFFMAN_TABLE_SIZE \
- MAINCODE_SIZE + OFFSETCODE_SIZE + LOWOFFSETCODE_SIZE + LENGTHCODE_SIZE
-
-#define MAX_SYMBOL_LENGTH 0xF
-#define MAX_SYMBOLS 20
-
-/* Virtual Machine Properties */
-#define VM_MEMORY_SIZE 0x40000
-#define VM_MEMORY_MASK (VM_MEMORY_SIZE - 1)
-#define PROGRAM_WORK_SIZE 0x3C000
-#define PROGRAM_GLOBAL_SIZE 0x2000
-#define PROGRAM_SYSTEM_GLOBAL_ADDRESS PROGRAM_WORK_SIZE
-#define PROGRAM_SYSTEM_GLOBAL_SIZE 0x40
-#define PROGRAM_USER_GLOBAL_ADDRESS (PROGRAM_SYSTEM_GLOBAL_ADDRESS + PROGRAM_SYSTEM_GLOBAL_SIZE)
-#define PROGRAM_USER_GLOBAL_SIZE (PROGRAM_GLOBAL_SIZE - PROGRAM_SYSTEM_GLOBAL_SIZE)
-
-/*
- * Considering L1,L2 cache miss and a calling of write system-call,
- * the best size of the output buffer(uncompressed buffer) is 128K.
- * If the structure of extracting process is changed, this value
- * might be researched again.
- */
-#define UNP_BUFFER_SIZE (128 * 1024)
-
-/* Define this here for non-Windows platforms */
-#if !((defined(__WIN32__) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__))
-#define FILE_ATTRIBUTE_DIRECTORY 0x10
-#endif
-
-#undef minimum
-#define minimum(a, b) ((a)<(b)?(a):(b))
-
-/* Stack overflow check */
-#define MAX_COMPRESS_DEPTH 1024
-
-/* Fields common to all headers */
-struct rar_header
-{
- char crc[2];
- char type;
- char flags[2];
- char size[2];
-};
-
-/* Fields common to all file headers */
-struct rar_file_header
-{
- char pack_size[4];
- char unp_size[4];
- char host_os;
- char file_crc[4];
- char file_time[4];
- char unp_ver;
- char method;
- char name_size[2];
- char file_attr[4];
-};
-
-struct huffman_tree_node
-{
- int branches[2];
-};
-
-struct huffman_table_entry
-{
- unsigned int length;
- int value;
-};
-
-struct huffman_code
-{
- struct huffman_tree_node *tree;
- int numentries;
- int numallocatedentries;
- int minlength;
- int maxlength;
- int tablesize;
- struct huffman_table_entry *table;
-};
-
-struct lzss
-{
- unsigned char *window;
- int mask;
- int64_t position;
-};
-
-struct data_block_offsets
-{
- int64_t header_size;
- int64_t start_offset;
- int64_t end_offset;
-};
-
-struct rar_program_code
-{
- uint8_t *staticdata;
- uint32_t staticdatalen;
- uint8_t *globalbackup;
- uint32_t globalbackuplen;
- uint64_t fingerprint;
- uint32_t usagecount;
- uint32_t oldfilterlength;
- struct rar_program_code *next;
-};
-
-struct rar_filter
-{
- struct rar_program_code *prog;
- uint32_t initialregisters[8];
- uint8_t *globaldata;
- uint32_t globaldatalen;
- size_t blockstartpos;
- uint32_t blocklength;
- uint32_t filteredblockaddress;
- uint32_t filteredblocklength;
- struct rar_filter *next;
-};
-
-struct memory_bit_reader
-{
- const uint8_t *bytes;
- size_t length;
- size_t offset;
- uint64_t bits;
- int available;
- int at_eof;
-};
-
-struct rar_virtual_machine
-{
- uint32_t registers[8];
- uint8_t memory[VM_MEMORY_SIZE + sizeof(uint32_t)];
-};
-
-struct rar_filters
-{
- struct rar_virtual_machine *vm;
- struct rar_program_code *progs;
- struct rar_filter *stack;
- int64_t filterstart;
- uint32_t lastfilternum;
- int64_t lastend;
- uint8_t *bytes;
- size_t bytes_ready;
-};
-
-struct audio_state
-{
- int8_t weight[5];
- int16_t delta[4];
- int8_t lastdelta;
- int error[11];
- int count;
- uint8_t lastbyte;
-};
-
-struct rar
-{
- /* Entries from main RAR header */
- unsigned main_flags;
- unsigned long file_crc;
- char reserved1[2];
- char reserved2[4];
- char encryptver;
-
- /* File header entries */
- char compression_method;
- unsigned file_flags;
- int64_t packed_size;
- int64_t unp_size;
- time_t mtime;
- long mnsec;
- mode_t mode;
- char *filename;
- char *filename_save;
- size_t filename_save_size;
- size_t filename_allocated;
-
- /* File header optional entries */
- char salt[8];
- time_t atime;
- long ansec;
- time_t ctime;
- long cnsec;
- time_t arctime;
- long arcnsec;
-
- /* Fields to help with tracking decompression of files. */
- int64_t bytes_unconsumed;
- int64_t bytes_remaining;
- int64_t bytes_uncopied;
- int64_t offset;
- int64_t offset_outgoing;
- int64_t offset_seek;
- char valid;
- unsigned int unp_offset;
- unsigned int unp_buffer_size;
- unsigned char *unp_buffer;
- unsigned int dictionary_size;
- char start_new_block;
- char entry_eof;
- unsigned long crc_calculated;
- int found_first_header;
- char has_endarc_header;
- struct data_block_offsets *dbo;
- unsigned int cursor;
- unsigned int nodes;
- char filename_must_match;
-
- /* LZSS members */
- struct huffman_code maincode;
- struct huffman_code offsetcode;
- struct huffman_code lowoffsetcode;
- struct huffman_code lengthcode;
- unsigned char lengthtable[HUFFMAN_TABLE_SIZE];
- struct lzss lzss;
- unsigned int lastlength;
- unsigned int lastoffset;
- unsigned int oldoffset[4];
- unsigned int lastlowoffset;
- unsigned int numlowoffsetrepeats;
- char start_new_table;
-
- /* Filters */
- struct rar_filters filters;
-
- /* PPMd Variant H members */
- char ppmd_valid;
- char ppmd_eod;
- char is_ppmd_block;
- int ppmd_escape;
- CPpmd7 ppmd7_context;
- CPpmd7z_RangeDec range_dec;
- IByteIn bytein;
-
- /*
- * String conversion object.
- */
- int init_default_conversion;
- struct archive_string_conv *sconv_default;
- struct archive_string_conv *opt_sconv;
- struct archive_string_conv *sconv_utf8;
- struct archive_string_conv *sconv_utf16be;
-
- /*
- * Bit stream reader.
- */
- struct rar_br {
-#define CACHE_TYPE uint64_t
-#define CACHE_BITS (8 * sizeof(CACHE_TYPE))
- /* Cache buffer. */
- CACHE_TYPE cache_buffer;
- /* Indicates how many bits avail in cache_buffer. */
- int cache_avail;
- ssize_t avail_in;
- const unsigned char *next_in;
- } br;
-
- /*
- * Custom field to denote that this archive contains encrypted entries
- */
- int has_encrypted_entries;
-};
-
-static int archive_read_support_format_rar_capabilities(struct archive_read *);
-static int archive_read_format_rar_has_encrypted_entries(struct archive_read *);
-static int archive_read_format_rar_bid(struct archive_read *, int);
-static int archive_read_format_rar_options(struct archive_read *,
- const char *, const char *);
-static int archive_read_format_rar_read_header(struct archive_read *,
- struct archive_entry *);
-static int archive_read_format_rar_read_data(struct archive_read *,
- const void **, size_t *, int64_t *);
-static int archive_read_format_rar_read_data_skip(struct archive_read *a);
-static int64_t archive_read_format_rar_seek_data(struct archive_read *, int64_t,
- int);
-static int archive_read_format_rar_cleanup(struct archive_read *);
-
-/* Support functions */
-static int read_header(struct archive_read *, struct archive_entry *, char);
-static time_t get_time(int);
-static int read_exttime(const char *, struct rar *, const char *);
-static int read_symlink_stored(struct archive_read *, struct archive_entry *,
- struct archive_string_conv *);
-static int read_data_stored(struct archive_read *, const void **, size_t *,
- int64_t *);
-static int read_data_compressed(struct archive_read *, const void **, size_t *,
- int64_t *, size_t);
-static int rar_br_preparation(struct archive_read *, struct rar_br *);
-static int parse_codes(struct archive_read *);
-static void free_codes(struct archive_read *);
-static int read_next_symbol(struct archive_read *, struct huffman_code *);
-static int create_code(struct archive_read *, struct huffman_code *,
- unsigned char *, int, char);
-static int add_value(struct archive_read *, struct huffman_code *, int, int,
- int);
-static int new_node(struct huffman_code *);
-static int make_table(struct archive_read *, struct huffman_code *);
-static int make_table_recurse(struct archive_read *, struct huffman_code *, int,
- struct huffman_table_entry *, int, int);
-static int expand(struct archive_read *, int64_t *);
-static int copy_from_lzss_window_to_unp(struct archive_read *, const void **,
- int64_t, int);
-static const void *rar_read_ahead(struct archive_read *, size_t, ssize_t *);
-static int parse_filter(struct archive_read *, const uint8_t *, uint16_t,
- uint8_t);
-static int run_filters(struct archive_read *);
-static void clear_filters(struct rar_filters *);
-static struct rar_filter *create_filter(struct rar_program_code *,
- const uint8_t *, uint32_t,
- uint32_t[8], size_t, uint32_t);
-static void delete_filter(struct rar_filter *filter);
-static struct rar_program_code *compile_program(const uint8_t *, size_t);
-static void delete_program_code(struct rar_program_code *prog);
-static uint32_t membr_next_rarvm_number(struct memory_bit_reader *br);
-static inline uint32_t membr_bits(struct memory_bit_reader *br, int bits);
-static int membr_fill(struct memory_bit_reader *br, int bits);
-static int read_filter(struct archive_read *, int64_t *);
-static int rar_decode_byte(struct archive_read*, uint8_t *);
-static int execute_filter(struct archive_read*, struct rar_filter *,
- struct rar_virtual_machine *, size_t);
-static int copy_from_lzss_window(struct archive_read *, void *, int64_t, int);
-static inline void vm_write_32(struct rar_virtual_machine*, size_t, uint32_t);
-static inline uint32_t vm_read_32(struct rar_virtual_machine*, size_t);
-
-/*
- * Bit stream reader.
- */
-/* Check that the cache buffer has enough bits. */
-#define rar_br_has(br, n) ((br)->cache_avail >= n)
-/* Get compressed data by bit. */
-#define rar_br_bits(br, n) \
- (((uint32_t)((br)->cache_buffer >> \
- ((br)->cache_avail - (n)))) & cache_masks[n])
-#define rar_br_bits_forced(br, n) \
- (((uint32_t)((br)->cache_buffer << \
- ((n) - (br)->cache_avail))) & cache_masks[n])
-/* Read ahead to make sure the cache buffer has enough compressed data we
- * will use.
- * True : completed, there is enough data in the cache buffer.
- * False : there is no data in the stream. */
-#define rar_br_read_ahead(a, br, n) \
- ((rar_br_has(br, (n)) || rar_br_fillup(a, br)) || rar_br_has(br, (n)))
-/* Notify how many bits we consumed. */
-#define rar_br_consume(br, n) ((br)->cache_avail -= (n))
-#define rar_br_consume_unalined_bits(br) ((br)->cache_avail &= ~7)
-
-static const uint32_t cache_masks[] = {
- 0x00000000, 0x00000001, 0x00000003, 0x00000007,
- 0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F,
- 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF,
- 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF,
- 0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF,
- 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF,
- 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF,
- 0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
-};
-
-/*
- * Shift away used bits in the cache data and fill it up with following bits.
- * Call this when cache buffer does not have enough bits you need.
- *
- * Returns 1 if the cache buffer is full.
- * Returns 0 if the cache buffer is not full; input buffer is empty.
- */
-static int
-rar_br_fillup(struct archive_read *a, struct rar_br *br)
-{
- struct rar *rar = (struct rar *)(a->format->data);
- int n = CACHE_BITS - br->cache_avail;
-
- for (;;) {
- switch (n >> 3) {
- case 8:
- if (br->avail_in >= 8) {
- br->cache_buffer =
- ((uint64_t)br->next_in[0]) << 56 |
- ((uint64_t)br->next_in[1]) << 48 |
- ((uint64_t)br->next_in[2]) << 40 |
- ((uint64_t)br->next_in[3]) << 32 |
- ((uint32_t)br->next_in[4]) << 24 |
- ((uint32_t)br->next_in[5]) << 16 |
- ((uint32_t)br->next_in[6]) << 8 |
- (uint32_t)br->next_in[7];
- br->next_in += 8;
- br->avail_in -= 8;
- br->cache_avail += 8 * 8;
- rar->bytes_unconsumed += 8;
- rar->bytes_remaining -= 8;
- return (1);
- }
- break;
- case 7:
- if (br->avail_in >= 7) {
- br->cache_buffer =
- (br->cache_buffer << 56) |
- ((uint64_t)br->next_in[0]) << 48 |
- ((uint64_t)br->next_in[1]) << 40 |
- ((uint64_t)br->next_in[2]) << 32 |
- ((uint32_t)br->next_in[3]) << 24 |
- ((uint32_t)br->next_in[4]) << 16 |
- ((uint32_t)br->next_in[5]) << 8 |
- (uint32_t)br->next_in[6];
- br->next_in += 7;
- br->avail_in -= 7;
- br->cache_avail += 7 * 8;
- rar->bytes_unconsumed += 7;
- rar->bytes_remaining -= 7;
- return (1);
- }
- break;
- case 6:
- if (br->avail_in >= 6) {
- br->cache_buffer =
- (br->cache_buffer << 48) |
- ((uint64_t)br->next_in[0]) << 40 |
- ((uint64_t)br->next_in[1]) << 32 |
- ((uint32_t)br->next_in[2]) << 24 |
- ((uint32_t)br->next_in[3]) << 16 |
- ((uint32_t)br->next_in[4]) << 8 |
- (uint32_t)br->next_in[5];
- br->next_in += 6;
- br->avail_in -= 6;
- br->cache_avail += 6 * 8;
- rar->bytes_unconsumed += 6;
- rar->bytes_remaining -= 6;
- return (1);
- }
- break;
- case 0:
- /* We have enough compressed data in
- * the cache buffer.*/
- return (1);
- default:
- break;
- }
- if (br->avail_in <= 0) {
-
- if (rar->bytes_unconsumed > 0) {
- /* Consume as much as the decompressor
- * actually used. */
- __archive_read_consume(a, rar->bytes_unconsumed);
- rar->bytes_unconsumed = 0;
- }
- br->next_in = rar_read_ahead(a, 1, &(br->avail_in));
- if (br->next_in == NULL)
- return (0);
- if (br->avail_in == 0)
- return (0);
- }
- br->cache_buffer =
- (br->cache_buffer << 8) | *br->next_in++;
- br->avail_in--;
- br->cache_avail += 8;
- n -= 8;
- rar->bytes_unconsumed++;
- rar->bytes_remaining--;
- }
-}
-
-static int
-rar_br_preparation(struct archive_read *a, struct rar_br *br)
-{
- struct rar *rar = (struct rar *)(a->format->data);
-
- if (rar->bytes_remaining > 0) {
- br->next_in = rar_read_ahead(a, 1, &(br->avail_in));
- if (br->next_in == NULL) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated RAR file data");
- return (ARCHIVE_FATAL);
- }
- if (br->cache_avail == 0)
- (void)rar_br_fillup(a, br);
- }
- return (ARCHIVE_OK);
-}
-
-/* Find last bit set */
-static inline int
-rar_fls(unsigned int word)
-{
- word |= (word >> 1);
- word |= (word >> 2);
- word |= (word >> 4);
- word |= (word >> 8);
- word |= (word >> 16);
- return word - (word >> 1);
-}
-
-/* LZSS functions */
-static inline int64_t
-lzss_position(struct lzss *lzss)
-{
- return lzss->position;
-}
-
-static inline int
-lzss_mask(struct lzss *lzss)
-{
- return lzss->mask;
-}
-
-static inline int
-lzss_size(struct lzss *lzss)
-{
- return lzss->mask + 1;
-}
-
-static inline int
-lzss_offset_for_position(struct lzss *lzss, int64_t pos)
-{
- return (int)(pos & lzss->mask);
-}
-
-static inline unsigned char *
-lzss_pointer_for_position(struct lzss *lzss, int64_t pos)
-{
- return &lzss->window[lzss_offset_for_position(lzss, pos)];
-}
-
-static inline int
-lzss_current_offset(struct lzss *lzss)
-{
- return lzss_offset_for_position(lzss, lzss->position);
-}
-
-static inline uint8_t *
-lzss_current_pointer(struct lzss *lzss)
-{
- return lzss_pointer_for_position(lzss, lzss->position);
-}
-
-static inline void
-lzss_emit_literal(struct rar *rar, uint8_t literal)
-{
- *lzss_current_pointer(&rar->lzss) = literal;
- rar->lzss.position++;
-}
-
-static inline void
-lzss_emit_match(struct rar *rar, int offset, int length)
-{
- int dstoffs = lzss_current_offset(&rar->lzss);
- int srcoffs = (dstoffs - offset) & lzss_mask(&rar->lzss);
- int l, li, remaining;
- unsigned char *d, *s;
-
- remaining = length;
- while (remaining > 0) {
- l = remaining;
- if (dstoffs > srcoffs) {
- if (l > lzss_size(&rar->lzss) - dstoffs)
- l = lzss_size(&rar->lzss) - dstoffs;
- } else {
- if (l > lzss_size(&rar->lzss) - srcoffs)
- l = lzss_size(&rar->lzss) - srcoffs;
- }
- d = &(rar->lzss.window[dstoffs]);
- s = &(rar->lzss.window[srcoffs]);
- if ((dstoffs + l < srcoffs) || (srcoffs + l < dstoffs))
- memcpy(d, s, l);
- else {
- for (li = 0; li < l; li++)
- d[li] = s[li];
- }
- remaining -= l;
- dstoffs = (dstoffs + l) & lzss_mask(&(rar->lzss));
- srcoffs = (srcoffs + l) & lzss_mask(&(rar->lzss));
- }
- rar->lzss.position += length;
-}
-
-static Byte
-ppmd_read(void *p)
-{
- struct archive_read *a = ((IByteIn*)p)->a;
- struct rar *rar = (struct rar *)(a->format->data);
- struct rar_br *br = &(rar->br);
- Byte b;
- if (!rar_br_read_ahead(a, br, 8))
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated RAR file data");
- rar->valid = 0;
- return 0;
- }
- b = rar_br_bits(br, 8);
- rar_br_consume(br, 8);
- return b;
-}
-
-int
-archive_read_support_format_rar(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- struct rar *rar;
- int r;
-
- archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
- "archive_read_support_format_rar");
-
- rar = (struct rar *)calloc(sizeof(*rar), 1);
- if (rar == NULL)
- {
- archive_set_error(&a->archive, ENOMEM, "Can't allocate rar data");
- return (ARCHIVE_FATAL);
- }
-
- /*
- * Until enough data has been read, we cannot tell about
- * any encrypted entries yet.
- */
- rar->has_encrypted_entries = ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
-
- r = __archive_read_register_format(a,
- rar,
- "rar",
- archive_read_format_rar_bid,
- archive_read_format_rar_options,
- archive_read_format_rar_read_header,
- archive_read_format_rar_read_data,
- archive_read_format_rar_read_data_skip,
- archive_read_format_rar_seek_data,
- archive_read_format_rar_cleanup,
- archive_read_support_format_rar_capabilities,
- archive_read_format_rar_has_encrypted_entries);
-
- if (r != ARCHIVE_OK)
- free(rar);
- return (r);
-}
-
-static int
-archive_read_support_format_rar_capabilities(struct archive_read * a)
-{
- (void)a; /* UNUSED */
- return (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA
- | ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA);
-}
-
-static int
-archive_read_format_rar_has_encrypted_entries(struct archive_read *_a)
-{
- if (_a && _a->format) {
- struct rar * rar = (struct rar *)_a->format->data;
- if (rar) {
- return rar->has_encrypted_entries;
- }
- }
- return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
-}
-
-
-static int
-archive_read_format_rar_bid(struct archive_read *a, int best_bid)
-{
- const char *p;
-
- /* If there's already a bid > 30, we'll never win. */
- if (best_bid > 30)
- return (-1);
-
- if ((p = __archive_read_ahead(a, 7, NULL)) == NULL)
- return (-1);
-
- if (memcmp(p, RAR_SIGNATURE, 7) == 0)
- return (30);
-
- if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) {
- /* This is a PE file */
- ssize_t offset = 0x10000;
- ssize_t window = 4096;
- ssize_t bytes_avail;
- while (offset + window <= (1024 * 128)) {
- const char *buff = __archive_read_ahead(a, offset + window, &bytes_avail);
- if (buff == NULL) {
- /* Remaining bytes are less than window. */
- window >>= 1;
- if (window < 0x40)
- return (0);
- continue;
- }
- p = buff + offset;
- while (p + 7 < buff + bytes_avail) {
- if (memcmp(p, RAR_SIGNATURE, 7) == 0)
- return (30);
- p += 0x10;
- }
- offset = p - buff;
- }
- }
- return (0);
-}
-
-static int
-skip_sfx(struct archive_read *a)
-{
- const void *h;
- const char *p, *q;
- size_t skip, total;
- ssize_t bytes, window;
-
- total = 0;
- window = 4096;
- while (total + window <= (1024 * 128)) {
- h = __archive_read_ahead(a, window, &bytes);
- if (h == NULL) {
- /* Remaining bytes are less than window. */
- window >>= 1;
- if (window < 0x40)
- goto fatal;
- continue;
- }
- if (bytes < 0x40)
- goto fatal;
- p = h;
- q = p + bytes;
-
- /*
- * Scan ahead until we find something that looks
- * like the RAR header.
- */
- while (p + 7 < q) {
- if (memcmp(p, RAR_SIGNATURE, 7) == 0) {
- skip = p - (const char *)h;
- __archive_read_consume(a, skip);
- return (ARCHIVE_OK);
- }
- p += 0x10;
- }
- skip = p - (const char *)h;
- __archive_read_consume(a, skip);
- total += skip;
- }
-fatal:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Couldn't find out RAR header");
- return (ARCHIVE_FATAL);
-}
-
-static int
-archive_read_format_rar_options(struct archive_read *a,
- const char *key, const char *val)
-{
- struct rar *rar;
- int ret = ARCHIVE_FAILED;
-
- rar = (struct rar *)(a->format->data);
- if (strcmp(key, "hdrcharset") == 0) {
- if (val == NULL || val[0] == 0)
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "rar: hdrcharset option needs a character-set name");
- else {
- rar->opt_sconv =
- archive_string_conversion_from_charset(
- &a->archive, val, 0);
- if (rar->opt_sconv != NULL)
- ret = ARCHIVE_OK;
- else
- ret = ARCHIVE_FATAL;
- }
- return (ret);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-static int
-archive_read_format_rar_read_header(struct archive_read *a,
- struct archive_entry *entry)
-{
- const void *h;
- const char *p;
- struct rar *rar;
- size_t skip;
- char head_type;
- int ret;
- unsigned flags;
- unsigned long crc32_expected;
-
- a->archive.archive_format = ARCHIVE_FORMAT_RAR;
- if (a->archive.archive_format_name == NULL)
- a->archive.archive_format_name = "RAR";
-
- rar = (struct rar *)(a->format->data);
-
- /*
- * It should be sufficient to call archive_read_next_header() for
- * a reader to determine if an entry is encrypted or not. If the
- * encryption of an entry is only detectable when calling
- * archive_read_data(), so be it. We'll do the same check there
- * as well.
- */
- if (rar->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
- rar->has_encrypted_entries = 0;
- }
-
- /* RAR files can be generated without EOF headers, so return ARCHIVE_EOF if
- * this fails.
- */
- if ((h = __archive_read_ahead(a, 7, NULL)) == NULL)
- return (ARCHIVE_EOF);
-
- p = h;
- if (rar->found_first_header == 0 &&
- ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0)) {
- /* This is an executable ? Must be self-extracting... */
- ret = skip_sfx(a);
- if (ret < ARCHIVE_WARN)
- return (ret);
- }
- rar->found_first_header = 1;
-
- while (1)
- {
- unsigned long crc32_val;
-
- if ((h = __archive_read_ahead(a, 7, NULL)) == NULL)
- return (ARCHIVE_FATAL);
- p = h;
-
- head_type = p[2];
- switch(head_type)
- {
- case MARK_HEAD:
- if (memcmp(p, RAR_SIGNATURE, 7) != 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid marker header");
- return (ARCHIVE_FATAL);
- }
- __archive_read_consume(a, 7);
- break;
-
- case MAIN_HEAD:
- rar->main_flags = archive_le16dec(p + 3);
- skip = archive_le16dec(p + 5);
- if (skip < 7 + sizeof(rar->reserved1) + sizeof(rar->reserved2)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid header size");
- return (ARCHIVE_FATAL);
- }
- if ((h = __archive_read_ahead(a, skip, NULL)) == NULL)
- return (ARCHIVE_FATAL);
- p = h;
- memcpy(rar->reserved1, p + 7, sizeof(rar->reserved1));
- memcpy(rar->reserved2, p + 7 + sizeof(rar->reserved1),
- sizeof(rar->reserved2));
- if (rar->main_flags & MHD_ENCRYPTVER) {
- if (skip < 7 + sizeof(rar->reserved1) + sizeof(rar->reserved2)+1) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid header size");
- return (ARCHIVE_FATAL);
- }
- rar->encryptver = *(p + 7 + sizeof(rar->reserved1) +
- sizeof(rar->reserved2));
- }
-
- /* Main header is password encrypted, so we cannot read any
- file names or any other info about files from the header. */
- if (rar->main_flags & MHD_PASSWORD)
- {
- archive_entry_set_is_metadata_encrypted(entry, 1);
- archive_entry_set_is_data_encrypted(entry, 1);
- rar->has_encrypted_entries = 1;
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "RAR encryption support unavailable.");
- return (ARCHIVE_FATAL);
- }
-
- crc32_val = crc32(0, (const unsigned char *)p + 2, (unsigned)skip - 2);
- if ((crc32_val & 0xffff) != archive_le16dec(p)) {
-#ifndef DONT_FAIL_ON_CRC_ERROR
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Header CRC error");
- return (ARCHIVE_FATAL);
-#endif
- }
- __archive_read_consume(a, skip);
- break;
-
- case FILE_HEAD:
- return read_header(a, entry, head_type);
-
- case COMM_HEAD:
- case AV_HEAD:
- case SUB_HEAD:
- case PROTECT_HEAD:
- case SIGN_HEAD:
- case ENDARC_HEAD:
- flags = archive_le16dec(p + 3);
- skip = archive_le16dec(p + 5);
- if (skip < 7) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid header size too small");
- return (ARCHIVE_FATAL);
- }
- if (flags & HD_ADD_SIZE_PRESENT)
- {
- if (skip < 7 + 4) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid header size too small");
- return (ARCHIVE_FATAL);
- }
- if ((h = __archive_read_ahead(a, skip, NULL)) == NULL)
- return (ARCHIVE_FATAL);
- p = h;
- skip += archive_le32dec(p + 7);
- }
-
- /* Skip over the 2-byte CRC at the beginning of the header. */
- crc32_expected = archive_le16dec(p);
- __archive_read_consume(a, 2);
- skip -= 2;
-
- /* Skim the entire header and compute the CRC. */
- crc32_val = 0;
- while (skip > 0) {
- size_t to_read = skip;
- if (to_read > 32 * 1024)
- to_read = 32 * 1024;
- if ((h = __archive_read_ahead(a, to_read, NULL)) == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Bad RAR file");
- return (ARCHIVE_FATAL);
- }
- p = h;
- crc32_val = crc32(crc32_val, (const unsigned char *)p, (unsigned int)to_read);
- __archive_read_consume(a, to_read);
- skip -= to_read;
- }
- if ((crc32_val & 0xffff) != crc32_expected) {
-#ifndef DONT_FAIL_ON_CRC_ERROR
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Header CRC error");
- return (ARCHIVE_FATAL);
-#endif
- }
- if (head_type == ENDARC_HEAD)
- return (ARCHIVE_EOF);
- break;
-
- case NEWSUB_HEAD:
- if ((ret = read_header(a, entry, head_type)) < ARCHIVE_WARN)
- return ret;
- break;
-
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Bad RAR file");
- return (ARCHIVE_FATAL);
- }
- }
-}
-
-static int
-archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
- size_t *size, int64_t *offset)
-{
- struct rar *rar = (struct rar *)(a->format->data);
- int ret;
-
- if (rar->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
- rar->has_encrypted_entries = 0;
- }
-
- if (rar->bytes_unconsumed > 0) {
- /* Consume as much as the decompressor actually used. */
- __archive_read_consume(a, rar->bytes_unconsumed);
- rar->bytes_unconsumed = 0;
- }
-
- *buff = NULL;
- if (rar->entry_eof || rar->offset_seek >= rar->unp_size) {
- *size = 0;
- *offset = rar->offset;
- if (*offset < rar->unp_size)
- *offset = rar->unp_size;
- return (ARCHIVE_EOF);
- }
-
- switch (rar->compression_method)
- {
- case COMPRESS_METHOD_STORE:
- ret = read_data_stored(a, buff, size, offset);
- break;
-
- case COMPRESS_METHOD_FASTEST:
- case COMPRESS_METHOD_FAST:
- case COMPRESS_METHOD_NORMAL:
- case COMPRESS_METHOD_GOOD:
- case COMPRESS_METHOD_BEST:
- ret = read_data_compressed(a, buff, size, offset, 0);
- if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN) {
- __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
- rar->start_new_table = 1;
- rar->ppmd_valid = 0;
- }
- break;
-
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unsupported compression method for RAR file.");
- ret = ARCHIVE_FATAL;
- break;
- }
- return (ret);
-}
-
-static int
-archive_read_format_rar_read_data_skip(struct archive_read *a)
-{
- struct rar *rar;
- int64_t bytes_skipped;
- int ret;
-
- rar = (struct rar *)(a->format->data);
-
- if (rar->bytes_unconsumed > 0) {
- /* Consume as much as the decompressor actually used. */
- __archive_read_consume(a, rar->bytes_unconsumed);
- rar->bytes_unconsumed = 0;
- }
-
- if (rar->bytes_remaining > 0) {
- bytes_skipped = __archive_read_consume(a, rar->bytes_remaining);
- if (bytes_skipped < 0)
- return (ARCHIVE_FATAL);
- }
-
- /* Compressed data to skip must be read from each header in a multivolume
- * archive.
- */
- if (rar->main_flags & MHD_VOLUME && rar->file_flags & FHD_SPLIT_AFTER)
- {
- ret = archive_read_format_rar_read_header(a, a->entry);
- if (ret == (ARCHIVE_EOF))
- ret = archive_read_format_rar_read_header(a, a->entry);
- if (ret != (ARCHIVE_OK))
- return ret;
- return archive_read_format_rar_read_data_skip(a);
- }
-
- return (ARCHIVE_OK);
-}
-
-static int64_t
-archive_read_format_rar_seek_data(struct archive_read *a, int64_t offset,
- int whence)
-{
- int64_t client_offset, ret;
- unsigned int i;
- struct rar *rar = (struct rar *)(a->format->data);
-
- if (rar->compression_method == COMPRESS_METHOD_STORE)
- {
- /* Modify the offset for use with SEEK_SET */
- switch (whence)
- {
- case SEEK_CUR:
- client_offset = rar->offset_seek;
- break;
- case SEEK_END:
- client_offset = rar->unp_size;
- break;
- case SEEK_SET:
- default:
- client_offset = 0;
- }
- client_offset += offset;
- if (client_offset < 0)
- {
- /* Can't seek past beginning of data block */
- return -1;
- }
- else if (client_offset > rar->unp_size)
- {
- /*
- * Set the returned offset but only seek to the end of
- * the data block.
- */
- rar->offset_seek = client_offset;
- client_offset = rar->unp_size;
- }
-
- client_offset += rar->dbo[0].start_offset;
- i = 0;
- while (i < rar->cursor)
- {
- i++;
- client_offset += rar->dbo[i].start_offset - rar->dbo[i-1].end_offset;
- }
- if (rar->main_flags & MHD_VOLUME)
- {
- /* Find the appropriate offset among the multivolume archive */
- while (1)
- {
- if (client_offset < rar->dbo[rar->cursor].start_offset &&
- rar->file_flags & FHD_SPLIT_BEFORE)
- {
- /* Search backwards for the correct data block */
- if (rar->cursor == 0)
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Attempt to seek past beginning of RAR data block");
- return (ARCHIVE_FAILED);
- }
- rar->cursor--;
- client_offset -= rar->dbo[rar->cursor+1].start_offset -
- rar->dbo[rar->cursor].end_offset;
- if (client_offset < rar->dbo[rar->cursor].start_offset)
- continue;
- ret = __archive_read_seek(a, rar->dbo[rar->cursor].start_offset -
- rar->dbo[rar->cursor].header_size, SEEK_SET);
- if (ret < (ARCHIVE_OK))
- return ret;
- ret = archive_read_format_rar_read_header(a, a->entry);
- if (ret != (ARCHIVE_OK))
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Error during seek of RAR file");
- return (ARCHIVE_FAILED);
- }
- rar->cursor--;
- break;
- }
- else if (client_offset > rar->dbo[rar->cursor].end_offset &&
- rar->file_flags & FHD_SPLIT_AFTER)
- {
- /* Search forward for the correct data block */
- rar->cursor++;
- if (rar->cursor < rar->nodes &&
- client_offset > rar->dbo[rar->cursor].end_offset)
- {
- client_offset += rar->dbo[rar->cursor].start_offset -
- rar->dbo[rar->cursor-1].end_offset;
- continue;
- }
- rar->cursor--;
- ret = __archive_read_seek(a, rar->dbo[rar->cursor].end_offset,
- SEEK_SET);
- if (ret < (ARCHIVE_OK))
- return ret;
- ret = archive_read_format_rar_read_header(a, a->entry);
- if (ret == (ARCHIVE_EOF))
- {
- rar->has_endarc_header = 1;
- ret = archive_read_format_rar_read_header(a, a->entry);
- }
- if (ret != (ARCHIVE_OK))
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Error during seek of RAR file");
- return (ARCHIVE_FAILED);
- }
- client_offset += rar->dbo[rar->cursor].start_offset -
- rar->dbo[rar->cursor-1].end_offset;
- continue;
- }
- break;
- }
- }
-
- ret = __archive_read_seek(a, client_offset, SEEK_SET);
- if (ret < (ARCHIVE_OK))
- return ret;
- rar->bytes_remaining = rar->dbo[rar->cursor].end_offset - ret;
- i = rar->cursor;
- while (i > 0)
- {
- i--;
- ret -= rar->dbo[i+1].start_offset - rar->dbo[i].end_offset;
- }
- ret -= rar->dbo[0].start_offset;
-
- /* Always restart reading the file after a seek */
- __archive_reset_read_data(&a->archive);
-
- rar->bytes_unconsumed = 0;
- rar->offset = 0;
-
- /*
- * If a seek past the end of file was requested, return the requested
- * offset.
- */
- if (ret == rar->unp_size && rar->offset_seek > rar->unp_size)
- return rar->offset_seek;
-
- /* Return the new offset */
- rar->offset_seek = ret;
- return rar->offset_seek;
- }
- else
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Seeking of compressed RAR files is unsupported");
- }
- return (ARCHIVE_FAILED);
-}
-
-static int
-archive_read_format_rar_cleanup(struct archive_read *a)
-{
- struct rar *rar;
-
- rar = (struct rar *)(a->format->data);
- free_codes(a);
- clear_filters(&rar->filters);
- free(rar->filename);
- free(rar->filename_save);
- free(rar->dbo);
- free(rar->unp_buffer);
- free(rar->lzss.window);
- __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
- free(rar);
- (a->format->data) = NULL;
- return (ARCHIVE_OK);
-}
-
-static int
-read_header(struct archive_read *a, struct archive_entry *entry,
- char head_type)
-{
- const void *h;
- const char *p, *endp;
- struct rar *rar;
- struct rar_header rar_header;
- struct rar_file_header file_header;
- int64_t header_size;
- unsigned filename_size, end;
- char *filename;
- char *strp;
- char packed_size[8];
- char unp_size[8];
- int ttime;
- struct archive_string_conv *sconv, *fn_sconv;
- unsigned long crc32_val;
- int ret = (ARCHIVE_OK), ret2;
-
- rar = (struct rar *)(a->format->data);
-
- /* Setup a string conversion object for non-rar-unicode filenames. */
- sconv = rar->opt_sconv;
- if (sconv == NULL) {
- if (!rar->init_default_conversion) {
- rar->sconv_default =
- archive_string_default_conversion_for_read(
- &(a->archive));
- rar->init_default_conversion = 1;
- }
- sconv = rar->sconv_default;
- }
-
-
- if ((h = __archive_read_ahead(a, 7, NULL)) == NULL)
- return (ARCHIVE_FATAL);
- p = h;
- memcpy(&rar_header, p, sizeof(rar_header));
- rar->file_flags = archive_le16dec(rar_header.flags);
- header_size = archive_le16dec(rar_header.size);
- if (header_size < (int64_t)sizeof(file_header) + 7) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid header size");
- return (ARCHIVE_FATAL);
- }
- crc32_val = crc32(0, (const unsigned char *)p + 2, 7 - 2);
- __archive_read_consume(a, 7);
-
- if (!(rar->file_flags & FHD_SOLID))
- {
- rar->compression_method = 0;
- rar->packed_size = 0;
- rar->unp_size = 0;
- rar->mtime = 0;
- rar->ctime = 0;
- rar->atime = 0;
- rar->arctime = 0;
- rar->mode = 0;
- memset(&rar->salt, 0, sizeof(rar->salt));
- rar->atime = 0;
- rar->ansec = 0;
- rar->ctime = 0;
- rar->cnsec = 0;
- rar->mtime = 0;
- rar->mnsec = 0;
- rar->arctime = 0;
- rar->arcnsec = 0;
- }
- else
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "RAR solid archive support unavailable.");
- return (ARCHIVE_FATAL);
- }
-
- if ((h = __archive_read_ahead(a, (size_t)header_size - 7, NULL)) == NULL)
- return (ARCHIVE_FATAL);
-
- /* File Header CRC check. */
- crc32_val = crc32(crc32_val, h, (unsigned)(header_size - 7));
- if ((crc32_val & 0xffff) != archive_le16dec(rar_header.crc)) {
-#ifndef DONT_FAIL_ON_CRC_ERROR
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Header CRC error");
- return (ARCHIVE_FATAL);
-#endif
- }
- /* If no CRC error, Go on parsing File Header. */
- p = h;
- endp = p + header_size - 7;
- memcpy(&file_header, p, sizeof(file_header));
- p += sizeof(file_header);
-
- rar->compression_method = file_header.method;
-
- ttime = archive_le32dec(file_header.file_time);
- rar->mtime = get_time(ttime);
-
- rar->file_crc = archive_le32dec(file_header.file_crc);
-
- if (rar->file_flags & FHD_PASSWORD)
- {
- archive_entry_set_is_data_encrypted(entry, 1);
- rar->has_encrypted_entries = 1;
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "RAR encryption support unavailable.");
- /* Since it is only the data part itself that is encrypted we can at least
- extract information about the currently processed entry and don't need
- to return ARCHIVE_FATAL here. */
- /*return (ARCHIVE_FATAL);*/
- }
-
- if (rar->file_flags & FHD_LARGE)
- {
- memcpy(packed_size, file_header.pack_size, 4);
- memcpy(packed_size + 4, p, 4); /* High pack size */
- p += 4;
- memcpy(unp_size, file_header.unp_size, 4);
- memcpy(unp_size + 4, p, 4); /* High unpack size */
- p += 4;
- rar->packed_size = archive_le64dec(&packed_size);
- rar->unp_size = archive_le64dec(&unp_size);
- }
- else
- {
- rar->packed_size = archive_le32dec(file_header.pack_size);
- rar->unp_size = archive_le32dec(file_header.unp_size);
- }
-
- if (rar->packed_size < 0 || rar->unp_size < 0)
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid sizes specified.");
- return (ARCHIVE_FATAL);
- }
-
- rar->bytes_remaining = rar->packed_size;
-
- /* TODO: RARv3 subblocks contain comments. For now the complete block is
- * consumed at the end.
- */
- if (head_type == NEWSUB_HEAD) {
- size_t distance = p - (const char *)h;
- header_size += rar->packed_size;
- /* Make sure we have the extended data. */
- if ((h = __archive_read_ahead(a, (size_t)header_size - 7, NULL)) == NULL)
- return (ARCHIVE_FATAL);
- p = h;
- endp = p + header_size - 7;
- p += distance;
- }
-
- filename_size = archive_le16dec(file_header.name_size);
- if (p + filename_size > endp) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid filename size");
- return (ARCHIVE_FATAL);
- }
- if (rar->filename_allocated < filename_size * 2 + 2) {
- char *newptr;
- size_t newsize = filename_size * 2 + 2;
- newptr = realloc(rar->filename, newsize);
- if (newptr == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Couldn't allocate memory.");
- return (ARCHIVE_FATAL);
- }
- rar->filename = newptr;
- rar->filename_allocated = newsize;
- }
- filename = rar->filename;
- memcpy(filename, p, filename_size);
- filename[filename_size] = '\0';
- if (rar->file_flags & FHD_UNICODE)
- {
- if (filename_size != strlen(filename))
- {
- unsigned char highbyte, flagbits, flagbyte;
- unsigned fn_end, offset;
-
- end = filename_size;
- fn_end = filename_size * 2;
- filename_size = 0;
- offset = (unsigned)strlen(filename) + 1;
- highbyte = *(p + offset++);
- flagbits = 0;
- flagbyte = 0;
- while (offset < end && filename_size < fn_end)
- {
- if (!flagbits)
- {
- flagbyte = *(p + offset++);
- flagbits = 8;
- }
-
- flagbits -= 2;
- switch((flagbyte >> flagbits) & 3)
- {
- case 0:
- filename[filename_size++] = '\0';
- filename[filename_size++] = *(p + offset++);
- break;
- case 1:
- filename[filename_size++] = highbyte;
- filename[filename_size++] = *(p + offset++);
- break;
- case 2:
- filename[filename_size++] = *(p + offset + 1);
- filename[filename_size++] = *(p + offset);
- offset += 2;
- break;
- case 3:
- {
- char extra, high;
- uint8_t length = *(p + offset++);
-
- if (length & 0x80) {
- extra = *(p + offset++);
- high = (char)highbyte;
- } else
- extra = high = 0;
- length = (length & 0x7f) + 2;
- while (length && filename_size < fn_end) {
- unsigned cp = filename_size >> 1;
- filename[filename_size++] = high;
- filename[filename_size++] = p[cp] + extra;
- length--;
- }
- }
- break;
- }
- }
- if (filename_size > fn_end) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid filename");
- return (ARCHIVE_FATAL);
- }
- filename[filename_size++] = '\0';
- /*
- * Do not increment filename_size here as the computations below
- * add the space for the terminating NUL explicitly.
- */
- filename[filename_size] = '\0';
-
- /* Decoded unicode form is UTF-16BE, so we have to update a string
- * conversion object for it. */
- if (rar->sconv_utf16be == NULL) {
- rar->sconv_utf16be = archive_string_conversion_from_charset(
- &a->archive, "UTF-16BE", 1);
- if (rar->sconv_utf16be == NULL)
- return (ARCHIVE_FATAL);
- }
- fn_sconv = rar->sconv_utf16be;
-
- strp = filename;
- while (memcmp(strp, "\x00\x00", 2))
- {
- if (!memcmp(strp, "\x00\\", 2))
- *(strp + 1) = '/';
- strp += 2;
- }
- p += offset;
- } else {
- /*
- * If FHD_UNICODE is set but no unicode data, this file name form
- * is UTF-8, so we have to update a string conversion object for
- * it accordingly.
- */
- if (rar->sconv_utf8 == NULL) {
- rar->sconv_utf8 = archive_string_conversion_from_charset(
- &a->archive, "UTF-8", 1);
- if (rar->sconv_utf8 == NULL)
- return (ARCHIVE_FATAL);
- }
- fn_sconv = rar->sconv_utf8;
- while ((strp = strchr(filename, '\\')) != NULL)
- *strp = '/';
- p += filename_size;
- }
- }
- else
- {
- fn_sconv = sconv;
- while ((strp = strchr(filename, '\\')) != NULL)
- *strp = '/';
- p += filename_size;
- }
-
- /* Split file in multivolume RAR. No more need to process header. */
- if (rar->filename_save &&
- filename_size == rar->filename_save_size &&
- !memcmp(rar->filename, rar->filename_save, filename_size + 1))
- {
- __archive_read_consume(a, header_size - 7);
- rar->cursor++;
- if (rar->cursor >= rar->nodes)
- {
- rar->nodes++;
- if ((rar->dbo =
- realloc(rar->dbo, sizeof(*rar->dbo) * rar->nodes)) == NULL)
- {
- archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory.");
- return (ARCHIVE_FATAL);
- }
- rar->dbo[rar->cursor].header_size = header_size;
- rar->dbo[rar->cursor].start_offset = -1;
- rar->dbo[rar->cursor].end_offset = -1;
- }
- if (rar->dbo[rar->cursor].start_offset < 0)
- {
- rar->dbo[rar->cursor].start_offset = a->filter->position;
- rar->dbo[rar->cursor].end_offset = rar->dbo[rar->cursor].start_offset +
- rar->packed_size;
- }
- return ret;
- }
- else if (rar->filename_must_match)
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Mismatch of file parts split across multi-volume archive");
- return (ARCHIVE_FATAL);
- }
-
- rar->filename_save = (char*)realloc(rar->filename_save,
- filename_size + 1);
- memcpy(rar->filename_save, rar->filename, filename_size + 1);
- rar->filename_save_size = filename_size;
-
- /* Set info for seeking */
- free(rar->dbo);
- if ((rar->dbo = calloc(1, sizeof(*rar->dbo))) == NULL)
- {
- archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory.");
- return (ARCHIVE_FATAL);
- }
- rar->dbo[0].header_size = header_size;
- rar->dbo[0].start_offset = -1;
- rar->dbo[0].end_offset = -1;
- rar->cursor = 0;
- rar->nodes = 1;
-
- if (rar->file_flags & FHD_SALT)
- {
- if (p + 8 > endp) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid header size");
- return (ARCHIVE_FATAL);
- }
- memcpy(rar->salt, p, 8);
- p += 8;
- }
-
- if (rar->file_flags & FHD_EXTTIME) {
- if (read_exttime(p, rar, endp) < 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid header size");
- return (ARCHIVE_FATAL);
- }
- }
-
- __archive_read_consume(a, header_size - 7);
- rar->dbo[0].start_offset = a->filter->position;
- rar->dbo[0].end_offset = rar->dbo[0].start_offset + rar->packed_size;
-
- switch(file_header.host_os)
- {
- case OS_MSDOS:
- case OS_OS2:
- case OS_WIN32:
- rar->mode = archive_le32dec(file_header.file_attr);
- if (rar->mode & FILE_ATTRIBUTE_DIRECTORY)
- rar->mode = AE_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
- else
- rar->mode = AE_IFREG;
- rar->mode |= S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
- break;
-
- case OS_UNIX:
- case OS_MAC_OS:
- case OS_BEOS:
- rar->mode = archive_le32dec(file_header.file_attr);
- break;
-
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unknown file attributes from RAR file's host OS");
- return (ARCHIVE_FATAL);
- }
-
- rar->bytes_uncopied = rar->bytes_unconsumed = 0;
- rar->lzss.position = rar->offset = 0;
- rar->offset_seek = 0;
- rar->dictionary_size = 0;
- rar->offset_outgoing = 0;
- rar->br.cache_avail = 0;
- rar->br.avail_in = 0;
- rar->crc_calculated = 0;
- rar->entry_eof = 0;
- rar->valid = 1;
- rar->is_ppmd_block = 0;
- rar->start_new_table = 1;
- free(rar->unp_buffer);
- rar->unp_buffer = NULL;
- rar->unp_offset = 0;
- rar->unp_buffer_size = UNP_BUFFER_SIZE;
- memset(rar->lengthtable, 0, sizeof(rar->lengthtable));
- __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
- rar->ppmd_valid = rar->ppmd_eod = 0;
- rar->filters.filterstart = INT64_MAX;
-
- /* Don't set any archive entries for non-file header types */
- if (head_type == NEWSUB_HEAD)
- return ret;
-
- archive_entry_set_mtime(entry, rar->mtime, rar->mnsec);
- archive_entry_set_ctime(entry, rar->ctime, rar->cnsec);
- archive_entry_set_atime(entry, rar->atime, rar->ansec);
- archive_entry_set_size(entry, rar->unp_size);
- archive_entry_set_mode(entry, rar->mode);
-
- if (archive_entry_copy_pathname_l(entry, filename, filename_size, fn_sconv))
- {
- if (errno == ENOMEM)
- {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Pathname cannot be converted from %s to current locale.",
- archive_string_conversion_charset_name(fn_sconv));
- ret = (ARCHIVE_WARN);
- }
-
- if (((rar->mode) & AE_IFMT) == AE_IFLNK)
- {
- /* Make sure a symbolic-link file does not have its body. */
- rar->bytes_remaining = 0;
- archive_entry_set_size(entry, 0);
-
- /* Read a symbolic-link name. */
- if ((ret2 = read_symlink_stored(a, entry, sconv)) < (ARCHIVE_WARN))
- return ret2;
- if (ret > ret2)
- ret = ret2;
- }
-
- if (rar->bytes_remaining == 0)
- rar->entry_eof = 1;
-
- return ret;
-}
-
-static time_t
-get_time(int ttime)
-{
- struct tm tm;
- tm.tm_sec = 2 * (ttime & 0x1f);
- tm.tm_min = (ttime >> 5) & 0x3f;
- tm.tm_hour = (ttime >> 11) & 0x1f;
- tm.tm_mday = (ttime >> 16) & 0x1f;
- tm.tm_mon = ((ttime >> 21) & 0x0f) - 1;
- tm.tm_year = ((ttime >> 25) & 0x7f) + 80;
- tm.tm_isdst = -1;
- return mktime(&tm);
-}
-
-static int
-read_exttime(const char *p, struct rar *rar, const char *endp)
-{
- unsigned rmode, flags, rem, j, count;
- int ttime, i;
- struct tm *tm;
- time_t t;
- long nsec;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
- struct tm tmbuf;
-#endif
-
- if (p + 2 > endp)
- return (-1);
- flags = archive_le16dec(p);
- p += 2;
-
- for (i = 3; i >= 0; i--)
- {
- t = 0;
- if (i == 3)
- t = rar->mtime;
- rmode = flags >> i * 4;
- if (rmode & 8)
- {
- if (!t)
- {
- if (p + 4 > endp)
- return (-1);
- ttime = archive_le32dec(p);
- t = get_time(ttime);
- p += 4;
- }
- rem = 0;
- count = rmode & 3;
- if (p + count > endp)
- return (-1);
- for (j = 0; j < count; j++)
- {
- rem = (((unsigned)(unsigned char)*p) << 16) | (rem >> 8);
- p++;
- }
-#if defined(HAVE_LOCALTIME_S)
- tm = localtime_s(&tmbuf, &t) ? NULL : &tmbuf;
-#elif defined(HAVE_LOCALTIME_R)
- tm = localtime_r(&t, &tmbuf);
-#else
- tm = localtime(&t);
-#endif
- nsec = tm->tm_sec + rem / NS_UNIT;
- if (rmode & 4)
- {
- tm->tm_sec++;
- t = mktime(tm);
- }
- if (i == 3)
- {
- rar->mtime = t;
- rar->mnsec = nsec;
- }
- else if (i == 2)
- {
- rar->ctime = t;
- rar->cnsec = nsec;
- }
- else if (i == 1)
- {
- rar->atime = t;
- rar->ansec = nsec;
- }
- else
- {
- rar->arctime = t;
- rar->arcnsec = nsec;
- }
- }
- }
- return (0);
-}
-
-static int
-read_symlink_stored(struct archive_read *a, struct archive_entry *entry,
- struct archive_string_conv *sconv)
-{
- const void *h;
- const char *p;
- struct rar *rar;
- int ret = (ARCHIVE_OK);
-
- rar = (struct rar *)(a->format->data);
- if ((h = rar_read_ahead(a, (size_t)rar->packed_size, NULL)) == NULL)
- return (ARCHIVE_FATAL);
- p = h;
-
- if (archive_entry_copy_symlink_l(entry,
- p, (size_t)rar->packed_size, sconv))
- {
- if (errno == ENOMEM)
- {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for link");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "link cannot be converted from %s to current locale.",
- archive_string_conversion_charset_name(sconv));
- ret = (ARCHIVE_WARN);
- }
- __archive_read_consume(a, rar->packed_size);
- return ret;
-}
-
-static int
-read_data_stored(struct archive_read *a, const void **buff, size_t *size,
- int64_t *offset)
-{
- struct rar *rar;
- ssize_t bytes_avail;
-
- rar = (struct rar *)(a->format->data);
- if (rar->bytes_remaining == 0 &&
- !(rar->main_flags & MHD_VOLUME && rar->file_flags & FHD_SPLIT_AFTER))
- {
- *buff = NULL;
- *size = 0;
- *offset = rar->offset;
- if (rar->file_crc != rar->crc_calculated) {
-#ifndef DONT_FAIL_ON_CRC_ERROR
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "File CRC error");
- return (ARCHIVE_FATAL);
-#endif
- }
- rar->entry_eof = 1;
- return (ARCHIVE_EOF);
- }
-
- *buff = rar_read_ahead(a, 1, &bytes_avail);
- if (bytes_avail <= 0)
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated RAR file data");
- return (ARCHIVE_FATAL);
- }
-
- *size = bytes_avail;
- *offset = rar->offset;
- rar->offset += bytes_avail;
- rar->offset_seek += bytes_avail;
- rar->bytes_remaining -= bytes_avail;
- rar->bytes_unconsumed = bytes_avail;
- /* Calculate File CRC. */
- rar->crc_calculated = crc32(rar->crc_calculated, *buff,
- (unsigned)bytes_avail);
- return (ARCHIVE_OK);
-}
-
-static int
-read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
- int64_t *offset, size_t looper)
-{
- if (looper++ > MAX_COMPRESS_DEPTH)
- return (ARCHIVE_FATAL);
-
- struct rar *rar;
- int64_t start, end;
- size_t bs;
- int ret = (ARCHIVE_OK), sym, code, lzss_offset, length, i;
-
- rar = (struct rar *)(a->format->data);
-
- do {
- if (!rar->valid)
- return (ARCHIVE_FATAL);
-
- if (rar->filters.bytes_ready > 0)
- {
- /* Flush unp_buffer first */
- if (rar->unp_offset > 0)
- {
- *buff = rar->unp_buffer;
- *size = rar->unp_offset;
- rar->unp_offset = 0;
- *offset = rar->offset_outgoing;
- rar->offset_outgoing += *size;
- }
- else
- {
- *buff = rar->filters.bytes;
- *size = rar->filters.bytes_ready;
-
- rar->offset += *size;
- *offset = rar->offset_outgoing;
- rar->offset_outgoing += *size;
-
- rar->filters.bytes_ready -= *size;
- rar->filters.bytes += *size;
- }
- goto ending_block;
- }
-
- if (rar->ppmd_eod ||
- (rar->dictionary_size && rar->offset >= rar->unp_size))
- {
- if (rar->unp_offset > 0) {
- /*
- * We have unprocessed extracted data. write it out.
- */
- *buff = rar->unp_buffer;
- *size = rar->unp_offset;
- *offset = rar->offset_outgoing;
- rar->offset_outgoing += *size;
- /* Calculate File CRC. */
- rar->crc_calculated = crc32(rar->crc_calculated, *buff,
- (unsigned)*size);
- rar->unp_offset = 0;
- return (ARCHIVE_OK);
- }
- *buff = NULL;
- *size = 0;
- *offset = rar->offset;
- if (rar->file_crc != rar->crc_calculated) {
-#ifndef DONT_FAIL_ON_CRC_ERROR
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "File CRC error");
- return (ARCHIVE_FATAL);
-#endif
- }
- rar->entry_eof = 1;
- return (ARCHIVE_EOF);
- }
-
- if (!rar->is_ppmd_block && rar->dictionary_size && rar->bytes_uncopied > 0)
- {
- if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset))
- bs = rar->unp_buffer_size - rar->unp_offset;
- else
- bs = (size_t)rar->bytes_uncopied;
- ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, (int)bs);
- if (ret != ARCHIVE_OK)
- return (ret);
- rar->offset += bs;
- rar->bytes_uncopied -= bs;
- if (*buff != NULL) {
- rar->unp_offset = 0;
- *size = rar->unp_buffer_size;
- *offset = rar->offset_outgoing;
- rar->offset_outgoing += *size;
- /* Calculate File CRC. */
- rar->crc_calculated = crc32(rar->crc_calculated, *buff,
- (unsigned)*size);
- return (ret);
- }
- continue;
- }
-
- if (rar->filters.lastend == rar->filters.filterstart)
- {
- if (!run_filters(a))
- return (ARCHIVE_FATAL);
- continue;
- }
-
- if (!rar->br.next_in &&
- (ret = rar_br_preparation(a, &(rar->br))) < ARCHIVE_WARN)
- return (ret);
- if (rar->start_new_table && ((ret = parse_codes(a)) < (ARCHIVE_WARN)))
- return (ret);
-
- if (rar->is_ppmd_block)
- {
- if ((sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
- &rar->ppmd7_context, &rar->range_dec.p)) < 0)
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid symbol");
- return (ARCHIVE_FATAL);
- }
- if(sym != rar->ppmd_escape)
- {
- lzss_emit_literal(rar, sym);
- rar->bytes_uncopied++;
- }
- else
- {
- if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
- &rar->ppmd7_context, &rar->range_dec.p)) < 0)
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid symbol");
- return (ARCHIVE_FATAL);
- }
-
- switch(code)
- {
- case 0:
- rar->start_new_table = 1;
- return read_data_compressed(a, buff, size, offset, looper);
-
- case 2:
- rar->ppmd_eod = 1;/* End Of ppmd Data. */
- continue;
-
- case 3:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Parsing filters is unsupported.");
- return (ARCHIVE_FAILED);
-
- case 4:
- lzss_offset = 0;
- for (i = 2; i >= 0; i--)
- {
- if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
- &rar->ppmd7_context, &rar->range_dec.p)) < 0)
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid symbol");
- return (ARCHIVE_FATAL);
- }
- lzss_offset |= code << (i * 8);
- }
- if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
- &rar->ppmd7_context, &rar->range_dec.p)) < 0)
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid symbol");
- return (ARCHIVE_FATAL);
- }
- lzss_emit_match(rar, lzss_offset + 2, length + 32);
- rar->bytes_uncopied += length + 32;
- break;
-
- case 5:
- if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
- &rar->ppmd7_context, &rar->range_dec.p)) < 0)
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid symbol");
- return (ARCHIVE_FATAL);
- }
- lzss_emit_match(rar, 1, length + 4);
- rar->bytes_uncopied += length + 4;
- break;
-
- default:
- lzss_emit_literal(rar, sym);
- rar->bytes_uncopied++;
- }
- }
- }
- else
- {
- start = rar->offset;
- end = start + rar->dictionary_size;
- if (rar->filters.filterstart < end) {
- end = rar->filters.filterstart;
- }
-
- ret = expand(a, &end);
- if (ret != ARCHIVE_OK)
- return (ret);
-
- rar->bytes_uncopied = end - start;
- rar->filters.lastend = end;
- if (rar->filters.lastend != rar->filters.filterstart && rar->bytes_uncopied == 0) {
- /* Broken RAR files cause this case.
- * NOTE: If this case were possible on a normal RAR file
- * we would find out where it was actually bad and
- * what we would do to solve it. */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Internal error extracting RAR file");
- return (ARCHIVE_FATAL);
- }
- }
- if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset))
- bs = rar->unp_buffer_size - rar->unp_offset;
- else
- bs = (size_t)rar->bytes_uncopied;
- ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, (int)bs);
- if (ret != ARCHIVE_OK)
- return (ret);
- rar->offset += bs;
- rar->bytes_uncopied -= bs;
- /*
- * If *buff is NULL, it means unp_buffer is not full.
- * So we have to continue extracting a RAR file.
- */
- } while (*buff == NULL);
-
- rar->unp_offset = 0;
- *size = rar->unp_buffer_size;
- *offset = rar->offset_outgoing;
- rar->offset_outgoing += *size;
-ending_block:
- /* Calculate File CRC. */
- rar->crc_calculated = crc32(rar->crc_calculated, *buff, (unsigned)*size);
- return ret;
-}
-
-static int
-parse_codes(struct archive_read *a)
-{
- int i, j, val, n, r;
- unsigned char bitlengths[MAX_SYMBOLS], zerocount, ppmd_flags;
- unsigned int maxorder;
- struct huffman_code precode;
- struct rar *rar = (struct rar *)(a->format->data);
- struct rar_br *br = &(rar->br);
-
- free_codes(a);
-
- /* Skip to the next byte */
- rar_br_consume_unalined_bits(br);
-
- /* PPMd block flag */
- if (!rar_br_read_ahead(a, br, 1))
- goto truncated_data;
- if ((rar->is_ppmd_block = rar_br_bits(br, 1)) != 0)
- {
- rar_br_consume(br, 1);
- if (!rar_br_read_ahead(a, br, 7))
- goto truncated_data;
- ppmd_flags = rar_br_bits(br, 7);
- rar_br_consume(br, 7);
-
- /* Memory is allocated in MB */
- if (ppmd_flags & 0x20)
- {
- if (!rar_br_read_ahead(a, br, 8))
- goto truncated_data;
- rar->dictionary_size = (rar_br_bits(br, 8) + 1) << 20;
- rar_br_consume(br, 8);
- }
-
- if (ppmd_flags & 0x40)
- {
- if (!rar_br_read_ahead(a, br, 8))
- goto truncated_data;
- rar->ppmd_escape = rar->ppmd7_context.InitEsc = rar_br_bits(br, 8);
- rar_br_consume(br, 8);
- }
- else
- rar->ppmd_escape = 2;
-
- if (ppmd_flags & 0x20)
- {
- maxorder = (ppmd_flags & 0x1F) + 1;
- if(maxorder > 16)
- maxorder = 16 + (maxorder - 16) * 3;
-
- if (maxorder == 1)
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated RAR file data");
- return (ARCHIVE_FATAL);
- }
-
- /* Make sure ppmd7_contest is freed before Ppmd7_Construct
- * because reading a broken file cause this abnormal sequence. */
- __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
-
- rar->bytein.a = a;
- rar->bytein.Read = &ppmd_read;
- __archive_ppmd7_functions.PpmdRAR_RangeDec_CreateVTable(&rar->range_dec);
- rar->range_dec.Stream = &rar->bytein;
- __archive_ppmd7_functions.Ppmd7_Construct(&rar->ppmd7_context);
-
- if (rar->dictionary_size == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid zero dictionary size");
- return (ARCHIVE_FATAL);
- }
-
- if (!__archive_ppmd7_functions.Ppmd7_Alloc(&rar->ppmd7_context,
- rar->dictionary_size))
- {
- archive_set_error(&a->archive, ENOMEM,
- "Out of memory");
- return (ARCHIVE_FATAL);
- }
- if (!__archive_ppmd7_functions.PpmdRAR_RangeDec_Init(&rar->range_dec))
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unable to initialize PPMd range decoder");
- return (ARCHIVE_FATAL);
- }
- __archive_ppmd7_functions.Ppmd7_Init(&rar->ppmd7_context, maxorder);
- rar->ppmd_valid = 1;
- }
- else
- {
- if (!rar->ppmd_valid) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid PPMd sequence");
- return (ARCHIVE_FATAL);
- }
- if (!__archive_ppmd7_functions.PpmdRAR_RangeDec_Init(&rar->range_dec))
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unable to initialize PPMd range decoder");
- return (ARCHIVE_FATAL);
- }
- }
- }
- else
- {
- rar_br_consume(br, 1);
-
- /* Keep existing table flag */
- if (!rar_br_read_ahead(a, br, 1))
- goto truncated_data;
- if (!rar_br_bits(br, 1))
- memset(rar->lengthtable, 0, sizeof(rar->lengthtable));
- rar_br_consume(br, 1);
-
- memset(&bitlengths, 0, sizeof(bitlengths));
- for (i = 0; i < MAX_SYMBOLS;)
- {
- if (!rar_br_read_ahead(a, br, 4))
- goto truncated_data;
- bitlengths[i++] = rar_br_bits(br, 4);
- rar_br_consume(br, 4);
- if (bitlengths[i-1] == 0xF)
- {
- if (!rar_br_read_ahead(a, br, 4))
- goto truncated_data;
- zerocount = rar_br_bits(br, 4);
- rar_br_consume(br, 4);
- if (zerocount)
- {
- i--;
- for (j = 0; j < zerocount + 2 && i < MAX_SYMBOLS; j++)
- bitlengths[i++] = 0;
- }
- }
- }
-
- memset(&precode, 0, sizeof(precode));
- r = create_code(a, &precode, bitlengths, MAX_SYMBOLS, MAX_SYMBOL_LENGTH);
- if (r != ARCHIVE_OK) {
- free(precode.tree);
- free(precode.table);
- return (r);
- }
-
- for (i = 0; i < HUFFMAN_TABLE_SIZE;)
- {
- if ((val = read_next_symbol(a, &precode)) < 0) {
- free(precode.tree);
- free(precode.table);
- return (ARCHIVE_FATAL);
- }
- if (val < 16)
- {
- rar->lengthtable[i] = (rar->lengthtable[i] + val) & 0xF;
- i++;
- }
- else if (val < 18)
- {
- if (i == 0)
- {
- free(precode.tree);
- free(precode.table);
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Internal error extracting RAR file.");
- return (ARCHIVE_FATAL);
- }
-
- if(val == 16) {
- if (!rar_br_read_ahead(a, br, 3)) {
- free(precode.tree);
- free(precode.table);
- goto truncated_data;
- }
- n = rar_br_bits(br, 3) + 3;
- rar_br_consume(br, 3);
- } else {
- if (!rar_br_read_ahead(a, br, 7)) {
- free(precode.tree);
- free(precode.table);
- goto truncated_data;
- }
- n = rar_br_bits(br, 7) + 11;
- rar_br_consume(br, 7);
- }
-
- for (j = 0; j < n && i < HUFFMAN_TABLE_SIZE; j++)
- {
- rar->lengthtable[i] = rar->lengthtable[i-1];
- i++;
- }
- }
- else
- {
- if(val == 18) {
- if (!rar_br_read_ahead(a, br, 3)) {
- free(precode.tree);
- free(precode.table);
- goto truncated_data;
- }
- n = rar_br_bits(br, 3) + 3;
- rar_br_consume(br, 3);
- } else {
- if (!rar_br_read_ahead(a, br, 7)) {
- free(precode.tree);
- free(precode.table);
- goto truncated_data;
- }
- n = rar_br_bits(br, 7) + 11;
- rar_br_consume(br, 7);
- }
-
- for(j = 0; j < n && i < HUFFMAN_TABLE_SIZE; j++)
- rar->lengthtable[i++] = 0;
- }
- }
- free(precode.tree);
- free(precode.table);
-
- r = create_code(a, &rar->maincode, &rar->lengthtable[0], MAINCODE_SIZE,
- MAX_SYMBOL_LENGTH);
- if (r != ARCHIVE_OK)
- return (r);
- r = create_code(a, &rar->offsetcode, &rar->lengthtable[MAINCODE_SIZE],
- OFFSETCODE_SIZE, MAX_SYMBOL_LENGTH);
- if (r != ARCHIVE_OK)
- return (r);
- r = create_code(a, &rar->lowoffsetcode,
- &rar->lengthtable[MAINCODE_SIZE + OFFSETCODE_SIZE],
- LOWOFFSETCODE_SIZE, MAX_SYMBOL_LENGTH);
- if (r != ARCHIVE_OK)
- return (r);
- r = create_code(a, &rar->lengthcode,
- &rar->lengthtable[MAINCODE_SIZE + OFFSETCODE_SIZE +
- LOWOFFSETCODE_SIZE], LENGTHCODE_SIZE, MAX_SYMBOL_LENGTH);
- if (r != ARCHIVE_OK)
- return (r);
- }
-
- if (!rar->dictionary_size || !rar->lzss.window)
- {
- /* Seems as though dictionary sizes are not used. Even so, minimize
- * memory usage as much as possible.
- */
- void *new_window;
- unsigned int new_size;
-
- if (rar->unp_size >= DICTIONARY_MAX_SIZE)
- new_size = DICTIONARY_MAX_SIZE;
- else
- new_size = rar_fls((unsigned int)rar->unp_size) << 1;
- if (new_size == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Zero window size is invalid.");
- return (ARCHIVE_FATAL);
- }
- new_window = realloc(rar->lzss.window, new_size);
- if (new_window == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Unable to allocate memory for uncompressed data.");
- return (ARCHIVE_FATAL);
- }
- rar->lzss.window = (unsigned char *)new_window;
- rar->dictionary_size = new_size;
- memset(rar->lzss.window, 0, rar->dictionary_size);
- rar->lzss.mask = rar->dictionary_size - 1;
- }
-
- rar->start_new_table = 0;
- return (ARCHIVE_OK);
-truncated_data:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated RAR file data");
- rar->valid = 0;
- return (ARCHIVE_FATAL);
-}
-
-static void
-free_codes(struct archive_read *a)
-{
- struct rar *rar = (struct rar *)(a->format->data);
- free(rar->maincode.tree);
- free(rar->offsetcode.tree);
- free(rar->lowoffsetcode.tree);
- free(rar->lengthcode.tree);
- free(rar->maincode.table);
- free(rar->offsetcode.table);
- free(rar->lowoffsetcode.table);
- free(rar->lengthcode.table);
- memset(&rar->maincode, 0, sizeof(rar->maincode));
- memset(&rar->offsetcode, 0, sizeof(rar->offsetcode));
- memset(&rar->lowoffsetcode, 0, sizeof(rar->lowoffsetcode));
- memset(&rar->lengthcode, 0, sizeof(rar->lengthcode));
-}
-
-
-static int
-read_next_symbol(struct archive_read *a, struct huffman_code *code)
-{
- unsigned char bit;
- unsigned int bits;
- int length, value, node;
- struct rar *rar;
- struct rar_br *br;
-
- if (!code->table)
- {
- if (make_table(a, code) != (ARCHIVE_OK))
- return -1;
- }
-
- rar = (struct rar *)(a->format->data);
- br = &(rar->br);
-
- /* Look ahead (peek) at bits */
- if (!rar_br_read_ahead(a, br, code->tablesize)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated RAR file data");
- rar->valid = 0;
- return -1;
- }
- bits = rar_br_bits(br, code->tablesize);
-
- length = code->table[bits].length;
- value = code->table[bits].value;
-
- if (length < 0)
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid prefix code in bitstream");
- return -1;
- }
-
- if (length <= code->tablesize)
- {
- /* Skip length bits */
- rar_br_consume(br, length);
- return value;
- }
-
- /* Skip tablesize bits */
- rar_br_consume(br, code->tablesize);
-
- node = value;
- while (!(code->tree[node].branches[0] ==
- code->tree[node].branches[1]))
- {
- if (!rar_br_read_ahead(a, br, 1)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated RAR file data");
- rar->valid = 0;
- return -1;
- }
- bit = rar_br_bits(br, 1);
- rar_br_consume(br, 1);
-
- if (code->tree[node].branches[bit] < 0)
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid prefix code in bitstream");
- return -1;
- }
- node = code->tree[node].branches[bit];
- }
-
- return code->tree[node].branches[0];
-}
-
-static int
-create_code(struct archive_read *a, struct huffman_code *code,
- unsigned char *lengths, int numsymbols, char maxlength)
-{
- int i, j, codebits = 0, symbolsleft = numsymbols;
-
- code->numentries = 0;
- code->numallocatedentries = 0;
- if (new_node(code) < 0) {
- archive_set_error(&a->archive, ENOMEM,
- "Unable to allocate memory for node data.");
- return (ARCHIVE_FATAL);
- }
- code->numentries = 1;
- code->minlength = INT_MAX;
- code->maxlength = INT_MIN;
- codebits = 0;
- for(i = 1; i <= maxlength; i++)
- {
- for(j = 0; j < numsymbols; j++)
- {
- if (lengths[j] != i) continue;
- if (add_value(a, code, j, codebits, i) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- codebits++;
- if (--symbolsleft <= 0)
- break;
- }
- if (symbolsleft <= 0)
- break;
- codebits <<= 1;
- }
- return (ARCHIVE_OK);
-}
-
-static int
-add_value(struct archive_read *a, struct huffman_code *code, int value,
- int codebits, int length)
-{
- int lastnode, bitpos, bit;
- /* int repeatpos, repeatnode, nextnode; */
-
- free(code->table);
- code->table = NULL;
-
- if(length > code->maxlength)
- code->maxlength = length;
- if(length < code->minlength)
- code->minlength = length;
-
- /*
- * Dead code, repeatpos was is -1
- *
- repeatpos = -1;
- if (repeatpos == 0 || (repeatpos >= 0
- && (((codebits >> (repeatpos - 1)) & 3) == 0
- || ((codebits >> (repeatpos - 1)) & 3) == 3)))
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid repeat position");
- return (ARCHIVE_FATAL);
- }
- */
-
- lastnode = 0;
- for (bitpos = length - 1; bitpos >= 0; bitpos--)
- {
- bit = (codebits >> bitpos) & 1;
-
- /* Leaf node check */
- if (code->tree[lastnode].branches[0] ==
- code->tree[lastnode].branches[1])
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Prefix found");
- return (ARCHIVE_FATAL);
- }
-
- /*
- * Dead code, repeatpos was -1, bitpos >=0
- *
- if (bitpos == repeatpos)
- {
- * Open branch check *
- if (!(code->tree[lastnode].branches[bit] < 0))
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid repeating code");
- return (ARCHIVE_FATAL);
- }
-
- if ((repeatnode = new_node(code)) < 0) {
- archive_set_error(&a->archive, ENOMEM,
- "Unable to allocate memory for node data.");
- return (ARCHIVE_FATAL);
- }
- if ((nextnode = new_node(code)) < 0) {
- archive_set_error(&a->archive, ENOMEM,
- "Unable to allocate memory for node data.");
- return (ARCHIVE_FATAL);
- }
-
- * Set branches *
- code->tree[lastnode].branches[bit] = repeatnode;
- code->tree[repeatnode].branches[bit] = repeatnode;
- code->tree[repeatnode].branches[bit^1] = nextnode;
- lastnode = nextnode;
-
- bitpos++; * terminating bit already handled, skip it *
- }
- else
- {
- */
- /* Open branch check */
- if (code->tree[lastnode].branches[bit] < 0)
- {
- if (new_node(code) < 0) {
- archive_set_error(&a->archive, ENOMEM,
- "Unable to allocate memory for node data.");
- return (ARCHIVE_FATAL);
- }
- code->tree[lastnode].branches[bit] = code->numentries++;
- }
-
- /* set to branch */
- lastnode = code->tree[lastnode].branches[bit];
- /* } */
- }
-
- if (!(code->tree[lastnode].branches[0] == -1
- && code->tree[lastnode].branches[1] == -2))
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Prefix found");
- return (ARCHIVE_FATAL);
- }
-
- /* Set leaf value */
- code->tree[lastnode].branches[0] = value;
- code->tree[lastnode].branches[1] = value;
-
- return (ARCHIVE_OK);
-}
-
-static int
-new_node(struct huffman_code *code)
-{
- void *new_tree;
- if (code->numallocatedentries == code->numentries) {
- int new_num_entries = 256;
- if (code->numentries > 0) {
- new_num_entries = code->numentries * 2;
- }
- new_tree = realloc(code->tree, new_num_entries * sizeof(*code->tree));
- if (new_tree == NULL)
- return (-1);
- code->tree = (struct huffman_tree_node *)new_tree;
- code->numallocatedentries = new_num_entries;
- }
- code->tree[code->numentries].branches[0] = -1;
- code->tree[code->numentries].branches[1] = -2;
- return 1;
-}
-
-static int
-make_table(struct archive_read *a, struct huffman_code *code)
-{
- if (code->maxlength < code->minlength || code->maxlength > 10)
- code->tablesize = 10;
- else
- code->tablesize = code->maxlength;
-
- code->table =
- (struct huffman_table_entry *)calloc(1, sizeof(*code->table)
- * ((size_t)1 << code->tablesize));
-
- return make_table_recurse(a, code, 0, code->table, 0, code->tablesize);
-}
-
-static int
-make_table_recurse(struct archive_read *a, struct huffman_code *code, int node,
- struct huffman_table_entry *table, int depth,
- int maxdepth)
-{
- int currtablesize, i, ret = (ARCHIVE_OK);
-
- if (!code->tree)
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Huffman tree was not created.");
- return (ARCHIVE_FATAL);
- }
- if (node < 0 || node >= code->numentries)
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid location to Huffman tree specified.");
- return (ARCHIVE_FATAL);
- }
-
- currtablesize = 1 << (maxdepth - depth);
-
- if (code->tree[node].branches[0] ==
- code->tree[node].branches[1])
- {
- for(i = 0; i < currtablesize; i++)
- {
- table[i].length = depth;
- table[i].value = code->tree[node].branches[0];
- }
- }
- /*
- * Dead code, node >= 0
- *
- else if (node < 0)
- {
- for(i = 0; i < currtablesize; i++)
- table[i].length = -1;
- }
- */
- else
- {
- if(depth == maxdepth)
- {
- table[0].length = maxdepth + 1;
- table[0].value = node;
- }
- else
- {
- ret |= make_table_recurse(a, code, code->tree[node].branches[0], table,
- depth + 1, maxdepth);
- ret |= make_table_recurse(a, code, code->tree[node].branches[1],
- table + currtablesize / 2, depth + 1, maxdepth);
- }
- }
- return ret;
-}
-
-static int
-expand(struct archive_read *a, int64_t *end)
-{
- static const unsigned char lengthbases[] =
- { 0, 1, 2, 3, 4, 5, 6,
- 7, 8, 10, 12, 14, 16, 20,
- 24, 28, 32, 40, 48, 56, 64,
- 80, 96, 112, 128, 160, 192, 224 };
- static const unsigned char lengthbits[] =
- { 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 1, 1, 1, 2, 2,
- 2, 2, 3, 3, 3, 3, 4,
- 4, 4, 4, 5, 5, 5, 5 };
- static const int lengthb_min = minimum(
- (int)(sizeof(lengthbases)/sizeof(lengthbases[0])),
- (int)(sizeof(lengthbits)/sizeof(lengthbits[0]))
- );
- static const unsigned int offsetbases[] =
- { 0, 1, 2, 3, 4, 6,
- 8, 12, 16, 24, 32, 48,
- 64, 96, 128, 192, 256, 384,
- 512, 768, 1024, 1536, 2048, 3072,
- 4096, 6144, 8192, 12288, 16384, 24576,
- 32768, 49152, 65536, 98304, 131072, 196608,
- 262144, 327680, 393216, 458752, 524288, 589824,
- 655360, 720896, 786432, 851968, 917504, 983040,
- 1048576, 1310720, 1572864, 1835008, 2097152, 2359296,
- 2621440, 2883584, 3145728, 3407872, 3670016, 3932160 };
- static const unsigned char offsetbits[] =
- { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4,
- 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10,
- 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 };
- static const int offsetb_min = minimum(
- (int)(sizeof(offsetbases)/sizeof(offsetbases[0])),
- (int)(sizeof(offsetbits)/sizeof(offsetbits[0]))
- );
- static const unsigned char shortbases[] =
- { 0, 4, 8, 16, 32, 64, 128, 192 };
- static const unsigned char shortbits[] =
- { 2, 2, 3, 4, 5, 6, 6, 6 };
-
- int symbol, offs, len, offsindex, lensymbol, i, offssymbol, lowoffsetsymbol;
- unsigned char newfile;
- struct rar *rar = (struct rar *)(a->format->data);
- struct rar_br *br = &(rar->br);
-
- if (rar->filters.filterstart < *end)
- *end = rar->filters.filterstart;
-
- while (1)
- {
- if(lzss_position(&rar->lzss) >= *end) {
- return (ARCHIVE_OK);
- }
-
- if(rar->is_ppmd_block) {
- *end = lzss_position(&rar->lzss);
- return (ARCHIVE_OK);
- }
-
- if ((symbol = read_next_symbol(a, &rar->maincode)) < 0)
- return (ARCHIVE_FATAL);
-
- if (symbol < 256)
- {
- lzss_emit_literal(rar, symbol);
- continue;
- }
- else if (symbol == 256)
- {
- if (!rar_br_read_ahead(a, br, 1))
- goto truncated_data;
- newfile = !rar_br_bits(br, 1);
- rar_br_consume(br, 1);
-
- if(newfile)
- {
- rar->start_new_block = 1;
- if (!rar_br_read_ahead(a, br, 1))
- goto truncated_data;
- rar->start_new_table = rar_br_bits(br, 1);
- rar_br_consume(br, 1);
- *end = lzss_position(&rar->lzss);
- return (ARCHIVE_OK);
- }
- else
- {
- if (parse_codes(a) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- continue;
- }
- }
- else if(symbol==257)
- {
- if (!read_filter(a, end))
- return (ARCHIVE_FATAL);
- continue;
- }
- else if(symbol==258)
- {
- if(rar->lastlength == 0)
- continue;
-
- offs = rar->lastoffset;
- len = rar->lastlength;
- }
- else if (symbol <= 262)
- {
- offsindex = symbol - 259;
- offs = rar->oldoffset[offsindex];
-
- if ((lensymbol = read_next_symbol(a, &rar->lengthcode)) < 0)
- goto bad_data;
- if (lensymbol > lengthb_min)
- goto bad_data;
- len = lengthbases[lensymbol] + 2;
- if (lengthbits[lensymbol] > 0) {
- if (!rar_br_read_ahead(a, br, lengthbits[lensymbol]))
- goto truncated_data;
- len += rar_br_bits(br, lengthbits[lensymbol]);
- rar_br_consume(br, lengthbits[lensymbol]);
- }
-
- for (i = offsindex; i > 0; i--)
- rar->oldoffset[i] = rar->oldoffset[i-1];
- rar->oldoffset[0] = offs;
- }
- else if(symbol<=270)
- {
- offs = shortbases[symbol-263] + 1;
- if(shortbits[symbol-263] > 0) {
- if (!rar_br_read_ahead(a, br, shortbits[symbol-263]))
- goto truncated_data;
- offs += rar_br_bits(br, shortbits[symbol-263]);
- rar_br_consume(br, shortbits[symbol-263]);
- }
-
- len = 2;
-
- for(i = 3; i > 0; i--)
- rar->oldoffset[i] = rar->oldoffset[i-1];
- rar->oldoffset[0] = offs;
- }
- else
- {
- if (symbol-271 > lengthb_min)
- goto bad_data;
- len = lengthbases[symbol-271]+3;
- if(lengthbits[symbol-271] > 0) {
- if (!rar_br_read_ahead(a, br, lengthbits[symbol-271]))
- goto truncated_data;
- len += rar_br_bits(br, lengthbits[symbol-271]);
- rar_br_consume(br, lengthbits[symbol-271]);
- }
-
- if ((offssymbol = read_next_symbol(a, &rar->offsetcode)) < 0)
- goto bad_data;
- if (offssymbol > offsetb_min)
- goto bad_data;
- offs = offsetbases[offssymbol]+1;
- if(offsetbits[offssymbol] > 0)
- {
- if(offssymbol > 9)
- {
- if(offsetbits[offssymbol] > 4) {
- if (!rar_br_read_ahead(a, br, offsetbits[offssymbol] - 4))
- goto truncated_data;
- offs += rar_br_bits(br, offsetbits[offssymbol] - 4) << 4;
- rar_br_consume(br, offsetbits[offssymbol] - 4);
- }
-
- if(rar->numlowoffsetrepeats > 0)
- {
- rar->numlowoffsetrepeats--;
- offs += rar->lastlowoffset;
- }
- else
- {
- if ((lowoffsetsymbol =
- read_next_symbol(a, &rar->lowoffsetcode)) < 0)
- return (ARCHIVE_FATAL);
- if(lowoffsetsymbol == 16)
- {
- rar->numlowoffsetrepeats = 15;
- offs += rar->lastlowoffset;
- }
- else
- {
- offs += lowoffsetsymbol;
- rar->lastlowoffset = lowoffsetsymbol;
- }
- }
- }
- else {
- if (!rar_br_read_ahead(a, br, offsetbits[offssymbol]))
- goto truncated_data;
- offs += rar_br_bits(br, offsetbits[offssymbol]);
- rar_br_consume(br, offsetbits[offssymbol]);
- }
- }
-
- if (offs >= 0x40000)
- len++;
- if (offs >= 0x2000)
- len++;
-
- for(i = 3; i > 0; i--)
- rar->oldoffset[i] = rar->oldoffset[i-1];
- rar->oldoffset[0] = offs;
- }
-
- rar->lastoffset = offs;
- rar->lastlength = len;
-
- lzss_emit_match(rar, rar->lastoffset, rar->lastlength);
- }
-truncated_data:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated RAR file data");
- rar->valid = 0;
- return (ARCHIVE_FATAL);
-bad_data:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Bad RAR file data");
- return (ARCHIVE_FATAL);
-}
-
-static int
-copy_from_lzss_window(struct archive_read *a, void *buffer,
- int64_t startpos, int length)
-{
- int windowoffs, firstpart;
- struct rar *rar = (struct rar *)(a->format->data);
-
- windowoffs = lzss_offset_for_position(&rar->lzss, startpos);
- firstpart = lzss_size(&rar->lzss) - windowoffs;
- if (firstpart < 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Bad RAR file data");
- return (ARCHIVE_FATAL);
- }
- if (firstpart < length) {
- memcpy(buffer, &rar->lzss.window[windowoffs], firstpart);
- memcpy(buffer, &rar->lzss.window[0], length - firstpart);
- } else {
- memcpy(buffer, &rar->lzss.window[windowoffs], length);
- }
- return (ARCHIVE_OK);
-}
-
-static int
-copy_from_lzss_window_to_unp(struct archive_read *a, const void **buffer,
- int64_t startpos, int length)
-{
- int windowoffs, firstpart;
- struct rar *rar = (struct rar *)(a->format->data);
-
- if (!rar->unp_buffer)
- {
- if ((rar->unp_buffer = malloc(rar->unp_buffer_size)) == NULL)
- {
- archive_set_error(&a->archive, ENOMEM,
- "Unable to allocate memory for uncompressed data.");
- return (ARCHIVE_FATAL);
- }
- }
-
- windowoffs = lzss_offset_for_position(&rar->lzss, startpos);
- if(windowoffs + length <= lzss_size(&rar->lzss)) {
- memcpy(&rar->unp_buffer[rar->unp_offset], &rar->lzss.window[windowoffs],
- length);
- } else if (length <= lzss_size(&rar->lzss)) {
- firstpart = lzss_size(&rar->lzss) - windowoffs;
- if (firstpart < 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Bad RAR file data");
- return (ARCHIVE_FATAL);
- }
- if (firstpart < length) {
- memcpy(&rar->unp_buffer[rar->unp_offset],
- &rar->lzss.window[windowoffs], firstpart);
- memcpy(&rar->unp_buffer[rar->unp_offset + firstpart],
- &rar->lzss.window[0], length - firstpart);
- } else {
- memcpy(&rar->unp_buffer[rar->unp_offset],
- &rar->lzss.window[windowoffs], length);
- }
- } else {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Bad RAR file data");
- return (ARCHIVE_FATAL);
- }
- rar->unp_offset += length;
- if (rar->unp_offset >= rar->unp_buffer_size)
- *buffer = rar->unp_buffer;
- else
- *buffer = NULL;
- return (ARCHIVE_OK);
-}
-
-static const void *
-rar_read_ahead(struct archive_read *a, size_t min, ssize_t *avail)
-{
- struct rar *rar = (struct rar *)(a->format->data);
- const void *h = __archive_read_ahead(a, min, avail);
- int ret;
- if (avail)
- {
- if (a->archive.read_data_is_posix_read && *avail > (ssize_t)a->archive.read_data_requested)
- *avail = a->archive.read_data_requested;
- if (*avail > rar->bytes_remaining)
- *avail = (ssize_t)rar->bytes_remaining;
- if (*avail < 0)
- return NULL;
- else if (*avail == 0 && rar->main_flags & MHD_VOLUME &&
- rar->file_flags & FHD_SPLIT_AFTER)
- {
- rar->filename_must_match = 1;
- ret = archive_read_format_rar_read_header(a, a->entry);
- if (ret == (ARCHIVE_EOF))
- {
- rar->has_endarc_header = 1;
- ret = archive_read_format_rar_read_header(a, a->entry);
- }
- rar->filename_must_match = 0;
- if (ret != (ARCHIVE_OK))
- return NULL;
- return rar_read_ahead(a, min, avail);
- }
- }
- return h;
-}
-
-static int
-parse_filter(struct archive_read *a, const uint8_t *bytes, uint16_t length, uint8_t flags)
-{
- struct rar *rar = (struct rar *)(a->format->data);
- struct rar_filters *filters = &rar->filters;
-
- struct memory_bit_reader br = { 0 };
- struct rar_program_code *prog;
- struct rar_filter *filter, **nextfilter;
-
- uint32_t numprogs, num, blocklength, globaldatalen;
- uint8_t *globaldata;
- size_t blockstartpos;
- uint32_t registers[8] = { 0 };
- uint32_t i;
-
- br.bytes = bytes;
- br.length = length;
-
- numprogs = 0;
- for (prog = filters->progs; prog; prog = prog->next)
- numprogs++;
-
- if ((flags & 0x80))
- {
- num = membr_next_rarvm_number(&br);
- if (num == 0)
- {
- delete_filter(filters->stack);
- filters->stack = NULL;
- delete_program_code(filters->progs);
- filters->progs = NULL;
- }
- else
- num--;
- if (num > numprogs) {
- return 0;
- }
- filters->lastfilternum = num;
- }
- else
- num = filters->lastfilternum;
-
- prog = filters->progs;
- for (i = 0; i < num; i++)
- prog = prog->next;
- if (prog)
- prog->usagecount++;
-
- blockstartpos = membr_next_rarvm_number(&br) + (size_t)lzss_position(&rar->lzss);
- if ((flags & 0x40))
- blockstartpos += 258;
- if ((flags & 0x20))
- blocklength = membr_next_rarvm_number(&br);
- else
- blocklength = prog ? prog->oldfilterlength : 0;
-
- registers[3] = PROGRAM_SYSTEM_GLOBAL_ADDRESS;
- registers[4] = blocklength;
- registers[5] = prog ? prog->usagecount : 0;
- registers[7] = VM_MEMORY_SIZE;
-
- if ((flags & 0x10))
- {
- uint8_t mask = (uint8_t)membr_bits(&br, 7);
- for (i = 0; i < 7; i++)
- if ((mask & (1 << i)))
- registers[i] = membr_next_rarvm_number(&br);
- }
-
- if (!prog)
- {
- uint32_t len = membr_next_rarvm_number(&br);
- uint8_t *bytecode;
- struct rar_program_code **next;
-
- if (len == 0 || len > 0x10000)
- return 0;
- bytecode = malloc(len);
- if (!bytecode)
- return 0;
- for (i = 0; i < len; i++)
- bytecode[i] = (uint8_t)membr_bits(&br, 8);
- prog = compile_program(bytecode, len);
- if (!prog) {
- free(bytecode);
- return 0;
- }
- free(bytecode);
- next = &filters->progs;
- while (*next)
- next = &(*next)->next;
- *next = prog;
- }
- prog->oldfilterlength = blocklength;
-
- globaldata = NULL;
- globaldatalen = 0;
- if ((flags & 0x08))
- {
- globaldatalen = membr_next_rarvm_number(&br);
- if (globaldatalen > PROGRAM_USER_GLOBAL_SIZE)
- return 0;
- globaldata = malloc(globaldatalen + PROGRAM_SYSTEM_GLOBAL_SIZE);
- if (!globaldata)
- return 0;
- for (i = 0; i < globaldatalen; i++)
- globaldata[i + PROGRAM_SYSTEM_GLOBAL_SIZE] = (uint8_t)membr_bits(&br, 8);
- }
-
- if (br.at_eof)
- {
- free(globaldata);
- return 0;
- }
-
- filter = create_filter(prog, globaldata, globaldatalen, registers, blockstartpos, blocklength);
- free(globaldata);
- if (!filter)
- return 0;
-
- for (i = 0; i < 7; i++)
- archive_le32enc(&filter->globaldata[i * 4], registers[i]);
- archive_le32enc(&filter->globaldata[0x1C], blocklength);
- archive_le32enc(&filter->globaldata[0x20], 0);
- archive_le32enc(&filter->globaldata[0x2C], prog->usagecount);
-
- nextfilter = &filters->stack;
- while (*nextfilter)
- nextfilter = &(*nextfilter)->next;
- *nextfilter = filter;
-
- if (!filters->stack->next)
- filters->filterstart = blockstartpos;
-
- return 1;
-}
-
-static struct rar_filter *
-create_filter(struct rar_program_code *prog, const uint8_t *globaldata, uint32_t globaldatalen, uint32_t registers[8], size_t startpos, uint32_t length)
-{
- struct rar_filter *filter;
-
- filter = calloc(1, sizeof(*filter));
- if (!filter)
- return NULL;
- filter->prog = prog;
- filter->globaldatalen = globaldatalen > PROGRAM_SYSTEM_GLOBAL_SIZE ? globaldatalen : PROGRAM_SYSTEM_GLOBAL_SIZE;
- filter->globaldata = calloc(1, filter->globaldatalen);
- if (!filter->globaldata)
- return NULL;
- if (globaldata)
- memcpy(filter->globaldata, globaldata, globaldatalen);
- if (registers)
- memcpy(filter->initialregisters, registers, sizeof(filter->initialregisters));
- filter->blockstartpos = startpos;
- filter->blocklength = length;
-
- return filter;
-}
-
-static int
-run_filters(struct archive_read *a)
-{
- struct rar *rar = (struct rar *)(a->format->data);
- struct rar_filters *filters = &rar->filters;
- struct rar_filter *filter = filters->stack;
- struct rar_filter *f;
- size_t start, end;
- int64_t tend;
- uint32_t lastfilteraddress;
- uint32_t lastfilterlength;
- int ret;
-
- if (filters == NULL || filter == NULL)
- return (0);
-
- start = filters->filterstart;
- end = start + filter->blocklength;
-
- filters->filterstart = INT64_MAX;
- tend = (int64_t)end;
- ret = expand(a, &tend);
- if (ret != ARCHIVE_OK)
- return 0;
-
- /* Check if filter stack was modified in expand() */
- ret = ARCHIVE_FATAL;
- f = filters->stack;
- while (f)
- {
- if (f == filter)
- {
- ret = ARCHIVE_OK;
- break;
- }
- f = f->next;
- }
- if (ret != ARCHIVE_OK)
- return 0;
-
- if (tend < 0)
- return 0;
- end = (size_t)tend;
- if (end != start + filter->blocklength)
- return 0;
-
- if (!filters->vm)
- {
- filters->vm = calloc(1, sizeof(*filters->vm));
- if (!filters->vm)
- return 0;
- }
-
- ret = copy_from_lzss_window(a, filters->vm->memory, start, filter->blocklength);
- if (ret != ARCHIVE_OK)
- return 0;
- if (!execute_filter(a, filter, filters->vm, rar->offset))
- return 0;
-
- lastfilteraddress = filter->filteredblockaddress;
- lastfilterlength = filter->filteredblocklength;
- filters->stack = filter->next;
- filter->next = NULL;
- delete_filter(filter);
-
- while ((filter = filters->stack) != NULL && (int64_t)filter->blockstartpos == filters->filterstart && filter->blocklength == lastfilterlength)
- {
- memmove(&filters->vm->memory[0], &filters->vm->memory[lastfilteraddress], lastfilterlength);
- if (!execute_filter(a, filter, filters->vm, rar->offset))
- return 0;
-
- lastfilteraddress = filter->filteredblockaddress;
- lastfilterlength = filter->filteredblocklength;
- filters->stack = filter->next;
- filter->next = NULL;
- delete_filter(filter);
- }
-
- if (filters->stack)
- {
- if (filters->stack->blockstartpos < end)
- return 0;
- filters->filterstart = filters->stack->blockstartpos;
- }
-
- filters->lastend = end;
- filters->bytes = &filters->vm->memory[lastfilteraddress];
- filters->bytes_ready = lastfilterlength;
-
- return 1;
-}
-
-static struct rar_program_code *
-compile_program(const uint8_t *bytes, size_t length)
-{
- struct memory_bit_reader br = { 0 };
- struct rar_program_code *prog;
- // uint32_t instrcount = 0;
- uint8_t xor;
- size_t i;
-
- xor = 0;
- for (i = 1; i < length; i++)
- xor ^= bytes[i];
- if (!length || xor != bytes[0])
- return NULL;
-
- br.bytes = bytes;
- br.length = length;
- br.offset = 1;
-
- prog = calloc(1, sizeof(*prog));
- if (!prog)
- return NULL;
- prog->fingerprint = crc32(0, bytes, (unsigned int)length) | ((uint64_t)length << 32);
-
- if (membr_bits(&br, 1))
- {
- prog->staticdatalen = membr_next_rarvm_number(&br) + 1;
- prog->staticdata = malloc(prog->staticdatalen);
- if (!prog->staticdata)
- {
- delete_program_code(prog);
- return NULL;
- }
- for (i = 0; i < prog->staticdatalen; i++)
- prog->staticdata[i] = (uint8_t)membr_bits(&br, 8);
- }
-
- return prog;
-}
-
-static void
-delete_filter(struct rar_filter *filter)
-{
- while (filter)
- {
- struct rar_filter *next = filter->next;
- free(filter->globaldata);
- free(filter);
- filter = next;
- }
-}
-
-static void
-clear_filters(struct rar_filters *filters)
-{
- delete_filter(filters->stack);
- delete_program_code(filters->progs);
- free(filters->vm);
-}
-
-static void
-delete_program_code(struct rar_program_code *prog)
-{
- while (prog)
- {
- struct rar_program_code *next = prog->next;
- free(prog->staticdata);
- free(prog->globalbackup);
- free(prog);
- prog = next;
- }
-}
-
-static uint32_t
-membr_next_rarvm_number(struct memory_bit_reader *br)
-{
- uint32_t val;
- switch (membr_bits(br, 2))
- {
- case 0:
- return membr_bits(br, 4);
- case 1:
- val = membr_bits(br, 8);
- if (val >= 16)
- return val;
- return 0xFFFFFF00 | (val << 4) | membr_bits(br, 4);
- case 2:
- return membr_bits(br, 16);
- default:
- return membr_bits(br, 32);
- }
-}
-
-static inline uint32_t
-membr_bits(struct memory_bit_reader *br, int bits)
-{
- if (bits > br->available && (br->at_eof || !membr_fill(br, bits)))
- return 0;
- return (uint32_t)((br->bits >> (br->available -= bits)) & (((uint64_t)1 << bits) - 1));
-}
-
-static int
-membr_fill(struct memory_bit_reader *br, int bits)
-{
- while (br->available < bits && br->offset < br->length)
- {
- br->bits = (br->bits << 8) | br->bytes[br->offset++];
- br->available += 8;
- }
- if (bits > br->available)
- {
- br->at_eof = 1;
- return 0;
- }
- return 1;
-}
-
-static int
-read_filter(struct archive_read *a, int64_t *end)
-{
- struct rar *rar = (struct rar *)(a->format->data);
- uint8_t flags, val, *code;
- uint16_t length, i;
-
- if (!rar_decode_byte(a, &flags))
- return 0;
- length = (flags & 0x07) + 1;
- if (length == 7)
- {
- if (!rar_decode_byte(a, &val))
- return 0;
- length = val + 7;
- }
- else if (length == 8)
- {
- if (!rar_decode_byte(a, &val))
- return 0;
- length = val << 8;
- if (!rar_decode_byte(a, &val))
- return 0;
- length |= val;
- }
-
- code = malloc(length);
- if (!code)
- return 0;
- for (i = 0; i < length; i++)
- {
- if (!rar_decode_byte(a, &code[i]))
- {
- free(code);
- return 0;
- }
- }
- if (!parse_filter(a, code, length, flags))
- {
- free(code);
- return 0;
- }
- free(code);
-
- if (rar->filters.filterstart < *end)
- *end = rar->filters.filterstart;
-
- return 1;
-}
-
-static int
-execute_filter_delta(struct rar_filter *filter, struct rar_virtual_machine *vm)
-{
- uint32_t length = filter->initialregisters[4];
- uint32_t numchannels = filter->initialregisters[0];
- uint8_t *src, *dst;
- uint32_t i, idx;
-
- if (length > PROGRAM_WORK_SIZE / 2)
- return 0;
-
- src = &vm->memory[0];
- dst = &vm->memory[length];
- for (i = 0; i < numchannels; i++)
- {
- uint8_t lastbyte = 0;
- for (idx = i; idx < length; idx += numchannels)
- lastbyte = dst[idx] = lastbyte - *src++;
- }
-
- filter->filteredblockaddress = length;
- filter->filteredblocklength = length;
-
- return 1;
-}
-
-static int
-execute_filter_e8(struct rar_filter *filter, struct rar_virtual_machine *vm, size_t pos, int e9also)
-{
- uint32_t length = filter->initialregisters[4];
- uint32_t filesize = 0x1000000;
- uint32_t i;
-
- if (length > PROGRAM_WORK_SIZE || length < 4)
- return 0;
-
- for (i = 0; i <= length - 5; i++)
- {
- if (vm->memory[i] == 0xE8 || (e9also && vm->memory[i] == 0xE9))
- {
- uint32_t currpos = (uint32_t)pos + i + 1;
- int32_t address = (int32_t)vm_read_32(vm, i + 1);
- if (address < 0 && currpos >= (uint32_t)-address)
- vm_write_32(vm, i + 1, address + filesize);
- else if (address >= 0 && (uint32_t)address < filesize)
- vm_write_32(vm, i + 1, address - currpos);
- i += 4;
- }
- }
-
- filter->filteredblockaddress = 0;
- filter->filteredblocklength = length;
-
- return 1;
-}
-
-static int
-execute_filter_rgb(struct rar_filter *filter, struct rar_virtual_machine *vm)
-{
- uint32_t stride = filter->initialregisters[0];
- uint32_t byteoffset = filter->initialregisters[1];
- uint32_t blocklength = filter->initialregisters[4];
- uint8_t *src, *dst;
- uint32_t i, j;
-
- if (blocklength > PROGRAM_WORK_SIZE / 2 || stride > blocklength)
- return 0;
-
- src = &vm->memory[0];
- dst = &vm->memory[blocklength];
- for (i = 0; i < 3; i++) {
- uint8_t byte = 0;
- uint8_t *prev = dst + i - stride;
- for (j = i; j < blocklength; j += 3)
- {
- if (prev >= dst)
- {
- uint32_t delta1 = abs(prev[3] - prev[0]);
- uint32_t delta2 = abs(byte - prev[0]);
- uint32_t delta3 = abs(prev[3] - prev[0] + byte - prev[0]);
- if (delta1 > delta2 || delta1 > delta3)
- byte = delta2 <= delta3 ? prev[3] : prev[0];
- }
- byte -= *src++;
- dst[j] = byte;
- prev += 3;
- }
- }
- for (i = byteoffset; i < blocklength - 2; i += 3)
- {
- dst[i] += dst[i + 1];
- dst[i + 2] += dst[i + 1];
- }
-
- filter->filteredblockaddress = blocklength;
- filter->filteredblocklength = blocklength;
-
- return 1;
-}
-
-static int
-execute_filter_audio(struct rar_filter *filter, struct rar_virtual_machine *vm)
-{
- uint32_t length = filter->initialregisters[4];
- uint32_t numchannels = filter->initialregisters[0];
- uint8_t *src, *dst;
- uint32_t i, j;
-
- if (length > PROGRAM_WORK_SIZE / 2)
- return 0;
-
- src = &vm->memory[0];
- dst = &vm->memory[length];
- for (i = 0; i < numchannels; i++)
- {
- struct audio_state state;
- memset(&state, 0, sizeof(state));
- for (j = i; j < length; j += numchannels)
- {
- int8_t delta = (int8_t)*src++;
- uint8_t predbyte, byte;
- int prederror;
- state.delta[2] = state.delta[1];
- state.delta[1] = state.lastdelta - state.delta[0];
- state.delta[0] = state.lastdelta;
- predbyte = ((8 * state.lastbyte + state.weight[0] * state.delta[0] + state.weight[1] * state.delta[1] + state.weight[2] * state.delta[2]) >> 3) & 0xFF;
- byte = (predbyte - delta) & 0xFF;
- prederror = delta << 3;
- state.error[0] += abs(prederror);
- state.error[1] += abs(prederror - state.delta[0]); state.error[2] += abs(prederror + state.delta[0]);
- state.error[3] += abs(prederror - state.delta[1]); state.error[4] += abs(prederror + state.delta[1]);
- state.error[5] += abs(prederror - state.delta[2]); state.error[6] += abs(prederror + state.delta[2]);
- state.lastdelta = (int8_t)(byte - state.lastbyte);
- dst[j] = state.lastbyte = byte;
- if (!(state.count++ & 0x1F))
- {
- uint8_t k, idx = 0;
- for (k = 1; k < 7; k++)
- {
- if (state.error[k] < state.error[idx])
- idx = k;
- }
- memset(state.error, 0, sizeof(state.error));
- switch (idx)
- {
- case 1: if (state.weight[0] >= -16) state.weight[0]--; break;
- case 2: if (state.weight[0] < 16) state.weight[0]++; break;
- case 3: if (state.weight[1] >= -16) state.weight[1]--; break;
- case 4: if (state.weight[1] < 16) state.weight[1]++; break;
- case 5: if (state.weight[2] >= -16) state.weight[2]--; break;
- case 6: if (state.weight[2] < 16) state.weight[2]++; break;
- }
- }
- }
- }
-
- filter->filteredblockaddress = length;
- filter->filteredblocklength = length;
-
- return 1;
-}
-
-
-static int
-execute_filter(struct archive_read *a, struct rar_filter *filter, struct rar_virtual_machine *vm, size_t pos)
-{
- if (filter->prog->fingerprint == 0x1D0E06077D)
- return execute_filter_delta(filter, vm);
- if (filter->prog->fingerprint == 0x35AD576887)
- return execute_filter_e8(filter, vm, pos, 0);
- if (filter->prog->fingerprint == 0x393CD7E57E)
- return execute_filter_e8(filter, vm, pos, 1);
- if (filter->prog->fingerprint == 0x951C2C5DC8)
- return execute_filter_rgb(filter, vm);
- if (filter->prog->fingerprint == 0xD8BC85E701)
- return execute_filter_audio(filter, vm);
-
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "No support for RAR VM program filter");
- return 0;
-}
-
-static int
-rar_decode_byte(struct archive_read *a, uint8_t *byte)
-{
- struct rar *rar = (struct rar *)(a->format->data);
- struct rar_br *br = &(rar->br);
- if (!rar_br_read_ahead(a, br, 8))
- return 0;
- *byte = (uint8_t)rar_br_bits(br, 8);
- rar_br_consume(br, 8);
- return 1;
-}
-
-static inline void
-vm_write_32(struct rar_virtual_machine* vm, size_t offset, uint32_t u32)
-{
- archive_le32enc(vm->memory + offset, u32);
-}
-
-static inline uint32_t
-vm_read_32(struct rar_virtual_machine* vm, size_t offset)
-{
- return archive_le32dec(vm->memory + offset);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_format_rar5.c b/contrib/libs/libarchive/libarchive/archive_read_support_format_rar5.c
deleted file mode 100644
index 52fe8b10ff..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_format_rar5.c
+++ /dev/null
@@ -1,4251 +0,0 @@
-/*-
-* Copyright (c) 2018 Grzegorz Antoniak (http://antoniak.org)
-* 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(S) ``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(S) 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 "archive_platform.h"
-#include "archive_endian.h"
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <time.h>
-#ifdef HAVE_ZLIB_H
-#include <zlib.h> /* crc32 */
-#endif
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-
-#include "archive.h"
-#ifndef HAVE_ZLIB_H
-#error #include "archive_crc32.h"
-#endif
-
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_ppmd7_private.h"
-#include "archive_entry_private.h"
-
-#ifdef HAVE_BLAKE2_H
-#include <blake2.h>
-#else
-#error #include "archive_blake2.h"
-#endif
-
-/*#define CHECK_CRC_ON_SOLID_SKIP*/
-/*#define DONT_FAIL_ON_CRC_ERROR*/
-/*#define DEBUG*/
-
-#define rar5_min(a, b) (((a) > (b)) ? (b) : (a))
-#define rar5_max(a, b) (((a) > (b)) ? (a) : (b))
-#define rar5_countof(X) ((const ssize_t) (sizeof(X) / sizeof(*X)))
-
-#if defined DEBUG
-#define DEBUG_CODE if(1)
-#define LOG(...) do { printf("rar5: " __VA_ARGS__); puts(""); } while(0)
-#else
-#define DEBUG_CODE if(0)
-#endif
-
-/* Real RAR5 magic number is:
- *
- * 0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x01, 0x00
- * "Rar!→•☺·\x00"
- *
- * Retrieved with `rar5_signature()` by XOR'ing it with 0xA1, because I don't
- * want to put this magic sequence in each binary that uses libarchive, so
- * applications that scan through the file for this marker won't trigger on
- * this "false" one.
- *
- * The array itself is decrypted in `rar5_init` function. */
-
-static unsigned char rar5_signature_xor[] = { 243, 192, 211, 128, 187, 166, 160, 161 };
-static const size_t g_unpack_window_size = 0x20000;
-
-/* These could have been static const's, but they aren't, because of
- * Visual Studio. */
-#define MAX_NAME_IN_CHARS 2048
-#define MAX_NAME_IN_BYTES (4 * MAX_NAME_IN_CHARS)
-
-struct file_header {
- ssize_t bytes_remaining;
- ssize_t unpacked_size;
- int64_t last_offset; /* Used in sanity checks. */
- int64_t last_size; /* Used in sanity checks. */
-
- uint8_t solid : 1; /* Is this a solid stream? */
- uint8_t service : 1; /* Is this file a service data? */
- uint8_t eof : 1; /* Did we finish unpacking the file? */
- uint8_t dir : 1; /* Is this file entry a directory? */
-
- /* Optional time fields. */
- uint64_t e_mtime;
- uint64_t e_ctime;
- uint64_t e_atime;
- uint32_t e_unix_ns;
-
- /* Optional hash fields. */
- uint32_t stored_crc32;
- uint32_t calculated_crc32;
- uint8_t blake2sp[32];
- blake2sp_state b2state;
- char has_blake2;
-
- /* Optional redir fields */
- uint64_t redir_type;
- uint64_t redir_flags;
-
- ssize_t solid_window_size; /* Used in file format check. */
-};
-
-enum EXTRA {
- EX_CRYPT = 0x01,
- EX_HASH = 0x02,
- EX_HTIME = 0x03,
- EX_VERSION = 0x04,
- EX_REDIR = 0x05,
- EX_UOWNER = 0x06,
- EX_SUBDATA = 0x07
-};
-
-#define REDIR_SYMLINK_IS_DIR 1
-
-enum REDIR_TYPE {
- REDIR_TYPE_NONE = 0,
- REDIR_TYPE_UNIXSYMLINK = 1,
- REDIR_TYPE_WINSYMLINK = 2,
- REDIR_TYPE_JUNCTION = 3,
- REDIR_TYPE_HARDLINK = 4,
- REDIR_TYPE_FILECOPY = 5,
-};
-
-#define OWNER_USER_NAME 0x01
-#define OWNER_GROUP_NAME 0x02
-#define OWNER_USER_UID 0x04
-#define OWNER_GROUP_GID 0x08
-#define OWNER_MAXNAMELEN 256
-
-enum FILTER_TYPE {
- FILTER_DELTA = 0, /* Generic pattern. */
- FILTER_E8 = 1, /* Intel x86 code. */
- FILTER_E8E9 = 2, /* Intel x86 code. */
- FILTER_ARM = 3, /* ARM code. */
- FILTER_AUDIO = 4, /* Audio filter, not used in RARv5. */
- FILTER_RGB = 5, /* Color palette, not used in RARv5. */
- FILTER_ITANIUM = 6, /* Intel's Itanium, not used in RARv5. */
- FILTER_PPM = 7, /* Predictive pattern matching, not used in
- RARv5. */
- FILTER_NONE = 8,
-};
-
-struct filter_info {
- int type;
- int channels;
- int pos_r;
-
- int64_t block_start;
- ssize_t block_length;
- uint16_t width;
-};
-
-struct data_ready {
- char used;
- const uint8_t* buf;
- size_t size;
- int64_t offset;
-};
-
-struct cdeque {
- uint16_t beg_pos;
- uint16_t end_pos;
- uint16_t cap_mask;
- uint16_t size;
- size_t* arr;
-};
-
-struct decode_table {
- uint32_t size;
- int32_t decode_len[16];
- uint32_t decode_pos[16];
- uint32_t quick_bits;
- uint8_t quick_len[1 << 10];
- uint16_t quick_num[1 << 10];
- uint16_t decode_num[306];
-};
-
-struct comp_state {
- /* Flag used to specify if unpacker needs to reinitialize the
- uncompression context. */
- uint8_t initialized : 1;
-
- /* Flag used when applying filters. */
- uint8_t all_filters_applied : 1;
-
- /* Flag used to skip file context reinitialization, used when unpacker
- is skipping through different multivolume archives. */
- uint8_t switch_multivolume : 1;
-
- /* Flag used to specify if unpacker has processed the whole data block
- or just a part of it. */
- uint8_t block_parsing_finished : 1;
-
- signed int notused : 4;
-
- int flags; /* Uncompression flags. */
- int method; /* Uncompression algorithm method. */
- int version; /* Uncompression algorithm version. */
- ssize_t window_size; /* Size of window_buf. */
- uint8_t* window_buf; /* Circular buffer used during
- decompression. */
- uint8_t* filtered_buf; /* Buffer used when applying filters. */
- const uint8_t* block_buf; /* Buffer used when merging blocks. */
- size_t window_mask; /* Convenience field; window_size - 1. */
- int64_t write_ptr; /* This amount of data has been unpacked
- in the window buffer. */
- int64_t last_write_ptr; /* This amount of data has been stored in
- the output file. */
- int64_t last_unstore_ptr; /* Counter of bytes extracted during
- unstoring. This is separate from
- last_write_ptr because of how SERVICE
- base blocks are handled during skipping
- in solid multiarchive archives. */
- int64_t solid_offset; /* Additional offset inside the window
- buffer, used in unpacking solid
- archives. */
- ssize_t cur_block_size; /* Size of current data block. */
- int last_len; /* Flag used in lzss decompression. */
-
- /* Decode tables used during lzss uncompression. */
-
-#define HUFF_BC 20
- struct decode_table bd; /* huffman bit lengths */
-#define HUFF_NC 306
- struct decode_table ld; /* literals */
-#define HUFF_DC 64
- struct decode_table dd; /* distances */
-#define HUFF_LDC 16
- struct decode_table ldd; /* lower bits of distances */
-#define HUFF_RC 44
- struct decode_table rd; /* repeating distances */
-#define HUFF_TABLE_SIZE (HUFF_NC + HUFF_DC + HUFF_RC + HUFF_LDC)
-
- /* Circular deque for storing filters. */
- struct cdeque filters;
- int64_t last_block_start; /* Used for sanity checking. */
- ssize_t last_block_length; /* Used for sanity checking. */
-
- /* Distance cache used during lzss uncompression. */
- int dist_cache[4];
-
- /* Data buffer stack. */
- struct data_ready dready[2];
-};
-
-/* Bit reader state. */
-struct bit_reader {
- int8_t bit_addr; /* Current bit pointer inside current byte. */
- int in_addr; /* Current byte pointer. */
-};
-
-/* RARv5 block header structure. Use bf_* functions to get values from
- * block_flags_u8 field. I.e. bf_byte_count, etc. */
-struct compressed_block_header {
- /* block_flags_u8 contain fields encoded in little-endian bitfield:
- *
- * - table present flag (shr 7, and 1),
- * - last block flag (shr 6, and 1),
- * - byte_count (shr 3, and 7),
- * - bit_size (shr 0, and 7).
- */
- uint8_t block_flags_u8;
- uint8_t block_cksum;
-};
-
-/* RARv5 main header structure. */
-struct main_header {
- /* Does the archive contain solid streams? */
- uint8_t solid : 1;
-
- /* If this a multi-file archive? */
- uint8_t volume : 1;
- uint8_t endarc : 1;
- uint8_t notused : 5;
-
- unsigned int vol_no;
-};
-
-struct generic_header {
- uint8_t split_after : 1;
- uint8_t split_before : 1;
- uint8_t padding : 6;
- int size;
- int last_header_id;
-};
-
-struct multivolume {
- unsigned int expected_vol_no;
- uint8_t* push_buf;
-};
-
-/* Main context structure. */
-struct rar5 {
- int header_initialized;
-
- /* Set to 1 if current file is positioned AFTER the magic value
- * of the archive file. This is used in header reading functions. */
- int skipped_magic;
-
- /* Set to not zero if we're in skip mode (either by calling
- * rar5_data_skip function or when skipping over solid streams).
- * Set to 0 when in * extraction mode. This is used during checksum
- * calculation functions. */
- int skip_mode;
-
- /* Set to not zero if we're in block merging mode (i.e. when switching
- * to another file in multivolume archive, last block from 1st archive
- * needs to be merged with 1st block from 2nd archive). This flag
- * guards against recursive use of the merging function, which doesn't
- * support recursive calls. */
- int merge_mode;
-
- /* An offset to QuickOpen list. This is not supported by this unpacker,
- * because we're focusing on streaming interface. QuickOpen is designed
- * to make things quicker for non-stream interfaces, so it's not our
- * use case. */
- uint64_t qlist_offset;
-
- /* An offset to additional Recovery data. This is not supported by this
- * unpacker. Recovery data are additional Reed-Solomon codes that could
- * be used to calculate bytes that are missing in archive or are
- * corrupted. */
- uint64_t rr_offset;
-
- /* Various context variables grouped to different structures. */
- struct generic_header generic;
- struct main_header main;
- struct comp_state cstate;
- struct file_header file;
- struct bit_reader bits;
- struct multivolume vol;
-
- /* The header of currently processed RARv5 block. Used in main
- * decompression logic loop. */
- struct compressed_block_header last_block_hdr;
-};
-
-/* Forward function declarations. */
-
-static void rar5_signature(char *buf);
-static int verify_global_checksums(struct archive_read* a);
-static int rar5_read_data_skip(struct archive_read *a);
-static int push_data_ready(struct archive_read* a, struct rar5* rar,
- const uint8_t* buf, size_t size, int64_t offset);
-
-/* CDE_xxx = Circular Double Ended (Queue) return values. */
-enum CDE_RETURN_VALUES {
- CDE_OK, CDE_ALLOC, CDE_PARAM, CDE_OUT_OF_BOUNDS,
-};
-
-/* Clears the contents of this circular deque. */
-static void cdeque_clear(struct cdeque* d) {
- d->size = 0;
- d->beg_pos = 0;
- d->end_pos = 0;
-}
-
-/* Creates a new circular deque object. Capacity must be power of 2: 8, 16, 32,
- * 64, 256, etc. When the user will add another item above current capacity,
- * the circular deque will overwrite the oldest entry. */
-static int cdeque_init(struct cdeque* d, int max_capacity_power_of_2) {
- if(d == NULL || max_capacity_power_of_2 == 0)
- return CDE_PARAM;
-
- d->cap_mask = max_capacity_power_of_2 - 1;
- d->arr = NULL;
-
- if((max_capacity_power_of_2 & d->cap_mask) != 0)
- return CDE_PARAM;
-
- cdeque_clear(d);
- d->arr = malloc(sizeof(void*) * max_capacity_power_of_2);
-
- return d->arr ? CDE_OK : CDE_ALLOC;
-}
-
-/* Return the current size (not capacity) of circular deque `d`. */
-static size_t cdeque_size(struct cdeque* d) {
- return d->size;
-}
-
-/* Returns the first element of current circular deque. Note that this function
- * doesn't perform any bounds checking. If you need bounds checking, use
- * `cdeque_front()` function instead. */
-static void cdeque_front_fast(struct cdeque* d, void** value) {
- *value = (void*) d->arr[d->beg_pos];
-}
-
-/* Returns the first element of current circular deque. This function
- * performs bounds checking. */
-static int cdeque_front(struct cdeque* d, void** value) {
- if(d->size > 0) {
- cdeque_front_fast(d, value);
- return CDE_OK;
- } else
- return CDE_OUT_OF_BOUNDS;
-}
-
-/* Pushes a new element into the end of this circular deque object. If current
- * size will exceed capacity, the oldest element will be overwritten. */
-static int cdeque_push_back(struct cdeque* d, void* item) {
- if(d == NULL)
- return CDE_PARAM;
-
- if(d->size == d->cap_mask + 1)
- return CDE_OUT_OF_BOUNDS;
-
- d->arr[d->end_pos] = (size_t) item;
- d->end_pos = (d->end_pos + 1) & d->cap_mask;
- d->size++;
-
- return CDE_OK;
-}
-
-/* Pops a front element of this circular deque object and returns its value.
- * This function doesn't perform any bounds checking. */
-static void cdeque_pop_front_fast(struct cdeque* d, void** value) {
- *value = (void*) d->arr[d->beg_pos];
- d->beg_pos = (d->beg_pos + 1) & d->cap_mask;
- d->size--;
-}
-
-/* Pops a front element of this circular deque object and returns its value.
- * This function performs bounds checking. */
-static int cdeque_pop_front(struct cdeque* d, void** value) {
- if(!d || !value)
- return CDE_PARAM;
-
- if(d->size == 0)
- return CDE_OUT_OF_BOUNDS;
-
- cdeque_pop_front_fast(d, value);
- return CDE_OK;
-}
-
-/* Convenience function to cast filter_info** to void **. */
-static void** cdeque_filter_p(struct filter_info** f) {
- return (void**) (size_t) f;
-}
-
-/* Convenience function to cast filter_info* to void *. */
-static void* cdeque_filter(struct filter_info* f) {
- return (void**) (size_t) f;
-}
-
-/* Destroys this circular deque object. Deallocates the memory of the
- * collection buffer, but doesn't deallocate the memory of any pointer passed
- * to this deque as a value. */
-static void cdeque_free(struct cdeque* d) {
- if(!d)
- return;
-
- if(!d->arr)
- return;
-
- free(d->arr);
-
- d->arr = NULL;
- d->beg_pos = -1;
- d->end_pos = -1;
- d->cap_mask = 0;
-}
-
-static inline
-uint8_t bf_bit_size(const struct compressed_block_header* hdr) {
- return hdr->block_flags_u8 & 7;
-}
-
-static inline
-uint8_t bf_byte_count(const struct compressed_block_header* hdr) {
- return (hdr->block_flags_u8 >> 3) & 7;
-}
-
-static inline
-uint8_t bf_is_table_present(const struct compressed_block_header* hdr) {
- return (hdr->block_flags_u8 >> 7) & 1;
-}
-
-static inline struct rar5* get_context(struct archive_read* a) {
- return (struct rar5*) a->format->data;
-}
-
-/* Convenience functions used by filter implementations. */
-static void circular_memcpy(uint8_t* dst, uint8_t* window, const uint64_t mask,
- int64_t start, int64_t end)
-{
- if((start & mask) > (end & mask)) {
- ssize_t len1 = mask + 1 - (start & mask);
- ssize_t len2 = end & mask;
-
- memcpy(dst, &window[start & mask], len1);
- memcpy(dst + len1, window, len2);
- } else {
- memcpy(dst, &window[start & mask], (size_t) (end - start));
- }
-}
-
-static uint32_t read_filter_data(struct rar5* rar, uint32_t offset) {
- uint8_t linear_buf[4];
- circular_memcpy(linear_buf, rar->cstate.window_buf,
- rar->cstate.window_mask, offset, offset + 4);
- return archive_le32dec(linear_buf);
-}
-
-static void write_filter_data(struct rar5* rar, uint32_t offset,
- uint32_t value)
-{
- archive_le32enc(&rar->cstate.filtered_buf[offset], value);
-}
-
-/* Allocates a new filter descriptor and adds it to the filter array. */
-static struct filter_info* add_new_filter(struct rar5* rar) {
- struct filter_info* f =
- (struct filter_info*) calloc(1, sizeof(struct filter_info));
-
- if(!f) {
- return NULL;
- }
-
- cdeque_push_back(&rar->cstate.filters, cdeque_filter(f));
- return f;
-}
-
-static int run_delta_filter(struct rar5* rar, struct filter_info* flt) {
- int i;
- ssize_t dest_pos, src_pos = 0;
-
- for(i = 0; i < flt->channels; i++) {
- uint8_t prev_byte = 0;
- for(dest_pos = i;
- dest_pos < flt->block_length;
- dest_pos += flt->channels)
- {
- uint8_t byte;
-
- byte = rar->cstate.window_buf[
- (rar->cstate.solid_offset + flt->block_start +
- src_pos) & rar->cstate.window_mask];
-
- prev_byte -= byte;
- rar->cstate.filtered_buf[dest_pos] = prev_byte;
- src_pos++;
- }
- }
-
- return ARCHIVE_OK;
-}
-
-static int run_e8e9_filter(struct rar5* rar, struct filter_info* flt,
- int extended)
-{
- const uint32_t file_size = 0x1000000;
- ssize_t i;
-
- circular_memcpy(rar->cstate.filtered_buf,
- rar->cstate.window_buf, rar->cstate.window_mask,
- rar->cstate.solid_offset + flt->block_start,
- rar->cstate.solid_offset + flt->block_start + flt->block_length);
-
- for(i = 0; i < flt->block_length - 4;) {
- uint8_t b = rar->cstate.window_buf[
- (rar->cstate.solid_offset + flt->block_start +
- i++) & rar->cstate.window_mask];
-
- /*
- * 0xE8 = x86's call <relative_addr_uint32> (function call)
- * 0xE9 = x86's jmp <relative_addr_uint32> (unconditional jump)
- */
- if(b == 0xE8 || (extended && b == 0xE9)) {
-
- uint32_t addr;
- uint32_t offset = (i + flt->block_start) % file_size;
-
- addr = read_filter_data(rar,
- (uint32_t)(rar->cstate.solid_offset +
- flt->block_start + i) & rar->cstate.window_mask);
-
- if(addr & 0x80000000) {
- if(((addr + offset) & 0x80000000) == 0) {
- write_filter_data(rar, (uint32_t)i,
- addr + file_size);
- }
- } else {
- if((addr - file_size) & 0x80000000) {
- uint32_t naddr = addr - offset;
- write_filter_data(rar, (uint32_t)i,
- naddr);
- }
- }
-
- i += 4;
- }
- }
-
- return ARCHIVE_OK;
-}
-
-static int run_arm_filter(struct rar5* rar, struct filter_info* flt) {
- ssize_t i = 0;
- uint32_t offset;
-
- circular_memcpy(rar->cstate.filtered_buf,
- rar->cstate.window_buf, rar->cstate.window_mask,
- rar->cstate.solid_offset + flt->block_start,
- rar->cstate.solid_offset + flt->block_start + flt->block_length);
-
- for(i = 0; i < flt->block_length - 3; i += 4) {
- uint8_t* b = &rar->cstate.window_buf[
- (rar->cstate.solid_offset +
- flt->block_start + i + 3) & rar->cstate.window_mask];
-
- if(*b == 0xEB) {
- /* 0xEB = ARM's BL (branch + link) instruction. */
- offset = read_filter_data(rar,
- (rar->cstate.solid_offset + flt->block_start + i) &
- (uint32_t)rar->cstate.window_mask) & 0x00ffffff;
-
- offset -= (uint32_t) ((i + flt->block_start) / 4);
- offset = (offset & 0x00ffffff) | 0xeb000000;
- write_filter_data(rar, (uint32_t)i, offset);
- }
- }
-
- return ARCHIVE_OK;
-}
-
-static int run_filter(struct archive_read* a, struct filter_info* flt) {
- int ret;
- struct rar5* rar = get_context(a);
-
- free(rar->cstate.filtered_buf);
-
- rar->cstate.filtered_buf = malloc(flt->block_length);
- if(!rar->cstate.filtered_buf) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for filter data.");
- return ARCHIVE_FATAL;
- }
-
- switch(flt->type) {
- case FILTER_DELTA:
- ret = run_delta_filter(rar, flt);
- break;
-
- case FILTER_E8:
- /* fallthrough */
- case FILTER_E8E9:
- ret = run_e8e9_filter(rar, flt,
- flt->type == FILTER_E8E9);
- break;
-
- case FILTER_ARM:
- ret = run_arm_filter(rar, flt);
- break;
-
- default:
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Unsupported filter type: 0x%x", flt->type);
- return ARCHIVE_FATAL;
- }
-
- if(ret != ARCHIVE_OK) {
- /* Filter has failed. */
- return ret;
- }
-
- if(ARCHIVE_OK != push_data_ready(a, rar, rar->cstate.filtered_buf,
- flt->block_length, rar->cstate.last_write_ptr))
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Stack overflow when submitting unpacked data");
-
- return ARCHIVE_FATAL;
- }
-
- rar->cstate.last_write_ptr += flt->block_length;
- return ARCHIVE_OK;
-}
-
-/* The `push_data` function submits the selected data range to the user.
- * Next call of `use_data` will use the pointer, size and offset arguments
- * that are specified here. These arguments are pushed to the FIFO stack here,
- * and popped from the stack by the `use_data` function. */
-static void push_data(struct archive_read* a, struct rar5* rar,
- const uint8_t* buf, int64_t idx_begin, int64_t idx_end)
-{
- const uint64_t wmask = rar->cstate.window_mask;
- const ssize_t solid_write_ptr = (rar->cstate.solid_offset +
- rar->cstate.last_write_ptr) & wmask;
-
- idx_begin += rar->cstate.solid_offset;
- idx_end += rar->cstate.solid_offset;
-
- /* Check if our unpacked data is wrapped inside the window circular
- * buffer. If it's not wrapped, it can be copied out by using
- * a single memcpy, but when it's wrapped, we need to copy the first
- * part with one memcpy, and the second part with another memcpy. */
-
- if((idx_begin & wmask) > (idx_end & wmask)) {
- /* The data is wrapped (begin offset sis bigger than end
- * offset). */
- const ssize_t frag1_size = rar->cstate.window_size -
- (idx_begin & wmask);
- const ssize_t frag2_size = idx_end & wmask;
-
- /* Copy the first part of the buffer first. */
- push_data_ready(a, rar, buf + solid_write_ptr, frag1_size,
- rar->cstate.last_write_ptr);
-
- /* Copy the second part of the buffer. */
- push_data_ready(a, rar, buf, frag2_size,
- rar->cstate.last_write_ptr + frag1_size);
-
- rar->cstate.last_write_ptr += frag1_size + frag2_size;
- } else {
- /* Data is not wrapped, so we can just use one call to copy the
- * data. */
- push_data_ready(a, rar,
- buf + solid_write_ptr, (idx_end - idx_begin) & wmask,
- rar->cstate.last_write_ptr);
-
- rar->cstate.last_write_ptr += idx_end - idx_begin;
- }
-}
-
-/* Convenience function that submits the data to the user. It uses the
- * unpack window buffer as a source location. */
-static void push_window_data(struct archive_read* a, struct rar5* rar,
- int64_t idx_begin, int64_t idx_end)
-{
- push_data(a, rar, rar->cstate.window_buf, idx_begin, idx_end);
-}
-
-static int apply_filters(struct archive_read* a) {
- struct filter_info* flt;
- struct rar5* rar = get_context(a);
- int ret;
-
- rar->cstate.all_filters_applied = 0;
-
- /* Get the first filter that can be applied to our data. The data
- * needs to be fully unpacked before the filter can be run. */
- if(CDE_OK == cdeque_front(&rar->cstate.filters,
- cdeque_filter_p(&flt))) {
- /* Check if our unpacked data fully covers this filter's
- * range. */
- if(rar->cstate.write_ptr > flt->block_start &&
- rar->cstate.write_ptr >= flt->block_start +
- flt->block_length) {
- /* Check if we have some data pending to be written
- * right before the filter's start offset. */
- if(rar->cstate.last_write_ptr == flt->block_start) {
- /* Run the filter specified by descriptor
- * `flt`. */
- ret = run_filter(a, flt);
- if(ret != ARCHIVE_OK) {
- /* Filter failure, return error. */
- return ret;
- }
-
- /* Filter descriptor won't be needed anymore
- * after it's used, * so remove it from the
- * filter list and free its memory. */
- (void) cdeque_pop_front(&rar->cstate.filters,
- cdeque_filter_p(&flt));
-
- free(flt);
- } else {
- /* We can't run filters yet, dump the memory
- * right before the filter. */
- push_window_data(a, rar,
- rar->cstate.last_write_ptr,
- flt->block_start);
- }
-
- /* Return 'filter applied or not needed' state to the
- * caller. */
- return ARCHIVE_RETRY;
- }
- }
-
- rar->cstate.all_filters_applied = 1;
- return ARCHIVE_OK;
-}
-
-static void dist_cache_push(struct rar5* rar, int value) {
- int* q = rar->cstate.dist_cache;
-
- q[3] = q[2];
- q[2] = q[1];
- q[1] = q[0];
- q[0] = value;
-}
-
-static int dist_cache_touch(struct rar5* rar, int idx) {
- int* q = rar->cstate.dist_cache;
- int i, dist = q[idx];
-
- for(i = idx; i > 0; i--)
- q[i] = q[i - 1];
-
- q[0] = dist;
- return dist;
-}
-
-static void free_filters(struct rar5* rar) {
- struct cdeque* d = &rar->cstate.filters;
-
- /* Free any remaining filters. All filters should be naturally
- * consumed by the unpacking function, so remaining filters after
- * unpacking normally mean that unpacking wasn't successful.
- * But still of course we shouldn't leak memory in such case. */
-
- /* cdeque_size() is a fast operation, so we can use it as a loop
- * expression. */
- while(cdeque_size(d) > 0) {
- struct filter_info* f = NULL;
-
- /* Pop_front will also decrease the collection's size. */
- if (CDE_OK == cdeque_pop_front(d, cdeque_filter_p(&f)))
- free(f);
- }
-
- cdeque_clear(d);
-
- /* Also clear out the variables needed for sanity checking. */
- rar->cstate.last_block_start = 0;
- rar->cstate.last_block_length = 0;
-}
-
-static void reset_file_context(struct rar5* rar) {
- memset(&rar->file, 0, sizeof(rar->file));
- blake2sp_init(&rar->file.b2state, 32);
-
- if(rar->main.solid) {
- rar->cstate.solid_offset += rar->cstate.write_ptr;
- } else {
- rar->cstate.solid_offset = 0;
- }
-
- rar->cstate.write_ptr = 0;
- rar->cstate.last_write_ptr = 0;
- rar->cstate.last_unstore_ptr = 0;
-
- rar->file.redir_type = REDIR_TYPE_NONE;
- rar->file.redir_flags = 0;
-
- free_filters(rar);
-}
-
-static inline int get_archive_read(struct archive* a,
- struct archive_read** ar)
-{
- *ar = (struct archive_read*) a;
- archive_check_magic(a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
- "archive_read_support_format_rar5");
-
- return ARCHIVE_OK;
-}
-
-static int read_ahead(struct archive_read* a, size_t how_many,
- const uint8_t** ptr)
-{
- ssize_t avail = -1;
- if(!ptr)
- return 0;
-
- *ptr = __archive_read_ahead(a, how_many, &avail);
- if(*ptr == NULL) {
- return 0;
- }
-
- return 1;
-}
-
-static int consume(struct archive_read* a, int64_t how_many) {
- int ret;
-
- ret = how_many == __archive_read_consume(a, how_many)
- ? ARCHIVE_OK
- : ARCHIVE_FATAL;
-
- return ret;
-}
-
-/**
- * Read a RAR5 variable sized numeric value. This value will be stored in
- * `pvalue`. The `pvalue_len` argument points to a variable that will receive
- * the byte count that was consumed in order to decode the `pvalue` value, plus
- * one.
- *
- * pvalue_len is optional and can be NULL.
- *
- * NOTE: if `pvalue_len` is NOT NULL, the caller needs to manually consume
- * the number of bytes that `pvalue_len` value contains. If the `pvalue_len`
- * is NULL, this consuming operation is done automatically.
- *
- * Returns 1 if *pvalue was successfully read.
- * Returns 0 if there was an error. In this case, *pvalue contains an
- * invalid value.
- */
-
-static int read_var(struct archive_read* a, uint64_t* pvalue,
- uint64_t* pvalue_len)
-{
- uint64_t result = 0;
- size_t shift, i;
- const uint8_t* p;
- uint8_t b;
-
- /* We will read maximum of 8 bytes. We don't have to handle the
- * situation to read the RAR5 variable-sized value stored at the end of
- * the file, because such situation will never happen. */
- if(!read_ahead(a, 8, &p))
- return 0;
-
- for(shift = 0, i = 0; i < 8; i++, shift += 7) {
- b = p[i];
-
- /* Strip the MSB from the input byte and add the resulting
- * number to the `result`. */
- result += (b & (uint64_t)0x7F) << shift;
-
- /* MSB set to 1 means we need to continue decoding process.
- * MSB set to 0 means we're done.
- *
- * This conditional checks for the second case. */
- if((b & 0x80) == 0) {
- if(pvalue) {
- *pvalue = result;
- }
-
- /* If the caller has passed the `pvalue_len` pointer,
- * store the number of consumed bytes in it and do NOT
- * consume those bytes, since the caller has all the
- * information it needs to perform */
- if(pvalue_len) {
- *pvalue_len = 1 + i;
- } else {
- /* If the caller did not provide the
- * `pvalue_len` pointer, it will not have the
- * possibility to advance the file pointer,
- * because it will not know how many bytes it
- * needs to consume. This is why we handle
- * such situation here automatically. */
- if(ARCHIVE_OK != consume(a, 1 + i)) {
- return 0;
- }
- }
-
- /* End of decoding process, return success. */
- return 1;
- }
- }
-
- /* The decoded value takes the maximum number of 8 bytes.
- * It's a maximum number of bytes, so end decoding process here
- * even if the first bit of last byte is 1. */
- if(pvalue) {
- *pvalue = result;
- }
-
- if(pvalue_len) {
- *pvalue_len = 9;
- } else {
- if(ARCHIVE_OK != consume(a, 9)) {
- return 0;
- }
- }
-
- return 1;
-}
-
-static int read_var_sized(struct archive_read* a, size_t* pvalue,
- size_t* pvalue_len)
-{
- uint64_t v;
- uint64_t v_size = 0;
-
- const int ret = pvalue_len ? read_var(a, &v, &v_size)
- : read_var(a, &v, NULL);
-
- if(ret == 1 && pvalue) {
- *pvalue = (size_t) v;
- }
-
- if(pvalue_len) {
- /* Possible data truncation should be safe. */
- *pvalue_len = (size_t) v_size;
- }
-
- return ret;
-}
-
-static int read_bits_32(struct archive_read* a, struct rar5* rar,
- const uint8_t* p, uint32_t* value)
-{
- if(rar->bits.in_addr >= rar->cstate.cur_block_size) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_PROGRAMMER,
- "Premature end of stream during extraction of data (#1)");
- return ARCHIVE_FATAL;
- }
-
- uint32_t bits = ((uint32_t) p[rar->bits.in_addr]) << 24;
- bits |= p[rar->bits.in_addr + 1] << 16;
- bits |= p[rar->bits.in_addr + 2] << 8;
- bits |= p[rar->bits.in_addr + 3];
- bits <<= rar->bits.bit_addr;
- bits |= p[rar->bits.in_addr + 4] >> (8 - rar->bits.bit_addr);
- *value = bits;
- return ARCHIVE_OK;
-}
-
-static int read_bits_16(struct archive_read* a, struct rar5* rar,
- const uint8_t* p, uint16_t* value)
-{
- if(rar->bits.in_addr >= rar->cstate.cur_block_size) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_PROGRAMMER,
- "Premature end of stream during extraction of data (#2)");
- return ARCHIVE_FATAL;
- }
-
- int bits = (int) ((uint32_t) p[rar->bits.in_addr]) << 16;
- bits |= (int) p[rar->bits.in_addr + 1] << 8;
- bits |= (int) p[rar->bits.in_addr + 2];
- bits >>= (8 - rar->bits.bit_addr);
- *value = bits & 0xffff;
- return ARCHIVE_OK;
-}
-
-static void skip_bits(struct rar5* rar, int bits) {
- const int new_bits = rar->bits.bit_addr + bits;
- rar->bits.in_addr += new_bits >> 3;
- rar->bits.bit_addr = new_bits & 7;
-}
-
-/* n = up to 16 */
-static int read_consume_bits(struct archive_read* a, struct rar5* rar,
- const uint8_t* p, int n, int* value)
-{
- uint16_t v;
- int ret, num;
-
- if(n == 0 || n > 16) {
- /* This is a programmer error and should never happen
- * in runtime. */
- return ARCHIVE_FATAL;
- }
-
- ret = read_bits_16(a, rar, p, &v);
- if(ret != ARCHIVE_OK)
- return ret;
-
- num = (int) v;
- num >>= 16 - n;
-
- skip_bits(rar, n);
-
- if(value)
- *value = num;
-
- return ARCHIVE_OK;
-}
-
-static int read_u32(struct archive_read* a, uint32_t* pvalue) {
- const uint8_t* p;
- if(!read_ahead(a, 4, &p))
- return 0;
-
- *pvalue = archive_le32dec(p);
- return ARCHIVE_OK == consume(a, 4) ? 1 : 0;
-}
-
-static int read_u64(struct archive_read* a, uint64_t* pvalue) {
- const uint8_t* p;
- if(!read_ahead(a, 8, &p))
- return 0;
-
- *pvalue = archive_le64dec(p);
- return ARCHIVE_OK == consume(a, 8) ? 1 : 0;
-}
-
-static int bid_standard(struct archive_read* a) {
- const uint8_t* p;
- char signature[sizeof(rar5_signature_xor)];
-
- rar5_signature(signature);
-
- if(!read_ahead(a, sizeof(rar5_signature_xor), &p))
- return -1;
-
- if(!memcmp(signature, p, sizeof(rar5_signature_xor)))
- return 30;
-
- return -1;
-}
-
-static int bid_sfx(struct archive_read *a)
-{
- const char *p;
-
- if ((p = __archive_read_ahead(a, 7, NULL)) == NULL)
- return -1;
-
- if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) {
- /* This is a PE file */
- char signature[sizeof(rar5_signature_xor)];
- ssize_t offset = 0x10000;
- ssize_t window = 4096;
- ssize_t bytes_avail;
-
- rar5_signature(signature);
-
- while (offset + window <= (1024 * 512)) {
- const char *buff = __archive_read_ahead(a, offset + window, &bytes_avail);
- if (buff == NULL) {
- /* Remaining bytes are less than window. */
- window >>= 1;
- if (window < 0x40)
- return 0;
- continue;
- }
- p = buff + offset;
- while (p + 8 < buff + bytes_avail) {
- if (memcmp(p, signature, sizeof(signature)) == 0)
- return 30;
- p += 0x10;
- }
- offset = p - buff;
- }
- }
-
- return 0;
-}
-
-static int rar5_bid(struct archive_read* a, int best_bid) {
- int my_bid;
-
- if(best_bid > 30)
- return -1;
-
- my_bid = bid_standard(a);
- if(my_bid > -1) {
- return my_bid;
- }
- my_bid = bid_sfx(a);
- if (my_bid > -1) {
- return my_bid;
- }
-
- return -1;
-}
-
-static int rar5_options(struct archive_read *a, const char *key,
- const char *val) {
- (void) a;
- (void) key;
- (void) val;
-
- /* No options supported in this version. Return the ARCHIVE_WARN code
- * to signal the options supervisor that the unpacker didn't handle
- * setting this option. */
-
- return ARCHIVE_WARN;
-}
-
-static void init_header(struct archive_read* a) {
- a->archive.archive_format = ARCHIVE_FORMAT_RAR_V5;
- a->archive.archive_format_name = "RAR5";
-}
-
-static void init_window_mask(struct rar5* rar) {
- if (rar->cstate.window_size)
- rar->cstate.window_mask = rar->cstate.window_size - 1;
- else
- rar->cstate.window_mask = 0;
-}
-
-enum HEADER_FLAGS {
- HFL_EXTRA_DATA = 0x0001,
- HFL_DATA = 0x0002,
- HFL_SKIP_IF_UNKNOWN = 0x0004,
- HFL_SPLIT_BEFORE = 0x0008,
- HFL_SPLIT_AFTER = 0x0010,
- HFL_CHILD = 0x0020,
- HFL_INHERITED = 0x0040
-};
-
-static int process_main_locator_extra_block(struct archive_read* a,
- struct rar5* rar)
-{
- uint64_t locator_flags;
-
- enum LOCATOR_FLAGS {
- QLIST = 0x01, RECOVERY = 0x02,
- };
-
- if(!read_var(a, &locator_flags, NULL)) {
- return ARCHIVE_EOF;
- }
-
- if(locator_flags & QLIST) {
- if(!read_var(a, &rar->qlist_offset, NULL)) {
- return ARCHIVE_EOF;
- }
-
- /* qlist is not used */
- }
-
- if(locator_flags & RECOVERY) {
- if(!read_var(a, &rar->rr_offset, NULL)) {
- return ARCHIVE_EOF;
- }
-
- /* rr is not used */
- }
-
- return ARCHIVE_OK;
-}
-
-static int parse_file_extra_hash(struct archive_read* a, struct rar5* rar,
- ssize_t* extra_data_size)
-{
- size_t hash_type = 0;
- size_t value_len;
-
- enum HASH_TYPE {
- BLAKE2sp = 0x00
- };
-
- if(!read_var_sized(a, &hash_type, &value_len))
- return ARCHIVE_EOF;
-
- *extra_data_size -= value_len;
- if(ARCHIVE_OK != consume(a, value_len)) {
- return ARCHIVE_EOF;
- }
-
- /* The file uses BLAKE2sp checksum algorithm instead of plain old
- * CRC32. */
- if(hash_type == BLAKE2sp) {
- const uint8_t* p;
- const int hash_size = sizeof(rar->file.blake2sp);
-
- if(!read_ahead(a, hash_size, &p))
- return ARCHIVE_EOF;
-
- rar->file.has_blake2 = 1;
- memcpy(&rar->file.blake2sp, p, hash_size);
-
- if(ARCHIVE_OK != consume(a, hash_size)) {
- return ARCHIVE_EOF;
- }
-
- *extra_data_size -= hash_size;
- } else {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unsupported hash type (0x%x)", (int) hash_type);
- return ARCHIVE_FATAL;
- }
-
- return ARCHIVE_OK;
-}
-
-static uint64_t time_win_to_unix(uint64_t win_time) {
- const size_t ns_in_sec = 10000000;
- const uint64_t sec_to_unix = 11644473600LL;
- return win_time / ns_in_sec - sec_to_unix;
-}
-
-static int parse_htime_item(struct archive_read* a, char unix_time,
- uint64_t* where, ssize_t* extra_data_size)
-{
- if(unix_time) {
- uint32_t time_val;
- if(!read_u32(a, &time_val))
- return ARCHIVE_EOF;
-
- *extra_data_size -= 4;
- *where = (uint64_t) time_val;
- } else {
- uint64_t windows_time;
- if(!read_u64(a, &windows_time))
- return ARCHIVE_EOF;
-
- *where = time_win_to_unix(windows_time);
- *extra_data_size -= 8;
- }
-
- return ARCHIVE_OK;
-}
-
-static int parse_file_extra_version(struct archive_read* a,
- struct archive_entry* e, ssize_t* extra_data_size)
-{
- size_t flags = 0;
- size_t version = 0;
- size_t value_len = 0;
- struct archive_string version_string;
- struct archive_string name_utf8_string;
- const char* cur_filename;
-
- /* Flags are ignored. */
- if(!read_var_sized(a, &flags, &value_len))
- return ARCHIVE_EOF;
-
- *extra_data_size -= value_len;
- if(ARCHIVE_OK != consume(a, value_len))
- return ARCHIVE_EOF;
-
- if(!read_var_sized(a, &version, &value_len))
- return ARCHIVE_EOF;
-
- *extra_data_size -= value_len;
- if(ARCHIVE_OK != consume(a, value_len))
- return ARCHIVE_EOF;
-
- /* extra_data_size should be zero here. */
-
- cur_filename = archive_entry_pathname_utf8(e);
- if(cur_filename == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Version entry without file name");
- return ARCHIVE_FATAL;
- }
-
- archive_string_init(&version_string);
- archive_string_init(&name_utf8_string);
-
- /* Prepare a ;123 suffix for the filename, where '123' is the version
- * value of this file. */
- archive_string_sprintf(&version_string, ";%zu", version);
-
- /* Build the new filename. */
- archive_strcat(&name_utf8_string, cur_filename);
- archive_strcat(&name_utf8_string, version_string.s);
-
- /* Apply the new filename into this file's context. */
- archive_entry_update_pathname_utf8(e, name_utf8_string.s);
-
- /* Free buffers. */
- archive_string_free(&version_string);
- archive_string_free(&name_utf8_string);
- return ARCHIVE_OK;
-}
-
-static int parse_file_extra_htime(struct archive_read* a,
- struct archive_entry* e, struct rar5* rar, ssize_t* extra_data_size)
-{
- char unix_time = 0;
- size_t flags = 0;
- size_t value_len;
-
- enum HTIME_FLAGS {
- IS_UNIX = 0x01,
- HAS_MTIME = 0x02,
- HAS_CTIME = 0x04,
- HAS_ATIME = 0x08,
- HAS_UNIX_NS = 0x10,
- };
-
- if(!read_var_sized(a, &flags, &value_len))
- return ARCHIVE_EOF;
-
- *extra_data_size -= value_len;
- if(ARCHIVE_OK != consume(a, value_len)) {
- return ARCHIVE_EOF;
- }
-
- unix_time = flags & IS_UNIX;
-
- if(flags & HAS_MTIME) {
- parse_htime_item(a, unix_time, &rar->file.e_mtime,
- extra_data_size);
- archive_entry_set_mtime(e, rar->file.e_mtime, 0);
- }
-
- if(flags & HAS_CTIME) {
- parse_htime_item(a, unix_time, &rar->file.e_ctime,
- extra_data_size);
- archive_entry_set_ctime(e, rar->file.e_ctime, 0);
- }
-
- if(flags & HAS_ATIME) {
- parse_htime_item(a, unix_time, &rar->file.e_atime,
- extra_data_size);
- archive_entry_set_atime(e, rar->file.e_atime, 0);
- }
-
- if(flags & HAS_UNIX_NS) {
- if(!read_u32(a, &rar->file.e_unix_ns))
- return ARCHIVE_EOF;
-
- *extra_data_size -= 4;
- }
-
- return ARCHIVE_OK;
-}
-
-static int parse_file_extra_redir(struct archive_read* a,
- struct archive_entry* e, struct rar5* rar, ssize_t* extra_data_size)
-{
- uint64_t value_size = 0;
- size_t target_size = 0;
- char target_utf8_buf[MAX_NAME_IN_BYTES];
- const uint8_t* p;
-
- if(!read_var(a, &rar->file.redir_type, &value_size))
- return ARCHIVE_EOF;
- if(ARCHIVE_OK != consume(a, (int64_t)value_size))
- return ARCHIVE_EOF;
- *extra_data_size -= value_size;
-
- if(!read_var(a, &rar->file.redir_flags, &value_size))
- return ARCHIVE_EOF;
- if(ARCHIVE_OK != consume(a, (int64_t)value_size))
- return ARCHIVE_EOF;
- *extra_data_size -= value_size;
-
- if(!read_var_sized(a, &target_size, NULL))
- return ARCHIVE_EOF;
- *extra_data_size -= target_size + 1;
-
- if(!read_ahead(a, target_size, &p))
- return ARCHIVE_EOF;
-
- if(target_size > (MAX_NAME_IN_CHARS - 1)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Link target is too long");
- return ARCHIVE_FATAL;
- }
-
- if(target_size == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "No link target specified");
- return ARCHIVE_FATAL;
- }
-
- memcpy(target_utf8_buf, p, target_size);
- target_utf8_buf[target_size] = 0;
-
- if(ARCHIVE_OK != consume(a, (int64_t)target_size))
- return ARCHIVE_EOF;
-
- switch(rar->file.redir_type) {
- case REDIR_TYPE_UNIXSYMLINK:
- case REDIR_TYPE_WINSYMLINK:
- archive_entry_set_filetype(e, AE_IFLNK);
- archive_entry_update_symlink_utf8(e, target_utf8_buf);
- if (rar->file.redir_flags & REDIR_SYMLINK_IS_DIR) {
- archive_entry_set_symlink_type(e,
- AE_SYMLINK_TYPE_DIRECTORY);
- } else {
- archive_entry_set_symlink_type(e,
- AE_SYMLINK_TYPE_FILE);
- }
- break;
-
- case REDIR_TYPE_HARDLINK:
- archive_entry_set_filetype(e, AE_IFREG);
- archive_entry_update_hardlink_utf8(e, target_utf8_buf);
- break;
-
- default:
- /* Unknown redir type, skip it. */
- break;
- }
- return ARCHIVE_OK;
-}
-
-static int parse_file_extra_owner(struct archive_read* a,
- struct archive_entry* e, ssize_t* extra_data_size)
-{
- uint64_t flags = 0;
- uint64_t value_size = 0;
- uint64_t id = 0;
- size_t name_len = 0;
- size_t name_size = 0;
- char namebuf[OWNER_MAXNAMELEN];
- const uint8_t* p;
-
- if(!read_var(a, &flags, &value_size))
- return ARCHIVE_EOF;
- if(ARCHIVE_OK != consume(a, (int64_t)value_size))
- return ARCHIVE_EOF;
- *extra_data_size -= value_size;
-
- if ((flags & OWNER_USER_NAME) != 0) {
- if(!read_var_sized(a, &name_size, NULL))
- return ARCHIVE_EOF;
- *extra_data_size -= name_size + 1;
-
- if(!read_ahead(a, name_size, &p))
- return ARCHIVE_EOF;
-
- if (name_size >= OWNER_MAXNAMELEN) {
- name_len = OWNER_MAXNAMELEN - 1;
- } else {
- name_len = name_size;
- }
-
- memcpy(namebuf, p, name_len);
- namebuf[name_len] = 0;
- if(ARCHIVE_OK != consume(a, (int64_t)name_size))
- return ARCHIVE_EOF;
-
- archive_entry_set_uname(e, namebuf);
- }
- if ((flags & OWNER_GROUP_NAME) != 0) {
- if(!read_var_sized(a, &name_size, NULL))
- return ARCHIVE_EOF;
- *extra_data_size -= name_size + 1;
-
- if(!read_ahead(a, name_size, &p))
- return ARCHIVE_EOF;
-
- if (name_size >= OWNER_MAXNAMELEN) {
- name_len = OWNER_MAXNAMELEN - 1;
- } else {
- name_len = name_size;
- }
-
- memcpy(namebuf, p, name_len);
- namebuf[name_len] = 0;
- if(ARCHIVE_OK != consume(a, (int64_t)name_size))
- return ARCHIVE_EOF;
-
- archive_entry_set_gname(e, namebuf);
- }
- if ((flags & OWNER_USER_UID) != 0) {
- if(!read_var(a, &id, &value_size))
- return ARCHIVE_EOF;
- if(ARCHIVE_OK != consume(a, (int64_t)value_size))
- return ARCHIVE_EOF;
- *extra_data_size -= value_size;
-
- archive_entry_set_uid(e, (la_int64_t)id);
- }
- if ((flags & OWNER_GROUP_GID) != 0) {
- if(!read_var(a, &id, &value_size))
- return ARCHIVE_EOF;
- if(ARCHIVE_OK != consume(a, (int64_t)value_size))
- return ARCHIVE_EOF;
- *extra_data_size -= value_size;
-
- archive_entry_set_gid(e, (la_int64_t)id);
- }
- return ARCHIVE_OK;
-}
-
-static int process_head_file_extra(struct archive_read* a,
- struct archive_entry* e, struct rar5* rar, ssize_t extra_data_size)
-{
- size_t extra_field_size;
- size_t extra_field_id = 0;
- int ret = ARCHIVE_FATAL;
- size_t var_size;
-
- while(extra_data_size > 0) {
- if(!read_var_sized(a, &extra_field_size, &var_size))
- return ARCHIVE_EOF;
-
- extra_data_size -= var_size;
- if(ARCHIVE_OK != consume(a, var_size)) {
- return ARCHIVE_EOF;
- }
-
- if(!read_var_sized(a, &extra_field_id, &var_size))
- return ARCHIVE_EOF;
-
- extra_data_size -= var_size;
- if(ARCHIVE_OK != consume(a, var_size)) {
- return ARCHIVE_EOF;
- }
-
- switch(extra_field_id) {
- case EX_HASH:
- ret = parse_file_extra_hash(a, rar,
- &extra_data_size);
- break;
- case EX_HTIME:
- ret = parse_file_extra_htime(a, e, rar,
- &extra_data_size);
- break;
- case EX_REDIR:
- ret = parse_file_extra_redir(a, e, rar,
- &extra_data_size);
- break;
- case EX_UOWNER:
- ret = parse_file_extra_owner(a, e,
- &extra_data_size);
- break;
- case EX_VERSION:
- ret = parse_file_extra_version(a, e,
- &extra_data_size);
- break;
- case EX_CRYPT:
- /* fallthrough */
- case EX_SUBDATA:
- /* fallthrough */
- default:
- /* Skip unsupported entry. */
- return consume(a, extra_data_size);
- }
- }
-
- if(ret != ARCHIVE_OK) {
- /* Attribute not implemented. */
- return ret;
- }
-
- return ARCHIVE_OK;
-}
-
-static int process_head_file(struct archive_read* a, struct rar5* rar,
- struct archive_entry* entry, size_t block_flags)
-{
- ssize_t extra_data_size = 0;
- size_t data_size = 0;
- size_t file_flags = 0;
- size_t file_attr = 0;
- size_t compression_info = 0;
- size_t host_os = 0;
- size_t name_size = 0;
- uint64_t unpacked_size, window_size;
- uint32_t mtime = 0, crc = 0;
- int c_method = 0, c_version = 0;
- char name_utf8_buf[MAX_NAME_IN_BYTES];
- const uint8_t* p;
-
- enum FILE_FLAGS {
- DIRECTORY = 0x0001, UTIME = 0x0002, CRC32 = 0x0004,
- UNKNOWN_UNPACKED_SIZE = 0x0008,
- };
-
- enum FILE_ATTRS {
- ATTR_READONLY = 0x1, ATTR_HIDDEN = 0x2, ATTR_SYSTEM = 0x4,
- ATTR_DIRECTORY = 0x10,
- };
-
- enum COMP_INFO_FLAGS {
- SOLID = 0x0040,
- };
-
- enum HOST_OS {
- HOST_WINDOWS = 0,
- HOST_UNIX = 1,
- };
-
- archive_entry_clear(entry);
-
- /* Do not reset file context if we're switching archives. */
- if(!rar->cstate.switch_multivolume) {
- reset_file_context(rar);
- }
-
- if(block_flags & HFL_EXTRA_DATA) {
- size_t edata_size = 0;
- if(!read_var_sized(a, &edata_size, NULL))
- return ARCHIVE_EOF;
-
- /* Intentional type cast from unsigned to signed. */
- extra_data_size = (ssize_t) edata_size;
- }
-
- if(block_flags & HFL_DATA) {
- if(!read_var_sized(a, &data_size, NULL))
- return ARCHIVE_EOF;
-
- rar->file.bytes_remaining = data_size;
- } else {
- rar->file.bytes_remaining = 0;
-
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "no data found in file/service block");
- return ARCHIVE_FATAL;
- }
-
- if(!read_var_sized(a, &file_flags, NULL))
- return ARCHIVE_EOF;
-
- if(!read_var(a, &unpacked_size, NULL))
- return ARCHIVE_EOF;
-
- if(file_flags & UNKNOWN_UNPACKED_SIZE) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Files with unknown unpacked size are not supported");
- return ARCHIVE_FATAL;
- }
-
- rar->file.dir = (uint8_t) ((file_flags & DIRECTORY) > 0);
-
- if(!read_var_sized(a, &file_attr, NULL))
- return ARCHIVE_EOF;
-
- if(file_flags & UTIME) {
- if(!read_u32(a, &mtime))
- return ARCHIVE_EOF;
- }
-
- if(file_flags & CRC32) {
- if(!read_u32(a, &crc))
- return ARCHIVE_EOF;
- }
-
- if(!read_var_sized(a, &compression_info, NULL))
- return ARCHIVE_EOF;
-
- c_method = (int) (compression_info >> 7) & 0x7;
- c_version = (int) (compression_info & 0x3f);
-
- /* RAR5 seems to limit the dictionary size to 64MB. */
- window_size = (rar->file.dir > 0) ?
- 0 :
- g_unpack_window_size << ((compression_info >> 10) & 15);
- rar->cstate.method = c_method;
- rar->cstate.version = c_version + 50;
- rar->file.solid = (compression_info & SOLID) > 0;
-
- /* Archives which declare solid files without initializing the window
- * buffer first are invalid. */
-
- if(rar->file.solid > 0 && rar->cstate.window_buf == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Declared solid file, but no window buffer "
- "initialized yet.");
- return ARCHIVE_FATAL;
- }
-
- /* Check if window_size is a sane value. Also, if the file is not
- * declared as a directory, disallow window_size == 0. */
- if(window_size > (64 * 1024 * 1024) ||
- (rar->file.dir == 0 && window_size == 0))
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Declared dictionary size is not supported.");
- return ARCHIVE_FATAL;
- }
-
- if(rar->file.solid > 0) {
- /* Re-check if current window size is the same as previous
- * window size (for solid files only). */
- if(rar->file.solid_window_size > 0 &&
- rar->file.solid_window_size != (ssize_t) window_size)
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Window size for this solid file doesn't match "
- "the window size used in previous solid file. ");
- return ARCHIVE_FATAL;
- }
- }
-
- if(rar->cstate.window_size < (ssize_t) window_size &&
- rar->cstate.window_buf)
- {
- /* If window_buf has been allocated before, reallocate it, so
- * that its size will match new window_size. */
-
- uint8_t* new_window_buf =
- realloc(rar->cstate.window_buf, window_size);
-
- if(!new_window_buf) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Not enough memory when trying to realloc the window "
- "buffer.");
- return ARCHIVE_FATAL;
- }
-
- rar->cstate.window_buf = new_window_buf;
- }
-
- /* Values up to 64M should fit into ssize_t on every
- * architecture. */
- rar->cstate.window_size = (ssize_t) window_size;
-
- if(rar->file.solid > 0 && rar->file.solid_window_size == 0) {
- /* Solid files have to have the same window_size across
- whole archive. Remember the window_size parameter
- for first solid file found. */
- rar->file.solid_window_size = rar->cstate.window_size;
- }
-
- init_window_mask(rar);
-
- rar->file.service = 0;
-
- if(!read_var_sized(a, &host_os, NULL))
- return ARCHIVE_EOF;
-
- if(host_os == HOST_WINDOWS) {
- /* Host OS is Windows */
-
- __LA_MODE_T mode;
-
- if(file_attr & ATTR_DIRECTORY) {
- if (file_attr & ATTR_READONLY) {
- mode = 0555 | AE_IFDIR;
- } else {
- mode = 0755 | AE_IFDIR;
- }
- } else {
- if (file_attr & ATTR_READONLY) {
- mode = 0444 | AE_IFREG;
- } else {
- mode = 0644 | AE_IFREG;
- }
- }
-
- archive_entry_set_mode(entry, mode);
-
- if (file_attr & (ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM)) {
- char *fflags_text, *ptr;
- /* allocate for "rdonly,hidden,system," */
- fflags_text = malloc(22 * sizeof(char));
- if (fflags_text != NULL) {
- ptr = fflags_text;
- if (file_attr & ATTR_READONLY) {
- strcpy(ptr, "rdonly,");
- ptr = ptr + 7;
- }
- if (file_attr & ATTR_HIDDEN) {
- strcpy(ptr, "hidden,");
- ptr = ptr + 7;
- }
- if (file_attr & ATTR_SYSTEM) {
- strcpy(ptr, "system,");
- ptr = ptr + 7;
- }
- if (ptr > fflags_text) {
- /* Delete trailing comma */
- *(ptr - 1) = '\0';
- archive_entry_copy_fflags_text(entry,
- fflags_text);
- }
- free(fflags_text);
- }
- }
- } else if(host_os == HOST_UNIX) {
- /* Host OS is Unix */
- archive_entry_set_mode(entry, (__LA_MODE_T) file_attr);
- } else {
- /* Unknown host OS */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unsupported Host OS: 0x%x", (int) host_os);
-
- return ARCHIVE_FATAL;
- }
-
- if(!read_var_sized(a, &name_size, NULL))
- return ARCHIVE_EOF;
-
- if(!read_ahead(a, name_size, &p))
- return ARCHIVE_EOF;
-
- if(name_size > (MAX_NAME_IN_CHARS - 1)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Filename is too long");
-
- return ARCHIVE_FATAL;
- }
-
- if(name_size == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "No filename specified");
-
- return ARCHIVE_FATAL;
- }
-
- memcpy(name_utf8_buf, p, name_size);
- name_utf8_buf[name_size] = 0;
- if(ARCHIVE_OK != consume(a, name_size)) {
- return ARCHIVE_EOF;
- }
-
- archive_entry_update_pathname_utf8(entry, name_utf8_buf);
-
- if(extra_data_size > 0) {
- int ret = process_head_file_extra(a, entry, rar,
- extra_data_size);
-
- /*
- * TODO: rewrite or remove useless sanity check
- * as extra_data_size is not passed as a pointer
- *
- if(extra_data_size < 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "File extra data size is not zero");
- return ARCHIVE_FATAL;
- }
- */
-
- if(ret != ARCHIVE_OK)
- return ret;
- }
-
- if((file_flags & UNKNOWN_UNPACKED_SIZE) == 0) {
- rar->file.unpacked_size = (ssize_t) unpacked_size;
- if(rar->file.redir_type == REDIR_TYPE_NONE)
- archive_entry_set_size(entry, unpacked_size);
- }
-
- if(file_flags & UTIME) {
- archive_entry_set_mtime(entry, (time_t) mtime, 0);
- }
-
- if(file_flags & CRC32) {
- rar->file.stored_crc32 = crc;
- }
-
- if(!rar->cstate.switch_multivolume) {
- /* Do not reinitialize unpacking state if we're switching
- * archives. */
- rar->cstate.block_parsing_finished = 1;
- rar->cstate.all_filters_applied = 1;
- rar->cstate.initialized = 0;
- }
-
- if(rar->generic.split_before > 0) {
- /* If now we're standing on a header that has a 'split before'
- * mark, it means we're standing on a 'continuation' file
- * header. Signal the caller that if it wants to move to
- * another file, it must call rar5_read_header() function
- * again. */
-
- return ARCHIVE_RETRY;
- } else {
- return ARCHIVE_OK;
- }
-}
-
-static int process_head_service(struct archive_read* a, struct rar5* rar,
- struct archive_entry* entry, size_t block_flags)
-{
- /* Process this SERVICE block the same way as FILE blocks. */
- int ret = process_head_file(a, rar, entry, block_flags);
- if(ret != ARCHIVE_OK)
- return ret;
-
- rar->file.service = 1;
-
- /* But skip the data part automatically. It's no use for the user
- * anyway. It contains only service data, not even needed to
- * properly unpack the file. */
- ret = rar5_read_data_skip(a);
- if(ret != ARCHIVE_OK)
- return ret;
-
- /* After skipping, try parsing another block automatically. */
- return ARCHIVE_RETRY;
-}
-
-static int process_head_main(struct archive_read* a, struct rar5* rar,
- struct archive_entry* entry, size_t block_flags)
-{
- int ret;
- size_t extra_data_size = 0;
- size_t extra_field_size = 0;
- size_t extra_field_id = 0;
- size_t archive_flags = 0;
-
- enum MAIN_FLAGS {
- VOLUME = 0x0001, /* multi-volume archive */
- VOLUME_NUMBER = 0x0002, /* volume number, first vol doesn't
- * have it */
- SOLID = 0x0004, /* solid archive */
- PROTECT = 0x0008, /* contains Recovery info */
- LOCK = 0x0010, /* readonly flag, not used */
- };
-
- enum MAIN_EXTRA {
- // Just one attribute here.
- LOCATOR = 0x01,
- };
-
- (void) entry;
-
- if(block_flags & HFL_EXTRA_DATA) {
- if(!read_var_sized(a, &extra_data_size, NULL))
- return ARCHIVE_EOF;
- } else {
- extra_data_size = 0;
- }
-
- if(!read_var_sized(a, &archive_flags, NULL)) {
- return ARCHIVE_EOF;
- }
-
- rar->main.volume = (archive_flags & VOLUME) > 0;
- rar->main.solid = (archive_flags & SOLID) > 0;
-
- if(archive_flags & VOLUME_NUMBER) {
- size_t v = 0;
- if(!read_var_sized(a, &v, NULL)) {
- return ARCHIVE_EOF;
- }
-
- if (v > UINT_MAX) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid volume number");
- return ARCHIVE_FATAL;
- }
-
- rar->main.vol_no = (unsigned int) v;
- } else {
- rar->main.vol_no = 0;
- }
-
- if(rar->vol.expected_vol_no > 0 &&
- rar->main.vol_no != rar->vol.expected_vol_no)
- {
- /* Returning EOF instead of FATAL because of strange
- * libarchive behavior. When opening multiple files via
- * archive_read_open_filenames(), after reading up the whole
- * last file, the __archive_read_ahead function wraps up to
- * the first archive instead of returning EOF. */
- return ARCHIVE_EOF;
- }
-
- if(extra_data_size == 0) {
- /* Early return. */
- return ARCHIVE_OK;
- }
-
- if(!read_var_sized(a, &extra_field_size, NULL)) {
- return ARCHIVE_EOF;
- }
-
- if(!read_var_sized(a, &extra_field_id, NULL)) {
- return ARCHIVE_EOF;
- }
-
- if(extra_field_size == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid extra field size");
- return ARCHIVE_FATAL;
- }
-
- switch(extra_field_id) {
- case LOCATOR:
- ret = process_main_locator_extra_block(a, rar);
- if(ret != ARCHIVE_OK) {
- /* Error while parsing main locator extra
- * block. */
- return ret;
- }
-
- break;
- default:
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Unsupported extra type (0x%x)",
- (int) extra_field_id);
- return ARCHIVE_FATAL;
- }
-
- return ARCHIVE_OK;
-}
-
-static int skip_unprocessed_bytes(struct archive_read* a) {
- struct rar5* rar = get_context(a);
- int ret;
-
- if(rar->file.bytes_remaining) {
- /* Use different skipping method in block merging mode than in
- * normal mode. If merge mode is active, rar5_read_data_skip
- * can't be used, because it could allow recursive use of
- * merge_block() * function, and this function doesn't support
- * recursive use. */
- if(rar->merge_mode) {
- /* Discard whole merged block. This is valid in solid
- * mode as well, because the code will discard blocks
- * only if those blocks are safe to discard (i.e.
- * they're not FILE blocks). */
- ret = consume(a, rar->file.bytes_remaining);
- if(ret != ARCHIVE_OK) {
- return ret;
- }
- rar->file.bytes_remaining = 0;
- } else {
- /* If we're not in merge mode, use safe skipping code.
- * This will ensure we'll handle solid archives
- * properly. */
- ret = rar5_read_data_skip(a);
- if(ret != ARCHIVE_OK) {
- return ret;
- }
- }
- }
-
- return ARCHIVE_OK;
-}
-
-static int scan_for_signature(struct archive_read* a);
-
-/* Base block processing function. A 'base block' is a RARv5 header block
- * that tells the reader what kind of data is stored inside the block.
- *
- * From the birds-eye view a RAR file looks file this:
- *
- * <magic><base_block_1><base_block_2>...<base_block_n>
- *
- * There are a few types of base blocks. Those types are specified inside
- * the 'switch' statement in this function. For example purposes, I'll write
- * how a standard RARv5 file could look like here:
- *
- * <magic><MAIN><FILE><FILE><FILE><SERVICE><ENDARC>
- *
- * The structure above could describe an archive file with 3 files in it,
- * one service "QuickOpen" block (that is ignored by this parser), and an
- * end of file base block marker.
- *
- * If the file is stored in multiple archive files ("multiarchive"), it might
- * look like this:
- *
- * .part01.rar: <magic><MAIN><FILE><ENDARC>
- * .part02.rar: <magic><MAIN><FILE><ENDARC>
- * .part03.rar: <magic><MAIN><FILE><ENDARC>
- *
- * This example could describe 3 RAR files that contain ONE archived file.
- * Or it could describe 3 RAR files that contain 3 different files. Or 3
- * RAR files than contain 2 files. It all depends what metadata is stored in
- * the headers of <FILE> blocks.
- *
- * Each <FILE> block contains info about its size, the name of the file it's
- * storing inside, and whether this FILE block is a continuation block of
- * previous archive ('split before'), and is this FILE block should be
- * continued in another archive ('split after'). By parsing the 'split before'
- * and 'split after' flags, we're able to tell if multiple <FILE> base blocks
- * are describing one file, or multiple files (with the same filename, for
- * example).
- *
- * One thing to note is that if we're parsing the first <FILE> block, and
- * we see 'split after' flag, then we need to jump over to another <FILE>
- * block to be able to decompress rest of the data. To do this, we need
- * to skip the <ENDARC> block, then switch to another file, then skip the
- * <magic> block, <MAIN> block, and then we're standing on the proper
- * <FILE> block.
- */
-
-static int process_base_block(struct archive_read* a,
- struct archive_entry* entry)
-{
- const size_t SMALLEST_RAR5_BLOCK_SIZE = 3;
-
- struct rar5* rar = get_context(a);
- uint32_t hdr_crc, computed_crc;
- size_t raw_hdr_size = 0, hdr_size_len, hdr_size;
- size_t header_id = 0;
- size_t header_flags = 0;
- const uint8_t* p;
- int ret;
-
- enum HEADER_TYPE {
- HEAD_MARK = 0x00, HEAD_MAIN = 0x01, HEAD_FILE = 0x02,
- HEAD_SERVICE = 0x03, HEAD_CRYPT = 0x04, HEAD_ENDARC = 0x05,
- HEAD_UNKNOWN = 0xff,
- };
-
- /* Skip any unprocessed data for this file. */
- ret = skip_unprocessed_bytes(a);
- if(ret != ARCHIVE_OK)
- return ret;
-
- /* Read the expected CRC32 checksum. */
- if(!read_u32(a, &hdr_crc)) {
- return ARCHIVE_EOF;
- }
-
- /* Read header size. */
- if(!read_var_sized(a, &raw_hdr_size, &hdr_size_len)) {
- return ARCHIVE_EOF;
- }
-
- hdr_size = raw_hdr_size + hdr_size_len;
-
- /* Sanity check, maximum header size for RAR5 is 2MB. */
- if(hdr_size > (2 * 1024 * 1024)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Base block header is too large");
-
- return ARCHIVE_FATAL;
- }
-
- /* Additional sanity checks to weed out invalid files. */
- if(raw_hdr_size == 0 || hdr_size_len == 0 ||
- hdr_size < SMALLEST_RAR5_BLOCK_SIZE)
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Too small block encountered (%zu bytes)",
- raw_hdr_size);
-
- return ARCHIVE_FATAL;
- }
-
- /* Read the whole header data into memory, maximum memory use here is
- * 2MB. */
- if(!read_ahead(a, hdr_size, &p)) {
- return ARCHIVE_EOF;
- }
-
- /* Verify the CRC32 of the header data. */
- computed_crc = (uint32_t) crc32(0, p, (int) hdr_size);
- if(computed_crc != hdr_crc) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Header CRC error");
-
- return ARCHIVE_FATAL;
- }
-
- /* If the checksum is OK, we proceed with parsing. */
- if(ARCHIVE_OK != consume(a, hdr_size_len)) {
- return ARCHIVE_EOF;
- }
-
- if(!read_var_sized(a, &header_id, NULL))
- return ARCHIVE_EOF;
-
- if(!read_var_sized(a, &header_flags, NULL))
- return ARCHIVE_EOF;
-
- rar->generic.split_after = (header_flags & HFL_SPLIT_AFTER) > 0;
- rar->generic.split_before = (header_flags & HFL_SPLIT_BEFORE) > 0;
- rar->generic.size = (int)hdr_size;
- rar->generic.last_header_id = (int)header_id;
- rar->main.endarc = 0;
-
- /* Those are possible header ids in RARv5. */
- switch(header_id) {
- case HEAD_MAIN:
- ret = process_head_main(a, rar, entry, header_flags);
-
- /* Main header doesn't have any files in it, so it's
- * pointless to return to the caller. Retry to next
- * header, which should be HEAD_FILE/HEAD_SERVICE. */
- if(ret == ARCHIVE_OK)
- return ARCHIVE_RETRY;
-
- return ret;
- case HEAD_SERVICE:
- ret = process_head_service(a, rar, entry, header_flags);
- return ret;
- case HEAD_FILE:
- ret = process_head_file(a, rar, entry, header_flags);
- return ret;
- case HEAD_CRYPT:
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Encryption is not supported");
- return ARCHIVE_FATAL;
- case HEAD_ENDARC:
- rar->main.endarc = 1;
-
- /* After encountering an end of file marker, we need
- * to take into consideration if this archive is
- * continued in another file (i.e. is it part01.rar:
- * is there a part02.rar?) */
- if(rar->main.volume) {
- /* In case there is part02.rar, position the
- * read pointer in a proper place, so we can
- * resume parsing. */
- ret = scan_for_signature(a);
- if(ret == ARCHIVE_FATAL) {
- return ARCHIVE_EOF;
- } else {
- if(rar->vol.expected_vol_no ==
- UINT_MAX) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Header error");
- return ARCHIVE_FATAL;
- }
-
- rar->vol.expected_vol_no =
- rar->main.vol_no + 1;
- return ARCHIVE_OK;
- }
- } else {
- return ARCHIVE_EOF;
- }
- case HEAD_MARK:
- return ARCHIVE_EOF;
- default:
- if((header_flags & HFL_SKIP_IF_UNKNOWN) == 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Header type error");
- return ARCHIVE_FATAL;
- } else {
- /* If the block is marked as 'skip if unknown',
- * do as the flag says: skip the block
- * instead on failing on it. */
- return ARCHIVE_RETRY;
- }
- }
-
-#if !defined WIN32
- // Not reached.
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Internal unpacker error");
- return ARCHIVE_FATAL;
-#endif
-}
-
-static int skip_base_block(struct archive_read* a) {
- int ret;
- struct rar5* rar = get_context(a);
-
- /* Create a new local archive_entry structure that will be operated on
- * by header reader; operations on this archive_entry will be discarded.
- */
- struct archive_entry* entry = archive_entry_new();
- ret = process_base_block(a, entry);
-
- /* Discard operations on this archive_entry structure. */
- archive_entry_free(entry);
- if(ret == ARCHIVE_FATAL)
- return ret;
-
- if(rar->generic.last_header_id == 2 && rar->generic.split_before > 0)
- return ARCHIVE_OK;
-
- if(ret == ARCHIVE_OK)
- return ARCHIVE_RETRY;
- else
- return ret;
-}
-
-static int try_skip_sfx(struct archive_read *a)
-{
- const char *p;
-
- if ((p = __archive_read_ahead(a, 7, NULL)) == NULL)
- return ARCHIVE_EOF;
-
- if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0)
- {
- char signature[sizeof(rar5_signature_xor)];
- const void *h;
- const char *q;
- size_t skip, total = 0;
- ssize_t bytes, window = 4096;
-
- rar5_signature(signature);
-
- while (total + window <= (1024 * 512)) {
- h = __archive_read_ahead(a, window, &bytes);
- if (h == NULL) {
- /* Remaining bytes are less than window. */
- window >>= 1;
- if (window < 0x40)
- goto fatal;
- continue;
- }
- if (bytes < 0x40)
- goto fatal;
- p = h;
- q = p + bytes;
-
- /*
- * Scan ahead until we find something that looks
- * like the RAR header.
- */
- while (p + 8 < q) {
- if (memcmp(p, signature, sizeof(signature)) == 0) {
- skip = p - (const char *)h;
- __archive_read_consume(a, skip);
- return (ARCHIVE_OK);
- }
- p += 0x10;
- }
- skip = p - (const char *)h;
- __archive_read_consume(a, skip);
- total += skip;
- }
- }
-
- return ARCHIVE_OK;
-fatal:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Couldn't find out RAR header");
- return (ARCHIVE_FATAL);
-}
-
-static int rar5_read_header(struct archive_read *a,
- struct archive_entry *entry)
-{
- struct rar5* rar = get_context(a);
- int ret;
-
- if(rar->header_initialized == 0) {
- init_header(a);
- if ((ret = try_skip_sfx(a)) < ARCHIVE_WARN)
- return ret;
- rar->header_initialized = 1;
- }
-
- if(rar->skipped_magic == 0) {
- if(ARCHIVE_OK != consume(a, sizeof(rar5_signature_xor))) {
- return ARCHIVE_EOF;
- }
-
- rar->skipped_magic = 1;
- }
-
- do {
- ret = process_base_block(a, entry);
- } while(ret == ARCHIVE_RETRY ||
- (rar->main.endarc > 0 && ret == ARCHIVE_OK));
-
- return ret;
-}
-
-static void init_unpack(struct rar5* rar) {
- rar->file.calculated_crc32 = 0;
- init_window_mask(rar);
-
- free(rar->cstate.window_buf);
- free(rar->cstate.filtered_buf);
-
- if(rar->cstate.window_size > 0) {
- rar->cstate.window_buf = calloc(1, rar->cstate.window_size);
- rar->cstate.filtered_buf = calloc(1, rar->cstate.window_size);
- } else {
- rar->cstate.window_buf = NULL;
- rar->cstate.filtered_buf = NULL;
- }
-
- rar->cstate.write_ptr = 0;
- rar->cstate.last_write_ptr = 0;
-
- memset(&rar->cstate.bd, 0, sizeof(rar->cstate.bd));
- memset(&rar->cstate.ld, 0, sizeof(rar->cstate.ld));
- memset(&rar->cstate.dd, 0, sizeof(rar->cstate.dd));
- memset(&rar->cstate.ldd, 0, sizeof(rar->cstate.ldd));
- memset(&rar->cstate.rd, 0, sizeof(rar->cstate.rd));
-}
-
-static void update_crc(struct rar5* rar, const uint8_t* p, size_t to_read) {
- int verify_crc;
-
- if(rar->skip_mode) {
-#if defined CHECK_CRC_ON_SOLID_SKIP
- verify_crc = 1;
-#else
- verify_crc = 0;
-#endif
- } else
- verify_crc = 1;
-
- if(verify_crc) {
- /* Don't update CRC32 if the file doesn't have the
- * `stored_crc32` info filled in. */
- if(rar->file.stored_crc32 > 0) {
- rar->file.calculated_crc32 =
- crc32(rar->file.calculated_crc32, p, (unsigned int)to_read);
- }
-
- /* Check if the file uses an optional BLAKE2sp checksum
- * algorithm. */
- if(rar->file.has_blake2 > 0) {
- /* Return value of the `update` function is always 0,
- * so we can explicitly ignore it here. */
- (void) blake2sp_update(&rar->file.b2state, p, to_read);
- }
- }
-}
-
-static int create_decode_tables(uint8_t* bit_length,
- struct decode_table* table, int size)
-{
- int code, upper_limit = 0, i, lc[16];
- uint32_t decode_pos_clone[rar5_countof(table->decode_pos)];
- ssize_t cur_len, quick_data_size;
-
- memset(&lc, 0, sizeof(lc));
- memset(table->decode_num, 0, sizeof(table->decode_num));
- table->size = size;
- table->quick_bits = size == HUFF_NC ? 10 : 7;
-
- for(i = 0; i < size; i++) {
- lc[bit_length[i] & 15]++;
- }
-
- lc[0] = 0;
- table->decode_pos[0] = 0;
- table->decode_len[0] = 0;
-
- for(i = 1; i < 16; i++) {
- upper_limit += lc[i];
-
- table->decode_len[i] = upper_limit << (16 - i);
- table->decode_pos[i] = table->decode_pos[i - 1] + lc[i - 1];
-
- upper_limit <<= 1;
- }
-
- memcpy(decode_pos_clone, table->decode_pos, sizeof(decode_pos_clone));
-
- for(i = 0; i < size; i++) {
- uint8_t clen = bit_length[i] & 15;
- if(clen > 0) {
- int last_pos = decode_pos_clone[clen];
- table->decode_num[last_pos] = i;
- decode_pos_clone[clen]++;
- }
- }
-
- quick_data_size = (int64_t)1 << table->quick_bits;
- cur_len = 1;
- for(code = 0; code < quick_data_size; code++) {
- int bit_field = code << (16 - table->quick_bits);
- int dist, pos;
-
- while(cur_len < rar5_countof(table->decode_len) &&
- bit_field >= table->decode_len[cur_len]) {
- cur_len++;
- }
-
- table->quick_len[code] = (uint8_t) cur_len;
-
- dist = bit_field - table->decode_len[cur_len - 1];
- dist >>= (16 - cur_len);
-
- pos = table->decode_pos[cur_len & 15] + dist;
- if(cur_len < rar5_countof(table->decode_pos) && pos < size) {
- table->quick_num[code] = table->decode_num[pos];
- } else {
- table->quick_num[code] = 0;
- }
- }
-
- return ARCHIVE_OK;
-}
-
-static int decode_number(struct archive_read* a, struct decode_table* table,
- const uint8_t* p, uint16_t* num)
-{
- int i, bits, dist, ret;
- uint16_t bitfield;
- uint32_t pos;
- struct rar5* rar = get_context(a);
-
- if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &bitfield))) {
- return ret;
- }
-
- bitfield &= 0xfffe;
-
- if(bitfield < table->decode_len[table->quick_bits]) {
- int code = bitfield >> (16 - table->quick_bits);
- skip_bits(rar, table->quick_len[code]);
- *num = table->quick_num[code];
- return ARCHIVE_OK;
- }
-
- bits = 15;
-
- for(i = table->quick_bits + 1; i < 15; i++) {
- if(bitfield < table->decode_len[i]) {
- bits = i;
- break;
- }
- }
-
- skip_bits(rar, bits);
-
- dist = bitfield - table->decode_len[bits - 1];
- dist >>= (16 - bits);
- pos = table->decode_pos[bits] + dist;
-
- if(pos >= table->size)
- pos = 0;
-
- *num = table->decode_num[pos];
- return ARCHIVE_OK;
-}
-
-/* Reads and parses Huffman tables from the beginning of the block. */
-static int parse_tables(struct archive_read* a, struct rar5* rar,
- const uint8_t* p)
-{
- int ret, value, i, w, idx = 0;
- uint8_t bit_length[HUFF_BC],
- table[HUFF_TABLE_SIZE],
- nibble_mask = 0xF0,
- nibble_shift = 4;
-
- enum { ESCAPE = 15 };
-
- /* The data for table generation is compressed using a simple RLE-like
- * algorithm when storing zeroes, so we need to unpack it first. */
- for(w = 0, i = 0; w < HUFF_BC;) {
- if(i >= rar->cstate.cur_block_size) {
- /* Truncated data, can't continue. */
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated data in huffman tables");
- return ARCHIVE_FATAL;
- }
-
- value = (p[i] & nibble_mask) >> nibble_shift;
-
- if(nibble_mask == 0x0F)
- ++i;
-
- nibble_mask ^= 0xFF;
- nibble_shift ^= 4;
-
- /* Values smaller than 15 is data, so we write it directly.
- * Value 15 is a flag telling us that we need to unpack more
- * bytes. */
- if(value == ESCAPE) {
- value = (p[i] & nibble_mask) >> nibble_shift;
- if(nibble_mask == 0x0F)
- ++i;
- nibble_mask ^= 0xFF;
- nibble_shift ^= 4;
-
- if(value == 0) {
- /* We sometimes need to write the actual value
- * of 15, so this case handles that. */
- bit_length[w++] = ESCAPE;
- } else {
- int k;
-
- /* Fill zeroes. */
- for(k = 0; (k < value + 2) && (w < HUFF_BC);
- k++) {
- bit_length[w++] = 0;
- }
- }
- } else {
- bit_length[w++] = value;
- }
- }
-
- rar->bits.in_addr = i;
- rar->bits.bit_addr = nibble_shift ^ 4;
-
- ret = create_decode_tables(bit_length, &rar->cstate.bd, HUFF_BC);
- if(ret != ARCHIVE_OK) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Decoding huffman tables failed");
- return ARCHIVE_FATAL;
- }
-
- for(i = 0; i < HUFF_TABLE_SIZE;) {
- uint16_t num;
-
- ret = decode_number(a, &rar->cstate.bd, p, &num);
- if(ret != ARCHIVE_OK) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Decoding huffman tables failed");
- return ARCHIVE_FATAL;
- }
-
- if(num < 16) {
- /* 0..15: store directly */
- table[i] = (uint8_t) num;
- i++;
- } else if(num < 18) {
- /* 16..17: repeat previous code */
- uint16_t n;
-
- if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &n)))
- return ret;
-
- if(num == 16) {
- n >>= 13;
- n += 3;
- skip_bits(rar, 3);
- } else {
- n >>= 9;
- n += 11;
- skip_bits(rar, 7);
- }
-
- if(i > 0) {
- while(n-- > 0 && i < HUFF_TABLE_SIZE) {
- table[i] = table[i - 1];
- i++;
- }
- } else {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Unexpected error when decoding "
- "huffman tables");
- return ARCHIVE_FATAL;
- }
- } else {
- /* other codes: fill with zeroes `n` times */
- uint16_t n;
-
- if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &n)))
- return ret;
-
- if(num == 18) {
- n >>= 13;
- n += 3;
- skip_bits(rar, 3);
- } else {
- n >>= 9;
- n += 11;
- skip_bits(rar, 7);
- }
-
- while(n-- > 0 && i < HUFF_TABLE_SIZE)
- table[i++] = 0;
- }
- }
-
- ret = create_decode_tables(&table[idx], &rar->cstate.ld, HUFF_NC);
- if(ret != ARCHIVE_OK) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Failed to create literal table");
- return ARCHIVE_FATAL;
- }
-
- idx += HUFF_NC;
-
- ret = create_decode_tables(&table[idx], &rar->cstate.dd, HUFF_DC);
- if(ret != ARCHIVE_OK) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Failed to create distance table");
- return ARCHIVE_FATAL;
- }
-
- idx += HUFF_DC;
-
- ret = create_decode_tables(&table[idx], &rar->cstate.ldd, HUFF_LDC);
- if(ret != ARCHIVE_OK) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Failed to create lower bits of distances table");
- return ARCHIVE_FATAL;
- }
-
- idx += HUFF_LDC;
-
- ret = create_decode_tables(&table[idx], &rar->cstate.rd, HUFF_RC);
- if(ret != ARCHIVE_OK) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Failed to create repeating distances table");
- return ARCHIVE_FATAL;
- }
-
- return ARCHIVE_OK;
-}
-
-/* Parses the block header, verifies its CRC byte, and saves the header
- * fields inside the `hdr` pointer. */
-static int parse_block_header(struct archive_read* a, const uint8_t* p,
- ssize_t* block_size, struct compressed_block_header* hdr)
-{
- uint8_t calculated_cksum;
- memcpy(hdr, p, sizeof(struct compressed_block_header));
-
- if(bf_byte_count(hdr) > 2) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unsupported block header size (was %d, max is 2)",
- bf_byte_count(hdr));
- return ARCHIVE_FATAL;
- }
-
- /* This should probably use bit reader interface in order to be more
- * future-proof. */
- *block_size = 0;
- switch(bf_byte_count(hdr)) {
- /* 1-byte block size */
- case 0:
- *block_size = *(const uint8_t*) &p[2];
- break;
-
- /* 2-byte block size */
- case 1:
- *block_size = archive_le16dec(&p[2]);
- break;
-
- /* 3-byte block size */
- case 2:
- *block_size = archive_le32dec(&p[2]);
- *block_size &= 0x00FFFFFF;
- break;
-
- /* Other block sizes are not supported. This case is not
- * reached, because we have an 'if' guard before the switch
- * that makes sure of it. */
- default:
- return ARCHIVE_FATAL;
- }
-
- /* Verify the block header checksum. 0x5A is a magic value and is
- * always * constant. */
- calculated_cksum = 0x5A
- ^ (uint8_t) hdr->block_flags_u8
- ^ (uint8_t) *block_size
- ^ (uint8_t) (*block_size >> 8)
- ^ (uint8_t) (*block_size >> 16);
-
- if(calculated_cksum != hdr->block_cksum) {
-#ifndef DONT_FAIL_ON_CRC_ERROR
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Block checksum error: got 0x%x, expected 0x%x",
- hdr->block_cksum, calculated_cksum);
-
- return ARCHIVE_FATAL;
-#endif
- }
-
- return ARCHIVE_OK;
-}
-
-/* Convenience function used during filter processing. */
-static int parse_filter_data(struct archive_read* a, struct rar5* rar,
- const uint8_t* p, uint32_t* filter_data)
-{
- int i, bytes, ret;
- uint32_t data = 0;
-
- if(ARCHIVE_OK != (ret = read_consume_bits(a, rar, p, 2, &bytes)))
- return ret;
-
- bytes++;
-
- for(i = 0; i < bytes; i++) {
- uint16_t byte;
-
- if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &byte))) {
- return ret;
- }
-
- /* Cast to uint32_t will ensure the shift operation will not
- * produce undefined result. */
- data += ((uint32_t) byte >> 8) << (i * 8);
- skip_bits(rar, 8);
- }
-
- *filter_data = data;
- return ARCHIVE_OK;
-}
-
-/* Function is used during sanity checking. */
-static int is_valid_filter_block_start(struct rar5* rar,
- uint32_t start)
-{
- const int64_t block_start = (ssize_t) start + rar->cstate.write_ptr;
- const int64_t last_bs = rar->cstate.last_block_start;
- const ssize_t last_bl = rar->cstate.last_block_length;
-
- if(last_bs == 0 || last_bl == 0) {
- /* We didn't have any filters yet, so accept this offset. */
- return 1;
- }
-
- if(block_start >= last_bs + last_bl) {
- /* Current offset is bigger than last block's end offset, so
- * accept current offset. */
- return 1;
- }
-
- /* Any other case is not a normal situation and we should fail. */
- return 0;
-}
-
-/* The function will create a new filter, read its parameters from the input
- * stream and add it to the filter collection. */
-static int parse_filter(struct archive_read* ar, const uint8_t* p) {
- uint32_t block_start, block_length;
- uint16_t filter_type;
- struct filter_info* filt = NULL;
- struct rar5* rar = get_context(ar);
- int ret;
-
- /* Read the parameters from the input stream. */
- if(ARCHIVE_OK != (ret = parse_filter_data(ar, rar, p, &block_start)))
- return ret;
-
- if(ARCHIVE_OK != (ret = parse_filter_data(ar, rar, p, &block_length)))
- return ret;
-
- if(ARCHIVE_OK != (ret = read_bits_16(ar, rar, p, &filter_type)))
- return ret;
-
- filter_type >>= 13;
- skip_bits(rar, 3);
-
- /* Perform some sanity checks on this filter parameters. Note that we
- * allow only DELTA, E8/E9 and ARM filters here, because rest of
- * filters are not used in RARv5. */
-
- if(block_length < 4 ||
- block_length > 0x400000 ||
- filter_type > FILTER_ARM ||
- !is_valid_filter_block_start(rar, block_start))
- {
- archive_set_error(&ar->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid filter encountered");
- return ARCHIVE_FATAL;
- }
-
- /* Allocate a new filter. */
- filt = add_new_filter(rar);
- if(filt == NULL) {
- archive_set_error(&ar->archive, ENOMEM,
- "Can't allocate memory for a filter descriptor.");
- return ARCHIVE_FATAL;
- }
-
- filt->type = filter_type;
- filt->block_start = rar->cstate.write_ptr + block_start;
- filt->block_length = block_length;
-
- rar->cstate.last_block_start = filt->block_start;
- rar->cstate.last_block_length = filt->block_length;
-
- /* Read some more data in case this is a DELTA filter. Other filter
- * types don't require any additional data over what was already
- * read. */
- if(filter_type == FILTER_DELTA) {
- int channels;
-
- if(ARCHIVE_OK != (ret = read_consume_bits(ar, rar, p, 5, &channels)))
- return ret;
-
- filt->channels = channels + 1;
- }
-
- return ARCHIVE_OK;
-}
-
-static int decode_code_length(struct archive_read* a, struct rar5* rar,
- const uint8_t* p, uint16_t code)
-{
- int lbits, length = 2;
-
- if(code < 8) {
- lbits = 0;
- length += code;
- } else {
- lbits = code / 4 - 1;
- length += (4 | (code & 3)) << lbits;
- }
-
- if(lbits > 0) {
- int add;
-
- if(ARCHIVE_OK != read_consume_bits(a, rar, p, lbits, &add))
- return -1;
-
- length += add;
- }
-
- return length;
-}
-
-static int copy_string(struct archive_read* a, int len, int dist) {
- struct rar5* rar = get_context(a);
- const uint64_t cmask = rar->cstate.window_mask;
- const uint64_t write_ptr = rar->cstate.write_ptr +
- rar->cstate.solid_offset;
- int i;
-
- if (rar->cstate.window_buf == NULL)
- return ARCHIVE_FATAL;
-
- /* The unpacker spends most of the time in this function. It would be
- * a good idea to introduce some optimizations here.
- *
- * Just remember that this loop treats buffers that overlap differently
- * than buffers that do not overlap. This is why a simple memcpy(3)
- * call will not be enough. */
-
- for(i = 0; i < len; i++) {
- const ssize_t write_idx = (write_ptr + i) & cmask;
- const ssize_t read_idx = (write_ptr + i - dist) & cmask;
- rar->cstate.window_buf[write_idx] =
- rar->cstate.window_buf[read_idx];
- }
-
- rar->cstate.write_ptr += len;
- return ARCHIVE_OK;
-}
-
-static int do_uncompress_block(struct archive_read* a, const uint8_t* p) {
- struct rar5* rar = get_context(a);
- uint16_t num;
- int ret;
-
- const uint64_t cmask = rar->cstate.window_mask;
- const struct compressed_block_header* hdr = &rar->last_block_hdr;
- const uint8_t bit_size = 1 + bf_bit_size(hdr);
-
- while(1) {
- if(rar->cstate.write_ptr - rar->cstate.last_write_ptr >
- (rar->cstate.window_size >> 1)) {
- /* Don't allow growing data by more than half of the
- * window size at a time. In such case, break the loop;
- * next call to this function will continue processing
- * from this moment. */
- break;
- }
-
- if(rar->bits.in_addr > rar->cstate.cur_block_size - 1 ||
- (rar->bits.in_addr == rar->cstate.cur_block_size - 1 &&
- rar->bits.bit_addr >= bit_size))
- {
- /* If the program counter is here, it means the
- * function has finished processing the block. */
- rar->cstate.block_parsing_finished = 1;
- break;
- }
-
- /* Decode the next literal. */
- if(ARCHIVE_OK != decode_number(a, &rar->cstate.ld, p, &num)) {
- return ARCHIVE_EOF;
- }
-
- /* Num holds a decompression literal, or 'command code'.
- *
- * - Values lower than 256 are just bytes. Those codes
- * can be stored in the output buffer directly.
- *
- * - Code 256 defines a new filter, which is later used to
- * ransform the data block accordingly to the filter type.
- * The data block needs to be fully uncompressed first.
- *
- * - Code bigger than 257 and smaller than 262 define
- * a repetition pattern that should be copied from
- * an already uncompressed chunk of data.
- */
-
- if(num < 256) {
- /* Directly store the byte. */
- int64_t write_idx = rar->cstate.solid_offset +
- rar->cstate.write_ptr++;
-
- rar->cstate.window_buf[write_idx & cmask] =
- (uint8_t) num;
- continue;
- } else if(num >= 262) {
- uint16_t dist_slot;
- int len = decode_code_length(a, rar, p, num - 262),
- dbits,
- dist = 1;
-
- if(len == -1) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_PROGRAMMER,
- "Failed to decode the code length");
-
- return ARCHIVE_FATAL;
- }
-
- if(ARCHIVE_OK != decode_number(a, &rar->cstate.dd, p,
- &dist_slot))
- {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_PROGRAMMER,
- "Failed to decode the distance slot");
-
- return ARCHIVE_FATAL;
- }
-
- if(dist_slot < 4) {
- dbits = 0;
- dist += dist_slot;
- } else {
- dbits = dist_slot / 2 - 1;
-
- /* Cast to uint32_t will make sure the shift
- * left operation won't produce undefined
- * result. Then, the uint32_t type will
- * be implicitly casted to int. */
- dist += (uint32_t) (2 |
- (dist_slot & 1)) << dbits;
- }
-
- if(dbits > 0) {
- if(dbits >= 4) {
- uint32_t add = 0;
- uint16_t low_dist;
-
- if(dbits > 4) {
- if(ARCHIVE_OK != (ret = read_bits_32(
- a, rar, p, &add))) {
- /* Return EOF if we
- * can't read more
- * data. */
- return ret;
- }
-
- skip_bits(rar, dbits - 4);
- add = (add >> (
- 36 - dbits)) << 4;
- dist += add;
- }
-
- if(ARCHIVE_OK != decode_number(a,
- &rar->cstate.ldd, p, &low_dist))
- {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_PROGRAMMER,
- "Failed to decode the "
- "distance slot");
-
- return ARCHIVE_FATAL;
- }
-
- if(dist >= INT_MAX - low_dist - 1) {
- /* This only happens in
- * invalid archives. */
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Distance pointer "
- "overflow");
- return ARCHIVE_FATAL;
- }
-
- dist += low_dist;
- } else {
- /* dbits is one of [0,1,2,3] */
- int add;
-
- if(ARCHIVE_OK != (ret = read_consume_bits(a, rar,
- p, dbits, &add))) {
- /* Return EOF if we can't read
- * more data. */
- return ret;
- }
-
- dist += add;
- }
- }
-
- if(dist > 0x100) {
- len++;
-
- if(dist > 0x2000) {
- len++;
-
- if(dist > 0x40000) {
- len++;
- }
- }
- }
-
- dist_cache_push(rar, dist);
- rar->cstate.last_len = len;
-
- if(ARCHIVE_OK != copy_string(a, len, dist))
- return ARCHIVE_FATAL;
-
- continue;
- } else if(num == 256) {
- /* Create a filter. */
- ret = parse_filter(a, p);
- if(ret != ARCHIVE_OK)
- return ret;
-
- continue;
- } else if(num == 257) {
- if(rar->cstate.last_len != 0) {
- if(ARCHIVE_OK != copy_string(a,
- rar->cstate.last_len,
- rar->cstate.dist_cache[0]))
- {
- return ARCHIVE_FATAL;
- }
- }
-
- continue;
- } else {
- /* num < 262 */
- const int idx = num - 258;
- const int dist = dist_cache_touch(rar, idx);
-
- uint16_t len_slot;
- int len;
-
- if(ARCHIVE_OK != decode_number(a, &rar->cstate.rd, p,
- &len_slot)) {
- return ARCHIVE_FATAL;
- }
-
- len = decode_code_length(a, rar, p, len_slot);
- if (len == -1) {
- return ARCHIVE_FATAL;
- }
-
- rar->cstate.last_len = len;
-
- if(ARCHIVE_OK != copy_string(a, len, dist))
- return ARCHIVE_FATAL;
-
- continue;
- }
- }
-
- return ARCHIVE_OK;
-}
-
-/* Binary search for the RARv5 signature. */
-static int scan_for_signature(struct archive_read* a) {
- const uint8_t* p;
- const int chunk_size = 512;
- ssize_t i;
- char signature[sizeof(rar5_signature_xor)];
-
- /* If we're here, it means we're on an 'unknown territory' data.
- * There's no indication what kind of data we're reading here.
- * It could be some text comment, any kind of binary data,
- * digital sign, dragons, etc.
- *
- * We want to find a valid RARv5 magic header inside this unknown
- * data. */
-
- /* Is it possible in libarchive to just skip everything until the
- * end of the file? If so, it would be a better approach than the
- * current implementation of this function. */
-
- rar5_signature(signature);
-
- while(1) {
- if(!read_ahead(a, chunk_size, &p))
- return ARCHIVE_EOF;
-
- for(i = 0; i < chunk_size - (int)sizeof(rar5_signature_xor);
- i++) {
- if(memcmp(&p[i], signature,
- sizeof(rar5_signature_xor)) == 0) {
- /* Consume the number of bytes we've used to
- * search for the signature, as well as the
- * number of bytes used by the signature
- * itself. After this we should be standing
- * on a valid base block header. */
- (void) consume(a,
- i + sizeof(rar5_signature_xor));
- return ARCHIVE_OK;
- }
- }
-
- consume(a, chunk_size);
- }
-
- return ARCHIVE_FATAL;
-}
-
-/* This function will switch the multivolume archive file to another file,
- * i.e. from part03 to part 04. */
-static int advance_multivolume(struct archive_read* a) {
- int lret;
- struct rar5* rar = get_context(a);
-
- /* A small state machine that will skip unnecessary data, needed to
- * switch from one multivolume to another. Such skipping is needed if
- * we want to be an stream-oriented (instead of file-oriented)
- * unpacker.
- *
- * The state machine starts with `rar->main.endarc` == 0. It also
- * assumes that current stream pointer points to some base block
- * header.
- *
- * The `endarc` field is being set when the base block parsing
- * function encounters the 'end of archive' marker.
- */
-
- while(1) {
- if(rar->main.endarc == 1) {
- int looping = 1;
-
- rar->main.endarc = 0;
-
- while(looping) {
- lret = skip_base_block(a);
- switch(lret) {
- case ARCHIVE_RETRY:
- /* Continue looping. */
- break;
- case ARCHIVE_OK:
- /* Break loop. */
- looping = 0;
- break;
- default:
- /* Forward any errors to the
- * caller. */
- return lret;
- }
- }
-
- break;
- } else {
- /* Skip current base block. In order to properly skip
- * it, we really need to simply parse it and discard
- * the results. */
-
- lret = skip_base_block(a);
- if(lret == ARCHIVE_FATAL || lret == ARCHIVE_FAILED)
- return lret;
-
- /* The `skip_base_block` function tells us if we
- * should continue with skipping, or we should stop
- * skipping. We're trying to skip everything up to
- * a base FILE block. */
-
- if(lret != ARCHIVE_RETRY) {
- /* If there was an error during skipping, or we
- * have just skipped a FILE base block... */
-
- if(rar->main.endarc == 0) {
- return lret;
- } else {
- continue;
- }
- }
- }
- }
-
- return ARCHIVE_OK;
-}
-
-/* Merges the partial block from the first multivolume archive file, and
- * partial block from the second multivolume archive file. The result is
- * a chunk of memory containing the whole block, and the stream pointer
- * is advanced to the next block in the second multivolume archive file. */
-static int merge_block(struct archive_read* a, ssize_t block_size,
- const uint8_t** p)
-{
- struct rar5* rar = get_context(a);
- ssize_t cur_block_size, partial_offset = 0;
- const uint8_t* lp;
- int ret;
-
- if(rar->merge_mode) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Recursive merge is not allowed");
-
- return ARCHIVE_FATAL;
- }
-
- /* Set a flag that we're in the switching mode. */
- rar->cstate.switch_multivolume = 1;
-
- /* Reallocate the memory which will hold the whole block. */
- if(rar->vol.push_buf)
- free((void*) rar->vol.push_buf);
-
- /* Increasing the allocation block by 8 is due to bit reading functions,
- * which are using additional 2 or 4 bytes. Allocating the block size
- * by exact value would make bit reader perform reads from invalid
- * memory block when reading the last byte from the buffer. */
- rar->vol.push_buf = malloc(block_size + 8);
- if(!rar->vol.push_buf) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for a merge block buffer.");
- return ARCHIVE_FATAL;
- }
-
- /* Valgrind complains if the extension block for bit reader is not
- * initialized, so initialize it. */
- memset(&rar->vol.push_buf[block_size], 0, 8);
-
- /* A single block can span across multiple multivolume archive files,
- * so we use a loop here. This loop will consume enough multivolume
- * archive files until the whole block is read. */
-
- while(1) {
- /* Get the size of current block chunk in this multivolume
- * archive file and read it. */
- cur_block_size = rar5_min(rar->file.bytes_remaining,
- block_size - partial_offset);
-
- if(cur_block_size == 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Encountered block size == 0 during block merge");
- return ARCHIVE_FATAL;
- }
-
- if(!read_ahead(a, cur_block_size, &lp))
- return ARCHIVE_EOF;
-
- /* Sanity check; there should never be a situation where this
- * function reads more data than the block's size. */
- if(partial_offset + cur_block_size > block_size) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_PROGRAMMER,
- "Consumed too much data when merging blocks.");
- return ARCHIVE_FATAL;
- }
-
- /* Merge previous block chunk with current block chunk,
- * or create first block chunk if this is our first
- * iteration. */
- memcpy(&rar->vol.push_buf[partial_offset], lp, cur_block_size);
-
- /* Advance the stream read pointer by this block chunk size. */
- if(ARCHIVE_OK != consume(a, cur_block_size))
- return ARCHIVE_EOF;
-
- /* Update the pointers. `partial_offset` contains information
- * about the sum of merged block chunks. */
- partial_offset += cur_block_size;
- rar->file.bytes_remaining -= cur_block_size;
-
- /* If `partial_offset` is the same as `block_size`, this means
- * we've merged all block chunks and we have a valid full
- * block. */
- if(partial_offset == block_size) {
- break;
- }
-
- /* If we don't have any bytes to read, this means we should
- * switch to another multivolume archive file. */
- if(rar->file.bytes_remaining == 0) {
- rar->merge_mode++;
- ret = advance_multivolume(a);
- rar->merge_mode--;
- if(ret != ARCHIVE_OK) {
- return ret;
- }
- }
- }
-
- *p = rar->vol.push_buf;
-
- /* If we're here, we can resume unpacking by processing the block
- * pointed to by the `*p` memory pointer. */
-
- return ARCHIVE_OK;
-}
-
-static int process_block(struct archive_read* a) {
- const uint8_t* p;
- struct rar5* rar = get_context(a);
- int ret;
-
- /* If we don't have any data to be processed, this most probably means
- * we need to switch to the next volume. */
- if(rar->main.volume && rar->file.bytes_remaining == 0) {
- ret = advance_multivolume(a);
- if(ret != ARCHIVE_OK)
- return ret;
- }
-
- if(rar->cstate.block_parsing_finished) {
- ssize_t block_size;
- ssize_t to_skip;
- ssize_t cur_block_size;
-
- /* The header size won't be bigger than 6 bytes. */
- if(!read_ahead(a, 6, &p)) {
- /* Failed to prefetch data block header. */
- return ARCHIVE_EOF;
- }
-
- /*
- * Read block_size by parsing block header. Validate the header
- * by calculating CRC byte stored inside the header. Size of
- * the header is not constant (block size can be stored either
- * in 1 or 2 bytes), that's why block size is left out from the
- * `compressed_block_header` structure and returned by
- * `parse_block_header` as the second argument. */
-
- ret = parse_block_header(a, p, &block_size,
- &rar->last_block_hdr);
- if(ret != ARCHIVE_OK) {
- return ret;
- }
-
- /* Skip block header. Next data is huffman tables,
- * if present. */
- to_skip = sizeof(struct compressed_block_header) +
- bf_byte_count(&rar->last_block_hdr) + 1;
-
- if(ARCHIVE_OK != consume(a, to_skip))
- return ARCHIVE_EOF;
-
- rar->file.bytes_remaining -= to_skip;
-
- /* The block size gives information about the whole block size,
- * but the block could be stored in split form when using
- * multi-volume archives. In this case, the block size will be
- * bigger than the actual data stored in this file. Remaining
- * part of the data will be in another file. */
-
- cur_block_size =
- rar5_min(rar->file.bytes_remaining, block_size);
-
- if(block_size > rar->file.bytes_remaining) {
- /* If current blocks' size is bigger than our data
- * size, this means we have a multivolume archive.
- * In this case, skip all base headers until the end
- * of the file, proceed to next "partXXX.rar" volume,
- * find its signature, skip all headers up to the first
- * FILE base header, and continue from there.
- *
- * Note that `merge_block` will update the `rar`
- * context structure quite extensively. */
-
- ret = merge_block(a, block_size, &p);
- if(ret != ARCHIVE_OK) {
- return ret;
- }
-
- cur_block_size = block_size;
-
- /* Current stream pointer should be now directly
- * *after* the block that spanned through multiple
- * archive files. `p` pointer should have the data of
- * the *whole* block (merged from partial blocks
- * stored in multiple archives files). */
- } else {
- rar->cstate.switch_multivolume = 0;
-
- /* Read the whole block size into memory. This can take
- * up to 8 megabytes of memory in theoretical cases.
- * Might be worth to optimize this and use a standard
- * chunk of 4kb's. */
- if(!read_ahead(a, 4 + cur_block_size, &p)) {
- /* Failed to prefetch block data. */
- return ARCHIVE_EOF;
- }
- }
-
- rar->cstate.block_buf = p;
- rar->cstate.cur_block_size = cur_block_size;
- rar->cstate.block_parsing_finished = 0;
-
- rar->bits.in_addr = 0;
- rar->bits.bit_addr = 0;
-
- if(bf_is_table_present(&rar->last_block_hdr)) {
- /* Load Huffman tables. */
- ret = parse_tables(a, rar, p);
- if(ret != ARCHIVE_OK) {
- /* Error during decompression of Huffman
- * tables. */
- return ret;
- }
- }
- } else {
- /* Block parsing not finished, reuse previous memory buffer. */
- p = rar->cstate.block_buf;
- }
-
- /* Uncompress the block, or a part of it, depending on how many bytes
- * will be generated by uncompressing the block.
- *
- * In case too many bytes will be generated, calling this function
- * again will resume the uncompression operation. */
- ret = do_uncompress_block(a, p);
- if(ret != ARCHIVE_OK) {
- return ret;
- }
-
- if(rar->cstate.block_parsing_finished &&
- rar->cstate.switch_multivolume == 0 &&
- rar->cstate.cur_block_size > 0)
- {
- /* If we're processing a normal block, consume the whole
- * block. We can do this because we've already read the whole
- * block to memory. */
- if(ARCHIVE_OK != consume(a, rar->cstate.cur_block_size))
- return ARCHIVE_FATAL;
-
- rar->file.bytes_remaining -= rar->cstate.cur_block_size;
- } else if(rar->cstate.switch_multivolume) {
- /* Don't consume the block if we're doing multivolume
- * processing. The volume switching function will consume
- * the proper count of bytes instead. */
- rar->cstate.switch_multivolume = 0;
- }
-
- return ARCHIVE_OK;
-}
-
-/* Pops the `buf`, `size` and `offset` from the "data ready" stack.
- *
- * Returns ARCHIVE_OK when those arguments can be used, ARCHIVE_RETRY
- * when there is no data on the stack. */
-static int use_data(struct rar5* rar, const void** buf, size_t* size,
- int64_t* offset)
-{
- int i;
-
- for(i = 0; i < rar5_countof(rar->cstate.dready); i++) {
- struct data_ready *d = &rar->cstate.dready[i];
-
- if(d->used) {
- if(buf) *buf = d->buf;
- if(size) *size = d->size;
- if(offset) *offset = d->offset;
-
- d->used = 0;
- return ARCHIVE_OK;
- }
- }
-
- return ARCHIVE_RETRY;
-}
-
-/* Pushes the `buf`, `size` and `offset` arguments to the rar->cstate.dready
- * FIFO stack. Those values will be popped from this stack by the `use_data`
- * function. */
-static int push_data_ready(struct archive_read* a, struct rar5* rar,
- const uint8_t* buf, size_t size, int64_t offset)
-{
- int i;
-
- /* Don't push if we're in skip mode. This is needed because solid
- * streams need full processing even if we're skipping data. After
- * fully processing the stream, we need to discard the generated bytes,
- * because we're interested only in the side effect: building up the
- * internal window circular buffer. This window buffer will be used
- * later during unpacking of requested data. */
- if(rar->skip_mode)
- return ARCHIVE_OK;
-
- /* Sanity check. */
- if(offset != rar->file.last_offset + rar->file.last_size) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Sanity check error: output stream is not continuous");
- return ARCHIVE_FATAL;
- }
-
- for(i = 0; i < rar5_countof(rar->cstate.dready); i++) {
- struct data_ready* d = &rar->cstate.dready[i];
- if(!d->used) {
- d->used = 1;
- d->buf = buf;
- d->size = size;
- d->offset = offset;
-
- /* These fields are used only in sanity checking. */
- rar->file.last_offset = offset;
- rar->file.last_size = size;
-
- /* Calculate the checksum of this new block before
- * submitting data to libarchive's engine. */
- update_crc(rar, d->buf, d->size);
-
- return ARCHIVE_OK;
- }
- }
-
- /* Program counter will reach this code if the `rar->cstate.data_ready`
- * stack will be filled up so that no new entries will be allowed. The
- * code shouldn't allow such situation to occur. So we treat this case
- * as an internal error. */
-
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Error: premature end of data_ready stack");
- return ARCHIVE_FATAL;
-}
-
-/* This function uncompresses the data that is stored in the <FILE> base
- * block.
- *
- * The FILE base block looks like this:
- *
- * <header><huffman tables><block_1><block_2>...<block_n>
- *
- * The <header> is a block header, that is parsed in parse_block_header().
- * It's a "compressed_block_header" structure, containing metadata needed
- * to know when we should stop looking for more <block_n> blocks.
- *
- * <huffman tables> contain data needed to set up the huffman tables, needed
- * for the actual decompression.
- *
- * Each <block_n> consists of series of literals:
- *
- * <literal><literal><literal>...<literal>
- *
- * Those literals generate the uncompression data. They operate on a circular
- * buffer, sometimes writing raw data into it, sometimes referencing
- * some previous data inside this buffer, and sometimes declaring a filter
- * that will need to be executed on the data stored in the circular buffer.
- * It all depends on the literal that is used.
- *
- * Sometimes blocks produce output data, sometimes they don't. For example, for
- * some huge files that use lots of filters, sometimes a block is filled with
- * only filter declaration literals. Such blocks won't produce any data in the
- * circular buffer.
- *
- * Sometimes blocks will produce 4 bytes of data, and sometimes 1 megabyte,
- * because a literal can reference previously decompressed data. For example,
- * there can be a literal that says: 'append a byte 0xFE here', and after
- * it another literal can say 'append 1 megabyte of data from circular buffer
- * offset 0x12345'. This is how RAR format handles compressing repeated
- * patterns.
- *
- * The RAR compressor creates those literals and the actual efficiency of
- * compression depends on what those literals are. The literals can also
- * be seen as a kind of a non-turing-complete virtual machine that simply
- * tells the decompressor what it should do.
- * */
-
-static int do_uncompress_file(struct archive_read* a) {
- struct rar5* rar = get_context(a);
- int ret;
- int64_t max_end_pos;
-
- if(!rar->cstate.initialized) {
- /* Don't perform full context reinitialization if we're
- * processing a solid archive. */
- if(!rar->main.solid || !rar->cstate.window_buf) {
- init_unpack(rar);
- }
-
- rar->cstate.initialized = 1;
- }
-
- /* Don't allow extraction if window_size is invalid. */
- if(rar->cstate.window_size == 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid window size declaration in this file");
-
- /* This should never happen in valid files. */
- return ARCHIVE_FATAL;
- }
-
- if(rar->cstate.all_filters_applied == 1) {
- /* We use while(1) here, but standard case allows for just 1
- * iteration. The loop will iterate if process_block() didn't
- * generate any data at all. This can happen if the block
- * contains only filter definitions (this is common in big
- * files). */
- while(1) {
- ret = process_block(a);
- if(ret == ARCHIVE_EOF || ret == ARCHIVE_FATAL)
- return ret;
-
- if(rar->cstate.last_write_ptr ==
- rar->cstate.write_ptr) {
- /* The block didn't generate any new data,
- * so just process a new block. */
- continue;
- }
-
- /* The block has generated some new data, so break
- * the loop. */
- break;
- }
- }
-
- /* Try to run filters. If filters won't be applied, it means that
- * insufficient data was generated. */
- ret = apply_filters(a);
- if(ret == ARCHIVE_RETRY) {
- return ARCHIVE_OK;
- } else if(ret == ARCHIVE_FATAL) {
- return ARCHIVE_FATAL;
- }
-
- /* If apply_filters() will return ARCHIVE_OK, we can continue here. */
-
- if(cdeque_size(&rar->cstate.filters) > 0) {
- /* Check if we can write something before hitting first
- * filter. */
- struct filter_info* flt;
-
- /* Get the block_start offset from the first filter. */
- if(CDE_OK != cdeque_front(&rar->cstate.filters,
- cdeque_filter_p(&flt)))
- {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_PROGRAMMER,
- "Can't read first filter");
- return ARCHIVE_FATAL;
- }
-
- max_end_pos = rar5_min(flt->block_start,
- rar->cstate.write_ptr);
- } else {
- /* There are no filters defined, or all filters were applied.
- * This means we can just store the data without any
- * postprocessing. */
- max_end_pos = rar->cstate.write_ptr;
- }
-
- if(max_end_pos == rar->cstate.last_write_ptr) {
- /* We can't write anything yet. The block uncompression
- * function did not generate enough data, and no filter can be
- * applied. At the same time we don't have any data that can be
- * stored without filter postprocessing. This means we need to
- * wait for more data to be generated, so we can apply the
- * filters.
- *
- * Signal the caller that we need more data to be able to do
- * anything.
- */
- return ARCHIVE_RETRY;
- } else {
- /* We can write the data before hitting the first filter.
- * So let's do it. The push_window_data() function will
- * effectively return the selected data block to the user
- * application. */
- push_window_data(a, rar, rar->cstate.last_write_ptr,
- max_end_pos);
- rar->cstate.last_write_ptr = max_end_pos;
- }
-
- return ARCHIVE_OK;
-}
-
-static int uncompress_file(struct archive_read* a) {
- int ret;
-
- while(1) {
- /* Sometimes the uncompression function will return a
- * 'retry' signal. If this will happen, we have to retry
- * the function. */
- ret = do_uncompress_file(a);
- if(ret != ARCHIVE_RETRY)
- return ret;
- }
-}
-
-
-static int do_unstore_file(struct archive_read* a,
- struct rar5* rar, const void** buf, size_t* size, int64_t* offset)
-{
- size_t to_read;
- const uint8_t* p;
-
- if(rar->file.bytes_remaining == 0 && rar->main.volume > 0 &&
- rar->generic.split_after > 0)
- {
- int ret;
-
- rar->cstate.switch_multivolume = 1;
- ret = advance_multivolume(a);
- rar->cstate.switch_multivolume = 0;
-
- if(ret != ARCHIVE_OK) {
- /* Failed to advance to next multivolume archive
- * file. */
- return ret;
- }
- }
-
- to_read = rar5_min(rar->file.bytes_remaining, 64 * 1024);
- if(to_read == 0) {
- return ARCHIVE_EOF;
- }
-
- if(!read_ahead(a, to_read, &p)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "I/O error when unstoring file");
- return ARCHIVE_FATAL;
- }
-
- if(ARCHIVE_OK != consume(a, to_read)) {
- return ARCHIVE_EOF;
- }
-
- if(buf) *buf = p;
- if(size) *size = to_read;
- if(offset) *offset = rar->cstate.last_unstore_ptr;
-
- rar->file.bytes_remaining -= to_read;
- rar->cstate.last_unstore_ptr += to_read;
-
- update_crc(rar, p, to_read);
- return ARCHIVE_OK;
-}
-
-static int do_unpack(struct archive_read* a, struct rar5* rar,
- const void** buf, size_t* size, int64_t* offset)
-{
- enum COMPRESSION_METHOD {
- STORE = 0, FASTEST = 1, FAST = 2, NORMAL = 3, GOOD = 4,
- BEST = 5
- };
-
- if(rar->file.service > 0) {
- return do_unstore_file(a, rar, buf, size, offset);
- } else {
- switch(rar->cstate.method) {
- case STORE:
- return do_unstore_file(a, rar, buf, size,
- offset);
- case FASTEST:
- /* fallthrough */
- case FAST:
- /* fallthrough */
- case NORMAL:
- /* fallthrough */
- case GOOD:
- /* fallthrough */
- case BEST:
- /* No data is returned here. But because a sparse-file aware
- * caller (like archive_read_data_into_fd) may treat zero-size
- * as a sparse file block, we need to update the offset
- * accordingly. At this point the decoder doesn't have any
- * pending uncompressed data blocks, so the current position in
- * the output file should be last_write_ptr. */
- if (offset) *offset = rar->cstate.last_write_ptr;
- return uncompress_file(a);
- default:
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Compression method not supported: 0x%x",
- rar->cstate.method);
-
- return ARCHIVE_FATAL;
- }
- }
-
-#if !defined WIN32
- /* Not reached. */
- return ARCHIVE_OK;
-#endif
-}
-
-static int verify_checksums(struct archive_read* a) {
- int verify_crc;
- struct rar5* rar = get_context(a);
-
- /* Check checksums only when actually unpacking the data. There's no
- * need to calculate checksum when we're skipping data in solid archives
- * (skipping in solid archives is the same thing as unpacking compressed
- * data and discarding the result). */
-
- if(!rar->skip_mode) {
- /* Always check checksums if we're not in skip mode */
- verify_crc = 1;
- } else {
- /* We can override the logic above with a compile-time option
- * NO_CRC_ON_SOLID_SKIP. This option is used during debugging,
- * and it will check checksums of unpacked data even when
- * we're skipping it. */
-
-#if defined CHECK_CRC_ON_SOLID_SKIP
- /* Debug case */
- verify_crc = 1;
-#else
- /* Normal case */
- verify_crc = 0;
-#endif
- }
-
- if(verify_crc) {
- /* During unpacking, on each unpacked block we're calling the
- * update_crc() function. Since we are here, the unpacking
- * process is already over and we can check if calculated
- * checksum (CRC32 or BLAKE2sp) is the same as what is stored
- * in the archive. */
- if(rar->file.stored_crc32 > 0) {
- /* Check CRC32 only when the file contains a CRC32
- * value for this file. */
-
- if(rar->file.calculated_crc32 !=
- rar->file.stored_crc32) {
- /* Checksums do not match; the unpacked file
- * is corrupted. */
-
- DEBUG_CODE {
- printf("Checksum error: CRC32 "
- "(was: %08" PRIx32 ", expected: %08" PRIx32 ")\n",
- rar->file.calculated_crc32,
- rar->file.stored_crc32);
- }
-
-#ifndef DONT_FAIL_ON_CRC_ERROR
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Checksum error: CRC32");
- return ARCHIVE_FATAL;
-#endif
- } else {
- DEBUG_CODE {
- printf("Checksum OK: CRC32 "
- "(%08" PRIx32 "/%08" PRIx32 ")\n",
- rar->file.stored_crc32,
- rar->file.calculated_crc32);
- }
- }
- }
-
- if(rar->file.has_blake2 > 0) {
- /* BLAKE2sp is an optional checksum algorithm that is
- * added to RARv5 archives when using the `-htb` switch
- * during creation of archive.
- *
- * We now finalize the hash calculation by calling the
- * `final` function. This will generate the final hash
- * value we can use to compare it with the BLAKE2sp
- * checksum that is stored in the archive.
- *
- * The return value of this `final` function is not
- * very helpful, as it guards only against improper use.
- * This is why we're explicitly ignoring it. */
-
- uint8_t b2_buf[32];
- (void) blake2sp_final(&rar->file.b2state, b2_buf, 32);
-
- if(memcmp(&rar->file.blake2sp, b2_buf, 32) != 0) {
-#ifndef DONT_FAIL_ON_CRC_ERROR
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Checksum error: BLAKE2");
-
- return ARCHIVE_FATAL;
-#endif
- }
- }
- }
-
- /* Finalization for this file has been successfully completed. */
- return ARCHIVE_OK;
-}
-
-static int verify_global_checksums(struct archive_read* a) {
- return verify_checksums(a);
-}
-
-/*
- * Decryption function for the magic signature pattern. Check the comment near
- * the `rar5_signature_xor` symbol to read the rationale behind this.
- */
-static void rar5_signature(char *buf) {
- size_t i;
-
- for(i = 0; i < sizeof(rar5_signature_xor); i++) {
- buf[i] = rar5_signature_xor[i] ^ 0xA1;
- }
-}
-
-static int rar5_read_data(struct archive_read *a, const void **buff,
- size_t *size, int64_t *offset) {
- int ret;
- struct rar5* rar = get_context(a);
-
- if (size)
- *size = 0;
-
- if(rar->file.dir > 0) {
- /* Don't process any data if this file entry was declared
- * as a directory. This is needed, because entries marked as
- * directory doesn't have any dictionary buffer allocated, so
- * it's impossible to perform any decompression. */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't decompress an entry marked as a directory");
- return ARCHIVE_FAILED;
- }
-
- if(!rar->skip_mode && (rar->cstate.last_write_ptr > rar->file.unpacked_size)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Unpacker has written too many bytes");
- return ARCHIVE_FATAL;
- }
-
- ret = use_data(rar, buff, size, offset);
- if(ret == ARCHIVE_OK) {
- return ret;
- }
-
- if(rar->file.eof == 1) {
- return ARCHIVE_EOF;
- }
-
- ret = do_unpack(a, rar, buff, size, offset);
- if(ret != ARCHIVE_OK) {
- return ret;
- }
-
- if(rar->file.bytes_remaining == 0 &&
- rar->cstate.last_write_ptr == rar->file.unpacked_size)
- {
- /* If all bytes of current file were processed, run
- * finalization.
- *
- * Finalization will check checksum against proper values. If
- * some of the checksums will not match, we'll return an error
- * value in the last `archive_read_data` call to signal an error
- * to the user. */
-
- rar->file.eof = 1;
- return verify_global_checksums(a);
- }
-
- return ARCHIVE_OK;
-}
-
-static int rar5_read_data_skip(struct archive_read *a) {
- struct rar5* rar = get_context(a);
-
- if(rar->main.solid) {
- /* In solid archives, instead of skipping the data, we need to
- * extract it, and dispose the result. The side effect of this
- * operation will be setting up the initial window buffer state
- * needed to be able to extract the selected file. */
-
- int ret;
-
- /* Make sure to process all blocks in the compressed stream. */
- while(rar->file.bytes_remaining > 0) {
- /* Setting the "skip mode" will allow us to skip
- * checksum checks during data skipping. Checking the
- * checksum of skipped data isn't really necessary and
- * it's only slowing things down.
- *
- * This is incremented instead of setting to 1 because
- * this data skipping function can be called
- * recursively. */
- rar->skip_mode++;
-
- /* We're disposing 1 block of data, so we use triple
- * NULLs in arguments. */
- ret = rar5_read_data(a, NULL, NULL, NULL);
-
- /* Turn off "skip mode". */
- rar->skip_mode--;
-
- if(ret < 0 || ret == ARCHIVE_EOF) {
- /* Propagate any potential error conditions
- * to the caller. */
- return ret;
- }
- }
- } else {
- /* In standard archives, we can just jump over the compressed
- * stream. Each file in non-solid archives starts from an empty
- * window buffer. */
-
- if(ARCHIVE_OK != consume(a, rar->file.bytes_remaining)) {
- return ARCHIVE_FATAL;
- }
-
- rar->file.bytes_remaining = 0;
- }
-
- return ARCHIVE_OK;
-}
-
-static int64_t rar5_seek_data(struct archive_read *a, int64_t offset,
- int whence)
-{
- (void) a;
- (void) offset;
- (void) whence;
-
- /* We're a streaming unpacker, and we don't support seeking. */
-
- return ARCHIVE_FATAL;
-}
-
-static int rar5_cleanup(struct archive_read *a) {
- struct rar5* rar = get_context(a);
-
- free(rar->cstate.window_buf);
- free(rar->cstate.filtered_buf);
-
- free(rar->vol.push_buf);
-
- free_filters(rar);
- cdeque_free(&rar->cstate.filters);
-
- free(rar);
- a->format->data = NULL;
-
- return ARCHIVE_OK;
-}
-
-static int rar5_capabilities(struct archive_read * a) {
- (void) a;
- return 0;
-}
-
-static int rar5_has_encrypted_entries(struct archive_read *_a) {
- (void) _a;
-
- /* Unsupported for now. */
- return ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED;
-}
-
-static int rar5_init(struct rar5* rar) {
- memset(rar, 0, sizeof(struct rar5));
-
- if(CDE_OK != cdeque_init(&rar->cstate.filters, 8192))
- return ARCHIVE_FATAL;
-
- return ARCHIVE_OK;
-}
-
-int archive_read_support_format_rar5(struct archive *_a) {
- struct archive_read* ar;
- int ret;
- struct rar5* rar;
-
- if(ARCHIVE_OK != (ret = get_archive_read(_a, &ar)))
- return ret;
-
- rar = malloc(sizeof(*rar));
- if(rar == NULL) {
- archive_set_error(&ar->archive, ENOMEM,
- "Can't allocate rar5 data");
- return ARCHIVE_FATAL;
- }
-
- if(ARCHIVE_OK != rar5_init(rar)) {
- archive_set_error(&ar->archive, ENOMEM,
- "Can't allocate rar5 filter buffer");
- free(rar);
- return ARCHIVE_FATAL;
- }
-
- ret = __archive_read_register_format(ar,
- rar,
- "rar5",
- rar5_bid,
- rar5_options,
- rar5_read_header,
- rar5_read_data,
- rar5_read_data_skip,
- rar5_seek_data,
- rar5_cleanup,
- rar5_capabilities,
- rar5_has_encrypted_entries);
-
- if(ret != ARCHIVE_OK) {
- (void) rar5_cleanup(ar);
- }
-
- return ret;
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_format_raw.c b/contrib/libs/libarchive/libarchive/archive_read_support_format_raw.c
deleted file mode 100644
index ec0520b60a..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_format_raw.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*-
- * Copyright (c) 2003-2009 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_raw.c 201107 2009-12-28 03:25:33Z kientzle $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-struct raw_info {
- int64_t offset; /* Current position in the file. */
- int64_t unconsumed;
- int end_of_file;
-};
-
-static int archive_read_format_raw_bid(struct archive_read *, int);
-static int archive_read_format_raw_cleanup(struct archive_read *);
-static int archive_read_format_raw_read_data(struct archive_read *,
- const void **, size_t *, int64_t *);
-static int archive_read_format_raw_read_data_skip(struct archive_read *);
-static int archive_read_format_raw_read_header(struct archive_read *,
- struct archive_entry *);
-
-int
-archive_read_support_format_raw(struct archive *_a)
-{
- struct raw_info *info;
- struct archive_read *a = (struct archive_read *)_a;
- int r;
-
- archive_check_magic(_a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_format_raw");
-
- info = (struct raw_info *)calloc(1, sizeof(*info));
- if (info == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate raw_info data");
- return (ARCHIVE_FATAL);
- }
-
- r = __archive_read_register_format(a,
- info,
- "raw",
- archive_read_format_raw_bid,
- NULL,
- archive_read_format_raw_read_header,
- archive_read_format_raw_read_data,
- archive_read_format_raw_read_data_skip,
- NULL,
- archive_read_format_raw_cleanup,
- NULL,
- NULL);
- if (r != ARCHIVE_OK)
- free(info);
- return (r);
-}
-
-/*
- * Bid 1 if this is a non-empty file. Anyone who can really support
- * this should outbid us, so it should generally be safe to use "raw"
- * in conjunction with other formats. But, this could really confuse
- * folks if there are bid errors or minor file damage, so we don't
- * include "raw" as part of support_format_all().
- */
-static int
-archive_read_format_raw_bid(struct archive_read *a, int best_bid)
-{
- if (best_bid < 1 && __archive_read_ahead(a, 1, NULL) != NULL)
- return (1);
- return (-1);
-}
-
-/*
- * Mock up a fake header.
- */
-static int
-archive_read_format_raw_read_header(struct archive_read *a,
- struct archive_entry *entry)
-{
- struct raw_info *info;
-
- info = (struct raw_info *)(a->format->data);
- if (info->end_of_file)
- return (ARCHIVE_EOF);
-
- a->archive.archive_format = ARCHIVE_FORMAT_RAW;
- a->archive.archive_format_name = "raw";
- archive_entry_set_pathname(entry, "data");
- archive_entry_set_filetype(entry, AE_IFREG);
- archive_entry_set_perm(entry, 0644);
- /* I'm deliberately leaving most fields unset here. */
-
- /* Let the filter fill out any fields it might have. */
- return __archive_read_header(a, entry);
-}
-
-static int
-archive_read_format_raw_read_data(struct archive_read *a,
- const void **buff, size_t *size, int64_t *offset)
-{
- struct raw_info *info;
- ssize_t avail;
-
- info = (struct raw_info *)(a->format->data);
-
- /* Consume the bytes we read last time. */
- if (info->unconsumed) {
- __archive_read_consume(a, info->unconsumed);
- info->unconsumed = 0;
- }
-
- if (info->end_of_file)
- return (ARCHIVE_EOF);
-
- /* Get whatever bytes are immediately available. */
- *buff = __archive_read_ahead(a, 1, &avail);
- if (avail > 0) {
- /* Return the bytes we just read */
- *size = avail;
- *offset = info->offset;
- info->offset += *size;
- info->unconsumed = avail;
- return (ARCHIVE_OK);
- } else if (0 == avail) {
- /* Record and return end-of-file. */
- info->end_of_file = 1;
- *size = 0;
- *offset = info->offset;
- return (ARCHIVE_EOF);
- } else {
- /* Record and return an error. */
- *size = 0;
- *offset = info->offset;
- return ((int)avail);
- }
-}
-
-static int
-archive_read_format_raw_read_data_skip(struct archive_read *a)
-{
- struct raw_info *info = (struct raw_info *)(a->format->data);
-
- /* Consume the bytes we read last time. */
- if (info->unconsumed) {
- __archive_read_consume(a, info->unconsumed);
- info->unconsumed = 0;
- }
- info->end_of_file = 1;
- return (ARCHIVE_OK);
-}
-
-static int
-archive_read_format_raw_cleanup(struct archive_read *a)
-{
- struct raw_info *info;
-
- info = (struct raw_info *)(a->format->data);
- free(info);
- a->format->data = NULL;
- return (ARCHIVE_OK);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_format_tar.c b/contrib/libs/libarchive/libarchive/archive_read_support_format_tar.c
deleted file mode 100644
index 93c3fd5857..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_format_tar.c
+++ /dev/null
@@ -1,2946 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * Copyright (c) 2011-2012 Michihiro NAKAJIMA
- * Copyright (c) 2016 Martin Matuska
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_tar.c 201161 2009-12-29 05:44:39Z kientzle $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stddef.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_acl_private.h" /* For ACL parsing routines. */
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-#define tar_min(a,b) ((a) < (b) ? (a) : (b))
-
-/*
- * Layout of POSIX 'ustar' tar header.
- */
-struct archive_entry_header_ustar {
- char name[100];
- char mode[8];
- char uid[8];
- char gid[8];
- char size[12];
- char mtime[12];
- char checksum[8];
- char typeflag[1];
- char linkname[100]; /* "old format" header ends here */
- char magic[6]; /* For POSIX: "ustar\0" */
- char version[2]; /* For POSIX: "00" */
- char uname[32];
- char gname[32];
- char rdevmajor[8];
- char rdevminor[8];
- char prefix[155];
-};
-
-/*
- * Structure of GNU tar header
- */
-struct gnu_sparse {
- char offset[12];
- char numbytes[12];
-};
-
-struct archive_entry_header_gnutar {
- char name[100];
- char mode[8];
- char uid[8];
- char gid[8];
- char size[12];
- char mtime[12];
- char checksum[8];
- char typeflag[1];
- char linkname[100];
- char magic[8]; /* "ustar \0" (note blank/blank/null at end) */
- char uname[32];
- char gname[32];
- char rdevmajor[8];
- char rdevminor[8];
- char atime[12];
- char ctime[12];
- char offset[12];
- char longnames[4];
- char unused[1];
- struct gnu_sparse sparse[4];
- char isextended[1];
- char realsize[12];
- /*
- * Old GNU format doesn't use POSIX 'prefix' field; they use
- * the 'L' (longname) entry instead.
- */
-};
-
-/*
- * Data specific to this format.
- */
-struct sparse_block {
- struct sparse_block *next;
- int64_t offset;
- int64_t remaining;
- int hole;
-};
-
-struct tar {
- struct archive_string acl_text;
- struct archive_string entry_pathname;
- /* For "GNU.sparse.name" and other similar path extensions. */
- struct archive_string entry_pathname_override;
- struct archive_string entry_linkpath;
- struct archive_string entry_uname;
- struct archive_string entry_gname;
- struct archive_string longlink;
- struct archive_string longname;
- struct archive_string pax_header;
- struct archive_string pax_global;
- struct archive_string line;
- int pax_hdrcharset_binary;
- int header_recursion_depth;
- int64_t entry_bytes_remaining;
- int64_t entry_offset;
- int64_t entry_padding;
- int64_t entry_bytes_unconsumed;
- int64_t realsize;
- int sparse_allowed;
- struct sparse_block *sparse_list;
- struct sparse_block *sparse_last;
- int64_t sparse_offset;
- int64_t sparse_numbytes;
- int sparse_gnu_major;
- int sparse_gnu_minor;
- char sparse_gnu_pending;
-
- struct archive_string localname;
- struct archive_string_conv *opt_sconv;
- struct archive_string_conv *sconv;
- struct archive_string_conv *sconv_acl;
- struct archive_string_conv *sconv_default;
- int init_default_conversion;
- int compat_2x;
- int process_mac_extensions;
- int read_concatenated_archives;
- int realsize_override;
-};
-
-static int archive_block_is_null(const char *p);
-static char *base64_decode(const char *, size_t, size_t *);
-static int gnu_add_sparse_entry(struct archive_read *, struct tar *,
- int64_t offset, int64_t remaining);
-
-static void gnu_clear_sparse_list(struct tar *);
-static int gnu_sparse_old_read(struct archive_read *, struct tar *,
- const struct archive_entry_header_gnutar *header, size_t *);
-static int gnu_sparse_old_parse(struct archive_read *, struct tar *,
- const struct gnu_sparse *sparse, int length);
-static int gnu_sparse_01_parse(struct archive_read *, struct tar *,
- const char *);
-static ssize_t gnu_sparse_10_read(struct archive_read *, struct tar *,
- size_t *);
-static int header_Solaris_ACL(struct archive_read *, struct tar *,
- struct archive_entry *, const void *, size_t *);
-static int header_common(struct archive_read *, struct tar *,
- struct archive_entry *, const void *);
-static int header_old_tar(struct archive_read *, struct tar *,
- struct archive_entry *, const void *);
-static int header_pax_extensions(struct archive_read *, struct tar *,
- struct archive_entry *, const void *, size_t *);
-static int header_pax_global(struct archive_read *, struct tar *,
- struct archive_entry *, const void *h, size_t *);
-static int header_longlink(struct archive_read *, struct tar *,
- struct archive_entry *, const void *h, size_t *);
-static int header_longname(struct archive_read *, struct tar *,
- struct archive_entry *, const void *h, size_t *);
-static int read_mac_metadata_blob(struct archive_read *, struct tar *,
- struct archive_entry *, const void *h, size_t *);
-static int header_volume(struct archive_read *, struct tar *,
- struct archive_entry *, const void *h, size_t *);
-static int header_ustar(struct archive_read *, struct tar *,
- struct archive_entry *, const void *h);
-static int header_gnutar(struct archive_read *, struct tar *,
- struct archive_entry *, const void *h, size_t *);
-static int archive_read_format_tar_bid(struct archive_read *, int);
-static int archive_read_format_tar_options(struct archive_read *,
- const char *, const char *);
-static int archive_read_format_tar_cleanup(struct archive_read *);
-static int archive_read_format_tar_read_data(struct archive_read *a,
- const void **buff, size_t *size, int64_t *offset);
-static int archive_read_format_tar_skip(struct archive_read *a);
-static int archive_read_format_tar_read_header(struct archive_read *,
- struct archive_entry *);
-static int checksum(struct archive_read *, const void *);
-static int pax_attribute(struct archive_read *, struct tar *,
- struct archive_entry *, const char *key, const char *value,
- size_t value_length);
-static int pax_attribute_acl(struct archive_read *, struct tar *,
- struct archive_entry *, const char *, int);
-static int pax_attribute_xattr(struct archive_entry *, const char *,
- const char *);
-static int pax_header(struct archive_read *, struct tar *,
- struct archive_entry *, struct archive_string *);
-static void pax_time(const char *, int64_t *sec, long *nanos);
-static ssize_t readline(struct archive_read *, struct tar *, const char **,
- ssize_t limit, size_t *);
-static int read_body_to_string(struct archive_read *, struct tar *,
- struct archive_string *, const void *h, size_t *);
-static int solaris_sparse_parse(struct archive_read *, struct tar *,
- struct archive_entry *, const char *);
-static int64_t tar_atol(const char *, size_t);
-static int64_t tar_atol10(const char *, size_t);
-static int64_t tar_atol256(const char *, size_t);
-static int64_t tar_atol8(const char *, size_t);
-static int tar_read_header(struct archive_read *, struct tar *,
- struct archive_entry *, size_t *);
-static int tohex(int c);
-static char *url_decode(const char *);
-static void tar_flush_unconsumed(struct archive_read *, size_t *);
-
-
-int
-archive_read_support_format_gnutar(struct archive *a)
-{
- archive_check_magic(a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_format_gnutar");
- return (archive_read_support_format_tar(a));
-}
-
-
-int
-archive_read_support_format_tar(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- struct tar *tar;
- int r;
-
- archive_check_magic(_a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_format_tar");
-
- tar = (struct tar *)calloc(1, sizeof(*tar));
- if (tar == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate tar data");
- return (ARCHIVE_FATAL);
- }
-#ifdef HAVE_COPYFILE_H
- /* Set this by default on Mac OS. */
- tar->process_mac_extensions = 1;
-#endif
-
- r = __archive_read_register_format(a, tar, "tar",
- archive_read_format_tar_bid,
- archive_read_format_tar_options,
- archive_read_format_tar_read_header,
- archive_read_format_tar_read_data,
- archive_read_format_tar_skip,
- NULL,
- archive_read_format_tar_cleanup,
- NULL,
- NULL);
-
- if (r != ARCHIVE_OK)
- free(tar);
- return (ARCHIVE_OK);
-}
-
-static int
-archive_read_format_tar_cleanup(struct archive_read *a)
-{
- struct tar *tar;
-
- tar = (struct tar *)(a->format->data);
- gnu_clear_sparse_list(tar);
- archive_string_free(&tar->acl_text);
- archive_string_free(&tar->entry_pathname);
- archive_string_free(&tar->entry_pathname_override);
- archive_string_free(&tar->entry_linkpath);
- archive_string_free(&tar->entry_uname);
- archive_string_free(&tar->entry_gname);
- archive_string_free(&tar->line);
- archive_string_free(&tar->pax_global);
- archive_string_free(&tar->pax_header);
- archive_string_free(&tar->longname);
- archive_string_free(&tar->longlink);
- archive_string_free(&tar->localname);
- free(tar);
- (a->format->data) = NULL;
- return (ARCHIVE_OK);
-}
-
-/*
- * Validate number field
- *
- * This has to be pretty lenient in order to accommodate the enormous
- * variety of tar writers in the world:
- * = POSIX (IEEE Std 1003.1-1988) ustar requires octal values with leading
- * zeros and allows fields to be terminated with space or null characters
- * = Many writers use different termination (in particular, libarchive
- * omits terminator bytes to squeeze one or two more digits)
- * = Many writers pad with space and omit leading zeros
- * = GNU tar and star write base-256 values if numbers are too
- * big to be represented in octal
- *
- * Examples of specific tar headers that we should support:
- * = Perl Archive::Tar terminates uid, gid, devminor and devmajor with two
- * null bytes, pads size with spaces and other numeric fields with zeroes
- * = plexus-archiver prior to 2.6.3 (before switching to commons-compress)
- * may have uid and gid fields filled with spaces without any octal digits
- * at all and pads all numeric fields with spaces
- *
- * This should tolerate all variants in use. It will reject a field
- * where the writer just left garbage after a trailing NUL.
- */
-static int
-validate_number_field(const char* p_field, size_t i_size)
-{
- unsigned char marker = (unsigned char)p_field[0];
- if (marker == 128 || marker == 255 || marker == 0) {
- /* Base-256 marker, there's nothing we can check. */
- return 1;
- } else {
- /* Must be octal */
- size_t i = 0;
- /* Skip any leading spaces */
- while (i < i_size && p_field[i] == ' ') {
- ++i;
- }
- /* Skip octal digits. */
- while (i < i_size && p_field[i] >= '0' && p_field[i] <= '7') {
- ++i;
- }
- /* Any remaining characters must be space or NUL padding. */
- while (i < i_size) {
- if (p_field[i] != ' ' && p_field[i] != 0) {
- return 0;
- }
- ++i;
- }
- return 1;
- }
-}
-
-static int
-archive_read_format_tar_bid(struct archive_read *a, int best_bid)
-{
- int bid;
- const char *h;
- const struct archive_entry_header_ustar *header;
-
- (void)best_bid; /* UNUSED */
-
- bid = 0;
-
- /* Now let's look at the actual header and see if it matches. */
- h = __archive_read_ahead(a, 512, NULL);
- if (h == NULL)
- return (-1);
-
- /* If it's an end-of-archive mark, we can handle it. */
- if (h[0] == 0 && archive_block_is_null(h)) {
- /*
- * Usually, I bid the number of bits verified, but
- * in this case, 4096 seems excessive so I picked 10 as
- * an arbitrary but reasonable-seeming value.
- */
- return (10);
- }
-
- /* If it's not an end-of-archive mark, it must have a valid checksum.*/
- if (!checksum(a, h))
- return (0);
- bid += 48; /* Checksum is usually 6 octal digits. */
-
- header = (const struct archive_entry_header_ustar *)h;
-
- /* Recognize POSIX formats. */
- if ((memcmp(header->magic, "ustar\0", 6) == 0)
- && (memcmp(header->version, "00", 2) == 0))
- bid += 56;
-
- /* Recognize GNU tar format. */
- if ((memcmp(header->magic, "ustar ", 6) == 0)
- && (memcmp(header->version, " \0", 2) == 0))
- bid += 56;
-
- /* Type flag must be null, digit or A-Z, a-z. */
- if (header->typeflag[0] != 0 &&
- !( header->typeflag[0] >= '0' && header->typeflag[0] <= '9') &&
- !( header->typeflag[0] >= 'A' && header->typeflag[0] <= 'Z') &&
- !( header->typeflag[0] >= 'a' && header->typeflag[0] <= 'z') )
- return (0);
- bid += 2; /* 6 bits of variation in an 8-bit field leaves 2 bits. */
-
- /*
- * Check format of mode/uid/gid/mtime/size/rdevmajor/rdevminor fields.
- */
- if (validate_number_field(header->mode, sizeof(header->mode)) == 0
- || validate_number_field(header->uid, sizeof(header->uid)) == 0
- || validate_number_field(header->gid, sizeof(header->gid)) == 0
- || validate_number_field(header->mtime, sizeof(header->mtime)) == 0
- || validate_number_field(header->size, sizeof(header->size)) == 0
- || validate_number_field(header->rdevmajor, sizeof(header->rdevmajor)) == 0
- || validate_number_field(header->rdevminor, sizeof(header->rdevminor)) == 0) {
- bid = 0;
- }
-
- return (bid);
-}
-
-static int
-archive_read_format_tar_options(struct archive_read *a,
- const char *key, const char *val)
-{
- struct tar *tar;
- int ret = ARCHIVE_FAILED;
-
- tar = (struct tar *)(a->format->data);
- if (strcmp(key, "compat-2x") == 0) {
- /* Handle UTF-8 filenames as libarchive 2.x */
- tar->compat_2x = (val != NULL && val[0] != 0);
- tar->init_default_conversion = tar->compat_2x;
- return (ARCHIVE_OK);
- } else if (strcmp(key, "hdrcharset") == 0) {
- if (val == NULL || val[0] == 0)
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "tar: hdrcharset option needs a character-set name");
- else {
- tar->opt_sconv =
- archive_string_conversion_from_charset(
- &a->archive, val, 0);
- if (tar->opt_sconv != NULL)
- ret = ARCHIVE_OK;
- else
- ret = ARCHIVE_FATAL;
- }
- return (ret);
- } else if (strcmp(key, "mac-ext") == 0) {
- tar->process_mac_extensions = (val != NULL && val[0] != 0);
- return (ARCHIVE_OK);
- } else if (strcmp(key, "read_concatenated_archives") == 0) {
- tar->read_concatenated_archives = (val != NULL && val[0] != 0);
- return (ARCHIVE_OK);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-/* utility function- this exists to centralize the logic of tracking
- * how much unconsumed data we have floating around, and to consume
- * anything outstanding since we're going to do read_aheads
- */
-static void
-tar_flush_unconsumed(struct archive_read *a, size_t *unconsumed)
-{
- if (*unconsumed) {
-/*
- void *data = (void *)__archive_read_ahead(a, *unconsumed, NULL);
- * this block of code is to poison claimed unconsumed space, ensuring
- * things break if it is in use still.
- * currently it WILL break things, so enable it only for debugging this issue
- if (data) {
- memset(data, 0xff, *unconsumed);
- }
-*/
- __archive_read_consume(a, *unconsumed);
- *unconsumed = 0;
- }
-}
-
-/*
- * The function invoked by archive_read_next_header(). This
- * just sets up a few things and then calls the internal
- * tar_read_header() function below.
- */
-static int
-archive_read_format_tar_read_header(struct archive_read *a,
- struct archive_entry *entry)
-{
- /*
- * When converting tar archives to cpio archives, it is
- * essential that each distinct file have a distinct inode
- * number. To simplify this, we keep a static count here to
- * assign fake dev/inode numbers to each tar entry. Note that
- * pax format archives may overwrite this with something more
- * useful.
- *
- * Ideally, we would track every file read from the archive so
- * that we could assign the same dev/ino pair to hardlinks,
- * but the memory required to store a complete lookup table is
- * probably not worthwhile just to support the relatively
- * obscure tar->cpio conversion case.
- */
- static int default_inode;
- static int default_dev;
- struct tar *tar;
- const char *p;
- const wchar_t *wp;
- int r;
- size_t l, unconsumed = 0;
-
- /* Assign default device/inode values. */
- archive_entry_set_dev(entry, 1 + default_dev); /* Don't use zero. */
- archive_entry_set_ino(entry, ++default_inode); /* Don't use zero. */
- /* Limit generated st_ino number to 16 bits. */
- if (default_inode >= 0xffff) {
- ++default_dev;
- default_inode = 0;
- }
-
- tar = (struct tar *)(a->format->data);
- tar->entry_offset = 0;
- gnu_clear_sparse_list(tar);
- tar->realsize = -1; /* Mark this as "unset" */
- tar->realsize_override = 0;
-
- /* Setup default string conversion. */
- tar->sconv = tar->opt_sconv;
- if (tar->sconv == NULL) {
- if (!tar->init_default_conversion) {
- tar->sconv_default =
- archive_string_default_conversion_for_read(&(a->archive));
- tar->init_default_conversion = 1;
- }
- tar->sconv = tar->sconv_default;
- }
-
- r = tar_read_header(a, tar, entry, &unconsumed);
-
- tar_flush_unconsumed(a, &unconsumed);
-
- /*
- * "non-sparse" files are really just sparse files with
- * a single block.
- */
- if (tar->sparse_list == NULL) {
- if (gnu_add_sparse_entry(a, tar, 0, tar->entry_bytes_remaining)
- != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- } else {
- struct sparse_block *sb;
-
- for (sb = tar->sparse_list; sb != NULL; sb = sb->next) {
- if (!sb->hole)
- archive_entry_sparse_add_entry(entry,
- sb->offset, sb->remaining);
- }
- }
-
- if (r == ARCHIVE_OK && archive_entry_filetype(entry) == AE_IFREG) {
- /*
- * "Regular" entry with trailing '/' is really
- * directory: This is needed for certain old tar
- * variants and even for some broken newer ones.
- */
- if ((wp = archive_entry_pathname_w(entry)) != NULL) {
- l = wcslen(wp);
- if (l > 0 && wp[l - 1] == L'/') {
- archive_entry_set_filetype(entry, AE_IFDIR);
- tar->entry_bytes_remaining = 0;
- tar->entry_padding = 0;
- }
- } else if ((p = archive_entry_pathname(entry)) != NULL) {
- l = strlen(p);
- if (l > 0 && p[l - 1] == '/') {
- archive_entry_set_filetype(entry, AE_IFDIR);
- tar->entry_bytes_remaining = 0;
- tar->entry_padding = 0;
- }
- }
- }
- return (r);
-}
-
-static int
-archive_read_format_tar_read_data(struct archive_read *a,
- const void **buff, size_t *size, int64_t *offset)
-{
- ssize_t bytes_read;
- struct tar *tar;
- struct sparse_block *p;
-
- tar = (struct tar *)(a->format->data);
-
- for (;;) {
- /* Remove exhausted entries from sparse list. */
- while (tar->sparse_list != NULL &&
- tar->sparse_list->remaining == 0) {
- p = tar->sparse_list;
- tar->sparse_list = p->next;
- free(p);
- }
-
- if (tar->entry_bytes_unconsumed) {
- __archive_read_consume(a, tar->entry_bytes_unconsumed);
- tar->entry_bytes_unconsumed = 0;
- }
-
- /* If we're at end of file, return EOF. */
- if (tar->sparse_list == NULL ||
- tar->entry_bytes_remaining == 0) {
- if (__archive_read_consume(a, tar->entry_padding) < 0)
- return (ARCHIVE_FATAL);
- tar->entry_padding = 0;
- *buff = NULL;
- *size = 0;
- *offset = tar->realsize;
- return (ARCHIVE_EOF);
- }
-
- *buff = __archive_read_ahead(a, 1, &bytes_read);
- if (bytes_read < 0)
- return (ARCHIVE_FATAL);
- if (*buff == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Truncated tar archive");
- return (ARCHIVE_FATAL);
- }
- if (bytes_read > tar->entry_bytes_remaining)
- bytes_read = (ssize_t)tar->entry_bytes_remaining;
- /* Don't read more than is available in the
- * current sparse block. */
- if (tar->sparse_list->remaining < bytes_read)
- bytes_read = (ssize_t)tar->sparse_list->remaining;
- *size = bytes_read;
- *offset = tar->sparse_list->offset;
- tar->sparse_list->remaining -= bytes_read;
- tar->sparse_list->offset += bytes_read;
- tar->entry_bytes_remaining -= bytes_read;
- tar->entry_bytes_unconsumed = bytes_read;
-
- if (!tar->sparse_list->hole)
- return (ARCHIVE_OK);
- /* Current is hole data and skip this. */
- }
-}
-
-static int
-archive_read_format_tar_skip(struct archive_read *a)
-{
- int64_t bytes_skipped;
- int64_t request;
- struct sparse_block *p;
- struct tar* tar;
-
- tar = (struct tar *)(a->format->data);
-
- /* Do not consume the hole of a sparse file. */
- request = 0;
- for (p = tar->sparse_list; p != NULL; p = p->next) {
- if (!p->hole) {
- if (p->remaining >= INT64_MAX - request) {
- return ARCHIVE_FATAL;
- }
- request += p->remaining;
- }
- }
- if (request > tar->entry_bytes_remaining)
- request = tar->entry_bytes_remaining;
- request += tar->entry_padding + tar->entry_bytes_unconsumed;
-
- bytes_skipped = __archive_read_consume(a, request);
- if (bytes_skipped < 0)
- return (ARCHIVE_FATAL);
-
- tar->entry_bytes_remaining = 0;
- tar->entry_bytes_unconsumed = 0;
- tar->entry_padding = 0;
-
- /* Free the sparse list. */
- gnu_clear_sparse_list(tar);
-
- return (ARCHIVE_OK);
-}
-
-/*
- * This function recursively interprets all of the headers associated
- * with a single entry.
- */
-static int
-tar_read_header(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, size_t *unconsumed)
-{
- ssize_t bytes;
- int err, eof_vol_header;
- const char *h;
- const struct archive_entry_header_ustar *header;
- const struct archive_entry_header_gnutar *gnuheader;
-
- eof_vol_header = 0;
-
- /* Loop until we find a workable header record. */
- for (;;) {
- tar_flush_unconsumed(a, unconsumed);
-
- /* Read 512-byte header record */
- h = __archive_read_ahead(a, 512, &bytes);
- if (bytes < 0)
- return ((int)bytes);
- if (bytes == 0) { /* EOF at a block boundary. */
- /* Some writers do omit the block of nulls. <sigh> */
- return (ARCHIVE_EOF);
- }
- if (bytes < 512) { /* Short block at EOF; this is bad. */
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated tar archive");
- return (ARCHIVE_FATAL);
- }
- *unconsumed = 512;
-
- /* Header is workable if it's not an end-of-archive mark. */
- if (h[0] != 0 || !archive_block_is_null(h))
- break;
-
- /* Ensure format is set for archives with only null blocks. */
- if (a->archive.archive_format_name == NULL) {
- a->archive.archive_format = ARCHIVE_FORMAT_TAR;
- a->archive.archive_format_name = "tar";
- }
-
- if (!tar->read_concatenated_archives) {
- /* Try to consume a second all-null record, as well. */
- tar_flush_unconsumed(a, unconsumed);
- h = __archive_read_ahead(a, 512, NULL);
- if (h != NULL && h[0] == 0 && archive_block_is_null(h))
- __archive_read_consume(a, 512);
- archive_clear_error(&a->archive);
- return (ARCHIVE_EOF);
- }
-
- /*
- * We're reading concatenated archives, ignore this block and
- * loop to get the next.
- */
- }
-
- /*
- * Note: If the checksum fails and we return ARCHIVE_RETRY,
- * then the client is likely to just retry. This is a very
- * crude way to search for the next valid header!
- *
- * TODO: Improve this by implementing a real header scan.
- */
- if (!checksum(a, h)) {
- tar_flush_unconsumed(a, unconsumed);
- archive_set_error(&a->archive, EINVAL, "Damaged tar archive");
- return (ARCHIVE_RETRY); /* Retryable: Invalid header */
- }
-
- if (++tar->header_recursion_depth > 32) {
- tar_flush_unconsumed(a, unconsumed);
- archive_set_error(&a->archive, EINVAL, "Too many special headers");
- return (ARCHIVE_WARN);
- }
-
- /* Determine the format variant. */
- header = (const struct archive_entry_header_ustar *)h;
-
- switch(header->typeflag[0]) {
- case 'A': /* Solaris tar ACL */
- a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
- a->archive.archive_format_name = "Solaris tar";
- err = header_Solaris_ACL(a, tar, entry, h, unconsumed);
- break;
- case 'g': /* POSIX-standard 'g' header. */
- a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
- a->archive.archive_format_name = "POSIX pax interchange format";
- err = header_pax_global(a, tar, entry, h, unconsumed);
- if (err == ARCHIVE_EOF)
- return (err);
- break;
- case 'K': /* Long link name (GNU tar, others) */
- err = header_longlink(a, tar, entry, h, unconsumed);
- break;
- case 'L': /* Long filename (GNU tar, others) */
- err = header_longname(a, tar, entry, h, unconsumed);
- break;
- case 'V': /* GNU volume header */
- err = header_volume(a, tar, entry, h, unconsumed);
- if (err == ARCHIVE_EOF)
- eof_vol_header = 1;
- break;
- case 'X': /* Used by SUN tar; same as 'x'. */
- a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
- a->archive.archive_format_name =
- "POSIX pax interchange format (Sun variant)";
- err = header_pax_extensions(a, tar, entry, h, unconsumed);
- break;
- case 'x': /* POSIX-standard 'x' header. */
- a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
- a->archive.archive_format_name = "POSIX pax interchange format";
- err = header_pax_extensions(a, tar, entry, h, unconsumed);
- break;
- default:
- gnuheader = (const struct archive_entry_header_gnutar *)h;
- if (memcmp(gnuheader->magic, "ustar \0", 8) == 0) {
- a->archive.archive_format = ARCHIVE_FORMAT_TAR_GNUTAR;
- a->archive.archive_format_name = "GNU tar format";
- err = header_gnutar(a, tar, entry, h, unconsumed);
- } else if (memcmp(header->magic, "ustar", 5) == 0) {
- if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE) {
- a->archive.archive_format = ARCHIVE_FORMAT_TAR_USTAR;
- a->archive.archive_format_name = "POSIX ustar format";
- }
- err = header_ustar(a, tar, entry, h);
- } else {
- a->archive.archive_format = ARCHIVE_FORMAT_TAR;
- a->archive.archive_format_name = "tar (non-POSIX)";
- err = header_old_tar(a, tar, entry, h);
- }
- }
- if (err == ARCHIVE_FATAL)
- return (err);
-
- tar_flush_unconsumed(a, unconsumed);
-
- h = NULL;
- header = NULL;
-
- --tar->header_recursion_depth;
- /* Yuck. Apple's design here ends up storing long pathname
- * extensions for both the AppleDouble extension entry and the
- * regular entry.
- */
- if ((err == ARCHIVE_WARN || err == ARCHIVE_OK) &&
- tar->header_recursion_depth == 0 &&
- tar->process_mac_extensions) {
- int err2 = read_mac_metadata_blob(a, tar, entry, h, unconsumed);
- if (err2 < err)
- err = err2;
- }
-
- /* We return warnings or success as-is. Anything else is fatal. */
- if (err == ARCHIVE_WARN || err == ARCHIVE_OK) {
- if (tar->sparse_gnu_pending) {
- if (tar->sparse_gnu_major == 1 &&
- tar->sparse_gnu_minor == 0) {
- ssize_t bytes_read;
-
- tar->sparse_gnu_pending = 0;
- /* Read initial sparse map. */
- bytes_read = gnu_sparse_10_read(a, tar, unconsumed);
- if (bytes_read < 0)
- return ((int)bytes_read);
- tar->entry_bytes_remaining -= bytes_read;
- } else {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Unrecognized GNU sparse file format");
- return (ARCHIVE_WARN);
- }
- tar->sparse_gnu_pending = 0;
- }
- return (err);
- }
- if (err == ARCHIVE_EOF) {
- if (!eof_vol_header) {
- /* EOF when recursively reading a header is bad. */
- archive_set_error(&a->archive, EINVAL,
- "Damaged tar archive");
- } else {
- /* If we encounter just a GNU volume header treat
- * this situation as an empty archive */
- return (ARCHIVE_EOF);
- }
- }
- return (ARCHIVE_FATAL);
-}
-
-/*
- * Return true if block checksum is correct.
- */
-static int
-checksum(struct archive_read *a, const void *h)
-{
- const unsigned char *bytes;
- const struct archive_entry_header_ustar *header;
- int check, sum;
- size_t i;
-
- (void)a; /* UNUSED */
- bytes = (const unsigned char *)h;
- header = (const struct archive_entry_header_ustar *)h;
-
- /* Checksum field must hold an octal number */
- for (i = 0; i < sizeof(header->checksum); ++i) {
- char c = header->checksum[i];
- if (c != ' ' && c != '\0' && (c < '0' || c > '7'))
- return 0;
- }
-
- /*
- * Test the checksum. Note that POSIX specifies _unsigned_
- * bytes for this calculation.
- */
- sum = (int)tar_atol(header->checksum, sizeof(header->checksum));
- check = 0;
- for (i = 0; i < 148; i++)
- check += (unsigned char)bytes[i];
- for (; i < 156; i++)
- check += 32;
- for (; i < 512; i++)
- check += (unsigned char)bytes[i];
- if (sum == check)
- return (1);
-
- /*
- * Repeat test with _signed_ bytes, just in case this archive
- * was created by an old BSD, Solaris, or HP-UX tar with a
- * broken checksum calculation.
- */
- check = 0;
- for (i = 0; i < 148; i++)
- check += (signed char)bytes[i];
- for (; i < 156; i++)
- check += 32;
- for (; i < 512; i++)
- check += (signed char)bytes[i];
- if (sum == check)
- return (1);
-
- return (0);
-}
-
-/*
- * Return true if this block contains only nulls.
- */
-static int
-archive_block_is_null(const char *p)
-{
- unsigned i;
-
- for (i = 0; i < 512; i++)
- if (*p++)
- return (0);
- return (1);
-}
-
-/*
- * Interpret 'A' Solaris ACL header
- */
-static int
-header_Solaris_ACL(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const void *h, size_t *unconsumed)
-{
- const struct archive_entry_header_ustar *header;
- size_t size;
- int err, acl_type;
- int64_t type;
- char *acl, *p;
-
- /*
- * read_body_to_string adds a NUL terminator, but we need a little
- * more to make sure that we don't overrun acl_text later.
- */
- header = (const struct archive_entry_header_ustar *)h;
- size = (size_t)tar_atol(header->size, sizeof(header->size));
- err = read_body_to_string(a, tar, &(tar->acl_text), h, unconsumed);
- if (err != ARCHIVE_OK)
- return (err);
-
- /* Recursively read next header */
- err = tar_read_header(a, tar, entry, unconsumed);
- if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
- return (err);
-
- /* TODO: Examine the first characters to see if this
- * is an AIX ACL descriptor. We'll likely never support
- * them, but it would be polite to recognize and warn when
- * we do see them. */
-
- /* Leading octal number indicates ACL type and number of entries. */
- p = acl = tar->acl_text.s;
- type = 0;
- while (*p != '\0' && p < acl + size) {
- if (*p < '0' || *p > '7') {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Malformed Solaris ACL attribute (invalid digit)");
- return(ARCHIVE_WARN);
- }
- type <<= 3;
- type += *p - '0';
- if (type > 077777777) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Malformed Solaris ACL attribute (count too large)");
- return (ARCHIVE_WARN);
- }
- p++;
- }
- switch ((int)type & ~0777777) {
- case 01000000:
- /* POSIX.1e ACL */
- acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
- break;
- case 03000000:
- /* NFSv4 ACL */
- acl_type = ARCHIVE_ENTRY_ACL_TYPE_NFS4;
- break;
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Malformed Solaris ACL attribute (unsupported type %o)",
- (int)type);
- return (ARCHIVE_WARN);
- }
- p++;
-
- if (p >= acl + size) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Malformed Solaris ACL attribute (body overflow)");
- return(ARCHIVE_WARN);
- }
-
- /* ACL text is null-terminated; find the end. */
- size -= (p - acl);
- acl = p;
-
- while (*p != '\0' && p < acl + size)
- p++;
-
- if (tar->sconv_acl == NULL) {
- tar->sconv_acl = archive_string_conversion_from_charset(
- &(a->archive), "UTF-8", 1);
- if (tar->sconv_acl == NULL)
- return (ARCHIVE_FATAL);
- }
- archive_strncpy(&(tar->localname), acl, p - acl);
- err = archive_acl_from_text_l(archive_entry_acl(entry),
- tar->localname.s, acl_type, tar->sconv_acl);
- if (err != ARCHIVE_OK) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for ACL");
- } else
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Malformed Solaris ACL attribute (unparsable)");
- }
- return (err);
-}
-
-/*
- * Interpret 'K' long linkname header.
- */
-static int
-header_longlink(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const void *h, size_t *unconsumed)
-{
- int err;
-
- err = read_body_to_string(a, tar, &(tar->longlink), h, unconsumed);
- if (err != ARCHIVE_OK)
- return (err);
- err = tar_read_header(a, tar, entry, unconsumed);
- if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
- return (err);
- /* Set symlink if symlink already set, else hardlink. */
- archive_entry_copy_link(entry, tar->longlink.s);
- return (ARCHIVE_OK);
-}
-
-static int
-set_conversion_failed_error(struct archive_read *a,
- struct archive_string_conv *sconv, const char *name)
-{
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for %s", name);
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "%s can't be converted from %s to current locale.",
- name, archive_string_conversion_charset_name(sconv));
- return (ARCHIVE_WARN);
-}
-
-/*
- * Interpret 'L' long filename header.
- */
-static int
-header_longname(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const void *h, size_t *unconsumed)
-{
- int err;
-
- err = read_body_to_string(a, tar, &(tar->longname), h, unconsumed);
- if (err != ARCHIVE_OK)
- return (err);
- /* Read and parse "real" header, then override name. */
- err = tar_read_header(a, tar, entry, unconsumed);
- if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
- return (err);
- if (archive_entry_copy_pathname_l(entry, tar->longname.s,
- archive_strlen(&(tar->longname)), tar->sconv) != 0)
- err = set_conversion_failed_error(a, tar->sconv, "Pathname");
- return (err);
-}
-
-
-/*
- * Interpret 'V' GNU tar volume header.
- */
-static int
-header_volume(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const void *h, size_t *unconsumed)
-{
- (void)h;
-
- /* Just skip this and read the next header. */
- return (tar_read_header(a, tar, entry, unconsumed));
-}
-
-/*
- * Read body of an archive entry into an archive_string object.
- */
-static int
-read_body_to_string(struct archive_read *a, struct tar *tar,
- struct archive_string *as, const void *h, size_t *unconsumed)
-{
- int64_t size;
- const struct archive_entry_header_ustar *header;
- const void *src;
-
- (void)tar; /* UNUSED */
- header = (const struct archive_entry_header_ustar *)h;
- size = tar_atol(header->size, sizeof(header->size));
- if ((size > 1048576) || (size < 0)) {
- archive_set_error(&a->archive, EINVAL,
- "Special header too large");
- return (ARCHIVE_FATAL);
- }
-
- /* Fail if we can't make our buffer big enough. */
- if (archive_string_ensure(as, (size_t)size+1) == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory");
- return (ARCHIVE_FATAL);
- }
-
- tar_flush_unconsumed(a, unconsumed);
-
- /* Read the body into the string. */
- *unconsumed = (size_t)((size + 511) & ~ 511);
- src = __archive_read_ahead(a, *unconsumed, NULL);
- if (src == NULL) {
- *unconsumed = 0;
- return (ARCHIVE_FATAL);
- }
- memcpy(as->s, src, (size_t)size);
- as->s[size] = '\0';
- as->length = (size_t)size;
- return (ARCHIVE_OK);
-}
-
-/*
- * Parse out common header elements.
- *
- * This would be the same as header_old_tar, except that the
- * filename is handled slightly differently for old and POSIX
- * entries (POSIX entries support a 'prefix'). This factoring
- * allows header_old_tar and header_ustar
- * to handle filenames differently, while still putting most of the
- * common parsing into one place.
- */
-static int
-header_common(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const void *h)
-{
- const struct archive_entry_header_ustar *header;
- char tartype;
- int err = ARCHIVE_OK;
-
- header = (const struct archive_entry_header_ustar *)h;
- if (header->linkname[0])
- archive_strncpy(&(tar->entry_linkpath),
- header->linkname, sizeof(header->linkname));
- else
- archive_string_empty(&(tar->entry_linkpath));
-
- /* Parse out the numeric fields (all are octal) */
- archive_entry_set_mode(entry,
- (mode_t)tar_atol(header->mode, sizeof(header->mode)));
- archive_entry_set_uid(entry, tar_atol(header->uid, sizeof(header->uid)));
- archive_entry_set_gid(entry, tar_atol(header->gid, sizeof(header->gid)));
- tar->entry_bytes_remaining = tar_atol(header->size, sizeof(header->size));
- if (tar->entry_bytes_remaining < 0) {
- tar->entry_bytes_remaining = 0;
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Tar entry has negative size");
- return (ARCHIVE_FATAL);
- }
- if (tar->entry_bytes_remaining == INT64_MAX) {
- /* Note: tar_atol returns INT64_MAX on overflow */
- tar->entry_bytes_remaining = 0;
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Tar entry size overflow");
- return (ARCHIVE_FATAL);
- }
- tar->realsize = tar->entry_bytes_remaining;
- archive_entry_set_size(entry, tar->entry_bytes_remaining);
- archive_entry_set_mtime(entry, tar_atol(header->mtime, sizeof(header->mtime)), 0);
-
- /* Handle the tar type flag appropriately. */
- tartype = header->typeflag[0];
-
- switch (tartype) {
- case '1': /* Hard link */
- if (archive_entry_copy_hardlink_l(entry, tar->entry_linkpath.s,
- archive_strlen(&(tar->entry_linkpath)), tar->sconv) != 0) {
- err = set_conversion_failed_error(a, tar->sconv,
- "Linkname");
- if (err == ARCHIVE_FATAL)
- return (err);
- }
- /*
- * The following may seem odd, but: Technically, tar
- * does not store the file type for a "hard link"
- * entry, only the fact that it is a hard link. So, I
- * leave the type zero normally. But, pax interchange
- * format allows hard links to have data, which
- * implies that the underlying entry is a regular
- * file.
- */
- if (archive_entry_size(entry) > 0)
- archive_entry_set_filetype(entry, AE_IFREG);
-
- /*
- * A tricky point: Traditionally, tar readers have
- * ignored the size field when reading hardlink
- * entries, and some writers put non-zero sizes even
- * though the body is empty. POSIX blessed this
- * convention in the 1988 standard, but broke with
- * this tradition in 2001 by permitting hardlink
- * entries to store valid bodies in pax interchange
- * format, but not in ustar format. Since there is no
- * hard and fast way to distinguish pax interchange
- * from earlier archives (the 'x' and 'g' entries are
- * optional, after all), we need a heuristic.
- */
- if (archive_entry_size(entry) == 0) {
- /* If the size is already zero, we're done. */
- } else if (a->archive.archive_format
- == ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE) {
- /* Definitely pax extended; must obey hardlink size. */
- } else if (a->archive.archive_format == ARCHIVE_FORMAT_TAR
- || a->archive.archive_format == ARCHIVE_FORMAT_TAR_GNUTAR)
- {
- /* Old-style or GNU tar: we must ignore the size. */
- archive_entry_set_size(entry, 0);
- tar->entry_bytes_remaining = 0;
- } else if (archive_read_format_tar_bid(a, 50) > 50) {
- /*
- * We don't know if it's pax: If the bid
- * function sees a valid ustar header
- * immediately following, then let's ignore
- * the hardlink size.
- */
- archive_entry_set_size(entry, 0);
- tar->entry_bytes_remaining = 0;
- }
- /*
- * TODO: There are still two cases I'd like to handle:
- * = a ustar non-pax archive with a hardlink entry at
- * end-of-archive. (Look for block of nulls following?)
- * = a pax archive that has not seen any pax headers
- * and has an entry which is a hardlink entry storing
- * a body containing an uncompressed tar archive.
- * The first is worth addressing; I don't see any reliable
- * way to deal with the second possibility.
- */
- break;
- case '2': /* Symlink */
- archive_entry_set_filetype(entry, AE_IFLNK);
- archive_entry_set_size(entry, 0);
- tar->entry_bytes_remaining = 0;
- if (archive_entry_copy_symlink_l(entry, tar->entry_linkpath.s,
- archive_strlen(&(tar->entry_linkpath)), tar->sconv) != 0) {
- err = set_conversion_failed_error(a, tar->sconv,
- "Linkname");
- if (err == ARCHIVE_FATAL)
- return (err);
- }
- break;
- case '3': /* Character device */
- archive_entry_set_filetype(entry, AE_IFCHR);
- archive_entry_set_size(entry, 0);
- tar->entry_bytes_remaining = 0;
- break;
- case '4': /* Block device */
- archive_entry_set_filetype(entry, AE_IFBLK);
- archive_entry_set_size(entry, 0);
- tar->entry_bytes_remaining = 0;
- break;
- case '5': /* Dir */
- archive_entry_set_filetype(entry, AE_IFDIR);
- archive_entry_set_size(entry, 0);
- tar->entry_bytes_remaining = 0;
- break;
- case '6': /* FIFO device */
- archive_entry_set_filetype(entry, AE_IFIFO);
- archive_entry_set_size(entry, 0);
- tar->entry_bytes_remaining = 0;
- break;
- case 'D': /* GNU incremental directory type */
- /*
- * No special handling is actually required here.
- * It might be nice someday to preprocess the file list and
- * provide it to the client, though.
- */
- archive_entry_set_filetype(entry, AE_IFDIR);
- break;
- case 'M': /* GNU "Multi-volume" (remainder of file from last archive)*/
- /*
- * As far as I can tell, this is just like a regular file
- * entry, except that the contents should be _appended_ to
- * the indicated file at the indicated offset. This may
- * require some API work to fully support.
- */
- break;
- case 'N': /* Old GNU "long filename" entry. */
- /* The body of this entry is a script for renaming
- * previously-extracted entries. Ugh. It will never
- * be supported by libarchive. */
- archive_entry_set_filetype(entry, AE_IFREG);
- break;
- case 'S': /* GNU sparse files */
- /*
- * Sparse files are really just regular files with
- * sparse information in the extended area.
- */
- /* FALLTHROUGH */
- case '0':
- /*
- * Enable sparse file "read" support only for regular
- * files and explicit GNU sparse files. However, we
- * don't allow non-standard file types to be sparse.
- */
- tar->sparse_allowed = 1;
- /* FALLTHROUGH */
- default: /* Regular file and non-standard types */
- /*
- * Per POSIX: non-recognized types should always be
- * treated as regular files.
- */
- archive_entry_set_filetype(entry, AE_IFREG);
- break;
- }
- return (err);
-}
-
-/*
- * Parse out header elements for "old-style" tar archives.
- */
-static int
-header_old_tar(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const void *h)
-{
- const struct archive_entry_header_ustar *header;
- int err = ARCHIVE_OK, err2;
-
- /* Copy filename over (to ensure null termination). */
- header = (const struct archive_entry_header_ustar *)h;
- if (archive_entry_copy_pathname_l(entry,
- header->name, sizeof(header->name), tar->sconv) != 0) {
- err = set_conversion_failed_error(a, tar->sconv, "Pathname");
- if (err == ARCHIVE_FATAL)
- return (err);
- }
-
- /* Grab rest of common fields */
- err2 = header_common(a, tar, entry, h);
- if (err > err2)
- err = err2;
-
- tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
- return (err);
-}
-
-/*
- * Read a Mac AppleDouble-encoded blob of file metadata,
- * if there is one.
- */
-static int
-read_mac_metadata_blob(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const void *h, size_t *unconsumed)
-{
- int64_t size;
- size_t msize;
- const void *data;
- const char *p, *name;
- const wchar_t *wp, *wname;
-
- (void)h; /* UNUSED */
-
- wname = wp = archive_entry_pathname_w(entry);
- if (wp != NULL) {
- /* Find the last path element. */
- for (; *wp != L'\0'; ++wp) {
- if (wp[0] == '/' && wp[1] != L'\0')
- wname = wp + 1;
- }
- /*
- * If last path element starts with "._", then
- * this is a Mac extension.
- */
- if (wname[0] != L'.' || wname[1] != L'_' || wname[2] == L'\0')
- return ARCHIVE_OK;
- } else {
- /* Find the last path element. */
- name = p = archive_entry_pathname(entry);
- if (p == NULL)
- return (ARCHIVE_FAILED);
- for (; *p != '\0'; ++p) {
- if (p[0] == '/' && p[1] != '\0')
- name = p + 1;
- }
- /*
- * If last path element starts with "._", then
- * this is a Mac extension.
- */
- if (name[0] != '.' || name[1] != '_' || name[2] == '\0')
- return ARCHIVE_OK;
- }
-
- /* Read the body as a Mac OS metadata blob. */
- size = archive_entry_size(entry);
- msize = (size_t)size;
- if (size < 0 || (uintmax_t)msize != (uintmax_t)size) {
- *unconsumed = 0;
- return (ARCHIVE_FATAL);
- }
-
- /*
- * TODO: Look beyond the body here to peek at the next header.
- * If it's a regular header (not an extension header)
- * that has the wrong name, just return the current
- * entry as-is, without consuming the body here.
- * That would reduce the risk of us mis-identifying
- * an ordinary file that just happened to have
- * a name starting with "._".
- *
- * Q: Is the above idea really possible? Even
- * when there are GNU or pax extension entries?
- */
- data = __archive_read_ahead(a, msize, NULL);
- if (data == NULL) {
- *unconsumed = 0;
- return (ARCHIVE_FATAL);
- }
- archive_entry_copy_mac_metadata(entry, data, msize);
- *unconsumed = (msize + 511) & ~ 511;
- tar_flush_unconsumed(a, unconsumed);
- return (tar_read_header(a, tar, entry, unconsumed));
-}
-
-/*
- * Parse a file header for a pax extended archive entry.
- */
-static int
-header_pax_global(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const void *h, size_t *unconsumed)
-{
- int err;
-
- err = read_body_to_string(a, tar, &(tar->pax_global), h, unconsumed);
- if (err != ARCHIVE_OK)
- return (err);
- err = tar_read_header(a, tar, entry, unconsumed);
- return (err);
-}
-
-static int
-header_pax_extensions(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const void *h, size_t *unconsumed)
-{
- int err, err2;
-
- err = read_body_to_string(a, tar, &(tar->pax_header), h, unconsumed);
- if (err != ARCHIVE_OK)
- return (err);
-
- /* Parse the next header. */
- err = tar_read_header(a, tar, entry, unconsumed);
- if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
- return (err);
-
- /*
- * TODO: Parse global/default options into 'entry' struct here
- * before handling file-specific options.
- *
- * This design (parse standard header, then overwrite with pax
- * extended attribute data) usually works well, but isn't ideal;
- * it would be better to parse the pax extended attributes first
- * and then skip any fields in the standard header that were
- * defined in the pax header.
- */
- err2 = pax_header(a, tar, entry, &tar->pax_header);
- err = err_combine(err, err2);
- tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
- return (err);
-}
-
-
-/*
- * Parse a file header for a Posix "ustar" archive entry. This also
- * handles "pax" or "extended ustar" entries.
- */
-static int
-header_ustar(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const void *h)
-{
- const struct archive_entry_header_ustar *header;
- struct archive_string *as;
- int err = ARCHIVE_OK, r;
-
- header = (const struct archive_entry_header_ustar *)h;
-
- /* Copy name into an internal buffer to ensure null-termination. */
- as = &(tar->entry_pathname);
- if (header->prefix[0]) {
- archive_strncpy(as, header->prefix, sizeof(header->prefix));
- if (as->s[archive_strlen(as) - 1] != '/')
- archive_strappend_char(as, '/');
- archive_strncat(as, header->name, sizeof(header->name));
- } else {
- archive_strncpy(as, header->name, sizeof(header->name));
- }
- if (archive_entry_copy_pathname_l(entry, as->s, archive_strlen(as),
- tar->sconv) != 0) {
- err = set_conversion_failed_error(a, tar->sconv, "Pathname");
- if (err == ARCHIVE_FATAL)
- return (err);
- }
-
- /* Handle rest of common fields. */
- r = header_common(a, tar, entry, h);
- if (r == ARCHIVE_FATAL)
- return (r);
- if (r < err)
- err = r;
-
- /* Handle POSIX ustar fields. */
- if (archive_entry_copy_uname_l(entry,
- header->uname, sizeof(header->uname), tar->sconv) != 0) {
- err = set_conversion_failed_error(a, tar->sconv, "Uname");
- if (err == ARCHIVE_FATAL)
- return (err);
- }
-
- if (archive_entry_copy_gname_l(entry,
- header->gname, sizeof(header->gname), tar->sconv) != 0) {
- err = set_conversion_failed_error(a, tar->sconv, "Gname");
- if (err == ARCHIVE_FATAL)
- return (err);
- }
-
- /* Parse out device numbers only for char and block specials. */
- if (header->typeflag[0] == '3' || header->typeflag[0] == '4') {
- archive_entry_set_rdevmajor(entry, (dev_t)
- tar_atol(header->rdevmajor, sizeof(header->rdevmajor)));
- archive_entry_set_rdevminor(entry, (dev_t)
- tar_atol(header->rdevminor, sizeof(header->rdevminor)));
- }
-
- tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
-
- return (err);
-}
-
-
-/*
- * Parse the pax extended attributes record.
- *
- * Returns non-zero if there's an error in the data.
- */
-static int
-pax_header(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, struct archive_string *in_as)
-{
- size_t attr_length, l, line_length, value_length;
- char *p;
- char *key, *value;
- struct archive_string *as;
- struct archive_string_conv *sconv;
- int err, err2;
- char *attr = in_as->s;
-
- attr_length = in_as->length;
- tar->pax_hdrcharset_binary = 0;
- archive_string_empty(&(tar->entry_gname));
- archive_string_empty(&(tar->entry_linkpath));
- archive_string_empty(&(tar->entry_pathname));
- archive_string_empty(&(tar->entry_pathname_override));
- archive_string_empty(&(tar->entry_uname));
- err = ARCHIVE_OK;
- while (attr_length > 0) {
- /* Parse decimal length field at start of line. */
- line_length = 0;
- l = attr_length;
- p = attr; /* Record start of line. */
- while (l>0) {
- if (*p == ' ') {
- p++;
- l--;
- break;
- }
- if (*p < '0' || *p > '9') {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Ignoring malformed pax extended attributes");
- return (ARCHIVE_WARN);
- }
- line_length *= 10;
- line_length += *p - '0';
- if (line_length > 999999) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Rejecting pax extended attribute > 1MB");
- return (ARCHIVE_WARN);
- }
- p++;
- l--;
- }
-
- /*
- * Parsed length must be no bigger than available data,
- * at least 1, and the last character of the line must
- * be '\n'.
- */
- if (line_length > attr_length
- || line_length < 1
- || attr[line_length - 1] != '\n')
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Ignoring malformed pax extended attribute");
- return (ARCHIVE_WARN);
- }
-
- /* Null-terminate the line. */
- attr[line_length - 1] = '\0';
-
- /* Find end of key and null terminate it. */
- key = p;
- if (key[0] == '=')
- return (-1);
- while (*p && *p != '=')
- ++p;
- if (*p == '\0') {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Invalid pax extended attributes");
- return (ARCHIVE_WARN);
- }
- *p = '\0';
-
- value = p + 1;
-
- /* Some values may be binary data */
- value_length = attr + line_length - 1 - value;
-
- /* Identify this attribute and set it in the entry. */
- err2 = pax_attribute(a, tar, entry, key, value, value_length);
- if (err2 == ARCHIVE_FATAL)
- return (err2);
- err = err_combine(err, err2);
-
- /* Skip to next line */
- attr += line_length;
- attr_length -= line_length;
- }
-
- /*
- * PAX format uses UTF-8 as default charset for its metadata
- * unless hdrcharset=BINARY is present in its header.
- * We apply the charset specified by the hdrcharset option only
- * when the hdrcharset attribute(in PAX header) is BINARY because
- * we respect the charset described in PAX header and BINARY also
- * means that metadata(filename,uname and gname) character-set
- * is unknown.
- */
- if (tar->pax_hdrcharset_binary)
- sconv = tar->opt_sconv;
- else {
- sconv = archive_string_conversion_from_charset(
- &(a->archive), "UTF-8", 1);
- if (sconv == NULL)
- return (ARCHIVE_FATAL);
- if (tar->compat_2x)
- archive_string_conversion_set_opt(sconv,
- SCONV_SET_OPT_UTF8_LIBARCHIVE2X);
- }
-
- if (archive_strlen(&(tar->entry_gname)) > 0) {
- if (archive_entry_copy_gname_l(entry, tar->entry_gname.s,
- archive_strlen(&(tar->entry_gname)), sconv) != 0) {
- err = set_conversion_failed_error(a, sconv, "Gname");
- if (err == ARCHIVE_FATAL)
- return (err);
- /* Use a converted an original name. */
- archive_entry_copy_gname(entry, tar->entry_gname.s);
- }
- }
- if (archive_strlen(&(tar->entry_linkpath)) > 0) {
- if (archive_entry_copy_link_l(entry, tar->entry_linkpath.s,
- archive_strlen(&(tar->entry_linkpath)), sconv) != 0) {
- err = set_conversion_failed_error(a, sconv, "Linkname");
- if (err == ARCHIVE_FATAL)
- return (err);
- /* Use a converted an original name. */
- archive_entry_copy_link(entry, tar->entry_linkpath.s);
- }
- }
- /*
- * Some extensions (such as the GNU sparse file extensions)
- * deliberately store a synthetic name under the regular 'path'
- * attribute and the real file name under a different attribute.
- * Since we're supposed to not care about the order, we
- * have no choice but to store all of the various filenames
- * we find and figure it all out afterwards. This is the
- * figuring out part.
- */
- as = NULL;
- if (archive_strlen(&(tar->entry_pathname_override)) > 0)
- as = &(tar->entry_pathname_override);
- else if (archive_strlen(&(tar->entry_pathname)) > 0)
- as = &(tar->entry_pathname);
- if (as != NULL) {
- if (archive_entry_copy_pathname_l(entry, as->s,
- archive_strlen(as), sconv) != 0) {
- err = set_conversion_failed_error(a, sconv, "Pathname");
- if (err == ARCHIVE_FATAL)
- return (err);
- /* Use a converted an original name. */
- archive_entry_copy_pathname(entry, as->s);
- }
- }
- if (archive_strlen(&(tar->entry_uname)) > 0) {
- if (archive_entry_copy_uname_l(entry, tar->entry_uname.s,
- archive_strlen(&(tar->entry_uname)), sconv) != 0) {
- err = set_conversion_failed_error(a, sconv, "Uname");
- if (err == ARCHIVE_FATAL)
- return (err);
- /* Use a converted an original name. */
- archive_entry_copy_uname(entry, tar->entry_uname.s);
- }
- }
- return (err);
-}
-
-static int
-pax_attribute_xattr(struct archive_entry *entry,
- const char *name, const char *value)
-{
- char *name_decoded;
- void *value_decoded;
- size_t value_len;
-
- if (strlen(name) < 18 || (memcmp(name, "LIBARCHIVE.xattr.", 17)) != 0)
- return 3;
-
- name += 17;
-
- /* URL-decode name */
- name_decoded = url_decode(name);
- if (name_decoded == NULL)
- return 2;
-
- /* Base-64 decode value */
- value_decoded = base64_decode(value, strlen(value), &value_len);
- if (value_decoded == NULL) {
- free(name_decoded);
- return 1;
- }
-
- archive_entry_xattr_add_entry(entry, name_decoded,
- value_decoded, value_len);
-
- free(name_decoded);
- free(value_decoded);
- return 0;
-}
-
-static int
-pax_attribute_schily_xattr(struct archive_entry *entry,
- const char *name, const char *value, size_t value_length)
-{
- if (strlen(name) < 14 || (memcmp(name, "SCHILY.xattr.", 13)) != 0)
- return 1;
-
- name += 13;
-
- archive_entry_xattr_add_entry(entry, name, value, value_length);
-
- return 0;
-}
-
-static int
-pax_attribute_rht_security_selinux(struct archive_entry *entry,
- const char *value, size_t value_length)
-{
- archive_entry_xattr_add_entry(entry, "security.selinux",
- value, value_length);
-
- return 0;
-}
-
-static int
-pax_attribute_acl(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const char *value, int type)
-{
- int r;
- const char* errstr;
-
- switch (type) {
- case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
- errstr = "SCHILY.acl.access";
- break;
- case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
- errstr = "SCHILY.acl.default";
- break;
- case ARCHIVE_ENTRY_ACL_TYPE_NFS4:
- errstr = "SCHILY.acl.ace";
- break;
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Unknown ACL type: %d", type);
- return(ARCHIVE_FATAL);
- }
-
- if (tar->sconv_acl == NULL) {
- tar->sconv_acl =
- archive_string_conversion_from_charset(
- &(a->archive), "UTF-8", 1);
- if (tar->sconv_acl == NULL)
- return (ARCHIVE_FATAL);
- }
-
- r = archive_acl_from_text_l(archive_entry_acl(entry), value, type,
- tar->sconv_acl);
- if (r != ARCHIVE_OK) {
- if (r == ARCHIVE_FATAL) {
- archive_set_error(&a->archive, ENOMEM,
- "%s %s", "Can't allocate memory for ",
- errstr);
- return (r);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC, "%s %s", "Parse error: ", errstr);
- }
- return (r);
-}
-
-/*
- * Parse a single key=value attribute. key/value pointers are
- * assumed to point into reasonably long-lived storage.
- *
- * Note that POSIX reserves all-lowercase keywords. Vendor-specific
- * extensions should always have keywords of the form "VENDOR.attribute"
- * In particular, it's quite feasible to support many different
- * vendor extensions here. I'm using "LIBARCHIVE" for extensions
- * unique to this library.
- *
- * Investigate other vendor-specific extensions and see if
- * any of them look useful.
- */
-static int
-pax_attribute(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const char *key, const char *value, size_t value_length)
-{
- int64_t s;
- long n;
- int err = ARCHIVE_OK, r;
-
- if (value == NULL)
- value = ""; /* Disable compiler warning; do not pass
- * NULL pointer to strlen(). */
- switch (key[0]) {
- case 'G':
- /* Reject GNU.sparse.* headers on non-regular files. */
- if (strncmp(key, "GNU.sparse", 10) == 0 &&
- !tar->sparse_allowed) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Non-regular file cannot be sparse");
- return (ARCHIVE_FATAL);
- }
-
- /* GNU "0.0" sparse pax format. */
- if (strcmp(key, "GNU.sparse.numblocks") == 0) {
- tar->sparse_offset = -1;
- tar->sparse_numbytes = -1;
- tar->sparse_gnu_major = 0;
- tar->sparse_gnu_minor = 0;
- }
- if (strcmp(key, "GNU.sparse.offset") == 0) {
- tar->sparse_offset = tar_atol10(value, strlen(value));
- if (tar->sparse_numbytes != -1) {
- if (gnu_add_sparse_entry(a, tar,
- tar->sparse_offset, tar->sparse_numbytes)
- != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- tar->sparse_offset = -1;
- tar->sparse_numbytes = -1;
- }
- }
- if (strcmp(key, "GNU.sparse.numbytes") == 0) {
- tar->sparse_numbytes = tar_atol10(value, strlen(value));
- if (tar->sparse_offset != -1) {
- if (gnu_add_sparse_entry(a, tar,
- tar->sparse_offset, tar->sparse_numbytes)
- != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- tar->sparse_offset = -1;
- tar->sparse_numbytes = -1;
- }
- }
- if (strcmp(key, "GNU.sparse.size") == 0) {
- tar->realsize = tar_atol10(value, strlen(value));
- archive_entry_set_size(entry, tar->realsize);
- tar->realsize_override = 1;
- }
-
- /* GNU "0.1" sparse pax format. */
- if (strcmp(key, "GNU.sparse.map") == 0) {
- tar->sparse_gnu_major = 0;
- tar->sparse_gnu_minor = 1;
- if (gnu_sparse_01_parse(a, tar, value) != ARCHIVE_OK)
- return (ARCHIVE_WARN);
- }
-
- /* GNU "1.0" sparse pax format */
- if (strcmp(key, "GNU.sparse.major") == 0) {
- tar->sparse_gnu_major = (int)tar_atol10(value, strlen(value));
- tar->sparse_gnu_pending = 1;
- }
- if (strcmp(key, "GNU.sparse.minor") == 0) {
- tar->sparse_gnu_minor = (int)tar_atol10(value, strlen(value));
- tar->sparse_gnu_pending = 1;
- }
- if (strcmp(key, "GNU.sparse.name") == 0) {
- /*
- * The real filename; when storing sparse
- * files, GNU tar puts a synthesized name into
- * the regular 'path' attribute in an attempt
- * to limit confusion. ;-)
- */
- archive_strcpy(&(tar->entry_pathname_override), value);
- }
- if (strcmp(key, "GNU.sparse.realsize") == 0) {
- tar->realsize = tar_atol10(value, strlen(value));
- archive_entry_set_size(entry, tar->realsize);
- tar->realsize_override = 1;
- }
- break;
- case 'L':
- /* Our extensions */
-/* TODO: Handle arbitrary extended attributes... */
-/*
- if (strcmp(key, "LIBARCHIVE.xxxxxxx") == 0)
- archive_entry_set_xxxxxx(entry, value);
-*/
- if (strcmp(key, "LIBARCHIVE.creationtime") == 0) {
- pax_time(value, &s, &n);
- archive_entry_set_birthtime(entry, s, n);
- }
- if (strcmp(key, "LIBARCHIVE.symlinktype") == 0) {
- if (strcmp(value, "file") == 0) {
- archive_entry_set_symlink_type(entry,
- AE_SYMLINK_TYPE_FILE);
- } else if (strcmp(value, "dir") == 0) {
- archive_entry_set_symlink_type(entry,
- AE_SYMLINK_TYPE_DIRECTORY);
- }
- }
- if (memcmp(key, "LIBARCHIVE.xattr.", 17) == 0)
- pax_attribute_xattr(entry, key, value);
- break;
- case 'R':
- /* GNU tar uses RHT.security header to store SELinux xattrs
- * SCHILY.xattr.security.selinux == RHT.security.selinux */
- if (strcmp(key, "RHT.security.selinux") == 0) {
- pax_attribute_rht_security_selinux(entry, value,
- value_length);
- }
- break;
- case 'S':
- /* We support some keys used by the "star" archiver */
- if (strcmp(key, "SCHILY.acl.access") == 0) {
- r = pax_attribute_acl(a, tar, entry, value,
- ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
- if (r == ARCHIVE_FATAL)
- return (r);
- } else if (strcmp(key, "SCHILY.acl.default") == 0) {
- r = pax_attribute_acl(a, tar, entry, value,
- ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
- if (r == ARCHIVE_FATAL)
- return (r);
- } else if (strcmp(key, "SCHILY.acl.ace") == 0) {
- r = pax_attribute_acl(a, tar, entry, value,
- ARCHIVE_ENTRY_ACL_TYPE_NFS4);
- if (r == ARCHIVE_FATAL)
- return (r);
- } else if (strcmp(key, "SCHILY.devmajor") == 0) {
- archive_entry_set_rdevmajor(entry,
- (dev_t)tar_atol10(value, strlen(value)));
- } else if (strcmp(key, "SCHILY.devminor") == 0) {
- archive_entry_set_rdevminor(entry,
- (dev_t)tar_atol10(value, strlen(value)));
- } else if (strcmp(key, "SCHILY.fflags") == 0) {
- archive_entry_copy_fflags_text(entry, value);
- } else if (strcmp(key, "SCHILY.dev") == 0) {
- archive_entry_set_dev(entry,
- (dev_t)tar_atol10(value, strlen(value)));
- } else if (strcmp(key, "SCHILY.ino") == 0) {
- archive_entry_set_ino(entry,
- tar_atol10(value, strlen(value)));
- } else if (strcmp(key, "SCHILY.nlink") == 0) {
- archive_entry_set_nlink(entry, (unsigned)
- tar_atol10(value, strlen(value)));
- } else if (strcmp(key, "SCHILY.realsize") == 0) {
- tar->realsize = tar_atol10(value, strlen(value));
- tar->realsize_override = 1;
- archive_entry_set_size(entry, tar->realsize);
- } else if (strncmp(key, "SCHILY.xattr.", 13) == 0) {
- pax_attribute_schily_xattr(entry, key, value,
- value_length);
- } else if (strcmp(key, "SUN.holesdata") == 0) {
- /* A Solaris extension for sparse. */
- r = solaris_sparse_parse(a, tar, entry, value);
- if (r < err) {
- if (r == ARCHIVE_FATAL)
- return (r);
- err = r;
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Parse error: SUN.holesdata");
- }
- }
- break;
- case 'a':
- if (strcmp(key, "atime") == 0) {
- pax_time(value, &s, &n);
- archive_entry_set_atime(entry, s, n);
- }
- break;
- case 'c':
- if (strcmp(key, "ctime") == 0) {
- pax_time(value, &s, &n);
- archive_entry_set_ctime(entry, s, n);
- } else if (strcmp(key, "charset") == 0) {
- /* TODO: Publish charset information in entry. */
- } else if (strcmp(key, "comment") == 0) {
- /* TODO: Publish comment in entry. */
- }
- break;
- case 'g':
- if (strcmp(key, "gid") == 0) {
- archive_entry_set_gid(entry,
- tar_atol10(value, strlen(value)));
- } else if (strcmp(key, "gname") == 0) {
- archive_strcpy(&(tar->entry_gname), value);
- }
- break;
- case 'h':
- if (strcmp(key, "hdrcharset") == 0) {
- if (strcmp(value, "BINARY") == 0)
- /* Binary mode. */
- tar->pax_hdrcharset_binary = 1;
- else if (strcmp(value, "ISO-IR 10646 2000 UTF-8") == 0)
- tar->pax_hdrcharset_binary = 0;
- }
- break;
- case 'l':
- /* pax interchange doesn't distinguish hardlink vs. symlink. */
- if (strcmp(key, "linkpath") == 0) {
- archive_strcpy(&(tar->entry_linkpath), value);
- }
- break;
- case 'm':
- if (strcmp(key, "mtime") == 0) {
- pax_time(value, &s, &n);
- archive_entry_set_mtime(entry, s, n);
- }
- break;
- case 'p':
- if (strcmp(key, "path") == 0) {
- archive_strcpy(&(tar->entry_pathname), value);
- }
- break;
- case 'r':
- /* POSIX has reserved 'realtime.*' */
- break;
- case 's':
- /* POSIX has reserved 'security.*' */
- /* Someday: if (strcmp(key, "security.acl") == 0) { ... } */
- if (strcmp(key, "size") == 0) {
- /* "size" is the size of the data in the entry. */
- tar->entry_bytes_remaining
- = tar_atol10(value, strlen(value));
- if (tar->entry_bytes_remaining < 0) {
- tar->entry_bytes_remaining = 0;
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Tar size attribute is negative");
- return (ARCHIVE_FATAL);
- }
- if (tar->entry_bytes_remaining == INT64_MAX) {
- /* Note: tar_atol returns INT64_MAX on overflow */
- tar->entry_bytes_remaining = 0;
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Tar size attribute overflow");
- return (ARCHIVE_FATAL);
- }
- /*
- * The "size" pax header keyword always overrides the
- * "size" field in the tar header.
- * GNU.sparse.realsize, GNU.sparse.size and
- * SCHILY.realsize override this value.
- */
- if (!tar->realsize_override) {
- archive_entry_set_size(entry,
- tar->entry_bytes_remaining);
- tar->realsize
- = tar->entry_bytes_remaining;
- }
- }
- break;
- case 'u':
- if (strcmp(key, "uid") == 0) {
- archive_entry_set_uid(entry,
- tar_atol10(value, strlen(value)));
- } else if (strcmp(key, "uname") == 0) {
- archive_strcpy(&(tar->entry_uname), value);
- }
- break;
- }
- return (err);
-}
-
-
-
-/*
- * parse a decimal time value, which may include a fractional portion
- */
-static void
-pax_time(const char *p, int64_t *ps, long *pn)
-{
- char digit;
- int64_t s;
- unsigned long l;
- int sign;
- int64_t limit, last_digit_limit;
-
- limit = INT64_MAX / 10;
- last_digit_limit = INT64_MAX % 10;
-
- s = 0;
- sign = 1;
- if (*p == '-') {
- sign = -1;
- p++;
- }
- while (*p >= '0' && *p <= '9') {
- digit = *p - '0';
- if (s > limit ||
- (s == limit && digit > last_digit_limit)) {
- s = INT64_MAX;
- break;
- }
- s = (s * 10) + digit;
- ++p;
- }
-
- *ps = s * sign;
-
- /* Calculate nanoseconds. */
- *pn = 0;
-
- if (*p != '.')
- return;
-
- l = 100000000UL;
- do {
- ++p;
- if (*p >= '0' && *p <= '9')
- *pn += (*p - '0') * l;
- else
- break;
- } while (l /= 10);
-}
-
-/*
- * Parse GNU tar header
- */
-static int
-header_gnutar(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const void *h, size_t *unconsumed)
-{
- const struct archive_entry_header_gnutar *header;
- int64_t t;
- int err = ARCHIVE_OK;
-
- /*
- * GNU header is like POSIX ustar, except 'prefix' is
- * replaced with some other fields. This also means the
- * filename is stored as in old-style archives.
- */
-
- /* Grab fields common to all tar variants. */
- err = header_common(a, tar, entry, h);
- if (err == ARCHIVE_FATAL)
- return (err);
-
- /* Copy filename over (to ensure null termination). */
- header = (const struct archive_entry_header_gnutar *)h;
- if (archive_entry_copy_pathname_l(entry,
- header->name, sizeof(header->name), tar->sconv) != 0) {
- err = set_conversion_failed_error(a, tar->sconv, "Pathname");
- if (err == ARCHIVE_FATAL)
- return (err);
- }
-
- /* Fields common to ustar and GNU */
- /* XXX Can the following be factored out since it's common
- * to ustar and gnu tar? Is it okay to move it down into
- * header_common, perhaps? */
- if (archive_entry_copy_uname_l(entry,
- header->uname, sizeof(header->uname), tar->sconv) != 0) {
- err = set_conversion_failed_error(a, tar->sconv, "Uname");
- if (err == ARCHIVE_FATAL)
- return (err);
- }
-
- if (archive_entry_copy_gname_l(entry,
- header->gname, sizeof(header->gname), tar->sconv) != 0) {
- err = set_conversion_failed_error(a, tar->sconv, "Gname");
- if (err == ARCHIVE_FATAL)
- return (err);
- }
-
- /* Parse out device numbers only for char and block specials */
- if (header->typeflag[0] == '3' || header->typeflag[0] == '4') {
- archive_entry_set_rdevmajor(entry, (dev_t)
- tar_atol(header->rdevmajor, sizeof(header->rdevmajor)));
- archive_entry_set_rdevminor(entry, (dev_t)
- tar_atol(header->rdevminor, sizeof(header->rdevminor)));
- } else
- archive_entry_set_rdev(entry, 0);
-
- tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
-
- /* Grab GNU-specific fields. */
- t = tar_atol(header->atime, sizeof(header->atime));
- if (t > 0)
- archive_entry_set_atime(entry, t, 0);
- t = tar_atol(header->ctime, sizeof(header->ctime));
- if (t > 0)
- archive_entry_set_ctime(entry, t, 0);
-
- if (header->realsize[0] != 0) {
- tar->realsize
- = tar_atol(header->realsize, sizeof(header->realsize));
- archive_entry_set_size(entry, tar->realsize);
- tar->realsize_override = 1;
- }
-
- if (header->sparse[0].offset[0] != 0) {
- if (gnu_sparse_old_read(a, tar, header, unconsumed)
- != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- } else {
- if (header->isextended[0] != 0) {
- /* XXX WTF? XXX */
- }
- }
-
- return (err);
-}
-
-static int
-gnu_add_sparse_entry(struct archive_read *a, struct tar *tar,
- int64_t offset, int64_t remaining)
-{
- struct sparse_block *p;
-
- p = (struct sparse_block *)calloc(1, sizeof(*p));
- if (p == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- if (tar->sparse_last != NULL)
- tar->sparse_last->next = p;
- else
- tar->sparse_list = p;
- tar->sparse_last = p;
- if (remaining < 0 || offset < 0 || offset > INT64_MAX - remaining) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Malformed sparse map data");
- return (ARCHIVE_FATAL);
- }
- p->offset = offset;
- p->remaining = remaining;
- return (ARCHIVE_OK);
-}
-
-static void
-gnu_clear_sparse_list(struct tar *tar)
-{
- struct sparse_block *p;
-
- while (tar->sparse_list != NULL) {
- p = tar->sparse_list;
- tar->sparse_list = p->next;
- free(p);
- }
- tar->sparse_last = NULL;
-}
-
-/*
- * GNU tar old-format sparse data.
- *
- * GNU old-format sparse data is stored in a fixed-field
- * format. Offset/size values are 11-byte octal fields (same
- * format as 'size' field in ustart header). These are
- * stored in the header, allocating subsequent header blocks
- * as needed. Extending the header in this way is a pretty
- * severe POSIX violation; this design has earned GNU tar a
- * lot of criticism.
- */
-
-static int
-gnu_sparse_old_read(struct archive_read *a, struct tar *tar,
- const struct archive_entry_header_gnutar *header, size_t *unconsumed)
-{
- ssize_t bytes_read;
- const void *data;
- struct extended {
- struct gnu_sparse sparse[21];
- char isextended[1];
- char padding[7];
- };
- const struct extended *ext;
-
- if (gnu_sparse_old_parse(a, tar, header->sparse, 4) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- if (header->isextended[0] == 0)
- return (ARCHIVE_OK);
-
- do {
- tar_flush_unconsumed(a, unconsumed);
- data = __archive_read_ahead(a, 512, &bytes_read);
- if (bytes_read < 0)
- return (ARCHIVE_FATAL);
- if (bytes_read < 512) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated tar archive "
- "detected while reading sparse file data");
- return (ARCHIVE_FATAL);
- }
- *unconsumed = 512;
- ext = (const struct extended *)data;
- if (gnu_sparse_old_parse(a, tar, ext->sparse, 21) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- } while (ext->isextended[0] != 0);
- if (tar->sparse_list != NULL)
- tar->entry_offset = tar->sparse_list->offset;
- return (ARCHIVE_OK);
-}
-
-static int
-gnu_sparse_old_parse(struct archive_read *a, struct tar *tar,
- const struct gnu_sparse *sparse, int length)
-{
- while (length > 0 && sparse->offset[0] != 0) {
- if (gnu_add_sparse_entry(a, tar,
- tar_atol(sparse->offset, sizeof(sparse->offset)),
- tar_atol(sparse->numbytes, sizeof(sparse->numbytes)))
- != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- sparse++;
- length--;
- }
- return (ARCHIVE_OK);
-}
-
-/*
- * GNU tar sparse format 0.0
- *
- * Beginning with GNU tar 1.15, sparse files are stored using
- * information in the pax extended header. The GNU tar maintainers
- * have gone through a number of variations in the process of working
- * out this scheme; fortunately, they're all numbered.
- *
- * Sparse format 0.0 uses attribute GNU.sparse.numblocks to store the
- * number of blocks, and GNU.sparse.offset/GNU.sparse.numbytes to
- * store offset/size for each block. The repeated instances of these
- * latter fields violate the pax specification (which frowns on
- * duplicate keys), so this format was quickly replaced.
- */
-
-/*
- * GNU tar sparse format 0.1
- *
- * This version replaced the offset/numbytes attributes with
- * a single "map" attribute that stored a list of integers. This
- * format had two problems: First, the "map" attribute could be very
- * long, which caused problems for some implementations. More
- * importantly, the sparse data was lost when extracted by archivers
- * that didn't recognize this extension.
- */
-
-static int
-gnu_sparse_01_parse(struct archive_read *a, struct tar *tar, const char *p)
-{
- const char *e;
- int64_t offset = -1, size = -1;
-
- for (;;) {
- e = p;
- while (*e != '\0' && *e != ',') {
- if (*e < '0' || *e > '9')
- return (ARCHIVE_WARN);
- e++;
- }
- if (offset < 0) {
- offset = tar_atol10(p, e - p);
- if (offset < 0)
- return (ARCHIVE_WARN);
- } else {
- size = tar_atol10(p, e - p);
- if (size < 0)
- return (ARCHIVE_WARN);
- if (gnu_add_sparse_entry(a, tar, offset, size)
- != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- offset = -1;
- }
- if (*e == '\0')
- return (ARCHIVE_OK);
- p = e + 1;
- }
-}
-
-/*
- * GNU tar sparse format 1.0
- *
- * The idea: The offset/size data is stored as a series of base-10
- * ASCII numbers prepended to the file data, so that dearchivers that
- * don't support this format will extract the block map along with the
- * data and a separate post-process can restore the sparseness.
- *
- * Unfortunately, GNU tar 1.16 had a bug that added unnecessary
- * padding to the body of the file when using this format. GNU tar
- * 1.17 corrected this bug without bumping the version number, so
- * it's not possible to support both variants. This code supports
- * the later variant at the expense of not supporting the former.
- *
- * This variant also replaced GNU.sparse.size with GNU.sparse.realsize
- * and introduced the GNU.sparse.major/GNU.sparse.minor attributes.
- */
-
-/*
- * Read the next line from the input, and parse it as a decimal
- * integer followed by '\n'. Returns positive integer value or
- * negative on error.
- */
-static int64_t
-gnu_sparse_10_atol(struct archive_read *a, struct tar *tar,
- int64_t *remaining, size_t *unconsumed)
-{
- int64_t l, limit, last_digit_limit;
- const char *p;
- ssize_t bytes_read;
- int base, digit;
-
- base = 10;
- limit = INT64_MAX / base;
- last_digit_limit = INT64_MAX % base;
-
- /*
- * Skip any lines starting with '#'; GNU tar specs
- * don't require this, but they should.
- */
- do {
- bytes_read = readline(a, tar, &p,
- (ssize_t)tar_min(*remaining, 100), unconsumed);
- if (bytes_read <= 0)
- return (ARCHIVE_FATAL);
- *remaining -= bytes_read;
- } while (p[0] == '#');
-
- l = 0;
- while (bytes_read > 0) {
- if (*p == '\n')
- return (l);
- if (*p < '0' || *p >= '0' + base)
- return (ARCHIVE_WARN);
- digit = *p - '0';
- if (l > limit || (l == limit && digit > last_digit_limit))
- l = INT64_MAX; /* Truncate on overflow. */
- else
- l = (l * base) + digit;
- p++;
- bytes_read--;
- }
- /* TODO: Error message. */
- return (ARCHIVE_WARN);
-}
-
-/*
- * Returns length (in bytes) of the sparse data description
- * that was read.
- */
-static ssize_t
-gnu_sparse_10_read(struct archive_read *a, struct tar *tar, size_t *unconsumed)
-{
- ssize_t bytes_read;
- int entries;
- int64_t offset, size, to_skip, remaining;
-
- /* Clear out the existing sparse list. */
- gnu_clear_sparse_list(tar);
-
- remaining = tar->entry_bytes_remaining;
-
- /* Parse entries. */
- entries = (int)gnu_sparse_10_atol(a, tar, &remaining, unconsumed);
- if (entries < 0)
- return (ARCHIVE_FATAL);
- /* Parse the individual entries. */
- while (entries-- > 0) {
- /* Parse offset/size */
- offset = gnu_sparse_10_atol(a, tar, &remaining, unconsumed);
- if (offset < 0)
- return (ARCHIVE_FATAL);
- size = gnu_sparse_10_atol(a, tar, &remaining, unconsumed);
- if (size < 0)
- return (ARCHIVE_FATAL);
- /* Add a new sparse entry. */
- if (gnu_add_sparse_entry(a, tar, offset, size) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- }
- /* Skip rest of block... */
- tar_flush_unconsumed(a, unconsumed);
- bytes_read = (ssize_t)(tar->entry_bytes_remaining - remaining);
- to_skip = 0x1ff & -bytes_read;
- /* Fail if tar->entry_bytes_remaing would get negative */
- if (to_skip > remaining)
- return (ARCHIVE_FATAL);
- if (to_skip != __archive_read_consume(a, to_skip))
- return (ARCHIVE_FATAL);
- return ((ssize_t)(bytes_read + to_skip));
-}
-
-/*
- * Solaris pax extension for a sparse file. This is recorded with the
- * data and hole pairs. The way recording sparse information by Solaris'
- * pax simply indicates where data and sparse are, so the stored contents
- * consist of both data and hole.
- */
-static int
-solaris_sparse_parse(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const char *p)
-{
- const char *e;
- int64_t start, end;
- int hole = 1;
-
- (void)entry; /* UNUSED */
-
- end = 0;
- if (*p == ' ')
- p++;
- else
- return (ARCHIVE_WARN);
- for (;;) {
- e = p;
- while (*e != '\0' && *e != ' ') {
- if (*e < '0' || *e > '9')
- return (ARCHIVE_WARN);
- e++;
- }
- start = end;
- end = tar_atol10(p, e - p);
- if (end < 0)
- return (ARCHIVE_WARN);
- if (start < end) {
- if (gnu_add_sparse_entry(a, tar, start,
- end - start) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- tar->sparse_last->hole = hole;
- }
- if (*e == '\0')
- return (ARCHIVE_OK);
- p = e + 1;
- hole = hole == 0;
- }
-}
-
-/*-
- * Convert text->integer.
- *
- * Traditional tar formats (including POSIX) specify base-8 for
- * all of the standard numeric fields. This is a significant limitation
- * in practice:
- * = file size is limited to 8GB
- * = rdevmajor and rdevminor are limited to 21 bits
- * = uid/gid are limited to 21 bits
- *
- * There are two workarounds for this:
- * = pax extended headers, which use variable-length string fields
- * = GNU tar and STAR both allow either base-8 or base-256 in
- * most fields. The high bit is set to indicate base-256.
- *
- * On read, this implementation supports both extensions.
- */
-static int64_t
-tar_atol(const char *p, size_t char_cnt)
-{
- /*
- * Technically, GNU tar considers a field to be in base-256
- * only if the first byte is 0xff or 0x80.
- */
- if (*p & 0x80)
- return (tar_atol256(p, char_cnt));
- return (tar_atol8(p, char_cnt));
-}
-
-/*
- * Note that this implementation does not (and should not!) obey
- * locale settings; you cannot simply substitute strtol here, since
- * it does obey locale.
- */
-static int64_t
-tar_atol_base_n(const char *p, size_t char_cnt, int base)
-{
- int64_t l, maxval, limit, last_digit_limit;
- int digit, sign;
-
- maxval = INT64_MAX;
- limit = INT64_MAX / base;
- last_digit_limit = INT64_MAX % base;
-
- /* the pointer will not be dereferenced if char_cnt is zero
- * due to the way the && operator is evaluated.
- */
- while (char_cnt != 0 && (*p == ' ' || *p == '\t')) {
- p++;
- char_cnt--;
- }
-
- sign = 1;
- if (char_cnt != 0 && *p == '-') {
- sign = -1;
- p++;
- char_cnt--;
-
- maxval = INT64_MIN;
- limit = -(INT64_MIN / base);
- last_digit_limit = -(INT64_MIN % base);
- }
-
- l = 0;
- if (char_cnt != 0) {
- digit = *p - '0';
- while (digit >= 0 && digit < base && char_cnt != 0) {
- if (l>limit || (l == limit && digit >= last_digit_limit)) {
- return maxval; /* Truncate on overflow. */
- }
- l = (l * base) + digit;
- digit = *++p - '0';
- char_cnt--;
- }
- }
- return (sign < 0) ? -l : l;
-}
-
-static int64_t
-tar_atol8(const char *p, size_t char_cnt)
-{
- return tar_atol_base_n(p, char_cnt, 8);
-}
-
-static int64_t
-tar_atol10(const char *p, size_t char_cnt)
-{
- return tar_atol_base_n(p, char_cnt, 10);
-}
-
-/*
- * Parse a base-256 integer. This is just a variable-length
- * twos-complement signed binary value in big-endian order, except
- * that the high-order bit is ignored. The values here can be up to
- * 12 bytes, so we need to be careful about overflowing 64-bit
- * (8-byte) integers.
- *
- * This code unashamedly assumes that the local machine uses 8-bit
- * bytes and twos-complement arithmetic.
- */
-static int64_t
-tar_atol256(const char *_p, size_t char_cnt)
-{
- uint64_t l;
- const unsigned char *p = (const unsigned char *)_p;
- unsigned char c, neg;
-
- /* Extend 7-bit 2s-comp to 8-bit 2s-comp, decide sign. */
- c = *p;
- if (c & 0x40) {
- neg = 0xff;
- c |= 0x80;
- l = ~ARCHIVE_LITERAL_ULL(0);
- } else {
- neg = 0;
- c &= 0x7f;
- l = 0;
- }
-
- /* If more than 8 bytes, check that we can ignore
- * high-order bits without overflow. */
- while (char_cnt > sizeof(int64_t)) {
- --char_cnt;
- if (c != neg)
- return neg ? INT64_MIN : INT64_MAX;
- c = *++p;
- }
-
- /* c is first byte that fits; if sign mismatch, return overflow */
- if ((c ^ neg) & 0x80) {
- return neg ? INT64_MIN : INT64_MAX;
- }
-
- /* Accumulate remaining bytes. */
- while (--char_cnt > 0) {
- l = (l << 8) | c;
- c = *++p;
- }
- l = (l << 8) | c;
- /* Return signed twos-complement value. */
- return (int64_t)(l);
-}
-
-/*
- * Returns length of line (including trailing newline)
- * or negative on error. 'start' argument is updated to
- * point to first character of line. This avoids copying
- * when possible.
- */
-static ssize_t
-readline(struct archive_read *a, struct tar *tar, const char **start,
- ssize_t limit, size_t *unconsumed)
-{
- ssize_t bytes_read;
- ssize_t total_size = 0;
- const void *t;
- const char *s;
- void *p;
-
- tar_flush_unconsumed(a, unconsumed);
-
- t = __archive_read_ahead(a, 1, &bytes_read);
- if (bytes_read <= 0)
- return (ARCHIVE_FATAL);
- s = t; /* Start of line? */
- p = memchr(t, '\n', bytes_read);
- /* If we found '\n' in the read buffer, return pointer to that. */
- if (p != NULL) {
- bytes_read = 1 + ((const char *)p) - s;
- if (bytes_read > limit) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Line too long");
- return (ARCHIVE_FATAL);
- }
- *unconsumed = bytes_read;
- *start = s;
- return (bytes_read);
- }
- *unconsumed = bytes_read;
- /* Otherwise, we need to accumulate in a line buffer. */
- for (;;) {
- if (total_size + bytes_read > limit) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Line too long");
- return (ARCHIVE_FATAL);
- }
- if (archive_string_ensure(&tar->line, total_size + bytes_read) == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate working buffer");
- return (ARCHIVE_FATAL);
- }
- memcpy(tar->line.s + total_size, t, bytes_read);
- tar_flush_unconsumed(a, unconsumed);
- total_size += bytes_read;
- /* If we found '\n', clean up and return. */
- if (p != NULL) {
- *start = tar->line.s;
- return (total_size);
- }
- /* Read some more. */
- t = __archive_read_ahead(a, 1, &bytes_read);
- if (bytes_read <= 0)
- return (ARCHIVE_FATAL);
- s = t; /* Start of line? */
- p = memchr(t, '\n', bytes_read);
- /* If we found '\n', trim the read. */
- if (p != NULL) {
- bytes_read = 1 + ((const char *)p) - s;
- }
- *unconsumed = bytes_read;
- }
-}
-
-/*
- * base64_decode - Base64 decode
- *
- * This accepts most variations of base-64 encoding, including:
- * * with or without line breaks
- * * with or without the final group padded with '=' or '_' characters
- * (The most economical Base-64 variant does not pad the last group and
- * omits line breaks; RFC1341 used for MIME requires both.)
- */
-static char *
-base64_decode(const char *s, size_t len, size_t *out_len)
-{
- static const unsigned char digits[64] = {
- 'A','B','C','D','E','F','G','H','I','J','K','L','M','N',
- 'O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b',
- 'c','d','e','f','g','h','i','j','k','l','m','n','o','p',
- 'q','r','s','t','u','v','w','x','y','z','0','1','2','3',
- '4','5','6','7','8','9','+','/' };
- static unsigned char decode_table[128];
- char *out, *d;
- const unsigned char *src = (const unsigned char *)s;
-
- /* If the decode table is not yet initialized, prepare it. */
- if (decode_table[digits[1]] != 1) {
- unsigned i;
- memset(decode_table, 0xff, sizeof(decode_table));
- for (i = 0; i < sizeof(digits); i++)
- decode_table[digits[i]] = i;
- }
-
- /* Allocate enough space to hold the entire output. */
- /* Note that we may not use all of this... */
- out = (char *)malloc(len - len / 4 + 1);
- if (out == NULL) {
- *out_len = 0;
- return (NULL);
- }
- d = out;
-
- while (len > 0) {
- /* Collect the next group of (up to) four characters. */
- int v = 0;
- int group_size = 0;
- while (group_size < 4 && len > 0) {
- /* '=' or '_' padding indicates final group. */
- if (*src == '=' || *src == '_') {
- len = 0;
- break;
- }
- /* Skip illegal characters (including line breaks) */
- if (*src > 127 || *src < 32
- || decode_table[*src] == 0xff) {
- len--;
- src++;
- continue;
- }
- v <<= 6;
- v |= decode_table[*src++];
- len --;
- group_size++;
- }
- /* Align a short group properly. */
- v <<= 6 * (4 - group_size);
- /* Unpack the group we just collected. */
- switch (group_size) {
- case 4: d[2] = v & 0xff;
- /* FALLTHROUGH */
- case 3: d[1] = (v >> 8) & 0xff;
- /* FALLTHROUGH */
- case 2: d[0] = (v >> 16) & 0xff;
- break;
- case 1: /* this is invalid! */
- break;
- }
- d += group_size * 3 / 4;
- }
-
- *out_len = d - out;
- return (out);
-}
-
-static char *
-url_decode(const char *in)
-{
- char *out, *d;
- const char *s;
-
- out = (char *)malloc(strlen(in) + 1);
- if (out == NULL)
- return (NULL);
- for (s = in, d = out; *s != '\0'; ) {
- if (s[0] == '%' && s[1] != '\0' && s[2] != '\0') {
- /* Try to convert % escape */
- int digit1 = tohex(s[1]);
- int digit2 = tohex(s[2]);
- if (digit1 >= 0 && digit2 >= 0) {
- /* Looks good, consume three chars */
- s += 3;
- /* Convert output */
- *d++ = ((digit1 << 4) | digit2);
- continue;
- }
- /* Else fall through and treat '%' as normal char */
- }
- *d++ = *s++;
- }
- *d = '\0';
- return (out);
-}
-
-static int
-tohex(int c)
-{
- if (c >= '0' && c <= '9')
- return (c - '0');
- else if (c >= 'A' && c <= 'F')
- return (c - 'A' + 10);
- else if (c >= 'a' && c <= 'f')
- return (c - 'a' + 10);
- else
- return (-1);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_format_warc.c b/contrib/libs/libarchive/libarchive/archive_read_support_format_warc.c
deleted file mode 100644
index 61ab29ea14..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_format_warc.c
+++ /dev/null
@@ -1,848 +0,0 @@
-/*-
- * Copyright (c) 2014 Sebastian Freundt
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-/**
- * WARC is standardised by ISO TC46/SC4/WG12 and currently available as
- * ISO 28500:2009.
- * For the purposes of this file we used the final draft from:
- * http://bibnum.bnf.fr/warc/WARC_ISO_28500_version1_latestdraft.pdf
- *
- * Todo:
- * [ ] real-world warcs can contain resources at endpoints ending in /
- * e.g. http://bibnum.bnf.fr/warc/
- * if you're lucky their response contains a Content-Location: header
- * pointing to a unix-compliant filename, in the example above it's
- * Content-Location: http://bibnum.bnf.fr/warc/index.html
- * however, that's not mandated and github for example doesn't follow
- * this convention.
- * We need a set of archive options to control what to do with
- * entries like these, at the moment care is taken to skip them.
- *
- **/
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-#ifdef HAVE_CTYPE_H
-#include <ctype.h>
-#endif
-#ifdef HAVE_TIME_H
-#include <time.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-typedef enum {
- WT_NONE,
- /* warcinfo */
- WT_INFO,
- /* metadata */
- WT_META,
- /* resource */
- WT_RSRC,
- /* request, unsupported */
- WT_REQ,
- /* response, unsupported */
- WT_RSP,
- /* revisit, unsupported */
- WT_RVIS,
- /* conversion, unsupported */
- WT_CONV,
- /* continuation, unsupported at the moment */
- WT_CONT,
- /* invalid type */
- LAST_WT
-} warc_type_t;
-
-typedef struct {
- size_t len;
- const char *str;
-} warc_string_t;
-
-typedef struct {
- size_t len;
- char *str;
-} warc_strbuf_t;
-
-struct warc_s {
- /* content length ahead */
- size_t cntlen;
- /* and how much we've processed so far */
- size_t cntoff;
- /* and how much we need to consume between calls */
- size_t unconsumed;
-
- /* string pool */
- warc_strbuf_t pool;
- /* previous version */
- unsigned int pver;
- /* stringified format name */
- struct archive_string sver;
-};
-
-static int _warc_bid(struct archive_read *a, int);
-static int _warc_cleanup(struct archive_read *a);
-static int _warc_read(struct archive_read*, const void**, size_t*, int64_t*);
-static int _warc_skip(struct archive_read *a);
-static int _warc_rdhdr(struct archive_read *a, struct archive_entry *e);
-
-/* private routines */
-static unsigned int _warc_rdver(const char *buf, size_t bsz);
-static unsigned int _warc_rdtyp(const char *buf, size_t bsz);
-static warc_string_t _warc_rduri(const char *buf, size_t bsz);
-static ssize_t _warc_rdlen(const char *buf, size_t bsz);
-static time_t _warc_rdrtm(const char *buf, size_t bsz);
-static time_t _warc_rdmtm(const char *buf, size_t bsz);
-static const char *_warc_find_eoh(const char *buf, size_t bsz);
-static const char *_warc_find_eol(const char *buf, size_t bsz);
-
-int
-archive_read_support_format_warc(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- struct warc_s *w;
- int r;
-
- archive_check_magic(_a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_format_warc");
-
- if ((w = calloc(1, sizeof(*w))) == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate warc data");
- return (ARCHIVE_FATAL);
- }
-
- r = __archive_read_register_format(
- a, w, "warc",
- _warc_bid, NULL, _warc_rdhdr, _warc_read,
- _warc_skip, NULL, _warc_cleanup, NULL, NULL);
-
- if (r != ARCHIVE_OK) {
- free(w);
- return (r);
- }
- return (ARCHIVE_OK);
-}
-
-static int
-_warc_cleanup(struct archive_read *a)
-{
- struct warc_s *w = a->format->data;
-
- if (w->pool.len > 0U) {
- free(w->pool.str);
- }
- archive_string_free(&w->sver);
- free(w);
- a->format->data = NULL;
- return (ARCHIVE_OK);
-}
-
-static int
-_warc_bid(struct archive_read *a, int best_bid)
-{
- const char *hdr;
- ssize_t nrd;
- unsigned int ver;
-
- (void)best_bid; /* UNUSED */
-
- /* check first line of file, it should be a record already */
- if ((hdr = __archive_read_ahead(a, 12U, &nrd)) == NULL) {
- /* no idea what to do */
- return -1;
- } else if (nrd < 12) {
- /* nah, not for us, our magic cookie is at least 12 bytes */
- return -1;
- }
-
- /* otherwise snarf the record's version number */
- ver = _warc_rdver(hdr, nrd);
- if (ver < 1200U || ver > 10000U) {
- /* we only support WARC 0.12 to 1.0 */
- return -1;
- }
-
- /* otherwise be confident */
- return (64);
-}
-
-static int
-_warc_rdhdr(struct archive_read *a, struct archive_entry *entry)
-{
-#define HDR_PROBE_LEN (12U)
- struct warc_s *w = a->format->data;
- unsigned int ver;
- const char *buf;
- ssize_t nrd;
- const char *eoh;
- /* for the file name, saves some strndup()'ing */
- warc_string_t fnam;
- /* warc record type, not that we really use it a lot */
- warc_type_t ftyp;
- /* content-length+error monad */
- ssize_t cntlen;
- /* record time is the WARC-Date time we reinterpret it as ctime */
- time_t rtime;
- /* mtime is the Last-Modified time which will be the entry's mtime */
- time_t mtime;
-
-start_over:
- /* just use read_ahead() they keep track of unconsumed
- * bits and bobs for us; no need to put an extra shift in
- * and reproduce that functionality here */
- buf = __archive_read_ahead(a, HDR_PROBE_LEN, &nrd);
-
- if (nrd < 0) {
- /* no good */
- archive_set_error(
- &a->archive, ARCHIVE_ERRNO_MISC,
- "Bad record header");
- return (ARCHIVE_FATAL);
- } else if (buf == NULL) {
- /* there should be room for at least WARC/bla\r\n
- * must be EOF therefore */
- return (ARCHIVE_EOF);
- }
- /* looks good so far, try and find the end of the header now */
- eoh = _warc_find_eoh(buf, nrd);
- if (eoh == NULL) {
- /* still no good, the header end might be beyond the
- * probe we've requested, but then again who'd cram
- * so much stuff into the header *and* be 28500-compliant */
- archive_set_error(
- &a->archive, ARCHIVE_ERRNO_MISC,
- "Bad record header");
- return (ARCHIVE_FATAL);
- }
- ver = _warc_rdver(buf, eoh - buf);
- /* we currently support WARC 0.12 to 1.0 */
- if (ver == 0U) {
- archive_set_error(
- &a->archive, ARCHIVE_ERRNO_MISC,
- "Invalid record version");
- return (ARCHIVE_FATAL);
- } else if (ver < 1200U || ver > 10000U) {
- archive_set_error(
- &a->archive, ARCHIVE_ERRNO_MISC,
- "Unsupported record version: %u.%u",
- ver / 10000, (ver % 10000) / 100);
- return (ARCHIVE_FATAL);
- }
- cntlen = _warc_rdlen(buf, eoh - buf);
- if (cntlen < 0) {
- /* nightmare! the specs say content-length is mandatory
- * so I don't feel overly bad stopping the reader here */
- archive_set_error(
- &a->archive, EINVAL,
- "Bad content length");
- return (ARCHIVE_FATAL);
- }
- rtime = _warc_rdrtm(buf, eoh - buf);
- if (rtime == (time_t)-1) {
- /* record time is mandatory as per WARC/1.0,
- * so just barf here, fast and loud */
- archive_set_error(
- &a->archive, EINVAL,
- "Bad record time");
- return (ARCHIVE_FATAL);
- }
-
- /* let the world know we're a WARC archive */
- a->archive.archive_format = ARCHIVE_FORMAT_WARC;
- if (ver != w->pver) {
- /* stringify this entry's version */
- archive_string_sprintf(&w->sver,
- "WARC/%u.%u", ver / 10000, (ver % 10000) / 100);
- /* remember the version */
- w->pver = ver;
- }
- /* start off with the type */
- ftyp = _warc_rdtyp(buf, eoh - buf);
- /* and let future calls know about the content */
- w->cntlen = cntlen;
- w->cntoff = 0U;
- mtime = 0;/* Avoid compiling error on some platform. */
-
- switch (ftyp) {
- case WT_RSRC:
- case WT_RSP:
- /* only try and read the filename in the cases that are
- * guaranteed to have one */
- fnam = _warc_rduri(buf, eoh - buf);
- /* check the last character in the URI to avoid creating
- * directory endpoints as files, see Todo above */
- if (fnam.len == 0 || fnam.str[fnam.len - 1] == '/') {
- /* break here for now */
- fnam.len = 0U;
- fnam.str = NULL;
- break;
- }
- /* bang to our string pool, so we save a
- * malloc()+free() roundtrip */
- if (fnam.len + 1U > w->pool.len) {
- w->pool.len = ((fnam.len + 64U) / 64U) * 64U;
- w->pool.str = realloc(w->pool.str, w->pool.len);
- }
- memcpy(w->pool.str, fnam.str, fnam.len);
- w->pool.str[fnam.len] = '\0';
- /* let no one else know about the pool, it's a secret, shhh */
- fnam.str = w->pool.str;
-
- /* snarf mtime or deduce from rtime
- * this is a custom header added by our writer, it's quite
- * hard to believe anyone else would go through with it
- * (apart from being part of some http responses of course) */
- if ((mtime = _warc_rdmtm(buf, eoh - buf)) == (time_t)-1) {
- mtime = rtime;
- }
- break;
- case WT_NONE:
- case WT_INFO:
- case WT_META:
- case WT_REQ:
- case WT_RVIS:
- case WT_CONV:
- case WT_CONT:
- case LAST_WT:
- default:
- fnam.len = 0U;
- fnam.str = NULL;
- break;
- }
-
- /* now eat some of those delicious buffer bits */
- __archive_read_consume(a, eoh - buf);
-
- switch (ftyp) {
- case WT_RSRC:
- case WT_RSP:
- if (fnam.len > 0U) {
- /* populate entry object */
- archive_entry_set_filetype(entry, AE_IFREG);
- archive_entry_copy_pathname(entry, fnam.str);
- archive_entry_set_size(entry, cntlen);
- archive_entry_set_perm(entry, 0644);
- /* rtime is the new ctime, mtime stays mtime */
- archive_entry_set_ctime(entry, rtime, 0L);
- archive_entry_set_mtime(entry, mtime, 0L);
- break;
- }
- /* FALLTHROUGH */
- case WT_NONE:
- case WT_INFO:
- case WT_META:
- case WT_REQ:
- case WT_RVIS:
- case WT_CONV:
- case WT_CONT:
- case LAST_WT:
- default:
- /* consume the content and start over */
- _warc_skip(a);
- goto start_over;
- }
- return (ARCHIVE_OK);
-}
-
-static int
-_warc_read(struct archive_read *a, const void **buf, size_t *bsz, int64_t *off)
-{
- struct warc_s *w = a->format->data;
- const char *rab;
- ssize_t nrd;
-
- if (w->cntoff >= w->cntlen) {
- eof:
- /* it's our lucky day, no work, we can leave early */
- *buf = NULL;
- *bsz = 0U;
- *off = w->cntoff + 4U/*for \r\n\r\n separator*/;
- w->unconsumed = 0U;
- return (ARCHIVE_EOF);
- }
-
- if (w->unconsumed) {
- __archive_read_consume(a, w->unconsumed);
- w->unconsumed = 0U;
- }
-
- rab = __archive_read_ahead(a, 1U, &nrd);
- if (nrd < 0) {
- *bsz = 0U;
- /* big catastrophe */
- return (int)nrd;
- } else if (nrd == 0) {
- goto eof;
- } else if ((size_t)nrd > w->cntlen - w->cntoff) {
- /* clamp to content-length */
- nrd = w->cntlen - w->cntoff;
- }
- *off = w->cntoff;
- *bsz = nrd;
- *buf = rab;
-
- w->cntoff += nrd;
- w->unconsumed = (size_t)nrd;
- return (ARCHIVE_OK);
-}
-
-static int
-_warc_skip(struct archive_read *a)
-{
- struct warc_s *w = a->format->data;
-
- __archive_read_consume(a, w->cntlen + 4U/*\r\n\r\n separator*/);
- w->cntlen = 0U;
- w->cntoff = 0U;
- return (ARCHIVE_OK);
-}
-
-
-/* private routines */
-static void*
-deconst(const void *c)
-{
- return (void *)(uintptr_t)c;
-}
-
-static char*
-xmemmem(const char *hay, const size_t haysize,
- const char *needle, const size_t needlesize)
-{
- const char *const eoh = hay + haysize;
- const char *const eon = needle + needlesize;
- const char *hp;
- const char *np;
- const char *cand;
- unsigned int hsum;
- unsigned int nsum;
- unsigned int eqp;
-
- /* trivial checks first
- * a 0-sized needle is defined to be found anywhere in haystack
- * then run strchr() to find a candidate in HAYSTACK (i.e. a portion
- * that happens to begin with *NEEDLE) */
- if (needlesize == 0UL) {
- return deconst(hay);
- } else if ((hay = memchr(hay, *needle, haysize)) == NULL) {
- /* trivial */
- return NULL;
- }
-
- /* First characters of haystack and needle are the same now. Both are
- * guaranteed to be at least one character long. Now computes the sum
- * of characters values of needle together with the sum of the first
- * needle_len characters of haystack. */
- for (hp = hay + 1U, np = needle + 1U, hsum = *hay, nsum = *hay, eqp = 1U;
- hp < eoh && np < eon;
- hsum ^= *hp, nsum ^= *np, eqp &= *hp == *np, hp++, np++);
-
- /* HP now references the (NEEDLESIZE + 1)-th character. */
- if (np < eon) {
- /* haystack is smaller than needle, :O */
- return NULL;
- } else if (eqp) {
- /* found a match */
- return deconst(hay);
- }
-
- /* now loop through the rest of haystack,
- * updating the sum iteratively */
- for (cand = hay; hp < eoh; hp++) {
- hsum ^= *cand++;
- hsum ^= *hp;
-
- /* Since the sum of the characters is already known to be
- * equal at that point, it is enough to check just NEEDLESIZE - 1
- * characters for equality,
- * also CAND is by design < HP, so no need for range checks */
- if (hsum == nsum && memcmp(cand, needle, needlesize - 1U) == 0) {
- return deconst(cand);
- }
- }
- return NULL;
-}
-
-static int
-strtoi_lim(const char *str, const char **ep, int llim, int ulim)
-{
- int res = 0;
- const char *sp;
- /* we keep track of the number of digits via rulim */
- int rulim;
-
- for (sp = str, rulim = ulim > 10 ? ulim : 10;
- res * 10 <= ulim && rulim && *sp >= '0' && *sp <= '9';
- sp++, rulim /= 10) {
- res *= 10;
- res += *sp - '0';
- }
- if (sp == str) {
- res = -1;
- } else if (res < llim || res > ulim) {
- res = -2;
- }
- *ep = (const char*)sp;
- return res;
-}
-
-static time_t
-time_from_tm(struct tm *t)
-{
-#if HAVE__MKGMTIME
- return _mkgmtime(t);
-#elif HAVE_TIMEGM
- /* Use platform timegm() if available. */
- return (timegm(t));
-#else
- /* Else use direct calculation using POSIX assumptions. */
- /* First, fix up tm_yday based on the year/month/day. */
- if (mktime(t) == (time_t)-1)
- return ((time_t)-1);
- /* Then we can compute timegm() from first principles. */
- return (t->tm_sec
- + t->tm_min * 60
- + t->tm_hour * 3600
- + t->tm_yday * 86400
- + (t->tm_year - 70) * 31536000
- + ((t->tm_year - 69) / 4) * 86400
- - ((t->tm_year - 1) / 100) * 86400
- + ((t->tm_year + 299) / 400) * 86400);
-#endif
-}
-
-static time_t
-xstrpisotime(const char *s, char **endptr)
-{
-/** like strptime() but strictly for ISO 8601 Zulu strings */
- struct tm tm;
- time_t res = (time_t)-1;
-
- /* make sure tm is clean */
- memset(&tm, 0, sizeof(tm));
-
- /* as a courtesy to our callers, and since this is a non-standard
- * routine, we skip leading whitespace */
- while (*s == ' ' || *s == '\t')
- ++s;
-
- /* read year */
- if ((tm.tm_year = strtoi_lim(s, &s, 1583, 4095)) < 0 || *s++ != '-') {
- goto out;
- }
- /* read month */
- if ((tm.tm_mon = strtoi_lim(s, &s, 1, 12)) < 0 || *s++ != '-') {
- goto out;
- }
- /* read day-of-month */
- if ((tm.tm_mday = strtoi_lim(s, &s, 1, 31)) < 0 || *s++ != 'T') {
- goto out;
- }
- /* read hour */
- if ((tm.tm_hour = strtoi_lim(s, &s, 0, 23)) < 0 || *s++ != ':') {
- goto out;
- }
- /* read minute */
- if ((tm.tm_min = strtoi_lim(s, &s, 0, 59)) < 0 || *s++ != ':') {
- goto out;
- }
- /* read second */
- if ((tm.tm_sec = strtoi_lim(s, &s, 0, 60)) < 0 || *s++ != 'Z') {
- goto out;
- }
-
- /* massage TM to fulfill some of POSIX' constraints */
- tm.tm_year -= 1900;
- tm.tm_mon--;
-
- /* now convert our custom tm struct to a unix stamp using UTC */
- res = time_from_tm(&tm);
-
-out:
- if (endptr != NULL) {
- *endptr = deconst(s);
- }
- return res;
-}
-
-static unsigned int
-_warc_rdver(const char *buf, size_t bsz)
-{
- static const char magic[] = "WARC/";
- const char *c;
- unsigned int ver = 0U;
- unsigned int end = 0U;
-
- if (bsz < 12 || memcmp(buf, magic, sizeof(magic) - 1U) != 0) {
- /* buffer too small or invalid magic */
- return ver;
- }
- /* looks good so far, read the version number for a laugh */
- buf += sizeof(magic) - 1U;
-
- if (isdigit((unsigned char)buf[0U]) && (buf[1U] == '.') &&
- isdigit((unsigned char)buf[2U])) {
- /* we support a maximum of 2 digits in the minor version */
- if (isdigit((unsigned char)buf[3U]))
- end = 1U;
- /* set up major version */
- ver = (buf[0U] - '0') * 10000U;
- /* set up minor version */
- if (end == 1U) {
- ver += (buf[2U] - '0') * 1000U;
- ver += (buf[3U] - '0') * 100U;
- } else
- ver += (buf[2U] - '0') * 100U;
- /*
- * WARC below version 0.12 has a space-separated header
- * WARC 0.12 and above terminates the version with a CRLF
- */
- c = buf + 3U + end;
- if (ver >= 1200U) {
- if (memcmp(c, "\r\n", 2U) != 0)
- ver = 0U;
- } else {
- /* ver < 1200U */
- if (*c != ' ' && *c != '\t')
- ver = 0U;
- }
- }
- return ver;
-}
-
-static unsigned int
-_warc_rdtyp(const char *buf, size_t bsz)
-{
- static const char _key[] = "\r\nWARC-Type:";
- const char *val, *eol;
-
- if ((val = xmemmem(buf, bsz, _key, sizeof(_key) - 1U)) == NULL) {
- /* no bother */
- return WT_NONE;
- }
- val += sizeof(_key) - 1U;
- if ((eol = _warc_find_eol(val, buf + bsz - val)) == NULL) {
- /* no end of line */
- return WT_NONE;
- }
-
- /* overread whitespace */
- while (val < eol && (*val == ' ' || *val == '\t'))
- ++val;
-
- if (val + 8U == eol) {
- if (memcmp(val, "resource", 8U) == 0)
- return WT_RSRC;
- else if (memcmp(val, "response", 8U) == 0)
- return WT_RSP;
- }
- return WT_NONE;
-}
-
-static warc_string_t
-_warc_rduri(const char *buf, size_t bsz)
-{
- static const char _key[] = "\r\nWARC-Target-URI:";
- const char *val, *uri, *eol, *p;
- warc_string_t res = {0U, NULL};
-
- if ((val = xmemmem(buf, bsz, _key, sizeof(_key) - 1U)) == NULL) {
- /* no bother */
- return res;
- }
- /* overread whitespace */
- val += sizeof(_key) - 1U;
- if ((eol = _warc_find_eol(val, buf + bsz - val)) == NULL) {
- /* no end of line */
- return res;
- }
-
- while (val < eol && (*val == ' ' || *val == '\t'))
- ++val;
-
- /* overread URL designators */
- if ((uri = xmemmem(val, eol - val, "://", 3U)) == NULL) {
- /* not touching that! */
- return res;
- }
-
- /* spaces inside uri are not allowed, CRLF should follow */
- for (p = val; p < eol; p++) {
- if (isspace((unsigned char)*p))
- return res;
- }
-
- /* there must be at least space for ftp */
- if (uri < (val + 3U))
- return res;
-
- /* move uri to point to after :// */
- uri += 3U;
-
- /* now then, inspect the URI */
- if (memcmp(val, "file", 4U) == 0) {
- /* perfect, nothing left to do here */
-
- } else if (memcmp(val, "http", 4U) == 0 ||
- memcmp(val, "ftp", 3U) == 0) {
- /* overread domain, and the first / */
- while (uri < eol && *uri++ != '/');
- } else {
- /* not sure what to do? best to bugger off */
- return res;
- }
- res.str = uri;
- res.len = eol - uri;
- return res;
-}
-
-static ssize_t
-_warc_rdlen(const char *buf, size_t bsz)
-{
- static const char _key[] = "\r\nContent-Length:";
- const char *val, *eol;
- char *on = NULL;
- long int len;
-
- if ((val = xmemmem(buf, bsz, _key, sizeof(_key) - 1U)) == NULL) {
- /* no bother */
- return -1;
- }
- val += sizeof(_key) - 1U;
- if ((eol = _warc_find_eol(val, buf + bsz - val)) == NULL) {
- /* no end of line */
- return -1;
- }
-
- /* skip leading whitespace */
- while (val < eol && (*val == ' ' || *val == '\t'))
- val++;
- /* there must be at least one digit */
- if (!isdigit((unsigned char)*val))
- return -1;
- errno = 0;
- len = strtol(val, &on, 10);
- if (errno != 0 || on != eol) {
- /* line must end here */
- return -1;
- }
-
- return (size_t)len;
-}
-
-static time_t
-_warc_rdrtm(const char *buf, size_t bsz)
-{
- static const char _key[] = "\r\nWARC-Date:";
- const char *val, *eol;
- char *on = NULL;
- time_t res;
-
- if ((val = xmemmem(buf, bsz, _key, sizeof(_key) - 1U)) == NULL) {
- /* no bother */
- return (time_t)-1;
- }
- val += sizeof(_key) - 1U;
- if ((eol = _warc_find_eol(val, buf + bsz - val)) == NULL ) {
- /* no end of line */
- return -1;
- }
-
- /* xstrpisotime() kindly overreads whitespace for us, so use that */
- res = xstrpisotime(val, &on);
- if (on != eol) {
- /* line must end here */
- return -1;
- }
- return res;
-}
-
-static time_t
-_warc_rdmtm(const char *buf, size_t bsz)
-{
- static const char _key[] = "\r\nLast-Modified:";
- const char *val, *eol;
- char *on = NULL;
- time_t res;
-
- if ((val = xmemmem(buf, bsz, _key, sizeof(_key) - 1U)) == NULL) {
- /* no bother */
- return (time_t)-1;
- }
- val += sizeof(_key) - 1U;
- if ((eol = _warc_find_eol(val, buf + bsz - val)) == NULL ) {
- /* no end of line */
- return -1;
- }
-
- /* xstrpisotime() kindly overreads whitespace for us, so use that */
- res = xstrpisotime(val, &on);
- if (on != eol) {
- /* line must end here */
- return -1;
- }
- return res;
-}
-
-static const char*
-_warc_find_eoh(const char *buf, size_t bsz)
-{
- static const char _marker[] = "\r\n\r\n";
- const char *hit = xmemmem(buf, bsz, _marker, sizeof(_marker) - 1U);
-
- if (hit != NULL) {
- hit += sizeof(_marker) - 1U;
- }
- return hit;
-}
-
-static const char*
-_warc_find_eol(const char *buf, size_t bsz)
-{
- static const char _marker[] = "\r\n";
- const char *hit = xmemmem(buf, bsz, _marker, sizeof(_marker) - 1U);
-
- return hit;
-}
-/* archive_read_support_format_warc.c ends here */
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_format_xar.c b/contrib/libs/libarchive/libarchive/archive_read_support_format_xar.c
deleted file mode 100644
index 312a1db2d1..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_format_xar.c
+++ /dev/null
@@ -1,3332 +0,0 @@
-/*-
- * Copyright (c) 2009 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#if HAVE_LIBXML_XMLREADER_H
-#error #include <libxml/xmlreader.h>
-#elif HAVE_BSDXML_H
-#include <bsdxml.h>
-#elif HAVE_EXPAT_H
-#error #include <expat.h>
-#endif
-#ifdef HAVE_BZLIB_H
-#include <bzlib.h>
-#endif
-#if HAVE_LZMA_H
-#error #include <lzma.h>
-#endif
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-
-#include "archive.h"
-#include "archive_digest_private.h"
-#include "archive_endian.h"
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-#if (!defined(HAVE_LIBXML_XMLREADER_H) && \
- !defined(HAVE_BSDXML_H) && !defined(HAVE_EXPAT_H)) ||\
- !defined(HAVE_ZLIB_H) || \
- !defined(ARCHIVE_HAS_MD5) || !defined(ARCHIVE_HAS_SHA1)
-/*
- * xar needs several external libraries.
- * o libxml2 or expat --- XML parser
- * o openssl or MD5/SHA1 hash function
- * o zlib
- * o bzlib2 (option)
- * o liblzma (option)
- */
-int
-archive_read_support_format_xar(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- archive_check_magic(_a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_format_xar");
-
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Xar not supported on this platform");
- return (ARCHIVE_WARN);
-}
-
-#else /* Support xar format */
-
-/* #define DEBUG 1 */
-/* #define DEBUG_PRINT_TOC 1 */
-#if DEBUG_PRINT_TOC
-#define PRINT_TOC(d, outbytes) do { \
- unsigned char *x = (unsigned char *)(uintptr_t)d; \
- unsigned char c = x[outbytes-1]; \
- x[outbytes - 1] = 0; \
- fprintf(stderr, "%s", x); \
- fprintf(stderr, "%c", c); \
- x[outbytes - 1] = c; \
-} while (0)
-#else
-#define PRINT_TOC(d, outbytes)
-#endif
-
-#define HEADER_MAGIC 0x78617221
-#define HEADER_SIZE 28
-#define HEADER_VERSION 1
-#define CKSUM_NONE 0
-#define CKSUM_SHA1 1
-#define CKSUM_MD5 2
-
-#define MD5_SIZE 16
-#define SHA1_SIZE 20
-#define MAX_SUM_SIZE 20
-
-enum enctype {
- NONE,
- GZIP,
- BZIP2,
- LZMA,
- XZ,
-};
-
-struct chksumval {
- int alg;
- size_t len;
- unsigned char val[MAX_SUM_SIZE];
-};
-
-struct chksumwork {
- int alg;
-#ifdef ARCHIVE_HAS_MD5
- archive_md5_ctx md5ctx;
-#endif
-#ifdef ARCHIVE_HAS_SHA1
- archive_sha1_ctx sha1ctx;
-#endif
-};
-
-struct xattr {
- struct xattr *next;
- struct archive_string name;
- uint64_t id;
- uint64_t length;
- uint64_t offset;
- uint64_t size;
- enum enctype encoding;
- struct chksumval a_sum;
- struct chksumval e_sum;
- struct archive_string fstype;
-};
-
-struct xar_file {
- struct xar_file *next;
- struct xar_file *hdnext;
- struct xar_file *parent;
- int subdirs;
-
- unsigned int has;
-#define HAS_DATA 0x00001
-#define HAS_PATHNAME 0x00002
-#define HAS_SYMLINK 0x00004
-#define HAS_TIME 0x00008
-#define HAS_UID 0x00010
-#define HAS_GID 0x00020
-#define HAS_MODE 0x00040
-#define HAS_TYPE 0x00080
-#define HAS_DEV 0x00100
-#define HAS_DEVMAJOR 0x00200
-#define HAS_DEVMINOR 0x00400
-#define HAS_INO 0x00800
-#define HAS_FFLAGS 0x01000
-#define HAS_XATTR 0x02000
-#define HAS_ACL 0x04000
-#define HAS_CTIME 0x08000
-#define HAS_MTIME 0x10000
-#define HAS_ATIME 0x20000
-
- uint64_t id;
- uint64_t length;
- uint64_t offset;
- uint64_t size;
- enum enctype encoding;
- struct chksumval a_sum;
- struct chksumval e_sum;
- struct archive_string pathname;
- struct archive_string symlink;
- time_t ctime;
- time_t mtime;
- time_t atime;
- struct archive_string uname;
- int64_t uid;
- struct archive_string gname;
- int64_t gid;
- mode_t mode;
- dev_t dev;
- dev_t devmajor;
- dev_t devminor;
- int64_t ino64;
- struct archive_string fflags_text;
- unsigned int link;
- unsigned int nlink;
- struct archive_string hardlink;
- struct xattr *xattr_list;
-};
-
-struct hdlink {
- struct hdlink *next;
-
- unsigned int id;
- int cnt;
- struct xar_file *files;
-};
-
-struct heap_queue {
- struct xar_file **files;
- int allocated;
- int used;
-};
-
-enum xmlstatus {
- INIT,
- XAR,
- TOC,
- TOC_CREATION_TIME,
- TOC_CHECKSUM,
- TOC_CHECKSUM_OFFSET,
- TOC_CHECKSUM_SIZE,
- TOC_FILE,
- FILE_DATA,
- FILE_DATA_LENGTH,
- FILE_DATA_OFFSET,
- FILE_DATA_SIZE,
- FILE_DATA_ENCODING,
- FILE_DATA_A_CHECKSUM,
- FILE_DATA_E_CHECKSUM,
- FILE_DATA_CONTENT,
- FILE_EA,
- FILE_EA_LENGTH,
- FILE_EA_OFFSET,
- FILE_EA_SIZE,
- FILE_EA_ENCODING,
- FILE_EA_A_CHECKSUM,
- FILE_EA_E_CHECKSUM,
- FILE_EA_NAME,
- FILE_EA_FSTYPE,
- FILE_CTIME,
- FILE_MTIME,
- FILE_ATIME,
- FILE_GROUP,
- FILE_GID,
- FILE_USER,
- FILE_UID,
- FILE_MODE,
- FILE_DEVICE,
- FILE_DEVICE_MAJOR,
- FILE_DEVICE_MINOR,
- FILE_DEVICENO,
- FILE_INODE,
- FILE_LINK,
- FILE_TYPE,
- FILE_NAME,
- FILE_ACL,
- FILE_ACL_DEFAULT,
- FILE_ACL_ACCESS,
- FILE_ACL_APPLEEXTENDED,
- /* BSD file flags. */
- FILE_FLAGS,
- FILE_FLAGS_USER_NODUMP,
- FILE_FLAGS_USER_IMMUTABLE,
- FILE_FLAGS_USER_APPEND,
- FILE_FLAGS_USER_OPAQUE,
- FILE_FLAGS_USER_NOUNLINK,
- FILE_FLAGS_SYS_ARCHIVED,
- FILE_FLAGS_SYS_IMMUTABLE,
- FILE_FLAGS_SYS_APPEND,
- FILE_FLAGS_SYS_NOUNLINK,
- FILE_FLAGS_SYS_SNAPSHOT,
- /* Linux file flags. */
- FILE_EXT2,
- FILE_EXT2_SecureDeletion,
- FILE_EXT2_Undelete,
- FILE_EXT2_Compress,
- FILE_EXT2_Synchronous,
- FILE_EXT2_Immutable,
- FILE_EXT2_AppendOnly,
- FILE_EXT2_NoDump,
- FILE_EXT2_NoAtime,
- FILE_EXT2_CompDirty,
- FILE_EXT2_CompBlock,
- FILE_EXT2_NoCompBlock,
- FILE_EXT2_CompError,
- FILE_EXT2_BTree,
- FILE_EXT2_HashIndexed,
- FILE_EXT2_iMagic,
- FILE_EXT2_Journaled,
- FILE_EXT2_NoTail,
- FILE_EXT2_DirSync,
- FILE_EXT2_TopDir,
- FILE_EXT2_Reserved,
- UNKNOWN,
-};
-
-struct unknown_tag {
- struct unknown_tag *next;
- struct archive_string name;
-};
-
-struct xar {
- uint64_t offset; /* Current position in the file. */
- int64_t total;
- uint64_t h_base;
- int end_of_file;
-#define OUTBUFF_SIZE (1024 * 64)
- unsigned char *outbuff;
-
- enum xmlstatus xmlsts;
- enum xmlstatus xmlsts_unknown;
- struct unknown_tag *unknowntags;
- int base64text;
-
- /*
- * TOC
- */
- uint64_t toc_remaining;
- uint64_t toc_total;
- uint64_t toc_chksum_offset;
- uint64_t toc_chksum_size;
-
- /*
- * For Decoding data.
- */
- enum enctype rd_encoding;
- z_stream stream;
- int stream_valid;
-#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
- bz_stream bzstream;
- int bzstream_valid;
-#endif
-#if HAVE_LZMA_H && HAVE_LIBLZMA
- lzma_stream lzstream;
- int lzstream_valid;
-#endif
- /*
- * For Checksum data.
- */
- struct chksumwork a_sumwrk;
- struct chksumwork e_sumwrk;
-
- struct xar_file *file; /* current reading file. */
- struct xattr *xattr; /* current reading extended attribute. */
- struct heap_queue file_queue;
- struct xar_file *hdlink_orgs;
- struct hdlink *hdlink_list;
-
- int entry_init;
- uint64_t entry_total;
- uint64_t entry_remaining;
- size_t entry_unconsumed;
- uint64_t entry_size;
- enum enctype entry_encoding;
- struct chksumval entry_a_sum;
- struct chksumval entry_e_sum;
-
- struct archive_string_conv *sconv;
-};
-
-struct xmlattr {
- struct xmlattr *next;
- char *name;
- char *value;
-};
-
-struct xmlattr_list {
- struct xmlattr *first;
- struct xmlattr **last;
-};
-
-static int xar_bid(struct archive_read *, int);
-static int xar_read_header(struct archive_read *,
- struct archive_entry *);
-static int xar_read_data(struct archive_read *,
- const void **, size_t *, int64_t *);
-static int xar_read_data_skip(struct archive_read *);
-static int xar_cleanup(struct archive_read *);
-static int move_reading_point(struct archive_read *, uint64_t);
-static int rd_contents_init(struct archive_read *,
- enum enctype, int, int);
-static int rd_contents(struct archive_read *, const void **,
- size_t *, size_t *, uint64_t);
-static uint64_t atol10(const char *, size_t);
-static int64_t atol8(const char *, size_t);
-static size_t atohex(unsigned char *, size_t, const char *, size_t);
-static time_t parse_time(const char *p, size_t n);
-static int heap_add_entry(struct archive_read *a,
- struct heap_queue *, struct xar_file *);
-static struct xar_file *heap_get_entry(struct heap_queue *);
-static int add_link(struct archive_read *,
- struct xar *, struct xar_file *);
-static void checksum_init(struct archive_read *, int, int);
-static void checksum_update(struct archive_read *, const void *,
- size_t, const void *, size_t);
-static int checksum_final(struct archive_read *, const void *,
- size_t, const void *, size_t);
-static void checksum_cleanup(struct archive_read *);
-static int decompression_init(struct archive_read *, enum enctype);
-static int decompress(struct archive_read *, const void **,
- size_t *, const void *, size_t *);
-static int decompression_cleanup(struct archive_read *);
-static void xmlattr_cleanup(struct xmlattr_list *);
-static int file_new(struct archive_read *,
- struct xar *, struct xmlattr_list *);
-static void file_free(struct xar_file *);
-static int xattr_new(struct archive_read *,
- struct xar *, struct xmlattr_list *);
-static void xattr_free(struct xattr *);
-static int getencoding(struct xmlattr_list *);
-static int getsumalgorithm(struct xmlattr_list *);
-static int unknowntag_start(struct archive_read *,
- struct xar *, const char *);
-static void unknowntag_end(struct xar *, const char *);
-static int xml_start(struct archive_read *,
- const char *, struct xmlattr_list *);
-static void xml_end(void *, const char *);
-static void xml_data(void *, const char *, int);
-static int xml_parse_file_flags(struct xar *, const char *);
-static int xml_parse_file_ext2(struct xar *, const char *);
-#if defined(HAVE_LIBXML_XMLREADER_H)
-static int xml2_xmlattr_setup(struct archive_read *,
- struct xmlattr_list *, xmlTextReaderPtr);
-static int xml2_read_cb(void *, char *, int);
-static int xml2_close_cb(void *);
-static void xml2_error_hdr(void *, const char *, xmlParserSeverities,
- xmlTextReaderLocatorPtr);
-static int xml2_read_toc(struct archive_read *);
-#elif defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H)
-struct expat_userData {
- int state;
- struct archive_read *archive;
-};
-static int expat_xmlattr_setup(struct archive_read *,
- struct xmlattr_list *, const XML_Char **);
-static void expat_start_cb(void *, const XML_Char *, const XML_Char **);
-static void expat_end_cb(void *, const XML_Char *);
-static void expat_data_cb(void *, const XML_Char *, int);
-static int expat_read_toc(struct archive_read *);
-#endif
-
-int
-archive_read_support_format_xar(struct archive *_a)
-{
- struct xar *xar;
- struct archive_read *a = (struct archive_read *)_a;
- int r;
-
- archive_check_magic(_a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_format_xar");
-
- xar = (struct xar *)calloc(1, sizeof(*xar));
- if (xar == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate xar data");
- return (ARCHIVE_FATAL);
- }
-
- /* initialize xar->file_queue */
- xar->file_queue.allocated = 0;
- xar->file_queue.used = 0;
- xar->file_queue.files = NULL;
-
- r = __archive_read_register_format(a,
- xar,
- "xar",
- xar_bid,
- NULL,
- xar_read_header,
- xar_read_data,
- xar_read_data_skip,
- NULL,
- xar_cleanup,
- NULL,
- NULL);
- if (r != ARCHIVE_OK)
- free(xar);
- return (r);
-}
-
-static int
-xar_bid(struct archive_read *a, int best_bid)
-{
- const unsigned char *b;
- int bid;
-
- (void)best_bid; /* UNUSED */
-
- b = __archive_read_ahead(a, HEADER_SIZE, NULL);
- if (b == NULL)
- return (-1);
-
- bid = 0;
- /*
- * Verify magic code
- */
- if (archive_be32dec(b) != HEADER_MAGIC)
- return (0);
- bid += 32;
- /*
- * Verify header size
- */
- if (archive_be16dec(b+4) != HEADER_SIZE)
- return (0);
- bid += 16;
- /*
- * Verify header version
- */
- if (archive_be16dec(b+6) != HEADER_VERSION)
- return (0);
- bid += 16;
- /*
- * Verify type of checksum
- */
- switch (archive_be32dec(b+24)) {
- case CKSUM_NONE:
- case CKSUM_SHA1:
- case CKSUM_MD5:
- bid += 32;
- break;
- default:
- return (0);
- }
-
- return (bid);
-}
-
-static int
-read_toc(struct archive_read *a)
-{
- struct xar *xar;
- struct xar_file *file;
- const unsigned char *b;
- uint64_t toc_compressed_size;
- uint64_t toc_uncompressed_size;
- uint32_t toc_chksum_alg;
- ssize_t bytes;
- int r;
-
- xar = (struct xar *)(a->format->data);
-
- /*
- * Read xar header.
- */
- b = __archive_read_ahead(a, HEADER_SIZE, &bytes);
- if (bytes < 0)
- return ((int)bytes);
- if (bytes < HEADER_SIZE) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated archive header");
- return (ARCHIVE_FATAL);
- }
-
- if (archive_be32dec(b) != HEADER_MAGIC) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid header magic");
- return (ARCHIVE_FATAL);
- }
- if (archive_be16dec(b+6) != HEADER_VERSION) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Unsupported header version(%d)",
- archive_be16dec(b+6));
- return (ARCHIVE_FATAL);
- }
- toc_compressed_size = archive_be64dec(b+8);
- xar->toc_remaining = toc_compressed_size;
- toc_uncompressed_size = archive_be64dec(b+16);
- toc_chksum_alg = archive_be32dec(b+24);
- __archive_read_consume(a, HEADER_SIZE);
- xar->offset += HEADER_SIZE;
- xar->toc_total = 0;
-
- /*
- * Read TOC(Table of Contents).
- */
- /* Initialize reading contents. */
- r = move_reading_point(a, HEADER_SIZE);
- if (r != ARCHIVE_OK)
- return (r);
- r = rd_contents_init(a, GZIP, toc_chksum_alg, CKSUM_NONE);
- if (r != ARCHIVE_OK)
- return (r);
-
-#ifdef HAVE_LIBXML_XMLREADER_H
- r = xml2_read_toc(a);
-#elif defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H)
- r = expat_read_toc(a);
-#endif
- if (r != ARCHIVE_OK)
- return (r);
-
- /* Set 'The HEAP' base. */
- xar->h_base = xar->offset;
- if (xar->toc_total != toc_uncompressed_size) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "TOC uncompressed size error");
- return (ARCHIVE_FATAL);
- }
-
- /*
- * Checksum TOC
- */
- if (toc_chksum_alg != CKSUM_NONE) {
- r = move_reading_point(a, xar->toc_chksum_offset);
- if (r != ARCHIVE_OK)
- return (r);
- b = __archive_read_ahead(a,
- (size_t)xar->toc_chksum_size, &bytes);
- if (bytes < 0)
- return ((int)bytes);
- if ((uint64_t)bytes < xar->toc_chksum_size) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated archive file");
- return (ARCHIVE_FATAL);
- }
- r = checksum_final(a, b,
- (size_t)xar->toc_chksum_size, NULL, 0);
- __archive_read_consume(a, xar->toc_chksum_size);
- xar->offset += xar->toc_chksum_size;
- if (r != ARCHIVE_OK)
-#ifndef DONT_FAIL_ON_CRC_ERROR
- return (ARCHIVE_FATAL);
-#endif
- }
-
- /*
- * Connect hardlinked files.
- */
- for (file = xar->hdlink_orgs; file != NULL; file = file->hdnext) {
- struct hdlink **hdlink;
-
- for (hdlink = &(xar->hdlink_list); *hdlink != NULL;
- hdlink = &((*hdlink)->next)) {
- if ((*hdlink)->id == file->id) {
- struct hdlink *hltmp;
- struct xar_file *f2;
- int nlink = (*hdlink)->cnt + 1;
-
- file->nlink = nlink;
- for (f2 = (*hdlink)->files; f2 != NULL;
- f2 = f2->hdnext) {
- f2->nlink = nlink;
- archive_string_copy(
- &(f2->hardlink), &(file->pathname));
- }
- /* Remove resolved files from hdlist_list. */
- hltmp = *hdlink;
- *hdlink = hltmp->next;
- free(hltmp);
- break;
- }
- }
- }
- a->archive.archive_format = ARCHIVE_FORMAT_XAR;
- a->archive.archive_format_name = "xar";
-
- return (ARCHIVE_OK);
-}
-
-static int
-xar_read_header(struct archive_read *a, struct archive_entry *entry)
-{
- struct xar *xar;
- struct xar_file *file;
- struct xattr *xattr;
- int r;
-
- xar = (struct xar *)(a->format->data);
- r = ARCHIVE_OK;
-
- if (xar->offset == 0) {
- /* Create a character conversion object. */
- if (xar->sconv == NULL) {
- xar->sconv = archive_string_conversion_from_charset(
- &(a->archive), "UTF-8", 1);
- if (xar->sconv == NULL)
- return (ARCHIVE_FATAL);
- }
-
- /* Read TOC. */
- r = read_toc(a);
- if (r != ARCHIVE_OK)
- return (r);
- }
-
- for (;;) {
- file = xar->file = heap_get_entry(&(xar->file_queue));
- if (file == NULL) {
- xar->end_of_file = 1;
- return (ARCHIVE_EOF);
- }
- if ((file->mode & AE_IFMT) != AE_IFDIR)
- break;
- if (file->has != (HAS_PATHNAME | HAS_TYPE))
- break;
- /*
- * If a file type is a directory and it does not have
- * any metadata, do not export.
- */
- file_free(file);
- }
- if (file->has & HAS_ATIME) {
- archive_entry_set_atime(entry, file->atime, 0);
- }
- if (file->has & HAS_CTIME) {
- archive_entry_set_ctime(entry, file->ctime, 0);
- }
- if (file->has & HAS_MTIME) {
- archive_entry_set_mtime(entry, file->mtime, 0);
- }
- archive_entry_set_gid(entry, file->gid);
- if (file->gname.length > 0 &&
- archive_entry_copy_gname_l(entry, file->gname.s,
- archive_strlen(&(file->gname)), xar->sconv) != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Gname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Gname cannot be converted from %s to current locale.",
- archive_string_conversion_charset_name(xar->sconv));
- r = ARCHIVE_WARN;
- }
- archive_entry_set_uid(entry, file->uid);
- if (file->uname.length > 0 &&
- archive_entry_copy_uname_l(entry, file->uname.s,
- archive_strlen(&(file->uname)), xar->sconv) != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Uname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Uname cannot be converted from %s to current locale.",
- archive_string_conversion_charset_name(xar->sconv));
- r = ARCHIVE_WARN;
- }
- archive_entry_set_mode(entry, file->mode);
- if (archive_entry_copy_pathname_l(entry, file->pathname.s,
- archive_strlen(&(file->pathname)), xar->sconv) != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Pathname cannot be converted from %s to current locale.",
- archive_string_conversion_charset_name(xar->sconv));
- r = ARCHIVE_WARN;
- }
-
-
- if (file->symlink.length > 0 &&
- archive_entry_copy_symlink_l(entry, file->symlink.s,
- archive_strlen(&(file->symlink)), xar->sconv) != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Linkname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Linkname cannot be converted from %s to current locale.",
- archive_string_conversion_charset_name(xar->sconv));
- r = ARCHIVE_WARN;
- }
- /* Set proper nlink. */
- if ((file->mode & AE_IFMT) == AE_IFDIR)
- archive_entry_set_nlink(entry, file->subdirs + 2);
- else
- archive_entry_set_nlink(entry, file->nlink);
- archive_entry_set_size(entry, file->size);
- if (archive_strlen(&(file->hardlink)) > 0)
- archive_entry_set_hardlink(entry, file->hardlink.s);
- archive_entry_set_ino64(entry, file->ino64);
- if (file->has & HAS_DEV)
- archive_entry_set_dev(entry, file->dev);
- if (file->has & HAS_DEVMAJOR)
- archive_entry_set_devmajor(entry, file->devmajor);
- if (file->has & HAS_DEVMINOR)
- archive_entry_set_devminor(entry, file->devminor);
- if (archive_strlen(&(file->fflags_text)) > 0)
- archive_entry_copy_fflags_text(entry, file->fflags_text.s);
-
- xar->entry_init = 1;
- xar->entry_total = 0;
- xar->entry_remaining = file->length;
- xar->entry_size = file->size;
- xar->entry_encoding = file->encoding;
- xar->entry_a_sum = file->a_sum;
- xar->entry_e_sum = file->e_sum;
- /*
- * Read extended attributes.
- */
- xattr = file->xattr_list;
- while (xattr != NULL) {
- const void *d;
- size_t outbytes = 0;
- size_t used = 0;
-
- r = move_reading_point(a, xattr->offset);
- if (r != ARCHIVE_OK)
- break;
- r = rd_contents_init(a, xattr->encoding,
- xattr->a_sum.alg, xattr->e_sum.alg);
- if (r != ARCHIVE_OK)
- break;
- d = NULL;
- r = rd_contents(a, &d, &outbytes, &used, xattr->length);
- if (r != ARCHIVE_OK)
- break;
- if (outbytes != xattr->size) {
- archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
- "Decompressed size error");
- r = ARCHIVE_FATAL;
- break;
- }
- r = checksum_final(a,
- xattr->a_sum.val, xattr->a_sum.len,
- xattr->e_sum.val, xattr->e_sum.len);
- if (r != ARCHIVE_OK) {
-#ifndef DONT_FAIL_ON_CRC_ERROR
- archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
- "Xattr checksum error");
- r = ARCHIVE_WARN;
- break;
-#endif
- }
- if (xattr->name.s == NULL) {
- archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
- "Xattr name error");
- r = ARCHIVE_WARN;
- break;
- }
- archive_entry_xattr_add_entry(entry,
- xattr->name.s, d, outbytes);
- xattr = xattr->next;
- }
- if (r != ARCHIVE_OK) {
- file_free(file);
- return (r);
- }
-
- if (xar->entry_remaining > 0)
- /* Move reading point to the beginning of current
- * file contents. */
- r = move_reading_point(a, file->offset);
- else
- r = ARCHIVE_OK;
-
- file_free(file);
- return (r);
-}
-
-static int
-xar_read_data(struct archive_read *a,
- const void **buff, size_t *size, int64_t *offset)
-{
- struct xar *xar;
- size_t used = 0;
- int r;
-
- xar = (struct xar *)(a->format->data);
-
- if (xar->entry_unconsumed) {
- __archive_read_consume(a, xar->entry_unconsumed);
- xar->entry_unconsumed = 0;
- }
-
- if (xar->end_of_file || xar->entry_remaining <= 0) {
- r = ARCHIVE_EOF;
- goto abort_read_data;
- }
-
- if (xar->entry_init) {
- r = rd_contents_init(a, xar->entry_encoding,
- xar->entry_a_sum.alg, xar->entry_e_sum.alg);
- if (r != ARCHIVE_OK) {
- xar->entry_remaining = 0;
- return (r);
- }
- xar->entry_init = 0;
- }
-
- *buff = NULL;
- r = rd_contents(a, buff, size, &used, xar->entry_remaining);
- if (r != ARCHIVE_OK)
- goto abort_read_data;
-
- *offset = xar->entry_total;
- xar->entry_total += *size;
- xar->total += *size;
- xar->offset += used;
- xar->entry_remaining -= used;
- xar->entry_unconsumed = used;
-
- if (xar->entry_remaining == 0) {
- if (xar->entry_total != xar->entry_size) {
- archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
- "Decompressed size error");
- r = ARCHIVE_FATAL;
- goto abort_read_data;
- }
- r = checksum_final(a,
- xar->entry_a_sum.val, xar->entry_a_sum.len,
- xar->entry_e_sum.val, xar->entry_e_sum.len);
- if (r != ARCHIVE_OK)
- goto abort_read_data;
- }
-
- return (ARCHIVE_OK);
-abort_read_data:
- *buff = NULL;
- *size = 0;
- *offset = xar->total;
- return (r);
-}
-
-static int
-xar_read_data_skip(struct archive_read *a)
-{
- struct xar *xar;
- int64_t bytes_skipped;
-
- xar = (struct xar *)(a->format->data);
- if (xar->end_of_file)
- return (ARCHIVE_EOF);
- bytes_skipped = __archive_read_consume(a, xar->entry_remaining +
- xar->entry_unconsumed);
- if (bytes_skipped < 0)
- return (ARCHIVE_FATAL);
- xar->offset += bytes_skipped;
- xar->entry_unconsumed = 0;
- return (ARCHIVE_OK);
-}
-
-static int
-xar_cleanup(struct archive_read *a)
-{
- struct xar *xar;
- struct hdlink *hdlink;
- int i;
- int r;
-
- xar = (struct xar *)(a->format->data);
- checksum_cleanup(a);
- r = decompression_cleanup(a);
- hdlink = xar->hdlink_list;
- while (hdlink != NULL) {
- struct hdlink *next = hdlink->next;
-
- free(hdlink);
- hdlink = next;
- }
- for (i = 0; i < xar->file_queue.used; i++)
- file_free(xar->file_queue.files[i]);
- free(xar->file_queue.files);
- while (xar->unknowntags != NULL) {
- struct unknown_tag *tag;
-
- tag = xar->unknowntags;
- xar->unknowntags = tag->next;
- archive_string_free(&(tag->name));
- free(tag);
- }
- free(xar->outbuff);
- free(xar);
- a->format->data = NULL;
- return (r);
-}
-
-static int
-move_reading_point(struct archive_read *a, uint64_t offset)
-{
- struct xar *xar;
-
- xar = (struct xar *)(a->format->data);
- if (xar->offset - xar->h_base != offset) {
- /* Seek forward to the start of file contents. */
- int64_t step;
-
- step = offset - (xar->offset - xar->h_base);
- if (step > 0) {
- step = __archive_read_consume(a, step);
- if (step < 0)
- return ((int)step);
- xar->offset += step;
- } else {
- int64_t pos = __archive_read_seek(a, xar->h_base + offset, SEEK_SET);
- if (pos == ARCHIVE_FAILED) {
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "Cannot seek.");
- return (ARCHIVE_FAILED);
- }
- xar->offset = pos;
- }
- }
- return (ARCHIVE_OK);
-}
-
-static int
-rd_contents_init(struct archive_read *a, enum enctype encoding,
- int a_sum_alg, int e_sum_alg)
-{
- int r;
-
- /* Init decompress library. */
- if ((r = decompression_init(a, encoding)) != ARCHIVE_OK)
- return (r);
- /* Init checksum library. */
- checksum_init(a, a_sum_alg, e_sum_alg);
- return (ARCHIVE_OK);
-}
-
-static int
-rd_contents(struct archive_read *a, const void **buff, size_t *size,
- size_t *used, uint64_t remaining)
-{
- const unsigned char *b;
- ssize_t bytes;
-
- /* Get whatever bytes are immediately available. */
- b = __archive_read_ahead(a, 1, &bytes);
- if (bytes < 0)
- return ((int)bytes);
- if (bytes == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Truncated archive file");
- return (ARCHIVE_FATAL);
- }
- if ((uint64_t)bytes > remaining)
- bytes = (ssize_t)remaining;
-
- /*
- * Decompress contents of file.
- */
- *used = bytes;
- if (decompress(a, buff, size, b, used) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /*
- * Update checksum of a compressed data and a extracted data.
- */
- checksum_update(a, b, *used, *buff, *size);
-
- return (ARCHIVE_OK);
-}
-
-/*
- * Note that this implementation does not (and should not!) obey
- * locale settings; you cannot simply substitute strtol here, since
- * it does obey locale.
- */
-
-static uint64_t
-atol10(const char *p, size_t char_cnt)
-{
- uint64_t l;
- int digit;
-
- if (char_cnt == 0)
- return (0);
-
- l = 0;
- digit = *p - '0';
- while (digit >= 0 && digit < 10 && char_cnt-- > 0) {
- l = (l * 10) + digit;
- digit = *++p - '0';
- }
- return (l);
-}
-
-static int64_t
-atol8(const char *p, size_t char_cnt)
-{
- int64_t l;
- int digit;
-
- if (char_cnt == 0)
- return (0);
-
- l = 0;
- while (char_cnt-- > 0) {
- if (*p >= '0' && *p <= '7')
- digit = *p - '0';
- else
- break;
- p++;
- l <<= 3;
- l |= digit;
- }
- return (l);
-}
-
-static size_t
-atohex(unsigned char *b, size_t bsize, const char *p, size_t psize)
-{
- size_t fbsize = bsize;
-
- while (bsize && psize > 1) {
- unsigned char x;
-
- if (p[0] >= 'a' && p[0] <= 'z')
- x = (p[0] - 'a' + 0x0a) << 4;
- else if (p[0] >= 'A' && p[0] <= 'Z')
- x = (p[0] - 'A' + 0x0a) << 4;
- else if (p[0] >= '0' && p[0] <= '9')
- x = (p[0] - '0') << 4;
- else
- return (-1);
- if (p[1] >= 'a' && p[1] <= 'z')
- x |= p[1] - 'a' + 0x0a;
- else if (p[1] >= 'A' && p[1] <= 'Z')
- x |= p[1] - 'A' + 0x0a;
- else if (p[1] >= '0' && p[1] <= '9')
- x |= p[1] - '0';
- else
- return (-1);
-
- *b++ = x;
- bsize--;
- p += 2;
- psize -= 2;
- }
- return (fbsize - bsize);
-}
-
-static time_t
-time_from_tm(struct tm *t)
-{
-#if HAVE__MKGMTIME
- return _mkgmtime(t);
-#elif HAVE_TIMEGM
- /* Use platform timegm() if available. */
- return (timegm(t));
-#else
- /* Else use direct calculation using POSIX assumptions. */
- /* First, fix up tm_yday based on the year/month/day. */
- mktime(t);
- /* Then we can compute timegm() from first principles. */
- return (t->tm_sec
- + t->tm_min * 60
- + t->tm_hour * 3600
- + t->tm_yday * 86400
- + (t->tm_year - 70) * 31536000
- + ((t->tm_year - 69) / 4) * 86400
- - ((t->tm_year - 1) / 100) * 86400
- + ((t->tm_year + 299) / 400) * 86400);
-#endif
-}
-
-static time_t
-parse_time(const char *p, size_t n)
-{
- struct tm tm;
- time_t t = 0;
- int64_t data;
-
- memset(&tm, 0, sizeof(tm));
- if (n != 20)
- return (t);
- data = atol10(p, 4);
- if (data < 1900)
- return (t);
- tm.tm_year = (int)data - 1900;
- p += 4;
- if (*p++ != '-')
- return (t);
- data = atol10(p, 2);
- if (data < 1 || data > 12)
- return (t);
- tm.tm_mon = (int)data -1;
- p += 2;
- if (*p++ != '-')
- return (t);
- data = atol10(p, 2);
- if (data < 1 || data > 31)
- return (t);
- tm.tm_mday = (int)data;
- p += 2;
- if (*p++ != 'T')
- return (t);
- data = atol10(p, 2);
- if (data < 0 || data > 23)
- return (t);
- tm.tm_hour = (int)data;
- p += 2;
- if (*p++ != ':')
- return (t);
- data = atol10(p, 2);
- if (data < 0 || data > 59)
- return (t);
- tm.tm_min = (int)data;
- p += 2;
- if (*p++ != ':')
- return (t);
- data = atol10(p, 2);
- if (data < 0 || data > 60)
- return (t);
- tm.tm_sec = (int)data;
-#if 0
- p += 2;
- if (*p != 'Z')
- return (t);
-#endif
-
- t = time_from_tm(&tm);
-
- return (t);
-}
-
-static int
-heap_add_entry(struct archive_read *a,
- struct heap_queue *heap, struct xar_file *file)
-{
- uint64_t file_id, parent_id;
- int hole, parent;
-
- /* Expand our pending files list as necessary. */
- if (heap->used >= heap->allocated) {
- struct xar_file **new_pending_files;
- int new_size;
-
- if (heap->allocated < 1024)
- new_size = 1024;
- else
- new_size = heap->allocated * 2;
- /* Overflow might keep us from growing the list. */
- if (new_size <= heap->allocated) {
- archive_set_error(&a->archive,
- ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- new_pending_files = (struct xar_file **)
- malloc(new_size * sizeof(new_pending_files[0]));
- if (new_pending_files == NULL) {
- archive_set_error(&a->archive,
- ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- if (heap->allocated) {
- memcpy(new_pending_files, heap->files,
- heap->allocated * sizeof(new_pending_files[0]));
- free(heap->files);
- }
- heap->files = new_pending_files;
- heap->allocated = new_size;
- }
-
- file_id = file->id;
-
- /*
- * Start with hole at end, walk it up tree to find insertion point.
- */
- hole = heap->used++;
- while (hole > 0) {
- parent = (hole - 1)/2;
- parent_id = heap->files[parent]->id;
- if (file_id >= parent_id) {
- heap->files[hole] = file;
- return (ARCHIVE_OK);
- }
- /* Move parent into hole <==> move hole up tree. */
- heap->files[hole] = heap->files[parent];
- hole = parent;
- }
- heap->files[0] = file;
-
- return (ARCHIVE_OK);
-}
-
-static struct xar_file *
-heap_get_entry(struct heap_queue *heap)
-{
- uint64_t a_id, b_id, c_id;
- int a, b, c;
- struct xar_file *r, *tmp;
-
- if (heap->used < 1)
- return (NULL);
-
- /*
- * The first file in the list is the earliest; we'll return this.
- */
- r = heap->files[0];
-
- /*
- * Move the last item in the heap to the root of the tree
- */
- heap->files[0] = heap->files[--(heap->used)];
-
- /*
- * Rebalance the heap.
- */
- a = 0; /* Starting element and its heap key */
- a_id = heap->files[a]->id;
- for (;;) {
- b = a + a + 1; /* First child */
- if (b >= heap->used)
- return (r);
- b_id = heap->files[b]->id;
- c = b + 1; /* Use second child if it is smaller. */
- if (c < heap->used) {
- c_id = heap->files[c]->id;
- if (c_id < b_id) {
- b = c;
- b_id = c_id;
- }
- }
- if (a_id <= b_id)
- return (r);
- tmp = heap->files[a];
- heap->files[a] = heap->files[b];
- heap->files[b] = tmp;
- a = b;
- }
-}
-
-static int
-add_link(struct archive_read *a, struct xar *xar, struct xar_file *file)
-{
- struct hdlink *hdlink;
-
- for (hdlink = xar->hdlink_list; hdlink != NULL; hdlink = hdlink->next) {
- if (hdlink->id == file->link) {
- file->hdnext = hdlink->files;
- hdlink->cnt++;
- hdlink->files = file;
- return (ARCHIVE_OK);
- }
- }
- hdlink = malloc(sizeof(*hdlink));
- if (hdlink == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- file->hdnext = NULL;
- hdlink->id = file->link;
- hdlink->cnt = 1;
- hdlink->files = file;
- hdlink->next = xar->hdlink_list;
- xar->hdlink_list = hdlink;
- return (ARCHIVE_OK);
-}
-
-static void
-_checksum_init(struct chksumwork *sumwrk, int sum_alg)
-{
- sumwrk->alg = sum_alg;
- switch (sum_alg) {
- case CKSUM_NONE:
- break;
- case CKSUM_SHA1:
- archive_sha1_init(&(sumwrk->sha1ctx));
- break;
- case CKSUM_MD5:
- archive_md5_init(&(sumwrk->md5ctx));
- break;
- }
-}
-
-static void
-_checksum_update(struct chksumwork *sumwrk, const void *buff, size_t size)
-{
-
- switch (sumwrk->alg) {
- case CKSUM_NONE:
- break;
- case CKSUM_SHA1:
- archive_sha1_update(&(sumwrk->sha1ctx), buff, size);
- break;
- case CKSUM_MD5:
- archive_md5_update(&(sumwrk->md5ctx), buff, size);
- break;
- }
-}
-
-static int
-_checksum_final(struct chksumwork *sumwrk, const void *val, size_t len)
-{
- unsigned char sum[MAX_SUM_SIZE];
- int r = ARCHIVE_OK;
-
- switch (sumwrk->alg) {
- case CKSUM_NONE:
- break;
- case CKSUM_SHA1:
- archive_sha1_final(&(sumwrk->sha1ctx), sum);
- if (len != SHA1_SIZE ||
- memcmp(val, sum, SHA1_SIZE) != 0)
- r = ARCHIVE_FAILED;
- break;
- case CKSUM_MD5:
- archive_md5_final(&(sumwrk->md5ctx), sum);
- if (len != MD5_SIZE ||
- memcmp(val, sum, MD5_SIZE) != 0)
- r = ARCHIVE_FAILED;
- break;
- }
- return (r);
-}
-
-static void
-checksum_init(struct archive_read *a, int a_sum_alg, int e_sum_alg)
-{
- struct xar *xar;
-
- xar = (struct xar *)(a->format->data);
- _checksum_init(&(xar->a_sumwrk), a_sum_alg);
- _checksum_init(&(xar->e_sumwrk), e_sum_alg);
-}
-
-static void
-checksum_update(struct archive_read *a, const void *abuff, size_t asize,
- const void *ebuff, size_t esize)
-{
- struct xar *xar;
-
- xar = (struct xar *)(a->format->data);
- _checksum_update(&(xar->a_sumwrk), abuff, asize);
- _checksum_update(&(xar->e_sumwrk), ebuff, esize);
-}
-
-static int
-checksum_final(struct archive_read *a, const void *a_sum_val,
- size_t a_sum_len, const void *e_sum_val, size_t e_sum_len)
-{
- struct xar *xar;
- int r;
-
- xar = (struct xar *)(a->format->data);
- r = _checksum_final(&(xar->a_sumwrk), a_sum_val, a_sum_len);
- if (r == ARCHIVE_OK)
- r = _checksum_final(&(xar->e_sumwrk), e_sum_val, e_sum_len);
- if (r != ARCHIVE_OK)
- archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
- "Sumcheck error");
- return (r);
-}
-
-static int
-decompression_init(struct archive_read *a, enum enctype encoding)
-{
- struct xar *xar;
- const char *detail;
- int r;
-
- xar = (struct xar *)(a->format->data);
- xar->rd_encoding = encoding;
- switch (encoding) {
- case NONE:
- break;
- case GZIP:
- if (xar->stream_valid)
- r = inflateReset(&(xar->stream));
- else
- r = inflateInit(&(xar->stream));
- if (r != Z_OK) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Couldn't initialize zlib stream.");
- return (ARCHIVE_FATAL);
- }
- xar->stream_valid = 1;
- xar->stream.total_in = 0;
- xar->stream.total_out = 0;
- break;
-#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
- case BZIP2:
- if (xar->bzstream_valid) {
- BZ2_bzDecompressEnd(&(xar->bzstream));
- xar->bzstream_valid = 0;
- }
- r = BZ2_bzDecompressInit(&(xar->bzstream), 0, 0);
- if (r == BZ_MEM_ERROR)
- r = BZ2_bzDecompressInit(&(xar->bzstream), 0, 1);
- if (r != BZ_OK) {
- int err = ARCHIVE_ERRNO_MISC;
- detail = NULL;
- switch (r) {
- case BZ_PARAM_ERROR:
- detail = "invalid setup parameter";
- break;
- case BZ_MEM_ERROR:
- err = ENOMEM;
- detail = "out of memory";
- break;
- case BZ_CONFIG_ERROR:
- detail = "mis-compiled library";
- break;
- }
- archive_set_error(&a->archive, err,
- "Internal error initializing decompressor: %s",
- detail == NULL ? "??" : detail);
- xar->bzstream_valid = 0;
- return (ARCHIVE_FATAL);
- }
- xar->bzstream_valid = 1;
- xar->bzstream.total_in_lo32 = 0;
- xar->bzstream.total_in_hi32 = 0;
- xar->bzstream.total_out_lo32 = 0;
- xar->bzstream.total_out_hi32 = 0;
- break;
-#endif
-#if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
-#if LZMA_VERSION_MAJOR >= 5
-/* Effectively disable the limiter. */
-#define LZMA_MEMLIMIT UINT64_MAX
-#else
-/* NOTE: This needs to check memory size which running system has. */
-#define LZMA_MEMLIMIT (1U << 30)
-#endif
- case XZ:
- case LZMA:
- if (xar->lzstream_valid) {
- lzma_end(&(xar->lzstream));
- xar->lzstream_valid = 0;
- }
- if (xar->entry_encoding == XZ)
- r = lzma_stream_decoder(&(xar->lzstream),
- LZMA_MEMLIMIT,/* memlimit */
- LZMA_CONCATENATED);
- else
- r = lzma_alone_decoder(&(xar->lzstream),
- LZMA_MEMLIMIT);/* memlimit */
- if (r != LZMA_OK) {
- switch (r) {
- case LZMA_MEM_ERROR:
- archive_set_error(&a->archive,
- ENOMEM,
- "Internal error initializing "
- "compression library: "
- "Cannot allocate memory");
- break;
- case LZMA_OPTIONS_ERROR:
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Internal error initializing "
- "compression library: "
- "Invalid or unsupported options");
- break;
- default:
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Internal error initializing "
- "lzma library");
- break;
- }
- return (ARCHIVE_FATAL);
- }
- xar->lzstream_valid = 1;
- xar->lzstream.total_in = 0;
- xar->lzstream.total_out = 0;
- break;
-#endif
- /*
- * Unsupported compression.
- */
- default:
-#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR)
- case BZIP2:
-#endif
-#if !defined(HAVE_LZMA_H) || !defined(HAVE_LIBLZMA)
- case LZMA:
- case XZ:
-#endif
- switch (xar->entry_encoding) {
- case BZIP2: detail = "bzip2"; break;
- case LZMA: detail = "lzma"; break;
- case XZ: detail = "xz"; break;
- default: detail = "??"; break;
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "%s compression not supported on this platform",
- detail);
- return (ARCHIVE_FAILED);
- }
- return (ARCHIVE_OK);
-}
-
-static int
-decompress(struct archive_read *a, const void **buff, size_t *outbytes,
- const void *b, size_t *used)
-{
- struct xar *xar;
- void *outbuff;
- size_t avail_in, avail_out;
- int r;
-
- xar = (struct xar *)(a->format->data);
- avail_in = *used;
- outbuff = (void *)(uintptr_t)*buff;
- if (outbuff == NULL) {
- if (xar->outbuff == NULL) {
- xar->outbuff = malloc(OUTBUFF_SIZE);
- if (xar->outbuff == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Couldn't allocate memory for out buffer");
- return (ARCHIVE_FATAL);
- }
- }
- outbuff = xar->outbuff;
- *buff = outbuff;
- avail_out = OUTBUFF_SIZE;
- } else
- avail_out = *outbytes;
- switch (xar->rd_encoding) {
- case GZIP:
- xar->stream.next_in = (Bytef *)(uintptr_t)b;
- xar->stream.avail_in = avail_in;
- xar->stream.next_out = (unsigned char *)outbuff;
- xar->stream.avail_out = avail_out;
- r = inflate(&(xar->stream), 0);
- switch (r) {
- case Z_OK: /* Decompressor made some progress.*/
- case Z_STREAM_END: /* Found end of stream. */
- break;
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "File decompression failed (%d)", r);
- return (ARCHIVE_FATAL);
- }
- *used = avail_in - xar->stream.avail_in;
- *outbytes = avail_out - xar->stream.avail_out;
- break;
-#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
- case BZIP2:
- xar->bzstream.next_in = (char *)(uintptr_t)b;
- xar->bzstream.avail_in = avail_in;
- xar->bzstream.next_out = (char *)outbuff;
- xar->bzstream.avail_out = avail_out;
- r = BZ2_bzDecompress(&(xar->bzstream));
- switch (r) {
- case BZ_STREAM_END: /* Found end of stream. */
- switch (BZ2_bzDecompressEnd(&(xar->bzstream))) {
- case BZ_OK:
- break;
- default:
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "Failed to clean up decompressor");
- return (ARCHIVE_FATAL);
- }
- xar->bzstream_valid = 0;
- /* FALLTHROUGH */
- case BZ_OK: /* Decompressor made some progress. */
- break;
- default:
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "bzip decompression failed");
- return (ARCHIVE_FATAL);
- }
- *used = avail_in - xar->bzstream.avail_in;
- *outbytes = avail_out - xar->bzstream.avail_out;
- break;
-#endif
-#if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
- case LZMA:
- case XZ:
- xar->lzstream.next_in = b;
- xar->lzstream.avail_in = avail_in;
- xar->lzstream.next_out = (unsigned char *)outbuff;
- xar->lzstream.avail_out = avail_out;
- r = lzma_code(&(xar->lzstream), LZMA_RUN);
- switch (r) {
- case LZMA_STREAM_END: /* Found end of stream. */
- lzma_end(&(xar->lzstream));
- xar->lzstream_valid = 0;
- /* FALLTHROUGH */
- case LZMA_OK: /* Decompressor made some progress. */
- break;
- default:
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "%s decompression failed(%d)",
- (xar->entry_encoding == XZ)?"xz":"lzma",
- r);
- return (ARCHIVE_FATAL);
- }
- *used = avail_in - xar->lzstream.avail_in;
- *outbytes = avail_out - xar->lzstream.avail_out;
- break;
-#endif
-#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR)
- case BZIP2:
-#endif
-#if !defined(HAVE_LZMA_H) || !defined(HAVE_LIBLZMA)
- case LZMA:
- case XZ:
-#endif
- case NONE:
- default:
- if (outbuff == xar->outbuff) {
- *buff = b;
- *used = avail_in;
- *outbytes = avail_in;
- } else {
- if (avail_out > avail_in)
- avail_out = avail_in;
- memcpy(outbuff, b, avail_out);
- *used = avail_out;
- *outbytes = avail_out;
- }
- break;
- }
- return (ARCHIVE_OK);
-}
-
-static int
-decompression_cleanup(struct archive_read *a)
-{
- struct xar *xar;
- int r;
-
- xar = (struct xar *)(a->format->data);
- r = ARCHIVE_OK;
- if (xar->stream_valid) {
- if (inflateEnd(&(xar->stream)) != Z_OK) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Failed to clean up zlib decompressor");
- r = ARCHIVE_FATAL;
- }
- }
-#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
- if (xar->bzstream_valid) {
- if (BZ2_bzDecompressEnd(&(xar->bzstream)) != BZ_OK) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Failed to clean up bzip2 decompressor");
- r = ARCHIVE_FATAL;
- }
- }
-#endif
-#if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
- if (xar->lzstream_valid)
- lzma_end(&(xar->lzstream));
-#elif defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
- if (xar->lzstream_valid) {
- if (lzmadec_end(&(xar->lzstream)) != LZMADEC_OK) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Failed to clean up lzmadec decompressor");
- r = ARCHIVE_FATAL;
- }
- }
-#endif
- return (r);
-}
-
-static void
-checksum_cleanup(struct archive_read *a) {
- struct xar *xar;
-
- xar = (struct xar *)(a->format->data);
-
- _checksum_final(&(xar->a_sumwrk), NULL, 0);
- _checksum_final(&(xar->e_sumwrk), NULL, 0);
-}
-
-static void
-xmlattr_cleanup(struct xmlattr_list *list)
-{
- struct xmlattr *attr, *next;
-
- attr = list->first;
- while (attr != NULL) {
- next = attr->next;
- free(attr->name);
- free(attr->value);
- free(attr);
- attr = next;
- }
- list->first = NULL;
- list->last = &(list->first);
-}
-
-static int
-file_new(struct archive_read *a, struct xar *xar, struct xmlattr_list *list)
-{
- struct xar_file *file;
- struct xmlattr *attr;
-
- file = calloc(1, sizeof(*file));
- if (file == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- file->parent = xar->file;
- file->mode = 0777 | AE_IFREG;
- file->atime = 0;
- file->mtime = 0;
- xar->file = file;
- xar->xattr = NULL;
- for (attr = list->first; attr != NULL; attr = attr->next) {
- if (strcmp(attr->name, "id") == 0)
- file->id = atol10(attr->value, strlen(attr->value));
- }
- file->nlink = 1;
- if (heap_add_entry(a, &(xar->file_queue), file) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- return (ARCHIVE_OK);
-}
-
-static void
-file_free(struct xar_file *file)
-{
- struct xattr *xattr;
-
- archive_string_free(&(file->pathname));
- archive_string_free(&(file->symlink));
- archive_string_free(&(file->uname));
- archive_string_free(&(file->gname));
- archive_string_free(&(file->hardlink));
- xattr = file->xattr_list;
- while (xattr != NULL) {
- struct xattr *next;
-
- next = xattr->next;
- xattr_free(xattr);
- xattr = next;
- }
-
- free(file);
-}
-
-static int
-xattr_new(struct archive_read *a, struct xar *xar, struct xmlattr_list *list)
-{
- struct xattr *xattr, **nx;
- struct xmlattr *attr;
-
- xattr = calloc(1, sizeof(*xattr));
- if (xattr == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- xar->xattr = xattr;
- for (attr = list->first; attr != NULL; attr = attr->next) {
- if (strcmp(attr->name, "id") == 0)
- xattr->id = atol10(attr->value, strlen(attr->value));
- }
- /* Chain to xattr list. */
- for (nx = &(xar->file->xattr_list);
- *nx != NULL; nx = &((*nx)->next)) {
- if (xattr->id < (*nx)->id)
- break;
- }
- xattr->next = *nx;
- *nx = xattr;
-
- return (ARCHIVE_OK);
-}
-
-static void
-xattr_free(struct xattr *xattr)
-{
- archive_string_free(&(xattr->name));
- free(xattr);
-}
-
-static int
-getencoding(struct xmlattr_list *list)
-{
- struct xmlattr *attr;
- enum enctype encoding = NONE;
-
- for (attr = list->first; attr != NULL; attr = attr->next) {
- if (strcmp(attr->name, "style") == 0) {
- if (strcmp(attr->value, "application/octet-stream") == 0)
- encoding = NONE;
- else if (strcmp(attr->value, "application/x-gzip") == 0)
- encoding = GZIP;
- else if (strcmp(attr->value, "application/x-bzip2") == 0)
- encoding = BZIP2;
- else if (strcmp(attr->value, "application/x-lzma") == 0)
- encoding = LZMA;
- else if (strcmp(attr->value, "application/x-xz") == 0)
- encoding = XZ;
- }
- }
- return (encoding);
-}
-
-static int
-getsumalgorithm(struct xmlattr_list *list)
-{
- struct xmlattr *attr;
- int alg = CKSUM_NONE;
-
- for (attr = list->first; attr != NULL; attr = attr->next) {
- if (strcmp(attr->name, "style") == 0) {
- const char *v = attr->value;
- if ((v[0] == 'S' || v[0] == 's') &&
- (v[1] == 'H' || v[1] == 'h') &&
- (v[2] == 'A' || v[2] == 'a') &&
- v[3] == '1' && v[4] == '\0')
- alg = CKSUM_SHA1;
- if ((v[0] == 'M' || v[0] == 'm') &&
- (v[1] == 'D' || v[1] == 'd') &&
- v[2] == '5' && v[3] == '\0')
- alg = CKSUM_MD5;
- }
- }
- return (alg);
-}
-
-static int
-unknowntag_start(struct archive_read *a, struct xar *xar, const char *name)
-{
- struct unknown_tag *tag;
-
- tag = malloc(sizeof(*tag));
- if (tag == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- tag->next = xar->unknowntags;
- archive_string_init(&(tag->name));
- archive_strcpy(&(tag->name), name);
- if (xar->unknowntags == NULL) {
-#if DEBUG
- fprintf(stderr, "UNKNOWNTAG_START:%s\n", name);
-#endif
- xar->xmlsts_unknown = xar->xmlsts;
- xar->xmlsts = UNKNOWN;
- }
- xar->unknowntags = tag;
- return (ARCHIVE_OK);
-}
-
-static void
-unknowntag_end(struct xar *xar, const char *name)
-{
- struct unknown_tag *tag;
-
- tag = xar->unknowntags;
- if (tag == NULL || name == NULL)
- return;
- if (strcmp(tag->name.s, name) == 0) {
- xar->unknowntags = tag->next;
- archive_string_free(&(tag->name));
- free(tag);
- if (xar->unknowntags == NULL) {
-#if DEBUG
- fprintf(stderr, "UNKNOWNTAG_END:%s\n", name);
-#endif
- xar->xmlsts = xar->xmlsts_unknown;
- }
- }
-}
-
-static int
-xml_start(struct archive_read *a, const char *name, struct xmlattr_list *list)
-{
- struct xar *xar;
- struct xmlattr *attr;
-
- xar = (struct xar *)(a->format->data);
-
-#if DEBUG
- fprintf(stderr, "xml_sta:[%s]\n", name);
- for (attr = list->first; attr != NULL; attr = attr->next)
- fprintf(stderr, " attr:\"%s\"=\"%s\"\n",
- attr->name, attr->value);
-#endif
- xar->base64text = 0;
- switch (xar->xmlsts) {
- case INIT:
- if (strcmp(name, "xar") == 0)
- xar->xmlsts = XAR;
- else
- if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- break;
- case XAR:
- if (strcmp(name, "toc") == 0)
- xar->xmlsts = TOC;
- else
- if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- break;
- case TOC:
- if (strcmp(name, "creation-time") == 0)
- xar->xmlsts = TOC_CREATION_TIME;
- else if (strcmp(name, "checksum") == 0)
- xar->xmlsts = TOC_CHECKSUM;
- else if (strcmp(name, "file") == 0) {
- if (file_new(a, xar, list) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- xar->xmlsts = TOC_FILE;
- }
- else
- if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- break;
- case TOC_CHECKSUM:
- if (strcmp(name, "offset") == 0)
- xar->xmlsts = TOC_CHECKSUM_OFFSET;
- else if (strcmp(name, "size") == 0)
- xar->xmlsts = TOC_CHECKSUM_SIZE;
- else
- if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- break;
- case TOC_FILE:
- if (strcmp(name, "file") == 0) {
- if (file_new(a, xar, list) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- }
- else if (strcmp(name, "data") == 0)
- xar->xmlsts = FILE_DATA;
- else if (strcmp(name, "ea") == 0) {
- if (xattr_new(a, xar, list) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- xar->xmlsts = FILE_EA;
- }
- else if (strcmp(name, "ctime") == 0)
- xar->xmlsts = FILE_CTIME;
- else if (strcmp(name, "mtime") == 0)
- xar->xmlsts = FILE_MTIME;
- else if (strcmp(name, "atime") == 0)
- xar->xmlsts = FILE_ATIME;
- else if (strcmp(name, "group") == 0)
- xar->xmlsts = FILE_GROUP;
- else if (strcmp(name, "gid") == 0)
- xar->xmlsts = FILE_GID;
- else if (strcmp(name, "user") == 0)
- xar->xmlsts = FILE_USER;
- else if (strcmp(name, "uid") == 0)
- xar->xmlsts = FILE_UID;
- else if (strcmp(name, "mode") == 0)
- xar->xmlsts = FILE_MODE;
- else if (strcmp(name, "device") == 0)
- xar->xmlsts = FILE_DEVICE;
- else if (strcmp(name, "deviceno") == 0)
- xar->xmlsts = FILE_DEVICENO;
- else if (strcmp(name, "inode") == 0)
- xar->xmlsts = FILE_INODE;
- else if (strcmp(name, "link") == 0)
- xar->xmlsts = FILE_LINK;
- else if (strcmp(name, "type") == 0) {
- xar->xmlsts = FILE_TYPE;
- for (attr = list->first; attr != NULL;
- attr = attr->next) {
- if (strcmp(attr->name, "link") != 0)
- continue;
- if (strcmp(attr->value, "original") == 0) {
- xar->file->hdnext = xar->hdlink_orgs;
- xar->hdlink_orgs = xar->file;
- } else {
- xar->file->link = (unsigned)atol10(attr->value,
- strlen(attr->value));
- if (xar->file->link > 0)
- if (add_link(a, xar, xar->file) != ARCHIVE_OK) {
- return (ARCHIVE_FATAL);
- };
- }
- }
- }
- else if (strcmp(name, "name") == 0) {
- xar->xmlsts = FILE_NAME;
- for (attr = list->first; attr != NULL;
- attr = attr->next) {
- if (strcmp(attr->name, "enctype") == 0 &&
- strcmp(attr->value, "base64") == 0)
- xar->base64text = 1;
- }
- }
- else if (strcmp(name, "acl") == 0)
- xar->xmlsts = FILE_ACL;
- else if (strcmp(name, "flags") == 0)
- xar->xmlsts = FILE_FLAGS;
- else if (strcmp(name, "ext2") == 0)
- xar->xmlsts = FILE_EXT2;
- else
- if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- break;
- case FILE_DATA:
- if (strcmp(name, "length") == 0)
- xar->xmlsts = FILE_DATA_LENGTH;
- else if (strcmp(name, "offset") == 0)
- xar->xmlsts = FILE_DATA_OFFSET;
- else if (strcmp(name, "size") == 0)
- xar->xmlsts = FILE_DATA_SIZE;
- else if (strcmp(name, "encoding") == 0) {
- xar->xmlsts = FILE_DATA_ENCODING;
- xar->file->encoding = getencoding(list);
- }
- else if (strcmp(name, "archived-checksum") == 0) {
- xar->xmlsts = FILE_DATA_A_CHECKSUM;
- xar->file->a_sum.alg = getsumalgorithm(list);
- }
- else if (strcmp(name, "extracted-checksum") == 0) {
- xar->xmlsts = FILE_DATA_E_CHECKSUM;
- xar->file->e_sum.alg = getsumalgorithm(list);
- }
- else if (strcmp(name, "content") == 0)
- xar->xmlsts = FILE_DATA_CONTENT;
- else
- if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- break;
- case FILE_DEVICE:
- if (strcmp(name, "major") == 0)
- xar->xmlsts = FILE_DEVICE_MAJOR;
- else if (strcmp(name, "minor") == 0)
- xar->xmlsts = FILE_DEVICE_MINOR;
- else
- if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- break;
- case FILE_DATA_CONTENT:
- if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- break;
- case FILE_EA:
- if (strcmp(name, "length") == 0)
- xar->xmlsts = FILE_EA_LENGTH;
- else if (strcmp(name, "offset") == 0)
- xar->xmlsts = FILE_EA_OFFSET;
- else if (strcmp(name, "size") == 0)
- xar->xmlsts = FILE_EA_SIZE;
- else if (strcmp(name, "encoding") == 0) {
- xar->xmlsts = FILE_EA_ENCODING;
- xar->xattr->encoding = getencoding(list);
- } else if (strcmp(name, "archived-checksum") == 0)
- xar->xmlsts = FILE_EA_A_CHECKSUM;
- else if (strcmp(name, "extracted-checksum") == 0)
- xar->xmlsts = FILE_EA_E_CHECKSUM;
- else if (strcmp(name, "name") == 0)
- xar->xmlsts = FILE_EA_NAME;
- else if (strcmp(name, "fstype") == 0)
- xar->xmlsts = FILE_EA_FSTYPE;
- else
- if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- break;
- case FILE_ACL:
- if (strcmp(name, "appleextended") == 0)
- xar->xmlsts = FILE_ACL_APPLEEXTENDED;
- else if (strcmp(name, "default") == 0)
- xar->xmlsts = FILE_ACL_DEFAULT;
- else if (strcmp(name, "access") == 0)
- xar->xmlsts = FILE_ACL_ACCESS;
- else
- if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- break;
- case FILE_FLAGS:
- if (!xml_parse_file_flags(xar, name))
- if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- break;
- case FILE_EXT2:
- if (!xml_parse_file_ext2(xar, name))
- if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- break;
- case TOC_CREATION_TIME:
- case TOC_CHECKSUM_OFFSET:
- case TOC_CHECKSUM_SIZE:
- case FILE_DATA_LENGTH:
- case FILE_DATA_OFFSET:
- case FILE_DATA_SIZE:
- case FILE_DATA_ENCODING:
- case FILE_DATA_A_CHECKSUM:
- case FILE_DATA_E_CHECKSUM:
- case FILE_EA_LENGTH:
- case FILE_EA_OFFSET:
- case FILE_EA_SIZE:
- case FILE_EA_ENCODING:
- case FILE_EA_A_CHECKSUM:
- case FILE_EA_E_CHECKSUM:
- case FILE_EA_NAME:
- case FILE_EA_FSTYPE:
- case FILE_CTIME:
- case FILE_MTIME:
- case FILE_ATIME:
- case FILE_GROUP:
- case FILE_GID:
- case FILE_USER:
- case FILE_UID:
- case FILE_INODE:
- case FILE_DEVICE_MAJOR:
- case FILE_DEVICE_MINOR:
- case FILE_DEVICENO:
- case FILE_MODE:
- case FILE_TYPE:
- case FILE_LINK:
- case FILE_NAME:
- case FILE_ACL_DEFAULT:
- case FILE_ACL_ACCESS:
- case FILE_ACL_APPLEEXTENDED:
- case FILE_FLAGS_USER_NODUMP:
- case FILE_FLAGS_USER_IMMUTABLE:
- case FILE_FLAGS_USER_APPEND:
- case FILE_FLAGS_USER_OPAQUE:
- case FILE_FLAGS_USER_NOUNLINK:
- case FILE_FLAGS_SYS_ARCHIVED:
- case FILE_FLAGS_SYS_IMMUTABLE:
- case FILE_FLAGS_SYS_APPEND:
- case FILE_FLAGS_SYS_NOUNLINK:
- case FILE_FLAGS_SYS_SNAPSHOT:
- case FILE_EXT2_SecureDeletion:
- case FILE_EXT2_Undelete:
- case FILE_EXT2_Compress:
- case FILE_EXT2_Synchronous:
- case FILE_EXT2_Immutable:
- case FILE_EXT2_AppendOnly:
- case FILE_EXT2_NoDump:
- case FILE_EXT2_NoAtime:
- case FILE_EXT2_CompDirty:
- case FILE_EXT2_CompBlock:
- case FILE_EXT2_NoCompBlock:
- case FILE_EXT2_CompError:
- case FILE_EXT2_BTree:
- case FILE_EXT2_HashIndexed:
- case FILE_EXT2_iMagic:
- case FILE_EXT2_Journaled:
- case FILE_EXT2_NoTail:
- case FILE_EXT2_DirSync:
- case FILE_EXT2_TopDir:
- case FILE_EXT2_Reserved:
- case UNKNOWN:
- if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- break;
- }
- return (ARCHIVE_OK);
-}
-
-static void
-xml_end(void *userData, const char *name)
-{
- struct archive_read *a;
- struct xar *xar;
-
- a = (struct archive_read *)userData;
- xar = (struct xar *)(a->format->data);
-
-#if DEBUG
- fprintf(stderr, "xml_end:[%s]\n", name);
-#endif
- switch (xar->xmlsts) {
- case INIT:
- break;
- case XAR:
- if (strcmp(name, "xar") == 0)
- xar->xmlsts = INIT;
- break;
- case TOC:
- if (strcmp(name, "toc") == 0)
- xar->xmlsts = XAR;
- break;
- case TOC_CREATION_TIME:
- if (strcmp(name, "creation-time") == 0)
- xar->xmlsts = TOC;
- break;
- case TOC_CHECKSUM:
- if (strcmp(name, "checksum") == 0)
- xar->xmlsts = TOC;
- break;
- case TOC_CHECKSUM_OFFSET:
- if (strcmp(name, "offset") == 0)
- xar->xmlsts = TOC_CHECKSUM;
- break;
- case TOC_CHECKSUM_SIZE:
- if (strcmp(name, "size") == 0)
- xar->xmlsts = TOC_CHECKSUM;
- break;
- case TOC_FILE:
- if (strcmp(name, "file") == 0) {
- if (xar->file->parent != NULL &&
- ((xar->file->mode & AE_IFMT) == AE_IFDIR))
- xar->file->parent->subdirs++;
- xar->file = xar->file->parent;
- if (xar->file == NULL)
- xar->xmlsts = TOC;
- }
- break;
- case FILE_DATA:
- if (strcmp(name, "data") == 0)
- xar->xmlsts = TOC_FILE;
- break;
- case FILE_DATA_LENGTH:
- if (strcmp(name, "length") == 0)
- xar->xmlsts = FILE_DATA;
- break;
- case FILE_DATA_OFFSET:
- if (strcmp(name, "offset") == 0)
- xar->xmlsts = FILE_DATA;
- break;
- case FILE_DATA_SIZE:
- if (strcmp(name, "size") == 0)
- xar->xmlsts = FILE_DATA;
- break;
- case FILE_DATA_ENCODING:
- if (strcmp(name, "encoding") == 0)
- xar->xmlsts = FILE_DATA;
- break;
- case FILE_DATA_A_CHECKSUM:
- if (strcmp(name, "archived-checksum") == 0)
- xar->xmlsts = FILE_DATA;
- break;
- case FILE_DATA_E_CHECKSUM:
- if (strcmp(name, "extracted-checksum") == 0)
- xar->xmlsts = FILE_DATA;
- break;
- case FILE_DATA_CONTENT:
- if (strcmp(name, "content") == 0)
- xar->xmlsts = FILE_DATA;
- break;
- case FILE_EA:
- if (strcmp(name, "ea") == 0) {
- xar->xmlsts = TOC_FILE;
- xar->xattr = NULL;
- }
- break;
- case FILE_EA_LENGTH:
- if (strcmp(name, "length") == 0)
- xar->xmlsts = FILE_EA;
- break;
- case FILE_EA_OFFSET:
- if (strcmp(name, "offset") == 0)
- xar->xmlsts = FILE_EA;
- break;
- case FILE_EA_SIZE:
- if (strcmp(name, "size") == 0)
- xar->xmlsts = FILE_EA;
- break;
- case FILE_EA_ENCODING:
- if (strcmp(name, "encoding") == 0)
- xar->xmlsts = FILE_EA;
- break;
- case FILE_EA_A_CHECKSUM:
- if (strcmp(name, "archived-checksum") == 0)
- xar->xmlsts = FILE_EA;
- break;
- case FILE_EA_E_CHECKSUM:
- if (strcmp(name, "extracted-checksum") == 0)
- xar->xmlsts = FILE_EA;
- break;
- case FILE_EA_NAME:
- if (strcmp(name, "name") == 0)
- xar->xmlsts = FILE_EA;
- break;
- case FILE_EA_FSTYPE:
- if (strcmp(name, "fstype") == 0)
- xar->xmlsts = FILE_EA;
- break;
- case FILE_CTIME:
- if (strcmp(name, "ctime") == 0)
- xar->xmlsts = TOC_FILE;
- break;
- case FILE_MTIME:
- if (strcmp(name, "mtime") == 0)
- xar->xmlsts = TOC_FILE;
- break;
- case FILE_ATIME:
- if (strcmp(name, "atime") == 0)
- xar->xmlsts = TOC_FILE;
- break;
- case FILE_GROUP:
- if (strcmp(name, "group") == 0)
- xar->xmlsts = TOC_FILE;
- break;
- case FILE_GID:
- if (strcmp(name, "gid") == 0)
- xar->xmlsts = TOC_FILE;
- break;
- case FILE_USER:
- if (strcmp(name, "user") == 0)
- xar->xmlsts = TOC_FILE;
- break;
- case FILE_UID:
- if (strcmp(name, "uid") == 0)
- xar->xmlsts = TOC_FILE;
- break;
- case FILE_MODE:
- if (strcmp(name, "mode") == 0)
- xar->xmlsts = TOC_FILE;
- break;
- case FILE_DEVICE:
- if (strcmp(name, "device") == 0)
- xar->xmlsts = TOC_FILE;
- break;
- case FILE_DEVICE_MAJOR:
- if (strcmp(name, "major") == 0)
- xar->xmlsts = FILE_DEVICE;
- break;
- case FILE_DEVICE_MINOR:
- if (strcmp(name, "minor") == 0)
- xar->xmlsts = FILE_DEVICE;
- break;
- case FILE_DEVICENO:
- if (strcmp(name, "deviceno") == 0)
- xar->xmlsts = TOC_FILE;
- break;
- case FILE_INODE:
- if (strcmp(name, "inode") == 0)
- xar->xmlsts = TOC_FILE;
- break;
- case FILE_LINK:
- if (strcmp(name, "link") == 0)
- xar->xmlsts = TOC_FILE;
- break;
- case FILE_TYPE:
- if (strcmp(name, "type") == 0)
- xar->xmlsts = TOC_FILE;
- break;
- case FILE_NAME:
- if (strcmp(name, "name") == 0)
- xar->xmlsts = TOC_FILE;
- break;
- case FILE_ACL:
- if (strcmp(name, "acl") == 0)
- xar->xmlsts = TOC_FILE;
- break;
- case FILE_ACL_DEFAULT:
- if (strcmp(name, "default") == 0)
- xar->xmlsts = FILE_ACL;
- break;
- case FILE_ACL_ACCESS:
- if (strcmp(name, "access") == 0)
- xar->xmlsts = FILE_ACL;
- break;
- case FILE_ACL_APPLEEXTENDED:
- if (strcmp(name, "appleextended") == 0)
- xar->xmlsts = FILE_ACL;
- break;
- case FILE_FLAGS:
- if (strcmp(name, "flags") == 0)
- xar->xmlsts = TOC_FILE;
- break;
- case FILE_FLAGS_USER_NODUMP:
- if (strcmp(name, "UserNoDump") == 0)
- xar->xmlsts = FILE_FLAGS;
- break;
- case FILE_FLAGS_USER_IMMUTABLE:
- if (strcmp(name, "UserImmutable") == 0)
- xar->xmlsts = FILE_FLAGS;
- break;
- case FILE_FLAGS_USER_APPEND:
- if (strcmp(name, "UserAppend") == 0)
- xar->xmlsts = FILE_FLAGS;
- break;
- case FILE_FLAGS_USER_OPAQUE:
- if (strcmp(name, "UserOpaque") == 0)
- xar->xmlsts = FILE_FLAGS;
- break;
- case FILE_FLAGS_USER_NOUNLINK:
- if (strcmp(name, "UserNoUnlink") == 0)
- xar->xmlsts = FILE_FLAGS;
- break;
- case FILE_FLAGS_SYS_ARCHIVED:
- if (strcmp(name, "SystemArchived") == 0)
- xar->xmlsts = FILE_FLAGS;
- break;
- case FILE_FLAGS_SYS_IMMUTABLE:
- if (strcmp(name, "SystemImmutable") == 0)
- xar->xmlsts = FILE_FLAGS;
- break;
- case FILE_FLAGS_SYS_APPEND:
- if (strcmp(name, "SystemAppend") == 0)
- xar->xmlsts = FILE_FLAGS;
- break;
- case FILE_FLAGS_SYS_NOUNLINK:
- if (strcmp(name, "SystemNoUnlink") == 0)
- xar->xmlsts = FILE_FLAGS;
- break;
- case FILE_FLAGS_SYS_SNAPSHOT:
- if (strcmp(name, "SystemSnapshot") == 0)
- xar->xmlsts = FILE_FLAGS;
- break;
- case FILE_EXT2:
- if (strcmp(name, "ext2") == 0)
- xar->xmlsts = TOC_FILE;
- break;
- case FILE_EXT2_SecureDeletion:
- if (strcmp(name, "SecureDeletion") == 0)
- xar->xmlsts = FILE_EXT2;
- break;
- case FILE_EXT2_Undelete:
- if (strcmp(name, "Undelete") == 0)
- xar->xmlsts = FILE_EXT2;
- break;
- case FILE_EXT2_Compress:
- if (strcmp(name, "Compress") == 0)
- xar->xmlsts = FILE_EXT2;
- break;
- case FILE_EXT2_Synchronous:
- if (strcmp(name, "Synchronous") == 0)
- xar->xmlsts = FILE_EXT2;
- break;
- case FILE_EXT2_Immutable:
- if (strcmp(name, "Immutable") == 0)
- xar->xmlsts = FILE_EXT2;
- break;
- case FILE_EXT2_AppendOnly:
- if (strcmp(name, "AppendOnly") == 0)
- xar->xmlsts = FILE_EXT2;
- break;
- case FILE_EXT2_NoDump:
- if (strcmp(name, "NoDump") == 0)
- xar->xmlsts = FILE_EXT2;
- break;
- case FILE_EXT2_NoAtime:
- if (strcmp(name, "NoAtime") == 0)
- xar->xmlsts = FILE_EXT2;
- break;
- case FILE_EXT2_CompDirty:
- if (strcmp(name, "CompDirty") == 0)
- xar->xmlsts = FILE_EXT2;
- break;
- case FILE_EXT2_CompBlock:
- if (strcmp(name, "CompBlock") == 0)
- xar->xmlsts = FILE_EXT2;
- break;
- case FILE_EXT2_NoCompBlock:
- if (strcmp(name, "NoCompBlock") == 0)
- xar->xmlsts = FILE_EXT2;
- break;
- case FILE_EXT2_CompError:
- if (strcmp(name, "CompError") == 0)
- xar->xmlsts = FILE_EXT2;
- break;
- case FILE_EXT2_BTree:
- if (strcmp(name, "BTree") == 0)
- xar->xmlsts = FILE_EXT2;
- break;
- case FILE_EXT2_HashIndexed:
- if (strcmp(name, "HashIndexed") == 0)
- xar->xmlsts = FILE_EXT2;
- break;
- case FILE_EXT2_iMagic:
- if (strcmp(name, "iMagic") == 0)
- xar->xmlsts = FILE_EXT2;
- break;
- case FILE_EXT2_Journaled:
- if (strcmp(name, "Journaled") == 0)
- xar->xmlsts = FILE_EXT2;
- break;
- case FILE_EXT2_NoTail:
- if (strcmp(name, "NoTail") == 0)
- xar->xmlsts = FILE_EXT2;
- break;
- case FILE_EXT2_DirSync:
- if (strcmp(name, "DirSync") == 0)
- xar->xmlsts = FILE_EXT2;
- break;
- case FILE_EXT2_TopDir:
- if (strcmp(name, "TopDir") == 0)
- xar->xmlsts = FILE_EXT2;
- break;
- case FILE_EXT2_Reserved:
- if (strcmp(name, "Reserved") == 0)
- xar->xmlsts = FILE_EXT2;
- break;
- case UNKNOWN:
- unknowntag_end(xar, name);
- break;
- }
-}
-
-static const int base64[256] = {
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, /* 00 - 0F */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, /* 10 - 1F */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 62, -1, -1, -1, 63, /* 20 - 2F */
- 52, 53, 54, 55, 56, 57, 58, 59,
- 60, 61, -1, -1, -1, -1, -1, -1, /* 30 - 3F */
- -1, 0, 1, 2, 3, 4, 5, 6,
- 7, 8, 9, 10, 11, 12, 13, 14, /* 40 - 4F */
- 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, -1, -1, -1, -1, -1, /* 50 - 5F */
- -1, 26, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, 38, 39, 40, /* 60 - 6F */
- 41, 42, 43, 44, 45, 46, 47, 48,
- 49, 50, 51, -1, -1, -1, -1, -1, /* 70 - 7F */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, /* 80 - 8F */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, /* 90 - 9F */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, /* A0 - AF */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, /* B0 - BF */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, /* C0 - CF */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, /* D0 - DF */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, /* E0 - EF */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, /* F0 - FF */
-};
-
-static void
-strappend_base64(struct xar *xar,
- struct archive_string *as, const char *s, size_t l)
-{
- unsigned char buff[256];
- unsigned char *out;
- const unsigned char *b;
- size_t len;
-
- (void)xar; /* UNUSED */
- len = 0;
- out = buff;
- b = (const unsigned char *)s;
- while (l > 0) {
- int n = 0;
-
- if (base64[b[0]] < 0 || base64[b[1]] < 0)
- break;
- n = base64[*b++] << 18;
- n |= base64[*b++] << 12;
- *out++ = n >> 16;
- len++;
- l -= 2;
-
- if (l > 0) {
- if (base64[*b] < 0)
- break;
- n |= base64[*b++] << 6;
- *out++ = (n >> 8) & 0xFF;
- len++;
- --l;
- }
- if (l > 0) {
- if (base64[*b] < 0)
- break;
- n |= base64[*b++];
- *out++ = n & 0xFF;
- len++;
- --l;
- }
- if (len+3 >= sizeof(buff)) {
- archive_strncat(as, (const char *)buff, len);
- len = 0;
- out = buff;
- }
- }
- if (len > 0)
- archive_strncat(as, (const char *)buff, len);
-}
-
-static int
-is_string(const char *known, const char *data, size_t len)
-{
- if (strlen(known) != len)
- return -1;
- return memcmp(data, known, len);
-}
-
-static void
-xml_data(void *userData, const char *s, int len)
-{
- struct archive_read *a;
- struct xar *xar;
-
- a = (struct archive_read *)userData;
- xar = (struct xar *)(a->format->data);
-
-#if DEBUG
- {
- char buff[1024];
- if (len > (int)(sizeof(buff)-1))
- len = (int)(sizeof(buff)-1);
- strncpy(buff, s, len);
- buff[len] = 0;
- fprintf(stderr, "\tlen=%d:\"%s\"\n", len, buff);
- }
-#endif
- switch (xar->xmlsts) {
- case TOC_CHECKSUM_OFFSET:
- xar->toc_chksum_offset = atol10(s, len);
- break;
- case TOC_CHECKSUM_SIZE:
- xar->toc_chksum_size = atol10(s, len);
- break;
- default:
- break;
- }
- if (xar->file == NULL)
- return;
-
- switch (xar->xmlsts) {
- case FILE_NAME:
- if (xar->file->parent != NULL) {
- archive_string_concat(&(xar->file->pathname),
- &(xar->file->parent->pathname));
- archive_strappend_char(&(xar->file->pathname), '/');
- }
- xar->file->has |= HAS_PATHNAME;
- if (xar->base64text) {
- strappend_base64(xar,
- &(xar->file->pathname), s, len);
- } else
- archive_strncat(&(xar->file->pathname), s, len);
- break;
- case FILE_LINK:
- xar->file->has |= HAS_SYMLINK;
- archive_strncpy(&(xar->file->symlink), s, len);
- break;
- case FILE_TYPE:
- if (is_string("file", s, len) == 0 ||
- is_string("hardlink", s, len) == 0)
- xar->file->mode =
- (xar->file->mode & ~AE_IFMT) | AE_IFREG;
- if (is_string("directory", s, len) == 0)
- xar->file->mode =
- (xar->file->mode & ~AE_IFMT) | AE_IFDIR;
- if (is_string("symlink", s, len) == 0)
- xar->file->mode =
- (xar->file->mode & ~AE_IFMT) | AE_IFLNK;
- if (is_string("character special", s, len) == 0)
- xar->file->mode =
- (xar->file->mode & ~AE_IFMT) | AE_IFCHR;
- if (is_string("block special", s, len) == 0)
- xar->file->mode =
- (xar->file->mode & ~AE_IFMT) | AE_IFBLK;
- if (is_string("socket", s, len) == 0)
- xar->file->mode =
- (xar->file->mode & ~AE_IFMT) | AE_IFSOCK;
- if (is_string("fifo", s, len) == 0)
- xar->file->mode =
- (xar->file->mode & ~AE_IFMT) | AE_IFIFO;
- xar->file->has |= HAS_TYPE;
- break;
- case FILE_INODE:
- xar->file->has |= HAS_INO;
- xar->file->ino64 = atol10(s, len);
- break;
- case FILE_DEVICE_MAJOR:
- xar->file->has |= HAS_DEVMAJOR;
- xar->file->devmajor = (dev_t)atol10(s, len);
- break;
- case FILE_DEVICE_MINOR:
- xar->file->has |= HAS_DEVMINOR;
- xar->file->devminor = (dev_t)atol10(s, len);
- break;
- case FILE_DEVICENO:
- xar->file->has |= HAS_DEV;
- xar->file->dev = (dev_t)atol10(s, len);
- break;
- case FILE_MODE:
- xar->file->has |= HAS_MODE;
- xar->file->mode =
- (xar->file->mode & AE_IFMT) |
- ((mode_t)(atol8(s, len)) & ~AE_IFMT);
- break;
- case FILE_GROUP:
- xar->file->has |= HAS_GID;
- archive_strncpy(&(xar->file->gname), s, len);
- break;
- case FILE_GID:
- xar->file->has |= HAS_GID;
- xar->file->gid = atol10(s, len);
- break;
- case FILE_USER:
- xar->file->has |= HAS_UID;
- archive_strncpy(&(xar->file->uname), s, len);
- break;
- case FILE_UID:
- xar->file->has |= HAS_UID;
- xar->file->uid = atol10(s, len);
- break;
- case FILE_CTIME:
- xar->file->has |= HAS_TIME | HAS_CTIME;
- xar->file->ctime = parse_time(s, len);
- break;
- case FILE_MTIME:
- xar->file->has |= HAS_TIME | HAS_MTIME;
- xar->file->mtime = parse_time(s, len);
- break;
- case FILE_ATIME:
- xar->file->has |= HAS_TIME | HAS_ATIME;
- xar->file->atime = parse_time(s, len);
- break;
- case FILE_DATA_LENGTH:
- xar->file->has |= HAS_DATA;
- xar->file->length = atol10(s, len);
- break;
- case FILE_DATA_OFFSET:
- xar->file->has |= HAS_DATA;
- xar->file->offset = atol10(s, len);
- break;
- case FILE_DATA_SIZE:
- xar->file->has |= HAS_DATA;
- xar->file->size = atol10(s, len);
- break;
- case FILE_DATA_A_CHECKSUM:
- xar->file->a_sum.len = atohex(xar->file->a_sum.val,
- sizeof(xar->file->a_sum.val), s, len);
- break;
- case FILE_DATA_E_CHECKSUM:
- xar->file->e_sum.len = atohex(xar->file->e_sum.val,
- sizeof(xar->file->e_sum.val), s, len);
- break;
- case FILE_EA_LENGTH:
- xar->file->has |= HAS_XATTR;
- xar->xattr->length = atol10(s, len);
- break;
- case FILE_EA_OFFSET:
- xar->file->has |= HAS_XATTR;
- xar->xattr->offset = atol10(s, len);
- break;
- case FILE_EA_SIZE:
- xar->file->has |= HAS_XATTR;
- xar->xattr->size = atol10(s, len);
- break;
- case FILE_EA_A_CHECKSUM:
- xar->file->has |= HAS_XATTR;
- xar->xattr->a_sum.len = atohex(xar->xattr->a_sum.val,
- sizeof(xar->xattr->a_sum.val), s, len);
- break;
- case FILE_EA_E_CHECKSUM:
- xar->file->has |= HAS_XATTR;
- xar->xattr->e_sum.len = atohex(xar->xattr->e_sum.val,
- sizeof(xar->xattr->e_sum.val), s, len);
- break;
- case FILE_EA_NAME:
- xar->file->has |= HAS_XATTR;
- archive_strncpy(&(xar->xattr->name), s, len);
- break;
- case FILE_EA_FSTYPE:
- xar->file->has |= HAS_XATTR;
- archive_strncpy(&(xar->xattr->fstype), s, len);
- break;
- break;
- case FILE_ACL_DEFAULT:
- case FILE_ACL_ACCESS:
- case FILE_ACL_APPLEEXTENDED:
- xar->file->has |= HAS_ACL;
- /* TODO */
- break;
- case INIT:
- case XAR:
- case TOC:
- case TOC_CREATION_TIME:
- case TOC_CHECKSUM:
- case TOC_CHECKSUM_OFFSET:
- case TOC_CHECKSUM_SIZE:
- case TOC_FILE:
- case FILE_DATA:
- case FILE_DATA_ENCODING:
- case FILE_DATA_CONTENT:
- case FILE_DEVICE:
- case FILE_EA:
- case FILE_EA_ENCODING:
- case FILE_ACL:
- case FILE_FLAGS:
- case FILE_FLAGS_USER_NODUMP:
- case FILE_FLAGS_USER_IMMUTABLE:
- case FILE_FLAGS_USER_APPEND:
- case FILE_FLAGS_USER_OPAQUE:
- case FILE_FLAGS_USER_NOUNLINK:
- case FILE_FLAGS_SYS_ARCHIVED:
- case FILE_FLAGS_SYS_IMMUTABLE:
- case FILE_FLAGS_SYS_APPEND:
- case FILE_FLAGS_SYS_NOUNLINK:
- case FILE_FLAGS_SYS_SNAPSHOT:
- case FILE_EXT2:
- case FILE_EXT2_SecureDeletion:
- case FILE_EXT2_Undelete:
- case FILE_EXT2_Compress:
- case FILE_EXT2_Synchronous:
- case FILE_EXT2_Immutable:
- case FILE_EXT2_AppendOnly:
- case FILE_EXT2_NoDump:
- case FILE_EXT2_NoAtime:
- case FILE_EXT2_CompDirty:
- case FILE_EXT2_CompBlock:
- case FILE_EXT2_NoCompBlock:
- case FILE_EXT2_CompError:
- case FILE_EXT2_BTree:
- case FILE_EXT2_HashIndexed:
- case FILE_EXT2_iMagic:
- case FILE_EXT2_Journaled:
- case FILE_EXT2_NoTail:
- case FILE_EXT2_DirSync:
- case FILE_EXT2_TopDir:
- case FILE_EXT2_Reserved:
- case UNKNOWN:
- break;
- }
-}
-
-/*
- * BSD file flags.
- */
-static int
-xml_parse_file_flags(struct xar *xar, const char *name)
-{
- const char *flag = NULL;
-
- if (strcmp(name, "UserNoDump") == 0) {
- xar->xmlsts = FILE_FLAGS_USER_NODUMP;
- flag = "nodump";
- }
- else if (strcmp(name, "UserImmutable") == 0) {
- xar->xmlsts = FILE_FLAGS_USER_IMMUTABLE;
- flag = "uimmutable";
- }
- else if (strcmp(name, "UserAppend") == 0) {
- xar->xmlsts = FILE_FLAGS_USER_APPEND;
- flag = "uappend";
- }
- else if (strcmp(name, "UserOpaque") == 0) {
- xar->xmlsts = FILE_FLAGS_USER_OPAQUE;
- flag = "opaque";
- }
- else if (strcmp(name, "UserNoUnlink") == 0) {
- xar->xmlsts = FILE_FLAGS_USER_NOUNLINK;
- flag = "nouunlink";
- }
- else if (strcmp(name, "SystemArchived") == 0) {
- xar->xmlsts = FILE_FLAGS_SYS_ARCHIVED;
- flag = "archived";
- }
- else if (strcmp(name, "SystemImmutable") == 0) {
- xar->xmlsts = FILE_FLAGS_SYS_IMMUTABLE;
- flag = "simmutable";
- }
- else if (strcmp(name, "SystemAppend") == 0) {
- xar->xmlsts = FILE_FLAGS_SYS_APPEND;
- flag = "sappend";
- }
- else if (strcmp(name, "SystemNoUnlink") == 0) {
- xar->xmlsts = FILE_FLAGS_SYS_NOUNLINK;
- flag = "nosunlink";
- }
- else if (strcmp(name, "SystemSnapshot") == 0) {
- xar->xmlsts = FILE_FLAGS_SYS_SNAPSHOT;
- flag = "snapshot";
- }
-
- if (flag == NULL)
- return (0);
- xar->file->has |= HAS_FFLAGS;
- if (archive_strlen(&(xar->file->fflags_text)) > 0)
- archive_strappend_char(&(xar->file->fflags_text), ',');
- archive_strcat(&(xar->file->fflags_text), flag);
- return (1);
-}
-
-/*
- * Linux file flags.
- */
-static int
-xml_parse_file_ext2(struct xar *xar, const char *name)
-{
- const char *flag = NULL;
-
- if (strcmp(name, "SecureDeletion") == 0) {
- xar->xmlsts = FILE_EXT2_SecureDeletion;
- flag = "securedeletion";
- }
- else if (strcmp(name, "Undelete") == 0) {
- xar->xmlsts = FILE_EXT2_Undelete;
- flag = "nouunlink";
- }
- else if (strcmp(name, "Compress") == 0) {
- xar->xmlsts = FILE_EXT2_Compress;
- flag = "compress";
- }
- else if (strcmp(name, "Synchronous") == 0) {
- xar->xmlsts = FILE_EXT2_Synchronous;
- flag = "sync";
- }
- else if (strcmp(name, "Immutable") == 0) {
- xar->xmlsts = FILE_EXT2_Immutable;
- flag = "simmutable";
- }
- else if (strcmp(name, "AppendOnly") == 0) {
- xar->xmlsts = FILE_EXT2_AppendOnly;
- flag = "sappend";
- }
- else if (strcmp(name, "NoDump") == 0) {
- xar->xmlsts = FILE_EXT2_NoDump;
- flag = "nodump";
- }
- else if (strcmp(name, "NoAtime") == 0) {
- xar->xmlsts = FILE_EXT2_NoAtime;
- flag = "noatime";
- }
- else if (strcmp(name, "CompDirty") == 0) {
- xar->xmlsts = FILE_EXT2_CompDirty;
- flag = "compdirty";
- }
- else if (strcmp(name, "CompBlock") == 0) {
- xar->xmlsts = FILE_EXT2_CompBlock;
- flag = "comprblk";
- }
- else if (strcmp(name, "NoCompBlock") == 0) {
- xar->xmlsts = FILE_EXT2_NoCompBlock;
- flag = "nocomprblk";
- }
- else if (strcmp(name, "CompError") == 0) {
- xar->xmlsts = FILE_EXT2_CompError;
- flag = "comperr";
- }
- else if (strcmp(name, "BTree") == 0) {
- xar->xmlsts = FILE_EXT2_BTree;
- flag = "btree";
- }
- else if (strcmp(name, "HashIndexed") == 0) {
- xar->xmlsts = FILE_EXT2_HashIndexed;
- flag = "hashidx";
- }
- else if (strcmp(name, "iMagic") == 0) {
- xar->xmlsts = FILE_EXT2_iMagic;
- flag = "imagic";
- }
- else if (strcmp(name, "Journaled") == 0) {
- xar->xmlsts = FILE_EXT2_Journaled;
- flag = "journal";
- }
- else if (strcmp(name, "NoTail") == 0) {
- xar->xmlsts = FILE_EXT2_NoTail;
- flag = "notail";
- }
- else if (strcmp(name, "DirSync") == 0) {
- xar->xmlsts = FILE_EXT2_DirSync;
- flag = "dirsync";
- }
- else if (strcmp(name, "TopDir") == 0) {
- xar->xmlsts = FILE_EXT2_TopDir;
- flag = "topdir";
- }
- else if (strcmp(name, "Reserved") == 0) {
- xar->xmlsts = FILE_EXT2_Reserved;
- flag = "reserved";
- }
-
- if (flag == NULL)
- return (0);
- if (archive_strlen(&(xar->file->fflags_text)) > 0)
- archive_strappend_char(&(xar->file->fflags_text), ',');
- archive_strcat(&(xar->file->fflags_text), flag);
- return (1);
-}
-
-#ifdef HAVE_LIBXML_XMLREADER_H
-
-static int
-xml2_xmlattr_setup(struct archive_read *a,
- struct xmlattr_list *list, xmlTextReaderPtr reader)
-{
- struct xmlattr *attr;
- int r;
-
- list->first = NULL;
- list->last = &(list->first);
- r = xmlTextReaderMoveToFirstAttribute(reader);
- while (r == 1) {
- attr = malloc(sizeof*(attr));
- if (attr == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- attr->name = strdup(
- (const char *)xmlTextReaderConstLocalName(reader));
- if (attr->name == NULL) {
- free(attr);
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- attr->value = strdup(
- (const char *)xmlTextReaderConstValue(reader));
- if (attr->value == NULL) {
- free(attr->name);
- free(attr);
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- attr->next = NULL;
- *list->last = attr;
- list->last = &(attr->next);
- r = xmlTextReaderMoveToNextAttribute(reader);
- }
- return (r);
-}
-
-static int
-xml2_read_cb(void *context, char *buffer, int len)
-{
- struct archive_read *a;
- struct xar *xar;
- const void *d;
- size_t outbytes;
- size_t used = 0;
- int r;
-
- a = (struct archive_read *)context;
- xar = (struct xar *)(a->format->data);
-
- if (xar->toc_remaining <= 0)
- return (0);
- d = buffer;
- outbytes = len;
- r = rd_contents(a, &d, &outbytes, &used, xar->toc_remaining);
- if (r != ARCHIVE_OK)
- return (r);
- __archive_read_consume(a, used);
- xar->toc_remaining -= used;
- xar->offset += used;
- xar->toc_total += outbytes;
- PRINT_TOC(buffer, len);
-
- return ((int)outbytes);
-}
-
-static int
-xml2_close_cb(void *context)
-{
-
- (void)context; /* UNUSED */
- return (0);
-}
-
-static void
-xml2_error_hdr(void *arg, const char *msg, xmlParserSeverities severity,
- xmlTextReaderLocatorPtr locator)
-{
- struct archive_read *a;
-
- (void)locator; /* UNUSED */
- a = (struct archive_read *)arg;
- switch (severity) {
- case XML_PARSER_SEVERITY_VALIDITY_WARNING:
- case XML_PARSER_SEVERITY_WARNING:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "XML Parsing error: %s", msg);
- break;
- case XML_PARSER_SEVERITY_VALIDITY_ERROR:
- case XML_PARSER_SEVERITY_ERROR:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "XML Parsing error: %s", msg);
- break;
- }
-}
-
-static int
-xml2_read_toc(struct archive_read *a)
-{
- xmlTextReaderPtr reader;
- struct xmlattr_list list;
- int r;
-
- reader = xmlReaderForIO(xml2_read_cb, xml2_close_cb, a, NULL, NULL, 0);
- if (reader == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Couldn't allocate memory for xml parser");
- return (ARCHIVE_FATAL);
- }
- xmlTextReaderSetErrorHandler(reader, xml2_error_hdr, a);
-
- while ((r = xmlTextReaderRead(reader)) == 1) {
- const char *name, *value;
- int type, empty;
-
- type = xmlTextReaderNodeType(reader);
- name = (const char *)xmlTextReaderConstLocalName(reader);
- switch (type) {
- case XML_READER_TYPE_ELEMENT:
- empty = xmlTextReaderIsEmptyElement(reader);
- r = xml2_xmlattr_setup(a, &list, reader);
- if (r == ARCHIVE_OK)
- r = xml_start(a, name, &list);
- xmlattr_cleanup(&list);
- if (r != ARCHIVE_OK)
- return (r);
- if (empty)
- xml_end(a, name);
- break;
- case XML_READER_TYPE_END_ELEMENT:
- xml_end(a, name);
- break;
- case XML_READER_TYPE_TEXT:
- value = (const char *)xmlTextReaderConstValue(reader);
- xml_data(a, value, strlen(value));
- break;
- case XML_READER_TYPE_SIGNIFICANT_WHITESPACE:
- default:
- break;
- }
- if (r < 0)
- break;
- }
- xmlFreeTextReader(reader);
- xmlCleanupParser();
-
- return ((r == 0)?ARCHIVE_OK:ARCHIVE_FATAL);
-}
-
-#elif defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H)
-
-static int
-expat_xmlattr_setup(struct archive_read *a,
- struct xmlattr_list *list, const XML_Char **atts)
-{
- struct xmlattr *attr;
- char *name, *value;
-
- list->first = NULL;
- list->last = &(list->first);
- if (atts == NULL)
- return (ARCHIVE_OK);
- while (atts[0] != NULL && atts[1] != NULL) {
- attr = malloc(sizeof*(attr));
- name = strdup(atts[0]);
- value = strdup(atts[1]);
- if (attr == NULL || name == NULL || value == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- free(attr);
- free(name);
- free(value);
- return (ARCHIVE_FATAL);
- }
- attr->name = name;
- attr->value = value;
- attr->next = NULL;
- *list->last = attr;
- list->last = &(attr->next);
- atts += 2;
- }
- return (ARCHIVE_OK);
-}
-
-static void
-expat_start_cb(void *userData, const XML_Char *name, const XML_Char **atts)
-{
- struct expat_userData *ud = (struct expat_userData *)userData;
- struct archive_read *a = ud->archive;
- struct xmlattr_list list;
- int r;
-
- r = expat_xmlattr_setup(a, &list, atts);
- if (r == ARCHIVE_OK)
- r = xml_start(a, (const char *)name, &list);
- xmlattr_cleanup(&list);
- ud->state = r;
-}
-
-static void
-expat_end_cb(void *userData, const XML_Char *name)
-{
- struct expat_userData *ud = (struct expat_userData *)userData;
-
- xml_end(ud->archive, (const char *)name);
-}
-
-static void
-expat_data_cb(void *userData, const XML_Char *s, int len)
-{
- struct expat_userData *ud = (struct expat_userData *)userData;
-
- xml_data(ud->archive, s, len);
-}
-
-static int
-expat_read_toc(struct archive_read *a)
-{
- struct xar *xar;
- XML_Parser parser;
- struct expat_userData ud;
-
- ud.state = ARCHIVE_OK;
- ud.archive = a;
-
- xar = (struct xar *)(a->format->data);
-
- /* Initialize XML Parser library. */
- parser = XML_ParserCreate(NULL);
- if (parser == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Couldn't allocate memory for xml parser");
- return (ARCHIVE_FATAL);
- }
- XML_SetUserData(parser, &ud);
- XML_SetElementHandler(parser, expat_start_cb, expat_end_cb);
- XML_SetCharacterDataHandler(parser, expat_data_cb);
- xar->xmlsts = INIT;
-
- while (xar->toc_remaining && ud.state == ARCHIVE_OK) {
- enum XML_Status xr;
- const void *d;
- size_t outbytes;
- size_t used;
- int r;
-
- d = NULL;
- r = rd_contents(a, &d, &outbytes, &used, xar->toc_remaining);
- if (r != ARCHIVE_OK)
- return (r);
- xar->toc_remaining -= used;
- xar->offset += used;
- xar->toc_total += outbytes;
- PRINT_TOC(d, outbytes);
-
- xr = XML_Parse(parser, d, outbytes, xar->toc_remaining == 0);
- __archive_read_consume(a, used);
- if (xr == XML_STATUS_ERROR) {
- XML_ParserFree(parser);
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "XML Parsing failed");
- return (ARCHIVE_FATAL);
- }
- }
- XML_ParserFree(parser);
- return (ud.state);
-}
-#endif /* defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H) */
-
-#endif /* Support xar format */
diff --git a/contrib/libs/libarchive/libarchive/archive_read_support_format_zip.c b/contrib/libs/libarchive/libarchive/archive_read_support_format_zip.c
deleted file mode 100644
index cca4a3af7e..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_read_support_format_zip.c
+++ /dev/null
@@ -1,4270 +0,0 @@
-/*-
- * Copyright (c) 2004-2013 Tim Kientzle
- * Copyright (c) 2011-2012,2014 Michihiro NAKAJIMA
- * Copyright (c) 2013 Konrad Kleine
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_zip.c 201102 2009-12-28 03:11:36Z kientzle $");
-
-/*
- * The definitive documentation of the Zip file format is:
- * http://www.pkware.com/documents/casestudies/APPNOTE.TXT
- *
- * The Info-Zip project has pioneered various extensions to better
- * support Zip on Unix, including the 0x5455 "UT", 0x5855 "UX", 0x7855
- * "Ux", and 0x7875 "ux" extensions for time and ownership
- * information.
- *
- * History of this code: The streaming Zip reader was first added to
- * libarchive in January 2005. Support for seekable input sources was
- * added in Nov 2011. Zip64 support (including a significant code
- * refactoring) was added in 2014.
- */
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-#ifdef HAVE_BZLIB_H
-#include <bzlib.h>
-#endif
-#ifdef HAVE_LZMA_H
-#error #include <lzma.h>
-#endif
-#ifdef HAVE_ZSTD_H
-#include <zstd.h>
-#endif
-
-#include "archive.h"
-#include "archive_digest_private.h"
-#include "archive_cryptor_private.h"
-#include "archive_endian.h"
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_hmac_private.h"
-#include "archive_private.h"
-#include "archive_rb.h"
-#include "archive_read_private.h"
-#include "archive_ppmd8_private.h"
-
-#ifndef HAVE_ZLIB_H
-#error #include "archive_crc32.h"
-#endif
-
-struct zip_entry {
- struct archive_rb_node node;
- struct zip_entry *next;
- int64_t local_header_offset;
- int64_t compressed_size;
- int64_t uncompressed_size;
- int64_t gid;
- int64_t uid;
- struct archive_string rsrcname;
- time_t mtime;
- time_t atime;
- time_t ctime;
- uint32_t crc32;
- uint16_t mode;
- uint16_t zip_flags; /* From GP Flags Field */
- unsigned char compression;
- unsigned char system; /* From "version written by" */
- unsigned char flags; /* Our extra markers. */
- unsigned char decdat;/* Used for Decryption check */
-
- /* WinZip AES encryption extra field should be available
- * when compression is 99. */
- struct {
- /* Vendor version: AE-1 - 0x0001, AE-2 - 0x0002 */
- unsigned vendor;
-#define AES_VENDOR_AE_1 0x0001
-#define AES_VENDOR_AE_2 0x0002
- /* AES encryption strength:
- * 1 - 128 bits, 2 - 192 bits, 2 - 256 bits. */
- unsigned strength;
- /* Actual compression method. */
- unsigned char compression;
- } aes_extra;
-};
-
-struct trad_enc_ctx {
- uint32_t keys[3];
-};
-
-/* Bits used in zip_flags. */
-#define ZIP_ENCRYPTED (1 << 0)
-#define ZIP_LENGTH_AT_END (1 << 3)
-#define ZIP_STRONG_ENCRYPTED (1 << 6)
-#define ZIP_UTF8_NAME (1 << 11)
-/* See "7.2 Single Password Symmetric Encryption Method"
- in http://www.pkware.com/documents/casestudies/APPNOTE.TXT */
-#define ZIP_CENTRAL_DIRECTORY_ENCRYPTED (1 << 13)
-
-/* Bits used in flags. */
-#define LA_USED_ZIP64 (1 << 0)
-#define LA_FROM_CENTRAL_DIRECTORY (1 << 1)
-
-/*
- * See "WinZip - AES Encryption Information"
- * http://www.winzip.com/aes_info.htm
- */
-/* Value used in compression method. */
-#define WINZIP_AES_ENCRYPTION 99
-/* Authentication code size. */
-#define AUTH_CODE_SIZE 10
-/**/
-#define MAX_DERIVED_KEY_BUF_SIZE (AES_MAX_KEY_SIZE * 2 + 2)
-
-struct zip {
- /* Structural information about the archive. */
- struct archive_string format_name;
- int64_t central_directory_offset;
- int64_t central_directory_offset_adjusted;
- size_t central_directory_entries_total;
- size_t central_directory_entries_on_this_disk;
- int has_encrypted_entries;
-
- /* List of entries (seekable Zip only) */
- struct zip_entry *zip_entries;
- struct archive_rb_tree tree;
- struct archive_rb_tree tree_rsrc;
-
- /* Bytes read but not yet consumed via __archive_read_consume() */
- size_t unconsumed;
-
- /* Information about entry we're currently reading. */
- struct zip_entry *entry;
- int64_t entry_bytes_remaining;
-
- /* These count the number of bytes actually read for the entry. */
- int64_t entry_compressed_bytes_read;
- int64_t entry_uncompressed_bytes_read;
-
- /* Running CRC32 of the decompressed data */
- unsigned long entry_crc32;
- unsigned long (*crc32func)(unsigned long, const void *,
- size_t);
- char ignore_crc32;
-
- /* Flags to mark progress of decompression. */
- char decompress_init;
- char end_of_entry;
-
- unsigned char *uncompressed_buffer;
- size_t uncompressed_buffer_size;
-
-#ifdef HAVE_ZLIB_H
- z_stream stream;
- char stream_valid;
-#endif
-
-#if HAVE_LZMA_H && HAVE_LIBLZMA
- lzma_stream zipx_lzma_stream;
- char zipx_lzma_valid;
-#endif
-
-#ifdef HAVE_BZLIB_H
- bz_stream bzstream;
- char bzstream_valid;
-#endif
-
-#if HAVE_ZSTD_H && HAVE_LIBZSTD
- ZSTD_DStream *zstdstream;
- char zstdstream_valid;
-#endif
-
- IByteIn zipx_ppmd_stream;
- ssize_t zipx_ppmd_read_compressed;
- CPpmd8 ppmd8;
- char ppmd8_valid;
- char ppmd8_stream_failed;
-
- struct archive_string_conv *sconv;
- struct archive_string_conv *sconv_default;
- struct archive_string_conv *sconv_utf8;
- int init_default_conversion;
- int process_mac_extensions;
-
- char init_decryption;
-
- /* Decryption buffer. */
- /*
- * The decrypted data starts at decrypted_ptr and
- * extends for decrypted_bytes_remaining. Decryption
- * adds new data to the end of this block, data is returned
- * to clients from the beginning. When the block hits the
- * end of decrypted_buffer, it has to be shuffled back to
- * the beginning of the buffer.
- */
- unsigned char *decrypted_buffer;
- unsigned char *decrypted_ptr;
- size_t decrypted_buffer_size;
- size_t decrypted_bytes_remaining;
- size_t decrypted_unconsumed_bytes;
-
- /* Traditional PKWARE decryption. */
- struct trad_enc_ctx tctx;
- char tctx_valid;
-
- /* WinZip AES decryption. */
- /* Contexts used for AES decryption. */
- archive_crypto_ctx cctx;
- char cctx_valid;
- archive_hmac_sha1_ctx hctx;
- char hctx_valid;
-
- /* Strong encryption's decryption header information. */
- unsigned iv_size;
- unsigned alg_id;
- unsigned bit_len;
- unsigned flags;
- unsigned erd_size;
- unsigned v_size;
- unsigned v_crc32;
- uint8_t *iv;
- uint8_t *erd;
- uint8_t *v_data;
-};
-
-/* Many systems define min or MIN, but not all. */
-#define zipmin(a,b) ((a) < (b) ? (a) : (b))
-
-#ifdef HAVE_ZLIB_H
-static int
-zip_read_data_deflate(struct archive_read *a, const void **buff,
- size_t *size, int64_t *offset);
-#endif
-#if HAVE_LZMA_H && HAVE_LIBLZMA
-static int
-zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
- size_t *size, int64_t *offset);
-#endif
-
-/* This function is used by Ppmd8_DecodeSymbol during decompression of Ppmd8
- * streams inside ZIP files. It has 2 purposes: one is to fetch the next
- * compressed byte from the stream, second one is to increase the counter how
- * many compressed bytes were read. */
-static Byte
-ppmd_read(void* p) {
- /* Get the handle to current decompression context. */
- struct archive_read *a = ((IByteIn*)p)->a;
- struct zip *zip = (struct zip*) a->format->data;
- ssize_t bytes_avail = 0;
-
- /* Fetch next byte. */
- const uint8_t* data = __archive_read_ahead(a, 1, &bytes_avail);
- if(bytes_avail < 1) {
- zip->ppmd8_stream_failed = 1;
- return 0;
- }
-
- __archive_read_consume(a, 1);
-
- /* Increment the counter. */
- ++zip->zipx_ppmd_read_compressed;
-
- /* Return the next compressed byte. */
- return data[0];
-}
-
-/* ------------------------------------------------------------------------ */
-
-/*
- Traditional PKWARE Decryption functions.
- */
-
-static void
-trad_enc_update_keys(struct trad_enc_ctx *ctx, uint8_t c)
-{
- uint8_t t;
-#define CRC32(c, b) (crc32(c ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL)
-
- ctx->keys[0] = CRC32(ctx->keys[0], c);
- ctx->keys[1] = (ctx->keys[1] + (ctx->keys[0] & 0xff)) * 134775813L + 1;
- t = (ctx->keys[1] >> 24) & 0xff;
- ctx->keys[2] = CRC32(ctx->keys[2], t);
-#undef CRC32
-}
-
-static uint8_t
-trad_enc_decrypt_byte(struct trad_enc_ctx *ctx)
-{
- unsigned temp = ctx->keys[2] | 2;
- return (uint8_t)((temp * (temp ^ 1)) >> 8) & 0xff;
-}
-
-static void
-trad_enc_decrypt_update(struct trad_enc_ctx *ctx, const uint8_t *in,
- size_t in_len, uint8_t *out, size_t out_len)
-{
- unsigned i, max;
-
- max = (unsigned)((in_len < out_len)? in_len: out_len);
-
- for (i = 0; i < max; i++) {
- uint8_t t = in[i] ^ trad_enc_decrypt_byte(ctx);
- out[i] = t;
- trad_enc_update_keys(ctx, t);
- }
-}
-
-static int
-trad_enc_init(struct trad_enc_ctx *ctx, const char *pw, size_t pw_len,
- const uint8_t *key, size_t key_len, uint8_t *crcchk)
-{
- uint8_t header[12];
-
- if (key_len < 12) {
- *crcchk = 0xff;
- return -1;
- }
-
- ctx->keys[0] = 305419896L;
- ctx->keys[1] = 591751049L;
- ctx->keys[2] = 878082192L;
-
- for (;pw_len; --pw_len)
- trad_enc_update_keys(ctx, *pw++);
-
- trad_enc_decrypt_update(ctx, key, 12, header, 12);
- /* Return the last byte for CRC check. */
- *crcchk = header[11];
- return 0;
-}
-
-#if 0
-static void
-crypt_derive_key_sha1(const void *p, int size, unsigned char *key,
- int key_size)
-{
-#define MD_SIZE 20
- archive_sha1_ctx ctx;
- unsigned char md1[MD_SIZE];
- unsigned char md2[MD_SIZE * 2];
- unsigned char mkb[64];
- int i;
-
- archive_sha1_init(&ctx);
- archive_sha1_update(&ctx, p, size);
- archive_sha1_final(&ctx, md1);
-
- memset(mkb, 0x36, sizeof(mkb));
- for (i = 0; i < MD_SIZE; i++)
- mkb[i] ^= md1[i];
- archive_sha1_init(&ctx);
- archive_sha1_update(&ctx, mkb, sizeof(mkb));
- archive_sha1_final(&ctx, md2);
-
- memset(mkb, 0x5C, sizeof(mkb));
- for (i = 0; i < MD_SIZE; i++)
- mkb[i] ^= md1[i];
- archive_sha1_init(&ctx);
- archive_sha1_update(&ctx, mkb, sizeof(mkb));
- archive_sha1_final(&ctx, md2 + MD_SIZE);
-
- if (key_size > 32)
- key_size = 32;
- memcpy(key, md2, key_size);
-#undef MD_SIZE
-}
-#endif
-
-/*
- * Common code for streaming or seeking modes.
- *
- * Includes code to read local file headers, decompress data
- * from entry bodies, and common API.
- */
-
-static unsigned long
-real_crc32(unsigned long crc, const void *buff, size_t len)
-{
- return crc32(crc, buff, (unsigned int)len);
-}
-
-/* Used by "ignorecrc32" option to speed up tests. */
-static unsigned long
-fake_crc32(unsigned long crc, const void *buff, size_t len)
-{
- (void)crc; /* UNUSED */
- (void)buff; /* UNUSED */
- (void)len; /* UNUSED */
- return 0;
-}
-
-static const struct {
- int id;
- const char * name;
-} compression_methods[] = {
- {0, "uncompressed"}, /* The file is stored (no compression) */
- {1, "shrinking"}, /* The file is Shrunk */
- {2, "reduced-1"}, /* The file is Reduced with compression factor 1 */
- {3, "reduced-2"}, /* The file is Reduced with compression factor 2 */
- {4, "reduced-3"}, /* The file is Reduced with compression factor 3 */
- {5, "reduced-4"}, /* The file is Reduced with compression factor 4 */
- {6, "imploded"}, /* The file is Imploded */
- {7, "reserved"}, /* Reserved for Tokenizing compression algorithm */
- {8, "deflation"}, /* The file is Deflated */
- {9, "deflation-64-bit"}, /* Enhanced Deflating using Deflate64(tm) */
- {10, "ibm-terse"},/* PKWARE Data Compression Library Imploding
- * (old IBM TERSE) */
- {11, "reserved"}, /* Reserved by PKWARE */
- {12, "bzip"}, /* File is compressed using BZIP2 algorithm */
- {13, "reserved"}, /* Reserved by PKWARE */
- {14, "lzma"}, /* LZMA (EFS) */
- {15, "reserved"}, /* Reserved by PKWARE */
- {16, "reserved"}, /* Reserved by PKWARE */
- {17, "reserved"}, /* Reserved by PKWARE */
- {18, "ibm-terse-new"}, /* File is compressed using IBM TERSE (new) */
- {19, "ibm-lz777"},/* IBM LZ77 z Architecture (PFS) */
- {93, "zstd"}, /* Zstandard (zstd) Compression */
- {95, "xz"}, /* XZ compressed data */
- {96, "jpeg"}, /* JPEG compressed data */
- {97, "wav-pack"}, /* WavPack compressed data */
- {98, "ppmd-1"}, /* PPMd version I, Rev 1 */
- {99, "aes"} /* WinZip AES encryption */
-};
-
-static const char *
-compression_name(const int compression)
-{
- static const int num_compression_methods =
- sizeof(compression_methods)/sizeof(compression_methods[0]);
- int i=0;
-
- while(compression >= 0 && i < num_compression_methods) {
- if (compression_methods[i].id == compression)
- return compression_methods[i].name;
- i++;
- }
- return "??";
-}
-
-/* Convert an MSDOS-style date/time into Unix-style time. */
-static time_t
-zip_time(const char *p)
-{
- int msTime, msDate;
- struct tm ts;
-
- msTime = (0xff & (unsigned)p[0]) + 256 * (0xff & (unsigned)p[1]);
- msDate = (0xff & (unsigned)p[2]) + 256 * (0xff & (unsigned)p[3]);
-
- memset(&ts, 0, sizeof(ts));
- ts.tm_year = ((msDate >> 9) & 0x7f) + 80; /* Years since 1900. */
- ts.tm_mon = ((msDate >> 5) & 0x0f) - 1; /* Month number. */
- ts.tm_mday = msDate & 0x1f; /* Day of month. */
- ts.tm_hour = (msTime >> 11) & 0x1f;
- ts.tm_min = (msTime >> 5) & 0x3f;
- ts.tm_sec = (msTime << 1) & 0x3e;
- ts.tm_isdst = -1;
- return mktime(&ts);
-}
-
-/*
- * The extra data is stored as a list of
- * id1+size1+data1 + id2+size2+data2 ...
- * triplets. id and size are 2 bytes each.
- */
-static int
-process_extra(struct archive_read *a, struct archive_entry *entry,
- const char *p, size_t extra_length, struct zip_entry* zip_entry)
-{
- unsigned offset = 0;
- struct zip *zip = (struct zip *)(a->format->data);
-
- if (extra_length == 0) {
- return ARCHIVE_OK;
- }
-
- if (extra_length < 4) {
- size_t i = 0;
- /* Some ZIP files may have trailing 0 bytes. Let's check they
- * are all 0 and ignore them instead of returning an error.
- *
- * This is not technically correct, but some ZIP files look
- * like this and other tools support those files - so let's
- * also support them.
- */
- for (; i < extra_length; i++) {
- if (p[i] != 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Too-small extra data: "
- "Need at least 4 bytes, "
- "but only found %d bytes",
- (int)extra_length);
- return ARCHIVE_FAILED;
- }
- }
-
- return ARCHIVE_OK;
- }
-
- while (offset <= extra_length - 4) {
- unsigned short headerid = archive_le16dec(p + offset);
- unsigned short datasize = archive_le16dec(p + offset + 2);
-
- offset += 4;
- if (offset + datasize > extra_length) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT, "Extra data overflow: "
- "Need %d bytes but only found %d bytes",
- (int)datasize, (int)(extra_length - offset));
- return ARCHIVE_FAILED;
- }
-#ifdef DEBUG
- fprintf(stderr, "Header id 0x%04x, length %d\n",
- headerid, datasize);
-#endif
- switch (headerid) {
- case 0x0001:
- /* Zip64 extended information extra field. */
- zip_entry->flags |= LA_USED_ZIP64;
- if (zip_entry->uncompressed_size == 0xffffffff) {
- uint64_t t = 0;
- if (datasize < 8
- || (t = archive_le64dec(p + offset)) >
- INT64_MAX) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Malformed 64-bit "
- "uncompressed size");
- return ARCHIVE_FAILED;
- }
- zip_entry->uncompressed_size = t;
- offset += 8;
- datasize -= 8;
- }
- if (zip_entry->compressed_size == 0xffffffff) {
- uint64_t t = 0;
- if (datasize < 8
- || (t = archive_le64dec(p + offset)) >
- INT64_MAX) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Malformed 64-bit "
- "compressed size");
- return ARCHIVE_FAILED;
- }
- zip_entry->compressed_size = t;
- offset += 8;
- datasize -= 8;
- }
- if (zip_entry->local_header_offset == 0xffffffff) {
- uint64_t t = 0;
- if (datasize < 8
- || (t = archive_le64dec(p + offset)) >
- INT64_MAX) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Malformed 64-bit "
- "local header offset");
- return ARCHIVE_FAILED;
- }
- zip_entry->local_header_offset = t;
- offset += 8;
- datasize -= 8;
- }
- /* archive_le32dec(p + offset) gives disk
- * on which file starts, but we don't handle
- * multi-volume Zip files. */
- break;
-#ifdef DEBUG
- case 0x0017:
- {
- /* Strong encryption field. */
- if (archive_le16dec(p + offset) == 2) {
- unsigned algId =
- archive_le16dec(p + offset + 2);
- unsigned bitLen =
- archive_le16dec(p + offset + 4);
- int flags =
- archive_le16dec(p + offset + 6);
- fprintf(stderr, "algId=0x%04x, bitLen=%u, "
- "flgas=%d\n", algId, bitLen,flags);
- }
- break;
- }
-#endif
- case 0x5455:
- {
- /* Extended time field "UT". */
- int flags;
- if (datasize == 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Incomplete extended time field");
- return ARCHIVE_FAILED;
- }
- flags = p[offset];
- offset++;
- datasize--;
- /* Flag bits indicate which dates are present. */
- if (flags & 0x01)
- {
-#ifdef DEBUG
- fprintf(stderr, "mtime: %lld -> %d\n",
- (long long)zip_entry->mtime,
- archive_le32dec(p + offset));
-#endif
- if (datasize < 4)
- break;
- zip_entry->mtime = archive_le32dec(p + offset);
- offset += 4;
- datasize -= 4;
- }
- if (flags & 0x02)
- {
- if (datasize < 4)
- break;
- zip_entry->atime = archive_le32dec(p + offset);
- offset += 4;
- datasize -= 4;
- }
- if (flags & 0x04)
- {
- if (datasize < 4)
- break;
- zip_entry->ctime = archive_le32dec(p + offset);
- offset += 4;
- datasize -= 4;
- }
- break;
- }
- case 0x5855:
- {
- /* Info-ZIP Unix Extra Field (old version) "UX". */
- if (datasize >= 8) {
- zip_entry->atime = archive_le32dec(p + offset);
- zip_entry->mtime =
- archive_le32dec(p + offset + 4);
- }
- if (datasize >= 12) {
- zip_entry->uid =
- archive_le16dec(p + offset + 8);
- zip_entry->gid =
- archive_le16dec(p + offset + 10);
- }
- break;
- }
- case 0x6c78:
- {
- /* Experimental 'xl' field */
- /*
- * Introduced Dec 2013 to provide a way to
- * include external file attributes (and other
- * fields that ordinarily appear only in
- * central directory) in local file header.
- * This provides file type and permission
- * information necessary to support full
- * streaming extraction. Currently being
- * discussed with other Zip developers
- * ... subject to change.
- *
- * Format:
- * The field starts with a bitmap that specifies
- * which additional fields are included. The
- * bitmap is variable length and can be extended in
- * the future.
- *
- * n bytes - feature bitmap: first byte has low-order
- * 7 bits. If high-order bit is set, a subsequent
- * byte holds the next 7 bits, etc.
- *
- * if bitmap & 1, 2 byte "version made by"
- * if bitmap & 2, 2 byte "internal file attributes"
- * if bitmap & 4, 4 byte "external file attributes"
- * if bitmap & 8, 2 byte comment length + n byte
- * comment
- */
- int bitmap, bitmap_last;
-
- if (datasize < 1)
- break;
- bitmap_last = bitmap = 0xff & p[offset];
- offset += 1;
- datasize -= 1;
-
- /* We only support first 7 bits of bitmap; skip rest. */
- while ((bitmap_last & 0x80) != 0
- && datasize >= 1) {
- bitmap_last = p[offset];
- offset += 1;
- datasize -= 1;
- }
-
- if (bitmap & 1) {
- /* 2 byte "version made by" */
- if (datasize < 2)
- break;
- zip_entry->system
- = archive_le16dec(p + offset) >> 8;
- offset += 2;
- datasize -= 2;
- }
- if (bitmap & 2) {
- /* 2 byte "internal file attributes" */
- uint32_t internal_attributes;
- if (datasize < 2)
- break;
- internal_attributes
- = archive_le16dec(p + offset);
- /* Not used by libarchive at present. */
- (void)internal_attributes; /* UNUSED */
- offset += 2;
- datasize -= 2;
- }
- if (bitmap & 4) {
- /* 4 byte "external file attributes" */
- uint32_t external_attributes;
- if (datasize < 4)
- break;
- external_attributes
- = archive_le32dec(p + offset);
- if (zip_entry->system == 3) {
- zip_entry->mode
- = external_attributes >> 16;
- } else if (zip_entry->system == 0) {
- // Interpret MSDOS directory bit
- if (0x10 == (external_attributes &
- 0x10)) {
- zip_entry->mode =
- AE_IFDIR | 0775;
- } else {
- zip_entry->mode =
- AE_IFREG | 0664;
- }
- if (0x01 == (external_attributes &
- 0x01)) {
- /* Read-only bit;
- * strip write permissions */
- zip_entry->mode &= 0555;
- }
- } else {
- zip_entry->mode = 0;
- }
- offset += 4;
- datasize -= 4;
- }
- if (bitmap & 8) {
- /* 2 byte comment length + comment */
- uint32_t comment_length;
- if (datasize < 2)
- break;
- comment_length
- = archive_le16dec(p + offset);
- offset += 2;
- datasize -= 2;
-
- if (datasize < comment_length)
- break;
- /* Comment is not supported by libarchive */
- offset += comment_length;
- datasize -= comment_length;
- }
- break;
- }
- case 0x7075:
- {
- /* Info-ZIP Unicode Path Extra Field. */
- if (datasize < 5 || entry == NULL)
- break;
- offset += 5;
- datasize -= 5;
-
- /* The path name in this field is always encoded
- * in UTF-8. */
- if (zip->sconv_utf8 == NULL) {
- zip->sconv_utf8 =
- archive_string_conversion_from_charset(
- &a->archive, "UTF-8", 1);
- /* If the converter from UTF-8 is not
- * available, then the path name from the main
- * field will more likely be correct. */
- if (zip->sconv_utf8 == NULL)
- break;
- }
-
- /* Make sure the CRC32 of the filename matches. */
- if (!zip->ignore_crc32) {
- const char *cp = archive_entry_pathname(entry);
- if (cp) {
- unsigned long file_crc =
- zip->crc32func(0, cp, strlen(cp));
- unsigned long utf_crc =
- archive_le32dec(p + offset - 4);
- if (file_crc != utf_crc) {
-#ifdef DEBUG
- fprintf(stderr,
- "CRC filename mismatch; "
- "CDE is %lx, but UTF8 "
- "is outdated with %lx\n",
- file_crc, utf_crc);
-#endif
- break;
- }
- }
- }
-
- if (archive_entry_copy_pathname_l(entry,
- p + offset, datasize, zip->sconv_utf8) != 0) {
- /* Ignore the error, and fallback to the path
- * name from the main field. */
-#ifdef DEBUG
- fprintf(stderr, "Failed to read the ZIP "
- "0x7075 extra field path.\n");
-#endif
- }
- break;
- }
- case 0x7855:
- /* Info-ZIP Unix Extra Field (type 2) "Ux". */
-#ifdef DEBUG
- fprintf(stderr, "uid %d gid %d\n",
- archive_le16dec(p + offset),
- archive_le16dec(p + offset + 2));
-#endif
- if (datasize >= 2)
- zip_entry->uid = archive_le16dec(p + offset);
- if (datasize >= 4)
- zip_entry->gid =
- archive_le16dec(p + offset + 2);
- break;
- case 0x7875:
- {
- /* Info-Zip Unix Extra Field (type 3) "ux". */
- int uidsize = 0, gidsize = 0;
-
- /* TODO: support arbitrary uidsize/gidsize. */
- if (datasize >= 1 && p[offset] == 1) {/* version=1 */
- if (datasize >= 4) {
- /* get a uid size. */
- uidsize = 0xff & (int)p[offset+1];
- if (uidsize == 2)
- zip_entry->uid =
- archive_le16dec(
- p + offset + 2);
- else if (uidsize == 4 && datasize >= 6)
- zip_entry->uid =
- archive_le32dec(
- p + offset + 2);
- }
- if (datasize >= (2 + uidsize + 3)) {
- /* get a gid size. */
- gidsize = 0xff &
- (int)p[offset+2+uidsize];
- if (gidsize == 2)
- zip_entry->gid =
- archive_le16dec(
- p+offset+2+uidsize+1);
- else if (gidsize == 4 &&
- datasize >= (2 + uidsize + 5))
- zip_entry->gid =
- archive_le32dec(
- p+offset+2+uidsize+1);
- }
- }
- break;
- }
- case 0x9901:
- /* WinZip AES extra data field. */
- if (datasize < 6) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Incomplete AES field");
- return ARCHIVE_FAILED;
- }
- if (p[offset + 2] == 'A' && p[offset + 3] == 'E') {
- /* Vendor version. */
- zip_entry->aes_extra.vendor =
- archive_le16dec(p + offset);
- /* AES encryption strength. */
- zip_entry->aes_extra.strength = p[offset + 4];
- /* Actual compression method. */
- zip_entry->aes_extra.compression =
- p[offset + 5];
- }
- break;
- default:
- break;
- }
- offset += datasize;
- }
- return ARCHIVE_OK;
-}
-
-/*
- * Assumes file pointer is at beginning of local file header.
- */
-static int
-zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
- struct zip *zip)
-{
- const char *p;
- const void *h;
- const wchar_t *wp;
- const char *cp;
- size_t len, filename_length, extra_length;
- struct archive_string_conv *sconv;
- struct zip_entry *zip_entry = zip->entry;
- struct zip_entry zip_entry_central_dir;
- int ret = ARCHIVE_OK;
- char version;
-
- /* Save a copy of the original for consistency checks. */
- zip_entry_central_dir = *zip_entry;
-
- zip->decompress_init = 0;
- zip->end_of_entry = 0;
- zip->entry_uncompressed_bytes_read = 0;
- zip->entry_compressed_bytes_read = 0;
- zip->entry_crc32 = zip->crc32func(0, NULL, 0);
-
- /* Setup default conversion. */
- if (zip->sconv == NULL && !zip->init_default_conversion) {
- zip->sconv_default =
- archive_string_default_conversion_for_read(&(a->archive));
- zip->init_default_conversion = 1;
- }
-
- if ((p = __archive_read_ahead(a, 30, NULL)) == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated ZIP file header");
- return (ARCHIVE_FATAL);
- }
-
- if (memcmp(p, "PK\003\004", 4) != 0) {
- archive_set_error(&a->archive, -1, "Damaged Zip archive");
- return ARCHIVE_FATAL;
- }
- version = p[4];
- zip_entry->system = p[5];
- zip_entry->zip_flags = archive_le16dec(p + 6);
- if (zip_entry->zip_flags & (ZIP_ENCRYPTED | ZIP_STRONG_ENCRYPTED)) {
- zip->has_encrypted_entries = 1;
- archive_entry_set_is_data_encrypted(entry, 1);
- if (zip_entry->zip_flags & ZIP_CENTRAL_DIRECTORY_ENCRYPTED &&
- zip_entry->zip_flags & ZIP_ENCRYPTED &&
- zip_entry->zip_flags & ZIP_STRONG_ENCRYPTED) {
- archive_entry_set_is_metadata_encrypted(entry, 1);
- return ARCHIVE_FATAL;
- }
- }
- zip->init_decryption = (zip_entry->zip_flags & ZIP_ENCRYPTED);
- zip_entry->compression = (char)archive_le16dec(p + 8);
- zip_entry->mtime = zip_time(p + 10);
- zip_entry->crc32 = archive_le32dec(p + 14);
- if (zip_entry->zip_flags & ZIP_LENGTH_AT_END)
- zip_entry->decdat = p[11];
- else
- zip_entry->decdat = p[17];
- zip_entry->compressed_size = archive_le32dec(p + 18);
- zip_entry->uncompressed_size = archive_le32dec(p + 22);
- filename_length = archive_le16dec(p + 26);
- extra_length = archive_le16dec(p + 28);
-
- __archive_read_consume(a, 30);
-
- /* Read the filename. */
- if ((h = __archive_read_ahead(a, filename_length, NULL)) == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated ZIP file header");
- return (ARCHIVE_FATAL);
- }
- if (zip_entry->zip_flags & ZIP_UTF8_NAME) {
- /* The filename is stored to be UTF-8. */
- if (zip->sconv_utf8 == NULL) {
- zip->sconv_utf8 =
- archive_string_conversion_from_charset(
- &a->archive, "UTF-8", 1);
- if (zip->sconv_utf8 == NULL)
- return (ARCHIVE_FATAL);
- }
- sconv = zip->sconv_utf8;
- } else if (zip->sconv != NULL)
- sconv = zip->sconv;
- else
- sconv = zip->sconv_default;
-
- if (archive_entry_copy_pathname_l(entry,
- h, filename_length, sconv) != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Pathname cannot be converted "
- "from %s to current locale.",
- archive_string_conversion_charset_name(sconv));
- ret = ARCHIVE_WARN;
- }
- __archive_read_consume(a, filename_length);
-
- /* Read the extra data. */
- if ((h = __archive_read_ahead(a, extra_length, NULL)) == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated ZIP file header");
- return (ARCHIVE_FATAL);
- }
-
- if (ARCHIVE_OK != process_extra(a, entry, h, extra_length,
- zip_entry)) {
- return ARCHIVE_FATAL;
- }
- __archive_read_consume(a, extra_length);
-
- /* Work around a bug in Info-Zip: When reading from a pipe, it
- * stats the pipe instead of synthesizing a file entry. */
- if ((zip_entry->mode & AE_IFMT) == AE_IFIFO) {
- zip_entry->mode &= ~ AE_IFMT;
- zip_entry->mode |= AE_IFREG;
- }
-
- /* If the mode is totally empty, set some sane default. */
- if (zip_entry->mode == 0) {
- zip_entry->mode |= 0664;
- }
-
- /* Windows archivers sometimes use backslash as the directory
- * separator. Normalize to slash. */
- if (zip_entry->system == 0 &&
- (wp = archive_entry_pathname_w(entry)) != NULL) {
- if (wcschr(wp, L'/') == NULL && wcschr(wp, L'\\') != NULL) {
- size_t i;
- struct archive_wstring s;
- archive_string_init(&s);
- archive_wstrcpy(&s, wp);
- for (i = 0; i < archive_strlen(&s); i++) {
- if (s.s[i] == '\\')
- s.s[i] = '/';
- }
- archive_entry_copy_pathname_w(entry, s.s);
- archive_wstring_free(&s);
- }
- }
-
- /* Make sure that entries with a trailing '/' are marked as directories
- * even if the External File Attributes contains bogus values. If this
- * is not a directory and there is no type, assume a regular file. */
- if ((zip_entry->mode & AE_IFMT) != AE_IFDIR) {
- int has_slash;
-
- wp = archive_entry_pathname_w(entry);
- if (wp != NULL) {
- len = wcslen(wp);
- has_slash = len > 0 && wp[len - 1] == L'/';
- } else {
- cp = archive_entry_pathname(entry);
- len = (cp != NULL)?strlen(cp):0;
- has_slash = len > 0 && cp[len - 1] == '/';
- }
- /* Correct file type as needed. */
- if (has_slash) {
- zip_entry->mode &= ~AE_IFMT;
- zip_entry->mode |= AE_IFDIR;
- zip_entry->mode |= 0111;
- } else if ((zip_entry->mode & AE_IFMT) == 0) {
- zip_entry->mode |= AE_IFREG;
- }
- }
-
- /* Make sure directories end in '/' */
- if ((zip_entry->mode & AE_IFMT) == AE_IFDIR) {
- wp = archive_entry_pathname_w(entry);
- if (wp != NULL) {
- len = wcslen(wp);
- if (len > 0 && wp[len - 1] != L'/') {
- struct archive_wstring s;
- archive_string_init(&s);
- archive_wstrcat(&s, wp);
- archive_wstrappend_wchar(&s, L'/');
- archive_entry_copy_pathname_w(entry, s.s);
- archive_wstring_free(&s);
- }
- } else {
- cp = archive_entry_pathname(entry);
- len = (cp != NULL)?strlen(cp):0;
- if (len > 0 && cp[len - 1] != '/') {
- struct archive_string s;
- archive_string_init(&s);
- archive_strcat(&s, cp);
- archive_strappend_char(&s, '/');
- archive_entry_set_pathname(entry, s.s);
- archive_string_free(&s);
- }
- }
- }
-
- if (zip_entry->flags & LA_FROM_CENTRAL_DIRECTORY) {
- /* If this came from the central dir, its size info
- * is definitive, so ignore the length-at-end flag. */
- zip_entry->zip_flags &= ~ZIP_LENGTH_AT_END;
- /* If local header is missing a value, use the one from
- the central directory. If both have it, warn about
- mismatches. */
- if (zip_entry->crc32 == 0) {
- zip_entry->crc32 = zip_entry_central_dir.crc32;
- } else if (!zip->ignore_crc32
- && zip_entry->crc32 != zip_entry_central_dir.crc32) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Inconsistent CRC32 values");
- ret = ARCHIVE_WARN;
- }
- if (zip_entry->compressed_size == 0) {
- zip_entry->compressed_size
- = zip_entry_central_dir.compressed_size;
- } else if (zip_entry->compressed_size
- != zip_entry_central_dir.compressed_size) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Inconsistent compressed size: "
- "%jd in central directory, %jd in local header",
- (intmax_t)zip_entry_central_dir.compressed_size,
- (intmax_t)zip_entry->compressed_size);
- ret = ARCHIVE_WARN;
- }
- if (zip_entry->uncompressed_size == 0 ||
- zip_entry->uncompressed_size == 0xffffffff) {
- zip_entry->uncompressed_size
- = zip_entry_central_dir.uncompressed_size;
- } else if (zip_entry->uncompressed_size
- != zip_entry_central_dir.uncompressed_size) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Inconsistent uncompressed size: "
- "%jd in central directory, %jd in local header",
- (intmax_t)zip_entry_central_dir.uncompressed_size,
- (intmax_t)zip_entry->uncompressed_size);
- ret = ARCHIVE_WARN;
- }
- }
-
- /* Populate some additional entry fields: */
- archive_entry_set_mode(entry, zip_entry->mode);
- archive_entry_set_uid(entry, zip_entry->uid);
- archive_entry_set_gid(entry, zip_entry->gid);
- archive_entry_set_mtime(entry, zip_entry->mtime, 0);
- archive_entry_set_ctime(entry, zip_entry->ctime, 0);
- archive_entry_set_atime(entry, zip_entry->atime, 0);
-
- if ((zip->entry->mode & AE_IFMT) == AE_IFLNK) {
- size_t linkname_length;
-
- if (zip_entry->compressed_size > 64 * 1024) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Zip file with oversized link entry");
- return ARCHIVE_FATAL;
- }
-
- linkname_length = (size_t)zip_entry->compressed_size;
-
- archive_entry_set_size(entry, 0);
-
- // take into account link compression if any
- size_t linkname_full_length = linkname_length;
- if (zip->entry->compression != 0)
- {
- // symlink target string appeared to be compressed
- int status = ARCHIVE_FATAL;
- const void *uncompressed_buffer = NULL;
-
- switch (zip->entry->compression)
- {
-#if HAVE_ZLIB_H
- case 8: /* Deflate compression. */
- zip->entry_bytes_remaining = zip_entry->compressed_size;
- status = zip_read_data_deflate(a, &uncompressed_buffer,
- &linkname_full_length, NULL);
- break;
-#endif
-#if HAVE_LZMA_H && HAVE_LIBLZMA
- case 14: /* ZIPx LZMA compression. */
- /*(see zip file format specification, section 4.4.5)*/
- zip->entry_bytes_remaining = zip_entry->compressed_size;
- status = zip_read_data_zipx_lzma_alone(a, &uncompressed_buffer,
- &linkname_full_length, NULL);
- break;
-#endif
- default: /* Unsupported compression. */
- break;
- }
- if (status == ARCHIVE_OK)
- {
- p = uncompressed_buffer;
- }
- else
- {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Unsupported ZIP compression method "
- "during decompression of link entry (%d: %s)",
- zip->entry->compression,
- compression_name(zip->entry->compression));
- return ARCHIVE_FAILED;
- }
- }
- else
- {
- p = __archive_read_ahead(a, linkname_length, NULL);
- }
-
- if (p == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Truncated Zip file");
- return ARCHIVE_FATAL;
- }
-
- sconv = zip->sconv;
- if (sconv == NULL && (zip->entry->zip_flags & ZIP_UTF8_NAME))
- sconv = zip->sconv_utf8;
- if (sconv == NULL)
- sconv = zip->sconv_default;
- if (archive_entry_copy_symlink_l(entry, p, linkname_full_length,
- sconv) != 0) {
- if (errno != ENOMEM && sconv == zip->sconv_utf8 &&
- (zip->entry->zip_flags & ZIP_UTF8_NAME))
- archive_entry_copy_symlink_l(entry, p,
- linkname_full_length, NULL);
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Symlink");
- return (ARCHIVE_FATAL);
- }
- /*
- * Since there is no character-set regulation for
- * symlink name, do not report the conversion error
- * in an automatic conversion.
- */
- if (sconv != zip->sconv_utf8 ||
- (zip->entry->zip_flags & ZIP_UTF8_NAME) == 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Symlink cannot be converted "
- "from %s to current locale.",
- archive_string_conversion_charset_name(
- sconv));
- ret = ARCHIVE_WARN;
- }
- }
- zip_entry->uncompressed_size = zip_entry->compressed_size = 0;
-
- if (__archive_read_consume(a, linkname_length) < 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Read error skipping symlink target name");
- return ARCHIVE_FATAL;
- }
- } else if (0 == (zip_entry->zip_flags & ZIP_LENGTH_AT_END)
- || zip_entry->uncompressed_size > 0) {
- /* Set the size only if it's meaningful. */
- archive_entry_set_size(entry, zip_entry->uncompressed_size);
- }
- zip->entry_bytes_remaining = zip_entry->compressed_size;
-
- /* If there's no body, force read_data() to return EOF immediately. */
- if (0 == (zip_entry->zip_flags & ZIP_LENGTH_AT_END)
- && zip->entry_bytes_remaining < 1)
- zip->end_of_entry = 1;
-
- /* Set up a more descriptive format name. */
- archive_string_empty(&zip->format_name);
- archive_string_sprintf(&zip->format_name, "ZIP %d.%d (%s)",
- version / 10, version % 10,
- compression_name(zip->entry->compression));
- a->archive.archive_format_name = zip->format_name.s;
-
- return (ret);
-}
-
-static int
-check_authentication_code(struct archive_read *a, const void *_p)
-{
- struct zip *zip = (struct zip *)(a->format->data);
-
- /* Check authentication code. */
- if (zip->hctx_valid) {
- const void *p;
- uint8_t hmac[20];
- size_t hmac_len = 20;
- int cmp;
-
- archive_hmac_sha1_final(&zip->hctx, hmac, &hmac_len);
- if (_p == NULL) {
- /* Read authentication code. */
- p = __archive_read_ahead(a, AUTH_CODE_SIZE, NULL);
- if (p == NULL) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated ZIP file data");
- return (ARCHIVE_FATAL);
- }
- } else {
- p = _p;
- }
- cmp = memcmp(hmac, p, AUTH_CODE_SIZE);
- __archive_read_consume(a, AUTH_CODE_SIZE);
- if (cmp != 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "ZIP bad Authentication code");
- return (ARCHIVE_WARN);
- }
- }
- return (ARCHIVE_OK);
-}
-
-/*
- * Read "uncompressed" data. There are three cases:
- * 1) We know the size of the data. This is always true for the
- * seeking reader (we've examined the Central Directory already).
- * 2) ZIP_LENGTH_AT_END was set, but only the CRC was deferred.
- * Info-ZIP seems to do this; we know the size but have to grab
- * the CRC from the data descriptor afterwards.
- * 3) We're streaming and ZIP_LENGTH_AT_END was specified and
- * we have no size information. In this case, we can do pretty
- * well by watching for the data descriptor record. The data
- * descriptor is 16 bytes and includes a computed CRC that should
- * provide a strong check.
- *
- * TODO: Technically, the PK\007\010 signature is optional.
- * In the original spec, the data descriptor contained CRC
- * and size fields but had no leading signature. In practice,
- * newer writers seem to provide the signature pretty consistently.
- *
- * For uncompressed data, the PK\007\010 marker seems essential
- * to be sure we've actually seen the end of the entry.
- *
- * Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets
- * zip->end_of_entry if it consumes all of the data.
- */
-static int
-zip_read_data_none(struct archive_read *a, const void **_buff,
- size_t *size, int64_t *offset)
-{
- struct zip *zip;
- const char *buff;
- ssize_t bytes_avail;
- int r;
-
- (void)offset; /* UNUSED */
-
- zip = (struct zip *)(a->format->data);
-
- if (zip->entry->zip_flags & ZIP_LENGTH_AT_END) {
- const char *p;
- ssize_t grabbing_bytes = 24;
-
- if (zip->hctx_valid)
- grabbing_bytes += AUTH_CODE_SIZE;
- /* Grab at least 24 bytes. */
- buff = __archive_read_ahead(a, grabbing_bytes, &bytes_avail);
- if (bytes_avail < grabbing_bytes) {
- /* Zip archives have end-of-archive markers
- that are longer than this, so a failure to get at
- least 24 bytes really does indicate a truncated
- file. */
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated ZIP file data");
- return (ARCHIVE_FATAL);
- }
- /* Check for a complete PK\007\010 signature, followed
- * by the correct 4-byte CRC. */
- p = buff;
- if (zip->hctx_valid)
- p += AUTH_CODE_SIZE;
- if (p[0] == 'P' && p[1] == 'K'
- && p[2] == '\007' && p[3] == '\010'
- && (archive_le32dec(p + 4) == zip->entry_crc32
- || zip->ignore_crc32
- || (zip->hctx_valid
- && zip->entry->aes_extra.vendor == AES_VENDOR_AE_2))) {
- if (zip->entry->flags & LA_USED_ZIP64) {
- uint64_t compressed, uncompressed;
- zip->entry->crc32 = archive_le32dec(p + 4);
- compressed = archive_le64dec(p + 8);
- uncompressed = archive_le64dec(p + 16);
- if (compressed > INT64_MAX || uncompressed >
- INT64_MAX) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Overflow of 64-bit file sizes");
- return ARCHIVE_FAILED;
- }
- zip->entry->compressed_size = compressed;
- zip->entry->uncompressed_size = uncompressed;
- zip->unconsumed = 24;
- } else {
- zip->entry->crc32 = archive_le32dec(p + 4);
- zip->entry->compressed_size =
- archive_le32dec(p + 8);
- zip->entry->uncompressed_size =
- archive_le32dec(p + 12);
- zip->unconsumed = 16;
- }
- if (zip->hctx_valid) {
- r = check_authentication_code(a, buff);
- if (r != ARCHIVE_OK)
- return (r);
- }
- zip->end_of_entry = 1;
- return (ARCHIVE_OK);
- }
- /* If not at EOF, ensure we consume at least one byte. */
- ++p;
-
- /* Scan forward until we see where a PK\007\010 signature
- * might be. */
- /* Return bytes up until that point. On the next call,
- * the code above will verify the data descriptor. */
- while (p < buff + bytes_avail - 4) {
- if (p[3] == 'P') { p += 3; }
- else if (p[3] == 'K') { p += 2; }
- else if (p[3] == '\007') { p += 1; }
- else if (p[3] == '\010' && p[2] == '\007'
- && p[1] == 'K' && p[0] == 'P') {
- if (zip->hctx_valid)
- p -= AUTH_CODE_SIZE;
- break;
- } else { p += 4; }
- }
- bytes_avail = p - buff;
- } else {
- if (zip->entry_bytes_remaining == 0) {
- zip->end_of_entry = 1;
- if (zip->hctx_valid) {
- r = check_authentication_code(a, NULL);
- if (r != ARCHIVE_OK)
- return (r);
- }
- return (ARCHIVE_OK);
- }
- /* Grab a bunch of bytes. */
- buff = __archive_read_ahead(a, 1, &bytes_avail);
- if (bytes_avail <= 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated ZIP file data");
- return (ARCHIVE_FATAL);
- }
- if (bytes_avail > zip->entry_bytes_remaining)
- bytes_avail = (ssize_t)zip->entry_bytes_remaining;
- }
- if (zip->tctx_valid || zip->cctx_valid) {
- size_t dec_size = bytes_avail;
-
- if (dec_size > zip->decrypted_buffer_size)
- dec_size = zip->decrypted_buffer_size;
- if (zip->tctx_valid) {
- trad_enc_decrypt_update(&zip->tctx,
- (const uint8_t *)buff, dec_size,
- zip->decrypted_buffer, dec_size);
- } else {
- size_t dsize = dec_size;
- archive_hmac_sha1_update(&zip->hctx,
- (const uint8_t *)buff, dec_size);
- archive_decrypto_aes_ctr_update(&zip->cctx,
- (const uint8_t *)buff, dec_size,
- zip->decrypted_buffer, &dsize);
- }
- bytes_avail = dec_size;
- buff = (const char *)zip->decrypted_buffer;
- }
- *size = bytes_avail;
- zip->entry_bytes_remaining -= bytes_avail;
- zip->entry_uncompressed_bytes_read += bytes_avail;
- zip->entry_compressed_bytes_read += bytes_avail;
- zip->unconsumed += bytes_avail;
- *_buff = buff;
- return (ARCHIVE_OK);
-}
-
-static int
-consume_optional_marker(struct archive_read *a, struct zip *zip)
-{
- if (zip->end_of_entry && (zip->entry->zip_flags & ZIP_LENGTH_AT_END)) {
- const char *p;
-
- if (NULL == (p = __archive_read_ahead(a, 24, NULL))) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated ZIP end-of-file record");
- return (ARCHIVE_FATAL);
- }
- /* Consume the optional PK\007\010 marker. */
- if (p[0] == 'P' && p[1] == 'K' &&
- p[2] == '\007' && p[3] == '\010') {
- p += 4;
- zip->unconsumed = 4;
- }
- if (zip->entry->flags & LA_USED_ZIP64) {
- uint64_t compressed, uncompressed;
- zip->entry->crc32 = archive_le32dec(p);
- compressed = archive_le64dec(p + 4);
- uncompressed = archive_le64dec(p + 12);
- if (compressed > INT64_MAX ||
- uncompressed > INT64_MAX) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Overflow of 64-bit file sizes");
- return ARCHIVE_FAILED;
- }
- zip->entry->compressed_size = compressed;
- zip->entry->uncompressed_size = uncompressed;
- zip->unconsumed += 20;
- } else {
- zip->entry->crc32 = archive_le32dec(p);
- zip->entry->compressed_size = archive_le32dec(p + 4);
- zip->entry->uncompressed_size = archive_le32dec(p + 8);
- zip->unconsumed += 12;
- }
- }
-
- return (ARCHIVE_OK);
-}
-
-#if HAVE_LZMA_H && HAVE_LIBLZMA
-static int
-zipx_xz_init(struct archive_read *a, struct zip *zip)
-{
- lzma_ret r;
-
- if(zip->zipx_lzma_valid) {
- lzma_end(&zip->zipx_lzma_stream);
- zip->zipx_lzma_valid = 0;
- }
-
- memset(&zip->zipx_lzma_stream, 0, sizeof(zip->zipx_lzma_stream));
- r = lzma_stream_decoder(&zip->zipx_lzma_stream, UINT64_MAX, 0);
- if (r != LZMA_OK) {
- archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
- "xz initialization failed(%d)",
- r);
-
- return (ARCHIVE_FAILED);
- }
-
- zip->zipx_lzma_valid = 1;
-
- free(zip->uncompressed_buffer);
-
- zip->uncompressed_buffer_size = 256 * 1024;
- zip->uncompressed_buffer =
- (uint8_t*) malloc(zip->uncompressed_buffer_size);
- if (zip->uncompressed_buffer == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for xz decompression");
- return (ARCHIVE_FATAL);
- }
-
- zip->decompress_init = 1;
- return (ARCHIVE_OK);
-}
-
-static int
-zipx_lzma_alone_init(struct archive_read *a, struct zip *zip)
-{
- lzma_ret r;
- const uint8_t* p;
-
-#pragma pack(push)
-#pragma pack(1)
- struct _alone_header {
- uint8_t bytes[5];
- uint64_t uncompressed_size;
- } alone_header;
-#pragma pack(pop)
-
- if(zip->zipx_lzma_valid) {
- lzma_end(&zip->zipx_lzma_stream);
- zip->zipx_lzma_valid = 0;
- }
-
- /* To unpack ZIPX's "LZMA" (id 14) stream we can use standard liblzma
- * that is a part of XZ Utils. The stream format stored inside ZIPX
- * file is a modified "lzma alone" file format, that was used by the
- * `lzma` utility which was later deprecated in favour of `xz` utility.
- * Since those formats are nearly the same, we can use a standard
- * "lzma alone" decoder from XZ Utils. */
-
- memset(&zip->zipx_lzma_stream, 0, sizeof(zip->zipx_lzma_stream));
- r = lzma_alone_decoder(&zip->zipx_lzma_stream, UINT64_MAX);
- if (r != LZMA_OK) {
- archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
- "lzma initialization failed(%d)", r);
-
- return (ARCHIVE_FAILED);
- }
-
- /* Flag the cleanup function that we want our lzma-related structures
- * to be freed later. */
- zip->zipx_lzma_valid = 1;
-
- /* The "lzma alone" file format and the stream format inside ZIPx are
- * almost the same. Here's an example of a structure of "lzma alone"
- * format:
- *
- * $ cat /bin/ls | lzma | xxd | head -n 1
- * 00000000: 5d00 0080 00ff ffff ffff ffff ff00 2814
- *
- * 5 bytes 8 bytes n bytes
- * <lzma_params><uncompressed_size><data...>
- *
- * lzma_params is a 5-byte blob that has to be decoded to extract
- * parameters of this LZMA stream. The uncompressed_size field is an
- * uint64_t value that contains information about the size of the
- * uncompressed file, or UINT64_MAX if this value is unknown.
- * The <data...> part is the actual lzma-compressed data stream.
- *
- * Now here's the structure of the stream inside the ZIPX file:
- *
- * $ cat stream_inside_zipx | xxd | head -n 1
- * 00000000: 0914 0500 5d00 8000 0000 2814 .... ....
- *
- * 2byte 2byte 5 bytes n bytes
- * <magic1><magic2><lzma_params><data...>
- *
- * This means that the ZIPX file contains an additional magic1 and
- * magic2 headers, the lzma_params field contains the same parameter
- * set as in the "lzma alone" format, and the <data...> field is the
- * same as in the "lzma alone" format as well. Note that also the zipx
- * format is missing the uncompressed_size field.
- *
- * So, in order to use the "lzma alone" decoder for the zipx lzma
- * stream, we simply need to shuffle around some fields, prepare a new
- * lzma alone header, feed it into lzma alone decoder so it will
- * initialize itself properly, and then we can start feeding normal
- * zipx lzma stream into the decoder.
- */
-
- /* Read magic1,magic2,lzma_params from the ZIPX stream. */
- if(zip->entry_bytes_remaining < 9 || (p = __archive_read_ahead(a, 9, NULL)) == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated lzma data");
- return (ARCHIVE_FATAL);
- }
-
- if(p[2] != 0x05 || p[3] != 0x00) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid lzma data");
- return (ARCHIVE_FATAL);
- }
-
- /* Prepare an lzma alone header: copy the lzma_params blob into
- * a proper place into the lzma alone header. */
- memcpy(&alone_header.bytes[0], p + 4, 5);
-
- /* Initialize the 'uncompressed size' field to unknown; we'll manually
- * monitor how many bytes there are still to be uncompressed. */
- alone_header.uncompressed_size = UINT64_MAX;
-
- if(!zip->uncompressed_buffer) {
- zip->uncompressed_buffer_size = 256 * 1024;
- zip->uncompressed_buffer =
- (uint8_t*) malloc(zip->uncompressed_buffer_size);
-
- if (zip->uncompressed_buffer == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for lzma decompression");
- return (ARCHIVE_FATAL);
- }
- }
-
- zip->zipx_lzma_stream.next_in = (void*) &alone_header;
- zip->zipx_lzma_stream.avail_in = sizeof(alone_header);
- zip->zipx_lzma_stream.total_in = 0;
- zip->zipx_lzma_stream.next_out = zip->uncompressed_buffer;
- zip->zipx_lzma_stream.avail_out = zip->uncompressed_buffer_size;
- zip->zipx_lzma_stream.total_out = 0;
-
- /* Feed only the header into the lzma alone decoder. This will
- * effectively initialize the decoder, and will not produce any
- * output bytes yet. */
- r = lzma_code(&zip->zipx_lzma_stream, LZMA_RUN);
- if (r != LZMA_OK) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "lzma stream initialization error");
- return ARCHIVE_FATAL;
- }
-
- /* We've already consumed some bytes, so take this into account. */
- __archive_read_consume(a, 9);
- zip->entry_bytes_remaining -= 9;
- zip->entry_compressed_bytes_read += 9;
-
- zip->decompress_init = 1;
- return (ARCHIVE_OK);
-}
-
-static int
-zip_read_data_zipx_xz(struct archive_read *a, const void **buff,
- size_t *size, int64_t *offset)
-{
- struct zip* zip = (struct zip *)(a->format->data);
- int ret;
- lzma_ret lz_ret;
- const void* compressed_buf;
- ssize_t bytes_avail, in_bytes, to_consume = 0;
-
- (void) offset; /* UNUSED */
-
- /* Initialize decompressor if not yet initialized. */
- if (!zip->decompress_init) {
- ret = zipx_xz_init(a, zip);
- if (ret != ARCHIVE_OK)
- return (ret);
- }
-
- compressed_buf = __archive_read_ahead(a, 1, &bytes_avail);
- if (bytes_avail < 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated xz file body");
- return (ARCHIVE_FATAL);
- }
-
- in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
- zip->zipx_lzma_stream.next_in = compressed_buf;
- zip->zipx_lzma_stream.avail_in = in_bytes;
- zip->zipx_lzma_stream.total_in = 0;
- zip->zipx_lzma_stream.next_out = zip->uncompressed_buffer;
- zip->zipx_lzma_stream.avail_out = zip->uncompressed_buffer_size;
- zip->zipx_lzma_stream.total_out = 0;
-
- /* Perform the decompression. */
- lz_ret = lzma_code(&zip->zipx_lzma_stream, LZMA_RUN);
- switch(lz_ret) {
- case LZMA_DATA_ERROR:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "xz data error (error %d)", (int) lz_ret);
- return (ARCHIVE_FATAL);
-
- case LZMA_NO_CHECK:
- case LZMA_OK:
- break;
-
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "xz unknown error %d", (int) lz_ret);
- return (ARCHIVE_FATAL);
-
- case LZMA_STREAM_END:
- lzma_end(&zip->zipx_lzma_stream);
- zip->zipx_lzma_valid = 0;
-
- if((int64_t) zip->zipx_lzma_stream.total_in !=
- zip->entry_bytes_remaining)
- {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xz premature end of stream");
- return (ARCHIVE_FATAL);
- }
-
- zip->end_of_entry = 1;
- break;
- }
-
- to_consume = zip->zipx_lzma_stream.total_in;
-
- __archive_read_consume(a, to_consume);
- zip->entry_bytes_remaining -= to_consume;
- zip->entry_compressed_bytes_read += to_consume;
- zip->entry_uncompressed_bytes_read += zip->zipx_lzma_stream.total_out;
-
- *size = zip->zipx_lzma_stream.total_out;
- *buff = zip->uncompressed_buffer;
-
- ret = consume_optional_marker(a, zip);
- if (ret != ARCHIVE_OK)
- return (ret);
-
- return (ARCHIVE_OK);
-}
-
-static int
-zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
- size_t *size, int64_t *offset)
-{
- struct zip* zip = (struct zip *)(a->format->data);
- int ret;
- lzma_ret lz_ret;
- const void* compressed_buf;
- ssize_t bytes_avail, in_bytes, to_consume;
-
- (void) offset; /* UNUSED */
-
- /* Initialize decompressor if not yet initialized. */
- if (!zip->decompress_init) {
- ret = zipx_lzma_alone_init(a, zip);
- if (ret != ARCHIVE_OK)
- return (ret);
- }
-
- /* Fetch more compressed data. The same note as in deflate handler
- * applies here as well:
- *
- * Note: '1' here is a performance optimization. Recall that the
- * decompression layer returns a count of available bytes; asking for
- * more than that forces the decompressor to combine reads by copying
- * data.
- */
- compressed_buf = __archive_read_ahead(a, 1, &bytes_avail);
- if (bytes_avail < 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated lzma file body");
- return (ARCHIVE_FATAL);
- }
-
- /* Set decompressor parameters. */
- in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
-
- zip->zipx_lzma_stream.next_in = compressed_buf;
- zip->zipx_lzma_stream.avail_in = in_bytes;
- zip->zipx_lzma_stream.total_in = 0;
- zip->zipx_lzma_stream.next_out = zip->uncompressed_buffer;
- zip->zipx_lzma_stream.avail_out =
- /* These lzma_alone streams lack end of stream marker, so let's
- * make sure the unpacker won't try to unpack more than it's
- * supposed to. */
- zipmin((int64_t) zip->uncompressed_buffer_size,
- zip->entry->uncompressed_size -
- zip->entry_uncompressed_bytes_read);
- zip->zipx_lzma_stream.total_out = 0;
-
- /* Perform the decompression. */
- lz_ret = lzma_code(&zip->zipx_lzma_stream, LZMA_RUN);
- switch(lz_ret) {
- case LZMA_DATA_ERROR:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "lzma data error (error %d)", (int) lz_ret);
- return (ARCHIVE_FATAL);
-
- /* This case is optional in lzma alone format. It can happen,
- * but most of the files don't have it. (GitHub #1257) */
- case LZMA_STREAM_END:
- lzma_end(&zip->zipx_lzma_stream);
- zip->zipx_lzma_valid = 0;
- if((int64_t) zip->zipx_lzma_stream.total_in !=
- zip->entry_bytes_remaining)
- {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "lzma alone premature end of stream");
- return (ARCHIVE_FATAL);
- }
-
- zip->end_of_entry = 1;
- break;
-
- case LZMA_OK:
- break;
-
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "lzma unknown error %d", (int) lz_ret);
- return (ARCHIVE_FATAL);
- }
-
- to_consume = zip->zipx_lzma_stream.total_in;
-
- /* Update pointers. */
- __archive_read_consume(a, to_consume);
- zip->entry_bytes_remaining -= to_consume;
- zip->entry_compressed_bytes_read += to_consume;
- zip->entry_uncompressed_bytes_read += zip->zipx_lzma_stream.total_out;
-
- if(zip->entry_bytes_remaining == 0) {
- zip->end_of_entry = 1;
- }
-
- /* Return values. */
- *size = zip->zipx_lzma_stream.total_out;
- *buff = zip->uncompressed_buffer;
-
- /* Behave the same way as during deflate decompression. */
- ret = consume_optional_marker(a, zip);
- if (ret != ARCHIVE_OK)
- return (ret);
-
- /* Free lzma decoder handle because we'll no longer need it. */
- if(zip->end_of_entry) {
- lzma_end(&zip->zipx_lzma_stream);
- zip->zipx_lzma_valid = 0;
- }
-
- /* If we're here, then we're good! */
- return (ARCHIVE_OK);
-}
-#endif /* HAVE_LZMA_H && HAVE_LIBLZMA */
-
-static int
-zipx_ppmd8_init(struct archive_read *a, struct zip *zip)
-{
- const void* p;
- uint32_t val;
- uint32_t order;
- uint32_t mem;
- uint32_t restore_method;
-
- /* Remove previous decompression context if it exists. */
- if(zip->ppmd8_valid) {
- __archive_ppmd8_functions.Ppmd8_Free(&zip->ppmd8);
- zip->ppmd8_valid = 0;
- }
-
- /* Create a new decompression context. */
- __archive_ppmd8_functions.Ppmd8_Construct(&zip->ppmd8);
- zip->ppmd8_stream_failed = 0;
-
- /* Setup function pointers required by Ppmd8 decompressor. The
- * 'ppmd_read' function will feed new bytes to the decompressor,
- * and will increment the 'zip->zipx_ppmd_read_compressed' counter. */
- zip->ppmd8.Stream.In = &zip->zipx_ppmd_stream;
- zip->zipx_ppmd_stream.a = a;
- zip->zipx_ppmd_stream.Read = &ppmd_read;
-
- /* Reset number of read bytes to 0. */
- zip->zipx_ppmd_read_compressed = 0;
-
- /* Read Ppmd8 header (2 bytes). */
- p = __archive_read_ahead(a, 2, NULL);
- if(!p) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated file data in PPMd8 stream");
- return (ARCHIVE_FATAL);
- }
- __archive_read_consume(a, 2);
-
- /* Decode the stream's compression parameters. */
- val = archive_le16dec(p);
- order = (val & 15) + 1;
- mem = ((val >> 4) & 0xff) + 1;
- restore_method = (val >> 12);
-
- if(order < 2 || restore_method > 2) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid parameter set in PPMd8 stream (order=%" PRId32 ", "
- "restore=%" PRId32 ")", order, restore_method);
- return (ARCHIVE_FAILED);
- }
-
- /* Allocate the memory needed to properly decompress the file. */
- if(!__archive_ppmd8_functions.Ppmd8_Alloc(&zip->ppmd8, mem << 20)) {
- archive_set_error(&a->archive, ENOMEM,
- "Unable to allocate memory for PPMd8 stream: %" PRId32 " bytes",
- mem << 20);
- return (ARCHIVE_FATAL);
- }
-
- /* Signal the cleanup function to release Ppmd8 context in the
- * cleanup phase. */
- zip->ppmd8_valid = 1;
-
- /* Perform further Ppmd8 initialization. */
- if(!__archive_ppmd8_functions.Ppmd8_RangeDec_Init(&zip->ppmd8)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "PPMd8 stream range decoder initialization error");
- return (ARCHIVE_FATAL);
- }
-
- __archive_ppmd8_functions.Ppmd8_Init(&zip->ppmd8, order,
- restore_method);
-
- /* Allocate the buffer that will hold uncompressed data. */
- free(zip->uncompressed_buffer);
-
- zip->uncompressed_buffer_size = 256 * 1024;
- zip->uncompressed_buffer =
- (uint8_t*) malloc(zip->uncompressed_buffer_size);
-
- if(zip->uncompressed_buffer == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for PPMd8 decompression");
- return ARCHIVE_FATAL;
- }
-
- /* Ppmd8 initialization is done. */
- zip->decompress_init = 1;
-
- /* We've already read 2 bytes in the output stream. Additionally,
- * Ppmd8 initialization code could read some data as well. So we
- * are advancing the stream by 2 bytes plus whatever number of
- * bytes Ppmd8 init function used. */
- zip->entry_compressed_bytes_read += 2 + zip->zipx_ppmd_read_compressed;
-
- return ARCHIVE_OK;
-}
-
-static int
-zip_read_data_zipx_ppmd(struct archive_read *a, const void **buff,
- size_t *size, int64_t *offset)
-{
- struct zip* zip = (struct zip *)(a->format->data);
- int ret;
- size_t consumed_bytes = 0;
- ssize_t bytes_avail = 0;
-
- (void) offset; /* UNUSED */
-
- /* If we're here for the first time, initialize Ppmd8 decompression
- * context first. */
- if(!zip->decompress_init) {
- ret = zipx_ppmd8_init(a, zip);
- if(ret != ARCHIVE_OK)
- return ret;
- }
-
- /* Fetch for more data. We're reading 1 byte here, but libarchive
- * should prefetch more bytes. */
- (void) __archive_read_ahead(a, 1, &bytes_avail);
- if(bytes_avail < 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated PPMd8 file body");
- return (ARCHIVE_FATAL);
- }
-
- /* This counter will be updated inside ppmd_read(), which at one
- * point will be called by Ppmd8_DecodeSymbol. */
- zip->zipx_ppmd_read_compressed = 0;
-
- /* Decompression loop. */
- do {
- int sym = __archive_ppmd8_functions.Ppmd8_DecodeSymbol(
- &zip->ppmd8);
- if(sym < 0) {
- zip->end_of_entry = 1;
- break;
- }
-
- /* This field is set by ppmd_read() when there was no more data
- * to be read. */
- if(zip->ppmd8_stream_failed) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated PPMd8 file body");
- return (ARCHIVE_FATAL);
- }
-
- zip->uncompressed_buffer[consumed_bytes] = (uint8_t) sym;
- ++consumed_bytes;
- } while(consumed_bytes < zip->uncompressed_buffer_size);
-
- /* Update pointers for libarchive. */
- *buff = zip->uncompressed_buffer;
- *size = consumed_bytes;
-
- /* Update pointers so we can continue decompression in another call. */
- zip->entry_bytes_remaining -= zip->zipx_ppmd_read_compressed;
- zip->entry_compressed_bytes_read += zip->zipx_ppmd_read_compressed;
- zip->entry_uncompressed_bytes_read += consumed_bytes;
-
- /* If we're at the end of stream, deinitialize Ppmd8 context. */
- if(zip->end_of_entry) {
- __archive_ppmd8_functions.Ppmd8_Free(&zip->ppmd8);
- zip->ppmd8_valid = 0;
- }
-
- /* Seek for optional marker, same way as in each zip entry. */
- ret = consume_optional_marker(a, zip);
- if (ret != ARCHIVE_OK)
- return ret;
-
- return ARCHIVE_OK;
-}
-
-#ifdef HAVE_BZLIB_H
-static int
-zipx_bzip2_init(struct archive_read *a, struct zip *zip)
-{
- int r;
-
- /* Deallocate already existing BZ2 decompression context if it
- * exists. */
- if(zip->bzstream_valid) {
- BZ2_bzDecompressEnd(&zip->bzstream);
- zip->bzstream_valid = 0;
- }
-
- /* Allocate a new BZ2 decompression context. */
- memset(&zip->bzstream, 0, sizeof(bz_stream));
- r = BZ2_bzDecompressInit(&zip->bzstream, 0, 1);
- if(r != BZ_OK) {
- archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
- "bzip2 initialization failed(%d)",
- r);
-
- return ARCHIVE_FAILED;
- }
-
- /* Mark the bzstream field to be released in cleanup phase. */
- zip->bzstream_valid = 1;
-
- /* (Re)allocate the buffer that will contain decompressed bytes. */
- free(zip->uncompressed_buffer);
-
- zip->uncompressed_buffer_size = 256 * 1024;
- zip->uncompressed_buffer =
- (uint8_t*) malloc(zip->uncompressed_buffer_size);
- if (zip->uncompressed_buffer == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for bzip2 decompression");
- return ARCHIVE_FATAL;
- }
-
- /* Initialization done. */
- zip->decompress_init = 1;
- return ARCHIVE_OK;
-}
-
-static int
-zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff,
- size_t *size, int64_t *offset)
-{
- struct zip *zip = (struct zip *)(a->format->data);
- ssize_t bytes_avail = 0, in_bytes, to_consume;
- const void *compressed_buff;
- int r;
- uint64_t total_out;
-
- (void) offset; /* UNUSED */
-
- /* Initialize decompression context if we're here for the first time. */
- if(!zip->decompress_init) {
- r = zipx_bzip2_init(a, zip);
- if(r != ARCHIVE_OK)
- return r;
- }
-
- /* Fetch more compressed bytes. */
- compressed_buff = __archive_read_ahead(a, 1, &bytes_avail);
- if(bytes_avail < 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated bzip2 file body");
- return (ARCHIVE_FATAL);
- }
-
- in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
- if(in_bytes < 1) {
- /* libbz2 doesn't complain when caller feeds avail_in == 0.
- * It will actually return success in this case, which is
- * undesirable. This is why we need to make this check
- * manually. */
-
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated bzip2 file body");
- return (ARCHIVE_FATAL);
- }
-
- /* Setup buffer boundaries. */
- zip->bzstream.next_in = (char*)(uintptr_t) compressed_buff;
- zip->bzstream.avail_in = (uint32_t)in_bytes;
- zip->bzstream.total_in_hi32 = 0;
- zip->bzstream.total_in_lo32 = 0;
- zip->bzstream.next_out = (char*) zip->uncompressed_buffer;
- zip->bzstream.avail_out = (uint32_t)zip->uncompressed_buffer_size;
- zip->bzstream.total_out_hi32 = 0;
- zip->bzstream.total_out_lo32 = 0;
-
- /* Perform the decompression. */
- r = BZ2_bzDecompress(&zip->bzstream);
- switch(r) {
- case BZ_STREAM_END:
- /* If we're at the end of the stream, deinitialize the
- * decompression context now. */
- switch(BZ2_bzDecompressEnd(&zip->bzstream)) {
- case BZ_OK:
- break;
- default:
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Failed to clean up bzip2 "
- "decompressor");
- return ARCHIVE_FATAL;
- }
-
- zip->end_of_entry = 1;
- break;
- case BZ_OK:
- /* The decompressor has successfully decoded this
- * chunk of data, but more data is still in queue. */
- break;
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "bzip2 decompression failed");
- return ARCHIVE_FATAL;
- }
-
- /* Update the pointers so decompressor can continue decoding. */
- to_consume = zip->bzstream.total_in_lo32;
- __archive_read_consume(a, to_consume);
-
- total_out = ((uint64_t) zip->bzstream.total_out_hi32 << 32) |
- zip->bzstream.total_out_lo32;
-
- zip->entry_bytes_remaining -= to_consume;
- zip->entry_compressed_bytes_read += to_consume;
- zip->entry_uncompressed_bytes_read += total_out;
-
- /* Give libarchive its due. */
- *size = total_out;
- *buff = zip->uncompressed_buffer;
-
- /* Seek for optional marker, like in other entries. */
- r = consume_optional_marker(a, zip);
- if(r != ARCHIVE_OK)
- return r;
-
- return ARCHIVE_OK;
-}
-
-#endif
-
-#if HAVE_ZSTD_H && HAVE_LIBZSTD
-static int
-zipx_zstd_init(struct archive_read *a, struct zip *zip)
-{
- size_t r;
-
- /* Deallocate already existing Zstd decompression context if it
- * exists. */
- if(zip->zstdstream_valid) {
- ZSTD_freeDStream(zip->zstdstream);
- zip->zstdstream_valid = 0;
- }
-
- /* Allocate a new Zstd decompression context. */
- zip->zstdstream = ZSTD_createDStream();
-
- r = ZSTD_initDStream(zip->zstdstream);
- if (ZSTD_isError(r)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Error initializing zstd decompressor: %s",
- ZSTD_getErrorName(r));
-
- return ARCHIVE_FAILED;
- }
-
- /* Mark the zstdstream field to be released in cleanup phase. */
- zip->zstdstream_valid = 1;
-
- /* (Re)allocate the buffer that will contain decompressed bytes. */
- free(zip->uncompressed_buffer);
-
- zip->uncompressed_buffer_size = ZSTD_DStreamOutSize();
- zip->uncompressed_buffer =
- (uint8_t*) malloc(zip->uncompressed_buffer_size);
- if (zip->uncompressed_buffer == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for Zstd decompression");
-
- return ARCHIVE_FATAL;
- }
-
- /* Initialization done. */
- zip->decompress_init = 1;
- return ARCHIVE_OK;
-}
-
-static int
-zip_read_data_zipx_zstd(struct archive_read *a, const void **buff,
- size_t *size, int64_t *offset)
-{
- struct zip *zip = (struct zip *)(a->format->data);
- ssize_t bytes_avail = 0, in_bytes, to_consume;
- const void *compressed_buff;
- int r;
- size_t ret;
- uint64_t total_out;
- ZSTD_outBuffer out;
- ZSTD_inBuffer in;
-
- (void) offset; /* UNUSED */
-
- /* Initialize decompression context if we're here for the first time. */
- if(!zip->decompress_init) {
- r = zipx_zstd_init(a, zip);
- if(r != ARCHIVE_OK)
- return r;
- }
-
- /* Fetch more compressed bytes */
- compressed_buff = __archive_read_ahead(a, 1, &bytes_avail);
- if(bytes_avail < 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated zstd file body");
- return (ARCHIVE_FATAL);
- }
-
- in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
- if(in_bytes < 1) {
- /* zstd doesn't complain when caller feeds avail_in == 0.
- * It will actually return success in this case, which is
- * undesirable. This is why we need to make this check
- * manually. */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated zstd file body");
- return (ARCHIVE_FATAL);
- }
-
- /* Setup buffer boundaries */
- in.src = compressed_buff;
- in.size = in_bytes;
- in.pos = 0;
- out = (ZSTD_outBuffer) { zip->uncompressed_buffer, zip->uncompressed_buffer_size, 0 };
-
- /* Perform the decompression. */
- ret = ZSTD_decompressStream(zip->zstdstream, &out, &in);
- if (ZSTD_isError(ret)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Error during zstd decompression: %s",
- ZSTD_getErrorName(ret));
- return (ARCHIVE_FATAL);
- }
-
- /* Check end of the stream. */
- if (ret == 0) {
- if ((in.pos == in.size) && (out.pos < out.size)) {
- zip->end_of_entry = 1;
- ZSTD_freeDStream(zip->zstdstream);
- zip->zstdstream_valid = 0;
- }
- }
-
- /* Update the pointers so decompressor can continue decoding. */
- to_consume = in.pos;
- __archive_read_consume(a, to_consume);
-
- total_out = out.pos;
-
- zip->entry_bytes_remaining -= to_consume;
- zip->entry_compressed_bytes_read += to_consume;
- zip->entry_uncompressed_bytes_read += total_out;
-
- /* Give libarchive its due. */
- *size = total_out;
- *buff = zip->uncompressed_buffer;
-
- /* Seek for optional marker, like in other entries. */
- r = consume_optional_marker(a, zip);
- if(r != ARCHIVE_OK)
- return r;
-
- return ARCHIVE_OK;
-}
-#endif
-
-#ifdef HAVE_ZLIB_H
-static int
-zip_deflate_init(struct archive_read *a, struct zip *zip)
-{
- int r;
-
- /* If we haven't yet read any data, initialize the decompressor. */
- if (!zip->decompress_init) {
- if (zip->stream_valid)
- r = inflateReset(&zip->stream);
- else
- r = inflateInit2(&zip->stream,
- -15 /* Don't check for zlib header */);
- if (r != Z_OK) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Can't initialize ZIP decompression.");
- return (ARCHIVE_FATAL);
- }
- /* Stream structure has been set up. */
- zip->stream_valid = 1;
- /* We've initialized decompression for this stream. */
- zip->decompress_init = 1;
- }
- return (ARCHIVE_OK);
-}
-
-static int
-zip_read_data_deflate(struct archive_read *a, const void **buff,
- size_t *size, int64_t *offset)
-{
- struct zip *zip;
- ssize_t bytes_avail;
- const void *compressed_buff, *sp;
- int r;
-
- (void)offset; /* UNUSED */
-
- zip = (struct zip *)(a->format->data);
-
- /* If the buffer hasn't been allocated, allocate it now. */
- if (zip->uncompressed_buffer == NULL) {
- zip->uncompressed_buffer_size = 256 * 1024;
- zip->uncompressed_buffer
- = (unsigned char *)malloc(zip->uncompressed_buffer_size);
- if (zip->uncompressed_buffer == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for ZIP decompression");
- return (ARCHIVE_FATAL);
- }
- }
-
- r = zip_deflate_init(a, zip);
- if (r != ARCHIVE_OK)
- return (r);
-
- /*
- * Note: '1' here is a performance optimization.
- * Recall that the decompression layer returns a count of
- * available bytes; asking for more than that forces the
- * decompressor to combine reads by copying data.
- */
- compressed_buff = sp = __archive_read_ahead(a, 1, &bytes_avail);
- if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END)
- && bytes_avail > zip->entry_bytes_remaining) {
- bytes_avail = (ssize_t)zip->entry_bytes_remaining;
- }
- if (bytes_avail < 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated ZIP file body");
- return (ARCHIVE_FATAL);
- }
-
- if (zip->tctx_valid || zip->cctx_valid) {
- if (zip->decrypted_bytes_remaining < (size_t)bytes_avail) {
- size_t buff_remaining =
- (zip->decrypted_buffer +
- zip->decrypted_buffer_size)
- - (zip->decrypted_ptr +
- zip->decrypted_bytes_remaining);
-
- if (buff_remaining > (size_t)bytes_avail)
- buff_remaining = (size_t)bytes_avail;
-
- if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END) &&
- zip->entry_bytes_remaining > 0) {
- if ((int64_t)(zip->decrypted_bytes_remaining
- + buff_remaining)
- > zip->entry_bytes_remaining) {
- if (zip->entry_bytes_remaining <
- (int64_t)zip->decrypted_bytes_remaining)
- buff_remaining = 0;
- else
- buff_remaining =
- (size_t)zip->entry_bytes_remaining
- - zip->decrypted_bytes_remaining;
- }
- }
- if (buff_remaining > 0) {
- if (zip->tctx_valid) {
- trad_enc_decrypt_update(&zip->tctx,
- compressed_buff, buff_remaining,
- zip->decrypted_ptr
- + zip->decrypted_bytes_remaining,
- buff_remaining);
- } else {
- size_t dsize = buff_remaining;
- archive_decrypto_aes_ctr_update(
- &zip->cctx,
- compressed_buff, buff_remaining,
- zip->decrypted_ptr
- + zip->decrypted_bytes_remaining,
- &dsize);
- }
- zip->decrypted_bytes_remaining +=
- buff_remaining;
- }
- }
- bytes_avail = zip->decrypted_bytes_remaining;
- compressed_buff = (const char *)zip->decrypted_ptr;
- }
-
- /*
- * A bug in zlib.h: stream.next_in should be marked 'const'
- * but isn't (the library never alters data through the
- * next_in pointer, only reads it). The result: this ugly
- * cast to remove 'const'.
- */
- zip->stream.next_in = (Bytef *)(uintptr_t)(const void *)compressed_buff;
- zip->stream.avail_in = (uInt)bytes_avail;
- zip->stream.total_in = 0;
- zip->stream.next_out = zip->uncompressed_buffer;
- zip->stream.avail_out = (uInt)zip->uncompressed_buffer_size;
- zip->stream.total_out = 0;
-
- r = inflate(&zip->stream, 0);
- switch (r) {
- case Z_OK:
- break;
- case Z_STREAM_END:
- zip->end_of_entry = 1;
- break;
- case Z_MEM_ERROR:
- archive_set_error(&a->archive, ENOMEM,
- "Out of memory for ZIP decompression");
- return (ARCHIVE_FATAL);
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "ZIP decompression failed (%d)", r);
- return (ARCHIVE_FATAL);
- }
-
- /* Consume as much as the compressor actually used. */
- bytes_avail = zip->stream.total_in;
- if (zip->tctx_valid || zip->cctx_valid) {
- zip->decrypted_bytes_remaining -= bytes_avail;
- if (zip->decrypted_bytes_remaining == 0)
- zip->decrypted_ptr = zip->decrypted_buffer;
- else
- zip->decrypted_ptr += bytes_avail;
- }
- /* Calculate compressed data as much as we used.*/
- if (zip->hctx_valid)
- archive_hmac_sha1_update(&zip->hctx, sp, bytes_avail);
- __archive_read_consume(a, bytes_avail);
- zip->entry_bytes_remaining -= bytes_avail;
- zip->entry_compressed_bytes_read += bytes_avail;
-
- *size = zip->stream.total_out;
- zip->entry_uncompressed_bytes_read += zip->stream.total_out;
- *buff = zip->uncompressed_buffer;
-
- if (zip->end_of_entry && zip->hctx_valid) {
- r = check_authentication_code(a, NULL);
- if (r != ARCHIVE_OK)
- return (r);
- }
-
- r = consume_optional_marker(a, zip);
- if (r != ARCHIVE_OK)
- return (r);
-
- return (ARCHIVE_OK);
-}
-#endif
-
-static int
-read_decryption_header(struct archive_read *a)
-{
- struct zip *zip = (struct zip *)(a->format->data);
- const char *p;
- unsigned int remaining_size;
- unsigned int ts;
-
- /*
- * Read an initialization vector data field.
- */
- p = __archive_read_ahead(a, 2, NULL);
- if (p == NULL)
- goto truncated;
- ts = zip->iv_size;
- zip->iv_size = archive_le16dec(p);
- __archive_read_consume(a, 2);
- if (ts < zip->iv_size) {
- free(zip->iv);
- zip->iv = NULL;
- }
- p = __archive_read_ahead(a, zip->iv_size, NULL);
- if (p == NULL)
- goto truncated;
- if (zip->iv == NULL) {
- zip->iv = malloc(zip->iv_size);
- if (zip->iv == NULL)
- goto nomem;
- }
- memcpy(zip->iv, p, zip->iv_size);
- __archive_read_consume(a, zip->iv_size);
-
- /*
- * Read a size of remaining decryption header field.
- */
- p = __archive_read_ahead(a, 14, NULL);
- if (p == NULL)
- goto truncated;
- remaining_size = archive_le32dec(p);
- if (remaining_size < 16 || remaining_size > (1 << 18))
- goto corrupted;
-
- /* Check if format version is supported. */
- if (archive_le16dec(p+4) != 3) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Unsupported encryption format version: %u",
- archive_le16dec(p+4));
- return (ARCHIVE_FAILED);
- }
-
- /*
- * Read an encryption algorithm field.
- */
- zip->alg_id = archive_le16dec(p+6);
- switch (zip->alg_id) {
- case 0x6601:/* DES */
- case 0x6602:/* RC2 */
- case 0x6603:/* 3DES 168 */
- case 0x6609:/* 3DES 112 */
- case 0x660E:/* AES 128 */
- case 0x660F:/* AES 192 */
- case 0x6610:/* AES 256 */
- case 0x6702:/* RC2 (version >= 5.2) */
- case 0x6720:/* Blowfish */
- case 0x6721:/* Twofish */
- case 0x6801:/* RC4 */
- /* Supported encryption algorithm. */
- break;
- default:
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Unknown encryption algorithm: %u", zip->alg_id);
- return (ARCHIVE_FAILED);
- }
-
- /*
- * Read a bit length field.
- */
- zip->bit_len = archive_le16dec(p+8);
-
- /*
- * Read a flags field.
- */
- zip->flags = archive_le16dec(p+10);
- switch (zip->flags & 0xf000) {
- case 0x0001: /* Password is required to decrypt. */
- case 0x0002: /* Certificates only. */
- case 0x0003: /* Password or certificate required to decrypt. */
- break;
- default:
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Unknown encryption flag: %u", zip->flags);
- return (ARCHIVE_FAILED);
- }
- if ((zip->flags & 0xf000) == 0 ||
- (zip->flags & 0xf000) == 0x4000) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Unknown encryption flag: %u", zip->flags);
- return (ARCHIVE_FAILED);
- }
-
- /*
- * Read an encrypted random data field.
- */
- ts = zip->erd_size;
- zip->erd_size = archive_le16dec(p+12);
- __archive_read_consume(a, 14);
- if ((zip->erd_size & 0xf) != 0 ||
- (zip->erd_size + 16) > remaining_size ||
- (zip->erd_size + 16) < zip->erd_size)
- goto corrupted;
-
- if (ts < zip->erd_size) {
- free(zip->erd);
- zip->erd = NULL;
- }
- p = __archive_read_ahead(a, zip->erd_size, NULL);
- if (p == NULL)
- goto truncated;
- if (zip->erd == NULL) {
- zip->erd = malloc(zip->erd_size);
- if (zip->erd == NULL)
- goto nomem;
- }
- memcpy(zip->erd, p, zip->erd_size);
- __archive_read_consume(a, zip->erd_size);
-
- /*
- * Read a reserved data field.
- */
- p = __archive_read_ahead(a, 4, NULL);
- if (p == NULL)
- goto truncated;
- /* Reserved data size should be zero. */
- if (archive_le32dec(p) != 0)
- goto corrupted;
- __archive_read_consume(a, 4);
-
- /*
- * Read a password validation data field.
- */
- p = __archive_read_ahead(a, 2, NULL);
- if (p == NULL)
- goto truncated;
- ts = zip->v_size;
- zip->v_size = archive_le16dec(p);
- __archive_read_consume(a, 2);
- if ((zip->v_size & 0x0f) != 0 ||
- (zip->erd_size + zip->v_size + 16) > remaining_size ||
- (zip->erd_size + zip->v_size + 16) < (zip->erd_size + zip->v_size))
- goto corrupted;
- if (ts < zip->v_size) {
- free(zip->v_data);
- zip->v_data = NULL;
- }
- p = __archive_read_ahead(a, zip->v_size, NULL);
- if (p == NULL)
- goto truncated;
- if (zip->v_data == NULL) {
- zip->v_data = malloc(zip->v_size);
- if (zip->v_data == NULL)
- goto nomem;
- }
- memcpy(zip->v_data, p, zip->v_size);
- __archive_read_consume(a, zip->v_size);
-
- p = __archive_read_ahead(a, 4, NULL);
- if (p == NULL)
- goto truncated;
- zip->v_crc32 = archive_le32dec(p);
- __archive_read_consume(a, 4);
-
- /*return (ARCHIVE_OK);
- * This is not fully implemented yet.*/
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Encrypted file is unsupported");
- return (ARCHIVE_FAILED);
-truncated:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated ZIP file data");
- return (ARCHIVE_FATAL);
-corrupted:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Corrupted ZIP file data");
- return (ARCHIVE_FATAL);
-nomem:
- archive_set_error(&a->archive, ENOMEM,
- "No memory for ZIP decryption");
- return (ARCHIVE_FATAL);
-}
-
-static int
-zip_alloc_decryption_buffer(struct archive_read *a)
-{
- struct zip *zip = (struct zip *)(a->format->data);
- size_t bs = 256 * 1024;
-
- if (zip->decrypted_buffer == NULL) {
- zip->decrypted_buffer_size = bs;
- zip->decrypted_buffer = malloc(bs);
- if (zip->decrypted_buffer == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for ZIP decryption");
- return (ARCHIVE_FATAL);
- }
- }
- zip->decrypted_ptr = zip->decrypted_buffer;
- return (ARCHIVE_OK);
-}
-
-static int
-init_traditional_PKWARE_decryption(struct archive_read *a)
-{
- struct zip *zip = (struct zip *)(a->format->data);
- const void *p;
- int retry;
- int r;
-
- if (zip->tctx_valid)
- return (ARCHIVE_OK);
-
- /*
- Read the 12 bytes encryption header stored at
- the start of the data area.
- */
-#define ENC_HEADER_SIZE 12
- if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END)
- && zip->entry_bytes_remaining < ENC_HEADER_SIZE) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated Zip encrypted body: only %jd bytes available",
- (intmax_t)zip->entry_bytes_remaining);
- return (ARCHIVE_FATAL);
- }
-
- p = __archive_read_ahead(a, ENC_HEADER_SIZE, NULL);
- if (p == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated ZIP file data");
- return (ARCHIVE_FATAL);
- }
-
- for (retry = 0;; retry++) {
- const char *passphrase;
- uint8_t crcchk;
-
- passphrase = __archive_read_next_passphrase(a);
- if (passphrase == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- (retry > 0)?
- "Incorrect passphrase":
- "Passphrase required for this entry");
- return (ARCHIVE_FAILED);
- }
-
- /*
- * Initialize ctx for Traditional PKWARE Decryption.
- */
- r = trad_enc_init(&zip->tctx, passphrase, strlen(passphrase),
- p, ENC_HEADER_SIZE, &crcchk);
- if (r == 0 && crcchk == zip->entry->decdat)
- break;/* The passphrase is OK. */
- if (retry > 10000) {
- /* Avoid infinity loop. */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Too many incorrect passphrases");
- return (ARCHIVE_FAILED);
- }
- }
-
- __archive_read_consume(a, ENC_HEADER_SIZE);
- zip->tctx_valid = 1;
- if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END)) {
- zip->entry_bytes_remaining -= ENC_HEADER_SIZE;
- }
- /*zip->entry_uncompressed_bytes_read += ENC_HEADER_SIZE;*/
- zip->entry_compressed_bytes_read += ENC_HEADER_SIZE;
- zip->decrypted_bytes_remaining = 0;
-
- return (zip_alloc_decryption_buffer(a));
-#undef ENC_HEADER_SIZE
-}
-
-static int
-init_WinZip_AES_decryption(struct archive_read *a)
-{
- struct zip *zip = (struct zip *)(a->format->data);
- const void *p;
- const uint8_t *pv;
- size_t key_len, salt_len;
- uint8_t derived_key[MAX_DERIVED_KEY_BUF_SIZE];
- int retry;
- int r;
-
- if (zip->cctx_valid || zip->hctx_valid)
- return (ARCHIVE_OK);
-
- switch (zip->entry->aes_extra.strength) {
- case 1: salt_len = 8; key_len = 16; break;
- case 2: salt_len = 12; key_len = 24; break;
- case 3: salt_len = 16; key_len = 32; break;
- default: goto corrupted;
- }
- p = __archive_read_ahead(a, salt_len + 2, NULL);
- if (p == NULL)
- goto truncated;
-
- for (retry = 0;; retry++) {
- const char *passphrase;
-
- passphrase = __archive_read_next_passphrase(a);
- if (passphrase == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- (retry > 0)?
- "Incorrect passphrase":
- "Passphrase required for this entry");
- return (ARCHIVE_FAILED);
- }
- memset(derived_key, 0, sizeof(derived_key));
- r = archive_pbkdf2_sha1(passphrase, strlen(passphrase),
- p, salt_len, 1000, derived_key, key_len * 2 + 2);
- if (r != 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Decryption is unsupported due to lack of "
- "crypto library");
- return (ARCHIVE_FAILED);
- }
-
- /* Check password verification value. */
- pv = ((const uint8_t *)p) + salt_len;
- if (derived_key[key_len * 2] == pv[0] &&
- derived_key[key_len * 2 + 1] == pv[1])
- break;/* The passphrase is OK. */
- if (retry > 10000) {
- /* Avoid infinity loop. */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Too many incorrect passphrases");
- return (ARCHIVE_FAILED);
- }
- }
-
- r = archive_decrypto_aes_ctr_init(&zip->cctx, derived_key, key_len);
- if (r != 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Decryption is unsupported due to lack of crypto library");
- return (ARCHIVE_FAILED);
- }
- r = archive_hmac_sha1_init(&zip->hctx, derived_key + key_len, key_len);
- if (r != 0) {
- archive_decrypto_aes_ctr_release(&zip->cctx);
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Failed to initialize HMAC-SHA1");
- return (ARCHIVE_FAILED);
- }
- zip->cctx_valid = zip->hctx_valid = 1;
- __archive_read_consume(a, salt_len + 2);
- zip->entry_bytes_remaining -= salt_len + 2 + AUTH_CODE_SIZE;
- if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END)
- && zip->entry_bytes_remaining < 0)
- goto corrupted;
- zip->entry_compressed_bytes_read += salt_len + 2 + AUTH_CODE_SIZE;
- zip->decrypted_bytes_remaining = 0;
-
- zip->entry->compression = zip->entry->aes_extra.compression;
- return (zip_alloc_decryption_buffer(a));
-
-truncated:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated ZIP file data");
- return (ARCHIVE_FATAL);
-corrupted:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Corrupted ZIP file data");
- return (ARCHIVE_FATAL);
-}
-
-static int
-archive_read_format_zip_read_data(struct archive_read *a,
- const void **buff, size_t *size, int64_t *offset)
-{
- int r;
- struct zip *zip = (struct zip *)(a->format->data);
-
- if (zip->has_encrypted_entries ==
- ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
- zip->has_encrypted_entries = 0;
- }
-
- *offset = zip->entry_uncompressed_bytes_read;
- *size = 0;
- *buff = NULL;
-
- /* If we hit end-of-entry last time, return ARCHIVE_EOF. */
- if (zip->end_of_entry)
- return (ARCHIVE_EOF);
-
- /* Return EOF immediately if this is a non-regular file. */
- if (AE_IFREG != (zip->entry->mode & AE_IFMT))
- return (ARCHIVE_EOF);
-
- __archive_read_consume(a, zip->unconsumed);
- zip->unconsumed = 0;
-
- if (zip->init_decryption) {
- zip->has_encrypted_entries = 1;
- if (zip->entry->zip_flags & ZIP_STRONG_ENCRYPTED)
- r = read_decryption_header(a);
- else if (zip->entry->compression == WINZIP_AES_ENCRYPTION)
- r = init_WinZip_AES_decryption(a);
- else
- r = init_traditional_PKWARE_decryption(a);
- if (r != ARCHIVE_OK)
- return (r);
- zip->init_decryption = 0;
- }
-
- switch(zip->entry->compression) {
- case 0: /* No compression. */
- r = zip_read_data_none(a, buff, size, offset);
- break;
-#ifdef HAVE_BZLIB_H
- case 12: /* ZIPx bzip2 compression. */
- r = zip_read_data_zipx_bzip2(a, buff, size, offset);
- break;
-#endif
-#if HAVE_LZMA_H && HAVE_LIBLZMA
- case 14: /* ZIPx LZMA compression. */
- r = zip_read_data_zipx_lzma_alone(a, buff, size, offset);
- break;
- case 95: /* ZIPx XZ compression. */
- r = zip_read_data_zipx_xz(a, buff, size, offset);
- break;
-#endif
-#if HAVE_ZSTD_H && HAVE_LIBZSTD
- case 93: /* ZIPx Zstd compression. */
- r = zip_read_data_zipx_zstd(a, buff, size, offset);
- break;
-#endif
- /* PPMd support is built-in, so we don't need any #if guards. */
- case 98: /* ZIPx PPMd compression. */
- r = zip_read_data_zipx_ppmd(a, buff, size, offset);
- break;
-
-#ifdef HAVE_ZLIB_H
- case 8: /* Deflate compression. */
- r = zip_read_data_deflate(a, buff, size, offset);
- break;
-#endif
- default: /* Unsupported compression. */
- /* Return a warning. */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unsupported ZIP compression method (%d: %s)",
- zip->entry->compression, compression_name(zip->entry->compression));
- /* We can't decompress this entry, but we will
- * be able to skip() it and try the next entry. */
- return (ARCHIVE_FAILED);
- break;
- }
- if (r != ARCHIVE_OK)
- return (r);
- /* Update checksum */
- if (*size)
- zip->entry_crc32 = zip->crc32func(zip->entry_crc32, *buff,
- (unsigned)*size);
- /* If we hit the end, swallow any end-of-data marker. */
- if (zip->end_of_entry) {
- /* Check file size, CRC against these values. */
- if (zip->entry->compressed_size !=
- zip->entry_compressed_bytes_read) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "ZIP compressed data is wrong size "
- "(read %jd, expected %jd)",
- (intmax_t)zip->entry_compressed_bytes_read,
- (intmax_t)zip->entry->compressed_size);
- return (ARCHIVE_WARN);
- }
- /* Size field only stores the lower 32 bits of the actual
- * size. */
- if ((zip->entry->uncompressed_size & UINT32_MAX)
- != (zip->entry_uncompressed_bytes_read & UINT32_MAX)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "ZIP uncompressed data is wrong size "
- "(read %jd, expected %jd)\n",
- (intmax_t)zip->entry_uncompressed_bytes_read,
- (intmax_t)zip->entry->uncompressed_size);
- return (ARCHIVE_WARN);
- }
- /* Check computed CRC against header */
- if ((!zip->hctx_valid ||
- zip->entry->aes_extra.vendor != AES_VENDOR_AE_2) &&
- zip->entry->crc32 != zip->entry_crc32
- && !zip->ignore_crc32) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "ZIP bad CRC: 0x%lx should be 0x%lx",
- (unsigned long)zip->entry_crc32,
- (unsigned long)zip->entry->crc32);
- return (ARCHIVE_WARN);
- }
- }
-
- return (ARCHIVE_OK);
-}
-
-static int
-archive_read_format_zip_cleanup(struct archive_read *a)
-{
- struct zip *zip;
- struct zip_entry *zip_entry, *next_zip_entry;
-
- zip = (struct zip *)(a->format->data);
-
-#ifdef HAVE_ZLIB_H
- if (zip->stream_valid)
- inflateEnd(&zip->stream);
-#endif
-
-#if HAVE_LZMA_H && HAVE_LIBLZMA
- if (zip->zipx_lzma_valid) {
- lzma_end(&zip->zipx_lzma_stream);
- }
-#endif
-
-#ifdef HAVE_BZLIB_H
- if (zip->bzstream_valid) {
- BZ2_bzDecompressEnd(&zip->bzstream);
- }
-#endif
-
-#if HAVE_ZSTD_H && HAVE_LIBZSTD
- if (zip->zstdstream_valid) {
- ZSTD_freeDStream(zip->zstdstream);
- }
-#endif
-
- free(zip->uncompressed_buffer);
-
- if (zip->ppmd8_valid)
- __archive_ppmd8_functions.Ppmd8_Free(&zip->ppmd8);
-
- if (zip->zip_entries) {
- zip_entry = zip->zip_entries;
- while (zip_entry != NULL) {
- next_zip_entry = zip_entry->next;
- archive_string_free(&zip_entry->rsrcname);
- free(zip_entry);
- zip_entry = next_zip_entry;
- }
- }
- free(zip->decrypted_buffer);
- if (zip->cctx_valid)
- archive_decrypto_aes_ctr_release(&zip->cctx);
- if (zip->hctx_valid)
- archive_hmac_sha1_cleanup(&zip->hctx);
- free(zip->iv);
- free(zip->erd);
- free(zip->v_data);
- archive_string_free(&zip->format_name);
- free(zip);
- (a->format->data) = NULL;
- return (ARCHIVE_OK);
-}
-
-static int
-archive_read_format_zip_has_encrypted_entries(struct archive_read *_a)
-{
- if (_a && _a->format) {
- struct zip * zip = (struct zip *)_a->format->data;
- if (zip) {
- return zip->has_encrypted_entries;
- }
- }
- return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
-}
-
-static int
-archive_read_format_zip_options(struct archive_read *a,
- const char *key, const char *val)
-{
- struct zip *zip;
- int ret = ARCHIVE_FAILED;
-
- zip = (struct zip *)(a->format->data);
- if (strcmp(key, "compat-2x") == 0) {
- /* Handle filenames as libarchive 2.x */
- zip->init_default_conversion = (val != NULL) ? 1 : 0;
- return (ARCHIVE_OK);
- } else if (strcmp(key, "hdrcharset") == 0) {
- if (val == NULL || val[0] == 0)
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "zip: hdrcharset option needs a character-set name"
- );
- else {
- zip->sconv = archive_string_conversion_from_charset(
- &a->archive, val, 0);
- if (zip->sconv != NULL) {
- if (strcmp(val, "UTF-8") == 0)
- zip->sconv_utf8 = zip->sconv;
- ret = ARCHIVE_OK;
- } else
- ret = ARCHIVE_FATAL;
- }
- return (ret);
- } else if (strcmp(key, "ignorecrc32") == 0) {
- /* Mostly useful for testing. */
- if (val == NULL || val[0] == 0) {
- zip->crc32func = real_crc32;
- zip->ignore_crc32 = 0;
- } else {
- zip->crc32func = fake_crc32;
- zip->ignore_crc32 = 1;
- }
- return (ARCHIVE_OK);
- } else if (strcmp(key, "mac-ext") == 0) {
- zip->process_mac_extensions = (val != NULL && val[0] != 0);
- return (ARCHIVE_OK);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-int
-archive_read_support_format_zip(struct archive *a)
-{
- int r;
- r = archive_read_support_format_zip_streamable(a);
- if (r != ARCHIVE_OK)
- return r;
- return (archive_read_support_format_zip_seekable(a));
-}
-
-/* ------------------------------------------------------------------------ */
-
-/*
- * Streaming-mode support
- */
-
-
-static int
-archive_read_support_format_zip_capabilities_streamable(struct archive_read * a)
-{
- (void)a; /* UNUSED */
- return (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA |
- ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA);
-}
-
-static int
-archive_read_format_zip_streamable_bid(struct archive_read *a, int best_bid)
-{
- const char *p;
-
- (void)best_bid; /* UNUSED */
-
- if ((p = __archive_read_ahead(a, 4, NULL)) == NULL)
- return (-1);
-
- /*
- * Bid of 29 here comes from:
- * + 16 bits for "PK",
- * + next 16-bit field has 6 options so contributes
- * about 16 - log_2(6) ~= 16 - 2.6 ~= 13 bits
- *
- * So we've effectively verified ~29 total bits of check data.
- */
- if (p[0] == 'P' && p[1] == 'K') {
- if ((p[2] == '\001' && p[3] == '\002')
- || (p[2] == '\003' && p[3] == '\004')
- || (p[2] == '\005' && p[3] == '\006')
- || (p[2] == '\006' && p[3] == '\006')
- || (p[2] == '\007' && p[3] == '\010')
- || (p[2] == '0' && p[3] == '0'))
- return (29);
- }
-
- /* TODO: It's worth looking ahead a little bit for a valid
- * PK signature. In particular, that would make it possible
- * to read some UUEncoded SFX files or SFX files coming from
- * a network socket. */
-
- return (0);
-}
-
-static int
-archive_read_format_zip_streamable_read_header(struct archive_read *a,
- struct archive_entry *entry)
-{
- struct zip *zip;
-
- a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
- if (a->archive.archive_format_name == NULL)
- a->archive.archive_format_name = "ZIP";
-
- zip = (struct zip *)(a->format->data);
-
- /*
- * It should be sufficient to call archive_read_next_header() for
- * a reader to determine if an entry is encrypted or not. If the
- * encryption of an entry is only detectable when calling
- * archive_read_data(), so be it. We'll do the same check there
- * as well.
- */
- if (zip->has_encrypted_entries ==
- ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW)
- zip->has_encrypted_entries = 0;
-
- /* Make sure we have a zip_entry structure to use. */
- if (zip->zip_entries == NULL) {
- zip->zip_entries = malloc(sizeof(struct zip_entry));
- if (zip->zip_entries == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Out of memory");
- return ARCHIVE_FATAL;
- }
- }
- zip->entry = zip->zip_entries;
- memset(zip->entry, 0, sizeof(struct zip_entry));
-
- if (zip->cctx_valid)
- archive_decrypto_aes_ctr_release(&zip->cctx);
- if (zip->hctx_valid)
- archive_hmac_sha1_cleanup(&zip->hctx);
- zip->tctx_valid = zip->cctx_valid = zip->hctx_valid = 0;
- __archive_read_reset_passphrase(a);
-
- /* Search ahead for the next local file header. */
- __archive_read_consume(a, zip->unconsumed);
- zip->unconsumed = 0;
- for (;;) {
- int64_t skipped = 0;
- const char *p, *end;
- ssize_t bytes;
-
- p = __archive_read_ahead(a, 4, &bytes);
- if (p == NULL)
- return (ARCHIVE_FATAL);
- end = p + bytes;
-
- while (p + 4 <= end) {
- if (p[0] == 'P' && p[1] == 'K') {
- if (p[2] == '\003' && p[3] == '\004') {
- /* Regular file entry. */
- __archive_read_consume(a, skipped);
- return zip_read_local_file_header(a,
- entry, zip);
- }
-
- /*
- * TODO: We cannot restore permissions
- * based only on the local file headers.
- * Consider scanning the central
- * directory and returning additional
- * entries for at least directories.
- * This would allow us to properly set
- * directory permissions.
- *
- * This won't help us fix symlinks
- * and may not help with regular file
- * permissions, either. <sigh>
- */
- if (p[2] == '\001' && p[3] == '\002') {
- return (ARCHIVE_EOF);
- }
-
- /* End of central directory? Must be an
- * empty archive. */
- if ((p[2] == '\005' && p[3] == '\006')
- || (p[2] == '\006' && p[3] == '\006'))
- return (ARCHIVE_EOF);
- }
- ++p;
- ++skipped;
- }
- __archive_read_consume(a, skipped);
- }
-}
-
-static int
-archive_read_format_zip_read_data_skip_streamable(struct archive_read *a)
-{
- struct zip *zip;
- int64_t bytes_skipped;
-
- zip = (struct zip *)(a->format->data);
- bytes_skipped = __archive_read_consume(a, zip->unconsumed);
- zip->unconsumed = 0;
- if (bytes_skipped < 0)
- return (ARCHIVE_FATAL);
-
- /* If we've already read to end of data, we're done. */
- if (zip->end_of_entry)
- return (ARCHIVE_OK);
-
- /* So we know we're streaming... */
- if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END)
- || zip->entry->compressed_size > 0) {
- /* We know the compressed length, so we can just skip. */
- bytes_skipped = __archive_read_consume(a,
- zip->entry_bytes_remaining);
- if (bytes_skipped < 0)
- return (ARCHIVE_FATAL);
- return (ARCHIVE_OK);
- }
-
- if (zip->init_decryption) {
- int r;
-
- zip->has_encrypted_entries = 1;
- if (zip->entry->zip_flags & ZIP_STRONG_ENCRYPTED)
- r = read_decryption_header(a);
- else if (zip->entry->compression == WINZIP_AES_ENCRYPTION)
- r = init_WinZip_AES_decryption(a);
- else
- r = init_traditional_PKWARE_decryption(a);
- if (r != ARCHIVE_OK)
- return (r);
- zip->init_decryption = 0;
- }
-
- /* We're streaming and we don't know the length. */
- /* If the body is compressed and we know the format, we can
- * find an exact end-of-entry by decompressing it. */
- switch (zip->entry->compression) {
-#ifdef HAVE_ZLIB_H
- case 8: /* Deflate compression. */
- while (!zip->end_of_entry) {
- int64_t offset = 0;
- const void *buff = NULL;
- size_t size = 0;
- int r;
- r = zip_read_data_deflate(a, &buff, &size, &offset);
- if (r != ARCHIVE_OK)
- return (r);
- }
- return ARCHIVE_OK;
-#endif
- default: /* Uncompressed or unknown. */
- /* Scan for a PK\007\010 signature. */
- for (;;) {
- const char *p, *buff;
- ssize_t bytes_avail;
- buff = __archive_read_ahead(a, 16, &bytes_avail);
- if (bytes_avail < 16) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated ZIP file data");
- return (ARCHIVE_FATAL);
- }
- p = buff;
- while (p <= buff + bytes_avail - 16) {
- if (p[3] == 'P') { p += 3; }
- else if (p[3] == 'K') { p += 2; }
- else if (p[3] == '\007') { p += 1; }
- else if (p[3] == '\010' && p[2] == '\007'
- && p[1] == 'K' && p[0] == 'P') {
- if (zip->entry->flags & LA_USED_ZIP64)
- __archive_read_consume(a,
- p - buff + 24);
- else
- __archive_read_consume(a,
- p - buff + 16);
- return ARCHIVE_OK;
- } else { p += 4; }
- }
- __archive_read_consume(a, p - buff);
- }
- }
-}
-
-int
-archive_read_support_format_zip_streamable(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- struct zip *zip;
- int r;
-
- archive_check_magic(_a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_format_zip");
-
- zip = (struct zip *)calloc(1, sizeof(*zip));
- if (zip == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate zip data");
- return (ARCHIVE_FATAL);
- }
-
- /* Streamable reader doesn't support mac extensions. */
- zip->process_mac_extensions = 0;
-
- /*
- * Until enough data has been read, we cannot tell about
- * any encrypted entries yet.
- */
- zip->has_encrypted_entries = ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
- zip->crc32func = real_crc32;
-
- r = __archive_read_register_format(a,
- zip,
- "zip",
- archive_read_format_zip_streamable_bid,
- archive_read_format_zip_options,
- archive_read_format_zip_streamable_read_header,
- archive_read_format_zip_read_data,
- archive_read_format_zip_read_data_skip_streamable,
- NULL,
- archive_read_format_zip_cleanup,
- archive_read_support_format_zip_capabilities_streamable,
- archive_read_format_zip_has_encrypted_entries);
-
- if (r != ARCHIVE_OK)
- free(zip);
- return (ARCHIVE_OK);
-}
-
-/* ------------------------------------------------------------------------ */
-
-/*
- * Seeking-mode support
- */
-
-static int
-archive_read_support_format_zip_capabilities_seekable(struct archive_read * a)
-{
- (void)a; /* UNUSED */
- return (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA |
- ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA);
-}
-
-/*
- * TODO: This is a performance sink because it forces the read core to
- * drop buffered data from the start of file, which will then have to
- * be re-read again if this bidder loses.
- *
- * We workaround this a little by passing in the best bid so far so
- * that later bidders can do nothing if they know they'll never
- * outbid. But we can certainly do better...
- */
-static int
-read_eocd(struct zip *zip, const char *p, int64_t current_offset)
-{
- uint16_t disk_num;
- uint32_t cd_size, cd_offset;
-
- disk_num = archive_le16dec(p + 4);
- cd_size = archive_le32dec(p + 12);
- cd_offset = archive_le32dec(p + 16);
-
- /* Sanity-check the EOCD we've found. */
-
- /* This must be the first volume. */
- if (disk_num != 0)
- return 0;
- /* Central directory must be on this volume. */
- if (disk_num != archive_le16dec(p + 6))
- return 0;
- /* All central directory entries must be on this volume. */
- if (archive_le16dec(p + 10) != archive_le16dec(p + 8))
- return 0;
- /* Central directory can't extend beyond start of EOCD record. */
- if (cd_offset + cd_size > current_offset)
- return 0;
-
- /* Save the central directory location for later use. */
- zip->central_directory_offset = cd_offset;
- zip->central_directory_offset_adjusted = current_offset - cd_size;
-
- /* This is just a tiny bit higher than the maximum
- returned by the streaming Zip bidder. This ensures
- that the more accurate seeking Zip parser wins
- whenever seek is available. */
- return 32;
-}
-
-/*
- * Examine Zip64 EOCD locator: If it's valid, store the information
- * from it.
- */
-static int
-read_zip64_eocd(struct archive_read *a, struct zip *zip, const char *p)
-{
- int64_t eocd64_offset;
- int64_t eocd64_size;
-
- /* Sanity-check the locator record. */
-
- /* Central dir must be on first volume. */
- if (archive_le32dec(p + 4) != 0)
- return 0;
- /* Must be only a single volume. */
- if (archive_le32dec(p + 16) != 1)
- return 0;
-
- /* Find the Zip64 EOCD record. */
- eocd64_offset = archive_le64dec(p + 8);
- if (__archive_read_seek(a, eocd64_offset, SEEK_SET) < 0)
- return 0;
- if ((p = __archive_read_ahead(a, 56, NULL)) == NULL)
- return 0;
- /* Make sure we can read all of it. */
- eocd64_size = archive_le64dec(p + 4) + 12;
- if (eocd64_size < 56 || eocd64_size > 16384)
- return 0;
- if ((p = __archive_read_ahead(a, (size_t)eocd64_size, NULL)) == NULL)
- return 0;
-
- /* Sanity-check the EOCD64 */
- if (archive_le32dec(p + 16) != 0) /* Must be disk #0 */
- return 0;
- if (archive_le32dec(p + 20) != 0) /* CD must be on disk #0 */
- return 0;
- /* CD can't be split. */
- if (archive_le64dec(p + 24) != archive_le64dec(p + 32))
- return 0;
-
- /* Save the central directory offset for later use. */
- zip->central_directory_offset = archive_le64dec(p + 48);
- /* TODO: Needs scanning backwards to find the eocd64 instead of assuming */
- zip->central_directory_offset_adjusted = zip->central_directory_offset;
-
- return 32;
-}
-
-static int
-archive_read_format_zip_seekable_bid(struct archive_read *a, int best_bid)
-{
- struct zip *zip = (struct zip *)a->format->data;
- int64_t file_size, current_offset;
- const char *p;
- int i, tail;
-
- /* If someone has already bid more than 32, then avoid
- trashing the look-ahead buffers with a seek. */
- if (best_bid > 32)
- return (-1);
-
- file_size = __archive_read_seek(a, 0, SEEK_END);
- if (file_size <= 0)
- return 0;
-
- /* Search last 16k of file for end-of-central-directory
- * record (which starts with PK\005\006) */
- tail = (int)zipmin(1024 * 16, file_size);
- current_offset = __archive_read_seek(a, -tail, SEEK_END);
- if (current_offset < 0)
- return 0;
- if ((p = __archive_read_ahead(a, (size_t)tail, NULL)) == NULL)
- return 0;
- /* Boyer-Moore search backwards from the end, since we want
- * to match the last EOCD in the file (there can be more than
- * one if there is an uncompressed Zip archive as a member
- * within this Zip archive). */
- for (i = tail - 22; i > 0;) {
- switch (p[i]) {
- case 'P':
- if (memcmp(p + i, "PK\005\006", 4) == 0) {
- int ret = read_eocd(zip, p + i,
- current_offset + i);
- /* Zip64 EOCD locator precedes
- * regular EOCD if present. */
- if (i >= 20 && memcmp(p + i - 20, "PK\006\007", 4) == 0) {
- int ret_zip64 = read_zip64_eocd(a, zip, p + i - 20);
- if (ret_zip64 > ret)
- ret = ret_zip64;
- }
- return (ret);
- }
- i -= 4;
- break;
- case 'K': i -= 1; break;
- case 005: i -= 2; break;
- case 006: i -= 3; break;
- default: i -= 4; break;
- }
- }
- return 0;
-}
-
-/* The red-black trees are only used in seeking mode to manage
- * the in-memory copy of the central directory. */
-
-static int
-cmp_node(const struct archive_rb_node *n1, const struct archive_rb_node *n2)
-{
- const struct zip_entry *e1 = (const struct zip_entry *)n1;
- const struct zip_entry *e2 = (const struct zip_entry *)n2;
-
- if (e1->local_header_offset > e2->local_header_offset)
- return -1;
- if (e1->local_header_offset < e2->local_header_offset)
- return 1;
- return 0;
-}
-
-static int
-cmp_key(const struct archive_rb_node *n, const void *key)
-{
- /* This function won't be called */
- (void)n; /* UNUSED */
- (void)key; /* UNUSED */
- return 1;
-}
-
-static const struct archive_rb_tree_ops rb_ops = {
- &cmp_node, &cmp_key
-};
-
-static int
-rsrc_cmp_node(const struct archive_rb_node *n1,
- const struct archive_rb_node *n2)
-{
- const struct zip_entry *e1 = (const struct zip_entry *)n1;
- const struct zip_entry *e2 = (const struct zip_entry *)n2;
-
- return (strcmp(e2->rsrcname.s, e1->rsrcname.s));
-}
-
-static int
-rsrc_cmp_key(const struct archive_rb_node *n, const void *key)
-{
- const struct zip_entry *e = (const struct zip_entry *)n;
- return (strcmp((const char *)key, e->rsrcname.s));
-}
-
-static const struct archive_rb_tree_ops rb_rsrc_ops = {
- &rsrc_cmp_node, &rsrc_cmp_key
-};
-
-static const char *
-rsrc_basename(const char *name, size_t name_length)
-{
- const char *s, *r;
-
- r = s = name;
- for (;;) {
- s = memchr(s, '/', name_length - (s - name));
- if (s == NULL)
- break;
- r = ++s;
- }
- return (r);
-}
-
-static void
-expose_parent_dirs(struct zip *zip, const char *name, size_t name_length)
-{
- struct archive_string str;
- struct zip_entry *dir;
- char *s;
-
- archive_string_init(&str);
- archive_strncpy(&str, name, name_length);
- for (;;) {
- s = strrchr(str.s, '/');
- if (s == NULL)
- break;
- *s = '\0';
- /* Transfer the parent directory from zip->tree_rsrc RB
- * tree to zip->tree RB tree to expose. */
- dir = (struct zip_entry *)
- __archive_rb_tree_find_node(&zip->tree_rsrc, str.s);
- if (dir == NULL)
- break;
- __archive_rb_tree_remove_node(&zip->tree_rsrc, &dir->node);
- archive_string_free(&dir->rsrcname);
- __archive_rb_tree_insert_node(&zip->tree, &dir->node);
- }
- archive_string_free(&str);
-}
-
-static int
-slurp_central_directory(struct archive_read *a, struct archive_entry* entry,
- struct zip *zip)
-{
- ssize_t i;
- unsigned found;
- int64_t correction;
- ssize_t bytes_avail;
- const char *p;
-
- /*
- * Find the start of the central directory. The end-of-CD
- * record has our starting point, but there are lots of
- * Zip archives which have had other data prepended to the
- * file, which makes the recorded offsets all too small.
- * So we search forward from the specified offset until we
- * find the real start of the central directory. Then we
- * know the correction we need to apply to account for leading
- * padding.
- */
- if (__archive_read_seek(a, zip->central_directory_offset_adjusted, SEEK_SET)
- < 0)
- return ARCHIVE_FATAL;
-
- found = 0;
- while (!found) {
- if ((p = __archive_read_ahead(a, 20, &bytes_avail)) == NULL)
- return ARCHIVE_FATAL;
- for (found = 0, i = 0; !found && i < bytes_avail - 4;) {
- switch (p[i + 3]) {
- case 'P': i += 3; break;
- case 'K': i += 2; break;
- case 001: i += 1; break;
- case 002:
- if (memcmp(p + i, "PK\001\002", 4) == 0) {
- p += i;
- found = 1;
- } else
- i += 4;
- break;
- case 005: i += 1; break;
- case 006:
- if (memcmp(p + i, "PK\005\006", 4) == 0) {
- p += i;
- found = 1;
- } else if (memcmp(p + i, "PK\006\006", 4) == 0) {
- p += i;
- found = 1;
- } else
- i += 1;
- break;
- default: i += 4; break;
- }
- }
- __archive_read_consume(a, i);
- }
- correction = archive_filter_bytes(&a->archive, 0)
- - zip->central_directory_offset;
-
- __archive_rb_tree_init(&zip->tree, &rb_ops);
- __archive_rb_tree_init(&zip->tree_rsrc, &rb_rsrc_ops);
-
- zip->central_directory_entries_total = 0;
- while (1) {
- struct zip_entry *zip_entry;
- size_t filename_length, extra_length, comment_length;
- uint32_t external_attributes;
- const char *name, *r;
-
- if ((p = __archive_read_ahead(a, 4, NULL)) == NULL)
- return ARCHIVE_FATAL;
- if (memcmp(p, "PK\006\006", 4) == 0
- || memcmp(p, "PK\005\006", 4) == 0) {
- break;
- } else if (memcmp(p, "PK\001\002", 4) != 0) {
- archive_set_error(&a->archive,
- -1, "Invalid central directory signature");
- return ARCHIVE_FATAL;
- }
- if ((p = __archive_read_ahead(a, 46, NULL)) == NULL)
- return ARCHIVE_FATAL;
-
- zip_entry = calloc(1, sizeof(struct zip_entry));
- if (zip_entry == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate zip entry");
- return ARCHIVE_FATAL;
- }
- zip_entry->next = zip->zip_entries;
- zip_entry->flags |= LA_FROM_CENTRAL_DIRECTORY;
- zip->zip_entries = zip_entry;
- zip->central_directory_entries_total++;
-
- /* version = p[4]; */
- zip_entry->system = p[5];
- /* version_required = archive_le16dec(p + 6); */
- zip_entry->zip_flags = archive_le16dec(p + 8);
- if (zip_entry->zip_flags
- & (ZIP_ENCRYPTED | ZIP_STRONG_ENCRYPTED)){
- zip->has_encrypted_entries = 1;
- }
- zip_entry->compression = (char)archive_le16dec(p + 10);
- zip_entry->mtime = zip_time(p + 12);
- zip_entry->crc32 = archive_le32dec(p + 16);
- if (zip_entry->zip_flags & ZIP_LENGTH_AT_END)
- zip_entry->decdat = p[13];
- else
- zip_entry->decdat = p[19];
- zip_entry->compressed_size = archive_le32dec(p + 20);
- zip_entry->uncompressed_size = archive_le32dec(p + 24);
- filename_length = archive_le16dec(p + 28);
- extra_length = archive_le16dec(p + 30);
- comment_length = archive_le16dec(p + 32);
- /* disk_start = archive_le16dec(p + 34);
- * Better be zero.
- * internal_attributes = archive_le16dec(p + 36);
- * text bit */
- external_attributes = archive_le32dec(p + 38);
- zip_entry->local_header_offset =
- archive_le32dec(p + 42) + correction;
-
- /* If we can't guess the mode, leave it zero here;
- when we read the local file header we might get
- more information. */
- if (zip_entry->system == 3) {
- zip_entry->mode = external_attributes >> 16;
- } else if (zip_entry->system == 0) {
- // Interpret MSDOS directory bit
- if (0x10 == (external_attributes & 0x10)) {
- zip_entry->mode = AE_IFDIR | 0775;
- } else {
- zip_entry->mode = AE_IFREG | 0664;
- }
- if (0x01 == (external_attributes & 0x01)) {
- // Read-only bit; strip write permissions
- zip_entry->mode &= 0555;
- }
- } else {
- zip_entry->mode = 0;
- }
-
- /* We're done with the regular data; get the filename and
- * extra data. */
- __archive_read_consume(a, 46);
- p = __archive_read_ahead(a, filename_length + extra_length,
- NULL);
- if (p == NULL) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated ZIP file header");
- return ARCHIVE_FATAL;
- }
- if (ARCHIVE_OK != process_extra(a, entry, p + filename_length,
- extra_length, zip_entry)) {
- return ARCHIVE_FATAL;
- }
-
- /*
- * Mac resource fork files are stored under the
- * "__MACOSX/" directory, so we should check if
- * it is.
- */
- if (!zip->process_mac_extensions) {
- /* Treat every entry as a regular entry. */
- __archive_rb_tree_insert_node(&zip->tree,
- &zip_entry->node);
- } else {
- name = p;
- r = rsrc_basename(name, filename_length);
- if (filename_length >= 9 &&
- strncmp("__MACOSX/", name, 9) == 0) {
- /* If this file is not a resource fork nor
- * a directory. We should treat it as a non
- * resource fork file to expose it. */
- if (name[filename_length-1] != '/' &&
- (r - name < 3 || r[0] != '.' ||
- r[1] != '_')) {
- __archive_rb_tree_insert_node(
- &zip->tree, &zip_entry->node);
- /* Expose its parent directories. */
- expose_parent_dirs(zip, name,
- filename_length);
- } else {
- /* This file is a resource fork file or
- * a directory. */
- archive_strncpy(&(zip_entry->rsrcname),
- name, filename_length);
- __archive_rb_tree_insert_node(
- &zip->tree_rsrc, &zip_entry->node);
- }
- } else {
- /* Generate resource fork name to find its
- * resource file at zip->tree_rsrc. */
- archive_strcpy(&(zip_entry->rsrcname),
- "__MACOSX/");
- archive_strncat(&(zip_entry->rsrcname),
- name, r - name);
- archive_strcat(&(zip_entry->rsrcname), "._");
- archive_strncat(&(zip_entry->rsrcname),
- name + (r - name),
- filename_length - (r - name));
- /* Register an entry to RB tree to sort it by
- * file offset. */
- __archive_rb_tree_insert_node(&zip->tree,
- &zip_entry->node);
- }
- }
-
- /* Skip the comment too ... */
- __archive_read_consume(a,
- filename_length + extra_length + comment_length);
- }
-
- return ARCHIVE_OK;
-}
-
-static ssize_t
-zip_get_local_file_header_size(struct archive_read *a, size_t extra)
-{
- const char *p;
- ssize_t filename_length, extra_length;
-
- if ((p = __archive_read_ahead(a, extra + 30, NULL)) == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated ZIP file header");
- return (ARCHIVE_WARN);
- }
- p += extra;
-
- if (memcmp(p, "PK\003\004", 4) != 0) {
- archive_set_error(&a->archive, -1, "Damaged Zip archive");
- return ARCHIVE_WARN;
- }
- filename_length = archive_le16dec(p + 26);
- extra_length = archive_le16dec(p + 28);
-
- return (30 + filename_length + extra_length);
-}
-
-static int
-zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
- struct zip_entry *rsrc)
-{
- struct zip *zip = (struct zip *)a->format->data;
- unsigned char *metadata, *mp;
- int64_t offset = archive_filter_bytes(&a->archive, 0);
- size_t remaining_bytes, metadata_bytes;
- ssize_t hsize;
- int ret = ARCHIVE_OK, eof;
-
- switch(rsrc->compression) {
- case 0: /* No compression. */
- if (rsrc->uncompressed_size != rsrc->compressed_size) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Malformed OS X metadata entry: "
- "inconsistent size");
- return (ARCHIVE_FATAL);
- }
-#ifdef HAVE_ZLIB_H
- case 8: /* Deflate compression. */
-#endif
- break;
- default: /* Unsupported compression. */
- /* Return a warning. */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unsupported ZIP compression method (%s)",
- compression_name(rsrc->compression));
- /* We can't decompress this entry, but we will
- * be able to skip() it and try the next entry. */
- return (ARCHIVE_WARN);
- }
-
- if (rsrc->uncompressed_size > (4 * 1024 * 1024)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Mac metadata is too large: %jd > 4M bytes",
- (intmax_t)rsrc->uncompressed_size);
- return (ARCHIVE_WARN);
- }
- if (rsrc->compressed_size > (4 * 1024 * 1024)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Mac metadata is too large: %jd > 4M bytes",
- (intmax_t)rsrc->compressed_size);
- return (ARCHIVE_WARN);
- }
-
- metadata = malloc((size_t)rsrc->uncompressed_size);
- if (metadata == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Mac metadata");
- return (ARCHIVE_FATAL);
- }
-
- if (offset < rsrc->local_header_offset)
- __archive_read_consume(a, rsrc->local_header_offset - offset);
- else if (offset != rsrc->local_header_offset) {
- __archive_read_seek(a, rsrc->local_header_offset, SEEK_SET);
- }
-
- hsize = zip_get_local_file_header_size(a, 0);
- __archive_read_consume(a, hsize);
-
- remaining_bytes = (size_t)rsrc->compressed_size;
- metadata_bytes = (size_t)rsrc->uncompressed_size;
- mp = metadata;
- eof = 0;
- while (!eof && remaining_bytes) {
- const unsigned char *p;
- ssize_t bytes_avail;
- size_t bytes_used;
-
- p = __archive_read_ahead(a, 1, &bytes_avail);
- if (p == NULL) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated ZIP file header");
- ret = ARCHIVE_WARN;
- goto exit_mac_metadata;
- }
- if ((size_t)bytes_avail > remaining_bytes)
- bytes_avail = remaining_bytes;
- switch(rsrc->compression) {
- case 0: /* No compression. */
- if ((size_t)bytes_avail > metadata_bytes)
- bytes_avail = metadata_bytes;
- memcpy(mp, p, bytes_avail);
- bytes_used = (size_t)bytes_avail;
- metadata_bytes -= bytes_used;
- mp += bytes_used;
- if (metadata_bytes == 0)
- eof = 1;
- break;
-#ifdef HAVE_ZLIB_H
- case 8: /* Deflate compression. */
- {
- int r;
-
- ret = zip_deflate_init(a, zip);
- if (ret != ARCHIVE_OK)
- goto exit_mac_metadata;
- zip->stream.next_in =
- (Bytef *)(uintptr_t)(const void *)p;
- zip->stream.avail_in = (uInt)bytes_avail;
- zip->stream.total_in = 0;
- zip->stream.next_out = mp;
- zip->stream.avail_out = (uInt)metadata_bytes;
- zip->stream.total_out = 0;
-
- r = inflate(&zip->stream, 0);
- switch (r) {
- case Z_OK:
- break;
- case Z_STREAM_END:
- eof = 1;
- break;
- case Z_MEM_ERROR:
- archive_set_error(&a->archive, ENOMEM,
- "Out of memory for ZIP decompression");
- ret = ARCHIVE_FATAL;
- goto exit_mac_metadata;
- default:
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "ZIP decompression failed (%d)", r);
- ret = ARCHIVE_FATAL;
- goto exit_mac_metadata;
- }
- bytes_used = zip->stream.total_in;
- metadata_bytes -= zip->stream.total_out;
- mp += zip->stream.total_out;
- break;
- }
-#endif
- default:
- bytes_used = 0;
- break;
- }
- __archive_read_consume(a, bytes_used);
- remaining_bytes -= bytes_used;
- }
- archive_entry_copy_mac_metadata(entry, metadata,
- (size_t)rsrc->uncompressed_size - metadata_bytes);
-
-exit_mac_metadata:
- __archive_read_seek(a, offset, SEEK_SET);
- zip->decompress_init = 0;
- free(metadata);
- return (ret);
-}
-
-static int
-archive_read_format_zip_seekable_read_header(struct archive_read *a,
- struct archive_entry *entry)
-{
- struct zip *zip = (struct zip *)a->format->data;
- struct zip_entry *rsrc;
- int64_t offset;
- int r, ret = ARCHIVE_OK;
-
- /*
- * It should be sufficient to call archive_read_next_header() for
- * a reader to determine if an entry is encrypted or not. If the
- * encryption of an entry is only detectable when calling
- * archive_read_data(), so be it. We'll do the same check there
- * as well.
- */
- if (zip->has_encrypted_entries ==
- ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW)
- zip->has_encrypted_entries = 0;
-
- a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
- if (a->archive.archive_format_name == NULL)
- a->archive.archive_format_name = "ZIP";
-
- if (zip->zip_entries == NULL) {
- r = slurp_central_directory(a, entry, zip);
- if (r != ARCHIVE_OK)
- return r;
- /* Get first entry whose local header offset is lower than
- * other entries in the archive file. */
- zip->entry =
- (struct zip_entry *)ARCHIVE_RB_TREE_MIN(&zip->tree);
- } else if (zip->entry != NULL) {
- /* Get next entry in local header offset order. */
- zip->entry = (struct zip_entry *)__archive_rb_tree_iterate(
- &zip->tree, &zip->entry->node, ARCHIVE_RB_DIR_RIGHT);
- }
-
- if (zip->entry == NULL)
- return ARCHIVE_EOF;
-
- if (zip->entry->rsrcname.s)
- rsrc = (struct zip_entry *)__archive_rb_tree_find_node(
- &zip->tree_rsrc, zip->entry->rsrcname.s);
- else
- rsrc = NULL;
-
- if (zip->cctx_valid)
- archive_decrypto_aes_ctr_release(&zip->cctx);
- if (zip->hctx_valid)
- archive_hmac_sha1_cleanup(&zip->hctx);
- zip->tctx_valid = zip->cctx_valid = zip->hctx_valid = 0;
- __archive_read_reset_passphrase(a);
-
- /* File entries are sorted by the header offset, we should mostly
- * use __archive_read_consume to advance a read point to avoid
- * redundant data reading. */
- offset = archive_filter_bytes(&a->archive, 0);
- if (offset < zip->entry->local_header_offset)
- __archive_read_consume(a,
- zip->entry->local_header_offset - offset);
- else if (offset != zip->entry->local_header_offset) {
- __archive_read_seek(a, zip->entry->local_header_offset,
- SEEK_SET);
- }
- zip->unconsumed = 0;
- r = zip_read_local_file_header(a, entry, zip);
- if (r != ARCHIVE_OK)
- return r;
- if (rsrc) {
- int ret2 = zip_read_mac_metadata(a, entry, rsrc);
- if (ret2 < ret)
- ret = ret2;
- }
- return (ret);
-}
-
-/*
- * We're going to seek for the next header anyway, so we don't
- * need to bother doing anything here.
- */
-static int
-archive_read_format_zip_read_data_skip_seekable(struct archive_read *a)
-{
- struct zip *zip;
- zip = (struct zip *)(a->format->data);
-
- zip->unconsumed = 0;
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_support_format_zip_seekable(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- struct zip *zip;
- int r;
-
- archive_check_magic(_a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_format_zip_seekable");
-
- zip = (struct zip *)calloc(1, sizeof(*zip));
- if (zip == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate zip data");
- return (ARCHIVE_FATAL);
- }
-
-#ifdef HAVE_COPYFILE_H
- /* Set this by default on Mac OS. */
- zip->process_mac_extensions = 1;
-#endif
-
- /*
- * Until enough data has been read, we cannot tell about
- * any encrypted entries yet.
- */
- zip->has_encrypted_entries = ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
- zip->crc32func = real_crc32;
-
- r = __archive_read_register_format(a,
- zip,
- "zip",
- archive_read_format_zip_seekable_bid,
- archive_read_format_zip_options,
- archive_read_format_zip_seekable_read_header,
- archive_read_format_zip_read_data,
- archive_read_format_zip_read_data_skip_seekable,
- NULL,
- archive_read_format_zip_cleanup,
- archive_read_support_format_zip_capabilities_seekable,
- archive_read_format_zip_has_encrypted_entries);
-
- if (r != ARCHIVE_OK)
- free(zip);
- return (ARCHIVE_OK);
-}
-
-/*# vim:set noet:*/
diff --git a/contrib/libs/libarchive/libarchive/archive_string.c b/contrib/libs/libarchive/libarchive/archive_string.c
deleted file mode 100644
index c89b315399..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_string.c
+++ /dev/null
@@ -1,4244 +0,0 @@
-/*-
- * Copyright (c) 2003-2011 Tim Kientzle
- * Copyright (c) 2011-2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_string.c 201095 2009-12-28 02:33:22Z kientzle $");
-
-/*
- * Basic resizable string support, to simplify manipulating arbitrary-sized
- * strings while minimizing heap activity.
- *
- * In particular, the buffer used by a string object is only grown, it
- * never shrinks, so you can clear and reuse the same string object
- * without incurring additional memory allocations.
- */
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_ICONV_H
-#include <iconv.h>
-#endif
-#ifdef HAVE_LANGINFO_H
-#include <langinfo.h>
-#endif
-#ifdef HAVE_LOCALCHARSET_H
-#error #include <localcharset.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_WCHAR_H
-#include <wchar.h>
-#endif
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#include <windows.h>
-#include <locale.h>
-#endif
-
-#include "archive_endian.h"
-#include "archive_private.h"
-#include "archive_string.h"
-#include "archive_string_composition.h"
-
-#if !defined(HAVE_WMEMCPY) && !defined(wmemcpy)
-#define wmemcpy(a,b,i) (wchar_t *)memcpy((a), (b), (i) * sizeof(wchar_t))
-#endif
-
-#if !defined(HAVE_WMEMMOVE) && !defined(wmemmove)
-#define wmemmove(a,b,i) (wchar_t *)memmove((a), (b), (i) * sizeof(wchar_t))
-#endif
-
-#undef max
-#define max(a, b) ((a)>(b)?(a):(b))
-
-struct archive_string_conv {
- struct archive_string_conv *next;
- char *from_charset;
- char *to_charset;
- unsigned from_cp;
- unsigned to_cp;
- /* Set 1 if from_charset and to_charset are the same. */
- int same;
- int flag;
-#define SCONV_TO_CHARSET 1 /* MBS is being converted to specified
- * charset. */
-#define SCONV_FROM_CHARSET (1<<1) /* MBS is being converted from
- * specified charset. */
-#define SCONV_BEST_EFFORT (1<<2) /* Copy at least ASCII code. */
-#define SCONV_WIN_CP (1<<3) /* Use Windows API for converting
- * MBS. */
-#define SCONV_UTF8_LIBARCHIVE_2 (1<<4) /* Incorrect UTF-8 made by libarchive
- * 2.x in the wrong assumption. */
-#define SCONV_NORMALIZATION_C (1<<6) /* Need normalization to be Form C.
- * Before UTF-8 characters are actually
- * processed. */
-#define SCONV_NORMALIZATION_D (1<<7) /* Need normalization to be Form D.
- * Before UTF-8 characters are actually
- * processed.
- * Currently this only for MAC OS X. */
-#define SCONV_TO_UTF8 (1<<8) /* "to charset" side is UTF-8. */
-#define SCONV_FROM_UTF8 (1<<9) /* "from charset" side is UTF-8. */
-#define SCONV_TO_UTF16BE (1<<10) /* "to charset" side is UTF-16BE. */
-#define SCONV_FROM_UTF16BE (1<<11) /* "from charset" side is UTF-16BE. */
-#define SCONV_TO_UTF16LE (1<<12) /* "to charset" side is UTF-16LE. */
-#define SCONV_FROM_UTF16LE (1<<13) /* "from charset" side is UTF-16LE. */
-#define SCONV_TO_UTF16 (SCONV_TO_UTF16BE | SCONV_TO_UTF16LE)
-#define SCONV_FROM_UTF16 (SCONV_FROM_UTF16BE | SCONV_FROM_UTF16LE)
-
-#if HAVE_ICONV
- iconv_t cd;
- iconv_t cd_w;/* Use at archive_mstring on
- * Windows. */
-#endif
- /* A temporary buffer for normalization. */
- struct archive_string utftmp;
- int (*converter[2])(struct archive_string *, const void *, size_t,
- struct archive_string_conv *);
- int nconverter;
-};
-
-#define CP_C_LOCALE 0 /* "C" locale only for this file. */
-#define CP_UTF16LE 1200
-#define CP_UTF16BE 1201
-
-#define IS_HIGH_SURROGATE_LA(uc) ((uc) >= 0xD800 && (uc) <= 0xDBFF)
-#define IS_LOW_SURROGATE_LA(uc) ((uc) >= 0xDC00 && (uc) <= 0xDFFF)
-#define IS_SURROGATE_PAIR_LA(uc) ((uc) >= 0xD800 && (uc) <= 0xDFFF)
-#define UNICODE_MAX 0x10FFFF
-#define UNICODE_R_CHAR 0xFFFD /* Replacement character. */
-/* Set U+FFFD(Replacement character) in UTF-8. */
-static const char utf8_replacement_char[] = {0xef, 0xbf, 0xbd};
-
-static struct archive_string_conv *find_sconv_object(struct archive *,
- const char *, const char *);
-static void add_sconv_object(struct archive *, struct archive_string_conv *);
-static struct archive_string_conv *create_sconv_object(const char *,
- const char *, unsigned, int);
-static void free_sconv_object(struct archive_string_conv *);
-static struct archive_string_conv *get_sconv_object(struct archive *,
- const char *, const char *, int);
-static unsigned make_codepage_from_charset(const char *);
-static unsigned get_current_codepage(void);
-static unsigned get_current_oemcp(void);
-static size_t mbsnbytes(const void *, size_t);
-static size_t utf16nbytes(const void *, size_t);
-#if defined(_WIN32) && !defined(__CYGWIN__)
-static int archive_wstring_append_from_mbs_in_codepage(
- struct archive_wstring *, const char *, size_t,
- struct archive_string_conv *);
-static int archive_string_append_from_wcs_in_codepage(struct archive_string *,
- const wchar_t *, size_t, struct archive_string_conv *);
-static int is_big_endian(void);
-static int strncat_in_codepage(struct archive_string *, const void *,
- size_t, struct archive_string_conv *);
-static int win_strncat_from_utf16be(struct archive_string *, const void *,
- size_t, struct archive_string_conv *);
-static int win_strncat_from_utf16le(struct archive_string *, const void *,
- size_t, struct archive_string_conv *);
-static int win_strncat_to_utf16be(struct archive_string *, const void *,
- size_t, struct archive_string_conv *);
-static int win_strncat_to_utf16le(struct archive_string *, const void *,
- size_t, struct archive_string_conv *);
-#endif
-static int best_effort_strncat_from_utf16be(struct archive_string *,
- const void *, size_t, struct archive_string_conv *);
-static int best_effort_strncat_from_utf16le(struct archive_string *,
- const void *, size_t, struct archive_string_conv *);
-static int best_effort_strncat_to_utf16be(struct archive_string *,
- const void *, size_t, struct archive_string_conv *);
-static int best_effort_strncat_to_utf16le(struct archive_string *,
- const void *, size_t, struct archive_string_conv *);
-#if defined(HAVE_ICONV)
-static int iconv_strncat_in_locale(struct archive_string *, const void *,
- size_t, struct archive_string_conv *);
-#endif
-static int best_effort_strncat_in_locale(struct archive_string *,
- const void *, size_t, struct archive_string_conv *);
-static int _utf8_to_unicode(uint32_t *, const char *, size_t);
-static int utf8_to_unicode(uint32_t *, const char *, size_t);
-static inline uint32_t combine_surrogate_pair(uint32_t, uint32_t);
-static int cesu8_to_unicode(uint32_t *, const char *, size_t);
-static size_t unicode_to_utf8(char *, size_t, uint32_t);
-static int utf16_to_unicode(uint32_t *, const char *, size_t, int);
-static size_t unicode_to_utf16be(char *, size_t, uint32_t);
-static size_t unicode_to_utf16le(char *, size_t, uint32_t);
-static int strncat_from_utf8_libarchive2(struct archive_string *,
- const void *, size_t, struct archive_string_conv *);
-static int strncat_from_utf8_to_utf8(struct archive_string *, const void *,
- size_t, struct archive_string_conv *);
-static int archive_string_normalize_C(struct archive_string *, const void *,
- size_t, struct archive_string_conv *);
-static int archive_string_normalize_D(struct archive_string *, const void *,
- size_t, struct archive_string_conv *);
-static int archive_string_append_unicode(struct archive_string *,
- const void *, size_t, struct archive_string_conv *);
-
-static struct archive_string *
-archive_string_append(struct archive_string *as, const char *p, size_t s)
-{
- if (archive_string_ensure(as, as->length + s + 1) == NULL)
- return (NULL);
- if (s)
- memmove(as->s + as->length, p, s);
- as->length += s;
- as->s[as->length] = 0;
- return (as);
-}
-
-static struct archive_wstring *
-archive_wstring_append(struct archive_wstring *as, const wchar_t *p, size_t s)
-{
- if (archive_wstring_ensure(as, as->length + s + 1) == NULL)
- return (NULL);
- if (s)
- wmemmove(as->s + as->length, p, s);
- as->length += s;
- as->s[as->length] = 0;
- return (as);
-}
-
-struct archive_string *
-archive_array_append(struct archive_string *as, const char *p, size_t s)
-{
- return archive_string_append(as, p, s);
-}
-
-void
-archive_string_concat(struct archive_string *dest, struct archive_string *src)
-{
- if (archive_string_append(dest, src->s, src->length) == NULL)
- __archive_errx(1, "Out of memory");
-}
-
-void
-archive_wstring_concat(struct archive_wstring *dest,
- struct archive_wstring *src)
-{
- if (archive_wstring_append(dest, src->s, src->length) == NULL)
- __archive_errx(1, "Out of memory");
-}
-
-void
-archive_string_free(struct archive_string *as)
-{
- as->length = 0;
- as->buffer_length = 0;
- free(as->s);
- as->s = NULL;
-}
-
-void
-archive_wstring_free(struct archive_wstring *as)
-{
- as->length = 0;
- as->buffer_length = 0;
- free(as->s);
- as->s = NULL;
-}
-
-struct archive_wstring *
-archive_wstring_ensure(struct archive_wstring *as, size_t s)
-{
- return (struct archive_wstring *)
- archive_string_ensure((struct archive_string *)as,
- s * sizeof(wchar_t));
-}
-
-/* Returns NULL on any allocation failure. */
-struct archive_string *
-archive_string_ensure(struct archive_string *as, size_t s)
-{
- char *p;
- size_t new_length;
-
- /* If buffer is already big enough, don't reallocate. */
- if (as->s && (s <= as->buffer_length))
- return (as);
-
- /*
- * Growing the buffer at least exponentially ensures that
- * append operations are always linear in the number of
- * characters appended. Using a smaller growth rate for
- * larger buffers reduces memory waste somewhat at the cost of
- * a larger constant factor.
- */
- if (as->buffer_length < 32)
- /* Start with a minimum 32-character buffer. */
- new_length = 32;
- else if (as->buffer_length < 8192)
- /* Buffers under 8k are doubled for speed. */
- new_length = as->buffer_length + as->buffer_length;
- else {
- /* Buffers 8k and over grow by at least 25% each time. */
- new_length = as->buffer_length + as->buffer_length / 4;
- /* Be safe: If size wraps, fail. */
- if (new_length < as->buffer_length) {
- /* On failure, wipe the string and return NULL. */
- archive_string_free(as);
- errno = ENOMEM;/* Make sure errno has ENOMEM. */
- return (NULL);
- }
- }
- /*
- * The computation above is a lower limit to how much we'll
- * grow the buffer. In any case, we have to grow it enough to
- * hold the request.
- */
- if (new_length < s)
- new_length = s;
- /* Now we can reallocate the buffer. */
- p = (char *)realloc(as->s, new_length);
- if (p == NULL) {
- /* On failure, wipe the string and return NULL. */
- archive_string_free(as);
- errno = ENOMEM;/* Make sure errno has ENOMEM. */
- return (NULL);
- }
-
- as->s = p;
- as->buffer_length = new_length;
- return (as);
-}
-
-/*
- * TODO: See if there's a way to avoid scanning
- * the source string twice. Then test to see
- * if it actually helps (remember that we're almost
- * always called with pretty short arguments, so
- * such an optimization might not help).
- */
-struct archive_string *
-archive_strncat(struct archive_string *as, const void *_p, size_t n)
-{
- size_t s;
- const char *p, *pp;
-
- p = (const char *)_p;
-
- /* Like strlen(p), except won't examine positions beyond p[n]. */
- s = 0;
- pp = p;
- while (s < n && *pp) {
- pp++;
- s++;
- }
- if ((as = archive_string_append(as, p, s)) == NULL)
- __archive_errx(1, "Out of memory");
- return (as);
-}
-
-struct archive_wstring *
-archive_wstrncat(struct archive_wstring *as, const wchar_t *p, size_t n)
-{
- size_t s;
- const wchar_t *pp;
-
- /* Like strlen(p), except won't examine positions beyond p[n]. */
- s = 0;
- pp = p;
- while (s < n && *pp) {
- pp++;
- s++;
- }
- if ((as = archive_wstring_append(as, p, s)) == NULL)
- __archive_errx(1, "Out of memory");
- return (as);
-}
-
-struct archive_string *
-archive_strcat(struct archive_string *as, const void *p)
-{
- /* strcat is just strncat without an effective limit.
- * Assert that we'll never get called with a source
- * string over 16MB.
- * TODO: Review all uses of strcat in the source
- * and try to replace them with strncat().
- */
- return archive_strncat(as, p, 0x1000000);
-}
-
-struct archive_wstring *
-archive_wstrcat(struct archive_wstring *as, const wchar_t *p)
-{
- /* Ditto. */
- return archive_wstrncat(as, p, 0x1000000);
-}
-
-struct archive_string *
-archive_strappend_char(struct archive_string *as, char c)
-{
- if ((as = archive_string_append(as, &c, 1)) == NULL)
- __archive_errx(1, "Out of memory");
- return (as);
-}
-
-struct archive_wstring *
-archive_wstrappend_wchar(struct archive_wstring *as, wchar_t c)
-{
- if ((as = archive_wstring_append(as, &c, 1)) == NULL)
- __archive_errx(1, "Out of memory");
- return (as);
-}
-
-/*
- * Get the "current character set" name to use with iconv.
- * On FreeBSD, the empty character set name "" chooses
- * the correct character encoding for the current locale,
- * so this isn't necessary.
- * But iconv on Mac OS 10.6 doesn't seem to handle this correctly;
- * on that system, we have to explicitly call nl_langinfo()
- * to get the right name. Not sure about other platforms.
- *
- * NOTE: GNU libiconv does not recognize the character-set name
- * which some platform nl_langinfo(CODESET) returns, so we should
- * use locale_charset() instead of nl_langinfo(CODESET) for GNU libiconv.
- */
-static const char *
-default_iconv_charset(const char *charset) {
- if (charset != NULL && charset[0] != '\0')
- return charset;
-#if HAVE_LOCALE_CHARSET && !defined(__APPLE__)
- /* locale_charset() is broken on Mac OS */
- return locale_charset();
-#elif HAVE_NL_LANGINFO
- return nl_langinfo(CODESET);
-#else
- return "";
-#endif
-}
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-
-/*
- * Convert MBS to WCS.
- * Note: returns -1 if conversion fails.
- */
-int
-archive_wstring_append_from_mbs(struct archive_wstring *dest,
- const char *p, size_t len)
-{
- return archive_wstring_append_from_mbs_in_codepage(dest, p, len, NULL);
-}
-
-static int
-archive_wstring_append_from_mbs_in_codepage(struct archive_wstring *dest,
- const char *s, size_t length, struct archive_string_conv *sc)
-{
- int count, ret = 0;
- UINT from_cp;
-
- if (sc != NULL)
- from_cp = sc->from_cp;
- else
- from_cp = get_current_codepage();
-
- if (from_cp == CP_C_LOCALE) {
- /*
- * "C" locale special processing.
- */
- wchar_t *ws;
- const unsigned char *mp;
-
- if (NULL == archive_wstring_ensure(dest,
- dest->length + length + 1))
- return (-1);
-
- ws = dest->s + dest->length;
- mp = (const unsigned char *)s;
- count = 0;
- while (count < (int)length && *mp) {
- *ws++ = (wchar_t)*mp++;
- count++;
- }
- } else if (sc != NULL &&
- (sc->flag & (SCONV_NORMALIZATION_C | SCONV_NORMALIZATION_D))) {
- /*
- * Normalize UTF-8 and UTF-16BE and convert it directly
- * to UTF-16 as wchar_t.
- */
- struct archive_string u16;
- int saved_flag = sc->flag;/* save current flag. */
-
- if (is_big_endian())
- sc->flag |= SCONV_TO_UTF16BE;
- else
- sc->flag |= SCONV_TO_UTF16LE;
-
- if (sc->flag & SCONV_FROM_UTF16) {
- /*
- * UTF-16BE/LE NFD ===> UTF-16 NFC
- * UTF-16BE/LE NFC ===> UTF-16 NFD
- */
- count = (int)utf16nbytes(s, length);
- } else {
- /*
- * UTF-8 NFD ===> UTF-16 NFC
- * UTF-8 NFC ===> UTF-16 NFD
- */
- count = (int)mbsnbytes(s, length);
- }
- u16.s = (char *)dest->s;
- u16.length = dest->length << 1;;
- u16.buffer_length = dest->buffer_length;
- if (sc->flag & SCONV_NORMALIZATION_C)
- ret = archive_string_normalize_C(&u16, s, count, sc);
- else
- ret = archive_string_normalize_D(&u16, s, count, sc);
- dest->s = (wchar_t *)u16.s;
- dest->length = u16.length >> 1;
- dest->buffer_length = u16.buffer_length;
- sc->flag = saved_flag;/* restore the saved flag. */
- return (ret);
- } else if (sc != NULL && (sc->flag & SCONV_FROM_UTF16)) {
- count = (int)utf16nbytes(s, length);
- count >>= 1; /* to be WCS length */
- /* Allocate memory for WCS. */
- if (NULL == archive_wstring_ensure(dest,
- dest->length + count + 1))
- return (-1);
- wmemcpy(dest->s + dest->length, (const wchar_t *)s, count);
- if ((sc->flag & SCONV_FROM_UTF16BE) && !is_big_endian()) {
- uint16_t *u16 = (uint16_t *)(dest->s + dest->length);
- int b;
- for (b = 0; b < count; b++) {
- uint16_t val = archive_le16dec(u16+b);
- archive_be16enc(u16+b, val);
- }
- } else if ((sc->flag & SCONV_FROM_UTF16LE) && is_big_endian()) {
- uint16_t *u16 = (uint16_t *)(dest->s + dest->length);
- int b;
- for (b = 0; b < count; b++) {
- uint16_t val = archive_be16dec(u16+b);
- archive_le16enc(u16+b, val);
- }
- }
- } else {
- DWORD mbflag;
- size_t buffsize;
-
- if (sc == NULL)
- mbflag = 0;
- else if (sc->flag & SCONV_FROM_CHARSET) {
- /* Do not trust the length which comes from
- * an archive file. */
- length = mbsnbytes(s, length);
- mbflag = 0;
- } else
- mbflag = MB_PRECOMPOSED;
-
- buffsize = dest->length + length + 1;
- do {
- /* Allocate memory for WCS. */
- if (NULL == archive_wstring_ensure(dest, buffsize))
- return (-1);
- /* Convert MBS to WCS. */
- count = MultiByteToWideChar(from_cp,
- mbflag, s, (int)length, dest->s + dest->length,
- (int)(dest->buffer_length >> 1) -1);
- if (count == 0 &&
- GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
- /* Expand the WCS buffer. */
- buffsize = dest->buffer_length << 1;
- continue;
- }
- if (count == 0 && length != 0)
- ret = -1;
- break;
- } while (1);
- }
- dest->length += count;
- dest->s[dest->length] = L'\0';
- return (ret);
-}
-
-#else
-
-/*
- * Convert MBS to WCS.
- * Note: returns -1 if conversion fails.
- */
-int
-archive_wstring_append_from_mbs(struct archive_wstring *dest,
- const char *p, size_t len)
-{
- size_t r;
- int ret_val = 0;
- /*
- * No single byte will be more than one wide character,
- * so this length estimate will always be big enough.
- */
- // size_t wcs_length = len;
- size_t mbs_length = len;
- const char *mbs = p;
- wchar_t *wcs;
-#if HAVE_MBRTOWC
- mbstate_t shift_state;
-
- memset(&shift_state, 0, sizeof(shift_state));
-#endif
- /*
- * As we decided to have wcs_length == mbs_length == len
- * we can use len here instead of wcs_length
- */
- if (NULL == archive_wstring_ensure(dest, dest->length + len + 1))
- return (-1);
- wcs = dest->s + dest->length;
- /*
- * We cannot use mbsrtowcs/mbstowcs here because those may convert
- * extra MBS when strlen(p) > len and one wide character consists of
- * multi bytes.
- */
- while (*mbs && mbs_length > 0) {
- /*
- * The buffer we allocated is always big enough.
- * Keep this code path in a comment if we decide to choose
- * smaller wcs_length in the future
- */
-/*
- if (wcs_length == 0) {
- dest->length = wcs - dest->s;
- dest->s[dest->length] = L'\0';
- wcs_length = mbs_length;
- if (NULL == archive_wstring_ensure(dest,
- dest->length + wcs_length + 1))
- return (-1);
- wcs = dest->s + dest->length;
- }
-*/
-#if HAVE_MBRTOWC
- r = mbrtowc(wcs, mbs, mbs_length, &shift_state);
-#else
- r = mbtowc(wcs, mbs, mbs_length);
-#endif
- if (r == (size_t)-1 || r == (size_t)-2) {
- ret_val = -1;
- break;
- }
- if (r == 0 || r > mbs_length)
- break;
- wcs++;
- // wcs_length--;
- mbs += r;
- mbs_length -= r;
- }
- dest->length = wcs - dest->s;
- dest->s[dest->length] = L'\0';
- return (ret_val);
-}
-
-#endif
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-
-/*
- * WCS ==> MBS.
- * Note: returns -1 if conversion fails.
- *
- * Win32 builds use WideCharToMultiByte from the Windows API.
- * (Maybe Cygwin should too? WideCharToMultiByte will know a
- * lot more about local character encodings than the wcrtomb()
- * wrapper is going to know.)
- */
-int
-archive_string_append_from_wcs(struct archive_string *as,
- const wchar_t *w, size_t len)
-{
- return archive_string_append_from_wcs_in_codepage(as, w, len, NULL);
-}
-
-static int
-archive_string_append_from_wcs_in_codepage(struct archive_string *as,
- const wchar_t *ws, size_t len, struct archive_string_conv *sc)
-{
- BOOL defchar_used, *dp;
- int count, ret = 0;
- UINT to_cp;
- int wslen = (int)len;
-
- if (sc != NULL)
- to_cp = sc->to_cp;
- else
- to_cp = get_current_codepage();
-
- if (to_cp == CP_C_LOCALE) {
- /*
- * "C" locale special processing.
- */
- const wchar_t *wp = ws;
- char *p;
-
- if (NULL == archive_string_ensure(as,
- as->length + wslen +1))
- return (-1);
- p = as->s + as->length;
- count = 0;
- defchar_used = 0;
- while (count < wslen && *wp) {
- if (*wp > 255) {
- *p++ = '?';
- wp++;
- defchar_used = 1;
- } else
- *p++ = (char)*wp++;
- count++;
- }
- } else if (sc != NULL && (sc->flag & SCONV_TO_UTF16)) {
- uint16_t *u16;
-
- if (NULL ==
- archive_string_ensure(as, as->length + len * 2 + 2))
- return (-1);
- u16 = (uint16_t *)(as->s + as->length);
- count = 0;
- defchar_used = 0;
- if (sc->flag & SCONV_TO_UTF16BE) {
- while (count < (int)len && *ws) {
- archive_be16enc(u16+count, *ws);
- ws++;
- count++;
- }
- } else {
- while (count < (int)len && *ws) {
- archive_le16enc(u16+count, *ws);
- ws++;
- count++;
- }
- }
- count <<= 1; /* to be byte size */
- } else {
- /* Make sure the MBS buffer has plenty to set. */
- if (NULL ==
- archive_string_ensure(as, as->length + len * 2 + 1))
- return (-1);
- do {
- defchar_used = 0;
- if (to_cp == CP_UTF8 || sc == NULL)
- dp = NULL;
- else
- dp = &defchar_used;
- count = WideCharToMultiByte(to_cp, 0, ws, wslen,
- as->s + as->length,
- (int)as->buffer_length - (int)as->length - 1, NULL, dp);
- if (count == 0 &&
- GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
- /* Expand the MBS buffer and retry. */
- if (NULL == archive_string_ensure(as,
- as->buffer_length + len))
- return (-1);
- continue;
- }
- if (count == 0)
- ret = -1;
- break;
- } while (1);
- }
- as->length += count;
- as->s[as->length] = '\0';
- return (defchar_used?-1:ret);
-}
-
-#elif defined(HAVE_WCTOMB) || defined(HAVE_WCRTOMB)
-
-/*
- * Translates a wide character string into current locale character set
- * and appends to the archive_string. Note: returns -1 if conversion
- * fails.
- */
-int
-archive_string_append_from_wcs(struct archive_string *as,
- const wchar_t *w, size_t len)
-{
- /* We cannot use the standard wcstombs() here because it
- * cannot tell us how big the output buffer should be. So
- * I've built a loop around wcrtomb() or wctomb() that
- * converts a character at a time and resizes the string as
- * needed. We prefer wcrtomb() when it's available because
- * it's thread-safe. */
- int n, ret_val = 0;
- char *p;
- char *end;
-#if HAVE_WCRTOMB
- mbstate_t shift_state;
-
- memset(&shift_state, 0, sizeof(shift_state));
-#else
- /* Clear the shift state before starting. */
- wctomb(NULL, L'\0');
-#endif
- /*
- * Allocate buffer for MBS.
- * We need this allocation here since it is possible that
- * as->s is still NULL.
- */
- if (archive_string_ensure(as, as->length + len + 1) == NULL)
- return (-1);
-
- p = as->s + as->length;
- end = as->s + as->buffer_length - MB_CUR_MAX -1;
- while (*w != L'\0' && len > 0) {
- if (p >= end) {
- as->length = p - as->s;
- as->s[as->length] = '\0';
- /* Re-allocate buffer for MBS. */
- if (archive_string_ensure(as,
- as->length + max(len * 2,
- (size_t)MB_CUR_MAX) + 1) == NULL)
- return (-1);
- p = as->s + as->length;
- end = as->s + as->buffer_length - MB_CUR_MAX -1;
- }
-#if HAVE_WCRTOMB
- n = wcrtomb(p, *w++, &shift_state);
-#else
- n = wctomb(p, *w++);
-#endif
- if (n == -1) {
- if (errno == EILSEQ) {
- /* Skip an illegal wide char. */
- *p++ = '?';
- ret_val = -1;
- } else {
- ret_val = -1;
- break;
- }
- } else
- p += n;
- len--;
- }
- as->length = p - as->s;
- as->s[as->length] = '\0';
- return (ret_val);
-}
-
-#else /* HAVE_WCTOMB || HAVE_WCRTOMB */
-
-/*
- * TODO: Test if __STDC_ISO_10646__ is defined.
- * Non-Windows uses ISO C wcrtomb() or wctomb() to perform the conversion
- * one character at a time. If a non-Windows platform doesn't have
- * either of these, fall back to the built-in UTF8 conversion.
- */
-int
-archive_string_append_from_wcs(struct archive_string *as,
- const wchar_t *w, size_t len)
-{
- (void)as;/* UNUSED */
- (void)w;/* UNUSED */
- (void)len;/* UNUSED */
- errno = ENOSYS;
- return (-1);
-}
-
-#endif /* HAVE_WCTOMB || HAVE_WCRTOMB */
-
-/*
- * Find a string conversion object by a pair of 'from' charset name
- * and 'to' charset name from an archive object.
- * Return NULL if not found.
- */
-static struct archive_string_conv *
-find_sconv_object(struct archive *a, const char *fc, const char *tc)
-{
- struct archive_string_conv *sc;
-
- if (a == NULL)
- return (NULL);
-
- for (sc = a->sconv; sc != NULL; sc = sc->next) {
- if (strcmp(sc->from_charset, fc) == 0 &&
- strcmp(sc->to_charset, tc) == 0)
- break;
- }
- return (sc);
-}
-
-/*
- * Register a string object to an archive object.
- */
-static void
-add_sconv_object(struct archive *a, struct archive_string_conv *sc)
-{
- struct archive_string_conv **psc;
-
- /* Add a new sconv to sconv list. */
- psc = &(a->sconv);
- while (*psc != NULL)
- psc = &((*psc)->next);
- *psc = sc;
-}
-
-static void
-add_converter(struct archive_string_conv *sc, int (*converter)
- (struct archive_string *, const void *, size_t,
- struct archive_string_conv *))
-{
- if (sc == NULL || sc->nconverter >= 2)
- __archive_errx(1, "Programming error");
- sc->converter[sc->nconverter++] = converter;
-}
-
-static void
-setup_converter(struct archive_string_conv *sc)
-{
-
- /* Reset. */
- sc->nconverter = 0;
-
- /*
- * Perform special sequence for the incorrect UTF-8 filenames
- * made by libarchive2.x.
- */
- if (sc->flag & SCONV_UTF8_LIBARCHIVE_2) {
- add_converter(sc, strncat_from_utf8_libarchive2);
- return;
- }
-
- /*
- * Convert a string to UTF-16BE/LE.
- */
- if (sc->flag & SCONV_TO_UTF16) {
- /*
- * If the current locale is UTF-8, we can translate
- * a UTF-8 string into a UTF-16BE string.
- */
- if (sc->flag & SCONV_FROM_UTF8) {
- add_converter(sc, archive_string_append_unicode);
- return;
- }
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if (sc->flag & SCONV_WIN_CP) {
- if (sc->flag & SCONV_TO_UTF16BE)
- add_converter(sc, win_strncat_to_utf16be);
- else
- add_converter(sc, win_strncat_to_utf16le);
- return;
- }
-#endif
-
-#if defined(HAVE_ICONV)
- if (sc->cd != (iconv_t)-1) {
- add_converter(sc, iconv_strncat_in_locale);
- return;
- }
-#endif
-
- if (sc->flag & SCONV_BEST_EFFORT) {
- if (sc->flag & SCONV_TO_UTF16BE)
- add_converter(sc,
- best_effort_strncat_to_utf16be);
- else
- add_converter(sc,
- best_effort_strncat_to_utf16le);
- } else
- /* Make sure we have no converter. */
- sc->nconverter = 0;
- return;
- }
-
- /*
- * Convert a string from UTF-16BE/LE.
- */
- if (sc->flag & SCONV_FROM_UTF16) {
- /*
- * At least we should normalize a UTF-16BE string.
- */
- if (sc->flag & SCONV_NORMALIZATION_D)
- add_converter(sc,archive_string_normalize_D);
- else if (sc->flag & SCONV_NORMALIZATION_C)
- add_converter(sc, archive_string_normalize_C);
-
- if (sc->flag & SCONV_TO_UTF8) {
- /*
- * If the current locale is UTF-8, we can translate
- * a UTF-16BE/LE string into a UTF-8 string directly.
- */
- if (!(sc->flag &
- (SCONV_NORMALIZATION_D |SCONV_NORMALIZATION_C)))
- add_converter(sc,
- archive_string_append_unicode);
- return;
- }
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if (sc->flag & SCONV_WIN_CP) {
- if (sc->flag & SCONV_FROM_UTF16BE)
- add_converter(sc, win_strncat_from_utf16be);
- else
- add_converter(sc, win_strncat_from_utf16le);
- return;
- }
-#endif
-
-#if defined(HAVE_ICONV)
- if (sc->cd != (iconv_t)-1) {
- add_converter(sc, iconv_strncat_in_locale);
- return;
- }
-#endif
-
- if ((sc->flag & (SCONV_BEST_EFFORT | SCONV_FROM_UTF16BE))
- == (SCONV_BEST_EFFORT | SCONV_FROM_UTF16BE))
- add_converter(sc, best_effort_strncat_from_utf16be);
- else if ((sc->flag & (SCONV_BEST_EFFORT | SCONV_FROM_UTF16LE))
- == (SCONV_BEST_EFFORT | SCONV_FROM_UTF16LE))
- add_converter(sc, best_effort_strncat_from_utf16le);
- else
- /* Make sure we have no converter. */
- sc->nconverter = 0;
- return;
- }
-
- if (sc->flag & SCONV_FROM_UTF8) {
- /*
- * At least we should normalize a UTF-8 string.
- */
- if (sc->flag & SCONV_NORMALIZATION_D)
- add_converter(sc,archive_string_normalize_D);
- else if (sc->flag & SCONV_NORMALIZATION_C)
- add_converter(sc, archive_string_normalize_C);
-
- /*
- * Copy UTF-8 string with a check of CESU-8.
- * Apparently, iconv does not check surrogate pairs in UTF-8
- * when both from-charset and to-charset are UTF-8, and then
- * we use our UTF-8 copy code.
- */
- if (sc->flag & SCONV_TO_UTF8) {
- /*
- * If the current locale is UTF-8, we can translate
- * a UTF-16BE string into a UTF-8 string directly.
- */
- if (!(sc->flag &
- (SCONV_NORMALIZATION_D |SCONV_NORMALIZATION_C)))
- add_converter(sc, strncat_from_utf8_to_utf8);
- return;
- }
- }
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /*
- * On Windows we can use Windows API for a string conversion.
- */
- if (sc->flag & SCONV_WIN_CP) {
- add_converter(sc, strncat_in_codepage);
- return;
- }
-#endif
-
-#if HAVE_ICONV
- if (sc->cd != (iconv_t)-1) {
- add_converter(sc, iconv_strncat_in_locale);
- /*
- * iconv generally does not support UTF-8-MAC and so
- * we have to the output of iconv from NFC to NFD if
- * need.
- */
- if ((sc->flag & SCONV_FROM_CHARSET) &&
- (sc->flag & SCONV_TO_UTF8)) {
- if (sc->flag & SCONV_NORMALIZATION_D)
- add_converter(sc, archive_string_normalize_D);
- }
- return;
- }
-#endif
-
- /*
- * Try conversion in the best effort or no conversion.
- */
- if ((sc->flag & SCONV_BEST_EFFORT) || sc->same)
- add_converter(sc, best_effort_strncat_in_locale);
- else
- /* Make sure we have no converter. */
- sc->nconverter = 0;
-}
-
-/*
- * Return canonicalized charset-name but this supports just UTF-8, UTF-16BE
- * and CP932 which are referenced in create_sconv_object().
- */
-static const char *
-canonical_charset_name(const char *charset)
-{
- char cs[16];
- char *p;
- const char *s;
-
- if (charset == NULL || charset[0] == '\0'
- || strlen(charset) > 15)
- return (charset);
-
- /* Copy name to uppercase. */
- p = cs;
- s = charset;
- while (*s) {
- char c = *s++;
- if (c >= 'a' && c <= 'z')
- c -= 'a' - 'A';
- *p++ = c;
- }
- *p++ = '\0';
-
- if (strcmp(cs, "UTF-8") == 0 ||
- strcmp(cs, "UTF8") == 0)
- return ("UTF-8");
- if (strcmp(cs, "UTF-16BE") == 0 ||
- strcmp(cs, "UTF16BE") == 0)
- return ("UTF-16BE");
- if (strcmp(cs, "UTF-16LE") == 0 ||
- strcmp(cs, "UTF16LE") == 0)
- return ("UTF-16LE");
- if (strcmp(cs, "CP932") == 0)
- return ("CP932");
- return (charset);
-}
-
-/*
- * Create a string conversion object.
- */
-static struct archive_string_conv *
-create_sconv_object(const char *fc, const char *tc,
- unsigned current_codepage, int flag)
-{
- struct archive_string_conv *sc;
-
- sc = calloc(1, sizeof(*sc));
- if (sc == NULL)
- return (NULL);
- sc->next = NULL;
- sc->from_charset = strdup(fc);
- if (sc->from_charset == NULL) {
- free(sc);
- return (NULL);
- }
- sc->to_charset = strdup(tc);
- if (sc->to_charset == NULL) {
- free(sc->from_charset);
- free(sc);
- return (NULL);
- }
- archive_string_init(&sc->utftmp);
-
- if (flag & SCONV_TO_CHARSET) {
- /*
- * Convert characters from the current locale charset to
- * a specified charset.
- */
- sc->from_cp = current_codepage;
- sc->to_cp = make_codepage_from_charset(tc);
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if (IsValidCodePage(sc->to_cp))
- flag |= SCONV_WIN_CP;
-#endif
- } else if (flag & SCONV_FROM_CHARSET) {
- /*
- * Convert characters from a specified charset to
- * the current locale charset.
- */
- sc->to_cp = current_codepage;
- sc->from_cp = make_codepage_from_charset(fc);
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if (IsValidCodePage(sc->from_cp))
- flag |= SCONV_WIN_CP;
-#endif
- }
-
- /*
- * Check if "from charset" and "to charset" are the same.
- */
- if (strcmp(fc, tc) == 0 ||
- (sc->from_cp != (unsigned)-1 && sc->from_cp == sc->to_cp))
- sc->same = 1;
- else
- sc->same = 0;
-
- /*
- * Mark if "from charset" or "to charset" are UTF-8 or UTF-16BE/LE.
- */
- if (strcmp(tc, "UTF-8") == 0)
- flag |= SCONV_TO_UTF8;
- else if (strcmp(tc, "UTF-16BE") == 0)
- flag |= SCONV_TO_UTF16BE;
- else if (strcmp(tc, "UTF-16LE") == 0)
- flag |= SCONV_TO_UTF16LE;
- if (strcmp(fc, "UTF-8") == 0)
- flag |= SCONV_FROM_UTF8;
- else if (strcmp(fc, "UTF-16BE") == 0)
- flag |= SCONV_FROM_UTF16BE;
- else if (strcmp(fc, "UTF-16LE") == 0)
- flag |= SCONV_FROM_UTF16LE;
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if (sc->to_cp == CP_UTF8)
- flag |= SCONV_TO_UTF8;
- else if (sc->to_cp == CP_UTF16BE)
- flag |= SCONV_TO_UTF16BE | SCONV_WIN_CP;
- else if (sc->to_cp == CP_UTF16LE)
- flag |= SCONV_TO_UTF16LE | SCONV_WIN_CP;
- if (sc->from_cp == CP_UTF8)
- flag |= SCONV_FROM_UTF8;
- else if (sc->from_cp == CP_UTF16BE)
- flag |= SCONV_FROM_UTF16BE | SCONV_WIN_CP;
- else if (sc->from_cp == CP_UTF16LE)
- flag |= SCONV_FROM_UTF16LE | SCONV_WIN_CP;
-#endif
-
- /*
- * Set a flag for Unicode NFD. Usually iconv cannot correctly
- * handle it. So we have to translate NFD characters to NFC ones
- * ourselves before iconv handles. Another reason is to prevent
- * that the same sight of two filenames, one is NFC and other
- * is NFD, would be in its directory.
- * On Mac OS X, although its filesystem layer automatically
- * convert filenames to NFD, it would be useful for filename
- * comparing to find out the same filenames that we normalize
- * that to be NFD ourselves.
- */
- if ((flag & SCONV_FROM_CHARSET) &&
- (flag & (SCONV_FROM_UTF16 | SCONV_FROM_UTF8))) {
-#if defined(__APPLE__)
- if (flag & SCONV_TO_UTF8)
- flag |= SCONV_NORMALIZATION_D;
- else
-#endif
- flag |= SCONV_NORMALIZATION_C;
- }
-#if defined(__APPLE__)
- /*
- * In case writing an archive file, make sure that a filename
- * going to be passed to iconv is a Unicode NFC string since
- * a filename in HFS Plus filesystem is a Unicode NFD one and
- * iconv cannot handle it with "UTF-8" charset. It is simpler
- * than a use of "UTF-8-MAC" charset.
- */
- if ((flag & SCONV_TO_CHARSET) &&
- (flag & (SCONV_FROM_UTF16 | SCONV_FROM_UTF8)) &&
- !(flag & (SCONV_TO_UTF16 | SCONV_TO_UTF8)))
- flag |= SCONV_NORMALIZATION_C;
- /*
- * In case reading an archive file. make sure that a filename
- * will be passed to users is a Unicode NFD string in order to
- * correctly compare the filename with other one which comes
- * from HFS Plus filesystem.
- */
- if ((flag & SCONV_FROM_CHARSET) &&
- !(flag & (SCONV_FROM_UTF16 | SCONV_FROM_UTF8)) &&
- (flag & SCONV_TO_UTF8))
- flag |= SCONV_NORMALIZATION_D;
-#endif
-
-#if defined(HAVE_ICONV)
- sc->cd_w = (iconv_t)-1;
- /*
- * Create an iconv object.
- */
- if (((flag & (SCONV_TO_UTF8 | SCONV_TO_UTF16)) &&
- (flag & (SCONV_FROM_UTF8 | SCONV_FROM_UTF16))) ||
- (flag & SCONV_WIN_CP)) {
- /* This case we won't use iconv. */
- sc->cd = (iconv_t)-1;
- } else {
- sc->cd = iconv_open(tc, fc);
- if (sc->cd == (iconv_t)-1 && (sc->flag & SCONV_BEST_EFFORT)) {
- /*
- * Unfortunately, all of iconv implements do support
- * "CP932" character-set, so we should use "SJIS"
- * instead if iconv_open failed.
- */
- if (strcmp(tc, "CP932") == 0)
- sc->cd = iconv_open("SJIS", fc);
- else if (strcmp(fc, "CP932") == 0)
- sc->cd = iconv_open(tc, "SJIS");
- }
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /*
- * archive_mstring on Windows directly convert multi-bytes
- * into archive_wstring in order not to depend on locale
- * so that you can do a I18N programming. This will be
- * used only in archive_mstring_copy_mbs_len_l so far.
- */
- if (flag & SCONV_FROM_CHARSET) {
- sc->cd_w = iconv_open("UTF-8", fc);
- if (sc->cd_w == (iconv_t)-1 &&
- (sc->flag & SCONV_BEST_EFFORT)) {
- if (strcmp(fc, "CP932") == 0)
- sc->cd_w = iconv_open("UTF-8", "SJIS");
- }
- }
-#endif /* _WIN32 && !__CYGWIN__ */
- }
-#endif /* HAVE_ICONV */
-
- sc->flag = flag;
-
- /*
- * Set up converters.
- */
- setup_converter(sc);
-
- return (sc);
-}
-
-/*
- * Free a string conversion object.
- */
-static void
-free_sconv_object(struct archive_string_conv *sc)
-{
- free(sc->from_charset);
- free(sc->to_charset);
- archive_string_free(&sc->utftmp);
-#if HAVE_ICONV
- if (sc->cd != (iconv_t)-1)
- iconv_close(sc->cd);
- if (sc->cd_w != (iconv_t)-1)
- iconv_close(sc->cd_w);
-#endif
- free(sc);
-}
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-# if defined(WINAPI_FAMILY_PARTITION) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
-# define GetOEMCP() CP_OEMCP
-# endif
-
-static unsigned
-my_atoi(const char *p)
-{
- unsigned cp;
-
- cp = 0;
- while (*p) {
- if (*p >= '0' && *p <= '9')
- cp = cp * 10 + (*p - '0');
- else
- return (-1);
- p++;
- }
- return (cp);
-}
-
-/*
- * Translate Charset name (as used by iconv) into CodePage (as used by Windows)
- * Return -1 if failed.
- *
- * Note: This translation code may be insufficient.
- */
-static struct charset {
- const char *name;
- unsigned cp;
-} charsets[] = {
- /* MUST BE SORTED! */
- {"ASCII", 1252},
- {"ASMO-708", 708},
- {"BIG5", 950},
- {"CHINESE", 936},
- {"CP367", 1252},
- {"CP819", 1252},
- {"CP1025", 21025},
- {"DOS-720", 720},
- {"DOS-862", 862},
- {"EUC-CN", 51936},
- {"EUC-JP", 51932},
- {"EUC-KR", 949},
- {"EUCCN", 51936},
- {"EUCJP", 51932},
- {"EUCKR", 949},
- {"GB18030", 54936},
- {"GB2312", 936},
- {"HEBREW", 1255},
- {"HZ-GB-2312", 52936},
- {"IBM273", 20273},
- {"IBM277", 20277},
- {"IBM278", 20278},
- {"IBM280", 20280},
- {"IBM284", 20284},
- {"IBM285", 20285},
- {"IBM290", 20290},
- {"IBM297", 20297},
- {"IBM367", 1252},
- {"IBM420", 20420},
- {"IBM423", 20423},
- {"IBM424", 20424},
- {"IBM819", 1252},
- {"IBM871", 20871},
- {"IBM880", 20880},
- {"IBM905", 20905},
- {"IBM924", 20924},
- {"ISO-8859-1", 28591},
- {"ISO-8859-13", 28603},
- {"ISO-8859-15", 28605},
- {"ISO-8859-2", 28592},
- {"ISO-8859-3", 28593},
- {"ISO-8859-4", 28594},
- {"ISO-8859-5", 28595},
- {"ISO-8859-6", 28596},
- {"ISO-8859-7", 28597},
- {"ISO-8859-8", 28598},
- {"ISO-8859-9", 28599},
- {"ISO8859-1", 28591},
- {"ISO8859-13", 28603},
- {"ISO8859-15", 28605},
- {"ISO8859-2", 28592},
- {"ISO8859-3", 28593},
- {"ISO8859-4", 28594},
- {"ISO8859-5", 28595},
- {"ISO8859-6", 28596},
- {"ISO8859-7", 28597},
- {"ISO8859-8", 28598},
- {"ISO8859-9", 28599},
- {"JOHAB", 1361},
- {"KOI8-R", 20866},
- {"KOI8-U", 21866},
- {"KS_C_5601-1987", 949},
- {"LATIN1", 1252},
- {"LATIN2", 28592},
- {"MACINTOSH", 10000},
- {"SHIFT-JIS", 932},
- {"SHIFT_JIS", 932},
- {"SJIS", 932},
- {"US", 1252},
- {"US-ASCII", 1252},
- {"UTF-16", 1200},
- {"UTF-16BE", 1201},
- {"UTF-16LE", 1200},
- {"UTF-8", CP_UTF8},
- {"X-EUROPA", 29001},
- {"X-MAC-ARABIC", 10004},
- {"X-MAC-CE", 10029},
- {"X-MAC-CHINESEIMP", 10008},
- {"X-MAC-CHINESETRAD", 10002},
- {"X-MAC-CROATIAN", 10082},
- {"X-MAC-CYRILLIC", 10007},
- {"X-MAC-GREEK", 10006},
- {"X-MAC-HEBREW", 10005},
- {"X-MAC-ICELANDIC", 10079},
- {"X-MAC-JAPANESE", 10001},
- {"X-MAC-KOREAN", 10003},
- {"X-MAC-ROMANIAN", 10010},
- {"X-MAC-THAI", 10021},
- {"X-MAC-TURKISH", 10081},
- {"X-MAC-UKRAINIAN", 10017},
-};
-static unsigned
-make_codepage_from_charset(const char *charset)
-{
- char cs[16];
- char *p;
- unsigned cp;
- int a, b;
-
- if (charset == NULL || strlen(charset) > 15)
- return -1;
-
- /* Copy name to uppercase. */
- p = cs;
- while (*charset) {
- char c = *charset++;
- if (c >= 'a' && c <= 'z')
- c -= 'a' - 'A';
- *p++ = c;
- }
- *p++ = '\0';
- cp = -1;
-
- /* Look it up in the table first, so that we can easily
- * override CP367, which we map to 1252 instead of 367. */
- a = 0;
- b = sizeof(charsets)/sizeof(charsets[0]);
- while (b > a) {
- int c = (b + a) / 2;
- int r = strcmp(charsets[c].name, cs);
- if (r < 0)
- a = c + 1;
- else if (r > 0)
- b = c;
- else
- return charsets[c].cp;
- }
-
- /* If it's not in the table, try to parse it. */
- switch (*cs) {
- case 'C':
- if (cs[1] == 'P' && cs[2] >= '0' && cs[2] <= '9') {
- cp = my_atoi(cs + 2);
- } else if (strcmp(cs, "CP_ACP") == 0)
- cp = get_current_codepage();
- else if (strcmp(cs, "CP_OEMCP") == 0)
- cp = get_current_oemcp();
- break;
- case 'I':
- if (cs[1] == 'B' && cs[2] == 'M' &&
- cs[3] >= '0' && cs[3] <= '9') {
- cp = my_atoi(cs + 3);
- }
- break;
- case 'W':
- if (strncmp(cs, "WINDOWS-", 8) == 0) {
- cp = my_atoi(cs + 8);
- if (cp != 874 && (cp < 1250 || cp > 1258))
- cp = -1;/* This may invalid code. */
- }
- break;
- }
- return (cp);
-}
-
-/*
- * Return ANSI Code Page of current locale set by setlocale().
- */
-static unsigned
-get_current_codepage(void)
-{
- char *locale, *p;
- unsigned cp;
-
- locale = setlocale(LC_CTYPE, NULL);
- if (locale == NULL)
- return (GetACP());
- if (locale[0] == 'C' && locale[1] == '\0')
- return (CP_C_LOCALE);
- p = strrchr(locale, '.');
- if (p == NULL)
- return (GetACP());
- if (strcmp(p+1, "utf8") == 0)
- return CP_UTF8;
- cp = my_atoi(p+1);
- if ((int)cp <= 0)
- return (GetACP());
- return (cp);
-}
-
-/*
- * Translation table between Locale Name and ACP/OEMCP.
- */
-static struct {
- unsigned acp;
- unsigned ocp;
- const char *locale;
-} acp_ocp_map[] = {
- { 950, 950, "Chinese_Taiwan" },
- { 936, 936, "Chinese_People's Republic of China" },
- { 950, 950, "Chinese_Taiwan" },
- { 1250, 852, "Czech_Czech Republic" },
- { 1252, 850, "Danish_Denmark" },
- { 1252, 850, "Dutch_Netherlands" },
- { 1252, 850, "Dutch_Belgium" },
- { 1252, 437, "English_United States" },
- { 1252, 850, "English_Australia" },
- { 1252, 850, "English_Canada" },
- { 1252, 850, "English_New Zealand" },
- { 1252, 850, "English_United Kingdom" },
- { 1252, 437, "English_United States" },
- { 1252, 850, "Finnish_Finland" },
- { 1252, 850, "French_France" },
- { 1252, 850, "French_Belgium" },
- { 1252, 850, "French_Canada" },
- { 1252, 850, "French_Switzerland" },
- { 1252, 850, "German_Germany" },
- { 1252, 850, "German_Austria" },
- { 1252, 850, "German_Switzerland" },
- { 1253, 737, "Greek_Greece" },
- { 1250, 852, "Hungarian_Hungary" },
- { 1252, 850, "Icelandic_Iceland" },
- { 1252, 850, "Italian_Italy" },
- { 1252, 850, "Italian_Switzerland" },
- { 932, 932, "Japanese_Japan" },
- { 949, 949, "Korean_Korea" },
- { 1252, 850, "Norwegian (BokmOl)_Norway" },
- { 1252, 850, "Norwegian (BokmOl)_Norway" },
- { 1252, 850, "Norwegian-Nynorsk_Norway" },
- { 1250, 852, "Polish_Poland" },
- { 1252, 850, "Portuguese_Portugal" },
- { 1252, 850, "Portuguese_Brazil" },
- { 1251, 866, "Russian_Russia" },
- { 1250, 852, "Slovak_Slovakia" },
- { 1252, 850, "Spanish_Spain" },
- { 1252, 850, "Spanish_Mexico" },
- { 1252, 850, "Spanish_Spain" },
- { 1252, 850, "Swedish_Sweden" },
- { 1254, 857, "Turkish_Turkey" },
- { 0, 0, NULL}
-};
-
-/*
- * Return OEM Code Page of current locale set by setlocale().
- */
-static unsigned
-get_current_oemcp(void)
-{
- int i;
- char *locale, *p;
- size_t len;
-
- locale = setlocale(LC_CTYPE, NULL);
- if (locale == NULL)
- return (GetOEMCP());
- if (locale[0] == 'C' && locale[1] == '\0')
- return (CP_C_LOCALE);
-
- p = strrchr(locale, '.');
- if (p == NULL)
- return (GetOEMCP());
- len = p - locale;
- for (i = 0; acp_ocp_map[i].acp; i++) {
- if (strncmp(acp_ocp_map[i].locale, locale, len) == 0)
- return (acp_ocp_map[i].ocp);
- }
- return (GetOEMCP());
-}
-#else
-
-/*
- * POSIX platform does not use CodePage.
- */
-
-static unsigned
-get_current_codepage(void)
-{
- return (-1);/* Unknown */
-}
-static unsigned
-make_codepage_from_charset(const char *charset)
-{
- (void)charset; /* UNUSED */
- return (-1);/* Unknown */
-}
-static unsigned
-get_current_oemcp(void)
-{
- return (-1);/* Unknown */
-}
-
-#endif /* defined(_WIN32) && !defined(__CYGWIN__) */
-
-/*
- * Return a string conversion object.
- */
-static struct archive_string_conv *
-get_sconv_object(struct archive *a, const char *fc, const char *tc, int flag)
-{
- struct archive_string_conv *sc;
- unsigned current_codepage;
-
- /* Check if we have made the sconv object. */
- sc = find_sconv_object(a, fc, tc);
- if (sc != NULL)
- return (sc);
-
- if (a == NULL)
- current_codepage = get_current_codepage();
- else
- current_codepage = a->current_codepage;
-
- sc = create_sconv_object(canonical_charset_name(fc),
- canonical_charset_name(tc), current_codepage, flag);
- if (sc == NULL) {
- if (a != NULL)
- archive_set_error(a, ENOMEM,
- "Could not allocate memory for "
- "a string conversion object");
- return (NULL);
- }
-
- /*
- * If there is no converter for current string conversion object,
- * we cannot handle this conversion.
- */
- if (sc->nconverter == 0) {
- if (a != NULL) {
-#if HAVE_ICONV
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "iconv_open failed : Cannot handle ``%s''",
- (flag & SCONV_TO_CHARSET)?tc:fc);
-#else
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "A character-set conversion not fully supported "
- "on this platform");
-#endif
- }
- /* Failed; free a sconv object. */
- free_sconv_object(sc);
- return (NULL);
- }
-
- /*
- * Success!
- */
- if (a != NULL)
- add_sconv_object(a, sc);
- return (sc);
-}
-
-static const char *
-get_current_charset(struct archive *a)
-{
- const char *cur_charset;
-
- if (a == NULL)
- cur_charset = default_iconv_charset("");
- else {
- cur_charset = default_iconv_charset(a->current_code);
- if (a->current_code == NULL) {
- a->current_code = strdup(cur_charset);
- a->current_codepage = get_current_codepage();
- a->current_oemcp = get_current_oemcp();
- }
- }
- return (cur_charset);
-}
-
-/*
- * Make and Return a string conversion object.
- * Return NULL if the platform does not support the specified conversion
- * and best_effort is 0.
- * If best_effort is set, A string conversion object must be returned
- * unless memory allocation for the object fails, but the conversion
- * might fail when non-ASCII code is found.
- */
-struct archive_string_conv *
-archive_string_conversion_to_charset(struct archive *a, const char *charset,
- int best_effort)
-{
- int flag = SCONV_TO_CHARSET;
-
- if (best_effort)
- flag |= SCONV_BEST_EFFORT;
- return (get_sconv_object(a, get_current_charset(a), charset, flag));
-}
-
-struct archive_string_conv *
-archive_string_conversion_from_charset(struct archive *a, const char *charset,
- int best_effort)
-{
- int flag = SCONV_FROM_CHARSET;
-
- if (best_effort)
- flag |= SCONV_BEST_EFFORT;
- return (get_sconv_object(a, charset, get_current_charset(a), flag));
-}
-
-/*
- * archive_string_default_conversion_*_archive() are provided for Windows
- * platform because other archiver application use CP_OEMCP for
- * MultiByteToWideChar() and WideCharToMultiByte() for the filenames
- * in tar or zip files. But mbstowcs/wcstombs(CRT) usually use CP_ACP
- * unless you use setlocale(LC_ALL, ".OCP")(specify CP_OEMCP).
- * So we should make a string conversion between CP_ACP and CP_OEMCP
- * for compatibility.
- */
-#if defined(_WIN32) && !defined(__CYGWIN__)
-struct archive_string_conv *
-archive_string_default_conversion_for_read(struct archive *a)
-{
- const char *cur_charset = get_current_charset(a);
- char oemcp[16];
-
- /* NOTE: a check of cur_charset is unneeded but we need
- * that get_current_charset() has been surely called at
- * this time whatever C compiler optimized. */
- if (cur_charset != NULL &&
- (a->current_codepage == CP_C_LOCALE ||
- a->current_codepage == a->current_oemcp))
- return (NULL);/* no conversion. */
-
- _snprintf(oemcp, sizeof(oemcp)-1, "CP%d", a->current_oemcp);
- /* Make sure a null termination must be set. */
- oemcp[sizeof(oemcp)-1] = '\0';
- return (get_sconv_object(a, oemcp, cur_charset,
- SCONV_FROM_CHARSET));
-}
-
-struct archive_string_conv *
-archive_string_default_conversion_for_write(struct archive *a)
-{
- const char *cur_charset = get_current_charset(a);
- char oemcp[16];
-
- /* NOTE: a check of cur_charset is unneeded but we need
- * that get_current_charset() has been surely called at
- * this time whatever C compiler optimized. */
- if (cur_charset != NULL &&
- (a->current_codepage == CP_C_LOCALE ||
- a->current_codepage == a->current_oemcp))
- return (NULL);/* no conversion. */
-
- _snprintf(oemcp, sizeof(oemcp)-1, "CP%d", a->current_oemcp);
- /* Make sure a null termination must be set. */
- oemcp[sizeof(oemcp)-1] = '\0';
- return (get_sconv_object(a, cur_charset, oemcp,
- SCONV_TO_CHARSET));
-}
-#else
-struct archive_string_conv *
-archive_string_default_conversion_for_read(struct archive *a)
-{
- (void)a; /* UNUSED */
- return (NULL);
-}
-
-struct archive_string_conv *
-archive_string_default_conversion_for_write(struct archive *a)
-{
- (void)a; /* UNUSED */
- return (NULL);
-}
-#endif
-
-/*
- * Dispose of all character conversion objects in the archive object.
- */
-void
-archive_string_conversion_free(struct archive *a)
-{
- struct archive_string_conv *sc;
- struct archive_string_conv *sc_next;
-
- for (sc = a->sconv; sc != NULL; sc = sc_next) {
- sc_next = sc->next;
- free_sconv_object(sc);
- }
- a->sconv = NULL;
- free(a->current_code);
- a->current_code = NULL;
-}
-
-/*
- * Return a conversion charset name.
- */
-const char *
-archive_string_conversion_charset_name(struct archive_string_conv *sc)
-{
- if (sc->flag & SCONV_TO_CHARSET)
- return (sc->to_charset);
- else
- return (sc->from_charset);
-}
-
-/*
- * Change the behavior of a string conversion.
- */
-void
-archive_string_conversion_set_opt(struct archive_string_conv *sc, int opt)
-{
- switch (opt) {
- /*
- * A filename in UTF-8 was made with libarchive 2.x in a wrong
- * assumption that wchar_t was Unicode.
- * This option enables simulating the assumption in order to read
- * that filename correctly.
- */
- case SCONV_SET_OPT_UTF8_LIBARCHIVE2X:
-#if (defined(_WIN32) && !defined(__CYGWIN__)) \
- || defined(__STDC_ISO_10646__) || defined(__APPLE__)
- /*
- * Nothing to do for it since wchar_t on these platforms
- * is really Unicode.
- */
- (void)sc; /* UNUSED */
-#else
- if ((sc->flag & SCONV_UTF8_LIBARCHIVE_2) == 0) {
- sc->flag |= SCONV_UTF8_LIBARCHIVE_2;
- /* Set up string converters. */
- setup_converter(sc);
- }
-#endif
- break;
- case SCONV_SET_OPT_NORMALIZATION_C:
- if ((sc->flag & SCONV_NORMALIZATION_C) == 0) {
- sc->flag |= SCONV_NORMALIZATION_C;
- sc->flag &= ~SCONV_NORMALIZATION_D;
- /* Set up string converters. */
- setup_converter(sc);
- }
- break;
- case SCONV_SET_OPT_NORMALIZATION_D:
-#if defined(HAVE_ICONV)
- /*
- * If iconv will take the string, do not change the
- * setting of the normalization.
- */
- if (!(sc->flag & SCONV_WIN_CP) &&
- (sc->flag & (SCONV_FROM_UTF16 | SCONV_FROM_UTF8)) &&
- !(sc->flag & (SCONV_TO_UTF16 | SCONV_TO_UTF8)))
- break;
-#endif
- if ((sc->flag & SCONV_NORMALIZATION_D) == 0) {
- sc->flag |= SCONV_NORMALIZATION_D;
- sc->flag &= ~SCONV_NORMALIZATION_C;
- /* Set up string converters. */
- setup_converter(sc);
- }
- break;
- default:
- break;
- }
-}
-
-/*
- *
- * Copy one archive_string to another in locale conversion.
- *
- * archive_strncat_l();
- * archive_strncpy_l();
- *
- */
-
-static size_t
-mbsnbytes(const void *_p, size_t n)
-{
- size_t s;
- const char *p, *pp;
-
- if (_p == NULL)
- return (0);
- p = (const char *)_p;
-
- /* Like strlen(p), except won't examine positions beyond p[n]. */
- s = 0;
- pp = p;
- while (s < n && *pp) {
- pp++;
- s++;
- }
- return (s);
-}
-
-static size_t
-utf16nbytes(const void *_p, size_t n)
-{
- size_t s;
- const char *p, *pp;
-
- if (_p == NULL)
- return (0);
- p = (const char *)_p;
-
- /* Like strlen(p), except won't examine positions beyond p[n]. */
- s = 0;
- pp = p;
- n >>= 1;
- while (s < n && (pp[0] || pp[1])) {
- pp += 2;
- s++;
- }
- return (s<<1);
-}
-
-int
-archive_strncpy_l(struct archive_string *as, const void *_p, size_t n,
- struct archive_string_conv *sc)
-{
- as->length = 0;
- return (archive_strncat_l(as, _p, n, sc));
-}
-
-int
-archive_strncat_l(struct archive_string *as, const void *_p, size_t n,
- struct archive_string_conv *sc)
-{
- const void *s;
- size_t length = 0;
- int i, r = 0, r2;
-
- if (_p != NULL && n > 0) {
- if (sc != NULL && (sc->flag & SCONV_FROM_UTF16))
- length = utf16nbytes(_p, n);
- else
- length = mbsnbytes(_p, n);
- }
-
- /* We must allocate memory even if there is no data for conversion
- * or copy. This simulates archive_string_append behavior. */
- if (length == 0) {
- int tn = 1;
- if (sc != NULL && (sc->flag & SCONV_TO_UTF16))
- tn = 2;
- if (archive_string_ensure(as, as->length + tn) == NULL)
- return (-1);
- as->s[as->length] = 0;
- if (tn == 2)
- as->s[as->length+1] = 0;
- return (0);
- }
-
- /*
- * If sc is NULL, we just make a copy.
- */
- if (sc == NULL) {
- if (archive_string_append(as, _p, length) == NULL)
- return (-1);/* No memory */
- return (0);
- }
-
- s = _p;
- i = 0;
- if (sc->nconverter > 1) {
- sc->utftmp.length = 0;
- r2 = sc->converter[0](&(sc->utftmp), s, length, sc);
- if (r2 != 0 && errno == ENOMEM)
- return (r2);
- if (r > r2)
- r = r2;
- s = sc->utftmp.s;
- length = sc->utftmp.length;
- ++i;
- }
- r2 = sc->converter[i](as, s, length, sc);
- if (r > r2)
- r = r2;
- return (r);
-}
-
-#if HAVE_ICONV
-
-/*
- * Return -1 if conversion fails.
- */
-static int
-iconv_strncat_in_locale(struct archive_string *as, const void *_p,
- size_t length, struct archive_string_conv *sc)
-{
- ICONV_CONST char *itp;
- size_t remaining;
- iconv_t cd;
- char *outp;
- size_t avail, bs;
- int return_value = 0; /* success */
- int to_size, from_size;
-
- if (sc->flag & SCONV_TO_UTF16)
- to_size = 2;
- else
- to_size = 1;
- if (sc->flag & SCONV_FROM_UTF16)
- from_size = 2;
- else
- from_size = 1;
-
- if (archive_string_ensure(as, as->length + length*2+to_size) == NULL)
- return (-1);
-
- cd = sc->cd;
- itp = (char *)(uintptr_t)_p;
- remaining = length;
- outp = as->s + as->length;
- avail = as->buffer_length - as->length - to_size;
- while (remaining >= (size_t)from_size) {
- size_t result = iconv(cd, &itp, &remaining, &outp, &avail);
-
- if (result != (size_t)-1)
- break; /* Conversion completed. */
-
- if (errno == EILSEQ || errno == EINVAL) {
- /*
- * If an output charset is UTF-8 or UTF-16BE/LE,
- * unknown character should be U+FFFD
- * (replacement character).
- */
- if (sc->flag & (SCONV_TO_UTF8 | SCONV_TO_UTF16)) {
- size_t rbytes;
- if (sc->flag & SCONV_TO_UTF8)
- rbytes = sizeof(utf8_replacement_char);
- else
- rbytes = 2;
-
- if (avail < rbytes) {
- as->length = outp - as->s;
- bs = as->buffer_length +
- (remaining * to_size) + rbytes;
- if (NULL ==
- archive_string_ensure(as, bs))
- return (-1);
- outp = as->s + as->length;
- avail = as->buffer_length
- - as->length - to_size;
- }
- if (sc->flag & SCONV_TO_UTF8)
- memcpy(outp, utf8_replacement_char, sizeof(utf8_replacement_char));
- else if (sc->flag & SCONV_TO_UTF16BE)
- archive_be16enc(outp, UNICODE_R_CHAR);
- else
- archive_le16enc(outp, UNICODE_R_CHAR);
- outp += rbytes;
- avail -= rbytes;
- } else {
- /* Skip the illegal input bytes. */
- *outp++ = '?';
- avail--;
- }
- itp += from_size;
- remaining -= from_size;
- return_value = -1; /* failure */
- } else {
- /* E2BIG no output buffer,
- * Increase an output buffer. */
- as->length = outp - as->s;
- bs = as->buffer_length + remaining * 2;
- if (NULL == archive_string_ensure(as, bs))
- return (-1);
- outp = as->s + as->length;
- avail = as->buffer_length - as->length - to_size;
- }
- }
- as->length = outp - as->s;
- as->s[as->length] = 0;
- if (to_size == 2)
- as->s[as->length+1] = 0;
- return (return_value);
-}
-
-#endif /* HAVE_ICONV */
-
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-
-/*
- * Translate a string from a some CodePage to an another CodePage by
- * Windows APIs, and copy the result. Return -1 if conversion fails.
- */
-static int
-strncat_in_codepage(struct archive_string *as,
- const void *_p, size_t length, struct archive_string_conv *sc)
-{
- const char *s = (const char *)_p;
- struct archive_wstring aws;
- size_t l;
- int r, saved_flag;
-
- archive_string_init(&aws);
- saved_flag = sc->flag;
- sc->flag &= ~(SCONV_NORMALIZATION_D | SCONV_NORMALIZATION_C);
- r = archive_wstring_append_from_mbs_in_codepage(&aws, s, length, sc);
- sc->flag = saved_flag;
- if (r != 0) {
- archive_wstring_free(&aws);
- if (errno != ENOMEM)
- archive_string_append(as, s, length);
- return (-1);
- }
-
- l = as->length;
- r = archive_string_append_from_wcs_in_codepage(
- as, aws.s, aws.length, sc);
- if (r != 0 && errno != ENOMEM && l == as->length)
- archive_string_append(as, s, length);
- archive_wstring_free(&aws);
- return (r);
-}
-
-/*
- * Test whether MBS ==> WCS is okay.
- */
-static int
-invalid_mbs(const void *_p, size_t n, struct archive_string_conv *sc)
-{
- const char *p = (const char *)_p;
- unsigned codepage;
- DWORD mbflag = MB_ERR_INVALID_CHARS;
-
- if (sc->flag & SCONV_FROM_CHARSET)
- codepage = sc->to_cp;
- else
- codepage = sc->from_cp;
-
- if (codepage == CP_C_LOCALE)
- return (0);
- if (codepage != CP_UTF8)
- mbflag |= MB_PRECOMPOSED;
-
- if (MultiByteToWideChar(codepage, mbflag, p, (int)n, NULL, 0) == 0)
- return (-1); /* Invalid */
- return (0); /* Okay */
-}
-
-#else
-
-/*
- * Test whether MBS ==> WCS is okay.
- */
-static int
-invalid_mbs(const void *_p, size_t n, struct archive_string_conv *sc)
-{
- const char *p = (const char *)_p;
- size_t r;
-
-#if HAVE_MBRTOWC
- mbstate_t shift_state;
-
- memset(&shift_state, 0, sizeof(shift_state));
-#else
- /* Clear the shift state before starting. */
- mbtowc(NULL, NULL, 0);
-#endif
- while (n) {
- wchar_t wc;
-
-#if HAVE_MBRTOWC
- r = mbrtowc(&wc, p, n, &shift_state);
-#else
- r = mbtowc(&wc, p, n);
-#endif
- if (r == (size_t)-1 || r == (size_t)-2)
- return (-1);/* Invalid. */
- if (r == 0)
- break;
- p += r;
- n -= r;
- }
- (void)sc; /* UNUSED */
- return (0); /* All Okey. */
-}
-
-#endif /* defined(_WIN32) && !defined(__CYGWIN__) */
-
-/*
- * Basically returns -1 because we cannot make a conversion of charset
- * without iconv but in some cases this would return 0.
- * Returns 0 if all copied characters are ASCII.
- * Returns 0 if both from-locale and to-locale are the same and those
- * can be WCS with no error.
- */
-static int
-best_effort_strncat_in_locale(struct archive_string *as, const void *_p,
- size_t length, struct archive_string_conv *sc)
-{
- size_t remaining;
- const uint8_t *itp;
- int return_value = 0; /* success */
-
- /*
- * If both from-locale and to-locale is the same, this makes a copy.
- * And then this checks all copied MBS can be WCS if so returns 0.
- */
- if (sc->same) {
- if (archive_string_append(as, _p, length) == NULL)
- return (-1);/* No memory */
- return (invalid_mbs(_p, length, sc));
- }
-
- /*
- * If a character is ASCII, this just copies it. If not, this
- * assigns '?' character instead but in UTF-8 locale this assigns
- * byte sequence 0xEF 0xBD 0xBD, which are code point U+FFFD,
- * a Replacement Character in Unicode.
- */
-
- remaining = length;
- itp = (const uint8_t *)_p;
- while (*itp && remaining > 0) {
- if (*itp > 127) {
- // Non-ASCII: Substitute with suitable replacement
- if (sc->flag & SCONV_TO_UTF8) {
- if (archive_string_append(as, utf8_replacement_char, sizeof(utf8_replacement_char)) == NULL) {
- __archive_errx(1, "Out of memory");
- }
- } else {
- archive_strappend_char(as, '?');
- }
- return_value = -1;
- } else {
- archive_strappend_char(as, *itp);
- }
- ++itp;
- }
- return (return_value);
-}
-
-
-/*
- * Unicode conversion functions.
- * - UTF-8 <===> UTF-8 in removing surrogate pairs.
- * - UTF-8 NFD ===> UTF-8 NFC in removing surrogate pairs.
- * - UTF-8 made by libarchive 2.x ===> UTF-8.
- * - UTF-16BE <===> UTF-8.
- *
- */
-
-/*
- * Utility to convert a single UTF-8 sequence.
- *
- * Usually return used bytes, return used byte in negative value when
- * a unicode character is replaced with U+FFFD.
- * See also http://unicode.org/review/pr-121.html Public Review Issue #121
- * Recommended Practice for Replacement Characters.
- */
-static int
-_utf8_to_unicode(uint32_t *pwc, const char *s, size_t n)
-{
- static const char utf8_count[256] = {
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 00 - 0F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 10 - 1F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20 - 2F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30 - 3F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40 - 4F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 50 - 5F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60 - 6F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 70 - 7F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 80 - 8F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 90 - 9F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* A0 - AF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* B0 - BF */
- 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,/* C0 - CF */
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,/* D0 - DF */
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,/* E0 - EF */
- 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* F0 - FF */
- };
- int ch, i;
- int cnt;
- uint32_t wc;
-
- /* Sanity check. */
- if (n == 0)
- return (0);
- /*
- * Decode 1-4 bytes depending on the value of the first byte.
- */
- ch = (unsigned char)*s;
- if (ch == 0)
- return (0); /* Standard: return 0 for end-of-string. */
- cnt = utf8_count[ch];
-
- /* Invalid sequence or there are not plenty bytes. */
- if ((int)n < cnt) {
- cnt = (int)n;
- for (i = 1; i < cnt; i++) {
- if ((s[i] & 0xc0) != 0x80) {
- cnt = i;
- break;
- }
- }
- goto invalid_sequence;
- }
-
- /* Make a Unicode code point from a single UTF-8 sequence. */
- switch (cnt) {
- case 1: /* 1 byte sequence. */
- *pwc = ch & 0x7f;
- return (cnt);
- case 2: /* 2 bytes sequence. */
- if ((s[1] & 0xc0) != 0x80) {
- cnt = 1;
- goto invalid_sequence;
- }
- *pwc = ((ch & 0x1f) << 6) | (s[1] & 0x3f);
- return (cnt);
- case 3: /* 3 bytes sequence. */
- if ((s[1] & 0xc0) != 0x80) {
- cnt = 1;
- goto invalid_sequence;
- }
- if ((s[2] & 0xc0) != 0x80) {
- cnt = 2;
- goto invalid_sequence;
- }
- wc = ((ch & 0x0f) << 12)
- | ((s[1] & 0x3f) << 6)
- | (s[2] & 0x3f);
- if (wc < 0x800)
- goto invalid_sequence;/* Overlong sequence. */
- break;
- case 4: /* 4 bytes sequence. */
- if ((s[1] & 0xc0) != 0x80) {
- cnt = 1;
- goto invalid_sequence;
- }
- if ((s[2] & 0xc0) != 0x80) {
- cnt = 2;
- goto invalid_sequence;
- }
- if ((s[3] & 0xc0) != 0x80) {
- cnt = 3;
- goto invalid_sequence;
- }
- wc = ((ch & 0x07) << 18)
- | ((s[1] & 0x3f) << 12)
- | ((s[2] & 0x3f) << 6)
- | (s[3] & 0x3f);
- if (wc < 0x10000)
- goto invalid_sequence;/* Overlong sequence. */
- break;
- default: /* Others are all invalid sequence. */
- if (ch == 0xc0 || ch == 0xc1)
- cnt = 2;
- else if (ch >= 0xf5 && ch <= 0xf7)
- cnt = 4;
- else if (ch >= 0xf8 && ch <= 0xfb)
- cnt = 5;
- else if (ch == 0xfc || ch == 0xfd)
- cnt = 6;
- else
- cnt = 1;
- if ((int)n < cnt)
- cnt = (int)n;
- for (i = 1; i < cnt; i++) {
- if ((s[i] & 0xc0) != 0x80) {
- cnt = i;
- break;
- }
- }
- goto invalid_sequence;
- }
-
- /* The code point larger than 0x10FFFF is not legal
- * Unicode values. */
- if (wc > UNICODE_MAX)
- goto invalid_sequence;
- /* Correctly gets a Unicode, returns used bytes. */
- *pwc = wc;
- return (cnt);
-invalid_sequence:
- *pwc = UNICODE_R_CHAR;/* set the Replacement Character instead. */
- return (cnt * -1);
-}
-
-static int
-utf8_to_unicode(uint32_t *pwc, const char *s, size_t n)
-{
- int cnt;
-
- cnt = _utf8_to_unicode(pwc, s, n);
- /* Any of Surrogate pair is not legal Unicode values. */
- if (cnt == 3 && IS_SURROGATE_PAIR_LA(*pwc))
- return (-3);
- return (cnt);
-}
-
-static inline uint32_t
-combine_surrogate_pair(uint32_t uc, uint32_t uc2)
-{
- uc -= 0xD800;
- uc *= 0x400;
- uc += uc2 - 0xDC00;
- uc += 0x10000;
- return (uc);
-}
-
-/*
- * Convert a single UTF-8/CESU-8 sequence to a Unicode code point in
- * removing surrogate pairs.
- *
- * CESU-8: The Compatibility Encoding Scheme for UTF-16.
- *
- * Usually return used bytes, return used byte in negative value when
- * a unicode character is replaced with U+FFFD.
- */
-static int
-cesu8_to_unicode(uint32_t *pwc, const char *s, size_t n)
-{
- uint32_t wc = 0;
- int cnt;
-
- cnt = _utf8_to_unicode(&wc, s, n);
- if (cnt == 3 && IS_HIGH_SURROGATE_LA(wc)) {
- uint32_t wc2 = 0;
- if (n - 3 < 3) {
- /* Invalid byte sequence. */
- goto invalid_sequence;
- }
- cnt = _utf8_to_unicode(&wc2, s+3, n-3);
- if (cnt != 3 || !IS_LOW_SURROGATE_LA(wc2)) {
- /* Invalid byte sequence. */
- goto invalid_sequence;
- }
- wc = combine_surrogate_pair(wc, wc2);
- cnt = 6;
- } else if (cnt == 3 && IS_LOW_SURROGATE_LA(wc)) {
- /* Invalid byte sequence. */
- goto invalid_sequence;
- }
- *pwc = wc;
- return (cnt);
-invalid_sequence:
- *pwc = UNICODE_R_CHAR;/* set the Replacement Character instead. */
- if (cnt > 0)
- cnt *= -1;
- return (cnt);
-}
-
-/*
- * Convert a Unicode code point to a single UTF-8 sequence.
- *
- * NOTE:This function does not check if the Unicode is legal or not.
- * Please you definitely check it before calling this.
- */
-static size_t
-unicode_to_utf8(char *p, size_t remaining, uint32_t uc)
-{
- char *_p = p;
-
- /* Invalid Unicode char maps to Replacement character */
- if (uc > UNICODE_MAX)
- uc = UNICODE_R_CHAR;
- /* Translate code point to UTF8 */
- if (uc <= 0x7f) {
- if (remaining == 0)
- return (0);
- *p++ = (char)uc;
- } else if (uc <= 0x7ff) {
- if (remaining < 2)
- return (0);
- *p++ = 0xc0 | ((uc >> 6) & 0x1f);
- *p++ = 0x80 | (uc & 0x3f);
- } else if (uc <= 0xffff) {
- if (remaining < 3)
- return (0);
- *p++ = 0xe0 | ((uc >> 12) & 0x0f);
- *p++ = 0x80 | ((uc >> 6) & 0x3f);
- *p++ = 0x80 | (uc & 0x3f);
- } else {
- if (remaining < 4)
- return (0);
- *p++ = 0xf0 | ((uc >> 18) & 0x07);
- *p++ = 0x80 | ((uc >> 12) & 0x3f);
- *p++ = 0x80 | ((uc >> 6) & 0x3f);
- *p++ = 0x80 | (uc & 0x3f);
- }
- return (p - _p);
-}
-
-static int
-utf16be_to_unicode(uint32_t *pwc, const char *s, size_t n)
-{
- return (utf16_to_unicode(pwc, s, n, 1));
-}
-
-static int
-utf16le_to_unicode(uint32_t *pwc, const char *s, size_t n)
-{
- return (utf16_to_unicode(pwc, s, n, 0));
-}
-
-static int
-utf16_to_unicode(uint32_t *pwc, const char *s, size_t n, int be)
-{
- const char *utf16 = s;
- unsigned uc;
-
- if (n == 0)
- return (0);
- if (n == 1) {
- /* set the Replacement Character instead. */
- *pwc = UNICODE_R_CHAR;
- return (-1);
- }
-
- if (be)
- uc = archive_be16dec(utf16);
- else
- uc = archive_le16dec(utf16);
- utf16 += 2;
-
- /* If this is a surrogate pair, assemble the full code point.*/
- if (IS_HIGH_SURROGATE_LA(uc)) {
- unsigned uc2;
-
- if (n >= 4) {
- if (be)
- uc2 = archive_be16dec(utf16);
- else
- uc2 = archive_le16dec(utf16);
- } else
- uc2 = 0;
- if (IS_LOW_SURROGATE_LA(uc2)) {
- uc = combine_surrogate_pair(uc, uc2);
- utf16 += 2;
- } else {
- /* Undescribed code point should be U+FFFD
- * (replacement character). */
- *pwc = UNICODE_R_CHAR;
- return (-2);
- }
- }
-
- /*
- * Surrogate pair values(0xd800 through 0xdfff) are only
- * used by UTF-16, so, after above calculation, the code
- * must not be surrogate values, and Unicode has no codes
- * larger than 0x10ffff. Thus, those are not legal Unicode
- * values.
- */
- if (IS_SURROGATE_PAIR_LA(uc) || uc > UNICODE_MAX) {
- /* Undescribed code point should be U+FFFD
- * (replacement character). */
- *pwc = UNICODE_R_CHAR;
- return (((int)(utf16 - s)) * -1);
- }
- *pwc = uc;
- return ((int)(utf16 - s));
-}
-
-static size_t
-unicode_to_utf16be(char *p, size_t remaining, uint32_t uc)
-{
- char *utf16 = p;
-
- if (uc > 0xffff) {
- /* We have a code point that won't fit into a
- * wchar_t; convert it to a surrogate pair. */
- if (remaining < 4)
- return (0);
- uc -= 0x10000;
- archive_be16enc(utf16, ((uc >> 10) & 0x3ff) + 0xD800);
- archive_be16enc(utf16+2, (uc & 0x3ff) + 0xDC00);
- return (4);
- } else {
- if (remaining < 2)
- return (0);
- archive_be16enc(utf16, uc);
- return (2);
- }
-}
-
-static size_t
-unicode_to_utf16le(char *p, size_t remaining, uint32_t uc)
-{
- char *utf16 = p;
-
- if (uc > 0xffff) {
- /* We have a code point that won't fit into a
- * wchar_t; convert it to a surrogate pair. */
- if (remaining < 4)
- return (0);
- uc -= 0x10000;
- archive_le16enc(utf16, ((uc >> 10) & 0x3ff) + 0xD800);
- archive_le16enc(utf16+2, (uc & 0x3ff) + 0xDC00);
- return (4);
- } else {
- if (remaining < 2)
- return (0);
- archive_le16enc(utf16, uc);
- return (2);
- }
-}
-
-/*
- * Copy UTF-8 string in checking surrogate pair.
- * If any surrogate pair are found, it would be canonicalized.
- */
-static int
-strncat_from_utf8_to_utf8(struct archive_string *as, const void *_p,
- size_t len, struct archive_string_conv *sc)
-{
- const char *s;
- char *p, *endp;
- int n, ret = 0;
-
- (void)sc; /* UNUSED */
-
- if (archive_string_ensure(as, as->length + len + 1) == NULL)
- return (-1);
-
- s = (const char *)_p;
- p = as->s + as->length;
- endp = as->s + as->buffer_length -1;
- do {
- uint32_t uc;
- const char *ss = s;
- size_t w;
-
- /*
- * Forward byte sequence until a conversion of that is needed.
- */
- while ((n = utf8_to_unicode(&uc, s, len)) > 0) {
- s += n;
- len -= n;
- }
- if (ss < s) {
- if (p + (s - ss) > endp) {
- as->length = p - as->s;
- if (archive_string_ensure(as,
- as->buffer_length + len + 1) == NULL)
- return (-1);
- p = as->s + as->length;
- endp = as->s + as->buffer_length -1;
- }
-
- memcpy(p, ss, s - ss);
- p += s - ss;
- }
-
- /*
- * If n is negative, current byte sequence needs a replacement.
- */
- if (n < 0) {
- if (n == -3 && IS_SURROGATE_PAIR_LA(uc)) {
- /* Current byte sequence may be CESU-8. */
- n = cesu8_to_unicode(&uc, s, len);
- }
- if (n < 0) {
- ret = -1;
- n *= -1;/* Use a replaced unicode character. */
- }
-
- /* Rebuild UTF-8 byte sequence. */
- while ((w = unicode_to_utf8(p, endp - p, uc)) == 0) {
- as->length = p - as->s;
- if (archive_string_ensure(as,
- as->buffer_length + len + 1) == NULL)
- return (-1);
- p = as->s + as->length;
- endp = as->s + as->buffer_length -1;
- }
- p += w;
- s += n;
- len -= n;
- }
- } while (n > 0);
- as->length = p - as->s;
- as->s[as->length] = '\0';
- return (ret);
-}
-
-static int
-archive_string_append_unicode(struct archive_string *as, const void *_p,
- size_t len, struct archive_string_conv *sc)
-{
- const char *s;
- char *p, *endp;
- uint32_t uc;
- size_t w;
- int n, ret = 0, ts, tm;
- int (*parse)(uint32_t *, const char *, size_t);
- size_t (*unparse)(char *, size_t, uint32_t);
-
- if (sc->flag & SCONV_TO_UTF16BE) {
- unparse = unicode_to_utf16be;
- ts = 2;
- } else if (sc->flag & SCONV_TO_UTF16LE) {
- unparse = unicode_to_utf16le;
- ts = 2;
- } else if (sc->flag & SCONV_TO_UTF8) {
- unparse = unicode_to_utf8;
- ts = 1;
- } else {
- /*
- * This case is going to be converted to another
- * character-set through iconv.
- */
- if (sc->flag & SCONV_FROM_UTF16BE) {
- unparse = unicode_to_utf16be;
- ts = 2;
- } else if (sc->flag & SCONV_FROM_UTF16LE) {
- unparse = unicode_to_utf16le;
- ts = 2;
- } else {
- unparse = unicode_to_utf8;
- ts = 1;
- }
- }
-
- if (sc->flag & SCONV_FROM_UTF16BE) {
- parse = utf16be_to_unicode;
- tm = 1;
- } else if (sc->flag & SCONV_FROM_UTF16LE) {
- parse = utf16le_to_unicode;
- tm = 1;
- } else {
- parse = cesu8_to_unicode;
- tm = ts;
- }
-
- if (archive_string_ensure(as, as->length + len * tm + ts) == NULL)
- return (-1);
-
- s = (const char *)_p;
- p = as->s + as->length;
- endp = as->s + as->buffer_length - ts;
- while ((n = parse(&uc, s, len)) != 0) {
- if (n < 0) {
- /* Use a replaced unicode character. */
- n *= -1;
- ret = -1;
- }
- s += n;
- len -= n;
- while ((w = unparse(p, endp - p, uc)) == 0) {
- /* There is not enough output buffer so
- * we have to expand it. */
- as->length = p - as->s;
- if (archive_string_ensure(as,
- as->buffer_length + len * tm + ts) == NULL)
- return (-1);
- p = as->s + as->length;
- endp = as->s + as->buffer_length - ts;
- }
- p += w;
- }
- as->length = p - as->s;
- as->s[as->length] = '\0';
- if (ts == 2)
- as->s[as->length+1] = '\0';
- return (ret);
-}
-
-/*
- * Following Constants for Hangul compositions this information comes from
- * Unicode Standard Annex #15 http://unicode.org/reports/tr15/
- */
-#define HC_SBASE 0xAC00
-#define HC_LBASE 0x1100
-#define HC_VBASE 0x1161
-#define HC_TBASE 0x11A7
-#define HC_LCOUNT 19
-#define HC_VCOUNT 21
-#define HC_TCOUNT 28
-#define HC_NCOUNT (HC_VCOUNT * HC_TCOUNT)
-#define HC_SCOUNT (HC_LCOUNT * HC_NCOUNT)
-
-static uint32_t
-get_nfc(uint32_t uc, uint32_t uc2)
-{
- int t, b;
-
- t = 0;
- b = sizeof(u_composition_table)/sizeof(u_composition_table[0]) -1;
- while (b >= t) {
- int m = (t + b) / 2;
- if (u_composition_table[m].cp1 < uc)
- t = m + 1;
- else if (u_composition_table[m].cp1 > uc)
- b = m - 1;
- else if (u_composition_table[m].cp2 < uc2)
- t = m + 1;
- else if (u_composition_table[m].cp2 > uc2)
- b = m - 1;
- else
- return (u_composition_table[m].nfc);
- }
- return (0);
-}
-
-#define FDC_MAX 10 /* The maximum number of Following Decomposable
- * Characters. */
-
-/*
- * Update first code point.
- */
-#define UPDATE_UC(new_uc) do { \
- uc = new_uc; \
- ucptr = NULL; \
-} while (0)
-
-/*
- * Replace first code point with second code point.
- */
-#define REPLACE_UC_WITH_UC2() do { \
- uc = uc2; \
- ucptr = uc2ptr; \
- n = n2; \
-} while (0)
-
-#define EXPAND_BUFFER() do { \
- as->length = p - as->s; \
- if (archive_string_ensure(as, \
- as->buffer_length + len * tm + ts) == NULL)\
- return (-1); \
- p = as->s + as->length; \
- endp = as->s + as->buffer_length - ts; \
-} while (0)
-
-#define UNPARSE(p, endp, uc) do { \
- while ((w = unparse(p, (endp) - (p), uc)) == 0) {\
- EXPAND_BUFFER(); \
- } \
- p += w; \
-} while (0)
-
-/*
- * Write first code point.
- * If the code point has not be changed from its original code,
- * this just copies it from its original buffer pointer.
- * If not, this converts it to UTF-8 byte sequence and copies it.
- */
-#define WRITE_UC() do { \
- if (ucptr) { \
- if (p + n > endp) \
- EXPAND_BUFFER(); \
- switch (n) { \
- case 4: \
- *p++ = *ucptr++; \
- /* FALL THROUGH */ \
- case 3: \
- *p++ = *ucptr++; \
- /* FALL THROUGH */ \
- case 2: \
- *p++ = *ucptr++; \
- /* FALL THROUGH */ \
- case 1: \
- *p++ = *ucptr; \
- break; \
- } \
- ucptr = NULL; \
- } else { \
- UNPARSE(p, endp, uc); \
- } \
-} while (0)
-
-/*
- * Collect following decomposable code points.
- */
-#define COLLECT_CPS(start) do { \
- int _i; \
- for (_i = start; _i < FDC_MAX ; _i++) { \
- nx = parse(&ucx[_i], s, len); \
- if (nx <= 0) \
- break; \
- cx = CCC(ucx[_i]); \
- if (cl >= cx && cl != 228 && cx != 228)\
- break; \
- s += nx; \
- len -= nx; \
- cl = cx; \
- ccx[_i] = cx; \
- } \
- if (_i >= FDC_MAX) { \
- ret = -1; \
- ucx_size = FDC_MAX; \
- } else \
- ucx_size = _i; \
-} while (0)
-
-/*
- * Normalize UTF-8/UTF-16BE characters to Form C and copy the result.
- *
- * TODO: Convert composition exclusions, which are never converted
- * from NFC,NFD,NFKC and NFKD, to Form C.
- */
-static int
-archive_string_normalize_C(struct archive_string *as, const void *_p,
- size_t len, struct archive_string_conv *sc)
-{
- const char *s = (const char *)_p;
- char *p, *endp;
- uint32_t uc, uc2;
- size_t w;
- int always_replace, n, n2, ret = 0, spair, ts, tm;
- int (*parse)(uint32_t *, const char *, size_t);
- size_t (*unparse)(char *, size_t, uint32_t);
-
- always_replace = 1;
- ts = 1;/* text size. */
- if (sc->flag & SCONV_TO_UTF16BE) {
- unparse = unicode_to_utf16be;
- ts = 2;
- if (sc->flag & SCONV_FROM_UTF16BE)
- always_replace = 0;
- } else if (sc->flag & SCONV_TO_UTF16LE) {
- unparse = unicode_to_utf16le;
- ts = 2;
- if (sc->flag & SCONV_FROM_UTF16LE)
- always_replace = 0;
- } else if (sc->flag & SCONV_TO_UTF8) {
- unparse = unicode_to_utf8;
- if (sc->flag & SCONV_FROM_UTF8)
- always_replace = 0;
- } else {
- /*
- * This case is going to be converted to another
- * character-set through iconv.
- */
- always_replace = 0;
- if (sc->flag & SCONV_FROM_UTF16BE) {
- unparse = unicode_to_utf16be;
- ts = 2;
- } else if (sc->flag & SCONV_FROM_UTF16LE) {
- unparse = unicode_to_utf16le;
- ts = 2;
- } else {
- unparse = unicode_to_utf8;
- }
- }
-
- if (sc->flag & SCONV_FROM_UTF16BE) {
- parse = utf16be_to_unicode;
- tm = 1;
- spair = 4;/* surrogate pair size in UTF-16. */
- } else if (sc->flag & SCONV_FROM_UTF16LE) {
- parse = utf16le_to_unicode;
- tm = 1;
- spair = 4;/* surrogate pair size in UTF-16. */
- } else {
- parse = cesu8_to_unicode;
- tm = ts;
- spair = 6;/* surrogate pair size in UTF-8. */
- }
-
- if (archive_string_ensure(as, as->length + len * tm + ts) == NULL)
- return (-1);
-
- p = as->s + as->length;
- endp = as->s + as->buffer_length - ts;
- while ((n = parse(&uc, s, len)) != 0) {
- const char *ucptr, *uc2ptr;
-
- if (n < 0) {
- /* Use a replaced unicode character. */
- UNPARSE(p, endp, uc);
- s += n*-1;
- len -= n*-1;
- ret = -1;
- continue;
- } else if (n == spair || always_replace)
- /* uc is converted from a surrogate pair.
- * this should be treated as a changed code. */
- ucptr = NULL;
- else
- ucptr = s;
- s += n;
- len -= n;
-
- /* Read second code point. */
- while ((n2 = parse(&uc2, s, len)) > 0) {
- uint32_t ucx[FDC_MAX];
- int ccx[FDC_MAX];
- int cl, cx, i, nx, ucx_size;
- int LIndex,SIndex;
- uint32_t nfc;
-
- if (n2 == spair || always_replace)
- /* uc2 is converted from a surrogate pair.
- * this should be treated as a changed code. */
- uc2ptr = NULL;
- else
- uc2ptr = s;
- s += n2;
- len -= n2;
-
- /*
- * If current second code point is out of decomposable
- * code points, finding compositions is unneeded.
- */
- if (!IS_DECOMPOSABLE_BLOCK(uc2)) {
- WRITE_UC();
- REPLACE_UC_WITH_UC2();
- continue;
- }
-
- /*
- * Try to combine current code points.
- */
- /*
- * We have to combine Hangul characters according to
- * http://uniicode.org/reports/tr15/#Hangul
- */
- if (0 <= (LIndex = uc - HC_LBASE) &&
- LIndex < HC_LCOUNT) {
- /*
- * Hangul Composition.
- * 1. Two current code points are L and V.
- */
- int VIndex = uc2 - HC_VBASE;
- if (0 <= VIndex && VIndex < HC_VCOUNT) {
- /* Make syllable of form LV. */
- UPDATE_UC(HC_SBASE +
- (LIndex * HC_VCOUNT + VIndex) *
- HC_TCOUNT);
- } else {
- WRITE_UC();
- REPLACE_UC_WITH_UC2();
- }
- continue;
- } else if (0 <= (SIndex = uc - HC_SBASE) &&
- SIndex < HC_SCOUNT && (SIndex % HC_TCOUNT) == 0) {
- /*
- * Hangul Composition.
- * 2. Two current code points are LV and T.
- */
- int TIndex = uc2 - HC_TBASE;
- if (0 < TIndex && TIndex < HC_TCOUNT) {
- /* Make syllable of form LVT. */
- UPDATE_UC(uc + TIndex);
- } else {
- WRITE_UC();
- REPLACE_UC_WITH_UC2();
- }
- continue;
- } else if ((nfc = get_nfc(uc, uc2)) != 0) {
- /* A composition to current code points
- * is found. */
- UPDATE_UC(nfc);
- continue;
- } else if ((cl = CCC(uc2)) == 0) {
- /* Clearly 'uc2' the second code point is not
- * a decomposable code. */
- WRITE_UC();
- REPLACE_UC_WITH_UC2();
- continue;
- }
-
- /*
- * Collect following decomposable code points.
- */
- cx = 0;
- ucx[0] = uc2;
- ccx[0] = cl;
- COLLECT_CPS(1);
-
- /*
- * Find a composed code in the collected code points.
- */
- i = 1;
- while (i < ucx_size) {
- int j;
-
- if ((nfc = get_nfc(uc, ucx[i])) == 0) {
- i++;
- continue;
- }
-
- /*
- * nfc is composed of uc and ucx[i].
- */
- UPDATE_UC(nfc);
-
- /*
- * Remove ucx[i] by shifting
- * following code points.
- */
- for (j = i; j+1 < ucx_size; j++) {
- ucx[j] = ucx[j+1];
- ccx[j] = ccx[j+1];
- }
- ucx_size --;
-
- /*
- * Collect following code points blocked
- * by ucx[i] the removed code point.
- */
- if (ucx_size > 0 && i == ucx_size &&
- nx > 0 && cx == cl) {
- cl = ccx[ucx_size-1];
- COLLECT_CPS(ucx_size);
- }
- /*
- * Restart finding a composed code with
- * the updated uc from the top of the
- * collected code points.
- */
- i = 0;
- }
-
- /*
- * Apparently the current code points are not
- * decomposed characters or already composed.
- */
- WRITE_UC();
- for (i = 0; i < ucx_size; i++)
- UNPARSE(p, endp, ucx[i]);
-
- /*
- * Flush out remaining canonical combining characters.
- */
- if (nx > 0 && cx == cl && len > 0) {
- while ((nx = parse(&ucx[0], s, len))
- > 0) {
- cx = CCC(ucx[0]);
- if (cl > cx)
- break;
- s += nx;
- len -= nx;
- cl = cx;
- UNPARSE(p, endp, ucx[0]);
- }
- }
- break;
- }
- if (n2 < 0) {
- WRITE_UC();
- /* Use a replaced unicode character. */
- UNPARSE(p, endp, uc2);
- s += n2*-1;
- len -= n2*-1;
- ret = -1;
- continue;
- } else if (n2 == 0) {
- WRITE_UC();
- break;
- }
- }
- as->length = p - as->s;
- as->s[as->length] = '\0';
- if (ts == 2)
- as->s[as->length+1] = '\0';
- return (ret);
-}
-
-static int
-get_nfd(uint32_t *cp1, uint32_t *cp2, uint32_t uc)
-{
- int t, b;
-
- /*
- * These are not converted to NFD on Mac OS.
- */
- if ((uc >= 0x2000 && uc <= 0x2FFF) ||
- (uc >= 0xF900 && uc <= 0xFAFF) ||
- (uc >= 0x2F800 && uc <= 0x2FAFF))
- return (0);
- /*
- * Those code points are not converted to NFD on Mac OS.
- * I do not know the reason because it is undocumented.
- * NFC NFD
- * 1109A ==> 11099 110BA
- * 1109C ==> 1109B 110BA
- * 110AB ==> 110A5 110BA
- */
- if (uc == 0x1109A || uc == 0x1109C || uc == 0x110AB)
- return (0);
-
- t = 0;
- b = sizeof(u_decomposition_table)/sizeof(u_decomposition_table[0]) -1;
- while (b >= t) {
- int m = (t + b) / 2;
- if (u_decomposition_table[m].nfc < uc)
- t = m + 1;
- else if (u_decomposition_table[m].nfc > uc)
- b = m - 1;
- else {
- *cp1 = u_decomposition_table[m].cp1;
- *cp2 = u_decomposition_table[m].cp2;
- return (1);
- }
- }
- return (0);
-}
-
-#define REPLACE_UC_WITH(cp) do { \
- uc = cp; \
- ucptr = NULL; \
-} while (0)
-
-/*
- * Normalize UTF-8 characters to Form D and copy the result.
- */
-static int
-archive_string_normalize_D(struct archive_string *as, const void *_p,
- size_t len, struct archive_string_conv *sc)
-{
- const char *s = (const char *)_p;
- char *p, *endp;
- uint32_t uc, uc2;
- size_t w;
- int always_replace, n, n2, ret = 0, spair, ts, tm;
- int (*parse)(uint32_t *, const char *, size_t);
- size_t (*unparse)(char *, size_t, uint32_t);
-
- always_replace = 1;
- ts = 1;/* text size. */
- if (sc->flag & SCONV_TO_UTF16BE) {
- unparse = unicode_to_utf16be;
- ts = 2;
- if (sc->flag & SCONV_FROM_UTF16BE)
- always_replace = 0;
- } else if (sc->flag & SCONV_TO_UTF16LE) {
- unparse = unicode_to_utf16le;
- ts = 2;
- if (sc->flag & SCONV_FROM_UTF16LE)
- always_replace = 0;
- } else if (sc->flag & SCONV_TO_UTF8) {
- unparse = unicode_to_utf8;
- if (sc->flag & SCONV_FROM_UTF8)
- always_replace = 0;
- } else {
- /*
- * This case is going to be converted to another
- * character-set through iconv.
- */
- always_replace = 0;
- if (sc->flag & SCONV_FROM_UTF16BE) {
- unparse = unicode_to_utf16be;
- ts = 2;
- } else if (sc->flag & SCONV_FROM_UTF16LE) {
- unparse = unicode_to_utf16le;
- ts = 2;
- } else {
- unparse = unicode_to_utf8;
- }
- }
-
- if (sc->flag & SCONV_FROM_UTF16BE) {
- parse = utf16be_to_unicode;
- tm = 1;
- spair = 4;/* surrogate pair size in UTF-16. */
- } else if (sc->flag & SCONV_FROM_UTF16LE) {
- parse = utf16le_to_unicode;
- tm = 1;
- spair = 4;/* surrogate pair size in UTF-16. */
- } else {
- parse = cesu8_to_unicode;
- tm = ts;
- spair = 6;/* surrogate pair size in UTF-8. */
- }
-
- if (archive_string_ensure(as, as->length + len * tm + ts) == NULL)
- return (-1);
-
- p = as->s + as->length;
- endp = as->s + as->buffer_length - ts;
- while ((n = parse(&uc, s, len)) != 0) {
- const char *ucptr;
- uint32_t cp1, cp2;
- int SIndex;
- struct {
- uint32_t uc;
- int ccc;
- } fdc[FDC_MAX];
- int fdi, fdj;
- int ccc;
-
-check_first_code:
- if (n < 0) {
- /* Use a replaced unicode character. */
- UNPARSE(p, endp, uc);
- s += n*-1;
- len -= n*-1;
- ret = -1;
- continue;
- } else if (n == spair || always_replace)
- /* uc is converted from a surrogate pair.
- * this should be treated as a changed code. */
- ucptr = NULL;
- else
- ucptr = s;
- s += n;
- len -= n;
-
- /* Hangul Decomposition. */
- if ((SIndex = uc - HC_SBASE) >= 0 && SIndex < HC_SCOUNT) {
- int L = HC_LBASE + SIndex / HC_NCOUNT;
- int V = HC_VBASE + (SIndex % HC_NCOUNT) / HC_TCOUNT;
- int T = HC_TBASE + SIndex % HC_TCOUNT;
-
- REPLACE_UC_WITH(L);
- WRITE_UC();
- REPLACE_UC_WITH(V);
- WRITE_UC();
- if (T != HC_TBASE) {
- REPLACE_UC_WITH(T);
- WRITE_UC();
- }
- continue;
- }
- if (IS_DECOMPOSABLE_BLOCK(uc) && CCC(uc) != 0) {
- WRITE_UC();
- continue;
- }
-
- fdi = 0;
- while (get_nfd(&cp1, &cp2, uc) && fdi < FDC_MAX) {
- int k;
-
- for (k = fdi; k > 0; k--)
- fdc[k] = fdc[k-1];
- fdc[0].ccc = CCC(cp2);
- fdc[0].uc = cp2;
- fdi++;
- REPLACE_UC_WITH(cp1);
- }
-
- /* Read following code points. */
- while ((n2 = parse(&uc2, s, len)) > 0 &&
- (ccc = CCC(uc2)) != 0 && fdi < FDC_MAX) {
- int j, k;
-
- s += n2;
- len -= n2;
- for (j = 0; j < fdi; j++) {
- if (fdc[j].ccc > ccc)
- break;
- }
- if (j < fdi) {
- for (k = fdi; k > j; k--)
- fdc[k] = fdc[k-1];
- fdc[j].ccc = ccc;
- fdc[j].uc = uc2;
- } else {
- fdc[fdi].ccc = ccc;
- fdc[fdi].uc = uc2;
- }
- fdi++;
- }
-
- WRITE_UC();
- for (fdj = 0; fdj < fdi; fdj++) {
- REPLACE_UC_WITH(fdc[fdj].uc);
- WRITE_UC();
- }
-
- if (n2 == 0)
- break;
- REPLACE_UC_WITH(uc2);
- n = n2;
- goto check_first_code;
- }
- as->length = p - as->s;
- as->s[as->length] = '\0';
- if (ts == 2)
- as->s[as->length+1] = '\0';
- return (ret);
-}
-
-/*
- * libarchive 2.x made incorrect UTF-8 strings in the wrong assumption
- * that WCS is Unicode. It is true for several platforms but some are false.
- * And then people who did not use UTF-8 locale on the non Unicode WCS
- * platform and made a tar file with libarchive(mostly bsdtar) 2.x. Those
- * now cannot get right filename from libarchive 3.x and later since we
- * fixed the wrong assumption and it is incompatible to older its versions.
- * So we provide special option, "compat-2x.x", for resolving it.
- * That option enable the string conversion of libarchive 2.x.
- *
- * Translates the wrong UTF-8 string made by libarchive 2.x into current
- * locale character set and appends to the archive_string.
- * Note: returns -1 if conversion fails.
- */
-static int
-strncat_from_utf8_libarchive2(struct archive_string *as,
- const void *_p, size_t len, struct archive_string_conv *sc)
-{
- const char *s;
- int n;
- char *p;
- char *end;
- uint32_t unicode;
-#if HAVE_WCRTOMB
- mbstate_t shift_state;
-
- memset(&shift_state, 0, sizeof(shift_state));
-#else
- /* Clear the shift state before starting. */
- wctomb(NULL, L'\0');
-#endif
- (void)sc; /* UNUSED */
- /*
- * Allocate buffer for MBS.
- * We need this allocation here since it is possible that
- * as->s is still NULL.
- */
- if (archive_string_ensure(as, as->length + len + 1) == NULL)
- return (-1);
-
- s = (const char *)_p;
- p = as->s + as->length;
- end = as->s + as->buffer_length - MB_CUR_MAX -1;
- while ((n = _utf8_to_unicode(&unicode, s, len)) != 0) {
- wchar_t wc;
-
- if (p >= end) {
- as->length = p - as->s;
- /* Re-allocate buffer for MBS. */
- if (archive_string_ensure(as,
- as->length + max(len * 2,
- (size_t)MB_CUR_MAX) + 1) == NULL)
- return (-1);
- p = as->s + as->length;
- end = as->s + as->buffer_length - MB_CUR_MAX -1;
- }
-
- /*
- * As libarchive 2.x, translates the UTF-8 characters into
- * wide-characters in the assumption that WCS is Unicode.
- */
- if (n < 0) {
- n *= -1;
- wc = L'?';
- } else
- wc = (wchar_t)unicode;
-
- s += n;
- len -= n;
- /*
- * Translates the wide-character into the current locale MBS.
- */
-#if HAVE_WCRTOMB
- n = (int)wcrtomb(p, wc, &shift_state);
-#else
- n = (int)wctomb(p, wc);
-#endif
- if (n == -1)
- return (-1);
- p += n;
- }
- as->length = p - as->s;
- as->s[as->length] = '\0';
- return (0);
-}
-
-
-/*
- * Conversion functions between current locale dependent MBS and UTF-16BE.
- * strncat_from_utf16be() : UTF-16BE --> MBS
- * strncat_to_utf16be() : MBS --> UTF16BE
- */
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-
-/*
- * Convert a UTF-16BE/LE string to current locale and copy the result.
- * Return -1 if conversion fails.
- */
-static int
-win_strncat_from_utf16(struct archive_string *as, const void *_p, size_t bytes,
- struct archive_string_conv *sc, int be)
-{
- struct archive_string tmp;
- const char *u16;
- int ll;
- BOOL defchar;
- char *mbs;
- size_t mbs_size, b;
- int ret = 0;
-
- bytes &= ~1;
- if (archive_string_ensure(as, as->length + bytes +1) == NULL)
- return (-1);
-
- mbs = as->s + as->length;
- mbs_size = as->buffer_length - as->length -1;
-
- if (sc->to_cp == CP_C_LOCALE) {
- /*
- * "C" locale special process.
- */
- u16 = _p;
- ll = 0;
- for (b = 0; b < bytes; b += 2) {
- uint16_t val;
- if (be)
- val = archive_be16dec(u16+b);
- else
- val = archive_le16dec(u16+b);
- if (val > 255) {
- *mbs++ = '?';
- ret = -1;
- } else
- *mbs++ = (char)(val&0xff);
- ll++;
- }
- as->length += ll;
- as->s[as->length] = '\0';
- return (ret);
- }
-
- archive_string_init(&tmp);
- if (be) {
- if (is_big_endian()) {
- u16 = _p;
- } else {
- if (archive_string_ensure(&tmp, bytes+2) == NULL)
- return (-1);
- memcpy(tmp.s, _p, bytes);
- for (b = 0; b < bytes; b += 2) {
- uint16_t val = archive_be16dec(tmp.s+b);
- archive_le16enc(tmp.s+b, val);
- }
- u16 = tmp.s;
- }
- } else {
- if (!is_big_endian()) {
- u16 = _p;
- } else {
- if (archive_string_ensure(&tmp, bytes+2) == NULL)
- return (-1);
- memcpy(tmp.s, _p, bytes);
- for (b = 0; b < bytes; b += 2) {
- uint16_t val = archive_le16dec(tmp.s+b);
- archive_be16enc(tmp.s+b, val);
- }
- u16 = tmp.s;
- }
- }
-
- do {
- defchar = 0;
- ll = WideCharToMultiByte(sc->to_cp, 0,
- (LPCWSTR)u16, (int)bytes>>1, mbs, (int)mbs_size,
- NULL, &defchar);
- /* Exit loop if we succeeded */
- if (ll != 0 ||
- GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
- break;
- }
- /* Else expand buffer and loop to try again. */
- ll = WideCharToMultiByte(sc->to_cp, 0,
- (LPCWSTR)u16, (int)bytes, NULL, 0, NULL, NULL);
- if (archive_string_ensure(as, ll +1) == NULL)
- return (-1);
- mbs = as->s + as->length;
- mbs_size = as->buffer_length - as->length -1;
- } while (1);
- archive_string_free(&tmp);
- as->length += ll;
- as->s[as->length] = '\0';
- if (ll == 0 || defchar)
- ret = -1;
- return (ret);
-}
-
-static int
-win_strncat_from_utf16be(struct archive_string *as, const void *_p,
- size_t bytes, struct archive_string_conv *sc)
-{
- return (win_strncat_from_utf16(as, _p, bytes, sc, 1));
-}
-
-static int
-win_strncat_from_utf16le(struct archive_string *as, const void *_p,
- size_t bytes, struct archive_string_conv *sc)
-{
- return (win_strncat_from_utf16(as, _p, bytes, sc, 0));
-}
-
-static int
-is_big_endian(void)
-{
- uint16_t d = 1;
-
- return (archive_be16dec(&d) == 1);
-}
-
-/*
- * Convert a current locale string to UTF-16BE/LE and copy the result.
- * Return -1 if conversion fails.
- */
-static int
-win_strncat_to_utf16(struct archive_string *as16, const void *_p,
- size_t length, struct archive_string_conv *sc, int bigendian)
-{
- const char *s = (const char *)_p;
- char *u16;
- size_t count, avail;
-
- if (archive_string_ensure(as16,
- as16->length + (length + 1) * 2) == NULL)
- return (-1);
-
- u16 = as16->s + as16->length;
- avail = as16->buffer_length - 2;
- if (sc->from_cp == CP_C_LOCALE) {
- /*
- * "C" locale special process.
- */
- count = 0;
- while (count < length && *s) {
- if (bigendian)
- archive_be16enc(u16, *s);
- else
- archive_le16enc(u16, *s);
- u16 += 2;
- s++;
- count++;
- }
- as16->length += count << 1;
- as16->s[as16->length] = 0;
- as16->s[as16->length+1] = 0;
- return (0);
- }
- do {
- count = MultiByteToWideChar(sc->from_cp,
- MB_PRECOMPOSED, s, (int)length, (LPWSTR)u16, (int)avail>>1);
- /* Exit loop if we succeeded */
- if (count != 0 ||
- GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
- break;
- }
- /* Expand buffer and try again */
- count = MultiByteToWideChar(sc->from_cp,
- MB_PRECOMPOSED, s, (int)length, NULL, 0);
- if (archive_string_ensure(as16, (count +1) * 2)
- == NULL)
- return (-1);
- u16 = as16->s + as16->length;
- avail = as16->buffer_length - 2;
- } while (1);
- as16->length += count * 2;
- as16->s[as16->length] = 0;
- as16->s[as16->length+1] = 0;
- if (count == 0)
- return (-1);
-
- if (is_big_endian()) {
- if (!bigendian) {
- while (count > 0) {
- uint16_t v = archive_be16dec(u16);
- archive_le16enc(u16, v);
- u16 += 2;
- count--;
- }
- }
- } else {
- if (bigendian) {
- while (count > 0) {
- uint16_t v = archive_le16dec(u16);
- archive_be16enc(u16, v);
- u16 += 2;
- count--;
- }
- }
- }
- return (0);
-}
-
-static int
-win_strncat_to_utf16be(struct archive_string *as16, const void *_p,
- size_t length, struct archive_string_conv *sc)
-{
- return (win_strncat_to_utf16(as16, _p, length, sc, 1));
-}
-
-static int
-win_strncat_to_utf16le(struct archive_string *as16, const void *_p,
- size_t length, struct archive_string_conv *sc)
-{
- return (win_strncat_to_utf16(as16, _p, length, sc, 0));
-}
-
-#endif /* _WIN32 && !__CYGWIN__ */
-
-/*
- * Do the best effort for conversions.
- * We cannot handle UTF-16BE character-set without such iconv,
- * but there is a chance if a string consists just ASCII code or
- * a current locale is UTF-8.
- */
-
-/*
- * Convert a UTF-16BE string to current locale and copy the result.
- * Return -1 if conversion fails.
- */
-static int
-best_effort_strncat_from_utf16(struct archive_string *as, const void *_p,
- size_t bytes, struct archive_string_conv *sc, int be)
-{
- const char *utf16 = (const char *)_p;
- char *mbs;
- uint32_t uc;
- int n, ret;
-
- (void)sc; /* UNUSED */
- /*
- * Other case, we should do the best effort.
- * If all character are ASCII(<0x7f), we can convert it.
- * if not , we set a alternative character and return -1.
- */
- ret = 0;
- if (archive_string_ensure(as, as->length + bytes +1) == NULL)
- return (-1);
- mbs = as->s + as->length;
-
- while ((n = utf16_to_unicode(&uc, utf16, bytes, be)) != 0) {
- if (n < 0) {
- n *= -1;
- ret = -1;
- }
- bytes -= n;
- utf16 += n;
-
- if (uc > 127) {
- /* We cannot handle it. */
- *mbs++ = '?';
- ret = -1;
- } else
- *mbs++ = (char)uc;
- }
- as->length = mbs - as->s;
- as->s[as->length] = '\0';
- return (ret);
-}
-
-static int
-best_effort_strncat_from_utf16be(struct archive_string *as, const void *_p,
- size_t bytes, struct archive_string_conv *sc)
-{
- return (best_effort_strncat_from_utf16(as, _p, bytes, sc, 1));
-}
-
-static int
-best_effort_strncat_from_utf16le(struct archive_string *as, const void *_p,
- size_t bytes, struct archive_string_conv *sc)
-{
- return (best_effort_strncat_from_utf16(as, _p, bytes, sc, 0));
-}
-
-/*
- * Convert a current locale string to UTF-16BE/LE and copy the result.
- * Return -1 if conversion fails.
- */
-static int
-best_effort_strncat_to_utf16(struct archive_string *as16, const void *_p,
- size_t length, struct archive_string_conv *sc, int bigendian)
-{
- const char *s = (const char *)_p;
- char *utf16;
- size_t remaining;
- int ret;
-
- (void)sc; /* UNUSED */
- /*
- * Other case, we should do the best effort.
- * If all character are ASCII(<0x7f), we can convert it.
- * if not , we set a alternative character and return -1.
- */
- ret = 0;
- remaining = length;
-
- if (archive_string_ensure(as16,
- as16->length + (length + 1) * 2) == NULL)
- return (-1);
-
- utf16 = as16->s + as16->length;
- while (remaining--) {
- unsigned c = *s++;
- if (c > 127) {
- /* We cannot handle it. */
- c = UNICODE_R_CHAR;
- ret = -1;
- }
- if (bigendian)
- archive_be16enc(utf16, c);
- else
- archive_le16enc(utf16, c);
- utf16 += 2;
- }
- as16->length = utf16 - as16->s;
- as16->s[as16->length] = 0;
- as16->s[as16->length+1] = 0;
- return (ret);
-}
-
-static int
-best_effort_strncat_to_utf16be(struct archive_string *as16, const void *_p,
- size_t length, struct archive_string_conv *sc)
-{
- return (best_effort_strncat_to_utf16(as16, _p, length, sc, 1));
-}
-
-static int
-best_effort_strncat_to_utf16le(struct archive_string *as16, const void *_p,
- size_t length, struct archive_string_conv *sc)
-{
- return (best_effort_strncat_to_utf16(as16, _p, length, sc, 0));
-}
-
-
-/*
- * Multistring operations.
- */
-
-void
-archive_mstring_clean(struct archive_mstring *aes)
-{
- archive_wstring_free(&(aes->aes_wcs));
- archive_string_free(&(aes->aes_mbs));
- archive_string_free(&(aes->aes_utf8));
- archive_string_free(&(aes->aes_mbs_in_locale));
- aes->aes_set = 0;
-}
-
-void
-archive_mstring_copy(struct archive_mstring *dest, struct archive_mstring *src)
-{
- dest->aes_set = src->aes_set;
- archive_string_copy(&(dest->aes_mbs), &(src->aes_mbs));
- archive_string_copy(&(dest->aes_utf8), &(src->aes_utf8));
- archive_wstring_copy(&(dest->aes_wcs), &(src->aes_wcs));
-}
-
-int
-archive_mstring_get_utf8(struct archive *a, struct archive_mstring *aes,
- const char **p)
-{
- struct archive_string_conv *sc;
- int r;
-
- /* If we already have a UTF8 form, return that immediately. */
- if (aes->aes_set & AES_SET_UTF8) {
- *p = aes->aes_utf8.s;
- return (0);
- }
-
- *p = NULL;
- /* Try converting WCS to MBS first if MBS does not exist yet. */
- if ((aes->aes_set & AES_SET_MBS) == 0) {
- const char *pm; /* unused */
- archive_mstring_get_mbs(a, aes, &pm); /* ignore errors, we'll handle it later */
- }
- if (aes->aes_set & AES_SET_MBS) {
- sc = archive_string_conversion_to_charset(a, "UTF-8", 1);
- if (sc == NULL)
- return (-1);/* Couldn't allocate memory for sc. */
- r = archive_strncpy_l(&(aes->aes_utf8), aes->aes_mbs.s,
- aes->aes_mbs.length, sc);
- if (a == NULL)
- free_sconv_object(sc);
- if (r == 0) {
- aes->aes_set |= AES_SET_UTF8;
- *p = aes->aes_utf8.s;
- return (0);/* success. */
- } else
- return (-1);/* failure. */
- }
- return (0);/* success. */
-}
-
-int
-archive_mstring_get_mbs(struct archive *a, struct archive_mstring *aes,
- const char **p)
-{
- struct archive_string_conv *sc;
- int r, ret = 0;
-
- /* If we already have an MBS form, return that immediately. */
- if (aes->aes_set & AES_SET_MBS) {
- *p = aes->aes_mbs.s;
- return (ret);
- }
-
- *p = NULL;
- /* If there's a WCS form, try converting with the native locale. */
- if (aes->aes_set & AES_SET_WCS) {
- archive_string_empty(&(aes->aes_mbs));
- r = archive_string_append_from_wcs(&(aes->aes_mbs),
- aes->aes_wcs.s, aes->aes_wcs.length);
- *p = aes->aes_mbs.s;
- if (r == 0) {
- aes->aes_set |= AES_SET_MBS;
- return (ret);
- } else
- ret = -1;
- }
-
- /* If there's a UTF-8 form, try converting with the native locale. */
- if (aes->aes_set & AES_SET_UTF8) {
- archive_string_empty(&(aes->aes_mbs));
- sc = archive_string_conversion_from_charset(a, "UTF-8", 1);
- if (sc == NULL)
- return (-1);/* Couldn't allocate memory for sc. */
- r = archive_strncpy_l(&(aes->aes_mbs),
- aes->aes_utf8.s, aes->aes_utf8.length, sc);
- if (a == NULL)
- free_sconv_object(sc);
- *p = aes->aes_mbs.s;
- if (r == 0) {
- aes->aes_set |= AES_SET_MBS;
- ret = 0;/* success; overwrite previous error. */
- } else
- ret = -1;/* failure. */
- }
- return (ret);
-}
-
-int
-archive_mstring_get_wcs(struct archive *a, struct archive_mstring *aes,
- const wchar_t **wp)
-{
- int r, ret = 0;
-
- (void)a;/* UNUSED */
- /* Return WCS form if we already have it. */
- if (aes->aes_set & AES_SET_WCS) {
- *wp = aes->aes_wcs.s;
- return (ret);
- }
-
- *wp = NULL;
- /* Try converting UTF8 to MBS first if MBS does not exist yet. */
- if ((aes->aes_set & AES_SET_MBS) == 0) {
- const char *p; /* unused */
- archive_mstring_get_mbs(a, aes, &p); /* ignore errors, we'll handle it later */
- }
- /* Try converting MBS to WCS using native locale. */
- if (aes->aes_set & AES_SET_MBS) {
- archive_wstring_empty(&(aes->aes_wcs));
- r = archive_wstring_append_from_mbs(&(aes->aes_wcs),
- aes->aes_mbs.s, aes->aes_mbs.length);
- if (r == 0) {
- aes->aes_set |= AES_SET_WCS;
- *wp = aes->aes_wcs.s;
- } else
- ret = -1;/* failure. */
- }
- return (ret);
-}
-
-int
-archive_mstring_get_mbs_l(struct archive *a, struct archive_mstring *aes,
- const char **p, size_t *length, struct archive_string_conv *sc)
-{
- int ret = 0;
-#if defined(_WIN32) && !defined(__CYGWIN__)
- int r;
-
- /*
- * Internationalization programming on Windows must use Wide
- * characters because Windows platform cannot make locale UTF-8.
- */
- if (sc != NULL && (aes->aes_set & AES_SET_WCS) != 0) {
- archive_string_empty(&(aes->aes_mbs_in_locale));
- r = archive_string_append_from_wcs_in_codepage(
- &(aes->aes_mbs_in_locale), aes->aes_wcs.s,
- aes->aes_wcs.length, sc);
- if (r == 0) {
- *p = aes->aes_mbs_in_locale.s;
- if (length != NULL)
- *length = aes->aes_mbs_in_locale.length;
- return (0);
- } else if (errno == ENOMEM)
- return (-1);
- else
- ret = -1;
- }
-#endif
-
- /* If there is not an MBS form but there is a WCS or UTF8 form, try converting
- * with the native locale to be used for translating it to specified
- * character-set. */
- if ((aes->aes_set & AES_SET_MBS) == 0) {
- const char *pm; /* unused */
- archive_mstring_get_mbs(a, aes, &pm); /* ignore errors, we'll handle it later */
- }
- /* If we already have an MBS form, use it to be translated to
- * specified character-set. */
- if (aes->aes_set & AES_SET_MBS) {
- if (sc == NULL) {
- /* Conversion is unneeded. */
- *p = aes->aes_mbs.s;
- if (length != NULL)
- *length = aes->aes_mbs.length;
- return (0);
- }
- ret = archive_strncpy_l(&(aes->aes_mbs_in_locale),
- aes->aes_mbs.s, aes->aes_mbs.length, sc);
- *p = aes->aes_mbs_in_locale.s;
- if (length != NULL)
- *length = aes->aes_mbs_in_locale.length;
- } else {
- *p = NULL;
- if (length != NULL)
- *length = 0;
- }
- return (ret);
-}
-
-int
-archive_mstring_copy_mbs(struct archive_mstring *aes, const char *mbs)
-{
- if (mbs == NULL) {
- aes->aes_set = 0;
- return (0);
- }
- return (archive_mstring_copy_mbs_len(aes, mbs, strlen(mbs)));
-}
-
-int
-archive_mstring_copy_mbs_len(struct archive_mstring *aes, const char *mbs,
- size_t len)
-{
- if (mbs == NULL) {
- aes->aes_set = 0;
- return (0);
- }
- aes->aes_set = AES_SET_MBS; /* Only MBS form is set now. */
- archive_strncpy(&(aes->aes_mbs), mbs, len);
- archive_string_empty(&(aes->aes_utf8));
- archive_wstring_empty(&(aes->aes_wcs));
- return (0);
-}
-
-int
-archive_mstring_copy_wcs(struct archive_mstring *aes, const wchar_t *wcs)
-{
- return archive_mstring_copy_wcs_len(aes, wcs,
- wcs == NULL ? 0 : wcslen(wcs));
-}
-
-int
-archive_mstring_copy_utf8(struct archive_mstring *aes, const char *utf8)
-{
- if (utf8 == NULL) {
- aes->aes_set = 0;
- return (0);
- }
- aes->aes_set = AES_SET_UTF8;
- archive_string_empty(&(aes->aes_mbs));
- archive_string_empty(&(aes->aes_wcs));
- archive_strncpy(&(aes->aes_utf8), utf8, strlen(utf8));
- return (int)strlen(utf8);
-}
-
-int
-archive_mstring_copy_wcs_len(struct archive_mstring *aes, const wchar_t *wcs,
- size_t len)
-{
- if (wcs == NULL) {
- aes->aes_set = 0;
- return (0);
- }
- aes->aes_set = AES_SET_WCS; /* Only WCS form set. */
- archive_string_empty(&(aes->aes_mbs));
- archive_string_empty(&(aes->aes_utf8));
- archive_wstrncpy(&(aes->aes_wcs), wcs, len);
- return (0);
-}
-
-int
-archive_mstring_copy_mbs_len_l(struct archive_mstring *aes,
- const char *mbs, size_t len, struct archive_string_conv *sc)
-{
- int r;
-
- if (mbs == NULL) {
- aes->aes_set = 0;
- return (0);
- }
- archive_string_empty(&(aes->aes_mbs));
- archive_wstring_empty(&(aes->aes_wcs));
- archive_string_empty(&(aes->aes_utf8));
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /*
- * Internationalization programming on Windows must use Wide
- * characters because Windows platform cannot make locale UTF-8.
- */
- if (sc == NULL) {
- if (archive_string_append(&(aes->aes_mbs),
- mbs, mbsnbytes(mbs, len)) == NULL) {
- aes->aes_set = 0;
- r = -1;
- } else {
- aes->aes_set = AES_SET_MBS;
- r = 0;
- }
-#if defined(HAVE_ICONV)
- } else if (sc != NULL && sc->cd_w != (iconv_t)-1) {
- /*
- * This case happens only when MultiByteToWideChar() cannot
- * handle sc->from_cp, and we have to iconv in order to
- * translate character-set to wchar_t,UTF-16.
- */
- iconv_t cd = sc->cd;
- unsigned from_cp;
- int flag;
-
- /*
- * Translate multi-bytes from some character-set to UTF-8.
- */
- sc->cd = sc->cd_w;
- r = archive_strncpy_l(&(aes->aes_utf8), mbs, len, sc);
- sc->cd = cd;
- if (r != 0) {
- aes->aes_set = 0;
- return (r);
- }
- aes->aes_set = AES_SET_UTF8;
-
- /*
- * Append the UTF-8 string into wstring.
- */
- flag = sc->flag;
- sc->flag &= ~(SCONV_NORMALIZATION_C
- | SCONV_TO_UTF16| SCONV_FROM_UTF16);
- from_cp = sc->from_cp;
- sc->from_cp = CP_UTF8;
- r = archive_wstring_append_from_mbs_in_codepage(&(aes->aes_wcs),
- aes->aes_utf8.s, aes->aes_utf8.length, sc);
- sc->flag = flag;
- sc->from_cp = from_cp;
- if (r == 0)
- aes->aes_set |= AES_SET_WCS;
-#endif
- } else {
- r = archive_wstring_append_from_mbs_in_codepage(
- &(aes->aes_wcs), mbs, len, sc);
- if (r == 0)
- aes->aes_set = AES_SET_WCS;
- else
- aes->aes_set = 0;
- }
-#else
- r = archive_strncpy_l(&(aes->aes_mbs), mbs, len, sc);
- if (r == 0)
- aes->aes_set = AES_SET_MBS; /* Only MBS form is set now. */
- else
- aes->aes_set = 0;
-#endif
- return (r);
-}
-
-/*
- * The 'update' form tries to proactively update all forms of
- * this string (WCS and MBS) and returns an error if any of
- * them fail. This is used by the 'pax' handler, for instance,
- * to detect and report character-conversion failures early while
- * still allowing clients to get potentially useful values from
- * the more tolerant lazy conversions. (get_mbs and get_wcs will
- * strive to give the user something useful, so you can get hopefully
- * usable values even if some of the character conversions are failing.)
- */
-int
-archive_mstring_update_utf8(struct archive *a, struct archive_mstring *aes,
- const char *utf8)
-{
- struct archive_string_conv *sc;
- int r;
-
- if (utf8 == NULL) {
- aes->aes_set = 0;
- return (0); /* Succeeded in clearing everything. */
- }
-
- /* Save the UTF8 string. */
- archive_strcpy(&(aes->aes_utf8), utf8);
-
- /* Empty the mbs and wcs strings. */
- archive_string_empty(&(aes->aes_mbs));
- archive_wstring_empty(&(aes->aes_wcs));
-
- aes->aes_set = AES_SET_UTF8; /* Only UTF8 is set now. */
-
- /* Try converting UTF-8 to MBS, return false on failure. */
- sc = archive_string_conversion_from_charset(a, "UTF-8", 1);
- if (sc == NULL)
- return (-1);/* Couldn't allocate memory for sc. */
- r = archive_strcpy_l(&(aes->aes_mbs), utf8, sc);
- if (a == NULL)
- free_sconv_object(sc);
- if (r != 0)
- return (-1);
- aes->aes_set = AES_SET_UTF8 | AES_SET_MBS; /* Both UTF8 and MBS set. */
-
- /* Try converting MBS to WCS, return false on failure. */
- if (archive_wstring_append_from_mbs(&(aes->aes_wcs), aes->aes_mbs.s,
- aes->aes_mbs.length))
- return (-1);
- aes->aes_set = AES_SET_UTF8 | AES_SET_WCS | AES_SET_MBS;
-
- /* All conversions succeeded. */
- return (0);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_string.h b/contrib/libs/libarchive/libarchive/archive_string.h
deleted file mode 100644
index 49d7d3064a..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_string.h
+++ /dev/null
@@ -1,243 +0,0 @@
-/*-
- * Copyright (c) 2003-2010 Tim Kientzle
- * 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(S) ``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(S) 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.
- *
- * $FreeBSD: head/lib/libarchive/archive_string.h 201092 2009-12-28 02:26:06Z kientzle $
- *
- */
-
-#ifndef ARCHIVE_STRING_H_INCLUDED
-#define ARCHIVE_STRING_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#ifndef __LIBARCHIVE_TEST
-#error This header is only to be used internally to libarchive.
-#endif
-#endif
-
-#include <stdarg.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h> /* required for wchar_t on some systems */
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_WCHAR_H
-#include <wchar.h>
-#endif
-
-#include "archive.h"
-
-/*
- * Basic resizable/reusable string support similar to Java's "StringBuffer."
- *
- * Unlike sbuf(9), the buffers here are fully reusable and track the
- * length throughout.
- */
-
-struct archive_string {
- char *s; /* Pointer to the storage */
- size_t length; /* Length of 's' in characters */
- size_t buffer_length; /* Length of malloc-ed storage in bytes. */
-};
-
-struct archive_wstring {
- wchar_t *s; /* Pointer to the storage */
- size_t length; /* Length of 's' in characters */
- size_t buffer_length; /* Length of malloc-ed storage in bytes. */
-};
-
-struct archive_string_conv;
-
-/* Initialize an archive_string object on the stack or elsewhere. */
-#define archive_string_init(a) \
- do { (a)->s = NULL; (a)->length = 0; (a)->buffer_length = 0; } while(0)
-
-/* Append a C char to an archive_string, resizing as necessary. */
-struct archive_string *
-archive_strappend_char(struct archive_string *, char);
-
-/* Ditto for a wchar_t and an archive_wstring. */
-struct archive_wstring *
-archive_wstrappend_wchar(struct archive_wstring *, wchar_t);
-
-/* Append a raw array to an archive_string, resizing as necessary */
-struct archive_string *
-archive_array_append(struct archive_string *, const char *, size_t);
-
-/* Convert a Unicode string to current locale and append the result. */
-/* Returns -1 if conversion fails. */
-int
-archive_string_append_from_wcs(struct archive_string *, const wchar_t *, size_t);
-
-
-/* Create a string conversion object.
- * Return NULL and set a error message if the conversion is not supported
- * on the platform. */
-struct archive_string_conv *
-archive_string_conversion_to_charset(struct archive *, const char *, int);
-struct archive_string_conv *
-archive_string_conversion_from_charset(struct archive *, const char *, int);
-/* Create the default string conversion object for reading/writing an archive.
- * Return NULL if the conversion is unneeded.
- * Note: On non Windows platform this always returns NULL.
- */
-struct archive_string_conv *
-archive_string_default_conversion_for_read(struct archive *);
-struct archive_string_conv *
-archive_string_default_conversion_for_write(struct archive *);
-/* Dispose of a string conversion object. */
-void
-archive_string_conversion_free(struct archive *);
-const char *
-archive_string_conversion_charset_name(struct archive_string_conv *);
-void
-archive_string_conversion_set_opt(struct archive_string_conv *, int);
-#define SCONV_SET_OPT_UTF8_LIBARCHIVE2X 1
-#define SCONV_SET_OPT_NORMALIZATION_C 2
-#define SCONV_SET_OPT_NORMALIZATION_D 4
-
-
-/* Copy one archive_string to another in locale conversion.
- * Return -1 if conversion fails. */
-int
-archive_strncpy_l(struct archive_string *, const void *, size_t,
- struct archive_string_conv *);
-
-/* Copy one archive_string to another in locale conversion.
- * Return -1 if conversion fails. */
-int
-archive_strncat_l(struct archive_string *, const void *, size_t,
- struct archive_string_conv *);
-
-
-/* Copy one archive_string to another */
-#define archive_string_copy(dest, src) \
- ((dest)->length = 0, archive_string_concat((dest), (src)))
-#define archive_wstring_copy(dest, src) \
- ((dest)->length = 0, archive_wstring_concat((dest), (src)))
-
-/* Concatenate one archive_string to another */
-void archive_string_concat(struct archive_string *dest, struct archive_string *src);
-void archive_wstring_concat(struct archive_wstring *dest, struct archive_wstring *src);
-
-/* Ensure that the underlying buffer is at least as large as the request. */
-struct archive_string *
-archive_string_ensure(struct archive_string *, size_t);
-struct archive_wstring *
-archive_wstring_ensure(struct archive_wstring *, size_t);
-
-/* Append C string, which may lack trailing \0. */
-/* The source is declared void * here because this gets used with
- * "signed char *", "unsigned char *" and "char *" arguments.
- * Declaring it "char *" as with some of the other functions just
- * leads to a lot of extra casts. */
-struct archive_string *
-archive_strncat(struct archive_string *, const void *, size_t);
-struct archive_wstring *
-archive_wstrncat(struct archive_wstring *, const wchar_t *, size_t);
-
-/* Append a C string to an archive_string, resizing as necessary. */
-struct archive_string *
-archive_strcat(struct archive_string *, const void *);
-struct archive_wstring *
-archive_wstrcat(struct archive_wstring *, const wchar_t *);
-
-/* Copy a C string to an archive_string, resizing as necessary. */
-#define archive_strcpy(as,p) \
- archive_strncpy((as), (p), ((p) == NULL ? 0 : strlen(p)))
-#define archive_wstrcpy(as,p) \
- archive_wstrncpy((as), (p), ((p) == NULL ? 0 : wcslen(p)))
-#define archive_strcpy_l(as,p,lo) \
- archive_strncpy_l((as), (p), ((p) == NULL ? 0 : strlen(p)), (lo))
-
-/* Copy a C string to an archive_string with limit, resizing as necessary. */
-#define archive_strncpy(as,p,l) \
- ((as)->length=0, archive_strncat((as), (p), (l)))
-#define archive_wstrncpy(as,p,l) \
- ((as)->length = 0, archive_wstrncat((as), (p), (l)))
-
-/* Return length of string. */
-#define archive_strlen(a) ((a)->length)
-
-/* Set string length to zero. */
-#define archive_string_empty(a) ((a)->length = 0)
-#define archive_wstring_empty(a) ((a)->length = 0)
-
-/* Release any allocated storage resources. */
-void archive_string_free(struct archive_string *);
-void archive_wstring_free(struct archive_wstring *);
-
-/* Like 'vsprintf', but resizes the underlying string as necessary. */
-/* Note: This only implements a small subset of standard printf functionality. */
-void archive_string_vsprintf(struct archive_string *, const char *,
- va_list) __LA_PRINTF(2, 0);
-void archive_string_sprintf(struct archive_string *, const char *, ...)
- __LA_PRINTF(2, 3);
-
-/* Translates from MBS to Unicode. */
-/* Returns non-zero if conversion failed in any way. */
-int archive_wstring_append_from_mbs(struct archive_wstring *dest,
- const char *, size_t);
-
-
-/* A "multistring" can hold Unicode, UTF8, or MBS versions of
- * the string. If you set and read the same version, no translation
- * is done. If you set and read different versions, the library
- * will attempt to transparently convert.
- */
-struct archive_mstring {
- struct archive_string aes_mbs;
- struct archive_string aes_utf8;
- struct archive_wstring aes_wcs;
- struct archive_string aes_mbs_in_locale;
- /* Bitmap of which of the above are valid. Because we're lazy
- * about malloc-ing and reusing the underlying storage, we
- * can't rely on NULL pointers to indicate whether a string
- * has been set. */
- int aes_set;
-#define AES_SET_MBS 1
-#define AES_SET_UTF8 2
-#define AES_SET_WCS 4
-};
-
-void archive_mstring_clean(struct archive_mstring *);
-void archive_mstring_copy(struct archive_mstring *dest, struct archive_mstring *src);
-int archive_mstring_get_mbs(struct archive *, struct archive_mstring *, const char **);
-int archive_mstring_get_utf8(struct archive *, struct archive_mstring *, const char **);
-int archive_mstring_get_wcs(struct archive *, struct archive_mstring *, const wchar_t **);
-int archive_mstring_get_mbs_l(struct archive *, struct archive_mstring *, const char **,
- size_t *, struct archive_string_conv *);
-int archive_mstring_copy_mbs(struct archive_mstring *, const char *mbs);
-int archive_mstring_copy_mbs_len(struct archive_mstring *, const char *mbs,
- size_t);
-int archive_mstring_copy_utf8(struct archive_mstring *, const char *utf8);
-int archive_mstring_copy_wcs(struct archive_mstring *, const wchar_t *wcs);
-int archive_mstring_copy_wcs_len(struct archive_mstring *,
- const wchar_t *wcs, size_t);
-int archive_mstring_copy_mbs_len_l(struct archive_mstring *,
- const char *mbs, size_t, struct archive_string_conv *);
-int archive_mstring_update_utf8(struct archive *, struct archive_mstring *aes, const char *utf8);
-
-
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_string_composition.h b/contrib/libs/libarchive/libarchive/archive_string_composition.h
deleted file mode 100644
index d0ac340961..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_string_composition.h
+++ /dev/null
@@ -1,2292 +0,0 @@
-/*-
- * Copyright (c) 2011-2012 libarchive Project
- * 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(S) 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(S) 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.
- *
- * $FreeBSD$
- *
- */
-
-/*
- * ATTENTION!
- * This file is generated by build/utils/gen_archive_string_composition_h.sh
- * from http://unicode.org/Public/6.0.0/ucd/UnicodeData.txt
- *
- * See also http://unicode.org/report/tr15/
- */
-
-#ifndef ARCHIVE_STRING_COMPOSITION_H_INCLUDED
-#define ARCHIVE_STRING_COMPOSITION_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
-struct unicode_composition_table {
- uint32_t cp1;
- uint32_t cp2;
- uint32_t nfc;
-};
-
-static const struct unicode_composition_table u_composition_table[] = {
- { 0x0003C , 0x00338 , 0x0226E },
- { 0x0003D , 0x00338 , 0x02260 },
- { 0x0003E , 0x00338 , 0x0226F },
- { 0x00041 , 0x00300 , 0x000C0 },
- { 0x00041 , 0x00301 , 0x000C1 },
- { 0x00041 , 0x00302 , 0x000C2 },
- { 0x00041 , 0x00303 , 0x000C3 },
- { 0x00041 , 0x00304 , 0x00100 },
- { 0x00041 , 0x00306 , 0x00102 },
- { 0x00041 , 0x00307 , 0x00226 },
- { 0x00041 , 0x00308 , 0x000C4 },
- { 0x00041 , 0x00309 , 0x01EA2 },
- { 0x00041 , 0x0030A , 0x000C5 },
- { 0x00041 , 0x0030C , 0x001CD },
- { 0x00041 , 0x0030F , 0x00200 },
- { 0x00041 , 0x00311 , 0x00202 },
- { 0x00041 , 0x00323 , 0x01EA0 },
- { 0x00041 , 0x00325 , 0x01E00 },
- { 0x00041 , 0x00328 , 0x00104 },
- { 0x00042 , 0x00307 , 0x01E02 },
- { 0x00042 , 0x00323 , 0x01E04 },
- { 0x00042 , 0x00331 , 0x01E06 },
- { 0x00043 , 0x00301 , 0x00106 },
- { 0x00043 , 0x00302 , 0x00108 },
- { 0x00043 , 0x00307 , 0x0010A },
- { 0x00043 , 0x0030C , 0x0010C },
- { 0x00043 , 0x00327 , 0x000C7 },
- { 0x00044 , 0x00307 , 0x01E0A },
- { 0x00044 , 0x0030C , 0x0010E },
- { 0x00044 , 0x00323 , 0x01E0C },
- { 0x00044 , 0x00327 , 0x01E10 },
- { 0x00044 , 0x0032D , 0x01E12 },
- { 0x00044 , 0x00331 , 0x01E0E },
- { 0x00045 , 0x00300 , 0x000C8 },
- { 0x00045 , 0x00301 , 0x000C9 },
- { 0x00045 , 0x00302 , 0x000CA },
- { 0x00045 , 0x00303 , 0x01EBC },
- { 0x00045 , 0x00304 , 0x00112 },
- { 0x00045 , 0x00306 , 0x00114 },
- { 0x00045 , 0x00307 , 0x00116 },
- { 0x00045 , 0x00308 , 0x000CB },
- { 0x00045 , 0x00309 , 0x01EBA },
- { 0x00045 , 0x0030C , 0x0011A },
- { 0x00045 , 0x0030F , 0x00204 },
- { 0x00045 , 0x00311 , 0x00206 },
- { 0x00045 , 0x00323 , 0x01EB8 },
- { 0x00045 , 0x00327 , 0x00228 },
- { 0x00045 , 0x00328 , 0x00118 },
- { 0x00045 , 0x0032D , 0x01E18 },
- { 0x00045 , 0x00330 , 0x01E1A },
- { 0x00046 , 0x00307 , 0x01E1E },
- { 0x00047 , 0x00301 , 0x001F4 },
- { 0x00047 , 0x00302 , 0x0011C },
- { 0x00047 , 0x00304 , 0x01E20 },
- { 0x00047 , 0x00306 , 0x0011E },
- { 0x00047 , 0x00307 , 0x00120 },
- { 0x00047 , 0x0030C , 0x001E6 },
- { 0x00047 , 0x00327 , 0x00122 },
- { 0x00048 , 0x00302 , 0x00124 },
- { 0x00048 , 0x00307 , 0x01E22 },
- { 0x00048 , 0x00308 , 0x01E26 },
- { 0x00048 , 0x0030C , 0x0021E },
- { 0x00048 , 0x00323 , 0x01E24 },
- { 0x00048 , 0x00327 , 0x01E28 },
- { 0x00048 , 0x0032E , 0x01E2A },
- { 0x00049 , 0x00300 , 0x000CC },
- { 0x00049 , 0x00301 , 0x000CD },
- { 0x00049 , 0x00302 , 0x000CE },
- { 0x00049 , 0x00303 , 0x00128 },
- { 0x00049 , 0x00304 , 0x0012A },
- { 0x00049 , 0x00306 , 0x0012C },
- { 0x00049 , 0x00307 , 0x00130 },
- { 0x00049 , 0x00308 , 0x000CF },
- { 0x00049 , 0x00309 , 0x01EC8 },
- { 0x00049 , 0x0030C , 0x001CF },
- { 0x00049 , 0x0030F , 0x00208 },
- { 0x00049 , 0x00311 , 0x0020A },
- { 0x00049 , 0x00323 , 0x01ECA },
- { 0x00049 , 0x00328 , 0x0012E },
- { 0x00049 , 0x00330 , 0x01E2C },
- { 0x0004A , 0x00302 , 0x00134 },
- { 0x0004B , 0x00301 , 0x01E30 },
- { 0x0004B , 0x0030C , 0x001E8 },
- { 0x0004B , 0x00323 , 0x01E32 },
- { 0x0004B , 0x00327 , 0x00136 },
- { 0x0004B , 0x00331 , 0x01E34 },
- { 0x0004C , 0x00301 , 0x00139 },
- { 0x0004C , 0x0030C , 0x0013D },
- { 0x0004C , 0x00323 , 0x01E36 },
- { 0x0004C , 0x00327 , 0x0013B },
- { 0x0004C , 0x0032D , 0x01E3C },
- { 0x0004C , 0x00331 , 0x01E3A },
- { 0x0004D , 0x00301 , 0x01E3E },
- { 0x0004D , 0x00307 , 0x01E40 },
- { 0x0004D , 0x00323 , 0x01E42 },
- { 0x0004E , 0x00300 , 0x001F8 },
- { 0x0004E , 0x00301 , 0x00143 },
- { 0x0004E , 0x00303 , 0x000D1 },
- { 0x0004E , 0x00307 , 0x01E44 },
- { 0x0004E , 0x0030C , 0x00147 },
- { 0x0004E , 0x00323 , 0x01E46 },
- { 0x0004E , 0x00327 , 0x00145 },
- { 0x0004E , 0x0032D , 0x01E4A },
- { 0x0004E , 0x00331 , 0x01E48 },
- { 0x0004F , 0x00300 , 0x000D2 },
- { 0x0004F , 0x00301 , 0x000D3 },
- { 0x0004F , 0x00302 , 0x000D4 },
- { 0x0004F , 0x00303 , 0x000D5 },
- { 0x0004F , 0x00304 , 0x0014C },
- { 0x0004F , 0x00306 , 0x0014E },
- { 0x0004F , 0x00307 , 0x0022E },
- { 0x0004F , 0x00308 , 0x000D6 },
- { 0x0004F , 0x00309 , 0x01ECE },
- { 0x0004F , 0x0030B , 0x00150 },
- { 0x0004F , 0x0030C , 0x001D1 },
- { 0x0004F , 0x0030F , 0x0020C },
- { 0x0004F , 0x00311 , 0x0020E },
- { 0x0004F , 0x0031B , 0x001A0 },
- { 0x0004F , 0x00323 , 0x01ECC },
- { 0x0004F , 0x00328 , 0x001EA },
- { 0x00050 , 0x00301 , 0x01E54 },
- { 0x00050 , 0x00307 , 0x01E56 },
- { 0x00052 , 0x00301 , 0x00154 },
- { 0x00052 , 0x00307 , 0x01E58 },
- { 0x00052 , 0x0030C , 0x00158 },
- { 0x00052 , 0x0030F , 0x00210 },
- { 0x00052 , 0x00311 , 0x00212 },
- { 0x00052 , 0x00323 , 0x01E5A },
- { 0x00052 , 0x00327 , 0x00156 },
- { 0x00052 , 0x00331 , 0x01E5E },
- { 0x00053 , 0x00301 , 0x0015A },
- { 0x00053 , 0x00302 , 0x0015C },
- { 0x00053 , 0x00307 , 0x01E60 },
- { 0x00053 , 0x0030C , 0x00160 },
- { 0x00053 , 0x00323 , 0x01E62 },
- { 0x00053 , 0x00326 , 0x00218 },
- { 0x00053 , 0x00327 , 0x0015E },
- { 0x00054 , 0x00307 , 0x01E6A },
- { 0x00054 , 0x0030C , 0x00164 },
- { 0x00054 , 0x00323 , 0x01E6C },
- { 0x00054 , 0x00326 , 0x0021A },
- { 0x00054 , 0x00327 , 0x00162 },
- { 0x00054 , 0x0032D , 0x01E70 },
- { 0x00054 , 0x00331 , 0x01E6E },
- { 0x00055 , 0x00300 , 0x000D9 },
- { 0x00055 , 0x00301 , 0x000DA },
- { 0x00055 , 0x00302 , 0x000DB },
- { 0x00055 , 0x00303 , 0x00168 },
- { 0x00055 , 0x00304 , 0x0016A },
- { 0x00055 , 0x00306 , 0x0016C },
- { 0x00055 , 0x00308 , 0x000DC },
- { 0x00055 , 0x00309 , 0x01EE6 },
- { 0x00055 , 0x0030A , 0x0016E },
- { 0x00055 , 0x0030B , 0x00170 },
- { 0x00055 , 0x0030C , 0x001D3 },
- { 0x00055 , 0x0030F , 0x00214 },
- { 0x00055 , 0x00311 , 0x00216 },
- { 0x00055 , 0x0031B , 0x001AF },
- { 0x00055 , 0x00323 , 0x01EE4 },
- { 0x00055 , 0x00324 , 0x01E72 },
- { 0x00055 , 0x00328 , 0x00172 },
- { 0x00055 , 0x0032D , 0x01E76 },
- { 0x00055 , 0x00330 , 0x01E74 },
- { 0x00056 , 0x00303 , 0x01E7C },
- { 0x00056 , 0x00323 , 0x01E7E },
- { 0x00057 , 0x00300 , 0x01E80 },
- { 0x00057 , 0x00301 , 0x01E82 },
- { 0x00057 , 0x00302 , 0x00174 },
- { 0x00057 , 0x00307 , 0x01E86 },
- { 0x00057 , 0x00308 , 0x01E84 },
- { 0x00057 , 0x00323 , 0x01E88 },
- { 0x00058 , 0x00307 , 0x01E8A },
- { 0x00058 , 0x00308 , 0x01E8C },
- { 0x00059 , 0x00300 , 0x01EF2 },
- { 0x00059 , 0x00301 , 0x000DD },
- { 0x00059 , 0x00302 , 0x00176 },
- { 0x00059 , 0x00303 , 0x01EF8 },
- { 0x00059 , 0x00304 , 0x00232 },
- { 0x00059 , 0x00307 , 0x01E8E },
- { 0x00059 , 0x00308 , 0x00178 },
- { 0x00059 , 0x00309 , 0x01EF6 },
- { 0x00059 , 0x00323 , 0x01EF4 },
- { 0x0005A , 0x00301 , 0x00179 },
- { 0x0005A , 0x00302 , 0x01E90 },
- { 0x0005A , 0x00307 , 0x0017B },
- { 0x0005A , 0x0030C , 0x0017D },
- { 0x0005A , 0x00323 , 0x01E92 },
- { 0x0005A , 0x00331 , 0x01E94 },
- { 0x00061 , 0x00300 , 0x000E0 },
- { 0x00061 , 0x00301 , 0x000E1 },
- { 0x00061 , 0x00302 , 0x000E2 },
- { 0x00061 , 0x00303 , 0x000E3 },
- { 0x00061 , 0x00304 , 0x00101 },
- { 0x00061 , 0x00306 , 0x00103 },
- { 0x00061 , 0x00307 , 0x00227 },
- { 0x00061 , 0x00308 , 0x000E4 },
- { 0x00061 , 0x00309 , 0x01EA3 },
- { 0x00061 , 0x0030A , 0x000E5 },
- { 0x00061 , 0x0030C , 0x001CE },
- { 0x00061 , 0x0030F , 0x00201 },
- { 0x00061 , 0x00311 , 0x00203 },
- { 0x00061 , 0x00323 , 0x01EA1 },
- { 0x00061 , 0x00325 , 0x01E01 },
- { 0x00061 , 0x00328 , 0x00105 },
- { 0x00062 , 0x00307 , 0x01E03 },
- { 0x00062 , 0x00323 , 0x01E05 },
- { 0x00062 , 0x00331 , 0x01E07 },
- { 0x00063 , 0x00301 , 0x00107 },
- { 0x00063 , 0x00302 , 0x00109 },
- { 0x00063 , 0x00307 , 0x0010B },
- { 0x00063 , 0x0030C , 0x0010D },
- { 0x00063 , 0x00327 , 0x000E7 },
- { 0x00064 , 0x00307 , 0x01E0B },
- { 0x00064 , 0x0030C , 0x0010F },
- { 0x00064 , 0x00323 , 0x01E0D },
- { 0x00064 , 0x00327 , 0x01E11 },
- { 0x00064 , 0x0032D , 0x01E13 },
- { 0x00064 , 0x00331 , 0x01E0F },
- { 0x00065 , 0x00300 , 0x000E8 },
- { 0x00065 , 0x00301 , 0x000E9 },
- { 0x00065 , 0x00302 , 0x000EA },
- { 0x00065 , 0x00303 , 0x01EBD },
- { 0x00065 , 0x00304 , 0x00113 },
- { 0x00065 , 0x00306 , 0x00115 },
- { 0x00065 , 0x00307 , 0x00117 },
- { 0x00065 , 0x00308 , 0x000EB },
- { 0x00065 , 0x00309 , 0x01EBB },
- { 0x00065 , 0x0030C , 0x0011B },
- { 0x00065 , 0x0030F , 0x00205 },
- { 0x00065 , 0x00311 , 0x00207 },
- { 0x00065 , 0x00323 , 0x01EB9 },
- { 0x00065 , 0x00327 , 0x00229 },
- { 0x00065 , 0x00328 , 0x00119 },
- { 0x00065 , 0x0032D , 0x01E19 },
- { 0x00065 , 0x00330 , 0x01E1B },
- { 0x00066 , 0x00307 , 0x01E1F },
- { 0x00067 , 0x00301 , 0x001F5 },
- { 0x00067 , 0x00302 , 0x0011D },
- { 0x00067 , 0x00304 , 0x01E21 },
- { 0x00067 , 0x00306 , 0x0011F },
- { 0x00067 , 0x00307 , 0x00121 },
- { 0x00067 , 0x0030C , 0x001E7 },
- { 0x00067 , 0x00327 , 0x00123 },
- { 0x00068 , 0x00302 , 0x00125 },
- { 0x00068 , 0x00307 , 0x01E23 },
- { 0x00068 , 0x00308 , 0x01E27 },
- { 0x00068 , 0x0030C , 0x0021F },
- { 0x00068 , 0x00323 , 0x01E25 },
- { 0x00068 , 0x00327 , 0x01E29 },
- { 0x00068 , 0x0032E , 0x01E2B },
- { 0x00068 , 0x00331 , 0x01E96 },
- { 0x00069 , 0x00300 , 0x000EC },
- { 0x00069 , 0x00301 , 0x000ED },
- { 0x00069 , 0x00302 , 0x000EE },
- { 0x00069 , 0x00303 , 0x00129 },
- { 0x00069 , 0x00304 , 0x0012B },
- { 0x00069 , 0x00306 , 0x0012D },
- { 0x00069 , 0x00308 , 0x000EF },
- { 0x00069 , 0x00309 , 0x01EC9 },
- { 0x00069 , 0x0030C , 0x001D0 },
- { 0x00069 , 0x0030F , 0x00209 },
- { 0x00069 , 0x00311 , 0x0020B },
- { 0x00069 , 0x00323 , 0x01ECB },
- { 0x00069 , 0x00328 , 0x0012F },
- { 0x00069 , 0x00330 , 0x01E2D },
- { 0x0006A , 0x00302 , 0x00135 },
- { 0x0006A , 0x0030C , 0x001F0 },
- { 0x0006B , 0x00301 , 0x01E31 },
- { 0x0006B , 0x0030C , 0x001E9 },
- { 0x0006B , 0x00323 , 0x01E33 },
- { 0x0006B , 0x00327 , 0x00137 },
- { 0x0006B , 0x00331 , 0x01E35 },
- { 0x0006C , 0x00301 , 0x0013A },
- { 0x0006C , 0x0030C , 0x0013E },
- { 0x0006C , 0x00323 , 0x01E37 },
- { 0x0006C , 0x00327 , 0x0013C },
- { 0x0006C , 0x0032D , 0x01E3D },
- { 0x0006C , 0x00331 , 0x01E3B },
- { 0x0006D , 0x00301 , 0x01E3F },
- { 0x0006D , 0x00307 , 0x01E41 },
- { 0x0006D , 0x00323 , 0x01E43 },
- { 0x0006E , 0x00300 , 0x001F9 },
- { 0x0006E , 0x00301 , 0x00144 },
- { 0x0006E , 0x00303 , 0x000F1 },
- { 0x0006E , 0x00307 , 0x01E45 },
- { 0x0006E , 0x0030C , 0x00148 },
- { 0x0006E , 0x00323 , 0x01E47 },
- { 0x0006E , 0x00327 , 0x00146 },
- { 0x0006E , 0x0032D , 0x01E4B },
- { 0x0006E , 0x00331 , 0x01E49 },
- { 0x0006F , 0x00300 , 0x000F2 },
- { 0x0006F , 0x00301 , 0x000F3 },
- { 0x0006F , 0x00302 , 0x000F4 },
- { 0x0006F , 0x00303 , 0x000F5 },
- { 0x0006F , 0x00304 , 0x0014D },
- { 0x0006F , 0x00306 , 0x0014F },
- { 0x0006F , 0x00307 , 0x0022F },
- { 0x0006F , 0x00308 , 0x000F6 },
- { 0x0006F , 0x00309 , 0x01ECF },
- { 0x0006F , 0x0030B , 0x00151 },
- { 0x0006F , 0x0030C , 0x001D2 },
- { 0x0006F , 0x0030F , 0x0020D },
- { 0x0006F , 0x00311 , 0x0020F },
- { 0x0006F , 0x0031B , 0x001A1 },
- { 0x0006F , 0x00323 , 0x01ECD },
- { 0x0006F , 0x00328 , 0x001EB },
- { 0x00070 , 0x00301 , 0x01E55 },
- { 0x00070 , 0x00307 , 0x01E57 },
- { 0x00072 , 0x00301 , 0x00155 },
- { 0x00072 , 0x00307 , 0x01E59 },
- { 0x00072 , 0x0030C , 0x00159 },
- { 0x00072 , 0x0030F , 0x00211 },
- { 0x00072 , 0x00311 , 0x00213 },
- { 0x00072 , 0x00323 , 0x01E5B },
- { 0x00072 , 0x00327 , 0x00157 },
- { 0x00072 , 0x00331 , 0x01E5F },
- { 0x00073 , 0x00301 , 0x0015B },
- { 0x00073 , 0x00302 , 0x0015D },
- { 0x00073 , 0x00307 , 0x01E61 },
- { 0x00073 , 0x0030C , 0x00161 },
- { 0x00073 , 0x00323 , 0x01E63 },
- { 0x00073 , 0x00326 , 0x00219 },
- { 0x00073 , 0x00327 , 0x0015F },
- { 0x00074 , 0x00307 , 0x01E6B },
- { 0x00074 , 0x00308 , 0x01E97 },
- { 0x00074 , 0x0030C , 0x00165 },
- { 0x00074 , 0x00323 , 0x01E6D },
- { 0x00074 , 0x00326 , 0x0021B },
- { 0x00074 , 0x00327 , 0x00163 },
- { 0x00074 , 0x0032D , 0x01E71 },
- { 0x00074 , 0x00331 , 0x01E6F },
- { 0x00075 , 0x00300 , 0x000F9 },
- { 0x00075 , 0x00301 , 0x000FA },
- { 0x00075 , 0x00302 , 0x000FB },
- { 0x00075 , 0x00303 , 0x00169 },
- { 0x00075 , 0x00304 , 0x0016B },
- { 0x00075 , 0x00306 , 0x0016D },
- { 0x00075 , 0x00308 , 0x000FC },
- { 0x00075 , 0x00309 , 0x01EE7 },
- { 0x00075 , 0x0030A , 0x0016F },
- { 0x00075 , 0x0030B , 0x00171 },
- { 0x00075 , 0x0030C , 0x001D4 },
- { 0x00075 , 0x0030F , 0x00215 },
- { 0x00075 , 0x00311 , 0x00217 },
- { 0x00075 , 0x0031B , 0x001B0 },
- { 0x00075 , 0x00323 , 0x01EE5 },
- { 0x00075 , 0x00324 , 0x01E73 },
- { 0x00075 , 0x00328 , 0x00173 },
- { 0x00075 , 0x0032D , 0x01E77 },
- { 0x00075 , 0x00330 , 0x01E75 },
- { 0x00076 , 0x00303 , 0x01E7D },
- { 0x00076 , 0x00323 , 0x01E7F },
- { 0x00077 , 0x00300 , 0x01E81 },
- { 0x00077 , 0x00301 , 0x01E83 },
- { 0x00077 , 0x00302 , 0x00175 },
- { 0x00077 , 0x00307 , 0x01E87 },
- { 0x00077 , 0x00308 , 0x01E85 },
- { 0x00077 , 0x0030A , 0x01E98 },
- { 0x00077 , 0x00323 , 0x01E89 },
- { 0x00078 , 0x00307 , 0x01E8B },
- { 0x00078 , 0x00308 , 0x01E8D },
- { 0x00079 , 0x00300 , 0x01EF3 },
- { 0x00079 , 0x00301 , 0x000FD },
- { 0x00079 , 0x00302 , 0x00177 },
- { 0x00079 , 0x00303 , 0x01EF9 },
- { 0x00079 , 0x00304 , 0x00233 },
- { 0x00079 , 0x00307 , 0x01E8F },
- { 0x00079 , 0x00308 , 0x000FF },
- { 0x00079 , 0x00309 , 0x01EF7 },
- { 0x00079 , 0x0030A , 0x01E99 },
- { 0x00079 , 0x00323 , 0x01EF5 },
- { 0x0007A , 0x00301 , 0x0017A },
- { 0x0007A , 0x00302 , 0x01E91 },
- { 0x0007A , 0x00307 , 0x0017C },
- { 0x0007A , 0x0030C , 0x0017E },
- { 0x0007A , 0x00323 , 0x01E93 },
- { 0x0007A , 0x00331 , 0x01E95 },
- { 0x000A8 , 0x00300 , 0x01FED },
- { 0x000A8 , 0x00301 , 0x00385 },
- { 0x000A8 , 0x00342 , 0x01FC1 },
- { 0x000C2 , 0x00300 , 0x01EA6 },
- { 0x000C2 , 0x00301 , 0x01EA4 },
- { 0x000C2 , 0x00303 , 0x01EAA },
- { 0x000C2 , 0x00309 , 0x01EA8 },
- { 0x000C4 , 0x00304 , 0x001DE },
- { 0x000C5 , 0x00301 , 0x001FA },
- { 0x000C6 , 0x00301 , 0x001FC },
- { 0x000C6 , 0x00304 , 0x001E2 },
- { 0x000C7 , 0x00301 , 0x01E08 },
- { 0x000CA , 0x00300 , 0x01EC0 },
- { 0x000CA , 0x00301 , 0x01EBE },
- { 0x000CA , 0x00303 , 0x01EC4 },
- { 0x000CA , 0x00309 , 0x01EC2 },
- { 0x000CF , 0x00301 , 0x01E2E },
- { 0x000D4 , 0x00300 , 0x01ED2 },
- { 0x000D4 , 0x00301 , 0x01ED0 },
- { 0x000D4 , 0x00303 , 0x01ED6 },
- { 0x000D4 , 0x00309 , 0x01ED4 },
- { 0x000D5 , 0x00301 , 0x01E4C },
- { 0x000D5 , 0x00304 , 0x0022C },
- { 0x000D5 , 0x00308 , 0x01E4E },
- { 0x000D6 , 0x00304 , 0x0022A },
- { 0x000D8 , 0x00301 , 0x001FE },
- { 0x000DC , 0x00300 , 0x001DB },
- { 0x000DC , 0x00301 , 0x001D7 },
- { 0x000DC , 0x00304 , 0x001D5 },
- { 0x000DC , 0x0030C , 0x001D9 },
- { 0x000E2 , 0x00300 , 0x01EA7 },
- { 0x000E2 , 0x00301 , 0x01EA5 },
- { 0x000E2 , 0x00303 , 0x01EAB },
- { 0x000E2 , 0x00309 , 0x01EA9 },
- { 0x000E4 , 0x00304 , 0x001DF },
- { 0x000E5 , 0x00301 , 0x001FB },
- { 0x000E6 , 0x00301 , 0x001FD },
- { 0x000E6 , 0x00304 , 0x001E3 },
- { 0x000E7 , 0x00301 , 0x01E09 },
- { 0x000EA , 0x00300 , 0x01EC1 },
- { 0x000EA , 0x00301 , 0x01EBF },
- { 0x000EA , 0x00303 , 0x01EC5 },
- { 0x000EA , 0x00309 , 0x01EC3 },
- { 0x000EF , 0x00301 , 0x01E2F },
- { 0x000F4 , 0x00300 , 0x01ED3 },
- { 0x000F4 , 0x00301 , 0x01ED1 },
- { 0x000F4 , 0x00303 , 0x01ED7 },
- { 0x000F4 , 0x00309 , 0x01ED5 },
- { 0x000F5 , 0x00301 , 0x01E4D },
- { 0x000F5 , 0x00304 , 0x0022D },
- { 0x000F5 , 0x00308 , 0x01E4F },
- { 0x000F6 , 0x00304 , 0x0022B },
- { 0x000F8 , 0x00301 , 0x001FF },
- { 0x000FC , 0x00300 , 0x001DC },
- { 0x000FC , 0x00301 , 0x001D8 },
- { 0x000FC , 0x00304 , 0x001D6 },
- { 0x000FC , 0x0030C , 0x001DA },
- { 0x00102 , 0x00300 , 0x01EB0 },
- { 0x00102 , 0x00301 , 0x01EAE },
- { 0x00102 , 0x00303 , 0x01EB4 },
- { 0x00102 , 0x00309 , 0x01EB2 },
- { 0x00103 , 0x00300 , 0x01EB1 },
- { 0x00103 , 0x00301 , 0x01EAF },
- { 0x00103 , 0x00303 , 0x01EB5 },
- { 0x00103 , 0x00309 , 0x01EB3 },
- { 0x00112 , 0x00300 , 0x01E14 },
- { 0x00112 , 0x00301 , 0x01E16 },
- { 0x00113 , 0x00300 , 0x01E15 },
- { 0x00113 , 0x00301 , 0x01E17 },
- { 0x0014C , 0x00300 , 0x01E50 },
- { 0x0014C , 0x00301 , 0x01E52 },
- { 0x0014D , 0x00300 , 0x01E51 },
- { 0x0014D , 0x00301 , 0x01E53 },
- { 0x0015A , 0x00307 , 0x01E64 },
- { 0x0015B , 0x00307 , 0x01E65 },
- { 0x00160 , 0x00307 , 0x01E66 },
- { 0x00161 , 0x00307 , 0x01E67 },
- { 0x00168 , 0x00301 , 0x01E78 },
- { 0x00169 , 0x00301 , 0x01E79 },
- { 0x0016A , 0x00308 , 0x01E7A },
- { 0x0016B , 0x00308 , 0x01E7B },
- { 0x0017F , 0x00307 , 0x01E9B },
- { 0x001A0 , 0x00300 , 0x01EDC },
- { 0x001A0 , 0x00301 , 0x01EDA },
- { 0x001A0 , 0x00303 , 0x01EE0 },
- { 0x001A0 , 0x00309 , 0x01EDE },
- { 0x001A0 , 0x00323 , 0x01EE2 },
- { 0x001A1 , 0x00300 , 0x01EDD },
- { 0x001A1 , 0x00301 , 0x01EDB },
- { 0x001A1 , 0x00303 , 0x01EE1 },
- { 0x001A1 , 0x00309 , 0x01EDF },
- { 0x001A1 , 0x00323 , 0x01EE3 },
- { 0x001AF , 0x00300 , 0x01EEA },
- { 0x001AF , 0x00301 , 0x01EE8 },
- { 0x001AF , 0x00303 , 0x01EEE },
- { 0x001AF , 0x00309 , 0x01EEC },
- { 0x001AF , 0x00323 , 0x01EF0 },
- { 0x001B0 , 0x00300 , 0x01EEB },
- { 0x001B0 , 0x00301 , 0x01EE9 },
- { 0x001B0 , 0x00303 , 0x01EEF },
- { 0x001B0 , 0x00309 , 0x01EED },
- { 0x001B0 , 0x00323 , 0x01EF1 },
- { 0x001B7 , 0x0030C , 0x001EE },
- { 0x001EA , 0x00304 , 0x001EC },
- { 0x001EB , 0x00304 , 0x001ED },
- { 0x00226 , 0x00304 , 0x001E0 },
- { 0x00227 , 0x00304 , 0x001E1 },
- { 0x00228 , 0x00306 , 0x01E1C },
- { 0x00229 , 0x00306 , 0x01E1D },
- { 0x0022E , 0x00304 , 0x00230 },
- { 0x0022F , 0x00304 , 0x00231 },
- { 0x00292 , 0x0030C , 0x001EF },
- { 0x00391 , 0x00300 , 0x01FBA },
- { 0x00391 , 0x00301 , 0x00386 },
- { 0x00391 , 0x00304 , 0x01FB9 },
- { 0x00391 , 0x00306 , 0x01FB8 },
- { 0x00391 , 0x00313 , 0x01F08 },
- { 0x00391 , 0x00314 , 0x01F09 },
- { 0x00391 , 0x00345 , 0x01FBC },
- { 0x00395 , 0x00300 , 0x01FC8 },
- { 0x00395 , 0x00301 , 0x00388 },
- { 0x00395 , 0x00313 , 0x01F18 },
- { 0x00395 , 0x00314 , 0x01F19 },
- { 0x00397 , 0x00300 , 0x01FCA },
- { 0x00397 , 0x00301 , 0x00389 },
- { 0x00397 , 0x00313 , 0x01F28 },
- { 0x00397 , 0x00314 , 0x01F29 },
- { 0x00397 , 0x00345 , 0x01FCC },
- { 0x00399 , 0x00300 , 0x01FDA },
- { 0x00399 , 0x00301 , 0x0038A },
- { 0x00399 , 0x00304 , 0x01FD9 },
- { 0x00399 , 0x00306 , 0x01FD8 },
- { 0x00399 , 0x00308 , 0x003AA },
- { 0x00399 , 0x00313 , 0x01F38 },
- { 0x00399 , 0x00314 , 0x01F39 },
- { 0x0039F , 0x00300 , 0x01FF8 },
- { 0x0039F , 0x00301 , 0x0038C },
- { 0x0039F , 0x00313 , 0x01F48 },
- { 0x0039F , 0x00314 , 0x01F49 },
- { 0x003A1 , 0x00314 , 0x01FEC },
- { 0x003A5 , 0x00300 , 0x01FEA },
- { 0x003A5 , 0x00301 , 0x0038E },
- { 0x003A5 , 0x00304 , 0x01FE9 },
- { 0x003A5 , 0x00306 , 0x01FE8 },
- { 0x003A5 , 0x00308 , 0x003AB },
- { 0x003A5 , 0x00314 , 0x01F59 },
- { 0x003A9 , 0x00300 , 0x01FFA },
- { 0x003A9 , 0x00301 , 0x0038F },
- { 0x003A9 , 0x00313 , 0x01F68 },
- { 0x003A9 , 0x00314 , 0x01F69 },
- { 0x003A9 , 0x00345 , 0x01FFC },
- { 0x003AC , 0x00345 , 0x01FB4 },
- { 0x003AE , 0x00345 , 0x01FC4 },
- { 0x003B1 , 0x00300 , 0x01F70 },
- { 0x003B1 , 0x00301 , 0x003AC },
- { 0x003B1 , 0x00304 , 0x01FB1 },
- { 0x003B1 , 0x00306 , 0x01FB0 },
- { 0x003B1 , 0x00313 , 0x01F00 },
- { 0x003B1 , 0x00314 , 0x01F01 },
- { 0x003B1 , 0x00342 , 0x01FB6 },
- { 0x003B1 , 0x00345 , 0x01FB3 },
- { 0x003B5 , 0x00300 , 0x01F72 },
- { 0x003B5 , 0x00301 , 0x003AD },
- { 0x003B5 , 0x00313 , 0x01F10 },
- { 0x003B5 , 0x00314 , 0x01F11 },
- { 0x003B7 , 0x00300 , 0x01F74 },
- { 0x003B7 , 0x00301 , 0x003AE },
- { 0x003B7 , 0x00313 , 0x01F20 },
- { 0x003B7 , 0x00314 , 0x01F21 },
- { 0x003B7 , 0x00342 , 0x01FC6 },
- { 0x003B7 , 0x00345 , 0x01FC3 },
- { 0x003B9 , 0x00300 , 0x01F76 },
- { 0x003B9 , 0x00301 , 0x003AF },
- { 0x003B9 , 0x00304 , 0x01FD1 },
- { 0x003B9 , 0x00306 , 0x01FD0 },
- { 0x003B9 , 0x00308 , 0x003CA },
- { 0x003B9 , 0x00313 , 0x01F30 },
- { 0x003B9 , 0x00314 , 0x01F31 },
- { 0x003B9 , 0x00342 , 0x01FD6 },
- { 0x003BF , 0x00300 , 0x01F78 },
- { 0x003BF , 0x00301 , 0x003CC },
- { 0x003BF , 0x00313 , 0x01F40 },
- { 0x003BF , 0x00314 , 0x01F41 },
- { 0x003C1 , 0x00313 , 0x01FE4 },
- { 0x003C1 , 0x00314 , 0x01FE5 },
- { 0x003C5 , 0x00300 , 0x01F7A },
- { 0x003C5 , 0x00301 , 0x003CD },
- { 0x003C5 , 0x00304 , 0x01FE1 },
- { 0x003C5 , 0x00306 , 0x01FE0 },
- { 0x003C5 , 0x00308 , 0x003CB },
- { 0x003C5 , 0x00313 , 0x01F50 },
- { 0x003C5 , 0x00314 , 0x01F51 },
- { 0x003C5 , 0x00342 , 0x01FE6 },
- { 0x003C9 , 0x00300 , 0x01F7C },
- { 0x003C9 , 0x00301 , 0x003CE },
- { 0x003C9 , 0x00313 , 0x01F60 },
- { 0x003C9 , 0x00314 , 0x01F61 },
- { 0x003C9 , 0x00342 , 0x01FF6 },
- { 0x003C9 , 0x00345 , 0x01FF3 },
- { 0x003CA , 0x00300 , 0x01FD2 },
- { 0x003CA , 0x00301 , 0x00390 },
- { 0x003CA , 0x00342 , 0x01FD7 },
- { 0x003CB , 0x00300 , 0x01FE2 },
- { 0x003CB , 0x00301 , 0x003B0 },
- { 0x003CB , 0x00342 , 0x01FE7 },
- { 0x003CE , 0x00345 , 0x01FF4 },
- { 0x003D2 , 0x00301 , 0x003D3 },
- { 0x003D2 , 0x00308 , 0x003D4 },
- { 0x00406 , 0x00308 , 0x00407 },
- { 0x00410 , 0x00306 , 0x004D0 },
- { 0x00410 , 0x00308 , 0x004D2 },
- { 0x00413 , 0x00301 , 0x00403 },
- { 0x00415 , 0x00300 , 0x00400 },
- { 0x00415 , 0x00306 , 0x004D6 },
- { 0x00415 , 0x00308 , 0x00401 },
- { 0x00416 , 0x00306 , 0x004C1 },
- { 0x00416 , 0x00308 , 0x004DC },
- { 0x00417 , 0x00308 , 0x004DE },
- { 0x00418 , 0x00300 , 0x0040D },
- { 0x00418 , 0x00304 , 0x004E2 },
- { 0x00418 , 0x00306 , 0x00419 },
- { 0x00418 , 0x00308 , 0x004E4 },
- { 0x0041A , 0x00301 , 0x0040C },
- { 0x0041E , 0x00308 , 0x004E6 },
- { 0x00423 , 0x00304 , 0x004EE },
- { 0x00423 , 0x00306 , 0x0040E },
- { 0x00423 , 0x00308 , 0x004F0 },
- { 0x00423 , 0x0030B , 0x004F2 },
- { 0x00427 , 0x00308 , 0x004F4 },
- { 0x0042B , 0x00308 , 0x004F8 },
- { 0x0042D , 0x00308 , 0x004EC },
- { 0x00430 , 0x00306 , 0x004D1 },
- { 0x00430 , 0x00308 , 0x004D3 },
- { 0x00433 , 0x00301 , 0x00453 },
- { 0x00435 , 0x00300 , 0x00450 },
- { 0x00435 , 0x00306 , 0x004D7 },
- { 0x00435 , 0x00308 , 0x00451 },
- { 0x00436 , 0x00306 , 0x004C2 },
- { 0x00436 , 0x00308 , 0x004DD },
- { 0x00437 , 0x00308 , 0x004DF },
- { 0x00438 , 0x00300 , 0x0045D },
- { 0x00438 , 0x00304 , 0x004E3 },
- { 0x00438 , 0x00306 , 0x00439 },
- { 0x00438 , 0x00308 , 0x004E5 },
- { 0x0043A , 0x00301 , 0x0045C },
- { 0x0043E , 0x00308 , 0x004E7 },
- { 0x00443 , 0x00304 , 0x004EF },
- { 0x00443 , 0x00306 , 0x0045E },
- { 0x00443 , 0x00308 , 0x004F1 },
- { 0x00443 , 0x0030B , 0x004F3 },
- { 0x00447 , 0x00308 , 0x004F5 },
- { 0x0044B , 0x00308 , 0x004F9 },
- { 0x0044D , 0x00308 , 0x004ED },
- { 0x00456 , 0x00308 , 0x00457 },
- { 0x00474 , 0x0030F , 0x00476 },
- { 0x00475 , 0x0030F , 0x00477 },
- { 0x004D8 , 0x00308 , 0x004DA },
- { 0x004D9 , 0x00308 , 0x004DB },
- { 0x004E8 , 0x00308 , 0x004EA },
- { 0x004E9 , 0x00308 , 0x004EB },
- { 0x00627 , 0x00653 , 0x00622 },
- { 0x00627 , 0x00654 , 0x00623 },
- { 0x00627 , 0x00655 , 0x00625 },
- { 0x00648 , 0x00654 , 0x00624 },
- { 0x0064A , 0x00654 , 0x00626 },
- { 0x006C1 , 0x00654 , 0x006C2 },
- { 0x006D2 , 0x00654 , 0x006D3 },
- { 0x006D5 , 0x00654 , 0x006C0 },
- { 0x00928 , 0x0093C , 0x00929 },
- { 0x00930 , 0x0093C , 0x00931 },
- { 0x00933 , 0x0093C , 0x00934 },
- { 0x009C7 , 0x009BE , 0x009CB },
- { 0x009C7 , 0x009D7 , 0x009CC },
- { 0x00B47 , 0x00B3E , 0x00B4B },
- { 0x00B47 , 0x00B56 , 0x00B48 },
- { 0x00B47 , 0x00B57 , 0x00B4C },
- { 0x00B92 , 0x00BD7 , 0x00B94 },
- { 0x00BC6 , 0x00BBE , 0x00BCA },
- { 0x00BC6 , 0x00BD7 , 0x00BCC },
- { 0x00BC7 , 0x00BBE , 0x00BCB },
- { 0x00C46 , 0x00C56 , 0x00C48 },
- { 0x00CBF , 0x00CD5 , 0x00CC0 },
- { 0x00CC6 , 0x00CC2 , 0x00CCA },
- { 0x00CC6 , 0x00CD5 , 0x00CC7 },
- { 0x00CC6 , 0x00CD6 , 0x00CC8 },
- { 0x00CCA , 0x00CD5 , 0x00CCB },
- { 0x00D46 , 0x00D3E , 0x00D4A },
- { 0x00D46 , 0x00D57 , 0x00D4C },
- { 0x00D47 , 0x00D3E , 0x00D4B },
- { 0x00DD9 , 0x00DCA , 0x00DDA },
- { 0x00DD9 , 0x00DCF , 0x00DDC },
- { 0x00DD9 , 0x00DDF , 0x00DDE },
- { 0x00DDC , 0x00DCA , 0x00DDD },
- { 0x01025 , 0x0102E , 0x01026 },
- { 0x01B05 , 0x01B35 , 0x01B06 },
- { 0x01B07 , 0x01B35 , 0x01B08 },
- { 0x01B09 , 0x01B35 , 0x01B0A },
- { 0x01B0B , 0x01B35 , 0x01B0C },
- { 0x01B0D , 0x01B35 , 0x01B0E },
- { 0x01B11 , 0x01B35 , 0x01B12 },
- { 0x01B3A , 0x01B35 , 0x01B3B },
- { 0x01B3C , 0x01B35 , 0x01B3D },
- { 0x01B3E , 0x01B35 , 0x01B40 },
- { 0x01B3F , 0x01B35 , 0x01B41 },
- { 0x01B42 , 0x01B35 , 0x01B43 },
- { 0x01E36 , 0x00304 , 0x01E38 },
- { 0x01E37 , 0x00304 , 0x01E39 },
- { 0x01E5A , 0x00304 , 0x01E5C },
- { 0x01E5B , 0x00304 , 0x01E5D },
- { 0x01E62 , 0x00307 , 0x01E68 },
- { 0x01E63 , 0x00307 , 0x01E69 },
- { 0x01EA0 , 0x00302 , 0x01EAC },
- { 0x01EA0 , 0x00306 , 0x01EB6 },
- { 0x01EA1 , 0x00302 , 0x01EAD },
- { 0x01EA1 , 0x00306 , 0x01EB7 },
- { 0x01EB8 , 0x00302 , 0x01EC6 },
- { 0x01EB9 , 0x00302 , 0x01EC7 },
- { 0x01ECC , 0x00302 , 0x01ED8 },
- { 0x01ECD , 0x00302 , 0x01ED9 },
- { 0x01F00 , 0x00300 , 0x01F02 },
- { 0x01F00 , 0x00301 , 0x01F04 },
- { 0x01F00 , 0x00342 , 0x01F06 },
- { 0x01F00 , 0x00345 , 0x01F80 },
- { 0x01F01 , 0x00300 , 0x01F03 },
- { 0x01F01 , 0x00301 , 0x01F05 },
- { 0x01F01 , 0x00342 , 0x01F07 },
- { 0x01F01 , 0x00345 , 0x01F81 },
- { 0x01F02 , 0x00345 , 0x01F82 },
- { 0x01F03 , 0x00345 , 0x01F83 },
- { 0x01F04 , 0x00345 , 0x01F84 },
- { 0x01F05 , 0x00345 , 0x01F85 },
- { 0x01F06 , 0x00345 , 0x01F86 },
- { 0x01F07 , 0x00345 , 0x01F87 },
- { 0x01F08 , 0x00300 , 0x01F0A },
- { 0x01F08 , 0x00301 , 0x01F0C },
- { 0x01F08 , 0x00342 , 0x01F0E },
- { 0x01F08 , 0x00345 , 0x01F88 },
- { 0x01F09 , 0x00300 , 0x01F0B },
- { 0x01F09 , 0x00301 , 0x01F0D },
- { 0x01F09 , 0x00342 , 0x01F0F },
- { 0x01F09 , 0x00345 , 0x01F89 },
- { 0x01F0A , 0x00345 , 0x01F8A },
- { 0x01F0B , 0x00345 , 0x01F8B },
- { 0x01F0C , 0x00345 , 0x01F8C },
- { 0x01F0D , 0x00345 , 0x01F8D },
- { 0x01F0E , 0x00345 , 0x01F8E },
- { 0x01F0F , 0x00345 , 0x01F8F },
- { 0x01F10 , 0x00300 , 0x01F12 },
- { 0x01F10 , 0x00301 , 0x01F14 },
- { 0x01F11 , 0x00300 , 0x01F13 },
- { 0x01F11 , 0x00301 , 0x01F15 },
- { 0x01F18 , 0x00300 , 0x01F1A },
- { 0x01F18 , 0x00301 , 0x01F1C },
- { 0x01F19 , 0x00300 , 0x01F1B },
- { 0x01F19 , 0x00301 , 0x01F1D },
- { 0x01F20 , 0x00300 , 0x01F22 },
- { 0x01F20 , 0x00301 , 0x01F24 },
- { 0x01F20 , 0x00342 , 0x01F26 },
- { 0x01F20 , 0x00345 , 0x01F90 },
- { 0x01F21 , 0x00300 , 0x01F23 },
- { 0x01F21 , 0x00301 , 0x01F25 },
- { 0x01F21 , 0x00342 , 0x01F27 },
- { 0x01F21 , 0x00345 , 0x01F91 },
- { 0x01F22 , 0x00345 , 0x01F92 },
- { 0x01F23 , 0x00345 , 0x01F93 },
- { 0x01F24 , 0x00345 , 0x01F94 },
- { 0x01F25 , 0x00345 , 0x01F95 },
- { 0x01F26 , 0x00345 , 0x01F96 },
- { 0x01F27 , 0x00345 , 0x01F97 },
- { 0x01F28 , 0x00300 , 0x01F2A },
- { 0x01F28 , 0x00301 , 0x01F2C },
- { 0x01F28 , 0x00342 , 0x01F2E },
- { 0x01F28 , 0x00345 , 0x01F98 },
- { 0x01F29 , 0x00300 , 0x01F2B },
- { 0x01F29 , 0x00301 , 0x01F2D },
- { 0x01F29 , 0x00342 , 0x01F2F },
- { 0x01F29 , 0x00345 , 0x01F99 },
- { 0x01F2A , 0x00345 , 0x01F9A },
- { 0x01F2B , 0x00345 , 0x01F9B },
- { 0x01F2C , 0x00345 , 0x01F9C },
- { 0x01F2D , 0x00345 , 0x01F9D },
- { 0x01F2E , 0x00345 , 0x01F9E },
- { 0x01F2F , 0x00345 , 0x01F9F },
- { 0x01F30 , 0x00300 , 0x01F32 },
- { 0x01F30 , 0x00301 , 0x01F34 },
- { 0x01F30 , 0x00342 , 0x01F36 },
- { 0x01F31 , 0x00300 , 0x01F33 },
- { 0x01F31 , 0x00301 , 0x01F35 },
- { 0x01F31 , 0x00342 , 0x01F37 },
- { 0x01F38 , 0x00300 , 0x01F3A },
- { 0x01F38 , 0x00301 , 0x01F3C },
- { 0x01F38 , 0x00342 , 0x01F3E },
- { 0x01F39 , 0x00300 , 0x01F3B },
- { 0x01F39 , 0x00301 , 0x01F3D },
- { 0x01F39 , 0x00342 , 0x01F3F },
- { 0x01F40 , 0x00300 , 0x01F42 },
- { 0x01F40 , 0x00301 , 0x01F44 },
- { 0x01F41 , 0x00300 , 0x01F43 },
- { 0x01F41 , 0x00301 , 0x01F45 },
- { 0x01F48 , 0x00300 , 0x01F4A },
- { 0x01F48 , 0x00301 , 0x01F4C },
- { 0x01F49 , 0x00300 , 0x01F4B },
- { 0x01F49 , 0x00301 , 0x01F4D },
- { 0x01F50 , 0x00300 , 0x01F52 },
- { 0x01F50 , 0x00301 , 0x01F54 },
- { 0x01F50 , 0x00342 , 0x01F56 },
- { 0x01F51 , 0x00300 , 0x01F53 },
- { 0x01F51 , 0x00301 , 0x01F55 },
- { 0x01F51 , 0x00342 , 0x01F57 },
- { 0x01F59 , 0x00300 , 0x01F5B },
- { 0x01F59 , 0x00301 , 0x01F5D },
- { 0x01F59 , 0x00342 , 0x01F5F },
- { 0x01F60 , 0x00300 , 0x01F62 },
- { 0x01F60 , 0x00301 , 0x01F64 },
- { 0x01F60 , 0x00342 , 0x01F66 },
- { 0x01F60 , 0x00345 , 0x01FA0 },
- { 0x01F61 , 0x00300 , 0x01F63 },
- { 0x01F61 , 0x00301 , 0x01F65 },
- { 0x01F61 , 0x00342 , 0x01F67 },
- { 0x01F61 , 0x00345 , 0x01FA1 },
- { 0x01F62 , 0x00345 , 0x01FA2 },
- { 0x01F63 , 0x00345 , 0x01FA3 },
- { 0x01F64 , 0x00345 , 0x01FA4 },
- { 0x01F65 , 0x00345 , 0x01FA5 },
- { 0x01F66 , 0x00345 , 0x01FA6 },
- { 0x01F67 , 0x00345 , 0x01FA7 },
- { 0x01F68 , 0x00300 , 0x01F6A },
- { 0x01F68 , 0x00301 , 0x01F6C },
- { 0x01F68 , 0x00342 , 0x01F6E },
- { 0x01F68 , 0x00345 , 0x01FA8 },
- { 0x01F69 , 0x00300 , 0x01F6B },
- { 0x01F69 , 0x00301 , 0x01F6D },
- { 0x01F69 , 0x00342 , 0x01F6F },
- { 0x01F69 , 0x00345 , 0x01FA9 },
- { 0x01F6A , 0x00345 , 0x01FAA },
- { 0x01F6B , 0x00345 , 0x01FAB },
- { 0x01F6C , 0x00345 , 0x01FAC },
- { 0x01F6D , 0x00345 , 0x01FAD },
- { 0x01F6E , 0x00345 , 0x01FAE },
- { 0x01F6F , 0x00345 , 0x01FAF },
- { 0x01F70 , 0x00345 , 0x01FB2 },
- { 0x01F74 , 0x00345 , 0x01FC2 },
- { 0x01F7C , 0x00345 , 0x01FF2 },
- { 0x01FB6 , 0x00345 , 0x01FB7 },
- { 0x01FBF , 0x00300 , 0x01FCD },
- { 0x01FBF , 0x00301 , 0x01FCE },
- { 0x01FBF , 0x00342 , 0x01FCF },
- { 0x01FC6 , 0x00345 , 0x01FC7 },
- { 0x01FF6 , 0x00345 , 0x01FF7 },
- { 0x01FFE , 0x00300 , 0x01FDD },
- { 0x01FFE , 0x00301 , 0x01FDE },
- { 0x01FFE , 0x00342 , 0x01FDF },
- { 0x02190 , 0x00338 , 0x0219A },
- { 0x02192 , 0x00338 , 0x0219B },
- { 0x02194 , 0x00338 , 0x021AE },
- { 0x021D0 , 0x00338 , 0x021CD },
- { 0x021D2 , 0x00338 , 0x021CF },
- { 0x021D4 , 0x00338 , 0x021CE },
- { 0x02203 , 0x00338 , 0x02204 },
- { 0x02208 , 0x00338 , 0x02209 },
- { 0x0220B , 0x00338 , 0x0220C },
- { 0x02223 , 0x00338 , 0x02224 },
- { 0x02225 , 0x00338 , 0x02226 },
- { 0x0223C , 0x00338 , 0x02241 },
- { 0x02243 , 0x00338 , 0x02244 },
- { 0x02245 , 0x00338 , 0x02247 },
- { 0x02248 , 0x00338 , 0x02249 },
- { 0x0224D , 0x00338 , 0x0226D },
- { 0x02261 , 0x00338 , 0x02262 },
- { 0x02264 , 0x00338 , 0x02270 },
- { 0x02265 , 0x00338 , 0x02271 },
- { 0x02272 , 0x00338 , 0x02274 },
- { 0x02273 , 0x00338 , 0x02275 },
- { 0x02276 , 0x00338 , 0x02278 },
- { 0x02277 , 0x00338 , 0x02279 },
- { 0x0227A , 0x00338 , 0x02280 },
- { 0x0227B , 0x00338 , 0x02281 },
- { 0x0227C , 0x00338 , 0x022E0 },
- { 0x0227D , 0x00338 , 0x022E1 },
- { 0x02282 , 0x00338 , 0x02284 },
- { 0x02283 , 0x00338 , 0x02285 },
- { 0x02286 , 0x00338 , 0x02288 },
- { 0x02287 , 0x00338 , 0x02289 },
- { 0x02291 , 0x00338 , 0x022E2 },
- { 0x02292 , 0x00338 , 0x022E3 },
- { 0x022A2 , 0x00338 , 0x022AC },
- { 0x022A8 , 0x00338 , 0x022AD },
- { 0x022A9 , 0x00338 , 0x022AE },
- { 0x022AB , 0x00338 , 0x022AF },
- { 0x022B2 , 0x00338 , 0x022EA },
- { 0x022B3 , 0x00338 , 0x022EB },
- { 0x022B4 , 0x00338 , 0x022EC },
- { 0x022B5 , 0x00338 , 0x022ED },
- { 0x03046 , 0x03099 , 0x03094 },
- { 0x0304B , 0x03099 , 0x0304C },
- { 0x0304D , 0x03099 , 0x0304E },
- { 0x0304F , 0x03099 , 0x03050 },
- { 0x03051 , 0x03099 , 0x03052 },
- { 0x03053 , 0x03099 , 0x03054 },
- { 0x03055 , 0x03099 , 0x03056 },
- { 0x03057 , 0x03099 , 0x03058 },
- { 0x03059 , 0x03099 , 0x0305A },
- { 0x0305B , 0x03099 , 0x0305C },
- { 0x0305D , 0x03099 , 0x0305E },
- { 0x0305F , 0x03099 , 0x03060 },
- { 0x03061 , 0x03099 , 0x03062 },
- { 0x03064 , 0x03099 , 0x03065 },
- { 0x03066 , 0x03099 , 0x03067 },
- { 0x03068 , 0x03099 , 0x03069 },
- { 0x0306F , 0x03099 , 0x03070 },
- { 0x0306F , 0x0309A , 0x03071 },
- { 0x03072 , 0x03099 , 0x03073 },
- { 0x03072 , 0x0309A , 0x03074 },
- { 0x03075 , 0x03099 , 0x03076 },
- { 0x03075 , 0x0309A , 0x03077 },
- { 0x03078 , 0x03099 , 0x03079 },
- { 0x03078 , 0x0309A , 0x0307A },
- { 0x0307B , 0x03099 , 0x0307C },
- { 0x0307B , 0x0309A , 0x0307D },
- { 0x0309D , 0x03099 , 0x0309E },
- { 0x030A6 , 0x03099 , 0x030F4 },
- { 0x030AB , 0x03099 , 0x030AC },
- { 0x030AD , 0x03099 , 0x030AE },
- { 0x030AF , 0x03099 , 0x030B0 },
- { 0x030B1 , 0x03099 , 0x030B2 },
- { 0x030B3 , 0x03099 , 0x030B4 },
- { 0x030B5 , 0x03099 , 0x030B6 },
- { 0x030B7 , 0x03099 , 0x030B8 },
- { 0x030B9 , 0x03099 , 0x030BA },
- { 0x030BB , 0x03099 , 0x030BC },
- { 0x030BD , 0x03099 , 0x030BE },
- { 0x030BF , 0x03099 , 0x030C0 },
- { 0x030C1 , 0x03099 , 0x030C2 },
- { 0x030C4 , 0x03099 , 0x030C5 },
- { 0x030C6 , 0x03099 , 0x030C7 },
- { 0x030C8 , 0x03099 , 0x030C9 },
- { 0x030CF , 0x03099 , 0x030D0 },
- { 0x030CF , 0x0309A , 0x030D1 },
- { 0x030D2 , 0x03099 , 0x030D3 },
- { 0x030D2 , 0x0309A , 0x030D4 },
- { 0x030D5 , 0x03099 , 0x030D6 },
- { 0x030D5 , 0x0309A , 0x030D7 },
- { 0x030D8 , 0x03099 , 0x030D9 },
- { 0x030D8 , 0x0309A , 0x030DA },
- { 0x030DB , 0x03099 , 0x030DC },
- { 0x030DB , 0x0309A , 0x030DD },
- { 0x030EF , 0x03099 , 0x030F7 },
- { 0x030F0 , 0x03099 , 0x030F8 },
- { 0x030F1 , 0x03099 , 0x030F9 },
- { 0x030F2 , 0x03099 , 0x030FA },
- { 0x030FD , 0x03099 , 0x030FE },
- { 0x11099 , 0x110BA , 0x1109A },
- { 0x1109B , 0x110BA , 0x1109C },
- { 0x110A5 , 0x110BA , 0x110AB },
-};
-
-#define CANONICAL_CLASS_MIN 0x0300
-#define CANONICAL_CLASS_MAX 0x1D244
-
-#define IS_DECOMPOSABLE_BLOCK(uc) \
- (((uc)>>8) <= 0x1D2 && u_decomposable_blocks[(uc)>>8])
-static const char u_decomposable_blocks[0x1D2+1] = {
- 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,1,1,1,1,1,1,1,0,0,
- 1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
- 0,0,0,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,1,0,
- 0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,
-};
-
-/* Get Canonical Combining Class(CCC). */
-#define CCC(uc) \
- (((uc) > 0x1D244)?0:\
- ccc_val[ccc_val_index[ccc_index[(uc)>>8]][((uc)>>4)&0x0F]][(uc)&0x0F])
-
-/* The table of the value of Canonical Combining Class */
-static const unsigned char ccc_val[][16] = {
- /* idx=0: XXXX0 - XXXXF */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=1: 00300 - 0030F */
- {230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 },
- /* idx=2: 00310 - 0031F */
- {230, 230, 230, 230, 230, 232, 220, 220, 220, 220, 232, 216, 220, 220, 220, 220 },
- /* idx=3: 00320 - 0032F */
- {220, 202, 202, 220, 220, 220, 220, 202, 202, 220, 220, 220, 220, 220, 220, 220 },
- /* idx=4: 00330 - 0033F */
- {220, 220, 220, 220, 1, 1, 1, 1, 1, 220, 220, 220, 220, 230, 230, 230 },
- /* idx=5: 00340 - 0034F */
- {230, 230, 230, 230, 230, 240, 230, 220, 220, 220, 230, 230, 230, 220, 220, 0 },
- /* idx=6: 00350 - 0035F */
- {230, 230, 230, 220, 220, 220, 220, 230, 232, 220, 220, 230, 233, 234, 234, 233 },
- /* idx=7: 00360 - 0036F */
- {234, 234, 233, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 },
- /* idx=8: 00480 - 0048F */
- {0, 0, 0, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=9: 00590 - 0059F */
- {0, 220, 230, 230, 230, 230, 220, 230, 230, 230, 222, 220, 230, 230, 230, 230 },
- /* idx=10: 005A0 - 005AF */
- {230, 230, 220, 220, 220, 220, 220, 220, 230, 230, 220, 230, 230, 222, 228, 230 },
- /* idx=11: 005B0 - 005BF */
- {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23 },
- /* idx=12: 005C0 - 005CF */
- {0, 24, 25, 0, 230, 220, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=13: 00610 - 0061F */
- {230, 230, 230, 230, 230, 230, 230, 230, 30, 31, 32, 0, 0, 0, 0, 0 },
- /* idx=14: 00640 - 0064F */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, 30, 31 },
- /* idx=15: 00650 - 0065F */
- {32, 33, 34, 230, 230, 220, 220, 230, 230, 230, 230, 230, 220, 230, 230, 220 },
- /* idx=16: 00670 - 0067F */
- {35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=17: 006D0 - 006DF */
- {0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 0, 0, 230 },
- /* idx=18: 006E0 - 006EF */
- {230, 230, 230, 220, 230, 0, 0, 230, 230, 0, 220, 230, 230, 220, 0, 0 },
- /* idx=19: 00710 - 0071F */
- {0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=20: 00730 - 0073F */
- {230, 220, 230, 230, 220, 230, 230, 220, 220, 220, 230, 220, 220, 230, 220, 230 },
- /* idx=21: 00740 - 0074F */
- {230, 230, 220, 230, 220, 230, 220, 230, 220, 230, 230, 0, 0, 0, 0, 0 },
- /* idx=22: 007E0 - 007EF */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230 },
- /* idx=23: 007F0 - 007FF */
- {230, 230, 220, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=24: 00810 - 0081F */
- {0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0, 230, 230, 230, 230, 230 },
- /* idx=25: 00820 - 0082F */
- {230, 230, 230, 230, 0, 230, 230, 230, 0, 230, 230, 230, 230, 230, 0, 0 },
- /* idx=26: 00850 - 0085F */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 0, 0, 0, 0 },
- /* idx=27: 00930 - 0093F */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 },
- /* idx=28: 00940 - 0094F */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
- /* idx=29: 00950 - 0095F */
- {0, 230, 220, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=30: 009B0 - 009BF */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 },
- /* idx=31: 009C0 - 009CF */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
- /* idx=32: 00A30 - 00A3F */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 },
- /* idx=33: 00A40 - 00A4F */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
- /* idx=34: 00AB0 - 00ABF */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 },
- /* idx=35: 00AC0 - 00ACF */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
- /* idx=36: 00B30 - 00B3F */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 },
- /* idx=37: 00B40 - 00B4F */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
- /* idx=38: 00BC0 - 00BCF */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
- /* idx=39: 00C40 - 00C4F */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
- /* idx=40: 00C50 - 00C5F */
- {0, 0, 0, 0, 0, 84, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=41: 00CB0 - 00CBF */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 },
- /* idx=42: 00CC0 - 00CCF */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
- /* idx=43: 00D40 - 00D4F */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
- /* idx=44: 00DC0 - 00DCF */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0 },
- /* idx=45: 00E30 - 00E3F */
- {0, 0, 0, 0, 0, 0, 0, 0, 103, 103, 9, 0, 0, 0, 0, 0 },
- /* idx=46: 00E40 - 00E4F */
- {0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 0, 0, 0, 0 },
- /* idx=47: 00EB0 - 00EBF */
- {0, 0, 0, 0, 0, 0, 0, 0, 118, 118, 0, 0, 0, 0, 0, 0 },
- /* idx=48: 00EC0 - 00ECF */
- {0, 0, 0, 0, 0, 0, 0, 0, 122, 122, 122, 122, 0, 0, 0, 0 },
- /* idx=49: 00F10 - 00F1F */
- {0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 0, 0, 0, 0, 0, 0 },
- /* idx=50: 00F30 - 00F3F */
- {0, 0, 0, 0, 0, 220, 0, 220, 0, 216, 0, 0, 0, 0, 0, 0 },
- /* idx=51: 00F70 - 00F7F */
- {0, 129, 130, 0, 132, 0, 0, 0, 0, 0, 130, 130, 130, 130, 0, 0 },
- /* idx=52: 00F80 - 00F8F */
- {130, 0, 230, 230, 9, 0, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=53: 00FC0 - 00FCF */
- {0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=54: 01030 - 0103F */
- {0, 0, 0, 0, 0, 0, 0, 7, 0, 9, 9, 0, 0, 0, 0, 0 },
- /* idx=55: 01080 - 0108F */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0 },
- /* idx=56: 01350 - 0135F */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230 },
- /* idx=57: 01710 - 0171F */
- {0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=58: 01730 - 0173F */
- {0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=59: 017D0 - 017DF */
- {0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 0, 0 },
- /* idx=60: 018A0 - 018AF */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0 },
- /* idx=61: 01930 - 0193F */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 222, 230, 220, 0, 0, 0, 0 },
- /* idx=62: 01A10 - 01A1F */
- {0, 0, 0, 0, 0, 0, 0, 230, 220, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=63: 01A60 - 01A6F */
- {9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=64: 01A70 - 01A7F */
- {0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 230, 0, 0, 220 },
- /* idx=65: 01B30 - 01B3F */
- {0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=66: 01B40 - 01B4F */
- {0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=67: 01B60 - 01B6F */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 220, 230, 230, 230 },
- /* idx=68: 01B70 - 01B7F */
- {230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=69: 01BA0 - 01BAF */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0 },
- /* idx=70: 01BE0 - 01BEF */
- {0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=71: 01BF0 - 01BFF */
- {0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=72: 01C30 - 01C3F */
- {0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=73: 01CD0 - 01CDF */
- {230, 230, 230, 0, 1, 220, 220, 220, 220, 220, 230, 230, 220, 220, 220, 220 },
- /* idx=74: 01CE0 - 01CEF */
- {230, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 220, 0, 0 },
- /* idx=75: 01DC0 - 01DCF */
- {230, 230, 220, 230, 230, 230, 230, 230, 230, 230, 220, 230, 230, 234, 214, 220 },
- /* idx=76: 01DD0 - 01DDF */
- {202, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 },
- /* idx=77: 01DE0 - 01DEF */
- {230, 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=78: 01DF0 - 01DFF */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, 220, 230, 220 },
- /* idx=79: 020D0 - 020DF */
- {230, 230, 1, 1, 230, 230, 230, 230, 1, 1, 1, 230, 230, 0, 0, 0 },
- /* idx=80: 020E0 - 020EF */
- {0, 230, 0, 0, 0, 1, 1, 230, 220, 230, 1, 1, 220, 220, 220, 220 },
- /* idx=81: 020F0 - 020FF */
- {230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=82: 02CE0 - 02CEF */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230 },
- /* idx=83: 02CF0 - 02CFF */
- {230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=84: 02D70 - 02D7F */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9 },
- /* idx=85: 02DE0 - 02DEF */
- {230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 },
- /* idx=86: 02DF0 - 02DFF */
- {230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 },
- /* idx=87: 03020 - 0302F */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 218, 228, 232, 222, 224, 224 },
- /* idx=88: 03090 - 0309F */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0 },
- /* idx=89: 0A660 - 0A66F */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230 },
- /* idx=90: 0A670 - 0A67F */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 0, 0 },
- /* idx=91: 0A6F0 - 0A6FF */
- {230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=92: 0A800 - 0A80F */
- {0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=93: 0A8C0 - 0A8CF */
- {0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=94: 0A8E0 - 0A8EF */
- {230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 },
- /* idx=95: 0A8F0 - 0A8FF */
- {230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=96: 0A920 - 0A92F */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 0, 0 },
- /* idx=97: 0A950 - 0A95F */
- {0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=98: 0A9B0 - 0A9BF */
- {0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=99: 0A9C0 - 0A9CF */
- {9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=100: 0AAB0 - 0AABF */
- {230, 0, 230, 230, 220, 0, 0, 230, 230, 0, 0, 0, 0, 0, 230, 230 },
- /* idx=101: 0AAC0 - 0AACF */
- {0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=102: 0ABE0 - 0ABEF */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
- /* idx=103: 0FB10 - 0FB1F */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0 },
- /* idx=104: 0FE20 - 0FE2F */
- {230, 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=105: 101F0 - 101FF */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0 },
- /* idx=106: 10A00 - 10A0F */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 230 },
- /* idx=107: 10A30 - 10A3F */
- {0, 0, 0, 0, 0, 0, 0, 0, 230, 1, 220, 0, 0, 0, 0, 9 },
- /* idx=108: 11040 - 1104F */
- {0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=109: 110B0 - 110BF */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 7, 0, 0, 0, 0, 0 },
- /* idx=110: 1D160 - 1D16F */
- {0, 0, 0, 0, 0, 216, 216, 1, 1, 1, 0, 0, 0, 226, 216, 216 },
- /* idx=111: 1D170 - 1D17F */
- {216, 216, 216, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 220, 220 },
- /* idx=112: 1D180 - 1D18F */
- {220, 220, 220, 0, 0, 230, 230, 230, 230, 230, 220, 220, 0, 0, 0, 0 },
- /* idx=113: 1D1A0 - 1D1AF */
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0, 0 },
- /* idx=114: 1D240 - 1D24F */
- {0, 0, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-};
-
-/* The index table to ccc_val[*][16] */
-static const unsigned char ccc_val_index[][16] = {
- /* idx=0: XXX00 - XXXFF */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=1: 00300 - 003FF */
- { 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=2: 00400 - 004FF */
- { 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=3: 00500 - 005FF */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,10,11,12, 0, 0, 0 },
- /* idx=4: 00600 - 006FF */
- { 0,13, 0, 0,14,15, 0,16, 0, 0, 0, 0, 0,17,18, 0 },
- /* idx=5: 00700 - 007FF */
- { 0,19, 0,20,21, 0, 0, 0, 0, 0, 0, 0, 0, 0,22,23 },
- /* idx=6: 00800 - 008FF */
- { 0,24,25, 0, 0,26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=7: 00900 - 009FF */
- { 0, 0, 0,27,28,29, 0, 0, 0, 0, 0,30,31, 0, 0, 0 },
- /* idx=8: 00A00 - 00AFF */
- { 0, 0, 0,32,33, 0, 0, 0, 0, 0, 0,34,35, 0, 0, 0 },
- /* idx=9: 00B00 - 00BFF */
- { 0, 0, 0,36,37, 0, 0, 0, 0, 0, 0, 0,38, 0, 0, 0 },
- /* idx=10: 00C00 - 00CFF */
- { 0, 0, 0, 0,39,40, 0, 0, 0, 0, 0,41,42, 0, 0, 0 },
- /* idx=11: 00D00 - 00DFF */
- { 0, 0, 0, 0,43, 0, 0, 0, 0, 0, 0, 0,44, 0, 0, 0 },
- /* idx=12: 00E00 - 00EFF */
- { 0, 0, 0,45,46, 0, 0, 0, 0, 0, 0,47,48, 0, 0, 0 },
- /* idx=13: 00F00 - 00FFF */
- { 0,49, 0,50, 0, 0, 0,51,52, 0, 0, 0,53, 0, 0, 0 },
- /* idx=14: 01000 - 010FF */
- { 0, 0, 0,54, 0, 0, 0, 0,55, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=15: 01300 - 013FF */
- { 0, 0, 0, 0, 0,56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=16: 01700 - 017FF */
- { 0,57, 0,58, 0, 0, 0, 0, 0, 0, 0, 0, 0,59, 0, 0 },
- /* idx=17: 01800 - 018FF */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,60, 0, 0, 0, 0, 0 },
- /* idx=18: 01900 - 019FF */
- { 0, 0, 0,61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=19: 01A00 - 01AFF */
- { 0,62, 0, 0, 0, 0,63,64, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=20: 01B00 - 01BFF */
- { 0, 0, 0,65,66, 0,67,68, 0, 0,69, 0, 0, 0,70,71 },
- /* idx=21: 01C00 - 01CFF */
- { 0, 0, 0,72, 0, 0, 0, 0, 0, 0, 0, 0, 0,73,74, 0 },
- /* idx=22: 01D00 - 01DFF */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,75,76,77,78 },
- /* idx=23: 02000 - 020FF */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,79,80,81 },
- /* idx=24: 02C00 - 02CFF */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,82,83 },
- /* idx=25: 02D00 - 02DFF */
- { 0, 0, 0, 0, 0, 0, 0,84, 0, 0, 0, 0, 0, 0,85,86 },
- /* idx=26: 03000 - 030FF */
- { 0, 0,87, 0, 0, 0, 0, 0, 0,88, 0, 0, 0, 0, 0, 0 },
- /* idx=27: 0A600 - 0A6FF */
- { 0, 0, 0, 0, 0, 0,89,90, 0, 0, 0, 0, 0, 0, 0,91 },
- /* idx=28: 0A800 - 0A8FF */
- {92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,93, 0,94,95 },
- /* idx=29: 0A900 - 0A9FF */
- { 0, 0,96, 0, 0,97, 0, 0, 0, 0, 0,98,99, 0, 0, 0 },
- /* idx=30: 0AA00 - 0AAFF */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100,101, 0, 0, 0 },
- /* idx=31: 0AB00 - 0ABFF */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,102, 0 },
- /* idx=32: 0FB00 - 0FBFF */
- { 0,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=33: 0FE00 - 0FEFF */
- { 0, 0,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=34: 10100 - 101FF */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105 },
- /* idx=35: 10A00 - 10AFF */
- {106, 0, 0,107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* idx=36: 11000 - 110FF */
- { 0, 0, 0, 0,108, 0, 0, 0, 0, 0, 0,109, 0, 0, 0, 0 },
- /* idx=37: 1D100 - 1D1FF */
- { 0, 0, 0, 0, 0, 0,110,111,112, 0,113, 0, 0, 0, 0, 0 },
- /* idx=38: 1D200 - 1D2FF */
- { 0, 0, 0, 0,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-};
-
-/* The index table to ccc_val_index[*][16] */
-static const unsigned char ccc_index[] = {
- 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, 0, 0,15, 0, 0, 0,16,
- 17,18,19,20,21,22, 0, 0,23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,24,25, 0, 0,
- 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,27, 0,
- 28,29,30,31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,33, 0, 0,34, 0, 0, 0, 0, 0, 0,
- 0, 0,35, 0, 0, 0, 0, 0,36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,37,38,};
-
-struct unicode_decomposition_table {
- uint32_t nfc;
- uint32_t cp1;
- uint32_t cp2;
-};
-
-static const struct unicode_decomposition_table u_decomposition_table[] = {
- { 0x000C0 , 0x00041 , 0x00300 },
- { 0x000C1 , 0x00041 , 0x00301 },
- { 0x000C2 , 0x00041 , 0x00302 },
- { 0x000C3 , 0x00041 , 0x00303 },
- { 0x000C4 , 0x00041 , 0x00308 },
- { 0x000C5 , 0x00041 , 0x0030A },
- { 0x000C7 , 0x00043 , 0x00327 },
- { 0x000C8 , 0x00045 , 0x00300 },
- { 0x000C9 , 0x00045 , 0x00301 },
- { 0x000CA , 0x00045 , 0x00302 },
- { 0x000CB , 0x00045 , 0x00308 },
- { 0x000CC , 0x00049 , 0x00300 },
- { 0x000CD , 0x00049 , 0x00301 },
- { 0x000CE , 0x00049 , 0x00302 },
- { 0x000CF , 0x00049 , 0x00308 },
- { 0x000D1 , 0x0004E , 0x00303 },
- { 0x000D2 , 0x0004F , 0x00300 },
- { 0x000D3 , 0x0004F , 0x00301 },
- { 0x000D4 , 0x0004F , 0x00302 },
- { 0x000D5 , 0x0004F , 0x00303 },
- { 0x000D6 , 0x0004F , 0x00308 },
- { 0x000D9 , 0x00055 , 0x00300 },
- { 0x000DA , 0x00055 , 0x00301 },
- { 0x000DB , 0x00055 , 0x00302 },
- { 0x000DC , 0x00055 , 0x00308 },
- { 0x000DD , 0x00059 , 0x00301 },
- { 0x000E0 , 0x00061 , 0x00300 },
- { 0x000E1 , 0x00061 , 0x00301 },
- { 0x000E2 , 0x00061 , 0x00302 },
- { 0x000E3 , 0x00061 , 0x00303 },
- { 0x000E4 , 0x00061 , 0x00308 },
- { 0x000E5 , 0x00061 , 0x0030A },
- { 0x000E7 , 0x00063 , 0x00327 },
- { 0x000E8 , 0x00065 , 0x00300 },
- { 0x000E9 , 0x00065 , 0x00301 },
- { 0x000EA , 0x00065 , 0x00302 },
- { 0x000EB , 0x00065 , 0x00308 },
- { 0x000EC , 0x00069 , 0x00300 },
- { 0x000ED , 0x00069 , 0x00301 },
- { 0x000EE , 0x00069 , 0x00302 },
- { 0x000EF , 0x00069 , 0x00308 },
- { 0x000F1 , 0x0006E , 0x00303 },
- { 0x000F2 , 0x0006F , 0x00300 },
- { 0x000F3 , 0x0006F , 0x00301 },
- { 0x000F4 , 0x0006F , 0x00302 },
- { 0x000F5 , 0x0006F , 0x00303 },
- { 0x000F6 , 0x0006F , 0x00308 },
- { 0x000F9 , 0x00075 , 0x00300 },
- { 0x000FA , 0x00075 , 0x00301 },
- { 0x000FB , 0x00075 , 0x00302 },
- { 0x000FC , 0x00075 , 0x00308 },
- { 0x000FD , 0x00079 , 0x00301 },
- { 0x000FF , 0x00079 , 0x00308 },
- { 0x00100 , 0x00041 , 0x00304 },
- { 0x00101 , 0x00061 , 0x00304 },
- { 0x00102 , 0x00041 , 0x00306 },
- { 0x00103 , 0x00061 , 0x00306 },
- { 0x00104 , 0x00041 , 0x00328 },
- { 0x00105 , 0x00061 , 0x00328 },
- { 0x00106 , 0x00043 , 0x00301 },
- { 0x00107 , 0x00063 , 0x00301 },
- { 0x00108 , 0x00043 , 0x00302 },
- { 0x00109 , 0x00063 , 0x00302 },
- { 0x0010A , 0x00043 , 0x00307 },
- { 0x0010B , 0x00063 , 0x00307 },
- { 0x0010C , 0x00043 , 0x0030C },
- { 0x0010D , 0x00063 , 0x0030C },
- { 0x0010E , 0x00044 , 0x0030C },
- { 0x0010F , 0x00064 , 0x0030C },
- { 0x00112 , 0x00045 , 0x00304 },
- { 0x00113 , 0x00065 , 0x00304 },
- { 0x00114 , 0x00045 , 0x00306 },
- { 0x00115 , 0x00065 , 0x00306 },
- { 0x00116 , 0x00045 , 0x00307 },
- { 0x00117 , 0x00065 , 0x00307 },
- { 0x00118 , 0x00045 , 0x00328 },
- { 0x00119 , 0x00065 , 0x00328 },
- { 0x0011A , 0x00045 , 0x0030C },
- { 0x0011B , 0x00065 , 0x0030C },
- { 0x0011C , 0x00047 , 0x00302 },
- { 0x0011D , 0x00067 , 0x00302 },
- { 0x0011E , 0x00047 , 0x00306 },
- { 0x0011F , 0x00067 , 0x00306 },
- { 0x00120 , 0x00047 , 0x00307 },
- { 0x00121 , 0x00067 , 0x00307 },
- { 0x00122 , 0x00047 , 0x00327 },
- { 0x00123 , 0x00067 , 0x00327 },
- { 0x00124 , 0x00048 , 0x00302 },
- { 0x00125 , 0x00068 , 0x00302 },
- { 0x00128 , 0x00049 , 0x00303 },
- { 0x00129 , 0x00069 , 0x00303 },
- { 0x0012A , 0x00049 , 0x00304 },
- { 0x0012B , 0x00069 , 0x00304 },
- { 0x0012C , 0x00049 , 0x00306 },
- { 0x0012D , 0x00069 , 0x00306 },
- { 0x0012E , 0x00049 , 0x00328 },
- { 0x0012F , 0x00069 , 0x00328 },
- { 0x00130 , 0x00049 , 0x00307 },
- { 0x00134 , 0x0004A , 0x00302 },
- { 0x00135 , 0x0006A , 0x00302 },
- { 0x00136 , 0x0004B , 0x00327 },
- { 0x00137 , 0x0006B , 0x00327 },
- { 0x00139 , 0x0004C , 0x00301 },
- { 0x0013A , 0x0006C , 0x00301 },
- { 0x0013B , 0x0004C , 0x00327 },
- { 0x0013C , 0x0006C , 0x00327 },
- { 0x0013D , 0x0004C , 0x0030C },
- { 0x0013E , 0x0006C , 0x0030C },
- { 0x00143 , 0x0004E , 0x00301 },
- { 0x00144 , 0x0006E , 0x00301 },
- { 0x00145 , 0x0004E , 0x00327 },
- { 0x00146 , 0x0006E , 0x00327 },
- { 0x00147 , 0x0004E , 0x0030C },
- { 0x00148 , 0x0006E , 0x0030C },
- { 0x0014C , 0x0004F , 0x00304 },
- { 0x0014D , 0x0006F , 0x00304 },
- { 0x0014E , 0x0004F , 0x00306 },
- { 0x0014F , 0x0006F , 0x00306 },
- { 0x00150 , 0x0004F , 0x0030B },
- { 0x00151 , 0x0006F , 0x0030B },
- { 0x00154 , 0x00052 , 0x00301 },
- { 0x00155 , 0x00072 , 0x00301 },
- { 0x00156 , 0x00052 , 0x00327 },
- { 0x00157 , 0x00072 , 0x00327 },
- { 0x00158 , 0x00052 , 0x0030C },
- { 0x00159 , 0x00072 , 0x0030C },
- { 0x0015A , 0x00053 , 0x00301 },
- { 0x0015B , 0x00073 , 0x00301 },
- { 0x0015C , 0x00053 , 0x00302 },
- { 0x0015D , 0x00073 , 0x00302 },
- { 0x0015E , 0x00053 , 0x00327 },
- { 0x0015F , 0x00073 , 0x00327 },
- { 0x00160 , 0x00053 , 0x0030C },
- { 0x00161 , 0x00073 , 0x0030C },
- { 0x00162 , 0x00054 , 0x00327 },
- { 0x00163 , 0x00074 , 0x00327 },
- { 0x00164 , 0x00054 , 0x0030C },
- { 0x00165 , 0x00074 , 0x0030C },
- { 0x00168 , 0x00055 , 0x00303 },
- { 0x00169 , 0x00075 , 0x00303 },
- { 0x0016A , 0x00055 , 0x00304 },
- { 0x0016B , 0x00075 , 0x00304 },
- { 0x0016C , 0x00055 , 0x00306 },
- { 0x0016D , 0x00075 , 0x00306 },
- { 0x0016E , 0x00055 , 0x0030A },
- { 0x0016F , 0x00075 , 0x0030A },
- { 0x00170 , 0x00055 , 0x0030B },
- { 0x00171 , 0x00075 , 0x0030B },
- { 0x00172 , 0x00055 , 0x00328 },
- { 0x00173 , 0x00075 , 0x00328 },
- { 0x00174 , 0x00057 , 0x00302 },
- { 0x00175 , 0x00077 , 0x00302 },
- { 0x00176 , 0x00059 , 0x00302 },
- { 0x00177 , 0x00079 , 0x00302 },
- { 0x00178 , 0x00059 , 0x00308 },
- { 0x00179 , 0x0005A , 0x00301 },
- { 0x0017A , 0x0007A , 0x00301 },
- { 0x0017B , 0x0005A , 0x00307 },
- { 0x0017C , 0x0007A , 0x00307 },
- { 0x0017D , 0x0005A , 0x0030C },
- { 0x0017E , 0x0007A , 0x0030C },
- { 0x001A0 , 0x0004F , 0x0031B },
- { 0x001A1 , 0x0006F , 0x0031B },
- { 0x001AF , 0x00055 , 0x0031B },
- { 0x001B0 , 0x00075 , 0x0031B },
- { 0x001CD , 0x00041 , 0x0030C },
- { 0x001CE , 0x00061 , 0x0030C },
- { 0x001CF , 0x00049 , 0x0030C },
- { 0x001D0 , 0x00069 , 0x0030C },
- { 0x001D1 , 0x0004F , 0x0030C },
- { 0x001D2 , 0x0006F , 0x0030C },
- { 0x001D3 , 0x00055 , 0x0030C },
- { 0x001D4 , 0x00075 , 0x0030C },
- { 0x001D5 , 0x000DC , 0x00304 },
- { 0x001D6 , 0x000FC , 0x00304 },
- { 0x001D7 , 0x000DC , 0x00301 },
- { 0x001D8 , 0x000FC , 0x00301 },
- { 0x001D9 , 0x000DC , 0x0030C },
- { 0x001DA , 0x000FC , 0x0030C },
- { 0x001DB , 0x000DC , 0x00300 },
- { 0x001DC , 0x000FC , 0x00300 },
- { 0x001DE , 0x000C4 , 0x00304 },
- { 0x001DF , 0x000E4 , 0x00304 },
- { 0x001E0 , 0x00226 , 0x00304 },
- { 0x001E1 , 0x00227 , 0x00304 },
- { 0x001E2 , 0x000C6 , 0x00304 },
- { 0x001E3 , 0x000E6 , 0x00304 },
- { 0x001E6 , 0x00047 , 0x0030C },
- { 0x001E7 , 0x00067 , 0x0030C },
- { 0x001E8 , 0x0004B , 0x0030C },
- { 0x001E9 , 0x0006B , 0x0030C },
- { 0x001EA , 0x0004F , 0x00328 },
- { 0x001EB , 0x0006F , 0x00328 },
- { 0x001EC , 0x001EA , 0x00304 },
- { 0x001ED , 0x001EB , 0x00304 },
- { 0x001EE , 0x001B7 , 0x0030C },
- { 0x001EF , 0x00292 , 0x0030C },
- { 0x001F0 , 0x0006A , 0x0030C },
- { 0x001F4 , 0x00047 , 0x00301 },
- { 0x001F5 , 0x00067 , 0x00301 },
- { 0x001F8 , 0x0004E , 0x00300 },
- { 0x001F9 , 0x0006E , 0x00300 },
- { 0x001FA , 0x000C5 , 0x00301 },
- { 0x001FB , 0x000E5 , 0x00301 },
- { 0x001FC , 0x000C6 , 0x00301 },
- { 0x001FD , 0x000E6 , 0x00301 },
- { 0x001FE , 0x000D8 , 0x00301 },
- { 0x001FF , 0x000F8 , 0x00301 },
- { 0x00200 , 0x00041 , 0x0030F },
- { 0x00201 , 0x00061 , 0x0030F },
- { 0x00202 , 0x00041 , 0x00311 },
- { 0x00203 , 0x00061 , 0x00311 },
- { 0x00204 , 0x00045 , 0x0030F },
- { 0x00205 , 0x00065 , 0x0030F },
- { 0x00206 , 0x00045 , 0x00311 },
- { 0x00207 , 0x00065 , 0x00311 },
- { 0x00208 , 0x00049 , 0x0030F },
- { 0x00209 , 0x00069 , 0x0030F },
- { 0x0020A , 0x00049 , 0x00311 },
- { 0x0020B , 0x00069 , 0x00311 },
- { 0x0020C , 0x0004F , 0x0030F },
- { 0x0020D , 0x0006F , 0x0030F },
- { 0x0020E , 0x0004F , 0x00311 },
- { 0x0020F , 0x0006F , 0x00311 },
- { 0x00210 , 0x00052 , 0x0030F },
- { 0x00211 , 0x00072 , 0x0030F },
- { 0x00212 , 0x00052 , 0x00311 },
- { 0x00213 , 0x00072 , 0x00311 },
- { 0x00214 , 0x00055 , 0x0030F },
- { 0x00215 , 0x00075 , 0x0030F },
- { 0x00216 , 0x00055 , 0x00311 },
- { 0x00217 , 0x00075 , 0x00311 },
- { 0x00218 , 0x00053 , 0x00326 },
- { 0x00219 , 0x00073 , 0x00326 },
- { 0x0021A , 0x00054 , 0x00326 },
- { 0x0021B , 0x00074 , 0x00326 },
- { 0x0021E , 0x00048 , 0x0030C },
- { 0x0021F , 0x00068 , 0x0030C },
- { 0x00226 , 0x00041 , 0x00307 },
- { 0x00227 , 0x00061 , 0x00307 },
- { 0x00228 , 0x00045 , 0x00327 },
- { 0x00229 , 0x00065 , 0x00327 },
- { 0x0022A , 0x000D6 , 0x00304 },
- { 0x0022B , 0x000F6 , 0x00304 },
- { 0x0022C , 0x000D5 , 0x00304 },
- { 0x0022D , 0x000F5 , 0x00304 },
- { 0x0022E , 0x0004F , 0x00307 },
- { 0x0022F , 0x0006F , 0x00307 },
- { 0x00230 , 0x0022E , 0x00304 },
- { 0x00231 , 0x0022F , 0x00304 },
- { 0x00232 , 0x00059 , 0x00304 },
- { 0x00233 , 0x00079 , 0x00304 },
- { 0x00385 , 0x000A8 , 0x00301 },
- { 0x00386 , 0x00391 , 0x00301 },
- { 0x00388 , 0x00395 , 0x00301 },
- { 0x00389 , 0x00397 , 0x00301 },
- { 0x0038A , 0x00399 , 0x00301 },
- { 0x0038C , 0x0039F , 0x00301 },
- { 0x0038E , 0x003A5 , 0x00301 },
- { 0x0038F , 0x003A9 , 0x00301 },
- { 0x00390 , 0x003CA , 0x00301 },
- { 0x003AA , 0x00399 , 0x00308 },
- { 0x003AB , 0x003A5 , 0x00308 },
- { 0x003AC , 0x003B1 , 0x00301 },
- { 0x003AD , 0x003B5 , 0x00301 },
- { 0x003AE , 0x003B7 , 0x00301 },
- { 0x003AF , 0x003B9 , 0x00301 },
- { 0x003B0 , 0x003CB , 0x00301 },
- { 0x003CA , 0x003B9 , 0x00308 },
- { 0x003CB , 0x003C5 , 0x00308 },
- { 0x003CC , 0x003BF , 0x00301 },
- { 0x003CD , 0x003C5 , 0x00301 },
- { 0x003CE , 0x003C9 , 0x00301 },
- { 0x003D3 , 0x003D2 , 0x00301 },
- { 0x003D4 , 0x003D2 , 0x00308 },
- { 0x00400 , 0x00415 , 0x00300 },
- { 0x00401 , 0x00415 , 0x00308 },
- { 0x00403 , 0x00413 , 0x00301 },
- { 0x00407 , 0x00406 , 0x00308 },
- { 0x0040C , 0x0041A , 0x00301 },
- { 0x0040D , 0x00418 , 0x00300 },
- { 0x0040E , 0x00423 , 0x00306 },
- { 0x00419 , 0x00418 , 0x00306 },
- { 0x00439 , 0x00438 , 0x00306 },
- { 0x00450 , 0x00435 , 0x00300 },
- { 0x00451 , 0x00435 , 0x00308 },
- { 0x00453 , 0x00433 , 0x00301 },
- { 0x00457 , 0x00456 , 0x00308 },
- { 0x0045C , 0x0043A , 0x00301 },
- { 0x0045D , 0x00438 , 0x00300 },
- { 0x0045E , 0x00443 , 0x00306 },
- { 0x00476 , 0x00474 , 0x0030F },
- { 0x00477 , 0x00475 , 0x0030F },
- { 0x004C1 , 0x00416 , 0x00306 },
- { 0x004C2 , 0x00436 , 0x00306 },
- { 0x004D0 , 0x00410 , 0x00306 },
- { 0x004D1 , 0x00430 , 0x00306 },
- { 0x004D2 , 0x00410 , 0x00308 },
- { 0x004D3 , 0x00430 , 0x00308 },
- { 0x004D6 , 0x00415 , 0x00306 },
- { 0x004D7 , 0x00435 , 0x00306 },
- { 0x004DA , 0x004D8 , 0x00308 },
- { 0x004DB , 0x004D9 , 0x00308 },
- { 0x004DC , 0x00416 , 0x00308 },
- { 0x004DD , 0x00436 , 0x00308 },
- { 0x004DE , 0x00417 , 0x00308 },
- { 0x004DF , 0x00437 , 0x00308 },
- { 0x004E2 , 0x00418 , 0x00304 },
- { 0x004E3 , 0x00438 , 0x00304 },
- { 0x004E4 , 0x00418 , 0x00308 },
- { 0x004E5 , 0x00438 , 0x00308 },
- { 0x004E6 , 0x0041E , 0x00308 },
- { 0x004E7 , 0x0043E , 0x00308 },
- { 0x004EA , 0x004E8 , 0x00308 },
- { 0x004EB , 0x004E9 , 0x00308 },
- { 0x004EC , 0x0042D , 0x00308 },
- { 0x004ED , 0x0044D , 0x00308 },
- { 0x004EE , 0x00423 , 0x00304 },
- { 0x004EF , 0x00443 , 0x00304 },
- { 0x004F0 , 0x00423 , 0x00308 },
- { 0x004F1 , 0x00443 , 0x00308 },
- { 0x004F2 , 0x00423 , 0x0030B },
- { 0x004F3 , 0x00443 , 0x0030B },
- { 0x004F4 , 0x00427 , 0x00308 },
- { 0x004F5 , 0x00447 , 0x00308 },
- { 0x004F8 , 0x0042B , 0x00308 },
- { 0x004F9 , 0x0044B , 0x00308 },
- { 0x00622 , 0x00627 , 0x00653 },
- { 0x00623 , 0x00627 , 0x00654 },
- { 0x00624 , 0x00648 , 0x00654 },
- { 0x00625 , 0x00627 , 0x00655 },
- { 0x00626 , 0x0064A , 0x00654 },
- { 0x006C0 , 0x006D5 , 0x00654 },
- { 0x006C2 , 0x006C1 , 0x00654 },
- { 0x006D3 , 0x006D2 , 0x00654 },
- { 0x00929 , 0x00928 , 0x0093C },
- { 0x00931 , 0x00930 , 0x0093C },
- { 0x00934 , 0x00933 , 0x0093C },
- { 0x009CB , 0x009C7 , 0x009BE },
- { 0x009CC , 0x009C7 , 0x009D7 },
- { 0x00B48 , 0x00B47 , 0x00B56 },
- { 0x00B4B , 0x00B47 , 0x00B3E },
- { 0x00B4C , 0x00B47 , 0x00B57 },
- { 0x00B94 , 0x00B92 , 0x00BD7 },
- { 0x00BCA , 0x00BC6 , 0x00BBE },
- { 0x00BCB , 0x00BC7 , 0x00BBE },
- { 0x00BCC , 0x00BC6 , 0x00BD7 },
- { 0x00C48 , 0x00C46 , 0x00C56 },
- { 0x00CC0 , 0x00CBF , 0x00CD5 },
- { 0x00CC7 , 0x00CC6 , 0x00CD5 },
- { 0x00CC8 , 0x00CC6 , 0x00CD6 },
- { 0x00CCA , 0x00CC6 , 0x00CC2 },
- { 0x00CCB , 0x00CCA , 0x00CD5 },
- { 0x00D4A , 0x00D46 , 0x00D3E },
- { 0x00D4B , 0x00D47 , 0x00D3E },
- { 0x00D4C , 0x00D46 , 0x00D57 },
- { 0x00DDA , 0x00DD9 , 0x00DCA },
- { 0x00DDC , 0x00DD9 , 0x00DCF },
- { 0x00DDD , 0x00DDC , 0x00DCA },
- { 0x00DDE , 0x00DD9 , 0x00DDF },
- { 0x01026 , 0x01025 , 0x0102E },
- { 0x01B06 , 0x01B05 , 0x01B35 },
- { 0x01B08 , 0x01B07 , 0x01B35 },
- { 0x01B0A , 0x01B09 , 0x01B35 },
- { 0x01B0C , 0x01B0B , 0x01B35 },
- { 0x01B0E , 0x01B0D , 0x01B35 },
- { 0x01B12 , 0x01B11 , 0x01B35 },
- { 0x01B3B , 0x01B3A , 0x01B35 },
- { 0x01B3D , 0x01B3C , 0x01B35 },
- { 0x01B40 , 0x01B3E , 0x01B35 },
- { 0x01B41 , 0x01B3F , 0x01B35 },
- { 0x01B43 , 0x01B42 , 0x01B35 },
- { 0x01E00 , 0x00041 , 0x00325 },
- { 0x01E01 , 0x00061 , 0x00325 },
- { 0x01E02 , 0x00042 , 0x00307 },
- { 0x01E03 , 0x00062 , 0x00307 },
- { 0x01E04 , 0x00042 , 0x00323 },
- { 0x01E05 , 0x00062 , 0x00323 },
- { 0x01E06 , 0x00042 , 0x00331 },
- { 0x01E07 , 0x00062 , 0x00331 },
- { 0x01E08 , 0x000C7 , 0x00301 },
- { 0x01E09 , 0x000E7 , 0x00301 },
- { 0x01E0A , 0x00044 , 0x00307 },
- { 0x01E0B , 0x00064 , 0x00307 },
- { 0x01E0C , 0x00044 , 0x00323 },
- { 0x01E0D , 0x00064 , 0x00323 },
- { 0x01E0E , 0x00044 , 0x00331 },
- { 0x01E0F , 0x00064 , 0x00331 },
- { 0x01E10 , 0x00044 , 0x00327 },
- { 0x01E11 , 0x00064 , 0x00327 },
- { 0x01E12 , 0x00044 , 0x0032D },
- { 0x01E13 , 0x00064 , 0x0032D },
- { 0x01E14 , 0x00112 , 0x00300 },
- { 0x01E15 , 0x00113 , 0x00300 },
- { 0x01E16 , 0x00112 , 0x00301 },
- { 0x01E17 , 0x00113 , 0x00301 },
- { 0x01E18 , 0x00045 , 0x0032D },
- { 0x01E19 , 0x00065 , 0x0032D },
- { 0x01E1A , 0x00045 , 0x00330 },
- { 0x01E1B , 0x00065 , 0x00330 },
- { 0x01E1C , 0x00228 , 0x00306 },
- { 0x01E1D , 0x00229 , 0x00306 },
- { 0x01E1E , 0x00046 , 0x00307 },
- { 0x01E1F , 0x00066 , 0x00307 },
- { 0x01E20 , 0x00047 , 0x00304 },
- { 0x01E21 , 0x00067 , 0x00304 },
- { 0x01E22 , 0x00048 , 0x00307 },
- { 0x01E23 , 0x00068 , 0x00307 },
- { 0x01E24 , 0x00048 , 0x00323 },
- { 0x01E25 , 0x00068 , 0x00323 },
- { 0x01E26 , 0x00048 , 0x00308 },
- { 0x01E27 , 0x00068 , 0x00308 },
- { 0x01E28 , 0x00048 , 0x00327 },
- { 0x01E29 , 0x00068 , 0x00327 },
- { 0x01E2A , 0x00048 , 0x0032E },
- { 0x01E2B , 0x00068 , 0x0032E },
- { 0x01E2C , 0x00049 , 0x00330 },
- { 0x01E2D , 0x00069 , 0x00330 },
- { 0x01E2E , 0x000CF , 0x00301 },
- { 0x01E2F , 0x000EF , 0x00301 },
- { 0x01E30 , 0x0004B , 0x00301 },
- { 0x01E31 , 0x0006B , 0x00301 },
- { 0x01E32 , 0x0004B , 0x00323 },
- { 0x01E33 , 0x0006B , 0x00323 },
- { 0x01E34 , 0x0004B , 0x00331 },
- { 0x01E35 , 0x0006B , 0x00331 },
- { 0x01E36 , 0x0004C , 0x00323 },
- { 0x01E37 , 0x0006C , 0x00323 },
- { 0x01E38 , 0x01E36 , 0x00304 },
- { 0x01E39 , 0x01E37 , 0x00304 },
- { 0x01E3A , 0x0004C , 0x00331 },
- { 0x01E3B , 0x0006C , 0x00331 },
- { 0x01E3C , 0x0004C , 0x0032D },
- { 0x01E3D , 0x0006C , 0x0032D },
- { 0x01E3E , 0x0004D , 0x00301 },
- { 0x01E3F , 0x0006D , 0x00301 },
- { 0x01E40 , 0x0004D , 0x00307 },
- { 0x01E41 , 0x0006D , 0x00307 },
- { 0x01E42 , 0x0004D , 0x00323 },
- { 0x01E43 , 0x0006D , 0x00323 },
- { 0x01E44 , 0x0004E , 0x00307 },
- { 0x01E45 , 0x0006E , 0x00307 },
- { 0x01E46 , 0x0004E , 0x00323 },
- { 0x01E47 , 0x0006E , 0x00323 },
- { 0x01E48 , 0x0004E , 0x00331 },
- { 0x01E49 , 0x0006E , 0x00331 },
- { 0x01E4A , 0x0004E , 0x0032D },
- { 0x01E4B , 0x0006E , 0x0032D },
- { 0x01E4C , 0x000D5 , 0x00301 },
- { 0x01E4D , 0x000F5 , 0x00301 },
- { 0x01E4E , 0x000D5 , 0x00308 },
- { 0x01E4F , 0x000F5 , 0x00308 },
- { 0x01E50 , 0x0014C , 0x00300 },
- { 0x01E51 , 0x0014D , 0x00300 },
- { 0x01E52 , 0x0014C , 0x00301 },
- { 0x01E53 , 0x0014D , 0x00301 },
- { 0x01E54 , 0x00050 , 0x00301 },
- { 0x01E55 , 0x00070 , 0x00301 },
- { 0x01E56 , 0x00050 , 0x00307 },
- { 0x01E57 , 0x00070 , 0x00307 },
- { 0x01E58 , 0x00052 , 0x00307 },
- { 0x01E59 , 0x00072 , 0x00307 },
- { 0x01E5A , 0x00052 , 0x00323 },
- { 0x01E5B , 0x00072 , 0x00323 },
- { 0x01E5C , 0x01E5A , 0x00304 },
- { 0x01E5D , 0x01E5B , 0x00304 },
- { 0x01E5E , 0x00052 , 0x00331 },
- { 0x01E5F , 0x00072 , 0x00331 },
- { 0x01E60 , 0x00053 , 0x00307 },
- { 0x01E61 , 0x00073 , 0x00307 },
- { 0x01E62 , 0x00053 , 0x00323 },
- { 0x01E63 , 0x00073 , 0x00323 },
- { 0x01E64 , 0x0015A , 0x00307 },
- { 0x01E65 , 0x0015B , 0x00307 },
- { 0x01E66 , 0x00160 , 0x00307 },
- { 0x01E67 , 0x00161 , 0x00307 },
- { 0x01E68 , 0x01E62 , 0x00307 },
- { 0x01E69 , 0x01E63 , 0x00307 },
- { 0x01E6A , 0x00054 , 0x00307 },
- { 0x01E6B , 0x00074 , 0x00307 },
- { 0x01E6C , 0x00054 , 0x00323 },
- { 0x01E6D , 0x00074 , 0x00323 },
- { 0x01E6E , 0x00054 , 0x00331 },
- { 0x01E6F , 0x00074 , 0x00331 },
- { 0x01E70 , 0x00054 , 0x0032D },
- { 0x01E71 , 0x00074 , 0x0032D },
- { 0x01E72 , 0x00055 , 0x00324 },
- { 0x01E73 , 0x00075 , 0x00324 },
- { 0x01E74 , 0x00055 , 0x00330 },
- { 0x01E75 , 0x00075 , 0x00330 },
- { 0x01E76 , 0x00055 , 0x0032D },
- { 0x01E77 , 0x00075 , 0x0032D },
- { 0x01E78 , 0x00168 , 0x00301 },
- { 0x01E79 , 0x00169 , 0x00301 },
- { 0x01E7A , 0x0016A , 0x00308 },
- { 0x01E7B , 0x0016B , 0x00308 },
- { 0x01E7C , 0x00056 , 0x00303 },
- { 0x01E7D , 0x00076 , 0x00303 },
- { 0x01E7E , 0x00056 , 0x00323 },
- { 0x01E7F , 0x00076 , 0x00323 },
- { 0x01E80 , 0x00057 , 0x00300 },
- { 0x01E81 , 0x00077 , 0x00300 },
- { 0x01E82 , 0x00057 , 0x00301 },
- { 0x01E83 , 0x00077 , 0x00301 },
- { 0x01E84 , 0x00057 , 0x00308 },
- { 0x01E85 , 0x00077 , 0x00308 },
- { 0x01E86 , 0x00057 , 0x00307 },
- { 0x01E87 , 0x00077 , 0x00307 },
- { 0x01E88 , 0x00057 , 0x00323 },
- { 0x01E89 , 0x00077 , 0x00323 },
- { 0x01E8A , 0x00058 , 0x00307 },
- { 0x01E8B , 0x00078 , 0x00307 },
- { 0x01E8C , 0x00058 , 0x00308 },
- { 0x01E8D , 0x00078 , 0x00308 },
- { 0x01E8E , 0x00059 , 0x00307 },
- { 0x01E8F , 0x00079 , 0x00307 },
- { 0x01E90 , 0x0005A , 0x00302 },
- { 0x01E91 , 0x0007A , 0x00302 },
- { 0x01E92 , 0x0005A , 0x00323 },
- { 0x01E93 , 0x0007A , 0x00323 },
- { 0x01E94 , 0x0005A , 0x00331 },
- { 0x01E95 , 0x0007A , 0x00331 },
- { 0x01E96 , 0x00068 , 0x00331 },
- { 0x01E97 , 0x00074 , 0x00308 },
- { 0x01E98 , 0x00077 , 0x0030A },
- { 0x01E99 , 0x00079 , 0x0030A },
- { 0x01E9B , 0x0017F , 0x00307 },
- { 0x01EA0 , 0x00041 , 0x00323 },
- { 0x01EA1 , 0x00061 , 0x00323 },
- { 0x01EA2 , 0x00041 , 0x00309 },
- { 0x01EA3 , 0x00061 , 0x00309 },
- { 0x01EA4 , 0x000C2 , 0x00301 },
- { 0x01EA5 , 0x000E2 , 0x00301 },
- { 0x01EA6 , 0x000C2 , 0x00300 },
- { 0x01EA7 , 0x000E2 , 0x00300 },
- { 0x01EA8 , 0x000C2 , 0x00309 },
- { 0x01EA9 , 0x000E2 , 0x00309 },
- { 0x01EAA , 0x000C2 , 0x00303 },
- { 0x01EAB , 0x000E2 , 0x00303 },
- { 0x01EAC , 0x01EA0 , 0x00302 },
- { 0x01EAD , 0x01EA1 , 0x00302 },
- { 0x01EAE , 0x00102 , 0x00301 },
- { 0x01EAF , 0x00103 , 0x00301 },
- { 0x01EB0 , 0x00102 , 0x00300 },
- { 0x01EB1 , 0x00103 , 0x00300 },
- { 0x01EB2 , 0x00102 , 0x00309 },
- { 0x01EB3 , 0x00103 , 0x00309 },
- { 0x01EB4 , 0x00102 , 0x00303 },
- { 0x01EB5 , 0x00103 , 0x00303 },
- { 0x01EB6 , 0x01EA0 , 0x00306 },
- { 0x01EB7 , 0x01EA1 , 0x00306 },
- { 0x01EB8 , 0x00045 , 0x00323 },
- { 0x01EB9 , 0x00065 , 0x00323 },
- { 0x01EBA , 0x00045 , 0x00309 },
- { 0x01EBB , 0x00065 , 0x00309 },
- { 0x01EBC , 0x00045 , 0x00303 },
- { 0x01EBD , 0x00065 , 0x00303 },
- { 0x01EBE , 0x000CA , 0x00301 },
- { 0x01EBF , 0x000EA , 0x00301 },
- { 0x01EC0 , 0x000CA , 0x00300 },
- { 0x01EC1 , 0x000EA , 0x00300 },
- { 0x01EC2 , 0x000CA , 0x00309 },
- { 0x01EC3 , 0x000EA , 0x00309 },
- { 0x01EC4 , 0x000CA , 0x00303 },
- { 0x01EC5 , 0x000EA , 0x00303 },
- { 0x01EC6 , 0x01EB8 , 0x00302 },
- { 0x01EC7 , 0x01EB9 , 0x00302 },
- { 0x01EC8 , 0x00049 , 0x00309 },
- { 0x01EC9 , 0x00069 , 0x00309 },
- { 0x01ECA , 0x00049 , 0x00323 },
- { 0x01ECB , 0x00069 , 0x00323 },
- { 0x01ECC , 0x0004F , 0x00323 },
- { 0x01ECD , 0x0006F , 0x00323 },
- { 0x01ECE , 0x0004F , 0x00309 },
- { 0x01ECF , 0x0006F , 0x00309 },
- { 0x01ED0 , 0x000D4 , 0x00301 },
- { 0x01ED1 , 0x000F4 , 0x00301 },
- { 0x01ED2 , 0x000D4 , 0x00300 },
- { 0x01ED3 , 0x000F4 , 0x00300 },
- { 0x01ED4 , 0x000D4 , 0x00309 },
- { 0x01ED5 , 0x000F4 , 0x00309 },
- { 0x01ED6 , 0x000D4 , 0x00303 },
- { 0x01ED7 , 0x000F4 , 0x00303 },
- { 0x01ED8 , 0x01ECC , 0x00302 },
- { 0x01ED9 , 0x01ECD , 0x00302 },
- { 0x01EDA , 0x001A0 , 0x00301 },
- { 0x01EDB , 0x001A1 , 0x00301 },
- { 0x01EDC , 0x001A0 , 0x00300 },
- { 0x01EDD , 0x001A1 , 0x00300 },
- { 0x01EDE , 0x001A0 , 0x00309 },
- { 0x01EDF , 0x001A1 , 0x00309 },
- { 0x01EE0 , 0x001A0 , 0x00303 },
- { 0x01EE1 , 0x001A1 , 0x00303 },
- { 0x01EE2 , 0x001A0 , 0x00323 },
- { 0x01EE3 , 0x001A1 , 0x00323 },
- { 0x01EE4 , 0x00055 , 0x00323 },
- { 0x01EE5 , 0x00075 , 0x00323 },
- { 0x01EE6 , 0x00055 , 0x00309 },
- { 0x01EE7 , 0x00075 , 0x00309 },
- { 0x01EE8 , 0x001AF , 0x00301 },
- { 0x01EE9 , 0x001B0 , 0x00301 },
- { 0x01EEA , 0x001AF , 0x00300 },
- { 0x01EEB , 0x001B0 , 0x00300 },
- { 0x01EEC , 0x001AF , 0x00309 },
- { 0x01EED , 0x001B0 , 0x00309 },
- { 0x01EEE , 0x001AF , 0x00303 },
- { 0x01EEF , 0x001B0 , 0x00303 },
- { 0x01EF0 , 0x001AF , 0x00323 },
- { 0x01EF1 , 0x001B0 , 0x00323 },
- { 0x01EF2 , 0x00059 , 0x00300 },
- { 0x01EF3 , 0x00079 , 0x00300 },
- { 0x01EF4 , 0x00059 , 0x00323 },
- { 0x01EF5 , 0x00079 , 0x00323 },
- { 0x01EF6 , 0x00059 , 0x00309 },
- { 0x01EF7 , 0x00079 , 0x00309 },
- { 0x01EF8 , 0x00059 , 0x00303 },
- { 0x01EF9 , 0x00079 , 0x00303 },
- { 0x01F00 , 0x003B1 , 0x00313 },
- { 0x01F01 , 0x003B1 , 0x00314 },
- { 0x01F02 , 0x01F00 , 0x00300 },
- { 0x01F03 , 0x01F01 , 0x00300 },
- { 0x01F04 , 0x01F00 , 0x00301 },
- { 0x01F05 , 0x01F01 , 0x00301 },
- { 0x01F06 , 0x01F00 , 0x00342 },
- { 0x01F07 , 0x01F01 , 0x00342 },
- { 0x01F08 , 0x00391 , 0x00313 },
- { 0x01F09 , 0x00391 , 0x00314 },
- { 0x01F0A , 0x01F08 , 0x00300 },
- { 0x01F0B , 0x01F09 , 0x00300 },
- { 0x01F0C , 0x01F08 , 0x00301 },
- { 0x01F0D , 0x01F09 , 0x00301 },
- { 0x01F0E , 0x01F08 , 0x00342 },
- { 0x01F0F , 0x01F09 , 0x00342 },
- { 0x01F10 , 0x003B5 , 0x00313 },
- { 0x01F11 , 0x003B5 , 0x00314 },
- { 0x01F12 , 0x01F10 , 0x00300 },
- { 0x01F13 , 0x01F11 , 0x00300 },
- { 0x01F14 , 0x01F10 , 0x00301 },
- { 0x01F15 , 0x01F11 , 0x00301 },
- { 0x01F18 , 0x00395 , 0x00313 },
- { 0x01F19 , 0x00395 , 0x00314 },
- { 0x01F1A , 0x01F18 , 0x00300 },
- { 0x01F1B , 0x01F19 , 0x00300 },
- { 0x01F1C , 0x01F18 , 0x00301 },
- { 0x01F1D , 0x01F19 , 0x00301 },
- { 0x01F20 , 0x003B7 , 0x00313 },
- { 0x01F21 , 0x003B7 , 0x00314 },
- { 0x01F22 , 0x01F20 , 0x00300 },
- { 0x01F23 , 0x01F21 , 0x00300 },
- { 0x01F24 , 0x01F20 , 0x00301 },
- { 0x01F25 , 0x01F21 , 0x00301 },
- { 0x01F26 , 0x01F20 , 0x00342 },
- { 0x01F27 , 0x01F21 , 0x00342 },
- { 0x01F28 , 0x00397 , 0x00313 },
- { 0x01F29 , 0x00397 , 0x00314 },
- { 0x01F2A , 0x01F28 , 0x00300 },
- { 0x01F2B , 0x01F29 , 0x00300 },
- { 0x01F2C , 0x01F28 , 0x00301 },
- { 0x01F2D , 0x01F29 , 0x00301 },
- { 0x01F2E , 0x01F28 , 0x00342 },
- { 0x01F2F , 0x01F29 , 0x00342 },
- { 0x01F30 , 0x003B9 , 0x00313 },
- { 0x01F31 , 0x003B9 , 0x00314 },
- { 0x01F32 , 0x01F30 , 0x00300 },
- { 0x01F33 , 0x01F31 , 0x00300 },
- { 0x01F34 , 0x01F30 , 0x00301 },
- { 0x01F35 , 0x01F31 , 0x00301 },
- { 0x01F36 , 0x01F30 , 0x00342 },
- { 0x01F37 , 0x01F31 , 0x00342 },
- { 0x01F38 , 0x00399 , 0x00313 },
- { 0x01F39 , 0x00399 , 0x00314 },
- { 0x01F3A , 0x01F38 , 0x00300 },
- { 0x01F3B , 0x01F39 , 0x00300 },
- { 0x01F3C , 0x01F38 , 0x00301 },
- { 0x01F3D , 0x01F39 , 0x00301 },
- { 0x01F3E , 0x01F38 , 0x00342 },
- { 0x01F3F , 0x01F39 , 0x00342 },
- { 0x01F40 , 0x003BF , 0x00313 },
- { 0x01F41 , 0x003BF , 0x00314 },
- { 0x01F42 , 0x01F40 , 0x00300 },
- { 0x01F43 , 0x01F41 , 0x00300 },
- { 0x01F44 , 0x01F40 , 0x00301 },
- { 0x01F45 , 0x01F41 , 0x00301 },
- { 0x01F48 , 0x0039F , 0x00313 },
- { 0x01F49 , 0x0039F , 0x00314 },
- { 0x01F4A , 0x01F48 , 0x00300 },
- { 0x01F4B , 0x01F49 , 0x00300 },
- { 0x01F4C , 0x01F48 , 0x00301 },
- { 0x01F4D , 0x01F49 , 0x00301 },
- { 0x01F50 , 0x003C5 , 0x00313 },
- { 0x01F51 , 0x003C5 , 0x00314 },
- { 0x01F52 , 0x01F50 , 0x00300 },
- { 0x01F53 , 0x01F51 , 0x00300 },
- { 0x01F54 , 0x01F50 , 0x00301 },
- { 0x01F55 , 0x01F51 , 0x00301 },
- { 0x01F56 , 0x01F50 , 0x00342 },
- { 0x01F57 , 0x01F51 , 0x00342 },
- { 0x01F59 , 0x003A5 , 0x00314 },
- { 0x01F5B , 0x01F59 , 0x00300 },
- { 0x01F5D , 0x01F59 , 0x00301 },
- { 0x01F5F , 0x01F59 , 0x00342 },
- { 0x01F60 , 0x003C9 , 0x00313 },
- { 0x01F61 , 0x003C9 , 0x00314 },
- { 0x01F62 , 0x01F60 , 0x00300 },
- { 0x01F63 , 0x01F61 , 0x00300 },
- { 0x01F64 , 0x01F60 , 0x00301 },
- { 0x01F65 , 0x01F61 , 0x00301 },
- { 0x01F66 , 0x01F60 , 0x00342 },
- { 0x01F67 , 0x01F61 , 0x00342 },
- { 0x01F68 , 0x003A9 , 0x00313 },
- { 0x01F69 , 0x003A9 , 0x00314 },
- { 0x01F6A , 0x01F68 , 0x00300 },
- { 0x01F6B , 0x01F69 , 0x00300 },
- { 0x01F6C , 0x01F68 , 0x00301 },
- { 0x01F6D , 0x01F69 , 0x00301 },
- { 0x01F6E , 0x01F68 , 0x00342 },
- { 0x01F6F , 0x01F69 , 0x00342 },
- { 0x01F70 , 0x003B1 , 0x00300 },
- { 0x01F72 , 0x003B5 , 0x00300 },
- { 0x01F74 , 0x003B7 , 0x00300 },
- { 0x01F76 , 0x003B9 , 0x00300 },
- { 0x01F78 , 0x003BF , 0x00300 },
- { 0x01F7A , 0x003C5 , 0x00300 },
- { 0x01F7C , 0x003C9 , 0x00300 },
- { 0x01F80 , 0x01F00 , 0x00345 },
- { 0x01F81 , 0x01F01 , 0x00345 },
- { 0x01F82 , 0x01F02 , 0x00345 },
- { 0x01F83 , 0x01F03 , 0x00345 },
- { 0x01F84 , 0x01F04 , 0x00345 },
- { 0x01F85 , 0x01F05 , 0x00345 },
- { 0x01F86 , 0x01F06 , 0x00345 },
- { 0x01F87 , 0x01F07 , 0x00345 },
- { 0x01F88 , 0x01F08 , 0x00345 },
- { 0x01F89 , 0x01F09 , 0x00345 },
- { 0x01F8A , 0x01F0A , 0x00345 },
- { 0x01F8B , 0x01F0B , 0x00345 },
- { 0x01F8C , 0x01F0C , 0x00345 },
- { 0x01F8D , 0x01F0D , 0x00345 },
- { 0x01F8E , 0x01F0E , 0x00345 },
- { 0x01F8F , 0x01F0F , 0x00345 },
- { 0x01F90 , 0x01F20 , 0x00345 },
- { 0x01F91 , 0x01F21 , 0x00345 },
- { 0x01F92 , 0x01F22 , 0x00345 },
- { 0x01F93 , 0x01F23 , 0x00345 },
- { 0x01F94 , 0x01F24 , 0x00345 },
- { 0x01F95 , 0x01F25 , 0x00345 },
- { 0x01F96 , 0x01F26 , 0x00345 },
- { 0x01F97 , 0x01F27 , 0x00345 },
- { 0x01F98 , 0x01F28 , 0x00345 },
- { 0x01F99 , 0x01F29 , 0x00345 },
- { 0x01F9A , 0x01F2A , 0x00345 },
- { 0x01F9B , 0x01F2B , 0x00345 },
- { 0x01F9C , 0x01F2C , 0x00345 },
- { 0x01F9D , 0x01F2D , 0x00345 },
- { 0x01F9E , 0x01F2E , 0x00345 },
- { 0x01F9F , 0x01F2F , 0x00345 },
- { 0x01FA0 , 0x01F60 , 0x00345 },
- { 0x01FA1 , 0x01F61 , 0x00345 },
- { 0x01FA2 , 0x01F62 , 0x00345 },
- { 0x01FA3 , 0x01F63 , 0x00345 },
- { 0x01FA4 , 0x01F64 , 0x00345 },
- { 0x01FA5 , 0x01F65 , 0x00345 },
- { 0x01FA6 , 0x01F66 , 0x00345 },
- { 0x01FA7 , 0x01F67 , 0x00345 },
- { 0x01FA8 , 0x01F68 , 0x00345 },
- { 0x01FA9 , 0x01F69 , 0x00345 },
- { 0x01FAA , 0x01F6A , 0x00345 },
- { 0x01FAB , 0x01F6B , 0x00345 },
- { 0x01FAC , 0x01F6C , 0x00345 },
- { 0x01FAD , 0x01F6D , 0x00345 },
- { 0x01FAE , 0x01F6E , 0x00345 },
- { 0x01FAF , 0x01F6F , 0x00345 },
- { 0x01FB0 , 0x003B1 , 0x00306 },
- { 0x01FB1 , 0x003B1 , 0x00304 },
- { 0x01FB2 , 0x01F70 , 0x00345 },
- { 0x01FB3 , 0x003B1 , 0x00345 },
- { 0x01FB4 , 0x003AC , 0x00345 },
- { 0x01FB6 , 0x003B1 , 0x00342 },
- { 0x01FB7 , 0x01FB6 , 0x00345 },
- { 0x01FB8 , 0x00391 , 0x00306 },
- { 0x01FB9 , 0x00391 , 0x00304 },
- { 0x01FBA , 0x00391 , 0x00300 },
- { 0x01FBC , 0x00391 , 0x00345 },
- { 0x01FC1 , 0x000A8 , 0x00342 },
- { 0x01FC2 , 0x01F74 , 0x00345 },
- { 0x01FC3 , 0x003B7 , 0x00345 },
- { 0x01FC4 , 0x003AE , 0x00345 },
- { 0x01FC6 , 0x003B7 , 0x00342 },
- { 0x01FC7 , 0x01FC6 , 0x00345 },
- { 0x01FC8 , 0x00395 , 0x00300 },
- { 0x01FCA , 0x00397 , 0x00300 },
- { 0x01FCC , 0x00397 , 0x00345 },
- { 0x01FCD , 0x01FBF , 0x00300 },
- { 0x01FCE , 0x01FBF , 0x00301 },
- { 0x01FCF , 0x01FBF , 0x00342 },
- { 0x01FD0 , 0x003B9 , 0x00306 },
- { 0x01FD1 , 0x003B9 , 0x00304 },
- { 0x01FD2 , 0x003CA , 0x00300 },
- { 0x01FD6 , 0x003B9 , 0x00342 },
- { 0x01FD7 , 0x003CA , 0x00342 },
- { 0x01FD8 , 0x00399 , 0x00306 },
- { 0x01FD9 , 0x00399 , 0x00304 },
- { 0x01FDA , 0x00399 , 0x00300 },
- { 0x01FDD , 0x01FFE , 0x00300 },
- { 0x01FDE , 0x01FFE , 0x00301 },
- { 0x01FDF , 0x01FFE , 0x00342 },
- { 0x01FE0 , 0x003C5 , 0x00306 },
- { 0x01FE1 , 0x003C5 , 0x00304 },
- { 0x01FE2 , 0x003CB , 0x00300 },
- { 0x01FE4 , 0x003C1 , 0x00313 },
- { 0x01FE5 , 0x003C1 , 0x00314 },
- { 0x01FE6 , 0x003C5 , 0x00342 },
- { 0x01FE7 , 0x003CB , 0x00342 },
- { 0x01FE8 , 0x003A5 , 0x00306 },
- { 0x01FE9 , 0x003A5 , 0x00304 },
- { 0x01FEA , 0x003A5 , 0x00300 },
- { 0x01FEC , 0x003A1 , 0x00314 },
- { 0x01FED , 0x000A8 , 0x00300 },
- { 0x01FF2 , 0x01F7C , 0x00345 },
- { 0x01FF3 , 0x003C9 , 0x00345 },
- { 0x01FF4 , 0x003CE , 0x00345 },
- { 0x01FF6 , 0x003C9 , 0x00342 },
- { 0x01FF7 , 0x01FF6 , 0x00345 },
- { 0x01FF8 , 0x0039F , 0x00300 },
- { 0x01FFA , 0x003A9 , 0x00300 },
- { 0x01FFC , 0x003A9 , 0x00345 },
- { 0x0219A , 0x02190 , 0x00338 },
- { 0x0219B , 0x02192 , 0x00338 },
- { 0x021AE , 0x02194 , 0x00338 },
- { 0x021CD , 0x021D0 , 0x00338 },
- { 0x021CE , 0x021D4 , 0x00338 },
- { 0x021CF , 0x021D2 , 0x00338 },
- { 0x02204 , 0x02203 , 0x00338 },
- { 0x02209 , 0x02208 , 0x00338 },
- { 0x0220C , 0x0220B , 0x00338 },
- { 0x02224 , 0x02223 , 0x00338 },
- { 0x02226 , 0x02225 , 0x00338 },
- { 0x02241 , 0x0223C , 0x00338 },
- { 0x02244 , 0x02243 , 0x00338 },
- { 0x02247 , 0x02245 , 0x00338 },
- { 0x02249 , 0x02248 , 0x00338 },
- { 0x02260 , 0x0003D , 0x00338 },
- { 0x02262 , 0x02261 , 0x00338 },
- { 0x0226D , 0x0224D , 0x00338 },
- { 0x0226E , 0x0003C , 0x00338 },
- { 0x0226F , 0x0003E , 0x00338 },
- { 0x02270 , 0x02264 , 0x00338 },
- { 0x02271 , 0x02265 , 0x00338 },
- { 0x02274 , 0x02272 , 0x00338 },
- { 0x02275 , 0x02273 , 0x00338 },
- { 0x02278 , 0x02276 , 0x00338 },
- { 0x02279 , 0x02277 , 0x00338 },
- { 0x02280 , 0x0227A , 0x00338 },
- { 0x02281 , 0x0227B , 0x00338 },
- { 0x02284 , 0x02282 , 0x00338 },
- { 0x02285 , 0x02283 , 0x00338 },
- { 0x02288 , 0x02286 , 0x00338 },
- { 0x02289 , 0x02287 , 0x00338 },
- { 0x022AC , 0x022A2 , 0x00338 },
- { 0x022AD , 0x022A8 , 0x00338 },
- { 0x022AE , 0x022A9 , 0x00338 },
- { 0x022AF , 0x022AB , 0x00338 },
- { 0x022E0 , 0x0227C , 0x00338 },
- { 0x022E1 , 0x0227D , 0x00338 },
- { 0x022E2 , 0x02291 , 0x00338 },
- { 0x022E3 , 0x02292 , 0x00338 },
- { 0x022EA , 0x022B2 , 0x00338 },
- { 0x022EB , 0x022B3 , 0x00338 },
- { 0x022EC , 0x022B4 , 0x00338 },
- { 0x022ED , 0x022B5 , 0x00338 },
- { 0x0304C , 0x0304B , 0x03099 },
- { 0x0304E , 0x0304D , 0x03099 },
- { 0x03050 , 0x0304F , 0x03099 },
- { 0x03052 , 0x03051 , 0x03099 },
- { 0x03054 , 0x03053 , 0x03099 },
- { 0x03056 , 0x03055 , 0x03099 },
- { 0x03058 , 0x03057 , 0x03099 },
- { 0x0305A , 0x03059 , 0x03099 },
- { 0x0305C , 0x0305B , 0x03099 },
- { 0x0305E , 0x0305D , 0x03099 },
- { 0x03060 , 0x0305F , 0x03099 },
- { 0x03062 , 0x03061 , 0x03099 },
- { 0x03065 , 0x03064 , 0x03099 },
- { 0x03067 , 0x03066 , 0x03099 },
- { 0x03069 , 0x03068 , 0x03099 },
- { 0x03070 , 0x0306F , 0x03099 },
- { 0x03071 , 0x0306F , 0x0309A },
- { 0x03073 , 0x03072 , 0x03099 },
- { 0x03074 , 0x03072 , 0x0309A },
- { 0x03076 , 0x03075 , 0x03099 },
- { 0x03077 , 0x03075 , 0x0309A },
- { 0x03079 , 0x03078 , 0x03099 },
- { 0x0307A , 0x03078 , 0x0309A },
- { 0x0307C , 0x0307B , 0x03099 },
- { 0x0307D , 0x0307B , 0x0309A },
- { 0x03094 , 0x03046 , 0x03099 },
- { 0x0309E , 0x0309D , 0x03099 },
- { 0x030AC , 0x030AB , 0x03099 },
- { 0x030AE , 0x030AD , 0x03099 },
- { 0x030B0 , 0x030AF , 0x03099 },
- { 0x030B2 , 0x030B1 , 0x03099 },
- { 0x030B4 , 0x030B3 , 0x03099 },
- { 0x030B6 , 0x030B5 , 0x03099 },
- { 0x030B8 , 0x030B7 , 0x03099 },
- { 0x030BA , 0x030B9 , 0x03099 },
- { 0x030BC , 0x030BB , 0x03099 },
- { 0x030BE , 0x030BD , 0x03099 },
- { 0x030C0 , 0x030BF , 0x03099 },
- { 0x030C2 , 0x030C1 , 0x03099 },
- { 0x030C5 , 0x030C4 , 0x03099 },
- { 0x030C7 , 0x030C6 , 0x03099 },
- { 0x030C9 , 0x030C8 , 0x03099 },
- { 0x030D0 , 0x030CF , 0x03099 },
- { 0x030D1 , 0x030CF , 0x0309A },
- { 0x030D3 , 0x030D2 , 0x03099 },
- { 0x030D4 , 0x030D2 , 0x0309A },
- { 0x030D6 , 0x030D5 , 0x03099 },
- { 0x030D7 , 0x030D5 , 0x0309A },
- { 0x030D9 , 0x030D8 , 0x03099 },
- { 0x030DA , 0x030D8 , 0x0309A },
- { 0x030DC , 0x030DB , 0x03099 },
- { 0x030DD , 0x030DB , 0x0309A },
- { 0x030F4 , 0x030A6 , 0x03099 },
- { 0x030F7 , 0x030EF , 0x03099 },
- { 0x030F8 , 0x030F0 , 0x03099 },
- { 0x030F9 , 0x030F1 , 0x03099 },
- { 0x030FA , 0x030F2 , 0x03099 },
- { 0x030FE , 0x030FD , 0x03099 },
- { 0x1109A , 0x11099 , 0x110BA },
- { 0x1109C , 0x1109B , 0x110BA },
- { 0x110AB , 0x110A5 , 0x110BA },
-};
-
-#endif /* ARCHIVE_STRING_COMPOSITION_H_INCLUDED */
-
diff --git a/contrib/libs/libarchive/libarchive/archive_string_sprintf.c b/contrib/libs/libarchive/libarchive/archive_string_sprintf.c
deleted file mode 100644
index 969a5603a4..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_string_sprintf.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_string_sprintf.c 189435 2009-03-06 05:14:55Z kientzle $");
-
-/*
- * The use of printf()-family functions can be troublesome
- * for space-constrained applications. In addition, correctly
- * implementing this function in terms of vsnprintf() requires
- * two calls (one to determine the size, another to format the
- * result), which in turn requires duplicating the argument list
- * using va_copy, which isn't yet universally available. <sigh>
- *
- * So, I've implemented a bare minimum of printf()-like capability
- * here. This is only used to format error messages, so doesn't
- * require any floating-point support or field-width handling.
- */
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stdio.h>
-
-#include "archive_string.h"
-#include "archive_private.h"
-
-/*
- * Utility functions to format signed/unsigned integers and append
- * them to an archive_string.
- */
-static void
-append_uint(struct archive_string *as, uintmax_t d, unsigned base)
-{
- static const char digits[] = "0123456789abcdef";
- if (d >= base)
- append_uint(as, d/base, base);
- archive_strappend_char(as, digits[d % base]);
-}
-
-static void
-append_int(struct archive_string *as, intmax_t d, unsigned base)
-{
- uintmax_t ud;
-
- if (d < 0) {
- archive_strappend_char(as, '-');
- ud = (d == INTMAX_MIN) ? (uintmax_t)(INTMAX_MAX) + 1 : (uintmax_t)(-d);
- } else
- ud = d;
- append_uint(as, ud, base);
-}
-
-
-void
-archive_string_sprintf(struct archive_string *as, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- archive_string_vsprintf(as, fmt, ap);
- va_end(ap);
-}
-
-/*
- * Like 'vsprintf', but ensures the target is big enough, resizing if
- * necessary.
- */
-void
-archive_string_vsprintf(struct archive_string *as, const char *fmt,
- va_list ap)
-{
- char long_flag;
- intmax_t s; /* Signed integer temp. */
- uintmax_t u; /* Unsigned integer temp. */
- const char *p, *p2;
- const wchar_t *pw;
-
- if (archive_string_ensure(as, 64) == NULL)
- __archive_errx(1, "Out of memory");
-
- if (fmt == NULL) {
- as->s[0] = 0;
- return;
- }
-
- for (p = fmt; *p != '\0'; p++) {
- const char *saved_p = p;
-
- if (*p != '%') {
- archive_strappend_char(as, *p);
- continue;
- }
-
- p++;
-
- long_flag = '\0';
- switch(*p) {
- case 'j':
- case 'l':
- case 'z':
- long_flag = *p;
- p++;
- break;
- }
-
- switch (*p) {
- case '%':
- archive_strappend_char(as, '%');
- break;
- case 'c':
- s = va_arg(ap, int);
- archive_strappend_char(as, (char)s);
- break;
- case 'd':
- switch(long_flag) {
- case 'j': s = va_arg(ap, intmax_t); break;
- case 'l': s = va_arg(ap, long); break;
- case 'z': s = va_arg(ap, ssize_t); break;
- default: s = va_arg(ap, int); break;
- }
- append_int(as, s, 10);
- break;
- case 's':
- switch(long_flag) {
- case 'l':
- pw = va_arg(ap, wchar_t *);
- if (pw == NULL)
- pw = L"(null)";
- if (archive_string_append_from_wcs(as, pw,
- wcslen(pw)) != 0 && errno == ENOMEM)
- __archive_errx(1, "Out of memory");
- break;
- default:
- p2 = va_arg(ap, char *);
- if (p2 == NULL)
- p2 = "(null)";
- archive_strcat(as, p2);
- break;
- }
- break;
- case 'S':
- pw = va_arg(ap, wchar_t *);
- if (pw == NULL)
- pw = L"(null)";
- if (archive_string_append_from_wcs(as, pw,
- wcslen(pw)) != 0 && errno == ENOMEM)
- __archive_errx(1, "Out of memory");
- break;
- case 'o': case 'u': case 'x': case 'X':
- /* Common handling for unsigned integer formats. */
- switch(long_flag) {
- case 'j': u = va_arg(ap, uintmax_t); break;
- case 'l': u = va_arg(ap, unsigned long); break;
- case 'z': u = va_arg(ap, size_t); break;
- default: u = va_arg(ap, unsigned int); break;
- }
- /* Format it in the correct base. */
- switch (*p) {
- case 'o': append_uint(as, u, 8); break;
- case 'u': append_uint(as, u, 10); break;
- default: append_uint(as, u, 16); break;
- }
- break;
- default:
- /* Rewind and print the initial '%' literally. */
- p = saved_p;
- archive_strappend_char(as, *p);
- }
- }
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_util.c b/contrib/libs/libarchive/libarchive/archive_util.c
deleted file mode 100644
index 0fd344d05b..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_util.c
+++ /dev/null
@@ -1,704 +0,0 @@
-/*-
- * Copyright (c) 2009-2012,2014 Michihiro NAKAJIMA
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:14Z kientzle $");
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
-/* don't use bcrypt when XP needs to be supported */
-#include <bcrypt.h>
-
-/* Common in other bcrypt implementations, but missing from VS2008. */
-#ifndef BCRYPT_SUCCESS
-#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
-#endif
-
-#elif defined(HAVE_WINCRYPT_H)
-#include <wincrypt.h>
-#endif
-#endif
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-#ifdef HAVE_LZMA_H
-#error #include <lzma.h>
-#endif
-#ifdef HAVE_BZLIB_H
-#include <bzlib.h>
-#endif
-#ifdef HAVE_LZ4_H
-#include <lz4.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_random_private.h"
-#include "archive_string.h"
-
-#ifndef O_CLOEXEC
-#define O_CLOEXEC 0
-#endif
-
-static int archive_utility_string_sort_helper(char **, unsigned int);
-
-/* Generic initialization of 'struct archive' objects. */
-int
-__archive_clean(struct archive *a)
-{
- archive_string_conversion_free(a);
- return (ARCHIVE_OK);
-}
-
-int
-archive_version_number(void)
-{
- return (ARCHIVE_VERSION_NUMBER);
-}
-
-const char *
-archive_version_string(void)
-{
- return (ARCHIVE_VERSION_STRING);
-}
-
-int
-archive_errno(struct archive *a)
-{
- return (a->archive_error_number);
-}
-
-const char *
-archive_error_string(struct archive *a)
-{
-
- if (a->error != NULL && *a->error != '\0')
- return (a->error);
- else
- return (NULL);
-}
-
-int
-archive_file_count(struct archive *a)
-{
- return (a->file_count);
-}
-
-int
-archive_format(struct archive *a)
-{
- return (a->archive_format);
-}
-
-const char *
-archive_format_name(struct archive *a)
-{
- return (a->archive_format_name);
-}
-
-
-int
-archive_compression(struct archive *a)
-{
- return archive_filter_code(a, 0);
-}
-
-const char *
-archive_compression_name(struct archive *a)
-{
- return archive_filter_name(a, 0);
-}
-
-
-/*
- * Return a count of the number of compressed bytes processed.
- */
-la_int64_t
-archive_position_compressed(struct archive *a)
-{
- return archive_filter_bytes(a, -1);
-}
-
-/*
- * Return a count of the number of uncompressed bytes processed.
- */
-la_int64_t
-archive_position_uncompressed(struct archive *a)
-{
- return archive_filter_bytes(a, 0);
-}
-
-void
-archive_clear_error(struct archive *a)
-{
- archive_string_empty(&a->error_string);
- a->error = NULL;
- a->archive_error_number = 0;
-}
-
-void
-archive_set_error(struct archive *a, int error_number, const char *fmt, ...)
-{
- va_list ap;
-
- a->archive_error_number = error_number;
- if (fmt == NULL) {
- a->error = NULL;
- return;
- }
-
- archive_string_empty(&(a->error_string));
- va_start(ap, fmt);
- archive_string_vsprintf(&(a->error_string), fmt, ap);
- va_end(ap);
- a->error = a->error_string.s;
-}
-
-void
-archive_copy_error(struct archive *dest, struct archive *src)
-{
- dest->archive_error_number = src->archive_error_number;
-
- archive_string_copy(&dest->error_string, &src->error_string);
- dest->error = dest->error_string.s;
-}
-
-void
-__archive_errx(int retvalue, const char *msg)
-{
- static const char msg1[] = "Fatal Internal Error in libarchive: ";
- size_t s;
-
- s = write(2, msg1, strlen(msg1));
- (void)s; /* UNUSED */
- s = write(2, msg, strlen(msg));
- (void)s; /* UNUSED */
- s = write(2, "\n", 1);
- (void)s; /* UNUSED */
- exit(retvalue);
-}
-
-/*
- * Create a temporary file
- */
-#if defined(_WIN32) && !defined(__CYGWIN__)
-
-/*
- * Do not use Windows tmpfile() function.
- * It will make a temporary file under the root directory
- * and it'll cause permission error if a user who is
- * non-Administrator creates temporary files.
- * Also Windows version of mktemp family including _mktemp_s
- * are not secure.
- */
-static int
-__archive_mktempx(const char *tmpdir, wchar_t *template)
-{
- static const wchar_t prefix[] = L"libarchive_";
- static const wchar_t suffix[] = L"XXXXXXXXXX";
- static const wchar_t num[] = {
- L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
- L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F',
- L'G', L'H', L'I', L'J', L'K', L'L', L'M', L'N',
- L'O', L'P', L'Q', L'R', L'S', L'T', L'U', L'V',
- L'W', L'X', L'Y', L'Z', L'a', L'b', L'c', L'd',
- L'e', L'f', L'g', L'h', L'i', L'j', L'k', L'l',
- L'm', L'n', L'o', L'p', L'q', L'r', L's', L't',
- L'u', L'v', L'w', L'x', L'y', L'z'
- };
- struct archive_wstring temp_name;
- wchar_t *ws;
- DWORD attr;
- wchar_t *xp, *ep;
- int fd;
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
- BCRYPT_ALG_HANDLE hAlg = NULL;
-#else
- HCRYPTPROV hProv = (HCRYPTPROV)NULL;
-#endif
- fd = -1;
- ws = NULL;
-
- if (template == NULL) {
- archive_string_init(&temp_name);
-
- /* Get a temporary directory. */
- if (tmpdir == NULL) {
- size_t l;
- wchar_t *tmp;
-
- l = GetTempPathW(0, NULL);
- if (l == 0) {
- la_dosmaperr(GetLastError());
- goto exit_tmpfile;
- }
- tmp = malloc(l*sizeof(wchar_t));
- if (tmp == NULL) {
- errno = ENOMEM;
- goto exit_tmpfile;
- }
- GetTempPathW((DWORD)l, tmp);
- archive_wstrcpy(&temp_name, tmp);
- free(tmp);
- } else {
- if (archive_wstring_append_from_mbs(&temp_name, tmpdir,
- strlen(tmpdir)) < 0)
- goto exit_tmpfile;
- if (temp_name.s[temp_name.length-1] != L'/')
- archive_wstrappend_wchar(&temp_name, L'/');
- }
-
- /* Check if temp_name is a directory. */
- attr = GetFileAttributesW(temp_name.s);
- if (attr == (DWORD)-1) {
- if (GetLastError() != ERROR_FILE_NOT_FOUND) {
- la_dosmaperr(GetLastError());
- goto exit_tmpfile;
- }
- ws = __la_win_permissive_name_w(temp_name.s);
- if (ws == NULL) {
- errno = EINVAL;
- goto exit_tmpfile;
- }
- attr = GetFileAttributesW(ws);
- if (attr == (DWORD)-1) {
- la_dosmaperr(GetLastError());
- goto exit_tmpfile;
- }
- }
- if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
- errno = ENOTDIR;
- goto exit_tmpfile;
- }
-
- /*
- * Create a temporary file.
- */
- archive_wstrcat(&temp_name, prefix);
- archive_wstrcat(&temp_name, suffix);
- ep = temp_name.s + archive_strlen(&temp_name);
- xp = ep - wcslen(suffix);
- template = temp_name.s;
- } else {
- xp = wcschr(template, L'X');
- if (xp == NULL) /* No X, programming error */
- abort();
- for (ep = xp; *ep == L'X'; ep++)
- continue;
- if (*ep) /* X followed by non X, programming error */
- abort();
- }
-
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
- if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM,
- NULL, 0))) {
- la_dosmaperr(GetLastError());
- goto exit_tmpfile;
- }
-#else
- if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT)) {
- la_dosmaperr(GetLastError());
- goto exit_tmpfile;
- }
-#endif
-
- for (;;) {
- wchar_t *p;
- HANDLE h;
-# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- CREATEFILE2_EXTENDED_PARAMETERS createExParams;
-#endif
-
- /* Generate a random file name through CryptGenRandom(). */
- p = xp;
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
- if (!BCRYPT_SUCCESS(BCryptGenRandom(hAlg, (PUCHAR)p,
- (DWORD)(ep - p)*sizeof(wchar_t), 0))) {
- la_dosmaperr(GetLastError());
- goto exit_tmpfile;
- }
-#else
- if (!CryptGenRandom(hProv, (DWORD)(ep - p)*sizeof(wchar_t),
- (BYTE*)p)) {
- la_dosmaperr(GetLastError());
- goto exit_tmpfile;
- }
-#endif
- for (; p < ep; p++)
- *p = num[((DWORD)*p) % (sizeof(num)/sizeof(num[0]))];
-
- free(ws);
- ws = __la_win_permissive_name_w(template);
- if (ws == NULL) {
- errno = EINVAL;
- goto exit_tmpfile;
- }
- if (template == temp_name.s) {
- attr = FILE_ATTRIBUTE_TEMPORARY |
- FILE_FLAG_DELETE_ON_CLOSE;
- } else {
- /* mkstemp */
- attr = FILE_ATTRIBUTE_NORMAL;
- }
-# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- ZeroMemory(&createExParams, sizeof(createExParams));
- createExParams.dwSize = sizeof(createExParams);
- createExParams.dwFileAttributes = attr & 0xFFFF;
- createExParams.dwFileFlags = attr & 0xFFF00000;
- h = CreateFile2(ws,
- GENERIC_READ | GENERIC_WRITE | DELETE,
- 0,/* Not share */
- CREATE_NEW,
- &createExParams);
-#else
- h = CreateFileW(ws,
- GENERIC_READ | GENERIC_WRITE | DELETE,
- 0,/* Not share */
- NULL,
- CREATE_NEW,/* Create a new file only */
- attr,
- NULL);
-#endif
- if (h == INVALID_HANDLE_VALUE) {
- /* The same file already exists. retry with
- * a new filename. */
- if (GetLastError() == ERROR_FILE_EXISTS)
- continue;
- /* Otherwise, fail creation temporary file. */
- la_dosmaperr(GetLastError());
- goto exit_tmpfile;
- }
- fd = _open_osfhandle((intptr_t)h, _O_BINARY | _O_RDWR);
- if (fd == -1) {
- la_dosmaperr(GetLastError());
- CloseHandle(h);
- goto exit_tmpfile;
- } else
- break;/* success! */
- }
-exit_tmpfile:
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
- if (hAlg != NULL)
- BCryptCloseAlgorithmProvider(hAlg, 0);
-#else
- if (hProv != (HCRYPTPROV)NULL)
- CryptReleaseContext(hProv, 0);
-#endif
- free(ws);
- if (template == temp_name.s)
- archive_wstring_free(&temp_name);
- return (fd);
-}
-
-int
-__archive_mktemp(const char *tmpdir)
-{
- return __archive_mktempx(tmpdir, NULL);
-}
-
-int
-__archive_mkstemp(wchar_t *template)
-{
- return __archive_mktempx(NULL, template);
-}
-
-#else
-
-static int
-get_tempdir(struct archive_string *temppath)
-{
- const char *tmp;
-
- tmp = getenv("TMPDIR");
- if (tmp == NULL)
-#ifdef _PATH_TMP
- tmp = _PATH_TMP;
-#else
- tmp = "/tmp";
-#endif
- archive_strcpy(temppath, tmp);
- if (temppath->s[temppath->length-1] != '/')
- archive_strappend_char(temppath, '/');
- return (ARCHIVE_OK);
-}
-
-#if defined(HAVE_MKSTEMP)
-
-/*
- * We can use mkstemp().
- */
-
-int
-__archive_mktemp(const char *tmpdir)
-{
- struct archive_string temp_name;
- int fd = -1;
-
- archive_string_init(&temp_name);
- if (tmpdir == NULL) {
- if (get_tempdir(&temp_name) != ARCHIVE_OK)
- goto exit_tmpfile;
- } else {
- archive_strcpy(&temp_name, tmpdir);
- if (temp_name.s[temp_name.length-1] != '/')
- archive_strappend_char(&temp_name, '/');
- }
-#ifdef O_TMPFILE
- fd = open(temp_name.s, O_RDWR|O_CLOEXEC|O_TMPFILE|O_EXCL, 0600);
- if(fd >= 0)
- goto exit_tmpfile;
-#endif
- archive_strcat(&temp_name, "libarchive_XXXXXX");
- fd = mkstemp(temp_name.s);
- if (fd < 0)
- goto exit_tmpfile;
- __archive_ensure_cloexec_flag(fd);
- unlink(temp_name.s);
-exit_tmpfile:
- archive_string_free(&temp_name);
- return (fd);
-}
-
-int
-__archive_mkstemp(char *template)
-{
- int fd = -1;
- fd = mkstemp(template);
- if (fd >= 0)
- __archive_ensure_cloexec_flag(fd);
- return (fd);
-}
-
-#else /* !HAVE_MKSTEMP */
-
-/*
- * We use a private routine.
- */
-
-static int
-__archive_mktempx(const char *tmpdir, char *template)
-{
- static const char num[] = {
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
- 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
- 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
- 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
- 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
- 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
- 'u', 'v', 'w', 'x', 'y', 'z'
- };
- struct archive_string temp_name;
- struct stat st;
- int fd;
- char *tp, *ep;
-
- fd = -1;
- if (template == NULL) {
- archive_string_init(&temp_name);
- if (tmpdir == NULL) {
- if (get_tempdir(&temp_name) != ARCHIVE_OK)
- goto exit_tmpfile;
- } else
- archive_strcpy(&temp_name, tmpdir);
- if (temp_name.s[temp_name.length-1] == '/') {
- temp_name.s[temp_name.length-1] = '\0';
- temp_name.length --;
- }
- if (la_stat(temp_name.s, &st) < 0)
- goto exit_tmpfile;
- if (!S_ISDIR(st.st_mode)) {
- errno = ENOTDIR;
- goto exit_tmpfile;
- }
- archive_strcat(&temp_name, "/libarchive_");
- tp = temp_name.s + archive_strlen(&temp_name);
- archive_strcat(&temp_name, "XXXXXXXXXX");
- ep = temp_name.s + archive_strlen(&temp_name);
- template = temp_name.s;
- } else {
- tp = strchr(template, 'X');
- if (tp == NULL) /* No X, programming error */
- abort();
- for (ep = tp; *ep == 'X'; ep++)
- continue;
- if (*ep) /* X followed by non X, programming error */
- abort();
- }
-
- do {
- char *p;
-
- p = tp;
- archive_random(p, ep - p);
- while (p < ep) {
- int d = *((unsigned char *)p) % sizeof(num);
- *p++ = num[d];
- }
- fd = open(template, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC,
- 0600);
- } while (fd < 0 && errno == EEXIST);
- if (fd < 0)
- goto exit_tmpfile;
- __archive_ensure_cloexec_flag(fd);
- if (template == temp_name.s)
- unlink(temp_name.s);
-exit_tmpfile:
- if (template == temp_name.s)
- archive_string_free(&temp_name);
- return (fd);
-}
-
-int
-__archive_mktemp(const char *tmpdir)
-{
- return __archive_mktempx(tmpdir, NULL);
-}
-
-int
-__archive_mkstemp(char *template)
-{
- return __archive_mktempx(NULL, template);
-}
-
-#endif /* !HAVE_MKSTEMP */
-#endif /* !_WIN32 || __CYGWIN__ */
-
-/*
- * Set FD_CLOEXEC flag to a file descriptor if it is not set.
- * We have to set the flag if the platform does not provide O_CLOEXEC
- * or F_DUPFD_CLOEXEC flags.
- *
- * Note: This function is absolutely called after creating a new file
- * descriptor even if the platform seemingly provides O_CLOEXEC or
- * F_DUPFD_CLOEXEC macros because it is possible that the platform
- * merely declares those macros, especially Linux 2.6.18 - 2.6.24 do it.
- */
-void
-__archive_ensure_cloexec_flag(int fd)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- (void)fd; /* UNUSED */
-#else
- int flags;
-
- if (fd >= 0) {
- flags = fcntl(fd, F_GETFD);
- if (flags != -1 && (flags & FD_CLOEXEC) == 0)
- fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
- }
-#endif
-}
-
-/*
- * Utility function to sort a group of strings using quicksort.
- */
-static int
-archive_utility_string_sort_helper(char **strings, unsigned int n)
-{
- unsigned int i, lesser_count, greater_count;
- char **lesser, **greater, **tmp, *pivot;
- int retval1, retval2;
-
- /* A list of 0 or 1 elements is already sorted */
- if (n <= 1)
- return (ARCHIVE_OK);
-
- lesser_count = greater_count = 0;
- lesser = greater = NULL;
- pivot = strings[0];
- for (i = 1; i < n; i++)
- {
- if (strcmp(strings[i], pivot) < 0)
- {
- lesser_count++;
- tmp = (char **)realloc(lesser,
- lesser_count * sizeof(char *));
- if (!tmp) {
- free(greater);
- free(lesser);
- return (ARCHIVE_FATAL);
- }
- lesser = tmp;
- lesser[lesser_count - 1] = strings[i];
- }
- else
- {
- greater_count++;
- tmp = (char **)realloc(greater,
- greater_count * sizeof(char *));
- if (!tmp) {
- free(greater);
- free(lesser);
- return (ARCHIVE_FATAL);
- }
- greater = tmp;
- greater[greater_count - 1] = strings[i];
- }
- }
-
- /* quicksort(lesser) */
- retval1 = archive_utility_string_sort_helper(lesser, lesser_count);
- for (i = 0; i < lesser_count; i++)
- strings[i] = lesser[i];
- free(lesser);
-
- /* pivot */
- strings[lesser_count] = pivot;
-
- /* quicksort(greater) */
- retval2 = archive_utility_string_sort_helper(greater, greater_count);
- for (i = 0; i < greater_count; i++)
- strings[lesser_count + 1 + i] = greater[i];
- free(greater);
-
- return (retval1 < retval2) ? retval1 : retval2;
-}
-
-int
-archive_utility_string_sort(char **strings)
-{
- unsigned int size = 0;
- while (strings[size] != NULL)
- size++;
- return archive_utility_string_sort_helper(strings, size);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_version_details.c b/contrib/libs/libarchive/libarchive/archive_version_details.c
deleted file mode 100644
index 2a143388fc..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_version_details.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*-
- * Copyright (c) 2009-2012,2014 Michihiro NAKAJIMA
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:14Z kientzle $");
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-#ifdef HAVE_LZMA_H
-#error #include <lzma.h>
-#endif
-#ifdef HAVE_BZLIB_H
-#include <bzlib.h>
-#endif
-#ifdef HAVE_LZ4_H
-#include <lz4.h>
-#endif
-#ifdef HAVE_ZSTD_H
-#include <zstd.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_string.h"
-
-const char *
-archive_version_details(void)
-{
- static struct archive_string str;
- static int init = 0;
- const char *zlib = archive_zlib_version();
- const char *liblzma = archive_liblzma_version();
- const char *bzlib = archive_bzlib_version();
- const char *liblz4 = archive_liblz4_version();
- const char *libzstd = archive_libzstd_version();
-
- if (!init) {
- archive_string_init(&str);
-
- archive_strcat(&str, ARCHIVE_VERSION_STRING);
- if (zlib != NULL) {
- archive_strcat(&str, " zlib/");
- archive_strcat(&str, zlib);
- }
- if (liblzma) {
- archive_strcat(&str, " liblzma/");
- archive_strcat(&str, liblzma);
- }
- if (bzlib) {
- const char *p = bzlib;
- const char *sep = strchr(p, ',');
- if (sep == NULL)
- sep = p + strlen(p);
- archive_strcat(&str, " bz2lib/");
- archive_strncat(&str, p, sep - p);
- }
- if (liblz4) {
- archive_strcat(&str, " liblz4/");
- archive_strcat(&str, liblz4);
- }
- if (libzstd) {
- archive_strcat(&str, " libzstd/");
- archive_strcat(&str, libzstd);
- }
- }
- return str.s;
-}
-
-const char *
-archive_zlib_version(void)
-{
-#ifdef HAVE_ZLIB_H
- return ZLIB_VERSION;
-#else
- return NULL;
-#endif
-}
-
-const char *
-archive_liblzma_version(void)
-{
-#ifdef HAVE_LZMA_H
- return LZMA_VERSION_STRING;
-#else
- return NULL;
-#endif
-}
-
-const char *
-archive_bzlib_version(void)
-{
-#ifdef HAVE_BZLIB_H
- return BZ2_bzlibVersion();
-#else
- return NULL;
-#endif
-}
-
-const char *
-archive_liblz4_version(void)
-{
-#if defined(HAVE_LZ4_H) && defined(HAVE_LIBLZ4)
-#define str(s) #s
-#define NUMBER(x) str(x)
- return NUMBER(LZ4_VERSION_MAJOR) "." NUMBER(LZ4_VERSION_MINOR) "." NUMBER(LZ4_VERSION_RELEASE);
-#undef NUMBER
-#undef str
-#else
- return NULL;
-#endif
-}
-
-const char *
-archive_libzstd_version(void)
-{
-#if HAVE_ZSTD_H && HAVE_LIBZSTD
- return ZSTD_VERSION_STRING;
-#else
- return NULL;
-#endif
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_virtual.c b/contrib/libs/libarchive/libarchive/archive_virtual.c
deleted file mode 100644
index f509ee5c67..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_virtual.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_virtual.c 201098 2009-12-28 02:58:14Z kientzle $");
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_private.h"
-
-int
-archive_filter_code(struct archive *a, int n)
-{
- return ((a->vtable->archive_filter_code)(a, n));
-}
-
-int
-archive_filter_count(struct archive *a)
-{
- return ((a->vtable->archive_filter_count)(a));
-}
-
-const char *
-archive_filter_name(struct archive *a, int n)
-{
- return ((a->vtable->archive_filter_name)(a, n));
-}
-
-la_int64_t
-archive_filter_bytes(struct archive *a, int n)
-{
- return ((a->vtable->archive_filter_bytes)(a, n));
-}
-
-int
-archive_free(struct archive *a)
-{
- if (a == NULL)
- return (ARCHIVE_OK);
- return ((a->vtable->archive_free)(a));
-}
-
-int
-archive_write_close(struct archive *a)
-{
- return ((a->vtable->archive_close)(a));
-}
-
-int
-archive_read_close(struct archive *a)
-{
- return ((a->vtable->archive_close)(a));
-}
-
-int
-archive_write_fail(struct archive *a)
-{
- a->state = ARCHIVE_STATE_FATAL;
- return a->state;
-}
-
-int
-archive_write_free(struct archive *a)
-{
- return archive_free(a);
-}
-
-#if ARCHIVE_VERSION_NUMBER < 4000000
-/* For backwards compatibility; will be removed with libarchive 4.0. */
-int
-archive_write_finish(struct archive *a)
-{
- return archive_write_free(a);
-}
-#endif
-
-int
-archive_read_free(struct archive *a)
-{
- return archive_free(a);
-}
-
-#if ARCHIVE_VERSION_NUMBER < 4000000
-/* For backwards compatibility; will be removed with libarchive 4.0. */
-int
-archive_read_finish(struct archive *a)
-{
- return archive_read_free(a);
-}
-#endif
-
-int
-archive_write_header(struct archive *a, struct archive_entry *entry)
-{
- ++a->file_count;
- return ((a->vtable->archive_write_header)(a, entry));
-}
-
-int
-archive_write_finish_entry(struct archive *a)
-{
- return ((a->vtable->archive_write_finish_entry)(a));
-}
-
-la_ssize_t
-archive_write_data(struct archive *a, const void *buff, size_t s)
-{
- return ((a->vtable->archive_write_data)(a, buff, s));
-}
-
-la_ssize_t
-archive_write_data_block(struct archive *a, const void *buff, size_t s,
- la_int64_t o)
-{
- if (a->vtable->archive_write_data_block == NULL) {
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "archive_write_data_block not supported");
- a->state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- }
- return ((a->vtable->archive_write_data_block)(a, buff, s, o));
-}
-
-int
-archive_read_next_header(struct archive *a, struct archive_entry **entry)
-{
- return ((a->vtable->archive_read_next_header)(a, entry));
-}
-
-int
-archive_read_next_header2(struct archive *a, struct archive_entry *entry)
-{
- return ((a->vtable->archive_read_next_header2)(a, entry));
-}
-
-int
-archive_read_data_block(struct archive *a,
- const void **buff, size_t *s, la_int64_t *o)
-{
- return ((a->vtable->archive_read_data_block)(a, buff, s, o));
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_windows.c b/contrib/libs/libarchive/libarchive/archive_windows.c
deleted file mode 100644
index ebc5eefb80..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_windows.c
+++ /dev/null
@@ -1,938 +0,0 @@
-/*-
- * Copyright (c) 2009-2011 Michihiro NAKAJIMA
- * Copyright (c) 2003-2007 Kees Zeelenberg
- * 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(S) ``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(S) 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.
- *
- * $FreeBSD$
- */
-
-/*
- * A set of compatibility glue for building libarchive on Windows platforms.
- *
- * Originally created as "libarchive-nonposix.c" by Kees Zeelenberg
- * for the GnuWin32 project, trimmed significantly by Tim Kientzle.
- *
- * Much of the original file was unnecessary for libarchive, because
- * many of the features it emulated were not strictly necessary for
- * libarchive. I hope for this to shrink further as libarchive
- * internals are gradually reworked to sit more naturally on both
- * POSIX and Windows. Any ideas for this are greatly appreciated.
- *
- * The biggest remaining issue is the dev/ino emulation; libarchive
- * has a couple of public APIs that rely on dev/ino uniquely
- * identifying a file. This doesn't match well with Windows. I'm
- * considering alternative APIs.
- */
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-
-#include "archive_platform.h"
-#include "archive_private.h"
-#include "archive_entry.h"
-#include <ctype.h>
-#include <errno.h>
-#include <stddef.h>
-#ifdef HAVE_SYS_UTIME_H
-#include <sys/utime.h>
-#endif
-#include <sys/stat.h>
-#include <locale.h>
-#include <process.h>
-#include <stdlib.h>
-#include <wchar.h>
-#include <windows.h>
-#include <share.h>
-
-#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
-
-#if defined(__LA_LSEEK_NEEDED)
-static BOOL SetFilePointerEx_perso(HANDLE hFile,
- LARGE_INTEGER liDistanceToMove,
- PLARGE_INTEGER lpNewFilePointer,
- DWORD dwMoveMethod)
-{
- LARGE_INTEGER li;
- li.QuadPart = liDistanceToMove.QuadPart;
- li.LowPart = SetFilePointer(
- hFile, li.LowPart, &li.HighPart, dwMoveMethod);
- if(lpNewFilePointer) {
- lpNewFilePointer->QuadPart = li.QuadPart;
- }
- return li.LowPart != -1 || GetLastError() == NO_ERROR;
-}
-#endif
-
-struct ustat {
- int64_t st_atime;
- uint32_t st_atime_nsec;
- int64_t st_ctime;
- uint32_t st_ctime_nsec;
- int64_t st_mtime;
- uint32_t st_mtime_nsec;
- gid_t st_gid;
- /* 64bits ino */
- int64_t st_ino;
- mode_t st_mode;
- uint32_t st_nlink;
- uint64_t st_size;
- uid_t st_uid;
- dev_t st_dev;
- dev_t st_rdev;
-};
-
-/* Transform 64-bits ino into 32-bits by hashing.
- * You do not forget that really unique number size is 64-bits.
- */
-#define INOSIZE (8*sizeof(ino_t)) /* 32 */
-static __inline ino_t
-getino(struct ustat *ub)
-{
- ULARGE_INTEGER ino64;
- ino64.QuadPart = ub->st_ino;
- /* I don't know this hashing is correct way */
- return ((ino_t)(ino64.LowPart ^ (ino64.LowPart >> INOSIZE)));
-}
-
-/*
- * Prepend "\\?\" to the path name and convert it to unicode to permit
- * an extended-length path for a maximum total path length of 32767
- * characters.
- * see also http://msdn.microsoft.com/en-us/library/aa365247.aspx
- */
-wchar_t *
-__la_win_permissive_name(const char *name)
-{
- wchar_t *wn;
- wchar_t *ws;
- size_t ll;
-
- ll = strlen(name);
- wn = malloc((ll + 1) * sizeof(wchar_t));
- if (wn == NULL)
- return (NULL);
- ll = mbstowcs(wn, name, ll);
- if (ll == (size_t)-1) {
- free(wn);
- return (NULL);
- }
- wn[ll] = L'\0';
- ws = __la_win_permissive_name_w(wn);
- free(wn);
- return (ws);
-}
-
-wchar_t *
-__la_win_permissive_name_w(const wchar_t *wname)
-{
- wchar_t *wn, *wnp;
- wchar_t *ws, *wsp;
- DWORD l, len, slen;
- int unc;
-
- /* Get a full-pathname. */
- l = GetFullPathNameW(wname, 0, NULL, NULL);
- if (l == 0)
- return (NULL);
- /* NOTE: GetFullPathNameW has a bug that if the length of the file
- * name is just 1 then it returns incomplete buffer size. Thus, we
- * have to add three to the size to allocate a sufficient buffer
- * size for the full-pathname of the file name. */
- l += 3;
- wnp = malloc(l * sizeof(wchar_t));
- if (wnp == NULL)
- return (NULL);
- len = GetFullPathNameW(wname, l, wnp, NULL);
- wn = wnp;
-
- if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
- wnp[2] == L'?' && wnp[3] == L'\\')
- /* We have already a permissive name. */
- return (wn);
-
- if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
- wnp[2] == L'.' && wnp[3] == L'\\') {
- /* This is a device name */
- if (((wnp[4] >= L'a' && wnp[4] <= L'z') ||
- (wnp[4] >= L'A' && wnp[4] <= L'Z')) &&
- wnp[5] == L':' && wnp[6] == L'\\')
- wnp[2] = L'?';/* Not device name. */
- return (wn);
- }
-
- unc = 0;
- if (wnp[0] == L'\\' && wnp[1] == L'\\' && wnp[2] != L'\\') {
- wchar_t *p = &wnp[2];
-
- /* Skip server-name letters. */
- while (*p != L'\\' && *p != L'\0')
- ++p;
- if (*p == L'\\') {
- wchar_t *rp = ++p;
- /* Skip share-name letters. */
- while (*p != L'\\' && *p != L'\0')
- ++p;
- if (*p == L'\\' && p != rp) {
- /* Now, match patterns such as
- * "\\server-name\share-name\" */
- wnp += 2;
- len -= 2;
- unc = 1;
- }
- }
- }
-
- slen = 4 + (unc * 4) + len + 1;
- ws = wsp = malloc(slen * sizeof(wchar_t));
- if (ws == NULL) {
- free(wn);
- return (NULL);
- }
- /* prepend "\\?\" */
- wcsncpy(wsp, L"\\\\?\\", 4);
- wsp += 4;
- slen -= 4;
- if (unc) {
- /* append "UNC\" ---> "\\?\UNC\" */
- wcsncpy(wsp, L"UNC\\", 4);
- wsp += 4;
- slen -= 4;
- }
- wcsncpy(wsp, wnp, slen);
- wsp[slen - 1] = L'\0'; /* Ensure null termination. */
- free(wn);
- return (ws);
-}
-
-/*
- * Create a file handle.
- * This can exceed MAX_PATH limitation.
- */
-static HANDLE
-la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
- LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
- DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
-{
- wchar_t *wpath;
- HANDLE handle;
-# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- CREATEFILE2_EXTENDED_PARAMETERS createExParams;
-#endif
-
-#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
- handle = CreateFileA(path, dwDesiredAccess, dwShareMode,
- lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
- hTemplateFile);
- if (handle != INVALID_HANDLE_VALUE)
- return (handle);
- if (GetLastError() != ERROR_PATH_NOT_FOUND)
- return (handle);
-#endif
- wpath = __la_win_permissive_name(path);
- if (wpath == NULL)
- return INVALID_HANDLE_VALUE;
-# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- ZeroMemory(&createExParams, sizeof(createExParams));
- createExParams.dwSize = sizeof(createExParams);
- createExParams.dwFileAttributes = dwFlagsAndAttributes & 0xFFFF;
- createExParams.dwFileFlags = dwFlagsAndAttributes & 0xFFF00000;
- createExParams.dwSecurityQosFlags = dwFlagsAndAttributes & 0x000F00000;
- createExParams.lpSecurityAttributes = lpSecurityAttributes;
- createExParams.hTemplateFile = hTemplateFile;
- handle = CreateFile2(wpath, dwDesiredAccess, dwShareMode,
- dwCreationDisposition, &createExParams);
-#else /* !WINAPI_PARTITION_DESKTOP */
- handle = CreateFileW(wpath, dwDesiredAccess, dwShareMode,
- lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
- hTemplateFile);
-#endif /* !WINAPI_PARTITION_DESKTOP */
- free(wpath);
- return (handle);
-}
-
-#if defined(__LA_LSEEK_NEEDED)
-__int64
-__la_lseek(int fd, __int64 offset, int whence)
-{
- LARGE_INTEGER distance;
- LARGE_INTEGER newpointer;
- HANDLE handle;
-
- if (fd < 0) {
- errno = EBADF;
- return (-1);
- }
- handle = (HANDLE)_get_osfhandle(fd);
- if (GetFileType(handle) != FILE_TYPE_DISK) {
- errno = EBADF;
- return (-1);
- }
- distance.QuadPart = offset;
- if (!SetFilePointerEx_perso(handle, distance, &newpointer, whence)) {
- DWORD lasterr;
-
- lasterr = GetLastError();
- if (lasterr == ERROR_BROKEN_PIPE)
- return (0);
- if (lasterr == ERROR_ACCESS_DENIED)
- errno = EBADF;
- else
- la_dosmaperr(lasterr);
- return (-1);
- }
- return (newpointer.QuadPart);
-}
-#endif
-
-/* This can exceed MAX_PATH limitation. */
-int
-__la_open(const char *path, int flags, ...)
-{
- va_list ap;
- wchar_t *ws;
- int r, pmode;
- DWORD attr;
-
- va_start(ap, flags);
- pmode = va_arg(ap, int);
- va_end(ap);
- ws = NULL;
- if ((flags & ~O_BINARY) == O_RDONLY) {
- /*
- * When we open a directory, _open function returns
- * "Permission denied" error.
- */
- attr = GetFileAttributesA(path);
-#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
- if (attr == (DWORD)-1 && GetLastError() == ERROR_PATH_NOT_FOUND)
-#endif
- {
- ws = __la_win_permissive_name(path);
- if (ws == NULL) {
- errno = EINVAL;
- return (-1);
- }
- attr = GetFileAttributesW(ws);
- }
- if (attr == (DWORD)-1) {
- la_dosmaperr(GetLastError());
- free(ws);
- return (-1);
- }
- if (attr & FILE_ATTRIBUTE_DIRECTORY) {
- HANDLE handle;
-#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
- if (ws != NULL)
- handle = CreateFileW(ws, 0, 0, NULL,
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS |
- FILE_ATTRIBUTE_READONLY,
- NULL);
- else
- handle = CreateFileA(path, 0, 0, NULL,
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS |
- FILE_ATTRIBUTE_READONLY,
- NULL);
-#else /* !WINAPI_PARTITION_DESKTOP */
- CREATEFILE2_EXTENDED_PARAMETERS createExParams;
- ZeroMemory(&createExParams, sizeof(createExParams));
- createExParams.dwSize = sizeof(createExParams);
- createExParams.dwFileAttributes = FILE_ATTRIBUTE_READONLY;
- createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
- handle = CreateFile2(ws, 0, 0,
- OPEN_EXISTING, &createExParams);
-#endif /* !WINAPI_PARTITION_DESKTOP */
- free(ws);
- if (handle == INVALID_HANDLE_VALUE) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- r = _open_osfhandle((intptr_t)handle, _O_RDONLY);
- return (r);
- }
- }
- if (ws == NULL) {
-#if defined(__BORLANDC__)
- /* Borland has no mode argument.
- TODO: Fix mode of new file. */
- r = _open(path, flags);
-#else
- r = _open(path, flags, pmode);
-#endif
- if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
- /* Simulate other POSIX system action to pass our test suite. */
- attr = GetFileAttributesA(path);
- if (attr == (DWORD)-1)
- la_dosmaperr(GetLastError());
- else if (attr & FILE_ATTRIBUTE_DIRECTORY)
- errno = EISDIR;
- else
- errno = EACCES;
- return (-1);
- }
- if (r >= 0 || errno != ENOENT)
- return (r);
- ws = __la_win_permissive_name(path);
- if (ws == NULL) {
- errno = EINVAL;
- return (-1);
- }
- }
- r = _wopen(ws, flags, pmode);
- if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
- /* Simulate other POSIX system action to pass our test suite. */
- attr = GetFileAttributesW(ws);
- if (attr == (DWORD)-1)
- la_dosmaperr(GetLastError());
- else if (attr & FILE_ATTRIBUTE_DIRECTORY)
- errno = EISDIR;
- else
- errno = EACCES;
- }
- free(ws);
- return (r);
-}
-
-ssize_t
-__la_read(int fd, void *buf, size_t nbytes)
-{
- HANDLE handle;
- DWORD bytes_read, lasterr;
- int r;
-
-#ifdef _WIN64
- if (nbytes > UINT32_MAX)
- nbytes = UINT32_MAX;
-#endif
- if (fd < 0) {
- errno = EBADF;
- return (-1);
- }
- /* Do not pass 0 to third parameter of ReadFile(), read bytes.
- * This will not return to application side. */
- if (nbytes == 0)
- return (0);
- handle = (HANDLE)_get_osfhandle(fd);
- r = ReadFile(handle, buf, (uint32_t)nbytes,
- &bytes_read, NULL);
- if (r == 0) {
- lasterr = GetLastError();
- if (lasterr == ERROR_NO_DATA) {
- errno = EAGAIN;
- return (-1);
- }
- if (lasterr == ERROR_BROKEN_PIPE)
- return (0);
- if (lasterr == ERROR_ACCESS_DENIED)
- errno = EBADF;
- else
- la_dosmaperr(lasterr);
- return (-1);
- }
- return ((ssize_t)bytes_read);
-}
-
-/* Convert Windows FILETIME to UTC */
-__inline static void
-fileTimeToUTC(const FILETIME *filetime, time_t *t, long *ns)
-{
- ULARGE_INTEGER utc;
-
- utc.HighPart = filetime->dwHighDateTime;
- utc.LowPart = filetime->dwLowDateTime;
- if (utc.QuadPart >= EPOC_TIME) {
- utc.QuadPart -= EPOC_TIME;
- *t = (time_t)(utc.QuadPart / 10000000); /* milli seconds base */
- *ns = (long)(utc.QuadPart % 10000000) * 100;/* nano seconds base */
- } else {
- *t = 0;
- *ns = 0;
- }
-}
-
-/* Stat by handle
- * Windows' stat() does not accept the path added "\\?\" especially "?"
- * character.
- * It means we cannot access the long name path longer than MAX_PATH.
- * So I've implemented a function similar to Windows' stat() to access the
- * long name path.
- * And I've added some feature.
- * 1. set st_ino by nFileIndexHigh and nFileIndexLow of
- * BY_HANDLE_FILE_INFORMATION.
- * 2. set st_nlink by nNumberOfLinks of BY_HANDLE_FILE_INFORMATION.
- * 3. set st_dev by dwVolumeSerialNumber by BY_HANDLE_FILE_INFORMATION.
- */
-static int
-__hstat(HANDLE handle, struct ustat *st)
-{
- BY_HANDLE_FILE_INFORMATION info;
- ULARGE_INTEGER ino64;
- DWORD ftype;
- mode_t mode;
- time_t t;
- long ns;
-
- switch (ftype = GetFileType(handle)) {
- case FILE_TYPE_UNKNOWN:
- errno = EBADF;
- return (-1);
- case FILE_TYPE_CHAR:
- case FILE_TYPE_PIPE:
- if (ftype == FILE_TYPE_CHAR) {
- st->st_mode = S_IFCHR;
- st->st_size = 0;
- } else {
- DWORD avail;
-
- st->st_mode = S_IFIFO;
- if (PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL))
- st->st_size = avail;
- else
- st->st_size = 0;
- }
- st->st_atime = 0;
- st->st_atime_nsec = 0;
- st->st_mtime = 0;
- st->st_mtime_nsec = 0;
- st->st_ctime = 0;
- st->st_ctime_nsec = 0;
- st->st_ino = 0;
- st->st_nlink = 1;
- st->st_uid = 0;
- st->st_gid = 0;
- st->st_rdev = 0;
- st->st_dev = 0;
- return (0);
- case FILE_TYPE_DISK:
- break;
- default:
- /* This ftype is undocumented type. */
- la_dosmaperr(GetLastError());
- return (-1);
- }
-
- ZeroMemory(&info, sizeof(info));
- if (!GetFileInformationByHandle (handle, &info)) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
-
- mode = S_IRUSR | S_IRGRP | S_IROTH;
- if ((info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
- mode |= S_IWUSR | S_IWGRP | S_IWOTH;
- if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
- else
- mode |= S_IFREG;
- st->st_mode = mode;
-
- fileTimeToUTC(&info.ftLastAccessTime, &t, &ns);
- st->st_atime = t;
- st->st_atime_nsec = ns;
- fileTimeToUTC(&info.ftLastWriteTime, &t, &ns);
- st->st_mtime = t;
- st->st_mtime_nsec = ns;
- fileTimeToUTC(&info.ftCreationTime, &t, &ns);
- st->st_ctime = t;
- st->st_ctime_nsec = ns;
- st->st_size =
- ((int64_t)(info.nFileSizeHigh) * ((int64_t)MAXDWORD + 1))
- + (int64_t)(info.nFileSizeLow);
-#ifdef SIMULATE_WIN_STAT
- st->st_ino = 0;
- st->st_nlink = 1;
- st->st_dev = 0;
-#else
- /* Getting FileIndex as i-node. We should remove a sequence which
- * is high-16-bits of nFileIndexHigh. */
- ino64.HighPart = info.nFileIndexHigh & 0x0000FFFFUL;
- ino64.LowPart = info.nFileIndexLow;
- st->st_ino = ino64.QuadPart;
- st->st_nlink = info.nNumberOfLinks;
- if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- ++st->st_nlink;/* Add parent directory. */
- st->st_dev = info.dwVolumeSerialNumber;
-#endif
- st->st_uid = 0;
- st->st_gid = 0;
- st->st_rdev = 0;
- return (0);
-}
-
-static void
-copy_stat(struct stat *st, struct ustat *us)
-{
- st->st_atime = us->st_atime;
- st->st_ctime = us->st_ctime;
- st->st_mtime = us->st_mtime;
- st->st_gid = us->st_gid;
- st->st_ino = getino(us);
- st->st_mode = us->st_mode;
- st->st_nlink = us->st_nlink;
- st->st_size = (off_t)us->st_size;
- st->st_uid = us->st_uid;
- st->st_dev = us->st_dev;
- st->st_rdev = us->st_rdev;
-}
-
-/*
- * TODO: Remove a use of __la_fstat and __la_stat.
- * We should use GetFileInformationByHandle in place
- * where We still use the *stat functions.
- */
-int
-__la_fstat(int fd, struct stat *st)
-{
- struct ustat u;
- int ret;
-
- if (fd < 0) {
- errno = EBADF;
- return (-1);
- }
- ret = __hstat((HANDLE)_get_osfhandle(fd), &u);
- if (ret >= 0) {
- copy_stat(st, &u);
- if (u.st_mode & (S_IFCHR | S_IFIFO)) {
- st->st_dev = fd;
- st->st_rdev = fd;
- }
- }
- return (ret);
-}
-
-/* This can exceed MAX_PATH limitation. */
-int
-__la_stat(const char *path, struct stat *st)
-{
- HANDLE handle;
- struct ustat u;
- int ret;
-
- handle = la_CreateFile(path, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS,
- NULL);
- if (handle == INVALID_HANDLE_VALUE) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- ret = __hstat(handle, &u);
- CloseHandle(handle);
- if (ret >= 0) {
- char *p;
-
- copy_stat(st, &u);
- p = strrchr(path, '.');
- if (p != NULL && strlen(p) == 4) {
- char exttype[4];
-
- ++ p;
- exttype[0] = toupper(*p++);
- exttype[1] = toupper(*p++);
- exttype[2] = toupper(*p++);
- exttype[3] = '\0';
- if (!strcmp(exttype, "EXE") || !strcmp(exttype, "CMD") ||
- !strcmp(exttype, "BAT") || !strcmp(exttype, "COM"))
- st->st_mode |= S_IXUSR | S_IXGRP | S_IXOTH;
- }
- }
- return (ret);
-}
-
-/*
- * This waitpid is limited implementation.
- */
-pid_t
-__la_waitpid(HANDLE child, int *status, int option)
-{
- DWORD cs;
-
- (void)option;/* UNUSED */
- do {
- if (GetExitCodeProcess(child, &cs) == 0) {
- CloseHandle(child);
- la_dosmaperr(GetLastError());
- *status = 0;
- return (-1);
- }
- } while (cs == STILL_ACTIVE);
-
- *status = (int)(cs & 0xff);
- return (0);
-}
-
-ssize_t
-__la_write(int fd, const void *buf, size_t nbytes)
-{
- DWORD bytes_written;
-
-#ifdef _WIN64
- if (nbytes > UINT32_MAX)
- nbytes = UINT32_MAX;
-#endif
- if (fd < 0) {
- errno = EBADF;
- return (-1);
- }
- if (!WriteFile((HANDLE)_get_osfhandle(fd), buf, (uint32_t)nbytes,
- &bytes_written, NULL)) {
- DWORD lasterr;
-
- lasterr = GetLastError();
- if (lasterr == ERROR_ACCESS_DENIED)
- errno = EBADF;
- else
- la_dosmaperr(lasterr);
- return (-1);
- }
- return (bytes_written);
-}
-
-/*
- * Replace the Windows path separator '\' with '/'.
- */
-static int
-replace_pathseparator(struct archive_wstring *ws, const wchar_t *wp)
-{
- wchar_t *w;
- size_t path_length;
-
- if (wp == NULL)
- return(0);
- if (wcschr(wp, L'\\') == NULL)
- return(0);
- path_length = wcslen(wp);
- if (archive_wstring_ensure(ws, path_length) == NULL)
- return(-1);
- archive_wstrncpy(ws, wp, path_length);
- for (w = ws->s; *w; w++) {
- if (*w == L'\\')
- *w = L'/';
- }
- return(1);
-}
-
-static int
-fix_pathseparator(struct archive_entry *entry)
-{
- struct archive_wstring ws;
- const wchar_t *wp;
- int ret = ARCHIVE_OK;
-
- archive_string_init(&ws);
- wp = archive_entry_pathname_w(entry);
- switch (replace_pathseparator(&ws, wp)) {
- case 0: /* Not replaced. */
- break;
- case 1: /* Replaced. */
- archive_entry_copy_pathname_w(entry, ws.s);
- break;
- default:
- ret = ARCHIVE_FAILED;
- }
- wp = archive_entry_hardlink_w(entry);
- switch (replace_pathseparator(&ws, wp)) {
- case 0: /* Not replaced. */
- break;
- case 1: /* Replaced. */
- archive_entry_copy_hardlink_w(entry, ws.s);
- break;
- default:
- ret = ARCHIVE_FAILED;
- }
- wp = archive_entry_symlink_w(entry);
- switch (replace_pathseparator(&ws, wp)) {
- case 0: /* Not replaced. */
- break;
- case 1: /* Replaced. */
- archive_entry_copy_symlink_w(entry, ws.s);
- break;
- default:
- ret = ARCHIVE_FAILED;
- }
- archive_wstring_free(&ws);
- return(ret);
-}
-
-struct archive_entry *
-__la_win_entry_in_posix_pathseparator(struct archive_entry *entry)
-{
- struct archive_entry *entry_main;
- const wchar_t *wp;
- int has_backslash = 0;
- int ret;
-
- wp = archive_entry_pathname_w(entry);
- if (wp != NULL && wcschr(wp, L'\\') != NULL)
- has_backslash = 1;
- if (!has_backslash) {
- wp = archive_entry_hardlink_w(entry);
- if (wp != NULL && wcschr(wp, L'\\') != NULL)
- has_backslash = 1;
- }
- if (!has_backslash) {
- wp = archive_entry_symlink_w(entry);
- if (wp != NULL && wcschr(wp, L'\\') != NULL)
- has_backslash = 1;
- }
- /*
- * If there is no backslash chars, return the original.
- */
- if (!has_backslash)
- return (entry);
-
- /* Copy entry so we can modify it as needed. */
- entry_main = archive_entry_clone(entry);
- if (entry_main == NULL)
- return (NULL);
- /* Replace the Windows path-separator '\' with '/'. */
- ret = fix_pathseparator(entry_main);
- if (ret < ARCHIVE_WARN) {
- archive_entry_free(entry_main);
- return (NULL);
- }
- return (entry_main);
-}
-
-
-/*
- * The following function was modified from PostgreSQL sources and is
- * subject to the copyright below.
- */
-/*-------------------------------------------------------------------------
- *
- * win32error.c
- * Map win32 error codes to errno values
- *
- * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
- *
- * IDENTIFICATION
- * $PostgreSQL: pgsql/src/port/win32error.c,v 1.4 2008/01/01 19:46:00 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-/*
-PostgreSQL Database Management System
-(formerly known as Postgres, then as Postgres95)
-
-Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
-
-Portions Copyright (c) 1994, The Regents of the University of California
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose, without fee, and without a written agreement
-is hereby granted, provided that the above copyright notice and this
-paragraph and the following two paragraphs appear in all copies.
-
-IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
-DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
-LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
-DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
-THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
-INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
-ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
-PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
-*/
-
-static const struct {
- DWORD winerr;
- int doserr;
-} doserrors[] =
-{
- { ERROR_INVALID_FUNCTION, EINVAL },
- { ERROR_FILE_NOT_FOUND, ENOENT },
- { ERROR_PATH_NOT_FOUND, ENOENT },
- { ERROR_TOO_MANY_OPEN_FILES, EMFILE },
- { ERROR_ACCESS_DENIED, EACCES },
- { ERROR_INVALID_HANDLE, EBADF },
- { ERROR_ARENA_TRASHED, ENOMEM },
- { ERROR_NOT_ENOUGH_MEMORY, ENOMEM },
- { ERROR_INVALID_BLOCK, ENOMEM },
- { ERROR_BAD_ENVIRONMENT, E2BIG },
- { ERROR_BAD_FORMAT, ENOEXEC },
- { ERROR_INVALID_ACCESS, EINVAL },
- { ERROR_INVALID_DATA, EINVAL },
- { ERROR_INVALID_DRIVE, ENOENT },
- { ERROR_CURRENT_DIRECTORY, EACCES },
- { ERROR_NOT_SAME_DEVICE, EXDEV },
- { ERROR_NO_MORE_FILES, ENOENT },
- { ERROR_LOCK_VIOLATION, EACCES },
- { ERROR_SHARING_VIOLATION, EACCES },
- { ERROR_BAD_NETPATH, ENOENT },
- { ERROR_NETWORK_ACCESS_DENIED, EACCES },
- { ERROR_BAD_NET_NAME, ENOENT },
- { ERROR_FILE_EXISTS, EEXIST },
- { ERROR_CANNOT_MAKE, EACCES },
- { ERROR_FAIL_I24, EACCES },
- { ERROR_INVALID_PARAMETER, EINVAL },
- { ERROR_NO_PROC_SLOTS, EAGAIN },
- { ERROR_DRIVE_LOCKED, EACCES },
- { ERROR_BROKEN_PIPE, EPIPE },
- { ERROR_DISK_FULL, ENOSPC },
- { ERROR_INVALID_TARGET_HANDLE, EBADF },
- { ERROR_INVALID_HANDLE, EINVAL },
- { ERROR_WAIT_NO_CHILDREN, ECHILD },
- { ERROR_CHILD_NOT_COMPLETE, ECHILD },
- { ERROR_DIRECT_ACCESS_HANDLE, EBADF },
- { ERROR_NEGATIVE_SEEK, EINVAL },
- { ERROR_SEEK_ON_DEVICE, EACCES },
- { ERROR_DIR_NOT_EMPTY, ENOTEMPTY },
- { ERROR_NOT_LOCKED, EACCES },
- { ERROR_BAD_PATHNAME, ENOENT },
- { ERROR_MAX_THRDS_REACHED, EAGAIN },
- { ERROR_LOCK_FAILED, EACCES },
- { ERROR_ALREADY_EXISTS, EEXIST },
- { ERROR_FILENAME_EXCED_RANGE, ENOENT },
- { ERROR_NESTING_NOT_ALLOWED, EAGAIN },
- { ERROR_NOT_ENOUGH_QUOTA, ENOMEM }
-};
-
-void
-__la_dosmaperr(unsigned long e)
-{
- int i;
-
- if (e == 0)
- {
- errno = 0;
- return;
- }
-
- for (i = 0; i < (int)(sizeof(doserrors)/sizeof(doserrors[0])); i++)
- {
- if (doserrors[i].winerr == e)
- {
- errno = doserrors[i].doserr;
- return;
- }
- }
-
- /* fprintf(stderr, "unrecognized win32 error code: %lu", e); */
- errno = EINVAL;
- return;
-}
-
-#endif /* _WIN32 && !__CYGWIN__ */
diff --git a/contrib/libs/libarchive/libarchive/archive_windows.h b/contrib/libs/libarchive/libarchive/archive_windows.h
deleted file mode 100644
index 47b7cb8e37..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_windows.h
+++ /dev/null
@@ -1,315 +0,0 @@
-/*-
- * Copyright (c) 2009-2011 Michihiro NAKAJIMA
- * Copyright (c) 2003-2006 Tim Kientzle
- * 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
- * in this position and unchanged.
- * 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(S) ``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(S) 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.
- *
- * $FreeBSD$
- */
-
-/*
- * TODO: A lot of stuff in here isn't actually used by libarchive and
- * can be trimmed out. Note that this file is used by libarchive and
- * libarchive_test but nowhere else. (But note that it gets compiled
- * with many different Windows environments, including MinGW, Visual
- * Studio, and Cygwin. Significant changes should be tested in all three.)
- */
-
-/*
- * TODO: Don't use off_t in here. Use __int64 instead. Note that
- * Visual Studio and the Windows SDK define off_t as 32 bits; Win32's
- * more modern file handling APIs all use __int64 instead of off_t.
- */
-
-#ifndef LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED
-#define LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
-/* Start of configuration for native Win32 */
-#ifndef MINGW_HAS_SECURE_API
-#define MINGW_HAS_SECURE_API 1
-#endif
-
-#include <errno.h>
-#define set_errno(val) ((errno)=val)
-#include <io.h>
-#include <stdlib.h> //brings in NULL
-#if defined(HAVE_STDINT_H)
-#include <stdint.h>
-#endif
-#include <stdio.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <process.h>
-#include <direct.h>
-#if defined(__MINGW32__) && defined(HAVE_UNISTD_H)
-/* Prevent build error from a type mismatch of ftruncate().
- * This unistd.h defines it as ftruncate(int, off_t). */
-#include <unistd.h>
-#endif
-#define NOCRYPT
-#include <windows.h>
-//#define EFTYPE 7
-
-#if defined(__BORLANDC__)
-#pragma warn -8068 /* Constant out of range in comparison. */
-#pragma warn -8072 /* Suspicious pointer arithmetic. */
-#endif
-
-#ifndef NULL
-#ifdef __cplusplus
-#define NULL 0
-#else
-#define NULL ((void *)0)
-#endif
-#endif
-
-/* Alias the Windows _function to the POSIX equivalent. */
-#define close _close
-#define fcntl(fd, cmd, flg) /* No operation. */
-#ifndef fileno
-#define fileno _fileno
-#endif
-#ifdef fstat
-#undef fstat
-#endif
-#define fstat __la_fstat
-#if !defined(__BORLANDC__)
-#ifdef lseek
-#undef lseek
-#endif
-#define lseek _lseeki64
-#else
-#define lseek __la_lseek
-#define __LA_LSEEK_NEEDED
-#endif
-#define lstat __la_stat
-#define open __la_open
-#define read __la_read
-#if !defined(__BORLANDC__) && !defined(__WATCOMC__)
-#define setmode _setmode
-#endif
-#define la_stat(path,stref) __la_stat(path,stref)
-#if !defined(__WATCOMC__)
-#if !defined(__BORLANDC__)
-#define strdup _strdup
-#endif
-#define tzset _tzset
-#if !defined(__BORLANDC__)
-#define umask _umask
-#endif
-#endif
-#define waitpid __la_waitpid
-#define write __la_write
-
-#if !defined(__WATCOMC__)
-
-#ifndef O_RDONLY
-#define O_RDONLY _O_RDONLY
-#define O_WRONLY _O_WRONLY
-#define O_TRUNC _O_TRUNC
-#define O_CREAT _O_CREAT
-#define O_EXCL _O_EXCL
-#define O_BINARY _O_BINARY
-#endif
-
-#ifndef _S_IFIFO
- #define _S_IFIFO 0010000 /* pipe */
-#endif
-#ifndef _S_IFCHR
- #define _S_IFCHR 0020000 /* character special */
-#endif
-#ifndef _S_IFDIR
- #define _S_IFDIR 0040000 /* directory */
-#endif
-#ifndef _S_IFBLK
- #define _S_IFBLK 0060000 /* block special */
-#endif
-#ifndef _S_IFLNK
- #define _S_IFLNK 0120000 /* symbolic link */
-#endif
-#ifndef _S_IFSOCK
- #define _S_IFSOCK 0140000 /* socket */
-#endif
-#ifndef _S_IFREG
- #define _S_IFREG 0100000 /* regular */
-#endif
-#ifndef _S_IFMT
- #define _S_IFMT 0170000 /* file type mask */
-#endif
-
-#ifndef S_IFIFO
-#define S_IFIFO _S_IFIFO
-#endif
-//#define S_IFCHR _S_IFCHR
-//#define S_IFDIR _S_IFDIR
-#ifndef S_IFBLK
-#define S_IFBLK _S_IFBLK
-#endif
-#ifndef S_IFLNK
-#define S_IFLNK _S_IFLNK
-#endif
-#ifndef S_IFSOCK
-#define S_IFSOCK _S_IFSOCK
-#endif
-//#define S_IFREG _S_IFREG
-//#define S_IFMT _S_IFMT
-
-#ifndef S_ISBLK
-#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) /* block special */
-#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) /* fifo or socket */
-#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) /* char special */
-#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) /* directory */
-#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) /* regular file */
-#endif
-#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) /* Symbolic link */
-#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) /* Socket */
-
-#define _S_ISUID 0004000 /* set user id on execution */
-#define _S_ISGID 0002000 /* set group id on execution */
-#define _S_ISVTX 0001000 /* save swapped text even after use */
-
-#define S_ISUID _S_ISUID
-#define S_ISGID _S_ISGID
-#define S_ISVTX _S_ISVTX
-
-#define _S_IRWXU (_S_IREAD | _S_IWRITE | _S_IEXEC)
-#define _S_IXUSR _S_IEXEC /* read permission, user */
-#define _S_IWUSR _S_IWRITE /* write permission, user */
-#define _S_IRUSR _S_IREAD /* execute/search permission, user */
-#define _S_IRWXG (_S_IRWXU >> 3)
-#define _S_IXGRP (_S_IXUSR >> 3) /* read permission, group */
-#define _S_IWGRP (_S_IWUSR >> 3) /* write permission, group */
-#define _S_IRGRP (_S_IRUSR >> 3) /* execute/search permission, group */
-#define _S_IRWXO (_S_IRWXG >> 3)
-#define _S_IXOTH (_S_IXGRP >> 3) /* read permission, other */
-#define _S_IWOTH (_S_IWGRP >> 3) /* write permission, other */
-#define _S_IROTH (_S_IRGRP >> 3) /* execute/search permission, other */
-
-#ifndef S_IRWXU
-#define S_IRWXU _S_IRWXU
-#define S_IXUSR _S_IXUSR
-#define S_IWUSR _S_IWUSR
-#define S_IRUSR _S_IRUSR
-#endif
-#ifndef S_IRWXG
-#define S_IRWXG _S_IRWXG
-#define S_IXGRP _S_IXGRP
-#define S_IWGRP _S_IWGRP
-#endif
-#ifndef S_IRGRP
-#define S_IRGRP _S_IRGRP
-#endif
-#ifndef S_IRWXO
-#define S_IRWXO _S_IRWXO
-#define S_IXOTH _S_IXOTH
-#define S_IWOTH _S_IWOTH
-#define S_IROTH _S_IROTH
-#endif
-
-#endif
-
-#define F_DUPFD 0 /* Duplicate file descriptor. */
-#define F_GETFD 1 /* Get file descriptor flags. */
-#define F_SETFD 2 /* Set file descriptor flags. */
-#define F_GETFL 3 /* Get file status flags. */
-#define F_SETFL 4 /* Set file status flags. */
-#define F_GETOWN 5 /* Get owner (receiver of SIGIO). */
-#define F_SETOWN 6 /* Set owner (receiver of SIGIO). */
-#define F_GETLK 7 /* Get record locking info. */
-#define F_SETLK 8 /* Set record locking info (non-blocking). */
-#define F_SETLKW 9 /* Set record locking info (blocking). */
-
-/* XXX missing */
-#define F_GETLK64 7 /* Get record locking info. */
-#define F_SETLK64 8 /* Set record locking info (non-blocking). */
-#define F_SETLKW64 9 /* Set record locking info (blocking). */
-
-/* File descriptor flags used with F_GETFD and F_SETFD. */
-#define FD_CLOEXEC 1 /* Close on exec. */
-
-//NOT SURE IF O_NONBLOCK is OK here but at least the 0x0004 flag is not used by anything else...
-#define O_NONBLOCK 0x0004 /* Non-blocking I/O. */
-//#define O_NDELAY O_NONBLOCK
-
-/* Symbolic constants for the access() function */
-#if !defined(F_OK)
- #define R_OK 4 /* Test for read permission */
- #define W_OK 2 /* Test for write permission */
- #define X_OK 1 /* Test for execute permission */
- #define F_OK 0 /* Test for existence of file */
-#endif
-
-
-/* Replacement POSIX function */
-extern int __la_fstat(int fd, struct stat *st);
-extern int __la_lstat(const char *path, struct stat *st);
-#if defined(__LA_LSEEK_NEEDED)
-extern __int64 __la_lseek(int fd, __int64 offset, int whence);
-#endif
-extern int __la_open(const char *path, int flags, ...);
-extern ssize_t __la_read(int fd, void *buf, size_t nbytes);
-extern int __la_stat(const char *path, struct stat *st);
-extern pid_t __la_waitpid(HANDLE child, int *status, int option);
-extern ssize_t __la_write(int fd, const void *buf, size_t nbytes);
-
-#define _stat64i32(path, st) __la_stat(path, st)
-#define _stat64(path, st) __la_stat(path, st)
-/* for status returned by la_waitpid */
-#define WIFEXITED(sts) ((sts & 0x100) == 0)
-#define WEXITSTATUS(sts) (sts & 0x0FF)
-
-extern wchar_t *__la_win_permissive_name(const char *name);
-extern wchar_t *__la_win_permissive_name_w(const wchar_t *wname);
-extern void __la_dosmaperr(unsigned long e);
-#define la_dosmaperr(e) __la_dosmaperr(e)
-extern struct archive_entry *__la_win_entry_in_posix_pathseparator(
- struct archive_entry *);
-
-#if defined(HAVE_WCRTOMB) && defined(__BORLANDC__)
-typedef int mbstate_t;
-size_t wcrtomb(char *, wchar_t, mbstate_t *);
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER < 1300
-WINBASEAPI BOOL WINAPI GetVolumePathNameW(
- LPCWSTR lpszFileName,
- LPWSTR lpszVolumePathName,
- DWORD cchBufferLength
- );
-# if _WIN32_WINNT < 0x0500 /* windows.h not providing 0x500 API */
-typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
- LARGE_INTEGER FileOffset;
- LARGE_INTEGER Length;
-} FILE_ALLOCATED_RANGE_BUFFER, *PFILE_ALLOCATED_RANGE_BUFFER;
-# define FSCTL_SET_SPARSE \
- CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 49, METHOD_BUFFERED, FILE_WRITE_DATA)
-# define FSCTL_QUERY_ALLOCATED_RANGES \
- CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 51, METHOD_NEITHER, FILE_READ_DATA)
-# endif
-#endif
-
-#endif /* LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED */
diff --git a/contrib/libs/libarchive/libarchive/archive_write.c b/contrib/libs/libarchive/libarchive/archive_write.c
deleted file mode 100644
index ec3c95c566..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write.c
+++ /dev/null
@@ -1,859 +0,0 @@
-/*-
- * Copyright (c) 2003-2010 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write.c 201099 2009-12-28 03:03:00Z kientzle $");
-
-/*
- * This file contains the "essential" portions of the write API, that
- * is, stuff that will essentially always be used by any client that
- * actually needs to write an archive. Optional pieces have been, as
- * far as possible, separated out into separate files to reduce
- * needlessly bloating statically-linked clients.
- */
-
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#include <time.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_private.h"
-#include "archive_write_private.h"
-
-static int _archive_filter_code(struct archive *, int);
-static const char *_archive_filter_name(struct archive *, int);
-static int64_t _archive_filter_bytes(struct archive *, int);
-static int _archive_write_filter_count(struct archive *);
-static int _archive_write_close(struct archive *);
-static int _archive_write_free(struct archive *);
-static int _archive_write_header(struct archive *, struct archive_entry *);
-static int _archive_write_finish_entry(struct archive *);
-static ssize_t _archive_write_data(struct archive *, const void *, size_t);
-
-struct archive_none {
- size_t buffer_size;
- size_t avail;
- char *buffer;
- char *next;
-};
-
-static const struct archive_vtable
-archive_write_vtable = {
- .archive_close = _archive_write_close,
- .archive_filter_bytes = _archive_filter_bytes,
- .archive_filter_code = _archive_filter_code,
- .archive_filter_name = _archive_filter_name,
- .archive_filter_count = _archive_write_filter_count,
- .archive_free = _archive_write_free,
- .archive_write_header = _archive_write_header,
- .archive_write_finish_entry = _archive_write_finish_entry,
- .archive_write_data = _archive_write_data,
-};
-
-/*
- * Allocate, initialize and return an archive object.
- */
-struct archive *
-archive_write_new(void)
-{
- struct archive_write *a;
- unsigned char *nulls;
-
- a = (struct archive_write *)calloc(1, sizeof(*a));
- if (a == NULL)
- return (NULL);
- a->archive.magic = ARCHIVE_WRITE_MAGIC;
- a->archive.state = ARCHIVE_STATE_NEW;
- a->archive.vtable = &archive_write_vtable;
- /*
- * The value 10240 here matches the traditional tar default,
- * but is otherwise arbitrary.
- * TODO: Set the default block size from the format selected.
- */
- a->bytes_per_block = 10240;
- a->bytes_in_last_block = -1; /* Default */
-
- /* Initialize a block of nulls for padding purposes. */
- a->null_length = 1024;
- nulls = (unsigned char *)calloc(1, a->null_length);
- if (nulls == NULL) {
- free(a);
- return (NULL);
- }
- a->nulls = nulls;
- return (&a->archive);
-}
-
-/*
- * Set the block size. Returns 0 if successful.
- */
-int
-archive_write_set_bytes_per_block(struct archive *_a, int bytes_per_block)
-{
- struct archive_write *a = (struct archive_write *)_a;
- archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_bytes_per_block");
- a->bytes_per_block = bytes_per_block;
- return (ARCHIVE_OK);
-}
-
-/*
- * Get the current block size. -1 if it has never been set.
- */
-int
-archive_write_get_bytes_per_block(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_ANY, "archive_write_get_bytes_per_block");
- return (a->bytes_per_block);
-}
-
-/*
- * Set the size for the last block.
- * Returns 0 if successful.
- */
-int
-archive_write_set_bytes_in_last_block(struct archive *_a, int bytes)
-{
- struct archive_write *a = (struct archive_write *)_a;
- archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_ANY, "archive_write_set_bytes_in_last_block");
- a->bytes_in_last_block = bytes;
- return (ARCHIVE_OK);
-}
-
-/*
- * Return the value set above. -1 indicates it has not been set.
- */
-int
-archive_write_get_bytes_in_last_block(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_ANY, "archive_write_get_bytes_in_last_block");
- return (a->bytes_in_last_block);
-}
-
-/*
- * dev/ino of a file to be rejected. Used to prevent adding
- * an archive to itself recursively.
- */
-int
-archive_write_set_skip_file(struct archive *_a, la_int64_t d, la_int64_t i)
-{
- struct archive_write *a = (struct archive_write *)_a;
- archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_ANY, "archive_write_set_skip_file");
- a->skip_file_set = 1;
- a->skip_file_dev = d;
- a->skip_file_ino = i;
- return (ARCHIVE_OK);
-}
-
-/*
- * Allocate and return the next filter structure.
- */
-struct archive_write_filter *
-__archive_write_allocate_filter(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct archive_write_filter *f;
-
- f = calloc(1, sizeof(*f));
-
- if (f == NULL)
- return (NULL);
-
- f->archive = _a;
- f->state = ARCHIVE_WRITE_FILTER_STATE_NEW;
- if (a->filter_first == NULL)
- a->filter_first = f;
- else
- a->filter_last->next_filter = f;
- a->filter_last = f;
- return f;
-}
-
-/*
- * Write data to a particular filter.
- */
-int
-__archive_write_filter(struct archive_write_filter *f,
- const void *buff, size_t length)
-{
- int r;
- /* Never write to non-open filters */
- if (f->state != ARCHIVE_WRITE_FILTER_STATE_OPEN)
- return(ARCHIVE_FATAL);
- if (length == 0)
- return(ARCHIVE_OK);
- if (f->write == NULL)
- /* If unset, a fatal error has already occurred, so this filter
- * didn't open. We cannot write anything. */
- return(ARCHIVE_FATAL);
- r = (f->write)(f, buff, length);
- f->bytes_written += length;
- return (r);
-}
-
-/*
- * Recursive function for opening the filter chain
- * Last filter is opened first
- */
-static int
-__archive_write_open_filter(struct archive_write_filter *f)
-{
- int ret;
-
- ret = ARCHIVE_OK;
- if (f->next_filter != NULL)
- ret = __archive_write_open_filter(f->next_filter);
- if (ret != ARCHIVE_OK)
- return (ret);
- if (f->state != ARCHIVE_WRITE_FILTER_STATE_NEW)
- return (ARCHIVE_FATAL);
- if (f->open == NULL) {
- f->state = ARCHIVE_WRITE_FILTER_STATE_OPEN;
- return (ARCHIVE_OK);
- }
- ret = (f->open)(f);
- if (ret == ARCHIVE_OK)
- f->state = ARCHIVE_WRITE_FILTER_STATE_OPEN;
- else
- f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL;
- return (ret);
-}
-
-/*
- * Open all filters
- */
-static int
-__archive_write_filters_open(struct archive_write *a)
-{
- return (__archive_write_open_filter(a->filter_first));
-}
-
-/*
- * Close all filtes
- */
-static int
-__archive_write_filters_close(struct archive_write *a)
-{
- struct archive_write_filter *f;
- int ret, ret1;
- ret = ARCHIVE_OK;
- for (f = a->filter_first; f != NULL; f = f->next_filter) {
- /* Do not close filters that are not open */
- if (f->state == ARCHIVE_WRITE_FILTER_STATE_OPEN) {
- if (f->close != NULL) {
- ret1 = (f->close)(f);
- if (ret1 < ret)
- ret = ret1;
- if (ret1 == ARCHIVE_OK) {
- f->state =
- ARCHIVE_WRITE_FILTER_STATE_CLOSED;
- } else {
- f->state =
- ARCHIVE_WRITE_FILTER_STATE_FATAL;
- }
- } else
- f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED;
- }
- }
- return (ret);
-}
-
-int
-__archive_write_output(struct archive_write *a, const void *buff, size_t length)
-{
- return (__archive_write_filter(a->filter_first, buff, length));
-}
-
-static int
-__archive_write_filters_flush(struct archive_write *a)
-{
- struct archive_write_filter *f;
- int ret, ret1;
-
- ret = ARCHIVE_OK;
- for (f = a->filter_first; f != NULL; f = f->next_filter) {
- if (f->flush != NULL && f->bytes_written > 0) {
- ret1 = (f->flush)(f);
- if (ret1 < ret)
- ret = ret1;
- if (ret1 < ARCHIVE_WARN)
- f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL;
- }
- }
- return (ret);
-}
-
-int
-__archive_write_nulls(struct archive_write *a, size_t length)
-{
- if (length == 0)
- return (ARCHIVE_OK);
-
- while (length > 0) {
- size_t to_write = length < a->null_length ? length : a->null_length;
- int r = __archive_write_output(a, a->nulls, to_write);
- if (r < ARCHIVE_OK)
- return (r);
- length -= to_write;
- }
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_client_open(struct archive_write_filter *f)
-{
- struct archive_write *a = (struct archive_write *)f->archive;
- struct archive_none *state;
- void *buffer;
- size_t buffer_size;
- int ret;
-
- f->bytes_per_block = archive_write_get_bytes_per_block(f->archive);
- f->bytes_in_last_block =
- archive_write_get_bytes_in_last_block(f->archive);
- buffer_size = f->bytes_per_block;
-
- state = (struct archive_none *)calloc(1, sizeof(*state));
- buffer = (char *)malloc(buffer_size);
- if (state == NULL || buffer == NULL) {
- free(state);
- free(buffer);
- archive_set_error(f->archive, ENOMEM,
- "Can't allocate data for output buffering");
- return (ARCHIVE_FATAL);
- }
-
- state->buffer_size = buffer_size;
- state->buffer = buffer;
- state->next = state->buffer;
- state->avail = state->buffer_size;
- f->data = state;
-
- if (a->client_opener == NULL)
- return (ARCHIVE_OK);
- ret = a->client_opener(f->archive, a->client_data);
- if (ret != ARCHIVE_OK) {
- free(state->buffer);
- free(state);
- f->data = NULL;
- }
- return (ret);
-}
-
-static int
-archive_write_client_write(struct archive_write_filter *f,
- const void *_buff, size_t length)
-{
- struct archive_write *a = (struct archive_write *)f->archive;
- struct archive_none *state = (struct archive_none *)f->data;
- const char *buff = (const char *)_buff;
- ssize_t remaining, to_copy;
- ssize_t bytes_written;
-
- remaining = length;
-
- /*
- * If there is no buffer for blocking, just pass the data
- * straight through to the client write callback. In
- * particular, this supports "no write delay" operation for
- * special applications. Just set the block size to zero.
- */
- if (state->buffer_size == 0) {
- while (remaining > 0) {
- bytes_written = (a->client_writer)(&a->archive,
- a->client_data, buff, remaining);
- if (bytes_written <= 0)
- return (ARCHIVE_FATAL);
- remaining -= bytes_written;
- buff += bytes_written;
- }
- return (ARCHIVE_OK);
- }
-
- /* If the copy buffer isn't empty, try to fill it. */
- if (state->avail < state->buffer_size) {
- /* If buffer is not empty... */
- /* ... copy data into buffer ... */
- to_copy = ((size_t)remaining > state->avail) ?
- state->avail : (size_t)remaining;
- memcpy(state->next, buff, to_copy);
- state->next += to_copy;
- state->avail -= to_copy;
- buff += to_copy;
- remaining -= to_copy;
- /* ... if it's full, write it out. */
- if (state->avail == 0) {
- char *p = state->buffer;
- size_t to_write = state->buffer_size;
- while (to_write > 0) {
- bytes_written = (a->client_writer)(&a->archive,
- a->client_data, p, to_write);
- if (bytes_written <= 0)
- return (ARCHIVE_FATAL);
- if ((size_t)bytes_written > to_write) {
- archive_set_error(&(a->archive),
- -1, "write overrun");
- return (ARCHIVE_FATAL);
- }
- p += bytes_written;
- to_write -= bytes_written;
- }
- state->next = state->buffer;
- state->avail = state->buffer_size;
- }
- }
-
- while ((size_t)remaining >= state->buffer_size) {
- /* Write out full blocks directly to client. */
- bytes_written = (a->client_writer)(&a->archive,
- a->client_data, buff, state->buffer_size);
- if (bytes_written <= 0)
- return (ARCHIVE_FATAL);
- buff += bytes_written;
- remaining -= bytes_written;
- }
-
- if (remaining > 0) {
- /* Copy last bit into copy buffer. */
- memcpy(state->next, buff, remaining);
- state->next += remaining;
- state->avail -= remaining;
- }
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_client_free(struct archive_write_filter *f)
-{
- struct archive_write *a = (struct archive_write *)f->archive;
-
- if (a->client_freer)
- (*a->client_freer)(&a->archive, a->client_data);
- a->client_data = NULL;
-
- /* Clear passphrase. */
- if (a->passphrase != NULL) {
- memset(a->passphrase, 0, strlen(a->passphrase));
- free(a->passphrase);
- a->passphrase = NULL;
- }
-
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_client_close(struct archive_write_filter *f)
-{
- struct archive_write *a = (struct archive_write *)f->archive;
- struct archive_none *state = (struct archive_none *)f->data;
- ssize_t block_length;
- ssize_t target_block_length;
- ssize_t bytes_written;
- size_t to_write;
- char *p;
- int ret = ARCHIVE_OK;
-
- /* If there's pending data, pad and write the last block */
- if (state->next != state->buffer) {
- block_length = state->buffer_size - state->avail;
-
- /* Tricky calculation to determine size of last block */
- if (a->bytes_in_last_block <= 0)
- /* Default or Zero: pad to full block */
- target_block_length = a->bytes_per_block;
- else
- /* Round to next multiple of bytes_in_last_block. */
- target_block_length = a->bytes_in_last_block *
- ( (block_length + a->bytes_in_last_block - 1) /
- a->bytes_in_last_block);
- if (target_block_length > a->bytes_per_block)
- target_block_length = a->bytes_per_block;
- if (block_length < target_block_length) {
- memset(state->next, 0,
- target_block_length - block_length);
- block_length = target_block_length;
- }
- p = state->buffer;
- to_write = block_length;
- while (to_write > 0) {
- bytes_written = (a->client_writer)(&a->archive,
- a->client_data, p, to_write);
- if (bytes_written <= 0) {
- ret = ARCHIVE_FATAL;
- break;
- }
- if ((size_t)bytes_written > to_write) {
- archive_set_error(&(a->archive),
- -1, "write overrun");
- ret = ARCHIVE_FATAL;
- break;
- }
- p += bytes_written;
- to_write -= bytes_written;
- }
- }
- if (a->client_closer)
- (*a->client_closer)(&a->archive, a->client_data);
- free(state->buffer);
- free(state);
-
- /* Clear the close handler myself not to be called again. */
- f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED;
- return (ret);
-}
-
-/*
- * Open the archive using the current settings.
- */
-int
-archive_write_open2(struct archive *_a, void *client_data,
- archive_open_callback *opener, archive_write_callback *writer,
- archive_close_callback *closer, archive_free_callback *freer)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct archive_write_filter *client_filter;
- int ret, r1;
-
- archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_open");
- archive_clear_error(&a->archive);
-
- a->client_writer = writer;
- a->client_opener = opener;
- a->client_closer = closer;
- a->client_freer = freer;
- a->client_data = client_data;
-
- client_filter = __archive_write_allocate_filter(_a);
-
- if (client_filter == NULL)
- return (ARCHIVE_FATAL);
-
- client_filter->open = archive_write_client_open;
- client_filter->write = archive_write_client_write;
- client_filter->close = archive_write_client_close;
- client_filter->free = archive_write_client_free;
-
- ret = __archive_write_filters_open(a);
- if (ret < ARCHIVE_WARN) {
- r1 = __archive_write_filters_close(a);
- __archive_write_filters_free(_a);
- return (r1 < ret ? r1 : ret);
- }
-
- a->archive.state = ARCHIVE_STATE_HEADER;
- if (a->format_init)
- ret = (a->format_init)(a);
- return (ret);
-}
-
-int
-archive_write_open(struct archive *_a, void *client_data,
- archive_open_callback *opener, archive_write_callback *writer,
- archive_close_callback *closer)
-{
- return archive_write_open2(_a, client_data, opener, writer,
- closer, NULL);
-}
-
-/*
- * Close out the archive.
- */
-static int
-_archive_write_close(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- int r = ARCHIVE_OK, r1 = ARCHIVE_OK;
-
- archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL,
- "archive_write_close");
- if (a->archive.state == ARCHIVE_STATE_NEW
- || a->archive.state == ARCHIVE_STATE_CLOSED)
- return (ARCHIVE_OK); /* Okay to close() when not open. */
-
- archive_clear_error(&a->archive);
-
- /* Finish the last entry if a finish callback is specified */
- if (a->archive.state == ARCHIVE_STATE_DATA
- && a->format_finish_entry != NULL)
- r = ((a->format_finish_entry)(a));
-
- /* Finish off the archive. */
- /* TODO: have format closers invoke compression close. */
- if (a->format_close != NULL) {
- r1 = (a->format_close)(a);
- if (r1 < r)
- r = r1;
- }
-
- /* Finish the compression and close the stream. */
- r1 = __archive_write_filters_close(a);
- if (r1 < r)
- r = r1;
-
- if (a->archive.state != ARCHIVE_STATE_FATAL)
- a->archive.state = ARCHIVE_STATE_CLOSED;
- return (r);
-}
-
-static int
-_archive_write_filter_count(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct archive_write_filter *p = a->filter_first;
- int count = 0;
- while(p) {
- count++;
- p = p->next_filter;
- }
- return count;
-}
-
-void
-__archive_write_filters_free(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- int r = ARCHIVE_OK, r1;
-
- while (a->filter_first != NULL) {
- struct archive_write_filter *next
- = a->filter_first->next_filter;
- if (a->filter_first->free != NULL) {
- r1 = (*a->filter_first->free)(a->filter_first);
- if (r > r1)
- r = r1;
- }
- free(a->filter_first);
- a->filter_first = next;
- }
- a->filter_last = NULL;
-}
-
-/*
- * Destroy the archive structure.
- *
- * Be careful: user might just call write_new and then write_free.
- * Don't assume we actually wrote anything or performed any non-trivial
- * initialization.
- */
-static int
-_archive_write_free(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- int r = ARCHIVE_OK, r1;
-
- if (_a == NULL)
- return (ARCHIVE_OK);
- /* It is okay to call free() in state FATAL. */
- archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_free");
- if (a->archive.state != ARCHIVE_STATE_FATAL)
- r = archive_write_close(&a->archive);
-
- /* Release format resources. */
- if (a->format_free != NULL) {
- r1 = (a->format_free)(a);
- if (r1 < r)
- r = r1;
- }
-
- __archive_write_filters_free(_a);
-
- /* Release various dynamic buffers. */
- free((void *)(uintptr_t)(const void *)a->nulls);
- archive_string_free(&a->archive.error_string);
- if (a->passphrase != NULL) {
- /* A passphrase should be cleaned. */
- memset(a->passphrase, 0, strlen(a->passphrase));
- free(a->passphrase);
- }
- a->archive.magic = 0;
- __archive_clean(&a->archive);
- free(a);
- return (r);
-}
-
-/*
- * Write the appropriate header.
- */
-static int
-_archive_write_header(struct archive *_a, struct archive_entry *entry)
-{
- struct archive_write *a = (struct archive_write *)_a;
- int ret, r2;
-
- archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_DATA | ARCHIVE_STATE_HEADER, "archive_write_header");
- archive_clear_error(&a->archive);
-
- if (a->format_write_header == NULL) {
- archive_set_error(&(a->archive), -1,
- "Format must be set before you can write to an archive.");
- a->archive.state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- }
-
- /* In particular, "retry" and "fatal" get returned immediately. */
- ret = archive_write_finish_entry(&a->archive);
- if (ret == ARCHIVE_FATAL) {
- a->archive.state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- }
- if (ret < ARCHIVE_OK && ret != ARCHIVE_WARN)
- return (ret);
-
- if (a->skip_file_set &&
- archive_entry_dev_is_set(entry) &&
- archive_entry_ino_is_set(entry) &&
- archive_entry_dev(entry) == (dev_t)a->skip_file_dev &&
- archive_entry_ino64(entry) == a->skip_file_ino) {
- archive_set_error(&a->archive, 0,
- "Can't add archive to itself");
- return (ARCHIVE_FAILED);
- }
-
- /* Flush filters at boundary. */
- r2 = __archive_write_filters_flush(a);
- if (r2 == ARCHIVE_FAILED) {
- return (ARCHIVE_FAILED);
- }
- if (r2 == ARCHIVE_FATAL) {
- a->archive.state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- }
- if (r2 < ret)
- ret = r2;
-
- /* Format and write header. */
- r2 = ((a->format_write_header)(a, entry));
- if (r2 == ARCHIVE_FAILED) {
- return (ARCHIVE_FAILED);
- }
- if (r2 == ARCHIVE_FATAL) {
- a->archive.state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- }
- if (r2 < ret)
- ret = r2;
-
- a->archive.state = ARCHIVE_STATE_DATA;
- return (ret);
-}
-
-static int
-_archive_write_finish_entry(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- int ret = ARCHIVE_OK;
-
- archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
- "archive_write_finish_entry");
- if (a->archive.state & ARCHIVE_STATE_DATA
- && a->format_finish_entry != NULL)
- ret = (a->format_finish_entry)(a);
- a->archive.state = ARCHIVE_STATE_HEADER;
- return (ret);
-}
-
-/*
- * Note that the compressor is responsible for blocking.
- */
-static ssize_t
-_archive_write_data(struct archive *_a, const void *buff, size_t s)
-{
- struct archive_write *a = (struct archive_write *)_a;
- const size_t max_write = INT_MAX;
-
- archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_DATA, "archive_write_data");
- /* In particular, this catches attempts to pass negative values. */
- if (s > max_write)
- s = max_write;
- archive_clear_error(&a->archive);
- return ((a->format_write_data)(a, buff, s));
-}
-
-static struct archive_write_filter *
-filter_lookup(struct archive *_a, int n)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct archive_write_filter *f = a->filter_first;
- if (n == -1)
- return a->filter_last;
- if (n < 0)
- return NULL;
- while (n > 0 && f != NULL) {
- f = f->next_filter;
- --n;
- }
- return f;
-}
-
-static int
-_archive_filter_code(struct archive *_a, int n)
-{
- struct archive_write_filter *f = filter_lookup(_a, n);
- return f == NULL ? -1 : f->code;
-}
-
-static const char *
-_archive_filter_name(struct archive *_a, int n)
-{
- struct archive_write_filter *f = filter_lookup(_a, n);
- return f != NULL ? f->name : NULL;
-}
-
-static int64_t
-_archive_filter_bytes(struct archive *_a, int n)
-{
- struct archive_write_filter *f = filter_lookup(_a, n);
- return f == NULL ? -1 : f->bytes_written;
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_add_filter.c b/contrib/libs/libarchive/libarchive/archive_write_add_filter.c
deleted file mode 100644
index 203f4142b5..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_add_filter.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*-
- * Copyright (c) 2012 Ondrej Holy
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-
-/* A table that maps filter codes to functions. */
-static const
-struct { int code; int (*setter)(struct archive *); } codes[] =
-{
- { ARCHIVE_FILTER_NONE, archive_write_add_filter_none },
- { ARCHIVE_FILTER_GZIP, archive_write_add_filter_gzip },
- { ARCHIVE_FILTER_BZIP2, archive_write_add_filter_bzip2 },
- { ARCHIVE_FILTER_COMPRESS, archive_write_add_filter_compress },
- { ARCHIVE_FILTER_GRZIP, archive_write_add_filter_grzip },
- { ARCHIVE_FILTER_LRZIP, archive_write_add_filter_lrzip },
- { ARCHIVE_FILTER_LZ4, archive_write_add_filter_lz4 },
- { ARCHIVE_FILTER_LZIP, archive_write_add_filter_lzip },
- { ARCHIVE_FILTER_LZMA, archive_write_add_filter_lzma },
- { ARCHIVE_FILTER_LZOP, archive_write_add_filter_lzip },
- { ARCHIVE_FILTER_UU, archive_write_add_filter_uuencode },
- { ARCHIVE_FILTER_XZ, archive_write_add_filter_xz },
- { ARCHIVE_FILTER_ZSTD, archive_write_add_filter_zstd },
- { -1, NULL }
-};
-
-int
-archive_write_add_filter(struct archive *a, int code)
-{
- int i;
-
- for (i = 0; codes[i].code != -1; i++) {
- if (code == codes[i].code)
- return ((codes[i].setter)(a));
- }
-
- archive_set_error(a, EINVAL, "No such filter");
- return (ARCHIVE_FATAL);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_add_filter_b64encode.c b/contrib/libs/libarchive/libarchive/archive_write_add_filter_b64encode.c
deleted file mode 100644
index 87fdb73ecb..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_add_filter_b64encode.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/*-
- * Copyright (c) 2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_string.h"
-#include "archive_write_private.h"
-
-#define LBYTES 57
-
-struct private_b64encode {
- int mode;
- struct archive_string name;
- struct archive_string encoded_buff;
- size_t bs;
- size_t hold_len;
- unsigned char hold[LBYTES];
-};
-
-static int archive_filter_b64encode_options(struct archive_write_filter *,
- const char *, const char *);
-static int archive_filter_b64encode_open(struct archive_write_filter *);
-static int archive_filter_b64encode_write(struct archive_write_filter *,
- const void *, size_t);
-static int archive_filter_b64encode_close(struct archive_write_filter *);
-static int archive_filter_b64encode_free(struct archive_write_filter *);
-static void la_b64_encode(struct archive_string *, const unsigned char *, size_t);
-static int64_t atol8(const char *, size_t);
-
-static const char base64[] = {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
- 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
- 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
- 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
- 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
- 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
- 'w', 'x', 'y', 'z', '0', '1', '2', '3',
- '4', '5', '6', '7', '8', '9', '+', '/'
-};
-
-/*
- * Add a compress filter to this write handle.
- */
-int
-archive_write_add_filter_b64encode(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct archive_write_filter *f = __archive_write_allocate_filter(_a);
- struct private_b64encode *state;
-
- archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_add_filter_uu");
-
- state = (struct private_b64encode *)calloc(1, sizeof(*state));
- if (state == NULL) {
- archive_set_error(f->archive, ENOMEM,
- "Can't allocate data for b64encode filter");
- return (ARCHIVE_FATAL);
- }
- archive_strcpy(&state->name, "-");
- state->mode = 0644;
-
- f->data = state;
- f->name = "b64encode";
- f->code = ARCHIVE_FILTER_UU;
- f->open = archive_filter_b64encode_open;
- f->options = archive_filter_b64encode_options;
- f->write = archive_filter_b64encode_write;
- f->close = archive_filter_b64encode_close;
- f->free = archive_filter_b64encode_free;
-
- return (ARCHIVE_OK);
-}
-
-/*
- * Set write options.
- */
-static int
-archive_filter_b64encode_options(struct archive_write_filter *f, const char *key,
- const char *value)
-{
- struct private_b64encode *state = (struct private_b64encode *)f->data;
-
- if (strcmp(key, "mode") == 0) {
- if (value == NULL) {
- archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
- "mode option requires octal digits");
- return (ARCHIVE_FAILED);
- }
- state->mode = (int)atol8(value, strlen(value)) & 0777;
- return (ARCHIVE_OK);
- } else if (strcmp(key, "name") == 0) {
- if (value == NULL) {
- archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
- "name option requires a string");
- return (ARCHIVE_FAILED);
- }
- archive_strcpy(&state->name, value);
- return (ARCHIVE_OK);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-/*
- * Setup callback.
- */
-static int
-archive_filter_b64encode_open(struct archive_write_filter *f)
-{
- struct private_b64encode *state = (struct private_b64encode *)f->data;
- size_t bs = 65536, bpb;
-
- if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
- /* Buffer size should be a multiple number of the of bytes
- * per block for performance. */
- bpb = archive_write_get_bytes_per_block(f->archive);
- if (bpb > bs)
- bs = bpb;
- else if (bpb != 0)
- bs -= bs % bpb;
- }
-
- state->bs = bs;
- if (archive_string_ensure(&state->encoded_buff, bs + 512) == NULL) {
- archive_set_error(f->archive, ENOMEM,
- "Can't allocate data for b64encode buffer");
- return (ARCHIVE_FATAL);
- }
-
- archive_string_sprintf(&state->encoded_buff, "begin-base64 %o %s\n",
- state->mode, state->name.s);
-
- f->data = state;
- return (0);
-}
-
-static void
-la_b64_encode(struct archive_string *as, const unsigned char *p, size_t len)
-{
- int c;
-
- for (; len >= 3; p += 3, len -= 3) {
- c = p[0] >> 2;
- archive_strappend_char(as, base64[c]);
- c = ((p[0] & 0x03) << 4) | ((p[1] & 0xf0) >> 4);
- archive_strappend_char(as, base64[c]);
- c = ((p[1] & 0x0f) << 2) | ((p[2] & 0xc0) >> 6);
- archive_strappend_char(as, base64[c]);
- c = p[2] & 0x3f;
- archive_strappend_char(as, base64[c]);
- }
- if (len > 0) {
- c = p[0] >> 2;
- archive_strappend_char(as, base64[c]);
- c = (p[0] & 0x03) << 4;
- if (len == 1) {
- archive_strappend_char(as, base64[c]);
- archive_strappend_char(as, '=');
- archive_strappend_char(as, '=');
- } else {
- c |= (p[1] & 0xf0) >> 4;
- archive_strappend_char(as, base64[c]);
- c = (p[1] & 0x0f) << 2;
- archive_strappend_char(as, base64[c]);
- archive_strappend_char(as, '=');
- }
- }
- archive_strappend_char(as, '\n');
-}
-
-/*
- * Write data to the encoded stream.
- */
-static int
-archive_filter_b64encode_write(struct archive_write_filter *f, const void *buff,
- size_t length)
-{
- struct private_b64encode *state = (struct private_b64encode *)f->data;
- const unsigned char *p = buff;
- int ret = ARCHIVE_OK;
-
- if (length == 0)
- return (ret);
-
- if (state->hold_len) {
- while (state->hold_len < LBYTES && length > 0) {
- state->hold[state->hold_len++] = *p++;
- length--;
- }
- if (state->hold_len < LBYTES)
- return (ret);
- la_b64_encode(&state->encoded_buff, state->hold, LBYTES);
- state->hold_len = 0;
- }
-
- for (; length >= LBYTES; length -= LBYTES, p += LBYTES)
- la_b64_encode(&state->encoded_buff, p, LBYTES);
-
- /* Save remaining bytes. */
- if (length > 0) {
- memcpy(state->hold, p, length);
- state->hold_len = length;
- }
- while (archive_strlen(&state->encoded_buff) >= state->bs) {
- ret = __archive_write_filter(f->next_filter,
- state->encoded_buff.s, state->bs);
- memmove(state->encoded_buff.s,
- state->encoded_buff.s + state->bs,
- state->encoded_buff.length - state->bs);
- state->encoded_buff.length -= state->bs;
- }
-
- return (ret);
-}
-
-
-/*
- * Finish the compression...
- */
-static int
-archive_filter_b64encode_close(struct archive_write_filter *f)
-{
- struct private_b64encode *state = (struct private_b64encode *)f->data;
-
- /* Flush remaining bytes. */
- if (state->hold_len != 0)
- la_b64_encode(&state->encoded_buff, state->hold, state->hold_len);
- archive_string_sprintf(&state->encoded_buff, "====\n");
- /* Write the last block */
- archive_write_set_bytes_in_last_block(f->archive, 1);
- return __archive_write_filter(f->next_filter,
- state->encoded_buff.s, archive_strlen(&state->encoded_buff));
-}
-
-static int
-archive_filter_b64encode_free(struct archive_write_filter *f)
-{
- struct private_b64encode *state = (struct private_b64encode *)f->data;
-
- archive_string_free(&state->name);
- archive_string_free(&state->encoded_buff);
- free(state);
- return (ARCHIVE_OK);
-}
-
-static int64_t
-atol8(const char *p, size_t char_cnt)
-{
- int64_t l;
- int digit;
-
- l = 0;
- while (char_cnt-- > 0) {
- if (*p >= '0' && *p <= '7')
- digit = *p - '0';
- else
- break;
- p++;
- l <<= 3;
- l |= digit;
- }
- return (l);
-}
-
diff --git a/contrib/libs/libarchive/libarchive/archive_write_add_filter_by_name.c b/contrib/libs/libarchive/libarchive/archive_write_add_filter_by_name.c
deleted file mode 100644
index ffa633c963..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_add_filter_by_name.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * Copyright (c) 2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-
-/* A table that maps names to functions. */
-static const
-struct { const char *name; int (*setter)(struct archive *); } names[] =
-{
- { "b64encode", archive_write_add_filter_b64encode },
- { "bzip2", archive_write_add_filter_bzip2 },
- { "compress", archive_write_add_filter_compress },
- { "grzip", archive_write_add_filter_grzip },
- { "gzip", archive_write_add_filter_gzip },
- { "lrzip", archive_write_add_filter_lrzip },
- { "lz4", archive_write_add_filter_lz4 },
- { "lzip", archive_write_add_filter_lzip },
- { "lzma", archive_write_add_filter_lzma },
- { "lzop", archive_write_add_filter_lzop },
- { "uuencode", archive_write_add_filter_uuencode },
- { "xz", archive_write_add_filter_xz },
- { "zstd", archive_write_add_filter_zstd },
- { NULL, NULL }
-};
-
-int
-archive_write_add_filter_by_name(struct archive *a, const char *name)
-{
- int i;
-
- for (i = 0; names[i].name != NULL; i++) {
- if (strcmp(name, names[i].name) == 0)
- return ((names[i].setter)(a));
- }
-
- archive_set_error(a, EINVAL, "No such filter '%s'", name);
- a->state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_add_filter_bzip2.c b/contrib/libs/libarchive/libarchive/archive_write_add_filter_bzip2.c
deleted file mode 100644
index 3e5c0891ae..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_add_filter_bzip2.c
+++ /dev/null
@@ -1,401 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * Copyright (c) 2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_bzip2.c 201091 2009-12-28 02:22:41Z kientzle $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_BZLIB_H
-#include <bzlib.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_write_private.h"
-
-#if ARCHIVE_VERSION_NUMBER < 4000000
-int
-archive_write_set_compression_bzip2(struct archive *a)
-{
- __archive_write_filters_free(a);
- return (archive_write_add_filter_bzip2(a));
-}
-#endif
-
-struct private_data {
- int compression_level;
-#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
- bz_stream stream;
- int64_t total_in;
- char *compressed;
- size_t compressed_buffer_size;
-#else
- struct archive_write_program_data *pdata;
-#endif
-};
-
-static int archive_compressor_bzip2_close(struct archive_write_filter *);
-static int archive_compressor_bzip2_free(struct archive_write_filter *);
-static int archive_compressor_bzip2_open(struct archive_write_filter *);
-static int archive_compressor_bzip2_options(struct archive_write_filter *,
- const char *, const char *);
-static int archive_compressor_bzip2_write(struct archive_write_filter *,
- const void *, size_t);
-
-/*
- * Add a bzip2 compression filter to this write handle.
- */
-int
-archive_write_add_filter_bzip2(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct archive_write_filter *f = __archive_write_allocate_filter(_a);
- struct private_data *data;
-
- archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_add_filter_bzip2");
-
- data = calloc(1, sizeof(*data));
- if (data == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- data->compression_level = 9; /* default */
-
- f->data = data;
- f->options = &archive_compressor_bzip2_options;
- f->close = &archive_compressor_bzip2_close;
- f->free = &archive_compressor_bzip2_free;
- f->open = &archive_compressor_bzip2_open;
- f->code = ARCHIVE_FILTER_BZIP2;
- f->name = "bzip2";
-#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
- return (ARCHIVE_OK);
-#else
- data->pdata = __archive_write_program_allocate("bzip2");
- if (data->pdata == NULL) {
- free(data);
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- data->compression_level = 0;
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Using external bzip2 program");
- return (ARCHIVE_WARN);
-#endif
-}
-
-/*
- * Set write options.
- */
-static int
-archive_compressor_bzip2_options(struct archive_write_filter *f,
- const char *key, const char *value)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- if (strcmp(key, "compression-level") == 0) {
- if (value == NULL || !(value[0] >= '0' && value[0] <= '9') ||
- value[1] != '\0')
- return (ARCHIVE_WARN);
- data->compression_level = value[0] - '0';
- /* Make '0' be a synonym for '1'. */
- /* This way, bzip2 compressor supports the same 0..9
- * range of levels as gzip. */
- if (data->compression_level < 1)
- data->compression_level = 1;
- return (ARCHIVE_OK);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
-/* Don't compile this if we don't have bzlib. */
-
-/*
- * Yuck. bzlib.h is not const-correct, so I need this one bit
- * of ugly hackery to convert a const * pointer to a non-const pointer.
- */
-#define SET_NEXT_IN(st,src) \
- (st)->stream.next_in = (char *)(uintptr_t)(const void *)(src)
-static int drive_compressor(struct archive_write_filter *,
- struct private_data *, int finishing);
-
-/*
- * Setup callback.
- */
-static int
-archive_compressor_bzip2_open(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
- int ret;
-
- if (data->compressed == NULL) {
- size_t bs = 65536, bpb;
- if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
- /* Buffer size should be a multiple number of the of bytes
- * per block for performance. */
- bpb = archive_write_get_bytes_per_block(f->archive);
- if (bpb > bs)
- bs = bpb;
- else if (bpb != 0)
- bs -= bs % bpb;
- }
- data->compressed_buffer_size = bs;
- data->compressed
- = (char *)malloc(data->compressed_buffer_size);
- if (data->compressed == NULL) {
- archive_set_error(f->archive, ENOMEM,
- "Can't allocate data for compression buffer");
- return (ARCHIVE_FATAL);
- }
- }
-
- memset(&data->stream, 0, sizeof(data->stream));
- data->stream.next_out = data->compressed;
- data->stream.avail_out = (uint32_t)data->compressed_buffer_size;
- f->write = archive_compressor_bzip2_write;
-
- /* Initialize compression library */
- ret = BZ2_bzCompressInit(&(data->stream),
- data->compression_level, 0, 30);
- if (ret == BZ_OK) {
- f->data = data;
- return (ARCHIVE_OK);
- }
-
- /* Library setup failed: clean up. */
- archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library");
-
- /* Override the error message if we know what really went wrong. */
- switch (ret) {
- case BZ_PARAM_ERROR:
- archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library: "
- "invalid setup parameter");
- break;
- case BZ_MEM_ERROR:
- archive_set_error(f->archive, ENOMEM,
- "Internal error initializing compression library: "
- "out of memory");
- break;
- case BZ_CONFIG_ERROR:
- archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library: "
- "mis-compiled library");
- break;
- }
-
- return (ARCHIVE_FATAL);
-
-}
-
-/*
- * Write data to the compressed stream.
- *
- * Returns ARCHIVE_OK if all data written, error otherwise.
- */
-static int
-archive_compressor_bzip2_write(struct archive_write_filter *f,
- const void *buff, size_t length)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- /* Update statistics */
- data->total_in += length;
-
- /* Compress input data to output buffer */
- SET_NEXT_IN(data, buff);
- data->stream.avail_in = (uint32_t)length;
- if (drive_compressor(f, data, 0))
- return (ARCHIVE_FATAL);
- return (ARCHIVE_OK);
-}
-
-
-/*
- * Finish the compression.
- */
-static int
-archive_compressor_bzip2_close(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
- int ret;
-
- /* Finish compression cycle. */
- ret = drive_compressor(f, data, 1);
- if (ret == ARCHIVE_OK) {
- /* Write the last block */
- ret = __archive_write_filter(f->next_filter,
- data->compressed,
- data->compressed_buffer_size - data->stream.avail_out);
- }
-
- switch (BZ2_bzCompressEnd(&(data->stream))) {
- case BZ_OK:
- break;
- default:
- archive_set_error(f->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Failed to clean up compressor");
- ret = ARCHIVE_FATAL;
- }
- return ret;
-}
-
-static int
-archive_compressor_bzip2_free(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
- free(data->compressed);
- free(data);
- f->data = NULL;
- return (ARCHIVE_OK);
-}
-
-/*
- * Utility function to push input data through compressor, writing
- * full output blocks as necessary.
- *
- * Note that this handles both the regular write case (finishing ==
- * false) and the end-of-archive case (finishing == true).
- */
-static int
-drive_compressor(struct archive_write_filter *f,
- struct private_data *data, int finishing)
-{
- int ret;
-
- for (;;) {
- if (data->stream.avail_out == 0) {
- ret = __archive_write_filter(f->next_filter,
- data->compressed,
- data->compressed_buffer_size);
- if (ret != ARCHIVE_OK) {
- /* TODO: Handle this write failure */
- return (ARCHIVE_FATAL);
- }
- data->stream.next_out = data->compressed;
- data->stream.avail_out = (uint32_t)data->compressed_buffer_size;
- }
-
- /* If there's nothing to do, we're done. */
- if (!finishing && data->stream.avail_in == 0)
- return (ARCHIVE_OK);
-
- ret = BZ2_bzCompress(&(data->stream),
- finishing ? BZ_FINISH : BZ_RUN);
-
- switch (ret) {
- case BZ_RUN_OK:
- /* In non-finishing case, did compressor
- * consume everything? */
- if (!finishing && data->stream.avail_in == 0)
- return (ARCHIVE_OK);
- break;
- case BZ_FINISH_OK: /* Finishing: There's more work to do */
- break;
- case BZ_STREAM_END: /* Finishing: all done */
- /* Only occurs in finishing case */
- return (ARCHIVE_OK);
- default:
- /* Any other return value indicates an error */
- archive_set_error(f->archive,
- ARCHIVE_ERRNO_PROGRAMMER,
- "Bzip2 compression failed;"
- " BZ2_bzCompress() returned %d",
- ret);
- return (ARCHIVE_FATAL);
- }
- }
-}
-
-#else /* HAVE_BZLIB_H && BZ_CONFIG_ERROR */
-
-static int
-archive_compressor_bzip2_open(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
- struct archive_string as;
- int r;
-
- archive_string_init(&as);
- archive_strcpy(&as, "bzip2");
-
- /* Specify compression level. */
- if (data->compression_level > 0) {
- archive_strcat(&as, " -");
- archive_strappend_char(&as, '0' + data->compression_level);
- }
- f->write = archive_compressor_bzip2_write;
-
- r = __archive_write_program_open(f, data->pdata, as.s);
- archive_string_free(&as);
- return (r);
-}
-
-static int
-archive_compressor_bzip2_write(struct archive_write_filter *f, const void *buff,
- size_t length)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- return __archive_write_program_write(f, data->pdata, buff, length);
-}
-
-static int
-archive_compressor_bzip2_close(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- return __archive_write_program_close(f, data->pdata);
-}
-
-static int
-archive_compressor_bzip2_free(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- __archive_write_program_free(data->pdata);
- free(data);
- return (ARCHIVE_OK);
-}
-
-#endif /* HAVE_BZLIB_H && BZ_CONFIG_ERROR */
diff --git a/contrib/libs/libarchive/libarchive/archive_write_add_filter_compress.c b/contrib/libs/libarchive/libarchive/archive_write_add_filter_compress.c
deleted file mode 100644
index 3ed269fce9..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_add_filter_compress.c
+++ /dev/null
@@ -1,447 +0,0 @@
-/*-
- * Copyright (c) 2008 Joerg Sonnenberger
- * 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(S) ``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(S) 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.
- */
-
-/*-
- * Copyright (c) 1985, 1986, 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Diomidis Spinellis and James A. Woods, derived from original
- * work by Spencer Thomas and Joseph Orost.
- *
- * 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.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 "archive_platform.h"
-
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_compress.c 201111 2009-12-28 03:33:05Z kientzle $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_write_private.h"
-
-#define HSIZE 69001 /* 95% occupancy */
-#define HSHIFT 8 /* 8 - trunc(log2(HSIZE / 65536)) */
-#define CHECK_GAP 10000 /* Ratio check interval. */
-
-#define MAXCODE(bits) ((1 << (bits)) - 1)
-
-/*
- * the next two codes should not be changed lightly, as they must not
- * lie within the contiguous general code space.
- */
-#define FIRST 257 /* First free entry. */
-#define CLEAR 256 /* Table clear output code. */
-
-struct private_data {
- int64_t in_count, out_count, checkpoint;
-
- int code_len; /* Number of bits/code. */
- int cur_maxcode; /* Maximum code, given n_bits. */
- int max_maxcode; /* Should NEVER generate this code. */
- int hashtab [HSIZE];
- unsigned short codetab [HSIZE];
- int first_free; /* First unused entry. */
- int compress_ratio;
-
- int cur_code, cur_fcode;
-
- int bit_offset;
- unsigned char bit_buf;
-
- unsigned char *compressed;
- size_t compressed_buffer_size;
- size_t compressed_offset;
-};
-
-static int archive_compressor_compress_open(struct archive_write_filter *);
-static int archive_compressor_compress_write(struct archive_write_filter *,
- const void *, size_t);
-static int archive_compressor_compress_close(struct archive_write_filter *);
-static int archive_compressor_compress_free(struct archive_write_filter *);
-
-#if ARCHIVE_VERSION_NUMBER < 4000000
-int
-archive_write_set_compression_compress(struct archive *a)
-{
- __archive_write_filters_free(a);
- return (archive_write_add_filter_compress(a));
-}
-#endif
-
-/*
- * Add a compress filter to this write handle.
- */
-int
-archive_write_add_filter_compress(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct archive_write_filter *f = __archive_write_allocate_filter(_a);
-
- archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_add_filter_compress");
- f->open = &archive_compressor_compress_open;
- f->code = ARCHIVE_FILTER_COMPRESS;
- f->name = "compress";
- return (ARCHIVE_OK);
-}
-
-/*
- * Setup callback.
- */
-static int
-archive_compressor_compress_open(struct archive_write_filter *f)
-{
- struct private_data *state;
- size_t bs = 65536, bpb;
-
- f->code = ARCHIVE_FILTER_COMPRESS;
- f->name = "compress";
-
- state = (struct private_data *)calloc(1, sizeof(*state));
- if (state == NULL) {
- archive_set_error(f->archive, ENOMEM,
- "Can't allocate data for compression");
- return (ARCHIVE_FATAL);
- }
-
- if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
- /* Buffer size should be a multiple number of the of bytes
- * per block for performance. */
- bpb = archive_write_get_bytes_per_block(f->archive);
- if (bpb > bs)
- bs = bpb;
- else if (bpb != 0)
- bs -= bs % bpb;
- }
- state->compressed_buffer_size = bs;
- state->compressed = malloc(state->compressed_buffer_size);
-
- if (state->compressed == NULL) {
- archive_set_error(f->archive, ENOMEM,
- "Can't allocate data for compression buffer");
- free(state);
- return (ARCHIVE_FATAL);
- }
-
- f->write = archive_compressor_compress_write;
- f->close = archive_compressor_compress_close;
- f->free = archive_compressor_compress_free;
-
- state->max_maxcode = 0x10000; /* Should NEVER generate this code. */
- state->in_count = 0; /* Length of input. */
- state->bit_buf = 0;
- state->bit_offset = 0;
- state->out_count = 3; /* Includes 3-byte header mojo. */
- state->compress_ratio = 0;
- state->checkpoint = CHECK_GAP;
- state->code_len = 9;
- state->cur_maxcode = MAXCODE(state->code_len);
- state->first_free = FIRST;
-
- memset(state->hashtab, 0xff, sizeof(state->hashtab));
-
- /* Prime output buffer with a gzip header. */
- state->compressed[0] = 0x1f; /* Compress */
- state->compressed[1] = 0x9d;
- state->compressed[2] = 0x90; /* Block mode, 16bit max */
- state->compressed_offset = 3;
-
- f->data = state;
- return (0);
-}
-
-/*-
- * Output the given code.
- * Inputs:
- * code: A n_bits-bit integer. If == -1, then EOF. This assumes
- * that n_bits <= (long)wordsize - 1.
- * Outputs:
- * Outputs code to the file.
- * Assumptions:
- * Chars are 8 bits long.
- * Algorithm:
- * Maintain a BITS character long buffer (so that 8 codes will
- * fit in it exactly). Use the VAX insv instruction to insert each
- * code in turn. When the buffer fills up empty it and start over.
- */
-
-static const unsigned char rmask[9] =
- {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
-
-static int
-output_byte(struct archive_write_filter *f, unsigned char c)
-{
- struct private_data *state = f->data;
-
- state->compressed[state->compressed_offset++] = c;
- ++state->out_count;
-
- if (state->compressed_buffer_size == state->compressed_offset) {
- int ret = __archive_write_filter(f->next_filter,
- state->compressed, state->compressed_buffer_size);
- if (ret != ARCHIVE_OK)
- return ARCHIVE_FATAL;
- state->compressed_offset = 0;
- }
-
- return ARCHIVE_OK;
-}
-
-static int
-output_code(struct archive_write_filter *f, int ocode)
-{
- struct private_data *state = f->data;
- int bits, ret, clear_flg, bit_offset;
-
- clear_flg = ocode == CLEAR;
-
- /*
- * Since ocode is always >= 8 bits, only need to mask the first
- * hunk on the left.
- */
- bit_offset = state->bit_offset % 8;
- state->bit_buf |= (ocode << bit_offset) & 0xff;
- output_byte(f, state->bit_buf);
-
- bits = state->code_len - (8 - bit_offset);
- ocode >>= 8 - bit_offset;
- /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
- if (bits >= 8) {
- output_byte(f, ocode & 0xff);
- ocode >>= 8;
- bits -= 8;
- }
- /* Last bits. */
- state->bit_offset += state->code_len;
- state->bit_buf = ocode & rmask[bits];
- if (state->bit_offset == state->code_len * 8)
- state->bit_offset = 0;
-
- /*
- * If the next entry is going to be too big for the ocode size,
- * then increase it, if possible.
- */
- if (clear_flg || state->first_free > state->cur_maxcode) {
- /*
- * Write the whole buffer, because the input side won't
- * discover the size increase until after it has read it.
- */
- if (state->bit_offset > 0) {
- while (state->bit_offset < state->code_len * 8) {
- ret = output_byte(f, state->bit_buf);
- if (ret != ARCHIVE_OK)
- return ret;
- state->bit_offset += 8;
- state->bit_buf = 0;
- }
- }
- state->bit_buf = 0;
- state->bit_offset = 0;
-
- if (clear_flg) {
- state->code_len = 9;
- state->cur_maxcode = MAXCODE(state->code_len);
- } else {
- state->code_len++;
- if (state->code_len == 16)
- state->cur_maxcode = state->max_maxcode;
- else
- state->cur_maxcode = MAXCODE(state->code_len);
- }
- }
-
- return (ARCHIVE_OK);
-}
-
-static int
-output_flush(struct archive_write_filter *f)
-{
- struct private_data *state = f->data;
- int ret;
-
- /* At EOF, write the rest of the buffer. */
- if (state->bit_offset % 8) {
- state->code_len = (state->bit_offset % 8 + 7) / 8;
- ret = output_byte(f, state->bit_buf);
- if (ret != ARCHIVE_OK)
- return ret;
- }
-
- return (ARCHIVE_OK);
-}
-
-/*
- * Write data to the compressed stream.
- */
-static int
-archive_compressor_compress_write(struct archive_write_filter *f,
- const void *buff, size_t length)
-{
- struct private_data *state = (struct private_data *)f->data;
- int i;
- int ratio;
- int c, disp, ret;
- const unsigned char *bp;
-
- if (length == 0)
- return ARCHIVE_OK;
-
- bp = buff;
-
- if (state->in_count == 0) {
- state->cur_code = *bp++;
- ++state->in_count;
- --length;
- }
-
- while (length--) {
- c = *bp++;
- state->in_count++;
- state->cur_fcode = (c << 16) | state->cur_code;
- i = ((c << HSHIFT) ^ state->cur_code); /* Xor hashing. */
-
- if (state->hashtab[i] == state->cur_fcode) {
- state->cur_code = state->codetab[i];
- continue;
- }
- if (state->hashtab[i] < 0) /* Empty slot. */
- goto nomatch;
- /* Secondary hash (after G. Knott). */
- if (i == 0)
- disp = 1;
- else
- disp = HSIZE - i;
- probe:
- if ((i -= disp) < 0)
- i += HSIZE;
-
- if (state->hashtab[i] == state->cur_fcode) {
- state->cur_code = state->codetab[i];
- continue;
- }
- if (state->hashtab[i] >= 0)
- goto probe;
- nomatch:
- ret = output_code(f, state->cur_code);
- if (ret != ARCHIVE_OK)
- return ret;
- state->cur_code = c;
- if (state->first_free < state->max_maxcode) {
- state->codetab[i] = state->first_free++; /* code -> hashtable */
- state->hashtab[i] = state->cur_fcode;
- continue;
- }
- if (state->in_count < state->checkpoint)
- continue;
-
- state->checkpoint = state->in_count + CHECK_GAP;
-
- if (state->in_count <= 0x007fffff && state->out_count != 0)
- ratio = (int)(state->in_count * 256 / state->out_count);
- else if ((ratio = (int)(state->out_count / 256)) == 0)
- ratio = 0x7fffffff;
- else
- ratio = (int)(state->in_count / ratio);
-
- if (ratio > state->compress_ratio)
- state->compress_ratio = ratio;
- else {
- state->compress_ratio = 0;
- memset(state->hashtab, 0xff, sizeof(state->hashtab));
- state->first_free = FIRST;
- ret = output_code(f, CLEAR);
- if (ret != ARCHIVE_OK)
- return ret;
- }
- }
-
- return (ARCHIVE_OK);
-}
-
-
-/*
- * Finish the compression...
- */
-static int
-archive_compressor_compress_close(struct archive_write_filter *f)
-{
- struct private_data *state = (struct private_data *)f->data;
- int ret;
-
- ret = output_code(f, state->cur_code);
- if (ret != ARCHIVE_OK)
- return ret;
- ret = output_flush(f);
- if (ret != ARCHIVE_OK)
- return ret;
-
- /* Write the last block */
- ret = __archive_write_filter(f->next_filter,
- state->compressed, state->compressed_offset);
- return (ret);
-}
-
-static int
-archive_compressor_compress_free(struct archive_write_filter *f)
-{
- struct private_data *state = (struct private_data *)f->data;
-
- free(state->compressed);
- free(state);
- return (ARCHIVE_OK);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_add_filter_grzip.c b/contrib/libs/libarchive/libarchive/archive_write_add_filter_grzip.c
deleted file mode 100644
index 371102d74c..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_add_filter_grzip.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#include "archive.h"
-#include "archive_write_private.h"
-
-struct write_grzip {
- struct archive_write_program_data *pdata;
-};
-
-static int archive_write_grzip_open(struct archive_write_filter *);
-static int archive_write_grzip_options(struct archive_write_filter *,
- const char *, const char *);
-static int archive_write_grzip_write(struct archive_write_filter *,
- const void *, size_t);
-static int archive_write_grzip_close(struct archive_write_filter *);
-static int archive_write_grzip_free(struct archive_write_filter *);
-
-int
-archive_write_add_filter_grzip(struct archive *_a)
-{
- struct archive_write_filter *f = __archive_write_allocate_filter(_a);
- struct write_grzip *data;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_add_filter_grzip");
-
- data = calloc(1, sizeof(*data));
- if (data == NULL) {
- archive_set_error(_a, ENOMEM, "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- data->pdata = __archive_write_program_allocate("grzip");
- if (data->pdata == NULL) {
- free(data);
- archive_set_error(_a, ENOMEM, "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
-
- f->name = "grzip";
- f->code = ARCHIVE_FILTER_GRZIP;
- f->data = data;
- f->open = archive_write_grzip_open;
- f->options = archive_write_grzip_options;
- f->write = archive_write_grzip_write;
- f->close = archive_write_grzip_close;
- f->free = archive_write_grzip_free;
-
- /* Note: This filter always uses an external program, so we
- * return "warn" to inform of the fact. */
- archive_set_error(_a, ARCHIVE_ERRNO_MISC,
- "Using external grzip program for grzip compression");
- return (ARCHIVE_WARN);
-}
-
-static int
-archive_write_grzip_options(struct archive_write_filter *f, const char *key,
- const char *value)
-{
- (void)f; /* UNUSED */
- (void)key; /* UNUSED */
- (void)value; /* UNUSED */
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-static int
-archive_write_grzip_open(struct archive_write_filter *f)
-{
- struct write_grzip *data = (struct write_grzip *)f->data;
-
- return __archive_write_program_open(f, data->pdata, "grzip");
-}
-
-static int
-archive_write_grzip_write(struct archive_write_filter *f,
- const void *buff, size_t length)
-{
- struct write_grzip *data = (struct write_grzip *)f->data;
-
- return __archive_write_program_write(f, data->pdata, buff, length);
-}
-
-static int
-archive_write_grzip_close(struct archive_write_filter *f)
-{
- struct write_grzip *data = (struct write_grzip *)f->data;
-
- return __archive_write_program_close(f, data->pdata);
-}
-
-static int
-archive_write_grzip_free(struct archive_write_filter *f)
-{
- struct write_grzip *data = (struct write_grzip *)f->data;
-
- __archive_write_program_free(data->pdata);
- free(data);
- return (ARCHIVE_OK);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_add_filter_gzip.c b/contrib/libs/libarchive/libarchive/archive_write_add_filter_gzip.c
deleted file mode 100644
index 8670d5ca74..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_add_filter_gzip.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_gzip.c 201081 2009-12-28 02:04:42Z kientzle $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#include <time.h>
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_string.h"
-#include "archive_write_private.h"
-
-#if ARCHIVE_VERSION_NUMBER < 4000000
-int
-archive_write_set_compression_gzip(struct archive *a)
-{
- __archive_write_filters_free(a);
- return (archive_write_add_filter_gzip(a));
-}
-#endif
-
-/* Don't compile this if we don't have zlib. */
-
-struct private_data {
- int compression_level;
- int timestamp;
-#ifdef HAVE_ZLIB_H
- z_stream stream;
- int64_t total_in;
- unsigned char *compressed;
- size_t compressed_buffer_size;
- unsigned long crc;
-#else
- struct archive_write_program_data *pdata;
-#endif
-};
-
-/*
- * Yuck. zlib.h is not const-correct, so I need this one bit
- * of ugly hackery to convert a const * pointer to a non-const pointer.
- */
-#define SET_NEXT_IN(st,src) \
- (st)->stream.next_in = (Bytef *)(uintptr_t)(const void *)(src)
-
-static int archive_compressor_gzip_options(struct archive_write_filter *,
- const char *, const char *);
-static int archive_compressor_gzip_open(struct archive_write_filter *);
-static int archive_compressor_gzip_write(struct archive_write_filter *,
- const void *, size_t);
-static int archive_compressor_gzip_close(struct archive_write_filter *);
-static int archive_compressor_gzip_free(struct archive_write_filter *);
-#ifdef HAVE_ZLIB_H
-static int drive_compressor(struct archive_write_filter *,
- struct private_data *, int finishing);
-#endif
-
-
-/*
- * Add a gzip compression filter to this write handle.
- */
-int
-archive_write_add_filter_gzip(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct archive_write_filter *f = __archive_write_allocate_filter(_a);
- struct private_data *data;
- archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_add_filter_gzip");
-
- data = calloc(1, sizeof(*data));
- if (data == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- f->data = data;
- f->open = &archive_compressor_gzip_open;
- f->options = &archive_compressor_gzip_options;
- f->close = &archive_compressor_gzip_close;
- f->free = &archive_compressor_gzip_free;
- f->code = ARCHIVE_FILTER_GZIP;
- f->name = "gzip";
-#ifdef HAVE_ZLIB_H
- data->compression_level = Z_DEFAULT_COMPRESSION;
- return (ARCHIVE_OK);
-#else
- data->pdata = __archive_write_program_allocate("gzip");
- if (data->pdata == NULL) {
- free(data);
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- data->compression_level = 0;
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Using external gzip program");
- return (ARCHIVE_WARN);
-#endif
-}
-
-static int
-archive_compressor_gzip_free(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
-
-#ifdef HAVE_ZLIB_H
- free(data->compressed);
-#else
- __archive_write_program_free(data->pdata);
-#endif
- free(data);
- f->data = NULL;
- return (ARCHIVE_OK);
-}
-
-/*
- * Set write options.
- */
-static int
-archive_compressor_gzip_options(struct archive_write_filter *f, const char *key,
- const char *value)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- if (strcmp(key, "compression-level") == 0) {
- if (value == NULL || !(value[0] >= '0' && value[0] <= '9') ||
- value[1] != '\0')
- return (ARCHIVE_WARN);
- data->compression_level = value[0] - '0';
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "timestamp") == 0) {
- data->timestamp = (value == NULL)?-1:1;
- return (ARCHIVE_OK);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-#ifdef HAVE_ZLIB_H
-/*
- * Setup callback.
- */
-static int
-archive_compressor_gzip_open(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
- int ret;
-
- if (data->compressed == NULL) {
- size_t bs = 65536, bpb;
- if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
- /* Buffer size should be a multiple number of
- * the of bytes per block for performance. */
- bpb = archive_write_get_bytes_per_block(f->archive);
- if (bpb > bs)
- bs = bpb;
- else if (bpb != 0)
- bs -= bs % bpb;
- }
- data->compressed_buffer_size = bs;
- data->compressed
- = (unsigned char *)malloc(data->compressed_buffer_size);
- if (data->compressed == NULL) {
- archive_set_error(f->archive, ENOMEM,
- "Can't allocate data for compression buffer");
- return (ARCHIVE_FATAL);
- }
- }
-
- data->crc = crc32(0L, NULL, 0);
- data->stream.next_out = data->compressed;
- data->stream.avail_out = (uInt)data->compressed_buffer_size;
-
- /* Prime output buffer with a gzip header. */
- data->compressed[0] = 0x1f; /* GZip signature bytes */
- data->compressed[1] = 0x8b;
- data->compressed[2] = 0x08; /* "Deflate" compression */
- data->compressed[3] = 0; /* No options */
- if (data->timestamp >= 0) {
- time_t t = time(NULL);
- data->compressed[4] = (uint8_t)(t)&0xff; /* Timestamp */
- data->compressed[5] = (uint8_t)(t>>8)&0xff;
- data->compressed[6] = (uint8_t)(t>>16)&0xff;
- data->compressed[7] = (uint8_t)(t>>24)&0xff;
- } else
- memset(&data->compressed[4], 0, 4);
- if (data->compression_level == 9)
- data->compressed[8] = 2;
- else if(data->compression_level == 1)
- data->compressed[8] = 4;
- else
- data->compressed[8] = 0;
- data->compressed[9] = 3; /* OS=Unix */
- data->stream.next_out += 10;
- data->stream.avail_out -= 10;
-
- f->write = archive_compressor_gzip_write;
-
- /* Initialize compression library. */
- ret = deflateInit2(&(data->stream),
- data->compression_level,
- Z_DEFLATED,
- -15 /* < 0 to suppress zlib header */,
- 8,
- Z_DEFAULT_STRATEGY);
-
- if (ret == Z_OK) {
- f->data = data;
- return (ARCHIVE_OK);
- }
-
- /* Library setup failed: clean up. */
- archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, "Internal error "
- "initializing compression library");
-
- /* Override the error message if we know what really went wrong. */
- switch (ret) {
- case Z_STREAM_ERROR:
- archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
- "Internal error initializing "
- "compression library: invalid setup parameter");
- break;
- case Z_MEM_ERROR:
- archive_set_error(f->archive, ENOMEM,
- "Internal error initializing compression library");
- break;
- case Z_VERSION_ERROR:
- archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
- "Internal error initializing "
- "compression library: invalid library version");
- break;
- }
-
- return (ARCHIVE_FATAL);
-}
-
-/*
- * Write data to the compressed stream.
- */
-static int
-archive_compressor_gzip_write(struct archive_write_filter *f, const void *buff,
- size_t length)
-{
- struct private_data *data = (struct private_data *)f->data;
- int ret;
-
- /* Update statistics */
- data->crc = crc32(data->crc, (const Bytef *)buff, (uInt)length);
- data->total_in += length;
-
- /* Compress input data to output buffer */
- SET_NEXT_IN(data, buff);
- data->stream.avail_in = (uInt)length;
- if ((ret = drive_compressor(f, data, 0)) != ARCHIVE_OK)
- return (ret);
-
- return (ARCHIVE_OK);
-}
-
-/*
- * Finish the compression...
- */
-static int
-archive_compressor_gzip_close(struct archive_write_filter *f)
-{
- unsigned char trailer[8];
- struct private_data *data = (struct private_data *)f->data;
- int ret;
-
- /* Finish compression cycle */
- ret = drive_compressor(f, data, 1);
- if (ret == ARCHIVE_OK) {
- /* Write the last compressed data. */
- ret = __archive_write_filter(f->next_filter,
- data->compressed,
- data->compressed_buffer_size - data->stream.avail_out);
- }
- if (ret == ARCHIVE_OK) {
- /* Build and write out 8-byte trailer. */
- trailer[0] = (uint8_t)(data->crc)&0xff;
- trailer[1] = (uint8_t)(data->crc >> 8)&0xff;
- trailer[2] = (uint8_t)(data->crc >> 16)&0xff;
- trailer[3] = (uint8_t)(data->crc >> 24)&0xff;
- trailer[4] = (uint8_t)(data->total_in)&0xff;
- trailer[5] = (uint8_t)(data->total_in >> 8)&0xff;
- trailer[6] = (uint8_t)(data->total_in >> 16)&0xff;
- trailer[7] = (uint8_t)(data->total_in >> 24)&0xff;
- ret = __archive_write_filter(f->next_filter, trailer, 8);
- }
-
- switch (deflateEnd(&(data->stream))) {
- case Z_OK:
- break;
- default:
- archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
- "Failed to clean up compressor");
- ret = ARCHIVE_FATAL;
- }
- return ret;
-}
-
-/*
- * Utility function to push input data through compressor,
- * writing full output blocks as necessary.
- *
- * Note that this handles both the regular write case (finishing ==
- * false) and the end-of-archive case (finishing == true).
- */
-static int
-drive_compressor(struct archive_write_filter *f,
- struct private_data *data, int finishing)
-{
- int ret;
-
- for (;;) {
- if (data->stream.avail_out == 0) {
- ret = __archive_write_filter(f->next_filter,
- data->compressed,
- data->compressed_buffer_size);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- data->stream.next_out = data->compressed;
- data->stream.avail_out =
- (uInt)data->compressed_buffer_size;
- }
-
- /* If there's nothing to do, we're done. */
- if (!finishing && data->stream.avail_in == 0)
- return (ARCHIVE_OK);
-
- ret = deflate(&(data->stream),
- finishing ? Z_FINISH : Z_NO_FLUSH );
-
- switch (ret) {
- case Z_OK:
- /* In non-finishing case, check if compressor
- * consumed everything */
- if (!finishing && data->stream.avail_in == 0)
- return (ARCHIVE_OK);
- /* In finishing case, this return always means
- * there's more work */
- break;
- case Z_STREAM_END:
- /* This return can only occur in finishing case. */
- return (ARCHIVE_OK);
- default:
- /* Any other return value indicates an error. */
- archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
- "GZip compression failed:"
- " deflate() call returned status %d",
- ret);
- return (ARCHIVE_FATAL);
- }
- }
-}
-
-#else /* HAVE_ZLIB_H */
-
-static int
-archive_compressor_gzip_open(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
- struct archive_string as;
- int r;
-
- archive_string_init(&as);
- archive_strcpy(&as, "gzip");
-
- /* Specify compression level. */
- if (data->compression_level > 0) {
- archive_strcat(&as, " -");
- archive_strappend_char(&as, '0' + data->compression_level);
- }
- if (data->timestamp < 0)
- /* Do not save timestamp. */
- archive_strcat(&as, " -n");
- else if (data->timestamp > 0)
- /* Save timestamp. */
- archive_strcat(&as, " -N");
-
- f->write = archive_compressor_gzip_write;
- r = __archive_write_program_open(f, data->pdata, as.s);
- archive_string_free(&as);
- return (r);
-}
-
-static int
-archive_compressor_gzip_write(struct archive_write_filter *f, const void *buff,
- size_t length)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- return __archive_write_program_write(f, data->pdata, buff, length);
-}
-
-static int
-archive_compressor_gzip_close(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- return __archive_write_program_close(f, data->pdata);
-}
-
-#endif /* HAVE_ZLIB_H */
diff --git a/contrib/libs/libarchive/libarchive/archive_write_add_filter_lrzip.c b/contrib/libs/libarchive/libarchive/archive_write_add_filter_lrzip.c
deleted file mode 100644
index e215f89032..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_add_filter_lrzip.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_string.h"
-#include "archive_write_private.h"
-
-struct write_lrzip {
- struct archive_write_program_data *pdata;
- int compression_level;
- enum { lzma = 0, bzip2, gzip, lzo, none, zpaq } compression;
-};
-
-static int archive_write_lrzip_open(struct archive_write_filter *);
-static int archive_write_lrzip_options(struct archive_write_filter *,
- const char *, const char *);
-static int archive_write_lrzip_write(struct archive_write_filter *,
- const void *, size_t);
-static int archive_write_lrzip_close(struct archive_write_filter *);
-static int archive_write_lrzip_free(struct archive_write_filter *);
-
-int
-archive_write_add_filter_lrzip(struct archive *_a)
-{
- struct archive_write_filter *f = __archive_write_allocate_filter(_a);
- struct write_lrzip *data;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_add_filter_lrzip");
-
- data = calloc(1, sizeof(*data));
- if (data == NULL) {
- archive_set_error(_a, ENOMEM, "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- data->pdata = __archive_write_program_allocate("lrzip");
- if (data->pdata == NULL) {
- free(data);
- archive_set_error(_a, ENOMEM, "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
-
- f->name = "lrzip";
- f->code = ARCHIVE_FILTER_LRZIP;
- f->data = data;
- f->open = archive_write_lrzip_open;
- f->options = archive_write_lrzip_options;
- f->write = archive_write_lrzip_write;
- f->close = archive_write_lrzip_close;
- f->free = archive_write_lrzip_free;
-
- /* Note: This filter always uses an external program, so we
- * return "warn" to inform of the fact. */
- archive_set_error(_a, ARCHIVE_ERRNO_MISC,
- "Using external lrzip program for lrzip compression");
- return (ARCHIVE_WARN);
-}
-
-static int
-archive_write_lrzip_options(struct archive_write_filter *f, const char *key,
- const char *value)
-{
- struct write_lrzip *data = (struct write_lrzip *)f->data;
-
- if (strcmp(key, "compression") == 0) {
- if (value == NULL)
- return (ARCHIVE_WARN);
- else if (strcmp(value, "bzip2") == 0)
- data->compression = bzip2;
- else if (strcmp(value, "gzip") == 0)
- data->compression = gzip;
- else if (strcmp(value, "lzo") == 0)
- data->compression = lzo;
- else if (strcmp(value, "none") == 0)
- data->compression = none;
- else if (strcmp(value, "zpaq") == 0)
- data->compression = zpaq;
- else
- return (ARCHIVE_WARN);
- return (ARCHIVE_OK);
- } else if (strcmp(key, "compression-level") == 0) {
- if (value == NULL || !(value[0] >= '1' && value[0] <= '9') ||
- value[1] != '\0')
- return (ARCHIVE_WARN);
- data->compression_level = value[0] - '0';
- return (ARCHIVE_OK);
- }
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-static int
-archive_write_lrzip_open(struct archive_write_filter *f)
-{
- struct write_lrzip *data = (struct write_lrzip *)f->data;
- struct archive_string as;
- int r;
-
- archive_string_init(&as);
- archive_strcpy(&as, "lrzip -q");
-
- /* Specify compression type. */
- switch (data->compression) {
- case lzma:/* default compression */
- break;
- case bzip2:
- archive_strcat(&as, " -b");
- break;
- case gzip:
- archive_strcat(&as, " -g");
- break;
- case lzo:
- archive_strcat(&as, " -l");
- break;
- case none:
- archive_strcat(&as, " -n");
- break;
- case zpaq:
- archive_strcat(&as, " -z");
- break;
- }
-
- /* Specify compression level. */
- if (data->compression_level > 0) {
- archive_strcat(&as, " -L ");
- archive_strappend_char(&as, '0' + data->compression_level);
- }
-
- r = __archive_write_program_open(f, data->pdata, as.s);
- archive_string_free(&as);
- return (r);
-}
-
-static int
-archive_write_lrzip_write(struct archive_write_filter *f,
- const void *buff, size_t length)
-{
- struct write_lrzip *data = (struct write_lrzip *)f->data;
-
- return __archive_write_program_write(f, data->pdata, buff, length);
-}
-
-static int
-archive_write_lrzip_close(struct archive_write_filter *f)
-{
- struct write_lrzip *data = (struct write_lrzip *)f->data;
-
- return __archive_write_program_close(f, data->pdata);
-}
-
-static int
-archive_write_lrzip_free(struct archive_write_filter *f)
-{
- struct write_lrzip *data = (struct write_lrzip *)f->data;
-
- __archive_write_program_free(data->pdata);
- free(data);
- return (ARCHIVE_OK);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_add_filter_lz4.c b/contrib/libs/libarchive/libarchive/archive_write_add_filter_lz4.c
deleted file mode 100644
index 6ac450357d..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_add_filter_lz4.c
+++ /dev/null
@@ -1,700 +0,0 @@
-/*-
- * Copyright (c) 2014 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_LZ4_H
-#include <lz4.h>
-#endif
-#ifdef HAVE_LZ4HC_H
-#include <lz4hc.h>
-#endif
-
-#include "archive.h"
-#include "archive_endian.h"
-#include "archive_private.h"
-#include "archive_write_private.h"
-#include "archive_xxhash.h"
-
-#define LZ4_MAGICNUMBER 0x184d2204
-
-struct private_data {
- int compression_level;
- unsigned header_written:1;
- unsigned version_number:1;
- unsigned block_independence:1;
- unsigned block_checksum:1;
- unsigned stream_size:1;
- unsigned stream_checksum:1;
- unsigned preset_dictionary:1;
- unsigned block_maximum_size:3;
-#if defined(HAVE_LIBLZ4) && LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 2
- int64_t total_in;
- char *out;
- char *out_buffer;
- size_t out_buffer_size;
- size_t out_block_size;
- char *in;
- char *in_buffer_allocated;
- char *in_buffer;
- size_t in_buffer_size;
- size_t block_size;
-
- void *xxh32_state;
- void *lz4_stream;
-#else
- struct archive_write_program_data *pdata;
-#endif
-};
-
-static int archive_filter_lz4_close(struct archive_write_filter *);
-static int archive_filter_lz4_free(struct archive_write_filter *);
-static int archive_filter_lz4_open(struct archive_write_filter *);
-static int archive_filter_lz4_options(struct archive_write_filter *,
- const char *, const char *);
-static int archive_filter_lz4_write(struct archive_write_filter *,
- const void *, size_t);
-
-/*
- * Add a lz4 compression filter to this write handle.
- */
-int
-archive_write_add_filter_lz4(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct archive_write_filter *f = __archive_write_allocate_filter(_a);
- struct private_data *data;
-
- archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_add_filter_lz4");
-
- data = calloc(1, sizeof(*data));
- if (data == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
-
- /*
- * Setup default settings.
- */
- data->compression_level = 1;
- data->version_number = 0x01;
- data->block_independence = 1;
- data->block_checksum = 0;
- data->stream_size = 0;
- data->stream_checksum = 1;
- data->preset_dictionary = 0;
- data->block_maximum_size = 7;
-
- /*
- * Setup a filter setting.
- */
- f->data = data;
- f->options = &archive_filter_lz4_options;
- f->close = &archive_filter_lz4_close;
- f->free = &archive_filter_lz4_free;
- f->open = &archive_filter_lz4_open;
- f->code = ARCHIVE_FILTER_LZ4;
- f->name = "lz4";
-#if defined(HAVE_LIBLZ4) && LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 2
- return (ARCHIVE_OK);
-#else
- /*
- * We don't have lz4 library, and execute external lz4 program
- * instead.
- */
- data->pdata = __archive_write_program_allocate("lz4");
- if (data->pdata == NULL) {
- free(data);
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- data->compression_level = 0;
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Using external lz4 program");
- return (ARCHIVE_WARN);
-#endif
-}
-
-/*
- * Set write options.
- */
-static int
-archive_filter_lz4_options(struct archive_write_filter *f,
- const char *key, const char *value)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- if (strcmp(key, "compression-level") == 0) {
- int val;
- if (value == NULL || !((val = value[0] - '0') >= 1 && val <= 9) ||
- value[1] != '\0')
- return (ARCHIVE_WARN);
-
-#ifndef HAVE_LZ4HC_H
- if(val >= 3)
- {
- archive_set_error(f->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "High compression not included in this build");
- return (ARCHIVE_FATAL);
- }
-#endif
- data->compression_level = val;
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "stream-checksum") == 0) {
- data->stream_checksum = value != NULL;
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "block-checksum") == 0) {
- data->block_checksum = value != NULL;
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "block-size") == 0) {
- if (value == NULL || !(value[0] >= '4' && value[0] <= '7') ||
- value[1] != '\0')
- return (ARCHIVE_WARN);
- data->block_maximum_size = value[0] - '0';
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "block-dependence") == 0) {
- data->block_independence = value == NULL;
- return (ARCHIVE_OK);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-#if defined(HAVE_LIBLZ4) && LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 2
-/* Don't compile this if we don't have liblz4. */
-
-static int drive_compressor(struct archive_write_filter *, const char *,
- size_t);
-static int drive_compressor_independence(struct archive_write_filter *,
- const char *, size_t);
-static int drive_compressor_dependence(struct archive_write_filter *,
- const char *, size_t);
-static int lz4_write_stream_descriptor(struct archive_write_filter *);
-static ssize_t lz4_write_one_block(struct archive_write_filter *, const char *,
- size_t);
-
-
-/*
- * Setup callback.
- */
-static int
-archive_filter_lz4_open(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
- size_t required_size;
- static size_t const bkmap[] = { 64 * 1024, 256 * 1024, 1 * 1024 * 1024,
- 4 * 1024 * 1024 };
- size_t pre_block_size;
-
- if (data->block_maximum_size < 4)
- data->block_size = bkmap[0];
- else
- data->block_size = bkmap[data->block_maximum_size - 4];
-
- required_size = 4 + 15 + 4 + data->block_size + 4 + 4;
- if (data->out_buffer_size < required_size) {
- size_t bs = required_size, bpb;
- free(data->out_buffer);
- if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
- /* Buffer size should be a multiple number of
- * the of bytes per block for performance. */
- bpb = archive_write_get_bytes_per_block(f->archive);
- if (bpb > bs)
- bs = bpb;
- else if (bpb != 0) {
- bs += bpb;
- bs -= bs % bpb;
- }
- }
- data->out_block_size = bs;
- bs += required_size;
- data->out_buffer = malloc(bs);
- data->out = data->out_buffer;
- data->out_buffer_size = bs;
- }
-
- pre_block_size = (data->block_independence)? 0: 64 * 1024;
- if (data->in_buffer_size < data->block_size + pre_block_size) {
- free(data->in_buffer_allocated);
- data->in_buffer_size = data->block_size;
- data->in_buffer_allocated =
- malloc(data->in_buffer_size + pre_block_size);
- data->in_buffer = data->in_buffer_allocated + pre_block_size;
- if (!data->block_independence && data->compression_level >= 3)
- data->in_buffer = data->in_buffer_allocated;
- data->in = data->in_buffer;
- data->in_buffer_size = data->block_size;
- }
-
- if (data->out_buffer == NULL || data->in_buffer_allocated == NULL) {
- archive_set_error(f->archive, ENOMEM,
- "Can't allocate data for compression buffer");
- return (ARCHIVE_FATAL);
- }
-
- f->write = archive_filter_lz4_write;
-
- return (ARCHIVE_OK);
-}
-
-/*
- * Write data to the out stream.
- *
- * Returns ARCHIVE_OK if all data written, error otherwise.
- */
-static int
-archive_filter_lz4_write(struct archive_write_filter *f,
- const void *buff, size_t length)
-{
- struct private_data *data = (struct private_data *)f->data;
- int ret = ARCHIVE_OK;
- const char *p;
- size_t remaining;
- ssize_t size;
-
- /* If we haven't written a stream descriptor, we have to do it first. */
- if (!data->header_written) {
- ret = lz4_write_stream_descriptor(f);
- if (ret != ARCHIVE_OK)
- return (ret);
- data->header_written = 1;
- }
-
- /* Update statistics */
- data->total_in += length;
-
- p = (const char *)buff;
- remaining = length;
- while (remaining) {
- size_t l;
- /* Compress input data to output buffer */
- size = lz4_write_one_block(f, p, remaining);
- if (size < ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- l = data->out - data->out_buffer;
- if (l >= data->out_block_size) {
- ret = __archive_write_filter(f->next_filter,
- data->out_buffer, data->out_block_size);
- l -= data->out_block_size;
- memcpy(data->out_buffer,
- data->out_buffer + data->out_block_size, l);
- data->out = data->out_buffer + l;
- if (ret < ARCHIVE_WARN)
- break;
- }
- p += size;
- remaining -= size;
- }
-
- return (ret);
-}
-
-/*
- * Finish the compression.
- */
-static int
-archive_filter_lz4_close(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
- int ret;
-
- /* Finish compression cycle. */
- ret = (int)lz4_write_one_block(f, NULL, 0);
- if (ret >= 0) {
- /*
- * Write the last block and the end of the stream data.
- */
-
- /* Write End Of Stream. */
- memset(data->out, 0, 4); data->out += 4;
- /* Write Stream checksum if needed. */
- if (data->stream_checksum) {
- unsigned int checksum;
- checksum = __archive_xxhash.XXH32_digest(
- data->xxh32_state);
- data->xxh32_state = NULL;
- archive_le32enc(data->out, checksum);
- data->out += 4;
- }
- ret = __archive_write_filter(f->next_filter,
- data->out_buffer, data->out - data->out_buffer);
- }
- return ret;
-}
-
-static int
-archive_filter_lz4_free(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- if (data->lz4_stream != NULL) {
-#ifdef HAVE_LZ4HC_H
- if (data->compression_level >= 3)
-#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7
- LZ4_freeStreamHC(data->lz4_stream);
-#else
- LZ4_freeHC(data->lz4_stream);
-#endif
- else
-#endif
-#if LZ4_VERSION_MINOR >= 3
- LZ4_freeStream(data->lz4_stream);
-#else
- LZ4_free(data->lz4_stream);
-#endif
- }
- free(data->out_buffer);
- free(data->in_buffer_allocated);
- free(data->xxh32_state);
- free(data);
- f->data = NULL;
- return (ARCHIVE_OK);
-}
-
-static int
-lz4_write_stream_descriptor(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
- uint8_t *sd;
-
- sd = (uint8_t *)data->out;
- /* Write Magic Number. */
- archive_le32enc(&sd[0], LZ4_MAGICNUMBER);
- /* FLG */
- sd[4] = (data->version_number << 6)
- | (data->block_independence << 5)
- | (data->block_checksum << 4)
- | (data->stream_size << 3)
- | (data->stream_checksum << 2)
- | (data->preset_dictionary << 0);
- /* BD */
- sd[5] = (data->block_maximum_size << 4);
- sd[6] = (__archive_xxhash.XXH32(&sd[4], 2, 0) >> 8) & 0xff;
- data->out += 7;
- if (data->stream_checksum)
- data->xxh32_state = __archive_xxhash.XXH32_init(0);
- else
- data->xxh32_state = NULL;
- return (ARCHIVE_OK);
-}
-
-static ssize_t
-lz4_write_one_block(struct archive_write_filter *f, const char *p,
- size_t length)
-{
- struct private_data *data = (struct private_data *)f->data;
- ssize_t r;
-
- if (p == NULL) {
- /* Compress remaining uncompressed data. */
- if (data->in_buffer == data->in)
- return 0;
- else {
- size_t l = data->in - data->in_buffer;
- r = drive_compressor(f, data->in_buffer, l);
- if (r == ARCHIVE_OK)
- r = (ssize_t)l;
- }
- } else if ((data->block_independence || data->compression_level < 3) &&
- data->in_buffer == data->in && length >= data->block_size) {
- r = drive_compressor(f, p, data->block_size);
- if (r == ARCHIVE_OK)
- r = (ssize_t)data->block_size;
- } else {
- size_t remaining_size = data->in_buffer_size -
- (data->in - data->in_buffer);
- size_t l = (remaining_size > length)? length: remaining_size;
- memcpy(data->in, p, l);
- data->in += l;
- if (l == remaining_size) {
- r = drive_compressor(f, data->in_buffer,
- data->block_size);
- if (r == ARCHIVE_OK)
- r = (ssize_t)l;
- data->in = data->in_buffer;
- } else
- r = (ssize_t)l;
- }
-
- return (r);
-}
-
-
-/*
- * Utility function to push input data through compressor, writing
- * full output blocks as necessary.
- *
- * Note that this handles both the regular write case (finishing ==
- * false) and the end-of-archive case (finishing == true).
- */
-static int
-drive_compressor(struct archive_write_filter *f, const char *p, size_t length)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- if (data->stream_checksum)
- __archive_xxhash.XXH32_update(data->xxh32_state,
- p, (int)length);
- if (data->block_independence)
- return drive_compressor_independence(f, p, length);
- else
- return drive_compressor_dependence(f, p, length);
-}
-
-static int
-drive_compressor_independence(struct archive_write_filter *f, const char *p,
- size_t length)
-{
- struct private_data *data = (struct private_data *)f->data;
- unsigned int outsize;
-
-#ifdef HAVE_LZ4HC_H
- if (data->compression_level >= 3)
-#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7
- outsize = LZ4_compress_HC(p, data->out + 4,
- (int)length, (int)data->block_size,
- data->compression_level);
-#else
- outsize = LZ4_compressHC2_limitedOutput(p, data->out + 4,
- (int)length, (int)data->block_size,
- data->compression_level);
-#endif
- else
-#endif
-#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7
- outsize = LZ4_compress_default(p, data->out + 4,
- (int)length, (int)data->block_size);
-#else
- outsize = LZ4_compress_limitedOutput(p, data->out + 4,
- (int)length, (int)data->block_size);
-#endif
-
- if (outsize) {
- /* The buffer is compressed. */
- archive_le32enc(data->out, outsize);
- data->out += 4;
- } else {
- /* The buffer is not compressed. The compressed size was
- * bigger than its uncompressed size. */
- archive_le32enc(data->out, (uint32_t)(length | 0x80000000));
- data->out += 4;
- memcpy(data->out, p, length);
- outsize = (uint32_t)length;
- }
- data->out += outsize;
- if (data->block_checksum) {
- unsigned int checksum =
- __archive_xxhash.XXH32(data->out - outsize, outsize, 0);
- archive_le32enc(data->out, checksum);
- data->out += 4;
- }
- return (ARCHIVE_OK);
-}
-
-static int
-drive_compressor_dependence(struct archive_write_filter *f, const char *p,
- size_t length)
-{
- struct private_data *data = (struct private_data *)f->data;
- int outsize;
-
-#define DICT_SIZE (64 * 1024)
-#ifdef HAVE_LZ4HC_H
- if (data->compression_level >= 3) {
- if (data->lz4_stream == NULL) {
-#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7
- data->lz4_stream = LZ4_createStreamHC();
- LZ4_resetStreamHC(data->lz4_stream, data->compression_level);
-#else
- data->lz4_stream =
- LZ4_createHC(data->in_buffer_allocated);
-#endif
- if (data->lz4_stream == NULL) {
- archive_set_error(f->archive, ENOMEM,
- "Can't allocate data for compression"
- " buffer");
- return (ARCHIVE_FATAL);
- }
- }
- else
- LZ4_loadDictHC(data->lz4_stream, data->in_buffer_allocated, DICT_SIZE);
-
-#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7
- outsize = LZ4_compress_HC_continue(
- data->lz4_stream, p, data->out + 4, (int)length,
- (int)data->block_size);
-#else
- outsize = LZ4_compressHC2_limitedOutput_continue(
- data->lz4_stream, p, data->out + 4, (int)length,
- (int)data->block_size, data->compression_level);
-#endif
- } else
-#endif
- {
- if (data->lz4_stream == NULL) {
- data->lz4_stream = LZ4_createStream();
- if (data->lz4_stream == NULL) {
- archive_set_error(f->archive, ENOMEM,
- "Can't allocate data for compression"
- " buffer");
- return (ARCHIVE_FATAL);
- }
- }
- else
- LZ4_loadDict(data->lz4_stream, data->in_buffer_allocated, DICT_SIZE);
-
-#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7
- outsize = LZ4_compress_fast_continue(
- data->lz4_stream, p, data->out + 4, (int)length,
- (int)data->block_size, 1);
-#else
- outsize = LZ4_compress_limitedOutput_continue(
- data->lz4_stream, p, data->out + 4, (int)length,
- (int)data->block_size);
-#endif
- }
-
- if (outsize) {
- /* The buffer is compressed. */
- archive_le32enc(data->out, outsize);
- data->out += 4;
- } else {
- /* The buffer is not compressed. The compressed size was
- * bigger than its uncompressed size. */
- archive_le32enc(data->out, (uint32_t)(length | 0x80000000));
- data->out += 4;
- memcpy(data->out, p, length);
- outsize = (uint32_t)length;
- }
- data->out += outsize;
- if (data->block_checksum) {
- unsigned int checksum =
- __archive_xxhash.XXH32(data->out - outsize, outsize, 0);
- archive_le32enc(data->out, checksum);
- data->out += 4;
- }
-
- if (length == data->block_size) {
-#ifdef HAVE_LZ4HC_H
- if (data->compression_level >= 3) {
-#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7
- LZ4_saveDictHC(data->lz4_stream, data->in_buffer_allocated, DICT_SIZE);
-#else
- LZ4_slideInputBufferHC(data->lz4_stream);
-#endif
- data->in_buffer = data->in_buffer_allocated + DICT_SIZE;
- }
- else
-#endif
- LZ4_saveDict(data->lz4_stream,
- data->in_buffer_allocated, DICT_SIZE);
-#undef DICT_SIZE
- }
- return (ARCHIVE_OK);
-}
-
-#else /* HAVE_LIBLZ4 */
-
-static int
-archive_filter_lz4_open(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
- struct archive_string as;
- int r;
-
- archive_string_init(&as);
- archive_strcpy(&as, "lz4 -z -q -q");
-
- /* Specify a compression level. */
- if (data->compression_level > 0) {
- archive_strcat(&as, " -");
- archive_strappend_char(&as, '0' + data->compression_level);
- }
- /* Specify a block size. */
- archive_strcat(&as, " -B");
- archive_strappend_char(&as, '0' + data->block_maximum_size);
-
- if (data->block_checksum)
- archive_strcat(&as, " -BX");
- if (data->stream_checksum == 0)
- archive_strcat(&as, " --no-frame-crc");
- if (data->block_independence == 0)
- archive_strcat(&as, " -BD");
-
- f->write = archive_filter_lz4_write;
-
- r = __archive_write_program_open(f, data->pdata, as.s);
- archive_string_free(&as);
- return (r);
-}
-
-static int
-archive_filter_lz4_write(struct archive_write_filter *f, const void *buff,
- size_t length)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- return __archive_write_program_write(f, data->pdata, buff, length);
-}
-
-static int
-archive_filter_lz4_close(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- return __archive_write_program_close(f, data->pdata);
-}
-
-static int
-archive_filter_lz4_free(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- __archive_write_program_free(data->pdata);
- free(data);
- return (ARCHIVE_OK);
-}
-
-#endif /* HAVE_LIBLZ4 */
diff --git a/contrib/libs/libarchive/libarchive/archive_write_add_filter_lzop.c b/contrib/libs/libarchive/libarchive/archive_write_add_filter_lzop.c
deleted file mode 100644
index c4cb9ed733..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_add_filter_lzop.c
+++ /dev/null
@@ -1,478 +0,0 @@
-/*-
- * Copyright (c) 2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-__FBSDID("$FreeBSD$");
-//#undef HAVE_LZO_LZOCONF_H
-//#undef HAVE_LZO_LZO1X_H
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#include <time.h>
-#ifdef HAVE_LZO_LZOCONF_H
-#error #include <lzo/lzoconf.h>
-#endif
-#ifdef HAVE_LZO_LZO1X_H
-#error #include <lzo/lzo1x.h>
-#endif
-
-#include "archive.h"
-#include "archive_string.h"
-#include "archive_endian.h"
-#include "archive_write_private.h"
-
-enum lzo_method {
- METHOD_LZO1X_1 = 1,
- METHOD_LZO1X_1_15 = 2,
- METHOD_LZO1X_999 = 3
-};
-struct write_lzop {
- int compression_level;
-#if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H)
- unsigned char *uncompressed;
- size_t uncompressed_buffer_size;
- size_t uncompressed_avail_bytes;
- unsigned char *compressed;
- size_t compressed_buffer_size;
- enum lzo_method method;
- unsigned char level;
- lzo_voidp work_buffer;
- lzo_uint32 work_buffer_size;
- char header_written;
-#else
- struct archive_write_program_data *pdata;
-#endif
-};
-
-static int archive_write_lzop_open(struct archive_write_filter *);
-static int archive_write_lzop_options(struct archive_write_filter *,
- const char *, const char *);
-static int archive_write_lzop_write(struct archive_write_filter *,
- const void *, size_t);
-static int archive_write_lzop_close(struct archive_write_filter *);
-static int archive_write_lzop_free(struct archive_write_filter *);
-
-#if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H)
-/* Maximum block size. */
-#define BLOCK_SIZE (256 * 1024)
-/* Block information is composed of uncompressed size(4 bytes),
- * compressed size(4 bytes) and the checksum of uncompressed data(4 bytes)
- * in this lzop writer. */
-#define BLOCK_INfO_SIZE 12
-
-#define HEADER_VERSION 9
-#define HEADER_LIBVERSION 11
-#define HEADER_METHOD 15
-#define HEADER_LEVEL 16
-#define HEADER_MTIME_LOW 25
-#define HEADER_MTIME_HIGH 29
-#define HEADER_H_CHECKSUM 34
-
-/*
- * Header template.
- */
-static const unsigned char header[] = {
- /* LZOP Magic code 9 bytes */
- 0x89, 0x4c, 0x5a, 0x4f, 0x00, 0x0d, 0x0a, 0x1a, 0x0a,
- /* LZOP utility version(fake data) 2 bytes */
- 0x10, 0x30,
- /* LZO library version 2 bytes */
- 0x09, 0x40,
- /* Minimum required LZO library version 2 bytes */
- 0x09, 0x40,
- /* Method */
- 1,
- /* Level */
- 5,
- /* Flags 4 bytes
- * -OS Unix
- * -Stdout
- * -Stdin
- * -Adler32 used for uncompressed data 4 bytes */
- 0x03, 0x00, 0x00, 0x0d,
- /* Mode (AE_IFREG | 0644) 4 bytes */
- 0x00, 0x00, 0x81, 0xa4,
- /* Mtime low 4 bytes */
- 0x00, 0x00, 0x00, 0x00,
- /* Mtime high 4 bytes */
- 0x00, 0x00, 0x00, 0x00,
- /* Filename length */
- 0x00,
- /* Header checksum 4 bytes */
- 0x00, 0x00, 0x00, 0x00,
-};
-#endif
-
-int
-archive_write_add_filter_lzop(struct archive *_a)
-{
- struct archive_write_filter *f = __archive_write_allocate_filter(_a);
- struct write_lzop *data;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_add_filter_lzop");
-
- data = calloc(1, sizeof(*data));
- if (data == NULL) {
- archive_set_error(_a, ENOMEM, "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
-
- f->name = "lzop";
- f->code = ARCHIVE_FILTER_LZOP;
- f->data = data;
- f->open = archive_write_lzop_open;
- f->options = archive_write_lzop_options;
- f->write = archive_write_lzop_write;
- f->close = archive_write_lzop_close;
- f->free = archive_write_lzop_free;
-#if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H)
- if (lzo_init() != LZO_E_OK) {
- free(data);
- archive_set_error(_a, ARCHIVE_ERRNO_MISC,
- "lzo_init(type check) failed");
- return (ARCHIVE_FATAL);
- }
- if (lzo_version() < 0x940) {
- free(data);
- archive_set_error(_a, ARCHIVE_ERRNO_MISC,
- "liblzo library is too old(%s < 0.940)",
- lzo_version_string());
- return (ARCHIVE_FATAL);
- }
- data->compression_level = 5;
- return (ARCHIVE_OK);
-#else
- data->pdata = __archive_write_program_allocate("lzop");
- if (data->pdata == NULL) {
- free(data);
- archive_set_error(_a, ENOMEM, "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- data->compression_level = 0;
- /* Note: We return "warn" to inform of using an external lzop
- * program. */
- archive_set_error(_a, ARCHIVE_ERRNO_MISC,
- "Using external lzop program for lzop compression");
- return (ARCHIVE_WARN);
-#endif
-}
-
-static int
-archive_write_lzop_free(struct archive_write_filter *f)
-{
- struct write_lzop *data = (struct write_lzop *)f->data;
-
-#if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H)
- free(data->uncompressed);
- free(data->compressed);
- free(data->work_buffer);
-#else
- __archive_write_program_free(data->pdata);
-#endif
- free(data);
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_lzop_options(struct archive_write_filter *f, const char *key,
- const char *value)
-{
- struct write_lzop *data = (struct write_lzop *)f->data;
-
- if (strcmp(key, "compression-level") == 0) {
- if (value == NULL || !(value[0] >= '1' && value[0] <= '9') ||
- value[1] != '\0')
- return (ARCHIVE_WARN);
- data->compression_level = value[0] - '0';
- return (ARCHIVE_OK);
- }
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-#if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H)
-static int
-archive_write_lzop_open(struct archive_write_filter *f)
-{
- struct write_lzop *data = (struct write_lzop *)f->data;
-
- switch (data->compression_level) {
- case 1:
- data->method = METHOD_LZO1X_1_15; data->level = 1; break;
- default:
- case 2: case 3: case 4: case 5: case 6:
- data->method = METHOD_LZO1X_1; data->level = 5; break;
- case 7:
- data->method = METHOD_LZO1X_999; data->level = 7; break;
- case 8:
- data->method = METHOD_LZO1X_999; data->level = 8; break;
- case 9:
- data->method = METHOD_LZO1X_999; data->level = 9; break;
- }
- switch (data->method) {
- case METHOD_LZO1X_1:
- data->work_buffer_size = LZO1X_1_MEM_COMPRESS; break;
- case METHOD_LZO1X_1_15:
- data->work_buffer_size = LZO1X_1_15_MEM_COMPRESS; break;
- case METHOD_LZO1X_999:
- data->work_buffer_size = LZO1X_999_MEM_COMPRESS; break;
- }
- if (data->work_buffer == NULL) {
- data->work_buffer = (lzo_voidp)malloc(data->work_buffer_size);
- if (data->work_buffer == NULL) {
- archive_set_error(f->archive, ENOMEM,
- "Can't allocate data for compression buffer");
- return (ARCHIVE_FATAL);
- }
- }
- if (data->compressed == NULL) {
- data->compressed_buffer_size = sizeof(header) +
- BLOCK_SIZE + (BLOCK_SIZE >> 4) + 64 + 3;
- data->compressed = (unsigned char *)
- malloc(data->compressed_buffer_size);
- if (data->compressed == NULL) {
- archive_set_error(f->archive, ENOMEM,
- "Can't allocate data for compression buffer");
- return (ARCHIVE_FATAL);
- }
- }
- if (data->uncompressed == NULL) {
- data->uncompressed_buffer_size = BLOCK_SIZE;
- data->uncompressed = (unsigned char *)
- malloc(data->uncompressed_buffer_size);
- if (data->uncompressed == NULL) {
- archive_set_error(f->archive, ENOMEM,
- "Can't allocate data for compression buffer");
- return (ARCHIVE_FATAL);
- }
- data->uncompressed_avail_bytes = BLOCK_SIZE;
- }
- return (ARCHIVE_OK);
-}
-
-static int
-make_header(struct archive_write_filter *f)
-{
- struct write_lzop *data = (struct write_lzop *)f->data;
- int64_t t;
- uint32_t checksum;
-
- memcpy(data->compressed, header, sizeof(header));
- /* Overwrite library version. */
- data->compressed[HEADER_LIBVERSION] = (unsigned char )
- (lzo_version() >> 8) & 0xff;
- data->compressed[HEADER_LIBVERSION + 1] = (unsigned char )
- lzo_version() & 0xff;
- /* Overwrite method and level. */
- data->compressed[HEADER_METHOD] = (unsigned char)data->method;
- data->compressed[HEADER_LEVEL] = data->level;
- /* Overwrite mtime with current time. */
- t = (int64_t)time(NULL);
- archive_be32enc(&data->compressed[HEADER_MTIME_LOW],
- (uint32_t)(t & 0xffffffff));
- archive_be32enc(&data->compressed[HEADER_MTIME_HIGH],
- (uint32_t)((t >> 32) & 0xffffffff));
- /* Overwrite header checksum with calculated value. */
- checksum = lzo_adler32(1, data->compressed + HEADER_VERSION,
- (lzo_uint)(HEADER_H_CHECKSUM - HEADER_VERSION));
- archive_be32enc(&data->compressed[HEADER_H_CHECKSUM], checksum);
- return (sizeof(header));
-}
-
-static int
-drive_compressor(struct archive_write_filter *f)
-{
- struct write_lzop *data = (struct write_lzop *)f->data;
- unsigned char *p;
- const int block_info_bytes = 12;
- int header_bytes, r;
- lzo_uint usize, csize;
- uint32_t checksum;
-
- if (!data->header_written) {
- header_bytes = make_header(f);
- data->header_written = 1;
- } else
- header_bytes = 0;
- p = data->compressed;
-
- usize = (lzo_uint)
- (data->uncompressed_buffer_size - data->uncompressed_avail_bytes);
- csize = 0;
- switch (data->method) {
- default:
- case METHOD_LZO1X_1:
- r = lzo1x_1_compress(data->uncompressed, usize,
- p + header_bytes + block_info_bytes, &csize,
- data->work_buffer);
- break;
- case METHOD_LZO1X_1_15:
- r = lzo1x_1_15_compress(data->uncompressed, usize,
- p + header_bytes + block_info_bytes, &csize,
- data->work_buffer);
- break;
- case METHOD_LZO1X_999:
- r = lzo1x_999_compress_level(data->uncompressed, usize,
- p + header_bytes + block_info_bytes, &csize,
- data->work_buffer, NULL, 0, 0, data->level);
- break;
- }
- if (r != LZO_E_OK) {
- archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
- "Lzop compression failed: returned status %d", r);
- return (ARCHIVE_FATAL);
- }
-
- /* Store uncompressed size. */
- archive_be32enc(p + header_bytes, (uint32_t)usize);
- /* Store the checksum of the uncompressed data. */
- checksum = lzo_adler32(1, data->uncompressed, usize);
- archive_be32enc(p + header_bytes + 8, checksum);
-
- if (csize < usize) {
- /* Store compressed size. */
- archive_be32enc(p + header_bytes + 4, (uint32_t)csize);
- r = __archive_write_filter(f->next_filter, data->compressed,
- header_bytes + block_info_bytes + csize);
- } else {
- /*
- * This case, we output uncompressed data instead.
- */
- /* Store uncompressed size as compressed size. */
- archive_be32enc(p + header_bytes + 4, (uint32_t)usize);
- r = __archive_write_filter(f->next_filter, data->compressed,
- header_bytes + block_info_bytes);
- if (r != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- r = __archive_write_filter(f->next_filter, data->uncompressed,
- usize);
- }
-
- if (r != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_lzop_write(struct archive_write_filter *f,
- const void *buff, size_t length)
-{
- struct write_lzop *data = (struct write_lzop *)f->data;
- const char *p = buff;
- int r;
-
- do {
- if (data->uncompressed_avail_bytes > length) {
- memcpy(data->uncompressed
- + data->uncompressed_buffer_size
- - data->uncompressed_avail_bytes,
- p, length);
- data->uncompressed_avail_bytes -= length;
- return (ARCHIVE_OK);
- }
-
- memcpy(data->uncompressed + data->uncompressed_buffer_size
- - data->uncompressed_avail_bytes,
- p, data->uncompressed_avail_bytes);
- length -= data->uncompressed_avail_bytes;
- p += data->uncompressed_avail_bytes;
- data->uncompressed_avail_bytes = 0;
-
- r = drive_compressor(f);
- if (r != ARCHIVE_OK) return (r);
- data->uncompressed_avail_bytes = BLOCK_SIZE;
- } while (length);
-
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_lzop_close(struct archive_write_filter *f)
-{
- struct write_lzop *data = (struct write_lzop *)f->data;
- const uint32_t endmark = 0;
- int r;
-
- if (data->uncompressed_avail_bytes < BLOCK_SIZE) {
- /* Compress and output remaining data. */
- r = drive_compressor(f);
- if (r != ARCHIVE_OK)
- return (r);
- }
- /* Write a zero uncompressed size as the end mark of the series of
- * compressed block. */
- return __archive_write_filter(f->next_filter, &endmark, sizeof(endmark));
-}
-
-#else
-static int
-archive_write_lzop_open(struct archive_write_filter *f)
-{
- struct write_lzop *data = (struct write_lzop *)f->data;
- struct archive_string as;
- int r;
-
- archive_string_init(&as);
- archive_strcpy(&as, "lzop");
- /* Specify compression level. */
- if (data->compression_level > 0) {
- archive_strappend_char(&as, ' ');
- archive_strappend_char(&as, '-');
- archive_strappend_char(&as, '0' + data->compression_level);
- }
-
- r = __archive_write_program_open(f, data->pdata, as.s);
- archive_string_free(&as);
- return (r);
-}
-
-static int
-archive_write_lzop_write(struct archive_write_filter *f,
- const void *buff, size_t length)
-{
- struct write_lzop *data = (struct write_lzop *)f->data;
-
- return __archive_write_program_write(f, data->pdata, buff, length);
-}
-
-static int
-archive_write_lzop_close(struct archive_write_filter *f)
-{
- struct write_lzop *data = (struct write_lzop *)f->data;
-
- return __archive_write_program_close(f, data->pdata);
-}
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_write_add_filter_none.c b/contrib/libs/libarchive/libarchive/archive_write_add_filter_none.c
deleted file mode 100644
index 3c06c642e7..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_add_filter_none.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*-
- * Copyright (c) 2003-2010 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_none.c 201080 2009-12-28 02:03:54Z kientzle $");
-
-#include "archive.h"
-
-int
-archive_write_set_compression_none(struct archive *a)
-{
- (void)a; /* UNUSED */
- return (ARCHIVE_OK);
-}
-
-int
-archive_write_add_filter_none(struct archive *a)
-{
- (void)a; /* UNUSED */
- return (ARCHIVE_OK);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_add_filter_program.c b/contrib/libs/libarchive/libarchive/archive_write_add_filter_program.c
deleted file mode 100644
index c096e7227b..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_add_filter_program.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/*-
- * Copyright (c) 2007 Joerg Sonnenberger
- * Copyright (c) 2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_program.c 201104 2009-12-28 03:14:30Z kientzle $");
-
-#ifdef HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-#ifdef HAVE_ERRNO_H
-# include <errno.h>
-#endif
-#ifdef HAVE_FCNTL_H
-# include <fcntl.h>
-#endif
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-# include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_string.h"
-#include "archive_write_private.h"
-#include "filter_fork.h"
-
-#if ARCHIVE_VERSION_NUMBER < 4000000
-int
-archive_write_set_compression_program(struct archive *a, const char *cmd)
-{
- __archive_write_filters_free(a);
- return (archive_write_add_filter_program(a, cmd));
-}
-#endif
-
-struct archive_write_program_data {
-#if defined(_WIN32) && !defined(__CYGWIN__)
- HANDLE child;
-#else
- pid_t child;
-#endif
- int child_stdin, child_stdout;
-
- char *child_buf;
- size_t child_buf_len, child_buf_avail;
- char *program_name;
-};
-
-struct private_data {
- struct archive_write_program_data *pdata;
- struct archive_string description;
- char *cmd;
-};
-
-static int archive_compressor_program_open(struct archive_write_filter *);
-static int archive_compressor_program_write(struct archive_write_filter *,
- const void *, size_t);
-static int archive_compressor_program_close(struct archive_write_filter *);
-static int archive_compressor_program_free(struct archive_write_filter *);
-
-/*
- * Add a filter to this write handle that passes all data through an
- * external program.
- */
-int
-archive_write_add_filter_program(struct archive *_a, const char *cmd)
-{
- struct archive_write_filter *f = __archive_write_allocate_filter(_a);
- struct private_data *data;
- static const char prefix[] = "Program: ";
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_add_filter_program");
-
- f->data = calloc(1, sizeof(*data));
- if (f->data == NULL)
- goto memerr;
- data = (struct private_data *)f->data;
-
- data->cmd = strdup(cmd);
- if (data->cmd == NULL)
- goto memerr;
-
- data->pdata = __archive_write_program_allocate(cmd);
- if (data->pdata == NULL)
- goto memerr;
-
- /* Make up a description string. */
- if (archive_string_ensure(&data->description,
- strlen(prefix) + strlen(cmd) + 1) == NULL)
- goto memerr;
- archive_strcpy(&data->description, prefix);
- archive_strcat(&data->description, cmd);
-
- f->name = data->description.s;
- f->code = ARCHIVE_FILTER_PROGRAM;
- f->open = archive_compressor_program_open;
- f->write = archive_compressor_program_write;
- f->close = archive_compressor_program_close;
- f->free = archive_compressor_program_free;
- return (ARCHIVE_OK);
-memerr:
- archive_compressor_program_free(f);
- archive_set_error(_a, ENOMEM,
- "Can't allocate memory for filter program");
- return (ARCHIVE_FATAL);
-}
-
-static int
-archive_compressor_program_open(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- return __archive_write_program_open(f, data->pdata, data->cmd);
-}
-
-static int
-archive_compressor_program_write(struct archive_write_filter *f,
- const void *buff, size_t length)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- return __archive_write_program_write(f, data->pdata, buff, length);
-}
-
-static int
-archive_compressor_program_close(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- return __archive_write_program_close(f, data->pdata);
-}
-
-static int
-archive_compressor_program_free(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- if (data) {
- free(data->cmd);
- archive_string_free(&data->description);
- __archive_write_program_free(data->pdata);
- free(data);
- f->data = NULL;
- }
- return (ARCHIVE_OK);
-}
-
-/*
- * Allocate resources for executing an external program.
- */
-struct archive_write_program_data *
-__archive_write_program_allocate(const char *program)
-{
- struct archive_write_program_data *data;
-
- data = calloc(1, sizeof(struct archive_write_program_data));
- if (data == NULL)
- return (data);
- data->child_stdin = -1;
- data->child_stdout = -1;
- data->program_name = strdup(program);
- return (data);
-}
-
-/*
- * Release the resources.
- */
-int
-__archive_write_program_free(struct archive_write_program_data *data)
-{
-
- if (data) {
- free(data->program_name);
- free(data->child_buf);
- free(data);
- }
- return (ARCHIVE_OK);
-}
-
-int
-__archive_write_program_open(struct archive_write_filter *f,
- struct archive_write_program_data *data, const char *cmd)
-{
- int ret;
-
- if (data->child_buf == NULL) {
- data->child_buf_len = 65536;
- data->child_buf_avail = 0;
- data->child_buf = malloc(data->child_buf_len);
-
- if (data->child_buf == NULL) {
- archive_set_error(f->archive, ENOMEM,
- "Can't allocate compression buffer");
- return (ARCHIVE_FATAL);
- }
- }
-
- ret = __archive_create_child(cmd, &data->child_stdin,
- &data->child_stdout, &data->child);
- if (ret != ARCHIVE_OK) {
- archive_set_error(f->archive, EINVAL,
- "Can't launch external program: %s", cmd);
- return (ARCHIVE_FATAL);
- }
- return (ARCHIVE_OK);
-}
-
-static ssize_t
-child_write(struct archive_write_filter *f,
- struct archive_write_program_data *data, const char *buf, size_t buf_len)
-{
- ssize_t ret;
-
- if (data->child_stdin == -1)
- return (-1);
-
- if (buf_len == 0)
- return (-1);
-
- for (;;) {
- do {
- ret = write(data->child_stdin, buf, buf_len);
- } while (ret == -1 && errno == EINTR);
-
- if (ret > 0)
- return (ret);
- if (ret == 0) {
- close(data->child_stdin);
- data->child_stdin = -1;
- fcntl(data->child_stdout, F_SETFL, 0);
- return (0);
- }
- if (ret == -1 && errno != EAGAIN)
- return (-1);
-
- if (data->child_stdout == -1) {
- fcntl(data->child_stdin, F_SETFL, 0);
- __archive_check_child(data->child_stdin,
- data->child_stdout);
- continue;
- }
-
- do {
- ret = read(data->child_stdout,
- data->child_buf + data->child_buf_avail,
- data->child_buf_len - data->child_buf_avail);
- } while (ret == -1 && errno == EINTR);
-
- if (ret == 0 || (ret == -1 && errno == EPIPE)) {
- close(data->child_stdout);
- data->child_stdout = -1;
- fcntl(data->child_stdin, F_SETFL, 0);
- continue;
- }
- if (ret == -1 && errno == EAGAIN) {
- __archive_check_child(data->child_stdin,
- data->child_stdout);
- continue;
- }
- if (ret == -1)
- return (-1);
-
- data->child_buf_avail += ret;
-
- ret = __archive_write_filter(f->next_filter,
- data->child_buf, data->child_buf_avail);
- if (ret != ARCHIVE_OK)
- return (-1);
- data->child_buf_avail = 0;
- }
-}
-
-/*
- * Write data to the filter stream.
- */
-int
-__archive_write_program_write(struct archive_write_filter *f,
- struct archive_write_program_data *data, const void *buff, size_t length)
-{
- ssize_t ret;
- const char *buf;
-
- if (data->child == 0)
- return (ARCHIVE_OK);
-
- buf = buff;
- while (length > 0) {
- ret = child_write(f, data, buf, length);
- if (ret == -1 || ret == 0) {
- archive_set_error(f->archive, EIO,
- "Can't write to program: %s", data->program_name);
- return (ARCHIVE_FATAL);
- }
- length -= ret;
- buf += ret;
- }
- return (ARCHIVE_OK);
-}
-
-/*
- * Finish the filtering...
- */
-int
-__archive_write_program_close(struct archive_write_filter *f,
- struct archive_write_program_data *data)
-{
- int ret, status;
- ssize_t bytes_read;
-
- if (data->child == 0)
- return ARCHIVE_OK;
-
- ret = 0;
- close(data->child_stdin);
- data->child_stdin = -1;
- fcntl(data->child_stdout, F_SETFL, 0);
-
- for (;;) {
- do {
- bytes_read = read(data->child_stdout,
- data->child_buf + data->child_buf_avail,
- data->child_buf_len - data->child_buf_avail);
- } while (bytes_read == -1 && errno == EINTR);
-
- if (bytes_read == 0 || (bytes_read == -1 && errno == EPIPE))
- break;
-
- if (bytes_read == -1) {
- archive_set_error(f->archive, errno,
- "Error reading from program: %s", data->program_name);
- ret = ARCHIVE_FATAL;
- goto cleanup;
- }
- data->child_buf_avail += bytes_read;
-
- ret = __archive_write_filter(f->next_filter,
- data->child_buf, data->child_buf_avail);
- if (ret != ARCHIVE_OK) {
- ret = ARCHIVE_FATAL;
- goto cleanup;
- }
- data->child_buf_avail = 0;
- }
-
-cleanup:
- /* Shut down the child. */
- if (data->child_stdin != -1)
- close(data->child_stdin);
- if (data->child_stdout != -1)
- close(data->child_stdout);
- while (waitpid(data->child, &status, 0) == -1 && errno == EINTR)
- continue;
-#if defined(_WIN32) && !defined(__CYGWIN__)
- CloseHandle(data->child);
-#endif
- data->child = 0;
-
- if (status != 0) {
- archive_set_error(f->archive, EIO,
- "Error closing program: %s", data->program_name);
- ret = ARCHIVE_FATAL;
- }
- return ret;
-}
-
diff --git a/contrib/libs/libarchive/libarchive/archive_write_add_filter_uuencode.c b/contrib/libs/libarchive/libarchive/archive_write_add_filter_uuencode.c
deleted file mode 100644
index 1ad4589219..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_add_filter_uuencode.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*-
- * Copyright (c) 2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_string.h"
-#include "archive_write_private.h"
-
-#define LBYTES 45
-
-struct private_uuencode {
- int mode;
- struct archive_string name;
- struct archive_string encoded_buff;
- size_t bs;
- size_t hold_len;
- unsigned char hold[LBYTES];
-};
-
-static int archive_filter_uuencode_options(struct archive_write_filter *,
- const char *, const char *);
-static int archive_filter_uuencode_open(struct archive_write_filter *);
-static int archive_filter_uuencode_write(struct archive_write_filter *,
- const void *, size_t);
-static int archive_filter_uuencode_close(struct archive_write_filter *);
-static int archive_filter_uuencode_free(struct archive_write_filter *);
-static void uu_encode(struct archive_string *, const unsigned char *, size_t);
-static int64_t atol8(const char *, size_t);
-
-/*
- * Add a compress filter to this write handle.
- */
-int
-archive_write_add_filter_uuencode(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct archive_write_filter *f = __archive_write_allocate_filter(_a);
- struct private_uuencode *state;
-
- archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_add_filter_uu");
-
- state = (struct private_uuencode *)calloc(1, sizeof(*state));
- if (state == NULL) {
- archive_set_error(f->archive, ENOMEM,
- "Can't allocate data for uuencode filter");
- return (ARCHIVE_FATAL);
- }
- archive_strcpy(&state->name, "-");
- state->mode = 0644;
-
- f->data = state;
- f->name = "uuencode";
- f->code = ARCHIVE_FILTER_UU;
- f->open = archive_filter_uuencode_open;
- f->options = archive_filter_uuencode_options;
- f->write = archive_filter_uuencode_write;
- f->close = archive_filter_uuencode_close;
- f->free = archive_filter_uuencode_free;
-
- return (ARCHIVE_OK);
-}
-
-/*
- * Set write options.
- */
-static int
-archive_filter_uuencode_options(struct archive_write_filter *f, const char *key,
- const char *value)
-{
- struct private_uuencode *state = (struct private_uuencode *)f->data;
-
- if (strcmp(key, "mode") == 0) {
- if (value == NULL) {
- archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
- "mode option requires octal digits");
- return (ARCHIVE_FAILED);
- }
- state->mode = (int)atol8(value, strlen(value)) & 0777;
- return (ARCHIVE_OK);
- } else if (strcmp(key, "name") == 0) {
- if (value == NULL) {
- archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
- "name option requires a string");
- return (ARCHIVE_FAILED);
- }
- archive_strcpy(&state->name, value);
- return (ARCHIVE_OK);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-/*
- * Setup callback.
- */
-static int
-archive_filter_uuencode_open(struct archive_write_filter *f)
-{
- struct private_uuencode *state = (struct private_uuencode *)f->data;
- size_t bs = 65536, bpb;
-
- if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
- /* Buffer size should be a multiple number of the of bytes
- * per block for performance. */
- bpb = archive_write_get_bytes_per_block(f->archive);
- if (bpb > bs)
- bs = bpb;
- else if (bpb != 0)
- bs -= bs % bpb;
- }
-
- state->bs = bs;
- if (archive_string_ensure(&state->encoded_buff, bs + 512) == NULL) {
- archive_set_error(f->archive, ENOMEM,
- "Can't allocate data for uuencode buffer");
- return (ARCHIVE_FATAL);
- }
-
- archive_string_sprintf(&state->encoded_buff, "begin %o %s\n",
- state->mode, state->name.s);
-
- f->data = state;
- return (0);
-}
-
-static void
-uu_encode(struct archive_string *as, const unsigned char *p, size_t len)
-{
- int c;
-
- c = (int)len;
- archive_strappend_char(as, c?c + 0x20:'`');
- for (; len >= 3; p += 3, len -= 3) {
- c = p[0] >> 2;
- archive_strappend_char(as, c?c + 0x20:'`');
- c = ((p[0] & 0x03) << 4) | ((p[1] & 0xf0) >> 4);
- archive_strappend_char(as, c?c + 0x20:'`');
- c = ((p[1] & 0x0f) << 2) | ((p[2] & 0xc0) >> 6);
- archive_strappend_char(as, c?c + 0x20:'`');
- c = p[2] & 0x3f;
- archive_strappend_char(as, c?c + 0x20:'`');
- }
- if (len > 0) {
- c = p[0] >> 2;
- archive_strappend_char(as, c?c + 0x20:'`');
- c = (p[0] & 0x03) << 4;
- if (len == 1) {
- archive_strappend_char(as, c?c + 0x20:'`');
- archive_strappend_char(as, '`');
- archive_strappend_char(as, '`');
- } else {
- c |= (p[1] & 0xf0) >> 4;
- archive_strappend_char(as, c?c + 0x20:'`');
- c = (p[1] & 0x0f) << 2;
- archive_strappend_char(as, c?c + 0x20:'`');
- archive_strappend_char(as, '`');
- }
- }
- archive_strappend_char(as, '\n');
-}
-
-/*
- * Write data to the encoded stream.
- */
-static int
-archive_filter_uuencode_write(struct archive_write_filter *f, const void *buff,
- size_t length)
-{
- struct private_uuencode *state = (struct private_uuencode *)f->data;
- const unsigned char *p = buff;
- int ret = ARCHIVE_OK;
-
- if (length == 0)
- return (ret);
-
- if (state->hold_len) {
- while (state->hold_len < LBYTES && length > 0) {
- state->hold[state->hold_len++] = *p++;
- length--;
- }
- if (state->hold_len < LBYTES)
- return (ret);
- uu_encode(&state->encoded_buff, state->hold, LBYTES);
- state->hold_len = 0;
- }
-
- for (; length >= LBYTES; length -= LBYTES, p += LBYTES)
- uu_encode(&state->encoded_buff, p, LBYTES);
-
- /* Save remaining bytes. */
- if (length > 0) {
- memcpy(state->hold, p, length);
- state->hold_len = length;
- }
- while (archive_strlen(&state->encoded_buff) >= state->bs) {
- ret = __archive_write_filter(f->next_filter,
- state->encoded_buff.s, state->bs);
- memmove(state->encoded_buff.s,
- state->encoded_buff.s + state->bs,
- state->encoded_buff.length - state->bs);
- state->encoded_buff.length -= state->bs;
- }
-
- return (ret);
-}
-
-
-/*
- * Finish the compression...
- */
-static int
-archive_filter_uuencode_close(struct archive_write_filter *f)
-{
- struct private_uuencode *state = (struct private_uuencode *)f->data;
-
- /* Flush remaining bytes. */
- if (state->hold_len != 0)
- uu_encode(&state->encoded_buff, state->hold, state->hold_len);
- archive_string_sprintf(&state->encoded_buff, "`\nend\n");
- /* Write the last block */
- archive_write_set_bytes_in_last_block(f->archive, 1);
- return __archive_write_filter(f->next_filter,
- state->encoded_buff.s, archive_strlen(&state->encoded_buff));
-}
-
-static int
-archive_filter_uuencode_free(struct archive_write_filter *f)
-{
- struct private_uuencode *state = (struct private_uuencode *)f->data;
-
- archive_string_free(&state->name);
- archive_string_free(&state->encoded_buff);
- free(state);
- return (ARCHIVE_OK);
-}
-
-static int64_t
-atol8(const char *p, size_t char_cnt)
-{
- int64_t l;
- int digit;
-
- l = 0;
- while (char_cnt-- > 0) {
- if (*p >= '0' && *p <= '7')
- digit = *p - '0';
- else
- break;
- p++;
- l <<= 3;
- l |= digit;
- }
- return (l);
-}
-
diff --git a/contrib/libs/libarchive/libarchive/archive_write_add_filter_xz.c b/contrib/libs/libarchive/libarchive/archive_write_add_filter_xz.c
deleted file mode 100644
index 7ecf701544..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_add_filter_xz.c
+++ /dev/null
@@ -1,545 +0,0 @@
-/*-
- * Copyright (c) 2003-2010 Tim Kientzle
- * Copyright (c) 2009-2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_xz.c 201108 2009-12-28 03:28:21Z kientzle $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#include <time.h>
-#ifdef HAVE_LZMA_H
-#error #include <lzma.h>
-#endif
-
-#include "archive.h"
-#include "archive_endian.h"
-#include "archive_private.h"
-#include "archive_write_private.h"
-
-#if ARCHIVE_VERSION_NUMBER < 4000000
-int
-archive_write_set_compression_lzip(struct archive *a)
-{
- __archive_write_filters_free(a);
- return (archive_write_add_filter_lzip(a));
-}
-
-int
-archive_write_set_compression_lzma(struct archive *a)
-{
- __archive_write_filters_free(a);
- return (archive_write_add_filter_lzma(a));
-}
-
-int
-archive_write_set_compression_xz(struct archive *a)
-{
- __archive_write_filters_free(a);
- return (archive_write_add_filter_xz(a));
-}
-
-#endif
-
-#ifndef HAVE_LZMA_H
-int
-archive_write_add_filter_xz(struct archive *a)
-{
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "xz compression not supported on this platform");
- return (ARCHIVE_FATAL);
-}
-
-int
-archive_write_add_filter_lzma(struct archive *a)
-{
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "lzma compression not supported on this platform");
- return (ARCHIVE_FATAL);
-}
-
-int
-archive_write_add_filter_lzip(struct archive *a)
-{
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "lzma compression not supported on this platform");
- return (ARCHIVE_FATAL);
-}
-#else
-/* Don't compile this if we don't have liblzma. */
-
-struct private_data {
- int compression_level;
- uint32_t threads;
- lzma_stream stream;
- lzma_filter lzmafilters[2];
- lzma_options_lzma lzma_opt;
- int64_t total_in;
- unsigned char *compressed;
- size_t compressed_buffer_size;
- int64_t total_out;
- /* the CRC32 value of uncompressed data for lzip */
- uint32_t crc32;
-};
-
-static int archive_compressor_xz_options(struct archive_write_filter *,
- const char *, const char *);
-static int archive_compressor_xz_open(struct archive_write_filter *);
-static int archive_compressor_xz_write(struct archive_write_filter *,
- const void *, size_t);
-static int archive_compressor_xz_close(struct archive_write_filter *);
-static int archive_compressor_xz_free(struct archive_write_filter *);
-static int drive_compressor(struct archive_write_filter *,
- struct private_data *, int finishing);
-
-struct option_value {
- uint32_t dict_size;
- uint32_t nice_len;
- lzma_match_finder mf;
-};
-static const struct option_value option_values[] = {
- { 1 << 16, 32, LZMA_MF_HC3},
- { 1 << 20, 32, LZMA_MF_HC3},
- { 3 << 19, 32, LZMA_MF_HC4},
- { 1 << 21, 32, LZMA_MF_BT4},
- { 3 << 20, 32, LZMA_MF_BT4},
- { 1 << 22, 32, LZMA_MF_BT4},
- { 1 << 23, 64, LZMA_MF_BT4},
- { 1 << 24, 64, LZMA_MF_BT4},
- { 3 << 23, 64, LZMA_MF_BT4},
- { 1 << 25, 64, LZMA_MF_BT4}
-};
-
-static int
-common_setup(struct archive_write_filter *f)
-{
- struct private_data *data;
- struct archive_write *a = (struct archive_write *)f->archive;
- data = calloc(1, sizeof(*data));
- if (data == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- f->data = data;
- data->compression_level = LZMA_PRESET_DEFAULT;
- data->threads = 1;
- f->open = &archive_compressor_xz_open;
- f->close = archive_compressor_xz_close;
- f->free = archive_compressor_xz_free;
- f->options = &archive_compressor_xz_options;
- return (ARCHIVE_OK);
-}
-
-/*
- * Add an xz compression filter to this write handle.
- */
-int
-archive_write_add_filter_xz(struct archive *_a)
-{
- struct archive_write_filter *f;
- int r;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_add_filter_xz");
- f = __archive_write_allocate_filter(_a);
- r = common_setup(f);
- if (r == ARCHIVE_OK) {
- f->code = ARCHIVE_FILTER_XZ;
- f->name = "xz";
- }
- return (r);
-}
-
-/* LZMA is handled identically, we just need a different compression
- * code set. (The liblzma setup looks at the code to determine
- * the one place that XZ and LZMA require different handling.) */
-int
-archive_write_add_filter_lzma(struct archive *_a)
-{
- struct archive_write_filter *f;
- int r;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_add_filter_lzma");
- f = __archive_write_allocate_filter(_a);
- r = common_setup(f);
- if (r == ARCHIVE_OK) {
- f->code = ARCHIVE_FILTER_LZMA;
- f->name = "lzma";
- }
- return (r);
-}
-
-int
-archive_write_add_filter_lzip(struct archive *_a)
-{
- struct archive_write_filter *f;
- int r;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_add_filter_lzip");
- f = __archive_write_allocate_filter(_a);
- r = common_setup(f);
- if (r == ARCHIVE_OK) {
- f->code = ARCHIVE_FILTER_LZIP;
- f->name = "lzip";
- }
- return (r);
-}
-
-static int
-archive_compressor_xz_init_stream(struct archive_write_filter *f,
- struct private_data *data)
-{
- static const lzma_stream lzma_stream_init_data = LZMA_STREAM_INIT;
- int ret;
-#ifdef HAVE_LZMA_STREAM_ENCODER_MT
- lzma_mt mt_options;
-#endif
-
- data->stream = lzma_stream_init_data;
- data->stream.next_out = data->compressed;
- data->stream.avail_out = data->compressed_buffer_size;
- if (f->code == ARCHIVE_FILTER_XZ) {
-#ifdef HAVE_LZMA_STREAM_ENCODER_MT
- if (data->threads != 1) {
- memset(&mt_options, 0, sizeof(mt_options));
- mt_options.threads = data->threads;
- mt_options.timeout = 300;
- mt_options.filters = data->lzmafilters;
- mt_options.check = LZMA_CHECK_CRC64;
- ret = lzma_stream_encoder_mt(&(data->stream),
- &mt_options);
- } else
-#endif
- ret = lzma_stream_encoder(&(data->stream),
- data->lzmafilters, LZMA_CHECK_CRC64);
- } else if (f->code == ARCHIVE_FILTER_LZMA) {
- ret = lzma_alone_encoder(&(data->stream), &data->lzma_opt);
- } else { /* ARCHIVE_FILTER_LZIP */
- int dict_size = data->lzma_opt.dict_size;
- int ds, log2dic, wedges;
-
- /* Calculate a coded dictionary size */
- if (dict_size < (1 << 12) || dict_size > (1 << 29)) {
- archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
- "Unacceptable dictionary size for lzip: %d",
- dict_size);
- return (ARCHIVE_FATAL);
- }
- for (log2dic = 29; log2dic >= 12; log2dic--) {
- if (dict_size & (1 << log2dic))
- break;
- }
- if (dict_size > (1 << log2dic)) {
- log2dic++;
- wedges =
- ((1 << log2dic) - dict_size) / (1 << (log2dic - 4));
- } else
- wedges = 0;
- ds = ((wedges << 5) & 0xe0) | (log2dic & 0x1f);
-
- data->crc32 = 0;
- /* Make a header */
- data->compressed[0] = 0x4C;
- data->compressed[1] = 0x5A;
- data->compressed[2] = 0x49;
- data->compressed[3] = 0x50;
- data->compressed[4] = 1;/* Version */
- data->compressed[5] = (unsigned char)ds;
- data->stream.next_out += 6;
- data->stream.avail_out -= 6;
-
- ret = lzma_raw_encoder(&(data->stream), data->lzmafilters);
- }
- if (ret == LZMA_OK)
- return (ARCHIVE_OK);
-
- switch (ret) {
- case LZMA_MEM_ERROR:
- archive_set_error(f->archive, ENOMEM,
- "Internal error initializing compression library: "
- "Cannot allocate memory");
- break;
- default:
- archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library: "
- "It's a bug in liblzma");
- break;
- }
- return (ARCHIVE_FATAL);
-}
-
-/*
- * Setup callback.
- */
-static int
-archive_compressor_xz_open(struct archive_write_filter *f)
-{
- struct private_data *data = f->data;
- int ret;
-
- if (data->compressed == NULL) {
- size_t bs = 65536, bpb;
- if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
- /* Buffer size should be a multiple number of the of bytes
- * per block for performance. */
- bpb = archive_write_get_bytes_per_block(f->archive);
- if (bpb > bs)
- bs = bpb;
- else if (bpb != 0)
- bs -= bs % bpb;
- }
- data->compressed_buffer_size = bs;
- data->compressed
- = (unsigned char *)malloc(data->compressed_buffer_size);
- if (data->compressed == NULL) {
- archive_set_error(f->archive, ENOMEM,
- "Can't allocate data for compression buffer");
- return (ARCHIVE_FATAL);
- }
- }
-
- f->write = archive_compressor_xz_write;
-
- /* Initialize compression library. */
- if (f->code == ARCHIVE_FILTER_LZIP) {
- const struct option_value *val =
- &option_values[data->compression_level];
-
- data->lzma_opt.dict_size = val->dict_size;
- data->lzma_opt.preset_dict = NULL;
- data->lzma_opt.preset_dict_size = 0;
- data->lzma_opt.lc = LZMA_LC_DEFAULT;
- data->lzma_opt.lp = LZMA_LP_DEFAULT;
- data->lzma_opt.pb = LZMA_PB_DEFAULT;
- data->lzma_opt.mode =
- data->compression_level<= 2? LZMA_MODE_FAST:LZMA_MODE_NORMAL;
- data->lzma_opt.nice_len = val->nice_len;
- data->lzma_opt.mf = val->mf;
- data->lzma_opt.depth = 0;
- data->lzmafilters[0].id = LZMA_FILTER_LZMA1;
- data->lzmafilters[0].options = &data->lzma_opt;
- data->lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */
- } else {
- if (lzma_lzma_preset(&data->lzma_opt, data->compression_level)) {
- archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library");
- }
- data->lzmafilters[0].id = LZMA_FILTER_LZMA2;
- data->lzmafilters[0].options = &data->lzma_opt;
- data->lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */
- }
- ret = archive_compressor_xz_init_stream(f, data);
- if (ret == LZMA_OK) {
- f->data = data;
- return (0);
- }
- return (ARCHIVE_FATAL);
-}
-
-/*
- * Set write options.
- */
-static int
-archive_compressor_xz_options(struct archive_write_filter *f,
- const char *key, const char *value)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- if (strcmp(key, "compression-level") == 0) {
- if (value == NULL || !(value[0] >= '0' && value[0] <= '9') ||
- value[1] != '\0')
- return (ARCHIVE_WARN);
- data->compression_level = value[0] - '0';
- if (data->compression_level > 9)
- data->compression_level = 9;
- return (ARCHIVE_OK);
- } else if (strcmp(key, "threads") == 0) {
- char *endptr;
-
- if (value == NULL)
- return (ARCHIVE_WARN);
- errno = 0;
- data->threads = (int)strtoul(value, &endptr, 10);
- if (errno != 0 || *endptr != '\0') {
- data->threads = 1;
- return (ARCHIVE_WARN);
- }
- if (data->threads == 0) {
-#ifdef HAVE_LZMA_STREAM_ENCODER_MT
- data->threads = lzma_cputhreads();
-#else
- data->threads = 1;
-#endif
- }
- return (ARCHIVE_OK);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-/*
- * Write data to the compressed stream.
- */
-static int
-archive_compressor_xz_write(struct archive_write_filter *f,
- const void *buff, size_t length)
-{
- struct private_data *data = (struct private_data *)f->data;
- int ret;
-
- /* Update statistics */
- data->total_in += length;
- if (f->code == ARCHIVE_FILTER_LZIP)
- data->crc32 = lzma_crc32(buff, length, data->crc32);
-
- /* Compress input data to output buffer */
- data->stream.next_in = buff;
- data->stream.avail_in = length;
- if ((ret = drive_compressor(f, data, 0)) != ARCHIVE_OK)
- return (ret);
-
- return (ARCHIVE_OK);
-}
-
-
-/*
- * Finish the compression...
- */
-static int
-archive_compressor_xz_close(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
- int ret;
-
- ret = drive_compressor(f, data, 1);
- if (ret == ARCHIVE_OK) {
- data->total_out +=
- data->compressed_buffer_size - data->stream.avail_out;
- ret = __archive_write_filter(f->next_filter,
- data->compressed,
- data->compressed_buffer_size - data->stream.avail_out);
- if (f->code == ARCHIVE_FILTER_LZIP && ret == ARCHIVE_OK) {
- archive_le32enc(data->compressed, data->crc32);
- archive_le64enc(data->compressed+4, data->total_in);
- archive_le64enc(data->compressed+12, data->total_out + 20);
- ret = __archive_write_filter(f->next_filter,
- data->compressed, 20);
- }
- }
- lzma_end(&(data->stream));
- return ret;
-}
-
-static int
-archive_compressor_xz_free(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
- free(data->compressed);
- free(data);
- f->data = NULL;
- return (ARCHIVE_OK);
-}
-
-/*
- * Utility function to push input data through compressor,
- * writing full output blocks as necessary.
- *
- * Note that this handles both the regular write case (finishing ==
- * false) and the end-of-archive case (finishing == true).
- */
-static int
-drive_compressor(struct archive_write_filter *f,
- struct private_data *data, int finishing)
-{
- int ret;
-
- for (;;) {
- if (data->stream.avail_out == 0) {
- data->total_out += data->compressed_buffer_size;
- ret = __archive_write_filter(f->next_filter,
- data->compressed,
- data->compressed_buffer_size);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- data->stream.next_out = data->compressed;
- data->stream.avail_out = data->compressed_buffer_size;
- }
-
- /* If there's nothing to do, we're done. */
- if (!finishing && data->stream.avail_in == 0)
- return (ARCHIVE_OK);
-
- ret = lzma_code(&(data->stream),
- finishing ? LZMA_FINISH : LZMA_RUN );
-
- switch (ret) {
- case LZMA_OK:
- /* In non-finishing case, check if compressor
- * consumed everything */
- if (!finishing && data->stream.avail_in == 0)
- return (ARCHIVE_OK);
- /* In finishing case, this return always means
- * there's more work */
- break;
- case LZMA_STREAM_END:
- /* This return can only occur in finishing case. */
- if (finishing)
- return (ARCHIVE_OK);
- archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
- "lzma compression data error");
- return (ARCHIVE_FATAL);
- case LZMA_MEMLIMIT_ERROR:
- archive_set_error(f->archive, ENOMEM,
- "lzma compression error: "
- "%ju MiB would have been needed",
- (uintmax_t)((lzma_memusage(&(data->stream))
- + 1024 * 1024 -1)
- / (1024 * 1024)));
- return (ARCHIVE_FATAL);
- default:
- /* Any other return value indicates an error. */
- archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
- "lzma compression failed:"
- " lzma_code() call returned status %d",
- ret);
- return (ARCHIVE_FATAL);
- }
- }
-}
-
-#endif /* HAVE_LZMA_H */
diff --git a/contrib/libs/libarchive/libarchive/archive_write_add_filter_zstd.c b/contrib/libs/libarchive/libarchive/archive_write_add_filter_zstd.c
deleted file mode 100644
index 584cfb668f..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_add_filter_zstd.c
+++ /dev/null
@@ -1,467 +0,0 @@
-/*-
- * Copyright (c) 2017 Sean Purcell
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-__FBSDID("$FreeBSD$");
-
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_ZSTD_H
-#include <zstd.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_string.h"
-#include "archive_write_private.h"
-
-/* Don't compile this if we don't have zstd.h */
-
-struct private_data {
- int compression_level;
- int threads;
-#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
- enum {
- running,
- finishing,
- resetting,
- } state;
- int frame_per_file;
- size_t min_frame_size;
- size_t max_frame_size;
- size_t cur_frame;
- size_t cur_frame_in;
- size_t cur_frame_out;
- size_t total_in;
- ZSTD_CStream *cstream;
- ZSTD_outBuffer out;
-#else
- struct archive_write_program_data *pdata;
-#endif
-};
-
-/* If we don't have the library use default range values (zstdcli.c v1.4.0) */
-#define CLEVEL_MIN -99
-#define CLEVEL_STD_MIN 0 /* prior to 1.3.4 and more recent without using --fast */
-#define CLEVEL_DEFAULT 3
-#define CLEVEL_STD_MAX 19 /* without using --ultra */
-#define CLEVEL_MAX 22
-
-#define MINVER_NEGCLEVEL 10304
-#define MINVER_MINCLEVEL 10306
-
-static int archive_compressor_zstd_options(struct archive_write_filter *,
- const char *, const char *);
-static int archive_compressor_zstd_open(struct archive_write_filter *);
-static int archive_compressor_zstd_write(struct archive_write_filter *,
- const void *, size_t);
-static int archive_compressor_zstd_flush(struct archive_write_filter *);
-static int archive_compressor_zstd_close(struct archive_write_filter *);
-static int archive_compressor_zstd_free(struct archive_write_filter *);
-#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
-static int drive_compressor(struct archive_write_filter *,
- struct private_data *, int, const void *, size_t);
-#endif
-
-
-/*
- * Add a zstd compression filter to this write handle.
- */
-int
-archive_write_add_filter_zstd(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct archive_write_filter *f = __archive_write_allocate_filter(_a);
- struct private_data *data;
- archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_add_filter_zstd");
-
- data = calloc(1, sizeof(*data));
- if (data == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- f->data = data;
- f->open = &archive_compressor_zstd_open;
- f->options = &archive_compressor_zstd_options;
- f->flush = &archive_compressor_zstd_flush;
- f->close = &archive_compressor_zstd_close;
- f->free = &archive_compressor_zstd_free;
- f->code = ARCHIVE_FILTER_ZSTD;
- f->name = "zstd";
- data->compression_level = CLEVEL_DEFAULT;
- data->threads = 0;
-#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
- data->frame_per_file = 0;
- data->min_frame_size = 0;
- data->max_frame_size = SIZE_MAX;
- data->cur_frame_in = 0;
- data->cur_frame_out = 0;
- data->cstream = ZSTD_createCStream();
- if (data->cstream == NULL) {
- free(data);
- archive_set_error(&a->archive, ENOMEM,
- "Failed to allocate zstd compressor object");
- return (ARCHIVE_FATAL);
- }
-
- return (ARCHIVE_OK);
-#else
- data->pdata = __archive_write_program_allocate("zstd");
- if (data->pdata == NULL) {
- free(data);
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Using external zstd program");
- return (ARCHIVE_WARN);
-#endif
-}
-
-static int
-archive_compressor_zstd_free(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
-#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
- ZSTD_freeCStream(data->cstream);
- free(data->out.dst);
-#else
- __archive_write_program_free(data->pdata);
-#endif
- free(data);
- f->data = NULL;
- return (ARCHIVE_OK);
-}
-
-static int string_to_number(const char *string, intmax_t *numberp)
-{
- char *end;
-
- if (string == NULL || *string == '\0')
- return (ARCHIVE_WARN);
- *numberp = strtoimax(string, &end, 10);
- if (end == string || *end != '\0' || errno == EOVERFLOW) {
- *numberp = 0;
- return (ARCHIVE_WARN);
- }
- return (ARCHIVE_OK);
-}
-
-/*
- * Set write options.
- */
-static int
-archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
- const char *value)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- if (strcmp(key, "compression-level") == 0) {
- intmax_t level;
- if (string_to_number(value, &level) != ARCHIVE_OK) {
- return (ARCHIVE_WARN);
- }
- /* If we don't have the library, hard-code the max level */
- int minimum = CLEVEL_MIN;
- int maximum = CLEVEL_MAX;
-#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
- maximum = ZSTD_maxCLevel();
-#if ZSTD_VERSION_NUMBER >= MINVER_MINCLEVEL
- if (ZSTD_versionNumber() >= MINVER_MINCLEVEL) {
- minimum = ZSTD_minCLevel();
- }
- else
-#endif
- if (ZSTD_versionNumber() < MINVER_NEGCLEVEL) {
- minimum = CLEVEL_STD_MIN;
- }
-#endif
- if (level < minimum || level > maximum) {
- return (ARCHIVE_WARN);
- }
- data->compression_level = (int)level;
- return (ARCHIVE_OK);
- } else if (strcmp(key, "threads") == 0) {
- intmax_t threads;
- if (string_to_number(value, &threads) != ARCHIVE_OK) {
- return (ARCHIVE_WARN);
- }
- if (threads < 0) {
- return (ARCHIVE_WARN);
- }
- data->threads = (int)threads;
- return (ARCHIVE_OK);
-#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
- } else if (strcmp(key, "frame-per-file") == 0) {
- data->frame_per_file = 1;
- return (ARCHIVE_OK);
- } else if (strcmp(key, "min-frame-size") == 0) {
- intmax_t min_frame_size;
- if (string_to_number(value, &min_frame_size) != ARCHIVE_OK) {
- return (ARCHIVE_WARN);
- }
- if (min_frame_size < 0) {
- return (ARCHIVE_WARN);
- }
- data->min_frame_size = min_frame_size;
- return (ARCHIVE_OK);
- } else if (strcmp(key, "max-frame-size") == 0) {
- intmax_t max_frame_size;
- if (string_to_number(value, &max_frame_size) != ARCHIVE_OK) {
- return (ARCHIVE_WARN);
- }
- if (max_frame_size < 1024) {
- return (ARCHIVE_WARN);
- }
- data->max_frame_size = max_frame_size;
- return (ARCHIVE_OK);
-#endif
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
-/*
- * Setup callback.
- */
-static int
-archive_compressor_zstd_open(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- if (data->out.dst == NULL) {
- size_t bs = ZSTD_CStreamOutSize(), bpb;
- if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
- /* Buffer size should be a multiple number of
- * the of bytes per block for performance. */
- bpb = archive_write_get_bytes_per_block(f->archive);
- if (bpb > bs)
- bs = bpb;
- else if (bpb != 0)
- bs -= bs % bpb;
- }
- data->out.size = bs;
- data->out.pos = 0;
- data->out.dst
- = (unsigned char *)malloc(data->out.size);
- if (data->out.dst == NULL) {
- archive_set_error(f->archive, ENOMEM,
- "Can't allocate data for compression buffer");
- return (ARCHIVE_FATAL);
- }
- }
-
- f->write = archive_compressor_zstd_write;
-
- if (ZSTD_isError(ZSTD_initCStream(data->cstream,
- data->compression_level))) {
- archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
- "Internal error initializing zstd compressor object");
- return (ARCHIVE_FATAL);
- }
-
- ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_nbWorkers, data->threads);
-
- return (ARCHIVE_OK);
-}
-
-/*
- * Write data to the compressed stream.
- */
-static int
-archive_compressor_zstd_write(struct archive_write_filter *f, const void *buff,
- size_t length)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- return (drive_compressor(f, data, 0, buff, length));
-}
-
-/*
- * Flush the compressed stream.
- */
-static int
-archive_compressor_zstd_flush(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- if (data->frame_per_file && data->state == running &&
- data->cur_frame_out > data->min_frame_size)
- data->state = finishing;
- return (drive_compressor(f, data, 1, NULL, 0));
-}
-
-/*
- * Finish the compression...
- */
-static int
-archive_compressor_zstd_close(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- if (data->state == running)
- data->state = finishing;
- return (drive_compressor(f, data, 1, NULL, 0));
-}
-
-/*
- * Utility function to push input data through compressor,
- * writing full output blocks as necessary.
- */
-static int
-drive_compressor(struct archive_write_filter *f,
- struct private_data *data, int flush, const void *src, size_t length)
-{
- ZSTD_inBuffer in = { .src = src, .size = length, .pos = 0 };
- size_t ipos, opos, zstdret = 0;
- int ret;
-
- for (;;) {
- ipos = in.pos;
- opos = data->out.pos;
- switch (data->state) {
- case running:
- if (in.pos == in.size)
- return (ARCHIVE_OK);
- zstdret = ZSTD_compressStream(data->cstream,
- &data->out, &in);
- if (ZSTD_isError(zstdret))
- goto zstd_fatal;
- break;
- case finishing:
- zstdret = ZSTD_endStream(data->cstream, &data->out);
- if (ZSTD_isError(zstdret))
- goto zstd_fatal;
- if (zstdret == 0)
- data->state = resetting;
- break;
- case resetting:
- ZSTD_CCtx_reset(data->cstream, ZSTD_reset_session_only);
- data->cur_frame++;
- data->cur_frame_in = 0;
- data->cur_frame_out = 0;
- data->state = running;
- break;
- }
- data->total_in += in.pos - ipos;
- data->cur_frame_in += in.pos - ipos;
- data->cur_frame_out += data->out.pos - opos;
- if (data->state == running &&
- data->cur_frame_in >= data->max_frame_size) {
- data->state = finishing;
- }
- if (data->out.pos == data->out.size ||
- (flush && data->out.pos > 0)) {
- ret = __archive_write_filter(f->next_filter,
- data->out.dst, data->out.pos);
- if (ret != ARCHIVE_OK)
- goto fatal;
- data->out.pos = 0;
- }
- }
-zstd_fatal:
- archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
- "Zstd compression failed: %s",
- ZSTD_getErrorName(zstdret));
-fatal:
- return (ARCHIVE_FATAL);
-}
-
-#else /* HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR */
-
-static int
-archive_compressor_zstd_open(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
- struct archive_string as;
- int r;
-
- archive_string_init(&as);
- /* --no-check matches library default */
- archive_strcpy(&as, "zstd --no-check");
-
- if (data->compression_level < CLEVEL_STD_MIN) {
- archive_string_sprintf(&as, " --fast=%d", -data->compression_level);
- } else {
- archive_string_sprintf(&as, " -%d", data->compression_level);
- }
-
- if (data->compression_level > CLEVEL_STD_MAX) {
- archive_strcat(&as, " --ultra");
- }
-
- if (data->threads != 0) {
- archive_string_sprintf(&as, " --threads=%d", data->threads);
- }
-
- f->write = archive_compressor_zstd_write;
- r = __archive_write_program_open(f, data->pdata, as.s);
- archive_string_free(&as);
- return (r);
-}
-
-static int
-archive_compressor_zstd_write(struct archive_write_filter *f, const void *buff,
- size_t length)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- return __archive_write_program_write(f, data->pdata, buff, length);
-}
-
-static int
-archive_compressor_zstd_flush(struct archive_write_filter *f)
-{
- (void)f; /* UNUSED */
-
- return (ARCHIVE_OK);
-}
-
-static int
-archive_compressor_zstd_close(struct archive_write_filter *f)
-{
- struct private_data *data = (struct private_data *)f->data;
-
- return __archive_write_program_close(f, data->pdata);
-}
-
-#endif /* HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR */
diff --git a/contrib/libs/libarchive/libarchive/archive_write_disk_posix.c b/contrib/libs/libarchive/libarchive/archive_write_disk_posix.c
deleted file mode 100644
index 33aa2f4d89..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_disk_posix.c
+++ /dev/null
@@ -1,4759 +0,0 @@
-/*-
- * Copyright (c) 2003-2010 Tim Kientzle
- * Copyright (c) 2012 Michihiro NAKAJIMA
- * 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
- * in this position and unchanged.
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#if !defined(_WIN32) || defined(__CYGWIN__)
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_ACL_H
-#include <sys/acl.h>
-#endif
-#ifdef HAVE_SYS_EXTATTR_H
-#include <sys/extattr.h>
-#endif
-#if HAVE_SYS_XATTR_H
-#include <sys/xattr.h>
-#elif HAVE_ATTR_XATTR_H
-#include <attr/xattr.h>
-#endif
-#ifdef HAVE_SYS_EA_H
-#error #include <sys/ea.h>
-#endif
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_SYS_UTIME_H
-#include <sys/utime.h>
-#endif
-#ifdef HAVE_COPYFILE_H
-#include <copyfile.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_GRP_H
-#include <grp.h>
-#endif
-#ifdef HAVE_LANGINFO_H
-#include <langinfo.h>
-#endif
-#ifdef HAVE_LINUX_FS_H
-#include <linux/fs.h> /* for Linux file flags */
-#endif
-/*
- * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
- * As the include guards don't agree, the order of include is important.
- */
-#ifdef HAVE_LINUX_EXT2_FS_H
-#error #include <linux/ext2_fs.h> /* for Linux file flags */
-#endif
-#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
-#error #include <ext2fs/ext2_fs.h> /* Linux file flags, broken on Cygwin */
-#endif
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-#ifdef HAVE_PWD_H
-#include <pwd.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_UTIME_H
-#include <utime.h>
-#endif
-#ifdef F_GETTIMES /* Tru64 specific */
-#error #include <sys/fcntl1.h>
-#endif
-
-/*
- * Macro to cast st_mtime and time_t to an int64 so that 2 numbers can reliably be compared.
- *
- * It assumes that the input is an integer type of no more than 64 bits.
- * If the number is less than zero, t must be a signed type, so it fits in
- * int64_t. Otherwise, it's a nonnegative value so we can cast it to uint64_t
- * without loss. But it could be a large unsigned value, so we have to clip it
- * to INT64_MAX.*
- */
-#define to_int64_time(t) \
- ((t) < 0 ? (int64_t)(t) : (uint64_t)(t) > (uint64_t)INT64_MAX ? INT64_MAX : (int64_t)(t))
-
-#if __APPLE__
-#include <TargetConditionals.h>
-#if TARGET_OS_MAC && !TARGET_OS_EMBEDDED && HAVE_QUARANTINE_H
-#error #include <quarantine.h>
-#define HAVE_QUARANTINE 1
-#endif
-#endif
-
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-
-/* TODO: Support Mac OS 'quarantine' feature. This is really just a
- * standard tag to mark files that have been downloaded as "tainted".
- * On Mac OS, we should mark the extracted files as tainted if the
- * archive being read was tainted. Windows has a similar feature; we
- * should investigate ways to support this generically. */
-
-#include "archive.h"
-#include "archive_acl_private.h"
-#include "archive_string.h"
-#include "archive_endian.h"
-#include "archive_entry.h"
-#include "archive_private.h"
-#include "archive_write_disk_private.h"
-
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-#ifndef O_CLOEXEC
-#define O_CLOEXEC 0
-#endif
-
-/* Ignore non-int O_NOFOLLOW constant. */
-/* gnulib's fcntl.h does this on AIX, but it seems practical everywhere */
-#if defined O_NOFOLLOW && !(INT_MIN <= O_NOFOLLOW && O_NOFOLLOW <= INT_MAX)
-#undef O_NOFOLLOW
-#endif
-
-#ifndef O_NOFOLLOW
-#define O_NOFOLLOW 0
-#endif
-
-#ifndef AT_FDCWD
-#define AT_FDCWD -100
-#endif
-
-struct fixup_entry {
- struct fixup_entry *next;
- struct archive_acl acl;
- mode_t mode;
- __LA_MODE_T filetype;
- int64_t atime;
- int64_t birthtime;
- int64_t mtime;
- int64_t ctime;
- unsigned long atime_nanos;
- unsigned long birthtime_nanos;
- unsigned long mtime_nanos;
- unsigned long ctime_nanos;
- unsigned long fflags_set;
- size_t mac_metadata_size;
- void *mac_metadata;
- int fixup; /* bitmask of what needs fixing */
- char *name;
-};
-
-/*
- * We use a bitmask to track which operations remain to be done for
- * this file. In particular, this helps us avoid unnecessary
- * operations when it's possible to take care of one step as a
- * side-effect of another. For example, mkdir() can specify the mode
- * for the newly-created object but symlink() cannot. This means we
- * can skip chmod() if mkdir() succeeded, but we must explicitly
- * chmod() if we're trying to create a directory that already exists
- * (mkdir() failed) or if we're restoring a symlink. Similarly, we
- * need to verify UID/GID before trying to restore SUID/SGID bits;
- * that verification can occur explicitly through a stat() call or
- * implicitly because of a successful chown() call.
- */
-#define TODO_MODE_FORCE 0x40000000
-#define TODO_MODE_BASE 0x20000000
-#define TODO_SUID 0x10000000
-#define TODO_SUID_CHECK 0x08000000
-#define TODO_SGID 0x04000000
-#define TODO_SGID_CHECK 0x02000000
-#define TODO_APPLEDOUBLE 0x01000000
-#define TODO_MODE (TODO_MODE_BASE|TODO_SUID|TODO_SGID)
-#define TODO_TIMES ARCHIVE_EXTRACT_TIME
-#define TODO_OWNER ARCHIVE_EXTRACT_OWNER
-#define TODO_FFLAGS ARCHIVE_EXTRACT_FFLAGS
-#define TODO_ACLS ARCHIVE_EXTRACT_ACL
-#define TODO_XATTR ARCHIVE_EXTRACT_XATTR
-#define TODO_MAC_METADATA ARCHIVE_EXTRACT_MAC_METADATA
-#define TODO_HFS_COMPRESSION ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED
-
-struct archive_write_disk {
- struct archive archive;
-
- mode_t user_umask;
- struct fixup_entry *fixup_list;
- struct fixup_entry *current_fixup;
- int64_t user_uid;
- int skip_file_set;
- int64_t skip_file_dev;
- int64_t skip_file_ino;
- time_t start_time;
-
- int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid);
- void (*cleanup_gid)(void *private);
- void *lookup_gid_data;
- int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid);
- void (*cleanup_uid)(void *private);
- void *lookup_uid_data;
-
- /*
- * Full path of last file to satisfy symlink checks.
- */
- struct archive_string path_safe;
-
- /*
- * Cached stat data from disk for the current entry.
- * If this is valid, pst points to st. Otherwise,
- * pst is null.
- */
- struct stat st;
- struct stat *pst;
-
- /* Information about the object being restored right now. */
- struct archive_entry *entry; /* Entry being extracted. */
- char *name; /* Name of entry, possibly edited. */
- struct archive_string _name_data; /* backing store for 'name' */
- char *tmpname; /* Temporary name * */
- struct archive_string _tmpname_data; /* backing store for 'tmpname' */
- /* Tasks remaining for this object. */
- int todo;
- /* Tasks deferred until end-of-archive. */
- int deferred;
- /* Options requested by the client. */
- int flags;
- /* Handle for the file we're restoring. */
- int fd;
- /* Current offset for writing data to the file. */
- int64_t offset;
- /* Last offset actually written to disk. */
- int64_t fd_offset;
- /* Total bytes actually written to files. */
- int64_t total_bytes_written;
- /* Maximum size of file, -1 if unknown. */
- int64_t filesize;
- /* Dir we were in before this restore; only for deep paths. */
- int restore_pwd;
- /* Mode we should use for this entry; affected by _PERM and umask. */
- mode_t mode;
- /* UID/GID to use in restoring this entry. */
- int64_t uid;
- int64_t gid;
- /*
- * HFS+ Compression.
- */
- /* Xattr "com.apple.decmpfs". */
- uint32_t decmpfs_attr_size;
- unsigned char *decmpfs_header_p;
- /* ResourceFork set options used for fsetxattr. */
- int rsrc_xattr_options;
- /* Xattr "com.apple.ResourceFork". */
- unsigned char *resource_fork;
- size_t resource_fork_allocated_size;
- unsigned int decmpfs_block_count;
- uint32_t *decmpfs_block_info;
- /* Buffer for compressed data. */
- unsigned char *compressed_buffer;
- size_t compressed_buffer_size;
- size_t compressed_buffer_remaining;
- /* The offset of the ResourceFork where compressed data will
- * be placed. */
- uint32_t compressed_rsrc_position;
- uint32_t compressed_rsrc_position_v;
- /* Buffer for uncompressed data. */
- char *uncompressed_buffer;
- size_t block_remaining_bytes;
- size_t file_remaining_bytes;
-#ifdef HAVE_ZLIB_H
- z_stream stream;
- int stream_valid;
- int decmpfs_compression_level;
-#endif
-};
-
-/*
- * Default mode for dirs created automatically (will be modified by umask).
- * Note that POSIX specifies 0777 for implicitly-created dirs, "modified
- * by the process' file creation mask."
- */
-#define DEFAULT_DIR_MODE 0777
-/*
- * Dir modes are restored in two steps: During the extraction, the permissions
- * in the archive are modified to match the following limits. During
- * the post-extract fixup pass, the permissions from the archive are
- * applied.
- */
-#define MINIMUM_DIR_MODE 0700
-#define MAXIMUM_DIR_MODE 0775
-
-/*
- * Maximum uncompressed size of a decmpfs block.
- */
-#define MAX_DECMPFS_BLOCK_SIZE (64 * 1024)
-/*
- * HFS+ compression type.
- */
-#define CMP_XATTR 3/* Compressed data in xattr. */
-#define CMP_RESOURCE_FORK 4/* Compressed data in resource fork. */
-/*
- * HFS+ compression resource fork.
- */
-#define RSRC_H_SIZE 260 /* Base size of Resource fork header. */
-#define RSRC_F_SIZE 50 /* Size of Resource fork footer. */
-/* Size to write compressed data to resource fork. */
-#define COMPRESSED_W_SIZE (64 * 1024)
-/* decmpfs definitions. */
-#define MAX_DECMPFS_XATTR_SIZE 3802
-#ifndef DECMPFS_XATTR_NAME
-#define DECMPFS_XATTR_NAME "com.apple.decmpfs"
-#endif
-#define DECMPFS_MAGIC 0x636d7066
-#define DECMPFS_COMPRESSION_MAGIC 0
-#define DECMPFS_COMPRESSION_TYPE 4
-#define DECMPFS_UNCOMPRESSED_SIZE 8
-#define DECMPFS_HEADER_SIZE 16
-
-#define HFS_BLOCKS(s) ((s) >> 12)
-
-
-static int la_opendirat(int, const char *);
-static int la_mktemp(struct archive_write_disk *);
-static int la_verify_filetype(mode_t, __LA_MODE_T);
-static void fsobj_error(int *, struct archive_string *, int, const char *,
- const char *);
-static int check_symlinks_fsobj(char *, int *, struct archive_string *,
- int, int);
-static int check_symlinks(struct archive_write_disk *);
-static int create_filesystem_object(struct archive_write_disk *);
-static struct fixup_entry *current_fixup(struct archive_write_disk *,
- const char *pathname);
-#if defined(HAVE_FCHDIR) && defined(PATH_MAX)
-static void edit_deep_directories(struct archive_write_disk *ad);
-#endif
-static int cleanup_pathname_fsobj(char *, int *, struct archive_string *,
- int);
-static int cleanup_pathname(struct archive_write_disk *);
-static int create_dir(struct archive_write_disk *, char *);
-static int create_parent_dir(struct archive_write_disk *, char *);
-static ssize_t hfs_write_data_block(struct archive_write_disk *,
- const char *, size_t);
-static int fixup_appledouble(struct archive_write_disk *, const char *);
-static int older(struct stat *, struct archive_entry *);
-static int restore_entry(struct archive_write_disk *);
-static int set_mac_metadata(struct archive_write_disk *, const char *,
- const void *, size_t);
-static int set_xattrs(struct archive_write_disk *);
-static int clear_nochange_fflags(struct archive_write_disk *);
-static int set_fflags(struct archive_write_disk *);
-static int set_fflags_platform(struct archive_write_disk *, int fd,
- const char *name, mode_t mode,
- unsigned long fflags_set, unsigned long fflags_clear);
-static int set_ownership(struct archive_write_disk *);
-static int set_mode(struct archive_write_disk *, int mode);
-static int set_time(int, int, const char *, time_t, long, time_t, long);
-static int set_times(struct archive_write_disk *, int, int, const char *,
- time_t, long, time_t, long, time_t, long, time_t, long);
-static int set_times_from_entry(struct archive_write_disk *);
-static struct fixup_entry *sort_dir_list(struct fixup_entry *p);
-static ssize_t write_data_block(struct archive_write_disk *,
- const char *, size_t);
-static void close_file_descriptor(struct archive_write_disk *);
-
-static int _archive_write_disk_close(struct archive *);
-static int _archive_write_disk_free(struct archive *);
-static int _archive_write_disk_header(struct archive *,
- struct archive_entry *);
-static int64_t _archive_write_disk_filter_bytes(struct archive *, int);
-static int _archive_write_disk_finish_entry(struct archive *);
-static ssize_t _archive_write_disk_data(struct archive *, const void *,
- size_t);
-static ssize_t _archive_write_disk_data_block(struct archive *, const void *,
- size_t, int64_t);
-
-static int
-la_mktemp(struct archive_write_disk *a)
-{
- int oerrno, fd;
- mode_t mode;
-
- archive_string_empty(&a->_tmpname_data);
- archive_string_sprintf(&a->_tmpname_data, "%s.XXXXXX", a->name);
- a->tmpname = a->_tmpname_data.s;
-
- fd = __archive_mkstemp(a->tmpname);
- if (fd == -1)
- return -1;
-
- mode = a->mode & 0777 & ~a->user_umask;
- if (fchmod(fd, mode) == -1) {
- oerrno = errno;
- close(fd);
- errno = oerrno;
- return -1;
- }
- return fd;
-}
-
-static int
-la_opendirat(int fd, const char *path) {
- const int flags = O_CLOEXEC
-#if defined(O_BINARY)
- | O_BINARY
-#endif
-#if defined(O_DIRECTORY)
- | O_DIRECTORY
-#endif
-#if defined(O_PATH)
- | O_PATH
-#elif defined(O_SEARCH)
- | O_SEARCH
-#elif defined(__FreeBSD__) && defined(O_EXEC)
- | O_EXEC
-#else
- | O_RDONLY
-#endif
- ;
-
-#if !defined(HAVE_OPENAT)
- if (fd != AT_FDCWD) {
- errno = ENOTSUP;
- return (-1);
- } else
- return (open(path, flags));
-#else
- return (openat(fd, path, flags));
-#endif
-}
-
-static int
-la_verify_filetype(mode_t mode, __LA_MODE_T filetype) {
- int ret = 0;
-
- switch (filetype) {
- case AE_IFREG:
- ret = (S_ISREG(mode));
- break;
- case AE_IFDIR:
- ret = (S_ISDIR(mode));
- break;
- case AE_IFLNK:
- ret = (S_ISLNK(mode));
- break;
- case AE_IFSOCK:
- ret = (S_ISSOCK(mode));
- break;
- case AE_IFCHR:
- ret = (S_ISCHR(mode));
- break;
- case AE_IFBLK:
- ret = (S_ISBLK(mode));
- break;
- case AE_IFIFO:
- ret = (S_ISFIFO(mode));
- break;
- default:
- break;
- }
-
- return (ret);
-}
-
-static int
-lazy_stat(struct archive_write_disk *a)
-{
- if (a->pst != NULL) {
- /* Already have stat() data available. */
- return (ARCHIVE_OK);
- }
-#ifdef HAVE_FSTAT
- if (a->fd >= 0 && fstat(a->fd, &a->st) == 0) {
- a->pst = &a->st;
- return (ARCHIVE_OK);
- }
-#endif
- /*
- * XXX At this point, symlinks should not be hit, otherwise
- * XXX a race occurred. Do we want to check explicitly for that?
- */
-#ifdef HAVE_LSTAT
- if (lstat(a->name, &a->st) == 0)
-#else
- if (la_stat(a->name, &a->st) == 0)
-#endif
- {
- a->pst = &a->st;
- return (ARCHIVE_OK);
- }
- archive_set_error(&a->archive, errno, "Couldn't stat file");
- return (ARCHIVE_WARN);
-}
-
-static const struct archive_vtable
-archive_write_disk_vtable = {
- .archive_close = _archive_write_disk_close,
- .archive_filter_bytes = _archive_write_disk_filter_bytes,
- .archive_free = _archive_write_disk_free,
- .archive_write_header = _archive_write_disk_header,
- .archive_write_finish_entry = _archive_write_disk_finish_entry,
- .archive_write_data = _archive_write_disk_data,
- .archive_write_data_block = _archive_write_disk_data_block,
-};
-
-static int64_t
-_archive_write_disk_filter_bytes(struct archive *_a, int n)
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
- (void)n; /* UNUSED */
- if (n == -1 || n == 0)
- return (a->total_bytes_written);
- return (-1);
-}
-
-
-int
-archive_write_disk_set_options(struct archive *_a, int flags)
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
-
- a->flags = flags;
- return (ARCHIVE_OK);
-}
-
-
-/*
- * Extract this entry to disk.
- *
- * TODO: Validate hardlinks. According to the standards, we're
- * supposed to check each extracted hardlink and squawk if it refers
- * to a file that we didn't restore. I'm not entirely convinced this
- * is a good idea, but more importantly: Is there any way to validate
- * hardlinks without keeping a complete list of filenames from the
- * entire archive?? Ugh.
- *
- */
-static int
-_archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
- struct fixup_entry *fe;
- const char *linkname;
- int ret, r;
-
- archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
- "archive_write_disk_header");
- archive_clear_error(&a->archive);
- if (a->archive.state & ARCHIVE_STATE_DATA) {
- r = _archive_write_disk_finish_entry(&a->archive);
- if (r == ARCHIVE_FATAL)
- return (r);
- }
-
- /* Set up for this particular entry. */
- a->pst = NULL;
- a->current_fixup = NULL;
- a->deferred = 0;
- if (a->entry) {
- archive_entry_free(a->entry);
- a->entry = NULL;
- }
- a->entry = archive_entry_clone(entry);
- a->fd = -1;
- a->fd_offset = 0;
- a->offset = 0;
- a->restore_pwd = -1;
- a->uid = a->user_uid;
- a->mode = archive_entry_mode(a->entry);
- if (archive_entry_size_is_set(a->entry))
- a->filesize = archive_entry_size(a->entry);
- else
- a->filesize = -1;
- archive_strcpy(&(a->_name_data), archive_entry_pathname(a->entry));
- a->name = a->_name_data.s;
- archive_clear_error(&a->archive);
-
- /*
- * Clean up the requested path. This is necessary for correct
- * dir restores; the dir restore logic otherwise gets messed
- * up by nonsense like "dir/.".
- */
- ret = cleanup_pathname(a);
- if (ret != ARCHIVE_OK)
- return (ret);
-
- /*
- * Check if we have a hardlink that points to itself.
- */
- linkname = archive_entry_hardlink(a->entry);
- if (linkname != NULL && strcmp(a->name, linkname) == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Skipping hardlink pointing to itself: %s",
- a->name);
- return (ARCHIVE_WARN);
- }
-
- /*
- * Query the umask so we get predictable mode settings.
- * This gets done on every call to _write_header in case the
- * user edits their umask during the extraction for some
- * reason.
- */
- umask(a->user_umask = umask(0));
-
- /* Figure out what we need to do for this entry. */
- a->todo = TODO_MODE_BASE;
- if (a->flags & ARCHIVE_EXTRACT_PERM) {
- a->todo |= TODO_MODE_FORCE; /* Be pushy about permissions. */
- /*
- * SGID requires an extra "check" step because we
- * cannot easily predict the GID that the system will
- * assign. (Different systems assign GIDs to files
- * based on a variety of criteria, including process
- * credentials and the gid of the enclosing
- * directory.) We can only restore the SGID bit if
- * the file has the right GID, and we only know the
- * GID if we either set it (see set_ownership) or if
- * we've actually called stat() on the file after it
- * was restored. Since there are several places at
- * which we might verify the GID, we need a TODO bit
- * to keep track.
- */
- if (a->mode & S_ISGID)
- a->todo |= TODO_SGID | TODO_SGID_CHECK;
- /*
- * Verifying the SUID is simpler, but can still be
- * done in multiple ways, hence the separate "check" bit.
- */
- if (a->mode & S_ISUID)
- a->todo |= TODO_SUID | TODO_SUID_CHECK;
- } else {
- /*
- * User didn't request full permissions, so don't
- * restore SUID, SGID bits and obey umask.
- */
- a->mode &= ~S_ISUID;
- a->mode &= ~S_ISGID;
- a->mode &= ~S_ISVTX;
- a->mode &= ~a->user_umask;
- }
- if (a->flags & ARCHIVE_EXTRACT_OWNER)
- a->todo |= TODO_OWNER;
- if (a->flags & ARCHIVE_EXTRACT_TIME)
- a->todo |= TODO_TIMES;
- if (a->flags & ARCHIVE_EXTRACT_ACL) {
-#if ARCHIVE_ACL_DARWIN
- /*
- * On MacOS, platform ACLs get stored in mac_metadata, too.
- * If we intend to extract mac_metadata and it is present
- * we skip extracting libarchive NFSv4 ACLs.
- */
- size_t metadata_size;
-
- if ((a->flags & ARCHIVE_EXTRACT_MAC_METADATA) == 0 ||
- archive_entry_mac_metadata(a->entry,
- &metadata_size) == NULL || metadata_size == 0)
-#endif
-#if ARCHIVE_ACL_LIBRICHACL
- /*
- * RichACLs are stored in an extended attribute.
- * If we intend to extract extended attributes and have this
- * attribute we skip extracting libarchive NFSv4 ACLs.
- */
- short extract_acls = 1;
- if (a->flags & ARCHIVE_EXTRACT_XATTR && (
- archive_entry_acl_types(a->entry) &
- ARCHIVE_ENTRY_ACL_TYPE_NFS4)) {
- const char *attr_name;
- const void *attr_value;
- size_t attr_size;
- int i = archive_entry_xattr_reset(a->entry);
- while (i--) {
- archive_entry_xattr_next(a->entry, &attr_name,
- &attr_value, &attr_size);
- if (attr_name != NULL && attr_value != NULL &&
- attr_size > 0 && strcmp(attr_name,
- "trusted.richacl") == 0) {
- extract_acls = 0;
- break;
- }
- }
- }
- if (extract_acls)
-#endif
-#if ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_LIBRICHACL
- {
-#endif
- if (archive_entry_filetype(a->entry) == AE_IFDIR)
- a->deferred |= TODO_ACLS;
- else
- a->todo |= TODO_ACLS;
-#if ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_LIBRICHACL
- }
-#endif
- }
- if (a->flags & ARCHIVE_EXTRACT_MAC_METADATA) {
- if (archive_entry_filetype(a->entry) == AE_IFDIR)
- a->deferred |= TODO_MAC_METADATA;
- else
- a->todo |= TODO_MAC_METADATA;
- }
-#if defined(__APPLE__) && defined(UF_COMPRESSED) && defined(HAVE_ZLIB_H)
- if ((a->flags & ARCHIVE_EXTRACT_NO_HFS_COMPRESSION) == 0) {
- unsigned long set, clear;
- archive_entry_fflags(a->entry, &set, &clear);
- if ((set & ~clear) & UF_COMPRESSED) {
- a->todo |= TODO_HFS_COMPRESSION;
- a->decmpfs_block_count = (unsigned)-1;
- }
- }
- if ((a->flags & ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED) != 0 &&
- (a->mode & AE_IFMT) == AE_IFREG && a->filesize > 0) {
- a->todo |= TODO_HFS_COMPRESSION;
- a->decmpfs_block_count = (unsigned)-1;
- }
- {
- const char *p;
-
- /* Check if the current file name is a type of the
- * resource fork file. */
- p = strrchr(a->name, '/');
- if (p == NULL)
- p = a->name;
- else
- p++;
- if (p[0] == '.' && p[1] == '_') {
- /* Do not compress "._XXX" files. */
- a->todo &= ~TODO_HFS_COMPRESSION;
- if (a->filesize > 0)
- a->todo |= TODO_APPLEDOUBLE;
- }
- }
-#endif
-
- if (a->flags & ARCHIVE_EXTRACT_XATTR) {
-#if ARCHIVE_XATTR_DARWIN
- /*
- * On MacOS, extended attributes get stored in mac_metadata,
- * too. If we intend to extract mac_metadata and it is present
- * we skip extracting extended attributes.
- */
- size_t metadata_size;
-
- if ((a->flags & ARCHIVE_EXTRACT_MAC_METADATA) == 0 ||
- archive_entry_mac_metadata(a->entry,
- &metadata_size) == NULL || metadata_size == 0)
-#endif
- a->todo |= TODO_XATTR;
- }
- if (a->flags & ARCHIVE_EXTRACT_FFLAGS)
- a->todo |= TODO_FFLAGS;
- if (a->flags & ARCHIVE_EXTRACT_SECURE_SYMLINKS) {
- ret = check_symlinks(a);
- if (ret != ARCHIVE_OK)
- return (ret);
- }
-#if defined(HAVE_FCHDIR) && defined(PATH_MAX)
- /* If path exceeds PATH_MAX, shorten the path. */
- edit_deep_directories(a);
-#endif
-
- ret = restore_entry(a);
-
-#if defined(__APPLE__) && defined(UF_COMPRESSED) && defined(HAVE_ZLIB_H)
- /*
- * Check if the filesystem the file is restoring on supports
- * HFS+ Compression. If not, cancel HFS+ Compression.
- */
- if (a->todo | TODO_HFS_COMPRESSION) {
- /*
- * NOTE: UF_COMPRESSED is ignored even if the filesystem
- * supports HFS+ Compression because the file should
- * have at least an extended attribute "com.apple.decmpfs"
- * before the flag is set to indicate that the file have
- * been compressed. If the filesystem does not support
- * HFS+ Compression the system call will fail.
- */
- if (a->fd < 0 || fchflags(a->fd, UF_COMPRESSED) != 0)
- a->todo &= ~TODO_HFS_COMPRESSION;
- }
-#endif
-
- /*
- * TODO: There are rumours that some extended attributes must
- * be restored before file data is written. If this is true,
- * then we either need to write all extended attributes both
- * before and after restoring the data, or find some rule for
- * determining which must go first and which last. Due to the
- * many ways people are using xattrs, this may prove to be an
- * intractable problem.
- */
-
-#ifdef HAVE_FCHDIR
- /* If we changed directory above, restore it here. */
- if (a->restore_pwd >= 0) {
- r = fchdir(a->restore_pwd);
- if (r != 0) {
- archive_set_error(&a->archive, errno,
- "chdir() failure");
- ret = ARCHIVE_FATAL;
- }
- close(a->restore_pwd);
- a->restore_pwd = -1;
- }
-#endif
-
- /*
- * Fixup uses the unedited pathname from archive_entry_pathname(),
- * because it is relative to the base dir and the edited path
- * might be relative to some intermediate dir as a result of the
- * deep restore logic.
- */
- if (a->deferred & TODO_MODE) {
- fe = current_fixup(a, archive_entry_pathname(entry));
- if (fe == NULL)
- return (ARCHIVE_FATAL);
- fe->filetype = archive_entry_filetype(entry);
- fe->fixup |= TODO_MODE_BASE;
- fe->mode = a->mode;
- }
-
- if ((a->deferred & TODO_TIMES)
- && (archive_entry_mtime_is_set(entry)
- || archive_entry_atime_is_set(entry))) {
- fe = current_fixup(a, archive_entry_pathname(entry));
- if (fe == NULL)
- return (ARCHIVE_FATAL);
- fe->filetype = archive_entry_filetype(entry);
- fe->mode = a->mode;
- fe->fixup |= TODO_TIMES;
- if (archive_entry_atime_is_set(entry)) {
- fe->atime = archive_entry_atime(entry);
- fe->atime_nanos = archive_entry_atime_nsec(entry);
- } else {
- /* If atime is unset, use start time. */
- fe->atime = a->start_time;
- fe->atime_nanos = 0;
- }
- if (archive_entry_mtime_is_set(entry)) {
- fe->mtime = archive_entry_mtime(entry);
- fe->mtime_nanos = archive_entry_mtime_nsec(entry);
- } else {
- /* If mtime is unset, use start time. */
- fe->mtime = a->start_time;
- fe->mtime_nanos = 0;
- }
- if (archive_entry_birthtime_is_set(entry)) {
- fe->birthtime = archive_entry_birthtime(entry);
- fe->birthtime_nanos = archive_entry_birthtime_nsec(
- entry);
- } else {
- /* If birthtime is unset, use mtime. */
- fe->birthtime = fe->mtime;
- fe->birthtime_nanos = fe->mtime_nanos;
- }
- }
-
- if (a->deferred & TODO_ACLS) {
- fe = current_fixup(a, archive_entry_pathname(entry));
- if (fe == NULL)
- return (ARCHIVE_FATAL);
- fe->filetype = archive_entry_filetype(entry);
- fe->fixup |= TODO_ACLS;
- archive_acl_copy(&fe->acl, archive_entry_acl(entry));
- }
-
- if (a->deferred & TODO_MAC_METADATA) {
- const void *metadata;
- size_t metadata_size;
- metadata = archive_entry_mac_metadata(a->entry, &metadata_size);
- if (metadata != NULL && metadata_size > 0) {
- fe = current_fixup(a, archive_entry_pathname(entry));
- if (fe == NULL)
- return (ARCHIVE_FATAL);
- fe->filetype = archive_entry_filetype(entry);
- fe->mac_metadata = malloc(metadata_size);
- if (fe->mac_metadata != NULL) {
- memcpy(fe->mac_metadata, metadata,
- metadata_size);
- fe->mac_metadata_size = metadata_size;
- fe->fixup |= TODO_MAC_METADATA;
- }
- }
- }
-
- if (a->deferred & TODO_FFLAGS) {
- fe = current_fixup(a, archive_entry_pathname(entry));
- if (fe == NULL)
- return (ARCHIVE_FATAL);
- fe->filetype = archive_entry_filetype(entry);
- fe->fixup |= TODO_FFLAGS;
- /* TODO: Complete this.. defer fflags from below. */
- }
-
- /* We've created the object and are ready to pour data into it. */
- if (ret >= ARCHIVE_WARN)
- a->archive.state = ARCHIVE_STATE_DATA;
- /*
- * If it's not open, tell our client not to try writing.
- * In particular, dirs, links, etc, don't get written to.
- */
- if (a->fd < 0) {
- archive_entry_set_size(entry, 0);
- a->filesize = 0;
- }
-
- return (ret);
-}
-
-int
-archive_write_disk_set_skip_file(struct archive *_a, la_int64_t d, la_int64_t i)
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
- archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_write_disk_set_skip_file");
- a->skip_file_set = 1;
- a->skip_file_dev = d;
- a->skip_file_ino = i;
- return (ARCHIVE_OK);
-}
-
-static ssize_t
-write_data_block(struct archive_write_disk *a, const char *buff, size_t size)
-{
- uint64_t start_size = size;
- ssize_t bytes_written = 0;
- ssize_t block_size = 0, bytes_to_write;
-
- if (size == 0)
- return (ARCHIVE_OK);
-
- if (a->filesize == 0 || a->fd < 0) {
- archive_set_error(&a->archive, 0,
- "Attempt to write to an empty file");
- return (ARCHIVE_WARN);
- }
-
- if (a->flags & ARCHIVE_EXTRACT_SPARSE) {
-#if HAVE_STRUCT_STAT_ST_BLKSIZE
- int r;
- if ((r = lazy_stat(a)) != ARCHIVE_OK)
- return (r);
- block_size = a->pst->st_blksize;
-#else
- /* XXX TODO XXX Is there a more appropriate choice here ? */
- /* This needn't match the filesystem allocation size. */
- block_size = 16*1024;
-#endif
- }
-
- /* If this write would run beyond the file size, truncate it. */
- if (a->filesize >= 0 && (int64_t)(a->offset + size) > a->filesize)
- start_size = size = (size_t)(a->filesize - a->offset);
-
- /* Write the data. */
- while (size > 0) {
- if (block_size == 0) {
- bytes_to_write = size;
- } else {
- /* We're sparsifying the file. */
- const char *p, *end;
- int64_t block_end;
-
- /* Skip leading zero bytes. */
- for (p = buff, end = buff + size; p < end; ++p) {
- if (*p != '\0')
- break;
- }
- a->offset += p - buff;
- size -= p - buff;
- buff = p;
- if (size == 0)
- break;
-
- /* Calculate next block boundary after offset. */
- block_end
- = (a->offset / block_size + 1) * block_size;
-
- /* If the adjusted write would cross block boundary,
- * truncate it to the block boundary. */
- bytes_to_write = size;
- if (a->offset + bytes_to_write > block_end)
- bytes_to_write = block_end - a->offset;
- }
- /* Seek if necessary to the specified offset. */
- if (a->offset != a->fd_offset) {
- if (lseek(a->fd, a->offset, SEEK_SET) < 0) {
- archive_set_error(&a->archive, errno,
- "Seek failed");
- return (ARCHIVE_FATAL);
- }
- a->fd_offset = a->offset;
- }
- bytes_written = write(a->fd, buff, bytes_to_write);
- if (bytes_written < 0) {
- archive_set_error(&a->archive, errno, "Write failed");
- return (ARCHIVE_WARN);
- }
- buff += bytes_written;
- size -= bytes_written;
- a->total_bytes_written += bytes_written;
- a->offset += bytes_written;
- a->fd_offset = a->offset;
- }
- return (start_size - size);
-}
-
-#if defined(__APPLE__) && defined(UF_COMPRESSED) && defined(HAVE_SYS_XATTR_H)\
- && defined(HAVE_ZLIB_H)
-
-/*
- * Set UF_COMPRESSED file flag.
- * This have to be called after hfs_write_decmpfs() because if the
- * file does not have "com.apple.decmpfs" xattr the flag is ignored.
- */
-static int
-hfs_set_compressed_fflag(struct archive_write_disk *a)
-{
- int r;
-
- if ((r = lazy_stat(a)) != ARCHIVE_OK)
- return (r);
-
- a->st.st_flags |= UF_COMPRESSED;
- if (fchflags(a->fd, a->st.st_flags) != 0) {
- archive_set_error(&a->archive, errno,
- "Failed to set UF_COMPRESSED file flag");
- return (ARCHIVE_WARN);
- }
- return (ARCHIVE_OK);
-}
-
-/*
- * HFS+ Compression decmpfs
- *
- * +------------------------------+ +0
- * | Magic(LE 4 bytes) |
- * +------------------------------+
- * | Type(LE 4 bytes) |
- * +------------------------------+
- * | Uncompressed size(LE 8 bytes)|
- * +------------------------------+ +16
- * | |
- * | Compressed data |
- * | (Placed only if Type == 3) |
- * | |
- * +------------------------------+ +3802 = MAX_DECMPFS_XATTR_SIZE
- *
- * Type is 3: decmpfs has compressed data.
- * Type is 4: Resource Fork has compressed data.
- */
-/*
- * Write "com.apple.decmpfs"
- */
-static int
-hfs_write_decmpfs(struct archive_write_disk *a)
-{
- int r;
- uint32_t compression_type;
-
- r = fsetxattr(a->fd, DECMPFS_XATTR_NAME, a->decmpfs_header_p,
- a->decmpfs_attr_size, 0, 0);
- if (r < 0) {
- archive_set_error(&a->archive, errno,
- "Cannot restore xattr:%s", DECMPFS_XATTR_NAME);
- compression_type = archive_le32dec(
- &a->decmpfs_header_p[DECMPFS_COMPRESSION_TYPE]);
- if (compression_type == CMP_RESOURCE_FORK)
- fremovexattr(a->fd, XATTR_RESOURCEFORK_NAME,
- XATTR_SHOWCOMPRESSION);
- return (ARCHIVE_WARN);
- }
- return (ARCHIVE_OK);
-}
-
-/*
- * HFS+ Compression Resource Fork
- *
- * +-----------------------------+
- * | Header(260 bytes) |
- * +-----------------------------+
- * | Block count(LE 4 bytes) |
- * +-----------------------------+ --+
- * +-- | Offset (LE 4 bytes) | |
- * | | [distance from Block count] | | Block 0
- * | +-----------------------------+ |
- * | | Compressed size(LE 4 bytes) | |
- * | +-----------------------------+ --+
- * | | |
- * | | .................. |
- * | | |
- * | +-----------------------------+ --+
- * | | Offset (LE 4 bytes) | |
- * | +-----------------------------+ | Block (Block count -1)
- * | | Compressed size(LE 4 bytes) | |
- * +-> +-----------------------------+ --+
- * | Compressed data(n bytes) | Block 0
- * +-----------------------------+
- * | |
- * | .................. |
- * | |
- * +-----------------------------+
- * | Compressed data(n bytes) | Block (Block count -1)
- * +-----------------------------+
- * | Footer(50 bytes) |
- * +-----------------------------+
- *
- */
-/*
- * Write the header of "com.apple.ResourceFork"
- */
-static int
-hfs_write_resource_fork(struct archive_write_disk *a, unsigned char *buff,
- size_t bytes, uint32_t position)
-{
- int ret;
-
- ret = fsetxattr(a->fd, XATTR_RESOURCEFORK_NAME, buff, bytes,
- position, a->rsrc_xattr_options);
- if (ret < 0) {
- archive_set_error(&a->archive, errno,
- "Cannot restore xattr: %s at %u pos %u bytes",
- XATTR_RESOURCEFORK_NAME,
- (unsigned)position,
- (unsigned)bytes);
- return (ARCHIVE_WARN);
- }
- a->rsrc_xattr_options &= ~XATTR_CREATE;
- return (ARCHIVE_OK);
-}
-
-static int
-hfs_write_compressed_data(struct archive_write_disk *a, size_t bytes_compressed)
-{
- int ret;
-
- ret = hfs_write_resource_fork(a, a->compressed_buffer,
- bytes_compressed, a->compressed_rsrc_position);
- if (ret == ARCHIVE_OK)
- a->compressed_rsrc_position += bytes_compressed;
- return (ret);
-}
-
-static int
-hfs_write_resource_fork_header(struct archive_write_disk *a)
-{
- unsigned char *buff;
- uint32_t rsrc_bytes;
- uint32_t rsrc_header_bytes;
-
- /*
- * Write resource fork header + block info.
- */
- buff = a->resource_fork;
- rsrc_bytes = a->compressed_rsrc_position - RSRC_F_SIZE;
- rsrc_header_bytes =
- RSRC_H_SIZE + /* Header base size. */
- 4 + /* Block count. */
- (a->decmpfs_block_count * 8);/* Block info */
- archive_be32enc(buff, 0x100);
- archive_be32enc(buff + 4, rsrc_bytes);
- archive_be32enc(buff + 8, rsrc_bytes - 256);
- archive_be32enc(buff + 12, 0x32);
- memset(buff + 16, 0, 240);
- archive_be32enc(buff + 256, rsrc_bytes - 260);
- return hfs_write_resource_fork(a, buff, rsrc_header_bytes, 0);
-}
-
-static size_t
-hfs_set_resource_fork_footer(unsigned char *buff, size_t buff_size)
-{
- static const char rsrc_footer[RSRC_F_SIZE] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x1c, 0x00, 0x32, 0x00, 0x00, 'c', 'm',
- 'p', 'f', 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01,
- 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00
- };
- if (buff_size < sizeof(rsrc_footer))
- return (0);
- memcpy(buff, rsrc_footer, sizeof(rsrc_footer));
- return (sizeof(rsrc_footer));
-}
-
-static int
-hfs_reset_compressor(struct archive_write_disk *a)
-{
- int ret;
-
- if (a->stream_valid)
- ret = deflateReset(&a->stream);
- else
- ret = deflateInit(&a->stream, a->decmpfs_compression_level);
-
- if (ret != Z_OK) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Failed to initialize compressor");
- return (ARCHIVE_FATAL);
- } else
- a->stream_valid = 1;
-
- return (ARCHIVE_OK);
-}
-
-static int
-hfs_decompress(struct archive_write_disk *a)
-{
- uint32_t *block_info;
- unsigned int block_count;
- uint32_t data_pos, data_size;
- ssize_t r;
- ssize_t bytes_written, bytes_to_write;
- unsigned char *b;
-
- block_info = (uint32_t *)(a->resource_fork + RSRC_H_SIZE);
- block_count = archive_le32dec(block_info++);
- while (block_count--) {
- data_pos = RSRC_H_SIZE + archive_le32dec(block_info++);
- data_size = archive_le32dec(block_info++);
- r = fgetxattr(a->fd, XATTR_RESOURCEFORK_NAME,
- a->compressed_buffer, data_size, data_pos, 0);
- if (r != data_size) {
- archive_set_error(&a->archive,
- (r < 0)?errno:ARCHIVE_ERRNO_MISC,
- "Failed to read resource fork");
- return (ARCHIVE_WARN);
- }
- if (a->compressed_buffer[0] == 0xff) {
- bytes_to_write = data_size -1;
- b = a->compressed_buffer + 1;
- } else {
- uLong dest_len = MAX_DECMPFS_BLOCK_SIZE;
- int zr;
-
- zr = uncompress((Bytef *)a->uncompressed_buffer,
- &dest_len, a->compressed_buffer, data_size);
- if (zr != Z_OK) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Failed to decompress resource fork");
- return (ARCHIVE_WARN);
- }
- bytes_to_write = dest_len;
- b = (unsigned char *)a->uncompressed_buffer;
- }
- do {
- bytes_written = write(a->fd, b, bytes_to_write);
- if (bytes_written < 0) {
- archive_set_error(&a->archive, errno,
- "Write failed");
- return (ARCHIVE_WARN);
- }
- bytes_to_write -= bytes_written;
- b += bytes_written;
- } while (bytes_to_write > 0);
- }
- r = fremovexattr(a->fd, XATTR_RESOURCEFORK_NAME, 0);
- if (r == -1) {
- archive_set_error(&a->archive, errno,
- "Failed to remove resource fork");
- return (ARCHIVE_WARN);
- }
- return (ARCHIVE_OK);
-}
-
-static int
-hfs_drive_compressor(struct archive_write_disk *a, const char *buff,
- size_t size)
-{
- unsigned char *buffer_compressed;
- size_t bytes_compressed;
- size_t bytes_used;
- int ret;
-
- ret = hfs_reset_compressor(a);
- if (ret != ARCHIVE_OK)
- return (ret);
-
- if (a->compressed_buffer == NULL) {
- size_t block_size;
-
- block_size = COMPRESSED_W_SIZE + RSRC_F_SIZE +
- + compressBound(MAX_DECMPFS_BLOCK_SIZE);
- a->compressed_buffer = malloc(block_size);
- if (a->compressed_buffer == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Resource Fork");
- return (ARCHIVE_FATAL);
- }
- a->compressed_buffer_size = block_size;
- a->compressed_buffer_remaining = block_size;
- }
-
- buffer_compressed = a->compressed_buffer +
- a->compressed_buffer_size - a->compressed_buffer_remaining;
- a->stream.next_in = (Bytef *)(uintptr_t)(const void *)buff;
- a->stream.avail_in = size;
- a->stream.next_out = buffer_compressed;
- a->stream.avail_out = a->compressed_buffer_remaining;
- do {
- ret = deflate(&a->stream, Z_FINISH);
- switch (ret) {
- case Z_OK:
- case Z_STREAM_END:
- break;
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Failed to compress data");
- return (ARCHIVE_FAILED);
- }
- } while (ret == Z_OK);
- bytes_compressed = a->compressed_buffer_remaining - a->stream.avail_out;
-
- /*
- * If the compressed size is larger than the original size,
- * throw away compressed data, use uncompressed data instead.
- */
- if (bytes_compressed > size) {
- buffer_compressed[0] = 0xFF;/* uncompressed marker. */
- memcpy(buffer_compressed + 1, buff, size);
- bytes_compressed = size + 1;
- }
- a->compressed_buffer_remaining -= bytes_compressed;
-
- /*
- * If the compressed size is smaller than MAX_DECMPFS_XATTR_SIZE
- * and the block count in the file is only one, store compressed
- * data to decmpfs xattr instead of the resource fork.
- */
- if (a->decmpfs_block_count == 1 &&
- (a->decmpfs_attr_size + bytes_compressed)
- <= MAX_DECMPFS_XATTR_SIZE) {
- archive_le32enc(&a->decmpfs_header_p[DECMPFS_COMPRESSION_TYPE],
- CMP_XATTR);
- memcpy(a->decmpfs_header_p + DECMPFS_HEADER_SIZE,
- buffer_compressed, bytes_compressed);
- a->decmpfs_attr_size += bytes_compressed;
- a->compressed_buffer_remaining = a->compressed_buffer_size;
- /*
- * Finish HFS+ Compression.
- * - Write the decmpfs xattr.
- * - Set the UF_COMPRESSED file flag.
- */
- ret = hfs_write_decmpfs(a);
- if (ret == ARCHIVE_OK)
- ret = hfs_set_compressed_fflag(a);
- return (ret);
- }
-
- /* Update block info. */
- archive_le32enc(a->decmpfs_block_info++,
- a->compressed_rsrc_position_v - RSRC_H_SIZE);
- archive_le32enc(a->decmpfs_block_info++, bytes_compressed);
- a->compressed_rsrc_position_v += bytes_compressed;
-
- /*
- * Write the compressed data to the resource fork.
- */
- bytes_used = a->compressed_buffer_size - a->compressed_buffer_remaining;
- while (bytes_used >= COMPRESSED_W_SIZE) {
- ret = hfs_write_compressed_data(a, COMPRESSED_W_SIZE);
- if (ret != ARCHIVE_OK)
- return (ret);
- bytes_used -= COMPRESSED_W_SIZE;
- if (bytes_used > COMPRESSED_W_SIZE)
- memmove(a->compressed_buffer,
- a->compressed_buffer + COMPRESSED_W_SIZE,
- bytes_used);
- else
- memcpy(a->compressed_buffer,
- a->compressed_buffer + COMPRESSED_W_SIZE,
- bytes_used);
- }
- a->compressed_buffer_remaining = a->compressed_buffer_size - bytes_used;
-
- /*
- * If the current block is the last block, write the remaining
- * compressed data and the resource fork footer.
- */
- if (a->file_remaining_bytes == 0) {
- size_t rsrc_size;
- int64_t bk;
-
- /* Append the resource footer. */
- rsrc_size = hfs_set_resource_fork_footer(
- a->compressed_buffer + bytes_used,
- a->compressed_buffer_remaining);
- ret = hfs_write_compressed_data(a, bytes_used + rsrc_size);
- a->compressed_buffer_remaining = a->compressed_buffer_size;
-
- /* If the compressed size is not enough smaller than
- * the uncompressed size. cancel HFS+ compression.
- * TODO: study a behavior of ditto utility and improve
- * the condition to fall back into no HFS+ compression. */
- bk = HFS_BLOCKS(a->compressed_rsrc_position);
- bk += bk >> 7;
- if (bk > HFS_BLOCKS(a->filesize))
- return hfs_decompress(a);
- /*
- * Write the resourcefork header.
- */
- if (ret == ARCHIVE_OK)
- ret = hfs_write_resource_fork_header(a);
- /*
- * Finish HFS+ Compression.
- * - Write the decmpfs xattr.
- * - Set the UF_COMPRESSED file flag.
- */
- if (ret == ARCHIVE_OK)
- ret = hfs_write_decmpfs(a);
- if (ret == ARCHIVE_OK)
- ret = hfs_set_compressed_fflag(a);
- }
- return (ret);
-}
-
-static ssize_t
-hfs_write_decmpfs_block(struct archive_write_disk *a, const char *buff,
- size_t size)
-{
- const char *buffer_to_write;
- size_t bytes_to_write;
- int ret;
-
- if (a->decmpfs_block_count == (unsigned)-1) {
- void *new_block;
- size_t new_size;
- unsigned int block_count;
-
- if (a->decmpfs_header_p == NULL) {
- new_block = malloc(MAX_DECMPFS_XATTR_SIZE
- + sizeof(uint32_t));
- if (new_block == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for decmpfs");
- return (ARCHIVE_FATAL);
- }
- a->decmpfs_header_p = new_block;
- }
- a->decmpfs_attr_size = DECMPFS_HEADER_SIZE;
- archive_le32enc(&a->decmpfs_header_p[DECMPFS_COMPRESSION_MAGIC],
- DECMPFS_MAGIC);
- archive_le32enc(&a->decmpfs_header_p[DECMPFS_COMPRESSION_TYPE],
- CMP_RESOURCE_FORK);
- archive_le64enc(&a->decmpfs_header_p[DECMPFS_UNCOMPRESSED_SIZE],
- a->filesize);
-
- /* Calculate a block count of the file. */
- block_count =
- (a->filesize + MAX_DECMPFS_BLOCK_SIZE -1) /
- MAX_DECMPFS_BLOCK_SIZE;
- /*
- * Allocate buffer for resource fork.
- * Set up related pointers;
- */
- new_size =
- RSRC_H_SIZE + /* header */
- 4 + /* Block count */
- (block_count * sizeof(uint32_t) * 2) +
- RSRC_F_SIZE; /* footer */
- if (new_size > a->resource_fork_allocated_size) {
- new_block = realloc(a->resource_fork, new_size);
- if (new_block == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for ResourceFork");
- return (ARCHIVE_FATAL);
- }
- a->resource_fork_allocated_size = new_size;
- a->resource_fork = new_block;
- }
-
- /* Allocate uncompressed buffer */
- if (a->uncompressed_buffer == NULL) {
- new_block = malloc(MAX_DECMPFS_BLOCK_SIZE);
- if (new_block == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for decmpfs");
- return (ARCHIVE_FATAL);
- }
- a->uncompressed_buffer = new_block;
- }
- a->block_remaining_bytes = MAX_DECMPFS_BLOCK_SIZE;
- a->file_remaining_bytes = a->filesize;
- a->compressed_buffer_remaining = a->compressed_buffer_size;
-
- /*
- * Set up a resource fork.
- */
- a->rsrc_xattr_options = XATTR_CREATE;
- /* Get the position where we are going to set a bunch
- * of block info. */
- a->decmpfs_block_info =
- (uint32_t *)(a->resource_fork + RSRC_H_SIZE);
- /* Set the block count to the resource fork. */
- archive_le32enc(a->decmpfs_block_info++, block_count);
- /* Get the position where we are going to set compressed
- * data. */
- a->compressed_rsrc_position =
- RSRC_H_SIZE + 4 + (block_count * 8);
- a->compressed_rsrc_position_v = a->compressed_rsrc_position;
- a->decmpfs_block_count = block_count;
- }
-
- /* Ignore redundant bytes. */
- if (a->file_remaining_bytes == 0)
- return ((ssize_t)size);
-
- /* Do not overrun a block size. */
- if (size > a->block_remaining_bytes)
- bytes_to_write = a->block_remaining_bytes;
- else
- bytes_to_write = size;
- /* Do not overrun the file size. */
- if (bytes_to_write > a->file_remaining_bytes)
- bytes_to_write = a->file_remaining_bytes;
-
- /* For efficiency, if a copy length is full of the uncompressed
- * buffer size, do not copy writing data to it. */
- if (bytes_to_write == MAX_DECMPFS_BLOCK_SIZE)
- buffer_to_write = buff;
- else {
- memcpy(a->uncompressed_buffer +
- MAX_DECMPFS_BLOCK_SIZE - a->block_remaining_bytes,
- buff, bytes_to_write);
- buffer_to_write = a->uncompressed_buffer;
- }
- a->block_remaining_bytes -= bytes_to_write;
- a->file_remaining_bytes -= bytes_to_write;
-
- if (a->block_remaining_bytes == 0 || a->file_remaining_bytes == 0) {
- ret = hfs_drive_compressor(a, buffer_to_write,
- MAX_DECMPFS_BLOCK_SIZE - a->block_remaining_bytes);
- if (ret < 0)
- return (ret);
- a->block_remaining_bytes = MAX_DECMPFS_BLOCK_SIZE;
- }
- /* Ignore redundant bytes. */
- if (a->file_remaining_bytes == 0)
- return ((ssize_t)size);
- return (bytes_to_write);
-}
-
-static ssize_t
-hfs_write_data_block(struct archive_write_disk *a, const char *buff,
- size_t size)
-{
- uint64_t start_size = size;
- ssize_t bytes_written = 0;
- ssize_t bytes_to_write;
-
- if (size == 0)
- return (ARCHIVE_OK);
-
- if (a->filesize == 0 || a->fd < 0) {
- archive_set_error(&a->archive, 0,
- "Attempt to write to an empty file");
- return (ARCHIVE_WARN);
- }
-
- /* If this write would run beyond the file size, truncate it. */
- if (a->filesize >= 0 && (int64_t)(a->offset + size) > a->filesize)
- start_size = size = (size_t)(a->filesize - a->offset);
-
- /* Write the data. */
- while (size > 0) {
- bytes_to_write = size;
- /* Seek if necessary to the specified offset. */
- if (a->offset < a->fd_offset) {
- /* Can't support backward move. */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Seek failed");
- return (ARCHIVE_FATAL);
- } else if (a->offset > a->fd_offset) {
- uint64_t skip = a->offset - a->fd_offset;
- char nullblock[1024];
-
- memset(nullblock, 0, sizeof(nullblock));
- while (skip > 0) {
- if (skip > sizeof(nullblock))
- bytes_written = hfs_write_decmpfs_block(
- a, nullblock, sizeof(nullblock));
- else
- bytes_written = hfs_write_decmpfs_block(
- a, nullblock, skip);
- if (bytes_written < 0) {
- archive_set_error(&a->archive, errno,
- "Write failed");
- return (ARCHIVE_WARN);
- }
- skip -= bytes_written;
- }
-
- a->fd_offset = a->offset;
- }
- bytes_written =
- hfs_write_decmpfs_block(a, buff, bytes_to_write);
- if (bytes_written < 0)
- return (bytes_written);
- buff += bytes_written;
- size -= bytes_written;
- a->total_bytes_written += bytes_written;
- a->offset += bytes_written;
- a->fd_offset = a->offset;
- }
- return (start_size - size);
-}
-#else
-static ssize_t
-hfs_write_data_block(struct archive_write_disk *a, const char *buff,
- size_t size)
-{
- return (write_data_block(a, buff, size));
-}
-#endif
-
-static ssize_t
-_archive_write_disk_data_block(struct archive *_a,
- const void *buff, size_t size, int64_t offset)
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
- ssize_t r;
-
- archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_DATA, "archive_write_data_block");
-
- a->offset = offset;
- if (a->todo & TODO_HFS_COMPRESSION)
- r = hfs_write_data_block(a, buff, size);
- else
- r = write_data_block(a, buff, size);
- if (r < ARCHIVE_OK)
- return (r);
- if ((size_t)r < size) {
- archive_set_error(&a->archive, 0,
- "Too much data: Truncating file at %ju bytes",
- (uintmax_t)a->filesize);
- return (ARCHIVE_WARN);
- }
-#if ARCHIVE_VERSION_NUMBER < 3999000
- return (ARCHIVE_OK);
-#else
- return (size);
-#endif
-}
-
-static ssize_t
-_archive_write_disk_data(struct archive *_a, const void *buff, size_t size)
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
-
- archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_DATA, "archive_write_data");
-
- if (a->todo & TODO_HFS_COMPRESSION)
- return (hfs_write_data_block(a, buff, size));
- return (write_data_block(a, buff, size));
-}
-
-static int
-_archive_write_disk_finish_entry(struct archive *_a)
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
- int ret = ARCHIVE_OK;
-
- archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
- "archive_write_finish_entry");
- if (a->archive.state & ARCHIVE_STATE_HEADER)
- return (ARCHIVE_OK);
- archive_clear_error(&a->archive);
-
- /* Pad or truncate file to the right size. */
- if (a->fd < 0) {
- /* There's no file. */
- } else if (a->filesize < 0) {
- /* File size is unknown, so we can't set the size. */
- } else if (a->fd_offset == a->filesize) {
- /* Last write ended at exactly the filesize; we're done. */
- /* Hopefully, this is the common case. */
-#if defined(__APPLE__) && defined(UF_COMPRESSED) && defined(HAVE_ZLIB_H)
- } else if (a->todo & TODO_HFS_COMPRESSION) {
- char null_d[1024];
- ssize_t r;
-
- if (a->file_remaining_bytes)
- memset(null_d, 0, sizeof(null_d));
- while (a->file_remaining_bytes) {
- if (a->file_remaining_bytes > sizeof(null_d))
- r = hfs_write_data_block(
- a, null_d, sizeof(null_d));
- else
- r = hfs_write_data_block(
- a, null_d, a->file_remaining_bytes);
- if (r < 0) {
- close_file_descriptor(a);
- return ((int)r);
- }
- }
-#endif
- } else {
-#if HAVE_FTRUNCATE
- if (ftruncate(a->fd, a->filesize) == -1 &&
- a->filesize == 0) {
- archive_set_error(&a->archive, errno,
- "File size could not be restored");
- close_file_descriptor(a);
- return (ARCHIVE_FAILED);
- }
-#endif
- /*
- * Not all platforms implement the XSI option to
- * extend files via ftruncate. Stat() the file again
- * to see what happened.
- */
- a->pst = NULL;
- if ((ret = lazy_stat(a)) != ARCHIVE_OK) {
- close_file_descriptor(a);
- return (ret);
- }
- /* We can use lseek()/write() to extend the file if
- * ftruncate didn't work or isn't available. */
- if (a->st.st_size < a->filesize) {
- const char nul = '\0';
- if (lseek(a->fd, a->filesize - 1, SEEK_SET) < 0) {
- archive_set_error(&a->archive, errno,
- "Seek failed");
- close_file_descriptor(a);
- return (ARCHIVE_FATAL);
- }
- if (write(a->fd, &nul, 1) < 0) {
- archive_set_error(&a->archive, errno,
- "Write to restore size failed");
- close_file_descriptor(a);
- return (ARCHIVE_FATAL);
- }
- a->pst = NULL;
- }
- }
-
- /* Restore metadata. */
-
- /*
- * This is specific to Mac OS X.
- * If the current file is an AppleDouble file, it should be
- * linked with the data fork file and remove it.
- */
- if (a->todo & TODO_APPLEDOUBLE) {
- int r2 = fixup_appledouble(a, a->name);
- if (r2 == ARCHIVE_EOF) {
- /* The current file has been successfully linked
- * with the data fork file and removed. So there
- * is nothing to do on the current file. */
- goto finish_metadata;
- }
- if (r2 < ret) ret = r2;
- }
-
- /*
- * Look up the "real" UID only if we're going to need it.
- * TODO: the TODO_SGID condition can be dropped here, can't it?
- */
- if (a->todo & (TODO_OWNER | TODO_SUID | TODO_SGID)) {
- a->uid = archive_write_disk_uid(&a->archive,
- archive_entry_uname(a->entry),
- archive_entry_uid(a->entry));
- }
- /* Look up the "real" GID only if we're going to need it. */
- /* TODO: the TODO_SUID condition can be dropped here, can't it? */
- if (a->todo & (TODO_OWNER | TODO_SGID | TODO_SUID)) {
- a->gid = archive_write_disk_gid(&a->archive,
- archive_entry_gname(a->entry),
- archive_entry_gid(a->entry));
- }
-
- /*
- * Restore ownership before set_mode tries to restore suid/sgid
- * bits. If we set the owner, we know what it is and can skip
- * a stat() call to examine the ownership of the file on disk.
- */
- if (a->todo & TODO_OWNER) {
- int r2 = set_ownership(a);
- if (r2 < ret) ret = r2;
- }
-
- /*
- * HYPOTHESIS:
- * If we're not root, we won't be setting any security
- * attributes that may be wiped by the set_mode() routine
- * below. We also can't set xattr on non-owner-writable files,
- * which may be the state after set_mode(). Perform
- * set_xattrs() first based on these constraints.
- */
- if (a->user_uid != 0 &&
- (a->todo & TODO_XATTR)) {
- int r2 = set_xattrs(a);
- if (r2 < ret) ret = r2;
- }
-
- /*
- * set_mode must precede ACLs on systems such as Solaris and
- * FreeBSD where setting the mode implicitly clears extended ACLs
- */
- if (a->todo & TODO_MODE) {
- int r2 = set_mode(a, a->mode);
- if (r2 < ret) ret = r2;
- }
-
- /*
- * Security-related extended attributes (such as
- * security.capability on Linux) have to be restored last,
- * since they're implicitly removed by other file changes.
- * We do this last only when root.
- */
- if (a->user_uid == 0 &&
- (a->todo & TODO_XATTR)) {
- int r2 = set_xattrs(a);
- if (r2 < ret) ret = r2;
- }
-
- /*
- * Some flags prevent file modification; they must be restored after
- * file contents are written.
- */
- if (a->todo & TODO_FFLAGS) {
- int r2 = set_fflags(a);
- if (r2 < ret) ret = r2;
- }
-
- /*
- * Time must follow most other metadata;
- * otherwise atime will get changed.
- */
- if (a->todo & TODO_TIMES) {
- int r2 = set_times_from_entry(a);
- if (r2 < ret) ret = r2;
- }
-
- /*
- * Mac extended metadata includes ACLs.
- */
- if (a->todo & TODO_MAC_METADATA) {
- const void *metadata;
- size_t metadata_size;
- metadata = archive_entry_mac_metadata(a->entry, &metadata_size);
- if (metadata != NULL && metadata_size > 0) {
- int r2 = set_mac_metadata(a, archive_entry_pathname(
- a->entry), metadata, metadata_size);
- if (r2 < ret) ret = r2;
- }
- }
-
- /*
- * ACLs must be restored after timestamps because there are
- * ACLs that prevent attribute changes (including time).
- */
- if (a->todo & TODO_ACLS) {
- int r2;
- r2 = archive_write_disk_set_acls(&a->archive, a->fd,
- archive_entry_pathname(a->entry),
- archive_entry_acl(a->entry),
- archive_entry_mode(a->entry));
- if (r2 < ret) ret = r2;
- }
-
-finish_metadata:
- /* If there's an fd, we can close it now. */
- if (a->fd >= 0) {
- close(a->fd);
- a->fd = -1;
- if (a->tmpname) {
- if (rename(a->tmpname, a->name) == -1) {
- archive_set_error(&a->archive, errno,
- "Failed to rename temporary file");
- ret = ARCHIVE_FAILED;
- unlink(a->tmpname);
- }
- a->tmpname = NULL;
- }
- }
- /* If there's an entry, we can release it now. */
- archive_entry_free(a->entry);
- a->entry = NULL;
- a->archive.state = ARCHIVE_STATE_HEADER;
- return (ret);
-}
-
-int
-archive_write_disk_set_group_lookup(struct archive *_a,
- void *private_data,
- la_int64_t (*lookup_gid)(void *private, const char *gname, la_int64_t gid),
- void (*cleanup_gid)(void *private))
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
- archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_write_disk_set_group_lookup");
-
- if (a->cleanup_gid != NULL && a->lookup_gid_data != NULL)
- (a->cleanup_gid)(a->lookup_gid_data);
-
- a->lookup_gid = lookup_gid;
- a->cleanup_gid = cleanup_gid;
- a->lookup_gid_data = private_data;
- return (ARCHIVE_OK);
-}
-
-int
-archive_write_disk_set_user_lookup(struct archive *_a,
- void *private_data,
- int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid),
- void (*cleanup_uid)(void *private))
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
- archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_write_disk_set_user_lookup");
-
- if (a->cleanup_uid != NULL && a->lookup_uid_data != NULL)
- (a->cleanup_uid)(a->lookup_uid_data);
-
- a->lookup_uid = lookup_uid;
- a->cleanup_uid = cleanup_uid;
- a->lookup_uid_data = private_data;
- return (ARCHIVE_OK);
-}
-
-int64_t
-archive_write_disk_gid(struct archive *_a, const char *name, la_int64_t id)
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
- archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_write_disk_gid");
- if (a->lookup_gid)
- return (a->lookup_gid)(a->lookup_gid_data, name, id);
- return (id);
-}
-
-int64_t
-archive_write_disk_uid(struct archive *_a, const char *name, la_int64_t id)
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
- archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_write_disk_uid");
- if (a->lookup_uid)
- return (a->lookup_uid)(a->lookup_uid_data, name, id);
- return (id);
-}
-
-/*
- * Create a new archive_write_disk object and initialize it with global state.
- */
-struct archive *
-archive_write_disk_new(void)
-{
- struct archive_write_disk *a;
-
- a = (struct archive_write_disk *)calloc(1, sizeof(*a));
- if (a == NULL)
- return (NULL);
- a->archive.magic = ARCHIVE_WRITE_DISK_MAGIC;
- /* We're ready to write a header immediately. */
- a->archive.state = ARCHIVE_STATE_HEADER;
- a->archive.vtable = &archive_write_disk_vtable;
- a->start_time = time(NULL);
- /* Query and restore the umask. */
- umask(a->user_umask = umask(0));
-#ifdef HAVE_GETEUID
- a->user_uid = geteuid();
-#endif /* HAVE_GETEUID */
- if (archive_string_ensure(&a->path_safe, 512) == NULL) {
- free(a);
- return (NULL);
- }
- a->path_safe.s[0] = 0;
-
-#ifdef HAVE_ZLIB_H
- a->decmpfs_compression_level = 5;
-#endif
- return (&a->archive);
-}
-
-
-/*
- * If pathname is longer than PATH_MAX, chdir to a suitable
- * intermediate dir and edit the path down to a shorter suffix. Note
- * that this routine never returns an error; if the chdir() attempt
- * fails for any reason, we just go ahead with the long pathname. The
- * object creation is likely to fail, but any error will get handled
- * at that time.
- */
-#if defined(HAVE_FCHDIR) && defined(PATH_MAX)
-static void
-edit_deep_directories(struct archive_write_disk *a)
-{
- int ret;
- char *tail = a->name;
-
- /* If path is short, avoid the open() below. */
- if (strlen(tail) < PATH_MAX)
- return;
-
- /* Try to record our starting dir. */
- a->restore_pwd = la_opendirat(AT_FDCWD, ".");
- __archive_ensure_cloexec_flag(a->restore_pwd);
- if (a->restore_pwd < 0)
- return;
-
- /* As long as the path is too long... */
- while (strlen(tail) >= PATH_MAX) {
- /* Locate a dir prefix shorter than PATH_MAX. */
- tail += PATH_MAX - 8;
- while (tail > a->name && *tail != '/')
- tail--;
- /* Exit if we find a too-long path component. */
- if (tail <= a->name)
- return;
- /* Create the intermediate dir and chdir to it. */
- *tail = '\0'; /* Terminate dir portion */
- ret = create_dir(a, a->name);
- if (ret == ARCHIVE_OK && chdir(a->name) != 0)
- ret = ARCHIVE_FAILED;
- *tail = '/'; /* Restore the / we removed. */
- if (ret != ARCHIVE_OK)
- return;
- tail++;
- /* The chdir() succeeded; we've now shortened the path. */
- a->name = tail;
- }
- return;
-}
-#endif
-
-/*
- * The main restore function.
- */
-static int
-restore_entry(struct archive_write_disk *a)
-{
- int ret = ARCHIVE_OK, en;
-
- if (a->flags & ARCHIVE_EXTRACT_UNLINK && !S_ISDIR(a->mode)) {
- /*
- * TODO: Fix this. Apparently, there are platforms
- * that still allow root to hose the entire filesystem
- * by unlinking a dir. The S_ISDIR() test above
- * prevents us from using unlink() here if the new
- * object is a dir, but that doesn't mean the old
- * object isn't a dir.
- */
- if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS)
- (void)clear_nochange_fflags(a);
- if (unlink(a->name) == 0) {
- /* We removed it, reset cached stat. */
- a->pst = NULL;
- } else if (errno == ENOENT) {
- /* File didn't exist, that's just as good. */
- } else if (rmdir(a->name) == 0) {
- /* It was a dir, but now it's gone. */
- a->pst = NULL;
- } else {
- /* We tried, but couldn't get rid of it. */
- archive_set_error(&a->archive, errno,
- "Could not unlink");
- return(ARCHIVE_FAILED);
- }
- }
-
- /* Try creating it first; if this fails, we'll try to recover. */
- en = create_filesystem_object(a);
-
- if ((en == ENOTDIR || en == ENOENT)
- && !(a->flags & ARCHIVE_EXTRACT_NO_AUTODIR)) {
- /* If the parent dir doesn't exist, try creating it. */
- create_parent_dir(a, a->name);
- /* Now try to create the object again. */
- en = create_filesystem_object(a);
- }
-
- if ((en == ENOENT) && (archive_entry_hardlink(a->entry) != NULL)) {
- archive_set_error(&a->archive, en,
- "Hard-link target '%s' does not exist.",
- archive_entry_hardlink(a->entry));
- return (ARCHIVE_FAILED);
- }
-
- if ((en == EISDIR || en == EEXIST)
- && (a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
- /* If we're not overwriting, we're done. */
- if (S_ISDIR(a->mode)) {
- /* Don't overwrite any settings on existing directories. */
- a->todo = 0;
- }
- archive_entry_unset_size(a->entry);
- return (ARCHIVE_OK);
- }
-
- /*
- * Some platforms return EISDIR if you call
- * open(O_WRONLY | O_EXCL | O_CREAT) on a directory, some
- * return EEXIST. POSIX is ambiguous, requiring EISDIR
- * for open(O_WRONLY) on a dir and EEXIST for open(O_EXCL | O_CREAT)
- * on an existing item.
- */
- if (en == EISDIR) {
- /* A dir is in the way of a non-dir, rmdir it. */
- if (rmdir(a->name) != 0) {
- archive_set_error(&a->archive, errno,
- "Can't remove already-existing dir");
- return (ARCHIVE_FAILED);
- }
- a->pst = NULL;
- /* Try again. */
- en = create_filesystem_object(a);
- } else if (en == EEXIST) {
- /*
- * We know something is in the way, but we don't know what;
- * we need to find out before we go any further.
- */
- int r = 0;
- /*
- * The SECURE_SYMLINKS logic has already removed a
- * symlink to a dir if the client wants that. So
- * follow the symlink if we're creating a dir.
- */
- if (S_ISDIR(a->mode))
- r = la_stat(a->name, &a->st);
- /*
- * If it's not a dir (or it's a broken symlink),
- * then don't follow it.
- */
- if (r != 0 || !S_ISDIR(a->mode))
-#ifdef HAVE_LSTAT
- r = lstat(a->name, &a->st);
-#else
- r = la_stat(a->name, &a->st);
-#endif
- if (r != 0) {
- archive_set_error(&a->archive, errno,
- "Can't stat existing object");
- return (ARCHIVE_FAILED);
- }
-
- /*
- * NO_OVERWRITE_NEWER doesn't apply to directories.
- */
- if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER)
- && !S_ISDIR(a->st.st_mode)) {
- if (!older(&(a->st), a->entry)) {
- archive_entry_unset_size(a->entry);
- return (ARCHIVE_OK);
- }
- }
-
- /* If it's our archive, we're done. */
- if (a->skip_file_set &&
- a->st.st_dev == (dev_t)a->skip_file_dev &&
- a->st.st_ino == (ino_t)a->skip_file_ino) {
- archive_set_error(&a->archive, 0,
- "Refusing to overwrite archive");
- return (ARCHIVE_FAILED);
- }
-
- if (!S_ISDIR(a->st.st_mode)) {
- if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS)
- (void)clear_nochange_fflags(a);
-
- if ((a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) &&
- S_ISREG(a->st.st_mode)) {
- /* Use a temporary file to extract */
- if ((a->fd = la_mktemp(a)) == -1) {
- archive_set_error(&a->archive, errno,
- "Can't create temporary file");
- return ARCHIVE_FAILED;
- }
- a->pst = NULL;
- en = 0;
- } else {
- /* A non-dir is in the way, unlink it. */
- if (unlink(a->name) != 0) {
- archive_set_error(&a->archive, errno,
- "Can't unlink already-existing "
- "object");
- return (ARCHIVE_FAILED);
- }
- a->pst = NULL;
- /* Try again. */
- en = create_filesystem_object(a);
- }
- } else if (!S_ISDIR(a->mode)) {
- /* A dir is in the way of a non-dir, rmdir it. */
- if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS)
- (void)clear_nochange_fflags(a);
- if (rmdir(a->name) != 0) {
- archive_set_error(&a->archive, errno,
- "Can't replace existing directory with non-directory");
- return (ARCHIVE_FAILED);
- }
- /* Try again. */
- en = create_filesystem_object(a);
- } else {
- /*
- * There's a dir in the way of a dir. Don't
- * waste time with rmdir()/mkdir(), just fix
- * up the permissions on the existing dir.
- * Note that we don't change perms on existing
- * dirs unless _EXTRACT_PERM is specified.
- */
- if ((a->mode != a->st.st_mode)
- && (a->todo & TODO_MODE_FORCE))
- a->deferred |= (a->todo & TODO_MODE);
- /* Ownership doesn't need deferred fixup. */
- en = 0; /* Forget the EEXIST. */
- }
- }
-
- if (en) {
- /* Everything failed; give up here. */
- if ((&a->archive)->error == NULL)
- archive_set_error(&a->archive, en, "Can't create '%s'",
- a->name);
- return (ARCHIVE_FAILED);
- }
-
- a->pst = NULL; /* Cached stat data no longer valid. */
- return (ret);
-}
-
-/*
- * Returns 0 if creation succeeds, or else returns errno value from
- * the failed system call. Note: This function should only ever perform
- * a single system call.
- */
-static int
-create_filesystem_object(struct archive_write_disk *a)
-{
- /* Create the entry. */
- const char *linkname;
- mode_t final_mode, mode;
- int r;
- /* these for check_symlinks_fsobj */
- char *linkname_copy; /* non-const copy of linkname */
- struct stat st;
- struct archive_string error_string;
- int error_number;
-
- /* We identify hard/symlinks according to the link names. */
- /* Since link(2) and symlink(2) don't handle modes, we're done here. */
- linkname = archive_entry_hardlink(a->entry);
- if (linkname != NULL) {
-#if !HAVE_LINK
- return (EPERM);
-#else
- archive_string_init(&error_string);
- linkname_copy = strdup(linkname);
- if (linkname_copy == NULL) {
- return (EPERM);
- }
- /*
- * TODO: consider using the cleaned-up path as the link
- * target?
- */
- r = cleanup_pathname_fsobj(linkname_copy, &error_number,
- &error_string, a->flags);
- if (r != ARCHIVE_OK) {
- archive_set_error(&a->archive, error_number, "%s",
- error_string.s);
- free(linkname_copy);
- archive_string_free(&error_string);
- /*
- * EPERM is more appropriate than error_number for our
- * callers
- */
- return (EPERM);
- }
- r = check_symlinks_fsobj(linkname_copy, &error_number,
- &error_string, a->flags, 1);
- if (r != ARCHIVE_OK) {
- archive_set_error(&a->archive, error_number, "%s",
- error_string.s);
- free(linkname_copy);
- archive_string_free(&error_string);
- /*
- * EPERM is more appropriate than error_number for our
- * callers
- */
- return (EPERM);
- }
- free(linkname_copy);
- archive_string_free(&error_string);
- /*
- * Unlinking and linking here is really not atomic,
- * but doing it right, would require us to construct
- * an mktemplink() function, and then use rename(2).
- */
- if (a->flags & ARCHIVE_EXTRACT_SAFE_WRITES)
- unlink(a->name);
-#ifdef HAVE_LINKAT
- r = linkat(AT_FDCWD, linkname, AT_FDCWD, a->name,
- 0) ? errno : 0;
-#else
- r = link(linkname, a->name) ? errno : 0;
-#endif
- /*
- * New cpio and pax formats allow hardlink entries
- * to carry data, so we may have to open the file
- * for hardlink entries.
- *
- * If the hardlink was successfully created and
- * the archive doesn't have carry data for it,
- * consider it to be non-authoritative for meta data.
- * This is consistent with GNU tar and BSD pax.
- * If the hardlink does carry data, let the last
- * archive entry decide ownership.
- */
- if (r == 0 && a->filesize <= 0) {
- a->todo = 0;
- a->deferred = 0;
- } else if (r == 0 && a->filesize > 0) {
-#ifdef HAVE_LSTAT
- r = lstat(a->name, &st);
-#else
- r = la_stat(a->name, &st);
-#endif
- if (r != 0)
- r = errno;
- else if ((st.st_mode & AE_IFMT) == AE_IFREG) {
- a->fd = open(a->name, O_WRONLY | O_TRUNC |
- O_BINARY | O_CLOEXEC | O_NOFOLLOW);
- __archive_ensure_cloexec_flag(a->fd);
- if (a->fd < 0)
- r = errno;
- }
- }
- return (r);
-#endif
- }
- linkname = archive_entry_symlink(a->entry);
- if (linkname != NULL) {
-#if HAVE_SYMLINK
- /*
- * Unlinking and linking here is really not atomic,
- * but doing it right, would require us to construct
- * an mktempsymlink() function, and then use rename(2).
- */
- if (a->flags & ARCHIVE_EXTRACT_SAFE_WRITES)
- unlink(a->name);
- return symlink(linkname, a->name) ? errno : 0;
-#else
- return (EPERM);
-#endif
- }
-
- /*
- * The remaining system calls all set permissions, so let's
- * try to take advantage of that to avoid an extra chmod()
- * call. (Recall that umask is set to zero right now!)
- */
-
- /* Mode we want for the final restored object (w/o file type bits). */
- final_mode = a->mode & 07777;
- /*
- * The mode that will actually be restored in this step. Note
- * that SUID, SGID, etc, require additional work to ensure
- * security, so we never restore them at this point.
- */
- mode = final_mode & 0777 & ~a->user_umask;
-
- /*
- * Always create writable such that [f]setxattr() works if we're not
- * root.
- */
- if (a->user_uid != 0 &&
- a->todo & (TODO_HFS_COMPRESSION | TODO_XATTR)) {
- mode |= 0200;
- }
-
- switch (a->mode & AE_IFMT) {
- default:
- /* POSIX requires that we fall through here. */
- /* FALLTHROUGH */
- case AE_IFREG:
- a->tmpname = NULL;
- a->fd = open(a->name,
- O_WRONLY | O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC, mode);
- __archive_ensure_cloexec_flag(a->fd);
- r = (a->fd < 0);
- break;
- case AE_IFCHR:
-#ifdef HAVE_MKNOD
- /* Note: we use AE_IFCHR for the case label, and
- * S_IFCHR for the mknod() call. This is correct. */
- r = mknod(a->name, mode | S_IFCHR,
- archive_entry_rdev(a->entry));
- break;
-#else
- /* TODO: Find a better way to warn about our inability
- * to restore a char device node. */
- return (EINVAL);
-#endif /* HAVE_MKNOD */
- case AE_IFBLK:
-#ifdef HAVE_MKNOD
- r = mknod(a->name, mode | S_IFBLK,
- archive_entry_rdev(a->entry));
- break;
-#else
- /* TODO: Find a better way to warn about our inability
- * to restore a block device node. */
- return (EINVAL);
-#endif /* HAVE_MKNOD */
- case AE_IFDIR:
- mode = (mode | MINIMUM_DIR_MODE) & MAXIMUM_DIR_MODE;
- r = mkdir(a->name, mode);
- if (r == 0) {
- /* Defer setting dir times. */
- a->deferred |= (a->todo & TODO_TIMES);
- a->todo &= ~TODO_TIMES;
- /* Never use an immediate chmod(). */
- /* We can't avoid the chmod() entirely if EXTRACT_PERM
- * because of SysV SGID inheritance. */
- if ((mode != final_mode)
- || (a->flags & ARCHIVE_EXTRACT_PERM))
- a->deferred |= (a->todo & TODO_MODE);
- a->todo &= ~TODO_MODE;
- }
- break;
- case AE_IFIFO:
-#ifdef HAVE_MKFIFO
- r = mkfifo(a->name, mode);
- break;
-#else
- /* TODO: Find a better way to warn about our inability
- * to restore a fifo. */
- return (EINVAL);
-#endif /* HAVE_MKFIFO */
- }
-
- /* All the system calls above set errno on failure. */
- if (r)
- return (errno);
-
- /* If we managed to set the final mode, we've avoided a chmod(). */
- if (mode == final_mode)
- a->todo &= ~TODO_MODE;
- return (0);
-}
-
-/*
- * Cleanup function for archive_extract. Mostly, this involves processing
- * the fixup list, which is used to address a number of problems:
- * * Dir permissions might prevent us from restoring a file in that
- * dir, so we restore the dir with minimum 0700 permissions first,
- * then correct the mode at the end.
- * * Similarly, the act of restoring a file touches the directory
- * and changes the timestamp on the dir, so we have to touch-up dir
- * timestamps at the end as well.
- * * Some file flags can interfere with the restore by, for example,
- * preventing the creation of hardlinks to those files.
- * * Mac OS extended metadata includes ACLs, so must be deferred on dirs.
- *
- * Note that tar/cpio do not require that archives be in a particular
- * order; there is no way to know when the last file has been restored
- * within a directory, so there's no way to optimize the memory usage
- * here by fixing up the directory any earlier than the
- * end-of-archive.
- *
- * XXX TODO: Directory ACLs should be restored here, for the same
- * reason we set directory perms here. XXX
- */
-static int
-_archive_write_disk_close(struct archive *_a)
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
- struct fixup_entry *next, *p;
- struct stat st;
- char *c;
- int fd, ret, openflags;
-
- archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
- "archive_write_disk_close");
- ret = _archive_write_disk_finish_entry(&a->archive);
-
- /* Sort dir list so directories are fixed up in depth-first order. */
- p = sort_dir_list(a->fixup_list);
-
- while (p != NULL) {
- fd = -1;
- a->pst = NULL; /* Mark stat cache as out-of-date. */
-
- /* We must strip trailing slashes from the path to avoid
- dereferencing symbolic links to directories */
- c = p->name;
- while (*c != '\0')
- c++;
- while (c != p->name && *(c - 1) == '/') {
- c--;
- *c = '\0';
- }
-
- if (p->fixup == 0)
- goto skip_fixup_entry;
- else {
- /*
- * We need to verify if the type of the file
- * we are going to open matches the file type
- * of the fixup entry.
- */
- openflags = O_BINARY | O_NOFOLLOW | O_RDONLY
- | O_CLOEXEC;
-#if defined(O_DIRECTORY)
- if (p->filetype == AE_IFDIR)
- openflags |= O_DIRECTORY;
-#endif
- fd = open(p->name, openflags);
-
-#if defined(O_DIRECTORY)
- /*
- * If we support O_DIRECTORY and open was
- * successful we can skip the file type check
- * for directories. For other file types
- * we need to verify via fstat() or lstat()
- */
- if (fd == -1 || p->filetype != AE_IFDIR) {
-#if HAVE_FSTAT
- if (fd > 0 && (
- fstat(fd, &st) != 0 ||
- la_verify_filetype(st.st_mode,
- p->filetype) == 0)) {
- goto skip_fixup_entry;
- } else
-#endif
- if (
-#ifdef HAVE_LSTAT
- lstat(p->name, &st) != 0 ||
-#else
- la_stat(p->name, &st) != 0 ||
-#endif
- la_verify_filetype(st.st_mode,
- p->filetype) == 0) {
- goto skip_fixup_entry;
- }
- }
-#else
-#if HAVE_FSTAT
- if (fd > 0 && (
- fstat(fd, &st) != 0 ||
- la_verify_filetype(st.st_mode,
- p->filetype) == 0)) {
- goto skip_fixup_entry;
- } else
-#endif
- if (
-#ifdef HAVE_LSTAT
- lstat(p->name, &st) != 0 ||
-#else
- la_stat(p->name, &st) != 0 ||
-#endif
- la_verify_filetype(st.st_mode,
- p->filetype) == 0) {
- goto skip_fixup_entry;
- }
-#endif
- }
- if (p->fixup & TODO_TIMES) {
- set_times(a, fd, p->mode, p->name,
- p->atime, p->atime_nanos,
- p->birthtime, p->birthtime_nanos,
- p->mtime, p->mtime_nanos,
- p->ctime, p->ctime_nanos);
- }
- if (p->fixup & TODO_MODE_BASE) {
-#ifdef HAVE_FCHMOD
- if (fd >= 0)
- fchmod(fd, p->mode & 07777);
- else
-#endif
-#ifdef HAVE_LCHMOD
- lchmod(p->name, p->mode & 07777);
-#else
- chmod(p->name, p->mode & 07777);
-#endif
- }
- if (p->fixup & TODO_ACLS)
- archive_write_disk_set_acls(&a->archive, fd,
- p->name, &p->acl, p->mode);
- if (p->fixup & TODO_FFLAGS)
- set_fflags_platform(a, fd, p->name,
- p->mode, p->fflags_set, 0);
- if (p->fixup & TODO_MAC_METADATA)
- set_mac_metadata(a, p->name, p->mac_metadata,
- p->mac_metadata_size);
-skip_fixup_entry:
- next = p->next;
- archive_acl_clear(&p->acl);
- free(p->mac_metadata);
- free(p->name);
- if (fd >= 0)
- close(fd);
- free(p);
- p = next;
- }
- a->fixup_list = NULL;
- return (ret);
-}
-
-static int
-_archive_write_disk_free(struct archive *_a)
-{
- struct archive_write_disk *a;
- int ret;
- if (_a == NULL)
- return (ARCHIVE_OK);
- archive_check_magic(_a, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_disk_free");
- a = (struct archive_write_disk *)_a;
- ret = _archive_write_disk_close(&a->archive);
- archive_write_disk_set_group_lookup(&a->archive, NULL, NULL, NULL);
- archive_write_disk_set_user_lookup(&a->archive, NULL, NULL, NULL);
- archive_entry_free(a->entry);
- archive_string_free(&a->_name_data);
- archive_string_free(&a->_tmpname_data);
- archive_string_free(&a->archive.error_string);
- archive_string_free(&a->path_safe);
- a->archive.magic = 0;
- __archive_clean(&a->archive);
- free(a->decmpfs_header_p);
- free(a->resource_fork);
- free(a->compressed_buffer);
- free(a->uncompressed_buffer);
-#if defined(__APPLE__) && defined(UF_COMPRESSED) && defined(HAVE_SYS_XATTR_H)\
- && defined(HAVE_ZLIB_H)
- if (a->stream_valid) {
- switch (deflateEnd(&a->stream)) {
- case Z_OK:
- break;
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Failed to clean up compressor");
- ret = ARCHIVE_FATAL;
- break;
- }
- }
-#endif
- free(a);
- return (ret);
-}
-
-/*
- * Simple O(n log n) merge sort to order the fixup list. In
- * particular, we want to restore dir timestamps depth-first.
- */
-static struct fixup_entry *
-sort_dir_list(struct fixup_entry *p)
-{
- struct fixup_entry *a, *b, *t;
-
- if (p == NULL)
- return (NULL);
- /* A one-item list is already sorted. */
- if (p->next == NULL)
- return (p);
-
- /* Step 1: split the list. */
- t = p;
- a = p->next->next;
- while (a != NULL) {
- /* Step a twice, t once. */
- a = a->next;
- if (a != NULL)
- a = a->next;
- t = t->next;
- }
- /* Now, t is at the mid-point, so break the list here. */
- b = t->next;
- t->next = NULL;
- a = p;
-
- /* Step 2: Recursively sort the two sub-lists. */
- a = sort_dir_list(a);
- b = sort_dir_list(b);
-
- /* Step 3: Merge the returned lists. */
- /* Pick the first element for the merged list. */
- if (strcmp(a->name, b->name) > 0) {
- t = p = a;
- a = a->next;
- } else {
- t = p = b;
- b = b->next;
- }
-
- /* Always put the later element on the list first. */
- while (a != NULL && b != NULL) {
- if (strcmp(a->name, b->name) > 0) {
- t->next = a;
- a = a->next;
- } else {
- t->next = b;
- b = b->next;
- }
- t = t->next;
- }
-
- /* Only one list is non-empty, so just splice it on. */
- if (a != NULL)
- t->next = a;
- if (b != NULL)
- t->next = b;
-
- return (p);
-}
-
-/*
- * Returns a new, initialized fixup entry.
- *
- * TODO: Reduce the memory requirements for this list by using a tree
- * structure rather than a simple list of names.
- */
-static struct fixup_entry *
-new_fixup(struct archive_write_disk *a, const char *pathname)
-{
- struct fixup_entry *fe;
-
- fe = (struct fixup_entry *)calloc(1, sizeof(struct fixup_entry));
- if (fe == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for a fixup");
- return (NULL);
- }
- fe->next = a->fixup_list;
- a->fixup_list = fe;
- fe->fixup = 0;
- fe->filetype = 0;
- fe->name = strdup(pathname);
- return (fe);
-}
-
-/*
- * Returns a fixup structure for the current entry.
- */
-static struct fixup_entry *
-current_fixup(struct archive_write_disk *a, const char *pathname)
-{
- if (a->current_fixup == NULL)
- a->current_fixup = new_fixup(a, pathname);
- return (a->current_fixup);
-}
-
-/* Error helper for new *_fsobj functions */
-static void
-fsobj_error(int *a_eno, struct archive_string *a_estr,
- int err, const char *errstr, const char *path)
-{
- if (a_eno)
- *a_eno = err;
- if (a_estr)
- archive_string_sprintf(a_estr, "%s%s", errstr, path);
-}
-
-/*
- * TODO: Someday, integrate this with the deep dir support; they both
- * scan the path and both can be optimized by comparing against other
- * recent paths.
- */
-/*
- * Checks the given path to see if any elements along it are symlinks. Returns
- * ARCHIVE_OK if there are none, otherwise puts an error in errmsg.
- */
-static int
-check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
- int flags, int checking_linkname)
-{
-#if !defined(HAVE_LSTAT) && \
- !(defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT))
- /* Platform doesn't have lstat, so we can't look for symlinks. */
- (void)path; /* UNUSED */
- (void)a_eno; /* UNUSED */
- (void)a_estr; /* UNUSED */
- (void)flags; /* UNUSED */
- (void)checking_linkname; /* UNUSED */
- return (ARCHIVE_OK);
-#else
- int res = ARCHIVE_OK;
- char *tail;
- char *head;
- int last;
- char c = '\0';
- int r;
- struct stat st;
- int chdir_fd;
-#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)
- int fd;
-#endif
-
- /* Nothing to do here if name is empty */
- if(path[0] == '\0')
- return (ARCHIVE_OK);
-
- /*
- * Guard against symlink tricks. Reject any archive entry whose
- * destination would be altered by a symlink.
- *
- * Walk the filename in chunks separated by '/'. For each segment:
- * - if it doesn't exist, continue
- * - if it's symlink, abort or remove it
- * - if it's a directory and it's not the last chunk, cd into it
- * As we go:
- * head points to the current (relative) path
- * tail points to the temporary \0 terminating the segment we're
- * currently examining
- * c holds what used to be in *tail
- * last is 1 if this is the last tail
- */
- chdir_fd = la_opendirat(AT_FDCWD, ".");
- __archive_ensure_cloexec_flag(chdir_fd);
- if (chdir_fd < 0) {
- fsobj_error(a_eno, a_estr, errno,
- "Could not open ", path);
- return (ARCHIVE_FATAL);
- }
- head = path;
- tail = path;
- last = 0;
- /* TODO: reintroduce a safe cache here? */
- /* Skip the root directory if the path is absolute. */
- if(tail == path && tail[0] == '/')
- ++tail;
- /* Keep going until we've checked the entire name.
- * head, tail, path all alias the same string, which is
- * temporarily zeroed at tail, so be careful restoring the
- * stashed (c=tail[0]) for error messages.
- * Exiting the loop with break is okay; continue is not.
- */
- while (!last) {
- /*
- * Skip the separator we just consumed, plus any adjacent ones
- */
- while (*tail == '/')
- ++tail;
- /* Skip the next path element. */
- while (*tail != '\0' && *tail != '/')
- ++tail;
- /* is this the last path component? */
- last = (tail[0] == '\0') || (tail[0] == '/' && tail[1] == '\0');
- /* temporarily truncate the string here */
- c = tail[0];
- tail[0] = '\0';
- /* Check that we haven't hit a symlink. */
-#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)
- r = fstatat(chdir_fd, head, &st, AT_SYMLINK_NOFOLLOW);
-#elif defined(HAVE_LSTAT)
- r = lstat(head, &st);
-#else
- r = la_stat(head, &st);
-#endif
- if (r != 0) {
- tail[0] = c;
- /* We've hit a dir that doesn't exist; stop now. */
- if (errno == ENOENT) {
- break;
- } else {
- /*
- * Treat any other error as fatal - best to be
- * paranoid here.
- * Note: This effectively disables deep
- * directory support when security checks are
- * enabled. Otherwise, very long pathnames that
- * trigger an error here could evade the
- * sandbox.
- * TODO: We could do better, but it would
- * probably require merging the symlink checks
- * with the deep-directory editing.
- */
- fsobj_error(a_eno, a_estr, errno,
- "Could not stat ", path);
- res = ARCHIVE_FAILED;
- break;
- }
- } else if (S_ISDIR(st.st_mode)) {
- if (!last) {
-#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)
- fd = la_opendirat(chdir_fd, head);
- if (fd < 0)
- r = -1;
- else {
- r = 0;
- close(chdir_fd);
- chdir_fd = fd;
- }
-#else
- r = chdir(head);
-#endif
- if (r != 0) {
- tail[0] = c;
- fsobj_error(a_eno, a_estr, errno,
- "Could not chdir ", path);
- res = (ARCHIVE_FATAL);
- break;
- }
- /* Our view is now from inside this dir: */
- head = tail + 1;
- }
- } else if (S_ISLNK(st.st_mode)) {
- if (last && checking_linkname) {
-#ifdef HAVE_LINKAT
- /*
- * Hardlinks to symlinks are safe to write
- * if linkat() is supported as it does not
- * follow symlinks.
- */
- res = ARCHIVE_OK;
-#else
- /*
- * We return ARCHIVE_FAILED here as we are
- * not able to safely write hardlinks
- * to symlinks.
- */
- tail[0] = c;
- fsobj_error(a_eno, a_estr, errno,
- "Cannot write hardlink to symlink ",
- path);
- res = ARCHIVE_FAILED;
-#endif
- break;
- } else
- if (last) {
- /*
- * Last element is symlink; remove it
- * so we can overwrite it with the
- * item being extracted.
- */
-#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)
- r = unlinkat(chdir_fd, head, 0);
-#else
- r = unlink(head);
-#endif
- if (r != 0) {
- tail[0] = c;
- fsobj_error(a_eno, a_estr, errno,
- "Could not remove symlink ",
- path);
- res = ARCHIVE_FAILED;
- break;
- }
- /*
- * Even if we did remove it, a warning
- * is in order. The warning is silly,
- * though, if we're just replacing one
- * symlink with another symlink.
- */
- tail[0] = c;
- /*
- * FIXME: not sure how important this is to
- * restore
- */
- /*
- if (!S_ISLNK(path)) {
- fsobj_error(a_eno, a_estr, 0,
- "Removing symlink ", path);
- }
- */
- /* Symlink gone. No more problem! */
- res = ARCHIVE_OK;
- break;
- } else if (flags & ARCHIVE_EXTRACT_UNLINK) {
- /* User asked us to remove problems. */
-#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)
- r = unlinkat(chdir_fd, head, 0);
-#else
- r = unlink(head);
-#endif
- if (r != 0) {
- tail[0] = c;
- fsobj_error(a_eno, a_estr, 0,
- "Cannot remove intervening "
- "symlink ", path);
- res = ARCHIVE_FAILED;
- break;
- }
- tail[0] = c;
- } else if ((flags &
- ARCHIVE_EXTRACT_SECURE_SYMLINKS) == 0) {
- /*
- * We are not the last element and we want to
- * follow symlinks if they are a directory.
- *
- * This is needed to extract hardlinks over
- * symlinks.
- */
-#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)
- r = fstatat(chdir_fd, head, &st, 0);
-#else
- r = la_stat(head, &st);
-#endif
- if (r != 0) {
- tail[0] = c;
- if (errno == ENOENT) {
- break;
- } else {
- fsobj_error(a_eno, a_estr,
- errno,
- "Could not stat ", path);
- res = (ARCHIVE_FAILED);
- break;
- }
- } else if (S_ISDIR(st.st_mode)) {
-#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)
- fd = la_opendirat(chdir_fd, head);
- if (fd < 0)
- r = -1;
- else {
- r = 0;
- close(chdir_fd);
- chdir_fd = fd;
- }
-#else
- r = chdir(head);
-#endif
- if (r != 0) {
- tail[0] = c;
- fsobj_error(a_eno, a_estr,
- errno,
- "Could not chdir ", path);
- res = (ARCHIVE_FATAL);
- break;
- }
- /*
- * Our view is now from inside
- * this dir:
- */
- head = tail + 1;
- } else {
- tail[0] = c;
- fsobj_error(a_eno, a_estr, 0,
- "Cannot extract through "
- "symlink ", path);
- res = ARCHIVE_FAILED;
- break;
- }
- } else {
- tail[0] = c;
- fsobj_error(a_eno, a_estr, 0,
- "Cannot extract through symlink ", path);
- res = ARCHIVE_FAILED;
- break;
- }
- }
- /* be sure to always maintain this */
- tail[0] = c;
- if (tail[0] != '\0')
- tail++; /* Advance to the next segment. */
- }
- /* Catches loop exits via break */
- tail[0] = c;
-#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)
- /* If we operate with openat(), fstatat() and unlinkat() there was
- * no chdir(), so just close the fd */
- if (chdir_fd >= 0)
- close(chdir_fd);
-#elif HAVE_FCHDIR
- /* If we changed directory above, restore it here. */
- if (chdir_fd >= 0) {
- r = fchdir(chdir_fd);
- if (r != 0) {
- fsobj_error(a_eno, a_estr, errno,
- "chdir() failure", "");
- }
- close(chdir_fd);
- chdir_fd = -1;
- if (r != 0) {
- res = (ARCHIVE_FATAL);
- }
- }
-#endif
- /* TODO: reintroduce a safe cache here? */
- return res;
-#endif
-}
-
-/*
- * Check a->name for symlinks, returning ARCHIVE_OK if its clean, otherwise
- * calls archive_set_error and returns ARCHIVE_{FATAL,FAILED}
- */
-static int
-check_symlinks(struct archive_write_disk *a)
-{
- struct archive_string error_string;
- int error_number;
- int rc;
- archive_string_init(&error_string);
- rc = check_symlinks_fsobj(a->name, &error_number, &error_string,
- a->flags, 0);
- if (rc != ARCHIVE_OK) {
- archive_set_error(&a->archive, error_number, "%s",
- error_string.s);
- }
- archive_string_free(&error_string);
- a->pst = NULL; /* to be safe */
- return rc;
-}
-
-
-#if defined(__CYGWIN__)
-/*
- * 1. Convert a path separator from '\' to '/' .
- * We shouldn't check multibyte character directly because some
- * character-set have been using the '\' character for a part of
- * its multibyte character code.
- * 2. Replace unusable characters in Windows with underscore('_').
- * See also : http://msdn.microsoft.com/en-us/library/aa365247.aspx
- */
-static void
-cleanup_pathname_win(char *path)
-{
- wchar_t wc;
- char *p;
- size_t alen, l;
- int mb, complete, utf8;
-
- alen = 0;
- mb = 0;
- complete = 1;
- utf8 = (strcmp(nl_langinfo(CODESET), "UTF-8") == 0)? 1: 0;
- for (p = path; *p != '\0'; p++) {
- ++alen;
- if (*p == '\\') {
- /* If previous byte is smaller than 128,
- * this is not second byte of multibyte characters,
- * so we can replace '\' with '/'. */
- if (utf8 || !mb)
- *p = '/';
- else
- complete = 0;/* uncompleted. */
- } else if (*(unsigned char *)p > 127)
- mb = 1;
- else
- mb = 0;
- /* Rewrite the path name if its next character is unusable. */
- if (*p == ':' || *p == '*' || *p == '?' || *p == '"' ||
- *p == '<' || *p == '>' || *p == '|')
- *p = '_';
- }
- if (complete)
- return;
-
- /*
- * Convert path separator in wide-character.
- */
- p = path;
- while (*p != '\0' && alen) {
- l = mbtowc(&wc, p, alen);
- if (l == (size_t)-1) {
- while (*p != '\0') {
- if (*p == '\\')
- *p = '/';
- ++p;
- }
- break;
- }
- if (l == 1 && wc == L'\\')
- *p = '/';
- p += l;
- alen -= l;
- }
-}
-#endif
-
-/*
- * Canonicalize the pathname. In particular, this strips duplicate
- * '/' characters, '.' elements, and trailing '/'. It also raises an
- * error for an empty path, a trailing '..', (if _SECURE_NODOTDOT is
- * set) any '..' in the path or (if ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS
- * is set) if the path is absolute.
- */
-static int
-cleanup_pathname_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
- int flags)
-{
- char *dest, *src;
- char separator = '\0';
-
- dest = src = path;
- if (*src == '\0') {
- fsobj_error(a_eno, a_estr, ARCHIVE_ERRNO_MISC,
- "Invalid empty ", "pathname");
- return (ARCHIVE_FAILED);
- }
-
-#if defined(__CYGWIN__)
- cleanup_pathname_win(path);
-#endif
- /* Skip leading '/'. */
- if (*src == '/') {
- if (flags & ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS) {
- fsobj_error(a_eno, a_estr, ARCHIVE_ERRNO_MISC,
- "Path is ", "absolute");
- return (ARCHIVE_FAILED);
- }
-
- separator = *src++;
- }
-
- /* Scan the pathname one element at a time. */
- for (;;) {
- /* src points to first char after '/' */
- if (src[0] == '\0') {
- break;
- } else if (src[0] == '/') {
- /* Found '//', ignore second one. */
- src++;
- continue;
- } else if (src[0] == '.') {
- if (src[1] == '\0') {
- /* Ignore trailing '.' */
- break;
- } else if (src[1] == '/') {
- /* Skip './'. */
- src += 2;
- continue;
- } else if (src[1] == '.') {
- if (src[2] == '/' || src[2] == '\0') {
- /* Conditionally warn about '..' */
- if (flags
- & ARCHIVE_EXTRACT_SECURE_NODOTDOT) {
- fsobj_error(a_eno, a_estr,
- ARCHIVE_ERRNO_MISC,
- "Path contains ", "'..'");
- return (ARCHIVE_FAILED);
- }
- }
- /*
- * Note: Under no circumstances do we
- * remove '..' elements. In
- * particular, restoring
- * '/foo/../bar/' should create the
- * 'foo' dir as a side-effect.
- */
- }
- }
-
- /* Copy current element, including leading '/'. */
- if (separator)
- *dest++ = '/';
- while (*src != '\0' && *src != '/') {
- *dest++ = *src++;
- }
-
- if (*src == '\0')
- break;
-
- /* Skip '/' separator. */
- separator = *src++;
- }
- /*
- * We've just copied zero or more path elements, not including the
- * final '/'.
- */
- if (dest == path) {
- /*
- * Nothing got copied. The path must have been something
- * like '.' or '/' or './' or '/././././/./'.
- */
- if (separator)
- *dest++ = '/';
- else
- *dest++ = '.';
- }
- /* Terminate the result. */
- *dest = '\0';
- return (ARCHIVE_OK);
-}
-
-static int
-cleanup_pathname(struct archive_write_disk *a)
-{
- struct archive_string error_string;
- int error_number;
- int rc;
- archive_string_init(&error_string);
- rc = cleanup_pathname_fsobj(a->name, &error_number, &error_string,
- a->flags);
- if (rc != ARCHIVE_OK) {
- archive_set_error(&a->archive, error_number, "%s",
- error_string.s);
- }
- archive_string_free(&error_string);
- return rc;
-}
-
-/*
- * Create the parent directory of the specified path, assuming path
- * is already in mutable storage.
- */
-static int
-create_parent_dir(struct archive_write_disk *a, char *path)
-{
- char *slash;
- int r;
-
- /* Remove tail element to obtain parent name. */
- slash = strrchr(path, '/');
- if (slash == NULL)
- return (ARCHIVE_OK);
- *slash = '\0';
- r = create_dir(a, path);
- *slash = '/';
- return (r);
-}
-
-/*
- * Create the specified dir, recursing to create parents as necessary.
- *
- * Returns ARCHIVE_OK if the path exists when we're done here.
- * Otherwise, returns ARCHIVE_FAILED.
- * Assumes path is in mutable storage; path is unchanged on exit.
- */
-static int
-create_dir(struct archive_write_disk *a, char *path)
-{
- struct stat st;
- struct fixup_entry *le;
- char *slash, *base;
- mode_t mode_final, mode;
- int r;
-
- /* Check for special names and just skip them. */
- slash = strrchr(path, '/');
- if (slash == NULL)
- base = path;
- else
- base = slash + 1;
-
- if (base[0] == '\0' ||
- (base[0] == '.' && base[1] == '\0') ||
- (base[0] == '.' && base[1] == '.' && base[2] == '\0')) {
- /* Don't bother trying to create null path, '.', or '..'. */
- if (slash != NULL) {
- *slash = '\0';
- r = create_dir(a, path);
- *slash = '/';
- return (r);
- }
- return (ARCHIVE_OK);
- }
-
- /*
- * Yes, this should be stat() and not lstat(). Using lstat()
- * here loses the ability to extract through symlinks. Also note
- * that this should not use the a->st cache.
- */
- if (la_stat(path, &st) == 0) {
- if (S_ISDIR(st.st_mode))
- return (ARCHIVE_OK);
- if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
- archive_set_error(&a->archive, EEXIST,
- "Can't create directory '%s'", path);
- return (ARCHIVE_FAILED);
- }
- if (unlink(path) != 0) {
- archive_set_error(&a->archive, errno,
- "Can't create directory '%s': "
- "Conflicting file cannot be removed",
- path);
- return (ARCHIVE_FAILED);
- }
- } else if (errno != ENOENT && errno != ENOTDIR) {
- /* Stat failed? */
- archive_set_error(&a->archive, errno,
- "Can't test directory '%s'", path);
- return (ARCHIVE_FAILED);
- } else if (slash != NULL) {
- *slash = '\0';
- r = create_dir(a, path);
- *slash = '/';
- if (r != ARCHIVE_OK)
- return (r);
- }
-
- /*
- * Mode we want for the final restored directory. Per POSIX,
- * implicitly-created dirs must be created obeying the umask.
- * There's no mention whether this is different for privileged
- * restores (which the rest of this code handles by pretending
- * umask=0). I've chosen here to always obey the user's umask for
- * implicit dirs, even if _EXTRACT_PERM was specified.
- */
- mode_final = DEFAULT_DIR_MODE & ~a->user_umask;
- /* Mode we want on disk during the restore process. */
- mode = mode_final;
- mode |= MINIMUM_DIR_MODE;
- mode &= MAXIMUM_DIR_MODE;
- if (mkdir(path, mode) == 0) {
- if (mode != mode_final) {
- le = new_fixup(a, path);
- if (le == NULL)
- return (ARCHIVE_FATAL);
- le->fixup |=TODO_MODE_BASE;
- le->mode = mode_final;
- }
- return (ARCHIVE_OK);
- }
-
- /*
- * Without the following check, a/b/../b/c/d fails at the
- * second visit to 'b', so 'd' can't be created. Note that we
- * don't add it to the fixup list here, as it's already been
- * added.
- */
- if (la_stat(path, &st) == 0 && S_ISDIR(st.st_mode))
- return (ARCHIVE_OK);
-
- archive_set_error(&a->archive, errno, "Failed to create dir '%s'",
- path);
- return (ARCHIVE_FAILED);
-}
-
-/*
- * Note: Although we can skip setting the user id if the desired user
- * id matches the current user, we cannot skip setting the group, as
- * many systems set the gid based on the containing directory. So
- * we have to perform a chown syscall if we want to set the SGID
- * bit. (The alternative is to stat() and then possibly chown(); it's
- * more efficient to skip the stat() and just always chown().) Note
- * that a successful chown() here clears the TODO_SGID_CHECK bit, which
- * allows set_mode to skip the stat() check for the GID.
- */
-static int
-set_ownership(struct archive_write_disk *a)
-{
-#if !defined(__CYGWIN__) && !defined(__linux__)
-/*
- * On Linux, a process may have the CAP_CHOWN capability.
- * On Windows there is no 'root' user with uid 0.
- * Elsewhere we can skip calling chown if we are not root and the desired
- * user id does not match the current user.
- */
- if (a->user_uid != 0 && a->user_uid != a->uid) {
- archive_set_error(&a->archive, errno,
- "Can't set UID=%jd", (intmax_t)a->uid);
- return (ARCHIVE_WARN);
- }
-#endif
-
-#ifdef HAVE_FCHOWN
- /* If we have an fd, we can avoid a race. */
- if (a->fd >= 0 && fchown(a->fd, a->uid, a->gid) == 0) {
- /* We've set owner and know uid/gid are correct. */
- a->todo &= ~(TODO_OWNER | TODO_SGID_CHECK | TODO_SUID_CHECK);
- return (ARCHIVE_OK);
- }
-#endif
-
- /* We prefer lchown() but will use chown() if that's all we have. */
- /* Of course, if we have neither, this will always fail. */
-#ifdef HAVE_LCHOWN
- if (lchown(a->name, a->uid, a->gid) == 0) {
- /* We've set owner and know uid/gid are correct. */
- a->todo &= ~(TODO_OWNER | TODO_SGID_CHECK | TODO_SUID_CHECK);
- return (ARCHIVE_OK);
- }
-#elif HAVE_CHOWN
- if (!S_ISLNK(a->mode) && chown(a->name, a->uid, a->gid) == 0) {
- /* We've set owner and know uid/gid are correct. */
- a->todo &= ~(TODO_OWNER | TODO_SGID_CHECK | TODO_SUID_CHECK);
- return (ARCHIVE_OK);
- }
-#endif
-
- archive_set_error(&a->archive, errno,
- "Can't set user=%jd/group=%jd for %s",
- (intmax_t)a->uid, (intmax_t)a->gid, a->name);
- return (ARCHIVE_WARN);
-}
-
-/*
- * Note: Returns 0 on success, non-zero on failure.
- */
-static int
-set_time(int fd, int mode, const char *name,
- time_t atime, long atime_nsec,
- time_t mtime, long mtime_nsec)
-{
- /* Select the best implementation for this platform. */
-#if defined(HAVE_UTIMENSAT) && defined(HAVE_FUTIMENS)
- /*
- * utimensat() and futimens() are defined in
- * POSIX.1-2008. They support ns resolution and setting times
- * on fds and symlinks.
- */
- struct timespec ts[2];
- (void)mode; /* UNUSED */
- ts[0].tv_sec = atime;
- ts[0].tv_nsec = atime_nsec;
- ts[1].tv_sec = mtime;
- ts[1].tv_nsec = mtime_nsec;
- if (fd >= 0)
- return futimens(fd, ts);
- return utimensat(AT_FDCWD, name, ts, AT_SYMLINK_NOFOLLOW);
-
-#elif HAVE_UTIMES
- /*
- * The utimes()-family functions support µs-resolution and
- * setting times fds and symlinks. utimes() is documented as
- * LEGACY by POSIX, futimes() and lutimes() are not described
- * in POSIX.
- */
- struct timeval times[2];
-
- times[0].tv_sec = atime;
- times[0].tv_usec = atime_nsec / 1000;
- times[1].tv_sec = mtime;
- times[1].tv_usec = mtime_nsec / 1000;
-
-#ifdef HAVE_FUTIMES
- if (fd >= 0)
- return (futimes(fd, times));
-#else
- (void)fd; /* UNUSED */
-#endif
-#ifdef HAVE_LUTIMES
- (void)mode; /* UNUSED */
- return (lutimes(name, times));
-#else
- if (S_ISLNK(mode))
- return (0);
- return (utimes(name, times));
-#endif
-
-#elif defined(HAVE_UTIME)
- /*
- * utime() is POSIX-standard but only supports 1s resolution and
- * does not support fds or symlinks.
- */
- struct utimbuf times;
- (void)fd; /* UNUSED */
- (void)name; /* UNUSED */
- (void)atime_nsec; /* UNUSED */
- (void)mtime_nsec; /* UNUSED */
- times.actime = atime;
- times.modtime = mtime;
- if (S_ISLNK(mode))
- return (ARCHIVE_OK);
- return (utime(name, &times));
-
-#else
- /*
- * We don't know how to set the time on this platform.
- */
- (void)fd; /* UNUSED */
- (void)mode; /* UNUSED */
- (void)name; /* UNUSED */
- (void)atime; /* UNUSED */
- (void)atime_nsec; /* UNUSED */
- (void)mtime; /* UNUSED */
- (void)mtime_nsec; /* UNUSED */
- return (ARCHIVE_WARN);
-#endif
-}
-
-#ifdef F_SETTIMES
-static int
-set_time_tru64(int fd, int mode, const char *name,
- time_t atime, long atime_nsec,
- time_t mtime, long mtime_nsec,
- time_t ctime, long ctime_nsec)
-{
- struct attr_timbuf tstamp;
- tstamp.atime.tv_sec = atime;
- tstamp.mtime.tv_sec = mtime;
- tstamp.ctime.tv_sec = ctime;
-#if defined (__hpux) && defined (__ia64)
- tstamp.atime.tv_nsec = atime_nsec;
- tstamp.mtime.tv_nsec = mtime_nsec;
- tstamp.ctime.tv_nsec = ctime_nsec;
-#else
- tstamp.atime.tv_usec = atime_nsec / 1000;
- tstamp.mtime.tv_usec = mtime_nsec / 1000;
- tstamp.ctime.tv_usec = ctime_nsec / 1000;
-#endif
- return (fcntl(fd,F_SETTIMES,&tstamp));
-}
-#endif /* F_SETTIMES */
-
-static int
-set_times(struct archive_write_disk *a,
- int fd, int mode, const char *name,
- time_t atime, long atime_nanos,
- time_t birthtime, long birthtime_nanos,
- time_t mtime, long mtime_nanos,
- time_t cctime, long ctime_nanos)
-{
- /* Note: set_time doesn't use libarchive return conventions!
- * It uses syscall conventions. So 0 here instead of ARCHIVE_OK. */
- int r1 = 0, r2 = 0;
-
-#ifdef F_SETTIMES
- /*
- * on Tru64 try own fcntl first which can restore even the
- * ctime, fall back to default code path below if it fails
- * or if we are not running as root
- */
- if (a->user_uid == 0 &&
- set_time_tru64(fd, mode, name,
- atime, atime_nanos, mtime,
- mtime_nanos, cctime, ctime_nanos) == 0) {
- return (ARCHIVE_OK);
- }
-#else /* Tru64 */
- (void)cctime; /* UNUSED */
- (void)ctime_nanos; /* UNUSED */
-#endif /* Tru64 */
-
-#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
- /*
- * If you have struct stat.st_birthtime, we assume BSD
- * birthtime semantics, in which {f,l,}utimes() updates
- * birthtime to earliest mtime. So we set the time twice,
- * first using the birthtime, then using the mtime. If
- * birthtime == mtime, this isn't necessary, so we skip it.
- * If birthtime > mtime, then this won't work, so we skip it.
- */
- if (birthtime < mtime
- || (birthtime == mtime && birthtime_nanos < mtime_nanos))
- r1 = set_time(fd, mode, name,
- atime, atime_nanos,
- birthtime, birthtime_nanos);
-#else
- (void)birthtime; /* UNUSED */
- (void)birthtime_nanos; /* UNUSED */
-#endif
- r2 = set_time(fd, mode, name,
- atime, atime_nanos,
- mtime, mtime_nanos);
- if (r1 != 0 || r2 != 0) {
- archive_set_error(&a->archive, errno,
- "Can't restore time");
- return (ARCHIVE_WARN);
- }
- return (ARCHIVE_OK);
-}
-
-static int
-set_times_from_entry(struct archive_write_disk *a)
-{
- time_t atime, birthtime, mtime, cctime;
- long atime_nsec, birthtime_nsec, mtime_nsec, ctime_nsec;
-
- /* Suitable defaults. */
- atime = birthtime = mtime = cctime = a->start_time;
- atime_nsec = birthtime_nsec = mtime_nsec = ctime_nsec = 0;
-
- /* If no time was provided, we're done. */
- if (!archive_entry_atime_is_set(a->entry)
-#if HAVE_STRUCT_STAT_ST_BIRTHTIME
- && !archive_entry_birthtime_is_set(a->entry)
-#endif
- && !archive_entry_mtime_is_set(a->entry))
- return (ARCHIVE_OK);
-
- if (archive_entry_atime_is_set(a->entry)) {
- atime = archive_entry_atime(a->entry);
- atime_nsec = archive_entry_atime_nsec(a->entry);
- }
- if (archive_entry_birthtime_is_set(a->entry)) {
- birthtime = archive_entry_birthtime(a->entry);
- birthtime_nsec = archive_entry_birthtime_nsec(a->entry);
- }
- if (archive_entry_mtime_is_set(a->entry)) {
- mtime = archive_entry_mtime(a->entry);
- mtime_nsec = archive_entry_mtime_nsec(a->entry);
- }
- if (archive_entry_ctime_is_set(a->entry)) {
- cctime = archive_entry_ctime(a->entry);
- ctime_nsec = archive_entry_ctime_nsec(a->entry);
- }
-
- return set_times(a, a->fd, a->mode, a->name,
- atime, atime_nsec,
- birthtime, birthtime_nsec,
- mtime, mtime_nsec,
- cctime, ctime_nsec);
-}
-
-static int
-set_mode(struct archive_write_disk *a, int mode)
-{
- int r = ARCHIVE_OK;
- int r2;
- mode &= 07777; /* Strip off file type bits. */
-
- if (a->todo & TODO_SGID_CHECK) {
- /*
- * If we don't know the GID is right, we must stat()
- * to verify it. We can't just check the GID of this
- * process, since systems sometimes set GID from
- * the enclosing dir or based on ACLs.
- */
- if ((r = lazy_stat(a)) != ARCHIVE_OK)
- return (r);
- if (a->pst->st_gid != a->gid) {
- mode &= ~ S_ISGID;
- if (a->flags & ARCHIVE_EXTRACT_OWNER) {
- /*
- * This is only an error if you
- * requested owner restore. If you
- * didn't, we'll try to restore
- * sgid/suid, but won't consider it a
- * problem if we can't.
- */
- archive_set_error(&a->archive, -1,
- "Can't restore SGID bit");
- r = ARCHIVE_WARN;
- }
- }
- /* While we're here, double-check the UID. */
- if (a->pst->st_uid != a->uid
- && (a->todo & TODO_SUID)) {
- mode &= ~ S_ISUID;
- if (a->flags & ARCHIVE_EXTRACT_OWNER) {
- archive_set_error(&a->archive, -1,
- "Can't restore SUID bit");
- r = ARCHIVE_WARN;
- }
- }
- a->todo &= ~TODO_SGID_CHECK;
- a->todo &= ~TODO_SUID_CHECK;
- } else if (a->todo & TODO_SUID_CHECK) {
- /*
- * If we don't know the UID is right, we can just check
- * the user, since all systems set the file UID from
- * the process UID.
- */
- if (a->user_uid != a->uid) {
- mode &= ~ S_ISUID;
- if (a->flags & ARCHIVE_EXTRACT_OWNER) {
- archive_set_error(&a->archive, -1,
- "Can't make file SUID");
- r = ARCHIVE_WARN;
- }
- }
- a->todo &= ~TODO_SUID_CHECK;
- }
-
- if (S_ISLNK(a->mode)) {
-#ifdef HAVE_LCHMOD
- /*
- * If this is a symlink, use lchmod(). If the
- * platform doesn't support lchmod(), just skip it. A
- * platform that doesn't provide a way to set
- * permissions on symlinks probably ignores
- * permissions on symlinks, so a failure here has no
- * impact.
- */
- if (lchmod(a->name, mode) != 0) {
- switch (errno) {
- case ENOTSUP:
- case ENOSYS:
-#if ENOTSUP != EOPNOTSUPP
- case EOPNOTSUPP:
-#endif
- /*
- * if lchmod is defined but the platform
- * doesn't support it, silently ignore
- * error
- */
- break;
- default:
- archive_set_error(&a->archive, errno,
- "Can't set permissions to 0%o", (int)mode);
- r = ARCHIVE_WARN;
- }
- }
-#endif
- } else if (!S_ISDIR(a->mode)) {
- /*
- * If it's not a symlink and not a dir, then use
- * fchmod() or chmod(), depending on whether we have
- * an fd. Dirs get their perms set during the
- * post-extract fixup, which is handled elsewhere.
- */
-#ifdef HAVE_FCHMOD
- if (a->fd >= 0)
- r2 = fchmod(a->fd, mode);
- else
-#endif
- /* If this platform lacks fchmod(), then
- * we'll just use chmod(). */
- r2 = chmod(a->name, mode);
-
- if (r2 != 0) {
- archive_set_error(&a->archive, errno,
- "Can't set permissions to 0%o", (int)mode);
- r = ARCHIVE_WARN;
- }
- }
- return (r);
-}
-
-static int
-set_fflags(struct archive_write_disk *a)
-{
- struct fixup_entry *le;
- unsigned long set, clear;
- int r;
- mode_t mode = archive_entry_mode(a->entry);
- /*
- * Make 'critical_flags' hold all file flags that can't be
- * immediately restored. For example, on BSD systems,
- * SF_IMMUTABLE prevents hardlinks from being created, so
- * should not be set until after any hardlinks are created. To
- * preserve some semblance of portability, this uses #ifdef
- * extensively. Ugly, but it works.
- *
- * Yes, Virginia, this does create a security race. It's mitigated
- * somewhat by the practice of creating dirs 0700 until the extract
- * is done, but it would be nice if we could do more than that.
- * People restoring critical file systems should be wary of
- * other programs that might try to muck with files as they're
- * being restored.
- */
- const int critical_flags = 0
-#ifdef SF_IMMUTABLE
- | SF_IMMUTABLE
-#endif
-#ifdef UF_IMMUTABLE
- | UF_IMMUTABLE
-#endif
-#ifdef SF_APPEND
- | SF_APPEND
-#endif
-#ifdef UF_APPEND
- | UF_APPEND
-#endif
-#if defined(FS_APPEND_FL)
- | FS_APPEND_FL
-#elif defined(EXT2_APPEND_FL)
- | EXT2_APPEND_FL
-#endif
-#if defined(FS_IMMUTABLE_FL)
- | FS_IMMUTABLE_FL
-#elif defined(EXT2_IMMUTABLE_FL)
- | EXT2_IMMUTABLE_FL
-#endif
-#ifdef FS_JOURNAL_DATA_FL
- | FS_JOURNAL_DATA_FL
-#endif
- ;
-
- if (a->todo & TODO_FFLAGS) {
- archive_entry_fflags(a->entry, &set, &clear);
-
- /*
- * The first test encourages the compiler to eliminate
- * all of this if it's not necessary.
- */
- if ((critical_flags != 0) && (set & critical_flags)) {
- le = current_fixup(a, a->name);
- if (le == NULL)
- return (ARCHIVE_FATAL);
- le->filetype = archive_entry_filetype(a->entry);
- le->fixup |= TODO_FFLAGS;
- le->fflags_set = set;
- /* Store the mode if it's not already there. */
- if ((le->fixup & TODO_MODE) == 0)
- le->mode = mode;
- } else {
- r = set_fflags_platform(a, a->fd,
- a->name, mode, set, clear);
- if (r != ARCHIVE_OK)
- return (r);
- }
- }
- return (ARCHIVE_OK);
-}
-
-static int
-clear_nochange_fflags(struct archive_write_disk *a)
-{
- mode_t mode = archive_entry_mode(a->entry);
- const int nochange_flags = 0
-#ifdef SF_IMMUTABLE
- | SF_IMMUTABLE
-#endif
-#ifdef UF_IMMUTABLE
- | UF_IMMUTABLE
-#endif
-#ifdef SF_APPEND
- | SF_APPEND
-#endif
-#ifdef UF_APPEND
- | UF_APPEND
-#endif
-#ifdef EXT2_APPEND_FL
- | EXT2_APPEND_FL
-#endif
-#ifdef EXT2_IMMUTABLE_FL
- | EXT2_IMMUTABLE_FL
-#endif
- ;
-
- return (set_fflags_platform(a, a->fd, a->name, mode, 0,
- nochange_flags));
-}
-
-
-#if ( defined(HAVE_LCHFLAGS) || defined(HAVE_CHFLAGS) || defined(HAVE_FCHFLAGS) ) && defined(HAVE_STRUCT_STAT_ST_FLAGS)
-/*
- * BSD reads flags using stat() and sets them with one of {f,l,}chflags()
- */
-static int
-set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
- mode_t mode, unsigned long set, unsigned long clear)
-{
- int r;
- const int sf_mask = 0
-#ifdef SF_APPEND
- | SF_APPEND
-#endif
-#ifdef SF_ARCHIVED
- | SF_ARCHIVED
-#endif
-#ifdef SF_IMMUTABLE
- | SF_IMMUTABLE
-#endif
-#ifdef SF_NOUNLINK
- | SF_NOUNLINK
-#endif
- ;
- (void)mode; /* UNUSED */
-
- if (set == 0 && clear == 0)
- return (ARCHIVE_OK);
-
- /*
- * XXX Is the stat here really necessary? Or can I just use
- * the 'set' flags directly? In particular, I'm not sure
- * about the correct approach if we're overwriting an existing
- * file that already has flags on it. XXX
- */
- if ((r = lazy_stat(a)) != ARCHIVE_OK)
- return (r);
-
- a->st.st_flags &= ~clear;
- a->st.st_flags |= set;
-
- /* Only super-user may change SF_* flags */
-
- if (a->user_uid != 0)
- a->st.st_flags &= ~sf_mask;
-
-#ifdef HAVE_FCHFLAGS
- /* If platform has fchflags() and we were given an fd, use it. */
- if (fd >= 0 && fchflags(fd, a->st.st_flags) == 0)
- return (ARCHIVE_OK);
-#endif
- /*
- * If we can't use the fd to set the flags, we'll use the
- * pathname to set flags. We prefer lchflags() but will use
- * chflags() if we must.
- */
-#ifdef HAVE_LCHFLAGS
- if (lchflags(name, a->st.st_flags) == 0)
- return (ARCHIVE_OK);
-#elif defined(HAVE_CHFLAGS)
- if (S_ISLNK(a->st.st_mode)) {
- archive_set_error(&a->archive, errno,
- "Can't set file flags on symlink.");
- return (ARCHIVE_WARN);
- }
- if (chflags(name, a->st.st_flags) == 0)
- return (ARCHIVE_OK);
-#endif
- archive_set_error(&a->archive, errno,
- "Failed to set file flags");
- return (ARCHIVE_WARN);
-}
-
-#elif (defined(FS_IOC_GETFLAGS) && defined(FS_IOC_SETFLAGS) && \
- defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \
- (defined(EXT2_IOC_GETFLAGS) && defined(EXT2_IOC_SETFLAGS) && \
- defined(HAVE_WORKING_EXT2_IOC_GETFLAGS))
-/*
- * Linux uses ioctl() to read and write file flags.
- */
-static int
-set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
- mode_t mode, unsigned long set, unsigned long clear)
-{
- int ret;
- int myfd = fd;
- int newflags, oldflags;
- /*
- * Linux has no define for the flags that are only settable by
- * the root user. This code may seem a little complex, but
- * there seem to be some Linux systems that lack these
- * defines. (?) The code below degrades reasonably gracefully
- * if sf_mask is incomplete.
- */
- const int sf_mask = 0
-#if defined(FS_IMMUTABLE_FL)
- | FS_IMMUTABLE_FL
-#elif defined(EXT2_IMMUTABLE_FL)
- | EXT2_IMMUTABLE_FL
-#endif
-#if defined(FS_APPEND_FL)
- | FS_APPEND_FL
-#elif defined(EXT2_APPEND_FL)
- | EXT2_APPEND_FL
-#endif
-#if defined(FS_JOURNAL_DATA_FL)
- | FS_JOURNAL_DATA_FL
-#endif
- ;
-
- if (set == 0 && clear == 0)
- return (ARCHIVE_OK);
- /* Only regular files and dirs can have flags. */
- if (!S_ISREG(mode) && !S_ISDIR(mode))
- return (ARCHIVE_OK);
-
- /* If we weren't given an fd, open it ourselves. */
- if (myfd < 0) {
- myfd = open(name, O_RDONLY | O_NONBLOCK | O_BINARY |
- O_CLOEXEC | O_NOFOLLOW);
- __archive_ensure_cloexec_flag(myfd);
- }
- if (myfd < 0)
- return (ARCHIVE_OK);
-
- /*
- * XXX As above, this would be way simpler if we didn't have
- * to read the current flags from disk. XXX
- */
- ret = ARCHIVE_OK;
-
- /* Read the current file flags. */
- if (ioctl(myfd,
-#ifdef FS_IOC_GETFLAGS
- FS_IOC_GETFLAGS,
-#else
- EXT2_IOC_GETFLAGS,
-#endif
- &oldflags) < 0)
- goto fail;
-
- /* Try setting the flags as given. */
- newflags = (oldflags & ~clear) | set;
- if (ioctl(myfd,
-#ifdef FS_IOC_SETFLAGS
- FS_IOC_SETFLAGS,
-#else
- EXT2_IOC_SETFLAGS,
-#endif
- &newflags) >= 0)
- goto cleanup;
- if (errno != EPERM)
- goto fail;
-
- /* If we couldn't set all the flags, try again with a subset. */
- newflags &= ~sf_mask;
- oldflags &= sf_mask;
- newflags |= oldflags;
- if (ioctl(myfd,
-#ifdef FS_IOC_SETFLAGS
- FS_IOC_SETFLAGS,
-#else
- EXT2_IOC_SETFLAGS,
-#endif
- &newflags) >= 0)
- goto cleanup;
-
- /* We couldn't set the flags, so report the failure. */
-fail:
- archive_set_error(&a->archive, errno,
- "Failed to set file flags");
- ret = ARCHIVE_WARN;
-cleanup:
- if (fd < 0)
- close(myfd);
- return (ret);
-}
-
-#else
-
-/*
- * Of course, some systems have neither BSD chflags() nor Linux' flags
- * support through ioctl().
- */
-static int
-set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
- mode_t mode, unsigned long set, unsigned long clear)
-{
- (void)a; /* UNUSED */
- (void)fd; /* UNUSED */
- (void)name; /* UNUSED */
- (void)mode; /* UNUSED */
- (void)set; /* UNUSED */
- (void)clear; /* UNUSED */
- return (ARCHIVE_OK);
-}
-
-#endif /* __linux */
-
-#ifndef HAVE_COPYFILE_H
-/* Default is to simply drop Mac extended metadata. */
-static int
-set_mac_metadata(struct archive_write_disk *a, const char *pathname,
- const void *metadata, size_t metadata_size)
-{
- (void)a; /* UNUSED */
- (void)pathname; /* UNUSED */
- (void)metadata; /* UNUSED */
- (void)metadata_size; /* UNUSED */
- return (ARCHIVE_OK);
-}
-
-static int
-fixup_appledouble(struct archive_write_disk *a, const char *pathname)
-{
- (void)a; /* UNUSED */
- (void)pathname; /* UNUSED */
- return (ARCHIVE_OK);
-}
-#else
-
-/*
- * On Mac OS, we use copyfile() to unpack the metadata and
- * apply it to the target file.
- */
-
-#if defined(HAVE_SYS_XATTR_H)
-static int
-copy_xattrs(struct archive_write_disk *a, int tmpfd, int dffd)
-{
- ssize_t xattr_size;
- char *xattr_names = NULL, *xattr_val = NULL;
- int ret = ARCHIVE_OK, xattr_i;
-
- xattr_size = flistxattr(tmpfd, NULL, 0, 0);
- if (xattr_size == -1) {
- archive_set_error(&a->archive, errno,
- "Failed to read metadata(xattr)");
- ret = ARCHIVE_WARN;
- goto exit_xattr;
- }
- xattr_names = malloc(xattr_size);
- if (xattr_names == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for metadata(xattr)");
- ret = ARCHIVE_FATAL;
- goto exit_xattr;
- }
- xattr_size = flistxattr(tmpfd, xattr_names, xattr_size, 0);
- if (xattr_size == -1) {
- archive_set_error(&a->archive, errno,
- "Failed to read metadata(xattr)");
- ret = ARCHIVE_WARN;
- goto exit_xattr;
- }
- for (xattr_i = 0; xattr_i < xattr_size;
- xattr_i += strlen(xattr_names + xattr_i) + 1) {
- char *xattr_val_saved;
- ssize_t s;
- int f;
-
- s = fgetxattr(tmpfd, xattr_names + xattr_i, NULL, 0, 0, 0);
- if (s == -1) {
- archive_set_error(&a->archive, errno,
- "Failed to get metadata(xattr)");
- ret = ARCHIVE_WARN;
- goto exit_xattr;
- }
- xattr_val_saved = xattr_val;
- xattr_val = realloc(xattr_val, s);
- if (xattr_val == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Failed to get metadata(xattr)");
- ret = ARCHIVE_WARN;
- free(xattr_val_saved);
- goto exit_xattr;
- }
- s = fgetxattr(tmpfd, xattr_names + xattr_i, xattr_val, s, 0, 0);
- if (s == -1) {
- archive_set_error(&a->archive, errno,
- "Failed to get metadata(xattr)");
- ret = ARCHIVE_WARN;
- goto exit_xattr;
- }
- f = fsetxattr(dffd, xattr_names + xattr_i, xattr_val, s, 0, 0);
- if (f == -1) {
- archive_set_error(&a->archive, errno,
- "Failed to get metadata(xattr)");
- ret = ARCHIVE_WARN;
- goto exit_xattr;
- }
- }
-exit_xattr:
- free(xattr_names);
- free(xattr_val);
- return (ret);
-}
-#endif
-
-static int
-copy_acls(struct archive_write_disk *a, int tmpfd, int dffd)
-{
-#ifndef HAVE_SYS_ACL_H
- return 0;
-#else
- acl_t acl, dfacl = NULL;
- int acl_r, ret = ARCHIVE_OK;
-
- acl = acl_get_fd(tmpfd);
- if (acl == NULL) {
- if (errno == ENOENT)
- /* There are not any ACLs. */
- return (ret);
- archive_set_error(&a->archive, errno,
- "Failed to get metadata(acl)");
- ret = ARCHIVE_WARN;
- goto exit_acl;
- }
- dfacl = acl_dup(acl);
- acl_r = acl_set_fd(dffd, dfacl);
- if (acl_r == -1) {
- archive_set_error(&a->archive, errno,
- "Failed to get metadata(acl)");
- ret = ARCHIVE_WARN;
- goto exit_acl;
- }
-exit_acl:
- if (acl)
- acl_free(acl);
- if (dfacl)
- acl_free(dfacl);
- return (ret);
-#endif
-}
-
-static int
-create_tempdatafork(struct archive_write_disk *a, const char *pathname)
-{
- struct archive_string tmpdatafork;
- int tmpfd;
-
- archive_string_init(&tmpdatafork);
- archive_strcpy(&tmpdatafork, "tar.md.XXXXXX");
- tmpfd = mkstemp(tmpdatafork.s);
- if (tmpfd < 0) {
- archive_set_error(&a->archive, errno,
- "Failed to mkstemp");
- archive_string_free(&tmpdatafork);
- return (-1);
- }
- if (copyfile(pathname, tmpdatafork.s, 0,
- COPYFILE_UNPACK | COPYFILE_NOFOLLOW
- | COPYFILE_ACL | COPYFILE_XATTR) < 0) {
- archive_set_error(&a->archive, errno,
- "Failed to restore metadata");
- close(tmpfd);
- tmpfd = -1;
- }
- unlink(tmpdatafork.s);
- archive_string_free(&tmpdatafork);
- return (tmpfd);
-}
-
-static int
-copy_metadata(struct archive_write_disk *a, const char *metadata,
- const char *datafork, int datafork_compressed)
-{
- int ret = ARCHIVE_OK;
-
- if (datafork_compressed) {
- int dffd, tmpfd;
-
- tmpfd = create_tempdatafork(a, metadata);
- if (tmpfd == -1)
- return (ARCHIVE_WARN);
-
- /*
- * Do not open the data fork compressed by HFS+ compression
- * with at least a writing mode(O_RDWR or O_WRONLY). it
- * makes the data fork uncompressed.
- */
- dffd = open(datafork, 0);
- if (dffd == -1) {
- archive_set_error(&a->archive, errno,
- "Failed to open the data fork for metadata");
- close(tmpfd);
- return (ARCHIVE_WARN);
- }
-
-#if defined(HAVE_SYS_XATTR_H)
- ret = copy_xattrs(a, tmpfd, dffd);
- if (ret == ARCHIVE_OK)
-#endif
- ret = copy_acls(a, tmpfd, dffd);
- close(tmpfd);
- close(dffd);
- } else {
- if (copyfile(metadata, datafork, 0,
- COPYFILE_UNPACK | COPYFILE_NOFOLLOW
- | COPYFILE_ACL | COPYFILE_XATTR) < 0) {
- archive_set_error(&a->archive, errno,
- "Failed to restore metadata");
- ret = ARCHIVE_WARN;
- }
- }
- return (ret);
-}
-
-static int
-set_mac_metadata(struct archive_write_disk *a, const char *pathname,
- const void *metadata, size_t metadata_size)
-{
- struct archive_string tmp;
- ssize_t written;
- int fd;
- int ret = ARCHIVE_OK;
-
- /* This would be simpler if copyfile() could just accept the
- * metadata as a block of memory; then we could sidestep this
- * silly dance of writing the data to disk just so that
- * copyfile() can read it back in again. */
- archive_string_init(&tmp);
- archive_strcpy(&tmp, pathname);
- archive_strcat(&tmp, ".XXXXXX");
- fd = mkstemp(tmp.s);
-
- if (fd < 0) {
- archive_set_error(&a->archive, errno,
- "Failed to restore metadata");
- archive_string_free(&tmp);
- return (ARCHIVE_WARN);
- }
- written = write(fd, metadata, metadata_size);
- close(fd);
- if ((size_t)written != metadata_size) {
- archive_set_error(&a->archive, errno,
- "Failed to restore metadata");
- ret = ARCHIVE_WARN;
- } else {
- int compressed;
-
-#if defined(UF_COMPRESSED)
- if ((a->todo & TODO_HFS_COMPRESSION) != 0 &&
- (ret = lazy_stat(a)) == ARCHIVE_OK)
- compressed = a->st.st_flags & UF_COMPRESSED;
- else
-#endif
- compressed = 0;
- ret = copy_metadata(a, tmp.s, pathname, compressed);
- }
- unlink(tmp.s);
- archive_string_free(&tmp);
- return (ret);
-}
-
-static int
-fixup_appledouble(struct archive_write_disk *a, const char *pathname)
-{
- char buff[8];
- struct stat st;
- const char *p;
- struct archive_string datafork;
- int fd = -1, ret = ARCHIVE_OK;
-
- archive_string_init(&datafork);
- /* Check if the current file name is a type of the resource
- * fork file. */
- p = strrchr(pathname, '/');
- if (p == NULL)
- p = pathname;
- else
- p++;
- if (p[0] != '.' || p[1] != '_')
- goto skip_appledouble;
-
- /*
- * Check if the data fork file exists.
- *
- * TODO: Check if this write disk object has handled it.
- */
- archive_strncpy(&datafork, pathname, p - pathname);
- archive_strcat(&datafork, p + 2);
- if (
-#ifdef HAVE_LSTAT
- lstat(datafork.s, &st) == -1 ||
-#else
- la_stat(datafork.s, &st) == -1 ||
-#endif
- (st.st_mode & AE_IFMT) != AE_IFREG)
- goto skip_appledouble;
-
- /*
- * Check if the file is in the AppleDouble form.
- */
- fd = open(pathname, O_RDONLY | O_BINARY | O_CLOEXEC);
- __archive_ensure_cloexec_flag(fd);
- if (fd == -1) {
- archive_set_error(&a->archive, errno,
- "Failed to open a restoring file");
- ret = ARCHIVE_WARN;
- goto skip_appledouble;
- }
- if (read(fd, buff, 8) == -1) {
- archive_set_error(&a->archive, errno,
- "Failed to read a restoring file");
- close(fd);
- ret = ARCHIVE_WARN;
- goto skip_appledouble;
- }
- close(fd);
- /* Check AppleDouble Magic Code. */
- if (archive_be32dec(buff) != 0x00051607)
- goto skip_appledouble;
- /* Check AppleDouble Version. */
- if (archive_be32dec(buff+4) != 0x00020000)
- goto skip_appledouble;
-
- ret = copy_metadata(a, pathname, datafork.s,
-#if defined(UF_COMPRESSED)
- st.st_flags & UF_COMPRESSED);
-#else
- 0);
-#endif
- if (ret == ARCHIVE_OK) {
- unlink(pathname);
- ret = ARCHIVE_EOF;
- }
-skip_appledouble:
- archive_string_free(&datafork);
- return (ret);
-}
-#endif
-
-#if ARCHIVE_XATTR_LINUX || ARCHIVE_XATTR_DARWIN || ARCHIVE_XATTR_AIX
-/*
- * Restore extended attributes - Linux, Darwin and AIX implementations:
- * AIX' ea interface is syntaxwise identical to the Linux xattr interface.
- */
-static int
-set_xattrs(struct archive_write_disk *a)
-{
- struct archive_entry *entry = a->entry;
- struct archive_string errlist;
- int ret = ARCHIVE_OK;
- int i = archive_entry_xattr_reset(entry);
- short fail = 0;
-
- archive_string_init(&errlist);
-
- while (i--) {
- const char *name;
- const void *value;
- size_t size;
- int e;
-
- archive_entry_xattr_next(entry, &name, &value, &size);
-
- if (name == NULL)
- continue;
-#if ARCHIVE_XATTR_LINUX
- /* Linux: quietly skip POSIX.1e ACL extended attributes */
- if (strncmp(name, "system.", 7) == 0 &&
- (strcmp(name + 7, "posix_acl_access") == 0 ||
- strcmp(name + 7, "posix_acl_default") == 0))
- continue;
- if (strncmp(name, "trusted.SGI_", 12) == 0 &&
- (strcmp(name + 12, "ACL_DEFAULT") == 0 ||
- strcmp(name + 12, "ACL_FILE") == 0))
- continue;
-
- /* Linux: xfsroot namespace is obsolete and unsupported */
- if (strncmp(name, "xfsroot.", 8) == 0) {
- fail = 1;
- archive_strcat(&errlist, name);
- archive_strappend_char(&errlist, ' ');
- continue;
- }
-#endif
-
- if (a->fd >= 0) {
-#if ARCHIVE_XATTR_LINUX
- e = fsetxattr(a->fd, name, value, size, 0);
-#elif ARCHIVE_XATTR_DARWIN
- e = fsetxattr(a->fd, name, value, size, 0, 0);
-#elif ARCHIVE_XATTR_AIX
- e = fsetea(a->fd, name, value, size, 0);
-#endif
- } else {
-#if ARCHIVE_XATTR_LINUX
- e = lsetxattr(archive_entry_pathname(entry),
- name, value, size, 0);
-#elif ARCHIVE_XATTR_DARWIN
- e = setxattr(archive_entry_pathname(entry),
- name, value, size, 0, XATTR_NOFOLLOW);
-#elif ARCHIVE_XATTR_AIX
- e = lsetea(archive_entry_pathname(entry),
- name, value, size, 0);
-#endif
- }
- if (e == -1) {
- ret = ARCHIVE_WARN;
- archive_strcat(&errlist, name);
- archive_strappend_char(&errlist, ' ');
- if (errno != ENOTSUP && errno != ENOSYS)
- fail = 1;
- }
- }
-
- if (ret == ARCHIVE_WARN) {
- if (fail && errlist.length > 0) {
- errlist.length--;
- errlist.s[errlist.length] = '\0';
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Cannot restore extended attributes: %s",
- errlist.s);
- } else
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Cannot restore extended "
- "attributes on this file system.");
- }
-
- archive_string_free(&errlist);
- return (ret);
-}
-#elif ARCHIVE_XATTR_FREEBSD
-/*
- * Restore extended attributes - FreeBSD implementation
- */
-static int
-set_xattrs(struct archive_write_disk *a)
-{
- struct archive_entry *entry = a->entry;
- struct archive_string errlist;
- int ret = ARCHIVE_OK;
- int i = archive_entry_xattr_reset(entry);
- short fail = 0;
-
- archive_string_init(&errlist);
-
- while (i--) {
- const char *name;
- const void *value;
- size_t size;
- archive_entry_xattr_next(entry, &name, &value, &size);
- if (name != NULL) {
- int e;
- int namespace;
-
- namespace = EXTATTR_NAMESPACE_USER;
-
- if (strncmp(name, "user.", 5) == 0) {
- /* "user." attributes go to user namespace */
- name += 5;
- namespace = EXTATTR_NAMESPACE_USER;
- } else if (strncmp(name, "system.", 7) == 0) {
- name += 7;
- namespace = EXTATTR_NAMESPACE_SYSTEM;
- if (!strcmp(name, "nfs4.acl") ||
- !strcmp(name, "posix1e.acl_access") ||
- !strcmp(name, "posix1e.acl_default"))
- continue;
- } else {
- /* Other namespaces are unsupported */
- archive_strcat(&errlist, name);
- archive_strappend_char(&errlist, ' ');
- fail = 1;
- ret = ARCHIVE_WARN;
- continue;
- }
-
- if (a->fd >= 0) {
- /*
- * On FreeBSD, extattr_set_fd does not
- * return the same as
- * extattr_set_file. It returns zero
- * on success, non-zero on failure.
- *
- * We can detect the failure by
- * manually setting errno prior to the
- * call and checking after.
- *
- * If errno remains zero, fake the
- * return value by setting e to size.
- *
- * This is a hack for now until I
- * (Shawn Webb) get FreeBSD to fix the
- * issue, if that's even possible.
- */
- errno = 0;
- e = extattr_set_fd(a->fd, namespace, name,
- value, size);
- if (e == 0 && errno == 0) {
- e = size;
- }
- } else {
- e = extattr_set_link(
- archive_entry_pathname(entry), namespace,
- name, value, size);
- }
- if (e != (int)size) {
- archive_strcat(&errlist, name);
- archive_strappend_char(&errlist, ' ');
- ret = ARCHIVE_WARN;
- if (errno != ENOTSUP && errno != ENOSYS)
- fail = 1;
- }
- }
- }
-
- if (ret == ARCHIVE_WARN) {
- if (fail && errlist.length > 0) {
- errlist.length--;
- errlist.s[errlist.length] = '\0';
-
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Cannot restore extended attributes: %s",
- errlist.s);
- } else
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Cannot restore extended "
- "attributes on this file system.");
- }
-
- archive_string_free(&errlist);
- return (ret);
-}
-#else
-/*
- * Restore extended attributes - stub implementation for unsupported systems
- */
-static int
-set_xattrs(struct archive_write_disk *a)
-{
- static int warning_done = 0;
-
- /* If there aren't any extended attributes, then it's okay not
- * to extract them, otherwise, issue a single warning. */
- if (archive_entry_xattr_count(a->entry) != 0 && !warning_done) {
- warning_done = 1;
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Cannot restore extended attributes on this system");
- return (ARCHIVE_WARN);
- }
- /* Warning was already emitted; suppress further warnings. */
- return (ARCHIVE_OK);
-}
-#endif
-
-/*
- * Test if file on disk is older than entry.
- */
-static int
-older(struct stat *st, struct archive_entry *entry)
-{
- /* First, test the seconds and return if we have a definite answer. */
- /* Definitely older. */
- if (to_int64_time(st->st_mtime) < to_int64_time(archive_entry_mtime(entry)))
- return (1);
- /* Definitely younger. */
- if (to_int64_time(st->st_mtime) > to_int64_time(archive_entry_mtime(entry)))
- return (0);
- /* If this platform supports fractional seconds, try those. */
-#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
- /* Definitely older. */
- if (st->st_mtimespec.tv_nsec < archive_entry_mtime_nsec(entry))
- return (1);
-#elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
- /* Definitely older. */
- if (st->st_mtim.tv_nsec < archive_entry_mtime_nsec(entry))
- return (1);
-#elif HAVE_STRUCT_STAT_ST_MTIME_N
- /* older. */
- if (st->st_mtime_n < archive_entry_mtime_nsec(entry))
- return (1);
-#elif HAVE_STRUCT_STAT_ST_UMTIME
- /* older. */
- if (st->st_umtime * 1000 < archive_entry_mtime_nsec(entry))
- return (1);
-#elif HAVE_STRUCT_STAT_ST_MTIME_USEC
- /* older. */
- if (st->st_mtime_usec * 1000 < archive_entry_mtime_nsec(entry))
- return (1);
-#else
- /* This system doesn't have high-res timestamps. */
-#endif
- /* Same age or newer, so not older. */
- return (0);
-}
-
-#ifndef ARCHIVE_ACL_SUPPORT
-int
-archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
- struct archive_acl *abstract_acl, __LA_MODE_T mode)
-{
- (void)a; /* UNUSED */
- (void)fd; /* UNUSED */
- (void)name; /* UNUSED */
- (void)abstract_acl; /* UNUSED */
- (void)mode; /* UNUSED */
- return (ARCHIVE_OK);
-}
-#endif
-
-/*
- * Close the file descriptor if one is open.
- */
-static void close_file_descriptor(struct archive_write_disk* a)
-{
- if (a->fd >= 0) {
- close(a->fd);
- a->fd = -1;
- }
-}
-
-
-#endif /* !_WIN32 || __CYGWIN__ */
-
diff --git a/contrib/libs/libarchive/libarchive/archive_write_disk_private.h b/contrib/libs/libarchive/libarchive/archive_write_disk_private.h
deleted file mode 100644
index 557d7e2bf3..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_disk_private.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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
- * in this position and unchanged.
- * 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(S) ``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(S) 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.
- *
- * $FreeBSD: head/lib/libarchive/archive_write_disk_private.h 201086 2009-12-28 02:17:53Z kientzle $
- */
-
-#ifndef ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
-#define ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
-#include "archive_platform_acl.h"
-#include "archive_acl_private.h"
-#include "archive_entry.h"
-
-struct archive_write_disk;
-
-int archive_write_disk_set_acls(struct archive *, int, const char *,
- struct archive_acl *, __LA_MODE_T);
-
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_write_disk_set_standard_lookup.c b/contrib/libs/libarchive/libarchive/archive_write_disk_set_standard_lookup.c
deleted file mode 100644
index 5fccdb9dc6..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_disk_set_standard_lookup.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk_set_standard_lookup.c 201083 2009-12-28 02:09:57Z kientzle $");
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_GRP_H
-#include <grp.h>
-#endif
-#ifdef HAVE_PWD_H
-#include <pwd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-#include "archive_write_disk_private.h"
-
-struct bucket {
- char *name;
- int hash;
- id_t id;
-};
-
-static const size_t cache_size = 127;
-static unsigned int hash(const char *);
-static int64_t lookup_gid(void *, const char *uname, int64_t);
-static int64_t lookup_uid(void *, const char *uname, int64_t);
-static void cleanup(void *);
-
-/*
- * Installs functions that use getpwnam()/getgrnam()---along with
- * a simple cache to accelerate such lookups---into the archive_write_disk
- * object. This is in a separate file because getpwnam()/getgrnam()
- * can pull in a LOT of library code (including NIS/LDAP functions, which
- * pull in DNS resolvers, etc). This can easily top 500kB, which makes
- * it inappropriate for some space-constrained applications.
- *
- * Applications that are size-sensitive may want to just use the
- * real default functions (defined in archive_write_disk.c) that just
- * use the uid/gid without the lookup. Or define your own custom functions
- * if you prefer.
- *
- * TODO: Replace these hash tables with simpler move-to-front LRU
- * lists with a bounded size (128 items?). The hash is a bit faster,
- * but has a bad pathology in which it thrashes a single bucket. Even
- * walking a list of 128 items is a lot faster than calling
- * getpwnam()!
- */
-int
-archive_write_disk_set_standard_lookup(struct archive *a)
-{
- struct bucket *ucache = calloc(cache_size, sizeof(struct bucket));
- struct bucket *gcache = calloc(cache_size, sizeof(struct bucket));
- if (ucache == NULL || gcache == NULL) {
- free(ucache);
- free(gcache);
- return (ARCHIVE_FATAL);
- }
- archive_write_disk_set_group_lookup(a, gcache, lookup_gid, cleanup);
- archive_write_disk_set_user_lookup(a, ucache, lookup_uid, cleanup);
- return (ARCHIVE_OK);
-}
-
-static int64_t
-lookup_gid(void *private_data, const char *gname, int64_t gid)
-{
- int h;
- struct bucket *b;
- struct bucket *gcache = (struct bucket *)private_data;
-
- /* If no gname, just use the gid provided. */
- if (gname == NULL || *gname == '\0')
- return (gid);
-
- /* Try to find gname in the cache. */
- h = hash(gname);
- b = &gcache[h % cache_size ];
- if (b->name != NULL && b->hash == h && strcmp(gname, b->name) == 0)
- return ((gid_t)b->id);
-
- /* Free the cache slot for a new entry. */
- free(b->name);
- b->name = strdup(gname);
- /* Note: If strdup fails, that's okay; we just won't cache. */
- b->hash = h;
-#if HAVE_GRP_H
-# if HAVE_GETGRNAM_R
- {
- char _buffer[128];
- size_t bufsize = 128;
- char *buffer = _buffer;
- char *allocated = NULL;
- struct group grent, *result;
- int r;
-
- for (;;) {
- result = &grent; /* Old getgrnam_r ignores last arg. */
- r = getgrnam_r(gname, &grent, buffer, bufsize, &result);
- if (r == 0)
- break;
- if (r != ERANGE)
- break;
- bufsize *= 2;
- free(allocated);
- allocated = malloc(bufsize);
- if (allocated == NULL)
- break;
- buffer = allocated;
- }
- if (result != NULL)
- gid = result->gr_gid;
- free(allocated);
- }
-# else /* HAVE_GETGRNAM_R */
- {
- struct group *result;
-
- result = getgrnam(gname);
- if (result != NULL)
- gid = result->gr_gid;
- }
-# endif /* HAVE_GETGRNAM_R */
-#elif defined(_WIN32) && !defined(__CYGWIN__)
- /* TODO: do a gname->gid lookup for Windows. */
-#else
- #error No way to perform gid lookups on this platform
-#endif
- b->id = (gid_t)gid;
-
- return (gid);
-}
-
-static int64_t
-lookup_uid(void *private_data, const char *uname, int64_t uid)
-{
- int h;
- struct bucket *b;
- struct bucket *ucache = (struct bucket *)private_data;
-
- /* If no uname, just use the uid provided. */
- if (uname == NULL || *uname == '\0')
- return (uid);
-
- /* Try to find uname in the cache. */
- h = hash(uname);
- b = &ucache[h % cache_size ];
- if (b->name != NULL && b->hash == h && strcmp(uname, b->name) == 0)
- return ((uid_t)b->id);
-
- /* Free the cache slot for a new entry. */
- free(b->name);
- b->name = strdup(uname);
- /* Note: If strdup fails, that's okay; we just won't cache. */
- b->hash = h;
-#if HAVE_PWD_H
-# if HAVE_GETPWNAM_R
- {
- char _buffer[128];
- size_t bufsize = 128;
- char *buffer = _buffer;
- char *allocated = NULL;
- struct passwd pwent, *result;
- int r;
-
- for (;;) {
- result = &pwent; /* Old getpwnam_r ignores last arg. */
- r = getpwnam_r(uname, &pwent, buffer, bufsize, &result);
- if (r == 0)
- break;
- if (r != ERANGE)
- break;
- bufsize *= 2;
- free(allocated);
- allocated = malloc(bufsize);
- if (allocated == NULL)
- break;
- buffer = allocated;
- }
- if (result != NULL)
- uid = result->pw_uid;
- free(allocated);
- }
-# else /* HAVE_GETPWNAM_R */
- {
- struct passwd *result;
-
- result = getpwnam(uname);
- if (result != NULL)
- uid = result->pw_uid;
- }
-#endif /* HAVE_GETPWNAM_R */
-#elif defined(_WIN32) && !defined(__CYGWIN__)
- /* TODO: do a uname->uid lookup for Windows. */
-#else
- #error No way to look up uids on this platform
-#endif
- b->id = (uid_t)uid;
-
- return (uid);
-}
-
-static void
-cleanup(void *private)
-{
- size_t i;
- struct bucket *cache = (struct bucket *)private;
-
- for (i = 0; i < cache_size; i++)
- free(cache[i].name);
- free(cache);
-}
-
-
-static unsigned int
-hash(const char *p)
-{
- /* A 32-bit version of Peter Weinberger's (PJW) hash algorithm,
- as used by ELF for hashing function names. */
- unsigned g, h = 0;
- while (*p != '\0') {
- h = (h << 4) + *p++;
- if ((g = h & 0xF0000000) != 0) {
- h ^= g >> 24;
- h &= 0x0FFFFFFF;
- }
- }
- return h;
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_disk_windows.c b/contrib/libs/libarchive/libarchive/archive_write_disk_windows.c
deleted file mode 100644
index 7b9ea74937..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_disk_windows.c
+++ /dev/null
@@ -1,2911 +0,0 @@
-/*-
- * Copyright (c) 2003-2010 Tim Kientzle
- * Copyright (c) 2011-2012 Michihiro NAKAJIMA
- * 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
- * in this position and unchanged.
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_UTIME_H
-#include <sys/utime.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#include <winioctl.h>
-
-/* TODO: Support Mac OS 'quarantine' feature. This is really just a
- * standard tag to mark files that have been downloaded as "tainted".
- * On Mac OS, we should mark the extracted files as tainted if the
- * archive being read was tainted. Windows has a similar feature; we
- * should investigate ways to support this generically. */
-
-#include "archive.h"
-#include "archive_acl_private.h"
-#include "archive_string.h"
-#include "archive_entry.h"
-#include "archive_private.h"
-
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-#ifndef IO_REPARSE_TAG_SYMLINK
-/* Old SDKs do not provide IO_REPARSE_TAG_SYMLINK */
-#define IO_REPARSE_TAG_SYMLINK 0xA000000CL
-#endif
-
-static BOOL SetFilePointerEx_perso(HANDLE hFile,
- LARGE_INTEGER liDistanceToMove,
- PLARGE_INTEGER lpNewFilePointer,
- DWORD dwMoveMethod)
-{
- LARGE_INTEGER li;
- li.QuadPart = liDistanceToMove.QuadPart;
- li.LowPart = SetFilePointer(
- hFile, li.LowPart, &li.HighPart, dwMoveMethod);
- if(lpNewFilePointer) {
- lpNewFilePointer->QuadPart = li.QuadPart;
- }
- return li.LowPart != (DWORD)-1 || GetLastError() == NO_ERROR;
-}
-
-struct fixup_entry {
- struct fixup_entry *next;
- struct archive_acl acl;
- mode_t mode;
- int64_t atime;
- int64_t birthtime;
- int64_t mtime;
- int64_t ctime;
- unsigned long atime_nanos;
- unsigned long birthtime_nanos;
- unsigned long mtime_nanos;
- unsigned long ctime_nanos;
- unsigned long fflags_set;
- int fixup; /* bitmask of what needs fixing */
- wchar_t *name;
-};
-
-/*
- * We use a bitmask to track which operations remain to be done for
- * this file. In particular, this helps us avoid unnecessary
- * operations when it's possible to take care of one step as a
- * side-effect of another. For example, mkdir() can specify the mode
- * for the newly-created object but symlink() cannot. This means we
- * can skip chmod() if mkdir() succeeded, but we must explicitly
- * chmod() if we're trying to create a directory that already exists
- * (mkdir() failed) or if we're restoring a symlink. Similarly, we
- * need to verify UID/GID before trying to restore SUID/SGID bits;
- * that verification can occur explicitly through a stat() call or
- * implicitly because of a successful chown() call.
- */
-#define TODO_MODE_FORCE 0x40000000
-#define TODO_MODE_BASE 0x20000000
-#define TODO_SUID 0x10000000
-#define TODO_SUID_CHECK 0x08000000
-#define TODO_SGID 0x04000000
-#define TODO_SGID_CHECK 0x02000000
-#define TODO_MODE (TODO_MODE_BASE|TODO_SUID|TODO_SGID)
-#define TODO_TIMES ARCHIVE_EXTRACT_TIME
-#define TODO_OWNER ARCHIVE_EXTRACT_OWNER
-#define TODO_FFLAGS ARCHIVE_EXTRACT_FFLAGS
-#define TODO_ACLS ARCHIVE_EXTRACT_ACL
-#define TODO_XATTR ARCHIVE_EXTRACT_XATTR
-#define TODO_MAC_METADATA ARCHIVE_EXTRACT_MAC_METADATA
-
-struct archive_write_disk {
- struct archive archive;
-
- mode_t user_umask;
- struct fixup_entry *fixup_list;
- struct fixup_entry *current_fixup;
- int64_t user_uid;
- int skip_file_set;
- int64_t skip_file_dev;
- int64_t skip_file_ino;
- time_t start_time;
-
- int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid);
- void (*cleanup_gid)(void *private);
- void *lookup_gid_data;
- int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid);
- void (*cleanup_uid)(void *private);
- void *lookup_uid_data;
-
- /*
- * Full path of last file to satisfy symlink checks.
- */
- struct archive_wstring path_safe;
-
- /*
- * Cached stat data from disk for the current entry.
- * If this is valid, pst points to st. Otherwise,
- * pst is null.
- */
- BY_HANDLE_FILE_INFORMATION st;
- BY_HANDLE_FILE_INFORMATION *pst;
-
- /* Information about the object being restored right now. */
- struct archive_entry *entry; /* Entry being extracted. */
- wchar_t *name; /* Name of entry, possibly edited. */
- struct archive_wstring _name_data; /* backing store for 'name' */
- wchar_t *tmpname; /* Temporary name */
- struct archive_wstring _tmpname_data; /* backing store for 'tmpname' */
- /* Tasks remaining for this object. */
- int todo;
- /* Tasks deferred until end-of-archive. */
- int deferred;
- /* Options requested by the client. */
- int flags;
- /* Handle for the file we're restoring. */
- HANDLE fh;
- /* Current offset for writing data to the file. */
- int64_t offset;
- /* Last offset actually written to disk. */
- int64_t fd_offset;
- /* Total bytes actually written to files. */
- int64_t total_bytes_written;
- /* Maximum size of file, -1 if unknown. */
- int64_t filesize;
- /* Dir we were in before this restore; only for deep paths. */
- int restore_pwd;
- /* Mode we should use for this entry; affected by _PERM and umask. */
- mode_t mode;
- /* UID/GID to use in restoring this entry. */
- int64_t uid;
- int64_t gid;
-};
-
-/*
- * Default mode for dirs created automatically (will be modified by umask).
- * Note that POSIX specifies 0777 for implicitly-created dirs, "modified
- * by the process' file creation mask."
- */
-#define DEFAULT_DIR_MODE 0777
-/*
- * Dir modes are restored in two steps: During the extraction, the permissions
- * in the archive are modified to match the following limits. During
- * the post-extract fixup pass, the permissions from the archive are
- * applied.
- */
-#define MINIMUM_DIR_MODE 0700
-#define MAXIMUM_DIR_MODE 0775
-
-static int disk_unlink(const wchar_t *);
-static int disk_rmdir(const wchar_t *);
-static int check_symlinks(struct archive_write_disk *);
-static int create_filesystem_object(struct archive_write_disk *);
-static struct fixup_entry *current_fixup(struct archive_write_disk *,
- const wchar_t *pathname);
-static int cleanup_pathname(struct archive_write_disk *, wchar_t *);
-static int create_dir(struct archive_write_disk *, wchar_t *);
-static int create_parent_dir(struct archive_write_disk *, wchar_t *);
-static int la_chmod(const wchar_t *, mode_t);
-static int la_mktemp(struct archive_write_disk *);
-static int older(BY_HANDLE_FILE_INFORMATION *, struct archive_entry *);
-static int permissive_name_w(struct archive_write_disk *);
-static int restore_entry(struct archive_write_disk *);
-static int set_acls(struct archive_write_disk *, HANDLE h,
- const wchar_t *, struct archive_acl *);
-static int set_xattrs(struct archive_write_disk *);
-static int clear_nochange_fflags(struct archive_write_disk *);
-static int set_fflags(struct archive_write_disk *);
-static int set_fflags_platform(const wchar_t *, unsigned long,
- unsigned long);
-static int set_ownership(struct archive_write_disk *);
-static int set_mode(struct archive_write_disk *, int mode);
-static int set_times(struct archive_write_disk *, HANDLE, int,
- const wchar_t *, time_t, long, time_t, long, time_t,
- long, time_t, long);
-static int set_times_from_entry(struct archive_write_disk *);
-static struct fixup_entry *sort_dir_list(struct fixup_entry *p);
-static ssize_t write_data_block(struct archive_write_disk *,
- const char *, size_t);
-
-static int _archive_write_disk_close(struct archive *);
-static int _archive_write_disk_free(struct archive *);
-static int _archive_write_disk_header(struct archive *,
- struct archive_entry *);
-static int64_t _archive_write_disk_filter_bytes(struct archive *, int);
-static int _archive_write_disk_finish_entry(struct archive *);
-static ssize_t _archive_write_disk_data(struct archive *, const void *,
- size_t);
-static ssize_t _archive_write_disk_data_block(struct archive *, const void *,
- size_t, int64_t);
-
-#define bhfi_dev(bhfi) ((bhfi)->dwVolumeSerialNumber)
-/* Treat FileIndex as i-node. We should remove a sequence number
- * which is high-16-bits of nFileIndexHigh. */
-#define bhfi_ino(bhfi) \
- ((((int64_t)((bhfi)->nFileIndexHigh & 0x0000FFFFUL)) << 32) \
- | (bhfi)->nFileIndexLow)
-#define bhfi_size(bhfi) \
- ((((int64_t)(bhfi)->nFileSizeHigh) << 32) | (bhfi)->nFileSizeLow)
-
-static int
-file_information(struct archive_write_disk *a, wchar_t *path,
- BY_HANDLE_FILE_INFORMATION *st, mode_t *mode, int sim_lstat)
-{
- HANDLE h;
- int r;
- DWORD flag = FILE_FLAG_BACKUP_SEMANTICS;
- WIN32_FIND_DATAW findData;
-# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- CREATEFILE2_EXTENDED_PARAMETERS createExParams;
-#endif
-
- if (sim_lstat || mode != NULL) {
- h = FindFirstFileW(path, &findData);
- if (h == INVALID_HANDLE_VALUE &&
- GetLastError() == ERROR_INVALID_NAME) {
- wchar_t *full;
- full = __la_win_permissive_name_w(path);
- h = FindFirstFileW(full, &findData);
- free(full);
- }
- if (h == INVALID_HANDLE_VALUE) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- FindClose(h);
- }
-
- /* Is symlink file ? */
- if (sim_lstat &&
- ((findData.dwFileAttributes
- & FILE_ATTRIBUTE_REPARSE_POINT) &&
- (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)))
- flag |= FILE_FLAG_OPEN_REPARSE_POINT;
-
-# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- ZeroMemory(&createExParams, sizeof(createExParams));
- createExParams.dwSize = sizeof(createExParams);
- createExParams.dwFileFlags = flag;
- h = CreateFile2(a->name, 0, 0,
- OPEN_EXISTING, &createExParams);
-#else
- h = CreateFileW(a->name, 0, 0, NULL,
- OPEN_EXISTING, flag, NULL);
-#endif
- if (h == INVALID_HANDLE_VALUE &&
- GetLastError() == ERROR_INVALID_NAME) {
- wchar_t *full;
- full = __la_win_permissive_name_w(path);
-# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- h = CreateFile2(full, 0, 0,
- OPEN_EXISTING, &createExParams);
-#else
- h = CreateFileW(full, 0, 0, NULL,
- OPEN_EXISTING, flag, NULL);
-#endif
- free(full);
- }
- if (h == INVALID_HANDLE_VALUE) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- r = GetFileInformationByHandle(h, st);
- CloseHandle(h);
- if (r == 0) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
-
- if (mode == NULL)
- return (0);
-
- *mode = S_IRUSR | S_IRGRP | S_IROTH;
- if ((st->dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
- *mode |= S_IWUSR | S_IWGRP | S_IWOTH;
- if ((st->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
- findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)
- *mode |= S_IFLNK;
- else if (st->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- *mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
- else {
- const wchar_t *p;
-
- *mode |= S_IFREG;
- p = wcsrchr(path, L'.');
- if (p != NULL && wcslen(p) == 4) {
- switch (p[1]) {
- case L'B': case L'b':
- if ((p[2] == L'A' || p[2] == L'a' ) &&
- (p[3] == L'T' || p[3] == L't' ))
- *mode |= S_IXUSR | S_IXGRP | S_IXOTH;
- break;
- case L'C': case L'c':
- if (((p[2] == L'M' || p[2] == L'm' ) &&
- (p[3] == L'D' || p[3] == L'd' )))
- *mode |= S_IXUSR | S_IXGRP | S_IXOTH;
- break;
- case L'E': case L'e':
- if ((p[2] == L'X' || p[2] == L'x' ) &&
- (p[3] == L'E' || p[3] == L'e' ))
- *mode |= S_IXUSR | S_IXGRP | S_IXOTH;
- break;
- default:
- break;
- }
- }
- }
- return (0);
-}
-
-/*
- * Note: The path, for example, "aa/a/../b../c" will be converted to "aa/c"
- * by GetFullPathNameW() W32 API, which __la_win_permissive_name_w uses.
- * It means we cannot handle multiple dirs in one archive_entry.
- * So we have to make the full-pathname in another way, which does not
- * break "../" path string.
- */
-static int
-permissive_name_w(struct archive_write_disk *a)
-{
- wchar_t *wn, *wnp;
- wchar_t *ws, *wsp;
- DWORD l;
-
- wnp = a->name;
- if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
- wnp[2] == L'?' && wnp[3] == L'\\')
- /* We have already a permissive name. */
- return (0);
-
- if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
- wnp[2] == L'.' && wnp[3] == L'\\') {
- /* This is a device name */
- if (((wnp[4] >= L'a' && wnp[4] <= L'z') ||
- (wnp[4] >= L'A' && wnp[4] <= L'Z')) &&
- wnp[5] == L':' && wnp[6] == L'\\') {
- wnp[2] = L'?';/* Not device name. */
- return (0);
- }
- }
-
- /*
- * A full-pathname starting with a drive name like "C:\abc".
- */
- if (((wnp[0] >= L'a' && wnp[0] <= L'z') ||
- (wnp[0] >= L'A' && wnp[0] <= L'Z')) &&
- wnp[1] == L':' && wnp[2] == L'\\') {
- wn = _wcsdup(wnp);
- if (wn == NULL)
- return (-1);
- archive_wstring_ensure(&(a->_name_data), 4 + wcslen(wn) + 1);
- a->name = a->_name_data.s;
- /* Prepend "\\?\" */
- archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
- archive_wstrcat(&(a->_name_data), wn);
- free(wn);
- return (0);
- }
-
- /*
- * A full-pathname pointing to a network drive
- * like "\\<server-name>\<share-name>\file".
- */
- if (wnp[0] == L'\\' && wnp[1] == L'\\' && wnp[2] != L'\\') {
- const wchar_t *p = &wnp[2];
-
- /* Skip server-name letters. */
- while (*p != L'\\' && *p != L'\0')
- ++p;
- if (*p == L'\\') {
- const wchar_t *rp = ++p;
- /* Skip share-name letters. */
- while (*p != L'\\' && *p != L'\0')
- ++p;
- if (*p == L'\\' && p != rp) {
- /* Now, match patterns such as
- * "\\server-name\share-name\" */
- wn = _wcsdup(wnp);
- if (wn == NULL)
- return (-1);
- archive_wstring_ensure(&(a->_name_data),
- 8 + wcslen(wn) + 1);
- a->name = a->_name_data.s;
- /* Prepend "\\?\UNC\" */
- archive_wstrncpy(&(a->_name_data),
- L"\\\\?\\UNC\\", 8);
- archive_wstrcat(&(a->_name_data), wn+2);
- free(wn);
- return (0);
- }
- }
- return (0);
- }
-
- /*
- * Get current working directory.
- */
- l = GetCurrentDirectoryW(0, NULL);
- if (l == 0)
- return (-1);
- ws = malloc(l * sizeof(wchar_t));
- l = GetCurrentDirectoryW(l, ws);
- if (l == 0) {
- free(ws);
- return (-1);
- }
- wsp = ws;
-
- /*
- * A full-pathname starting without a drive name like "\abc".
- */
- if (wnp[0] == L'\\') {
- wn = _wcsdup(wnp);
- if (wn == NULL)
- return (-1);
- archive_wstring_ensure(&(a->_name_data),
- 4 + 2 + wcslen(wn) + 1);
- a->name = a->_name_data.s;
- /* Prepend "\\?\" and drive name. */
- archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
- archive_wstrncat(&(a->_name_data), wsp, 2);
- archive_wstrcat(&(a->_name_data), wn);
- free(wsp);
- free(wn);
- return (0);
- }
-
- wn = _wcsdup(wnp);
- if (wn == NULL)
- return (-1);
- archive_wstring_ensure(&(a->_name_data), 4 + l + 1 + wcslen(wn) + 1);
- a->name = a->_name_data.s;
- /* Prepend "\\?\" and drive name if not already added. */
- if (l > 3 && wsp[0] == L'\\' && wsp[1] == L'\\' &&
- wsp[2] == L'?' && wsp[3] == L'\\')
- {
- archive_wstrncpy(&(a->_name_data), wsp, l);
- }
- else if (l > 2 && wsp[0] == L'\\' && wsp[1] == L'\\' && wsp[2] != L'\\')
- {
- archive_wstrncpy(&(a->_name_data), L"\\\\?\\UNC\\", 8);
- archive_wstrncat(&(a->_name_data), wsp+2, l-2);
- }
- else
- {
- archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
- archive_wstrncat(&(a->_name_data), wsp, l);
- }
- archive_wstrncat(&(a->_name_data), L"\\", 1);
- archive_wstrcat(&(a->_name_data), wn);
- a->name = a->_name_data.s;
- free(wsp);
- free(wn);
- return (0);
-}
-
-static int
-la_chmod(const wchar_t *path, mode_t mode)
-{
- DWORD attr;
- BOOL r;
- wchar_t *fullname;
- int ret = 0;
-
- fullname = NULL;
- attr = GetFileAttributesW(path);
- if (attr == (DWORD)-1 &&
- GetLastError() == ERROR_INVALID_NAME) {
- fullname = __la_win_permissive_name_w(path);
- attr = GetFileAttributesW(fullname);
- }
- if (attr == (DWORD)-1) {
- la_dosmaperr(GetLastError());
- ret = -1;
- goto exit_chmode;
- }
- if (mode & _S_IWRITE)
- attr &= ~FILE_ATTRIBUTE_READONLY;
- else
- attr |= FILE_ATTRIBUTE_READONLY;
- if (fullname != NULL)
- r = SetFileAttributesW(fullname, attr);
- else
- r = SetFileAttributesW(path, attr);
- if (r == 0) {
- la_dosmaperr(GetLastError());
- ret = -1;
- }
-exit_chmode:
- free(fullname);
- return (ret);
-}
-
-static int
-la_mktemp(struct archive_write_disk *a)
-{
- int fd;
- mode_t mode;
-
- archive_wstring_empty(&(a->_tmpname_data));
- archive_wstrcpy(&(a->_tmpname_data), a->name);
- archive_wstrcat(&(a->_tmpname_data), L".XXXXXX");
- a->tmpname = a->_tmpname_data.s;
-
- fd = __archive_mkstemp(a->tmpname);
- if (fd == -1)
- return -1;
-
- mode = a->mode & 0777 & ~a->user_umask;
- if (la_chmod(a->tmpname, mode) == -1) {
- la_dosmaperr(GetLastError());
- _close(fd);
- return -1;
- }
- return (fd);
-}
-
-#if _WIN32_WINNT < _WIN32_WINNT_VISTA
-static void *
-la_GetFunctionKernel32(const char *name)
-{
- static HINSTANCE lib;
- static int set;
- if (!set) {
- set = 1;
- lib = LoadLibrary(TEXT("kernel32.dll"));
- }
- if (lib == NULL) {
- fprintf(stderr, "Can't load kernel32.dll?!\n");
- exit(1);
- }
- return (void *)GetProcAddress(lib, name);
-}
-#endif
-
-static int
-la_CreateHardLinkW(wchar_t *linkname, wchar_t *target)
-{
- static BOOL (WINAPI *f)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);
- BOOL ret;
-
-#if _WIN32_WINNT < _WIN32_WINNT_XP
- static int set;
-/* CreateHardLinkW is available since XP and always loaded */
- if (!set) {
- set = 1;
- f = la_GetFunctionKernel32("CreateHardLinkW");
- }
-#else
- f = CreateHardLinkW;
-#endif
- if (!f) {
- errno = ENOTSUP;
- return (0);
- }
- ret = (*f)(linkname, target, NULL);
- if (!ret) {
- /* Under windows 2000, it is necessary to remove
- * the "\\?\" prefix. */
-#define IS_UNC(name) ((name[0] == L'U' || name[0] == L'u') && \
- (name[1] == L'N' || name[1] == L'n') && \
- (name[2] == L'C' || name[2] == L'c') && \
- name[3] == L'\\')
- if (!wcsncmp(linkname,L"\\\\?\\", 4)) {
- linkname += 4;
- if (IS_UNC(linkname))
- linkname += 4;
- }
- if (!wcsncmp(target,L"\\\\?\\", 4)) {
- target += 4;
- if (IS_UNC(target))
- target += 4;
- }
-#undef IS_UNC
- ret = (*f)(linkname, target, NULL);
- }
- return (ret);
-}
-
-/*
- * Create file or directory symolic link
- *
- * If linktype is AE_SYMLINK_TYPE_UNDEFINED (or unknown), guess linktype from
- * the link target
- */
-static int
-la_CreateSymbolicLinkW(const wchar_t *linkname, const wchar_t *target,
- int linktype) {
- static BOOLEAN (WINAPI *f)(LPCWSTR, LPCWSTR, DWORD);
- wchar_t *ttarget, *p;
- size_t len;
- DWORD attrs = 0;
- DWORD flags = 0;
- DWORD newflags = 0;
- BOOL ret = 0;
-
-#if _WIN32_WINNT < _WIN32_WINNT_VISTA
-/* CreateSymbolicLinkW is available since Vista and always loaded */
- static int set;
- if (!set) {
- set = 1;
- f = la_GetFunctionKernel32("CreateSymbolicLinkW");
- }
-#else
-# if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
- f = CreateSymbolicLinkW;
-# else
- f = NULL;
-# endif
-#endif
- if (!f)
- return (0);
-
- len = wcslen(target);
- if (len == 0) {
- errno = EINVAL;
- return(0);
- }
- /*
- * When writing path targets, we need to translate slashes
- * to backslashes
- */
- ttarget = malloc((len + 1) * sizeof(wchar_t));
- if (ttarget == NULL)
- return(0);
-
- p = ttarget;
-
- while(*target != L'\0') {
- if (*target == L'/')
- *p = L'\\';
- else
- *p = *target;
- target++;
- p++;
- }
- *p = L'\0';
-
- /*
- * In case of undefined symlink type we guess it from the target.
- * If the target equals ".", "..", ends with a backslash or a
- * backslash followed by "." or ".." we assume it is a directory
- * symlink. In all other cases we assume a file symlink.
- */
- if (linktype != AE_SYMLINK_TYPE_FILE && (
- linktype == AE_SYMLINK_TYPE_DIRECTORY ||
- *(p - 1) == L'\\' || (*(p - 1) == L'.' && (
- len == 1 || *(p - 2) == L'\\' || ( *(p - 2) == L'.' && (
- len == 2 || *(p - 3) == L'\\')))))) {
-#if defined(SYMBOLIC_LINK_FLAG_DIRECTORY)
- flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
-#else
- flags |= 0x1;
-#endif
- }
-
-#if defined(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE)
- newflags = flags | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
-#else
- newflags = flags | 0x2;
-#endif
-
- /*
- * Windows won't overwrite existing links
- */
- attrs = GetFileAttributesW(linkname);
- if (attrs != INVALID_FILE_ATTRIBUTES) {
- if (attrs & FILE_ATTRIBUTE_DIRECTORY)
- disk_rmdir(linkname);
- else
- disk_unlink(linkname);
- }
-
- ret = (*f)(linkname, ttarget, newflags);
- /*
- * Prior to Windows 10 calling CreateSymbolicLinkW() will fail
- * if SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE is set
- */
- if (!ret) {
- ret = (*f)(linkname, ttarget, flags);
- }
- free(ttarget);
- return (ret);
-}
-
-static int
-la_ftruncate(HANDLE handle, int64_t length)
-{
- LARGE_INTEGER distance;
-
- if (GetFileType(handle) != FILE_TYPE_DISK) {
- errno = EBADF;
- return (-1);
- }
- distance.QuadPart = length;
- if (!SetFilePointerEx_perso(handle, distance, NULL, FILE_BEGIN)) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- if (!SetEndOfFile(handle)) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- return (0);
-}
-
-static int
-lazy_stat(struct archive_write_disk *a)
-{
- if (a->pst != NULL) {
- /* Already have stat() data available. */
- return (ARCHIVE_OK);
- }
- if (a->fh != INVALID_HANDLE_VALUE &&
- GetFileInformationByHandle(a->fh, &a->st) == 0) {
- a->pst = &a->st;
- return (ARCHIVE_OK);
- }
-
- /*
- * XXX At this point, symlinks should not be hit, otherwise
- * XXX a race occurred. Do we want to check explicitly for that?
- */
- if (file_information(a, a->name, &a->st, NULL, 1) == 0) {
- a->pst = &a->st;
- return (ARCHIVE_OK);
- }
- archive_set_error(&a->archive, errno, "Couldn't stat file");
- return (ARCHIVE_WARN);
-}
-
-static const struct archive_vtable
-archive_write_disk_vtable = {
- .archive_close = _archive_write_disk_close,
- .archive_filter_bytes = _archive_write_disk_filter_bytes,
- .archive_free = _archive_write_disk_free,
- .archive_write_header = _archive_write_disk_header,
- .archive_write_finish_entry = _archive_write_disk_finish_entry,
- .archive_write_data = _archive_write_disk_data,
- .archive_write_data_block = _archive_write_disk_data_block,
-};
-
-static int64_t
-_archive_write_disk_filter_bytes(struct archive *_a, int n)
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
- (void)n; /* UNUSED */
- if (n == -1 || n == 0)
- return (a->total_bytes_written);
- return (-1);
-}
-
-
-int
-archive_write_disk_set_options(struct archive *_a, int flags)
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
-
- a->flags = flags;
- return (ARCHIVE_OK);
-}
-
-
-/*
- * Extract this entry to disk.
- *
- * TODO: Validate hardlinks. According to the standards, we're
- * supposed to check each extracted hardlink and squawk if it refers
- * to a file that we didn't restore. I'm not entirely convinced this
- * is a good idea, but more importantly: Is there any way to validate
- * hardlinks without keeping a complete list of filenames from the
- * entire archive?? Ugh.
- *
- */
-static int
-_archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
- struct fixup_entry *fe;
- int ret, r;
-
- archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
- "archive_write_disk_header");
- archive_clear_error(&a->archive);
- if (a->archive.state & ARCHIVE_STATE_DATA) {
- r = _archive_write_disk_finish_entry(&a->archive);
- if (r == ARCHIVE_FATAL)
- return (r);
- }
-
- /* Set up for this particular entry. */
- a->pst = NULL;
- a->current_fixup = NULL;
- a->deferred = 0;
- archive_entry_free(a->entry);
- a->entry = NULL;
- a->entry = archive_entry_clone(entry);
- a->fh = INVALID_HANDLE_VALUE;
- a->fd_offset = 0;
- a->offset = 0;
- a->restore_pwd = -1;
- a->uid = a->user_uid;
- a->mode = archive_entry_mode(a->entry);
- if (archive_entry_size_is_set(a->entry))
- a->filesize = archive_entry_size(a->entry);
- else
- a->filesize = -1;
- archive_wstrcpy(&(a->_name_data), archive_entry_pathname_w(a->entry));
- a->name = a->_name_data.s;
- archive_clear_error(&a->archive);
-
- /*
- * Clean up the requested path. This is necessary for correct
- * dir restores; the dir restore logic otherwise gets messed
- * up by nonsense like "dir/.".
- */
- ret = cleanup_pathname(a, a->name);
- if (ret != ARCHIVE_OK)
- return (ret);
-
- /*
- * Generate a full-pathname and use it from here.
- */
- if (permissive_name_w(a) < 0) {
- errno = EINVAL;
- return (ARCHIVE_FAILED);
- }
-
- /*
- * Query the umask so we get predictable mode settings.
- * This gets done on every call to _write_header in case the
- * user edits their umask during the extraction for some
- * reason.
- */
- umask(a->user_umask = umask(0));
-
- /* Figure out what we need to do for this entry. */
- a->todo = TODO_MODE_BASE;
- if (a->flags & ARCHIVE_EXTRACT_PERM) {
- a->todo |= TODO_MODE_FORCE; /* Be pushy about permissions. */
- /*
- * SGID requires an extra "check" step because we
- * cannot easily predict the GID that the system will
- * assign. (Different systems assign GIDs to files
- * based on a variety of criteria, including process
- * credentials and the gid of the enclosing
- * directory.) We can only restore the SGID bit if
- * the file has the right GID, and we only know the
- * GID if we either set it (see set_ownership) or if
- * we've actually called stat() on the file after it
- * was restored. Since there are several places at
- * which we might verify the GID, we need a TODO bit
- * to keep track.
- */
- if (a->mode & S_ISGID)
- a->todo |= TODO_SGID | TODO_SGID_CHECK;
- /*
- * Verifying the SUID is simpler, but can still be
- * done in multiple ways, hence the separate "check" bit.
- */
- if (a->mode & S_ISUID)
- a->todo |= TODO_SUID | TODO_SUID_CHECK;
- } else {
- /*
- * User didn't request full permissions, so don't
- * restore SUID, SGID bits and obey umask.
- */
- a->mode &= ~S_ISUID;
- a->mode &= ~S_ISGID;
- a->mode &= ~S_ISVTX;
- a->mode &= ~a->user_umask;
- }
-#if 0
- if (a->flags & ARCHIVE_EXTRACT_OWNER)
- a->todo |= TODO_OWNER;
-#endif
- if (a->flags & ARCHIVE_EXTRACT_TIME)
- a->todo |= TODO_TIMES;
- if (a->flags & ARCHIVE_EXTRACT_ACL) {
- if (archive_entry_filetype(a->entry) == AE_IFDIR)
- a->deferred |= TODO_ACLS;
- else
- a->todo |= TODO_ACLS;
- }
- if (a->flags & ARCHIVE_EXTRACT_XATTR)
- a->todo |= TODO_XATTR;
- if (a->flags & ARCHIVE_EXTRACT_FFLAGS)
- a->todo |= TODO_FFLAGS;
- if (a->flags & ARCHIVE_EXTRACT_SECURE_SYMLINKS) {
- ret = check_symlinks(a);
- if (ret != ARCHIVE_OK)
- return (ret);
- }
-
- ret = restore_entry(a);
-
- /*
- * TODO: There are rumours that some extended attributes must
- * be restored before file data is written. If this is true,
- * then we either need to write all extended attributes both
- * before and after restoring the data, or find some rule for
- * determining which must go first and which last. Due to the
- * many ways people are using xattrs, this may prove to be an
- * intractable problem.
- */
-
- /*
- * Fixup uses the unedited pathname from archive_entry_pathname(),
- * because it is relative to the base dir and the edited path
- * might be relative to some intermediate dir as a result of the
- * deep restore logic.
- */
- if (a->deferred & TODO_MODE) {
- fe = current_fixup(a, archive_entry_pathname_w(entry));
- fe->fixup |= TODO_MODE_BASE;
- fe->mode = a->mode;
- }
-
- if ((a->deferred & TODO_TIMES)
- && (archive_entry_mtime_is_set(entry)
- || archive_entry_atime_is_set(entry))) {
- fe = current_fixup(a, archive_entry_pathname_w(entry));
- fe->mode = a->mode;
- fe->fixup |= TODO_TIMES;
- if (archive_entry_atime_is_set(entry)) {
- fe->atime = archive_entry_atime(entry);
- fe->atime_nanos = archive_entry_atime_nsec(entry);
- } else {
- /* If atime is unset, use start time. */
- fe->atime = a->start_time;
- fe->atime_nanos = 0;
- }
- if (archive_entry_mtime_is_set(entry)) {
- fe->mtime = archive_entry_mtime(entry);
- fe->mtime_nanos = archive_entry_mtime_nsec(entry);
- } else {
- /* If mtime is unset, use start time. */
- fe->mtime = a->start_time;
- fe->mtime_nanos = 0;
- }
- if (archive_entry_birthtime_is_set(entry)) {
- fe->birthtime = archive_entry_birthtime(entry);
- fe->birthtime_nanos = archive_entry_birthtime_nsec(entry);
- } else {
- /* If birthtime is unset, use mtime. */
- fe->birthtime = fe->mtime;
- fe->birthtime_nanos = fe->mtime_nanos;
- }
- }
-
- if (a->deferred & TODO_ACLS) {
- fe = current_fixup(a, archive_entry_pathname_w(entry));
- archive_acl_copy(&fe->acl, archive_entry_acl(entry));
- }
-
- if (a->deferred & TODO_FFLAGS) {
- unsigned long set, clear;
-
- fe = current_fixup(a, archive_entry_pathname_w(entry));
- archive_entry_fflags(entry, &set, &clear);
- fe->fflags_set = set;
- }
-
- /*
- * On Windows, A creating sparse file requires a special mark.
- */
- if (a->fh != INVALID_HANDLE_VALUE &&
- archive_entry_sparse_count(entry) > 0) {
- int64_t base = 0, offset, length;
- int i, cnt = archive_entry_sparse_reset(entry);
- int sparse = 0;
-
- for (i = 0; i < cnt; i++) {
- archive_entry_sparse_next(entry, &offset, &length);
- if (offset - base >= 4096) {
- sparse = 1;/* we have a hole. */
- break;
- }
- base = offset + length;
- }
- if (sparse) {
- DWORD dmy;
- /* Mark this file as sparse. */
- DeviceIoControl(a->fh, FSCTL_SET_SPARSE,
- NULL, 0, NULL, 0, &dmy, NULL);
- }
- }
-
- /* We've created the object and are ready to pour data into it. */
- if (ret >= ARCHIVE_WARN)
- a->archive.state = ARCHIVE_STATE_DATA;
- /*
- * If it's not open, tell our client not to try writing.
- * In particular, dirs, links, etc, don't get written to.
- */
- if (a->fh == INVALID_HANDLE_VALUE) {
- archive_entry_set_size(entry, 0);
- a->filesize = 0;
- }
-
- return (ret);
-}
-
-int
-archive_write_disk_set_skip_file(struct archive *_a, la_int64_t d, la_int64_t i)
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
- archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_write_disk_set_skip_file");
- a->skip_file_set = 1;
- a->skip_file_dev = d;
- a->skip_file_ino = i;
- return (ARCHIVE_OK);
-}
-
-static ssize_t
-write_data_block(struct archive_write_disk *a, const char *buff, size_t size)
-{
- OVERLAPPED ol;
- uint64_t start_size = size;
- DWORD bytes_written = 0;
- ssize_t block_size = 0, bytes_to_write;
-
- if (size == 0)
- return (ARCHIVE_OK);
-
- if (a->filesize == 0 || a->fh == INVALID_HANDLE_VALUE) {
- archive_set_error(&a->archive, 0,
- "Attempt to write to an empty file");
- return (ARCHIVE_WARN);
- }
-
- if (a->flags & ARCHIVE_EXTRACT_SPARSE) {
- /* XXX TODO XXX Is there a more appropriate choice here ? */
- /* This needn't match the filesystem allocation size. */
- block_size = 16*1024;
- }
-
- /* If this write would run beyond the file size, truncate it. */
- if (a->filesize >= 0 && (int64_t)(a->offset + size) > a->filesize)
- start_size = size = (size_t)(a->filesize - a->offset);
-
- /* Write the data. */
- while (size > 0) {
- if (block_size == 0) {
- bytes_to_write = size;
- } else {
- /* We're sparsifying the file. */
- const char *p, *end;
- int64_t block_end;
-
- /* Skip leading zero bytes. */
- for (p = buff, end = buff + size; p < end; ++p) {
- if (*p != '\0')
- break;
- }
- a->offset += p - buff;
- size -= p - buff;
- buff = p;
- if (size == 0)
- break;
-
- /* Calculate next block boundary after offset. */
- block_end
- = (a->offset / block_size + 1) * block_size;
-
- /* If the adjusted write would cross block boundary,
- * truncate it to the block boundary. */
- bytes_to_write = size;
- if (a->offset + bytes_to_write > block_end)
- bytes_to_write = (DWORD)(block_end - a->offset);
- }
- memset(&ol, 0, sizeof(ol));
- ol.Offset = (DWORD)(a->offset & 0xFFFFFFFF);
- ol.OffsetHigh = (DWORD)(a->offset >> 32);
- if (!WriteFile(a->fh, buff, (uint32_t)bytes_to_write,
- &bytes_written, &ol)) {
- DWORD lasterr;
-
- lasterr = GetLastError();
- if (lasterr == ERROR_ACCESS_DENIED)
- errno = EBADF;
- else
- la_dosmaperr(lasterr);
- archive_set_error(&a->archive, errno, "Write failed");
- return (ARCHIVE_WARN);
- }
- buff += bytes_written;
- size -= bytes_written;
- a->total_bytes_written += bytes_written;
- a->offset += bytes_written;
- a->fd_offset = a->offset;
- }
- return ((ssize_t)(start_size - size));
-}
-
-static ssize_t
-_archive_write_disk_data_block(struct archive *_a,
- const void *buff, size_t size, int64_t offset)
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
- ssize_t r;
-
- archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_DATA, "archive_write_data_block");
-
- a->offset = offset;
- r = write_data_block(a, buff, size);
- if (r < ARCHIVE_OK)
- return (r);
- if ((size_t)r < size) {
- archive_set_error(&a->archive, 0,
- "Write request too large");
- return (ARCHIVE_WARN);
- }
-#if ARCHIVE_VERSION_NUMBER < 3999000
- return (ARCHIVE_OK);
-#else
- return (size);
-#endif
-}
-
-static ssize_t
-_archive_write_disk_data(struct archive *_a, const void *buff, size_t size)
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
-
- archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_DATA, "archive_write_data");
-
- return (write_data_block(a, buff, size));
-}
-
-static int
-_archive_write_disk_finish_entry(struct archive *_a)
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
- int ret = ARCHIVE_OK;
-
- archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
- "archive_write_finish_entry");
- if (a->archive.state & ARCHIVE_STATE_HEADER)
- return (ARCHIVE_OK);
- archive_clear_error(&a->archive);
-
- /* Pad or truncate file to the right size. */
- if (a->fh == INVALID_HANDLE_VALUE) {
- /* There's no file. */
- } else if (a->filesize < 0) {
- /* File size is unknown, so we can't set the size. */
- } else if (a->fd_offset == a->filesize) {
- /* Last write ended at exactly the filesize; we're done. */
- /* Hopefully, this is the common case. */
- } else {
- if (la_ftruncate(a->fh, a->filesize) == -1) {
- archive_set_error(&a->archive, errno,
- "File size could not be restored");
- CloseHandle(a->fh);
- a->fh = INVALID_HANDLE_VALUE;
- return (ARCHIVE_FAILED);
- }
- }
-
- /* Restore metadata. */
-
- /*
- * Look up the "real" UID only if we're going to need it.
- * TODO: the TODO_SGID condition can be dropped here, can't it?
- */
- if (a->todo & (TODO_OWNER | TODO_SUID | TODO_SGID)) {
- a->uid = archive_write_disk_uid(&a->archive,
- archive_entry_uname(a->entry),
- archive_entry_uid(a->entry));
- }
- /* Look up the "real" GID only if we're going to need it. */
- /* TODO: the TODO_SUID condition can be dropped here, can't it? */
- if (a->todo & (TODO_OWNER | TODO_SGID | TODO_SUID)) {
- a->gid = archive_write_disk_gid(&a->archive,
- archive_entry_gname(a->entry),
- archive_entry_gid(a->entry));
- }
-
- /*
- * Restore ownership before set_mode tries to restore suid/sgid
- * bits. If we set the owner, we know what it is and can skip
- * a stat() call to examine the ownership of the file on disk.
- */
- if (a->todo & TODO_OWNER)
- ret = set_ownership(a);
-
- /*
- * set_mode must precede ACLs on systems such as Solaris and
- * FreeBSD where setting the mode implicitly clears extended ACLs
- */
- if (a->todo & TODO_MODE) {
- int r2 = set_mode(a, a->mode);
- if (r2 < ret) ret = r2;
- }
-
- /*
- * Security-related extended attributes (such as
- * security.capability on Linux) have to be restored last,
- * since they're implicitly removed by other file changes.
- */
- if (a->todo & TODO_XATTR) {
- int r2 = set_xattrs(a);
- if (r2 < ret) ret = r2;
- }
-
- /*
- * Some flags prevent file modification; they must be restored after
- * file contents are written.
- */
- if (a->todo & TODO_FFLAGS) {
- int r2 = set_fflags(a);
- if (r2 < ret) ret = r2;
- }
-
- /*
- * Time must follow most other metadata;
- * otherwise atime will get changed.
- */
- if (a->todo & TODO_TIMES) {
- int r2 = set_times_from_entry(a);
- if (r2 < ret) ret = r2;
- }
-
- /*
- * ACLs must be restored after timestamps because there are
- * ACLs that prevent attribute changes (including time).
- */
- if (a->todo & TODO_ACLS) {
- int r2 = set_acls(a, a->fh,
- archive_entry_pathname_w(a->entry),
- archive_entry_acl(a->entry));
- if (r2 < ret) ret = r2;
- }
-
- /* If there's an fd, we can close it now. */
- if (a->fh != INVALID_HANDLE_VALUE) {
- CloseHandle(a->fh);
- a->fh = INVALID_HANDLE_VALUE;
- if (a->tmpname) {
- /* Windows does not support atomic rename */
- disk_unlink(a->name);
- if (_wrename(a->tmpname, a->name) != 0) {
- la_dosmaperr(GetLastError());
- archive_set_error(&a->archive, errno,
- "Failed to rename temporary file");
- ret = ARCHIVE_FAILED;
- disk_unlink(a->tmpname);
- }
- a->tmpname = NULL;
- }
- }
- /* If there's an entry, we can release it now. */
- archive_entry_free(a->entry);
- a->entry = NULL;
- a->archive.state = ARCHIVE_STATE_HEADER;
- return (ret);
-}
-
-int
-archive_write_disk_set_group_lookup(struct archive *_a,
- void *private_data,
- la_int64_t (*lookup_gid)(void *private, const char *gname, la_int64_t gid),
- void (*cleanup_gid)(void *private))
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
- archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_write_disk_set_group_lookup");
-
- if (a->cleanup_gid != NULL && a->lookup_gid_data != NULL)
- (a->cleanup_gid)(a->lookup_gid_data);
-
- a->lookup_gid = lookup_gid;
- a->cleanup_gid = cleanup_gid;
- a->lookup_gid_data = private_data;
- return (ARCHIVE_OK);
-}
-
-int
-archive_write_disk_set_user_lookup(struct archive *_a,
- void *private_data,
- int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid),
- void (*cleanup_uid)(void *private))
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
- archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_write_disk_set_user_lookup");
-
- if (a->cleanup_uid != NULL && a->lookup_uid_data != NULL)
- (a->cleanup_uid)(a->lookup_uid_data);
-
- a->lookup_uid = lookup_uid;
- a->cleanup_uid = cleanup_uid;
- a->lookup_uid_data = private_data;
- return (ARCHIVE_OK);
-}
-
-int64_t
-archive_write_disk_gid(struct archive *_a, const char *name, la_int64_t id)
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
- archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_write_disk_gid");
- if (a->lookup_gid)
- return (a->lookup_gid)(a->lookup_gid_data, name, id);
- return (id);
-}
-
-int64_t
-archive_write_disk_uid(struct archive *_a, const char *name, la_int64_t id)
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
- archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_write_disk_uid");
- if (a->lookup_uid)
- return (a->lookup_uid)(a->lookup_uid_data, name, id);
- return (id);
-}
-
-/*
- * Create a new archive_write_disk object and initialize it with global state.
- */
-struct archive *
-archive_write_disk_new(void)
-{
- struct archive_write_disk *a;
-
- a = (struct archive_write_disk *)calloc(1, sizeof(*a));
- if (a == NULL)
- return (NULL);
- a->archive.magic = ARCHIVE_WRITE_DISK_MAGIC;
- /* We're ready to write a header immediately. */
- a->archive.state = ARCHIVE_STATE_HEADER;
- a->archive.vtable = &archive_write_disk_vtable;
- a->start_time = time(NULL);
- /* Query and restore the umask. */
- umask(a->user_umask = umask(0));
- if (archive_wstring_ensure(&a->path_safe, 512) == NULL) {
- free(a);
- return (NULL);
- }
- a->path_safe.s[0] = 0;
- return (&a->archive);
-}
-
-static int
-disk_unlink(const wchar_t *path)
-{
- wchar_t *fullname;
- int r;
-
- r = _wunlink(path);
- if (r != 0 && GetLastError() == ERROR_INVALID_NAME) {
- fullname = __la_win_permissive_name_w(path);
- r = _wunlink(fullname);
- free(fullname);
- }
- return (r);
-}
-
-static int
-disk_rmdir(const wchar_t *path)
-{
- wchar_t *fullname;
- int r;
-
- r = _wrmdir(path);
- if (r != 0 && GetLastError() == ERROR_INVALID_NAME) {
- fullname = __la_win_permissive_name_w(path);
- r = _wrmdir(fullname);
- free(fullname);
- }
- return (r);
-}
-
-/*
- * The main restore function.
- */
-static int
-restore_entry(struct archive_write_disk *a)
-{
- int ret = ARCHIVE_OK, en;
-
- if (a->flags & ARCHIVE_EXTRACT_UNLINK && !S_ISDIR(a->mode)) {
- /*
- * TODO: Fix this. Apparently, there are platforms
- * that still allow root to hose the entire filesystem
- * by unlinking a dir. The S_ISDIR() test above
- * prevents us from using unlink() here if the new
- * object is a dir, but that doesn't mean the old
- * object isn't a dir.
- */
- if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS)
- (void)clear_nochange_fflags(a);
- if (disk_unlink(a->name) == 0) {
- /* We removed it, reset cached stat. */
- a->pst = NULL;
- } else if (errno == ENOENT) {
- /* File didn't exist, that's just as good. */
- } else if (disk_rmdir(a->name) == 0) {
- /* It was a dir, but now it's gone. */
- a->pst = NULL;
- } else {
- /* We tried, but couldn't get rid of it. */
- archive_set_error(&a->archive, errno,
- "Could not unlink");
- return(ARCHIVE_FAILED);
- }
- }
-
- /* Try creating it first; if this fails, we'll try to recover. */
- en = create_filesystem_object(a);
-
- if ((en == ENOTDIR || en == ENOENT)
- && !(a->flags & ARCHIVE_EXTRACT_NO_AUTODIR)) {
- wchar_t *full;
- /* If the parent dir doesn't exist, try creating it. */
- create_parent_dir(a, a->name);
- /* Now try to create the object again. */
- full = __la_win_permissive_name_w(a->name);
- if (full == NULL) {
- en = EINVAL;
- } else {
- /* Remove multiple directories such as "a/../b../c" */
- archive_wstrcpy(&(a->_name_data), full);
- a->name = a->_name_data.s;
- free(full);
- en = create_filesystem_object(a);
- }
- }
-
- if ((en == ENOENT) && (archive_entry_hardlink(a->entry) != NULL)) {
- archive_set_error(&a->archive, en,
- "Hard-link target '%s' does not exist.",
- archive_entry_hardlink(a->entry));
- return (ARCHIVE_FAILED);
- }
-
- if ((en == EISDIR || en == EEXIST)
- && (a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
- /* If we're not overwriting, we're done. */
- if (S_ISDIR(a->mode)) {
- /* Don't overwrite any settings on existing directories. */
- a->todo = 0;
- }
- archive_entry_unset_size(a->entry);
- return (ARCHIVE_OK);
- }
-
- /*
- * Some platforms return EISDIR if you call
- * open(O_WRONLY | O_EXCL | O_CREAT) on a directory, some
- * return EEXIST. POSIX is ambiguous, requiring EISDIR
- * for open(O_WRONLY) on a dir and EEXIST for open(O_EXCL | O_CREAT)
- * on an existing item.
- */
- if (en == EISDIR) {
- /* A dir is in the way of a non-dir, rmdir it. */
- if (disk_rmdir(a->name) != 0) {
- archive_set_error(&a->archive, errno,
- "Can't remove already-existing dir");
- return (ARCHIVE_FAILED);
- }
- a->pst = NULL;
- /* Try again. */
- en = create_filesystem_object(a);
- } else if (en == EEXIST) {
- mode_t st_mode;
- mode_t lst_mode;
- BY_HANDLE_FILE_INFORMATION lst;
- /*
- * We know something is in the way, but we don't know what;
- * we need to find out before we go any further.
- */
- int r = 0;
- int dirlnk = 0;
-
- /*
- * The SECURE_SYMLINK logic has already removed a
- * symlink to a dir if the client wants that. So
- * follow the symlink if we're creating a dir.
- * If it's not a dir (or it's a broken symlink),
- * then don't follow it.
- *
- * Windows distinguishes file and directory symlinks.
- * A file symlink may erroneously point to a directory
- * and a directory symlink to a file. Windows does not follow
- * such symlinks. We always need both source and target
- * information.
- */
- r = file_information(a, a->name, &lst, &lst_mode, 1);
- if (r != 0) {
- archive_set_error(&a->archive, errno,
- "Can't stat existing object");
- return (ARCHIVE_FAILED);
- } else if (S_ISLNK(lst_mode)) {
- if (lst.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- dirlnk = 1;
- /* In case of a symlink we need target information */
- r = file_information(a, a->name, &a->st, &st_mode, 0);
- if (r != 0) {
- a->st = lst;
- st_mode = lst_mode;
- }
- } else {
- a->st = lst;
- st_mode = lst_mode;
- }
-
- /*
- * NO_OVERWRITE_NEWER doesn't apply to directories.
- */
- if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER)
- && !S_ISDIR(st_mode)) {
- if (!older(&(a->st), a->entry)) {
- archive_entry_unset_size(a->entry);
- return (ARCHIVE_OK);
- }
- }
-
- /* If it's our archive, we're done. */
- if (a->skip_file_set &&
- bhfi_dev(&a->st) == a->skip_file_dev &&
- bhfi_ino(&a->st) == a->skip_file_ino) {
- archive_set_error(&a->archive, 0,
- "Refusing to overwrite archive");
- return (ARCHIVE_FAILED);
- }
-
- if (!S_ISDIR(st_mode)) {
- if (a->flags &
- ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS) {
- (void)clear_nochange_fflags(a);
- }
- if ((a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) &&
- S_ISREG(st_mode)) {
- int fd = la_mktemp(a);
-
- if (fd == -1) {
- la_dosmaperr(GetLastError());
- archive_set_error(&a->archive, errno,
- "Can't create temporary file");
- return (ARCHIVE_FAILED);
- }
- a->fh = (HANDLE)_get_osfhandle(fd);
- if (a->fh == INVALID_HANDLE_VALUE) {
- la_dosmaperr(GetLastError());
- return (ARCHIVE_FAILED);
- }
- a->pst = NULL;
- en = 0;
- } else {
- if (dirlnk) {
- /* Edge case: dir symlink pointing
- * to a file */
- if (disk_rmdir(a->name) != 0) {
- archive_set_error(&a->archive,
- errno, "Can't unlink "
- "directory symlink");
- return (ARCHIVE_FAILED);
- }
- } else {
- if (disk_unlink(a->name) != 0) {
- /* A non-dir is in the way,
- * unlink it. */
- archive_set_error(&a->archive,
- errno, "Can't unlink "
- "already-existing object");
- return (ARCHIVE_FAILED);
- }
- }
- a->pst = NULL;
- /* Try again. */
- en = create_filesystem_object(a);
- }
- } else if (!S_ISDIR(a->mode)) {
- /* A dir is in the way of a non-dir, rmdir it. */
- if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS)
- (void)clear_nochange_fflags(a);
- if (disk_rmdir(a->name) != 0) {
- archive_set_error(&a->archive, errno,
- "Can't remove already-existing dir");
- return (ARCHIVE_FAILED);
- }
- /* Try again. */
- en = create_filesystem_object(a);
- } else {
- /*
- * There's a dir in the way of a dir. Don't
- * waste time with rmdir()/mkdir(), just fix
- * up the permissions on the existing dir.
- * Note that we don't change perms on existing
- * dirs unless _EXTRACT_PERM is specified.
- */
- if ((a->mode != st_mode)
- && (a->todo & TODO_MODE_FORCE))
- a->deferred |= (a->todo & TODO_MODE);
- /* Ownership doesn't need deferred fixup. */
- en = 0; /* Forget the EEXIST. */
- }
- }
-
- if (en) {
- /* Everything failed; give up here. */
- archive_set_error(&a->archive, en, "Can't create '%ls'",
- a->name);
- return (ARCHIVE_FAILED);
- }
-
- a->pst = NULL; /* Cached stat data no longer valid. */
- return (ret);
-}
-
-/*
- * Returns 0 if creation succeeds, or else returns errno value from
- * the failed system call. Note: This function should only ever perform
- * a single system call.
- */
-static int
-create_filesystem_object(struct archive_write_disk *a)
-{
- /* Create the entry. */
- const wchar_t *linkname;
- wchar_t *fullname;
- mode_t final_mode, mode;
- int r;
- DWORD attrs = 0;
-# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- CREATEFILE2_EXTENDED_PARAMETERS createExParams;
-#endif
-
- /* We identify hard/symlinks according to the link names. */
- /* Since link(2) and symlink(2) don't handle modes, we're done here. */
- linkname = archive_entry_hardlink_w(a->entry);
- if (linkname != NULL) {
- wchar_t *linksanitized, *linkfull, *namefull;
- size_t l = (wcslen(linkname) + 1) * sizeof(wchar_t);
- linksanitized = malloc(l);
- if (linksanitized == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for hardlink target");
- return (-1);
- }
- memcpy(linksanitized, linkname, l);
- r = cleanup_pathname(a, linksanitized);
- if (r != ARCHIVE_OK) {
- free(linksanitized);
- return (r);
- }
- linkfull = __la_win_permissive_name_w(linksanitized);
- free(linksanitized);
- namefull = __la_win_permissive_name_w(a->name);
- if (linkfull == NULL || namefull == NULL) {
- errno = EINVAL;
- r = -1;
- } else {
- /*
- * Unlinking and linking here is really not atomic,
- * but doing it right, would require us to construct
- * an mktemplink() function, and then use _wrename().
- */
- if (a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) {
- attrs = GetFileAttributesW(namefull);
- if (attrs != INVALID_FILE_ATTRIBUTES) {
- if (attrs & FILE_ATTRIBUTE_DIRECTORY)
- disk_rmdir(namefull);
- else
- disk_unlink(namefull);
- }
- }
- r = la_CreateHardLinkW(namefull, linkfull);
- if (r == 0) {
- la_dosmaperr(GetLastError());
- r = errno;
- } else
- r = 0;
- }
- /*
- * New cpio and pax formats allow hardlink entries
- * to carry data, so we may have to open the file
- * for hardlink entries.
- *
- * If the hardlink was successfully created and
- * the archive doesn't have carry data for it,
- * consider it to be non-authoritative for meta data.
- * This is consistent with GNU tar and BSD pax.
- * If the hardlink does carry data, let the last
- * archive entry decide ownership.
- */
- if (r == 0 && a->filesize <= 0) {
- a->todo = 0;
- a->deferred = 0;
- } else if (r == 0 && a->filesize > 0) {
-# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- ZeroMemory(&createExParams, sizeof(createExParams));
- createExParams.dwSize = sizeof(createExParams);
- createExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
- a->fh = CreateFile2(namefull, GENERIC_WRITE, 0,
- TRUNCATE_EXISTING, &createExParams);
-#else
- a->fh = CreateFileW(namefull, GENERIC_WRITE, 0, NULL,
- TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-#endif
- if (a->fh == INVALID_HANDLE_VALUE) {
- la_dosmaperr(GetLastError());
- r = errno;
- }
- }
- free(linkfull);
- free(namefull);
- return (r);
- }
- linkname = archive_entry_symlink_w(a->entry);
- if (linkname != NULL) {
- /*
- * Unlinking and linking here is really not atomic,
- * but doing it right, would require us to construct
- * an mktemplink() function, and then use _wrename().
- */
- attrs = GetFileAttributesW(a->name);
- if (attrs != INVALID_FILE_ATTRIBUTES) {
- if (attrs & FILE_ATTRIBUTE_DIRECTORY)
- disk_rmdir(a->name);
- else
- disk_unlink(a->name);
- }
-#if HAVE_SYMLINK
- return symlink(linkname, a->name) ? errno : 0;
-#else
- errno = 0;
- r = la_CreateSymbolicLinkW((const wchar_t *)a->name, linkname,
- archive_entry_symlink_type(a->entry));
- if (r == 0) {
- if (errno == 0)
- la_dosmaperr(GetLastError());
- r = errno;
- } else
- r = 0;
- return (r);
-#endif
- }
-
- /*
- * The remaining system calls all set permissions, so let's
- * try to take advantage of that to avoid an extra chmod()
- * call. (Recall that umask is set to zero right now!)
- */
-
- /* Mode we want for the final restored object (w/o file type bits). */
- final_mode = a->mode & 07777;
- /*
- * The mode that will actually be restored in this step. Note
- * that SUID, SGID, etc, require additional work to ensure
- * security, so we never restore them at this point.
- */
- mode = final_mode & 0777 & ~a->user_umask;
-
- switch (a->mode & AE_IFMT) {
- default:
- /* POSIX requires that we fall through here. */
- /* FALLTHROUGH */
- case AE_IFREG:
- a->tmpname = NULL;
- fullname = a->name;
- /* O_WRONLY | O_CREAT | O_EXCL */
-# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- ZeroMemory(&createExParams, sizeof(createExParams));
- createExParams.dwSize = sizeof(createExParams);
- createExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
- a->fh = CreateFile2(fullname, GENERIC_WRITE, 0,
- CREATE_NEW, &createExParams);
-#else
- a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
- CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
-#endif
- if (a->fh == INVALID_HANDLE_VALUE &&
- GetLastError() == ERROR_INVALID_NAME &&
- fullname == a->name) {
- fullname = __la_win_permissive_name_w(a->name);
-# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- a->fh = CreateFile2(fullname, GENERIC_WRITE, 0,
- CREATE_NEW, &createExParams);
-#else
- a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
- CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
-#endif
- }
- if (a->fh == INVALID_HANDLE_VALUE) {
- if (GetLastError() == ERROR_ACCESS_DENIED) {
- DWORD attr;
- /* Simulate an errno of POSIX system. */
- attr = GetFileAttributesW(fullname);
- if (attr == (DWORD)-1)
- la_dosmaperr(GetLastError());
- else if (attr & FILE_ATTRIBUTE_DIRECTORY)
- errno = EISDIR;
- else
- errno = EACCES;
- } else
- la_dosmaperr(GetLastError());
- r = 1;
- } else
- r = 0;
- if (fullname != a->name)
- free(fullname);
- break;
- case AE_IFCHR:
- case AE_IFBLK:
- /* TODO: Find a better way to warn about our inability
- * to restore a block device node. */
- return (EINVAL);
- case AE_IFDIR:
- mode = (mode | MINIMUM_DIR_MODE) & MAXIMUM_DIR_MODE;
- fullname = a->name;
- r = CreateDirectoryW(fullname, NULL);
- if (r == 0 && GetLastError() == ERROR_INVALID_NAME &&
- fullname == a->name) {
- fullname = __la_win_permissive_name_w(a->name);
- r = CreateDirectoryW(fullname, NULL);
- }
- if (r != 0) {
- r = 0;
- /* Defer setting dir times. */
- a->deferred |= (a->todo & TODO_TIMES);
- a->todo &= ~TODO_TIMES;
- /* Never use an immediate chmod(). */
- /* We can't avoid the chmod() entirely if EXTRACT_PERM
- * because of SysV SGID inheritance. */
- if ((mode != final_mode)
- || (a->flags & ARCHIVE_EXTRACT_PERM))
- a->deferred |= (a->todo & TODO_MODE);
- a->todo &= ~TODO_MODE;
- } else {
- la_dosmaperr(GetLastError());
- r = -1;
- }
- if (fullname != a->name)
- free(fullname);
- break;
- case AE_IFIFO:
- /* TODO: Find a better way to warn about our inability
- * to restore a fifo. */
- return (EINVAL);
- }
-
- /* All the system calls above set errno on failure. */
- if (r)
- return (errno);
-
- /* If we managed to set the final mode, we've avoided a chmod(). */
- if (mode == final_mode)
- a->todo &= ~TODO_MODE;
- return (0);
-}
-
-/*
- * Cleanup function for archive_extract. Mostly, this involves processing
- * the fixup list, which is used to address a number of problems:
- * * Dir permissions might prevent us from restoring a file in that
- * dir, so we restore the dir with minimum 0700 permissions first,
- * then correct the mode at the end.
- * * Similarly, the act of restoring a file touches the directory
- * and changes the timestamp on the dir, so we have to touch-up dir
- * timestamps at the end as well.
- * * Some file flags can interfere with the restore by, for example,
- * preventing the creation of hardlinks to those files.
- * * Mac OS extended metadata includes ACLs, so must be deferred on dirs.
- *
- * Note that tar/cpio do not require that archives be in a particular
- * order; there is no way to know when the last file has been restored
- * within a directory, so there's no way to optimize the memory usage
- * here by fixing up the directory any earlier than the
- * end-of-archive.
- *
- * XXX TODO: Directory ACLs should be restored here, for the same
- * reason we set directory perms here. XXX
- */
-static int
-_archive_write_disk_close(struct archive *_a)
-{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
- struct fixup_entry *next, *p;
- int ret;
-
- archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
- "archive_write_disk_close");
- ret = _archive_write_disk_finish_entry(&a->archive);
-
- /* Sort dir list so directories are fixed up in depth-first order. */
- p = sort_dir_list(a->fixup_list);
-
- while (p != NULL) {
- a->pst = NULL; /* Mark stat cache as out-of-date. */
- if (p->fixup & TODO_TIMES) {
- set_times(a, INVALID_HANDLE_VALUE, p->mode, p->name,
- p->atime, p->atime_nanos,
- p->birthtime, p->birthtime_nanos,
- p->mtime, p->mtime_nanos,
- p->ctime, p->ctime_nanos);
- }
- if (p->fixup & TODO_MODE_BASE)
- la_chmod(p->name, p->mode);
- if (p->fixup & TODO_ACLS)
- set_acls(a, INVALID_HANDLE_VALUE, p->name, &p->acl);
- if (p->fixup & TODO_FFLAGS)
- set_fflags_platform(p->name, p->fflags_set, 0);
- next = p->next;
- archive_acl_clear(&p->acl);
- free(p->name);
- free(p);
- p = next;
- }
- a->fixup_list = NULL;
- return (ret);
-}
-
-static int
-_archive_write_disk_free(struct archive *_a)
-{
- struct archive_write_disk *a;
- int ret;
- if (_a == NULL)
- return (ARCHIVE_OK);
- archive_check_magic(_a, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_disk_free");
- a = (struct archive_write_disk *)_a;
- ret = _archive_write_disk_close(&a->archive);
- archive_write_disk_set_group_lookup(&a->archive, NULL, NULL, NULL);
- archive_write_disk_set_user_lookup(&a->archive, NULL, NULL, NULL);
- archive_entry_free(a->entry);
- archive_wstring_free(&a->_name_data);
- archive_wstring_free(&a->_tmpname_data);
- archive_string_free(&a->archive.error_string);
- archive_wstring_free(&a->path_safe);
- a->archive.magic = 0;
- __archive_clean(&a->archive);
- free(a);
- return (ret);
-}
-
-/*
- * Simple O(n log n) merge sort to order the fixup list. In
- * particular, we want to restore dir timestamps depth-first.
- */
-static struct fixup_entry *
-sort_dir_list(struct fixup_entry *p)
-{
- struct fixup_entry *a, *b, *t;
-
- if (p == NULL)
- return (NULL);
- /* A one-item list is already sorted. */
- if (p->next == NULL)
- return (p);
-
- /* Step 1: split the list. */
- t = p;
- a = p->next->next;
- while (a != NULL) {
- /* Step a twice, t once. */
- a = a->next;
- if (a != NULL)
- a = a->next;
- t = t->next;
- }
- /* Now, t is at the mid-point, so break the list here. */
- b = t->next;
- t->next = NULL;
- a = p;
-
- /* Step 2: Recursively sort the two sub-lists. */
- a = sort_dir_list(a);
- b = sort_dir_list(b);
-
- /* Step 3: Merge the returned lists. */
- /* Pick the first element for the merged list. */
- if (wcscmp(a->name, b->name) > 0) {
- t = p = a;
- a = a->next;
- } else {
- t = p = b;
- b = b->next;
- }
-
- /* Always put the later element on the list first. */
- while (a != NULL && b != NULL) {
- if (wcscmp(a->name, b->name) > 0) {
- t->next = a;
- a = a->next;
- } else {
- t->next = b;
- b = b->next;
- }
- t = t->next;
- }
-
- /* Only one list is non-empty, so just splice it on. */
- if (a != NULL)
- t->next = a;
- if (b != NULL)
- t->next = b;
-
- return (p);
-}
-
-/*
- * Returns a new, initialized fixup entry.
- *
- * TODO: Reduce the memory requirements for this list by using a tree
- * structure rather than a simple list of names.
- */
-static struct fixup_entry *
-new_fixup(struct archive_write_disk *a, const wchar_t *pathname)
-{
- struct fixup_entry *fe;
-
- fe = (struct fixup_entry *)calloc(1, sizeof(struct fixup_entry));
- if (fe == NULL)
- return (NULL);
- fe->next = a->fixup_list;
- a->fixup_list = fe;
- fe->fixup = 0;
- fe->name = _wcsdup(pathname);
- fe->fflags_set = 0;
- return (fe);
-}
-
-/*
- * Returns a fixup structure for the current entry.
- */
-static struct fixup_entry *
-current_fixup(struct archive_write_disk *a, const wchar_t *pathname)
-{
- if (a->current_fixup == NULL)
- a->current_fixup = new_fixup(a, pathname);
- return (a->current_fixup);
-}
-
-/*
- * TODO: The deep-directory support bypasses this; disable deep directory
- * support if we're doing symlink checks.
- */
-/*
- * TODO: Someday, integrate this with the deep dir support; they both
- * scan the path and both can be optimized by comparing against other
- * recent paths.
- */
-static int
-check_symlinks(struct archive_write_disk *a)
-{
- wchar_t *pn, *p;
- wchar_t c;
- int r;
- BY_HANDLE_FILE_INFORMATION st;
- mode_t st_mode;
-
- /*
- * Guard against symlink tricks. Reject any archive entry whose
- * destination would be altered by a symlink.
- */
- /* Whatever we checked last time doesn't need to be re-checked. */
- pn = a->name;
- p = a->path_safe.s;
- while ((*pn != '\0') && (*p == *pn))
- ++p, ++pn;
- /* Skip leading backslashes */
- while (*pn == '\\')
- ++pn;
- c = pn[0];
- /* Keep going until we've checked the entire name. */
- while (pn[0] != '\0' && (pn[0] != '\\' || pn[1] != '\0')) {
- /* Skip the next path element. */
- while (*pn != '\0' && *pn != '\\')
- ++pn;
- c = pn[0];
- pn[0] = '\0';
- /* Check that we haven't hit a symlink. */
- r = file_information(a, a->name, &st, &st_mode, 1);
- if (r != 0) {
- /* We've hit a dir that doesn't exist; stop now. */
- if (errno == ENOENT)
- break;
- } else if (S_ISLNK(st_mode)) {
- if (c == '\0') {
- /*
- * Last element is a file or directory symlink.
- * Remove it so we can overwrite it with the
- * item being extracted.
- */
- if (a->flags &
- ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS) {
- (void)clear_nochange_fflags(a);
- }
- if (st.dwFileAttributes &
- FILE_ATTRIBUTE_DIRECTORY) {
- r = disk_rmdir(a->name);
- } else {
- r = disk_unlink(a->name);
- }
- if (r) {
- archive_set_error(&a->archive, errno,
- "Could not remove symlink %ls",
- a->name);
- pn[0] = c;
- return (ARCHIVE_FAILED);
- }
- a->pst = NULL;
- /*
- * Even if we did remove it, a warning
- * is in order. The warning is silly,
- * though, if we're just replacing one
- * symlink with another symlink.
- */
- if (!S_ISLNK(a->mode)) {
- archive_set_error(&a->archive, 0,
- "Removing symlink %ls",
- a->name);
- }
- /* Symlink gone. No more problem! */
- pn[0] = c;
- return (0);
- } else if (a->flags & ARCHIVE_EXTRACT_UNLINK) {
- /* User asked us to remove problems. */
- if (a->flags &
- ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS) {
- (void)clear_nochange_fflags(a);
- }
- if (st.dwFileAttributes &
- FILE_ATTRIBUTE_DIRECTORY) {
- r = disk_rmdir(a->name);
- } else {
- r = disk_unlink(a->name);
- }
- if (r != 0) {
- archive_set_error(&a->archive, 0,
- "Cannot remove intervening "
- "symlink %ls", a->name);
- pn[0] = c;
- return (ARCHIVE_FAILED);
- }
- a->pst = NULL;
- } else {
- archive_set_error(&a->archive, 0,
- "Cannot extract through symlink %ls",
- a->name);
- pn[0] = c;
- return (ARCHIVE_FAILED);
- }
- }
- if (!c)
- break;
- pn[0] = c;
- pn++;
- }
- pn[0] = c;
- /* We've checked and/or cleaned the whole path, so remember it. */
- archive_wstrcpy(&a->path_safe, a->name);
- return (ARCHIVE_OK);
-}
-
-static int
-guidword(wchar_t *p, int n)
-{
- int i;
-
- for (i = 0; i < n; i++) {
- if ((*p >= L'0' && *p <= L'9') ||
- (*p >= L'a' && *p <= L'f') ||
- (*p >= L'A' && *p <= L'F'))
- p++;
- else
- return (-1);
- }
- return (0);
-}
-
-/*
- * Canonicalize the pathname. In particular, this strips duplicate
- * '\' characters, '.' elements, and trailing '\'. It also raises an
- * error for an empty path, a trailing '..' or (if _SECURE_NODOTDOT is
- * set) any '..' in the path.
- */
-static int
-cleanup_pathname(struct archive_write_disk *a, wchar_t *name)
-{
- wchar_t *dest, *src, *p, *top;
- wchar_t separator = L'\0';
-
- p = name;
- if (*p == L'\0') {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Invalid empty pathname");
- return (ARCHIVE_FAILED);
- }
-
- /* Replace '/' by '\' */
- for (; *p != L'\0'; p++) {
- if (*p == L'/')
- *p = L'\\';
- }
- p = name;
-
- /* Skip leading "\\.\" or "\\?\" or "\\?\UNC\" or
- * "\\?\Volume{GUID}\"
- * (absolute path prefixes used by Windows API) */
- if (p[0] == L'\\' && p[1] == L'\\' &&
- (p[2] == L'.' || p[2] == L'?') && p[3] == L'\\')
- {
- /* A path begin with "\\?\UNC\" */
- if (p[2] == L'?' &&
- (p[4] == L'U' || p[4] == L'u') &&
- (p[5] == L'N' || p[5] == L'n') &&
- (p[6] == L'C' || p[6] == L'c') &&
- p[7] == L'\\')
- p += 8;
- /* A path begin with "\\?\Volume{GUID}\" */
- else if (p[2] == L'?' &&
- (p[4] == L'V' || p[4] == L'v') &&
- (p[5] == L'O' || p[5] == L'o') &&
- (p[6] == L'L' || p[6] == L'l') &&
- (p[7] == L'U' || p[7] == L'u') &&
- (p[8] == L'M' || p[8] == L'm') &&
- (p[9] == L'E' || p[9] == L'e') &&
- p[10] == L'{') {
- if (guidword(p+11, 8) == 0 && p[19] == L'-' &&
- guidword(p+20, 4) == 0 && p[24] == L'-' &&
- guidword(p+25, 4) == 0 && p[29] == L'-' &&
- guidword(p+30, 4) == 0 && p[34] == L'-' &&
- guidword(p+35, 12) == 0 && p[47] == L'}' &&
- p[48] == L'\\')
- p += 49;
- else
- p += 4;
- /* A path begin with "\\.\PhysicalDriveX" */
- } else if (p[2] == L'.' &&
- (p[4] == L'P' || p[4] == L'p') &&
- (p[5] == L'H' || p[5] == L'h') &&
- (p[6] == L'Y' || p[6] == L'y') &&
- (p[7] == L'S' || p[7] == L's') &&
- (p[8] == L'I' || p[8] == L'i') &&
- (p[9] == L'C' || p[9] == L'c') &&
- (p[9] == L'A' || p[9] == L'a') &&
- (p[9] == L'L' || p[9] == L'l') &&
- (p[9] == L'D' || p[9] == L'd') &&
- (p[9] == L'R' || p[9] == L'r') &&
- (p[9] == L'I' || p[9] == L'i') &&
- (p[9] == L'V' || p[9] == L'v') &&
- (p[9] == L'E' || p[9] == L'e') &&
- (p[10] >= L'0' && p[10] <= L'9') &&
- p[11] == L'\0') {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Path is a physical drive name");
- return (ARCHIVE_FAILED);
- } else
- p += 4;
- /* Network drive path like "\\<server-name>\<share-name>\file" */
- } else if (p[0] == L'\\' && p[1] == L'\\') {
- p += 2;
- }
-
- /* Skip leading drive letter from archives created
- * on Windows. */
- if (((p[0] >= L'a' && p[0] <= L'z') ||
- (p[0] >= L'A' && p[0] <= L'Z')) &&
- p[1] == L':') {
- if (p[2] == L'\0') {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Path is a drive name");
- return (ARCHIVE_FAILED);
- }
- if (p[2] == L'\\')
- p += 2;
- }
-
- top = dest = src = p;
- /* Rewrite the path name if its character is a unusable. */
- for (; *p != L'\0'; p++) {
- if (*p == L':' || *p == L'*' || *p == L'?' || *p == L'"' ||
- *p == L'<' || *p == L'>' || *p == L'|')
- *p = L'_';
- }
- /* Skip leading '\'. */
- if (*src == L'\\')
- separator = *src++;
-
- /* Scan the pathname one element at a time. */
- for (;;) {
- /* src points to first char after '\' */
- if (src[0] == L'\0') {
- break;
- } else if (src[0] == L'\\') {
- /* Found '\\'('//'), ignore second one. */
- src++;
- continue;
- } else if (src[0] == L'.') {
- if (src[1] == L'\0') {
- /* Ignore trailing '.' */
- break;
- } else if (src[1] == L'\\') {
- /* Skip '.\'. */
- src += 2;
- continue;
- } else if (src[1] == L'.') {
- if (src[2] == L'\\' || src[2] == L'\0') {
- /* Conditionally warn about '..' */
- if (a->flags &
- ARCHIVE_EXTRACT_SECURE_NODOTDOT) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Path contains '..'");
- return (ARCHIVE_FAILED);
- }
- }
- /*
- * Note: Under no circumstances do we
- * remove '..' elements. In
- * particular, restoring
- * '\foo\..\bar\' should create the
- * 'foo' dir as a side-effect.
- */
- }
- }
-
- /* Copy current element, including leading '\'. */
- if (separator)
- *dest++ = L'\\';
- while (*src != L'\0' && *src != L'\\') {
- *dest++ = *src++;
- }
-
- if (*src == L'\0')
- break;
-
- /* Skip '\' separator. */
- separator = *src++;
- }
- /*
- * We've just copied zero or more path elements, not including the
- * final '\'.
- */
- if (dest == top) {
- /*
- * Nothing got copied. The path must have been something
- * like '.' or '\' or './' or '/././././/./'.
- */
- if (separator)
- *dest++ = L'\\';
- else
- *dest++ = L'.';
- }
- /* Terminate the result. */
- *dest = L'\0';
- return (ARCHIVE_OK);
-}
-
-/*
- * Create the parent directory of the specified path, assuming path
- * is already in mutable storage.
- */
-static int
-create_parent_dir(struct archive_write_disk *a, wchar_t *path)
-{
- wchar_t *slash;
- int r;
-
- /* Remove tail element to obtain parent name. */
- slash = wcsrchr(path, L'\\');
- if (slash == NULL)
- return (ARCHIVE_OK);
- *slash = L'\0';
- r = create_dir(a, path);
- *slash = L'\\';
- return (r);
-}
-
-/*
- * Create the specified dir, recursing to create parents as necessary.
- *
- * Returns ARCHIVE_OK if the path exists when we're done here.
- * Otherwise, returns ARCHIVE_FAILED.
- * Assumes path is in mutable storage; path is unchanged on exit.
- */
-static int
-create_dir(struct archive_write_disk *a, wchar_t *path)
-{
- BY_HANDLE_FILE_INFORMATION st;
- struct fixup_entry *le;
- wchar_t *slash, *base, *full;
- mode_t mode_final, mode, st_mode;
- int r;
-
- /* Check for special names and just skip them. */
- slash = wcsrchr(path, L'\\');
- if (slash == NULL)
- base = path;
- else
- base = slash + 1;
-
- if (base[0] == L'\0' ||
- (base[0] == L'.' && base[1] == L'\0') ||
- (base[0] == L'.' && base[1] == L'.' && base[2] == L'\0')) {
- /* Don't bother trying to create null path, '.', or '..'. */
- if (slash != NULL) {
- *slash = L'\0';
- r = create_dir(a, path);
- *slash = L'\\';
- return (r);
- }
- return (ARCHIVE_OK);
- }
-
- /*
- * Yes, this should be stat() and not lstat(). Using lstat()
- * here loses the ability to extract through symlinks. Also note
- * that this should not use the a->st cache.
- */
- if (file_information(a, path, &st, &st_mode, 0) == 0) {
- if (S_ISDIR(st_mode))
- return (ARCHIVE_OK);
- if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
- archive_set_error(&a->archive, EEXIST,
- "Can't create directory '%ls'", path);
- return (ARCHIVE_FAILED);
- }
- if (disk_unlink(path) != 0) {
- archive_set_error(&a->archive, errno,
- "Can't create directory '%ls': "
- "Conflicting file cannot be removed",
- path);
- return (ARCHIVE_FAILED);
- }
- } else if (errno != ENOENT && errno != ENOTDIR) {
- /* Stat failed? */
- archive_set_error(&a->archive, errno,
- "Can't test directory '%ls'", path);
- return (ARCHIVE_FAILED);
- } else if (slash != NULL) {
- *slash = '\0';
- r = create_dir(a, path);
- *slash = '\\';
- if (r != ARCHIVE_OK)
- return (r);
- }
-
- /*
- * Mode we want for the final restored directory. Per POSIX,
- * implicitly-created dirs must be created obeying the umask.
- * There's no mention whether this is different for privileged
- * restores (which the rest of this code handles by pretending
- * umask=0). I've chosen here to always obey the user's umask for
- * implicit dirs, even if _EXTRACT_PERM was specified.
- */
- mode_final = DEFAULT_DIR_MODE & ~a->user_umask;
- /* Mode we want on disk during the restore process. */
- mode = mode_final;
- mode |= MINIMUM_DIR_MODE;
- mode &= MAXIMUM_DIR_MODE;
- /*
- * Apply __la_win_permissive_name_w to path in order to
- * remove '../' path string.
- */
- full = __la_win_permissive_name_w(path);
- if (full == NULL)
- errno = EINVAL;
- else if (CreateDirectoryW(full, NULL) != 0) {
- if (mode != mode_final) {
- le = new_fixup(a, path);
- le->fixup |=TODO_MODE_BASE;
- le->mode = mode_final;
- }
- free(full);
- return (ARCHIVE_OK);
- } else {
- la_dosmaperr(GetLastError());
- }
- free(full);
-
- /*
- * Without the following check, a/b/../b/c/d fails at the
- * second visit to 'b', so 'd' can't be created. Note that we
- * don't add it to the fixup list here, as it's already been
- * added.
- */
- if (file_information(a, path, &st, &st_mode, 0) == 0 &&
- S_ISDIR(st_mode))
- return (ARCHIVE_OK);
-
- archive_set_error(&a->archive, errno, "Failed to create dir '%ls'",
- path);
- return (ARCHIVE_FAILED);
-}
-
-/*
- * Note: Although we can skip setting the user id if the desired user
- * id matches the current user, we cannot skip setting the group, as
- * many systems set the gid based on the containing directory. So
- * we have to perform a chown syscall if we want to set the SGID
- * bit. (The alternative is to stat() and then possibly chown(); it's
- * more efficient to skip the stat() and just always chown().) Note
- * that a successful chown() here clears the TODO_SGID_CHECK bit, which
- * allows set_mode to skip the stat() check for the GID.
- */
-static int
-set_ownership(struct archive_write_disk *a)
-{
-/* unfortunately, on win32 there is no 'root' user with uid 0,
- so we just have to try the chown and see if it works */
-
- /* If we know we can't change it, don't bother trying. */
- if (a->user_uid != 0 && a->user_uid != a->uid) {
- archive_set_error(&a->archive, errno,
- "Can't set UID=%jd", (intmax_t)a->uid);
- return (ARCHIVE_WARN);
- }
-
- archive_set_error(&a->archive, errno,
- "Can't set user=%jd/group=%jd for %ls",
- (intmax_t)a->uid, (intmax_t)a->gid, a->name);
- return (ARCHIVE_WARN);
-}
-
-static int
-set_times(struct archive_write_disk *a,
- HANDLE h, int mode, const wchar_t *name,
- time_t atime, long atime_nanos,
- time_t birthtime, long birthtime_nanos,
- time_t mtime, long mtime_nanos,
- time_t ctime_sec, long ctime_nanos)
-{
-#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
-#define WINTIME(sec, nsec) ((Int32x32To64(sec, 10000000) + EPOC_TIME)\
- + (((nsec)/1000)*10))
-
- HANDLE hw = 0;
- ULARGE_INTEGER wintm;
- FILETIME *pfbtime;
- FILETIME fatime, fbtime, fmtime;
-
- (void)ctime_sec; /* UNUSED */
- (void)ctime_nanos; /* UNUSED */
-
- if (h != INVALID_HANDLE_VALUE) {
- hw = NULL;
- } else {
- wchar_t *ws;
-# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- CREATEFILE2_EXTENDED_PARAMETERS createExParams;
-#endif
-
- if (S_ISLNK(mode))
- return (ARCHIVE_OK);
- ws = __la_win_permissive_name_w(name);
- if (ws == NULL)
- goto settimes_failed;
-# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
- ZeroMemory(&createExParams, sizeof(createExParams));
- createExParams.dwSize = sizeof(createExParams);
- createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
- hw = CreateFile2(ws, FILE_WRITE_ATTRIBUTES, 0,
- OPEN_EXISTING, &createExParams);
-#else
- hw = CreateFileW(ws, FILE_WRITE_ATTRIBUTES,
- 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
-#endif
- free(ws);
- if (hw == INVALID_HANDLE_VALUE)
- goto settimes_failed;
- h = hw;
- }
-
- wintm.QuadPart = WINTIME(atime, atime_nanos);
- fatime.dwLowDateTime = wintm.LowPart;
- fatime.dwHighDateTime = wintm.HighPart;
- wintm.QuadPart = WINTIME(mtime, mtime_nanos);
- fmtime.dwLowDateTime = wintm.LowPart;
- fmtime.dwHighDateTime = wintm.HighPart;
- /*
- * SetFileTime() supports birthtime.
- */
- if (birthtime > 0 || birthtime_nanos > 0) {
- wintm.QuadPart = WINTIME(birthtime, birthtime_nanos);
- fbtime.dwLowDateTime = wintm.LowPart;
- fbtime.dwHighDateTime = wintm.HighPart;
- pfbtime = &fbtime;
- } else
- pfbtime = NULL;
- if (SetFileTime(h, pfbtime, &fatime, &fmtime) == 0)
- goto settimes_failed;
- CloseHandle(hw);
- return (ARCHIVE_OK);
-
-settimes_failed:
- CloseHandle(hw);
- archive_set_error(&a->archive, EINVAL, "Can't restore time");
- return (ARCHIVE_WARN);
-}
-
-static int
-set_times_from_entry(struct archive_write_disk *a)
-{
- time_t atime, birthtime, mtime, ctime_sec;
- long atime_nsec, birthtime_nsec, mtime_nsec, ctime_nsec;
-
- /* Suitable defaults. */
- atime = birthtime = mtime = ctime_sec = a->start_time;
- atime_nsec = birthtime_nsec = mtime_nsec = ctime_nsec = 0;
-
- /* If no time was provided, we're done. */
- if (!archive_entry_atime_is_set(a->entry)
- && !archive_entry_birthtime_is_set(a->entry)
- && !archive_entry_mtime_is_set(a->entry))
- return (ARCHIVE_OK);
-
- if (archive_entry_atime_is_set(a->entry)) {
- atime = archive_entry_atime(a->entry);
- atime_nsec = archive_entry_atime_nsec(a->entry);
- }
- if (archive_entry_birthtime_is_set(a->entry)) {
- birthtime = archive_entry_birthtime(a->entry);
- birthtime_nsec = archive_entry_birthtime_nsec(a->entry);
- }
- if (archive_entry_mtime_is_set(a->entry)) {
- mtime = archive_entry_mtime(a->entry);
- mtime_nsec = archive_entry_mtime_nsec(a->entry);
- }
- if (archive_entry_ctime_is_set(a->entry)) {
- ctime_sec = archive_entry_ctime(a->entry);
- ctime_nsec = archive_entry_ctime_nsec(a->entry);
- }
-
- return set_times(a, a->fh, a->mode, a->name,
- atime, atime_nsec,
- birthtime, birthtime_nsec,
- mtime, mtime_nsec,
- ctime_sec, ctime_nsec);
-}
-
-static int
-set_mode(struct archive_write_disk *a, int mode)
-{
- int r = ARCHIVE_OK;
- mode &= 07777; /* Strip off file type bits. */
-
- if (a->todo & TODO_SGID_CHECK) {
- /*
- * If we don't know the GID is right, we must stat()
- * to verify it. We can't just check the GID of this
- * process, since systems sometimes set GID from
- * the enclosing dir or based on ACLs.
- */
- if ((r = lazy_stat(a)) != ARCHIVE_OK)
- return (r);
- if (0 != a->gid) {
- mode &= ~ S_ISGID;
- }
- /* While we're here, double-check the UID. */
- if (0 != a->uid
- && (a->todo & TODO_SUID)) {
- mode &= ~ S_ISUID;
- }
- a->todo &= ~TODO_SGID_CHECK;
- a->todo &= ~TODO_SUID_CHECK;
- } else if (a->todo & TODO_SUID_CHECK) {
- /*
- * If we don't know the UID is right, we can just check
- * the user, since all systems set the file UID from
- * the process UID.
- */
- if (a->user_uid != a->uid) {
- mode &= ~ S_ISUID;
- }
- a->todo &= ~TODO_SUID_CHECK;
- }
-
- if (S_ISLNK(a->mode)) {
-#ifdef HAVE_LCHMOD
- /*
- * If this is a symlink, use lchmod(). If the
- * platform doesn't support lchmod(), just skip it. A
- * platform that doesn't provide a way to set
- * permissions on symlinks probably ignores
- * permissions on symlinks, so a failure here has no
- * impact.
- */
- if (lchmod(a->name, mode) != 0) {
- archive_set_error(&a->archive, errno,
- "Can't set permissions to 0%o", (int)mode);
- r = ARCHIVE_WARN;
- }
-#endif
- } else if (!S_ISDIR(a->mode)) {
- /*
- * If it's not a symlink and not a dir, then use
- * fchmod() or chmod(), depending on whether we have
- * an fd. Dirs get their perms set during the
- * post-extract fixup, which is handled elsewhere.
- */
-#ifdef HAVE_FCHMOD
- if (a->fd >= 0) {
- if (fchmod(a->fd, mode) != 0) {
- archive_set_error(&a->archive, errno,
- "Can't set permissions to 0%o", (int)mode);
- r = ARCHIVE_WARN;
- }
- } else
-#endif
- /* If this platform lacks fchmod(), then
- * we'll just use chmod(). */
- if (la_chmod(a->name, mode) != 0) {
- archive_set_error(&a->archive, errno,
- "Can't set permissions to 0%o", (int)mode);
- r = ARCHIVE_WARN;
- }
- }
- return (r);
-}
-
-static int set_fflags_platform(const wchar_t *name, unsigned long fflags_set,
- unsigned long fflags_clear)
-{
- DWORD oldflags, newflags;
- wchar_t *fullname;
-
- const DWORD settable_flags =
- FILE_ATTRIBUTE_ARCHIVE |
- FILE_ATTRIBUTE_HIDDEN |
- FILE_ATTRIBUTE_NORMAL |
- FILE_ATTRIBUTE_NOT_CONTENT_INDEXED |
- FILE_ATTRIBUTE_OFFLINE |
- FILE_ATTRIBUTE_READONLY |
- FILE_ATTRIBUTE_SYSTEM |
- FILE_ATTRIBUTE_TEMPORARY;
-
- oldflags = GetFileAttributesW(name);
- if (oldflags == (DWORD)-1 &&
- GetLastError() == ERROR_INVALID_NAME) {
- fullname = __la_win_permissive_name_w(name);
- oldflags = GetFileAttributesW(fullname);
- }
- if (oldflags == (DWORD)-1) {
- la_dosmaperr(GetLastError());
- return (ARCHIVE_WARN);
- }
- newflags = ((oldflags & ~fflags_clear) | fflags_set) & settable_flags;
- if(SetFileAttributesW(name, newflags) == 0)
- return (ARCHIVE_WARN);
- return (ARCHIVE_OK);
-}
-
-static int
-clear_nochange_fflags(struct archive_write_disk *a)
-{
- return (set_fflags_platform(a->name, 0, FILE_ATTRIBUTE_READONLY));
-}
-
-static int
-set_fflags(struct archive_write_disk *a)
-{
- unsigned long set, clear;
-
- if (a->todo & TODO_FFLAGS) {
- archive_entry_fflags(a->entry, &set, &clear);
- if (set == 0 && clear == 0)
- return (ARCHIVE_OK);
- return (set_fflags_platform(a->name, set, clear));
-
- }
- return (ARCHIVE_OK);
-}
-
-/* Default empty function body to satisfy mainline code. */
-static int
-set_acls(struct archive_write_disk *a, HANDLE h, const wchar_t *name,
- struct archive_acl *acl)
-{
- (void)a; /* UNUSED */
- (void)h; /* UNUSED */
- (void)name; /* UNUSED */
- (void)acl; /* UNUSED */
- return (ARCHIVE_OK);
-}
-
-/*
- * Restore extended attributes - stub implementation for unsupported systems
- */
-static int
-set_xattrs(struct archive_write_disk *a)
-{
- static int warning_done = 0;
-
- /* If there aren't any extended attributes, then it's okay not
- * to extract them, otherwise, issue a single warning. */
- if (archive_entry_xattr_count(a->entry) != 0 && !warning_done) {
- warning_done = 1;
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Cannot restore extended attributes on this system");
- return (ARCHIVE_WARN);
- }
- /* Warning was already emitted; suppress further warnings. */
- return (ARCHIVE_OK);
-}
-
-static void
-fileTimeToUtc(const FILETIME *filetime, time_t *t, long *ns)
-{
- ULARGE_INTEGER utc;
-
- utc.HighPart = filetime->dwHighDateTime;
- utc.LowPart = filetime->dwLowDateTime;
- if (utc.QuadPart >= EPOC_TIME) {
- utc.QuadPart -= EPOC_TIME;
- /* milli seconds base */
- *t = (time_t)(utc.QuadPart / 10000000);
- /* nano seconds base */
- *ns = (long)(utc.QuadPart % 10000000) * 100;
- } else {
- *t = 0;
- *ns = 0;
- }
-}
-/*
- * Test if file on disk is older than entry.
- */
-static int
-older(BY_HANDLE_FILE_INFORMATION *st, struct archive_entry *entry)
-{
- time_t sec;
- long nsec;
-
- fileTimeToUtc(&st->ftLastWriteTime, &sec, &nsec);
- /* First, test the seconds and return if we have a definite answer. */
- /* Definitely older. */
- if (sec < archive_entry_mtime(entry))
- return (1);
- /* Definitely younger. */
- if (sec > archive_entry_mtime(entry))
- return (0);
- if (nsec < archive_entry_mtime_nsec(entry))
- return (1);
- /* Same age or newer, so not older. */
- return (0);
-}
-
-#endif /* _WIN32 && !__CYGWIN__ */
-
diff --git a/contrib/libs/libarchive/libarchive/archive_write_open_fd.c b/contrib/libs/libarchive/libarchive/archive_write_open_fd.c
deleted file mode 100644
index b8d491faa2..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_open_fd.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_open_fd.c 201093 2009-12-28 02:28:44Z kientzle $");
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_IO_H
-#include <io.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "archive.h"
-
-struct write_fd_data {
- int fd;
-};
-
-static int file_free(struct archive *, void *);
-static int file_open(struct archive *, void *);
-static ssize_t file_write(struct archive *, void *, const void *buff, size_t);
-
-int
-archive_write_open_fd(struct archive *a, int fd)
-{
- struct write_fd_data *mine;
-
- mine = (struct write_fd_data *)malloc(sizeof(*mine));
- if (mine == NULL) {
- archive_set_error(a, ENOMEM, "No memory");
- return (ARCHIVE_FATAL);
- }
- mine->fd = fd;
-#if defined(__CYGWIN__) || defined(_WIN32)
- setmode(mine->fd, O_BINARY);
-#endif
- return (archive_write_open2(a, mine,
- file_open, file_write, NULL, file_free));
-}
-
-static int
-file_open(struct archive *a, void *client_data)
-{
- struct write_fd_data *mine;
- struct stat st;
-
- mine = (struct write_fd_data *)client_data;
-
- if (fstat(mine->fd, &st) != 0) {
- archive_set_error(a, errno, "Couldn't stat fd %d", mine->fd);
- return (ARCHIVE_FATAL);
- }
-
- /*
- * If this is a regular file, don't add it to itself.
- */
- if (S_ISREG(st.st_mode))
- archive_write_set_skip_file(a, st.st_dev, st.st_ino);
-
- /*
- * If client hasn't explicitly set the last block handling,
- * then set it here.
- */
- if (archive_write_get_bytes_in_last_block(a) < 0) {
- /* If the output is a block or character device, fifo,
- * or stdout, pad the last block, otherwise leave it
- * unpadded. */
- if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) ||
- S_ISFIFO(st.st_mode) || (mine->fd == 1))
- /* Last block will be fully padded. */
- archive_write_set_bytes_in_last_block(a, 0);
- else
- archive_write_set_bytes_in_last_block(a, 1);
- }
-
- return (ARCHIVE_OK);
-}
-
-static ssize_t
-file_write(struct archive *a, void *client_data, const void *buff, size_t length)
-{
- struct write_fd_data *mine;
- ssize_t bytesWritten;
-
- mine = (struct write_fd_data *)client_data;
- for (;;) {
- bytesWritten = write(mine->fd, buff, length);
- if (bytesWritten <= 0) {
- if (errno == EINTR)
- continue;
- archive_set_error(a, errno, "Write error");
- return (-1);
- }
- return (bytesWritten);
- }
-}
-
-static int
-file_free(struct archive *a, void *client_data)
-{
- struct write_fd_data *mine = (struct write_fd_data *)client_data;
-
- (void)a; /* UNUSED */
- if (mine == NULL)
- return (ARCHIVE_OK);
- free(mine);
- return (ARCHIVE_OK);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_open_file.c b/contrib/libs/libarchive/libarchive/archive_write_open_file.c
deleted file mode 100644
index bf5b55a672..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_open_file.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_open_file.c,v 1.19 2007/01/09 08:05:56 kientzle Exp $");
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "archive.h"
-
-struct write_FILE_data {
- FILE *f;
-};
-
-static int file_free(struct archive *, void *);
-static int file_open(struct archive *, void *);
-static ssize_t file_write(struct archive *, void *, const void *buff, size_t);
-
-int
-archive_write_open_FILE(struct archive *a, FILE *f)
-{
- struct write_FILE_data *mine;
-
- mine = (struct write_FILE_data *)malloc(sizeof(*mine));
- if (mine == NULL) {
- archive_set_error(a, ENOMEM, "No memory");
- return (ARCHIVE_FATAL);
- }
- mine->f = f;
- return (archive_write_open2(a, mine, file_open, file_write,
- NULL, file_free));
-}
-
-static int
-file_open(struct archive *a, void *client_data)
-{
- (void)a; /* UNUSED */
- (void)client_data; /* UNUSED */
-
- return (ARCHIVE_OK);
-}
-
-static ssize_t
-file_write(struct archive *a, void *client_data, const void *buff, size_t length)
-{
- struct write_FILE_data *mine;
- size_t bytesWritten;
-
- mine = client_data;
- for (;;) {
- bytesWritten = fwrite(buff, 1, length, mine->f);
- if (bytesWritten <= 0) {
- if (errno == EINTR)
- continue;
- archive_set_error(a, errno, "Write error");
- return (-1);
- }
- return (bytesWritten);
- }
-}
-
-static int
-file_free(struct archive *a, void *client_data)
-{
- struct write_FILE_data *mine = client_data;
-
- (void)a; /* UNUSED */
- if (mine == NULL)
- return (ARCHIVE_OK);
- free(mine);
- return (ARCHIVE_OK);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_open_filename.c b/contrib/libs/libarchive/libarchive/archive_write_open_filename.c
deleted file mode 100644
index 9ceefb19bc..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_open_filename.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_open_filename.c 191165 2009-04-17 00:39:35Z kientzle $");
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_string.h"
-
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-#ifndef O_CLOEXEC
-#define O_CLOEXEC 0
-#endif
-
-struct write_file_data {
- int fd;
- struct archive_mstring filename;
-};
-
-static int file_close(struct archive *, void *);
-static int file_free(struct archive *, void *);
-static int file_open(struct archive *, void *);
-static ssize_t file_write(struct archive *, void *, const void *buff, size_t);
-static int open_filename(struct archive *, int, const void *);
-
-int
-archive_write_open_file(struct archive *a, const char *filename)
-{
- return (archive_write_open_filename(a, filename));
-}
-
-int
-archive_write_open_filename(struct archive *a, const char *filename)
-{
-
- if (filename == NULL || filename[0] == '\0')
- return (archive_write_open_fd(a, 1));
-
- return (open_filename(a, 1, filename));
-}
-
-int
-archive_write_open_filename_w(struct archive *a, const wchar_t *filename)
-{
-
- if (filename == NULL || filename[0] == L'\0')
- return (archive_write_open_fd(a, 1));
-
- return (open_filename(a, 0, filename));
-}
-
-static int
-open_filename(struct archive *a, int mbs_fn, const void *filename)
-{
- struct write_file_data *mine;
- int r;
-
- mine = (struct write_file_data *)calloc(1, sizeof(*mine));
- if (mine == NULL) {
- archive_set_error(a, ENOMEM, "No memory");
- return (ARCHIVE_FATAL);
- }
- if (mbs_fn)
- r = archive_mstring_copy_mbs(&mine->filename, filename);
- else
- r = archive_mstring_copy_wcs(&mine->filename, filename);
- if (r < 0) {
- if (errno == ENOMEM) {
- archive_set_error(a, ENOMEM, "No memory");
- return (ARCHIVE_FATAL);
- }
- if (mbs_fn)
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Can't convert '%s' to WCS",
- (const char *)filename);
- else
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Can't convert '%S' to MBS",
- (const wchar_t *)filename);
- return (ARCHIVE_FAILED);
- }
- mine->fd = -1;
- return (archive_write_open2(a, mine,
- file_open, file_write, file_close, file_free));
-}
-
-static int
-file_open(struct archive *a, void *client_data)
-{
- int flags;
- struct write_file_data *mine;
- struct stat st;
-#if defined(_WIN32) && !defined(__CYGWIN__)
- wchar_t *fullpath;
-#endif
- const wchar_t *wcs;
- const char *mbs;
-
- mine = (struct write_file_data *)client_data;
- flags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_CLOEXEC;
-
- /*
- * Open the file.
- */
- mbs = NULL; wcs = NULL;
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if (archive_mstring_get_wcs(a, &mine->filename, &wcs) != 0) {
- if (errno == ENOMEM)
- archive_set_error(a, errno, "No memory");
- else {
- archive_mstring_get_mbs(a, &mine->filename, &mbs);
- archive_set_error(a, errno,
- "Can't convert '%s' to WCS", mbs);
- }
- return (ARCHIVE_FATAL);
- }
- fullpath = __la_win_permissive_name_w(wcs);
- if (fullpath != NULL) {
- mine->fd = _wopen(fullpath, flags, 0666);
- free(fullpath);
- } else
- mine->fd = _wopen(wcs, flags, 0666);
-#else
- if (archive_mstring_get_mbs(a, &mine->filename, &mbs) != 0) {
- if (errno == ENOMEM)
- archive_set_error(a, errno, "No memory");
- else {
- archive_mstring_get_wcs(a, &mine->filename, &wcs);
- archive_set_error(a, errno,
- "Can't convert '%S' to MBS", wcs);
- }
- return (ARCHIVE_FATAL);
- }
- mine->fd = open(mbs, flags, 0666);
- __archive_ensure_cloexec_flag(mine->fd);
-#endif
- if (mine->fd < 0) {
- if (mbs != NULL)
- archive_set_error(a, errno, "Failed to open '%s'", mbs);
- else
- archive_set_error(a, errno, "Failed to open '%S'", wcs);
- return (ARCHIVE_FATAL);
- }
-
- if (fstat(mine->fd, &st) != 0) {
- if (mbs != NULL)
- archive_set_error(a, errno, "Couldn't stat '%s'", mbs);
- else
- archive_set_error(a, errno, "Couldn't stat '%S'", wcs);
- return (ARCHIVE_FATAL);
- }
-
- /*
- * Set up default last block handling.
- */
- if (archive_write_get_bytes_in_last_block(a) < 0) {
- if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) ||
- S_ISFIFO(st.st_mode))
- /* Pad last block when writing to device or FIFO. */
- archive_write_set_bytes_in_last_block(a, 0);
- else
- /* Don't pad last block otherwise. */
- archive_write_set_bytes_in_last_block(a, 1);
- }
-
- /*
- * If the output file is a regular file, don't add it to
- * itself. If it's a device file, it's okay to add the device
- * entry to the output archive.
- */
- if (S_ISREG(st.st_mode))
- archive_write_set_skip_file(a, st.st_dev, st.st_ino);
-
- return (ARCHIVE_OK);
-}
-
-static ssize_t
-file_write(struct archive *a, void *client_data, const void *buff,
- size_t length)
-{
- struct write_file_data *mine;
- ssize_t bytesWritten;
-
- mine = (struct write_file_data *)client_data;
- for (;;) {
- bytesWritten = write(mine->fd, buff, length);
- if (bytesWritten <= 0) {
- if (errno == EINTR)
- continue;
- archive_set_error(a, errno, "Write error");
- return (-1);
- }
- return (bytesWritten);
- }
-}
-
-static int
-file_close(struct archive *a, void *client_data)
-{
- struct write_file_data *mine = (struct write_file_data *)client_data;
-
- (void)a; /* UNUSED */
-
- if (mine == NULL)
- return (ARCHIVE_FATAL);
-
- if (mine->fd >= 0)
- close(mine->fd);
-
- return (ARCHIVE_OK);
-}
-
-static int
-file_free(struct archive *a, void *client_data)
-{
- struct write_file_data *mine = (struct write_file_data *)client_data;
-
- (void)a; /* UNUSED */
-
- if (mine == NULL)
- return (ARCHIVE_OK);
-
- archive_mstring_clean(&mine->filename);
- free(mine);
- return (ARCHIVE_OK);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_open_memory.c b/contrib/libs/libarchive/libarchive/archive_write_open_memory.c
deleted file mode 100644
index a8a0b817fc..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_open_memory.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_open_memory.c,v 1.3 2007/01/09 08:05:56 kientzle Exp $");
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "archive.h"
-
-struct write_memory_data {
- size_t used;
- size_t size;
- size_t * client_size;
- unsigned char * buff;
-};
-
-static int memory_write_free(struct archive *, void *);
-static int memory_write_open(struct archive *, void *);
-static ssize_t memory_write(struct archive *, void *, const void *buff, size_t);
-
-/*
- * Client provides a pointer to a block of memory to receive
- * the data. The 'size' param both tells us the size of the
- * client buffer and lets us tell the client the final size.
- */
-int
-archive_write_open_memory(struct archive *a, void *buff, size_t buffSize, size_t *used)
-{
- struct write_memory_data *mine;
-
- mine = (struct write_memory_data *)calloc(1, sizeof(*mine));
- if (mine == NULL) {
- archive_set_error(a, ENOMEM, "No memory");
- return (ARCHIVE_FATAL);
- }
- mine->buff = buff;
- mine->size = buffSize;
- mine->client_size = used;
- return (archive_write_open2(a, mine,
- memory_write_open, memory_write, NULL, memory_write_free));
-}
-
-static int
-memory_write_open(struct archive *a, void *client_data)
-{
- struct write_memory_data *mine;
- mine = client_data;
- mine->used = 0;
- if (mine->client_size != NULL)
- *mine->client_size = mine->used;
- /* Disable padding if it hasn't been set explicitly. */
- if (-1 == archive_write_get_bytes_in_last_block(a))
- archive_write_set_bytes_in_last_block(a, 1);
- return (ARCHIVE_OK);
-}
-
-/*
- * Copy the data into the client buffer.
- * Note that we update mine->client_size on every write.
- * In particular, this means the client can follow exactly
- * how much has been written into their buffer at any time.
- */
-static ssize_t
-memory_write(struct archive *a, void *client_data, const void *buff, size_t length)
-{
- struct write_memory_data *mine;
- mine = client_data;
-
- if (mine->used + length > mine->size) {
- archive_set_error(a, ENOMEM, "Buffer exhausted");
- return (ARCHIVE_FATAL);
- }
- memcpy(mine->buff + mine->used, buff, length);
- mine->used += length;
- if (mine->client_size != NULL)
- *mine->client_size = mine->used;
- return (length);
-}
-
-static int
-memory_write_free(struct archive *a, void *client_data)
-{
- struct write_memory_data *mine;
- (void)a; /* UNUSED */
- mine = client_data;
- if (mine == NULL)
- return (ARCHIVE_OK);
- free(mine);
- return (ARCHIVE_OK);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_private.h b/contrib/libs/libarchive/libarchive/archive_write_private.h
deleted file mode 100644
index 6522e6521b..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_private.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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.
- *
- * $FreeBSD: head/lib/libarchive/archive_write_private.h 201155 2009-12-29 05:20:12Z kientzle $
- */
-
-#ifndef ARCHIVE_WRITE_PRIVATE_H_INCLUDED
-#define ARCHIVE_WRITE_PRIVATE_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#ifndef __LIBARCHIVE_TEST
-#error This header is only to be used internally to libarchive.
-#endif
-#endif
-
-#include "archive.h"
-#include "archive_string.h"
-#include "archive_private.h"
-
-#define ARCHIVE_WRITE_FILTER_STATE_NEW 1U
-#define ARCHIVE_WRITE_FILTER_STATE_OPEN 2U
-#define ARCHIVE_WRITE_FILTER_STATE_CLOSED 4U
-#define ARCHIVE_WRITE_FILTER_STATE_FATAL 0x8000U
-
-struct archive_write;
-
-struct archive_write_filter {
- int64_t bytes_written;
- struct archive *archive; /* Associated archive. */
- struct archive_write_filter *next_filter; /* Who I write to. */
- int (*options)(struct archive_write_filter *,
- const char *key, const char *value);
- int (*open)(struct archive_write_filter *);
- int (*write)(struct archive_write_filter *, const void *, size_t);
- int (*flush)(struct archive_write_filter *);
- int (*close)(struct archive_write_filter *);
- int (*free)(struct archive_write_filter *);
- void *data;
- const char *name;
- int code;
- int bytes_per_block;
- int bytes_in_last_block;
- int state;
-};
-
-#if ARCHIVE_VERSION < 4000000
-void __archive_write_filters_free(struct archive *);
-#endif
-
-struct archive_write_filter *__archive_write_allocate_filter(struct archive *);
-
-int __archive_write_output(struct archive_write *, const void *, size_t);
-int __archive_write_nulls(struct archive_write *, size_t);
-int __archive_write_filter(struct archive_write_filter *, const void *, size_t);
-
-struct archive_write {
- struct archive archive;
-
- /* Dev/ino of the archive being written. */
- int skip_file_set;
- int64_t skip_file_dev;
- int64_t skip_file_ino;
-
- /* Utility: Pointer to a block of nulls. */
- const unsigned char *nulls;
- size_t null_length;
-
- /* Callbacks to open/read/write/close archive stream. */
- archive_open_callback *client_opener;
- archive_write_callback *client_writer;
- archive_close_callback *client_closer;
- archive_free_callback *client_freer;
- void *client_data;
-
- /*
- * Blocking information. Note that bytes_in_last_block is
- * misleadingly named; I should find a better name. These
- * control the final output from all compressors, including
- * compression_none.
- */
- int bytes_per_block;
- int bytes_in_last_block;
-
- /*
- * First and last write filters in the pipeline.
- */
- struct archive_write_filter *filter_first;
- struct archive_write_filter *filter_last;
-
- /*
- * Pointers to format-specific functions for writing. They're
- * initialized by archive_write_set_format_XXX() calls.
- */
- void *format_data;
- const char *format_name;
- int (*format_init)(struct archive_write *);
- int (*format_options)(struct archive_write *,
- const char *key, const char *value);
- int (*format_finish_entry)(struct archive_write *);
- int (*format_write_header)(struct archive_write *,
- struct archive_entry *);
- ssize_t (*format_write_data)(struct archive_write *,
- const void *buff, size_t);
- int (*format_close)(struct archive_write *);
- int (*format_free)(struct archive_write *);
-
-
- /*
- * Encryption passphrase.
- */
- char *passphrase;
- archive_passphrase_callback *passphrase_callback;
- void *passphrase_client_data;
-};
-
-/*
- * Utility function to format a USTAR header into a buffer. If
- * "strict" is set, this tries to create the absolutely most portable
- * version of a ustar header. If "strict" is set to 0, then it will
- * relax certain requirements.
- *
- * Generally, format-specific declarations don't belong in this
- * header; this is a rare example of a function that is shared by
- * two very similar formats (ustar and pax).
- */
-int
-__archive_write_format_header_ustar(struct archive_write *, char buff[512],
- struct archive_entry *, int tartype, int strict,
- struct archive_string_conv *);
-
-struct archive_write_program_data;
-struct archive_write_program_data * __archive_write_program_allocate(const char *program_name);
-int __archive_write_program_free(struct archive_write_program_data *);
-int __archive_write_program_open(struct archive_write_filter *,
- struct archive_write_program_data *, const char *);
-int __archive_write_program_close(struct archive_write_filter *,
- struct archive_write_program_data *);
-int __archive_write_program_write(struct archive_write_filter *,
- struct archive_write_program_data *, const void *, size_t);
-
-/*
- * Get a encryption passphrase.
- */
-const char * __archive_write_get_passphrase(struct archive_write *a);
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_format.c b/contrib/libs/libarchive/libarchive/archive_write_set_format.c
deleted file mode 100644
index 1f65fa4a77..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_format.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format.c 201168 2009-12-29 06:15:32Z kientzle $");
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_write_set_format_private.h"
-
-/* A table that maps format codes to functions. */
-static const
-struct { int code; int (*setter)(struct archive *); } codes[] =
-{
- { ARCHIVE_FORMAT_7ZIP, archive_write_set_format_7zip },
- { ARCHIVE_FORMAT_CPIO, archive_write_set_format_cpio },
- { ARCHIVE_FORMAT_CPIO_BIN_LE, archive_write_set_format_cpio_bin },
- { ARCHIVE_FORMAT_CPIO_PWB, archive_write_set_format_cpio_pwb },
- { ARCHIVE_FORMAT_CPIO_POSIX, archive_write_set_format_cpio_odc },
- { ARCHIVE_FORMAT_CPIO_SVR4_NOCRC, archive_write_set_format_cpio_newc },
- { ARCHIVE_FORMAT_ISO9660, archive_write_set_format_iso9660 },
- { ARCHIVE_FORMAT_MTREE, archive_write_set_format_mtree },
- { ARCHIVE_FORMAT_RAW, archive_write_set_format_raw },
- { ARCHIVE_FORMAT_SHAR, archive_write_set_format_shar },
- { ARCHIVE_FORMAT_SHAR_BASE, archive_write_set_format_shar },
- { ARCHIVE_FORMAT_SHAR_DUMP, archive_write_set_format_shar_dump },
- { ARCHIVE_FORMAT_TAR, archive_write_set_format_pax_restricted },
- { ARCHIVE_FORMAT_TAR_GNUTAR, archive_write_set_format_gnutar },
- { ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE, archive_write_set_format_pax },
- { ARCHIVE_FORMAT_TAR_PAX_RESTRICTED,
- archive_write_set_format_pax_restricted },
- { ARCHIVE_FORMAT_TAR_USTAR, archive_write_set_format_ustar },
- { ARCHIVE_FORMAT_WARC, archive_write_set_format_warc },
- { ARCHIVE_FORMAT_XAR, archive_write_set_format_xar },
- { ARCHIVE_FORMAT_ZIP, archive_write_set_format_zip },
- { 0, NULL }
-};
-
-int
-archive_write_set_format(struct archive *a, int code)
-{
- int i;
-
- for (i = 0; codes[i].code != 0; i++) {
- if (code == codes[i].code)
- return ((codes[i].setter)(a));
- }
-
- archive_set_error(a, EINVAL, "No such format");
- return (ARCHIVE_FATAL);
-}
-
-void
-__archive_write_entry_filetype_unsupported(struct archive *a,
- struct archive_entry *entry, const char *format)
-{
- const char *name = NULL;
-
- switch (archive_entry_filetype(entry)) {
- /*
- * All formats should be able to archive regular files (AE_IFREG)
- */
- case AE_IFDIR:
- name = "directories";
- break;
- case AE_IFLNK:
- name = "symbolic links";
- break;
- case AE_IFCHR:
- name = "character devices";
- break;
- case AE_IFBLK:
- name = "block devices";
- break;
- case AE_IFIFO:
- name = "named pipes";
- break;
- case AE_IFSOCK:
- name = "sockets";
- break;
- default:
- break;
- }
-
- if (name != NULL) {
- archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
- "%s: %s format cannot archive %s",
- archive_entry_pathname(entry), format, name);
- } else {
- archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
- "%s: %s format cannot archive files with mode 0%lo",
- archive_entry_pathname(entry), format,
- (unsigned long)archive_entry_mode(entry));
- }
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_format_7zip.c b/contrib/libs/libarchive/libarchive/archive_write_set_format_7zip.c
deleted file mode 100644
index 3e97b25de7..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_format_7zip.c
+++ /dev/null
@@ -1,2322 +0,0 @@
-/*-
- * Copyright (c) 2011-2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stdlib.h>
-#ifdef HAVE_BZLIB_H
-#include <bzlib.h>
-#endif
-#if HAVE_LZMA_H
-#error #include <lzma.h>
-#endif
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-
-#include "archive.h"
-#ifndef HAVE_ZLIB_H
-#error #include "archive_crc32.h"
-#endif
-#include "archive_endian.h"
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_ppmd7_private.h"
-#include "archive_private.h"
-#include "archive_rb.h"
-#include "archive_string.h"
-#include "archive_write_private.h"
-#include "archive_write_set_format_private.h"
-
-/*
- * Codec ID
- */
-#define _7Z_COPY 0
-#define _7Z_LZMA1 0x030101
-#define _7Z_LZMA2 0x21
-#define _7Z_DEFLATE 0x040108
-#define _7Z_BZIP2 0x040202
-#define _7Z_PPMD 0x030401
-
-/*
- * 7-Zip header property IDs.
- */
-#define kEnd 0x00
-#define kHeader 0x01
-#define kArchiveProperties 0x02
-#define kAdditionalStreamsInfo 0x03
-#define kMainStreamsInfo 0x04
-#define kFilesInfo 0x05
-#define kPackInfo 0x06
-#define kUnPackInfo 0x07
-#define kSubStreamsInfo 0x08
-#define kSize 0x09
-#define kCRC 0x0A
-#define kFolder 0x0B
-#define kCodersUnPackSize 0x0C
-#define kNumUnPackStream 0x0D
-#define kEmptyStream 0x0E
-#define kEmptyFile 0x0F
-#define kAnti 0x10
-#define kName 0x11
-#define kCTime 0x12
-#define kATime 0x13
-#define kMTime 0x14
-#define kAttributes 0x15
-#define kEncodedHeader 0x17
-
-enum la_zaction {
- ARCHIVE_Z_FINISH,
- ARCHIVE_Z_RUN
-};
-
-/*
- * A stream object of universal compressor.
- */
-struct la_zstream {
- const uint8_t *next_in;
- size_t avail_in;
- uint64_t total_in;
-
- uint8_t *next_out;
- size_t avail_out;
- uint64_t total_out;
-
- uint32_t prop_size;
- uint8_t *props;
-
- int valid;
- void *real_stream;
- int (*code) (struct archive *a,
- struct la_zstream *lastrm,
- enum la_zaction action);
- int (*end)(struct archive *a,
- struct la_zstream *lastrm);
-};
-
-#define PPMD7_DEFAULT_ORDER 6
-#define PPMD7_DEFAULT_MEM_SIZE (1 << 24)
-
-struct ppmd_stream {
- int stat;
- CPpmd7 ppmd7_context;
- CPpmd7z_RangeEnc range_enc;
- IByteOut byteout;
- uint8_t *buff;
- uint8_t *buff_ptr;
- uint8_t *buff_end;
- size_t buff_bytes;
-};
-
-struct coder {
- unsigned codec;
- size_t prop_size;
- uint8_t *props;
-};
-
-struct file {
- struct archive_rb_node rbnode;
-
- struct file *next;
- unsigned name_len;
- uint8_t *utf16name;/* UTF16-LE name. */
- uint64_t size;
- unsigned flg;
-#define MTIME_IS_SET (1<<0)
-#define ATIME_IS_SET (1<<1)
-#define CTIME_IS_SET (1<<2)
-#define CRC32_IS_SET (1<<3)
-#define HAS_STREAM (1<<4)
-
- struct {
- time_t time;
- long time_ns;
- } times[3];
-#define MTIME 0
-#define ATIME 1
-#define CTIME 2
-
- mode_t mode;
- uint32_t crc32;
-
- unsigned dir:1;
-};
-
-struct _7zip {
- int temp_fd;
- uint64_t temp_offset;
-
- struct file *cur_file;
- size_t total_number_entry;
- size_t total_number_nonempty_entry;
- size_t total_number_empty_entry;
- size_t total_number_dir_entry;
- size_t total_bytes_entry_name;
- size_t total_number_time_defined[3];
- uint64_t total_bytes_compressed;
- uint64_t total_bytes_uncompressed;
- uint64_t entry_bytes_remaining;
- uint32_t entry_crc32;
- uint32_t precode_crc32;
- uint32_t encoded_crc32;
- int crc32flg;
-#define PRECODE_CRC32 1
-#define ENCODED_CRC32 2
-
- unsigned opt_compression;
- int opt_compression_level;
-
- struct la_zstream stream;
- struct coder coder;
-
- struct archive_string_conv *sconv;
-
- /*
- * Compressed data buffer.
- */
- unsigned char wbuff[512 * 20 * 6];
- size_t wbuff_remaining;
-
- /*
- * The list of the file entries which has its contents is used to
- * manage struct file objects.
- * We use 'next' (a member of struct file) to chain.
- */
- struct {
- struct file *first;
- struct file **last;
- } file_list, empty_list;
- struct archive_rb_tree rbtree;/* for empty files */
-};
-
-static int _7z_options(struct archive_write *,
- const char *, const char *);
-static int _7z_write_header(struct archive_write *,
- struct archive_entry *);
-static ssize_t _7z_write_data(struct archive_write *,
- const void *, size_t);
-static int _7z_finish_entry(struct archive_write *);
-static int _7z_close(struct archive_write *);
-static int _7z_free(struct archive_write *);
-static int file_cmp_node(const struct archive_rb_node *,
- const struct archive_rb_node *);
-static int file_cmp_key(const struct archive_rb_node *, const void *);
-static int file_new(struct archive_write *a, struct archive_entry *,
- struct file **);
-static void file_free(struct file *);
-static void file_register(struct _7zip *, struct file *);
-static void file_register_empty(struct _7zip *, struct file *);
-static void file_init_register(struct _7zip *);
-static void file_init_register_empty(struct _7zip *);
-static void file_free_register(struct _7zip *);
-static ssize_t compress_out(struct archive_write *, const void *, size_t ,
- enum la_zaction);
-static int compression_init_encoder_copy(struct archive *,
- struct la_zstream *);
-static int compression_code_copy(struct archive *,
- struct la_zstream *, enum la_zaction);
-static int compression_end_copy(struct archive *, struct la_zstream *);
-static int compression_init_encoder_deflate(struct archive *,
- struct la_zstream *, int, int);
-#ifdef HAVE_ZLIB_H
-static int compression_code_deflate(struct archive *,
- struct la_zstream *, enum la_zaction);
-static int compression_end_deflate(struct archive *, struct la_zstream *);
-#endif
-static int compression_init_encoder_bzip2(struct archive *,
- struct la_zstream *, int);
-#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
-static int compression_code_bzip2(struct archive *,
- struct la_zstream *, enum la_zaction);
-static int compression_end_bzip2(struct archive *, struct la_zstream *);
-#endif
-static int compression_init_encoder_lzma1(struct archive *,
- struct la_zstream *, int);
-static int compression_init_encoder_lzma2(struct archive *,
- struct la_zstream *, int);
-#if defined(HAVE_LZMA_H)
-static int compression_code_lzma(struct archive *,
- struct la_zstream *, enum la_zaction);
-static int compression_end_lzma(struct archive *, struct la_zstream *);
-#endif
-static int compression_init_encoder_ppmd(struct archive *,
- struct la_zstream *, unsigned, uint32_t);
-static int compression_code_ppmd(struct archive *,
- struct la_zstream *, enum la_zaction);
-static int compression_end_ppmd(struct archive *, struct la_zstream *);
-static int _7z_compression_init_encoder(struct archive_write *, unsigned,
- int);
-static int compression_code(struct archive *,
- struct la_zstream *, enum la_zaction);
-static int compression_end(struct archive *,
- struct la_zstream *);
-static int enc_uint64(struct archive_write *, uint64_t);
-static int make_header(struct archive_write *, uint64_t, uint64_t,
- uint64_t, int, struct coder *);
-static int make_streamsInfo(struct archive_write *, uint64_t, uint64_t,
- uint64_t, int, struct coder *, int, uint32_t);
-
-int
-archive_write_set_format_7zip(struct archive *_a)
-{
- static const struct archive_rb_tree_ops rb_ops = {
- file_cmp_node, file_cmp_key
- };
- struct archive_write *a = (struct archive_write *)_a;
- struct _7zip *zip;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_format_7zip");
-
- /* If another format was already registered, unregister it. */
- if (a->format_free != NULL)
- (a->format_free)(a);
-
- zip = calloc(1, sizeof(*zip));
- if (zip == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate 7-Zip data");
- return (ARCHIVE_FATAL);
- }
- zip->temp_fd = -1;
- __archive_rb_tree_init(&(zip->rbtree), &rb_ops);
- file_init_register(zip);
- file_init_register_empty(zip);
-
- /* Set default compression type and its level. */
-#if HAVE_LZMA_H
- zip->opt_compression = _7Z_LZMA1;
-#elif defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
- zip->opt_compression = _7Z_BZIP2;
-#elif defined(HAVE_ZLIB_H)
- zip->opt_compression = _7Z_DEFLATE;
-#else
- zip->opt_compression = _7Z_COPY;
-#endif
- zip->opt_compression_level = 6;
-
- a->format_data = zip;
-
- a->format_name = "7zip";
- a->format_options = _7z_options;
- a->format_write_header = _7z_write_header;
- a->format_write_data = _7z_write_data;
- a->format_finish_entry = _7z_finish_entry;
- a->format_close = _7z_close;
- a->format_free = _7z_free;
- a->archive.archive_format = ARCHIVE_FORMAT_7ZIP;
- a->archive.archive_format_name = "7zip";
-
- return (ARCHIVE_OK);
-}
-
-static int
-_7z_options(struct archive_write *a, const char *key, const char *value)
-{
- struct _7zip *zip;
-
- zip = (struct _7zip *)a->format_data;
-
- if (strcmp(key, "compression") == 0) {
- const char *name = NULL;
-
- if (value == NULL || strcmp(value, "copy") == 0 ||
- strcmp(value, "COPY") == 0 ||
- strcmp(value, "store") == 0 ||
- strcmp(value, "STORE") == 0)
- zip->opt_compression = _7Z_COPY;
- else if (strcmp(value, "deflate") == 0 ||
- strcmp(value, "DEFLATE") == 0)
-#if HAVE_ZLIB_H
- zip->opt_compression = _7Z_DEFLATE;
-#else
- name = "deflate";
-#endif
- else if (strcmp(value, "bzip2") == 0 ||
- strcmp(value, "BZIP2") == 0)
-#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
- zip->opt_compression = _7Z_BZIP2;
-#else
- name = "bzip2";
-#endif
- else if (strcmp(value, "lzma1") == 0 ||
- strcmp(value, "LZMA1") == 0)
-#if HAVE_LZMA_H
- zip->opt_compression = _7Z_LZMA1;
-#else
- name = "lzma1";
-#endif
- else if (strcmp(value, "lzma2") == 0 ||
- strcmp(value, "LZMA2") == 0)
-#if HAVE_LZMA_H
- zip->opt_compression = _7Z_LZMA2;
-#else
- name = "lzma2";
-#endif
- else if (strcmp(value, "ppmd") == 0 ||
- strcmp(value, "PPMD") == 0 ||
- strcmp(value, "PPMd") == 0)
- zip->opt_compression = _7Z_PPMD;
- else {
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "Unknown compression name: `%s'",
- value);
- return (ARCHIVE_FAILED);
- }
- if (name != NULL) {
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "`%s' compression not supported "
- "on this platform",
- name);
- return (ARCHIVE_FAILED);
- }
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "compression-level") == 0) {
- if (value == NULL ||
- !(value[0] >= '0' && value[0] <= '9') ||
- value[1] != '\0') {
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "Illegal value `%s'",
- value);
- return (ARCHIVE_FAILED);
- }
- zip->opt_compression_level = value[0] - '0';
- return (ARCHIVE_OK);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-static int
-_7z_write_header(struct archive_write *a, struct archive_entry *entry)
-{
- struct _7zip *zip;
- struct file *file;
- int r;
-
- zip = (struct _7zip *)a->format_data;
- zip->cur_file = NULL;
- zip->entry_bytes_remaining = 0;
-
- if (zip->sconv == NULL) {
- zip->sconv = archive_string_conversion_to_charset(
- &a->archive, "UTF-16LE", 1);
- if (zip->sconv == NULL)
- return (ARCHIVE_FATAL);
- }
-
- r = file_new(a, entry, &file);
- if (r < ARCHIVE_WARN) {
- if (file != NULL)
- file_free(file);
- return (r);
- }
- if (file->size == 0 && file->dir) {
- if (!__archive_rb_tree_insert_node(&(zip->rbtree),
- (struct archive_rb_node *)file)) {
- /* We have already had the same file. */
- file_free(file);
- return (ARCHIVE_OK);
- }
- }
-
- if (file->flg & MTIME_IS_SET)
- zip->total_number_time_defined[MTIME]++;
- if (file->flg & CTIME_IS_SET)
- zip->total_number_time_defined[CTIME]++;
- if (file->flg & ATIME_IS_SET)
- zip->total_number_time_defined[ATIME]++;
-
- zip->total_number_entry++;
- zip->total_bytes_entry_name += file->name_len + 2;
- if (file->size == 0) {
- /* Count up the number of empty files. */
- zip->total_number_empty_entry++;
- if (file->dir)
- zip->total_number_dir_entry++;
- else
- file_register_empty(zip, file);
- return (r);
- }
-
- /*
- * Init compression.
- */
- if ((zip->total_number_entry - zip->total_number_empty_entry) == 1) {
- r = _7z_compression_init_encoder(a, zip->opt_compression,
- zip->opt_compression_level);
- if (r < 0) {
- file_free(file);
- return (ARCHIVE_FATAL);
- }
- }
-
- /* Register a non-empty file. */
- file_register(zip, file);
-
- /*
- * Set the current file to cur_file to read its contents.
- */
- zip->cur_file = file;
-
-
- /* Save a offset of current file in temporary file. */
- zip->entry_bytes_remaining = file->size;
- zip->entry_crc32 = 0;
-
- /*
- * Store a symbolic link name as file contents.
- */
- if (archive_entry_filetype(entry) == AE_IFLNK) {
- ssize_t bytes;
- const void *p = (const void *)archive_entry_symlink(entry);
- bytes = compress_out(a, p, (size_t)file->size, ARCHIVE_Z_RUN);
- if (bytes < 0)
- return ((int)bytes);
- zip->entry_crc32 = crc32(zip->entry_crc32, p, (unsigned)bytes);
- zip->entry_bytes_remaining -= bytes;
- }
-
- return (r);
-}
-
-/*
- * Write data to a temporary file.
- */
-static int
-write_to_temp(struct archive_write *a, const void *buff, size_t s)
-{
- struct _7zip *zip;
- const unsigned char *p;
- ssize_t ws;
-
- zip = (struct _7zip *)a->format_data;
-
- /*
- * Open a temporary file.
- */
- if (zip->temp_fd == -1) {
- zip->temp_offset = 0;
- zip->temp_fd = __archive_mktemp(NULL);
- if (zip->temp_fd < 0) {
- archive_set_error(&a->archive, errno,
- "Couldn't create temporary file");
- return (ARCHIVE_FATAL);
- }
- }
-
- p = (const unsigned char *)buff;
- while (s) {
- ws = write(zip->temp_fd, p, s);
- if (ws < 0) {
- archive_set_error(&(a->archive), errno,
- "fwrite function failed");
- return (ARCHIVE_FATAL);
- }
- s -= ws;
- p += ws;
- zip->temp_offset += ws;
- }
- return (ARCHIVE_OK);
-}
-
-static ssize_t
-compress_out(struct archive_write *a, const void *buff, size_t s,
- enum la_zaction run)
-{
- struct _7zip *zip = (struct _7zip *)a->format_data;
- int r;
-
- if (run == ARCHIVE_Z_FINISH && zip->stream.total_in == 0 && s == 0)
- return (0);
-
- if ((zip->crc32flg & PRECODE_CRC32) && s)
- zip->precode_crc32 = crc32(zip->precode_crc32, buff,
- (unsigned)s);
- zip->stream.next_in = (const unsigned char *)buff;
- zip->stream.avail_in = s;
- for (;;) {
- /* Compress file data. */
- r = compression_code(&(a->archive), &(zip->stream), run);
- if (r != ARCHIVE_OK && r != ARCHIVE_EOF)
- return (ARCHIVE_FATAL);
- if (zip->stream.avail_out == 0) {
- if (write_to_temp(a, zip->wbuff, sizeof(zip->wbuff))
- != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- zip->stream.next_out = zip->wbuff;
- zip->stream.avail_out = sizeof(zip->wbuff);
- if (zip->crc32flg & ENCODED_CRC32)
- zip->encoded_crc32 = crc32(zip->encoded_crc32,
- zip->wbuff, sizeof(zip->wbuff));
- if (run == ARCHIVE_Z_FINISH && r != ARCHIVE_EOF)
- continue;
- }
- if (zip->stream.avail_in == 0)
- break;
- }
- if (run == ARCHIVE_Z_FINISH) {
- uint64_t bytes = sizeof(zip->wbuff) - zip->stream.avail_out;
- if (write_to_temp(a, zip->wbuff, (size_t)bytes) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- if ((zip->crc32flg & ENCODED_CRC32) && bytes)
- zip->encoded_crc32 = crc32(zip->encoded_crc32,
- zip->wbuff, (unsigned)bytes);
- }
-
- return (s);
-}
-
-static ssize_t
-_7z_write_data(struct archive_write *a, const void *buff, size_t s)
-{
- struct _7zip *zip;
- ssize_t bytes;
-
- zip = (struct _7zip *)a->format_data;
-
- if (s > zip->entry_bytes_remaining)
- s = (size_t)zip->entry_bytes_remaining;
- if (s == 0 || zip->cur_file == NULL)
- return (0);
- bytes = compress_out(a, buff, s, ARCHIVE_Z_RUN);
- if (bytes < 0)
- return (bytes);
- zip->entry_crc32 = crc32(zip->entry_crc32, buff, (unsigned)bytes);
- zip->entry_bytes_remaining -= bytes;
- return (bytes);
-}
-
-static int
-_7z_finish_entry(struct archive_write *a)
-{
- struct _7zip *zip;
- size_t s;
- ssize_t r;
-
- zip = (struct _7zip *)a->format_data;
- if (zip->cur_file == NULL)
- return (ARCHIVE_OK);
-
- while (zip->entry_bytes_remaining > 0) {
- s = (size_t)zip->entry_bytes_remaining;
- if (s > a->null_length)
- s = a->null_length;
- r = _7z_write_data(a, a->nulls, s);
- if (r < 0)
- return ((int)r);
- }
- zip->total_bytes_compressed += zip->stream.total_in;
- zip->total_bytes_uncompressed += zip->stream.total_out;
- zip->cur_file->crc32 = zip->entry_crc32;
- zip->cur_file = NULL;
-
- return (ARCHIVE_OK);
-}
-
-static int
-flush_wbuff(struct archive_write *a)
-{
- struct _7zip *zip;
- int r;
- size_t s;
-
- zip = (struct _7zip *)a->format_data;
- s = sizeof(zip->wbuff) - zip->wbuff_remaining;
- r = __archive_write_output(a, zip->wbuff, s);
- if (r != ARCHIVE_OK)
- return (r);
- zip->wbuff_remaining = sizeof(zip->wbuff);
- return (r);
-}
-
-static int
-copy_out(struct archive_write *a, uint64_t offset, uint64_t length)
-{
- struct _7zip *zip;
- int r;
-
- zip = (struct _7zip *)a->format_data;
- if (zip->temp_offset > 0 &&
- lseek(zip->temp_fd, offset, SEEK_SET) < 0) {
- archive_set_error(&(a->archive), errno, "lseek failed");
- return (ARCHIVE_FATAL);
- }
- while (length) {
- size_t rsize;
- ssize_t rs;
- unsigned char *wb;
-
- if (length > zip->wbuff_remaining)
- rsize = zip->wbuff_remaining;
- else
- rsize = (size_t)length;
- wb = zip->wbuff + (sizeof(zip->wbuff) - zip->wbuff_remaining);
- rs = read(zip->temp_fd, wb, rsize);
- if (rs < 0) {
- archive_set_error(&(a->archive), errno,
- "Can't read temporary file(%jd)",
- (intmax_t)rs);
- return (ARCHIVE_FATAL);
- }
- if (rs == 0) {
- archive_set_error(&(a->archive), 0,
- "Truncated 7-Zip archive");
- return (ARCHIVE_FATAL);
- }
- zip->wbuff_remaining -= rs;
- length -= rs;
- if (zip->wbuff_remaining == 0) {
- r = flush_wbuff(a);
- if (r != ARCHIVE_OK)
- return (r);
- }
- }
- return (ARCHIVE_OK);
-}
-
-static int
-_7z_close(struct archive_write *a)
-{
- struct _7zip *zip;
- unsigned char *wb;
- uint64_t header_offset, header_size, header_unpacksize;
- uint64_t length;
- uint32_t header_crc32;
- int r;
-
- zip = (struct _7zip *)a->format_data;
-
- if (zip->total_number_entry > 0) {
- struct archive_rb_node *n;
- uint64_t data_offset, data_size, data_unpacksize;
- unsigned header_compression;
-
- r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH);
- if (r < 0)
- return (r);
- data_offset = 0;
- data_size = zip->stream.total_out;
- data_unpacksize = zip->stream.total_in;
- zip->coder.codec = zip->opt_compression;
- zip->coder.prop_size = zip->stream.prop_size;
- zip->coder.props = zip->stream.props;
- zip->stream.prop_size = 0;
- zip->stream.props = NULL;
- zip->total_number_nonempty_entry =
- zip->total_number_entry - zip->total_number_empty_entry;
-
- /* Connect an empty file list. */
- if (zip->empty_list.first != NULL) {
- *zip->file_list.last = zip->empty_list.first;
- zip->file_list.last = zip->empty_list.last;
- }
- /* Connect a directory file list. */
- ARCHIVE_RB_TREE_FOREACH(n, &(zip->rbtree)) {
- file_register(zip, (struct file *)n);
- }
-
- /*
- * NOTE: 7z command supports just LZMA1, LZMA2 and COPY for
- * the compression type for encoding the header.
- */
-#if HAVE_LZMA_H
- header_compression = _7Z_LZMA1;
- if(zip->opt_compression == _7Z_LZMA2 ||
- zip->opt_compression == _7Z_COPY)
- header_compression = zip->opt_compression;
-
- /* If the stored file is only one, do not encode the header.
- * This is the same way 7z command does. */
- if (zip->total_number_entry == 1)
- header_compression = _7Z_COPY;
-#else
- header_compression = _7Z_COPY;
-#endif
- r = _7z_compression_init_encoder(a, header_compression,
- zip->opt_compression_level);
- if (r < 0)
- return (r);
- zip->crc32flg = PRECODE_CRC32;
- zip->precode_crc32 = 0;
- r = make_header(a, data_offset, data_size, data_unpacksize,
- 1, &(zip->coder));
- if (r < 0)
- return (r);
- r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH);
- if (r < 0)
- return (r);
- header_offset = data_offset + data_size;
- header_size = zip->stream.total_out;
- header_crc32 = zip->precode_crc32;
- header_unpacksize = zip->stream.total_in;
-
- if (header_compression != _7Z_COPY) {
- /*
- * Encode the header in order to reduce the size
- * of the archive.
- */
- free(zip->coder.props);
- zip->coder.codec = header_compression;
- zip->coder.prop_size = zip->stream.prop_size;
- zip->coder.props = zip->stream.props;
- zip->stream.prop_size = 0;
- zip->stream.props = NULL;
-
- r = _7z_compression_init_encoder(a, _7Z_COPY, 0);
- if (r < 0)
- return (r);
- zip->crc32flg = ENCODED_CRC32;
- zip->encoded_crc32 = 0;
-
- /*
- * Make EncodedHeader.
- */
- r = enc_uint64(a, kEncodedHeader);
- if (r < 0)
- return (r);
- r = make_streamsInfo(a, header_offset, header_size,
- header_unpacksize, 1, &(zip->coder), 0,
- header_crc32);
- if (r < 0)
- return (r);
- r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH);
- if (r < 0)
- return (r);
- header_offset = header_offset + header_size;
- header_size = zip->stream.total_out;
- header_crc32 = zip->encoded_crc32;
- }
- zip->crc32flg = 0;
- } else {
- header_offset = header_size = 0;
- header_crc32 = 0;
- }
-
- length = zip->temp_offset;
-
- /*
- * Make the zip header on wbuff(write buffer).
- */
- wb = zip->wbuff;
- zip->wbuff_remaining = sizeof(zip->wbuff);
- memcpy(&wb[0], "7z\xBC\xAF\x27\x1C", 6);
- wb[6] = 0;/* Major version. */
- wb[7] = 3;/* Minor version. */
- archive_le64enc(&wb[12], header_offset);/* Next Header Offset */
- archive_le64enc(&wb[20], header_size);/* Next Header Size */
- archive_le32enc(&wb[28], header_crc32);/* Next Header CRC */
- archive_le32enc(&wb[8], crc32(0, &wb[12], 20));/* Start Header CRC */
- zip->wbuff_remaining -= 32;
-
- /*
- * Read all file contents and an encoded header from the temporary
- * file and write out it.
- */
- r = copy_out(a, 0, length);
- if (r != ARCHIVE_OK)
- return (r);
- r = flush_wbuff(a);
- return (r);
-}
-
-/*
- * Encode 64 bits value into 7-Zip's encoded UINT64 value.
- */
-static int
-enc_uint64(struct archive_write *a, uint64_t val)
-{
- unsigned mask = 0x80;
- uint8_t numdata[9];
- int i;
-
- numdata[0] = 0;
- for (i = 1; i < (int)sizeof(numdata); i++) {
- if (val < mask) {
- numdata[0] |= (uint8_t)val;
- break;
- }
- numdata[i] = (uint8_t)val;
- val >>= 8;
- numdata[0] |= mask;
- mask >>= 1;
- }
- return ((int)compress_out(a, numdata, i, ARCHIVE_Z_RUN));
-}
-
-static int
-make_substreamsInfo(struct archive_write *a, struct coder *coders)
-{
- struct _7zip *zip = (struct _7zip *)a->format_data;
- struct file *file;
- int r;
-
- /*
- * Make SubStreamsInfo.
- */
- r = enc_uint64(a, kSubStreamsInfo);
- if (r < 0)
- return (r);
-
- if (zip->total_number_nonempty_entry > 1 && coders->codec != _7Z_COPY) {
- /*
- * Make NumUnPackStream.
- */
- r = enc_uint64(a, kNumUnPackStream);
- if (r < 0)
- return (r);
-
- /* Write numUnpackStreams */
- r = enc_uint64(a, zip->total_number_nonempty_entry);
- if (r < 0)
- return (r);
-
- /*
- * Make kSize.
- */
- r = enc_uint64(a, kSize);
- if (r < 0)
- return (r);
- file = zip->file_list.first;
- for (;file != NULL; file = file->next) {
- if (file->next == NULL ||
- file->next->size == 0)
- break;
- r = enc_uint64(a, file->size);
- if (r < 0)
- return (r);
- }
- }
-
- /*
- * Make CRC.
- */
- r = enc_uint64(a, kCRC);
- if (r < 0)
- return (r);
-
-
- /* All are defined */
- r = enc_uint64(a, 1);
- if (r < 0)
- return (r);
- file = zip->file_list.first;
- for (;file != NULL; file = file->next) {
- uint8_t crc[4];
- if (file->size == 0)
- break;
- archive_le32enc(crc, file->crc32);
- r = (int)compress_out(a, crc, 4, ARCHIVE_Z_RUN);
- if (r < 0)
- return (r);
- }
-
- /* Write End. */
- r = enc_uint64(a, kEnd);
- if (r < 0)
- return (r);
- return (ARCHIVE_OK);
-}
-
-static int
-make_streamsInfo(struct archive_write *a, uint64_t offset, uint64_t pack_size,
- uint64_t unpack_size, int num_coder, struct coder *coders, int substrm,
- uint32_t header_crc)
-{
- struct _7zip *zip = (struct _7zip *)a->format_data;
- uint8_t codec_buff[8];
- int numFolders, fi;
- int codec_size;
- int i, r;
-
- if (coders->codec == _7Z_COPY)
- numFolders = (int)zip->total_number_nonempty_entry;
- else
- numFolders = 1;
-
- /*
- * Make PackInfo.
- */
- r = enc_uint64(a, kPackInfo);
- if (r < 0)
- return (r);
-
- /* Write PackPos. */
- r = enc_uint64(a, offset);
- if (r < 0)
- return (r);
-
- /* Write NumPackStreams. */
- r = enc_uint64(a, numFolders);
- if (r < 0)
- return (r);
-
- /* Make Size. */
- r = enc_uint64(a, kSize);
- if (r < 0)
- return (r);
-
- if (numFolders > 1) {
- struct file *file = zip->file_list.first;
- for (;file != NULL; file = file->next) {
- if (file->size == 0)
- break;
- r = enc_uint64(a, file->size);
- if (r < 0)
- return (r);
- }
- } else {
- /* Write size. */
- r = enc_uint64(a, pack_size);
- if (r < 0)
- return (r);
- }
-
- r = enc_uint64(a, kEnd);
- if (r < 0)
- return (r);
-
- /*
- * Make UnPackInfo.
- */
- r = enc_uint64(a, kUnPackInfo);
- if (r < 0)
- return (r);
-
- /*
- * Make Folder.
- */
- r = enc_uint64(a, kFolder);
- if (r < 0)
- return (r);
-
- /* Write NumFolders. */
- r = enc_uint64(a, numFolders);
- if (r < 0)
- return (r);
-
- /* Write External. */
- r = enc_uint64(a, 0);
- if (r < 0)
- return (r);
-
- for (fi = 0; fi < numFolders; fi++) {
- /* Write NumCoders. */
- r = enc_uint64(a, num_coder);
- if (r < 0)
- return (r);
-
- for (i = 0; i < num_coder; i++) {
- unsigned codec_id = coders[i].codec;
-
- /* Write Codec flag. */
- archive_be64enc(codec_buff, codec_id);
- for (codec_size = 8; codec_size > 0; codec_size--) {
- if (codec_buff[8 - codec_size])
- break;
- }
- if (codec_size == 0)
- codec_size = 1;
- if (coders[i].prop_size)
- r = enc_uint64(a, codec_size | 0x20);
- else
- r = enc_uint64(a, codec_size);
- if (r < 0)
- return (r);
-
- /* Write Codec ID. */
- codec_size &= 0x0f;
- r = (int)compress_out(a, &codec_buff[8-codec_size],
- codec_size, ARCHIVE_Z_RUN);
- if (r < 0)
- return (r);
-
- if (coders[i].prop_size) {
- /* Write Codec property size. */
- r = enc_uint64(a, coders[i].prop_size);
- if (r < 0)
- return (r);
-
- /* Write Codec properties. */
- r = (int)compress_out(a, coders[i].props,
- coders[i].prop_size, ARCHIVE_Z_RUN);
- if (r < 0)
- return (r);
- }
- }
- }
-
- /*
- * Make CodersUnPackSize.
- */
- r = enc_uint64(a, kCodersUnPackSize);
- if (r < 0)
- return (r);
-
- if (numFolders > 1) {
- struct file *file = zip->file_list.first;
- for (;file != NULL; file = file->next) {
- if (file->size == 0)
- break;
- r = enc_uint64(a, file->size);
- if (r < 0)
- return (r);
- }
-
- } else {
- /* Write UnPackSize. */
- r = enc_uint64(a, unpack_size);
- if (r < 0)
- return (r);
- }
-
- if (!substrm) {
- uint8_t crc[4];
- /*
- * Make CRC.
- */
- r = enc_uint64(a, kCRC);
- if (r < 0)
- return (r);
-
- /* All are defined */
- r = enc_uint64(a, 1);
- if (r < 0)
- return (r);
- archive_le32enc(crc, header_crc);
- r = (int)compress_out(a, crc, 4, ARCHIVE_Z_RUN);
- if (r < 0)
- return (r);
- }
-
- /* Write End. */
- r = enc_uint64(a, kEnd);
- if (r < 0)
- return (r);
-
- if (substrm) {
- /*
- * Make SubStreamsInfo.
- */
- r = make_substreamsInfo(a, coders);
- if (r < 0)
- return (r);
- }
-
-
- /* Write End. */
- r = enc_uint64(a, kEnd);
- if (r < 0)
- return (r);
-
- return (ARCHIVE_OK);
-}
-
-
-#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
-static uint64_t
-utcToFiletime(time_t t, long ns)
-{
- uint64_t fileTime;
-
- fileTime = t;
- fileTime *= 10000000;
- fileTime += ns / 100;
- fileTime += EPOC_TIME;
- return (fileTime);
-}
-
-static int
-make_time(struct archive_write *a, uint8_t type, unsigned flg, int ti)
-{
- uint8_t filetime[8];
- struct _7zip *zip = (struct _7zip *)a->format_data;
- struct file *file;
- int r;
- uint8_t b, mask;
-
- /*
- * Make Time Bools.
- */
- if (zip->total_number_time_defined[ti] == zip->total_number_entry) {
- /* Write Time Type. */
- r = enc_uint64(a, type);
- if (r < 0)
- return (r);
- /* Write EmptyStream Size. */
- r = enc_uint64(a, 2 + zip->total_number_entry * 8);
- if (r < 0)
- return (r);
- /* All are defined. */
- r = enc_uint64(a, 1);
- if (r < 0)
- return (r);
- } else {
- if (zip->total_number_time_defined[ti] == 0)
- return (ARCHIVE_OK);
-
- /* Write Time Type. */
- r = enc_uint64(a, type);
- if (r < 0)
- return (r);
- /* Write EmptyStream Size. */
- r = enc_uint64(a, 2 + ((zip->total_number_entry + 7) >> 3)
- + zip->total_number_time_defined[ti] * 8);
- if (r < 0)
- return (r);
-
- /* All are not defined. */
- r = enc_uint64(a, 0);
- if (r < 0)
- return (r);
-
- b = 0;
- mask = 0x80;
- file = zip->file_list.first;
- for (;file != NULL; file = file->next) {
- if (file->flg & flg)
- b |= mask;
- mask >>= 1;
- if (mask == 0) {
- r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN);
- if (r < 0)
- return (r);
- mask = 0x80;
- b = 0;
- }
- }
- if (mask != 0x80) {
- r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN);
- if (r < 0)
- return (r);
- }
- }
-
- /* External. */
- r = enc_uint64(a, 0);
- if (r < 0)
- return (r);
-
-
- /*
- * Make Times.
- */
- file = zip->file_list.first;
- for (;file != NULL; file = file->next) {
- if ((file->flg & flg) == 0)
- continue;
- archive_le64enc(filetime, utcToFiletime(file->times[ti].time,
- file->times[ti].time_ns));
- r = (int)compress_out(a, filetime, 8, ARCHIVE_Z_RUN);
- if (r < 0)
- return (r);
- }
-
- return (ARCHIVE_OK);
-}
-
-static int
-make_header(struct archive_write *a, uint64_t offset, uint64_t pack_size,
- uint64_t unpack_size, int codernum, struct coder *coders)
-{
- struct _7zip *zip = (struct _7zip *)a->format_data;
- struct file *file;
- int r;
- uint8_t b, mask;
-
- /*
- * Make FilesInfo.
- */
- r = enc_uint64(a, kHeader);
- if (r < 0)
- return (r);
-
- /*
- * If there are empty files only, do not write MainStreamInfo.
- */
- if (zip->total_number_nonempty_entry) {
- /*
- * Make MainStreamInfo.
- */
- r = enc_uint64(a, kMainStreamsInfo);
- if (r < 0)
- return (r);
- r = make_streamsInfo(a, offset, pack_size, unpack_size,
- codernum, coders, 1, 0);
- if (r < 0)
- return (r);
- }
-
- /*
- * Make FilesInfo.
- */
- r = enc_uint64(a, kFilesInfo);
- if (r < 0)
- return (r);
-
- /* Write numFiles. */
- r = enc_uint64(a, zip->total_number_entry);
- if (r < 0)
- return (r);
-
- if (zip->total_number_empty_entry > 0) {
- /* Make EmptyStream. */
- r = enc_uint64(a, kEmptyStream);
- if (r < 0)
- return (r);
-
- /* Write EmptyStream Size. */
- r = enc_uint64(a, (zip->total_number_entry+7)>>3);
- if (r < 0)
- return (r);
-
- b = 0;
- mask = 0x80;
- file = zip->file_list.first;
- for (;file != NULL; file = file->next) {
- if (file->size == 0)
- b |= mask;
- mask >>= 1;
- if (mask == 0) {
- r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN);
- if (r < 0)
- return (r);
- mask = 0x80;
- b = 0;
- }
- }
- if (mask != 0x80) {
- r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN);
- if (r < 0)
- return (r);
- }
- }
-
- if (zip->total_number_empty_entry > zip->total_number_dir_entry) {
- /* Make EmptyFile. */
- r = enc_uint64(a, kEmptyFile);
- if (r < 0)
- return (r);
-
- /* Write EmptyFile Size. */
- r = enc_uint64(a, (zip->total_number_empty_entry + 7) >> 3);
- if (r < 0)
- return (r);
-
- b = 0;
- mask = 0x80;
- file = zip->file_list.first;
- for (;file != NULL; file = file->next) {
- if (file->size)
- continue;
- if (!file->dir)
- b |= mask;
- mask >>= 1;
- if (mask == 0) {
- r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN);
- if (r < 0)
- return (r);
- mask = 0x80;
- b = 0;
- }
- }
- if (mask != 0x80) {
- r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN);
- if (r < 0)
- return (r);
- }
- }
-
- /* Make Name. */
- r = enc_uint64(a, kName);
- if (r < 0)
- return (r);
-
- /* Write Name size. */
- r = enc_uint64(a, zip->total_bytes_entry_name+1);
- if (r < 0)
- return (r);
-
- /* Write dmy byte. */
- r = enc_uint64(a, 0);
- if (r < 0)
- return (r);
-
- file = zip->file_list.first;
- for (;file != NULL; file = file->next) {
- r = (int)compress_out(a, file->utf16name, file->name_len+2,
- ARCHIVE_Z_RUN);
- if (r < 0)
- return (r);
- }
-
- /* Make MTime. */
- r = make_time(a, kMTime, MTIME_IS_SET, MTIME);
- if (r < 0)
- return (r);
-
- /* Make CTime. */
- r = make_time(a, kCTime, CTIME_IS_SET, CTIME);
- if (r < 0)
- return (r);
-
- /* Make ATime. */
- r = make_time(a, kATime, ATIME_IS_SET, ATIME);
- if (r < 0)
- return (r);
-
- /* Make Attributes. */
- r = enc_uint64(a, kAttributes);
- if (r < 0)
- return (r);
-
- /* Write Attributes size. */
- r = enc_uint64(a, 2 + zip->total_number_entry * 4);
- if (r < 0)
- return (r);
-
- /* Write "All Are Defined". */
- r = enc_uint64(a, 1);
- if (r < 0)
- return (r);
-
- /* Write dmy byte. */
- r = enc_uint64(a, 0);
- if (r < 0)
- return (r);
-
- file = zip->file_list.first;
- for (;file != NULL; file = file->next) {
- /*
- * High 16bits is unix mode.
- * Low 16bits is Windows attributes.
- */
- uint32_t encattr, attr;
- if (file->dir)
- attr = 0x8010;
- else
- attr = 0x8020;
- if ((file->mode & 0222) == 0)
- attr |= 1;/* Read Only. */
- attr |= ((uint32_t)file->mode) << 16;
- archive_le32enc(&encattr, attr);
- r = (int)compress_out(a, &encattr, 4, ARCHIVE_Z_RUN);
- if (r < 0)
- return (r);
- }
-
- /* Write End. */
- r = enc_uint64(a, kEnd);
- if (r < 0)
- return (r);
-
- /* Write End. */
- r = enc_uint64(a, kEnd);
- if (r < 0)
- return (r);
-
- return (ARCHIVE_OK);
-}
-
-
-static int
-_7z_free(struct archive_write *a)
-{
- struct _7zip *zip = (struct _7zip *)a->format_data;
-
- /* Close the temporary file. */
- if (zip->temp_fd >= 0)
- close(zip->temp_fd);
-
- file_free_register(zip);
- compression_end(&(a->archive), &(zip->stream));
- free(zip->coder.props);
- free(zip);
-
- return (ARCHIVE_OK);
-}
-
-static int
-file_cmp_node(const struct archive_rb_node *n1,
- const struct archive_rb_node *n2)
-{
- const struct file *f1 = (const struct file *)n1;
- const struct file *f2 = (const struct file *)n2;
-
- if (f1->name_len == f2->name_len)
- return (memcmp(f1->utf16name, f2->utf16name, f1->name_len));
- return (f1->name_len > f2->name_len)?1:-1;
-}
-
-static int
-file_cmp_key(const struct archive_rb_node *n, const void *key)
-{
- const struct file *f = (const struct file *)n;
-
- return (f->name_len - *(const char *)key);
-}
-
-static int
-file_new(struct archive_write *a, struct archive_entry *entry,
- struct file **newfile)
-{
- struct _7zip *zip;
- struct file *file;
- const char *u16;
- size_t u16len;
- int ret = ARCHIVE_OK;
-
- zip = (struct _7zip *)a->format_data;
- *newfile = NULL;
-
- file = calloc(1, sizeof(*file));
- if (file == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
-
- if (0 > archive_entry_pathname_l(entry, &u16, &u16len, zip->sconv)) {
- if (errno == ENOMEM) {
- free(file);
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for UTF-16LE");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "A filename cannot be converted to UTF-16LE;"
- "You should disable making Joliet extension");
- ret = ARCHIVE_WARN;
- }
- file->utf16name = malloc(u16len + 2);
- if (file->utf16name == NULL) {
- free(file);
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Name");
- return (ARCHIVE_FATAL);
- }
- memcpy(file->utf16name, u16, u16len);
- file->utf16name[u16len+0] = 0;
- file->utf16name[u16len+1] = 0;
- file->name_len = (unsigned)u16len;
- file->mode = archive_entry_mode(entry);
- if (archive_entry_filetype(entry) == AE_IFREG)
- file->size = archive_entry_size(entry);
- else
- archive_entry_set_size(entry, 0);
- if (archive_entry_filetype(entry) == AE_IFDIR)
- file->dir = 1;
- else if (archive_entry_filetype(entry) == AE_IFLNK)
- file->size = strlen(archive_entry_symlink(entry));
- if (archive_entry_mtime_is_set(entry)) {
- file->flg |= MTIME_IS_SET;
- file->times[MTIME].time = archive_entry_mtime(entry);
- file->times[MTIME].time_ns = archive_entry_mtime_nsec(entry);
- }
- if (archive_entry_atime_is_set(entry)) {
- file->flg |= ATIME_IS_SET;
- file->times[ATIME].time = archive_entry_atime(entry);
- file->times[ATIME].time_ns = archive_entry_atime_nsec(entry);
- }
- if (archive_entry_ctime_is_set(entry)) {
- file->flg |= CTIME_IS_SET;
- file->times[CTIME].time = archive_entry_ctime(entry);
- file->times[CTIME].time_ns = archive_entry_ctime_nsec(entry);
- }
-
- *newfile = file;
- return (ret);
-}
-
-static void
-file_free(struct file *file)
-{
- free(file->utf16name);
- free(file);
-}
-
-static void
-file_register(struct _7zip *zip, struct file *file)
-{
- file->next = NULL;
- *zip->file_list.last = file;
- zip->file_list.last = &(file->next);
-}
-
-static void
-file_init_register(struct _7zip *zip)
-{
- zip->file_list.first = NULL;
- zip->file_list.last = &(zip->file_list.first);
-}
-
-static void
-file_free_register(struct _7zip *zip)
-{
- struct file *file, *file_next;
-
- file = zip->file_list.first;
- while (file != NULL) {
- file_next = file->next;
- file_free(file);
- file = file_next;
- }
-}
-
-static void
-file_register_empty(struct _7zip *zip, struct file *file)
-{
- file->next = NULL;
- *zip->empty_list.last = file;
- zip->empty_list.last = &(file->next);
-}
-
-static void
-file_init_register_empty(struct _7zip *zip)
-{
- zip->empty_list.first = NULL;
- zip->empty_list.last = &(zip->empty_list.first);
-}
-
-#if !defined(HAVE_ZLIB_H) || !defined(HAVE_BZLIB_H) ||\
- !defined(BZ_CONFIG_ERROR) || !defined(HAVE_LZMA_H)
-static int
-compression_unsupported_encoder(struct archive *a,
- struct la_zstream *lastrm, const char *name)
-{
-
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "%s compression not supported on this platform", name);
- lastrm->valid = 0;
- lastrm->real_stream = NULL;
- return (ARCHIVE_FAILED);
-}
-#endif
-
-/*
- * _7_COPY compressor.
- */
-static int
-compression_init_encoder_copy(struct archive *a, struct la_zstream *lastrm)
-{
-
- if (lastrm->valid)
- compression_end(a, lastrm);
- lastrm->valid = 1;
- lastrm->code = compression_code_copy;
- lastrm->end = compression_end_copy;
- return (ARCHIVE_OK);
-}
-
-static int
-compression_code_copy(struct archive *a,
- struct la_zstream *lastrm, enum la_zaction action)
-{
- size_t bytes;
-
- (void)a; /* UNUSED */
- if (lastrm->avail_out > lastrm->avail_in)
- bytes = lastrm->avail_in;
- else
- bytes = lastrm->avail_out;
- if (bytes) {
- memcpy(lastrm->next_out, lastrm->next_in, bytes);
- lastrm->next_in += bytes;
- lastrm->avail_in -= bytes;
- lastrm->total_in += bytes;
- lastrm->next_out += bytes;
- lastrm->avail_out -= bytes;
- lastrm->total_out += bytes;
- }
- if (action == ARCHIVE_Z_FINISH && lastrm->avail_in == 0)
- return (ARCHIVE_EOF);
- return (ARCHIVE_OK);
-}
-
-static int
-compression_end_copy(struct archive *a, struct la_zstream *lastrm)
-{
- (void)a; /* UNUSED */
- lastrm->valid = 0;
- return (ARCHIVE_OK);
-}
-
-/*
- * _7_DEFLATE compressor.
- */
-#ifdef HAVE_ZLIB_H
-static int
-compression_init_encoder_deflate(struct archive *a,
- struct la_zstream *lastrm, int level, int withheader)
-{
- z_stream *strm;
-
- if (lastrm->valid)
- compression_end(a, lastrm);
- strm = calloc(1, sizeof(*strm));
- if (strm == NULL) {
- archive_set_error(a, ENOMEM,
- "Can't allocate memory for gzip stream");
- return (ARCHIVE_FATAL);
- }
- /* zlib.h is not const-correct, so we need this one bit
- * of ugly hackery to convert a const * pointer to
- * a non-const pointer. */
- strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
- strm->avail_in = (uInt)lastrm->avail_in;
- strm->total_in = (uLong)lastrm->total_in;
- strm->next_out = lastrm->next_out;
- strm->avail_out = (uInt)lastrm->avail_out;
- strm->total_out = (uLong)lastrm->total_out;
- if (deflateInit2(strm, level, Z_DEFLATED,
- (withheader)?15:-15,
- 8, Z_DEFAULT_STRATEGY) != Z_OK) {
- free(strm);
- lastrm->real_stream = NULL;
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library");
- return (ARCHIVE_FATAL);
- }
- lastrm->real_stream = strm;
- lastrm->valid = 1;
- lastrm->code = compression_code_deflate;
- lastrm->end = compression_end_deflate;
- return (ARCHIVE_OK);
-}
-
-static int
-compression_code_deflate(struct archive *a,
- struct la_zstream *lastrm, enum la_zaction action)
-{
- z_stream *strm;
- int r;
-
- strm = (z_stream *)lastrm->real_stream;
- /* zlib.h is not const-correct, so we need this one bit
- * of ugly hackery to convert a const * pointer to
- * a non-const pointer. */
- strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
- strm->avail_in = (uInt)lastrm->avail_in;
- strm->total_in = (uLong)lastrm->total_in;
- strm->next_out = lastrm->next_out;
- strm->avail_out = (uInt)lastrm->avail_out;
- strm->total_out = (uLong)lastrm->total_out;
- r = deflate(strm,
- (action == ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH);
- lastrm->next_in = strm->next_in;
- lastrm->avail_in = strm->avail_in;
- lastrm->total_in = strm->total_in;
- lastrm->next_out = strm->next_out;
- lastrm->avail_out = strm->avail_out;
- lastrm->total_out = strm->total_out;
- switch (r) {
- case Z_OK:
- return (ARCHIVE_OK);
- case Z_STREAM_END:
- return (ARCHIVE_EOF);
- default:
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "GZip compression failed:"
- " deflate() call returned status %d", r);
- return (ARCHIVE_FATAL);
- }
-}
-
-static int
-compression_end_deflate(struct archive *a, struct la_zstream *lastrm)
-{
- z_stream *strm;
- int r;
-
- strm = (z_stream *)lastrm->real_stream;
- r = deflateEnd(strm);
- free(strm);
- lastrm->real_stream = NULL;
- lastrm->valid = 0;
- if (r != Z_OK) {
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Failed to clean up compressor");
- return (ARCHIVE_FATAL);
- }
- return (ARCHIVE_OK);
-}
-#else
-static int
-compression_init_encoder_deflate(struct archive *a,
- struct la_zstream *lastrm, int level, int withheader)
-{
-
- (void) level; /* UNUSED */
- (void) withheader; /* UNUSED */
- if (lastrm->valid)
- compression_end(a, lastrm);
- return (compression_unsupported_encoder(a, lastrm, "deflate"));
-}
-#endif
-
-/*
- * _7_BZIP2 compressor.
- */
-#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
-static int
-compression_init_encoder_bzip2(struct archive *a,
- struct la_zstream *lastrm, int level)
-{
- bz_stream *strm;
-
- if (lastrm->valid)
- compression_end(a, lastrm);
- strm = calloc(1, sizeof(*strm));
- if (strm == NULL) {
- archive_set_error(a, ENOMEM,
- "Can't allocate memory for bzip2 stream");
- return (ARCHIVE_FATAL);
- }
- /* bzlib.h is not const-correct, so we need this one bit
- * of ugly hackery to convert a const * pointer to
- * a non-const pointer. */
- strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
- strm->avail_in = (uint32_t)lastrm->avail_in;
- strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
- strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
- strm->next_out = (char *)lastrm->next_out;
- strm->avail_out = (uint32_t)lastrm->avail_out;
- strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
- strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
- if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) {
- free(strm);
- lastrm->real_stream = NULL;
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library");
- return (ARCHIVE_FATAL);
- }
- lastrm->real_stream = strm;
- lastrm->valid = 1;
- lastrm->code = compression_code_bzip2;
- lastrm->end = compression_end_bzip2;
- return (ARCHIVE_OK);
-}
-
-static int
-compression_code_bzip2(struct archive *a,
- struct la_zstream *lastrm, enum la_zaction action)
-{
- bz_stream *strm;
- int r;
-
- strm = (bz_stream *)lastrm->real_stream;
- /* bzlib.h is not const-correct, so we need this one bit
- * of ugly hackery to convert a const * pointer to
- * a non-const pointer. */
- strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
- strm->avail_in = (uint32_t)lastrm->avail_in;
- strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
- strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
- strm->next_out = (char *)lastrm->next_out;
- strm->avail_out = (uint32_t)lastrm->avail_out;
- strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
- strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
- r = BZ2_bzCompress(strm,
- (action == ARCHIVE_Z_FINISH)? BZ_FINISH: BZ_RUN);
- lastrm->next_in = (const unsigned char *)strm->next_in;
- lastrm->avail_in = strm->avail_in;
- lastrm->total_in =
- (((uint64_t)(uint32_t)strm->total_in_hi32) << 32)
- + (uint64_t)(uint32_t)strm->total_in_lo32;
- lastrm->next_out = (unsigned char *)strm->next_out;
- lastrm->avail_out = strm->avail_out;
- lastrm->total_out =
- (((uint64_t)(uint32_t)strm->total_out_hi32) << 32)
- + (uint64_t)(uint32_t)strm->total_out_lo32;
- switch (r) {
- case BZ_RUN_OK: /* Non-finishing */
- case BZ_FINISH_OK: /* Finishing: There's more work to do */
- return (ARCHIVE_OK);
- case BZ_STREAM_END: /* Finishing: all done */
- /* Only occurs in finishing case */
- return (ARCHIVE_EOF);
- default:
- /* Any other return value indicates an error */
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Bzip2 compression failed:"
- " BZ2_bzCompress() call returned status %d", r);
- return (ARCHIVE_FATAL);
- }
-}
-
-static int
-compression_end_bzip2(struct archive *a, struct la_zstream *lastrm)
-{
- bz_stream *strm;
- int r;
-
- strm = (bz_stream *)lastrm->real_stream;
- r = BZ2_bzCompressEnd(strm);
- free(strm);
- lastrm->real_stream = NULL;
- lastrm->valid = 0;
- if (r != BZ_OK) {
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Failed to clean up compressor");
- return (ARCHIVE_FATAL);
- }
- return (ARCHIVE_OK);
-}
-
-#else
-static int
-compression_init_encoder_bzip2(struct archive *a,
- struct la_zstream *lastrm, int level)
-{
-
- (void) level; /* UNUSED */
- if (lastrm->valid)
- compression_end(a, lastrm);
- return (compression_unsupported_encoder(a, lastrm, "bzip2"));
-}
-#endif
-
-/*
- * _7_LZMA1, _7_LZMA2 compressor.
- */
-#if defined(HAVE_LZMA_H)
-static int
-compression_init_encoder_lzma(struct archive *a,
- struct la_zstream *lastrm, int level, uint64_t filter_id)
-{
- static const lzma_stream lzma_init_data = LZMA_STREAM_INIT;
- lzma_stream *strm;
- lzma_filter *lzmafilters;
- lzma_options_lzma lzma_opt;
- int r;
-
- if (lastrm->valid)
- compression_end(a, lastrm);
- strm = calloc(1, sizeof(*strm) + sizeof(*lzmafilters) * 2);
- if (strm == NULL) {
- archive_set_error(a, ENOMEM,
- "Can't allocate memory for lzma stream");
- return (ARCHIVE_FATAL);
- }
- lzmafilters = (lzma_filter *)(strm+1);
- if (level > 9)
- level = 9;
- if (lzma_lzma_preset(&lzma_opt, level)) {
- free(strm);
- lastrm->real_stream = NULL;
- archive_set_error(a, ENOMEM,
- "Internal error initializing compression library");
- return (ARCHIVE_FATAL);
- }
- lzmafilters[0].id = filter_id;
- lzmafilters[0].options = &lzma_opt;
- lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */
-
- r = lzma_properties_size(&(lastrm->prop_size), lzmafilters);
- if (r != LZMA_OK) {
- free(strm);
- lastrm->real_stream = NULL;
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "lzma_properties_size failed");
- return (ARCHIVE_FATAL);
- }
- if (lastrm->prop_size) {
- lastrm->props = malloc(lastrm->prop_size);
- if (lastrm->props == NULL) {
- free(strm);
- lastrm->real_stream = NULL;
- archive_set_error(a, ENOMEM,
- "Cannot allocate memory");
- return (ARCHIVE_FATAL);
- }
- r = lzma_properties_encode(lzmafilters, lastrm->props);
- if (r != LZMA_OK) {
- free(strm);
- lastrm->real_stream = NULL;
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "lzma_properties_encode failed");
- return (ARCHIVE_FATAL);
- }
- }
-
- *strm = lzma_init_data;
- r = lzma_raw_encoder(strm, lzmafilters);
- switch (r) {
- case LZMA_OK:
- lastrm->real_stream = strm;
- lastrm->valid = 1;
- lastrm->code = compression_code_lzma;
- lastrm->end = compression_end_lzma;
- r = ARCHIVE_OK;
- break;
- case LZMA_MEM_ERROR:
- free(strm);
- lastrm->real_stream = NULL;
- archive_set_error(a, ENOMEM,
- "Internal error initializing compression library: "
- "Cannot allocate memory");
- r = ARCHIVE_FATAL;
- break;
- default:
- free(strm);
- lastrm->real_stream = NULL;
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library: "
- "It's a bug in liblzma");
- r = ARCHIVE_FATAL;
- break;
- }
- return (r);
-}
-
-static int
-compression_init_encoder_lzma1(struct archive *a,
- struct la_zstream *lastrm, int level)
-{
- return compression_init_encoder_lzma(a, lastrm, level,
- LZMA_FILTER_LZMA1);
-}
-
-static int
-compression_init_encoder_lzma2(struct archive *a,
- struct la_zstream *lastrm, int level)
-{
- return compression_init_encoder_lzma(a, lastrm, level,
- LZMA_FILTER_LZMA2);
-}
-
-static int
-compression_code_lzma(struct archive *a,
- struct la_zstream *lastrm, enum la_zaction action)
-{
- lzma_stream *strm;
- int r;
-
- strm = (lzma_stream *)lastrm->real_stream;
- strm->next_in = lastrm->next_in;
- strm->avail_in = lastrm->avail_in;
- strm->total_in = lastrm->total_in;
- strm->next_out = lastrm->next_out;
- strm->avail_out = lastrm->avail_out;
- strm->total_out = lastrm->total_out;
- r = lzma_code(strm,
- (action == ARCHIVE_Z_FINISH)? LZMA_FINISH: LZMA_RUN);
- lastrm->next_in = strm->next_in;
- lastrm->avail_in = strm->avail_in;
- lastrm->total_in = strm->total_in;
- lastrm->next_out = strm->next_out;
- lastrm->avail_out = strm->avail_out;
- lastrm->total_out = strm->total_out;
- switch (r) {
- case LZMA_OK:
- /* Non-finishing case */
- return (ARCHIVE_OK);
- case LZMA_STREAM_END:
- /* This return can only occur in finishing case. */
- return (ARCHIVE_EOF);
- case LZMA_MEMLIMIT_ERROR:
- archive_set_error(a, ENOMEM,
- "lzma compression error:"
- " %ju MiB would have been needed",
- (uintmax_t)((lzma_memusage(strm) + 1024 * 1024 -1)
- / (1024 * 1024)));
- return (ARCHIVE_FATAL);
- default:
- /* Any other return value indicates an error */
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "lzma compression failed:"
- " lzma_code() call returned status %d", r);
- return (ARCHIVE_FATAL);
- }
-}
-
-static int
-compression_end_lzma(struct archive *a, struct la_zstream *lastrm)
-{
- lzma_stream *strm;
-
- (void)a; /* UNUSED */
- strm = (lzma_stream *)lastrm->real_stream;
- lzma_end(strm);
- free(strm);
- lastrm->valid = 0;
- lastrm->real_stream = NULL;
- return (ARCHIVE_OK);
-}
-#else
-static int
-compression_init_encoder_lzma1(struct archive *a,
- struct la_zstream *lastrm, int level)
-{
-
- (void) level; /* UNUSED */
- if (lastrm->valid)
- compression_end(a, lastrm);
- return (compression_unsupported_encoder(a, lastrm, "lzma"));
-}
-static int
-compression_init_encoder_lzma2(struct archive *a,
- struct la_zstream *lastrm, int level)
-{
-
- (void) level; /* UNUSED */
- if (lastrm->valid)
- compression_end(a, lastrm);
- return (compression_unsupported_encoder(a, lastrm, "lzma"));
-}
-#endif
-
-/*
- * _7_PPMD compressor.
- */
-static void
-ppmd_write(void *p, Byte b)
-{
- struct archive_write *a = ((IByteOut *)p)->a;
- struct _7zip *zip = (struct _7zip *)(a->format_data);
- struct la_zstream *lastrm = &(zip->stream);
- struct ppmd_stream *strm;
-
- if (lastrm->avail_out) {
- *lastrm->next_out++ = b;
- lastrm->avail_out--;
- lastrm->total_out++;
- return;
- }
- strm = (struct ppmd_stream *)lastrm->real_stream;
- if (strm->buff_ptr < strm->buff_end) {
- *strm->buff_ptr++ = b;
- strm->buff_bytes++;
- }
-}
-
-static int
-compression_init_encoder_ppmd(struct archive *a,
- struct la_zstream *lastrm, unsigned maxOrder, uint32_t msize)
-{
- struct ppmd_stream *strm;
- uint8_t *props;
- int r;
-
- if (lastrm->valid)
- compression_end(a, lastrm);
- strm = calloc(1, sizeof(*strm));
- if (strm == NULL) {
- archive_set_error(a, ENOMEM,
- "Can't allocate memory for PPMd");
- return (ARCHIVE_FATAL);
- }
- strm->buff = malloc(32);
- if (strm->buff == NULL) {
- free(strm);
- archive_set_error(a, ENOMEM,
- "Can't allocate memory for PPMd");
- return (ARCHIVE_FATAL);
- }
- strm->buff_ptr = strm->buff;
- strm->buff_end = strm->buff + 32;
-
- props = malloc(1+4);
- if (props == NULL) {
- free(strm->buff);
- free(strm);
- archive_set_error(a, ENOMEM,
- "Coludn't allocate memory for PPMd");
- return (ARCHIVE_FATAL);
- }
- props[0] = maxOrder;
- archive_le32enc(props+1, msize);
- __archive_ppmd7_functions.Ppmd7_Construct(&strm->ppmd7_context);
- r = __archive_ppmd7_functions.Ppmd7_Alloc(
- &strm->ppmd7_context, msize);
- if (r == 0) {
- free(strm->buff);
- free(strm);
- free(props);
- archive_set_error(a, ENOMEM,
- "Coludn't allocate memory for PPMd");
- return (ARCHIVE_FATAL);
- }
- __archive_ppmd7_functions.Ppmd7_Init(&(strm->ppmd7_context), maxOrder);
- strm->byteout.a = (struct archive_write *)a;
- strm->byteout.Write = ppmd_write;
- strm->range_enc.Stream = &(strm->byteout);
- __archive_ppmd7_functions.Ppmd7z_RangeEnc_Init(&(strm->range_enc));
- strm->stat = 0;
-
- lastrm->real_stream = strm;
- lastrm->valid = 1;
- lastrm->code = compression_code_ppmd;
- lastrm->end = compression_end_ppmd;
- lastrm->prop_size = 5;
- lastrm->props = props;
- return (ARCHIVE_OK);
-}
-
-static int
-compression_code_ppmd(struct archive *a,
- struct la_zstream *lastrm, enum la_zaction action)
-{
- struct ppmd_stream *strm;
-
- (void)a; /* UNUSED */
-
- strm = (struct ppmd_stream *)lastrm->real_stream;
-
- /* Copy encoded data if there are remaining bytes from previous call. */
- if (strm->buff_bytes) {
- uint8_t *p = strm->buff_ptr - strm->buff_bytes;
- while (lastrm->avail_out && strm->buff_bytes) {
- *lastrm->next_out++ = *p++;
- lastrm->avail_out--;
- lastrm->total_out++;
- strm->buff_bytes--;
- }
- if (strm->buff_bytes)
- return (ARCHIVE_OK);
- if (strm->stat == 1)
- return (ARCHIVE_EOF);
- strm->buff_ptr = strm->buff;
- }
- while (lastrm->avail_in && lastrm->avail_out) {
- __archive_ppmd7_functions.Ppmd7_EncodeSymbol(
- &(strm->ppmd7_context), &(strm->range_enc),
- *lastrm->next_in++);
- lastrm->avail_in--;
- lastrm->total_in++;
- }
- if (lastrm->avail_in == 0 && action == ARCHIVE_Z_FINISH) {
- __archive_ppmd7_functions.Ppmd7z_RangeEnc_FlushData(
- &(strm->range_enc));
- strm->stat = 1;
- /* Return EOF if there are no remaining bytes. */
- if (strm->buff_bytes == 0)
- return (ARCHIVE_EOF);
- }
- return (ARCHIVE_OK);
-}
-
-static int
-compression_end_ppmd(struct archive *a, struct la_zstream *lastrm)
-{
- struct ppmd_stream *strm;
-
- (void)a; /* UNUSED */
-
- strm = (struct ppmd_stream *)lastrm->real_stream;
- __archive_ppmd7_functions.Ppmd7_Free(&strm->ppmd7_context);
- free(strm->buff);
- free(strm);
- lastrm->real_stream = NULL;
- lastrm->valid = 0;
- return (ARCHIVE_OK);
-}
-
-/*
- * Universal compressor initializer.
- */
-static int
-_7z_compression_init_encoder(struct archive_write *a, unsigned compression,
- int compression_level)
-{
- struct _7zip *zip;
- int r;
-
- zip = (struct _7zip *)a->format_data;
- switch (compression) {
- case _7Z_DEFLATE:
- r = compression_init_encoder_deflate(
- &(a->archive), &(zip->stream),
- compression_level, 0);
- break;
- case _7Z_BZIP2:
- r = compression_init_encoder_bzip2(
- &(a->archive), &(zip->stream),
- compression_level);
- break;
- case _7Z_LZMA1:
- r = compression_init_encoder_lzma1(
- &(a->archive), &(zip->stream),
- compression_level);
- break;
- case _7Z_LZMA2:
- r = compression_init_encoder_lzma2(
- &(a->archive), &(zip->stream),
- compression_level);
- break;
- case _7Z_PPMD:
- r = compression_init_encoder_ppmd(
- &(a->archive), &(zip->stream),
- PPMD7_DEFAULT_ORDER, PPMD7_DEFAULT_MEM_SIZE);
- break;
- case _7Z_COPY:
- default:
- r = compression_init_encoder_copy(
- &(a->archive), &(zip->stream));
- break;
- }
- if (r == ARCHIVE_OK) {
- zip->stream.total_in = 0;
- zip->stream.next_out = zip->wbuff;
- zip->stream.avail_out = sizeof(zip->wbuff);
- zip->stream.total_out = 0;
- }
-
- return (r);
-}
-
-static int
-compression_code(struct archive *a, struct la_zstream *lastrm,
- enum la_zaction action)
-{
- if (lastrm->valid)
- return (lastrm->code(a, lastrm, action));
- return (ARCHIVE_OK);
-}
-
-static int
-compression_end(struct archive *a, struct la_zstream *lastrm)
-{
- if (lastrm->valid) {
- lastrm->prop_size = 0;
- free(lastrm->props);
- lastrm->props = NULL;
- return (lastrm->end(a, lastrm));
- }
- return (ARCHIVE_OK);
-}
-
-
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_format_ar.c b/contrib/libs/libarchive/libarchive/archive_write_set_format_ar.c
deleted file mode 100644
index fc0de1e9f6..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_format_ar.c
+++ /dev/null
@@ -1,570 +0,0 @@
-/*-
- * Copyright (c) 2007 Kai Wang
- * Copyright (c) 2007 Tim Kientzle
- * 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
- * in this position and unchanged.
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_ar.c 201108 2009-12-28 03:28:21Z kientzle $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_private.h"
-#include "archive_write_private.h"
-#include "archive_write_set_format_private.h"
-
-struct ar_w {
- uint64_t entry_bytes_remaining;
- uint64_t entry_padding;
- int is_strtab;
- int has_strtab;
- char wrote_global_header;
- char *strtab;
-};
-
-/*
- * Define structure of the "ar" header.
- */
-#define AR_name_offset 0
-#define AR_name_size 16
-#define AR_date_offset 16
-#define AR_date_size 12
-#define AR_uid_offset 28
-#define AR_uid_size 6
-#define AR_gid_offset 34
-#define AR_gid_size 6
-#define AR_mode_offset 40
-#define AR_mode_size 8
-#define AR_size_offset 48
-#define AR_size_size 10
-#define AR_fmag_offset 58
-#define AR_fmag_size 2
-
-static int archive_write_set_format_ar(struct archive_write *);
-static int archive_write_ar_header(struct archive_write *,
- struct archive_entry *);
-static ssize_t archive_write_ar_data(struct archive_write *,
- const void *buff, size_t s);
-static int archive_write_ar_free(struct archive_write *);
-static int archive_write_ar_close(struct archive_write *);
-static int archive_write_ar_finish_entry(struct archive_write *);
-static const char *ar_basename(const char *path);
-static int format_octal(int64_t v, char *p, int s);
-static int format_decimal(int64_t v, char *p, int s);
-
-int
-archive_write_set_format_ar_bsd(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- int r;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_format_ar_bsd");
- r = archive_write_set_format_ar(a);
- if (r == ARCHIVE_OK) {
- a->archive.archive_format = ARCHIVE_FORMAT_AR_BSD;
- a->archive.archive_format_name = "ar (BSD)";
- }
- return (r);
-}
-
-int
-archive_write_set_format_ar_svr4(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- int r;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_format_ar_svr4");
- r = archive_write_set_format_ar(a);
- if (r == ARCHIVE_OK) {
- a->archive.archive_format = ARCHIVE_FORMAT_AR_GNU;
- a->archive.archive_format_name = "ar (GNU/SVR4)";
- }
- return (r);
-}
-
-/*
- * Generic initialization.
- */
-static int
-archive_write_set_format_ar(struct archive_write *a)
-{
- struct ar_w *ar;
-
- /* If someone else was already registered, unregister them. */
- if (a->format_free != NULL)
- (a->format_free)(a);
-
- ar = (struct ar_w *)calloc(1, sizeof(*ar));
- if (ar == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Can't allocate ar data");
- return (ARCHIVE_FATAL);
- }
- a->format_data = ar;
-
- a->format_name = "ar";
- a->format_write_header = archive_write_ar_header;
- a->format_write_data = archive_write_ar_data;
- a->format_close = archive_write_ar_close;
- a->format_free = archive_write_ar_free;
- a->format_finish_entry = archive_write_ar_finish_entry;
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_ar_header(struct archive_write *a, struct archive_entry *entry)
-{
- int ret, append_fn;
- char buff[60];
- char *ss, *se;
- struct ar_w *ar;
- const char *pathname;
- const char *filename;
- int64_t size;
-
- append_fn = 0;
- ar = (struct ar_w *)a->format_data;
- ar->is_strtab = 0;
- filename = NULL;
- size = archive_entry_size(entry);
-
-
- /*
- * Reject files with empty name.
- */
- pathname = archive_entry_pathname(entry);
- if (pathname == NULL || *pathname == '\0') {
- archive_set_error(&a->archive, EINVAL,
- "Invalid filename");
- return (ARCHIVE_WARN);
- }
-
- /*
- * If we are now at the beginning of the archive,
- * we need first write the ar global header.
- */
- if (!ar->wrote_global_header) {
- __archive_write_output(a, "!<arch>\n", 8);
- ar->wrote_global_header = 1;
- }
-
- memset(buff, ' ', 60);
- memcpy(&buff[AR_fmag_offset], "`\n", 2);
-
- if (strcmp(pathname, "/") == 0 ) {
- /* Entry is archive symbol table in GNU format */
- buff[AR_name_offset] = '/';
- goto stat;
- }
- if (strcmp(pathname, "/SYM64/") == 0) {
- /* Entry is archive symbol table in GNU 64-bit format */
- memcpy(buff + AR_name_offset, "/SYM64/", 7);
- goto stat;
- }
- if (strcmp(pathname, "__.SYMDEF") == 0) {
- /* Entry is archive symbol table in BSD format */
- memcpy(buff + AR_name_offset, "__.SYMDEF", 9);
- goto stat;
- }
- if (strcmp(pathname, "//") == 0) {
- /*
- * Entry is archive filename table, inform that we should
- * collect strtab in next _data call.
- */
- ar->is_strtab = 1;
- buff[AR_name_offset] = buff[AR_name_offset + 1] = '/';
- /*
- * For archive string table, only ar_size field should
- * be set.
- */
- goto size;
- }
-
- /*
- * Otherwise, entry is a normal archive member.
- * Strip leading paths from filenames, if any.
- */
- if ((filename = ar_basename(pathname)) == NULL) {
- /* Reject filenames with trailing "/" */
- archive_set_error(&a->archive, EINVAL,
- "Invalid filename");
- return (ARCHIVE_WARN);
- }
-
- if (a->archive.archive_format == ARCHIVE_FORMAT_AR_GNU) {
- /*
- * SVR4/GNU variant use a "/" to mark then end of the filename,
- * make it possible to have embedded spaces in the filename.
- * So, the longest filename here (without extension) is
- * actually 15 bytes.
- */
- if (strlen(filename) <= 15) {
- memcpy(&buff[AR_name_offset],
- filename, strlen(filename));
- buff[AR_name_offset + strlen(filename)] = '/';
- } else {
- /*
- * For filename longer than 15 bytes, GNU variant
- * makes use of a string table and instead stores the
- * offset of the real filename to in the ar_name field.
- * The string table should have been written before.
- */
- if (ar->has_strtab <= 0) {
- archive_set_error(&a->archive, EINVAL,
- "Can't find string table");
- return (ARCHIVE_WARN);
- }
-
- se = (char *)malloc(strlen(filename) + 3);
- if (se == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate filename buffer");
- return (ARCHIVE_FATAL);
- }
-
- memcpy(se, filename, strlen(filename));
- strcpy(se + strlen(filename), "/\n");
-
- ss = strstr(ar->strtab, se);
- free(se);
-
- if (ss == NULL) {
- archive_set_error(&a->archive, EINVAL,
- "Invalid string table");
- return (ARCHIVE_WARN);
- }
-
- /*
- * GNU variant puts "/" followed by digits into
- * ar_name field. These digits indicates the real
- * filename string's offset to the string table.
- */
- buff[AR_name_offset] = '/';
- if (format_decimal(ss - ar->strtab,
- buff + AR_name_offset + 1,
- AR_name_size - 1)) {
- archive_set_error(&a->archive, ERANGE,
- "string table offset too large");
- return (ARCHIVE_WARN);
- }
- }
- } else if (a->archive.archive_format == ARCHIVE_FORMAT_AR_BSD) {
- /*
- * BSD variant: for any file name which is more than
- * 16 chars or contains one or more embedded space(s), the
- * string "#1/" followed by the ASCII length of the name is
- * put into the ar_name field. The file size (stored in the
- * ar_size field) is incremented by the length of the name.
- * The name is then written immediately following the
- * archive header.
- */
- if (strlen(filename) <= 16 && strchr(filename, ' ') == NULL) {
- memcpy(&buff[AR_name_offset], filename, strlen(filename));
- buff[AR_name_offset + strlen(filename)] = ' ';
- }
- else {
- memcpy(buff + AR_name_offset, "#1/", 3);
- if (format_decimal(strlen(filename),
- buff + AR_name_offset + 3,
- AR_name_size - 3)) {
- archive_set_error(&a->archive, ERANGE,
- "File name too long");
- return (ARCHIVE_WARN);
- }
- append_fn = 1;
- size += strlen(filename);
- }
- }
-
-stat:
- if (format_decimal(archive_entry_mtime(entry), buff + AR_date_offset, AR_date_size)) {
- archive_set_error(&a->archive, ERANGE,
- "File modification time too large");
- return (ARCHIVE_WARN);
- }
- if (format_decimal(archive_entry_uid(entry), buff + AR_uid_offset, AR_uid_size)) {
- archive_set_error(&a->archive, ERANGE,
- "Numeric user ID too large");
- return (ARCHIVE_WARN);
- }
- if (format_decimal(archive_entry_gid(entry), buff + AR_gid_offset, AR_gid_size)) {
- archive_set_error(&a->archive, ERANGE,
- "Numeric group ID too large");
- return (ARCHIVE_WARN);
- }
- if (format_octal(archive_entry_mode(entry), buff + AR_mode_offset, AR_mode_size)) {
- archive_set_error(&a->archive, ERANGE,
- "Numeric mode too large");
- return (ARCHIVE_WARN);
- }
- /*
- * Sanity Check: A non-pseudo archive member should always be
- * a regular file.
- */
- if (filename != NULL && archive_entry_filetype(entry) != AE_IFREG) {
- archive_set_error(&a->archive, EINVAL,
- "Regular file required for non-pseudo member");
- return (ARCHIVE_WARN);
- }
-
-size:
- if (format_decimal(size, buff + AR_size_offset, AR_size_size)) {
- archive_set_error(&a->archive, ERANGE,
- "File size out of range");
- return (ARCHIVE_WARN);
- }
-
- ret = __archive_write_output(a, buff, 60);
- if (ret != ARCHIVE_OK)
- return (ret);
-
- ar->entry_bytes_remaining = size;
- ar->entry_padding = ar->entry_bytes_remaining % 2;
-
- if (append_fn > 0) {
- ret = __archive_write_output(a, filename, strlen(filename));
- if (ret != ARCHIVE_OK)
- return (ret);
- ar->entry_bytes_remaining -= strlen(filename);
- }
-
- return (ARCHIVE_OK);
-}
-
-static ssize_t
-archive_write_ar_data(struct archive_write *a, const void *buff, size_t s)
-{
- struct ar_w *ar;
- int ret;
-
- ar = (struct ar_w *)a->format_data;
- if (s > ar->entry_bytes_remaining)
- s = (size_t)ar->entry_bytes_remaining;
-
- if (ar->is_strtab > 0) {
- if (ar->has_strtab > 0) {
- archive_set_error(&a->archive, EINVAL,
- "More than one string tables exist");
- return (ARCHIVE_WARN);
- }
-
- ar->strtab = (char *)malloc(s + 1);
- if (ar->strtab == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate strtab buffer");
- return (ARCHIVE_FATAL);
- }
- memcpy(ar->strtab, buff, s);
- ar->strtab[s] = '\0';
- ar->has_strtab = 1;
- }
-
- ret = __archive_write_output(a, buff, s);
- if (ret != ARCHIVE_OK)
- return (ret);
-
- ar->entry_bytes_remaining -= s;
- return (s);
-}
-
-static int
-archive_write_ar_free(struct archive_write *a)
-{
- struct ar_w *ar;
-
- ar = (struct ar_w *)a->format_data;
-
- if (ar == NULL)
- return (ARCHIVE_OK);
-
- if (ar->has_strtab > 0) {
- free(ar->strtab);
- ar->strtab = NULL;
- }
-
- free(ar);
- a->format_data = NULL;
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_ar_close(struct archive_write *a)
-{
- struct ar_w *ar;
- int ret;
-
- /*
- * If we haven't written anything yet, we need to write
- * the ar global header now to make it a valid ar archive.
- */
- ar = (struct ar_w *)a->format_data;
- if (!ar->wrote_global_header) {
- ar->wrote_global_header = 1;
- ret = __archive_write_output(a, "!<arch>\n", 8);
- return (ret);
- }
-
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_ar_finish_entry(struct archive_write *a)
-{
- struct ar_w *ar;
- int ret;
-
- ar = (struct ar_w *)a->format_data;
-
- if (ar->entry_bytes_remaining != 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Entry remaining bytes larger than 0");
- return (ARCHIVE_WARN);
- }
-
- if (ar->entry_padding == 0) {
- return (ARCHIVE_OK);
- }
-
- if (ar->entry_padding != 1) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Padding wrong size: %ju should be 1 or 0",
- (uintmax_t)ar->entry_padding);
- return (ARCHIVE_WARN);
- }
-
- ret = __archive_write_output(a, "\n", 1);
- return (ret);
-}
-
-/*
- * Format a number into the specified field using base-8.
- * NB: This version is slightly different from the one in
- * _ustar.c
- */
-static int
-format_octal(int64_t v, char *p, int s)
-{
- int len;
- char *h;
-
- len = s;
- h = p;
-
- /* Octal values can't be negative, so use 0. */
- if (v < 0) {
- while (len-- > 0)
- *p++ = '0';
- return (-1);
- }
-
- p += s; /* Start at the end and work backwards. */
- do {
- *--p = (char)('0' + (v & 7));
- v >>= 3;
- } while (--s > 0 && v > 0);
-
- if (v == 0) {
- memmove(h, p, len - s);
- p = h + len - s;
- while (s-- > 0)
- *p++ = ' ';
- return (0);
- }
- /* If it overflowed, fill field with max value. */
- while (len-- > 0)
- *p++ = '7';
-
- return (-1);
-}
-
-/*
- * Format a number into the specified field using base-10.
- */
-static int
-format_decimal(int64_t v, char *p, int s)
-{
- int len;
- char *h;
-
- len = s;
- h = p;
-
- /* Negative values in ar header are meaningless, so use 0. */
- if (v < 0) {
- while (len-- > 0)
- *p++ = '0';
- return (-1);
- }
-
- p += s;
- do {
- *--p = (char)('0' + (v % 10));
- v /= 10;
- } while (--s > 0 && v > 0);
-
- if (v == 0) {
- memmove(h, p, len - s);
- p = h + len - s;
- while (s-- > 0)
- *p++ = ' ';
- return (0);
- }
- /* If it overflowed, fill field with max value. */
- while (len-- > 0)
- *p++ = '9';
-
- return (-1);
-}
-
-static const char *
-ar_basename(const char *path)
-{
- const char *endp, *startp;
-
- endp = path + strlen(path) - 1;
- /*
- * For filename with trailing slash(es), we return
- * NULL indicating an error.
- */
- if (*endp == '/')
- return (NULL);
-
- /* Find the start of the base */
- startp = endp;
- while (startp > path && *(startp - 1) != '/')
- startp--;
-
- return (startp);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_format_by_name.c b/contrib/libs/libarchive/libarchive/archive_write_set_format_by_name.c
deleted file mode 100644
index bfb4b3545f..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_format_by_name.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_by_name.c 201168 2009-12-29 06:15:32Z kientzle $");
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-
-/* A table that maps names to functions. */
-static const
-struct { const char *name; int (*setter)(struct archive *); } names[] =
-{
- { "7zip", archive_write_set_format_7zip },
- { "ar", archive_write_set_format_ar_bsd },
- { "arbsd", archive_write_set_format_ar_bsd },
- { "argnu", archive_write_set_format_ar_svr4 },
- { "arsvr4", archive_write_set_format_ar_svr4 },
- { "bin", archive_write_set_format_cpio_bin },
- { "bsdtar", archive_write_set_format_pax_restricted },
- { "cd9660", archive_write_set_format_iso9660 },
- { "cpio", archive_write_set_format_cpio },
- { "gnutar", archive_write_set_format_gnutar },
- { "iso", archive_write_set_format_iso9660 },
- { "iso9660", archive_write_set_format_iso9660 },
- { "mtree", archive_write_set_format_mtree },
- { "mtree-classic", archive_write_set_format_mtree_classic },
- { "newc", archive_write_set_format_cpio_newc },
- { "odc", archive_write_set_format_cpio_odc },
- { "oldtar", archive_write_set_format_v7tar },
- { "pax", archive_write_set_format_pax },
- { "paxr", archive_write_set_format_pax_restricted },
- { "posix", archive_write_set_format_pax },
- { "pwb", archive_write_set_format_cpio_pwb },
- { "raw", archive_write_set_format_raw },
- { "rpax", archive_write_set_format_pax_restricted },
- { "shar", archive_write_set_format_shar },
- { "shardump", archive_write_set_format_shar_dump },
- { "ustar", archive_write_set_format_ustar },
- { "v7tar", archive_write_set_format_v7tar },
- { "v7", archive_write_set_format_v7tar },
- { "warc", archive_write_set_format_warc },
- { "xar", archive_write_set_format_xar },
- { "zip", archive_write_set_format_zip },
- { NULL, NULL }
-};
-
-int
-archive_write_set_format_by_name(struct archive *a, const char *name)
-{
- int i;
-
- for (i = 0; names[i].name != NULL; i++) {
- if (strcmp(name, names[i].name) == 0)
- return ((names[i].setter)(a));
- }
-
- archive_set_error(a, EINVAL, "No such format '%s'", name);
- a->state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_format_cpio.c b/contrib/libs/libarchive/libarchive/archive_write_set_format_cpio.c
deleted file mode 100644
index 47152cc6a9..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_format_cpio.c
+++ /dev/null
@@ -1,11 +0,0 @@
-#include "archive_platform.h"
-#include "archive.h"
-
-/*
- * Set output format to the default 'cpio' format.
- */
-int
-archive_write_set_format_cpio(struct archive *_a)
-{
- return archive_write_set_format_cpio_odc(_a);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_format_cpio_binary.c b/contrib/libs/libarchive/libarchive/archive_write_set_format_cpio_binary.c
deleted file mode 100644
index d6ce35a7bc..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_format_cpio_binary.c
+++ /dev/null
@@ -1,610 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * Copyright (c) 2011-2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_cpio.c 201170 2009-12-29 06:34:23Z kientzle $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_private.h"
-#include "archive_write_private.h"
-#include "archive_write_set_format_private.h"
-
-static ssize_t archive_write_binary_data(struct archive_write *,
- const void *buff, size_t s);
-static int archive_write_binary_close(struct archive_write *);
-static int archive_write_binary_free(struct archive_write *);
-static int archive_write_binary_finish_entry(struct archive_write *);
-static int archive_write_binary_header(struct archive_write *,
- struct archive_entry *);
-static int archive_write_binary_options(struct archive_write *,
- const char *, const char *);
-static int write_header(struct archive_write *, struct archive_entry *);
-
-struct cpio {
- uint64_t entry_bytes_remaining;
-
- int64_t ino_next;
-
- struct { int64_t old; int new;} *ino_list;
- size_t ino_list_size;
- size_t ino_list_next;
-
- struct archive_string_conv *opt_sconv;
- struct archive_string_conv *sconv_default;
- int init_default_conversion;
-};
-
-/* This struct needs to be packed to get the header right */
-
-#if defined(__GNUC__)
-#define PACKED(x) x __attribute__((packed))
-#elif defined(_MSC_VER)
-#define PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop))
-#else
-#define PACKED(x) x
-#endif
-
-#define HSIZE 26
-
-PACKED(struct cpio_binary_header {
- uint16_t h_magic;
- uint16_t h_dev;
- uint16_t h_ino;
- uint16_t h_mode;
- uint16_t h_uid;
- uint16_t h_gid;
- uint16_t h_nlink;
- uint16_t h_majmin;
- uint32_t h_mtime;
- uint16_t h_namesize;
- uint32_t h_filesize;
-});
-
-/* Back in the day, the 7th Edition cpio.c had this, to
- * adapt to, as the comment said, "VAX, Interdata, ...":
- *
- * union { long l; short s[2]; char c[4]; } U;
- * #define MKSHORT(v,lv) {U.l=1L;if(U.c[0]) U.l=lv,v[0]=U.s[1],v[1]=U.s[0]; else U.l=lv,v[0]=U.s[0],v[1]=U.s[1];}
- * long mklong(v)
- * short v[];
- * {
- * U.l = 1;
- * if(U.c[0])
- * U.s[0] = v[1], U.s[1] = v[0];
- * else
- * U.s[0] = v[0], U.s[1] = v[1];
- * return U.l;
- * }
- *
- * Of course, that assumes that all machines have little-endian shorts,
- * and just adapts the others to the special endianness of the PDP-11.
- *
- * Now, we could do this:
- *
- * union { uint32_t l; uint16_t s[2]; uint8_t c[4]; } U;
- * #define PUTI16(v,sv) {U.s[0]=1;if(U.c[0]) v=sv; else U.s[0]=sv,U.c[2]=U.c[1],U.c[3]=U.c[0],v=U.s[1];}
- * #define PUTI32(v,lv) {char_t Ut;U.l=1;if(U.c[0]) U.l=lv,v[0]=U.s[1],v[1]=U.s[0]; else U.l=lv,Ut=U.c[0],U.c[0]=U.c[1],U.c[1]=Ut,Ut=U.c[2],U.c[2]=U.c[3],U.c[3]=Ut,v[0]=U.s[0],v[1]=U.s[1];}
- *
- * ...but it feels a little better to do it like this:
- */
-
-static uint16_t la_swap16(uint16_t in) {
- union {
- uint16_t s[2];
- uint8_t c[4];
- } U;
- U.s[0] = 1;
- if (U.c[0])
- return in;
- else {
- U.s[0] = in;
- U.c[2] = U.c[1];
- U.c[3] = U.c[0];
- return U.s[1];
- }
- /* NOTREACHED */
-}
-
-static uint32_t la_swap32(uint32_t in) {
- union {
- uint32_t l;
- uint16_t s[2];
- uint8_t c[4];
- } U;
- U.l = 1;
- if (U.c[0]) { /* Little-endian */
- uint16_t t;
- U.l = in;
- t = U.s[0];
- U.s[0] = U.s[1];
- U.s[1] = t;
- } else if (U.c[3]) { /* Big-endian */
- U.l = in;
- U.s[0] = la_swap16(U.s[0]);
- U.s[1] = la_swap16(U.s[1]);
- } else { /* PDP-endian */
- U.l = in;
- }
- return U.l;
-}
-
-/*
- * Set output format to the selected binary variant
- */
-static int
-archive_write_set_format_cpio_binary(struct archive *_a, int format)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct cpio *cpio;
-
- if (sizeof(struct cpio_binary_header) != HSIZE) {
- archive_set_error(&a->archive, EINVAL,
- "Binary cpio format not supported on this platform");
- return (ARCHIVE_FATAL);
- }
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_format_cpio_binary");
-
- /* If someone else was already registered, unregister them. */
- if (a->format_free != NULL)
- (a->format_free)(a);
-
- cpio = (struct cpio *)calloc(1, sizeof(*cpio));
- if (cpio == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data");
- return (ARCHIVE_FATAL);
- }
- a->format_data = cpio;
- a->format_name = "cpio";
- a->format_options = archive_write_binary_options;
- a->format_write_header = archive_write_binary_header;
- a->format_write_data = archive_write_binary_data;
- a->format_finish_entry = archive_write_binary_finish_entry;
- a->format_close = archive_write_binary_close;
- a->format_free = archive_write_binary_free;
- a->archive.archive_format = format;
- switch (format) {
- case ARCHIVE_FORMAT_CPIO_PWB:
- a->archive.archive_format_name = "PWB cpio";
- break;
- case ARCHIVE_FORMAT_CPIO_BIN_LE:
- a->archive.archive_format_name = "7th Edition cpio";
- break;
- default:
- archive_set_error(&a->archive, EINVAL, "binary format must be 'pwb' or 'bin'");
- return (ARCHIVE_FATAL);
- }
- return (ARCHIVE_OK);
-}
-
-/*
- * Set output format to PWB (6th Edition) binary format
- */
-int
-archive_write_set_format_cpio_pwb(struct archive *_a)
-{
- return archive_write_set_format_cpio_binary(_a, ARCHIVE_FORMAT_CPIO_PWB);
-}
-
-/*
- * Set output format to 7th Edition binary format
- */
-int
-archive_write_set_format_cpio_bin(struct archive *_a)
-{
- return archive_write_set_format_cpio_binary(_a, ARCHIVE_FORMAT_CPIO_BIN_LE);
-}
-
-static int
-archive_write_binary_options(struct archive_write *a, const char *key,
- const char *val)
-{
- struct cpio *cpio = (struct cpio *)a->format_data;
- int ret = ARCHIVE_FAILED;
-
- if (strcmp(key, "hdrcharset") == 0) {
- if (val == NULL || val[0] == 0)
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "%s: hdrcharset option needs a character-set name",
- a->format_name);
- else {
- cpio->opt_sconv = archive_string_conversion_to_charset(
- &a->archive, val, 0);
- if (cpio->opt_sconv != NULL)
- ret = ARCHIVE_OK;
- else
- ret = ARCHIVE_FATAL;
- }
- return (ret);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-/*
- * Ino values are as long as 64 bits on some systems; cpio format
- * only allows 16 bits and relies on the ino values to identify hardlinked
- * files. So, we can't merely "hash" the ino numbers since collisions
- * would corrupt the archive. Instead, we generate synthetic ino values
- * to store in the archive and maintain a map of original ino values to
- * synthetic ones so we can preserve hardlink information.
- *
- * TODO: Make this more efficient. It's not as bad as it looks (most
- * files don't have any hardlinks and we don't do any work here for those),
- * but it wouldn't be hard to do better.
- *
- * TODO: Work with dev/ino pairs here instead of just ino values.
- */
-static int
-synthesize_ino_value(struct cpio *cpio, struct archive_entry *entry)
-{
- int64_t ino = archive_entry_ino64(entry);
- int ino_new;
- size_t i;
-
- /*
- * If no index number was given, don't assign one. In
- * particular, this handles the end-of-archive marker
- * correctly by giving it a zero index value. (This is also
- * why we start our synthetic index numbers with one below.)
- */
- if (ino == 0)
- return (0);
-
- /* Don't store a mapping if we don't need to. */
- if (archive_entry_nlink(entry) < 2) {
- return (int)(++cpio->ino_next);
- }
-
- /* Look up old ino; if we have it, this is a hardlink
- * and we reuse the same value. */
- for (i = 0; i < cpio->ino_list_next; ++i) {
- if (cpio->ino_list[i].old == ino)
- return (cpio->ino_list[i].new);
- }
-
- /* Assign a new index number. */
- ino_new = (int)(++cpio->ino_next);
-
- /* Ensure space for the new mapping. */
- if (cpio->ino_list_size <= cpio->ino_list_next) {
- size_t newsize = cpio->ino_list_size < 512
- ? 512 : cpio->ino_list_size * 2;
- void *newlist = realloc(cpio->ino_list,
- sizeof(cpio->ino_list[0]) * newsize);
- if (newlist == NULL)
- return (-1);
-
- cpio->ino_list_size = newsize;
- cpio->ino_list = newlist;
- }
-
- /* Record and return the new value. */
- cpio->ino_list[cpio->ino_list_next].old = ino;
- cpio->ino_list[cpio->ino_list_next].new = ino_new;
- ++cpio->ino_list_next;
- return (ino_new);
-}
-
-
-static struct archive_string_conv *
-get_sconv(struct archive_write *a)
-{
- struct cpio *cpio;
- struct archive_string_conv *sconv;
-
- cpio = (struct cpio *)a->format_data;
- sconv = cpio->opt_sconv;
- if (sconv == NULL) {
- if (!cpio->init_default_conversion) {
- cpio->sconv_default =
- archive_string_default_conversion_for_write(
- &(a->archive));
- cpio->init_default_conversion = 1;
- }
- sconv = cpio->sconv_default;
- }
- return (sconv);
-}
-
-static int
-archive_write_binary_header(struct archive_write *a, struct archive_entry *entry)
-{
- const char *path;
- size_t len;
-
- if (archive_entry_filetype(entry) == 0 && archive_entry_hardlink(entry) == NULL) {
- archive_set_error(&a->archive, -1, "Filetype required");
- return (ARCHIVE_FAILED);
- }
-
- if (archive_entry_pathname_l(entry, &path, &len, get_sconv(a)) != 0
- && errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathname");
- return (ARCHIVE_FATAL);
- }
- if (len == 0 || path == NULL || path[0] == '\0') {
- archive_set_error(&a->archive, -1, "Pathname required");
- return (ARCHIVE_FAILED);
- }
-
- if (!archive_entry_size_is_set(entry) || archive_entry_size(entry) < 0) {
- archive_set_error(&a->archive, -1, "Size required");
- return (ARCHIVE_FAILED);
- }
- return write_header(a, entry);
-}
-
-static int
-write_header(struct archive_write *a, struct archive_entry *entry)
-{
- struct cpio *cpio;
- const char *p, *path;
- int pathlength, ret, ret_final;
- int64_t ino;
- struct cpio_binary_header h;
- struct archive_string_conv *sconv;
- struct archive_entry *entry_main;
- size_t len;
-
- cpio = (struct cpio *)a->format_data;
- ret_final = ARCHIVE_OK;
- sconv = get_sconv(a);
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Make sure the path separators in pathname, hardlink and symlink
- * are all slash '/', not the Windows path separator '\'. */
- entry_main = __la_win_entry_in_posix_pathseparator(entry);
- if (entry_main == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate ustar data");
- return(ARCHIVE_FATAL);
- }
- if (entry != entry_main)
- entry = entry_main;
- else
- entry_main = NULL;
-#else
- entry_main = NULL;
-#endif
-
- ret = archive_entry_pathname_l(entry, &path, &len, sconv);
- if (ret != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathname");
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate pathname '%s' to %s",
- archive_entry_pathname(entry),
- archive_string_conversion_charset_name(sconv));
- ret_final = ARCHIVE_WARN;
- }
- /* Include trailing null */
- pathlength = (int)len + 1;
-
- h.h_magic = la_swap16(070707);
- h.h_dev = la_swap16(archive_entry_dev(entry));
-
- ino = synthesize_ino_value(cpio, entry);
- if (ino < 0) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for ino translation table");
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- } else if (ino > 077777) {
- archive_set_error(&a->archive, ERANGE,
- "Too many files for this cpio format");
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- h.h_ino = la_swap16((uint16_t)ino);
-
- h.h_mode = archive_entry_mode(entry);
- if (((h.h_mode & AE_IFMT) == AE_IFSOCK) || ((h.h_mode & AE_IFMT) == AE_IFIFO)) {
- archive_set_error(&a->archive, EINVAL,
- "sockets and fifos cannot be represented in the binary cpio formats");
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- if (a->archive.archive_format == ARCHIVE_FORMAT_CPIO_PWB) {
- if ((h.h_mode & AE_IFMT) == AE_IFLNK) {
- archive_set_error(&a->archive, EINVAL,
- "symbolic links cannot be represented in the PWB cpio format");
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- /* we could turn off AE_IFREG here, but it does no harm, */
- /* and allows v7 cpio to read the entry without confusion */
- }
- h.h_mode = la_swap16(h.h_mode);
-
- h.h_uid = la_swap16((uint16_t)archive_entry_uid(entry));
- h.h_gid = la_swap16((uint16_t)archive_entry_gid(entry));
- h.h_nlink = la_swap16((uint16_t)archive_entry_nlink(entry));
-
- if (archive_entry_filetype(entry) == AE_IFBLK
- || archive_entry_filetype(entry) == AE_IFCHR)
- h.h_majmin = la_swap16(archive_entry_rdev(entry));
- else
- h.h_majmin = 0;
-
- h.h_mtime = la_swap32((uint32_t)archive_entry_mtime(entry));
- h.h_namesize = la_swap16(pathlength);
-
- /* Non-regular files don't store bodies. */
- if (archive_entry_filetype(entry) != AE_IFREG)
- archive_entry_set_size(entry, 0);
-
- /* Symlinks get the link written as the body of the entry. */
- ret = archive_entry_symlink_l(entry, &p, &len, sconv);
- if (ret != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Linkname");
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate linkname '%s' to %s",
- archive_entry_symlink(entry),
- archive_string_conversion_charset_name(sconv));
- ret_final = ARCHIVE_WARN;
- }
-
- if (len > 0 && p != NULL && *p != '\0') {
- if (a->archive.archive_format == ARCHIVE_FORMAT_CPIO_PWB) {
- archive_set_error(&a->archive, EINVAL,
- "symlinks are not supported by UNIX V6 or by PWB cpio");
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- h.h_filesize = la_swap32((uint32_t)strlen(p)); /* symlink */
- } else {
- if ((a->archive.archive_format == ARCHIVE_FORMAT_CPIO_PWB) &&
- (archive_entry_size(entry) > 256*256*256-1)) {
- archive_set_error(&a->archive, ERANGE,
- "File is too large for PWB binary cpio format.");
- ret_final = ARCHIVE_FAILED;
- goto exit_write_header;
- } else if (archive_entry_size(entry) > INT32_MAX) {
- archive_set_error(&a->archive, ERANGE,
- "File is too large for binary cpio format.");
- ret_final = ARCHIVE_FAILED;
- goto exit_write_header;
- }
- h.h_filesize = la_swap32((uint32_t)archive_entry_size(entry)); /* file */
- }
-
- ret = __archive_write_output(a, &h, HSIZE);
- if (ret != ARCHIVE_OK) {
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
-
- ret = __archive_write_output(a, path, pathlength);
- if ((ret == ARCHIVE_OK) && ((pathlength % 2) != 0))
- ret = __archive_write_nulls(a, 1);
- if (ret != ARCHIVE_OK) {
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
-
- cpio->entry_bytes_remaining = archive_entry_size(entry);
- if ((cpio->entry_bytes_remaining % 2) != 0)
- cpio->entry_bytes_remaining++;
-
- /* Write the symlink now. */
- if (p != NULL && *p != '\0') {
- ret = __archive_write_output(a, p, strlen(p));
- if ((ret == ARCHIVE_OK) && ((strlen(p) % 2) != 0))
- ret = __archive_write_nulls(a, 1);
- if (ret != ARCHIVE_OK) {
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- }
-
-exit_write_header:
- archive_entry_free(entry_main);
- return (ret_final);
-}
-
-static ssize_t
-archive_write_binary_data(struct archive_write *a, const void *buff, size_t s)
-{
- struct cpio *cpio;
- int ret;
-
- cpio = (struct cpio *)a->format_data;
- if (s > cpio->entry_bytes_remaining)
- s = (size_t)cpio->entry_bytes_remaining;
-
- ret = __archive_write_output(a, buff, s);
- cpio->entry_bytes_remaining -= s;
- if (ret >= 0)
- return (s);
- else
- return (ret);
-}
-
-static int
-archive_write_binary_close(struct archive_write *a)
-{
- int er;
- struct archive_entry *trailer;
-
- trailer = archive_entry_new2(NULL);
- /* nlink = 1 here for GNU cpio compat. */
- archive_entry_set_nlink(trailer, 1);
- archive_entry_set_size(trailer, 0);
- archive_entry_set_pathname(trailer, "TRAILER!!!");
- er = write_header(a, trailer);
- archive_entry_free(trailer);
- return (er);
-}
-
-static int
-archive_write_binary_free(struct archive_write *a)
-{
- struct cpio *cpio;
-
- cpio = (struct cpio *)a->format_data;
- free(cpio->ino_list);
- free(cpio);
- a->format_data = NULL;
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_binary_finish_entry(struct archive_write *a)
-{
- struct cpio *cpio;
-
- cpio = (struct cpio *)a->format_data;
- return (__archive_write_nulls(a,
- (size_t)cpio->entry_bytes_remaining));
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_format_cpio_newc.c b/contrib/libs/libarchive/libarchive/archive_write_set_format_cpio_newc.c
deleted file mode 100644
index f0f39809da..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_format_cpio_newc.c
+++ /dev/null
@@ -1,457 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * Copyright (c) 2006 Rudolf Marek SYSGO s.r.o.
- * Copyright (c) 2011-2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_cpio_newc.c 201160 2009-12-29 05:41:57Z kientzle $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_private.h"
-#include "archive_write_private.h"
-#include "archive_write_set_format_private.h"
-
-static ssize_t archive_write_newc_data(struct archive_write *,
- const void *buff, size_t s);
-static int archive_write_newc_close(struct archive_write *);
-static int archive_write_newc_free(struct archive_write *);
-static int archive_write_newc_finish_entry(struct archive_write *);
-static int archive_write_newc_header(struct archive_write *,
- struct archive_entry *);
-static int archive_write_newc_options(struct archive_write *,
- const char *, const char *);
-static int format_hex(int64_t, void *, int);
-static int64_t format_hex_recursive(int64_t, char *, int);
-static int write_header(struct archive_write *, struct archive_entry *);
-
-struct cpio {
- uint64_t entry_bytes_remaining;
- int padding;
-
- struct archive_string_conv *opt_sconv;
- struct archive_string_conv *sconv_default;
- int init_default_conversion;
-};
-
-#define c_magic_offset 0
-#define c_magic_size 6
-#define c_ino_offset 6
-#define c_ino_size 8
-#define c_mode_offset 14
-#define c_mode_size 8
-#define c_uid_offset 22
-#define c_uid_size 8
-#define c_gid_offset 30
-#define c_gid_size 8
-#define c_nlink_offset 38
-#define c_nlink_size 8
-#define c_mtime_offset 46
-#define c_mtime_size 8
-#define c_filesize_offset 54
-#define c_filesize_size 8
-#define c_devmajor_offset 62
-#define c_devmajor_size 8
-#define c_devminor_offset 70
-#define c_devminor_size 8
-#define c_rdevmajor_offset 78
-#define c_rdevmajor_size 8
-#define c_rdevminor_offset 86
-#define c_rdevminor_size 8
-#define c_namesize_offset 94
-#define c_namesize_size 8
-#define c_checksum_offset 102
-#define c_checksum_size 8
-#define c_header_size 110
-
-/* Logic trick: difference between 'n' and next multiple of 4 */
-#define PAD4(n) (3 & (1 + ~(n)))
-
-/*
- * Set output format to 'cpio' format.
- */
-int
-archive_write_set_format_cpio_newc(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct cpio *cpio;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_format_cpio_newc");
-
- /* If someone else was already registered, unregister them. */
- if (a->format_free != NULL)
- (a->format_free)(a);
-
- cpio = (struct cpio *)calloc(1, sizeof(*cpio));
- if (cpio == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data");
- return (ARCHIVE_FATAL);
- }
- a->format_data = cpio;
- a->format_name = "cpio";
- a->format_options = archive_write_newc_options;
- a->format_write_header = archive_write_newc_header;
- a->format_write_data = archive_write_newc_data;
- a->format_finish_entry = archive_write_newc_finish_entry;
- a->format_close = archive_write_newc_close;
- a->format_free = archive_write_newc_free;
- a->archive.archive_format = ARCHIVE_FORMAT_CPIO_SVR4_NOCRC;
- a->archive.archive_format_name = "SVR4 cpio nocrc";
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_newc_options(struct archive_write *a, const char *key,
- const char *val)
-{
- struct cpio *cpio = (struct cpio *)a->format_data;
- int ret = ARCHIVE_FAILED;
-
- if (strcmp(key, "hdrcharset") == 0) {
- if (val == NULL || val[0] == 0)
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "%s: hdrcharset option needs a character-set name",
- a->format_name);
- else {
- cpio->opt_sconv = archive_string_conversion_to_charset(
- &a->archive, val, 0);
- if (cpio->opt_sconv != NULL)
- ret = ARCHIVE_OK;
- else
- ret = ARCHIVE_FATAL;
- }
- return (ret);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-static struct archive_string_conv *
-get_sconv(struct archive_write *a)
-{
- struct cpio *cpio;
- struct archive_string_conv *sconv;
-
- cpio = (struct cpio *)a->format_data;
- sconv = cpio->opt_sconv;
- if (sconv == NULL) {
- if (!cpio->init_default_conversion) {
- cpio->sconv_default =
- archive_string_default_conversion_for_write(
- &(a->archive));
- cpio->init_default_conversion = 1;
- }
- sconv = cpio->sconv_default;
- }
- return (sconv);
-}
-
-static int
-archive_write_newc_header(struct archive_write *a, struct archive_entry *entry)
-{
- const char *path;
- size_t len;
-
- if (archive_entry_filetype(entry) == 0 && archive_entry_hardlink(entry) == NULL) {
- archive_set_error(&a->archive, -1, "Filetype required");
- return (ARCHIVE_FAILED);
- }
-
- if (archive_entry_pathname_l(entry, &path, &len, get_sconv(a)) != 0
- && errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathname");
- return (ARCHIVE_FATAL);
- }
- if (len == 0 || path == NULL || path[0] == '\0') {
- archive_set_error(&a->archive, -1, "Pathname required");
- return (ARCHIVE_FAILED);
- }
-
- if (archive_entry_hardlink(entry) == NULL
- && (!archive_entry_size_is_set(entry) || archive_entry_size(entry) < 0)) {
- archive_set_error(&a->archive, -1, "Size required");
- return (ARCHIVE_FAILED);
- }
- return write_header(a, entry);
-}
-
-static int
-write_header(struct archive_write *a, struct archive_entry *entry)
-{
- int64_t ino;
- struct cpio *cpio;
- const char *p, *path;
- int pathlength, ret, ret_final;
- char h[c_header_size];
- struct archive_string_conv *sconv;
- struct archive_entry *entry_main;
- size_t len;
- int pad;
-
- cpio = (struct cpio *)a->format_data;
- ret_final = ARCHIVE_OK;
- sconv = get_sconv(a);
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Make sure the path separators in pathname, hardlink and symlink
- * are all slash '/', not the Windows path separator '\'. */
- entry_main = __la_win_entry_in_posix_pathseparator(entry);
- if (entry_main == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate ustar data");
- return(ARCHIVE_FATAL);
- }
- if (entry != entry_main)
- entry = entry_main;
- else
- entry_main = NULL;
-#else
- entry_main = NULL;
-#endif
-
- ret = archive_entry_pathname_l(entry, &path, &len, sconv);
- if (ret != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathname");
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate pathname '%s' to %s",
- archive_entry_pathname(entry),
- archive_string_conversion_charset_name(sconv));
- ret_final = ARCHIVE_WARN;
- }
- pathlength = (int)len + 1; /* Include trailing null. */
-
- memset(h, 0, c_header_size);
- format_hex(0x070701, h + c_magic_offset, c_magic_size);
- format_hex(archive_entry_devmajor(entry), h + c_devmajor_offset,
- c_devmajor_size);
- format_hex(archive_entry_devminor(entry), h + c_devminor_offset,
- c_devminor_size);
-
- ino = archive_entry_ino64(entry);
- if (ino > 0xffffffff) {
- archive_set_error(&a->archive, ERANGE,
- "large inode number truncated");
- ret_final = ARCHIVE_WARN;
- }
-
- /* TODO: Set ret_final to ARCHIVE_WARN if any of these overflow. */
- format_hex(ino & 0xffffffff, h + c_ino_offset, c_ino_size);
- format_hex(archive_entry_mode(entry), h + c_mode_offset, c_mode_size);
- format_hex(archive_entry_uid(entry), h + c_uid_offset, c_uid_size);
- format_hex(archive_entry_gid(entry), h + c_gid_offset, c_gid_size);
- format_hex(archive_entry_nlink(entry), h + c_nlink_offset, c_nlink_size);
- if (archive_entry_filetype(entry) == AE_IFBLK
- || archive_entry_filetype(entry) == AE_IFCHR) {
- format_hex(archive_entry_rdevmajor(entry), h + c_rdevmajor_offset, c_rdevmajor_size);
- format_hex(archive_entry_rdevminor(entry), h + c_rdevminor_offset, c_rdevminor_size);
- } else {
- format_hex(0, h + c_rdevmajor_offset, c_rdevmajor_size);
- format_hex(0, h + c_rdevminor_offset, c_rdevminor_size);
- }
- format_hex(archive_entry_mtime(entry), h + c_mtime_offset, c_mtime_size);
- format_hex(pathlength, h + c_namesize_offset, c_namesize_size);
- format_hex(0, h + c_checksum_offset, c_checksum_size);
-
- /* Non-regular files don't store bodies. */
- if (archive_entry_filetype(entry) != AE_IFREG)
- archive_entry_set_size(entry, 0);
-
- /* Symlinks get the link written as the body of the entry. */
- ret = archive_entry_symlink_l(entry, &p, &len, sconv);
- if (ret != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Likname");
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate linkname '%s' to %s",
- archive_entry_symlink(entry),
- archive_string_conversion_charset_name(sconv));
- ret_final = ARCHIVE_WARN;
- }
- if (len > 0 && p != NULL && *p != '\0')
- ret = format_hex(strlen(p), h + c_filesize_offset,
- c_filesize_size);
- else
- ret = format_hex(archive_entry_size(entry),
- h + c_filesize_offset, c_filesize_size);
- if (ret) {
- archive_set_error(&a->archive, ERANGE,
- "File is too large for this format.");
- ret_final = ARCHIVE_FAILED;
- goto exit_write_header;
- }
-
- ret = __archive_write_output(a, h, c_header_size);
- if (ret != ARCHIVE_OK) {
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
-
- /* Pad pathname to even length. */
- ret = __archive_write_output(a, path, pathlength);
- if (ret != ARCHIVE_OK) {
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- pad = PAD4(pathlength + c_header_size);
- if (pad) {
- ret = __archive_write_output(a, "\0\0\0", pad);
- if (ret != ARCHIVE_OK) {
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- }
-
- cpio->entry_bytes_remaining = archive_entry_size(entry);
- cpio->padding = (int)PAD4(cpio->entry_bytes_remaining);
-
- /* Write the symlink now. */
- if (p != NULL && *p != '\0') {
- ret = __archive_write_output(a, p, strlen(p));
- if (ret != ARCHIVE_OK) {
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- pad = PAD4(strlen(p));
- ret = __archive_write_output(a, "\0\0\0", pad);
- if (ret != ARCHIVE_OK) {
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- }
-exit_write_header:
- archive_entry_free(entry_main);
- return (ret_final);
-}
-
-static ssize_t
-archive_write_newc_data(struct archive_write *a, const void *buff, size_t s)
-{
- struct cpio *cpio;
- int ret;
-
- cpio = (struct cpio *)a->format_data;
- if (s > cpio->entry_bytes_remaining)
- s = (size_t)cpio->entry_bytes_remaining;
-
- ret = __archive_write_output(a, buff, s);
- cpio->entry_bytes_remaining -= s;
- if (ret >= 0)
- return (s);
- else
- return (ret);
-}
-
-/*
- * Format a number into the specified field.
- */
-static int
-format_hex(int64_t v, void *p, int digits)
-{
- int64_t max;
- int ret;
-
- max = (((int64_t)1) << (digits * 4)) - 1;
- if (v >= 0 && v <= max) {
- format_hex_recursive(v, (char *)p, digits);
- ret = 0;
- } else {
- format_hex_recursive(max, (char *)p, digits);
- ret = -1;
- }
- return (ret);
-}
-
-static int64_t
-format_hex_recursive(int64_t v, char *p, int s)
-{
- if (s == 0)
- return (v);
- v = format_hex_recursive(v, p+1, s-1);
- *p = "0123456789abcdef"[v & 0xf];
- return (v >> 4);
-}
-
-static int
-archive_write_newc_close(struct archive_write *a)
-{
- int er;
- struct archive_entry *trailer;
-
- trailer = archive_entry_new();
- archive_entry_set_nlink(trailer, 1);
- archive_entry_set_size(trailer, 0);
- archive_entry_set_pathname(trailer, "TRAILER!!!");
- /* Bypass the required data checks. */
- er = write_header(a, trailer);
- archive_entry_free(trailer);
- return (er);
-}
-
-static int
-archive_write_newc_free(struct archive_write *a)
-{
- struct cpio *cpio;
-
- cpio = (struct cpio *)a->format_data;
- free(cpio);
- a->format_data = NULL;
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_newc_finish_entry(struct archive_write *a)
-{
- struct cpio *cpio;
-
- cpio = (struct cpio *)a->format_data;
- return (__archive_write_nulls(a,
- (size_t)cpio->entry_bytes_remaining + cpio->padding));
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_format_cpio_odc.c b/contrib/libs/libarchive/libarchive/archive_write_set_format_cpio_odc.c
deleted file mode 100644
index 091925a2f9..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_format_cpio_odc.c
+++ /dev/null
@@ -1,500 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * Copyright (c) 2011-2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_cpio.c 201170 2009-12-29 06:34:23Z kientzle $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_private.h"
-#include "archive_write_private.h"
-#include "archive_write_set_format_private.h"
-
-static ssize_t archive_write_odc_data(struct archive_write *,
- const void *buff, size_t s);
-static int archive_write_odc_close(struct archive_write *);
-static int archive_write_odc_free(struct archive_write *);
-static int archive_write_odc_finish_entry(struct archive_write *);
-static int archive_write_odc_header(struct archive_write *,
- struct archive_entry *);
-static int archive_write_odc_options(struct archive_write *,
- const char *, const char *);
-static int format_octal(int64_t, void *, int);
-static int64_t format_octal_recursive(int64_t, char *, int);
-static int write_header(struct archive_write *, struct archive_entry *);
-
-struct cpio {
- uint64_t entry_bytes_remaining;
-
- int64_t ino_next;
-
- struct { int64_t old; int new;} *ino_list;
- size_t ino_list_size;
- size_t ino_list_next;
-
- struct archive_string_conv *opt_sconv;
- struct archive_string_conv *sconv_default;
- int init_default_conversion;
-};
-
-#define c_magic_offset 0
-#define c_magic_size 6
-#define c_dev_offset 6
-#define c_dev_size 6
-#define c_ino_offset 12
-#define c_ino_size 6
-#define c_mode_offset 18
-#define c_mode_size 6
-#define c_uid_offset 24
-#define c_uid_size 6
-#define c_gid_offset 30
-#define c_gid_size 6
-#define c_nlink_offset 36
-#define c_nlink_size 6
-#define c_rdev_offset 42
-#define c_rdev_size 6
-#define c_mtime_offset 48
-#define c_mtime_size 11
-#define c_namesize_offset 59
-#define c_namesize_size 6
-#define c_filesize_offset 65
-#define c_filesize_size 11
-
-/*
- * Set output format to 'cpio' format.
- */
-int
-archive_write_set_format_cpio_odc(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct cpio *cpio;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_format_cpio_odc");
-
- /* If someone else was already registered, unregister them. */
- if (a->format_free != NULL)
- (a->format_free)(a);
-
- cpio = (struct cpio *)calloc(1, sizeof(*cpio));
- if (cpio == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data");
- return (ARCHIVE_FATAL);
- }
- a->format_data = cpio;
- a->format_name = "cpio";
- a->format_options = archive_write_odc_options;
- a->format_write_header = archive_write_odc_header;
- a->format_write_data = archive_write_odc_data;
- a->format_finish_entry = archive_write_odc_finish_entry;
- a->format_close = archive_write_odc_close;
- a->format_free = archive_write_odc_free;
- a->archive.archive_format = ARCHIVE_FORMAT_CPIO_POSIX;
- a->archive.archive_format_name = "POSIX cpio";
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_odc_options(struct archive_write *a, const char *key,
- const char *val)
-{
- struct cpio *cpio = (struct cpio *)a->format_data;
- int ret = ARCHIVE_FAILED;
-
- if (strcmp(key, "hdrcharset") == 0) {
- if (val == NULL || val[0] == 0)
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "%s: hdrcharset option needs a character-set name",
- a->format_name);
- else {
- cpio->opt_sconv = archive_string_conversion_to_charset(
- &a->archive, val, 0);
- if (cpio->opt_sconv != NULL)
- ret = ARCHIVE_OK;
- else
- ret = ARCHIVE_FATAL;
- }
- return (ret);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-/*
- * Ino values are as long as 64 bits on some systems; cpio format
- * only allows 18 bits and relies on the ino values to identify hardlinked
- * files. So, we can't merely "hash" the ino numbers since collisions
- * would corrupt the archive. Instead, we generate synthetic ino values
- * to store in the archive and maintain a map of original ino values to
- * synthetic ones so we can preserve hardlink information.
- *
- * TODO: Make this more efficient. It's not as bad as it looks (most
- * files don't have any hardlinks and we don't do any work here for those),
- * but it wouldn't be hard to do better.
- *
- * TODO: Work with dev/ino pairs here instead of just ino values.
- */
-static int
-synthesize_ino_value(struct cpio *cpio, struct archive_entry *entry)
-{
- int64_t ino = archive_entry_ino64(entry);
- int ino_new;
- size_t i;
-
- /*
- * If no index number was given, don't assign one. In
- * particular, this handles the end-of-archive marker
- * correctly by giving it a zero index value. (This is also
- * why we start our synthetic index numbers with one below.)
- */
- if (ino == 0)
- return (0);
-
- /* Don't store a mapping if we don't need to. */
- if (archive_entry_nlink(entry) < 2) {
- return (int)(++cpio->ino_next);
- }
-
- /* Look up old ino; if we have it, this is a hardlink
- * and we reuse the same value. */
- for (i = 0; i < cpio->ino_list_next; ++i) {
- if (cpio->ino_list[i].old == ino)
- return (cpio->ino_list[i].new);
- }
-
- /* Assign a new index number. */
- ino_new = (int)(++cpio->ino_next);
-
- /* Ensure space for the new mapping. */
- if (cpio->ino_list_size <= cpio->ino_list_next) {
- size_t newsize = cpio->ino_list_size < 512
- ? 512 : cpio->ino_list_size * 2;
- void *newlist = realloc(cpio->ino_list,
- sizeof(cpio->ino_list[0]) * newsize);
- if (newlist == NULL)
- return (-1);
-
- cpio->ino_list_size = newsize;
- cpio->ino_list = newlist;
- }
-
- /* Record and return the new value. */
- cpio->ino_list[cpio->ino_list_next].old = ino;
- cpio->ino_list[cpio->ino_list_next].new = ino_new;
- ++cpio->ino_list_next;
- return (ino_new);
-}
-
-
-static struct archive_string_conv *
-get_sconv(struct archive_write *a)
-{
- struct cpio *cpio;
- struct archive_string_conv *sconv;
-
- cpio = (struct cpio *)a->format_data;
- sconv = cpio->opt_sconv;
- if (sconv == NULL) {
- if (!cpio->init_default_conversion) {
- cpio->sconv_default =
- archive_string_default_conversion_for_write(
- &(a->archive));
- cpio->init_default_conversion = 1;
- }
- sconv = cpio->sconv_default;
- }
- return (sconv);
-}
-
-static int
-archive_write_odc_header(struct archive_write *a, struct archive_entry *entry)
-{
- const char *path;
- size_t len;
-
- if (archive_entry_filetype(entry) == 0 && archive_entry_hardlink(entry) == NULL) {
- archive_set_error(&a->archive, -1, "Filetype required");
- return (ARCHIVE_FAILED);
- }
-
- if (archive_entry_pathname_l(entry, &path, &len, get_sconv(a)) != 0
- && errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathname");
- return (ARCHIVE_FATAL);
- }
- if (len == 0 || path == NULL || path[0] == '\0') {
- archive_set_error(&a->archive, -1, "Pathname required");
- return (ARCHIVE_FAILED);
- }
-
- if (!archive_entry_size_is_set(entry) || archive_entry_size(entry) < 0) {
- archive_set_error(&a->archive, -1, "Size required");
- return (ARCHIVE_FAILED);
- }
- return write_header(a, entry);
-}
-
-static int
-write_header(struct archive_write *a, struct archive_entry *entry)
-{
- struct cpio *cpio;
- const char *p, *path;
- int pathlength, ret, ret_final;
- int64_t ino;
- char h[76];
- struct archive_string_conv *sconv;
- struct archive_entry *entry_main;
- size_t len;
-
- cpio = (struct cpio *)a->format_data;
- ret_final = ARCHIVE_OK;
- sconv = get_sconv(a);
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Make sure the path separators in pathname, hardlink and symlink
- * are all slash '/', not the Windows path separator '\'. */
- entry_main = __la_win_entry_in_posix_pathseparator(entry);
- if (entry_main == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate ustar data");
- return(ARCHIVE_FATAL);
- }
- if (entry != entry_main)
- entry = entry_main;
- else
- entry_main = NULL;
-#else
- entry_main = NULL;
-#endif
-
- ret = archive_entry_pathname_l(entry, &path, &len, sconv);
- if (ret != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathname");
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate pathname '%s' to %s",
- archive_entry_pathname(entry),
- archive_string_conversion_charset_name(sconv));
- ret_final = ARCHIVE_WARN;
- }
- /* Include trailing null. */
- pathlength = (int)len + 1;
-
- memset(h, 0, sizeof(h));
- format_octal(070707, h + c_magic_offset, c_magic_size);
- format_octal(archive_entry_dev(entry), h + c_dev_offset, c_dev_size);
-
- ino = synthesize_ino_value(cpio, entry);
- if (ino < 0) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for ino translation table");
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- } else if (ino > 0777777) {
- archive_set_error(&a->archive, ERANGE,
- "Too many files for this cpio format");
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- format_octal(ino & 0777777, h + c_ino_offset, c_ino_size);
-
- /* TODO: Set ret_final to ARCHIVE_WARN if any of these overflow. */
- format_octal(archive_entry_mode(entry), h + c_mode_offset, c_mode_size);
- format_octal(archive_entry_uid(entry), h + c_uid_offset, c_uid_size);
- format_octal(archive_entry_gid(entry), h + c_gid_offset, c_gid_size);
- format_octal(archive_entry_nlink(entry), h + c_nlink_offset, c_nlink_size);
- if (archive_entry_filetype(entry) == AE_IFBLK
- || archive_entry_filetype(entry) == AE_IFCHR)
- format_octal(archive_entry_rdev(entry), h + c_rdev_offset, c_rdev_size);
- else
- format_octal(0, h + c_rdev_offset, c_rdev_size);
- format_octal(archive_entry_mtime(entry), h + c_mtime_offset, c_mtime_size);
- format_octal(pathlength, h + c_namesize_offset, c_namesize_size);
-
- /* Non-regular files don't store bodies. */
- if (archive_entry_filetype(entry) != AE_IFREG)
- archive_entry_set_size(entry, 0);
-
- /* Symlinks get the link written as the body of the entry. */
- ret = archive_entry_symlink_l(entry, &p, &len, sconv);
- if (ret != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Linkname");
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate linkname '%s' to %s",
- archive_entry_symlink(entry),
- archive_string_conversion_charset_name(sconv));
- ret_final = ARCHIVE_WARN;
- }
- if (len > 0 && p != NULL && *p != '\0')
- ret = format_octal(strlen(p), h + c_filesize_offset,
- c_filesize_size);
- else
- ret = format_octal(archive_entry_size(entry),
- h + c_filesize_offset, c_filesize_size);
- if (ret) {
- archive_set_error(&a->archive, ERANGE,
- "File is too large for cpio format.");
- ret_final = ARCHIVE_FAILED;
- goto exit_write_header;
- }
-
- ret = __archive_write_output(a, h, sizeof(h));
- if (ret != ARCHIVE_OK) {
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
-
- ret = __archive_write_output(a, path, pathlength);
- if (ret != ARCHIVE_OK) {
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
-
- cpio->entry_bytes_remaining = archive_entry_size(entry);
-
- /* Write the symlink now. */
- if (p != NULL && *p != '\0') {
- ret = __archive_write_output(a, p, strlen(p));
- if (ret != ARCHIVE_OK) {
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- }
-exit_write_header:
- archive_entry_free(entry_main);
- return (ret_final);
-}
-
-static ssize_t
-archive_write_odc_data(struct archive_write *a, const void *buff, size_t s)
-{
- struct cpio *cpio;
- int ret;
-
- cpio = (struct cpio *)a->format_data;
- if (s > cpio->entry_bytes_remaining)
- s = (size_t)cpio->entry_bytes_remaining;
-
- ret = __archive_write_output(a, buff, s);
- cpio->entry_bytes_remaining -= s;
- if (ret >= 0)
- return (s);
- else
- return (ret);
-}
-
-/*
- * Format a number into the specified field.
- */
-static int
-format_octal(int64_t v, void *p, int digits)
-{
- int64_t max;
- int ret;
-
- max = (((int64_t)1) << (digits * 3)) - 1;
- if (v >= 0 && v <= max) {
- format_octal_recursive(v, (char *)p, digits);
- ret = 0;
- } else {
- format_octal_recursive(max, (char *)p, digits);
- ret = -1;
- }
- return (ret);
-}
-
-static int64_t
-format_octal_recursive(int64_t v, char *p, int s)
-{
- if (s == 0)
- return (v);
- v = format_octal_recursive(v, p+1, s-1);
- *p = '0' + ((char)v & 7);
- return (v >> 3);
-}
-
-static int
-archive_write_odc_close(struct archive_write *a)
-{
- int er;
- struct archive_entry *trailer;
-
- trailer = archive_entry_new2(NULL);
- /* nlink = 1 here for GNU cpio compat. */
- archive_entry_set_nlink(trailer, 1);
- archive_entry_set_size(trailer, 0);
- archive_entry_set_pathname(trailer, "TRAILER!!!");
- er = write_header(a, trailer);
- archive_entry_free(trailer);
- return (er);
-}
-
-static int
-archive_write_odc_free(struct archive_write *a)
-{
- struct cpio *cpio;
-
- cpio = (struct cpio *)a->format_data;
- free(cpio->ino_list);
- free(cpio);
- a->format_data = NULL;
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_odc_finish_entry(struct archive_write *a)
-{
- struct cpio *cpio;
-
- cpio = (struct cpio *)a->format_data;
- return (__archive_write_nulls(a,
- (size_t)cpio->entry_bytes_remaining));
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_format_filter_by_ext.c b/contrib/libs/libarchive/libarchive/archive_write_set_format_filter_by_ext.c
deleted file mode 100644
index 9fe21e4542..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_format_filter_by_ext.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * Copyright (c) 2015 Okhotnikov Kirill
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_by_name.c 201168 2009-12-29 06:15:32Z kientzle $");
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-
-/* A table that maps names to functions. */
-static const
-struct { const char *name; int (*format)(struct archive *); int (*filter)(struct archive *); } names[] =
-{
- { ".7z", archive_write_set_format_7zip, archive_write_add_filter_none},
- { ".zip", archive_write_set_format_zip, archive_write_add_filter_none},
- { ".jar", archive_write_set_format_zip, archive_write_add_filter_none},
- { ".cpio", archive_write_set_format_cpio, archive_write_add_filter_none},
- { ".iso", archive_write_set_format_iso9660, archive_write_add_filter_none},
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
- { ".a", archive_write_set_format_ar_bsd, archive_write_add_filter_none},
- { ".ar", archive_write_set_format_ar_bsd, archive_write_add_filter_none},
-#else
- { ".a", archive_write_set_format_ar_svr4, archive_write_add_filter_none},
- { ".ar", archive_write_set_format_ar_svr4, archive_write_add_filter_none},
-#endif
- { ".tar", archive_write_set_format_pax_restricted, archive_write_add_filter_none},
- { ".tgz", archive_write_set_format_pax_restricted, archive_write_add_filter_gzip},
- { ".tar.gz", archive_write_set_format_pax_restricted, archive_write_add_filter_gzip},
- { ".tar.bz2", archive_write_set_format_pax_restricted, archive_write_add_filter_bzip2},
- { ".tar.xz", archive_write_set_format_pax_restricted, archive_write_add_filter_xz},
- { NULL, NULL, NULL }
-};
-
-static
-int cmpsuff(const char *str, const char *suffix)
-{
- size_t length_str, length_suffix;
-
- if ((str == NULL) || (suffix == NULL))
- return -1;
-
- length_str = strlen(str);
- length_suffix = strlen(suffix);
-
- if (length_str >= length_suffix) {
- return strcmp(str + (length_str - length_suffix), suffix);
- } else {
- return -1;
- }
-}
-
-static int get_array_index(const char *name)
-{
- int i;
-
- for (i = 0; names[i].name != NULL; i++)
- {
- if (cmpsuff(name, names[i].name) == 0)
- return i;
- }
- return -1;
-
-}
-
-int
-archive_write_set_format_filter_by_ext(struct archive *a, const char *filename)
-{
- int names_index = get_array_index(filename);
-
- if (names_index >= 0)
- {
- int format_state = (names[names_index].format)(a);
- if (format_state == ARCHIVE_OK)
- return ((names[names_index].filter)(a));
- else
- return format_state;
- }
-
- archive_set_error(a, EINVAL, "No such format '%s'", filename);
- a->state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
-}
-
-int
-archive_write_set_format_filter_by_ext_def(struct archive *a, const char *filename, const char * def_ext)
-{
- int names_index = get_array_index(filename);
-
- if (names_index < 0)
- names_index = get_array_index(def_ext);
-
- if (names_index >= 0)
- {
- int format_state = (names[names_index].format)(a);
- if (format_state == ARCHIVE_OK)
- return ((names[names_index].filter)(a));
- else
- return format_state;
- }
-
- archive_set_error(a, EINVAL, "No such format '%s'", filename);
- a->state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
-}
-
-
-
-
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_format_gnutar.c b/contrib/libs/libarchive/libarchive/archive_write_set_format_gnutar.c
deleted file mode 100644
index ec29c5c418..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_format_gnutar.c
+++ /dev/null
@@ -1,755 +0,0 @@
-/*-
- * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
- * Author: Jonas Gastal <jgastal@profusion.mobi>
- * Copyright (c) 2011-2012 Michihiro NAKAJIMA
- *
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_gnu_tar.c 191579 2009-04-27 18:35:03Z gastal $");
-
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_private.h"
-#include "archive_write_private.h"
-#include "archive_write_set_format_private.h"
-
-struct gnutar {
- uint64_t entry_bytes_remaining;
- uint64_t entry_padding;
- const char * linkname;
- size_t linkname_length;
- const char * pathname;
- size_t pathname_length;
- const char * uname;
- size_t uname_length;
- const char * gname;
- size_t gname_length;
- struct archive_string_conv *opt_sconv;
- struct archive_string_conv *sconv_default;
- int init_default_conversion;
-};
-
-/*
- * Define structure of GNU tar header.
- */
-#define GNUTAR_name_offset 0
-#define GNUTAR_name_size 100
-#define GNUTAR_mode_offset 100
-#define GNUTAR_mode_size 7
-#define GNUTAR_mode_max_size 8
-#define GNUTAR_uid_offset 108
-#define GNUTAR_uid_size 7
-#define GNUTAR_uid_max_size 8
-#define GNUTAR_gid_offset 116
-#define GNUTAR_gid_size 7
-#define GNUTAR_gid_max_size 8
-#define GNUTAR_size_offset 124
-#define GNUTAR_size_size 11
-#define GNUTAR_size_max_size 12
-#define GNUTAR_mtime_offset 136
-#define GNUTAR_mtime_size 11
-#define GNUTAR_mtime_max_size 11
-#define GNUTAR_checksum_offset 148
-#define GNUTAR_checksum_size 8
-#define GNUTAR_typeflag_offset 156
-#define GNUTAR_typeflag_size 1
-#define GNUTAR_linkname_offset 157
-#define GNUTAR_linkname_size 100
-#define GNUTAR_magic_offset 257
-#define GNUTAR_magic_size 6
-#define GNUTAR_version_offset 263
-#define GNUTAR_version_size 2
-#define GNUTAR_uname_offset 265
-#define GNUTAR_uname_size 32
-#define GNUTAR_gname_offset 297
-#define GNUTAR_gname_size 32
-#define GNUTAR_rdevmajor_offset 329
-#define GNUTAR_rdevmajor_size 6
-#define GNUTAR_rdevmajor_max_size 8
-#define GNUTAR_rdevminor_offset 337
-#define GNUTAR_rdevminor_size 6
-#define GNUTAR_rdevminor_max_size 8
-
-/*
- * A filled-in copy of the header for initialization.
- */
-static const char template_header[] = {
- /* name: 100 bytes */
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,
- /* Mode, null termination: 8 bytes */
- '0','0','0','0','0','0', '0','\0',
- /* uid, null termination: 8 bytes */
- '0','0','0','0','0','0', '0','\0',
- /* gid, null termination: 8 bytes */
- '0','0','0','0','0','0', '0','\0',
- /* size, space termination: 12 bytes */
- '0','0','0','0','0','0','0','0','0','0','0', '\0',
- /* mtime, space termination: 12 bytes */
- '0','0','0','0','0','0','0','0','0','0','0', '\0',
- /* Initial checksum value: 8 spaces */
- ' ',' ',' ',' ',' ',' ',' ',' ',
- /* Typeflag: 1 byte */
- '0', /* '0' = regular file */
- /* Linkname: 100 bytes */
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,
- /* Magic: 8 bytes */
- 'u','s','t','a','r',' ', ' ','\0',
- /* Uname: 32 bytes */
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- /* Gname: 32 bytes */
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- /* rdevmajor + null padding: 8 bytes */
- '\0','\0','\0','\0','\0','\0', '\0','\0',
- /* rdevminor + null padding: 8 bytes */
- '\0','\0','\0','\0','\0','\0', '\0','\0',
- /* Padding: 167 bytes */
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0
-};
-
-static int archive_write_gnutar_options(struct archive_write *,
- const char *, const char *);
-static int archive_format_gnutar_header(struct archive_write *, char h[512],
- struct archive_entry *, int tartype);
-static int archive_write_gnutar_header(struct archive_write *,
- struct archive_entry *entry);
-static ssize_t archive_write_gnutar_data(struct archive_write *a, const void *buff,
- size_t s);
-static int archive_write_gnutar_free(struct archive_write *);
-static int archive_write_gnutar_close(struct archive_write *);
-static int archive_write_gnutar_finish_entry(struct archive_write *);
-static int format_256(int64_t, char *, int);
-static int format_number(int64_t, char *, int size, int maxsize);
-static int format_octal(int64_t, char *, int);
-
-/*
- * Set output format to 'GNU tar' format.
- */
-int
-archive_write_set_format_gnutar(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct gnutar *gnutar;
-
- gnutar = (struct gnutar *)calloc(1, sizeof(*gnutar));
- if (gnutar == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate gnutar data");
- return (ARCHIVE_FATAL);
- }
- a->format_data = gnutar;
- a->format_name = "gnutar";
- a->format_options = archive_write_gnutar_options;
- a->format_write_header = archive_write_gnutar_header;
- a->format_write_data = archive_write_gnutar_data;
- a->format_close = archive_write_gnutar_close;
- a->format_free = archive_write_gnutar_free;
- a->format_finish_entry = archive_write_gnutar_finish_entry;
- a->archive.archive_format = ARCHIVE_FORMAT_TAR_GNUTAR;
- a->archive.archive_format_name = "GNU tar";
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_gnutar_options(struct archive_write *a, const char *key,
- const char *val)
-{
- struct gnutar *gnutar = (struct gnutar *)a->format_data;
- int ret = ARCHIVE_FAILED;
-
- if (strcmp(key, "hdrcharset") == 0) {
- if (val == NULL || val[0] == 0)
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "%s: hdrcharset option needs a character-set name",
- a->format_name);
- else {
- gnutar->opt_sconv = archive_string_conversion_to_charset(
- &a->archive, val, 0);
- if (gnutar->opt_sconv != NULL)
- ret = ARCHIVE_OK;
- else
- ret = ARCHIVE_FATAL;
- }
- return (ret);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-static int
-archive_write_gnutar_close(struct archive_write *a)
-{
- return (__archive_write_nulls(a, 512*2));
-}
-
-static int
-archive_write_gnutar_free(struct archive_write *a)
-{
- struct gnutar *gnutar;
-
- gnutar = (struct gnutar *)a->format_data;
- free(gnutar);
- a->format_data = NULL;
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_gnutar_finish_entry(struct archive_write *a)
-{
- struct gnutar *gnutar;
- int ret;
-
- gnutar = (struct gnutar *)a->format_data;
- ret = __archive_write_nulls(a, (size_t)
- (gnutar->entry_bytes_remaining + gnutar->entry_padding));
- gnutar->entry_bytes_remaining = gnutar->entry_padding = 0;
- return (ret);
-}
-
-static ssize_t
-archive_write_gnutar_data(struct archive_write *a, const void *buff, size_t s)
-{
- struct gnutar *gnutar;
- int ret;
-
- gnutar = (struct gnutar *)a->format_data;
- if (s > gnutar->entry_bytes_remaining)
- s = (size_t)gnutar->entry_bytes_remaining;
- ret = __archive_write_output(a, buff, s);
- gnutar->entry_bytes_remaining -= s;
- if (ret != ARCHIVE_OK)
- return (ret);
- return (s);
-}
-
-static int
-archive_write_gnutar_header(struct archive_write *a,
- struct archive_entry *entry)
-{
- char buff[512];
- int r, ret, ret2 = ARCHIVE_OK;
- int tartype;
- struct gnutar *gnutar;
- struct archive_string_conv *sconv;
- struct archive_entry *entry_main;
-
- gnutar = (struct gnutar *)a->format_data;
-
- /* Setup default string conversion. */
- if (gnutar->opt_sconv == NULL) {
- if (!gnutar->init_default_conversion) {
- gnutar->sconv_default =
- archive_string_default_conversion_for_write(
- &(a->archive));
- gnutar->init_default_conversion = 1;
- }
- sconv = gnutar->sconv_default;
- } else
- sconv = gnutar->opt_sconv;
-
- /* Only regular files (not hardlinks) have data. */
- if (archive_entry_hardlink(entry) != NULL ||
- archive_entry_symlink(entry) != NULL ||
- !(archive_entry_filetype(entry) == AE_IFREG))
- archive_entry_set_size(entry, 0);
-
- if (AE_IFDIR == archive_entry_filetype(entry)) {
- const char *p;
- size_t path_length;
- /*
- * Ensure a trailing '/'. Modify the entry so
- * the client sees the change.
- */
-#if defined(_WIN32) && !defined(__CYGWIN__)
- const wchar_t *wp;
-
- wp = archive_entry_pathname_w(entry);
- if (wp != NULL && wp[wcslen(wp) -1] != L'/') {
- struct archive_wstring ws;
-
- archive_string_init(&ws);
- path_length = wcslen(wp);
- if (archive_wstring_ensure(&ws,
- path_length + 2) == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate ustar data");
- archive_wstring_free(&ws);
- return(ARCHIVE_FATAL);
- }
- /* Should we keep '\' ? */
- if (wp[path_length -1] == L'\\')
- path_length--;
- archive_wstrncpy(&ws, wp, path_length);
- archive_wstrappend_wchar(&ws, L'/');
- archive_entry_copy_pathname_w(entry, ws.s);
- archive_wstring_free(&ws);
- p = NULL;
- } else
-#endif
- p = archive_entry_pathname(entry);
- /*
- * On Windows, this is a backup operation just in
- * case getting WCS failed. On POSIX, this is a
- * normal operation.
- */
- if (p != NULL && p[0] != '\0' && p[strlen(p) - 1] != '/') {
- struct archive_string as;
-
- archive_string_init(&as);
- path_length = strlen(p);
- if (archive_string_ensure(&as,
- path_length + 2) == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate ustar data");
- archive_string_free(&as);
- return(ARCHIVE_FATAL);
- }
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* NOTE: This might break the pathname
- * if the current code page is CP932 and
- * the pathname includes a character '\'
- * as a part of its multibyte pathname. */
- if (p[strlen(p) -1] == '\\')
- path_length--;
- else
-#endif
- archive_strncpy(&as, p, path_length);
- archive_strappend_char(&as, '/');
- archive_entry_copy_pathname(entry, as.s);
- archive_string_free(&as);
- }
- }
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Make sure the path separators in pathname, hardlink and symlink
- * are all slash '/', not the Windows path separator '\'. */
- entry_main = __la_win_entry_in_posix_pathseparator(entry);
- if (entry_main == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate ustar data");
- return(ARCHIVE_FATAL);
- }
- if (entry != entry_main)
- entry = entry_main;
- else
- entry_main = NULL;
-#else
- entry_main = NULL;
-#endif
- r = archive_entry_pathname_l(entry, &(gnutar->pathname),
- &(gnutar->pathname_length), sconv);
- if (r != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathame");
- ret = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate pathname '%s' to %s",
- archive_entry_pathname(entry),
- archive_string_conversion_charset_name(sconv));
- ret2 = ARCHIVE_WARN;
- }
- r = archive_entry_uname_l(entry, &(gnutar->uname),
- &(gnutar->uname_length), sconv);
- if (r != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Uname");
- ret = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate uname '%s' to %s",
- archive_entry_uname(entry),
- archive_string_conversion_charset_name(sconv));
- ret2 = ARCHIVE_WARN;
- }
- r = archive_entry_gname_l(entry, &(gnutar->gname),
- &(gnutar->gname_length), sconv);
- if (r != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Gname");
- ret = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate gname '%s' to %s",
- archive_entry_gname(entry),
- archive_string_conversion_charset_name(sconv));
- ret2 = ARCHIVE_WARN;
- }
-
- /* If linkname is longer than 100 chars we need to add a 'K' header. */
- r = archive_entry_hardlink_l(entry, &(gnutar->linkname),
- &(gnutar->linkname_length), sconv);
- if (r != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Linkname");
- ret = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate linkname '%s' to %s",
- archive_entry_hardlink(entry),
- archive_string_conversion_charset_name(sconv));
- ret2 = ARCHIVE_WARN;
- }
- if (gnutar->linkname_length == 0) {
- r = archive_entry_symlink_l(entry, &(gnutar->linkname),
- &(gnutar->linkname_length), sconv);
- if (r != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Linkname");
- ret = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate linkname '%s' to %s",
- archive_entry_hardlink(entry),
- archive_string_conversion_charset_name(sconv));
- ret2 = ARCHIVE_WARN;
- }
- }
- if (gnutar->linkname_length > GNUTAR_linkname_size) {
- size_t length = gnutar->linkname_length + 1;
- struct archive_entry *temp = archive_entry_new2(&a->archive);
-
- /* Uname/gname here don't really matter since no one reads them;
- * these are the values that GNU tar happens to use on FreeBSD. */
- archive_entry_set_uname(temp, "root");
- archive_entry_set_gname(temp, "wheel");
-
- archive_entry_set_pathname(temp, "././@LongLink");
- archive_entry_set_size(temp, length);
- ret = archive_format_gnutar_header(a, buff, temp, 'K');
- archive_entry_free(temp);
- if (ret < ARCHIVE_WARN)
- goto exit_write_header;
- ret = __archive_write_output(a, buff, 512);
- if (ret < ARCHIVE_WARN)
- goto exit_write_header;
- /* Write name and trailing null byte. */
- ret = __archive_write_output(a, gnutar->linkname, length);
- if (ret < ARCHIVE_WARN)
- goto exit_write_header;
- /* Pad to 512 bytes */
- ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)length));
- if (ret < ARCHIVE_WARN)
- goto exit_write_header;
- }
-
- /* If pathname is longer than 100 chars we need to add an 'L' header. */
- if (gnutar->pathname_length > GNUTAR_name_size) {
- const char *pathname = gnutar->pathname;
- size_t length = gnutar->pathname_length + 1;
- struct archive_entry *temp = archive_entry_new2(&a->archive);
-
- /* Uname/gname here don't really matter since no one reads them;
- * these are the values that GNU tar happens to use on FreeBSD. */
- archive_entry_set_uname(temp, "root");
- archive_entry_set_gname(temp, "wheel");
-
- archive_entry_set_pathname(temp, "././@LongLink");
- archive_entry_set_size(temp, length);
- ret = archive_format_gnutar_header(a, buff, temp, 'L');
- archive_entry_free(temp);
- if (ret < ARCHIVE_WARN)
- goto exit_write_header;
- ret = __archive_write_output(a, buff, 512);
- if(ret < ARCHIVE_WARN)
- goto exit_write_header;
- /* Write pathname + trailing null byte. */
- ret = __archive_write_output(a, pathname, length);
- if(ret < ARCHIVE_WARN)
- goto exit_write_header;
- /* Pad to multiple of 512 bytes. */
- ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)length));
- if (ret < ARCHIVE_WARN)
- goto exit_write_header;
- }
-
- if (archive_entry_hardlink(entry) != NULL) {
- tartype = '1';
- } else
- switch (archive_entry_filetype(entry)) {
- case AE_IFREG: tartype = '0' ; break;
- case AE_IFLNK: tartype = '2' ; break;
- case AE_IFCHR: tartype = '3' ; break;
- case AE_IFBLK: tartype = '4' ; break;
- case AE_IFDIR: tartype = '5' ; break;
- case AE_IFIFO: tartype = '6' ; break;
- default: /* AE_IFSOCK and unknown */
- __archive_write_entry_filetype_unsupported(
- &a->archive, entry, "gnutar");
- ret = ARCHIVE_FAILED;
- goto exit_write_header;
- }
-
- ret = archive_format_gnutar_header(a, buff, entry, tartype);
- if (ret < ARCHIVE_WARN)
- goto exit_write_header;
- if (ret2 < ret)
- ret = ret2;
- ret2 = __archive_write_output(a, buff, 512);
- if (ret2 < ARCHIVE_WARN) {
- ret = ret2;
- goto exit_write_header;
- }
- if (ret2 < ret)
- ret = ret2;
-
- gnutar->entry_bytes_remaining = archive_entry_size(entry);
- gnutar->entry_padding = 0x1ff & (-(int64_t)gnutar->entry_bytes_remaining);
-exit_write_header:
- archive_entry_free(entry_main);
- return (ret);
-}
-
-static int
-archive_format_gnutar_header(struct archive_write *a, char h[512],
- struct archive_entry *entry, int tartype)
-{
- unsigned int checksum;
- int i, ret;
- size_t copy_length;
- const char *p;
- struct gnutar *gnutar;
-
- gnutar = (struct gnutar *)a->format_data;
-
- ret = 0;
-
- /*
- * The "template header" already includes the signature,
- * various end-of-field markers, and other required elements.
- */
- memcpy(h, &template_header, 512);
-
- /*
- * Because the block is already null-filled, and strings
- * are allowed to exactly fill their destination (without null),
- * I use memcpy(dest, src, strlen()) here a lot to copy strings.
- */
-
- if (tartype == 'K' || tartype == 'L') {
- p = archive_entry_pathname(entry);
- copy_length = strlen(p);
- } else {
- p = gnutar->pathname;
- copy_length = gnutar->pathname_length;
- }
- if (copy_length > GNUTAR_name_size)
- copy_length = GNUTAR_name_size;
- memcpy(h + GNUTAR_name_offset, p, copy_length);
-
- if ((copy_length = gnutar->linkname_length) > 0) {
- if (copy_length > GNUTAR_linkname_size)
- copy_length = GNUTAR_linkname_size;
- memcpy(h + GNUTAR_linkname_offset, gnutar->linkname,
- copy_length);
- }
-
- /* TODO: How does GNU tar handle unames longer than GNUTAR_uname_size? */
- if (tartype == 'K' || tartype == 'L') {
- p = archive_entry_uname(entry);
- copy_length = strlen(p);
- } else {
- p = gnutar->uname;
- copy_length = gnutar->uname_length;
- }
- if (copy_length > 0) {
- if (copy_length > GNUTAR_uname_size)
- copy_length = GNUTAR_uname_size;
- memcpy(h + GNUTAR_uname_offset, p, copy_length);
- }
-
- /* TODO: How does GNU tar handle gnames longer than GNUTAR_gname_size? */
- if (tartype == 'K' || tartype == 'L') {
- p = archive_entry_gname(entry);
- copy_length = strlen(p);
- } else {
- p = gnutar->gname;
- copy_length = gnutar->gname_length;
- }
- if (copy_length > 0) {
- if (strlen(p) > GNUTAR_gname_size)
- copy_length = GNUTAR_gname_size;
- memcpy(h + GNUTAR_gname_offset, p, copy_length);
- }
-
- /* By truncating the mode here, we ensure it always fits. */
- format_octal(archive_entry_mode(entry) & 07777,
- h + GNUTAR_mode_offset, GNUTAR_mode_size);
-
- /* GNU tar supports base-256 here, so should never overflow. */
- if (format_number(archive_entry_uid(entry), h + GNUTAR_uid_offset,
- GNUTAR_uid_size, GNUTAR_uid_max_size)) {
- archive_set_error(&a->archive, ERANGE,
- "Numeric user ID %jd too large",
- (intmax_t)archive_entry_uid(entry));
- ret = ARCHIVE_FAILED;
- }
-
- /* GNU tar supports base-256 here, so should never overflow. */
- if (format_number(archive_entry_gid(entry), h + GNUTAR_gid_offset,
- GNUTAR_gid_size, GNUTAR_gid_max_size)) {
- archive_set_error(&a->archive, ERANGE,
- "Numeric group ID %jd too large",
- (intmax_t)archive_entry_gid(entry));
- ret = ARCHIVE_FAILED;
- }
-
- /* GNU tar supports base-256 here, so should never overflow. */
- if (format_number(archive_entry_size(entry), h + GNUTAR_size_offset,
- GNUTAR_size_size, GNUTAR_size_max_size)) {
- archive_set_error(&a->archive, ERANGE,
- "File size out of range");
- ret = ARCHIVE_FAILED;
- }
-
- /* Shouldn't overflow before 2106, since mtime field is 33 bits. */
- format_octal(archive_entry_mtime(entry),
- h + GNUTAR_mtime_offset, GNUTAR_mtime_size);
-
- if (archive_entry_filetype(entry) == AE_IFBLK
- || archive_entry_filetype(entry) == AE_IFCHR) {
- if (format_octal(archive_entry_rdevmajor(entry),
- h + GNUTAR_rdevmajor_offset,
- GNUTAR_rdevmajor_size)) {
- archive_set_error(&a->archive, ERANGE,
- "Major device number too large");
- ret = ARCHIVE_FAILED;
- }
-
- if (format_octal(archive_entry_rdevminor(entry),
- h + GNUTAR_rdevminor_offset,
- GNUTAR_rdevminor_size)) {
- archive_set_error(&a->archive, ERANGE,
- "Minor device number too large");
- ret = ARCHIVE_FAILED;
- }
- }
-
- h[GNUTAR_typeflag_offset] = tartype;
-
- checksum = 0;
- for (i = 0; i < 512; i++)
- checksum += 255 & (unsigned int)h[i];
- h[GNUTAR_checksum_offset + 6] = '\0'; /* Can't be pre-set in the template. */
- /* h[GNUTAR_checksum_offset + 7] = ' '; */ /* This is pre-set in the template. */
- format_octal(checksum, h + GNUTAR_checksum_offset, 6);
- return (ret);
-}
-
-/*
- * Format a number into a field, falling back to base-256 if necessary.
- */
-static int
-format_number(int64_t v, char *p, int s, int maxsize)
-{
- int64_t limit = ((int64_t)1 << (s*3));
-
- if (v < limit)
- return (format_octal(v, p, s));
- return (format_256(v, p, maxsize));
-}
-
-/*
- * Format a number into the specified field using base-256.
- */
-static int
-format_256(int64_t v, char *p, int s)
-{
- p += s;
- while (s-- > 0) {
- *--p = (char)(v & 0xff);
- v >>= 8;
- }
- *p |= 0x80; /* Set the base-256 marker bit. */
- return (0);
-}
-
-/*
- * Format a number into the specified field using octal.
- */
-static int
-format_octal(int64_t v, char *p, int s)
-{
- int len = s;
-
- /* Octal values can't be negative, so use 0. */
- if (v < 0)
- v = 0;
-
- p += s; /* Start at the end and work backwards. */
- while (s-- > 0) {
- *--p = (char)('0' + (v & 7));
- v >>= 3;
- }
-
- if (v == 0)
- return (0);
-
- /* If it overflowed, fill field with max value. */
- while (len-- > 0)
- *p++ = '7';
-
- return (-1);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_format_iso9660.c b/contrib/libs/libarchive/libarchive/archive_write_set_format_iso9660.c
deleted file mode 100644
index 2a3ae07fa2..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_format_iso9660.c
+++ /dev/null
@@ -1,8161 +0,0 @@
-/*-
- * Copyright (c) 2009-2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_UTSNAME_H
-#include <sys/utsname.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-#include <stdio.h>
-#include <stdarg.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#include <time.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-
-#include "archive.h"
-#include "archive_endian.h"
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_private.h"
-#include "archive_rb.h"
-#include "archive_write_private.h"
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#define getuid() 0
-#define getgid() 0
-#endif
-
-/*#define DEBUG 1*/
-#ifdef DEBUG
-/* To compare to the ISO image file made by mkisofs. */
-#define COMPAT_MKISOFS 1
-#endif
-
-#define LOGICAL_BLOCK_BITS 11
-#define LOGICAL_BLOCK_SIZE 2048
-#define PATH_TABLE_BLOCK_SIZE 4096
-
-#define SYSTEM_AREA_BLOCK 16
-#define PRIMARY_VOLUME_DESCRIPTOR_BLOCK 1
-#define SUPPLEMENTARY_VOLUME_DESCRIPTOR_BLOCK 1
-#define BOOT_RECORD_DESCRIPTOR_BLOCK 1
-#define VOLUME_DESCRIPTOR_SET_TERMINATOR_BLOCK 1
-#define NON_ISO_FILE_SYSTEM_INFORMATION_BLOCK 1
-#define RRIP_ER_BLOCK 1
-#define PADDING_BLOCK 150
-
-#define FD_1_2M_SIZE (1024 * 1200)
-#define FD_1_44M_SIZE (1024 * 1440)
-#define FD_2_88M_SIZE (1024 * 2880)
-#define MULTI_EXTENT_SIZE (ARCHIVE_LITERAL_LL(1) << 32) /* 4Gi bytes. */
-#define MAX_DEPTH 8
-#define RR_CE_SIZE 28 /* SUSP "CE" extension size */
-
-#define FILE_FLAG_EXISTENCE 0x01
-#define FILE_FLAG_DIRECTORY 0x02
-#define FILE_FLAG_ASSOCIATED 0x04
-#define FILE_FLAG_RECORD 0x08
-#define FILE_FLAG_PROTECTION 0x10
-#define FILE_FLAG_MULTI_EXTENT 0x80
-
-static const char rrip_identifier[] =
- "RRIP_1991A";
-static const char rrip_descriptor[] =
- "THE ROCK RIDGE INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR "
- "POSIX FILE SYSTEM SEMANTICS";
-static const char rrip_source[] =
- "PLEASE CONTACT DISC PUBLISHER FOR SPECIFICATION SOURCE. "
- "SEE PUBLISHER IDENTIFIER IN PRIMARY VOLUME DESCRIPTOR FOR "
- "CONTACT INFORMATION.";
-#define RRIP_ER_ID_SIZE (sizeof(rrip_identifier)-1)
-#define RRIP_ER_DSC_SIZE (sizeof(rrip_descriptor)-1)
-#define RRIP_ER_SRC_SIZE (sizeof(rrip_source)-1)
-#define RRIP_ER_SIZE (8 + RRIP_ER_ID_SIZE + \
- RRIP_ER_DSC_SIZE + RRIP_ER_SRC_SIZE)
-
-static const unsigned char zisofs_magic[8] = {
- 0x37, 0xE4, 0x53, 0x96, 0xC9, 0xDB, 0xD6, 0x07
-};
-
-#define ZF_HEADER_SIZE 16 /* zisofs header size. */
-#define ZF_LOG2_BS 15 /* log2 block size; 32K bytes. */
-#define ZF_BLOCK_SIZE (1UL << ZF_LOG2_BS)
-
-/*
- * Manage extra records.
- */
-struct extr_rec {
- int location;
- int offset;
- unsigned char buf[LOGICAL_BLOCK_SIZE];
- struct extr_rec *next;
-};
-
-struct ctl_extr_rec {
- int use_extr;
- unsigned char *bp;
- struct isoent *isoent;
- unsigned char *ce_ptr;
- int cur_len;
- int dr_len;
- int limit;
- int extr_off;
- int extr_loc;
-};
-#define DR_SAFETY RR_CE_SIZE
-#define DR_LIMIT (254 - DR_SAFETY)
-
-/*
- * The relation of struct isofile and isoent and archive_entry.
- *
- * Primary volume tree --> struct isoent
- * |
- * v
- * struct isofile --> archive_entry
- * ^
- * |
- * Joliet volume tree --> struct isoent
- *
- * struct isoent has specific information for volume.
- */
-
-struct isofile {
- /* Used for managing struct isofile list. */
- struct isofile *allnext;
- struct isofile *datanext;
- /* Used for managing a hardlinked struct isofile list. */
- struct isofile *hlnext;
- struct isofile *hardlink_target;
-
- struct archive_entry *entry;
-
- /*
- * Used for making a directory tree.
- */
- struct archive_string parentdir;
- struct archive_string basename;
- struct archive_string basename_utf16;
- struct archive_string symlink;
- int dircnt; /* The number of elements of
- * its parent directory */
-
- /*
- * Used for a Directory Record.
- */
- struct content {
- int64_t offset_of_temp;
- int64_t size;
- int blocks;
- uint32_t location;
- /*
- * One extent equals one content.
- * If this entry has multi extent, `next' variable points
- * next content data.
- */
- struct content *next; /* next content */
- } content, *cur_content;
- int write_content;
-
- enum {
- NO = 0,
- BOOT_CATALOG,
- BOOT_IMAGE
- } boot;
-
- /*
- * Used for a zisofs.
- */
- struct {
- unsigned char header_size;
- unsigned char log2_bs;
- uint32_t uncompressed_size;
- } zisofs;
-};
-
-struct isoent {
- /* Keep `rbnode' at the first member of struct isoent. */
- struct archive_rb_node rbnode;
-
- struct isofile *file;
-
- struct isoent *parent;
- /* A list of children.(use chnext) */
- struct {
- struct isoent *first;
- struct isoent **last;
- int cnt;
- } children;
- struct archive_rb_tree rbtree;
-
- /* A list of sub directories.(use drnext) */
- struct {
- struct isoent *first;
- struct isoent **last;
- int cnt;
- } subdirs;
- /* A sorted list of sub directories. */
- struct isoent **children_sorted;
- /* Used for managing struct isoent list. */
- struct isoent *chnext;
- struct isoent *drnext;
- struct isoent *ptnext;
-
- /*
- * Used for making a Directory Record.
- */
- int dir_number;
- struct {
- int vd;
- int self;
- int parent;
- int normal;
- } dr_len;
- uint32_t dir_location;
- int dir_block;
-
- /*
- * Identifier:
- * on primary, ISO9660 file/directory name.
- * on joliet, UCS2 file/directory name.
- * ext_off : offset of identifier extension.
- * ext_len : length of identifier extension.
- * id_len : byte size of identifier.
- * on primary, this is ext_off + ext_len + version length.
- * on joliet, this is ext_off + ext_len.
- * mb_len : length of multibyte-character of identifier.
- * on primary, mb_len and id_len are always the same.
- * on joliet, mb_len and id_len are different.
- */
- char *identifier;
- int ext_off;
- int ext_len;
- int id_len;
- int mb_len;
-
- /*
- * Used for making a Rockridge extension.
- * This is a part of Directory Records.
- */
- struct isoent *rr_parent;
- struct isoent *rr_child;
-
- /* Extra Record.(which we call in this source file)
- * A maximum size of the Directory Record is 254.
- * so, if generated RRIP data of a file cannot into a Directory
- * Record because of its size, that surplus data relocate this
- * Extra Record.
- */
- struct {
- struct extr_rec *first;
- struct extr_rec **last;
- struct extr_rec *current;
- } extr_rec_list;
-
- unsigned int virtual:1;
- /* If set to one, this file type is a directory.
- * A convenience flag to be used as
- * "archive_entry_filetype(isoent->file->entry) == AE_IFDIR".
- */
- unsigned int dir:1;
-};
-
-struct hardlink {
- struct archive_rb_node rbnode;
- int nlink;
- struct {
- struct isofile *first;
- struct isofile **last;
- } file_list;
-};
-
-/*
- * ISO writer options
- */
-struct iso_option {
- /*
- * Usage : abstract-file=<value>
- * Type : string, max 37 bytes
- * Default: Not specified
- * COMPAT : mkisofs -abstract <value>
- *
- * Specifies Abstract Filename.
- * This file shall be described in the Root Directory
- * and containing a abstract statement.
- */
- unsigned int abstract_file:1;
-#define OPT_ABSTRACT_FILE_DEFAULT 0 /* Not specified */
-#define ABSTRACT_FILE_SIZE 37
-
- /*
- * Usage : application-id=<value>
- * Type : string, max 128 bytes
- * Default: Not specified
- * COMPAT : mkisofs -A/-appid <value>.
- *
- * Specifies Application Identifier.
- * If the first byte is set to '_'(5F), the remaining
- * bytes of this option shall specify an identifier
- * for a file containing the identification of the
- * application.
- * This file shall be described in the Root Directory.
- */
- unsigned int application_id:1;
-#define OPT_APPLICATION_ID_DEFAULT 0 /* Use default identifier */
-#define APPLICATION_IDENTIFIER_SIZE 128
-
- /*
- * Usage : !allow-vernum
- * Type : boolean
- * Default: Enabled
- * : Violates the ISO9660 standard if disable.
- * COMPAT: mkisofs -N
- *
- * Allow filenames to use version numbers.
- */
- unsigned int allow_vernum:1;
-#define OPT_ALLOW_VERNUM_DEFAULT 1 /* Enabled */
-
- /*
- * Usage : biblio-file=<value>
- * Type : string, max 37 bytes
- * Default: Not specified
- * COMPAT : mkisofs -biblio <value>
- *
- * Specifies Bibliographic Filename.
- * This file shall be described in the Root Directory
- * and containing bibliographic records.
- */
- unsigned int biblio_file:1;
-#define OPT_BIBLIO_FILE_DEFAULT 0 /* Not specified */
-#define BIBLIO_FILE_SIZE 37
-
- /*
- * Usage : boot=<value>
- * Type : string
- * Default: Not specified
- * COMPAT : mkisofs -b/-eltorito-boot <value>
- *
- * Specifies "El Torito" boot image file to make
- * a bootable CD.
- */
- unsigned int boot:1;
-#define OPT_BOOT_DEFAULT 0 /* Not specified */
-
- /*
- * Usage : boot-catalog=<value>
- * Type : string
- * Default: "boot.catalog"
- * COMPAT : mkisofs -c/-eltorito-catalog <value>
- *
- * Specifies a fullpath of El Torito boot catalog.
- */
- unsigned int boot_catalog:1;
-#define OPT_BOOT_CATALOG_DEFAULT 0 /* Not specified */
-
- /*
- * Usage : boot-info-table
- * Type : boolean
- * Default: Disabled
- * COMPAT : mkisofs -boot-info-table
- *
- * Modify the boot image file specified by `boot'
- * option; ISO writer stores boot file information
- * into the boot file in ISO image at offset 8
- * through offset 64.
- */
- unsigned int boot_info_table:1;
-#define OPT_BOOT_INFO_TABLE_DEFAULT 0 /* Disabled */
-
- /*
- * Usage : boot-load-seg=<value>
- * Type : hexadecimal
- * Default: Not specified
- * COMPAT : mkisofs -boot-load-seg <value>
- *
- * Specifies a load segment for boot image.
- * This is used with no-emulation mode.
- */
- unsigned int boot_load_seg:1;
-#define OPT_BOOT_LOAD_SEG_DEFAULT 0 /* Not specified */
-
- /*
- * Usage : boot-load-size=<value>
- * Type : decimal
- * Default: Not specified
- * COMPAT : mkisofs -boot-load-size <value>
- *
- * Specifies a sector count for boot image.
- * This is used with no-emulation mode.
- */
- unsigned int boot_load_size:1;
-#define OPT_BOOT_LOAD_SIZE_DEFAULT 0 /* Not specified */
-
- /*
- * Usage : boot-type=<boot-media-type>
- * : 'no-emulation' : 'no emulation' image
- * : 'fd' : floppy disk image
- * : 'hard-disk' : hard disk image
- * Type : string
- * Default: Auto detect
- * : We check a size of boot image;
- * : If the size is just 1.22M/1.44M/2.88M,
- * : we assume boot_type is 'fd';
- * : otherwise boot_type is 'no-emulation'.
- * COMPAT :
- * boot=no-emulation
- * mkisofs -no-emul-boot
- * boot=fd
- * This is a default on the mkisofs.
- * boot=hard-disk
- * mkisofs -hard-disk-boot
- *
- * Specifies a type of "El Torito" boot image.
- */
- unsigned int boot_type:2;
-#define OPT_BOOT_TYPE_AUTO 0 /* auto detect */
-#define OPT_BOOT_TYPE_NO_EMU 1 /* ``no emulation'' image */
-#define OPT_BOOT_TYPE_FD 2 /* floppy disk image */
-#define OPT_BOOT_TYPE_HARD_DISK 3 /* hard disk image */
-#define OPT_BOOT_TYPE_DEFAULT OPT_BOOT_TYPE_AUTO
-
- /*
- * Usage : compression-level=<value>
- * Type : decimal
- * Default: Not specified
- * COMPAT : NONE
- *
- * Specifies compression level for option zisofs=direct.
- */
- unsigned int compression_level:1;
-#define OPT_COMPRESSION_LEVEL_DEFAULT 0 /* Not specified */
-
- /*
- * Usage : copyright-file=<value>
- * Type : string, max 37 bytes
- * Default: Not specified
- * COMPAT : mkisofs -copyright <value>
- *
- * Specifies Copyright Filename.
- * This file shall be described in the Root Directory
- * and containing a copyright statement.
- */
- unsigned int copyright_file:1;
-#define OPT_COPYRIGHT_FILE_DEFAULT 0 /* Not specified */
-#define COPYRIGHT_FILE_SIZE 37
-
- /*
- * Usage : gid=<value>
- * Type : decimal
- * Default: Not specified
- * COMPAT : mkisofs -gid <value>
- *
- * Specifies a group id to rewrite the group id of all files.
- */
- unsigned int gid:1;
-#define OPT_GID_DEFAULT 0 /* Not specified */
-
- /*
- * Usage : iso-level=[1234]
- * Type : decimal
- * Default: 1
- * COMPAT : mkisofs -iso-level <value>
- *
- * Specifies ISO9600 Level.
- * Level 1: [DEFAULT]
- * - limits each file size less than 4Gi bytes;
- * - a File Name shall not contain more than eight
- * d-characters or eight d1-characters;
- * - a File Name Extension shall not contain more than
- * three d-characters or three d1-characters;
- * - a Directory Identifier shall not contain more
- * than eight d-characters or eight d1-characters.
- * Level 2:
- * - limits each file size less than 4Giga bytes;
- * - a File Name shall not contain more than thirty
- * d-characters or thirty d1-characters;
- * - a File Name Extension shall not contain more than
- * thirty d-characters or thirty d1-characters;
- * - a Directory Identifier shall not contain more
- * than thirty-one d-characters or thirty-one
- * d1-characters.
- * Level 3:
- * - no limit of file size; use multi extent.
- * Level 4:
- * - this level 4 simulates mkisofs option
- * '-iso-level 4';
- * - crate a enhanced volume as mkisofs doing;
- * - allow a File Name to have leading dot;
- * - allow a File Name to have all ASCII letters;
- * - allow a File Name to have multiple dots;
- * - allow more then 8 depths of directory trees;
- * - disable a version number to a File Name;
- * - disable a forced period to the tail of a File Name;
- * - the maximum length of files and directories is raised to 193.
- * if rockridge option is disabled, raised to 207.
- */
- unsigned int iso_level:3;
-#define OPT_ISO_LEVEL_DEFAULT 1 /* ISO Level 1 */
-
- /*
- * Usage : joliet[=long]
- * : !joliet
- * : Do not generate Joliet Volume and Records.
- * : joliet [DEFAULT]
- * : Generates Joliet Volume and Directory Records.
- * : [COMPAT: mkisofs -J/-joliet]
- * : joliet=long
- * : The joliet filenames are up to 103 Unicode
- * : characters.
- * : This option breaks the Joliet specification.
- * : [COMPAT: mkisofs -J -joliet-long]
- * Type : boolean/string
- * Default: Enabled
- * COMPAT : mkisofs -J / -joliet-long
- *
- * Generates Joliet Volume and Directory Records.
- */
- unsigned int joliet:2;
-#define OPT_JOLIET_DISABLE 0 /* Not generate Joliet Records. */
-#define OPT_JOLIET_ENABLE 1 /* Generate Joliet Records. */
-#define OPT_JOLIET_LONGNAME 2 /* Use long joliet filenames.*/
-#define OPT_JOLIET_DEFAULT OPT_JOLIET_ENABLE
-
- /*
- * Usage : !limit-depth
- * Type : boolean
- * Default: Enabled
- * : Violates the ISO9660 standard if disable.
- * COMPAT : mkisofs -D/-disable-deep-relocation
- *
- * The number of levels in hierarchy cannot exceed eight.
- */
- unsigned int limit_depth:1;
-#define OPT_LIMIT_DEPTH_DEFAULT 1 /* Enabled */
-
- /*
- * Usage : !limit-dirs
- * Type : boolean
- * Default: Enabled
- * : Violates the ISO9660 standard if disable.
- * COMPAT : mkisofs -no-limit-pathtables
- *
- * Limits the number of directories less than 65536 due
- * to the size of the Parent Directory Number of Path
- * Table.
- */
- unsigned int limit_dirs:1;
-#define OPT_LIMIT_DIRS_DEFAULT 1 /* Enabled */
-
- /*
- * Usage : !pad
- * Type : boolean
- * Default: Enabled
- * COMPAT : -pad/-no-pad
- *
- * Pads the end of the ISO image by null of 300Ki bytes.
- */
- unsigned int pad:1;
-#define OPT_PAD_DEFAULT 1 /* Enabled */
-
- /*
- * Usage : publisher=<value>
- * Type : string, max 128 bytes
- * Default: Not specified
- * COMPAT : mkisofs -publisher <value>
- *
- * Specifies Publisher Identifier.
- * If the first byte is set to '_'(5F), the remaining
- * bytes of this option shall specify an identifier
- * for a file containing the identification of the user.
- * This file shall be described in the Root Directory.
- */
- unsigned int publisher:1;
-#define OPT_PUBLISHER_DEFAULT 0 /* Not specified */
-#define PUBLISHER_IDENTIFIER_SIZE 128
-
- /*
- * Usage : rockridge
- * : !rockridge
- * : disable to generate SUSP and RR records.
- * : rockridge
- * : the same as 'rockridge=useful'.
- * : rockridge=strict
- * : generate SUSP and RR records.
- * : [COMPAT: mkisofs -R]
- * : rockridge=useful [DEFAULT]
- * : generate SUSP and RR records.
- * : [COMPAT: mkisofs -r]
- * : NOTE Our rockridge=useful option does not set a zero
- * : to uid and gid, you should use application
- * : option such as --gid,--gname,--uid and --uname
- * : bsdtar options instead.
- * Type : boolean/string
- * Default: Enabled as rockridge=useful
- * COMPAT : mkisofs -r / -R
- *
- * Generates SUSP and RR records.
- */
- unsigned int rr:2;
-#define OPT_RR_DISABLED 0
-#define OPT_RR_STRICT 1
-#define OPT_RR_USEFUL 2
-#define OPT_RR_DEFAULT OPT_RR_USEFUL
-
- /*
- * Usage : volume-id=<value>
- * Type : string, max 32 bytes
- * Default: Not specified
- * COMPAT : mkisofs -V <value>
- *
- * Specifies Volume Identifier.
- */
- unsigned int volume_id:1;
-#define OPT_VOLUME_ID_DEFAULT 0 /* Use default identifier */
-#define VOLUME_IDENTIFIER_SIZE 32
-
- /*
- * Usage : !zisofs [DEFAULT]
- * : Disable to generate RRIP 'ZF' extension.
- * : zisofs
- * : Make files zisofs file and generate RRIP 'ZF'
- * : extension. So you do not need mkzftree utility
- * : for making zisofs.
- * : When the file size is less than one Logical Block
- * : size, that file will not zisofs'ed since it does
- * : reduce an ISO-image size.
- * :
- * : When you specify option 'boot=<boot-image>', that
- * : 'boot-image' file won't be converted to zisofs file.
- * Type : boolean
- * Default: Disabled
- *
- * Generates RRIP 'ZF' System Use Entry.
- */
- unsigned int zisofs:1;
-#define OPT_ZISOFS_DISABLED 0
-#define OPT_ZISOFS_DIRECT 1
-#define OPT_ZISOFS_DEFAULT OPT_ZISOFS_DISABLED
-
-};
-
-struct iso9660 {
- /* The creation time of ISO image. */
- time_t birth_time;
- /* A file stream of a temporary file, which file contents
- * save to until ISO image can be created. */
- int temp_fd;
-
- struct isofile *cur_file;
- struct isoent *cur_dirent;
- struct archive_string cur_dirstr;
- uint64_t bytes_remaining;
- int need_multi_extent;
-
- /* Temporary string buffer for Joliet extension. */
- struct archive_string utf16be;
- struct archive_string mbs;
-
- struct archive_string_conv *sconv_to_utf16be;
- struct archive_string_conv *sconv_from_utf16be;
-
- /* A list of all of struct isofile entries. */
- struct {
- struct isofile *first;
- struct isofile **last;
- } all_file_list;
-
- /* A list of struct isofile entries which have its
- * contents and are not a directory, a hardlinked file
- * and a symlink file. */
- struct {
- struct isofile *first;
- struct isofile **last;
- } data_file_list;
-
- /* Used for managing to find hardlinking files. */
- struct archive_rb_tree hardlink_rbtree;
-
- /* Used for making the Path Table Record. */
- struct vdd {
- /* the root of entry tree. */
- struct isoent *rootent;
- enum vdd_type {
- VDD_PRIMARY,
- VDD_JOLIET,
- VDD_ENHANCED
- } vdd_type;
-
- struct path_table {
- struct isoent *first;
- struct isoent **last;
- struct isoent **sorted;
- int cnt;
- } *pathtbl;
- int max_depth;
-
- int path_table_block;
- int path_table_size;
- int location_type_L_path_table;
- int location_type_M_path_table;
- int total_dir_block;
- } primary, joliet;
-
- /* Used for making a Volume Descriptor. */
- int volume_space_size;
- int volume_sequence_number;
- int total_file_block;
- struct archive_string volume_identifier;
- struct archive_string publisher_identifier;
- struct archive_string data_preparer_identifier;
- struct archive_string application_identifier;
- struct archive_string copyright_file_identifier;
- struct archive_string abstract_file_identifier;
- struct archive_string bibliographic_file_identifier;
-
- /* Used for making rockridge extensions. */
- int location_rrip_er;
-
- /* Used for making zisofs. */
- struct {
- unsigned int detect_magic:1;
- unsigned int making:1;
- unsigned int allzero:1;
- unsigned char magic_buffer[64];
- int magic_cnt;
-
-#ifdef HAVE_ZLIB_H
- /*
- * Copy a compressed file to iso9660.zisofs.temp_fd
- * and also copy a uncompressed file(original file) to
- * iso9660.temp_fd . If the number of logical block
- * of the compressed file is less than the number of
- * logical block of the uncompressed file, use it and
- * remove the copy of the uncompressed file.
- * but if not, we use uncompressed file and remove
- * the copy of the compressed file.
- */
- uint32_t *block_pointers;
- size_t block_pointers_allocated;
- int block_pointers_cnt;
- int block_pointers_idx;
- int64_t total_size;
- int64_t block_offset;
-
- z_stream stream;
- int stream_valid;
- int64_t remaining;
- int compression_level;
-#endif
- } zisofs;
-
- struct isoent *directories_too_deep;
- int dircnt_max;
-
- /* Write buffer. */
-#define wb_buffmax() (LOGICAL_BLOCK_SIZE * 32)
-#define wb_remaining(a) (((struct iso9660 *)(a)->format_data)->wbuff_remaining)
-#define wb_offset(a) (((struct iso9660 *)(a)->format_data)->wbuff_offset \
- + wb_buffmax() - wb_remaining(a))
- unsigned char wbuff[LOGICAL_BLOCK_SIZE * 32];
- size_t wbuff_remaining;
- enum {
- WB_TO_STREAM,
- WB_TO_TEMP
- } wbuff_type;
- int64_t wbuff_offset;
- int64_t wbuff_written;
- int64_t wbuff_tail;
-
- /* 'El Torito' boot data. */
- struct {
- /* boot catalog file */
- struct archive_string catalog_filename;
- struct isoent *catalog;
- /* boot image file */
- struct archive_string boot_filename;
- struct isoent *boot;
-
- unsigned char platform_id;
-#define BOOT_PLATFORM_X86 0
-#define BOOT_PLATFORM_PPC 1
-#define BOOT_PLATFORM_MAC 2
- struct archive_string id;
- unsigned char media_type;
-#define BOOT_MEDIA_NO_EMULATION 0
-#define BOOT_MEDIA_1_2M_DISKETTE 1
-#define BOOT_MEDIA_1_44M_DISKETTE 2
-#define BOOT_MEDIA_2_88M_DISKETTE 3
-#define BOOT_MEDIA_HARD_DISK 4
- unsigned char system_type;
- uint16_t boot_load_seg;
- uint16_t boot_load_size;
-#define BOOT_LOAD_SIZE 4
- } el_torito;
-
- struct iso_option opt;
-};
-
-/*
- * Types of Volume Descriptor
- */
-enum VD_type {
- VDT_BOOT_RECORD=0, /* Boot Record Volume Descriptor */
- VDT_PRIMARY=1, /* Primary Volume Descriptor */
- VDT_SUPPLEMENTARY=2, /* Supplementary Volume Descriptor */
- VDT_TERMINATOR=255 /* Volume Descriptor Set Terminator */
-};
-
-/*
- * Types of Directory Record
- */
-enum dir_rec_type {
- DIR_REC_VD, /* Stored in Volume Descriptor. */
- DIR_REC_SELF, /* Stored as Current Directory. */
- DIR_REC_PARENT, /* Stored as Parent Directory. */
- DIR_REC_NORMAL /* Stored as Child. */
-};
-
-/*
- * Kinds of Volume Descriptor Character
- */
-enum vdc {
- VDC_STD,
- VDC_LOWERCASE,
- VDC_UCS2,
- VDC_UCS2_DIRECT
-};
-
-/*
- * IDentifier Resolver.
- * Used for resolving duplicated filenames.
- */
-struct idr {
- struct idrent {
- struct archive_rb_node rbnode;
- /* Used in wait_list. */
- struct idrent *wnext;
- struct idrent *avail;
-
- struct isoent *isoent;
- int weight;
- int noff;
- int rename_num;
- } *idrent_pool;
-
- struct archive_rb_tree rbtree;
-
- struct {
- struct idrent *first;
- struct idrent **last;
- } wait_list;
-
- int pool_size;
- int pool_idx;
- int num_size;
- int null_size;
-
- char char_map[0x80];
-};
-
-enum char_type {
- A_CHAR,
- D_CHAR
-};
-
-
-static int iso9660_options(struct archive_write *,
- const char *, const char *);
-static int iso9660_write_header(struct archive_write *,
- struct archive_entry *);
-static ssize_t iso9660_write_data(struct archive_write *,
- const void *, size_t);
-static int iso9660_finish_entry(struct archive_write *);
-static int iso9660_close(struct archive_write *);
-static int iso9660_free(struct archive_write *);
-
-static void get_system_identitier(char *, size_t);
-static void set_str(unsigned char *, const char *, size_t, char,
- const char *);
-static inline int joliet_allowed_char(unsigned char, unsigned char);
-static int set_str_utf16be(struct archive_write *, unsigned char *,
- const char *, size_t, uint16_t, enum vdc);
-static int set_str_a_characters_bp(struct archive_write *,
- unsigned char *, int, int, const char *, enum vdc);
-static int set_str_d_characters_bp(struct archive_write *,
- unsigned char *, int, int, const char *, enum vdc);
-static void set_VD_bp(unsigned char *, enum VD_type, unsigned char);
-static inline void set_unused_field_bp(unsigned char *, int, int);
-
-static unsigned char *extra_open_record(unsigned char *, int,
- struct isoent *, struct ctl_extr_rec *);
-static void extra_close_record(struct ctl_extr_rec *, int);
-static unsigned char * extra_next_record(struct ctl_extr_rec *, int);
-static unsigned char *extra_get_record(struct isoent *, int *, int *, int *);
-static void extra_tell_used_size(struct ctl_extr_rec *, int);
-static int extra_setup_location(struct isoent *, int);
-static int set_directory_record_rr(unsigned char *, int,
- struct isoent *, struct iso9660 *, enum dir_rec_type);
-static int set_directory_record(unsigned char *, size_t,
- struct isoent *, struct iso9660 *, enum dir_rec_type,
- enum vdd_type);
-static inline int get_dir_rec_size(struct iso9660 *, struct isoent *,
- enum dir_rec_type, enum vdd_type);
-static inline unsigned char *wb_buffptr(struct archive_write *);
-static int wb_write_out(struct archive_write *);
-static int wb_consume(struct archive_write *, size_t);
-#ifdef HAVE_ZLIB_H
-static int wb_set_offset(struct archive_write *, int64_t);
-#endif
-static int write_null(struct archive_write *, size_t);
-static int write_VD_terminator(struct archive_write *);
-static int set_file_identifier(unsigned char *, int, int, enum vdc,
- struct archive_write *, struct vdd *,
- struct archive_string *, const char *, int,
- enum char_type);
-static int write_VD(struct archive_write *, struct vdd *);
-static int write_VD_boot_record(struct archive_write *);
-static int write_information_block(struct archive_write *);
-static int write_path_table(struct archive_write *, int,
- struct vdd *);
-static int write_directory_descriptors(struct archive_write *,
- struct vdd *);
-static int write_file_descriptors(struct archive_write *);
-static int write_rr_ER(struct archive_write *);
-static void calculate_path_table_size(struct vdd *);
-
-static void isofile_init_entry_list(struct iso9660 *);
-static void isofile_add_entry(struct iso9660 *, struct isofile *);
-static void isofile_free_all_entries(struct iso9660 *);
-static void isofile_init_entry_data_file_list(struct iso9660 *);
-static void isofile_add_data_file(struct iso9660 *, struct isofile *);
-static struct isofile * isofile_new(struct archive_write *,
- struct archive_entry *);
-static void isofile_free(struct isofile *);
-static int isofile_gen_utility_names(struct archive_write *,
- struct isofile *);
-static int isofile_register_hardlink(struct archive_write *,
- struct isofile *);
-static void isofile_connect_hardlink_files(struct iso9660 *);
-static void isofile_init_hardlinks(struct iso9660 *);
-static void isofile_free_hardlinks(struct iso9660 *);
-
-static struct isoent *isoent_new(struct isofile *);
-static int isoent_clone_tree(struct archive_write *,
- struct isoent **, struct isoent *);
-static void _isoent_free(struct isoent *isoent);
-static void isoent_free_all(struct isoent *);
-static struct isoent * isoent_create_virtual_dir(struct archive_write *,
- struct iso9660 *, const char *);
-static int isoent_cmp_node(const struct archive_rb_node *,
- const struct archive_rb_node *);
-static int isoent_cmp_key(const struct archive_rb_node *,
- const void *);
-static int isoent_add_child_head(struct isoent *, struct isoent *);
-static int isoent_add_child_tail(struct isoent *, struct isoent *);
-static void isoent_remove_child(struct isoent *, struct isoent *);
-static void isoent_setup_directory_location(struct iso9660 *,
- int, struct vdd *);
-static void isoent_setup_file_location(struct iso9660 *, int);
-static int get_path_component(char *, size_t, const char *);
-static int isoent_tree(struct archive_write *, struct isoent **);
-static struct isoent *isoent_find_child(struct isoent *, const char *);
-static struct isoent *isoent_find_entry(struct isoent *, const char *);
-static void idr_relaxed_filenames(char *);
-static void idr_init(struct iso9660 *, struct vdd *, struct idr *);
-static void idr_cleanup(struct idr *);
-static int idr_ensure_poolsize(struct archive_write *, struct idr *,
- int);
-static int idr_start(struct archive_write *, struct idr *,
- int, int, int, int, const struct archive_rb_tree_ops *);
-static void idr_register(struct idr *, struct isoent *, int,
- int);
-static void idr_extend_identifier(struct idrent *, int, int);
-static void idr_resolve(struct idr *, void (*)(unsigned char *, int));
-static void idr_set_num(unsigned char *, int);
-static void idr_set_num_beutf16(unsigned char *, int);
-static int isoent_gen_iso9660_identifier(struct archive_write *,
- struct isoent *, struct idr *);
-static int isoent_gen_joliet_identifier(struct archive_write *,
- struct isoent *, struct idr *);
-static int isoent_cmp_iso9660_identifier(const struct isoent *,
- const struct isoent *);
-static int isoent_cmp_node_iso9660(const struct archive_rb_node *,
- const struct archive_rb_node *);
-static int isoent_cmp_key_iso9660(const struct archive_rb_node *,
- const void *);
-static int isoent_cmp_joliet_identifier(const struct isoent *,
- const struct isoent *);
-static int isoent_cmp_node_joliet(const struct archive_rb_node *,
- const struct archive_rb_node *);
-static int isoent_cmp_key_joliet(const struct archive_rb_node *,
- const void *);
-static inline void path_table_add_entry(struct path_table *, struct isoent *);
-static inline struct isoent * path_table_last_entry(struct path_table *);
-static int isoent_make_path_table(struct archive_write *);
-static int isoent_find_out_boot_file(struct archive_write *,
- struct isoent *);
-static int isoent_create_boot_catalog(struct archive_write *,
- struct isoent *);
-static size_t fd_boot_image_size(int);
-static int make_boot_catalog(struct archive_write *);
-static int setup_boot_information(struct archive_write *);
-
-static int zisofs_init(struct archive_write *, struct isofile *);
-static void zisofs_detect_magic(struct archive_write *,
- const void *, size_t);
-static int zisofs_write_to_temp(struct archive_write *,
- const void *, size_t);
-static int zisofs_finish_entry(struct archive_write *);
-static int zisofs_rewind_boot_file(struct archive_write *);
-static int zisofs_free(struct archive_write *);
-
-int
-archive_write_set_format_iso9660(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct iso9660 *iso9660;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_format_iso9660");
-
- /* If another format was already registered, unregister it. */
- if (a->format_free != NULL)
- (a->format_free)(a);
-
- iso9660 = calloc(1, sizeof(*iso9660));
- if (iso9660 == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate iso9660 data");
- return (ARCHIVE_FATAL);
- }
- iso9660->birth_time = 0;
- iso9660->temp_fd = -1;
- iso9660->cur_file = NULL;
- iso9660->primary.max_depth = 0;
- iso9660->primary.vdd_type = VDD_PRIMARY;
- iso9660->primary.pathtbl = NULL;
- iso9660->joliet.rootent = NULL;
- iso9660->joliet.max_depth = 0;
- iso9660->joliet.vdd_type = VDD_JOLIET;
- iso9660->joliet.pathtbl = NULL;
- isofile_init_entry_list(iso9660);
- isofile_init_entry_data_file_list(iso9660);
- isofile_init_hardlinks(iso9660);
- iso9660->directories_too_deep = NULL;
- iso9660->dircnt_max = 1;
- iso9660->wbuff_remaining = wb_buffmax();
- iso9660->wbuff_type = WB_TO_TEMP;
- iso9660->wbuff_offset = 0;
- iso9660->wbuff_written = 0;
- iso9660->wbuff_tail = 0;
- archive_string_init(&(iso9660->utf16be));
- archive_string_init(&(iso9660->mbs));
-
- /*
- * Init Identifiers used for PVD and SVD.
- */
- archive_string_init(&(iso9660->volume_identifier));
- archive_strcpy(&(iso9660->volume_identifier), "CDROM");
- archive_string_init(&(iso9660->publisher_identifier));
- archive_string_init(&(iso9660->data_preparer_identifier));
- archive_string_init(&(iso9660->application_identifier));
- archive_strcpy(&(iso9660->application_identifier),
- archive_version_string());
- archive_string_init(&(iso9660->copyright_file_identifier));
- archive_string_init(&(iso9660->abstract_file_identifier));
- archive_string_init(&(iso9660->bibliographic_file_identifier));
-
- /*
- * Init El Torito bootable CD variables.
- */
- archive_string_init(&(iso9660->el_torito.catalog_filename));
- iso9660->el_torito.catalog = NULL;
- /* Set default file name of boot catalog */
- archive_strcpy(&(iso9660->el_torito.catalog_filename),
- "boot.catalog");
- archive_string_init(&(iso9660->el_torito.boot_filename));
- iso9660->el_torito.boot = NULL;
- iso9660->el_torito.platform_id = BOOT_PLATFORM_X86;
- archive_string_init(&(iso9660->el_torito.id));
- iso9660->el_torito.boot_load_seg = 0;
- iso9660->el_torito.boot_load_size = BOOT_LOAD_SIZE;
-
- /*
- * Init zisofs variables.
- */
-#ifdef HAVE_ZLIB_H
- iso9660->zisofs.block_pointers = NULL;
- iso9660->zisofs.block_pointers_allocated = 0;
- iso9660->zisofs.stream_valid = 0;
- iso9660->zisofs.compression_level = 9;
- memset(&(iso9660->zisofs.stream), 0,
- sizeof(iso9660->zisofs.stream));
-#endif
-
- /*
- * Set default value of iso9660 options.
- */
- iso9660->opt.abstract_file = OPT_ABSTRACT_FILE_DEFAULT;
- iso9660->opt.application_id = OPT_APPLICATION_ID_DEFAULT;
- iso9660->opt.allow_vernum = OPT_ALLOW_VERNUM_DEFAULT;
- iso9660->opt.biblio_file = OPT_BIBLIO_FILE_DEFAULT;
- iso9660->opt.boot = OPT_BOOT_DEFAULT;
- iso9660->opt.boot_catalog = OPT_BOOT_CATALOG_DEFAULT;
- iso9660->opt.boot_info_table = OPT_BOOT_INFO_TABLE_DEFAULT;
- iso9660->opt.boot_load_seg = OPT_BOOT_LOAD_SEG_DEFAULT;
- iso9660->opt.boot_load_size = OPT_BOOT_LOAD_SIZE_DEFAULT;
- iso9660->opt.boot_type = OPT_BOOT_TYPE_DEFAULT;
- iso9660->opt.compression_level = OPT_COMPRESSION_LEVEL_DEFAULT;
- iso9660->opt.copyright_file = OPT_COPYRIGHT_FILE_DEFAULT;
- iso9660->opt.iso_level = OPT_ISO_LEVEL_DEFAULT;
- iso9660->opt.joliet = OPT_JOLIET_DEFAULT;
- iso9660->opt.limit_depth = OPT_LIMIT_DEPTH_DEFAULT;
- iso9660->opt.limit_dirs = OPT_LIMIT_DIRS_DEFAULT;
- iso9660->opt.pad = OPT_PAD_DEFAULT;
- iso9660->opt.publisher = OPT_PUBLISHER_DEFAULT;
- iso9660->opt.rr = OPT_RR_DEFAULT;
- iso9660->opt.volume_id = OPT_VOLUME_ID_DEFAULT;
- iso9660->opt.zisofs = OPT_ZISOFS_DEFAULT;
-
- /* Create the root directory. */
- iso9660->primary.rootent =
- isoent_create_virtual_dir(a, iso9660, "");
- if (iso9660->primary.rootent == NULL) {
- free(iso9660);
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- iso9660->primary.rootent->parent = iso9660->primary.rootent;
- iso9660->cur_dirent = iso9660->primary.rootent;
- archive_string_init(&(iso9660->cur_dirstr));
- archive_string_ensure(&(iso9660->cur_dirstr), 1);
- iso9660->cur_dirstr.s[0] = 0;
- iso9660->sconv_to_utf16be = NULL;
- iso9660->sconv_from_utf16be = NULL;
-
- a->format_data = iso9660;
- a->format_name = "iso9660";
- a->format_options = iso9660_options;
- a->format_write_header = iso9660_write_header;
- a->format_write_data = iso9660_write_data;
- a->format_finish_entry = iso9660_finish_entry;
- a->format_close = iso9660_close;
- a->format_free = iso9660_free;
- a->archive.archive_format = ARCHIVE_FORMAT_ISO9660;
- a->archive.archive_format_name = "ISO9660";
-
- return (ARCHIVE_OK);
-}
-
-static int
-get_str_opt(struct archive_write *a, struct archive_string *s,
- size_t maxsize, const char *key, const char *value)
-{
-
- if (strlen(value) > maxsize) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Value is longer than %zu characters "
- "for option ``%s''", maxsize, key);
- return (ARCHIVE_FATAL);
- }
- archive_strcpy(s, value);
- return (ARCHIVE_OK);
-}
-
-static int
-get_num_opt(struct archive_write *a, int *num, int high, int low,
- const char *key, const char *value)
-{
- const char *p = value;
- int data = 0;
- int neg = 0;
-
- if (p == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Invalid value(empty) for option ``%s''", key);
- return (ARCHIVE_FATAL);
- }
- if (*p == '-') {
- neg = 1;
- p++;
- }
- while (*p) {
- if (*p >= '0' && *p <= '9')
- data = data * 10 + *p - '0';
- else {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Invalid value for option ``%s''", key);
- return (ARCHIVE_FATAL);
- }
- if (data > high) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Invalid value(over %d) for "
- "option ``%s''", high, key);
- return (ARCHIVE_FATAL);
- }
- if (data < low) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Invalid value(under %d) for "
- "option ``%s''", low, key);
- return (ARCHIVE_FATAL);
- }
- p++;
- }
- if (neg)
- data *= -1;
- *num = data;
-
- return (ARCHIVE_OK);
-}
-
-static int
-iso9660_options(struct archive_write *a, const char *key, const char *value)
-{
- struct iso9660 *iso9660 = a->format_data;
- const char *p;
- int r;
-
- switch (key[0]) {
- case 'a':
- if (strcmp(key, "abstract-file") == 0) {
- r = get_str_opt(a,
- &(iso9660->abstract_file_identifier),
- ABSTRACT_FILE_SIZE, key, value);
- iso9660->opt.abstract_file = r == ARCHIVE_OK;
- return (r);
- }
- if (strcmp(key, "application-id") == 0) {
- r = get_str_opt(a,
- &(iso9660->application_identifier),
- APPLICATION_IDENTIFIER_SIZE, key, value);
- iso9660->opt.application_id = r == ARCHIVE_OK;
- return (r);
- }
- if (strcmp(key, "allow-vernum") == 0) {
- iso9660->opt.allow_vernum = value != NULL;
- return (ARCHIVE_OK);
- }
- break;
- case 'b':
- if (strcmp(key, "biblio-file") == 0) {
- r = get_str_opt(a,
- &(iso9660->bibliographic_file_identifier),
- BIBLIO_FILE_SIZE, key, value);
- iso9660->opt.biblio_file = r == ARCHIVE_OK;
- return (r);
- }
- if (strcmp(key, "boot") == 0) {
- if (value == NULL)
- iso9660->opt.boot = 0;
- else {
- iso9660->opt.boot = 1;
- archive_strcpy(
- &(iso9660->el_torito.boot_filename),
- value);
- }
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "boot-catalog") == 0) {
- r = get_str_opt(a,
- &(iso9660->el_torito.catalog_filename),
- 1024, key, value);
- iso9660->opt.boot_catalog = r == ARCHIVE_OK;
- return (r);
- }
- if (strcmp(key, "boot-info-table") == 0) {
- iso9660->opt.boot_info_table = value != NULL;
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "boot-load-seg") == 0) {
- uint32_t seg;
-
- iso9660->opt.boot_load_seg = 0;
- if (value == NULL)
- goto invalid_value;
- seg = 0;
- p = value;
- if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X'))
- p += 2;
- while (*p) {
- if (seg)
- seg <<= 4;
- if (*p >= 'A' && *p <= 'F')
- seg += *p - 'A' + 0x0a;
- else if (*p >= 'a' && *p <= 'f')
- seg += *p - 'a' + 0x0a;
- else if (*p >= '0' && *p <= '9')
- seg += *p - '0';
- else
- goto invalid_value;
- if (seg > 0xffff) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Invalid value(over 0xffff) for "
- "option ``%s''", key);
- return (ARCHIVE_FATAL);
- }
- p++;
- }
- iso9660->el_torito.boot_load_seg = (uint16_t)seg;
- iso9660->opt.boot_load_seg = 1;
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "boot-load-size") == 0) {
- int num = 0;
- r = get_num_opt(a, &num, 0xffff, 1, key, value);
- iso9660->opt.boot_load_size = r == ARCHIVE_OK;
- if (r != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- iso9660->el_torito.boot_load_size = (uint16_t)num;
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "boot-type") == 0) {
- if (value == NULL)
- goto invalid_value;
- if (strcmp(value, "no-emulation") == 0)
- iso9660->opt.boot_type = OPT_BOOT_TYPE_NO_EMU;
- else if (strcmp(value, "fd") == 0)
- iso9660->opt.boot_type = OPT_BOOT_TYPE_FD;
- else if (strcmp(value, "hard-disk") == 0)
- iso9660->opt.boot_type = OPT_BOOT_TYPE_HARD_DISK;
- else
- goto invalid_value;
- return (ARCHIVE_OK);
- }
- break;
- case 'c':
- if (strcmp(key, "compression-level") == 0) {
-#ifdef HAVE_ZLIB_H
- if (value == NULL ||
- !(value[0] >= '0' && value[0] <= '9') ||
- value[1] != '\0')
- goto invalid_value;
- iso9660->zisofs.compression_level = value[0] - '0';
- iso9660->opt.compression_level = 1;
- return (ARCHIVE_OK);
-#else
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Option ``%s'' "
- "is not supported on this platform.", key);
- return (ARCHIVE_FATAL);
-#endif
- }
- if (strcmp(key, "copyright-file") == 0) {
- r = get_str_opt(a,
- &(iso9660->copyright_file_identifier),
- COPYRIGHT_FILE_SIZE, key, value);
- iso9660->opt.copyright_file = r == ARCHIVE_OK;
- return (r);
- }
-#ifdef DEBUG
- /* Specifies Volume creation date and time;
- * year(4),month(2),day(2),hour(2),minute(2),second(2).
- * e.g. "20090929033757"
- */
- if (strcmp(key, "creation") == 0) {
- struct tm tm;
- char buf[5];
-
- p = value;
- if (p == NULL || strlen(p) < 14)
- goto invalid_value;
- memset(&tm, 0, sizeof(tm));
- memcpy(buf, p, 4); buf[4] = '\0'; p += 4;
- tm.tm_year = strtol(buf, NULL, 10) - 1900;
- memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
- tm.tm_mon = strtol(buf, NULL, 10) - 1;
- memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
- tm.tm_mday = strtol(buf, NULL, 10);
- memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
- tm.tm_hour = strtol(buf, NULL, 10);
- memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
- tm.tm_min = strtol(buf, NULL, 10);
- memcpy(buf, p, 2); buf[2] = '\0';
- tm.tm_sec = strtol(buf, NULL, 10);
- iso9660->birth_time = mktime(&tm);
- return (ARCHIVE_OK);
- }
-#endif
- break;
- case 'i':
- if (strcmp(key, "iso-level") == 0) {
- if (value != NULL && value[1] == '\0' &&
- (value[0] >= '1' && value[0] <= '4')) {
- iso9660->opt.iso_level = value[0]-'0';
- return (ARCHIVE_OK);
- }
- goto invalid_value;
- }
- break;
- case 'j':
- if (strcmp(key, "joliet") == 0) {
- if (value == NULL)
- iso9660->opt.joliet = OPT_JOLIET_DISABLE;
- else if (strcmp(value, "1") == 0)
- iso9660->opt.joliet = OPT_JOLIET_ENABLE;
- else if (strcmp(value, "long") == 0)
- iso9660->opt.joliet = OPT_JOLIET_LONGNAME;
- else
- goto invalid_value;
- return (ARCHIVE_OK);
- }
- break;
- case 'l':
- if (strcmp(key, "limit-depth") == 0) {
- iso9660->opt.limit_depth = value != NULL;
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "limit-dirs") == 0) {
- iso9660->opt.limit_dirs = value != NULL;
- return (ARCHIVE_OK);
- }
- break;
- case 'p':
- if (strcmp(key, "pad") == 0) {
- iso9660->opt.pad = value != NULL;
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "publisher") == 0) {
- r = get_str_opt(a,
- &(iso9660->publisher_identifier),
- PUBLISHER_IDENTIFIER_SIZE, key, value);
- iso9660->opt.publisher = r == ARCHIVE_OK;
- return (r);
- }
- break;
- case 'r':
- if (strcmp(key, "rockridge") == 0 ||
- strcmp(key, "Rockridge") == 0) {
- if (value == NULL)
- iso9660->opt.rr = OPT_RR_DISABLED;
- else if (strcmp(value, "1") == 0)
- iso9660->opt.rr = OPT_RR_USEFUL;
- else if (strcmp(value, "strict") == 0)
- iso9660->opt.rr = OPT_RR_STRICT;
- else if (strcmp(value, "useful") == 0)
- iso9660->opt.rr = OPT_RR_USEFUL;
- else
- goto invalid_value;
- return (ARCHIVE_OK);
- }
- break;
- case 'v':
- if (strcmp(key, "volume-id") == 0) {
- r = get_str_opt(a, &(iso9660->volume_identifier),
- VOLUME_IDENTIFIER_SIZE, key, value);
- iso9660->opt.volume_id = r == ARCHIVE_OK;
- return (r);
- }
- break;
- case 'z':
- if (strcmp(key, "zisofs") == 0) {
- if (value == NULL)
- iso9660->opt.zisofs = OPT_ZISOFS_DISABLED;
- else {
-#ifdef HAVE_ZLIB_H
- iso9660->opt.zisofs = OPT_ZISOFS_DIRECT;
-#else
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "``zisofs'' "
- "is not supported on this platform.");
- return (ARCHIVE_FATAL);
-#endif
- }
- return (ARCHIVE_OK);
- }
- break;
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-
-invalid_value:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Invalid value for option ``%s''", key);
- return (ARCHIVE_FAILED);
-}
-
-static int
-iso9660_write_header(struct archive_write *a, struct archive_entry *entry)
-{
- struct iso9660 *iso9660;
- struct isofile *file;
- struct isoent *isoent;
- int r, ret = ARCHIVE_OK;
-
- iso9660 = a->format_data;
-
- iso9660->cur_file = NULL;
- iso9660->bytes_remaining = 0;
- iso9660->need_multi_extent = 0;
- if (archive_entry_filetype(entry) == AE_IFLNK
- && iso9660->opt.rr == OPT_RR_DISABLED) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Ignore symlink file.");
- iso9660->cur_file = NULL;
- return (ARCHIVE_WARN);
- }
- if (archive_entry_filetype(entry) == AE_IFREG &&
- archive_entry_size(entry) >= MULTI_EXTENT_SIZE) {
- if (iso9660->opt.iso_level < 3) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Ignore over %lld bytes file. "
- "This file too large.",
- MULTI_EXTENT_SIZE);
- iso9660->cur_file = NULL;
- return (ARCHIVE_WARN);
- }
- iso9660->need_multi_extent = 1;
- }
-
- file = isofile_new(a, entry);
- if (file == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate data");
- return (ARCHIVE_FATAL);
- }
- r = isofile_gen_utility_names(a, file);
- if (r < ARCHIVE_WARN) {
- isofile_free(file);
- return (r);
- }
- else if (r < ret)
- ret = r;
-
- /*
- * Ignore a path which looks like the top of directory name
- * since we have already made the root directory of an ISO image.
- */
- if (archive_strlen(&(file->parentdir)) == 0 &&
- archive_strlen(&(file->basename)) == 0) {
- isofile_free(file);
- return (r);
- }
-
- isofile_add_entry(iso9660, file);
- isoent = isoent_new(file);
- if (isoent == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate data");
- return (ARCHIVE_FATAL);
- }
- if (isoent->file->dircnt > iso9660->dircnt_max)
- iso9660->dircnt_max = isoent->file->dircnt;
-
- /* Add the current file into tree */
- r = isoent_tree(a, &isoent);
- if (r != ARCHIVE_OK)
- return (r);
-
- /* If there is the same file in tree and
- * the current file is older than the file in tree.
- * So we don't need the current file data anymore. */
- if (isoent->file != file)
- return (ARCHIVE_OK);
-
- /* Non regular files contents are unneeded to be saved to
- * temporary files. */
- if (archive_entry_filetype(file->entry) != AE_IFREG)
- return (ret);
-
- /*
- * Set the current file to cur_file to read its contents.
- */
- iso9660->cur_file = file;
-
- if (archive_entry_nlink(file->entry) > 1) {
- r = isofile_register_hardlink(a, file);
- if (r != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- }
-
- /*
- * Prepare to save the contents of the file.
- */
- if (iso9660->temp_fd < 0) {
- iso9660->temp_fd = __archive_mktemp(NULL);
- if (iso9660->temp_fd < 0) {
- archive_set_error(&a->archive, errno,
- "Couldn't create temporary file");
- return (ARCHIVE_FATAL);
- }
- }
-
- /* Save an offset of current file in temporary file. */
- file->content.offset_of_temp = wb_offset(a);
- file->cur_content = &(file->content);
- r = zisofs_init(a, file);
- if (r < ret)
- ret = r;
- iso9660->bytes_remaining = archive_entry_size(file->entry);
-
- return (ret);
-}
-
-static int
-write_to_temp(struct archive_write *a, const void *buff, size_t s)
-{
- struct iso9660 *iso9660 = a->format_data;
- ssize_t written;
- const unsigned char *b;
-
- b = (const unsigned char *)buff;
- while (s) {
- written = write(iso9660->temp_fd, b, s);
- if (written < 0) {
- archive_set_error(&a->archive, errno,
- "Can't write to temporary file");
- return (ARCHIVE_FATAL);
- }
- s -= written;
- b += written;
- }
- return (ARCHIVE_OK);
-}
-
-static int
-wb_write_to_temp(struct archive_write *a, const void *buff, size_t s)
-{
- const char *xp = buff;
- size_t xs = s;
-
- /*
- * If a written data size is big enough to use system-call
- * and there is no waiting data, this calls write_to_temp() in
- * order to reduce a extra memory copy.
- */
- if (wb_remaining(a) == wb_buffmax() && s > (1024 * 16)) {
- struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
- xs = s % LOGICAL_BLOCK_SIZE;
- iso9660->wbuff_offset += s - xs;
- if (write_to_temp(a, buff, s - xs) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- if (xs == 0)
- return (ARCHIVE_OK);
- xp += s - xs;
- }
-
- while (xs) {
- size_t size = xs;
- if (size > wb_remaining(a))
- size = wb_remaining(a);
- memcpy(wb_buffptr(a), xp, size);
- if (wb_consume(a, size) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- xs -= size;
- xp += size;
- }
- return (ARCHIVE_OK);
-}
-
-static int
-wb_write_padding_to_temp(struct archive_write *a, int64_t csize)
-{
- size_t ns;
- int ret;
-
- ns = (size_t)(csize % LOGICAL_BLOCK_SIZE);
- if (ns != 0)
- ret = write_null(a, LOGICAL_BLOCK_SIZE - ns);
- else
- ret = ARCHIVE_OK;
- return (ret);
-}
-
-static ssize_t
-write_iso9660_data(struct archive_write *a, const void *buff, size_t s)
-{
- struct iso9660 *iso9660 = a->format_data;
- size_t ws;
-
- if (iso9660->temp_fd < 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Couldn't create temporary file");
- return (ARCHIVE_FATAL);
- }
-
- ws = s;
- if (iso9660->need_multi_extent &&
- (iso9660->cur_file->cur_content->size + ws) >=
- (MULTI_EXTENT_SIZE - LOGICAL_BLOCK_SIZE)) {
- struct content *con;
- size_t ts;
-
- ts = (size_t)(MULTI_EXTENT_SIZE - LOGICAL_BLOCK_SIZE -
- iso9660->cur_file->cur_content->size);
-
- if (iso9660->zisofs.detect_magic)
- zisofs_detect_magic(a, buff, ts);
-
- if (iso9660->zisofs.making) {
- if (zisofs_write_to_temp(a, buff, ts) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- } else {
- if (wb_write_to_temp(a, buff, ts) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- iso9660->cur_file->cur_content->size += ts;
- }
-
- /* Write padding. */
- if (wb_write_padding_to_temp(a,
- iso9660->cur_file->cur_content->size) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /* Compute the logical block number. */
- iso9660->cur_file->cur_content->blocks = (int)
- ((iso9660->cur_file->cur_content->size
- + LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS);
-
- /*
- * Make next extent.
- */
- ws -= ts;
- buff = (const void *)(((const unsigned char *)buff) + ts);
- /* Make a content for next extent. */
- con = calloc(1, sizeof(*con));
- if (con == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate content data");
- return (ARCHIVE_FATAL);
- }
- con->offset_of_temp = wb_offset(a);
- iso9660->cur_file->cur_content->next = con;
- iso9660->cur_file->cur_content = con;
-#ifdef HAVE_ZLIB_H
- iso9660->zisofs.block_offset = 0;
-#endif
- }
-
- if (iso9660->zisofs.detect_magic)
- zisofs_detect_magic(a, buff, ws);
-
- if (iso9660->zisofs.making) {
- if (zisofs_write_to_temp(a, buff, ws) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- } else {
- if (wb_write_to_temp(a, buff, ws) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- iso9660->cur_file->cur_content->size += ws;
- }
-
- return (s);
-}
-
-static ssize_t
-iso9660_write_data(struct archive_write *a, const void *buff, size_t s)
-{
- struct iso9660 *iso9660 = a->format_data;
- ssize_t r;
-
- if (iso9660->cur_file == NULL)
- return (0);
- if (archive_entry_filetype(iso9660->cur_file->entry) != AE_IFREG)
- return (0);
- if (s > iso9660->bytes_remaining)
- s = (size_t)iso9660->bytes_remaining;
- if (s == 0)
- return (0);
-
- r = write_iso9660_data(a, buff, s);
- if (r > 0)
- iso9660->bytes_remaining -= r;
- return (r);
-}
-
-static int
-iso9660_finish_entry(struct archive_write *a)
-{
- struct iso9660 *iso9660 = a->format_data;
-
- if (iso9660->cur_file == NULL)
- return (ARCHIVE_OK);
- if (archive_entry_filetype(iso9660->cur_file->entry) != AE_IFREG)
- return (ARCHIVE_OK);
- if (iso9660->cur_file->content.size == 0)
- return (ARCHIVE_OK);
-
- /* If there are unwritten data, write null data instead. */
- while (iso9660->bytes_remaining > 0) {
- size_t s;
-
- s = (iso9660->bytes_remaining > a->null_length)?
- a->null_length: (size_t)iso9660->bytes_remaining;
- if (write_iso9660_data(a, a->nulls, s) < 0)
- return (ARCHIVE_FATAL);
- iso9660->bytes_remaining -= s;
- }
-
- if (iso9660->zisofs.making && zisofs_finish_entry(a) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /* Write padding. */
- if (wb_write_padding_to_temp(a, iso9660->cur_file->cur_content->size)
- != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /* Compute the logical block number. */
- iso9660->cur_file->cur_content->blocks = (int)
- ((iso9660->cur_file->cur_content->size
- + LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS);
-
- /* Add the current file to data file list. */
- isofile_add_data_file(iso9660, iso9660->cur_file);
-
- return (ARCHIVE_OK);
-}
-
-static int
-iso9660_close(struct archive_write *a)
-{
- struct iso9660 *iso9660;
- int ret, blocks;
-
- iso9660 = a->format_data;
-
- /*
- * Write remaining data out to the temporary file.
- */
- if (wb_remaining(a) > 0) {
- ret = wb_write_out(a);
- if (ret < 0)
- return (ret);
- }
-
- /*
- * Preparations...
- */
-#ifdef DEBUG
- if (iso9660->birth_time == 0)
-#endif
- time(&(iso9660->birth_time));
-
- /*
- * Prepare a bootable ISO image.
- */
- if (iso9660->opt.boot) {
- /* Find out the boot file entry. */
- ret = isoent_find_out_boot_file(a, iso9660->primary.rootent);
- if (ret < 0)
- return (ret);
- /* Reconvert the boot file from zisofs'ed form to
- * plain form. */
- ret = zisofs_rewind_boot_file(a);
- if (ret < 0)
- return (ret);
- /* Write remaining data out to the temporary file. */
- if (wb_remaining(a) > 0) {
- ret = wb_write_out(a);
- if (ret < 0)
- return (ret);
- }
- /* Create the boot catalog. */
- ret = isoent_create_boot_catalog(a, iso9660->primary.rootent);
- if (ret < 0)
- return (ret);
- }
-
- /*
- * Prepare joliet extensions.
- */
- if (iso9660->opt.joliet) {
- /* Make a new tree for joliet. */
- ret = isoent_clone_tree(a, &(iso9660->joliet.rootent),
- iso9660->primary.rootent);
- if (ret < 0)
- return (ret);
- /* Make sure we have UTF-16BE converters.
- * if there is no file entry, converters are still
- * uninitialized. */
- if (iso9660->sconv_to_utf16be == NULL) {
- iso9660->sconv_to_utf16be =
- archive_string_conversion_to_charset(
- &(a->archive), "UTF-16BE", 1);
- if (iso9660->sconv_to_utf16be == NULL)
- /* Couldn't allocate memory */
- return (ARCHIVE_FATAL);
- iso9660->sconv_from_utf16be =
- archive_string_conversion_from_charset(
- &(a->archive), "UTF-16BE", 1);
- if (iso9660->sconv_from_utf16be == NULL)
- /* Couldn't allocate memory */
- return (ARCHIVE_FATAL);
- }
- }
-
- /*
- * Make Path Tables.
- */
- ret = isoent_make_path_table(a);
- if (ret < 0)
- return (ret);
-
- /*
- * Calculate a total volume size and setup all locations of
- * contents of an iso9660 image.
- */
- blocks = SYSTEM_AREA_BLOCK
- + PRIMARY_VOLUME_DESCRIPTOR_BLOCK
- + VOLUME_DESCRIPTOR_SET_TERMINATOR_BLOCK
- + NON_ISO_FILE_SYSTEM_INFORMATION_BLOCK;
- if (iso9660->opt.boot)
- blocks += BOOT_RECORD_DESCRIPTOR_BLOCK;
- if (iso9660->opt.joliet)
- blocks += SUPPLEMENTARY_VOLUME_DESCRIPTOR_BLOCK;
- if (iso9660->opt.iso_level == 4)
- blocks += SUPPLEMENTARY_VOLUME_DESCRIPTOR_BLOCK;
-
- /* Setup the locations of Path Table. */
- iso9660->primary.location_type_L_path_table = blocks;
- blocks += iso9660->primary.path_table_block;
- iso9660->primary.location_type_M_path_table = blocks;
- blocks += iso9660->primary.path_table_block;
- if (iso9660->opt.joliet) {
- iso9660->joliet.location_type_L_path_table = blocks;
- blocks += iso9660->joliet.path_table_block;
- iso9660->joliet.location_type_M_path_table = blocks;
- blocks += iso9660->joliet.path_table_block;
- }
-
- /* Setup the locations of directories. */
- isoent_setup_directory_location(iso9660, blocks,
- &(iso9660->primary));
- blocks += iso9660->primary.total_dir_block;
- if (iso9660->opt.joliet) {
- isoent_setup_directory_location(iso9660, blocks,
- &(iso9660->joliet));
- blocks += iso9660->joliet.total_dir_block;
- }
-
- if (iso9660->opt.rr) {
- iso9660->location_rrip_er = blocks;
- blocks += RRIP_ER_BLOCK;
- }
-
- /* Setup the locations of all file contents. */
- isoent_setup_file_location(iso9660, blocks);
- blocks += iso9660->total_file_block;
- if (iso9660->opt.boot && iso9660->opt.boot_info_table) {
- ret = setup_boot_information(a);
- if (ret < 0)
- return (ret);
- }
-
- /* Now we have a total volume size. */
- iso9660->volume_space_size = blocks;
- if (iso9660->opt.pad)
- iso9660->volume_space_size += PADDING_BLOCK;
- iso9660->volume_sequence_number = 1;
-
-
- /*
- * Write an ISO 9660 image.
- */
-
- /* Switch to start using wbuff as file buffer. */
- iso9660->wbuff_remaining = wb_buffmax();
- iso9660->wbuff_type = WB_TO_STREAM;
- iso9660->wbuff_offset = 0;
- iso9660->wbuff_written = 0;
- iso9660->wbuff_tail = 0;
-
- /* Write The System Area */
- ret = write_null(a, SYSTEM_AREA_BLOCK * LOGICAL_BLOCK_SIZE);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /* Write Primary Volume Descriptor */
- ret = write_VD(a, &(iso9660->primary));
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- if (iso9660->opt.boot) {
- /* Write Boot Record Volume Descriptor */
- ret = write_VD_boot_record(a);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- }
-
- if (iso9660->opt.iso_level == 4) {
- /* Write Enhanced Volume Descriptor */
- iso9660->primary.vdd_type = VDD_ENHANCED;
- ret = write_VD(a, &(iso9660->primary));
- iso9660->primary.vdd_type = VDD_PRIMARY;
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- }
-
- if (iso9660->opt.joliet) {
- ret = write_VD(a, &(iso9660->joliet));
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- }
-
- /* Write Volume Descriptor Set Terminator */
- ret = write_VD_terminator(a);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /* Write Non-ISO File System Information */
- ret = write_information_block(a);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /* Write Type L Path Table */
- ret = write_path_table(a, 0, &(iso9660->primary));
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /* Write Type M Path Table */
- ret = write_path_table(a, 1, &(iso9660->primary));
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- if (iso9660->opt.joliet) {
- /* Write Type L Path Table */
- ret = write_path_table(a, 0, &(iso9660->joliet));
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /* Write Type M Path Table */
- ret = write_path_table(a, 1, &(iso9660->joliet));
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- }
-
- /* Write Directory Descriptors */
- ret = write_directory_descriptors(a, &(iso9660->primary));
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- if (iso9660->opt.joliet) {
- ret = write_directory_descriptors(a, &(iso9660->joliet));
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- }
-
- if (iso9660->opt.rr) {
- /* Write Rockridge ER(Extensions Reference) */
- ret = write_rr_ER(a);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- }
-
- /* Write File Descriptors */
- ret = write_file_descriptors(a);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /* Write Padding */
- if (iso9660->opt.pad) {
- ret = write_null(a, PADDING_BLOCK * LOGICAL_BLOCK_SIZE);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- }
-
- if (iso9660->directories_too_deep != NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "%s: Directories too deep.",
- archive_entry_pathname(
- iso9660->directories_too_deep->file->entry));
- return (ARCHIVE_WARN);
- }
-
- /* Write remaining data out. */
- ret = wb_write_out(a);
-
- return (ret);
-}
-
-static int
-iso9660_free(struct archive_write *a)
-{
- struct iso9660 *iso9660;
- int i, ret;
-
- iso9660 = a->format_data;
-
- /* Close the temporary file. */
- if (iso9660->temp_fd >= 0)
- close(iso9660->temp_fd);
-
- /* Free some stuff for zisofs operations. */
- ret = zisofs_free(a);
-
- /* Remove directory entries in tree which includes file entries. */
- isoent_free_all(iso9660->primary.rootent);
- for (i = 0; i < iso9660->primary.max_depth; i++)
- free(iso9660->primary.pathtbl[i].sorted);
- free(iso9660->primary.pathtbl);
-
- if (iso9660->opt.joliet) {
- isoent_free_all(iso9660->joliet.rootent);
- for (i = 0; i < iso9660->joliet.max_depth; i++)
- free(iso9660->joliet.pathtbl[i].sorted);
- free(iso9660->joliet.pathtbl);
- }
-
- /* Remove isofile entries. */
- isofile_free_all_entries(iso9660);
- isofile_free_hardlinks(iso9660);
-
- archive_string_free(&(iso9660->cur_dirstr));
- archive_string_free(&(iso9660->volume_identifier));
- archive_string_free(&(iso9660->publisher_identifier));
- archive_string_free(&(iso9660->data_preparer_identifier));
- archive_string_free(&(iso9660->application_identifier));
- archive_string_free(&(iso9660->copyright_file_identifier));
- archive_string_free(&(iso9660->abstract_file_identifier));
- archive_string_free(&(iso9660->bibliographic_file_identifier));
- archive_string_free(&(iso9660->el_torito.catalog_filename));
- archive_string_free(&(iso9660->el_torito.boot_filename));
- archive_string_free(&(iso9660->el_torito.id));
- archive_string_free(&(iso9660->utf16be));
- archive_string_free(&(iso9660->mbs));
-
- free(iso9660);
- a->format_data = NULL;
-
- return (ret);
-}
-
-/*
- * Get the System Identifier
- */
-static void
-get_system_identitier(char *system_id, size_t size)
-{
-#if defined(HAVE_SYS_UTSNAME_H)
- struct utsname u;
-
- uname(&u);
- strncpy(system_id, u.sysname, size-1);
- system_id[size-1] = '\0';
-#elif defined(_WIN32) && !defined(__CYGWIN__)
- strncpy(system_id, "Windows", size-1);
- system_id[size-1] = '\0';
-#else
- strncpy(system_id, "Unknown", size-1);
- system_id[size-1] = '\0';
-#endif
-}
-
-static void
-set_str(unsigned char *p, const char *s, size_t l, char f, const char *map)
-{
- unsigned char c;
-
- if (s == NULL)
- s = "";
- while ((c = *s++) != 0 && l > 0) {
- if (c >= 0x80 || map[c] == 0)
- {
- /* illegal character */
- if (c >= 'a' && c <= 'z') {
- /* convert c from a-z to A-Z */
- c -= 0x20;
- } else
- c = 0x5f;
- }
- *p++ = c;
- l--;
- }
- /* If l isn't zero, fill p buffer by the character
- * which indicated by f. */
- if (l > 0)
- memset(p , f, l);
-}
-
-static inline int
-joliet_allowed_char(unsigned char high, unsigned char low)
-{
- int utf16 = (high << 8) | low;
-
- if (utf16 <= 0x001F)
- return (0);
-
- switch (utf16) {
- case 0x002A: /* '*' */
- case 0x002F: /* '/' */
- case 0x003A: /* ':' */
- case 0x003B: /* ';' */
- case 0x003F: /* '?' */
- case 0x005C: /* '\' */
- return (0);/* Not allowed. */
- }
- return (1);
-}
-
-static int
-set_str_utf16be(struct archive_write *a, unsigned char *p, const char *s,
- size_t l, uint16_t uf, enum vdc vdc)
-{
- size_t size, i;
- int onepad;
-
- if (s == NULL)
- s = "";
- if (l & 0x01) {
- onepad = 1;
- l &= ~1;
- } else
- onepad = 0;
- if (vdc == VDC_UCS2) {
- struct iso9660 *iso9660 = a->format_data;
- if (archive_strncpy_l(&iso9660->utf16be, s, strlen(s),
- iso9660->sconv_to_utf16be) != 0 && errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for UTF-16BE");
- return (ARCHIVE_FATAL);
- }
- size = iso9660->utf16be.length;
- if (size > l)
- size = l;
- memcpy(p, iso9660->utf16be.s, size);
- } else {
- const uint16_t *u16 = (const uint16_t *)s;
-
- size = 0;
- while (*u16++)
- size += 2;
- if (size > l)
- size = l;
- memcpy(p, s, size);
- }
- for (i = 0; i < size; i += 2, p += 2) {
- if (!joliet_allowed_char(p[0], p[1]))
- archive_be16enc(p, 0x005F);/* '_' */
- }
- l -= size;
- while (l > 0) {
- archive_be16enc(p, uf);
- p += 2;
- l -= 2;
- }
- if (onepad)
- *p = 0;
- return (ARCHIVE_OK);
-}
-
-static const char a_characters_map[0x80] = {
-/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
- 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20-2F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30-3F */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 60-6F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 70-7F */
-};
-
-static const char a1_characters_map[0x80] = {
-/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
- 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20-2F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30-3F */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60-6F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,/* 70-7F */
-};
-
-static const char d_characters_map[0x80] = {
-/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 20-2F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,/* 30-3F */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 60-6F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 70-7F */
-};
-
-static const char d1_characters_map[0x80] = {
-/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 20-2F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,/* 30-3F */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60-6F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,/* 70-7F */
-};
-
-static int
-set_str_a_characters_bp(struct archive_write *a, unsigned char *bp,
- int from, int to, const char *s, enum vdc vdc)
-{
- int r;
-
- switch (vdc) {
- case VDC_STD:
- set_str(bp+from, s, to - from + 1, 0x20,
- a_characters_map);
- r = ARCHIVE_OK;
- break;
- case VDC_LOWERCASE:
- set_str(bp+from, s, to - from + 1, 0x20,
- a1_characters_map);
- r = ARCHIVE_OK;
- break;
- case VDC_UCS2:
- case VDC_UCS2_DIRECT:
- r = set_str_utf16be(a, bp+from, s, to - from + 1,
- 0x0020, vdc);
- break;
- default:
- r = ARCHIVE_FATAL;
- }
- return (r);
-}
-
-static int
-set_str_d_characters_bp(struct archive_write *a, unsigned char *bp,
- int from, int to, const char *s, enum vdc vdc)
-{
- int r;
-
- switch (vdc) {
- case VDC_STD:
- set_str(bp+from, s, to - from + 1, 0x20,
- d_characters_map);
- r = ARCHIVE_OK;
- break;
- case VDC_LOWERCASE:
- set_str(bp+from, s, to - from + 1, 0x20,
- d1_characters_map);
- r = ARCHIVE_OK;
- break;
- case VDC_UCS2:
- case VDC_UCS2_DIRECT:
- r = set_str_utf16be(a, bp+from, s, to - from + 1,
- 0x0020, vdc);
- break;
- default:
- r = ARCHIVE_FATAL;
- }
- return (r);
-}
-
-static void
-set_VD_bp(unsigned char *bp, enum VD_type type, unsigned char ver)
-{
-
- /* Volume Descriptor Type */
- bp[1] = (unsigned char)type;
- /* Standard Identifier */
- memcpy(bp + 2, "CD001", 5);
- /* Volume Descriptor Version */
- bp[7] = ver;
-}
-
-static inline void
-set_unused_field_bp(unsigned char *bp, int from, int to)
-{
- memset(bp + from, 0, to - from + 1);
-}
-
-/*
- * 8-bit unsigned numerical values.
- * ISO9660 Standard 7.1.1
- */
-static inline void
-set_num_711(unsigned char *p, unsigned char value)
-{
- *p = value;
-}
-
-/*
- * 8-bit signed numerical values.
- * ISO9660 Standard 7.1.2
- */
-static inline void
-set_num_712(unsigned char *p, char value)
-{
- *((char *)p) = value;
-}
-
-/*
- * Least significant byte first.
- * ISO9660 Standard 7.2.1
- */
-static inline void
-set_num_721(unsigned char *p, uint16_t value)
-{
- archive_le16enc(p, value);
-}
-
-/*
- * Most significant byte first.
- * ISO9660 Standard 7.2.2
- */
-static inline void
-set_num_722(unsigned char *p, uint16_t value)
-{
- archive_be16enc(p, value);
-}
-
-/*
- * Both-byte orders.
- * ISO9660 Standard 7.2.3
- */
-static void
-set_num_723(unsigned char *p, uint16_t value)
-{
- archive_le16enc(p, value);
- archive_be16enc(p+2, value);
-}
-
-/*
- * Least significant byte first.
- * ISO9660 Standard 7.3.1
- */
-static inline void
-set_num_731(unsigned char *p, uint32_t value)
-{
- archive_le32enc(p, value);
-}
-
-/*
- * Most significant byte first.
- * ISO9660 Standard 7.3.2
- */
-static inline void
-set_num_732(unsigned char *p, uint32_t value)
-{
- archive_be32enc(p, value);
-}
-
-/*
- * Both-byte orders.
- * ISO9660 Standard 7.3.3
- */
-static inline void
-set_num_733(unsigned char *p, uint32_t value)
-{
- archive_le32enc(p, value);
- archive_be32enc(p+4, value);
-}
-
-static void
-set_digit(unsigned char *p, size_t s, int value)
-{
-
- while (s--) {
- p[s] = '0' + (value % 10);
- value /= 10;
- }
-}
-
-#if defined(HAVE_STRUCT_TM_TM_GMTOFF)
-#define get_gmoffset(tm) ((tm)->tm_gmtoff)
-#elif defined(HAVE_STRUCT_TM___TM_GMTOFF)
-#define get_gmoffset(tm) ((tm)->__tm_gmtoff)
-#else
-static long
-get_gmoffset(struct tm *tm)
-{
- long offset;
-
-#if defined(HAVE__GET_TIMEZONE)
- _get_timezone(&offset);
-#elif defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
- offset = _timezone;
-#else
- offset = timezone;
-#endif
- offset *= -1;
- if (tm->tm_isdst)
- offset += 3600;
- return (offset);
-}
-#endif
-
-static void
-get_tmfromtime(struct tm *tm, time_t *t)
-{
-#if HAVE_LOCALTIME_S
- localtime_s(tm, t);
-#elif HAVE_LOCALTIME_R
- tzset();
- localtime_r(t, tm);
-#else
- memcpy(tm, localtime(t), sizeof(*tm));
-#endif
-}
-
-/*
- * Date and Time Format.
- * ISO9660 Standard 8.4.26.1
- */
-static void
-set_date_time(unsigned char *p, time_t t)
-{
- struct tm tm;
-
- get_tmfromtime(&tm, &t);
- set_digit(p, 4, tm.tm_year + 1900);
- set_digit(p+4, 2, tm.tm_mon + 1);
- set_digit(p+6, 2, tm.tm_mday);
- set_digit(p+8, 2, tm.tm_hour);
- set_digit(p+10, 2, tm.tm_min);
- set_digit(p+12, 2, tm.tm_sec);
- set_digit(p+14, 2, 0);
- set_num_712(p+16, (char)(get_gmoffset(&tm)/(60*15)));
-}
-
-static void
-set_date_time_null(unsigned char *p)
-{
- memset(p, (int)'0', 16);
- p[16] = 0;
-}
-
-static void
-set_time_915(unsigned char *p, time_t t)
-{
- struct tm tm;
-
- get_tmfromtime(&tm, &t);
- set_num_711(p+0, tm.tm_year);
- set_num_711(p+1, tm.tm_mon+1);
- set_num_711(p+2, tm.tm_mday);
- set_num_711(p+3, tm.tm_hour);
- set_num_711(p+4, tm.tm_min);
- set_num_711(p+5, tm.tm_sec);
- set_num_712(p+6, (char)(get_gmoffset(&tm)/(60*15)));
-}
-
-
-/*
- * Write SUSP "CE" System Use Entry.
- */
-static int
-set_SUSP_CE(unsigned char *p, int location, int offset, int size)
-{
- unsigned char *bp = p -1;
- /* Extend the System Use Area
- * "CE" Format:
- * len ver
- * +----+----+----+----+-----------+-----------+
- * | 'C'| 'E'| 1C | 01 | LOCATION1 | LOCATION2 |
- * +----+----+----+----+-----------+-----------+
- * 0 1 2 3 4 12 20
- * +-----------+
- * | LOCATION3 |
- * +-----------+
- * 20 28
- * LOCATION1 : Location of Continuation of System Use Area.
- * LOCATION2 : Offset to Start of Continuation.
- * LOCATION3 : Length of the Continuation.
- */
-
- bp[1] = 'C';
- bp[2] = 'E';
- bp[3] = RR_CE_SIZE; /* length */
- bp[4] = 1; /* version */
- set_num_733(bp+5, location);
- set_num_733(bp+13, offset);
- set_num_733(bp+21, size);
- return (RR_CE_SIZE);
-}
-
-/*
- * The functions, which names are beginning with extra_, are used to
- * control extra records.
- * The maximum size of a Directory Record is 254. When a filename is
- * very long, all of RRIP data of a file won't stored to the Directory
- * Record and so remaining RRIP data store to an extra record instead.
- */
-static unsigned char *
-extra_open_record(unsigned char *bp, int dr_len, struct isoent *isoent,
- struct ctl_extr_rec *ctl)
-{
- ctl->bp = bp;
- if (bp != NULL)
- bp += dr_len;
- ctl->use_extr = 0;
- ctl->isoent = isoent;
- ctl->ce_ptr = NULL;
- ctl->cur_len = ctl->dr_len = dr_len;
- ctl->limit = DR_LIMIT;
-
- return (bp);
-}
-
-static void
-extra_close_record(struct ctl_extr_rec *ctl, int ce_size)
-{
- int padding = 0;
-
- if (ce_size > 0)
- extra_tell_used_size(ctl, ce_size);
- /* Padding. */
- if (ctl->cur_len & 0x01) {
- ctl->cur_len++;
- if (ctl->bp != NULL)
- ctl->bp[ctl->cur_len] = 0;
- padding = 1;
- }
- if (ctl->use_extr) {
- if (ctl->ce_ptr != NULL)
- set_SUSP_CE(ctl->ce_ptr, ctl->extr_loc,
- ctl->extr_off, ctl->cur_len - padding);
- } else
- ctl->dr_len = ctl->cur_len;
-}
-
-#define extra_space(ctl) ((ctl)->limit - (ctl)->cur_len)
-
-static unsigned char *
-extra_next_record(struct ctl_extr_rec *ctl, int length)
-{
- int cur_len = ctl->cur_len;/* save cur_len */
-
- /* Close the current extra record or Directory Record. */
- extra_close_record(ctl, RR_CE_SIZE);
-
- /* Get a next extra record. */
- ctl->use_extr = 1;
- if (ctl->bp != NULL) {
- /* Storing data into an extra record. */
- unsigned char *p;
-
- /* Save the pointer where a CE extension will be
- * stored to. */
- ctl->ce_ptr = &ctl->bp[cur_len+1];
- p = extra_get_record(ctl->isoent,
- &ctl->limit, &ctl->extr_off, &ctl->extr_loc);
- ctl->bp = p - 1;/* the base of bp offset is 1. */
- } else
- /* Calculating the size of an extra record. */
- (void)extra_get_record(ctl->isoent,
- &ctl->limit, NULL, NULL);
- ctl->cur_len = 0;
- /* Check if an extra record is almost full.
- * If so, get a next one. */
- if (extra_space(ctl) < length)
- (void)extra_next_record(ctl, length);
-
- return (ctl->bp);
-}
-
-static inline struct extr_rec *
-extra_last_record(struct isoent *isoent)
-{
- if (isoent->extr_rec_list.first == NULL)
- return (NULL);
- return ((struct extr_rec *)(void *)
- ((char *)(isoent->extr_rec_list.last)
- - offsetof(struct extr_rec, next)));
-}
-
-static unsigned char *
-extra_get_record(struct isoent *isoent, int *space, int *off, int *loc)
-{
- struct extr_rec *rec;
-
- isoent = isoent->parent;
- if (off != NULL) {
- /* Storing data into an extra record. */
- rec = isoent->extr_rec_list.current;
- if (DR_SAFETY > LOGICAL_BLOCK_SIZE - rec->offset)
- rec = rec->next;
- } else {
- /* Calculating the size of an extra record. */
- rec = extra_last_record(isoent);
- if (rec == NULL ||
- DR_SAFETY > LOGICAL_BLOCK_SIZE - rec->offset) {
- rec = malloc(sizeof(*rec));
- if (rec == NULL)
- return (NULL);
- rec->location = 0;
- rec->offset = 0;
- /* Insert `rec` into the tail of isoent->extr_rec_list */
- rec->next = NULL;
- /*
- * Note: testing isoent->extr_rec_list.last == NULL
- * here is really unneeded since it has been already
- * initialized at isoent_new function but Clang Static
- * Analyzer claims that it is dereference of null
- * pointer.
- */
- if (isoent->extr_rec_list.last == NULL)
- isoent->extr_rec_list.last =
- &(isoent->extr_rec_list.first);
- *isoent->extr_rec_list.last = rec;
- isoent->extr_rec_list.last = &(rec->next);
- }
- }
- *space = LOGICAL_BLOCK_SIZE - rec->offset - DR_SAFETY;
- if (*space & 0x01)
- *space -= 1;/* Keep padding space. */
- if (off != NULL)
- *off = rec->offset;
- if (loc != NULL)
- *loc = rec->location;
- isoent->extr_rec_list.current = rec;
-
- return (&rec->buf[rec->offset]);
-}
-
-static void
-extra_tell_used_size(struct ctl_extr_rec *ctl, int size)
-{
- struct isoent *isoent;
- struct extr_rec *rec;
-
- if (ctl->use_extr) {
- isoent = ctl->isoent->parent;
- rec = isoent->extr_rec_list.current;
- if (rec != NULL)
- rec->offset += size;
- }
- ctl->cur_len += size;
-}
-
-static int
-extra_setup_location(struct isoent *isoent, int location)
-{
- struct extr_rec *rec;
- int cnt;
-
- cnt = 0;
- rec = isoent->extr_rec_list.first;
- isoent->extr_rec_list.current = rec;
- while (rec) {
- cnt++;
- rec->location = location++;
- rec->offset = 0;
- rec = rec->next;
- }
- return (cnt);
-}
-
-/*
- * Create the RRIP entries.
- */
-static int
-set_directory_record_rr(unsigned char *bp, int dr_len,
- struct isoent *isoent, struct iso9660 *iso9660, enum dir_rec_type t)
-{
- /* Flags(BP 5) of the Rockridge "RR" System Use Field */
- unsigned char rr_flag;
-#define RR_USE_PX 0x01
-#define RR_USE_PN 0x02
-#define RR_USE_SL 0x04
-#define RR_USE_NM 0x08
-#define RR_USE_CL 0x10
-#define RR_USE_PL 0x20
-#define RR_USE_RE 0x40
-#define RR_USE_TF 0x80
- int length;
- struct ctl_extr_rec ctl;
- struct isoent *rr_parent, *pxent;
- struct isofile *file;
-
- bp = extra_open_record(bp, dr_len, isoent, &ctl);
-
- if (t == DIR_REC_PARENT) {
- rr_parent = isoent->rr_parent;
- pxent = isoent->parent;
- if (rr_parent != NULL)
- isoent = rr_parent;
- else
- isoent = isoent->parent;
- } else {
- rr_parent = NULL;
- pxent = isoent;
- }
- file = isoent->file;
-
- if (t != DIR_REC_NORMAL) {
- rr_flag = RR_USE_PX | RR_USE_TF;
- if (rr_parent != NULL)
- rr_flag |= RR_USE_PL;
- } else {
- rr_flag = RR_USE_PX | RR_USE_NM | RR_USE_TF;
- if (archive_entry_filetype(file->entry) == AE_IFLNK)
- rr_flag |= RR_USE_SL;
- if (isoent->rr_parent != NULL)
- rr_flag |= RR_USE_RE;
- if (isoent->rr_child != NULL)
- rr_flag |= RR_USE_CL;
- if (archive_entry_filetype(file->entry) == AE_IFCHR ||
- archive_entry_filetype(file->entry) == AE_IFBLK)
- rr_flag |= RR_USE_PN;
-#ifdef COMPAT_MKISOFS
- /*
- * mkisofs 2.01.01a63 records "RE" extension to
- * the entry of "rr_moved" directory.
- * I don't understand this behavior.
- */
- if (isoent->virtual &&
- isoent->parent == iso9660->primary.rootent &&
- strcmp(isoent->file->basename.s, "rr_moved") == 0)
- rr_flag |= RR_USE_RE;
-#endif
- }
-
- /* Write "SP" System Use Entry. */
- if (t == DIR_REC_SELF && isoent == isoent->parent) {
- length = 7;
- if (bp != NULL) {
- bp[1] = 'S';
- bp[2] = 'P';
- bp[3] = length;
- bp[4] = 1; /* version */
- bp[5] = 0xBE; /* Check Byte */
- bp[6] = 0xEF; /* Check Byte */
- bp[7] = 0;
- bp += length;
- }
- extra_tell_used_size(&ctl, length);
- }
-
- /* Write "RR" System Use Entry. */
- length = 5;
- if (extra_space(&ctl) < length)
- bp = extra_next_record(&ctl, length);
- if (bp != NULL) {
- bp[1] = 'R';
- bp[2] = 'R';
- bp[3] = length;
- bp[4] = 1; /* version */
- bp[5] = rr_flag;
- bp += length;
- }
- extra_tell_used_size(&ctl, length);
-
- /* Write "NM" System Use Entry. */
- if (rr_flag & RR_USE_NM) {
- /*
- * "NM" Format:
- * e.g. a basename is 'foo'
- * len ver flg
- * +----+----+----+----+----+----+----+----+
- * | 'N'| 'M'| 08 | 01 | 00 | 'f'| 'o'| 'o'|
- * +----+----+----+----+----+----+----+----+
- * <----------------- len ----------------->
- */
- size_t nmlen = file->basename.length;
- const char *nm = file->basename.s;
- size_t nmmax;
-
- if (extra_space(&ctl) < 6)
- bp = extra_next_record(&ctl, 6);
- if (bp != NULL) {
- bp[1] = 'N';
- bp[2] = 'M';
- bp[4] = 1; /* version */
- }
- nmmax = extra_space(&ctl);
- if (nmmax > 0xff)
- nmmax = 0xff;
- while (nmlen + 5 > nmmax) {
- length = (int)nmmax;
- if (bp != NULL) {
- bp[3] = length;
- bp[5] = 0x01;/* Alternate Name continues
- * in next "NM" field */
- memcpy(bp+6, nm, length - 5);
- bp += length;
- }
- nmlen -= length - 5;
- nm += length - 5;
- extra_tell_used_size(&ctl, length);
- if (extra_space(&ctl) < 6) {
- bp = extra_next_record(&ctl, 6);
- nmmax = extra_space(&ctl);
- if (nmmax > 0xff)
- nmmax = 0xff;
- }
- if (bp != NULL) {
- bp[1] = 'N';
- bp[2] = 'M';
- bp[4] = 1; /* version */
- }
- }
- length = 5 + (int)nmlen;
- if (bp != NULL) {
- bp[3] = length;
- bp[5] = 0;
- memcpy(bp+6, nm, nmlen);
- bp += length;
- }
- extra_tell_used_size(&ctl, length);
- }
-
- /* Write "PX" System Use Entry. */
- if (rr_flag & RR_USE_PX) {
- /*
- * "PX" Format:
- * len ver
- * +----+----+----+----+-----------+-----------+
- * | 'P'| 'X'| 2C | 01 | FILE MODE | LINKS |
- * +----+----+----+----+-----------+-----------+
- * 0 1 2 3 4 12 20
- * +-----------+-----------+------------------+
- * | USER ID | GROUP ID |FILE SERIAL NUMBER|
- * +-----------+-----------+------------------+
- * 20 28 36 44
- */
- length = 44;
- if (extra_space(&ctl) < length)
- bp = extra_next_record(&ctl, length);
- if (bp != NULL) {
- mode_t mode;
- int64_t uid;
- int64_t gid;
-
- mode = archive_entry_mode(file->entry);
- uid = archive_entry_uid(file->entry);
- gid = archive_entry_gid(file->entry);
- if (iso9660->opt.rr == OPT_RR_USEFUL) {
- /*
- * This action is similar to mkisofs -r option
- * but our rockridge=useful option does not
- * set a zero to uid and gid.
- */
- /* set all read bit ON */
- mode |= 0444;
-#if !defined(_WIN32) && !defined(__CYGWIN__)
- if (mode & 0111)
-#endif
- /* set all exec bit ON */
- mode |= 0111;
- /* clear all write bits. */
- mode &= ~0222;
- /* clear setuid,setgid,sticky bits. */
- mode &= ~07000;
- }
-
- bp[1] = 'P';
- bp[2] = 'X';
- bp[3] = length;
- bp[4] = 1; /* version */
- /* file mode */
- set_num_733(bp+5, mode);
- /* file links (stat.st_nlink) */
- set_num_733(bp+13,
- archive_entry_nlink(file->entry));
- set_num_733(bp+21, (uint32_t)uid);
- set_num_733(bp+29, (uint32_t)gid);
- /* File Serial Number */
- if (pxent->dir)
- set_num_733(bp+37, pxent->dir_location);
- else if (file->hardlink_target != NULL)
- set_num_733(bp+37,
- file->hardlink_target->cur_content->location);
- else
- set_num_733(bp+37,
- file->cur_content->location);
- bp += length;
- }
- extra_tell_used_size(&ctl, length);
- }
-
- /* Write "SL" System Use Entry. */
- if (rr_flag & RR_USE_SL) {
- /*
- * "SL" Format:
- * e.g. a symbolic name is 'foo/bar'
- * len ver flg
- * +----+----+----+----+----+------------+
- * | 'S'| 'L'| 0F | 01 | 00 | components |
- * +----+----+----+----+----+-----+------+
- * 0 1 2 3 4 5 ...|... 15
- * <----------------- len --------+------>
- * components : |
- * cflg clen |
- * +----+----+----+----+----+ |
- * | 00 | 03 | 'f'| 'o'| 'o'| <---+
- * +----+----+----+----+----+ |
- * 5 6 7 8 9 10 |
- * cflg clen |
- * +----+----+----+----+----+ |
- * | 00 | 03 | 'b'| 'a'| 'r'| <---+
- * +----+----+----+----+----+
- * 10 11 12 13 14 15
- *
- * - cflg : flag of component
- * - clen : length of component
- */
- const char *sl;
- char sl_last;
-
- if (extra_space(&ctl) < 7)
- bp = extra_next_record(&ctl, 7);
- sl = file->symlink.s;
- sl_last = '\0';
- if (bp != NULL) {
- bp[1] = 'S';
- bp[2] = 'L';
- bp[4] = 1; /* version */
- }
- for (;;) {
- unsigned char *nc, *cf, *cl, cldmy = 0;
- int sllen, slmax;
-
- slmax = extra_space(&ctl);
- if (slmax > 0xff)
- slmax = 0xff;
- if (bp != NULL)
- nc = &bp[6];
- else
- nc = NULL;
- cf = cl = NULL;
- sllen = 0;
- while (*sl && sllen + 11 < slmax) {
- if (sl_last == '\0' && sl[0] == '/') {
- /*
- * flg len
- * +----+----+
- * | 08 | 00 | ROOT component.
- * +----+----+ ("/")
- *
- * Root component has to appear
- * at the first component only.
- */
- if (nc != NULL) {
- cf = nc++;
- *cf = 0x08; /* ROOT */
- *nc++ = 0;
- }
- sllen += 2;
- sl++;
- sl_last = '/';
- cl = NULL;
- continue;
- }
- if (((sl_last == '\0' || sl_last == '/') &&
- sl[0] == '.' && sl[1] == '.' &&
- (sl[2] == '/' || sl[2] == '\0')) ||
- (sl[0] == '/' &&
- sl[1] == '.' && sl[2] == '.' &&
- (sl[3] == '/' || sl[3] == '\0'))) {
- /*
- * flg len
- * +----+----+
- * | 04 | 00 | PARENT component.
- * +----+----+ ("..")
- */
- if (nc != NULL) {
- cf = nc++;
- *cf = 0x04; /* PARENT */
- *nc++ = 0;
- }
- sllen += 2;
- if (sl[0] == '/')
- sl += 3;/* skip "/.." */
- else
- sl += 2;/* skip ".." */
- sl_last = '.';
- cl = NULL;
- continue;
- }
- if (((sl_last == '\0' || sl_last == '/') &&
- sl[0] == '.' &&
- (sl[1] == '/' || sl[1] == '\0')) ||
- (sl[0] == '/' && sl[1] == '.' &&
- (sl[2] == '/' || sl[2] == '\0'))) {
- /*
- * flg len
- * +----+----+
- * | 02 | 00 | CURRENT component.
- * +----+----+ (".")
- */
- if (nc != NULL) {
- cf = nc++;
- *cf = 0x02; /* CURRENT */
- *nc++ = 0;
- }
- sllen += 2;
- if (sl[0] == '/')
- sl += 2;/* skip "/." */
- else
- sl ++; /* skip "." */
- sl_last = '.';
- cl = NULL;
- continue;
- }
- if (sl[0] == '/' || cl == NULL) {
- if (nc != NULL) {
- cf = nc++;
- *cf = 0;
- cl = nc++;
- *cl = 0;
- } else
- cl = &cldmy;
- sllen += 2;
- if (sl[0] == '/') {
- sl_last = *sl++;
- continue;
- }
- }
- sl_last = *sl++;
- if (nc != NULL) {
- *nc++ = sl_last;
- (*cl) ++;
- }
- sllen++;
- }
- if (*sl) {
- length = 5 + sllen;
- if (bp != NULL) {
- /*
- * Mark flg as CONTINUE component.
- */
- *cf |= 0x01;
- /*
- * len ver flg
- * +----+----+----+----+----+-
- * | 'S'| 'L'| XX | 01 | 01 |
- * +----+----+----+----+----+-
- * ^
- * continues in next "SL"
- */
- bp[3] = length;
- bp[5] = 0x01;/* This Symbolic Link
- * continues in next
- * "SL" field */
- bp += length;
- }
- extra_tell_used_size(&ctl, length);
- if (extra_space(&ctl) < 11)
- bp = extra_next_record(&ctl, 11);
- if (bp != NULL) {
- /* Next 'SL' */
- bp[1] = 'S';
- bp[2] = 'L';
- bp[4] = 1; /* version */
- }
- } else {
- length = 5 + sllen;
- if (bp != NULL) {
- bp[3] = length;
- bp[5] = 0;
- bp += length;
- }
- extra_tell_used_size(&ctl, length);
- break;
- }
- }
- }
-
- /* Write "TF" System Use Entry. */
- if (rr_flag & RR_USE_TF) {
- /*
- * "TF" Format:
- * len ver
- * +----+----+----+----+-----+-------------+
- * | 'T'| 'F'| XX | 01 |FLAGS| TIME STAMPS |
- * +----+----+----+----+-----+-------------+
- * 0 1 2 3 4 5 XX
- * TIME STAMPS : ISO 9660 Standard 9.1.5.
- * If TF_LONG_FORM FLAGS is set,
- * use ISO9660 Standard 8.4.26.1.
- */
-#define TF_CREATION 0x01 /* Creation time recorded */
-#define TF_MODIFY 0x02 /* Modification time recorded */
-#define TF_ACCESS 0x04 /* Last Access time recorded */
-#define TF_ATTRIBUTES 0x08 /* Last Attribute Change time recorded */
-#define TF_BACKUP 0x10 /* Last Backup time recorded */
-#define TF_EXPIRATION 0x20 /* Expiration time recorded */
-#define TF_EFFECTIVE 0x40 /* Effective time recorded */
-#define TF_LONG_FORM 0x80 /* ISO 9660 17-byte time format used */
- unsigned char tf_flags;
-
- length = 5;
- tf_flags = 0;
-#ifndef COMPAT_MKISOFS
- if (archive_entry_birthtime_is_set(file->entry) &&
- archive_entry_birthtime(file->entry) <=
- archive_entry_mtime(file->entry)) {
- length += 7;
- tf_flags |= TF_CREATION;
- }
-#endif
- if (archive_entry_mtime_is_set(file->entry)) {
- length += 7;
- tf_flags |= TF_MODIFY;
- }
- if (archive_entry_atime_is_set(file->entry)) {
- length += 7;
- tf_flags |= TF_ACCESS;
- }
- if (archive_entry_ctime_is_set(file->entry)) {
- length += 7;
- tf_flags |= TF_ATTRIBUTES;
- }
- if (extra_space(&ctl) < length)
- bp = extra_next_record(&ctl, length);
- if (bp != NULL) {
- bp[1] = 'T';
- bp[2] = 'F';
- bp[3] = length;
- bp[4] = 1; /* version */
- bp[5] = tf_flags;
- bp += 5;
- /* Creation time */
- if (tf_flags & TF_CREATION) {
- set_time_915(bp+1,
- archive_entry_birthtime(file->entry));
- bp += 7;
- }
- /* Modification time */
- if (tf_flags & TF_MODIFY) {
- set_time_915(bp+1,
- archive_entry_mtime(file->entry));
- bp += 7;
- }
- /* Last Access time */
- if (tf_flags & TF_ACCESS) {
- set_time_915(bp+1,
- archive_entry_atime(file->entry));
- bp += 7;
- }
- /* Last Attribute Change time */
- if (tf_flags & TF_ATTRIBUTES) {
- set_time_915(bp+1,
- archive_entry_ctime(file->entry));
- bp += 7;
- }
- }
- extra_tell_used_size(&ctl, length);
- }
-
- /* Write "RE" System Use Entry. */
- if (rr_flag & RR_USE_RE) {
- /*
- * "RE" Format:
- * len ver
- * +----+----+----+----+
- * | 'R'| 'E'| 04 | 01 |
- * +----+----+----+----+
- * 0 1 2 3 4
- */
- length = 4;
- if (extra_space(&ctl) < length)
- bp = extra_next_record(&ctl, length);
- if (bp != NULL) {
- bp[1] = 'R';
- bp[2] = 'E';
- bp[3] = length;
- bp[4] = 1; /* version */
- bp += length;
- }
- extra_tell_used_size(&ctl, length);
- }
-
- /* Write "PL" System Use Entry. */
- if (rr_flag & RR_USE_PL) {
- /*
- * "PL" Format:
- * len ver
- * +----+----+----+----+------------+
- * | 'P'| 'L'| 0C | 01 | *LOCATION |
- * +----+----+----+----+------------+
- * 0 1 2 3 4 12
- * *LOCATION: location of parent directory
- */
- length = 12;
- if (extra_space(&ctl) < length)
- bp = extra_next_record(&ctl, length);
- if (bp != NULL) {
- bp[1] = 'P';
- bp[2] = 'L';
- bp[3] = length;
- bp[4] = 1; /* version */
- set_num_733(bp + 5,
- rr_parent->dir_location);
- bp += length;
- }
- extra_tell_used_size(&ctl, length);
- }
-
- /* Write "CL" System Use Entry. */
- if (rr_flag & RR_USE_CL) {
- /*
- * "CL" Format:
- * len ver
- * +----+----+----+----+------------+
- * | 'C'| 'L'| 0C | 01 | *LOCATION |
- * +----+----+----+----+------------+
- * 0 1 2 3 4 12
- * *LOCATION: location of child directory
- */
- length = 12;
- if (extra_space(&ctl) < length)
- bp = extra_next_record(&ctl, length);
- if (bp != NULL) {
- bp[1] = 'C';
- bp[2] = 'L';
- bp[3] = length;
- bp[4] = 1; /* version */
- set_num_733(bp + 5,
- isoent->rr_child->dir_location);
- bp += length;
- }
- extra_tell_used_size(&ctl, length);
- }
-
- /* Write "PN" System Use Entry. */
- if (rr_flag & RR_USE_PN) {
- /*
- * "PN" Format:
- * len ver
- * +----+----+----+----+------------+------------+
- * | 'P'| 'N'| 14 | 01 | dev_t high | dev_t low |
- * +----+----+----+----+------------+------------+
- * 0 1 2 3 4 12 20
- */
- length = 20;
- if (extra_space(&ctl) < length)
- bp = extra_next_record(&ctl, length);
- if (bp != NULL) {
- uint64_t dev;
-
- bp[1] = 'P';
- bp[2] = 'N';
- bp[3] = length;
- bp[4] = 1; /* version */
- dev = (uint64_t)archive_entry_rdev(file->entry);
- set_num_733(bp + 5, (uint32_t)(dev >> 32));
- set_num_733(bp + 13, (uint32_t)(dev & 0xFFFFFFFF));
- bp += length;
- }
- extra_tell_used_size(&ctl, length);
- }
-
- /* Write "ZF" System Use Entry. */
- if (file->zisofs.header_size) {
- /*
- * "ZF" Format:
- * len ver
- * +----+----+----+----+----+----+-------------+
- * | 'Z'| 'F'| 10 | 01 | 'p'| 'z'| Header Size |
- * +----+----+----+----+----+----+-------------+
- * 0 1 2 3 4 5 6 7
- * +--------------------+-------------------+
- * | Log2 of block Size | Uncompressed Size |
- * +--------------------+-------------------+
- * 7 8 16
- */
- length = 16;
- if (extra_space(&ctl) < length)
- bp = extra_next_record(&ctl, length);
- if (bp != NULL) {
- bp[1] = 'Z';
- bp[2] = 'F';
- bp[3] = length;
- bp[4] = 1; /* version */
- bp[5] = 'p';
- bp[6] = 'z';
- bp[7] = file->zisofs.header_size;
- bp[8] = file->zisofs.log2_bs;
- set_num_733(bp + 9, file->zisofs.uncompressed_size);
- bp += length;
- }
- extra_tell_used_size(&ctl, length);
- }
-
- /* Write "CE" System Use Entry. */
- if (t == DIR_REC_SELF && isoent == isoent->parent) {
- length = RR_CE_SIZE;
- if (bp != NULL)
- set_SUSP_CE(bp+1, iso9660->location_rrip_er,
- 0, RRIP_ER_SIZE);
- extra_tell_used_size(&ctl, length);
- }
-
- extra_close_record(&ctl, 0);
-
- return (ctl.dr_len);
-}
-
-/*
- * Write data of a Directory Record or calculate writing bytes itself.
- * If parameter `p' is NULL, calculates the size of writing data, which
- * a Directory Record needs to write, then it saved and return
- * the calculated size.
- * Parameter `n' is a remaining size of buffer. when parameter `p' is
- * not NULL, check whether that `n' is not less than the saved size.
- * if that `n' is small, return zero.
- *
- * This format of the Directory Record is according to
- * ISO9660 Standard 9.1
- */
-static int
-set_directory_record(unsigned char *p, size_t n, struct isoent *isoent,
- struct iso9660 *iso9660, enum dir_rec_type t,
- enum vdd_type vdd_type)
-{
- unsigned char *bp;
- size_t dr_len;
- size_t fi_len;
-
- if (p != NULL) {
- /*
- * Check whether a write buffer size is less than the
- * saved size which is needed to write this Directory
- * Record.
- */
- switch (t) {
- case DIR_REC_VD:
- dr_len = isoent->dr_len.vd; break;
- case DIR_REC_SELF:
- dr_len = isoent->dr_len.self; break;
- case DIR_REC_PARENT:
- dr_len = isoent->dr_len.parent; break;
- case DIR_REC_NORMAL:
- default:
- dr_len = isoent->dr_len.normal; break;
- }
- if (dr_len > n)
- return (0);/* Needs more buffer size. */
- }
-
- if (t == DIR_REC_NORMAL && isoent->identifier != NULL)
- fi_len = isoent->id_len;
- else
- fi_len = 1;
-
- if (p != NULL) {
- struct isoent *xisoent;
- struct isofile *file;
- unsigned char flag;
-
- if (t == DIR_REC_PARENT)
- xisoent = isoent->parent;
- else
- xisoent = isoent;
- file = isoent->file;
- if (file->hardlink_target != NULL)
- file = file->hardlink_target;
- /* Make a file flag. */
- if (xisoent->dir)
- flag = FILE_FLAG_DIRECTORY;
- else {
- if (file->cur_content->next != NULL)
- flag = FILE_FLAG_MULTI_EXTENT;
- else
- flag = 0;
- }
-
- bp = p -1;
- /* Extended Attribute Record Length */
- set_num_711(bp+2, 0);
- /* Location of Extent */
- if (xisoent->dir)
- set_num_733(bp+3, xisoent->dir_location);
- else
- set_num_733(bp+3, file->cur_content->location);
- /* Data Length */
- if (xisoent->dir)
- set_num_733(bp+11,
- xisoent->dir_block * LOGICAL_BLOCK_SIZE);
- else
- set_num_733(bp+11, (uint32_t)file->cur_content->size);
- /* Recording Date and Time */
- /* NOTE:
- * If a file type is symbolic link, you are seeing this
- * field value is different from a value mkisofs makes.
- * libarchive uses lstat to get this one, but it
- * seems mkisofs uses stat to get.
- */
- set_time_915(bp+19,
- archive_entry_mtime(xisoent->file->entry));
- /* File Flags */
- bp[26] = flag;
- /* File Unit Size */
- set_num_711(bp+27, 0);
- /* Interleave Gap Size */
- set_num_711(bp+28, 0);
- /* Volume Sequence Number */
- set_num_723(bp+29, iso9660->volume_sequence_number);
- /* Length of File Identifier */
- set_num_711(bp+33, (unsigned char)fi_len);
- /* File Identifier */
- switch (t) {
- case DIR_REC_VD:
- case DIR_REC_SELF:
- set_num_711(bp+34, 0);
- break;
- case DIR_REC_PARENT:
- set_num_711(bp+34, 1);
- break;
- case DIR_REC_NORMAL:
- if (isoent->identifier != NULL)
- memcpy(bp+34, isoent->identifier, fi_len);
- else
- set_num_711(bp+34, 0);
- break;
- }
- } else
- bp = NULL;
- dr_len = 33 + fi_len;
- /* Padding Field */
- if (dr_len & 0x01) {
- dr_len ++;
- if (p != NULL)
- bp[dr_len] = 0;
- }
-
- /* Volume Descriptor does not record extension. */
- if (t == DIR_REC_VD) {
- if (p != NULL)
- /* Length of Directory Record */
- set_num_711(p, (unsigned char)dr_len);
- else
- isoent->dr_len.vd = (int)dr_len;
- return ((int)dr_len);
- }
-
- /* Rockridge */
- if (iso9660->opt.rr && vdd_type != VDD_JOLIET)
- dr_len = set_directory_record_rr(bp, (int)dr_len,
- isoent, iso9660, t);
-
- if (p != NULL)
- /* Length of Directory Record */
- set_num_711(p, (unsigned char)dr_len);
- else {
- /*
- * Save the size which is needed to write this
- * Directory Record.
- */
- switch (t) {
- case DIR_REC_VD:
- /* This case does not come, but compiler
- * complains that DIR_REC_VD not handled
- * in switch .... */
- break;
- case DIR_REC_SELF:
- isoent->dr_len.self = (int)dr_len; break;
- case DIR_REC_PARENT:
- isoent->dr_len.parent = (int)dr_len; break;
- case DIR_REC_NORMAL:
- isoent->dr_len.normal = (int)dr_len; break;
- }
- }
-
- return ((int)dr_len);
-}
-
-/*
- * Calculate the size of a directory record.
- */
-static inline int
-get_dir_rec_size(struct iso9660 *iso9660, struct isoent *isoent,
- enum dir_rec_type t, enum vdd_type vdd_type)
-{
-
- return (set_directory_record(NULL, SIZE_MAX,
- isoent, iso9660, t, vdd_type));
-}
-
-/*
- * Manage to write ISO-image data with wbuff to reduce calling
- * __archive_write_output() for performance.
- */
-
-
-static inline unsigned char *
-wb_buffptr(struct archive_write *a)
-{
- struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
-
- return (&(iso9660->wbuff[sizeof(iso9660->wbuff)
- - iso9660->wbuff_remaining]));
-}
-
-static int
-wb_write_out(struct archive_write *a)
-{
- struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
- size_t wsize, nw;
- int r;
-
- wsize = sizeof(iso9660->wbuff) - iso9660->wbuff_remaining;
- nw = wsize % LOGICAL_BLOCK_SIZE;
- if (iso9660->wbuff_type == WB_TO_STREAM)
- r = __archive_write_output(a, iso9660->wbuff, wsize - nw);
- else
- r = write_to_temp(a, iso9660->wbuff, wsize - nw);
- /* Increase the offset. */
- iso9660->wbuff_offset += wsize - nw;
- if (iso9660->wbuff_offset > iso9660->wbuff_written)
- iso9660->wbuff_written = iso9660->wbuff_offset;
- iso9660->wbuff_remaining = sizeof(iso9660->wbuff);
- if (nw) {
- iso9660->wbuff_remaining -= nw;
- memmove(iso9660->wbuff, iso9660->wbuff + wsize - nw, nw);
- }
- return (r);
-}
-
-static int
-wb_consume(struct archive_write *a, size_t size)
-{
- struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
-
- if (size > iso9660->wbuff_remaining ||
- iso9660->wbuff_remaining == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Internal Programming error: iso9660:wb_consume()"
- " size=%jd, wbuff_remaining=%jd",
- (intmax_t)size, (intmax_t)iso9660->wbuff_remaining);
- return (ARCHIVE_FATAL);
- }
- iso9660->wbuff_remaining -= size;
- if (iso9660->wbuff_remaining < LOGICAL_BLOCK_SIZE)
- return (wb_write_out(a));
- return (ARCHIVE_OK);
-}
-
-#ifdef HAVE_ZLIB_H
-
-static int
-wb_set_offset(struct archive_write *a, int64_t off)
-{
- struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
- int64_t used, ext_bytes;
-
- if (iso9660->wbuff_type != WB_TO_TEMP) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Internal Programming error: iso9660:wb_set_offset()");
- return (ARCHIVE_FATAL);
- }
-
- used = sizeof(iso9660->wbuff) - iso9660->wbuff_remaining;
- if (iso9660->wbuff_offset + used > iso9660->wbuff_tail)
- iso9660->wbuff_tail = iso9660->wbuff_offset + used;
- if (iso9660->wbuff_offset < iso9660->wbuff_written) {
- if (used > 0 &&
- write_to_temp(a, iso9660->wbuff, (size_t)used) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- iso9660->wbuff_offset = iso9660->wbuff_written;
- lseek(iso9660->temp_fd, iso9660->wbuff_offset, SEEK_SET);
- iso9660->wbuff_remaining = sizeof(iso9660->wbuff);
- used = 0;
- }
- if (off < iso9660->wbuff_offset) {
- /*
- * Write out waiting data.
- */
- if (used > 0) {
- if (wb_write_out(a) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- }
- lseek(iso9660->temp_fd, off, SEEK_SET);
- iso9660->wbuff_offset = off;
- iso9660->wbuff_remaining = sizeof(iso9660->wbuff);
- } else if (off <= iso9660->wbuff_tail) {
- iso9660->wbuff_remaining = (size_t)
- (sizeof(iso9660->wbuff) - (off - iso9660->wbuff_offset));
- } else {
- ext_bytes = off - iso9660->wbuff_tail;
- iso9660->wbuff_remaining = (size_t)(sizeof(iso9660->wbuff)
- - (iso9660->wbuff_tail - iso9660->wbuff_offset));
- while (ext_bytes >= (int64_t)iso9660->wbuff_remaining) {
- if (write_null(a, (size_t)iso9660->wbuff_remaining)
- != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- ext_bytes -= iso9660->wbuff_remaining;
- }
- if (ext_bytes > 0) {
- if (write_null(a, (size_t)ext_bytes) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- }
- }
- return (ARCHIVE_OK);
-}
-
-#endif /* HAVE_ZLIB_H */
-
-static int
-write_null(struct archive_write *a, size_t size)
-{
- size_t remaining;
- unsigned char *p, *old;
- int r;
-
- remaining = wb_remaining(a);
- p = wb_buffptr(a);
- if (size <= remaining) {
- memset(p, 0, size);
- return (wb_consume(a, size));
- }
- memset(p, 0, remaining);
- r = wb_consume(a, remaining);
- if (r != ARCHIVE_OK)
- return (r);
- size -= remaining;
- old = p;
- p = wb_buffptr(a);
- memset(p, 0, old - p);
- remaining = wb_remaining(a);
- while (size) {
- size_t wsize = size;
-
- if (wsize > remaining)
- wsize = remaining;
- r = wb_consume(a, wsize);
- if (r != ARCHIVE_OK)
- return (r);
- size -= wsize;
- }
- return (ARCHIVE_OK);
-}
-
-/*
- * Write Volume Descriptor Set Terminator
- */
-static int
-write_VD_terminator(struct archive_write *a)
-{
- unsigned char *bp;
-
- bp = wb_buffptr(a) -1;
- set_VD_bp(bp, VDT_TERMINATOR, 1);
- set_unused_field_bp(bp, 8, LOGICAL_BLOCK_SIZE);
-
- return (wb_consume(a, LOGICAL_BLOCK_SIZE));
-}
-
-static int
-set_file_identifier(unsigned char *bp, int from, int to, enum vdc vdc,
- struct archive_write *a, struct vdd *vdd, struct archive_string *id,
- const char *label, int leading_under, enum char_type char_type)
-{
- char identifier[256];
- struct isoent *isoent;
- const char *ids;
- size_t len;
- int r;
-
- if (id->length > 0 && leading_under && id->s[0] != '_') {
- if (char_type == A_CHAR)
- r = set_str_a_characters_bp(a, bp, from, to, id->s, vdc);
- else
- r = set_str_d_characters_bp(a, bp, from, to, id->s, vdc);
- } else if (id->length > 0) {
- ids = id->s;
- if (leading_under)
- ids++;
- isoent = isoent_find_entry(vdd->rootent, ids);
- if (isoent == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Not Found %s `%s'.",
- label, ids);
- return (ARCHIVE_FATAL);
- }
- len = isoent->ext_off + isoent->ext_len;
- if (vdd->vdd_type == VDD_JOLIET) {
- if (len > sizeof(identifier)-2)
- len = sizeof(identifier)-2;
- } else {
- if (len > sizeof(identifier)-1)
- len = sizeof(identifier)-1;
- }
- memcpy(identifier, isoent->identifier, len);
- identifier[len] = '\0';
- if (vdd->vdd_type == VDD_JOLIET) {
- identifier[len+1] = 0;
- vdc = VDC_UCS2_DIRECT;
- }
- if (char_type == A_CHAR)
- r = set_str_a_characters_bp(a, bp, from, to,
- identifier, vdc);
- else
- r = set_str_d_characters_bp(a, bp, from, to,
- identifier, vdc);
- } else {
- if (char_type == A_CHAR)
- r = set_str_a_characters_bp(a, bp, from, to, NULL, vdc);
- else
- r = set_str_d_characters_bp(a, bp, from, to, NULL, vdc);
- }
- return (r);
-}
-
-/*
- * Write Primary/Supplementary Volume Descriptor
- */
-static int
-write_VD(struct archive_write *a, struct vdd *vdd)
-{
- struct iso9660 *iso9660;
- unsigned char *bp;
- uint16_t volume_set_size = 1;
- char identifier[256];
- enum VD_type vdt;
- enum vdc vdc;
- unsigned char vd_ver, fst_ver;
- int r;
-
- iso9660 = a->format_data;
- switch (vdd->vdd_type) {
- case VDD_JOLIET:
- vdt = VDT_SUPPLEMENTARY;
- vd_ver = fst_ver = 1;
- vdc = VDC_UCS2;
- break;
- case VDD_ENHANCED:
- vdt = VDT_SUPPLEMENTARY;
- vd_ver = fst_ver = 2;
- vdc = VDC_LOWERCASE;
- break;
- case VDD_PRIMARY:
- default:
- vdt = VDT_PRIMARY;
- vd_ver = fst_ver = 1;
-#ifdef COMPAT_MKISOFS
- vdc = VDC_LOWERCASE;
-#else
- vdc = VDC_STD;
-#endif
- break;
- }
-
- bp = wb_buffptr(a) -1;
- /* Volume Descriptor Type */
- set_VD_bp(bp, vdt, vd_ver);
- /* Unused Field */
- set_unused_field_bp(bp, 8, 8);
- /* System Identifier */
- get_system_identitier(identifier, sizeof(identifier));
- r = set_str_a_characters_bp(a, bp, 9, 40, identifier, vdc);
- if (r != ARCHIVE_OK)
- return (r);
- /* Volume Identifier */
- r = set_str_d_characters_bp(a, bp, 41, 72,
- iso9660->volume_identifier.s, vdc);
- if (r != ARCHIVE_OK)
- return (r);
- /* Unused Field */
- set_unused_field_bp(bp, 73, 80);
- /* Volume Space Size */
- set_num_733(bp+81, iso9660->volume_space_size);
- if (vdd->vdd_type == VDD_JOLIET) {
- /* Escape Sequences */
- bp[89] = 0x25;/* UCS-2 Level 3 */
- bp[90] = 0x2F;
- bp[91] = 0x45;
- memset(bp + 92, 0, 120 - 92 + 1);
- } else {
- /* Unused Field */
- set_unused_field_bp(bp, 89, 120);
- }
- /* Volume Set Size */
- set_num_723(bp+121, volume_set_size);
- /* Volume Sequence Number */
- set_num_723(bp+125, iso9660->volume_sequence_number);
- /* Logical Block Size */
- set_num_723(bp+129, LOGICAL_BLOCK_SIZE);
- /* Path Table Size */
- set_num_733(bp+133, vdd->path_table_size);
- /* Location of Occurrence of Type L Path Table */
- set_num_731(bp+141, vdd->location_type_L_path_table);
- /* Location of Optional Occurrence of Type L Path Table */
- set_num_731(bp+145, 0);
- /* Location of Occurrence of Type M Path Table */
- set_num_732(bp+149, vdd->location_type_M_path_table);
- /* Location of Optional Occurrence of Type M Path Table */
- set_num_732(bp+153, 0);
- /* Directory Record for Root Directory(BP 157 to 190) */
- set_directory_record(bp+157, 190-157+1, vdd->rootent,
- iso9660, DIR_REC_VD, vdd->vdd_type);
- /* Volume Set Identifier */
- r = set_str_d_characters_bp(a, bp, 191, 318, "", vdc);
- if (r != ARCHIVE_OK)
- return (r);
- /* Publisher Identifier */
- r = set_file_identifier(bp, 319, 446, vdc, a, vdd,
- &(iso9660->publisher_identifier),
- "Publisher File", 1, A_CHAR);
- if (r != ARCHIVE_OK)
- return (r);
- /* Data Preparer Identifier */
- r = set_file_identifier(bp, 447, 574, vdc, a, vdd,
- &(iso9660->data_preparer_identifier),
- "Data Preparer File", 1, A_CHAR);
- if (r != ARCHIVE_OK)
- return (r);
- /* Application Identifier */
- r = set_file_identifier(bp, 575, 702, vdc, a, vdd,
- &(iso9660->application_identifier),
- "Application File", 1, A_CHAR);
- if (r != ARCHIVE_OK)
- return (r);
- /* Copyright File Identifier */
- r = set_file_identifier(bp, 703, 739, vdc, a, vdd,
- &(iso9660->copyright_file_identifier),
- "Copyright File", 0, D_CHAR);
- if (r != ARCHIVE_OK)
- return (r);
- /* Abstract File Identifier */
- r = set_file_identifier(bp, 740, 776, vdc, a, vdd,
- &(iso9660->abstract_file_identifier),
- "Abstract File", 0, D_CHAR);
- if (r != ARCHIVE_OK)
- return (r);
- /* Bibliographic File Identifier */
- r = set_file_identifier(bp, 777, 813, vdc, a, vdd,
- &(iso9660->bibliographic_file_identifier),
- "Bibliongraphic File", 0, D_CHAR);
- if (r != ARCHIVE_OK)
- return (r);
- /* Volume Creation Date and Time */
- set_date_time(bp+814, iso9660->birth_time);
- /* Volume Modification Date and Time */
- set_date_time(bp+831, iso9660->birth_time);
- /* Volume Expiration Date and Time(obsolete) */
- set_date_time_null(bp+848);
- /* Volume Effective Date and Time */
- set_date_time(bp+865, iso9660->birth_time);
- /* File Structure Version */
- bp[882] = fst_ver;
- /* Reserved */
- bp[883] = 0;
- /* Application Use */
- memset(bp + 884, 0x20, 1395 - 884 + 1);
- /* Reserved */
- set_unused_field_bp(bp, 1396, LOGICAL_BLOCK_SIZE);
-
- return (wb_consume(a, LOGICAL_BLOCK_SIZE));
-}
-
-/*
- * Write Boot Record Volume Descriptor
- */
-static int
-write_VD_boot_record(struct archive_write *a)
-{
- struct iso9660 *iso9660;
- unsigned char *bp;
-
- iso9660 = a->format_data;
- bp = wb_buffptr(a) -1;
- /* Volume Descriptor Type */
- set_VD_bp(bp, VDT_BOOT_RECORD, 1);
- /* Boot System Identifier */
- memcpy(bp+8, "EL TORITO SPECIFICATION", 23);
- set_unused_field_bp(bp, 8+23, 39);
- /* Unused */
- set_unused_field_bp(bp, 40, 71);
- /* Absolute pointer to first sector of Boot Catalog */
- set_num_731(bp+72,
- iso9660->el_torito.catalog->file->content.location);
- /* Unused */
- set_unused_field_bp(bp, 76, LOGICAL_BLOCK_SIZE);
-
- return (wb_consume(a, LOGICAL_BLOCK_SIZE));
-}
-
-enum keytype {
- KEY_FLG,
- KEY_STR,
- KEY_INT,
- KEY_HEX
-};
-static void
-set_option_info(struct archive_string *info, int *opt, const char *key,
- enum keytype type, ...)
-{
- va_list ap;
- char prefix;
- const char *s;
- int d;
-
- prefix = (*opt==0)? ' ':',';
- va_start(ap, type);
- switch (type) {
- case KEY_FLG:
- d = va_arg(ap, int);
- archive_string_sprintf(info, "%c%s%s",
- prefix, (d == 0)?"!":"", key);
- break;
- case KEY_STR:
- s = va_arg(ap, const char *);
- archive_string_sprintf(info, "%c%s=%s",
- prefix, key, s);
- break;
- case KEY_INT:
- d = va_arg(ap, int);
- archive_string_sprintf(info, "%c%s=%d",
- prefix, key, d);
- break;
- case KEY_HEX:
- d = va_arg(ap, int);
- archive_string_sprintf(info, "%c%s=%x",
- prefix, key, d);
- break;
- }
- va_end(ap);
-
- *opt = 1;
-}
-
-/*
- * Make Non-ISO File System Information
- */
-static int
-write_information_block(struct archive_write *a)
-{
- struct iso9660 *iso9660;
- char buf[128];
- const char *v;
- int opt, r;
- struct archive_string info;
- size_t info_size = LOGICAL_BLOCK_SIZE *
- NON_ISO_FILE_SYSTEM_INFORMATION_BLOCK;
-
- iso9660 = (struct iso9660 *)a->format_data;
- if (info_size > wb_remaining(a)) {
- r = wb_write_out(a);
- if (r != ARCHIVE_OK)
- return (r);
- }
- archive_string_init(&info);
- if (archive_string_ensure(&info, info_size) == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- memset(info.s, 0, info_size);
- opt = 0;
-#if defined(HAVE_CTIME_S)
- ctime_s(buf, sizeof(buf), &(iso9660->birth_time));
-#elif defined(HAVE_CTIME_R)
- ctime_r(&(iso9660->birth_time), buf);
-#else
- strncpy(buf, ctime(&(iso9660->birth_time)), sizeof(buf)-1);
- buf[sizeof(buf)-1] = '\0';
-#endif
- archive_string_sprintf(&info,
- "INFO %s%s", buf, archive_version_string());
- if (iso9660->opt.abstract_file != OPT_ABSTRACT_FILE_DEFAULT)
- set_option_info(&info, &opt, "abstract-file",
- KEY_STR, iso9660->abstract_file_identifier.s);
- if (iso9660->opt.application_id != OPT_APPLICATION_ID_DEFAULT)
- set_option_info(&info, &opt, "application-id",
- KEY_STR, iso9660->application_identifier.s);
- if (iso9660->opt.allow_vernum != OPT_ALLOW_VERNUM_DEFAULT)
- set_option_info(&info, &opt, "allow-vernum",
- KEY_FLG, iso9660->opt.allow_vernum);
- if (iso9660->opt.biblio_file != OPT_BIBLIO_FILE_DEFAULT)
- set_option_info(&info, &opt, "biblio-file",
- KEY_STR, iso9660->bibliographic_file_identifier.s);
- if (iso9660->opt.boot != OPT_BOOT_DEFAULT)
- set_option_info(&info, &opt, "boot",
- KEY_STR, iso9660->el_torito.boot_filename.s);
- if (iso9660->opt.boot_catalog != OPT_BOOT_CATALOG_DEFAULT)
- set_option_info(&info, &opt, "boot-catalog",
- KEY_STR, iso9660->el_torito.catalog_filename.s);
- if (iso9660->opt.boot_info_table != OPT_BOOT_INFO_TABLE_DEFAULT)
- set_option_info(&info, &opt, "boot-info-table",
- KEY_FLG, iso9660->opt.boot_info_table);
- if (iso9660->opt.boot_load_seg != OPT_BOOT_LOAD_SEG_DEFAULT)
- set_option_info(&info, &opt, "boot-load-seg",
- KEY_HEX, iso9660->el_torito.boot_load_seg);
- if (iso9660->opt.boot_load_size != OPT_BOOT_LOAD_SIZE_DEFAULT)
- set_option_info(&info, &opt, "boot-load-size",
- KEY_INT, iso9660->el_torito.boot_load_size);
- if (iso9660->opt.boot_type != OPT_BOOT_TYPE_DEFAULT) {
- v = "no-emulation";
- if (iso9660->opt.boot_type == OPT_BOOT_TYPE_FD)
- v = "fd";
- if (iso9660->opt.boot_type == OPT_BOOT_TYPE_HARD_DISK)
- v = "hard-disk";
- set_option_info(&info, &opt, "boot-type",
- KEY_STR, v);
- }
-#ifdef HAVE_ZLIB_H
- if (iso9660->opt.compression_level != OPT_COMPRESSION_LEVEL_DEFAULT)
- set_option_info(&info, &opt, "compression-level",
- KEY_INT, iso9660->zisofs.compression_level);
-#endif
- if (iso9660->opt.copyright_file != OPT_COPYRIGHT_FILE_DEFAULT)
- set_option_info(&info, &opt, "copyright-file",
- KEY_STR, iso9660->copyright_file_identifier.s);
- if (iso9660->opt.iso_level != OPT_ISO_LEVEL_DEFAULT)
- set_option_info(&info, &opt, "iso-level",
- KEY_INT, iso9660->opt.iso_level);
- if (iso9660->opt.joliet != OPT_JOLIET_DEFAULT) {
- if (iso9660->opt.joliet == OPT_JOLIET_LONGNAME)
- set_option_info(&info, &opt, "joliet",
- KEY_STR, "long");
- else
- set_option_info(&info, &opt, "joliet",
- KEY_FLG, iso9660->opt.joliet);
- }
- if (iso9660->opt.limit_depth != OPT_LIMIT_DEPTH_DEFAULT)
- set_option_info(&info, &opt, "limit-depth",
- KEY_FLG, iso9660->opt.limit_depth);
- if (iso9660->opt.limit_dirs != OPT_LIMIT_DIRS_DEFAULT)
- set_option_info(&info, &opt, "limit-dirs",
- KEY_FLG, iso9660->opt.limit_dirs);
- if (iso9660->opt.pad != OPT_PAD_DEFAULT)
- set_option_info(&info, &opt, "pad",
- KEY_FLG, iso9660->opt.pad);
- if (iso9660->opt.publisher != OPT_PUBLISHER_DEFAULT)
- set_option_info(&info, &opt, "publisher",
- KEY_STR, iso9660->publisher_identifier.s);
- if (iso9660->opt.rr != OPT_RR_DEFAULT) {
- if (iso9660->opt.rr == OPT_RR_DISABLED)
- set_option_info(&info, &opt, "rockridge",
- KEY_FLG, iso9660->opt.rr);
- else if (iso9660->opt.rr == OPT_RR_STRICT)
- set_option_info(&info, &opt, "rockridge",
- KEY_STR, "strict");
- else if (iso9660->opt.rr == OPT_RR_USEFUL)
- set_option_info(&info, &opt, "rockridge",
- KEY_STR, "useful");
- }
- if (iso9660->opt.volume_id != OPT_VOLUME_ID_DEFAULT)
- set_option_info(&info, &opt, "volume-id",
- KEY_STR, iso9660->volume_identifier.s);
- if (iso9660->opt.zisofs != OPT_ZISOFS_DEFAULT)
- set_option_info(&info, &opt, "zisofs",
- KEY_FLG, iso9660->opt.zisofs);
-
- memcpy(wb_buffptr(a), info.s, info_size);
- archive_string_free(&info);
- return (wb_consume(a, info_size));
-}
-
-static int
-write_rr_ER(struct archive_write *a)
-{
- unsigned char *p;
-
- p = wb_buffptr(a);
-
- memset(p, 0, LOGICAL_BLOCK_SIZE);
- p[0] = 'E';
- p[1] = 'R';
- p[3] = 0x01;
- p[2] = RRIP_ER_SIZE;
- p[4] = RRIP_ER_ID_SIZE;
- p[5] = RRIP_ER_DSC_SIZE;
- p[6] = RRIP_ER_SRC_SIZE;
- p[7] = 0x01;
- memcpy(&p[8], rrip_identifier, p[4]);
- memcpy(&p[8+p[4]], rrip_descriptor, p[5]);
- memcpy(&p[8+p[4]+p[5]], rrip_source, p[6]);
-
- return (wb_consume(a, LOGICAL_BLOCK_SIZE));
-}
-
-static void
-calculate_path_table_size(struct vdd *vdd)
-{
- int depth, size;
- struct path_table *pt;
-
- pt = vdd->pathtbl;
- size = 0;
- for (depth = 0; depth < vdd->max_depth; depth++) {
- struct isoent **ptbl;
- int i, cnt;
-
- if ((cnt = pt[depth].cnt) == 0)
- break;
-
- ptbl = pt[depth].sorted;
- for (i = 0; i < cnt; i++) {
- int len;
-
- if (ptbl[i]->identifier == NULL)
- len = 1; /* root directory */
- else
- len = ptbl[i]->id_len;
- if (len & 0x01)
- len++; /* Padding Field */
- size += 8 + len;
- }
- }
- vdd->path_table_size = size;
- vdd->path_table_block =
- ((size + PATH_TABLE_BLOCK_SIZE -1) /
- PATH_TABLE_BLOCK_SIZE) *
- (PATH_TABLE_BLOCK_SIZE / LOGICAL_BLOCK_SIZE);
-}
-
-static int
-_write_path_table(struct archive_write *a, int type_m, int depth,
- struct vdd *vdd)
-{
- unsigned char *bp, *wb;
- struct isoent **ptbl;
- size_t wbremaining;
- int i, r, wsize;
-
- if (vdd->pathtbl[depth].cnt == 0)
- return (0);
-
- wsize = 0;
- wb = wb_buffptr(a);
- wbremaining = wb_remaining(a);
- bp = wb - 1;
- ptbl = vdd->pathtbl[depth].sorted;
- for (i = 0; i < vdd->pathtbl[depth].cnt; i++) {
- struct isoent *np;
- size_t len;
-
- np = ptbl[i];
- if (np->identifier == NULL)
- len = 1; /* root directory */
- else
- len = np->id_len;
- if (wbremaining - ((bp+1) - wb) < (len + 1 + 8)) {
- r = wb_consume(a, (bp+1) - wb);
- if (r < 0)
- return (r);
- wb = wb_buffptr(a);
- wbremaining = wb_remaining(a);
- bp = wb -1;
- }
- /* Length of Directory Identifier */
- set_num_711(bp+1, (unsigned char)len);
- /* Extended Attribute Record Length */
- set_num_711(bp+2, 0);
- /* Location of Extent */
- if (type_m)
- set_num_732(bp+3, np->dir_location);
- else
- set_num_731(bp+3, np->dir_location);
- /* Parent Directory Number */
- if (type_m)
- set_num_722(bp+7, np->parent->dir_number);
- else
- set_num_721(bp+7, np->parent->dir_number);
- /* Directory Identifier */
- if (np->identifier == NULL)
- bp[9] = 0;
- else
- memcpy(&bp[9], np->identifier, len);
- if (len & 0x01) {
- /* Padding Field */
- bp[9+len] = 0;
- len++;
- }
- wsize += 8 + (int)len;
- bp += 8 + len;
- }
- if ((bp + 1) > wb) {
- r = wb_consume(a, (bp+1)-wb);
- if (r < 0)
- return (r);
- }
- return (wsize);
-}
-
-static int
-write_path_table(struct archive_write *a, int type_m, struct vdd *vdd)
-{
- int depth, r;
- size_t path_table_size;
-
- r = ARCHIVE_OK;
- path_table_size = 0;
- for (depth = 0; depth < vdd->max_depth; depth++) {
- r = _write_path_table(a, type_m, depth, vdd);
- if (r < 0)
- return (r);
- path_table_size += r;
- }
-
- /* Write padding data. */
- path_table_size = path_table_size % PATH_TABLE_BLOCK_SIZE;
- if (path_table_size > 0)
- r = write_null(a, PATH_TABLE_BLOCK_SIZE - path_table_size);
- return (r);
-}
-
-static int
-calculate_directory_descriptors(struct iso9660 *iso9660, struct vdd *vdd,
- struct isoent *isoent, int depth)
-{
- struct isoent **enttbl;
- int bs, block, i;
-
- block = 1;
- bs = get_dir_rec_size(iso9660, isoent, DIR_REC_SELF, vdd->vdd_type);
- bs += get_dir_rec_size(iso9660, isoent, DIR_REC_PARENT, vdd->vdd_type);
-
- if (isoent->children.cnt <= 0 || (vdd->vdd_type != VDD_JOLIET &&
- !iso9660->opt.rr && depth + 1 >= vdd->max_depth))
- return (block);
-
- enttbl = isoent->children_sorted;
- for (i = 0; i < isoent->children.cnt; i++) {
- struct isoent *np = enttbl[i];
- struct isofile *file;
-
- file = np->file;
- if (file->hardlink_target != NULL)
- file = file->hardlink_target;
- file->cur_content = &(file->content);
- do {
- int dr_l;
-
- dr_l = get_dir_rec_size(iso9660, np, DIR_REC_NORMAL,
- vdd->vdd_type);
- if ((bs + dr_l) > LOGICAL_BLOCK_SIZE) {
- block ++;
- bs = dr_l;
- } else
- bs += dr_l;
- file->cur_content = file->cur_content->next;
- } while (file->cur_content != NULL);
- }
- return (block);
-}
-
-static int
-_write_directory_descriptors(struct archive_write *a, struct vdd *vdd,
- struct isoent *isoent, int depth)
-{
- struct iso9660 *iso9660 = a->format_data;
- struct isoent **enttbl;
- unsigned char *p, *wb;
- int i, r;
- int dr_l;
-
- p = wb = wb_buffptr(a);
-#define WD_REMAINING (LOGICAL_BLOCK_SIZE - (p - wb))
- p += set_directory_record(p, WD_REMAINING, isoent,
- iso9660, DIR_REC_SELF, vdd->vdd_type);
- p += set_directory_record(p, WD_REMAINING, isoent,
- iso9660, DIR_REC_PARENT, vdd->vdd_type);
-
- if (isoent->children.cnt <= 0 || (vdd->vdd_type != VDD_JOLIET &&
- !iso9660->opt.rr && depth + 1 >= vdd->max_depth)) {
- memset(p, 0, WD_REMAINING);
- return (wb_consume(a, LOGICAL_BLOCK_SIZE));
- }
-
- enttbl = isoent->children_sorted;
- for (i = 0; i < isoent->children.cnt; i++) {
- struct isoent *np = enttbl[i];
- struct isofile *file = np->file;
-
- if (file->hardlink_target != NULL)
- file = file->hardlink_target;
- file->cur_content = &(file->content);
- do {
- dr_l = set_directory_record(p, WD_REMAINING,
- np, iso9660, DIR_REC_NORMAL,
- vdd->vdd_type);
- if (dr_l == 0) {
- memset(p, 0, WD_REMAINING);
- r = wb_consume(a, LOGICAL_BLOCK_SIZE);
- if (r < 0)
- return (r);
- p = wb = wb_buffptr(a);
- dr_l = set_directory_record(p,
- WD_REMAINING, np, iso9660,
- DIR_REC_NORMAL, vdd->vdd_type);
- }
- p += dr_l;
- file->cur_content = file->cur_content->next;
- } while (file->cur_content != NULL);
- }
- memset(p, 0, WD_REMAINING);
- return (wb_consume(a, LOGICAL_BLOCK_SIZE));
-}
-
-static int
-write_directory_descriptors(struct archive_write *a, struct vdd *vdd)
-{
- struct isoent *np;
- int depth, r;
-
- depth = 0;
- np = vdd->rootent;
- do {
- struct extr_rec *extr;
-
- r = _write_directory_descriptors(a, vdd, np, depth);
- if (r < 0)
- return (r);
- if (vdd->vdd_type != VDD_JOLIET) {
- /*
- * This extract record is used by SUSP,RRIP.
- * Not for joliet.
- */
- for (extr = np->extr_rec_list.first;
- extr != NULL;
- extr = extr->next) {
- unsigned char *wb;
-
- wb = wb_buffptr(a);
- memcpy(wb, extr->buf, extr->offset);
- memset(wb + extr->offset, 0,
- LOGICAL_BLOCK_SIZE - extr->offset);
- r = wb_consume(a, LOGICAL_BLOCK_SIZE);
- if (r < 0)
- return (r);
- }
- }
-
- if (np->subdirs.first != NULL && depth + 1 < vdd->max_depth) {
- /* Enter to sub directories. */
- np = np->subdirs.first;
- depth++;
- continue;
- }
- while (np != np->parent) {
- if (np->drnext == NULL) {
- /* Return to the parent directory. */
- np = np->parent;
- depth--;
- } else {
- np = np->drnext;
- break;
- }
- }
- } while (np != np->parent);
-
- return (ARCHIVE_OK);
-}
-
-/*
- * Read file contents from the temporary file, and write it.
- */
-static int
-write_file_contents(struct archive_write *a, int64_t offset, int64_t size)
-{
- struct iso9660 *iso9660 = a->format_data;
- int r;
-
- lseek(iso9660->temp_fd, offset, SEEK_SET);
-
- while (size) {
- size_t rsize;
- ssize_t rs;
- unsigned char *wb;
-
- wb = wb_buffptr(a);
- rsize = wb_remaining(a);
- if (rsize > (size_t)size)
- rsize = (size_t)size;
- rs = read(iso9660->temp_fd, wb, rsize);
- if (rs <= 0) {
- archive_set_error(&a->archive, errno,
- "Can't read temporary file(%jd)", (intmax_t)rs);
- return (ARCHIVE_FATAL);
- }
- size -= rs;
- r = wb_consume(a, rs);
- if (r < 0)
- return (r);
- }
- return (ARCHIVE_OK);
-}
-
-static int
-write_file_descriptors(struct archive_write *a)
-{
- struct iso9660 *iso9660 = a->format_data;
- struct isofile *file;
- int64_t blocks, offset;
- int r;
-
- blocks = 0;
- offset = 0;
-
- /* Make the boot catalog contents, and write it. */
- if (iso9660->el_torito.catalog != NULL) {
- r = make_boot_catalog(a);
- if (r < 0)
- return (r);
- }
-
- /* Write the boot file contents. */
- if (iso9660->el_torito.boot != NULL) {
- file = iso9660->el_torito.boot->file;
- blocks = file->content.blocks;
- offset = file->content.offset_of_temp;
- if (offset != 0) {
- r = write_file_contents(a, offset,
- blocks << LOGICAL_BLOCK_BITS);
- if (r < 0)
- return (r);
- blocks = 0;
- offset = 0;
- }
- }
-
- /* Write out all file contents. */
- for (file = iso9660->data_file_list.first;
- file != NULL; file = file->datanext) {
-
- if (!file->write_content)
- continue;
-
- if ((offset + (blocks << LOGICAL_BLOCK_BITS)) <
- file->content.offset_of_temp) {
- if (blocks > 0) {
- r = write_file_contents(a, offset,
- blocks << LOGICAL_BLOCK_BITS);
- if (r < 0)
- return (r);
- }
- blocks = 0;
- offset = file->content.offset_of_temp;
- }
-
- file->cur_content = &(file->content);
- do {
- blocks += file->cur_content->blocks;
- /* Next fragment */
- file->cur_content = file->cur_content->next;
- } while (file->cur_content != NULL);
- }
-
- /* Flush out remaining blocks. */
- if (blocks > 0) {
- r = write_file_contents(a, offset,
- blocks << LOGICAL_BLOCK_BITS);
- if (r < 0)
- return (r);
- }
-
- return (ARCHIVE_OK);
-}
-
-static void
-isofile_init_entry_list(struct iso9660 *iso9660)
-{
- iso9660->all_file_list.first = NULL;
- iso9660->all_file_list.last = &(iso9660->all_file_list.first);
-}
-
-static void
-isofile_add_entry(struct iso9660 *iso9660, struct isofile *file)
-{
- file->allnext = NULL;
- *iso9660->all_file_list.last = file;
- iso9660->all_file_list.last = &(file->allnext);
-}
-
-static void
-isofile_free_all_entries(struct iso9660 *iso9660)
-{
- struct isofile *file, *file_next;
-
- file = iso9660->all_file_list.first;
- while (file != NULL) {
- file_next = file->allnext;
- isofile_free(file);
- file = file_next;
- }
-}
-
-static void
-isofile_init_entry_data_file_list(struct iso9660 *iso9660)
-{
- iso9660->data_file_list.first = NULL;
- iso9660->data_file_list.last = &(iso9660->data_file_list.first);
-}
-
-static void
-isofile_add_data_file(struct iso9660 *iso9660, struct isofile *file)
-{
- file->datanext = NULL;
- *iso9660->data_file_list.last = file;
- iso9660->data_file_list.last = &(file->datanext);
-}
-
-
-static struct isofile *
-isofile_new(struct archive_write *a, struct archive_entry *entry)
-{
- struct isofile *file;
-
- file = calloc(1, sizeof(*file));
- if (file == NULL)
- return (NULL);
-
- if (entry != NULL)
- file->entry = archive_entry_clone(entry);
- else
- file->entry = archive_entry_new2(&a->archive);
- if (file->entry == NULL) {
- free(file);
- return (NULL);
- }
- archive_string_init(&(file->parentdir));
- archive_string_init(&(file->basename));
- archive_string_init(&(file->basename_utf16));
- archive_string_init(&(file->symlink));
- file->cur_content = &(file->content);
-
- return (file);
-}
-
-static void
-isofile_free(struct isofile *file)
-{
- struct content *con, *tmp;
-
- con = file->content.next;
- while (con != NULL) {
- tmp = con;
- con = con->next;
- free(tmp);
- }
- archive_entry_free(file->entry);
- archive_string_free(&(file->parentdir));
- archive_string_free(&(file->basename));
- archive_string_free(&(file->basename_utf16));
- archive_string_free(&(file->symlink));
- free(file);
-}
-
-#if defined(_WIN32) || defined(__CYGWIN__)
-static int
-cleanup_backslash_1(char *p)
-{
- int mb, dos;
-
- mb = dos = 0;
- while (*p) {
- if (*(unsigned char *)p > 127)
- mb = 1;
- if (*p == '\\') {
- /* If we have not met any multi-byte characters,
- * we can replace '\' with '/'. */
- if (!mb)
- *p = '/';
- dos = 1;
- }
- p++;
- }
- if (!mb || !dos)
- return (0);
- return (-1);
-}
-
-static void
-cleanup_backslash_2(wchar_t *p)
-{
-
- /* Convert a path-separator from '\' to '/' */
- while (*p != L'\0') {
- if (*p == L'\\')
- *p = L'/';
- p++;
- }
-}
-#endif
-
-/*
- * Generate a parent directory name and a base name from a pathname.
- */
-static int
-isofile_gen_utility_names(struct archive_write *a, struct isofile *file)
-{
- struct iso9660 *iso9660;
- const char *pathname;
- char *p, *dirname, *slash;
- size_t len;
- int ret = ARCHIVE_OK;
-
- iso9660 = a->format_data;
-
- archive_string_empty(&(file->parentdir));
- archive_string_empty(&(file->basename));
- archive_string_empty(&(file->basename_utf16));
- archive_string_empty(&(file->symlink));
-
- pathname = archive_entry_pathname(file->entry);
- if (pathname == NULL || pathname[0] == '\0') {/* virtual root */
- file->dircnt = 0;
- return (ret);
- }
-
- /*
- * Make a UTF-16BE basename if Joliet extension enabled.
- */
- if (iso9660->opt.joliet) {
- const char *u16, *ulast;
- size_t u16len, ulen_last;
-
- if (iso9660->sconv_to_utf16be == NULL) {
- iso9660->sconv_to_utf16be =
- archive_string_conversion_to_charset(
- &(a->archive), "UTF-16BE", 1);
- if (iso9660->sconv_to_utf16be == NULL)
- /* Couldn't allocate memory */
- return (ARCHIVE_FATAL);
- iso9660->sconv_from_utf16be =
- archive_string_conversion_from_charset(
- &(a->archive), "UTF-16BE", 1);
- if (iso9660->sconv_from_utf16be == NULL)
- /* Couldn't allocate memory */
- return (ARCHIVE_FATAL);
- }
-
- /*
- * Convert a filename to UTF-16BE.
- */
- if (0 > archive_entry_pathname_l(file->entry, &u16, &u16len,
- iso9660->sconv_to_utf16be)) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for UTF-16BE");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "A filename cannot be converted to UTF-16BE;"
- "You should disable making Joliet extension");
- ret = ARCHIVE_WARN;
- }
-
- /*
- * Make sure a path separator is not in the last;
- * Remove trailing '/'.
- */
- while (u16len >= 2) {
-#if defined(_WIN32) || defined(__CYGWIN__)
- if (u16[u16len-2] == 0 &&
- (u16[u16len-1] == '/' || u16[u16len-1] == '\\'))
-#else
- if (u16[u16len-2] == 0 && u16[u16len-1] == '/')
-#endif
- {
- u16len -= 2;
- } else
- break;
- }
-
- /*
- * Find a basename in UTF-16BE.
- */
- ulast = u16;
- u16len >>= 1;
- ulen_last = u16len;
- while (u16len > 0) {
-#if defined(_WIN32) || defined(__CYGWIN__)
- if (u16[0] == 0 && (u16[1] == '/' || u16[1] == '\\'))
-#else
- if (u16[0] == 0 && u16[1] == '/')
-#endif
- {
- ulast = u16 + 2;
- ulen_last = u16len -1;
- }
- u16 += 2;
- u16len --;
- }
- ulen_last <<= 1;
- if (archive_string_ensure(&(file->basename_utf16),
- ulen_last) == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for UTF-16BE");
- return (ARCHIVE_FATAL);
- }
-
- /*
- * Set UTF-16BE basename.
- */
- memcpy(file->basename_utf16.s, ulast, ulen_last);
- file->basename_utf16.length = ulen_last;
- }
-
- archive_strcpy(&(file->parentdir), pathname);
-#if defined(_WIN32) || defined(__CYGWIN__)
- /*
- * Convert a path-separator from '\' to '/'
- */
- if (cleanup_backslash_1(file->parentdir.s) != 0) {
- const wchar_t *wp = archive_entry_pathname_w(file->entry);
- struct archive_wstring ws;
-
- if (wp != NULL) {
- int r;
- archive_string_init(&ws);
- archive_wstrcpy(&ws, wp);
- cleanup_backslash_2(ws.s);
- archive_string_empty(&(file->parentdir));
- r = archive_string_append_from_wcs(&(file->parentdir),
- ws.s, ws.length);
- archive_wstring_free(&ws);
- if (r < 0 && errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- }
- }
-#endif
-
- len = file->parentdir.length;
- p = dirname = file->parentdir.s;
-
- /*
- * Remove leading '/', '../' and './' elements
- */
- while (*p) {
- if (p[0] == '/') {
- p++;
- len--;
- } else if (p[0] != '.')
- break;
- else if (p[1] == '.' && p[2] == '/') {
- p += 3;
- len -= 3;
- } else if (p[1] == '/' || (p[1] == '.' && p[2] == '\0')) {
- p += 2;
- len -= 2;
- } else if (p[1] == '\0') {
- p++;
- len--;
- } else
- break;
- }
- if (p != dirname) {
- memmove(dirname, p, len+1);
- p = dirname;
- }
- /*
- * Remove "/","/." and "/.." elements from tail.
- */
- while (len > 0) {
- size_t ll = len;
-
- if (len > 0 && p[len-1] == '/') {
- p[len-1] = '\0';
- len--;
- }
- if (len > 1 && p[len-2] == '/' && p[len-1] == '.') {
- p[len-2] = '\0';
- len -= 2;
- }
- if (len > 2 && p[len-3] == '/' && p[len-2] == '.' &&
- p[len-1] == '.') {
- p[len-3] = '\0';
- len -= 3;
- }
- if (ll == len)
- break;
- }
- while (*p) {
- if (p[0] == '/') {
- if (p[1] == '/')
- /* Convert '//' --> '/' */
- memmove(p, p+1, strlen(p+1) + 1);
- else if (p[1] == '.' && p[2] == '/')
- /* Convert '/./' --> '/' */
- memmove(p, p+2, strlen(p+2) + 1);
- else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
- /* Convert 'dir/dir1/../dir2/'
- * --> 'dir/dir2/'
- */
- char *rp = p -1;
- while (rp >= dirname) {
- if (*rp == '/')
- break;
- --rp;
- }
- if (rp > dirname) {
- strcpy(rp, p+3);
- p = rp;
- } else {
- strcpy(dirname, p+4);
- p = dirname;
- }
- } else
- p++;
- } else
- p++;
- }
- p = dirname;
- len = strlen(p);
-
- if (archive_entry_filetype(file->entry) == AE_IFLNK) {
- /* Convert symlink name too. */
- pathname = archive_entry_symlink(file->entry);
- archive_strcpy(&(file->symlink), pathname);
-#if defined(_WIN32) || defined(__CYGWIN__)
- /*
- * Convert a path-separator from '\' to '/'
- */
- if (archive_strlen(&(file->symlink)) > 0 &&
- cleanup_backslash_1(file->symlink.s) != 0) {
- const wchar_t *wp =
- archive_entry_symlink_w(file->entry);
- struct archive_wstring ws;
-
- if (wp != NULL) {
- int r;
- archive_string_init(&ws);
- archive_wstrcpy(&ws, wp);
- cleanup_backslash_2(ws.s);
- archive_string_empty(&(file->symlink));
- r = archive_string_append_from_wcs(
- &(file->symlink),
- ws.s, ws.length);
- archive_wstring_free(&ws);
- if (r < 0 && errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- }
- }
-#endif
- }
- /*
- * - Count up directory elements.
- * - Find out the position which points the last position of
- * path separator('/').
- */
- slash = NULL;
- file->dircnt = 0;
- for (; *p != '\0'; p++)
- if (*p == '/') {
- slash = p;
- file->dircnt++;
- }
- if (slash == NULL) {
- /* The pathname doesn't have a parent directory. */
- file->parentdir.length = len;
- archive_string_copy(&(file->basename), &(file->parentdir));
- archive_string_empty(&(file->parentdir));
- *file->parentdir.s = '\0';
- return (ret);
- }
-
- /* Make a basename from dirname and slash */
- *slash = '\0';
- file->parentdir.length = slash - dirname;
- archive_strcpy(&(file->basename), slash + 1);
- if (archive_entry_filetype(file->entry) == AE_IFDIR)
- file->dircnt ++;
- return (ret);
-}
-
-/*
- * Register a entry to get a hardlink target.
- */
-static int
-isofile_register_hardlink(struct archive_write *a, struct isofile *file)
-{
- struct iso9660 *iso9660 = a->format_data;
- struct hardlink *hl;
- const char *pathname;
-
- archive_entry_set_nlink(file->entry, 1);
- pathname = archive_entry_hardlink(file->entry);
- if (pathname == NULL) {
- /* This `file` is a hardlink target. */
- hl = malloc(sizeof(*hl));
- if (hl == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- hl->nlink = 1;
- /* A hardlink target must be the first position. */
- file->hlnext = NULL;
- hl->file_list.first = file;
- hl->file_list.last = &(file->hlnext);
- __archive_rb_tree_insert_node(&(iso9660->hardlink_rbtree),
- (struct archive_rb_node *)hl);
- } else {
- hl = (struct hardlink *)__archive_rb_tree_find_node(
- &(iso9660->hardlink_rbtree), pathname);
- if (hl != NULL) {
- /* Insert `file` entry into the tail. */
- file->hlnext = NULL;
- *hl->file_list.last = file;
- hl->file_list.last = &(file->hlnext);
- hl->nlink++;
- }
- archive_entry_unset_size(file->entry);
- }
-
- return (ARCHIVE_OK);
-}
-
-/*
- * Hardlinked files have to have the same location of extent.
- * We have to find out hardlink target entries for the entries
- * which have a hardlink target name.
- */
-static void
-isofile_connect_hardlink_files(struct iso9660 *iso9660)
-{
- struct archive_rb_node *n;
- struct hardlink *hl;
- struct isofile *target, *nf;
-
- ARCHIVE_RB_TREE_FOREACH(n, &(iso9660->hardlink_rbtree)) {
- hl = (struct hardlink *)n;
-
- /* The first entry must be a hardlink target. */
- target = hl->file_list.first;
- archive_entry_set_nlink(target->entry, hl->nlink);
- /* Set a hardlink target to reference entries. */
- for (nf = target->hlnext;
- nf != NULL; nf = nf->hlnext) {
- nf->hardlink_target = target;
- archive_entry_set_nlink(nf->entry, hl->nlink);
- }
- }
-}
-
-static int
-isofile_hd_cmp_node(const struct archive_rb_node *n1,
- const struct archive_rb_node *n2)
-{
- const struct hardlink *h1 = (const struct hardlink *)n1;
- const struct hardlink *h2 = (const struct hardlink *)n2;
-
- return (strcmp(archive_entry_pathname(h1->file_list.first->entry),
- archive_entry_pathname(h2->file_list.first->entry)));
-}
-
-static int
-isofile_hd_cmp_key(const struct archive_rb_node *n, const void *key)
-{
- const struct hardlink *h = (const struct hardlink *)n;
-
- return (strcmp(archive_entry_pathname(h->file_list.first->entry),
- (const char *)key));
-}
-
-static void
-isofile_init_hardlinks(struct iso9660 *iso9660)
-{
- static const struct archive_rb_tree_ops rb_ops = {
- isofile_hd_cmp_node, isofile_hd_cmp_key,
- };
-
- __archive_rb_tree_init(&(iso9660->hardlink_rbtree), &rb_ops);
-}
-
-static void
-isofile_free_hardlinks(struct iso9660 *iso9660)
-{
- struct archive_rb_node *n, *tmp;
-
- ARCHIVE_RB_TREE_FOREACH_SAFE(n, &(iso9660->hardlink_rbtree), tmp) {
- __archive_rb_tree_remove_node(&(iso9660->hardlink_rbtree), n);
- free(n);
- }
-}
-
-static struct isoent *
-isoent_new(struct isofile *file)
-{
- struct isoent *isoent;
- static const struct archive_rb_tree_ops rb_ops = {
- isoent_cmp_node, isoent_cmp_key,
- };
-
- isoent = calloc(1, sizeof(*isoent));
- if (isoent == NULL)
- return (NULL);
- isoent->file = file;
- isoent->children.first = NULL;
- isoent->children.last = &(isoent->children.first);
- __archive_rb_tree_init(&(isoent->rbtree), &rb_ops);
- isoent->subdirs.first = NULL;
- isoent->subdirs.last = &(isoent->subdirs.first);
- isoent->extr_rec_list.first = NULL;
- isoent->extr_rec_list.last = &(isoent->extr_rec_list.first);
- isoent->extr_rec_list.current = NULL;
- if (archive_entry_filetype(file->entry) == AE_IFDIR)
- isoent->dir = 1;
-
- return (isoent);
-}
-
-static inline struct isoent *
-isoent_clone(struct isoent *src)
-{
- return (isoent_new(src->file));
-}
-
-static void
-_isoent_free(struct isoent *isoent)
-{
- struct extr_rec *er, *er_next;
-
- free(isoent->children_sorted);
- free(isoent->identifier);
- er = isoent->extr_rec_list.first;
- while (er != NULL) {
- er_next = er->next;
- free(er);
- er = er_next;
- }
- free(isoent);
-}
-
-static void
-isoent_free_all(struct isoent *isoent)
-{
- struct isoent *np, *np_temp;
-
- if (isoent == NULL)
- return;
- np = isoent;
- for (;;) {
- if (np->dir) {
- if (np->children.first != NULL) {
- /* Enter to sub directories. */
- np = np->children.first;
- continue;
- }
- }
- for (;;) {
- np_temp = np;
- if (np->chnext == NULL) {
- /* Return to the parent directory. */
- np = np->parent;
- _isoent_free(np_temp);
- if (np == np_temp)
- return;
- } else {
- np = np->chnext;
- _isoent_free(np_temp);
- break;
- }
- }
- }
-}
-
-static struct isoent *
-isoent_create_virtual_dir(struct archive_write *a, struct iso9660 *iso9660, const char *pathname)
-{
- struct isofile *file;
- struct isoent *isoent;
-
- file = isofile_new(a, NULL);
- if (file == NULL)
- return (NULL);
- archive_entry_set_pathname(file->entry, pathname);
- archive_entry_unset_mtime(file->entry);
- archive_entry_unset_atime(file->entry);
- archive_entry_unset_ctime(file->entry);
- archive_entry_set_uid(file->entry, getuid());
- archive_entry_set_gid(file->entry, getgid());
- archive_entry_set_mode(file->entry, 0555 | AE_IFDIR);
- archive_entry_set_nlink(file->entry, 2);
- if (isofile_gen_utility_names(a, file) < ARCHIVE_WARN) {
- isofile_free(file);
- return (NULL);
- }
- isofile_add_entry(iso9660, file);
-
- isoent = isoent_new(file);
- if (isoent == NULL)
- return (NULL);
- isoent->dir = 1;
- isoent->virtual = 1;
-
- return (isoent);
-}
-
-static int
-isoent_cmp_node(const struct archive_rb_node *n1,
- const struct archive_rb_node *n2)
-{
- const struct isoent *e1 = (const struct isoent *)n1;
- const struct isoent *e2 = (const struct isoent *)n2;
-
- return (strcmp(e1->file->basename.s, e2->file->basename.s));
-}
-
-static int
-isoent_cmp_key(const struct archive_rb_node *n, const void *key)
-{
- const struct isoent *e = (const struct isoent *)n;
-
- return (strcmp(e->file->basename.s, (const char *)key));
-}
-
-static int
-isoent_add_child_head(struct isoent *parent, struct isoent *child)
-{
-
- if (!__archive_rb_tree_insert_node(
- &(parent->rbtree), (struct archive_rb_node *)child))
- return (0);
- if ((child->chnext = parent->children.first) == NULL)
- parent->children.last = &(child->chnext);
- parent->children.first = child;
- parent->children.cnt++;
- child->parent = parent;
-
- /* Add a child to a sub-directory chain */
- if (child->dir) {
- if ((child->drnext = parent->subdirs.first) == NULL)
- parent->subdirs.last = &(child->drnext);
- parent->subdirs.first = child;
- parent->subdirs.cnt++;
- child->parent = parent;
- } else
- child->drnext = NULL;
- return (1);
-}
-
-static int
-isoent_add_child_tail(struct isoent *parent, struct isoent *child)
-{
-
- if (!__archive_rb_tree_insert_node(
- &(parent->rbtree), (struct archive_rb_node *)child))
- return (0);
- child->chnext = NULL;
- *parent->children.last = child;
- parent->children.last = &(child->chnext);
- parent->children.cnt++;
- child->parent = parent;
-
- /* Add a child to a sub-directory chain */
- child->drnext = NULL;
- if (child->dir) {
- *parent->subdirs.last = child;
- parent->subdirs.last = &(child->drnext);
- parent->subdirs.cnt++;
- child->parent = parent;
- }
- return (1);
-}
-
-static void
-isoent_remove_child(struct isoent *parent, struct isoent *child)
-{
- struct isoent *ent;
-
- /* Remove a child entry from children chain. */
- ent = parent->children.first;
- while (ent->chnext != child)
- ent = ent->chnext;
- if ((ent->chnext = ent->chnext->chnext) == NULL)
- parent->children.last = &(ent->chnext);
- parent->children.cnt--;
-
- if (child->dir) {
- /* Remove a child entry from sub-directory chain. */
- ent = parent->subdirs.first;
- while (ent->drnext != child)
- ent = ent->drnext;
- if ((ent->drnext = ent->drnext->drnext) == NULL)
- parent->subdirs.last = &(ent->drnext);
- parent->subdirs.cnt--;
- }
-
- __archive_rb_tree_remove_node(&(parent->rbtree),
- (struct archive_rb_node *)child);
-}
-
-static int
-isoent_clone_tree(struct archive_write *a, struct isoent **nroot,
- struct isoent *root)
-{
- struct isoent *np, *xroot, *newent;
-
- np = root;
- xroot = NULL;
- do {
- newent = isoent_clone(np);
- if (newent == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- if (xroot == NULL) {
- *nroot = xroot = newent;
- newent->parent = xroot;
- } else
- isoent_add_child_tail(xroot, newent);
- if (np->dir && np->children.first != NULL) {
- /* Enter to sub directories. */
- np = np->children.first;
- xroot = newent;
- continue;
- }
- while (np != np->parent) {
- if (np->chnext == NULL) {
- /* Return to the parent directory. */
- np = np->parent;
- xroot = xroot->parent;
- } else {
- np = np->chnext;
- break;
- }
- }
- } while (np != np->parent);
-
- return (ARCHIVE_OK);
-}
-
-/*
- * Setup directory locations.
- */
-static void
-isoent_setup_directory_location(struct iso9660 *iso9660, int location,
- struct vdd *vdd)
-{
- struct isoent *np;
- int depth;
-
- vdd->total_dir_block = 0;
- depth = 0;
- np = vdd->rootent;
- do {
- int block;
-
- np->dir_block = calculate_directory_descriptors(
- iso9660, vdd, np, depth);
- vdd->total_dir_block += np->dir_block;
- np->dir_location = location;
- location += np->dir_block;
- block = extra_setup_location(np, location);
- vdd->total_dir_block += block;
- location += block;
-
- if (np->subdirs.first != NULL && depth + 1 < vdd->max_depth) {
- /* Enter to sub directories. */
- np = np->subdirs.first;
- depth++;
- continue;
- }
- while (np != np->parent) {
- if (np->drnext == NULL) {
- /* Return to the parent directory. */
- np = np->parent;
- depth--;
- } else {
- np = np->drnext;
- break;
- }
- }
- } while (np != np->parent);
-}
-
-static void
-_isoent_file_location(struct iso9660 *iso9660, struct isoent *isoent,
- int *symlocation)
-{
- struct isoent **children;
- int n;
-
- if (isoent->children.cnt == 0)
- return;
-
- children = isoent->children_sorted;
- for (n = 0; n < isoent->children.cnt; n++) {
- struct isoent *np;
- struct isofile *file;
-
- np = children[n];
- if (np->dir)
- continue;
- if (np == iso9660->el_torito.boot)
- continue;
- file = np->file;
- if (file->boot || file->hardlink_target != NULL)
- continue;
- if (archive_entry_filetype(file->entry) == AE_IFLNK ||
- file->content.size == 0) {
- /*
- * Do not point a valid location.
- * Make sure entry is not hardlink file.
- */
- file->content.location = (*symlocation)--;
- continue;
- }
-
- file->write_content = 1;
- }
-}
-
-/*
- * Setup file locations.
- */
-static void
-isoent_setup_file_location(struct iso9660 *iso9660, int location)
-{
- struct isoent *isoent;
- struct isoent *np;
- struct isofile *file;
- size_t size;
- int block;
- int depth;
- int joliet;
- int symlocation;
- int total_block;
-
- iso9660->total_file_block = 0;
- if ((isoent = iso9660->el_torito.catalog) != NULL) {
- isoent->file->content.location = location;
- block = (int)((archive_entry_size(isoent->file->entry) +
- LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS);
- location += block;
- iso9660->total_file_block += block;
- }
- if ((isoent = iso9660->el_torito.boot) != NULL) {
- isoent->file->content.location = location;
- size = fd_boot_image_size(iso9660->el_torito.media_type);
- if (size == 0)
- size = (size_t)archive_entry_size(isoent->file->entry);
- block = ((int)size + LOGICAL_BLOCK_SIZE -1)
- >> LOGICAL_BLOCK_BITS;
- location += block;
- iso9660->total_file_block += block;
- isoent->file->content.blocks = block;
- }
-
- depth = 0;
- symlocation = -16;
- if (!iso9660->opt.rr && iso9660->opt.joliet) {
- joliet = 1;
- np = iso9660->joliet.rootent;
- } else {
- joliet = 0;
- np = iso9660->primary.rootent;
- }
- do {
- _isoent_file_location(iso9660, np, &symlocation);
-
- if (np->subdirs.first != NULL &&
- (joliet ||
- ((iso9660->opt.rr == OPT_RR_DISABLED &&
- depth + 2 < iso9660->primary.max_depth) ||
- (iso9660->opt.rr &&
- depth + 1 < iso9660->primary.max_depth)))) {
- /* Enter to sub directories. */
- np = np->subdirs.first;
- depth++;
- continue;
- }
- while (np != np->parent) {
- if (np->drnext == NULL) {
- /* Return to the parent directory. */
- np = np->parent;
- depth--;
- } else {
- np = np->drnext;
- break;
- }
- }
- } while (np != np->parent);
-
- total_block = 0;
- for (file = iso9660->data_file_list.first;
- file != NULL; file = file->datanext) {
-
- if (!file->write_content)
- continue;
-
- file->cur_content = &(file->content);
- do {
- file->cur_content->location = location;
- location += file->cur_content->blocks;
- total_block += file->cur_content->blocks;
- /* Next fragment */
- file->cur_content = file->cur_content->next;
- } while (file->cur_content != NULL);
- }
- iso9660->total_file_block += total_block;
-}
-
-static int
-get_path_component(char *name, size_t n, const char *fn)
-{
- char *p;
- size_t l;
-
- p = strchr(fn, '/');
- if (p == NULL) {
- if ((l = strlen(fn)) == 0)
- return (0);
- } else
- l = p - fn;
- if (l > n -1)
- return (-1);
- memcpy(name, fn, l);
- name[l] = '\0';
-
- return ((int)l);
-}
-
-/*
- * Add a new entry into the tree.
- */
-static int
-isoent_tree(struct archive_write *a, struct isoent **isoentpp)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- char name[_MAX_FNAME];/* Included null terminator size. */
-#elif defined(NAME_MAX) && NAME_MAX >= 255
- char name[NAME_MAX+1];
-#else
- char name[256];
-#endif
- struct iso9660 *iso9660 = a->format_data;
- struct isoent *dent, *isoent, *np;
- struct isofile *f1, *f2;
- const char *fn, *p;
- int l;
-
- isoent = *isoentpp;
- dent = iso9660->primary.rootent;
- if (isoent->file->parentdir.length > 0)
- fn = p = isoent->file->parentdir.s;
- else
- fn = p = "";
-
- /*
- * If the path of the parent directory of `isoent' entry is
- * the same as the path of `cur_dirent', add isoent to
- * `cur_dirent'.
- */
- if (archive_strlen(&(iso9660->cur_dirstr))
- == archive_strlen(&(isoent->file->parentdir)) &&
- strcmp(iso9660->cur_dirstr.s, fn) == 0) {
- if (!isoent_add_child_tail(iso9660->cur_dirent, isoent)) {
- np = (struct isoent *)__archive_rb_tree_find_node(
- &(iso9660->cur_dirent->rbtree),
- isoent->file->basename.s);
- goto same_entry;
- }
- return (ARCHIVE_OK);
- }
-
- for (;;) {
- l = get_path_component(name, sizeof(name), fn);
- if (l == 0) {
- np = NULL;
- break;
- }
- if (l < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "A name buffer is too small");
- _isoent_free(isoent);
- return (ARCHIVE_FATAL);
- }
-
- np = isoent_find_child(dent, name);
- if (np == NULL || fn[0] == '\0')
- break;
-
- /* Find next subdirectory. */
- if (!np->dir) {
- /* NOT Directory! */
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "`%s' is not directory, we cannot insert `%s' ",
- archive_entry_pathname(np->file->entry),
- archive_entry_pathname(isoent->file->entry));
- _isoent_free(isoent);
- *isoentpp = NULL;
- return (ARCHIVE_FAILED);
- }
- fn += l;
- if (fn[0] == '/')
- fn++;
- dent = np;
- }
- if (np == NULL) {
- /*
- * Create virtual parent directories.
- */
- while (fn[0] != '\0') {
- struct isoent *vp;
- struct archive_string as;
-
- archive_string_init(&as);
- archive_strncat(&as, p, fn - p + l);
- if (as.s[as.length-1] == '/') {
- as.s[as.length-1] = '\0';
- as.length--;
- }
- vp = isoent_create_virtual_dir(a, iso9660, as.s);
- if (vp == NULL) {
- archive_string_free(&as);
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- _isoent_free(isoent);
- *isoentpp = NULL;
- return (ARCHIVE_FATAL);
- }
- archive_string_free(&as);
-
- if (vp->file->dircnt > iso9660->dircnt_max)
- iso9660->dircnt_max = vp->file->dircnt;
- isoent_add_child_tail(dent, vp);
- np = vp;
-
- fn += l;
- if (fn[0] == '/')
- fn++;
- l = get_path_component(name, sizeof(name), fn);
- if (l < 0) {
- archive_string_free(&as);
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "A name buffer is too small");
- _isoent_free(isoent);
- *isoentpp = NULL;
- return (ARCHIVE_FATAL);
- }
- dent = np;
- }
-
- /* Found out the parent directory where isoent can be
- * inserted. */
- iso9660->cur_dirent = dent;
- archive_string_empty(&(iso9660->cur_dirstr));
- archive_string_ensure(&(iso9660->cur_dirstr),
- archive_strlen(&(dent->file->parentdir)) +
- archive_strlen(&(dent->file->basename)) + 2);
- if (archive_strlen(&(dent->file->parentdir)) +
- archive_strlen(&(dent->file->basename)) == 0)
- iso9660->cur_dirstr.s[0] = 0;
- else {
- if (archive_strlen(&(dent->file->parentdir)) > 0) {
- archive_string_copy(&(iso9660->cur_dirstr),
- &(dent->file->parentdir));
- archive_strappend_char(&(iso9660->cur_dirstr), '/');
- }
- archive_string_concat(&(iso9660->cur_dirstr),
- &(dent->file->basename));
- }
-
- if (!isoent_add_child_tail(dent, isoent)) {
- np = (struct isoent *)__archive_rb_tree_find_node(
- &(dent->rbtree), isoent->file->basename.s);
- goto same_entry;
- }
- return (ARCHIVE_OK);
- }
-
-same_entry:
- /*
- * We have already has the entry the filename of which is
- * the same.
- */
- f1 = np->file;
- f2 = isoent->file;
-
- /* If the file type of entries is different,
- * we cannot handle it. */
- if (archive_entry_filetype(f1->entry) !=
- archive_entry_filetype(f2->entry)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Found duplicate entries `%s' and its file type is "
- "different",
- archive_entry_pathname(f1->entry));
- _isoent_free(isoent);
- *isoentpp = NULL;
- return (ARCHIVE_FAILED);
- }
-
- /* Swap file entries. */
- np->file = f2;
- isoent->file = f1;
- np->virtual = 0;
-
- _isoent_free(isoent);
- *isoentpp = np;
- return (ARCHIVE_OK);
-}
-
-/*
- * Find a entry from `isoent'
- */
-static struct isoent *
-isoent_find_child(struct isoent *isoent, const char *child_name)
-{
- struct isoent *np;
-
- np = (struct isoent *)__archive_rb_tree_find_node(
- &(isoent->rbtree), child_name);
- return (np);
-}
-
-/*
- * Find a entry full-path of which is specified by `fn' parameter,
- * in the tree.
- */
-static struct isoent *
-isoent_find_entry(struct isoent *rootent, const char *fn)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- char name[_MAX_FNAME];/* Included null terminator size. */
-#elif defined(NAME_MAX) && NAME_MAX >= 255
- char name[NAME_MAX+1];
-#else
- char name[256];
-#endif
- struct isoent *isoent, *np;
- int l;
-
- isoent = rootent;
- np = NULL;
- for (;;) {
- l = get_path_component(name, sizeof(name), fn);
- if (l == 0)
- break;
- fn += l;
- if (fn[0] == '/')
- fn++;
-
- np = isoent_find_child(isoent, name);
- if (np == NULL)
- break;
- if (fn[0] == '\0')
- break;/* We found out the entry */
-
- /* Try sub directory. */
- isoent = np;
- np = NULL;
- if (!isoent->dir)
- break;/* Not directory */
- }
-
- return (np);
-}
-
-/*
- * Following idr_* functions are used for resolving duplicated filenames
- * and unreceivable filenames to generate ISO9660/Joliet Identifiers.
- */
-
-static void
-idr_relaxed_filenames(char *map)
-{
- int i;
-
- for (i = 0x21; i <= 0x2F; i++)
- map[i] = 1;
- for (i = 0x3A; i <= 0x41; i++)
- map[i] = 1;
- for (i = 0x5B; i <= 0x5E; i++)
- map[i] = 1;
- map[0x60] = 1;
- for (i = 0x7B; i <= 0x7E; i++)
- map[i] = 1;
-}
-
-static void
-idr_init(struct iso9660 *iso9660, struct vdd *vdd, struct idr *idr)
-{
-
- idr->idrent_pool = NULL;
- idr->pool_size = 0;
- if (vdd->vdd_type != VDD_JOLIET) {
- if (iso9660->opt.iso_level <= 3) {
- memcpy(idr->char_map, d_characters_map,
- sizeof(idr->char_map));
- } else {
- memcpy(idr->char_map, d1_characters_map,
- sizeof(idr->char_map));
- idr_relaxed_filenames(idr->char_map);
- }
- }
-}
-
-static void
-idr_cleanup(struct idr *idr)
-{
- free(idr->idrent_pool);
-}
-
-static int
-idr_ensure_poolsize(struct archive_write *a, struct idr *idr,
- int cnt)
-{
-
- if (idr->pool_size < cnt) {
- void *p;
- const int bk = (1 << 7) - 1;
- int psize;
-
- psize = (cnt + bk) & ~bk;
- p = realloc(idr->idrent_pool, sizeof(struct idrent) * psize);
- if (p == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- idr->idrent_pool = (struct idrent *)p;
- idr->pool_size = psize;
- }
- return (ARCHIVE_OK);
-}
-
-static int
-idr_start(struct archive_write *a, struct idr *idr, int cnt, int ffmax,
- int num_size, int null_size, const struct archive_rb_tree_ops *rbt_ops)
-{
- int r;
-
- (void)ffmax; /* UNUSED */
-
- r = idr_ensure_poolsize(a, idr, cnt);
- if (r != ARCHIVE_OK)
- return (r);
- __archive_rb_tree_init(&(idr->rbtree), rbt_ops);
- idr->wait_list.first = NULL;
- idr->wait_list.last = &(idr->wait_list.first);
- idr->pool_idx = 0;
- idr->num_size = num_size;
- idr->null_size = null_size;
- return (ARCHIVE_OK);
-}
-
-static void
-idr_register(struct idr *idr, struct isoent *isoent, int weight, int noff)
-{
- struct idrent *idrent, *n;
-
- idrent = &(idr->idrent_pool[idr->pool_idx++]);
- idrent->wnext = idrent->avail = NULL;
- idrent->isoent = isoent;
- idrent->weight = weight;
- idrent->noff = noff;
- idrent->rename_num = 0;
-
- if (!__archive_rb_tree_insert_node(&(idr->rbtree), &(idrent->rbnode))) {
- n = (struct idrent *)__archive_rb_tree_find_node(
- &(idr->rbtree), idrent->isoent);
- if (n != NULL) {
- /* this `idrent' needs to rename. */
- idrent->avail = n;
- *idr->wait_list.last = idrent;
- idr->wait_list.last = &(idrent->wnext);
- }
- }
-}
-
-static void
-idr_extend_identifier(struct idrent *wnp, int numsize, int nullsize)
-{
- unsigned char *p;
- int wnp_ext_off;
-
- wnp_ext_off = wnp->isoent->ext_off;
- if (wnp->noff + numsize != wnp_ext_off) {
- p = (unsigned char *)wnp->isoent->identifier;
- /* Extend the filename; foo.c --> foo___.c */
- memmove(p + wnp->noff + numsize, p + wnp_ext_off,
- wnp->isoent->ext_len + nullsize);
- wnp->isoent->ext_off = wnp_ext_off = wnp->noff + numsize;
- wnp->isoent->id_len = wnp_ext_off + wnp->isoent->ext_len;
- }
-}
-
-static void
-idr_resolve(struct idr *idr, void (*fsetnum)(unsigned char *p, int num))
-{
- struct idrent *n;
- unsigned char *p;
-
- for (n = idr->wait_list.first; n != NULL; n = n->wnext) {
- idr_extend_identifier(n, idr->num_size, idr->null_size);
- p = (unsigned char *)n->isoent->identifier + n->noff;
- do {
- fsetnum(p, n->avail->rename_num++);
- } while (!__archive_rb_tree_insert_node(
- &(idr->rbtree), &(n->rbnode)));
- }
-}
-
-static void
-idr_set_num(unsigned char *p, int num)
-{
- static const char xdig[] = {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
- 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
- 'U', 'V', 'W', 'X', 'Y', 'Z'
- };
-
- num %= sizeof(xdig) * sizeof(xdig) * sizeof(xdig);
- p[0] = xdig[(num / (sizeof(xdig) * sizeof(xdig)))];
- num %= sizeof(xdig) * sizeof(xdig);
- p[1] = xdig[ (num / sizeof(xdig))];
- num %= sizeof(xdig);
- p[2] = xdig[num];
-}
-
-static void
-idr_set_num_beutf16(unsigned char *p, int num)
-{
- static const uint16_t xdig[] = {
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
- 0x0036, 0x0037, 0x0038, 0x0039,
- 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046,
- 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C,
- 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052,
- 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
- 0x0059, 0x005A
- };
-#define XDIG_CNT (sizeof(xdig)/sizeof(xdig[0]))
-
- num %= XDIG_CNT * XDIG_CNT * XDIG_CNT;
- archive_be16enc(p, xdig[(num / (XDIG_CNT * XDIG_CNT))]);
- num %= XDIG_CNT * XDIG_CNT;
- archive_be16enc(p+2, xdig[ (num / XDIG_CNT)]);
- num %= XDIG_CNT;
- archive_be16enc(p+4, xdig[num]);
-}
-
-/*
- * Generate ISO9660 Identifier.
- */
-static int
-isoent_gen_iso9660_identifier(struct archive_write *a, struct isoent *isoent,
- struct idr *idr)
-{
- struct iso9660 *iso9660;
- struct isoent *np;
- char *p;
- int l, r;
- const char *char_map;
- char allow_ldots, allow_multidot, allow_period, allow_vernum;
- int fnmax, ffmax, dnmax;
- static const struct archive_rb_tree_ops rb_ops = {
- isoent_cmp_node_iso9660, isoent_cmp_key_iso9660
- };
-
- if (isoent->children.cnt == 0)
- return (0);
-
- iso9660 = a->format_data;
- char_map = idr->char_map;
- if (iso9660->opt.iso_level <= 3) {
- allow_ldots = 0;
- allow_multidot = 0;
- allow_period = 1;
- allow_vernum = iso9660->opt.allow_vernum;
- if (iso9660->opt.iso_level == 1) {
- fnmax = 8;
- ffmax = 12;/* fnmax + '.' + 3 */
- dnmax = 8;
- } else {
- fnmax = 30;
- ffmax = 31;
- dnmax = 31;
- }
- } else {
- allow_ldots = allow_multidot = 1;
- allow_period = allow_vernum = 0;
- if (iso9660->opt.rr)
- /*
- * MDR : The maximum size of Directory Record(254).
- * DRL : A Directory Record Length(33).
- * CE : A size of SUSP CE System Use Entry(28).
- * MDR - DRL - CE = 254 - 33 - 28 = 193.
- */
- fnmax = ffmax = dnmax = 193;
- else
- /*
- * XA : CD-ROM XA System Use Extension
- * Information(14).
- * MDR - DRL - XA = 254 - 33 -14 = 207.
- */
- fnmax = ffmax = dnmax = 207;
- }
-
- r = idr_start(a, idr, isoent->children.cnt, ffmax, 3, 1, &rb_ops);
- if (r < 0)
- return (r);
-
- for (np = isoent->children.first; np != NULL; np = np->chnext) {
- char *dot, *xdot;
- int ext_off, noff, weight;
-
- l = (int)np->file->basename.length;
- p = malloc(l+31+2+1);
- if (p == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- memcpy(p, np->file->basename.s, l);
- p[l] = '\0';
- np->identifier = p;
-
- dot = xdot = NULL;
- if (!allow_ldots) {
- /*
- * If there is a '.' character at the first byte,
- * it has to be replaced by '_' character.
- */
- if (*p == '.')
- *p++ = '_';
- }
- for (;*p; p++) {
- if (*p & 0x80) {
- *p = '_';
- continue;
- }
- if (char_map[(unsigned char)*p]) {
- /* if iso-level is '4', a character '.' is
- * allowed by char_map. */
- if (*p == '.') {
- xdot = dot;
- dot = p;
- }
- continue;
- }
- if (*p >= 'a' && *p <= 'z') {
- *p -= 'a' - 'A';
- continue;
- }
- if (*p == '.') {
- xdot = dot;
- dot = p;
- if (allow_multidot)
- continue;
- }
- *p = '_';
- }
- p = np->identifier;
- weight = -1;
- if (dot == NULL) {
- int nammax;
-
- if (np->dir)
- nammax = dnmax;
- else
- nammax = fnmax;
-
- if (l > nammax) {
- p[nammax] = '\0';
- weight = nammax;
- ext_off = nammax;
- } else
- ext_off = l;
- } else {
- *dot = '.';
- ext_off = (int)(dot - p);
-
- if (iso9660->opt.iso_level == 1) {
- if (dot - p <= 8) {
- if (strlen(dot) > 4) {
- /* A length of a file extension
- * must be less than 4 */
- dot[4] = '\0';
- weight = 0;
- }
- } else {
- p[8] = dot[0];
- p[9] = dot[1];
- p[10] = dot[2];
- p[11] = dot[3];
- p[12] = '\0';
- weight = 8;
- ext_off = 8;
- }
- } else if (np->dir) {
- if (l > dnmax) {
- p[dnmax] = '\0';
- weight = dnmax;
- if (ext_off > dnmax)
- ext_off = dnmax;
- }
- } else if (l > ffmax) {
- int extlen = (int)strlen(dot);
- int xdoff;
-
- if (xdot != NULL)
- xdoff = (int)(xdot - p);
- else
- xdoff = 0;
-
- if (extlen > 1 && xdoff < fnmax-1) {
- int off;
-
- if (extlen > ffmax)
- extlen = ffmax;
- off = ffmax - extlen;
- if (off == 0) {
- /* A dot('.') character
- * doesn't place to the first
- * byte of identifier. */
- off ++;
- extlen --;
- }
- memmove(p+off, dot, extlen);
- p[ffmax] = '\0';
- ext_off = off;
- weight = off;
-#ifdef COMPAT_MKISOFS
- } else if (xdoff >= fnmax-1) {
- /* Simulate a bug(?) of mkisofs. */
- p[fnmax-1] = '\0';
- ext_off = fnmax-1;
- weight = fnmax-1;
-#endif
- } else {
- p[fnmax] = '\0';
- ext_off = fnmax;
- weight = fnmax;
- }
- }
- }
- /* Save an offset of a file name extension to sort files. */
- np->ext_off = ext_off;
- np->ext_len = (int)strlen(&p[ext_off]);
- np->id_len = l = ext_off + np->ext_len;
-
- /* Make an offset of the number which is used to be set
- * hexadecimal number to avoid duplicate identifier. */
- if (iso9660->opt.iso_level == 1) {
- if (ext_off >= 5)
- noff = 5;
- else
- noff = ext_off;
- } else {
- if (l == ffmax)
- noff = ext_off - 3;
- else if (l == ffmax-1)
- noff = ext_off - 2;
- else if (l == ffmax-2)
- noff = ext_off - 1;
- else
- noff = ext_off;
- }
- /* Register entry to the identifier resolver. */
- idr_register(idr, np, weight, noff);
- }
-
- /* Resolve duplicate identifier. */
- idr_resolve(idr, idr_set_num);
-
- /* Add a period and a version number to identifiers. */
- for (np = isoent->children.first; np != NULL; np = np->chnext) {
- if (!np->dir && np->rr_child == NULL) {
- p = np->identifier + np->ext_off + np->ext_len;
- if (np->ext_len == 0 && allow_period) {
- *p++ = '.';
- np->ext_len = 1;
- }
- if (np->ext_len == 1 && !allow_period) {
- *--p = '\0';
- np->ext_len = 0;
- }
- np->id_len = np->ext_off + np->ext_len;
- if (allow_vernum) {
- *p++ = ';';
- *p++ = '1';
- np->id_len += 2;
- }
- *p = '\0';
- } else
- np->id_len = np->ext_off + np->ext_len;
- np->mb_len = np->id_len;
- }
- return (ARCHIVE_OK);
-}
-
-/*
- * Generate Joliet Identifier.
- */
-static int
-isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
- struct idr *idr)
-{
- struct iso9660 *iso9660;
- struct isoent *np;
- unsigned char *p;
- size_t l;
- int r;
- size_t ffmax, parent_len;
- static const struct archive_rb_tree_ops rb_ops = {
- isoent_cmp_node_joliet, isoent_cmp_key_joliet
- };
-
- if (isoent->children.cnt == 0)
- return (0);
-
- iso9660 = a->format_data;
- if (iso9660->opt.joliet == OPT_JOLIET_LONGNAME)
- ffmax = 206;
- else
- ffmax = 128;
-
- r = idr_start(a, idr, isoent->children.cnt, (int)ffmax, 6, 2, &rb_ops);
- if (r < 0)
- return (r);
-
- parent_len = 1;
- for (np = isoent; np->parent != np; np = np->parent)
- parent_len += np->mb_len + 1;
-
- for (np = isoent->children.first; np != NULL; np = np->chnext) {
- unsigned char *dot;
- int ext_off, noff, weight;
- size_t lt;
-
- if ((l = np->file->basename_utf16.length) > ffmax)
- l = ffmax;
-
- p = malloc((l+1)*2);
- if (p == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- memcpy(p, np->file->basename_utf16.s, l);
- p[l] = 0;
- p[l+1] = 0;
-
- np->identifier = (char *)p;
- lt = l;
- dot = p + l;
- weight = 0;
- while (lt > 0) {
- if (!joliet_allowed_char(p[0], p[1]))
- archive_be16enc(p, 0x005F); /* '_' */
- else if (p[0] == 0 && p[1] == 0x2E) /* '.' */
- dot = p;
- p += 2;
- lt -= 2;
- }
- ext_off = (int)(dot - (unsigned char *)np->identifier);
- np->ext_off = ext_off;
- np->ext_len = (int)l - ext_off;
- np->id_len = (int)l;
-
- /*
- * Get a length of MBS of a full-pathname.
- */
- if (np->file->basename_utf16.length > ffmax) {
- if (archive_strncpy_l(&iso9660->mbs,
- (const char *)np->identifier, l,
- iso9660->sconv_from_utf16be) != 0 &&
- errno == ENOMEM) {
- archive_set_error(&a->archive, errno,
- "No memory");
- return (ARCHIVE_FATAL);
- }
- np->mb_len = (int)iso9660->mbs.length;
- if (np->mb_len != (int)np->file->basename.length)
- weight = np->mb_len;
- } else
- np->mb_len = (int)np->file->basename.length;
-
- /* If a length of full-pathname is longer than 240 bytes,
- * it violates Joliet extensions regulation. */
- if (parent_len > 240
- || np->mb_len > 240
- || parent_len + np->mb_len > 240) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "The regulation of Joliet extensions;"
- " A length of a full-pathname of `%s' is "
- "longer than 240 bytes, (p=%d, b=%d)",
- archive_entry_pathname(np->file->entry),
- (int)parent_len, (int)np->mb_len);
- return (ARCHIVE_FATAL);
- }
-
- /* Make an offset of the number which is used to be set
- * hexadecimal number to avoid duplicate identifier. */
- if (l == ffmax)
- noff = ext_off - 6;
- else if (l == ffmax-2)
- noff = ext_off - 4;
- else if (l == ffmax-4)
- noff = ext_off - 2;
- else
- noff = ext_off;
- /* Register entry to the identifier resolver. */
- idr_register(idr, np, weight, noff);
- }
-
- /* Resolve duplicate identifier with Joliet Volume. */
- idr_resolve(idr, idr_set_num_beutf16);
-
- return (ARCHIVE_OK);
-}
-
-/*
- * This comparing rule is according to ISO9660 Standard 9.3
- */
-static int
-isoent_cmp_iso9660_identifier(const struct isoent *p1, const struct isoent *p2)
-{
- const char *s1, *s2;
- int cmp;
- int l;
-
- s1 = p1->identifier;
- s2 = p2->identifier;
-
- /* Compare File Name */
- l = p1->ext_off;
- if (l > p2->ext_off)
- l = p2->ext_off;
- cmp = memcmp(s1, s2, l);
- if (cmp != 0)
- return (cmp);
- if (p1->ext_off < p2->ext_off) {
- s2 += l;
- l = p2->ext_off - p1->ext_off;
- while (l--)
- if (0x20 != *s2++)
- return (0x20
- - *(const unsigned char *)(s2 - 1));
- } else if (p1->ext_off > p2->ext_off) {
- s1 += l;
- l = p1->ext_off - p2->ext_off;
- while (l--)
- if (0x20 != *s1++)
- return (*(const unsigned char *)(s1 - 1)
- - 0x20);
- }
- /* Compare File Name Extension */
- if (p1->ext_len == 0 && p2->ext_len == 0)
- return (0);
- if (p1->ext_len == 1 && p2->ext_len == 1)
- return (0);
- if (p1->ext_len <= 1)
- return (-1);
- if (p2->ext_len <= 1)
- return (1);
- l = p1->ext_len;
- if (l > p2->ext_len)
- l = p2->ext_len;
- s1 = p1->identifier + p1->ext_off;
- s2 = p2->identifier + p2->ext_off;
- if (l > 1) {
- cmp = memcmp(s1, s2, l);
- if (cmp != 0)
- return (cmp);
- }
- if (p1->ext_len < p2->ext_len) {
- s2 += l;
- l = p2->ext_len - p1->ext_len;
- while (l--)
- if (0x20 != *s2++)
- return (0x20
- - *(const unsigned char *)(s2 - 1));
- } else if (p1->ext_len > p2->ext_len) {
- s1 += l;
- l = p1->ext_len - p2->ext_len;
- while (l--)
- if (0x20 != *s1++)
- return (*(const unsigned char *)(s1 - 1)
- - 0x20);
- }
- /* Compare File Version Number */
- /* No operation. The File Version Number is always one. */
-
- return (cmp);
-}
-
-static int
-isoent_cmp_node_iso9660(const struct archive_rb_node *n1,
- const struct archive_rb_node *n2)
-{
- const struct idrent *e1 = (const struct idrent *)n1;
- const struct idrent *e2 = (const struct idrent *)n2;
-
- return (isoent_cmp_iso9660_identifier(e2->isoent, e1->isoent));
-}
-
-static int
-isoent_cmp_key_iso9660(const struct archive_rb_node *node, const void *key)
-{
- const struct isoent *isoent = (const struct isoent *)key;
- const struct idrent *idrent = (const struct idrent *)node;
-
- return (isoent_cmp_iso9660_identifier(isoent, idrent->isoent));
-}
-
-static int
-isoent_cmp_joliet_identifier(const struct isoent *p1, const struct isoent *p2)
-{
- const unsigned char *s1, *s2;
- int cmp;
- int l;
-
- s1 = (const unsigned char *)p1->identifier;
- s2 = (const unsigned char *)p2->identifier;
-
- /* Compare File Name */
- l = p1->ext_off;
- if (l > p2->ext_off)
- l = p2->ext_off;
- cmp = memcmp(s1, s2, l);
- if (cmp != 0)
- return (cmp);
- if (p1->ext_off < p2->ext_off) {
- s2 += l;
- l = p2->ext_off - p1->ext_off;
- while (l--)
- if (0 != *s2++)
- return (- *(const unsigned char *)(s2 - 1));
- } else if (p1->ext_off > p2->ext_off) {
- s1 += l;
- l = p1->ext_off - p2->ext_off;
- while (l--)
- if (0 != *s1++)
- return (*(const unsigned char *)(s1 - 1));
- }
- /* Compare File Name Extension */
- if (p1->ext_len == 0 && p2->ext_len == 0)
- return (0);
- if (p1->ext_len == 2 && p2->ext_len == 2)
- return (0);
- if (p1->ext_len <= 2)
- return (-1);
- if (p2->ext_len <= 2)
- return (1);
- l = p1->ext_len;
- if (l > p2->ext_len)
- l = p2->ext_len;
- s1 = (unsigned char *)(p1->identifier + p1->ext_off);
- s2 = (unsigned char *)(p2->identifier + p2->ext_off);
- if (l > 1) {
- cmp = memcmp(s1, s2, l);
- if (cmp != 0)
- return (cmp);
- }
- if (p1->ext_len < p2->ext_len) {
- s2 += l;
- l = p2->ext_len - p1->ext_len;
- while (l--)
- if (0 != *s2++)
- return (- *(const unsigned char *)(s2 - 1));
- } else if (p1->ext_len > p2->ext_len) {
- s1 += l;
- l = p1->ext_len - p2->ext_len;
- while (l--)
- if (0 != *s1++)
- return (*(const unsigned char *)(s1 - 1));
- }
- /* Compare File Version Number */
- /* No operation. The File Version Number is always one. */
-
- return (cmp);
-}
-
-static int
-isoent_cmp_node_joliet(const struct archive_rb_node *n1,
- const struct archive_rb_node *n2)
-{
- const struct idrent *e1 = (const struct idrent *)n1;
- const struct idrent *e2 = (const struct idrent *)n2;
-
- return (isoent_cmp_joliet_identifier(e2->isoent, e1->isoent));
-}
-
-static int
-isoent_cmp_key_joliet(const struct archive_rb_node *node, const void *key)
-{
- const struct isoent *isoent = (const struct isoent *)key;
- const struct idrent *idrent = (const struct idrent *)node;
-
- return (isoent_cmp_joliet_identifier(isoent, idrent->isoent));
-}
-
-static int
-isoent_make_sorted_files(struct archive_write *a, struct isoent *isoent,
- struct idr *idr)
-{
- struct archive_rb_node *rn;
- struct isoent **children;
-
- children = malloc(isoent->children.cnt * sizeof(struct isoent *));
- if (children == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- isoent->children_sorted = children;
-
- ARCHIVE_RB_TREE_FOREACH(rn, &(idr->rbtree)) {
- struct idrent *idrent = (struct idrent *)rn;
- *children ++ = idrent->isoent;
- }
- return (ARCHIVE_OK);
-}
-
-/*
- * - Generate ISO9660 and Joliet identifiers from basenames.
- * - Sort files by each directory.
- */
-static int
-isoent_traverse_tree(struct archive_write *a, struct vdd* vdd)
-{
- struct iso9660 *iso9660 = a->format_data;
- struct isoent *np;
- struct idr idr;
- int depth;
- int r;
- int (*genid)(struct archive_write *, struct isoent *, struct idr *);
-
- idr_init(iso9660, vdd, &idr);
- np = vdd->rootent;
- depth = 0;
- if (vdd->vdd_type == VDD_JOLIET)
- genid = isoent_gen_joliet_identifier;
- else
- genid = isoent_gen_iso9660_identifier;
- do {
- if (np->virtual &&
- !archive_entry_mtime_is_set(np->file->entry)) {
- /* Set properly times to virtual directory */
- archive_entry_set_mtime(np->file->entry,
- iso9660->birth_time, 0);
- archive_entry_set_atime(np->file->entry,
- iso9660->birth_time, 0);
- archive_entry_set_ctime(np->file->entry,
- iso9660->birth_time, 0);
- }
- if (np->children.first != NULL) {
- if (vdd->vdd_type != VDD_JOLIET &&
- !iso9660->opt.rr && depth + 1 >= vdd->max_depth) {
- if (np->children.cnt > 0)
- iso9660->directories_too_deep = np;
- } else {
- /* Generate Identifier */
- r = genid(a, np, &idr);
- if (r < 0)
- goto exit_traverse_tree;
- r = isoent_make_sorted_files(a, np, &idr);
- if (r < 0)
- goto exit_traverse_tree;
-
- if (np->subdirs.first != NULL &&
- depth + 1 < vdd->max_depth) {
- /* Enter to sub directories. */
- np = np->subdirs.first;
- depth++;
- continue;
- }
- }
- }
- while (np != np->parent) {
- if (np->drnext == NULL) {
- /* Return to the parent directory. */
- np = np->parent;
- depth--;
- } else {
- np = np->drnext;
- break;
- }
- }
- } while (np != np->parent);
-
- r = ARCHIVE_OK;
-exit_traverse_tree:
- idr_cleanup(&idr);
-
- return (r);
-}
-
-/*
- * Collect directory entries into path_table by a directory depth.
- */
-static int
-isoent_collect_dirs(struct vdd *vdd, struct isoent *rootent, int depth)
-{
- struct isoent *np;
-
- if (rootent == NULL)
- rootent = vdd->rootent;
- np = rootent;
- do {
- /* Register current directory to pathtable. */
- path_table_add_entry(&(vdd->pathtbl[depth]), np);
-
- if (np->subdirs.first != NULL && depth + 1 < vdd->max_depth) {
- /* Enter to sub directories. */
- np = np->subdirs.first;
- depth++;
- continue;
- }
- while (np != rootent) {
- if (np->drnext == NULL) {
- /* Return to the parent directory. */
- np = np->parent;
- depth--;
- } else {
- np = np->drnext;
- break;
- }
- }
- } while (np != rootent);
-
- return (ARCHIVE_OK);
-}
-
-/*
- * The entry whose number of levels in a directory hierarchy is
- * large than eight relocate to rr_move directory.
- */
-static int
-isoent_rr_move_dir(struct archive_write *a, struct isoent **rr_moved,
- struct isoent *curent, struct isoent **newent)
-{
- struct iso9660 *iso9660 = a->format_data;
- struct isoent *rrmoved, *mvent, *np;
-
- if ((rrmoved = *rr_moved) == NULL) {
- struct isoent *rootent = iso9660->primary.rootent;
- /* There isn't rr_move entry.
- * Create rr_move entry and insert it into the root entry.
- */
- rrmoved = isoent_create_virtual_dir(a, iso9660, "rr_moved");
- if (rrmoved == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- /* Add "rr_moved" entry to the root entry. */
- isoent_add_child_head(rootent, rrmoved);
- archive_entry_set_nlink(rootent->file->entry,
- archive_entry_nlink(rootent->file->entry) + 1);
- /* Register "rr_moved" entry to second level pathtable. */
- path_table_add_entry(&(iso9660->primary.pathtbl[1]), rrmoved);
- /* Save rr_moved. */
- *rr_moved = rrmoved;
- }
- /*
- * Make a clone of curent which is going to be relocated
- * to rr_moved.
- */
- mvent = isoent_clone(curent);
- if (mvent == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- /* linking.. and use for creating "CL", "PL" and "RE" */
- mvent->rr_parent = curent->parent;
- curent->rr_child = mvent;
- /*
- * Move subdirectories from the curent to mvent
- */
- if (curent->children.first != NULL) {
- *mvent->children.last = curent->children.first;
- mvent->children.last = curent->children.last;
- }
- for (np = mvent->children.first; np != NULL; np = np->chnext)
- np->parent = mvent;
- mvent->children.cnt = curent->children.cnt;
- curent->children.cnt = 0;
- curent->children.first = NULL;
- curent->children.last = &curent->children.first;
-
- if (curent->subdirs.first != NULL) {
- *mvent->subdirs.last = curent->subdirs.first;
- mvent->subdirs.last = curent->subdirs.last;
- }
- mvent->subdirs.cnt = curent->subdirs.cnt;
- curent->subdirs.cnt = 0;
- curent->subdirs.first = NULL;
- curent->subdirs.last = &curent->subdirs.first;
-
- /*
- * The mvent becomes a child of the rr_moved entry.
- */
- isoent_add_child_tail(rrmoved, mvent);
- archive_entry_set_nlink(rrmoved->file->entry,
- archive_entry_nlink(rrmoved->file->entry) + 1);
- /*
- * This entry which relocated to the rr_moved directory
- * has to set the flag as a file.
- * See also RRIP 4.1.5.1 Description of the "CL" System Use Entry.
- */
- curent->dir = 0;
-
- *newent = mvent;
-
- return (ARCHIVE_OK);
-}
-
-static int
-isoent_rr_move(struct archive_write *a)
-{
- struct iso9660 *iso9660 = a->format_data;
- struct path_table *pt;
- struct isoent *rootent, *rr_moved;
- struct isoent *np, *last;
- int r;
-
- pt = &(iso9660->primary.pathtbl[MAX_DEPTH-1]);
- /* There aren't level 8 directories reaching a deeper level. */
- if (pt->cnt == 0)
- return (ARCHIVE_OK);
-
- rootent = iso9660->primary.rootent;
- /* If "rr_moved" directory is already existing,
- * we have to use it. */
- rr_moved = isoent_find_child(rootent, "rr_moved");
- if (rr_moved != NULL &&
- rr_moved != rootent->children.first) {
- /*
- * It's necessary that rr_move is the first entry
- * of the root.
- */
- /* Remove "rr_moved" entry from children chain. */
- isoent_remove_child(rootent, rr_moved);
-
- /* Add "rr_moved" entry into the head of children chain. */
- isoent_add_child_head(rootent, rr_moved);
- }
-
- /*
- * Check level 8 path_table.
- * If find out sub directory entries, that entries move to rr_move.
- */
- np = pt->first;
- while (np != NULL) {
- last = path_table_last_entry(pt);
- for (; np != NULL; np = np->ptnext) {
- struct isoent *mvent;
- struct isoent *newent;
-
- if (!np->dir)
- continue;
- for (mvent = np->subdirs.first;
- mvent != NULL; mvent = mvent->drnext) {
- r = isoent_rr_move_dir(a, &rr_moved,
- mvent, &newent);
- if (r < 0)
- return (r);
- isoent_collect_dirs(&(iso9660->primary),
- newent, 2);
- }
- }
- /* If new entries are added to level 8 path_talbe,
- * its sub directory entries move to rr_move too.
- */
- np = last->ptnext;
- }
-
- return (ARCHIVE_OK);
-}
-
-/*
- * This comparing rule is according to ISO9660 Standard 6.9.1
- */
-static int
-__LA_LIBC_CC
-_compare_path_table(const void *v1, const void *v2)
-{
- const struct isoent *p1, *p2;
- const char *s1, *s2;
- int cmp, l;
-
- p1 = *((const struct isoent **)(uintptr_t)v1);
- p2 = *((const struct isoent **)(uintptr_t)v2);
-
- /* Compare parent directory number */
- cmp = p1->parent->dir_number - p2->parent->dir_number;
- if (cmp != 0)
- return (cmp);
-
- /* Compare identifier */
- s1 = p1->identifier;
- s2 = p2->identifier;
- l = p1->ext_off;
- if (l > p2->ext_off)
- l = p2->ext_off;
- cmp = strncmp(s1, s2, l);
- if (cmp != 0)
- return (cmp);
- if (p1->ext_off < p2->ext_off) {
- s2 += l;
- l = p2->ext_off - p1->ext_off;
- while (l--)
- if (0x20 != *s2++)
- return (0x20
- - *(const unsigned char *)(s2 - 1));
- } else if (p1->ext_off > p2->ext_off) {
- s1 += l;
- l = p1->ext_off - p2->ext_off;
- while (l--)
- if (0x20 != *s1++)
- return (*(const unsigned char *)(s1 - 1)
- - 0x20);
- }
- return (0);
-}
-
-static int
-__LA_LIBC_CC
-_compare_path_table_joliet(const void *v1, const void *v2)
-{
- const struct isoent *p1, *p2;
- const unsigned char *s1, *s2;
- int cmp, l;
-
- p1 = *((const struct isoent **)(uintptr_t)v1);
- p2 = *((const struct isoent **)(uintptr_t)v2);
-
- /* Compare parent directory number */
- cmp = p1->parent->dir_number - p2->parent->dir_number;
- if (cmp != 0)
- return (cmp);
-
- /* Compare identifier */
- s1 = (const unsigned char *)p1->identifier;
- s2 = (const unsigned char *)p2->identifier;
- l = p1->ext_off;
- if (l > p2->ext_off)
- l = p2->ext_off;
- cmp = memcmp(s1, s2, l);
- if (cmp != 0)
- return (cmp);
- if (p1->ext_off < p2->ext_off) {
- s2 += l;
- l = p2->ext_off - p1->ext_off;
- while (l--)
- if (0 != *s2++)
- return (- *(const unsigned char *)(s2 - 1));
- } else if (p1->ext_off > p2->ext_off) {
- s1 += l;
- l = p1->ext_off - p2->ext_off;
- while (l--)
- if (0 != *s1++)
- return (*(const unsigned char *)(s1 - 1));
- }
- return (0);
-}
-
-static inline void
-path_table_add_entry(struct path_table *pathtbl, struct isoent *ent)
-{
- ent->ptnext = NULL;
- *pathtbl->last = ent;
- pathtbl->last = &(ent->ptnext);
- pathtbl->cnt ++;
-}
-
-static inline struct isoent *
-path_table_last_entry(struct path_table *pathtbl)
-{
- if (pathtbl->first == NULL)
- return (NULL);
- return (((struct isoent *)(void *)
- ((char *)(pathtbl->last) - offsetof(struct isoent, ptnext))));
-}
-
-/*
- * Sort directory entries in path_table
- * and assign directory number to each entries.
- */
-static int
-isoent_make_path_table_2(struct archive_write *a, struct vdd *vdd,
- int depth, int *dir_number)
-{
- struct isoent *np;
- struct isoent **enttbl;
- struct path_table *pt;
- int i;
-
- pt = &vdd->pathtbl[depth];
- if (pt->cnt == 0) {
- pt->sorted = NULL;
- return (ARCHIVE_OK);
- }
- enttbl = malloc(pt->cnt * sizeof(struct isoent *));
- if (enttbl == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- pt->sorted = enttbl;
- for (np = pt->first; np != NULL; np = np->ptnext)
- *enttbl ++ = np;
- enttbl = pt->sorted;
-
- switch (vdd->vdd_type) {
- case VDD_PRIMARY:
- case VDD_ENHANCED:
-#ifdef __COMPAR_FN_T
- qsort(enttbl, pt->cnt, sizeof(struct isoent *),
- (__compar_fn_t)_compare_path_table);
-#else
- qsort(enttbl, pt->cnt, sizeof(struct isoent *),
- _compare_path_table);
-#endif
- break;
- case VDD_JOLIET:
-#ifdef __COMPAR_FN_T
- qsort(enttbl, pt->cnt, sizeof(struct isoent *),
- (__compar_fn_t)_compare_path_table_joliet);
-#else
- qsort(enttbl, pt->cnt, sizeof(struct isoent *),
- _compare_path_table_joliet);
-#endif
- break;
- }
- for (i = 0; i < pt->cnt; i++)
- enttbl[i]->dir_number = (*dir_number)++;
-
- return (ARCHIVE_OK);
-}
-
-static int
-isoent_alloc_path_table(struct archive_write *a, struct vdd *vdd,
- int max_depth)
-{
- int i;
-
- vdd->max_depth = max_depth;
- vdd->pathtbl = malloc(sizeof(*vdd->pathtbl) * vdd->max_depth);
- if (vdd->pathtbl == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- for (i = 0; i < vdd->max_depth; i++) {
- vdd->pathtbl[i].first = NULL;
- vdd->pathtbl[i].last = &(vdd->pathtbl[i].first);
- vdd->pathtbl[i].sorted = NULL;
- vdd->pathtbl[i].cnt = 0;
- }
- return (ARCHIVE_OK);
-}
-
-/*
- * Make Path Tables
- */
-static int
-isoent_make_path_table(struct archive_write *a)
-{
- struct iso9660 *iso9660 = a->format_data;
- int depth, r;
- int dir_number;
-
- /*
- * Init Path Table.
- */
- if (iso9660->dircnt_max >= MAX_DEPTH &&
- (!iso9660->opt.limit_depth || iso9660->opt.iso_level == 4))
- r = isoent_alloc_path_table(a, &(iso9660->primary),
- iso9660->dircnt_max + 1);
- else
- /* The number of levels in the hierarchy cannot exceed
- * eight. */
- r = isoent_alloc_path_table(a, &(iso9660->primary),
- MAX_DEPTH);
- if (r < 0)
- return (r);
- if (iso9660->opt.joliet) {
- r = isoent_alloc_path_table(a, &(iso9660->joliet),
- iso9660->dircnt_max + 1);
- if (r < 0)
- return (r);
- }
-
- /* Step 0.
- * - Collect directories for primary and joliet.
- */
- isoent_collect_dirs(&(iso9660->primary), NULL, 0);
- if (iso9660->opt.joliet)
- isoent_collect_dirs(&(iso9660->joliet), NULL, 0);
- /*
- * Rockridge; move deeper depth directories to rr_moved.
- */
- if (iso9660->opt.rr) {
- r = isoent_rr_move(a);
- if (r < 0)
- return (r);
- }
-
- /* Update nlink. */
- isofile_connect_hardlink_files(iso9660);
-
- /* Step 1.
- * - Renew a value of the depth of that directories.
- * - Resolve hardlinks.
- * - Convert pathnames to ISO9660 name or UCS2(joliet).
- * - Sort files by each directory.
- */
- r = isoent_traverse_tree(a, &(iso9660->primary));
- if (r < 0)
- return (r);
- if (iso9660->opt.joliet) {
- r = isoent_traverse_tree(a, &(iso9660->joliet));
- if (r < 0)
- return (r);
- }
-
- /* Step 2.
- * - Sort directories.
- * - Assign all directory number.
- */
- dir_number = 1;
- for (depth = 0; depth < iso9660->primary.max_depth; depth++) {
- r = isoent_make_path_table_2(a, &(iso9660->primary),
- depth, &dir_number);
- if (r < 0)
- return (r);
- }
- if (iso9660->opt.joliet) {
- dir_number = 1;
- for (depth = 0; depth < iso9660->joliet.max_depth; depth++) {
- r = isoent_make_path_table_2(a, &(iso9660->joliet),
- depth, &dir_number);
- if (r < 0)
- return (r);
- }
- }
- if (iso9660->opt.limit_dirs && dir_number > 0xffff) {
- /*
- * Maximum number of directories is 65535(0xffff)
- * doe to size(16bit) of Parent Directory Number of
- * the Path Table.
- * See also ISO9660 Standard 9.4.
- */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Too many directories(%d) over 65535.", dir_number);
- return (ARCHIVE_FATAL);
- }
-
- /* Get the size of the Path Table. */
- calculate_path_table_size(&(iso9660->primary));
- if (iso9660->opt.joliet)
- calculate_path_table_size(&(iso9660->joliet));
-
- return (ARCHIVE_OK);
-}
-
-static int
-isoent_find_out_boot_file(struct archive_write *a, struct isoent *rootent)
-{
- struct iso9660 *iso9660 = a->format_data;
-
- /* Find a isoent of the boot file. */
- iso9660->el_torito.boot = isoent_find_entry(rootent,
- iso9660->el_torito.boot_filename.s);
- if (iso9660->el_torito.boot == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Can't find the boot image file ``%s''",
- iso9660->el_torito.boot_filename.s);
- return (ARCHIVE_FATAL);
- }
- iso9660->el_torito.boot->file->boot = BOOT_IMAGE;
- return (ARCHIVE_OK);
-}
-
-static int
-isoent_create_boot_catalog(struct archive_write *a, struct isoent *rootent)
-{
- struct iso9660 *iso9660 = a->format_data;
- struct isofile *file;
- struct isoent *isoent;
- struct archive_entry *entry;
-
- (void)rootent; /* UNUSED */
- /*
- * Create the entry which is the "boot.catalog" file.
- */
- file = isofile_new(a, NULL);
- if (file == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- archive_entry_set_pathname(file->entry,
- iso9660->el_torito.catalog_filename.s);
- archive_entry_set_size(file->entry, LOGICAL_BLOCK_SIZE);
- archive_entry_set_mtime(file->entry, iso9660->birth_time, 0);
- archive_entry_set_atime(file->entry, iso9660->birth_time, 0);
- archive_entry_set_ctime(file->entry, iso9660->birth_time, 0);
- archive_entry_set_uid(file->entry, getuid());
- archive_entry_set_gid(file->entry, getgid());
- archive_entry_set_mode(file->entry, AE_IFREG | 0444);
- archive_entry_set_nlink(file->entry, 1);
-
- if (isofile_gen_utility_names(a, file) < ARCHIVE_WARN) {
- isofile_free(file);
- return (ARCHIVE_FATAL);
- }
- file->boot = BOOT_CATALOG;
- file->content.size = LOGICAL_BLOCK_SIZE;
- isofile_add_entry(iso9660, file);
-
- isoent = isoent_new(file);
- if (isoent == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- isoent->virtual = 1;
-
- /* Add the "boot.catalog" entry into tree */
- if (isoent_tree(a, &isoent) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- iso9660->el_torito.catalog = isoent;
- /*
- * Get a boot media type.
- */
- switch (iso9660->opt.boot_type) {
- default:
- case OPT_BOOT_TYPE_AUTO:
- /* Try detecting a media type of the boot image. */
- entry = iso9660->el_torito.boot->file->entry;
- if (archive_entry_size(entry) == FD_1_2M_SIZE)
- iso9660->el_torito.media_type =
- BOOT_MEDIA_1_2M_DISKETTE;
- else if (archive_entry_size(entry) == FD_1_44M_SIZE)
- iso9660->el_torito.media_type =
- BOOT_MEDIA_1_44M_DISKETTE;
- else if (archive_entry_size(entry) == FD_2_88M_SIZE)
- iso9660->el_torito.media_type =
- BOOT_MEDIA_2_88M_DISKETTE;
- else
- /* We cannot decide whether the boot image is
- * hard-disk. */
- iso9660->el_torito.media_type =
- BOOT_MEDIA_NO_EMULATION;
- break;
- case OPT_BOOT_TYPE_NO_EMU:
- iso9660->el_torito.media_type = BOOT_MEDIA_NO_EMULATION;
- break;
- case OPT_BOOT_TYPE_HARD_DISK:
- iso9660->el_torito.media_type = BOOT_MEDIA_HARD_DISK;
- break;
- case OPT_BOOT_TYPE_FD:
- entry = iso9660->el_torito.boot->file->entry;
- if (archive_entry_size(entry) <= FD_1_2M_SIZE)
- iso9660->el_torito.media_type =
- BOOT_MEDIA_1_2M_DISKETTE;
- else if (archive_entry_size(entry) <= FD_1_44M_SIZE)
- iso9660->el_torito.media_type =
- BOOT_MEDIA_1_44M_DISKETTE;
- else if (archive_entry_size(entry) <= FD_2_88M_SIZE)
- iso9660->el_torito.media_type =
- BOOT_MEDIA_2_88M_DISKETTE;
- else {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Boot image file(``%s'') size is too big "
- "for fd type.",
- iso9660->el_torito.boot_filename.s);
- return (ARCHIVE_FATAL);
- }
- break;
- }
-
- /*
- * Get a system type.
- * TODO: `El Torito' specification says "A copy of byte 5 from the
- * Partition Table found in the boot image".
- */
- iso9660->el_torito.system_type = 0;
-
- /*
- * Get an ID.
- */
- if (iso9660->opt.publisher)
- archive_string_copy(&(iso9660->el_torito.id),
- &(iso9660->publisher_identifier));
-
-
- return (ARCHIVE_OK);
-}
-
-/*
- * If a media type is floppy, return its image size.
- * otherwise return 0.
- */
-static size_t
-fd_boot_image_size(int media_type)
-{
- switch (media_type) {
- case BOOT_MEDIA_1_2M_DISKETTE:
- return (FD_1_2M_SIZE);
- case BOOT_MEDIA_1_44M_DISKETTE:
- return (FD_1_44M_SIZE);
- case BOOT_MEDIA_2_88M_DISKETTE:
- return (FD_2_88M_SIZE);
- default:
- return (0);
- }
-}
-
-/*
- * Make a boot catalog image data.
- */
-static int
-make_boot_catalog(struct archive_write *a)
-{
- struct iso9660 *iso9660 = a->format_data;
- unsigned char *block;
- unsigned char *p;
- uint16_t sum, *wp;
-
- block = wb_buffptr(a);
- memset(block, 0, LOGICAL_BLOCK_SIZE);
- p = block;
- /*
- * Validation Entry
- */
- /* Header ID */
- p[0] = 1;
- /* Platform ID */
- p[1] = iso9660->el_torito.platform_id;
- /* Reserved */
- p[2] = p[3] = 0;
- /* ID */
- if (archive_strlen(&(iso9660->el_torito.id)) > 0)
- strncpy((char *)p+4, iso9660->el_torito.id.s, 23);
- p[27] = 0;
- /* Checksum */
- p[28] = p[29] = 0;
- /* Key */
- p[30] = 0x55;
- p[31] = 0xAA;
-
- sum = 0;
- wp = (uint16_t *)block;
- while (wp < (uint16_t *)&block[32])
- sum += archive_le16dec(wp++);
- set_num_721(&block[28], (~sum) + 1);
-
- /*
- * Initial/Default Entry
- */
- p = &block[32];
- /* Boot Indicator */
- p[0] = 0x88;
- /* Boot media type */
- p[1] = iso9660->el_torito.media_type;
- /* Load Segment */
- if (iso9660->el_torito.media_type == BOOT_MEDIA_NO_EMULATION)
- set_num_721(&p[2], iso9660->el_torito.boot_load_seg);
- else
- set_num_721(&p[2], 0);
- /* System Type */
- p[4] = iso9660->el_torito.system_type;
- /* Unused */
- p[5] = 0;
- /* Sector Count */
- if (iso9660->el_torito.media_type == BOOT_MEDIA_NO_EMULATION)
- set_num_721(&p[6], iso9660->el_torito.boot_load_size);
- else
- set_num_721(&p[6], 1);
- /* Load RBA */
- set_num_731(&p[8],
- iso9660->el_torito.boot->file->content.location);
- /* Unused */
- memset(&p[12], 0, 20);
-
- return (wb_consume(a, LOGICAL_BLOCK_SIZE));
-}
-
-static int
-setup_boot_information(struct archive_write *a)
-{
- struct iso9660 *iso9660 = a->format_data;
- struct isoent *np;
- int64_t size;
- uint32_t sum;
- unsigned char buff[4096];
-
- np = iso9660->el_torito.boot;
- lseek(iso9660->temp_fd,
- np->file->content.offset_of_temp + 64, SEEK_SET);
- size = archive_entry_size(np->file->entry) - 64;
- if (size <= 0) {
- archive_set_error(&a->archive, errno,
- "Boot file(%jd) is too small", (intmax_t)size + 64);
- return (ARCHIVE_FATAL);
- }
- sum = 0;
- while (size > 0) {
- size_t rsize;
- ssize_t i, rs;
-
- if (size > (int64_t)sizeof(buff))
- rsize = sizeof(buff);
- else
- rsize = (size_t)size;
-
- rs = read(iso9660->temp_fd, buff, rsize);
- if (rs <= 0) {
- archive_set_error(&a->archive, errno,
- "Can't read temporary file(%jd)",
- (intmax_t)rs);
- return (ARCHIVE_FATAL);
- }
- for (i = 0; i < rs; i += 4)
- sum += archive_le32dec(buff + i);
- size -= rs;
- }
- /* Set the location of Primary Volume Descriptor. */
- set_num_731(buff, SYSTEM_AREA_BLOCK);
- /* Set the location of the boot file. */
- set_num_731(buff+4, np->file->content.location);
- /* Set the size of the boot file. */
- size = fd_boot_image_size(iso9660->el_torito.media_type);
- if (size == 0)
- size = archive_entry_size(np->file->entry);
- set_num_731(buff+8, (uint32_t)size);
- /* Set the sum of the boot file. */
- set_num_731(buff+12, sum);
- /* Clear reserved bytes. */
- memset(buff+16, 0, 40);
-
- /* Overwrite the boot file. */
- lseek(iso9660->temp_fd,
- np->file->content.offset_of_temp + 8, SEEK_SET);
- return (write_to_temp(a, buff, 56));
-}
-
-#ifdef HAVE_ZLIB_H
-
-static int
-zisofs_init_zstream(struct archive_write *a)
-{
- struct iso9660 *iso9660 = a->format_data;
- int r;
-
- iso9660->zisofs.stream.next_in = NULL;
- iso9660->zisofs.stream.avail_in = 0;
- iso9660->zisofs.stream.total_in = 0;
- iso9660->zisofs.stream.total_out = 0;
- if (iso9660->zisofs.stream_valid)
- r = deflateReset(&(iso9660->zisofs.stream));
- else {
- r = deflateInit(&(iso9660->zisofs.stream),
- iso9660->zisofs.compression_level);
- iso9660->zisofs.stream_valid = 1;
- }
- switch (r) {
- case Z_OK:
- break;
- default:
- case Z_STREAM_ERROR:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Internal error initializing "
- "compression library: invalid setup parameter");
- return (ARCHIVE_FATAL);
- case Z_MEM_ERROR:
- archive_set_error(&a->archive, ENOMEM,
- "Internal error initializing "
- "compression library");
- return (ARCHIVE_FATAL);
- case Z_VERSION_ERROR:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Internal error initializing "
- "compression library: invalid library version");
- return (ARCHIVE_FATAL);
- }
- return (ARCHIVE_OK);
-}
-
-#endif /* HAVE_ZLIB_H */
-
-static int
-zisofs_init(struct archive_write *a, struct isofile *file)
-{
- struct iso9660 *iso9660 = a->format_data;
-#ifdef HAVE_ZLIB_H
- uint64_t tsize;
- size_t _ceil, bpsize;
- int r;
-#endif
-
- iso9660->zisofs.detect_magic = 0;
- iso9660->zisofs.making = 0;
-
- if (!iso9660->opt.rr || !iso9660->opt.zisofs)
- return (ARCHIVE_OK);
-
- if (archive_entry_size(file->entry) >= 24 &&
- archive_entry_size(file->entry) < MULTI_EXTENT_SIZE) {
- /* Acceptable file size for zisofs. */
- iso9660->zisofs.detect_magic = 1;
- iso9660->zisofs.magic_cnt = 0;
- }
- if (!iso9660->zisofs.detect_magic)
- return (ARCHIVE_OK);
-
-#ifdef HAVE_ZLIB_H
- /* The number of Logical Blocks which uncompressed data
- * will use in iso-image file is the same as the number of
- * Logical Blocks which zisofs(compressed) data will use
- * in ISO-image file. It won't reduce iso-image file size. */
- if (archive_entry_size(file->entry) <= LOGICAL_BLOCK_SIZE)
- return (ARCHIVE_OK);
-
- /* Initialize compression library */
- r = zisofs_init_zstream(a);
- if (r != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /* Mark file->zisofs to create RRIP 'ZF' Use Entry. */
- file->zisofs.header_size = ZF_HEADER_SIZE >> 2;
- file->zisofs.log2_bs = ZF_LOG2_BS;
- file->zisofs.uncompressed_size =
- (uint32_t)archive_entry_size(file->entry);
-
- /* Calculate a size of Block Pointers of zisofs. */
- _ceil = (file->zisofs.uncompressed_size + ZF_BLOCK_SIZE -1)
- >> file->zisofs.log2_bs;
- iso9660->zisofs.block_pointers_cnt = (int)_ceil + 1;
- iso9660->zisofs.block_pointers_idx = 0;
-
- /* Ensure a buffer size used for Block Pointers */
- bpsize = iso9660->zisofs.block_pointers_cnt *
- sizeof(iso9660->zisofs.block_pointers[0]);
- if (iso9660->zisofs.block_pointers_allocated < bpsize) {
- free(iso9660->zisofs.block_pointers);
- iso9660->zisofs.block_pointers = malloc(bpsize);
- if (iso9660->zisofs.block_pointers == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate data");
- return (ARCHIVE_FATAL);
- }
- iso9660->zisofs.block_pointers_allocated = bpsize;
- }
-
- /*
- * Skip zisofs header and Block Pointers, which we will write
- * after all compressed data of a file written to the temporary
- * file.
- */
- tsize = ZF_HEADER_SIZE + bpsize;
- if (write_null(a, (size_t)tsize) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /*
- * Initialize some variables to make zisofs.
- */
- archive_le32enc(&(iso9660->zisofs.block_pointers[0]),
- (uint32_t)tsize);
- iso9660->zisofs.remaining = file->zisofs.uncompressed_size;
- iso9660->zisofs.making = 1;
- iso9660->zisofs.allzero = 1;
- iso9660->zisofs.block_offset = tsize;
- iso9660->zisofs.total_size = tsize;
- iso9660->cur_file->cur_content->size = tsize;
-#endif
-
- return (ARCHIVE_OK);
-}
-
-static void
-zisofs_detect_magic(struct archive_write *a, const void *buff, size_t s)
-{
- struct iso9660 *iso9660 = a->format_data;
- struct isofile *file = iso9660->cur_file;
- const unsigned char *p, *endp;
- const unsigned char *magic_buff;
- uint32_t uncompressed_size;
- unsigned char header_size;
- unsigned char log2_bs;
- size_t _ceil, doff;
- uint32_t bst, bed;
- int magic_max;
- int64_t entry_size;
-
- entry_size = archive_entry_size(file->entry);
- if ((int64_t)sizeof(iso9660->zisofs.magic_buffer) > entry_size)
- magic_max = (int)entry_size;
- else
- magic_max = sizeof(iso9660->zisofs.magic_buffer);
-
- if (iso9660->zisofs.magic_cnt == 0 && s >= (size_t)magic_max)
- /* It's unnecessary we copy buffer. */
- magic_buff = buff;
- else {
- if (iso9660->zisofs.magic_cnt < magic_max) {
- size_t l;
-
- l = sizeof(iso9660->zisofs.magic_buffer)
- - iso9660->zisofs.magic_cnt;
- if (l > s)
- l = s;
- memcpy(iso9660->zisofs.magic_buffer
- + iso9660->zisofs.magic_cnt, buff, l);
- iso9660->zisofs.magic_cnt += (int)l;
- if (iso9660->zisofs.magic_cnt < magic_max)
- return;
- }
- magic_buff = iso9660->zisofs.magic_buffer;
- }
- iso9660->zisofs.detect_magic = 0;
- p = magic_buff;
-
- /* Check the magic code of zisofs. */
- if (memcmp(p, zisofs_magic, sizeof(zisofs_magic)) != 0)
- /* This is not zisofs file which made by mkzftree. */
- return;
- p += sizeof(zisofs_magic);
-
- /* Read a zisofs header. */
- uncompressed_size = archive_le32dec(p);
- header_size = p[4];
- log2_bs = p[5];
- if (uncompressed_size < 24 || header_size != 4 ||
- log2_bs > 30 || log2_bs < 7)
- return;/* Invalid or not supported header. */
-
- /* Calculate a size of Block Pointers of zisofs. */
- _ceil = (uncompressed_size +
- (ARCHIVE_LITERAL_LL(1) << log2_bs) -1) >> log2_bs;
- doff = (_ceil + 1) * 4 + 16;
- if (entry_size < (int64_t)doff)
- return;/* Invalid data. */
-
- /* Check every Block Pointer has valid value. */
- p = magic_buff + 16;
- endp = magic_buff + magic_max;
- while (_ceil && p + 8 <= endp) {
- bst = archive_le32dec(p);
- if (bst != doff)
- return;/* Invalid data. */
- p += 4;
- bed = archive_le32dec(p);
- if (bed < bst || bed > entry_size)
- return;/* Invalid data. */
- doff += bed - bst;
- _ceil--;
- }
-
- file->zisofs.uncompressed_size = uncompressed_size;
- file->zisofs.header_size = header_size;
- file->zisofs.log2_bs = log2_bs;
-
- /* Disable making a zisofs image. */
- iso9660->zisofs.making = 0;
-}
-
-#ifdef HAVE_ZLIB_H
-
-/*
- * Compress data and write it to a temporary file.
- */
-static int
-zisofs_write_to_temp(struct archive_write *a, const void *buff, size_t s)
-{
- struct iso9660 *iso9660 = a->format_data;
- struct isofile *file = iso9660->cur_file;
- const unsigned char *b;
- z_stream *zstrm;
- size_t avail, csize;
- int flush, r;
-
- zstrm = &(iso9660->zisofs.stream);
- zstrm->next_out = wb_buffptr(a);
- zstrm->avail_out = (uInt)wb_remaining(a);
- b = (const unsigned char *)buff;
- do {
- avail = ZF_BLOCK_SIZE - zstrm->total_in;
- if (s < avail) {
- avail = s;
- flush = Z_NO_FLUSH;
- } else
- flush = Z_FINISH;
- iso9660->zisofs.remaining -= avail;
- if (iso9660->zisofs.remaining <= 0)
- flush = Z_FINISH;
-
- zstrm->next_in = (Bytef *)(uintptr_t)(const void *)b;
- zstrm->avail_in = (uInt)avail;
-
- /*
- * Check if current data block are all zero.
- */
- if (iso9660->zisofs.allzero) {
- const unsigned char *nonzero = b;
- const unsigned char *nonzeroend = b + avail;
-
- while (nonzero < nonzeroend)
- if (*nonzero++) {
- iso9660->zisofs.allzero = 0;
- break;
- }
- }
- b += avail;
- s -= avail;
-
- /*
- * If current data block are all zero, we do not use
- * compressed data.
- */
- if (flush == Z_FINISH && iso9660->zisofs.allzero &&
- avail + zstrm->total_in == ZF_BLOCK_SIZE) {
- if (iso9660->zisofs.block_offset !=
- file->cur_content->size) {
- int64_t diff;
-
- r = wb_set_offset(a,
- file->cur_content->offset_of_temp +
- iso9660->zisofs.block_offset);
- if (r != ARCHIVE_OK)
- return (r);
- diff = file->cur_content->size -
- iso9660->zisofs.block_offset;
- file->cur_content->size -= diff;
- iso9660->zisofs.total_size -= diff;
- }
- zstrm->avail_in = 0;
- }
-
- /*
- * Compress file data.
- */
- while (zstrm->avail_in > 0) {
- csize = zstrm->total_out;
- r = deflate(zstrm, flush);
- switch (r) {
- case Z_OK:
- case Z_STREAM_END:
- csize = zstrm->total_out - csize;
- if (wb_consume(a, csize) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- iso9660->zisofs.total_size += csize;
- iso9660->cur_file->cur_content->size += csize;
- zstrm->next_out = wb_buffptr(a);
- zstrm->avail_out = (uInt)wb_remaining(a);
- break;
- default:
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Compression failed:"
- " deflate() call returned status %d",
- r);
- return (ARCHIVE_FATAL);
- }
- }
-
- if (flush == Z_FINISH) {
- /*
- * Save the information of one zisofs block.
- */
- iso9660->zisofs.block_pointers_idx ++;
- archive_le32enc(&(iso9660->zisofs.block_pointers[
- iso9660->zisofs.block_pointers_idx]),
- (uint32_t)iso9660->zisofs.total_size);
- r = zisofs_init_zstream(a);
- if (r != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- iso9660->zisofs.allzero = 1;
- iso9660->zisofs.block_offset = file->cur_content->size;
- }
- } while (s);
-
- return (ARCHIVE_OK);
-}
-
-static int
-zisofs_finish_entry(struct archive_write *a)
-{
- struct iso9660 *iso9660 = a->format_data;
- struct isofile *file = iso9660->cur_file;
- unsigned char buff[16];
- size_t s;
- int64_t tail;
-
- /* Direct temp file stream to zisofs temp file stream. */
- archive_entry_set_size(file->entry, iso9660->zisofs.total_size);
-
- /*
- * Save a file pointer which points the end of current zisofs data.
- */
- tail = wb_offset(a);
-
- /*
- * Make a header.
- *
- * +-----------------+----------------+-----------------+
- * | Header 16 bytes | Block Pointers | Compressed data |
- * +-----------------+----------------+-----------------+
- * 0 16 +X
- * Block Pointers :
- * 4 * (((Uncompressed file size + block_size -1) / block_size) + 1)
- *
- * Write zisofs header.
- * Magic number
- * +----+----+----+----+----+----+----+----+
- * | 37 | E4 | 53 | 96 | C9 | DB | D6 | 07 |
- * +----+----+----+----+----+----+----+----+
- * 0 1 2 3 4 5 6 7 8
- *
- * +------------------------+------------------+
- * | Uncompressed file size | header_size >> 2 |
- * +------------------------+------------------+
- * 8 12 13
- *
- * +-----------------+----------------+
- * | log2 block_size | Reserved(0000) |
- * +-----------------+----------------+
- * 13 14 16
- */
- memcpy(buff, zisofs_magic, 8);
- set_num_731(buff+8, file->zisofs.uncompressed_size);
- buff[12] = file->zisofs.header_size;
- buff[13] = file->zisofs.log2_bs;
- buff[14] = buff[15] = 0;/* Reserved */
-
- /* Move to the right position to write the header. */
- wb_set_offset(a, file->content.offset_of_temp);
-
- /* Write the header. */
- if (wb_write_to_temp(a, buff, 16) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /*
- * Write zisofs Block Pointers.
- */
- s = iso9660->zisofs.block_pointers_cnt *
- sizeof(iso9660->zisofs.block_pointers[0]);
- if (wb_write_to_temp(a, iso9660->zisofs.block_pointers, s)
- != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /* Set a file pointer back to the end of the temporary file. */
- wb_set_offset(a, tail);
-
- return (ARCHIVE_OK);
-}
-
-static int
-zisofs_free(struct archive_write *a)
-{
- struct iso9660 *iso9660 = a->format_data;
- int ret = ARCHIVE_OK;
-
- free(iso9660->zisofs.block_pointers);
- if (iso9660->zisofs.stream_valid &&
- deflateEnd(&(iso9660->zisofs.stream)) != Z_OK) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Failed to clean up compressor");
- ret = ARCHIVE_FATAL;
- }
- iso9660->zisofs.block_pointers = NULL;
- iso9660->zisofs.stream_valid = 0;
- return (ret);
-}
-
-struct zisofs_extract {
- int pz_log2_bs; /* Log2 of block size */
- uint64_t pz_uncompressed_size;
- size_t uncompressed_buffer_size;
-
- unsigned int initialized:1;
- unsigned int header_passed:1;
-
- uint32_t pz_offset;
- unsigned char *block_pointers;
- size_t block_pointers_size;
- size_t block_pointers_avail;
- size_t block_off;
- uint32_t block_avail;
-
- z_stream stream;
- int stream_valid;
-};
-
-static ssize_t
-zisofs_extract_init(struct archive_write *a, struct zisofs_extract *zisofs,
- const unsigned char *p, size_t bytes)
-{
- size_t avail = bytes;
- size_t _ceil, xsize;
-
- /* Allocate block pointers buffer. */
- _ceil = (size_t)((zisofs->pz_uncompressed_size +
- (((int64_t)1) << zisofs->pz_log2_bs) - 1)
- >> zisofs->pz_log2_bs);
- xsize = (_ceil + 1) * 4;
- if (zisofs->block_pointers == NULL) {
- size_t alloc = ((xsize >> 10) + 1) << 10;
- zisofs->block_pointers = malloc(alloc);
- if (zisofs->block_pointers == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for zisofs decompression");
- return (ARCHIVE_FATAL);
- }
- }
- zisofs->block_pointers_size = xsize;
-
- /* Allocate uncompressed data buffer. */
- zisofs->uncompressed_buffer_size = (size_t)1UL << zisofs->pz_log2_bs;
-
- /*
- * Read the file header, and check the magic code of zisofs.
- */
- if (!zisofs->header_passed) {
- int err = 0;
- if (avail < 16) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Illegal zisofs file body");
- return (ARCHIVE_FATAL);
- }
-
- if (memcmp(p, zisofs_magic, sizeof(zisofs_magic)) != 0)
- err = 1;
- else if (archive_le32dec(p + 8) != zisofs->pz_uncompressed_size)
- err = 1;
- else if (p[12] != 4 || p[13] != zisofs->pz_log2_bs)
- err = 1;
- if (err) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Illegal zisofs file body");
- return (ARCHIVE_FATAL);
- }
- avail -= 16;
- p += 16;
- zisofs->header_passed = 1;
- }
-
- /*
- * Read block pointers.
- */
- if (zisofs->header_passed &&
- zisofs->block_pointers_avail < zisofs->block_pointers_size) {
- xsize = zisofs->block_pointers_size
- - zisofs->block_pointers_avail;
- if (avail < xsize)
- xsize = avail;
- memcpy(zisofs->block_pointers
- + zisofs->block_pointers_avail, p, xsize);
- zisofs->block_pointers_avail += xsize;
- avail -= xsize;
- if (zisofs->block_pointers_avail
- == zisofs->block_pointers_size) {
- /* We've got all block pointers and initialize
- * related variables. */
- zisofs->block_off = 0;
- zisofs->block_avail = 0;
- /* Complete a initialization */
- zisofs->initialized = 1;
- }
- }
- return ((ssize_t)avail);
-}
-
-static ssize_t
-zisofs_extract(struct archive_write *a, struct zisofs_extract *zisofs,
- const unsigned char *p, size_t bytes)
-{
- size_t avail;
- int r;
-
- if (!zisofs->initialized) {
- ssize_t rs = zisofs_extract_init(a, zisofs, p, bytes);
- if (rs < 0)
- return (rs);
- if (!zisofs->initialized) {
- /* We need more data. */
- zisofs->pz_offset += (uint32_t)bytes;
- return (bytes);
- }
- avail = rs;
- p += bytes - avail;
- } else
- avail = bytes;
-
- /*
- * Get block offsets from block pointers.
- */
- if (zisofs->block_avail == 0) {
- uint32_t bst, bed;
-
- if (zisofs->block_off + 4 >= zisofs->block_pointers_size) {
- /* There isn't a pair of offsets. */
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Illegal zisofs block pointers");
- return (ARCHIVE_FATAL);
- }
- bst = archive_le32dec(
- zisofs->block_pointers + zisofs->block_off);
- if (bst != zisofs->pz_offset + (bytes - avail)) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Illegal zisofs block pointers(cannot seek)");
- return (ARCHIVE_FATAL);
- }
- bed = archive_le32dec(
- zisofs->block_pointers + zisofs->block_off + 4);
- if (bed < bst) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Illegal zisofs block pointers");
- return (ARCHIVE_FATAL);
- }
- zisofs->block_avail = bed - bst;
- zisofs->block_off += 4;
-
- /* Initialize compression library for new block. */
- if (zisofs->stream_valid)
- r = inflateReset(&zisofs->stream);
- else
- r = inflateInit(&zisofs->stream);
- if (r != Z_OK) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Can't initialize zisofs decompression.");
- return (ARCHIVE_FATAL);
- }
- zisofs->stream_valid = 1;
- zisofs->stream.total_in = 0;
- zisofs->stream.total_out = 0;
- }
-
- /*
- * Make uncompressed data.
- */
- if (zisofs->block_avail == 0) {
- /*
- * It's basically 32K bytes NUL data.
- */
- unsigned char *wb;
- size_t size, wsize;
-
- size = zisofs->uncompressed_buffer_size;
- while (size) {
- wb = wb_buffptr(a);
- if (size > wb_remaining(a))
- wsize = wb_remaining(a);
- else
- wsize = size;
- memset(wb, 0, wsize);
- r = wb_consume(a, wsize);
- if (r < 0)
- return (r);
- size -= wsize;
- }
- } else {
- zisofs->stream.next_in = (Bytef *)(uintptr_t)(const void *)p;
- if (avail > zisofs->block_avail)
- zisofs->stream.avail_in = zisofs->block_avail;
- else
- zisofs->stream.avail_in = (uInt)avail;
- zisofs->stream.next_out = wb_buffptr(a);
- zisofs->stream.avail_out = (uInt)wb_remaining(a);
-
- r = inflate(&zisofs->stream, 0);
- switch (r) {
- case Z_OK: /* Decompressor made some progress.*/
- case Z_STREAM_END: /* Found end of stream. */
- break;
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "zisofs decompression failed (%d)", r);
- return (ARCHIVE_FATAL);
- }
- avail -= zisofs->stream.next_in - p;
- zisofs->block_avail -= (uint32_t)(zisofs->stream.next_in - p);
- r = wb_consume(a, wb_remaining(a) - zisofs->stream.avail_out);
- if (r < 0)
- return (r);
- }
- zisofs->pz_offset += (uint32_t)bytes;
- return (bytes - avail);
-}
-
-static int
-zisofs_rewind_boot_file(struct archive_write *a)
-{
- struct iso9660 *iso9660 = a->format_data;
- struct isofile *file;
- unsigned char *rbuff;
- ssize_t r;
- size_t remaining, rbuff_size;
- struct zisofs_extract zext;
- int64_t read_offset, write_offset, new_offset;
- int fd, ret = ARCHIVE_OK;
-
- file = iso9660->el_torito.boot->file;
- /*
- * There is nothing to do if this boot file does not have
- * zisofs header.
- */
- if (file->zisofs.header_size == 0)
- return (ARCHIVE_OK);
-
- /*
- * Uncompress the zisofs'ed file contents.
- */
- memset(&zext, 0, sizeof(zext));
- zext.pz_uncompressed_size = file->zisofs.uncompressed_size;
- zext.pz_log2_bs = file->zisofs.log2_bs;
-
- fd = iso9660->temp_fd;
- new_offset = wb_offset(a);
- read_offset = file->content.offset_of_temp;
- remaining = (size_t)file->content.size;
- if (remaining > 1024 * 32)
- rbuff_size = 1024 * 32;
- else
- rbuff_size = remaining;
-
- rbuff = malloc(rbuff_size);
- if (rbuff == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- while (remaining) {
- size_t rsize;
- ssize_t rs;
-
- /* Get the current file pointer. */
- write_offset = lseek(fd, 0, SEEK_CUR);
-
- /* Change the file pointer to read. */
- lseek(fd, read_offset, SEEK_SET);
-
- rsize = rbuff_size;
- if (rsize > remaining)
- rsize = remaining;
- rs = read(iso9660->temp_fd, rbuff, rsize);
- if (rs <= 0) {
- archive_set_error(&a->archive, errno,
- "Can't read temporary file(%jd)", (intmax_t)rs);
- ret = ARCHIVE_FATAL;
- break;
- }
- remaining -= rs;
- read_offset += rs;
-
- /* Put the file pointer back to write. */
- lseek(fd, write_offset, SEEK_SET);
-
- r = zisofs_extract(a, &zext, rbuff, rs);
- if (r < 0) {
- ret = (int)r;
- break;
- }
- }
-
- if (ret == ARCHIVE_OK) {
- /*
- * Change the boot file content from zisofs'ed data
- * to plain data.
- */
- file->content.offset_of_temp = new_offset;
- file->content.size = file->zisofs.uncompressed_size;
- archive_entry_set_size(file->entry, file->content.size);
- /* Set to be no zisofs. */
- file->zisofs.header_size = 0;
- file->zisofs.log2_bs = 0;
- file->zisofs.uncompressed_size = 0;
- r = wb_write_padding_to_temp(a, file->content.size);
- if (r < 0)
- ret = ARCHIVE_FATAL;
- }
-
- /*
- * Free the resource we used in this function only.
- */
- free(rbuff);
- free(zext.block_pointers);
- if (zext.stream_valid && inflateEnd(&(zext.stream)) != Z_OK) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Failed to clean up compressor");
- ret = ARCHIVE_FATAL;
- }
-
- return (ret);
-}
-
-#else
-
-static int
-zisofs_write_to_temp(struct archive_write *a, const void *buff, size_t s)
-{
- (void)buff; /* UNUSED */
- (void)s; /* UNUSED */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Programming error");
- return (ARCHIVE_FATAL);
-}
-
-static int
-zisofs_rewind_boot_file(struct archive_write *a)
-{
- struct iso9660 *iso9660 = a->format_data;
-
- if (iso9660->el_torito.boot->file->zisofs.header_size != 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "We cannot extract the zisofs imaged boot file;"
- " this may not boot in being zisofs imaged");
- return (ARCHIVE_FAILED);
- }
- return (ARCHIVE_OK);
-}
-
-static int
-zisofs_finish_entry(struct archive_write *a)
-{
- (void)a; /* UNUSED */
- return (ARCHIVE_OK);
-}
-
-static int
-zisofs_free(struct archive_write *a)
-{
- (void)a; /* UNUSED */
- return (ARCHIVE_OK);
-}
-
-#endif /* HAVE_ZLIB_H */
-
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_format_mtree.c b/contrib/libs/libarchive/libarchive/archive_write_set_format_mtree.c
deleted file mode 100644
index 619b7714ee..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_format_mtree.c
+++ /dev/null
@@ -1,2217 +0,0 @@
-/*-
- * Copyright (c) 2008 Joerg Sonnenberger
- * Copyright (c) 2009-2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_mtree.c 201171 2009-12-29 06:39:07Z kientzle $");
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "archive.h"
-#include "archive_digest_private.h"
-#include "archive_entry.h"
-#include "archive_entry_private.h"
-#include "archive_private.h"
-#include "archive_rb.h"
-#include "archive_string.h"
-#include "archive_write_private.h"
-
-#define INDENTNAMELEN 15
-#define MAXLINELEN 80
-#define SET_KEYS \
- (F_FLAGS | F_GID | F_GNAME | F_MODE | F_TYPE | F_UID | F_UNAME)
-
-struct attr_counter {
- struct attr_counter *prev;
- struct attr_counter *next;
- struct mtree_entry *m_entry;
- int count;
-};
-
-struct att_counter_set {
- struct attr_counter *uid_list;
- struct attr_counter *gid_list;
- struct attr_counter *mode_list;
- struct attr_counter *flags_list;
-};
-
-struct mtree_chain {
- struct mtree_entry *first;
- struct mtree_entry **last;
-};
-
-/*
- * The Data only for a directory file.
- */
-struct dir_info {
- struct archive_rb_tree rbtree;
- struct mtree_chain children;
- struct mtree_entry *chnext;
- int virtual;
-};
-
-/*
- * The Data only for a regular file.
- */
-struct reg_info {
- int compute_sum;
- uint32_t crc;
- struct ae_digest digest;
-};
-
-struct mtree_entry {
- struct archive_rb_node rbnode;
- struct mtree_entry *next;
- struct mtree_entry *parent;
- struct dir_info *dir_info;
- struct reg_info *reg_info;
-
- struct archive_string parentdir;
- struct archive_string basename;
- struct archive_string pathname;
- struct archive_string symlink;
- struct archive_string uname;
- struct archive_string gname;
- struct archive_string fflags_text;
- unsigned int nlink;
- mode_t filetype;
- mode_t mode;
- int64_t size;
- int64_t uid;
- int64_t gid;
- time_t mtime;
- long mtime_nsec;
- unsigned long fflags_set;
- unsigned long fflags_clear;
- dev_t rdevmajor;
- dev_t rdevminor;
- dev_t devmajor;
- dev_t devminor;
- int64_t ino;
-};
-
-struct mtree_writer {
- struct mtree_entry *mtree_entry;
- struct mtree_entry *root;
- struct mtree_entry *cur_dirent;
- struct archive_string cur_dirstr;
- struct mtree_chain file_list;
-
- struct archive_string ebuf;
- struct archive_string buf;
- int first;
- uint64_t entry_bytes_remaining;
-
- /*
- * Set global value.
- */
- struct {
- int processing;
- mode_t type;
- int keys;
- int64_t uid;
- int64_t gid;
- mode_t mode;
- unsigned long fflags_set;
- unsigned long fflags_clear;
- } set;
- struct att_counter_set acs;
- int classic;
- int depth;
-
- /* check sum */
- int compute_sum;
- uint32_t crc;
- uint64_t crc_len;
-#ifdef ARCHIVE_HAS_MD5
- archive_md5_ctx md5ctx;
-#endif
-#ifdef ARCHIVE_HAS_RMD160
- archive_rmd160_ctx rmd160ctx;
-#endif
-#ifdef ARCHIVE_HAS_SHA1
- archive_sha1_ctx sha1ctx;
-#endif
-#ifdef ARCHIVE_HAS_SHA256
- archive_sha256_ctx sha256ctx;
-#endif
-#ifdef ARCHIVE_HAS_SHA384
- archive_sha384_ctx sha384ctx;
-#endif
-#ifdef ARCHIVE_HAS_SHA512
- archive_sha512_ctx sha512ctx;
-#endif
- /* Keyword options */
- int keys;
-#define F_CKSUM 0x00000001 /* checksum */
-#define F_DEV 0x00000002 /* device type */
-#define F_DONE 0x00000004 /* directory done */
-#define F_FLAGS 0x00000008 /* file flags */
-#define F_GID 0x00000010 /* gid */
-#define F_GNAME 0x00000020 /* group name */
-#define F_IGN 0x00000040 /* ignore */
-#define F_MAGIC 0x00000080 /* name has magic chars */
-#define F_MD5 0x00000100 /* MD5 digest */
-#define F_MODE 0x00000200 /* mode */
-#define F_NLINK 0x00000400 /* number of links */
-#define F_NOCHANGE 0x00000800 /* If owner/mode "wrong", do
- * not change */
-#define F_OPT 0x00001000 /* existence optional */
-#define F_RMD160 0x00002000 /* RIPEMD160 digest */
-#define F_SHA1 0x00004000 /* SHA-1 digest */
-#define F_SIZE 0x00008000 /* size */
-#define F_SLINK 0x00010000 /* symbolic link */
-#define F_TAGS 0x00020000 /* tags */
-#define F_TIME 0x00040000 /* modification time */
-#define F_TYPE 0x00080000 /* file type */
-#define F_UID 0x00100000 /* uid */
-#define F_UNAME 0x00200000 /* user name */
-#define F_VISIT 0x00400000 /* file visited */
-#define F_SHA256 0x00800000 /* SHA-256 digest */
-#define F_SHA384 0x01000000 /* SHA-384 digest */
-#define F_SHA512 0x02000000 /* SHA-512 digest */
-#define F_INO 0x04000000 /* inode number */
-#define F_RESDEV 0x08000000 /* device ID on which the
- * entry resides */
-
- /* Options */
- int dironly; /* If it is set, ignore all files except
- * directory files, like mtree(8) -d option. */
- int indent; /* If it is set, indent output data. */
- int output_global_set; /* If it is set, use /set keyword to set
- * global values. When generating mtree
- * classic format, it is set by default. */
-};
-
-#define DEFAULT_KEYS (F_DEV | F_FLAGS | F_GID | F_GNAME | F_SLINK | F_MODE\
- | F_NLINK | F_SIZE | F_TIME | F_TYPE | F_UID\
- | F_UNAME)
-#define attr_counter_set_reset attr_counter_set_free
-
-static void attr_counter_free(struct attr_counter **);
-static int attr_counter_inc(struct attr_counter **, struct attr_counter *,
- struct attr_counter *, struct mtree_entry *);
-static struct attr_counter * attr_counter_new(struct mtree_entry *,
- struct attr_counter *);
-static int attr_counter_set_collect(struct mtree_writer *,
- struct mtree_entry *);
-static void attr_counter_set_free(struct mtree_writer *);
-static int get_global_set_keys(struct mtree_writer *, struct mtree_entry *);
-static int mtree_entry_add_child_tail(struct mtree_entry *,
- struct mtree_entry *);
-static int mtree_entry_create_virtual_dir(struct archive_write *, const char *,
- struct mtree_entry **);
-static int mtree_entry_cmp_node(const struct archive_rb_node *,
- const struct archive_rb_node *);
-static int mtree_entry_cmp_key(const struct archive_rb_node *, const void *);
-static int mtree_entry_exchange_same_entry(struct archive_write *,
- struct mtree_entry *, struct mtree_entry *);
-static void mtree_entry_free(struct mtree_entry *);
-static int mtree_entry_new(struct archive_write *, struct archive_entry *,
- struct mtree_entry **);
-static void mtree_entry_register_free(struct mtree_writer *);
-static void mtree_entry_register_init(struct mtree_writer *);
-static int mtree_entry_setup_filenames(struct archive_write *,
- struct mtree_entry *, struct archive_entry *);
-static int mtree_entry_tree_add(struct archive_write *, struct mtree_entry **);
-static void sum_init(struct mtree_writer *);
-static void sum_update(struct mtree_writer *, const void *, size_t);
-static void sum_final(struct mtree_writer *, struct reg_info *);
-static void sum_write(struct archive_string *, struct reg_info *);
-static int write_mtree_entry(struct archive_write *, struct mtree_entry *);
-static int write_dot_dot_entry(struct archive_write *, struct mtree_entry *);
-
-#define COMPUTE_CRC(var, ch) (var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)]
-static const uint32_t crctab[] = {
- 0x0,
- 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
- 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
- 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
- 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
- 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
- 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
- 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
- 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
- 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
- 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
- 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
- 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
- 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
- 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
- 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
- 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
- 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
- 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
- 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
- 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
- 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
- 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
- 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
- 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
- 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
- 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
- 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
- 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
- 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
- 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
- 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
- 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
- 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
- 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
- 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
- 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
- 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
- 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
- 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
- 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
- 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
- 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
- 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
- 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
- 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
- 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
- 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
- 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
- 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
- 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
- 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
-};
-
-static const unsigned char safe_char[256] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */
- /* !"$%&'()*+,-./ EXCLUSION:0x20( ) 0x23(#) */
- 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */
- /* 0123456789:;<>? EXCLUSION:0x3d(=) */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, /* 30 - 3F */
- /* @ABCDEFGHIJKLMNO */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */
- /* PQRSTUVWXYZ[]^_ EXCLUSION:0x5c(\) */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, /* 50 - 5F */
- /* `abcdefghijklmno */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */
- /* pqrstuvwxyz{|}~ */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* 70 - 7F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */
-};
-
-static void
-mtree_quote(struct archive_string *s, const char *str)
-{
- const char *start;
- char buf[4];
- unsigned char c;
-
- for (start = str; *str != '\0'; ++str) {
- if (safe_char[*(const unsigned char *)str])
- continue;
- if (start != str)
- archive_strncat(s, start, str - start);
- c = (unsigned char)*str;
- buf[0] = '\\';
- buf[1] = (c / 64) + '0';
- buf[2] = (c / 8 % 8) + '0';
- buf[3] = (c % 8) + '0';
- archive_strncat(s, buf, 4);
- start = str + 1;
- }
-
- if (start != str)
- archive_strncat(s, start, str - start);
-}
-
-/*
- * Indent a line as the mtree utility does so it is readable for people.
- */
-static void
-mtree_indent(struct mtree_writer *mtree)
-{
- int i, fn, nd, pd;
- const char *r, *s, *x;
-
- if (mtree->classic) {
- if (mtree->indent) {
- nd = 0;
- pd = mtree->depth * 4;
- } else {
- nd = mtree->depth?4:0;
- pd = 0;
- }
- } else
- nd = pd = 0;
- fn = 1;
- s = r = mtree->ebuf.s;
- x = NULL;
- while (*r == ' ')
- r++;
- while ((r = strchr(r, ' ')) != NULL) {
- if (fn) {
- fn = 0;
- for (i = 0; i < nd + pd; i++)
- archive_strappend_char(&mtree->buf, ' ');
- archive_strncat(&mtree->buf, s, r - s);
- if (nd + (r -s) > INDENTNAMELEN) {
- archive_strncat(&mtree->buf, " \\\n", 3);
- for (i = 0; i < (INDENTNAMELEN + 1 + pd); i++)
- archive_strappend_char(&mtree->buf, ' ');
- } else {
- for (i = (int)(r -s + nd);
- i < (INDENTNAMELEN + 1); i++)
- archive_strappend_char(&mtree->buf, ' ');
- }
- s = ++r;
- x = NULL;
- continue;
- }
- if (pd + (r - s) <= MAXLINELEN - 3 - INDENTNAMELEN)
- x = r++;
- else {
- if (x == NULL)
- x = r;
- archive_strncat(&mtree->buf, s, x - s);
- archive_strncat(&mtree->buf, " \\\n", 3);
- for (i = 0; i < (INDENTNAMELEN + 1 + pd); i++)
- archive_strappend_char(&mtree->buf, ' ');
- s = r = ++x;
- x = NULL;
- }
- }
- if (fn) {
- for (i = 0; i < nd + pd; i++)
- archive_strappend_char(&mtree->buf, ' ');
- archive_strcat(&mtree->buf, s);
- s += strlen(s);
- }
- if (x != NULL && pd + strlen(s) > MAXLINELEN - 3 - INDENTNAMELEN) {
- /* Last keyword is longer. */
- archive_strncat(&mtree->buf, s, x - s);
- archive_strncat(&mtree->buf, " \\\n", 3);
- for (i = 0; i < (INDENTNAMELEN + 1 + pd); i++)
- archive_strappend_char(&mtree->buf, ' ');
- s = ++x;
- }
- archive_strcat(&mtree->buf, s);
- archive_string_empty(&mtree->ebuf);
-}
-
-/*
- * Write /set keyword.
- * Set the most used value of uid, gid, mode and fflags, which are
- * collected by the attr_counter_set_collect() function.
- */
-static void
-write_global(struct mtree_writer *mtree)
-{
- struct archive_string setstr;
- struct archive_string unsetstr;
- struct att_counter_set *acs;
- int keys, oldkeys, effkeys;
-
- archive_string_init(&setstr);
- archive_string_init(&unsetstr);
- keys = mtree->keys & SET_KEYS;
- oldkeys = mtree->set.keys;
- effkeys = keys;
- acs = &mtree->acs;
- if (mtree->set.processing) {
- /*
- * Check if the global data needs updating.
- */
- effkeys &= ~F_TYPE;
- if (acs->uid_list == NULL)
- effkeys &= ~(F_UNAME | F_UID);
- else if (oldkeys & (F_UNAME | F_UID)) {
- if (acs->uid_list->count < 2 ||
- mtree->set.uid == acs->uid_list->m_entry->uid)
- effkeys &= ~(F_UNAME | F_UID);
- }
- if (acs->gid_list == NULL)
- effkeys &= ~(F_GNAME | F_GID);
- else if (oldkeys & (F_GNAME | F_GID)) {
- if (acs->gid_list->count < 2 ||
- mtree->set.gid == acs->gid_list->m_entry->gid)
- effkeys &= ~(F_GNAME | F_GID);
- }
- if (acs->mode_list == NULL)
- effkeys &= ~F_MODE;
- else if (oldkeys & F_MODE) {
- if (acs->mode_list->count < 2 ||
- mtree->set.mode == acs->mode_list->m_entry->mode)
- effkeys &= ~F_MODE;
- }
- if (acs->flags_list == NULL)
- effkeys &= ~F_FLAGS;
- else if ((oldkeys & F_FLAGS) != 0) {
- if (acs->flags_list->count < 2 ||
- (acs->flags_list->m_entry->fflags_set ==
- mtree->set.fflags_set &&
- acs->flags_list->m_entry->fflags_clear ==
- mtree->set.fflags_clear))
- effkeys &= ~F_FLAGS;
- }
- } else {
- if (acs->uid_list == NULL)
- keys &= ~(F_UNAME | F_UID);
- if (acs->gid_list == NULL)
- keys &= ~(F_GNAME | F_GID);
- if (acs->mode_list == NULL)
- keys &= ~F_MODE;
- if (acs->flags_list == NULL)
- keys &= ~F_FLAGS;
- }
- if ((keys & effkeys & F_TYPE) != 0) {
- if (mtree->dironly) {
- archive_strcat(&setstr, " type=dir");
- mtree->set.type = AE_IFDIR;
- } else {
- archive_strcat(&setstr, " type=file");
- mtree->set.type = AE_IFREG;
- }
- }
- if ((keys & effkeys & F_UNAME) != 0) {
- if (archive_strlen(&(acs->uid_list->m_entry->uname)) > 0) {
- archive_strcat(&setstr, " uname=");
- mtree_quote(&setstr, acs->uid_list->m_entry->uname.s);
- } else {
- keys &= ~F_UNAME;
- if ((oldkeys & F_UNAME) != 0)
- archive_strcat(&unsetstr, " uname");
- }
- }
- if ((keys & effkeys & F_UID) != 0) {
- mtree->set.uid = acs->uid_list->m_entry->uid;
- archive_string_sprintf(&setstr, " uid=%jd",
- (intmax_t)mtree->set.uid);
- }
- if ((keys & effkeys & F_GNAME) != 0) {
- if (archive_strlen(&(acs->gid_list->m_entry->gname)) > 0) {
- archive_strcat(&setstr, " gname=");
- mtree_quote(&setstr, acs->gid_list->m_entry->gname.s);
- } else {
- keys &= ~F_GNAME;
- if ((oldkeys & F_GNAME) != 0)
- archive_strcat(&unsetstr, " gname");
- }
- }
- if ((keys & effkeys & F_GID) != 0) {
- mtree->set.gid = acs->gid_list->m_entry->gid;
- archive_string_sprintf(&setstr, " gid=%jd",
- (intmax_t)mtree->set.gid);
- }
- if ((keys & effkeys & F_MODE) != 0) {
- mtree->set.mode = acs->mode_list->m_entry->mode;
- archive_string_sprintf(&setstr, " mode=%o",
- (unsigned int)mtree->set.mode);
- }
- if ((keys & effkeys & F_FLAGS) != 0) {
- if (archive_strlen(
- &(acs->flags_list->m_entry->fflags_text)) > 0) {
- archive_strcat(&setstr, " flags=");
- mtree_quote(&setstr,
- acs->flags_list->m_entry->fflags_text.s);
- mtree->set.fflags_set =
- acs->flags_list->m_entry->fflags_set;
- mtree->set.fflags_clear =
- acs->flags_list->m_entry->fflags_clear;
- } else {
- keys &= ~F_FLAGS;
- if ((oldkeys & F_FLAGS) != 0)
- archive_strcat(&unsetstr, " flags");
- }
- }
- if (unsetstr.length > 0)
- archive_string_sprintf(&mtree->buf, "/unset%s\n", unsetstr.s);
- archive_string_free(&unsetstr);
- if (setstr.length > 0)
- archive_string_sprintf(&mtree->buf, "/set%s\n", setstr.s);
- archive_string_free(&setstr);
- mtree->set.keys = keys;
- mtree->set.processing = 1;
-}
-
-static struct attr_counter *
-attr_counter_new(struct mtree_entry *me, struct attr_counter *prev)
-{
- struct attr_counter *ac;
-
- ac = malloc(sizeof(*ac));
- if (ac != NULL) {
- ac->prev = prev;
- ac->next = NULL;
- ac->count = 1;
- ac->m_entry = me;
- }
- return (ac);
-}
-
-static void
-attr_counter_free(struct attr_counter **top)
-{
- struct attr_counter *ac, *tac;
-
- if (*top == NULL)
- return;
- ac = *top;
- while (ac != NULL) {
- tac = ac->next;
- free(ac);
- ac = tac;
- }
- *top = NULL;
-}
-
-static int
-attr_counter_inc(struct attr_counter **top, struct attr_counter *ac,
- struct attr_counter *last, struct mtree_entry *me)
-{
- struct attr_counter *pac;
-
- if (ac != NULL) {
- ac->count++;
- if (*top == ac || ac->prev->count >= ac->count)
- return (0);
- for (pac = ac->prev; pac; pac = pac->prev) {
- if (pac->count >= ac->count)
- break;
- }
- ac->prev->next = ac->next;
- if (ac->next != NULL)
- ac->next->prev = ac->prev;
- if (pac != NULL) {
- ac->prev = pac;
- ac->next = pac->next;
- pac->next = ac;
- if (ac->next != NULL)
- ac->next->prev = ac;
- } else {
- ac->prev = NULL;
- ac->next = *top;
- *top = ac;
- ac->next->prev = ac;
- }
- } else if (last != NULL) {
- ac = attr_counter_new(me, last);
- if (ac == NULL)
- return (-1);
- last->next = ac;
- }
- return (0);
-}
-
-/*
- * Tabulate uid, gid, mode and fflags of a entry in order to be used for /set.
- */
-static int
-attr_counter_set_collect(struct mtree_writer *mtree, struct mtree_entry *me)
-{
- struct attr_counter *ac, *last;
- struct att_counter_set *acs = &mtree->acs;
- int keys = mtree->keys;
-
- if (keys & (F_UNAME | F_UID)) {
- if (acs->uid_list == NULL) {
- acs->uid_list = attr_counter_new(me, NULL);
- if (acs->uid_list == NULL)
- return (-1);
- } else {
- last = NULL;
- for (ac = acs->uid_list; ac; ac = ac->next) {
- if (ac->m_entry->uid == me->uid)
- break;
- last = ac;
- }
- if (attr_counter_inc(&acs->uid_list, ac, last, me) < 0)
- return (-1);
- }
- }
- if (keys & (F_GNAME | F_GID)) {
- if (acs->gid_list == NULL) {
- acs->gid_list = attr_counter_new(me, NULL);
- if (acs->gid_list == NULL)
- return (-1);
- } else {
- last = NULL;
- for (ac = acs->gid_list; ac; ac = ac->next) {
- if (ac->m_entry->gid == me->gid)
- break;
- last = ac;
- }
- if (attr_counter_inc(&acs->gid_list, ac, last, me) < 0)
- return (-1);
- }
- }
- if (keys & F_MODE) {
- if (acs->mode_list == NULL) {
- acs->mode_list = attr_counter_new(me, NULL);
- if (acs->mode_list == NULL)
- return (-1);
- } else {
- last = NULL;
- for (ac = acs->mode_list; ac; ac = ac->next) {
- if (ac->m_entry->mode == me->mode)
- break;
- last = ac;
- }
- if (attr_counter_inc(&acs->mode_list, ac, last, me) < 0)
- return (-1);
- }
- }
- if (keys & F_FLAGS) {
- if (acs->flags_list == NULL) {
- acs->flags_list = attr_counter_new(me, NULL);
- if (acs->flags_list == NULL)
- return (-1);
- } else {
- last = NULL;
- for (ac = acs->flags_list; ac; ac = ac->next) {
- if (ac->m_entry->fflags_set == me->fflags_set &&
- ac->m_entry->fflags_clear ==
- me->fflags_clear)
- break;
- last = ac;
- }
- if (attr_counter_inc(&acs->flags_list, ac, last, me) < 0)
- return (-1);
- }
- }
-
- return (0);
-}
-
-static void
-attr_counter_set_free(struct mtree_writer *mtree)
-{
- struct att_counter_set *acs = &mtree->acs;
-
- attr_counter_free(&acs->uid_list);
- attr_counter_free(&acs->gid_list);
- attr_counter_free(&acs->mode_list);
- attr_counter_free(&acs->flags_list);
-}
-
-static int
-get_global_set_keys(struct mtree_writer *mtree, struct mtree_entry *me)
-{
- int keys;
-
- keys = mtree->keys;
-
- /*
- * If a keyword has been set by /set, we do not need to
- * output it.
- */
- if (mtree->set.keys == 0)
- return (keys);/* /set is not used. */
-
- if ((mtree->set.keys & (F_GNAME | F_GID)) != 0 &&
- mtree->set.gid == me->gid)
- keys &= ~(F_GNAME | F_GID);
- if ((mtree->set.keys & (F_UNAME | F_UID)) != 0 &&
- mtree->set.uid == me->uid)
- keys &= ~(F_UNAME | F_UID);
- if (mtree->set.keys & F_FLAGS) {
- if (mtree->set.fflags_set == me->fflags_set &&
- mtree->set.fflags_clear == me->fflags_clear)
- keys &= ~F_FLAGS;
- }
- if ((mtree->set.keys & F_MODE) != 0 && mtree->set.mode == me->mode)
- keys &= ~F_MODE;
-
- switch (me->filetype) {
- case AE_IFLNK: case AE_IFSOCK: case AE_IFCHR:
- case AE_IFBLK: case AE_IFIFO:
- break;
- case AE_IFDIR:
- if ((mtree->set.keys & F_TYPE) != 0 &&
- mtree->set.type == AE_IFDIR)
- keys &= ~F_TYPE;
- break;
- case AE_IFREG:
- default: /* Handle unknown file types as regular files. */
- if ((mtree->set.keys & F_TYPE) != 0 &&
- mtree->set.type == AE_IFREG)
- keys &= ~F_TYPE;
- break;
- }
-
- return (keys);
-}
-
-static int
-mtree_entry_new(struct archive_write *a, struct archive_entry *entry,
- struct mtree_entry **m_entry)
-{
- struct mtree_entry *me;
- const char *s;
- int r;
- static const struct archive_rb_tree_ops rb_ops = {
- mtree_entry_cmp_node, mtree_entry_cmp_key
- };
-
- me = calloc(1, sizeof(*me));
- if (me == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for a mtree entry");
- *m_entry = NULL;
- return (ARCHIVE_FATAL);
- }
-
- r = mtree_entry_setup_filenames(a, me, entry);
- if (r < ARCHIVE_WARN) {
- mtree_entry_free(me);
- *m_entry = NULL;
- return (r);
- }
-
- if ((s = archive_entry_symlink(entry)) != NULL)
- archive_strcpy(&me->symlink, s);
- me->nlink = archive_entry_nlink(entry);
- me->filetype = archive_entry_filetype(entry);
- me->mode = archive_entry_mode(entry) & 07777;
- me->uid = archive_entry_uid(entry);
- me->gid = archive_entry_gid(entry);
- if ((s = archive_entry_uname(entry)) != NULL)
- archive_strcpy(&me->uname, s);
- if ((s = archive_entry_gname(entry)) != NULL)
- archive_strcpy(&me->gname, s);
- if ((s = archive_entry_fflags_text(entry)) != NULL)
- archive_strcpy(&me->fflags_text, s);
- archive_entry_fflags(entry, &me->fflags_set, &me->fflags_clear);
- me->mtime = archive_entry_mtime(entry);
- me->mtime_nsec = archive_entry_mtime_nsec(entry);
- me->rdevmajor = archive_entry_rdevmajor(entry);
- me->rdevminor = archive_entry_rdevminor(entry);
- me->devmajor = archive_entry_devmajor(entry);
- me->devminor = archive_entry_devminor(entry);
- me->ino = archive_entry_ino(entry);
- me->size = archive_entry_size(entry);
- if (me->filetype == AE_IFDIR) {
- me->dir_info = calloc(1, sizeof(*me->dir_info));
- if (me->dir_info == NULL) {
- mtree_entry_free(me);
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for a mtree entry");
- *m_entry = NULL;
- return (ARCHIVE_FATAL);
- }
- __archive_rb_tree_init(&me->dir_info->rbtree, &rb_ops);
- me->dir_info->children.first = NULL;
- me->dir_info->children.last = &(me->dir_info->children.first);
- me->dir_info->chnext = NULL;
- } else if (me->filetype == AE_IFREG) {
- me->reg_info = calloc(1, sizeof(*me->reg_info));
- if (me->reg_info == NULL) {
- mtree_entry_free(me);
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for a mtree entry");
- *m_entry = NULL;
- return (ARCHIVE_FATAL);
- }
- me->reg_info->compute_sum = 0;
- }
-
- *m_entry = me;
- return (ARCHIVE_OK);
-}
-
-static void
-mtree_entry_free(struct mtree_entry *me)
-{
- archive_string_free(&me->parentdir);
- archive_string_free(&me->basename);
- archive_string_free(&me->pathname);
- archive_string_free(&me->symlink);
- archive_string_free(&me->uname);
- archive_string_free(&me->gname);
- archive_string_free(&me->fflags_text);
- free(me->dir_info);
- free(me->reg_info);
- free(me);
-}
-
-static int
-archive_write_mtree_header(struct archive_write *a,
- struct archive_entry *entry)
-{
- struct mtree_writer *mtree= a->format_data;
- struct mtree_entry *mtree_entry;
- int r, r2;
-
- if (mtree->first) {
- mtree->first = 0;
- archive_strcat(&mtree->buf, "#mtree\n");
- if ((mtree->keys & SET_KEYS) == 0)
- mtree->output_global_set = 0;/* Disabled. */
- }
-
- mtree->entry_bytes_remaining = archive_entry_size(entry);
-
- /* While directory only mode, we do not handle non directory files. */
- if (mtree->dironly && archive_entry_filetype(entry) != AE_IFDIR)
- return (ARCHIVE_OK);
-
- r2 = mtree_entry_new(a, entry, &mtree_entry);
- if (r2 < ARCHIVE_WARN)
- return (r2);
- r = mtree_entry_tree_add(a, &mtree_entry);
- if (r < ARCHIVE_WARN) {
- mtree_entry_free(mtree_entry);
- return (r);
- }
- mtree->mtree_entry = mtree_entry;
-
- /* If the current file is a regular file, we have to
- * compute the sum of its content.
- * Initialize a bunch of checksum context. */
- if (mtree_entry->reg_info)
- sum_init(mtree);
-
- return (r2);
-}
-
-static int
-write_mtree_entry(struct archive_write *a, struct mtree_entry *me)
-{
- struct mtree_writer *mtree = a->format_data;
- struct archive_string *str;
- int keys, ret;
-
- if (me->dir_info) {
- if (mtree->classic) {
- /*
- * Output a comment line to describe the full
- * pathname of the entry as mtree utility does
- * while generating classic format.
- */
- if (!mtree->dironly)
- archive_strappend_char(&mtree->buf, '\n');
- if (me->parentdir.s)
- archive_string_sprintf(&mtree->buf,
- "# %s/%s\n",
- me->parentdir.s, me->basename.s);
- else
- archive_string_sprintf(&mtree->buf,
- "# %s\n",
- me->basename.s);
- }
- if (mtree->output_global_set)
- write_global(mtree);
- }
- archive_string_empty(&mtree->ebuf);
- str = (mtree->indent || mtree->classic)? &mtree->ebuf : &mtree->buf;
-
- if (!mtree->classic && me->parentdir.s) {
- /*
- * If generating format is not classic one(v1), output
- * a full pathname.
- */
- mtree_quote(str, me->parentdir.s);
- archive_strappend_char(str, '/');
- }
- mtree_quote(str, me->basename.s);
-
- keys = get_global_set_keys(mtree, me);
- if ((keys & F_NLINK) != 0 &&
- me->nlink != 1 && me->filetype != AE_IFDIR)
- archive_string_sprintf(str, " nlink=%u", me->nlink);
-
- if ((keys & F_GNAME) != 0 && archive_strlen(&me->gname) > 0) {
- archive_strcat(str, " gname=");
- mtree_quote(str, me->gname.s);
- }
- if ((keys & F_UNAME) != 0 && archive_strlen(&me->uname) > 0) {
- archive_strcat(str, " uname=");
- mtree_quote(str, me->uname.s);
- }
- if ((keys & F_FLAGS) != 0) {
- if (archive_strlen(&me->fflags_text) > 0) {
- archive_strcat(str, " flags=");
- mtree_quote(str, me->fflags_text.s);
- } else if (mtree->set.processing &&
- (mtree->set.keys & F_FLAGS) != 0)
- /* Overwrite the global parameter. */
- archive_strcat(str, " flags=none");
- }
- if ((keys & F_TIME) != 0)
- archive_string_sprintf(str, " time=%jd.%jd",
- (intmax_t)me->mtime, (intmax_t)me->mtime_nsec);
- if ((keys & F_MODE) != 0)
- archive_string_sprintf(str, " mode=%o", (unsigned int)me->mode);
- if ((keys & F_GID) != 0)
- archive_string_sprintf(str, " gid=%jd", (intmax_t)me->gid);
- if ((keys & F_UID) != 0)
- archive_string_sprintf(str, " uid=%jd", (intmax_t)me->uid);
-
- if ((keys & F_INO) != 0)
- archive_string_sprintf(str, " inode=%jd", (intmax_t)me->ino);
- if ((keys & F_RESDEV) != 0) {
- archive_string_sprintf(str,
- " resdevice=native,%ju,%ju",
- (uintmax_t)me->devmajor,
- (uintmax_t)me->devminor);
- }
-
- switch (me->filetype) {
- case AE_IFLNK:
- if ((keys & F_TYPE) != 0)
- archive_strcat(str, " type=link");
- if ((keys & F_SLINK) != 0) {
- archive_strcat(str, " link=");
- mtree_quote(str, me->symlink.s);
- }
- break;
- case AE_IFSOCK:
- if ((keys & F_TYPE) != 0)
- archive_strcat(str, " type=socket");
- break;
- case AE_IFCHR:
- if ((keys & F_TYPE) != 0)
- archive_strcat(str, " type=char");
- if ((keys & F_DEV) != 0) {
- archive_string_sprintf(str,
- " device=native,%ju,%ju",
- (uintmax_t)me->rdevmajor,
- (uintmax_t)me->rdevminor);
- }
- break;
- case AE_IFBLK:
- if ((keys & F_TYPE) != 0)
- archive_strcat(str, " type=block");
- if ((keys & F_DEV) != 0) {
- archive_string_sprintf(str,
- " device=native,%ju,%ju",
- (uintmax_t)me->rdevmajor,
- (uintmax_t)me->rdevminor);
- }
- break;
- case AE_IFDIR:
- if ((keys & F_TYPE) != 0)
- archive_strcat(str, " type=dir");
- break;
- case AE_IFIFO:
- if ((keys & F_TYPE) != 0)
- archive_strcat(str, " type=fifo");
- break;
- case AE_IFREG:
- default: /* Handle unknown file types as regular files. */
- if ((keys & F_TYPE) != 0)
- archive_strcat(str, " type=file");
- if ((keys & F_SIZE) != 0)
- archive_string_sprintf(str, " size=%jd",
- (intmax_t)me->size);
- break;
- }
-
- /* Write a bunch of sum. */
- if (me->reg_info)
- sum_write(str, me->reg_info);
-
- archive_strappend_char(str, '\n');
- if (mtree->indent || mtree->classic)
- mtree_indent(mtree);
-
- if (mtree->buf.length > 32768) {
- ret = __archive_write_output(
- a, mtree->buf.s, mtree->buf.length);
- archive_string_empty(&mtree->buf);
- } else
- ret = ARCHIVE_OK;
- return (ret);
-}
-
-static int
-write_dot_dot_entry(struct archive_write *a, struct mtree_entry *n)
-{
- struct mtree_writer *mtree = a->format_data;
- int ret;
-
- if (n->parentdir.s) {
- if (mtree->indent) {
- int i, pd = mtree->depth * 4;
- for (i = 0; i < pd; i++)
- archive_strappend_char(&mtree->buf, ' ');
- }
- archive_string_sprintf(&mtree->buf, "# %s/%s\n",
- n->parentdir.s, n->basename.s);
- }
-
- if (mtree->indent) {
- archive_string_empty(&mtree->ebuf);
- archive_strncat(&mtree->ebuf, "..\n\n", (mtree->dironly)?3:4);
- mtree_indent(mtree);
- } else
- archive_strncat(&mtree->buf, "..\n\n", (mtree->dironly)?3:4);
-
- if (mtree->buf.length > 32768) {
- ret = __archive_write_output(
- a, mtree->buf.s, mtree->buf.length);
- archive_string_empty(&mtree->buf);
- } else
- ret = ARCHIVE_OK;
- return (ret);
-}
-
-/*
- * Write mtree entries saved at attr_counter_set_collect() function.
- */
-static int
-write_mtree_entry_tree(struct archive_write *a)
-{
- struct mtree_writer *mtree = a->format_data;
- struct mtree_entry *np = mtree->root;
- struct archive_rb_node *n;
- int ret;
-
- do {
- if (mtree->output_global_set) {
- /*
- * Collect attribute information to know which value
- * is frequently used among the children.
- */
- attr_counter_set_reset(mtree);
- ARCHIVE_RB_TREE_FOREACH(n, &(np->dir_info->rbtree)) {
- struct mtree_entry *e = (struct mtree_entry *)n;
- if (attr_counter_set_collect(mtree, e) < 0) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- }
- }
- if (!np->dir_info->virtual || mtree->classic) {
- ret = write_mtree_entry(a, np);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- } else {
- /* Whenever output_global_set is enabled
- * output global value(/set keywords)
- * even if the directory entry is not allowed
- * to be written because the global values
- * can be used for the children. */
- if (mtree->output_global_set)
- write_global(mtree);
- }
- /*
- * Output the attribute of all files except directory files.
- */
- mtree->depth++;
- ARCHIVE_RB_TREE_FOREACH(n, &(np->dir_info->rbtree)) {
- struct mtree_entry *e = (struct mtree_entry *)n;
-
- if (e->dir_info)
- mtree_entry_add_child_tail(np, e);
- else {
- ret = write_mtree_entry(a, e);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- }
- }
- mtree->depth--;
-
- if (np->dir_info->children.first != NULL) {
- /*
- * Descend the tree.
- */
- np = np->dir_info->children.first;
- if (mtree->indent)
- mtree->depth++;
- continue;
- } else if (mtree->classic) {
- /*
- * While printing mtree classic, if there are not
- * any directory files(except "." and "..") in the
- * directory, output two dots ".." as returning
- * the parent directory.
- */
- ret = write_dot_dot_entry(a, np);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- }
-
- while (np != np->parent) {
- if (np->dir_info->chnext == NULL) {
- /*
- * Ascend the tree; go back to the parent.
- */
- if (mtree->indent)
- mtree->depth--;
- if (mtree->classic) {
- ret = write_dot_dot_entry(a,
- np->parent);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- }
- np = np->parent;
- } else {
- /*
- * Switch to next mtree entry in the directory.
- */
- np = np->dir_info->chnext;
- break;
- }
- }
- } while (np != np->parent);
-
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_mtree_finish_entry(struct archive_write *a)
-{
- struct mtree_writer *mtree = a->format_data;
- struct mtree_entry *me;
-
- if ((me = mtree->mtree_entry) == NULL)
- return (ARCHIVE_OK);
- mtree->mtree_entry = NULL;
-
- if (me->reg_info)
- sum_final(mtree, me->reg_info);
-
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_mtree_close(struct archive_write *a)
-{
- struct mtree_writer *mtree= a->format_data;
- int ret;
-
- if (mtree->root != NULL) {
- ret = write_mtree_entry_tree(a);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- }
-
- archive_write_set_bytes_in_last_block(&a->archive, 1);
-
- return __archive_write_output(a, mtree->buf.s, mtree->buf.length);
-}
-
-static ssize_t
-archive_write_mtree_data(struct archive_write *a, const void *buff, size_t n)
-{
- struct mtree_writer *mtree= a->format_data;
-
- if (n > mtree->entry_bytes_remaining)
- n = (size_t)mtree->entry_bytes_remaining;
- mtree->entry_bytes_remaining -= n;
-
- /* We don't need to compute a regular file sum */
- if (mtree->mtree_entry == NULL)
- return (n);
-
- if (mtree->mtree_entry->filetype == AE_IFREG)
- sum_update(mtree, buff, n);
-
- return (n);
-}
-
-static int
-archive_write_mtree_free(struct archive_write *a)
-{
- struct mtree_writer *mtree= a->format_data;
-
- if (mtree == NULL)
- return (ARCHIVE_OK);
-
- /* Make sure we do not leave any entries. */
- mtree_entry_register_free(mtree);
- archive_string_free(&mtree->cur_dirstr);
- archive_string_free(&mtree->ebuf);
- archive_string_free(&mtree->buf);
- attr_counter_set_free(mtree);
- free(mtree);
- a->format_data = NULL;
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_mtree_options(struct archive_write *a, const char *key,
- const char *value)
-{
- struct mtree_writer *mtree= a->format_data;
- int keybit = 0;
-
- switch (key[0]) {
- case 'a':
- if (strcmp(key, "all") == 0)
- keybit = ~0;
- break;
- case 'c':
- if (strcmp(key, "cksum") == 0)
- keybit = F_CKSUM;
- break;
- case 'd':
- if (strcmp(key, "device") == 0)
- keybit = F_DEV;
- else if (strcmp(key, "dironly") == 0) {
- mtree->dironly = (value != NULL)? 1: 0;
- return (ARCHIVE_OK);
- }
- break;
- case 'f':
- if (strcmp(key, "flags") == 0)
- keybit = F_FLAGS;
- break;
- case 'g':
- if (strcmp(key, "gid") == 0)
- keybit = F_GID;
- else if (strcmp(key, "gname") == 0)
- keybit = F_GNAME;
- break;
- case 'i':
- if (strcmp(key, "indent") == 0) {
- mtree->indent = (value != NULL)? 1: 0;
- return (ARCHIVE_OK);
- } else if (strcmp(key, "inode") == 0) {
- keybit = F_INO;
- }
- break;
- case 'l':
- if (strcmp(key, "link") == 0)
- keybit = F_SLINK;
- break;
- case 'm':
- if (strcmp(key, "md5") == 0 ||
- strcmp(key, "md5digest") == 0)
- keybit = F_MD5;
- if (strcmp(key, "mode") == 0)
- keybit = F_MODE;
- break;
- case 'n':
- if (strcmp(key, "nlink") == 0)
- keybit = F_NLINK;
- break;
- case 'r':
- if (strcmp(key, "resdevice") == 0) {
- keybit = F_RESDEV;
- } else if (strcmp(key, "ripemd160digest") == 0 ||
- strcmp(key, "rmd160") == 0 ||
- strcmp(key, "rmd160digest") == 0)
- keybit = F_RMD160;
- break;
- case 's':
- if (strcmp(key, "sha1") == 0 ||
- strcmp(key, "sha1digest") == 0)
- keybit = F_SHA1;
- if (strcmp(key, "sha256") == 0 ||
- strcmp(key, "sha256digest") == 0)
- keybit = F_SHA256;
- if (strcmp(key, "sha384") == 0 ||
- strcmp(key, "sha384digest") == 0)
- keybit = F_SHA384;
- if (strcmp(key, "sha512") == 0 ||
- strcmp(key, "sha512digest") == 0)
- keybit = F_SHA512;
- if (strcmp(key, "size") == 0)
- keybit = F_SIZE;
- break;
- case 't':
- if (strcmp(key, "time") == 0)
- keybit = F_TIME;
- else if (strcmp(key, "type") == 0)
- keybit = F_TYPE;
- break;
- case 'u':
- if (strcmp(key, "uid") == 0)
- keybit = F_UID;
- else if (strcmp(key, "uname") == 0)
- keybit = F_UNAME;
- else if (strcmp(key, "use-set") == 0) {
- mtree->output_global_set = (value != NULL)? 1: 0;
- return (ARCHIVE_OK);
- }
- break;
- }
- if (keybit != 0) {
- if (value != NULL)
- mtree->keys |= keybit;
- else
- mtree->keys &= ~keybit;
- return (ARCHIVE_OK);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-static int
-archive_write_set_format_mtree_default(struct archive *_a, const char *fn)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct mtree_writer *mtree;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_NEW, fn);
-
- if (a->format_free != NULL)
- (a->format_free)(a);
-
- if ((mtree = calloc(1, sizeof(*mtree))) == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate mtree data");
- return (ARCHIVE_FATAL);
- }
-
- mtree->mtree_entry = NULL;
- mtree->first = 1;
- memset(&(mtree->set), 0, sizeof(mtree->set));
- mtree->keys = DEFAULT_KEYS;
- mtree->dironly = 0;
- mtree->indent = 0;
- archive_string_init(&mtree->ebuf);
- archive_string_init(&mtree->buf);
- mtree_entry_register_init(mtree);
- a->format_data = mtree;
- a->format_free = archive_write_mtree_free;
- a->format_name = "mtree";
- a->format_options = archive_write_mtree_options;
- a->format_write_header = archive_write_mtree_header;
- a->format_close = archive_write_mtree_close;
- a->format_write_data = archive_write_mtree_data;
- a->format_finish_entry = archive_write_mtree_finish_entry;
- a->archive.archive_format = ARCHIVE_FORMAT_MTREE;
- a->archive.archive_format_name = "mtree";
-
- return (ARCHIVE_OK);
-}
-
-int
-archive_write_set_format_mtree(struct archive *_a)
-{
- return archive_write_set_format_mtree_default(_a,
- "archive_write_set_format_mtree");
-}
-
-int
-archive_write_set_format_mtree_classic(struct archive *_a)
-{
- int r;
-
- r = archive_write_set_format_mtree_default(_a,
- "archive_write_set_format_mtree_classic");
- if (r == ARCHIVE_OK) {
- struct archive_write *a = (struct archive_write *)_a;
- struct mtree_writer *mtree;
-
- mtree = (struct mtree_writer *)a->format_data;
-
- /* Set to output a mtree archive in classic format. */
- mtree->classic = 1;
- /* Basically, mtree classic format uses '/set' global
- * value. */
- mtree->output_global_set = 1;
- }
- return (r);
-}
-
-static void
-sum_init(struct mtree_writer *mtree)
-{
-
- mtree->compute_sum = 0;
-
- if (mtree->keys & F_CKSUM) {
- mtree->compute_sum |= F_CKSUM;
- mtree->crc = 0;
- mtree->crc_len = 0;
- }
-#ifdef ARCHIVE_HAS_MD5
- if (mtree->keys & F_MD5) {
- if (archive_md5_init(&mtree->md5ctx) == ARCHIVE_OK)
- mtree->compute_sum |= F_MD5;
- else
- mtree->keys &= ~F_MD5;/* Not supported. */
- }
-#endif
-#ifdef ARCHIVE_HAS_RMD160
- if (mtree->keys & F_RMD160) {
- if (archive_rmd160_init(&mtree->rmd160ctx) == ARCHIVE_OK)
- mtree->compute_sum |= F_RMD160;
- else
- mtree->keys &= ~F_RMD160;/* Not supported. */
- }
-#endif
-#ifdef ARCHIVE_HAS_SHA1
- if (mtree->keys & F_SHA1) {
- if (archive_sha1_init(&mtree->sha1ctx) == ARCHIVE_OK)
- mtree->compute_sum |= F_SHA1;
- else
- mtree->keys &= ~F_SHA1;/* Not supported. */
- }
-#endif
-#ifdef ARCHIVE_HAS_SHA256
- if (mtree->keys & F_SHA256) {
- if (archive_sha256_init(&mtree->sha256ctx) == ARCHIVE_OK)
- mtree->compute_sum |= F_SHA256;
- else
- mtree->keys &= ~F_SHA256;/* Not supported. */
- }
-#endif
-#ifdef ARCHIVE_HAS_SHA384
- if (mtree->keys & F_SHA384) {
- if (archive_sha384_init(&mtree->sha384ctx) == ARCHIVE_OK)
- mtree->compute_sum |= F_SHA384;
- else
- mtree->keys &= ~F_SHA384;/* Not supported. */
- }
-#endif
-#ifdef ARCHIVE_HAS_SHA512
- if (mtree->keys & F_SHA512) {
- if (archive_sha512_init(&mtree->sha512ctx) == ARCHIVE_OK)
- mtree->compute_sum |= F_SHA512;
- else
- mtree->keys &= ~F_SHA512;/* Not supported. */
- }
-#endif
-}
-
-static void
-sum_update(struct mtree_writer *mtree, const void *buff, size_t n)
-{
- if (mtree->compute_sum & F_CKSUM) {
- /*
- * Compute a POSIX 1003.2 checksum
- */
- const unsigned char *p;
- size_t nn;
-
- for (nn = n, p = buff; nn--; ++p)
- COMPUTE_CRC(mtree->crc, *p);
- mtree->crc_len += n;
- }
-#ifdef ARCHIVE_HAS_MD5
- if (mtree->compute_sum & F_MD5)
- archive_md5_update(&mtree->md5ctx, buff, n);
-#endif
-#ifdef ARCHIVE_HAS_RMD160
- if (mtree->compute_sum & F_RMD160)
- archive_rmd160_update(&mtree->rmd160ctx, buff, n);
-#endif
-#ifdef ARCHIVE_HAS_SHA1
- if (mtree->compute_sum & F_SHA1)
- archive_sha1_update(&mtree->sha1ctx, buff, n);
-#endif
-#ifdef ARCHIVE_HAS_SHA256
- if (mtree->compute_sum & F_SHA256)
- archive_sha256_update(&mtree->sha256ctx, buff, n);
-#endif
-#ifdef ARCHIVE_HAS_SHA384
- if (mtree->compute_sum & F_SHA384)
- archive_sha384_update(&mtree->sha384ctx, buff, n);
-#endif
-#ifdef ARCHIVE_HAS_SHA512
- if (mtree->compute_sum & F_SHA512)
- archive_sha512_update(&mtree->sha512ctx, buff, n);
-#endif
-}
-
-static void
-sum_final(struct mtree_writer *mtree, struct reg_info *reg)
-{
-
- if (mtree->compute_sum & F_CKSUM) {
- uint64_t len;
- /* Include the length of the file. */
- for (len = mtree->crc_len; len != 0; len >>= 8)
- COMPUTE_CRC(mtree->crc, len & 0xff);
- reg->crc = ~mtree->crc;
- }
-#ifdef ARCHIVE_HAS_MD5
- if (mtree->compute_sum & F_MD5)
- archive_md5_final(&mtree->md5ctx, reg->digest.md5);
-#endif
-#ifdef ARCHIVE_HAS_RMD160
- if (mtree->compute_sum & F_RMD160)
- archive_rmd160_final(&mtree->rmd160ctx, reg->digest.rmd160);
-#endif
-#ifdef ARCHIVE_HAS_SHA1
- if (mtree->compute_sum & F_SHA1)
- archive_sha1_final(&mtree->sha1ctx, reg->digest.sha1);
-#endif
-#ifdef ARCHIVE_HAS_SHA256
- if (mtree->compute_sum & F_SHA256)
- archive_sha256_final(&mtree->sha256ctx, reg->digest.sha256);
-#endif
-#ifdef ARCHIVE_HAS_SHA384
- if (mtree->compute_sum & F_SHA384)
- archive_sha384_final(&mtree->sha384ctx, reg->digest.sha384);
-#endif
-#ifdef ARCHIVE_HAS_SHA512
- if (mtree->compute_sum & F_SHA512)
- archive_sha512_final(&mtree->sha512ctx, reg->digest.sha512);
-#endif
- /* Save what types of sum are computed. */
- reg->compute_sum = mtree->compute_sum;
-}
-
-#if defined(ARCHIVE_HAS_MD5) || defined(ARCHIVE_HAS_RMD160) || \
- defined(ARCHIVE_HAS_SHA1) || defined(ARCHIVE_HAS_SHA256) || \
- defined(ARCHIVE_HAS_SHA384) || defined(ARCHIVE_HAS_SHA512)
-static void
-strappend_bin(struct archive_string *s, const unsigned char *bin, int n)
-{
- static const char hex[] = "0123456789abcdef";
- int i;
-
- for (i = 0; i < n; i++) {
- archive_strappend_char(s, hex[bin[i] >> 4]);
- archive_strappend_char(s, hex[bin[i] & 0x0f]);
- }
-}
-#endif
-
-static void
-sum_write(struct archive_string *str, struct reg_info *reg)
-{
-
- if (reg->compute_sum & F_CKSUM) {
- archive_string_sprintf(str, " cksum=%ju",
- (uintmax_t)reg->crc);
- }
-
-#define append_digest(_s, _r, _t) \
- strappend_bin(_s, _r->digest._t, sizeof(_r->digest._t))
-
-#ifdef ARCHIVE_HAS_MD5
- if (reg->compute_sum & F_MD5) {
- archive_strcat(str, " md5digest=");
- append_digest(str, reg, md5);
- }
-#endif
-#ifdef ARCHIVE_HAS_RMD160
- if (reg->compute_sum & F_RMD160) {
- archive_strcat(str, " rmd160digest=");
- append_digest(str, reg, rmd160);
- }
-#endif
-#ifdef ARCHIVE_HAS_SHA1
- if (reg->compute_sum & F_SHA1) {
- archive_strcat(str, " sha1digest=");
- append_digest(str, reg, sha1);
- }
-#endif
-#ifdef ARCHIVE_HAS_SHA256
- if (reg->compute_sum & F_SHA256) {
- archive_strcat(str, " sha256digest=");
- append_digest(str, reg, sha256);
- }
-#endif
-#ifdef ARCHIVE_HAS_SHA384
- if (reg->compute_sum & F_SHA384) {
- archive_strcat(str, " sha384digest=");
- append_digest(str, reg, sha384);
- }
-#endif
-#ifdef ARCHIVE_HAS_SHA512
- if (reg->compute_sum & F_SHA512) {
- archive_strcat(str, " sha512digest=");
- append_digest(str, reg, sha512);
- }
-#endif
-#undef append_digest
-}
-
-static int
-mtree_entry_cmp_node(const struct archive_rb_node *n1,
- const struct archive_rb_node *n2)
-{
- const struct mtree_entry *e1 = (const struct mtree_entry *)n1;
- const struct mtree_entry *e2 = (const struct mtree_entry *)n2;
-
- return (strcmp(e2->basename.s, e1->basename.s));
-}
-
-static int
-mtree_entry_cmp_key(const struct archive_rb_node *n, const void *key)
-{
- const struct mtree_entry *e = (const struct mtree_entry *)n;
-
- return (strcmp((const char *)key, e->basename.s));
-}
-
-#if defined(_WIN32) || defined(__CYGWIN__)
-static int
-cleanup_backslash_1(char *p)
-{
- int mb, dos;
-
- mb = dos = 0;
- while (*p) {
- if (*(unsigned char *)p > 127)
- mb = 1;
- if (*p == '\\') {
- /* If we have not met any multi-byte characters,
- * we can replace '\' with '/'. */
- if (!mb)
- *p = '/';
- dos = 1;
- }
- p++;
- }
- if (!mb || !dos)
- return (0);
- return (-1);
-}
-
-static void
-cleanup_backslash_2(wchar_t *p)
-{
-
- /* Convert a path-separator from '\' to '/' */
- while (*p != L'\0') {
- if (*p == L'\\')
- *p = L'/';
- p++;
- }
-}
-#endif
-
-/*
- * Generate a parent directory name and a base name from a pathname.
- */
-static int
-mtree_entry_setup_filenames(struct archive_write *a, struct mtree_entry *file,
- struct archive_entry *entry)
-{
- const char *pathname;
- char *p, *dirname, *slash;
- size_t len;
- int ret = ARCHIVE_OK;
-
- archive_strcpy(&file->pathname, archive_entry_pathname(entry));
-#if defined(_WIN32) || defined(__CYGWIN__)
- /*
- * Convert a path-separator from '\' to '/'
- */
- if (cleanup_backslash_1(file->pathname.s) != 0) {
- const wchar_t *wp = archive_entry_pathname_w(entry);
- struct archive_wstring ws;
-
- if (wp != NULL) {
- int r;
- archive_string_init(&ws);
- archive_wstrcpy(&ws, wp);
- cleanup_backslash_2(ws.s);
- archive_string_empty(&(file->pathname));
- r = archive_string_append_from_wcs(&(file->pathname),
- ws.s, ws.length);
- archive_wstring_free(&ws);
- if (r < 0 && errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- }
- }
-#else
- (void)a; /* UNUSED */
-#endif
- pathname = file->pathname.s;
- if (strcmp(pathname, ".") == 0) {
- archive_strcpy(&file->basename, ".");
- return (ARCHIVE_OK);
- }
-
- archive_strcpy(&(file->parentdir), pathname);
-
- len = file->parentdir.length;
- p = dirname = file->parentdir.s;
-
- /*
- * Remove leading '/' and '../' elements
- */
- while (*p) {
- if (p[0] == '/') {
- p++;
- len--;
- } else if (p[0] != '.')
- break;
- else if (p[1] == '.' && p[2] == '/') {
- p += 3;
- len -= 3;
- } else
- break;
- }
- if (p != dirname) {
- memmove(dirname, p, len+1);
- p = dirname;
- }
- /*
- * Remove "/","/." and "/.." elements from tail.
- */
- while (len > 0) {
- size_t ll = len;
-
- if (len > 0 && p[len-1] == '/') {
- p[len-1] = '\0';
- len--;
- }
- if (len > 1 && p[len-2] == '/' && p[len-1] == '.') {
- p[len-2] = '\0';
- len -= 2;
- }
- if (len > 2 && p[len-3] == '/' && p[len-2] == '.' &&
- p[len-1] == '.') {
- p[len-3] = '\0';
- len -= 3;
- }
- if (ll == len)
- break;
- }
- while (*p) {
- if (p[0] == '/') {
- if (p[1] == '/')
- /* Convert '//' --> '/' */
- memmove(p, p+1, strlen(p+1) + 1);
- else if (p[1] == '.' && p[2] == '/')
- /* Convert '/./' --> '/' */
- memmove(p, p+2, strlen(p+2) + 1);
- else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
- /* Convert 'dir/dir1/../dir2/'
- * --> 'dir/dir2/'
- */
- char *rp = p -1;
- while (rp >= dirname) {
- if (*rp == '/')
- break;
- --rp;
- }
- if (rp > dirname) {
- strcpy(rp, p+3);
- p = rp;
- } else {
- strcpy(dirname, p+4);
- p = dirname;
- }
- } else
- p++;
- } else
- p++;
- }
- p = dirname;
- len = strlen(p);
-
- /*
- * Add "./" prefix.
- * NOTE: If the pathname does not have a path separator, we have
- * to add "./" to the head of the pathname because mtree reader
- * will suppose that it is v1(a.k.a classic) mtree format and
- * change the directory unexpectedly and so it will make a wrong
- * path.
- */
- if (strcmp(p, ".") != 0 && strncmp(p, "./", 2) != 0) {
- struct archive_string as;
- archive_string_init(&as);
- archive_strcpy(&as, "./");
- archive_strncat(&as, p, len);
- archive_string_empty(&file->parentdir);
- archive_string_concat(&file->parentdir, &as);
- archive_string_free(&as);
- p = file->parentdir.s;
- len = archive_strlen(&file->parentdir);
- }
-
- /*
- * Find out the position which points the last position of
- * path separator('/').
- */
- slash = NULL;
- for (; *p != '\0'; p++) {
- if (*p == '/')
- slash = p;
- }
- if (slash == NULL) {
- /* The pathname doesn't have a parent directory. */
- file->parentdir.length = len;
- archive_string_copy(&(file->basename), &(file->parentdir));
- archive_string_empty(&(file->parentdir));
- *file->parentdir.s = '\0';
- return (ret);
- }
-
- /* Make a basename from file->parentdir.s and slash */
- *slash = '\0';
- file->parentdir.length = slash - file->parentdir.s;
- archive_strcpy(&(file->basename), slash + 1);
- return (ret);
-}
-
-static int
-mtree_entry_create_virtual_dir(struct archive_write *a, const char *pathname,
- struct mtree_entry **m_entry)
-{
- struct archive_entry *entry;
- struct mtree_entry *file;
- int r;
-
- entry = archive_entry_new();
- if (entry == NULL) {
- *m_entry = NULL;
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- archive_entry_copy_pathname(entry, pathname);
- archive_entry_set_mode(entry, AE_IFDIR | 0755);
- archive_entry_set_mtime(entry, time(NULL), 0);
-
- r = mtree_entry_new(a, entry, &file);
- archive_entry_free(entry);
- if (r < ARCHIVE_WARN) {
- *m_entry = NULL;
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
-
- file->dir_info->virtual = 1;
-
- *m_entry = file;
- return (ARCHIVE_OK);
-}
-
-static void
-mtree_entry_register_add(struct mtree_writer *mtree, struct mtree_entry *file)
-{
- file->next = NULL;
- *mtree->file_list.last = file;
- mtree->file_list.last = &(file->next);
-}
-
-static void
-mtree_entry_register_init(struct mtree_writer *mtree)
-{
- mtree->file_list.first = NULL;
- mtree->file_list.last = &(mtree->file_list.first);
-}
-
-static void
-mtree_entry_register_free(struct mtree_writer *mtree)
-{
- struct mtree_entry *file, *file_next;
-
- file = mtree->file_list.first;
- while (file != NULL) {
- file_next = file->next;
- mtree_entry_free(file);
- file = file_next;
- }
-}
-
-static int
-mtree_entry_add_child_tail(struct mtree_entry *parent,
- struct mtree_entry *child)
-{
- child->dir_info->chnext = NULL;
- *parent->dir_info->children.last = child;
- parent->dir_info->children.last = &(child->dir_info->chnext);
- return (1);
-}
-
-/*
- * Find a entry from a parent entry with the name.
- */
-static struct mtree_entry *
-mtree_entry_find_child(struct mtree_entry *parent, const char *child_name)
-{
- struct mtree_entry *np;
-
- if (parent == NULL)
- return (NULL);
- np = (struct mtree_entry *)__archive_rb_tree_find_node(
- &(parent->dir_info->rbtree), child_name);
- return (np);
-}
-
-static int
-get_path_component(char *name, size_t n, const char *fn)
-{
- char *p;
- size_t l;
-
- p = strchr(fn, '/');
- if (p == NULL) {
- if ((l = strlen(fn)) == 0)
- return (0);
- } else
- l = p - fn;
- if (l > n -1)
- return (-1);
- memcpy(name, fn, l);
- name[l] = '\0';
-
- return ((int)l);
-}
-
-/*
- * Add a new entry into the tree.
- */
-static int
-mtree_entry_tree_add(struct archive_write *a, struct mtree_entry **filep)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- char name[_MAX_FNAME];/* Included null terminator size. */
-#elif defined(NAME_MAX) && NAME_MAX >= 255
- char name[NAME_MAX+1];
-#else
- char name[256];
-#endif
- struct mtree_writer *mtree = (struct mtree_writer *)a->format_data;
- struct mtree_entry *dent, *file, *np;
- const char *fn, *p;
- int l, r;
-
- file = *filep;
- if (file->parentdir.length == 0 && file->basename.length == 1 &&
- file->basename.s[0] == '.') {
- file->parent = file;
- if (mtree->root != NULL) {
- np = mtree->root;
- goto same_entry;
- }
- mtree->root = file;
- mtree_entry_register_add(mtree, file);
- return (ARCHIVE_OK);
- }
-
- if (file->parentdir.length == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Internal programming error "
- "in generating canonical name for %s",
- file->pathname.s);
- return (ARCHIVE_FAILED);
- }
-
- fn = p = file->parentdir.s;
-
- /*
- * If the path of the parent directory of `file' entry is
- * the same as the path of `cur_dirent', add `file' entry to
- * `cur_dirent'.
- */
- if (archive_strlen(&(mtree->cur_dirstr))
- == archive_strlen(&(file->parentdir)) &&
- strcmp(mtree->cur_dirstr.s, fn) == 0) {
- if (!__archive_rb_tree_insert_node(
- &(mtree->cur_dirent->dir_info->rbtree),
- (struct archive_rb_node *)file)) {
- /* There is the same name in the tree. */
- np = (struct mtree_entry *)__archive_rb_tree_find_node(
- &(mtree->cur_dirent->dir_info->rbtree),
- file->basename.s);
- goto same_entry;
- }
- file->parent = mtree->cur_dirent;
- mtree_entry_register_add(mtree, file);
- return (ARCHIVE_OK);
- }
-
- dent = mtree->root;
- for (;;) {
- l = get_path_component(name, sizeof(name), fn);
- if (l == 0) {
- np = NULL;
- break;
- }
- if (l < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "A name buffer is too small");
- return (ARCHIVE_FATAL);
- }
- if (l == 1 && name[0] == '.' && dent != NULL &&
- dent == mtree->root) {
- fn += l;
- if (fn[0] == '/')
- fn++;
- continue;
- }
-
- np = mtree_entry_find_child(dent, name);
- if (np == NULL || fn[0] == '\0')
- break;
-
- /* Find next sub directory. */
- if (!np->dir_info) {
- /* NOT Directory! */
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "`%s' is not directory, we cannot insert `%s' ",
- np->pathname.s, file->pathname.s);
- return (ARCHIVE_FAILED);
- }
- fn += l;
- if (fn[0] == '/')
- fn++;
- dent = np;
- }
- if (np == NULL) {
- /*
- * Create virtual parent directories.
- */
- while (fn[0] != '\0') {
- struct mtree_entry *vp;
- struct archive_string as;
-
- archive_string_init(&as);
- archive_strncat(&as, p, fn - p + l);
- if (as.s[as.length-1] == '/') {
- as.s[as.length-1] = '\0';
- as.length--;
- }
- r = mtree_entry_create_virtual_dir(a, as.s, &vp);
- archive_string_free(&as);
- if (r < ARCHIVE_WARN)
- return (r);
-
- if (strcmp(vp->pathname.s, ".") == 0) {
- vp->parent = vp;
- mtree->root = vp;
- } else {
- __archive_rb_tree_insert_node(
- &(dent->dir_info->rbtree),
- (struct archive_rb_node *)vp);
- vp->parent = dent;
- }
- mtree_entry_register_add(mtree, vp);
- np = vp;
-
- fn += l;
- if (fn[0] == '/')
- fn++;
- l = get_path_component(name, sizeof(name), fn);
- if (l < 0) {
- archive_string_free(&as);
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "A name buffer is too small");
- return (ARCHIVE_FATAL);
- }
- dent = np;
- }
-
- /* Found out the parent directory where `file' can be
- * inserted. */
- mtree->cur_dirent = dent;
- archive_string_empty(&(mtree->cur_dirstr));
- archive_string_ensure(&(mtree->cur_dirstr),
- archive_strlen(&(dent->parentdir)) +
- archive_strlen(&(dent->basename)) + 2);
- if (archive_strlen(&(dent->parentdir)) +
- archive_strlen(&(dent->basename)) == 0)
- mtree->cur_dirstr.s[0] = 0;
- else {
- if (archive_strlen(&(dent->parentdir)) > 0) {
- archive_string_copy(&(mtree->cur_dirstr),
- &(dent->parentdir));
- archive_strappend_char(
- &(mtree->cur_dirstr), '/');
- }
- archive_string_concat(&(mtree->cur_dirstr),
- &(dent->basename));
- }
-
- if (!__archive_rb_tree_insert_node(
- &(dent->dir_info->rbtree),
- (struct archive_rb_node *)file)) {
- np = (struct mtree_entry *)__archive_rb_tree_find_node(
- &(dent->dir_info->rbtree), file->basename.s);
- goto same_entry;
- }
- file->parent = dent;
- mtree_entry_register_add(mtree, file);
- return (ARCHIVE_OK);
- }
-
-same_entry:
- /*
- * We have already has the entry the filename of which is
- * the same.
- */
- r = mtree_entry_exchange_same_entry(a, np, file);
- if (r < ARCHIVE_WARN)
- return (r);
- if (np->dir_info)
- np->dir_info->virtual = 0;
- *filep = np;
- mtree_entry_free(file);
- return (ARCHIVE_WARN);
-}
-
-static int
-mtree_entry_exchange_same_entry(struct archive_write *a, struct mtree_entry *np,
- struct mtree_entry *file)
-{
-
- if ((np->mode & AE_IFMT) != (file->mode & AE_IFMT)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Found duplicate entries `%s' and its file type is "
- "different",
- np->pathname.s);
- return (ARCHIVE_FAILED);
- }
-
- /* Update the existent mtree entry's attributes by the new one's. */
- archive_string_empty(&np->symlink);
- archive_string_concat(&np->symlink, &file->symlink);
- archive_string_empty(&np->uname);
- archive_string_concat(&np->uname, &file->uname);
- archive_string_empty(&np->gname);
- archive_string_concat(&np->gname, &file->gname);
- archive_string_empty(&np->fflags_text);
- archive_string_concat(&np->fflags_text, &file->fflags_text);
- np->nlink = file->nlink;
- np->filetype = file->filetype;
- np->mode = file->mode;
- np->size = file->size;
- np->uid = file->uid;
- np->gid = file->gid;
- np->fflags_set = file->fflags_set;
- np->fflags_clear = file->fflags_clear;
- np->mtime = file->mtime;
- np->mtime_nsec = file->mtime_nsec;
- np->rdevmajor = file->rdevmajor;
- np->rdevminor = file->rdevminor;
- np->devmajor = file->devmajor;
- np->devminor = file->devminor;
- np->ino = file->ino;
-
- return (ARCHIVE_WARN);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_format_pax.c b/contrib/libs/libarchive/libarchive/archive_write_set_format_pax.c
deleted file mode 100644
index c9c1591646..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_format_pax.c
+++ /dev/null
@@ -1,2063 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * Copyright (c) 2010-2012 Michihiro NAKAJIMA
- * Copyright (c) 2016 Martin Matuska
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_pax.c 201162 2009-12-29 05:47:46Z kientzle $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_private.h"
-#include "archive_write_private.h"
-#include "archive_write_set_format_private.h"
-
-struct sparse_block {
- struct sparse_block *next;
- int is_hole;
- uint64_t offset;
- uint64_t remaining;
-};
-
-struct pax {
- uint64_t entry_bytes_remaining;
- uint64_t entry_padding;
- struct archive_string l_url_encoded_name;
- struct archive_string pax_header;
- struct archive_string sparse_map;
- size_t sparse_map_padding;
- struct sparse_block *sparse_list;
- struct sparse_block *sparse_tail;
- struct archive_string_conv *sconv_utf8;
- int opt_binary;
-
- unsigned flags;
-#define WRITE_SCHILY_XATTR (1 << 0)
-#define WRITE_LIBARCHIVE_XATTR (1 << 1)
-};
-
-static void add_pax_attr(struct archive_string *, const char *key,
- const char *value);
-static void add_pax_attr_binary(struct archive_string *,
- const char *key,
- const char *value, size_t value_len);
-static void add_pax_attr_int(struct archive_string *,
- const char *key, int64_t value);
-static void add_pax_attr_time(struct archive_string *,
- const char *key, int64_t sec,
- unsigned long nanos);
-static int add_pax_acl(struct archive_write *,
- struct archive_entry *, struct pax *, int);
-static ssize_t archive_write_pax_data(struct archive_write *,
- const void *, size_t);
-static int archive_write_pax_close(struct archive_write *);
-static int archive_write_pax_free(struct archive_write *);
-static int archive_write_pax_finish_entry(struct archive_write *);
-static int archive_write_pax_header(struct archive_write *,
- struct archive_entry *);
-static int archive_write_pax_options(struct archive_write *,
- const char *, const char *);
-static char *base64_encode(const char *src, size_t len);
-static char *build_gnu_sparse_name(char *dest, const char *src);
-static char *build_pax_attribute_name(char *dest, const char *src);
-static char *build_ustar_entry_name(char *dest, const char *src,
- size_t src_length, const char *insert);
-static char *format_int(char *dest, int64_t);
-static int has_non_ASCII(const char *);
-static void sparse_list_clear(struct pax *);
-static int sparse_list_add(struct pax *, int64_t, int64_t);
-static char *url_encode(const char *in);
-static time_t get_ustar_max_mtime(void);
-
-/*
- * Set output format to 'restricted pax' format.
- *
- * This is the same as normal 'pax', but tries to suppress
- * the pax header whenever possible. This is the default for
- * bsdtar, for instance.
- */
-int
-archive_write_set_format_pax_restricted(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- int r;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_format_pax_restricted");
-
- r = archive_write_set_format_pax(&a->archive);
- a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED;
- a->archive.archive_format_name = "restricted POSIX pax interchange";
- return (r);
-}
-
-/*
- * Set output format to 'pax' format.
- */
-int
-archive_write_set_format_pax(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct pax *pax;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_format_pax");
-
- if (a->format_free != NULL)
- (a->format_free)(a);
-
- pax = (struct pax *)calloc(1, sizeof(*pax));
- if (pax == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate pax data");
- return (ARCHIVE_FATAL);
- }
- pax->flags = WRITE_LIBARCHIVE_XATTR | WRITE_SCHILY_XATTR;
-
- a->format_data = pax;
- a->format_name = "pax";
- a->format_options = archive_write_pax_options;
- a->format_write_header = archive_write_pax_header;
- a->format_write_data = archive_write_pax_data;
- a->format_close = archive_write_pax_close;
- a->format_free = archive_write_pax_free;
- a->format_finish_entry = archive_write_pax_finish_entry;
- a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
- a->archive.archive_format_name = "POSIX pax interchange";
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_pax_options(struct archive_write *a, const char *key,
- const char *val)
-{
- struct pax *pax = (struct pax *)a->format_data;
- int ret = ARCHIVE_FAILED;
-
- if (strcmp(key, "hdrcharset") == 0) {
- /*
- * The character-set we can use are defined in
- * IEEE Std 1003.1-2001
- */
- if (val == NULL || val[0] == 0)
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "pax: hdrcharset option needs a character-set name");
- else if (strcmp(val, "BINARY") == 0 ||
- strcmp(val, "binary") == 0) {
- /*
- * Specify binary mode. We will not convert
- * filenames, uname and gname to any charsets.
- */
- pax->opt_binary = 1;
- ret = ARCHIVE_OK;
- } else if (strcmp(val, "UTF-8") == 0) {
- /*
- * Specify UTF-8 character-set to be used for
- * filenames. This is almost the test that
- * running platform supports the string conversion.
- * Especially libarchive_test needs this trick for
- * its test.
- */
- pax->sconv_utf8 = archive_string_conversion_to_charset(
- &(a->archive), "UTF-8", 0);
- if (pax->sconv_utf8 == NULL)
- ret = ARCHIVE_FATAL;
- else
- ret = ARCHIVE_OK;
- } else
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "pax: invalid charset name");
- return (ret);
- } else if (strcmp(key, "xattrheader") == 0) {
- if (val == NULL || val[0] == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "pax: xattrheader requires a value");
- } else if (strcmp(val, "ALL") == 0 ||
- strcmp(val, "all") == 0) {
- pax->flags |= WRITE_LIBARCHIVE_XATTR | WRITE_SCHILY_XATTR;
- ret = ARCHIVE_OK;
- } else if (strcmp(val, "SCHILY") == 0 ||
- strcmp(val, "schily") == 0) {
- pax->flags |= WRITE_SCHILY_XATTR;
- pax->flags &= ~WRITE_LIBARCHIVE_XATTR;
- ret = ARCHIVE_OK;
- } else if (strcmp(val, "LIBARCHIVE") == 0 ||
- strcmp(val, "libarchive") == 0) {
- pax->flags |= WRITE_LIBARCHIVE_XATTR;
- pax->flags &= ~WRITE_SCHILY_XATTR;
- ret = ARCHIVE_OK;
- } else
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "pax: invalid xattr header name");
- return (ret);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-/*
- * Note: This code assumes that 'nanos' has the same sign as 'sec',
- * which implies that sec=-1, nanos=200000000 represents -1.2 seconds
- * and not -0.8 seconds. This is a pretty pedantic point, as we're
- * unlikely to encounter many real files created before Jan 1, 1970,
- * much less ones with timestamps recorded to sub-second resolution.
- */
-static void
-add_pax_attr_time(struct archive_string *as, const char *key,
- int64_t sec, unsigned long nanos)
-{
- int digit, i;
- char *t;
- /*
- * Note that each byte contributes fewer than 3 base-10
- * digits, so this will always be big enough.
- */
- char tmp[1 + 3*sizeof(sec) + 1 + 3*sizeof(nanos)];
-
- tmp[sizeof(tmp) - 1] = 0;
- t = tmp + sizeof(tmp) - 1;
-
- /* Skip trailing zeros in the fractional part. */
- for (digit = 0, i = 10; i > 0 && digit == 0; i--) {
- digit = nanos % 10;
- nanos /= 10;
- }
-
- /* Only format the fraction if it's non-zero. */
- if (i > 0) {
- while (i > 0) {
- *--t = "0123456789"[digit];
- digit = nanos % 10;
- nanos /= 10;
- i--;
- }
- *--t = '.';
- }
- t = format_int(t, sec);
-
- add_pax_attr(as, key, t);
-}
-
-static char *
-format_int(char *t, int64_t i)
-{
- uint64_t ui;
-
- if (i < 0)
- ui = (i == INT64_MIN) ? (uint64_t)(INT64_MAX) + 1 : (uint64_t)(-i);
- else
- ui = i;
-
- do {
- *--t = "0123456789"[ui % 10];
- } while (ui /= 10);
- if (i < 0)
- *--t = '-';
- return (t);
-}
-
-static void
-add_pax_attr_int(struct archive_string *as, const char *key, int64_t value)
-{
- char tmp[1 + 3 * sizeof(value)];
-
- tmp[sizeof(tmp) - 1] = 0;
- add_pax_attr(as, key, format_int(tmp + sizeof(tmp) - 1, value));
-}
-
-/*
- * Add a key/value attribute to the pax header. This function handles
- * the length field and various other syntactic requirements.
- */
-static void
-add_pax_attr(struct archive_string *as, const char *key, const char *value)
-{
- add_pax_attr_binary(as, key, value, strlen(value));
-}
-
-/*
- * Add a key/value attribute to the pax header. This function handles
- * binary values.
- */
-static void
-add_pax_attr_binary(struct archive_string *as, const char *key,
- const char *value, size_t value_len)
-{
- int digits, i, len, next_ten;
- char tmp[1 + 3 * sizeof(int)]; /* < 3 base-10 digits per byte */
-
- /*-
- * PAX attributes have the following layout:
- * <len> <space> <key> <=> <value> <nl>
- */
- len = 1 + (int)strlen(key) + 1 + (int)value_len + 1;
-
- /*
- * The <len> field includes the length of the <len> field, so
- * computing the correct length is tricky. I start by
- * counting the number of base-10 digits in 'len' and
- * computing the next higher power of 10.
- */
- next_ten = 1;
- digits = 0;
- i = len;
- while (i > 0) {
- i = i / 10;
- digits++;
- next_ten = next_ten * 10;
- }
- /*
- * For example, if string without the length field is 99
- * chars, then adding the 2 digit length "99" will force the
- * total length past 100, requiring an extra digit. The next
- * statement adjusts for this effect.
- */
- if (len + digits >= next_ten)
- digits++;
-
- /* Now, we have the right length so we can build the line. */
- tmp[sizeof(tmp) - 1] = 0; /* Null-terminate the work area. */
- archive_strcat(as, format_int(tmp + sizeof(tmp) - 1, len + digits));
- archive_strappend_char(as, ' ');
- archive_strcat(as, key);
- archive_strappend_char(as, '=');
- archive_array_append(as, value, value_len);
- archive_strappend_char(as, '\n');
-}
-
-static void
-archive_write_pax_header_xattr(struct pax *pax, const char *encoded_name,
- const void *value, size_t value_len)
-{
- struct archive_string s;
- char *encoded_value;
-
- if (pax->flags & WRITE_LIBARCHIVE_XATTR) {
- encoded_value = base64_encode((const char *)value, value_len);
-
- if (encoded_name != NULL && encoded_value != NULL) {
- archive_string_init(&s);
- archive_strcpy(&s, "LIBARCHIVE.xattr.");
- archive_strcat(&s, encoded_name);
- add_pax_attr(&(pax->pax_header), s.s, encoded_value);
- archive_string_free(&s);
- }
- free(encoded_value);
- }
- if (pax->flags & WRITE_SCHILY_XATTR) {
- archive_string_init(&s);
- archive_strcpy(&s, "SCHILY.xattr.");
- archive_strcat(&s, encoded_name);
- add_pax_attr_binary(&(pax->pax_header), s.s, value, value_len);
- archive_string_free(&s);
- }
-}
-
-static int
-archive_write_pax_header_xattrs(struct archive_write *a,
- struct pax *pax, struct archive_entry *entry)
-{
- int i = archive_entry_xattr_reset(entry);
-
- while (i--) {
- const char *name;
- const void *value;
- char *url_encoded_name = NULL, *encoded_name = NULL;
- size_t size;
- int r;
-
- archive_entry_xattr_next(entry, &name, &value, &size);
- url_encoded_name = url_encode(name);
- if (url_encoded_name != NULL) {
- /* Convert narrow-character to UTF-8. */
- r = archive_strcpy_l(&(pax->l_url_encoded_name),
- url_encoded_name, pax->sconv_utf8);
- free(url_encoded_name); /* Done with this. */
- if (r == 0)
- encoded_name = pax->l_url_encoded_name.s;
- else if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Linkname");
- return (ARCHIVE_FATAL);
- }
- }
-
- archive_write_pax_header_xattr(pax, encoded_name,
- value, size);
-
- }
- return (ARCHIVE_OK);
-}
-
-static int
-get_entry_hardlink(struct archive_write *a, struct archive_entry *entry,
- const char **name, size_t *length, struct archive_string_conv *sc)
-{
- int r;
-
- r = archive_entry_hardlink_l(entry, name, length, sc);
- if (r != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Linkname");
- return (ARCHIVE_FATAL);
- }
- return (ARCHIVE_WARN);
- }
- return (ARCHIVE_OK);
-}
-
-static int
-get_entry_pathname(struct archive_write *a, struct archive_entry *entry,
- const char **name, size_t *length, struct archive_string_conv *sc)
-{
- int r;
-
- r = archive_entry_pathname_l(entry, name, length, sc);
- if (r != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathname");
- return (ARCHIVE_FATAL);
- }
- return (ARCHIVE_WARN);
- }
- return (ARCHIVE_OK);
-}
-
-static int
-get_entry_uname(struct archive_write *a, struct archive_entry *entry,
- const char **name, size_t *length, struct archive_string_conv *sc)
-{
- int r;
-
- r = archive_entry_uname_l(entry, name, length, sc);
- if (r != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Uname");
- return (ARCHIVE_FATAL);
- }
- return (ARCHIVE_WARN);
- }
- return (ARCHIVE_OK);
-}
-
-static int
-get_entry_gname(struct archive_write *a, struct archive_entry *entry,
- const char **name, size_t *length, struct archive_string_conv *sc)
-{
- int r;
-
- r = archive_entry_gname_l(entry, name, length, sc);
- if (r != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Gname");
- return (ARCHIVE_FATAL);
- }
- return (ARCHIVE_WARN);
- }
- return (ARCHIVE_OK);
-}
-
-static int
-get_entry_symlink(struct archive_write *a, struct archive_entry *entry,
- const char **name, size_t *length, struct archive_string_conv *sc)
-{
- int r;
-
- r = archive_entry_symlink_l(entry, name, length, sc);
- if (r != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Linkname");
- return (ARCHIVE_FATAL);
- }
- return (ARCHIVE_WARN);
- }
- return (ARCHIVE_OK);
-}
-
-/* Add ACL to pax header */
-static int
-add_pax_acl(struct archive_write *a,
- struct archive_entry *entry, struct pax *pax, int flags)
-{
- char *p;
- const char *attr;
- int acl_types;
-
- acl_types = archive_entry_acl_types(entry);
-
- if ((acl_types & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0)
- attr = "SCHILY.acl.ace";
- else if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0)
- attr = "SCHILY.acl.access";
- else if ((flags & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
- attr = "SCHILY.acl.default";
- else
- return (ARCHIVE_FATAL);
-
- p = archive_entry_acl_to_text_l(entry, NULL, flags, pax->sconv_utf8);
- if (p == NULL) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM, "%s %s",
- "Can't allocate memory for ", attr);
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT, "%s %s %s",
- "Can't translate ", attr, " to UTF-8");
- return(ARCHIVE_WARN);
- }
-
- if (*p != '\0') {
- add_pax_attr(&(pax->pax_header),
- attr, p);
- }
- free(p);
- return(ARCHIVE_OK);
-}
-
-/*
- * TODO: Consider adding 'comment' and 'charset' fields to
- * archive_entry so that clients can specify them. Also, consider
- * adding generic key/value tags so clients can add arbitrary
- * key/value data.
- *
- * TODO: Break up this 700-line function!!!! Yowza!
- */
-static int
-archive_write_pax_header(struct archive_write *a,
- struct archive_entry *entry_original)
-{
- struct archive_entry *entry_main;
- const char *p;
- const char *suffix;
- int need_extension, r, ret;
- int acl_types;
- int sparse_count;
- uint64_t sparse_total, real_size;
- struct pax *pax;
- const char *hardlink;
- const char *path = NULL, *linkpath = NULL;
- const char *uname = NULL, *gname = NULL;
- const void *mac_metadata;
- size_t mac_metadata_size;
- struct archive_string_conv *sconv;
- size_t hardlink_length, path_length, linkpath_length;
- size_t uname_length, gname_length;
-
- char paxbuff[512];
- char ustarbuff[512];
- char ustar_entry_name[256];
- char pax_entry_name[256];
- char gnu_sparse_name[256];
- struct archive_string entry_name;
-
- ret = ARCHIVE_OK;
- need_extension = 0;
- pax = (struct pax *)a->format_data;
-
- const time_t ustar_max_mtime = get_ustar_max_mtime();
-
- /* Sanity check. */
- if (archive_entry_pathname(entry_original) == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Can't record entry in tar file without pathname");
- return (ARCHIVE_FAILED);
- }
-
- /*
- * Choose a header encoding.
- */
- if (pax->opt_binary)
- sconv = NULL;/* Binary mode. */
- else {
- /* Header encoding is UTF-8. */
- if (pax->sconv_utf8 == NULL) {
- /* Initialize the string conversion object
- * we must need */
- pax->sconv_utf8 = archive_string_conversion_to_charset(
- &(a->archive), "UTF-8", 1);
- if (pax->sconv_utf8 == NULL)
- /* Couldn't allocate memory */
- return (ARCHIVE_FAILED);
- }
- sconv = pax->sconv_utf8;
- }
-
- r = get_entry_hardlink(a, entry_original, &hardlink,
- &hardlink_length, sconv);
- if (r == ARCHIVE_FATAL)
- return (r);
- else if (r != ARCHIVE_OK) {
- r = get_entry_hardlink(a, entry_original, &hardlink,
- &hardlink_length, NULL);
- if (r == ARCHIVE_FATAL)
- return (r);
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate linkname '%s' to %s", hardlink,
- archive_string_conversion_charset_name(sconv));
- ret = ARCHIVE_WARN;
- sconv = NULL;/* The header charset switches to binary mode. */
- }
-
- /* Make sure this is a type of entry that we can handle here */
- if (hardlink == NULL) {
- switch (archive_entry_filetype(entry_original)) {
- case AE_IFBLK:
- case AE_IFCHR:
- case AE_IFIFO:
- case AE_IFLNK:
- case AE_IFREG:
- break;
- case AE_IFDIR:
- {
- /*
- * Ensure a trailing '/'. Modify the original
- * entry so the client sees the change.
- */
-#if defined(_WIN32) && !defined(__CYGWIN__)
- const wchar_t *wp;
-
- wp = archive_entry_pathname_w(entry_original);
- if (wp != NULL && wp[wcslen(wp) -1] != L'/') {
- struct archive_wstring ws;
-
- archive_string_init(&ws);
- path_length = wcslen(wp);
- if (archive_wstring_ensure(&ws,
- path_length + 2) == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate pax data");
- archive_wstring_free(&ws);
- return(ARCHIVE_FATAL);
- }
- /* Should we keep '\' ? */
- if (wp[path_length -1] == L'\\')
- path_length--;
- archive_wstrncpy(&ws, wp, path_length);
- archive_wstrappend_wchar(&ws, L'/');
- archive_entry_copy_pathname_w(
- entry_original, ws.s);
- archive_wstring_free(&ws);
- p = NULL;
- } else
-#endif
- p = archive_entry_pathname(entry_original);
- /*
- * On Windows, this is a backup operation just in
- * case getting WCS failed. On POSIX, this is a
- * normal operation.
- */
- if (p != NULL && p[0] != '\0' && p[strlen(p) - 1] != '/') {
- struct archive_string as;
-
- archive_string_init(&as);
- path_length = strlen(p);
- if (archive_string_ensure(&as,
- path_length + 2) == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate pax data");
- archive_string_free(&as);
- return(ARCHIVE_FATAL);
- }
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* NOTE: This might break the pathname
- * if the current code page is CP932 and
- * the pathname includes a character '\'
- * as a part of its multibyte pathname. */
- if (p[strlen(p) -1] == '\\')
- path_length--;
- else
-#endif
- archive_strncpy(&as, p, path_length);
- archive_strappend_char(&as, '/');
- archive_entry_copy_pathname(
- entry_original, as.s);
- archive_string_free(&as);
- }
- break;
- }
- default: /* AE_IFSOCK and unknown */
- __archive_write_entry_filetype_unsupported(
- &a->archive, entry_original, "pax");
- return (ARCHIVE_FAILED);
- }
- }
-
- /*
- * If Mac OS metadata blob is here, recurse to write that
- * as a separate entry. This is really a pretty poor design:
- * In particular, it doubles the overhead for long filenames.
- * TODO: Help Apple folks design something better and figure
- * out how to transition from this legacy format.
- *
- * Note that this code is present on every platform; clients
- * on non-Mac are unlikely to ever provide this data, but
- * applications that copy entries from one archive to another
- * should not lose data just because the local filesystem
- * can't store it.
- */
- mac_metadata =
- archive_entry_mac_metadata(entry_original, &mac_metadata_size);
- if (mac_metadata != NULL) {
- const char *oname;
- char *name, *bname;
- size_t name_length;
- struct archive_entry *extra = archive_entry_new2(&a->archive);
-
- oname = archive_entry_pathname(entry_original);
- name_length = strlen(oname);
- name = malloc(name_length + 3);
- if (name == NULL || extra == NULL) {
- /* XXX error message */
- archive_entry_free(extra);
- free(name);
- return (ARCHIVE_FAILED);
- }
- strcpy(name, oname);
- /* Find last '/'; strip trailing '/' characters */
- bname = strrchr(name, '/');
- while (bname != NULL && bname[1] == '\0') {
- *bname = '\0';
- bname = strrchr(name, '/');
- }
- if (bname == NULL) {
- memmove(name + 2, name, name_length + 1);
- memmove(name, "._", 2);
- } else {
- bname += 1;
- memmove(bname + 2, bname, strlen(bname) + 1);
- memmove(bname, "._", 2);
- }
- archive_entry_copy_pathname(extra, name);
- free(name);
-
- archive_entry_set_size(extra, mac_metadata_size);
- archive_entry_set_filetype(extra, AE_IFREG);
- archive_entry_set_perm(extra,
- archive_entry_perm(entry_original));
- archive_entry_set_mtime(extra,
- archive_entry_mtime(entry_original),
- archive_entry_mtime_nsec(entry_original));
- archive_entry_set_gid(extra,
- archive_entry_gid(entry_original));
- archive_entry_set_gname(extra,
- archive_entry_gname(entry_original));
- archive_entry_set_uid(extra,
- archive_entry_uid(entry_original));
- archive_entry_set_uname(extra,
- archive_entry_uname(entry_original));
-
- /* Recurse to write the special copyfile entry. */
- r = archive_write_pax_header(a, extra);
- archive_entry_free(extra);
- if (r < ARCHIVE_WARN)
- return (r);
- if (r < ret)
- ret = r;
- r = (int)archive_write_pax_data(a, mac_metadata,
- mac_metadata_size);
- if (r < ARCHIVE_WARN)
- return (r);
- if (r < ret)
- ret = r;
- r = archive_write_pax_finish_entry(a);
- if (r < ARCHIVE_WARN)
- return (r);
- if (r < ret)
- ret = r;
- }
-
- /* Copy entry so we can modify it as needed. */
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Make sure the path separators in pathname, hardlink and symlink
- * are all slash '/', not the Windows path separator '\'. */
- entry_main = __la_win_entry_in_posix_pathseparator(entry_original);
- if (entry_main == entry_original)
- entry_main = archive_entry_clone(entry_original);
-#else
- entry_main = archive_entry_clone(entry_original);
-#endif
- if (entry_main == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate pax data");
- return(ARCHIVE_FATAL);
- }
- archive_string_empty(&(pax->pax_header)); /* Blank our work area. */
- archive_string_empty(&(pax->sparse_map));
- sparse_total = 0;
- sparse_list_clear(pax);
-
- if (hardlink == NULL &&
- archive_entry_filetype(entry_main) == AE_IFREG)
- sparse_count = archive_entry_sparse_reset(entry_main);
- else
- sparse_count = 0;
- if (sparse_count) {
- int64_t offset, length, last_offset = 0;
- /* Get the last entry of sparse block. */
- while (archive_entry_sparse_next(
- entry_main, &offset, &length) == ARCHIVE_OK)
- last_offset = offset + length;
-
- /* If the last sparse block does not reach the end of file,
- * We have to add a empty sparse block as the last entry to
- * manage storing file data. */
- if (last_offset < archive_entry_size(entry_main))
- archive_entry_sparse_add_entry(entry_main,
- archive_entry_size(entry_main), 0);
- sparse_count = archive_entry_sparse_reset(entry_main);
- }
-
- /*
- * First, check the name fields and see if any of them
- * require binary coding. If any of them does, then all of
- * them do.
- */
- r = get_entry_pathname(a, entry_main, &path, &path_length, sconv);
- if (r == ARCHIVE_FATAL) {
- archive_entry_free(entry_main);
- return (r);
- } else if (r != ARCHIVE_OK) {
- r = get_entry_pathname(a, entry_main, &path,
- &path_length, NULL);
- if (r == ARCHIVE_FATAL) {
- archive_entry_free(entry_main);
- return (r);
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate pathname '%s' to %s", path,
- archive_string_conversion_charset_name(sconv));
- ret = ARCHIVE_WARN;
- sconv = NULL;/* The header charset switches to binary mode. */
- }
- r = get_entry_uname(a, entry_main, &uname, &uname_length, sconv);
- if (r == ARCHIVE_FATAL) {
- archive_entry_free(entry_main);
- return (r);
- } else if (r != ARCHIVE_OK) {
- r = get_entry_uname(a, entry_main, &uname, &uname_length, NULL);
- if (r == ARCHIVE_FATAL) {
- archive_entry_free(entry_main);
- return (r);
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate uname '%s' to %s", uname,
- archive_string_conversion_charset_name(sconv));
- ret = ARCHIVE_WARN;
- sconv = NULL;/* The header charset switches to binary mode. */
- }
- r = get_entry_gname(a, entry_main, &gname, &gname_length, sconv);
- if (r == ARCHIVE_FATAL) {
- archive_entry_free(entry_main);
- return (r);
- } else if (r != ARCHIVE_OK) {
- r = get_entry_gname(a, entry_main, &gname, &gname_length, NULL);
- if (r == ARCHIVE_FATAL) {
- archive_entry_free(entry_main);
- return (r);
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate gname '%s' to %s", gname,
- archive_string_conversion_charset_name(sconv));
- ret = ARCHIVE_WARN;
- sconv = NULL;/* The header charset switches to binary mode. */
- }
- linkpath = hardlink;
- linkpath_length = hardlink_length;
- if (linkpath == NULL) {
- r = get_entry_symlink(a, entry_main, &linkpath,
- &linkpath_length, sconv);
- if (r == ARCHIVE_FATAL) {
- archive_entry_free(entry_main);
- return (r);
- } else if (r != ARCHIVE_OK) {
- r = get_entry_symlink(a, entry_main, &linkpath,
- &linkpath_length, NULL);
- if (r == ARCHIVE_FATAL) {
- archive_entry_free(entry_main);
- return (r);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate linkname '%s' to %s", linkpath,
- archive_string_conversion_charset_name(sconv));
- ret = ARCHIVE_WARN;
- sconv = NULL;
- }
- }
-
- /* If any string conversions failed, get all attributes
- * in binary-mode. */
- if (sconv == NULL && !pax->opt_binary) {
- if (hardlink != NULL) {
- r = get_entry_hardlink(a, entry_main, &hardlink,
- &hardlink_length, NULL);
- if (r == ARCHIVE_FATAL) {
- archive_entry_free(entry_main);
- return (r);
- }
- linkpath = hardlink;
- linkpath_length = hardlink_length;
- }
- r = get_entry_pathname(a, entry_main, &path,
- &path_length, NULL);
- if (r == ARCHIVE_FATAL) {
- archive_entry_free(entry_main);
- return (r);
- }
- r = get_entry_uname(a, entry_main, &uname, &uname_length, NULL);
- if (r == ARCHIVE_FATAL) {
- archive_entry_free(entry_main);
- return (r);
- }
- r = get_entry_gname(a, entry_main, &gname, &gname_length, NULL);
- if (r == ARCHIVE_FATAL) {
- archive_entry_free(entry_main);
- return (r);
- }
- }
-
- /* Store the header encoding first, to be nice to readers. */
- if (sconv == NULL)
- add_pax_attr(&(pax->pax_header), "hdrcharset", "BINARY");
-
-
- /*
- * If name is too long, or has non-ASCII characters, add
- * 'path' to pax extended attrs. (Note that an unconvertible
- * name must have non-ASCII characters.)
- */
- if (has_non_ASCII(path)) {
- /* We have non-ASCII characters. */
- add_pax_attr(&(pax->pax_header), "path", path);
- archive_entry_set_pathname(entry_main,
- build_ustar_entry_name(ustar_entry_name,
- path, path_length, NULL));
- need_extension = 1;
- } else {
- /* We have an all-ASCII path; we'd like to just store
- * it in the ustar header if it will fit. Yes, this
- * duplicates some of the logic in
- * archive_write_set_format_ustar.c
- */
- if (path_length <= 100) {
- /* Fits in the old 100-char tar name field. */
- } else {
- /* Find largest suffix that will fit. */
- /* Note: strlen() > 100, so strlen() - 100 - 1 >= 0 */
- suffix = strchr(path + path_length - 100 - 1, '/');
- /* Don't attempt an empty prefix. */
- if (suffix == path)
- suffix = strchr(suffix + 1, '/');
- /* We can put it in the ustar header if it's
- * all ASCII and it's either <= 100 characters
- * or can be split at a '/' into a prefix <=
- * 155 chars and a suffix <= 100 chars. (Note
- * the strchr() above will return NULL exactly
- * when the path can't be split.)
- */
- if (suffix == NULL /* Suffix > 100 chars. */
- || suffix[1] == '\0' /* empty suffix */
- || suffix - path > 155) /* Prefix > 155 chars */
- {
- add_pax_attr(&(pax->pax_header), "path", path);
- archive_entry_set_pathname(entry_main,
- build_ustar_entry_name(ustar_entry_name,
- path, path_length, NULL));
- need_extension = 1;
- }
- }
- }
-
- if (linkpath != NULL) {
- /* If link name is too long or has non-ASCII characters, add
- * 'linkpath' to pax extended attrs. */
- if (linkpath_length > 100 || has_non_ASCII(linkpath)) {
- add_pax_attr(&(pax->pax_header), "linkpath", linkpath);
- if (linkpath_length > 100) {
- if (hardlink != NULL)
- archive_entry_set_hardlink(entry_main,
- "././@LongHardLink");
- else
- archive_entry_set_symlink(entry_main,
- "././@LongSymLink");
- }
- need_extension = 1;
- }
- }
- /* Save a pathname since it will be renamed if `entry_main` has
- * sparse blocks. */
- archive_string_init(&entry_name);
- archive_strcpy(&entry_name, archive_entry_pathname(entry_main));
-
- /* If file size is too large, we need pax extended attrs. */
- if (archive_entry_size(entry_main) >= (((int64_t)1) << 33)) {
- need_extension = 1;
- }
-
- /* If numeric GID is too large, add 'gid' to pax extended attrs. */
- if ((unsigned int)archive_entry_gid(entry_main) >= (1 << 18)) {
- add_pax_attr_int(&(pax->pax_header), "gid",
- archive_entry_gid(entry_main));
- need_extension = 1;
- }
-
- /* If group name is too large or has non-ASCII characters, add
- * 'gname' to pax extended attrs. */
- if (gname != NULL) {
- if (gname_length > 31 || has_non_ASCII(gname)) {
- add_pax_attr(&(pax->pax_header), "gname", gname);
- need_extension = 1;
- }
- }
-
- /* If numeric UID is too large, add 'uid' to pax extended attrs. */
- if ((unsigned int)archive_entry_uid(entry_main) >= (1 << 18)) {
- add_pax_attr_int(&(pax->pax_header), "uid",
- archive_entry_uid(entry_main));
- need_extension = 1;
- }
-
- /* Add 'uname' to pax extended attrs if necessary. */
- if (uname != NULL) {
- if (uname_length > 31 || has_non_ASCII(uname)) {
- add_pax_attr(&(pax->pax_header), "uname", uname);
- need_extension = 1;
- }
- }
-
- /*
- * POSIX/SUSv3 doesn't provide a standard key for large device
- * numbers. I use the same keys here that Joerg Schilling
- * used for 'star.' (Which, somewhat confusingly, are called
- * "devXXX" even though they code "rdev" values.) No doubt,
- * other implementations use other keys. Note that there's no
- * reason we can't write the same information into a number of
- * different keys.
- *
- * Of course, this is only needed for block or char device entries.
- */
- if (archive_entry_filetype(entry_main) == AE_IFBLK
- || archive_entry_filetype(entry_main) == AE_IFCHR) {
- /*
- * If rdevmajor is too large, add 'SCHILY.devmajor' to
- * extended attributes.
- */
- int rdevmajor, rdevminor;
- rdevmajor = archive_entry_rdevmajor(entry_main);
- rdevminor = archive_entry_rdevminor(entry_main);
- if (rdevmajor >= (1 << 18)) {
- add_pax_attr_int(&(pax->pax_header), "SCHILY.devmajor",
- rdevmajor);
- /*
- * Non-strict formatting below means we don't
- * have to truncate here. Not truncating improves
- * the chance that some more modern tar archivers
- * (such as GNU tar 1.13) can restore the full
- * value even if they don't understand the pax
- * extended attributes. See my rant below about
- * file size fields for additional details.
- */
- /* archive_entry_set_rdevmajor(entry_main,
- rdevmajor & ((1 << 18) - 1)); */
- need_extension = 1;
- }
-
- /*
- * If devminor is too large, add 'SCHILY.devminor' to
- * extended attributes.
- */
- if (rdevminor >= (1 << 18)) {
- add_pax_attr_int(&(pax->pax_header), "SCHILY.devminor",
- rdevminor);
- /* Truncation is not necessary here, either. */
- /* archive_entry_set_rdevminor(entry_main,
- rdevminor & ((1 << 18) - 1)); */
- need_extension = 1;
- }
- }
-
- /*
- * Yes, this check is duplicated just below; this helps to
- * avoid writing an mtime attribute just to handle a
- * high-resolution timestamp in "restricted pax" mode.
- */
- if (!need_extension &&
- ((archive_entry_mtime(entry_main) < 0)
- || (archive_entry_mtime(entry_main) >= ustar_max_mtime)))
- need_extension = 1;
-
- /* I use a star-compatible file flag attribute. */
- p = archive_entry_fflags_text(entry_main);
- if (!need_extension && p != NULL && *p != '\0')
- need_extension = 1;
-
- /* If there are extended attributes, we need an extension */
- if (!need_extension && archive_entry_xattr_count(entry_original) > 0)
- need_extension = 1;
-
- /* If there are sparse info, we need an extension */
- if (!need_extension && sparse_count > 0)
- need_extension = 1;
-
- acl_types = archive_entry_acl_types(entry_original);
-
- /* If there are any ACL entries, we need an extension */
- if (!need_extension && acl_types != 0)
- need_extension = 1;
-
- /* If the symlink type is defined, we need an extension */
- if (!need_extension && archive_entry_symlink_type(entry_main) > 0)
- need_extension = 1;
-
- /*
- * Libarchive used to include these in extended headers for
- * restricted pax format, but that confused people who
- * expected ustar-like time semantics. So now we only include
- * them in full pax format.
- */
- if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_RESTRICTED) {
- if (archive_entry_ctime(entry_main) != 0 ||
- archive_entry_ctime_nsec(entry_main) != 0)
- add_pax_attr_time(&(pax->pax_header), "ctime",
- archive_entry_ctime(entry_main),
- archive_entry_ctime_nsec(entry_main));
-
- if (archive_entry_atime(entry_main) != 0 ||
- archive_entry_atime_nsec(entry_main) != 0)
- add_pax_attr_time(&(pax->pax_header), "atime",
- archive_entry_atime(entry_main),
- archive_entry_atime_nsec(entry_main));
-
- /* Store birth/creationtime only if it's earlier than mtime */
- if (archive_entry_birthtime_is_set(entry_main) &&
- archive_entry_birthtime(entry_main)
- < archive_entry_mtime(entry_main))
- add_pax_attr_time(&(pax->pax_header),
- "LIBARCHIVE.creationtime",
- archive_entry_birthtime(entry_main),
- archive_entry_birthtime_nsec(entry_main));
- }
-
- /*
- * The following items are handled differently in "pax
- * restricted" format. In particular, in "pax restricted"
- * format they won't be added unless need_extension is
- * already set (we're already generating an extended header, so
- * may as well include these).
- */
- if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_RESTRICTED ||
- need_extension) {
- if (archive_entry_mtime(entry_main) < 0 ||
- archive_entry_mtime(entry_main) >= ustar_max_mtime ||
- archive_entry_mtime_nsec(entry_main) != 0)
- add_pax_attr_time(&(pax->pax_header), "mtime",
- archive_entry_mtime(entry_main),
- archive_entry_mtime_nsec(entry_main));
-
- /* I use a star-compatible file flag attribute. */
- p = archive_entry_fflags_text(entry_main);
- if (p != NULL && *p != '\0')
- add_pax_attr(&(pax->pax_header), "SCHILY.fflags", p);
-
- /* I use star-compatible ACL attributes. */
- if ((acl_types & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
- ret = add_pax_acl(a, entry_original, pax,
- ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID |
- ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA |
- ARCHIVE_ENTRY_ACL_STYLE_COMPACT);
- if (ret == ARCHIVE_FATAL) {
- archive_entry_free(entry_main);
- archive_string_free(&entry_name);
- return (ARCHIVE_FATAL);
- }
- }
- if (acl_types & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) {
- ret = add_pax_acl(a, entry_original, pax,
- ARCHIVE_ENTRY_ACL_TYPE_ACCESS |
- ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID |
- ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA);
- if (ret == ARCHIVE_FATAL) {
- archive_entry_free(entry_main);
- archive_string_free(&entry_name);
- return (ARCHIVE_FATAL);
- }
- }
- if (acl_types & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) {
- ret = add_pax_acl(a, entry_original, pax,
- ARCHIVE_ENTRY_ACL_TYPE_DEFAULT |
- ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID |
- ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA);
- if (ret == ARCHIVE_FATAL) {
- archive_entry_free(entry_main);
- archive_string_free(&entry_name);
- return (ARCHIVE_FATAL);
- }
- }
-
- /* We use GNU-tar-compatible sparse attributes. */
- if (sparse_count > 0) {
- int64_t soffset, slength;
-
- add_pax_attr_int(&(pax->pax_header),
- "GNU.sparse.major", 1);
- add_pax_attr_int(&(pax->pax_header),
- "GNU.sparse.minor", 0);
- /*
- * Make sure to store the original path, since
- * truncation to ustar limit happened already.
- */
- add_pax_attr(&(pax->pax_header),
- "GNU.sparse.name", path);
- add_pax_attr_int(&(pax->pax_header),
- "GNU.sparse.realsize",
- archive_entry_size(entry_main));
-
- /* Rename the file name which will be used for
- * ustar header to a special name, which GNU
- * PAX Format 1.0 requires */
- archive_entry_set_pathname(entry_main,
- build_gnu_sparse_name(gnu_sparse_name,
- entry_name.s));
-
- /*
- * - Make a sparse map, which will precede a file data.
- * - Get the total size of available data of sparse.
- */
- archive_string_sprintf(&(pax->sparse_map), "%d\n",
- sparse_count);
- while (archive_entry_sparse_next(entry_main,
- &soffset, &slength) == ARCHIVE_OK) {
- archive_string_sprintf(&(pax->sparse_map),
- "%jd\n%jd\n",
- (intmax_t)soffset,
- (intmax_t)slength);
- sparse_total += slength;
- if (sparse_list_add(pax, soffset, slength)
- != ARCHIVE_OK) {
- archive_set_error(&a->archive,
- ENOMEM,
- "Can't allocate memory");
- archive_entry_free(entry_main);
- archive_string_free(&entry_name);
- return (ARCHIVE_FATAL);
- }
- }
- }
-
- /* Store extended attributes */
- if (archive_write_pax_header_xattrs(a, pax, entry_original)
- == ARCHIVE_FATAL) {
- archive_entry_free(entry_main);
- archive_string_free(&entry_name);
- return (ARCHIVE_FATAL);
- }
-
- /* Store extended symlink information */
- if (archive_entry_symlink_type(entry_main) ==
- AE_SYMLINK_TYPE_FILE) {
- add_pax_attr(&(pax->pax_header),
- "LIBARCHIVE.symlinktype", "file");
- } else if (archive_entry_symlink_type(entry_main) ==
- AE_SYMLINK_TYPE_DIRECTORY) {
- add_pax_attr(&(pax->pax_header),
- "LIBARCHIVE.symlinktype", "dir");
- }
- }
-
- /* Only regular files have data. */
- if (archive_entry_filetype(entry_main) != AE_IFREG)
- archive_entry_set_size(entry_main, 0);
-
- /*
- * Pax-restricted does not store data for hardlinks, in order
- * to improve compatibility with ustar.
- */
- if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE &&
- hardlink != NULL)
- archive_entry_set_size(entry_main, 0);
-
- /*
- * XXX Full pax interchange format does permit a hardlink
- * entry to have data associated with it. I'm not supporting
- * that here because the client expects me to tell them whether
- * or not this format expects data for hardlinks. If I
- * don't check here, then every pax archive will end up with
- * duplicated data for hardlinks. Someday, there may be
- * need to select this behavior, in which case the following
- * will need to be revisited. XXX
- */
- if (hardlink != NULL)
- archive_entry_set_size(entry_main, 0);
-
- /* Save a real file size. */
- real_size = archive_entry_size(entry_main);
- /*
- * Overwrite a file size by the total size of sparse blocks and
- * the size of sparse map info. That file size is the length of
- * the data, which we will exactly store into an archive file.
- */
- if (archive_strlen(&(pax->sparse_map))) {
- size_t mapsize = archive_strlen(&(pax->sparse_map));
- pax->sparse_map_padding = 0x1ff & (-(ssize_t)mapsize);
- archive_entry_set_size(entry_main,
- mapsize + pax->sparse_map_padding + sparse_total);
- }
-
- /* If file size is too large, add 'size' to pax extended attrs. */
- if (archive_entry_size(entry_main) >= (((int64_t)1) << 33)) {
- add_pax_attr_int(&(pax->pax_header), "size",
- archive_entry_size(entry_main));
- }
-
- /* Format 'ustar' header for main entry.
- *
- * The trouble with file size: If the reader can't understand
- * the file size, they may not be able to locate the next
- * entry and the rest of the archive is toast. Pax-compliant
- * readers are supposed to ignore the file size in the main
- * header, so the question becomes how to maximize portability
- * for readers that don't support pax attribute extensions.
- * For maximum compatibility, I permit numeric extensions in
- * the main header so that the file size stored will always be
- * correct, even if it's in a format that only some
- * implementations understand. The technique used here is:
- *
- * a) If possible, follow the standard exactly. This handles
- * files up to 8 gigabytes minus 1.
- *
- * b) If that fails, try octal but omit the field terminator.
- * That handles files up to 64 gigabytes minus 1.
- *
- * c) Otherwise, use base-256 extensions. That handles files
- * up to 2^63 in this implementation, with the potential to
- * go up to 2^94. That should hold us for a while. ;-)
- *
- * The non-strict formatter uses similar logic for other
- * numeric fields, though they're less critical.
- */
- if (__archive_write_format_header_ustar(a, ustarbuff, entry_main, -1, 0,
- NULL) == ARCHIVE_FATAL) {
- archive_entry_free(entry_main);
- archive_string_free(&entry_name);
- return (ARCHIVE_FATAL);
- }
-
- /* If we built any extended attributes, write that entry first. */
- if (archive_strlen(&(pax->pax_header)) > 0) {
- struct archive_entry *pax_attr_entry;
- time_t s;
- int64_t uid, gid;
- int mode;
-
- pax_attr_entry = archive_entry_new2(&a->archive);
- p = entry_name.s;
- archive_entry_set_pathname(pax_attr_entry,
- build_pax_attribute_name(pax_entry_name, p));
- archive_entry_set_size(pax_attr_entry,
- archive_strlen(&(pax->pax_header)));
- /* Copy uid/gid (but clip to ustar limits). */
- uid = archive_entry_uid(entry_main);
- if (uid >= 1 << 18)
- uid = (1 << 18) - 1;
- archive_entry_set_uid(pax_attr_entry, uid);
- gid = archive_entry_gid(entry_main);
- if (gid >= 1 << 18)
- gid = (1 << 18) - 1;
- archive_entry_set_gid(pax_attr_entry, gid);
- /* Copy mode over (but not setuid/setgid bits) */
- mode = archive_entry_mode(entry_main);
-#ifdef S_ISUID
- mode &= ~S_ISUID;
-#endif
-#ifdef S_ISGID
- mode &= ~S_ISGID;
-#endif
-#ifdef S_ISVTX
- mode &= ~S_ISVTX;
-#endif
- archive_entry_set_mode(pax_attr_entry, mode);
-
- /* Copy uname/gname. */
- archive_entry_set_uname(pax_attr_entry,
- archive_entry_uname(entry_main));
- archive_entry_set_gname(pax_attr_entry,
- archive_entry_gname(entry_main));
-
- /* Copy mtime, but clip to ustar limits. */
- s = archive_entry_mtime(entry_main);
- if (s < 0) { s = 0; }
- if (s > ustar_max_mtime) { s = ustar_max_mtime; }
- archive_entry_set_mtime(pax_attr_entry, s, 0);
-
- /* Standard ustar doesn't support atime. */
- archive_entry_set_atime(pax_attr_entry, 0, 0);
-
- /* Standard ustar doesn't support ctime. */
- archive_entry_set_ctime(pax_attr_entry, 0, 0);
-
- r = __archive_write_format_header_ustar(a, paxbuff,
- pax_attr_entry, 'x', 1, NULL);
-
- archive_entry_free(pax_attr_entry);
-
- /* Note that the 'x' header shouldn't ever fail to format */
- if (r < ARCHIVE_WARN) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "archive_write_pax_header: "
- "'x' header failed?! This can't happen.\n");
- archive_entry_free(entry_main);
- archive_string_free(&entry_name);
- return (ARCHIVE_FATAL);
- } else if (r < ret)
- ret = r;
- r = __archive_write_output(a, paxbuff, 512);
- if (r != ARCHIVE_OK) {
- sparse_list_clear(pax);
- pax->entry_bytes_remaining = 0;
- pax->entry_padding = 0;
- archive_entry_free(entry_main);
- archive_string_free(&entry_name);
- return (ARCHIVE_FATAL);
- }
-
- pax->entry_bytes_remaining = archive_strlen(&(pax->pax_header));
- pax->entry_padding =
- 0x1ff & (-(int64_t)pax->entry_bytes_remaining);
-
- r = __archive_write_output(a, pax->pax_header.s,
- archive_strlen(&(pax->pax_header)));
- if (r != ARCHIVE_OK) {
- /* If a write fails, we're pretty much toast. */
- archive_entry_free(entry_main);
- archive_string_free(&entry_name);
- return (ARCHIVE_FATAL);
- }
- /* Pad out the end of the entry. */
- r = __archive_write_nulls(a, (size_t)pax->entry_padding);
- if (r != ARCHIVE_OK) {
- /* If a write fails, we're pretty much toast. */
- archive_entry_free(entry_main);
- archive_string_free(&entry_name);
- return (ARCHIVE_FATAL);
- }
- pax->entry_bytes_remaining = pax->entry_padding = 0;
- }
-
- /* Write the header for main entry. */
- r = __archive_write_output(a, ustarbuff, 512);
- if (r != ARCHIVE_OK) {
- archive_entry_free(entry_main);
- archive_string_free(&entry_name);
- return (r);
- }
-
- /*
- * Inform the client of the on-disk size we're using, so
- * they can avoid unnecessarily writing a body for something
- * that we're just going to ignore.
- */
- archive_entry_set_size(entry_original, real_size);
- if (pax->sparse_list == NULL && real_size > 0) {
- /* This is not a sparse file but we handle its data as
- * a sparse block. */
- sparse_list_add(pax, 0, real_size);
- sparse_total = real_size;
- }
- pax->entry_padding = 0x1ff & (-(int64_t)sparse_total);
- archive_entry_free(entry_main);
- archive_string_free(&entry_name);
-
- return (ret);
-}
-
-/*
- * We need a valid name for the regular 'ustar' entry. This routine
- * tries to hack something more-or-less reasonable.
- *
- * The approach here tries to preserve leading dir names. We do so by
- * working with four sections:
- * 1) "prefix" directory names,
- * 2) "suffix" directory names,
- * 3) inserted dir name (optional),
- * 4) filename.
- *
- * These sections must satisfy the following requirements:
- * * Parts 1 & 2 together form an initial portion of the dir name.
- * * Part 3 is specified by the caller. (It should not contain a leading
- * or trailing '/'.)
- * * Part 4 forms an initial portion of the base filename.
- * * The filename must be <= 99 chars to fit the ustar 'name' field.
- * * Parts 2, 3, 4 together must be <= 99 chars to fit the ustar 'name' fld.
- * * Part 1 must be <= 155 chars to fit the ustar 'prefix' field.
- * * If the original name ends in a '/', the new name must also end in a '/'
- * * Trailing '/.' sequences may be stripped.
- *
- * Note: Recall that the ustar format does not store the '/' separating
- * parts 1 & 2, but does store the '/' separating parts 2 & 3.
- */
-static char *
-build_ustar_entry_name(char *dest, const char *src, size_t src_length,
- const char *insert)
-{
- const char *prefix, *prefix_end;
- const char *suffix, *suffix_end;
- const char *filename, *filename_end;
- char *p;
- int need_slash = 0; /* Was there a trailing slash? */
- size_t suffix_length = 99;
- size_t insert_length;
-
- /* Length of additional dir element to be added. */
- if (insert == NULL)
- insert_length = 0;
- else
- /* +2 here allows for '/' before and after the insert. */
- insert_length = strlen(insert) + 2;
-
- /* Step 0: Quick bailout in a common case. */
- if (src_length < 100 && insert == NULL) {
- strncpy(dest, src, src_length);
- dest[src_length] = '\0';
- return (dest);
- }
-
- /* Step 1: Locate filename and enforce the length restriction. */
- filename_end = src + src_length;
- /* Remove trailing '/' chars and '/.' pairs. */
- for (;;) {
- if (filename_end > src && filename_end[-1] == '/') {
- filename_end --;
- need_slash = 1; /* Remember to restore trailing '/'. */
- continue;
- }
- if (filename_end > src + 1 && filename_end[-1] == '.'
- && filename_end[-2] == '/') {
- filename_end -= 2;
- need_slash = 1; /* "foo/." will become "foo/" */
- continue;
- }
- break;
- }
- if (need_slash)
- suffix_length--;
- /* Find start of filename. */
- filename = filename_end - 1;
- while ((filename > src) && (*filename != '/'))
- filename --;
- if ((*filename == '/') && (filename < filename_end - 1))
- filename ++;
- /* Adjust filename_end so that filename + insert fits in 99 chars. */
- suffix_length -= insert_length;
- if (filename_end > filename + suffix_length)
- filename_end = filename + suffix_length;
- /* Calculate max size for "suffix" section (#3 above). */
- suffix_length -= filename_end - filename;
-
- /* Step 2: Locate the "prefix" section of the dirname, including
- * trailing '/'. */
- prefix = src;
- prefix_end = prefix + 155;
- if (prefix_end > filename)
- prefix_end = filename;
- while (prefix_end > prefix && *prefix_end != '/')
- prefix_end--;
- if ((prefix_end < filename) && (*prefix_end == '/'))
- prefix_end++;
-
- /* Step 3: Locate the "suffix" section of the dirname,
- * including trailing '/'. */
- suffix = prefix_end;
- suffix_end = suffix + suffix_length; /* Enforce limit. */
- if (suffix_end > filename)
- suffix_end = filename;
- if (suffix_end < suffix)
- suffix_end = suffix;
- while (suffix_end > suffix && *suffix_end != '/')
- suffix_end--;
- if ((suffix_end < filename) && (*suffix_end == '/'))
- suffix_end++;
-
- /* Step 4: Build the new name. */
- /* The OpenBSD strlcpy function is safer, but less portable. */
- /* Rather than maintain two versions, just use the strncpy version. */
- p = dest;
- if (prefix_end > prefix) {
- strncpy(p, prefix, prefix_end - prefix);
- p += prefix_end - prefix;
- }
- if (suffix_end > suffix) {
- strncpy(p, suffix, suffix_end - suffix);
- p += suffix_end - suffix;
- }
- if (insert != NULL) {
- /* Note: assume insert does not have leading or trailing '/' */
- strcpy(p, insert);
- p += strlen(insert);
- *p++ = '/';
- }
- strncpy(p, filename, filename_end - filename);
- p += filename_end - filename;
- if (need_slash)
- *p++ = '/';
- *p = '\0';
-
- return (dest);
-}
-
-/*
- * The ustar header for the pax extended attributes must have a
- * reasonable name: SUSv3 requires 'dirname'/PaxHeader.'pid'/'filename'
- * where 'pid' is the PID of the archiving process. Unfortunately,
- * that makes testing a pain since the output varies for each run,
- * so I'm sticking with the simpler 'dirname'/PaxHeader/'filename'
- * for now. (Someday, I'll make this settable. Then I can use the
- * SUS recommendation as default and test harnesses can override it
- * to get predictable results.)
- *
- * Joerg Schilling has argued that this is unnecessary because, in
- * practice, if the pax extended attributes get extracted as regular
- * files, no one is going to bother reading those attributes to
- * manually restore them. Based on this, 'star' uses
- * /tmp/PaxHeader/'basename' as the ustar header name. This is a
- * tempting argument, in part because it's simpler than the SUSv3
- * recommendation, but I'm not entirely convinced. I'm also
- * uncomfortable with the fact that "/tmp" is a Unix-ism.
- *
- * The following routine leverages build_ustar_entry_name() above and
- * so is simpler than you might think. It just needs to provide the
- * additional path element and handle a few pathological cases).
- */
-static char *
-build_pax_attribute_name(char *dest, const char *src)
-{
- char buff[64];
- const char *p;
-
- /* Handle the null filename case. */
- if (src == NULL || *src == '\0') {
- strcpy(dest, "PaxHeader/blank");
- return (dest);
- }
-
- /* Prune final '/' and other unwanted final elements. */
- p = src + strlen(src);
- for (;;) {
- /* Ends in "/", remove the '/' */
- if (p > src && p[-1] == '/') {
- --p;
- continue;
- }
- /* Ends in "/.", remove the '.' */
- if (p > src + 1 && p[-1] == '.'
- && p[-2] == '/') {
- --p;
- continue;
- }
- break;
- }
-
- /* Pathological case: After above, there was nothing left.
- * This includes "/." "/./." "/.//./." etc. */
- if (p == src) {
- strcpy(dest, "/PaxHeader/rootdir");
- return (dest);
- }
-
- /* Convert unadorned "." into a suitable filename. */
- if (*src == '.' && p == src + 1) {
- strcpy(dest, "PaxHeader/currentdir");
- return (dest);
- }
-
- /*
- * TODO: Push this string into the 'pax' structure to avoid
- * recomputing it every time. That will also open the door
- * to having clients override it.
- */
-#if HAVE_GETPID && 0 /* Disable this for now; see above comment. */
- snprintf(buff, sizeof(buff), "PaxHeader.%d", getpid());
-#else
- /* If the platform can't fetch the pid, don't include it. */
- strcpy(buff, "PaxHeader");
-#endif
- /* General case: build a ustar-compatible name adding
- * "/PaxHeader/". */
- build_ustar_entry_name(dest, src, p - src, buff);
-
- return (dest);
-}
-
-/*
- * GNU PAX Format 1.0 requires the special name, which pattern is:
- * <dir>/GNUSparseFile.<pid>/<original file name>
- *
- * Since reproducible archives are more important, use 0 as pid.
- *
- * This function is used for only Sparse file, a file type of which
- * is regular file.
- */
-static char *
-build_gnu_sparse_name(char *dest, const char *src)
-{
- const char *p;
-
- /* Handle the null filename case. */
- if (src == NULL || *src == '\0') {
- strcpy(dest, "GNUSparseFile/blank");
- return (dest);
- }
-
- /* Prune final '/' and other unwanted final elements. */
- p = src + strlen(src);
- for (;;) {
- /* Ends in "/", remove the '/' */
- if (p > src && p[-1] == '/') {
- --p;
- continue;
- }
- /* Ends in "/.", remove the '.' */
- if (p > src + 1 && p[-1] == '.'
- && p[-2] == '/') {
- --p;
- continue;
- }
- break;
- }
-
- /* General case: build a ustar-compatible name adding
- * "/GNUSparseFile/". */
- build_ustar_entry_name(dest, src, p - src, "GNUSparseFile.0");
-
- return (dest);
-}
-
-/* Write two null blocks for the end of archive */
-static int
-archive_write_pax_close(struct archive_write *a)
-{
- return (__archive_write_nulls(a, 512 * 2));
-}
-
-static int
-archive_write_pax_free(struct archive_write *a)
-{
- struct pax *pax;
-
- pax = (struct pax *)a->format_data;
- if (pax == NULL)
- return (ARCHIVE_OK);
-
- archive_string_free(&pax->pax_header);
- archive_string_free(&pax->sparse_map);
- archive_string_free(&pax->l_url_encoded_name);
- sparse_list_clear(pax);
- free(pax);
- a->format_data = NULL;
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_pax_finish_entry(struct archive_write *a)
-{
- struct pax *pax;
- uint64_t remaining;
- int ret;
-
- pax = (struct pax *)a->format_data;
- remaining = pax->entry_bytes_remaining;
- if (remaining == 0) {
- while (pax->sparse_list) {
- struct sparse_block *sb;
- if (!pax->sparse_list->is_hole)
- remaining += pax->sparse_list->remaining;
- sb = pax->sparse_list->next;
- free(pax->sparse_list);
- pax->sparse_list = sb;
- }
- }
- ret = __archive_write_nulls(a, (size_t)(remaining + pax->entry_padding));
- pax->entry_bytes_remaining = pax->entry_padding = 0;
- return (ret);
-}
-
-static ssize_t
-archive_write_pax_data(struct archive_write *a, const void *buff, size_t s)
-{
- struct pax *pax;
- size_t ws;
- size_t total;
- int ret;
-
- pax = (struct pax *)a->format_data;
-
- /*
- * According to GNU PAX format 1.0, write a sparse map
- * before the body.
- */
- if (archive_strlen(&(pax->sparse_map))) {
- ret = __archive_write_output(a, pax->sparse_map.s,
- archive_strlen(&(pax->sparse_map)));
- if (ret != ARCHIVE_OK)
- return (ret);
- ret = __archive_write_nulls(a, pax->sparse_map_padding);
- if (ret != ARCHIVE_OK)
- return (ret);
- archive_string_empty(&(pax->sparse_map));
- }
-
- total = 0;
- while (total < s) {
- const unsigned char *p;
-
- while (pax->sparse_list != NULL &&
- pax->sparse_list->remaining == 0) {
- struct sparse_block *sb = pax->sparse_list->next;
- free(pax->sparse_list);
- pax->sparse_list = sb;
- }
-
- if (pax->sparse_list == NULL)
- return (total);
-
- p = ((const unsigned char *)buff) + total;
- ws = s - total;
- if (ws > pax->sparse_list->remaining)
- ws = (size_t)pax->sparse_list->remaining;
-
- if (pax->sparse_list->is_hole) {
- /* Current block is hole thus we do not write
- * the body. */
- pax->sparse_list->remaining -= ws;
- total += ws;
- continue;
- }
-
- ret = __archive_write_output(a, p, ws);
- pax->sparse_list->remaining -= ws;
- total += ws;
- if (ret != ARCHIVE_OK)
- return (ret);
- }
- return (total);
-}
-
-static int
-has_non_ASCII(const char *_p)
-{
- const unsigned char *p = (const unsigned char *)_p;
-
- if (p == NULL)
- return (1);
- while (*p != '\0' && *p < 128)
- p++;
- return (*p != '\0');
-}
-
-/*
- * Used by extended attribute support; encodes the name
- * so that there will be no '=' characters in the result.
- */
-static char *
-url_encode(const char *in)
-{
- const char *s;
- char *d;
- int out_len = 0;
- char *out;
-
- for (s = in; *s != '\0'; s++) {
- if (*s < 33 || *s > 126 || *s == '%' || *s == '=')
- out_len += 3;
- else
- out_len++;
- }
-
- out = (char *)malloc(out_len + 1);
- if (out == NULL)
- return (NULL);
-
- for (s = in, d = out; *s != '\0'; s++) {
- /* encode any non-printable ASCII character or '%' or '=' */
- if (*s < 33 || *s > 126 || *s == '%' || *s == '=') {
- /* URL encoding is '%' followed by two hex digits */
- *d++ = '%';
- *d++ = "0123456789ABCDEF"[0x0f & (*s >> 4)];
- *d++ = "0123456789ABCDEF"[0x0f & *s];
- } else {
- *d++ = *s;
- }
- }
- *d = '\0';
- return (out);
-}
-
-/*
- * Encode a sequence of bytes into a C string using base-64 encoding.
- *
- * Returns a null-terminated C string allocated with malloc(); caller
- * is responsible for freeing the result.
- */
-static char *
-base64_encode(const char *s, size_t len)
-{
- static const char digits[64] =
- { 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',
- 'P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d',
- 'e','f','g','h','i','j','k','l','m','n','o','p','q','r','s',
- 't','u','v','w','x','y','z','0','1','2','3','4','5','6','7',
- '8','9','+','/' };
- int v;
- char *d, *out;
-
- /* 3 bytes becomes 4 chars, but round up and allow for trailing NUL */
- out = (char *)malloc((len * 4 + 2) / 3 + 1);
- if (out == NULL)
- return (NULL);
- d = out;
-
- /* Convert each group of 3 bytes into 4 characters. */
- while (len >= 3) {
- v = (((int)s[0] << 16) & 0xff0000)
- | (((int)s[1] << 8) & 0xff00)
- | (((int)s[2]) & 0x00ff);
- s += 3;
- len -= 3;
- *d++ = digits[(v >> 18) & 0x3f];
- *d++ = digits[(v >> 12) & 0x3f];
- *d++ = digits[(v >> 6) & 0x3f];
- *d++ = digits[(v) & 0x3f];
- }
- /* Handle final group of 1 byte (2 chars) or 2 bytes (3 chars). */
- switch (len) {
- case 0: break;
- case 1:
- v = (((int)s[0] << 16) & 0xff0000);
- *d++ = digits[(v >> 18) & 0x3f];
- *d++ = digits[(v >> 12) & 0x3f];
- break;
- case 2:
- v = (((int)s[0] << 16) & 0xff0000)
- | (((int)s[1] << 8) & 0xff00);
- *d++ = digits[(v >> 18) & 0x3f];
- *d++ = digits[(v >> 12) & 0x3f];
- *d++ = digits[(v >> 6) & 0x3f];
- break;
- }
- /* Add trailing NUL character so output is a valid C string. */
- *d = '\0';
- return (out);
-}
-
-static void
-sparse_list_clear(struct pax *pax)
-{
- while (pax->sparse_list != NULL) {
- struct sparse_block *sb = pax->sparse_list;
- pax->sparse_list = sb->next;
- free(sb);
- }
- pax->sparse_tail = NULL;
-}
-
-static int
-_sparse_list_add_block(struct pax *pax, int64_t offset, int64_t length,
- int is_hole)
-{
- struct sparse_block *sb;
-
- sb = (struct sparse_block *)malloc(sizeof(*sb));
- if (sb == NULL)
- return (ARCHIVE_FATAL);
- sb->next = NULL;
- sb->is_hole = is_hole;
- sb->offset = offset;
- sb->remaining = length;
- if (pax->sparse_list == NULL || pax->sparse_tail == NULL)
- pax->sparse_list = pax->sparse_tail = sb;
- else {
- pax->sparse_tail->next = sb;
- pax->sparse_tail = sb;
- }
- return (ARCHIVE_OK);
-}
-
-static int
-sparse_list_add(struct pax *pax, int64_t offset, int64_t length)
-{
- int64_t last_offset;
- int r;
-
- if (pax->sparse_tail == NULL)
- last_offset = 0;
- else {
- last_offset = pax->sparse_tail->offset +
- pax->sparse_tail->remaining;
- }
- if (last_offset < offset) {
- /* Add a hole block. */
- r = _sparse_list_add_block(pax, last_offset,
- offset - last_offset, 1);
- if (r != ARCHIVE_OK)
- return (r);
- }
- /* Add data block. */
- return (_sparse_list_add_block(pax, offset, length, 0));
-}
-
-static time_t
-get_ustar_max_mtime(void)
-{
- /*
- * Technically, the mtime field in the ustar header can
- * support 33 bits. We are using all of them to keep
- * tar/test/test_option_C_mtree.c simple and passing after 2038.
- * For platforms that use signed 32-bit time values we
- * use the 32-bit maximum.
- */
- if (sizeof(time_t) > sizeof(int32_t))
- return (time_t)0x1ffffffff;
- else
- return (time_t)0x7fffffff;
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_format_private.h b/contrib/libs/libarchive/libarchive/archive_write_set_format_private.h
deleted file mode 100644
index e20022755f..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_format_private.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*-
- * Copyright (c) 2020 Martin Matuska
- * 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(S) ``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(S) 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.
- *
- * $FreeBSD$
- */
-
-#ifndef ARCHIVE_WRITE_SET_FORMAT_PRIVATE_H_INCLUDED
-#define ARCHIVE_WRITE_SET_FORMAT_PRIVATE_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#ifndef __LIBARCHIVE_TEST
-#error This header is only to be used internally to libarchive.
-#endif
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-
-void __archive_write_entry_filetype_unsupported(struct archive *a,
- struct archive_entry *entry, const char *format);
-#endif
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_format_raw.c b/contrib/libs/libarchive/libarchive/archive_write_set_format_raw.c
deleted file mode 100644
index feff936977..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_format_raw.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*-
- * Copyright (c) 2013 Marek Kubica
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
-#include "archive_entry.h"
-#include "archive_write_private.h"
-
-static ssize_t archive_write_raw_data(struct archive_write *,
- const void *buff, size_t s);
-static int archive_write_raw_free(struct archive_write *);
-static int archive_write_raw_header(struct archive_write *,
- struct archive_entry *);
-
-struct raw {
- int entries_written;
-};
-
-/*
- * Set output format to 'raw' format.
- */
-int
-archive_write_set_format_raw(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct raw *raw;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_format_raw");
-
- /* If someone else was already registered, unregister them. */
- if (a->format_free != NULL)
- (a->format_free)(a);
-
- raw = (struct raw *)calloc(1, sizeof(*raw));
- if (raw == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Can't allocate raw data");
- return (ARCHIVE_FATAL);
- }
- raw->entries_written = 0;
- a->format_data = raw;
- a->format_name = "raw";
- /* no options exist for this format */
- a->format_options = NULL;
- a->format_write_header = archive_write_raw_header;
- a->format_write_data = archive_write_raw_data;
- a->format_finish_entry = NULL;
- /* nothing needs to be done on closing */
- a->format_close = NULL;
- a->format_free = archive_write_raw_free;
- a->archive.archive_format = ARCHIVE_FORMAT_RAW;
- a->archive.archive_format_name = "RAW";
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_raw_header(struct archive_write *a, struct archive_entry *entry)
-{
- struct raw *raw = (struct raw *)a->format_data;
-
- if (archive_entry_filetype(entry) != AE_IFREG) {
- archive_set_error(&a->archive, ERANGE,
- "Raw format only supports filetype AE_IFREG");
- return (ARCHIVE_FATAL);
- }
-
-
- if (raw->entries_written > 0) {
- archive_set_error(&a->archive, ERANGE,
- "Raw format only supports one entry per archive");
- return (ARCHIVE_FATAL);
- }
- raw->entries_written++;
-
- return (ARCHIVE_OK);
-}
-
-static ssize_t
-archive_write_raw_data(struct archive_write *a, const void *buff, size_t s)
-{
- int ret;
-
- ret = __archive_write_output(a, buff, s);
- if (ret >= 0)
- return (s);
- else
- return (ret);
-}
-
-static int
-archive_write_raw_free(struct archive_write *a)
-{
- struct raw *raw;
-
- raw = (struct raw *)a->format_data;
- free(raw);
- a->format_data = NULL;
- return (ARCHIVE_OK);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_format_shar.c b/contrib/libs/libarchive/libarchive/archive_write_set_format_shar.c
deleted file mode 100644
index 9e4931c95c..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_format_shar.c
+++ /dev/null
@@ -1,641 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * Copyright (c) 2008 Joerg Sonnenberger
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_shar.c 189438 2009-03-06 05:58:56Z kientzle $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_private.h"
-#include "archive_write_private.h"
-#include "archive_write_set_format_private.h"
-
-struct shar {
- int dump;
- int end_of_line;
- struct archive_entry *entry;
- int has_data;
- char *last_dir;
-
- /* Line buffer for uuencoded dump format */
- char outbuff[45];
- size_t outpos;
-
- int wrote_header;
- struct archive_string work;
- struct archive_string quoted_name;
-};
-
-static int archive_write_shar_close(struct archive_write *);
-static int archive_write_shar_free(struct archive_write *);
-static int archive_write_shar_header(struct archive_write *,
- struct archive_entry *);
-static ssize_t archive_write_shar_data_sed(struct archive_write *,
- const void * buff, size_t);
-static ssize_t archive_write_shar_data_uuencode(struct archive_write *,
- const void * buff, size_t);
-static int archive_write_shar_finish_entry(struct archive_write *);
-
-/*
- * Copy the given string to the buffer, quoting all shell meta characters
- * found.
- */
-static void
-shar_quote(struct archive_string *buf, const char *str, int in_shell)
-{
- static const char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~";
- size_t len;
-
- while (*str != '\0') {
- if ((len = strcspn(str, meta)) != 0) {
- archive_strncat(buf, str, len);
- str += len;
- } else if (*str == '\n') {
- if (in_shell)
- archive_strcat(buf, "\"\n\"");
- else
- archive_strcat(buf, "\\n");
- ++str;
- } else {
- archive_strappend_char(buf, '\\');
- archive_strappend_char(buf, *str);
- ++str;
- }
- }
-}
-
-/*
- * Set output format to 'shar' format.
- */
-int
-archive_write_set_format_shar(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct shar *shar;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_format_shar");
-
- /* If someone else was already registered, unregister them. */
- if (a->format_free != NULL)
- (a->format_free)(a);
-
- shar = (struct shar *)calloc(1, sizeof(*shar));
- if (shar == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Can't allocate shar data");
- return (ARCHIVE_FATAL);
- }
- archive_string_init(&shar->work);
- archive_string_init(&shar->quoted_name);
- a->format_data = shar;
- a->format_name = "shar";
- a->format_write_header = archive_write_shar_header;
- a->format_close = archive_write_shar_close;
- a->format_free = archive_write_shar_free;
- a->format_write_data = archive_write_shar_data_sed;
- a->format_finish_entry = archive_write_shar_finish_entry;
- a->archive.archive_format = ARCHIVE_FORMAT_SHAR_BASE;
- a->archive.archive_format_name = "shar";
- return (ARCHIVE_OK);
-}
-
-/*
- * An alternate 'shar' that uses uudecode instead of 'sed' to encode
- * file contents and can therefore be used to archive binary files.
- * In addition, this variant also attempts to restore ownership, file modes,
- * and other extended file information.
- */
-int
-archive_write_set_format_shar_dump(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct shar *shar;
-
- archive_write_set_format_shar(&a->archive);
- shar = (struct shar *)a->format_data;
- shar->dump = 1;
- a->format_write_data = archive_write_shar_data_uuencode;
- a->archive.archive_format = ARCHIVE_FORMAT_SHAR_DUMP;
- a->archive.archive_format_name = "shar dump";
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_shar_header(struct archive_write *a, struct archive_entry *entry)
-{
- const char *linkname;
- const char *name;
- char *p, *pp;
- struct shar *shar;
-
- shar = (struct shar *)a->format_data;
- if (!shar->wrote_header) {
- archive_strcat(&shar->work, "#!/bin/sh\n");
- archive_strcat(&shar->work, "# This is a shell archive\n");
- shar->wrote_header = 1;
- }
-
- /* Save the entry for the closing. */
- archive_entry_free(shar->entry);
- shar->entry = archive_entry_clone(entry);
- name = archive_entry_pathname(entry);
-
- /* Handle some preparatory issues. */
- switch(archive_entry_filetype(entry)) {
- case AE_IFREG:
- /* Only regular files have non-zero size. */
- break;
- case AE_IFDIR:
- archive_entry_set_size(entry, 0);
- /* Don't bother trying to recreate '.' */
- if (strcmp(name, ".") == 0 || strcmp(name, "./") == 0)
- return (ARCHIVE_OK);
- break;
- case AE_IFIFO:
- case AE_IFCHR:
- case AE_IFBLK:
- /* All other file types have zero size in the archive. */
- archive_entry_set_size(entry, 0);
- break;
- default:
- archive_entry_set_size(entry, 0);
- if (archive_entry_hardlink(entry) == NULL &&
- archive_entry_symlink(entry) == NULL) {
- __archive_write_entry_filetype_unsupported(
- &a->archive, entry, "shar");
- return (ARCHIVE_WARN);
- }
- }
-
- archive_string_empty(&shar->quoted_name);
- shar_quote(&shar->quoted_name, name, 1);
-
- /* Stock preparation for all file types. */
- archive_string_sprintf(&shar->work, "echo x %s\n", shar->quoted_name.s);
-
- if (archive_entry_filetype(entry) != AE_IFDIR) {
- /* Try to create the dir. */
- p = strdup(name);
- pp = strrchr(p, '/');
- /* If there is a / character, try to create the dir. */
- if (pp != NULL) {
- *pp = '\0';
-
- /* Try to avoid a lot of redundant mkdir commands. */
- if (strcmp(p, ".") == 0) {
- /* Don't try to "mkdir ." */
- free(p);
- } else if (shar->last_dir == NULL) {
- archive_strcat(&shar->work, "mkdir -p ");
- shar_quote(&shar->work, p, 1);
- archive_strcat(&shar->work,
- " > /dev/null 2>&1\n");
- shar->last_dir = p;
- } else if (strcmp(p, shar->last_dir) == 0) {
- /* We've already created this exact dir. */
- free(p);
- } else if (strlen(p) < strlen(shar->last_dir) &&
- strncmp(p, shar->last_dir, strlen(p)) == 0) {
- /* We've already created a subdir. */
- free(p);
- } else {
- archive_strcat(&shar->work, "mkdir -p ");
- shar_quote(&shar->work, p, 1);
- archive_strcat(&shar->work,
- " > /dev/null 2>&1\n");
- shar->last_dir = p;
- }
- } else {
- free(p);
- }
- }
-
- /* Handle file-type specific issues. */
- shar->has_data = 0;
- if ((linkname = archive_entry_hardlink(entry)) != NULL) {
- archive_strcat(&shar->work, "ln -f ");
- shar_quote(&shar->work, linkname, 1);
- archive_string_sprintf(&shar->work, " %s\n",
- shar->quoted_name.s);
- } else if ((linkname = archive_entry_symlink(entry)) != NULL) {
- archive_strcat(&shar->work, "ln -fs ");
- shar_quote(&shar->work, linkname, 1);
- archive_string_sprintf(&shar->work, " %s\n",
- shar->quoted_name.s);
- } else {
- switch(archive_entry_filetype(entry)) {
- case AE_IFREG:
- if (archive_entry_size(entry) == 0) {
- /* More portable than "touch." */
- archive_string_sprintf(&shar->work,
- "test -e \"%s\" || :> \"%s\"\n",
- shar->quoted_name.s, shar->quoted_name.s);
- } else {
- if (shar->dump) {
- unsigned int mode = archive_entry_mode(entry) & 0777;
- archive_string_sprintf(&shar->work,
- "uudecode -p > %s << 'SHAR_END'\n",
- shar->quoted_name.s);
- archive_string_sprintf(&shar->work,
- "begin %o ", mode);
- shar_quote(&shar->work, name, 0);
- archive_strcat(&shar->work, "\n");
- } else {
- archive_string_sprintf(&shar->work,
- "sed 's/^X//' > %s << 'SHAR_END'\n",
- shar->quoted_name.s);
- }
- shar->has_data = 1;
- shar->end_of_line = 1;
- shar->outpos = 0;
- }
- break;
- case AE_IFDIR:
- archive_string_sprintf(&shar->work,
- "mkdir -p %s > /dev/null 2>&1\n",
- shar->quoted_name.s);
- /* Record that we just created this directory. */
- free(shar->last_dir);
-
- shar->last_dir = strdup(name);
- /* Trim a trailing '/'. */
- pp = strrchr(shar->last_dir, '/');
- if (pp != NULL && pp[1] == '\0')
- *pp = '\0';
- /*
- * TODO: Put dir name/mode on a list to be fixed
- * up at end of archive.
- */
- break;
- case AE_IFIFO:
- archive_string_sprintf(&shar->work,
- "mkfifo %s\n", shar->quoted_name.s);
- break;
- case AE_IFCHR:
- archive_string_sprintf(&shar->work,
- "mknod %s c %ju %ju\n", shar->quoted_name.s,
- (uintmax_t)archive_entry_rdevmajor(entry),
- (uintmax_t)archive_entry_rdevminor(entry));
- break;
- case AE_IFBLK:
- archive_string_sprintf(&shar->work,
- "mknod %s b %ju %ju\n", shar->quoted_name.s,
- (uintmax_t)archive_entry_rdevmajor(entry),
- (uintmax_t)archive_entry_rdevminor(entry));
- break;
- default:
- return (ARCHIVE_WARN);
- }
- }
-
- return (ARCHIVE_OK);
-}
-
-static ssize_t
-archive_write_shar_data_sed(struct archive_write *a, const void *buff, size_t n)
-{
- static const size_t ensured = 65533;
- struct shar *shar;
- const char *src;
- char *buf, *buf_end;
- int ret;
- size_t written = n;
-
- shar = (struct shar *)a->format_data;
- if (!shar->has_data || n == 0)
- return (0);
-
- src = (const char *)buff;
-
- /*
- * ensure is the number of bytes in buffer before expanding the
- * current character. Each operation writes the current character
- * and optionally the start-of-new-line marker. This can happen
- * twice before entering the loop, so make sure three additional
- * bytes can be written.
- */
- if (archive_string_ensure(&shar->work, ensured + 3) == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
-
- if (shar->work.length > ensured) {
- ret = __archive_write_output(a, shar->work.s,
- shar->work.length);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- archive_string_empty(&shar->work);
- }
- buf = shar->work.s + shar->work.length;
- buf_end = shar->work.s + ensured;
-
- if (shar->end_of_line) {
- *buf++ = 'X';
- shar->end_of_line = 0;
- }
-
- while (n-- != 0) {
- if ((*buf++ = *src++) == '\n') {
- if (n == 0)
- shar->end_of_line = 1;
- else
- *buf++ = 'X';
- }
-
- if (buf >= buf_end) {
- shar->work.length = buf - shar->work.s;
- ret = __archive_write_output(a, shar->work.s,
- shar->work.length);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- archive_string_empty(&shar->work);
- buf = shar->work.s;
- }
- }
-
- shar->work.length = buf - shar->work.s;
-
- return (written);
-}
-
-#define UUENC(c) (((c)!=0) ? ((c) & 077) + ' ': '`')
-
-static void
-uuencode_group(const char _in[3], char out[4])
-{
- const unsigned char *in = (const unsigned char *)_in;
- int t;
-
- t = (in[0] << 16) | (in[1] << 8) | in[2];
- out[0] = UUENC( 0x3f & (t >> 18) );
- out[1] = UUENC( 0x3f & (t >> 12) );
- out[2] = UUENC( 0x3f & (t >> 6) );
- out[3] = UUENC( 0x3f & t );
-}
-
-static int
-_uuencode_line(struct archive_write *a, struct shar *shar, const char *inbuf, size_t len)
-{
- char *buf;
- size_t alloc_len;
-
- /* len <= 45 -> expanded to 60 + len byte + new line */
- alloc_len = shar->work.length + 62;
- if (archive_string_ensure(&shar->work, alloc_len) == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
-
- buf = shar->work.s + shar->work.length;
- *buf++ = UUENC(len);
- while (len >= 3) {
- uuencode_group(inbuf, buf);
- len -= 3;
- inbuf += 3;
- buf += 4;
- }
- if (len != 0) {
- char tmp_buf[3];
- tmp_buf[0] = inbuf[0];
- if (len == 1)
- tmp_buf[1] = '\0';
- else
- tmp_buf[1] = inbuf[1];
- tmp_buf[2] = '\0';
- uuencode_group(tmp_buf, buf);
- buf += 4;
- }
- *buf++ = '\n';
- if ((buf - shar->work.s) > (ptrdiff_t)(shar->work.length + 62)) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC, "Buffer overflow");
- return (ARCHIVE_FATAL);
- }
- shar->work.length = buf - shar->work.s;
- return (ARCHIVE_OK);
-}
-
-#define uuencode_line(__a, __shar, __inbuf, __len) \
- do { \
- int r = _uuencode_line(__a, __shar, __inbuf, __len); \
- if (r != ARCHIVE_OK) \
- return (ARCHIVE_FATAL); \
- } while (0)
-
-static ssize_t
-archive_write_shar_data_uuencode(struct archive_write *a, const void *buff,
- size_t length)
-{
- struct shar *shar;
- const char *src;
- size_t n;
- int ret;
-
- shar = (struct shar *)a->format_data;
- if (!shar->has_data)
- return (ARCHIVE_OK);
- src = (const char *)buff;
-
- if (shar->outpos != 0) {
- n = 45 - shar->outpos;
- if (n > length)
- n = length;
- memcpy(shar->outbuff + shar->outpos, src, n);
- if (shar->outpos + n < 45) {
- shar->outpos += n;
- return length;
- }
- uuencode_line(a, shar, shar->outbuff, 45);
- src += n;
- n = length - n;
- } else {
- n = length;
- }
-
- while (n >= 45) {
- uuencode_line(a, shar, src, 45);
- src += 45;
- n -= 45;
-
- if (shar->work.length < 65536)
- continue;
- ret = __archive_write_output(a, shar->work.s,
- shar->work.length);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- archive_string_empty(&shar->work);
- }
- if (n != 0) {
- memcpy(shar->outbuff, src, n);
- shar->outpos = n;
- }
- return (length);
-}
-
-static int
-archive_write_shar_finish_entry(struct archive_write *a)
-{
- const char *g, *p, *u;
- struct shar *shar;
- int ret;
-
- shar = (struct shar *)a->format_data;
- if (shar->entry == NULL)
- return (0);
-
- if (shar->dump) {
- /* Finish uuencoded data. */
- if (shar->has_data) {
- if (shar->outpos > 0)
- uuencode_line(a, shar, shar->outbuff,
- shar->outpos);
- archive_strcat(&shar->work, "`\nend\n");
- archive_strcat(&shar->work, "SHAR_END\n");
- }
- /* Restore file mode, owner, flags. */
- /*
- * TODO: Don't immediately restore mode for
- * directories; defer that to end of script.
- */
- archive_string_sprintf(&shar->work, "chmod %o ",
- (unsigned int)(archive_entry_mode(shar->entry) & 07777));
- shar_quote(&shar->work, archive_entry_pathname(shar->entry), 1);
- archive_strcat(&shar->work, "\n");
-
- u = archive_entry_uname(shar->entry);
- g = archive_entry_gname(shar->entry);
- if (u != NULL || g != NULL) {
- archive_strcat(&shar->work, "chown ");
- if (u != NULL)
- shar_quote(&shar->work, u, 1);
- if (g != NULL) {
- archive_strcat(&shar->work, ":");
- shar_quote(&shar->work, g, 1);
- }
- archive_strcat(&shar->work, " ");
- shar_quote(&shar->work,
- archive_entry_pathname(shar->entry), 1);
- archive_strcat(&shar->work, "\n");
- }
-
- if ((p = archive_entry_fflags_text(shar->entry)) != NULL) {
- archive_string_sprintf(&shar->work, "chflags %s ", p);
- shar_quote(&shar->work,
- archive_entry_pathname(shar->entry), 1);
- archive_strcat(&shar->work, "\n");
- }
-
- /* TODO: restore ACLs */
-
- } else {
- if (shar->has_data) {
- /* Finish sed-encoded data: ensure last line ends. */
- if (!shar->end_of_line)
- archive_strappend_char(&shar->work, '\n');
- archive_strcat(&shar->work, "SHAR_END\n");
- }
- }
-
- archive_entry_free(shar->entry);
- shar->entry = NULL;
-
- if (shar->work.length < 65536)
- return (ARCHIVE_OK);
-
- ret = __archive_write_output(a, shar->work.s, shar->work.length);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- archive_string_empty(&shar->work);
-
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_shar_close(struct archive_write *a)
-{
- struct shar *shar;
- int ret;
-
- /*
- * TODO: Accumulate list of directory names/modes and
- * fix them all up at end-of-archive.
- */
-
- shar = (struct shar *)a->format_data;
-
- /*
- * Only write the end-of-archive markers if the archive was
- * actually started. This avoids problems if someone sets
- * shar format, then sets another format (which would invoke
- * shar_finish to free the format-specific data).
- */
- if (shar->wrote_header == 0)
- return (ARCHIVE_OK);
-
- archive_strcat(&shar->work, "exit\n");
-
- ret = __archive_write_output(a, shar->work.s, shar->work.length);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /* Shar output is never padded. */
- archive_write_set_bytes_in_last_block(&a->archive, 1);
- /*
- * TODO: shar should also suppress padding of
- * uncompressed data within gzip/bzip2 streams.
- */
-
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_shar_free(struct archive_write *a)
-{
- struct shar *shar;
-
- shar = (struct shar *)a->format_data;
- if (shar == NULL)
- return (ARCHIVE_OK);
-
- archive_entry_free(shar->entry);
- free(shar->last_dir);
- archive_string_free(&(shar->work));
- archive_string_free(&(shar->quoted_name));
- free(shar);
- a->format_data = NULL;
- return (ARCHIVE_OK);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_format_ustar.c b/contrib/libs/libarchive/libarchive/archive_write_set_format_ustar.c
deleted file mode 100644
index d1a06bc4f7..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_format_ustar.c
+++ /dev/null
@@ -1,758 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * Copyright (c) 2011-2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_ustar.c 191579 2009-04-27 18:35:03Z kientzle $");
-
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_private.h"
-#include "archive_write_private.h"
-#include "archive_write_set_format_private.h"
-
-struct ustar {
- uint64_t entry_bytes_remaining;
- uint64_t entry_padding;
-
- struct archive_string_conv *opt_sconv;
- struct archive_string_conv *sconv_default;
- int init_default_conversion;
-};
-
-/*
- * Define structure of POSIX 'ustar' tar header.
- */
-#define USTAR_name_offset 0
-#define USTAR_name_size 100
-#define USTAR_mode_offset 100
-#define USTAR_mode_size 6
-#define USTAR_mode_max_size 8
-#define USTAR_uid_offset 108
-#define USTAR_uid_size 6
-#define USTAR_uid_max_size 8
-#define USTAR_gid_offset 116
-#define USTAR_gid_size 6
-#define USTAR_gid_max_size 8
-#define USTAR_size_offset 124
-#define USTAR_size_size 11
-#define USTAR_size_max_size 12
-#define USTAR_mtime_offset 136
-#define USTAR_mtime_size 11
-#define USTAR_mtime_max_size 11
-#define USTAR_checksum_offset 148
-#define USTAR_checksum_size 8
-#define USTAR_typeflag_offset 156
-#define USTAR_typeflag_size 1
-#define USTAR_linkname_offset 157
-#define USTAR_linkname_size 100
-#define USTAR_magic_offset 257
-#define USTAR_magic_size 6
-#define USTAR_version_offset 263
-#define USTAR_version_size 2
-#define USTAR_uname_offset 265
-#define USTAR_uname_size 32
-#define USTAR_gname_offset 297
-#define USTAR_gname_size 32
-#define USTAR_rdevmajor_offset 329
-#define USTAR_rdevmajor_size 6
-#define USTAR_rdevmajor_max_size 8
-#define USTAR_rdevminor_offset 337
-#define USTAR_rdevminor_size 6
-#define USTAR_rdevminor_max_size 8
-#define USTAR_prefix_offset 345
-#define USTAR_prefix_size 155
-#define USTAR_padding_offset 500
-#define USTAR_padding_size 12
-
-/*
- * A filled-in copy of the header for initialization.
- */
-static const char template_header[] = {
- /* name: 100 bytes */
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,
- /* Mode, space-null termination: 8 bytes */
- '0','0','0','0','0','0', ' ','\0',
- /* uid, space-null termination: 8 bytes */
- '0','0','0','0','0','0', ' ','\0',
- /* gid, space-null termination: 8 bytes */
- '0','0','0','0','0','0', ' ','\0',
- /* size, space termination: 12 bytes */
- '0','0','0','0','0','0','0','0','0','0','0', ' ',
- /* mtime, space termination: 12 bytes */
- '0','0','0','0','0','0','0','0','0','0','0', ' ',
- /* Initial checksum value: 8 spaces */
- ' ',' ',' ',' ',' ',' ',' ',' ',
- /* Typeflag: 1 byte */
- '0', /* '0' = regular file */
- /* Linkname: 100 bytes */
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,
- /* Magic: 6 bytes, Version: 2 bytes */
- 'u','s','t','a','r','\0', '0','0',
- /* Uname: 32 bytes */
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- /* Gname: 32 bytes */
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- /* rdevmajor + space/null padding: 8 bytes */
- '0','0','0','0','0','0', ' ','\0',
- /* rdevminor + space/null padding: 8 bytes */
- '0','0','0','0','0','0', ' ','\0',
- /* Prefix: 155 bytes */
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,
- /* Padding: 12 bytes */
- 0,0,0,0,0,0,0,0, 0,0,0,0
-};
-
-static ssize_t archive_write_ustar_data(struct archive_write *a, const void *buff,
- size_t s);
-static int archive_write_ustar_free(struct archive_write *);
-static int archive_write_ustar_close(struct archive_write *);
-static int archive_write_ustar_finish_entry(struct archive_write *);
-static int archive_write_ustar_header(struct archive_write *,
- struct archive_entry *entry);
-static int archive_write_ustar_options(struct archive_write *,
- const char *, const char *);
-static int format_256(int64_t, char *, int);
-static int format_number(int64_t, char *, int size, int max, int strict);
-static int format_octal(int64_t, char *, int);
-
-/*
- * Set output format to 'ustar' format.
- */
-int
-archive_write_set_format_ustar(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct ustar *ustar;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_format_ustar");
-
- /* If someone else was already registered, unregister them. */
- if (a->format_free != NULL)
- (a->format_free)(a);
-
- /* Basic internal sanity test. */
- if (sizeof(template_header) != 512) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Internal: template_header wrong size: %zu should be 512",
- sizeof(template_header));
- return (ARCHIVE_FATAL);
- }
-
- ustar = (struct ustar *)calloc(1, sizeof(*ustar));
- if (ustar == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate ustar data");
- return (ARCHIVE_FATAL);
- }
- a->format_data = ustar;
- a->format_name = "ustar";
- a->format_options = archive_write_ustar_options;
- a->format_write_header = archive_write_ustar_header;
- a->format_write_data = archive_write_ustar_data;
- a->format_close = archive_write_ustar_close;
- a->format_free = archive_write_ustar_free;
- a->format_finish_entry = archive_write_ustar_finish_entry;
- a->archive.archive_format = ARCHIVE_FORMAT_TAR_USTAR;
- a->archive.archive_format_name = "POSIX ustar";
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_ustar_options(struct archive_write *a, const char *key,
- const char *val)
-{
- struct ustar *ustar = (struct ustar *)a->format_data;
- int ret = ARCHIVE_FAILED;
-
- if (strcmp(key, "hdrcharset") == 0) {
- if (val == NULL || val[0] == 0)
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "%s: hdrcharset option needs a character-set name",
- a->format_name);
- else {
- ustar->opt_sconv = archive_string_conversion_to_charset(
- &a->archive, val, 0);
- if (ustar->opt_sconv != NULL)
- ret = ARCHIVE_OK;
- else
- ret = ARCHIVE_FATAL;
- }
- return (ret);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-static int
-archive_write_ustar_header(struct archive_write *a, struct archive_entry *entry)
-{
- char buff[512];
- int ret, ret2;
- struct ustar *ustar;
- struct archive_entry *entry_main;
- struct archive_string_conv *sconv;
-
- ustar = (struct ustar *)a->format_data;
-
- /* Setup default string conversion. */
- if (ustar->opt_sconv == NULL) {
- if (!ustar->init_default_conversion) {
- ustar->sconv_default =
- archive_string_default_conversion_for_write(&(a->archive));
- ustar->init_default_conversion = 1;
- }
- sconv = ustar->sconv_default;
- } else
- sconv = ustar->opt_sconv;
-
- /* Sanity check. */
- if (archive_entry_pathname(entry) == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Can't record entry in tar file without pathname");
- return (ARCHIVE_FAILED);
- }
-
- /* Only regular files (not hardlinks) have data. */
- if (archive_entry_hardlink(entry) != NULL ||
- archive_entry_symlink(entry) != NULL ||
- !(archive_entry_filetype(entry) == AE_IFREG))
- archive_entry_set_size(entry, 0);
-
- if (AE_IFDIR == archive_entry_filetype(entry)) {
- const char *p;
- size_t path_length;
- /*
- * Ensure a trailing '/'. Modify the entry so
- * the client sees the change.
- */
-#if defined(_WIN32) && !defined(__CYGWIN__)
- const wchar_t *wp;
-
- wp = archive_entry_pathname_w(entry);
- if (wp != NULL && wp[wcslen(wp) -1] != L'/') {
- struct archive_wstring ws;
-
- archive_string_init(&ws);
- path_length = wcslen(wp);
- if (archive_wstring_ensure(&ws,
- path_length + 2) == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate ustar data");
- archive_wstring_free(&ws);
- return(ARCHIVE_FATAL);
- }
- /* Should we keep '\' ? */
- if (wp[path_length -1] == L'\\')
- path_length--;
- archive_wstrncpy(&ws, wp, path_length);
- archive_wstrappend_wchar(&ws, L'/');
- archive_entry_copy_pathname_w(entry, ws.s);
- archive_wstring_free(&ws);
- p = NULL;
- } else
-#endif
- p = archive_entry_pathname(entry);
- /*
- * On Windows, this is a backup operation just in
- * case getting WCS failed. On POSIX, this is a
- * normal operation.
- */
- if (p != NULL && p[0] != '\0' && p[strlen(p) - 1] != '/') {
- struct archive_string as;
-
- archive_string_init(&as);
- path_length = strlen(p);
- if (archive_string_ensure(&as,
- path_length + 2) == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate ustar data");
- archive_string_free(&as);
- return(ARCHIVE_FATAL);
- }
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* NOTE: This might break the pathname
- * if the current code page is CP932 and
- * the pathname includes a character '\'
- * as a part of its multibyte pathname. */
- if (p[strlen(p) -1] == '\\')
- path_length--;
- else
-#endif
- archive_strncpy(&as, p, path_length);
- archive_strappend_char(&as, '/');
- archive_entry_copy_pathname(entry, as.s);
- archive_string_free(&as);
- }
- }
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Make sure the path separators in pathname, hardlink and symlink
- * are all slash '/', not the Windows path separator '\'. */
- entry_main = __la_win_entry_in_posix_pathseparator(entry);
- if (entry_main == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate ustar data");
- return(ARCHIVE_FATAL);
- }
- if (entry != entry_main)
- entry = entry_main;
- else
- entry_main = NULL;
-#else
- entry_main = NULL;
-#endif
- ret = __archive_write_format_header_ustar(a, buff, entry, -1, 1, sconv);
- if (ret < ARCHIVE_WARN) {
- archive_entry_free(entry_main);
- return (ret);
- }
- ret2 = __archive_write_output(a, buff, 512);
- if (ret2 < ARCHIVE_WARN) {
- archive_entry_free(entry_main);
- return (ret2);
- }
- if (ret2 < ret)
- ret = ret2;
-
- ustar->entry_bytes_remaining = archive_entry_size(entry);
- ustar->entry_padding = 0x1ff & (-(int64_t)ustar->entry_bytes_remaining);
- archive_entry_free(entry_main);
- return (ret);
-}
-
-/*
- * Format a basic 512-byte "ustar" header.
- *
- * Returns -1 if format failed (due to field overflow).
- * Note that this always formats as much of the header as possible.
- * If "strict" is set to zero, it will extend numeric fields as
- * necessary (overwriting terminators or using base-256 extensions).
- *
- * This is exported so that other 'tar' formats can use it.
- */
-int
-__archive_write_format_header_ustar(struct archive_write *a, char h[512],
- struct archive_entry *entry, int tartype, int strict,
- struct archive_string_conv *sconv)
-{
- unsigned int checksum;
- int i, r, ret;
- size_t copy_length;
- const char *p, *pp;
- int mytartype;
-
- ret = 0;
- mytartype = -1;
- /*
- * The "template header" already includes the "ustar"
- * signature, various end-of-field markers and other required
- * elements.
- */
- memcpy(h, &template_header, 512);
-
- /*
- * Because the block is already null-filled, and strings
- * are allowed to exactly fill their destination (without null),
- * I use memcpy(dest, src, strlen()) here a lot to copy strings.
- */
- r = archive_entry_pathname_l(entry, &pp, &copy_length, sconv);
- if (r != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate pathname '%s' to %s",
- pp, archive_string_conversion_charset_name(sconv));
- ret = ARCHIVE_WARN;
- }
- if (copy_length <= USTAR_name_size)
- memcpy(h + USTAR_name_offset, pp, copy_length);
- else {
- /* Store in two pieces, splitting at a '/'. */
- p = strchr(pp + copy_length - USTAR_name_size - 1, '/');
- /*
- * Look for the next '/' if we chose the first character
- * as the separator. (ustar format doesn't permit
- * an empty prefix.)
- */
- if (p == pp)
- p = strchr(p + 1, '/');
- /* Fail if the name won't fit. */
- if (!p) {
- /* No separator. */
- archive_set_error(&a->archive, ENAMETOOLONG,
- "Pathname too long");
- ret = ARCHIVE_FAILED;
- } else if (p[1] == '\0') {
- /*
- * The only feasible separator is a final '/';
- * this would result in a non-empty prefix and
- * an empty name, which POSIX doesn't
- * explicitly forbid, but it just feels wrong.
- */
- archive_set_error(&a->archive, ENAMETOOLONG,
- "Pathname too long");
- ret = ARCHIVE_FAILED;
- } else if (p > pp + USTAR_prefix_size) {
- /* Prefix is too long. */
- archive_set_error(&a->archive, ENAMETOOLONG,
- "Pathname too long");
- ret = ARCHIVE_FAILED;
- } else {
- /* Copy prefix and remainder to appropriate places */
- memcpy(h + USTAR_prefix_offset, pp, p - pp);
- memcpy(h + USTAR_name_offset, p + 1,
- pp + copy_length - p - 1);
- }
- }
-
- r = archive_entry_hardlink_l(entry, &p, &copy_length, sconv);
- if (r != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Linkname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate linkname '%s' to %s",
- p, archive_string_conversion_charset_name(sconv));
- ret = ARCHIVE_WARN;
- }
- if (copy_length > 0)
- mytartype = '1';
- else {
- r = archive_entry_symlink_l(entry, &p, &copy_length, sconv);
- if (r != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Linkname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate linkname '%s' to %s",
- p, archive_string_conversion_charset_name(sconv));
- ret = ARCHIVE_WARN;
- }
- }
- if (copy_length > 0) {
- if (copy_length > USTAR_linkname_size) {
- archive_set_error(&a->archive, ENAMETOOLONG,
- "Link contents too long");
- ret = ARCHIVE_FAILED;
- copy_length = USTAR_linkname_size;
- }
- memcpy(h + USTAR_linkname_offset, p, copy_length);
- }
-
- r = archive_entry_uname_l(entry, &p, &copy_length, sconv);
- if (r != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Uname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate uname '%s' to %s",
- p, archive_string_conversion_charset_name(sconv));
- ret = ARCHIVE_WARN;
- }
- if (copy_length > 0) {
- if (copy_length > USTAR_uname_size) {
- if (tartype != 'x') {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC, "Username too long");
- ret = ARCHIVE_FAILED;
- }
- copy_length = USTAR_uname_size;
- }
- memcpy(h + USTAR_uname_offset, p, copy_length);
- }
-
- r = archive_entry_gname_l(entry, &p, &copy_length, sconv);
- if (r != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Gname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate gname '%s' to %s",
- p, archive_string_conversion_charset_name(sconv));
- ret = ARCHIVE_WARN;
- }
- if (copy_length > 0) {
- if (strlen(p) > USTAR_gname_size) {
- if (tartype != 'x') {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC, "Group name too long");
- ret = ARCHIVE_FAILED;
- }
- copy_length = USTAR_gname_size;
- }
- memcpy(h + USTAR_gname_offset, p, copy_length);
- }
-
- if (format_number(archive_entry_mode(entry) & 07777,
- h + USTAR_mode_offset, USTAR_mode_size, USTAR_mode_max_size, strict)) {
- archive_set_error(&a->archive, ERANGE,
- "Numeric mode too large");
- ret = ARCHIVE_FAILED;
- }
-
- if (format_number(archive_entry_uid(entry),
- h + USTAR_uid_offset, USTAR_uid_size, USTAR_uid_max_size, strict)) {
- archive_set_error(&a->archive, ERANGE,
- "Numeric user ID too large");
- ret = ARCHIVE_FAILED;
- }
-
- if (format_number(archive_entry_gid(entry),
- h + USTAR_gid_offset, USTAR_gid_size, USTAR_gid_max_size, strict)) {
- archive_set_error(&a->archive, ERANGE,
- "Numeric group ID too large");
- ret = ARCHIVE_FAILED;
- }
-
- if (format_number(archive_entry_size(entry),
- h + USTAR_size_offset, USTAR_size_size, USTAR_size_max_size, strict)) {
- archive_set_error(&a->archive, ERANGE,
- "File size out of range");
- ret = ARCHIVE_FAILED;
- }
-
- if (format_number(archive_entry_mtime(entry),
- h + USTAR_mtime_offset, USTAR_mtime_size, USTAR_mtime_max_size, strict)) {
- archive_set_error(&a->archive, ERANGE,
- "File modification time too large");
- ret = ARCHIVE_FAILED;
- }
-
- if (archive_entry_filetype(entry) == AE_IFBLK
- || archive_entry_filetype(entry) == AE_IFCHR) {
- if (format_number(archive_entry_rdevmajor(entry),
- h + USTAR_rdevmajor_offset, USTAR_rdevmajor_size,
- USTAR_rdevmajor_max_size, strict)) {
- archive_set_error(&a->archive, ERANGE,
- "Major device number too large");
- ret = ARCHIVE_FAILED;
- }
-
- if (format_number(archive_entry_rdevminor(entry),
- h + USTAR_rdevminor_offset, USTAR_rdevminor_size,
- USTAR_rdevminor_max_size, strict)) {
- archive_set_error(&a->archive, ERANGE,
- "Minor device number too large");
- ret = ARCHIVE_FAILED;
- }
- }
-
- if (tartype >= 0) {
- h[USTAR_typeflag_offset] = tartype;
- } else if (mytartype >= 0) {
- h[USTAR_typeflag_offset] = mytartype;
- } else {
- switch (archive_entry_filetype(entry)) {
- case AE_IFREG: h[USTAR_typeflag_offset] = '0' ; break;
- case AE_IFLNK: h[USTAR_typeflag_offset] = '2' ; break;
- case AE_IFCHR: h[USTAR_typeflag_offset] = '3' ; break;
- case AE_IFBLK: h[USTAR_typeflag_offset] = '4' ; break;
- case AE_IFDIR: h[USTAR_typeflag_offset] = '5' ; break;
- case AE_IFIFO: h[USTAR_typeflag_offset] = '6' ; break;
- default: /* AE_IFSOCK and unknown */
- __archive_write_entry_filetype_unsupported(
- &a->archive, entry, "ustar");
- ret = ARCHIVE_FAILED;
- }
- }
-
- checksum = 0;
- for (i = 0; i < 512; i++)
- checksum += 255 & (unsigned int)h[i];
- h[USTAR_checksum_offset + 6] = '\0'; /* Can't be pre-set in the template. */
- /* h[USTAR_checksum_offset + 7] = ' '; */ /* This is pre-set in the template. */
- format_octal(checksum, h + USTAR_checksum_offset, 6);
- return (ret);
-}
-
-/*
- * Format a number into a field, with some intelligence.
- */
-static int
-format_number(int64_t v, char *p, int s, int maxsize, int strict)
-{
- int64_t limit;
-
- limit = ((int64_t)1 << (s*3));
-
- /* "Strict" only permits octal values with proper termination. */
- if (strict)
- return (format_octal(v, p, s));
-
- /*
- * In non-strict mode, we allow the number to overwrite one or
- * more bytes of the field termination. Even old tar
- * implementations should be able to handle this with no
- * problem.
- */
- if (v >= 0) {
- while (s <= maxsize) {
- if (v < limit)
- return (format_octal(v, p, s));
- s++;
- limit <<= 3;
- }
- }
-
- /* Base-256 can handle any number, positive or negative. */
- return (format_256(v, p, maxsize));
-}
-
-/*
- * Format a number into the specified field using base-256.
- */
-static int
-format_256(int64_t v, char *p, int s)
-{
- p += s;
- while (s-- > 0) {
- *--p = (char)(v & 0xff);
- v >>= 8;
- }
- *p |= 0x80; /* Set the base-256 marker bit. */
- return (0);
-}
-
-/*
- * Format a number into the specified field.
- */
-static int
-format_octal(int64_t v, char *p, int s)
-{
- int len;
-
- len = s;
-
- /* Octal values can't be negative, so use 0. */
- if (v < 0) {
- while (len-- > 0)
- *p++ = '0';
- return (-1);
- }
-
- p += s; /* Start at the end and work backwards. */
- while (s-- > 0) {
- *--p = (char)('0' + (v & 7));
- v >>= 3;
- }
-
- if (v == 0)
- return (0);
-
- /* If it overflowed, fill field with max value. */
- while (len-- > 0)
- *p++ = '7';
-
- return (-1);
-}
-
-static int
-archive_write_ustar_close(struct archive_write *a)
-{
- return (__archive_write_nulls(a, 512*2));
-}
-
-static int
-archive_write_ustar_free(struct archive_write *a)
-{
- struct ustar *ustar;
-
- ustar = (struct ustar *)a->format_data;
- free(ustar);
- a->format_data = NULL;
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_ustar_finish_entry(struct archive_write *a)
-{
- struct ustar *ustar;
- int ret;
-
- ustar = (struct ustar *)a->format_data;
- ret = __archive_write_nulls(a,
- (size_t)(ustar->entry_bytes_remaining + ustar->entry_padding));
- ustar->entry_bytes_remaining = ustar->entry_padding = 0;
- return (ret);
-}
-
-static ssize_t
-archive_write_ustar_data(struct archive_write *a, const void *buff, size_t s)
-{
- struct ustar *ustar;
- int ret;
-
- ustar = (struct ustar *)a->format_data;
- if (s > ustar->entry_bytes_remaining)
- s = (size_t)ustar->entry_bytes_remaining;
- ret = __archive_write_output(a, buff, s);
- ustar->entry_bytes_remaining -= s;
- if (ret != ARCHIVE_OK)
- return (ret);
- return (s);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_format_v7tar.c b/contrib/libs/libarchive/libarchive/archive_write_set_format_v7tar.c
deleted file mode 100644
index 5994071441..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_format_v7tar.c
+++ /dev/null
@@ -1,638 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * Copyright (c) 2011-2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_private.h"
-#include "archive_write_private.h"
-#include "archive_write_set_format_private.h"
-
-struct v7tar {
- uint64_t entry_bytes_remaining;
- uint64_t entry_padding;
-
- struct archive_string_conv *opt_sconv;
- struct archive_string_conv *sconv_default;
- int init_default_conversion;
-};
-
-/*
- * Define structure of POSIX 'v7tar' tar header.
- */
-#define V7TAR_name_offset 0
-#define V7TAR_name_size 100
-#define V7TAR_mode_offset 100
-#define V7TAR_mode_size 6
-#define V7TAR_mode_max_size 8
-#define V7TAR_uid_offset 108
-#define V7TAR_uid_size 6
-#define V7TAR_uid_max_size 8
-#define V7TAR_gid_offset 116
-#define V7TAR_gid_size 6
-#define V7TAR_gid_max_size 8
-#define V7TAR_size_offset 124
-#define V7TAR_size_size 11
-#define V7TAR_size_max_size 12
-#define V7TAR_mtime_offset 136
-#define V7TAR_mtime_size 11
-#define V7TAR_mtime_max_size 12
-#define V7TAR_checksum_offset 148
-#define V7TAR_checksum_size 8
-#define V7TAR_typeflag_offset 156
-#define V7TAR_typeflag_size 1
-#define V7TAR_linkname_offset 157
-#define V7TAR_linkname_size 100
-#define V7TAR_padding_offset 257
-#define V7TAR_padding_size 255
-
-/*
- * A filled-in copy of the header for initialization.
- */
-static const char template_header[] = {
- /* name: 100 bytes */
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,
- /* Mode, space-null termination: 8 bytes */
- '0','0','0','0','0','0', ' ','\0',
- /* uid, space-null termination: 8 bytes */
- '0','0','0','0','0','0', ' ','\0',
- /* gid, space-null termination: 8 bytes */
- '0','0','0','0','0','0', ' ','\0',
- /* size, space termination: 12 bytes */
- '0','0','0','0','0','0','0','0','0','0','0', ' ',
- /* mtime, space termination: 12 bytes */
- '0','0','0','0','0','0','0','0','0','0','0', ' ',
- /* Initial checksum value: 8 spaces */
- ' ',' ',' ',' ',' ',' ',' ',' ',
- /* Typeflag: 1 byte */
- 0,
- /* Linkname: 100 bytes */
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,
- /* Padding: 255 bytes */
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0
-};
-
-static ssize_t archive_write_v7tar_data(struct archive_write *a, const void *buff,
- size_t s);
-static int archive_write_v7tar_free(struct archive_write *);
-static int archive_write_v7tar_close(struct archive_write *);
-static int archive_write_v7tar_finish_entry(struct archive_write *);
-static int archive_write_v7tar_header(struct archive_write *,
- struct archive_entry *entry);
-static int archive_write_v7tar_options(struct archive_write *,
- const char *, const char *);
-static int format_256(int64_t, char *, int);
-static int format_number(int64_t, char *, int size, int max, int strict);
-static int format_octal(int64_t, char *, int);
-static int format_header_v7tar(struct archive_write *, char h[512],
- struct archive_entry *, int, struct archive_string_conv *);
-
-/*
- * Set output format to 'v7tar' format.
- */
-int
-archive_write_set_format_v7tar(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct v7tar *v7tar;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_format_v7tar");
-
- /* If someone else was already registered, unregister them. */
- if (a->format_free != NULL)
- (a->format_free)(a);
-
- /* Basic internal sanity test. */
- if (sizeof(template_header) != 512) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Internal: template_header wrong size: %zu should be 512",
- sizeof(template_header));
- return (ARCHIVE_FATAL);
- }
-
- v7tar = (struct v7tar *)calloc(1, sizeof(*v7tar));
- if (v7tar == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate v7tar data");
- return (ARCHIVE_FATAL);
- }
- a->format_data = v7tar;
- a->format_name = "tar (non-POSIX)";
- a->format_options = archive_write_v7tar_options;
- a->format_write_header = archive_write_v7tar_header;
- a->format_write_data = archive_write_v7tar_data;
- a->format_close = archive_write_v7tar_close;
- a->format_free = archive_write_v7tar_free;
- a->format_finish_entry = archive_write_v7tar_finish_entry;
- a->archive.archive_format = ARCHIVE_FORMAT_TAR;
- a->archive.archive_format_name = "tar (non-POSIX)";
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_v7tar_options(struct archive_write *a, const char *key,
- const char *val)
-{
- struct v7tar *v7tar = (struct v7tar *)a->format_data;
- int ret = ARCHIVE_FAILED;
-
- if (strcmp(key, "hdrcharset") == 0) {
- if (val == NULL || val[0] == 0)
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "%s: hdrcharset option needs a character-set name",
- a->format_name);
- else {
- v7tar->opt_sconv = archive_string_conversion_to_charset(
- &a->archive, val, 0);
- if (v7tar->opt_sconv != NULL)
- ret = ARCHIVE_OK;
- else
- ret = ARCHIVE_FATAL;
- }
- return (ret);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-static int
-archive_write_v7tar_header(struct archive_write *a, struct archive_entry *entry)
-{
- char buff[512];
- int ret, ret2;
- struct v7tar *v7tar;
- struct archive_entry *entry_main;
- struct archive_string_conv *sconv;
-
- v7tar = (struct v7tar *)a->format_data;
-
- /* Setup default string conversion. */
- if (v7tar->opt_sconv == NULL) {
- if (!v7tar->init_default_conversion) {
- v7tar->sconv_default =
- archive_string_default_conversion_for_write(
- &(a->archive));
- v7tar->init_default_conversion = 1;
- }
- sconv = v7tar->sconv_default;
- } else
- sconv = v7tar->opt_sconv;
-
- /* Sanity check. */
- if (archive_entry_pathname(entry) == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Can't record entry in tar file without pathname");
- return (ARCHIVE_FAILED);
- }
-
- /* Only regular files (not hardlinks) have data. */
- if (archive_entry_hardlink(entry) != NULL ||
- archive_entry_symlink(entry) != NULL ||
- !(archive_entry_filetype(entry) == AE_IFREG))
- archive_entry_set_size(entry, 0);
-
- if (AE_IFDIR == archive_entry_filetype(entry)) {
- const char *p;
- size_t path_length;
- /*
- * Ensure a trailing '/'. Modify the entry so
- * the client sees the change.
- */
-#if defined(_WIN32) && !defined(__CYGWIN__)
- const wchar_t *wp;
-
- wp = archive_entry_pathname_w(entry);
- if (wp != NULL && wp[wcslen(wp) -1] != L'/') {
- struct archive_wstring ws;
-
- archive_string_init(&ws);
- path_length = wcslen(wp);
- if (archive_wstring_ensure(&ws,
- path_length + 2) == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate v7tar data");
- archive_wstring_free(&ws);
- return(ARCHIVE_FATAL);
- }
- /* Should we keep '\' ? */
- if (wp[path_length -1] == L'\\')
- path_length--;
- archive_wstrncpy(&ws, wp, path_length);
- archive_wstrappend_wchar(&ws, L'/');
- archive_entry_copy_pathname_w(entry, ws.s);
- archive_wstring_free(&ws);
- p = NULL;
- } else
-#endif
- p = archive_entry_pathname(entry);
- /*
- * On Windows, this is a backup operation just in
- * case getting WCS failed. On POSIX, this is a
- * normal operation.
- */
- if (p != NULL && p[0] != '\0' && p[strlen(p) - 1] != '/') {
- struct archive_string as;
-
- archive_string_init(&as);
- path_length = strlen(p);
- if (archive_string_ensure(&as,
- path_length + 2) == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate v7tar data");
- archive_string_free(&as);
- return(ARCHIVE_FATAL);
- }
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* NOTE: This might break the pathname
- * if the current code page is CP932 and
- * the pathname includes a character '\'
- * as a part of its multibyte pathname. */
- if (p[strlen(p) -1] == '\\')
- path_length--;
- else
-#endif
- archive_strncpy(&as, p, path_length);
- archive_strappend_char(&as, '/');
- archive_entry_copy_pathname(entry, as.s);
- archive_string_free(&as);
- }
- }
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Make sure the path separators in pathname, hardlink and symlink
- * are all slash '/', not the Windows path separator '\'. */
- entry_main = __la_win_entry_in_posix_pathseparator(entry);
- if (entry_main == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate v7tar data");
- return(ARCHIVE_FATAL);
- }
- if (entry != entry_main)
- entry = entry_main;
- else
- entry_main = NULL;
-#else
- entry_main = NULL;
-#endif
- ret = format_header_v7tar(a, buff, entry, 1, sconv);
- if (ret < ARCHIVE_WARN) {
- archive_entry_free(entry_main);
- return (ret);
- }
- ret2 = __archive_write_output(a, buff, 512);
- if (ret2 < ARCHIVE_WARN) {
- archive_entry_free(entry_main);
- return (ret2);
- }
- if (ret2 < ret)
- ret = ret2;
-
- v7tar->entry_bytes_remaining = archive_entry_size(entry);
- v7tar->entry_padding = 0x1ff & (-(int64_t)v7tar->entry_bytes_remaining);
- archive_entry_free(entry_main);
- return (ret);
-}
-
-/*
- * Format a basic 512-byte "v7tar" header.
- *
- * Returns -1 if format failed (due to field overflow).
- * Note that this always formats as much of the header as possible.
- * If "strict" is set to zero, it will extend numeric fields as
- * necessary (overwriting terminators or using base-256 extensions).
- *
- */
-static int
-format_header_v7tar(struct archive_write *a, char h[512],
- struct archive_entry *entry, int strict,
- struct archive_string_conv *sconv)
-{
- unsigned int checksum;
- int i, r, ret;
- size_t copy_length;
- const char *p, *pp;
- int mytartype;
-
- ret = 0;
- mytartype = -1;
- /*
- * The "template header" already includes the "v7tar"
- * signature, various end-of-field markers and other required
- * elements.
- */
- memcpy(h, &template_header, 512);
-
- /*
- * Because the block is already null-filled, and strings
- * are allowed to exactly fill their destination (without null),
- * I use memcpy(dest, src, strlen()) here a lot to copy strings.
- */
- r = archive_entry_pathname_l(entry, &pp, &copy_length, sconv);
- if (r != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate pathname '%s' to %s",
- pp, archive_string_conversion_charset_name(sconv));
- ret = ARCHIVE_WARN;
- }
- if (strict && copy_length < V7TAR_name_size)
- memcpy(h + V7TAR_name_offset, pp, copy_length);
- else if (!strict && copy_length <= V7TAR_name_size)
- memcpy(h + V7TAR_name_offset, pp, copy_length);
- else {
- /* Prefix is too long. */
- archive_set_error(&a->archive, ENAMETOOLONG,
- "Pathname too long");
- ret = ARCHIVE_FAILED;
- }
-
- r = archive_entry_hardlink_l(entry, &p, &copy_length, sconv);
- if (r != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Linkname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate linkname '%s' to %s",
- p, archive_string_conversion_charset_name(sconv));
- ret = ARCHIVE_WARN;
- }
- if (copy_length > 0)
- mytartype = '1';
- else {
- r = archive_entry_symlink_l(entry, &p, &copy_length, sconv);
- if (r != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Linkname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate linkname '%s' to %s",
- p, archive_string_conversion_charset_name(sconv));
- ret = ARCHIVE_WARN;
- }
- }
- if (copy_length > 0) {
- if (copy_length >= V7TAR_linkname_size) {
- archive_set_error(&a->archive, ENAMETOOLONG,
- "Link contents too long");
- ret = ARCHIVE_FAILED;
- copy_length = V7TAR_linkname_size;
- }
- memcpy(h + V7TAR_linkname_offset, p, copy_length);
- }
-
- if (format_number(archive_entry_mode(entry) & 07777,
- h + V7TAR_mode_offset, V7TAR_mode_size,
- V7TAR_mode_max_size, strict)) {
- archive_set_error(&a->archive, ERANGE,
- "Numeric mode too large");
- ret = ARCHIVE_FAILED;
- }
-
- if (format_number(archive_entry_uid(entry),
- h + V7TAR_uid_offset, V7TAR_uid_size, V7TAR_uid_max_size, strict)) {
- archive_set_error(&a->archive, ERANGE,
- "Numeric user ID too large");
- ret = ARCHIVE_FAILED;
- }
-
- if (format_number(archive_entry_gid(entry),
- h + V7TAR_gid_offset, V7TAR_gid_size, V7TAR_gid_max_size, strict)) {
- archive_set_error(&a->archive, ERANGE,
- "Numeric group ID too large");
- ret = ARCHIVE_FAILED;
- }
-
- if (format_number(archive_entry_size(entry),
- h + V7TAR_size_offset, V7TAR_size_size,
- V7TAR_size_max_size, strict)) {
- archive_set_error(&a->archive, ERANGE,
- "File size out of range");
- ret = ARCHIVE_FAILED;
- }
-
- if (format_number(archive_entry_mtime(entry),
- h + V7TAR_mtime_offset, V7TAR_mtime_size,
- V7TAR_mtime_max_size, strict)) {
- archive_set_error(&a->archive, ERANGE,
- "File modification time too large");
- ret = ARCHIVE_FAILED;
- }
-
- if (mytartype >= 0) {
- h[V7TAR_typeflag_offset] = mytartype;
- } else {
- switch (archive_entry_filetype(entry)) {
- case AE_IFREG: case AE_IFDIR:
- break;
- case AE_IFLNK:
- h[V7TAR_typeflag_offset] = '2';
- break;
- default:
- /* AE_IFBLK, AE_IFCHR, AE_IFIFO, AE_IFSOCK
- * and unknown */
- __archive_write_entry_filetype_unsupported(
- &a->archive, entry, "v7tar");
- ret = ARCHIVE_FAILED;
- }
- }
-
- checksum = 0;
- for (i = 0; i < 512; i++)
- checksum += 255 & (unsigned int)h[i];
- format_octal(checksum, h + V7TAR_checksum_offset, 6);
- /* Can't be pre-set in the template. */
- h[V7TAR_checksum_offset + 6] = '\0';
- return (ret);
-}
-
-/*
- * Format a number into a field, with some intelligence.
- */
-static int
-format_number(int64_t v, char *p, int s, int maxsize, int strict)
-{
- int64_t limit;
-
- limit = ((int64_t)1 << (s*3));
-
- /* "Strict" only permits octal values with proper termination. */
- if (strict)
- return (format_octal(v, p, s));
-
- /*
- * In non-strict mode, we allow the number to overwrite one or
- * more bytes of the field termination. Even old tar
- * implementations should be able to handle this with no
- * problem.
- */
- if (v >= 0) {
- while (s <= maxsize) {
- if (v < limit)
- return (format_octal(v, p, s));
- s++;
- limit <<= 3;
- }
- }
-
- /* Base-256 can handle any number, positive or negative. */
- return (format_256(v, p, maxsize));
-}
-
-/*
- * Format a number into the specified field using base-256.
- */
-static int
-format_256(int64_t v, char *p, int s)
-{
- p += s;
- while (s-- > 0) {
- *--p = (char)(v & 0xff);
- v >>= 8;
- }
- *p |= 0x80; /* Set the base-256 marker bit. */
- return (0);
-}
-
-/*
- * Format a number into the specified field.
- */
-static int
-format_octal(int64_t v, char *p, int s)
-{
- int len;
-
- len = s;
-
- /* Octal values can't be negative, so use 0. */
- if (v < 0) {
- while (len-- > 0)
- *p++ = '0';
- return (-1);
- }
-
- p += s; /* Start at the end and work backwards. */
- while (s-- > 0) {
- *--p = (char)('0' + (v & 7));
- v >>= 3;
- }
-
- if (v == 0)
- return (0);
-
- /* If it overflowed, fill field with max value. */
- while (len-- > 0)
- *p++ = '7';
-
- return (-1);
-}
-
-static int
-archive_write_v7tar_close(struct archive_write *a)
-{
- return (__archive_write_nulls(a, 512*2));
-}
-
-static int
-archive_write_v7tar_free(struct archive_write *a)
-{
- struct v7tar *v7tar;
-
- v7tar = (struct v7tar *)a->format_data;
- free(v7tar);
- a->format_data = NULL;
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_v7tar_finish_entry(struct archive_write *a)
-{
- struct v7tar *v7tar;
- int ret;
-
- v7tar = (struct v7tar *)a->format_data;
- ret = __archive_write_nulls(a,
- (size_t)(v7tar->entry_bytes_remaining + v7tar->entry_padding));
- v7tar->entry_bytes_remaining = v7tar->entry_padding = 0;
- return (ret);
-}
-
-static ssize_t
-archive_write_v7tar_data(struct archive_write *a, const void *buff, size_t s)
-{
- struct v7tar *v7tar;
- int ret;
-
- v7tar = (struct v7tar *)a->format_data;
- if (s > v7tar->entry_bytes_remaining)
- s = (size_t)v7tar->entry_bytes_remaining;
- ret = __archive_write_output(a, buff, s);
- v7tar->entry_bytes_remaining -= s;
- if (ret != ARCHIVE_OK)
- return (ret);
- return (s);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_format_warc.c b/contrib/libs/libarchive/libarchive/archive_write_set_format_warc.c
deleted file mode 100644
index 0ef003e2fc..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_format_warc.c
+++ /dev/null
@@ -1,444 +0,0 @@
-/*-
- * Copyright (c) 2014 Sebastian Freundt
- * Author: Sebastian Freundt <devel@fresse.org>
- *
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_TIME_H
-#include <time.h>
-#endif
-
-#include "archive.h"
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_private.h"
-#include "archive_random_private.h"
-#include "archive_write_private.h"
-#include "archive_write_set_format_private.h"
-
-struct warc_s {
- unsigned int omit_warcinfo:1;
-
- time_t now;
- mode_t typ;
- unsigned int rng;
- /* populated size */
- uint64_t populz;
-};
-
-static const char warcinfo[] =
- "software: libarchive/" ARCHIVE_VERSION_ONLY_STRING "\r\n"
- "format: WARC file version 1.0\r\n";
-
-typedef enum {
- WT_NONE,
- /* warcinfo */
- WT_INFO,
- /* metadata */
- WT_META,
- /* resource */
- WT_RSRC,
- /* request, unsupported */
- WT_REQ,
- /* response, unsupported */
- WT_RSP,
- /* revisit, unsupported */
- WT_RVIS,
- /* conversion, unsupported */
- WT_CONV,
- /* continuation, unsupported at the moment */
- WT_CONT,
- /* invalid type */
- LAST_WT
-} warc_type_t;
-
-typedef struct {
- warc_type_t type;
- const char *tgturi;
- const char *recid;
- time_t rtime;
- time_t mtime;
- const char *cnttyp;
- uint64_t cntlen;
-} warc_essential_hdr_t;
-
-typedef struct {
- unsigned int u[4U];
-} warc_uuid_t;
-
-static int _warc_options(struct archive_write*, const char *key, const char *v);
-static int _warc_header(struct archive_write *a, struct archive_entry *entry);
-static ssize_t _warc_data(struct archive_write *a, const void *buf, size_t sz);
-static int _warc_finish_entry(struct archive_write *a);
-static int _warc_close(struct archive_write *a);
-static int _warc_free(struct archive_write *a);
-
-/* private routines */
-static ssize_t _popul_ehdr(struct archive_string *t, size_t z, warc_essential_hdr_t);
-static int _gen_uuid(warc_uuid_t *tgt);
-
-
-/*
- * Set output format to ISO 28500 (aka WARC) format.
- */
-int
-archive_write_set_format_warc(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct warc_s *w;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_format_warc");
-
- /* If another format was already registered, unregister it. */
- if (a->format_free != NULL) {
- (a->format_free)(a);
- }
-
- w = malloc(sizeof(*w));
- if (w == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate warc data");
- return (ARCHIVE_FATAL);
- }
- /* by default we're emitting a file wide header */
- w->omit_warcinfo = 0U;
- /* obtain current time for date fields */
- w->now = time(NULL);
- /* reset file type info */
- w->typ = 0;
- /* also initialise our rng */
- w->rng = (unsigned int)w->now;
-
- a->format_data = w;
- a->format_name = "WARC/1.0";
- a->format_options = _warc_options;
- a->format_write_header = _warc_header;
- a->format_write_data = _warc_data;
- a->format_close = _warc_close;
- a->format_free = _warc_free;
- a->format_finish_entry = _warc_finish_entry;
- a->archive.archive_format = ARCHIVE_FORMAT_WARC;
- a->archive.archive_format_name = "WARC/1.0";
- return (ARCHIVE_OK);
-}
-
-
-/* archive methods */
-static int
-_warc_options(struct archive_write *a, const char *key, const char *val)
-{
- struct warc_s *w = a->format_data;
-
- if (strcmp(key, "omit-warcinfo") == 0) {
- if (val == NULL || strcmp(val, "true") == 0) {
- /* great */
- w->omit_warcinfo = 1U;
- return (ARCHIVE_OK);
- }
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-static int
-_warc_header(struct archive_write *a, struct archive_entry *entry)
-{
- struct warc_s *w = a->format_data;
- struct archive_string hdr;
-#define MAX_HDR_SIZE 512
-
- /* check whether warcinfo record needs outputting */
- if (!w->omit_warcinfo) {
- ssize_t r;
- warc_essential_hdr_t wi = {
- WT_INFO,
- /*uri*/NULL,
- /*urn*/NULL,
- /*rtm*/0,
- /*mtm*/0,
- /*cty*/"application/warc-fields",
- /*len*/sizeof(warcinfo) - 1U,
- };
- wi.rtime = w->now;
- wi.mtime = w->now;
-
- archive_string_init(&hdr);
- r = _popul_ehdr(&hdr, MAX_HDR_SIZE, wi);
- if (r >= 0) {
- /* jackpot! */
- /* now also use HDR buffer for the actual warcinfo */
- archive_strncat(&hdr, warcinfo, sizeof(warcinfo) -1);
-
- /* append end-of-record indicator */
- archive_strncat(&hdr, "\r\n\r\n", 4);
-
- /* write to output stream */
- __archive_write_output(a, hdr.s, archive_strlen(&hdr));
- }
- /* indicate we're done with file header writing */
- w->omit_warcinfo = 1U;
- archive_string_free(&hdr);
- }
-
- if (archive_entry_pathname(entry) == NULL) {
- archive_set_error(&a->archive, EINVAL,
- "Invalid filename");
- return (ARCHIVE_WARN);
- }
-
- w->typ = archive_entry_filetype(entry);
- w->populz = 0U;
- if (w->typ == AE_IFREG) {
- warc_essential_hdr_t rh = {
- WT_RSRC,
- /*uri*/NULL,
- /*urn*/NULL,
- /*rtm*/0,
- /*mtm*/0,
- /*cty*/NULL,
- /*len*/0,
- };
- ssize_t r;
- rh.tgturi = archive_entry_pathname(entry);
- rh.rtime = w->now;
- rh.mtime = archive_entry_mtime(entry);
- rh.cntlen = (size_t)archive_entry_size(entry);
-
- archive_string_init(&hdr);
- r = _popul_ehdr(&hdr, MAX_HDR_SIZE, rh);
- if (r < 0) {
- /* don't bother */
- archive_set_error(
- &a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "cannot archive file");
- return (ARCHIVE_WARN);
- }
- /* otherwise append to output stream */
- __archive_write_output(a, hdr.s, r);
- /* and let subsequent calls to _data() know about the size */
- w->populz = rh.cntlen;
- archive_string_free(&hdr);
- return (ARCHIVE_OK);
- }
- /* just resort to erroring as per Tim's advice */
- __archive_write_entry_filetype_unsupported(
- &a->archive, entry, "WARC");
- return (ARCHIVE_FAILED);
-}
-
-static ssize_t
-_warc_data(struct archive_write *a, const void *buf, size_t len)
-{
- struct warc_s *w = a->format_data;
-
- if (w->typ == AE_IFREG) {
- int rc;
-
- /* never write more bytes than announced */
- if (len > w->populz) {
- len = (size_t)w->populz;
- }
-
- /* now then, out we put the whole shebang */
- rc = __archive_write_output(a, buf, len);
- if (rc != ARCHIVE_OK) {
- return rc;
- }
- }
- return len;
-}
-
-static int
-_warc_finish_entry(struct archive_write *a)
-{
- static const char _eor[] = "\r\n\r\n";
- struct warc_s *w = a->format_data;
-
- if (w->typ == AE_IFREG) {
- int rc = __archive_write_output(a, _eor, sizeof(_eor) - 1U);
-
- if (rc != ARCHIVE_OK) {
- return rc;
- }
- }
- /* reset type info */
- w->typ = 0;
- return (ARCHIVE_OK);
-}
-
-static int
-_warc_close(struct archive_write *a)
-{
- (void)a; /* UNUSED */
- return (ARCHIVE_OK);
-}
-
-static int
-_warc_free(struct archive_write *a)
-{
- struct warc_s *w = a->format_data;
-
- free(w);
- a->format_data = NULL;
- return (ARCHIVE_OK);
-}
-
-
-/* private routines */
-static void
-xstrftime(struct archive_string *as, const char *fmt, time_t t)
-{
-/** like strftime(3) but for time_t objects */
- struct tm *rt;
-#if defined(HAVE_GMTIME_R) || defined(HAVE_GMTIME_S)
- struct tm timeHere;
-#endif
- char strtime[100];
- size_t len;
-
-#if defined(HAVE_GMTIME_S)
- rt = gmtime_s(&timeHere, &t) ? NULL : &timeHere;
-#elif defined(HAVE_GMTIME_R)
- rt = gmtime_r(&t, &timeHere);
-#else
- rt = gmtime(&t);
-#endif
- if (!rt)
- return;
- /* leave the hard yacker to our role model strftime() */
- len = strftime(strtime, sizeof(strtime)-1, fmt, rt);
- archive_strncat(as, strtime, len);
-}
-
-static ssize_t
-_popul_ehdr(struct archive_string *tgt, size_t tsz, warc_essential_hdr_t hdr)
-{
- static const char _ver[] = "WARC/1.0\r\n";
- static const char * const _typ[LAST_WT] = {
- NULL, "warcinfo", "metadata", "resource", NULL
- };
- char std_uuid[48U];
-
- if (hdr.type == WT_NONE || hdr.type > WT_RSRC) {
- /* brilliant, how exactly did we get here? */
- return -1;
- }
-
- archive_strcpy(tgt, _ver);
-
- archive_string_sprintf(tgt, "WARC-Type: %s\r\n", _typ[hdr.type]);
-
- if (hdr.tgturi != NULL) {
- /* check if there's a xyz:// */
- static const char _uri[] = "";
- static const char _fil[] = "file://";
- const char *u;
- char *chk = strchr(hdr.tgturi, ':');
-
- if (chk != NULL && chk[1U] == '/' && chk[2U] == '/') {
- /* yep, it's definitely a URI */
- u = _uri;
- } else {
- /* hm, best to prepend file:// then */
- u = _fil;
- }
- archive_string_sprintf(tgt,
- "WARC-Target-URI: %s%s\r\n", u, hdr.tgturi);
- }
-
- /* record time is usually when the http is sent off,
- * just treat the archive writing as such for a moment */
- xstrftime(tgt, "WARC-Date: %Y-%m-%dT%H:%M:%SZ\r\n", hdr.rtime);
-
- /* while we're at it, record the mtime */
- xstrftime(tgt, "Last-Modified: %Y-%m-%dT%H:%M:%SZ\r\n", hdr.mtime);
-
- if (hdr.recid == NULL) {
- /* generate one, grrrr */
- warc_uuid_t u;
-
- _gen_uuid(&u);
- /* Unfortunately, archive_string_sprintf does not
- * handle the minimum number following '%'.
- * So we have to use snprintf function here instead
- * of archive_string_snprintf function. */
-#if defined(_WIN32) && !defined(__CYGWIN__) && !( defined(_MSC_VER) && _MSC_VER >= 1900)
-#define snprintf _snprintf
-#endif
- snprintf(
- std_uuid, sizeof(std_uuid),
- "<urn:uuid:%08x-%04x-%04x-%04x-%04x%08x>",
- u.u[0U],
- u.u[1U] >> 16U, u.u[1U] & 0xffffU,
- u.u[2U] >> 16U, u.u[2U] & 0xffffU,
- u.u[3U]);
- hdr.recid = std_uuid;
- }
-
- /* record-id is mandatory, fingers crossed we won't fail */
- archive_string_sprintf(tgt, "WARC-Record-ID: %s\r\n", hdr.recid);
-
- if (hdr.cnttyp != NULL) {
- archive_string_sprintf(tgt, "Content-Type: %s\r\n", hdr.cnttyp);
- }
-
- /* next one is mandatory */
- archive_string_sprintf(tgt, "Content-Length: %ju\r\n", (uintmax_t)hdr.cntlen);
- /**/
- archive_strncat(tgt, "\r\n", 2);
-
- return (archive_strlen(tgt) >= tsz)? -1: (ssize_t)archive_strlen(tgt);
-}
-
-static int
-_gen_uuid(warc_uuid_t *tgt)
-{
- archive_random(tgt->u, sizeof(tgt->u));
- /* obey uuid version 4 rules */
- tgt->u[1U] &= 0xffff0fffU;
- tgt->u[1U] |= 0x4000U;
- tgt->u[2U] &= 0x3fffffffU;
- tgt->u[2U] |= 0x80000000U;
- return 0;
-}
-
-/* archive_write_set_format_warc.c ends here */
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_format_xar.c b/contrib/libs/libarchive/libarchive/archive_write_set_format_xar.c
deleted file mode 100644
index c3acf86b57..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_format_xar.c
+++ /dev/null
@@ -1,3255 +0,0 @@
-/*-
- * Copyright (c) 2010-2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-#include <stdlib.h>
-#if HAVE_LIBXML_XMLWRITER_H
-#error #include <libxml/xmlwriter.h>
-#endif
-#ifdef HAVE_BZLIB_H
-#include <bzlib.h>
-#endif
-#if HAVE_LZMA_H
-#error #include <lzma.h>
-#endif
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-
-#include "archive.h"
-#include "archive_digest_private.h"
-#include "archive_endian.h"
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_private.h"
-#include "archive_rb.h"
-#include "archive_string.h"
-#include "archive_write_private.h"
-
-/*
- * Differences to xar utility.
- * - Subdocument is not supported yet.
- * - ACL is not supported yet.
- * - When writing an XML element <link type="<file-type>">, <file-type>
- * which is a file type a symbolic link is referencing is always marked
- * as "broken". Xar utility uses stat(2) to get the file type, but, in
- * libarchive format writer, we should not use it; if it is needed, we
- * should get about it at archive_read_disk.c.
- * - It is possible to appear both <flags> and <ext2> elements.
- * Xar utility generates <flags> on BSD platform and <ext2> on Linux
- * platform.
- *
- */
-
-#if !(defined(HAVE_LIBXML_XMLWRITER_H) && defined(LIBXML_VERSION) &&\
- LIBXML_VERSION >= 20703) ||\
- !defined(HAVE_ZLIB_H) || \
- !defined(ARCHIVE_HAS_MD5) || !defined(ARCHIVE_HAS_SHA1)
-/*
- * xar needs several external libraries.
- * o libxml2
- * o openssl or MD5/SHA1 hash function
- * o zlib
- * o bzlib2 (option)
- * o liblzma (option)
- */
-int
-archive_write_set_format_xar(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
-
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Xar not supported on this platform");
- return (ARCHIVE_WARN);
-}
-
-#else /* Support xar format */
-
-/*#define DEBUG_PRINT_TOC 1 */
-
-#define BAD_CAST_CONST (const xmlChar *)
-
-#define HEADER_MAGIC 0x78617221
-#define HEADER_SIZE 28
-#define HEADER_VERSION 1
-
-enum sumalg {
- CKSUM_NONE = 0,
- CKSUM_SHA1 = 1,
- CKSUM_MD5 = 2
-};
-
-#define MD5_SIZE 16
-#define SHA1_SIZE 20
-#define MAX_SUM_SIZE 20
-#define MD5_NAME "md5"
-#define SHA1_NAME "sha1"
-
-enum enctype {
- NONE,
- GZIP,
- BZIP2,
- LZMA,
- XZ,
-};
-
-struct chksumwork {
- enum sumalg alg;
-#ifdef ARCHIVE_HAS_MD5
- archive_md5_ctx md5ctx;
-#endif
-#ifdef ARCHIVE_HAS_SHA1
- archive_sha1_ctx sha1ctx;
-#endif
-};
-
-enum la_zaction {
- ARCHIVE_Z_FINISH,
- ARCHIVE_Z_RUN
-};
-
-/*
- * Universal zstream.
- */
-struct la_zstream {
- const unsigned char *next_in;
- size_t avail_in;
- uint64_t total_in;
-
- unsigned char *next_out;
- size_t avail_out;
- uint64_t total_out;
-
- int valid;
- void *real_stream;
- int (*code) (struct archive *a,
- struct la_zstream *lastrm,
- enum la_zaction action);
- int (*end)(struct archive *a,
- struct la_zstream *lastrm);
-};
-
-struct chksumval {
- enum sumalg alg;
- size_t len;
- unsigned char val[MAX_SUM_SIZE];
-};
-
-struct heap_data {
- int id;
- struct heap_data *next;
- uint64_t temp_offset;
- uint64_t length; /* archived size. */
- uint64_t size; /* extracted size. */
- enum enctype compression;
- struct chksumval a_sum; /* archived checksum. */
- struct chksumval e_sum; /* extracted checksum. */
-};
-
-struct file {
- struct archive_rb_node rbnode;
-
- int id;
- struct archive_entry *entry;
-
- struct archive_rb_tree rbtree;
- struct file *next;
- struct file *chnext;
- struct file *hlnext;
- /* For hardlinked files.
- * Use only when archive_entry_nlink() > 1 */
- struct file *hardlink_target;
- struct file *parent; /* parent directory entry */
- /*
- * To manage sub directory files.
- * We use 'chnext' (a member of struct file) to chain.
- */
- struct {
- struct file *first;
- struct file **last;
- } children;
-
- /* For making a directory tree. */
- struct archive_string parentdir;
- struct archive_string basename;
- struct archive_string symlink;
-
- int ea_idx;
- struct {
- struct heap_data *first;
- struct heap_data **last;
- } xattr;
- struct heap_data data;
- struct archive_string script;
-
- unsigned int virtual:1;
- unsigned int dir:1;
-};
-
-struct hardlink {
- struct archive_rb_node rbnode;
- int nlink;
- struct {
- struct file *first;
- struct file **last;
- } file_list;
-};
-
-struct xar {
- int temp_fd;
- uint64_t temp_offset;
-
- int file_idx;
- struct file *root;
- struct file *cur_dirent;
- struct archive_string cur_dirstr;
- struct file *cur_file;
- uint64_t bytes_remaining;
- struct archive_string tstr;
- struct archive_string vstr;
-
- enum sumalg opt_toc_sumalg;
- enum sumalg opt_sumalg;
- enum enctype opt_compression;
- int opt_compression_level;
- uint32_t opt_threads;
-
- struct chksumwork a_sumwrk; /* archived checksum. */
- struct chksumwork e_sumwrk; /* extracted checksum. */
- struct la_zstream stream;
- struct archive_string_conv *sconv;
- /*
- * Compressed data buffer.
- */
- unsigned char wbuff[1024 * 64];
- size_t wbuff_remaining;
-
- struct heap_data toc;
- /*
- * The list of all file entries is used to manage struct file
- * objects.
- * We use 'next' (a member of struct file) to chain.
- */
- struct {
- struct file *first;
- struct file **last;
- } file_list;
- /*
- * The list of hard-linked file entries.
- * We use 'hlnext' (a member of struct file) to chain.
- */
- struct archive_rb_tree hardlink_rbtree;
-};
-
-static int xar_options(struct archive_write *,
- const char *, const char *);
-static int xar_write_header(struct archive_write *,
- struct archive_entry *);
-static ssize_t xar_write_data(struct archive_write *,
- const void *, size_t);
-static int xar_finish_entry(struct archive_write *);
-static int xar_close(struct archive_write *);
-static int xar_free(struct archive_write *);
-
-static struct file *file_new(struct archive_write *a, struct archive_entry *);
-static void file_free(struct file *);
-static struct file *file_create_virtual_dir(struct archive_write *a, struct xar *,
- const char *);
-static int file_add_child_tail(struct file *, struct file *);
-static struct file *file_find_child(struct file *, const char *);
-static int file_gen_utility_names(struct archive_write *,
- struct file *);
-static int get_path_component(char *, int, const char *);
-static int file_tree(struct archive_write *, struct file **);
-static void file_register(struct xar *, struct file *);
-static void file_init_register(struct xar *);
-static void file_free_register(struct xar *);
-static int file_register_hardlink(struct archive_write *,
- struct file *);
-static void file_connect_hardlink_files(struct xar *);
-static void file_init_hardlinks(struct xar *);
-static void file_free_hardlinks(struct xar *);
-
-static void checksum_init(struct chksumwork *, enum sumalg);
-static void checksum_update(struct chksumwork *, const void *, size_t);
-static void checksum_final(struct chksumwork *, struct chksumval *);
-static int compression_init_encoder_gzip(struct archive *,
- struct la_zstream *, int, int);
-static int compression_code_gzip(struct archive *,
- struct la_zstream *, enum la_zaction);
-static int compression_end_gzip(struct archive *, struct la_zstream *);
-static int compression_init_encoder_bzip2(struct archive *,
- struct la_zstream *, int);
-#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
-static int compression_code_bzip2(struct archive *,
- struct la_zstream *, enum la_zaction);
-static int compression_end_bzip2(struct archive *, struct la_zstream *);
-#endif
-static int compression_init_encoder_lzma(struct archive *,
- struct la_zstream *, int);
-static int compression_init_encoder_xz(struct archive *,
- struct la_zstream *, int, int);
-#if defined(HAVE_LZMA_H)
-static int compression_code_lzma(struct archive *,
- struct la_zstream *, enum la_zaction);
-static int compression_end_lzma(struct archive *, struct la_zstream *);
-#endif
-static int xar_compression_init_encoder(struct archive_write *);
-static int compression_code(struct archive *,
- struct la_zstream *, enum la_zaction);
-static int compression_end(struct archive *,
- struct la_zstream *);
-static int save_xattrs(struct archive_write *, struct file *);
-static int getalgsize(enum sumalg);
-static const char *getalgname(enum sumalg);
-
-int
-archive_write_set_format_xar(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct xar *xar;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_format_xar");
-
- /* If another format was already registered, unregister it. */
- if (a->format_free != NULL)
- (a->format_free)(a);
-
- xar = calloc(1, sizeof(*xar));
- if (xar == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate xar data");
- return (ARCHIVE_FATAL);
- }
- xar->temp_fd = -1;
- file_init_register(xar);
- file_init_hardlinks(xar);
- archive_string_init(&(xar->tstr));
- archive_string_init(&(xar->vstr));
-
- /*
- * Create the root directory.
- */
- xar->root = file_create_virtual_dir(a, xar, "");
- if (xar->root == NULL) {
- free(xar);
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate xar data");
- return (ARCHIVE_FATAL);
- }
- xar->root->parent = xar->root;
- file_register(xar, xar->root);
- xar->cur_dirent = xar->root;
- archive_string_init(&(xar->cur_dirstr));
- archive_string_ensure(&(xar->cur_dirstr), 1);
- xar->cur_dirstr.s[0] = 0;
-
- /*
- * Initialize option.
- */
- /* Set default checksum type. */
- xar->opt_toc_sumalg = CKSUM_SHA1;
- xar->opt_sumalg = CKSUM_SHA1;
- /* Set default compression type, level, and number of threads. */
- xar->opt_compression = GZIP;
- xar->opt_compression_level = 6;
- xar->opt_threads = 1;
-
- a->format_data = xar;
-
- a->format_name = "xar";
- a->format_options = xar_options;
- a->format_write_header = xar_write_header;
- a->format_write_data = xar_write_data;
- a->format_finish_entry = xar_finish_entry;
- a->format_close = xar_close;
- a->format_free = xar_free;
- a->archive.archive_format = ARCHIVE_FORMAT_XAR;
- a->archive.archive_format_name = "xar";
-
- return (ARCHIVE_OK);
-}
-
-static int
-xar_options(struct archive_write *a, const char *key, const char *value)
-{
- struct xar *xar;
-
- xar = (struct xar *)a->format_data;
-
- if (strcmp(key, "checksum") == 0) {
- if (value == NULL)
- xar->opt_sumalg = CKSUM_NONE;
- else if (strcmp(value, "none") == 0)
- xar->opt_sumalg = CKSUM_NONE;
- else if (strcmp(value, "sha1") == 0)
- xar->opt_sumalg = CKSUM_SHA1;
- else if (strcmp(value, "md5") == 0)
- xar->opt_sumalg = CKSUM_MD5;
- else {
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "Unknown checksum name: `%s'",
- value);
- return (ARCHIVE_FAILED);
- }
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "compression") == 0) {
- const char *name = NULL;
-
- if (value == NULL)
- xar->opt_compression = NONE;
- else if (strcmp(value, "none") == 0)
- xar->opt_compression = NONE;
- else if (strcmp(value, "gzip") == 0)
- xar->opt_compression = GZIP;
- else if (strcmp(value, "bzip2") == 0)
-#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
- xar->opt_compression = BZIP2;
-#else
- name = "bzip2";
-#endif
- else if (strcmp(value, "lzma") == 0)
-#if HAVE_LZMA_H
- xar->opt_compression = LZMA;
-#else
- name = "lzma";
-#endif
- else if (strcmp(value, "xz") == 0)
-#if HAVE_LZMA_H
- xar->opt_compression = XZ;
-#else
- name = "xz";
-#endif
- else {
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "Unknown compression name: `%s'",
- value);
- return (ARCHIVE_FAILED);
- }
- if (name != NULL) {
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "`%s' compression not supported "
- "on this platform",
- name);
- return (ARCHIVE_FAILED);
- }
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "compression-level") == 0) {
- if (value == NULL ||
- !(value[0] >= '0' && value[0] <= '9') ||
- value[1] != '\0') {
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "Illegal value `%s'",
- value);
- return (ARCHIVE_FAILED);
- }
- xar->opt_compression_level = value[0] - '0';
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "toc-checksum") == 0) {
- if (value == NULL)
- xar->opt_toc_sumalg = CKSUM_NONE;
- else if (strcmp(value, "none") == 0)
- xar->opt_toc_sumalg = CKSUM_NONE;
- else if (strcmp(value, "sha1") == 0)
- xar->opt_toc_sumalg = CKSUM_SHA1;
- else if (strcmp(value, "md5") == 0)
- xar->opt_toc_sumalg = CKSUM_MD5;
- else {
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "Unknown checksum name: `%s'",
- value);
- return (ARCHIVE_FAILED);
- }
- return (ARCHIVE_OK);
- }
- if (strcmp(key, "threads") == 0) {
- char *endptr;
-
- if (value == NULL)
- return (ARCHIVE_FAILED);
- errno = 0;
- xar->opt_threads = (int)strtoul(value, &endptr, 10);
- if (errno != 0 || *endptr != '\0') {
- xar->opt_threads = 1;
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "Illegal value `%s'",
- value);
- return (ARCHIVE_FAILED);
- }
- if (xar->opt_threads == 0) {
-#ifdef HAVE_LZMA_STREAM_ENCODER_MT
- xar->opt_threads = lzma_cputhreads();
-#else
- xar->opt_threads = 1;
-#endif
- }
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-static int
-xar_write_header(struct archive_write *a, struct archive_entry *entry)
-{
- struct xar *xar;
- struct file *file;
- struct archive_entry *file_entry;
- int r, r2;
-
- xar = (struct xar *)a->format_data;
- xar->cur_file = NULL;
- xar->bytes_remaining = 0;
-
- if (xar->sconv == NULL) {
- xar->sconv = archive_string_conversion_to_charset(
- &a->archive, "UTF-8", 1);
- if (xar->sconv == NULL)
- return (ARCHIVE_FATAL);
- }
-
- file = file_new(a, entry);
- if (file == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate data");
- return (ARCHIVE_FATAL);
- }
- r2 = file_gen_utility_names(a, file);
- if (r2 < ARCHIVE_WARN)
- return (r2);
-
- /*
- * Ignore a path which looks like the top of directory name
- * since we have already made the root directory of an Xar archive.
- */
- if (archive_strlen(&(file->parentdir)) == 0 &&
- archive_strlen(&(file->basename)) == 0) {
- file_free(file);
- return (r2);
- }
-
- /* Add entry into tree */
- file_entry = file->entry;
- r = file_tree(a, &file);
- if (r != ARCHIVE_OK)
- return (r);
- /* There is the same file in tree and
- * the current file is older than the file in tree.
- * So we don't need the current file data anymore. */
- if (file->entry != file_entry)
- return (r2);
- if (file->id == 0)
- file_register(xar, file);
-
- /* A virtual file, which is a directory, does not have
- * any contents and we won't store it into a archive
- * file other than its name. */
- if (file->virtual)
- return (r2);
-
- /*
- * Prepare to save the contents of the file.
- */
- if (xar->temp_fd == -1) {
- int algsize;
- xar->temp_offset = 0;
- xar->temp_fd = __archive_mktemp(NULL);
- if (xar->temp_fd < 0) {
- archive_set_error(&a->archive, errno,
- "Couldn't create temporary file");
- return (ARCHIVE_FATAL);
- }
- algsize = getalgsize(xar->opt_toc_sumalg);
- if (algsize > 0) {
- if (lseek(xar->temp_fd, algsize, SEEK_SET) < 0) {
- archive_set_error(&(a->archive), errno,
- "lseek failed");
- return (ARCHIVE_FATAL);
- }
- xar->temp_offset = algsize;
- }
- }
-
- if (archive_entry_hardlink(file->entry) == NULL) {
- r = save_xattrs(a, file);
- if (r != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- }
-
- /* Non regular files contents are unneeded to be saved to
- * a temporary file. */
- if (archive_entry_filetype(file->entry) != AE_IFREG)
- return (r2);
-
- /*
- * Set the current file to cur_file to read its contents.
- */
- xar->cur_file = file;
-
- if (archive_entry_nlink(file->entry) > 1) {
- r = file_register_hardlink(a, file);
- if (r != ARCHIVE_OK)
- return (r);
- if (archive_entry_hardlink(file->entry) != NULL) {
- archive_entry_unset_size(file->entry);
- return (r2);
- }
- }
-
- /* Save a offset of current file in temporary file. */
- file->data.temp_offset = xar->temp_offset;
- file->data.size = archive_entry_size(file->entry);
- file->data.compression = xar->opt_compression;
- xar->bytes_remaining = archive_entry_size(file->entry);
- checksum_init(&(xar->a_sumwrk), xar->opt_sumalg);
- checksum_init(&(xar->e_sumwrk), xar->opt_sumalg);
- r = xar_compression_init_encoder(a);
-
- if (r != ARCHIVE_OK)
- return (r);
- else
- return (r2);
-}
-
-static int
-write_to_temp(struct archive_write *a, const void *buff, size_t s)
-{
- struct xar *xar;
- const unsigned char *p;
- ssize_t ws;
-
- xar = (struct xar *)a->format_data;
- p = (const unsigned char *)buff;
- while (s) {
- ws = write(xar->temp_fd, p, s);
- if (ws < 0) {
- archive_set_error(&(a->archive), errno,
- "fwrite function failed");
- return (ARCHIVE_FATAL);
- }
- s -= ws;
- p += ws;
- xar->temp_offset += ws;
- }
- return (ARCHIVE_OK);
-}
-
-static ssize_t
-xar_write_data(struct archive_write *a, const void *buff, size_t s)
-{
- struct xar *xar;
- enum la_zaction run;
- size_t size = 0;
- size_t rsize;
- int r;
-
- xar = (struct xar *)a->format_data;
-
- if (s > xar->bytes_remaining)
- s = (size_t)xar->bytes_remaining;
- if (s == 0 || xar->cur_file == NULL)
- return (0);
- if (xar->cur_file->data.compression == NONE) {
- checksum_update(&(xar->e_sumwrk), buff, s);
- checksum_update(&(xar->a_sumwrk), buff, s);
- size = rsize = s;
- } else {
- xar->stream.next_in = (const unsigned char *)buff;
- xar->stream.avail_in = s;
- if (xar->bytes_remaining > s)
- run = ARCHIVE_Z_RUN;
- else
- run = ARCHIVE_Z_FINISH;
- /* Compress file data. */
- for (;;) {
- r = compression_code(&(a->archive), &(xar->stream),
- run);
- if (r != ARCHIVE_OK && r != ARCHIVE_EOF)
- return (ARCHIVE_FATAL);
- if (xar->stream.avail_out == 0 ||
- run == ARCHIVE_Z_FINISH) {
- size = sizeof(xar->wbuff) -
- xar->stream.avail_out;
- checksum_update(&(xar->a_sumwrk), xar->wbuff,
- size);
- xar->cur_file->data.length += size;
- if (write_to_temp(a, xar->wbuff,
- size) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- if (r == ARCHIVE_OK) {
- /* Output buffer was full */
- xar->stream.next_out = xar->wbuff;
- xar->stream.avail_out =
- sizeof(xar->wbuff);
- } else {
- /* ARCHIVE_EOF - We are done */
- break;
- }
- } else {
- /* Compressor wants more input */
- break;
- }
- }
- rsize = s - xar->stream.avail_in;
- checksum_update(&(xar->e_sumwrk), buff, rsize);
- }
-#if !defined(_WIN32) || defined(__CYGWIN__)
- if (xar->bytes_remaining ==
- (uint64_t)archive_entry_size(xar->cur_file->entry)) {
- /*
- * Get the path of a shell script if so.
- */
- const unsigned char *b = (const unsigned char *)buff;
-
- archive_string_empty(&(xar->cur_file->script));
- if (rsize > 2 && b[0] == '#' && b[1] == '!') {
- size_t i, end, off;
-
- off = 2;
- if (b[off] == ' ')
- off++;
-#ifdef PATH_MAX
- if ((rsize - off) > PATH_MAX)
- end = off + PATH_MAX;
- else
-#endif
- end = rsize;
- /* Find the end of a script path. */
- for (i = off; i < end && b[i] != '\0' &&
- b[i] != '\n' && b[i] != '\r' &&
- b[i] != ' ' && b[i] != '\t'; i++)
- ;
- archive_strncpy(&(xar->cur_file->script), b + off,
- i - off);
- }
- }
-#endif
-
- if (xar->cur_file->data.compression == NONE) {
- if (write_to_temp(a, buff, size) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- xar->cur_file->data.length += size;
- }
- xar->bytes_remaining -= rsize;
-
- return (rsize);
-}
-
-static int
-xar_finish_entry(struct archive_write *a)
-{
- struct xar *xar;
- struct file *file;
- size_t s;
- ssize_t w;
-
- xar = (struct xar *)a->format_data;
- if (xar->cur_file == NULL)
- return (ARCHIVE_OK);
-
- while (xar->bytes_remaining > 0) {
- s = (size_t)xar->bytes_remaining;
- if (s > a->null_length)
- s = a->null_length;
- w = xar_write_data(a, a->nulls, s);
- if (w > 0)
- xar->bytes_remaining -= w;
- else
- return (w);
- }
- file = xar->cur_file;
- checksum_final(&(xar->e_sumwrk), &(file->data.e_sum));
- checksum_final(&(xar->a_sumwrk), &(file->data.a_sum));
- xar->cur_file = NULL;
-
- return (ARCHIVE_OK);
-}
-
-static int
-xmlwrite_string_attr(struct archive_write *a, xmlTextWriterPtr writer,
- const char *key, const char *value,
- const char *attrkey, const char *attrvalue)
-{
- int r;
-
- r = xmlTextWriterStartElement(writer, BAD_CAST_CONST(key));
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterStartElement() failed: %d", r);
- return (ARCHIVE_FATAL);
- }
- if (attrkey != NULL && attrvalue != NULL) {
- r = xmlTextWriterWriteAttribute(writer,
- BAD_CAST_CONST(attrkey), BAD_CAST_CONST(attrvalue));
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterWriteAttribute() failed: %d", r);
- return (ARCHIVE_FATAL);
- }
- }
- if (value != NULL) {
- r = xmlTextWriterWriteString(writer, BAD_CAST_CONST(value));
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterWriteString() failed: %d", r);
- return (ARCHIVE_FATAL);
- }
- }
- r = xmlTextWriterEndElement(writer);
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterEndElement() failed: %d", r);
- return (ARCHIVE_FATAL);
- }
- return (ARCHIVE_OK);
-}
-
-static int
-xmlwrite_string(struct archive_write *a, xmlTextWriterPtr writer,
- const char *key, const char *value)
-{
- int r;
-
- if (value == NULL)
- return (ARCHIVE_OK);
-
- r = xmlTextWriterStartElement(writer, BAD_CAST_CONST(key));
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterStartElement() failed: %d", r);
- return (ARCHIVE_FATAL);
- }
- if (value != NULL) {
- r = xmlTextWriterWriteString(writer, BAD_CAST_CONST(value));
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterWriteString() failed: %d", r);
- return (ARCHIVE_FATAL);
- }
- }
- r = xmlTextWriterEndElement(writer);
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterEndElement() failed: %d", r);
- return (ARCHIVE_FATAL);
- }
- return (ARCHIVE_OK);
-}
-
-static int
-xmlwrite_fstring(struct archive_write *a, xmlTextWriterPtr writer,
- const char *key, const char *fmt, ...)
-{
- struct xar *xar;
- va_list ap;
-
- xar = (struct xar *)a->format_data;
- va_start(ap, fmt);
- archive_string_empty(&xar->vstr);
- archive_string_vsprintf(&xar->vstr, fmt, ap);
- va_end(ap);
- return (xmlwrite_string(a, writer, key, xar->vstr.s));
-}
-
-static int
-xmlwrite_time(struct archive_write *a, xmlTextWriterPtr writer,
- const char *key, time_t t, int z)
-{
- char timestr[100];
- struct tm tm;
-
-#if defined(HAVE_GMTIME_S)
- gmtime_s(&tm, &t);
-#elif defined(HAVE_GMTIME_R)
- gmtime_r(&t, &tm);
-#else
- memcpy(&tm, gmtime(&t), sizeof(tm));
-#endif
- memset(&timestr, 0, sizeof(timestr));
- /* Do not use %F and %T for portability. */
- strftime(timestr, sizeof(timestr), "%Y-%m-%dT%H:%M:%S", &tm);
- if (z)
- strcat(timestr, "Z");
- return (xmlwrite_string(a, writer, key, timestr));
-}
-
-static int
-xmlwrite_mode(struct archive_write *a, xmlTextWriterPtr writer,
- const char *key, mode_t mode)
-{
- char ms[5];
-
- ms[0] = '0';
- ms[1] = '0' + ((mode >> 6) & 07);
- ms[2] = '0' + ((mode >> 3) & 07);
- ms[3] = '0' + (mode & 07);
- ms[4] = '\0';
-
- return (xmlwrite_string(a, writer, key, ms));
-}
-
-static int
-xmlwrite_sum(struct archive_write *a, xmlTextWriterPtr writer,
- const char *key, struct chksumval *sum)
-{
- const char *algname;
- int algsize;
- char buff[MAX_SUM_SIZE*2 + 1];
- char *p;
- unsigned char *s;
- int i, r;
-
- if (sum->len > 0) {
- algname = getalgname(sum->alg);
- algsize = getalgsize(sum->alg);
- if (algname != NULL) {
- const char *hex = "0123456789abcdef";
- p = buff;
- s = sum->val;
- for (i = 0; i < algsize; i++) {
- *p++ = hex[(*s >> 4)];
- *p++ = hex[(*s & 0x0f)];
- s++;
- }
- *p = '\0';
- r = xmlwrite_string_attr(a, writer,
- key, buff,
- "style", algname);
- if (r < 0)
- return (ARCHIVE_FATAL);
- }
- }
- return (ARCHIVE_OK);
-}
-
-static int
-xmlwrite_heap(struct archive_write *a, xmlTextWriterPtr writer,
- struct heap_data *heap)
-{
- const char *encname;
- int r;
-
- r = xmlwrite_fstring(a, writer, "length", "%ju", heap->length);
- if (r < 0)
- return (ARCHIVE_FATAL);
- r = xmlwrite_fstring(a, writer, "offset", "%ju", heap->temp_offset);
- if (r < 0)
- return (ARCHIVE_FATAL);
- r = xmlwrite_fstring(a, writer, "size", "%ju", heap->size);
- if (r < 0)
- return (ARCHIVE_FATAL);
- switch (heap->compression) {
- case GZIP:
- encname = "application/x-gzip"; break;
- case BZIP2:
- encname = "application/x-bzip2"; break;
- case LZMA:
- encname = "application/x-lzma"; break;
- case XZ:
- encname = "application/x-xz"; break;
- default:
- encname = "application/octet-stream"; break;
- }
- r = xmlwrite_string_attr(a, writer, "encoding", NULL,
- "style", encname);
- if (r < 0)
- return (ARCHIVE_FATAL);
- r = xmlwrite_sum(a, writer, "archived-checksum", &(heap->a_sum));
- if (r < 0)
- return (ARCHIVE_FATAL);
- r = xmlwrite_sum(a, writer, "extracted-checksum", &(heap->e_sum));
- if (r < 0)
- return (ARCHIVE_FATAL);
- return (ARCHIVE_OK);
-}
-
-/*
- * xar utility records fflags as following xml elements:
- * <flags>
- * <UserNoDump/>
- * .....
- * </flags>
- * or
- * <ext2>
- * <NoDump/>
- * .....
- * </ext2>
- * If xar is running on BSD platform, records <flags>..</flags>;
- * if xar is running on linux platform, records <ext2>..</ext2>;
- * otherwise does not record.
- *
- * Our implements records both <flags> and <ext2> if it's necessary.
- */
-static int
-make_fflags_entry(struct archive_write *a, xmlTextWriterPtr writer,
- const char *element, const char *fflags_text)
-{
- static const struct flagentry {
- const char *name;
- const char *xarname;
- }
- flagbsd[] = {
- { "sappnd", "SystemAppend"},
- { "sappend", "SystemAppend"},
- { "arch", "SystemArchived"},
- { "archived", "SystemArchived"},
- { "schg", "SystemImmutable"},
- { "schange", "SystemImmutable"},
- { "simmutable", "SystemImmutable"},
- { "nosunlnk", "SystemNoUnlink"},
- { "nosunlink", "SystemNoUnlink"},
- { "snapshot", "SystemSnapshot"},
- { "uappnd", "UserAppend"},
- { "uappend", "UserAppend"},
- { "uchg", "UserImmutable"},
- { "uchange", "UserImmutable"},
- { "uimmutable", "UserImmutable"},
- { "nodump", "UserNoDump"},
- { "noopaque", "UserOpaque"},
- { "nouunlnk", "UserNoUnlink"},
- { "nouunlink", "UserNoUnlink"},
- { NULL, NULL}
- },
- flagext2[] = {
- { "sappnd", "AppendOnly"},
- { "sappend", "AppendOnly"},
- { "schg", "Immutable"},
- { "schange", "Immutable"},
- { "simmutable", "Immutable"},
- { "nodump", "NoDump"},
- { "nouunlnk", "Undelete"},
- { "nouunlink", "Undelete"},
- { "btree", "BTree"},
- { "comperr", "CompError"},
- { "compress", "Compress"},
- { "noatime", "NoAtime"},
- { "compdirty", "CompDirty"},
- { "comprblk", "CompBlock"},
- { "dirsync", "DirSync"},
- { "hashidx", "HashIndexed"},
- { "imagic", "iMagic"},
- { "journal", "Journaled"},
- { "securedeletion", "SecureDeletion"},
- { "sync", "Synchronous"},
- { "notail", "NoTail"},
- { "topdir", "TopDir"},
- { "reserved", "Reserved"},
- { NULL, NULL}
- };
- const struct flagentry *fe, *flagentry;
-#define FLAGENTRY_MAXSIZE ((sizeof(flagbsd)+sizeof(flagext2))/sizeof(flagbsd))
- const struct flagentry *avail[FLAGENTRY_MAXSIZE];
- const char *p;
- int i, n, r;
-
- if (strcmp(element, "ext2") == 0)
- flagentry = flagext2;
- else
- flagentry = flagbsd;
- n = 0;
- p = fflags_text;
- do {
- const char *cp;
-
- cp = strchr(p, ',');
- if (cp == NULL)
- cp = p + strlen(p);
-
- for (fe = flagentry; fe->name != NULL; fe++) {
- if (fe->name[cp - p] != '\0'
- || p[0] != fe->name[0])
- continue;
- if (strncmp(p, fe->name, cp - p) == 0) {
- avail[n++] = fe;
- break;
- }
- }
- if (*cp == ',')
- p = cp + 1;
- else
- p = NULL;
- } while (p != NULL);
-
- if (n > 0) {
- r = xmlTextWriterStartElement(writer, BAD_CAST_CONST(element));
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterStartElement() failed: %d", r);
- return (ARCHIVE_FATAL);
- }
- for (i = 0; i < n; i++) {
- r = xmlwrite_string(a, writer,
- avail[i]->xarname, NULL);
- if (r != ARCHIVE_OK)
- return (r);
- }
-
- r = xmlTextWriterEndElement(writer);
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterEndElement() failed: %d", r);
- return (ARCHIVE_FATAL);
- }
- }
- return (ARCHIVE_OK);
-}
-
-static int
-make_file_entry(struct archive_write *a, xmlTextWriterPtr writer,
- struct file *file)
-{
- struct xar *xar;
- const char *filetype, *filelink, *fflags;
- struct archive_string linkto;
- struct heap_data *heap;
- unsigned char *tmp;
- const char *p;
- size_t len;
- int r, r2, l, ll;
-
- xar = (struct xar *)a->format_data;
- r2 = ARCHIVE_OK;
-
- /*
- * Make a file name entry, "<name>".
- */
- l = ll = archive_strlen(&(file->basename));
- tmp = malloc(l);
- if (tmp == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- r = UTF8Toisolat1(tmp, &l, BAD_CAST(file->basename.s), &ll);
- free(tmp);
- if (r < 0) {
- r = xmlTextWriterStartElement(writer, BAD_CAST("name"));
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterStartElement() failed: %d", r);
- return (ARCHIVE_FATAL);
- }
- r = xmlTextWriterWriteAttribute(writer,
- BAD_CAST("enctype"), BAD_CAST("base64"));
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterWriteAttribute() failed: %d", r);
- return (ARCHIVE_FATAL);
- }
- r = xmlTextWriterWriteBase64(writer, file->basename.s,
- 0, archive_strlen(&(file->basename)));
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterWriteBase64() failed: %d", r);
- return (ARCHIVE_FATAL);
- }
- r = xmlTextWriterEndElement(writer);
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterEndElement() failed: %d", r);
- return (ARCHIVE_FATAL);
- }
- } else {
- r = xmlwrite_string(a, writer, "name", file->basename.s);
- if (r < 0)
- return (ARCHIVE_FATAL);
- }
-
- /*
- * Make a file type entry, "<type>".
- */
- filelink = NULL;
- archive_string_init(&linkto);
- switch (archive_entry_filetype(file->entry)) {
- case AE_IFDIR:
- filetype = "directory"; break;
- case AE_IFLNK:
- filetype = "symlink"; break;
- case AE_IFCHR:
- filetype = "character special"; break;
- case AE_IFBLK:
- filetype = "block special"; break;
- case AE_IFSOCK:
- filetype = "socket"; break;
- case AE_IFIFO:
- filetype = "fifo"; break;
- case AE_IFREG:
- default:
- if (file->hardlink_target != NULL) {
- filetype = "hardlink";
- filelink = "link";
- if (file->hardlink_target == file)
- archive_strcpy(&linkto, "original");
- else
- archive_string_sprintf(&linkto, "%d",
- file->hardlink_target->id);
- } else
- filetype = "file";
- break;
- }
- r = xmlwrite_string_attr(a, writer, "type", filetype,
- filelink, linkto.s);
- archive_string_free(&linkto);
- if (r < 0)
- return (ARCHIVE_FATAL);
-
- /*
- * On a virtual directory, we record "name" and "type" only.
- */
- if (file->virtual)
- return (ARCHIVE_OK);
-
- switch (archive_entry_filetype(file->entry)) {
- case AE_IFLNK:
- /*
- * xar utility has checked a file type, which
- * a symbolic-link file has referenced.
- * For example:
- * <link type="directory">../ref/</link>
- * The symlink target file is "../ref/" and its
- * file type is a directory.
- *
- * <link type="file">../f</link>
- * The symlink target file is "../f" and its
- * file type is a regular file.
- *
- * But our implementation cannot do it, and then we
- * always record that a attribute "type" is "broken",
- * for example:
- * <link type="broken">foo/bar</link>
- * It means "foo/bar" is not reachable.
- */
- r = xmlwrite_string_attr(a, writer, "link",
- file->symlink.s,
- "type", "broken");
- if (r < 0)
- return (ARCHIVE_FATAL);
- break;
- case AE_IFCHR:
- case AE_IFBLK:
- r = xmlTextWriterStartElement(writer, BAD_CAST("device"));
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterStartElement() failed: %d", r);
- return (ARCHIVE_FATAL);
- }
- r = xmlwrite_fstring(a, writer, "major",
- "%d", archive_entry_rdevmajor(file->entry));
- if (r < 0)
- return (ARCHIVE_FATAL);
- r = xmlwrite_fstring(a, writer, "minor",
- "%d", archive_entry_rdevminor(file->entry));
- if (r < 0)
- return (ARCHIVE_FATAL);
- r = xmlTextWriterEndElement(writer);
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterEndElement() failed: %d", r);
- return (ARCHIVE_FATAL);
- }
- break;
- default:
- break;
- }
-
- /*
- * Make a inode entry, "<inode>".
- */
- r = xmlwrite_fstring(a, writer, "inode",
- "%jd", archive_entry_ino64(file->entry));
- if (r < 0)
- return (ARCHIVE_FATAL);
- if (archive_entry_dev(file->entry) != 0) {
- r = xmlwrite_fstring(a, writer, "deviceno",
- "%d", archive_entry_dev(file->entry));
- if (r < 0)
- return (ARCHIVE_FATAL);
- }
-
- /*
- * Make a file mode entry, "<mode>".
- */
- r = xmlwrite_mode(a, writer, "mode",
- archive_entry_mode(file->entry));
- if (r < 0)
- return (ARCHIVE_FATAL);
-
- /*
- * Make a user entry, "<uid>" and "<user>.
- */
- r = xmlwrite_fstring(a, writer, "uid",
- "%d", archive_entry_uid(file->entry));
- if (r < 0)
- return (ARCHIVE_FATAL);
- r = archive_entry_uname_l(file->entry, &p, &len, xar->sconv);
- if (r != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Uname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate uname '%s' to UTF-8",
- archive_entry_uname(file->entry));
- r2 = ARCHIVE_WARN;
- }
- if (len > 0) {
- r = xmlwrite_string(a, writer, "user", p);
- if (r < 0)
- return (ARCHIVE_FATAL);
- }
-
- /*
- * Make a group entry, "<gid>" and "<group>.
- */
- r = xmlwrite_fstring(a, writer, "gid",
- "%d", archive_entry_gid(file->entry));
- if (r < 0)
- return (ARCHIVE_FATAL);
- r = archive_entry_gname_l(file->entry, &p, &len, xar->sconv);
- if (r != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Gname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate gname '%s' to UTF-8",
- archive_entry_gname(file->entry));
- r2 = ARCHIVE_WARN;
- }
- if (len > 0) {
- r = xmlwrite_string(a, writer, "group", p);
- if (r < 0)
- return (ARCHIVE_FATAL);
- }
-
- /*
- * Make a ctime entry, "<ctime>".
- */
- if (archive_entry_ctime_is_set(file->entry)) {
- r = xmlwrite_time(a, writer, "ctime",
- archive_entry_ctime(file->entry), 1);
- if (r < 0)
- return (ARCHIVE_FATAL);
- }
-
- /*
- * Make a mtime entry, "<mtime>".
- */
- if (archive_entry_mtime_is_set(file->entry)) {
- r = xmlwrite_time(a, writer, "mtime",
- archive_entry_mtime(file->entry), 1);
- if (r < 0)
- return (ARCHIVE_FATAL);
- }
-
- /*
- * Make a atime entry, "<atime>".
- */
- if (archive_entry_atime_is_set(file->entry)) {
- r = xmlwrite_time(a, writer, "atime",
- archive_entry_atime(file->entry), 1);
- if (r < 0)
- return (ARCHIVE_FATAL);
- }
-
- /*
- * Make fflags entries, "<flags>" and "<ext2>".
- */
- fflags = archive_entry_fflags_text(file->entry);
- if (fflags != NULL) {
- r = make_fflags_entry(a, writer, "flags", fflags);
- if (r < 0)
- return (r);
- r = make_fflags_entry(a, writer, "ext2", fflags);
- if (r < 0)
- return (r);
- }
-
- /*
- * Make extended attribute entries, "<ea>".
- */
- archive_entry_xattr_reset(file->entry);
- for (heap = file->xattr.first; heap != NULL; heap = heap->next) {
- const char *name;
- const void *value;
- size_t size;
-
- archive_entry_xattr_next(file->entry,
- &name, &value, &size);
- r = xmlTextWriterStartElement(writer, BAD_CAST("ea"));
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterStartElement() failed: %d", r);
- return (ARCHIVE_FATAL);
- }
- r = xmlTextWriterWriteFormatAttribute(writer,
- BAD_CAST("id"), "%d", heap->id);
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterWriteAttribute() failed: %d", r);
- return (ARCHIVE_FATAL);
- }
- r = xmlwrite_heap(a, writer, heap);
- if (r < 0)
- return (ARCHIVE_FATAL);
- r = xmlwrite_string(a, writer, "name", name);
- if (r < 0)
- return (ARCHIVE_FATAL);
-
- r = xmlTextWriterEndElement(writer);
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterEndElement() failed: %d", r);
- return (ARCHIVE_FATAL);
- }
- }
-
- /*
- * Make a file data entry, "<data>".
- */
- if (file->data.length > 0) {
- r = xmlTextWriterStartElement(writer, BAD_CAST("data"));
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterStartElement() failed: %d", r);
- return (ARCHIVE_FATAL);
- }
-
- r = xmlwrite_heap(a, writer, &(file->data));
- if (r < 0)
- return (ARCHIVE_FATAL);
-
- r = xmlTextWriterEndElement(writer);
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterEndElement() failed: %d", r);
- return (ARCHIVE_FATAL);
- }
- }
-
- if (archive_strlen(&file->script) > 0) {
- r = xmlTextWriterStartElement(writer, BAD_CAST("content"));
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterStartElement() failed: %d", r);
- return (ARCHIVE_FATAL);
- }
-
- r = xmlwrite_string(a, writer,
- "interpreter", file->script.s);
- if (r < 0)
- return (ARCHIVE_FATAL);
-
- r = xmlwrite_string(a, writer, "type", "script");
- if (r < 0)
- return (ARCHIVE_FATAL);
-
- r = xmlTextWriterEndElement(writer);
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterEndElement() failed: %d", r);
- return (ARCHIVE_FATAL);
- }
- }
-
- return (r2);
-}
-
-/*
- * Make the TOC
- */
-static int
-make_toc(struct archive_write *a)
-{
- struct xar *xar;
- struct file *np;
- xmlBufferPtr bp;
- xmlTextWriterPtr writer;
- int algsize;
- int r, ret;
-
- xar = (struct xar *)a->format_data;
-
- ret = ARCHIVE_FATAL;
-
- /*
- * Initialize xml writer.
- */
- writer = NULL;
- bp = xmlBufferCreate();
- if (bp == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "xmlBufferCreate() "
- "couldn't create xml buffer");
- goto exit_toc;
- }
- writer = xmlNewTextWriterMemory(bp, 0);
- if (writer == NULL) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlNewTextWriterMemory() "
- "couldn't create xml writer");
- goto exit_toc;
- }
- r = xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL);
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterStartDocument() failed: %d", r);
- goto exit_toc;
- }
- r = xmlTextWriterSetIndent(writer, 4);
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterSetIndent() failed: %d", r);
- goto exit_toc;
- }
-
- /*
- * Start recording TOC
- */
- r = xmlTextWriterStartElement(writer, BAD_CAST("xar"));
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterStartElement() failed: %d", r);
- goto exit_toc;
- }
- r = xmlTextWriterStartElement(writer, BAD_CAST("toc"));
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterStartDocument() failed: %d", r);
- goto exit_toc;
- }
-
- /*
- * Record the creation time of the archive file.
- */
- r = xmlwrite_time(a, writer, "creation-time", time(NULL), 0);
- if (r < 0)
- goto exit_toc;
-
- /*
- * Record the checksum value of TOC
- */
- algsize = getalgsize(xar->opt_toc_sumalg);
- if (algsize) {
- /*
- * Record TOC checksum
- */
- r = xmlTextWriterStartElement(writer, BAD_CAST("checksum"));
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterStartElement() failed: %d", r);
- goto exit_toc;
- }
- r = xmlTextWriterWriteAttribute(writer, BAD_CAST("style"),
- BAD_CAST_CONST(getalgname(xar->opt_toc_sumalg)));
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterWriteAttribute() failed: %d", r);
- goto exit_toc;
- }
-
- /*
- * Record the offset of the value of checksum of TOC
- */
- r = xmlwrite_string(a, writer, "offset", "0");
- if (r < 0)
- goto exit_toc;
-
- /*
- * Record the size of the value of checksum of TOC
- */
- r = xmlwrite_fstring(a, writer, "size", "%d", algsize);
- if (r < 0)
- goto exit_toc;
-
- r = xmlTextWriterEndElement(writer);
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterEndElement() failed: %d", r);
- goto exit_toc;
- }
- }
-
- np = xar->root;
- do {
- if (np != np->parent) {
- r = make_file_entry(a, writer, np);
- if (r != ARCHIVE_OK)
- goto exit_toc;
- }
-
- if (np->dir && np->children.first != NULL) {
- /* Enter to sub directories. */
- np = np->children.first;
- r = xmlTextWriterStartElement(writer,
- BAD_CAST("file"));
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterStartElement() "
- "failed: %d", r);
- goto exit_toc;
- }
- r = xmlTextWriterWriteFormatAttribute(
- writer, BAD_CAST("id"), "%d", np->id);
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterWriteAttribute() "
- "failed: %d", r);
- goto exit_toc;
- }
- continue;
- }
- while (np != np->parent) {
- r = xmlTextWriterEndElement(writer);
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterEndElement() "
- "failed: %d", r);
- goto exit_toc;
- }
- if (np->chnext == NULL) {
- /* Return to the parent directory. */
- np = np->parent;
- } else {
- np = np->chnext;
- r = xmlTextWriterStartElement(writer,
- BAD_CAST("file"));
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterStartElement() "
- "failed: %d", r);
- goto exit_toc;
- }
- r = xmlTextWriterWriteFormatAttribute(
- writer, BAD_CAST("id"), "%d", np->id);
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterWriteAttribute() "
- "failed: %d", r);
- goto exit_toc;
- }
- break;
- }
- }
- } while (np != np->parent);
-
- r = xmlTextWriterEndDocument(writer);
- if (r < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "xmlTextWriterEndDocument() failed: %d", r);
- goto exit_toc;
- }
-#if DEBUG_PRINT_TOC
- fprintf(stderr, "\n---TOC-- %d bytes --\n%s\n",
- strlen((const char *)bp->content), bp->content);
-#endif
-
- /*
- * Compress the TOC and calculate the sum of the TOC.
- */
- xar->toc.temp_offset = xar->temp_offset;
- xar->toc.size = bp->use;
- checksum_init(&(xar->a_sumwrk), xar->opt_toc_sumalg);
-
- r = compression_init_encoder_gzip(&(a->archive),
- &(xar->stream), 6, 1);
- if (r != ARCHIVE_OK)
- goto exit_toc;
- xar->stream.next_in = bp->content;
- xar->stream.avail_in = bp->use;
- xar->stream.total_in = 0;
- xar->stream.next_out = xar->wbuff;
- xar->stream.avail_out = sizeof(xar->wbuff);
- xar->stream.total_out = 0;
- for (;;) {
- size_t size;
-
- r = compression_code(&(a->archive),
- &(xar->stream), ARCHIVE_Z_FINISH);
- if (r != ARCHIVE_OK && r != ARCHIVE_EOF)
- goto exit_toc;
- size = sizeof(xar->wbuff) - xar->stream.avail_out;
- checksum_update(&(xar->a_sumwrk), xar->wbuff, size);
- if (write_to_temp(a, xar->wbuff, size) != ARCHIVE_OK)
- goto exit_toc;
- if (r == ARCHIVE_EOF)
- break;
- xar->stream.next_out = xar->wbuff;
- xar->stream.avail_out = sizeof(xar->wbuff);
- }
- r = compression_end(&(a->archive), &(xar->stream));
- if (r != ARCHIVE_OK)
- goto exit_toc;
- xar->toc.length = xar->stream.total_out;
- xar->toc.compression = GZIP;
- checksum_final(&(xar->a_sumwrk), &(xar->toc.a_sum));
-
- ret = ARCHIVE_OK;
-exit_toc:
- if (writer)
- xmlFreeTextWriter(writer);
- if (bp)
- xmlBufferFree(bp);
-
- return (ret);
-}
-
-static int
-flush_wbuff(struct archive_write *a)
-{
- struct xar *xar;
- int r;
- size_t s;
-
- xar = (struct xar *)a->format_data;
- s = sizeof(xar->wbuff) - xar->wbuff_remaining;
- r = __archive_write_output(a, xar->wbuff, s);
- if (r != ARCHIVE_OK)
- return (r);
- xar->wbuff_remaining = sizeof(xar->wbuff);
- return (r);
-}
-
-static int
-copy_out(struct archive_write *a, uint64_t offset, uint64_t length)
-{
- struct xar *xar;
- int r;
-
- xar = (struct xar *)a->format_data;
- if (lseek(xar->temp_fd, offset, SEEK_SET) < 0) {
- archive_set_error(&(a->archive), errno, "lseek failed");
- return (ARCHIVE_FATAL);
- }
- while (length) {
- size_t rsize;
- ssize_t rs;
- unsigned char *wb;
-
- if (length > xar->wbuff_remaining)
- rsize = xar->wbuff_remaining;
- else
- rsize = (size_t)length;
- wb = xar->wbuff + (sizeof(xar->wbuff) - xar->wbuff_remaining);
- rs = read(xar->temp_fd, wb, rsize);
- if (rs < 0) {
- archive_set_error(&(a->archive), errno,
- "Can't read temporary file(%jd)",
- (intmax_t)rs);
- return (ARCHIVE_FATAL);
- }
- if (rs == 0) {
- archive_set_error(&(a->archive), 0,
- "Truncated xar archive");
- return (ARCHIVE_FATAL);
- }
- xar->wbuff_remaining -= rs;
- length -= rs;
- if (xar->wbuff_remaining == 0) {
- r = flush_wbuff(a);
- if (r != ARCHIVE_OK)
- return (r);
- }
- }
- return (ARCHIVE_OK);
-}
-
-static int
-xar_close(struct archive_write *a)
-{
- struct xar *xar;
- unsigned char *wb;
- uint64_t length;
- int r;
-
- xar = (struct xar *)a->format_data;
-
- /* Empty! */
- if (xar->root->children.first == NULL)
- return (ARCHIVE_OK);
-
- /* Save the length of all file extended attributes and contents. */
- length = xar->temp_offset;
-
- /* Connect hardlinked files */
- file_connect_hardlink_files(xar);
-
- /* Make the TOC */
- r = make_toc(a);
- if (r != ARCHIVE_OK)
- return (r);
- /*
- * Make the xar header on wbuff(write buffer).
- */
- wb = xar->wbuff;
- xar->wbuff_remaining = sizeof(xar->wbuff);
- archive_be32enc(&wb[0], HEADER_MAGIC);
- archive_be16enc(&wb[4], HEADER_SIZE);
- archive_be16enc(&wb[6], HEADER_VERSION);
- archive_be64enc(&wb[8], xar->toc.length);
- archive_be64enc(&wb[16], xar->toc.size);
- archive_be32enc(&wb[24], xar->toc.a_sum.alg);
- xar->wbuff_remaining -= HEADER_SIZE;
-
- /*
- * Write the TOC
- */
- r = copy_out(a, xar->toc.temp_offset, xar->toc.length);
- if (r != ARCHIVE_OK)
- return (r);
-
- /* Write the checksum value of the TOC. */
- if (xar->toc.a_sum.len) {
- if (xar->wbuff_remaining < xar->toc.a_sum.len) {
- r = flush_wbuff(a);
- if (r != ARCHIVE_OK)
- return (r);
- }
- wb = xar->wbuff + (sizeof(xar->wbuff) - xar->wbuff_remaining);
- memcpy(wb, xar->toc.a_sum.val, xar->toc.a_sum.len);
- xar->wbuff_remaining -= xar->toc.a_sum.len;
- }
-
- /*
- * Write all file extended attributes and contents.
- */
- r = copy_out(a, xar->toc.a_sum.len, length);
- if (r != ARCHIVE_OK)
- return (r);
- r = flush_wbuff(a);
- return (r);
-}
-
-static int
-xar_free(struct archive_write *a)
-{
- struct xar *xar;
-
- xar = (struct xar *)a->format_data;
-
- /* Close the temporary file. */
- if (xar->temp_fd >= 0)
- close(xar->temp_fd);
-
- archive_string_free(&(xar->cur_dirstr));
- archive_string_free(&(xar->tstr));
- archive_string_free(&(xar->vstr));
- file_free_hardlinks(xar);
- file_free_register(xar);
- compression_end(&(a->archive), &(xar->stream));
- free(xar);
-
- return (ARCHIVE_OK);
-}
-
-static int
-file_cmp_node(const struct archive_rb_node *n1,
- const struct archive_rb_node *n2)
-{
- const struct file *f1 = (const struct file *)n1;
- const struct file *f2 = (const struct file *)n2;
-
- return (strcmp(f1->basename.s, f2->basename.s));
-}
-
-static int
-file_cmp_key(const struct archive_rb_node *n, const void *key)
-{
- const struct file *f = (const struct file *)n;
-
- return (strcmp(f->basename.s, (const char *)key));
-}
-
-static struct file *
-file_new(struct archive_write *a, struct archive_entry *entry)
-{
- struct file *file;
- static const struct archive_rb_tree_ops rb_ops = {
- file_cmp_node, file_cmp_key
- };
-
- file = calloc(1, sizeof(*file));
- if (file == NULL)
- return (NULL);
-
- if (entry != NULL)
- file->entry = archive_entry_clone(entry);
- else
- file->entry = archive_entry_new2(&a->archive);
- if (file->entry == NULL) {
- free(file);
- return (NULL);
- }
- __archive_rb_tree_init(&(file->rbtree), &rb_ops);
- file->children.first = NULL;
- file->children.last = &(file->children.first);
- file->xattr.first = NULL;
- file->xattr.last = &(file->xattr.first);
- archive_string_init(&(file->parentdir));
- archive_string_init(&(file->basename));
- archive_string_init(&(file->symlink));
- archive_string_init(&(file->script));
- if (entry != NULL && archive_entry_filetype(entry) == AE_IFDIR)
- file->dir = 1;
-
- return (file);
-}
-
-static void
-file_free(struct file *file)
-{
- struct heap_data *heap, *next_heap;
-
- heap = file->xattr.first;
- while (heap != NULL) {
- next_heap = heap->next;
- free(heap);
- heap = next_heap;
- }
- archive_string_free(&(file->parentdir));
- archive_string_free(&(file->basename));
- archive_string_free(&(file->symlink));
- archive_string_free(&(file->script));
- archive_entry_free(file->entry);
- free(file);
-}
-
-static struct file *
-file_create_virtual_dir(struct archive_write *a, struct xar *xar,
- const char *pathname)
-{
- struct file *file;
-
- (void)xar; /* UNUSED */
-
- file = file_new(a, NULL);
- if (file == NULL)
- return (NULL);
- archive_entry_set_pathname(file->entry, pathname);
- archive_entry_set_mode(file->entry, 0555 | AE_IFDIR);
-
- file->dir = 1;
- file->virtual = 1;
-
- return (file);
-}
-
-static int
-file_add_child_tail(struct file *parent, struct file *child)
-{
- if (!__archive_rb_tree_insert_node(
- &(parent->rbtree), (struct archive_rb_node *)child))
- return (0);
- child->chnext = NULL;
- *parent->children.last = child;
- parent->children.last = &(child->chnext);
- child->parent = parent;
- return (1);
-}
-
-/*
- * Find a entry from `parent'
- */
-static struct file *
-file_find_child(struct file *parent, const char *child_name)
-{
- struct file *np;
-
- np = (struct file *)__archive_rb_tree_find_node(
- &(parent->rbtree), child_name);
- return (np);
-}
-
-#if defined(_WIN32) || defined(__CYGWIN__)
-static void
-cleanup_backslash(char *utf8, size_t len)
-{
-
- /* Convert a path-separator from '\' to '/' */
- while (*utf8 != '\0' && len) {
- if (*utf8 == '\\')
- *utf8 = '/';
- ++utf8;
- --len;
- }
-}
-#else
-#define cleanup_backslash(p, len) /* nop */
-#endif
-
-/*
- * Generate a parent directory name and a base name from a pathname.
- */
-static int
-file_gen_utility_names(struct archive_write *a, struct file *file)
-{
- struct xar *xar;
- const char *pp;
- char *p, *dirname, *slash;
- size_t len;
- int r = ARCHIVE_OK;
-
- xar = (struct xar *)a->format_data;
- archive_string_empty(&(file->parentdir));
- archive_string_empty(&(file->basename));
- archive_string_empty(&(file->symlink));
-
- if (file->parent == file)/* virtual root */
- return (ARCHIVE_OK);
-
- if (archive_entry_pathname_l(file->entry, &pp, &len, xar->sconv)
- != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate pathname '%s' to UTF-8",
- archive_entry_pathname(file->entry));
- r = ARCHIVE_WARN;
- }
- archive_strncpy(&(file->parentdir), pp, len);
- len = file->parentdir.length;
- p = dirname = file->parentdir.s;
- /*
- * Convert a path-separator from '\' to '/'
- */
- cleanup_backslash(p, len);
-
- /*
- * Remove leading '/', '../' and './' elements
- */
- while (*p) {
- if (p[0] == '/') {
- p++;
- len--;
- } else if (p[0] != '.')
- break;
- else if (p[1] == '.' && p[2] == '/') {
- p += 3;
- len -= 3;
- } else if (p[1] == '/' || (p[1] == '.' && p[2] == '\0')) {
- p += 2;
- len -= 2;
- } else if (p[1] == '\0') {
- p++;
- len--;
- } else
- break;
- }
- if (p != dirname) {
- memmove(dirname, p, len+1);
- p = dirname;
- }
- /*
- * Remove "/","/." and "/.." elements from tail.
- */
- while (len > 0) {
- size_t ll = len;
-
- if (p[len-1] == '/') {
- p[len-1] = '\0';
- len--;
- }
- if (len > 1 && p[len-2] == '/' && p[len-1] == '.') {
- p[len-2] = '\0';
- len -= 2;
- }
- if (len > 2 && p[len-3] == '/' && p[len-2] == '.' &&
- p[len-1] == '.') {
- p[len-3] = '\0';
- len -= 3;
- }
- if (ll == len)
- break;
- }
- while (*p) {
- if (p[0] == '/') {
- if (p[1] == '/')
- /* Convert '//' --> '/' */
- memmove(p, p+1, strlen(p+1) + 1);
- else if (p[1] == '.' && p[2] == '/')
- /* Convert '/./' --> '/' */
- memmove(p, p+2, strlen(p+2) + 1);
- else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
- /* Convert 'dir/dir1/../dir2/'
- * --> 'dir/dir2/'
- */
- char *rp = p -1;
- while (rp >= dirname) {
- if (*rp == '/')
- break;
- --rp;
- }
- if (rp > dirname) {
- strcpy(rp, p+3);
- p = rp;
- } else {
- strcpy(dirname, p+4);
- p = dirname;
- }
- } else
- p++;
- } else
- p++;
- }
- p = dirname;
- len = strlen(p);
-
- if (archive_entry_filetype(file->entry) == AE_IFLNK) {
- size_t len2;
- /* Convert symlink name too. */
- if (archive_entry_symlink_l(file->entry, &pp, &len2,
- xar->sconv) != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Linkname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate symlink '%s' to UTF-8",
- archive_entry_symlink(file->entry));
- r = ARCHIVE_WARN;
- }
- archive_strncpy(&(file->symlink), pp, len2);
- cleanup_backslash(file->symlink.s, file->symlink.length);
- }
- /*
- * - Count up directory elements.
- * - Find out the position which points the last position of
- * path separator('/').
- */
- slash = NULL;
- for (; *p != '\0'; p++)
- if (*p == '/')
- slash = p;
- if (slash == NULL) {
- /* The pathname doesn't have a parent directory. */
- file->parentdir.length = len;
- archive_string_copy(&(file->basename), &(file->parentdir));
- archive_string_empty(&(file->parentdir));
- *file->parentdir.s = '\0';
- return (r);
- }
-
- /* Make a basename from dirname and slash */
- *slash = '\0';
- file->parentdir.length = slash - dirname;
- archive_strcpy(&(file->basename), slash + 1);
- return (r);
-}
-
-static int
-get_path_component(char *name, int n, const char *fn)
-{
- char *p;
- int l;
-
- p = strchr(fn, '/');
- if (p == NULL) {
- if ((l = strlen(fn)) == 0)
- return (0);
- } else
- l = p - fn;
- if (l > n -1)
- return (-1);
- memcpy(name, fn, l);
- name[l] = '\0';
-
- return (l);
-}
-
-/*
- * Add a new entry into the tree.
- */
-static int
-file_tree(struct archive_write *a, struct file **filepp)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- char name[_MAX_FNAME];/* Included null terminator size. */
-#elif defined(NAME_MAX) && NAME_MAX >= 255
- char name[NAME_MAX+1];
-#else
- char name[256];
-#endif
- struct xar *xar = (struct xar *)a->format_data;
- struct file *dent, *file, *np;
- struct archive_entry *ent;
- const char *fn, *p;
- int l;
-
- file = *filepp;
- dent = xar->root;
- if (file->parentdir.length > 0)
- fn = p = file->parentdir.s;
- else
- fn = p = "";
-
- /*
- * If the path of the parent directory of `file' entry is
- * the same as the path of `cur_dirent', add isoent to
- * `cur_dirent'.
- */
- if (archive_strlen(&(xar->cur_dirstr))
- == archive_strlen(&(file->parentdir)) &&
- strcmp(xar->cur_dirstr.s, fn) == 0) {
- if (!file_add_child_tail(xar->cur_dirent, file)) {
- np = (struct file *)__archive_rb_tree_find_node(
- &(xar->cur_dirent->rbtree),
- file->basename.s);
- goto same_entry;
- }
- return (ARCHIVE_OK);
- }
-
- for (;;) {
- l = get_path_component(name, sizeof(name), fn);
- if (l == 0) {
- np = NULL;
- break;
- }
- if (l < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "A name buffer is too small");
- file_free(file);
- *filepp = NULL;
- return (ARCHIVE_FATAL);
- }
-
- np = file_find_child(dent, name);
- if (np == NULL || fn[0] == '\0')
- break;
-
- /* Find next subdirectory. */
- if (!np->dir) {
- /* NOT Directory! */
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "`%s' is not directory, we cannot insert `%s' ",
- archive_entry_pathname(np->entry),
- archive_entry_pathname(file->entry));
- file_free(file);
- *filepp = NULL;
- return (ARCHIVE_FAILED);
- }
- fn += l;
- if (fn[0] == '/')
- fn++;
- dent = np;
- }
- if (np == NULL) {
- /*
- * Create virtual parent directories.
- */
- while (fn[0] != '\0') {
- struct file *vp;
- struct archive_string as;
-
- archive_string_init(&as);
- archive_strncat(&as, p, fn - p + l);
- if (as.s[as.length-1] == '/') {
- as.s[as.length-1] = '\0';
- as.length--;
- }
- vp = file_create_virtual_dir(a, xar, as.s);
- if (vp == NULL) {
- archive_string_free(&as);
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- file_free(file);
- *filepp = NULL;
- return (ARCHIVE_FATAL);
- }
- archive_string_free(&as);
- if (file_gen_utility_names(a, vp) <= ARCHIVE_FAILED)
- return (ARCHIVE_FATAL);
- file_add_child_tail(dent, vp);
- file_register(xar, vp);
- np = vp;
-
- fn += l;
- if (fn[0] == '/')
- fn++;
- l = get_path_component(name, sizeof(name), fn);
- if (l < 0) {
- archive_string_free(&as);
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "A name buffer is too small");
- file_free(file);
- *filepp = NULL;
- return (ARCHIVE_FATAL);
- }
- dent = np;
- }
-
- /* Found out the parent directory where isoent can be
- * inserted. */
- xar->cur_dirent = dent;
- archive_string_empty(&(xar->cur_dirstr));
- archive_string_ensure(&(xar->cur_dirstr),
- archive_strlen(&(dent->parentdir)) +
- archive_strlen(&(dent->basename)) + 2);
- if (archive_strlen(&(dent->parentdir)) +
- archive_strlen(&(dent->basename)) == 0)
- xar->cur_dirstr.s[0] = 0;
- else {
- if (archive_strlen(&(dent->parentdir)) > 0) {
- archive_string_copy(&(xar->cur_dirstr),
- &(dent->parentdir));
- archive_strappend_char(&(xar->cur_dirstr), '/');
- }
- archive_string_concat(&(xar->cur_dirstr),
- &(dent->basename));
- }
-
- if (!file_add_child_tail(dent, file)) {
- np = (struct file *)__archive_rb_tree_find_node(
- &(dent->rbtree), file->basename.s);
- goto same_entry;
- }
- return (ARCHIVE_OK);
- }
-
-same_entry:
- /*
- * We have already has the entry the filename of which is
- * the same.
- */
- if (archive_entry_filetype(np->entry) !=
- archive_entry_filetype(file->entry)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Found duplicate entries `%s' and its file type is "
- "different",
- archive_entry_pathname(np->entry));
- file_free(file);
- *filepp = NULL;
- return (ARCHIVE_FAILED);
- }
-
- /* Swap files. */
- ent = np->entry;
- np->entry = file->entry;
- file->entry = ent;
- np->virtual = 0;
-
- file_free(file);
- *filepp = np;
- return (ARCHIVE_OK);
-}
-
-static void
-file_register(struct xar *xar, struct file *file)
-{
- file->id = xar->file_idx++;
- file->next = NULL;
- *xar->file_list.last = file;
- xar->file_list.last = &(file->next);
-}
-
-static void
-file_init_register(struct xar *xar)
-{
- xar->file_list.first = NULL;
- xar->file_list.last = &(xar->file_list.first);
-}
-
-static void
-file_free_register(struct xar *xar)
-{
- struct file *file, *file_next;
-
- file = xar->file_list.first;
- while (file != NULL) {
- file_next = file->next;
- file_free(file);
- file = file_next;
- }
-}
-
-/*
- * Register entry to get a hardlink target.
- */
-static int
-file_register_hardlink(struct archive_write *a, struct file *file)
-{
- struct xar *xar = (struct xar *)a->format_data;
- struct hardlink *hl;
- const char *pathname;
-
- archive_entry_set_nlink(file->entry, 1);
- pathname = archive_entry_hardlink(file->entry);
- if (pathname == NULL) {
- /* This `file` is a hardlink target. */
- hl = malloc(sizeof(*hl));
- if (hl == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory");
- return (ARCHIVE_FATAL);
- }
- hl->nlink = 1;
- /* A hardlink target must be the first position. */
- file->hlnext = NULL;
- hl->file_list.first = file;
- hl->file_list.last = &(file->hlnext);
- __archive_rb_tree_insert_node(&(xar->hardlink_rbtree),
- (struct archive_rb_node *)hl);
- } else {
- hl = (struct hardlink *)__archive_rb_tree_find_node(
- &(xar->hardlink_rbtree), pathname);
- if (hl != NULL) {
- /* Insert `file` entry into the tail. */
- file->hlnext = NULL;
- *hl->file_list.last = file;
- hl->file_list.last = &(file->hlnext);
- hl->nlink++;
- }
- archive_entry_unset_size(file->entry);
- }
-
- return (ARCHIVE_OK);
-}
-
-/*
- * Hardlinked files have to have the same location of extent.
- * We have to find out hardlink target entries for entries which
- * have a hardlink target name.
- */
-static void
-file_connect_hardlink_files(struct xar *xar)
-{
- struct archive_rb_node *n;
- struct hardlink *hl;
- struct file *target, *nf;
-
- ARCHIVE_RB_TREE_FOREACH(n, &(xar->hardlink_rbtree)) {
- hl = (struct hardlink *)n;
-
- /* The first entry must be a hardlink target. */
- target = hl->file_list.first;
- archive_entry_set_nlink(target->entry, hl->nlink);
- if (hl->nlink > 1)
- /* It means this file is a hardlink
- * target itself. */
- target->hardlink_target = target;
- for (nf = target->hlnext;
- nf != NULL; nf = nf->hlnext) {
- nf->hardlink_target = target;
- archive_entry_set_nlink(nf->entry, hl->nlink);
- }
- }
-}
-
-static int
-file_hd_cmp_node(const struct archive_rb_node *n1,
- const struct archive_rb_node *n2)
-{
- const struct hardlink *h1 = (const struct hardlink *)n1;
- const struct hardlink *h2 = (const struct hardlink *)n2;
-
- return (strcmp(archive_entry_pathname(h1->file_list.first->entry),
- archive_entry_pathname(h2->file_list.first->entry)));
-}
-
-static int
-file_hd_cmp_key(const struct archive_rb_node *n, const void *key)
-{
- const struct hardlink *h = (const struct hardlink *)n;
-
- return (strcmp(archive_entry_pathname(h->file_list.first->entry),
- (const char *)key));
-}
-
-
-static void
-file_init_hardlinks(struct xar *xar)
-{
- static const struct archive_rb_tree_ops rb_ops = {
- file_hd_cmp_node, file_hd_cmp_key,
- };
-
- __archive_rb_tree_init(&(xar->hardlink_rbtree), &rb_ops);
-}
-
-static void
-file_free_hardlinks(struct xar *xar)
-{
- struct archive_rb_node *n, *tmp;
-
- ARCHIVE_RB_TREE_FOREACH_SAFE(n, &(xar->hardlink_rbtree), tmp) {
- __archive_rb_tree_remove_node(&(xar->hardlink_rbtree), n);
- free(n);
- }
-}
-
-static void
-checksum_init(struct chksumwork *sumwrk, enum sumalg sum_alg)
-{
- sumwrk->alg = sum_alg;
- switch (sum_alg) {
- case CKSUM_NONE:
- break;
- case CKSUM_SHA1:
- archive_sha1_init(&(sumwrk->sha1ctx));
- break;
- case CKSUM_MD5:
- archive_md5_init(&(sumwrk->md5ctx));
- break;
- }
-}
-
-static void
-checksum_update(struct chksumwork *sumwrk, const void *buff, size_t size)
-{
-
- switch (sumwrk->alg) {
- case CKSUM_NONE:
- break;
- case CKSUM_SHA1:
- archive_sha1_update(&(sumwrk->sha1ctx), buff, size);
- break;
- case CKSUM_MD5:
- archive_md5_update(&(sumwrk->md5ctx), buff, size);
- break;
- }
-}
-
-static void
-checksum_final(struct chksumwork *sumwrk, struct chksumval *sumval)
-{
-
- switch (sumwrk->alg) {
- case CKSUM_NONE:
- sumval->len = 0;
- break;
- case CKSUM_SHA1:
- archive_sha1_final(&(sumwrk->sha1ctx), sumval->val);
- sumval->len = SHA1_SIZE;
- break;
- case CKSUM_MD5:
- archive_md5_final(&(sumwrk->md5ctx), sumval->val);
- sumval->len = MD5_SIZE;
- break;
- }
- sumval->alg = sumwrk->alg;
-}
-
-#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR) || !defined(HAVE_LZMA_H)
-static int
-compression_unsupported_encoder(struct archive *a,
- struct la_zstream *lastrm, const char *name)
-{
-
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "%s compression not supported on this platform", name);
- lastrm->valid = 0;
- lastrm->real_stream = NULL;
- return (ARCHIVE_FAILED);
-}
-#endif
-
-static int
-compression_init_encoder_gzip(struct archive *a,
- struct la_zstream *lastrm, int level, int withheader)
-{
- z_stream *strm;
-
- if (lastrm->valid)
- compression_end(a, lastrm);
- strm = calloc(1, sizeof(*strm));
- if (strm == NULL) {
- archive_set_error(a, ENOMEM,
- "Can't allocate memory for gzip stream");
- return (ARCHIVE_FATAL);
- }
- /* zlib.h is not const-correct, so we need this one bit
- * of ugly hackery to convert a const * pointer to
- * a non-const pointer. */
- strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
- strm->avail_in = lastrm->avail_in;
- strm->total_in = (uLong)lastrm->total_in;
- strm->next_out = lastrm->next_out;
- strm->avail_out = lastrm->avail_out;
- strm->total_out = (uLong)lastrm->total_out;
- if (deflateInit2(strm, level, Z_DEFLATED,
- (withheader)?15:-15,
- 8, Z_DEFAULT_STRATEGY) != Z_OK) {
- free(strm);
- lastrm->real_stream = NULL;
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library");
- return (ARCHIVE_FATAL);
- }
- lastrm->real_stream = strm;
- lastrm->valid = 1;
- lastrm->code = compression_code_gzip;
- lastrm->end = compression_end_gzip;
- return (ARCHIVE_OK);
-}
-
-static int
-compression_code_gzip(struct archive *a,
- struct la_zstream *lastrm, enum la_zaction action)
-{
- z_stream *strm;
- int r;
-
- strm = (z_stream *)lastrm->real_stream;
- /* zlib.h is not const-correct, so we need this one bit
- * of ugly hackery to convert a const * pointer to
- * a non-const pointer. */
- strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
- strm->avail_in = lastrm->avail_in;
- strm->total_in = (uLong)lastrm->total_in;
- strm->next_out = lastrm->next_out;
- strm->avail_out = lastrm->avail_out;
- strm->total_out = (uLong)lastrm->total_out;
- r = deflate(strm,
- (action == ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH);
- lastrm->next_in = strm->next_in;
- lastrm->avail_in = strm->avail_in;
- lastrm->total_in = strm->total_in;
- lastrm->next_out = strm->next_out;
- lastrm->avail_out = strm->avail_out;
- lastrm->total_out = strm->total_out;
- switch (r) {
- case Z_OK:
- return (ARCHIVE_OK);
- case Z_STREAM_END:
- return (ARCHIVE_EOF);
- default:
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "GZip compression failed:"
- " deflate() call returned status %d", r);
- return (ARCHIVE_FATAL);
- }
-}
-
-static int
-compression_end_gzip(struct archive *a, struct la_zstream *lastrm)
-{
- z_stream *strm;
- int r;
-
- strm = (z_stream *)lastrm->real_stream;
- r = deflateEnd(strm);
- free(strm);
- lastrm->real_stream = NULL;
- lastrm->valid = 0;
- if (r != Z_OK) {
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Failed to clean up compressor");
- return (ARCHIVE_FATAL);
- }
- return (ARCHIVE_OK);
-}
-
-#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
-static int
-compression_init_encoder_bzip2(struct archive *a,
- struct la_zstream *lastrm, int level)
-{
- bz_stream *strm;
-
- if (lastrm->valid)
- compression_end(a, lastrm);
- strm = calloc(1, sizeof(*strm));
- if (strm == NULL) {
- archive_set_error(a, ENOMEM,
- "Can't allocate memory for bzip2 stream");
- return (ARCHIVE_FATAL);
- }
- /* bzlib.h is not const-correct, so we need this one bit
- * of ugly hackery to convert a const * pointer to
- * a non-const pointer. */
- strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
- strm->avail_in = lastrm->avail_in;
- strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
- strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
- strm->next_out = (char *)lastrm->next_out;
- strm->avail_out = lastrm->avail_out;
- strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
- strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
- if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) {
- free(strm);
- lastrm->real_stream = NULL;
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library");
- return (ARCHIVE_FATAL);
- }
- lastrm->real_stream = strm;
- lastrm->valid = 1;
- lastrm->code = compression_code_bzip2;
- lastrm->end = compression_end_bzip2;
- return (ARCHIVE_OK);
-}
-
-static int
-compression_code_bzip2(struct archive *a,
- struct la_zstream *lastrm, enum la_zaction action)
-{
- bz_stream *strm;
- int r;
-
- strm = (bz_stream *)lastrm->real_stream;
- /* bzlib.h is not const-correct, so we need this one bit
- * of ugly hackery to convert a const * pointer to
- * a non-const pointer. */
- strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
- strm->avail_in = lastrm->avail_in;
- strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
- strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
- strm->next_out = (char *)lastrm->next_out;
- strm->avail_out = lastrm->avail_out;
- strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
- strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
- r = BZ2_bzCompress(strm,
- (action == ARCHIVE_Z_FINISH)? BZ_FINISH: BZ_RUN);
- lastrm->next_in = (const unsigned char *)strm->next_in;
- lastrm->avail_in = strm->avail_in;
- lastrm->total_in =
- (((uint64_t)(uint32_t)strm->total_in_hi32) << 32)
- + (uint64_t)(uint32_t)strm->total_in_lo32;
- lastrm->next_out = (unsigned char *)strm->next_out;
- lastrm->avail_out = strm->avail_out;
- lastrm->total_out =
- (((uint64_t)(uint32_t)strm->total_out_hi32) << 32)
- + (uint64_t)(uint32_t)strm->total_out_lo32;
- switch (r) {
- case BZ_RUN_OK: /* Non-finishing */
- case BZ_FINISH_OK: /* Finishing: There's more work to do */
- return (ARCHIVE_OK);
- case BZ_STREAM_END: /* Finishing: all done */
- /* Only occurs in finishing case */
- return (ARCHIVE_EOF);
- default:
- /* Any other return value indicates an error */
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Bzip2 compression failed:"
- " BZ2_bzCompress() call returned status %d", r);
- return (ARCHIVE_FATAL);
- }
-}
-
-static int
-compression_end_bzip2(struct archive *a, struct la_zstream *lastrm)
-{
- bz_stream *strm;
- int r;
-
- strm = (bz_stream *)lastrm->real_stream;
- r = BZ2_bzCompressEnd(strm);
- free(strm);
- lastrm->real_stream = NULL;
- lastrm->valid = 0;
- if (r != BZ_OK) {
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Failed to clean up compressor");
- return (ARCHIVE_FATAL);
- }
- return (ARCHIVE_OK);
-}
-
-#else
-static int
-compression_init_encoder_bzip2(struct archive *a,
- struct la_zstream *lastrm, int level)
-{
-
- (void) level; /* UNUSED */
- if (lastrm->valid)
- compression_end(a, lastrm);
- return (compression_unsupported_encoder(a, lastrm, "bzip2"));
-}
-#endif
-
-#if defined(HAVE_LZMA_H)
-static int
-compression_init_encoder_lzma(struct archive *a,
- struct la_zstream *lastrm, int level)
-{
- static const lzma_stream lzma_init_data = LZMA_STREAM_INIT;
- lzma_stream *strm;
- lzma_options_lzma lzma_opt;
- int r;
-
- if (lastrm->valid)
- compression_end(a, lastrm);
- if (lzma_lzma_preset(&lzma_opt, level)) {
- lastrm->real_stream = NULL;
- archive_set_error(a, ENOMEM,
- "Internal error initializing compression library");
- return (ARCHIVE_FATAL);
- }
- strm = calloc(1, sizeof(*strm));
- if (strm == NULL) {
- archive_set_error(a, ENOMEM,
- "Can't allocate memory for lzma stream");
- return (ARCHIVE_FATAL);
- }
- *strm = lzma_init_data;
- r = lzma_alone_encoder(strm, &lzma_opt);
- switch (r) {
- case LZMA_OK:
- lastrm->real_stream = strm;
- lastrm->valid = 1;
- lastrm->code = compression_code_lzma;
- lastrm->end = compression_end_lzma;
- r = ARCHIVE_OK;
- break;
- case LZMA_MEM_ERROR:
- free(strm);
- lastrm->real_stream = NULL;
- archive_set_error(a, ENOMEM,
- "Internal error initializing compression library: "
- "Cannot allocate memory");
- r = ARCHIVE_FATAL;
- break;
- default:
- free(strm);
- lastrm->real_stream = NULL;
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library: "
- "It's a bug in liblzma");
- r = ARCHIVE_FATAL;
- break;
- }
- return (r);
-}
-
-static int
-compression_init_encoder_xz(struct archive *a,
- struct la_zstream *lastrm, int level, int threads)
-{
- static const lzma_stream lzma_init_data = LZMA_STREAM_INIT;
- lzma_stream *strm;
- lzma_filter *lzmafilters;
- lzma_options_lzma lzma_opt;
- int r;
-#ifdef HAVE_LZMA_STREAM_ENCODER_MT
- lzma_mt mt_options;
-#endif
-
- (void)threads; /* UNUSED (if multi-threaded LZMA library not avail) */
-
- if (lastrm->valid)
- compression_end(a, lastrm);
- strm = calloc(1, sizeof(*strm) + sizeof(*lzmafilters) * 2);
- if (strm == NULL) {
- archive_set_error(a, ENOMEM,
- "Can't allocate memory for xz stream");
- return (ARCHIVE_FATAL);
- }
- lzmafilters = (lzma_filter *)(strm+1);
- if (level > 9)
- level = 9;
- if (lzma_lzma_preset(&lzma_opt, level)) {
- free(strm);
- lastrm->real_stream = NULL;
- archive_set_error(a, ENOMEM,
- "Internal error initializing compression library");
- return (ARCHIVE_FATAL);
- }
- lzmafilters[0].id = LZMA_FILTER_LZMA2;
- lzmafilters[0].options = &lzma_opt;
- lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */
-
- *strm = lzma_init_data;
-#ifdef HAVE_LZMA_STREAM_ENCODER_MT
- if (threads > 1) {
- memset(&mt_options, 0, sizeof(mt_options));
- mt_options.threads = threads;
- mt_options.timeout = 300;
- mt_options.filters = lzmafilters;
- mt_options.check = LZMA_CHECK_CRC64;
- r = lzma_stream_encoder_mt(strm, &mt_options);
- } else
-#endif
- r = lzma_stream_encoder(strm, lzmafilters, LZMA_CHECK_CRC64);
- switch (r) {
- case LZMA_OK:
- lastrm->real_stream = strm;
- lastrm->valid = 1;
- lastrm->code = compression_code_lzma;
- lastrm->end = compression_end_lzma;
- r = ARCHIVE_OK;
- break;
- case LZMA_MEM_ERROR:
- free(strm);
- lastrm->real_stream = NULL;
- archive_set_error(a, ENOMEM,
- "Internal error initializing compression library: "
- "Cannot allocate memory");
- r = ARCHIVE_FATAL;
- break;
- default:
- free(strm);
- lastrm->real_stream = NULL;
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library: "
- "It's a bug in liblzma");
- r = ARCHIVE_FATAL;
- break;
- }
- return (r);
-}
-
-static int
-compression_code_lzma(struct archive *a,
- struct la_zstream *lastrm, enum la_zaction action)
-{
- lzma_stream *strm;
- int r;
-
- strm = (lzma_stream *)lastrm->real_stream;
- strm->next_in = lastrm->next_in;
- strm->avail_in = lastrm->avail_in;
- strm->total_in = lastrm->total_in;
- strm->next_out = lastrm->next_out;
- strm->avail_out = lastrm->avail_out;
- strm->total_out = lastrm->total_out;
- r = lzma_code(strm,
- (action == ARCHIVE_Z_FINISH)? LZMA_FINISH: LZMA_RUN);
- lastrm->next_in = strm->next_in;
- lastrm->avail_in = strm->avail_in;
- lastrm->total_in = strm->total_in;
- lastrm->next_out = strm->next_out;
- lastrm->avail_out = strm->avail_out;
- lastrm->total_out = strm->total_out;
- switch (r) {
- case LZMA_OK:
- /* Non-finishing case */
- return (ARCHIVE_OK);
- case LZMA_STREAM_END:
- /* This return can only occur in finishing case. */
- return (ARCHIVE_EOF);
- case LZMA_MEMLIMIT_ERROR:
- archive_set_error(a, ENOMEM,
- "lzma compression error:"
- " %ju MiB would have been needed",
- (uintmax_t)((lzma_memusage(strm) + 1024 * 1024 -1)
- / (1024 * 1024)));
- return (ARCHIVE_FATAL);
- default:
- /* Any other return value indicates an error */
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "lzma compression failed:"
- " lzma_code() call returned status %d", r);
- return (ARCHIVE_FATAL);
- }
-}
-
-static int
-compression_end_lzma(struct archive *a, struct la_zstream *lastrm)
-{
- lzma_stream *strm;
-
- (void)a; /* UNUSED */
- strm = (lzma_stream *)lastrm->real_stream;
- lzma_end(strm);
- free(strm);
- lastrm->valid = 0;
- lastrm->real_stream = NULL;
- return (ARCHIVE_OK);
-}
-#else
-static int
-compression_init_encoder_lzma(struct archive *a,
- struct la_zstream *lastrm, int level)
-{
-
- (void) level; /* UNUSED */
- if (lastrm->valid)
- compression_end(a, lastrm);
- return (compression_unsupported_encoder(a, lastrm, "lzma"));
-}
-static int
-compression_init_encoder_xz(struct archive *a,
- struct la_zstream *lastrm, int level, int threads)
-{
-
- (void) level; /* UNUSED */
- (void) threads; /* UNUSED */
- if (lastrm->valid)
- compression_end(a, lastrm);
- return (compression_unsupported_encoder(a, lastrm, "xz"));
-}
-#endif
-
-static int
-xar_compression_init_encoder(struct archive_write *a)
-{
- struct xar *xar;
- int r;
-
- xar = (struct xar *)a->format_data;
- switch (xar->opt_compression) {
- case GZIP:
- r = compression_init_encoder_gzip(
- &(a->archive), &(xar->stream),
- xar->opt_compression_level, 1);
- break;
- case BZIP2:
- r = compression_init_encoder_bzip2(
- &(a->archive), &(xar->stream),
- xar->opt_compression_level);
- break;
- case LZMA:
- r = compression_init_encoder_lzma(
- &(a->archive), &(xar->stream),
- xar->opt_compression_level);
- break;
- case XZ:
- r = compression_init_encoder_xz(
- &(a->archive), &(xar->stream),
- xar->opt_compression_level, xar->opt_threads);
- break;
- default:
- r = ARCHIVE_OK;
- break;
- }
- if (r == ARCHIVE_OK) {
- xar->stream.total_in = 0;
- xar->stream.next_out = xar->wbuff;
- xar->stream.avail_out = sizeof(xar->wbuff);
- xar->stream.total_out = 0;
- }
-
- return (r);
-}
-
-static int
-compression_code(struct archive *a, struct la_zstream *lastrm,
- enum la_zaction action)
-{
- if (lastrm->valid)
- return (lastrm->code(a, lastrm, action));
- return (ARCHIVE_OK);
-}
-
-static int
-compression_end(struct archive *a, struct la_zstream *lastrm)
-{
- if (lastrm->valid)
- return (lastrm->end(a, lastrm));
- return (ARCHIVE_OK);
-}
-
-
-static int
-save_xattrs(struct archive_write *a, struct file *file)
-{
- struct xar *xar;
- const char *name;
- const void *value;
- struct heap_data *heap;
- size_t size;
- int count, r;
-
- xar = (struct xar *)a->format_data;
- count = archive_entry_xattr_reset(file->entry);
- if (count == 0)
- return (ARCHIVE_OK);
- while (count--) {
- archive_entry_xattr_next(file->entry,
- &name, &value, &size);
- checksum_init(&(xar->a_sumwrk), xar->opt_sumalg);
- checksum_init(&(xar->e_sumwrk), xar->opt_sumalg);
-
- heap = calloc(1, sizeof(*heap));
- if (heap == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for xattr");
- return (ARCHIVE_FATAL);
- }
- heap->id = file->ea_idx++;
- heap->temp_offset = xar->temp_offset;
- heap->size = size;/* save a extracted size */
- heap->compression = xar->opt_compression;
- /* Get a extracted sumcheck value. */
- checksum_update(&(xar->e_sumwrk), value, size);
- checksum_final(&(xar->e_sumwrk), &(heap->e_sum));
-
- /*
- * Not compression to xattr is simple way.
- */
- if (heap->compression == NONE) {
- checksum_update(&(xar->a_sumwrk), value, size);
- checksum_final(&(xar->a_sumwrk), &(heap->a_sum));
- if (write_to_temp(a, value, size)
- != ARCHIVE_OK) {
- free(heap);
- return (ARCHIVE_FATAL);
- }
- heap->length = size;
- /* Add heap to the tail of file->xattr. */
- heap->next = NULL;
- *file->xattr.last = heap;
- file->xattr.last = &(heap->next);
- /* Next xattr */
- continue;
- }
-
- /*
- * Init compression library.
- */
- r = xar_compression_init_encoder(a);
- if (r != ARCHIVE_OK) {
- free(heap);
- return (ARCHIVE_FATAL);
- }
-
- xar->stream.next_in = (const unsigned char *)value;
- xar->stream.avail_in = size;
- for (;;) {
- r = compression_code(&(a->archive),
- &(xar->stream), ARCHIVE_Z_FINISH);
- if (r != ARCHIVE_OK && r != ARCHIVE_EOF) {
- free(heap);
- return (ARCHIVE_FATAL);
- }
- size = sizeof(xar->wbuff) - xar->stream.avail_out;
- checksum_update(&(xar->a_sumwrk),
- xar->wbuff, size);
- if (write_to_temp(a, xar->wbuff, size)
- != ARCHIVE_OK) {
- free(heap);
- return (ARCHIVE_FATAL);
- }
- if (r == ARCHIVE_OK) {
- xar->stream.next_out = xar->wbuff;
- xar->stream.avail_out = sizeof(xar->wbuff);
- } else {
- checksum_final(&(xar->a_sumwrk),
- &(heap->a_sum));
- heap->length = xar->stream.total_out;
- /* Add heap to the tail of file->xattr. */
- heap->next = NULL;
- *file->xattr.last = heap;
- file->xattr.last = &(heap->next);
- break;
- }
- }
- /* Clean up compression library. */
- r = compression_end(&(a->archive), &(xar->stream));
- if (r != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- }
- return (ARCHIVE_OK);
-}
-
-static int
-getalgsize(enum sumalg sumalg)
-{
- switch (sumalg) {
- default:
- case CKSUM_NONE:
- return (0);
- case CKSUM_SHA1:
- return (SHA1_SIZE);
- case CKSUM_MD5:
- return (MD5_SIZE);
- }
-}
-
-static const char *
-getalgname(enum sumalg sumalg)
-{
- switch (sumalg) {
- default:
- case CKSUM_NONE:
- return (NULL);
- case CKSUM_SHA1:
- return (SHA1_NAME);
- case CKSUM_MD5:
- return (MD5_NAME);
- }
-}
-
-#endif /* Support xar format */
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_format_zip.c b/contrib/libs/libarchive/libarchive/archive_write_set_format_zip.c
deleted file mode 100644
index 5ac7e03d38..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_format_zip.c
+++ /dev/null
@@ -1,1693 +0,0 @@
-/*-
- * Copyright (c) 2008 Anselm Strauss
- * Copyright (c) 2009 Joerg Sonnenberger
- * Copyright (c) 2011-2012,2014 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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.
- */
-
-/*
- * Development supported by Google Summer of Code 2008.
- */
-
-#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_zip.c 201168 2009-12-29 06:15:32Z kientzle $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_LANGINFO_H
-#include <langinfo.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-
-#include "archive.h"
-#include "archive_cryptor_private.h"
-#include "archive_endian.h"
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_hmac_private.h"
-#include "archive_private.h"
-#include "archive_random_private.h"
-#include "archive_write_private.h"
-#include "archive_write_set_format_private.h"
-
-#ifndef HAVE_ZLIB_H
-#error #include "archive_crc32.h"
-#endif
-
-#define ZIP_ENTRY_FLAG_ENCRYPTED (1<<0)
-#define ZIP_ENTRY_FLAG_LENGTH_AT_END (1<<3)
-#define ZIP_ENTRY_FLAG_UTF8_NAME (1 << 11)
-
-#define ZIP_4GB_MAX ARCHIVE_LITERAL_LL(0xffffffff)
-#define ZIP_4GB_MAX_UNCOMPRESSED ARCHIVE_LITERAL_LL(0xff000000)
-
-enum compression {
- COMPRESSION_UNSPECIFIED = -1,
- COMPRESSION_STORE = 0,
- COMPRESSION_DEFLATE = 8
-};
-
-#ifdef HAVE_ZLIB_H
-#define COMPRESSION_DEFAULT COMPRESSION_DEFLATE
-#else
-#define COMPRESSION_DEFAULT COMPRESSION_STORE
-#endif
-
-enum encryption {
- ENCRYPTION_NONE = 0,
- ENCRYPTION_TRADITIONAL, /* Traditional PKWARE encryption. */
- ENCRYPTION_WINZIP_AES128, /* WinZIP AES-128 encryption. */
- ENCRYPTION_WINZIP_AES256, /* WinZIP AES-256 encryption. */
-};
-
-#define TRAD_HEADER_SIZE 12
-/*
- * See "WinZip - AES Encryption Information"
- * http://www.winzip.com/aes_info.htm
- */
-/* Value used in compression method. */
-#define WINZIP_AES_ENCRYPTION 99
-/* A WinZip AES header size which is stored at the beginning of
- * file contents. */
-#define WINZIP_AES128_HEADER_SIZE (8 + 2)
-#define WINZIP_AES256_HEADER_SIZE (16 + 2)
-/* AES vendor version. */
-#define AES_VENDOR_AE_1 0x0001
-#define AES_VENDOR_AE_2 0x0002
-/* Authentication code size. */
-#define AUTH_CODE_SIZE 10
-/**/
-#define MAX_DERIVED_KEY_BUF_SIZE (AES_MAX_KEY_SIZE * 2 + 2)
-
-struct cd_segment {
- struct cd_segment *next;
- size_t buff_size;
- unsigned char *buff;
- unsigned char *p;
-};
-
-struct trad_enc_ctx {
- uint32_t keys[3];
-};
-
-struct zip {
-
- int64_t entry_offset;
- int64_t entry_compressed_size;
- int64_t entry_uncompressed_size;
- int64_t entry_compressed_written;
- int64_t entry_uncompressed_written;
- int64_t entry_uncompressed_limit;
- struct archive_entry *entry;
- uint32_t entry_crc32;
- enum compression entry_compression;
- enum encryption entry_encryption;
- int entry_flags;
- int entry_uses_zip64;
- int experiments;
- struct trad_enc_ctx tctx;
- char tctx_valid;
- unsigned char trad_chkdat;
- unsigned aes_vendor;
- archive_crypto_ctx cctx;
- char cctx_valid;
- archive_hmac_sha1_ctx hctx;
- char hctx_valid;
-
- unsigned char *file_header;
- size_t file_header_extra_offset;
- unsigned long (*crc32func)(unsigned long crc, const void *buff, size_t len);
-
- struct cd_segment *central_directory;
- struct cd_segment *central_directory_last;
- size_t central_directory_bytes;
- size_t central_directory_entries;
-
- int64_t written_bytes; /* Overall position in file. */
-
- struct archive_string_conv *opt_sconv;
- struct archive_string_conv *sconv_default;
- enum compression requested_compression;
- int deflate_compression_level;
- int init_default_conversion;
- enum encryption encryption_type;
-
-#define ZIP_FLAG_AVOID_ZIP64 1
-#define ZIP_FLAG_FORCE_ZIP64 2
-#define ZIP_FLAG_EXPERIMENT_xl 4
- int flags;
-
-#ifdef HAVE_ZLIB_H
- z_stream stream;
-#endif
- size_t len_buf;
- unsigned char *buf;
-};
-
-/* Don't call this min or MIN, since those are already defined
- on lots of platforms (but not all). */
-#define zipmin(a, b) ((a) > (b) ? (b) : (a))
-
-static ssize_t archive_write_zip_data(struct archive_write *,
- const void *buff, size_t s);
-static int archive_write_zip_close(struct archive_write *);
-static int archive_write_zip_free(struct archive_write *);
-static int archive_write_zip_finish_entry(struct archive_write *);
-static int archive_write_zip_header(struct archive_write *,
- struct archive_entry *);
-static int archive_write_zip_options(struct archive_write *,
- const char *, const char *);
-static unsigned int dos_time(const time_t);
-static size_t path_length(struct archive_entry *);
-static int write_path(struct archive_entry *, struct archive_write *);
-static void copy_path(struct archive_entry *, unsigned char *);
-static struct archive_string_conv *get_sconv(struct archive_write *, struct zip *);
-static int trad_enc_init(struct trad_enc_ctx *, const char *, size_t);
-static unsigned trad_enc_encrypt_update(struct trad_enc_ctx *, const uint8_t *,
- size_t, uint8_t *, size_t);
-static int init_traditional_pkware_encryption(struct archive_write *);
-static int is_traditional_pkware_encryption_supported(void);
-static int init_winzip_aes_encryption(struct archive_write *);
-static int is_winzip_aes_encryption_supported(int encryption);
-
-static unsigned char *
-cd_alloc(struct zip *zip, size_t length)
-{
- unsigned char *p;
-
- if (zip->central_directory == NULL
- || (zip->central_directory_last->p + length
- > zip->central_directory_last->buff + zip->central_directory_last->buff_size)) {
- struct cd_segment *segment = calloc(1, sizeof(*segment));
- if (segment == NULL)
- return NULL;
- segment->buff_size = 64 * 1024;
- segment->buff = malloc(segment->buff_size);
- if (segment->buff == NULL) {
- free(segment);
- return NULL;
- }
- segment->p = segment->buff;
-
- if (zip->central_directory == NULL) {
- zip->central_directory
- = zip->central_directory_last
- = segment;
- } else {
- zip->central_directory_last->next = segment;
- zip->central_directory_last = segment;
- }
- }
-
- p = zip->central_directory_last->p;
- zip->central_directory_last->p += length;
- zip->central_directory_bytes += length;
- return (p);
-}
-
-static unsigned long
-real_crc32(unsigned long crc, const void *buff, size_t len)
-{
- return crc32(crc, buff, (unsigned int)len);
-}
-
-static unsigned long
-fake_crc32(unsigned long crc, const void *buff, size_t len)
-{
- (void)crc; /* UNUSED */
- (void)buff; /* UNUSED */
- (void)len; /* UNUSED */
- return 0;
-}
-
-static int
-archive_write_zip_options(struct archive_write *a, const char *key,
- const char *val)
-{
- struct zip *zip = a->format_data;
- int ret = ARCHIVE_FAILED;
-
- if (strcmp(key, "compression") == 0) {
- /*
- * Set compression to use on all future entries.
- * This only affects regular files.
- */
- if (val == NULL || val[0] == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "%s: compression option needs a compression name",
- a->format_name);
- } else if (strcmp(val, "deflate") == 0) {
-#ifdef HAVE_ZLIB_H
- zip->requested_compression = COMPRESSION_DEFLATE;
- ret = ARCHIVE_OK;
-#else
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "deflate compression not supported");
-#endif
- } else if (strcmp(val, "store") == 0) {
- zip->requested_compression = COMPRESSION_STORE;
- ret = ARCHIVE_OK;
- }
- return (ret);
- } else if (strcmp(key, "compression-level") == 0) {
- if (val == NULL || !(val[0] >= '0' && val[0] <= '9') || val[1] != '\0') {
- return ARCHIVE_WARN;
- }
-
- if (val[0] == '0') {
- zip->requested_compression = COMPRESSION_STORE;
- return ARCHIVE_OK;
- } else {
-#ifdef HAVE_ZLIB_H
- zip->requested_compression = COMPRESSION_DEFLATE;
- zip->deflate_compression_level = val[0] - '0';
- return ARCHIVE_OK;
-#else
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "deflate compression not supported");
-#endif
- }
- } else if (strcmp(key, "encryption") == 0) {
- if (val == NULL) {
- zip->encryption_type = ENCRYPTION_NONE;
- ret = ARCHIVE_OK;
- } else if (val[0] == '1' || strcmp(val, "traditional") == 0
- || strcmp(val, "zipcrypt") == 0
- || strcmp(val, "ZipCrypt") == 0) {
- if (is_traditional_pkware_encryption_supported()) {
- zip->encryption_type = ENCRYPTION_TRADITIONAL;
- ret = ARCHIVE_OK;
- } else {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "encryption not supported");
- }
- } else if (strcmp(val, "aes128") == 0) {
- if (is_winzip_aes_encryption_supported(
- ENCRYPTION_WINZIP_AES128)) {
- zip->encryption_type = ENCRYPTION_WINZIP_AES128;
- ret = ARCHIVE_OK;
- } else {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "encryption not supported");
- }
- } else if (strcmp(val, "aes256") == 0) {
- if (is_winzip_aes_encryption_supported(
- ENCRYPTION_WINZIP_AES256)) {
- zip->encryption_type = ENCRYPTION_WINZIP_AES256;
- ret = ARCHIVE_OK;
- } else {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "encryption not supported");
- }
- } else {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "%s: unknown encryption '%s'",
- a->format_name, val);
- }
- return (ret);
- } else if (strcmp(key, "experimental") == 0) {
- if (val == NULL || val[0] == 0) {
- zip->flags &= ~ ZIP_FLAG_EXPERIMENT_xl;
- } else {
- zip->flags |= ZIP_FLAG_EXPERIMENT_xl;
- }
- return (ARCHIVE_OK);
- } else if (strcmp(key, "fakecrc32") == 0) {
- /*
- * FOR TESTING ONLY: disable CRC calculation to speed up
- * certain complex tests.
- */
- if (val == NULL || val[0] == 0) {
- zip->crc32func = real_crc32;
- } else {
- zip->crc32func = fake_crc32;
- }
- return (ARCHIVE_OK);
- } else if (strcmp(key, "hdrcharset") == 0) {
- /*
- * Set the character set used in translating filenames.
- */
- if (val == NULL || val[0] == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "%s: hdrcharset option needs a character-set name",
- a->format_name);
- } else {
- zip->opt_sconv = archive_string_conversion_to_charset(
- &a->archive, val, 0);
- if (zip->opt_sconv != NULL)
- ret = ARCHIVE_OK;
- else
- ret = ARCHIVE_FATAL;
- }
- return (ret);
- } else if (strcmp(key, "zip64") == 0) {
- /*
- * Bias decisions about Zip64: force them to be
- * generated in certain cases where they are not
- * forbidden or avoid them in certain cases where they
- * are not strictly required.
- */
- if (val != NULL && *val != '\0') {
- zip->flags |= ZIP_FLAG_FORCE_ZIP64;
- zip->flags &= ~ZIP_FLAG_AVOID_ZIP64;
- } else {
- zip->flags &= ~ZIP_FLAG_FORCE_ZIP64;
- zip->flags |= ZIP_FLAG_AVOID_ZIP64;
- }
- return (ARCHIVE_OK);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-int
-archive_write_zip_set_compression_deflate(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- int ret = ARCHIVE_FAILED;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW | ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
- "archive_write_zip_set_compression_deflate");
- if (a->archive.archive_format != ARCHIVE_FORMAT_ZIP) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Can only use archive_write_zip_set_compression_deflate"
- " with zip format");
- ret = ARCHIVE_FATAL;
- } else {
-#ifdef HAVE_ZLIB_H
- struct zip *zip = a->format_data;
- zip->requested_compression = COMPRESSION_DEFLATE;
- ret = ARCHIVE_OK;
-#else
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "deflate compression not supported");
- ret = ARCHIVE_FAILED;
-#endif
- }
- return (ret);
-}
-
-int
-archive_write_zip_set_compression_store(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct zip *zip = a->format_data;
- int ret = ARCHIVE_FAILED;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW | ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
- "archive_write_zip_set_compression_deflate");
- if (a->archive.archive_format != ARCHIVE_FORMAT_ZIP) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Can only use archive_write_zip_set_compression_store"
- " with zip format");
- ret = ARCHIVE_FATAL;
- } else {
- zip->requested_compression = COMPRESSION_STORE;
- ret = ARCHIVE_OK;
- }
- return (ret);
-}
-
-int
-archive_write_set_format_zip(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct zip *zip;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_format_zip");
-
- /* If another format was already registered, unregister it. */
- if (a->format_free != NULL)
- (a->format_free)(a);
-
- zip = (struct zip *) calloc(1, sizeof(*zip));
- if (zip == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate zip data");
- return (ARCHIVE_FATAL);
- }
-
- /* "Unspecified" lets us choose the appropriate compression. */
- zip->requested_compression = COMPRESSION_UNSPECIFIED;
-#ifdef HAVE_ZLIB_H
- zip->deflate_compression_level = Z_DEFAULT_COMPRESSION;
-#endif
- zip->crc32func = real_crc32;
-
- /* A buffer used for both compression and encryption. */
- zip->len_buf = 65536;
- zip->buf = malloc(zip->len_buf);
- if (zip->buf == NULL) {
- free(zip);
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate compression buffer");
- return (ARCHIVE_FATAL);
- }
-
- a->format_data = zip;
- a->format_name = "zip";
- a->format_options = archive_write_zip_options;
- a->format_write_header = archive_write_zip_header;
- a->format_write_data = archive_write_zip_data;
- a->format_finish_entry = archive_write_zip_finish_entry;
- a->format_close = archive_write_zip_close;
- a->format_free = archive_write_zip_free;
- a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
- a->archive.archive_format_name = "ZIP";
-
- return (ARCHIVE_OK);
-}
-
-static int
-is_all_ascii(const char *p)
-{
- const unsigned char *pp = (const unsigned char *)p;
-
- while (*pp) {
- if (*pp++ > 127)
- return (0);
- }
- return (1);
-}
-
-static int
-archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
-{
- unsigned char local_header[32];
- unsigned char local_extra[144];
- struct zip *zip = a->format_data;
- unsigned char *e;
- unsigned char *cd_extra;
- size_t filename_length;
- const char *slink = NULL;
- size_t slink_size = 0;
- struct archive_string_conv *sconv = get_sconv(a, zip);
- int ret, ret2 = ARCHIVE_OK;
- mode_t type;
- int version_needed = 10;
-
- /* Ignore types of entries that we don't support. */
- type = archive_entry_filetype(entry);
- if (type != AE_IFREG && type != AE_IFDIR && type != AE_IFLNK) {
- __archive_write_entry_filetype_unsupported(
- &a->archive, entry, "zip");
- return ARCHIVE_FAILED;
- };
-
- /* If we're not using Zip64, reject large files. */
- if (zip->flags & ZIP_FLAG_AVOID_ZIP64) {
- /* Reject entries over 4GB. */
- if (archive_entry_size_is_set(entry)
- && (archive_entry_size(entry) > ZIP_4GB_MAX)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Files > 4GB require Zip64 extensions");
- return ARCHIVE_FAILED;
- }
- /* Reject entries if archive is > 4GB. */
- if (zip->written_bytes > ZIP_4GB_MAX) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Archives > 4GB require Zip64 extensions");
- return ARCHIVE_FAILED;
- }
- }
-
- /* Only regular files can have size > 0. */
- if (type != AE_IFREG)
- archive_entry_set_size(entry, 0);
-
-
- /* Reset information from last entry. */
- zip->entry_offset = zip->written_bytes;
- zip->entry_uncompressed_limit = INT64_MAX;
- zip->entry_compressed_size = 0;
- zip->entry_uncompressed_size = 0;
- zip->entry_compressed_written = 0;
- zip->entry_uncompressed_written = 0;
- zip->entry_flags = 0;
- zip->entry_uses_zip64 = 0;
- zip->entry_crc32 = zip->crc32func(0, NULL, 0);
- zip->entry_encryption = 0;
- archive_entry_free(zip->entry);
- zip->entry = NULL;
-
- if (zip->cctx_valid)
- archive_encrypto_aes_ctr_release(&zip->cctx);
- if (zip->hctx_valid)
- archive_hmac_sha1_cleanup(&zip->hctx);
- zip->tctx_valid = zip->cctx_valid = zip->hctx_valid = 0;
-
- if (type == AE_IFREG
- &&(!archive_entry_size_is_set(entry)
- || archive_entry_size(entry) > 0)) {
- switch (zip->encryption_type) {
- case ENCRYPTION_TRADITIONAL:
- case ENCRYPTION_WINZIP_AES128:
- case ENCRYPTION_WINZIP_AES256:
- zip->entry_flags |= ZIP_ENTRY_FLAG_ENCRYPTED;
- zip->entry_encryption = zip->encryption_type;
- break;
- case ENCRYPTION_NONE:
- default:
- break;
- }
- }
-
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Make sure the path separators in pathname, hardlink and symlink
- * are all slash '/', not the Windows path separator '\'. */
- zip->entry = __la_win_entry_in_posix_pathseparator(entry);
- if (zip->entry == entry)
- zip->entry = archive_entry_clone(entry);
-#else
- zip->entry = archive_entry_clone(entry);
-#endif
- if (zip->entry == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate zip header data");
- return (ARCHIVE_FATAL);
- }
-
- if (sconv != NULL) {
- const char *p;
- size_t len;
-
- if (archive_entry_pathname_l(entry, &p, &len, sconv) != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate Pathname '%s' to %s",
- archive_entry_pathname(entry),
- archive_string_conversion_charset_name(sconv));
- ret2 = ARCHIVE_WARN;
- }
- if (len > 0)
- archive_entry_set_pathname(zip->entry, p);
-
- /*
- * There is no standard for symlink handling; we convert
- * it using the same character-set translation that we use
- * for filename.
- */
- if (type == AE_IFLNK) {
- if (archive_entry_symlink_l(entry, &p, &len, sconv)) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory "
- " for Symlink");
- return (ARCHIVE_FATAL);
- }
- /* No error if we can't convert. */
- } else if (len > 0)
- archive_entry_set_symlink(zip->entry, p);
- }
- }
-
- /* If filename isn't ASCII and we can use UTF-8, set the UTF-8 flag. */
- if (!is_all_ascii(archive_entry_pathname(zip->entry))) {
- if (zip->opt_sconv != NULL) {
- if (strcmp(archive_string_conversion_charset_name(
- zip->opt_sconv), "UTF-8") == 0)
- zip->entry_flags |= ZIP_ENTRY_FLAG_UTF8_NAME;
-#if HAVE_NL_LANGINFO
- } else if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0) {
- zip->entry_flags |= ZIP_ENTRY_FLAG_UTF8_NAME;
-#endif
- }
- }
- filename_length = path_length(zip->entry);
-
- /* Determine appropriate compression and size for this entry. */
- if (type == AE_IFLNK) {
- slink = archive_entry_symlink(zip->entry);
- if (slink != NULL)
- slink_size = strlen(slink);
- else
- slink_size = 0;
- zip->entry_uncompressed_limit = slink_size;
- zip->entry_compressed_size = slink_size;
- zip->entry_uncompressed_size = slink_size;
- zip->entry_crc32 = zip->crc32func(zip->entry_crc32,
- (const unsigned char *)slink, slink_size);
- zip->entry_compression = COMPRESSION_STORE;
- version_needed = 20;
- } else if (type != AE_IFREG) {
- zip->entry_compression = COMPRESSION_STORE;
- zip->entry_uncompressed_limit = 0;
- version_needed = 20;
- } else if (archive_entry_size_is_set(zip->entry)) {
- int64_t size = archive_entry_size(zip->entry);
- int64_t additional_size = 0;
-
- zip->entry_uncompressed_limit = size;
- zip->entry_compression = zip->requested_compression;
- if (zip->entry_compression == COMPRESSION_UNSPECIFIED) {
- zip->entry_compression = COMPRESSION_DEFAULT;
- }
- if (zip->entry_compression == COMPRESSION_STORE) {
- zip->entry_compressed_size = size;
- zip->entry_uncompressed_size = size;
- version_needed = 10;
- } else {
- zip->entry_uncompressed_size = size;
- version_needed = 20;
- }
-
- if (zip->entry_flags & ZIP_ENTRY_FLAG_ENCRYPTED) {
- switch (zip->entry_encryption) {
- case ENCRYPTION_TRADITIONAL:
- additional_size = TRAD_HEADER_SIZE;
- version_needed = 20;
- break;
- case ENCRYPTION_WINZIP_AES128:
- additional_size = WINZIP_AES128_HEADER_SIZE
- + AUTH_CODE_SIZE;
- version_needed = 20;
- break;
- case ENCRYPTION_WINZIP_AES256:
- additional_size = WINZIP_AES256_HEADER_SIZE
- + AUTH_CODE_SIZE;
- version_needed = 20;
- break;
- case ENCRYPTION_NONE:
- default:
- break;
- }
- if (zip->entry_compression == COMPRESSION_STORE)
- zip->entry_compressed_size += additional_size;
- }
-
- /*
- * Set Zip64 extension in any of the following cases
- * (this was suggested by discussion on info-zip-dev
- * mailing list):
- * = Zip64 is being forced by user
- * = File is over 4GiB uncompressed
- * (including encryption header, if any)
- * = File is close to 4GiB and is being compressed
- * (compression might make file larger)
- */
- if ((zip->flags & ZIP_FLAG_FORCE_ZIP64)
- || (zip->entry_uncompressed_size + additional_size > ZIP_4GB_MAX)
- || (zip->entry_uncompressed_size > ZIP_4GB_MAX_UNCOMPRESSED
- && zip->entry_compression != COMPRESSION_STORE)) {
- zip->entry_uses_zip64 = 1;
- version_needed = 45;
- }
-
- /* We may know the size, but never the CRC. */
- zip->entry_flags |= ZIP_ENTRY_FLAG_LENGTH_AT_END;
- } else {
- /* We don't know the size. Use the default
- * compression unless specified otherwise.
- * We enable Zip64 extensions unless we're told not to.
- */
-
- zip->entry_compression = zip->requested_compression;
- if(zip->entry_compression == COMPRESSION_UNSPECIFIED){
- zip->entry_compression = COMPRESSION_DEFAULT;
- }
-
- zip->entry_flags |= ZIP_ENTRY_FLAG_LENGTH_AT_END;
- if ((zip->flags & ZIP_FLAG_AVOID_ZIP64) == 0) {
- zip->entry_uses_zip64 = 1;
- version_needed = 45;
- } else if (zip->entry_compression == COMPRESSION_STORE) {
- version_needed = 10;
- } else {
- version_needed = 20;
- }
-
- if (zip->entry_flags & ZIP_ENTRY_FLAG_ENCRYPTED) {
- switch (zip->entry_encryption) {
- case ENCRYPTION_TRADITIONAL:
- case ENCRYPTION_WINZIP_AES128:
- case ENCRYPTION_WINZIP_AES256:
- if (version_needed < 20)
- version_needed = 20;
- break;
- case ENCRYPTION_NONE:
- default:
- break;
- }
- }
- }
-
- /* Format the local header. */
- memset(local_header, 0, sizeof(local_header));
- memcpy(local_header, "PK\003\004", 4);
- archive_le16enc(local_header + 4, version_needed);
- archive_le16enc(local_header + 6, zip->entry_flags);
- if (zip->entry_encryption == ENCRYPTION_WINZIP_AES128
- || zip->entry_encryption == ENCRYPTION_WINZIP_AES256)
- archive_le16enc(local_header + 8, WINZIP_AES_ENCRYPTION);
- else
- archive_le16enc(local_header + 8, zip->entry_compression);
- archive_le32enc(local_header + 10,
- dos_time(archive_entry_mtime(zip->entry)));
- archive_le32enc(local_header + 14, zip->entry_crc32);
- if (zip->entry_uses_zip64) {
- /* Zip64 data in the local header "must" include both
- * compressed and uncompressed sizes AND those fields
- * are included only if these are 0xffffffff;
- * THEREFORE these must be set this way, even if we
- * know one of them is smaller. */
- archive_le32enc(local_header + 18, ZIP_4GB_MAX);
- archive_le32enc(local_header + 22, ZIP_4GB_MAX);
- } else {
- archive_le32enc(local_header + 18, (uint32_t)zip->entry_compressed_size);
- archive_le32enc(local_header + 22, (uint32_t)zip->entry_uncompressed_size);
- }
- archive_le16enc(local_header + 26, (uint16_t)filename_length);
-
- if (zip->entry_encryption == ENCRYPTION_TRADITIONAL) {
- if (zip->entry_flags & ZIP_ENTRY_FLAG_LENGTH_AT_END)
- zip->trad_chkdat = local_header[11];
- else
- zip->trad_chkdat = local_header[17];
- }
-
- /* Format as much of central directory file header as we can: */
- zip->file_header = cd_alloc(zip, 46);
- /* If (zip->file_header == NULL) XXXX */
- ++zip->central_directory_entries;
- memset(zip->file_header, 0, 46);
- memcpy(zip->file_header, "PK\001\002", 4);
- /* "Made by PKZip 2.0 on Unix." */
- archive_le16enc(zip->file_header + 4, 3 * 256 + version_needed);
- archive_le16enc(zip->file_header + 6, version_needed);
- archive_le16enc(zip->file_header + 8, zip->entry_flags);
- if (zip->entry_encryption == ENCRYPTION_WINZIP_AES128
- || zip->entry_encryption == ENCRYPTION_WINZIP_AES256)
- archive_le16enc(zip->file_header + 10, WINZIP_AES_ENCRYPTION);
- else
- archive_le16enc(zip->file_header + 10, zip->entry_compression);
- archive_le32enc(zip->file_header + 12,
- dos_time(archive_entry_mtime(zip->entry)));
- archive_le16enc(zip->file_header + 28, (uint16_t)filename_length);
- /* Following Info-Zip, store mode in the "external attributes" field. */
- archive_le32enc(zip->file_header + 38,
- ((uint32_t)archive_entry_mode(zip->entry)) << 16);
- e = cd_alloc(zip, filename_length);
- /* If (e == NULL) XXXX */
- copy_path(zip->entry, e);
-
- /* Format extra data. */
- memset(local_extra, 0, sizeof(local_extra));
- e = local_extra;
-
- /* First, extra blocks that are the same between
- * the local file header and the central directory.
- * We format them once and then duplicate them. */
-
- /* UT timestamp, length depends on what timestamps are set. */
- memcpy(e, "UT", 2);
- archive_le16enc(e + 2,
- 1
- + (archive_entry_mtime_is_set(entry) ? 4 : 0)
- + (archive_entry_atime_is_set(entry) ? 4 : 0)
- + (archive_entry_ctime_is_set(entry) ? 4 : 0));
- e += 4;
- *e++ =
- (archive_entry_mtime_is_set(entry) ? 1 : 0)
- | (archive_entry_atime_is_set(entry) ? 2 : 0)
- | (archive_entry_ctime_is_set(entry) ? 4 : 0);
- if (archive_entry_mtime_is_set(entry)) {
- archive_le32enc(e, (uint32_t)archive_entry_mtime(entry));
- e += 4;
- }
- if (archive_entry_atime_is_set(entry)) {
- archive_le32enc(e, (uint32_t)archive_entry_atime(entry));
- e += 4;
- }
- if (archive_entry_ctime_is_set(entry)) {
- archive_le32enc(e, (uint32_t)archive_entry_ctime(entry));
- e += 4;
- }
-
- /* ux Unix extra data, length 11, version 1 */
- /* TODO: If uid < 64k, use 2 bytes, ditto for gid. */
- memcpy(e, "ux\013\000\001", 5);
- e += 5;
- *e++ = 4; /* Length of following UID */
- archive_le32enc(e, (uint32_t)archive_entry_uid(entry));
- e += 4;
- *e++ = 4; /* Length of following GID */
- archive_le32enc(e, (uint32_t)archive_entry_gid(entry));
- e += 4;
-
- /* AES extra data field: WinZIP AES information, ID=0x9901 */
- if ((zip->entry_flags & ZIP_ENTRY_FLAG_ENCRYPTED)
- && (zip->entry_encryption == ENCRYPTION_WINZIP_AES128
- || zip->entry_encryption == ENCRYPTION_WINZIP_AES256)) {
-
- memcpy(e, "\001\231\007\000\001\000AE", 8);
- /* AES vendor version AE-2 does not store a CRC.
- * WinZip 11 uses AE-1, which does store the CRC,
- * but it does not store the CRC when the file size
- * is less than 20 bytes. So we simulate what
- * WinZip 11 does.
- * NOTE: WinZip 9.0 and 10.0 uses AE-2 by default. */
- if (archive_entry_size_is_set(zip->entry)
- && archive_entry_size(zip->entry) < 20) {
- archive_le16enc(e+4, AES_VENDOR_AE_2);
- zip->aes_vendor = AES_VENDOR_AE_2;/* no CRC. */
- } else
- zip->aes_vendor = AES_VENDOR_AE_1;
- e += 8;
- /* AES encryption strength. */
- *e++ = (zip->entry_encryption == ENCRYPTION_WINZIP_AES128)?1:3;
- /* Actual compression method. */
- archive_le16enc(e, zip->entry_compression);
- e += 2;
- }
-
- /* Copy UT ,ux, and AES-extra into central directory as well. */
- zip->file_header_extra_offset = zip->central_directory_bytes;
- cd_extra = cd_alloc(zip, e - local_extra);
- memcpy(cd_extra, local_extra, e - local_extra);
-
- /*
- * Following extra blocks vary between local header and
- * central directory. These are the local header versions.
- * Central directory versions get formatted in
- * archive_write_zip_finish_entry() below.
- */
-
- /* "[Zip64 entry] in the local header MUST include BOTH
- * original [uncompressed] and compressed size fields." */
- if (zip->entry_uses_zip64) {
- unsigned char *zip64_start = e;
- memcpy(e, "\001\000\020\000", 4);
- e += 4;
- archive_le64enc(e, zip->entry_uncompressed_size);
- e += 8;
- archive_le64enc(e, zip->entry_compressed_size);
- e += 8;
- archive_le16enc(zip64_start + 2, (uint16_t)(e - (zip64_start + 4)));
- }
-
- if (zip->flags & ZIP_FLAG_EXPERIMENT_xl) {
- /* Experimental 'xl' extension to improve streaming. */
- unsigned char *external_info = e;
- int included = 7;
- memcpy(e, "xl\000\000", 4); // 0x6c65 + 2-byte length
- e += 4;
- e[0] = included; /* bitmap of included fields */
- e += 1;
- if (included & 1) {
- archive_le16enc(e, /* "Version created by" */
- 3 * 256 + version_needed);
- e += 2;
- }
- if (included & 2) {
- archive_le16enc(e, 0); /* internal file attributes */
- e += 2;
- }
- if (included & 4) {
- archive_le32enc(e, /* external file attributes */
- ((uint32_t)archive_entry_mode(zip->entry)) << 16);
- e += 4;
- }
- if (included & 8) {
- // Libarchive does not currently support file comments.
- }
- archive_le16enc(external_info + 2, (uint16_t)(e - (external_info + 4)));
- }
-
- /* Update local header with size of extra data and write it all out: */
- archive_le16enc(local_header + 28, (uint16_t)(e - local_extra));
-
- ret = __archive_write_output(a, local_header, 30);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- zip->written_bytes += 30;
-
- ret = write_path(zip->entry, a);
- if (ret <= ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- zip->written_bytes += ret;
-
- ret = __archive_write_output(a, local_extra, e - local_extra);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- zip->written_bytes += e - local_extra;
-
- /* For symlinks, write the body now. */
- if (slink != NULL) {
- ret = __archive_write_output(a, slink, slink_size);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- zip->entry_compressed_written += slink_size;
- zip->entry_uncompressed_written += slink_size;
- zip->written_bytes += slink_size;
- }
-
-#ifdef HAVE_ZLIB_H
- if (zip->entry_compression == COMPRESSION_DEFLATE) {
- zip->stream.zalloc = Z_NULL;
- zip->stream.zfree = Z_NULL;
- zip->stream.opaque = Z_NULL;
- zip->stream.next_out = zip->buf;
- zip->stream.avail_out = (uInt)zip->len_buf;
- if (deflateInit2(&zip->stream, zip->deflate_compression_level,
- Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't init deflate compressor");
- return (ARCHIVE_FATAL);
- }
- }
-#endif
-
- return (ret2);
-}
-
-static ssize_t
-archive_write_zip_data(struct archive_write *a, const void *buff, size_t s)
-{
- int ret;
- struct zip *zip = a->format_data;
-
- if ((int64_t)s > zip->entry_uncompressed_limit)
- s = (size_t)zip->entry_uncompressed_limit;
- zip->entry_uncompressed_written += s;
-
- if (s == 0) return 0;
-
- if (zip->entry_flags & ZIP_ENTRY_FLAG_ENCRYPTED) {
- switch (zip->entry_encryption) {
- case ENCRYPTION_TRADITIONAL:
- /* Initialize traditional PKWARE encryption context. */
- if (!zip->tctx_valid) {
- ret = init_traditional_pkware_encryption(a);
- if (ret != ARCHIVE_OK)
- return (ret);
- zip->tctx_valid = 1;
- }
- break;
- case ENCRYPTION_WINZIP_AES128:
- case ENCRYPTION_WINZIP_AES256:
- if (!zip->cctx_valid) {
- ret = init_winzip_aes_encryption(a);
- if (ret != ARCHIVE_OK)
- return (ret);
- zip->cctx_valid = zip->hctx_valid = 1;
- }
- break;
- case ENCRYPTION_NONE:
- default:
- break;
- }
- }
-
- switch (zip->entry_compression) {
- case COMPRESSION_STORE:
- if (zip->tctx_valid || zip->cctx_valid) {
- const uint8_t *rb = (const uint8_t *)buff;
- const uint8_t * const re = rb + s;
-
- while (rb < re) {
- size_t l;
-
- if (zip->tctx_valid) {
- l = trad_enc_encrypt_update(&zip->tctx,
- rb, re - rb,
- zip->buf, zip->len_buf);
- } else {
- l = zip->len_buf;
- ret = archive_encrypto_aes_ctr_update(
- &zip->cctx,
- rb, re - rb, zip->buf, &l);
- if (ret < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Failed to encrypt file");
- return (ARCHIVE_FAILED);
- }
- archive_hmac_sha1_update(&zip->hctx,
- zip->buf, l);
- }
- ret = __archive_write_output(a, zip->buf, l);
- if (ret != ARCHIVE_OK)
- return (ret);
- zip->entry_compressed_written += l;
- zip->written_bytes += l;
- rb += l;
- }
- } else {
- ret = __archive_write_output(a, buff, s);
- if (ret != ARCHIVE_OK)
- return (ret);
- zip->written_bytes += s;
- zip->entry_compressed_written += s;
- }
- break;
-#if HAVE_ZLIB_H
- case COMPRESSION_DEFLATE:
- zip->stream.next_in = (unsigned char*)(uintptr_t)buff;
- zip->stream.avail_in = (uInt)s;
- do {
- ret = deflate(&zip->stream, Z_NO_FLUSH);
- if (ret == Z_STREAM_ERROR)
- return (ARCHIVE_FATAL);
- if (zip->stream.avail_out == 0) {
- if (zip->tctx_valid) {
- trad_enc_encrypt_update(&zip->tctx,
- zip->buf, zip->len_buf,
- zip->buf, zip->len_buf);
- } else if (zip->cctx_valid) {
- size_t outl = zip->len_buf;
- ret = archive_encrypto_aes_ctr_update(
- &zip->cctx,
- zip->buf, zip->len_buf,
- zip->buf, &outl);
- if (ret < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Failed to encrypt file");
- return (ARCHIVE_FAILED);
- }
- archive_hmac_sha1_update(&zip->hctx,
- zip->buf, zip->len_buf);
- }
- ret = __archive_write_output(a, zip->buf,
- zip->len_buf);
- if (ret != ARCHIVE_OK)
- return (ret);
- zip->entry_compressed_written += zip->len_buf;
- zip->written_bytes += zip->len_buf;
- zip->stream.next_out = zip->buf;
- zip->stream.avail_out = (uInt)zip->len_buf;
- }
- } while (zip->stream.avail_in != 0);
- break;
-#endif
-
- case COMPRESSION_UNSPECIFIED:
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Invalid ZIP compression type");
- return ARCHIVE_FATAL;
- }
-
- zip->entry_uncompressed_limit -= s;
- if (!zip->cctx_valid || zip->aes_vendor != AES_VENDOR_AE_2)
- zip->entry_crc32 =
- zip->crc32func(zip->entry_crc32, buff, (unsigned)s);
- return (s);
-
-}
-
-static int
-archive_write_zip_finish_entry(struct archive_write *a)
-{
- struct zip *zip = a->format_data;
- int ret;
-
-#if HAVE_ZLIB_H
- if (zip->entry_compression == COMPRESSION_DEFLATE) {
- for (;;) {
- size_t remainder;
-
- ret = deflate(&zip->stream, Z_FINISH);
- if (ret == Z_STREAM_ERROR)
- return (ARCHIVE_FATAL);
- remainder = zip->len_buf - zip->stream.avail_out;
- if (zip->tctx_valid) {
- trad_enc_encrypt_update(&zip->tctx,
- zip->buf, remainder, zip->buf, remainder);
- } else if (zip->cctx_valid) {
- size_t outl = remainder;
- ret = archive_encrypto_aes_ctr_update(
- &zip->cctx, zip->buf, remainder,
- zip->buf, &outl);
- if (ret < 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Failed to encrypt file");
- return (ARCHIVE_FAILED);
- }
- archive_hmac_sha1_update(&zip->hctx,
- zip->buf, remainder);
- }
- ret = __archive_write_output(a, zip->buf, remainder);
- if (ret != ARCHIVE_OK)
- return (ret);
- zip->entry_compressed_written += remainder;
- zip->written_bytes += remainder;
- zip->stream.next_out = zip->buf;
- if (zip->stream.avail_out != 0)
- break;
- zip->stream.avail_out = (uInt)zip->len_buf;
- }
- deflateEnd(&zip->stream);
- }
-#endif
- if (zip->hctx_valid) {
- uint8_t hmac[20];
- size_t hmac_len = 20;
-
- archive_hmac_sha1_final(&zip->hctx, hmac, &hmac_len);
- ret = __archive_write_output(a, hmac, AUTH_CODE_SIZE);
- if (ret != ARCHIVE_OK)
- return (ret);
- zip->entry_compressed_written += AUTH_CODE_SIZE;
- zip->written_bytes += AUTH_CODE_SIZE;
- }
-
- /* Write trailing data descriptor. */
- if ((zip->entry_flags & ZIP_ENTRY_FLAG_LENGTH_AT_END) != 0) {
- char d[24];
- memcpy(d, "PK\007\010", 4);
- if (zip->cctx_valid && zip->aes_vendor == AES_VENDOR_AE_2)
- archive_le32enc(d + 4, 0);/* no CRC.*/
- else
- archive_le32enc(d + 4, zip->entry_crc32);
- if (zip->entry_uses_zip64) {
- archive_le64enc(d + 8,
- (uint64_t)zip->entry_compressed_written);
- archive_le64enc(d + 16,
- (uint64_t)zip->entry_uncompressed_written);
- ret = __archive_write_output(a, d, 24);
- zip->written_bytes += 24;
- } else {
- archive_le32enc(d + 8,
- (uint32_t)zip->entry_compressed_written);
- archive_le32enc(d + 12,
- (uint32_t)zip->entry_uncompressed_written);
- ret = __archive_write_output(a, d, 16);
- zip->written_bytes += 16;
- }
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- }
-
- /* Append Zip64 extra data to central directory information. */
- if (zip->entry_compressed_written > ZIP_4GB_MAX
- || zip->entry_uncompressed_written > ZIP_4GB_MAX
- || zip->entry_offset > ZIP_4GB_MAX) {
- unsigned char zip64[32];
- unsigned char *z = zip64, *zd;
- memcpy(z, "\001\000\000\000", 4);
- z += 4;
- if (zip->entry_uncompressed_written >= ZIP_4GB_MAX) {
- archive_le64enc(z, zip->entry_uncompressed_written);
- z += 8;
- }
- if (zip->entry_compressed_written >= ZIP_4GB_MAX) {
- archive_le64enc(z, zip->entry_compressed_written);
- z += 8;
- }
- if (zip->entry_offset >= ZIP_4GB_MAX) {
- archive_le64enc(z, zip->entry_offset);
- z += 8;
- }
- archive_le16enc(zip64 + 2, (uint16_t)(z - (zip64 + 4)));
- zd = cd_alloc(zip, z - zip64);
- if (zd == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate zip data");
- return (ARCHIVE_FATAL);
- }
- memcpy(zd, zip64, z - zip64);
- /* Zip64 means version needs to be set to at least 4.5 */
- if (archive_le16dec(zip->file_header + 6) < 45)
- archive_le16enc(zip->file_header + 6, 45);
- }
-
- /* Fix up central directory file header. */
- if (zip->cctx_valid && zip->aes_vendor == AES_VENDOR_AE_2)
- archive_le32enc(zip->file_header + 16, 0);/* no CRC.*/
- else
- archive_le32enc(zip->file_header + 16, zip->entry_crc32);
- archive_le32enc(zip->file_header + 20,
- (uint32_t)zipmin(zip->entry_compressed_written,
- ZIP_4GB_MAX));
- archive_le32enc(zip->file_header + 24,
- (uint32_t)zipmin(zip->entry_uncompressed_written,
- ZIP_4GB_MAX));
- archive_le16enc(zip->file_header + 30,
- (uint16_t)(zip->central_directory_bytes - zip->file_header_extra_offset));
- archive_le32enc(zip->file_header + 42,
- (uint32_t)zipmin(zip->entry_offset,
- ZIP_4GB_MAX));
-
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_zip_close(struct archive_write *a)
-{
- uint8_t buff[64];
- int64_t offset_start, offset_end;
- struct zip *zip = a->format_data;
- struct cd_segment *segment;
- int ret;
-
- offset_start = zip->written_bytes;
- segment = zip->central_directory;
- while (segment != NULL) {
- ret = __archive_write_output(a,
- segment->buff, segment->p - segment->buff);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- zip->written_bytes += segment->p - segment->buff;
- segment = segment->next;
- }
- offset_end = zip->written_bytes;
-
- /* If central dir info is too large, write Zip64 end-of-cd */
- if (offset_end - offset_start > ZIP_4GB_MAX
- || offset_start > ZIP_4GB_MAX
- || zip->central_directory_entries > 0xffffUL
- || (zip->flags & ZIP_FLAG_FORCE_ZIP64)) {
- /* Zip64 end-of-cd record */
- memset(buff, 0, 56);
- memcpy(buff, "PK\006\006", 4);
- archive_le64enc(buff + 4, 44);
- archive_le16enc(buff + 12, 45);
- archive_le16enc(buff + 14, 45);
- /* This is disk 0 of 0. */
- archive_le64enc(buff + 24, zip->central_directory_entries);
- archive_le64enc(buff + 32, zip->central_directory_entries);
- archive_le64enc(buff + 40, offset_end - offset_start);
- archive_le64enc(buff + 48, offset_start);
- ret = __archive_write_output(a, buff, 56);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- zip->written_bytes += 56;
-
- /* Zip64 end-of-cd locator record. */
- memset(buff, 0, 20);
- memcpy(buff, "PK\006\007", 4);
- archive_le32enc(buff + 4, 0);
- archive_le64enc(buff + 8, offset_end);
- archive_le32enc(buff + 16, 1);
- ret = __archive_write_output(a, buff, 20);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- zip->written_bytes += 20;
-
- }
-
- /* Format and write end of central directory. */
- memset(buff, 0, sizeof(buff));
- memcpy(buff, "PK\005\006", 4);
- archive_le16enc(buff + 8, (uint16_t)zipmin(0xffffU,
- zip->central_directory_entries));
- archive_le16enc(buff + 10, (uint16_t)zipmin(0xffffU,
- zip->central_directory_entries));
- archive_le32enc(buff + 12,
- (uint32_t)zipmin(ZIP_4GB_MAX, (offset_end - offset_start)));
- archive_le32enc(buff + 16,
- (uint32_t)zipmin(ZIP_4GB_MAX, offset_start));
- ret = __archive_write_output(a, buff, 22);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- zip->written_bytes += 22;
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_zip_free(struct archive_write *a)
-{
- struct zip *zip;
- struct cd_segment *segment;
-
- zip = a->format_data;
- while (zip->central_directory != NULL) {
- segment = zip->central_directory;
- zip->central_directory = segment->next;
- free(segment->buff);
- free(segment);
- }
- free(zip->buf);
- archive_entry_free(zip->entry);
- if (zip->cctx_valid)
- archive_encrypto_aes_ctr_release(&zip->cctx);
- if (zip->hctx_valid)
- archive_hmac_sha1_cleanup(&zip->hctx);
- /* TODO: Free opt_sconv, sconv_default */
-
- free(zip);
- a->format_data = NULL;
- return (ARCHIVE_OK);
-}
-
-/* Convert into MSDOS-style date/time. */
-static unsigned int
-dos_time(const time_t unix_time)
-{
- struct tm *t;
- unsigned int dt;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
- struct tm tmbuf;
-#endif
-
-#if defined(HAVE_LOCALTIME_S)
- t = localtime_s(&tmbuf, &unix_time) ? NULL : &tmbuf;
-#elif defined(HAVE_LOCALTIME_R)
- t = localtime_r(&unix_time, &tmbuf);
-#else
- t = localtime(&unix_time);
-#endif
-
- /* MSDOS-style date/time is only between 1980-01-01 and 2107-12-31 */
- if (t->tm_year < 1980 - 1900)
- /* Set minimum date/time '1980-01-01 00:00:00'. */
- dt = 0x00210000U;
- else if (t->tm_year > 2107 - 1900)
- /* Set maximum date/time '2107-12-31 23:59:58'. */
- dt = 0xff9fbf7dU;
- else {
- dt = 0;
- dt += ((t->tm_year - 80) & 0x7f) << 9;
- dt += ((t->tm_mon + 1) & 0x0f) << 5;
- dt += (t->tm_mday & 0x1f);
- dt <<= 16;
- dt += (t->tm_hour & 0x1f) << 11;
- dt += (t->tm_min & 0x3f) << 5;
- dt += (t->tm_sec & 0x3e) >> 1; /* Only counting every 2 seconds. */
- }
- return dt;
-}
-
-static size_t
-path_length(struct archive_entry *entry)
-{
- mode_t type;
- const char *path;
- size_t len;
-
- type = archive_entry_filetype(entry);
- path = archive_entry_pathname(entry);
-
- if (path == NULL)
- return (0);
- len = strlen(path);
- if (type == AE_IFDIR && (path[0] == '\0' || path[len - 1] != '/'))
- ++len; /* Space for the trailing / */
- return len;
-}
-
-static int
-write_path(struct archive_entry *entry, struct archive_write *archive)
-{
- int ret;
- const char *path;
- mode_t type;
- size_t written_bytes;
-
- path = archive_entry_pathname(entry);
- type = archive_entry_filetype(entry);
- written_bytes = 0;
-
- if (path == NULL)
- return (ARCHIVE_FATAL);
-
- ret = __archive_write_output(archive, path, strlen(path));
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- written_bytes += strlen(path);
-
- /* Folders are recognized by a trailing slash. */
- if ((type == AE_IFDIR) & (path[strlen(path) - 1] != '/')) {
- ret = __archive_write_output(archive, "/", 1);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- written_bytes += 1;
- }
-
- return ((int)written_bytes);
-}
-
-static void
-copy_path(struct archive_entry *entry, unsigned char *p)
-{
- const char *path;
- size_t pathlen;
- mode_t type;
-
- path = archive_entry_pathname(entry);
- pathlen = strlen(path);
- type = archive_entry_filetype(entry);
-
- memcpy(p, path, pathlen);
-
- /* Folders are recognized by a trailing slash. */
- if ((type == AE_IFDIR) && (path[pathlen - 1] != '/'))
- p[pathlen] = '/';
-}
-
-
-static struct archive_string_conv *
-get_sconv(struct archive_write *a, struct zip *zip)
-{
- if (zip->opt_sconv != NULL)
- return (zip->opt_sconv);
-
- if (!zip->init_default_conversion) {
- zip->sconv_default =
- archive_string_default_conversion_for_write(&(a->archive));
- zip->init_default_conversion = 1;
- }
- return (zip->sconv_default);
-}
-
-/*
- Traditional PKWARE Decryption functions.
- */
-
-static void
-trad_enc_update_keys(struct trad_enc_ctx *ctx, uint8_t c)
-{
- uint8_t t;
-#define CRC32(c, b) (crc32(c ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL)
-
- ctx->keys[0] = CRC32(ctx->keys[0], c);
- ctx->keys[1] = (ctx->keys[1] + (ctx->keys[0] & 0xff)) * 134775813L + 1;
- t = (ctx->keys[1] >> 24) & 0xff;
- ctx->keys[2] = CRC32(ctx->keys[2], t);
-#undef CRC32
-}
-
-static uint8_t
-trad_enc_decrypt_byte(struct trad_enc_ctx *ctx)
-{
- unsigned temp = ctx->keys[2] | 2;
- return (uint8_t)((temp * (temp ^ 1)) >> 8) & 0xff;
-}
-
-static unsigned
-trad_enc_encrypt_update(struct trad_enc_ctx *ctx, const uint8_t *in,
- size_t in_len, uint8_t *out, size_t out_len)
-{
- unsigned i, max;
-
- max = (unsigned)((in_len < out_len)? in_len: out_len);
-
- for (i = 0; i < max; i++) {
- uint8_t t = in[i];
- out[i] = t ^ trad_enc_decrypt_byte(ctx);
- trad_enc_update_keys(ctx, t);
- }
- return i;
-}
-
-static int
-trad_enc_init(struct trad_enc_ctx *ctx, const char *pw, size_t pw_len)
-{
-
- ctx->keys[0] = 305419896L;
- ctx->keys[1] = 591751049L;
- ctx->keys[2] = 878082192L;
-
- for (;pw_len; --pw_len)
- trad_enc_update_keys(ctx, *pw++);
- return 0;
-}
-
-static int
-is_traditional_pkware_encryption_supported(void)
-{
- uint8_t key[TRAD_HEADER_SIZE];
-
- if (archive_random(key, sizeof(key)-1) != ARCHIVE_OK)
- return (0);
- return (1);
-}
-
-static int
-init_traditional_pkware_encryption(struct archive_write *a)
-{
- struct zip *zip = a->format_data;
- const char *passphrase;
- uint8_t key[TRAD_HEADER_SIZE];
- uint8_t key_encrypted[TRAD_HEADER_SIZE];
- int ret;
-
- passphrase = __archive_write_get_passphrase(a);
- if (passphrase == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Encryption needs passphrase");
- return ARCHIVE_FAILED;
- }
- if (archive_random(key, sizeof(key)-1) != ARCHIVE_OK) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Can't generate random number for encryption");
- return ARCHIVE_FATAL;
- }
- trad_enc_init(&zip->tctx, passphrase, strlen(passphrase));
- /* Set the last key code which will be used as a check code
- * for verifying passphrase in decryption. */
- key[TRAD_HEADER_SIZE-1] = zip->trad_chkdat;
- trad_enc_encrypt_update(&zip->tctx, key, TRAD_HEADER_SIZE,
- key_encrypted, TRAD_HEADER_SIZE);
- /* Write encrypted keys in the top of the file content. */
- ret = __archive_write_output(a, key_encrypted, TRAD_HEADER_SIZE);
- if (ret != ARCHIVE_OK)
- return (ret);
- zip->written_bytes += TRAD_HEADER_SIZE;
- zip->entry_compressed_written += TRAD_HEADER_SIZE;
- return (ret);
-}
-
-static int
-init_winzip_aes_encryption(struct archive_write *a)
-{
- struct zip *zip = a->format_data;
- const char *passphrase;
- size_t key_len, salt_len;
- uint8_t salt[16 + 2];
- uint8_t derived_key[MAX_DERIVED_KEY_BUF_SIZE];
- int ret;
-
- passphrase = __archive_write_get_passphrase(a);
- if (passphrase == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Encryption needs passphrase");
- return (ARCHIVE_FAILED);
- }
- if (zip->entry_encryption == ENCRYPTION_WINZIP_AES128) {
- salt_len = 8;
- key_len = 16;
- } else {
- /* AES 256 */
- salt_len = 16;
- key_len = 32;
- }
- if (archive_random(salt, salt_len) != ARCHIVE_OK) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Can't generate random number for encryption");
- return (ARCHIVE_FATAL);
- }
- archive_pbkdf2_sha1(passphrase, strlen(passphrase),
- salt, salt_len, 1000, derived_key, key_len * 2 + 2);
-
- ret = archive_encrypto_aes_ctr_init(&zip->cctx, derived_key, key_len);
- if (ret != 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Decryption is unsupported due to lack of crypto library");
- return (ARCHIVE_FAILED);
- }
- ret = archive_hmac_sha1_init(&zip->hctx, derived_key + key_len,
- key_len);
- if (ret != 0) {
- archive_encrypto_aes_ctr_release(&zip->cctx);
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Failed to initialize HMAC-SHA1");
- return (ARCHIVE_FAILED);
- }
-
- /* Set a password verification value after the 'salt'. */
- salt[salt_len] = derived_key[key_len * 2];
- salt[salt_len + 1] = derived_key[key_len * 2 + 1];
-
- /* Write encrypted keys in the top of the file content. */
- ret = __archive_write_output(a, salt, salt_len + 2);
- if (ret != ARCHIVE_OK)
- return (ret);
- zip->written_bytes += salt_len + 2;
- zip->entry_compressed_written += salt_len + 2;
-
- return (ARCHIVE_OK);
-}
-
-static int
-is_winzip_aes_encryption_supported(int encryption)
-{
- size_t key_len, salt_len;
- uint8_t salt[16 + 2];
- uint8_t derived_key[MAX_DERIVED_KEY_BUF_SIZE];
- archive_crypto_ctx cctx;
- archive_hmac_sha1_ctx hctx;
- int ret;
-
- if (encryption == ENCRYPTION_WINZIP_AES128) {
- salt_len = 8;
- key_len = 16;
- } else {
- /* AES 256 */
- salt_len = 16;
- key_len = 32;
- }
- if (archive_random(salt, salt_len) != ARCHIVE_OK)
- return (0);
- ret = archive_pbkdf2_sha1("p", 1, salt, salt_len, 1000,
- derived_key, key_len * 2 + 2);
- if (ret != 0)
- return (0);
-
- ret = archive_encrypto_aes_ctr_init(&cctx, derived_key, key_len);
- if (ret != 0)
- return (0);
- ret = archive_hmac_sha1_init(&hctx, derived_key + key_len,
- key_len);
- archive_encrypto_aes_ctr_release(&cctx);
- if (ret != 0)
- return (0);
- archive_hmac_sha1_cleanup(&hctx);
- return (1);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_options.c b/contrib/libs/libarchive/libarchive/archive_write_set_options.c
deleted file mode 100644
index 962309ada5..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_options.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/*-
- * Copyright (c) 2003-2010 Tim Kientzle
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#include "archive_write_private.h"
-#include "archive_options_private.h"
-
-static int archive_set_format_option(struct archive *a,
- const char *m, const char *o, const char *v);
-static int archive_set_filter_option(struct archive *a,
- const char *m, const char *o, const char *v);
-static int archive_set_option(struct archive *a,
- const char *m, const char *o, const char *v);
-
-int
-archive_write_set_format_option(struct archive *a, const char *m, const char *o,
- const char *v)
-{
- return _archive_set_option(a, m, o, v,
- ARCHIVE_WRITE_MAGIC, "archive_write_set_format_option",
- archive_set_format_option);
-}
-
-int
-archive_write_set_filter_option(struct archive *a, const char *m, const char *o,
- const char *v)
-{
- return _archive_set_option(a, m, o, v,
- ARCHIVE_WRITE_MAGIC, "archive_write_set_filter_option",
- archive_set_filter_option);
-}
-
-int
-archive_write_set_option(struct archive *a, const char *m, const char *o,
- const char *v)
-{
- return _archive_set_option(a, m, o, v,
- ARCHIVE_WRITE_MAGIC, "archive_write_set_option",
- archive_set_option);
-}
-
-int
-archive_write_set_options(struct archive *a, const char *options)
-{
- return _archive_set_options(a, options,
- ARCHIVE_WRITE_MAGIC, "archive_write_set_options",
- archive_set_option);
-}
-
-static int
-archive_set_format_option(struct archive *_a, const char *m, const char *o,
- const char *v)
-{
- struct archive_write *a = (struct archive_write *)_a;
-
- if (a->format_name == NULL)
- return (m == NULL)?ARCHIVE_FAILED:ARCHIVE_WARN - 1;
- /* If the format name didn't match, return a special code for
- * _archive_set_option[s]. */
- if (m != NULL && strcmp(m, a->format_name) != 0)
- return (ARCHIVE_WARN - 1);
- if (a->format_options == NULL)
- return (ARCHIVE_WARN);
- return a->format_options(a, o, v);
-}
-
-static int
-archive_set_filter_option(struct archive *_a, const char *m, const char *o,
- const char *v)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct archive_write_filter *filter;
- int r, rv = ARCHIVE_WARN;
-
- for (filter = a->filter_first; filter != NULL; filter = filter->next_filter) {
- if (filter->options == NULL)
- continue;
- if (m != NULL && strcmp(filter->name, m) != 0)
- continue;
-
- r = filter->options(filter, o, v);
-
- if (r == ARCHIVE_FATAL)
- return (ARCHIVE_FATAL);
-
- if (m != NULL)
- return (r);
-
- if (r == ARCHIVE_OK)
- rv = ARCHIVE_OK;
- }
- /* If the filter name didn't match, return a special code for
- * _archive_set_option[s]. */
- if (rv == ARCHIVE_WARN && m != NULL)
- rv = ARCHIVE_WARN - 1;
- return (rv);
-}
-
-static int
-archive_set_option(struct archive *a, const char *m, const char *o,
- const char *v)
-{
- return _archive_set_either_option(a, m, o, v,
- archive_set_format_option,
- archive_set_filter_option);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_write_set_passphrase.c b/contrib/libs/libarchive/libarchive/archive_write_set_passphrase.c
deleted file mode 100644
index 710ecba52c..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_write_set_passphrase.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*-
- * Copyright (c) 2014 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include "archive_write_private.h"
-
-int
-archive_write_set_passphrase(struct archive *_a, const char *p)
-{
- struct archive_write *a = (struct archive_write *)_a;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_NEW,
- "archive_write_set_passphrase");
-
- if (p == NULL || p[0] == '\0') {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Empty passphrase is unacceptable");
- return (ARCHIVE_FAILED);
- }
- free(a->passphrase);
- a->passphrase = strdup(p);
- if (a->passphrase == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate data for passphrase");
- return (ARCHIVE_FATAL);
- }
- return (ARCHIVE_OK);
-}
-
-
-int
-archive_write_set_passphrase_callback(struct archive *_a, void *client_data,
- archive_passphrase_callback *cb)
-{
- struct archive_write *a = (struct archive_write *)_a;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_NEW,
- "archive_write_set_passphrase_callback");
-
- a->passphrase_callback = cb;
- a->passphrase_client_data = client_data;
- return (ARCHIVE_OK);
-}
-
-
-const char *
-__archive_write_get_passphrase(struct archive_write *a)
-{
-
- if (a->passphrase != NULL)
- return (a->passphrase);
-
- if (a->passphrase_callback != NULL) {
- const char *p;
- p = a->passphrase_callback(&a->archive,
- a->passphrase_client_data);
- if (p != NULL) {
- a->passphrase = strdup(p);
- if (a->passphrase == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate data for passphrase");
- return (NULL);
- }
- return (a->passphrase);
- }
- }
- return (NULL);
-}
diff --git a/contrib/libs/libarchive/libarchive/archive_xxhash.h b/contrib/libs/libarchive/libarchive/archive_xxhash.h
deleted file mode 100644
index 1c7131ca1e..0000000000
--- a/contrib/libs/libarchive/libarchive/archive_xxhash.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*-
- * Copyright (c) 2014 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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.
- *
- */
-
-#ifndef ARCHIVE_XXHASH_H_INCLUDED
-#define ARCHIVE_XXHASH_H_INCLUDED
-
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
-
-typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
-
-struct archive_xxhash {
- unsigned int (*XXH32)(const void* input, unsigned int len,
- unsigned int seed);
- void* (*XXH32_init)(unsigned int seed);
- XXH_errorcode (*XXH32_update)(void* state, const void* input,
- unsigned int len);
- unsigned int (*XXH32_digest)(void* state);
-};
-
-extern const struct archive_xxhash __archive_xxhash;
-
-#endif
diff --git a/contrib/libs/libarchive/libarchive/filter_fork.h b/contrib/libs/libarchive/libarchive/filter_fork.h
deleted file mode 100644
index 2bf290c4d9..0000000000
--- a/contrib/libs/libarchive/libarchive/filter_fork.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*-
- * Copyright (c) 2007 Joerg Sonnenberger
- * 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(S) ``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(S) 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.
- *
- * $FreeBSD: head/lib/libarchive/filter_fork.h 201087 2009-12-28 02:18:26Z kientzle $
- */
-
-#ifndef FILTER_FORK_H
-#define FILTER_FORK_H
-
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
-int
-__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
-#if defined(_WIN32) && !defined(__CYGWIN__)
- HANDLE *out_child);
-#else
- pid_t *out_child);
-#endif
-
-void
-__archive_check_child(int in, int out);
-
-#endif
diff --git a/contrib/libs/libarchive/libarchive/filter_fork_posix.c b/contrib/libs/libarchive/libarchive/filter_fork_posix.c
deleted file mode 100644
index 62085a7099..0000000000
--- a/contrib/libs/libarchive/libarchive/filter_fork_posix.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/*-
- * Copyright (c) 2007 Joerg Sonnenberger
- * Copyright (c) 2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-/* This capability is only available on POSIX systems. */
-#if defined(HAVE_PIPE) && defined(HAVE_FCNTL) && \
- (defined(HAVE_FORK) || defined(HAVE_VFORK) || defined(HAVE_POSIX_SPAWNP))
-
-__FBSDID("$FreeBSD: head/lib/libarchive/filter_fork.c 182958 2008-09-12 05:33:00Z kientzle $");
-
-#if defined(HAVE_SYS_TYPES_H)
-# include <sys/types.h>
-#endif
-#ifdef HAVE_ERRNO_H
-# include <errno.h>
-#endif
-#ifdef HAVE_STRING_H
-# include <string.h>
-#endif
-#if defined(HAVE_POLL) && (defined(HAVE_POLL_H) || defined(HAVE_SYS_POLL_H))
-# if defined(HAVE_POLL_H)
-# include <poll.h>
-# elif defined(HAVE_SYS_POLL_H)
-# include <sys/poll.h>
-# endif
-#elif defined(HAVE_SELECT)
-# if defined(HAVE_SYS_SELECT_H)
-# include <sys/select.h>
-# elif defined(HAVE_UNISTD_H)
-# include <unistd.h>
-# endif
-#endif
-#ifdef HAVE_FCNTL_H
-# include <fcntl.h>
-#endif
-#ifdef HAVE_SPAWN_H
-# include <spawn.h>
-#endif
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#include "archive.h"
-#include "archive_cmdline_private.h"
-
-#include "filter_fork.h"
-
-int
-__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
- pid_t *out_child)
-{
- pid_t child = -1;
- int stdin_pipe[2], stdout_pipe[2], tmp;
-#if HAVE_POSIX_SPAWNP
- posix_spawn_file_actions_t actions;
- int r;
-#endif
- struct archive_cmdline *cmdline;
-
- cmdline = __archive_cmdline_allocate();
- if (cmdline == NULL)
- goto state_allocated;
- if (__archive_cmdline_parse(cmdline, cmd) != ARCHIVE_OK)
- goto state_allocated;
-
- if (pipe(stdin_pipe) == -1)
- goto state_allocated;
- if (stdin_pipe[0] == 1 /* stdout */) {
- if ((tmp = dup(stdin_pipe[0])) == -1)
- goto stdin_opened;
- close(stdin_pipe[0]);
- stdin_pipe[0] = tmp;
- }
- if (pipe(stdout_pipe) == -1)
- goto stdin_opened;
- if (stdout_pipe[1] == 0 /* stdin */) {
- if ((tmp = dup(stdout_pipe[1])) == -1)
- goto stdout_opened;
- close(stdout_pipe[1]);
- stdout_pipe[1] = tmp;
- }
-
-#if HAVE_POSIX_SPAWNP
-
- r = posix_spawn_file_actions_init(&actions);
- if (r != 0) {
- errno = r;
- goto stdout_opened;
- }
- r = posix_spawn_file_actions_addclose(&actions, stdin_pipe[1]);
- if (r != 0)
- goto actions_inited;
- r = posix_spawn_file_actions_addclose(&actions, stdout_pipe[0]);
- if (r != 0)
- goto actions_inited;
- /* Setup for stdin. */
- r = posix_spawn_file_actions_adddup2(&actions, stdin_pipe[0], 0);
- if (r != 0)
- goto actions_inited;
- if (stdin_pipe[0] != 0 /* stdin */) {
- r = posix_spawn_file_actions_addclose(&actions, stdin_pipe[0]);
- if (r != 0)
- goto actions_inited;
- }
- /* Setup for stdout. */
- r = posix_spawn_file_actions_adddup2(&actions, stdout_pipe[1], 1);
- if (r != 0)
- goto actions_inited;
- if (stdout_pipe[1] != 1 /* stdout */) {
- r = posix_spawn_file_actions_addclose(&actions, stdout_pipe[1]);
- if (r != 0)
- goto actions_inited;
- }
- r = posix_spawnp(&child, cmdline->path, &actions, NULL,
- cmdline->argv, NULL);
- if (r != 0)
- goto actions_inited;
- posix_spawn_file_actions_destroy(&actions);
-
-#else /* HAVE_POSIX_SPAWNP */
-
-#if HAVE_VFORK
- child = vfork();
-#else
- child = fork();
-#endif
- if (child == -1)
- goto stdout_opened;
- if (child == 0) {
- close(stdin_pipe[1]);
- close(stdout_pipe[0]);
- if (dup2(stdin_pipe[0], 0 /* stdin */) == -1)
- _exit(254);
- if (stdin_pipe[0] != 0 /* stdin */)
- close(stdin_pipe[0]);
- if (dup2(stdout_pipe[1], 1 /* stdout */) == -1)
- _exit(254);
- if (stdout_pipe[1] != 1 /* stdout */)
- close(stdout_pipe[1]);
- execvp(cmdline->path, cmdline->argv);
- _exit(254);
- }
-#endif /* HAVE_POSIX_SPAWNP */
-
- close(stdin_pipe[0]);
- close(stdout_pipe[1]);
-
- *child_stdin = stdin_pipe[1];
- fcntl(*child_stdin, F_SETFL, O_NONBLOCK);
- *child_stdout = stdout_pipe[0];
- fcntl(*child_stdout, F_SETFL, O_NONBLOCK);
- __archive_cmdline_free(cmdline);
-
- *out_child = child;
- return ARCHIVE_OK;
-
-#if HAVE_POSIX_SPAWNP
-actions_inited:
- errno = r;
- posix_spawn_file_actions_destroy(&actions);
-#endif
-stdout_opened:
- close(stdout_pipe[0]);
- close(stdout_pipe[1]);
-stdin_opened:
- close(stdin_pipe[0]);
- close(stdin_pipe[1]);
-state_allocated:
- __archive_cmdline_free(cmdline);
- return ARCHIVE_FAILED;
-}
-
-void
-__archive_check_child(int in, int out)
-{
-#if defined(HAVE_POLL) && (defined(HAVE_POLL_H) || defined(HAVE_SYS_POLL_H))
- struct pollfd fds[2];
- int idx;
-
- idx = 0;
- if (in != -1) {
- fds[idx].fd = in;
- fds[idx].events = POLLOUT;
- ++idx;
- }
- if (out != -1) {
- fds[idx].fd = out;
- fds[idx].events = POLLIN;
- ++idx;
- }
-
- poll(fds, idx, -1); /* -1 == INFTIM, wait forever */
-#elif defined(HAVE_SELECT)
- fd_set fds_in, fds_out, fds_error;
-
- FD_ZERO(&fds_in);
- FD_ZERO(&fds_out);
- FD_ZERO(&fds_error);
- if (out != -1) {
- FD_SET(out, &fds_in);
- FD_SET(out, &fds_error);
- }
- if (in != -1) {
- FD_SET(in, &fds_out);
- FD_SET(in, &fds_error);
- }
- select(in < out ? out + 1 : in + 1, &fds_in, &fds_out, &fds_error, NULL);
-#else
- sleep(1);
-#endif
-}
-
-#endif /* defined(HAVE_PIPE) && defined(HAVE_VFORK) && defined(HAVE_FCNTL) */
diff --git a/contrib/libs/libarchive/libarchive/filter_fork_windows.c b/contrib/libs/libarchive/libarchive/filter_fork_windows.c
deleted file mode 100644
index 9e49c5655f..0000000000
--- a/contrib/libs/libarchive/libarchive/filter_fork_windows.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/*-
- * Copyright (c) 2009-2012 Michihiro NAKAJIMA
- * 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(S) ``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(S) 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 "archive_platform.h"
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#include "archive_cmdline_private.h"
-#include "archive_string.h"
-
-#include "filter_fork.h"
-
-#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
-/* There are some editions of Windows ("nano server," for example) that
- * do not host user32.dll. If we want to keep running on those editions,
- * we need to delay-load WaitForInputIdle. */
-static void *
-la_GetFunctionUser32(const char *name)
-{
- static HINSTANCE lib;
- static int set;
- if (!set) {
- set = 1;
- lib = LoadLibrary(TEXT("user32.dll"));
- }
- if (lib == NULL) {
- return NULL;
- }
- return (void *)GetProcAddress(lib, name);
-}
-
-static int
-la_WaitForInputIdle(HANDLE hProcess, DWORD dwMilliseconds)
-{
- static DWORD (WINAPI *f)(HANDLE, DWORD);
- static int set;
-
- if (!set) {
- set = 1;
- f = la_GetFunctionUser32("WaitForInputIdle");
- }
-
- if (!f) {
- /* An inability to wait for input idle is
- * not _good_, but it is not catastrophic. */
- return WAIT_FAILED;
- }
- return (*f)(hProcess, dwMilliseconds);
-}
-
-int
-__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
- HANDLE *out_child)
-{
- HANDLE childStdout[2], childStdin[2],childStderr;
- SECURITY_ATTRIBUTES secAtts;
- STARTUPINFOA staInfo;
- PROCESS_INFORMATION childInfo;
- struct archive_string cmdline;
- struct archive_string fullpath;
- struct archive_cmdline *acmd;
- char *arg0, *ext;
- int i, l;
- DWORD fl, fl_old;
- HANDLE child;
-
- childStdout[0] = childStdout[1] = INVALID_HANDLE_VALUE;
- childStdin[0] = childStdin[1] = INVALID_HANDLE_VALUE;
- childStderr = INVALID_HANDLE_VALUE;
- archive_string_init(&cmdline);
- archive_string_init(&fullpath);
-
- acmd = __archive_cmdline_allocate();
- if (acmd == NULL)
- goto fail;
- if (__archive_cmdline_parse(acmd, cmd) != ARCHIVE_OK)
- goto fail;
-
- /*
- * Search the full path of 'path'.
- * NOTE: This does not need if we give CreateProcessA 'path' as
- * a part of the cmdline and give CreateProcessA NULL as first
- * parameter, but I do not like that way.
- */
- ext = strrchr(acmd->path, '.');
- if (ext == NULL || strlen(ext) > 4)
- /* 'path' does not have a proper extension, so we have to
- * give SearchPath() ".exe" as the extension. */
- ext = ".exe";
- else
- ext = NULL;/* 'path' has an extension. */
-
- fl = MAX_PATH;
- do {
- if (archive_string_ensure(&fullpath, fl) == NULL)
- goto fail;
- fl_old = fl;
- fl = SearchPathA(NULL, acmd->path, ext, fl, fullpath.s,
- &arg0);
- } while (fl != 0 && fl > fl_old);
- if (fl == 0)
- goto fail;
-
- /*
- * Make a command line.
- */
- for (l = 0, i = 0; acmd->argv[i] != NULL; i++) {
- if (i == 0)
- continue;
- l += (int)strlen(acmd->argv[i]) + 1;
- }
- if (archive_string_ensure(&cmdline, l + 1) == NULL)
- goto fail;
- for (i = 0; acmd->argv[i] != NULL; i++) {
- if (i == 0) {
- const char *p, *sp;
-
- if ((p = strchr(acmd->argv[i], '/')) != NULL ||
- (p = strchr(acmd->argv[i], '\\')) != NULL)
- p++;
- else
- p = acmd->argv[i];
- if ((sp = strchr(p, ' ')) != NULL)
- archive_strappend_char(&cmdline, '"');
- archive_strcat(&cmdline, p);
- if (sp != NULL)
- archive_strappend_char(&cmdline, '"');
- } else {
- archive_strappend_char(&cmdline, ' ');
- archive_strcat(&cmdline, acmd->argv[i]);
- }
- }
- if (i <= 1) {
- const char *sp;
-
- if ((sp = strchr(arg0, ' ')) != NULL)
- archive_strappend_char(&cmdline, '"');
- archive_strcat(&cmdline, arg0);
- if (sp != NULL)
- archive_strappend_char(&cmdline, '"');
- }
-
- secAtts.nLength = sizeof(SECURITY_ATTRIBUTES);
- secAtts.bInheritHandle = TRUE;
- secAtts.lpSecurityDescriptor = NULL;
- if (CreatePipe(&childStdout[0], &childStdout[1], &secAtts, 0) == 0)
- goto fail;
- if (!SetHandleInformation(childStdout[0], HANDLE_FLAG_INHERIT, 0))
- goto fail;
- if (CreatePipe(&childStdin[0], &childStdin[1], &secAtts, 0) == 0)
- goto fail;
- if (!SetHandleInformation(childStdin[1], HANDLE_FLAG_INHERIT, 0))
- goto fail;
- if (DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_ERROR_HANDLE),
- GetCurrentProcess(), &childStderr, 0, TRUE,
- DUPLICATE_SAME_ACCESS) == 0)
- goto fail;
-
- memset(&staInfo, 0, sizeof(staInfo));
- staInfo.cb = sizeof(staInfo);
- staInfo.hStdError = childStderr;
- staInfo.hStdOutput = childStdout[1];
- staInfo.hStdInput = childStdin[0];
- staInfo.wShowWindow = SW_HIDE;
- staInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
- if (CreateProcessA(fullpath.s, cmdline.s, NULL, NULL, TRUE, 0,
- NULL, NULL, &staInfo, &childInfo) == 0)
- goto fail;
- la_WaitForInputIdle(childInfo.hProcess, INFINITE);
- CloseHandle(childInfo.hProcess);
- CloseHandle(childInfo.hThread);
-
- *child_stdout = _open_osfhandle((intptr_t)childStdout[0], _O_RDONLY);
- *child_stdin = _open_osfhandle((intptr_t)childStdin[1], _O_WRONLY);
-
- child = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
- childInfo.dwProcessId);
- if (child == NULL) // INVALID_HANDLE_VALUE ?
- goto fail;
-
- *out_child = child;
-
- CloseHandle(childStdout[1]);
- CloseHandle(childStdin[0]);
-
- archive_string_free(&cmdline);
- archive_string_free(&fullpath);
- __archive_cmdline_free(acmd);
- return ARCHIVE_OK;
-
-fail:
- if (childStdout[0] != INVALID_HANDLE_VALUE)
- CloseHandle(childStdout[0]);
- if (childStdout[1] != INVALID_HANDLE_VALUE)
- CloseHandle(childStdout[1]);
- if (childStdin[0] != INVALID_HANDLE_VALUE)
- CloseHandle(childStdin[0]);
- if (childStdin[1] != INVALID_HANDLE_VALUE)
- CloseHandle(childStdin[1]);
- if (childStderr != INVALID_HANDLE_VALUE)
- CloseHandle(childStderr);
- archive_string_free(&cmdline);
- archive_string_free(&fullpath);
- __archive_cmdline_free(acmd);
- return ARCHIVE_FAILED;
-}
-#else /* !WINAPI_PARTITION_DESKTOP */
-int
-__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout, HANDLE *out_child)
-{
- (void)cmd; (void)child_stdin; (void) child_stdout; (void) out_child;
- return ARCHIVE_FAILED;
-}
-#endif /* !WINAPI_PARTITION_DESKTOP */
-
-void
-__archive_check_child(int in, int out)
-{
- (void)in; /* UNUSED */
- (void)out; /* UNUSED */
- Sleep(100);
-}
-
-#endif /* _WIN32 && !__CYGWIN__ */
diff --git a/contrib/libs/libarchive/libarchive/xxhash.c b/contrib/libs/libarchive/libarchive/xxhash.c
deleted file mode 100644
index beacd23912..0000000000
--- a/contrib/libs/libarchive/libarchive/xxhash.c
+++ /dev/null
@@ -1,529 +0,0 @@
-/*
-xxHash - Fast Hash algorithm
-Copyright (C) 2012-2014, Yann Collet.
-BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-* Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-You can contact the author at :
-- xxHash source repository : http://code.google.com/p/xxhash/
-*/
-#include "archive_platform.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "archive_xxhash.h"
-
-#ifdef HAVE_LIBLZ4
-
-/***************************************
-** Tuning parameters
-****************************************/
-/* Unaligned memory access is automatically enabled for "common" CPU, such as x86.
-** For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected.
-** If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance.
-** You can also enable this parameter if you know your input data will always be aligned (boundaries of 4, for U32).
-*/
-#if defined(__ARM_FEATURE_UNALIGNED) || defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
-# define XXH_USE_UNALIGNED_ACCESS 1
-#endif
-
-/* XXH_ACCEPT_NULL_INPUT_POINTER :
-** If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer.
-** When this option is enabled, xxHash output for null input pointers will be the same as a null-length input.
-** This option has a very small performance cost (only measurable on small inputs).
-** By default, this option is disabled. To enable it, uncomment below define :
-** #define XXH_ACCEPT_NULL_INPUT_POINTER 1
-
-** XXH_FORCE_NATIVE_FORMAT :
-** By default, xxHash library provides endian-independent Hash values, based on little-endian convention.
-** Results are therefore identical for little-endian and big-endian CPU.
-** This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format.
-** Should endian-independence be of no importance for your application, you may set the #define below to 1.
-** It will improve speed for Big-endian CPU.
-** This option has no impact on Little_Endian CPU.
-*/
-#define XXH_FORCE_NATIVE_FORMAT 0
-
-/***************************************
-** Compiler Specific Options
-****************************************/
-/* Disable some Visual warning messages */
-#ifdef _MSC_VER /* Visual Studio */
-# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
-#endif
-
-#ifdef _MSC_VER /* Visual Studio */
-# define FORCE_INLINE __forceinline
-#else
-# ifdef __GNUC__
-# define FORCE_INLINE inline __attribute__((always_inline))
-# else
-# define FORCE_INLINE inline
-# endif
-#endif
-
-/***************************************
-** Includes & Memory related functions
-****************************************/
-#define XXH_malloc malloc
-#define XXH_free free
-#define XXH_memcpy memcpy
-
-
-static unsigned int XXH32 (const void*, unsigned int, unsigned int);
-static void* XXH32_init (unsigned int);
-static XXH_errorcode XXH32_update (void*, const void*, unsigned int);
-static unsigned int XXH32_digest (void*);
-/*static int XXH32_sizeofState(void);*/
-static XXH_errorcode XXH32_resetState(void*, unsigned int);
-#define XXH32_SIZEOFSTATE 48
-typedef struct { long long ll[(XXH32_SIZEOFSTATE+(sizeof(long long)-1))/sizeof(long long)]; } XXH32_stateSpace_t;
-static unsigned int XXH32_intermediateDigest (void*);
-
-/***************************************
-** Basic Types
-****************************************/
-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
-# include <stdint.h>
- typedef uint8_t BYTE;
- typedef uint16_t U16;
- typedef uint32_t U32;
- typedef int32_t S32;
- typedef uint64_t U64;
-#else
- typedef unsigned char BYTE;
- typedef unsigned short U16;
- typedef unsigned int U32;
- typedef signed int S32;
- typedef unsigned long long U64;
-#endif
-
-#if defined(__GNUC__) && !defined(XXH_USE_UNALIGNED_ACCESS)
-# define _PACKED __attribute__ ((packed))
-#else
-# define _PACKED
-#endif
-
-#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__)
-# ifdef __IBMC__
-# pragma pack(1)
-# else
-# pragma pack(push, 1)
-# endif
-#endif
-
-typedef struct _U32_S { U32 v; } _PACKED U32_S;
-
-#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__)
-# pragma pack(pop)
-#endif
-
-
-/****************************************
-** Compiler-specific Functions and Macros
-*****************************************/
-#define GCC_VERSION ((__GNUC__-0) * 100 + (__GNUC_MINOR__ - 0))
-
-#if GCC_VERSION >= 409
-__attribute__((__no_sanitize_undefined__))
-#else
-# if defined(__clang__)
-__attribute__((no_sanitize("undefined")))
-# endif
-#endif
-#if defined(_MSC_VER)
-static __inline U32 A32(const void * x)
-#else
-static inline U32 A32(const void* x)
-#endif
-{
- return (((const U32_S *)(x))->v);
-}
-
-/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */
-#if defined(_MSC_VER)
-# define XXH_rotl32(x,r) _rotl(x,r)
-#else
-# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))
-#endif
-
-#if defined(_MSC_VER) /* Visual Studio */
-# define XXH_swap32 _byteswap_ulong
-#elif GCC_VERSION >= 403
-# define XXH_swap32 __builtin_bswap32
-#else
-static inline U32 XXH_swap32 (U32 x) {
- return ((x << 24) & 0xff000000 ) |
- ((x << 8) & 0x00ff0000 ) |
- ((x >> 8) & 0x0000ff00 ) |
- ((x >> 24) & 0x000000ff );}
-#endif
-
-
-/***************************************
-** Constants
-****************************************/
-#define PRIME32_1 2654435761U
-#define PRIME32_2 2246822519U
-#define PRIME32_3 3266489917U
-#define PRIME32_4 668265263U
-#define PRIME32_5 374761393U
-
-
-/***************************************
-** Architecture Macros
-****************************************/
-typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
-#ifndef XXH_CPU_LITTLE_ENDIAN /* It is possible to define XXH_CPU_LITTLE_ENDIAN externally, for example using a compiler switch */
- static const int one = 1;
-# define XXH_CPU_LITTLE_ENDIAN (*(const char*)(&one))
-#endif
-
-
-/***************************************
-** Macros
-****************************************/
-#define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(!!(c)) }; } /* use only *after* variable declarations */
-
-
-/*****************************
-** Memory reads
-******************************/
-typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
-
-static
-FORCE_INLINE U32 XXH_readLE32_align(const U32* ptr, XXH_endianess endian, XXH_alignment align)
-{
- if (align==XXH_unaligned)
- return endian==XXH_littleEndian ? A32(ptr) : XXH_swap32(A32(ptr));
- else
- return endian==XXH_littleEndian ? *ptr : XXH_swap32(*ptr);
-}
-
-static
-FORCE_INLINE U32 XXH_readLE32(const U32* ptr, XXH_endianess endian) { return XXH_readLE32_align(ptr, endian, XXH_unaligned); }
-
-
-/*****************************
-** Simple Hash Functions
-******************************/
-static
-FORCE_INLINE U32 XXH32_endian_align(const void* input, unsigned int len, U32 seed, XXH_endianess endian, XXH_alignment align)
-{
- const BYTE* p = (const BYTE*)input;
- const BYTE* bEnd = p + len;
- U32 h32;
-#define XXH_get32bits(p) XXH_readLE32_align((const U32*)p, endian, align)
-
-#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
- if (p==NULL) { len=0; bEnd=p=(const BYTE*)(size_t)16; }
-#endif
-
- if (len>=16)
- {
- const BYTE* const limit = bEnd - 16;
- U32 v1 = seed + PRIME32_1 + PRIME32_2;
- U32 v2 = seed + PRIME32_2;
- U32 v3 = seed + 0;
- U32 v4 = seed - PRIME32_1;
-
- do
- {
- v1 += XXH_get32bits(p) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4;
- v2 += XXH_get32bits(p) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4;
- v3 += XXH_get32bits(p) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4;
- v4 += XXH_get32bits(p) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4;
- } while (p<=limit);
-
- h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
- }
- else
- {
- h32 = seed + PRIME32_5;
- }
-
- h32 += (U32) len;
-
- while (p<=bEnd-4)
- {
- h32 += XXH_get32bits(p) * PRIME32_3;
- h32 = XXH_rotl32(h32, 17) * PRIME32_4 ;
- p+=4;
- }
-
- while (p<bEnd)
- {
- h32 += (*p) * PRIME32_5;
- h32 = XXH_rotl32(h32, 11) * PRIME32_1 ;
- p++;
- }
-
- h32 ^= h32 >> 15;
- h32 *= PRIME32_2;
- h32 ^= h32 >> 13;
- h32 *= PRIME32_3;
- h32 ^= h32 >> 16;
-
- return h32;
-}
-
-
-U32 XXH32(const void* input, unsigned int len, U32 seed)
-{
-#if 0
- // Simple version, good for code maintenance, but unfortunately slow for small inputs
- void* state = XXH32_init(seed);
- XXH32_update(state, input, len);
- return XXH32_digest(state);
-#else
- XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
-
-# if !defined(XXH_USE_UNALIGNED_ACCESS)
- if ((((size_t)input) & 3) == 0) /* Input is aligned, let's leverage the speed advantage */
- {
- if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
- return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
- else
- return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
- }
-# endif
-
- if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
- return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
- else
- return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
-#endif
-}
-
-/*****************************
-** Advanced Hash Functions
-******************************/
-
-struct XXH_state32_t
-{
- U64 total_len;
- U32 seed;
- U32 v1;
- U32 v2;
- U32 v3;
- U32 v4;
- int memsize;
- char memory[16];
-};
-
-#if 0
-static
-int XXH32_sizeofState(void)
-{
- XXH_STATIC_ASSERT(XXH32_SIZEOFSTATE >= sizeof(struct XXH_state32_t)); /* A compilation error here means XXH32_SIZEOFSTATE is not large enough */
- return sizeof(struct XXH_state32_t);
-}
-#endif
-
-static
-XXH_errorcode XXH32_resetState(void* state_in, U32 seed)
-{
- struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
- state->seed = seed;
- state->v1 = seed + PRIME32_1 + PRIME32_2;
- state->v2 = seed + PRIME32_2;
- state->v3 = seed + 0;
- state->v4 = seed - PRIME32_1;
- state->total_len = 0;
- state->memsize = 0;
- return XXH_OK;
-}
-
-static
-void* XXH32_init (U32 seed)
-{
- void* state = XXH_malloc (sizeof(struct XXH_state32_t));
- XXH32_resetState(state, seed);
- return state;
-}
-
-static
-FORCE_INLINE XXH_errorcode XXH32_update_endian (void* state_in, const void* input, int len, XXH_endianess endian)
-{
- struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
- const BYTE* p = (const BYTE*)input;
- const BYTE* const bEnd = p + len;
-
-#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
- if (input==NULL) return XXH_ERROR;
-#endif
-
- state->total_len += len;
-
- if (state->memsize + len < 16) /* fill in tmp buffer */
- {
- XXH_memcpy(state->memory + state->memsize, input, len);
- state->memsize += len;
- return XXH_OK;
- }
-
- if (state->memsize) /* some data left from previous update */
- {
- XXH_memcpy(state->memory + state->memsize, input, 16-state->memsize);
- {
- const U32* p32 = (const U32*)state->memory;
- state->v1 += XXH_readLE32(p32, endian) * PRIME32_2; state->v1 = XXH_rotl32(state->v1, 13); state->v1 *= PRIME32_1; p32++;
- state->v2 += XXH_readLE32(p32, endian) * PRIME32_2; state->v2 = XXH_rotl32(state->v2, 13); state->v2 *= PRIME32_1; p32++;
- state->v3 += XXH_readLE32(p32, endian) * PRIME32_2; state->v3 = XXH_rotl32(state->v3, 13); state->v3 *= PRIME32_1; p32++;
- state->v4 += XXH_readLE32(p32, endian) * PRIME32_2; state->v4 = XXH_rotl32(state->v4, 13); state->v4 *= PRIME32_1; p32++;
- }
- p += 16-state->memsize;
- state->memsize = 0;
- }
-
- if (p <= bEnd-16)
- {
- const BYTE* const limit = bEnd - 16;
- U32 v1 = state->v1;
- U32 v2 = state->v2;
- U32 v3 = state->v3;
- U32 v4 = state->v4;
-
- do
- {
- v1 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4;
- v2 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4;
- v3 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4;
- v4 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4;
- } while (p<=limit);
-
- state->v1 = v1;
- state->v2 = v2;
- state->v3 = v3;
- state->v4 = v4;
- }
-
- if (p < bEnd)
- {
- XXH_memcpy(state->memory, p, bEnd-p);
- state->memsize = (int)(bEnd-p);
- }
-
- return XXH_OK;
-}
-
-static
-XXH_errorcode XXH32_update (void* state_in, const void* input, unsigned int len)
-{
- XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
-
- if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
- return XXH32_update_endian(state_in, input, len, XXH_littleEndian);
- else
- return XXH32_update_endian(state_in, input, len, XXH_bigEndian);
-}
-
-
-
-static
-FORCE_INLINE U32 XXH32_intermediateDigest_endian (void* state_in, XXH_endianess endian)
-{
- struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
- const BYTE * p = (const BYTE*)state->memory;
- BYTE* bEnd = (BYTE*)state->memory + state->memsize;
- U32 h32;
-
- if (state->total_len >= 16)
- {
- h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18);
- }
- else
- {
- h32 = state->seed + PRIME32_5;
- }
-
- h32 += (U32) state->total_len;
-
- while (p<=bEnd-4)
- {
- h32 += XXH_readLE32((const U32*)p, endian) * PRIME32_3;
- h32 = XXH_rotl32(h32, 17) * PRIME32_4;
- p+=4;
- }
-
- while (p<bEnd)
- {
- h32 += (*p) * PRIME32_5;
- h32 = XXH_rotl32(h32, 11) * PRIME32_1;
- p++;
- }
-
- h32 ^= h32 >> 15;
- h32 *= PRIME32_2;
- h32 ^= h32 >> 13;
- h32 *= PRIME32_3;
- h32 ^= h32 >> 16;
-
- return h32;
-}
-
-static
-U32 XXH32_intermediateDigest (void* state_in)
-{
- XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
-
- if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
- return XXH32_intermediateDigest_endian(state_in, XXH_littleEndian);
- else
- return XXH32_intermediateDigest_endian(state_in, XXH_bigEndian);
-}
-
-static
-U32 XXH32_digest (void* state_in)
-{
- U32 h32 = XXH32_intermediateDigest(state_in);
-
- XXH_free(state_in);
-
- return h32;
-}
-
-const
-struct archive_xxhash __archive_xxhash = {
- XXH32,
- XXH32_init,
- XXH32_update,
- XXH32_digest
-};
-#else
-
-/*
- * Define an empty version of the struct if we aren't using the LZ4 library.
- */
-const
-struct archive_xxhash __archive_xxhash = {
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-#endif /* HAVE_LIBLZ4 */
diff --git a/contrib/libs/libarchive/ya.make b/contrib/libs/libarchive/ya.make
deleted file mode 100644
index 1b89dda0b9..0000000000
--- a/contrib/libs/libarchive/ya.make
+++ /dev/null
@@ -1,183 +0,0 @@
-# Generated by devtools/yamaker from nixpkgs 22.11.
-
-LIBRARY()
-
-VERSION(3.7.1)
-
-ORIGINAL_SOURCE(https://github.com/libarchive/libarchive/archive/v3.7.1.tar.gz)
-
-LICENSE(
- "(CC0-1.0 OR OpenSSL OR Apache-2.0)" AND
- BSD-2-Clause AND
- BSD-3-Clause AND
- Bsd-Unchanged AND
- ISC AND
- PostgreSQL AND
- Public-Domain
-)
-
-LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-
-PEERDIR(
- contrib/libs/blake2
- contrib/libs/libbz2
- contrib/libs/lz4
- contrib/libs/openssl
- contrib/libs/zlib
- contrib/libs/zstd
-)
-
-ADDINCL(
- contrib/libs/blake2/include
- contrib/libs/libarchive
- contrib/libs/libarchive/libarchive
- contrib/libs/libbz2
- contrib/libs/lz4
- contrib/libs/zstd/include
-)
-
-NO_COMPILER_WARNINGS()
-
-NO_RUNTIME()
-
-CFLAGS(
- -DHAVE_CONFIG_H
-)
-
-SRCS(
- libarchive/archive_acl.c
- libarchive/archive_check_magic.c
- libarchive/archive_cmdline.c
- libarchive/archive_cryptor.c
- libarchive/archive_digest.c
- libarchive/archive_entry.c
- libarchive/archive_entry_copy_stat.c
- libarchive/archive_entry_link_resolver.c
- libarchive/archive_entry_sparse.c
- libarchive/archive_entry_stat.c
- libarchive/archive_entry_strmode.c
- libarchive/archive_entry_xattr.c
- libarchive/archive_getdate.c
- libarchive/archive_hmac.c
- libarchive/archive_match.c
- libarchive/archive_options.c
- libarchive/archive_pack_dev.c
- libarchive/archive_pathmatch.c
- libarchive/archive_ppmd7.c
- libarchive/archive_ppmd8.c
- libarchive/archive_random.c
- libarchive/archive_rb.c
- libarchive/archive_read.c
- libarchive/archive_read_add_passphrase.c
- libarchive/archive_read_append_filter.c
- libarchive/archive_read_data_into_fd.c
- libarchive/archive_read_disk_entry_from_file.c
- libarchive/archive_read_disk_posix.c
- libarchive/archive_read_disk_set_standard_lookup.c
- libarchive/archive_read_extract.c
- libarchive/archive_read_extract2.c
- libarchive/archive_read_open_fd.c
- libarchive/archive_read_open_file.c
- libarchive/archive_read_open_filename.c
- libarchive/archive_read_open_memory.c
- libarchive/archive_read_set_format.c
- libarchive/archive_read_set_options.c
- libarchive/archive_read_support_filter_all.c
- libarchive/archive_read_support_filter_by_code.c
- libarchive/archive_read_support_filter_bzip2.c
- libarchive/archive_read_support_filter_compress.c
- libarchive/archive_read_support_filter_grzip.c
- libarchive/archive_read_support_filter_gzip.c
- libarchive/archive_read_support_filter_lrzip.c
- libarchive/archive_read_support_filter_lz4.c
- libarchive/archive_read_support_filter_lzop.c
- libarchive/archive_read_support_filter_none.c
- libarchive/archive_read_support_filter_program.c
- libarchive/archive_read_support_filter_rpm.c
- libarchive/archive_read_support_filter_uu.c
- libarchive/archive_read_support_filter_xz.c
- libarchive/archive_read_support_filter_zstd.c
- libarchive/archive_read_support_format_7zip.c
- libarchive/archive_read_support_format_all.c
- libarchive/archive_read_support_format_ar.c
- libarchive/archive_read_support_format_by_code.c
- libarchive/archive_read_support_format_cab.c
- libarchive/archive_read_support_format_cpio.c
- libarchive/archive_read_support_format_empty.c
- libarchive/archive_read_support_format_iso9660.c
- libarchive/archive_read_support_format_lha.c
- libarchive/archive_read_support_format_mtree.c
- libarchive/archive_read_support_format_rar.c
- libarchive/archive_read_support_format_rar5.c
- libarchive/archive_read_support_format_raw.c
- libarchive/archive_read_support_format_tar.c
- libarchive/archive_read_support_format_warc.c
- libarchive/archive_read_support_format_xar.c
- libarchive/archive_read_support_format_zip.c
- libarchive/archive_string.c
- libarchive/archive_string_sprintf.c
- libarchive/archive_util.c
- libarchive/archive_version_details.c
- libarchive/archive_virtual.c
- libarchive/archive_write.c
- libarchive/archive_write_add_filter.c
- libarchive/archive_write_add_filter_b64encode.c
- libarchive/archive_write_add_filter_by_name.c
- libarchive/archive_write_add_filter_bzip2.c
- libarchive/archive_write_add_filter_compress.c
- libarchive/archive_write_add_filter_grzip.c
- libarchive/archive_write_add_filter_gzip.c
- libarchive/archive_write_add_filter_lrzip.c
- libarchive/archive_write_add_filter_lz4.c
- libarchive/archive_write_add_filter_lzop.c
- libarchive/archive_write_add_filter_none.c
- libarchive/archive_write_add_filter_program.c
- libarchive/archive_write_add_filter_uuencode.c
- libarchive/archive_write_add_filter_xz.c
- libarchive/archive_write_add_filter_zstd.c
- libarchive/archive_write_disk_posix.c
- libarchive/archive_write_disk_set_standard_lookup.c
- libarchive/archive_write_open_fd.c
- libarchive/archive_write_open_file.c
- libarchive/archive_write_open_filename.c
- libarchive/archive_write_open_memory.c
- libarchive/archive_write_set_format.c
- libarchive/archive_write_set_format_7zip.c
- libarchive/archive_write_set_format_ar.c
- libarchive/archive_write_set_format_by_name.c
- libarchive/archive_write_set_format_cpio.c
- libarchive/archive_write_set_format_cpio_binary.c
- libarchive/archive_write_set_format_cpio_newc.c
- libarchive/archive_write_set_format_cpio_odc.c
- libarchive/archive_write_set_format_filter_by_ext.c
- libarchive/archive_write_set_format_gnutar.c
- libarchive/archive_write_set_format_iso9660.c
- libarchive/archive_write_set_format_mtree.c
- libarchive/archive_write_set_format_pax.c
- libarchive/archive_write_set_format_raw.c
- libarchive/archive_write_set_format_shar.c
- libarchive/archive_write_set_format_ustar.c
- libarchive/archive_write_set_format_v7tar.c
- libarchive/archive_write_set_format_warc.c
- libarchive/archive_write_set_format_xar.c
- libarchive/archive_write_set_format_zip.c
- libarchive/archive_write_set_options.c
- libarchive/archive_write_set_passphrase.c
- libarchive/filter_fork_posix.c
- libarchive/xxhash.c
-)
-
-IF (OS_WINDOWS)
- CFLAGS(
- GLOBAL -DLIBARCHIVE_STATIC
- )
- SRCS(
- libarchive/archive_entry_copy_bhfi.c
- libarchive/archive_read_disk_windows.c
- libarchive/archive_windows.c
- libarchive/archive_write_disk_windows.c
- libarchive/filter_fork_windows.c
- )
-ENDIF()
-
-END()
diff --git a/contrib/libs/linux-headers/linux/fiemap.h b/contrib/libs/linux-headers/linux/fiemap.h
deleted file mode 100644
index 7a900b2377..0000000000
--- a/contrib/libs/linux-headers/linux/fiemap.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- * FS_IOC_FIEMAP ioctl infrastructure.
- *
- * Some portions copyright (C) 2007 Cluster File Systems, Inc
- *
- * Authors: Mark Fasheh <mfasheh@suse.com>
- * Kalpak Shah <kalpak.shah@sun.com>
- * Andreas Dilger <adilger@sun.com>
- */
-
-#ifndef _LINUX_FIEMAP_H
-#define _LINUX_FIEMAP_H
-
-#include <linux/types.h>
-
-struct fiemap_extent {
- __u64 fe_logical; /* logical offset in bytes for the start of
- * the extent from the beginning of the file */
- __u64 fe_physical; /* physical offset in bytes for the start
- * of the extent from the beginning of the disk */
- __u64 fe_length; /* length in bytes for this extent */
- __u64 fe_reserved64[2];
- __u32 fe_flags; /* FIEMAP_EXTENT_* flags for this extent */
- __u32 fe_reserved[3];
-};
-
-struct fiemap {
- __u64 fm_start; /* logical offset (inclusive) at
- * which to start mapping (in) */
- __u64 fm_length; /* logical length of mapping which
- * userspace wants (in) */
- __u32 fm_flags; /* FIEMAP_FLAG_* flags for request (in/out) */
- __u32 fm_mapped_extents;/* number of extents that were mapped (out) */
- __u32 fm_extent_count; /* size of fm_extents array (in) */
- __u32 fm_reserved;
- struct fiemap_extent fm_extents[]; /* array of mapped extents (out) */
-};
-
-#define FIEMAP_MAX_OFFSET (~0ULL)
-
-#define FIEMAP_FLAG_SYNC 0x00000001 /* sync file data before map */
-#define FIEMAP_FLAG_XATTR 0x00000002 /* map extended attribute tree */
-#define FIEMAP_FLAG_CACHE 0x00000004 /* request caching of the extents */
-
-#define FIEMAP_FLAGS_COMPAT (FIEMAP_FLAG_SYNC | FIEMAP_FLAG_XATTR)
-
-#define FIEMAP_EXTENT_LAST 0x00000001 /* Last extent in file. */
-#define FIEMAP_EXTENT_UNKNOWN 0x00000002 /* Data location unknown. */
-#define FIEMAP_EXTENT_DELALLOC 0x00000004 /* Location still pending.
- * Sets EXTENT_UNKNOWN. */
-#define FIEMAP_EXTENT_ENCODED 0x00000008 /* Data can not be read
- * while fs is unmounted */
-#define FIEMAP_EXTENT_DATA_ENCRYPTED 0x00000080 /* Data is encrypted by fs.
- * Sets EXTENT_NO_BYPASS. */
-#define FIEMAP_EXTENT_NOT_ALIGNED 0x00000100 /* Extent offsets may not be
- * block aligned. */
-#define FIEMAP_EXTENT_DATA_INLINE 0x00000200 /* Data mixed with metadata.
- * Sets EXTENT_NOT_ALIGNED.*/
-#define FIEMAP_EXTENT_DATA_TAIL 0x00000400 /* Multiple files in block.
- * Sets EXTENT_NOT_ALIGNED.*/
-#define FIEMAP_EXTENT_UNWRITTEN 0x00000800 /* Space allocated, but
- * no data (i.e. zero). */
-#define FIEMAP_EXTENT_MERGED 0x00001000 /* File does not natively
- * support extents. Result
- * merged for efficiency. */
-#define FIEMAP_EXTENT_SHARED 0x00002000 /* Space shared with other
- * files. */
-
-#endif /* _LINUX_FIEMAP_H */
diff --git a/contrib/libs/pcre2/AUTHORS b/contrib/libs/pcre2/AUTHORS
deleted file mode 100644
index 11ef898b25..0000000000
--- a/contrib/libs/pcre2/AUTHORS
+++ /dev/null
@@ -1,36 +0,0 @@
-THE MAIN PCRE2 LIBRARY CODE
----------------------------
-
-Written by: Philip Hazel
-Email local part: Philip.Hazel
-Email domain: gmail.com
-
-Retired from University of Cambridge Computing Service,
-Cambridge, England.
-
-Copyright (c) 1997-2022 University of Cambridge
-All rights reserved
-
-
-PCRE2 JUST-IN-TIME COMPILATION SUPPORT
---------------------------------------
-
-Written by: Zoltan Herczeg
-Email local part: hzmester
-Emain domain: freemail.hu
-
-Copyright(c) 2010-2022 Zoltan Herczeg
-All rights reserved.
-
-
-STACK-LESS JUST-IN-TIME COMPILER
---------------------------------
-
-Written by: Zoltan Herczeg
-Email local part: hzmester
-Emain domain: freemail.hu
-
-Copyright(c) 2009-2022 Zoltan Herczeg
-All rights reserved.
-
-####
diff --git a/contrib/libs/pcre2/COPYING b/contrib/libs/pcre2/COPYING
deleted file mode 100644
index c233950f6f..0000000000
--- a/contrib/libs/pcre2/COPYING
+++ /dev/null
@@ -1,5 +0,0 @@
-PCRE2 LICENCE
-
-Please see the file LICENCE in the PCRE2 distribution for licensing details.
-
-End
diff --git a/contrib/libs/pcre2/ChangeLog b/contrib/libs/pcre2/ChangeLog
deleted file mode 100644
index 2b100361e8..0000000000
--- a/contrib/libs/pcre2/ChangeLog
+++ /dev/null
@@ -1,2827 +0,0 @@
-Change Log for PCRE2 - see also the Git log
--------------------------------------------
-
-
-Version 10.42 11-December-2022
-------------------------------
-
-1. Change 19 of 10.41 wasn't quite right; it put the definition of a default,
-empty value for PCRE2_CALL_CONVENTION in src/pcre2posix.c instead of
-src/pcre2posix.h, which meant that programs that included pcre2posix.h but not
-pcre2.h failed to compile.
-
-2. To catch similar issues to the above in future, a new small test program
-that includes pcre2posix.h but not pcre2.h has been added to the test suite.
-
-3. When the -S option of pcre2test was used to set a stack size greater than
-the allowed maximum, the error message displayed the hard limit incorrectly.
-This was pointed out on GitHub pull request #171, but the suggested patch
-didn't cope with all cases. Some further modification was required.
-
-4. Supplying an ovector count of more than 65535 to pcre2_match_data_create()
-caused a crash because the field in the match data block is only 16 bits. A
-maximum of 65535 is now silently applied.
-
-5. Merged @carenas patch #175 which fixes #86 - segfault on aarch64 (ARM),
-
-
-Version 10.41 06-December-2022
-------------------------------
-
-1. Add fflush() before and after a fork callout in pcre2grep to get its output
-to be the same on all systems. (There were previously ordering differences in
-Alpine Linux).
-
-2. Merged patch from @carenas (GitHub #110) for pthreads support in CMake.
-
-3. SSF scorecards grumbled about possible overflow in an expression in
-pcre2test. It never would have overflowed in practice, but some casts have been
-added and at the some time there's been some tidying of fprints that output
-size_t values.
-
-4. PR #94 showed up an unused enum in pcre2_convert.c, which is now removed.
-
-5. Minor code re-arrangement to remove gcc warning about realloc() in
-pcre2test.
-
-6. Change a number of int variables that hold buffer and line lengths in
-pcre2grep to PCRE2_SIZE (aka size_t).
-
-7. Added an #ifdef to cut out a call to PRIV(jit_free) when JIT is not
-supported (even though that function would do nothing in that case) at the
-request of a user who doesn't even want to link with pcre_jit_compile.o. Also
-tidied up an untidy #ifdef arrangement in pcre2test.
-
-8. Fixed an issue in the backtracking optimization of character repeats in
-JIT. Furthermore optimize star repetitions, not just plus repetitions.
-
-9. Removed the use of an initial backtracking frames vector on the system stack
-in pcre2_match() so that it now always uses the heap. (In a multi-thread
-environment with very small stacks there had been an issue.) This also is
-tidier for JIT matching, which didn't need that vector. The heap vector is now
-remembered in the match data block and re-used if that block itself is re-used.
-It is freed with the match data block.
-
-10. Adjusted the find_limits code in pcre2test to work with change 9 above.
-
-11. Added find_limits_noheap to pcre2test, because the heap limits are now
-different in different environments and so cannot be included in the standard
-tests.
-
-12. Created a test for pcre2_match() heap processing that is not part of the
-tests run by 'make check', but can be run manually. The current output is from
-a 64-bit system.
-
-13. Implemented -Z aka --null in pcre2grep.
-
-14. A minor change to pcre2test and the addition of several new pcre2grep tests
-have improved LCOV coverage statistics. At the same time, code in pcre2grep and
-elsewhere that can never be obeyed in normal testing has been excluded from
-coverage.
-
-15. Fixed a bug in pcre2grep that could cause an extra newline to be written
-after output generaed by --output.
-
-16. If a file has a .bz2 extension but is not in fact compressed, pcre2grep
-should process it as a plain text file. A bug stopped this happening; now fixed
-and added to the tests.
-
-17. When pcre2grep was running not in UTF mode, if a string specified by
---output or obtained from a callout in a pattern contained a character (byte)
-greater than 127, it was incorrectly output in UTF-8 format.
-
-18. Added some casts after warnings from Clang sanitize.
-
-19. Merged patch from cbouc (GitHub #139): 4 function prototypes were missing
-PCRE2_CALL_CONVENTION in src/pcre2posix.h. All function prototypes returning
-pointers had out of place PCRE2_CALL_CONVENTION in src/pcre2.h.*. These
-produced errors when building for Windows with #define PCRE2_CALL_CONVENTION
-__stdcall.
-
-20. A negative repeat value in a pcre2test subject line was not being
-diagnosed, leading to infinite looping.
-
-21. Updated RunGrepTest to discard the warning that Bash now gives when setting
-LC_CTYPE to a bad value (because older versions didn't).
-
-22. Updated pcre2grep so that it behaves like GNU grep when matching more than
-one pattern and a later pattern matches at an earlier point in the subject when
-the matched substrings are being identified by colour or by offsets.
-
-23. Updated the PrepareRelease script so that the man page that it makes for
-the pcre2demo demonstration program is more standard and does not cause errors
-when processed by lexgrog or mandb -c (GitHub issue #160).
-
-24. The JIT compiler was updated.
-
-
-Version 10.40 15-April-2022
----------------------------
-
-1. Merged patch from @carenas (GitHub #35, 7db87842) to fix pcre2grep incorrect
-handling of multiple passes.
-
-2. Merged patch from @carenas (GitHub #36, dae47509) to fix portability issue
-in pcre2grep with buffered fseek(stdin).
-
-3. Merged patch from @carenas (GitHub #37, acc520924) to fix tests when -S is
-not supported.
-
-4. Revert an unintended change in JIT repeat detection.
-
-5. Merged patch from @carenas (GitHub #52, b037bfa1) to fix build on GNU Hurd.
-
-6. Merged documentation and comments patches from @carenas (GitHub #47).
-
-7. Merged patch from @carenas (GitHub #49) to remove obsolete JFriedl test code
-from pcre2grep.
-
-8. Merged patch from @carenas (GitHub #48) to fix CMake install issue #46.
-
-9. Merged patch from @carenas (GitHub #53) fixing NULL checks in matching and
-substituting.
-
-10. Add null_subject and null_replacement modifiers to pcre2test.
-
-11. Add check for NULL subject to POSIX regexec() function.
-
-12. Add check for NULL replacement to pcre2_substitute().
-
-13. For the subject arguments of pcre2_match(), pcre2_dfa_match(), and
-pcre2_substitute(), and the replacement argument of the latter, if the pointer
-is NULL and the length is zero, treat as an empty string. Apparently a number
-of applications treat NULL/0 in this way.
-
-14. Added support for Bidi_Class and a number of binary Unicode properties,
-including Bidi_Control.
-
-15. Fix some minor issues raised by clang sanitize.
-
-16. Very minor code speed up for maximizing character property matches.
-
-17. A number of changes to script matching for \p and \P:
-
- (a) Script extensions for a character are now coded as a bitmap instead of
- a list of script numbers, which should be faster and does not need a
- loop.
-
- (b) Added the syntax \p{script:xxx} and \p{script_extensions:xxx} (synonyms
- sc and scx).
-
- (c) Changed \p{scriptname} from being the same as \p{sc:scriptname} to being
- the same as \p{scx:scriptname} because this change happened in Perl at
- release 5.26.
-
- (d) The standard Unicode 4-letter abbreviations for script names are now
- recognized.
-
- (e) In accordance with Unicode and Perl's "loose matching" rules, spaces,
- hyphens, and underscores are ignored in property names, which are then
- matched independent of case.
-
-18. The Python scripts in the maint directory have been refactored. There are
-now three scripts that generate pcre2_ucd.c, pcre2_ucp.h, and pcre2_ucptables.c
-(which is #included by pcre2_tables.c). The data lists that used to be
-duplicated are now held in a single common Python module.
-
-19. On CHERI, and thus Arm's Morello prototype, pointers are represented as
-hardware capabilities, which consist of both an integer address and additional
-metadata, meaning they are twice the size of the platform's size_t type, i.e.
-16 bytes on a 64-bit system. The ovector member of heapframe happens to only be
-8 byte aligned, and so computing frame_size ended up with a multiple of 8 but
-not 16. Whilst the first frame was always suitably aligned, this then
-misaligned the frame that follows, resulting in an alignment fault when storing
-a pointer to Fecode at the start of match. Patch to fix this issue by Jessica
-Clarke PR#72.
-
-20. Added -LP and -LS listing options to pcre2test.
-
-21. A user discovered that the library names in CMakeLists.txt for MSVC
-debugger (PDB) files were incorrect - perhaps never tried for PCRE2?
-
-22. An item such as [Aa] is optimized into a caseless single character match.
-When this was quantified (e.g. [Aa]{2}) and was also the last literal item in a
-pattern, the optimizing "must be present for a match" character check was not
-being flagged as caseless, causing some matches that should have succeeded to
-fail.
-
-23. Fixed a unicode property matching issue in JIT. The character was not
-fully read in caseless matching.
-
-24. Fixed an issue affecting recursions in JIT caused by duplicated data
-transfers.
-
-25. Merged patch from @carenas (GitHub #96) which fixes some problems with
-pcre2test and readline/readedit:
-
- * Use the right header for libedit in FreeBSD with autoconf
- * Really allow libedit with cmake
- * Avoid using readline headers with libedit
-
-
-Version 10.39 29-October-2021
------------------------------
-
-1. Fix incorrect detection of alternatives in first character search in JIT.
-
-2. Merged patch from @carenas (GitHub #28):
-
- Visual Studio 2013 includes support for %zu and %td, so let newer
- versions of it avoid the fallback, and while at it, make sure that
- the first check is for DISABLE_PERCENT_ZT so it will be always
- honoured if chosen.
-
- prtdiff_t is signed, so use a signed type instead, and make sure
- that an appropriate width is chosen if pointers are 64bit wide and
- long is not (ex: Windows 64bit).
-
- IMHO removing the cast (and therefore the possibilty of truncation)
- make the code cleaner and the fallback is likely portable enough
- with all 64-bit POSIX systems doing LP64 except for Windows.
-
-3. Merged patch from @carenas (GitHub #29) to update to Unicode 14.0.0.
-
-4. Merged patch from @carenas (GitHub #30):
-
- * Cleanup: remove references to no longer used stdint.h
-
- Since 19c50b9d (Unconditionally use inttypes.h instead of trying for stdint.h
- (simplification) and remove the now unnecessary inclusion in
- pcre2_internal.h., 2018-11-14), stdint.h is no longer used.
-
- Remove checks for it in autotools and CMake and document better the expected
- build failures for systems that might have stdint.h (C99) and not inttypes.h
- (from POSIX), like old Windows.
-
- * Cleanup: remove detection for inttypes.h which is a hard dependency
-
- CMake checks for standard headers are not meant to be used for hard
- dependencies, so will prevent a possible fallback to work.
-
- Alternatively, the header could be checked to make the configuration fail
- instead of breaking the build, but that was punted, as it was missing anyway
- from autotools.
-
-5. Merged patch from @carenas (GitHub #32):
-
- * jit: allow building with ancient MSVC versions
-
- Visual Studio older than 2013 fails to build with JIT enabled, because it is
- unable to parse non C89 compatible syntax, with mixed declarations and code.
- While most recent compilers wouldn't even report this as a warning since it
- is valid C99, it could be also made visible by adding to gcc/clang the
- -Wdeclaration-after-statement flag at build time.
-
- Move the code below the affected definitions.
-
- * pcre2grep: avoid mixing declarations with code
-
- Since d5a61ee8 (Patch to detect (and ignore) symlink loops in pcre2grep,
- 2021-08-28), code will fail to build in a strict C89 compiler.
-
- Reformat slightly to make it C89 compatible again.
-
-
-Version 10.38 01-October-2021
------------------------------
-
-1. Fix invalid single character repetition issues in JIT when the repetition
-is inside a capturing bracket and the bracket is preceded by character
-literals.
-
-2. Installed revised CMake configuration files provided by Jan-Willem Blokland.
-This extends the CMake build system to build both static and shared libraries
-in one go, builds the static library with PIC, and exposes PCRE2 libraries
-using the CMake config files. JWB provided these notes:
-
-- Introduced CMake variable BUILD_STATIC_LIBS to build the static library.
-
-- Make a small modification to config-cmake.h.in by removing the PCRE2_STATIC
- variable. Added PCRE2_STATIC variable to the static build using the
- target_compile_definitions() function.
-
-- Extended the CMake config files.
-
- - Introduced CMake variable PCRE2_USE_STATIC_LIBS to easily switch between
- the static and shared libraries.
-
- - Added the PCRE_STATIC variable to the target compile definitions for the
- import of the static library.
-
-Building static and shared libraries using MSVC results in a name clash of
-the libraries. Both static and shared library builds create, for example, the
-file pcre2-8.lib. Therefore, I decided to change the static library names by
-adding "-static". For example, pcre2-8.lib has become pcre2-8-static.lib.
-[Comment by PH: this is MSVC-specific. It doesn't happen on Linux.]
-
-3. Increased the minimum release number for CMake to 3.0.0 because older than
-2.8.12 is deprecated (it was set to 2.8.5) and causes warnings. Even 3.0.0 is
-quite old; it was released in 2014.
-
-4. Implemented a modified version of Thomas Tempelmann's pcre2grep patch for
-detecting symlink loops. This is dependent on the availability of realpath(),
-which is now tested for in ./configure and CMakeLists.txt.
-
-5. Implemented a modified version of Thomas Tempelmann's patch for faster
-case-independent "first code unit" searches for unanchored patterns in 8-bit
-mode in the interpreters. Instead of just remembering whether one case matched
-or not, it remembers the position of a previous match so as to avoid
-unnecessary repeated searching.
-
-6. Perl now locks out \K in lookarounds, so PCRE2 now does the same by default.
-However, just in case anybody was relying on the old behaviour, there is an
-option called PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK that enables the old behaviour.
-An option has also been added to pcre2grep to enable this.
-
-7. Re-enable a JIT optimization which was unintentionally disabled in 10.35.
-
-8. There is a loop counter to catch excessively crazy patterns when checking
-the lengths of lookbehinds at compile time. This was incorrectly getting reset
-whenever a lookahead was processed, leading to some fuzzer-generated patterns
-taking a very long time to compile when (?|) was present in the pattern,
-because (?|) disables caching of group lengths.
-
-
-Version 10.37 26-May-2021
--------------------------
-
-1. Change RunGrepTest to use tr instead of sed when testing with binary
-zero bytes, because sed varies a lot from system to system and has problems
-with binary zeros. This is from Bugzilla #2681. Patch from Jeremie
-Courreges-Anglas via Nam Nguyen. This fixes RunGrepTest for OpenBSD. Later:
-it broke it for at least one version of Solaris, where tr can't handle binary
-zeros. However, that system had /usr/xpg4/bin/tr installed, which works OK, so
-RunGrepTest now checks for that command and uses it if found.
-
-2. Compiling with gcc 10.2's -fanalyzer option showed up a hypothetical problem
-with a NULL dereference. I don't think this case could ever occur in practice,
-but I have put in a check in order to get rid of the compiler error.
-
-3. An alternative patch for CMakeLists.txt because 10.36 #4 breaks CMake on
-Windows. Patch from email@cs-ware.de fixes bugzilla #2688.
-
-4. Two bugs related to over-large numbers have been fixed so the behaviour is
-now the same as Perl.
-
- (a) A pattern such as /\214748364/ gave an overflow error instead of being
- treated as the octal number \214 followed by literal digits.
-
- (b) A sequence such as {65536 that has no terminating } so is not a
- quantifier was nevertheless complaining that a quantifier number was too big.
-
-5. A run of autoconf suggested that configure.ac was out-of-date with respect
-to the lastest autoconf. Running autoupdate made some valid changes, some valid
-suggestions, and also some invalid changes, which were fixed by hand. Autoconf
-now runs clean and the resulting "configure" seems to work, so I hope nothing
-is broken. Later: the requirement for autoconf 2.70 broke some automatic test
-robots. It doesn't seem to be necessary: trying a reduction to 2.60.
-
-6. The pattern /a\K.(?0)*/ when matched against "abac" by the interpreter gave
-the answer "bac", whereas Perl and JIT both yield "c". This was because the
-effect of \K was not propagating back from the full pattern recursion. Other
-recursions such as /(a\K.(?1)*)/ did not have this problem.
-
-7. Restore single character repetition optimization in JIT. Currently fewer
-character repetitions are optimized than in 10.34.
-
-8. When the names of the functions in the POSIX wrapper were changed to
-pcre2_regcomp() etc. (see change 10.33 #4 below), functions with the original
-names were left in the library so that pre-compiled programs would still work.
-However, this has proved troublesome when programs link with several libraries,
-some of which use PCRE2 via the POSIX interface while others use a native POSIX
-library. For this reason, the POSIX function names are removed in this release.
-The macros in pcre2posix.h should ensure that re-compiling fixes any programs
-that haven't been compiled since before 10.33.
-
-
-Version 10.36 04-December-2020
-------------------------------
-
-1. Add CET_CFLAGS so that when Intel CET is enabled, pass -mshstk to
-compiler. This fixes https://bugs.exim.org/show_bug.cgi?id=2578. Patch for
-Makefile.am and configure.ac by H.J. Lu. Equivalent patch for CMakeLists.txt
-invented by PH.
-
-2. Fix inifinite loop when a single byte newline is searched in JIT when
-invalid utf8 mode is enabled.
-
-3. Updated CMakeLists.txt with patch from Wolfgang Stöggl (Bugzilla #2584):
-
- - Include GNUInstallDirs and use ${CMAKE_INSTALL_LIBDIR} instead of hardcoded
- lib. This allows differentiation between lib and lib64.
- CMAKE_INSTALL_LIBDIR is used for installation of libraries and also for
- pkgconfig file generation.
-
- - Add the version of PCRE2 to the configuration summary like ./configure
- does.
-
- - Fix typo: MACTHED_STRING->MATCHED_STRING
-
-4. Updated CMakeLists.txt with another patch from Wolfgang Stöggl (Bugzilla
-#2588):
-
- - Add escaped double quotes around include directory in CMakeLists.txt to
- allow spaces in directory names.
-
- - This fixes a cmake error, if the path of the pcre2 source contains a space.
-
-5. Updated CMakeLists.txt with a patch from B. Scott Michel: CMake's
-documentation suggests using CHECK_SYMBOL_EXISTS over CHECK_FUNCTION_EXIST.
-Moreover, these functions come from specific header files, which need to be
-specified (and, thankfully, are the same on both the Linux and WinXX
-platforms.)
-
-6. Added a (uint32_t) cast to prevent a compiler warning in pcre2_compile.c.
-
-7. Applied a patch from Wolfgang Stöggl (Bugzilla #2600) to fix postfix for
-debug Windows builds using CMake. This also updated configure so that it
-generates *.pc files and pcre2-config with the same content, as in the past.
-
-8. If a pattern ended with (?(VERSION=n.d where n is any number but d is just a
-single digit, the code unit beyond d was being read (i.e. there was a read
-buffer overflow). Fixes ClusterFuzz 23779.
-
-9. After the rework in r1235, certain character ranges were incorrectly
-handled by an optimization in JIT. Furthermore a wrong offset was used to
-read a value from a buffer which could lead to memory overread.
-
-10. Unnoticed for many years was the fact that delimiters other than / in the
-testinput1 and testinput4 files could cause incorrect behaviour when these
-files were processed by perltest.sh. There were several tests that used quotes
-as delimiters, and it was just luck that they didn't go wrong with perltest.sh.
-All the patterns in testinput1 and testinput4 now use / as their delimiter.
-This fixes Bugzilla #2641.
-
-11. Perl has started to give an error for \K within lookarounds (though there
-are cases where it doesn't). PCRE2 still allows this, so the tests that include
-this case have been moved from test 1 to test 2.
-
-12. Further to 10 above, pcre2test has been updated to detect and grumble if a
-delimiter other than / is used after #perltest.
-
-13. Fixed a bug with PCRE2_MATCH_INVALID_UTF in 8-bit mode when PCRE2_CASELESS
-was set and PCRE2_NO_START_OPTIMIZE was not set. The optimization for finding
-the start of a match was not resetting correctly after a failed match on the
-first valid fragment of the subject, possibly causing incorrect "no match"
-returns on subsequent fragments. For example, the pattern /A/ failed to match
-the subject \xe5A. Fixes Bugzilla #2642.
-
-14. Fixed a bug in character set matching when JIT is enabled and both unicode
-scripts and unicode classes are present at the same time.
-
-15. Added GNU grep's -m (aka --max-count) option to pcre2grep.
-
-16. Refactored substitution processing in pcre2grep strings, both for the -O
-option and when dealing with callouts. There is now a single function that
-handles $ expansion in all cases (instead of multiple copies of almost
-identical code). This means that the same escape sequences are available
-everywhere, which was not previously the case. At the same time, the escape
-sequences $x{...} and $o{...} have been introduced, to allow for characters
-whose code points are greater than 255 in Unicode mode.
-
-17. Applied the patch from Bugzilla #2628 to RunGrepTest. This does an explicit
-test for a version of sed that can handle binary zero, instead of assuming that
-any Linux version will work. Later: replaced $(...) by `...` because not all
-shells recognize the former.
-
-18. Fixed a word boundary check bug in JIT when partial matching is enabled.
-
-19. Fix ARM64 compilation warning in JIT. Patch by Carlo.
-
-20. A bug in the RunTest script meant that if the first part of test 2 failed,
-the failure was not reported.
-
-21. Test 2 was failing when run from a directory other than the source
-directory. This failure was previously missed in RunTest because of 20 above.
-Fixes added to both RunTest and RunTest.bat.
-
-22. Patch to CMakeLists.txt from Daniel to fix problem with testing under
-Windows.
-
-
-Version 10.35 09-May-2020
----------------------------
-
-1. Use PCRE2_MATCH_EMPTY flag to detect empty matches in JIT.
-
-2. Fix ARMv5 JIT improper handling of labels right after a constant pool.
-
-3. A JIT bug is fixed which allowed to read the fields of the compiled
-pattern before its existence is checked.
-
-4. Back in the PCRE1 day, capturing groups that contained recursive back
-references to themselves were made atomic (version 8.01, change 18) because
-after the end a repeated group, the captured substrings had their values from
-the final repetition, not from an earlier repetition that might be the
-destination of a backtrack. This feature was documented, and was carried over
-into PCRE2. However, it has now been realized that the major refactoring that
-was done for 10.30 has made this atomicizing unnecessary, and it is confusing
-when users are unaware of it, making some patterns appear not to be working as
-expected. Capture values of recursive back references in repeated groups are
-now correctly backtracked, so this unnecessary restriction has been removed.
-
-5. Added PCRE2_SUBSTITUTE_LITERAL.
-
-6. Avoid some VS compiler warnings.
-
-7. Added PCRE2_SUBSTITUTE_MATCHED.
-
-8. Added (?* and (?<* as synonyms for (*napla: and (*naplb: to match another
-regex engine. The Perl regex folks are aware of this usage and have made a note
-about it.
-
-9. When an assertion is repeated, PCRE2 used to limit the maximum repetition to
-1, believing that repeating an assertion is pointless. However, if a positive
-assertion contains capturing groups, repetition can be useful. In any case, an
-assertion could always be wrapped in a repeated group. The only restriction
-that is now imposed is that an unlimited maximum is changed to one more than
-the minimum.
-
-10. Fix *THEN verbs in lookahead assertions in JIT.
-
-11. Added PCRE2_SUBSTITUTE_REPLACEMENT_ONLY.
-
-12. The JIT stack should be freed when the low-level stack allocation fails.
-
-13. In pcre2grep, if the final line in a scanned file is output but does not
-end with a newline sequence, add a newline according to the --newline setting.
-
-14. (?(DEFINE)...) groups were not being handled correctly when checking for
-the fixed length of a lookbehind assertion. Such a group within a lookbehind
-should be skipped, as it does not contribute to the length of the group.
-Instead, the (DEFINE) group was being processed, and if at the end of the
-lookbehind, that end was not correctly recognized. Errors such as "lookbehind
-assertion is not fixed length" and also "internal error: bad code value in
-parsed_skip()" could result.
-
-15. Put a limit of 1000 on recursive calls in pcre2_study() when searching
-nested groups for starting code units, in order to avoid stack overflow issues.
-If the limit is reached, it just gives up trying for this optimization.
-
-16. The control verb chain list must always be restored when exiting from a
-recurse function in JIT.
-
-17. Fix a crash which occurs when the character type of an invalid UTF
-character is decoded in JIT.
-
-18. Changes in many areas of the code so that when Unicode is supported and
-PCRE2_UCP is set without PCRE2_UTF, Unicode character properties are used for
-upper/lower case computations on characters whose code points are greater than
-127.
-
-19. The function for checking UTF-16 validity was returning an incorrect offset
-for the start of the error when a high surrogate was not followed by a valid
-low surrogate. This caused incorrect behaviour, for example when
-PCRE2_MATCH_INVALID_UTF was set and a match started immediately following the
-invalid high surrogate, such as /aa/ matching "\x{d800}aa".
-
-20. If a DEFINE group immediately preceded a lookbehind assertion, the pattern
-could be mis-compiled and therefore not match correctly. This is the example
-that found this: /(?(DEFINE)(?<foo>bar))(?<![-a-z0-9])word/ which failed to
-match "word" because the "move back" value was set to zero.
-
-21. Following a request from a user, some extensions and tidies to the
-character tables handling have been done:
-
- (a) The dftables auxiliary program is renamed pcre2_dftables, but it is still
- not installed for public use.
-
- (b) There is now a -b option for pcre2_dftables, which causes the tables to
- be written in binary. There is also a -help option.
-
- (c) PCRE2_CONFIG_TABLES_LENGTH is added to pcre2_config() so that an
- application that wants to save tables in binary knows how long they are.
-
-22. Changed setting of CMAKE_MODULE_PATH in CMakeLists.txt from SET to
-LIST(APPEND...) to allow a setting from the command line to be included.
-
-23. Updated to Unicode 13.0.0.
-
-24. CMake build now checks for secure_getenv() and strerror(). Patch by Carlo.
-
-25. Avoid using [-1] as a suffix in pcre2test because it can provoke a compiler
-warning.
-
-26. Added tests for __attribute__((uninitialized)) to both the configure and
-CMake build files, and then applied this attribute to the variable called
-stack_frames_vector[] in pcre2_match(). When implemented, this disables
-automatic initialization (a facility in clang), which can take time on big
-variables.
-
-27. Updated CMakeLists.txt (patches by Uwe Korn) to add support for
-pcre2-config, the libpcre*.pc files, SOVERSION, VERSION and the
-MACHO_*_VERSIONS settings for CMake builds.
-
-28. Another patch to CMakeLists.txt to check for mkostemp (configure already
-does). Patch by Carlo Marcelo Arenas Belon.
-
-29. Check for the existence of memfd_create in both CMake and configure
-configurations. Patch by Carlo Marcelo Arenas Belon.
-
-30. Restrict the configuration setting for the SELinux compatible execmem
-allocator (change 10.30/44) to Linux and NetBSD.
-
-
-Version 10.34 21-November-2019
-------------------------------
-
-1. The maximum number of capturing subpatterns is 65535 (documented), but no
-check on this was ever implemented. This omission has been rectified; it fixes
-ClusterFuzz 14376.
-
-2. Improved the invalid utf32 support of the JIT compiler. Now it correctly
-detects invalid characters in the 0xd800-0xdfff range.
-
-3. Fix minor typo bug in JIT compile when \X is used in a non-UTF string.
-
-4. Add support for matching in invalid UTF strings to the pcre2_match()
-interpreter, and integrate with the existing JIT support via the new
-PCRE2_MATCH_INVALID_UTF compile-time option.
-
-5. Give more error detail for invalid UTF-8 when detected in pcre2grep.
-
-6. Add support for invalid UTF-8 to pcre2grep.
-
-7. Adjust the limit for "must have" code unit searching, in particular,
-increase it substantially for non-anchored patterns.
-
-8. Allow (*ACCEPT) to be quantified, because an ungreedy quantifier with a zero
-minimum is potentially useful.
-
-9. Some changes to the way the minimum subject length is handled:
-
- * When PCRE2_NO_START_OPTIMIZE is set, no minimum length is computed;
- pcre2test now omits this item instead of showing a value of zero.
-
- * An incorrect minimum length could be calculated for a pattern that
- contained (*ACCEPT) inside a qualified group whose minimum repetition was
- zero, for example /A(?:(*ACCEPT))?B/, which incorrectly computed a minimum
- of 2. The minimum length scan no longer happens for a pattern that
- contains (*ACCEPT).
-
- * When no minimum length is set by the normal scan, but a first and/or last
- code unit is recorded, set the minimum to 1 or 2 as appropriate.
-
- * When a pattern contains multiple groups with the same number, a back
- reference cannot know which one to scan for a minimum length. This used to
- cause the minimum length finder to give up with no result. Now it treats
- such references as not adding to the minimum length (which it should have
- done all along).
-
- * Furthermore, the above action now happens only if the back reference is to
- a group that exists more than once in a pattern instead of any back
- reference in a pattern with duplicate numbers.
-
-10. A (*MARK) value inside a successful condition was not being returned by the
-interpretive matcher (it was returned by JIT). This bug has been mended.
-
-11. A bug in pcre2grep meant that -o without an argument (or -o0) didn't work
-if the pattern had more than 32 capturing parentheses. This is fixed. In
-addition (a) the default limit for groups requested by -o<n> has been raised to
-50, (b) the new --om-capture option changes the limit, (c) an error is raised
-if -o asks for a group that is above the limit.
-
-12. The quantifier {1} was always being ignored, but this is incorrect when it
-is made possessive and applied to an item in parentheses, because a
-parenthesized item may contain multiple branches or other backtracking points,
-for example /(a|ab){1}+c/ or /(a+){1}+a/.
-
-13. For partial matches, pcre2test was always showing the maximum lookbehind
-characters, flagged with "<", which is misleading when the lookbehind didn't
-actually look behind the start (because it was later in the pattern). Showing
-all consulted preceding characters for partial matches is now controlled by the
-existing "allusedtext" modifier and, as for complete matches, this facility is
-available only for non-JIT matching, because JIT does not maintain the first
-and last consulted characters.
-
-14. DFA matching (using pcre2_dfa_match()) was not recognising a partial match
-if the end of the subject was encountered in a lookahead (conditional or
-otherwise), an atomic group, or a recursion.
-
-15. Give error if pcre2test -t, -T, -tm or -TM is given an argument of zero.
-
-16. Check for integer overflow when computing lookbehind lengths. Fixes
-Clusterfuzz issue 15636.
-
-17. Implemented non-atomic positive lookaround assertions.
-
-18. If a lookbehind contained a lookahead that contained another lookbehind
-within it, the nested lookbehind was not correctly processed. For example, if
-/(?<=(?=(?<=a)))b/ was matched to "ab" it gave no match instead of matching
-"b".
-
-19. Implemented pcre2_get_match_data_size().
-
-20. Two alterations to partial matching:
-
- (a) The definition of a partial match is slightly changed: if a pattern
- contains any lookbehinds, an empty partial match may be given, because this
- is another situation where adding characters to the current subject can
- lead to a full match. Example: /c*+(?<=[bc])/ with subject "ab".
-
- (b) Similarly, if a pattern could match an empty string, an empty partial
- match may be given. Example: /(?![ab]).*/ with subject "ab". This case
- applies only to PCRE2_PARTIAL_HARD.
-
- (c) An empty string partial hard match can be returned for \z and \Z as it
- is documented that they shouldn't match.
-
-21. A branch that started with (*ACCEPT) was not being recognized as one that
-could match an empty string.
-
-22. Corrected pcre2_set_character_tables() tables data type: was const unsigned
-char * instead of const uint8_t *, as generated by pcre2_maketables().
-
-23. Upgraded to Unicode 12.1.0.
-
-24. Add -jitfast command line option to pcre2test (to make all the jit options
-available directly).
-
-25. Make pcre2test -C show if libreadline or libedit is supported.
-
-26. If the length of one branch of a group exceeded 65535 (the maximum value
-that is remembered as a minimum length), the whole group's length was
-incorrectly recorded as 65535, leading to incorrect "no match" when start-up
-optimizations were in force.
-
-27. The "rightmost consulted character" value was not always correct; in
-particular, if a pattern ended with a negative lookahead, characters that were
-inspected in that lookahead were not included.
-
-28. Add the pcre2_maketables_free() function.
-
-29. The start-up optimization that looks for a unique initial matching
-code unit in the interpretive engines uses memchr() in 8-bit mode. When the
-search is caseless, it was doing so inefficiently, which ended up slowing down
-the match drastically when the subject was very long. The revised code (a)
-remembers if one case is not found, so it never repeats the search for that
-case after a bumpalong and (b) when one case has been found, it searches only
-up to that position for an earlier occurrence of the other case. This fix
-applies to both interpretive pcre2_match() and to pcre2_dfa_match().
-
-30. While scanning to find the minimum length of a group, if any branch has
-minimum length zero, there is no need to scan any subsequent branches (a small
-compile-time performance improvement).
-
-31. Installed a .gitignore file on a user's suggestion. When using the svn
-repository with git (through git svn) this helps keep it tidy.
-
-32. Add underflow check in JIT which may occur when the value of subject
-string pointer is close to 0.
-
-33. Arrange for classes such as [Aa] which contain just the two cases of the
-same character, to be treated as a single caseless character. This causes the
-first and required code unit optimizations to kick in where relevant.
-
-34. Improve the bitmap of starting bytes for positive classes that include wide
-characters, but no property types, in UTF-8 mode. Previously, on encountering
-such a class, the bits for all bytes greater than \xc4 were set, thus
-specifying any character with codepoint >= 0x100. Now the only bits that are
-set are for the relevant bytes that start the wide characters. This can give a
-noticeable performance improvement.
-
-35. If the bitmap of starting code units contains only 1 or 2 bits, replace it
-with a single starting code unit (1 bit) or a caseless single starting code
-unit if the two relevant characters are case-partners. This is particularly
-relevant to the 8-bit library, though it applies to all. It can give a
-performance boost for patterns such as [Ww]ord and (word|WORD). However, this
-optimization doesn't happen if there is a "required" code unit of the same
-value (because the search for a "required" code unit starts at the match start
-for non-unique first code unit patterns, but after a unique first code unit,
-and patterns such as a*a need the former action).
-
-36. Small patch to pcre2posix.c to set the erroroffset field to -1 immediately
-after a successful compile, instead of at the start of matching to avoid a
-sanitizer complaint (regexec is supposed to be thread safe).
-
-37. Add NEON vectorization to JIT to speed up matching of first character and
-pairs of characters on ARM64 CPUs.
-
-38. If a non-ASCII character was the first in a starting assertion in a
-caseless match, the "first code unit" optimization did not get the casing
-right, and the assertion failed to match a character in the other case if it
-did not start with the same code unit.
-
-39. Fixed the incorrect computation of jump sizes on x86 CPUs in JIT. A masking
-operation was incorrectly removed in r1136. Reported by Ralf Junker.
-
-
-Version 10.33 16-April-2019
----------------------------
-
-1. Added "allvector" to pcre2test to make it easy to check the part of the
-ovector that shouldn't be changed, in particular after substitute and failed or
-partial matches.
-
-2. Fix subject buffer overread in JIT when UTF is disabled and \X or \R has
-a greater than 1 fixed quantifier. This issue was found by Yunho Kim.
-
-3. Added support for callouts from pcre2_substitute(). After 10.33-RC1, but
-prior to release, fixed a bug that caused a crash if pcre2_substitute() was
-called with a NULL match context.
-
-4. The POSIX functions are now all called pcre2_regcomp() etc., with wrapper
-functions that use the standard POSIX names. However, in pcre2posix.h the POSIX
-names are defined as macros. This should help avoid linking with the wrong
-library in some environments while still exporting the POSIX names for
-pre-existing programs that use them. (The Debian alternative names are also
-defined as macros, but not documented.)
-
-5. Fix an xclass matching issue in JIT.
-
-6. Implement PCRE2_EXTRA_ESCAPED_CR_IS_LF (see Bugzilla 2315).
-
-7. Implement the Perl 5.28 experimental alphabetic names for atomic groups and
-lookaround assertions, for example, (*pla:...) and (*atomic:...). These are
-characterized by a lower case letter following (* and to simplify coding for
-this, the character tables created by pcre2_maketables() were updated to add a
-new "is lower case letter" bit. At the same time, the now unused "is
-hexadecimal digit" bit was removed. The default tables in
-src/pcre2_chartables.c.dist are updated.
-
-8. Implement the new Perl "script run" features (*script_run:...) and
-(*atomic_script_run:...) aka (*sr:...) and (*asr:...).
-
-9. Fixed two typos in change 22 for 10.21, which added special handling for
-ranges such as a-z in EBCDIC environments. The original code probably never
-worked, though there were no bug reports.
-
-10. Implement PCRE2_COPY_MATCHED_SUBJECT for pcre2_match() (including JIT via
-pcre2_match()) and pcre2_dfa_match(), but *not* the pcre2_jit_match() fast
-path. Also, when a match fails, set the subject field in the match data to NULL
-for tidiness - none of the substring extractors should reference this after
-match failure.
-
-11. If a pattern started with a subroutine call that had a quantifier with a
-minimum of zero, an incorrect "match must start with this character" could be
-recorded. Example: /(?&xxx)*ABC(?<xxx>XYZ)/ would (incorrectly) expect 'A' to
-be the first character of a match.
-
-12. The heap limit checking code in pcre2_dfa_match() could suffer from
-overflow if the heap limit was set very large. This could cause incorrect "heap
-limit exceeded" errors.
-
-13. Add "kibibytes" to the heap limit output from pcre2test -C to make the
-units clear.
-
-14. Add a call to pcre2_jit_free_unused_memory() in pcre2grep, for tidiness.
-
-15. Updated the VMS-specific code in pcre2test on the advice of a VMS user.
-
-16. Removed the unnecessary inclusion of stdint.h (or inttypes.h) from
-pcre2_internal.h as it is now included by pcre2.h. Also, change 17 for 10.32
-below was unnecessarily complicated, as inttypes.h is a Standard C header,
-which is defined to be a superset of stdint.h. Instead of conditionally
-including stdint.h or inttypes.h, pcre2.h now unconditionally includes
-inttypes.h. This supports environments that do not have stdint.h but do have
-inttypes.h, which are known to exist. A note in the autotools documentation
-says (November 2018) that there are none known that are the other way round.
-
-17. Added --disable-percent-zt to "configure" (and equivalent to CMake) to
-forcibly disable the use of %zu and %td in formatting strings because there is
-at least one version of VMS that claims to be C99 but does not support these
-modifiers.
-
-18. Added --disable-pcre2grep-callout-fork, which restricts the callout support
-in pcre2grep to the inbuilt echo facility. This may be useful in environments
-that do not support fork().
-
-19. Fix two instances of <= 0 being applied to unsigned integers (the VMS
-compiler complains).
-
-20. Added "fork" support for VMS to pcre2grep, for running an external program
-via a string callout.
-
-21. Improve MAP_JIT flag usage on MacOS. Patch by Rich Siegel.
-
-22. If a pattern started with (*MARK), (*COMMIT), (*PRUNE), (*SKIP), or (*THEN)
-followed by ^ it was not recognized as anchored.
-
-23. The RunGrepTest script used to cut out the test of NUL characters for
-Solaris and MacOS as printf and sed can't handle them. It seems that the *BSD
-systems can't either. I've inverted the test so that only those OS that are
-known to work (currently only Linux) try to run this test.
-
-24. Some tests in RunGrepTest appended to testtrygrep from two different file
-descriptors instead of redirecting stderr to stdout. This worked on Linux, but
-it was reported not to on other systems, causing the tests to fail.
-
-25. In the RunTest script, make the test for stack setting use the same value
-for the stack as it needs for -bigstack.
-
-26. Insert a cast in pcre2_dfa_match.c to suppress a compiler warning.
-
-26. With PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL set, escape sequences such as \s
-which are valid in character classes, but not as the end of ranges, were being
-treated as literals. An example is [_-\s] (but not [\s-_] because that gave an
-error at the *start* of a range). Now an "invalid range" error is given
-independently of PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL.
-
-27. Related to 26 above, PCRE2_BAD_ESCAPE_IS_LITERAL was affecting known escape
-sequences such as \eX when they appeared invalidly in a character class. Now
-the option applies only to unrecognized or malformed escape sequences.
-
-28. Fix word boundary in JIT compiler. Patch by Mike Munday.
-
-29. The pcre2_dfa_match() function was incorrectly handling conditional version
-tests such as (?(VERSION>=0)...) when the version test was true. Incorrect
-processing or a crash could result.
-
-30. When PCRE2_UTF is set, allow non-ASCII letters and decimal digits in group
-names, as Perl does. There was a small bug in this new code, found by
-ClusterFuzz 12950, fixed before release.
-
-31. Implemented PCRE2_EXTRA_ALT_BSUX to support ECMAScript 6's \u{hhh}
-construct.
-
-32. Compile \p{Any} to be the same as . in DOTALL mode, so that it benefits
-from auto-anchoring if \p{Any}* starts a pattern.
-
-33. Compile invalid UTF check in JIT test when only pcre32 is enabled.
-
-34. For some time now, CMake has been warning about the setting of policy
-CMP0026 to "OLD" in CmakeLists.txt, and hinting that the feature might be
-removed in a future version. A request for CMake expertise on the list produced
-no result, so I have now hacked CMakeLists.txt along the lines of some changes
-I found on the Internet. The new code no longer needs the policy setting, and
-it appears to work fine on Linux.
-
-35. Setting --enable-jit=auto for an out-of-tree build failed because the
-source directory wasn't in the search path for AC_TRY_COMPILE always. Patch
-from Ross Burton.
-
-36. Disable SSE2 JIT optimizations in x86 CPUs when SSE2 is not available.
-Patch by Guillem Jover.
-
-37. Changed expressions such as 1<<10 to 1u<<10 in many places because compiler
-warnings were reported.
-
-38. Using the clang compiler with sanitizing options causes runtime complaints
-about truncation for statements such as x = ~x when x is an 8-bit value; it
-seems to compute ~x as a 32-bit value. Changing such statements to x = 255 ^ x
-gets rid of the warnings. There were also two missing casts in pcre2test.
-
-
-Version 10.32 10-September-2018
--------------------------------
-
-1. When matching using the the REG_STARTEND feature of the POSIX API with a
-non-zero starting offset, unset capturing groups with lower numbers than a
-group that did capture something were not being correctly returned as "unset"
-(that is, with offset values of -1).
-
-2. When matching using the POSIX API, pcre2test used to omit listing unset
-groups altogether. Now it shows those that come before any actual captures as
-"<unset>", as happens for non-POSIX matching.
-
-3. Running "pcre2test -C" always stated "\R matches CR, LF, or CRLF only",
-whatever the build configuration was. It now correctly says "\R matches all
-Unicode newlines" in the default case when --enable-bsr-anycrlf has not been
-specified. Similarly, running "pcre2test -C bsr" never produced the result
-ANY.
-
-4. Matching the pattern /(*UTF)\C[^\v]+\x80/ against an 8-bit string containing
-multi-code-unit characters caused bad behaviour and possibly a crash. This
-issue was fixed for other kinds of repeat in release 10.20 by change 19, but
-repeating character classes were overlooked.
-
-5. pcre2grep now supports the inclusion of binary zeros in patterns that are
-read from files via the -f option.
-
-6. A small fix to pcre2grep to avoid compiler warnings for -Wformat-overflow=2.
-
-7. Added --enable-jit=auto support to configure.ac.
-
-8. Added some dummy variables to the heapframe structure in 16-bit and 32-bit
-modes for the benefit of m68k, where pointers can be 16-bit aligned. The
-dummies force 32-bit alignment and this ensures that the structure is a
-multiple of PCRE2_SIZE, a requirement that is tested at compile time. In other
-architectures, alignment requirements take care of this automatically.
-
-9. When returning an error from pcre2_pattern_convert(), ensure the error
-offset is set zero for early errors.
-
-10. A number of patches for Windows support from Daniel Richard G:
-
- (a) List of error numbers in Runtest.bat corrected (it was not the same as in
- Runtest).
-
- (b) pcre2grep snprintf() workaround as used elsewhere in the tree.
-
- (c) Support for non-C99 snprintf() that returns -1 in the overflow case.
-
-11. Minor tidy of pcre2_dfa_match() code.
-
-12. Refactored pcre2_dfa_match() so that the internal recursive calls no longer
-use the stack for local workspace and local ovectors. Instead, an initial block
-of stack is reserved, but if this is insufficient, heap memory is used. The
-heap limit parameter now applies to pcre2_dfa_match().
-
-13. If a "find limits" test of DFA matching in pcre2test resulted in too many
-matches for the ovector, no matches were displayed.
-
-14. Removed an occurrence of ctrl/Z from test 6 because Windows treats it as
-EOF. The test looks to have come from a fuzzer.
-
-15. If PCRE2 was built with a default match limit a lot greater than the
-default default of 10 000 000, some JIT tests of the match limit no longer
-failed. All such tests now set 10 000 000 as the upper limit.
-
-16. Another Windows related patch for pcregrep to ensure that WIN32 is
-undefined under Cygwin.
-
-17. Test for the presence of stdint.h and inttypes.h in configure and CMake and
-include whichever exists (stdint preferred) instead of unconditionally
-including stdint. This makes life easier for old and non-standard systems.
-
-18. Further changes to improve portability, especially to old and or non-
-standard systems:
-
- (a) Put all printf arguments in RunGrepTest into single, not double, quotes,
- and use \0 not \x00 for binary zero.
-
- (b) Avoid the use of C++ (i.e. BCPL) // comments.
-
- (c) Parameterize the use of %zu in pcre2test to make it like %td. For both of
- these now, if using MSVC or a standard C before C99, %lu is used with a
- cast if necessary.
-
-19. Applied a contributed patch to CMakeLists.txt to increase the stack size
-when linking pcre2test with MSVC. This gets rid of a stack overflow error in
-the standard set of tests.
-
-20. Output a warning in pcre2test when ignoring the "altglobal" modifier when
-it is given with the "replace" modifier.
-
-21. In both pcre2test and pcre2_substitute(), with global matching, a pattern
-that matched an empty string, but never at the starting match offset, was not
-handled in a Perl-compatible way. The pattern /(<?=\G.)/ is an example of such
-a pattern. Because \G is in a lookbehind assertion, there has to be a
-"bumpalong" before there can be a match. The automatic "advance by one
-character after an empty string match" rule is therefore inappropriate. A more
-complicated algorithm has now been implemented.
-
-22. When checking to see if a lookbehind is of fixed length, lookaheads were
-correctly ignored, but qualifiers on lookaheads were not being ignored, leading
-to an incorrect "lookbehind assertion is not fixed length" error.
-
-23. The VERSION condition test was reading fractional PCRE2 version numbers
-such as the 04 in 10.04 incorrectly and hence giving wrong results.
-
-24. Updated to Unicode version 11.0.0. As well as the usual addition of new
-scripts and characters, this involved re-jigging the grapheme break property
-algorithm because Unicode has changed the way emojis are handled.
-
-25. Fixed an obscure bug that struck when there were two atomic groups not
-separated by something with a backtracking point. There could be an incorrect
-backtrack into the first of the atomic groups. A complicated example is
-/(?>a(*:1))(?>b)(*SKIP:1)x|.*/ matched against "abc", where the *SKIP
-shouldn't find a MARK (because is in an atomic group), but it did.
-
-26. Upgraded the perltest.sh script: (1) #pattern lines can now be used to set
-a list of modifiers for all subsequent patterns - only those that the script
-recognizes are meaningful; (2) #subject lines can be used to set or unset a
-default "mark" modifier; (3) Unsupported #command lines give a warning when
-they are ignored; (4) Mark data is output only if the "mark" modifier is
-present.
-
-27. (*ACCEPT:ARG), (*FAIL:ARG), and (*COMMIT:ARG) are now supported.
-
-28. A (*MARK) name was not being passed back for positive assertions that were
-terminated by (*ACCEPT).
-
-29. Add support for \N{U+dddd}, but only in Unicode mode.
-
-30. Add support for (?^) for unsetting all imnsx options.
-
-31. The PCRE2_EXTENDED (/x) option only ever discarded space characters whose
-code point was less than 256 and that were recognized by the lookup table
-generated by pcre2_maketables(), which uses isspace() to identify white space.
-Now, when Unicode support is compiled, PCRE2_EXTENDED also discards U+0085,
-U+200E, U+200F, U+2028, and U+2029, which are additional characters defined by
-Unicode as "Pattern White Space". This makes PCRE2 compatible with Perl.
-
-32. In certain circumstances, option settings within patterns were not being
-correctly processed. For example, the pattern /((?i)A)(?m)B/ incorrectly
-matched "ab". (The (?m) setting lost the fact that (?i) should be reset at the
-end of its group during the parse process, but without another setting such as
-(?m) the compile phase got it right.) This bug was introduced by the
-refactoring in release 10.23.
-
-33. PCRE2 uses bcopy() if available when memmove() is not, and it used just to
-define memmove() as function call to bcopy(). This hasn't been tested for a
-long time because in pcre2test the result of memmove() was being used, whereas
-bcopy() doesn't return a result. This feature is now refactored always to call
-an emulation function when there is no memmove(). The emulation makes use of
-bcopy() when available.
-
-34. When serializing a pattern, set the memctl, executable_jit, and tables
-fields (that is, all the fields that contain pointers) to zeros so that the
-result of serializing is always the same. These fields are re-set when the
-pattern is deserialized.
-
-35. In a pattern such as /[^\x{100}-\x{ffff}]*[\x80-\xff]/ which has a repeated
-negative class with no characters less than 0x100 followed by a positive class
-with only characters less than 0x100, the first class was incorrectly being
-auto-possessified, causing incorrect match failures.
-
-36. Removed the character type bit ctype_meta, which dates from PCRE1 and is
-not used in PCRE2.
-
-37. Tidied up unnecessarily complicated macros used in the escapes table.
-
-38. Since 10.21, the new testoutput8-16-4 file has accidentally been omitted
-from distribution tarballs, owing to a typo in Makefile.am which had
-testoutput8-16-3 twice. Now fixed.
-
-39. If the only branch in a conditional subpattern was anchored, the whole
-subpattern was treated as anchored, when it should not have been, since the
-assumed empty second branch cannot be anchored. Demonstrated by test patterns
-such as /(?(1)^())b/ or /(?(?=^))b/.
-
-40. A repeated conditional subpattern that could match an empty string was
-always assumed to be unanchored. Now it it checked just like any other
-repeated conditional subpattern, and can be found to be anchored if the minimum
-quantifier is one or more. I can't see much use for a repeated anchored
-pattern, but the behaviour is now consistent.
-
-41. Minor addition to pcre2_jit_compile.c to avoid static analyzer complaint
-(for an event that could never occur but you had to have external information
-to know that).
-
-42. If before the first match in a file that was being searched by pcre2grep
-there was a line that was sufficiently long to cause the input buffer to be
-expanded, the variable holding the location of the end of the previous match
-was being adjusted incorrectly, and could cause an overflow warning from a code
-sanitizer. However, as the value is used only to print pending "after" lines
-when the next match is reached (and there are no such lines in this case) this
-bug could do no damage.
-
-
-Version 10.31 12-February-2018
-------------------------------
-
-1. Fix typo (missing ]) in VMS code in pcre2test.c.
-
-2. Replace the replicated code for matching extended Unicode grapheme sequences
-(which got a lot more complicated by change 10.30/49) by a single subroutine
-that is called by both pcre2_match() and pcre2_dfa_match().
-
-3. Add idempotent guard to pcre2_internal.h.
-
-4. Add new pcre2_config() options: PCRE2_CONFIG_NEVER_BACKSLASH_C and
-PCRE2_CONFIG_COMPILED_WIDTHS.
-
-5. Cut out \C tests in the JIT regression tests when NEVER_BACKSLASH_C is
-defined (e.g. by --enable-never-backslash-C).
-
-6. Defined public names for all the pcre2_compile() error numbers, and used
-the public names in pcre2_convert.c.
-
-7. Fixed a small memory leak in pcre2test (convert contexts).
-
-8. Added two casts to compile.c and one to match.c to avoid compiler warnings.
-
-9. Added code to pcre2grep when compiled under VMS to set the symbol
-PCRE2GREP_RC to the exit status, because VMS does not distinguish between
-exit(0) and exit(1).
-
-10. Added the -LM (list modifiers) option to pcre2test. Also made -C complain
-about a bad option only if the following argument item does not start with a
-hyphen.
-
-11. pcre2grep was truncating components of file names to 128 characters when
-processing files with the -r option, and also (some very odd code) truncating
-path names to 512 characters. There is now a check on the absolute length of
-full path file names, which may be up to 2047 characters long.
-
-12. When an assertion contained (*ACCEPT) it caused all open capturing groups
-to be closed (as for a non-assertion ACCEPT), which was wrong and could lead to
-misbehaviour for subsequent references to groups that started outside the
-assertion. ACCEPT in an assertion now closes only those groups that were
-started within that assertion. Fixes oss-fuzz issues 3852 and 3891.
-
-13. Multiline matching in pcre2grep was misbehaving if the pattern matched
-within a line, and then matched again at the end of the line and over into
-subsequent lines. Behaviour was different with and without colouring, and
-sometimes context lines were incorrectly printed and/or line endings were lost.
-All these issues should now be fixed.
-
-14. If --line-buffered was specified for pcre2grep when input was from a
-compressed file (.gz or .bz2) a segfault occurred. (Line buffering should be
-ignored for compressed files.)
-
-15. Although pcre2_jit_match checks whether the pattern is compiled
-in a given mode, it was also expected that at least one mode is available.
-This is fixed and pcre2_jit_match returns with PCRE2_ERROR_JIT_BADOPTION
-when the pattern is not optimized by JIT at all.
-
-16. The line number and related variables such as match counts in pcre2grep
-were all int variables, causing overflow when files with more than 2147483647
-lines were processed (assuming 32-bit ints). They have all been changed to
-unsigned long ints.
-
-17. If a backreference with a minimum repeat count of zero was first in a
-pattern, apart from assertions, an incorrect first matching character could be
-recorded. For example, for the pattern /(?=(a))\1?b/, "b" was incorrectly set
-as the first character of a match.
-
-18. Characters in a leading positive assertion are considered for recording a
-first character of a match when the rest of the pattern does not provide one.
-However, a character in a non-assertive group within a leading assertion such
-as in the pattern /(?=(a))\1?b/ caused this process to fail. This was an
-infelicity rather than an outright bug, because it did not affect the result of
-a match, just its speed. (In fact, in this case, the starting 'a' was
-subsequently picked up in the study.)
-
-19. A minor tidy in pcre2_match(): making all PCRE2_ERROR_ returns use "return"
-instead of "RRETURN" saves unwinding the backtracks in these cases (only one
-didn't).
-
-20. Allocate a single callout block on the stack at the start of pcre2_match()
-and set its never-changing fields once only. Do the same for pcre2_dfa_match().
-
-21. Save the extra compile options (set in the compile context) with the
-compiled pattern (they were not previously saved), add PCRE2_INFO_EXTRAOPTIONS
-to retrieve them, and update pcre2test to show them.
-
-22. Added PCRE2_CALLOUT_STARTMATCH and PCRE2_CALLOUT_BACKTRACK bits to a new
-field callout_flags in callout blocks. The bits are set by pcre2_match(), but
-not by JIT or pcre2_dfa_match(). Their settings are shown in pcre2test callouts
-if the callout_extra subject modifier is set. These bits are provided to help
-with tracking how a backtracking match is proceeding.
-
-23. Updated the pcre2demo.c demonstration program, which was missing the extra
-code for -g that handles the case when \K in an assertion causes the match to
-end at the original start point. Also arranged for it to detect when \K causes
-the end of a match to be before its start.
-
-24. Similar to 23 above, strange things (including loops) could happen in
-pcre2grep when \K was used in an assertion when --colour was used or in
-multiline mode. The "end at original start point" bug is fixed, and if the end
-point is found to be before the start point, they are swapped.
-
-25. When PCRE2_FIRSTLINE without PCRE2_NO_START_OPTIMIZE was used in non-JIT
-matching (both pcre2_match() and pcre2_dfa_match()) and the matched string
-started with the first code unit of a newline sequence, matching failed because
-it was not tried at the newline.
-
-26. Code for giving up a non-partial match after failing to find a starting
-code unit anywhere in the subject was missing when searching for one of a
-number of code units (the bitmap case) in both pcre2_match() and
-pcre2_dfa_match(). This was a missing optimization rather than a bug.
-
-27. Tidied up the ACROSSCHAR macro to be like FORWARDCHAR and BACKCHAR, using a
-pointer argument rather than a code unit value. This should not have affected
-the generated code.
-
-28. The JIT compiler has been updated.
-
-29. Avoid pointer overflow for unset captures in pcre2_substring_list_get().
-This could not actually cause a crash because it was always used in a memcpy()
-call with zero length.
-
-30. Some internal structures have a variable-length ovector[] as their last
-element. Their actual memory is obtained dynamically, giving an ovector of
-appropriate length. However, they are defined in the structure as
-ovector[NUMBER], where NUMBER is large so that array bound checkers don't
-grumble. The value of NUMBER was 10000, but a fuzzer exceeded 5000 capturing
-groups, making the ovector larger than this. The number has been increased to
-131072, which allows for the maximum number of captures (65535) plus the
-overall match. This fixes oss-fuzz issue 5415.
-
-31. Auto-possessification at the end of a capturing group was dependent on what
-follows the group (e.g. /(a+)b/ would auto-possessify the a+) but this caused
-incorrect behaviour when the group was called recursively from elsewhere in the
-pattern where something different might follow. This bug is an unforseen
-consequence of change #1 for 10.30 - the implementation of backtracking into
-recursions. Iterators at the ends of capturing groups are no longer considered
-for auto-possessification if the pattern contains any recursions. Fixes
-Bugzilla #2232.
-
-
-Version 10.30 14-August-2017
-----------------------------
-
-1. The main interpreter, pcre2_match(), has been refactored into a new version
-that does not use recursive function calls (and therefore the stack) for
-remembering backtracking positions. This makes --disable-stack-for-recursion a
-NOOP. The new implementation allows backtracking into recursive group calls in
-patterns, making it more compatible with Perl, and also fixes some other
-hard-to-do issues such as #1887 in Bugzilla. The code is also cleaner because
-the old code had a number of fudges to try to reduce stack usage. It seems to
-run no slower than the old code.
-
-A number of bugs in the refactored code were subsequently fixed during testing
-before release, but after the code was made available in the repository. These
-bugs were never in fully released code, but are noted here for the record.
-
- (a) If a pattern had fewer capturing parentheses than the ovector supplied in
- the match data block, a memory error (detectable by ASAN) occurred after
- a match, because the external block was being set from non-existent
- internal ovector fields. Fixes oss-fuzz issue 781.
-
- (b) A pattern with very many capturing parentheses (when the internal frame
- size was greater than the initial frame vector on the stack) caused a
- crash. A vector on the heap is now set up at the start of matching if the
- vector on the stack is not big enough to handle at least 10 frames.
- Fixes oss-fuzz issue 783.
-
- (c) Handling of (*VERB)s in recursions was wrong in some cases.
-
- (d) Captures in negative assertions that were used as conditions were not
- happening if the assertion matched via (*ACCEPT).
-
- (e) Mark values were not being passed out of recursions.
-
- (f) Refactor some code in do_callout() to avoid picky compiler warnings about
- negative indices. Fixes oss-fuzz issue 1454.
-
- (g) Similarly refactor the way the variable length ovector is addressed for
- similar reasons. Fixes oss-fuzz issue 1465.
-
-2. Now that pcre2_match() no longer uses recursive function calls (see above),
-the "match limit recursion" value seems misnamed. It still exists, and limits
-the depth of tree that is searched. To avoid future confusion, it has been
-renamed as "depth limit" in all relevant places (--with-depth-limit,
-(*LIMIT_DEPTH), pcre2_set_depth_limit(), etc) but the old names are still
-available for backwards compatibility.
-
-3. Hardened pcre2test so as to reduce the number of bugs reported by fuzzers:
-
- (a) Check for malloc failures when getting memory for the ovector (POSIX) or
- the match data block (non-POSIX).
-
-4. In the 32-bit library in non-UTF mode, an attempt to find a Unicode property
-for a character with a code point greater than 0x10ffff (the Unicode maximum)
-caused a crash.
-
-5. If a lookbehind assertion that contained a back reference to a group
-appearing later in the pattern was compiled with the PCRE2_ANCHORED option,
-undefined actions (often a segmentation fault) could occur, depending on what
-other options were set. An example assertion is (?<!\1(abc)) where the
-reference \1 precedes the group (abc). This fixes oss-fuzz issue 865.
-
-6. Added the PCRE2_INFO_FRAMESIZE item to pcre2_pattern_info() and arranged for
-pcre2test to use it to output the frame size when the "framesize" modifier is
-given.
-
-7. Reworked the recursive pattern matching in the JIT compiler to follow the
-interpreter changes.
-
-8. When the zero_terminate modifier was specified on a pcre2test subject line
-for global matching, unpredictable things could happen. For example, in UTF-8
-mode, the pattern //g,zero_terminate read random memory when matched against an
-empty string with zero_terminate. This was a bug in pcre2test, not the library.
-
-9. Moved some Windows-specific code in pcre2grep (introduced in 10.23/13) out
-of the section that is compiled when Unix-style directory scanning is
-available, and into a new section that is always compiled for Windows.
-
-10. In pcre2test, explicitly close the file after an error during serialization
-or deserialization (the "load" or "save" commands).
-
-11. Fix memory leak in pcre2_serialize_decode() when the input is invalid.
-
-12. Fix potential NULL dereference in pcre2_callout_enumerate() if called with
-a NULL pattern pointer when Unicode support is available.
-
-13. When the 32-bit library was being tested by pcre2test, error messages that
-were longer than 64 code units could cause a buffer overflow. This was a bug in
-pcre2test.
-
-14. The alternative matching function, pcre2_dfa_match() misbehaved if it
-encountered a character class with a possessive repeat, for example [a-f]{3}+.
-
-15. The depth (formerly recursion) limit now applies to DFA matching (as
-of 10.23/36); pcre2test has been upgraded so that \=find_limits works with DFA
-matching to find the minimum value for this limit.
-
-16. Since 10.21, if pcre2_match() was called with a null context, default
-memory allocation functions were used instead of whatever was used when the
-pattern was compiled.
-
-17. Changes to the pcre2test "memory" modifier on a subject line. These apply
-only to pcre2_match():
-
- (a) Warn if null_context is set on both pattern and subject, because the
- memory details cannot then be shown.
-
- (b) Remember (up to a certain number of) memory allocations and their
- lengths, and list only the lengths, so as to be system-independent.
- (In practice, the new interpreter never has more than 2 blocks allocated
- simultaneously.)
-
-18. Make pcre2test detect an error return from pcre2_get_error_message(), give
-a message, and abandon the run (this would have detected #13 above).
-
-19. Implemented PCRE2_ENDANCHORED.
-
-20. Applied Jason Hood's patches (slightly modified) to pcre2grep, to implement
-the --output=text (-O) option and the inbuilt callout echo.
-
-21. Extend auto-anchoring etc. to ignore groups with a zero qualifier and
-single-branch conditions with a false condition (e.g. DEFINE) at the start of a
-branch. For example, /(?(DEFINE)...)^A/ and /(...){0}^B/ are now flagged as
-anchored.
-
-22. Added an explicit limit on the amount of heap used by pcre2_match(), set by
-pcre2_set_heap_limit() or (*LIMIT_HEAP=xxx). Upgraded pcre2test to show the
-heap limit along with other pattern information, and to find the minimum when
-the find_limits modifier is set.
-
-23. Write to the last 8 bytes of the pcre2_real_code structure when a compiled
-pattern is set up so as to initialize any padding the compiler might have
-included. This avoids valgrind warnings when a compiled pattern is copied, in
-particular when it is serialized.
-
-24. Remove a redundant line of code left in accidentally a long time ago.
-
-25. Remove a duplication typo in pcre2_tables.c
-
-26. Correct an incorrect cast in pcre2_valid_utf.c
-
-27. Update pcre2test, remove some unused code in pcre2_match(), and upgrade the
-tests to improve coverage.
-
-28. Some fixes/tidies as a result of looking at Coverity Scan output:
-
- (a) Typo: ">" should be ">=" in opcode check in pcre2_auto_possess.c.
- (b) Added some casts to avoid "suspicious implicit sign extension".
- (c) Resource leaks in pcre2test in rare error cases.
- (d) Avoid warning for never-use case OP_TABLE_LENGTH which is just a fudge
- for checking at compile time that tables are the right size.
- (e) Add missing "fall through" comment.
-
-29. Implemented PCRE2_EXTENDED_MORE and related /xx and (?xx) features.
-
-30. Implement (?n: for PCRE2_NO_AUTO_CAPTURE, because Perl now has this.
-
-31. If more than one of "push", "pushcopy", or "pushtablescopy" were set in
-pcre2test, a crash could occur.
-
-32. Make -bigstack in RunTest allocate a 64MiB stack (instead of 16MiB) so
-that all the tests can run with clang's sanitizing options.
-
-33. Implement extra compile options in the compile context and add the first
-one: PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES.
-
-34. Implement newline type PCRE2_NEWLINE_NUL.
-
-35. A lookbehind assertion that had a zero-length branch caused undefined
-behaviour when processed by pcre2_dfa_match(). This is oss-fuzz issue 1859.
-
-36. The match limit value now also applies to pcre2_dfa_match() as there are
-patterns that can use up a lot of resources without necessarily recursing very
-deeply. (Compare item 10.23/36.) This should fix oss-fuzz #1761.
-
-37. Implement PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL.
-
-38. Fix returned offsets from regexec() when REG_STARTEND is used with a
-starting offset greater than zero.
-
-39. Implement REG_PEND (GNU extension) for the POSIX wrapper.
-
-40. Implement the subject_literal modifier in pcre2test, and allow jitstack on
-pattern lines.
-
-41. Implement PCRE2_LITERAL and use it to support REG_NOSPEC.
-
-42. Implement PCRE2_EXTRA_MATCH_LINE and PCRE2_EXTRA_MATCH_WORD for the benefit
-of pcre2grep.
-
-43. Re-implement pcre2grep's -F, -w, and -x options using PCRE2_LITERAL,
-PCRE2_EXTRA_MATCH_WORD, and PCRE2_EXTRA_MATCH_LINE. This fixes two bugs:
-
- (a) The -F option did not work for fixed strings containing \E.
- (b) The -w option did not work for patterns with multiple branches.
-
-44. Added configuration options for the SELinux compatible execmem allocator in
-JIT.
-
-45. Increased the limit for searching for a "must be present" code unit in
-subjects from 1000 to 2000 for 8-bit searches, since they use memchr() and are
-much faster.
-
-46. Arrange for anchored patterns to record and use "first code unit" data,
-because this can give a fast "no match" without searching for a "required code
-unit". Previously only non-anchored patterns did this.
-
-47. Upgraded the Unicode tables from Unicode 8.0.0 to Unicode 10.0.0.
-
-48. Add the callout_no_where modifier to pcre2test.
-
-49. Update extended grapheme breaking rules to the latest set that are in
-Unicode Standard Annex #29.
-
-50. Added experimental foreign pattern conversion facilities
-(pcre2_pattern_convert() and friends).
-
-51. Change the macro FWRITE, used in pcre2grep, to FWRITE_IGNORE because FWRITE
-is defined in a system header in cygwin. Also modified some of the #ifdefs in
-pcre2grep related to Windows and Cygwin support.
-
-52. Change 3(g) for 10.23 was a bit too zealous. If a hyphen that follows a
-character class is the last character in the class, Perl does not give a
-warning. PCRE2 now also treats this as a literal.
-
-53. Related to 52, though PCRE2 was throwing an error for [[:digit:]-X] it was
-not doing so for [\d-X] (and similar escapes), as is documented.
-
-54. Fixed a MIPS issue in the JIT compiler reported by Joshua Kinard.
-
-55. Fixed a "maybe uninitialized" warning for class_uchardata in \p handling in
-pcre2_compile() which could never actually trigger (code should have been cut
-out when Unicode support is disabled).
-
-
-Version 10.23 14-February-2017
-------------------------------
-
-1. Extended pcre2test with the utf8_input modifier so that it is able to
-generate all possible 16-bit and 32-bit code unit values in non-UTF modes.
-
-2. In any wide-character mode (8-bit UTF or any 16-bit or 32-bit mode), without
-PCRE2_UCP set, a negative character type such as \D in a positive class should
-cause all characters greater than 255 to match, whatever else is in the class.
-There was a bug that caused this not to happen if a Unicode property item was
-added to such a class, for example [\D\P{Nd}] or [\W\pL].
-
-3. There has been a major re-factoring of the pcre2_compile.c file. Most syntax
-checking is now done in the pre-pass that identifies capturing groups. This has
-reduced the amount of duplication and made the code tidier. While doing this,
-some minor bugs and Perl incompatibilities were fixed, including:
-
- (a) \Q\E in the middle of a quantifier such as A+\Q\E+ is now ignored instead
- of giving an invalid quantifier error.
-
- (b) {0} can now be used after a group in a lookbehind assertion; previously
- this caused an "assertion is not fixed length" error.
-
- (c) Perl always treats (?(DEFINE) as a "define" group, even if a group with
- the name "DEFINE" exists. PCRE2 now does likewise.
-
- (d) A recursion condition test such as (?(R2)...) must now refer to an
- existing subpattern.
-
- (e) A conditional recursion test such as (?(R)...) misbehaved if there was a
- group whose name began with "R".
-
- (f) When testing zero-terminated patterns under valgrind, the terminating
- zero is now marked "no access". This catches bugs that would otherwise
- show up only with non-zero-terminated patterns.
-
- (g) A hyphen appearing immediately after a POSIX character class (for example
- /[[:ascii:]-z]/) now generates an error. Perl does accept this as a
- literal, but gives a warning, so it seems best to fail it in PCRE.
-
- (h) An empty \Q\E sequence may appear after a callout that precedes an
- assertion condition (it is, of course, ignored).
-
-One effect of the refactoring is that some error numbers and messages have
-changed, and the pattern offset given for compiling errors is not always the
-right-most character that has been read. In particular, for a variable-length
-lookbehind assertion it now points to the start of the assertion. Another
-change is that when a callout appears before a group, the "length of next
-pattern item" that is passed now just gives the length of the opening
-parenthesis item, not the length of the whole group. A length of zero is now
-given only for a callout at the end of the pattern. Automatic callouts are no
-longer inserted before and after explicit callouts in the pattern.
-
-A number of bugs in the refactored code were subsequently fixed during testing
-before release, but after the code was made available in the repository. Many
-of the bugs were discovered by fuzzing testing. Several of them were related to
-the change from assuming a zero-terminated pattern (which previously had
-required non-zero terminated strings to be copied). These bugs were never in
-fully released code, but are noted here for the record.
-
- (a) An overall recursion such as (?0) inside a lookbehind assertion was not
- being diagnosed as an error.
-
- (b) In utf mode, the length of a *MARK (or other verb) name was being checked
- in characters instead of code units, which could lead to bad code being
- compiled, leading to unpredictable behaviour.
-
- (c) In extended /x mode, characters whose code was greater than 255 caused
- a lookup outside one of the global tables. A similar bug existed for wide
- characters in *VERB names.
-
- (d) The amount of memory needed for a compiled pattern was miscalculated if a
- lookbehind contained more than one toplevel branch and the first branch
- was of length zero.
-
- (e) In UTF-8 or UTF-16 modes with PCRE2_EXTENDED (/x) set and a non-zero-
- terminated pattern, if a # comment ran on to the end of the pattern, one
- or more code units past the end were being read.
-
- (f) An unterminated repeat at the end of a non-zero-terminated pattern (e.g.
- "{2,2") could cause reading beyond the pattern.
-
- (g) When reading a callout string, if the end delimiter was at the end of the
- pattern one further code unit was read.
-
- (h) An unterminated number after \g' could cause reading beyond the pattern.
-
- (i) An insufficient memory size was being computed for compiling with
- PCRE2_AUTO_CALLOUT.
-
- (j) A conditional group with an assertion condition used more memory than was
- allowed for it during parsing, so too many of them could therefore
- overrun a buffer.
-
- (k) If parsing a pattern exactly filled the buffer, the internal test for
- overrun did not check when the final META_END item was added.
-
- (l) If a lookbehind contained a subroutine call, and the called group
- contained an option setting such as (?s), and the PCRE2_ANCHORED option
- was set, unpredictable behaviour could occur. The underlying bug was
- incorrect code and insufficient checking while searching for the end of
- the called subroutine in the parsed pattern.
-
- (m) Quantifiers following (*VERB)s were not being diagnosed as errors.
-
- (n) The use of \Q...\E in a (*VERB) name when PCRE2_ALT_VERBNAMES and
- PCRE2_AUTO_CALLOUT were both specified caused undetermined behaviour.
-
- (o) If \Q was preceded by a quantified item, and the following \E was
- followed by '?' or '+', and there was at least one literal character
- between them, an internal error "unexpected repeat" occurred (example:
- /.+\QX\E+/).
-
- (p) A buffer overflow could occur while sorting the names in the group name
- list (depending on the order in which the names were seen).
-
- (q) A conditional group that started with a callout was not doing the right
- check for a following assertion, leading to compiling bad code. Example:
- /(?(C'XX))?!XX/
-
- (r) If a character whose code point was greater than 0xffff appeared within
- a lookbehind that was within another lookbehind, the calculation of the
- lookbehind length went wrong and could provoke an internal error.
-
- (t) The sequence \E- or \Q\E- after a POSIX class in a character class caused
- an internal error. Now the hyphen is treated as a literal.
-
-4. Back references are now permitted in lookbehind assertions when there are
-no duplicated group numbers (that is, (?| has not been used), and, if the
-reference is by name, there is only one group of that name. The referenced
-group must, of course be of fixed length.
-
-5. pcre2test has been upgraded so that, when run under valgrind with valgrind
-support enabled, reading past the end of the pattern is detected, both when
-compiling and during callout processing.
-
-6. \g{+<number>} (e.g. \g{+2} ) is now supported. It is a "forward back
-reference" and can be useful in repetitions (compare \g{-<number>} ). Perl does
-not recognize this syntax.
-
-7. Automatic callouts are no longer generated before and after callouts in the
-pattern.
-
-8. When pcre2test was outputing information from a callout, the caret indicator
-for the current position in the subject line was incorrect if it was after an
-escape sequence for a character whose code point was greater than \x{ff}.
-
-9. Change 19 for 10.22 had a typo (PCRE_STATIC_RUNTIME should be
-PCRE2_STATIC_RUNTIME). Fix from David Gaussmann.
-
-10. Added --max-buffer-size to pcre2grep, to allow for automatic buffer
-expansion when long lines are encountered. Original patch by Dmitry
-Cherniachenko.
-
-11. If pcre2grep was compiled with JIT support, but the library was compiled
-without it (something that neither ./configure nor CMake allow, but it can be
-done by editing config.h), pcre2grep was giving a JIT error. Now it detects
-this situation and does not try to use JIT.
-
-12. Added some "const" qualifiers to variables in pcre2grep.
-
-13. Added Dmitry Cherniachenko's patch for colouring output in Windows
-(untested by me). Also, look for GREP_COLOUR or GREP_COLOR if the environment
-variables PCRE2GREP_COLOUR and PCRE2GREP_COLOR are not found.
-
-14. Add the -t (grand total) option to pcre2grep.
-
-15. A number of bugs have been mended relating to match start-up optimizations
-when the first thing in a pattern is a positive lookahead. These all applied
-only when PCRE2_NO_START_OPTIMIZE was *not* set:
-
- (a) A pattern such as (?=.*X)X$ was incorrectly optimized as if it needed
- both an initial 'X' and a following 'X'.
- (b) Some patterns starting with an assertion that started with .* were
- incorrectly optimized as having to match at the start of the subject or
- after a newline. There are cases where this is not true, for example,
- (?=.*[A-Z])(?=.{8,16})(?!.*[\s]) matches after the start in lines that
- start with spaces. Starting .* in an assertion is no longer taken as an
- indication of matching at the start (or after a newline).
-
-16. The "offset" modifier in pcre2test was not being ignored (as documented)
-when the POSIX API was in use.
-
-17. Added --enable-fuzz-support to "configure", causing an non-installed
-library containing a test function that can be called by fuzzers to be
-compiled. A non-installed binary to run the test function locally, called
-pcre2fuzzcheck is also compiled.
-
-18. A pattern with PCRE2_DOTALL (/s) set but not PCRE2_NO_DOTSTAR_ANCHOR, and
-which started with .* inside a positive lookahead was incorrectly being
-compiled as implicitly anchored.
-
-19. Removed all instances of "register" declarations, as they are considered
-obsolete these days and in any case had become very haphazard.
-
-20. Add strerror() to pcre2test for failed file opening.
-
-21. Make pcre2test -C list valgrind support when it is enabled.
-
-22. Add the use_length modifier to pcre2test.
-
-23. Fix an off-by-one bug in pcre2test for the list of names for 'get' and
-'copy' modifiers.
-
-24. Add PCRE2_CALL_CONVENTION into the prototype declarations in pcre2.h as it
-is apparently needed there as well as in the function definitions. (Why did
-nobody ask for this in PCRE1?)
-
-25. Change the _PCRE2_H and _PCRE2_UCP_H guard macros in the header files to
-PCRE2_H_IDEMPOTENT_GUARD and PCRE2_UCP_H_IDEMPOTENT_GUARD to be more standard
-compliant and unique.
-
-26. pcre2-config --libs-posix was listing -lpcre2posix instead of
--lpcre2-posix. Also, the CMake build process was building the library with the
-wrong name.
-
-27. In pcre2test, give some offset information for errors in hex patterns.
-This uses the C99 formatting sequence %td, except for MSVC which doesn't
-support it - %lu is used instead.
-
-28. Implemented pcre2_code_copy_with_tables(), and added pushtablescopy to
-pcre2test for testing it.
-
-29. Fix small memory leak in pcre2test.
-
-30. Fix out-of-bounds read for partial matching of /./ against an empty string
-when the newline type is CRLF.
-
-31. Fix a bug in pcre2test that caused a crash when a locale was set either in
-the current pattern or a previous one and a wide character was matched.
-
-32. The appearance of \p, \P, or \X in a substitution string when
-PCRE2_SUBSTITUTE_EXTENDED was set caused a segmentation fault (NULL
-dereference).
-
-33. If the starting offset was specified as greater than the subject length in
-a call to pcre2_substitute() an out-of-bounds memory reference could occur.
-
-34. When PCRE2 was compiled to use the heap instead of the stack for recursive
-calls to match(), a repeated minimizing caseless back reference, or a
-maximizing one where the two cases had different numbers of code units,
-followed by a caseful back reference, could lose the caselessness of the first
-repeated back reference (example: /(Z)(a)\2{1,2}?(?-i)\1X/i should match ZaAAZX
-but didn't).
-
-35. When a pattern is too complicated, PCRE2 gives up trying to find a minimum
-matching length and just records zero. Typically this happens when there are
-too many nested or recursive back references. If the limit was reached in
-certain recursive cases it failed to be triggered and an internal error could
-be the result.
-
-36. The pcre2_dfa_match() function now takes note of the recursion limit for
-the internal recursive calls that are used for lookrounds and recursions within
-the pattern.
-
-37. More refactoring has got rid of the internal could_be_empty_branch()
-function (around 400 lines of code, including comments) by keeping track of
-could-be-emptiness as the pattern is compiled instead of scanning compiled
-groups. (This would have been much harder before the refactoring of #3 above.)
-This lifts a restriction on the number of branches in a group (more than about
-1100 would give "pattern is too complicated").
-
-38. Add the "-ac" command line option to pcre2test as a synonym for "-pattern
-auto_callout".
-
-39. In a library with Unicode support, incorrect data was compiled for a
-pattern with PCRE2_UCP set without PCRE2_UTF if a class required all wide
-characters to match (for example, /[\s[:^ascii:]]/).
-
-40. The callout_error modifier has been added to pcre2test to make it possible
-to return PCRE2_ERROR_CALLOUT from a callout.
-
-41. A minor change to pcre2grep: colour reset is now "<esc>[0m" instead of
-"<esc>[00m".
-
-42. The limit in the auto-possessification code that was intended to catch
-overly-complicated patterns and not spend too much time auto-possessifying was
-being reset too often, resulting in very long compile times for some patterns.
-Now such patterns are no longer completely auto-possessified.
-
-43. Applied Jason Hood's revised patch for RunTest.bat.
-
-44. Added a new Windows script RunGrepTest.bat, courtesy of Jason Hood.
-
-45. Minor cosmetic fix to pcre2test: move a variable that is not used under
-Windows into the "not Windows" code.
-
-46. Applied Jason Hood's patches to upgrade pcre2grep under Windows and tidy
-some of the code:
-
- * normalised the Windows condition by ensuring WIN32 is defined;
- * enables the callout feature under Windows;
- * adds globbing (Microsoft's implementation expands quoted args),
- using a tweaked opendirectory;
- * implements the is_*_tty functions for Windows;
- * --color=always will write the ANSI sequences to file;
- * add sequences 4 (underline works on Win10) and 5 (blink as bright
- background, relatively standard on DOS/Win);
- * remove the (char *) casts for the now-const strings;
- * remove GREP_COLOUR (grep's command line allowed the 'u', but not
- the environment), parsing GREP_COLORS instead;
- * uses the current colour if not set, rather than black;
- * add print_match for the undefined case;
- * fixes a typo.
-
-In addition, colour settings containing anything other than digits and
-semicolon are ignored, and the colour controls are no longer output for empty
-strings.
-
-47. Detecting patterns that are too large inside the length-measuring loop
-saves processing ridiculously long patterns to their end.
-
-48. Ignore PCRE2_CASELESS when processing \h, \H, \v, and \V in classes as it
-just wastes time. In the UTF case it can also produce redundant entries in
-XCLASS lists caused by characters with multiple other cases and pairs of
-characters in the same "not-x" sublists.
-
-49. A pattern such as /(?=(a\K))/ can report the end of the match being before
-its start; pcre2test was not handling this correctly when using the POSIX
-interface (it was OK with the native interface).
-
-50. In pcre2grep, ignore all JIT compile errors. This means that pcre2grep will
-continue to work, falling back to interpretation if anything goes wrong with
-JIT.
-
-51. Applied patches from Christian Persch to configure.ac to make use of the
-AC_USE_SYSTEM_EXTENSIONS macro and to test for functions used by the JIT
-modules.
-
-52. Minor fixes to pcre2grep from Jason Hood:
- * fixed some spacing;
- * Windows doesn't usually use single quotes, so I've added a define
- to use appropriate quotes [in an example];
- * LC_ALL was displayed as "LCC_ALL";
- * numbers 11, 12 & 13 should end in "th";
- * use double quotes in usage message.
-
-53. When autopossessifying, skip empty branches without recursion, to reduce
-stack usage for the benefit of clang with -fsanitize-address, which uses huge
-stack frames. Example pattern: /X?(R||){3335}/. Fixes oss-fuzz issue 553.
-
-54. A pattern with very many explicit back references to a group that is a long
-way from the start of the pattern could take a long time to compile because
-searching for the referenced group in order to find the minimum length was
-being done repeatedly. Now up to 128 group minimum lengths are cached and the
-attempt to find a minimum length is abandoned if there is a back reference to a
-group whose number is greater than 128. (In that case, the pattern is so
-complicated that this optimization probably isn't worth it.) This fixes
-oss-fuzz issue 557.
-
-55. Issue 32 for 10.22 below was not correctly fixed. If pcre2grep in multiline
-mode with --only-matching matched several lines, it restarted scanning at the
-next line instead of moving on to the end of the matched string, which can be
-several lines after the start.
-
-56. Applied Jason Hood's new patch for RunGrepTest.bat that updates it in line
-with updates to the non-Windows version.
-
-
-
-Version 10.22 29-July-2016
---------------------------
-
-1. Applied Jason Hood's patches to RunTest.bat and testdata/wintestoutput3
-to fix problems with running the tests under Windows.
-
-2. Implemented a facility for quoting literal characters within hexadecimal
-patterns in pcre2test, to make it easier to create patterns with just a few
-non-printing characters.
-
-3. Binary zeros are not supported in pcre2test input files. It now detects them
-and gives an error.
-
-4. Updated the valgrind parameters in RunTest: (a) changed smc-check=all to
-smc-check=all-non-file; (b) changed obj:* in the suppression file to obj:??? so
-that it matches only unknown objects.
-
-5. Updated the maintenance script maint/ManyConfigTests to make it easier to
-select individual groups of tests.
-
-6. When the POSIX wrapper function regcomp() is called, the REG_NOSUB option
-used to set PCRE2_NO_AUTO_CAPTURE when calling pcre2_compile(). However, this
-disables the use of back references (and subroutine calls), which are supported
-by other implementations of regcomp() with RE_NOSUB. Therefore, REG_NOSUB no
-longer causes PCRE2_NO_AUTO_CAPTURE to be set, though it still ignores nmatch
-and pmatch when regexec() is called.
-
-7. Because of 6 above, pcre2test has been modified with a new modifier called
-posix_nosub, to call regcomp() with REG_NOSUB. Previously the no_auto_capture
-modifier had this effect. That option is now ignored when the POSIX API is in
-use.
-
-8. Minor tidies to the pcre2demo.c sample program, including more comments
-about its 8-bit-ness.
-
-9. Detect unmatched closing parentheses and give the error in the pre-scan
-instead of later. Previously the pre-scan carried on and could give a
-misleading incorrect error message. For example, /(?J)(?'a'))(?'a')/ gave a
-message about invalid duplicate group names.
-
-10. It has happened that pcre2test was accidentally linked with another POSIX
-regex library instead of libpcre2-posix. In this situation, a call to regcomp()
-(in the other library) may succeed, returning zero, but of course putting its
-own data into the regex_t block. In one example the re_pcre2_code field was
-left as NULL, which made pcre2test think it had not got a compiled POSIX regex,
-so it treated the next line as another pattern line, resulting in a confusing
-error message. A check has been added to pcre2test to see if the data returned
-from a successful call of regcomp() are valid for PCRE2's regcomp(). If they
-are not, an error message is output and the pcre2test run is abandoned. The
-message points out the possibility of a mis-linking. Hopefully this will avoid
-some head-scratching the next time this happens.
-
-11. A pattern such as /(?<=((?C)0))/, which has a callout inside a lookbehind
-assertion, caused pcre2test to output a very large number of spaces when the
-callout was taken, making the program appearing to loop.
-
-12. A pattern that included (*ACCEPT) in the middle of a sufficiently deeply
-nested set of parentheses of sufficient size caused an overflow of the
-compiling workspace (which was diagnosed, but of course is not desirable).
-
-13. Detect missing closing parentheses during the pre-pass for group
-identification.
-
-14. Changed some integer variable types and put in a number of casts, following
-a report of compiler warnings from Visual Studio 2013 and a few tests with
-gcc's -Wconversion (which still throws up a lot).
-
-15. Implemented pcre2_code_copy(), and added pushcopy and #popcopy to pcre2test
-for testing it.
-
-16. Change 66 for 10.21 introduced the use of snprintf() in PCRE2's version of
-regerror(). When the error buffer is too small, my version of snprintf() puts a
-binary zero in the final byte. Bug #1801 seems to show that other versions do
-not do this, leading to bad output from pcre2test when it was checking for
-buffer overflow. It no longer assumes a binary zero at the end of a too-small
-regerror() buffer.
-
-17. Fixed typo ("&&" for "&") in pcre2_study(). Fortunately, this could not
-actually affect anything, by sheer luck.
-
-18. Two minor fixes for MSVC compilation: (a) removal of apparently incorrect
-"const" qualifiers in pcre2test and (b) defining snprintf as _snprintf for
-older MSVC compilers. This has been done both in src/pcre2_internal.h for most
-of the library, and also in src/pcre2posix.c, which no longer includes
-pcre2_internal.h (see 24 below).
-
-19. Applied Chris Wilson's patch (Bugzilla #1681) to CMakeLists.txt for MSVC
-static compilation. Subsequently applied Chris Wilson's second patch, putting
-the first patch under a new option instead of being unconditional when
-PCRE_STATIC is set.
-
-20. Updated pcre2grep to set stdout as binary when run under Windows, so as not
-to convert \r\n at the ends of reflected lines into \r\r\n. This required
-ensuring that other output that is written to stdout (e.g. file names) uses the
-appropriate line terminator: \r\n for Windows, \n otherwise.
-
-21. When a line is too long for pcre2grep's internal buffer, show the maximum
-length in the error message.
-
-22. Added support for string callouts to pcre2grep (Zoltan's patch with PH
-additions).
-
-23. RunTest.bat was missing a "set type" line for test 22.
-
-24. The pcre2posix.c file was including pcre2_internal.h, and using some
-"private" knowledge of the data structures. This is unnecessary; the code has
-been re-factored and no longer includes pcre2_internal.h.
-
-25. A racing condition is fixed in JIT reported by Mozilla.
-
-26. Minor code refactor to avoid "array subscript is below array bounds"
-compiler warning.
-
-27. Minor code refactor to avoid "left shift of negative number" warning.
-
-28. Add a bit more sanity checking to pcre2_serialize_decode() and document
-that it expects trusted data.
-
-29. Fix typo in pcre2_jit_test.c
-
-30. Due to an oversight, pcre2grep was not making use of JIT when available.
-This is now fixed.
-
-31. The RunGrepTest script is updated to use the valgrind suppressions file
-when testing with JIT under valgrind (compare 10.21/51 below). The suppressions
-file is updated so that is now the same as for PCRE1: it suppresses the
-Memcheck warnings Addr16 and Cond in unknown objects (that is, JIT-compiled
-code). Also changed smc-check=all to smc-check=all-non-file as was done for
-RunTest (see 4 above).
-
-32. Implemented the PCRE2_NO_JIT option for pcre2_match().
-
-33. Fix typo that gave a compiler error when JIT not supported.
-
-34. Fix comment describing the returns from find_fixedlength().
-
-35. Fix potential negative index in pcre2test.
-
-36. Calls to pcre2_get_error_message() with error numbers that are never
-returned by PCRE2 functions were returning empty strings. Now the error code
-PCRE2_ERROR_BADDATA is returned. A facility has been added to pcre2test to
-show the texts for given error numbers (i.e. to call pcre2_get_error_message()
-and display what it returns) and a few representative error codes are now
-checked in RunTest.
-
-37. Added "&& !defined(__INTEL_COMPILER)" to the test for __GNUC__ in
-pcre2_match.c, in anticipation that this is needed for the same reason it was
-recently added to pcrecpp.cc in PCRE1.
-
-38. Using -o with -M in pcre2grep could cause unnecessary repeated output when
-the match extended over a line boundary, as it tried to find more matches "on
-the same line" - but it was already over the end.
-
-39. Allow \C in lookbehinds and DFA matching in UTF-32 mode (by converting it
-to the same code as '.' when PCRE2_DOTALL is set).
-
-40. Fix two clang compiler warnings in pcre2test when only one code unit width
-is supported.
-
-41. Upgrade RunTest to automatically re-run test 2 with a large (64MiB) stack
-if it fails when running the interpreter with a 16MiB stack (and if changing
-the stack size via pcre2test is possible). This avoids having to manually set a
-large stack size when testing with clang.
-
-42. Fix register overwite in JIT when SSE2 acceleration is enabled.
-
-43. Detect integer overflow in pcre2test pattern and data repetition counts.
-
-44. In pcre2test, ignore "allcaptures" after DFA matching.
-
-45. Fix unaligned accesses on x86. Patch by Marc Mutz.
-
-46. Fix some more clang compiler warnings.
-
-
-Version 10.21 12-January-2016
------------------------------
-
-1. Improve matching speed of patterns starting with + or * in JIT.
-
-2. Use memchr() to find the first character in an unanchored match in 8-bit
-mode in the interpreter. This gives a significant speed improvement.
-
-3. Removed a redundant copy of the opcode_possessify table in the
-pcre2_auto_possessify.c source.
-
-4. Fix typos in dftables.c for z/OS.
-
-5. Change 36 for 10.20 broke the handling of [[:>:]] and [[:<:]] in that
-processing them could involve a buffer overflow if the following character was
-an opening parenthesis.
-
-6. Change 36 for 10.20 also introduced a bug in processing this pattern:
-/((?x)(*:0))#(?'/. Specifically: if a setting of (?x) was followed by a (*MARK)
-setting (which (*:0) is), then (?x) did not get unset at the end of its group
-during the scan for named groups, and hence the external # was incorrectly
-treated as a comment and the invalid (?' at the end of the pattern was not
-diagnosed. This caused a buffer overflow during the real compile. This bug was
-discovered by Karl Skomski with the LLVM fuzzer.
-
-7. Moved the pcre2_find_bracket() function from src/pcre2_compile.c into its
-own source module to avoid a circular dependency between src/pcre2_compile.c
-and src/pcre2_study.c
-
-8. A callout with a string argument containing an opening square bracket, for
-example /(?C$[$)(?<]/, was incorrectly processed and could provoke a buffer
-overflow. This bug was discovered by Karl Skomski with the LLVM fuzzer.
-
-9. The handling of callouts during the pre-pass for named group identification
-has been tightened up.
-
-10. The quantifier {1} can be ignored, whether greedy, non-greedy, or
-possessive. This is a very minor optimization.
-
-11. A possessively repeated conditional group that could match an empty string,
-for example, /(?(R))*+/, was incorrectly compiled.
-
-12. The Unicode tables have been updated to Unicode 8.0.0 (thanks to Christian
-Persch).
-
-13. An empty comment (?#) in a pattern was incorrectly processed and could
-provoke a buffer overflow. This bug was discovered by Karl Skomski with the
-LLVM fuzzer.
-
-14. Fix infinite recursion in the JIT compiler when certain patterns such as
-/(?:|a|){100}x/ are analysed.
-
-15. Some patterns with character classes involving [: and \\ were incorrectly
-compiled and could cause reading from uninitialized memory or an incorrect
-error diagnosis. Examples are: /[[:\\](?<[::]/ and /[[:\\](?'abc')[a:]. The
-first of these bugs was discovered by Karl Skomski with the LLVM fuzzer.
-
-16. Pathological patterns containing many nested occurrences of [: caused
-pcre2_compile() to run for a very long time. This bug was found by the LLVM
-fuzzer.
-
-17. A missing closing parenthesis for a callout with a string argument was not
-being diagnosed, possibly leading to a buffer overflow. This bug was found by
-the LLVM fuzzer.
-
-18. A conditional group with only one branch has an implicit empty alternative
-branch and must therefore be treated as potentially matching an empty string.
-
-19. If (?R was followed by - or + incorrect behaviour happened instead of a
-diagnostic. This bug was discovered by Karl Skomski with the LLVM fuzzer.
-
-20. Another bug that was introduced by change 36 for 10.20: conditional groups
-whose condition was an assertion preceded by an explicit callout with a string
-argument might be incorrectly processed, especially if the string contained \Q.
-This bug was discovered by Karl Skomski with the LLVM fuzzer.
-
-21. Compiling PCRE2 with the sanitize options of clang showed up a number of
-very pedantic coding infelicities and a buffer overflow while checking a UTF-8
-string if the final multi-byte UTF-8 character was truncated.
-
-22. For Perl compatibility in EBCDIC environments, ranges such as a-z in a
-class, where both values are literal letters in the same case, omit the
-non-letter EBCDIC code points within the range.
-
-23. Finding the minimum matching length of complex patterns with back
-references and/or recursions can take a long time. There is now a cut-off that
-gives up trying to find a minimum length when things get too complex.
-
-24. An optimization has been added that speeds up finding the minimum matching
-length for patterns containing repeated capturing groups or recursions.
-
-25. If a pattern contained a back reference to a group whose number was
-duplicated as a result of appearing in a (?|...) group, the computation of the
-minimum matching length gave a wrong result, which could cause incorrect "no
-match" errors. For such patterns, a minimum matching length cannot at present
-be computed.
-
-26. Added a check for integer overflow in conditions (?(<digits>) and
-(?(R<digits>). This omission was discovered by Karl Skomski with the LLVM
-fuzzer.
-
-27. Fixed an issue when \p{Any} inside an xclass did not read the current
-character.
-
-28. If pcre2grep was given the -q option with -c or -l, or when handling a
-binary file, it incorrectly wrote output to stdout.
-
-29. The JIT compiler did not restore the control verb head in case of *THEN
-control verbs. This issue was found by Karl Skomski with a custom LLVM fuzzer.
-
-30. The way recursive references such as (?3) are compiled has been re-written
-because the old way was the cause of many issues. Now, conversion of the group
-number into a pattern offset does not happen until the pattern has been
-completely compiled. This does mean that detection of all infinitely looping
-recursions is postponed till match time. In the past, some easy ones were
-detected at compile time. This re-writing was done in response to yet another
-bug found by the LLVM fuzzer.
-
-31. A test for a back reference to a non-existent group was missing for items
-such as \987. This caused incorrect code to be compiled. This issue was found
-by Karl Skomski with a custom LLVM fuzzer.
-
-32. Error messages for syntax errors following \g and \k were giving inaccurate
-offsets in the pattern.
-
-33. Improve the performance of starting single character repetitions in JIT.
-
-34. (*LIMIT_MATCH=) now gives an error instead of setting the value to 0.
-
-35. Error messages for syntax errors in *LIMIT_MATCH and *LIMIT_RECURSION now
-give the right offset instead of zero.
-
-36. The JIT compiler should not check repeats after a {0,1} repeat byte code.
-This issue was found by Karl Skomski with a custom LLVM fuzzer.
-
-37. The JIT compiler should restore the control chain for empty possessive
-repeats. This issue was found by Karl Skomski with a custom LLVM fuzzer.
-
-38. A bug which was introduced by the single character repetition optimization
-was fixed.
-
-39. Match limit check added to recursion. This issue was found by Karl Skomski
-with a custom LLVM fuzzer.
-
-40. Arrange for the UTF check in pcre2_match() and pcre2_dfa_match() to look
-only at the part of the subject that is relevant when the starting offset is
-non-zero.
-
-41. Improve first character match in JIT with SSE2 on x86.
-
-42. Fix two assertion fails in JIT. These issues were found by Karl Skomski
-with a custom LLVM fuzzer.
-
-43. Correct the setting of CMAKE_C_FLAGS in CMakeLists.txt (patch from Roy Ivy
-III).
-
-44. Fix bug in RunTest.bat for new test 14, and adjust the script for the added
-test (there are now 20 in total).
-
-45. Fixed a corner case of range optimization in JIT.
-
-46. Add the ${*MARK} facility to pcre2_substitute().
-
-47. Modifier lists in pcre2test were splitting at spaces without the required
-commas.
-
-48. Implemented PCRE2_ALT_VERBNAMES.
-
-49. Fixed two issues in JIT. These were found by Karl Skomski with a custom
-LLVM fuzzer.
-
-50. The pcre2test program has been extended by adding the #newline_default
-command. This has made it possible to run the standard tests when PCRE2 is
-compiled with either CR or CRLF as the default newline convention. As part of
-this work, the new command was added to several test files and the testing
-scripts were modified. The pcre2grep tests can now also be run when there is no
-LF in the default newline convention.
-
-51. The RunTest script has been modified so that, when JIT is used and valgrind
-is specified, a valgrind suppressions file is set up to ignore "Invalid read of
-size 16" errors because these are false positives when the hardware supports
-the SSE2 instruction set.
-
-52. It is now possible to have comment lines amid the subject strings in
-pcre2test (and perltest.sh) input.
-
-53. Implemented PCRE2_USE_OFFSET_LIMIT and pcre2_set_offset_limit().
-
-54. Add the null_context modifier to pcre2test so that calling pcre2_compile()
-and the matching functions with NULL contexts can be tested.
-
-55. Implemented PCRE2_SUBSTITUTE_EXTENDED.
-
-56. In a character class such as [\W\p{Any}] where both a negative-type escape
-("not a word character") and a property escape were present, the property
-escape was being ignored.
-
-57. Fixed integer overflow for patterns whose minimum matching length is very,
-very large.
-
-58. Implemented --never-backslash-C.
-
-59. Change 55 above introduced a bug by which certain patterns provoked the
-erroneous error "\ at end of pattern".
-
-60. The special sequences [[:<:]] and [[:>:]] gave rise to incorrect compiling
-errors or other strange effects if compiled in UCP mode. Found with libFuzzer
-and AddressSanitizer.
-
-61. Whitespace at the end of a pcre2test pattern line caused a spurious error
-message if there were only single-character modifiers. It should be ignored.
-
-62. The use of PCRE2_NO_AUTO_CAPTURE could cause incorrect compilation results
-or segmentation errors for some patterns. Found with libFuzzer and
-AddressSanitizer.
-
-63. Very long names in (*MARK) or (*THEN) etc. items could provoke a buffer
-overflow.
-
-64. Improve error message for overly-complicated patterns.
-
-65. Implemented an optional replication feature for patterns in pcre2test, to
-make it easier to test long repetitive patterns. The tests for 63 above are
-converted to use the new feature.
-
-66. In the POSIX wrapper, if regerror() was given too small a buffer, it could
-misbehave.
-
-67. In pcre2_substitute() in UTF mode, the UTF validity check on the
-replacement string was happening before the length setting when the replacement
-string was zero-terminated.
-
-68. In pcre2_substitute() in UTF mode, PCRE2_NO_UTF_CHECK can be set for the
-second and subsequent calls to pcre2_match().
-
-69. There was no check for integer overflow for a replacement group number in
-pcre2_substitute(). An added check for a number greater than the largest group
-number in the pattern means this is not now needed.
-
-70. The PCRE2-specific VERSION condition didn't work correctly if only one
-digit was given after the decimal point, or if more than two digits were given.
-It now works with one or two digits, and gives a compile time error if more are
-given.
-
-71. In pcre2_substitute() there was the possibility of reading one code unit
-beyond the end of the replacement string.
-
-72. The code for checking a subject's UTF-32 validity for a pattern with a
-lookbehind involved an out-of-bounds pointer, which could potentially cause
-trouble in some environments.
-
-73. The maximum lookbehind length was incorrectly calculated for patterns such
-as /(?<=(a)(?-1))x/ which have a recursion within a backreference.
-
-74. Give an error if a lookbehind assertion is longer than 65535 code units.
-
-75. Give an error in pcre2_substitute() if a match ends before it starts (as a
-result of the use of \K).
-
-76. Check the length of subpattern names and the names in (*MARK:xx) etc.
-dynamically to avoid the possibility of integer overflow.
-
-77. Implement pcre2_set_max_pattern_length() so that programs can restrict the
-size of patterns that they are prepared to handle.
-
-78. (*NO_AUTO_POSSESS) was not working.
-
-79. Adding group information caching improves the speed of compiling when
-checking whether a group has a fixed length and/or could match an empty string,
-especially when recursion or subroutine calls are involved. However, this
-cannot be used when (?| is present in the pattern because the same number may
-be used for groups of different sizes. To catch runaway patterns in this
-situation, counts have been introduced to the functions that scan for empty
-branches or compute fixed lengths.
-
-80. Allow for the possibility of the size of the nest_save structure not being
-a factor of the size of the compiling workspace (it currently is).
-
-81. Check for integer overflow in minimum length calculation and cap it at
-65535.
-
-82. Small optimizations in code for finding the minimum matching length.
-
-83. Lock out configuring for EBCDIC with non-8-bit libraries.
-
-84. Test for error code <= 0 in regerror().
-
-85. Check for too many replacements (more than INT_MAX) in pcre2_substitute().
-
-86. Avoid the possibility of computing with an out-of-bounds pointer (though
-not dereferencing it) while handling lookbehind assertions.
-
-87. Failure to get memory for the match data in regcomp() is now given as a
-regcomp() error instead of waiting for regexec() to pick it up.
-
-88. In pcre2_substitute(), ensure that CRLF is not split when it is a valid
-newline sequence.
-
-89. Paranoid check in regcomp() for bad error code from pcre2_compile().
-
-90. Run test 8 (internal offsets and code sizes) for link sizes 3 and 4 as well
-as for link size 2.
-
-91. Document that JIT has a limit on pattern size, and give more information
-about JIT compile failures in pcre2test.
-
-92. Implement PCRE2_INFO_HASBACKSLASHC.
-
-93. Re-arrange valgrind support code in pcre2test to avoid spurious reports
-with JIT (possibly caused by SSE2?).
-
-94. Support offset_limit in JIT.
-
-95. A sequence such as [[:punct:]b] that is, a POSIX character class followed
-by a single ASCII character in a class item, was incorrectly compiled in UCP
-mode. The POSIX class got lost, but only if the single character followed it.
-
-96. [:punct:] in UCP mode was matching some characters in the range 128-255
-that should not have been matched.
-
-97. If [:^ascii:] or [:^xdigit:] are present in a non-negated class, all
-characters with code points greater than 255 are in the class. When a Unicode
-property was also in the class (if PCRE2_UCP is set, escapes such as \w are
-turned into Unicode properties), wide characters were not correctly handled,
-and could fail to match.
-
-98. In pcre2test, make the "startoffset" modifier a synonym of "offset",
-because it sets the "startoffset" parameter for pcre2_match().
-
-99. If PCRE2_AUTO_CALLOUT was set on a pattern that had a (?# comment between
-an item and its qualifier (for example, A(?#comment)?B) pcre2_compile()
-misbehaved. This bug was found by the LLVM fuzzer.
-
-100. The error for an invalid UTF pattern string always gave the code unit
-offset as zero instead of where the invalidity was found.
-
-101. Further to 97 above, negated classes such as [^[:^ascii:]\d] were also not
-working correctly in UCP mode.
-
-102. Similar to 99 above, if an isolated \E was present between an item and its
-qualifier when PCRE2_AUTO_CALLOUT was set, pcre2_compile() misbehaved. This bug
-was found by the LLVM fuzzer.
-
-103. The POSIX wrapper function regexec() crashed if the option REG_STARTEND
-was set when the pmatch argument was NULL. It now returns REG_INVARG.
-
-104. Allow for up to 32-bit numbers in the ordin() function in pcre2grep.
-
-105. An empty \Q\E sequence between an item and its qualifier caused
-pcre2_compile() to misbehave when auto callouts were enabled. This bug
-was found by the LLVM fuzzer.
-
-106. If both PCRE2_ALT_VERBNAMES and PCRE2_EXTENDED were set, and a (*MARK) or
-other verb "name" ended with whitespace immediately before the closing
-parenthesis, pcre2_compile() misbehaved. Example: /(*:abc )/, but only when
-both those options were set.
-
-107. In a number of places pcre2_compile() was not handling NULL characters
-correctly, and pcre2test with the "bincode" modifier was not always correctly
-displaying fields containing NULLS:
-
- (a) Within /x extended #-comments
- (b) Within the "name" part of (*MARK) and other *verbs
- (c) Within the text argument of a callout
-
-108. If a pattern that was compiled with PCRE2_EXTENDED started with white
-space or a #-type comment that was followed by (?-x), which turns off
-PCRE2_EXTENDED, and there was no subsequent (?x) to turn it on again,
-pcre2_compile() assumed that (?-x) applied to the whole pattern and
-consequently mis-compiled it. This bug was found by the LLVM fuzzer. The fix
-for this bug means that a setting of any of the (?imsxJU) options at the start
-of a pattern is no longer transferred to the options that are returned by
-PCRE2_INFO_ALLOPTIONS. In fact, this was an anachronism that should have
-changed when the effects of those options were all moved to compile time.
-
-109. An escaped closing parenthesis in the "name" part of a (*verb) when
-PCRE2_ALT_VERBNAMES was set caused pcre2_compile() to malfunction. This bug
-was found by the LLVM fuzzer.
-
-110. Implemented PCRE2_SUBSTITUTE_UNSET_EMPTY, and updated pcre2test to make it
-possible to test it.
-
-111. "Harden" pcre2test against ridiculously large values in modifiers and
-command line arguments.
-
-112. Implemented PCRE2_SUBSTITUTE_UNKNOWN_UNSET and PCRE2_SUBSTITUTE_OVERFLOW_
-LENGTH.
-
-113. Fix printing of *MARK names that contain binary zeroes in pcre2test.
-
-
-Version 10.20 30-June-2015
---------------------------
-
-1. Callouts with string arguments have been added.
-
-2. Assertion code generator in JIT has been optimized.
-
-3. The invalid pattern (?(?C) has a missing assertion condition at the end. The
-pcre2_compile() function read past the end of the input before diagnosing an
-error. This bug was discovered by the LLVM fuzzer.
-
-4. Implemented pcre2_callout_enumerate().
-
-5. Fix JIT compilation of conditional blocks whose assertion is converted to
-(*FAIL). E.g: /(?(?!))/.
-
-6. The pattern /(?(?!)^)/ caused references to random memory. This bug was
-discovered by the LLVM fuzzer.
-
-7. The assertion (?!) is optimized to (*FAIL). This was not handled correctly
-when this assertion was used as a condition, for example (?(?!)a|b). In
-pcre2_match() it worked by luck; in pcre2_dfa_match() it gave an incorrect
-error about an unsupported item.
-
-8. For some types of pattern, for example /Z*(|d*){216}/, the auto-
-possessification code could take exponential time to complete. A recursion
-depth limit of 1000 has been imposed to limit the resources used by this
-optimization. This infelicity was discovered by the LLVM fuzzer.
-
-9. A pattern such as /(*UTF)[\S\V\H]/, which contains a negated special class
-such as \S in non-UCP mode, explicit wide characters (> 255) can be ignored
-because \S ensures they are all in the class. The code for doing this was
-interacting badly with the code for computing the amount of space needed to
-compile the pattern, leading to a buffer overflow. This bug was discovered by
-the LLVM fuzzer.
-
-10. A pattern such as /((?2)+)((?1))/ which has mutual recursion nested inside
-other kinds of group caused stack overflow at compile time. This bug was
-discovered by the LLVM fuzzer.
-
-11. A pattern such as /(?1)(?#?'){8}(a)/ which had a parenthesized comment
-between a subroutine call and its quantifier was incorrectly compiled, leading
-to buffer overflow or other errors. This bug was discovered by the LLVM fuzzer.
-
-12. The illegal pattern /(?(?<E>.*!.*)?)/ was not being diagnosed as missing an
-assertion after (?(. The code was failing to check the character after (?(?<
-for the ! or = that would indicate a lookbehind assertion. This bug was
-discovered by the LLVM fuzzer.
-
-13. A pattern such as /X((?2)()*+){2}+/ which has a possessive quantifier with
-a fixed maximum following a group that contains a subroutine reference was
-incorrectly compiled and could trigger buffer overflow. This bug was discovered
-by the LLVM fuzzer.
-
-14. Negative relative recursive references such as (?-7) to non-existent
-subpatterns were not being diagnosed and could lead to unpredictable behaviour.
-This bug was discovered by the LLVM fuzzer.
-
-15. The bug fixed in 14 was due to an integer variable that was unsigned when
-it should have been signed. Some other "int" variables, having been checked,
-have either been changed to uint32_t or commented as "must be signed".
-
-16. A mutual recursion within a lookbehind assertion such as (?<=((?2))((?1)))
-caused a stack overflow instead of the diagnosis of a non-fixed length
-lookbehind assertion. This bug was discovered by the LLVM fuzzer.
-
-17. The use of \K in a positive lookbehind assertion in a non-anchored pattern
-(e.g. /(?<=\Ka)/) could make pcre2grep loop.
-
-18. There was a similar problem to 17 in pcre2test for global matches, though
-the code there did catch the loop.
-
-19. If a greedy quantified \X was preceded by \C in UTF mode (e.g. \C\X*),
-and a subsequent item in the pattern caused a non-match, backtracking over the
-repeated \X did not stop, but carried on past the start of the subject, causing
-reference to random memory and/or a segfault. There were also some other cases
-where backtracking after \C could crash. This set of bugs was discovered by the
-LLVM fuzzer.
-
-20. The function for finding the minimum length of a matching string could take
-a very long time if mutual recursion was present many times in a pattern, for
-example, /((?2){73}(?2))((?1))/. A better mutual recursion detection method has
-been implemented. This infelicity was discovered by the LLVM fuzzer.
-
-21. Implemented PCRE2_NEVER_BACKSLASH_C.
-
-22. The feature for string replication in pcre2test could read from freed
-memory if the replication required a buffer to be extended, and it was not
-working properly in 16-bit and 32-bit modes. This issue was discovered by a
-fuzzer: see http://lcamtuf.coredump.cx/afl/.
-
-23. Added the PCRE2_ALT_CIRCUMFLEX option.
-
-24. Adjust the treatment of \8 and \9 to be the same as the current Perl
-behaviour.
-
-25. Static linking against the PCRE2 library using the pkg-config module was
-failing on missing pthread symbols.
-
-26. If a group that contained a recursive back reference also contained a
-forward reference subroutine call followed by a non-forward-reference
-subroutine call, for example /.((?2)(?R)\1)()/, pcre2_compile() failed to
-compile correct code, leading to undefined behaviour or an internally detected
-error. This bug was discovered by the LLVM fuzzer.
-
-27. Quantification of certain items (e.g. atomic back references) could cause
-incorrect code to be compiled when recursive forward references were involved.
-For example, in this pattern: /(?1)()((((((\1++))\x85)+)|))/. This bug was
-discovered by the LLVM fuzzer.
-
-28. A repeated conditional group whose condition was a reference by name caused
-a buffer overflow if there was more than one group with the given name. This
-bug was discovered by the LLVM fuzzer.
-
-29. A recursive back reference by name within a group that had the same name as
-another group caused a buffer overflow. For example: /(?J)(?'d'(?'d'\g{d}))/.
-This bug was discovered by the LLVM fuzzer.
-
-30. A forward reference by name to a group whose number is the same as the
-current group, for example in this pattern: /(?|(\k'Pm')|(?'Pm'))/, caused a
-buffer overflow at compile time. This bug was discovered by the LLVM fuzzer.
-
-31. Fix -fsanitize=undefined warnings for left shifts of 1 by 31 (it treats 1
-as an int; fixed by writing it as 1u).
-
-32. Fix pcre2grep compile when -std=c99 is used with gcc, though it still gives
-a warning for "fileno" unless -std=gnu99 us used.
-
-33. A lookbehind assertion within a set of mutually recursive subpatterns could
-provoke a buffer overflow. This bug was discovered by the LLVM fuzzer.
-
-34. Give an error for an empty subpattern name such as (?'').
-
-35. Make pcre2test give an error if a pattern that follows #forbud_utf contains
-\P, \p, or \X.
-
-36. The way named subpatterns are handled has been refactored. There is now a
-pre-pass over the regex which does nothing other than identify named
-subpatterns and count the total captures. This means that information about
-named patterns is known before the rest of the compile. In particular, it means
-that forward references can be checked as they are encountered. Previously, the
-code for handling forward references was contorted and led to several errors in
-computing the memory requirements for some patterns, leading to buffer
-overflows.
-
-37. There was no check for integer overflow in subroutine calls such as (?123).
-
-38. The table entry for \l in EBCDIC environments was incorrect, leading to its
-being treated as a literal 'l' instead of causing an error.
-
-39. If a non-capturing group containing a conditional group that could match
-an empty string was repeated, it was not identified as matching an empty string
-itself. For example: /^(?:(?(1)x|)+)+$()/.
-
-40. In an EBCDIC environment, pcretest was mishandling the escape sequences
-\a and \e in test subject lines.
-
-41. In an EBCDIC environment, \a in a pattern was converted to the ASCII
-instead of the EBCDIC value.
-
-42. The handling of \c in an EBCDIC environment has been revised so that it is
-now compatible with the specification in Perl's perlebcdic page.
-
-43. Single character repetition in JIT has been improved. 20-30% speedup
-was achieved on certain patterns.
-
-44. The EBCDIC character 0x41 is a non-breaking space, equivalent to 0xa0 in
-ASCII/Unicode. This has now been added to the list of characters that are
-recognized as white space in EBCDIC.
-
-45. When PCRE2 was compiled without Unicode support, the use of \p and \P gave
-an error (correctly) when used outside a class, but did not give an error
-within a class.
-
-46. \h within a class was incorrectly compiled in EBCDIC environments.
-
-47. JIT should return with error when the compiled pattern requires
-more stack space than the maximum.
-
-48. Fixed a memory leak in pcre2grep when a locale is set.
-
-
-Version 10.10 06-March-2015
----------------------------
-
-1. When a pattern is compiled, it remembers the highest back reference so that
-when matching, if the ovector is too small, extra memory can be obtained to
-use instead. A conditional subpattern whose condition is a check on a capture
-having happened, such as, for example in the pattern /^(?:(a)|b)(?(1)A|B)/, is
-another kind of back reference, but it was not setting the highest
-backreference number. This mattered only if pcre2_match() was called with an
-ovector that was too small to hold the capture, and there was no other kind of
-back reference (a situation which is probably quite rare). The effect of the
-bug was that the condition was always treated as FALSE when the capture could
-not be consulted, leading to a incorrect behaviour by pcre2_match(). This bug
-has been fixed.
-
-2. Functions for serialization and deserialization of sets of compiled patterns
-have been added.
-
-3. The value that is returned by PCRE2_INFO_SIZE has been corrected to remove
-excess code units at the end of the data block that may occasionally occur if
-the code for calculating the size over-estimates. This change stops the
-serialization code copying uninitialized data, to which valgrind objects. The
-documentation of PCRE2_INFO_SIZE was incorrect in stating that the size did not
-include the general overhead. This has been corrected.
-
-4. All code units in every slot in the table of group names are now set, again
-in order to avoid accessing uninitialized data when serializing.
-
-5. The (*NO_JIT) feature is implemented.
-
-6. If a bug that caused pcre2_compile() to use more memory than allocated was
-triggered when using valgrind, the code in (3) above passed a stupidly large
-value to valgrind. This caused a crash instead of an "internal error" return.
-
-7. A reference to a duplicated named group (either a back reference or a test
-for being set in a conditional) that occurred in a part of the pattern where
-PCRE2_DUPNAMES was not set caused the amount of memory needed for the pattern
-to be incorrectly calculated, leading to overwriting.
-
-8. A mutually recursive set of back references such as (\2)(\1) caused a
-segfault at compile time (while trying to find the minimum matching length).
-The infinite loop is now broken (with the minimum length unset, that is, zero).
-
-9. If an assertion that was used as a condition was quantified with a minimum
-of zero, matching went wrong. In particular, if the whole group had unlimited
-repetition and could match an empty string, a segfault was likely. The pattern
-(?(?=0)?)+ is an example that caused this. Perl allows assertions to be
-quantified, but not if they are being used as conditions, so the above pattern
-is faulted by Perl. PCRE2 has now been changed so that it also rejects such
-patterns.
-
-10. The error message for an invalid quantifier has been changed from "nothing
-to repeat" to "quantifier does not follow a repeatable item".
-
-11. If a bad UTF string is compiled with NO_UTF_CHECK, it may succeed, but
-scanning the compiled pattern in subsequent auto-possessification can get out
-of step and lead to an unknown opcode. Previously this could have caused an
-infinite loop. Now it generates an "internal error" error. This is a tidyup,
-not a bug fix; passing bad UTF with NO_UTF_CHECK is documented as having an
-undefined outcome.
-
-12. A UTF pattern containing a "not" match of a non-ASCII character and a
-subroutine reference could loop at compile time. Example: /[^\xff]((?1))/.
-
-13. The locale test (RunTest 3) has been upgraded. It now checks that a locale
-that is found in the output of "locale -a" can actually be set by pcre2test
-before it is accepted. Previously, in an environment where a locale was listed
-but would not set (an example does exist), the test would "pass" without
-actually doing anything. Also the fr_CA locale has been added to the list of
-locales that can be used.
-
-14. Fixed a bug in pcre2_substitute(). If a replacement string ended in a
-capturing group number without parentheses, the last character was incorrectly
-literally included at the end of the replacement string.
-
-15. A possessive capturing group such as (a)*+ with a minimum repeat of zero
-failed to allow the zero-repeat case if pcre2_match() was called with an
-ovector too small to capture the group.
-
-16. Improved error message in pcre2test when setting the stack size (-S) fails.
-
-17. Fixed two bugs in CMakeLists.txt: (1) Some lines had got lost in the
-transfer from PCRE1, meaning that CMake configuration failed if "build tests"
-was selected. (2) The file src/pcre2_serialize.c had not been added to the list
-of PCRE2 sources, which caused a failure to build pcre2test.
-
-18. Fixed typo in pcre2_serialize.c (DECL instead of DEFN) that causes problems
-only on Windows.
-
-19. Use binary input when reading back saved serialized patterns in pcre2test.
-
-20. Added RunTest.bat for running the tests under Windows.
-
-21. "make distclean" was not removing config.h, a file that may be created for
-use with CMake.
-
-22. A pattern such as "((?2){0,1999}())?", which has a group containing a
-forward reference repeated a large (but limited) number of times within a
-repeated outer group that has a zero minimum quantifier, caused incorrect code
-to be compiled, leading to the error "internal error: previously-checked
-referenced subpattern not found" when an incorrect memory address was read.
-This bug was reported as "heap overflow", discovered by Kai Lu of Fortinet's
-FortiGuard Labs. (Added 24-March-2015: CVE-2015-2325 was given to this.)
-
-23. A pattern such as "((?+1)(\1))/" containing a forward reference subroutine
-call within a group that also contained a recursive back reference caused
-incorrect code to be compiled. This bug was reported as "heap overflow",
-discovered by Kai Lu of Fortinet's FortiGuard Labs. (Added 24-March-2015:
-CVE-2015-2326 was given to this.)
-
-24. Computing the size of the JIT read-only data in advance has been a source
-of various issues, and new ones are still appear unfortunately. To fix
-existing and future issues, size computation is eliminated from the code,
-and replaced by on-demand memory allocation.
-
-25. A pattern such as /(?i)[A-`]/, where characters in the other case are
-adjacent to the end of the range, and the range contained characters with more
-than one other case, caused incorrect behaviour when compiled in UTF mode. In
-that example, the range a-j was left out of the class.
-
-
-Version 10.00 05-January-2015
------------------------------
-
-Version 10.00 is the first release of PCRE2, a revised API for the PCRE
-library. Changes prior to 10.00 are logged in the ChangeLog file for the old
-API, up to item 20 for release 8.36.
-
-The code of the library was heavily revised as part of the new API
-implementation. Details of each and every modification were not individually
-logged. In addition to the API changes, the following changes were made. They
-are either new functionality, or bug fixes and other noticeable changes of
-behaviour that were implemented after the code had been forked.
-
-1. Including Unicode support at build time is now enabled by default, but it
-can optionally be disabled. It is not enabled by default at run time (no
-change).
-
-2. The test program, now called pcre2test, was re-specified and almost
-completely re-written. Its input is not compatible with input for pcretest.
-
-3. Patterns may start with (*NOTEMPTY) or (*NOTEMPTY_ATSTART) to set the
-PCRE2_NOTEMPTY or PCRE2_NOTEMPTY_ATSTART options for every subject line that is
-matched by that pattern.
-
-4. For the benefit of those who use PCRE2 via some other application, that is,
-not writing the function calls themselves, it is possible to check the PCRE2
-version by matching a pattern such as /(?(VERSION>=10)yes|no)/ against a
-string such as "yesno".
-
-5. There are case-equivalent Unicode characters whose encodings use different
-numbers of code units in UTF-8. U+023A and U+2C65 are one example. (It is
-theoretically possible for this to happen in UTF-16 too.) If a backreference to
-a group containing one of these characters was greedily repeated, and during
-the match a backtrack occurred, the subject might be backtracked by the wrong
-number of code units. For example, if /^(\x{23a})\1*(.)/ is matched caselessly
-(and in UTF-8 mode) against "\x{23a}\x{2c65}\x{2c65}\x{2c65}", group 2 should
-capture the final character, which is the three bytes E2, B1, and A5 in UTF-8.
-Incorrect backtracking meant that group 2 captured only the last two bytes.
-This bug has been fixed; the new code is slower, but it is used only when the
-strings matched by the repetition are not all the same length.
-
-6. A pattern such as /()a/ was not setting the "first character must be 'a'"
-information. This applied to any pattern with a group that matched no
-characters, for example: /(?:(?=.)|(?<!x))a/.
-
-7. When an (*ACCEPT) is triggered inside capturing parentheses, it arranges for
-those parentheses to be closed with whatever has been captured so far. However,
-it was failing to mark any other groups between the highest capture so far and
-the currrent group as "unset". Thus, the ovector for those groups contained
-whatever was previously there. An example is the pattern /(x)|((*ACCEPT))/ when
-matched against "abcd".
-
-8. The pcre2_substitute() function has been implemented.
-
-9. If an assertion used as a condition was quantified with a minimum of zero
-(an odd thing to do, but it happened), SIGSEGV or other misbehaviour could
-occur.
-
-10. The PCRE2_NO_DOTSTAR_ANCHOR option has been implemented.
-
-****
diff --git a/contrib/libs/pcre2/INSTALL b/contrib/libs/pcre2/INSTALL
deleted file mode 100644
index e82fd21de2..0000000000
--- a/contrib/libs/pcre2/INSTALL
+++ /dev/null
@@ -1,368 +0,0 @@
-Installation Instructions
-*************************
-
- Copyright (C) 1994-1996, 1999-2002, 2004-2017, 2020-2021 Free
-Software Foundation, Inc.
-
- Copying and distribution of this file, with or without modification,
-are permitted in any medium without royalty provided the copyright
-notice and this notice are preserved. This file is offered as-is,
-without warranty of any kind.
-
-Basic Installation
-==================
-
- Briefly, the shell command './configure && make && make install'
-should configure, build, and install this package. The following
-more-detailed instructions are generic; see the 'README' file for
-instructions specific to this package. Some packages provide this
-'INSTALL' file but do not implement all of the features documented
-below. The lack of an optional feature in a given package is not
-necessarily a bug. More recommendations for GNU packages can be found
-in *note Makefile Conventions: (standards)Makefile Conventions.
-
- The 'configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation. It uses
-those values to create a 'Makefile' in each directory of the package.
-It may also create one or more '.h' files containing system-dependent
-definitions. Finally, it creates a shell script 'config.status' that
-you can run in the future to recreate the current configuration, and a
-file 'config.log' containing compiler output (useful mainly for
-debugging 'configure').
-
- It can also use an optional file (typically called 'config.cache' and
-enabled with '--cache-file=config.cache' or simply '-C') that saves the
-results of its tests to speed up reconfiguring. Caching is disabled by
-default to prevent problems with accidental use of stale cache files.
-
- If you need to do unusual things to compile the package, please try
-to figure out how 'configure' could check whether to do them, and mail
-diffs or instructions to the address given in the 'README' so they can
-be considered for the next release. If you are using the cache, and at
-some point 'config.cache' contains results you don't want to keep, you
-may remove or edit it.
-
- The file 'configure.ac' (or 'configure.in') is used to create
-'configure' by a program called 'autoconf'. You need 'configure.ac' if
-you want to change it or regenerate 'configure' using a newer version of
-'autoconf'.
-
- The simplest way to compile this package is:
-
- 1. 'cd' to the directory containing the package's source code and type
- './configure' to configure the package for your system.
-
- Running 'configure' might take a while. While running, it prints
- some messages telling which features it is checking for.
-
- 2. Type 'make' to compile the package.
-
- 3. Optionally, type 'make check' to run any self-tests that come with
- the package, generally using the just-built uninstalled binaries.
-
- 4. Type 'make install' to install the programs and any data files and
- documentation. When installing into a prefix owned by root, it is
- recommended that the package be configured and built as a regular
- user, and only the 'make install' phase executed with root
- privileges.
-
- 5. Optionally, type 'make installcheck' to repeat any self-tests, but
- this time using the binaries in their final installed location.
- This target does not install anything. Running this target as a
- regular user, particularly if the prior 'make install' required
- root privileges, verifies that the installation completed
- correctly.
-
- 6. You can remove the program binaries and object files from the
- source code directory by typing 'make clean'. To also remove the
- files that 'configure' created (so you can compile the package for
- a different kind of computer), type 'make distclean'. There is
- also a 'make maintainer-clean' target, but that is intended mainly
- for the package's developers. If you use it, you may have to get
- all sorts of other programs in order to regenerate files that came
- with the distribution.
-
- 7. Often, you can also type 'make uninstall' to remove the installed
- files again. In practice, not all packages have tested that
- uninstallation works correctly, even though it is required by the
- GNU Coding Standards.
-
- 8. Some packages, particularly those that use Automake, provide 'make
- distcheck', which can by used by developers to test that all other
- targets like 'make install' and 'make uninstall' work correctly.
- This target is generally not run by end users.
-
-Compilers and Options
-=====================
-
- Some systems require unusual options for compilation or linking that
-the 'configure' script does not know about. Run './configure --help'
-for details on some of the pertinent environment variables.
-
- You can give 'configure' initial values for configuration parameters
-by setting variables in the command line or in the environment. Here is
-an example:
-
- ./configure CC=c99 CFLAGS=-g LIBS=-lposix
-
- *Note Defining Variables::, for more details.
-
-Compiling For Multiple Architectures
-====================================
-
- You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory. To do this, you can use GNU 'make'. 'cd' to the
-directory where you want the object files and executables to go and run
-the 'configure' script. 'configure' automatically checks for the source
-code in the directory that 'configure' is in and in '..'. This is known
-as a "VPATH" build.
-
- With a non-GNU 'make', it is safer to compile the package for one
-architecture at a time in the source code directory. After you have
-installed the package for one architecture, use 'make distclean' before
-reconfiguring for another architecture.
-
- On MacOS X 10.5 and later systems, you can create libraries and
-executables that work on multiple system types--known as "fat" or
-"universal" binaries--by specifying multiple '-arch' options to the
-compiler but only a single '-arch' option to the preprocessor. Like
-this:
-
- ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
- CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
- CPP="gcc -E" CXXCPP="g++ -E"
-
- This is not guaranteed to produce working output in all cases, you
-may have to build one architecture at a time and combine the results
-using the 'lipo' tool if you have problems.
-
-Installation Names
-==================
-
- By default, 'make install' installs the package's commands under
-'/usr/local/bin', include files under '/usr/local/include', etc. You
-can specify an installation prefix other than '/usr/local' by giving
-'configure' the option '--prefix=PREFIX', where PREFIX must be an
-absolute file name.
-
- You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files. If you
-pass the option '--exec-prefix=PREFIX' to 'configure', the package uses
-PREFIX as the prefix for installing programs and libraries.
-Documentation and other data files still use the regular prefix.
-
- In addition, if you use an unusual directory layout you can give
-options like '--bindir=DIR' to specify different values for particular
-kinds of files. Run 'configure --help' for a list of the directories
-you can set and what kinds of files go in them. In general, the default
-for these options is expressed in terms of '${prefix}', so that
-specifying just '--prefix' will affect all of the other directory
-specifications that were not explicitly provided.
-
- The most portable way to affect installation locations is to pass the
-correct locations to 'configure'; however, many packages provide one or
-both of the following shortcuts of passing variable assignments to the
-'make install' command line to change installation locations without
-having to reconfigure or recompile.
-
- The first method involves providing an override variable for each
-affected directory. For example, 'make install
-prefix=/alternate/directory' will choose an alternate location for all
-directory configuration variables that were expressed in terms of
-'${prefix}'. Any directories that were specified during 'configure',
-but not in terms of '${prefix}', must each be overridden at install time
-for the entire installation to be relocated. The approach of makefile
-variable overrides for each directory variable is required by the GNU
-Coding Standards, and ideally causes no recompilation. However, some
-platforms have known limitations with the semantics of shared libraries
-that end up requiring recompilation when using this method, particularly
-noticeable in packages that use GNU Libtool.
-
- The second method involves providing the 'DESTDIR' variable. For
-example, 'make install DESTDIR=/alternate/directory' will prepend
-'/alternate/directory' before all installation names. The approach of
-'DESTDIR' overrides is not required by the GNU Coding Standards, and
-does not work on platforms that have drive letters. On the other hand,
-it does better at avoiding recompilation issues, and works well even
-when some directory options were not specified in terms of '${prefix}'
-at 'configure' time.
-
-Optional Features
-=================
-
- If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving 'configure' the
-option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'.
-
- Some packages pay attention to '--enable-FEATURE' options to
-'configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to '--with-PACKAGE' options, where PACKAGE
-is something like 'gnu-as' or 'x' (for the X Window System). The
-'README' should mention any '--enable-' and '--with-' options that the
-package recognizes.
-
- For packages that use the X Window System, 'configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the 'configure' options '--x-includes=DIR' and
-'--x-libraries=DIR' to specify their locations.
-
- Some packages offer the ability to configure how verbose the
-execution of 'make' will be. For these packages, running './configure
---enable-silent-rules' sets the default to minimal output, which can be
-overridden with 'make V=1'; while running './configure
---disable-silent-rules' sets the default to verbose, which can be
-overridden with 'make V=0'.
-
-Particular systems
-==================
-
- On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC
-is not installed, it is recommended to use the following options in
-order to use an ANSI C compiler:
-
- ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
-
-and if that doesn't work, install pre-built binaries of GCC for HP-UX.
-
- HP-UX 'make' updates targets which have the same timestamps as their
-prerequisites, which makes it generally unusable when shipped generated
-files such as 'configure' are involved. Use GNU 'make' instead.
-
- On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
-parse its '<wchar.h>' header file. The option '-nodtk' can be used as a
-workaround. If GNU CC is not installed, it is therefore recommended to
-try
-
- ./configure CC="cc"
-
-and if that doesn't work, try
-
- ./configure CC="cc -nodtk"
-
- On Solaris, don't put '/usr/ucb' early in your 'PATH'. This
-directory contains several dysfunctional programs; working variants of
-these programs are available in '/usr/bin'. So, if you need '/usr/ucb'
-in your 'PATH', put it _after_ '/usr/bin'.
-
- On Haiku, software installed for all users goes in '/boot/common',
-not '/usr/local'. It is recommended to use the following options:
-
- ./configure --prefix=/boot/common
-
-Specifying the System Type
-==========================
-
- There may be some features 'configure' cannot figure out
-automatically, but needs to determine by the type of machine the package
-will run on. Usually, assuming the package is built to be run on the
-_same_ architectures, 'configure' can figure that out, but if it prints
-a message saying it cannot guess the machine type, give it the
-'--build=TYPE' option. TYPE can either be a short name for the system
-type, such as 'sun4', or a canonical name which has the form:
-
- CPU-COMPANY-SYSTEM
-
-where SYSTEM can have one of these forms:
-
- OS
- KERNEL-OS
-
- See the file 'config.sub' for the possible values of each field. If
-'config.sub' isn't included in this package, then this package doesn't
-need to know the machine type.
-
- If you are _building_ compiler tools for cross-compiling, you should
-use the option '--target=TYPE' to select the type of system they will
-produce code for.
-
- If you want to _use_ a cross compiler, that generates code for a
-platform different from the build platform, you should specify the
-"host" platform (i.e., that on which the generated programs will
-eventually be run) with '--host=TYPE'.
-
-Sharing Defaults
-================
-
- If you want to set default values for 'configure' scripts to share,
-you can create a site shell script called 'config.site' that gives
-default values for variables like 'CC', 'cache_file', and 'prefix'.
-'configure' looks for 'PREFIX/share/config.site' if it exists, then
-'PREFIX/etc/config.site' if it exists. Or, you can set the
-'CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all 'configure' scripts look for a site script.
-
-Defining Variables
-==================
-
- Variables not defined in a site shell script can be set in the
-environment passed to 'configure'. However, some packages may run
-configure again during the build, and the customized values of these
-variables may be lost. In order to avoid this problem, you should set
-them in the 'configure' command line, using 'VAR=value'. For example:
-
- ./configure CC=/usr/local2/bin/gcc
-
-causes the specified 'gcc' to be used as the C compiler (unless it is
-overridden in the site shell script).
-
-Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an
-Autoconf limitation. Until the limitation is lifted, you can use this
-workaround:
-
- CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
-
-'configure' Invocation
-======================
-
- 'configure' recognizes the following options to control how it
-operates.
-
-'--help'
-'-h'
- Print a summary of all of the options to 'configure', and exit.
-
-'--help=short'
-'--help=recursive'
- Print a summary of the options unique to this package's
- 'configure', and exit. The 'short' variant lists options used only
- in the top level, while the 'recursive' variant lists options also
- present in any nested packages.
-
-'--version'
-'-V'
- Print the version of Autoconf used to generate the 'configure'
- script, and exit.
-
-'--cache-file=FILE'
- Enable the cache: use and save the results of the tests in FILE,
- traditionally 'config.cache'. FILE defaults to '/dev/null' to
- disable caching.
-
-'--config-cache'
-'-C'
- Alias for '--cache-file=config.cache'.
-
-'--quiet'
-'--silent'
-'-q'
- Do not print messages saying which checks are being made. To
- suppress all normal output, redirect it to '/dev/null' (any error
- messages will still be shown).
-
-'--srcdir=DIR'
- Look for the package's source code in directory DIR. Usually
- 'configure' can determine that directory automatically.
-
-'--prefix=DIR'
- Use DIR as the installation prefix. *note Installation Names:: for
- more details, including other options available for fine-tuning the
- installation locations.
-
-'--no-create'
-'-n'
- Run the configure checks, but stop before creating any output
- files.
-
-'configure' also accepts some other, not widely useful, options. Run
-'configure --help' for more details.
diff --git a/contrib/libs/pcre2/NEWS b/contrib/libs/pcre2/NEWS
deleted file mode 100644
index 97da19e071..0000000000
--- a/contrib/libs/pcre2/NEWS
+++ /dev/null
@@ -1,436 +0,0 @@
-News about PCRE2 releases
--------------------------
-
-
-Version 10.42 11-December-2022
-------------------------------
-
-This is an unexpectedly early release to fix a problem that was introduced in
-10.41. ChangeLog number 19 (GitHub #139) added the default definition of
-PCRE2_CALL_CONVENTION to pcre2posix.c instead of pcre2posix.h, which meant that
-programs including pcre2posix.h but not pcre2.h couldn't compile. A new test
-that checks this case has been added.
-
-A couple of other minor issues are also fixed, and a patch for an intermittent
-JIT fault is also included. See ChangeLog and the Git log.
-
-
-Version 10.41 06-December-2022
-------------------------------
-
-This is another mainly bug-fixing and code-tidying release. There is one
-significant upgrade to pcre2grep: it now behaves like GNU grep when matching
-more than one pattern and a later pattern matches at an earlier point in the
-subject when the matched substrings are being identified by colour or by
-offsets.
-
-
-Version 10.40 15-April-2022
----------------------------
-
-This is mostly a bug-fixing and code-tidying release. However, there are some
-extensions to Unicode property handling:
-
-* Added support for Bidi_Class and a number of binary Unicode properties,
-including Bidi_Control.
-
-* A number of changes to script matching for \p and \P:
-
- (a) Script extensions for a character are now coded as a bitmap instead of
- a list of script numbers, which should be faster and does not need a
- loop.
-
- (b) Added the syntax \p{script:xxx} and \p{script_extensions:xxx} (synonyms
- sc and scx).
-
- (c) Changed \p{scriptname} from being the same as \p{sc:scriptname} to being
- the same as \p{scx:scriptname} because this change happened in Perl at
- release 5.26.
-
- (d) The standard Unicode 4-letter abbreviations for script names are now
- recognized.
-
- (e) In accordance with Unicode and Perl's "loose matching" rules, spaces,
- hyphens, and underscores are ignored in property names, which are then
- matched independent of case.
-
-As always, see ChangeLog for a list of all changes (also the Git log).
-
-
-Version 10.39 29-October-2021
------------------------------
-
-This release is happening soon after 10.38 because the bug fix is important.
-
-1. Fix incorrect detection of alternatives in first character search in JIT.
-
-2. Update to Unicode 14.0.0.
-
-3. Some code cleanups (see ChangeLog).
-
-
-Version 10.38 01-October-2021
------------------------------
-
-As well as some bug fixes and tidies (as always, see ChangeLog for details),
-the documentation is updated to list the new URLs, following the move of the
-source repository to GitHub and the mailing list to Google Groups.
-
-* The CMake build system can now build both static and shared libraries in one
-go.
-
-* Following Perl's lead, \K is now locked out in lookaround assertions by
-default, but an option is provided to re-enable the previous behaviour.
-
-
-Version 10.37 26-May-2021
--------------------------
-
-A few more bug fixes and tidies. The only change of real note is the removal of
-the actual POSIX names regcomp etc. from the POSIX wrapper library because
-these have caused issues for some applications (see 10.33 #2 below).
-
-
-Version 10.36 04-December-2020
-------------------------------
-
-Again, mainly bug fixes and tidies. The only enhancements are the addition of
-GNU grep's -m (aka --max-count) option to pcre2grep, and also unifying the
-handling of substitution strings for both -O and callouts in pcre2grep, with
-the addition of $x{...} and $o{...} to allow for characters whose code points
-are greater than 255 in Unicode mode.
-
-NOTE: there is an outstanding issue with JIT support for MacOS on arm64
-hardware. For details, please see Bugzilla issue #2618.
-
-
-Version 10.35 15-April-2020
----------------------------
-
-Bugfixes, tidies, and a few new enhancements.
-
-1. Capturing groups that contain recursive backreferences to themselves are no
-longer automatically atomic, because the restriction is no longer necessary
-as a result of the 10.30 restructuring.
-
-2. Several new options for pcre2_substitute().
-
-3. When Unicode is supported and PCRE2_UCP is set without PCRE2_UTF, Unicode
-character properties are used for upper/lower case computations on characters
-whose code points are greater than 127.
-
-4. The character tables (for low-valued characters) can now more easily be
-saved and restored in binary.
-
-5. Updated to Unicode 13.0.0.
-
-
-Version 10.34 21-November-2019
-------------------------------
-
-Another release with a few enhancements as well as bugfixes and tidies. The
-main new features are:
-
-1. There is now some support for matching in invalid UTF strings.
-
-2. Non-atomic positive lookarounds are implemented in the pcre2_match()
-interpreter, but not in JIT.
-
-3. Added two new functions: pcre2_get_match_data_size() and
-pcre2_maketables_free().
-
-4. Upgraded to Unicode 12.1.0.
-
-
-Version 10.33 16-April-2019
----------------------------
-
-Yet more bugfixes, tidies, and a few enhancements, summarized here (see
-ChangeLog for the full list):
-
-1. Callouts from pcre2_substitute() are now available.
-
-2. The POSIX functions are now all called pcre2_regcomp() etc., with wrapper
-functions that use the standard POSIX names. However, in pcre2posix.h the POSIX
-names are defined as macros. This should help avoid linking with the wrong
-library in some environments, while still exporting the POSIX names for
-pre-existing programs that use them.
-
-3. Some new options:
-
- (a) PCRE2_EXTRA_ESCAPED_CR_IS_LF makes \r behave as \n.
-
- (b) PCRE2_EXTRA_ALT_BSUX enables support for ECMAScript 6's \u{hh...}
- construct.
-
- (c) PCRE2_COPY_MATCHED_SUBJECT causes a copy of a matched subject to be
- made, instead of just remembering a pointer.
-
-4. Some new Perl features:
-
- (a) Perl 5.28's experimental alphabetic names for atomic groups and
- lookaround assertions, for example, (*pla:...) and (*atomic:...).
-
- (b) The new Perl "script run" features (*script_run:...) and
- (*atomic_script_run:...) aka (*sr:...) and (*asr:...).
-
- (c) When PCRE2_UTF is set, allow non-ASCII letters and decimal digits in
- capture group names.
-
-5. --disable-percent-zt disables the use of %zu and %td in formatting strings
-in pcre2test. They were already automatically disabled for VC and older C
-compilers.
-
-6. Some changes related to callouts in pcre2grep:
-
- (a) Support for running an external program under VMS has been added, in
- addition to Windows and fork() support.
-
- (b) --disable-pcre2grep-callout-fork restricts the callout support in
- to the inbuilt echo facility.
-
-
-Version 10.32 10-September-2018
--------------------------------
-
-This is another mainly bugfix and tidying release with a few minor
-enhancements. These are the main ones:
-
-1. pcre2grep now supports the inclusion of binary zeros in patterns that are
-read from files via the -f option.
-
-2. ./configure now supports --enable-jit=auto, which automatically enables JIT
-if the hardware supports it.
-
-3. In pcre2_dfa_match(), internal recursive calls no longer use the stack for
-local workspace and local ovectors. Instead, an initial block of stack is
-reserved, but if this is insufficient, heap memory is used. The heap limit
-parameter now applies to pcre2_dfa_match().
-
-4. Updated to Unicode version 11.0.0.
-
-5. (*ACCEPT:ARG), (*FAIL:ARG), and (*COMMIT:ARG) are now supported.
-
-6. Added support for \N{U+dddd}, but only in Unicode mode.
-
-7. Added support for (?^) to unset all imnsx options.
-
-
-Version 10.31 12-February-2018
-------------------------------
-
-This is mainly a bugfix and tidying release (see ChangeLog for full details).
-However, there are some minor enhancements.
-
-1. New pcre2_config() options: PCRE2_CONFIG_NEVER_BACKSLASH_C and
-PCRE2_CONFIG_COMPILED_WIDTHS.
-
-2. New pcre2_pattern_info() option PCRE2_INFO_EXTRAOPTIONS to retrieve the
-extra compile time options.
-
-3. There are now public names for all the pcre2_compile() error numbers.
-
-4. Added PCRE2_CALLOUT_STARTMATCH and PCRE2_CALLOUT_BACKTRACK bits to a new
-field callout_flags in callout blocks.
-
-
-Version 10.30 14-August-2017
-----------------------------
-
-The full list of changes that includes bugfixes and tidies is, as always, in
-ChangeLog. These are the most important new features:
-
-1. The main interpreter, pcre2_match(), has been refactored into a new version
-that does not use recursive function calls (and therefore the system stack) for
-remembering backtracking positions. This makes --disable-stack-for-recursion a
-NOOP. The new implementation allows backtracking into recursive group calls in
-patterns, making it more compatible with Perl, and also fixes some other
-previously hard-to-do issues. For patterns that have a lot of backtracking, the
-heap is now used, and there is an explicit limit on the amount, settable by
-pcre2_set_heap_limit() or (*LIMIT_HEAP=xxx). The "recursion limit" is retained,
-but is renamed as "depth limit" (though the old names remain for
-compatibility).
-
-There is also a change in the way callouts from pcre2_match() are handled. The
-offset_vector field in the callout block is no longer a pointer to the
-actual ovector that was passed to the matching function in the match data
-block. Instead it points to an internal ovector of a size large enough to hold
-all possible captured substrings in the pattern.
-
-2. The new option PCRE2_ENDANCHORED insists that a pattern match must end at
-the end of the subject.
-
-3. The new option PCRE2_EXTENDED_MORE implements Perl's /xx feature, and
-pcre2test is upgraded to support it. Setting within the pattern by (?xx) is
-also supported.
-
-4. (?n) can be used to set PCRE2_NO_AUTO_CAPTURE, because Perl now has this.
-
-5. Additional compile options in the compile context are now available, and the
-first two are: PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES and
-PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL.
-
-6. The newline type PCRE2_NEWLINE_NUL is now available.
-
-7. The match limit value now also applies to pcre2_dfa_match() as there are
-patterns that can use up a lot of resources without necessarily recursing very
-deeply.
-
-8. The option REG_PEND (a GNU extension) is now available for the POSIX
-wrapper. Also there is a new option PCRE2_LITERAL which is used to support
-REG_NOSPEC.
-
-9. PCRE2_EXTRA_MATCH_LINE and PCRE2_EXTRA_MATCH_WORD are implemented for the
-benefit of pcre2grep, and pcre2grep's -F, -w, and -x options are re-implemented
-using PCRE2_LITERAL, PCRE2_EXTRA_MATCH_WORD, and PCRE2_EXTRA_MATCH_LINE. This
-is tidier and also fixes some bugs.
-
-10. The Unicode tables are upgraded from Unicode 8.0.0 to Unicode 10.0.0.
-
-11. There are some experimental functions for converting foreign patterns
-(globs and POSIX patterns) into PCRE2 patterns.
-
-
-Version 10.23 14-February-2017
-------------------------------
-
-1. ChangeLog has the details of a lot of bug fixes and tidies.
-
-2. There has been a major re-factoring of the pcre2_compile.c file. Most syntax
-checking is now done in the pre-pass that identifies capturing groups. This has
-reduced the amount of duplication and made the code tidier. While doing this,
-some minor bugs and Perl incompatibilities were fixed (see ChangeLog for
-details.)
-
-3. Back references are now permitted in lookbehind assertions when there are
-no duplicated group numbers (that is, (?| has not been used), and, if the
-reference is by name, there is only one group of that name. The referenced
-group must, of course be of fixed length.
-
-4. \g{+<number>} (e.g. \g{+2} ) is now supported. It is a "forward back
-reference" and can be useful in repetitions (compare \g{-<number>} ). Perl does
-not recognize this syntax.
-
-5. pcre2grep now automatically expands its buffer up to a maximum set by
---max-buffer-size.
-
-6. The -t option (grand total) has been added to pcre2grep.
-
-7. A new function called pcre2_code_copy_with_tables() exists to copy a
-compiled pattern along with a private copy of the character tables that is
-uses.
-
-8. A user supplied a number of patches to upgrade pcre2grep under Windows and
-tidy the code.
-
-9. Several updates have been made to pcre2test and test scripts (see
-ChangeLog).
-
-
-Version 10.22 29-July-2016
---------------------------
-
-1. ChangeLog has the details of a number of bug fixes.
-
-2. The POSIX wrapper function regcomp() did not used to support back references
-and subroutine calls if called with the REG_NOSUB option. It now does.
-
-3. A new function, pcre2_code_copy(), is added, to make a copy of a compiled
-pattern.
-
-4. Support for string callouts is added to pcre2grep.
-
-5. Added the PCRE2_NO_JIT option to pcre2_match().
-
-6. The pcre2_get_error_message() function now returns with a negative error
-code if the error number it is given is unknown.
-
-7. Several updates have been made to pcre2test and test scripts (see
-ChangeLog).
-
-
-Version 10.21 12-January-2016
------------------------------
-
-1. Many bugs have been fixed. A large number of them were provoked only by very
-strange pattern input, and were discovered by fuzzers. Some others were
-discovered by code auditing. See ChangeLog for details.
-
-2. The Unicode tables have been updated to Unicode version 8.0.0.
-
-3. For Perl compatibility in EBCDIC environments, ranges such as a-z in a
-class, where both values are literal letters in the same case, omit the
-non-letter EBCDIC code points within the range.
-
-4. There have been a number of enhancements to the pcre2_substitute() function,
-giving more flexibility to replacement facilities. It is now also possible to
-cause the function to return the needed buffer size if the one given is too
-small.
-
-5. The PCRE2_ALT_VERBNAMES option causes the "name" parts of special verbs such
-as (*THEN:name) to be processed for backslashes and to take note of
-PCRE2_EXTENDED.
-
-6. PCRE2_INFO_HASBACKSLASHC makes it possible for a client to find out if a
-pattern uses \C, and --never-backslash-C makes it possible to compile a version
-PCRE2 in which the use of \C is always forbidden.
-
-7. A limit to the length of pattern that can be handled can now be set by
-calling pcre2_set_max_pattern_length().
-
-8. When matching an unanchored pattern, a match can be required to begin within
-a given number of code units after the start of the subject by calling
-pcre2_set_offset_limit().
-
-9. The pcre2test program has been extended to test new facilities, and it can
-now run the tests when LF on its own is not a valid newline sequence.
-
-10. The RunTest script has also been updated to enable more tests to be run.
-
-11. There have been some minor performance enhancements.
-
-
-Version 10.20 30-June-2015
---------------------------
-
-1. Callouts with string arguments and the pcre2_callout_enumerate() function
-have been implemented.
-
-2. The PCRE2_NEVER_BACKSLASH_C option, which locks out the use of \C, is added.
-
-3. The PCRE2_ALT_CIRCUMFLEX option lets ^ match after a newline at the end of a
-subject in multiline mode.
-
-4. The way named subpatterns are handled has been refactored. The previous
-approach had several bugs.
-
-5. The handling of \c in EBCDIC environments has been changed to conform to the
-perlebcdic document. This is an incompatible change.
-
-6. Bugs have been mended, many of them discovered by fuzzers.
-
-
-Version 10.10 06-March-2015
----------------------------
-
-1. Serialization and de-serialization functions have been added to the API,
-making it possible to save and restore sets of compiled patterns, though
-restoration must be done in the same environment that was used for compilation.
-
-2. The (*NO_JIT) feature has been added; this makes it possible for a pattern
-creator to specify that JIT is not to be used.
-
-3. A number of bugs have been fixed. In particular, bugs that caused building
-on Windows using CMake to fail have been mended.
-
-
-Version 10.00 05-January-2015
------------------------------
-
-Version 10.00 is the first release of PCRE2, a revised API for the PCRE
-library. Changes prior to 10.00 are logged in the ChangeLog file for the old
-API, up to item 20 for release 8.36. New programs are recommended to use the
-new library. Programs that use the original (PCRE1) API will need changing
-before linking with the new library.
-
-****
diff --git a/contrib/libs/pcre2/README b/contrib/libs/pcre2/README
deleted file mode 100644
index c88acff8ba..0000000000
--- a/contrib/libs/pcre2/README
+++ /dev/null
@@ -1,924 +0,0 @@
-README file for PCRE2 (Perl-compatible regular expression library)
-------------------------------------------------------------------
-
-PCRE2 is a re-working of the original PCRE1 library to provide an entirely new
-API. Since its initial release in 2015, there has been further development of
-the code and it now differs from PCRE1 in more than just the API. There are new
-features, and the internals have been improved. The original PCRE1 library is
-now obsolete and no longer maintained. The latest release of PCRE2 is available
-in .tar.gz, tar.bz2, or .zip form from this GitHub repository:
-
-https://github.com/PCRE2Project/pcre2/releases
-
-There is a mailing list for discussion about the development of PCRE2 at
-pcre2-dev@googlegroups.com. You can subscribe by sending an email to
-pcre2-dev+subscribe@googlegroups.com.
-
-You can access the archives and also subscribe or manage your subscription
-here:
-
-https://groups.google.com/g/pcre2-dev
-
-Please read the NEWS file if you are upgrading from a previous release. The
-contents of this README file are:
-
- The PCRE2 APIs
- Documentation for PCRE2
- Contributions by users of PCRE2
- Building PCRE2 on non-Unix-like systems
- Building PCRE2 without using autotools
- Building PCRE2 using autotools
- Retrieving configuration information
- Shared libraries
- Cross-compiling using autotools
- Making new tarballs
- Testing PCRE2
- Character tables
- File manifest
-
-
-The PCRE2 APIs
---------------
-
-PCRE2 is written in C, and it has its own API. There are three sets of
-functions, one for the 8-bit library, which processes strings of bytes, one for
-the 16-bit library, which processes strings of 16-bit values, and one for the
-32-bit library, which processes strings of 32-bit values. Unlike PCRE1, there
-are no C++ wrappers.
-
-The distribution does contain a set of C wrapper functions for the 8-bit
-library that are based on the POSIX regular expression API (see the pcre2posix
-man page). These are built into a library called libpcre2-posix. Note that this
-just provides a POSIX calling interface to PCRE2; the regular expressions
-themselves still follow Perl syntax and semantics. The POSIX API is restricted,
-and does not give full access to all of PCRE2's facilities.
-
-The header file for the POSIX-style functions is called pcre2posix.h. The
-official POSIX name is regex.h, but I did not want to risk possible problems
-with existing files of that name by distributing it that way. To use PCRE2 with
-an existing program that uses the POSIX API, pcre2posix.h will have to be
-renamed or pointed at by a link (or the program modified, of course). See the
-pcre2posix documentation for more details.
-
-
-Documentation for PCRE2
------------------------
-
-If you install PCRE2 in the normal way on a Unix-like system, you will end up
-with a set of man pages whose names all start with "pcre2". The one that is
-just called "pcre2" lists all the others. In addition to these man pages, the
-PCRE2 documentation is supplied in two other forms:
-
- 1. There are files called doc/pcre2.txt, doc/pcre2grep.txt, and
- doc/pcre2test.txt in the source distribution. The first of these is a
- concatenation of the text forms of all the section 3 man pages except the
- listing of pcre2demo.c and those that summarize individual functions. The
- other two are the text forms of the section 1 man pages for the pcre2grep
- and pcre2test commands. These text forms are provided for ease of scanning
- with text editors or similar tools. They are installed in
- <prefix>/share/doc/pcre2, where <prefix> is the installation prefix
- (defaulting to /usr/local).
-
- 2. A set of files containing all the documentation in HTML form, hyperlinked
- in various ways, and rooted in a file called index.html, is distributed in
- doc/html and installed in <prefix>/share/doc/pcre2/html.
-
-
-Building PCRE2 on non-Unix-like systems
----------------------------------------
-
-For a non-Unix-like system, please read the file NON-AUTOTOOLS-BUILD, though if
-your system supports the use of "configure" and "make" you may be able to build
-PCRE2 using autotools in the same way as for many Unix-like systems.
-
-PCRE2 can also be configured using CMake, which can be run in various ways
-(command line, GUI, etc). This creates Makefiles, solution files, etc. The file
-NON-AUTOTOOLS-BUILD has information about CMake.
-
-PCRE2 has been compiled on many different operating systems. It should be
-straightforward to build PCRE2 on any system that has a Standard C compiler and
-library, because it uses only Standard C functions.
-
-
-Building PCRE2 without using autotools
---------------------------------------
-
-The use of autotools (in particular, libtool) is problematic in some
-environments, even some that are Unix or Unix-like. See the NON-AUTOTOOLS-BUILD
-file for ways of building PCRE2 without using autotools.
-
-
-Building PCRE2 using autotools
-------------------------------
-
-The following instructions assume the use of the widely used "configure; make;
-make install" (autotools) process.
-
-If you have downloaded and unpacked a PCRE2 release tarball, run the
-"configure" command from the PCRE2 directory, with your current directory set
-to the directory where you want the files to be created. This command is a
-standard GNU "autoconf" configuration script, for which generic instructions
-are supplied in the file INSTALL.
-
-The files in the GitHub repository do not contain "configure". If you have
-downloaded the PCRE2 source files from GitHub, before you can run "configure"
-you must run the shell script called autogen.sh. This runs a number of
-autotools to create a "configure" script (you must of course have the autotools
-commands installed in order to do this).
-
-Most commonly, people build PCRE2 within its own distribution directory, and in
-this case, on many systems, just running "./configure" is sufficient. However,
-the usual methods of changing standard defaults are available. For example:
-
-CFLAGS='-O2 -Wall' ./configure --prefix=/opt/local
-
-This command specifies that the C compiler should be run with the flags '-O2
--Wall' instead of the default, and that "make install" should install PCRE2
-under /opt/local instead of the default /usr/local.
-
-If you want to build in a different directory, just run "configure" with that
-directory as current. For example, suppose you have unpacked the PCRE2 source
-into /source/pcre2/pcre2-xxx, but you want to build it in
-/build/pcre2/pcre2-xxx:
-
-cd /build/pcre2/pcre2-xxx
-/source/pcre2/pcre2-xxx/configure
-
-PCRE2 is written in C and is normally compiled as a C library. However, it is
-possible to build it as a C++ library, though the provided building apparatus
-does not have any features to support this.
-
-There are some optional features that can be included or omitted from the PCRE2
-library. They are also documented in the pcre2build man page.
-
-. By default, both shared and static libraries are built. You can change this
- by adding one of these options to the "configure" command:
-
- --disable-shared
- --disable-static
-
- (See also "Shared libraries on Unix-like systems" below.)
-
-. By default, only the 8-bit library is built. If you add --enable-pcre2-16 to
- the "configure" command, the 16-bit library is also built. If you add
- --enable-pcre2-32 to the "configure" command, the 32-bit library is also
- built. If you want only the 16-bit or 32-bit library, use --disable-pcre2-8
- to disable building the 8-bit library.
-
-. If you want to include support for just-in-time (JIT) compiling, which can
- give large performance improvements on certain platforms, add --enable-jit to
- the "configure" command. This support is available only for certain hardware
- architectures. If you try to enable it on an unsupported architecture, there
- will be a compile time error. If in doubt, use --enable-jit=auto, which
- enables JIT only if the current hardware is supported.
-
-. If you are enabling JIT under SELinux environment you may also want to add
- --enable-jit-sealloc, which enables the use of an executable memory allocator
- that is compatible with SELinux. Warning: this allocator is experimental!
- It does not support fork() operation and may crash when no disk space is
- available. This option has no effect if JIT is disabled.
-
-. If you do not want to make use of the default support for UTF-8 Unicode
- character strings in the 8-bit library, UTF-16 Unicode character strings in
- the 16-bit library, or UTF-32 Unicode character strings in the 32-bit
- library, you can add --disable-unicode to the "configure" command. This
- reduces the size of the libraries. It is not possible to configure one
- library with Unicode support, and another without, in the same configuration.
- It is also not possible to use --enable-ebcdic (see below) with Unicode
- support, so if this option is set, you must also use --disable-unicode.
-
- When Unicode support is available, the use of a UTF encoding still has to be
- enabled by setting the PCRE2_UTF option at run time or starting a pattern
- with (*UTF). When PCRE2 is compiled with Unicode support, its input can only
- either be ASCII or UTF-8/16/32, even when running on EBCDIC platforms.
-
- As well as supporting UTF strings, Unicode support includes support for the
- \P, \p, and \X sequences that recognize Unicode character properties.
- However, only a subset of Unicode properties are supported; see the
- pcre2pattern man page for details. Escape sequences such as \d and \w in
- patterns do not by default make use of Unicode properties, but can be made to
- do so by setting the PCRE2_UCP option or starting a pattern with (*UCP).
-
-. You can build PCRE2 to recognize either CR or LF or the sequence CRLF, or any
- of the preceding, or any of the Unicode newline sequences, or the NUL (zero)
- character as indicating the end of a line. Whatever you specify at build time
- is the default; the caller of PCRE2 can change the selection at run time. The
- default newline indicator is a single LF character (the Unix standard). You
- can specify the default newline indicator by adding --enable-newline-is-cr,
- --enable-newline-is-lf, --enable-newline-is-crlf,
- --enable-newline-is-anycrlf, --enable-newline-is-any, or
- --enable-newline-is-nul to the "configure" command, respectively.
-
-. By default, the sequence \R in a pattern matches any Unicode line ending
- sequence. This is independent of the option specifying what PCRE2 considers
- to be the end of a line (see above). However, the caller of PCRE2 can
- restrict \R to match only CR, LF, or CRLF. You can make this the default by
- adding --enable-bsr-anycrlf to the "configure" command (bsr = "backslash R").
-
-. In a pattern, the escape sequence \C matches a single code unit, even in a
- UTF mode. This can be dangerous because it breaks up multi-code-unit
- characters. You can build PCRE2 with the use of \C permanently locked out by
- adding --enable-never-backslash-C (note the upper case C) to the "configure"
- command. When \C is allowed by the library, individual applications can lock
- it out by calling pcre2_compile() with the PCRE2_NEVER_BACKSLASH_C option.
-
-. PCRE2 has a counter that limits the depth of nesting of parentheses in a
- pattern. This limits the amount of system stack that a pattern uses when it
- is compiled. The default is 250, but you can change it by setting, for
- example,
-
- --with-parens-nest-limit=500
-
-. PCRE2 has a counter that can be set to limit the amount of computing resource
- it uses when matching a pattern. If the limit is exceeded during a match, the
- match fails. The default is ten million. You can change the default by
- setting, for example,
-
- --with-match-limit=500000
-
- on the "configure" command. This is just the default; individual calls to
- pcre2_match() or pcre2_dfa_match() can supply their own value. There is more
- discussion in the pcre2api man page (search for pcre2_set_match_limit).
-
-. There is a separate counter that limits the depth of nested backtracking
- (pcre2_match()) or nested function calls (pcre2_dfa_match()) during a
- matching process, which indirectly limits the amount of heap memory that is
- used, and in the case of pcre2_dfa_match() the amount of stack as well. This
- counter also has a default of ten million, which is essentially "unlimited".
- You can change the default by setting, for example,
-
- --with-match-limit-depth=5000
-
- There is more discussion in the pcre2api man page (search for
- pcre2_set_depth_limit).
-
-. You can also set an explicit limit on the amount of heap memory used by
- the pcre2_match() and pcre2_dfa_match() interpreters:
-
- --with-heap-limit=500
-
- The units are kibibytes (units of 1024 bytes). This limit does not apply when
- the JIT optimization (which has its own memory control features) is used.
- There is more discussion on the pcre2api man page (search for
- pcre2_set_heap_limit).
-
-. In the 8-bit library, the default maximum compiled pattern size is around
- 64 kibibytes. You can increase this by adding --with-link-size=3 to the
- "configure" command. PCRE2 then uses three bytes instead of two for offsets
- to different parts of the compiled pattern. In the 16-bit library,
- --with-link-size=3 is the same as --with-link-size=4, which (in both
- libraries) uses four-byte offsets. Increasing the internal link size reduces
- performance in the 8-bit and 16-bit libraries. In the 32-bit library, the
- link size setting is ignored, as 4-byte offsets are always used.
-
-. For speed, PCRE2 uses four tables for manipulating and identifying characters
- whose code point values are less than 256. By default, it uses a set of
- tables for ASCII encoding that is part of the distribution. If you specify
-
- --enable-rebuild-chartables
-
- a program called pcre2_dftables is compiled and run in the default C locale
- when you obey "make". It builds a source file called pcre2_chartables.c. If
- you do not specify this option, pcre2_chartables.c is created as a copy of
- pcre2_chartables.c.dist. See "Character tables" below for further
- information.
-
-. It is possible to compile PCRE2 for use on systems that use EBCDIC as their
- character code (as opposed to ASCII/Unicode) by specifying
-
- --enable-ebcdic --disable-unicode
-
- This automatically implies --enable-rebuild-chartables (see above). However,
- when PCRE2 is built this way, it always operates in EBCDIC. It cannot support
- both EBCDIC and UTF-8/16/32. There is a second option, --enable-ebcdic-nl25,
- which specifies that the code value for the EBCDIC NL character is 0x25
- instead of the default 0x15.
-
-. If you specify --enable-debug, additional debugging code is included in the
- build. This option is intended for use by the PCRE2 maintainers.
-
-. In environments where valgrind is installed, if you specify
-
- --enable-valgrind
-
- PCRE2 will use valgrind annotations to mark certain memory regions as
- unaddressable. This allows it to detect invalid memory accesses, and is
- mostly useful for debugging PCRE2 itself.
-
-. In environments where the gcc compiler is used and lcov is installed, if you
- specify
-
- --enable-coverage
-
- the build process implements a code coverage report for the test suite. The
- report is generated by running "make coverage". If ccache is installed on
- your system, it must be disabled when building PCRE2 for coverage reporting.
- You can do this by setting the environment variable CCACHE_DISABLE=1 before
- running "make" to build PCRE2. There is more information about coverage
- reporting in the "pcre2build" documentation.
-
-. When JIT support is enabled, pcre2grep automatically makes use of it, unless
- you add --disable-pcre2grep-jit to the "configure" command.
-
-. There is support for calling external programs during matching in the
- pcre2grep command, using PCRE2's callout facility with string arguments. This
- support can be disabled by adding --disable-pcre2grep-callout to the
- "configure" command. There are two kinds of callout: one that generates
- output from inbuilt code, and another that calls an external program. The
- latter has special support for Windows and VMS; otherwise it assumes the
- existence of the fork() function. This facility can be disabled by adding
- --disable-pcre2grep-callout-fork to the "configure" command.
-
-. The pcre2grep program currently supports only 8-bit data files, and so
- requires the 8-bit PCRE2 library. It is possible to compile pcre2grep to use
- libz and/or libbz2, in order to read .gz and .bz2 files (respectively), by
- specifying one or both of
-
- --enable-pcre2grep-libz
- --enable-pcre2grep-libbz2
-
- Of course, the relevant libraries must be installed on your system.
-
-. The default starting size (in bytes) of the internal buffer used by pcre2grep
- can be set by, for example:
-
- --with-pcre2grep-bufsize=51200
-
- The value must be a plain integer. The default is 20480. The amount of memory
- used by pcre2grep is actually three times this number, to allow for "before"
- and "after" lines. If very long lines are encountered, the buffer is
- automatically enlarged, up to a fixed maximum size.
-
-. The default maximum size of pcre2grep's internal buffer can be set by, for
- example:
-
- --with-pcre2grep-max-bufsize=2097152
-
- The default is either 1048576 or the value of --with-pcre2grep-bufsize,
- whichever is the larger.
-
-. It is possible to compile pcre2test so that it links with the libreadline
- or libedit libraries, by specifying, respectively,
-
- --enable-pcre2test-libreadline or --enable-pcre2test-libedit
-
- If this is done, when pcre2test's input is from a terminal, it reads it using
- the readline() function. This provides line-editing and history facilities.
- Note that libreadline is GPL-licenced, so if you distribute a binary of
- pcre2test linked in this way, there may be licensing issues. These can be
- avoided by linking with libedit (which has a BSD licence) instead.
-
- Enabling libreadline causes the -lreadline option to be added to the
- pcre2test build. In many operating environments with a sytem-installed
- readline library this is sufficient. However, in some environments (e.g. if
- an unmodified distribution version of readline is in use), it may be
- necessary to specify something like LIBS="-lncurses" as well. This is
- because, to quote the readline INSTALL, "Readline uses the termcap functions,
- but does not link with the termcap or curses library itself, allowing
- applications which link with readline the option to choose an appropriate
- library." If you get error messages about missing functions tgetstr, tgetent,
- tputs, tgetflag, or tgoto, this is the problem, and linking with the ncurses
- library should fix it.
-
-. The C99 standard defines formatting modifiers z and t for size_t and
- ptrdiff_t values, respectively. By default, PCRE2 uses these modifiers in
- environments other than Microsoft Visual Studio versions earlier than 2013
- when __STDC_VERSION__ is defined and has a value greater than or equal to
- 199901L (indicating C99). However, there is at least one environment that
- claims to be C99 but does not support these modifiers. If
- --disable-percent-zt is specified, no use is made of the z or t modifiers.
- Instead of %td or %zu, %lu is used, with a cast for size_t values.
-
-. There is a special option called --enable-fuzz-support for use by people who
- want to run fuzzing tests on PCRE2. At present this applies only to the 8-bit
- library. If set, it causes an extra library called libpcre2-fuzzsupport.a to
- be built, but not installed. This contains a single function called
- LLVMFuzzerTestOneInput() whose arguments are a pointer to a string and the
- length of the string. When called, this function tries to compile the string
- as a pattern, and if that succeeds, to match it. This is done both with no
- options and with some random options bits that are generated from the string.
- Setting --enable-fuzz-support also causes a binary called pcre2fuzzcheck to
- be created. This is normally run under valgrind or used when PCRE2 is
- compiled with address sanitizing enabled. It calls the fuzzing function and
- outputs information about what it is doing. The input strings are specified
- by arguments: if an argument starts with "=" the rest of it is a literal
- input string. Otherwise, it is assumed to be a file name, and the contents
- of the file are the test string.
-
-. Releases before 10.30 could be compiled with --disable-stack-for-recursion,
- which caused pcre2_match() to use individual blocks on the heap for
- backtracking instead of recursive function calls (which use the stack). This
- is now obsolete because pcre2_match() was refactored always to use the heap
- (in a much more efficient way than before). This option is retained for
- backwards compatibility, but has no effect other than to output a warning.
-
-The "configure" script builds the following files for the basic C library:
-
-. Makefile the makefile that builds the library
-. src/config.h build-time configuration options for the library
-. src/pcre2.h the public PCRE2 header file
-. pcre2-config script that shows the building settings such as CFLAGS
- that were set for "configure"
-. libpcre2-8.pc )
-. libpcre2-16.pc ) data for the pkg-config command
-. libpcre2-32.pc )
-. libpcre2-posix.pc )
-. libtool script that builds shared and/or static libraries
-
-Versions of config.h and pcre2.h are distributed in the src directory of PCRE2
-tarballs under the names config.h.generic and pcre2.h.generic. These are
-provided for those who have to build PCRE2 without using "configure" or CMake.
-If you use "configure" or CMake, the .generic versions are not used.
-
-The "configure" script also creates config.status, which is an executable
-script that can be run to recreate the configuration, and config.log, which
-contains compiler output from tests that "configure" runs.
-
-Once "configure" has run, you can run "make". This builds whichever of the
-libraries libpcre2-8, libpcre2-16 and libpcre2-32 are configured, and a test
-program called pcre2test. If you enabled JIT support with --enable-jit, another
-test program called pcre2_jit_test is built as well. If the 8-bit library is
-built, libpcre2-posix, pcre2posix_test, and the pcre2grep command are also
-built. Running "make" with the -j option may speed up compilation on
-multiprocessor systems.
-
-The command "make check" runs all the appropriate tests. Details of the PCRE2
-tests are given below in a separate section of this document. The -j option of
-"make" can also be used when running the tests.
-
-You can use "make install" to install PCRE2 into live directories on your
-system. The following are installed (file names are all relative to the
-<prefix> that is set when "configure" is run):
-
- Commands (bin):
- pcre2test
- pcre2grep (if 8-bit support is enabled)
- pcre2-config
-
- Libraries (lib):
- libpcre2-8 (if 8-bit support is enabled)
- libpcre2-16 (if 16-bit support is enabled)
- libpcre2-32 (if 32-bit support is enabled)
- libpcre2-posix (if 8-bit support is enabled)
-
- Configuration information (lib/pkgconfig):
- libpcre2-8.pc
- libpcre2-16.pc
- libpcre2-32.pc
- libpcre2-posix.pc
-
- Header files (include):
- pcre2.h
- pcre2posix.h
-
- Man pages (share/man/man{1,3}):
- pcre2grep.1
- pcre2test.1
- pcre2-config.1
- pcre2.3
- pcre2*.3 (lots more pages, all starting "pcre2")
-
- HTML documentation (share/doc/pcre2/html):
- index.html
- *.html (lots more pages, hyperlinked from index.html)
-
- Text file documentation (share/doc/pcre2):
- AUTHORS
- COPYING
- ChangeLog
- LICENCE
- NEWS
- README
- pcre2.txt (a concatenation of the man(3) pages)
- pcre2test.txt the pcre2test man page
- pcre2grep.txt the pcre2grep man page
- pcre2-config.txt the pcre2-config man page
-
-If you want to remove PCRE2 from your system, you can run "make uninstall".
-This removes all the files that "make install" installed. However, it does not
-remove any directories, because these are often shared with other programs.
-
-
-Retrieving configuration information
-------------------------------------
-
-Running "make install" installs the command pcre2-config, which can be used to
-recall information about the PCRE2 configuration and installation. For example:
-
- pcre2-config --version
-
-prints the version number, and
-
- pcre2-config --libs8
-
-outputs information about where the 8-bit library is installed. This command
-can be included in makefiles for programs that use PCRE2, saving the programmer
-from having to remember too many details. Run pcre2-config with no arguments to
-obtain a list of possible arguments.
-
-The pkg-config command is another system for saving and retrieving information
-about installed libraries. Instead of separate commands for each library, a
-single command is used. For example:
-
- pkg-config --libs libpcre2-16
-
-The data is held in *.pc files that are installed in a directory called
-<prefix>/lib/pkgconfig.
-
-
-Shared libraries
-----------------
-
-The default distribution builds PCRE2 as shared libraries and static libraries,
-as long as the operating system supports shared libraries. Shared library
-support relies on the "libtool" script which is built as part of the
-"configure" process.
-
-The libtool script is used to compile and link both shared and static
-libraries. They are placed in a subdirectory called .libs when they are newly
-built. The programs pcre2test and pcre2grep are built to use these uninstalled
-libraries (by means of wrapper scripts in the case of shared libraries). When
-you use "make install" to install shared libraries, pcre2grep and pcre2test are
-automatically re-built to use the newly installed shared libraries before being
-installed themselves. However, the versions left in the build directory still
-use the uninstalled libraries.
-
-To build PCRE2 using static libraries only you must use --disable-shared when
-configuring it. For example:
-
-./configure --prefix=/usr/gnu --disable-shared
-
-Then run "make" in the usual way. Similarly, you can use --disable-static to
-build only shared libraries.
-
-
-Cross-compiling using autotools
--------------------------------
-
-You can specify CC and CFLAGS in the normal way to the "configure" command, in
-order to cross-compile PCRE2 for some other host. However, you should NOT
-specify --enable-rebuild-chartables, because if you do, the pcre2_dftables.c
-source file is compiled and run on the local host, in order to generate the
-inbuilt character tables (the pcre2_chartables.c file). This will probably not
-work, because pcre2_dftables.c needs to be compiled with the local compiler,
-not the cross compiler.
-
-When --enable-rebuild-chartables is not specified, pcre2_chartables.c is
-created by making a copy of pcre2_chartables.c.dist, which is a default set of
-tables that assumes ASCII code. Cross-compiling with the default tables should
-not be a problem.
-
-If you need to modify the character tables when cross-compiling, you should
-move pcre2_chartables.c.dist out of the way, then compile pcre2_dftables.c by
-hand and run it on the local host to make a new version of
-pcre2_chartables.c.dist. See the pcre2build section "Creating character tables
-at build time" for more details.
-
-
-Making new tarballs
--------------------
-
-The command "make dist" creates three PCRE2 tarballs, in tar.gz, tar.bz2, and
-zip formats. The command "make distcheck" does the same, but then does a trial
-build of the new distribution to ensure that it works.
-
-If you have modified any of the man page sources in the doc directory, you
-should first run the PrepareRelease script before making a distribution. This
-script creates the .txt and HTML forms of the documentation from the man pages.
-
-
-Testing PCRE2
--------------
-
-To test the basic PCRE2 library on a Unix-like system, run the RunTest script.
-There is another script called RunGrepTest that tests the pcre2grep command.
-When the 8-bit library is built, a test program for the POSIX wrapper, called
-pcre2posix_test, is compiled, and when JIT support is enabled, a test program
-called pcre2_jit_test is built. The scripts and the program tests are all run
-when you obey "make check". For other environments, see the instructions in
-NON-AUTOTOOLS-BUILD.
-
-The RunTest script runs the pcre2test test program (which is documented in its
-own man page) on each of the relevant testinput files in the testdata
-directory, and compares the output with the contents of the corresponding
-testoutput files. RunTest uses a file called testtry to hold the main output
-from pcre2test. Other files whose names begin with "test" are used as working
-files in some tests.
-
-Some tests are relevant only when certain build-time options were selected. For
-example, the tests for UTF-8/16/32 features are run only when Unicode support
-is available. RunTest outputs a comment when it skips a test.
-
-Many (but not all) of the tests that are not skipped are run twice if JIT
-support is available. On the second run, JIT compilation is forced. This
-testing can be suppressed by putting "-nojit" on the RunTest command line.
-
-The entire set of tests is run once for each of the 8-bit, 16-bit and 32-bit
-libraries that are enabled. If you want to run just one set of tests, call
-RunTest with either the -8, -16 or -32 option.
-
-If valgrind is installed, you can run the tests under it by putting "-valgrind"
-on the RunTest command line. To run pcre2test on just one or more specific test
-files, give their numbers as arguments to RunTest, for example:
-
- RunTest 2 7 11
-
-You can also specify ranges of tests such as 3-6 or 3- (meaning 3 to the
-end), or a number preceded by ~ to exclude a test. For example:
-
- Runtest 3-15 ~10
-
-This runs tests 3 to 15, excluding test 10, and just ~13 runs all the tests
-except test 13. Whatever order the arguments are in, the tests are always run
-in numerical order.
-
-You can also call RunTest with the single argument "list" to cause it to output
-a list of tests.
-
-The test sequence starts with "test 0", which is a special test that has no
-input file, and whose output is not checked. This is because it will be
-different on different hardware and with different configurations. The test
-exists in order to exercise some of pcre2test's code that would not otherwise
-be run.
-
-Tests 1 and 2 can always be run, as they expect only plain text strings (not
-UTF) and make no use of Unicode properties. The first test file can be fed
-directly into the perltest.sh script to check that Perl gives the same results.
-The only difference you should see is in the first few lines, where the Perl
-version is given instead of the PCRE2 version. The second set of tests check
-auxiliary functions, error detection, and run-time flags that are specific to
-PCRE2. It also uses the debugging flags to check some of the internals of
-pcre2_compile().
-
-If you build PCRE2 with a locale setting that is not the standard C locale, the
-character tables may be different (see next paragraph). In some cases, this may
-cause failures in the second set of tests. For example, in a locale where the
-isprint() function yields TRUE for characters in the range 128-255, the use of
-[:isascii:] inside a character class defines a different set of characters, and
-this shows up in this test as a difference in the compiled code, which is being
-listed for checking. For example, where the comparison test output contains
-[\x00-\x7f] the test might contain [\x00-\xff], and similarly in some other
-cases. This is not a bug in PCRE2.
-
-Test 3 checks pcre2_maketables(), the facility for building a set of character
-tables for a specific locale and using them instead of the default tables. The
-script uses the "locale" command to check for the availability of the "fr_FR",
-"french", or "fr" locale, and uses the first one that it finds. If the "locale"
-command fails, or if its output doesn't include "fr_FR", "french", or "fr" in
-the list of available locales, the third test cannot be run, and a comment is
-output to say why. If running this test produces an error like this:
-
- ** Failed to set locale "fr_FR"
-
-it means that the given locale is not available on your system, despite being
-listed by "locale". This does not mean that PCRE2 is broken. There are three
-alternative output files for the third test, because three different versions
-of the French locale have been encountered. The test passes if its output
-matches any one of them.
-
-Tests 4 and 5 check UTF and Unicode property support, test 4 being compatible
-with the perltest.sh script, and test 5 checking PCRE2-specific things.
-
-Tests 6 and 7 check the pcre2_dfa_match() alternative matching function, in
-non-UTF mode and UTF-mode with Unicode property support, respectively.
-
-Test 8 checks some internal offsets and code size features, but it is run only
-when Unicode support is enabled. The output is different in 8-bit, 16-bit, and
-32-bit modes and for different link sizes, so there are different output files
-for each mode and link size.
-
-Tests 9 and 10 are run only in 8-bit mode, and tests 11 and 12 are run only in
-16-bit and 32-bit modes. These are tests that generate different output in
-8-bit mode. Each pair are for general cases and Unicode support, respectively.
-
-Test 13 checks the handling of non-UTF characters greater than 255 by
-pcre2_dfa_match() in 16-bit and 32-bit modes.
-
-Test 14 contains some special UTF and UCP tests that give different output for
-different code unit widths.
-
-Test 15 contains a number of tests that must not be run with JIT. They check,
-among other non-JIT things, the match-limiting features of the interpretive
-matcher.
-
-Test 16 is run only when JIT support is not available. It checks that an
-attempt to use JIT has the expected behaviour.
-
-Test 17 is run only when JIT support is available. It checks JIT complete and
-partial modes, match-limiting under JIT, and other JIT-specific features.
-
-Tests 18 and 19 are run only in 8-bit mode. They check the POSIX interface to
-the 8-bit library, without and with Unicode support, respectively.
-
-Test 20 checks the serialization functions by writing a set of compiled
-patterns to a file, and then reloading and checking them.
-
-Tests 21 and 22 test \C support when the use of \C is not locked out, without
-and with UTF support, respectively. Test 23 tests \C when it is locked out.
-
-Tests 24 and 25 test the experimental pattern conversion functions, without and
-with UTF support, respectively.
-
-Test 26 checks Unicode property support using tests that are generated
-automatically from the Unicode data tables.
-
-
-Character tables
-----------------
-
-For speed, PCRE2 uses four tables for manipulating and identifying characters
-whose code point values are less than 256. By default, a set of tables that is
-built into the library is used. The pcre2_maketables() function can be called
-by an application to create a new set of tables in the current locale. This are
-passed to PCRE2 by calling pcre2_set_character_tables() to put a pointer into a
-compile context.
-
-The source file called pcre2_chartables.c contains the default set of tables.
-By default, this is created as a copy of pcre2_chartables.c.dist, which
-contains tables for ASCII coding. However, if --enable-rebuild-chartables is
-specified for ./configure, a new version of pcre2_chartables.c is built by the
-program pcre2_dftables (compiled from pcre2_dftables.c), which uses the ANSI C
-character handling functions such as isalnum(), isalpha(), isupper(),
-islower(), etc. to build the table sources. This means that the default C
-locale that is set for your system will control the contents of these default
-tables. You can change the default tables by editing pcre2_chartables.c and
-then re-building PCRE2. If you do this, you should take care to ensure that the
-file does not get automatically re-generated. The best way to do this is to
-move pcre2_chartables.c.dist out of the way and replace it with your customized
-tables.
-
-When the pcre2_dftables program is run as a result of specifying
---enable-rebuild-chartables, it uses the default C locale that is set on your
-system. It does not pay attention to the LC_xxx environment variables. In other
-words, it uses the system's default locale rather than whatever the compiling
-user happens to have set. If you really do want to build a source set of
-character tables in a locale that is specified by the LC_xxx variables, you can
-run the pcre2_dftables program by hand with the -L option. For example:
-
- ./pcre2_dftables -L pcre2_chartables.c.special
-
-The second argument names the file where the source code for the tables is
-written. The first two 256-byte tables provide lower casing and case flipping
-functions, respectively. The next table consists of a number of 32-byte bit
-maps which identify certain character classes such as digits, "word"
-characters, white space, etc. These are used when building 32-byte bit maps
-that represent character classes for code points less than 256. The final
-256-byte table has bits indicating various character types, as follows:
-
- 1 white space character
- 2 letter
- 4 lower case letter
- 8 decimal digit
- 16 alphanumeric or '_'
-
-You can also specify -b (with or without -L) when running pcre2_dftables. This
-causes the tables to be written in binary instead of as source code. A set of
-binary tables can be loaded into memory by an application and passed to
-pcre2_compile() in the same way as tables created dynamically by calling
-pcre2_maketables(). The tables are just a string of bytes, independent of
-hardware characteristics such as endianness. This means they can be bundled
-with an application that runs in different environments, to ensure consistent
-behaviour.
-
-See also the pcre2build section "Creating character tables at build time".
-
-
-File manifest
--------------
-
-The distribution should contain the files listed below.
-
-(A) Source files for the PCRE2 library functions and their headers are found in
- the src directory:
-
- src/pcre2_dftables.c auxiliary program for building pcre2_chartables.c
- when --enable-rebuild-chartables is specified
-
- src/pcre2_chartables.c.dist a default set of character tables that assume
- ASCII coding; unless --enable-rebuild-chartables is
- specified, used by copying to pcre2_chartables.c
-
- src/pcre2posix.c )
- src/pcre2_auto_possess.c )
- src/pcre2_compile.c )
- src/pcre2_config.c )
- src/pcre2_context.c )
- src/pcre2_convert.c )
- src/pcre2_dfa_match.c )
- src/pcre2_error.c )
- src/pcre2_extuni.c )
- src/pcre2_find_bracket.c )
- src/pcre2_jit_compile.c )
- src/pcre2_jit_match.c ) sources for the functions in the library,
- src/pcre2_jit_misc.c ) and some internal functions that they use
- src/pcre2_maketables.c )
- src/pcre2_match.c )
- src/pcre2_match_data.c )
- src/pcre2_newline.c )
- src/pcre2_ord2utf.c )
- src/pcre2_pattern_info.c )
- src/pcre2_script_run.c )
- src/pcre2_serialize.c )
- src/pcre2_string_utils.c )
- src/pcre2_study.c )
- src/pcre2_substitute.c )
- src/pcre2_substring.c )
- src/pcre2_tables.c )
- src/pcre2_ucd.c )
- src/pcre2_ucptables.c )
- src/pcre2_valid_utf.c )
- src/pcre2_xclass.c )
-
- src/pcre2_printint.c debugging function that is used by pcre2test,
- src/pcre2_fuzzsupport.c function for (optional) fuzzing support
-
- src/config.h.in template for config.h, when built by "configure"
- src/pcre2.h.in template for pcre2.h when built by "configure"
- src/pcre2posix.h header for the external POSIX wrapper API
- src/pcre2_internal.h header for internal use
- src/pcre2_intmodedep.h a mode-specific internal header
- src/pcre2_jit_neon_inc.h header used by JIT
- src/pcre2_jit_simd_inc.h header used by JIT
- src/pcre2_ucp.h header for Unicode property handling
-
- sljit/* source files for the JIT compiler
-
-(B) Source files for programs that use PCRE2:
-
- src/pcre2demo.c simple demonstration of coding calls to PCRE2
- src/pcre2grep.c source of a grep utility that uses PCRE2
- src/pcre2test.c comprehensive test program
- src/pcre2_jit_test.c JIT test program
- src/pcre2posix_test.c POSIX wrapper API test program
-
-(C) Auxiliary files:
-
- 132html script to turn "man" pages into HTML
- AUTHORS information about the author of PCRE2
- ChangeLog log of changes to the code
- CleanTxt script to clean nroff output for txt man pages
- Detrail script to remove trailing spaces
- HACKING some notes about the internals of PCRE2
- INSTALL generic installation instructions
- LICENCE conditions for the use of PCRE2
- COPYING the same, using GNU's standard name
- Makefile.in ) template for Unix Makefile, which is built by
- ) "configure"
- Makefile.am ) the automake input that was used to create
- ) Makefile.in
- NEWS important changes in this release
- NON-AUTOTOOLS-BUILD notes on building PCRE2 without using autotools
- PrepareRelease script to make preparations for "make dist"
- README this file
- RunTest a Unix shell script for running tests
- RunGrepTest a Unix shell script for pcre2grep tests
- aclocal.m4 m4 macros (generated by "aclocal")
- config.guess ) files used by libtool,
- config.sub ) used only when building a shared library
- configure a configuring shell script (built by autoconf)
- configure.ac ) the autoconf input that was used to build
- ) "configure" and config.h
- depcomp ) script to find program dependencies, generated by
- ) automake
- doc/*.3 man page sources for PCRE2
- doc/*.1 man page sources for pcre2grep and pcre2test
- doc/index.html.src the base HTML page
- doc/html/* HTML documentation
- doc/pcre2.txt plain text version of the man pages
- doc/pcre2test.txt plain text documentation of test program
- install-sh a shell script for installing files
- libpcre2-8.pc.in template for libpcre2-8.pc for pkg-config
- libpcre2-16.pc.in template for libpcre2-16.pc for pkg-config
- libpcre2-32.pc.in template for libpcre2-32.pc for pkg-config
- libpcre2-posix.pc.in template for libpcre2-posix.pc for pkg-config
- ltmain.sh file used to build a libtool script
- missing ) common stub for a few missing GNU programs while
- ) installing, generated by automake
- mkinstalldirs script for making install directories
- perltest.sh Script for running a Perl test program
- pcre2-config.in source of script which retains PCRE2 information
- testdata/testinput* test data for main library tests
- testdata/testoutput* expected test results
- testdata/grep* input and output for pcre2grep tests
- testdata/* other supporting test files
-
-(D) Auxiliary files for cmake support
-
- cmake/COPYING-CMAKE-SCRIPTS
- cmake/FindPackageHandleStandardArgs.cmake
- cmake/FindEditline.cmake
- cmake/FindReadline.cmake
- CMakeLists.txt
- config-cmake.h.in
-
-(E) Auxiliary files for building PCRE2 "by hand"
-
- src/pcre2.h.generic ) a version of the public PCRE2 header file
- ) for use in non-"configure" environments
- src/config.h.generic ) a version of config.h for use in non-"configure"
- ) environments
-
-Philip Hazel
-Email local part: Philip.Hazel
-Email domain: gmail.com
-Last updated: 10 December 2022
diff --git a/contrib/libs/pcre2/README.md b/contrib/libs/pcre2/README.md
deleted file mode 100644
index d3fff179e3..0000000000
--- a/contrib/libs/pcre2/README.md
+++ /dev/null
@@ -1,56 +0,0 @@
-# PCRE2 - Perl-Compatible Regular Expressions
-
-The PCRE2 library is a set of C functions that implement regular expression
-pattern matching using the same syntax and semantics as Perl 5. PCRE2 has its
-own native API, as well as a set of wrapper functions that correspond to the
-POSIX regular expression API. The PCRE2 library is free, even for building
-proprietary software. It comes in three forms, for processing 8-bit, 16-bit,
-or 32-bit code units, in either literal or UTF encoding.
-
-PCRE2 was first released in 2015 to replace the API in the original PCRE
-library, which is now obsolete and no longer maintained. As well as a more
-flexible API, the code of PCRE2 has been much improved since the fork.
-
-## Download
-
-As well as downloading from the
-[GitHub site](https://github.com/PCRE2Project/pcre2), you can download PCRE2
-or the older, unmaintained PCRE1 library from an
-[*unofficial* mirror](https://sourceforge.net/projects/pcre/files/) at SourceForge.
-
-You can check out the PCRE2 source code via Git or Subversion:
-
- git clone https://github.com/PCRE2Project/pcre2.git
- svn co https://github.com/PCRE2Project/pcre2.git
-
-## Contributed Ports
-
-If you just need the command-line PCRE2 tools on Windows, precompiled binary
-versions are available at this
-[Rexegg page](http://www.rexegg.com/pcregrep-pcretest.html).
-
-A PCRE2 port for z/OS, a mainframe operating system which uses EBCDIC as its
-default character encoding, can be found at
-[http://www.cbttape.org](http://www.cbttape.org/) (File 939).
-
-## Documentation
-
-You can read the PCRE2 documentation
-[here](https://PCRE2Project.github.io/pcre2/doc/html/index.html).
-
-Comparisons to Perl's regular expression semantics can be found in the
-community authored Wikipedia entry for PCRE.
-
-There is a curated summary of changes for each PCRE release, copies of
-documentation from older releases, and other useful information from the third
-party authored
-[RexEgg PCRE Documentation and Change Log page](http://www.rexegg.com/pcre-documentation.html).
-
-## Contact
-
-To report a problem with the PCRE2 library, or to make a feature request, please
-use the PCRE2 GitHub issues tracker. There is a mailing list for discussion of
- PCRE2 issues and development at pcre2-dev@googlegroups.com, which is where any
-announcements will be made. You can browse the
-[list archives](https://groups.google.com/g/pcre2-dev).
-
diff --git a/contrib/libs/pcre2/pcre2.h b/contrib/libs/pcre2/pcre2.h
deleted file mode 100644
index 1cbecd0e86..0000000000
--- a/contrib/libs/pcre2/pcre2.h
+++ /dev/null
@@ -1,993 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* This is the public header file for the PCRE library, second API, to be
-#included by applications that call PCRE2 functions.
-
- Copyright (c) 2016-2021 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-#ifndef PCRE2_H_IDEMPOTENT_GUARD
-#define PCRE2_H_IDEMPOTENT_GUARD
-
-/* The current PCRE version information. */
-
-#define PCRE2_MAJOR 10
-#define PCRE2_MINOR 42
-#define PCRE2_PRERELEASE
-#define PCRE2_DATE 2022-12-11
-
-/* When an application links to a PCRE DLL in Windows, the symbols that are
-imported have to be identified as such. When building PCRE2, the appropriate
-export setting is defined in pcre2_internal.h, which includes this file. So we
-don't change existing definitions of PCRE2_EXP_DECL. */
-
-#if defined(_WIN32) && !defined(PCRE2_STATIC)
-# ifndef PCRE2_EXP_DECL
-# define PCRE2_EXP_DECL extern __declspec(dllimport)
-# endif
-#endif
-
-/* By default, we use the standard "extern" declarations. */
-
-#ifndef PCRE2_EXP_DECL
-# ifdef __cplusplus
-# define PCRE2_EXP_DECL extern "C"
-# else
-# define PCRE2_EXP_DECL extern
-# endif
-#endif
-
-/* When compiling with the MSVC compiler, it is sometimes necessary to include
-a "calling convention" before exported function names. (This is secondhand
-information; I know nothing about MSVC myself). For example, something like
-
- void __cdecl function(....)
-
-might be needed. In order so make this easy, all the exported functions have
-PCRE2_CALL_CONVENTION just before their names. It is rarely needed; if not
-set, we ensure here that it has no effect. */
-
-#ifndef PCRE2_CALL_CONVENTION
-#define PCRE2_CALL_CONVENTION
-#endif
-
-/* Have to include limits.h, stdlib.h, and inttypes.h to ensure that size_t and
-uint8_t, UCHAR_MAX, etc are defined. Some systems that do have inttypes.h do
-not have stdint.h, which is why we use inttypes.h, which according to the C
-standard is a superset of stdint.h. If inttypes.h is not available the build
-will break and the relevant values must be provided by some other means. */
-
-#include <limits.h>
-#include <stdlib.h>
-#include <inttypes.h>
-
-/* Allow for C++ users compiling this directly. */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* The following option bits can be passed to pcre2_compile(), pcre2_match(),
-or pcre2_dfa_match(). PCRE2_NO_UTF_CHECK affects only the function to which it
-is passed. Put these bits at the most significant end of the options word so
-others can be added next to them */
-
-#define PCRE2_ANCHORED 0x80000000u
-#define PCRE2_NO_UTF_CHECK 0x40000000u
-#define PCRE2_ENDANCHORED 0x20000000u
-
-/* The following option bits can be passed only to pcre2_compile(). However,
-they may affect compilation, JIT compilation, and/or interpretive execution.
-The following tags indicate which:
-
-C alters what is compiled by pcre2_compile()
-J alters what is compiled by pcre2_jit_compile()
-M is inspected during pcre2_match() execution
-D is inspected during pcre2_dfa_match() execution
-*/
-
-#define PCRE2_ALLOW_EMPTY_CLASS 0x00000001u /* C */
-#define PCRE2_ALT_BSUX 0x00000002u /* C */
-#define PCRE2_AUTO_CALLOUT 0x00000004u /* C */
-#define PCRE2_CASELESS 0x00000008u /* C */
-#define PCRE2_DOLLAR_ENDONLY 0x00000010u /* J M D */
-#define PCRE2_DOTALL 0x00000020u /* C */
-#define PCRE2_DUPNAMES 0x00000040u /* C */
-#define PCRE2_EXTENDED 0x00000080u /* C */
-#define PCRE2_FIRSTLINE 0x00000100u /* J M D */
-#define PCRE2_MATCH_UNSET_BACKREF 0x00000200u /* C J M */
-#define PCRE2_MULTILINE 0x00000400u /* C */
-#define PCRE2_NEVER_UCP 0x00000800u /* C */
-#define PCRE2_NEVER_UTF 0x00001000u /* C */
-#define PCRE2_NO_AUTO_CAPTURE 0x00002000u /* C */
-#define PCRE2_NO_AUTO_POSSESS 0x00004000u /* C */
-#define PCRE2_NO_DOTSTAR_ANCHOR 0x00008000u /* C */
-#define PCRE2_NO_START_OPTIMIZE 0x00010000u /* J M D */
-#define PCRE2_UCP 0x00020000u /* C J M D */
-#define PCRE2_UNGREEDY 0x00040000u /* C */
-#define PCRE2_UTF 0x00080000u /* C J M D */
-#define PCRE2_NEVER_BACKSLASH_C 0x00100000u /* C */
-#define PCRE2_ALT_CIRCUMFLEX 0x00200000u /* J M D */
-#define PCRE2_ALT_VERBNAMES 0x00400000u /* C */
-#define PCRE2_USE_OFFSET_LIMIT 0x00800000u /* J M D */
-#define PCRE2_EXTENDED_MORE 0x01000000u /* C */
-#define PCRE2_LITERAL 0x02000000u /* C */
-#define PCRE2_MATCH_INVALID_UTF 0x04000000u /* J M D */
-
-/* An additional compile options word is available in the compile context. */
-
-#define PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES 0x00000001u /* C */
-#define PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL 0x00000002u /* C */
-#define PCRE2_EXTRA_MATCH_WORD 0x00000004u /* C */
-#define PCRE2_EXTRA_MATCH_LINE 0x00000008u /* C */
-#define PCRE2_EXTRA_ESCAPED_CR_IS_LF 0x00000010u /* C */
-#define PCRE2_EXTRA_ALT_BSUX 0x00000020u /* C */
-#define PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK 0x00000040u /* C */
-
-/* These are for pcre2_jit_compile(). */
-
-#define PCRE2_JIT_COMPLETE 0x00000001u /* For full matching */
-#define PCRE2_JIT_PARTIAL_SOFT 0x00000002u
-#define PCRE2_JIT_PARTIAL_HARD 0x00000004u
-#define PCRE2_JIT_INVALID_UTF 0x00000100u
-
-/* These are for pcre2_match(), pcre2_dfa_match(), pcre2_jit_match(), and
-pcre2_substitute(). Some are allowed only for one of the functions, and in
-these cases it is noted below. Note that PCRE2_ANCHORED, PCRE2_ENDANCHORED and
-PCRE2_NO_UTF_CHECK can also be passed to these functions (though
-pcre2_jit_match() ignores the latter since it bypasses all sanity checks). */
-
-#define PCRE2_NOTBOL 0x00000001u
-#define PCRE2_NOTEOL 0x00000002u
-#define PCRE2_NOTEMPTY 0x00000004u /* ) These two must be kept */
-#define PCRE2_NOTEMPTY_ATSTART 0x00000008u /* ) adjacent to each other. */
-#define PCRE2_PARTIAL_SOFT 0x00000010u
-#define PCRE2_PARTIAL_HARD 0x00000020u
-#define PCRE2_DFA_RESTART 0x00000040u /* pcre2_dfa_match() only */
-#define PCRE2_DFA_SHORTEST 0x00000080u /* pcre2_dfa_match() only */
-#define PCRE2_SUBSTITUTE_GLOBAL 0x00000100u /* pcre2_substitute() only */
-#define PCRE2_SUBSTITUTE_EXTENDED 0x00000200u /* pcre2_substitute() only */
-#define PCRE2_SUBSTITUTE_UNSET_EMPTY 0x00000400u /* pcre2_substitute() only */
-#define PCRE2_SUBSTITUTE_UNKNOWN_UNSET 0x00000800u /* pcre2_substitute() only */
-#define PCRE2_SUBSTITUTE_OVERFLOW_LENGTH 0x00001000u /* pcre2_substitute() only */
-#define PCRE2_NO_JIT 0x00002000u /* Not for pcre2_dfa_match() */
-#define PCRE2_COPY_MATCHED_SUBJECT 0x00004000u
-#define PCRE2_SUBSTITUTE_LITERAL 0x00008000u /* pcre2_substitute() only */
-#define PCRE2_SUBSTITUTE_MATCHED 0x00010000u /* pcre2_substitute() only */
-#define PCRE2_SUBSTITUTE_REPLACEMENT_ONLY 0x00020000u /* pcre2_substitute() only */
-
-/* Options for pcre2_pattern_convert(). */
-
-#define PCRE2_CONVERT_UTF 0x00000001u
-#define PCRE2_CONVERT_NO_UTF_CHECK 0x00000002u
-#define PCRE2_CONVERT_POSIX_BASIC 0x00000004u
-#define PCRE2_CONVERT_POSIX_EXTENDED 0x00000008u
-#define PCRE2_CONVERT_GLOB 0x00000010u
-#define PCRE2_CONVERT_GLOB_NO_WILD_SEPARATOR 0x00000030u
-#define PCRE2_CONVERT_GLOB_NO_STARSTAR 0x00000050u
-
-/* Newline and \R settings, for use in compile contexts. The newline values
-must be kept in step with values set in config.h and both sets must all be
-greater than zero. */
-
-#define PCRE2_NEWLINE_CR 1
-#define PCRE2_NEWLINE_LF 2
-#define PCRE2_NEWLINE_CRLF 3
-#define PCRE2_NEWLINE_ANY 4
-#define PCRE2_NEWLINE_ANYCRLF 5
-#define PCRE2_NEWLINE_NUL 6
-
-#define PCRE2_BSR_UNICODE 1
-#define PCRE2_BSR_ANYCRLF 2
-
-/* Error codes for pcre2_compile(). Some of these are also used by
-pcre2_pattern_convert(). */
-
-#define PCRE2_ERROR_END_BACKSLASH 101
-#define PCRE2_ERROR_END_BACKSLASH_C 102
-#define PCRE2_ERROR_UNKNOWN_ESCAPE 103
-#define PCRE2_ERROR_QUANTIFIER_OUT_OF_ORDER 104
-#define PCRE2_ERROR_QUANTIFIER_TOO_BIG 105
-#define PCRE2_ERROR_MISSING_SQUARE_BRACKET 106
-#define PCRE2_ERROR_ESCAPE_INVALID_IN_CLASS 107
-#define PCRE2_ERROR_CLASS_RANGE_ORDER 108
-#define PCRE2_ERROR_QUANTIFIER_INVALID 109
-#define PCRE2_ERROR_INTERNAL_UNEXPECTED_REPEAT 110
-#define PCRE2_ERROR_INVALID_AFTER_PARENS_QUERY 111
-#define PCRE2_ERROR_POSIX_CLASS_NOT_IN_CLASS 112
-#define PCRE2_ERROR_POSIX_NO_SUPPORT_COLLATING 113
-#define PCRE2_ERROR_MISSING_CLOSING_PARENTHESIS 114
-#define PCRE2_ERROR_BAD_SUBPATTERN_REFERENCE 115
-#define PCRE2_ERROR_NULL_PATTERN 116
-#define PCRE2_ERROR_BAD_OPTIONS 117
-#define PCRE2_ERROR_MISSING_COMMENT_CLOSING 118
-#define PCRE2_ERROR_PARENTHESES_NEST_TOO_DEEP 119
-#define PCRE2_ERROR_PATTERN_TOO_LARGE 120
-#define PCRE2_ERROR_HEAP_FAILED 121
-#define PCRE2_ERROR_UNMATCHED_CLOSING_PARENTHESIS 122
-#define PCRE2_ERROR_INTERNAL_CODE_OVERFLOW 123
-#define PCRE2_ERROR_MISSING_CONDITION_CLOSING 124
-#define PCRE2_ERROR_LOOKBEHIND_NOT_FIXED_LENGTH 125
-#define PCRE2_ERROR_ZERO_RELATIVE_REFERENCE 126
-#define PCRE2_ERROR_TOO_MANY_CONDITION_BRANCHES 127
-#define PCRE2_ERROR_CONDITION_ASSERTION_EXPECTED 128
-#define PCRE2_ERROR_BAD_RELATIVE_REFERENCE 129
-#define PCRE2_ERROR_UNKNOWN_POSIX_CLASS 130
-#define PCRE2_ERROR_INTERNAL_STUDY_ERROR 131
-#define PCRE2_ERROR_UNICODE_NOT_SUPPORTED 132
-#define PCRE2_ERROR_PARENTHESES_STACK_CHECK 133
-#define PCRE2_ERROR_CODE_POINT_TOO_BIG 134
-#define PCRE2_ERROR_LOOKBEHIND_TOO_COMPLICATED 135
-#define PCRE2_ERROR_LOOKBEHIND_INVALID_BACKSLASH_C 136
-#define PCRE2_ERROR_UNSUPPORTED_ESCAPE_SEQUENCE 137
-#define PCRE2_ERROR_CALLOUT_NUMBER_TOO_BIG 138
-#define PCRE2_ERROR_MISSING_CALLOUT_CLOSING 139
-#define PCRE2_ERROR_ESCAPE_INVALID_IN_VERB 140
-#define PCRE2_ERROR_UNRECOGNIZED_AFTER_QUERY_P 141
-#define PCRE2_ERROR_MISSING_NAME_TERMINATOR 142
-#define PCRE2_ERROR_DUPLICATE_SUBPATTERN_NAME 143
-#define PCRE2_ERROR_INVALID_SUBPATTERN_NAME 144
-#define PCRE2_ERROR_UNICODE_PROPERTIES_UNAVAILABLE 145
-#define PCRE2_ERROR_MALFORMED_UNICODE_PROPERTY 146
-#define PCRE2_ERROR_UNKNOWN_UNICODE_PROPERTY 147
-#define PCRE2_ERROR_SUBPATTERN_NAME_TOO_LONG 148
-#define PCRE2_ERROR_TOO_MANY_NAMED_SUBPATTERNS 149
-#define PCRE2_ERROR_CLASS_INVALID_RANGE 150
-#define PCRE2_ERROR_OCTAL_BYTE_TOO_BIG 151
-#define PCRE2_ERROR_INTERNAL_OVERRAN_WORKSPACE 152
-#define PCRE2_ERROR_INTERNAL_MISSING_SUBPATTERN 153
-#define PCRE2_ERROR_DEFINE_TOO_MANY_BRANCHES 154
-#define PCRE2_ERROR_BACKSLASH_O_MISSING_BRACE 155
-#define PCRE2_ERROR_INTERNAL_UNKNOWN_NEWLINE 156
-#define PCRE2_ERROR_BACKSLASH_G_SYNTAX 157
-#define PCRE2_ERROR_PARENS_QUERY_R_MISSING_CLOSING 158
-/* Error 159 is obsolete and should now never occur */
-#define PCRE2_ERROR_VERB_ARGUMENT_NOT_ALLOWED 159
-#define PCRE2_ERROR_VERB_UNKNOWN 160
-#define PCRE2_ERROR_SUBPATTERN_NUMBER_TOO_BIG 161
-#define PCRE2_ERROR_SUBPATTERN_NAME_EXPECTED 162
-#define PCRE2_ERROR_INTERNAL_PARSED_OVERFLOW 163
-#define PCRE2_ERROR_INVALID_OCTAL 164
-#define PCRE2_ERROR_SUBPATTERN_NAMES_MISMATCH 165
-#define PCRE2_ERROR_MARK_MISSING_ARGUMENT 166
-#define PCRE2_ERROR_INVALID_HEXADECIMAL 167
-#define PCRE2_ERROR_BACKSLASH_C_SYNTAX 168
-#define PCRE2_ERROR_BACKSLASH_K_SYNTAX 169
-#define PCRE2_ERROR_INTERNAL_BAD_CODE_LOOKBEHINDS 170
-#define PCRE2_ERROR_BACKSLASH_N_IN_CLASS 171
-#define PCRE2_ERROR_CALLOUT_STRING_TOO_LONG 172
-#define PCRE2_ERROR_UNICODE_DISALLOWED_CODE_POINT 173
-#define PCRE2_ERROR_UTF_IS_DISABLED 174
-#define PCRE2_ERROR_UCP_IS_DISABLED 175
-#define PCRE2_ERROR_VERB_NAME_TOO_LONG 176
-#define PCRE2_ERROR_BACKSLASH_U_CODE_POINT_TOO_BIG 177
-#define PCRE2_ERROR_MISSING_OCTAL_OR_HEX_DIGITS 178
-#define PCRE2_ERROR_VERSION_CONDITION_SYNTAX 179
-#define PCRE2_ERROR_INTERNAL_BAD_CODE_AUTO_POSSESS 180
-#define PCRE2_ERROR_CALLOUT_NO_STRING_DELIMITER 181
-#define PCRE2_ERROR_CALLOUT_BAD_STRING_DELIMITER 182
-#define PCRE2_ERROR_BACKSLASH_C_CALLER_DISABLED 183
-#define PCRE2_ERROR_QUERY_BARJX_NEST_TOO_DEEP 184
-#define PCRE2_ERROR_BACKSLASH_C_LIBRARY_DISABLED 185
-#define PCRE2_ERROR_PATTERN_TOO_COMPLICATED 186
-#define PCRE2_ERROR_LOOKBEHIND_TOO_LONG 187
-#define PCRE2_ERROR_PATTERN_STRING_TOO_LONG 188
-#define PCRE2_ERROR_INTERNAL_BAD_CODE 189
-#define PCRE2_ERROR_INTERNAL_BAD_CODE_IN_SKIP 190
-#define PCRE2_ERROR_NO_SURROGATES_IN_UTF16 191
-#define PCRE2_ERROR_BAD_LITERAL_OPTIONS 192
-#define PCRE2_ERROR_SUPPORTED_ONLY_IN_UNICODE 193
-#define PCRE2_ERROR_INVALID_HYPHEN_IN_OPTIONS 194
-#define PCRE2_ERROR_ALPHA_ASSERTION_UNKNOWN 195
-#define PCRE2_ERROR_SCRIPT_RUN_NOT_AVAILABLE 196
-#define PCRE2_ERROR_TOO_MANY_CAPTURES 197
-#define PCRE2_ERROR_CONDITION_ATOMIC_ASSERTION_EXPECTED 198
-#define PCRE2_ERROR_BACKSLASH_K_IN_LOOKAROUND 199
-
-
-/* "Expected" matching error codes: no match and partial match. */
-
-#define PCRE2_ERROR_NOMATCH (-1)
-#define PCRE2_ERROR_PARTIAL (-2)
-
-/* Error codes for UTF-8 validity checks */
-
-#define PCRE2_ERROR_UTF8_ERR1 (-3)
-#define PCRE2_ERROR_UTF8_ERR2 (-4)
-#define PCRE2_ERROR_UTF8_ERR3 (-5)
-#define PCRE2_ERROR_UTF8_ERR4 (-6)
-#define PCRE2_ERROR_UTF8_ERR5 (-7)
-#define PCRE2_ERROR_UTF8_ERR6 (-8)
-#define PCRE2_ERROR_UTF8_ERR7 (-9)
-#define PCRE2_ERROR_UTF8_ERR8 (-10)
-#define PCRE2_ERROR_UTF8_ERR9 (-11)
-#define PCRE2_ERROR_UTF8_ERR10 (-12)
-#define PCRE2_ERROR_UTF8_ERR11 (-13)
-#define PCRE2_ERROR_UTF8_ERR12 (-14)
-#define PCRE2_ERROR_UTF8_ERR13 (-15)
-#define PCRE2_ERROR_UTF8_ERR14 (-16)
-#define PCRE2_ERROR_UTF8_ERR15 (-17)
-#define PCRE2_ERROR_UTF8_ERR16 (-18)
-#define PCRE2_ERROR_UTF8_ERR17 (-19)
-#define PCRE2_ERROR_UTF8_ERR18 (-20)
-#define PCRE2_ERROR_UTF8_ERR19 (-21)
-#define PCRE2_ERROR_UTF8_ERR20 (-22)
-#define PCRE2_ERROR_UTF8_ERR21 (-23)
-
-/* Error codes for UTF-16 validity checks */
-
-#define PCRE2_ERROR_UTF16_ERR1 (-24)
-#define PCRE2_ERROR_UTF16_ERR2 (-25)
-#define PCRE2_ERROR_UTF16_ERR3 (-26)
-
-/* Error codes for UTF-32 validity checks */
-
-#define PCRE2_ERROR_UTF32_ERR1 (-27)
-#define PCRE2_ERROR_UTF32_ERR2 (-28)
-
-/* Miscellaneous error codes for pcre2[_dfa]_match(), substring extraction
-functions, context functions, and serializing functions. They are in numerical
-order. Originally they were in alphabetical order too, but now that PCRE2 is
-released, the numbers must not be changed. */
-
-#define PCRE2_ERROR_BADDATA (-29)
-#define PCRE2_ERROR_MIXEDTABLES (-30) /* Name was changed */
-#define PCRE2_ERROR_BADMAGIC (-31)
-#define PCRE2_ERROR_BADMODE (-32)
-#define PCRE2_ERROR_BADOFFSET (-33)
-#define PCRE2_ERROR_BADOPTION (-34)
-#define PCRE2_ERROR_BADREPLACEMENT (-35)
-#define PCRE2_ERROR_BADUTFOFFSET (-36)
-#define PCRE2_ERROR_CALLOUT (-37) /* Never used by PCRE2 itself */
-#define PCRE2_ERROR_DFA_BADRESTART (-38)
-#define PCRE2_ERROR_DFA_RECURSE (-39)
-#define PCRE2_ERROR_DFA_UCOND (-40)
-#define PCRE2_ERROR_DFA_UFUNC (-41)
-#define PCRE2_ERROR_DFA_UITEM (-42)
-#define PCRE2_ERROR_DFA_WSSIZE (-43)
-#define PCRE2_ERROR_INTERNAL (-44)
-#define PCRE2_ERROR_JIT_BADOPTION (-45)
-#define PCRE2_ERROR_JIT_STACKLIMIT (-46)
-#define PCRE2_ERROR_MATCHLIMIT (-47)
-#define PCRE2_ERROR_NOMEMORY (-48)
-#define PCRE2_ERROR_NOSUBSTRING (-49)
-#define PCRE2_ERROR_NOUNIQUESUBSTRING (-50)
-#define PCRE2_ERROR_NULL (-51)
-#define PCRE2_ERROR_RECURSELOOP (-52)
-#define PCRE2_ERROR_DEPTHLIMIT (-53)
-#define PCRE2_ERROR_RECURSIONLIMIT (-53) /* Obsolete synonym */
-#define PCRE2_ERROR_UNAVAILABLE (-54)
-#define PCRE2_ERROR_UNSET (-55)
-#define PCRE2_ERROR_BADOFFSETLIMIT (-56)
-#define PCRE2_ERROR_BADREPESCAPE (-57)
-#define PCRE2_ERROR_REPMISSINGBRACE (-58)
-#define PCRE2_ERROR_BADSUBSTITUTION (-59)
-#define PCRE2_ERROR_BADSUBSPATTERN (-60)
-#define PCRE2_ERROR_TOOMANYREPLACE (-61)
-#define PCRE2_ERROR_BADSERIALIZEDDATA (-62)
-#define PCRE2_ERROR_HEAPLIMIT (-63)
-#define PCRE2_ERROR_CONVERT_SYNTAX (-64)
-#define PCRE2_ERROR_INTERNAL_DUPMATCH (-65)
-#define PCRE2_ERROR_DFA_UINVALID_UTF (-66)
-
-
-/* Request types for pcre2_pattern_info() */
-
-#define PCRE2_INFO_ALLOPTIONS 0
-#define PCRE2_INFO_ARGOPTIONS 1
-#define PCRE2_INFO_BACKREFMAX 2
-#define PCRE2_INFO_BSR 3
-#define PCRE2_INFO_CAPTURECOUNT 4
-#define PCRE2_INFO_FIRSTCODEUNIT 5
-#define PCRE2_INFO_FIRSTCODETYPE 6
-#define PCRE2_INFO_FIRSTBITMAP 7
-#define PCRE2_INFO_HASCRORLF 8
-#define PCRE2_INFO_JCHANGED 9
-#define PCRE2_INFO_JITSIZE 10
-#define PCRE2_INFO_LASTCODEUNIT 11
-#define PCRE2_INFO_LASTCODETYPE 12
-#define PCRE2_INFO_MATCHEMPTY 13
-#define PCRE2_INFO_MATCHLIMIT 14
-#define PCRE2_INFO_MAXLOOKBEHIND 15
-#define PCRE2_INFO_MINLENGTH 16
-#define PCRE2_INFO_NAMECOUNT 17
-#define PCRE2_INFO_NAMEENTRYSIZE 18
-#define PCRE2_INFO_NAMETABLE 19
-#define PCRE2_INFO_NEWLINE 20
-#define PCRE2_INFO_DEPTHLIMIT 21
-#define PCRE2_INFO_RECURSIONLIMIT 21 /* Obsolete synonym */
-#define PCRE2_INFO_SIZE 22
-#define PCRE2_INFO_HASBACKSLASHC 23
-#define PCRE2_INFO_FRAMESIZE 24
-#define PCRE2_INFO_HEAPLIMIT 25
-#define PCRE2_INFO_EXTRAOPTIONS 26
-
-/* Request types for pcre2_config(). */
-
-#define PCRE2_CONFIG_BSR 0
-#define PCRE2_CONFIG_JIT 1
-#define PCRE2_CONFIG_JITTARGET 2
-#define PCRE2_CONFIG_LINKSIZE 3
-#define PCRE2_CONFIG_MATCHLIMIT 4
-#define PCRE2_CONFIG_NEWLINE 5
-#define PCRE2_CONFIG_PARENSLIMIT 6
-#define PCRE2_CONFIG_DEPTHLIMIT 7
-#define PCRE2_CONFIG_RECURSIONLIMIT 7 /* Obsolete synonym */
-#define PCRE2_CONFIG_STACKRECURSE 8 /* Obsolete */
-#define PCRE2_CONFIG_UNICODE 9
-#define PCRE2_CONFIG_UNICODE_VERSION 10
-#define PCRE2_CONFIG_VERSION 11
-#define PCRE2_CONFIG_HEAPLIMIT 12
-#define PCRE2_CONFIG_NEVER_BACKSLASH_C 13
-#define PCRE2_CONFIG_COMPILED_WIDTHS 14
-#define PCRE2_CONFIG_TABLES_LENGTH 15
-
-
-/* Types for code units in patterns and subject strings. */
-
-typedef uint8_t PCRE2_UCHAR8;
-typedef uint16_t PCRE2_UCHAR16;
-typedef uint32_t PCRE2_UCHAR32;
-
-typedef const PCRE2_UCHAR8 *PCRE2_SPTR8;
-typedef const PCRE2_UCHAR16 *PCRE2_SPTR16;
-typedef const PCRE2_UCHAR32 *PCRE2_SPTR32;
-
-/* The PCRE2_SIZE type is used for all string lengths and offsets in PCRE2,
-including pattern offsets for errors and subject offsets after a match. We
-define special values to indicate zero-terminated strings and unset offsets in
-the offset vector (ovector). */
-
-#define PCRE2_SIZE size_t
-#define PCRE2_SIZE_MAX SIZE_MAX
-#define PCRE2_ZERO_TERMINATED (~(PCRE2_SIZE)0)
-#define PCRE2_UNSET (~(PCRE2_SIZE)0)
-
-/* Generic types for opaque structures and JIT callback functions. These
-declarations are defined in a macro that is expanded for each width later. */
-
-#define PCRE2_TYPES_LIST \
-struct pcre2_real_general_context; \
-typedef struct pcre2_real_general_context pcre2_general_context; \
-\
-struct pcre2_real_compile_context; \
-typedef struct pcre2_real_compile_context pcre2_compile_context; \
-\
-struct pcre2_real_match_context; \
-typedef struct pcre2_real_match_context pcre2_match_context; \
-\
-struct pcre2_real_convert_context; \
-typedef struct pcre2_real_convert_context pcre2_convert_context; \
-\
-struct pcre2_real_code; \
-typedef struct pcre2_real_code pcre2_code; \
-\
-struct pcre2_real_match_data; \
-typedef struct pcre2_real_match_data pcre2_match_data; \
-\
-struct pcre2_real_jit_stack; \
-typedef struct pcre2_real_jit_stack pcre2_jit_stack; \
-\
-typedef pcre2_jit_stack *(*pcre2_jit_callback)(void *);
-
-
-/* The structures for passing out data via callout functions. We use structures
-so that new fields can be added on the end in future versions, without changing
-the API of the function, thereby allowing old clients to work without
-modification. Define the generic versions in a macro; the width-specific
-versions are generated from this macro below. */
-
-/* Flags for the callout_flags field. These are cleared after a callout. */
-
-#define PCRE2_CALLOUT_STARTMATCH 0x00000001u /* Set for each bumpalong */
-#define PCRE2_CALLOUT_BACKTRACK 0x00000002u /* Set after a backtrack */
-
-#define PCRE2_STRUCTURE_LIST \
-typedef struct pcre2_callout_block { \
- uint32_t version; /* Identifies version of block */ \
- /* ------------------------ Version 0 ------------------------------- */ \
- uint32_t callout_number; /* Number compiled into pattern */ \
- uint32_t capture_top; /* Max current capture */ \
- uint32_t capture_last; /* Most recently closed capture */ \
- PCRE2_SIZE *offset_vector; /* The offset vector */ \
- PCRE2_SPTR mark; /* Pointer to current mark or NULL */ \
- PCRE2_SPTR subject; /* The subject being matched */ \
- PCRE2_SIZE subject_length; /* The length of the subject */ \
- PCRE2_SIZE start_match; /* Offset to start of this match attempt */ \
- PCRE2_SIZE current_position; /* Where we currently are in the subject */ \
- PCRE2_SIZE pattern_position; /* Offset to next item in the pattern */ \
- PCRE2_SIZE next_item_length; /* Length of next item in the pattern */ \
- /* ------------------- Added for Version 1 -------------------------- */ \
- PCRE2_SIZE callout_string_offset; /* Offset to string within pattern */ \
- PCRE2_SIZE callout_string_length; /* Length of string compiled into pattern */ \
- PCRE2_SPTR callout_string; /* String compiled into pattern */ \
- /* ------------------- Added for Version 2 -------------------------- */ \
- uint32_t callout_flags; /* See above for list */ \
- /* ------------------------------------------------------------------ */ \
-} pcre2_callout_block; \
-\
-typedef struct pcre2_callout_enumerate_block { \
- uint32_t version; /* Identifies version of block */ \
- /* ------------------------ Version 0 ------------------------------- */ \
- PCRE2_SIZE pattern_position; /* Offset to next item in the pattern */ \
- PCRE2_SIZE next_item_length; /* Length of next item in the pattern */ \
- uint32_t callout_number; /* Number compiled into pattern */ \
- PCRE2_SIZE callout_string_offset; /* Offset to string within pattern */ \
- PCRE2_SIZE callout_string_length; /* Length of string compiled into pattern */ \
- PCRE2_SPTR callout_string; /* String compiled into pattern */ \
- /* ------------------------------------------------------------------ */ \
-} pcre2_callout_enumerate_block; \
-\
-typedef struct pcre2_substitute_callout_block { \
- uint32_t version; /* Identifies version of block */ \
- /* ------------------------ Version 0 ------------------------------- */ \
- PCRE2_SPTR input; /* Pointer to input subject string */ \
- PCRE2_SPTR output; /* Pointer to output buffer */ \
- PCRE2_SIZE output_offsets[2]; /* Changed portion of the output */ \
- PCRE2_SIZE *ovector; /* Pointer to current ovector */ \
- uint32_t oveccount; /* Count of pairs set in ovector */ \
- uint32_t subscount; /* Substitution number */ \
- /* ------------------------------------------------------------------ */ \
-} pcre2_substitute_callout_block;
-
-
-/* List the generic forms of all other functions in macros, which will be
-expanded for each width below. Start with functions that give general
-information. */
-
-#define PCRE2_GENERAL_INFO_FUNCTIONS \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION pcre2_config(uint32_t, void *);
-
-
-/* Functions for manipulating contexts. */
-
-#define PCRE2_GENERAL_CONTEXT_FUNCTIONS \
-PCRE2_EXP_DECL pcre2_general_context *PCRE2_CALL_CONVENTION \
- pcre2_general_context_copy(pcre2_general_context *); \
-PCRE2_EXP_DECL pcre2_general_context *PCRE2_CALL_CONVENTION \
- pcre2_general_context_create(void *(*)(PCRE2_SIZE, void *), \
- void (*)(void *, void *), void *); \
-PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
- pcre2_general_context_free(pcre2_general_context *);
-
-#define PCRE2_COMPILE_CONTEXT_FUNCTIONS \
-PCRE2_EXP_DECL pcre2_compile_context *PCRE2_CALL_CONVENTION \
- pcre2_compile_context_copy(pcre2_compile_context *); \
-PCRE2_EXP_DECL pcre2_compile_context *PCRE2_CALL_CONVENTION \
- pcre2_compile_context_create(pcre2_general_context *);\
-PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
- pcre2_compile_context_free(pcre2_compile_context *); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_set_bsr(pcre2_compile_context *, uint32_t); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_set_character_tables(pcre2_compile_context *, const uint8_t *); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_set_compile_extra_options(pcre2_compile_context *, uint32_t); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_set_max_pattern_length(pcre2_compile_context *, PCRE2_SIZE); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_set_newline(pcre2_compile_context *, uint32_t); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_set_parens_nest_limit(pcre2_compile_context *, uint32_t); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_set_compile_recursion_guard(pcre2_compile_context *, \
- int (*)(uint32_t, void *), void *);
-
-#define PCRE2_MATCH_CONTEXT_FUNCTIONS \
-PCRE2_EXP_DECL pcre2_match_context *PCRE2_CALL_CONVENTION \
- pcre2_match_context_copy(pcre2_match_context *); \
-PCRE2_EXP_DECL pcre2_match_context *PCRE2_CALL_CONVENTION \
- pcre2_match_context_create(pcre2_general_context *); \
-PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
- pcre2_match_context_free(pcre2_match_context *); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_set_callout(pcre2_match_context *, \
- int (*)(pcre2_callout_block *, void *), void *); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_set_substitute_callout(pcre2_match_context *, \
- int (*)(pcre2_substitute_callout_block *, void *), void *); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_set_depth_limit(pcre2_match_context *, uint32_t); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_set_heap_limit(pcre2_match_context *, uint32_t); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_set_match_limit(pcre2_match_context *, uint32_t); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_set_offset_limit(pcre2_match_context *, PCRE2_SIZE); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_set_recursion_limit(pcre2_match_context *, uint32_t); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_set_recursion_memory_management(pcre2_match_context *, \
- void *(*)(PCRE2_SIZE, void *), void (*)(void *, void *), void *);
-
-#define PCRE2_CONVERT_CONTEXT_FUNCTIONS \
-PCRE2_EXP_DECL pcre2_convert_context *PCRE2_CALL_CONVENTION \
- pcre2_convert_context_copy(pcre2_convert_context *); \
-PCRE2_EXP_DECL pcre2_convert_context *PCRE2_CALL_CONVENTION \
- pcre2_convert_context_create(pcre2_general_context *); \
-PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
- pcre2_convert_context_free(pcre2_convert_context *); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_set_glob_escape(pcre2_convert_context *, uint32_t); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_set_glob_separator(pcre2_convert_context *, uint32_t);
-
-
-/* Functions concerned with compiling a pattern to PCRE internal code. */
-
-#define PCRE2_COMPILE_FUNCTIONS \
-PCRE2_EXP_DECL pcre2_code *PCRE2_CALL_CONVENTION \
- pcre2_compile(PCRE2_SPTR, PCRE2_SIZE, uint32_t, int *, PCRE2_SIZE *, \
- pcre2_compile_context *); \
-PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
- pcre2_code_free(pcre2_code *); \
-PCRE2_EXP_DECL pcre2_code *PCRE2_CALL_CONVENTION \
- pcre2_code_copy(const pcre2_code *); \
-PCRE2_EXP_DECL pcre2_code *PCRE2_CALL_CONVENTION \
- pcre2_code_copy_with_tables(const pcre2_code *);
-
-
-/* Functions that give information about a compiled pattern. */
-
-#define PCRE2_PATTERN_INFO_FUNCTIONS \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_pattern_info(const pcre2_code *, uint32_t, void *); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_callout_enumerate(const pcre2_code *, \
- int (*)(pcre2_callout_enumerate_block *, void *), void *);
-
-
-/* Functions for running a match and inspecting the result. */
-
-#define PCRE2_MATCH_FUNCTIONS \
-PCRE2_EXP_DECL pcre2_match_data *PCRE2_CALL_CONVENTION \
- pcre2_match_data_create(uint32_t, pcre2_general_context *); \
-PCRE2_EXP_DECL pcre2_match_data *PCRE2_CALL_CONVENTION \
- pcre2_match_data_create_from_pattern(const pcre2_code *, \
- pcre2_general_context *); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_dfa_match(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \
- uint32_t, pcre2_match_data *, pcre2_match_context *, int *, PCRE2_SIZE); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_match(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \
- uint32_t, pcre2_match_data *, pcre2_match_context *); \
-PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
- pcre2_match_data_free(pcre2_match_data *); \
-PCRE2_EXP_DECL PCRE2_SPTR PCRE2_CALL_CONVENTION \
- pcre2_get_mark(pcre2_match_data *); \
-PCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \
- pcre2_get_match_data_size(pcre2_match_data *); \
-PCRE2_EXP_DECL uint32_t PCRE2_CALL_CONVENTION \
- pcre2_get_ovector_count(pcre2_match_data *); \
-PCRE2_EXP_DECL PCRE2_SIZE *PCRE2_CALL_CONVENTION \
- pcre2_get_ovector_pointer(pcre2_match_data *); \
-PCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \
- pcre2_get_startchar(pcre2_match_data *);
-
-
-/* Convenience functions for handling matched substrings. */
-
-#define PCRE2_SUBSTRING_FUNCTIONS \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_substring_copy_byname(pcre2_match_data *, PCRE2_SPTR, PCRE2_UCHAR *, \
- PCRE2_SIZE *); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_substring_copy_bynumber(pcre2_match_data *, uint32_t, PCRE2_UCHAR *, \
- PCRE2_SIZE *); \
-PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
- pcre2_substring_free(PCRE2_UCHAR *); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_substring_get_byname(pcre2_match_data *, PCRE2_SPTR, PCRE2_UCHAR **, \
- PCRE2_SIZE *); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_substring_get_bynumber(pcre2_match_data *, uint32_t, PCRE2_UCHAR **, \
- PCRE2_SIZE *); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_substring_length_byname(pcre2_match_data *, PCRE2_SPTR, PCRE2_SIZE *); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_substring_length_bynumber(pcre2_match_data *, uint32_t, PCRE2_SIZE *); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_substring_nametable_scan(const pcre2_code *, PCRE2_SPTR, PCRE2_SPTR *, \
- PCRE2_SPTR *); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_substring_number_from_name(const pcre2_code *, PCRE2_SPTR); \
-PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
- pcre2_substring_list_free(PCRE2_SPTR *); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_substring_list_get(pcre2_match_data *, PCRE2_UCHAR ***, PCRE2_SIZE **);
-
-/* Functions for serializing / deserializing compiled patterns. */
-
-#define PCRE2_SERIALIZE_FUNCTIONS \
-PCRE2_EXP_DECL int32_t PCRE2_CALL_CONVENTION \
- pcre2_serialize_encode(const pcre2_code **, int32_t, uint8_t **, \
- PCRE2_SIZE *, pcre2_general_context *); \
-PCRE2_EXP_DECL int32_t PCRE2_CALL_CONVENTION \
- pcre2_serialize_decode(pcre2_code **, int32_t, const uint8_t *, \
- pcre2_general_context *); \
-PCRE2_EXP_DECL int32_t PCRE2_CALL_CONVENTION \
- pcre2_serialize_get_number_of_codes(const uint8_t *); \
-PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
- pcre2_serialize_free(uint8_t *);
-
-
-/* Convenience function for match + substitute. */
-
-#define PCRE2_SUBSTITUTE_FUNCTION \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_substitute(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \
- uint32_t, pcre2_match_data *, pcre2_match_context *, PCRE2_SPTR, \
- PCRE2_SIZE, PCRE2_UCHAR *, PCRE2_SIZE *);
-
-
-/* Functions for converting pattern source strings. */
-
-#define PCRE2_CONVERT_FUNCTIONS \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_pattern_convert(PCRE2_SPTR, PCRE2_SIZE, uint32_t, PCRE2_UCHAR **, \
- PCRE2_SIZE *, pcre2_convert_context *); \
-PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
- pcre2_converted_pattern_free(PCRE2_UCHAR *);
-
-
-/* Functions for JIT processing */
-
-#define PCRE2_JIT_FUNCTIONS \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_jit_compile(pcre2_code *, uint32_t); \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_jit_match(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \
- uint32_t, pcre2_match_data *, pcre2_match_context *); \
-PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
- pcre2_jit_free_unused_memory(pcre2_general_context *); \
-PCRE2_EXP_DECL pcre2_jit_stack *PCRE2_CALL_CONVENTION \
- pcre2_jit_stack_create(PCRE2_SIZE, PCRE2_SIZE, pcre2_general_context *); \
-PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
- pcre2_jit_stack_assign(pcre2_match_context *, pcre2_jit_callback, void *); \
-PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
- pcre2_jit_stack_free(pcre2_jit_stack *);
-
-
-/* Other miscellaneous functions. */
-
-#define PCRE2_OTHER_FUNCTIONS \
-PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_get_error_message(int, PCRE2_UCHAR *, PCRE2_SIZE); \
-PCRE2_EXP_DECL const uint8_t *PCRE2_CALL_CONVENTION \
- pcre2_maketables(pcre2_general_context *); \
-PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
- pcre2_maketables_free(pcre2_general_context *, const uint8_t *);
-
-/* Define macros that generate width-specific names from generic versions. The
-three-level macro scheme is necessary to get the macros expanded when we want
-them to be. First we get the width from PCRE2_LOCAL_WIDTH, which is used for
-generating three versions of everything below. After that, PCRE2_SUFFIX will be
-re-defined to use PCRE2_CODE_UNIT_WIDTH, for use when macros such as
-pcre2_compile are called by application code. */
-
-#define PCRE2_JOIN(a,b) a ## b
-#define PCRE2_GLUE(a,b) PCRE2_JOIN(a,b)
-#define PCRE2_SUFFIX(a) PCRE2_GLUE(a,PCRE2_LOCAL_WIDTH)
-
-
-/* Data types */
-
-#define PCRE2_UCHAR PCRE2_SUFFIX(PCRE2_UCHAR)
-#define PCRE2_SPTR PCRE2_SUFFIX(PCRE2_SPTR)
-
-#define pcre2_code PCRE2_SUFFIX(pcre2_code_)
-#define pcre2_jit_callback PCRE2_SUFFIX(pcre2_jit_callback_)
-#define pcre2_jit_stack PCRE2_SUFFIX(pcre2_jit_stack_)
-
-#define pcre2_real_code PCRE2_SUFFIX(pcre2_real_code_)
-#define pcre2_real_general_context PCRE2_SUFFIX(pcre2_real_general_context_)
-#define pcre2_real_compile_context PCRE2_SUFFIX(pcre2_real_compile_context_)
-#define pcre2_real_convert_context PCRE2_SUFFIX(pcre2_real_convert_context_)
-#define pcre2_real_match_context PCRE2_SUFFIX(pcre2_real_match_context_)
-#define pcre2_real_jit_stack PCRE2_SUFFIX(pcre2_real_jit_stack_)
-#define pcre2_real_match_data PCRE2_SUFFIX(pcre2_real_match_data_)
-
-
-/* Data blocks */
-
-#define pcre2_callout_block PCRE2_SUFFIX(pcre2_callout_block_)
-#define pcre2_callout_enumerate_block PCRE2_SUFFIX(pcre2_callout_enumerate_block_)
-#define pcre2_substitute_callout_block PCRE2_SUFFIX(pcre2_substitute_callout_block_)
-#define pcre2_general_context PCRE2_SUFFIX(pcre2_general_context_)
-#define pcre2_compile_context PCRE2_SUFFIX(pcre2_compile_context_)
-#define pcre2_convert_context PCRE2_SUFFIX(pcre2_convert_context_)
-#define pcre2_match_context PCRE2_SUFFIX(pcre2_match_context_)
-#define pcre2_match_data PCRE2_SUFFIX(pcre2_match_data_)
-
-
-/* Functions: the complete list in alphabetical order */
-
-#define pcre2_callout_enumerate PCRE2_SUFFIX(pcre2_callout_enumerate_)
-#define pcre2_code_copy PCRE2_SUFFIX(pcre2_code_copy_)
-#define pcre2_code_copy_with_tables PCRE2_SUFFIX(pcre2_code_copy_with_tables_)
-#define pcre2_code_free PCRE2_SUFFIX(pcre2_code_free_)
-#define pcre2_compile PCRE2_SUFFIX(pcre2_compile_)
-#define pcre2_compile_context_copy PCRE2_SUFFIX(pcre2_compile_context_copy_)
-#define pcre2_compile_context_create PCRE2_SUFFIX(pcre2_compile_context_create_)
-#define pcre2_compile_context_free PCRE2_SUFFIX(pcre2_compile_context_free_)
-#define pcre2_config PCRE2_SUFFIX(pcre2_config_)
-#define pcre2_convert_context_copy PCRE2_SUFFIX(pcre2_convert_context_copy_)
-#define pcre2_convert_context_create PCRE2_SUFFIX(pcre2_convert_context_create_)
-#define pcre2_convert_context_free PCRE2_SUFFIX(pcre2_convert_context_free_)
-#define pcre2_converted_pattern_free PCRE2_SUFFIX(pcre2_converted_pattern_free_)
-#define pcre2_dfa_match PCRE2_SUFFIX(pcre2_dfa_match_)
-#define pcre2_general_context_copy PCRE2_SUFFIX(pcre2_general_context_copy_)
-#define pcre2_general_context_create PCRE2_SUFFIX(pcre2_general_context_create_)
-#define pcre2_general_context_free PCRE2_SUFFIX(pcre2_general_context_free_)
-#define pcre2_get_error_message PCRE2_SUFFIX(pcre2_get_error_message_)
-#define pcre2_get_mark PCRE2_SUFFIX(pcre2_get_mark_)
-#define pcre2_get_match_data_size PCRE2_SUFFIX(pcre2_get_match_data_size_)
-#define pcre2_get_ovector_pointer PCRE2_SUFFIX(pcre2_get_ovector_pointer_)
-#define pcre2_get_ovector_count PCRE2_SUFFIX(pcre2_get_ovector_count_)
-#define pcre2_get_startchar PCRE2_SUFFIX(pcre2_get_startchar_)
-#define pcre2_jit_compile PCRE2_SUFFIX(pcre2_jit_compile_)
-#define pcre2_jit_match PCRE2_SUFFIX(pcre2_jit_match_)
-#define pcre2_jit_free_unused_memory PCRE2_SUFFIX(pcre2_jit_free_unused_memory_)
-#define pcre2_jit_stack_assign PCRE2_SUFFIX(pcre2_jit_stack_assign_)
-#define pcre2_jit_stack_create PCRE2_SUFFIX(pcre2_jit_stack_create_)
-#define pcre2_jit_stack_free PCRE2_SUFFIX(pcre2_jit_stack_free_)
-#define pcre2_maketables PCRE2_SUFFIX(pcre2_maketables_)
-#define pcre2_maketables_free PCRE2_SUFFIX(pcre2_maketables_free_)
-#define pcre2_match PCRE2_SUFFIX(pcre2_match_)
-#define pcre2_match_context_copy PCRE2_SUFFIX(pcre2_match_context_copy_)
-#define pcre2_match_context_create PCRE2_SUFFIX(pcre2_match_context_create_)
-#define pcre2_match_context_free PCRE2_SUFFIX(pcre2_match_context_free_)
-#define pcre2_match_data_create PCRE2_SUFFIX(pcre2_match_data_create_)
-#define pcre2_match_data_create_from_pattern PCRE2_SUFFIX(pcre2_match_data_create_from_pattern_)
-#define pcre2_match_data_free PCRE2_SUFFIX(pcre2_match_data_free_)
-#define pcre2_pattern_convert PCRE2_SUFFIX(pcre2_pattern_convert_)
-#define pcre2_pattern_info PCRE2_SUFFIX(pcre2_pattern_info_)
-#define pcre2_serialize_decode PCRE2_SUFFIX(pcre2_serialize_decode_)
-#define pcre2_serialize_encode PCRE2_SUFFIX(pcre2_serialize_encode_)
-#define pcre2_serialize_free PCRE2_SUFFIX(pcre2_serialize_free_)
-#define pcre2_serialize_get_number_of_codes PCRE2_SUFFIX(pcre2_serialize_get_number_of_codes_)
-#define pcre2_set_bsr PCRE2_SUFFIX(pcre2_set_bsr_)
-#define pcre2_set_callout PCRE2_SUFFIX(pcre2_set_callout_)
-#define pcre2_set_character_tables PCRE2_SUFFIX(pcre2_set_character_tables_)
-#define pcre2_set_compile_extra_options PCRE2_SUFFIX(pcre2_set_compile_extra_options_)
-#define pcre2_set_compile_recursion_guard PCRE2_SUFFIX(pcre2_set_compile_recursion_guard_)
-#define pcre2_set_depth_limit PCRE2_SUFFIX(pcre2_set_depth_limit_)
-#define pcre2_set_glob_escape PCRE2_SUFFIX(pcre2_set_glob_escape_)
-#define pcre2_set_glob_separator PCRE2_SUFFIX(pcre2_set_glob_separator_)
-#define pcre2_set_heap_limit PCRE2_SUFFIX(pcre2_set_heap_limit_)
-#define pcre2_set_match_limit PCRE2_SUFFIX(pcre2_set_match_limit_)
-#define pcre2_set_max_pattern_length PCRE2_SUFFIX(pcre2_set_max_pattern_length_)
-#define pcre2_set_newline PCRE2_SUFFIX(pcre2_set_newline_)
-#define pcre2_set_parens_nest_limit PCRE2_SUFFIX(pcre2_set_parens_nest_limit_)
-#define pcre2_set_offset_limit PCRE2_SUFFIX(pcre2_set_offset_limit_)
-#define pcre2_set_substitute_callout PCRE2_SUFFIX(pcre2_set_substitute_callout_)
-#define pcre2_substitute PCRE2_SUFFIX(pcre2_substitute_)
-#define pcre2_substring_copy_byname PCRE2_SUFFIX(pcre2_substring_copy_byname_)
-#define pcre2_substring_copy_bynumber PCRE2_SUFFIX(pcre2_substring_copy_bynumber_)
-#define pcre2_substring_free PCRE2_SUFFIX(pcre2_substring_free_)
-#define pcre2_substring_get_byname PCRE2_SUFFIX(pcre2_substring_get_byname_)
-#define pcre2_substring_get_bynumber PCRE2_SUFFIX(pcre2_substring_get_bynumber_)
-#define pcre2_substring_length_byname PCRE2_SUFFIX(pcre2_substring_length_byname_)
-#define pcre2_substring_length_bynumber PCRE2_SUFFIX(pcre2_substring_length_bynumber_)
-#define pcre2_substring_list_get PCRE2_SUFFIX(pcre2_substring_list_get_)
-#define pcre2_substring_list_free PCRE2_SUFFIX(pcre2_substring_list_free_)
-#define pcre2_substring_nametable_scan PCRE2_SUFFIX(pcre2_substring_nametable_scan_)
-#define pcre2_substring_number_from_name PCRE2_SUFFIX(pcre2_substring_number_from_name_)
-
-/* Keep this old function name for backwards compatibility */
-#define pcre2_set_recursion_limit PCRE2_SUFFIX(pcre2_set_recursion_limit_)
-
-/* Keep this obsolete function for backwards compatibility: it is now a noop. */
-#define pcre2_set_recursion_memory_management PCRE2_SUFFIX(pcre2_set_recursion_memory_management_)
-
-/* Now generate all three sets of width-specific structures and function
-prototypes. */
-
-#define PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS \
-PCRE2_TYPES_LIST \
-PCRE2_STRUCTURE_LIST \
-PCRE2_GENERAL_INFO_FUNCTIONS \
-PCRE2_GENERAL_CONTEXT_FUNCTIONS \
-PCRE2_COMPILE_CONTEXT_FUNCTIONS \
-PCRE2_CONVERT_CONTEXT_FUNCTIONS \
-PCRE2_CONVERT_FUNCTIONS \
-PCRE2_MATCH_CONTEXT_FUNCTIONS \
-PCRE2_COMPILE_FUNCTIONS \
-PCRE2_PATTERN_INFO_FUNCTIONS \
-PCRE2_MATCH_FUNCTIONS \
-PCRE2_SUBSTRING_FUNCTIONS \
-PCRE2_SERIALIZE_FUNCTIONS \
-PCRE2_SUBSTITUTE_FUNCTION \
-PCRE2_JIT_FUNCTIONS \
-PCRE2_OTHER_FUNCTIONS
-
-#define PCRE2_LOCAL_WIDTH 8
-PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS
-#undef PCRE2_LOCAL_WIDTH
-
-#define PCRE2_LOCAL_WIDTH 16
-PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS
-#undef PCRE2_LOCAL_WIDTH
-
-#define PCRE2_LOCAL_WIDTH 32
-PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS
-#undef PCRE2_LOCAL_WIDTH
-
-/* Undefine the list macros; they are no longer needed. */
-
-#undef PCRE2_TYPES_LIST
-#undef PCRE2_STRUCTURE_LIST
-#undef PCRE2_GENERAL_INFO_FUNCTIONS
-#undef PCRE2_GENERAL_CONTEXT_FUNCTIONS
-#undef PCRE2_COMPILE_CONTEXT_FUNCTIONS
-#undef PCRE2_CONVERT_CONTEXT_FUNCTIONS
-#undef PCRE2_MATCH_CONTEXT_FUNCTIONS
-#undef PCRE2_COMPILE_FUNCTIONS
-#undef PCRE2_PATTERN_INFO_FUNCTIONS
-#undef PCRE2_MATCH_FUNCTIONS
-#undef PCRE2_SUBSTRING_FUNCTIONS
-#undef PCRE2_SERIALIZE_FUNCTIONS
-#undef PCRE2_SUBSTITUTE_FUNCTION
-#undef PCRE2_JIT_FUNCTIONS
-#undef PCRE2_OTHER_FUNCTIONS
-#undef PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS
-
-/* PCRE2_CODE_UNIT_WIDTH must be defined. If it is 8, 16, or 32, redefine
-PCRE2_SUFFIX to use it. If it is 0, undefine the other macros and make
-PCRE2_SUFFIX a no-op. Otherwise, generate an error. */
-
-#undef PCRE2_SUFFIX
-#ifndef PCRE2_CODE_UNIT_WIDTH
-#error PCRE2_CODE_UNIT_WIDTH must be defined before including pcre2.h.
-#error Use 8, 16, or 32; or 0 for a multi-width application.
-#else /* PCRE2_CODE_UNIT_WIDTH is defined */
-#if PCRE2_CODE_UNIT_WIDTH == 8 || \
- PCRE2_CODE_UNIT_WIDTH == 16 || \
- PCRE2_CODE_UNIT_WIDTH == 32
-#define PCRE2_SUFFIX(a) PCRE2_GLUE(a, PCRE2_CODE_UNIT_WIDTH)
-#elif PCRE2_CODE_UNIT_WIDTH == 0
-#undef PCRE2_JOIN
-#undef PCRE2_GLUE
-#define PCRE2_SUFFIX(a) a
-#else
-#error PCRE2_CODE_UNIT_WIDTH must be 0, 8, 16, or 32.
-#endif
-#endif /* PCRE2_CODE_UNIT_WIDTH is defined */
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* PCRE2_H_IDEMPOTENT_GUARD */
-
-/* End of pcre2.h */
diff --git a/contrib/libs/pcre2/src/pcre2_auto_possess.c b/contrib/libs/pcre2/src/pcre2_auto_possess.c
deleted file mode 100644
index e8338690ca..0000000000
--- a/contrib/libs/pcre2/src/pcre2_auto_possess.c
+++ /dev/null
@@ -1,1365 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2022 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-/* This module contains functions that scan a compiled pattern and change
-repeats into possessive repeats where possible. */
-
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-
-#include "pcre2_internal.h"
-
-
-/*************************************************
-* Tables for auto-possessification *
-*************************************************/
-
-/* This table is used to check whether auto-possessification is possible
-between adjacent character-type opcodes. The left-hand (repeated) opcode is
-used to select the row, and the right-hand opcode is use to select the column.
-A value of 1 means that auto-possessification is OK. For example, the second
-value in the first row means that \D+\d can be turned into \D++\d.
-
-The Unicode property types (\P and \p) have to be present to fill out the table
-because of what their opcode values are, but the table values should always be
-zero because property types are handled separately in the code. The last four
-columns apply to items that cannot be repeated, so there is no need to have
-rows for them. Note that OP_DIGIT etc. are generated only when PCRE_UCP is
-*not* set. When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */
-
-#define APTROWS (LAST_AUTOTAB_LEFT_OP - FIRST_AUTOTAB_OP + 1)
-#define APTCOLS (LAST_AUTOTAB_RIGHT_OP - FIRST_AUTOTAB_OP + 1)
-
-static const uint8_t autoposstab[APTROWS][APTCOLS] = {
-/* \D \d \S \s \W \w . .+ \C \P \p \R \H \h \V \v \X \Z \z $ $M */
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \D */
- { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 }, /* \d */
- { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 }, /* \S */
- { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \s */
- { 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \W */
- { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 }, /* \w */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \C */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* \P */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* \p */
- { 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 }, /* \R */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 }, /* \H */
- { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0 }, /* \h */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0 }, /* \V */
- { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0 }, /* \v */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } /* \X */
-};
-
-#ifdef SUPPORT_UNICODE
-/* This table is used to check whether auto-possessification is possible
-between adjacent Unicode property opcodes (OP_PROP and OP_NOTPROP). The
-left-hand (repeated) opcode is used to select the row, and the right-hand
-opcode is used to select the column. The values are as follows:
-
- 0 Always return FALSE (never auto-possessify)
- 1 Character groups are distinct (possessify if both are OP_PROP)
- 2 Check character categories in the same group (general or particular)
- 3 TRUE if the two opcodes are not the same (PROP vs NOTPROP)
-
- 4 Check left general category vs right particular category
- 5 Check right general category vs left particular category
-
- 6 Left alphanum vs right general category
- 7 Left space vs right general category
- 8 Left word vs right general category
-
- 9 Right alphanum vs left general category
- 10 Right space vs left general category
- 11 Right word vs left general category
-
- 12 Left alphanum vs right particular category
- 13 Left space vs right particular category
- 14 Left word vs right particular category
-
- 15 Right alphanum vs left particular category
- 16 Right space vs left particular category
- 17 Right word vs left particular category
-*/
-
-static const uint8_t propposstab[PT_TABSIZE][PT_TABSIZE] = {
-/* ANY LAMP GC PC SC SCX ALNUM SPACE PXSPACE WORD CLIST UCNC BIDICL BOOL */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_ANY */
- { 0, 3, 0, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0, 0 }, /* PT_LAMP */
- { 0, 0, 2, 4, 0, 0, 9, 10, 10, 11, 0, 0, 0, 0 }, /* PT_GC */
- { 0, 0, 5, 2, 0, 0, 15, 16, 16, 17, 0, 0, 0, 0 }, /* PT_PC */
- { 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_SC */
- { 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_SCX */
- { 0, 3, 6, 12, 0, 0, 3, 1, 1, 0, 0, 0, 0, 0 }, /* PT_ALNUM */
- { 0, 1, 7, 13, 0, 0, 1, 3, 3, 1, 0, 0, 0, 0 }, /* PT_SPACE */
- { 0, 1, 7, 13, 0, 0, 1, 3, 3, 1, 0, 0, 0, 0 }, /* PT_PXSPACE */
- { 0, 0, 8, 14, 0, 0, 0, 1, 1, 3, 0, 0, 0, 0 }, /* PT_WORD */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_CLIST */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 }, /* PT_UCNC */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_BIDICL */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* PT_BOOL */
-};
-
-/* This table is used to check whether auto-possessification is possible
-between adjacent Unicode property opcodes (OP_PROP and OP_NOTPROP) when one
-specifies a general category and the other specifies a particular category. The
-row is selected by the general category and the column by the particular
-category. The value is 1 if the particular category is not part of the general
-category. */
-
-static const uint8_t catposstab[7][30] = {
-/* Cc Cf Cn Co Cs Ll Lm Lo Lt Lu Mc Me Mn Nd Nl No Pc Pd Pe Pf Pi Po Ps Sc Sk Sm So Zl Zp Zs */
- { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* C */
- { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* L */
- { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* M */
- { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* N */
- { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 }, /* P */
- { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1 }, /* S */
- { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 } /* Z */
-};
-
-/* This table is used when checking ALNUM, (PX)SPACE, SPACE, and WORD against
-a general or particular category. The properties in each row are those
-that apply to the character set in question. Duplication means that a little
-unnecessary work is done when checking, but this keeps things much simpler
-because they can all use the same code. For more details see the comment where
-this table is used.
-
-Note: SPACE and PXSPACE used to be different because Perl excluded VT from
-"space", but from Perl 5.18 it's included, so both categories are treated the
-same here. */
-
-static const uint8_t posspropstab[3][4] = {
- { ucp_L, ucp_N, ucp_N, ucp_Nl }, /* ALNUM, 3rd and 4th values redundant */
- { ucp_Z, ucp_Z, ucp_C, ucp_Cc }, /* SPACE and PXSPACE, 2nd value redundant */
- { ucp_L, ucp_N, ucp_P, ucp_Po } /* WORD */
-};
-#endif /* SUPPORT_UNICODE */
-
-
-
-#ifdef SUPPORT_UNICODE
-/*************************************************
-* Check a character and a property *
-*************************************************/
-
-/* This function is called by compare_opcodes() when a property item is
-adjacent to a fixed character.
-
-Arguments:
- c the character
- ptype the property type
- pdata the data for the type
- negated TRUE if it's a negated property (\P or \p{^)
-
-Returns: TRUE if auto-possessifying is OK
-*/
-
-static BOOL
-check_char_prop(uint32_t c, unsigned int ptype, unsigned int pdata,
- BOOL negated)
-{
-BOOL ok;
-const uint32_t *p;
-const ucd_record *prop = GET_UCD(c);
-
-switch(ptype)
- {
- case PT_LAMP:
- return (prop->chartype == ucp_Lu ||
- prop->chartype == ucp_Ll ||
- prop->chartype == ucp_Lt) == negated;
-
- case PT_GC:
- return (pdata == PRIV(ucp_gentype)[prop->chartype]) == negated;
-
- case PT_PC:
- return (pdata == prop->chartype) == negated;
-
- case PT_SC:
- return (pdata == prop->script) == negated;
-
- case PT_SCX:
- ok = (pdata == prop->script
- || MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), pdata) != 0);
- return ok == negated;
-
- /* These are specials */
-
- case PT_ALNUM:
- return (PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N) == negated;
-
- /* Perl space used to exclude VT, but from Perl 5.18 it is included, which
- means that Perl space and POSIX space are now identical. PCRE was changed
- at release 8.34. */
-
- case PT_SPACE: /* Perl space */
- case PT_PXSPACE: /* POSIX space */
- switch(c)
- {
- HSPACE_CASES:
- VSPACE_CASES:
- return negated;
-
- default:
- return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == negated;
- }
- break; /* Control never reaches here */
-
- case PT_WORD:
- return (PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
- c == CHAR_UNDERSCORE) == negated;
-
- case PT_CLIST:
- p = PRIV(ucd_caseless_sets) + prop->caseset;
- for (;;)
- {
- if (c < *p) return !negated;
- if (c == *p++) return negated;
- }
- break; /* Control never reaches here */
-
- /* Haven't yet thought these through. */
-
- case PT_BIDICL:
- return FALSE;
-
- case PT_BOOL:
- return FALSE;
- }
-
-return FALSE;
-}
-#endif /* SUPPORT_UNICODE */
-
-
-
-/*************************************************
-* Base opcode of repeated opcodes *
-*************************************************/
-
-/* Returns the base opcode for repeated single character type opcodes. If the
-opcode is not a repeated character type, it returns with the original value.
-
-Arguments: c opcode
-Returns: base opcode for the type
-*/
-
-static PCRE2_UCHAR
-get_repeat_base(PCRE2_UCHAR c)
-{
-return (c > OP_TYPEPOSUPTO)? c :
- (c >= OP_TYPESTAR)? OP_TYPESTAR :
- (c >= OP_NOTSTARI)? OP_NOTSTARI :
- (c >= OP_NOTSTAR)? OP_NOTSTAR :
- (c >= OP_STARI)? OP_STARI :
- OP_STAR;
-}
-
-
-/*************************************************
-* Fill the character property list *
-*************************************************/
-
-/* Checks whether the code points to an opcode that can take part in auto-
-possessification, and if so, fills a list with its properties.
-
-Arguments:
- code points to start of expression
- utf TRUE if in UTF mode
- ucp TRUE if in UCP mode
- fcc points to the case-flipping table
- list points to output list
- list[0] will be filled with the opcode
- list[1] will be non-zero if this opcode
- can match an empty character string
- list[2..7] depends on the opcode
-
-Returns: points to the start of the next opcode if *code is accepted
- NULL if *code is not accepted
-*/
-
-static PCRE2_SPTR
-get_chr_property_list(PCRE2_SPTR code, BOOL utf, BOOL ucp, const uint8_t *fcc,
- uint32_t *list)
-{
-PCRE2_UCHAR c = *code;
-PCRE2_UCHAR base;
-PCRE2_SPTR end;
-uint32_t chr;
-
-#ifdef SUPPORT_UNICODE
-uint32_t *clist_dest;
-const uint32_t *clist_src;
-#else
-(void)utf; /* Suppress "unused parameter" compiler warnings */
-(void)ucp;
-#endif
-
-list[0] = c;
-list[1] = FALSE;
-code++;
-
-if (c >= OP_STAR && c <= OP_TYPEPOSUPTO)
- {
- base = get_repeat_base(c);
- c -= (base - OP_STAR);
-
- if (c == OP_UPTO || c == OP_MINUPTO || c == OP_EXACT || c == OP_POSUPTO)
- code += IMM2_SIZE;
-
- list[1] = (c != OP_PLUS && c != OP_MINPLUS && c != OP_EXACT &&
- c != OP_POSPLUS);
-
- switch(base)
- {
- case OP_STAR:
- list[0] = OP_CHAR;
- break;
-
- case OP_STARI:
- list[0] = OP_CHARI;
- break;
-
- case OP_NOTSTAR:
- list[0] = OP_NOT;
- break;
-
- case OP_NOTSTARI:
- list[0] = OP_NOTI;
- break;
-
- case OP_TYPESTAR:
- list[0] = *code;
- code++;
- break;
- }
- c = list[0];
- }
-
-switch(c)
- {
- case OP_NOT_DIGIT:
- case OP_DIGIT:
- case OP_NOT_WHITESPACE:
- case OP_WHITESPACE:
- case OP_NOT_WORDCHAR:
- case OP_WORDCHAR:
- case OP_ANY:
- case OP_ALLANY:
- case OP_ANYNL:
- case OP_NOT_HSPACE:
- case OP_HSPACE:
- case OP_NOT_VSPACE:
- case OP_VSPACE:
- case OP_EXTUNI:
- case OP_EODN:
- case OP_EOD:
- case OP_DOLL:
- case OP_DOLLM:
- return code;
-
- case OP_CHAR:
- case OP_NOT:
- GETCHARINCTEST(chr, code);
- list[2] = chr;
- list[3] = NOTACHAR;
- return code;
-
- case OP_CHARI:
- case OP_NOTI:
- list[0] = (c == OP_CHARI) ? OP_CHAR : OP_NOT;
- GETCHARINCTEST(chr, code);
- list[2] = chr;
-
-#ifdef SUPPORT_UNICODE
- if (chr < 128 || (chr < 256 && !utf && !ucp))
- list[3] = fcc[chr];
- else
- list[3] = UCD_OTHERCASE(chr);
-#elif defined SUPPORT_WIDE_CHARS
- list[3] = (chr < 256) ? fcc[chr] : chr;
-#else
- list[3] = fcc[chr];
-#endif
-
- /* The othercase might be the same value. */
-
- if (chr == list[3])
- list[3] = NOTACHAR;
- else
- list[4] = NOTACHAR;
- return code;
-
-#ifdef SUPPORT_UNICODE
- case OP_PROP:
- case OP_NOTPROP:
- if (code[0] != PT_CLIST)
- {
- list[2] = code[0];
- list[3] = code[1];
- return code + 2;
- }
-
- /* Convert only if we have enough space. */
-
- clist_src = PRIV(ucd_caseless_sets) + code[1];
- clist_dest = list + 2;
- code += 2;
-
- do {
- if (clist_dest >= list + 8)
- {
- /* Early return if there is not enough space. This should never
- happen, since all clists are shorter than 5 character now. */
- list[2] = code[0];
- list[3] = code[1];
- return code;
- }
- *clist_dest++ = *clist_src;
- }
- while(*clist_src++ != NOTACHAR);
-
- /* All characters are stored. The terminating NOTACHAR is copied from the
- clist itself. */
-
- list[0] = (c == OP_PROP) ? OP_CHAR : OP_NOT;
- return code;
-#endif
-
- case OP_NCLASS:
- case OP_CLASS:
-#ifdef SUPPORT_WIDE_CHARS
- case OP_XCLASS:
- if (c == OP_XCLASS)
- end = code + GET(code, 0) - 1;
- else
-#endif
- end = code + 32 / sizeof(PCRE2_UCHAR);
-
- switch(*end)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- case OP_CRPOSSTAR:
- case OP_CRPOSQUERY:
- list[1] = TRUE;
- end++;
- break;
-
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRPOSPLUS:
- end++;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- case OP_CRPOSRANGE:
- list[1] = (GET2(end, 1) == 0);
- end += 1 + 2 * IMM2_SIZE;
- break;
- }
- list[2] = (uint32_t)(end - code);
- return end;
- }
-
-return NULL; /* Opcode not accepted */
-}
-
-
-
-/*************************************************
-* Scan further character sets for match *
-*************************************************/
-
-/* Checks whether the base and the current opcode have a common character, in
-which case the base cannot be possessified.
-
-Arguments:
- code points to the byte code
- utf TRUE in UTF mode
- ucp TRUE in UCP mode
- cb compile data block
- base_list the data list of the base opcode
- base_end the end of the base opcode
- rec_limit points to recursion depth counter
-
-Returns: TRUE if the auto-possessification is possible
-*/
-
-static BOOL
-compare_opcodes(PCRE2_SPTR code, BOOL utf, BOOL ucp, const compile_block *cb,
- const uint32_t *base_list, PCRE2_SPTR base_end, int *rec_limit)
-{
-PCRE2_UCHAR c;
-uint32_t list[8];
-const uint32_t *chr_ptr;
-const uint32_t *ochr_ptr;
-const uint32_t *list_ptr;
-PCRE2_SPTR next_code;
-#ifdef SUPPORT_WIDE_CHARS
-PCRE2_SPTR xclass_flags;
-#endif
-const uint8_t *class_bitset;
-const uint8_t *set1, *set2, *set_end;
-uint32_t chr;
-BOOL accepted, invert_bits;
-BOOL entered_a_group = FALSE;
-
-if (--(*rec_limit) <= 0) return FALSE; /* Recursion has gone too deep */
-
-/* Note: the base_list[1] contains whether the current opcode has a greedy
-(represented by a non-zero value) quantifier. This is a different from
-other character type lists, which store here that the character iterator
-matches to an empty string (also represented by a non-zero value). */
-
-for(;;)
- {
- /* All operations move the code pointer forward.
- Therefore infinite recursions are not possible. */
-
- c = *code;
-
- /* Skip over callouts */
-
- if (c == OP_CALLOUT)
- {
- code += PRIV(OP_lengths)[c];
- continue;
- }
-
- if (c == OP_CALLOUT_STR)
- {
- code += GET(code, 1 + 2*LINK_SIZE);
- continue;
- }
-
- /* At the end of a branch, skip to the end of the group. */
-
- if (c == OP_ALT)
- {
- do code += GET(code, 1); while (*code == OP_ALT);
- c = *code;
- }
-
- /* Inspect the next opcode. */
-
- switch(c)
- {
- /* We can always possessify a greedy iterator at the end of the pattern,
- which is reached after skipping over the final OP_KET. A non-greedy
- iterator must never be possessified. */
-
- case OP_END:
- return base_list[1] != 0;
-
- /* When an iterator is at the end of certain kinds of group we can inspect
- what follows the group by skipping over the closing ket. Note that this
- does not apply to OP_KETRMAX or OP_KETRMIN because what follows any given
- iteration is variable (could be another iteration or could be the next
- item). As these two opcodes are not listed in the next switch, they will
- end up as the next code to inspect, and return FALSE by virtue of being
- unsupported. */
-
- case OP_KET:
- case OP_KETRPOS:
- /* The non-greedy case cannot be converted to a possessive form. */
-
- if (base_list[1] == 0) return FALSE;
-
- /* If the bracket is capturing it might be referenced by an OP_RECURSE
- so its last iterator can never be possessified if the pattern contains
- recursions. (This could be improved by keeping a list of group numbers that
- are called by recursion.) */
-
- switch(*(code - GET(code, 1)))
- {
- case OP_CBRA:
- case OP_SCBRA:
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- if (cb->had_recurse) return FALSE;
- break;
-
- /* A script run might have to backtrack if the iterated item can match
- characters from more than one script. So give up unless repeating an
- explicit character. */
-
- case OP_SCRIPT_RUN:
- if (base_list[0] != OP_CHAR && base_list[0] != OP_CHARI)
- return FALSE;
- break;
-
- /* Atomic sub-patterns and assertions can always auto-possessify their
- last iterator. However, if the group was entered as a result of checking
- a previous iterator, this is not possible. */
-
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- case OP_ONCE:
- return !entered_a_group;
-
- /* Non-atomic assertions - don't possessify last iterator. This needs
- more thought. */
-
- case OP_ASSERT_NA:
- case OP_ASSERTBACK_NA:
- return FALSE;
- }
-
- /* Skip over the bracket and inspect what comes next. */
-
- code += PRIV(OP_lengths)[c];
- continue;
-
- /* Handle cases where the next item is a group. */
-
- case OP_ONCE:
- case OP_BRA:
- case OP_CBRA:
- next_code = code + GET(code, 1);
- code += PRIV(OP_lengths)[c];
-
- /* Check each branch. We have to recurse a level for all but the last
- branch. */
-
- while (*next_code == OP_ALT)
- {
- if (!compare_opcodes(code, utf, ucp, cb, base_list, base_end, rec_limit))
- return FALSE;
- code = next_code + 1 + LINK_SIZE;
- next_code += GET(next_code, 1);
- }
-
- entered_a_group = TRUE;
- continue;
-
- case OP_BRAZERO:
- case OP_BRAMINZERO:
-
- next_code = code + 1;
- if (*next_code != OP_BRA && *next_code != OP_CBRA &&
- *next_code != OP_ONCE) return FALSE;
-
- do next_code += GET(next_code, 1); while (*next_code == OP_ALT);
-
- /* The bracket content will be checked by the OP_BRA/OP_CBRA case above. */
-
- next_code += 1 + LINK_SIZE;
- if (!compare_opcodes(next_code, utf, ucp, cb, base_list, base_end,
- rec_limit))
- return FALSE;
-
- code += PRIV(OP_lengths)[c];
- continue;
-
- /* The next opcode does not need special handling; fall through and use it
- to see if the base can be possessified. */
-
- default:
- break;
- }
-
- /* We now have the next appropriate opcode to compare with the base. Check
- for a supported opcode, and load its properties. */
-
- code = get_chr_property_list(code, utf, ucp, cb->fcc, list);
- if (code == NULL) return FALSE; /* Unsupported */
-
- /* If either opcode is a small character list, set pointers for comparing
- characters from that list with another list, or with a property. */
-
- if (base_list[0] == OP_CHAR)
- {
- chr_ptr = base_list + 2;
- list_ptr = list;
- }
- else if (list[0] == OP_CHAR)
- {
- chr_ptr = list + 2;
- list_ptr = base_list;
- }
-
- /* Character bitsets can also be compared to certain opcodes. */
-
- else if (base_list[0] == OP_CLASS || list[0] == OP_CLASS
-#if PCRE2_CODE_UNIT_WIDTH == 8
- /* In 8 bit, non-UTF mode, OP_CLASS and OP_NCLASS are the same. */
- || (!utf && (base_list[0] == OP_NCLASS || list[0] == OP_NCLASS))
-#endif
- )
- {
-#if PCRE2_CODE_UNIT_WIDTH == 8
- if (base_list[0] == OP_CLASS || (!utf && base_list[0] == OP_NCLASS))
-#else
- if (base_list[0] == OP_CLASS)
-#endif
- {
- set1 = (uint8_t *)(base_end - base_list[2]);
- list_ptr = list;
- }
- else
- {
- set1 = (uint8_t *)(code - list[2]);
- list_ptr = base_list;
- }
-
- invert_bits = FALSE;
- switch(list_ptr[0])
- {
- case OP_CLASS:
- case OP_NCLASS:
- set2 = (uint8_t *)
- ((list_ptr == list ? code : base_end) - list_ptr[2]);
- break;
-
-#ifdef SUPPORT_WIDE_CHARS
- case OP_XCLASS:
- xclass_flags = (list_ptr == list ? code : base_end) - list_ptr[2] + LINK_SIZE;
- if ((*xclass_flags & XCL_HASPROP) != 0) return FALSE;
- if ((*xclass_flags & XCL_MAP) == 0)
- {
- /* No bits are set for characters < 256. */
- if (list[1] == 0) return (*xclass_flags & XCL_NOT) == 0;
- /* Might be an empty repeat. */
- continue;
- }
- set2 = (uint8_t *)(xclass_flags + 1);
- break;
-#endif
-
- case OP_NOT_DIGIT:
- invert_bits = TRUE;
- /* Fall through */
- case OP_DIGIT:
- set2 = (uint8_t *)(cb->cbits + cbit_digit);
- break;
-
- case OP_NOT_WHITESPACE:
- invert_bits = TRUE;
- /* Fall through */
- case OP_WHITESPACE:
- set2 = (uint8_t *)(cb->cbits + cbit_space);
- break;
-
- case OP_NOT_WORDCHAR:
- invert_bits = TRUE;
- /* Fall through */
- case OP_WORDCHAR:
- set2 = (uint8_t *)(cb->cbits + cbit_word);
- break;
-
- default:
- return FALSE;
- }
-
- /* Because the bit sets are unaligned bytes, we need to perform byte
- comparison here. */
-
- set_end = set1 + 32;
- if (invert_bits)
- {
- do
- {
- if ((*set1++ & ~(*set2++)) != 0) return FALSE;
- }
- while (set1 < set_end);
- }
- else
- {
- do
- {
- if ((*set1++ & *set2++) != 0) return FALSE;
- }
- while (set1 < set_end);
- }
-
- if (list[1] == 0) return TRUE;
- /* Might be an empty repeat. */
- continue;
- }
-
- /* Some property combinations also acceptable. Unicode property opcodes are
- processed specially; the rest can be handled with a lookup table. */
-
- else
- {
- uint32_t leftop, rightop;
-
- leftop = base_list[0];
- rightop = list[0];
-
-#ifdef SUPPORT_UNICODE
- accepted = FALSE; /* Always set in non-unicode case. */
- if (leftop == OP_PROP || leftop == OP_NOTPROP)
- {
- if (rightop == OP_EOD)
- accepted = TRUE;
- else if (rightop == OP_PROP || rightop == OP_NOTPROP)
- {
- int n;
- const uint8_t *p;
- BOOL same = leftop == rightop;
- BOOL lisprop = leftop == OP_PROP;
- BOOL risprop = rightop == OP_PROP;
- BOOL bothprop = lisprop && risprop;
-
- /* There's a table that specifies how each combination is to be
- processed:
- 0 Always return FALSE (never auto-possessify)
- 1 Character groups are distinct (possessify if both are OP_PROP)
- 2 Check character categories in the same group (general or particular)
- 3 Return TRUE if the two opcodes are not the same
- ... see comments below
- */
-
- n = propposstab[base_list[2]][list[2]];
- switch(n)
- {
- case 0: break;
- case 1: accepted = bothprop; break;
- case 2: accepted = (base_list[3] == list[3]) != same; break;
- case 3: accepted = !same; break;
-
- case 4: /* Left general category, right particular category */
- accepted = risprop && catposstab[base_list[3]][list[3]] == same;
- break;
-
- case 5: /* Right general category, left particular category */
- accepted = lisprop && catposstab[list[3]][base_list[3]] == same;
- break;
-
- /* This code is logically tricky. Think hard before fiddling with it.
- The posspropstab table has four entries per row. Each row relates to
- one of PCRE's special properties such as ALNUM or SPACE or WORD.
- Only WORD actually needs all four entries, but using repeats for the
- others means they can all use the same code below.
-
- The first two entries in each row are Unicode general categories, and
- apply always, because all the characters they include are part of the
- PCRE character set. The third and fourth entries are a general and a
- particular category, respectively, that include one or more relevant
- characters. One or the other is used, depending on whether the check
- is for a general or a particular category. However, in both cases the
- category contains more characters than the specials that are defined
- for the property being tested against. Therefore, it cannot be used
- in a NOTPROP case.
-
- Example: the row for WORD contains ucp_L, ucp_N, ucp_P, ucp_Po.
- Underscore is covered by ucp_P or ucp_Po. */
-
- case 6: /* Left alphanum vs right general category */
- case 7: /* Left space vs right general category */
- case 8: /* Left word vs right general category */
- p = posspropstab[n-6];
- accepted = risprop && lisprop ==
- (list[3] != p[0] &&
- list[3] != p[1] &&
- (list[3] != p[2] || !lisprop));
- break;
-
- case 9: /* Right alphanum vs left general category */
- case 10: /* Right space vs left general category */
- case 11: /* Right word vs left general category */
- p = posspropstab[n-9];
- accepted = lisprop && risprop ==
- (base_list[3] != p[0] &&
- base_list[3] != p[1] &&
- (base_list[3] != p[2] || !risprop));
- break;
-
- case 12: /* Left alphanum vs right particular category */
- case 13: /* Left space vs right particular category */
- case 14: /* Left word vs right particular category */
- p = posspropstab[n-12];
- accepted = risprop && lisprop ==
- (catposstab[p[0]][list[3]] &&
- catposstab[p[1]][list[3]] &&
- (list[3] != p[3] || !lisprop));
- break;
-
- case 15: /* Right alphanum vs left particular category */
- case 16: /* Right space vs left particular category */
- case 17: /* Right word vs left particular category */
- p = posspropstab[n-15];
- accepted = lisprop && risprop ==
- (catposstab[p[0]][base_list[3]] &&
- catposstab[p[1]][base_list[3]] &&
- (base_list[3] != p[3] || !risprop));
- break;
- }
- }
- }
-
- else
-#endif /* SUPPORT_UNICODE */
-
- accepted = leftop >= FIRST_AUTOTAB_OP && leftop <= LAST_AUTOTAB_LEFT_OP &&
- rightop >= FIRST_AUTOTAB_OP && rightop <= LAST_AUTOTAB_RIGHT_OP &&
- autoposstab[leftop - FIRST_AUTOTAB_OP][rightop - FIRST_AUTOTAB_OP];
-
- if (!accepted) return FALSE;
-
- if (list[1] == 0) return TRUE;
- /* Might be an empty repeat. */
- continue;
- }
-
- /* Control reaches here only if one of the items is a small character list.
- All characters are checked against the other side. */
-
- do
- {
- chr = *chr_ptr;
-
- switch(list_ptr[0])
- {
- case OP_CHAR:
- ochr_ptr = list_ptr + 2;
- do
- {
- if (chr == *ochr_ptr) return FALSE;
- ochr_ptr++;
- }
- while(*ochr_ptr != NOTACHAR);
- break;
-
- case OP_NOT:
- ochr_ptr = list_ptr + 2;
- do
- {
- if (chr == *ochr_ptr)
- break;
- ochr_ptr++;
- }
- while(*ochr_ptr != NOTACHAR);
- if (*ochr_ptr == NOTACHAR) return FALSE; /* Not found */
- break;
-
- /* Note that OP_DIGIT etc. are generated only when PCRE2_UCP is *not*
- set. When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */
-
- case OP_DIGIT:
- if (chr < 256 && (cb->ctypes[chr] & ctype_digit) != 0) return FALSE;
- break;
-
- case OP_NOT_DIGIT:
- if (chr > 255 || (cb->ctypes[chr] & ctype_digit) == 0) return FALSE;
- break;
-
- case OP_WHITESPACE:
- if (chr < 256 && (cb->ctypes[chr] & ctype_space) != 0) return FALSE;
- break;
-
- case OP_NOT_WHITESPACE:
- if (chr > 255 || (cb->ctypes[chr] & ctype_space) == 0) return FALSE;
- break;
-
- case OP_WORDCHAR:
- if (chr < 255 && (cb->ctypes[chr] & ctype_word) != 0) return FALSE;
- break;
-
- case OP_NOT_WORDCHAR:
- if (chr > 255 || (cb->ctypes[chr] & ctype_word) == 0) return FALSE;
- break;
-
- case OP_HSPACE:
- switch(chr)
- {
- HSPACE_CASES: return FALSE;
- default: break;
- }
- break;
-
- case OP_NOT_HSPACE:
- switch(chr)
- {
- HSPACE_CASES: break;
- default: return FALSE;
- }
- break;
-
- case OP_ANYNL:
- case OP_VSPACE:
- switch(chr)
- {
- VSPACE_CASES: return FALSE;
- default: break;
- }
- break;
-
- case OP_NOT_VSPACE:
- switch(chr)
- {
- VSPACE_CASES: break;
- default: return FALSE;
- }
- break;
-
- case OP_DOLL:
- case OP_EODN:
- switch (chr)
- {
- case CHAR_CR:
- case CHAR_LF:
- case CHAR_VT:
- case CHAR_FF:
- case CHAR_NEL:
-#ifndef EBCDIC
- case 0x2028:
- case 0x2029:
-#endif /* Not EBCDIC */
- return FALSE;
- }
- break;
-
- case OP_EOD: /* Can always possessify before \z */
- break;
-
-#ifdef SUPPORT_UNICODE
- case OP_PROP:
- case OP_NOTPROP:
- if (!check_char_prop(chr, list_ptr[2], list_ptr[3],
- list_ptr[0] == OP_NOTPROP))
- return FALSE;
- break;
-#endif
-
- case OP_NCLASS:
- if (chr > 255) return FALSE;
- /* Fall through */
-
- case OP_CLASS:
- if (chr > 255) break;
- class_bitset = (uint8_t *)
- ((list_ptr == list ? code : base_end) - list_ptr[2]);
- if ((class_bitset[chr >> 3] & (1u << (chr & 7))) != 0) return FALSE;
- break;
-
-#ifdef SUPPORT_WIDE_CHARS
- case OP_XCLASS:
- if (PRIV(xclass)(chr, (list_ptr == list ? code : base_end) -
- list_ptr[2] + LINK_SIZE, utf)) return FALSE;
- break;
-#endif
-
- default:
- return FALSE;
- }
-
- chr_ptr++;
- }
- while(*chr_ptr != NOTACHAR);
-
- /* At least one character must be matched from this opcode. */
-
- if (list[1] == 0) return TRUE;
- }
-
-/* Control never reaches here. There used to be a fail-save return FALSE; here,
-but some compilers complain about an unreachable statement. */
-}
-
-
-
-/*************************************************
-* Scan compiled regex for auto-possession *
-*************************************************/
-
-/* Replaces single character iterations with their possessive alternatives
-if appropriate. This function modifies the compiled opcode! Hitting a
-non-existent opcode may indicate a bug in PCRE2, but it can also be caused if a
-bad UTF string was compiled with PCRE2_NO_UTF_CHECK. The rec_limit catches
-overly complicated or large patterns. In these cases, the check just stops,
-leaving the remainder of the pattern unpossessified.
-
-Arguments:
- code points to start of the byte code
- cb compile data block
-
-Returns: 0 for success
- -1 if a non-existant opcode is encountered
-*/
-
-int
-PRIV(auto_possessify)(PCRE2_UCHAR *code, const compile_block *cb)
-{
-PCRE2_UCHAR c;
-PCRE2_SPTR end;
-PCRE2_UCHAR *repeat_opcode;
-uint32_t list[8];
-int rec_limit = 1000; /* Was 10,000 but clang+ASAN uses a lot of stack. */
-BOOL utf = (cb->external_options & PCRE2_UTF) != 0;
-BOOL ucp = (cb->external_options & PCRE2_UCP) != 0;
-
-for (;;)
- {
- c = *code;
-
- if (c >= OP_TABLE_LENGTH) return -1; /* Something gone wrong */
-
- if (c >= OP_STAR && c <= OP_TYPEPOSUPTO)
- {
- c -= get_repeat_base(c) - OP_STAR;
- end = (c <= OP_MINUPTO) ?
- get_chr_property_list(code, utf, ucp, cb->fcc, list) : NULL;
- list[1] = c == OP_STAR || c == OP_PLUS || c == OP_QUERY || c == OP_UPTO;
-
- if (end != NULL && compare_opcodes(end, utf, ucp, cb, list, end,
- &rec_limit))
- {
- switch(c)
- {
- case OP_STAR:
- *code += OP_POSSTAR - OP_STAR;
- break;
-
- case OP_MINSTAR:
- *code += OP_POSSTAR - OP_MINSTAR;
- break;
-
- case OP_PLUS:
- *code += OP_POSPLUS - OP_PLUS;
- break;
-
- case OP_MINPLUS:
- *code += OP_POSPLUS - OP_MINPLUS;
- break;
-
- case OP_QUERY:
- *code += OP_POSQUERY - OP_QUERY;
- break;
-
- case OP_MINQUERY:
- *code += OP_POSQUERY - OP_MINQUERY;
- break;
-
- case OP_UPTO:
- *code += OP_POSUPTO - OP_UPTO;
- break;
-
- case OP_MINUPTO:
- *code += OP_POSUPTO - OP_MINUPTO;
- break;
- }
- }
- c = *code;
- }
- else if (c == OP_CLASS || c == OP_NCLASS || c == OP_XCLASS)
- {
-#ifdef SUPPORT_WIDE_CHARS
- if (c == OP_XCLASS)
- repeat_opcode = code + GET(code, 1);
- else
-#endif
- repeat_opcode = code + 1 + (32 / sizeof(PCRE2_UCHAR));
-
- c = *repeat_opcode;
- if (c >= OP_CRSTAR && c <= OP_CRMINRANGE)
- {
- /* The return from get_chr_property_list() will never be NULL when
- *code (aka c) is one of the three class opcodes. However, gcc with
- -fanalyzer notes that a NULL return is possible, and grumbles. Hence we
- put in a check. */
-
- end = get_chr_property_list(code, utf, ucp, cb->fcc, list);
- list[1] = (c & 1) == 0;
-
- if (end != NULL &&
- compare_opcodes(end, utf, ucp, cb, list, end, &rec_limit))
- {
- switch (c)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- *repeat_opcode = OP_CRPOSSTAR;
- break;
-
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- *repeat_opcode = OP_CRPOSPLUS;
- break;
-
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- *repeat_opcode = OP_CRPOSQUERY;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- *repeat_opcode = OP_CRPOSRANGE;
- break;
- }
- }
- }
- c = *code;
- }
-
- switch(c)
- {
- case OP_END:
- return 0;
-
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSPLUS:
- case OP_TYPEPOSQUERY:
- if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
- break;
-
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEEXACT:
- case OP_TYPEPOSUPTO:
- if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)
- code += 2;
- break;
-
- case OP_CALLOUT_STR:
- code += GET(code, 1 + 2*LINK_SIZE);
- break;
-
-#ifdef SUPPORT_WIDE_CHARS
- case OP_XCLASS:
- code += GET(code, 1);
- break;
-#endif
-
- case OP_MARK:
- case OP_COMMIT_ARG:
- case OP_PRUNE_ARG:
- case OP_SKIP_ARG:
- case OP_THEN_ARG:
- code += code[1];
- break;
- }
-
- /* Add in the fixed length from the table */
-
- code += PRIV(OP_lengths)[c];
-
- /* In UTF-8 and UTF-16 modes, opcodes that are followed by a character may be
- followed by a multi-byte character. The length in the table is a minimum, so
- we have to arrange to skip the extra code units. */
-
-#ifdef MAYBE_UTF_MULTI
- if (utf) switch(c)
- {
- case OP_CHAR:
- case OP_CHARI:
- case OP_NOT:
- case OP_NOTI:
- case OP_STAR:
- case OP_MINSTAR:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_EXACT:
- case OP_POSSTAR:
- case OP_POSPLUS:
- case OP_POSQUERY:
- case OP_POSUPTO:
- case OP_STARI:
- case OP_MINSTARI:
- case OP_PLUSI:
- case OP_MINPLUSI:
- case OP_QUERYI:
- case OP_MINQUERYI:
- case OP_UPTOI:
- case OP_MINUPTOI:
- case OP_EXACTI:
- case OP_POSSTARI:
- case OP_POSPLUSI:
- case OP_POSQUERYI:
- case OP_POSUPTOI:
- case OP_NOTSTAR:
- case OP_NOTMINSTAR:
- case OP_NOTPLUS:
- case OP_NOTMINPLUS:
- case OP_NOTQUERY:
- case OP_NOTMINQUERY:
- case OP_NOTUPTO:
- case OP_NOTMINUPTO:
- case OP_NOTEXACT:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSPLUS:
- case OP_NOTPOSQUERY:
- case OP_NOTPOSUPTO:
- case OP_NOTSTARI:
- case OP_NOTMINSTARI:
- case OP_NOTPLUSI:
- case OP_NOTMINPLUSI:
- case OP_NOTQUERYI:
- case OP_NOTMINQUERYI:
- case OP_NOTUPTOI:
- case OP_NOTMINUPTOI:
- case OP_NOTEXACTI:
- case OP_NOTPOSSTARI:
- case OP_NOTPOSPLUSI:
- case OP_NOTPOSQUERYI:
- case OP_NOTPOSUPTOI:
- if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);
- break;
- }
-#else
- (void)(utf); /* Keep compiler happy by referencing function argument */
-#endif /* SUPPORT_WIDE_CHARS */
- }
-}
-
-/* End of pcre2_auto_possess.c */
diff --git a/contrib/libs/pcre2/src/pcre2_chartables.c b/contrib/libs/pcre2/src/pcre2_chartables.c
deleted file mode 100644
index 4506b0d5ee..0000000000
--- a/contrib/libs/pcre2/src/pcre2_chartables.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* This file was automatically written by the pcre2_dftables auxiliary
-program. It contains character tables that are used when no external
-tables are passed to PCRE2 by the application that calls it. The tables
-are used only for characters whose code values are less than 256. */
-
-/* This set of tables was written in the C locale. */
-
-/* The pcre2_ftables program (which is distributed with PCRE2) can be used
-to build alternative versions of this file. This is necessary if you are
-running in an EBCDIC environment, or if you want to default to a different
-encoding, for example ISO-8859-1. When pcre2_dftables is run, it creates
-these tables in the "C" locale by default. This happens automatically if
-PCRE2 is configured with --enable-rebuild-chartables. However, you can run
-pcre2_dftables manually with the -L option to build tables using the LC_ALL
-locale. */
-
-/* The following #include is present because without it gcc 4.x may remove
-the array definition from the final binary if PCRE2 is built into a static
-library and dead code stripping is activated. This leads to link errors.
-Pulling in the header ensures that the array gets flagged as "someone
-outside this compilation unit might reference this" and so it will always
-be supplied to the linker. */
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-#include "pcre2_internal.h"
-
-const uint8_t PRIV(default_tables)[] = {
-
-/* This table is a lower casing table. */
-
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 97, 98, 99,100,101,102,103,
- 104,105,106,107,108,109,110,111,
- 112,113,114,115,116,117,118,119,
- 120,121,122, 91, 92, 93, 94, 95,
- 96, 97, 98, 99,100,101,102,103,
- 104,105,106,107,108,109,110,111,
- 112,113,114,115,116,117,118,119,
- 120,121,122,123,124,125,126,127,
- 128,129,130,131,132,133,134,135,
- 136,137,138,139,140,141,142,143,
- 144,145,146,147,148,149,150,151,
- 152,153,154,155,156,157,158,159,
- 160,161,162,163,164,165,166,167,
- 168,169,170,171,172,173,174,175,
- 176,177,178,179,180,181,182,183,
- 184,185,186,187,188,189,190,191,
- 192,193,194,195,196,197,198,199,
- 200,201,202,203,204,205,206,207,
- 208,209,210,211,212,213,214,215,
- 216,217,218,219,220,221,222,223,
- 224,225,226,227,228,229,230,231,
- 232,233,234,235,236,237,238,239,
- 240,241,242,243,244,245,246,247,
- 248,249,250,251,252,253,254,255,
-
-/* This table is a case flipping table. */
-
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 97, 98, 99,100,101,102,103,
- 104,105,106,107,108,109,110,111,
- 112,113,114,115,116,117,118,119,
- 120,121,122, 91, 92, 93, 94, 95,
- 96, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87,
- 88, 89, 90,123,124,125,126,127,
- 128,129,130,131,132,133,134,135,
- 136,137,138,139,140,141,142,143,
- 144,145,146,147,148,149,150,151,
- 152,153,154,155,156,157,158,159,
- 160,161,162,163,164,165,166,167,
- 168,169,170,171,172,173,174,175,
- 176,177,178,179,180,181,182,183,
- 184,185,186,187,188,189,190,191,
- 192,193,194,195,196,197,198,199,
- 200,201,202,203,204,205,206,207,
- 208,209,210,211,212,213,214,215,
- 216,217,218,219,220,221,222,223,
- 224,225,226,227,228,229,230,231,
- 232,233,234,235,236,237,238,239,
- 240,241,242,243,244,245,246,247,
- 248,249,250,251,252,253,254,255,
-
-/* This table contains bit maps for various character classes. Each map is 32
-bytes long and the bits run from the least significant end of each byte. The
-classes that have their own maps are: space, xdigit, digit, upper, lower, word,
-graph, print, punct, and cntrl. Other classes are built from combinations. */
-
- 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00, /* space */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, /* xdigit */
- 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, /* digit */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* upper */
- 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* lower */
- 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, /* word */
- 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff, /* graph */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, /* print */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc, /* punct */
- 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, /* cntrl */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
-/* This table identifies various classes of character by individual bits:
- 0x01 white space character
- 0x02 letter
- 0x04 lower case letter
- 0x08 decimal digit
- 0x10 alphanumeric or '_'
-*/
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */
- 0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, /* 8- 15 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
- 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - ' */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ( - / */
- 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0 - 7 */
- 0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00, /* 8 - ? */
- 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* @ - G */
- 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */
- 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */
- 0x12,0x12,0x12,0x00,0x00,0x00,0x00,0x10, /* X - _ */
- 0x00,0x16,0x16,0x16,0x16,0x16,0x16,0x16, /* ` - g */
- 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16, /* h - o */
- 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16, /* p - w */
- 0x16,0x16,0x16,0x00,0x00,0x00,0x00,0x00, /* x -127 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
-
-/* End of pcre2_chartables.c */
diff --git a/contrib/libs/pcre2/src/pcre2_compile.c b/contrib/libs/pcre2/src/pcre2_compile.c
deleted file mode 100644
index 4caeecf6a4..0000000000
--- a/contrib/libs/pcre2/src/pcre2_compile.c
+++ /dev/null
@@ -1,10631 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2022 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-#define NLBLOCK cb /* Block containing newline information */
-#define PSSTART start_pattern /* Field containing processed string start */
-#define PSEND end_pattern /* Field containing processed string end */
-
-#include "pcre2_internal.h"
-
-/* In rare error cases debugging might require calling pcre2_printint(). */
-
-#if 0
-#ifdef EBCDIC
-#define PRINTABLE(c) ((c) >= 64 && (c) < 255)
-#else
-#define PRINTABLE(c) ((c) >= 32 && (c) < 127)
-#endif
-#error #include "pcre2_printint.c"
-#define DEBUG_CALL_PRINTINT
-#endif
-
-/* Other debugging code can be enabled by these defines. */
-
-/* #define DEBUG_SHOW_CAPTURES */
-/* #define DEBUG_SHOW_PARSED */
-
-/* There are a few things that vary with different code unit sizes. Handle them
-by defining macros in order to minimize #if usage. */
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
-#define STRING_UTFn_RIGHTPAR STRING_UTF8_RIGHTPAR, 5
-#define XDIGIT(c) xdigitab[c]
-
-#else /* Either 16-bit or 32-bit */
-#define XDIGIT(c) (MAX_255(c)? xdigitab[c] : 0xff)
-
-#if PCRE2_CODE_UNIT_WIDTH == 16
-#define STRING_UTFn_RIGHTPAR STRING_UTF16_RIGHTPAR, 6
-
-#else /* 32-bit */
-#define STRING_UTFn_RIGHTPAR STRING_UTF32_RIGHTPAR, 6
-#endif
-#endif
-
-/* Macros to store and retrieve a PCRE2_SIZE value in the parsed pattern, which
-consists of uint32_t elements. Assume that if uint32_t can't hold it, two of
-them will be able to (i.e. assume a 64-bit world). */
-
-#if PCRE2_SIZE_MAX <= UINT32_MAX
-#define PUTOFFSET(s,p) *p++ = s
-#define GETOFFSET(s,p) s = *p++
-#define GETPLUSOFFSET(s,p) s = *(++p)
-#define READPLUSOFFSET(s,p) s = p[1]
-#define SKIPOFFSET(p) p++
-#define SIZEOFFSET 1
-#else
-#define PUTOFFSET(s,p) \
- { *p++ = (uint32_t)(s >> 32); *p++ = (uint32_t)(s & 0xffffffff); }
-#define GETOFFSET(s,p) \
- { s = ((PCRE2_SIZE)p[0] << 32) | (PCRE2_SIZE)p[1]; p += 2; }
-#define GETPLUSOFFSET(s,p) \
- { s = ((PCRE2_SIZE)p[1] << 32) | (PCRE2_SIZE)p[2]; p += 2; }
-#define READPLUSOFFSET(s,p) \
- { s = ((PCRE2_SIZE)p[1] << 32) | (PCRE2_SIZE)p[2]; }
-#define SKIPOFFSET(p) p += 2
-#define SIZEOFFSET 2
-#endif
-
-/* Macros for manipulating elements of the parsed pattern vector. */
-
-#define META_CODE(x) (x & 0xffff0000u)
-#define META_DATA(x) (x & 0x0000ffffu)
-#define META_DIFF(x,y) ((x-y)>>16)
-
-/* Function definitions to allow mutual recursion */
-
-#ifdef SUPPORT_UNICODE
-static unsigned int
- add_list_to_class_internal(uint8_t *, PCRE2_UCHAR **, uint32_t,
- compile_block *, const uint32_t *, unsigned int);
-#endif
-
-static int
- compile_regex(uint32_t, PCRE2_UCHAR **, uint32_t **, int *, uint32_t,
- uint32_t *, uint32_t *, uint32_t *, uint32_t *, branch_chain *,
- compile_block *, PCRE2_SIZE *);
-
-static int
- get_branchlength(uint32_t **, int *, int *, parsed_recurse_check *,
- compile_block *);
-
-static BOOL
- set_lookbehind_lengths(uint32_t **, int *, int *, parsed_recurse_check *,
- compile_block *);
-
-static int
- check_lookbehinds(uint32_t *, uint32_t **, parsed_recurse_check *,
- compile_block *, int *);
-
-
-/*************************************************
-* Code parameters and static tables *
-*************************************************/
-
-#define MAX_GROUP_NUMBER 65535u
-#define MAX_REPEAT_COUNT 65535u
-#define REPEAT_UNLIMITED (MAX_REPEAT_COUNT+1)
-
-/* COMPILE_WORK_SIZE specifies the size of stack workspace, which is used in
-different ways in the different pattern scans. The parsing and group-
-identifying pre-scan uses it to handle nesting, and needs it to be 16-bit
-aligned for this. Having defined the size in code units, we set up
-C16_WORK_SIZE as the number of elements in the 16-bit vector.
-
-During the first compiling phase, when determining how much memory is required,
-the regex is partly compiled into this space, but the compiled parts are
-discarded as soon as they can be, so that hopefully there will never be an
-overrun. The code does, however, check for an overrun, which can occur for
-pathological patterns. The size of the workspace depends on LINK_SIZE because
-the length of compiled items varies with this.
-
-In the real compile phase, this workspace is not currently used. */
-
-#define COMPILE_WORK_SIZE (3000*LINK_SIZE) /* Size in code units */
-
-#define C16_WORK_SIZE \
- ((COMPILE_WORK_SIZE * sizeof(PCRE2_UCHAR))/sizeof(uint16_t))
-
-/* A uint32_t vector is used for caching information about the size of
-capturing groups, to improve performance. A default is created on the stack of
-this size. */
-
-#define GROUPINFO_DEFAULT_SIZE 256
-
-/* The overrun tests check for a slightly smaller size so that they detect the
-overrun before it actually does run off the end of the data block. */
-
-#define WORK_SIZE_SAFETY_MARGIN (100)
-
-/* This value determines the size of the initial vector that is used for
-remembering named groups during the pre-compile. It is allocated on the stack,
-but if it is too small, it is expanded, in a similar way to the workspace. The
-value is the number of slots in the list. */
-
-#define NAMED_GROUP_LIST_SIZE 20
-
-/* The pre-compiling pass over the pattern creates a parsed pattern in a vector
-of uint32_t. For short patterns this lives on the stack, with this size. Heap
-memory is used for longer patterns. */
-
-#define PARSED_PATTERN_DEFAULT_SIZE 1024
-
-/* Maximum length value to check against when making sure that the variable
-that holds the compiled pattern length does not overflow. We make it a bit less
-than INT_MAX to allow for adding in group terminating code units, so that we
-don't have to check them every time. */
-
-#define OFLOW_MAX (INT_MAX - 20)
-
-/* Code values for parsed patterns, which are stored in a vector of 32-bit
-unsigned ints. Values less than META_END are literal data values. The coding
-for identifying the item is in the top 16-bits, leaving 16 bits for the
-additional data that some of them need. The META_CODE, META_DATA, and META_DIFF
-macros are used to manipulate parsed pattern elements.
-
-NOTE: When these definitions are changed, the table of extra lengths for each
-code (meta_extra_lengths, just below) must be updated to remain in step. */
-
-#define META_END 0x80000000u /* End of pattern */
-
-#define META_ALT 0x80010000u /* alternation */
-#define META_ATOMIC 0x80020000u /* atomic group */
-#define META_BACKREF 0x80030000u /* Back ref */
-#define META_BACKREF_BYNAME 0x80040000u /* \k'name' */
-#define META_BIGVALUE 0x80050000u /* Next is a literal > META_END */
-#define META_CALLOUT_NUMBER 0x80060000u /* (?C with numerical argument */
-#define META_CALLOUT_STRING 0x80070000u /* (?C with string argument */
-#define META_CAPTURE 0x80080000u /* Capturing parenthesis */
-#define META_CIRCUMFLEX 0x80090000u /* ^ metacharacter */
-#define META_CLASS 0x800a0000u /* start non-empty class */
-#define META_CLASS_EMPTY 0x800b0000u /* empty class */
-#define META_CLASS_EMPTY_NOT 0x800c0000u /* negative empty class */
-#define META_CLASS_END 0x800d0000u /* end of non-empty class */
-#define META_CLASS_NOT 0x800e0000u /* start non-empty negative class */
-#define META_COND_ASSERT 0x800f0000u /* (?(?assertion)... */
-#define META_COND_DEFINE 0x80100000u /* (?(DEFINE)... */
-#define META_COND_NAME 0x80110000u /* (?(<name>)... */
-#define META_COND_NUMBER 0x80120000u /* (?(digits)... */
-#define META_COND_RNAME 0x80130000u /* (?(R&name)... */
-#define META_COND_RNUMBER 0x80140000u /* (?(Rdigits)... */
-#define META_COND_VERSION 0x80150000u /* (?(VERSION<op>x.y)... */
-#define META_DOLLAR 0x80160000u /* $ metacharacter */
-#define META_DOT 0x80170000u /* . metacharacter */
-#define META_ESCAPE 0x80180000u /* \d and friends */
-#define META_KET 0x80190000u /* closing parenthesis */
-#define META_NOCAPTURE 0x801a0000u /* no capture parens */
-#define META_OPTIONS 0x801b0000u /* (?i) and friends */
-#define META_POSIX 0x801c0000u /* POSIX class item */
-#define META_POSIX_NEG 0x801d0000u /* negative POSIX class item */
-#define META_RANGE_ESCAPED 0x801e0000u /* range with at least one escape */
-#define META_RANGE_LITERAL 0x801f0000u /* range defined literally */
-#define META_RECURSE 0x80200000u /* Recursion */
-#define META_RECURSE_BYNAME 0x80210000u /* (?&name) */
-#define META_SCRIPT_RUN 0x80220000u /* (*script_run:...) */
-
-/* These must be kept together to make it easy to check that an assertion
-is present where expected in a conditional group. */
-
-#define META_LOOKAHEAD 0x80230000u /* (?= */
-#define META_LOOKAHEADNOT 0x80240000u /* (?! */
-#define META_LOOKBEHIND 0x80250000u /* (?<= */
-#define META_LOOKBEHINDNOT 0x80260000u /* (?<! */
-
-/* These cannot be conditions */
-
-#define META_LOOKAHEAD_NA 0x80270000u /* (*napla: */
-#define META_LOOKBEHIND_NA 0x80280000u /* (*naplb: */
-
-/* These must be kept in this order, with consecutive values, and the _ARG
-versions of COMMIT, PRUNE, SKIP, and THEN immediately after their non-argument
-versions. */
-
-#define META_MARK 0x80290000u /* (*MARK) */
-#define META_ACCEPT 0x802a0000u /* (*ACCEPT) */
-#define META_FAIL 0x802b0000u /* (*FAIL) */
-#define META_COMMIT 0x802c0000u /* These */
-#define META_COMMIT_ARG 0x802d0000u /* pairs */
-#define META_PRUNE 0x802e0000u /* must */
-#define META_PRUNE_ARG 0x802f0000u /* be */
-#define META_SKIP 0x80300000u /* kept */
-#define META_SKIP_ARG 0x80310000u /* in */
-#define META_THEN 0x80320000u /* this */
-#define META_THEN_ARG 0x80330000u /* order */
-
-/* These must be kept in groups of adjacent 3 values, and all together. */
-
-#define META_ASTERISK 0x80340000u /* * */
-#define META_ASTERISK_PLUS 0x80350000u /* *+ */
-#define META_ASTERISK_QUERY 0x80360000u /* *? */
-#define META_PLUS 0x80370000u /* + */
-#define META_PLUS_PLUS 0x80380000u /* ++ */
-#define META_PLUS_QUERY 0x80390000u /* +? */
-#define META_QUERY 0x803a0000u /* ? */
-#define META_QUERY_PLUS 0x803b0000u /* ?+ */
-#define META_QUERY_QUERY 0x803c0000u /* ?? */
-#define META_MINMAX 0x803d0000u /* {n,m} repeat */
-#define META_MINMAX_PLUS 0x803e0000u /* {n,m}+ repeat */
-#define META_MINMAX_QUERY 0x803f0000u /* {n,m}? repeat */
-
-#define META_FIRST_QUANTIFIER META_ASTERISK
-#define META_LAST_QUANTIFIER META_MINMAX_QUERY
-
-/* This is a special "meta code" that is used only to distinguish (*asr: from
-(*sr: in the table of aphabetic assertions. It is never stored in the parsed
-pattern because (*asr: is turned into (*sr:(*atomic: at that stage. There is
-therefore no need for it to have a length entry, so use a high value. */
-
-#define META_ATOMIC_SCRIPT_RUN 0x8fff0000u
-
-/* Table of extra lengths for each of the meta codes. Must be kept in step with
-the definitions above. For some items these values are a basic length to which
-a variable amount has to be added. */
-
-static unsigned char meta_extra_lengths[] = {
- 0, /* META_END */
- 0, /* META_ALT */
- 0, /* META_ATOMIC */
- 0, /* META_BACKREF - more if group is >= 10 */
- 1+SIZEOFFSET, /* META_BACKREF_BYNAME */
- 1, /* META_BIGVALUE */
- 3, /* META_CALLOUT_NUMBER */
- 3+SIZEOFFSET, /* META_CALLOUT_STRING */
- 0, /* META_CAPTURE */
- 0, /* META_CIRCUMFLEX */
- 0, /* META_CLASS */
- 0, /* META_CLASS_EMPTY */
- 0, /* META_CLASS_EMPTY_NOT */
- 0, /* META_CLASS_END */
- 0, /* META_CLASS_NOT */
- 0, /* META_COND_ASSERT */
- SIZEOFFSET, /* META_COND_DEFINE */
- 1+SIZEOFFSET, /* META_COND_NAME */
- 1+SIZEOFFSET, /* META_COND_NUMBER */
- 1+SIZEOFFSET, /* META_COND_RNAME */
- 1+SIZEOFFSET, /* META_COND_RNUMBER */
- 3, /* META_COND_VERSION */
- 0, /* META_DOLLAR */
- 0, /* META_DOT */
- 0, /* META_ESCAPE - more for ESC_P, ESC_p, ESC_g, ESC_k */
- 0, /* META_KET */
- 0, /* META_NOCAPTURE */
- 1, /* META_OPTIONS */
- 1, /* META_POSIX */
- 1, /* META_POSIX_NEG */
- 0, /* META_RANGE_ESCAPED */
- 0, /* META_RANGE_LITERAL */
- SIZEOFFSET, /* META_RECURSE */
- 1+SIZEOFFSET, /* META_RECURSE_BYNAME */
- 0, /* META_SCRIPT_RUN */
- 0, /* META_LOOKAHEAD */
- 0, /* META_LOOKAHEADNOT */
- SIZEOFFSET, /* META_LOOKBEHIND */
- SIZEOFFSET, /* META_LOOKBEHINDNOT */
- 0, /* META_LOOKAHEAD_NA */
- SIZEOFFSET, /* META_LOOKBEHIND_NA */
- 1, /* META_MARK - plus the string length */
- 0, /* META_ACCEPT */
- 0, /* META_FAIL */
- 0, /* META_COMMIT */
- 1, /* META_COMMIT_ARG - plus the string length */
- 0, /* META_PRUNE */
- 1, /* META_PRUNE_ARG - plus the string length */
- 0, /* META_SKIP */
- 1, /* META_SKIP_ARG - plus the string length */
- 0, /* META_THEN */
- 1, /* META_THEN_ARG - plus the string length */
- 0, /* META_ASTERISK */
- 0, /* META_ASTERISK_PLUS */
- 0, /* META_ASTERISK_QUERY */
- 0, /* META_PLUS */
- 0, /* META_PLUS_PLUS */
- 0, /* META_PLUS_QUERY */
- 0, /* META_QUERY */
- 0, /* META_QUERY_PLUS */
- 0, /* META_QUERY_QUERY */
- 2, /* META_MINMAX */
- 2, /* META_MINMAX_PLUS */
- 2 /* META_MINMAX_QUERY */
-};
-
-/* Types for skipping parts of a parsed pattern. */
-
-enum { PSKIP_ALT, PSKIP_CLASS, PSKIP_KET };
-
-/* Macro for setting individual bits in class bitmaps. It took some
-experimenting to figure out how to stop gcc 5.3.0 from warning with
--Wconversion. This version gets a warning:
-
- #define SETBIT(a,b) a[(b)/8] |= (uint8_t)(1u << ((b)&7))
-
-Let's hope the apparently less efficient version isn't actually so bad if the
-compiler is clever with identical subexpressions. */
-
-#define SETBIT(a,b) a[(b)/8] = (uint8_t)(a[(b)/8] | (1u << ((b)&7)))
-
-/* Values and flags for the unsigned xxcuflags variables that accompany xxcu
-variables, which are concerned with first and required code units. A value
-greater than or equal to REQ_NONE means "no code unit set"; otherwise the
-matching xxcu variable is set, and the low valued bits are relevant. */
-
-#define REQ_UNSET 0xffffffffu /* Not yet found anything */
-#define REQ_NONE 0xfffffffeu /* Found not fixed character */
-#define REQ_CASELESS 0x00000001u /* Code unit in xxcu is caseless */
-#define REQ_VARY 0x00000002u /* Code unit is followed by non-literal */
-
-/* These flags are used in the groupinfo vector. */
-
-#define GI_SET_FIXED_LENGTH 0x80000000u
-#define GI_NOT_FIXED_LENGTH 0x40000000u
-#define GI_FIXED_LENGTH_MASK 0x0000ffffu
-
-/* This simple test for a decimal digit works for both ASCII/Unicode and EBCDIC
-and is fast (a good compiler can turn it into a subtraction and unsigned
-comparison). */
-
-#define IS_DIGIT(x) ((x) >= CHAR_0 && (x) <= CHAR_9)
-
-/* Table to identify hex digits. The tables in chartables are dependent on the
-locale, and may mark arbitrary characters as digits. We want to recognize only
-0-9, a-z, and A-Z as hex digits, which is why we have a private table here. It
-costs 256 bytes, but it is a lot faster than doing character value tests (at
-least in some simple cases I timed), and in some applications one wants PCRE2
-to compile efficiently as well as match efficiently. The value in the table is
-the binary hex digit value, or 0xff for non-hex digits. */
-
-/* This is the "normal" case, for ASCII systems, and EBCDIC systems running in
-UTF-8 mode. */
-
-#ifndef EBCDIC
-static const uint8_t xdigitab[] =
- {
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0- 7 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 8- 15 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 16- 23 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 24- 31 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* - ' */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* ( - / */
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, /* 0 - 7 */
- 0x08,0x09,0xff,0xff,0xff,0xff,0xff,0xff, /* 8 - ? */
- 0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /* @ - G */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* H - O */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* P - W */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* X - _ */
- 0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /* ` - g */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* h - o */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* p - w */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* x -127 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 128-135 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 136-143 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 144-151 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 152-159 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 160-167 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 168-175 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 176-183 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 184-191 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 192-199 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 2ff-207 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 208-215 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 216-223 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 224-231 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 232-239 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 240-247 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};/* 248-255 */
-
-#else
-
-/* This is the "abnormal" case, for EBCDIC systems not running in UTF-8 mode. */
-
-static const uint8_t xdigitab[] =
- {
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0- 7 0 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 8- 15 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 16- 23 10 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 24- 31 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 32- 39 20 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 40- 47 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 48- 55 30 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 56- 63 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* - 71 40 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 72- | */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* & - 87 50 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 88- 95 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* - -103 60 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 104- ? */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 112-119 70 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 120- " */
- 0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /* 128- g 80 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* h -143 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 144- p 90 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* q -159 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 160- x A0 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* y -175 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* ^ -183 B0 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 184-191 */
- 0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /* { - G C0 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* H -207 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* } - P D0 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* Q -223 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* \ - X E0 */
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* Y -239 */
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, /* 0 - 7 F0 */
- 0x08,0x09,0xff,0xff,0xff,0xff,0xff,0xff};/* 8 -255 */
-#endif /* EBCDIC */
-
-
-/* Table for handling alphanumeric escaped characters. Positive returns are
-simple data values; negative values are for special things like \d and so on.
-Zero means further processing is needed (for things like \x), or the escape is
-invalid. */
-
-/* This is the "normal" table for ASCII systems or for EBCDIC systems running
-in UTF-8 mode. It runs from '0' to 'z'. */
-
-#ifndef EBCDIC
-#define ESCAPES_FIRST CHAR_0
-#define ESCAPES_LAST CHAR_z
-#define UPPER_CASE(c) (c-32)
-
-static const short int escapes[] = {
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- CHAR_COLON, CHAR_SEMICOLON,
- CHAR_LESS_THAN_SIGN, CHAR_EQUALS_SIGN,
- CHAR_GREATER_THAN_SIGN, CHAR_QUESTION_MARK,
- CHAR_COMMERCIAL_AT, -ESC_A,
- -ESC_B, -ESC_C,
- -ESC_D, -ESC_E,
- 0, -ESC_G,
- -ESC_H, 0,
- 0, -ESC_K,
- 0, 0,
- -ESC_N, 0,
- -ESC_P, -ESC_Q,
- -ESC_R, -ESC_S,
- 0, 0,
- -ESC_V, -ESC_W,
- -ESC_X, 0,
- -ESC_Z, CHAR_LEFT_SQUARE_BRACKET,
- CHAR_BACKSLASH, CHAR_RIGHT_SQUARE_BRACKET,
- CHAR_CIRCUMFLEX_ACCENT, CHAR_UNDERSCORE,
- CHAR_GRAVE_ACCENT, CHAR_BEL,
- -ESC_b, 0,
- -ESC_d, CHAR_ESC,
- CHAR_FF, 0,
- -ESC_h, 0,
- 0, -ESC_k,
- 0, 0,
- CHAR_LF, 0,
- -ESC_p, 0,
- CHAR_CR, -ESC_s,
- CHAR_HT, 0,
- -ESC_v, -ESC_w,
- 0, 0,
- -ESC_z
-};
-
-#else
-
-/* This is the "abnormal" table for EBCDIC systems without UTF-8 support.
-It runs from 'a' to '9'. For some minimal testing of EBCDIC features, the code
-is sometimes compiled on an ASCII system. In this case, we must not use CHAR_a
-because it is defined as 'a', which of course picks up the ASCII value. */
-
-#if 'a' == 0x81 /* Check for a real EBCDIC environment */
-#define ESCAPES_FIRST CHAR_a
-#define ESCAPES_LAST CHAR_9
-#define UPPER_CASE(c) (c+64)
-#else /* Testing in an ASCII environment */
-#define ESCAPES_FIRST ((unsigned char)'\x81') /* EBCDIC 'a' */
-#define ESCAPES_LAST ((unsigned char)'\xf9') /* EBCDIC '9' */
-#define UPPER_CASE(c) (c-32)
-#endif
-
-static const short int escapes[] = {
-/* 80 */ CHAR_BEL, -ESC_b, 0, -ESC_d, CHAR_ESC, CHAR_FF, 0,
-/* 88 */ -ESC_h, 0, 0, '{', 0, 0, 0, 0,
-/* 90 */ 0, 0, -ESC_k, 0, 0, CHAR_LF, 0, -ESC_p,
-/* 98 */ 0, CHAR_CR, 0, '}', 0, 0, 0, 0,
-/* A0 */ 0, '~', -ESC_s, CHAR_HT, 0, -ESC_v, -ESC_w, 0,
-/* A8 */ 0, -ESC_z, 0, 0, 0, '[', 0, 0,
-/* B0 */ 0, 0, 0, 0, 0, 0, 0, 0,
-/* B8 */ 0, 0, 0, 0, 0, ']', '=', '-',
-/* C0 */ '{', -ESC_A, -ESC_B, -ESC_C, -ESC_D, -ESC_E, 0, -ESC_G,
-/* C8 */ -ESC_H, 0, 0, 0, 0, 0, 0, 0,
-/* D0 */ '}', 0, -ESC_K, 0, 0, -ESC_N, 0, -ESC_P,
-/* D8 */ -ESC_Q, -ESC_R, 0, 0, 0, 0, 0, 0,
-/* E0 */ '\\', 0, -ESC_S, 0, 0, -ESC_V, -ESC_W, -ESC_X,
-/* E8 */ 0, -ESC_Z, 0, 0, 0, 0, 0, 0,
-/* F0 */ 0, 0, 0, 0, 0, 0, 0, 0,
-/* F8 */ 0, 0
-};
-
-/* We also need a table of characters that may follow \c in an EBCDIC
-environment for characters 0-31. */
-
-static unsigned char ebcdic_escape_c[] = "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
-
-#endif /* EBCDIC */
-
-
-/* Table of special "verbs" like (*PRUNE). This is a short table, so it is
-searched linearly. Put all the names into a single string, in order to reduce
-the number of relocations when a shared library is dynamically linked. The
-string is built from string macros so that it works in UTF-8 mode on EBCDIC
-platforms. */
-
-typedef struct verbitem {
- unsigned int len; /* Length of verb name */
- uint32_t meta; /* Base META_ code */
- int has_arg; /* Argument requirement */
-} verbitem;
-
-static const char verbnames[] =
- "\0" /* Empty name is a shorthand for MARK */
- STRING_MARK0
- STRING_ACCEPT0
- STRING_F0
- STRING_FAIL0
- STRING_COMMIT0
- STRING_PRUNE0
- STRING_SKIP0
- STRING_THEN;
-
-static const verbitem verbs[] = {
- { 0, META_MARK, +1 }, /* > 0 => must have an argument */
- { 4, META_MARK, +1 },
- { 6, META_ACCEPT, -1 }, /* < 0 => Optional argument, convert to pre-MARK */
- { 1, META_FAIL, -1 },
- { 4, META_FAIL, -1 },
- { 6, META_COMMIT, 0 },
- { 5, META_PRUNE, 0 }, /* Optional argument; bump META code if found */
- { 4, META_SKIP, 0 },
- { 4, META_THEN, 0 }
-};
-
-static const int verbcount = sizeof(verbs)/sizeof(verbitem);
-
-/* Verb opcodes, indexed by their META code offset from META_MARK. */
-
-static const uint32_t verbops[] = {
- OP_MARK, OP_ACCEPT, OP_FAIL, OP_COMMIT, OP_COMMIT_ARG, OP_PRUNE,
- OP_PRUNE_ARG, OP_SKIP, OP_SKIP_ARG, OP_THEN, OP_THEN_ARG };
-
-/* Table of "alpha assertions" like (*pla:...), similar to the (*VERB) table. */
-
-typedef struct alasitem {
- unsigned int len; /* Length of name */
- uint32_t meta; /* Base META_ code */
-} alasitem;
-
-static const char alasnames[] =
- STRING_pla0
- STRING_plb0
- STRING_napla0
- STRING_naplb0
- STRING_nla0
- STRING_nlb0
- STRING_positive_lookahead0
- STRING_positive_lookbehind0
- STRING_non_atomic_positive_lookahead0
- STRING_non_atomic_positive_lookbehind0
- STRING_negative_lookahead0
- STRING_negative_lookbehind0
- STRING_atomic0
- STRING_sr0
- STRING_asr0
- STRING_script_run0
- STRING_atomic_script_run;
-
-static const alasitem alasmeta[] = {
- { 3, META_LOOKAHEAD },
- { 3, META_LOOKBEHIND },
- { 5, META_LOOKAHEAD_NA },
- { 5, META_LOOKBEHIND_NA },
- { 3, META_LOOKAHEADNOT },
- { 3, META_LOOKBEHINDNOT },
- { 18, META_LOOKAHEAD },
- { 19, META_LOOKBEHIND },
- { 29, META_LOOKAHEAD_NA },
- { 30, META_LOOKBEHIND_NA },
- { 18, META_LOOKAHEADNOT },
- { 19, META_LOOKBEHINDNOT },
- { 6, META_ATOMIC },
- { 2, META_SCRIPT_RUN }, /* sr = script run */
- { 3, META_ATOMIC_SCRIPT_RUN }, /* asr = atomic script run */
- { 10, META_SCRIPT_RUN }, /* script run */
- { 17, META_ATOMIC_SCRIPT_RUN } /* atomic script run */
-};
-
-static const int alascount = sizeof(alasmeta)/sizeof(alasitem);
-
-/* Offsets from OP_STAR for case-independent and negative repeat opcodes. */
-
-static uint32_t chartypeoffset[] = {
- OP_STAR - OP_STAR, OP_STARI - OP_STAR,
- OP_NOTSTAR - OP_STAR, OP_NOTSTARI - OP_STAR };
-
-/* Tables of names of POSIX character classes and their lengths. The names are
-now all in a single string, to reduce the number of relocations when a shared
-library is dynamically loaded. The list of lengths is terminated by a zero
-length entry. The first three must be alpha, lower, upper, as this is assumed
-for handling case independence. The indices for graph, print, and punct are
-needed, so identify them. */
-
-static const char posix_names[] =
- STRING_alpha0 STRING_lower0 STRING_upper0 STRING_alnum0
- STRING_ascii0 STRING_blank0 STRING_cntrl0 STRING_digit0
- STRING_graph0 STRING_print0 STRING_punct0 STRING_space0
- STRING_word0 STRING_xdigit;
-
-static const uint8_t posix_name_lengths[] = {
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 };
-
-#define PC_GRAPH 8
-#define PC_PRINT 9
-#define PC_PUNCT 10
-
-/* Table of class bit maps for each POSIX class. Each class is formed from a
-base map, with an optional addition or removal of another map. Then, for some
-classes, there is some additional tweaking: for [:blank:] the vertical space
-characters are removed, and for [:alpha:] and [:alnum:] the underscore
-character is removed. The triples in the table consist of the base map offset,
-second map offset or -1 if no second map, and a non-negative value for map
-addition or a negative value for map subtraction (if there are two maps). The
-absolute value of the third field has these meanings: 0 => no tweaking, 1 =>
-remove vertical space characters, 2 => remove underscore. */
-
-static const int posix_class_maps[] = {
- cbit_word, cbit_digit, -2, /* alpha */
- cbit_lower, -1, 0, /* lower */
- cbit_upper, -1, 0, /* upper */
- cbit_word, -1, 2, /* alnum - word without underscore */
- cbit_print, cbit_cntrl, 0, /* ascii */
- cbit_space, -1, 1, /* blank - a GNU extension */
- cbit_cntrl, -1, 0, /* cntrl */
- cbit_digit, -1, 0, /* digit */
- cbit_graph, -1, 0, /* graph */
- cbit_print, -1, 0, /* print */
- cbit_punct, -1, 0, /* punct */
- cbit_space, -1, 0, /* space */
- cbit_word, -1, 0, /* word - a Perl extension */
- cbit_xdigit,-1, 0 /* xdigit */
-};
-
-#ifdef SUPPORT_UNICODE
-
-/* The POSIX class Unicode property substitutes that are used in UCP mode must
-be in the order of the POSIX class names, defined above. */
-
-static int posix_substitutes[] = {
- PT_GC, ucp_L, /* alpha */
- PT_PC, ucp_Ll, /* lower */
- PT_PC, ucp_Lu, /* upper */
- PT_ALNUM, 0, /* alnum */
- -1, 0, /* ascii, treat as non-UCP */
- -1, 1, /* blank, treat as \h */
- PT_PC, ucp_Cc, /* cntrl */
- PT_PC, ucp_Nd, /* digit */
- PT_PXGRAPH, 0, /* graph */
- PT_PXPRINT, 0, /* print */
- PT_PXPUNCT, 0, /* punct */
- PT_PXSPACE, 0, /* space */ /* Xps is POSIX space, but from 8.34 */
- PT_WORD, 0, /* word */ /* Perl and POSIX space are the same */
- -1, 0 /* xdigit, treat as non-UCP */
-};
-#define POSIX_SUBSIZE (sizeof(posix_substitutes) / (2*sizeof(uint32_t)))
-#endif /* SUPPORT_UNICODE */
-
-/* Masks for checking option settings. When PCRE2_LITERAL is set, only a subset
-are allowed. */
-
-#define PUBLIC_LITERAL_COMPILE_OPTIONS \
- (PCRE2_ANCHORED|PCRE2_AUTO_CALLOUT|PCRE2_CASELESS|PCRE2_ENDANCHORED| \
- PCRE2_FIRSTLINE|PCRE2_LITERAL|PCRE2_MATCH_INVALID_UTF| \
- PCRE2_NO_START_OPTIMIZE|PCRE2_NO_UTF_CHECK|PCRE2_USE_OFFSET_LIMIT|PCRE2_UTF)
-
-#define PUBLIC_COMPILE_OPTIONS \
- (PUBLIC_LITERAL_COMPILE_OPTIONS| \
- PCRE2_ALLOW_EMPTY_CLASS|PCRE2_ALT_BSUX|PCRE2_ALT_CIRCUMFLEX| \
- PCRE2_ALT_VERBNAMES|PCRE2_DOLLAR_ENDONLY|PCRE2_DOTALL|PCRE2_DUPNAMES| \
- PCRE2_EXTENDED|PCRE2_EXTENDED_MORE|PCRE2_MATCH_UNSET_BACKREF| \
- PCRE2_MULTILINE|PCRE2_NEVER_BACKSLASH_C|PCRE2_NEVER_UCP| \
- PCRE2_NEVER_UTF|PCRE2_NO_AUTO_CAPTURE|PCRE2_NO_AUTO_POSSESS| \
- PCRE2_NO_DOTSTAR_ANCHOR|PCRE2_UCP|PCRE2_UNGREEDY)
-
-#define PUBLIC_LITERAL_COMPILE_EXTRA_OPTIONS \
- (PCRE2_EXTRA_MATCH_LINE|PCRE2_EXTRA_MATCH_WORD)
-
-#define PUBLIC_COMPILE_EXTRA_OPTIONS \
- (PUBLIC_LITERAL_COMPILE_EXTRA_OPTIONS| \
- PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES|PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL| \
- PCRE2_EXTRA_ESCAPED_CR_IS_LF|PCRE2_EXTRA_ALT_BSUX| \
- PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK)
-
-/* Compile time error code numbers. They are given names so that they can more
-easily be tracked. When a new number is added, the tables called eint1 and
-eint2 in pcre2posix.c may need to be updated, and a new error text must be
-added to compile_error_texts in pcre2_error.c. Also, the error codes in
-pcre2.h.in must be updated - their values are exactly 100 greater than these
-values. */
-
-enum { ERR0 = COMPILE_ERROR_BASE,
- ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9, ERR10,
- ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19, ERR20,
- ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29, ERR30,
- ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39, ERR40,
- ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49, ERR50,
- ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59, ERR60,
- ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, ERR70,
- ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79, ERR80,
- ERR81, ERR82, ERR83, ERR84, ERR85, ERR86, ERR87, ERR88, ERR89, ERR90,
- ERR91, ERR92, ERR93, ERR94, ERR95, ERR96, ERR97, ERR98, ERR99 };
-
-/* This is a table of start-of-pattern options such as (*UTF) and settings such
-as (*LIMIT_MATCH=nnnn) and (*CRLF). For completeness and backward
-compatibility, (*UTFn) is supported in the relevant libraries, but (*UTF) is
-generic and always supported. */
-
-enum { PSO_OPT, /* Value is an option bit */
- PSO_FLG, /* Value is a flag bit */
- PSO_NL, /* Value is a newline type */
- PSO_BSR, /* Value is a \R type */
- PSO_LIMH, /* Read integer value for heap limit */
- PSO_LIMM, /* Read integer value for match limit */
- PSO_LIMD }; /* Read integer value for depth limit */
-
-typedef struct pso {
- const uint8_t *name;
- uint16_t length;
- uint16_t type;
- uint32_t value;
-} pso;
-
-/* NB: STRING_UTFn_RIGHTPAR contains the length as well */
-
-static pso pso_list[] = {
- { (uint8_t *)STRING_UTFn_RIGHTPAR, PSO_OPT, PCRE2_UTF },
- { (uint8_t *)STRING_UTF_RIGHTPAR, 4, PSO_OPT, PCRE2_UTF },
- { (uint8_t *)STRING_UCP_RIGHTPAR, 4, PSO_OPT, PCRE2_UCP },
- { (uint8_t *)STRING_NOTEMPTY_RIGHTPAR, 9, PSO_FLG, PCRE2_NOTEMPTY_SET },
- { (uint8_t *)STRING_NOTEMPTY_ATSTART_RIGHTPAR, 17, PSO_FLG, PCRE2_NE_ATST_SET },
- { (uint8_t *)STRING_NO_AUTO_POSSESS_RIGHTPAR, 16, PSO_OPT, PCRE2_NO_AUTO_POSSESS },
- { (uint8_t *)STRING_NO_DOTSTAR_ANCHOR_RIGHTPAR, 18, PSO_OPT, PCRE2_NO_DOTSTAR_ANCHOR },
- { (uint8_t *)STRING_NO_JIT_RIGHTPAR, 7, PSO_FLG, PCRE2_NOJIT },
- { (uint8_t *)STRING_NO_START_OPT_RIGHTPAR, 13, PSO_OPT, PCRE2_NO_START_OPTIMIZE },
- { (uint8_t *)STRING_LIMIT_HEAP_EQ, 11, PSO_LIMH, 0 },
- { (uint8_t *)STRING_LIMIT_MATCH_EQ, 12, PSO_LIMM, 0 },
- { (uint8_t *)STRING_LIMIT_DEPTH_EQ, 12, PSO_LIMD, 0 },
- { (uint8_t *)STRING_LIMIT_RECURSION_EQ, 16, PSO_LIMD, 0 },
- { (uint8_t *)STRING_CR_RIGHTPAR, 3, PSO_NL, PCRE2_NEWLINE_CR },
- { (uint8_t *)STRING_LF_RIGHTPAR, 3, PSO_NL, PCRE2_NEWLINE_LF },
- { (uint8_t *)STRING_CRLF_RIGHTPAR, 5, PSO_NL, PCRE2_NEWLINE_CRLF },
- { (uint8_t *)STRING_ANY_RIGHTPAR, 4, PSO_NL, PCRE2_NEWLINE_ANY },
- { (uint8_t *)STRING_NUL_RIGHTPAR, 4, PSO_NL, PCRE2_NEWLINE_NUL },
- { (uint8_t *)STRING_ANYCRLF_RIGHTPAR, 8, PSO_NL, PCRE2_NEWLINE_ANYCRLF },
- { (uint8_t *)STRING_BSR_ANYCRLF_RIGHTPAR, 12, PSO_BSR, PCRE2_BSR_ANYCRLF },
- { (uint8_t *)STRING_BSR_UNICODE_RIGHTPAR, 12, PSO_BSR, PCRE2_BSR_UNICODE }
-};
-
-/* This table is used when converting repeating opcodes into possessified
-versions as a result of an explicit possessive quantifier such as ++. A zero
-value means there is no possessified version - in those cases the item in
-question must be wrapped in ONCE brackets. The table is truncated at OP_CALLOUT
-because all relevant opcodes are less than that. */
-
-static const uint8_t opcode_possessify[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 - 15 */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16 - 31 */
-
- 0, /* NOTI */
- OP_POSSTAR, 0, /* STAR, MINSTAR */
- OP_POSPLUS, 0, /* PLUS, MINPLUS */
- OP_POSQUERY, 0, /* QUERY, MINQUERY */
- OP_POSUPTO, 0, /* UPTO, MINUPTO */
- 0, /* EXACT */
- 0, 0, 0, 0, /* POS{STAR,PLUS,QUERY,UPTO} */
-
- OP_POSSTARI, 0, /* STARI, MINSTARI */
- OP_POSPLUSI, 0, /* PLUSI, MINPLUSI */
- OP_POSQUERYI, 0, /* QUERYI, MINQUERYI */
- OP_POSUPTOI, 0, /* UPTOI, MINUPTOI */
- 0, /* EXACTI */
- 0, 0, 0, 0, /* POS{STARI,PLUSI,QUERYI,UPTOI} */
-
- OP_NOTPOSSTAR, 0, /* NOTSTAR, NOTMINSTAR */
- OP_NOTPOSPLUS, 0, /* NOTPLUS, NOTMINPLUS */
- OP_NOTPOSQUERY, 0, /* NOTQUERY, NOTMINQUERY */
- OP_NOTPOSUPTO, 0, /* NOTUPTO, NOTMINUPTO */
- 0, /* NOTEXACT */
- 0, 0, 0, 0, /* NOTPOS{STAR,PLUS,QUERY,UPTO} */
-
- OP_NOTPOSSTARI, 0, /* NOTSTARI, NOTMINSTARI */
- OP_NOTPOSPLUSI, 0, /* NOTPLUSI, NOTMINPLUSI */
- OP_NOTPOSQUERYI, 0, /* NOTQUERYI, NOTMINQUERYI */
- OP_NOTPOSUPTOI, 0, /* NOTUPTOI, NOTMINUPTOI */
- 0, /* NOTEXACTI */
- 0, 0, 0, 0, /* NOTPOS{STARI,PLUSI,QUERYI,UPTOI} */
-
- OP_TYPEPOSSTAR, 0, /* TYPESTAR, TYPEMINSTAR */
- OP_TYPEPOSPLUS, 0, /* TYPEPLUS, TYPEMINPLUS */
- OP_TYPEPOSQUERY, 0, /* TYPEQUERY, TYPEMINQUERY */
- OP_TYPEPOSUPTO, 0, /* TYPEUPTO, TYPEMINUPTO */
- 0, /* TYPEEXACT */
- 0, 0, 0, 0, /* TYPEPOS{STAR,PLUS,QUERY,UPTO} */
-
- OP_CRPOSSTAR, 0, /* CRSTAR, CRMINSTAR */
- OP_CRPOSPLUS, 0, /* CRPLUS, CRMINPLUS */
- OP_CRPOSQUERY, 0, /* CRQUERY, CRMINQUERY */
- OP_CRPOSRANGE, 0, /* CRRANGE, CRMINRANGE */
- 0, 0, 0, 0, /* CRPOS{STAR,PLUS,QUERY,RANGE} */
-
- 0, 0, 0, /* CLASS, NCLASS, XCLASS */
- 0, 0, /* REF, REFI */
- 0, 0, /* DNREF, DNREFI */
- 0, 0 /* RECURSE, CALLOUT */
-};
-
-
-#ifdef DEBUG_SHOW_PARSED
-/*************************************************
-* Show the parsed pattern for debugging *
-*************************************************/
-
-/* For debugging the pre-scan, this code, which outputs the parsed data vector,
-can be enabled. */
-
-static void show_parsed(compile_block *cb)
-{
-uint32_t *pptr = cb->parsed_pattern;
-
-for (;;)
- {
- int max, min;
- PCRE2_SIZE offset;
- uint32_t i;
- uint32_t length;
- uint32_t meta_arg = META_DATA(*pptr);
-
- fprintf(stderr, "+++ %02d %.8x ", (int)(pptr - cb->parsed_pattern), *pptr);
-
- if (*pptr < META_END)
- {
- if (*pptr > 32 && *pptr < 128) fprintf(stderr, "%c", *pptr);
- pptr++;
- }
-
- else switch (META_CODE(*pptr++))
- {
- default:
- fprintf(stderr, "**** OOPS - unknown META value - giving up ****\n");
- return;
-
- case META_END:
- fprintf(stderr, "META_END\n");
- return;
-
- case META_CAPTURE:
- fprintf(stderr, "META_CAPTURE %d", meta_arg);
- break;
-
- case META_RECURSE:
- GETOFFSET(offset, pptr);
- fprintf(stderr, "META_RECURSE %d %zd", meta_arg, offset);
- break;
-
- case META_BACKREF:
- if (meta_arg < 10)
- offset = cb->small_ref_offset[meta_arg];
- else
- GETOFFSET(offset, pptr);
- fprintf(stderr, "META_BACKREF %d %zd", meta_arg, offset);
- break;
-
- case META_ESCAPE:
- if (meta_arg == ESC_P || meta_arg == ESC_p)
- {
- uint32_t ptype = *pptr >> 16;
- uint32_t pvalue = *pptr++ & 0xffff;
- fprintf(stderr, "META \\%c %d %d", (meta_arg == ESC_P)? 'P':'p',
- ptype, pvalue);
- }
- else
- {
- uint32_t cc;
- /* There's just one escape we might have here that isn't negated in the
- escapes table. */
- if (meta_arg == ESC_g) cc = CHAR_g;
- else for (cc = ESCAPES_FIRST; cc <= ESCAPES_LAST; cc++)
- {
- if (meta_arg == (uint32_t)(-escapes[cc - ESCAPES_FIRST])) break;
- }
- if (cc > ESCAPES_LAST) cc = CHAR_QUESTION_MARK;
- fprintf(stderr, "META \\%c", cc);
- }
- break;
-
- case META_MINMAX:
- min = *pptr++;
- max = *pptr++;
- if (max != REPEAT_UNLIMITED)
- fprintf(stderr, "META {%d,%d}", min, max);
- else
- fprintf(stderr, "META {%d,}", min);
- break;
-
- case META_MINMAX_QUERY:
- min = *pptr++;
- max = *pptr++;
- if (max != REPEAT_UNLIMITED)
- fprintf(stderr, "META {%d,%d}?", min, max);
- else
- fprintf(stderr, "META {%d,}?", min);
- break;
-
- case META_MINMAX_PLUS:
- min = *pptr++;
- max = *pptr++;
- if (max != REPEAT_UNLIMITED)
- fprintf(stderr, "META {%d,%d}+", min, max);
- else
- fprintf(stderr, "META {%d,}+", min);
- break;
-
- case META_BIGVALUE: fprintf(stderr, "META_BIGVALUE %.8x", *pptr++); break;
- case META_CIRCUMFLEX: fprintf(stderr, "META_CIRCUMFLEX"); break;
- case META_COND_ASSERT: fprintf(stderr, "META_COND_ASSERT"); break;
- case META_DOLLAR: fprintf(stderr, "META_DOLLAR"); break;
- case META_DOT: fprintf(stderr, "META_DOT"); break;
- case META_ASTERISK: fprintf(stderr, "META *"); break;
- case META_ASTERISK_QUERY: fprintf(stderr, "META *?"); break;
- case META_ASTERISK_PLUS: fprintf(stderr, "META *+"); break;
- case META_PLUS: fprintf(stderr, "META +"); break;
- case META_PLUS_QUERY: fprintf(stderr, "META +?"); break;
- case META_PLUS_PLUS: fprintf(stderr, "META ++"); break;
- case META_QUERY: fprintf(stderr, "META ?"); break;
- case META_QUERY_QUERY: fprintf(stderr, "META ??"); break;
- case META_QUERY_PLUS: fprintf(stderr, "META ?+"); break;
-
- case META_ATOMIC: fprintf(stderr, "META (?>"); break;
- case META_NOCAPTURE: fprintf(stderr, "META (?:"); break;
- case META_LOOKAHEAD: fprintf(stderr, "META (?="); break;
- case META_LOOKAHEADNOT: fprintf(stderr, "META (?!"); break;
- case META_LOOKAHEAD_NA: fprintf(stderr, "META (*napla:"); break;
- case META_SCRIPT_RUN: fprintf(stderr, "META (*sr:"); break;
- case META_KET: fprintf(stderr, "META )"); break;
- case META_ALT: fprintf(stderr, "META | %d", meta_arg); break;
-
- case META_CLASS: fprintf(stderr, "META ["); break;
- case META_CLASS_NOT: fprintf(stderr, "META [^"); break;
- case META_CLASS_END: fprintf(stderr, "META ]"); break;
- case META_CLASS_EMPTY: fprintf(stderr, "META []"); break;
- case META_CLASS_EMPTY_NOT: fprintf(stderr, "META [^]"); break;
-
- case META_RANGE_LITERAL: fprintf(stderr, "META - (literal)"); break;
- case META_RANGE_ESCAPED: fprintf(stderr, "META - (escaped)"); break;
-
- case META_POSIX: fprintf(stderr, "META_POSIX %d", *pptr++); break;
- case META_POSIX_NEG: fprintf(stderr, "META_POSIX_NEG %d", *pptr++); break;
-
- case META_ACCEPT: fprintf(stderr, "META (*ACCEPT)"); break;
- case META_FAIL: fprintf(stderr, "META (*FAIL)"); break;
- case META_COMMIT: fprintf(stderr, "META (*COMMIT)"); break;
- case META_PRUNE: fprintf(stderr, "META (*PRUNE)"); break;
- case META_SKIP: fprintf(stderr, "META (*SKIP)"); break;
- case META_THEN: fprintf(stderr, "META (*THEN)"); break;
-
- case META_OPTIONS: fprintf(stderr, "META_OPTIONS 0x%02x", *pptr++); break;
-
- case META_LOOKBEHIND:
- fprintf(stderr, "META (?<= %d offset=", meta_arg);
- GETOFFSET(offset, pptr);
- fprintf(stderr, "%zd", offset);
- break;
-
- case META_LOOKBEHIND_NA:
- fprintf(stderr, "META (*naplb: %d offset=", meta_arg);
- GETOFFSET(offset, pptr);
- fprintf(stderr, "%zd", offset);
- break;
-
- case META_LOOKBEHINDNOT:
- fprintf(stderr, "META (?<! %d offset=", meta_arg);
- GETOFFSET(offset, pptr);
- fprintf(stderr, "%zd", offset);
- break;
-
- case META_CALLOUT_NUMBER:
- fprintf(stderr, "META (?C%d) next=%d/%d", pptr[2], pptr[0],
- pptr[1]);
- pptr += 3;
- break;
-
- case META_CALLOUT_STRING:
- {
- uint32_t patoffset = *pptr++; /* Offset of next pattern item */
- uint32_t patlength = *pptr++; /* Length of next pattern item */
- fprintf(stderr, "META (?Cstring) length=%d offset=", *pptr++);
- GETOFFSET(offset, pptr);
- fprintf(stderr, "%zd next=%d/%d", offset, patoffset, patlength);
- }
- break;
-
- case META_RECURSE_BYNAME:
- fprintf(stderr, "META (?(&name) length=%d offset=", *pptr++);
- GETOFFSET(offset, pptr);
- fprintf(stderr, "%zd", offset);
- break;
-
- case META_BACKREF_BYNAME:
- fprintf(stderr, "META_BACKREF_BYNAME length=%d offset=", *pptr++);
- GETOFFSET(offset, pptr);
- fprintf(stderr, "%zd", offset);
- break;
-
- case META_COND_NUMBER:
- fprintf(stderr, "META_COND_NUMBER %d offset=", pptr[SIZEOFFSET]);
- GETOFFSET(offset, pptr);
- fprintf(stderr, "%zd", offset);
- pptr++;
- break;
-
- case META_COND_DEFINE:
- fprintf(stderr, "META (?(DEFINE) offset=");
- GETOFFSET(offset, pptr);
- fprintf(stderr, "%zd", offset);
- break;
-
- case META_COND_VERSION:
- fprintf(stderr, "META (?(VERSION%s", (*pptr++ == 0)? "=" : ">=");
- fprintf(stderr, "%d.", *pptr++);
- fprintf(stderr, "%d)", *pptr++);
- break;
-
- case META_COND_NAME:
- fprintf(stderr, "META (?(<name>) length=%d offset=", *pptr++);
- GETOFFSET(offset, pptr);
- fprintf(stderr, "%zd", offset);
- break;
-
- case META_COND_RNAME:
- fprintf(stderr, "META (?(R&name) length=%d offset=", *pptr++);
- GETOFFSET(offset, pptr);
- fprintf(stderr, "%zd", offset);
- break;
-
- /* This is kept as a name, because it might be. */
-
- case META_COND_RNUMBER:
- fprintf(stderr, "META (?(Rnumber) length=%d offset=", *pptr++);
- GETOFFSET(offset, pptr);
- fprintf(stderr, "%zd", offset);
- break;
-
- case META_MARK:
- fprintf(stderr, "META (*MARK:");
- goto SHOWARG;
-
- case META_COMMIT_ARG:
- fprintf(stderr, "META (*COMMIT:");
- goto SHOWARG;
-
- case META_PRUNE_ARG:
- fprintf(stderr, "META (*PRUNE:");
- goto SHOWARG;
-
- case META_SKIP_ARG:
- fprintf(stderr, "META (*SKIP:");
- goto SHOWARG;
-
- case META_THEN_ARG:
- fprintf(stderr, "META (*THEN:");
- SHOWARG:
- length = *pptr++;
- for (i = 0; i < length; i++)
- {
- uint32_t cc = *pptr++;
- if (cc > 32 && cc < 128) fprintf(stderr, "%c", cc);
- else fprintf(stderr, "\\x{%x}", cc);
- }
- fprintf(stderr, ") length=%u", length);
- break;
- }
- fprintf(stderr, "\n");
- }
-return;
-}
-#endif /* DEBUG_SHOW_PARSED */
-
-
-
-/*************************************************
-* Copy compiled code *
-*************************************************/
-
-/* Compiled JIT code cannot be copied, so the new compiled block has no
-associated JIT data. */
-
-PCRE2_EXP_DEFN pcre2_code * PCRE2_CALL_CONVENTION
-pcre2_code_copy(const pcre2_code *code)
-{
-PCRE2_SIZE* ref_count;
-pcre2_code *newcode;
-
-if (code == NULL) return NULL;
-newcode = code->memctl.malloc(code->blocksize, code->memctl.memory_data);
-if (newcode == NULL) return NULL;
-memcpy(newcode, code, code->blocksize);
-newcode->executable_jit = NULL;
-
-/* If the code is one that has been deserialized, increment the reference count
-in the decoded tables. */
-
-if ((code->flags & PCRE2_DEREF_TABLES) != 0)
- {
- ref_count = (PCRE2_SIZE *)(code->tables + TABLES_LENGTH);
- (*ref_count)++;
- }
-
-return newcode;
-}
-
-
-
-/*************************************************
-* Copy compiled code and character tables *
-*************************************************/
-
-/* Compiled JIT code cannot be copied, so the new compiled block has no
-associated JIT data. This version of code_copy also makes a separate copy of
-the character tables. */
-
-PCRE2_EXP_DEFN pcre2_code * PCRE2_CALL_CONVENTION
-pcre2_code_copy_with_tables(const pcre2_code *code)
-{
-PCRE2_SIZE* ref_count;
-pcre2_code *newcode;
-uint8_t *newtables;
-
-if (code == NULL) return NULL;
-newcode = code->memctl.malloc(code->blocksize, code->memctl.memory_data);
-if (newcode == NULL) return NULL;
-memcpy(newcode, code, code->blocksize);
-newcode->executable_jit = NULL;
-
-newtables = code->memctl.malloc(TABLES_LENGTH + sizeof(PCRE2_SIZE),
- code->memctl.memory_data);
-if (newtables == NULL)
- {
- code->memctl.free((void *)newcode, code->memctl.memory_data);
- return NULL;
- }
-memcpy(newtables, code->tables, TABLES_LENGTH);
-ref_count = (PCRE2_SIZE *)(newtables + TABLES_LENGTH);
-*ref_count = 1;
-
-newcode->tables = newtables;
-newcode->flags |= PCRE2_DEREF_TABLES;
-return newcode;
-}
-
-
-
-/*************************************************
-* Free compiled code *
-*************************************************/
-
-PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
-pcre2_code_free(pcre2_code *code)
-{
-PCRE2_SIZE* ref_count;
-
-if (code != NULL)
- {
-#ifdef SUPPORT_JIT
- if (code->executable_jit != NULL)
- PRIV(jit_free)(code->executable_jit, &code->memctl);
-#endif
-
- if ((code->flags & PCRE2_DEREF_TABLES) != 0)
- {
- /* Decoded tables belong to the codes after deserialization, and they must
- be freed when there are no more references to them. The *ref_count should
- always be > 0. */
-
- ref_count = (PCRE2_SIZE *)(code->tables + TABLES_LENGTH);
- if (*ref_count > 0)
- {
- (*ref_count)--;
- if (*ref_count == 0)
- code->memctl.free((void *)code->tables, code->memctl.memory_data);
- }
- }
-
- code->memctl.free(code, code->memctl.memory_data);
- }
-}
-
-
-
-/*************************************************
-* Read a number, possibly signed *
-*************************************************/
-
-/* This function is used to read numbers in the pattern. The initial pointer
-must be the sign or first digit of the number. When relative values (introduced
-by + or -) are allowed, they are relative group numbers, and the result must be
-greater than zero.
-
-Arguments:
- ptrptr points to the character pointer variable
- ptrend points to the end of the input string
- allow_sign if < 0, sign not allowed; if >= 0, sign is relative to this
- max_value the largest number allowed
- max_error the error to give for an over-large number
- intptr where to put the result
- errcodeptr where to put an error code
-
-Returns: TRUE - a number was read
- FALSE - errorcode == 0 => no number was found
- errorcode != 0 => an error occurred
-*/
-
-static BOOL
-read_number(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, int32_t allow_sign,
- uint32_t max_value, uint32_t max_error, int *intptr, int *errorcodeptr)
-{
-int sign = 0;
-uint32_t n = 0;
-PCRE2_SPTR ptr = *ptrptr;
-BOOL yield = FALSE;
-
-*errorcodeptr = 0;
-
-if (allow_sign >= 0 && ptr < ptrend)
- {
- if (*ptr == CHAR_PLUS)
- {
- sign = +1;
- max_value -= allow_sign;
- ptr++;
- }
- else if (*ptr == CHAR_MINUS)
- {
- sign = -1;
- ptr++;
- }
- }
-
-if (ptr >= ptrend || !IS_DIGIT(*ptr)) return FALSE;
-while (ptr < ptrend && IS_DIGIT(*ptr))
- {
- n = n * 10 + *ptr++ - CHAR_0;
- if (n > max_value)
- {
- *errorcodeptr = max_error;
- goto EXIT;
- }
- }
-
-if (allow_sign >= 0 && sign != 0)
- {
- if (n == 0)
- {
- *errorcodeptr = ERR26; /* +0 and -0 are not allowed */
- goto EXIT;
- }
-
- if (sign > 0) n += allow_sign;
- else if ((int)n > allow_sign)
- {
- *errorcodeptr = ERR15; /* Non-existent subpattern */
- goto EXIT;
- }
- else n = allow_sign + 1 - n;
- }
-
-yield = TRUE;
-
-EXIT:
-*intptr = n;
-*ptrptr = ptr;
-return yield;
-}
-
-
-
-/*************************************************
-* Read repeat counts *
-*************************************************/
-
-/* Read an item of the form {n,m} and return the values if non-NULL pointers
-are supplied. Repeat counts must be less than 65536 (MAX_REPEAT_COUNT); a
-larger value is used for "unlimited". We have to use signed arguments for
-read_number() because it is capable of returning a signed value.
-
-Arguments:
- ptrptr points to pointer to character after'{'
- ptrend pointer to end of input
- minp if not NULL, pointer to int for min
- maxp if not NULL, pointer to int for max (-1 if no max)
- returned as -1 if no max
- errorcodeptr points to error code variable
-
-Returns: FALSE if not a repeat quantifier, errorcode set zero
- FALSE on error, with errorcode set non-zero
- TRUE on success, with pointer updated to point after '}'
-*/
-
-static BOOL
-read_repeat_counts(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, uint32_t *minp,
- uint32_t *maxp, int *errorcodeptr)
-{
-PCRE2_SPTR p;
-BOOL yield = FALSE;
-BOOL had_comma = FALSE;
-int32_t min = 0;
-int32_t max = REPEAT_UNLIMITED; /* This value is larger than MAX_REPEAT_COUNT */
-
-/* Check the syntax */
-
-*errorcodeptr = 0;
-for (p = *ptrptr;; p++)
- {
- uint32_t c;
- if (p >= ptrend) return FALSE;
- c = *p;
- if (IS_DIGIT(c)) continue;
- if (c == CHAR_RIGHT_CURLY_BRACKET) break;
- if (c == CHAR_COMMA)
- {
- if (had_comma) return FALSE;
- had_comma = TRUE;
- }
- else return FALSE;
- }
-
-/* The only error from read_number() is for a number that is too big. */
-
-p = *ptrptr;
-if (!read_number(&p, ptrend, -1, MAX_REPEAT_COUNT, ERR5, &min, errorcodeptr))
- goto EXIT;
-
-if (*p == CHAR_RIGHT_CURLY_BRACKET)
- {
- p++;
- max = min;
- }
-else
- {
- if (*(++p) != CHAR_RIGHT_CURLY_BRACKET)
- {
- if (!read_number(&p, ptrend, -1, MAX_REPEAT_COUNT, ERR5, &max,
- errorcodeptr))
- goto EXIT;
- if (max < min)
- {
- *errorcodeptr = ERR4;
- goto EXIT;
- }
- }
- p++;
- }
-
-yield = TRUE;
-if (minp != NULL) *minp = (uint32_t)min;
-if (maxp != NULL) *maxp = (uint32_t)max;
-
-/* Update the pattern pointer */
-
-EXIT:
-*ptrptr = p;
-return yield;
-}
-
-
-
-/*************************************************
-* Handle escapes *
-*************************************************/
-
-/* This function is called when a \ has been encountered. It either returns a
-positive value for a simple escape such as \d, or 0 for a data character, which
-is placed in chptr. A backreference to group n is returned as negative n. On
-entry, ptr is pointing at the character after \. On exit, it points after the
-final code unit of the escape sequence.
-
-This function is also called from pcre2_substitute() to handle escape sequences
-in replacement strings. In this case, the cb argument is NULL, and in the case
-of escapes that have further processing, only sequences that define a data
-character are recognised. The isclass argument is not relevant; the options
-argument is the final value of the compiled pattern's options.
-
-Arguments:
- ptrptr points to the input position pointer
- ptrend points to the end of the input
- chptr points to a returned data character
- errorcodeptr points to the errorcode variable (containing zero)
- options the current options bits
- isclass TRUE if inside a character class
- cb compile data block or NULL when called from pcre2_substitute()
-
-Returns: zero => a data character
- positive => a special escape sequence
- negative => a numerical back reference
- on error, errorcodeptr is set non-zero
-*/
-
-int
-PRIV(check_escape)(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, uint32_t *chptr,
- int *errorcodeptr, uint32_t options, uint32_t extra_options, BOOL isclass,
- compile_block *cb)
-{
-BOOL utf = (options & PCRE2_UTF) != 0;
-PCRE2_SPTR ptr = *ptrptr;
-uint32_t c, cc;
-int escape = 0;
-int i;
-
-/* If backslash is at the end of the string, it's an error. */
-
-if (ptr >= ptrend)
- {
- *errorcodeptr = ERR1;
- return 0;
- }
-
-GETCHARINCTEST(c, ptr); /* Get character value, increment pointer */
-*errorcodeptr = 0; /* Be optimistic */
-
-/* Non-alphanumerics are literals, so we just leave the value in c. An initial
-value test saves a memory lookup for code points outside the alphanumeric
-range. */
-
-if (c < ESCAPES_FIRST || c > ESCAPES_LAST) {} /* Definitely literal */
-
-/* Otherwise, do a table lookup. Non-zero values need little processing here. A
-positive value is a literal value for something like \n. A negative value is
-the negation of one of the ESC_ macros that is passed back for handling by the
-calling function. Some extra checking is needed for \N because only \N{U+dddd}
-is supported. If the value is zero, further processing is handled below. */
-
-else if ((i = escapes[c - ESCAPES_FIRST]) != 0)
- {
- if (i > 0)
- {
- c = (uint32_t)i;
- if (c == CHAR_CR && (extra_options & PCRE2_EXTRA_ESCAPED_CR_IS_LF) != 0)
- c = CHAR_LF;
- }
- else /* Negative table entry */
- {
- escape = -i; /* Else return a special escape */
- if (cb != NULL && (escape == ESC_P || escape == ESC_p || escape == ESC_X))
- cb->external_flags |= PCRE2_HASBKPORX; /* Note \P, \p, or \X */
-
- /* Perl supports \N{name} for character names and \N{U+dddd} for numerical
- Unicode code points, as well as plain \N for "not newline". PCRE does not
- support \N{name}. However, it does support quantification such as \N{2,3},
- so if \N{ is not followed by U+dddd we check for a quantifier. */
-
- if (escape == ESC_N && ptr < ptrend && *ptr == CHAR_LEFT_CURLY_BRACKET)
- {
- PCRE2_SPTR p = ptr + 1;
-
- /* \N{U+ can be handled by the \x{ code. However, this construction is
- not valid in EBCDIC environments because it specifies a Unicode
- character, not a codepoint in the local code. For example \N{U+0041}
- must be "A" in all environments. Also, in Perl, \N{U+ forces Unicode
- casing semantics for the entire pattern, so allow it only in UTF (i.e.
- Unicode) mode. */
-
- if (ptrend - p > 1 && *p == CHAR_U && p[1] == CHAR_PLUS)
- {
-#ifdef EBCDIC
- *errorcodeptr = ERR93;
-#else
- if (utf)
- {
- ptr = p + 1;
- escape = 0; /* Not a fancy escape after all */
- goto COME_FROM_NU;
- }
- else *errorcodeptr = ERR93;
-#endif
- }
-
- /* Give an error if what follows is not a quantifier, but don't override
- an error set by the quantifier reader (e.g. number overflow). */
-
- else
- {
- if (!read_repeat_counts(&p, ptrend, NULL, NULL, errorcodeptr) &&
- *errorcodeptr == 0)
- *errorcodeptr = ERR37;
- }
- }
- }
- }
-
-/* Escapes that need further processing, including those that are unknown, have
-a zero entry in the lookup table. When called from pcre2_substitute(), only \c,
-\o, and \x are recognized (\u and \U can never appear as they are used for case
-forcing). */
-
-else
- {
- int s;
- PCRE2_SPTR oldptr;
- BOOL overflow;
- BOOL alt_bsux =
- ((options & PCRE2_ALT_BSUX) | (extra_options & PCRE2_EXTRA_ALT_BSUX)) != 0;
-
- /* Filter calls from pcre2_substitute(). */
-
- if (cb == NULL)
- {
- if (c != CHAR_c && c != CHAR_o && c != CHAR_x)
- {
- *errorcodeptr = ERR3;
- return 0;
- }
- alt_bsux = FALSE; /* Do not modify \x handling */
- }
-
- switch (c)
- {
- /* A number of Perl escapes are not handled by PCRE. We give an explicit
- error. */
-
- case CHAR_F:
- case CHAR_l:
- case CHAR_L:
- *errorcodeptr = ERR37;
- break;
-
- /* \u is unrecognized when neither PCRE2_ALT_BSUX nor PCRE2_EXTRA_ALT_BSUX
- is set. Otherwise, \u must be followed by exactly four hex digits or, if
- PCRE2_EXTRA_ALT_BSUX is set, by any number of hex digits in braces.
- Otherwise it is a lowercase u letter. This gives some compatibility with
- ECMAScript (aka JavaScript). */
-
- case CHAR_u:
- if (!alt_bsux) *errorcodeptr = ERR37; else
- {
- uint32_t xc;
-
- if (ptr >= ptrend) break;
- if (*ptr == CHAR_LEFT_CURLY_BRACKET &&
- (extra_options & PCRE2_EXTRA_ALT_BSUX) != 0)
- {
- PCRE2_SPTR hptr = ptr + 1;
- cc = 0;
-
- while (hptr < ptrend && (xc = XDIGIT(*hptr)) != 0xff)
- {
- if ((cc & 0xf0000000) != 0) /* Test for 32-bit overflow */
- {
- *errorcodeptr = ERR77;
- ptr = hptr; /* Show where */
- break; /* *hptr != } will cause another break below */
- }
- cc = (cc << 4) | xc;
- hptr++;
- }
-
- if (hptr == ptr + 1 || /* No hex digits */
- hptr >= ptrend || /* Hit end of input */
- *hptr != CHAR_RIGHT_CURLY_BRACKET) /* No } terminator */
- break; /* Hex escape not recognized */
-
- c = cc; /* Accept the code point */
- ptr = hptr + 1;
- }
-
- else /* Must be exactly 4 hex digits */
- {
- if (ptrend - ptr < 4) break; /* Less than 4 chars */
- if ((cc = XDIGIT(ptr[0])) == 0xff) break; /* Not a hex digit */
- if ((xc = XDIGIT(ptr[1])) == 0xff) break; /* Not a hex digit */
- cc = (cc << 4) | xc;
- if ((xc = XDIGIT(ptr[2])) == 0xff) break; /* Not a hex digit */
- cc = (cc << 4) | xc;
- if ((xc = XDIGIT(ptr[3])) == 0xff) break; /* Not a hex digit */
- c = (cc << 4) | xc;
- ptr += 4;
- }
-
- if (utf)
- {
- if (c > 0x10ffffU) *errorcodeptr = ERR77;
- else
- if (c >= 0xd800 && c <= 0xdfff &&
- (extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0)
- *errorcodeptr = ERR73;
- }
- else if (c > MAX_NON_UTF_CHAR) *errorcodeptr = ERR77;
- }
- break;
-
- /* \U is unrecognized unless PCRE2_ALT_BSUX or PCRE2_EXTRA_ALT_BSUX is set,
- in which case it is an upper case letter. */
-
- case CHAR_U:
- if (!alt_bsux) *errorcodeptr = ERR37;
- break;
-
- /* In a character class, \g is just a literal "g". Outside a character
- class, \g must be followed by one of a number of specific things:
-
- (1) A number, either plain or braced. If positive, it is an absolute
- backreference. If negative, it is a relative backreference. This is a Perl
- 5.10 feature.
-
- (2) Perl 5.10 also supports \g{name} as a reference to a named group. This
- is part of Perl's movement towards a unified syntax for back references. As
- this is synonymous with \k{name}, we fudge it up by pretending it really
- was \k{name}.
-
- (3) For Oniguruma compatibility we also support \g followed by a name or a
- number either in angle brackets or in single quotes. However, these are
- (possibly recursive) subroutine calls, _not_ backreferences. We return
- the ESC_g code.
-
- Summary: Return a negative number for a numerical back reference, ESC_k for
- a named back reference, and ESC_g for a named or numbered subroutine call.
- */
-
- case CHAR_g:
- if (isclass) break;
-
- if (ptr >= ptrend)
- {
- *errorcodeptr = ERR57;
- break;
- }
-
- if (*ptr == CHAR_LESS_THAN_SIGN || *ptr == CHAR_APOSTROPHE)
- {
- escape = ESC_g;
- break;
- }
-
- /* If there is a brace delimiter, try to read a numerical reference. If
- there isn't one, assume we have a name and treat it as \k. */
-
- if (*ptr == CHAR_LEFT_CURLY_BRACKET)
- {
- PCRE2_SPTR p = ptr + 1;
- if (!read_number(&p, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, &s,
- errorcodeptr))
- {
- if (*errorcodeptr == 0) escape = ESC_k; /* No number found */
- break;
- }
- if (p >= ptrend || *p != CHAR_RIGHT_CURLY_BRACKET)
- {
- *errorcodeptr = ERR57;
- break;
- }
- ptr = p + 1;
- }
-
- /* Read an undelimited number */
-
- else
- {
- if (!read_number(&ptr, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, &s,
- errorcodeptr))
- {
- if (*errorcodeptr == 0) *errorcodeptr = ERR57; /* No number found */
- break;
- }
- }
-
- if (s <= 0)
- {
- *errorcodeptr = ERR15;
- break;
- }
-
- escape = -s;
- break;
-
- /* The handling of escape sequences consisting of a string of digits
- starting with one that is not zero is not straightforward. Perl has changed
- over the years. Nowadays \g{} for backreferences and \o{} for octal are
- recommended to avoid the ambiguities in the old syntax.
-
- Outside a character class, the digits are read as a decimal number. If the
- number is less than 10, or if there are that many previous extracting left
- brackets, it is a back reference. Otherwise, up to three octal digits are
- read to form an escaped character code. Thus \123 is likely to be octal 123
- (cf \0123, which is octal 012 followed by the literal 3).
-
- Inside a character class, \ followed by a digit is always either a literal
- 8 or 9 or an octal number. */
-
- case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5:
- case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9:
-
- if (!isclass)
- {
- oldptr = ptr;
- ptr--; /* Back to the digit */
-
- /* As we know we are at a digit, the only possible error from
- read_number() is a number that is too large to be a group number. In this
- case we fall through handle this as not a group reference. If we have
- read a small enough number, check for a back reference.
-
- \1 to \9 are always back references. \8x and \9x are too; \1x to \7x
- are octal escapes if there are not that many previous captures. */
-
- if (read_number(&ptr, ptrend, -1, INT_MAX/10 - 1, 0, &s, errorcodeptr) &&
- (s < 10 || oldptr[-1] >= CHAR_8 || s <= (int)cb->bracount))
- {
- if (s > (int)MAX_GROUP_NUMBER) *errorcodeptr = ERR61;
- else escape = -s; /* Indicates a back reference */
- break;
- }
-
- ptr = oldptr; /* Put the pointer back and fall through */
- }
-
- /* Handle a digit following \ when the number is not a back reference, or
- we are within a character class. If the first digit is 8 or 9, Perl used to
- generate a binary zero and then treat the digit as a following literal. At
- least by Perl 5.18 this changed so as not to insert the binary zero. */
-
- if (c >= CHAR_8) break;
-
- /* Fall through */
-
- /* \0 always starts an octal number, but we may drop through to here with a
- larger first octal digit. The original code used just to take the least
- significant 8 bits of octal numbers (I think this is what early Perls used
- to do). Nowadays we allow for larger numbers in UTF-8 mode and 16-bit mode,
- but no more than 3 octal digits. */
-
- case CHAR_0:
- c -= CHAR_0;
- while(i++ < 2 && ptr < ptrend && *ptr >= CHAR_0 && *ptr <= CHAR_7)
- c = c * 8 + *ptr++ - CHAR_0;
-#if PCRE2_CODE_UNIT_WIDTH == 8
- if (!utf && c > 0xff) *errorcodeptr = ERR51;
-#endif
- break;
-
- /* \o is a relatively new Perl feature, supporting a more general way of
- specifying character codes in octal. The only supported form is \o{ddd}. */
-
- case CHAR_o:
- if (ptr >= ptrend || *ptr++ != CHAR_LEFT_CURLY_BRACKET)
- {
- ptr--;
- *errorcodeptr = ERR55;
- }
- else if (ptr >= ptrend || *ptr == CHAR_RIGHT_CURLY_BRACKET)
- *errorcodeptr = ERR78;
- else
- {
- c = 0;
- overflow = FALSE;
- while (ptr < ptrend && *ptr >= CHAR_0 && *ptr <= CHAR_7)
- {
- cc = *ptr++;
- if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */
-#if PCRE2_CODE_UNIT_WIDTH == 32
- if (c >= 0x20000000l) { overflow = TRUE; break; }
-#endif
- c = (c << 3) + (cc - CHAR_0);
-#if PCRE2_CODE_UNIT_WIDTH == 8
- if (c > (utf ? 0x10ffffU : 0xffU)) { overflow = TRUE; break; }
-#elif PCRE2_CODE_UNIT_WIDTH == 16
- if (c > (utf ? 0x10ffffU : 0xffffU)) { overflow = TRUE; break; }
-#elif PCRE2_CODE_UNIT_WIDTH == 32
- if (utf && c > 0x10ffffU) { overflow = TRUE; break; }
-#endif
- }
- if (overflow)
- {
- while (ptr < ptrend && *ptr >= CHAR_0 && *ptr <= CHAR_7) ptr++;
- *errorcodeptr = ERR34;
- }
- else if (ptr < ptrend && *ptr++ == CHAR_RIGHT_CURLY_BRACKET)
- {
- if (utf && c >= 0xd800 && c <= 0xdfff &&
- (extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0)
- {
- ptr--;
- *errorcodeptr = ERR73;
- }
- }
- else
- {
- ptr--;
- *errorcodeptr = ERR64;
- }
- }
- break;
-
- /* When PCRE2_ALT_BSUX or PCRE2_EXTRA_ALT_BSUX is set, \x must be followed
- by two hexadecimal digits. Otherwise it is a lowercase x letter. */
-
- case CHAR_x:
- if (alt_bsux)
- {
- uint32_t xc;
- if (ptrend - ptr < 2) break; /* Less than 2 characters */
- if ((cc = XDIGIT(ptr[0])) == 0xff) break; /* Not a hex digit */
- if ((xc = XDIGIT(ptr[1])) == 0xff) break; /* Not a hex digit */
- c = (cc << 4) | xc;
- ptr += 2;
- }
-
- /* Handle \x in Perl's style. \x{ddd} is a character code which can be
- greater than 0xff in UTF-8 or non-8bit mode, but only if the ddd are hex
- digits. If not, { used to be treated as a data character. However, Perl
- seems to read hex digits up to the first non-such, and ignore the rest, so
- that, for example \x{zz} matches a binary zero. This seems crazy, so PCRE
- now gives an error. */
-
- else
- {
- if (ptr < ptrend && *ptr == CHAR_LEFT_CURLY_BRACKET)
- {
-#ifndef EBCDIC
- COME_FROM_NU:
-#endif
- if (++ptr >= ptrend || *ptr == CHAR_RIGHT_CURLY_BRACKET)
- {
- *errorcodeptr = ERR78;
- break;
- }
- c = 0;
- overflow = FALSE;
-
- while (ptr < ptrend && (cc = XDIGIT(*ptr)) != 0xff)
- {
- ptr++;
- if (c == 0 && cc == 0) continue; /* Leading zeroes */
-#if PCRE2_CODE_UNIT_WIDTH == 32
- if (c >= 0x10000000l) { overflow = TRUE; break; }
-#endif
- c = (c << 4) | cc;
- if ((utf && c > 0x10ffffU) || (!utf && c > MAX_NON_UTF_CHAR))
- {
- overflow = TRUE;
- break;
- }
- }
-
- if (overflow)
- {
- while (ptr < ptrend && XDIGIT(*ptr) != 0xff) ptr++;
- *errorcodeptr = ERR34;
- }
- else if (ptr < ptrend && *ptr++ == CHAR_RIGHT_CURLY_BRACKET)
- {
- if (utf && c >= 0xd800 && c <= 0xdfff &&
- (extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0)
- {
- ptr--;
- *errorcodeptr = ERR73;
- }
- }
-
- /* If the sequence of hex digits does not end with '}', give an error.
- We used just to recognize this construct and fall through to the normal
- \x handling, but nowadays Perl gives an error, which seems much more
- sensible, so we do too. */
-
- else
- {
- ptr--;
- *errorcodeptr = ERR67;
- }
- } /* End of \x{} processing */
-
- /* Read a up to two hex digits after \x */
-
- else
- {
- c = 0;
- if (ptr >= ptrend || (cc = XDIGIT(*ptr)) == 0xff) break; /* Not a hex digit */
- ptr++;
- c = cc;
- if (ptr >= ptrend || (cc = XDIGIT(*ptr)) == 0xff) break; /* Not a hex digit */
- ptr++;
- c = (c << 4) | cc;
- } /* End of \xdd handling */
- } /* End of Perl-style \x handling */
- break;
-
- /* The handling of \c is different in ASCII and EBCDIC environments. In an
- ASCII (or Unicode) environment, an error is given if the character
- following \c is not a printable ASCII character. Otherwise, the following
- character is upper-cased if it is a letter, and after that the 0x40 bit is
- flipped. The result is the value of the escape.
-
- In an EBCDIC environment the handling of \c is compatible with the
- specification in the perlebcdic document. The following character must be
- a letter or one of small number of special characters. These provide a
- means of defining the character values 0-31.
-
- For testing the EBCDIC handling of \c in an ASCII environment, recognize
- the EBCDIC value of 'c' explicitly. */
-
-#if defined EBCDIC && 'a' != 0x81
- case 0x83:
-#else
- case CHAR_c:
-#endif
- if (ptr >= ptrend)
- {
- *errorcodeptr = ERR2;
- break;
- }
- c = *ptr;
- if (c >= CHAR_a && c <= CHAR_z) c = UPPER_CASE(c);
-
- /* Handle \c in an ASCII/Unicode environment. */
-
-#ifndef EBCDIC /* ASCII/UTF-8 coding */
- if (c < 32 || c > 126) /* Excludes all non-printable ASCII */
- {
- *errorcodeptr = ERR68;
- break;
- }
- c ^= 0x40;
-
- /* Handle \c in an EBCDIC environment. The special case \c? is converted to
- 255 (0xff) or 95 (0x5f) if other characters suggest we are using the
- POSIX-BC encoding. (This is the way Perl indicates that it handles \c?.)
- The other valid sequences correspond to a list of specific characters. */
-
-#else
- if (c == CHAR_QUESTION_MARK)
- c = ('\\' == 188 && '`' == 74)? 0x5f : 0xff;
- else
- {
- for (i = 0; i < 32; i++)
- {
- if (c == ebcdic_escape_c[i]) break;
- }
- if (i < 32) c = i; else *errorcodeptr = ERR68;
- }
-#endif /* EBCDIC */
-
- ptr++;
- break;
-
- /* Any other alphanumeric following \ is an error. Perl gives an error only
- if in warning mode, but PCRE doesn't have a warning mode. */
-
- default:
- *errorcodeptr = ERR3;
- *ptrptr = ptr - 1; /* Point to the character at fault */
- return 0;
- }
- }
-
-/* Set the pointer to the next character before returning. */
-
-*ptrptr = ptr;
-*chptr = c;
-return escape;
-}
-
-
-
-#ifdef SUPPORT_UNICODE
-/*************************************************
-* Handle \P and \p *
-*************************************************/
-
-/* This function is called after \P or \p has been encountered, provided that
-PCRE2 is compiled with support for UTF and Unicode properties. On entry, the
-contents of ptrptr are pointing after the P or p. On exit, it is left pointing
-after the final code unit of the escape sequence.
-
-Arguments:
- ptrptr the pattern position pointer
- negptr a boolean that is set TRUE for negation else FALSE
- ptypeptr an unsigned int that is set to the type value
- pdataptr an unsigned int that is set to the detailed property value
- errorcodeptr the error code variable
- cb the compile data
-
-Returns: TRUE if the type value was found, or FALSE for an invalid type
-*/
-
-static BOOL
-get_ucp(PCRE2_SPTR *ptrptr, BOOL *negptr, uint16_t *ptypeptr,
- uint16_t *pdataptr, int *errorcodeptr, compile_block *cb)
-{
-PCRE2_UCHAR c;
-PCRE2_SIZE i, bot, top;
-PCRE2_SPTR ptr = *ptrptr;
-PCRE2_UCHAR name[50];
-PCRE2_UCHAR *vptr = NULL;
-uint16_t ptscript = PT_NOTSCRIPT;
-
-if (ptr >= cb->end_pattern) goto ERROR_RETURN;
-c = *ptr++;
-*negptr = FALSE;
-
-/* \P or \p can be followed by a name in {}, optionally preceded by ^ for
-negation. */
-
-if (c == CHAR_LEFT_CURLY_BRACKET)
- {
- if (ptr >= cb->end_pattern) goto ERROR_RETURN;
-
- if (*ptr == CHAR_CIRCUMFLEX_ACCENT)
- {
- *negptr = TRUE;
- ptr++;
- }
-
- for (i = 0; i < (int)(sizeof(name) / sizeof(PCRE2_UCHAR)) - 1; i++)
- {
- if (ptr >= cb->end_pattern) goto ERROR_RETURN;
- c = *ptr++;
- while (c == '_' || c == '-' || isspace(c))
- {
- if (ptr >= cb->end_pattern) goto ERROR_RETURN;
- c = *ptr++;
- }
- if (c == CHAR_NUL) goto ERROR_RETURN;
- if (c == CHAR_RIGHT_CURLY_BRACKET) break;
- name[i] = tolower(c);
- if ((c == ':' || c == '=') && vptr == NULL) vptr = name + i;
- }
-
- if (c != CHAR_RIGHT_CURLY_BRACKET) goto ERROR_RETURN;
- name[i] = 0;
- }
-
-/* If { doesn't follow \p or \P there is just one following character, which
-must be an ASCII letter. */
-
-else if (MAX_255(c) && (cb->ctypes[c] & ctype_letter) != 0)
- {
- name[0] = tolower(c);
- name[1] = 0;
- }
-else goto ERROR_RETURN;
-
-*ptrptr = ptr;
-
-/* If the property contains ':' or '=' we have class name and value separately
-specified. The following are supported:
-
- . Bidi_Class (synonym bc), for which the property names are "bidi<name>".
- . Script (synonym sc) for which the property name is the script name
- . Script_Extensions (synonym scx), ditto
-
-As this is a small number, we currently just check the names directly. If this
-grows, a sorted table and a switch will be neater.
-
-For both the script properties, set a PT_xxx value so that (1) they can be
-distinguished and (2) invalid script names that happen to be the name of
-another property can be diagnosed. */
-
-if (vptr != NULL)
- {
- int offset = 0;
- PCRE2_UCHAR sname[8];
-
- *vptr = 0; /* Terminate property name */
- if (PRIV(strcmp_c8)(name, STRING_bidiclass) == 0 ||
- PRIV(strcmp_c8)(name, STRING_bc) == 0)
- {
- offset = 4;
- sname[0] = CHAR_b;
- sname[1] = CHAR_i; /* There is no strcpy_c8 function */
- sname[2] = CHAR_d;
- sname[3] = CHAR_i;
- }
-
- else if (PRIV(strcmp_c8)(name, STRING_script) == 0 ||
- PRIV(strcmp_c8)(name, STRING_sc) == 0)
- ptscript = PT_SC;
-
- else if (PRIV(strcmp_c8)(name, STRING_scriptextensions) == 0 ||
- PRIV(strcmp_c8)(name, STRING_scx) == 0)
- ptscript = PT_SCX;
-
- else
- {
- *errorcodeptr = ERR47;
- return FALSE;
- }
-
- /* Adjust the string in name[] as needed */
-
- memmove(name + offset, vptr + 1, (name + i - vptr)*sizeof(PCRE2_UCHAR));
- if (offset != 0) memmove(name, sname, offset*sizeof(PCRE2_UCHAR));
- }
-
-/* Search for a recognized property using binary chop. */
-
-bot = 0;
-top = PRIV(utt_size);
-
-while (bot < top)
- {
- int r;
- i = (bot + top) >> 1;
- r = PRIV(strcmp_c8)(name, PRIV(utt_names) + PRIV(utt)[i].name_offset);
-
- /* When a matching property is found, some extra checking is needed when the
- \p{xx:yy} syntax is used and xx is either sc or scx. */
-
- if (r == 0)
- {
- *pdataptr = PRIV(utt)[i].value;
- if (vptr == NULL || ptscript == PT_NOTSCRIPT)
- {
- *ptypeptr = PRIV(utt)[i].type;
- return TRUE;
- }
-
- switch (PRIV(utt)[i].type)
- {
- case PT_SC:
- *ptypeptr = PT_SC;
- return TRUE;
-
- case PT_SCX:
- *ptypeptr = ptscript;
- return TRUE;
- }
-
- break; /* Non-script found */
- }
-
- if (r > 0) bot = i + 1; else top = i;
- }
-
-*errorcodeptr = ERR47; /* Unrecognized property */
-return FALSE;
-
-ERROR_RETURN: /* Malformed \P or \p */
-*errorcodeptr = ERR46;
-*ptrptr = ptr;
-return FALSE;
-}
-#endif
-
-
-
-/*************************************************
-* Check for POSIX class syntax *
-*************************************************/
-
-/* This function is called when the sequence "[:" or "[." or "[=" is
-encountered in a character class. It checks whether this is followed by a
-sequence of characters terminated by a matching ":]" or ".]" or "=]". If we
-reach an unescaped ']' without the special preceding character, return FALSE.
-
-Originally, this function only recognized a sequence of letters between the
-terminators, but it seems that Perl recognizes any sequence of characters,
-though of course unknown POSIX names are subsequently rejected. Perl gives an
-"Unknown POSIX class" error for [:f\oo:] for example, where previously PCRE
-didn't consider this to be a POSIX class. Likewise for [:1234:].
-
-The problem in trying to be exactly like Perl is in the handling of escapes. We
-have to be sure that [abc[:x\]pqr] is *not* treated as containing a POSIX
-class, but [abc[:x\]pqr:]] is (so that an error can be generated). The code
-below handles the special cases \\ and \], but does not try to do any other
-escape processing. This makes it different from Perl for cases such as
-[:l\ower:] where Perl recognizes it as the POSIX class "lower" but PCRE does
-not recognize "l\ower". This is a lesser evil than not diagnosing bad classes
-when Perl does, I think.
-
-A user pointed out that PCRE was rejecting [:a[:digit:]] whereas Perl was not.
-It seems that the appearance of a nested POSIX class supersedes an apparent
-external class. For example, [:a[:digit:]b:] matches "a", "b", ":", or
-a digit. This is handled by returning FALSE if the start of a new group with
-the same terminator is encountered, since the next closing sequence must close
-the nested group, not the outer one.
-
-In Perl, unescaped square brackets may also appear as part of class names. For
-example, [:a[:abc]b:] gives unknown POSIX class "[:abc]b:]". However, for
-[:a[:abc]b][b:] it gives unknown POSIX class "[:abc]b][b:]", which does not
-seem right at all. PCRE does not allow closing square brackets in POSIX class
-names.
-
-Arguments:
- ptr pointer to the character after the initial [ (colon, dot, equals)
- ptrend pointer to the end of the pattern
- endptr where to return a pointer to the terminating ':', '.', or '='
-
-Returns: TRUE or FALSE
-*/
-
-static BOOL
-check_posix_syntax(PCRE2_SPTR ptr, PCRE2_SPTR ptrend, PCRE2_SPTR *endptr)
-{
-PCRE2_UCHAR terminator; /* Don't combine these lines; the Solaris cc */
-terminator = *ptr++; /* compiler warns about "non-constant" initializer. */
-
-for (; ptrend - ptr >= 2; ptr++)
- {
- if (*ptr == CHAR_BACKSLASH &&
- (ptr[1] == CHAR_RIGHT_SQUARE_BRACKET || ptr[1] == CHAR_BACKSLASH))
- ptr++;
-
- else if ((*ptr == CHAR_LEFT_SQUARE_BRACKET && ptr[1] == terminator) ||
- *ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE;
-
- else if (*ptr == terminator && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
- {
- *endptr = ptr;
- return TRUE;
- }
- }
-
-return FALSE;
-}
-
-
-
-/*************************************************
-* Check POSIX class name *
-*************************************************/
-
-/* This function is called to check the name given in a POSIX-style class entry
-such as [:alnum:].
-
-Arguments:
- ptr points to the first letter
- len the length of the name
-
-Returns: a value representing the name, or -1 if unknown
-*/
-
-static int
-check_posix_name(PCRE2_SPTR ptr, int len)
-{
-const char *pn = posix_names;
-int yield = 0;
-while (posix_name_lengths[yield] != 0)
- {
- if (len == posix_name_lengths[yield] &&
- PRIV(strncmp_c8)(ptr, pn, (unsigned int)len) == 0) return yield;
- pn += posix_name_lengths[yield] + 1;
- yield++;
- }
-return -1;
-}
-
-
-
-/*************************************************
-* Read a subpattern or VERB name *
-*************************************************/
-
-/* This function is called from parse_regex() below whenever it needs to read
-the name of a subpattern or a (*VERB) or an (*alpha_assertion). The initial
-pointer must be to the character before the name. If that character is '*' we
-are reading a verb or alpha assertion name. The pointer is updated to point
-after the name, for a VERB or alpha assertion name, or after tha name's
-terminator for a subpattern name. Returning both the offset and the name
-pointer is redundant information, but some callers use one and some the other,
-so it is simplest just to return both.
-
-Arguments:
- ptrptr points to the character pointer variable
- ptrend points to the end of the input string
- utf true if the input is UTF-encoded
- terminator the terminator of a subpattern name must be this
- offsetptr where to put the offset from the start of the pattern
- nameptr where to put a pointer to the name in the input
- namelenptr where to put the length of the name
- errcodeptr where to put an error code
- cb pointer to the compile data block
-
-Returns: TRUE if a name was read
- FALSE otherwise, with error code set
-*/
-
-static BOOL
-read_name(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, BOOL utf, uint32_t terminator,
- PCRE2_SIZE *offsetptr, PCRE2_SPTR *nameptr, uint32_t *namelenptr,
- int *errorcodeptr, compile_block *cb)
-{
-PCRE2_SPTR ptr = *ptrptr;
-BOOL is_group = (*ptr != CHAR_ASTERISK);
-
-if (++ptr >= ptrend) /* No characters in name */
- {
- *errorcodeptr = is_group? ERR62: /* Subpattern name expected */
- ERR60; /* Verb not recognized or malformed */
- goto FAILED;
- }
-
-*nameptr = ptr;
-*offsetptr = (PCRE2_SIZE)(ptr - cb->start_pattern);
-
-/* In UTF mode, a group name may contain letters and decimal digits as defined
-by Unicode properties, and underscores, but must not start with a digit. */
-
-#ifdef SUPPORT_UNICODE
-if (utf && is_group)
- {
- uint32_t c, type;
-
- GETCHAR(c, ptr);
- type = UCD_CHARTYPE(c);
-
- if (type == ucp_Nd)
- {
- *errorcodeptr = ERR44;
- goto FAILED;
- }
-
- for(;;)
- {
- if (type != ucp_Nd && PRIV(ucp_gentype)[type] != ucp_L &&
- c != CHAR_UNDERSCORE) break;
- ptr++;
- FORWARDCHARTEST(ptr, ptrend);
- if (ptr >= ptrend) break;
- GETCHAR(c, ptr);
- type = UCD_CHARTYPE(c);
- }
- }
-else
-#else
-(void)utf; /* Avoid compiler warning */
-#endif /* SUPPORT_UNICODE */
-
-/* Handle non-group names and group names in non-UTF modes. A group name must
-not start with a digit. If either of the others start with a digit it just
-won't be recognized. */
-
- {
- if (is_group && IS_DIGIT(*ptr))
- {
- *errorcodeptr = ERR44;
- goto FAILED;
- }
-
- while (ptr < ptrend && MAX_255(*ptr) && (cb->ctypes[*ptr] & ctype_word) != 0)
- {
- ptr++;
- }
- }
-
-/* Check name length */
-
-if (ptr > *nameptr + MAX_NAME_SIZE)
- {
- *errorcodeptr = ERR48;
- goto FAILED;
- }
-*namelenptr = (uint32_t)(ptr - *nameptr);
-
-/* Subpattern names must not be empty, and their terminator is checked here.
-(What follows a verb or alpha assertion name is checked separately.) */
-
-if (is_group)
- {
- if (ptr == *nameptr)
- {
- *errorcodeptr = ERR62; /* Subpattern name expected */
- goto FAILED;
- }
- if (ptr >= ptrend || *ptr != (PCRE2_UCHAR)terminator)
- {
- *errorcodeptr = ERR42;
- goto FAILED;
- }
- ptr++;
- }
-
-*ptrptr = ptr;
-return TRUE;
-
-FAILED:
-*ptrptr = ptr;
-return FALSE;
-}
-
-
-
-/*************************************************
-* Manage callouts at start of cycle *
-*************************************************/
-
-/* At the start of a new item in parse_regex() we are able to record the
-details of the previous item in a prior callout, and also to set up an
-automatic callout if enabled. Avoid having two adjacent automatic callouts,
-which would otherwise happen for items such as \Q that contribute nothing to
-the parsed pattern.
-
-Arguments:
- ptr current pattern pointer
- pcalloutptr points to a pointer to previous callout, or NULL
- auto_callout TRUE if auto_callouts are enabled
- parsed_pattern the parsed pattern pointer
- cb compile block
-
-Returns: possibly updated parsed_pattern pointer.
-*/
-
-static uint32_t *
-manage_callouts(PCRE2_SPTR ptr, uint32_t **pcalloutptr, BOOL auto_callout,
- uint32_t *parsed_pattern, compile_block *cb)
-{
-uint32_t *previous_callout = *pcalloutptr;
-
-if (previous_callout != NULL) previous_callout[2] = (uint32_t)(ptr -
- cb->start_pattern - (PCRE2_SIZE)previous_callout[1]);
-
-if (!auto_callout) previous_callout = NULL; else
- {
- if (previous_callout == NULL ||
- previous_callout != parsed_pattern - 4 ||
- previous_callout[3] != 255)
- {
- previous_callout = parsed_pattern; /* Set up new automatic callout */
- parsed_pattern += 4;
- previous_callout[0] = META_CALLOUT_NUMBER;
- previous_callout[2] = 0;
- previous_callout[3] = 255;
- }
- previous_callout[1] = (uint32_t)(ptr - cb->start_pattern);
- }
-
-*pcalloutptr = previous_callout;
-return parsed_pattern;
-}
-
-
-
-/*************************************************
-* Parse regex and identify named groups *
-*************************************************/
-
-/* This function is called first of all. It scans the pattern and does two
-things: (1) It identifies capturing groups and makes a table of named capturing
-groups so that information about them is fully available to both the compiling
-scans. (2) It writes a parsed version of the pattern with comments omitted and
-escapes processed into the parsed_pattern vector.
-
-Arguments:
- ptr points to the start of the pattern
- options compiling dynamic options (may change during the scan)
- has_lookbehind points to a boolean, set TRUE if a lookbehind is found
- cb pointer to the compile data block
-
-Returns: zero on success or a non-zero error code, with the
- error offset placed in the cb field
-*/
-
-/* A structure and some flags for dealing with nested groups. */
-
-typedef struct nest_save {
- uint16_t nest_depth;
- uint16_t reset_group;
- uint16_t max_group;
- uint16_t flags;
- uint32_t options;
-} nest_save;
-
-#define NSF_RESET 0x0001u
-#define NSF_CONDASSERT 0x0002u
-#define NSF_ATOMICSR 0x0004u
-
-/* Options that are changeable within the pattern must be tracked during
-parsing. Some (e.g. PCRE2_EXTENDED) are implemented entirely during parsing,
-but all must be tracked so that META_OPTIONS items set the correct values for
-the main compiling phase. */
-
-#define PARSE_TRACKED_OPTIONS (PCRE2_CASELESS|PCRE2_DOTALL|PCRE2_DUPNAMES| \
- PCRE2_EXTENDED|PCRE2_EXTENDED_MORE|PCRE2_MULTILINE|PCRE2_NO_AUTO_CAPTURE| \
- PCRE2_UNGREEDY)
-
-/* States used for analyzing ranges in character classes. The two OK values
-must be last. */
-
-enum { RANGE_NO, RANGE_STARTED, RANGE_OK_ESCAPED, RANGE_OK_LITERAL };
-
-/* Only in 32-bit mode can there be literals > META_END. A macro encapsulates
-the storing of literal values in the main parsed pattern, where they can always
-be quantified. */
-
-#if PCRE2_CODE_UNIT_WIDTH == 32
-#define PARSED_LITERAL(c, p) \
- { \
- if (c >= META_END) *p++ = META_BIGVALUE; \
- *p++ = c; \
- okquantifier = TRUE; \
- }
-#else
-#define PARSED_LITERAL(c, p) *p++ = c; okquantifier = TRUE;
-#endif
-
-/* Here's the actual function. */
-
-static int parse_regex(PCRE2_SPTR ptr, uint32_t options, BOOL *has_lookbehind,
- compile_block *cb)
-{
-uint32_t c;
-uint32_t delimiter;
-uint32_t namelen;
-uint32_t class_range_state;
-uint32_t *verblengthptr = NULL; /* Value avoids compiler warning */
-uint32_t *verbstartptr = NULL;
-uint32_t *previous_callout = NULL;
-uint32_t *parsed_pattern = cb->parsed_pattern;
-uint32_t *parsed_pattern_end = cb->parsed_pattern_end;
-uint32_t meta_quantifier = 0;
-uint32_t add_after_mark = 0;
-uint32_t extra_options = cb->cx->extra_options;
-uint16_t nest_depth = 0;
-int after_manual_callout = 0;
-int expect_cond_assert = 0;
-int errorcode = 0;
-int escape;
-int i;
-BOOL inescq = FALSE;
-BOOL inverbname = FALSE;
-BOOL utf = (options & PCRE2_UTF) != 0;
-BOOL auto_callout = (options & PCRE2_AUTO_CALLOUT) != 0;
-BOOL isdupname;
-BOOL negate_class;
-BOOL okquantifier = FALSE;
-PCRE2_SPTR thisptr;
-PCRE2_SPTR name;
-PCRE2_SPTR ptrend = cb->end_pattern;
-PCRE2_SPTR verbnamestart = NULL; /* Value avoids compiler warning */
-named_group *ng;
-nest_save *top_nest, *end_nests;
-
-/* Insert leading items for word and line matching (features provided for the
-benefit of pcre2grep). */
-
-if ((extra_options & PCRE2_EXTRA_MATCH_LINE) != 0)
- {
- *parsed_pattern++ = META_CIRCUMFLEX;
- *parsed_pattern++ = META_NOCAPTURE;
- }
-else if ((extra_options & PCRE2_EXTRA_MATCH_WORD) != 0)
- {
- *parsed_pattern++ = META_ESCAPE + ESC_b;
- *parsed_pattern++ = META_NOCAPTURE;
- }
-
-/* If the pattern is actually a literal string, process it separately to avoid
-cluttering up the main loop. */
-
-if ((options & PCRE2_LITERAL) != 0)
- {
- while (ptr < ptrend)
- {
- if (parsed_pattern >= parsed_pattern_end)
- {
- errorcode = ERR63; /* Internal error (parsed pattern overflow) */
- goto FAILED;
- }
- thisptr = ptr;
- GETCHARINCTEST(c, ptr);
- if (auto_callout)
- parsed_pattern = manage_callouts(thisptr, &previous_callout,
- auto_callout, parsed_pattern, cb);
- PARSED_LITERAL(c, parsed_pattern);
- }
- goto PARSED_END;
- }
-
-/* Process a real regex which may contain meta-characters. */
-
-top_nest = NULL;
-end_nests = (nest_save *)(cb->start_workspace + cb->workspace_size);
-
-/* The size of the nest_save structure might not be a factor of the size of the
-workspace. Therefore we must round down end_nests so as to correctly avoid
-creating a nest_save that spans the end of the workspace. */
-
-end_nests = (nest_save *)((char *)end_nests -
- ((cb->workspace_size * sizeof(PCRE2_UCHAR)) % sizeof(nest_save)));
-
-/* PCRE2_EXTENDED_MORE implies PCRE2_EXTENDED */
-
-if ((options & PCRE2_EXTENDED_MORE) != 0) options |= PCRE2_EXTENDED;
-
-/* Now scan the pattern */
-
-while (ptr < ptrend)
- {
- int prev_expect_cond_assert;
- uint32_t min_repeat = 0, max_repeat = 0;
- uint32_t set, unset, *optset;
- uint32_t terminator;
- uint32_t prev_meta_quantifier;
- BOOL prev_okquantifier;
- PCRE2_SPTR tempptr;
- PCRE2_SIZE offset;
-
- if (parsed_pattern >= parsed_pattern_end)
- {
- errorcode = ERR63; /* Internal error (parsed pattern overflow) */
- goto FAILED;
- }
-
- if (nest_depth > cb->cx->parens_nest_limit)
- {
- errorcode = ERR19;
- goto FAILED; /* Parentheses too deeply nested */
- }
-
- /* Get next input character, save its position for callout handling. */
-
- thisptr = ptr;
- GETCHARINCTEST(c, ptr);
-
- /* Copy quoted literals until \E, allowing for the possibility of automatic
- callouts, except when processing a (*VERB) "name". */
-
- if (inescq)
- {
- if (c == CHAR_BACKSLASH && ptr < ptrend && *ptr == CHAR_E)
- {
- inescq = FALSE;
- ptr++; /* Skip E */
- }
- else
- {
- if (expect_cond_assert > 0) /* A literal is not allowed if we are */
- { /* expecting a conditional assertion, */
- ptr--; /* but an empty \Q\E sequence is OK. */
- errorcode = ERR28;
- goto FAILED;
- }
- if (inverbname)
- { /* Don't use PARSED_LITERAL() because it */
-#if PCRE2_CODE_UNIT_WIDTH == 32 /* sets okquantifier. */
- if (c >= META_END) *parsed_pattern++ = META_BIGVALUE;
-#endif
- *parsed_pattern++ = c;
- }
- else
- {
- if (after_manual_callout-- <= 0)
- parsed_pattern = manage_callouts(thisptr, &previous_callout,
- auto_callout, parsed_pattern, cb);
- PARSED_LITERAL(c, parsed_pattern);
- }
- meta_quantifier = 0;
- }
- continue; /* Next character */
- }
-
- /* If we are processing the "name" part of a (*VERB:NAME) item, all
- characters up to the closing parenthesis are literals except when
- PCRE2_ALT_VERBNAMES is set. That causes backslash interpretation, but only \Q
- and \E and escaped characters are allowed (no character types such as \d). If
- PCRE2_EXTENDED is also set, we must ignore white space and # comments. Do
- this by not entering the special (*VERB:NAME) processing - they are then
- picked up below. Note that c is a character, not a code unit, so we must not
- use MAX_255 to test its size because MAX_255 tests code units and is assumed
- TRUE in 8-bit mode. */
-
- if (inverbname &&
- (
- /* EITHER: not both options set */
- ((options & (PCRE2_EXTENDED | PCRE2_ALT_VERBNAMES)) !=
- (PCRE2_EXTENDED | PCRE2_ALT_VERBNAMES)) ||
-#ifdef SUPPORT_UNICODE
- /* OR: character > 255 AND not Unicode Pattern White Space */
- (c > 255 && (c|1) != 0x200f && (c|1) != 0x2029) ||
-#endif
- /* OR: not a # comment or isspace() white space */
- (c < 256 && c != CHAR_NUMBER_SIGN && (cb->ctypes[c] & ctype_space) == 0
-#ifdef SUPPORT_UNICODE
- /* and not CHAR_NEL when Unicode is supported */
- && c != CHAR_NEL
-#endif
- )))
- {
- PCRE2_SIZE verbnamelength;
-
- switch(c)
- {
- default: /* Don't use PARSED_LITERAL() because it */
-#if PCRE2_CODE_UNIT_WIDTH == 32 /* sets okquantifier. */
- if (c >= META_END) *parsed_pattern++ = META_BIGVALUE;
-#endif
- *parsed_pattern++ = c;
- break;
-
- case CHAR_RIGHT_PARENTHESIS:
- inverbname = FALSE;
- /* This is the length in characters */
- verbnamelength = (PCRE2_SIZE)(parsed_pattern - verblengthptr - 1);
- /* But the limit on the length is in code units */
- if (ptr - verbnamestart - 1 > (int)MAX_MARK)
- {
- ptr--;
- errorcode = ERR76;
- goto FAILED;
- }
- *verblengthptr = (uint32_t)verbnamelength;
-
- /* If this name was on a verb such as (*ACCEPT) which does not continue,
- a (*MARK) was generated for the name. We now add the original verb as the
- next item. */
-
- if (add_after_mark != 0)
- {
- *parsed_pattern++ = add_after_mark;
- add_after_mark = 0;
- }
- break;
-
- case CHAR_BACKSLASH:
- if ((options & PCRE2_ALT_VERBNAMES) != 0)
- {
- escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options,
- cb->cx->extra_options, FALSE, cb);
- if (errorcode != 0) goto FAILED;
- }
- else escape = 0; /* Treat all as literal */
-
- switch(escape)
- {
- case 0: /* Don't use PARSED_LITERAL() because it */
-#if PCRE2_CODE_UNIT_WIDTH == 32 /* sets okquantifier. */
- if (c >= META_END) *parsed_pattern++ = META_BIGVALUE;
-#endif
- *parsed_pattern++ = c;
- break;
-
- case ESC_Q:
- inescq = TRUE;
- break;
-
- case ESC_E: /* Ignore */
- break;
-
- default:
- errorcode = ERR40; /* Invalid in verb name */
- goto FAILED;
- }
- }
- continue; /* Next character in pattern */
- }
-
- /* Not a verb name character. At this point we must process everything that
- must not change the quantification state. This is mainly comments, but we
- handle \Q and \E here as well, so that an item such as A\Q\E+ is treated as
- A+, as in Perl. An isolated \E is ignored. */
-
- if (c == CHAR_BACKSLASH && ptr < ptrend)
- {
- if (*ptr == CHAR_Q || *ptr == CHAR_E)
- {
- inescq = *ptr == CHAR_Q;
- ptr++;
- continue;
- }
- }
-
- /* Skip over whitespace and # comments in extended mode. Note that c is a
- character, not a code unit, so we must not use MAX_255 to test its size
- because MAX_255 tests code units and is assumed TRUE in 8-bit mode. The
- whitespace characters are those designated as "Pattern White Space" by
- Unicode, which are the isspace() characters plus CHAR_NEL (newline), which is
- U+0085 in Unicode, plus U+200E, U+200F, U+2028, and U+2029. These are a
- subset of space characters that match \h and \v. */
-
- if ((options & PCRE2_EXTENDED) != 0)
- {
- if (c < 256 && (cb->ctypes[c] & ctype_space) != 0) continue;
-#ifdef SUPPORT_UNICODE
- if (c == CHAR_NEL || (c|1) == 0x200f || (c|1) == 0x2029) continue;
-#endif
- if (c == CHAR_NUMBER_SIGN)
- {
- while (ptr < ptrend)
- {
- if (IS_NEWLINE(ptr)) /* For non-fixed-length newline cases, */
- { /* IS_NEWLINE sets cb->nllen. */
- ptr += cb->nllen;
- break;
- }
- ptr++;
-#ifdef SUPPORT_UNICODE
- if (utf) FORWARDCHARTEST(ptr, ptrend);
-#endif
- }
- continue; /* Next character in pattern */
- }
- }
-
- /* Skip over bracketed comments */
-
- if (c == CHAR_LEFT_PARENTHESIS && ptrend - ptr >= 2 &&
- ptr[0] == CHAR_QUESTION_MARK && ptr[1] == CHAR_NUMBER_SIGN)
- {
- while (++ptr < ptrend && *ptr != CHAR_RIGHT_PARENTHESIS);
- if (ptr >= ptrend)
- {
- errorcode = ERR18; /* A special error for missing ) in a comment */
- goto FAILED; /* to make it easier to debug. */
- }
- ptr++;
- continue; /* Next character in pattern */
- }
-
- /* If the next item is not a quantifier, fill in length of any previous
- callout and create an auto callout if required. */
-
- if (c != CHAR_ASTERISK && c != CHAR_PLUS && c != CHAR_QUESTION_MARK &&
- (c != CHAR_LEFT_CURLY_BRACKET ||
- (tempptr = ptr,
- !read_repeat_counts(&tempptr, ptrend, NULL, NULL, &errorcode))))
- {
- if (after_manual_callout-- <= 0)
- parsed_pattern = manage_callouts(thisptr, &previous_callout, auto_callout,
- parsed_pattern, cb);
- }
-
- /* If expect_cond_assert is 2, we have just passed (?( and are expecting an
- assertion, possibly preceded by a callout. If the value is 1, we have just
- had the callout and expect an assertion. There must be at least 3 more
- characters in all cases. When expect_cond_assert is 2, we know that the
- current character is an opening parenthesis, as otherwise we wouldn't be
- here. However, when it is 1, we need to check, and it's easiest just to check
- always. Note that expect_cond_assert may be negative, since all callouts just
- decrement it. */
-
- if (expect_cond_assert > 0)
- {
- BOOL ok = c == CHAR_LEFT_PARENTHESIS && ptrend - ptr >= 3 &&
- (ptr[0] == CHAR_QUESTION_MARK || ptr[0] == CHAR_ASTERISK);
- if (ok)
- {
- if (ptr[0] == CHAR_ASTERISK) /* New alpha assertion format, possibly */
- {
- ok = MAX_255(ptr[1]) && (cb->ctypes[ptr[1]] & ctype_lcletter) != 0;
- }
- else switch(ptr[1]) /* Traditional symbolic format */
- {
- case CHAR_C:
- ok = expect_cond_assert == 2;
- break;
-
- case CHAR_EQUALS_SIGN:
- case CHAR_EXCLAMATION_MARK:
- break;
-
- case CHAR_LESS_THAN_SIGN:
- ok = ptr[2] == CHAR_EQUALS_SIGN || ptr[2] == CHAR_EXCLAMATION_MARK;
- break;
-
- default:
- ok = FALSE;
- }
- }
-
- if (!ok)
- {
- ptr--; /* Adjust error offset */
- errorcode = ERR28;
- goto FAILED;
- }
- }
-
- /* Remember whether we are expecting a conditional assertion, and set the
- default for this item. */
-
- prev_expect_cond_assert = expect_cond_assert;
- expect_cond_assert = 0;
-
- /* Remember quantification status for the previous significant item, then set
- default for this item. */
-
- prev_okquantifier = okquantifier;
- prev_meta_quantifier = meta_quantifier;
- okquantifier = FALSE;
- meta_quantifier = 0;
-
- /* If the previous significant item was a quantifier, adjust the parsed code
- if there is a following modifier. The base meta value is always followed by
- the PLUS and QUERY values, in that order. We do this here rather than after
- reading a quantifier so that intervening comments and /x whitespace can be
- ignored without having to replicate code. */
-
- if (prev_meta_quantifier != 0 && (c == CHAR_QUESTION_MARK || c == CHAR_PLUS))
- {
- parsed_pattern[(prev_meta_quantifier == META_MINMAX)? -3 : -1] =
- prev_meta_quantifier + ((c == CHAR_QUESTION_MARK)?
- 0x00020000u : 0x00010000u);
- continue; /* Next character in pattern */
- }
-
-
- /* Process the next item in the main part of a pattern. */
-
- switch(c)
- {
- default: /* Non-special character */
- PARSED_LITERAL(c, parsed_pattern);
- break;
-
-
- /* ---- Escape sequence ---- */
-
- case CHAR_BACKSLASH:
- tempptr = ptr;
- escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options,
- cb->cx->extra_options, FALSE, cb);
- if (errorcode != 0)
- {
- ESCAPE_FAILED:
- if ((extra_options & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) == 0)
- goto FAILED;
- ptr = tempptr;
- if (ptr >= ptrend) c = CHAR_BACKSLASH; else
- {
- GETCHARINCTEST(c, ptr); /* Get character value, increment pointer */
- }
- escape = 0; /* Treat as literal character */
- }
-
- /* The escape was a data escape or literal character. */
-
- if (escape == 0)
- {
- PARSED_LITERAL(c, parsed_pattern);
- }
-
- /* The escape was a back (or forward) reference. We keep the offset in
- order to give a more useful diagnostic for a bad forward reference. For
- references to groups numbered less than 10 we can't use more than two items
- in parsed_pattern because they may be just two characters in the input (and
- in a 64-bit world an offset may need two elements). So for them, the offset
- of the first occurrent is held in a special vector. */
-
- else if (escape < 0)
- {
- offset = (PCRE2_SIZE)(ptr - cb->start_pattern - 1);
- escape = -escape;
- *parsed_pattern++ = META_BACKREF | (uint32_t)escape;
- if (escape < 10)
- {
- if (cb->small_ref_offset[escape] == PCRE2_UNSET)
- cb->small_ref_offset[escape] = offset;
- }
- else
- {
- PUTOFFSET(offset, parsed_pattern);
- }
- okquantifier = TRUE;
- }
-
- /* The escape was a character class such as \d etc. or other special
- escape indicator such as \A or \X. Most of them generate just a single
- parsed item, but \P and \p are followed by a 16-bit type and a 16-bit
- value. They are supported only when Unicode is available. The type and
- value are packed into a single 32-bit value so that the whole sequences
- uses only two elements in the parsed_vector. This is because the same
- coding is used if \d (for example) is turned into \p{Nd} when PCRE2_UCP is
- set.
-
- There are also some cases where the escape sequence is followed by a name:
- \k{name}, \k<name>, and \k'name' are backreferences by name, and \g<name>
- and \g'name' are subroutine calls by name; \g{name} is a synonym for
- \k{name}. Note that \g<number> and \g'number' are handled by check_escape()
- and returned as a negative value (handled above). A name is coded as an
- offset into the pattern and a length. */
-
- else switch (escape)
- {
- case ESC_C:
-#ifdef NEVER_BACKSLASH_C
- errorcode = ERR85;
- goto ESCAPE_FAILED;
-#else
- if ((options & PCRE2_NEVER_BACKSLASH_C) != 0)
- {
- errorcode = ERR83;
- goto ESCAPE_FAILED;
- }
-#endif
- okquantifier = TRUE;
- *parsed_pattern++ = META_ESCAPE + escape;
- break;
-
- case ESC_X:
-#ifndef SUPPORT_UNICODE
- errorcode = ERR45; /* Supported only with Unicode support */
- goto ESCAPE_FAILED;
-#endif
- case ESC_H:
- case ESC_h:
- case ESC_N:
- case ESC_R:
- case ESC_V:
- case ESC_v:
- okquantifier = TRUE;
- *parsed_pattern++ = META_ESCAPE + escape;
- break;
-
- default: /* \A, \B, \b, \G, \K, \Z, \z cannot be quantified. */
- *parsed_pattern++ = META_ESCAPE + escape;
- break;
-
- /* Escapes that change in UCP mode. Note that PCRE2_UCP will never be set
- without Unicode support because it is checked when pcre2_compile() is
- called. */
-
- case ESC_d:
- case ESC_D:
- case ESC_s:
- case ESC_S:
- case ESC_w:
- case ESC_W:
- okquantifier = TRUE;
- if ((options & PCRE2_UCP) == 0)
- {
- *parsed_pattern++ = META_ESCAPE + escape;
- }
- else
- {
- *parsed_pattern++ = META_ESCAPE +
- ((escape == ESC_d || escape == ESC_s || escape == ESC_w)?
- ESC_p : ESC_P);
- switch(escape)
- {
- case ESC_d:
- case ESC_D:
- *parsed_pattern++ = (PT_PC << 16) | ucp_Nd;
- break;
-
- case ESC_s:
- case ESC_S:
- *parsed_pattern++ = PT_SPACE << 16;
- break;
-
- case ESC_w:
- case ESC_W:
- *parsed_pattern++ = PT_WORD << 16;
- break;
- }
- }
- break;
-
- /* Unicode property matching */
-
- case ESC_P:
- case ESC_p:
-#ifdef SUPPORT_UNICODE
- {
- BOOL negated;
- uint16_t ptype = 0, pdata = 0;
- if (!get_ucp(&ptr, &negated, &ptype, &pdata, &errorcode, cb))
- goto ESCAPE_FAILED;
- if (negated) escape = (escape == ESC_P)? ESC_p : ESC_P;
- *parsed_pattern++ = META_ESCAPE + escape;
- *parsed_pattern++ = (ptype << 16) | pdata;
- okquantifier = TRUE;
- }
-#else
- errorcode = ERR45;
- goto ESCAPE_FAILED;
-#endif
- break; /* End \P and \p */
-
- /* When \g is used with quotes or angle brackets as delimiters, it is a
- numerical or named subroutine call, and control comes here. When used
- with brace delimiters it is a numberical back reference and does not come
- here because check_escape() returns it directly as a reference. \k is
- always a named back reference. */
-
- case ESC_g:
- case ESC_k:
- if (ptr >= ptrend || (*ptr != CHAR_LEFT_CURLY_BRACKET &&
- *ptr != CHAR_LESS_THAN_SIGN && *ptr != CHAR_APOSTROPHE))
- {
- errorcode = (escape == ESC_g)? ERR57 : ERR69;
- goto ESCAPE_FAILED;
- }
- terminator = (*ptr == CHAR_LESS_THAN_SIGN)?
- CHAR_GREATER_THAN_SIGN : (*ptr == CHAR_APOSTROPHE)?
- CHAR_APOSTROPHE : CHAR_RIGHT_CURLY_BRACKET;
-
- /* For a non-braced \g, check for a numerical recursion. */
-
- if (escape == ESC_g && terminator != CHAR_RIGHT_CURLY_BRACKET)
- {
- PCRE2_SPTR p = ptr + 1;
-
- if (read_number(&p, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, &i,
- &errorcode))
- {
- if (p >= ptrend || *p != terminator)
- {
- errorcode = ERR57;
- goto ESCAPE_FAILED;
- }
- ptr = p;
- goto SET_RECURSION;
- }
- if (errorcode != 0) goto ESCAPE_FAILED;
- }
-
- /* Not a numerical recursion */
-
- if (!read_name(&ptr, ptrend, utf, terminator, &offset, &name, &namelen,
- &errorcode, cb)) goto ESCAPE_FAILED;
-
- /* \k and \g when used with braces are back references, whereas \g used
- with quotes or angle brackets is a recursion */
-
- *parsed_pattern++ =
- (escape == ESC_k || terminator == CHAR_RIGHT_CURLY_BRACKET)?
- META_BACKREF_BYNAME : META_RECURSE_BYNAME;
- *parsed_pattern++ = namelen;
-
- PUTOFFSET(offset, parsed_pattern);
- okquantifier = TRUE;
- break; /* End special escape processing */
- }
- break; /* End escape sequence processing */
-
-
- /* ---- Single-character special items ---- */
-
- case CHAR_CIRCUMFLEX_ACCENT:
- *parsed_pattern++ = META_CIRCUMFLEX;
- break;
-
- case CHAR_DOLLAR_SIGN:
- *parsed_pattern++ = META_DOLLAR;
- break;
-
- case CHAR_DOT:
- *parsed_pattern++ = META_DOT;
- okquantifier = TRUE;
- break;
-
-
- /* ---- Single-character quantifiers ---- */
-
- case CHAR_ASTERISK:
- meta_quantifier = META_ASTERISK;
- goto CHECK_QUANTIFIER;
-
- case CHAR_PLUS:
- meta_quantifier = META_PLUS;
- goto CHECK_QUANTIFIER;
-
- case CHAR_QUESTION_MARK:
- meta_quantifier = META_QUERY;
- goto CHECK_QUANTIFIER;
-
-
- /* ---- Potential {n,m} quantifier ---- */
-
- case CHAR_LEFT_CURLY_BRACKET:
- if (!read_repeat_counts(&ptr, ptrend, &min_repeat, &max_repeat,
- &errorcode))
- {
- if (errorcode != 0) goto FAILED; /* Error in quantifier. */
- PARSED_LITERAL(c, parsed_pattern); /* Not a quantifier */
- break; /* No more quantifier processing */
- }
- meta_quantifier = META_MINMAX;
- /* Fall through */
-
-
- /* ---- Quantifier post-processing ---- */
-
- /* Check that a quantifier is allowed after the previous item. */
-
- CHECK_QUANTIFIER:
- if (!prev_okquantifier)
- {
- errorcode = ERR9;
- goto FAILED_BACK;
- }
-
- /* Most (*VERB)s are not allowed to be quantified, but an ungreedy
- quantifier can be useful for (*ACCEPT) - meaning "succeed on backtrack", a
- sort of negated (*COMMIT). We therefore allow (*ACCEPT) to be quantified by
- wrapping it in non-capturing brackets, but we have to allow for a preceding
- (*MARK) for when (*ACCEPT) has an argument. */
-
- if (parsed_pattern[-1] == META_ACCEPT)
- {
- uint32_t *p;
- for (p = parsed_pattern - 1; p >= verbstartptr; p--) p[1] = p[0];
- *verbstartptr = META_NOCAPTURE;
- parsed_pattern[1] = META_KET;
- parsed_pattern += 2;
- }
-
- /* Now we can put the quantifier into the parsed pattern vector. At this
- stage, we have only the basic quantifier. The check for a following + or ?
- modifier happens at the top of the loop, after any intervening comments
- have been removed. */
-
- *parsed_pattern++ = meta_quantifier;
- if (c == CHAR_LEFT_CURLY_BRACKET)
- {
- *parsed_pattern++ = min_repeat;
- *parsed_pattern++ = max_repeat;
- }
- break;
-
-
- /* ---- Character class ---- */
-
- case CHAR_LEFT_SQUARE_BRACKET:
- okquantifier = TRUE;
-
- /* In another (POSIX) regex library, the ugly syntax [[:<:]] and [[:>:]] is
- used for "start of word" and "end of word". As these are otherwise illegal
- sequences, we don't break anything by recognizing them. They are replaced
- by \b(?=\w) and \b(?<=\w) respectively. Sequences like [a[:<:]] are
- erroneous and are handled by the normal code below. */
-
- if (ptrend - ptr >= 6 &&
- (PRIV(strncmp_c8)(ptr, STRING_WEIRD_STARTWORD, 6) == 0 ||
- PRIV(strncmp_c8)(ptr, STRING_WEIRD_ENDWORD, 6) == 0))
- {
- *parsed_pattern++ = META_ESCAPE + ESC_b;
-
- if (ptr[2] == CHAR_LESS_THAN_SIGN)
- {
- *parsed_pattern++ = META_LOOKAHEAD;
- }
- else
- {
- *parsed_pattern++ = META_LOOKBEHIND;
- *has_lookbehind = TRUE;
-
- /* The offset is used only for the "non-fixed length" error; this won't
- occur here, so just store zero. */
-
- PUTOFFSET((PCRE2_SIZE)0, parsed_pattern);
- }
-
- if ((options & PCRE2_UCP) == 0)
- *parsed_pattern++ = META_ESCAPE + ESC_w;
- else
- {
- *parsed_pattern++ = META_ESCAPE + ESC_p;
- *parsed_pattern++ = PT_WORD << 16;
- }
- *parsed_pattern++ = META_KET;
- ptr += 6;
- break;
- }
-
- /* PCRE supports POSIX class stuff inside a class. Perl gives an error if
- they are encountered at the top level, so we'll do that too. */
-
- if (ptr < ptrend && (*ptr == CHAR_COLON || *ptr == CHAR_DOT ||
- *ptr == CHAR_EQUALS_SIGN) &&
- check_posix_syntax(ptr, ptrend, &tempptr))
- {
- errorcode = (*ptr-- == CHAR_COLON)? ERR12 : ERR13;
- goto FAILED;
- }
-
- /* Process a regular character class. If the first character is '^', set
- the negation flag. If the first few characters (either before or after ^)
- are \Q\E or \E or space or tab in extended-more mode, we skip them too.
- This makes for compatibility with Perl. */
-
- negate_class = FALSE;
- while (ptr < ptrend)
- {
- GETCHARINCTEST(c, ptr);
- if (c == CHAR_BACKSLASH)
- {
- if (ptr < ptrend && *ptr == CHAR_E) ptr++;
- else if (ptrend - ptr >= 3 &&
- PRIV(strncmp_c8)(ptr, STR_Q STR_BACKSLASH STR_E, 3) == 0)
- ptr += 3;
- else
- break;
- }
- else if ((options & PCRE2_EXTENDED_MORE) != 0 &&
- (c == CHAR_SPACE || c == CHAR_HT)) /* Note: just these two */
- continue;
- else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT)
- negate_class = TRUE;
- else break;
- }
-
- /* Now the real contents of the class; c has the first "real" character.
- Empty classes are permitted only if the option is set. */
-
- if (c == CHAR_RIGHT_SQUARE_BRACKET &&
- (cb->external_options & PCRE2_ALLOW_EMPTY_CLASS) != 0)
- {
- *parsed_pattern++ = negate_class? META_CLASS_EMPTY_NOT : META_CLASS_EMPTY;
- break; /* End of class processing */
- }
-
- /* Process a non-empty class. */
-
- *parsed_pattern++ = negate_class? META_CLASS_NOT : META_CLASS;
- class_range_state = RANGE_NO;
-
- /* In an EBCDIC environment, Perl treats alphabetic ranges specially
- because there are holes in the encoding, and simply using the range A-Z
- (for example) would include the characters in the holes. This applies only
- to ranges where both values are literal; [\xC1-\xE9] is different to [A-Z]
- in this respect. In order to accommodate this, we keep track of whether
- character values are literal or not, and a state variable for handling
- ranges. */
-
- /* Loop for the contents of the class */
-
- for (;;)
- {
- BOOL char_is_literal = TRUE;
-
- /* Inside \Q...\E everything is literal except \E */
-
- if (inescq)
- {
- if (c == CHAR_BACKSLASH && ptr < ptrend && *ptr == CHAR_E)
- {
- inescq = FALSE; /* Reset literal state */
- ptr++; /* Skip the 'E' */
- goto CLASS_CONTINUE;
- }
- goto CLASS_LITERAL;
- }
-
- /* Skip over space and tab (only) in extended-more mode. */
-
- if ((options & PCRE2_EXTENDED_MORE) != 0 &&
- (c == CHAR_SPACE || c == CHAR_HT))
- goto CLASS_CONTINUE;
-
- /* Handle POSIX class names. Perl allows a negation extension of the
- form [:^name:]. A square bracket that doesn't match the syntax is
- treated as a literal. We also recognize the POSIX constructions
- [.ch.] and [=ch=] ("collating elements") and fault them, as Perl
- 5.6 and 5.8 do. */
-
- if (c == CHAR_LEFT_SQUARE_BRACKET &&
- ptrend - ptr >= 3 &&
- (*ptr == CHAR_COLON || *ptr == CHAR_DOT ||
- *ptr == CHAR_EQUALS_SIGN) &&
- check_posix_syntax(ptr, ptrend, &tempptr))
- {
- BOOL posix_negate = FALSE;
- int posix_class;
-
- /* Perl treats a hyphen before a POSIX class as a literal, not the
- start of a range. However, it gives a warning in its warning mode. PCRE
- does not have a warning mode, so we give an error, because this is
- likely an error on the user's part. */
-
- if (class_range_state == RANGE_STARTED)
- {
- errorcode = ERR50;
- goto FAILED;
- }
-
- if (*ptr != CHAR_COLON)
- {
- errorcode = ERR13;
- goto FAILED_BACK;
- }
-
- if (*(++ptr) == CHAR_CIRCUMFLEX_ACCENT)
- {
- posix_negate = TRUE;
- ptr++;
- }
-
- posix_class = check_posix_name(ptr, (int)(tempptr - ptr));
- if (posix_class < 0)
- {
- errorcode = ERR30;
- goto FAILED;
- }
- ptr = tempptr + 2;
-
- /* Perl treats a hyphen after a POSIX class as a literal, not the
- start of a range. However, it gives a warning in its warning mode
- unless the hyphen is the last character in the class. PCRE does not
- have a warning mode, so we give an error, because this is likely an
- error on the user's part. */
-
- if (ptr < ptrend - 1 && *ptr == CHAR_MINUS &&
- ptr[1] != CHAR_RIGHT_SQUARE_BRACKET)
- {
- errorcode = ERR50;
- goto FAILED;
- }
-
- /* Set "a hyphen is not the start of a range" for the -] case, and also
- in case the POSIX class is followed by \E or \Q\E (possibly repeated -
- fuzzers do that kind of thing) and *then* a hyphen. This causes that
- hyphen to be treated as a literal. I don't think it's worth setting up
- special apparatus to do otherwise. */
-
- class_range_state = RANGE_NO;
-
- /* When PCRE2_UCP is set, some of the POSIX classes are converted to
- use Unicode properties \p or \P or, in one case, \h or \H. The
- substitutes table has two values per class, containing the type and
- value of a \p or \P item. The special cases are specified with a
- negative type: a non-zero value causes \h or \H to be used, and a zero
- value falls through to behave like a non-UCP POSIX class. */
-
-#ifdef SUPPORT_UNICODE
- if ((options & PCRE2_UCP) != 0)
- {
- int ptype = posix_substitutes[2*posix_class];
- int pvalue = posix_substitutes[2*posix_class + 1];
- if (ptype >= 0)
- {
- *parsed_pattern++ = META_ESCAPE + (posix_negate? ESC_P : ESC_p);
- *parsed_pattern++ = (ptype << 16) | pvalue;
- goto CLASS_CONTINUE;
- }
-
- if (pvalue != 0)
- {
- *parsed_pattern++ = META_ESCAPE + (posix_negate? ESC_H : ESC_h);
- goto CLASS_CONTINUE;
- }
-
- /* Fall through */
- }
-#endif /* SUPPORT_UNICODE */
-
- /* Non-UCP POSIX class */
-
- *parsed_pattern++ = posix_negate? META_POSIX_NEG : META_POSIX;
- *parsed_pattern++ = posix_class;
- }
-
- /* Handle potential start of range */
-
- else if (c == CHAR_MINUS && class_range_state >= RANGE_OK_ESCAPED)
- {
- *parsed_pattern++ = (class_range_state == RANGE_OK_LITERAL)?
- META_RANGE_LITERAL : META_RANGE_ESCAPED;
- class_range_state = RANGE_STARTED;
- }
-
- /* Handle a literal character */
-
- else if (c != CHAR_BACKSLASH)
- {
- CLASS_LITERAL:
- if (class_range_state == RANGE_STARTED)
- {
- if (c == parsed_pattern[-2]) /* Optimize one-char range */
- parsed_pattern--;
- else if (parsed_pattern[-2] > c) /* Check range is in order */
- {
- errorcode = ERR8;
- goto FAILED_BACK;
- }
- else
- {
- if (!char_is_literal && parsed_pattern[-1] == META_RANGE_LITERAL)
- parsed_pattern[-1] = META_RANGE_ESCAPED;
- PARSED_LITERAL(c, parsed_pattern);
- }
- class_range_state = RANGE_NO;
- }
- else /* Potential start of range */
- {
- class_range_state = char_is_literal?
- RANGE_OK_LITERAL : RANGE_OK_ESCAPED;
- PARSED_LITERAL(c, parsed_pattern);
- }
- }
-
- /* Handle escapes in a class */
-
- else
- {
- tempptr = ptr;
- escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options,
- cb->cx->extra_options, TRUE, cb);
-
- if (errorcode != 0)
- {
- if ((extra_options & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) == 0)
- goto FAILED;
- ptr = tempptr;
- if (ptr >= ptrend) c = CHAR_BACKSLASH; else
- {
- GETCHARINCTEST(c, ptr); /* Get character value, increment pointer */
- }
- escape = 0; /* Treat as literal character */
- }
-
- switch(escape)
- {
- case 0: /* Escaped character code point is in c */
- char_is_literal = FALSE;
- goto CLASS_LITERAL;
-
- case ESC_b:
- c = CHAR_BS; /* \b is backspace in a class */
- char_is_literal = FALSE;
- goto CLASS_LITERAL;
-
- case ESC_Q:
- inescq = TRUE; /* Enter literal mode */
- goto CLASS_CONTINUE;
-
- case ESC_E: /* Ignore orphan \E */
- goto CLASS_CONTINUE;
-
- case ESC_B: /* Always an error in a class */
- case ESC_R:
- case ESC_X:
- errorcode = ERR7;
- ptr--;
- goto FAILED;
- }
-
- /* The second part of a range can be a single-character escape
- sequence (detected above), but not any of the other escapes. Perl
- treats a hyphen as a literal in such circumstances. However, in Perl's
- warning mode, a warning is given, so PCRE now faults it, as it is
- almost certainly a mistake on the user's part. */
-
- if (class_range_state == RANGE_STARTED)
- {
- errorcode = ERR50;
- goto FAILED; /* Not CLASS_ESCAPE_FAILED; always an error */
- }
-
- /* Of the remaining escapes, only those that define characters are
- allowed in a class. None may start a range. */
-
- class_range_state = RANGE_NO;
- switch(escape)
- {
- case ESC_N:
- errorcode = ERR71;
- goto FAILED;
-
- case ESC_H:
- case ESC_h:
- case ESC_V:
- case ESC_v:
- *parsed_pattern++ = META_ESCAPE + escape;
- break;
-
- /* These escapes are converted to Unicode property tests when
- PCRE2_UCP is set. */
-
- case ESC_d:
- case ESC_D:
- case ESC_s:
- case ESC_S:
- case ESC_w:
- case ESC_W:
- if ((options & PCRE2_UCP) == 0)
- {
- *parsed_pattern++ = META_ESCAPE + escape;
- }
- else
- {
- *parsed_pattern++ = META_ESCAPE +
- ((escape == ESC_d || escape == ESC_s || escape == ESC_w)?
- ESC_p : ESC_P);
- switch(escape)
- {
- case ESC_d:
- case ESC_D:
- *parsed_pattern++ = (PT_PC << 16) | ucp_Nd;
- break;
-
- case ESC_s:
- case ESC_S:
- *parsed_pattern++ = PT_SPACE << 16;
- break;
-
- case ESC_w:
- case ESC_W:
- *parsed_pattern++ = PT_WORD << 16;
- break;
- }
- }
- break;
-
- /* Explicit Unicode property matching */
-
- case ESC_P:
- case ESC_p:
-#ifdef SUPPORT_UNICODE
- {
- BOOL negated;
- uint16_t ptype = 0, pdata = 0;
- if (!get_ucp(&ptr, &negated, &ptype, &pdata, &errorcode, cb))
- goto FAILED;
- if (negated) escape = (escape == ESC_P)? ESC_p : ESC_P;
- *parsed_pattern++ = META_ESCAPE + escape;
- *parsed_pattern++ = (ptype << 16) | pdata;
- }
-#else
- errorcode = ERR45;
- goto FAILED;
-#endif
- break; /* End \P and \p */
-
- default: /* All others are not allowed in a class */
- errorcode = ERR7;
- ptr--;
- goto FAILED;
- }
-
- /* Perl gives a warning unless a following hyphen is the last character
- in the class. PCRE throws an error. */
-
- if (ptr < ptrend - 1 && *ptr == CHAR_MINUS &&
- ptr[1] != CHAR_RIGHT_SQUARE_BRACKET)
- {
- errorcode = ERR50;
- goto FAILED;
- }
- }
-
- /* Proceed to next thing in the class. */
-
- CLASS_CONTINUE:
- if (ptr >= ptrend)
- {
- errorcode = ERR6; /* Missing terminating ']' */
- goto FAILED;
- }
- GETCHARINCTEST(c, ptr);
- if (c == CHAR_RIGHT_SQUARE_BRACKET && !inescq) break;
- } /* End of class-processing loop */
-
- /* -] at the end of a class is a literal '-' */
-
- if (class_range_state == RANGE_STARTED)
- {
- parsed_pattern[-1] = CHAR_MINUS;
- class_range_state = RANGE_NO;
- }
-
- *parsed_pattern++ = META_CLASS_END;
- break; /* End of character class */
-
-
- /* ---- Opening parenthesis ---- */
-
- case CHAR_LEFT_PARENTHESIS:
- if (ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
-
- /* If ( is not followed by ? it is either a capture or a special verb or an
- alpha assertion or a positive non-atomic lookahead. */
-
- if (*ptr != CHAR_QUESTION_MARK)
- {
- const char *vn;
-
- /* Handle capturing brackets (or non-capturing if auto-capture is turned
- off). */
-
- if (*ptr != CHAR_ASTERISK)
- {
- nest_depth++;
- if ((options & PCRE2_NO_AUTO_CAPTURE) == 0)
- {
- if (cb->bracount >= MAX_GROUP_NUMBER)
- {
- errorcode = ERR97;
- goto FAILED;
- }
- cb->bracount++;
- *parsed_pattern++ = META_CAPTURE | cb->bracount;
- }
- else *parsed_pattern++ = META_NOCAPTURE;
- }
-
- /* Do nothing for (* followed by end of pattern or ) so it gives a "bad
- quantifier" error rather than "(*MARK) must have an argument". */
-
- else if (ptrend - ptr <= 1 || (c = ptr[1]) == CHAR_RIGHT_PARENTHESIS)
- break;
-
- /* Handle "alpha assertions" such as (*pla:...). Most of these are
- synonyms for the historical symbolic assertions, but the script run and
- non-atomic lookaround ones are new. They are distinguished by starting
- with a lower case letter. Checking both ends of the alphabet makes this
- work in all character codes. */
-
- else if (CHMAX_255(c) && (cb->ctypes[c] & ctype_lcletter) != 0)
- {
- uint32_t meta;
-
- vn = alasnames;
- if (!read_name(&ptr, ptrend, utf, 0, &offset, &name, &namelen,
- &errorcode, cb)) goto FAILED;
- if (ptr >= ptrend || *ptr != CHAR_COLON)
- {
- errorcode = ERR95; /* Malformed */
- goto FAILED;
- }
-
- /* Scan the table of alpha assertion names */
-
- for (i = 0; i < alascount; i++)
- {
- if (namelen == alasmeta[i].len &&
- PRIV(strncmp_c8)(name, vn, namelen) == 0)
- break;
- vn += alasmeta[i].len + 1;
- }
-
- if (i >= alascount)
- {
- errorcode = ERR95; /* Alpha assertion not recognized */
- goto FAILED;
- }
-
- /* Check for expecting an assertion condition. If so, only atomic
- lookaround assertions are valid. */
-
- meta = alasmeta[i].meta;
- if (prev_expect_cond_assert > 0 &&
- (meta < META_LOOKAHEAD || meta > META_LOOKBEHINDNOT))
- {
- errorcode = (meta == META_LOOKAHEAD_NA || meta == META_LOOKBEHIND_NA)?
- ERR98 : ERR28; /* (Atomic) assertion expected */
- goto FAILED;
- }
-
- /* The lookaround alphabetic synonyms can mostly be handled by jumping
- to the code that handles the traditional symbolic forms. */
-
- switch(meta)
- {
- default:
- errorcode = ERR89; /* Unknown code; should never occur because */
- goto FAILED; /* the meta values come from a table above. */
-
- case META_ATOMIC:
- goto ATOMIC_GROUP;
-
- case META_LOOKAHEAD:
- goto POSITIVE_LOOK_AHEAD;
-
- case META_LOOKAHEAD_NA:
- goto POSITIVE_NONATOMIC_LOOK_AHEAD;
-
- case META_LOOKAHEADNOT:
- goto NEGATIVE_LOOK_AHEAD;
-
- case META_LOOKBEHIND:
- case META_LOOKBEHINDNOT:
- case META_LOOKBEHIND_NA:
- *parsed_pattern++ = meta;
- ptr--;
- goto POST_LOOKBEHIND;
-
- /* The script run facilities are handled here. Unicode support is
- required (give an error if not, as this is a security issue). Always
- record a META_SCRIPT_RUN item. Then, for the atomic version, insert
- META_ATOMIC and remember that we need two META_KETs at the end. */
-
- case META_SCRIPT_RUN:
- case META_ATOMIC_SCRIPT_RUN:
-#ifdef SUPPORT_UNICODE
- *parsed_pattern++ = META_SCRIPT_RUN;
- nest_depth++;
- ptr++;
- if (meta == META_ATOMIC_SCRIPT_RUN)
- {
- *parsed_pattern++ = META_ATOMIC;
- if (top_nest == NULL) top_nest = (nest_save *)(cb->start_workspace);
- else if (++top_nest >= end_nests)
- {
- errorcode = ERR84;
- goto FAILED;
- }
- top_nest->nest_depth = nest_depth;
- top_nest->flags = NSF_ATOMICSR;
- top_nest->options = options & PARSE_TRACKED_OPTIONS;
- }
- break;
-#else /* SUPPORT_UNICODE */
- errorcode = ERR96;
- goto FAILED;
-#endif
- }
- }
-
-
- /* ---- Handle (*VERB) and (*VERB:NAME) ---- */
-
- else
- {
- vn = verbnames;
- if (!read_name(&ptr, ptrend, utf, 0, &offset, &name, &namelen,
- &errorcode, cb)) goto FAILED;
- if (ptr >= ptrend || (*ptr != CHAR_COLON &&
- *ptr != CHAR_RIGHT_PARENTHESIS))
- {
- errorcode = ERR60; /* Malformed */
- goto FAILED;
- }
-
- /* Scan the table of verb names */
-
- for (i = 0; i < verbcount; i++)
- {
- if (namelen == verbs[i].len &&
- PRIV(strncmp_c8)(name, vn, namelen) == 0)
- break;
- vn += verbs[i].len + 1;
- }
-
- if (i >= verbcount)
- {
- errorcode = ERR60; /* Verb not recognized */
- goto FAILED;
- }
-
- /* An empty argument is treated as no argument. */
-
- if (*ptr == CHAR_COLON && ptr + 1 < ptrend &&
- ptr[1] == CHAR_RIGHT_PARENTHESIS)
- ptr++; /* Advance to the closing parens */
-
- /* Check for mandatory non-empty argument; this is (*MARK) */
-
- if (verbs[i].has_arg > 0 && *ptr != CHAR_COLON)
- {
- errorcode = ERR66;
- goto FAILED;
- }
-
- /* Remember where this verb, possibly with a preceding (*MARK), starts,
- for handling quantified (*ACCEPT). */
-
- verbstartptr = parsed_pattern;
- okquantifier = (verbs[i].meta == META_ACCEPT);
-
- /* It appears that Perl allows any characters whatsoever, other than a
- closing parenthesis, to appear in arguments ("names"), so we no longer
- insist on letters, digits, and underscores. Perl does not, however, do
- any interpretation within arguments, and has no means of including a
- closing parenthesis. PCRE supports escape processing but only when it
- is requested by an option. We set inverbname TRUE here, and let the
- main loop take care of this so that escape and \x processing is done by
- the main code above. */
-
- if (*ptr++ == CHAR_COLON) /* Skip past : or ) */
- {
- /* Some optional arguments can be treated as a preceding (*MARK) */
-
- if (verbs[i].has_arg < 0)
- {
- add_after_mark = verbs[i].meta;
- *parsed_pattern++ = META_MARK;
- }
-
- /* The remaining verbs with arguments (except *MARK) need a different
- opcode. */
-
- else
- {
- *parsed_pattern++ = verbs[i].meta +
- ((verbs[i].meta != META_MARK)? 0x00010000u:0);
- }
-
- /* Set up for reading the name in the main loop. */
-
- verblengthptr = parsed_pattern++;
- verbnamestart = ptr;
- inverbname = TRUE;
- }
- else /* No verb "name" argument */
- {
- *parsed_pattern++ = verbs[i].meta;
- }
- } /* End of (*VERB) handling */
- break; /* Done with this parenthesis */
- } /* End of groups that don't start with (? */
-
-
- /* ---- Items starting (? ---- */
-
- /* The type of item is determined by what follows (?. Handle (?| and option
- changes under "default" because both need a new block on the nest stack.
- Comments starting with (?# are handled above. Note that there is some
- ambiguity about the sequence (?- because if a digit follows it's a relative
- recursion or subroutine call whereas otherwise it's an option unsetting. */
-
- if (++ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
-
- switch(*ptr)
- {
- default:
- if (*ptr == CHAR_MINUS && ptrend - ptr > 1 && IS_DIGIT(ptr[1]))
- goto RECURSION_BYNUMBER; /* The + case is handled by CHAR_PLUS */
-
- /* We now have either (?| or a (possibly empty) option setting,
- optionally followed by a non-capturing group. */
-
- nest_depth++;
- if (top_nest == NULL) top_nest = (nest_save *)(cb->start_workspace);
- else if (++top_nest >= end_nests)
- {
- errorcode = ERR84;
- goto FAILED;
- }
- top_nest->nest_depth = nest_depth;
- top_nest->flags = 0;
- top_nest->options = options & PARSE_TRACKED_OPTIONS;
-
- /* Start of non-capturing group that resets the capture count for each
- branch. */
-
- if (*ptr == CHAR_VERTICAL_LINE)
- {
- top_nest->reset_group = (uint16_t)cb->bracount;
- top_nest->max_group = (uint16_t)cb->bracount;
- top_nest->flags |= NSF_RESET;
- cb->external_flags |= PCRE2_DUPCAPUSED;
- *parsed_pattern++ = META_NOCAPTURE;
- ptr++;
- }
-
- /* Scan for options imnsxJU to be set or unset. */
-
- else
- {
- BOOL hyphenok = TRUE;
- uint32_t oldoptions = options;
-
- top_nest->reset_group = 0;
- top_nest->max_group = 0;
- set = unset = 0;
- optset = &set;
-
- /* ^ at the start unsets imnsx and disables the subsequent use of - */
-
- if (ptr < ptrend && *ptr == CHAR_CIRCUMFLEX_ACCENT)
- {
- options &= ~(PCRE2_CASELESS|PCRE2_MULTILINE|PCRE2_NO_AUTO_CAPTURE|
- PCRE2_DOTALL|PCRE2_EXTENDED|PCRE2_EXTENDED_MORE);
- hyphenok = FALSE;
- ptr++;
- }
-
- while (ptr < ptrend && *ptr != CHAR_RIGHT_PARENTHESIS &&
- *ptr != CHAR_COLON)
- {
- switch (*ptr++)
- {
- case CHAR_MINUS:
- if (!hyphenok)
- {
- errorcode = ERR94;
- ptr--; /* Correct the offset */
- goto FAILED;
- }
- optset = &unset;
- hyphenok = FALSE;
- break;
-
- case CHAR_J: /* Record that it changed in the external options */
- *optset |= PCRE2_DUPNAMES;
- cb->external_flags |= PCRE2_JCHANGED;
- break;
-
- case CHAR_i: *optset |= PCRE2_CASELESS; break;
- case CHAR_m: *optset |= PCRE2_MULTILINE; break;
- case CHAR_n: *optset |= PCRE2_NO_AUTO_CAPTURE; break;
- case CHAR_s: *optset |= PCRE2_DOTALL; break;
- case CHAR_U: *optset |= PCRE2_UNGREEDY; break;
-
- /* If x appears twice it sets the extended extended option. */
-
- case CHAR_x:
- *optset |= PCRE2_EXTENDED;
- if (ptr < ptrend && *ptr == CHAR_x)
- {
- *optset |= PCRE2_EXTENDED_MORE;
- ptr++;
- }
- break;
-
- default:
- errorcode = ERR11;
- ptr--; /* Correct the offset */
- goto FAILED;
- }
- }
-
- /* If we are setting extended without extended-more, ensure that any
- existing extended-more gets unset. Also, unsetting extended must also
- unset extended-more. */
-
- if ((set & (PCRE2_EXTENDED|PCRE2_EXTENDED_MORE)) == PCRE2_EXTENDED ||
- (unset & PCRE2_EXTENDED) != 0)
- unset |= PCRE2_EXTENDED_MORE;
-
- options = (options | set) & (~unset);
-
- /* If the options ended with ')' this is not the start of a nested
- group with option changes, so the options change at this level.
- In this case, if the previous level set up a nest block, discard the
- one we have just created. Otherwise adjust it for the previous level.
- If the options ended with ':' we are starting a non-capturing group,
- possibly with an options setting. */
-
- if (ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
- if (*ptr++ == CHAR_RIGHT_PARENTHESIS)
- {
- nest_depth--; /* This is not a nested group after all. */
- if (top_nest > (nest_save *)(cb->start_workspace) &&
- (top_nest-1)->nest_depth == nest_depth) top_nest--;
- else top_nest->nest_depth = nest_depth;
- }
- else *parsed_pattern++ = META_NOCAPTURE;
-
- /* If nothing changed, no need to record. */
-
- if (options != oldoptions)
- {
- *parsed_pattern++ = META_OPTIONS;
- *parsed_pattern++ = options;
- }
- } /* End options processing */
- break; /* End default case after (? */
-
-
- /* ---- Python syntax support ---- */
-
- case CHAR_P:
- if (++ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
-
- /* (?P<name> is the same as (?<name>, which defines a named group. */
-
- if (*ptr == CHAR_LESS_THAN_SIGN)
- {
- terminator = CHAR_GREATER_THAN_SIGN;
- goto DEFINE_NAME;
- }
-
- /* (?P>name) is the same as (?&name), which is a recursion or subroutine
- call. */
-
- if (*ptr == CHAR_GREATER_THAN_SIGN) goto RECURSE_BY_NAME;
-
- /* (?P=name) is the same as \k<name>, a back reference by name. Anything
- else after (?P is an error. */
-
- if (*ptr != CHAR_EQUALS_SIGN)
- {
- errorcode = ERR41;
- goto FAILED;
- }
- if (!read_name(&ptr, ptrend, utf, CHAR_RIGHT_PARENTHESIS, &offset, &name,
- &namelen, &errorcode, cb)) goto FAILED;
- *parsed_pattern++ = META_BACKREF_BYNAME;
- *parsed_pattern++ = namelen;
- PUTOFFSET(offset, parsed_pattern);
- okquantifier = TRUE;
- break; /* End of (?P processing */
-
-
- /* ---- Recursion/subroutine calls by number ---- */
-
- case CHAR_R:
- i = 0; /* (?R) == (?R0) */
- ptr++;
- if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
- {
- errorcode = ERR58;
- goto FAILED;
- }
- goto SET_RECURSION;
-
- /* An item starting (?- followed by a digit comes here via the "default"
- case because (?- followed by a non-digit is an options setting. */
-
- case CHAR_PLUS:
- if (ptrend - ptr < 2 || !IS_DIGIT(ptr[1]))
- {
- errorcode = ERR29; /* Missing number */
- goto FAILED;
- }
- /* Fall through */
-
- case CHAR_0: case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4:
- case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9:
- RECURSION_BYNUMBER:
- if (!read_number(&ptr, ptrend,
- (IS_DIGIT(*ptr))? -1:(int)(cb->bracount), /* + and - are relative */
- MAX_GROUP_NUMBER, ERR61,
- &i, &errorcode)) goto FAILED;
- if (i < 0) /* NB (?0) is permitted */
- {
- errorcode = ERR15; /* Unknown group */
- goto FAILED_BACK;
- }
- if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
- goto UNCLOSED_PARENTHESIS;
-
- SET_RECURSION:
- *parsed_pattern++ = META_RECURSE | (uint32_t)i;
- offset = (PCRE2_SIZE)(ptr - cb->start_pattern);
- ptr++;
- PUTOFFSET(offset, parsed_pattern);
- okquantifier = TRUE;
- break; /* End of recursive call by number handling */
-
-
- /* ---- Recursion/subroutine calls by name ---- */
-
- case CHAR_AMPERSAND:
- RECURSE_BY_NAME:
- if (!read_name(&ptr, ptrend, utf, CHAR_RIGHT_PARENTHESIS, &offset, &name,
- &namelen, &errorcode, cb)) goto FAILED;
- *parsed_pattern++ = META_RECURSE_BYNAME;
- *parsed_pattern++ = namelen;
- PUTOFFSET(offset, parsed_pattern);
- okquantifier = TRUE;
- break;
-
- /* ---- Callout with numerical or string argument ---- */
-
- case CHAR_C:
- if (++ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
-
- /* If the previous item was a condition starting (?(? an assertion,
- optionally preceded by a callout, is expected. This is checked later on,
- during actual compilation. However we need to identify this kind of
- assertion in this pass because it must not be qualified. The value of
- expect_cond_assert is set to 2 after (?(? is processed. We decrement it
- for a callout - still leaving a positive value that identifies the
- assertion. Multiple callouts or any other items will make it zero or
- less, which doesn't matter because they will cause an error later. */
-
- expect_cond_assert = prev_expect_cond_assert - 1;
-
- /* If previous_callout is not NULL, it means this follows a previous
- callout. If it was a manual callout, do nothing; this means its "length
- of next pattern item" field will remain zero. If it was an automatic
- callout, abolish it. */
-
- if (previous_callout != NULL && (options & PCRE2_AUTO_CALLOUT) != 0 &&
- previous_callout == parsed_pattern - 4 &&
- parsed_pattern[-1] == 255)
- parsed_pattern = previous_callout;
-
- /* Save for updating next pattern item length, and skip one item before
- completing. */
-
- previous_callout = parsed_pattern;
- after_manual_callout = 1;
-
- /* Handle a string argument; specific delimiter is required. */
-
- if (*ptr != CHAR_RIGHT_PARENTHESIS && !IS_DIGIT(*ptr))
- {
- PCRE2_SIZE calloutlength;
- PCRE2_SPTR startptr = ptr;
-
- delimiter = 0;
- for (i = 0; PRIV(callout_start_delims)[i] != 0; i++)
- {
- if (*ptr == PRIV(callout_start_delims)[i])
- {
- delimiter = PRIV(callout_end_delims)[i];
- break;
- }
- }
- if (delimiter == 0)
- {
- errorcode = ERR82;
- goto FAILED;
- }
-
- *parsed_pattern = META_CALLOUT_STRING;
- parsed_pattern += 3; /* Skip pattern info */
-
- for (;;)
- {
- if (++ptr >= ptrend)
- {
- errorcode = ERR81;
- ptr = startptr; /* To give a more useful message */
- goto FAILED;
- }
- if (*ptr == delimiter && (++ptr >= ptrend || *ptr != delimiter))
- break;
- }
-
- calloutlength = (PCRE2_SIZE)(ptr - startptr);
- if (calloutlength > UINT32_MAX)
- {
- errorcode = ERR72;
- goto FAILED;
- }
- *parsed_pattern++ = (uint32_t)calloutlength;
- offset = (PCRE2_SIZE)(startptr - cb->start_pattern);
- PUTOFFSET(offset, parsed_pattern);
- }
-
- /* Handle a callout with an optional numerical argument, which must be
- less than or equal to 255. A missing argument gives 0. */
-
- else
- {
- int n = 0;
- *parsed_pattern = META_CALLOUT_NUMBER; /* Numerical callout */
- parsed_pattern += 3; /* Skip pattern info */
- while (ptr < ptrend && IS_DIGIT(*ptr))
- {
- n = n * 10 + *ptr++ - CHAR_0;
- if (n > 255)
- {
- errorcode = ERR38;
- goto FAILED;
- }
- }
- *parsed_pattern++ = n;
- }
-
- /* Both formats must have a closing parenthesis */
-
- if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
- {
- errorcode = ERR39;
- goto FAILED;
- }
- ptr++;
-
- /* Remember the offset to the next item in the pattern, and set a default
- length. This should get updated after the next item is read. */
-
- previous_callout[1] = (uint32_t)(ptr - cb->start_pattern);
- previous_callout[2] = 0;
- break; /* End callout */
-
-
- /* ---- Conditional group ---- */
-
- /* A condition can be an assertion, a number (referring to a numbered
- group's having been set), a name (referring to a named group), or 'R',
- referring to overall recursion. R<digits> and R&name are also permitted
- for recursion state tests. Numbers may be preceded by + or - to specify a
- relative group number.
-
- There are several syntaxes for testing a named group: (?(name)) is used
- by Python; Perl 5.10 onwards uses (?(<name>) or (?('name')).
-
- There are two unfortunate ambiguities. 'R' can be the recursive thing or
- the name 'R' (and similarly for 'R' followed by digits). 'DEFINE' can be
- the Perl DEFINE feature or the Python named test. We look for a name
- first; if not found, we try the other case.
-
- For compatibility with auto-callouts, we allow a callout to be specified
- before a condition that is an assertion. */
-
- case CHAR_LEFT_PARENTHESIS:
- if (++ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
- nest_depth++;
-
- /* If the next character is ? or * there must be an assertion next
- (optionally preceded by a callout). We do not check this here, but
- instead we set expect_cond_assert to 2. If this is still greater than
- zero (callouts decrement it) when the next assertion is read, it will be
- marked as a condition that must not be repeated. A value greater than
- zero also causes checking that an assertion (possibly with callout)
- follows. */
-
- if (*ptr == CHAR_QUESTION_MARK || *ptr == CHAR_ASTERISK)
- {
- *parsed_pattern++ = META_COND_ASSERT;
- ptr--; /* Pull pointer back to the opening parenthesis. */
- expect_cond_assert = 2;
- break; /* End of conditional */
- }
-
- /* Handle (?([+-]number)... */
-
- if (read_number(&ptr, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, &i,
- &errorcode))
- {
- if (i <= 0)
- {
- errorcode = ERR15;
- goto FAILED;
- }
- *parsed_pattern++ = META_COND_NUMBER;
- offset = (PCRE2_SIZE)(ptr - cb->start_pattern - 2);
- PUTOFFSET(offset, parsed_pattern);
- *parsed_pattern++ = i;
- }
- else if (errorcode != 0) goto FAILED; /* Number too big */
-
- /* No number found. Handle the special case (?(VERSION[>]=n.m)... */
-
- else if (ptrend - ptr >= 10 &&
- PRIV(strncmp_c8)(ptr, STRING_VERSION, 7) == 0 &&
- ptr[7] != CHAR_RIGHT_PARENTHESIS)
- {
- uint32_t ge = 0;
- int major = 0;
- int minor = 0;
-
- ptr += 7;
- if (*ptr == CHAR_GREATER_THAN_SIGN)
- {
- ge = 1;
- ptr++;
- }
-
- /* NOTE: cannot write IS_DIGIT(*(++ptr)) here because IS_DIGIT
- references its argument twice. */
-
- if (*ptr != CHAR_EQUALS_SIGN || (ptr++, !IS_DIGIT(*ptr)))
- goto BAD_VERSION_CONDITION;
-
- if (!read_number(&ptr, ptrend, -1, 1000, ERR79, &major, &errorcode))
- goto FAILED;
-
- if (ptr >= ptrend) goto BAD_VERSION_CONDITION;
- if (*ptr == CHAR_DOT)
- {
- if (++ptr >= ptrend || !IS_DIGIT(*ptr)) goto BAD_VERSION_CONDITION;
- minor = (*ptr++ - CHAR_0) * 10;
- if (ptr >= ptrend) goto BAD_VERSION_CONDITION;
- if (IS_DIGIT(*ptr)) minor += *ptr++ - CHAR_0;
- if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
- goto BAD_VERSION_CONDITION;
- }
-
- *parsed_pattern++ = META_COND_VERSION;
- *parsed_pattern++ = ge;
- *parsed_pattern++ = major;
- *parsed_pattern++ = minor;
- }
-
- /* All the remaining cases now require us to read a name. We cannot at
- this stage distinguish ambiguous cases such as (?(R12) which might be a
- recursion test by number or a name, because the named groups have not yet
- all been identified. Those cases are treated as names, but given a
- different META code. */
-
- else
- {
- BOOL was_r_ampersand = FALSE;
-
- if (*ptr == CHAR_R && ptrend - ptr > 1 && ptr[1] == CHAR_AMPERSAND)
- {
- terminator = CHAR_RIGHT_PARENTHESIS;
- was_r_ampersand = TRUE;
- ptr++;
- }
- else if (*ptr == CHAR_LESS_THAN_SIGN)
- terminator = CHAR_GREATER_THAN_SIGN;
- else if (*ptr == CHAR_APOSTROPHE)
- terminator = CHAR_APOSTROPHE;
- else
- {
- terminator = CHAR_RIGHT_PARENTHESIS;
- ptr--; /* Point to char before name */
- }
- if (!read_name(&ptr, ptrend, utf, terminator, &offset, &name, &namelen,
- &errorcode, cb)) goto FAILED;
-
- /* Handle (?(R&name) */
-
- if (was_r_ampersand)
- {
- *parsed_pattern = META_COND_RNAME;
- ptr--; /* Back to closing parens */
- }
-
- /* Handle (?(name). If the name is "DEFINE" we identify it with a
- special code. Likewise if the name consists of R followed only by
- digits. Otherwise, handle it like a quoted name. */
-
- else if (terminator == CHAR_RIGHT_PARENTHESIS)
- {
- if (namelen == 6 && PRIV(strncmp_c8)(name, STRING_DEFINE, 6) == 0)
- *parsed_pattern = META_COND_DEFINE;
- else
- {
- for (i = 1; i < (int)namelen; i++)
- if (!IS_DIGIT(name[i])) break;
- *parsed_pattern = (*name == CHAR_R && i >= (int)namelen)?
- META_COND_RNUMBER : META_COND_NAME;
- }
- ptr--; /* Back to closing parens */
- }
-
- /* Handle (?('name') or (?(<name>) */
-
- else *parsed_pattern = META_COND_NAME;
-
- /* All these cases except DEFINE end with the name length and offset;
- DEFINE just has an offset (for the "too many branches" error). */
-
- if (*parsed_pattern++ != META_COND_DEFINE) *parsed_pattern++ = namelen;
- PUTOFFSET(offset, parsed_pattern);
- } /* End cases that read a name */
-
- /* Check the closing parenthesis of the condition */
-
- if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
- {
- errorcode = ERR24;
- goto FAILED;
- }
- ptr++;
- break; /* End of condition processing */
-
-
- /* ---- Atomic group ---- */
-
- case CHAR_GREATER_THAN_SIGN:
- ATOMIC_GROUP: /* Come from (*atomic: */
- *parsed_pattern++ = META_ATOMIC;
- nest_depth++;
- ptr++;
- break;
-
-
- /* ---- Lookahead assertions ---- */
-
- case CHAR_EQUALS_SIGN:
- POSITIVE_LOOK_AHEAD: /* Come from (*pla: */
- *parsed_pattern++ = META_LOOKAHEAD;
- ptr++;
- goto POST_ASSERTION;
-
- case CHAR_ASTERISK:
- POSITIVE_NONATOMIC_LOOK_AHEAD: /* Come from (?* */
- *parsed_pattern++ = META_LOOKAHEAD_NA;
- ptr++;
- goto POST_ASSERTION;
-
- case CHAR_EXCLAMATION_MARK:
- NEGATIVE_LOOK_AHEAD: /* Come from (*nla: */
- *parsed_pattern++ = META_LOOKAHEADNOT;
- ptr++;
- goto POST_ASSERTION;
-
-
- /* ---- Lookbehind assertions ---- */
-
- /* (?< followed by = or ! or * is a lookbehind assertion. Otherwise (?<
- is the start of the name of a capturing group. */
-
- case CHAR_LESS_THAN_SIGN:
- if (ptrend - ptr <= 1 ||
- (ptr[1] != CHAR_EQUALS_SIGN &&
- ptr[1] != CHAR_EXCLAMATION_MARK &&
- ptr[1] != CHAR_ASTERISK))
- {
- terminator = CHAR_GREATER_THAN_SIGN;
- goto DEFINE_NAME;
- }
- *parsed_pattern++ = (ptr[1] == CHAR_EQUALS_SIGN)?
- META_LOOKBEHIND : (ptr[1] == CHAR_EXCLAMATION_MARK)?
- META_LOOKBEHINDNOT : META_LOOKBEHIND_NA;
-
- POST_LOOKBEHIND: /* Come from (*plb: (*naplb: and (*nlb: */
- *has_lookbehind = TRUE;
- offset = (PCRE2_SIZE)(ptr - cb->start_pattern - 2);
- PUTOFFSET(offset, parsed_pattern);
- ptr += 2;
- /* Fall through */
-
- /* If the previous item was a condition starting (?(? an assertion,
- optionally preceded by a callout, is expected. This is checked later on,
- during actual compilation. However we need to identify this kind of
- assertion in this pass because it must not be qualified. The value of
- expect_cond_assert is set to 2 after (?(? is processed. We decrement it
- for a callout - still leaving a positive value that identifies the
- assertion. Multiple callouts or any other items will make it zero or
- less, which doesn't matter because they will cause an error later. */
-
- POST_ASSERTION:
- nest_depth++;
- if (prev_expect_cond_assert > 0)
- {
- if (top_nest == NULL) top_nest = (nest_save *)(cb->start_workspace);
- else if (++top_nest >= end_nests)
- {
- errorcode = ERR84;
- goto FAILED;
- }
- top_nest->nest_depth = nest_depth;
- top_nest->flags = NSF_CONDASSERT;
- top_nest->options = options & PARSE_TRACKED_OPTIONS;
- }
- break;
-
-
- /* ---- Define a named group ---- */
-
- /* A named group may be defined as (?'name') or (?<name>). In the latter
- case we jump to DEFINE_NAME from the disambiguation of (?< above with the
- terminator set to '>'. */
-
- case CHAR_APOSTROPHE:
- terminator = CHAR_APOSTROPHE; /* Terminator */
-
- DEFINE_NAME:
- if (!read_name(&ptr, ptrend, utf, terminator, &offset, &name, &namelen,
- &errorcode, cb)) goto FAILED;
-
- /* We have a name for this capturing group. It is also assigned a number,
- which is its primary means of identification. */
-
- if (cb->bracount >= MAX_GROUP_NUMBER)
- {
- errorcode = ERR97;
- goto FAILED;
- }
- cb->bracount++;
- *parsed_pattern++ = META_CAPTURE | cb->bracount;
- nest_depth++;
-
- /* Check not too many names */
-
- if (cb->names_found >= MAX_NAME_COUNT)
- {
- errorcode = ERR49;
- goto FAILED;
- }
-
- /* Adjust the entry size to accommodate the longest name found. */
-
- if (namelen + IMM2_SIZE + 1 > cb->name_entry_size)
- cb->name_entry_size = (uint16_t)(namelen + IMM2_SIZE + 1);
-
- /* Scan the list to check for duplicates. For duplicate names, if the
- number is the same, break the loop, which causes the name to be
- discarded; otherwise, if DUPNAMES is not set, give an error.
- If it is set, allow the name with a different number, but continue
- scanning in case this is a duplicate with the same number. For
- non-duplicate names, give an error if the number is duplicated. */
-
- isdupname = FALSE;
- ng = cb->named_groups;
- for (i = 0; i < cb->names_found; i++, ng++)
- {
- if (namelen == ng->length &&
- PRIV(strncmp)(name, ng->name, (PCRE2_SIZE)namelen) == 0)
- {
- if (ng->number == cb->bracount) break;
- if ((options & PCRE2_DUPNAMES) == 0)
- {
- errorcode = ERR43;
- goto FAILED;
- }
- isdupname = ng->isdup = TRUE; /* Mark as a duplicate */
- cb->dupnames = TRUE; /* Duplicate names exist */
- }
- else if (ng->number == cb->bracount)
- {
- errorcode = ERR65;
- goto FAILED;
- }
- }
-
- if (i < cb->names_found) break; /* Ignore duplicate with same number */
-
- /* Increase the list size if necessary */
-
- if (cb->names_found >= cb->named_group_list_size)
- {
- uint32_t newsize = cb->named_group_list_size * 2;
- named_group *newspace =
- cb->cx->memctl.malloc(newsize * sizeof(named_group),
- cb->cx->memctl.memory_data);
- if (newspace == NULL)
- {
- errorcode = ERR21;
- goto FAILED;
- }
-
- memcpy(newspace, cb->named_groups,
- cb->named_group_list_size * sizeof(named_group));
- if (cb->named_group_list_size > NAMED_GROUP_LIST_SIZE)
- cb->cx->memctl.free((void *)cb->named_groups,
- cb->cx->memctl.memory_data);
- cb->named_groups = newspace;
- cb->named_group_list_size = newsize;
- }
-
- /* Add this name to the list */
-
- cb->named_groups[cb->names_found].name = name;
- cb->named_groups[cb->names_found].length = (uint16_t)namelen;
- cb->named_groups[cb->names_found].number = cb->bracount;
- cb->named_groups[cb->names_found].isdup = (uint16_t)isdupname;
- cb->names_found++;
- break;
- } /* End of (? switch */
- break; /* End of ( handling */
-
-
- /* ---- Branch terminators ---- */
-
- /* Alternation: reset the capture count if we are in a (?| group. */
-
- case CHAR_VERTICAL_LINE:
- if (top_nest != NULL && top_nest->nest_depth == nest_depth &&
- (top_nest->flags & NSF_RESET) != 0)
- {
- if (cb->bracount > top_nest->max_group)
- top_nest->max_group = (uint16_t)cb->bracount;
- cb->bracount = top_nest->reset_group;
- }
- *parsed_pattern++ = META_ALT;
- break;
-
- /* End of group; reset the capture count to the maximum if we are in a (?|
- group and/or reset the options that are tracked during parsing. Disallow
- quantifier for a condition that is an assertion. */
-
- case CHAR_RIGHT_PARENTHESIS:
- okquantifier = TRUE;
- if (top_nest != NULL && top_nest->nest_depth == nest_depth)
- {
- options = (options & ~PARSE_TRACKED_OPTIONS) | top_nest->options;
- if ((top_nest->flags & NSF_RESET) != 0 &&
- top_nest->max_group > cb->bracount)
- cb->bracount = top_nest->max_group;
- if ((top_nest->flags & NSF_CONDASSERT) != 0)
- okquantifier = FALSE;
-
- if ((top_nest->flags & NSF_ATOMICSR) != 0)
- {
- *parsed_pattern++ = META_KET;
- }
-
- if (top_nest == (nest_save *)(cb->start_workspace)) top_nest = NULL;
- else top_nest--;
- }
- if (nest_depth == 0) /* Unmatched closing parenthesis */
- {
- errorcode = ERR22;
- goto FAILED_BACK;
- }
- nest_depth--;
- *parsed_pattern++ = META_KET;
- break;
- } /* End of switch on pattern character */
- } /* End of main character scan loop */
-
-/* End of pattern reached. Check for missing ) at the end of a verb name. */
-
-if (inverbname && ptr >= ptrend)
- {
- errorcode = ERR60;
- goto FAILED;
- }
-
-/* Manage callout for the final item */
-
-PARSED_END:
-parsed_pattern = manage_callouts(ptr, &previous_callout, auto_callout,
- parsed_pattern, cb);
-
-/* Insert trailing items for word and line matching (features provided for the
-benefit of pcre2grep). */
-
-if ((extra_options & PCRE2_EXTRA_MATCH_LINE) != 0)
- {
- *parsed_pattern++ = META_KET;
- *parsed_pattern++ = META_DOLLAR;
- }
-else if ((extra_options & PCRE2_EXTRA_MATCH_WORD) != 0)
- {
- *parsed_pattern++ = META_KET;
- *parsed_pattern++ = META_ESCAPE + ESC_b;
- }
-
-/* Terminate the parsed pattern, then return success if all groups are closed.
-Otherwise we have unclosed parentheses. */
-
-if (parsed_pattern >= parsed_pattern_end)
- {
- errorcode = ERR63; /* Internal error (parsed pattern overflow) */
- goto FAILED;
- }
-
-*parsed_pattern = META_END;
-if (nest_depth == 0) return 0;
-
-UNCLOSED_PARENTHESIS:
-errorcode = ERR14;
-
-/* Come here for all failures. */
-
-FAILED:
-cb->erroroffset = (PCRE2_SIZE)(ptr - cb->start_pattern);
-return errorcode;
-
-/* Some errors need to indicate the previous character. */
-
-FAILED_BACK:
-ptr--;
-goto FAILED;
-
-/* This failure happens several times. */
-
-BAD_VERSION_CONDITION:
-errorcode = ERR79;
-goto FAILED;
-}
-
-
-
-/*************************************************
-* Find first significant opcode *
-*************************************************/
-
-/* This is called by several functions that scan a compiled expression looking
-for a fixed first character, or an anchoring opcode etc. It skips over things
-that do not influence this. For some calls, it makes sense to skip negative
-forward and all backward assertions, and also the \b assertion; for others it
-does not.
-
-Arguments:
- code pointer to the start of the group
- skipassert TRUE if certain assertions are to be skipped
-
-Returns: pointer to the first significant opcode
-*/
-
-static const PCRE2_UCHAR*
-first_significant_code(PCRE2_SPTR code, BOOL skipassert)
-{
-for (;;)
- {
- switch ((int)*code)
- {
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- case OP_ASSERTBACK_NA:
- if (!skipassert) return code;
- do code += GET(code, 1); while (*code == OP_ALT);
- code += PRIV(OP_lengths)[*code];
- break;
-
- case OP_WORD_BOUNDARY:
- case OP_NOT_WORD_BOUNDARY:
- if (!skipassert) return code;
- /* Fall through */
-
- case OP_CALLOUT:
- case OP_CREF:
- case OP_DNCREF:
- case OP_RREF:
- case OP_DNRREF:
- case OP_FALSE:
- case OP_TRUE:
- code += PRIV(OP_lengths)[*code];
- break;
-
- case OP_CALLOUT_STR:
- code += GET(code, 1 + 2*LINK_SIZE);
- break;
-
- case OP_SKIPZERO:
- code += 2 + GET(code, 2) + LINK_SIZE;
- break;
-
- case OP_COND:
- case OP_SCOND:
- if (code[1+LINK_SIZE] != OP_FALSE || /* Not DEFINE */
- code[GET(code, 1)] != OP_KET) /* More than one branch */
- return code;
- code += GET(code, 1) + 1 + LINK_SIZE;
- break;
-
- case OP_MARK:
- case OP_COMMIT_ARG:
- case OP_PRUNE_ARG:
- case OP_SKIP_ARG:
- case OP_THEN_ARG:
- code += code[1] + PRIV(OP_lengths)[*code];
- break;
-
- default:
- return code;
- }
- }
-/* Control never reaches here */
-}
-
-
-
-#ifdef SUPPORT_UNICODE
-/*************************************************
-* Get othercase range *
-*************************************************/
-
-/* This function is passed the start and end of a class range in UCP mode. It
-searches up the characters, looking for ranges of characters in the "other"
-case. Each call returns the next one, updating the start address. A character
-with multiple other cases is returned on its own with a special return value.
-
-Arguments:
- cptr points to starting character value; updated
- d end value
- ocptr where to put start of othercase range
- odptr where to put end of othercase range
-
-Yield: -1 when no more
- 0 when a range is returned
- >0 the CASESET offset for char with multiple other cases
- in this case, ocptr contains the original
-*/
-
-static int
-get_othercase_range(uint32_t *cptr, uint32_t d, uint32_t *ocptr,
- uint32_t *odptr)
-{
-uint32_t c, othercase, next;
-unsigned int co;
-
-/* Find the first character that has an other case. If it has multiple other
-cases, return its case offset value. */
-
-for (c = *cptr; c <= d; c++)
- {
- if ((co = UCD_CASESET(c)) != 0)
- {
- *ocptr = c++; /* Character that has the set */
- *cptr = c; /* Rest of input range */
- return (int)co;
- }
- if ((othercase = UCD_OTHERCASE(c)) != c) break;
- }
-
-if (c > d) return -1; /* Reached end of range */
-
-/* Found a character that has a single other case. Search for the end of the
-range, which is either the end of the input range, or a character that has zero
-or more than one other cases. */
-
-*ocptr = othercase;
-next = othercase + 1;
-
-for (++c; c <= d; c++)
- {
- if ((co = UCD_CASESET(c)) != 0 || UCD_OTHERCASE(c) != next) break;
- next++;
- }
-
-*odptr = next - 1; /* End of othercase range */
-*cptr = c; /* Rest of input range */
-return 0;
-}
-#endif /* SUPPORT_UNICODE */
-
-
-
-/*************************************************
-* Add a character or range to a class (internal) *
-*************************************************/
-
-/* This function packages up the logic of adding a character or range of
-characters to a class. The character values in the arguments will be within the
-valid values for the current mode (8-bit, 16-bit, UTF, etc). This function is
-called only from within the "add to class" group of functions, some of which
-are recursive and mutually recursive. The external entry point is
-add_to_class().
-
-Arguments:
- classbits the bit map for characters < 256
- uchardptr points to the pointer for extra data
- options the options word
- cb compile data
- start start of range character
- end end of range character
-
-Returns: the number of < 256 characters added
- the pointer to extra data is updated
-*/
-
-static unsigned int
-add_to_class_internal(uint8_t *classbits, PCRE2_UCHAR **uchardptr,
- uint32_t options, compile_block *cb, uint32_t start, uint32_t end)
-{
-uint32_t c;
-uint32_t classbits_end = (end <= 0xff ? end : 0xff);
-unsigned int n8 = 0;
-
-/* If caseless matching is required, scan the range and process alternate
-cases. In Unicode, there are 8-bit characters that have alternate cases that
-are greater than 255 and vice-versa. Sometimes we can just extend the original
-range. */
-
-if ((options & PCRE2_CASELESS) != 0)
- {
-#ifdef SUPPORT_UNICODE
- if ((options & (PCRE2_UTF|PCRE2_UCP)) != 0)
- {
- int rc;
- uint32_t oc, od;
-
- options &= ~PCRE2_CASELESS; /* Remove for recursive calls */
- c = start;
-
- while ((rc = get_othercase_range(&c, end, &oc, &od)) >= 0)
- {
- /* Handle a single character that has more than one other case. */
-
- if (rc > 0) n8 += add_list_to_class_internal(classbits, uchardptr, options, cb,
- PRIV(ucd_caseless_sets) + rc, oc);
-
- /* Do nothing if the other case range is within the original range. */
-
- else if (oc >= cb->class_range_start && od <= cb->class_range_end) continue;
-
- /* Extend the original range if there is overlap, noting that if oc < c, we
- can't have od > end because a subrange is always shorter than the basic
- range. Otherwise, use a recursive call to add the additional range. */
-
- else if (oc < start && od >= start - 1) start = oc; /* Extend downwards */
- else if (od > end && oc <= end + 1)
- {
- end = od; /* Extend upwards */
- if (end > classbits_end) classbits_end = (end <= 0xff ? end : 0xff);
- }
- else n8 += add_to_class_internal(classbits, uchardptr, options, cb, oc, od);
- }
- }
- else
-#endif /* SUPPORT_UNICODE */
-
- /* Not UTF mode */
-
- for (c = start; c <= classbits_end; c++)
- {
- SETBIT(classbits, cb->fcc[c]);
- n8++;
- }
- }
-
-/* Now handle the originally supplied range. Adjust the final value according
-to the bit length - this means that the same lists of (e.g.) horizontal spaces
-can be used in all cases. */
-
-if ((options & PCRE2_UTF) == 0 && end > MAX_NON_UTF_CHAR)
- end = MAX_NON_UTF_CHAR;
-
-if (start > cb->class_range_start && end < cb->class_range_end) return n8;
-
-/* Use the bitmap for characters < 256. Otherwise use extra data.*/
-
-for (c = start; c <= classbits_end; c++)
- {
- /* Regardless of start, c will always be <= 255. */
- SETBIT(classbits, c);
- n8++;
- }
-
-#ifdef SUPPORT_WIDE_CHARS
-if (start <= 0xff) start = 0xff + 1;
-
-if (end >= start)
- {
- PCRE2_UCHAR *uchardata = *uchardptr;
-
-#ifdef SUPPORT_UNICODE
- if ((options & PCRE2_UTF) != 0)
- {
- if (start < end)
- {
- *uchardata++ = XCL_RANGE;
- uchardata += PRIV(ord2utf)(start, uchardata);
- uchardata += PRIV(ord2utf)(end, uchardata);
- }
- else if (start == end)
- {
- *uchardata++ = XCL_SINGLE;
- uchardata += PRIV(ord2utf)(start, uchardata);
- }
- }
- else
-#endif /* SUPPORT_UNICODE */
-
- /* Without UTF support, character values are constrained by the bit length,
- and can only be > 256 for 16-bit and 32-bit libraries. */
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
- {}
-#else
- if (start < end)
- {
- *uchardata++ = XCL_RANGE;
- *uchardata++ = start;
- *uchardata++ = end;
- }
- else if (start == end)
- {
- *uchardata++ = XCL_SINGLE;
- *uchardata++ = start;
- }
-#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
- *uchardptr = uchardata; /* Updata extra data pointer */
- }
-#else /* SUPPORT_WIDE_CHARS */
- (void)uchardptr; /* Avoid compiler warning */
-#endif /* SUPPORT_WIDE_CHARS */
-
-return n8; /* Number of 8-bit characters */
-}
-
-
-
-#ifdef SUPPORT_UNICODE
-/*************************************************
-* Add a list of characters to a class (internal) *
-*************************************************/
-
-/* This function is used for adding a list of case-equivalent characters to a
-class when in UTF mode. This function is called only from within
-add_to_class_internal(), with which it is mutually recursive.
-
-Arguments:
- classbits the bit map for characters < 256
- uchardptr points to the pointer for extra data
- options the options word
- cb contains pointers to tables etc.
- p points to row of 32-bit values, terminated by NOTACHAR
- except character to omit; this is used when adding lists of
- case-equivalent characters to avoid including the one we
- already know about
-
-Returns: the number of < 256 characters added
- the pointer to extra data is updated
-*/
-
-static unsigned int
-add_list_to_class_internal(uint8_t *classbits, PCRE2_UCHAR **uchardptr,
- uint32_t options, compile_block *cb, const uint32_t *p, unsigned int except)
-{
-unsigned int n8 = 0;
-while (p[0] < NOTACHAR)
- {
- unsigned int n = 0;
- if (p[0] != except)
- {
- while(p[n+1] == p[0] + n + 1) n++;
- n8 += add_to_class_internal(classbits, uchardptr, options, cb, p[0], p[n]);
- }
- p += n + 1;
- }
-return n8;
-}
-#endif
-
-
-
-/*************************************************
-* External entry point for add range to class *
-*************************************************/
-
-/* This function sets the overall range so that the internal functions can try
-to avoid duplication when handling case-independence.
-
-Arguments:
- classbits the bit map for characters < 256
- uchardptr points to the pointer for extra data
- options the options word
- cb compile data
- start start of range character
- end end of range character
-
-Returns: the number of < 256 characters added
- the pointer to extra data is updated
-*/
-
-static unsigned int
-add_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, uint32_t options,
- compile_block *cb, uint32_t start, uint32_t end)
-{
-cb->class_range_start = start;
-cb->class_range_end = end;
-return add_to_class_internal(classbits, uchardptr, options, cb, start, end);
-}
-
-
-/*************************************************
-* External entry point for add list to class *
-*************************************************/
-
-/* This function is used for adding a list of horizontal or vertical whitespace
-characters to a class. The list must be in order so that ranges of characters
-can be detected and handled appropriately. This function sets the overall range
-so that the internal functions can try to avoid duplication when handling
-case-independence.
-
-Arguments:
- classbits the bit map for characters < 256
- uchardptr points to the pointer for extra data
- options the options word
- cb contains pointers to tables etc.
- p points to row of 32-bit values, terminated by NOTACHAR
- except character to omit; this is used when adding lists of
- case-equivalent characters to avoid including the one we
- already know about
-
-Returns: the number of < 256 characters added
- the pointer to extra data is updated
-*/
-
-static unsigned int
-add_list_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, uint32_t options,
- compile_block *cb, const uint32_t *p, unsigned int except)
-{
-unsigned int n8 = 0;
-while (p[0] < NOTACHAR)
- {
- unsigned int n = 0;
- if (p[0] != except)
- {
- while(p[n+1] == p[0] + n + 1) n++;
- cb->class_range_start = p[0];
- cb->class_range_end = p[n];
- n8 += add_to_class_internal(classbits, uchardptr, options, cb, p[0], p[n]);
- }
- p += n + 1;
- }
-return n8;
-}
-
-
-
-/*************************************************
-* Add characters not in a list to a class *
-*************************************************/
-
-/* This function is used for adding the complement of a list of horizontal or
-vertical whitespace to a class. The list must be in order.
-
-Arguments:
- classbits the bit map for characters < 256
- uchardptr points to the pointer for extra data
- options the options word
- cb contains pointers to tables etc.
- p points to row of 32-bit values, terminated by NOTACHAR
-
-Returns: the number of < 256 characters added
- the pointer to extra data is updated
-*/
-
-static unsigned int
-add_not_list_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr,
- uint32_t options, compile_block *cb, const uint32_t *p)
-{
-BOOL utf = (options & PCRE2_UTF) != 0;
-unsigned int n8 = 0;
-if (p[0] > 0)
- n8 += add_to_class(classbits, uchardptr, options, cb, 0, p[0] - 1);
-while (p[0] < NOTACHAR)
- {
- while (p[1] == p[0] + 1) p++;
- n8 += add_to_class(classbits, uchardptr, options, cb, p[0] + 1,
- (p[1] == NOTACHAR) ? (utf ? 0x10ffffu : 0xffffffffu) : p[1] - 1);
- p++;
- }
-return n8;
-}
-
-
-
-/*************************************************
-* Find details of duplicate group names *
-*************************************************/
-
-/* This is called from compile_branch() when it needs to know the index and
-count of duplicates in the names table when processing named backreferences,
-either directly, or as conditions.
-
-Arguments:
- name points to the name
- length the length of the name
- indexptr where to put the index
- countptr where to put the count of duplicates
- errorcodeptr where to put an error code
- cb the compile block
-
-Returns: TRUE if OK, FALSE if not, error code set
-*/
-
-static BOOL
-find_dupname_details(PCRE2_SPTR name, uint32_t length, int *indexptr,
- int *countptr, int *errorcodeptr, compile_block *cb)
-{
-uint32_t i, groupnumber;
-int count;
-PCRE2_UCHAR *slot = cb->name_table;
-
-/* Find the first entry in the table */
-
-for (i = 0; i < cb->names_found; i++)
- {
- if (PRIV(strncmp)(name, slot+IMM2_SIZE, length) == 0 &&
- slot[IMM2_SIZE+length] == 0) break;
- slot += cb->name_entry_size;
- }
-
-/* This should not occur, because this function is called only when we know we
-have duplicate names. Give an internal error. */
-
-if (i >= cb->names_found)
- {
- *errorcodeptr = ERR53;
- cb->erroroffset = name - cb->start_pattern;
- return FALSE;
- }
-
-/* Record the index and then see how many duplicates there are, updating the
-backref map and maximum back reference as we do. */
-
-*indexptr = i;
-count = 0;
-
-for (;;)
- {
- count++;
- groupnumber = GET2(slot,0);
- cb->backref_map |= (groupnumber < 32)? (1u << groupnumber) : 1;
- if (groupnumber > cb->top_backref) cb->top_backref = groupnumber;
- if (++i >= cb->names_found) break;
- slot += cb->name_entry_size;
- if (PRIV(strncmp)(name, slot+IMM2_SIZE, length) != 0 ||
- (slot+IMM2_SIZE)[length] != 0) break;
- }
-
-*countptr = count;
-return TRUE;
-}
-
-
-
-/*************************************************
-* Compile one branch *
-*************************************************/
-
-/* Scan the parsed pattern, compiling it into the a vector of PCRE2_UCHAR. If
-the options are changed during the branch, the pointer is used to change the
-external options bits. This function is used during the pre-compile phase when
-we are trying to find out the amount of memory needed, as well as during the
-real compile phase. The value of lengthptr distinguishes the two phases.
-
-Arguments:
- optionsptr pointer to the option bits
- codeptr points to the pointer to the current code point
- pptrptr points to the current parsed pattern pointer
- errorcodeptr points to error code variable
- firstcuptr place to put the first required code unit
- firstcuflagsptr place to put the first code unit flags
- reqcuptr place to put the last required code unit
- reqcuflagsptr place to put the last required code unit flags
- bcptr points to current branch chain
- cb contains pointers to tables etc.
- lengthptr NULL during the real compile phase
- points to length accumulator during pre-compile phase
-
-Returns: 0 There's been an error, *errorcodeptr is non-zero
- +1 Success, this branch must match at least one character
- -1 Success, this branch may match an empty string
-*/
-
-static int
-compile_branch(uint32_t *optionsptr, PCRE2_UCHAR **codeptr, uint32_t **pptrptr,
- int *errorcodeptr, uint32_t *firstcuptr, uint32_t *firstcuflagsptr,
- uint32_t *reqcuptr, uint32_t *reqcuflagsptr, branch_chain *bcptr,
- compile_block *cb, PCRE2_SIZE *lengthptr)
-{
-int bravalue = 0;
-int okreturn = -1;
-int group_return = 0;
-uint32_t repeat_min = 0, repeat_max = 0; /* To please picky compilers */
-uint32_t greedy_default, greedy_non_default;
-uint32_t repeat_type, op_type;
-uint32_t options = *optionsptr; /* May change dynamically */
-uint32_t firstcu, reqcu;
-uint32_t zeroreqcu, zerofirstcu;
-uint32_t escape;
-uint32_t *pptr = *pptrptr;
-uint32_t meta, meta_arg;
-uint32_t firstcuflags, reqcuflags;
-uint32_t zeroreqcuflags, zerofirstcuflags;
-uint32_t req_caseopt, reqvary, tempreqvary;
-PCRE2_SIZE offset = 0;
-PCRE2_SIZE length_prevgroup = 0;
-PCRE2_UCHAR *code = *codeptr;
-PCRE2_UCHAR *last_code = code;
-PCRE2_UCHAR *orig_code = code;
-PCRE2_UCHAR *tempcode;
-PCRE2_UCHAR *previous = NULL;
-PCRE2_UCHAR op_previous;
-BOOL groupsetfirstcu = FALSE;
-BOOL had_accept = FALSE;
-BOOL matched_char = FALSE;
-BOOL previous_matched_char = FALSE;
-BOOL reset_caseful = FALSE;
-const uint8_t *cbits = cb->cbits;
-uint8_t classbits[32];
-
-/* We can fish out the UTF setting once and for all into a BOOL, but we must
-not do this for other options (e.g. PCRE2_EXTENDED) because they may change
-dynamically as we process the pattern. */
-
-#ifdef SUPPORT_UNICODE
-BOOL utf = (options & PCRE2_UTF) != 0;
-BOOL ucp = (options & PCRE2_UCP) != 0;
-#else /* No Unicode support */
-BOOL utf = FALSE;
-#endif
-
-/* Helper variables for OP_XCLASS opcode (for characters > 255). We define
-class_uchardata always so that it can be passed to add_to_class() always,
-though it will not be used in non-UTF 8-bit cases. This avoids having to supply
-alternative calls for the different cases. */
-
-PCRE2_UCHAR *class_uchardata;
-#ifdef SUPPORT_WIDE_CHARS
-BOOL xclass;
-PCRE2_UCHAR *class_uchardata_base;
-#endif
-
-/* Set up the default and non-default settings for greediness */
-
-greedy_default = ((options & PCRE2_UNGREEDY) != 0);
-greedy_non_default = greedy_default ^ 1;
-
-/* Initialize no first unit, no required unit. REQ_UNSET means "no char
-matching encountered yet". It gets changed to REQ_NONE if we hit something that
-matches a non-fixed first unit; reqcu just remains unset if we never find one.
-
-When we hit a repeat whose minimum is zero, we may have to adjust these values
-to take the zero repeat into account. This is implemented by setting them to
-zerofirstcu and zeroreqcu when such a repeat is encountered. The individual
-item types that can be repeated set these backoff variables appropriately. */
-
-firstcu = reqcu = zerofirstcu = zeroreqcu = 0;
-firstcuflags = reqcuflags = zerofirstcuflags = zeroreqcuflags = REQ_UNSET;
-
-/* The variable req_caseopt contains either the REQ_CASELESS bit or zero,
-according to the current setting of the caseless flag. The REQ_CASELESS value
-leaves the lower 28 bit empty. It is added into the firstcu or reqcu variables
-to record the case status of the value. This is used only for ASCII characters.
-*/
-
-req_caseopt = ((options & PCRE2_CASELESS) != 0)? REQ_CASELESS : 0;
-
-/* Switch on next META item until the end of the branch */
-
-for (;; pptr++)
- {
-#ifdef SUPPORT_WIDE_CHARS
- BOOL xclass_has_prop;
-#endif
- BOOL negate_class;
- BOOL should_flip_negation;
- BOOL match_all_or_no_wide_chars;
- BOOL possessive_quantifier;
- BOOL note_group_empty;
- int class_has_8bitchar;
- uint32_t mclength;
- uint32_t skipunits;
- uint32_t subreqcu, subfirstcu;
- uint32_t groupnumber;
- uint32_t verbarglen, verbculen;
- uint32_t subreqcuflags, subfirstcuflags;
- open_capitem *oc;
- PCRE2_UCHAR mcbuffer[8];
-
- /* Get next META item in the pattern and its potential argument. */
-
- meta = META_CODE(*pptr);
- meta_arg = META_DATA(*pptr);
-
- /* If we are in the pre-compile phase, accumulate the length used for the
- previous cycle of this loop, unless the next item is a quantifier. */
-
- if (lengthptr != NULL)
- {
- if (code > cb->start_workspace + cb->workspace_size -
- WORK_SIZE_SAFETY_MARGIN) /* Check for overrun */
- {
- *errorcodeptr = (code >= cb->start_workspace + cb->workspace_size)?
- ERR52 : ERR86;
- return 0;
- }
-
- /* There is at least one situation where code goes backwards: this is the
- case of a zero quantifier after a class (e.g. [ab]{0}). When the quantifier
- is processed, the whole class is eliminated. However, it is created first,
- so we have to allow memory for it. Therefore, don't ever reduce the length
- at this point. */
-
- if (code < last_code) code = last_code;
-
- /* If the next thing is not a quantifier, we add the length of the previous
- item into the total, and reset the code pointer to the start of the
- workspace. Otherwise leave the previous item available to be quantified. */
-
- if (meta < META_ASTERISK || meta > META_MINMAX_QUERY)
- {
- if (OFLOW_MAX - *lengthptr < (PCRE2_SIZE)(code - orig_code))
- {
- *errorcodeptr = ERR20; /* Integer overflow */
- return 0;
- }
- *lengthptr += (PCRE2_SIZE)(code - orig_code);
- if (*lengthptr > MAX_PATTERN_SIZE)
- {
- *errorcodeptr = ERR20; /* Pattern is too large */
- return 0;
- }
- code = orig_code;
- }
-
- /* Remember where this code item starts so we can catch the "backwards"
- case above next time round. */
-
- last_code = code;
- }
-
- /* Process the next parsed pattern item. If it is not a quantifier, remember
- where it starts so that it can be quantified when a quantifier follows.
- Checking for the legality of quantifiers happens in parse_regex(), except for
- a quantifier after an assertion that is a condition. */
-
- if (meta < META_ASTERISK || meta > META_MINMAX_QUERY)
- {
- previous = code;
- if (matched_char && !had_accept) okreturn = 1;
- }
-
- previous_matched_char = matched_char;
- matched_char = FALSE;
- note_group_empty = FALSE;
- skipunits = 0; /* Default value for most subgroups */
-
- switch(meta)
- {
- /* ===================================================================*/
- /* The branch terminates at pattern end or | or ) */
-
- case META_END:
- case META_ALT:
- case META_KET:
- *firstcuptr = firstcu;
- *firstcuflagsptr = firstcuflags;
- *reqcuptr = reqcu;
- *reqcuflagsptr = reqcuflags;
- *codeptr = code;
- *pptrptr = pptr;
- return okreturn;
-
-
- /* ===================================================================*/
- /* Handle single-character metacharacters. In multiline mode, ^ disables
- the setting of any following char as a first character. */
-
- case META_CIRCUMFLEX:
- if ((options & PCRE2_MULTILINE) != 0)
- {
- if (firstcuflags == REQ_UNSET)
- zerofirstcuflags = firstcuflags = REQ_NONE;
- *code++ = OP_CIRCM;
- }
- else *code++ = OP_CIRC;
- break;
-
- case META_DOLLAR:
- *code++ = ((options & PCRE2_MULTILINE) != 0)? OP_DOLLM : OP_DOLL;
- break;
-
- /* There can never be a first char if '.' is first, whatever happens about
- repeats. The value of reqcu doesn't change either. */
-
- case META_DOT:
- matched_char = TRUE;
- if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
- zerofirstcu = firstcu;
- zerofirstcuflags = firstcuflags;
- zeroreqcu = reqcu;
- zeroreqcuflags = reqcuflags;
- *code++ = ((options & PCRE2_DOTALL) != 0)? OP_ALLANY: OP_ANY;
- break;
-
-
- /* ===================================================================*/
- /* Empty character classes are allowed if PCRE2_ALLOW_EMPTY_CLASS is set.
- Otherwise, an initial ']' is taken as a data character. When empty classes
- are allowed, [] must always fail, so generate OP_FAIL, whereas [^] must
- match any character, so generate OP_ALLANY. */
-
- case META_CLASS_EMPTY:
- case META_CLASS_EMPTY_NOT:
- matched_char = TRUE;
- *code++ = (meta == META_CLASS_EMPTY_NOT)? OP_ALLANY : OP_FAIL;
- if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
- zerofirstcu = firstcu;
- zerofirstcuflags = firstcuflags;
- break;
-
-
- /* ===================================================================*/
- /* Non-empty character class. If the included characters are all < 256, we
- build a 32-byte bitmap of the permitted characters, except in the special
- case where there is only one such character. For negated classes, we build
- the map as usual, then invert it at the end. However, we use a different
- opcode so that data characters > 255 can be handled correctly.
-
- If the class contains characters outside the 0-255 range, a different
- opcode is compiled. It may optionally have a bit map for characters < 256,
- but those above are are explicitly listed afterwards. A flag code unit
- tells whether the bitmap is present, and whether this is a negated class or
- not. */
-
- case META_CLASS_NOT:
- case META_CLASS:
- matched_char = TRUE;
- negate_class = meta == META_CLASS_NOT;
-
- /* We can optimize the case of a single character in a class by generating
- OP_CHAR or OP_CHARI if it's positive, or OP_NOT or OP_NOTI if it's
- negative. In the negative case there can be no first char if this item is
- first, whatever repeat count may follow. In the case of reqcu, save the
- previous value for reinstating. */
-
- /* NOTE: at present this optimization is not effective if the only
- character in a class in 32-bit, non-UCP mode has its top bit set. */
-
- if (pptr[1] < META_END && pptr[2] == META_CLASS_END)
- {
-#ifdef SUPPORT_UNICODE
- uint32_t d;
-#endif
- uint32_t c = pptr[1];
-
- pptr += 2; /* Move on to class end */
- if (meta == META_CLASS) /* A positive one-char class can be */
- { /* handled as a normal literal character. */
- meta = c; /* Set up the character */
- goto NORMAL_CHAR_SET;
- }
-
- /* Handle a negative one-character class */
-
- zeroreqcu = reqcu;
- zeroreqcuflags = reqcuflags;
- if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
- zerofirstcu = firstcu;
- zerofirstcuflags = firstcuflags;
-
- /* For caseless UTF or UCP mode, check whether this character has more
- than one other case. If so, generate a special OP_NOTPROP item instead of
- OP_NOTI. */
-
-#ifdef SUPPORT_UNICODE
- if ((utf||ucp) && (options & PCRE2_CASELESS) != 0 &&
- (d = UCD_CASESET(c)) != 0)
- {
- *code++ = OP_NOTPROP;
- *code++ = PT_CLIST;
- *code++ = d;
- break; /* We are finished with this class */
- }
-#endif
- /* Char has only one other case, or UCP not available */
-
- *code++ = ((options & PCRE2_CASELESS) != 0)? OP_NOTI: OP_NOT;
- code += PUTCHAR(c, code);
- break; /* We are finished with this class */
- } /* End of 1-char optimization */
-
- /* Handle character classes that contain more than just one literal
- character. If there are exactly two characters in a positive class, see if
- they are case partners. This can be optimized to generate a caseless single
- character match (which also sets first/required code units if relevant). */
-
- if (meta == META_CLASS && pptr[1] < META_END && pptr[2] < META_END &&
- pptr[3] == META_CLASS_END)
- {
- uint32_t c = pptr[1];
-
-#ifdef SUPPORT_UNICODE
- if (UCD_CASESET(c) == 0)
-#endif
- {
- uint32_t d;
-
-#ifdef SUPPORT_UNICODE
- if ((utf || ucp) && c > 127) d = UCD_OTHERCASE(c); else
-#endif
- {
-#if PCRE2_CODE_UNIT_WIDTH != 8
- if (c > 255) d = c; else
-#endif
- d = TABLE_GET(c, cb->fcc, c);
- }
-
- if (c != d && pptr[2] == d)
- {
- pptr += 3; /* Move on to class end */
- meta = c;
- if ((options & PCRE2_CASELESS) == 0)
- {
- reset_caseful = TRUE;
- options |= PCRE2_CASELESS;
- req_caseopt = REQ_CASELESS;
- }
- goto CLASS_CASELESS_CHAR;
- }
- }
- }
-
- /* If a non-extended class contains a negative special such as \S, we need
- to flip the negation flag at the end, so that support for characters > 255
- works correctly (they are all included in the class). An extended class may
- need to insert specific matching or non-matching code for wide characters.
- */
-
- should_flip_negation = match_all_or_no_wide_chars = FALSE;
-
- /* Extended class (xclass) will be used when characters > 255
- might match. */
-
-#ifdef SUPPORT_WIDE_CHARS
- xclass = FALSE;
- class_uchardata = code + LINK_SIZE + 2; /* For XCLASS items */
- class_uchardata_base = class_uchardata; /* Save the start */
-#endif
-
- /* For optimization purposes, we track some properties of the class:
- class_has_8bitchar will be non-zero if the class contains at least one
- character with a code point less than 256; xclass_has_prop will be TRUE if
- Unicode property checks are present in the class. */
-
- class_has_8bitchar = 0;
-#ifdef SUPPORT_WIDE_CHARS
- xclass_has_prop = FALSE;
-#endif
-
- /* Initialize the 256-bit (32-byte) bit map to all zeros. We build the map
- in a temporary bit of memory, in case the class contains fewer than two
- 8-bit characters because in that case the compiled code doesn't use the bit
- map. */
-
- memset(classbits, 0, 32 * sizeof(uint8_t));
-
- /* Process items until META_CLASS_END is reached. */
-
- while ((meta = *(++pptr)) != META_CLASS_END)
- {
- /* Handle POSIX classes such as [:alpha:] etc. */
-
- if (meta == META_POSIX || meta == META_POSIX_NEG)
- {
- BOOL local_negate = (meta == META_POSIX_NEG);
- int posix_class = *(++pptr);
- int taboffset, tabopt;
- uint8_t pbits[32];
-
- should_flip_negation = local_negate; /* Note negative special */
-
- /* If matching is caseless, upper and lower are converted to alpha.
- This relies on the fact that the class table starts with alpha,
- lower, upper as the first 3 entries. */
-
- if ((options & PCRE2_CASELESS) != 0 && posix_class <= 2)
- posix_class = 0;
-
- /* When PCRE2_UCP is set, some of the POSIX classes are converted to
- different escape sequences that use Unicode properties \p or \P.
- Others that are not available via \p or \P have to generate
- XCL_PROP/XCL_NOTPROP directly, which is done here. */
-
-#ifdef SUPPORT_UNICODE
- if ((options & PCRE2_UCP) != 0) switch(posix_class)
- {
- case PC_GRAPH:
- case PC_PRINT:
- case PC_PUNCT:
- *class_uchardata++ = local_negate? XCL_NOTPROP : XCL_PROP;
- *class_uchardata++ = (PCRE2_UCHAR)
- ((posix_class == PC_GRAPH)? PT_PXGRAPH :
- (posix_class == PC_PRINT)? PT_PXPRINT : PT_PXPUNCT);
- *class_uchardata++ = 0;
- xclass_has_prop = TRUE;
- goto CONTINUE_CLASS;
-
- /* For the other POSIX classes (ascii, xdigit) we are going to
- fall through to the non-UCP case and build a bit map for
- characters with code points less than 256. However, if we are in
- a negated POSIX class, characters with code points greater than
- 255 must either all match or all not match, depending on whether
- the whole class is not or is negated. For example, for
- [[:^ascii:]... they must all match, whereas for [^[:^xdigit:]...
- they must not.
-
- In the special case where there are no xclass items, this is
- automatically handled by the use of OP_CLASS or OP_NCLASS, but an
- explicit range is needed for OP_XCLASS. Setting a flag here
- causes the range to be generated later when it is known that
- OP_XCLASS is required. In the 8-bit library this is relevant only in
- utf mode, since no wide characters can exist otherwise. */
-
- default:
-#if PCRE2_CODE_UNIT_WIDTH == 8
- if (utf)
-#endif
- match_all_or_no_wide_chars |= local_negate;
- break;
- }
-#endif /* SUPPORT_UNICODE */
-
- /* In the non-UCP case, or when UCP makes no difference, we build the
- bit map for the POSIX class in a chunk of local store because we may
- be adding and subtracting from it, and we don't want to subtract bits
- that may be in the main map already. At the end we or the result into
- the bit map that is being built. */
-
- posix_class *= 3;
-
- /* Copy in the first table (always present) */
-
- memcpy(pbits, cbits + posix_class_maps[posix_class],
- 32 * sizeof(uint8_t));
-
- /* If there is a second table, add or remove it as required. */
-
- taboffset = posix_class_maps[posix_class + 1];
- tabopt = posix_class_maps[posix_class + 2];
-
- if (taboffset >= 0)
- {
- if (tabopt >= 0)
- for (int i = 0; i < 32; i++) pbits[i] |= cbits[(int)i + taboffset];
- else
- for (int i = 0; i < 32; i++) pbits[i] &= ~cbits[(int)i + taboffset];
- }
-
- /* Now see if we need to remove any special characters. An option
- value of 1 removes vertical space and 2 removes underscore. */
-
- if (tabopt < 0) tabopt = -tabopt;
- if (tabopt == 1) pbits[1] &= ~0x3c;
- else if (tabopt == 2) pbits[11] &= 0x7f;
-
- /* Add the POSIX table or its complement into the main table that is
- being built and we are done. */
-
- if (local_negate)
- for (int i = 0; i < 32; i++) classbits[i] |= (uint8_t)(~pbits[i]);
- else
- for (int i = 0; i < 32; i++) classbits[i] |= pbits[i];
-
- /* Every class contains at least one < 256 character. */
-
- class_has_8bitchar = 1;
- goto CONTINUE_CLASS; /* End of POSIX handling */
- }
-
- /* Other than POSIX classes, the only items we should encounter are
- \d-type escapes and literal characters (possibly as ranges). */
-
- if (meta == META_BIGVALUE)
- {
- meta = *(++pptr);
- goto CLASS_LITERAL;
- }
-
- /* Any other non-literal must be an escape */
-
- if (meta >= META_END)
- {
- if (META_CODE(meta) != META_ESCAPE)
- {
-#ifdef DEBUG_SHOW_PARSED
- fprintf(stderr, "** Unrecognized parsed pattern item 0x%.8x "
- "in character class\n", meta);
-#endif
- *errorcodeptr = ERR89; /* Internal error - unrecognized. */
- return 0;
- }
- escape = META_DATA(meta);
-
- /* Every class contains at least one < 256 character. */
-
- class_has_8bitchar++;
-
- switch(escape)
- {
- case ESC_d:
- for (int i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_digit];
- break;
-
- case ESC_D:
- should_flip_negation = TRUE;
- for (int i = 0; i < 32; i++)
- classbits[i] |= (uint8_t)(~cbits[i+cbit_digit]);
- break;
-
- case ESC_w:
- for (int i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_word];
- break;
-
- case ESC_W:
- should_flip_negation = TRUE;
- for (int i = 0; i < 32; i++)
- classbits[i] |= (uint8_t)(~cbits[i+cbit_word]);
- break;
-
- /* Perl 5.004 onwards omitted VT from \s, but restored it at Perl
- 5.18. Before PCRE 8.34, we had to preserve the VT bit if it was
- previously set by something earlier in the character class.
- Luckily, the value of CHAR_VT is 0x0b in both ASCII and EBCDIC, so
- we could just adjust the appropriate bit. From PCRE 8.34 we no
- longer treat \s and \S specially. */
-
- case ESC_s:
- for (int i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_space];
- break;
-
- case ESC_S:
- should_flip_negation = TRUE;
- for (int i = 0; i < 32; i++)
- classbits[i] |= (uint8_t)(~cbits[i+cbit_space]);
- break;
-
- /* When adding the horizontal or vertical space lists to a class, or
- their complements, disable PCRE2_CASELESS, because it justs wastes
- time, and in the "not-x" UTF cases can create unwanted duplicates in
- the XCLASS list (provoked by characters that have more than one other
- case and by both cases being in the same "not-x" sublist). */
-
- case ESC_h:
- (void)add_list_to_class(classbits, &class_uchardata,
- options & ~PCRE2_CASELESS, cb, PRIV(hspace_list), NOTACHAR);
- break;
-
- case ESC_H:
- (void)add_not_list_to_class(classbits, &class_uchardata,
- options & ~PCRE2_CASELESS, cb, PRIV(hspace_list));
- break;
-
- case ESC_v:
- (void)add_list_to_class(classbits, &class_uchardata,
- options & ~PCRE2_CASELESS, cb, PRIV(vspace_list), NOTACHAR);
- break;
-
- case ESC_V:
- (void)add_not_list_to_class(classbits, &class_uchardata,
- options & ~PCRE2_CASELESS, cb, PRIV(vspace_list));
- break;
-
- /* If Unicode is not supported, \P and \p are not allowed and are
- faulted at parse time, so will never appear here. */
-
-#ifdef SUPPORT_UNICODE
- case ESC_p:
- case ESC_P:
- {
- uint32_t ptype = *(++pptr) >> 16;
- uint32_t pdata = *pptr & 0xffff;
- *class_uchardata++ = (escape == ESC_p)? XCL_PROP : XCL_NOTPROP;
- *class_uchardata++ = ptype;
- *class_uchardata++ = pdata;
- xclass_has_prop = TRUE;
- class_has_8bitchar--; /* Undo! */
- }
- break;
-#endif
- }
-
- goto CONTINUE_CLASS;
- } /* End handling \d-type escapes */
-
- /* A literal character may be followed by a range meta. At parse time
- there are checks for out-of-order characters, for ranges where the two
- characters are equal, and for hyphens that cannot indicate a range. At
- this point, therefore, no checking is needed. */
-
- else
- {
- uint32_t c, d;
-
- CLASS_LITERAL:
- c = d = meta;
-
- /* Remember if \r or \n were explicitly used */
-
- if (c == CHAR_CR || c == CHAR_NL) cb->external_flags |= PCRE2_HASCRORLF;
-
- /* Process a character range */
-
- if (pptr[1] == META_RANGE_LITERAL || pptr[1] == META_RANGE_ESCAPED)
- {
-#ifdef EBCDIC
- BOOL range_is_literal = (pptr[1] == META_RANGE_LITERAL);
-#endif
- pptr += 2;
- d = *pptr;
- if (d == META_BIGVALUE) d = *(++pptr);
-
- /* Remember an explicit \r or \n, and add the range to the class. */
-
- if (d == CHAR_CR || d == CHAR_NL) cb->external_flags |= PCRE2_HASCRORLF;
-
- /* In an EBCDIC environment, Perl treats alphabetic ranges specially
- because there are holes in the encoding, and simply using the range
- A-Z (for example) would include the characters in the holes. This
- applies only to literal ranges; [\xC1-\xE9] is different to [A-Z]. */
-
-#ifdef EBCDIC
- if (range_is_literal &&
- (cb->ctypes[c] & ctype_letter) != 0 &&
- (cb->ctypes[d] & ctype_letter) != 0 &&
- (c <= CHAR_z) == (d <= CHAR_z))
- {
- uint32_t uc = (d <= CHAR_z)? 0 : 64;
- uint32_t C = c - uc;
- uint32_t D = d - uc;
-
- if (C <= CHAR_i)
- {
- class_has_8bitchar +=
- add_to_class(classbits, &class_uchardata, options, cb, C + uc,
- ((D < CHAR_i)? D : CHAR_i) + uc);
- C = CHAR_j;
- }
-
- if (C <= D && C <= CHAR_r)
- {
- class_has_8bitchar +=
- add_to_class(classbits, &class_uchardata, options, cb, C + uc,
- ((D < CHAR_r)? D : CHAR_r) + uc);
- C = CHAR_s;
- }
-
- if (C <= D)
- {
- class_has_8bitchar +=
- add_to_class(classbits, &class_uchardata, options, cb, C + uc,
- D + uc);
- }
- }
- else
-#endif
- /* Not an EBCDIC special range */
-
- class_has_8bitchar +=
- add_to_class(classbits, &class_uchardata, options, cb, c, d);
- goto CONTINUE_CLASS; /* Go get the next char in the class */
- } /* End of range handling */
-
-
- /* Handle a single character. */
-
- class_has_8bitchar +=
- add_to_class(classbits, &class_uchardata, options, cb, meta, meta);
- }
-
- /* Continue to the next item in the class. */
-
- CONTINUE_CLASS:
-
-#ifdef SUPPORT_WIDE_CHARS
- /* If any wide characters or Unicode properties have been encountered,
- set xclass = TRUE. Then, in the pre-compile phase, accumulate the length
- of the extra data and reset the pointer. This is so that very large
- classes that contain a zillion wide characters or Unicode property tests
- do not overwrite the workspace (which is on the stack). */
-
- if (class_uchardata > class_uchardata_base)
- {
- xclass = TRUE;
- if (lengthptr != NULL)
- {
- *lengthptr += class_uchardata - class_uchardata_base;
- class_uchardata = class_uchardata_base;
- }
- }
-#endif
-
- continue; /* Needed to avoid error when not supporting wide chars */
- } /* End of main class-processing loop */
-
- /* If this class is the first thing in the branch, there can be no first
- char setting, whatever the repeat count. Any reqcu setting must remain
- unchanged after any kind of repeat. */
-
- if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
- zerofirstcu = firstcu;
- zerofirstcuflags = firstcuflags;
- zeroreqcu = reqcu;
- zeroreqcuflags = reqcuflags;
-
- /* If there are characters with values > 255, or Unicode property settings
- (\p or \P), we have to compile an extended class, with its own opcode,
- unless there were no property settings and there was a negated special such
- as \S in the class, and PCRE2_UCP is not set, because in that case all
- characters > 255 are in or not in the class, so any that were explicitly
- given as well can be ignored.
-
- In the UCP case, if certain negated POSIX classes ([:^ascii:] or
- [^:xdigit:]) were present in a class, we either have to match or not match
- all wide characters (depending on whether the whole class is or is not
- negated). This requirement is indicated by match_all_or_no_wide_chars being
- true. We do this by including an explicit range, which works in both cases.
- This applies only in UTF and 16-bit and 32-bit non-UTF modes, since there
- cannot be any wide characters in 8-bit non-UTF mode.
-
- When there *are* properties in a positive UTF-8 or any 16-bit or 32_bit
- class where \S etc is present without PCRE2_UCP, causing an extended class
- to be compiled, we make sure that all characters > 255 are included by
- forcing match_all_or_no_wide_chars to be true.
-
- If, when generating an xclass, there are no characters < 256, we can omit
- the bitmap in the actual compiled code. */
-
-#ifdef SUPPORT_WIDE_CHARS /* Defined for 16/32 bits, or 8-bit with Unicode */
- if (xclass && (
-#ifdef SUPPORT_UNICODE
- (options & PCRE2_UCP) != 0 ||
-#endif
- xclass_has_prop || !should_flip_negation))
- {
- if (match_all_or_no_wide_chars || (
-#if PCRE2_CODE_UNIT_WIDTH == 8
- utf &&
-#endif
- should_flip_negation && !negate_class && (options & PCRE2_UCP) == 0))
- {
- *class_uchardata++ = XCL_RANGE;
- if (utf) /* Will always be utf in the 8-bit library */
- {
- class_uchardata += PRIV(ord2utf)(0x100, class_uchardata);
- class_uchardata += PRIV(ord2utf)(MAX_UTF_CODE_POINT, class_uchardata);
- }
- else /* Can only happen for the 16-bit & 32-bit libraries */
- {
-#if PCRE2_CODE_UNIT_WIDTH == 16
- *class_uchardata++ = 0x100;
- *class_uchardata++ = 0xffffu;
-#elif PCRE2_CODE_UNIT_WIDTH == 32
- *class_uchardata++ = 0x100;
- *class_uchardata++ = 0xffffffffu;
-#endif
- }
- }
- *class_uchardata++ = XCL_END; /* Marks the end of extra data */
- *code++ = OP_XCLASS;
- code += LINK_SIZE;
- *code = negate_class? XCL_NOT:0;
- if (xclass_has_prop) *code |= XCL_HASPROP;
-
- /* If the map is required, move up the extra data to make room for it;
- otherwise just move the code pointer to the end of the extra data. */
-
- if (class_has_8bitchar > 0)
- {
- *code++ |= XCL_MAP;
- (void)memmove(code + (32 / sizeof(PCRE2_UCHAR)), code,
- CU2BYTES(class_uchardata - code));
- if (negate_class && !xclass_has_prop)
- {
- /* Using 255 ^ instead of ~ avoids clang sanitize warning. */
- for (int i = 0; i < 32; i++) classbits[i] = 255 ^ classbits[i];
- }
- memcpy(code, classbits, 32);
- code = class_uchardata + (32 / sizeof(PCRE2_UCHAR));
- }
- else code = class_uchardata;
-
- /* Now fill in the complete length of the item */
-
- PUT(previous, 1, (int)(code - previous));
- break; /* End of class handling */
- }
-#endif /* SUPPORT_WIDE_CHARS */
-
- /* If there are no characters > 255, or they are all to be included or
- excluded, set the opcode to OP_CLASS or OP_NCLASS, depending on whether the
- whole class was negated and whether there were negative specials such as \S
- (non-UCP) in the class. Then copy the 32-byte map into the code vector,
- negating it if necessary. */
-
- *code++ = (negate_class == should_flip_negation) ? OP_CLASS : OP_NCLASS;
- if (lengthptr == NULL) /* Save time in the pre-compile phase */
- {
- if (negate_class)
- {
- /* Using 255 ^ instead of ~ avoids clang sanitize warning. */
- for (int i = 0; i < 32; i++) classbits[i] = 255 ^ classbits[i];
- }
- memcpy(code, classbits, 32);
- }
- code += 32 / sizeof(PCRE2_UCHAR);
- break; /* End of class processing */
-
-
- /* ===================================================================*/
- /* Deal with (*VERB)s. */
-
- /* Check for open captures before ACCEPT and close those that are within
- the same assertion level, also converting ACCEPT to ASSERT_ACCEPT in an
- assertion. In the first pass, just accumulate the length required;
- otherwise hitting (*ACCEPT) inside many nested parentheses can cause
- workspace overflow. Do not set firstcu after *ACCEPT. */
-
- case META_ACCEPT:
- cb->had_accept = had_accept = TRUE;
- for (oc = cb->open_caps;
- oc != NULL && oc->assert_depth >= cb->assert_depth;
- oc = oc->next)
- {
- if (lengthptr != NULL)
- {
- *lengthptr += CU2BYTES(1) + IMM2_SIZE;
- }
- else
- {
- *code++ = OP_CLOSE;
- PUT2INC(code, 0, oc->number);
- }
- }
- *code++ = (cb->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT;
- if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
- break;
-
- case META_PRUNE:
- case META_SKIP:
- cb->had_pruneorskip = TRUE;
- /* Fall through */
- case META_COMMIT:
- case META_FAIL:
- *code++ = verbops[(meta - META_MARK) >> 16];
- break;
-
- case META_THEN:
- cb->external_flags |= PCRE2_HASTHEN;
- *code++ = OP_THEN;
- break;
-
- /* Handle verbs with arguments. Arguments can be very long, especially in
- 16- and 32-bit modes, and can overflow the workspace in the first pass.
- However, the argument length is constrained to be small enough to fit in
- one code unit. This check happens in parse_regex(). In the first pass,
- instead of putting the argument into memory, we just update the length
- counter and set up an empty argument. */
-
- case META_THEN_ARG:
- cb->external_flags |= PCRE2_HASTHEN;
- goto VERB_ARG;
-
- case META_PRUNE_ARG:
- case META_SKIP_ARG:
- cb->had_pruneorskip = TRUE;
- /* Fall through */
- case META_MARK:
- case META_COMMIT_ARG:
- VERB_ARG:
- *code++ = verbops[(meta - META_MARK) >> 16];
- /* The length is in characters. */
- verbarglen = *(++pptr);
- verbculen = 0;
- tempcode = code++;
- for (int i = 0; i < (int)verbarglen; i++)
- {
- meta = *(++pptr);
-#ifdef SUPPORT_UNICODE
- if (utf) mclength = PRIV(ord2utf)(meta, mcbuffer); else
-#endif
- {
- mclength = 1;
- mcbuffer[0] = meta;
- }
- if (lengthptr != NULL) *lengthptr += mclength; else
- {
- memcpy(code, mcbuffer, CU2BYTES(mclength));
- code += mclength;
- verbculen += mclength;
- }
- }
-
- *tempcode = verbculen; /* Fill in the code unit length */
- *code++ = 0; /* Terminating zero */
- break;
-
-
- /* ===================================================================*/
- /* Handle options change. The new setting must be passed back for use in
- subsequent branches. Reset the greedy defaults and the case value for
- firstcu and reqcu. */
-
- case META_OPTIONS:
- *optionsptr = options = *(++pptr);
- greedy_default = ((options & PCRE2_UNGREEDY) != 0);
- greedy_non_default = greedy_default ^ 1;
- req_caseopt = ((options & PCRE2_CASELESS) != 0)? REQ_CASELESS : 0;
- break;
-
-
- /* ===================================================================*/
- /* Handle conditional subpatterns. The case of (?(Rdigits) is ambiguous
- because it could be a numerical check on recursion, or a name check on a
- group's being set. The pre-pass sets up META_COND_RNUMBER as a name so that
- we can handle it either way. We first try for a name; if not found, process
- the number. */
-
- case META_COND_RNUMBER: /* (?(Rdigits) */
- case META_COND_NAME: /* (?(name) or (?'name') or ?(<name>) */
- case META_COND_RNAME: /* (?(R&name) - test for recursion */
- bravalue = OP_COND;
- {
- int count, index;
- unsigned int i;
- PCRE2_SPTR name;
- named_group *ng = cb->named_groups;
- uint32_t length = *(++pptr);
-
- GETPLUSOFFSET(offset, pptr);
- name = cb->start_pattern + offset;
-
- /* In the first pass, the names generated in the pre-pass are available,
- but the main name table has not yet been created. Scan the list of names
- generated in the pre-pass in order to get a number and whether or not
- this name is duplicated. If it is not duplicated, we can handle it as a
- numerical group. */
-
- for (i = 0; i < cb->names_found; i++, ng++)
- {
- if (length == ng->length &&
- PRIV(strncmp)(name, ng->name, length) == 0)
- {
- if (!ng->isdup)
- {
- code[1+LINK_SIZE] = (meta == META_COND_RNAME)? OP_RREF : OP_CREF;
- PUT2(code, 2+LINK_SIZE, ng->number);
- if (ng->number > cb->top_backref) cb->top_backref = ng->number;
- skipunits = 1+IMM2_SIZE;
- goto GROUP_PROCESS_NOTE_EMPTY;
- }
- break; /* Found a duplicated name */
- }
- }
-
- /* If the name was not found we have a bad reference, unless we are
- dealing with R<digits>, which is treated as a recursion test by number.
- */
-
- if (i >= cb->names_found)
- {
- groupnumber = 0;
- if (meta == META_COND_RNUMBER)
- {
- for (i = 1; i < length; i++)
- {
- groupnumber = groupnumber * 10 + name[i] - CHAR_0;
- if (groupnumber > MAX_GROUP_NUMBER)
- {
- *errorcodeptr = ERR61;
- cb->erroroffset = offset + i;
- return 0;
- }
- }
- }
-
- if (meta != META_COND_RNUMBER || groupnumber > cb->bracount)
- {
- *errorcodeptr = ERR15;
- cb->erroroffset = offset;
- return 0;
- }
-
- /* (?Rdigits) treated as a recursion reference by number. A value of
- zero (which is the result of both (?R) and (?R0)) means "any", and is
- translated into RREF_ANY (which is 0xffff). */
-
- if (groupnumber == 0) groupnumber = RREF_ANY;
- code[1+LINK_SIZE] = OP_RREF;
- PUT2(code, 2+LINK_SIZE, groupnumber);
- skipunits = 1+IMM2_SIZE;
- goto GROUP_PROCESS_NOTE_EMPTY;
- }
-
- /* A duplicated name was found. Note that if an R<digits> name is found
- (META_COND_RNUMBER), it is a reference test, not a recursion test. */
-
- code[1+LINK_SIZE] = (meta == META_COND_RNAME)? OP_RREF : OP_CREF;
-
- /* We have a duplicated name. In the compile pass we have to search the
- main table in order to get the index and count values. */
-
- count = 0; /* Values for first pass (avoids compiler warning) */
- index = 0;
- if (lengthptr == NULL && !find_dupname_details(name, length, &index,
- &count, errorcodeptr, cb)) return 0;
-
- /* Add one to the opcode to change CREF/RREF into DNCREF/DNRREF and
- insert appropriate data values. */
-
- code[1+LINK_SIZE]++;
- skipunits = 1+2*IMM2_SIZE;
- PUT2(code, 2+LINK_SIZE, index);
- PUT2(code, 2+LINK_SIZE+IMM2_SIZE, count);
- }
- goto GROUP_PROCESS_NOTE_EMPTY;
-
- /* The DEFINE condition is always false. Its internal groups may never
- be called, so matched_char must remain false, hence the jump to
- GROUP_PROCESS rather than GROUP_PROCESS_NOTE_EMPTY. */
-
- case META_COND_DEFINE:
- bravalue = OP_COND;
- GETPLUSOFFSET(offset, pptr);
- code[1+LINK_SIZE] = OP_DEFINE;
- skipunits = 1;
- goto GROUP_PROCESS;
-
- /* Conditional test of a group's being set. */
-
- case META_COND_NUMBER:
- bravalue = OP_COND;
- GETPLUSOFFSET(offset, pptr);
- groupnumber = *(++pptr);
- if (groupnumber > cb->bracount)
- {
- *errorcodeptr = ERR15;
- cb->erroroffset = offset;
- return 0;
- }
- if (groupnumber > cb->top_backref) cb->top_backref = groupnumber;
- offset -= 2; /* Point at initial ( for too many branches error */
- code[1+LINK_SIZE] = OP_CREF;
- skipunits = 1+IMM2_SIZE;
- PUT2(code, 2+LINK_SIZE, groupnumber);
- goto GROUP_PROCESS_NOTE_EMPTY;
-
- /* Test for the PCRE2 version. */
-
- case META_COND_VERSION:
- bravalue = OP_COND;
- if (pptr[1] > 0)
- code[1+LINK_SIZE] = ((PCRE2_MAJOR > pptr[2]) ||
- (PCRE2_MAJOR == pptr[2] && PCRE2_MINOR >= pptr[3]))?
- OP_TRUE : OP_FALSE;
- else
- code[1+LINK_SIZE] = (PCRE2_MAJOR == pptr[2] && PCRE2_MINOR == pptr[3])?
- OP_TRUE : OP_FALSE;
- skipunits = 1;
- pptr += 3;
- goto GROUP_PROCESS_NOTE_EMPTY;
-
- /* The condition is an assertion, possibly preceded by a callout. */
-
- case META_COND_ASSERT:
- bravalue = OP_COND;
- goto GROUP_PROCESS_NOTE_EMPTY;
-
-
- /* ===================================================================*/
- /* Handle all kinds of nested bracketed groups. The non-capturing,
- non-conditional cases are here; others come to GROUP_PROCESS via goto. */
-
- case META_LOOKAHEAD:
- bravalue = OP_ASSERT;
- cb->assert_depth += 1;
- goto GROUP_PROCESS;
-
- case META_LOOKAHEAD_NA:
- bravalue = OP_ASSERT_NA;
- cb->assert_depth += 1;
- goto GROUP_PROCESS;
-
- /* Optimize (?!) to (*FAIL) unless it is quantified - which is a weird
- thing to do, but Perl allows all assertions to be quantified, and when
- they contain capturing parentheses there may be a potential use for
- this feature. Not that that applies to a quantified (?!) but we allow
- it for uniformity. */
-
- case META_LOOKAHEADNOT:
- if (pptr[1] == META_KET &&
- (pptr[2] < META_ASTERISK || pptr[2] > META_MINMAX_QUERY))
- {
- *code++ = OP_FAIL;
- pptr++;
- }
- else
- {
- bravalue = OP_ASSERT_NOT;
- cb->assert_depth += 1;
- goto GROUP_PROCESS;
- }
- break;
-
- case META_LOOKBEHIND:
- bravalue = OP_ASSERTBACK;
- cb->assert_depth += 1;
- goto GROUP_PROCESS;
-
- case META_LOOKBEHINDNOT:
- bravalue = OP_ASSERTBACK_NOT;
- cb->assert_depth += 1;
- goto GROUP_PROCESS;
-
- case META_LOOKBEHIND_NA:
- bravalue = OP_ASSERTBACK_NA;
- cb->assert_depth += 1;
- goto GROUP_PROCESS;
-
- case META_ATOMIC:
- bravalue = OP_ONCE;
- goto GROUP_PROCESS_NOTE_EMPTY;
-
- case META_SCRIPT_RUN:
- bravalue = OP_SCRIPT_RUN;
- goto GROUP_PROCESS_NOTE_EMPTY;
-
- case META_NOCAPTURE:
- bravalue = OP_BRA;
- /* Fall through */
-
- /* Process nested bracketed regex. The nesting depth is maintained for the
- benefit of the stackguard function. The test for too deep nesting is now
- done in parse_regex(). Assertion and DEFINE groups come to GROUP_PROCESS;
- others come to GROUP_PROCESS_NOTE_EMPTY, to indicate that we need to take
- note of whether or not they may match an empty string. */
-
- GROUP_PROCESS_NOTE_EMPTY:
- note_group_empty = TRUE;
-
- GROUP_PROCESS:
- cb->parens_depth += 1;
- *code = bravalue;
- pptr++;
- tempcode = code;
- tempreqvary = cb->req_varyopt; /* Save value before group */
- length_prevgroup = 0; /* Initialize for pre-compile phase */
-
- if ((group_return =
- compile_regex(
- options, /* The option state */
- &tempcode, /* Where to put code (updated) */
- &pptr, /* Input pointer (updated) */
- errorcodeptr, /* Where to put an error message */
- skipunits, /* Skip over bracket number */
- &subfirstcu, /* For possible first char */
- &subfirstcuflags,
- &subreqcu, /* For possible last char */
- &subreqcuflags,
- bcptr, /* Current branch chain */
- cb, /* Compile data block */
- (lengthptr == NULL)? NULL : /* Actual compile phase */
- &length_prevgroup /* Pre-compile phase */
- )) == 0)
- return 0; /* Error */
-
- cb->parens_depth -= 1;
-
- /* If that was a non-conditional significant group (not an assertion, not a
- DEFINE) that matches at least one character, then the current item matches
- a character. Conditionals are handled below. */
-
- if (note_group_empty && bravalue != OP_COND && group_return > 0)
- matched_char = TRUE;
-
- /* If we've just compiled an assertion, pop the assert depth. */
-
- if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NA)
- cb->assert_depth -= 1;
-
- /* At the end of compiling, code is still pointing to the start of the
- group, while tempcode has been updated to point past the end of the group.
- The parsed pattern pointer (pptr) is on the closing META_KET.
-
- If this is a conditional bracket, check that there are no more than
- two branches in the group, or just one if it's a DEFINE group. We do this
- in the real compile phase, not in the pre-pass, where the whole group may
- not be available. */
-
- if (bravalue == OP_COND && lengthptr == NULL)
- {
- PCRE2_UCHAR *tc = code;
- int condcount = 0;
-
- do {
- condcount++;
- tc += GET(tc,1);
- }
- while (*tc != OP_KET);
-
- /* A DEFINE group is never obeyed inline (the "condition" is always
- false). It must have only one branch. Having checked this, change the
- opcode to OP_FALSE. */
-
- if (code[LINK_SIZE+1] == OP_DEFINE)
- {
- if (condcount > 1)
- {
- cb->erroroffset = offset;
- *errorcodeptr = ERR54;
- return 0;
- }
- code[LINK_SIZE+1] = OP_FALSE;
- bravalue = OP_DEFINE; /* A flag to suppress char handling below */
- }
-
- /* A "normal" conditional group. If there is just one branch, we must not
- make use of its firstcu or reqcu, because this is equivalent to an
- empty second branch. Also, it may match an empty string. If there are two
- branches, this item must match a character if the group must. */
-
- else
- {
- if (condcount > 2)
- {
- cb->erroroffset = offset;
- *errorcodeptr = ERR27;
- return 0;
- }
- if (condcount == 1) subfirstcuflags = subreqcuflags = REQ_NONE;
- else if (group_return > 0) matched_char = TRUE;
- }
- }
-
- /* In the pre-compile phase, update the length by the length of the group,
- less the brackets at either end. Then reduce the compiled code to just a
- set of non-capturing brackets so that it doesn't use much memory if it is
- duplicated by a quantifier.*/
-
- if (lengthptr != NULL)
- {
- if (OFLOW_MAX - *lengthptr < length_prevgroup - 2 - 2*LINK_SIZE)
- {
- *errorcodeptr = ERR20;
- return 0;
- }
- *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE;
- code++; /* This already contains bravalue */
- PUTINC(code, 0, 1 + LINK_SIZE);
- *code++ = OP_KET;
- PUTINC(code, 0, 1 + LINK_SIZE);
- break; /* No need to waste time with special character handling */
- }
-
- /* Otherwise update the main code pointer to the end of the group. */
-
- code = tempcode;
-
- /* For a DEFINE group, required and first character settings are not
- relevant. */
-
- if (bravalue == OP_DEFINE) break;
-
- /* Handle updating of the required and first code units for other types of
- group. Update for normal brackets of all kinds, and conditions with two
- branches (see code above). If the bracket is followed by a quantifier with
- zero repeat, we have to back off. Hence the definition of zeroreqcu and
- zerofirstcu outside the main loop so that they can be accessed for the back
- off. */
-
- zeroreqcu = reqcu;
- zeroreqcuflags = reqcuflags;
- zerofirstcu = firstcu;
- zerofirstcuflags = firstcuflags;
- groupsetfirstcu = FALSE;
-
- if (bravalue >= OP_ONCE) /* Not an assertion */
- {
- /* If we have not yet set a firstcu in this branch, take it from the
- subpattern, remembering that it was set here so that a repeat of more
- than one can replicate it as reqcu if necessary. If the subpattern has
- no firstcu, set "none" for the whole branch. In both cases, a zero
- repeat forces firstcu to "none". */
-
- if (firstcuflags == REQ_UNSET && subfirstcuflags != REQ_UNSET)
- {
- if (subfirstcuflags < REQ_NONE)
- {
- firstcu = subfirstcu;
- firstcuflags = subfirstcuflags;
- groupsetfirstcu = TRUE;
- }
- else firstcuflags = REQ_NONE;
- zerofirstcuflags = REQ_NONE;
- }
-
- /* If firstcu was previously set, convert the subpattern's firstcu
- into reqcu if there wasn't one, using the vary flag that was in
- existence beforehand. */
-
- else if (subfirstcuflags < REQ_NONE && subreqcuflags >= REQ_NONE)
- {
- subreqcu = subfirstcu;
- subreqcuflags = subfirstcuflags | tempreqvary;
- }
-
- /* If the subpattern set a required code unit (or set a first code unit
- that isn't really the first code unit - see above), set it. */
-
- if (subreqcuflags < REQ_NONE)
- {
- reqcu = subreqcu;
- reqcuflags = subreqcuflags;
- }
- }
-
- /* For a forward assertion, we take the reqcu, if set, provided that the
- group has also set a firstcu. This can be helpful if the pattern that
- follows the assertion doesn't set a different char. For example, it's
- useful for /(?=abcde).+/. We can't set firstcu for an assertion, however
- because it leads to incorrect effect for patterns such as /(?=a)a.+/ when
- the "real" "a" would then become a reqcu instead of a firstcu. This is
- overcome by a scan at the end if there's no firstcu, looking for an
- asserted first char. A similar effect for patterns like /(?=.*X)X$/ means
- we must only take the reqcu when the group also set a firstcu. Otherwise,
- in that example, 'X' ends up set for both. */
-
- else if ((bravalue == OP_ASSERT || bravalue == OP_ASSERT_NA) &&
- subreqcuflags < REQ_NONE && subfirstcuflags < REQ_NONE)
- {
- reqcu = subreqcu;
- reqcuflags = subreqcuflags;
- }
-
- break; /* End of nested group handling */
-
-
- /* ===================================================================*/
- /* Handle named backreferences and recursions. */
-
- case META_BACKREF_BYNAME:
- case META_RECURSE_BYNAME:
- {
- int count, index;
- PCRE2_SPTR name;
- BOOL is_dupname = FALSE;
- named_group *ng = cb->named_groups;
- uint32_t length = *(++pptr);
-
- GETPLUSOFFSET(offset, pptr);
- name = cb->start_pattern + offset;
-
- /* In the first pass, the names generated in the pre-pass are available,
- but the main name table has not yet been created. Scan the list of names
- generated in the pre-pass in order to get a number and whether or not
- this name is duplicated. */
-
- groupnumber = 0;
- for (unsigned int i = 0; i < cb->names_found; i++, ng++)
- {
- if (length == ng->length &&
- PRIV(strncmp)(name, ng->name, length) == 0)
- {
- is_dupname = ng->isdup;
- groupnumber = ng->number;
-
- /* For a recursion, that's all that is needed. We can now go to
- the code that handles numerical recursion, applying it to the first
- group with the given name. */
-
- if (meta == META_RECURSE_BYNAME)
- {
- meta_arg = groupnumber;
- goto HANDLE_NUMERICAL_RECURSION;
- }
-
- /* For a back reference, update the back reference map and the
- maximum back reference. */
-
- cb->backref_map |= (groupnumber < 32)? (1u << groupnumber) : 1;
- if (groupnumber > cb->top_backref)
- cb->top_backref = groupnumber;
- }
- }
-
- /* If the name was not found we have a bad reference. */
-
- if (groupnumber == 0)
- {
- *errorcodeptr = ERR15;
- cb->erroroffset = offset;
- return 0;
- }
-
- /* If a back reference name is not duplicated, we can handle it as
- a numerical reference. */
-
- if (!is_dupname)
- {
- meta_arg = groupnumber;
- goto HANDLE_SINGLE_REFERENCE;
- }
-
- /* If a back reference name is duplicated, we generate a different
- opcode to a numerical back reference. In the second pass we must
- search for the index and count in the final name table. */
-
- count = 0; /* Values for first pass (avoids compiler warning) */
- index = 0;
- if (lengthptr == NULL && !find_dupname_details(name, length, &index,
- &count, errorcodeptr, cb)) return 0;
-
- if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
- *code++ = ((options & PCRE2_CASELESS) != 0)? OP_DNREFI : OP_DNREF;
- PUT2INC(code, 0, index);
- PUT2INC(code, 0, count);
- }
- break;
-
-
- /* ===================================================================*/
- /* Handle a numerical callout. */
-
- case META_CALLOUT_NUMBER:
- code[0] = OP_CALLOUT;
- PUT(code, 1, pptr[1]); /* Offset to next pattern item */
- PUT(code, 1 + LINK_SIZE, pptr[2]); /* Length of next pattern item */
- code[1 + 2*LINK_SIZE] = pptr[3];
- pptr += 3;
- code += PRIV(OP_lengths)[OP_CALLOUT];
- break;
-
-
- /* ===================================================================*/
- /* Handle a callout with a string argument. In the pre-pass we just compute
- the length without generating anything. The length in pptr[3] includes both
- delimiters; in the actual compile only the first one is copied, but a
- terminating zero is added. Any doubled delimiters within the string make
- this an overestimate, but it is not worth bothering about. */
-
- case META_CALLOUT_STRING:
- if (lengthptr != NULL)
- {
- *lengthptr += pptr[3] + (1 + 4*LINK_SIZE);
- pptr += 3;
- SKIPOFFSET(pptr);
- }
-
- /* In the real compile we can copy the string. The starting delimiter is
- included so that the client can discover it if they want. We also pass the
- start offset to help a script language give better error messages. */
-
- else
- {
- PCRE2_SPTR pp;
- uint32_t delimiter;
- uint32_t length = pptr[3];
- PCRE2_UCHAR *callout_string = code + (1 + 4*LINK_SIZE);
-
- code[0] = OP_CALLOUT_STR;
- PUT(code, 1, pptr[1]); /* Offset to next pattern item */
- PUT(code, 1 + LINK_SIZE, pptr[2]); /* Length of next pattern item */
-
- pptr += 3;
- GETPLUSOFFSET(offset, pptr); /* Offset to string in pattern */
- pp = cb->start_pattern + offset;
- delimiter = *callout_string++ = *pp++;
- if (delimiter == CHAR_LEFT_CURLY_BRACKET)
- delimiter = CHAR_RIGHT_CURLY_BRACKET;
- PUT(code, 1 + 3*LINK_SIZE, (int)(offset + 1)); /* One after delimiter */
-
- /* The syntax of the pattern was checked in the parsing scan. The length
- includes both delimiters, but we have passed the opening one just above,
- so we reduce length before testing it. The test is for > 1 because we do
- not want to copy the final delimiter. This also ensures that pp[1] is
- accessible. */
-
- while (--length > 1)
- {
- if (*pp == delimiter && pp[1] == delimiter)
- {
- *callout_string++ = delimiter;
- pp += 2;
- length--;
- }
- else *callout_string++ = *pp++;
- }
- *callout_string++ = CHAR_NUL;
-
- /* Set the length of the entire item, the advance to its end. */
-
- PUT(code, 1 + 2*LINK_SIZE, (int)(callout_string - code));
- code = callout_string;
- }
- break;
-
-
- /* ===================================================================*/
- /* Handle repetition. The different types are all sorted out in the parsing
- pass. */
-
- case META_MINMAX_PLUS:
- case META_MINMAX_QUERY:
- case META_MINMAX:
- repeat_min = *(++pptr);
- repeat_max = *(++pptr);
- goto REPEAT;
-
- case META_ASTERISK:
- case META_ASTERISK_PLUS:
- case META_ASTERISK_QUERY:
- repeat_min = 0;
- repeat_max = REPEAT_UNLIMITED;
- goto REPEAT;
-
- case META_PLUS:
- case META_PLUS_PLUS:
- case META_PLUS_QUERY:
- repeat_min = 1;
- repeat_max = REPEAT_UNLIMITED;
- goto REPEAT;
-
- case META_QUERY:
- case META_QUERY_PLUS:
- case META_QUERY_QUERY:
- repeat_min = 0;
- repeat_max = 1;
-
- REPEAT:
- if (previous_matched_char && repeat_min > 0) matched_char = TRUE;
-
- /* Remember whether this is a variable length repeat, and default to
- single-char opcodes. */
-
- reqvary = (repeat_min == repeat_max)? 0 : REQ_VARY;
- op_type = 0;
-
- /* Adjust first and required code units for a zero repeat. */
-
- if (repeat_min == 0)
- {
- firstcu = zerofirstcu;
- firstcuflags = zerofirstcuflags;
- reqcu = zeroreqcu;
- reqcuflags = zeroreqcuflags;
- }
-
- /* Note the greediness and possessiveness. */
-
- switch (meta)
- {
- case META_MINMAX_PLUS:
- case META_ASTERISK_PLUS:
- case META_PLUS_PLUS:
- case META_QUERY_PLUS:
- repeat_type = 0; /* Force greedy */
- possessive_quantifier = TRUE;
- break;
-
- case META_MINMAX_QUERY:
- case META_ASTERISK_QUERY:
- case META_PLUS_QUERY:
- case META_QUERY_QUERY:
- repeat_type = greedy_non_default;
- possessive_quantifier = FALSE;
- break;
-
- default:
- repeat_type = greedy_default;
- possessive_quantifier = FALSE;
- break;
- }
-
- /* Save start of previous item, in case we have to move it up in order to
- insert something before it, and remember what it was. */
-
- tempcode = previous;
- op_previous = *previous;
-
- /* Now handle repetition for the different types of item. If the repeat
- minimum and the repeat maximum are both 1, we can ignore the quantifier for
- non-parenthesized items, as they have only one alternative. For anything in
- parentheses, we must not ignore if {1} is possessive. */
-
- switch (op_previous)
- {
- /* If previous was a character or negated character match, abolish the
- item and generate a repeat item instead. If a char item has a minimum of
- more than one, ensure that it is set in reqcu - it might not be if a
- sequence such as x{3} is the first thing in a branch because the x will
- have gone into firstcu instead. */
-
- case OP_CHAR:
- case OP_CHARI:
- case OP_NOT:
- case OP_NOTI:
- if (repeat_max == 1 && repeat_min == 1) goto END_REPEAT;
- op_type = chartypeoffset[op_previous - OP_CHAR];
-
- /* Deal with UTF characters that take up more than one code unit. */
-
-#ifdef MAYBE_UTF_MULTI
- if (utf && NOT_FIRSTCU(code[-1]))
- {
- PCRE2_UCHAR *lastchar = code - 1;
- BACKCHAR(lastchar);
- mclength = (uint32_t)(code - lastchar); /* Length of UTF character */
- memcpy(mcbuffer, lastchar, CU2BYTES(mclength)); /* Save the char */
- }
- else
-#endif /* MAYBE_UTF_MULTI */
-
- /* Handle the case of a single code unit - either with no UTF support, or
- with UTF disabled, or for a single-code-unit UTF character. In the latter
- case, for a repeated positive match, get the caseless flag for the
- required code unit from the previous character, because a class like [Aa]
- sets a caseless A but by now the req_caseopt flag has been reset. */
-
- {
- mcbuffer[0] = code[-1];
- mclength = 1;
- if (op_previous <= OP_CHARI && repeat_min > 1)
- {
- reqcu = mcbuffer[0];
- reqcuflags = cb->req_varyopt;
- if (op_previous == OP_CHARI) reqcuflags |= REQ_CASELESS;
- }
- }
- goto OUTPUT_SINGLE_REPEAT; /* Code shared with single character types */
-
- /* If previous was a character class or a back reference, we put the
- repeat stuff after it, but just skip the item if the repeat was {0,0}. */
-
-#ifdef SUPPORT_WIDE_CHARS
- case OP_XCLASS:
-#endif
- case OP_CLASS:
- case OP_NCLASS:
- case OP_REF:
- case OP_REFI:
- case OP_DNREF:
- case OP_DNREFI:
-
- if (repeat_max == 0)
- {
- code = previous;
- goto END_REPEAT;
- }
- if (repeat_max == 1 && repeat_min == 1) goto END_REPEAT;
-
- if (repeat_min == 0 && repeat_max == REPEAT_UNLIMITED)
- *code++ = OP_CRSTAR + repeat_type;
- else if (repeat_min == 1 && repeat_max == REPEAT_UNLIMITED)
- *code++ = OP_CRPLUS + repeat_type;
- else if (repeat_min == 0 && repeat_max == 1)
- *code++ = OP_CRQUERY + repeat_type;
- else
- {
- *code++ = OP_CRRANGE + repeat_type;
- PUT2INC(code, 0, repeat_min);
- if (repeat_max == REPEAT_UNLIMITED) repeat_max = 0; /* 2-byte encoding for max */
- PUT2INC(code, 0, repeat_max);
- }
- break;
-
- /* If previous is OP_FAIL, it was generated by an empty class []
- (PCRE2_ALLOW_EMPTY_CLASS is set). The other ways in which OP_FAIL can be
- generated, that is by (*FAIL) or (?!), disallow a quantifier at parse
- time. We can just ignore this repeat. */
-
- case OP_FAIL:
- goto END_REPEAT;
-
- /* Prior to 10.30, repeated recursions were wrapped in OP_ONCE brackets
- because pcre2_match() could not handle backtracking into recursively
- called groups. Now that this backtracking is available, we no longer need
- to do this. However, we still need to replicate recursions as we do for
- groups so as to have independent backtracking points. We can replicate
- for the minimum number of repeats directly. For optional repeats we now
- wrap the recursion in OP_BRA brackets and make use of the bracket
- repetition. */
-
- case OP_RECURSE:
- if (repeat_max == 1 && repeat_min == 1 && !possessive_quantifier)
- goto END_REPEAT;
-
- /* Generate unwrapped repeats for a non-zero minimum, except when the
- minimum is 1 and the maximum unlimited, because that can be handled with
- OP_BRA terminated by OP_KETRMAX/MIN. When the maximum is equal to the
- minimum, we just need to generate the appropriate additional copies.
- Otherwise we need to generate one more, to simulate the situation when
- the minimum is zero. */
-
- if (repeat_min > 0 && (repeat_min != 1 || repeat_max != REPEAT_UNLIMITED))
- {
- int replicate = repeat_min;
- if (repeat_min == repeat_max) replicate--;
-
- /* In the pre-compile phase, we don't actually do the replication. We
- just adjust the length as if we had. Do some paranoid checks for
- potential integer overflow. The INT64_OR_DOUBLE type is a 64-bit
- integer type when available, otherwise double. */
-
- if (lengthptr != NULL)
- {
- PCRE2_SIZE delta = replicate*(1 + LINK_SIZE);
- if ((INT64_OR_DOUBLE)replicate*
- (INT64_OR_DOUBLE)(1 + LINK_SIZE) >
- (INT64_OR_DOUBLE)INT_MAX ||
- OFLOW_MAX - *lengthptr < delta)
- {
- *errorcodeptr = ERR20;
- return 0;
- }
- *lengthptr += delta;
- }
-
- else for (int i = 0; i < replicate; i++)
- {
- memcpy(code, previous, CU2BYTES(1 + LINK_SIZE));
- previous = code;
- code += 1 + LINK_SIZE;
- }
-
- /* If the number of repeats is fixed, we are done. Otherwise, adjust
- the counts and fall through. */
-
- if (repeat_min == repeat_max) break;
- if (repeat_max != REPEAT_UNLIMITED) repeat_max -= repeat_min;
- repeat_min = 0;
- }
-
- /* Wrap the recursion call in OP_BRA brackets. */
-
- (void)memmove(previous + 1 + LINK_SIZE, previous, CU2BYTES(1 + LINK_SIZE));
- op_previous = *previous = OP_BRA;
- PUT(previous, 1, 2 + 2*LINK_SIZE);
- previous[2 + 2*LINK_SIZE] = OP_KET;
- PUT(previous, 3 + 2*LINK_SIZE, 2 + 2*LINK_SIZE);
- code += 2 + 2 * LINK_SIZE;
- length_prevgroup = 3 + 3*LINK_SIZE;
- group_return = -1; /* Set "may match empty string" */
-
- /* Now treat as a repeated OP_BRA. */
- /* Fall through */
-
- /* If previous was a bracket group, we may have to replicate it in
- certain cases. Note that at this point we can encounter only the "basic"
- bracket opcodes such as BRA and CBRA, as this is the place where they get
- converted into the more special varieties such as BRAPOS and SBRA.
- Originally, PCRE did not allow repetition of assertions, but now it does,
- for Perl compatibility. */
-
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERT_NA:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- case OP_ASSERTBACK_NA:
- case OP_ONCE:
- case OP_SCRIPT_RUN:
- case OP_BRA:
- case OP_CBRA:
- case OP_COND:
- {
- int len = (int)(code - previous);
- PCRE2_UCHAR *bralink = NULL;
- PCRE2_UCHAR *brazeroptr = NULL;
-
- if (repeat_max == 1 && repeat_min == 1 && !possessive_quantifier)
- goto END_REPEAT;
-
- /* Repeating a DEFINE group (or any group where the condition is always
- FALSE and there is only one branch) is pointless, but Perl allows the
- syntax, so we just ignore the repeat. */
-
- if (op_previous == OP_COND && previous[LINK_SIZE+1] == OP_FALSE &&
- previous[GET(previous, 1)] != OP_ALT)
- goto END_REPEAT;
-
- /* Perl allows all assertions to be quantified, and when they contain
- capturing parentheses and/or are optional there are potential uses for
- this feature. PCRE2 used to force the maximum quantifier to 1 on the
- invalid grounds that further repetition was never useful. This was
- always a bit pointless, since an assertion could be wrapped with a
- repeated group to achieve the effect. General repetition is now
- permitted, but if the maximum is unlimited it is set to one more than
- the minimum. */
-
- if (op_previous < OP_ONCE) /* Assertion */
- {
- if (repeat_max == REPEAT_UNLIMITED) repeat_max = repeat_min + 1;
- }
-
- /* The case of a zero minimum is special because of the need to stick
- OP_BRAZERO in front of it, and because the group appears once in the
- data, whereas in other cases it appears the minimum number of times. For
- this reason, it is simplest to treat this case separately, as otherwise
- the code gets far too messy. There are several special subcases when the
- minimum is zero. */
-
- if (repeat_min == 0)
- {
- /* If the maximum is also zero, we used to just omit the group from
- the output altogether, like this:
-
- ** if (repeat_max == 0)
- ** {
- ** code = previous;
- ** goto END_REPEAT;
- ** }
-
- However, that fails when a group or a subgroup within it is
- referenced as a subroutine from elsewhere in the pattern, so now we
- stick in OP_SKIPZERO in front of it so that it is skipped on
- execution. As we don't have a list of which groups are referenced, we
- cannot do this selectively.
-
- If the maximum is 1 or unlimited, we just have to stick in the
- BRAZERO and do no more at this point. */
-
- if (repeat_max <= 1 || repeat_max == REPEAT_UNLIMITED)
- {
- (void)memmove(previous + 1, previous, CU2BYTES(len));
- code++;
- if (repeat_max == 0)
- {
- *previous++ = OP_SKIPZERO;
- goto END_REPEAT;
- }
- brazeroptr = previous; /* Save for possessive optimizing */
- *previous++ = OP_BRAZERO + repeat_type;
- }
-
- /* If the maximum is greater than 1 and limited, we have to replicate
- in a nested fashion, sticking OP_BRAZERO before each set of brackets.
- The first one has to be handled carefully because it's the original
- copy, which has to be moved up. The remainder can be handled by code
- that is common with the non-zero minimum case below. We have to
- adjust the value or repeat_max, since one less copy is required. */
-
- else
- {
- int linkoffset;
- (void)memmove(previous + 2 + LINK_SIZE, previous, CU2BYTES(len));
- code += 2 + LINK_SIZE;
- *previous++ = OP_BRAZERO + repeat_type;
- *previous++ = OP_BRA;
-
- /* We chain together the bracket link offset fields that have to be
- filled in later when the ends of the brackets are reached. */
-
- linkoffset = (bralink == NULL)? 0 : (int)(previous - bralink);
- bralink = previous;
- PUTINC(previous, 0, linkoffset);
- }
-
- if (repeat_max != REPEAT_UNLIMITED) repeat_max--;
- }
-
- /* If the minimum is greater than zero, replicate the group as many
- times as necessary, and adjust the maximum to the number of subsequent
- copies that we need. */
-
- else
- {
- if (repeat_min > 1)
- {
- /* In the pre-compile phase, we don't actually do the replication.
- We just adjust the length as if we had. Do some paranoid checks for
- potential integer overflow. The INT64_OR_DOUBLE type is a 64-bit
- integer type when available, otherwise double. */
-
- if (lengthptr != NULL)
- {
- PCRE2_SIZE delta = (repeat_min - 1)*length_prevgroup;
- if ((INT64_OR_DOUBLE)(repeat_min - 1)*
- (INT64_OR_DOUBLE)length_prevgroup >
- (INT64_OR_DOUBLE)INT_MAX ||
- OFLOW_MAX - *lengthptr < delta)
- {
- *errorcodeptr = ERR20;
- return 0;
- }
- *lengthptr += delta;
- }
-
- /* This is compiling for real. If there is a set first code unit
- for the group, and we have not yet set a "required code unit", set
- it. */
-
- else
- {
- if (groupsetfirstcu && reqcuflags >= REQ_NONE)
- {
- reqcu = firstcu;
- reqcuflags = firstcuflags;
- }
- for (uint32_t i = 1; i < repeat_min; i++)
- {
- memcpy(code, previous, CU2BYTES(len));
- code += len;
- }
- }
- }
-
- if (repeat_max != REPEAT_UNLIMITED) repeat_max -= repeat_min;
- }
-
- /* This code is common to both the zero and non-zero minimum cases. If
- the maximum is limited, it replicates the group in a nested fashion,
- remembering the bracket starts on a stack. In the case of a zero
- minimum, the first one was set up above. In all cases the repeat_max
- now specifies the number of additional copies needed. Again, we must
- remember to replicate entries on the forward reference list. */
-
- if (repeat_max != REPEAT_UNLIMITED)
- {
- /* In the pre-compile phase, we don't actually do the replication. We
- just adjust the length as if we had. For each repetition we must add
- 1 to the length for BRAZERO and for all but the last repetition we
- must add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some
- paranoid checks to avoid integer overflow. The INT64_OR_DOUBLE type
- is a 64-bit integer type when available, otherwise double. */
-
- if (lengthptr != NULL && repeat_max > 0)
- {
- PCRE2_SIZE delta = repeat_max*(length_prevgroup + 1 + 2 + 2*LINK_SIZE) -
- 2 - 2*LINK_SIZE; /* Last one doesn't nest */
- if ((INT64_OR_DOUBLE)repeat_max *
- (INT64_OR_DOUBLE)(length_prevgroup + 1 + 2 + 2*LINK_SIZE)
- > (INT64_OR_DOUBLE)INT_MAX ||
- OFLOW_MAX - *lengthptr < delta)
- {
- *errorcodeptr = ERR20;
- return 0;
- }
- *lengthptr += delta;
- }
-
- /* This is compiling for real */
-
- else for (uint32_t i = repeat_max; i >= 1; i--)
- {
- *code++ = OP_BRAZERO + repeat_type;
-
- /* All but the final copy start a new nesting, maintaining the
- chain of brackets outstanding. */
-
- if (i != 1)
- {
- int linkoffset;
- *code++ = OP_BRA;
- linkoffset = (bralink == NULL)? 0 : (int)(code - bralink);
- bralink = code;
- PUTINC(code, 0, linkoffset);
- }
-
- memcpy(code, previous, CU2BYTES(len));
- code += len;
- }
-
- /* Now chain through the pending brackets, and fill in their length
- fields (which are holding the chain links pro tem). */
-
- while (bralink != NULL)
- {
- int oldlinkoffset;
- int linkoffset = (int)(code - bralink + 1);
- PCRE2_UCHAR *bra = code - linkoffset;
- oldlinkoffset = GET(bra, 1);
- bralink = (oldlinkoffset == 0)? NULL : bralink - oldlinkoffset;
- *code++ = OP_KET;
- PUTINC(code, 0, linkoffset);
- PUT(bra, 1, linkoffset);
- }
- }
-
- /* If the maximum is unlimited, set a repeater in the final copy. For
- SCRIPT_RUN and ONCE brackets, that's all we need to do. However,
- possessively repeated ONCE brackets can be converted into non-capturing
- brackets, as the behaviour of (?:xx)++ is the same as (?>xx)++ and this
- saves having to deal with possessive ONCEs specially.
-
- Otherwise, when we are doing the actual compile phase, check to see
- whether this group is one that could match an empty string. If so,
- convert the initial operator to the S form (e.g. OP_BRA -> OP_SBRA) so
- that runtime checking can be done. [This check is also applied to ONCE
- and SCRIPT_RUN groups at runtime, but in a different way.]
-
- Then, if the quantifier was possessive and the bracket is not a
- conditional, we convert the BRA code to the POS form, and the KET code
- to KETRPOS. (It turns out to be convenient at runtime to detect this
- kind of subpattern at both the start and at the end.) The use of
- special opcodes makes it possible to reduce greatly the stack usage in
- pcre2_match(). If the group is preceded by OP_BRAZERO, convert this to
- OP_BRAPOSZERO.
-
- Then, if the minimum number of matches is 1 or 0, cancel the possessive
- flag so that the default action below, of wrapping everything inside
- atomic brackets, does not happen. When the minimum is greater than 1,
- there will be earlier copies of the group, and so we still have to wrap
- the whole thing. */
-
- else
- {
- PCRE2_UCHAR *ketcode = code - 1 - LINK_SIZE;
- PCRE2_UCHAR *bracode = ketcode - GET(ketcode, 1);
-
- /* Convert possessive ONCE brackets to non-capturing */
-
- if (*bracode == OP_ONCE && possessive_quantifier) *bracode = OP_BRA;
-
- /* For non-possessive ONCE and for SCRIPT_RUN brackets, all we need
- to do is to set the KET. */
-
- if (*bracode == OP_ONCE || *bracode == OP_SCRIPT_RUN)
- *ketcode = OP_KETRMAX + repeat_type;
-
- /* Handle non-SCRIPT_RUN and non-ONCE brackets and possessive ONCEs
- (which have been converted to non-capturing above). */
-
- else
- {
- /* In the compile phase, adjust the opcode if the group can match
- an empty string. For a conditional group with only one branch, the
- value of group_return will not show "could be empty", so we must
- check that separately. */
-
- if (lengthptr == NULL)
- {
- if (group_return < 0) *bracode += OP_SBRA - OP_BRA;
- if (*bracode == OP_COND && bracode[GET(bracode,1)] != OP_ALT)
- *bracode = OP_SCOND;
- }
-
- /* Handle possessive quantifiers. */
-
- if (possessive_quantifier)
- {
- /* For COND brackets, we wrap the whole thing in a possessively
- repeated non-capturing bracket, because we have not invented POS
- versions of the COND opcodes. */
-
- if (*bracode == OP_COND || *bracode == OP_SCOND)
- {
- int nlen = (int)(code - bracode);
- (void)memmove(bracode + 1 + LINK_SIZE, bracode, CU2BYTES(nlen));
- code += 1 + LINK_SIZE;
- nlen += 1 + LINK_SIZE;
- *bracode = (*bracode == OP_COND)? OP_BRAPOS : OP_SBRAPOS;
- *code++ = OP_KETRPOS;
- PUTINC(code, 0, nlen);
- PUT(bracode, 1, nlen);
- }
-
- /* For non-COND brackets, we modify the BRA code and use KETRPOS. */
-
- else
- {
- *bracode += 1; /* Switch to xxxPOS opcodes */
- *ketcode = OP_KETRPOS;
- }
-
- /* If the minimum is zero, mark it as possessive, then unset the
- possessive flag when the minimum is 0 or 1. */
-
- if (brazeroptr != NULL) *brazeroptr = OP_BRAPOSZERO;
- if (repeat_min < 2) possessive_quantifier = FALSE;
- }
-
- /* Non-possessive quantifier */
-
- else *ketcode = OP_KETRMAX + repeat_type;
- }
- }
- }
- break;
-
- /* If previous was a character type match (\d or similar), abolish it and
- create a suitable repeat item. The code is shared with single-character
- repeats by setting op_type to add a suitable offset into repeat_type.
- Note the the Unicode property types will be present only when
- SUPPORT_UNICODE is defined, but we don't wrap the little bits of code
- here because it just makes it horribly messy. */
-
- default:
- if (op_previous >= OP_EODN) /* Not a character type - internal error */
- {
- *errorcodeptr = ERR10;
- return 0;
- }
- else
- {
- int prop_type, prop_value;
- PCRE2_UCHAR *oldcode;
-
- if (repeat_max == 1 && repeat_min == 1) goto END_REPEAT;
-
- op_type = OP_TYPESTAR - OP_STAR; /* Use type opcodes */
- mclength = 0; /* Not a character */
-
- if (op_previous == OP_PROP || op_previous == OP_NOTPROP)
- {
- prop_type = previous[1];
- prop_value = previous[2];
- }
- else
- {
- /* Come here from just above with a character in mcbuffer/mclength. */
- OUTPUT_SINGLE_REPEAT:
- prop_type = prop_value = -1;
- }
-
- /* At this point, if prop_type == prop_value == -1 we either have a
- character in mcbuffer when mclength is greater than zero, or we have
- mclength zero, in which case there is a non-property character type in
- op_previous. If prop_type/value are not negative, we have a property
- character type in op_previous. */
-
- oldcode = code; /* Save where we were */
- code = previous; /* Usually overwrite previous item */
-
- /* If the maximum is zero then the minimum must also be zero; Perl allows
- this case, so we do too - by simply omitting the item altogether. */
-
- if (repeat_max == 0) goto END_REPEAT;
-
- /* Combine the op_type with the repeat_type */
-
- repeat_type += op_type;
-
- /* A minimum of zero is handled either as the special case * or ?, or as
- an UPTO, with the maximum given. */
-
- if (repeat_min == 0)
- {
- if (repeat_max == REPEAT_UNLIMITED) *code++ = OP_STAR + repeat_type;
- else if (repeat_max == 1) *code++ = OP_QUERY + repeat_type;
- else
- {
- *code++ = OP_UPTO + repeat_type;
- PUT2INC(code, 0, repeat_max);
- }
- }
-
- /* A repeat minimum of 1 is optimized into some special cases. If the
- maximum is unlimited, we use OP_PLUS. Otherwise, the original item is
- left in place and, if the maximum is greater than 1, we use OP_UPTO with
- one less than the maximum. */
-
- else if (repeat_min == 1)
- {
- if (repeat_max == REPEAT_UNLIMITED)
- *code++ = OP_PLUS + repeat_type;
- else
- {
- code = oldcode; /* Leave previous item in place */
- if (repeat_max == 1) goto END_REPEAT;
- *code++ = OP_UPTO + repeat_type;
- PUT2INC(code, 0, repeat_max - 1);
- }
- }
-
- /* The case {n,n} is just an EXACT, while the general case {n,m} is
- handled as an EXACT followed by an UPTO or STAR or QUERY. */
-
- else
- {
- *code++ = OP_EXACT + op_type; /* NB EXACT doesn't have repeat_type */
- PUT2INC(code, 0, repeat_min);
-
- /* Unless repeat_max equals repeat_min, fill in the data for EXACT,
- and then generate the second opcode. For a repeated Unicode property
- match, there are two extra values that define the required property,
- and mclength is set zero to indicate this. */
-
- if (repeat_max != repeat_min)
- {
- if (mclength > 0)
- {
- memcpy(code, mcbuffer, CU2BYTES(mclength));
- code += mclength;
- }
- else
- {
- *code++ = op_previous;
- if (prop_type >= 0)
- {
- *code++ = prop_type;
- *code++ = prop_value;
- }
- }
-
- /* Now set up the following opcode */
-
- if (repeat_max == REPEAT_UNLIMITED)
- *code++ = OP_STAR + repeat_type;
- else
- {
- repeat_max -= repeat_min;
- if (repeat_max == 1)
- {
- *code++ = OP_QUERY + repeat_type;
- }
- else
- {
- *code++ = OP_UPTO + repeat_type;
- PUT2INC(code, 0, repeat_max);
- }
- }
- }
- }
-
- /* Fill in the character or character type for the final opcode. */
-
- if (mclength > 0)
- {
- memcpy(code, mcbuffer, CU2BYTES(mclength));
- code += mclength;
- }
- else
- {
- *code++ = op_previous;
- if (prop_type >= 0)
- {
- *code++ = prop_type;
- *code++ = prop_value;
- }
- }
- }
- break;
- } /* End of switch on different op_previous values */
-
-
- /* If the character following a repeat is '+', possessive_quantifier is
- TRUE. For some opcodes, there are special alternative opcodes for this
- case. For anything else, we wrap the entire repeated item inside OP_ONCE
- brackets. Logically, the '+' notation is just syntactic sugar, taken from
- Sun's Java package, but the special opcodes can optimize it.
-
- Some (but not all) possessively repeated subpatterns have already been
- completely handled in the code just above. For them, possessive_quantifier
- is always FALSE at this stage. Note that the repeated item starts at
- tempcode, not at previous, which might be the first part of a string whose
- (former) last char we repeated. */
-
- if (possessive_quantifier)
- {
- int len;
-
- /* Possessifying an EXACT quantifier has no effect, so we can ignore it.
- However, QUERY, STAR, or UPTO may follow (for quantifiers such as {5,6},
- {5,}, or {5,10}). We skip over an EXACT item; if the length of what
- remains is greater than zero, there's a further opcode that can be
- handled. If not, do nothing, leaving the EXACT alone. */
-
- switch(*tempcode)
- {
- case OP_TYPEEXACT:
- tempcode += PRIV(OP_lengths)[*tempcode] +
- ((tempcode[1 + IMM2_SIZE] == OP_PROP
- || tempcode[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0);
- break;
-
- /* CHAR opcodes are used for exacts whose count is 1. */
-
- case OP_CHAR:
- case OP_CHARI:
- case OP_NOT:
- case OP_NOTI:
- case OP_EXACT:
- case OP_EXACTI:
- case OP_NOTEXACT:
- case OP_NOTEXACTI:
- tempcode += PRIV(OP_lengths)[*tempcode];
-#ifdef SUPPORT_UNICODE
- if (utf && HAS_EXTRALEN(tempcode[-1]))
- tempcode += GET_EXTRALEN(tempcode[-1]);
-#endif
- break;
-
- /* For the class opcodes, the repeat operator appears at the end;
- adjust tempcode to point to it. */
-
- case OP_CLASS:
- case OP_NCLASS:
- tempcode += 1 + 32/sizeof(PCRE2_UCHAR);
- break;
-
-#ifdef SUPPORT_WIDE_CHARS
- case OP_XCLASS:
- tempcode += GET(tempcode, 1);
- break;
-#endif
- }
-
- /* If tempcode is equal to code (which points to the end of the repeated
- item), it means we have skipped an EXACT item but there is no following
- QUERY, STAR, or UPTO; the value of len will be 0, and we do nothing. In
- all other cases, tempcode will be pointing to the repeat opcode, and will
- be less than code, so the value of len will be greater than 0. */
-
- len = (int)(code - tempcode);
- if (len > 0)
- {
- unsigned int repcode = *tempcode;
-
- /* There is a table for possessifying opcodes, all of which are less
- than OP_CALLOUT. A zero entry means there is no possessified version.
- */
-
- if (repcode < OP_CALLOUT && opcode_possessify[repcode] > 0)
- *tempcode = opcode_possessify[repcode];
-
- /* For opcode without a special possessified version, wrap the item in
- ONCE brackets. */
-
- else
- {
- (void)memmove(tempcode + 1 + LINK_SIZE, tempcode, CU2BYTES(len));
- code += 1 + LINK_SIZE;
- len += 1 + LINK_SIZE;
- tempcode[0] = OP_ONCE;
- *code++ = OP_KET;
- PUTINC(code, 0, len);
- PUT(tempcode, 1, len);
- }
- }
- }
-
- /* We set the "follows varying string" flag for subsequently encountered
- reqcus if it isn't already set and we have just passed a varying length
- item. */
-
- END_REPEAT:
- cb->req_varyopt |= reqvary;
- break;
-
-
- /* ===================================================================*/
- /* Handle a 32-bit data character with a value greater than META_END. */
-
- case META_BIGVALUE:
- pptr++;
- goto NORMAL_CHAR;
-
-
- /* ===============================================================*/
- /* Handle a back reference by number, which is the meta argument. The
- pattern offsets for back references to group numbers less than 10 are held
- in a special vector, to avoid using more than two parsed pattern elements
- in 64-bit environments. We only need the offset to the first occurrence,
- because if that doesn't fail, subsequent ones will also be OK. */
-
- case META_BACKREF:
- if (meta_arg < 10) offset = cb->small_ref_offset[meta_arg];
- else GETPLUSOFFSET(offset, pptr);
-
- if (meta_arg > cb->bracount)
- {
- cb->erroroffset = offset;
- *errorcodeptr = ERR15; /* Non-existent subpattern */
- return 0;
- }
-
- /* Come here from named backref handling when the reference is to a
- single group (that is, not to a duplicated name). The back reference
- data will have already been updated. We must disable firstcu if not
- set, to cope with cases like (?=(\w+))\1: which would otherwise set ':'
- later. */
-
- HANDLE_SINGLE_REFERENCE:
- if (firstcuflags == REQ_UNSET) zerofirstcuflags = firstcuflags = REQ_NONE;
- *code++ = ((options & PCRE2_CASELESS) != 0)? OP_REFI : OP_REF;
- PUT2INC(code, 0, meta_arg);
-
- /* Update the map of back references, and keep the highest one. We
- could do this in parse_regex() for numerical back references, but not
- for named back references, because we don't know the numbers to which
- named back references refer. So we do it all in this function. */
-
- cb->backref_map |= (meta_arg < 32)? (1u << meta_arg) : 1;
- if (meta_arg > cb->top_backref) cb->top_backref = meta_arg;
- break;
-
-
- /* ===============================================================*/
- /* Handle recursion by inserting the number of the called group (which is
- the meta argument) after OP_RECURSE. At the end of compiling the pattern is
- scanned and these numbers are replaced by offsets within the pattern. It is
- done like this to avoid problems with forward references and adjusting
- offsets when groups are duplicated and moved (as discovered in previous
- implementations). Note that a recursion does not have a set first
- character. */
-
- case META_RECURSE:
- GETPLUSOFFSET(offset, pptr);
- if (meta_arg > cb->bracount)
- {
- cb->erroroffset = offset;
- *errorcodeptr = ERR15; /* Non-existent subpattern */
- return 0;
- }
- HANDLE_NUMERICAL_RECURSION:
- *code = OP_RECURSE;
- PUT(code, 1, meta_arg);
- code += 1 + LINK_SIZE;
- groupsetfirstcu = FALSE;
- cb->had_recurse = TRUE;
- if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
- zerofirstcu = firstcu;
- zerofirstcuflags = firstcuflags;
- break;
-
-
- /* ===============================================================*/
- /* Handle capturing parentheses; the number is the meta argument. */
-
- case META_CAPTURE:
- bravalue = OP_CBRA;
- skipunits = IMM2_SIZE;
- PUT2(code, 1+LINK_SIZE, meta_arg);
- cb->lastcapture = meta_arg;
- goto GROUP_PROCESS_NOTE_EMPTY;
-
-
- /* ===============================================================*/
- /* Handle escape sequence items. For ones like \d, the ESC_values are
- arranged to be the same as the corresponding OP_values in the default case
- when PCRE2_UCP is not set (which is the only case in which they will appear
- here).
-
- Note: \Q and \E are never seen here, as they were dealt with in
- parse_pattern(). Neither are numerical back references or recursions, which
- were turned into META_BACKREF or META_RECURSE items, respectively. \k and
- \g, when followed by names, are turned into META_BACKREF_BYNAME or
- META_RECURSE_BYNAME. */
-
- case META_ESCAPE:
-
- /* We can test for escape sequences that consume a character because their
- values lie between ESC_b and ESC_Z; this may have to change if any new ones
- are ever created. For these sequences, we disable the setting of a first
- character if it hasn't already been set. */
-
- if (meta_arg > ESC_b && meta_arg < ESC_Z)
- {
- matched_char = TRUE;
- if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
- }
-
- /* Set values to reset to if this is followed by a zero repeat. */
-
- zerofirstcu = firstcu;
- zerofirstcuflags = firstcuflags;
- zeroreqcu = reqcu;
- zeroreqcuflags = reqcuflags;
-
- /* If Unicode is not supported, \P and \p are not allowed and are
- faulted at parse time, so will never appear here. */
-
-#ifdef SUPPORT_UNICODE
- if (meta_arg == ESC_P || meta_arg == ESC_p)
- {
- uint32_t ptype = *(++pptr) >> 16;
- uint32_t pdata = *pptr & 0xffff;
-
- /* The special case of \p{Any} is compiled to OP_ALLANY so as to benefit
- from the auto-anchoring code. */
-
- if (meta_arg == ESC_p && ptype == PT_ANY)
- {
- *code++ = OP_ALLANY;
- }
- else
- {
- *code++ = (meta_arg == ESC_p)? OP_PROP : OP_NOTPROP;
- *code++ = ptype;
- *code++ = pdata;
- }
- break; /* End META_ESCAPE */
- }
-#endif
-
- /* \K is forbidden in lookarounds since 10.38 because that's what Perl has
- done. However, there's an option, in case anyone was relying on it. */
-
- if (cb->assert_depth > 0 && meta_arg == ESC_K &&
- (cb->cx->extra_options & PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK) == 0)
- {
- *errorcodeptr = ERR99;
- return 0;
- }
-
- /* For the rest (including \X when Unicode is supported - if not it's
- faulted at parse time), the OP value is the escape value when PCRE2_UCP is
- not set; if it is set, these escapes do not show up here because they are
- converted into Unicode property tests in parse_regex(). Note that \b and \B
- do a one-character lookbehind, and \A also behaves as if it does. */
-
- if (meta_arg == ESC_C) cb->external_flags |= PCRE2_HASBKC; /* Record */
- if ((meta_arg == ESC_b || meta_arg == ESC_B || meta_arg == ESC_A) &&
- cb->max_lookbehind == 0)
- cb->max_lookbehind = 1;
-
- /* In non-UTF mode, and for both 32-bit modes, we turn \C into OP_ALLANY
- instead of OP_ANYBYTE so that it works in DFA mode and in lookbehinds. */
-
-#if PCRE2_CODE_UNIT_WIDTH == 32
- *code++ = (meta_arg == ESC_C)? OP_ALLANY : meta_arg;
-#else
- *code++ = (!utf && meta_arg == ESC_C)? OP_ALLANY : meta_arg;
-#endif
- break; /* End META_ESCAPE */
-
-
- /* ===================================================================*/
- /* Handle an unrecognized meta value. A parsed pattern value less than
- META_END is a literal. Otherwise we have a problem. */
-
- default:
- if (meta >= META_END)
- {
-#ifdef DEBUG_SHOW_PARSED
- fprintf(stderr, "** Unrecognized parsed pattern item 0x%.8x\n", *pptr);
-#endif
- *errorcodeptr = ERR89; /* Internal error - unrecognized. */
- return 0;
- }
-
- /* Handle a literal character. We come here by goto in the case of a
- 32-bit, non-UTF character whose value is greater than META_END. */
-
- NORMAL_CHAR:
- meta = *pptr; /* Get the full 32 bits */
- NORMAL_CHAR_SET: /* Character is already in meta */
- matched_char = TRUE;
-
- /* For caseless UTF or UCP mode, check whether this character has more than
- one other case. If so, generate a special OP_PROP item instead of OP_CHARI.
- */
-
-#ifdef SUPPORT_UNICODE
- if ((utf||ucp) && (options & PCRE2_CASELESS) != 0)
- {
- uint32_t caseset = UCD_CASESET(meta);
- if (caseset != 0)
- {
- *code++ = OP_PROP;
- *code++ = PT_CLIST;
- *code++ = caseset;
- if (firstcuflags == REQ_UNSET)
- firstcuflags = zerofirstcuflags = REQ_NONE;
- break; /* End handling this meta item */
- }
- }
-#endif
-
- /* Caseful matches, or caseless and not one of the multicase characters. We
- come here by goto in the case of a positive class that contains only
- case-partners of a character with just two cases; matched_char has already
- been set TRUE and options fudged if necessary. */
-
- CLASS_CASELESS_CHAR:
-
- /* Get the character's code units into mcbuffer, with the length in
- mclength. When not in UTF mode, the length is always 1. */
-
-#ifdef SUPPORT_UNICODE
- if (utf) mclength = PRIV(ord2utf)(meta, mcbuffer); else
-#endif
- {
- mclength = 1;
- mcbuffer[0] = meta;
- }
-
- /* Generate the appropriate code */
-
- *code++ = ((options & PCRE2_CASELESS) != 0)? OP_CHARI : OP_CHAR;
- memcpy(code, mcbuffer, CU2BYTES(mclength));
- code += mclength;
-
- /* Remember if \r or \n were seen */
-
- if (mcbuffer[0] == CHAR_CR || mcbuffer[0] == CHAR_NL)
- cb->external_flags |= PCRE2_HASCRORLF;
-
- /* Set the first and required code units appropriately. If no previous
- first code unit, set it from this character, but revert to none on a zero
- repeat. Otherwise, leave the firstcu value alone, and don't change it on
- a zero repeat. */
-
- if (firstcuflags == REQ_UNSET)
- {
- zerofirstcuflags = REQ_NONE;
- zeroreqcu = reqcu;
- zeroreqcuflags = reqcuflags;
-
- /* If the character is more than one code unit long, we can set a single
- firstcu only if it is not to be matched caselessly. Multiple possible
- starting code units may be picked up later in the studying code. */
-
- if (mclength == 1 || req_caseopt == 0)
- {
- firstcu = mcbuffer[0];
- firstcuflags = req_caseopt;
- if (mclength != 1)
- {
- reqcu = code[-1];
- reqcuflags = cb->req_varyopt;
- }
- }
- else firstcuflags = reqcuflags = REQ_NONE;
- }
-
- /* firstcu was previously set; we can set reqcu only if the length is
- 1 or the matching is caseful. */
-
- else
- {
- zerofirstcu = firstcu;
- zerofirstcuflags = firstcuflags;
- zeroreqcu = reqcu;
- zeroreqcuflags = reqcuflags;
- if (mclength == 1 || req_caseopt == 0)
- {
- reqcu = code[-1];
- reqcuflags = req_caseopt | cb->req_varyopt;
- }
- }
-
- /* If caselessness was temporarily instated, reset it. */
-
- if (reset_caseful)
- {
- options &= ~PCRE2_CASELESS;
- req_caseopt = 0;
- reset_caseful = FALSE;
- }
-
- break; /* End literal character handling */
- } /* End of big switch */
- } /* End of big loop */
-
-/* Control never reaches here. */
-}
-
-
-
-/*************************************************
-* Compile regex: a sequence of alternatives *
-*************************************************/
-
-/* On entry, pptr is pointing past the bracket meta, but on return it points to
-the closing bracket or META_END. The code variable is pointing at the code unit
-into which the BRA operator has been stored. This function is used during the
-pre-compile phase when we are trying to find out the amount of memory needed,
-as well as during the real compile phase. The value of lengthptr distinguishes
-the two phases.
-
-Arguments:
- options option bits, including any changes for this subpattern
- codeptr -> the address of the current code pointer
- pptrptr -> the address of the current parsed pattern pointer
- errorcodeptr -> pointer to error code variable
- skipunits skip this many code units at start (for brackets and OP_COND)
- firstcuptr place to put the first required code unit
- firstcuflagsptr place to put the first code unit flags
- reqcuptr place to put the last required code unit
- reqcuflagsptr place to put the last required code unit flags
- bcptr pointer to the chain of currently open branches
- cb points to the data block with tables pointers etc.
- lengthptr NULL during the real compile phase
- points to length accumulator during pre-compile phase
-
-Returns: 0 There has been an error
- +1 Success, this group must match at least one character
- -1 Success, this group may match an empty string
-*/
-
-static int
-compile_regex(uint32_t options, PCRE2_UCHAR **codeptr, uint32_t **pptrptr,
- int *errorcodeptr, uint32_t skipunits, uint32_t *firstcuptr,
- uint32_t *firstcuflagsptr, uint32_t *reqcuptr, uint32_t *reqcuflagsptr,
- branch_chain *bcptr, compile_block *cb, PCRE2_SIZE *lengthptr)
-{
-PCRE2_UCHAR *code = *codeptr;
-PCRE2_UCHAR *last_branch = code;
-PCRE2_UCHAR *start_bracket = code;
-BOOL lookbehind;
-open_capitem capitem;
-int capnumber = 0;
-int okreturn = 1;
-uint32_t *pptr = *pptrptr;
-uint32_t firstcu, reqcu;
-uint32_t lookbehindlength;
-uint32_t firstcuflags, reqcuflags;
-uint32_t branchfirstcu, branchreqcu;
-uint32_t branchfirstcuflags, branchreqcuflags;
-PCRE2_SIZE length;
-branch_chain bc;
-
-/* If set, call the external function that checks for stack availability. */
-
-if (cb->cx->stack_guard != NULL &&
- cb->cx->stack_guard(cb->parens_depth, cb->cx->stack_guard_data))
- {
- *errorcodeptr= ERR33;
- return 0;
- }
-
-/* Miscellaneous initialization */
-
-bc.outer = bcptr;
-bc.current_branch = code;
-
-firstcu = reqcu = 0;
-firstcuflags = reqcuflags = REQ_UNSET;
-
-/* Accumulate the length for use in the pre-compile phase. Start with the
-length of the BRA and KET and any extra code units that are required at the
-beginning. We accumulate in a local variable to save frequent testing of
-lengthptr for NULL. We cannot do this by looking at the value of 'code' at the
-start and end of each alternative, because compiled items are discarded during
-the pre-compile phase so that the workspace is not exceeded. */
-
-length = 2 + 2*LINK_SIZE + skipunits;
-
-/* Remember if this is a lookbehind assertion, and if it is, save its length
-and skip over the pattern offset. */
-
-lookbehind = *code == OP_ASSERTBACK ||
- *code == OP_ASSERTBACK_NOT ||
- *code == OP_ASSERTBACK_NA;
-
-if (lookbehind)
- {
- lookbehindlength = META_DATA(pptr[-1]);
- pptr += SIZEOFFSET;
- }
-else lookbehindlength = 0;
-
-/* If this is a capturing subpattern, add to the chain of open capturing items
-so that we can detect them if (*ACCEPT) is encountered. Note that only OP_CBRA
-need be tested here; changing this opcode to one of its variants, e.g.
-OP_SCBRAPOS, happens later, after the group has been compiled. */
-
-if (*code == OP_CBRA)
- {
- capnumber = GET2(code, 1 + LINK_SIZE);
- capitem.number = capnumber;
- capitem.next = cb->open_caps;
- capitem.assert_depth = cb->assert_depth;
- cb->open_caps = &capitem;
- }
-
-/* Offset is set zero to mark that this bracket is still open */
-
-PUT(code, 1, 0);
-code += 1 + LINK_SIZE + skipunits;
-
-/* Loop for each alternative branch */
-
-for (;;)
- {
- int branch_return;
-
- /* Insert OP_REVERSE if this is as lookbehind assertion. */
-
- if (lookbehind && lookbehindlength > 0)
- {
- *code++ = OP_REVERSE;
- PUTINC(code, 0, lookbehindlength);
- length += 1 + LINK_SIZE;
- }
-
- /* Now compile the branch; in the pre-compile phase its length gets added
- into the length. */
-
- if ((branch_return =
- compile_branch(&options, &code, &pptr, errorcodeptr, &branchfirstcu,
- &branchfirstcuflags, &branchreqcu, &branchreqcuflags, &bc,
- cb, (lengthptr == NULL)? NULL : &length)) == 0)
- return 0;
-
- /* If a branch can match an empty string, so can the whole group. */
-
- if (branch_return < 0) okreturn = -1;
-
- /* In the real compile phase, there is some post-processing to be done. */
-
- if (lengthptr == NULL)
- {
- /* If this is the first branch, the firstcu and reqcu values for the
- branch become the values for the regex. */
-
- if (*last_branch != OP_ALT)
- {
- firstcu = branchfirstcu;
- firstcuflags = branchfirstcuflags;
- reqcu = branchreqcu;
- reqcuflags = branchreqcuflags;
- }
-
- /* If this is not the first branch, the first char and reqcu have to
- match the values from all the previous branches, except that if the
- previous value for reqcu didn't have REQ_VARY set, it can still match,
- and we set REQ_VARY for the group from this branch's value. */
-
- else
- {
- /* If we previously had a firstcu, but it doesn't match the new branch,
- we have to abandon the firstcu for the regex, but if there was
- previously no reqcu, it takes on the value of the old firstcu. */
-
- if (firstcuflags != branchfirstcuflags || firstcu != branchfirstcu)
- {
- if (firstcuflags < REQ_NONE)
- {
- if (reqcuflags >= REQ_NONE)
- {
- reqcu = firstcu;
- reqcuflags = firstcuflags;
- }
- }
- firstcuflags = REQ_NONE;
- }
-
- /* If we (now or from before) have no firstcu, a firstcu from the
- branch becomes a reqcu if there isn't a branch reqcu. */
-
- if (firstcuflags >= REQ_NONE && branchfirstcuflags < REQ_NONE &&
- branchreqcuflags >= REQ_NONE)
- {
- branchreqcu = branchfirstcu;
- branchreqcuflags = branchfirstcuflags;
- }
-
- /* Now ensure that the reqcus match */
-
- if (((reqcuflags & ~REQ_VARY) != (branchreqcuflags & ~REQ_VARY)) ||
- reqcu != branchreqcu)
- reqcuflags = REQ_NONE;
- else
- {
- reqcu = branchreqcu;
- reqcuflags |= branchreqcuflags; /* To "or" REQ_VARY if present */
- }
- }
- }
-
- /* Handle reaching the end of the expression, either ')' or end of pattern.
- In the real compile phase, go back through the alternative branches and
- reverse the chain of offsets, with the field in the BRA item now becoming an
- offset to the first alternative. If there are no alternatives, it points to
- the end of the group. The length in the terminating ket is always the length
- of the whole bracketed item. Return leaving the pointer at the terminating
- char. */
-
- if (META_CODE(*pptr) != META_ALT)
- {
- if (lengthptr == NULL)
- {
- PCRE2_SIZE branch_length = code - last_branch;
- do
- {
- PCRE2_SIZE prev_length = GET(last_branch, 1);
- PUT(last_branch, 1, branch_length);
- branch_length = prev_length;
- last_branch -= branch_length;
- }
- while (branch_length > 0);
- }
-
- /* Fill in the ket */
-
- *code = OP_KET;
- PUT(code, 1, (int)(code - start_bracket));
- code += 1 + LINK_SIZE;
-
- /* If it was a capturing subpattern, remove the block from the chain. */
-
- if (capnumber > 0) cb->open_caps = cb->open_caps->next;
-
- /* Set values to pass back */
-
- *codeptr = code;
- *pptrptr = pptr;
- *firstcuptr = firstcu;
- *firstcuflagsptr = firstcuflags;
- *reqcuptr = reqcu;
- *reqcuflagsptr = reqcuflags;
- if (lengthptr != NULL)
- {
- if (OFLOW_MAX - *lengthptr < length)
- {
- *errorcodeptr = ERR20;
- return 0;
- }
- *lengthptr += length;
- }
- return okreturn;
- }
-
- /* Another branch follows. In the pre-compile phase, we can move the code
- pointer back to where it was for the start of the first branch. (That is,
- pretend that each branch is the only one.)
-
- In the real compile phase, insert an ALT node. Its length field points back
- to the previous branch while the bracket remains open. At the end the chain
- is reversed. It's done like this so that the start of the bracket has a
- zero offset until it is closed, making it possible to detect recursion. */
-
- if (lengthptr != NULL)
- {
- code = *codeptr + 1 + LINK_SIZE + skipunits;
- length += 1 + LINK_SIZE;
- }
- else
- {
- *code = OP_ALT;
- PUT(code, 1, (int)(code - last_branch));
- bc.current_branch = last_branch = code;
- code += 1 + LINK_SIZE;
- }
-
- /* Set the lookbehind length (if not in a lookbehind the value will be zero)
- and then advance past the vertical bar. */
-
- lookbehindlength = META_DATA(*pptr);
- pptr++;
- }
-/* Control never reaches here */
-}
-
-
-
-/*************************************************
-* Check for anchored pattern *
-*************************************************/
-
-/* Try to find out if this is an anchored regular expression. Consider each
-alternative branch. If they all start with OP_SOD or OP_CIRC, or with a bracket
-all of whose alternatives start with OP_SOD or OP_CIRC (recurse ad lib), then
-it's anchored. However, if this is a multiline pattern, then only OP_SOD will
-be found, because ^ generates OP_CIRCM in that mode.
-
-We can also consider a regex to be anchored if OP_SOM starts all its branches.
-This is the code for \G, which means "match at start of match position, taking
-into account the match offset".
-
-A branch is also implicitly anchored if it starts with .* and DOTALL is set,
-because that will try the rest of the pattern at all possible matching points,
-so there is no point trying again.... er ....
-
-.... except when the .* appears inside capturing parentheses, and there is a
-subsequent back reference to those parentheses. We haven't enough information
-to catch that case precisely.
-
-At first, the best we could do was to detect when .* was in capturing brackets
-and the highest back reference was greater than or equal to that level.
-However, by keeping a bitmap of the first 31 back references, we can catch some
-of the more common cases more precisely.
-
-... A second exception is when the .* appears inside an atomic group, because
-this prevents the number of characters it matches from being adjusted.
-
-Arguments:
- code points to start of the compiled pattern
- bracket_map a bitmap of which brackets we are inside while testing; this
- handles up to substring 31; after that we just have to take
- the less precise approach
- cb points to the compile data block
- atomcount atomic group level
- inassert TRUE if in an assertion
-
-Returns: TRUE or FALSE
-*/
-
-static BOOL
-is_anchored(PCRE2_SPTR code, uint32_t bracket_map, compile_block *cb,
- int atomcount, BOOL inassert)
-{
-do {
- PCRE2_SPTR scode = first_significant_code(
- code + PRIV(OP_lengths)[*code], FALSE);
- int op = *scode;
-
- /* Non-capturing brackets */
-
- if (op == OP_BRA || op == OP_BRAPOS ||
- op == OP_SBRA || op == OP_SBRAPOS)
- {
- if (!is_anchored(scode, bracket_map, cb, atomcount, inassert))
- return FALSE;
- }
-
- /* Capturing brackets */
-
- else if (op == OP_CBRA || op == OP_CBRAPOS ||
- op == OP_SCBRA || op == OP_SCBRAPOS)
- {
- int n = GET2(scode, 1+LINK_SIZE);
- uint32_t new_map = bracket_map | ((n < 32)? (1u << n) : 1);
- if (!is_anchored(scode, new_map, cb, atomcount, inassert)) return FALSE;
- }
-
- /* Positive forward assertion */
-
- else if (op == OP_ASSERT || op == OP_ASSERT_NA)
- {
- if (!is_anchored(scode, bracket_map, cb, atomcount, TRUE)) return FALSE;
- }
-
- /* Condition. If there is no second branch, it can't be anchored. */
-
- else if (op == OP_COND || op == OP_SCOND)
- {
- if (scode[GET(scode,1)] != OP_ALT) return FALSE;
- if (!is_anchored(scode, bracket_map, cb, atomcount, inassert))
- return FALSE;
- }
-
- /* Atomic groups */
-
- else if (op == OP_ONCE)
- {
- if (!is_anchored(scode, bracket_map, cb, atomcount + 1, inassert))
- return FALSE;
- }
-
- /* .* is not anchored unless DOTALL is set (which generates OP_ALLANY) and
- it isn't in brackets that are or may be referenced or inside an atomic
- group or an assertion. Also the pattern must not contain *PRUNE or *SKIP,
- because these break the feature. Consider, for example, /(?s).*?(*PRUNE)b/
- with the subject "aab", which matches "b", i.e. not at the start of a line.
- There is also an option that disables auto-anchoring. */
-
- else if ((op == OP_TYPESTAR || op == OP_TYPEMINSTAR ||
- op == OP_TYPEPOSSTAR))
- {
- if (scode[1] != OP_ALLANY || (bracket_map & cb->backref_map) != 0 ||
- atomcount > 0 || cb->had_pruneorskip || inassert ||
- (cb->external_options & PCRE2_NO_DOTSTAR_ANCHOR) != 0)
- return FALSE;
- }
-
- /* Check for explicit anchoring */
-
- else if (op != OP_SOD && op != OP_SOM && op != OP_CIRC) return FALSE;
-
- code += GET(code, 1);
- }
-while (*code == OP_ALT); /* Loop for each alternative */
-return TRUE;
-}
-
-
-
-/*************************************************
-* Check for starting with ^ or .* *
-*************************************************/
-
-/* This is called to find out if every branch starts with ^ or .* so that
-"first char" processing can be done to speed things up in multiline
-matching and for non-DOTALL patterns that start with .* (which must start at
-the beginning or after \n). As in the case of is_anchored() (see above), we
-have to take account of back references to capturing brackets that contain .*
-because in that case we can't make the assumption. Also, the appearance of .*
-inside atomic brackets or in an assertion, or in a pattern that contains *PRUNE
-or *SKIP does not count, because once again the assumption no longer holds.
-
-Arguments:
- code points to start of the compiled pattern or a group
- bracket_map a bitmap of which brackets we are inside while testing; this
- handles up to substring 31; after that we just have to take
- the less precise approach
- cb points to the compile data
- atomcount atomic group level
- inassert TRUE if in an assertion
-
-Returns: TRUE or FALSE
-*/
-
-static BOOL
-is_startline(PCRE2_SPTR code, unsigned int bracket_map, compile_block *cb,
- int atomcount, BOOL inassert)
-{
-do {
- PCRE2_SPTR scode = first_significant_code(
- code + PRIV(OP_lengths)[*code], FALSE);
- int op = *scode;
-
- /* If we are at the start of a conditional assertion group, *both* the
- conditional assertion *and* what follows the condition must satisfy the test
- for start of line. Other kinds of condition fail. Note that there may be an
- auto-callout at the start of a condition. */
-
- if (op == OP_COND)
- {
- scode += 1 + LINK_SIZE;
-
- if (*scode == OP_CALLOUT) scode += PRIV(OP_lengths)[OP_CALLOUT];
- else if (*scode == OP_CALLOUT_STR) scode += GET(scode, 1 + 2*LINK_SIZE);
-
- switch (*scode)
- {
- case OP_CREF:
- case OP_DNCREF:
- case OP_RREF:
- case OP_DNRREF:
- case OP_FAIL:
- case OP_FALSE:
- case OP_TRUE:
- return FALSE;
-
- default: /* Assertion */
- if (!is_startline(scode, bracket_map, cb, atomcount, TRUE)) return FALSE;
- do scode += GET(scode, 1); while (*scode == OP_ALT);
- scode += 1 + LINK_SIZE;
- break;
- }
- scode = first_significant_code(scode, FALSE);
- op = *scode;
- }
-
- /* Non-capturing brackets */
-
- if (op == OP_BRA || op == OP_BRAPOS ||
- op == OP_SBRA || op == OP_SBRAPOS)
- {
- if (!is_startline(scode, bracket_map, cb, atomcount, inassert))
- return FALSE;
- }
-
- /* Capturing brackets */
-
- else if (op == OP_CBRA || op == OP_CBRAPOS ||
- op == OP_SCBRA || op == OP_SCBRAPOS)
- {
- int n = GET2(scode, 1+LINK_SIZE);
- unsigned int new_map = bracket_map | ((n < 32)? (1u << n) : 1);
- if (!is_startline(scode, new_map, cb, atomcount, inassert)) return FALSE;
- }
-
- /* Positive forward assertions */
-
- else if (op == OP_ASSERT || op == OP_ASSERT_NA)
- {
- if (!is_startline(scode, bracket_map, cb, atomcount, TRUE))
- return FALSE;
- }
-
- /* Atomic brackets */
-
- else if (op == OP_ONCE)
- {
- if (!is_startline(scode, bracket_map, cb, atomcount + 1, inassert))
- return FALSE;
- }
-
- /* .* means "start at start or after \n" if it isn't in atomic brackets or
- brackets that may be referenced or an assertion, and as long as the pattern
- does not contain *PRUNE or *SKIP, because these break the feature. Consider,
- for example, /.*?a(*PRUNE)b/ with the subject "aab", which matches "ab",
- i.e. not at the start of a line. There is also an option that disables this
- optimization. */
-
- else if (op == OP_TYPESTAR || op == OP_TYPEMINSTAR || op == OP_TYPEPOSSTAR)
- {
- if (scode[1] != OP_ANY || (bracket_map & cb->backref_map) != 0 ||
- atomcount > 0 || cb->had_pruneorskip || inassert ||
- (cb->external_options & PCRE2_NO_DOTSTAR_ANCHOR) != 0)
- return FALSE;
- }
-
- /* Check for explicit circumflex; anything else gives a FALSE result. Note
- in particular that this includes atomic brackets OP_ONCE because the number
- of characters matched by .* cannot be adjusted inside them. */
-
- else if (op != OP_CIRC && op != OP_CIRCM) return FALSE;
-
- /* Move on to the next alternative */
-
- code += GET(code, 1);
- }
-while (*code == OP_ALT); /* Loop for each alternative */
-return TRUE;
-}
-
-
-
-/*************************************************
-* Scan compiled regex for recursion reference *
-*************************************************/
-
-/* This function scans through a compiled pattern until it finds an instance of
-OP_RECURSE.
-
-Arguments:
- code points to start of expression
- utf TRUE in UTF mode
-
-Returns: pointer to the opcode for OP_RECURSE, or NULL if not found
-*/
-
-static PCRE2_SPTR
-find_recurse(PCRE2_SPTR code, BOOL utf)
-{
-for (;;)
- {
- PCRE2_UCHAR c = *code;
- if (c == OP_END) return NULL;
- if (c == OP_RECURSE) return code;
-
- /* XCLASS is used for classes that cannot be represented just by a bit map.
- This includes negated single high-valued characters. CALLOUT_STR is used for
- callouts with string arguments. In both cases the length in the table is
- zero; the actual length is stored in the compiled code. */
-
- if (c == OP_XCLASS) code += GET(code, 1);
- else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE);
-
- /* Otherwise, we can get the item's length from the table, except that for
- repeated character types, we have to test for \p and \P, which have an extra
- two code units of parameters, and for MARK/PRUNE/SKIP/THEN with an argument,
- we must add in its length. */
-
- else
- {
- switch(c)
- {
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSPLUS:
- case OP_TYPEPOSQUERY:
- if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
- break;
-
- case OP_TYPEPOSUPTO:
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEEXACT:
- if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)
- code += 2;
- break;
-
- case OP_MARK:
- case OP_COMMIT_ARG:
- case OP_PRUNE_ARG:
- case OP_SKIP_ARG:
- case OP_THEN_ARG:
- code += code[1];
- break;
- }
-
- /* Add in the fixed length from the table */
-
- code += PRIV(OP_lengths)[c];
-
- /* In UTF-8 and UTF-16 modes, opcodes that are followed by a character may
- be followed by a multi-unit character. The length in the table is a
- minimum, so we have to arrange to skip the extra units. */
-
-#ifdef MAYBE_UTF_MULTI
- if (utf) switch(c)
- {
- case OP_CHAR:
- case OP_CHARI:
- case OP_NOT:
- case OP_NOTI:
- case OP_EXACT:
- case OP_EXACTI:
- case OP_NOTEXACT:
- case OP_NOTEXACTI:
- case OP_UPTO:
- case OP_UPTOI:
- case OP_NOTUPTO:
- case OP_NOTUPTOI:
- case OP_MINUPTO:
- case OP_MINUPTOI:
- case OP_NOTMINUPTO:
- case OP_NOTMINUPTOI:
- case OP_POSUPTO:
- case OP_POSUPTOI:
- case OP_NOTPOSUPTO:
- case OP_NOTPOSUPTOI:
- case OP_STAR:
- case OP_STARI:
- case OP_NOTSTAR:
- case OP_NOTSTARI:
- case OP_MINSTAR:
- case OP_MINSTARI:
- case OP_NOTMINSTAR:
- case OP_NOTMINSTARI:
- case OP_POSSTAR:
- case OP_POSSTARI:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSSTARI:
- case OP_PLUS:
- case OP_PLUSI:
- case OP_NOTPLUS:
- case OP_NOTPLUSI:
- case OP_MINPLUS:
- case OP_MINPLUSI:
- case OP_NOTMINPLUS:
- case OP_NOTMINPLUSI:
- case OP_POSPLUS:
- case OP_POSPLUSI:
- case OP_NOTPOSPLUS:
- case OP_NOTPOSPLUSI:
- case OP_QUERY:
- case OP_QUERYI:
- case OP_NOTQUERY:
- case OP_NOTQUERYI:
- case OP_MINQUERY:
- case OP_MINQUERYI:
- case OP_NOTMINQUERY:
- case OP_NOTMINQUERYI:
- case OP_POSQUERY:
- case OP_POSQUERYI:
- case OP_NOTPOSQUERY:
- case OP_NOTPOSQUERYI:
- if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);
- break;
- }
-#else
- (void)(utf); /* Keep compiler happy by referencing function argument */
-#endif /* MAYBE_UTF_MULTI */
- }
- }
-}
-
-
-
-/*************************************************
-* Check for asserted fixed first code unit *
-*************************************************/
-
-/* During compilation, the "first code unit" settings from forward assertions
-are discarded, because they can cause conflicts with actual literals that
-follow. However, if we end up without a first code unit setting for an
-unanchored pattern, it is worth scanning the regex to see if there is an
-initial asserted first code unit. If all branches start with the same asserted
-code unit, or with a non-conditional bracket all of whose alternatives start
-with the same asserted code unit (recurse ad lib), then we return that code
-unit, with the flags set to zero or REQ_CASELESS; otherwise return zero with
-REQ_NONE in the flags.
-
-Arguments:
- code points to start of compiled pattern
- flags points to the first code unit flags
- inassert non-zero if in an assertion
-
-Returns: the fixed first code unit, or 0 with REQ_NONE in flags
-*/
-
-static uint32_t
-find_firstassertedcu(PCRE2_SPTR code, uint32_t *flags, uint32_t inassert)
-{
-uint32_t c = 0;
-uint32_t cflags = REQ_NONE;
-
-*flags = REQ_NONE;
-do {
- uint32_t d;
- uint32_t dflags;
- int xl = (*code == OP_CBRA || *code == OP_SCBRA ||
- *code == OP_CBRAPOS || *code == OP_SCBRAPOS)? IMM2_SIZE:0;
- PCRE2_SPTR scode = first_significant_code(code + 1+LINK_SIZE + xl, TRUE);
- PCRE2_UCHAR op = *scode;
-
- switch(op)
- {
- default:
- return 0;
-
- case OP_BRA:
- case OP_BRAPOS:
- case OP_CBRA:
- case OP_SCBRA:
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- case OP_ASSERT:
- case OP_ASSERT_NA:
- case OP_ONCE:
- case OP_SCRIPT_RUN:
- d = find_firstassertedcu(scode, &dflags, inassert +
- ((op == OP_ASSERT || op == OP_ASSERT_NA)?1:0));
- if (dflags >= REQ_NONE) return 0;
- if (cflags >= REQ_NONE) { c = d; cflags = dflags; }
- else if (c != d || cflags != dflags) return 0;
- break;
-
- case OP_EXACT:
- scode += IMM2_SIZE;
- /* Fall through */
-
- case OP_CHAR:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_POSPLUS:
- if (inassert == 0) return 0;
- if (cflags >= REQ_NONE) { c = scode[1]; cflags = 0; }
- else if (c != scode[1]) return 0;
- break;
-
- case OP_EXACTI:
- scode += IMM2_SIZE;
- /* Fall through */
-
- case OP_CHARI:
- case OP_PLUSI:
- case OP_MINPLUSI:
- case OP_POSPLUSI:
- if (inassert == 0) return 0;
-
- /* If the character is more than one code unit long, we cannot set its
- first code unit when matching caselessly. Later scanning may pick up
- multiple code units. */
-
-#ifdef SUPPORT_UNICODE
-#if PCRE2_CODE_UNIT_WIDTH == 8
- if (scode[1] >= 0x80) return 0;
-#elif PCRE2_CODE_UNIT_WIDTH == 16
- if (scode[1] >= 0xd800 && scode[1] <= 0xdfff) return 0;
-#endif
-#endif
-
- if (cflags >= REQ_NONE) { c = scode[1]; cflags = REQ_CASELESS; }
- else if (c != scode[1]) return 0;
- break;
- }
-
- code += GET(code, 1);
- }
-while (*code == OP_ALT);
-
-*flags = cflags;
-return c;
-}
-
-
-
-/*************************************************
-* Add an entry to the name/number table *
-*************************************************/
-
-/* This function is called between compiling passes to add an entry to the
-name/number table, maintaining alphabetical order. Checking for permitted
-and forbidden duplicates has already been done.
-
-Arguments:
- cb the compile data block
- name the name to add
- length the length of the name
- groupno the group number
- tablecount the count of names in the table so far
-
-Returns: nothing
-*/
-
-static void
-add_name_to_table(compile_block *cb, PCRE2_SPTR name, int length,
- unsigned int groupno, uint32_t tablecount)
-{
-uint32_t i;
-PCRE2_UCHAR *slot = cb->name_table;
-
-for (i = 0; i < tablecount; i++)
- {
- int crc = memcmp(name, slot+IMM2_SIZE, CU2BYTES(length));
- if (crc == 0 && slot[IMM2_SIZE+length] != 0)
- crc = -1; /* Current name is a substring */
-
- /* Make space in the table and break the loop for an earlier name. For a
- duplicate or later name, carry on. We do this for duplicates so that in the
- simple case (when ?(| is not used) they are in order of their numbers. In all
- cases they are in the order in which they appear in the pattern. */
-
- if (crc < 0)
- {
- (void)memmove(slot + cb->name_entry_size, slot,
- CU2BYTES((tablecount - i) * cb->name_entry_size));
- break;
- }
-
- /* Continue the loop for a later or duplicate name */
-
- slot += cb->name_entry_size;
- }
-
-PUT2(slot, 0, groupno);
-memcpy(slot + IMM2_SIZE, name, CU2BYTES(length));
-
-/* Add a terminating zero and fill the rest of the slot with zeroes so that
-the memory is all initialized. Otherwise valgrind moans about uninitialized
-memory when saving serialized compiled patterns. */
-
-memset(slot + IMM2_SIZE + length, 0,
- CU2BYTES(cb->name_entry_size - length - IMM2_SIZE));
-}
-
-
-
-/*************************************************
-* Skip in parsed pattern *
-*************************************************/
-
-/* This function is called to skip parts of the parsed pattern when finding the
-length of a lookbehind branch. It is called after (*ACCEPT) and (*FAIL) to find
-the end of the branch, it is called to skip over an internal lookaround or
-(DEFINE) group, and it is also called to skip to the end of a class, during
-which it will never encounter nested groups (but there's no need to have
-special code for that).
-
-When called to find the end of a branch or group, pptr must point to the first
-meta code inside the branch, not the branch-starting code. In other cases it
-can point to the item that causes the function to be called.
-
-Arguments:
- pptr current pointer to skip from
- skiptype PSKIP_CLASS when skipping to end of class
- PSKIP_ALT when META_ALT ends the skip
- PSKIP_KET when only META_KET ends the skip
-
-Returns: new value of pptr
- NULL if META_END is reached - should never occur
- or for an unknown meta value - likewise
-*/
-
-static uint32_t *
-parsed_skip(uint32_t *pptr, uint32_t skiptype)
-{
-uint32_t nestlevel = 0;
-
-for (;; pptr++)
- {
- uint32_t meta = META_CODE(*pptr);
-
- switch(meta)
- {
- default: /* Just skip over most items */
- if (meta < META_END) continue; /* Literal */
- break;
-
- /* This should never occur. */
-
- case META_END:
- return NULL;
-
- /* The data for these items is variable in length. */
-
- case META_BACKREF: /* Offset is present only if group >= 10 */
- if (META_DATA(*pptr) >= 10) pptr += SIZEOFFSET;
- break;
-
- case META_ESCAPE: /* A few escapes are followed by data items. */
- switch (META_DATA(*pptr))
- {
- case ESC_P:
- case ESC_p:
- pptr += 1;
- break;
-
- case ESC_g:
- case ESC_k:
- pptr += 1 + SIZEOFFSET;
- break;
- }
- break;
-
- case META_MARK: /* Add the length of the name. */
- case META_COMMIT_ARG:
- case META_PRUNE_ARG:
- case META_SKIP_ARG:
- case META_THEN_ARG:
- pptr += pptr[1];
- break;
-
- /* These are the "active" items in this loop. */
-
- case META_CLASS_END:
- if (skiptype == PSKIP_CLASS) return pptr;
- break;
-
- case META_ATOMIC:
- case META_CAPTURE:
- case META_COND_ASSERT:
- case META_COND_DEFINE:
- case META_COND_NAME:
- case META_COND_NUMBER:
- case META_COND_RNAME:
- case META_COND_RNUMBER:
- case META_COND_VERSION:
- case META_LOOKAHEAD:
- case META_LOOKAHEADNOT:
- case META_LOOKAHEAD_NA:
- case META_LOOKBEHIND:
- case META_LOOKBEHINDNOT:
- case META_LOOKBEHIND_NA:
- case META_NOCAPTURE:
- case META_SCRIPT_RUN:
- nestlevel++;
- break;
-
- case META_ALT:
- if (nestlevel == 0 && skiptype == PSKIP_ALT) return pptr;
- break;
-
- case META_KET:
- if (nestlevel == 0) return pptr;
- nestlevel--;
- break;
- }
-
- /* The extra data item length for each meta is in a table. */
-
- meta = (meta >> 16) & 0x7fff;
- if (meta >= sizeof(meta_extra_lengths)) return NULL;
- pptr += meta_extra_lengths[meta];
- }
-/* Control never reaches here */
-return pptr;
-}
-
-
-
-/*************************************************
-* Find length of a parsed group *
-*************************************************/
-
-/* This is called for nested groups within a branch of a lookbehind whose
-length is being computed. If all the branches in the nested group have the same
-length, that is OK. On entry, the pointer must be at the first element after
-the group initializing code. On exit it points to OP_KET. Caching is used to
-improve processing speed when the same capturing group occurs many times.
-
-Arguments:
- pptrptr pointer to pointer in the parsed pattern
- isinline FALSE if a reference or recursion; TRUE for inline group
- errcodeptr pointer to the errorcode
- lcptr pointer to the loop counter
- group number of captured group or -1 for a non-capturing group
- recurses chain of recurse_check to catch mutual recursion
- cb pointer to the compile data
-
-Returns: the group length or a negative number
-*/
-
-static int
-get_grouplength(uint32_t **pptrptr, BOOL isinline, int *errcodeptr, int *lcptr,
- int group, parsed_recurse_check *recurses, compile_block *cb)
-{
-int branchlength;
-int grouplength = -1;
-
-/* The cache can be used only if there is no possibility of there being two
-groups with the same number. We do not need to set the end pointer for a group
-that is being processed as a back reference or recursion, but we must do so for
-an inline group. */
-
-if (group > 0 && (cb->external_flags & PCRE2_DUPCAPUSED) == 0)
- {
- uint32_t groupinfo = cb->groupinfo[group];
- if ((groupinfo & GI_NOT_FIXED_LENGTH) != 0) return -1;
- if ((groupinfo & GI_SET_FIXED_LENGTH) != 0)
- {
- if (isinline) *pptrptr = parsed_skip(*pptrptr, PSKIP_KET);
- return groupinfo & GI_FIXED_LENGTH_MASK;
- }
- }
-
-/* Scan the group. In this case we find the end pointer of necessity. */
-
-for(;;)
- {
- branchlength = get_branchlength(pptrptr, errcodeptr, lcptr, recurses, cb);
- if (branchlength < 0) goto ISNOTFIXED;
- if (grouplength == -1) grouplength = branchlength;
- else if (grouplength != branchlength) goto ISNOTFIXED;
- if (**pptrptr == META_KET) break;
- *pptrptr += 1; /* Skip META_ALT */
- }
-
-if (group > 0)
- cb->groupinfo[group] |= (uint32_t)(GI_SET_FIXED_LENGTH | grouplength);
-return grouplength;
-
-ISNOTFIXED:
-if (group > 0) cb->groupinfo[group] |= GI_NOT_FIXED_LENGTH;
-return -1;
-}
-
-
-
-/*************************************************
-* Find length of a parsed branch *
-*************************************************/
-
-/* Return a fixed length for a branch in a lookbehind, giving an error if the
-length is not fixed. On entry, *pptrptr points to the first element inside the
-branch. On exit it is set to point to the ALT or KET.
-
-Arguments:
- pptrptr pointer to pointer in the parsed pattern
- errcodeptr pointer to error code
- lcptr pointer to loop counter
- recurses chain of recurse_check to catch mutual recursion
- cb pointer to compile block
-
-Returns: the length, or a negative value on error
-*/
-
-static int
-get_branchlength(uint32_t **pptrptr, int *errcodeptr, int *lcptr,
- parsed_recurse_check *recurses, compile_block *cb)
-{
-int branchlength = 0;
-int grouplength;
-uint32_t lastitemlength = 0;
-uint32_t *pptr = *pptrptr;
-PCRE2_SIZE offset;
-parsed_recurse_check this_recurse;
-
-/* A large and/or complex regex can take too long to process. This can happen
-more often when (?| groups are present in the pattern because their length
-cannot be cached. */
-
-if ((*lcptr)++ > 2000)
- {
- *errcodeptr = ERR35; /* Lookbehind is too complicated */
- return -1;
- }
-
-/* Scan the branch, accumulating the length. */
-
-for (;; pptr++)
- {
- parsed_recurse_check *r;
- uint32_t *gptr, *gptrend;
- uint32_t escape;
- uint32_t group = 0;
- uint32_t itemlength = 0;
-
- if (*pptr < META_END)
- {
- itemlength = 1;
- }
-
- else switch (META_CODE(*pptr))
- {
- case META_KET:
- case META_ALT:
- goto EXIT;
-
- /* (*ACCEPT) and (*FAIL) terminate the branch, but we must skip to the
- actual termination. */
-
- case META_ACCEPT:
- case META_FAIL:
- pptr = parsed_skip(pptr, PSKIP_ALT);
- if (pptr == NULL) goto PARSED_SKIP_FAILED;
- goto EXIT;
-
- case META_MARK:
- case META_COMMIT_ARG:
- case META_PRUNE_ARG:
- case META_SKIP_ARG:
- case META_THEN_ARG:
- pptr += pptr[1] + 1;
- break;
-
- case META_CIRCUMFLEX:
- case META_COMMIT:
- case META_DOLLAR:
- case META_PRUNE:
- case META_SKIP:
- case META_THEN:
- break;
-
- case META_OPTIONS:
- pptr += 1;
- break;
-
- case META_BIGVALUE:
- itemlength = 1;
- pptr += 1;
- break;
-
- case META_CLASS:
- case META_CLASS_NOT:
- itemlength = 1;
- pptr = parsed_skip(pptr, PSKIP_CLASS);
- if (pptr == NULL) goto PARSED_SKIP_FAILED;
- break;
-
- case META_CLASS_EMPTY_NOT:
- case META_DOT:
- itemlength = 1;
- break;
-
- case META_CALLOUT_NUMBER:
- pptr += 3;
- break;
-
- case META_CALLOUT_STRING:
- pptr += 3 + SIZEOFFSET;
- break;
-
- /* Only some escapes consume a character. Of those, \R and \X are never
- allowed because they might match more than character. \C is allowed only in
- 32-bit and non-UTF 8/16-bit modes. */
-
- case META_ESCAPE:
- escape = META_DATA(*pptr);
- if (escape == ESC_R || escape == ESC_X) return -1;
- if (escape > ESC_b && escape < ESC_Z)
- {
-#if PCRE2_CODE_UNIT_WIDTH != 32
- if ((cb->external_options & PCRE2_UTF) != 0 && escape == ESC_C)
- {
- *errcodeptr = ERR36;
- return -1;
- }
-#endif
- itemlength = 1;
- if (escape == ESC_p || escape == ESC_P) pptr++; /* Skip prop data */
- }
- break;
-
- /* Lookaheads do not contribute to the length of this branch, but they may
- contain lookbehinds within them whose lengths need to be set. */
-
- case META_LOOKAHEAD:
- case META_LOOKAHEADNOT:
- case META_LOOKAHEAD_NA:
- *errcodeptr = check_lookbehinds(pptr + 1, &pptr, recurses, cb, lcptr);
- if (*errcodeptr != 0) return -1;
-
- /* Ignore any qualifiers that follow a lookahead assertion. */
-
- switch (pptr[1])
- {
- case META_ASTERISK:
- case META_ASTERISK_PLUS:
- case META_ASTERISK_QUERY:
- case META_PLUS:
- case META_PLUS_PLUS:
- case META_PLUS_QUERY:
- case META_QUERY:
- case META_QUERY_PLUS:
- case META_QUERY_QUERY:
- pptr++;
- break;
-
- case META_MINMAX:
- case META_MINMAX_PLUS:
- case META_MINMAX_QUERY:
- pptr += 3;
- break;
-
- default:
- break;
- }
- break;
-
- /* A nested lookbehind does not contribute any length to this lookbehind,
- but must itself be checked and have its lengths set. */
-
- case META_LOOKBEHIND:
- case META_LOOKBEHINDNOT:
- case META_LOOKBEHIND_NA:
- if (!set_lookbehind_lengths(&pptr, errcodeptr, lcptr, recurses, cb))
- return -1;
- break;
-
- /* Back references and recursions are handled by very similar code. At this
- stage, the names generated in the parsing pass are available, but the main
- name table has not yet been created. So for the named varieties, scan the
- list of names in order to get the number of the first one in the pattern,
- and whether or not this name is duplicated. */
-
- case META_BACKREF_BYNAME:
- if ((cb->external_options & PCRE2_MATCH_UNSET_BACKREF) != 0)
- goto ISNOTFIXED;
- /* Fall through */
-
- case META_RECURSE_BYNAME:
- {
- int i;
- PCRE2_SPTR name;
- BOOL is_dupname = FALSE;
- named_group *ng = cb->named_groups;
- uint32_t meta_code = META_CODE(*pptr);
- uint32_t length = *(++pptr);
-
- GETPLUSOFFSET(offset, pptr);
- name = cb->start_pattern + offset;
- for (i = 0; i < cb->names_found; i++, ng++)
- {
- if (length == ng->length && PRIV(strncmp)(name, ng->name, length) == 0)
- {
- group = ng->number;
- is_dupname = ng->isdup;
- break;
- }
- }
-
- if (group == 0)
- {
- *errcodeptr = ERR15; /* Non-existent subpattern */
- cb->erroroffset = offset;
- return -1;
- }
-
- /* A numerical back reference can be fixed length if duplicate capturing
- groups are not being used. A non-duplicate named back reference can also
- be handled. */
-
- if (meta_code == META_RECURSE_BYNAME ||
- (!is_dupname && (cb->external_flags & PCRE2_DUPCAPUSED) == 0))
- goto RECURSE_OR_BACKREF_LENGTH; /* Handle as a numbered version. */
- }
- goto ISNOTFIXED; /* Duplicate name or number */
-
- /* The offset values for back references < 10 are in a separate vector
- because otherwise they would use more than two parsed pattern elements on
- 64-bit systems. */
-
- case META_BACKREF:
- if ((cb->external_options & PCRE2_MATCH_UNSET_BACKREF) != 0 ||
- (cb->external_flags & PCRE2_DUPCAPUSED) != 0)
- goto ISNOTFIXED;
- group = META_DATA(*pptr);
- if (group < 10)
- {
- offset = cb->small_ref_offset[group];
- goto RECURSE_OR_BACKREF_LENGTH;
- }
-
- /* Fall through */
- /* For groups >= 10 - picking up group twice does no harm. */
-
- /* A true recursion implies not fixed length, but a subroutine call may
- be OK. Back reference "recursions" are also failed. */
-
- case META_RECURSE:
- group = META_DATA(*pptr);
- GETPLUSOFFSET(offset, pptr);
-
- RECURSE_OR_BACKREF_LENGTH:
- if (group > cb->bracount)
- {
- cb->erroroffset = offset;
- *errcodeptr = ERR15; /* Non-existent subpattern */
- return -1;
- }
- if (group == 0) goto ISNOTFIXED; /* Local recursion */
- for (gptr = cb->parsed_pattern; *gptr != META_END; gptr++)
- {
- if (META_CODE(*gptr) == META_BIGVALUE) gptr++;
- else if (*gptr == (META_CAPTURE | group)) break;
- }
-
- /* We must start the search for the end of the group at the first meta code
- inside the group. Otherwise it will be treated as an enclosed group. */
-
- gptrend = parsed_skip(gptr + 1, PSKIP_KET);
- if (gptrend == NULL) goto PARSED_SKIP_FAILED;
- if (pptr > gptr && pptr < gptrend) goto ISNOTFIXED; /* Local recursion */
- for (r = recurses; r != NULL; r = r->prev) if (r->groupptr == gptr) break;
- if (r != NULL) goto ISNOTFIXED; /* Mutual recursion */
- this_recurse.prev = recurses;
- this_recurse.groupptr = gptr;
-
- /* We do not need to know the position of the end of the group, that is,
- gptr is not used after the call to get_grouplength(). Setting the second
- argument FALSE stops it scanning for the end when the length can be found
- in the cache. */
-
- gptr++;
- grouplength = get_grouplength(&gptr, FALSE, errcodeptr, lcptr, group,
- &this_recurse, cb);
- if (grouplength < 0)
- {
- if (*errcodeptr == 0) goto ISNOTFIXED;
- return -1; /* Error already set */
- }
- itemlength = grouplength;
- break;
-
- /* A (DEFINE) group is never obeyed inline and so it does not contribute to
- the length of this branch. Skip from the following item to the next
- unpaired ket. */
-
- case META_COND_DEFINE:
- pptr = parsed_skip(pptr + 1, PSKIP_KET);
- break;
-
- /* Check other nested groups - advance past the initial data for each type
- and then seek a fixed length with get_grouplength(). */
-
- case META_COND_NAME:
- case META_COND_NUMBER:
- case META_COND_RNAME:
- case META_COND_RNUMBER:
- pptr += 2 + SIZEOFFSET;
- goto CHECK_GROUP;
-
- case META_COND_ASSERT:
- pptr += 1;
- goto CHECK_GROUP;
-
- case META_COND_VERSION:
- pptr += 4;
- goto CHECK_GROUP;
-
- case META_CAPTURE:
- group = META_DATA(*pptr);
- /* Fall through */
-
- case META_ATOMIC:
- case META_NOCAPTURE:
- case META_SCRIPT_RUN:
- pptr++;
- CHECK_GROUP:
- grouplength = get_grouplength(&pptr, TRUE, errcodeptr, lcptr, group,
- recurses, cb);
- if (grouplength < 0) return -1;
- itemlength = grouplength;
- break;
-
- /* Exact repetition is OK; variable repetition is not. A repetition of zero
- must subtract the length that has already been added. */
-
- case META_MINMAX:
- case META_MINMAX_PLUS:
- case META_MINMAX_QUERY:
- if (pptr[1] == pptr[2])
- {
- switch(pptr[1])
- {
- case 0:
- branchlength -= lastitemlength;
- break;
-
- case 1:
- itemlength = 0;
- break;
-
- default: /* Check for integer overflow */
- if (lastitemlength != 0 && /* Should not occur, but just in case */
- INT_MAX/lastitemlength < pptr[1] - 1)
- {
- *errcodeptr = ERR87; /* Integer overflow; lookbehind too big */
- return -1;
- }
- itemlength = (pptr[1] - 1) * lastitemlength;
- break;
- }
- pptr += 2;
- break;
- }
- /* Fall through */
-
- /* Any other item means this branch does not have a fixed length. */
-
- default:
- ISNOTFIXED:
- *errcodeptr = ERR25; /* Not fixed length */
- return -1;
- }
-
- /* Add the item length to the branchlength, checking for integer overflow and
- for the branch length exceeding the limit. */
-
- if (INT_MAX - branchlength < (int)itemlength ||
- (branchlength += itemlength) > LOOKBEHIND_MAX)
- {
- *errcodeptr = ERR87;
- return -1;
- }
-
- /* Save this item length for use if the next item is a quantifier. */
-
- lastitemlength = itemlength;
- }
-
-EXIT:
-*pptrptr = pptr;
-return branchlength;
-
-PARSED_SKIP_FAILED:
-*errcodeptr = ERR90;
-return -1;
-}
-
-
-
-/*************************************************
-* Set lengths in a lookbehind *
-*************************************************/
-
-/* This function is called for each lookbehind, to set the lengths in its
-branches. An error occurs if any branch does not have a fixed length that is
-less than the maximum (65535). On exit, the pointer must be left on the final
-ket.
-
-The function also maintains the max_lookbehind value. Any lookbehind branch
-that contains a nested lookbehind may actually look further back than the
-length of the branch. The additional amount is passed back from
-get_branchlength() as an "extra" value.
-
-Arguments:
- pptrptr pointer to pointer in the parsed pattern
- errcodeptr pointer to error code
- lcptr pointer to loop counter
- recurses chain of recurse_check to catch mutual recursion
- cb pointer to compile block
-
-Returns: TRUE if all is well
- FALSE otherwise, with error code and offset set
-*/
-
-static BOOL
-set_lookbehind_lengths(uint32_t **pptrptr, int *errcodeptr, int *lcptr,
- parsed_recurse_check *recurses, compile_block *cb)
-{
-PCRE2_SIZE offset;
-int branchlength;
-uint32_t *bptr = *pptrptr;
-
-READPLUSOFFSET(offset, bptr); /* Offset for error messages */
-*pptrptr += SIZEOFFSET;
-
-do
- {
- *pptrptr += 1;
- branchlength = get_branchlength(pptrptr, errcodeptr, lcptr, recurses, cb);
- if (branchlength < 0)
- {
- /* The errorcode and offset may already be set from a nested lookbehind. */
- if (*errcodeptr == 0) *errcodeptr = ERR25;
- if (cb->erroroffset == PCRE2_UNSET) cb->erroroffset = offset;
- return FALSE;
- }
- if (branchlength > cb->max_lookbehind) cb->max_lookbehind = branchlength;
- *bptr |= branchlength; /* branchlength never more than 65535 */
- bptr = *pptrptr;
- }
-while (*bptr == META_ALT);
-
-return TRUE;
-}
-
-
-
-/*************************************************
-* Check parsed pattern lookbehinds *
-*************************************************/
-
-/* This function is called at the end of parsing a pattern if any lookbehinds
-were encountered. It scans the parsed pattern for them, calling
-set_lookbehind_lengths() for each one. At the start, the errorcode is zero and
-the error offset is marked unset. The enables the functions above not to
-override settings from deeper nestings.
-
-This function is called recursively from get_branchlength() for lookaheads in
-order to process any lookbehinds that they may contain. It stops when it hits a
-non-nested closing parenthesis in this case, returning a pointer to it.
-
-Arguments
- pptr points to where to start (start of pattern or start of lookahead)
- retptr if not NULL, return the ket pointer here
- recurses chain of recurse_check to catch mutual recursion
- cb points to the compile block
- lcptr points to loop counter
-
-Returns: 0 on success, or an errorcode (cb->erroroffset will be set)
-*/
-
-static int
-check_lookbehinds(uint32_t *pptr, uint32_t **retptr,
- parsed_recurse_check *recurses, compile_block *cb, int *lcptr)
-{
-int errorcode = 0;
-int nestlevel = 0;
-
-cb->erroroffset = PCRE2_UNSET;
-
-for (; *pptr != META_END; pptr++)
- {
- if (*pptr < META_END) continue; /* Literal */
-
- switch (META_CODE(*pptr))
- {
- default:
- return ERR70; /* Unrecognized meta code */
-
- case META_ESCAPE:
- if (*pptr - META_ESCAPE == ESC_P || *pptr - META_ESCAPE == ESC_p)
- pptr += 1;
- break;
-
- case META_KET:
- if (--nestlevel < 0)
- {
- if (retptr != NULL) *retptr = pptr;
- return 0;
- }
- break;
-
- case META_ATOMIC:
- case META_CAPTURE:
- case META_COND_ASSERT:
- case META_LOOKAHEAD:
- case META_LOOKAHEADNOT:
- case META_LOOKAHEAD_NA:
- case META_NOCAPTURE:
- case META_SCRIPT_RUN:
- nestlevel++;
- break;
-
- case META_ACCEPT:
- case META_ALT:
- case META_ASTERISK:
- case META_ASTERISK_PLUS:
- case META_ASTERISK_QUERY:
- case META_BACKREF:
- case META_CIRCUMFLEX:
- case META_CLASS:
- case META_CLASS_EMPTY:
- case META_CLASS_EMPTY_NOT:
- case META_CLASS_END:
- case META_CLASS_NOT:
- case META_COMMIT:
- case META_DOLLAR:
- case META_DOT:
- case META_FAIL:
- case META_PLUS:
- case META_PLUS_PLUS:
- case META_PLUS_QUERY:
- case META_PRUNE:
- case META_QUERY:
- case META_QUERY_PLUS:
- case META_QUERY_QUERY:
- case META_RANGE_ESCAPED:
- case META_RANGE_LITERAL:
- case META_SKIP:
- case META_THEN:
- break;
-
- case META_RECURSE:
- pptr += SIZEOFFSET;
- break;
-
- case META_BACKREF_BYNAME:
- case META_RECURSE_BYNAME:
- pptr += 1 + SIZEOFFSET;
- break;
-
- case META_COND_DEFINE:
- pptr += SIZEOFFSET;
- nestlevel++;
- break;
-
- case META_COND_NAME:
- case META_COND_NUMBER:
- case META_COND_RNAME:
- case META_COND_RNUMBER:
- pptr += 1 + SIZEOFFSET;
- nestlevel++;
- break;
-
- case META_COND_VERSION:
- pptr += 3;
- nestlevel++;
- break;
-
- case META_CALLOUT_STRING:
- pptr += 3 + SIZEOFFSET;
- break;
-
- case META_BIGVALUE:
- case META_OPTIONS:
- case META_POSIX:
- case META_POSIX_NEG:
- pptr += 1;
- break;
-
- case META_MINMAX:
- case META_MINMAX_QUERY:
- case META_MINMAX_PLUS:
- pptr += 2;
- break;
-
- case META_CALLOUT_NUMBER:
- pptr += 3;
- break;
-
- case META_MARK:
- case META_COMMIT_ARG:
- case META_PRUNE_ARG:
- case META_SKIP_ARG:
- case META_THEN_ARG:
- pptr += 1 + pptr[1];
- break;
-
- case META_LOOKBEHIND:
- case META_LOOKBEHINDNOT:
- case META_LOOKBEHIND_NA:
- if (!set_lookbehind_lengths(&pptr, &errorcode, lcptr, recurses, cb))
- return errorcode;
- break;
- }
- }
-
-return 0;
-}
-
-
-
-/*************************************************
-* External function to compile a pattern *
-*************************************************/
-
-/* This function reads a regular expression in the form of a string and returns
-a pointer to a block of store holding a compiled version of the expression.
-
-Arguments:
- pattern the regular expression
- patlen the length of the pattern, or PCRE2_ZERO_TERMINATED
- options option bits
- errorptr pointer to errorcode
- erroroffset pointer to error offset
- ccontext points to a compile context or is NULL
-
-Returns: pointer to compiled data block, or NULL on error,
- with errorcode and erroroffset set
-*/
-
-PCRE2_EXP_DEFN pcre2_code * PCRE2_CALL_CONVENTION
-pcre2_compile(PCRE2_SPTR pattern, PCRE2_SIZE patlen, uint32_t options,
- int *errorptr, PCRE2_SIZE *erroroffset, pcre2_compile_context *ccontext)
-{
-BOOL utf; /* Set TRUE for UTF mode */
-BOOL ucp; /* Set TRUE for UCP mode */
-BOOL has_lookbehind = FALSE; /* Set TRUE if a lookbehind is found */
-BOOL zero_terminated; /* Set TRUE for zero-terminated pattern */
-pcre2_real_code *re = NULL; /* What we will return */
-compile_block cb; /* "Static" compile-time data */
-const uint8_t *tables; /* Char tables base pointer */
-
-PCRE2_UCHAR *code; /* Current pointer in compiled code */
-PCRE2_SPTR codestart; /* Start of compiled code */
-PCRE2_SPTR ptr; /* Current pointer in pattern */
-uint32_t *pptr; /* Current pointer in parsed pattern */
-
-PCRE2_SIZE length = 1; /* Allow for final END opcode */
-PCRE2_SIZE usedlength; /* Actual length used */
-PCRE2_SIZE re_blocksize; /* Size of memory block */
-PCRE2_SIZE big32count = 0; /* 32-bit literals >= 0x80000000 */
-PCRE2_SIZE parsed_size_needed; /* Needed for parsed pattern */
-
-uint32_t firstcuflags, reqcuflags; /* Type of first/req code unit */
-uint32_t firstcu, reqcu; /* Value of first/req code unit */
-uint32_t setflags = 0; /* NL and BSR set flags */
-
-uint32_t skipatstart; /* When checking (*UTF) etc */
-uint32_t limit_heap = UINT32_MAX;
-uint32_t limit_match = UINT32_MAX; /* Unset match limits */
-uint32_t limit_depth = UINT32_MAX;
-
-int newline = 0; /* Unset; can be set by the pattern */
-int bsr = 0; /* Unset; can be set by the pattern */
-int errorcode = 0; /* Initialize to avoid compiler warn */
-int regexrc; /* Return from compile */
-
-uint32_t i; /* Local loop counter */
-
-/* Comments at the head of this file explain about these variables. */
-
-uint32_t stack_groupinfo[GROUPINFO_DEFAULT_SIZE];
-uint32_t stack_parsed_pattern[PARSED_PATTERN_DEFAULT_SIZE];
-named_group named_groups[NAMED_GROUP_LIST_SIZE];
-
-/* The workspace is used in different ways in the different compiling phases.
-It needs to be 16-bit aligned for the preliminary parsing scan. */
-
-uint32_t c16workspace[C16_WORK_SIZE];
-PCRE2_UCHAR *cworkspace = (PCRE2_UCHAR *)c16workspace;
-
-
-/* -------------- Check arguments and set up the pattern ----------------- */
-
-/* There must be error code and offset pointers. */
-
-if (errorptr == NULL || erroroffset == NULL) return NULL;
-*errorptr = ERR0;
-*erroroffset = 0;
-
-/* There must be a pattern! */
-
-if (pattern == NULL)
- {
- *errorptr = ERR16;
- return NULL;
- }
-
-/* A NULL compile context means "use a default context" */
-
-if (ccontext == NULL)
- ccontext = (pcre2_compile_context *)(&PRIV(default_compile_context));
-
-/* PCRE2_MATCH_INVALID_UTF implies UTF */
-
-if ((options & PCRE2_MATCH_INVALID_UTF) != 0) options |= PCRE2_UTF;
-
-/* Check that all undefined public option bits are zero. */
-
-if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0 ||
- (ccontext->extra_options & ~PUBLIC_COMPILE_EXTRA_OPTIONS) != 0)
- {
- *errorptr = ERR17;
- return NULL;
- }
-
-if ((options & PCRE2_LITERAL) != 0 &&
- ((options & ~PUBLIC_LITERAL_COMPILE_OPTIONS) != 0 ||
- (ccontext->extra_options & ~PUBLIC_LITERAL_COMPILE_EXTRA_OPTIONS) != 0))
- {
- *errorptr = ERR92;
- return NULL;
- }
-
-/* A zero-terminated pattern is indicated by the special length value
-PCRE2_ZERO_TERMINATED. Check for an overlong pattern. */
-
-if ((zero_terminated = (patlen == PCRE2_ZERO_TERMINATED)))
- patlen = PRIV(strlen)(pattern);
-
-if (patlen > ccontext->max_pattern_length)
- {
- *errorptr = ERR88;
- return NULL;
- }
-
-/* From here on, all returns from this function should end up going via the
-EXIT label. */
-
-
-/* ------------ Initialize the "static" compile data -------------- */
-
-tables = (ccontext->tables != NULL)? ccontext->tables : PRIV(default_tables);
-
-cb.lcc = tables + lcc_offset; /* Individual */
-cb.fcc = tables + fcc_offset; /* character */
-cb.cbits = tables + cbits_offset; /* tables */
-cb.ctypes = tables + ctypes_offset;
-
-cb.assert_depth = 0;
-cb.bracount = 0;
-cb.cx = ccontext;
-cb.dupnames = FALSE;
-cb.end_pattern = pattern + patlen;
-cb.erroroffset = 0;
-cb.external_flags = 0;
-cb.external_options = options;
-cb.groupinfo = stack_groupinfo;
-cb.had_recurse = FALSE;
-cb.lastcapture = 0;
-cb.max_lookbehind = 0;
-cb.name_entry_size = 0;
-cb.name_table = NULL;
-cb.named_groups = named_groups;
-cb.named_group_list_size = NAMED_GROUP_LIST_SIZE;
-cb.names_found = 0;
-cb.open_caps = NULL;
-cb.parens_depth = 0;
-cb.parsed_pattern = stack_parsed_pattern;
-cb.req_varyopt = 0;
-cb.start_code = cworkspace;
-cb.start_pattern = pattern;
-cb.start_workspace = cworkspace;
-cb.workspace_size = COMPILE_WORK_SIZE;
-
-/* Maximum back reference and backref bitmap. The bitmap records up to 31 back
-references to help in deciding whether (.*) can be treated as anchored or not.
-*/
-
-cb.top_backref = 0;
-cb.backref_map = 0;
-
-/* Escape sequences \1 to \9 are always back references, but as they are only
-two characters long, only two elements can be used in the parsed_pattern
-vector. The first contains the reference, and we'd like to use the second to
-record the offset in the pattern, so that forward references to non-existent
-groups can be diagnosed later with an offset. However, on 64-bit systems,
-PCRE2_SIZE won't fit. Instead, we have a vector of offsets for the first
-occurrence of \1 to \9, indexed by the second parsed_pattern value. All other
-references have enough space for the offset to be put into the parsed pattern.
-*/
-
-for (i = 0; i < 10; i++) cb.small_ref_offset[i] = PCRE2_UNSET;
-
-
-/* --------------- Start looking at the pattern --------------- */
-
-/* Unless PCRE2_LITERAL is set, check for global one-time option settings at
-the start of the pattern, and remember the offset to the actual regex. With
-valgrind support, make the terminator of a zero-terminated pattern
-inaccessible. This catches bugs that would otherwise only show up for
-non-zero-terminated patterns. */
-
-#ifdef SUPPORT_VALGRIND
-if (zero_terminated) VALGRIND_MAKE_MEM_NOACCESS(pattern + patlen, CU2BYTES(1));
-#endif
-
-ptr = pattern;
-skipatstart = 0;
-
-if ((options & PCRE2_LITERAL) == 0)
- {
- while (patlen - skipatstart >= 2 &&
- ptr[skipatstart] == CHAR_LEFT_PARENTHESIS &&
- ptr[skipatstart+1] == CHAR_ASTERISK)
- {
- for (i = 0; i < sizeof(pso_list)/sizeof(pso); i++)
- {
- uint32_t c, pp;
- pso *p = pso_list + i;
-
- if (patlen - skipatstart - 2 >= p->length &&
- PRIV(strncmp_c8)(ptr + skipatstart + 2, (char *)(p->name),
- p->length) == 0)
- {
- skipatstart += p->length + 2;
- switch(p->type)
- {
- case PSO_OPT:
- cb.external_options |= p->value;
- break;
-
- case PSO_FLG:
- setflags |= p->value;
- break;
-
- case PSO_NL:
- newline = p->value;
- setflags |= PCRE2_NL_SET;
- break;
-
- case PSO_BSR:
- bsr = p->value;
- setflags |= PCRE2_BSR_SET;
- break;
-
- case PSO_LIMM:
- case PSO_LIMD:
- case PSO_LIMH:
- c = 0;
- pp = skipatstart;
- if (!IS_DIGIT(ptr[pp]))
- {
- errorcode = ERR60;
- ptr += pp;
- goto HAD_EARLY_ERROR;
- }
- while (IS_DIGIT(ptr[pp]))
- {
- if (c > UINT32_MAX / 10 - 1) break; /* Integer overflow */
- c = c*10 + (ptr[pp++] - CHAR_0);
- }
- if (ptr[pp++] != CHAR_RIGHT_PARENTHESIS)
- {
- errorcode = ERR60;
- ptr += pp;
- goto HAD_EARLY_ERROR;
- }
- if (p->type == PSO_LIMH) limit_heap = c;
- else if (p->type == PSO_LIMM) limit_match = c;
- else limit_depth = c;
- skipatstart += pp - skipatstart;
- break;
- }
- break; /* Out of the table scan loop */
- }
- }
- if (i >= sizeof(pso_list)/sizeof(pso)) break; /* Out of pso loop */
- }
- }
-
-/* End of pattern-start options; advance to start of real regex. */
-
-ptr += skipatstart;
-
-/* Can't support UTF or UCP if PCRE2 was built without Unicode support. */
-
-#ifndef SUPPORT_UNICODE
-if ((cb.external_options & (PCRE2_UTF|PCRE2_UCP)) != 0)
- {
- errorcode = ERR32;
- goto HAD_EARLY_ERROR;
- }
-#endif
-
-/* Check UTF. We have the original options in 'options', with that value as
-modified by (*UTF) etc in cb->external_options. The extra option
-PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES is not permitted in UTF-16 mode because the
-surrogate code points cannot be represented in UTF-16. */
-
-utf = (cb.external_options & PCRE2_UTF) != 0;
-if (utf)
- {
- if ((options & PCRE2_NEVER_UTF) != 0)
- {
- errorcode = ERR74;
- goto HAD_EARLY_ERROR;
- }
- if ((options & PCRE2_NO_UTF_CHECK) == 0 &&
- (errorcode = PRIV(valid_utf)(pattern, patlen, erroroffset)) != 0)
- goto HAD_ERROR; /* Offset was set by valid_utf() */
-
-#if PCRE2_CODE_UNIT_WIDTH == 16
- if ((ccontext->extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) != 0)
- {
- errorcode = ERR91;
- goto HAD_EARLY_ERROR;
- }
-#endif
- }
-
-/* Check UCP lockout. */
-
-ucp = (cb.external_options & PCRE2_UCP) != 0;
-if (ucp && (cb.external_options & PCRE2_NEVER_UCP) != 0)
- {
- errorcode = ERR75;
- goto HAD_EARLY_ERROR;
- }
-
-/* Process the BSR setting. */
-
-if (bsr == 0) bsr = ccontext->bsr_convention;
-
-/* Process the newline setting. */
-
-if (newline == 0) newline = ccontext->newline_convention;
-cb.nltype = NLTYPE_FIXED;
-switch(newline)
- {
- case PCRE2_NEWLINE_CR:
- cb.nllen = 1;
- cb.nl[0] = CHAR_CR;
- break;
-
- case PCRE2_NEWLINE_LF:
- cb.nllen = 1;
- cb.nl[0] = CHAR_NL;
- break;
-
- case PCRE2_NEWLINE_NUL:
- cb.nllen = 1;
- cb.nl[0] = CHAR_NUL;
- break;
-
- case PCRE2_NEWLINE_CRLF:
- cb.nllen = 2;
- cb.nl[0] = CHAR_CR;
- cb.nl[1] = CHAR_NL;
- break;
-
- case PCRE2_NEWLINE_ANY:
- cb.nltype = NLTYPE_ANY;
- break;
-
- case PCRE2_NEWLINE_ANYCRLF:
- cb.nltype = NLTYPE_ANYCRLF;
- break;
-
- default:
- errorcode = ERR56;
- goto HAD_EARLY_ERROR;
- }
-
-/* Pre-scan the pattern to do two things: (1) Discover the named groups and
-their numerical equivalents, so that this information is always available for
-the remaining processing. (2) At the same time, parse the pattern and put a
-processed version into the parsed_pattern vector. This has escapes interpreted
-and comments removed (amongst other things).
-
-In all but one case, when PCRE2_AUTO_CALLOUT is not set, the number of unsigned
-32-bit ints in the parsed pattern is bounded by the length of the pattern plus
-one (for the terminator) plus four if PCRE2_EXTRA_WORD or PCRE2_EXTRA_LINE is
-set. The exceptional case is when running in 32-bit, non-UTF mode, when literal
-characters greater than META_END (0x80000000) have to be coded as two units. In
-this case, therefore, we scan the pattern to check for such values. */
-
-#if PCRE2_CODE_UNIT_WIDTH == 32
-if (!utf)
- {
- PCRE2_SPTR p;
- for (p = ptr; p < cb.end_pattern; p++) if (*p >= META_END) big32count++;
- }
-#endif
-
-/* Ensure that the parsed pattern buffer is big enough. When PCRE2_AUTO_CALLOUT
-is set we have to assume a numerical callout (4 elements) for each character
-plus one at the end. This is overkill, but memory is plentiful these days. For
-many smaller patterns the vector on the stack (which was set up above) can be
-used. */
-
-parsed_size_needed = patlen - skipatstart + big32count;
-
-if ((ccontext->extra_options &
- (PCRE2_EXTRA_MATCH_WORD|PCRE2_EXTRA_MATCH_LINE)) != 0)
- parsed_size_needed += 4;
-
-if ((options & PCRE2_AUTO_CALLOUT) != 0)
- parsed_size_needed = (parsed_size_needed + 1) * 5;
-
-if (parsed_size_needed >= PARSED_PATTERN_DEFAULT_SIZE)
- {
- uint32_t *heap_parsed_pattern = ccontext->memctl.malloc(
- (parsed_size_needed + 1) * sizeof(uint32_t), ccontext->memctl.memory_data);
- if (heap_parsed_pattern == NULL)
- {
- *errorptr = ERR21;
- goto EXIT;
- }
- cb.parsed_pattern = heap_parsed_pattern;
- }
-cb.parsed_pattern_end = cb.parsed_pattern + parsed_size_needed + 1;
-
-/* Do the parsing scan. */
-
-errorcode = parse_regex(ptr, cb.external_options, &has_lookbehind, &cb);
-if (errorcode != 0) goto HAD_CB_ERROR;
-
-/* Workspace is needed to remember information about numbered groups: whether a
-group can match an empty string and what its fixed length is. This is done to
-avoid the possibility of recursive references causing very long compile times
-when checking these features. Unnumbered groups do not have this exposure since
-they cannot be referenced. We use an indexed vector for this purpose. If there
-are sufficiently few groups, the default vector on the stack, as set up above,
-can be used. Otherwise we have to get/free a special vector. The vector must be
-initialized to zero. */
-
-if (cb.bracount >= GROUPINFO_DEFAULT_SIZE)
- {
- cb.groupinfo = ccontext->memctl.malloc(
- (cb.bracount + 1)*sizeof(uint32_t), ccontext->memctl.memory_data);
- if (cb.groupinfo == NULL)
- {
- errorcode = ERR21;
- cb.erroroffset = 0;
- goto HAD_CB_ERROR;
- }
- }
-memset(cb.groupinfo, 0, (cb.bracount + 1) * sizeof(uint32_t));
-
-/* If there were any lookbehinds, scan the parsed pattern to figure out their
-lengths. */
-
-if (has_lookbehind)
- {
- int loopcount = 0;
- errorcode = check_lookbehinds(cb.parsed_pattern, NULL, NULL, &cb, &loopcount);
- if (errorcode != 0) goto HAD_CB_ERROR;
- }
-
-/* For debugging, there is a function that shows the parsed data vector. */
-
-#ifdef DEBUG_SHOW_PARSED
-fprintf(stderr, "+++ Pre-scan complete:\n");
-show_parsed(&cb);
-#endif
-
-/* For debugging capturing information this code can be enabled. */
-
-#ifdef DEBUG_SHOW_CAPTURES
- {
- named_group *ng = cb.named_groups;
- fprintf(stderr, "+++Captures: %d\n", cb.bracount);
- for (i = 0; i < cb.names_found; i++, ng++)
- {
- fprintf(stderr, "+++%3d %.*s\n", ng->number, ng->length, ng->name);
- }
- }
-#endif
-
-/* Pretend to compile the pattern while actually just accumulating the amount
-of memory required in the 'length' variable. This behaviour is triggered by
-passing a non-NULL final argument to compile_regex(). We pass a block of
-workspace (cworkspace) for it to compile parts of the pattern into; the
-compiled code is discarded when it is no longer needed, so hopefully this
-workspace will never overflow, though there is a test for its doing so.
-
-On error, errorcode will be set non-zero, so we don't need to look at the
-result of the function. The initial options have been put into the cb block,
-but we still have to pass a separate options variable (the first argument)
-because the options may change as the pattern is processed. */
-
-cb.erroroffset = patlen; /* For any subsequent errors that do not set it */
-pptr = cb.parsed_pattern;
-code = cworkspace;
-*code = OP_BRA;
-
-(void)compile_regex(cb.external_options, &code, &pptr, &errorcode, 0, &firstcu,
- &firstcuflags, &reqcu, &reqcuflags, NULL, &cb, &length);
-
-if (errorcode != 0) goto HAD_CB_ERROR; /* Offset is in cb.erroroffset */
-
-/* This should be caught in compile_regex(), but just in case... */
-
-if (length > MAX_PATTERN_SIZE)
- {
- errorcode = ERR20;
- goto HAD_CB_ERROR;
- }
-
-/* Compute the size of, and then get and initialize, the data block for storing
-the compiled pattern and names table. Integer overflow should no longer be
-possible because nowadays we limit the maximum value of cb.names_found and
-cb.name_entry_size. */
-
-re_blocksize = sizeof(pcre2_real_code) +
- CU2BYTES(length +
- (PCRE2_SIZE)cb.names_found * (PCRE2_SIZE)cb.name_entry_size);
-re = (pcre2_real_code *)
- ccontext->memctl.malloc(re_blocksize, ccontext->memctl.memory_data);
-if (re == NULL)
- {
- errorcode = ERR21;
- goto HAD_CB_ERROR;
- }
-
-/* The compiler may put padding at the end of the pcre2_real_code structure in
-order to round it up to a multiple of 4 or 8 bytes. This means that when a
-compiled pattern is copied (for example, when serialized) undefined bytes are
-read, and this annoys debuggers such as valgrind. To avoid this, we explicitly
-write to the last 8 bytes of the structure before setting the fields. */
-
-memset((char *)re + sizeof(pcre2_real_code) - 8, 0, 8);
-re->memctl = ccontext->memctl;
-re->tables = tables;
-re->executable_jit = NULL;
-memset(re->start_bitmap, 0, 32 * sizeof(uint8_t));
-re->blocksize = re_blocksize;
-re->magic_number = MAGIC_NUMBER;
-re->compile_options = options;
-re->overall_options = cb.external_options;
-re->extra_options = ccontext->extra_options;
-re->flags = PCRE2_CODE_UNIT_WIDTH/8 | cb.external_flags | setflags;
-re->limit_heap = limit_heap;
-re->limit_match = limit_match;
-re->limit_depth = limit_depth;
-re->first_codeunit = 0;
-re->last_codeunit = 0;
-re->bsr_convention = bsr;
-re->newline_convention = newline;
-re->max_lookbehind = 0;
-re->minlength = 0;
-re->top_bracket = 0;
-re->top_backref = 0;
-re->name_entry_size = cb.name_entry_size;
-re->name_count = cb.names_found;
-
-/* The basic block is immediately followed by the name table, and the compiled
-code follows after that. */
-
-codestart = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code)) +
- re->name_entry_size * re->name_count;
-
-/* Update the compile data block for the actual compile. The starting points of
-the name/number translation table and of the code are passed around in the
-compile data block. The start/end pattern and initial options are already set
-from the pre-compile phase, as is the name_entry_size field. */
-
-cb.parens_depth = 0;
-cb.assert_depth = 0;
-cb.lastcapture = 0;
-cb.name_table = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code));
-cb.start_code = codestart;
-cb.req_varyopt = 0;
-cb.had_accept = FALSE;
-cb.had_pruneorskip = FALSE;
-cb.open_caps = NULL;
-
-/* If any named groups were found, create the name/number table from the list
-created in the pre-pass. */
-
-if (cb.names_found > 0)
- {
- named_group *ng = cb.named_groups;
- for (i = 0; i < cb.names_found; i++, ng++)
- add_name_to_table(&cb, ng->name, ng->length, ng->number, i);
- }
-
-/* Set up a starting, non-extracting bracket, then compile the expression. On
-error, errorcode will be set non-zero, so we don't need to look at the result
-of the function here. */
-
-pptr = cb.parsed_pattern;
-code = (PCRE2_UCHAR *)codestart;
-*code = OP_BRA;
-regexrc = compile_regex(re->overall_options, &code, &pptr, &errorcode, 0,
- &firstcu, &firstcuflags, &reqcu, &reqcuflags, NULL, &cb, NULL);
-if (regexrc < 0) re->flags |= PCRE2_MATCH_EMPTY;
-re->top_bracket = cb.bracount;
-re->top_backref = cb.top_backref;
-re->max_lookbehind = cb.max_lookbehind;
-
-if (cb.had_accept)
- {
- reqcu = 0; /* Must disable after (*ACCEPT) */
- reqcuflags = REQ_NONE;
- re->flags |= PCRE2_HASACCEPT; /* Disables minimum length */
- }
-
-/* Fill in the final opcode and check for disastrous overflow. If no overflow,
-but the estimated length exceeds the really used length, adjust the value of
-re->blocksize, and if valgrind support is configured, mark the extra allocated
-memory as unaddressable, so that any out-of-bound reads can be detected. */
-
-*code++ = OP_END;
-usedlength = code - codestart;
-if (usedlength > length) errorcode = ERR23; else
- {
- re->blocksize -= CU2BYTES(length - usedlength);
-#ifdef SUPPORT_VALGRIND
- VALGRIND_MAKE_MEM_NOACCESS(code, CU2BYTES(length - usedlength));
-#endif
- }
-
-/* Scan the pattern for recursion/subroutine calls and convert the group
-numbers into offsets. Maintain a small cache so that repeated groups containing
-recursions are efficiently handled. */
-
-#define RSCAN_CACHE_SIZE 8
-
-if (errorcode == 0 && cb.had_recurse)
- {
- PCRE2_UCHAR *rcode;
- PCRE2_SPTR rgroup;
- unsigned int ccount = 0;
- int start = RSCAN_CACHE_SIZE;
- recurse_cache rc[RSCAN_CACHE_SIZE];
-
- for (rcode = (PCRE2_UCHAR *)find_recurse(codestart, utf);
- rcode != NULL;
- rcode = (PCRE2_UCHAR *)find_recurse(rcode + 1 + LINK_SIZE, utf))
- {
- int p, groupnumber;
-
- groupnumber = (int)GET(rcode, 1);
- if (groupnumber == 0) rgroup = codestart; else
- {
- PCRE2_SPTR search_from = codestart;
- rgroup = NULL;
- for (i = 0, p = start; i < ccount; i++, p = (p + 1) & 7)
- {
- if (groupnumber == rc[p].groupnumber)
- {
- rgroup = rc[p].group;
- break;
- }
-
- /* Group n+1 must always start to the right of group n, so we can save
- search time below when the new group number is greater than any of the
- previously found groups. */
-
- if (groupnumber > rc[p].groupnumber) search_from = rc[p].group;
- }
-
- if (rgroup == NULL)
- {
- rgroup = PRIV(find_bracket)(search_from, utf, groupnumber);
- if (rgroup == NULL)
- {
- errorcode = ERR53;
- break;
- }
- if (--start < 0) start = RSCAN_CACHE_SIZE - 1;
- rc[start].groupnumber = groupnumber;
- rc[start].group = rgroup;
- if (ccount < RSCAN_CACHE_SIZE) ccount++;
- }
- }
-
- PUT(rcode, 1, rgroup - codestart);
- }
- }
-
-/* In rare debugging situations we sometimes need to look at the compiled code
-at this stage. */
-
-#ifdef DEBUG_CALL_PRINTINT
-pcre2_printint(re, stderr, TRUE);
-fprintf(stderr, "Length=%lu Used=%lu\n", length, usedlength);
-#endif
-
-/* Unless disabled, check whether any single character iterators can be
-auto-possessified. The function overwrites the appropriate opcode values, so
-the type of the pointer must be cast. NOTE: the intermediate variable "temp" is
-used in this code because at least one compiler gives a warning about loss of
-"const" attribute if the cast (PCRE2_UCHAR *)codestart is used directly in the
-function call. */
-
-if (errorcode == 0 && (re->overall_options & PCRE2_NO_AUTO_POSSESS) == 0)
- {
- PCRE2_UCHAR *temp = (PCRE2_UCHAR *)codestart;
- if (PRIV(auto_possessify)(temp, &cb) != 0) errorcode = ERR80;
- }
-
-/* Failed to compile, or error while post-processing. */
-
-if (errorcode != 0) goto HAD_CB_ERROR;
-
-/* Successful compile. If the anchored option was not passed, set it if
-we can determine that the pattern is anchored by virtue of ^ characters or \A
-or anything else, such as starting with non-atomic .* when DOTALL is set and
-there are no occurrences of *PRUNE or *SKIP (though there is an option to
-disable this case). */
-
-if ((re->overall_options & PCRE2_ANCHORED) == 0 &&
- is_anchored(codestart, 0, &cb, 0, FALSE))
- re->overall_options |= PCRE2_ANCHORED;
-
-/* Set up the first code unit or startline flag, the required code unit, and
-then study the pattern. This code need not be obeyed if PCRE2_NO_START_OPTIMIZE
-is set, as the data it would create will not be used. Note that a first code
-unit (but not the startline flag) is useful for anchored patterns because it
-can still give a quick "no match" and also avoid searching for a last code
-unit. */
-
-if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
- {
- int minminlength = 0; /* For minimal minlength from first/required CU */
-
- /* If we do not have a first code unit, see if there is one that is asserted
- (these are not saved during the compile because they can cause conflicts with
- actual literals that follow). */
-
- if (firstcuflags >= REQ_NONE)
- firstcu = find_firstassertedcu(codestart, &firstcuflags, 0);
-
- /* Save the data for a first code unit. The existence of one means the
- minimum length must be at least 1. */
-
- if (firstcuflags < REQ_NONE)
- {
- re->first_codeunit = firstcu;
- re->flags |= PCRE2_FIRSTSET;
- minminlength++;
-
- /* Handle caseless first code units. */
-
- if ((firstcuflags & REQ_CASELESS) != 0)
- {
- if (firstcu < 128 || (!utf && !ucp && firstcu < 255))
- {
- if (cb.fcc[firstcu] != firstcu) re->flags |= PCRE2_FIRSTCASELESS;
- }
-
- /* The first code unit is > 128 in UTF or UCP mode, or > 255 otherwise.
- In 8-bit UTF mode, codepoints in the range 128-255 are introductory code
- points and cannot have another case, but if UCP is set they may do. */
-
-#ifdef SUPPORT_UNICODE
-#if PCRE2_CODE_UNIT_WIDTH == 8
- else if (ucp && !utf && UCD_OTHERCASE(firstcu) != firstcu)
- re->flags |= PCRE2_FIRSTCASELESS;
-#else
- else if ((utf || ucp) && firstcu <= MAX_UTF_CODE_POINT &&
- UCD_OTHERCASE(firstcu) != firstcu)
- re->flags |= PCRE2_FIRSTCASELESS;
-#endif
-#endif /* SUPPORT_UNICODE */
- }
- }
-
- /* When there is no first code unit, for non-anchored patterns, see if we can
- set the PCRE2_STARTLINE flag. This is helpful for multiline matches when all
- branches start with ^ and also when all branches start with non-atomic .* for
- non-DOTALL matches when *PRUNE and SKIP are not present. (There is an option
- that disables this case.) */
-
- else if ((re->overall_options & PCRE2_ANCHORED) == 0 &&
- is_startline(codestart, 0, &cb, 0, FALSE))
- re->flags |= PCRE2_STARTLINE;
-
- /* Handle the "required code unit", if one is set. In the UTF case we can
- increment the minimum minimum length only if we are sure this really is a
- different character and not a non-starting code unit of the first character,
- because the minimum length count is in characters, not code units. */
-
- if (reqcuflags < REQ_NONE)
- {
-#if PCRE2_CODE_UNIT_WIDTH == 16
- if ((re->overall_options & PCRE2_UTF) == 0 || /* Not UTF */
- firstcuflags >= REQ_NONE || /* First not set */
- (firstcu & 0xf800) != 0xd800 || /* First not surrogate */
- (reqcu & 0xfc00) != 0xdc00) /* Req not low surrogate */
-#elif PCRE2_CODE_UNIT_WIDTH == 8
- if ((re->overall_options & PCRE2_UTF) == 0 || /* Not UTF */
- firstcuflags >= REQ_NONE || /* First not set */
- (firstcu & 0x80) == 0 || /* First is ASCII */
- (reqcu & 0x80) == 0) /* Req is ASCII */
-#endif
- {
- minminlength++;
- }
-
- /* In the case of an anchored pattern, set up the value only if it follows
- a variable length item in the pattern. */
-
- if ((re->overall_options & PCRE2_ANCHORED) == 0 ||
- (reqcuflags & REQ_VARY) != 0)
- {
- re->last_codeunit = reqcu;
- re->flags |= PCRE2_LASTSET;
-
- /* Handle caseless required code units as for first code units (above). */
-
- if ((reqcuflags & REQ_CASELESS) != 0)
- {
- if (reqcu < 128 || (!utf && !ucp && reqcu < 255))
- {
- if (cb.fcc[reqcu] != reqcu) re->flags |= PCRE2_LASTCASELESS;
- }
-#ifdef SUPPORT_UNICODE
-#if PCRE2_CODE_UNIT_WIDTH == 8
- else if (ucp && !utf && UCD_OTHERCASE(reqcu) != reqcu)
- re->flags |= PCRE2_LASTCASELESS;
-#else
- else if ((utf || ucp) && reqcu <= MAX_UTF_CODE_POINT &&
- UCD_OTHERCASE(reqcu) != reqcu)
- re->flags |= PCRE2_LASTCASELESS;
-#endif
-#endif /* SUPPORT_UNICODE */
- }
- }
- }
-
- /* Study the compiled pattern to set up information such as a bitmap of
- starting code units and a minimum matching length. */
-
- if (PRIV(study)(re) != 0)
- {
- errorcode = ERR31;
- goto HAD_CB_ERROR;
- }
-
- /* If study() set a bitmap of starting code units, it implies a minimum
- length of at least one. */
-
- if ((re->flags & PCRE2_FIRSTMAPSET) != 0 && minminlength == 0)
- minminlength = 1;
-
- /* If the minimum length set (or not set) by study() is less than the minimum
- implied by required code units, override it. */
-
- if (re->minlength < minminlength) re->minlength = minminlength;
- } /* End of start-of-match optimizations. */
-
-/* Control ends up here in all cases. When running under valgrind, make a
-pattern's terminating zero defined again. If memory was obtained for the parsed
-version of the pattern, free it before returning. Also free the list of named
-groups if a larger one had to be obtained, and likewise the group information
-vector. */
-
-EXIT:
-#ifdef SUPPORT_VALGRIND
-if (zero_terminated) VALGRIND_MAKE_MEM_DEFINED(pattern + patlen, CU2BYTES(1));
-#endif
-if (cb.parsed_pattern != stack_parsed_pattern)
- ccontext->memctl.free(cb.parsed_pattern, ccontext->memctl.memory_data);
-if (cb.named_group_list_size > NAMED_GROUP_LIST_SIZE)
- ccontext->memctl.free((void *)cb.named_groups, ccontext->memctl.memory_data);
-if (cb.groupinfo != stack_groupinfo)
- ccontext->memctl.free((void *)cb.groupinfo, ccontext->memctl.memory_data);
-return re; /* Will be NULL after an error */
-
-/* Errors discovered in parse_regex() set the offset value in the compile
-block. Errors discovered before it is called must compute it from the ptr
-value. After parse_regex() is called, the offset in the compile block is set to
-the end of the pattern, but certain errors in compile_regex() may reset it if
-an offset is available in the parsed pattern. */
-
-HAD_CB_ERROR:
-ptr = pattern + cb.erroroffset;
-
-HAD_EARLY_ERROR:
-*erroroffset = ptr - pattern;
-
-HAD_ERROR:
-*errorptr = errorcode;
-pcre2_code_free(re);
-re = NULL;
-goto EXIT;
-}
-
-/* These #undefs are here to enable unity builds with CMake. */
-
-#undef NLBLOCK /* Block containing newline information */
-#undef PSSTART /* Field containing processed string start */
-#undef PSEND /* Field containing processed string end */
-
-/* End of pcre2_compile.c */
diff --git a/contrib/libs/pcre2/src/pcre2_config.c b/contrib/libs/pcre2/src/pcre2_config.c
deleted file mode 100644
index 04a011a29c..0000000000
--- a/contrib/libs/pcre2/src/pcre2_config.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2020 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-/* Save the configured link size, which is in bytes. In 16-bit and 32-bit modes
-its value gets changed by pcre2_intmodedep.h (included by pcre2_internal.h) to
-be in code units. */
-
-static int configured_link_size = LINK_SIZE;
-
-#include "pcre2_internal.h"
-
-/* These macros are the standard way of turning unquoted text into C strings.
-They allow macros like PCRE2_MAJOR to be defined without quotes, which is
-convenient for user programs that want to test their values. */
-
-#define STRING(a) # a
-#define XSTRING(s) STRING(s)
-
-
-/*************************************************
-* Return info about what features are configured *
-*************************************************/
-
-/* If where is NULL, the length of memory required is returned.
-
-Arguments:
- what what information is required
- where where to put the information
-
-Returns: 0 if a numerical value is returned
- >= 0 if a string value
- PCRE2_ERROR_BADOPTION if "where" not recognized
- or JIT target requested when JIT not enabled
-*/
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_config(uint32_t what, void *where)
-{
-if (where == NULL) /* Requests a length */
- {
- switch(what)
- {
- default:
- return PCRE2_ERROR_BADOPTION;
-
- case PCRE2_CONFIG_BSR:
- case PCRE2_CONFIG_COMPILED_WIDTHS:
- case PCRE2_CONFIG_DEPTHLIMIT:
- case PCRE2_CONFIG_HEAPLIMIT:
- case PCRE2_CONFIG_JIT:
- case PCRE2_CONFIG_LINKSIZE:
- case PCRE2_CONFIG_MATCHLIMIT:
- case PCRE2_CONFIG_NEVER_BACKSLASH_C:
- case PCRE2_CONFIG_NEWLINE:
- case PCRE2_CONFIG_PARENSLIMIT:
- case PCRE2_CONFIG_STACKRECURSE: /* Obsolete */
- case PCRE2_CONFIG_TABLES_LENGTH:
- case PCRE2_CONFIG_UNICODE:
- return sizeof(uint32_t);
-
- /* These are handled below */
-
- case PCRE2_CONFIG_JITTARGET:
- case PCRE2_CONFIG_UNICODE_VERSION:
- case PCRE2_CONFIG_VERSION:
- break;
- }
- }
-
-switch (what)
- {
- default:
- return PCRE2_ERROR_BADOPTION;
-
- case PCRE2_CONFIG_BSR:
-#ifdef BSR_ANYCRLF
- *((uint32_t *)where) = PCRE2_BSR_ANYCRLF;
-#else
- *((uint32_t *)where) = PCRE2_BSR_UNICODE;
-#endif
- break;
-
- case PCRE2_CONFIG_COMPILED_WIDTHS:
- *((uint32_t *)where) = 0
-#ifdef SUPPORT_PCRE2_8
- + 1
-#endif
-#ifdef SUPPORT_PCRE2_16
- + 2
-#endif
-#ifdef SUPPORT_PCRE2_32
- + 4
-#endif
- ;
- break;
-
- case PCRE2_CONFIG_DEPTHLIMIT:
- *((uint32_t *)where) = MATCH_LIMIT_DEPTH;
- break;
-
- case PCRE2_CONFIG_HEAPLIMIT:
- *((uint32_t *)where) = HEAP_LIMIT;
- break;
-
- case PCRE2_CONFIG_JIT:
-#ifdef SUPPORT_JIT
- *((uint32_t *)where) = 1;
-#else
- *((uint32_t *)where) = 0;
-#endif
- break;
-
- case PCRE2_CONFIG_JITTARGET:
-#ifdef SUPPORT_JIT
- {
- const char *v = PRIV(jit_get_target)();
- return (int)(1 + ((where == NULL)?
- strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)));
- }
-#else
- return PCRE2_ERROR_BADOPTION;
-#endif
-
- case PCRE2_CONFIG_LINKSIZE:
- *((uint32_t *)where) = (uint32_t)configured_link_size;
- break;
-
- case PCRE2_CONFIG_MATCHLIMIT:
- *((uint32_t *)where) = MATCH_LIMIT;
- break;
-
- case PCRE2_CONFIG_NEWLINE:
- *((uint32_t *)where) = NEWLINE_DEFAULT;
- break;
-
- case PCRE2_CONFIG_NEVER_BACKSLASH_C:
-#ifdef NEVER_BACKSLASH_C
- *((uint32_t *)where) = 1;
-#else
- *((uint32_t *)where) = 0;
-#endif
- break;
-
- case PCRE2_CONFIG_PARENSLIMIT:
- *((uint32_t *)where) = PARENS_NEST_LIMIT;
- break;
-
- /* This is now obsolete. The stack is no longer used via recursion for
- handling backtracking in pcre2_match(). */
-
- case PCRE2_CONFIG_STACKRECURSE:
- *((uint32_t *)where) = 0;
- break;
-
- case PCRE2_CONFIG_TABLES_LENGTH:
- *((uint32_t *)where) = TABLES_LENGTH;
- break;
-
- case PCRE2_CONFIG_UNICODE_VERSION:
- {
-#if defined SUPPORT_UNICODE
- const char *v = PRIV(unicode_version);
-#else
- const char *v = "Unicode not supported";
-#endif
- return (int)(1 + ((where == NULL)?
- strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)));
- }
- break;
-
- case PCRE2_CONFIG_UNICODE:
-#if defined SUPPORT_UNICODE
- *((uint32_t *)where) = 1;
-#else
- *((uint32_t *)where) = 0;
-#endif
- break;
-
- /* The hackery in setting "v" below is to cope with the case when
- PCRE2_PRERELEASE is set to an empty string (which it is for real releases).
- If the second alternative is used in this case, it does not leave a space
- before the date. On the other hand, if all four macros are put into a single
- XSTRING when PCRE2_PRERELEASE is not empty, an unwanted space is inserted.
- There are problems using an "obvious" approach like this:
-
- XSTRING(PCRE2_MAJOR) "." XSTRING(PCRE_MINOR)
- XSTRING(PCRE2_PRERELEASE) " " XSTRING(PCRE_DATE)
-
- because, when PCRE2_PRERELEASE is empty, this leads to an attempted expansion
- of STRING(). The C standard states: "If (before argument substitution) any
- argument consists of no preprocessing tokens, the behavior is undefined." It
- turns out the gcc treats this case as a single empty string - which is what
- we really want - but Visual C grumbles about the lack of an argument for the
- macro. Unfortunately, both are within their rights. As there seems to be no
- way to test for a macro's value being empty at compile time, we have to
- resort to a runtime test. */
-
- case PCRE2_CONFIG_VERSION:
- {
- const char *v = (XSTRING(Z PCRE2_PRERELEASE)[1] == 0)?
- XSTRING(PCRE2_MAJOR.PCRE2_MINOR PCRE2_DATE) :
- XSTRING(PCRE2_MAJOR.PCRE2_MINOR) XSTRING(PCRE2_PRERELEASE PCRE2_DATE);
- return (int)(1 + ((where == NULL)?
- strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)));
- }
- }
-
-return 0;
-}
-
-/* End of pcre2_config.c */
diff --git a/contrib/libs/pcre2/src/pcre2_config.h b/contrib/libs/pcre2/src/pcre2_config.h
deleted file mode 100644
index 14e49e08ce..0000000000
--- a/contrib/libs/pcre2/src/pcre2_config.h
+++ /dev/null
@@ -1,446 +0,0 @@
-/* src/config.h. Generated from config.h.in by configure. */
-/* src/config.h.in. Generated from configure.ac by autoheader. */
-
-
-/* PCRE2 is written in Standard C, but there are a few non-standard things it
-can cope with, allowing it to run on SunOS4 and other "close to standard"
-systems.
-
-In environments that support the GNU autotools, config.h.in is converted into
-config.h by the "configure" script. In environments that use CMake,
-config-cmake.in is converted into config.h. If you are going to build PCRE2 "by
-hand" without using "configure" or CMake, you should copy the distributed
-config.h.generic to config.h, and edit the macro definitions to be the way you
-need them. You must then add -DHAVE_CONFIG_H to all of your compile commands,
-so that config.h is included at the start of every source.
-
-Alternatively, you can avoid editing by using -D on the compiler command line
-to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H,
-but if you do, default values will be taken from config.h for non-boolean
-macros that are not defined on the command line.
-
-Boolean macros such as HAVE_STDLIB_H and SUPPORT_PCRE2_8 should either be
-defined (conventionally to 1) for TRUE, and not defined at all for FALSE. All
-such macros are listed as a commented #undef in config.h.generic. Macros such
-as MATCH_LIMIT, whose actual value is relevant, have defaults defined, but are
-surrounded by #ifndef/#endif lines so that the value can be overridden by -D.
-
-PCRE2 uses memmove() if HAVE_MEMMOVE is defined; otherwise it uses bcopy() if
-HAVE_BCOPY is defined. If your system has neither bcopy() nor memmove(), make
-sure both macros are undefined; an emulation function will then be used. */
-
-/* By default, the \R escape sequence matches any Unicode line ending
- character or sequence of characters. If BSR_ANYCRLF is defined (to any
- value), this is changed so that backslash-R matches only CR, LF, or CRLF.
- The build-time default can be overridden by the user of PCRE2 at runtime.
- */
-/* #undef BSR_ANYCRLF */
-
-/* Define to any value to disable the use of the z and t modifiers in
- formatting settings such as %zu or %td (this is rarely needed). */
-/* #undef DISABLE_PERCENT_ZT */
-
-/* If you are compiling for a system that uses EBCDIC instead of ASCII
- character codes, define this macro to any value. When EBCDIC is set, PCRE2
- assumes that all input strings are in EBCDIC. If you do not define this
- macro, PCRE2 will assume input strings are ASCII or UTF-8/16/32 Unicode. It
- is not possible to build a version of PCRE2 that supports both EBCDIC and
- UTF-8/16/32. */
-/* #undef EBCDIC */
-
-/* In an EBCDIC environment, define this macro to any value to arrange for the
- NL character to be 0x25 instead of the default 0x15. NL plays the role that
- LF does in an ASCII/Unicode environment. */
-/* #undef EBCDIC_NL25 */
-
-/* Define this if your compiler supports __attribute__((uninitialized)) */
-/* #undef HAVE_ATTRIBUTE_UNINITIALIZED */
-
-/* Define to 1 if you have the `bcopy' function. */
-#define HAVE_BCOPY 1
-
-/* Define to 1 if you have the <bzlib.h> header file. */
-/* #undef HAVE_BZLIB_H */
-
-/* Define to 1 if you have the <dirent.h> header file. */
-#define HAVE_DIRENT_H 1
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the <editline/readline.h> header file. */
-/* #undef HAVE_EDITLINE_READLINE_H */
-
-/* Define to 1 if you have the <edit/readline/readline.h> header file. */
-/* #undef HAVE_EDIT_READLINE_READLINE_H */
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the <limits.h> header file. */
-#define HAVE_LIMITS_H 1
-
-/* Define to 1 if you have the `memfd_create' function. */
-#define HAVE_MEMFD_CREATE 1
-
-/* Define to 1 if you have the `memmove' function. */
-#define HAVE_MEMMOVE 1
-
-/* Define to 1 if you have the <minix/config.h> header file. */
-/* #undef HAVE_MINIX_CONFIG_H */
-
-/* Define to 1 if you have the `mkostemp' function. */
-#define HAVE_MKOSTEMP 1
-
-/* Define if you have POSIX threads libraries and header files. */
-#define HAVE_PTHREAD 1
-
-/* Have PTHREAD_PRIO_INHERIT. */
-#define HAVE_PTHREAD_PRIO_INHERIT 1
-
-/* Define to 1 if you have the <readline.h> header file. */
-/* #undef HAVE_READLINE_H */
-
-/* Define to 1 if you have the <readline/history.h> header file. */
-/* #undef HAVE_READLINE_HISTORY_H */
-
-/* Define to 1 if you have the <readline/readline.h> header file. */
-/* #undef HAVE_READLINE_READLINE_H */
-
-/* Define to 1 if you have the `realpath' function. */
-#define HAVE_REALPATH 1
-
-/* Define to 1 if you have the `secure_getenv' function. */
-#define HAVE_SECURE_GETENV 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdio.h> header file. */
-#define HAVE_STDIO_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the `strerror' function. */
-#define HAVE_STRERROR 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <sys/wait.h> header file. */
-#define HAVE_SYS_WAIT_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to 1 if the compiler supports simple visibility declarations. */
-#define HAVE_VISIBILITY 1
-
-/* Define to 1 if you have the <wchar.h> header file. */
-#define HAVE_WCHAR_H 1
-
-/* Define to 1 if you have the <windows.h> header file. */
-/* #undef HAVE_WINDOWS_H */
-
-/* Define to 1 if you have the <zlib.h> header file. */
-/* #undef HAVE_ZLIB_H */
-
-/* This limits the amount of memory that may be used while matching a pattern.
- It applies to both pcre2_match() and pcre2_dfa_match(). It does not apply
- to JIT matching. The value is in kibibytes (units of 1024 bytes). */
-#define HEAP_LIMIT 20000000
-
-/* The value of LINK_SIZE determines the number of bytes used to store links
- as offsets within the compiled regex. The default is 2, which allows for
- compiled patterns up to 65535 code units long. This covers the vast
- majority of cases. However, PCRE2 can also be compiled to use 3 or 4 bytes
- instead. This allows for longer patterns in extreme cases. */
-#define LINK_SIZE 2
-
-/* Define to the sub-directory where libtool stores uninstalled libraries. */
-#define LT_OBJDIR ".libs/"
-
-/* The value of MATCH_LIMIT determines the default number of times the
- pcre2_match() function can record a backtrack position during a single
- matching attempt. The value is also used to limit a loop counter in
- pcre2_dfa_match(). There is a runtime interface for setting a different
- limit. The limit exists in order to catch runaway regular expressions that
- take for ever to determine that they do not match. The default is set very
- large so that it does not accidentally catch legitimate cases. */
-#define MATCH_LIMIT 10000000
-
-/* The above limit applies to all backtracks, whether or not they are nested.
- In some environments it is desirable to limit the nesting of backtracking
- (that is, the depth of tree that is searched) more strictly, in order to
- restrict the maximum amount of heap memory that is used. The value of
- MATCH_LIMIT_DEPTH provides this facility. To have any useful effect, it
- must be less than the value of MATCH_LIMIT. The default is to use the same
- value as MATCH_LIMIT. There is a runtime method for setting a different
- limit. In the case of pcre2_dfa_match(), this limit controls the depth of
- the internal nested function calls that are used for pattern recursions,
- lookarounds, and atomic groups. */
-#define MATCH_LIMIT_DEPTH MATCH_LIMIT
-
-/* This limit is parameterized just in case anybody ever wants to change it.
- Care must be taken if it is increased, because it guards against integer
- overflow caused by enormously large patterns. */
-#define MAX_NAME_COUNT 10000
-
-/* This limit is parameterized just in case anybody ever wants to change it.
- Care must be taken if it is increased, because it guards against integer
- overflow caused by enormously large patterns. */
-#define MAX_NAME_SIZE 32
-
-/* Defining NEVER_BACKSLASH_C locks out the use of \C in all patterns. */
-/* #undef NEVER_BACKSLASH_C */
-
-/* The value of NEWLINE_DEFAULT determines the default newline character
- sequence. PCRE2 client programs can override this by selecting other values
- at run time. The valid values are 1 (CR), 2 (LF), 3 (CRLF), 4 (ANY), 5
- (ANYCRLF), and 6 (NUL). */
-#define NEWLINE_DEFAULT 2
-
-/* Name of package */
-#define PACKAGE "pcre2"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "PCRE2"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "PCRE2 10.42"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "pcre2"
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "10.42"
-
-/* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested
- parentheses (of any kind) in a pattern. This limits the amount of system
- stack that is used while compiling a pattern. */
-#define PARENS_NEST_LIMIT 250
-
-/* The value of PCRE2GREP_BUFSIZE is the starting size of the buffer used by
- pcre2grep to hold parts of the file it is searching. The buffer will be
- expanded up to PCRE2GREP_MAX_BUFSIZE if necessary, for files containing
- very long lines. The actual amount of memory used by pcre2grep is three
- times this number, because it allows for the buffering of "before" and
- "after" lines. */
-#define PCRE2GREP_BUFSIZE 20480
-
-/* The value of PCRE2GREP_MAX_BUFSIZE specifies the maximum size of the buffer
- used by pcre2grep to hold parts of the file it is searching. The actual
- amount of memory used by pcre2grep is three times this number, because it
- allows for the buffering of "before" and "after" lines. */
-#define PCRE2GREP_MAX_BUFSIZE 1048576
-
-/* to make a symbol visible */
-#define PCRE2POSIX_EXP_DECL extern __attribute__ ((visibility ("default")))
-
-/* to make a symbol visible */
-#define PCRE2POSIX_EXP_DEFN extern __attribute__ ((visibility ("default")))
-
-/* Define to any value to include debugging code. */
-/* #undef PCRE2_DEBUG */
-
-/* to make a symbol visible */
-#define PCRE2_EXP_DECL extern __attribute__ ((visibility ("default")))
-
-
-/* If you are compiling for a system other than a Unix-like system or
- Win32, and it needs some magic to be inserted before the definition
- of a function that is exported by the library, define this macro to
- contain the relevant magic. If you do not define this macro, a suitable
- __declspec value is used for Windows systems; in other environments
- "extern" is used for a C compiler and "extern C" for a C++ compiler.
- This macro apears at the start of every exported function that is part
- of the external API. It does not appear on functions that are "external"
- in the C sense, but which are internal to the library. */
-#define PCRE2_EXP_DEFN __attribute__ ((visibility ("default")))
-
-/* Define to any value if linking statically (TODO: make nice with Libtool) */
-/* #undef PCRE2_STATIC */
-
-/* Define to necessary symbol if this constant uses a non-standard name on
- your system. */
-/* #undef PTHREAD_CREATE_JOINABLE */
-
-/* Define to any non-zero number to enable support for SELinux compatible
- executable memory allocator in JIT. Note that this will have no effect
- unless SUPPORT_JIT is also defined. */
-/* #undef SLJIT_PROT_EXECUTABLE_ALLOCATOR */
-
-/* Define to 1 if all of the C90 standard headers exist (not just the ones
- required in a freestanding environment). This macro is provided for
- backward compatibility; new code need not use it. */
-#define STDC_HEADERS 1
-
-/* Define to any value to enable support for Just-In-Time compiling. */
-#define SUPPORT_JIT /**/
-
-/* Define to any value to allow pcre2grep to be linked with libbz2, so that it
- is able to handle .bz2 files. */
-/* #undef SUPPORT_LIBBZ2 */
-
-/* Define to any value to allow pcre2test to be linked with libedit. */
-/* #undef SUPPORT_LIBEDIT */
-
-/* Define to any value to allow pcre2test to be linked with libreadline. */
-/* #undef SUPPORT_LIBREADLINE */
-
-/* Define to any value to allow pcre2grep to be linked with libz, so that it
- is able to handle .gz files. */
-/* #undef SUPPORT_LIBZ */
-
-/* Define to any value to enable callout script support in pcre2grep. */
-#define SUPPORT_PCRE2GREP_CALLOUT /**/
-
-/* Define to any value to enable fork support in pcre2grep callout scripts.
- This will have no effect unless SUPPORT_PCRE2GREP_CALLOUT is also defined.
- */
-#define SUPPORT_PCRE2GREP_CALLOUT_FORK /**/
-
-/* Define to any value to enable JIT support in pcre2grep. Note that this will
- have no effect unless SUPPORT_JIT is also defined. */
-#define SUPPORT_PCRE2GREP_JIT /**/
-
-/* Define to any value to enable the 16 bit PCRE2 library. */
-#define SUPPORT_PCRE2_16 /**/
-
-/* Define to any value to enable the 32 bit PCRE2 library. */
-#define SUPPORT_PCRE2_32 /**/
-
-/* Define to any value to enable the 8 bit PCRE2 library. */
-#define SUPPORT_PCRE2_8 /**/
-
-/* Define to any value to enable support for Unicode and UTF encoding. This
- will work even in an EBCDIC environment, but it is incompatible with the
- EBCDIC macro. That is, PCRE2 can support *either* EBCDIC code *or*
- ASCII/Unicode, but not both at once. */
-#define SUPPORT_UNICODE /**/
-
-/* Define to any value for valgrind support to find invalid memory reads. */
-/* #undef SUPPORT_VALGRIND */
-
-/* Enable extensions on AIX 3, Interix. */
-#ifndef _ALL_SOURCE
-# define _ALL_SOURCE 1
-#endif
-/* Enable general extensions on macOS. */
-#ifndef _DARWIN_C_SOURCE
-# define _DARWIN_C_SOURCE 1
-#endif
-/* Enable general extensions on Solaris. */
-#ifndef __EXTENSIONS__
-# define __EXTENSIONS__ 1
-#endif
-/* Enable GNU extensions on systems that have them. */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE 1
-#endif
-/* Enable X/Open compliant socket functions that do not require linking
- with -lxnet on HP-UX 11.11. */
-#ifndef _HPUX_ALT_XOPEN_SOCKET_API
-# define _HPUX_ALT_XOPEN_SOCKET_API 1
-#endif
-/* Identify the host operating system as Minix.
- This macro does not affect the system headers' behavior.
- A future release of Autoconf may stop defining this macro. */
-#ifndef _MINIX
-/* # undef _MINIX */
-#endif
-/* Enable general extensions on NetBSD.
- Enable NetBSD compatibility extensions on Minix. */
-#ifndef _NETBSD_SOURCE
-# define _NETBSD_SOURCE 1
-#endif
-/* Enable OpenBSD compatibility extensions on NetBSD.
- Oddly enough, this does nothing on OpenBSD. */
-#ifndef _OPENBSD_SOURCE
-# define _OPENBSD_SOURCE 1
-#endif
-/* Define to 1 if needed for POSIX-compatible behavior. */
-#ifndef _POSIX_SOURCE
-/* # undef _POSIX_SOURCE */
-#endif
-/* Define to 2 if needed for POSIX-compatible behavior. */
-#ifndef _POSIX_1_SOURCE
-/* # undef _POSIX_1_SOURCE */
-#endif
-/* Enable POSIX-compatible threading on Solaris. */
-#ifndef _POSIX_PTHREAD_SEMANTICS
-# define _POSIX_PTHREAD_SEMANTICS 1
-#endif
-/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */
-#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
-# define __STDC_WANT_IEC_60559_ATTRIBS_EXT__ 1
-#endif
-/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */
-#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
-# define __STDC_WANT_IEC_60559_BFP_EXT__ 1
-#endif
-/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */
-#ifndef __STDC_WANT_IEC_60559_DFP_EXT__
-# define __STDC_WANT_IEC_60559_DFP_EXT__ 1
-#endif
-/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */
-#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
-# define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1
-#endif
-/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */
-#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
-# define __STDC_WANT_IEC_60559_TYPES_EXT__ 1
-#endif
-/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */
-#ifndef __STDC_WANT_LIB_EXT2__
-# define __STDC_WANT_LIB_EXT2__ 1
-#endif
-/* Enable extensions specified by ISO/IEC 24747:2009. */
-#ifndef __STDC_WANT_MATH_SPEC_FUNCS__
-# define __STDC_WANT_MATH_SPEC_FUNCS__ 1
-#endif
-/* Enable extensions on HP NonStop. */
-#ifndef _TANDEM_SOURCE
-# define _TANDEM_SOURCE 1
-#endif
-/* Enable X/Open extensions. Define to 500 only if necessary
- to make mbstate_t available. */
-#ifndef _XOPEN_SOURCE
-/* # undef _XOPEN_SOURCE */
-#endif
-
-
-/* Version number of package */
-#define VERSION "10.42"
-
-/* Number of bits in a file offset, on hosts where this is settable. */
-/* #undef _FILE_OFFSET_BITS */
-
-/* Define for large files, on AIX-style hosts. */
-/* #undef _LARGE_FILES */
-
-/* Define to empty if `const' does not conform to ANSI C. */
-/* #undef const */
-
-/* Define to the type of a signed integer type of width exactly 64 bits if
- such a type exists and the standard includes do not define it. */
-/* #undef int64_t */
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-/* #undef size_t */
diff --git a/contrib/libs/pcre2/src/pcre2_context.c b/contrib/libs/pcre2/src/pcre2_context.c
deleted file mode 100644
index 013cf6e9ed..0000000000
--- a/contrib/libs/pcre2/src/pcre2_context.c
+++ /dev/null
@@ -1,494 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2022 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-#include "pcre2_internal.h"
-
-
-
-/*************************************************
-* Default malloc/free functions *
-*************************************************/
-
-/* Ignore the "user data" argument in each case. */
-
-static void *default_malloc(size_t size, void *data)
-{
-(void)data;
-return malloc(size);
-}
-
-
-static void default_free(void *block, void *data)
-{
-(void)data;
-free(block);
-}
-
-
-
-/*************************************************
-* Get a block and save memory control *
-*************************************************/
-
-/* This internal function is called to get a block of memory in which the
-memory control data is to be stored at the start for future use.
-
-Arguments:
- size amount of memory required
- memctl pointer to a memctl block or NULL
-
-Returns: pointer to memory or NULL on failure
-*/
-
-extern void *
-PRIV(memctl_malloc)(size_t size, pcre2_memctl *memctl)
-{
-pcre2_memctl *newmemctl;
-void *yield = (memctl == NULL)? malloc(size) :
- memctl->malloc(size, memctl->memory_data);
-if (yield == NULL) return NULL;
-newmemctl = (pcre2_memctl *)yield;
-if (memctl == NULL)
- {
- newmemctl->malloc = default_malloc;
- newmemctl->free = default_free;
- newmemctl->memory_data = NULL;
- }
-else *newmemctl = *memctl;
-return yield;
-}
-
-
-
-/*************************************************
-* Create and initialize contexts *
-*************************************************/
-
-/* Initializing for compile and match contexts is done in separate, private
-functions so that these can be called from functions such as pcre2_compile()
-when an external context is not supplied. The initializing functions have an
-option to set up default memory management. */
-
-PCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION
-pcre2_general_context_create(void *(*private_malloc)(size_t, void *),
- void (*private_free)(void *, void *), void *memory_data)
-{
-pcre2_general_context *gcontext;
-if (private_malloc == NULL) private_malloc = default_malloc;
-if (private_free == NULL) private_free = default_free;
-gcontext = private_malloc(sizeof(pcre2_real_general_context), memory_data);
-if (gcontext == NULL) return NULL;
-gcontext->memctl.malloc = private_malloc;
-gcontext->memctl.free = private_free;
-gcontext->memctl.memory_data = memory_data;
-return gcontext;
-}
-
-
-/* A default compile context is set up to save having to initialize at run time
-when no context is supplied to the compile function. */
-
-const pcre2_compile_context PRIV(default_compile_context) = {
- { default_malloc, default_free, NULL }, /* Default memory handling */
- NULL, /* Stack guard */
- NULL, /* Stack guard data */
- PRIV(default_tables), /* Character tables */
- PCRE2_UNSET, /* Max pattern length */
- BSR_DEFAULT, /* Backslash R default */
- NEWLINE_DEFAULT, /* Newline convention */
- PARENS_NEST_LIMIT, /* As it says */
- 0 }; /* Extra options */
-
-/* The create function copies the default into the new memory, but must
-override the default memory handling functions if a gcontext was provided. */
-
-PCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION
-pcre2_compile_context_create(pcre2_general_context *gcontext)
-{
-pcre2_compile_context *ccontext = PRIV(memctl_malloc)(
- sizeof(pcre2_real_compile_context), (pcre2_memctl *)gcontext);
-if (ccontext == NULL) return NULL;
-*ccontext = PRIV(default_compile_context);
-if (gcontext != NULL)
- *((pcre2_memctl *)ccontext) = *((pcre2_memctl *)gcontext);
-return ccontext;
-}
-
-
-/* A default match context is set up to save having to initialize at run time
-when no context is supplied to a match function. */
-
-const pcre2_match_context PRIV(default_match_context) = {
- { default_malloc, default_free, NULL },
-#ifdef SUPPORT_JIT
- NULL, /* JIT callback */
- NULL, /* JIT callback data */
-#endif
- NULL, /* Callout function */
- NULL, /* Callout data */
- NULL, /* Substitute callout function */
- NULL, /* Substitute callout data */
- PCRE2_UNSET, /* Offset limit */
- HEAP_LIMIT,
- MATCH_LIMIT,
- MATCH_LIMIT_DEPTH };
-
-/* The create function copies the default into the new memory, but must
-override the default memory handling functions if a gcontext was provided. */
-
-PCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION
-pcre2_match_context_create(pcre2_general_context *gcontext)
-{
-pcre2_match_context *mcontext = PRIV(memctl_malloc)(
- sizeof(pcre2_real_match_context), (pcre2_memctl *)gcontext);
-if (mcontext == NULL) return NULL;
-*mcontext = PRIV(default_match_context);
-if (gcontext != NULL)
- *((pcre2_memctl *)mcontext) = *((pcre2_memctl *)gcontext);
-return mcontext;
-}
-
-
-/* A default convert context is set up to save having to initialize at run time
-when no context is supplied to the convert function. */
-
-const pcre2_convert_context PRIV(default_convert_context) = {
- { default_malloc, default_free, NULL }, /* Default memory handling */
-#ifdef _WIN32
- CHAR_BACKSLASH, /* Default path separator */
- CHAR_GRAVE_ACCENT /* Default escape character */
-#else /* Not Windows */
- CHAR_SLASH, /* Default path separator */
- CHAR_BACKSLASH /* Default escape character */
-#endif
- };
-
-/* The create function copies the default into the new memory, but must
-override the default memory handling functions if a gcontext was provided. */
-
-PCRE2_EXP_DEFN pcre2_convert_context * PCRE2_CALL_CONVENTION
-pcre2_convert_context_create(pcre2_general_context *gcontext)
-{
-pcre2_convert_context *ccontext = PRIV(memctl_malloc)(
- sizeof(pcre2_real_convert_context), (pcre2_memctl *)gcontext);
-if (ccontext == NULL) return NULL;
-*ccontext = PRIV(default_convert_context);
-if (gcontext != NULL)
- *((pcre2_memctl *)ccontext) = *((pcre2_memctl *)gcontext);
-return ccontext;
-}
-
-
-/*************************************************
-* Context copy functions *
-*************************************************/
-
-PCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION
-pcre2_general_context_copy(pcre2_general_context *gcontext)
-{
-pcre2_general_context *new =
- gcontext->memctl.malloc(sizeof(pcre2_real_general_context),
- gcontext->memctl.memory_data);
-if (new == NULL) return NULL;
-memcpy(new, gcontext, sizeof(pcre2_real_general_context));
-return new;
-}
-
-
-PCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION
-pcre2_compile_context_copy(pcre2_compile_context *ccontext)
-{
-pcre2_compile_context *new =
- ccontext->memctl.malloc(sizeof(pcre2_real_compile_context),
- ccontext->memctl.memory_data);
-if (new == NULL) return NULL;
-memcpy(new, ccontext, sizeof(pcre2_real_compile_context));
-return new;
-}
-
-
-PCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION
-pcre2_match_context_copy(pcre2_match_context *mcontext)
-{
-pcre2_match_context *new =
- mcontext->memctl.malloc(sizeof(pcre2_real_match_context),
- mcontext->memctl.memory_data);
-if (new == NULL) return NULL;
-memcpy(new, mcontext, sizeof(pcre2_real_match_context));
-return new;
-}
-
-
-
-PCRE2_EXP_DEFN pcre2_convert_context * PCRE2_CALL_CONVENTION
-pcre2_convert_context_copy(pcre2_convert_context *ccontext)
-{
-pcre2_convert_context *new =
- ccontext->memctl.malloc(sizeof(pcre2_real_convert_context),
- ccontext->memctl.memory_data);
-if (new == NULL) return NULL;
-memcpy(new, ccontext, sizeof(pcre2_real_convert_context));
-return new;
-}
-
-
-/*************************************************
-* Context free functions *
-*************************************************/
-
-PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
-pcre2_general_context_free(pcre2_general_context *gcontext)
-{
-if (gcontext != NULL)
- gcontext->memctl.free(gcontext, gcontext->memctl.memory_data);
-}
-
-
-PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
-pcre2_compile_context_free(pcre2_compile_context *ccontext)
-{
-if (ccontext != NULL)
- ccontext->memctl.free(ccontext, ccontext->memctl.memory_data);
-}
-
-
-PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
-pcre2_match_context_free(pcre2_match_context *mcontext)
-{
-if (mcontext != NULL)
- mcontext->memctl.free(mcontext, mcontext->memctl.memory_data);
-}
-
-
-PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
-pcre2_convert_context_free(pcre2_convert_context *ccontext)
-{
-if (ccontext != NULL)
- ccontext->memctl.free(ccontext, ccontext->memctl.memory_data);
-}
-
-
-/*************************************************
-* Set values in contexts *
-*************************************************/
-
-/* All these functions return 0 for success or PCRE2_ERROR_BADDATA if invalid
-data is given. Only some of the functions are able to test the validity of the
-data. */
-
-
-/* ------------ Compile context ------------ */
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_set_character_tables(pcre2_compile_context *ccontext,
- const uint8_t *tables)
-{
-ccontext->tables = tables;
-return 0;
-}
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_set_bsr(pcre2_compile_context *ccontext, uint32_t value)
-{
-switch(value)
- {
- case PCRE2_BSR_ANYCRLF:
- case PCRE2_BSR_UNICODE:
- ccontext->bsr_convention = value;
- return 0;
-
- default:
- return PCRE2_ERROR_BADDATA;
- }
-}
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_set_max_pattern_length(pcre2_compile_context *ccontext, PCRE2_SIZE length)
-{
-ccontext->max_pattern_length = length;
-return 0;
-}
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_set_newline(pcre2_compile_context *ccontext, uint32_t newline)
-{
-switch(newline)
- {
- case PCRE2_NEWLINE_CR:
- case PCRE2_NEWLINE_LF:
- case PCRE2_NEWLINE_CRLF:
- case PCRE2_NEWLINE_ANY:
- case PCRE2_NEWLINE_ANYCRLF:
- case PCRE2_NEWLINE_NUL:
- ccontext->newline_convention = newline;
- return 0;
-
- default:
- return PCRE2_ERROR_BADDATA;
- }
-}
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_set_parens_nest_limit(pcre2_compile_context *ccontext, uint32_t limit)
-{
-ccontext->parens_nest_limit = limit;
-return 0;
-}
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_set_compile_extra_options(pcre2_compile_context *ccontext, uint32_t options)
-{
-ccontext->extra_options = options;
-return 0;
-}
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_set_compile_recursion_guard(pcre2_compile_context *ccontext,
- int (*guard)(uint32_t, void *), void *user_data)
-{
-ccontext->stack_guard = guard;
-ccontext->stack_guard_data = user_data;
-return 0;
-}
-
-
-/* ------------ Match context ------------ */
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_set_callout(pcre2_match_context *mcontext,
- int (*callout)(pcre2_callout_block *, void *), void *callout_data)
-{
-mcontext->callout = callout;
-mcontext->callout_data = callout_data;
-return 0;
-}
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_set_substitute_callout(pcre2_match_context *mcontext,
- int (*substitute_callout)(pcre2_substitute_callout_block *, void *),
- void *substitute_callout_data)
-{
-mcontext->substitute_callout = substitute_callout;
-mcontext->substitute_callout_data = substitute_callout_data;
-return 0;
-}
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_set_heap_limit(pcre2_match_context *mcontext, uint32_t limit)
-{
-mcontext->heap_limit = limit;
-return 0;
-}
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_set_match_limit(pcre2_match_context *mcontext, uint32_t limit)
-{
-mcontext->match_limit = limit;
-return 0;
-}
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_set_depth_limit(pcre2_match_context *mcontext, uint32_t limit)
-{
-mcontext->depth_limit = limit;
-return 0;
-}
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_set_offset_limit(pcre2_match_context *mcontext, PCRE2_SIZE limit)
-{
-mcontext->offset_limit = limit;
-return 0;
-}
-
-/* These functions became obsolete at release 10.30. The first is kept as a
-synonym for backwards compatibility. The second now does nothing. Exclude both
-from coverage reports. */
-
-/* LCOV_EXCL_START */
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_set_recursion_limit(pcre2_match_context *mcontext, uint32_t limit)
-{
-return pcre2_set_depth_limit(mcontext, limit);
-}
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_set_recursion_memory_management(pcre2_match_context *mcontext,
- void *(*mymalloc)(size_t, void *), void (*myfree)(void *, void *),
- void *mydata)
-{
-(void)mcontext;
-(void)mymalloc;
-(void)myfree;
-(void)mydata;
-return 0;
-}
-
-/* LCOV_EXCL_STOP */
-
-
-/* ------------ Convert context ------------ */
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_set_glob_separator(pcre2_convert_context *ccontext, uint32_t separator)
-{
-if (separator != CHAR_SLASH && separator != CHAR_BACKSLASH &&
- separator != CHAR_DOT) return PCRE2_ERROR_BADDATA;
-ccontext->glob_separator = separator;
-return 0;
-}
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_set_glob_escape(pcre2_convert_context *ccontext, uint32_t escape)
-{
-if (escape > 255 || (escape != 0 && !ispunct(escape)))
- return PCRE2_ERROR_BADDATA;
-ccontext->glob_escape = escape;
-return 0;
-}
-
-/* End of pcre2_context.c */
-
diff --git a/contrib/libs/pcre2/src/pcre2_convert.c b/contrib/libs/pcre2/src/pcre2_convert.c
deleted file mode 100644
index 240828bca5..0000000000
--- a/contrib/libs/pcre2/src/pcre2_convert.c
+++ /dev/null
@@ -1,1181 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2022 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-#include "pcre2_internal.h"
-
-#define TYPE_OPTIONS (PCRE2_CONVERT_GLOB| \
- PCRE2_CONVERT_POSIX_BASIC|PCRE2_CONVERT_POSIX_EXTENDED)
-
-#define ALL_OPTIONS (PCRE2_CONVERT_UTF|PCRE2_CONVERT_NO_UTF_CHECK| \
- PCRE2_CONVERT_GLOB_NO_WILD_SEPARATOR| \
- PCRE2_CONVERT_GLOB_NO_STARSTAR| \
- TYPE_OPTIONS)
-
-#define DUMMY_BUFFER_SIZE 100
-
-/* Generated pattern fragments */
-
-#define STR_BACKSLASH_A STR_BACKSLASH STR_A
-#define STR_BACKSLASH_z STR_BACKSLASH STR_z
-#define STR_COLON_RIGHT_SQUARE_BRACKET STR_COLON STR_RIGHT_SQUARE_BRACKET
-#define STR_DOT_STAR_LOOKBEHIND STR_DOT STR_ASTERISK STR_LEFT_PARENTHESIS STR_QUESTION_MARK STR_LESS_THAN_SIGN STR_EQUALS_SIGN
-#define STR_LOOKAHEAD_NOT_DOT STR_LEFT_PARENTHESIS STR_QUESTION_MARK STR_EXCLAMATION_MARK STR_BACKSLASH STR_DOT STR_RIGHT_PARENTHESIS
-#define STR_QUERY_s STR_LEFT_PARENTHESIS STR_QUESTION_MARK STR_s STR_RIGHT_PARENTHESIS
-#define STR_STAR_NUL STR_LEFT_PARENTHESIS STR_ASTERISK STR_N STR_U STR_L STR_RIGHT_PARENTHESIS
-
-/* States for POSIX processing */
-
-enum { POSIX_START_REGEX, POSIX_ANCHORED, POSIX_NOT_BRACKET,
- POSIX_CLASS_NOT_STARTED, POSIX_CLASS_STARTING, POSIX_CLASS_STARTED };
-
-/* Macro to add a character string to the output buffer, checking for overflow. */
-
-#define PUTCHARS(string) \
- { \
- for (s = (char *)(string); *s != 0; s++) \
- { \
- if (p >= endp) return PCRE2_ERROR_NOMEMORY; \
- *p++ = *s; \
- } \
- }
-
-/* Literals that must be escaped: \ ? * + | . ^ $ { } [ ] ( ) */
-
-static const char *pcre2_escaped_literals =
- STR_BACKSLASH STR_QUESTION_MARK STR_ASTERISK STR_PLUS
- STR_VERTICAL_LINE STR_DOT STR_CIRCUMFLEX_ACCENT STR_DOLLAR_SIGN
- STR_LEFT_CURLY_BRACKET STR_RIGHT_CURLY_BRACKET
- STR_LEFT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET
- STR_LEFT_PARENTHESIS STR_RIGHT_PARENTHESIS;
-
-/* Recognized escaped metacharacters in POSIX basic patterns. */
-
-static const char *posix_meta_escapes =
- STR_LEFT_PARENTHESIS STR_RIGHT_PARENTHESIS
- STR_LEFT_CURLY_BRACKET STR_RIGHT_CURLY_BRACKET
- STR_1 STR_2 STR_3 STR_4 STR_5 STR_6 STR_7 STR_8 STR_9;
-
-
-
-/*************************************************
-* Convert a POSIX pattern *
-*************************************************/
-
-/* This function handles both basic and extended POSIX patterns.
-
-Arguments:
- pattype the pattern type
- pattern the pattern
- plength length in code units
- utf TRUE if UTF
- use_buffer where to put the output
- use_length length of use_buffer
- bufflenptr where to put the used length
- dummyrun TRUE if a dummy run
- ccontext the convert context
-
-Returns: 0 => success
- !0 => error code
-*/
-
-static int
-convert_posix(uint32_t pattype, PCRE2_SPTR pattern, PCRE2_SIZE plength,
- BOOL utf, PCRE2_UCHAR *use_buffer, PCRE2_SIZE use_length,
- PCRE2_SIZE *bufflenptr, BOOL dummyrun, pcre2_convert_context *ccontext)
-{
-char *s;
-PCRE2_SPTR posix = pattern;
-PCRE2_UCHAR *p = use_buffer;
-PCRE2_UCHAR *pp = p;
-PCRE2_UCHAR *endp = p + use_length - 1; /* Allow for trailing zero */
-PCRE2_SIZE convlength = 0;
-
-uint32_t bracount = 0;
-uint32_t posix_state = POSIX_START_REGEX;
-uint32_t lastspecial = 0;
-BOOL extended = (pattype & PCRE2_CONVERT_POSIX_EXTENDED) != 0;
-BOOL nextisliteral = FALSE;
-
-(void)utf; /* Not used when Unicode not supported */
-(void)ccontext; /* Not currently used */
-
-/* Initialize default for error offset as end of input. */
-
-*bufflenptr = plength;
-PUTCHARS(STR_STAR_NUL);
-
-/* Now scan the input. */
-
-while (plength > 0)
- {
- uint32_t c, sc;
- int clength = 1;
-
- /* Add in the length of the last item, then, if in the dummy run, pull the
- pointer back to the start of the (temporary) buffer and then remember the
- start of the next item. */
-
- convlength += p - pp;
- if (dummyrun) p = use_buffer;
- pp = p;
-
- /* Pick up the next character */
-
-#ifndef SUPPORT_UNICODE
- c = *posix;
-#else
- GETCHARLENTEST(c, posix, clength);
-#endif
- posix += clength;
- plength -= clength;
-
- sc = nextisliteral? 0 : c;
- nextisliteral = FALSE;
-
- /* Handle a character within a class. */
-
- if (posix_state >= POSIX_CLASS_NOT_STARTED)
- {
- if (c == CHAR_RIGHT_SQUARE_BRACKET)
- {
- PUTCHARS(STR_RIGHT_SQUARE_BRACKET);
- posix_state = POSIX_NOT_BRACKET;
- }
-
- /* Not the end of the class */
-
- else
- {
- switch (posix_state)
- {
- case POSIX_CLASS_STARTED:
- if (c <= 127 && islower(c)) break; /* Remain in started state */
- posix_state = POSIX_CLASS_NOT_STARTED;
- if (c == CHAR_COLON && plength > 0 &&
- *posix == CHAR_RIGHT_SQUARE_BRACKET)
- {
- PUTCHARS(STR_COLON_RIGHT_SQUARE_BRACKET);
- plength--;
- posix++;
- continue; /* With next character after :] */
- }
- /* Fall through */
-
- case POSIX_CLASS_NOT_STARTED:
- if (c == CHAR_LEFT_SQUARE_BRACKET)
- posix_state = POSIX_CLASS_STARTING;
- break;
-
- case POSIX_CLASS_STARTING:
- if (c == CHAR_COLON) posix_state = POSIX_CLASS_STARTED;
- break;
- }
-
- if (c == CHAR_BACKSLASH) PUTCHARS(STR_BACKSLASH);
- if (p + clength > endp) return PCRE2_ERROR_NOMEMORY;
- memcpy(p, posix - clength, CU2BYTES(clength));
- p += clength;
- }
- }
-
- /* Handle a character not within a class. */
-
- else switch(sc)
- {
- case CHAR_LEFT_SQUARE_BRACKET:
- PUTCHARS(STR_LEFT_SQUARE_BRACKET);
-
-#ifdef NEVER
- /* We could handle special cases [[:<:]] and [[:>:]] (which PCRE does
- support) but they are not part of POSIX 1003.1. */
-
- if (plength >= 6)
- {
- if (posix[0] == CHAR_LEFT_SQUARE_BRACKET &&
- posix[1] == CHAR_COLON &&
- (posix[2] == CHAR_LESS_THAN_SIGN ||
- posix[2] == CHAR_GREATER_THAN_SIGN) &&
- posix[3] == CHAR_COLON &&
- posix[4] == CHAR_RIGHT_SQUARE_BRACKET &&
- posix[5] == CHAR_RIGHT_SQUARE_BRACKET)
- {
- if (p + 6 > endp) return PCRE2_ERROR_NOMEMORY;
- memcpy(p, posix, CU2BYTES(6));
- p += 6;
- posix += 6;
- plength -= 6;
- continue; /* With next character */
- }
- }
-#endif
-
- /* Handle start of "normal" character classes */
-
- posix_state = POSIX_CLASS_NOT_STARTED;
-
- /* Handle ^ and ] as first characters */
-
- if (plength > 0)
- {
- if (*posix == CHAR_CIRCUMFLEX_ACCENT)
- {
- posix++;
- plength--;
- PUTCHARS(STR_CIRCUMFLEX_ACCENT);
- }
- if (plength > 0 && *posix == CHAR_RIGHT_SQUARE_BRACKET)
- {
- posix++;
- plength--;
- PUTCHARS(STR_RIGHT_SQUARE_BRACKET);
- }
- }
- break;
-
- case CHAR_BACKSLASH:
- if (plength == 0) return PCRE2_ERROR_END_BACKSLASH;
- if (extended) nextisliteral = TRUE; else
- {
- if (*posix < 127 && strchr(posix_meta_escapes, *posix) != NULL)
- {
- if (isdigit(*posix)) PUTCHARS(STR_BACKSLASH);
- if (p + 1 > endp) return PCRE2_ERROR_NOMEMORY;
- lastspecial = *p++ = *posix++;
- plength--;
- }
- else nextisliteral = TRUE;
- }
- break;
-
- case CHAR_RIGHT_PARENTHESIS:
- if (!extended || bracount == 0) goto ESCAPE_LITERAL;
- bracount--;
- goto COPY_SPECIAL;
-
- case CHAR_LEFT_PARENTHESIS:
- bracount++;
- /* Fall through */
-
- case CHAR_QUESTION_MARK:
- case CHAR_PLUS:
- case CHAR_LEFT_CURLY_BRACKET:
- case CHAR_RIGHT_CURLY_BRACKET:
- case CHAR_VERTICAL_LINE:
- if (!extended) goto ESCAPE_LITERAL;
- /* Fall through */
-
- case CHAR_DOT:
- case CHAR_DOLLAR_SIGN:
- posix_state = POSIX_NOT_BRACKET;
- COPY_SPECIAL:
- lastspecial = c;
- if (p + 1 > endp) return PCRE2_ERROR_NOMEMORY;
- *p++ = c;
- break;
-
- case CHAR_ASTERISK:
- if (lastspecial != CHAR_ASTERISK)
- {
- if (!extended && (posix_state < POSIX_NOT_BRACKET ||
- lastspecial == CHAR_LEFT_PARENTHESIS))
- goto ESCAPE_LITERAL;
- goto COPY_SPECIAL;
- }
- break; /* Ignore second and subsequent asterisks */
-
- case CHAR_CIRCUMFLEX_ACCENT:
- if (extended) goto COPY_SPECIAL;
- if (posix_state == POSIX_START_REGEX ||
- lastspecial == CHAR_LEFT_PARENTHESIS)
- {
- posix_state = POSIX_ANCHORED;
- goto COPY_SPECIAL;
- }
- /* Fall through */
-
- default:
- if (c < 128 && strchr(pcre2_escaped_literals, c) != NULL)
- {
- ESCAPE_LITERAL:
- PUTCHARS(STR_BACKSLASH);
- }
- lastspecial = 0xff; /* Indicates nothing special */
- if (p + clength > endp) return PCRE2_ERROR_NOMEMORY;
- memcpy(p, posix - clength, CU2BYTES(clength));
- p += clength;
- posix_state = POSIX_NOT_BRACKET;
- break;
- }
- }
-
-if (posix_state >= POSIX_CLASS_NOT_STARTED)
- return PCRE2_ERROR_MISSING_SQUARE_BRACKET;
-convlength += p - pp; /* Final segment */
-*bufflenptr = convlength;
-*p++ = 0;
-return 0;
-}
-
-
-/*************************************************
-* Convert a glob pattern *
-*************************************************/
-
-/* Context for writing the output into a buffer. */
-
-typedef struct pcre2_output_context {
- PCRE2_UCHAR *output; /* current output position */
- PCRE2_SPTR output_end; /* output end */
- PCRE2_SIZE output_size; /* size of the output */
- uint8_t out_str[8]; /* string copied to the output */
-} pcre2_output_context;
-
-
-/* Write a character into the output.
-
-Arguments:
- out output context
- chr the next character
-*/
-
-static void
-convert_glob_write(pcre2_output_context *out, PCRE2_UCHAR chr)
-{
-out->output_size++;
-
-if (out->output < out->output_end)
- *out->output++ = chr;
-}
-
-
-/* Write a string into the output.
-
-Arguments:
- out output context
- length length of out->out_str
-*/
-
-static void
-convert_glob_write_str(pcre2_output_context *out, PCRE2_SIZE length)
-{
-uint8_t *out_str = out->out_str;
-PCRE2_UCHAR *output = out->output;
-PCRE2_SPTR output_end = out->output_end;
-PCRE2_SIZE output_size = out->output_size;
-
-do
- {
- output_size++;
-
- if (output < output_end)
- *output++ = *out_str++;
- }
-while (--length != 0);
-
-out->output = output;
-out->output_size = output_size;
-}
-
-
-/* Prints the separator into the output.
-
-Arguments:
- out output context
- separator glob separator
- with_escape backslash is needed before separator
-*/
-
-static void
-convert_glob_print_separator(pcre2_output_context *out,
- PCRE2_UCHAR separator, BOOL with_escape)
-{
-if (with_escape)
- convert_glob_write(out, CHAR_BACKSLASH);
-
-convert_glob_write(out, separator);
-}
-
-
-/* Prints a wildcard into the output.
-
-Arguments:
- out output context
- separator glob separator
- with_escape backslash is needed before separator
-*/
-
-static void
-convert_glob_print_wildcard(pcre2_output_context *out,
- PCRE2_UCHAR separator, BOOL with_escape)
-{
-out->out_str[0] = CHAR_LEFT_SQUARE_BRACKET;
-out->out_str[1] = CHAR_CIRCUMFLEX_ACCENT;
-convert_glob_write_str(out, 2);
-
-convert_glob_print_separator(out, separator, with_escape);
-
-convert_glob_write(out, CHAR_RIGHT_SQUARE_BRACKET);
-}
-
-
-/* Parse a posix class.
-
-Arguments:
- from starting point of scanning the range
- pattern_end end of pattern
- out output context
-
-Returns: >0 => class index
- 0 => malformed class
-*/
-
-static int
-convert_glob_parse_class(PCRE2_SPTR *from, PCRE2_SPTR pattern_end,
- pcre2_output_context *out)
-{
-static const char *posix_classes = "alnum:alpha:ascii:blank:cntrl:digit:"
- "graph:lower:print:punct:space:upper:word:xdigit:";
-PCRE2_SPTR start = *from + 1;
-PCRE2_SPTR pattern = start;
-const char *class_ptr;
-PCRE2_UCHAR c;
-int class_index;
-
-while (TRUE)
- {
- if (pattern >= pattern_end) return 0;
-
- c = *pattern++;
-
- if (c < CHAR_a || c > CHAR_z) break;
- }
-
-if (c != CHAR_COLON || pattern >= pattern_end ||
- *pattern != CHAR_RIGHT_SQUARE_BRACKET)
- return 0;
-
-class_ptr = posix_classes;
-class_index = 1;
-
-while (TRUE)
- {
- if (*class_ptr == CHAR_NUL) return 0;
-
- pattern = start;
-
- while (*pattern == (PCRE2_UCHAR) *class_ptr)
- {
- if (*pattern == CHAR_COLON)
- {
- pattern += 2;
- start -= 2;
-
- do convert_glob_write(out, *start++); while (start < pattern);
-
- *from = pattern;
- return class_index;
- }
- pattern++;
- class_ptr++;
- }
-
- while (*class_ptr != CHAR_COLON) class_ptr++;
- class_ptr++;
- class_index++;
- }
-}
-
-/* Checks whether the character is in the class.
-
-Arguments:
- class_index class index
- c character
-
-Returns: !0 => character is found in the class
- 0 => otherwise
-*/
-
-static BOOL
-convert_glob_char_in_class(int class_index, PCRE2_UCHAR c)
-{
-switch (class_index)
- {
- case 1: return isalnum(c);
- case 2: return isalpha(c);
- case 3: return 1;
- case 4: return c == CHAR_HT || c == CHAR_SPACE;
- case 5: return iscntrl(c);
- case 6: return isdigit(c);
- case 7: return isgraph(c);
- case 8: return islower(c);
- case 9: return isprint(c);
- case 10: return ispunct(c);
- case 11: return isspace(c);
- case 12: return isupper(c);
- case 13: return isalnum(c) || c == CHAR_UNDERSCORE;
- default: return isxdigit(c);
- }
-}
-
-/* Parse a range of characters.
-
-Arguments:
- from starting point of scanning the range
- pattern_end end of pattern
- out output context
- separator glob separator
- with_escape backslash is needed before separator
-
-Returns: 0 => success
- !0 => error code
-*/
-
-static int
-convert_glob_parse_range(PCRE2_SPTR *from, PCRE2_SPTR pattern_end,
- pcre2_output_context *out, BOOL utf, PCRE2_UCHAR separator,
- BOOL with_escape, PCRE2_UCHAR escape, BOOL no_wildsep)
-{
-BOOL is_negative = FALSE;
-BOOL separator_seen = FALSE;
-BOOL has_prev_c;
-PCRE2_SPTR pattern = *from;
-PCRE2_SPTR char_start = NULL;
-uint32_t c, prev_c;
-int len, class_index;
-
-(void)utf; /* Avoid compiler warning. */
-
-if (pattern >= pattern_end)
- {
- *from = pattern;
- return PCRE2_ERROR_MISSING_SQUARE_BRACKET;
- }
-
-if (*pattern == CHAR_EXCLAMATION_MARK
- || *pattern == CHAR_CIRCUMFLEX_ACCENT)
- {
- pattern++;
-
- if (pattern >= pattern_end)
- {
- *from = pattern;
- return PCRE2_ERROR_MISSING_SQUARE_BRACKET;
- }
-
- is_negative = TRUE;
-
- out->out_str[0] = CHAR_LEFT_SQUARE_BRACKET;
- out->out_str[1] = CHAR_CIRCUMFLEX_ACCENT;
- len = 2;
-
- if (!no_wildsep)
- {
- if (with_escape)
- {
- out->out_str[len] = CHAR_BACKSLASH;
- len++;
- }
- out->out_str[len] = (uint8_t) separator;
- }
-
- convert_glob_write_str(out, len + 1);
- }
-else
- convert_glob_write(out, CHAR_LEFT_SQUARE_BRACKET);
-
-has_prev_c = FALSE;
-prev_c = 0;
-
-if (*pattern == CHAR_RIGHT_SQUARE_BRACKET)
- {
- out->out_str[0] = CHAR_BACKSLASH;
- out->out_str[1] = CHAR_RIGHT_SQUARE_BRACKET;
- convert_glob_write_str(out, 2);
- has_prev_c = TRUE;
- prev_c = CHAR_RIGHT_SQUARE_BRACKET;
- pattern++;
- }
-
-while (pattern < pattern_end)
- {
- char_start = pattern;
- GETCHARINCTEST(c, pattern);
-
- if (c == CHAR_RIGHT_SQUARE_BRACKET)
- {
- convert_glob_write(out, c);
-
- if (!is_negative && !no_wildsep && separator_seen)
- {
- out->out_str[0] = CHAR_LEFT_PARENTHESIS;
- out->out_str[1] = CHAR_QUESTION_MARK;
- out->out_str[2] = CHAR_LESS_THAN_SIGN;
- out->out_str[3] = CHAR_EXCLAMATION_MARK;
- convert_glob_write_str(out, 4);
-
- convert_glob_print_separator(out, separator, with_escape);
- convert_glob_write(out, CHAR_RIGHT_PARENTHESIS);
- }
-
- *from = pattern;
- return 0;
- }
-
- if (pattern >= pattern_end) break;
-
- if (c == CHAR_LEFT_SQUARE_BRACKET && *pattern == CHAR_COLON)
- {
- *from = pattern;
- class_index = convert_glob_parse_class(from, pattern_end, out);
-
- if (class_index != 0)
- {
- pattern = *from;
-
- has_prev_c = FALSE;
- prev_c = 0;
-
- if (!is_negative &&
- convert_glob_char_in_class (class_index, separator))
- separator_seen = TRUE;
- continue;
- }
- }
- else if (c == CHAR_MINUS && has_prev_c &&
- *pattern != CHAR_RIGHT_SQUARE_BRACKET)
- {
- convert_glob_write(out, CHAR_MINUS);
-
- char_start = pattern;
- GETCHARINCTEST(c, pattern);
-
- if (pattern >= pattern_end) break;
-
- if (escape != 0 && c == escape)
- {
- char_start = pattern;
- GETCHARINCTEST(c, pattern);
- }
- else if (c == CHAR_LEFT_SQUARE_BRACKET && *pattern == CHAR_COLON)
- {
- *from = pattern;
- return PCRE2_ERROR_CONVERT_SYNTAX;
- }
-
- if (prev_c > c)
- {
- *from = pattern;
- return PCRE2_ERROR_CONVERT_SYNTAX;
- }
-
- if (prev_c < separator && separator < c) separator_seen = TRUE;
-
- has_prev_c = FALSE;
- prev_c = 0;
- }
- else
- {
- if (escape != 0 && c == escape)
- {
- char_start = pattern;
- GETCHARINCTEST(c, pattern);
-
- if (pattern >= pattern_end) break;
- }
-
- has_prev_c = TRUE;
- prev_c = c;
- }
-
- if (c == CHAR_LEFT_SQUARE_BRACKET || c == CHAR_RIGHT_SQUARE_BRACKET ||
- c == CHAR_BACKSLASH || c == CHAR_MINUS)
- convert_glob_write(out, CHAR_BACKSLASH);
-
- if (c == separator) separator_seen = TRUE;
-
- do convert_glob_write(out, *char_start++); while (char_start < pattern);
- }
-
-*from = pattern;
-return PCRE2_ERROR_MISSING_SQUARE_BRACKET;
-}
-
-
-/* Prints a (*COMMIT) into the output.
-
-Arguments:
- out output context
-*/
-
-static void
-convert_glob_print_commit(pcre2_output_context *out)
-{
-out->out_str[0] = CHAR_LEFT_PARENTHESIS;
-out->out_str[1] = CHAR_ASTERISK;
-out->out_str[2] = CHAR_C;
-out->out_str[3] = CHAR_O;
-out->out_str[4] = CHAR_M;
-out->out_str[5] = CHAR_M;
-out->out_str[6] = CHAR_I;
-out->out_str[7] = CHAR_T;
-convert_glob_write_str(out, 8);
-convert_glob_write(out, CHAR_RIGHT_PARENTHESIS);
-}
-
-
-/* Bash glob converter.
-
-Arguments:
- pattype the pattern type
- pattern the pattern
- plength length in code units
- utf TRUE if UTF
- use_buffer where to put the output
- use_length length of use_buffer
- bufflenptr where to put the used length
- dummyrun TRUE if a dummy run
- ccontext the convert context
-
-Returns: 0 => success
- !0 => error code
-*/
-
-static int
-convert_glob(uint32_t options, PCRE2_SPTR pattern, PCRE2_SIZE plength,
- BOOL utf, PCRE2_UCHAR *use_buffer, PCRE2_SIZE use_length,
- PCRE2_SIZE *bufflenptr, BOOL dummyrun, pcre2_convert_context *ccontext)
-{
-pcre2_output_context out;
-PCRE2_SPTR pattern_start = pattern;
-PCRE2_SPTR pattern_end = pattern + plength;
-PCRE2_UCHAR separator = ccontext->glob_separator;
-PCRE2_UCHAR escape = ccontext->glob_escape;
-PCRE2_UCHAR c;
-BOOL no_wildsep = (options & PCRE2_CONVERT_GLOB_NO_WILD_SEPARATOR) != 0;
-BOOL no_starstar = (options & PCRE2_CONVERT_GLOB_NO_STARSTAR) != 0;
-BOOL in_atomic = FALSE;
-BOOL after_starstar = FALSE;
-BOOL no_slash_z = FALSE;
-BOOL with_escape, is_start, after_separator;
-int result = 0;
-
-(void)utf; /* Avoid compiler warning. */
-
-#ifdef SUPPORT_UNICODE
-if (utf && (separator >= 128 || escape >= 128))
- {
- /* Currently only ASCII characters are supported. */
- *bufflenptr = 0;
- return PCRE2_ERROR_CONVERT_SYNTAX;
- }
-#endif
-
-with_escape = strchr(pcre2_escaped_literals, separator) != NULL;
-
-/* Initialize default for error offset as end of input. */
-out.output = use_buffer;
-out.output_end = use_buffer + use_length;
-out.output_size = 0;
-
-out.out_str[0] = CHAR_LEFT_PARENTHESIS;
-out.out_str[1] = CHAR_QUESTION_MARK;
-out.out_str[2] = CHAR_s;
-out.out_str[3] = CHAR_RIGHT_PARENTHESIS;
-convert_glob_write_str(&out, 4);
-
-is_start = TRUE;
-
-if (pattern < pattern_end && pattern[0] == CHAR_ASTERISK)
- {
- if (no_wildsep)
- is_start = FALSE;
- else if (!no_starstar && pattern + 1 < pattern_end &&
- pattern[1] == CHAR_ASTERISK)
- is_start = FALSE;
- }
-
-if (is_start)
- {
- out.out_str[0] = CHAR_BACKSLASH;
- out.out_str[1] = CHAR_A;
- convert_glob_write_str(&out, 2);
- }
-
-while (pattern < pattern_end)
- {
- c = *pattern++;
-
- if (c == CHAR_ASTERISK)
- {
- is_start = pattern == pattern_start + 1;
-
- if (in_atomic)
- {
- convert_glob_write(&out, CHAR_RIGHT_PARENTHESIS);
- in_atomic = FALSE;
- }
-
- if (!no_starstar && pattern < pattern_end && *pattern == CHAR_ASTERISK)
- {
- after_separator = is_start || (pattern[-2] == separator);
-
- do pattern++; while (pattern < pattern_end &&
- *pattern == CHAR_ASTERISK);
-
- if (pattern >= pattern_end)
- {
- no_slash_z = TRUE;
- break;
- }
-
- after_starstar = TRUE;
-
- if (after_separator && escape != 0 && *pattern == escape &&
- pattern + 1 < pattern_end && pattern[1] == separator)
- pattern++;
-
- if (is_start)
- {
- if (*pattern != separator) continue;
-
- out.out_str[0] = CHAR_LEFT_PARENTHESIS;
- out.out_str[1] = CHAR_QUESTION_MARK;
- out.out_str[2] = CHAR_COLON;
- out.out_str[3] = CHAR_BACKSLASH;
- out.out_str[4] = CHAR_A;
- out.out_str[5] = CHAR_VERTICAL_LINE;
- convert_glob_write_str(&out, 6);
-
- convert_glob_print_separator(&out, separator, with_escape);
- convert_glob_write(&out, CHAR_RIGHT_PARENTHESIS);
-
- pattern++;
- continue;
- }
-
- convert_glob_print_commit(&out);
-
- if (!after_separator || *pattern != separator)
- {
- out.out_str[0] = CHAR_DOT;
- out.out_str[1] = CHAR_ASTERISK;
- out.out_str[2] = CHAR_QUESTION_MARK;
- convert_glob_write_str(&out, 3);
- continue;
- }
-
- out.out_str[0] = CHAR_LEFT_PARENTHESIS;
- out.out_str[1] = CHAR_QUESTION_MARK;
- out.out_str[2] = CHAR_COLON;
- out.out_str[3] = CHAR_DOT;
- out.out_str[4] = CHAR_ASTERISK;
- out.out_str[5] = CHAR_QUESTION_MARK;
-
- convert_glob_write_str(&out, 6);
-
- convert_glob_print_separator(&out, separator, with_escape);
-
- out.out_str[0] = CHAR_RIGHT_PARENTHESIS;
- out.out_str[1] = CHAR_QUESTION_MARK;
- out.out_str[2] = CHAR_QUESTION_MARK;
- convert_glob_write_str(&out, 3);
-
- pattern++;
- continue;
- }
-
- if (pattern < pattern_end && *pattern == CHAR_ASTERISK)
- {
- do pattern++; while (pattern < pattern_end &&
- *pattern == CHAR_ASTERISK);
- }
-
- if (no_wildsep)
- {
- if (pattern >= pattern_end)
- {
- no_slash_z = TRUE;
- break;
- }
-
- /* Start check must be after the end check. */
- if (is_start) continue;
- }
-
- if (!is_start)
- {
- if (after_starstar)
- {
- out.out_str[0] = CHAR_LEFT_PARENTHESIS;
- out.out_str[1] = CHAR_QUESTION_MARK;
- out.out_str[2] = CHAR_GREATER_THAN_SIGN;
- convert_glob_write_str(&out, 3);
- in_atomic = TRUE;
- }
- else
- convert_glob_print_commit(&out);
- }
-
- if (no_wildsep)
- convert_glob_write(&out, CHAR_DOT);
- else
- convert_glob_print_wildcard(&out, separator, with_escape);
-
- out.out_str[0] = CHAR_ASTERISK;
- out.out_str[1] = CHAR_QUESTION_MARK;
- if (pattern >= pattern_end)
- out.out_str[1] = CHAR_PLUS;
- convert_glob_write_str(&out, 2);
- continue;
- }
-
- if (c == CHAR_QUESTION_MARK)
- {
- if (no_wildsep)
- convert_glob_write(&out, CHAR_DOT);
- else
- convert_glob_print_wildcard(&out, separator, with_escape);
- continue;
- }
-
- if (c == CHAR_LEFT_SQUARE_BRACKET)
- {
- result = convert_glob_parse_range(&pattern, pattern_end,
- &out, utf, separator, with_escape, escape, no_wildsep);
- if (result != 0) break;
- continue;
- }
-
- if (escape != 0 && c == escape)
- {
- if (pattern >= pattern_end)
- {
- result = PCRE2_ERROR_CONVERT_SYNTAX;
- break;
- }
- c = *pattern++;
- }
-
- if (c < 128 && strchr(pcre2_escaped_literals, c) != NULL)
- convert_glob_write(&out, CHAR_BACKSLASH);
-
- convert_glob_write(&out, c);
- }
-
-if (result == 0)
- {
- if (!no_slash_z)
- {
- out.out_str[0] = CHAR_BACKSLASH;
- out.out_str[1] = CHAR_z;
- convert_glob_write_str(&out, 2);
- }
-
- if (in_atomic)
- convert_glob_write(&out, CHAR_RIGHT_PARENTHESIS);
-
- convert_glob_write(&out, CHAR_NUL);
-
- if (!dummyrun && out.output_size != (PCRE2_SIZE) (out.output - use_buffer))
- result = PCRE2_ERROR_NOMEMORY;
- }
-
-if (result != 0)
- {
- *bufflenptr = pattern - pattern_start;
- return result;
- }
-
-*bufflenptr = out.output_size - 1;
-return 0;
-}
-
-
-/*************************************************
-* Convert pattern *
-*************************************************/
-
-/* This is the external-facing function for converting other forms of pattern
-into PCRE2 regular expression patterns. On error, the bufflenptr argument is
-used to return an offset in the original pattern.
-
-Arguments:
- pattern the input pattern
- plength length of input, or PCRE2_ZERO_TERMINATED
- options options bits
- buffptr pointer to pointer to output buffer
- bufflenptr pointer to length of output buffer
- ccontext convert context or NULL
-
-Returns: 0 for success, else an error code (+ve or -ve)
-*/
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_pattern_convert(PCRE2_SPTR pattern, PCRE2_SIZE plength, uint32_t options,
- PCRE2_UCHAR **buffptr, PCRE2_SIZE *bufflenptr,
- pcre2_convert_context *ccontext)
-{
-int i, rc;
-PCRE2_UCHAR dummy_buffer[DUMMY_BUFFER_SIZE];
-PCRE2_UCHAR *use_buffer = dummy_buffer;
-PCRE2_SIZE use_length = DUMMY_BUFFER_SIZE;
-BOOL utf = (options & PCRE2_CONVERT_UTF) != 0;
-uint32_t pattype = options & TYPE_OPTIONS;
-
-if (pattern == NULL || bufflenptr == NULL) return PCRE2_ERROR_NULL;
-
-if ((options & ~ALL_OPTIONS) != 0 || /* Undefined bit set */
- (pattype & (~pattype+1)) != pattype || /* More than one type set */
- pattype == 0) /* No type set */
- {
- *bufflenptr = 0; /* Error offset */
- return PCRE2_ERROR_BADOPTION;
- }
-
-if (plength == PCRE2_ZERO_TERMINATED) plength = PRIV(strlen)(pattern);
-if (ccontext == NULL) ccontext =
- (pcre2_convert_context *)(&PRIV(default_convert_context));
-
-/* Check UTF if required. */
-
-#ifndef SUPPORT_UNICODE
-if (utf)
- {
- *bufflenptr = 0; /* Error offset */
- return PCRE2_ERROR_UNICODE_NOT_SUPPORTED;
- }
-#else
-if (utf && (options & PCRE2_CONVERT_NO_UTF_CHECK) == 0)
- {
- PCRE2_SIZE erroroffset;
- rc = PRIV(valid_utf)(pattern, plength, &erroroffset);
- if (rc != 0)
- {
- *bufflenptr = erroroffset;
- return rc;
- }
- }
-#endif
-
-/* If buffptr is not NULL, and what it points to is not NULL, we are being
-provided with a buffer and a length, so set them as the buffer to use. */
-
-if (buffptr != NULL && *buffptr != NULL)
- {
- use_buffer = *buffptr;
- use_length = *bufflenptr;
- }
-
-/* Call an individual converter, either just once (if a buffer was provided or
-just the length is needed), or twice (if a memory allocation is required). */
-
-for (i = 0; i < 2; i++)
- {
- PCRE2_UCHAR *allocated;
- BOOL dummyrun = buffptr == NULL || *buffptr == NULL;
-
- switch(pattype)
- {
- case PCRE2_CONVERT_GLOB:
- rc = convert_glob(options & ~PCRE2_CONVERT_GLOB, pattern, plength, utf,
- use_buffer, use_length, bufflenptr, dummyrun, ccontext);
- break;
-
- case PCRE2_CONVERT_POSIX_BASIC:
- case PCRE2_CONVERT_POSIX_EXTENDED:
- rc = convert_posix(pattype, pattern, plength, utf, use_buffer, use_length,
- bufflenptr, dummyrun, ccontext);
- break;
-
- default:
- *bufflenptr = 0; /* Error offset */
- return PCRE2_ERROR_INTERNAL;
- }
-
- if (rc != 0 || /* Error */
- buffptr == NULL || /* Just the length is required */
- *buffptr != NULL) /* Buffer was provided or allocated */
- return rc;
-
- /* Allocate memory for the buffer, with hidden space for an allocator at
- the start. The next time round the loop runs the conversion for real. */
-
- allocated = PRIV(memctl_malloc)(sizeof(pcre2_memctl) +
- (*bufflenptr + 1)*PCRE2_CODE_UNIT_WIDTH, (pcre2_memctl *)ccontext);
- if (allocated == NULL) return PCRE2_ERROR_NOMEMORY;
- *buffptr = (PCRE2_UCHAR *)(((char *)allocated) + sizeof(pcre2_memctl));
-
- use_buffer = *buffptr;
- use_length = *bufflenptr + 1;
- }
-
-/* Control should never get here. */
-
-return PCRE2_ERROR_INTERNAL;
-}
-
-
-/*************************************************
-* Free converted pattern *
-*************************************************/
-
-/* This frees a converted pattern that was put in newly-allocated memory.
-
-Argument: the converted pattern
-Returns: nothing
-*/
-
-PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
-pcre2_converted_pattern_free(PCRE2_UCHAR *converted)
-{
-if (converted != NULL)
- {
- pcre2_memctl *memctl =
- (pcre2_memctl *)((char *)converted - sizeof(pcre2_memctl));
- memctl->free(memctl, memctl->memory_data);
- }
-}
-
-/* End of pcre2_convert.c */
diff --git a/contrib/libs/pcre2/src/pcre2_dfa_match.c b/contrib/libs/pcre2/src/pcre2_dfa_match.c
deleted file mode 100644
index faa3db8b57..0000000000
--- a/contrib/libs/pcre2/src/pcre2_dfa_match.c
+++ /dev/null
@@ -1,4066 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2022 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains the external function pcre2_dfa_match(), which is an
-alternative matching function that uses a sort of DFA algorithm (not a true
-FSM). This is NOT Perl-compatible, but it has advantages in certain
-applications. */
-
-
-/* NOTE ABOUT PERFORMANCE: A user of this function sent some code that improved
-the performance of his patterns greatly. I could not use it as it stood, as it
-was not thread safe, and made assumptions about pattern sizes. Also, it caused
-test 7 to loop, and test 9 to crash with a segfault.
-
-The issue is the check for duplicate states, which is done by a simple linear
-search up the state list. (Grep for "duplicate" below to find the code.) For
-many patterns, there will never be many states active at one time, so a simple
-linear search is fine. In patterns that have many active states, it might be a
-bottleneck. The suggested code used an indexing scheme to remember which states
-had previously been used for each character, and avoided the linear search when
-it knew there was no chance of a duplicate. This was implemented when adding
-states to the state lists.
-
-I wrote some thread-safe, not-limited code to try something similar at the time
-of checking for duplicates (instead of when adding states), using index vectors
-on the stack. It did give a 13% improvement with one specially constructed
-pattern for certain subject strings, but on other strings and on many of the
-simpler patterns in the test suite it did worse. The major problem, I think,
-was the extra time to initialize the index. This had to be done for each call
-of internal_dfa_match(). (The supplied patch used a static vector, initialized
-only once - I suspect this was the cause of the problems with the tests.)
-
-Overall, I concluded that the gains in some cases did not outweigh the losses
-in others, so I abandoned this code. */
-
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-#define NLBLOCK mb /* Block containing newline information */
-#define PSSTART start_subject /* Field containing processed string start */
-#define PSEND end_subject /* Field containing processed string end */
-
-#include "pcre2_internal.h"
-
-#define PUBLIC_DFA_MATCH_OPTIONS \
- (PCRE2_ANCHORED|PCRE2_ENDANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \
- PCRE2_NOTEMPTY_ATSTART|PCRE2_NO_UTF_CHECK|PCRE2_PARTIAL_HARD| \
- PCRE2_PARTIAL_SOFT|PCRE2_DFA_SHORTEST|PCRE2_DFA_RESTART| \
- PCRE2_COPY_MATCHED_SUBJECT)
-
-
-/*************************************************
-* Code parameters and static tables *
-*************************************************/
-
-/* These are offsets that are used to turn the OP_TYPESTAR and friends opcodes
-into others, under special conditions. A gap of 20 between the blocks should be
-enough. The resulting opcodes don't have to be less than 256 because they are
-never stored, so we push them well clear of the normal opcodes. */
-
-#define OP_PROP_EXTRA 300
-#define OP_EXTUNI_EXTRA 320
-#define OP_ANYNL_EXTRA 340
-#define OP_HSPACE_EXTRA 360
-#define OP_VSPACE_EXTRA 380
-
-
-/* This table identifies those opcodes that are followed immediately by a
-character that is to be tested in some way. This makes it possible to
-centralize the loading of these characters. In the case of Type * etc, the
-"character" is the opcode for \D, \d, \S, \s, \W, or \w, which will always be a
-small value. Non-zero values in the table are the offsets from the opcode where
-the character is to be found. ***NOTE*** If the start of this table is
-modified, the three tables that follow must also be modified. */
-
-static const uint8_t coptable[] = {
- 0, /* End */
- 0, 0, 0, 0, 0, /* \A, \G, \K, \B, \b */
- 0, 0, 0, 0, 0, 0, /* \D, \d, \S, \s, \W, \w */
- 0, 0, 0, /* Any, AllAny, Anybyte */
- 0, 0, /* \P, \p */
- 0, 0, 0, 0, 0, /* \R, \H, \h, \V, \v */
- 0, /* \X */
- 0, 0, 0, 0, 0, 0, /* \Z, \z, $, $M, ^, ^M */
- 1, /* Char */
- 1, /* Chari */
- 1, /* not */
- 1, /* noti */
- /* Positive single-char repeats */
- 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */
- 1+IMM2_SIZE, 1+IMM2_SIZE, /* upto, minupto */
- 1+IMM2_SIZE, /* exact */
- 1, 1, 1, 1+IMM2_SIZE, /* *+, ++, ?+, upto+ */
- 1, 1, 1, 1, 1, 1, /* *I, *?I, +I, +?I, ?I, ??I */
- 1+IMM2_SIZE, 1+IMM2_SIZE, /* upto I, minupto I */
- 1+IMM2_SIZE, /* exact I */
- 1, 1, 1, 1+IMM2_SIZE, /* *+I, ++I, ?+I, upto+I */
- /* Negative single-char repeats - only for chars < 256 */
- 1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */
- 1+IMM2_SIZE, 1+IMM2_SIZE, /* NOT upto, minupto */
- 1+IMM2_SIZE, /* NOT exact */
- 1, 1, 1, 1+IMM2_SIZE, /* NOT *+, ++, ?+, upto+ */
- 1, 1, 1, 1, 1, 1, /* NOT *I, *?I, +I, +?I, ?I, ??I */
- 1+IMM2_SIZE, 1+IMM2_SIZE, /* NOT upto I, minupto I */
- 1+IMM2_SIZE, /* NOT exact I */
- 1, 1, 1, 1+IMM2_SIZE, /* NOT *+I, ++I, ?+I, upto+I */
- /* Positive type repeats */
- 1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */
- 1+IMM2_SIZE, 1+IMM2_SIZE, /* Type upto, minupto */
- 1+IMM2_SIZE, /* Type exact */
- 1, 1, 1, 1+IMM2_SIZE, /* Type *+, ++, ?+, upto+ */
- /* Character class & ref repeats */
- 0, 0, 0, 0, 0, 0, /* *, *?, +, +?, ?, ?? */
- 0, 0, /* CRRANGE, CRMINRANGE */
- 0, 0, 0, 0, /* Possessive *+, ++, ?+, CRPOSRANGE */
- 0, /* CLASS */
- 0, /* NCLASS */
- 0, /* XCLASS - variable length */
- 0, /* REF */
- 0, /* REFI */
- 0, /* DNREF */
- 0, /* DNREFI */
- 0, /* RECURSE */
- 0, /* CALLOUT */
- 0, /* CALLOUT_STR */
- 0, /* Alt */
- 0, /* Ket */
- 0, /* KetRmax */
- 0, /* KetRmin */
- 0, /* KetRpos */
- 0, /* Reverse */
- 0, /* Assert */
- 0, /* Assert not */
- 0, /* Assert behind */
- 0, /* Assert behind not */
- 0, /* NA assert */
- 0, /* NA assert behind */
- 0, /* ONCE */
- 0, /* SCRIPT_RUN */
- 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */
- 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */
- 0, 0, /* CREF, DNCREF */
- 0, 0, /* RREF, DNRREF */
- 0, 0, /* FALSE, TRUE */
- 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */
- 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */
- 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */
- 0, 0, /* COMMIT, COMMIT_ARG */
- 0, 0, 0, /* FAIL, ACCEPT, ASSERT_ACCEPT */
- 0, 0, 0 /* CLOSE, SKIPZERO, DEFINE */
-};
-
-/* This table identifies those opcodes that inspect a character. It is used to
-remember the fact that a character could have been inspected when the end of
-the subject is reached. ***NOTE*** If the start of this table is modified, the
-two tables that follow must also be modified. */
-
-static const uint8_t poptable[] = {
- 0, /* End */
- 0, 0, 0, 1, 1, /* \A, \G, \K, \B, \b */
- 1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */
- 1, 1, 1, /* Any, AllAny, Anybyte */
- 1, 1, /* \P, \p */
- 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */
- 1, /* \X */
- 0, 0, 0, 0, 0, 0, /* \Z, \z, $, $M, ^, ^M */
- 1, /* Char */
- 1, /* Chari */
- 1, /* not */
- 1, /* noti */
- /* Positive single-char repeats */
- 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */
- 1, 1, 1, /* upto, minupto, exact */
- 1, 1, 1, 1, /* *+, ++, ?+, upto+ */
- 1, 1, 1, 1, 1, 1, /* *I, *?I, +I, +?I, ?I, ??I */
- 1, 1, 1, /* upto I, minupto I, exact I */
- 1, 1, 1, 1, /* *+I, ++I, ?+I, upto+I */
- /* Negative single-char repeats - only for chars < 256 */
- 1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */
- 1, 1, 1, /* NOT upto, minupto, exact */
- 1, 1, 1, 1, /* NOT *+, ++, ?+, upto+ */
- 1, 1, 1, 1, 1, 1, /* NOT *I, *?I, +I, +?I, ?I, ??I */
- 1, 1, 1, /* NOT upto I, minupto I, exact I */
- 1, 1, 1, 1, /* NOT *+I, ++I, ?+I, upto+I */
- /* Positive type repeats */
- 1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */
- 1, 1, 1, /* Type upto, minupto, exact */
- 1, 1, 1, 1, /* Type *+, ++, ?+, upto+ */
- /* Character class & ref repeats */
- 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */
- 1, 1, /* CRRANGE, CRMINRANGE */
- 1, 1, 1, 1, /* Possessive *+, ++, ?+, CRPOSRANGE */
- 1, /* CLASS */
- 1, /* NCLASS */
- 1, /* XCLASS - variable length */
- 0, /* REF */
- 0, /* REFI */
- 0, /* DNREF */
- 0, /* DNREFI */
- 0, /* RECURSE */
- 0, /* CALLOUT */
- 0, /* CALLOUT_STR */
- 0, /* Alt */
- 0, /* Ket */
- 0, /* KetRmax */
- 0, /* KetRmin */
- 0, /* KetRpos */
- 0, /* Reverse */
- 0, /* Assert */
- 0, /* Assert not */
- 0, /* Assert behind */
- 0, /* Assert behind not */
- 0, /* NA assert */
- 0, /* NA assert behind */
- 0, /* ONCE */
- 0, /* SCRIPT_RUN */
- 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */
- 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */
- 0, 0, /* CREF, DNCREF */
- 0, 0, /* RREF, DNRREF */
- 0, 0, /* FALSE, TRUE */
- 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */
- 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */
- 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */
- 0, 0, /* COMMIT, COMMIT_ARG */
- 0, 0, 0, /* FAIL, ACCEPT, ASSERT_ACCEPT */
- 0, 0, 0 /* CLOSE, SKIPZERO, DEFINE */
-};
-
-/* These 2 tables allow for compact code for testing for \D, \d, \S, \s, \W,
-and \w */
-
-static const uint8_t toptable1[] = {
- 0, 0, 0, 0, 0, 0,
- ctype_digit, ctype_digit,
- ctype_space, ctype_space,
- ctype_word, ctype_word,
- 0, 0 /* OP_ANY, OP_ALLANY */
-};
-
-static const uint8_t toptable2[] = {
- 0, 0, 0, 0, 0, 0,
- ctype_digit, 0,
- ctype_space, 0,
- ctype_word, 0,
- 1, 1 /* OP_ANY, OP_ALLANY */
-};
-
-
-/* Structure for holding data about a particular state, which is in effect the
-current data for an active path through the match tree. It must consist
-entirely of ints because the working vector we are passed, and which we put
-these structures in, is a vector of ints. */
-
-typedef struct stateblock {
- int offset; /* Offset to opcode (-ve has meaning) */
- int count; /* Count for repeats */
- int data; /* Some use extra data */
-} stateblock;
-
-#define INTS_PER_STATEBLOCK (int)(sizeof(stateblock)/sizeof(int))
-
-
-/* Before version 10.32 the recursive calls of internal_dfa_match() were passed
-local working space and output vectors that were created on the stack. This has
-caused issues for some patterns, especially in small-stack environments such as
-Windows. A new scheme is now in use which sets up a vector on the stack, but if
-this is too small, heap memory is used, up to the heap_limit. The main
-parameters are all numbers of ints because the workspace is a vector of ints.
-
-The size of the starting stack vector, DFA_START_RWS_SIZE, is in bytes, and is
-defined in pcre2_internal.h so as to be available to pcre2test when it is
-finding the minimum heap requirement for a match. */
-
-#define OVEC_UNIT (sizeof(PCRE2_SIZE)/sizeof(int))
-
-#define RWS_BASE_SIZE (DFA_START_RWS_SIZE/sizeof(int)) /* Stack vector */
-#define RWS_RSIZE 1000 /* Work size for recursion */
-#define RWS_OVEC_RSIZE (1000*OVEC_UNIT) /* Ovector for recursion */
-#define RWS_OVEC_OSIZE (2*OVEC_UNIT) /* Ovector in other cases */
-
-/* This structure is at the start of each workspace block. */
-
-typedef struct RWS_anchor {
- struct RWS_anchor *next;
- uint32_t size; /* Number of ints */
- uint32_t free; /* Number of ints */
-} RWS_anchor;
-
-#define RWS_ANCHOR_SIZE (sizeof(RWS_anchor)/sizeof(int))
-
-
-
-/*************************************************
-* Process a callout *
-*************************************************/
-
-/* This function is called to perform a callout.
-
-Arguments:
- code current code pointer
- offsets points to current capture offsets
- current_subject start of current subject match
- ptr current position in subject
- mb the match block
- extracode extra code offset when called from condition
- lengthptr where to return the callout length
-
-Returns: the return from the callout
-*/
-
-static int
-do_callout_dfa(PCRE2_SPTR code, PCRE2_SIZE *offsets, PCRE2_SPTR current_subject,
- PCRE2_SPTR ptr, dfa_match_block *mb, PCRE2_SIZE extracode,
- PCRE2_SIZE *lengthptr)
-{
-pcre2_callout_block *cb = mb->cb;
-
-*lengthptr = (code[extracode] == OP_CALLOUT)?
- (PCRE2_SIZE)PRIV(OP_lengths)[OP_CALLOUT] :
- (PCRE2_SIZE)GET(code, 1 + 2*LINK_SIZE + extracode);
-
-if (mb->callout == NULL) return 0; /* No callout provided */
-
-/* Fixed fields in the callout block are set once and for all at the start of
-matching. */
-
-cb->offset_vector = offsets;
-cb->start_match = (PCRE2_SIZE)(current_subject - mb->start_subject);
-cb->current_position = (PCRE2_SIZE)(ptr - mb->start_subject);
-cb->pattern_position = GET(code, 1 + extracode);
-cb->next_item_length = GET(code, 1 + LINK_SIZE + extracode);
-
-if (code[extracode] == OP_CALLOUT)
- {
- cb->callout_number = code[1 + 2*LINK_SIZE + extracode];
- cb->callout_string_offset = 0;
- cb->callout_string = NULL;
- cb->callout_string_length = 0;
- }
-else
- {
- cb->callout_number = 0;
- cb->callout_string_offset = GET(code, 1 + 3*LINK_SIZE + extracode);
- cb->callout_string = code + (1 + 4*LINK_SIZE + extracode) + 1;
- cb->callout_string_length = *lengthptr - (1 + 4*LINK_SIZE) - 2;
- }
-
-return (mb->callout)(cb, mb->callout_data);
-}
-
-
-
-/*************************************************
-* Expand local workspace memory *
-*************************************************/
-
-/* This function is called when internal_dfa_match() is about to be called
-recursively and there is insufficient working space left in the current
-workspace block. If there's an existing next block, use it; otherwise get a new
-block unless the heap limit is reached.
-
-Arguments:
- rwsptr pointer to block pointer (updated)
- ovecsize space needed for an ovector
- mb the match block
-
-Returns: 0 rwsptr has been updated
- !0 an error code
-*/
-
-static int
-more_workspace(RWS_anchor **rwsptr, unsigned int ovecsize, dfa_match_block *mb)
-{
-RWS_anchor *rws = *rwsptr;
-RWS_anchor *new;
-
-if (rws->next != NULL)
- {
- new = rws->next;
- }
-
-/* Sizes in the RWS_anchor blocks are in units of sizeof(int), but
-mb->heap_limit and mb->heap_used are in kibibytes. Play carefully, to avoid
-overflow. */
-
-else
- {
- uint32_t newsize = (rws->size >= UINT32_MAX/2)? UINT32_MAX/2 : rws->size * 2;
- uint32_t newsizeK = newsize/(1024/sizeof(int));
-
- if (newsizeK + mb->heap_used > mb->heap_limit)
- newsizeK = (uint32_t)(mb->heap_limit - mb->heap_used);
- newsize = newsizeK*(1024/sizeof(int));
-
- if (newsize < RWS_RSIZE + ovecsize + RWS_ANCHOR_SIZE)
- return PCRE2_ERROR_HEAPLIMIT;
- new = mb->memctl.malloc(newsize*sizeof(int), mb->memctl.memory_data);
- if (new == NULL) return PCRE2_ERROR_NOMEMORY;
- mb->heap_used += newsizeK;
- new->next = NULL;
- new->size = newsize;
- rws->next = new;
- }
-
-new->free = new->size - RWS_ANCHOR_SIZE;
-*rwsptr = new;
-return 0;
-}
-
-
-
-/*************************************************
-* Match a Regular Expression - DFA engine *
-*************************************************/
-
-/* This internal function applies a compiled pattern to a subject string,
-starting at a given point, using a DFA engine. This function is called from the
-external one, possibly multiple times if the pattern is not anchored. The
-function calls itself recursively for some kinds of subpattern.
-
-Arguments:
- mb the match_data block with fixed information
- this_start_code the opening bracket of this subexpression's code
- current_subject where we currently are in the subject string
- start_offset start offset in the subject string
- offsets vector to contain the matching string offsets
- offsetcount size of same
- workspace vector of workspace
- wscount size of same
- rlevel function call recursion level
-
-Returns: > 0 => number of match offset pairs placed in offsets
- = 0 => offsets overflowed; longest matches are present
- -1 => failed to match
- < -1 => some kind of unexpected problem
-
-The following macros are used for adding states to the two state vectors (one
-for the current character, one for the following character). */
-
-#define ADD_ACTIVE(x,y) \
- if (active_count++ < wscount) \
- { \
- next_active_state->offset = (x); \
- next_active_state->count = (y); \
- next_active_state++; \
- } \
- else return PCRE2_ERROR_DFA_WSSIZE
-
-#define ADD_ACTIVE_DATA(x,y,z) \
- if (active_count++ < wscount) \
- { \
- next_active_state->offset = (x); \
- next_active_state->count = (y); \
- next_active_state->data = (z); \
- next_active_state++; \
- } \
- else return PCRE2_ERROR_DFA_WSSIZE
-
-#define ADD_NEW(x,y) \
- if (new_count++ < wscount) \
- { \
- next_new_state->offset = (x); \
- next_new_state->count = (y); \
- next_new_state++; \
- } \
- else return PCRE2_ERROR_DFA_WSSIZE
-
-#define ADD_NEW_DATA(x,y,z) \
- if (new_count++ < wscount) \
- { \
- next_new_state->offset = (x); \
- next_new_state->count = (y); \
- next_new_state->data = (z); \
- next_new_state++; \
- } \
- else return PCRE2_ERROR_DFA_WSSIZE
-
-/* And now, here is the code */
-
-static int
-internal_dfa_match(
- dfa_match_block *mb,
- PCRE2_SPTR this_start_code,
- PCRE2_SPTR current_subject,
- PCRE2_SIZE start_offset,
- PCRE2_SIZE *offsets,
- uint32_t offsetcount,
- int *workspace,
- int wscount,
- uint32_t rlevel,
- int *RWS)
-{
-stateblock *active_states, *new_states, *temp_states;
-stateblock *next_active_state, *next_new_state;
-const uint8_t *ctypes, *lcc, *fcc;
-PCRE2_SPTR ptr;
-PCRE2_SPTR end_code;
-dfa_recursion_info new_recursive;
-int active_count, new_count, match_count;
-
-/* Some fields in the mb block are frequently referenced, so we load them into
-independent variables in the hope that this will perform better. */
-
-PCRE2_SPTR start_subject = mb->start_subject;
-PCRE2_SPTR end_subject = mb->end_subject;
-PCRE2_SPTR start_code = mb->start_code;
-
-#ifdef SUPPORT_UNICODE
-BOOL utf = (mb->poptions & PCRE2_UTF) != 0;
-BOOL utf_or_ucp = utf || (mb->poptions & PCRE2_UCP) != 0;
-#else
-BOOL utf = FALSE;
-#endif
-
-BOOL reset_could_continue = FALSE;
-
-if (mb->match_call_count++ >= mb->match_limit) return PCRE2_ERROR_MATCHLIMIT;
-if (rlevel++ > mb->match_limit_depth) return PCRE2_ERROR_DEPTHLIMIT;
-offsetcount &= (uint32_t)(-2); /* Round down */
-
-wscount -= 2;
-wscount = (wscount - (wscount % (INTS_PER_STATEBLOCK * 2))) /
- (2 * INTS_PER_STATEBLOCK);
-
-ctypes = mb->tables + ctypes_offset;
-lcc = mb->tables + lcc_offset;
-fcc = mb->tables + fcc_offset;
-
-match_count = PCRE2_ERROR_NOMATCH; /* A negative number */
-
-active_states = (stateblock *)(workspace + 2);
-next_new_state = new_states = active_states + wscount;
-new_count = 0;
-
-/* The first thing in any (sub) pattern is a bracket of some sort. Push all
-the alternative states onto the list, and find out where the end is. This
-makes is possible to use this function recursively, when we want to stop at a
-matching internal ket rather than at the end.
-
-If we are dealing with a backward assertion we have to find out the maximum
-amount to move back, and set up each alternative appropriately. */
-
-if (*this_start_code == OP_ASSERTBACK || *this_start_code == OP_ASSERTBACK_NOT)
- {
- size_t max_back = 0;
- size_t gone_back;
-
- end_code = this_start_code;
- do
- {
- size_t back = (size_t)GET(end_code, 2+LINK_SIZE);
- if (back > max_back) max_back = back;
- end_code += GET(end_code, 1);
- }
- while (*end_code == OP_ALT);
-
- /* If we can't go back the amount required for the longest lookbehind
- pattern, go back as far as we can; some alternatives may still be viable. */
-
-#ifdef SUPPORT_UNICODE
- /* In character mode we have to step back character by character */
-
- if (utf)
- {
- for (gone_back = 0; gone_back < max_back; gone_back++)
- {
- if (current_subject <= start_subject) break;
- current_subject--;
- ACROSSCHAR(current_subject > start_subject, current_subject,
- current_subject--);
- }
- }
- else
-#endif
-
- /* In byte-mode we can do this quickly. */
-
- {
- size_t current_offset = (size_t)(current_subject - start_subject);
- gone_back = (current_offset < max_back)? current_offset : max_back;
- current_subject -= gone_back;
- }
-
- /* Save the earliest consulted character */
-
- if (current_subject < mb->start_used_ptr)
- mb->start_used_ptr = current_subject;
-
- /* Now we can process the individual branches. There will be an OP_REVERSE at
- the start of each branch, except when the length of the branch is zero. */
-
- end_code = this_start_code;
- do
- {
- uint32_t revlen = (end_code[1+LINK_SIZE] == OP_REVERSE)? 1 + LINK_SIZE : 0;
- size_t back = (revlen == 0)? 0 : (size_t)GET(end_code, 2+LINK_SIZE);
- if (back <= gone_back)
- {
- int bstate = (int)(end_code - start_code + 1 + LINK_SIZE + revlen);
- ADD_NEW_DATA(-bstate, 0, (int)(gone_back - back));
- }
- end_code += GET(end_code, 1);
- }
- while (*end_code == OP_ALT);
- }
-
-/* This is the code for a "normal" subpattern (not a backward assertion). The
-start of a whole pattern is always one of these. If we are at the top level,
-we may be asked to restart matching from the same point that we reached for a
-previous partial match. We still have to scan through the top-level branches to
-find the end state. */
-
-else
- {
- end_code = this_start_code;
-
- /* Restarting */
-
- if (rlevel == 1 && (mb->moptions & PCRE2_DFA_RESTART) != 0)
- {
- do { end_code += GET(end_code, 1); } while (*end_code == OP_ALT);
- new_count = workspace[1];
- if (!workspace[0])
- memcpy(new_states, active_states, (size_t)new_count * sizeof(stateblock));
- }
-
- /* Not restarting */
-
- else
- {
- int length = 1 + LINK_SIZE +
- ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA ||
- *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS)
- ? IMM2_SIZE:0);
- do
- {
- ADD_NEW((int)(end_code - start_code + length), 0);
- end_code += GET(end_code, 1);
- length = 1 + LINK_SIZE;
- }
- while (*end_code == OP_ALT);
- }
- }
-
-workspace[0] = 0; /* Bit indicating which vector is current */
-
-/* Loop for scanning the subject */
-
-ptr = current_subject;
-for (;;)
- {
- int i, j;
- int clen, dlen;
- uint32_t c, d;
- int forced_fail = 0;
- BOOL partial_newline = FALSE;
- BOOL could_continue = reset_could_continue;
- reset_could_continue = FALSE;
-
- if (ptr > mb->last_used_ptr) mb->last_used_ptr = ptr;
-
- /* Make the new state list into the active state list and empty the
- new state list. */
-
- temp_states = active_states;
- active_states = new_states;
- new_states = temp_states;
- active_count = new_count;
- new_count = 0;
-
- workspace[0] ^= 1; /* Remember for the restarting feature */
- workspace[1] = active_count;
-
- /* Set the pointers for adding new states */
-
- next_active_state = active_states + active_count;
- next_new_state = new_states;
-
- /* Load the current character from the subject outside the loop, as many
- different states may want to look at it, and we assume that at least one
- will. */
-
- if (ptr < end_subject)
- {
- clen = 1; /* Number of data items in the character */
-#ifdef SUPPORT_UNICODE
- GETCHARLENTEST(c, ptr, clen);
-#else
- c = *ptr;
-#endif /* SUPPORT_UNICODE */
- }
- else
- {
- clen = 0; /* This indicates the end of the subject */
- c = NOTACHAR; /* This value should never actually be used */
- }
-
- /* Scan up the active states and act on each one. The result of an action
- may be to add more states to the currently active list (e.g. on hitting a
- parenthesis) or it may be to put states on the new list, for considering
- when we move the character pointer on. */
-
- for (i = 0; i < active_count; i++)
- {
- stateblock *current_state = active_states + i;
- BOOL caseless = FALSE;
- PCRE2_SPTR code;
- uint32_t codevalue;
- int state_offset = current_state->offset;
- int rrc;
- int count;
-
- /* A negative offset is a special case meaning "hold off going to this
- (negated) state until the number of characters in the data field have
- been skipped". If the could_continue flag was passed over from a previous
- state, arrange for it to passed on. */
-
- if (state_offset < 0)
- {
- if (current_state->data > 0)
- {
- ADD_NEW_DATA(state_offset, current_state->count,
- current_state->data - 1);
- if (could_continue) reset_could_continue = TRUE;
- continue;
- }
- else
- {
- current_state->offset = state_offset = -state_offset;
- }
- }
-
- /* Check for a duplicate state with the same count, and skip if found.
- See the note at the head of this module about the possibility of improving
- performance here. */
-
- for (j = 0; j < i; j++)
- {
- if (active_states[j].offset == state_offset &&
- active_states[j].count == current_state->count)
- goto NEXT_ACTIVE_STATE;
- }
-
- /* The state offset is the offset to the opcode */
-
- code = start_code + state_offset;
- codevalue = *code;
-
- /* If this opcode inspects a character, but we are at the end of the
- subject, remember the fact for use when testing for a partial match. */
-
- if (clen == 0 && poptable[codevalue] != 0)
- could_continue = TRUE;
-
- /* If this opcode is followed by an inline character, load it. It is
- tempting to test for the presence of a subject character here, but that
- is wrong, because sometimes zero repetitions of the subject are
- permitted.
-
- We also use this mechanism for opcodes such as OP_TYPEPLUS that take an
- argument that is not a data character - but is always one byte long because
- the values are small. We have to take special action to deal with \P, \p,
- \H, \h, \V, \v and \X in this case. To keep the other cases fast, convert
- these ones to new opcodes. */
-
- if (coptable[codevalue] > 0)
- {
- dlen = 1;
-#ifdef SUPPORT_UNICODE
- if (utf) { GETCHARLEN(d, (code + coptable[codevalue]), dlen); } else
-#endif /* SUPPORT_UNICODE */
- d = code[coptable[codevalue]];
- if (codevalue >= OP_TYPESTAR)
- {
- switch(d)
- {
- case OP_ANYBYTE: return PCRE2_ERROR_DFA_UITEM;
- case OP_NOTPROP:
- case OP_PROP: codevalue += OP_PROP_EXTRA; break;
- case OP_ANYNL: codevalue += OP_ANYNL_EXTRA; break;
- case OP_EXTUNI: codevalue += OP_EXTUNI_EXTRA; break;
- case OP_NOT_HSPACE:
- case OP_HSPACE: codevalue += OP_HSPACE_EXTRA; break;
- case OP_NOT_VSPACE:
- case OP_VSPACE: codevalue += OP_VSPACE_EXTRA; break;
- default: break;
- }
- }
- }
- else
- {
- dlen = 0; /* Not strictly necessary, but compilers moan */
- d = NOTACHAR; /* if these variables are not set. */
- }
-
-
- /* Now process the individual opcodes */
-
- switch (codevalue)
- {
-/* ========================================================================== */
- /* These cases are never obeyed. This is a fudge that causes a compile-
- time error if the vectors coptable or poptable, which are indexed by
- opcode, are not the correct length. It seems to be the only way to do
- such a check at compile time, as the sizeof() operator does not work
- in the C preprocessor. */
-
- case OP_TABLE_LENGTH:
- case OP_TABLE_LENGTH +
- ((sizeof(coptable) == OP_TABLE_LENGTH) &&
- (sizeof(poptable) == OP_TABLE_LENGTH)):
- return 0;
-
-/* ========================================================================== */
- /* Reached a closing bracket. If not at the end of the pattern, carry
- on with the next opcode. For repeating opcodes, also add the repeat
- state. Note that KETRPOS will always be encountered at the end of the
- subpattern, because the possessive subpattern repeats are always handled
- using recursive calls. Thus, it never adds any new states.
-
- At the end of the (sub)pattern, unless we have an empty string and
- PCRE2_NOTEMPTY is set, or PCRE2_NOTEMPTY_ATSTART is set and we are at the
- start of the subject, save the match data, shifting up all previous
- matches so we always have the longest first. */
-
- case OP_KET:
- case OP_KETRMIN:
- case OP_KETRMAX:
- case OP_KETRPOS:
- if (code != end_code)
- {
- ADD_ACTIVE(state_offset + 1 + LINK_SIZE, 0);
- if (codevalue != OP_KET)
- {
- ADD_ACTIVE(state_offset - (int)GET(code, 1), 0);
- }
- }
- else
- {
- if (ptr > current_subject ||
- ((mb->moptions & PCRE2_NOTEMPTY) == 0 &&
- ((mb->moptions & PCRE2_NOTEMPTY_ATSTART) == 0 ||
- current_subject > start_subject + mb->start_offset)))
- {
- if (match_count < 0) match_count = (offsetcount >= 2)? 1 : 0;
- else if (match_count > 0 && ++match_count * 2 > (int)offsetcount)
- match_count = 0;
- count = ((match_count == 0)? (int)offsetcount : match_count * 2) - 2;
- if (count > 0) (void)memmove(offsets + 2, offsets,
- (size_t)count * sizeof(PCRE2_SIZE));
- if (offsetcount >= 2)
- {
- offsets[0] = (PCRE2_SIZE)(current_subject - start_subject);
- offsets[1] = (PCRE2_SIZE)(ptr - start_subject);
- }
- if ((mb->moptions & PCRE2_DFA_SHORTEST) != 0) return match_count;
- }
- }
- break;
-
-/* ========================================================================== */
- /* These opcodes add to the current list of states without looking
- at the current character. */
-
- /*-----------------------------------------------------------------*/
- case OP_ALT:
- do { code += GET(code, 1); } while (*code == OP_ALT);
- ADD_ACTIVE((int)(code - start_code), 0);
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_BRA:
- case OP_SBRA:
- do
- {
- ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
- code += GET(code, 1);
- }
- while (*code == OP_ALT);
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_CBRA:
- case OP_SCBRA:
- ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE + IMM2_SIZE), 0);
- code += GET(code, 1);
- while (*code == OP_ALT)
- {
- ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
- code += GET(code, 1);
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_BRAZERO:
- case OP_BRAMINZERO:
- ADD_ACTIVE(state_offset + 1, 0);
- code += 1 + GET(code, 2);
- while (*code == OP_ALT) code += GET(code, 1);
- ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_SKIPZERO:
- code += 1 + GET(code, 2);
- while (*code == OP_ALT) code += GET(code, 1);
- ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_CIRC:
- if (ptr == start_subject && (mb->moptions & PCRE2_NOTBOL) == 0)
- { ADD_ACTIVE(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_CIRCM:
- if ((ptr == start_subject && (mb->moptions & PCRE2_NOTBOL) == 0) ||
- ((ptr != end_subject || (mb->poptions & PCRE2_ALT_CIRCUMFLEX) != 0 )
- && WAS_NEWLINE(ptr)))
- { ADD_ACTIVE(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_EOD:
- if (ptr >= end_subject)
- {
- if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)
- return PCRE2_ERROR_PARTIAL;
- else { ADD_ACTIVE(state_offset + 1, 0); }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_SOD:
- if (ptr == start_subject) { ADD_ACTIVE(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_SOM:
- if (ptr == start_subject + start_offset) { ADD_ACTIVE(state_offset + 1, 0); }
- break;
-
-
-/* ========================================================================== */
- /* These opcodes inspect the next subject character, and sometimes
- the previous one as well, but do not have an argument. The variable
- clen contains the length of the current character and is zero if we are
- at the end of the subject. */
-
- /*-----------------------------------------------------------------*/
- case OP_ANY:
- if (clen > 0 && !IS_NEWLINE(ptr))
- {
- if (ptr + 1 >= mb->end_subject &&
- (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- c == NLBLOCK->nl[0])
- {
- could_continue = partial_newline = TRUE;
- }
- else
- {
- ADD_NEW(state_offset + 1, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_ALLANY:
- if (clen > 0)
- { ADD_NEW(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_EODN:
- if (clen == 0 || (IS_NEWLINE(ptr) && ptr == end_subject - mb->nllen))
- {
- if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)
- return PCRE2_ERROR_PARTIAL;
- ADD_ACTIVE(state_offset + 1, 0);
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_DOLL:
- if ((mb->moptions & PCRE2_NOTEOL) == 0)
- {
- if (clen == 0 && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)
- could_continue = TRUE;
- else if (clen == 0 ||
- ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr) &&
- (ptr == end_subject - mb->nllen)
- ))
- { ADD_ACTIVE(state_offset + 1, 0); }
- else if (ptr + 1 >= mb->end_subject &&
- (mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0 &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- c == NLBLOCK->nl[0])
- {
- if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)
- {
- reset_could_continue = TRUE;
- ADD_NEW_DATA(-(state_offset + 1), 0, 1);
- }
- else could_continue = partial_newline = TRUE;
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_DOLLM:
- if ((mb->moptions & PCRE2_NOTEOL) == 0)
- {
- if (clen == 0 && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)
- could_continue = TRUE;
- else if (clen == 0 ||
- ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr)))
- { ADD_ACTIVE(state_offset + 1, 0); }
- else if (ptr + 1 >= mb->end_subject &&
- (mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0 &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- c == NLBLOCK->nl[0])
- {
- if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)
- {
- reset_could_continue = TRUE;
- ADD_NEW_DATA(-(state_offset + 1), 0, 1);
- }
- else could_continue = partial_newline = TRUE;
- }
- }
- else if (IS_NEWLINE(ptr))
- { ADD_ACTIVE(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
-
- case OP_DIGIT:
- case OP_WHITESPACE:
- case OP_WORDCHAR:
- if (clen > 0 && c < 256 &&
- ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0)
- { ADD_NEW(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_NOT_DIGIT:
- case OP_NOT_WHITESPACE:
- case OP_NOT_WORDCHAR:
- if (clen > 0 && (c >= 256 ||
- ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0))
- { ADD_NEW(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_WORD_BOUNDARY:
- case OP_NOT_WORD_BOUNDARY:
- {
- int left_word, right_word;
-
- if (ptr > start_subject)
- {
- PCRE2_SPTR temp = ptr - 1;
- if (temp < mb->start_used_ptr) mb->start_used_ptr = temp;
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (utf) { BACKCHAR(temp); }
-#endif
- GETCHARTEST(d, temp);
-#ifdef SUPPORT_UNICODE
- if ((mb->poptions & PCRE2_UCP) != 0)
- {
- if (d == '_') left_word = TRUE; else
- {
- uint32_t cat = UCD_CATEGORY(d);
- left_word = (cat == ucp_L || cat == ucp_N);
- }
- }
- else
-#endif
- left_word = d < 256 && (ctypes[d] & ctype_word) != 0;
- }
- else left_word = FALSE;
-
- if (clen > 0)
- {
- if (ptr >= mb->last_used_ptr)
- {
- PCRE2_SPTR temp = ptr + 1;
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (utf) { FORWARDCHARTEST(temp, mb->end_subject); }
-#endif
- mb->last_used_ptr = temp;
- }
-#ifdef SUPPORT_UNICODE
- if ((mb->poptions & PCRE2_UCP) != 0)
- {
- if (c == '_') right_word = TRUE; else
- {
- uint32_t cat = UCD_CATEGORY(c);
- right_word = (cat == ucp_L || cat == ucp_N);
- }
- }
- else
-#endif
- right_word = c < 256 && (ctypes[c] & ctype_word) != 0;
- }
- else right_word = FALSE;
-
- if ((left_word == right_word) == (codevalue == OP_NOT_WORD_BOUNDARY))
- { ADD_ACTIVE(state_offset + 1, 0); }
- }
- break;
-
-
- /*-----------------------------------------------------------------*/
- /* Check the next character by Unicode property. We will get here only
- if the support is in the binary; otherwise a compile-time error occurs.
- */
-
-#ifdef SUPPORT_UNICODE
- case OP_PROP:
- case OP_NOTPROP:
- if (clen > 0)
- {
- BOOL OK;
- const uint32_t *cp;
- const ucd_record * prop = GET_UCD(c);
- switch(code[1])
- {
- case PT_ANY:
- OK = TRUE;
- break;
-
- case PT_LAMP:
- OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
- prop->chartype == ucp_Lt;
- break;
-
- case PT_GC:
- OK = PRIV(ucp_gentype)[prop->chartype] == code[2];
- break;
-
- case PT_PC:
- OK = prop->chartype == code[2];
- break;
-
- case PT_SC:
- OK = prop->script == code[2];
- break;
-
- case PT_SCX:
- OK = (prop->script == code[2] ||
- MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), code[2]) != 0);
- break;
-
- /* These are specials for combination cases. */
-
- case PT_ALNUM:
- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N;
- break;
-
- /* Perl space used to exclude VT, but from Perl 5.18 it is included,
- which means that Perl space and POSIX space are now identical. PCRE
- was changed at release 8.34. */
-
- case PT_SPACE: /* Perl space */
- case PT_PXSPACE: /* POSIX space */
- switch(c)
- {
- HSPACE_CASES:
- VSPACE_CASES:
- OK = TRUE;
- break;
-
- default:
- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
- break;
- }
- break;
-
- case PT_WORD:
- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
- c == CHAR_UNDERSCORE;
- break;
-
- case PT_CLIST:
- cp = PRIV(ucd_caseless_sets) + code[2];
- for (;;)
- {
- if (c < *cp) { OK = FALSE; break; }
- if (c == *cp++) { OK = TRUE; break; }
- }
- break;
-
- case PT_UCNC:
- OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
- c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
- c >= 0xe000;
- break;
-
- case PT_BIDICL:
- OK = UCD_BIDICLASS(c) == code[2];
- break;
-
- case PT_BOOL:
- OK = MAPBIT(PRIV(ucd_boolprop_sets) +
- UCD_BPROPS_PROP(prop), code[2]) != 0;
- break;
-
- /* Should never occur, but keep compilers from grumbling. */
-
- default:
- OK = codevalue != OP_PROP;
- break;
- }
-
- if (OK == (codevalue == OP_PROP)) { ADD_NEW(state_offset + 3, 0); }
- }
- break;
-#endif
-
-
-
-/* ========================================================================== */
- /* These opcodes likewise inspect the subject character, but have an
- argument that is not a data character. It is one of these opcodes:
- OP_ANY, OP_ALLANY, OP_DIGIT, OP_NOT_DIGIT, OP_WHITESPACE, OP_NOT_SPACE,
- OP_WORDCHAR, OP_NOT_WORDCHAR. The value is loaded into d. */
-
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEPOSPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
- if (clen > 0)
- {
- if (d == OP_ANY && ptr + 1 >= mb->end_subject &&
- (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- c == NLBLOCK->nl[0])
- {
- could_continue = partial_newline = TRUE;
- }
- else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
- (c < 256 &&
- (d != OP_ANY || !IS_NEWLINE(ptr)) &&
- ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
- {
- if (count > 0 && codevalue == OP_TYPEPOSPLUS)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- count++;
- ADD_NEW(state_offset, count);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSQUERY:
- ADD_ACTIVE(state_offset + 2, 0);
- if (clen > 0)
- {
- if (d == OP_ANY && ptr + 1 >= mb->end_subject &&
- (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- c == NLBLOCK->nl[0])
- {
- could_continue = partial_newline = TRUE;
- }
- else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
- (c < 256 &&
- (d != OP_ANY || !IS_NEWLINE(ptr)) &&
- ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
- {
- if (codevalue == OP_TYPEPOSQUERY)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW(state_offset + 2, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPOSSTAR:
- ADD_ACTIVE(state_offset + 2, 0);
- if (clen > 0)
- {
- if (d == OP_ANY && ptr + 1 >= mb->end_subject &&
- (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- c == NLBLOCK->nl[0])
- {
- could_continue = partial_newline = TRUE;
- }
- else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
- (c < 256 &&
- (d != OP_ANY || !IS_NEWLINE(ptr)) &&
- ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
- {
- if (codevalue == OP_TYPEPOSSTAR)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW(state_offset, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_TYPEEXACT:
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- if (d == OP_ANY && ptr + 1 >= mb->end_subject &&
- (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- c == NLBLOCK->nl[0])
- {
- could_continue = partial_newline = TRUE;
- }
- else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
- (c < 256 &&
- (d != OP_ANY || !IS_NEWLINE(ptr)) &&
- ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
- {
- if (++count >= (int)GET2(code, 1))
- { ADD_NEW(state_offset + 1 + IMM2_SIZE + 1, 0); }
- else
- { ADD_NEW(state_offset, count); }
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEPOSUPTO:
- ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0);
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- if (d == OP_ANY && ptr + 1 >= mb->end_subject &&
- (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- c == NLBLOCK->nl[0])
- {
- could_continue = partial_newline = TRUE;
- }
- else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
- (c < 256 &&
- (d != OP_ANY || !IS_NEWLINE(ptr)) &&
- ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
- {
- if (codevalue == OP_TYPEPOSUPTO)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- if (++count >= (int)GET2(code, 1))
- { ADD_NEW(state_offset + 2 + IMM2_SIZE, 0); }
- else
- { ADD_NEW(state_offset, count); }
- }
- }
- break;
-
-/* ========================================================================== */
- /* These are virtual opcodes that are used when something like
- OP_TYPEPLUS has OP_PROP, OP_NOTPROP, OP_ANYNL, or OP_EXTUNI as its
- argument. It keeps the code above fast for the other cases. The argument
- is in the d variable. */
-
-#ifdef SUPPORT_UNICODE
- case OP_PROP_EXTRA + OP_TYPEPLUS:
- case OP_PROP_EXTRA + OP_TYPEMINPLUS:
- case OP_PROP_EXTRA + OP_TYPEPOSPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(state_offset + 4, 0); }
- if (clen > 0)
- {
- BOOL OK;
- const uint32_t *cp;
- const ucd_record * prop = GET_UCD(c);
- switch(code[2])
- {
- case PT_ANY:
- OK = TRUE;
- break;
-
- case PT_LAMP:
- OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
- prop->chartype == ucp_Lt;
- break;
-
- case PT_GC:
- OK = PRIV(ucp_gentype)[prop->chartype] == code[3];
- break;
-
- case PT_PC:
- OK = prop->chartype == code[3];
- break;
-
- case PT_SC:
- OK = prop->script == code[3];
- break;
-
- case PT_SCX:
- OK = (prop->script == code[3] ||
- MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), code[3]) != 0);
- break;
-
- /* These are specials for combination cases. */
-
- case PT_ALNUM:
- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N;
- break;
-
- /* Perl space used to exclude VT, but from Perl 5.18 it is included,
- which means that Perl space and POSIX space are now identical. PCRE
- was changed at release 8.34. */
-
- case PT_SPACE: /* Perl space */
- case PT_PXSPACE: /* POSIX space */
- switch(c)
- {
- HSPACE_CASES:
- VSPACE_CASES:
- OK = TRUE;
- break;
-
- default:
- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
- break;
- }
- break;
-
- case PT_WORD:
- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
- c == CHAR_UNDERSCORE;
- break;
-
- case PT_CLIST:
- cp = PRIV(ucd_caseless_sets) + code[3];
- for (;;)
- {
- if (c < *cp) { OK = FALSE; break; }
- if (c == *cp++) { OK = TRUE; break; }
- }
- break;
-
- case PT_UCNC:
- OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
- c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
- c >= 0xe000;
- break;
-
- case PT_BIDICL:
- OK = UCD_BIDICLASS(c) == code[3];
- break;
-
- case PT_BOOL:
- OK = MAPBIT(PRIV(ucd_boolprop_sets) +
- UCD_BPROPS_PROP(prop), code[3]) != 0;
- break;
-
- /* Should never occur, but keep compilers from grumbling. */
-
- default:
- OK = codevalue != OP_PROP;
- break;
- }
-
- if (OK == (d == OP_PROP))
- {
- if (count > 0 && codevalue == OP_PROP_EXTRA + OP_TYPEPOSPLUS)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- count++;
- ADD_NEW(state_offset, count);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_EXTUNI_EXTRA + OP_TYPEPLUS:
- case OP_EXTUNI_EXTRA + OP_TYPEMINPLUS:
- case OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
- if (clen > 0)
- {
- int ncount = 0;
- if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- (void)PRIV(extuni)(c, ptr + clen, mb->start_subject, end_subject, utf,
- &ncount);
- count++;
- ADD_NEW_DATA(-state_offset, count, ncount);
- }
- break;
-#endif
-
- /*-----------------------------------------------------------------*/
- case OP_ANYNL_EXTRA + OP_TYPEPLUS:
- case OP_ANYNL_EXTRA + OP_TYPEMINPLUS:
- case OP_ANYNL_EXTRA + OP_TYPEPOSPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
- if (clen > 0)
- {
- int ncount = 0;
- switch (c)
- {
- case CHAR_VT:
- case CHAR_FF:
- case CHAR_NEL:
-#ifndef EBCDIC
- case 0x2028:
- case 0x2029:
-#endif /* Not EBCDIC */
- if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break;
- goto ANYNL01;
-
- case CHAR_CR:
- if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1;
- /* Fall through */
-
- ANYNL01:
- case CHAR_LF:
- if (count > 0 && codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSPLUS)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- count++;
- ADD_NEW_DATA(-state_offset, count, ncount);
- break;
-
- default:
- break;
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_VSPACE_EXTRA + OP_TYPEPLUS:
- case OP_VSPACE_EXTRA + OP_TYPEMINPLUS:
- case OP_VSPACE_EXTRA + OP_TYPEPOSPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
- if (clen > 0)
- {
- BOOL OK;
- switch (c)
- {
- VSPACE_CASES:
- OK = TRUE;
- break;
-
- default:
- OK = FALSE;
- break;
- }
-
- if (OK == (d == OP_VSPACE))
- {
- if (count > 0 && codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSPLUS)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- count++;
- ADD_NEW_DATA(-state_offset, count, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_HSPACE_EXTRA + OP_TYPEPLUS:
- case OP_HSPACE_EXTRA + OP_TYPEMINPLUS:
- case OP_HSPACE_EXTRA + OP_TYPEPOSPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
- if (clen > 0)
- {
- BOOL OK;
- switch (c)
- {
- HSPACE_CASES:
- OK = TRUE;
- break;
-
- default:
- OK = FALSE;
- break;
- }
-
- if (OK == (d == OP_HSPACE))
- {
- if (count > 0 && codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSPLUS)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- count++;
- ADD_NEW_DATA(-state_offset, count, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
-#ifdef SUPPORT_UNICODE
- case OP_PROP_EXTRA + OP_TYPEQUERY:
- case OP_PROP_EXTRA + OP_TYPEMINQUERY:
- case OP_PROP_EXTRA + OP_TYPEPOSQUERY:
- count = 4;
- goto QS1;
-
- case OP_PROP_EXTRA + OP_TYPESTAR:
- case OP_PROP_EXTRA + OP_TYPEMINSTAR:
- case OP_PROP_EXTRA + OP_TYPEPOSSTAR:
- count = 0;
-
- QS1:
-
- ADD_ACTIVE(state_offset + 4, 0);
- if (clen > 0)
- {
- BOOL OK;
- const uint32_t *cp;
- const ucd_record * prop = GET_UCD(c);
- switch(code[2])
- {
- case PT_ANY:
- OK = TRUE;
- break;
-
- case PT_LAMP:
- OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
- prop->chartype == ucp_Lt;
- break;
-
- case PT_GC:
- OK = PRIV(ucp_gentype)[prop->chartype] == code[3];
- break;
-
- case PT_PC:
- OK = prop->chartype == code[3];
- break;
-
- case PT_SC:
- OK = prop->script == code[3];
- break;
-
- case PT_SCX:
- OK = (prop->script == code[3] ||
- MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), code[3]) != 0);
- break;
-
- /* These are specials for combination cases. */
-
- case PT_ALNUM:
- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N;
- break;
-
- /* Perl space used to exclude VT, but from Perl 5.18 it is included,
- which means that Perl space and POSIX space are now identical. PCRE
- was changed at release 8.34. */
-
- case PT_SPACE: /* Perl space */
- case PT_PXSPACE: /* POSIX space */
- switch(c)
- {
- HSPACE_CASES:
- VSPACE_CASES:
- OK = TRUE;
- break;
-
- default:
- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
- break;
- }
- break;
-
- case PT_WORD:
- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
- c == CHAR_UNDERSCORE;
- break;
-
- case PT_CLIST:
- cp = PRIV(ucd_caseless_sets) + code[3];
- for (;;)
- {
- if (c < *cp) { OK = FALSE; break; }
- if (c == *cp++) { OK = TRUE; break; }
- }
- break;
-
- case PT_UCNC:
- OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
- c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
- c >= 0xe000;
- break;
-
- case PT_BIDICL:
- OK = UCD_BIDICLASS(c) == code[3];
- break;
-
- case PT_BOOL:
- OK = MAPBIT(PRIV(ucd_boolprop_sets) +
- UCD_BPROPS_PROP(prop), code[3]) != 0;
- break;
-
- /* Should never occur, but keep compilers from grumbling. */
-
- default:
- OK = codevalue != OP_PROP;
- break;
- }
-
- if (OK == (d == OP_PROP))
- {
- if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSSTAR ||
- codevalue == OP_PROP_EXTRA + OP_TYPEPOSQUERY)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW(state_offset + count, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_EXTUNI_EXTRA + OP_TYPEQUERY:
- case OP_EXTUNI_EXTRA + OP_TYPEMINQUERY:
- case OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY:
- count = 2;
- goto QS2;
-
- case OP_EXTUNI_EXTRA + OP_TYPESTAR:
- case OP_EXTUNI_EXTRA + OP_TYPEMINSTAR:
- case OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR:
- count = 0;
-
- QS2:
-
- ADD_ACTIVE(state_offset + 2, 0);
- if (clen > 0)
- {
- int ncount = 0;
- if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR ||
- codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- (void)PRIV(extuni)(c, ptr + clen, mb->start_subject, end_subject, utf,
- &ncount);
- ADD_NEW_DATA(-(state_offset + count), 0, ncount);
- }
- break;
-#endif
-
- /*-----------------------------------------------------------------*/
- case OP_ANYNL_EXTRA + OP_TYPEQUERY:
- case OP_ANYNL_EXTRA + OP_TYPEMINQUERY:
- case OP_ANYNL_EXTRA + OP_TYPEPOSQUERY:
- count = 2;
- goto QS3;
-
- case OP_ANYNL_EXTRA + OP_TYPESTAR:
- case OP_ANYNL_EXTRA + OP_TYPEMINSTAR:
- case OP_ANYNL_EXTRA + OP_TYPEPOSSTAR:
- count = 0;
-
- QS3:
- ADD_ACTIVE(state_offset + 2, 0);
- if (clen > 0)
- {
- int ncount = 0;
- switch (c)
- {
- case CHAR_VT:
- case CHAR_FF:
- case CHAR_NEL:
-#ifndef EBCDIC
- case 0x2028:
- case 0x2029:
-#endif /* Not EBCDIC */
- if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break;
- goto ANYNL02;
-
- case CHAR_CR:
- if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1;
- /* Fall through */
-
- ANYNL02:
- case CHAR_LF:
- if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSSTAR ||
- codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSQUERY)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW_DATA(-(state_offset + (int)count), 0, ncount);
- break;
-
- default:
- break;
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_VSPACE_EXTRA + OP_TYPEQUERY:
- case OP_VSPACE_EXTRA + OP_TYPEMINQUERY:
- case OP_VSPACE_EXTRA + OP_TYPEPOSQUERY:
- count = 2;
- goto QS4;
-
- case OP_VSPACE_EXTRA + OP_TYPESTAR:
- case OP_VSPACE_EXTRA + OP_TYPEMINSTAR:
- case OP_VSPACE_EXTRA + OP_TYPEPOSSTAR:
- count = 0;
-
- QS4:
- ADD_ACTIVE(state_offset + 2, 0);
- if (clen > 0)
- {
- BOOL OK;
- switch (c)
- {
- VSPACE_CASES:
- OK = TRUE;
- break;
-
- default:
- OK = FALSE;
- break;
- }
- if (OK == (d == OP_VSPACE))
- {
- if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSSTAR ||
- codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSQUERY)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW_DATA(-(state_offset + (int)count), 0, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_HSPACE_EXTRA + OP_TYPEQUERY:
- case OP_HSPACE_EXTRA + OP_TYPEMINQUERY:
- case OP_HSPACE_EXTRA + OP_TYPEPOSQUERY:
- count = 2;
- goto QS5;
-
- case OP_HSPACE_EXTRA + OP_TYPESTAR:
- case OP_HSPACE_EXTRA + OP_TYPEMINSTAR:
- case OP_HSPACE_EXTRA + OP_TYPEPOSSTAR:
- count = 0;
-
- QS5:
- ADD_ACTIVE(state_offset + 2, 0);
- if (clen > 0)
- {
- BOOL OK;
- switch (c)
- {
- HSPACE_CASES:
- OK = TRUE;
- break;
-
- default:
- OK = FALSE;
- break;
- }
-
- if (OK == (d == OP_HSPACE))
- {
- if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSSTAR ||
- codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSQUERY)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW_DATA(-(state_offset + (int)count), 0, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
-#ifdef SUPPORT_UNICODE
- case OP_PROP_EXTRA + OP_TYPEEXACT:
- case OP_PROP_EXTRA + OP_TYPEUPTO:
- case OP_PROP_EXTRA + OP_TYPEMINUPTO:
- case OP_PROP_EXTRA + OP_TYPEPOSUPTO:
- if (codevalue != OP_PROP_EXTRA + OP_TYPEEXACT)
- { ADD_ACTIVE(state_offset + 1 + IMM2_SIZE + 3, 0); }
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- BOOL OK;
- const uint32_t *cp;
- const ucd_record * prop = GET_UCD(c);
- switch(code[1 + IMM2_SIZE + 1])
- {
- case PT_ANY:
- OK = TRUE;
- break;
-
- case PT_LAMP:
- OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
- prop->chartype == ucp_Lt;
- break;
-
- case PT_GC:
- OK = PRIV(ucp_gentype)[prop->chartype] == code[1 + IMM2_SIZE + 2];
- break;
-
- case PT_PC:
- OK = prop->chartype == code[1 + IMM2_SIZE + 2];
- break;
-
- case PT_SC:
- OK = prop->script == code[1 + IMM2_SIZE + 2];
- break;
-
- case PT_SCX:
- OK = (prop->script == code[1 + IMM2_SIZE + 2] ||
- MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop),
- code[1 + IMM2_SIZE + 2]) != 0);
- break;
-
- /* These are specials for combination cases. */
-
- case PT_ALNUM:
- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N;
- break;
-
- /* Perl space used to exclude VT, but from Perl 5.18 it is included,
- which means that Perl space and POSIX space are now identical. PCRE
- was changed at release 8.34. */
-
- case PT_SPACE: /* Perl space */
- case PT_PXSPACE: /* POSIX space */
- switch(c)
- {
- HSPACE_CASES:
- VSPACE_CASES:
- OK = TRUE;
- break;
-
- default:
- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
- break;
- }
- break;
-
- case PT_WORD:
- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
- c == CHAR_UNDERSCORE;
- break;
-
- case PT_CLIST:
- cp = PRIV(ucd_caseless_sets) + code[1 + IMM2_SIZE + 2];
- for (;;)
- {
- if (c < *cp) { OK = FALSE; break; }
- if (c == *cp++) { OK = TRUE; break; }
- }
- break;
-
- case PT_UCNC:
- OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
- c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
- c >= 0xe000;
- break;
-
- case PT_BIDICL:
- OK = UCD_BIDICLASS(c) == code[1 + IMM2_SIZE + 2];
- break;
-
- case PT_BOOL:
- OK = MAPBIT(PRIV(ucd_boolprop_sets) +
- UCD_BPROPS_PROP(prop), code[1 + IMM2_SIZE + 2]) != 0;
- break;
-
- /* Should never occur, but keep compilers from grumbling. */
-
- default:
- OK = codevalue != OP_PROP;
- break;
- }
-
- if (OK == (d == OP_PROP))
- {
- if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSUPTO)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- if (++count >= (int)GET2(code, 1))
- { ADD_NEW(state_offset + 1 + IMM2_SIZE + 3, 0); }
- else
- { ADD_NEW(state_offset, count); }
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_EXTUNI_EXTRA + OP_TYPEEXACT:
- case OP_EXTUNI_EXTRA + OP_TYPEUPTO:
- case OP_EXTUNI_EXTRA + OP_TYPEMINUPTO:
- case OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO:
- if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT)
- { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- PCRE2_SPTR nptr;
- int ncount = 0;
- if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- nptr = PRIV(extuni)(c, ptr + clen, mb->start_subject, end_subject, utf,
- &ncount);
- if (nptr >= end_subject && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)
- reset_could_continue = TRUE;
- if (++count >= (int)GET2(code, 1))
- { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }
- else
- { ADD_NEW_DATA(-state_offset, count, ncount); }
- }
- break;
-#endif
-
- /*-----------------------------------------------------------------*/
- case OP_ANYNL_EXTRA + OP_TYPEEXACT:
- case OP_ANYNL_EXTRA + OP_TYPEUPTO:
- case OP_ANYNL_EXTRA + OP_TYPEMINUPTO:
- case OP_ANYNL_EXTRA + OP_TYPEPOSUPTO:
- if (codevalue != OP_ANYNL_EXTRA + OP_TYPEEXACT)
- { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- int ncount = 0;
- switch (c)
- {
- case CHAR_VT:
- case CHAR_FF:
- case CHAR_NEL:
-#ifndef EBCDIC
- case 0x2028:
- case 0x2029:
-#endif /* Not EBCDIC */
- if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break;
- goto ANYNL03;
-
- case CHAR_CR:
- if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1;
- /* Fall through */
-
- ANYNL03:
- case CHAR_LF:
- if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSUPTO)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- if (++count >= (int)GET2(code, 1))
- { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }
- else
- { ADD_NEW_DATA(-state_offset, count, ncount); }
- break;
-
- default:
- break;
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_VSPACE_EXTRA + OP_TYPEEXACT:
- case OP_VSPACE_EXTRA + OP_TYPEUPTO:
- case OP_VSPACE_EXTRA + OP_TYPEMINUPTO:
- case OP_VSPACE_EXTRA + OP_TYPEPOSUPTO:
- if (codevalue != OP_VSPACE_EXTRA + OP_TYPEEXACT)
- { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- BOOL OK;
- switch (c)
- {
- VSPACE_CASES:
- OK = TRUE;
- break;
-
- default:
- OK = FALSE;
- }
-
- if (OK == (d == OP_VSPACE))
- {
- if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSUPTO)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- if (++count >= (int)GET2(code, 1))
- { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }
- else
- { ADD_NEW_DATA(-state_offset, count, 0); }
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_HSPACE_EXTRA + OP_TYPEEXACT:
- case OP_HSPACE_EXTRA + OP_TYPEUPTO:
- case OP_HSPACE_EXTRA + OP_TYPEMINUPTO:
- case OP_HSPACE_EXTRA + OP_TYPEPOSUPTO:
- if (codevalue != OP_HSPACE_EXTRA + OP_TYPEEXACT)
- { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- BOOL OK;
- switch (c)
- {
- HSPACE_CASES:
- OK = TRUE;
- break;
-
- default:
- OK = FALSE;
- break;
- }
-
- if (OK == (d == OP_HSPACE))
- {
- if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSUPTO)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- if (++count >= (int)GET2(code, 1))
- { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }
- else
- { ADD_NEW_DATA(-state_offset, count, 0); }
- }
- }
- break;
-
-/* ========================================================================== */
- /* These opcodes are followed by a character that is usually compared
- to the current subject character; it is loaded into d. We still get
- here even if there is no subject character, because in some cases zero
- repetitions are permitted. */
-
- /*-----------------------------------------------------------------*/
- case OP_CHAR:
- if (clen > 0 && c == d) { ADD_NEW(state_offset + dlen + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_CHARI:
- if (clen == 0) break;
-
-#ifdef SUPPORT_UNICODE
- if (utf_or_ucp)
- {
- if (c == d) { ADD_NEW(state_offset + dlen + 1, 0); } else
- {
- unsigned int othercase;
- if (c < 128)
- othercase = fcc[c];
- else
- othercase = UCD_OTHERCASE(c);
- if (d == othercase) { ADD_NEW(state_offset + dlen + 1, 0); }
- }
- }
- else
-#endif /* SUPPORT_UNICODE */
- /* Not UTF or UCP mode */
- {
- if (TABLE_GET(c, lcc, c) == TABLE_GET(d, lcc, d))
- { ADD_NEW(state_offset + 2, 0); }
- }
- break;
-
-
-#ifdef SUPPORT_UNICODE
- /*-----------------------------------------------------------------*/
- /* This is a tricky one because it can match more than one character.
- Find out how many characters to skip, and then set up a negative state
- to wait for them to pass before continuing. */
-
- case OP_EXTUNI:
- if (clen > 0)
- {
- int ncount = 0;
- PCRE2_SPTR nptr = PRIV(extuni)(c, ptr + clen, mb->start_subject,
- end_subject, utf, &ncount);
- if (nptr >= end_subject && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)
- reset_could_continue = TRUE;
- ADD_NEW_DATA(-(state_offset + 1), 0, ncount);
- }
- break;
-#endif
-
- /*-----------------------------------------------------------------*/
- /* This is a tricky like EXTUNI because it too can match more than one
- character (when CR is followed by LF). In this case, set up a negative
- state to wait for one character to pass before continuing. */
-
- case OP_ANYNL:
- if (clen > 0) switch(c)
- {
- case CHAR_VT:
- case CHAR_FF:
- case CHAR_NEL:
-#ifndef EBCDIC
- case 0x2028:
- case 0x2029:
-#endif /* Not EBCDIC */
- if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break;
- /* Fall through */
-
- case CHAR_LF:
- ADD_NEW(state_offset + 1, 0);
- break;
-
- case CHAR_CR:
- if (ptr + 1 >= end_subject)
- {
- ADD_NEW(state_offset + 1, 0);
- if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)
- reset_could_continue = TRUE;
- }
- else if (UCHAR21TEST(ptr + 1) == CHAR_LF)
- {
- ADD_NEW_DATA(-(state_offset + 1), 0, 1);
- }
- else
- {
- ADD_NEW(state_offset + 1, 0);
- }
- break;
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_NOT_VSPACE:
- if (clen > 0) switch(c)
- {
- VSPACE_CASES:
- break;
-
- default:
- ADD_NEW(state_offset + 1, 0);
- break;
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_VSPACE:
- if (clen > 0) switch(c)
- {
- VSPACE_CASES:
- ADD_NEW(state_offset + 1, 0);
- break;
-
- default:
- break;
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_NOT_HSPACE:
- if (clen > 0) switch(c)
- {
- HSPACE_CASES:
- break;
-
- default:
- ADD_NEW(state_offset + 1, 0);
- break;
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_HSPACE:
- if (clen > 0) switch(c)
- {
- HSPACE_CASES:
- ADD_NEW(state_offset + 1, 0);
- break;
-
- default:
- break;
- }
- break;
-
- /*-----------------------------------------------------------------*/
- /* Match a negated single character casefully. */
-
- case OP_NOT:
- if (clen > 0 && c != d) { ADD_NEW(state_offset + dlen + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- /* Match a negated single character caselessly. */
-
- case OP_NOTI:
- if (clen > 0)
- {
- uint32_t otherd;
-#ifdef SUPPORT_UNICODE
- if (utf_or_ucp && d >= 128)
- otherd = UCD_OTHERCASE(d);
- else
-#endif /* SUPPORT_UNICODE */
- otherd = TABLE_GET(d, fcc, d);
- if (c != d && c != otherd)
- { ADD_NEW(state_offset + dlen + 1, 0); }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_PLUSI:
- case OP_MINPLUSI:
- case OP_POSPLUSI:
- case OP_NOTPLUSI:
- case OP_NOTMINPLUSI:
- case OP_NOTPOSPLUSI:
- caseless = TRUE;
- codevalue -= OP_STARI - OP_STAR;
-
- /* Fall through */
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_POSPLUS:
- case OP_NOTPLUS:
- case OP_NOTMINPLUS:
- case OP_NOTPOSPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); }
- if (clen > 0)
- {
- uint32_t otherd = NOTACHAR;
- if (caseless)
- {
-#ifdef SUPPORT_UNICODE
- if (utf_or_ucp && d >= 128)
- otherd = UCD_OTHERCASE(d);
- else
-#endif /* SUPPORT_UNICODE */
- otherd = TABLE_GET(d, fcc, d);
- }
- if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
- {
- if (count > 0 &&
- (codevalue == OP_POSPLUS || codevalue == OP_NOTPOSPLUS))
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- count++;
- ADD_NEW(state_offset, count);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_QUERYI:
- case OP_MINQUERYI:
- case OP_POSQUERYI:
- case OP_NOTQUERYI:
- case OP_NOTMINQUERYI:
- case OP_NOTPOSQUERYI:
- caseless = TRUE;
- codevalue -= OP_STARI - OP_STAR;
- /* Fall through */
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_POSQUERY:
- case OP_NOTQUERY:
- case OP_NOTMINQUERY:
- case OP_NOTPOSQUERY:
- ADD_ACTIVE(state_offset + dlen + 1, 0);
- if (clen > 0)
- {
- uint32_t otherd = NOTACHAR;
- if (caseless)
- {
-#ifdef SUPPORT_UNICODE
- if (utf_or_ucp && d >= 128)
- otherd = UCD_OTHERCASE(d);
- else
-#endif /* SUPPORT_UNICODE */
- otherd = TABLE_GET(d, fcc, d);
- }
- if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
- {
- if (codevalue == OP_POSQUERY || codevalue == OP_NOTPOSQUERY)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW(state_offset + dlen + 1, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_STARI:
- case OP_MINSTARI:
- case OP_POSSTARI:
- case OP_NOTSTARI:
- case OP_NOTMINSTARI:
- case OP_NOTPOSSTARI:
- caseless = TRUE;
- codevalue -= OP_STARI - OP_STAR;
- /* Fall through */
- case OP_STAR:
- case OP_MINSTAR:
- case OP_POSSTAR:
- case OP_NOTSTAR:
- case OP_NOTMINSTAR:
- case OP_NOTPOSSTAR:
- ADD_ACTIVE(state_offset + dlen + 1, 0);
- if (clen > 0)
- {
- uint32_t otherd = NOTACHAR;
- if (caseless)
- {
-#ifdef SUPPORT_UNICODE
- if (utf_or_ucp && d >= 128)
- otherd = UCD_OTHERCASE(d);
- else
-#endif /* SUPPORT_UNICODE */
- otherd = TABLE_GET(d, fcc, d);
- }
- if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
- {
- if (codevalue == OP_POSSTAR || codevalue == OP_NOTPOSSTAR)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW(state_offset, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_EXACTI:
- case OP_NOTEXACTI:
- caseless = TRUE;
- codevalue -= OP_STARI - OP_STAR;
- /* Fall through */
- case OP_EXACT:
- case OP_NOTEXACT:
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- uint32_t otherd = NOTACHAR;
- if (caseless)
- {
-#ifdef SUPPORT_UNICODE
- if (utf_or_ucp && d >= 128)
- otherd = UCD_OTHERCASE(d);
- else
-#endif /* SUPPORT_UNICODE */
- otherd = TABLE_GET(d, fcc, d);
- }
- if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
- {
- if (++count >= (int)GET2(code, 1))
- { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }
- else
- { ADD_NEW(state_offset, count); }
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_UPTOI:
- case OP_MINUPTOI:
- case OP_POSUPTOI:
- case OP_NOTUPTOI:
- case OP_NOTMINUPTOI:
- case OP_NOTPOSUPTOI:
- caseless = TRUE;
- codevalue -= OP_STARI - OP_STAR;
- /* Fall through */
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_POSUPTO:
- case OP_NOTUPTO:
- case OP_NOTMINUPTO:
- case OP_NOTPOSUPTO:
- ADD_ACTIVE(state_offset + dlen + 1 + IMM2_SIZE, 0);
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- uint32_t otherd = NOTACHAR;
- if (caseless)
- {
-#ifdef SUPPORT_UNICODE
- if (utf_or_ucp && d >= 128)
- otherd = UCD_OTHERCASE(d);
- else
-#endif /* SUPPORT_UNICODE */
- otherd = TABLE_GET(d, fcc, d);
- }
- if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
- {
- if (codevalue == OP_POSUPTO || codevalue == OP_NOTPOSUPTO)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- if (++count >= (int)GET2(code, 1))
- { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }
- else
- { ADD_NEW(state_offset, count); }
- }
- }
- break;
-
-
-/* ========================================================================== */
- /* These are the class-handling opcodes */
-
- case OP_CLASS:
- case OP_NCLASS:
- case OP_XCLASS:
- {
- BOOL isinclass = FALSE;
- int next_state_offset;
- PCRE2_SPTR ecode;
-
- /* For a simple class, there is always just a 32-byte table, and we
- can set isinclass from it. */
-
- if (codevalue != OP_XCLASS)
- {
- ecode = code + 1 + (32 / sizeof(PCRE2_UCHAR));
- if (clen > 0)
- {
- isinclass = (c > 255)? (codevalue == OP_NCLASS) :
- ((((uint8_t *)(code + 1))[c/8] & (1u << (c&7))) != 0);
- }
- }
-
- /* An extended class may have a table or a list of single characters,
- ranges, or both, and it may be positive or negative. There's a
- function that sorts all this out. */
-
- else
- {
- ecode = code + GET(code, 1);
- if (clen > 0) isinclass = PRIV(xclass)(c, code + 1 + LINK_SIZE, utf);
- }
-
- /* At this point, isinclass is set for all kinds of class, and ecode
- points to the byte after the end of the class. If there is a
- quantifier, this is where it will be. */
-
- next_state_offset = (int)(ecode - start_code);
-
- switch (*ecode)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRPOSSTAR:
- ADD_ACTIVE(next_state_offset + 1, 0);
- if (isinclass)
- {
- if (*ecode == OP_CRPOSSTAR)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW(state_offset, 0);
- }
- break;
-
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRPOSPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(next_state_offset + 1, 0); }
- if (isinclass)
- {
- if (count > 0 && *ecode == OP_CRPOSPLUS)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- count++;
- ADD_NEW(state_offset, count);
- }
- break;
-
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- case OP_CRPOSQUERY:
- ADD_ACTIVE(next_state_offset + 1, 0);
- if (isinclass)
- {
- if (*ecode == OP_CRPOSQUERY)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW(next_state_offset + 1, 0);
- }
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- case OP_CRPOSRANGE:
- count = current_state->count; /* Already matched */
- if (count >= (int)GET2(ecode, 1))
- { ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
- if (isinclass)
- {
- int max = (int)GET2(ecode, 1 + IMM2_SIZE);
-
- if (*ecode == OP_CRPOSRANGE && count >= (int)GET2(ecode, 1))
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
-
- if (++count >= max && max != 0) /* Max 0 => no limit */
- { ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
- else
- { ADD_NEW(state_offset, count); }
- }
- break;
-
- default:
- if (isinclass) { ADD_NEW(next_state_offset, 0); }
- break;
- }
- }
- break;
-
-/* ========================================================================== */
- /* These are the opcodes for fancy brackets of various kinds. We have
- to use recursion in order to handle them. The "always failing" assertion
- (?!) is optimised to OP_FAIL when compiling, so we have to support that,
- though the other "backtracking verbs" are not supported. */
-
- case OP_FAIL:
- forced_fail++; /* Count FAILs for multiple states */
- break;
-
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- {
- int rc;
- int *local_workspace;
- PCRE2_SIZE *local_offsets;
- PCRE2_SPTR endasscode = code + GET(code, 1);
- RWS_anchor *rws = (RWS_anchor *)RWS;
-
- if (rws->free < RWS_RSIZE + RWS_OVEC_OSIZE)
- {
- rc = more_workspace(&rws, RWS_OVEC_OSIZE, mb);
- if (rc != 0) return rc;
- RWS = (int *)rws;
- }
-
- local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);
- local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;
- rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;
-
- while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);
-
- rc = internal_dfa_match(
- mb, /* static match data */
- code, /* this subexpression's code */
- ptr, /* where we currently are */
- (PCRE2_SIZE)(ptr - start_subject), /* start offset */
- local_offsets, /* offset vector */
- RWS_OVEC_OSIZE/OVEC_UNIT, /* size of same */
- local_workspace, /* workspace vector */
- RWS_RSIZE, /* size of same */
- rlevel, /* function recursion level */
- RWS); /* recursion workspace */
-
- rws->free += RWS_RSIZE + RWS_OVEC_OSIZE;
-
- if (rc < 0 && rc != PCRE2_ERROR_NOMATCH) return rc;
- if ((rc >= 0) == (codevalue == OP_ASSERT || codevalue == OP_ASSERTBACK))
- { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_COND:
- case OP_SCOND:
- {
- int codelink = (int)GET(code, 1);
- PCRE2_UCHAR condcode;
-
- /* Because of the way auto-callout works during compile, a callout item
- is inserted between OP_COND and an assertion condition. This does not
- happen for the other conditions. */
-
- if (code[LINK_SIZE + 1] == OP_CALLOUT
- || code[LINK_SIZE + 1] == OP_CALLOUT_STR)
- {
- PCRE2_SIZE callout_length;
- rrc = do_callout_dfa(code, offsets, current_subject, ptr, mb,
- 1 + LINK_SIZE, &callout_length);
- if (rrc < 0) return rrc; /* Abandon */
- if (rrc > 0) break; /* Fail this thread */
- code += callout_length; /* Skip callout data */
- }
-
- condcode = code[LINK_SIZE+1];
-
- /* Back reference conditions and duplicate named recursion conditions
- are not supported */
-
- if (condcode == OP_CREF || condcode == OP_DNCREF ||
- condcode == OP_DNRREF)
- return PCRE2_ERROR_DFA_UCOND;
-
- /* The DEFINE condition is always false, and the assertion (?!) is
- converted to OP_FAIL. */
-
- if (condcode == OP_FALSE || condcode == OP_FAIL)
- { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
-
- /* There is also an always-true condition */
-
- else if (condcode == OP_TRUE)
- { ADD_ACTIVE(state_offset + LINK_SIZE + 2, 0); }
-
- /* The only supported version of OP_RREF is for the value RREF_ANY,
- which means "test if in any recursion". We can't test for specifically
- recursed groups. */
-
- else if (condcode == OP_RREF)
- {
- unsigned int value = GET2(code, LINK_SIZE + 2);
- if (value != RREF_ANY) return PCRE2_ERROR_DFA_UCOND;
- if (mb->recursive != NULL)
- { ADD_ACTIVE(state_offset + LINK_SIZE + 2 + IMM2_SIZE, 0); }
- else { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
- }
-
- /* Otherwise, the condition is an assertion */
-
- else
- {
- int rc;
- int *local_workspace;
- PCRE2_SIZE *local_offsets;
- PCRE2_SPTR asscode = code + LINK_SIZE + 1;
- PCRE2_SPTR endasscode = asscode + GET(asscode, 1);
- RWS_anchor *rws = (RWS_anchor *)RWS;
-
- if (rws->free < RWS_RSIZE + RWS_OVEC_OSIZE)
- {
- rc = more_workspace(&rws, RWS_OVEC_OSIZE, mb);
- if (rc != 0) return rc;
- RWS = (int *)rws;
- }
-
- local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);
- local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;
- rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;
-
- while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);
-
- rc = internal_dfa_match(
- mb, /* fixed match data */
- asscode, /* this subexpression's code */
- ptr, /* where we currently are */
- (PCRE2_SIZE)(ptr - start_subject), /* start offset */
- local_offsets, /* offset vector */
- RWS_OVEC_OSIZE/OVEC_UNIT, /* size of same */
- local_workspace, /* workspace vector */
- RWS_RSIZE, /* size of same */
- rlevel, /* function recursion level */
- RWS); /* recursion workspace */
-
- rws->free += RWS_RSIZE + RWS_OVEC_OSIZE;
-
- if (rc < 0 && rc != PCRE2_ERROR_NOMATCH) return rc;
- if ((rc >= 0) ==
- (condcode == OP_ASSERT || condcode == OP_ASSERTBACK))
- { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); }
- else
- { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_RECURSE:
- {
- int rc;
- int *local_workspace;
- PCRE2_SIZE *local_offsets;
- RWS_anchor *rws = (RWS_anchor *)RWS;
- dfa_recursion_info *ri;
- PCRE2_SPTR callpat = start_code + GET(code, 1);
- uint32_t recno = (callpat == mb->start_code)? 0 :
- GET2(callpat, 1 + LINK_SIZE);
-
- if (rws->free < RWS_RSIZE + RWS_OVEC_RSIZE)
- {
- rc = more_workspace(&rws, RWS_OVEC_RSIZE, mb);
- if (rc != 0) return rc;
- RWS = (int *)rws;
- }
-
- local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);
- local_workspace = ((int *)local_offsets) + RWS_OVEC_RSIZE;
- rws->free -= RWS_RSIZE + RWS_OVEC_RSIZE;
-
- /* Check for repeating a recursion without advancing the subject
- pointer. This should catch convoluted mutual recursions. (Some simple
- cases are caught at compile time.) */
-
- for (ri = mb->recursive; ri != NULL; ri = ri->prevrec)
- if (recno == ri->group_num && ptr == ri->subject_position)
- return PCRE2_ERROR_RECURSELOOP;
-
- /* Remember this recursion and where we started it so as to
- catch infinite loops. */
-
- new_recursive.group_num = recno;
- new_recursive.subject_position = ptr;
- new_recursive.prevrec = mb->recursive;
- mb->recursive = &new_recursive;
-
- rc = internal_dfa_match(
- mb, /* fixed match data */
- callpat, /* this subexpression's code */
- ptr, /* where we currently are */
- (PCRE2_SIZE)(ptr - start_subject), /* start offset */
- local_offsets, /* offset vector */
- RWS_OVEC_RSIZE/OVEC_UNIT, /* size of same */
- local_workspace, /* workspace vector */
- RWS_RSIZE, /* size of same */
- rlevel, /* function recursion level */
- RWS); /* recursion workspace */
-
- rws->free += RWS_RSIZE + RWS_OVEC_RSIZE;
- mb->recursive = new_recursive.prevrec; /* Done this recursion */
-
- /* Ran out of internal offsets */
-
- if (rc == 0) return PCRE2_ERROR_DFA_RECURSE;
-
- /* For each successful matched substring, set up the next state with a
- count of characters to skip before trying it. Note that the count is in
- characters, not bytes. */
-
- if (rc > 0)
- {
- for (rc = rc*2 - 2; rc >= 0; rc -= 2)
- {
- PCRE2_SIZE charcount = local_offsets[rc+1] - local_offsets[rc];
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (utf)
- {
- PCRE2_SPTR p = start_subject + local_offsets[rc];
- PCRE2_SPTR pp = start_subject + local_offsets[rc+1];
- while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--;
- }
-#endif
- if (charcount > 0)
- {
- ADD_NEW_DATA(-(state_offset + LINK_SIZE + 1), 0,
- (int)(charcount - 1));
- }
- else
- {
- ADD_ACTIVE(state_offset + LINK_SIZE + 1, 0);
- }
- }
- }
- else if (rc != PCRE2_ERROR_NOMATCH) return rc;
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_BRAPOS:
- case OP_SBRAPOS:
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- case OP_BRAPOSZERO:
- {
- int rc;
- int *local_workspace;
- PCRE2_SIZE *local_offsets;
- PCRE2_SIZE charcount, matched_count;
- PCRE2_SPTR local_ptr = ptr;
- RWS_anchor *rws = (RWS_anchor *)RWS;
- BOOL allow_zero;
-
- if (rws->free < RWS_RSIZE + RWS_OVEC_OSIZE)
- {
- rc = more_workspace(&rws, RWS_OVEC_OSIZE, mb);
- if (rc != 0) return rc;
- RWS = (int *)rws;
- }
-
- local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);
- local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;
- rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;
-
- if (codevalue == OP_BRAPOSZERO)
- {
- allow_zero = TRUE;
- codevalue = *(++code); /* Codevalue will be one of above BRAs */
- }
- else allow_zero = FALSE;
-
- /* Loop to match the subpattern as many times as possible as if it were
- a complete pattern. */
-
- for (matched_count = 0;; matched_count++)
- {
- rc = internal_dfa_match(
- mb, /* fixed match data */
- code, /* this subexpression's code */
- local_ptr, /* where we currently are */
- (PCRE2_SIZE)(ptr - start_subject), /* start offset */
- local_offsets, /* offset vector */
- RWS_OVEC_OSIZE/OVEC_UNIT, /* size of same */
- local_workspace, /* workspace vector */
- RWS_RSIZE, /* size of same */
- rlevel, /* function recursion level */
- RWS); /* recursion workspace */
-
- /* Failed to match */
-
- if (rc < 0)
- {
- if (rc != PCRE2_ERROR_NOMATCH) return rc;
- break;
- }
-
- /* Matched: break the loop if zero characters matched. */
-
- charcount = local_offsets[1] - local_offsets[0];
- if (charcount == 0) break;
- local_ptr += charcount; /* Advance temporary position ptr */
- }
-
- rws->free += RWS_RSIZE + RWS_OVEC_OSIZE;
-
- /* At this point we have matched the subpattern matched_count
- times, and local_ptr is pointing to the character after the end of the
- last match. */
-
- if (matched_count > 0 || allow_zero)
- {
- PCRE2_SPTR end_subpattern = code;
- int next_state_offset;
-
- do { end_subpattern += GET(end_subpattern, 1); }
- while (*end_subpattern == OP_ALT);
- next_state_offset =
- (int)(end_subpattern - start_code + LINK_SIZE + 1);
-
- /* Optimization: if there are no more active states, and there
- are no new states yet set up, then skip over the subject string
- right here, to save looping. Otherwise, set up the new state to swing
- into action when the end of the matched substring is reached. */
-
- if (i + 1 >= active_count && new_count == 0)
- {
- ptr = local_ptr;
- clen = 0;
- ADD_NEW(next_state_offset, 0);
- }
- else
- {
- PCRE2_SPTR p = ptr;
- PCRE2_SPTR pp = local_ptr;
- charcount = (PCRE2_SIZE)(pp - p);
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (utf) while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--;
-#endif
- ADD_NEW_DATA(-next_state_offset, 0, (int)(charcount - 1));
- }
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_ONCE:
- {
- int rc;
- int *local_workspace;
- PCRE2_SIZE *local_offsets;
- RWS_anchor *rws = (RWS_anchor *)RWS;
-
- if (rws->free < RWS_RSIZE + RWS_OVEC_OSIZE)
- {
- rc = more_workspace(&rws, RWS_OVEC_OSIZE, mb);
- if (rc != 0) return rc;
- RWS = (int *)rws;
- }
-
- local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);
- local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;
- rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;
-
- rc = internal_dfa_match(
- mb, /* fixed match data */
- code, /* this subexpression's code */
- ptr, /* where we currently are */
- (PCRE2_SIZE)(ptr - start_subject), /* start offset */
- local_offsets, /* offset vector */
- RWS_OVEC_OSIZE/OVEC_UNIT, /* size of same */
- local_workspace, /* workspace vector */
- RWS_RSIZE, /* size of same */
- rlevel, /* function recursion level */
- RWS); /* recursion workspace */
-
- rws->free += RWS_RSIZE + RWS_OVEC_OSIZE;
-
- if (rc >= 0)
- {
- PCRE2_SPTR end_subpattern = code;
- PCRE2_SIZE charcount = local_offsets[1] - local_offsets[0];
- int next_state_offset, repeat_state_offset;
-
- do { end_subpattern += GET(end_subpattern, 1); }
- while (*end_subpattern == OP_ALT);
- next_state_offset =
- (int)(end_subpattern - start_code + LINK_SIZE + 1);
-
- /* If the end of this subpattern is KETRMAX or KETRMIN, we must
- arrange for the repeat state also to be added to the relevant list.
- Calculate the offset, or set -1 for no repeat. */
-
- repeat_state_offset = (*end_subpattern == OP_KETRMAX ||
- *end_subpattern == OP_KETRMIN)?
- (int)(end_subpattern - start_code - GET(end_subpattern, 1)) : -1;
-
- /* If we have matched an empty string, add the next state at the
- current character pointer. This is important so that the duplicate
- checking kicks in, which is what breaks infinite loops that match an
- empty string. */
-
- if (charcount == 0)
- {
- ADD_ACTIVE(next_state_offset, 0);
- }
-
- /* Optimization: if there are no more active states, and there
- are no new states yet set up, then skip over the subject string
- right here, to save looping. Otherwise, set up the new state to swing
- into action when the end of the matched substring is reached. */
-
- else if (i + 1 >= active_count && new_count == 0)
- {
- ptr += charcount;
- clen = 0;
- ADD_NEW(next_state_offset, 0);
-
- /* If we are adding a repeat state at the new character position,
- we must fudge things so that it is the only current state.
- Otherwise, it might be a duplicate of one we processed before, and
- that would cause it to be skipped. */
-
- if (repeat_state_offset >= 0)
- {
- next_active_state = active_states;
- active_count = 0;
- i = -1;
- ADD_ACTIVE(repeat_state_offset, 0);
- }
- }
- else
- {
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (utf)
- {
- PCRE2_SPTR p = start_subject + local_offsets[0];
- PCRE2_SPTR pp = start_subject + local_offsets[1];
- while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--;
- }
-#endif
- ADD_NEW_DATA(-next_state_offset, 0, (int)(charcount - 1));
- if (repeat_state_offset >= 0)
- { ADD_NEW_DATA(-repeat_state_offset, 0, (int)(charcount - 1)); }
- }
- }
- else if (rc != PCRE2_ERROR_NOMATCH) return rc;
- }
- break;
-
-
-/* ========================================================================== */
- /* Handle callouts */
-
- case OP_CALLOUT:
- case OP_CALLOUT_STR:
- {
- PCRE2_SIZE callout_length;
- rrc = do_callout_dfa(code, offsets, current_subject, ptr, mb, 0,
- &callout_length);
- if (rrc < 0) return rrc; /* Abandon */
- if (rrc == 0)
- { ADD_ACTIVE(state_offset + (int)callout_length, 0); }
- }
- break;
-
-
-/* ========================================================================== */
- default: /* Unsupported opcode */
- return PCRE2_ERROR_DFA_UITEM;
- }
-
- NEXT_ACTIVE_STATE: continue;
-
- } /* End of loop scanning active states */
-
- /* We have finished the processing at the current subject character. If no
- new states have been set for the next character, we have found all the
- matches that we are going to find. If partial matching has been requested,
- check for appropriate conditions.
-
- The "forced_ fail" variable counts the number of (*F) encountered for the
- character. If it is equal to the original active_count (saved in
- workspace[1]) it means that (*F) was found on every active state. In this
- case we don't want to give a partial match.
-
- The "could_continue" variable is true if a state could have continued but
- for the fact that the end of the subject was reached. */
-
- if (new_count <= 0)
- {
- if (could_continue && /* Some could go on, and */
- forced_fail != workspace[1] && /* Not all forced fail & */
- ( /* either... */
- (mb->moptions & PCRE2_PARTIAL_HARD) != 0 /* Hard partial */
- || /* or... */
- ((mb->moptions & PCRE2_PARTIAL_SOFT) != 0 && /* Soft partial and */
- match_count < 0) /* no matches */
- ) && /* And... */
- (
- partial_newline || /* Either partial NL */
- ( /* or ... */
- ptr >= end_subject && /* End of subject and */
- ( /* either */
- ptr > mb->start_used_ptr || /* Inspected non-empty string */
- mb->allowemptypartial /* or pattern has lookbehind */
- ) /* or could match empty */
- )
- ))
- match_count = PCRE2_ERROR_PARTIAL;
- break; /* Exit from loop along the subject string */
- }
-
- /* One or more states are active for the next character. */
-
- ptr += clen; /* Advance to next subject character */
- } /* Loop to move along the subject string */
-
-/* Control gets here from "break" a few lines above. If we have a match and
-PCRE2_ENDANCHORED is set, the match fails. */
-
-if (match_count >= 0 &&
- ((mb->moptions | mb->poptions) & PCRE2_ENDANCHORED) != 0 &&
- ptr < end_subject)
- match_count = PCRE2_ERROR_NOMATCH;
-
-return match_count;
-}
-
-
-
-/*************************************************
-* Match a pattern using the DFA algorithm *
-*************************************************/
-
-/* This function matches a compiled pattern to a subject string, using the
-alternate matching algorithm that finds all matches at once.
-
-Arguments:
- code points to the compiled pattern
- subject subject string
- length length of subject string
- startoffset where to start matching in the subject
- options option bits
- match_data points to a match data structure
- gcontext points to a match context
- workspace pointer to workspace
- wscount size of workspace
-
-Returns: > 0 => number of match offset pairs placed in offsets
- = 0 => offsets overflowed; longest matches are present
- -1 => failed to match
- < -1 => some kind of unexpected problem
-*/
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_dfa_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length,
- PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data,
- pcre2_match_context *mcontext, int *workspace, PCRE2_SIZE wscount)
-{
-int rc;
-int was_zero_terminated = 0;
-
-const pcre2_real_code *re = (const pcre2_real_code *)code;
-
-PCRE2_SPTR start_match;
-PCRE2_SPTR end_subject;
-PCRE2_SPTR bumpalong_limit;
-PCRE2_SPTR req_cu_ptr;
-
-BOOL utf, anchored, startline, firstline;
-BOOL has_first_cu = FALSE;
-BOOL has_req_cu = FALSE;
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
-PCRE2_SPTR memchr_found_first_cu = NULL;
-PCRE2_SPTR memchr_found_first_cu2 = NULL;
-#endif
-
-PCRE2_UCHAR first_cu = 0;
-PCRE2_UCHAR first_cu2 = 0;
-PCRE2_UCHAR req_cu = 0;
-PCRE2_UCHAR req_cu2 = 0;
-
-const uint8_t *start_bits = NULL;
-
-/* We need to have mb pointing to a match block, because the IS_NEWLINE macro
-is used below, and it expects NLBLOCK to be defined as a pointer. */
-
-pcre2_callout_block cb;
-dfa_match_block actual_match_block;
-dfa_match_block *mb = &actual_match_block;
-
-/* Set up a starting block of memory for use during recursive calls to
-internal_dfa_match(). By putting this on the stack, it minimizes resource use
-in the case when it is not needed. If this is too small, more memory is
-obtained from the heap. At the start of each block is an anchor structure.*/
-
-int base_recursion_workspace[RWS_BASE_SIZE];
-RWS_anchor *rws = (RWS_anchor *)base_recursion_workspace;
-rws->next = NULL;
-rws->size = RWS_BASE_SIZE;
-rws->free = RWS_BASE_SIZE - RWS_ANCHOR_SIZE;
-
-/* Recognize NULL, length 0 as an empty string. */
-
-if (subject == NULL && length == 0) subject = (PCRE2_SPTR)"";
-
-/* Plausibility checks */
-
-if ((options & ~PUBLIC_DFA_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION;
-if (re == NULL || subject == NULL || workspace == NULL || match_data == NULL)
- return PCRE2_ERROR_NULL;
-
-if (length == PCRE2_ZERO_TERMINATED)
- {
- length = PRIV(strlen)(subject);
- was_zero_terminated = 1;
- }
-
-if (wscount < 20) return PCRE2_ERROR_DFA_WSSIZE;
-if (start_offset > length) return PCRE2_ERROR_BADOFFSET;
-
-/* Partial matching and PCRE2_ENDANCHORED are currently not allowed at the same
-time. */
-
-if ((options & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0 &&
- ((re->overall_options | options) & PCRE2_ENDANCHORED) != 0)
- return PCRE2_ERROR_BADOPTION;
-
-/* Invalid UTF support is not available for DFA matching. */
-
-if ((re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0)
- return PCRE2_ERROR_DFA_UINVALID_UTF;
-
-/* Check that the first field in the block is the magic number. If it is not,
-return with PCRE2_ERROR_BADMAGIC. */
-
-if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;
-
-/* Check the code unit width. */
-
-if ((re->flags & PCRE2_MODE_MASK) != PCRE2_CODE_UNIT_WIDTH/8)
- return PCRE2_ERROR_BADMODE;
-
-/* PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART are match-time flags in the
-options variable for this function. Users of PCRE2 who are not calling the
-function directly would like to have a way of setting these flags, in the same
-way that they can set pcre2_compile() flags like PCRE2_NO_AUTOPOSSESS with
-constructions like (*NO_AUTOPOSSESS). To enable this, (*NOTEMPTY) and
-(*NOTEMPTY_ATSTART) set bits in the pattern's "flag" function which can now be
-transferred to the options for this function. The bits are guaranteed to be
-adjacent, but do not have the same values. This bit of Boolean trickery assumes
-that the match-time bits are not more significant than the flag bits. If by
-accident this is not the case, a compile-time division by zero error will
-occur. */
-
-#define FF (PCRE2_NOTEMPTY_SET|PCRE2_NE_ATST_SET)
-#define OO (PCRE2_NOTEMPTY|PCRE2_NOTEMPTY_ATSTART)
-options |= (re->flags & FF) / ((FF & (~FF+1)) / (OO & (~OO+1)));
-#undef FF
-#undef OO
-
-/* If restarting after a partial match, do some sanity checks on the contents
-of the workspace. */
-
-if ((options & PCRE2_DFA_RESTART) != 0)
- {
- if ((workspace[0] & (-2)) != 0 || workspace[1] < 1 ||
- workspace[1] > (int)((wscount - 2)/INTS_PER_STATEBLOCK))
- return PCRE2_ERROR_DFA_BADRESTART;
- }
-
-/* Set some local values */
-
-utf = (re->overall_options & PCRE2_UTF) != 0;
-start_match = subject + start_offset;
-end_subject = subject + length;
-req_cu_ptr = start_match - 1;
-anchored = (options & (PCRE2_ANCHORED|PCRE2_DFA_RESTART)) != 0 ||
- (re->overall_options & PCRE2_ANCHORED) != 0;
-
-/* The "must be at the start of a line" flags are used in a loop when finding
-where to start. */
-
-startline = (re->flags & PCRE2_STARTLINE) != 0;
-firstline = (re->overall_options & PCRE2_FIRSTLINE) != 0;
-bumpalong_limit = end_subject;
-
-/* Initialize and set up the fixed fields in the callout block, with a pointer
-in the match block. */
-
-mb->cb = &cb;
-cb.version = 2;
-cb.subject = subject;
-cb.subject_length = (PCRE2_SIZE)(end_subject - subject);
-cb.callout_flags = 0;
-cb.capture_top = 1; /* No capture support */
-cb.capture_last = 0;
-cb.mark = NULL; /* No (*MARK) support */
-
-/* Get data from the match context, if present, and fill in the remaining
-fields in the match block. It is an error to set an offset limit without
-setting the flag at compile time. */
-
-if (mcontext == NULL)
- {
- mb->callout = NULL;
- mb->memctl = re->memctl;
- mb->match_limit = PRIV(default_match_context).match_limit;
- mb->match_limit_depth = PRIV(default_match_context).depth_limit;
- mb->heap_limit = PRIV(default_match_context).heap_limit;
- }
-else
- {
- if (mcontext->offset_limit != PCRE2_UNSET)
- {
- if ((re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0)
- return PCRE2_ERROR_BADOFFSETLIMIT;
- bumpalong_limit = subject + mcontext->offset_limit;
- }
- mb->callout = mcontext->callout;
- mb->callout_data = mcontext->callout_data;
- mb->memctl = mcontext->memctl;
- mb->match_limit = mcontext->match_limit;
- mb->match_limit_depth = mcontext->depth_limit;
- mb->heap_limit = mcontext->heap_limit;
- }
-
-if (mb->match_limit > re->limit_match)
- mb->match_limit = re->limit_match;
-
-if (mb->match_limit_depth > re->limit_depth)
- mb->match_limit_depth = re->limit_depth;
-
-if (mb->heap_limit > re->limit_heap)
- mb->heap_limit = re->limit_heap;
-
-mb->start_code = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) +
- re->name_count * re->name_entry_size;
-mb->tables = re->tables;
-mb->start_subject = subject;
-mb->end_subject = end_subject;
-mb->start_offset = start_offset;
-mb->allowemptypartial = (re->max_lookbehind > 0) ||
- (re->flags & PCRE2_MATCH_EMPTY) != 0;
-mb->moptions = options;
-mb->poptions = re->overall_options;
-mb->match_call_count = 0;
-mb->heap_used = 0;
-
-/* Process the \R and newline settings. */
-
-mb->bsr_convention = re->bsr_convention;
-mb->nltype = NLTYPE_FIXED;
-switch(re->newline_convention)
- {
- case PCRE2_NEWLINE_CR:
- mb->nllen = 1;
- mb->nl[0] = CHAR_CR;
- break;
-
- case PCRE2_NEWLINE_LF:
- mb->nllen = 1;
- mb->nl[0] = CHAR_NL;
- break;
-
- case PCRE2_NEWLINE_NUL:
- mb->nllen = 1;
- mb->nl[0] = CHAR_NUL;
- break;
-
- case PCRE2_NEWLINE_CRLF:
- mb->nllen = 2;
- mb->nl[0] = CHAR_CR;
- mb->nl[1] = CHAR_NL;
- break;
-
- case PCRE2_NEWLINE_ANY:
- mb->nltype = NLTYPE_ANY;
- break;
-
- case PCRE2_NEWLINE_ANYCRLF:
- mb->nltype = NLTYPE_ANYCRLF;
- break;
-
- default: return PCRE2_ERROR_INTERNAL;
- }
-
-/* Check a UTF string for validity if required. For 8-bit and 16-bit strings,
-we must also check that a starting offset does not point into the middle of a
-multiunit character. We check only the portion of the subject that is going to
-be inspected during matching - from the offset minus the maximum back reference
-to the given length. This saves time when a small part of a large subject is
-being matched by the use of a starting offset. Note that the maximum lookbehind
-is a number of characters, not code units. */
-
-#ifdef SUPPORT_UNICODE
-if (utf && (options & PCRE2_NO_UTF_CHECK) == 0)
- {
- PCRE2_SPTR check_subject = start_match; /* start_match includes offset */
-
- if (start_offset > 0)
- {
-#if PCRE2_CODE_UNIT_WIDTH != 32
- unsigned int i;
- if (start_match < end_subject && NOT_FIRSTCU(*start_match))
- return PCRE2_ERROR_BADUTFOFFSET;
- for (i = re->max_lookbehind; i > 0 && check_subject > subject; i--)
- {
- check_subject--;
- while (check_subject > subject &&
-#if PCRE2_CODE_UNIT_WIDTH == 8
- (*check_subject & 0xc0) == 0x80)
-#else /* 16-bit */
- (*check_subject & 0xfc00) == 0xdc00)
-#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
- check_subject--;
- }
-#else /* In the 32-bit library, one code unit equals one character. */
- check_subject -= re->max_lookbehind;
- if (check_subject < subject) check_subject = subject;
-#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */
- }
-
- /* Validate the relevant portion of the subject. After an error, adjust the
- offset to be an absolute offset in the whole string. */
-
- match_data->rc = PRIV(valid_utf)(check_subject,
- length - (PCRE2_SIZE)(check_subject - subject), &(match_data->startchar));
- if (match_data->rc != 0)
- {
- match_data->startchar += (PCRE2_SIZE)(check_subject - subject);
- return match_data->rc;
- }
- }
-#endif /* SUPPORT_UNICODE */
-
-/* Set up the first code unit to match, if available. If there's no first code
-unit there may be a bitmap of possible first characters. */
-
-if ((re->flags & PCRE2_FIRSTSET) != 0)
- {
- has_first_cu = TRUE;
- first_cu = first_cu2 = (PCRE2_UCHAR)(re->first_codeunit);
- if ((re->flags & PCRE2_FIRSTCASELESS) != 0)
- {
- first_cu2 = TABLE_GET(first_cu, mb->tables + fcc_offset, first_cu);
-#ifdef SUPPORT_UNICODE
-#if PCRE2_CODE_UNIT_WIDTH == 8
- if (first_cu > 127 && !utf && (re->overall_options & PCRE2_UCP) != 0)
- first_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(first_cu);
-#else
- if (first_cu > 127 && (utf || (re->overall_options & PCRE2_UCP) != 0))
- first_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(first_cu);
-#endif
-#endif /* SUPPORT_UNICODE */
- }
- }
-else
- if (!startline && (re->flags & PCRE2_FIRSTMAPSET) != 0)
- start_bits = re->start_bitmap;
-
-/* There may be a "last known required code unit" set. */
-
-if ((re->flags & PCRE2_LASTSET) != 0)
- {
- has_req_cu = TRUE;
- req_cu = req_cu2 = (PCRE2_UCHAR)(re->last_codeunit);
- if ((re->flags & PCRE2_LASTCASELESS) != 0)
- {
- req_cu2 = TABLE_GET(req_cu, mb->tables + fcc_offset, req_cu);
-#ifdef SUPPORT_UNICODE
-#if PCRE2_CODE_UNIT_WIDTH == 8
- if (req_cu > 127 && !utf && (re->overall_options & PCRE2_UCP) != 0)
- req_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(req_cu);
-#else
- if (req_cu > 127 && (utf || (re->overall_options & PCRE2_UCP) != 0))
- req_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(req_cu);
-#endif
-#endif /* SUPPORT_UNICODE */
- }
- }
-
-/* If the match data block was previously used with PCRE2_COPY_MATCHED_SUBJECT,
-free the memory that was obtained. */
-
-if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0)
- {
- match_data->memctl.free((void *)match_data->subject,
- match_data->memctl.memory_data);
- match_data->flags &= ~PCRE2_MD_COPIED_SUBJECT;
- }
-
-/* Fill in fields that are always returned in the match data. */
-
-match_data->code = re;
-match_data->subject = NULL; /* Default for no match */
-match_data->mark = NULL;
-match_data->matchedby = PCRE2_MATCHEDBY_DFA_INTERPRETER;
-
-/* Call the main matching function, looping for a non-anchored regex after a
-failed match. If not restarting, perform certain optimizations at the start of
-a match. */
-
-for (;;)
- {
- /* ----------------- Start of match optimizations ---------------- */
-
- /* There are some optimizations that avoid running the match if a known
- starting point is not found, or if a known later code unit is not present.
- However, there is an option (settable at compile time) that disables
- these, for testing and for ensuring that all callouts do actually occur.
- The optimizations must also be avoided when restarting a DFA match. */
-
- if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0 &&
- (options & PCRE2_DFA_RESTART) == 0)
- {
- /* If firstline is TRUE, the start of the match is constrained to the first
- line of a multiline string. That is, the match must be before or at the
- first newline following the start of matching. Temporarily adjust
- end_subject so that we stop the optimization scans for a first code unit
- immediately after the first character of a newline (the first code unit can
- legitimately be a newline). If the match fails at the newline, later code
- breaks this loop. */
-
- if (firstline)
- {
- PCRE2_SPTR t = start_match;
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- while (t < end_subject && !IS_NEWLINE(t))
- {
- t++;
- ACROSSCHAR(t < end_subject, t, t++);
- }
- }
- else
-#endif
- while (t < end_subject && !IS_NEWLINE(t)) t++;
- end_subject = t;
- }
-
- /* Anchored: check the first code unit if one is recorded. This may seem
- pointless but it can help in detecting a no match case without scanning for
- the required code unit. */
-
- if (anchored)
- {
- if (has_first_cu || start_bits != NULL)
- {
- BOOL ok = start_match < end_subject;
- if (ok)
- {
- PCRE2_UCHAR c = UCHAR21TEST(start_match);
- ok = has_first_cu && (c == first_cu || c == first_cu2);
- if (!ok && start_bits != NULL)
- {
-#if PCRE2_CODE_UNIT_WIDTH != 8
- if (c > 255) c = 255;
-#endif
- ok = (start_bits[c/8] & (1u << (c&7))) != 0;
- }
- }
- if (!ok) break;
- }
- }
-
- /* Not anchored. Advance to a unique first code unit if there is one. */
-
- else
- {
- if (has_first_cu)
- {
- if (first_cu != first_cu2) /* Caseless */
- {
- /* In 16-bit and 32_bit modes we have to do our own search, so can
- look for both cases at once. */
-
-#if PCRE2_CODE_UNIT_WIDTH != 8
- PCRE2_UCHAR smc;
- while (start_match < end_subject &&
- (smc = UCHAR21TEST(start_match)) != first_cu &&
- smc != first_cu2)
- start_match++;
-#else
- /* In 8-bit mode, the use of memchr() gives a big speed up, even
- though we have to call it twice in order to find the earliest
- occurrence of the code unit in either of its cases. Caching is used
- to remember the positions of previously found code units. This can
- make a huge difference when the strings are very long and only one
- case is actually present. */
-
- PCRE2_SPTR pp1 = NULL;
- PCRE2_SPTR pp2 = NULL;
- PCRE2_SIZE searchlength = end_subject - start_match;
-
- /* If we haven't got a previously found position for first_cu, or if
- the current starting position is later, we need to do a search. If
- the code unit is not found, set it to the end. */
-
- if (memchr_found_first_cu == NULL ||
- start_match > memchr_found_first_cu)
- {
- pp1 = memchr(start_match, first_cu, searchlength);
- memchr_found_first_cu = (pp1 == NULL)? end_subject : pp1;
- }
-
- /* If the start is before a previously found position, use the
- previous position, or NULL if a previous search failed. */
-
- else pp1 = (memchr_found_first_cu == end_subject)? NULL :
- memchr_found_first_cu;
-
- /* Do the same thing for the other case. */
-
- if (memchr_found_first_cu2 == NULL ||
- start_match > memchr_found_first_cu2)
- {
- pp2 = memchr(start_match, first_cu2, searchlength);
- memchr_found_first_cu2 = (pp2 == NULL)? end_subject : pp2;
- }
-
- else pp2 = (memchr_found_first_cu2 == end_subject)? NULL :
- memchr_found_first_cu2;
-
- /* Set the start to the end of the subject if neither case was found.
- Otherwise, use the earlier found point. */
-
- if (pp1 == NULL)
- start_match = (pp2 == NULL)? end_subject : pp2;
- else
- start_match = (pp2 == NULL || pp1 < pp2)? pp1 : pp2;
-
-#endif /* 8-bit handling */
- }
-
- /* The caseful case is much simpler. */
-
- else
- {
-#if PCRE2_CODE_UNIT_WIDTH != 8
- while (start_match < end_subject && UCHAR21TEST(start_match) !=
- first_cu)
- start_match++;
-#else /* 8-bit code units */
- start_match = memchr(start_match, first_cu, end_subject - start_match);
- if (start_match == NULL) start_match = end_subject;
-#endif
- }
-
- /* If we can't find the required code unit, having reached the true end
- of the subject, break the bumpalong loop, to force a match failure,
- except when doing partial matching, when we let the next cycle run at
- the end of the subject. To see why, consider the pattern /(?<=abc)def/,
- which partially matches "abc", even though the string does not contain
- the starting character "d". If we have not reached the true end of the
- subject (PCRE2_FIRSTLINE caused end_subject to be temporarily modified)
- we also let the cycle run, because the matching string is legitimately
- allowed to start with the first code unit of a newline. */
-
- if ((mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) == 0 &&
- start_match >= mb->end_subject)
- break;
- }
-
- /* If there's no first code unit, advance to just after a linebreak for a
- multiline match if required. */
-
- else if (startline)
- {
- if (start_match > mb->start_subject + start_offset)
- {
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- while (start_match < end_subject && !WAS_NEWLINE(start_match))
- {
- start_match++;
- ACROSSCHAR(start_match < end_subject, start_match, start_match++);
- }
- }
- else
-#endif
- while (start_match < end_subject && !WAS_NEWLINE(start_match))
- start_match++;
-
- /* If we have just passed a CR and the newline option is ANY or
- ANYCRLF, and we are now at a LF, advance the match position by one
- more code unit. */
-
- if (start_match[-1] == CHAR_CR &&
- (mb->nltype == NLTYPE_ANY || mb->nltype == NLTYPE_ANYCRLF) &&
- start_match < end_subject &&
- UCHAR21TEST(start_match) == CHAR_NL)
- start_match++;
- }
- }
-
- /* If there's no first code unit or a requirement for a multiline line
- start, advance to a non-unique first code unit if any have been
- identified. The bitmap contains only 256 bits. When code units are 16 or
- 32 bits wide, all code units greater than 254 set the 255 bit. */
-
- else if (start_bits != NULL)
- {
- while (start_match < end_subject)
- {
- uint32_t c = UCHAR21TEST(start_match);
-#if PCRE2_CODE_UNIT_WIDTH != 8
- if (c > 255) c = 255;
-#endif
- if ((start_bits[c/8] & (1u << (c&7))) != 0) break;
- start_match++;
- }
-
- /* See comment above in first_cu checking about the next line. */
-
- if ((mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) == 0 &&
- start_match >= mb->end_subject)
- break;
- }
- } /* End of first code unit handling */
-
- /* Restore fudged end_subject */
-
- end_subject = mb->end_subject;
-
- /* The following two optimizations are disabled for partial matching. */
-
- if ((mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) == 0)
- {
- PCRE2_SPTR p;
-
- /* The minimum matching length is a lower bound; no actual string of that
- length may actually match the pattern. Although the value is, strictly,
- in characters, we treat it as code units to avoid spending too much time
- in this optimization. */
-
- if (end_subject - start_match < re->minlength) goto NOMATCH_EXIT;
-
- /* If req_cu is set, we know that that code unit must appear in the
- subject for the match to succeed. If the first code unit is set, req_cu
- must be later in the subject; otherwise the test starts at the match
- point. This optimization can save a huge amount of backtracking in
- patterns with nested unlimited repeats that aren't going to match.
- Writing separate code for cased/caseless versions makes it go faster, as
- does using an autoincrement and backing off on a match. As in the case of
- the first code unit, using memchr() in the 8-bit library gives a big
- speed up. Unlike the first_cu check above, we do not need to call
- memchr() twice in the caseless case because we only need to check for the
- presence of the character in either case, not find the first occurrence.
-
- The search can be skipped if the code unit was found later than the
- current starting point in a previous iteration of the bumpalong loop.
-
- HOWEVER: when the subject string is very, very long, searching to its end
- can take a long time, and give bad performance on quite ordinary
- patterns. This showed up when somebody was matching something like
- /^\d+C/ on a 32-megabyte string... so we don't do this when the string is
- sufficiently long, but it's worth searching a lot more for unanchored
- patterns. */
-
- p = start_match + (has_first_cu? 1:0);
- if (has_req_cu && p > req_cu_ptr)
- {
- PCRE2_SIZE check_length = end_subject - start_match;
-
- if (check_length < REQ_CU_MAX ||
- (!anchored && check_length < REQ_CU_MAX * 1000))
- {
- if (req_cu != req_cu2) /* Caseless */
- {
-#if PCRE2_CODE_UNIT_WIDTH != 8
- while (p < end_subject)
- {
- uint32_t pp = UCHAR21INCTEST(p);
- if (pp == req_cu || pp == req_cu2) { p--; break; }
- }
-#else /* 8-bit code units */
- PCRE2_SPTR pp = p;
- p = memchr(pp, req_cu, end_subject - pp);
- if (p == NULL)
- {
- p = memchr(pp, req_cu2, end_subject - pp);
- if (p == NULL) p = end_subject;
- }
-#endif /* PCRE2_CODE_UNIT_WIDTH != 8 */
- }
-
- /* The caseful case */
-
- else
- {
-#if PCRE2_CODE_UNIT_WIDTH != 8
- while (p < end_subject)
- {
- if (UCHAR21INCTEST(p) == req_cu) { p--; break; }
- }
-
-#else /* 8-bit code units */
- p = memchr(p, req_cu, end_subject - p);
- if (p == NULL) p = end_subject;
-#endif
- }
-
- /* If we can't find the required code unit, break the matching loop,
- forcing a match failure. */
-
- if (p >= end_subject) break;
-
- /* If we have found the required code unit, save the point where we
- found it, so that we don't search again next time round the loop if
- the start hasn't passed this code unit yet. */
-
- req_cu_ptr = p;
- }
- }
- }
- }
-
- /* ------------ End of start of match optimizations ------------ */
-
- /* Give no match if we have passed the bumpalong limit. */
-
- if (start_match > bumpalong_limit) break;
-
- /* OK, now we can do the business */
-
- mb->start_used_ptr = start_match;
- mb->last_used_ptr = start_match;
- mb->recursive = NULL;
-
- rc = internal_dfa_match(
- mb, /* fixed match data */
- mb->start_code, /* this subexpression's code */
- start_match, /* where we currently are */
- start_offset, /* start offset in subject */
- match_data->ovector, /* offset vector */
- (uint32_t)match_data->oveccount * 2, /* actual size of same */
- workspace, /* workspace vector */
- (int)wscount, /* size of same */
- 0, /* function recurse level */
- base_recursion_workspace); /* initial workspace for recursion */
-
- /* Anything other than "no match" means we are done, always; otherwise, carry
- on only if not anchored. */
-
- if (rc != PCRE2_ERROR_NOMATCH || anchored)
- {
- if (rc == PCRE2_ERROR_PARTIAL && match_data->oveccount > 0)
- {
- match_data->ovector[0] = (PCRE2_SIZE)(start_match - subject);
- match_data->ovector[1] = (PCRE2_SIZE)(end_subject - subject);
- }
- match_data->leftchar = (PCRE2_SIZE)(mb->start_used_ptr - subject);
- match_data->rightchar = (PCRE2_SIZE)( mb->last_used_ptr - subject);
- match_data->startchar = (PCRE2_SIZE)(start_match - subject);
- match_data->rc = rc;
-
- if (rc >= 0 &&(options & PCRE2_COPY_MATCHED_SUBJECT) != 0)
- {
- length = CU2BYTES(length + was_zero_terminated);
- match_data->subject = match_data->memctl.malloc(length,
- match_data->memctl.memory_data);
- if (match_data->subject == NULL) return PCRE2_ERROR_NOMEMORY;
- memcpy((void *)match_data->subject, subject, length);
- match_data->flags |= PCRE2_MD_COPIED_SUBJECT;
- }
- else
- {
- if (rc >= 0 || rc == PCRE2_ERROR_PARTIAL) match_data->subject = subject;
- }
- goto EXIT;
- }
-
- /* Advance to the next subject character unless we are at the end of a line
- and firstline is set. */
-
- if (firstline && IS_NEWLINE(start_match)) break;
- start_match++;
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- ACROSSCHAR(start_match < end_subject, start_match, start_match++);
- }
-#endif
- if (start_match > end_subject) break;
-
- /* If we have just passed a CR and we are now at a LF, and the pattern does
- not contain any explicit matches for \r or \n, and the newline option is CRLF
- or ANY or ANYCRLF, advance the match position by one more character. */
-
- if (UCHAR21TEST(start_match - 1) == CHAR_CR &&
- start_match < end_subject &&
- UCHAR21TEST(start_match) == CHAR_NL &&
- (re->flags & PCRE2_HASCRORLF) == 0 &&
- (mb->nltype == NLTYPE_ANY ||
- mb->nltype == NLTYPE_ANYCRLF ||
- mb->nllen == 2))
- start_match++;
-
- } /* "Bumpalong" loop */
-
-NOMATCH_EXIT:
-rc = PCRE2_ERROR_NOMATCH;
-
-EXIT:
-while (rws->next != NULL)
- {
- RWS_anchor *next = rws->next;
- rws->next = next->next;
- mb->memctl.free(next, mb->memctl.memory_data);
- }
-
-return rc;
-}
-
-/* These #undefs are here to enable unity builds with CMake. */
-
-#undef NLBLOCK /* Block containing newline information */
-#undef PSSTART /* Field containing processed string start */
-#undef PSEND /* Field containing processed string end */
-
-/* End of pcre2_dfa_match.c */
diff --git a/contrib/libs/pcre2/src/pcre2_error.c b/contrib/libs/pcre2/src/pcre2_error.c
deleted file mode 100644
index cbb9629674..0000000000
--- a/contrib/libs/pcre2/src/pcre2_error.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2021 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-#include "pcre2_internal.h"
-
-#define STRING(a) # a
-#define XSTRING(s) STRING(s)
-
-/* The texts of compile-time error messages. Compile-time error numbers start
-at COMPILE_ERROR_BASE (100).
-
-This used to be a table of strings, but in order to reduce the number of
-relocations needed when a shared library is loaded dynamically, it is now one
-long string. We cannot use a table of offsets, because the lengths of inserts
-such as XSTRING(MAX_NAME_SIZE) are not known. Instead,
-pcre2_get_error_message() counts through to the one it wants - this isn't a
-performance issue because these strings are used only when there is an error.
-
-Each substring ends with \0 to insert a null character. This includes the final
-substring, so that the whole string ends with \0\0, which can be detected when
-counting through. */
-
-static const unsigned char compile_error_texts[] =
- "no error\0"
- "\\ at end of pattern\0"
- "\\c at end of pattern\0"
- "unrecognized character follows \\\0"
- "numbers out of order in {} quantifier\0"
- /* 5 */
- "number too big in {} quantifier\0"
- "missing terminating ] for character class\0"
- "escape sequence is invalid in character class\0"
- "range out of order in character class\0"
- "quantifier does not follow a repeatable item\0"
- /* 10 */
- "internal error: unexpected repeat\0"
- "unrecognized character after (? or (?-\0"
- "POSIX named classes are supported only within a class\0"
- "POSIX collating elements are not supported\0"
- "missing closing parenthesis\0"
- /* 15 */
- "reference to non-existent subpattern\0"
- "pattern passed as NULL\0"
- "unrecognised compile-time option bit(s)\0"
- "missing ) after (?# comment\0"
- "parentheses are too deeply nested\0"
- /* 20 */
- "regular expression is too large\0"
- "failed to allocate heap memory\0"
- "unmatched closing parenthesis\0"
- "internal error: code overflow\0"
- "missing closing parenthesis for condition\0"
- /* 25 */
- "lookbehind assertion is not fixed length\0"
- "a relative value of zero is not allowed\0"
- "conditional subpattern contains more than two branches\0"
- "assertion expected after (?( or (?(?C)\0"
- "digit expected after (?+ or (?-\0"
- /* 30 */
- "unknown POSIX class name\0"
- "internal error in pcre2_study(): should not occur\0"
- "this version of PCRE2 does not have Unicode support\0"
- "parentheses are too deeply nested (stack check)\0"
- "character code point value in \\x{} or \\o{} is too large\0"
- /* 35 */
- "lookbehind is too complicated\0"
- "\\C is not allowed in a lookbehind assertion in UTF-" XSTRING(PCRE2_CODE_UNIT_WIDTH) " mode\0"
- "PCRE2 does not support \\F, \\L, \\l, \\N{name}, \\U, or \\u\0"
- "number after (?C is greater than 255\0"
- "closing parenthesis for (?C expected\0"
- /* 40 */
- "invalid escape sequence in (*VERB) name\0"
- "unrecognized character after (?P\0"
- "syntax error in subpattern name (missing terminator?)\0"
- "two named subpatterns have the same name (PCRE2_DUPNAMES not set)\0"
- "subpattern name must start with a non-digit\0"
- /* 45 */
- "this version of PCRE2 does not have support for \\P, \\p, or \\X\0"
- "malformed \\P or \\p sequence\0"
- "unknown property after \\P or \\p\0"
- "subpattern name is too long (maximum " XSTRING(MAX_NAME_SIZE) " code units)\0"
- "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")\0"
- /* 50 */
- "invalid range in character class\0"
- "octal value is greater than \\377 in 8-bit non-UTF-8 mode\0"
- "internal error: overran compiling workspace\0"
- "internal error: previously-checked referenced subpattern not found\0"
- "DEFINE subpattern contains more than one branch\0"
- /* 55 */
- "missing opening brace after \\o\0"
- "internal error: unknown newline setting\0"
- "\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number\0"
- "(?R (recursive pattern call) must be followed by a closing parenthesis\0"
- /* "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)\0" */
- "obsolete error (should not occur)\0" /* Was the above */
- /* 60 */
- "(*VERB) not recognized or malformed\0"
- "subpattern number is too big\0"
- "subpattern name expected\0"
- "internal error: parsed pattern overflow\0"
- "non-octal character in \\o{} (closing brace missing?)\0"
- /* 65 */
- "different names for subpatterns of the same number are not allowed\0"
- "(*MARK) must have an argument\0"
- "non-hex character in \\x{} (closing brace missing?)\0"
-#ifndef EBCDIC
- "\\c must be followed by a printable ASCII character\0"
-#else
- "\\c must be followed by a letter or one of [\\]^_?\0"
-#endif
- "\\k is not followed by a braced, angle-bracketed, or quoted name\0"
- /* 70 */
- "internal error: unknown meta code in check_lookbehinds()\0"
- "\\N is not supported in a class\0"
- "callout string is too long\0"
- "disallowed Unicode code point (>= 0xd800 && <= 0xdfff)\0"
- "using UTF is disabled by the application\0"
- /* 75 */
- "using UCP is disabled by the application\0"
- "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)\0"
- "character code point value in \\u.... sequence is too large\0"
- "digits missing in \\x{} or \\o{} or \\N{U+}\0"
- "syntax error or number too big in (?(VERSION condition\0"
- /* 80 */
- "internal error: unknown opcode in auto_possessify()\0"
- "missing terminating delimiter for callout with string argument\0"
- "unrecognized string delimiter follows (?C\0"
- "using \\C is disabled by the application\0"
- "(?| and/or (?J: or (?x: parentheses are too deeply nested\0"
- /* 85 */
- "using \\C is disabled in this PCRE2 library\0"
- "regular expression is too complicated\0"
- "lookbehind assertion is too long\0"
- "pattern string is longer than the limit set by the application\0"
- "internal error: unknown code in parsed pattern\0"
- /* 90 */
- "internal error: bad code value in parsed_skip()\0"
- "PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES is not allowed in UTF-16 mode\0"
- "invalid option bits with PCRE2_LITERAL\0"
- "\\N{U+dddd} is supported only in Unicode (UTF) mode\0"
- "invalid hyphen in option setting\0"
- /* 95 */
- "(*alpha_assertion) not recognized\0"
- "script runs require Unicode support, which this version of PCRE2 does not have\0"
- "too many capturing groups (maximum 65535)\0"
- "atomic assertion expected after (?( or (?(?C)\0"
- "\\K is not allowed in lookarounds (but see PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK)\0"
- ;
-
-/* Match-time and UTF error texts are in the same format. */
-
-static const unsigned char match_error_texts[] =
- "no error\0"
- "no match\0"
- "partial match\0"
- "UTF-8 error: 1 byte missing at end\0"
- "UTF-8 error: 2 bytes missing at end\0"
- /* 5 */
- "UTF-8 error: 3 bytes missing at end\0"
- "UTF-8 error: 4 bytes missing at end\0"
- "UTF-8 error: 5 bytes missing at end\0"
- "UTF-8 error: byte 2 top bits not 0x80\0"
- "UTF-8 error: byte 3 top bits not 0x80\0"
- /* 10 */
- "UTF-8 error: byte 4 top bits not 0x80\0"
- "UTF-8 error: byte 5 top bits not 0x80\0"
- "UTF-8 error: byte 6 top bits not 0x80\0"
- "UTF-8 error: 5-byte character is not allowed (RFC 3629)\0"
- "UTF-8 error: 6-byte character is not allowed (RFC 3629)\0"
- /* 15 */
- "UTF-8 error: code points greater than 0x10ffff are not defined\0"
- "UTF-8 error: code points 0xd800-0xdfff are not defined\0"
- "UTF-8 error: overlong 2-byte sequence\0"
- "UTF-8 error: overlong 3-byte sequence\0"
- "UTF-8 error: overlong 4-byte sequence\0"
- /* 20 */
- "UTF-8 error: overlong 5-byte sequence\0"
- "UTF-8 error: overlong 6-byte sequence\0"
- "UTF-8 error: isolated byte with 0x80 bit set\0"
- "UTF-8 error: illegal byte (0xfe or 0xff)\0"
- "UTF-16 error: missing low surrogate at end\0"
- /* 25 */
- "UTF-16 error: invalid low surrogate\0"
- "UTF-16 error: isolated low surrogate\0"
- "UTF-32 error: code points 0xd800-0xdfff are not defined\0"
- "UTF-32 error: code points greater than 0x10ffff are not defined\0"
- "bad data value\0"
- /* 30 */
- "patterns do not all use the same character tables\0"
- "magic number missing\0"
- "pattern compiled in wrong mode: 8/16/32-bit error\0"
- "bad offset value\0"
- "bad option value\0"
- /* 35 */
- "invalid replacement string\0"
- "bad offset into UTF string\0"
- "callout error code\0" /* Never returned by PCRE2 itself */
- "invalid data in workspace for DFA restart\0"
- "too much recursion for DFA matching\0"
- /* 40 */
- "backreference condition or recursion test is not supported for DFA matching\0"
- "function is not supported for DFA matching\0"
- "pattern contains an item that is not supported for DFA matching\0"
- "workspace size exceeded in DFA matching\0"
- "internal error - pattern overwritten?\0"
- /* 45 */
- "bad JIT option\0"
- "JIT stack limit reached\0"
- "match limit exceeded\0"
- "no more memory\0"
- "unknown substring\0"
- /* 50 */
- "non-unique substring name\0"
- "NULL argument passed with non-zero length\0"
- "nested recursion at the same subject position\0"
- "matching depth limit exceeded\0"
- "requested value is not available\0"
- /* 55 */
- "requested value is not set\0"
- "offset limit set without PCRE2_USE_OFFSET_LIMIT\0"
- "bad escape sequence in replacement string\0"
- "expected closing curly bracket in replacement string\0"
- "bad substitution in replacement string\0"
- /* 60 */
- "match with end before start or start moved backwards is not supported\0"
- "too many replacements (more than INT_MAX)\0"
- "bad serialized data\0"
- "heap limit exceeded\0"
- "invalid syntax\0"
- /* 65 */
- "internal error - duplicate substitution match\0"
- "PCRE2_MATCH_INVALID_UTF is not supported for DFA matching\0"
- ;
-
-
-/*************************************************
-* Return error message *
-*************************************************/
-
-/* This function copies an error message into a buffer whose units are of an
-appropriate width. Error numbers are positive for compile-time errors, and
-negative for match-time errors (except for UTF errors), but the numbers are all
-distinct.
-
-Arguments:
- enumber error number
- buffer where to put the message (zero terminated)
- size size of the buffer in code units
-
-Returns: length of message if all is well
- negative on error
-*/
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_get_error_message(int enumber, PCRE2_UCHAR *buffer, PCRE2_SIZE size)
-{
-const unsigned char *message;
-PCRE2_SIZE i;
-int n;
-
-if (size == 0) return PCRE2_ERROR_NOMEMORY;
-
-if (enumber >= COMPILE_ERROR_BASE) /* Compile error */
- {
- message = compile_error_texts;
- n = enumber - COMPILE_ERROR_BASE;
- }
-else if (enumber < 0) /* Match or UTF error */
- {
- message = match_error_texts;
- n = -enumber;
- }
-else /* Invalid error number */
- {
- message = (unsigned char *)"\0"; /* Empty message list */
- n = 1;
- }
-
-for (; n > 0; n--)
- {
- while (*message++ != CHAR_NUL) {};
- if (*message == CHAR_NUL) return PCRE2_ERROR_BADDATA;
- }
-
-for (i = 0; *message != 0; i++)
- {
- if (i >= size - 1)
- {
- buffer[i] = 0; /* Terminate partial message */
- return PCRE2_ERROR_NOMEMORY;
- }
- buffer[i] = *message++;
- }
-
-buffer[i] = 0;
-return (int)i;
-}
-
-/* End of pcre2_error.c */
diff --git a/contrib/libs/pcre2/src/pcre2_extuni.c b/contrib/libs/pcre2/src/pcre2_extuni.c
deleted file mode 100644
index eb2e4706bb..0000000000
--- a/contrib/libs/pcre2/src/pcre2_extuni.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2021 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-/* This module contains an internal function that is used to match a Unicode
-extended grapheme sequence. It is used by both pcre2_match() and
-pcre2_def_match(). However, it is called only when Unicode support is being
-compiled. Nevertheless, we provide a dummy function when there is no Unicode
-support, because some compilers do not like functionless source files. */
-
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-
-#include "pcre2_internal.h"
-
-
-/* Dummy function */
-
-#ifndef SUPPORT_UNICODE
-PCRE2_SPTR
-PRIV(extuni)(uint32_t c, PCRE2_SPTR eptr, PCRE2_SPTR start_subject,
- PCRE2_SPTR end_subject, BOOL utf, int *xcount)
-{
-(void)c;
-(void)eptr;
-(void)start_subject;
-(void)end_subject;
-(void)utf;
-(void)xcount;
-return NULL;
-}
-#else
-
-
-/*************************************************
-* Match an extended grapheme sequence *
-*************************************************/
-
-/*
-Arguments:
- c the first character
- eptr pointer to next character
- start_subject pointer to start of subject
- end_subject pointer to end of subject
- utf TRUE if in UTF mode
- xcount pointer to count of additional characters,
- or NULL if count not needed
-
-Returns: pointer after the end of the sequence
-*/
-
-PCRE2_SPTR
-PRIV(extuni)(uint32_t c, PCRE2_SPTR eptr, PCRE2_SPTR start_subject,
- PCRE2_SPTR end_subject, BOOL utf, int *xcount)
-{
-int lgb = UCD_GRAPHBREAK(c);
-
-while (eptr < end_subject)
- {
- int rgb;
- int len = 1;
- if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
- rgb = UCD_GRAPHBREAK(c);
- if ((PRIV(ucp_gbtable)[lgb] & (1u << rgb)) == 0) break;
-
- /* Not breaking between Regional Indicators is allowed only if there
- are an even number of preceding RIs. */
-
- if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator)
- {
- int ricount = 0;
- PCRE2_SPTR bptr = eptr - 1;
- if (utf) BACKCHAR(bptr);
-
- /* bptr is pointing to the left-hand character */
-
- while (bptr > start_subject)
- {
- bptr--;
- if (utf)
- {
- BACKCHAR(bptr);
- GETCHAR(c, bptr);
- }
- else
- c = *bptr;
- if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator) break;
- ricount++;
- }
- if ((ricount & 1) != 0) break; /* Grapheme break required */
- }
-
- /* If Extend or ZWJ follows Extended_Pictographic, do not update lgb; this
- allows any number of them before a following Extended_Pictographic. */
-
- if ((rgb != ucp_gbExtend && rgb != ucp_gbZWJ) ||
- lgb != ucp_gbExtended_Pictographic)
- lgb = rgb;
-
- eptr += len;
- if (xcount != NULL) *xcount += 1;
- }
-
-return eptr;
-}
-
-#endif /* SUPPORT_UNICODE */
-
-/* End of pcre2_extuni.c */
diff --git a/contrib/libs/pcre2/src/pcre2_find_bracket.c b/contrib/libs/pcre2/src/pcre2_find_bracket.c
deleted file mode 100644
index f80503a3f1..0000000000
--- a/contrib/libs/pcre2/src/pcre2_find_bracket.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2018 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains a single function that scans through a compiled pattern
-until it finds a capturing bracket with the given number, or, if the number is
-negative, an instance of OP_REVERSE for a lookbehind. The function is called
-from pcre2_compile.c and also from pcre2_study.c when finding the minimum
-matching length. */
-
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-#include "pcre2_internal.h"
-
-
-/*************************************************
-* Scan compiled regex for specific bracket *
-*************************************************/
-
-/*
-Arguments:
- code points to start of expression
- utf TRUE in UTF mode
- number the required bracket number or negative to find a lookbehind
-
-Returns: pointer to the opcode for the bracket, or NULL if not found
-*/
-
-PCRE2_SPTR
-PRIV(find_bracket)(PCRE2_SPTR code, BOOL utf, int number)
-{
-for (;;)
- {
- PCRE2_UCHAR c = *code;
-
- if (c == OP_END) return NULL;
-
- /* XCLASS is used for classes that cannot be represented just by a bit map.
- This includes negated single high-valued characters. CALLOUT_STR is used for
- callouts with string arguments. In both cases the length in the table is
- zero; the actual length is stored in the compiled code. */
-
- if (c == OP_XCLASS) code += GET(code, 1);
- else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE);
-
- /* Handle lookbehind */
-
- else if (c == OP_REVERSE)
- {
- if (number < 0) return (PCRE2_UCHAR *)code;
- code += PRIV(OP_lengths)[c];
- }
-
- /* Handle capturing bracket */
-
- else if (c == OP_CBRA || c == OP_SCBRA ||
- c == OP_CBRAPOS || c == OP_SCBRAPOS)
- {
- int n = (int)GET2(code, 1+LINK_SIZE);
- if (n == number) return (PCRE2_UCHAR *)code;
- code += PRIV(OP_lengths)[c];
- }
-
- /* Otherwise, we can get the item's length from the table, except that for
- repeated character types, we have to test for \p and \P, which have an extra
- two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we
- must add in its length. */
-
- else
- {
- switch(c)
- {
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSPLUS:
- case OP_TYPEPOSQUERY:
- if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
- break;
-
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEEXACT:
- case OP_TYPEPOSUPTO:
- if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)
- code += 2;
- break;
-
- case OP_MARK:
- case OP_COMMIT_ARG:
- case OP_PRUNE_ARG:
- case OP_SKIP_ARG:
- case OP_THEN_ARG:
- code += code[1];
- break;
- }
-
- /* Add in the fixed length from the table */
-
- code += PRIV(OP_lengths)[c];
-
- /* In UTF-8 and UTF-16 modes, opcodes that are followed by a character may be
- followed by a multi-byte character. The length in the table is a minimum, so
- we have to arrange to skip the extra bytes. */
-
-#ifdef MAYBE_UTF_MULTI
- if (utf) switch(c)
- {
- case OP_CHAR:
- case OP_CHARI:
- case OP_NOT:
- case OP_NOTI:
- case OP_EXACT:
- case OP_EXACTI:
- case OP_NOTEXACT:
- case OP_NOTEXACTI:
- case OP_UPTO:
- case OP_UPTOI:
- case OP_NOTUPTO:
- case OP_NOTUPTOI:
- case OP_MINUPTO:
- case OP_MINUPTOI:
- case OP_NOTMINUPTO:
- case OP_NOTMINUPTOI:
- case OP_POSUPTO:
- case OP_POSUPTOI:
- case OP_NOTPOSUPTO:
- case OP_NOTPOSUPTOI:
- case OP_STAR:
- case OP_STARI:
- case OP_NOTSTAR:
- case OP_NOTSTARI:
- case OP_MINSTAR:
- case OP_MINSTARI:
- case OP_NOTMINSTAR:
- case OP_NOTMINSTARI:
- case OP_POSSTAR:
- case OP_POSSTARI:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSSTARI:
- case OP_PLUS:
- case OP_PLUSI:
- case OP_NOTPLUS:
- case OP_NOTPLUSI:
- case OP_MINPLUS:
- case OP_MINPLUSI:
- case OP_NOTMINPLUS:
- case OP_NOTMINPLUSI:
- case OP_POSPLUS:
- case OP_POSPLUSI:
- case OP_NOTPOSPLUS:
- case OP_NOTPOSPLUSI:
- case OP_QUERY:
- case OP_QUERYI:
- case OP_NOTQUERY:
- case OP_NOTQUERYI:
- case OP_MINQUERY:
- case OP_MINQUERYI:
- case OP_NOTMINQUERY:
- case OP_NOTMINQUERYI:
- case OP_POSQUERY:
- case OP_POSQUERYI:
- case OP_NOTPOSQUERY:
- case OP_NOTPOSQUERYI:
- if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);
- break;
- }
-#else
- (void)(utf); /* Keep compiler happy by referencing function argument */
-#endif /* MAYBE_UTF_MULTI */
- }
- }
-}
-
-/* End of pcre2_find_bracket.c */
diff --git a/contrib/libs/pcre2/src/pcre2_internal.h b/contrib/libs/pcre2/src/pcre2_internal.h
deleted file mode 100644
index 92dd3138d4..0000000000
--- a/contrib/libs/pcre2/src/pcre2_internal.h
+++ /dev/null
@@ -1,2047 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE2 is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2022 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-#ifndef PCRE2_INTERNAL_H_IDEMPOTENT_GUARD
-#define PCRE2_INTERNAL_H_IDEMPOTENT_GUARD
-
-/* We do not support both EBCDIC and Unicode at the same time. The "configure"
-script prevents both being selected, but not everybody uses "configure". EBCDIC
-is only supported for the 8-bit library, but the check for this has to be later
-in this file, because the first part is not width-dependent, and is included by
-pcre2test.c with CODE_UNIT_WIDTH == 0. */
-
-#if defined EBCDIC && defined SUPPORT_UNICODE
-#error The use of both EBCDIC and SUPPORT_UNICODE is not supported.
-#endif
-
-/* Standard C headers */
-
-#include <ctype.h>
-#include <limits.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* Macros to make boolean values more obvious. The #ifndef is to pacify
-compiler warnings in environments where these macros are defined elsewhere.
-Unfortunately, there is no way to do the same for the typedef. */
-
-typedef int BOOL;
-#ifndef FALSE
-#define FALSE 0
-#define TRUE 1
-#endif
-
-/* Valgrind (memcheck) support */
-
-#ifdef SUPPORT_VALGRIND
-#include <valgrind/memcheck.h>
-#endif
-
-/* -ftrivial-auto-var-init support supports initializing all local variables
-to avoid some classes of bug, but this can cause an unacceptable slowdown
-for large on-stack arrays in hot functions. This macro lets us annotate
-such arrays. */
-
-#ifdef HAVE_ATTRIBUTE_UNINITIALIZED
-#define PCRE2_KEEP_UNINITIALIZED __attribute__((uninitialized))
-#else
-#define PCRE2_KEEP_UNINITIALIZED
-#endif
-
-/* Older versions of MSVC lack snprintf(). This define allows for
-warning/error-free compilation and testing with MSVC compilers back to at least
-MSVC 10/2010. Except for VC6 (which is missing some fundamentals and fails). */
-
-#if defined(_MSC_VER) && (_MSC_VER < 1900)
-#define snprintf _snprintf
-#endif
-
-/* When compiling a DLL for Windows, the exported symbols have to be declared
-using some MS magic. I found some useful information on this web page:
-http://msdn2.microsoft.com/en-us/library/y4h7bcy6(VS.80).aspx. According to the
-information there, using __declspec(dllexport) without "extern" we have a
-definition; with "extern" we have a declaration. The settings here override the
-setting in pcre2.h (which is included below); it defines only PCRE2_EXP_DECL,
-which is all that is needed for applications (they just import the symbols). We
-use:
-
- PCRE2_EXP_DECL for declarations
- PCRE2_EXP_DEFN for definitions
-
-The reason for wrapping this in #ifndef PCRE2_EXP_DECL is so that pcre2test,
-which is an application, but needs to import this file in order to "peek" at
-internals, can #include pcre2.h first to get an application's-eye view.
-
-In principle, people compiling for non-Windows, non-Unix-like (i.e. uncommon,
-special-purpose environments) might want to stick other stuff in front of
-exported symbols. That's why, in the non-Windows case, we set PCRE2_EXP_DEFN
-only if it is not already set. */
-
-#ifndef PCRE2_EXP_DECL
-# ifdef _WIN32
-# ifndef PCRE2_STATIC
-# define PCRE2_EXP_DECL extern __declspec(dllexport)
-# define PCRE2_EXP_DEFN __declspec(dllexport)
-# else
-# define PCRE2_EXP_DECL extern
-# define PCRE2_EXP_DEFN
-# endif
-# else
-# ifdef __cplusplus
-# define PCRE2_EXP_DECL extern "C"
-# else
-# define PCRE2_EXP_DECL extern
-# endif
-# ifndef PCRE2_EXP_DEFN
-# define PCRE2_EXP_DEFN PCRE2_EXP_DECL
-# endif
-# endif
-#endif
-
-/* Include the public PCRE2 header and the definitions of UCP character
-property values. This must follow the setting of PCRE2_EXP_DECL above. */
-
-#include "pcre2.h"
-#include "pcre2_ucp.h"
-
-/* When PCRE2 is compiled as a C++ library, the subject pointer can be replaced
-with a custom type. This makes it possible, for example, to allow pcre2_match()
-to process subject strings that are discontinuous by using a smart pointer
-class. It must always be possible to inspect all of the subject string in
-pcre2_match() because of the way it backtracks. */
-
-/* WARNING: This is as yet untested for PCRE2. */
-
-#ifdef CUSTOM_SUBJECT_PTR
-#undef PCRE2_SPTR
-#define PCRE2_SPTR CUSTOM_SUBJECT_PTR
-#endif
-
-/* When checking for integer overflow in pcre2_compile(), we need to handle
-large integers. If a 64-bit integer type is available, we can use that.
-Otherwise we have to cast to double, which of course requires floating point
-arithmetic. Handle this by defining a macro for the appropriate type. */
-
-#if defined INT64_MAX || defined int64_t
-#define INT64_OR_DOUBLE int64_t
-#else
-#define INT64_OR_DOUBLE double
-#endif
-
-/* External (in the C sense) functions and tables that are private to the
-libraries are always referenced using the PRIV macro. This makes it possible
-for pcre2test.c to include some of the source files from the libraries using a
-different PRIV definition to avoid name clashes. It also makes it clear in the
-code that a non-static object is being referenced. */
-
-#ifndef PRIV
-#define PRIV(name) _pcre2_##name
-#endif
-
-/* When compiling for use with the Virtual Pascal compiler, these functions
-need to have their names changed. PCRE2 must be compiled with the -DVPCOMPAT
-option on the command line. */
-
-#ifdef VPCOMPAT
-#define strlen(s) _strlen(s)
-#define strncmp(s1,s2,m) _strncmp(s1,s2,m)
-#define memcmp(s,c,n) _memcmp(s,c,n)
-#define memcpy(d,s,n) _memcpy(d,s,n)
-#define memmove(d,s,n) _memmove(d,s,n)
-#define memset(s,c,n) _memset(s,c,n)
-#else /* VPCOMPAT */
-
-/* Otherwise, to cope with SunOS4 and other systems that lack memmove(), define
-a macro that calls an emulating function. */
-
-#ifndef HAVE_MEMMOVE
-#undef memmove /* Some systems may have a macro */
-#define memmove(a, b, c) PRIV(memmove)(a, b, c)
-#endif /* not HAVE_MEMMOVE */
-#endif /* not VPCOMPAT */
-
-/* This is an unsigned int value that no UTF character can ever have, as
-Unicode doesn't go beyond 0x0010ffff. */
-
-#define NOTACHAR 0xffffffff
-
-/* This is the largest valid UTF/Unicode code point. */
-
-#define MAX_UTF_CODE_POINT 0x10ffff
-
-/* Compile-time positive error numbers (all except UTF errors, which are
-negative) start at this value. It should probably never be changed, in case
-some application is checking for specific numbers. There is a copy of this
-#define in pcre2posix.c (which now no longer includes this file). Ideally, a
-way of having a single definition should be found, but as the number is
-unlikely to change, this is not a pressing issue. The original reason for
-having a base other than 0 was to keep the absolute values of compile-time and
-run-time error numbers numerically different, but in the event the code does
-not rely on this. */
-
-#define COMPILE_ERROR_BASE 100
-
-/* The initial frames vector for remembering pcre2_match() backtracking points
-is allocated on the heap, of this size (bytes) or ten times the frame size if
-larger, unless the heap limit is smaller. Typical frame sizes are a few hundred
-bytes (it depends on the number of capturing parentheses) so 20KiB handles
-quite a few frames. A larger vector on the heap is obtained for matches that
-need more frames, subject to the heap limit. */
-
-#define START_FRAMES_SIZE 20480
-
-/* For DFA matching, an initial internal workspace vector is allocated on the
-stack. The heap is used only if this turns out to be too small. */
-
-#define DFA_START_RWS_SIZE 30720
-
-/* Define the default BSR convention. */
-
-#ifdef BSR_ANYCRLF
-#define BSR_DEFAULT PCRE2_BSR_ANYCRLF
-#else
-#define BSR_DEFAULT PCRE2_BSR_UNICODE
-#endif
-
-
-/* ---------------- Basic UTF-8 macros ---------------- */
-
-/* These UTF-8 macros are always defined because they are used in pcre2test for
-handling wide characters in 16-bit and 32-bit modes, even if an 8-bit library
-is not supported. */
-
-/* Tests whether a UTF-8 code point needs extra bytes to decode. */
-
-#define HASUTF8EXTRALEN(c) ((c) >= 0xc0)
-
-/* The following macros were originally written in the form of loops that used
-data from the tables whose names start with PRIV(utf8_table). They were
-rewritten by a user so as not to use loops, because in some environments this
-gives a significant performance advantage, and it seems never to do any harm.
-*/
-
-/* Base macro to pick up the remaining bytes of a UTF-8 character, not
-advancing the pointer. */
-
-#define GETUTF8(c, eptr) \
- { \
- if ((c & 0x20u) == 0) \
- c = ((c & 0x1fu) << 6) | (eptr[1] & 0x3fu); \
- else if ((c & 0x10u) == 0) \
- c = ((c & 0x0fu) << 12) | ((eptr[1] & 0x3fu) << 6) | (eptr[2] & 0x3fu); \
- else if ((c & 0x08u) == 0) \
- c = ((c & 0x07u) << 18) | ((eptr[1] & 0x3fu) << 12) | \
- ((eptr[2] & 0x3fu) << 6) | (eptr[3] & 0x3fu); \
- else if ((c & 0x04u) == 0) \
- c = ((c & 0x03u) << 24) | ((eptr[1] & 0x3fu) << 18) | \
- ((eptr[2] & 0x3fu) << 12) | ((eptr[3] & 0x3fu) << 6) | \
- (eptr[4] & 0x3fu); \
- else \
- c = ((c & 0x01u) << 30) | ((eptr[1] & 0x3fu) << 24) | \
- ((eptr[2] & 0x3fu) << 18) | ((eptr[3] & 0x3fu) << 12) | \
- ((eptr[4] & 0x3fu) << 6) | (eptr[5] & 0x3fu); \
- }
-
-/* Base macro to pick up the remaining bytes of a UTF-8 character, advancing
-the pointer. */
-
-#define GETUTF8INC(c, eptr) \
- { \
- if ((c & 0x20u) == 0) \
- c = ((c & 0x1fu) << 6) | (*eptr++ & 0x3fu); \
- else if ((c & 0x10u) == 0) \
- { \
- c = ((c & 0x0fu) << 12) | ((*eptr & 0x3fu) << 6) | (eptr[1] & 0x3fu); \
- eptr += 2; \
- } \
- else if ((c & 0x08u) == 0) \
- { \
- c = ((c & 0x07u) << 18) | ((*eptr & 0x3fu) << 12) | \
- ((eptr[1] & 0x3fu) << 6) | (eptr[2] & 0x3fu); \
- eptr += 3; \
- } \
- else if ((c & 0x04u) == 0) \
- { \
- c = ((c & 0x03u) << 24) | ((*eptr & 0x3fu) << 18) | \
- ((eptr[1] & 0x3fu) << 12) | ((eptr[2] & 0x3fu) << 6) | \
- (eptr[3] & 0x3fu); \
- eptr += 4; \
- } \
- else \
- { \
- c = ((c & 0x01u) << 30) | ((*eptr & 0x3fu) << 24) | \
- ((eptr[1] & 0x3fu) << 18) | ((eptr[2] & 0x3fu) << 12) | \
- ((eptr[3] & 0x3fu) << 6) | (eptr[4] & 0x3fu); \
- eptr += 5; \
- } \
- }
-
-/* Base macro to pick up the remaining bytes of a UTF-8 character, not
-advancing the pointer, incrementing the length. */
-
-#define GETUTF8LEN(c, eptr, len) \
- { \
- if ((c & 0x20u) == 0) \
- { \
- c = ((c & 0x1fu) << 6) | (eptr[1] & 0x3fu); \
- len++; \
- } \
- else if ((c & 0x10u) == 0) \
- { \
- c = ((c & 0x0fu) << 12) | ((eptr[1] & 0x3fu) << 6) | (eptr[2] & 0x3fu); \
- len += 2; \
- } \
- else if ((c & 0x08u) == 0) \
- {\
- c = ((c & 0x07u) << 18) | ((eptr[1] & 0x3fu) << 12) | \
- ((eptr[2] & 0x3fu) << 6) | (eptr[3] & 0x3fu); \
- len += 3; \
- } \
- else if ((c & 0x04u) == 0) \
- { \
- c = ((c & 0x03u) << 24) | ((eptr[1] & 0x3fu) << 18) | \
- ((eptr[2] & 0x3fu) << 12) | ((eptr[3] & 0x3fu) << 6) | \
- (eptr[4] & 0x3fu); \
- len += 4; \
- } \
- else \
- {\
- c = ((c & 0x01u) << 30) | ((eptr[1] & 0x3fu) << 24) | \
- ((eptr[2] & 0x3fu) << 18) | ((eptr[3] & 0x3fu) << 12) | \
- ((eptr[4] & 0x3fu) << 6) | (eptr[5] & 0x3fu); \
- len += 5; \
- } \
- }
-
-/* --------------- Whitespace macros ---------------- */
-
-/* Tests for Unicode horizontal and vertical whitespace characters must check a
-number of different values. Using a switch statement for this generates the
-fastest code (no loop, no memory access), and there are several places in the
-interpreter code where this happens. In order to ensure that all the case lists
-remain in step, we use macros so that there is only one place where the lists
-are defined.
-
-These values are also required as lists in pcre2_compile.c when processing \h,
-\H, \v and \V in a character class. The lists are defined in pcre2_tables.c,
-but macros that define the values are here so that all the definitions are
-together. The lists must be in ascending character order, terminated by
-NOTACHAR (which is 0xffffffff).
-
-Any changes should ensure that the various macros are kept in step with each
-other. NOTE: The values also appear in pcre2_jit_compile.c. */
-
-/* -------------- ASCII/Unicode environments -------------- */
-
-#ifndef EBCDIC
-
-/* Character U+180E (Mongolian Vowel Separator) is not included in the list of
-spaces in the Unicode file PropList.txt, and Perl does not recognize it as a
-space. However, in many other sources it is listed as a space and has been in
-PCRE (both APIs) for a long time. */
-
-#define HSPACE_LIST \
- CHAR_HT, CHAR_SPACE, CHAR_NBSP, \
- 0x1680, 0x180e, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, \
- 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202f, 0x205f, 0x3000, \
- NOTACHAR
-
-#define HSPACE_MULTIBYTE_CASES \
- case 0x1680: /* OGHAM SPACE MARK */ \
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ \
- case 0x2000: /* EN QUAD */ \
- case 0x2001: /* EM QUAD */ \
- case 0x2002: /* EN SPACE */ \
- case 0x2003: /* EM SPACE */ \
- case 0x2004: /* THREE-PER-EM SPACE */ \
- case 0x2005: /* FOUR-PER-EM SPACE */ \
- case 0x2006: /* SIX-PER-EM SPACE */ \
- case 0x2007: /* FIGURE SPACE */ \
- case 0x2008: /* PUNCTUATION SPACE */ \
- case 0x2009: /* THIN SPACE */ \
- case 0x200A: /* HAIR SPACE */ \
- case 0x202f: /* NARROW NO-BREAK SPACE */ \
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ \
- case 0x3000 /* IDEOGRAPHIC SPACE */
-
-#define HSPACE_BYTE_CASES \
- case CHAR_HT: \
- case CHAR_SPACE: \
- case CHAR_NBSP
-
-#define HSPACE_CASES \
- HSPACE_BYTE_CASES: \
- HSPACE_MULTIBYTE_CASES
-
-#define VSPACE_LIST \
- CHAR_LF, CHAR_VT, CHAR_FF, CHAR_CR, CHAR_NEL, 0x2028, 0x2029, NOTACHAR
-
-#define VSPACE_MULTIBYTE_CASES \
- case 0x2028: /* LINE SEPARATOR */ \
- case 0x2029 /* PARAGRAPH SEPARATOR */
-
-#define VSPACE_BYTE_CASES \
- case CHAR_LF: \
- case CHAR_VT: \
- case CHAR_FF: \
- case CHAR_CR: \
- case CHAR_NEL
-
-#define VSPACE_CASES \
- VSPACE_BYTE_CASES: \
- VSPACE_MULTIBYTE_CASES
-
-/* -------------- EBCDIC environments -------------- */
-
-#else
-#define HSPACE_LIST CHAR_HT, CHAR_SPACE, CHAR_NBSP, NOTACHAR
-
-#define HSPACE_BYTE_CASES \
- case CHAR_HT: \
- case CHAR_SPACE: \
- case CHAR_NBSP
-
-#define HSPACE_CASES HSPACE_BYTE_CASES
-
-#ifdef EBCDIC_NL25
-#define VSPACE_LIST \
- CHAR_VT, CHAR_FF, CHAR_CR, CHAR_NEL, CHAR_LF, NOTACHAR
-#else
-#define VSPACE_LIST \
- CHAR_VT, CHAR_FF, CHAR_CR, CHAR_LF, CHAR_NEL, NOTACHAR
-#endif
-
-#define VSPACE_BYTE_CASES \
- case CHAR_LF: \
- case CHAR_VT: \
- case CHAR_FF: \
- case CHAR_CR: \
- case CHAR_NEL
-
-#define VSPACE_CASES VSPACE_BYTE_CASES
-#endif /* EBCDIC */
-
-/* -------------- End of whitespace macros -------------- */
-
-
-/* PCRE2 is able to support several different kinds of newline (CR, LF, CRLF,
-"any" and "anycrlf" at present). The following macros are used to package up
-testing for newlines. NLBLOCK, PSSTART, and PSEND are defined in the various
-modules to indicate in which datablock the parameters exist, and what the
-start/end of string field names are. */
-
-#define NLTYPE_FIXED 0 /* Newline is a fixed length string */
-#define NLTYPE_ANY 1 /* Newline is any Unicode line ending */
-#define NLTYPE_ANYCRLF 2 /* Newline is CR, LF, or CRLF */
-
-/* This macro checks for a newline at the given position */
-
-#define IS_NEWLINE(p) \
- ((NLBLOCK->nltype != NLTYPE_FIXED)? \
- ((p) < NLBLOCK->PSEND && \
- PRIV(is_newline)((p), NLBLOCK->nltype, NLBLOCK->PSEND, \
- &(NLBLOCK->nllen), utf)) \
- : \
- ((p) <= NLBLOCK->PSEND - NLBLOCK->nllen && \
- UCHAR21TEST(p) == NLBLOCK->nl[0] && \
- (NLBLOCK->nllen == 1 || UCHAR21TEST(p+1) == NLBLOCK->nl[1]) \
- ) \
- )
-
-/* This macro checks for a newline immediately preceding the given position */
-
-#define WAS_NEWLINE(p) \
- ((NLBLOCK->nltype != NLTYPE_FIXED)? \
- ((p) > NLBLOCK->PSSTART && \
- PRIV(was_newline)((p), NLBLOCK->nltype, NLBLOCK->PSSTART, \
- &(NLBLOCK->nllen), utf)) \
- : \
- ((p) >= NLBLOCK->PSSTART + NLBLOCK->nllen && \
- UCHAR21TEST(p - NLBLOCK->nllen) == NLBLOCK->nl[0] && \
- (NLBLOCK->nllen == 1 || UCHAR21TEST(p - NLBLOCK->nllen + 1) == NLBLOCK->nl[1]) \
- ) \
- )
-
-/* Private flags containing information about the compiled pattern. The first
-three must not be changed, because whichever is set is actually the number of
-bytes in a code unit in that mode. */
-
-#define PCRE2_MODE8 0x00000001 /* compiled in 8 bit mode */
-#define PCRE2_MODE16 0x00000002 /* compiled in 16 bit mode */
-#define PCRE2_MODE32 0x00000004 /* compiled in 32 bit mode */
-#define PCRE2_FIRSTSET 0x00000010 /* first_code unit is set */
-#define PCRE2_FIRSTCASELESS 0x00000020 /* caseless first code unit */
-#define PCRE2_FIRSTMAPSET 0x00000040 /* bitmap of first code units is set */
-#define PCRE2_LASTSET 0x00000080 /* last code unit is set */
-#define PCRE2_LASTCASELESS 0x00000100 /* caseless last code unit */
-#define PCRE2_STARTLINE 0x00000200 /* start after \n for multiline */
-#define PCRE2_JCHANGED 0x00000400 /* j option used in pattern */
-#define PCRE2_HASCRORLF 0x00000800 /* explicit \r or \n in pattern */
-#define PCRE2_HASTHEN 0x00001000 /* pattern contains (*THEN) */
-#define PCRE2_MATCH_EMPTY 0x00002000 /* pattern can match empty string */
-#define PCRE2_BSR_SET 0x00004000 /* BSR was set in the pattern */
-#define PCRE2_NL_SET 0x00008000 /* newline was set in the pattern */
-#define PCRE2_NOTEMPTY_SET 0x00010000 /* (*NOTEMPTY) used ) keep */
-#define PCRE2_NE_ATST_SET 0x00020000 /* (*NOTEMPTY_ATSTART) used) together */
-#define PCRE2_DEREF_TABLES 0x00040000 /* release character tables */
-#define PCRE2_NOJIT 0x00080000 /* (*NOJIT) used */
-#define PCRE2_HASBKPORX 0x00100000 /* contains \P, \p, or \X */
-#define PCRE2_DUPCAPUSED 0x00200000 /* contains (?| */
-#define PCRE2_HASBKC 0x00400000 /* contains \C */
-#define PCRE2_HASACCEPT 0x00800000 /* contains (*ACCEPT) */
-
-#define PCRE2_MODE_MASK (PCRE2_MODE8 | PCRE2_MODE16 | PCRE2_MODE32)
-
-/* Values for the matchedby field in a match data block. */
-
-enum { PCRE2_MATCHEDBY_INTERPRETER, /* pcre2_match() */
- PCRE2_MATCHEDBY_DFA_INTERPRETER, /* pcre2_dfa_match() */
- PCRE2_MATCHEDBY_JIT }; /* pcre2_jit_match() */
-
-/* Values for the flags field in a match data block. */
-
-#define PCRE2_MD_COPIED_SUBJECT 0x01u
-
-/* Magic number to provide a small check against being handed junk. */
-
-#define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */
-
-/* The maximum remaining length of subject we are prepared to search for a
-req_unit match from an anchored pattern. In 8-bit mode, memchr() is used and is
-much faster than the search loop that has to be used in 16-bit and 32-bit
-modes. */
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
-#define REQ_CU_MAX 5000
-#else
-#define REQ_CU_MAX 2000
-#endif
-
-/* Offsets for the bitmap tables in the cbits set of tables. Each table
-contains a set of bits for a class map. Some classes are built by combining
-these tables. */
-
-#define cbit_space 0 /* [:space:] or \s */
-#define cbit_xdigit 32 /* [:xdigit:] */
-#define cbit_digit 64 /* [:digit:] or \d */
-#define cbit_upper 96 /* [:upper:] */
-#define cbit_lower 128 /* [:lower:] */
-#define cbit_word 160 /* [:word:] or \w */
-#define cbit_graph 192 /* [:graph:] */
-#define cbit_print 224 /* [:print:] */
-#define cbit_punct 256 /* [:punct:] */
-#define cbit_cntrl 288 /* [:cntrl:] */
-#define cbit_length 320 /* Length of the cbits table */
-
-/* Bit definitions for entries in the ctypes table. Do not change these values
-without checking pcre2_jit_compile.c, which has an assertion to ensure that
-ctype_word has the value 16. */
-
-#define ctype_space 0x01
-#define ctype_letter 0x02
-#define ctype_lcletter 0x04
-#define ctype_digit 0x08
-#define ctype_word 0x10 /* alphanumeric or '_' */
-
-/* Offsets of the various tables from the base tables pointer, and
-total length of the tables. */
-
-#define lcc_offset 0 /* Lower case */
-#define fcc_offset 256 /* Flip case */
-#define cbits_offset 512 /* Character classes */
-#define ctypes_offset (cbits_offset + cbit_length) /* Character types */
-#define TABLES_LENGTH (ctypes_offset + 256)
-
-
-/* -------------------- Character and string names ------------------------ */
-
-/* If PCRE2 is to support UTF-8 on EBCDIC platforms, we cannot use normal
-character constants like '*' because the compiler would emit their EBCDIC code,
-which is different from their ASCII/UTF-8 code. Instead we define macros for
-the characters so that they always use the ASCII/UTF-8 code when UTF-8 support
-is enabled. When UTF-8 support is not enabled, the definitions use character
-literals. Both character and string versions of each character are needed, and
-there are some longer strings as well.
-
-This means that, on EBCDIC platforms, the PCRE2 library can handle either
-EBCDIC, or UTF-8, but not both. To support both in the same compiled library
-would need different lookups depending on whether PCRE2_UTF was set or not.
-This would make it impossible to use characters in switch/case statements,
-which would reduce performance. For a theoretical use (which nobody has asked
-for) in a minority area (EBCDIC platforms), this is not sensible. Any
-application that did need both could compile two versions of the library, using
-macros to give the functions distinct names. */
-
-#ifndef SUPPORT_UNICODE
-
-/* UTF-8 support is not enabled; use the platform-dependent character literals
-so that PCRE2 works in both ASCII and EBCDIC environments, but only in non-UTF
-mode. Newline characters are problematic in EBCDIC. Though it has CR and LF
-characters, a common practice has been to use its NL (0x15) character as the
-line terminator in C-like processing environments. However, sometimes the LF
-(0x25) character is used instead, according to this Unicode document:
-
-http://unicode.org/standard/reports/tr13/tr13-5.html
-
-PCRE2 defaults EBCDIC NL to 0x15, but has a build-time option to select 0x25
-instead. Whichever is *not* chosen is defined as NEL.
-
-In both ASCII and EBCDIC environments, CHAR_NL and CHAR_LF are synonyms for the
-same code point. */
-
-#ifdef EBCDIC
-
-#ifndef EBCDIC_NL25
-#define CHAR_NL '\x15'
-#define CHAR_NEL '\x25'
-#define STR_NL "\x15"
-#define STR_NEL "\x25"
-#else
-#define CHAR_NL '\x25'
-#define CHAR_NEL '\x15'
-#define STR_NL "\x25"
-#define STR_NEL "\x15"
-#endif
-
-#define CHAR_LF CHAR_NL
-#define STR_LF STR_NL
-
-#define CHAR_ESC '\047'
-#define CHAR_DEL '\007'
-#define CHAR_NBSP ((unsigned char)'\x41')
-#define STR_ESC "\047"
-#define STR_DEL "\007"
-
-#else /* Not EBCDIC */
-
-/* In ASCII/Unicode, linefeed is '\n' and we equate this to NL for
-compatibility. NEL is the Unicode newline character; make sure it is
-a positive value. */
-
-#define CHAR_LF '\n'
-#define CHAR_NL CHAR_LF
-#define CHAR_NEL ((unsigned char)'\x85')
-#define CHAR_ESC '\033'
-#define CHAR_DEL '\177'
-#define CHAR_NBSP ((unsigned char)'\xa0')
-
-#define STR_LF "\n"
-#define STR_NL STR_LF
-#define STR_NEL "\x85"
-#define STR_ESC "\033"
-#define STR_DEL "\177"
-
-#endif /* EBCDIC */
-
-/* The remaining definitions work in both environments. */
-
-#define CHAR_NUL '\0'
-#define CHAR_HT '\t'
-#define CHAR_VT '\v'
-#define CHAR_FF '\f'
-#define CHAR_CR '\r'
-#define CHAR_BS '\b'
-#define CHAR_BEL '\a'
-
-#define CHAR_SPACE ' '
-#define CHAR_EXCLAMATION_MARK '!'
-#define CHAR_QUOTATION_MARK '"'
-#define CHAR_NUMBER_SIGN '#'
-#define CHAR_DOLLAR_SIGN '$'
-#define CHAR_PERCENT_SIGN '%'
-#define CHAR_AMPERSAND '&'
-#define CHAR_APOSTROPHE '\''
-#define CHAR_LEFT_PARENTHESIS '('
-#define CHAR_RIGHT_PARENTHESIS ')'
-#define CHAR_ASTERISK '*'
-#define CHAR_PLUS '+'
-#define CHAR_COMMA ','
-#define CHAR_MINUS '-'
-#define CHAR_DOT '.'
-#define CHAR_SLASH '/'
-#define CHAR_0 '0'
-#define CHAR_1 '1'
-#define CHAR_2 '2'
-#define CHAR_3 '3'
-#define CHAR_4 '4'
-#define CHAR_5 '5'
-#define CHAR_6 '6'
-#define CHAR_7 '7'
-#define CHAR_8 '8'
-#define CHAR_9 '9'
-#define CHAR_COLON ':'
-#define CHAR_SEMICOLON ';'
-#define CHAR_LESS_THAN_SIGN '<'
-#define CHAR_EQUALS_SIGN '='
-#define CHAR_GREATER_THAN_SIGN '>'
-#define CHAR_QUESTION_MARK '?'
-#define CHAR_COMMERCIAL_AT '@'
-#define CHAR_A 'A'
-#define CHAR_B 'B'
-#define CHAR_C 'C'
-#define CHAR_D 'D'
-#define CHAR_E 'E'
-#define CHAR_F 'F'
-#define CHAR_G 'G'
-#define CHAR_H 'H'
-#define CHAR_I 'I'
-#define CHAR_J 'J'
-#define CHAR_K 'K'
-#define CHAR_L 'L'
-#define CHAR_M 'M'
-#define CHAR_N 'N'
-#define CHAR_O 'O'
-#define CHAR_P 'P'
-#define CHAR_Q 'Q'
-#define CHAR_R 'R'
-#define CHAR_S 'S'
-#define CHAR_T 'T'
-#define CHAR_U 'U'
-#define CHAR_V 'V'
-#define CHAR_W 'W'
-#define CHAR_X 'X'
-#define CHAR_Y 'Y'
-#define CHAR_Z 'Z'
-#define CHAR_LEFT_SQUARE_BRACKET '['
-#define CHAR_BACKSLASH '\\'
-#define CHAR_RIGHT_SQUARE_BRACKET ']'
-#define CHAR_CIRCUMFLEX_ACCENT '^'
-#define CHAR_UNDERSCORE '_'
-#define CHAR_GRAVE_ACCENT '`'
-#define CHAR_a 'a'
-#define CHAR_b 'b'
-#define CHAR_c 'c'
-#define CHAR_d 'd'
-#define CHAR_e 'e'
-#define CHAR_f 'f'
-#define CHAR_g 'g'
-#define CHAR_h 'h'
-#define CHAR_i 'i'
-#define CHAR_j 'j'
-#define CHAR_k 'k'
-#define CHAR_l 'l'
-#define CHAR_m 'm'
-#define CHAR_n 'n'
-#define CHAR_o 'o'
-#define CHAR_p 'p'
-#define CHAR_q 'q'
-#define CHAR_r 'r'
-#define CHAR_s 's'
-#define CHAR_t 't'
-#define CHAR_u 'u'
-#define CHAR_v 'v'
-#define CHAR_w 'w'
-#define CHAR_x 'x'
-#define CHAR_y 'y'
-#define CHAR_z 'z'
-#define CHAR_LEFT_CURLY_BRACKET '{'
-#define CHAR_VERTICAL_LINE '|'
-#define CHAR_RIGHT_CURLY_BRACKET '}'
-#define CHAR_TILDE '~'
-
-#define STR_HT "\t"
-#define STR_VT "\v"
-#define STR_FF "\f"
-#define STR_CR "\r"
-#define STR_BS "\b"
-#define STR_BEL "\a"
-
-#define STR_SPACE " "
-#define STR_EXCLAMATION_MARK "!"
-#define STR_QUOTATION_MARK "\""
-#define STR_NUMBER_SIGN "#"
-#define STR_DOLLAR_SIGN "$"
-#define STR_PERCENT_SIGN "%"
-#define STR_AMPERSAND "&"
-#define STR_APOSTROPHE "'"
-#define STR_LEFT_PARENTHESIS "("
-#define STR_RIGHT_PARENTHESIS ")"
-#define STR_ASTERISK "*"
-#define STR_PLUS "+"
-#define STR_COMMA ","
-#define STR_MINUS "-"
-#define STR_DOT "."
-#define STR_SLASH "/"
-#define STR_0 "0"
-#define STR_1 "1"
-#define STR_2 "2"
-#define STR_3 "3"
-#define STR_4 "4"
-#define STR_5 "5"
-#define STR_6 "6"
-#define STR_7 "7"
-#define STR_8 "8"
-#define STR_9 "9"
-#define STR_COLON ":"
-#define STR_SEMICOLON ";"
-#define STR_LESS_THAN_SIGN "<"
-#define STR_EQUALS_SIGN "="
-#define STR_GREATER_THAN_SIGN ">"
-#define STR_QUESTION_MARK "?"
-#define STR_COMMERCIAL_AT "@"
-#define STR_A "A"
-#define STR_B "B"
-#define STR_C "C"
-#define STR_D "D"
-#define STR_E "E"
-#define STR_F "F"
-#define STR_G "G"
-#define STR_H "H"
-#define STR_I "I"
-#define STR_J "J"
-#define STR_K "K"
-#define STR_L "L"
-#define STR_M "M"
-#define STR_N "N"
-#define STR_O "O"
-#define STR_P "P"
-#define STR_Q "Q"
-#define STR_R "R"
-#define STR_S "S"
-#define STR_T "T"
-#define STR_U "U"
-#define STR_V "V"
-#define STR_W "W"
-#define STR_X "X"
-#define STR_Y "Y"
-#define STR_Z "Z"
-#define STR_LEFT_SQUARE_BRACKET "["
-#define STR_BACKSLASH "\\"
-#define STR_RIGHT_SQUARE_BRACKET "]"
-#define STR_CIRCUMFLEX_ACCENT "^"
-#define STR_UNDERSCORE "_"
-#define STR_GRAVE_ACCENT "`"
-#define STR_a "a"
-#define STR_b "b"
-#define STR_c "c"
-#define STR_d "d"
-#define STR_e "e"
-#define STR_f "f"
-#define STR_g "g"
-#define STR_h "h"
-#define STR_i "i"
-#define STR_j "j"
-#define STR_k "k"
-#define STR_l "l"
-#define STR_m "m"
-#define STR_n "n"
-#define STR_o "o"
-#define STR_p "p"
-#define STR_q "q"
-#define STR_r "r"
-#define STR_s "s"
-#define STR_t "t"
-#define STR_u "u"
-#define STR_v "v"
-#define STR_w "w"
-#define STR_x "x"
-#define STR_y "y"
-#define STR_z "z"
-#define STR_LEFT_CURLY_BRACKET "{"
-#define STR_VERTICAL_LINE "|"
-#define STR_RIGHT_CURLY_BRACKET "}"
-#define STR_TILDE "~"
-
-#define STRING_ACCEPT0 "ACCEPT\0"
-#define STRING_COMMIT0 "COMMIT\0"
-#define STRING_F0 "F\0"
-#define STRING_FAIL0 "FAIL\0"
-#define STRING_MARK0 "MARK\0"
-#define STRING_PRUNE0 "PRUNE\0"
-#define STRING_SKIP0 "SKIP\0"
-#define STRING_THEN "THEN"
-
-#define STRING_atomic0 "atomic\0"
-#define STRING_pla0 "pla\0"
-#define STRING_plb0 "plb\0"
-#define STRING_napla0 "napla\0"
-#define STRING_naplb0 "naplb\0"
-#define STRING_nla0 "nla\0"
-#define STRING_nlb0 "nlb\0"
-#define STRING_sr0 "sr\0"
-#define STRING_asr0 "asr\0"
-#define STRING_positive_lookahead0 "positive_lookahead\0"
-#define STRING_positive_lookbehind0 "positive_lookbehind\0"
-#define STRING_non_atomic_positive_lookahead0 "non_atomic_positive_lookahead\0"
-#define STRING_non_atomic_positive_lookbehind0 "non_atomic_positive_lookbehind\0"
-#define STRING_negative_lookahead0 "negative_lookahead\0"
-#define STRING_negative_lookbehind0 "negative_lookbehind\0"
-#define STRING_script_run0 "script_run\0"
-#define STRING_atomic_script_run "atomic_script_run"
-
-#define STRING_alpha0 "alpha\0"
-#define STRING_lower0 "lower\0"
-#define STRING_upper0 "upper\0"
-#define STRING_alnum0 "alnum\0"
-#define STRING_ascii0 "ascii\0"
-#define STRING_blank0 "blank\0"
-#define STRING_cntrl0 "cntrl\0"
-#define STRING_digit0 "digit\0"
-#define STRING_graph0 "graph\0"
-#define STRING_print0 "print\0"
-#define STRING_punct0 "punct\0"
-#define STRING_space0 "space\0"
-#define STRING_word0 "word\0"
-#define STRING_xdigit "xdigit"
-
-#define STRING_DEFINE "DEFINE"
-#define STRING_VERSION "VERSION"
-#define STRING_WEIRD_STARTWORD "[:<:]]"
-#define STRING_WEIRD_ENDWORD "[:>:]]"
-
-#define STRING_CR_RIGHTPAR "CR)"
-#define STRING_LF_RIGHTPAR "LF)"
-#define STRING_CRLF_RIGHTPAR "CRLF)"
-#define STRING_ANY_RIGHTPAR "ANY)"
-#define STRING_ANYCRLF_RIGHTPAR "ANYCRLF)"
-#define STRING_NUL_RIGHTPAR "NUL)"
-#define STRING_BSR_ANYCRLF_RIGHTPAR "BSR_ANYCRLF)"
-#define STRING_BSR_UNICODE_RIGHTPAR "BSR_UNICODE)"
-#define STRING_UTF8_RIGHTPAR "UTF8)"
-#define STRING_UTF16_RIGHTPAR "UTF16)"
-#define STRING_UTF32_RIGHTPAR "UTF32)"
-#define STRING_UTF_RIGHTPAR "UTF)"
-#define STRING_UCP_RIGHTPAR "UCP)"
-#define STRING_NO_AUTO_POSSESS_RIGHTPAR "NO_AUTO_POSSESS)"
-#define STRING_NO_DOTSTAR_ANCHOR_RIGHTPAR "NO_DOTSTAR_ANCHOR)"
-#define STRING_NO_JIT_RIGHTPAR "NO_JIT)"
-#define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)"
-#define STRING_NOTEMPTY_RIGHTPAR "NOTEMPTY)"
-#define STRING_NOTEMPTY_ATSTART_RIGHTPAR "NOTEMPTY_ATSTART)"
-#define STRING_LIMIT_HEAP_EQ "LIMIT_HEAP="
-#define STRING_LIMIT_MATCH_EQ "LIMIT_MATCH="
-#define STRING_LIMIT_DEPTH_EQ "LIMIT_DEPTH="
-#define STRING_LIMIT_RECURSION_EQ "LIMIT_RECURSION="
-#define STRING_MARK "MARK"
-
-#define STRING_bc "bc"
-#define STRING_bidiclass "bidiclass"
-#define STRING_sc "sc"
-#define STRING_script "script"
-#define STRING_scriptextensions "scriptextensions"
-#define STRING_scx "scx"
-
-#else /* SUPPORT_UNICODE */
-
-/* UTF-8 support is enabled; always use UTF-8 (=ASCII) character codes. This
-works in both modes non-EBCDIC platforms, and on EBCDIC platforms in UTF-8 mode
-only. */
-
-#define CHAR_HT '\011'
-#define CHAR_VT '\013'
-#define CHAR_FF '\014'
-#define CHAR_CR '\015'
-#define CHAR_LF '\012'
-#define CHAR_NL CHAR_LF
-#define CHAR_NEL ((unsigned char)'\x85')
-#define CHAR_BS '\010'
-#define CHAR_BEL '\007'
-#define CHAR_ESC '\033'
-#define CHAR_DEL '\177'
-
-#define CHAR_NUL '\0'
-#define CHAR_SPACE '\040'
-#define CHAR_EXCLAMATION_MARK '\041'
-#define CHAR_QUOTATION_MARK '\042'
-#define CHAR_NUMBER_SIGN '\043'
-#define CHAR_DOLLAR_SIGN '\044'
-#define CHAR_PERCENT_SIGN '\045'
-#define CHAR_AMPERSAND '\046'
-#define CHAR_APOSTROPHE '\047'
-#define CHAR_LEFT_PARENTHESIS '\050'
-#define CHAR_RIGHT_PARENTHESIS '\051'
-#define CHAR_ASTERISK '\052'
-#define CHAR_PLUS '\053'
-#define CHAR_COMMA '\054'
-#define CHAR_MINUS '\055'
-#define CHAR_DOT '\056'
-#define CHAR_SLASH '\057'
-#define CHAR_0 '\060'
-#define CHAR_1 '\061'
-#define CHAR_2 '\062'
-#define CHAR_3 '\063'
-#define CHAR_4 '\064'
-#define CHAR_5 '\065'
-#define CHAR_6 '\066'
-#define CHAR_7 '\067'
-#define CHAR_8 '\070'
-#define CHAR_9 '\071'
-#define CHAR_COLON '\072'
-#define CHAR_SEMICOLON '\073'
-#define CHAR_LESS_THAN_SIGN '\074'
-#define CHAR_EQUALS_SIGN '\075'
-#define CHAR_GREATER_THAN_SIGN '\076'
-#define CHAR_QUESTION_MARK '\077'
-#define CHAR_COMMERCIAL_AT '\100'
-#define CHAR_A '\101'
-#define CHAR_B '\102'
-#define CHAR_C '\103'
-#define CHAR_D '\104'
-#define CHAR_E '\105'
-#define CHAR_F '\106'
-#define CHAR_G '\107'
-#define CHAR_H '\110'
-#define CHAR_I '\111'
-#define CHAR_J '\112'
-#define CHAR_K '\113'
-#define CHAR_L '\114'
-#define CHAR_M '\115'
-#define CHAR_N '\116'
-#define CHAR_O '\117'
-#define CHAR_P '\120'
-#define CHAR_Q '\121'
-#define CHAR_R '\122'
-#define CHAR_S '\123'
-#define CHAR_T '\124'
-#define CHAR_U '\125'
-#define CHAR_V '\126'
-#define CHAR_W '\127'
-#define CHAR_X '\130'
-#define CHAR_Y '\131'
-#define CHAR_Z '\132'
-#define CHAR_LEFT_SQUARE_BRACKET '\133'
-#define CHAR_BACKSLASH '\134'
-#define CHAR_RIGHT_SQUARE_BRACKET '\135'
-#define CHAR_CIRCUMFLEX_ACCENT '\136'
-#define CHAR_UNDERSCORE '\137'
-#define CHAR_GRAVE_ACCENT '\140'
-#define CHAR_a '\141'
-#define CHAR_b '\142'
-#define CHAR_c '\143'
-#define CHAR_d '\144'
-#define CHAR_e '\145'
-#define CHAR_f '\146'
-#define CHAR_g '\147'
-#define CHAR_h '\150'
-#define CHAR_i '\151'
-#define CHAR_j '\152'
-#define CHAR_k '\153'
-#define CHAR_l '\154'
-#define CHAR_m '\155'
-#define CHAR_n '\156'
-#define CHAR_o '\157'
-#define CHAR_p '\160'
-#define CHAR_q '\161'
-#define CHAR_r '\162'
-#define CHAR_s '\163'
-#define CHAR_t '\164'
-#define CHAR_u '\165'
-#define CHAR_v '\166'
-#define CHAR_w '\167'
-#define CHAR_x '\170'
-#define CHAR_y '\171'
-#define CHAR_z '\172'
-#define CHAR_LEFT_CURLY_BRACKET '\173'
-#define CHAR_VERTICAL_LINE '\174'
-#define CHAR_RIGHT_CURLY_BRACKET '\175'
-#define CHAR_TILDE '\176'
-#define CHAR_NBSP ((unsigned char)'\xa0')
-
-#define STR_HT "\011"
-#define STR_VT "\013"
-#define STR_FF "\014"
-#define STR_CR "\015"
-#define STR_NL "\012"
-#define STR_BS "\010"
-#define STR_BEL "\007"
-#define STR_ESC "\033"
-#define STR_DEL "\177"
-
-#define STR_SPACE "\040"
-#define STR_EXCLAMATION_MARK "\041"
-#define STR_QUOTATION_MARK "\042"
-#define STR_NUMBER_SIGN "\043"
-#define STR_DOLLAR_SIGN "\044"
-#define STR_PERCENT_SIGN "\045"
-#define STR_AMPERSAND "\046"
-#define STR_APOSTROPHE "\047"
-#define STR_LEFT_PARENTHESIS "\050"
-#define STR_RIGHT_PARENTHESIS "\051"
-#define STR_ASTERISK "\052"
-#define STR_PLUS "\053"
-#define STR_COMMA "\054"
-#define STR_MINUS "\055"
-#define STR_DOT "\056"
-#define STR_SLASH "\057"
-#define STR_0 "\060"
-#define STR_1 "\061"
-#define STR_2 "\062"
-#define STR_3 "\063"
-#define STR_4 "\064"
-#define STR_5 "\065"
-#define STR_6 "\066"
-#define STR_7 "\067"
-#define STR_8 "\070"
-#define STR_9 "\071"
-#define STR_COLON "\072"
-#define STR_SEMICOLON "\073"
-#define STR_LESS_THAN_SIGN "\074"
-#define STR_EQUALS_SIGN "\075"
-#define STR_GREATER_THAN_SIGN "\076"
-#define STR_QUESTION_MARK "\077"
-#define STR_COMMERCIAL_AT "\100"
-#define STR_A "\101"
-#define STR_B "\102"
-#define STR_C "\103"
-#define STR_D "\104"
-#define STR_E "\105"
-#define STR_F "\106"
-#define STR_G "\107"
-#define STR_H "\110"
-#define STR_I "\111"
-#define STR_J "\112"
-#define STR_K "\113"
-#define STR_L "\114"
-#define STR_M "\115"
-#define STR_N "\116"
-#define STR_O "\117"
-#define STR_P "\120"
-#define STR_Q "\121"
-#define STR_R "\122"
-#define STR_S "\123"
-#define STR_T "\124"
-#define STR_U "\125"
-#define STR_V "\126"
-#define STR_W "\127"
-#define STR_X "\130"
-#define STR_Y "\131"
-#define STR_Z "\132"
-#define STR_LEFT_SQUARE_BRACKET "\133"
-#define STR_BACKSLASH "\134"
-#define STR_RIGHT_SQUARE_BRACKET "\135"
-#define STR_CIRCUMFLEX_ACCENT "\136"
-#define STR_UNDERSCORE "\137"
-#define STR_GRAVE_ACCENT "\140"
-#define STR_a "\141"
-#define STR_b "\142"
-#define STR_c "\143"
-#define STR_d "\144"
-#define STR_e "\145"
-#define STR_f "\146"
-#define STR_g "\147"
-#define STR_h "\150"
-#define STR_i "\151"
-#define STR_j "\152"
-#define STR_k "\153"
-#define STR_l "\154"
-#define STR_m "\155"
-#define STR_n "\156"
-#define STR_o "\157"
-#define STR_p "\160"
-#define STR_q "\161"
-#define STR_r "\162"
-#define STR_s "\163"
-#define STR_t "\164"
-#define STR_u "\165"
-#define STR_v "\166"
-#define STR_w "\167"
-#define STR_x "\170"
-#define STR_y "\171"
-#define STR_z "\172"
-#define STR_LEFT_CURLY_BRACKET "\173"
-#define STR_VERTICAL_LINE "\174"
-#define STR_RIGHT_CURLY_BRACKET "\175"
-#define STR_TILDE "\176"
-
-#define STRING_ACCEPT0 STR_A STR_C STR_C STR_E STR_P STR_T "\0"
-#define STRING_COMMIT0 STR_C STR_O STR_M STR_M STR_I STR_T "\0"
-#define STRING_F0 STR_F "\0"
-#define STRING_FAIL0 STR_F STR_A STR_I STR_L "\0"
-#define STRING_MARK0 STR_M STR_A STR_R STR_K "\0"
-#define STRING_PRUNE0 STR_P STR_R STR_U STR_N STR_E "\0"
-#define STRING_SKIP0 STR_S STR_K STR_I STR_P "\0"
-#define STRING_THEN STR_T STR_H STR_E STR_N
-
-#define STRING_atomic0 STR_a STR_t STR_o STR_m STR_i STR_c "\0"
-#define STRING_pla0 STR_p STR_l STR_a "\0"
-#define STRING_plb0 STR_p STR_l STR_b "\0"
-#define STRING_napla0 STR_n STR_a STR_p STR_l STR_a "\0"
-#define STRING_naplb0 STR_n STR_a STR_p STR_l STR_b "\0"
-#define STRING_nla0 STR_n STR_l STR_a "\0"
-#define STRING_nlb0 STR_n STR_l STR_b "\0"
-#define STRING_sr0 STR_s STR_r "\0"
-#define STRING_asr0 STR_a STR_s STR_r "\0"
-#define STRING_positive_lookahead0 STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_a STR_h STR_e STR_a STR_d "\0"
-#define STRING_positive_lookbehind0 STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_b STR_e STR_h STR_i STR_n STR_d "\0"
-#define STRING_non_atomic_positive_lookahead0 STR_n STR_o STR_n STR_UNDERSCORE STR_a STR_t STR_o STR_m STR_i STR_c STR_UNDERSCORE STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_a STR_h STR_e STR_a STR_d "\0"
-#define STRING_non_atomic_positive_lookbehind0 STR_n STR_o STR_n STR_UNDERSCORE STR_a STR_t STR_o STR_m STR_i STR_c STR_UNDERSCORE STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_b STR_e STR_h STR_i STR_n STR_d "\0"
-#define STRING_negative_lookahead0 STR_n STR_e STR_g STR_a STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_a STR_h STR_e STR_a STR_d "\0"
-#define STRING_negative_lookbehind0 STR_n STR_e STR_g STR_a STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_b STR_e STR_h STR_i STR_n STR_d "\0"
-#define STRING_script_run0 STR_s STR_c STR_r STR_i STR_p STR_t STR_UNDERSCORE STR_r STR_u STR_n "\0"
-#define STRING_atomic_script_run STR_a STR_t STR_o STR_m STR_i STR_c STR_UNDERSCORE STR_s STR_c STR_r STR_i STR_p STR_t STR_UNDERSCORE STR_r STR_u STR_n
-
-#define STRING_alpha0 STR_a STR_l STR_p STR_h STR_a "\0"
-#define STRING_lower0 STR_l STR_o STR_w STR_e STR_r "\0"
-#define STRING_upper0 STR_u STR_p STR_p STR_e STR_r "\0"
-#define STRING_alnum0 STR_a STR_l STR_n STR_u STR_m "\0"
-#define STRING_ascii0 STR_a STR_s STR_c STR_i STR_i "\0"
-#define STRING_blank0 STR_b STR_l STR_a STR_n STR_k "\0"
-#define STRING_cntrl0 STR_c STR_n STR_t STR_r STR_l "\0"
-#define STRING_digit0 STR_d STR_i STR_g STR_i STR_t "\0"
-#define STRING_graph0 STR_g STR_r STR_a STR_p STR_h "\0"
-#define STRING_print0 STR_p STR_r STR_i STR_n STR_t "\0"
-#define STRING_punct0 STR_p STR_u STR_n STR_c STR_t "\0"
-#define STRING_space0 STR_s STR_p STR_a STR_c STR_e "\0"
-#define STRING_word0 STR_w STR_o STR_r STR_d "\0"
-#define STRING_xdigit STR_x STR_d STR_i STR_g STR_i STR_t
-
-#define STRING_DEFINE STR_D STR_E STR_F STR_I STR_N STR_E
-#define STRING_VERSION STR_V STR_E STR_R STR_S STR_I STR_O STR_N
-#define STRING_WEIRD_STARTWORD STR_LEFT_SQUARE_BRACKET STR_COLON STR_LESS_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET
-#define STRING_WEIRD_ENDWORD STR_LEFT_SQUARE_BRACKET STR_COLON STR_GREATER_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET
-
-#define STRING_CR_RIGHTPAR STR_C STR_R STR_RIGHT_PARENTHESIS
-#define STRING_LF_RIGHTPAR STR_L STR_F STR_RIGHT_PARENTHESIS
-#define STRING_CRLF_RIGHTPAR STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
-#define STRING_ANY_RIGHTPAR STR_A STR_N STR_Y STR_RIGHT_PARENTHESIS
-#define STRING_ANYCRLF_RIGHTPAR STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
-#define STRING_NUL_RIGHTPAR STR_N STR_U STR_L STR_RIGHT_PARENTHESIS
-#define STRING_BSR_ANYCRLF_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
-#define STRING_BSR_UNICODE_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_U STR_N STR_I STR_C STR_O STR_D STR_E STR_RIGHT_PARENTHESIS
-#define STRING_UTF8_RIGHTPAR STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS
-#define STRING_UTF16_RIGHTPAR STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS
-#define STRING_UTF32_RIGHTPAR STR_U STR_T STR_F STR_3 STR_2 STR_RIGHT_PARENTHESIS
-#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_RIGHT_PARENTHESIS
-#define STRING_UCP_RIGHTPAR STR_U STR_C STR_P STR_RIGHT_PARENTHESIS
-#define STRING_NO_AUTO_POSSESS_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_A STR_U STR_T STR_O STR_UNDERSCORE STR_P STR_O STR_S STR_S STR_E STR_S STR_S STR_RIGHT_PARENTHESIS
-#define STRING_NO_DOTSTAR_ANCHOR_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_D STR_O STR_T STR_S STR_T STR_A STR_R STR_UNDERSCORE STR_A STR_N STR_C STR_H STR_O STR_R STR_RIGHT_PARENTHESIS
-#define STRING_NO_JIT_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_J STR_I STR_T STR_RIGHT_PARENTHESIS
-#define STRING_NO_START_OPT_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_S STR_T STR_A STR_R STR_T STR_UNDERSCORE STR_O STR_P STR_T STR_RIGHT_PARENTHESIS
-#define STRING_NOTEMPTY_RIGHTPAR STR_N STR_O STR_T STR_E STR_M STR_P STR_T STR_Y STR_RIGHT_PARENTHESIS
-#define STRING_NOTEMPTY_ATSTART_RIGHTPAR STR_N STR_O STR_T STR_E STR_M STR_P STR_T STR_Y STR_UNDERSCORE STR_A STR_T STR_S STR_T STR_A STR_R STR_T STR_RIGHT_PARENTHESIS
-#define STRING_LIMIT_HEAP_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_H STR_E STR_A STR_P STR_EQUALS_SIGN
-#define STRING_LIMIT_MATCH_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_M STR_A STR_T STR_C STR_H STR_EQUALS_SIGN
-#define STRING_LIMIT_DEPTH_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_D STR_E STR_P STR_T STR_H STR_EQUALS_SIGN
-#define STRING_LIMIT_RECURSION_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_R STR_E STR_C STR_U STR_R STR_S STR_I STR_O STR_N STR_EQUALS_SIGN
-#define STRING_MARK STR_M STR_A STR_R STR_K
-
-#define STRING_bc STR_b STR_c
-#define STRING_bidiclass STR_b STR_i STR_d STR_i STR_c STR_l STR_a STR_s STR_s
-#define STRING_sc STR_s STR_c
-#define STRING_script STR_s STR_c STR_r STR_i STR_p STR_t
-#define STRING_scriptextensions STR_s STR_c STR_r STR_i STR_p STR_t STR_e STR_x STR_t STR_e STR_n STR_s STR_i STR_o STR_n STR_s
-#define STRING_scx STR_s STR_c STR_x
-
-
-#endif /* SUPPORT_UNICODE */
-
-/* -------------------- End of character and string names -------------------*/
-
-/* -------------------- Definitions for compiled patterns -------------------*/
-
-/* Codes for different types of Unicode property. If these definitions are
-changed, the autopossessifying table in pcre2_auto_possess.c must be updated to
-match. */
-
-#define PT_ANY 0 /* Any property - matches all chars */
-#define PT_LAMP 1 /* L& - the union of Lu, Ll, Lt */
-#define PT_GC 2 /* Specified general characteristic (e.g. L) */
-#define PT_PC 3 /* Specified particular characteristic (e.g. Lu) */
-#define PT_SC 4 /* Script only (e.g. Han) */
-#define PT_SCX 5 /* Script extensions (includes SC) */
-#define PT_ALNUM 6 /* Alphanumeric - the union of L and N */
-#define PT_SPACE 7 /* Perl space - general category Z plus 9,10,12,13 */
-#define PT_PXSPACE 8 /* POSIX space - Z plus 9,10,11,12,13 */
-#define PT_WORD 9 /* Word - L plus N plus underscore */
-#define PT_CLIST 10 /* Pseudo-property: match character list */
-#define PT_UCNC 11 /* Universal Character nameable character */
-#define PT_BIDICL 12 /* Specified bidi class */
-#define PT_BOOL 13 /* Boolean property */
-#define PT_TABSIZE 14 /* Size of square table for autopossessify tests */
-
-/* The following special properties are used only in XCLASS items, when POSIX
-classes are specified and PCRE2_UCP is set - in other words, for Unicode
-handling of these classes. They are not available via the \p or \P escapes like
-those in the above list, and so they do not take part in the autopossessifying
-table. */
-
-#define PT_PXGRAPH 14 /* [:graph:] - characters that mark the paper */
-#define PT_PXPRINT 15 /* [:print:] - [:graph:] plus non-control spaces */
-#define PT_PXPUNCT 16 /* [:punct:] - punctuation characters */
-
-/* This value is used when parsing \p and \P escapes to indicate that neither
-\p{script:...} nor \p{scx:...} has been encountered. */
-
-#define PT_NOTSCRIPT 255
-
-/* Flag bits and data types for the extended class (OP_XCLASS) for classes that
-contain characters with values greater than 255. */
-
-#define XCL_NOT 0x01 /* Flag: this is a negative class */
-#define XCL_MAP 0x02 /* Flag: a 32-byte map is present */
-#define XCL_HASPROP 0x04 /* Flag: property checks are present. */
-
-#define XCL_END 0 /* Marks end of individual items */
-#define XCL_SINGLE 1 /* Single item (one multibyte char) follows */
-#define XCL_RANGE 2 /* A range (two multibyte chars) follows */
-#define XCL_PROP 3 /* Unicode property (2-byte property code follows) */
-#define XCL_NOTPROP 4 /* Unicode inverted property (ditto) */
-
-/* These are escaped items that aren't just an encoding of a particular data
-value such as \n. They must have non-zero values, as check_escape() returns 0
-for a data character. In the escapes[] table in pcre2_compile.c their values
-are negated in order to distinguish them from data values.
-
-They must appear here in the same order as in the opcode definitions below, up
-to ESC_z. There's a dummy for OP_ALLANY because it corresponds to "." in DOTALL
-mode rather than an escape sequence. It is also used for [^] in JavaScript
-compatibility mode, and for \C in non-utf mode. In non-DOTALL mode, "." behaves
-like \N.
-
-Negative numbers are used to encode a backreference (\1, \2, \3, etc.) in
-check_escape(). There are tests in the code for an escape greater than ESC_b
-and less than ESC_Z to detect the types that may be repeated. These are the
-types that consume characters. If any new escapes are put in between that don't
-consume a character, that code will have to change. */
-
-enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s,
- ESC_W, ESC_w, ESC_N, ESC_dum, ESC_C, ESC_P, ESC_p, ESC_R, ESC_H,
- ESC_h, ESC_V, ESC_v, ESC_X, ESC_Z, ESC_z,
- ESC_E, ESC_Q, ESC_g, ESC_k };
-
-
-/********************** Opcode definitions ******************/
-
-/****** NOTE NOTE NOTE ******
-
-Starting from 1 (i.e. after OP_END), the values up to OP_EOD must correspond in
-order to the list of escapes immediately above. Furthermore, values up to
-OP_DOLLM must not be changed without adjusting the table called autoposstab in
-pcre2_auto_possess.c.
-
-Whenever this list is updated, the two macro definitions that follow must be
-updated to match. The possessification table called "opcode_possessify" in
-pcre2_compile.c must also be updated, and also the tables called "coptable"
-and "poptable" in pcre2_dfa_match.c.
-
-****** NOTE NOTE NOTE ******/
-
-
-/* The values between FIRST_AUTOTAB_OP and LAST_AUTOTAB_RIGHT_OP, inclusive,
-are used in a table for deciding whether a repeated character type can be
-auto-possessified. */
-
-#define FIRST_AUTOTAB_OP OP_NOT_DIGIT
-#define LAST_AUTOTAB_LEFT_OP OP_EXTUNI
-#define LAST_AUTOTAB_RIGHT_OP OP_DOLLM
-
-enum {
- OP_END, /* 0 End of pattern */
-
- /* Values corresponding to backslashed metacharacters */
-
- OP_SOD, /* 1 Start of data: \A */
- OP_SOM, /* 2 Start of match (subject + offset): \G */
- OP_SET_SOM, /* 3 Set start of match (\K) */
- OP_NOT_WORD_BOUNDARY, /* 4 \B */
- OP_WORD_BOUNDARY, /* 5 \b */
- OP_NOT_DIGIT, /* 6 \D */
- OP_DIGIT, /* 7 \d */
- OP_NOT_WHITESPACE, /* 8 \S */
- OP_WHITESPACE, /* 9 \s */
- OP_NOT_WORDCHAR, /* 10 \W */
- OP_WORDCHAR, /* 11 \w */
-
- OP_ANY, /* 12 Match any character except newline (\N) */
- OP_ALLANY, /* 13 Match any character */
- OP_ANYBYTE, /* 14 Match any byte (\C); different to OP_ANY for UTF-8 */
- OP_NOTPROP, /* 15 \P (not Unicode property) */
- OP_PROP, /* 16 \p (Unicode property) */
- OP_ANYNL, /* 17 \R (any newline sequence) */
- OP_NOT_HSPACE, /* 18 \H (not horizontal whitespace) */
- OP_HSPACE, /* 19 \h (horizontal whitespace) */
- OP_NOT_VSPACE, /* 20 \V (not vertical whitespace) */
- OP_VSPACE, /* 21 \v (vertical whitespace) */
- OP_EXTUNI, /* 22 \X (extended Unicode sequence */
- OP_EODN, /* 23 End of data or \n at end of data (\Z) */
- OP_EOD, /* 24 End of data (\z) */
-
- /* Line end assertions */
-
- OP_DOLL, /* 25 End of line - not multiline */
- OP_DOLLM, /* 26 End of line - multiline */
- OP_CIRC, /* 27 Start of line - not multiline */
- OP_CIRCM, /* 28 Start of line - multiline */
-
- /* Single characters; caseful must precede the caseless ones, and these
- must remain in this order, and adjacent. */
-
- OP_CHAR, /* 29 Match one character, casefully */
- OP_CHARI, /* 30 Match one character, caselessly */
- OP_NOT, /* 31 Match one character, not the given one, casefully */
- OP_NOTI, /* 32 Match one character, not the given one, caselessly */
-
- /* The following sets of 13 opcodes must always be kept in step because
- the offset from the first one is used to generate the others. */
-
- /* Repeated characters; caseful must precede the caseless ones */
-
- OP_STAR, /* 33 The maximizing and minimizing versions of */
- OP_MINSTAR, /* 34 these six opcodes must come in pairs, with */
- OP_PLUS, /* 35 the minimizing one second. */
- OP_MINPLUS, /* 36 */
- OP_QUERY, /* 37 */
- OP_MINQUERY, /* 38 */
-
- OP_UPTO, /* 39 From 0 to n matches of one character, caseful*/
- OP_MINUPTO, /* 40 */
- OP_EXACT, /* 41 Exactly n matches */
-
- OP_POSSTAR, /* 42 Possessified star, caseful */
- OP_POSPLUS, /* 43 Possessified plus, caseful */
- OP_POSQUERY, /* 44 Posesssified query, caseful */
- OP_POSUPTO, /* 45 Possessified upto, caseful */
-
- /* Repeated characters; caseless must follow the caseful ones */
-
- OP_STARI, /* 46 */
- OP_MINSTARI, /* 47 */
- OP_PLUSI, /* 48 */
- OP_MINPLUSI, /* 49 */
- OP_QUERYI, /* 50 */
- OP_MINQUERYI, /* 51 */
-
- OP_UPTOI, /* 52 From 0 to n matches of one character, caseless */
- OP_MINUPTOI, /* 53 */
- OP_EXACTI, /* 54 */
-
- OP_POSSTARI, /* 55 Possessified star, caseless */
- OP_POSPLUSI, /* 56 Possessified plus, caseless */
- OP_POSQUERYI, /* 57 Posesssified query, caseless */
- OP_POSUPTOI, /* 58 Possessified upto, caseless */
-
- /* The negated ones must follow the non-negated ones, and match them */
- /* Negated repeated character, caseful; must precede the caseless ones */
-
- OP_NOTSTAR, /* 59 The maximizing and minimizing versions of */
- OP_NOTMINSTAR, /* 60 these six opcodes must come in pairs, with */
- OP_NOTPLUS, /* 61 the minimizing one second. They must be in */
- OP_NOTMINPLUS, /* 62 exactly the same order as those above. */
- OP_NOTQUERY, /* 63 */
- OP_NOTMINQUERY, /* 64 */
-
- OP_NOTUPTO, /* 65 From 0 to n matches, caseful */
- OP_NOTMINUPTO, /* 66 */
- OP_NOTEXACT, /* 67 Exactly n matches */
-
- OP_NOTPOSSTAR, /* 68 Possessified versions, caseful */
- OP_NOTPOSPLUS, /* 69 */
- OP_NOTPOSQUERY, /* 70 */
- OP_NOTPOSUPTO, /* 71 */
-
- /* Negated repeated character, caseless; must follow the caseful ones */
-
- OP_NOTSTARI, /* 72 */
- OP_NOTMINSTARI, /* 73 */
- OP_NOTPLUSI, /* 74 */
- OP_NOTMINPLUSI, /* 75 */
- OP_NOTQUERYI, /* 76 */
- OP_NOTMINQUERYI, /* 77 */
-
- OP_NOTUPTOI, /* 78 From 0 to n matches, caseless */
- OP_NOTMINUPTOI, /* 79 */
- OP_NOTEXACTI, /* 80 Exactly n matches */
-
- OP_NOTPOSSTARI, /* 81 Possessified versions, caseless */
- OP_NOTPOSPLUSI, /* 82 */
- OP_NOTPOSQUERYI, /* 83 */
- OP_NOTPOSUPTOI, /* 84 */
-
- /* Character types */
-
- OP_TYPESTAR, /* 85 The maximizing and minimizing versions of */
- OP_TYPEMINSTAR, /* 86 these six opcodes must come in pairs, with */
- OP_TYPEPLUS, /* 87 the minimizing one second. These codes must */
- OP_TYPEMINPLUS, /* 88 be in exactly the same order as those above. */
- OP_TYPEQUERY, /* 89 */
- OP_TYPEMINQUERY, /* 90 */
-
- OP_TYPEUPTO, /* 91 From 0 to n matches */
- OP_TYPEMINUPTO, /* 92 */
- OP_TYPEEXACT, /* 93 Exactly n matches */
-
- OP_TYPEPOSSTAR, /* 94 Possessified versions */
- OP_TYPEPOSPLUS, /* 95 */
- OP_TYPEPOSQUERY, /* 96 */
- OP_TYPEPOSUPTO, /* 97 */
-
- /* These are used for character classes and back references; only the
- first six are the same as the sets above. */
-
- OP_CRSTAR, /* 98 The maximizing and minimizing versions of */
- OP_CRMINSTAR, /* 99 all these opcodes must come in pairs, with */
- OP_CRPLUS, /* 100 the minimizing one second. These codes must */
- OP_CRMINPLUS, /* 101 be in exactly the same order as those above. */
- OP_CRQUERY, /* 102 */
- OP_CRMINQUERY, /* 103 */
-
- OP_CRRANGE, /* 104 These are different to the three sets above. */
- OP_CRMINRANGE, /* 105 */
-
- OP_CRPOSSTAR, /* 106 Possessified versions */
- OP_CRPOSPLUS, /* 107 */
- OP_CRPOSQUERY, /* 108 */
- OP_CRPOSRANGE, /* 109 */
-
- /* End of quantifier opcodes */
-
- OP_CLASS, /* 110 Match a character class, chars < 256 only */
- OP_NCLASS, /* 111 Same, but the bitmap was created from a negative
- class - the difference is relevant only when a
- character > 255 is encountered. */
- OP_XCLASS, /* 112 Extended class for handling > 255 chars within the
- class. This does both positive and negative. */
- OP_REF, /* 113 Match a back reference, casefully */
- OP_REFI, /* 114 Match a back reference, caselessly */
- OP_DNREF, /* 115 Match a duplicate name backref, casefully */
- OP_DNREFI, /* 116 Match a duplicate name backref, caselessly */
- OP_RECURSE, /* 117 Match a numbered subpattern (possibly recursive) */
- OP_CALLOUT, /* 118 Call out to external function if provided */
- OP_CALLOUT_STR, /* 119 Call out with string argument */
-
- OP_ALT, /* 120 Start of alternation */
- OP_KET, /* 121 End of group that doesn't have an unbounded repeat */
- OP_KETRMAX, /* 122 These two must remain together and in this */
- OP_KETRMIN, /* 123 order. They are for groups the repeat for ever. */
- OP_KETRPOS, /* 124 Possessive unlimited repeat. */
-
- /* The assertions must come before BRA, CBRA, ONCE, and COND. */
-
- OP_REVERSE, /* 125 Move pointer back - used in lookbehind assertions */
- OP_ASSERT, /* 126 Positive lookahead */
- OP_ASSERT_NOT, /* 127 Negative lookahead */
- OP_ASSERTBACK, /* 128 Positive lookbehind */
- OP_ASSERTBACK_NOT, /* 129 Negative lookbehind */
- OP_ASSERT_NA, /* 130 Positive non-atomic lookahead */
- OP_ASSERTBACK_NA, /* 131 Positive non-atomic lookbehind */
-
- /* ONCE, SCRIPT_RUN, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come
- immediately after the assertions, with ONCE first, as there's a test for >=
- ONCE for a subpattern that isn't an assertion. The POS versions must
- immediately follow the non-POS versions in each case. */
-
- OP_ONCE, /* 132 Atomic group, contains captures */
- OP_SCRIPT_RUN, /* 133 Non-capture, but check characters' scripts */
- OP_BRA, /* 134 Start of non-capturing bracket */
- OP_BRAPOS, /* 135 Ditto, with unlimited, possessive repeat */
- OP_CBRA, /* 136 Start of capturing bracket */
- OP_CBRAPOS, /* 137 Ditto, with unlimited, possessive repeat */
- OP_COND, /* 138 Conditional group */
-
- /* These five must follow the previous five, in the same order. There's a
- check for >= SBRA to distinguish the two sets. */
-
- OP_SBRA, /* 139 Start of non-capturing bracket, check empty */
- OP_SBRAPOS, /* 149 Ditto, with unlimited, possessive repeat */
- OP_SCBRA, /* 141 Start of capturing bracket, check empty */
- OP_SCBRAPOS, /* 142 Ditto, with unlimited, possessive repeat */
- OP_SCOND, /* 143 Conditional group, check empty */
-
- /* The next two pairs must (respectively) be kept together. */
-
- OP_CREF, /* 144 Used to hold a capture number as condition */
- OP_DNCREF, /* 145 Used to point to duplicate names as a condition */
- OP_RREF, /* 146 Used to hold a recursion number as condition */
- OP_DNRREF, /* 147 Used to point to duplicate names as a condition */
- OP_FALSE, /* 148 Always false (used by DEFINE and VERSION) */
- OP_TRUE, /* 149 Always true (used by VERSION) */
-
- OP_BRAZERO, /* 150 These two must remain together and in this */
- OP_BRAMINZERO, /* 151 order. */
- OP_BRAPOSZERO, /* 152 */
-
- /* These are backtracking control verbs */
-
- OP_MARK, /* 153 always has an argument */
- OP_PRUNE, /* 154 */
- OP_PRUNE_ARG, /* 155 same, but with argument */
- OP_SKIP, /* 156 */
- OP_SKIP_ARG, /* 157 same, but with argument */
- OP_THEN, /* 158 */
- OP_THEN_ARG, /* 159 same, but with argument */
- OP_COMMIT, /* 160 */
- OP_COMMIT_ARG, /* 161 same, but with argument */
-
- /* These are forced failure and success verbs. FAIL and ACCEPT do accept an
- argument, but these cases can be compiled as, for example, (*MARK:X)(*FAIL)
- without the need for a special opcode. */
-
- OP_FAIL, /* 162 */
- OP_ACCEPT, /* 163 */
- OP_ASSERT_ACCEPT, /* 164 Used inside assertions */
- OP_CLOSE, /* 165 Used before OP_ACCEPT to close open captures */
-
- /* This is used to skip a subpattern with a {0} quantifier */
-
- OP_SKIPZERO, /* 166 */
-
- /* This is used to identify a DEFINE group during compilation so that it can
- be checked for having only one branch. It is changed to OP_FALSE before
- compilation finishes. */
-
- OP_DEFINE, /* 167 */
-
- /* This is not an opcode, but is used to check that tables indexed by opcode
- are the correct length, in order to catch updating errors - there have been
- some in the past. */
-
- OP_TABLE_LENGTH
-
-};
-
-/* *** NOTE NOTE NOTE *** Whenever the list above is updated, the two macro
-definitions that follow must also be updated to match. There are also tables
-called "opcode_possessify" in pcre2_compile.c and "coptable" and "poptable" in
-pcre2_dfa_match.c that must be updated. */
-
-
-/* This macro defines textual names for all the opcodes. These are used only
-for debugging, and some of them are only partial names. The macro is referenced
-only in pcre2_printint.c, which fills out the full names in many cases (and in
-some cases doesn't actually use these names at all). */
-
-#define OP_NAME_LIST \
- "End", "\\A", "\\G", "\\K", "\\B", "\\b", "\\D", "\\d", \
- "\\S", "\\s", "\\W", "\\w", "Any", "AllAny", "Anybyte", \
- "notprop", "prop", "\\R", "\\H", "\\h", "\\V", "\\v", \
- "extuni", "\\Z", "\\z", \
- "$", "$", "^", "^", "char", "chari", "not", "noti", \
- "*", "*?", "+", "+?", "?", "??", \
- "{", "{", "{", \
- "*+","++", "?+", "{", \
- "*", "*?", "+", "+?", "?", "??", \
- "{", "{", "{", \
- "*+","++", "?+", "{", \
- "*", "*?", "+", "+?", "?", "??", \
- "{", "{", "{", \
- "*+","++", "?+", "{", \
- "*", "*?", "+", "+?", "?", "??", \
- "{", "{", "{", \
- "*+","++", "?+", "{", \
- "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
- "*+","++", "?+", "{", \
- "*", "*?", "+", "+?", "?", "??", "{", "{", \
- "*+","++", "?+", "{", \
- "class", "nclass", "xclass", "Ref", "Refi", "DnRef", "DnRefi", \
- "Recurse", "Callout", "CalloutStr", \
- "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \
- "Reverse", "Assert", "Assert not", \
- "Assert back", "Assert back not", \
- "Non-atomic assert", "Non-atomic assert back", \
- "Once", \
- "Script run", \
- "Bra", "BraPos", "CBra", "CBraPos", \
- "Cond", \
- "SBra", "SBraPos", "SCBra", "SCBraPos", \
- "SCond", \
- "Cond ref", "Cond dnref", "Cond rec", "Cond dnrec", \
- "Cond false", "Cond true", \
- "Brazero", "Braminzero", "Braposzero", \
- "*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP", \
- "*THEN", "*THEN", "*COMMIT", "*COMMIT", "*FAIL", \
- "*ACCEPT", "*ASSERT_ACCEPT", \
- "Close", "Skip zero", "Define"
-
-
-/* This macro defines the length of fixed length operations in the compiled
-regex. The lengths are used when searching for specific things, and also in the
-debugging printing of a compiled regex. We use a macro so that it can be
-defined close to the definitions of the opcodes themselves.
-
-As things have been extended, some of these are no longer fixed lenths, but are
-minima instead. For example, the length of a single-character repeat may vary
-in UTF-8 mode. The code that uses this table must know about such things. */
-
-#define OP_LENGTHS \
- 1, /* End */ \
- 1, 1, 1, 1, 1, /* \A, \G, \K, \B, \b */ \
- 1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */ \
- 1, 1, 1, /* Any, AllAny, Anybyte */ \
- 3, 3, /* \P, \p */ \
- 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ \
- 1, /* \X */ \
- 1, 1, 1, 1, 1, 1, /* \Z, \z, $, $M ^, ^M */ \
- 2, /* Char - the minimum length */ \
- 2, /* Chari - the minimum length */ \
- 2, /* not */ \
- 2, /* noti */ \
- /* Positive single-char repeats ** These are */ \
- 2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** minima in */ \
- 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto, minupto ** mode */ \
- 2+IMM2_SIZE, /* exact */ \
- 2, 2, 2, 2+IMM2_SIZE, /* *+, ++, ?+, upto+ */ \
- 2, 2, 2, 2, 2, 2, /* *I, *?I, +I, +?I, ?I, ??I ** UTF-8 */ \
- 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto I, minupto I */ \
- 2+IMM2_SIZE, /* exact I */ \
- 2, 2, 2, 2+IMM2_SIZE, /* *+I, ++I, ?+I, upto+I */ \
- /* Negative single-char repeats - only for chars < 256 */ \
- 2, 2, 2, 2, 2, 2, /* NOT *, *?, +, +?, ?, ?? */ \
- 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto, minupto */ \
- 2+IMM2_SIZE, /* NOT exact */ \
- 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *, +, ?, upto */ \
- 2, 2, 2, 2, 2, 2, /* NOT *I, *?I, +I, +?I, ?I, ??I */ \
- 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto I, minupto I */ \
- 2+IMM2_SIZE, /* NOT exact I */ \
- 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *I, +I, ?I, upto I */ \
- /* Positive type repeats */ \
- 2, 2, 2, 2, 2, 2, /* Type *, *?, +, +?, ?, ?? */ \
- 2+IMM2_SIZE, 2+IMM2_SIZE, /* Type upto, minupto */ \
- 2+IMM2_SIZE, /* Type exact */ \
- 2, 2, 2, 2+IMM2_SIZE, /* Possessive *+, ++, ?+, upto+ */ \
- /* Character class & ref repeats */ \
- 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ \
- 1+2*IMM2_SIZE, 1+2*IMM2_SIZE, /* CRRANGE, CRMINRANGE */ \
- 1, 1, 1, 1+2*IMM2_SIZE, /* Possessive *+, ++, ?+, CRPOSRANGE */ \
- 1+(32/sizeof(PCRE2_UCHAR)), /* CLASS */ \
- 1+(32/sizeof(PCRE2_UCHAR)), /* NCLASS */ \
- 0, /* XCLASS - variable length */ \
- 1+IMM2_SIZE, /* REF */ \
- 1+IMM2_SIZE, /* REFI */ \
- 1+2*IMM2_SIZE, /* DNREF */ \
- 1+2*IMM2_SIZE, /* DNREFI */ \
- 1+LINK_SIZE, /* RECURSE */ \
- 1+2*LINK_SIZE+1, /* CALLOUT */ \
- 0, /* CALLOUT_STR - variable length */ \
- 1+LINK_SIZE, /* Alt */ \
- 1+LINK_SIZE, /* Ket */ \
- 1+LINK_SIZE, /* KetRmax */ \
- 1+LINK_SIZE, /* KetRmin */ \
- 1+LINK_SIZE, /* KetRpos */ \
- 1+LINK_SIZE, /* Reverse */ \
- 1+LINK_SIZE, /* Assert */ \
- 1+LINK_SIZE, /* Assert not */ \
- 1+LINK_SIZE, /* Assert behind */ \
- 1+LINK_SIZE, /* Assert behind not */ \
- 1+LINK_SIZE, /* NA Assert */ \
- 1+LINK_SIZE, /* NA Assert behind */ \
- 1+LINK_SIZE, /* ONCE */ \
- 1+LINK_SIZE, /* SCRIPT_RUN */ \
- 1+LINK_SIZE, /* BRA */ \
- 1+LINK_SIZE, /* BRAPOS */ \
- 1+LINK_SIZE+IMM2_SIZE, /* CBRA */ \
- 1+LINK_SIZE+IMM2_SIZE, /* CBRAPOS */ \
- 1+LINK_SIZE, /* COND */ \
- 1+LINK_SIZE, /* SBRA */ \
- 1+LINK_SIZE, /* SBRAPOS */ \
- 1+LINK_SIZE+IMM2_SIZE, /* SCBRA */ \
- 1+LINK_SIZE+IMM2_SIZE, /* SCBRAPOS */ \
- 1+LINK_SIZE, /* SCOND */ \
- 1+IMM2_SIZE, 1+2*IMM2_SIZE, /* CREF, DNCREF */ \
- 1+IMM2_SIZE, 1+2*IMM2_SIZE, /* RREF, DNRREF */ \
- 1, 1, /* FALSE, TRUE */ \
- 1, 1, 1, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ \
- 3, 1, 3, /* MARK, PRUNE, PRUNE_ARG */ \
- 1, 3, /* SKIP, SKIP_ARG */ \
- 1, 3, /* THEN, THEN_ARG */ \
- 1, 3, /* COMMIT, COMMIT_ARG */ \
- 1, 1, 1, /* FAIL, ACCEPT, ASSERT_ACCEPT */ \
- 1+IMM2_SIZE, 1, /* CLOSE, SKIPZERO */ \
- 1 /* DEFINE */
-
-/* A magic value for OP_RREF to indicate the "any recursion" condition. */
-
-#define RREF_ANY 0xffff
-
-
-/* ---------- Private structures that are mode-independent. ---------- */
-
-/* Structure to hold data for custom memory management. */
-
-typedef struct pcre2_memctl {
- void * (*malloc)(size_t, void *);
- void (*free)(void *, void *);
- void *memory_data;
-} pcre2_memctl;
-
-/* Structure for building a chain of open capturing subpatterns during
-compiling, so that instructions to close them can be compiled when (*ACCEPT) is
-encountered. */
-
-typedef struct open_capitem {
- struct open_capitem *next; /* Chain link */
- uint16_t number; /* Capture number */
- uint16_t assert_depth; /* Assertion depth when opened */
-} open_capitem;
-
-/* Layout of the UCP type table that translates property names into types and
-codes. Each entry used to point directly to a name, but to reduce the number of
-relocations in shared libraries, it now has an offset into a single string
-instead. */
-
-typedef struct {
- uint16_t name_offset;
- uint16_t type;
- uint16_t value;
-} ucp_type_table;
-
-/* Unicode character database (UCD) record format */
-
-typedef struct {
- uint8_t script; /* ucp_Arabic, etc. */
- uint8_t chartype; /* ucp_Cc, etc. (general categories) */
- uint8_t gbprop; /* ucp_gbControl, etc. (grapheme break property) */
- uint8_t caseset; /* offset to multichar other cases or zero */
- int32_t other_case; /* offset to other case, or zero if none */
- uint16_t scriptx_bidiclass; /* script extension (11 bit) and bidi class (5 bit) values */
- uint16_t bprops; /* binary properties offset */
-} ucd_record;
-
-/* UCD access macros */
-
-#define UCD_BLOCK_SIZE 128
-#define REAL_GET_UCD(ch) (PRIV(ucd_records) + \
- PRIV(ucd_stage2)[PRIV(ucd_stage1)[(int)(ch) / UCD_BLOCK_SIZE] * \
- UCD_BLOCK_SIZE + (int)(ch) % UCD_BLOCK_SIZE])
-
-#if PCRE2_CODE_UNIT_WIDTH == 32
-#define GET_UCD(ch) ((ch > MAX_UTF_CODE_POINT)? \
- PRIV(dummy_ucd_record) : REAL_GET_UCD(ch))
-#else
-#define GET_UCD(ch) REAL_GET_UCD(ch)
-#endif
-
-#define UCD_SCRIPTX_MASK 0x3ff
-#define UCD_BIDICLASS_SHIFT 11
-#define UCD_BPROPS_MASK 0xfff
-
-#define UCD_SCRIPTX_PROP(prop) ((prop)->scriptx_bidiclass & UCD_SCRIPTX_MASK)
-#define UCD_BIDICLASS_PROP(prop) ((prop)->scriptx_bidiclass >> UCD_BIDICLASS_SHIFT)
-#define UCD_BPROPS_PROP(prop) ((prop)->bprops & UCD_BPROPS_MASK)
-
-#define UCD_CHARTYPE(ch) GET_UCD(ch)->chartype
-#define UCD_SCRIPT(ch) GET_UCD(ch)->script
-#define UCD_CATEGORY(ch) PRIV(ucp_gentype)[UCD_CHARTYPE(ch)]
-#define UCD_GRAPHBREAK(ch) GET_UCD(ch)->gbprop
-#define UCD_CASESET(ch) GET_UCD(ch)->caseset
-#define UCD_OTHERCASE(ch) ((uint32_t)((int)ch + (int)(GET_UCD(ch)->other_case)))
-#define UCD_SCRIPTX(ch) UCD_SCRIPTX_PROP(GET_UCD(ch))
-#define UCD_BPROPS(ch) UCD_BPROPS_PROP(GET_UCD(ch))
-#define UCD_BIDICLASS(ch) UCD_BIDICLASS_PROP(GET_UCD(ch))
-
-/* The "scriptx" and bprops fields contain offsets into vectors of 32-bit words
-that form a bitmap representing a list of scripts or boolean properties. These
-macros test or set a bit in the map by number. */
-
-#define MAPBIT(map,n) ((map)[(n)/32]&(1u<<((n)%32)))
-#define MAPSET(map,n) ((map)[(n)/32]|=(1u<<((n)%32)))
-
-/* Header for serialized pcre2 codes. */
-
-typedef struct pcre2_serialized_data {
- uint32_t magic;
- uint32_t version;
- uint32_t config;
- int32_t number_of_codes;
-} pcre2_serialized_data;
-
-
-
-/* ----------------- Items that need PCRE2_CODE_UNIT_WIDTH ----------------- */
-
-/* When this file is included by pcre2test, PCRE2_CODE_UNIT_WIDTH is defined as
-0, so the following items are omitted. */
-
-#if defined PCRE2_CODE_UNIT_WIDTH && PCRE2_CODE_UNIT_WIDTH != 0
-
-/* EBCDIC is supported only for the 8-bit library. */
-
-#if defined EBCDIC && PCRE2_CODE_UNIT_WIDTH != 8
-#error EBCDIC is not supported for the 16-bit or 32-bit libraries
-#endif
-
-/* This is the largest non-UTF code point. */
-
-#define MAX_NON_UTF_CHAR (0xffffffffU >> (32 - PCRE2_CODE_UNIT_WIDTH))
-
-/* Internal shared data tables and variables. These are used by more than one
-of the exported public functions. They have to be "external" in the C sense,
-but are not part of the PCRE2 public API. Although the data for some of them is
-identical in all libraries, they must have different names so that multiple
-libraries can be simultaneously linked to a single application. However, UTF-8
-tables are needed only when compiling the 8-bit library. */
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
-extern const int PRIV(utf8_table1)[];
-extern const int PRIV(utf8_table1_size);
-extern const int PRIV(utf8_table2)[];
-extern const int PRIV(utf8_table3)[];
-extern const uint8_t PRIV(utf8_table4)[];
-#endif
-
-#define _pcre2_OP_lengths PCRE2_SUFFIX(_pcre2_OP_lengths_)
-#define _pcre2_callout_end_delims PCRE2_SUFFIX(_pcre2_callout_end_delims_)
-#define _pcre2_callout_start_delims PCRE2_SUFFIX(_pcre2_callout_start_delims_)
-#define _pcre2_default_compile_context PCRE2_SUFFIX(_pcre2_default_compile_context_)
-#define _pcre2_default_convert_context PCRE2_SUFFIX(_pcre2_default_convert_context_)
-#define _pcre2_default_match_context PCRE2_SUFFIX(_pcre2_default_match_context_)
-#define _pcre2_default_tables PCRE2_SUFFIX(_pcre2_default_tables_)
-#if PCRE2_CODE_UNIT_WIDTH == 32
-#define _pcre2_dummy_ucd_record PCRE2_SUFFIX(_pcre2_dummy_ucd_record_)
-#endif
-#define _pcre2_hspace_list PCRE2_SUFFIX(_pcre2_hspace_list_)
-#define _pcre2_vspace_list PCRE2_SUFFIX(_pcre2_vspace_list_)
-#define _pcre2_ucd_boolprop_sets PCRE2_SUFFIX(_pcre2_ucd_boolprop_sets_)
-#define _pcre2_ucd_caseless_sets PCRE2_SUFFIX(_pcre2_ucd_caseless_sets_)
-#define _pcre2_ucd_digit_sets PCRE2_SUFFIX(_pcre2_ucd_digit_sets_)
-#define _pcre2_ucd_script_sets PCRE2_SUFFIX(_pcre2_ucd_script_sets_)
-#define _pcre2_ucd_records PCRE2_SUFFIX(_pcre2_ucd_records_)
-#define _pcre2_ucd_stage1 PCRE2_SUFFIX(_pcre2_ucd_stage1_)
-#define _pcre2_ucd_stage2 PCRE2_SUFFIX(_pcre2_ucd_stage2_)
-#define _pcre2_ucp_gbtable PCRE2_SUFFIX(_pcre2_ucp_gbtable_)
-#define _pcre2_ucp_gentype PCRE2_SUFFIX(_pcre2_ucp_gentype_)
-#define _pcre2_ucp_typerange PCRE2_SUFFIX(_pcre2_ucp_typerange_)
-#define _pcre2_unicode_version PCRE2_SUFFIX(_pcre2_unicode_version_)
-#define _pcre2_utt PCRE2_SUFFIX(_pcre2_utt_)
-#define _pcre2_utt_names PCRE2_SUFFIX(_pcre2_utt_names_)
-#define _pcre2_utt_size PCRE2_SUFFIX(_pcre2_utt_size_)
-
-extern const uint8_t PRIV(OP_lengths)[];
-extern const uint32_t PRIV(callout_end_delims)[];
-extern const uint32_t PRIV(callout_start_delims)[];
-extern const pcre2_compile_context PRIV(default_compile_context);
-extern const pcre2_convert_context PRIV(default_convert_context);
-extern const pcre2_match_context PRIV(default_match_context);
-extern const uint8_t PRIV(default_tables)[];
-extern const uint32_t PRIV(hspace_list)[];
-extern const uint32_t PRIV(vspace_list)[];
-extern const uint32_t PRIV(ucd_boolprop_sets)[];
-extern const uint32_t PRIV(ucd_caseless_sets)[];
-extern const uint32_t PRIV(ucd_digit_sets)[];
-extern const uint32_t PRIV(ucd_script_sets)[];
-extern const ucd_record PRIV(ucd_records)[];
-#if PCRE2_CODE_UNIT_WIDTH == 32
-extern const ucd_record PRIV(dummy_ucd_record)[];
-#endif
-extern const uint16_t PRIV(ucd_stage1)[];
-extern const uint16_t PRIV(ucd_stage2)[];
-extern const uint32_t PRIV(ucp_gbtable)[];
-extern const uint32_t PRIV(ucp_gentype)[];
-#ifdef SUPPORT_JIT
-extern const int PRIV(ucp_typerange)[];
-#endif
-extern const char *PRIV(unicode_version);
-extern const ucp_type_table PRIV(utt)[];
-extern const char PRIV(utt_names)[];
-extern const size_t PRIV(utt_size);
-
-/* Mode-dependent macros and hidden and private structures are defined in a
-separate file so that pcre2test can include them at all supported widths. When
-compiling the library, PCRE2_CODE_UNIT_WIDTH will be defined, and we can
-include them at the appropriate width, after setting up suffix macros for the
-private structures. */
-
-#define branch_chain PCRE2_SUFFIX(branch_chain_)
-#define compile_block PCRE2_SUFFIX(compile_block_)
-#define dfa_match_block PCRE2_SUFFIX(dfa_match_block_)
-#define match_block PCRE2_SUFFIX(match_block_)
-#define named_group PCRE2_SUFFIX(named_group_)
-
-#include "pcre2_intmodedep.h"
-
-/* Private "external" functions. These are internal functions that are called
-from modules other than the one in which they are defined. They have to be
-"external" in the C sense, but are not part of the PCRE2 public API. They are
-not referenced from pcre2test, and must not be defined when no code unit width
-is available. */
-
-#define _pcre2_auto_possessify PCRE2_SUFFIX(_pcre2_auto_possessify_)
-#define _pcre2_check_escape PCRE2_SUFFIX(_pcre2_check_escape_)
-#define _pcre2_extuni PCRE2_SUFFIX(_pcre2_extuni_)
-#define _pcre2_find_bracket PCRE2_SUFFIX(_pcre2_find_bracket_)
-#define _pcre2_is_newline PCRE2_SUFFIX(_pcre2_is_newline_)
-#define _pcre2_jit_free_rodata PCRE2_SUFFIX(_pcre2_jit_free_rodata_)
-#define _pcre2_jit_free PCRE2_SUFFIX(_pcre2_jit_free_)
-#define _pcre2_jit_get_size PCRE2_SUFFIX(_pcre2_jit_get_size_)
-#define _pcre2_jit_get_target PCRE2_SUFFIX(_pcre2_jit_get_target_)
-#define _pcre2_memctl_malloc PCRE2_SUFFIX(_pcre2_memctl_malloc_)
-#define _pcre2_ord2utf PCRE2_SUFFIX(_pcre2_ord2utf_)
-#define _pcre2_script_run PCRE2_SUFFIX(_pcre2_script_run_)
-#define _pcre2_strcmp PCRE2_SUFFIX(_pcre2_strcmp_)
-#define _pcre2_strcmp_c8 PCRE2_SUFFIX(_pcre2_strcmp_c8_)
-#define _pcre2_strcpy_c8 PCRE2_SUFFIX(_pcre2_strcpy_c8_)
-#define _pcre2_strlen PCRE2_SUFFIX(_pcre2_strlen_)
-#define _pcre2_strncmp PCRE2_SUFFIX(_pcre2_strncmp_)
-#define _pcre2_strncmp_c8 PCRE2_SUFFIX(_pcre2_strncmp_c8_)
-#define _pcre2_study PCRE2_SUFFIX(_pcre2_study_)
-#define _pcre2_valid_utf PCRE2_SUFFIX(_pcre2_valid_utf_)
-#define _pcre2_was_newline PCRE2_SUFFIX(_pcre2_was_newline_)
-#define _pcre2_xclass PCRE2_SUFFIX(_pcre2_xclass_)
-
-extern int _pcre2_auto_possessify(PCRE2_UCHAR *,
- const compile_block *);
-extern int _pcre2_check_escape(PCRE2_SPTR *, PCRE2_SPTR, uint32_t *,
- int *, uint32_t, uint32_t, BOOL, compile_block *);
-extern PCRE2_SPTR _pcre2_extuni(uint32_t, PCRE2_SPTR, PCRE2_SPTR, PCRE2_SPTR,
- BOOL, int *);
-extern PCRE2_SPTR _pcre2_find_bracket(PCRE2_SPTR, BOOL, int);
-extern BOOL _pcre2_is_newline(PCRE2_SPTR, uint32_t, PCRE2_SPTR,
- uint32_t *, BOOL);
-extern void _pcre2_jit_free_rodata(void *, void *);
-extern void _pcre2_jit_free(void *, pcre2_memctl *);
-extern size_t _pcre2_jit_get_size(void *);
-const char * _pcre2_jit_get_target(void);
-extern void * _pcre2_memctl_malloc(size_t, pcre2_memctl *);
-extern unsigned int _pcre2_ord2utf(uint32_t, PCRE2_UCHAR *);
-extern BOOL _pcre2_script_run(PCRE2_SPTR, PCRE2_SPTR, BOOL);
-extern int _pcre2_strcmp(PCRE2_SPTR, PCRE2_SPTR);
-extern int _pcre2_strcmp_c8(PCRE2_SPTR, const char *);
-extern PCRE2_SIZE _pcre2_strcpy_c8(PCRE2_UCHAR *, const char *);
-extern PCRE2_SIZE _pcre2_strlen(PCRE2_SPTR);
-extern int _pcre2_strncmp(PCRE2_SPTR, PCRE2_SPTR, size_t);
-extern int _pcre2_strncmp_c8(PCRE2_SPTR, const char *, size_t);
-extern int _pcre2_study(pcre2_real_code *);
-extern int _pcre2_valid_utf(PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE *);
-extern BOOL _pcre2_was_newline(PCRE2_SPTR, uint32_t, PCRE2_SPTR,
- uint32_t *, BOOL);
-extern BOOL _pcre2_xclass(uint32_t, PCRE2_SPTR, BOOL);
-
-/* This function is needed only when memmove() is not available. */
-
-#if !defined(VPCOMPAT) && !defined(HAVE_MEMMOVE)
-#define _pcre2_memmove PCRE2_SUFFIX(_pcre2_memmove)
-extern void * _pcre2_memmove(void *, const void *, size_t);
-#endif
-
-#endif /* PCRE2_CODE_UNIT_WIDTH */
-#endif /* PCRE2_INTERNAL_H_IDEMPOTENT_GUARD */
-
-/* End of pcre2_internal.h */
diff --git a/contrib/libs/pcre2/src/pcre2_intmodedep.h b/contrib/libs/pcre2/src/pcre2_intmodedep.h
deleted file mode 100644
index 390e737a6e..0000000000
--- a/contrib/libs/pcre2/src/pcre2_intmodedep.h
+++ /dev/null
@@ -1,934 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2022 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains mode-dependent macro and structure definitions. The
-file is #included by pcre2_internal.h if PCRE2_CODE_UNIT_WIDTH is defined.
-These mode-dependent items are kept in a separate file so that they can also be
-#included multiple times for different code unit widths by pcre2test in order
-to have access to the hidden structures at all supported widths.
-
-Some of the mode-dependent macros are required at different widths for
-different parts of the pcre2test code (in particular, the included
-pcre_printint.c file). We undefine them here so that they can be re-defined for
-multiple inclusions. Not all of these are used in pcre2test, but it's easier
-just to undefine them all. */
-
-#undef ACROSSCHAR
-#undef BACKCHAR
-#undef BYTES2CU
-#undef CHMAX_255
-#undef CU2BYTES
-#undef FORWARDCHAR
-#undef FORWARDCHARTEST
-#undef GET
-#undef GET2
-#undef GETCHAR
-#undef GETCHARINC
-#undef GETCHARINCTEST
-#undef GETCHARLEN
-#undef GETCHARLENTEST
-#undef GETCHARTEST
-#undef GET_EXTRALEN
-#undef HAS_EXTRALEN
-#undef IMM2_SIZE
-#undef MAX_255
-#undef MAX_MARK
-#undef MAX_PATTERN_SIZE
-#undef MAX_UTF_SINGLE_CU
-#undef NOT_FIRSTCU
-#undef PUT
-#undef PUT2
-#undef PUT2INC
-#undef PUTCHAR
-#undef PUTINC
-#undef TABLE_GET
-
-
-
-/* -------------------------- MACROS ----------------------------- */
-
-/* PCRE keeps offsets in its compiled code as at least 16-bit quantities
-(always stored in big-endian order in 8-bit mode) by default. These are used,
-for example, to link from the start of a subpattern to its alternatives and its
-end. The use of 16 bits per offset limits the size of an 8-bit compiled regex
-to around 64K, which is big enough for almost everybody. However, I received a
-request for an even bigger limit. For this reason, and also to make the code
-easier to maintain, the storing and loading of offsets from the compiled code
-unit string is now handled by the macros that are defined here.
-
-The macros are controlled by the value of LINK_SIZE. This defaults to 2, but
-values of 3 or 4 are also supported. */
-
-/* ------------------- 8-bit support ------------------ */
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
-
-#if LINK_SIZE == 2
-#define PUT(a,n,d) \
- (a[n] = (PCRE2_UCHAR)((d) >> 8)), \
- (a[(n)+1] = (PCRE2_UCHAR)((d) & 255))
-#define GET(a,n) \
- (unsigned int)(((a)[n] << 8) | (a)[(n)+1])
-#define MAX_PATTERN_SIZE (1 << 16)
-
-#elif LINK_SIZE == 3
-#define PUT(a,n,d) \
- (a[n] = (PCRE2_UCHAR)((d) >> 16)), \
- (a[(n)+1] = (PCRE2_UCHAR)((d) >> 8)), \
- (a[(n)+2] = (PCRE2_UCHAR)((d) & 255))
-#define GET(a,n) \
- (unsigned int)(((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2])
-#define MAX_PATTERN_SIZE (1 << 24)
-
-#elif LINK_SIZE == 4
-#define PUT(a,n,d) \
- (a[n] = (PCRE2_UCHAR)((d) >> 24)), \
- (a[(n)+1] = (PCRE2_UCHAR)((d) >> 16)), \
- (a[(n)+2] = (PCRE2_UCHAR)((d) >> 8)), \
- (a[(n)+3] = (PCRE2_UCHAR)((d) & 255))
-#define GET(a,n) \
- (unsigned int)(((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3])
-#define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */
-
-#else
-#error LINK_SIZE must be 2, 3, or 4
-#endif
-
-
-/* ------------------- 16-bit support ------------------ */
-
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-
-#if LINK_SIZE == 2
-#undef LINK_SIZE
-#define LINK_SIZE 1
-#define PUT(a,n,d) \
- (a[n] = (PCRE2_UCHAR)(d))
-#define GET(a,n) \
- (a[n])
-#define MAX_PATTERN_SIZE (1 << 16)
-
-#elif LINK_SIZE == 3 || LINK_SIZE == 4
-#undef LINK_SIZE
-#define LINK_SIZE 2
-#define PUT(a,n,d) \
- (a[n] = (PCRE2_UCHAR)((d) >> 16)), \
- (a[(n)+1] = (PCRE2_UCHAR)((d) & 65535))
-#define GET(a,n) \
- (unsigned int)(((a)[n] << 16) | (a)[(n)+1])
-#define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */
-
-#else
-#error LINK_SIZE must be 2, 3, or 4
-#endif
-
-
-/* ------------------- 32-bit support ------------------ */
-
-#elif PCRE2_CODE_UNIT_WIDTH == 32
-#undef LINK_SIZE
-#define LINK_SIZE 1
-#define PUT(a,n,d) \
- (a[n] = (d))
-#define GET(a,n) \
- (a[n])
-#define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */
-
-#else
-#error Unsupported compiling mode
-#endif
-
-
-/* --------------- Other mode-specific macros ----------------- */
-
-/* PCRE uses some other (at least) 16-bit quantities that do not change when
-the size of offsets changes. There are used for repeat counts and for other
-things such as capturing parenthesis numbers in back references.
-
-Define the number of code units required to hold a 16-bit count/offset, and
-macros to load and store such a value. For reasons that I do not understand,
-the expression in the 8-bit GET2 macro is treated by gcc as a signed
-expression, even when a is declared as unsigned. It seems that any kind of
-arithmetic results in a signed value. Hence the cast. */
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
-#define IMM2_SIZE 2
-#define GET2(a,n) (unsigned int)(((a)[n] << 8) | (a)[(n)+1])
-#define PUT2(a,n,d) a[n] = (d) >> 8, a[(n)+1] = (d) & 255
-
-#else /* Code units are 16 or 32 bits */
-#define IMM2_SIZE 1
-#define GET2(a,n) a[n]
-#define PUT2(a,n,d) a[n] = d
-#endif
-
-/* Other macros that are different for 8-bit mode. The MAX_255 macro checks
-whether its argument, which is assumed to be one code unit, is less than 256.
-The CHMAX_255 macro does not assume one code unit. The maximum length of a MARK
-name must fit in one code unit; currently it is set to 255 or 65535. The
-TABLE_GET macro is used to access elements of tables containing exactly 256
-items. Its argument is a code unit. When code points can be greater than 255, a
-check is needed before accessing these tables. */
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
-#define MAX_255(c) TRUE
-#define MAX_MARK ((1u << 8) - 1)
-#define TABLE_GET(c, table, default) ((table)[c])
-#ifdef SUPPORT_UNICODE
-#define SUPPORT_WIDE_CHARS
-#define CHMAX_255(c) ((c) <= 255u)
-#else
-#define CHMAX_255(c) TRUE
-#endif /* SUPPORT_UNICODE */
-
-#else /* Code units are 16 or 32 bits */
-#define CHMAX_255(c) ((c) <= 255u)
-#define MAX_255(c) ((c) <= 255u)
-#define MAX_MARK ((1u << 16) - 1)
-#define SUPPORT_WIDE_CHARS
-#define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default))
-#endif
-
-
-/* ----------------- Character-handling macros ----------------- */
-
-/* There is a proposed future special "UTF-21" mode, in which only the lowest
-21 bits of a 32-bit character are interpreted as UTF, with the remaining 11
-high-order bits available to the application for other uses. In preparation for
-the future implementation of this mode, there are macros that load a data item
-and, if in this special mode, mask it to 21 bits. These macros all have names
-starting with UCHAR21. In all other modes, including the normal 32-bit
-library, the macros all have the same simple definitions. When the new mode is
-implemented, it is expected that these definitions will be varied appropriately
-using #ifdef when compiling the library that supports the special mode. */
-
-#define UCHAR21(eptr) (*(eptr))
-#define UCHAR21TEST(eptr) (*(eptr))
-#define UCHAR21INC(eptr) (*(eptr)++)
-#define UCHAR21INCTEST(eptr) (*(eptr)++)
-
-/* When UTF encoding is being used, a character is no longer just a single
-byte in 8-bit mode or a single short in 16-bit mode. The macros for character
-handling generate simple sequences when used in the basic mode, and more
-complicated ones for UTF characters. GETCHARLENTEST and other macros are not
-used when UTF is not supported. To make sure they can never even appear when
-UTF support is omitted, we don't even define them. */
-
-#ifndef SUPPORT_UNICODE
-
-/* #define MAX_UTF_SINGLE_CU */
-/* #define HAS_EXTRALEN(c) */
-/* #define GET_EXTRALEN(c) */
-/* #define NOT_FIRSTCU(c) */
-#define GETCHAR(c, eptr) c = *eptr;
-#define GETCHARTEST(c, eptr) c = *eptr;
-#define GETCHARINC(c, eptr) c = *eptr++;
-#define GETCHARINCTEST(c, eptr) c = *eptr++;
-#define GETCHARLEN(c, eptr, len) c = *eptr;
-#define PUTCHAR(c, p) (*p = c, 1)
-/* #define GETCHARLENTEST(c, eptr, len) */
-/* #define BACKCHAR(eptr) */
-/* #define FORWARDCHAR(eptr) */
-/* #define FORWARCCHARTEST(eptr,end) */
-/* #define ACROSSCHAR(condition, eptr, action) */
-
-#else /* SUPPORT_UNICODE */
-
-/* ------------------- 8-bit support ------------------ */
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
-#define MAYBE_UTF_MULTI /* UTF chars may use multiple code units */
-
-/* The largest UTF code point that can be encoded as a single code unit. */
-
-#define MAX_UTF_SINGLE_CU 127
-
-/* Tests whether the code point needs extra characters to decode. */
-
-#define HAS_EXTRALEN(c) HASUTF8EXTRALEN(c)
-
-/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE.
-Otherwise it has an undefined behaviour. */
-
-#define GET_EXTRALEN(c) (PRIV(utf8_table4)[(c) & 0x3fu])
-
-/* Returns TRUE, if the given value is not the first code unit of a UTF
-sequence. */
-
-#define NOT_FIRSTCU(c) (((c) & 0xc0u) == 0x80u)
-
-/* Get the next UTF-8 character, not advancing the pointer. This is called when
-we know we are in UTF-8 mode. */
-
-#define GETCHAR(c, eptr) \
- c = *eptr; \
- if (c >= 0xc0u) GETUTF8(c, eptr);
-
-/* Get the next UTF-8 character, testing for UTF-8 mode, and not advancing the
-pointer. */
-
-#define GETCHARTEST(c, eptr) \
- c = *eptr; \
- if (utf && c >= 0xc0u) GETUTF8(c, eptr);
-
-/* Get the next UTF-8 character, advancing the pointer. This is called when we
-know we are in UTF-8 mode. */
-
-#define GETCHARINC(c, eptr) \
- c = *eptr++; \
- if (c >= 0xc0u) GETUTF8INC(c, eptr);
-
-/* Get the next character, testing for UTF-8 mode, and advancing the pointer.
-This is called when we don't know if we are in UTF-8 mode. */
-
-#define GETCHARINCTEST(c, eptr) \
- c = *eptr++; \
- if (utf && c >= 0xc0u) GETUTF8INC(c, eptr);
-
-/* Get the next UTF-8 character, not advancing the pointer, incrementing length
-if there are extra bytes. This is called when we know we are in UTF-8 mode. */
-
-#define GETCHARLEN(c, eptr, len) \
- c = *eptr; \
- if (c >= 0xc0u) GETUTF8LEN(c, eptr, len);
-
-/* Get the next UTF-8 character, testing for UTF-8 mode, not advancing the
-pointer, incrementing length if there are extra bytes. This is called when we
-do not know if we are in UTF-8 mode. */
-
-#define GETCHARLENTEST(c, eptr, len) \
- c = *eptr; \
- if (utf && c >= 0xc0u) GETUTF8LEN(c, eptr, len);
-
-/* If the pointer is not at the start of a character, move it back until
-it is. This is called only in UTF-8 mode - we don't put a test within the macro
-because almost all calls are already within a block of UTF-8 only code. */
-
-#define BACKCHAR(eptr) while((*eptr & 0xc0u) == 0x80u) eptr--
-
-/* Same as above, just in the other direction. */
-#define FORWARDCHAR(eptr) while((*eptr & 0xc0u) == 0x80u) eptr++
-#define FORWARDCHARTEST(eptr,end) while(eptr < end && (*eptr & 0xc0u) == 0x80u) eptr++
-
-/* Same as above, but it allows a fully customizable form. */
-#define ACROSSCHAR(condition, eptr, action) \
- while((condition) && ((*eptr) & 0xc0u) == 0x80u) action
-
-/* Deposit a character into memory, returning the number of code units. */
-
-#define PUTCHAR(c, p) ((utf && c > MAX_UTF_SINGLE_CU)? \
- PRIV(ord2utf)(c,p) : (*p = c, 1))
-
-
-/* ------------------- 16-bit support ------------------ */
-
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-#define MAYBE_UTF_MULTI /* UTF chars may use multiple code units */
-
-/* The largest UTF code point that can be encoded as a single code unit. */
-
-#define MAX_UTF_SINGLE_CU 65535
-
-/* Tests whether the code point needs extra characters to decode. */
-
-#define HAS_EXTRALEN(c) (((c) & 0xfc00u) == 0xd800u)
-
-/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE.
-Otherwise it has an undefined behaviour. */
-
-#define GET_EXTRALEN(c) 1
-
-/* Returns TRUE, if the given value is not the first code unit of a UTF
-sequence. */
-
-#define NOT_FIRSTCU(c) (((c) & 0xfc00u) == 0xdc00u)
-
-/* Base macro to pick up the low surrogate of a UTF-16 character, not
-advancing the pointer. */
-
-#define GETUTF16(c, eptr) \
- { c = (((c & 0x3ffu) << 10) | (eptr[1] & 0x3ffu)) + 0x10000u; }
-
-/* Get the next UTF-16 character, not advancing the pointer. This is called when
-we know we are in UTF-16 mode. */
-
-#define GETCHAR(c, eptr) \
- c = *eptr; \
- if ((c & 0xfc00u) == 0xd800u) GETUTF16(c, eptr);
-
-/* Get the next UTF-16 character, testing for UTF-16 mode, and not advancing the
-pointer. */
-
-#define GETCHARTEST(c, eptr) \
- c = *eptr; \
- if (utf && (c & 0xfc00u) == 0xd800u) GETUTF16(c, eptr);
-
-/* Base macro to pick up the low surrogate of a UTF-16 character, advancing
-the pointer. */
-
-#define GETUTF16INC(c, eptr) \
- { c = (((c & 0x3ffu) << 10) | (*eptr++ & 0x3ffu)) + 0x10000u; }
-
-/* Get the next UTF-16 character, advancing the pointer. This is called when we
-know we are in UTF-16 mode. */
-
-#define GETCHARINC(c, eptr) \
- c = *eptr++; \
- if ((c & 0xfc00u) == 0xd800u) GETUTF16INC(c, eptr);
-
-/* Get the next character, testing for UTF-16 mode, and advancing the pointer.
-This is called when we don't know if we are in UTF-16 mode. */
-
-#define GETCHARINCTEST(c, eptr) \
- c = *eptr++; \
- if (utf && (c & 0xfc00u) == 0xd800u) GETUTF16INC(c, eptr);
-
-/* Base macro to pick up the low surrogate of a UTF-16 character, not
-advancing the pointer, incrementing the length. */
-
-#define GETUTF16LEN(c, eptr, len) \
- { c = (((c & 0x3ffu) << 10) | (eptr[1] & 0x3ffu)) + 0x10000u; len++; }
-
-/* Get the next UTF-16 character, not advancing the pointer, incrementing
-length if there is a low surrogate. This is called when we know we are in
-UTF-16 mode. */
-
-#define GETCHARLEN(c, eptr, len) \
- c = *eptr; \
- if ((c & 0xfc00u) == 0xd800u) GETUTF16LEN(c, eptr, len);
-
-/* Get the next UTF-816character, testing for UTF-16 mode, not advancing the
-pointer, incrementing length if there is a low surrogate. This is called when
-we do not know if we are in UTF-16 mode. */
-
-#define GETCHARLENTEST(c, eptr, len) \
- c = *eptr; \
- if (utf && (c & 0xfc00u) == 0xd800u) GETUTF16LEN(c, eptr, len);
-
-/* If the pointer is not at the start of a character, move it back until
-it is. This is called only in UTF-16 mode - we don't put a test within the
-macro because almost all calls are already within a block of UTF-16 only
-code. */
-
-#define BACKCHAR(eptr) if ((*eptr & 0xfc00u) == 0xdc00u) eptr--
-
-/* Same as above, just in the other direction. */
-#define FORWARDCHAR(eptr) if ((*eptr & 0xfc00u) == 0xdc00u) eptr++
-#define FORWARDCHARTEST(eptr,end) if (eptr < end && (*eptr & 0xfc00u) == 0xdc00u) eptr++
-
-/* Same as above, but it allows a fully customizable form. */
-#define ACROSSCHAR(condition, eptr, action) \
- if ((condition) && ((*eptr) & 0xfc00u) == 0xdc00u) action
-
-/* Deposit a character into memory, returning the number of code units. */
-
-#define PUTCHAR(c, p) ((utf && c > MAX_UTF_SINGLE_CU)? \
- PRIV(ord2utf)(c,p) : (*p = c, 1))
-
-
-/* ------------------- 32-bit support ------------------ */
-
-#else
-
-/* These are trivial for the 32-bit library, since all UTF-32 characters fit
-into one PCRE2_UCHAR unit. */
-
-#define MAX_UTF_SINGLE_CU (0x10ffffu)
-#define HAS_EXTRALEN(c) (0)
-#define GET_EXTRALEN(c) (0)
-#define NOT_FIRSTCU(c) (0)
-
-/* Get the next UTF-32 character, not advancing the pointer. This is called when
-we know we are in UTF-32 mode. */
-
-#define GETCHAR(c, eptr) \
- c = *(eptr);
-
-/* Get the next UTF-32 character, testing for UTF-32 mode, and not advancing the
-pointer. */
-
-#define GETCHARTEST(c, eptr) \
- c = *(eptr);
-
-/* Get the next UTF-32 character, advancing the pointer. This is called when we
-know we are in UTF-32 mode. */
-
-#define GETCHARINC(c, eptr) \
- c = *((eptr)++);
-
-/* Get the next character, testing for UTF-32 mode, and advancing the pointer.
-This is called when we don't know if we are in UTF-32 mode. */
-
-#define GETCHARINCTEST(c, eptr) \
- c = *((eptr)++);
-
-/* Get the next UTF-32 character, not advancing the pointer, not incrementing
-length (since all UTF-32 is of length 1). This is called when we know we are in
-UTF-32 mode. */
-
-#define GETCHARLEN(c, eptr, len) \
- GETCHAR(c, eptr)
-
-/* Get the next UTF-32character, testing for UTF-32 mode, not advancing the
-pointer, not incrementing the length (since all UTF-32 is of length 1).
-This is called when we do not know if we are in UTF-32 mode. */
-
-#define GETCHARLENTEST(c, eptr, len) \
- GETCHARTEST(c, eptr)
-
-/* If the pointer is not at the start of a character, move it back until
-it is. This is called only in UTF-32 mode - we don't put a test within the
-macro because almost all calls are already within a block of UTF-32 only
-code.
-
-These are all no-ops since all UTF-32 characters fit into one PCRE2_UCHAR. */
-
-#define BACKCHAR(eptr) do { } while (0)
-
-/* Same as above, just in the other direction. */
-
-#define FORWARDCHAR(eptr) do { } while (0)
-#define FORWARDCHARTEST(eptr,end) do { } while (0)
-
-/* Same as above, but it allows a fully customizable form. */
-
-#define ACROSSCHAR(condition, eptr, action) do { } while (0)
-
-/* Deposit a character into memory, returning the number of code units. */
-
-#define PUTCHAR(c, p) (*p = c, 1)
-
-#endif /* UTF-32 character handling */
-#endif /* SUPPORT_UNICODE */
-
-
-/* Mode-dependent macros that have the same definition in all modes. */
-
-#define CU2BYTES(x) ((x)*((PCRE2_CODE_UNIT_WIDTH/8)))
-#define BYTES2CU(x) ((x)/((PCRE2_CODE_UNIT_WIDTH/8)))
-#define PUTINC(a,n,d) PUT(a,n,d), a += LINK_SIZE
-#define PUT2INC(a,n,d) PUT2(a,n,d), a += IMM2_SIZE
-
-
-/* ----------------------- HIDDEN STRUCTURES ----------------------------- */
-
-/* NOTE: All these structures *must* start with a pcre2_memctl structure. The
-code that uses them is simpler because it assumes this. */
-
-/* The real general context structure. At present it holds only data for custom
-memory control. */
-
-typedef struct pcre2_real_general_context {
- pcre2_memctl memctl;
-} pcre2_real_general_context;
-
-/* The real compile context structure */
-
-typedef struct pcre2_real_compile_context {
- pcre2_memctl memctl;
- int (*stack_guard)(uint32_t, void *);
- void *stack_guard_data;
- const uint8_t *tables;
- PCRE2_SIZE max_pattern_length;
- uint16_t bsr_convention;
- uint16_t newline_convention;
- uint32_t parens_nest_limit;
- uint32_t extra_options;
-} pcre2_real_compile_context;
-
-/* The real match context structure. */
-
-typedef struct pcre2_real_match_context {
- pcre2_memctl memctl;
-#ifdef SUPPORT_JIT
- pcre2_jit_callback jit_callback;
- void *jit_callback_data;
-#endif
- int (*callout)(pcre2_callout_block *, void *);
- void *callout_data;
- int (*substitute_callout)(pcre2_substitute_callout_block *, void *);
- void *substitute_callout_data;
- PCRE2_SIZE offset_limit;
- uint32_t heap_limit;
- uint32_t match_limit;
- uint32_t depth_limit;
-} pcre2_real_match_context;
-
-/* The real convert context structure. */
-
-typedef struct pcre2_real_convert_context {
- pcre2_memctl memctl;
- uint32_t glob_separator;
- uint32_t glob_escape;
-} pcre2_real_convert_context;
-
-/* The real compiled code structure. The type for the blocksize field is
-defined specially because it is required in pcre2_serialize_decode() when
-copying the size from possibly unaligned memory into a variable of the same
-type. Use a macro rather than a typedef to avoid compiler warnings when this
-file is included multiple times by pcre2test. LOOKBEHIND_MAX specifies the
-largest lookbehind that is supported. (OP_REVERSE in a pattern has a 16-bit
-argument in 8-bit and 16-bit modes, so we need no more than a 16-bit field
-here.) */
-
-#undef CODE_BLOCKSIZE_TYPE
-#define CODE_BLOCKSIZE_TYPE size_t
-
-#undef LOOKBEHIND_MAX
-#define LOOKBEHIND_MAX UINT16_MAX
-
-typedef struct pcre2_real_code {
- pcre2_memctl memctl; /* Memory control fields */
- const uint8_t *tables; /* The character tables */
- void *executable_jit; /* Pointer to JIT code */
- uint8_t start_bitmap[32]; /* Bitmap for starting code unit < 256 */
- CODE_BLOCKSIZE_TYPE blocksize; /* Total (bytes) that was malloc-ed */
- uint32_t magic_number; /* Paranoid and endianness check */
- uint32_t compile_options; /* Options passed to pcre2_compile() */
- uint32_t overall_options; /* Options after processing the pattern */
- uint32_t extra_options; /* Taken from compile_context */
- uint32_t flags; /* Various state flags */
- uint32_t limit_heap; /* Limit set in the pattern */
- uint32_t limit_match; /* Limit set in the pattern */
- uint32_t limit_depth; /* Limit set in the pattern */
- uint32_t first_codeunit; /* Starting code unit */
- uint32_t last_codeunit; /* This codeunit must be seen */
- uint16_t bsr_convention; /* What \R matches */
- uint16_t newline_convention; /* What is a newline? */
- uint16_t max_lookbehind; /* Longest lookbehind (characters) */
- uint16_t minlength; /* Minimum length of match */
- uint16_t top_bracket; /* Highest numbered group */
- uint16_t top_backref; /* Highest numbered back reference */
- uint16_t name_entry_size; /* Size (code units) of table entries */
- uint16_t name_count; /* Number of name entries in the table */
-} pcre2_real_code;
-
-/* The real match data structure. Define ovector as large as it can ever
-actually be so that array bound checkers don't grumble. Memory for this
-structure is obtained by calling pcre2_match_data_create(), which sets the size
-as the offset of ovector plus a pair of elements for each capturable string, so
-the size varies from call to call. As the maximum number of capturing
-subpatterns is 65535 we must allow for 65536 strings to include the overall
-match. (See also the heapframe structure below.) */
-
-struct heapframe; /* Forward reference */
-
-typedef struct pcre2_real_match_data {
- pcre2_memctl memctl; /* Memory control fields */
- const pcre2_real_code *code; /* The pattern used for the match */
- PCRE2_SPTR subject; /* The subject that was matched */
- PCRE2_SPTR mark; /* Pointer to last mark */
- struct heapframe *heapframes; /* Backtracking frames heap memory */
- PCRE2_SIZE heapframes_size; /* Malloc-ed size */
- PCRE2_SIZE leftchar; /* Offset to leftmost code unit */
- PCRE2_SIZE rightchar; /* Offset to rightmost code unit */
- PCRE2_SIZE startchar; /* Offset to starting code unit */
- uint8_t matchedby; /* Type of match (normal, JIT, DFA) */
- uint8_t flags; /* Various flags */
- uint16_t oveccount; /* Number of pairs */
- int rc; /* The return code from the match */
- PCRE2_SIZE ovector[131072]; /* Must be last in the structure */
-} pcre2_real_match_data;
-
-
-/* ----------------------- PRIVATE STRUCTURES ----------------------------- */
-
-/* These structures are not needed for pcre2test. */
-
-#ifndef PCRE2_PCRE2TEST
-
-/* Structures for checking for mutual recursion when scanning compiled or
-parsed code. */
-
-typedef struct recurse_check {
- struct recurse_check *prev;
- PCRE2_SPTR group;
-} recurse_check;
-
-typedef struct parsed_recurse_check {
- struct parsed_recurse_check *prev;
- uint32_t *groupptr;
-} parsed_recurse_check;
-
-/* Structure for building a cache when filling in recursion offsets. */
-
-typedef struct recurse_cache {
- PCRE2_SPTR group;
- int groupnumber;
-} recurse_cache;
-
-/* Structure for maintaining a chain of pointers to the currently incomplete
-branches, for testing for left recursion while compiling. */
-
-typedef struct branch_chain {
- struct branch_chain *outer;
- PCRE2_UCHAR *current_branch;
-} branch_chain;
-
-/* Structure for building a list of named groups during the first pass of
-compiling. */
-
-typedef struct named_group {
- PCRE2_SPTR name; /* Points to the name in the pattern */
- uint32_t number; /* Group number */
- uint16_t length; /* Length of the name */
- uint16_t isdup; /* TRUE if a duplicate */
-} named_group;
-
-/* Structure for passing "static" information around between the functions
-doing the compiling, so that they are thread-safe. */
-
-typedef struct compile_block {
- pcre2_real_compile_context *cx; /* Points to the compile context */
- const uint8_t *lcc; /* Points to lower casing table */
- const uint8_t *fcc; /* Points to case-flipping table */
- const uint8_t *cbits; /* Points to character type table */
- const uint8_t *ctypes; /* Points to table of type maps */
- PCRE2_SPTR start_workspace; /* The start of working space */
- PCRE2_SPTR start_code; /* The start of the compiled code */
- PCRE2_SPTR start_pattern; /* The start of the pattern */
- PCRE2_SPTR end_pattern; /* The end of the pattern */
- PCRE2_UCHAR *name_table; /* The name/number table */
- PCRE2_SIZE workspace_size; /* Size of workspace */
- PCRE2_SIZE small_ref_offset[10]; /* Offsets for \1 to \9 */
- PCRE2_SIZE erroroffset; /* Offset of error in pattern */
- uint16_t names_found; /* Number of entries so far */
- uint16_t name_entry_size; /* Size of each entry */
- uint16_t parens_depth; /* Depth of nested parentheses */
- uint16_t assert_depth; /* Depth of nested assertions */
- open_capitem *open_caps; /* Chain of open capture items */
- named_group *named_groups; /* Points to vector in pre-compile */
- uint32_t named_group_list_size; /* Number of entries in the list */
- uint32_t external_options; /* External (initial) options */
- uint32_t external_flags; /* External flag bits to be set */
- uint32_t bracount; /* Count of capturing parentheses */
- uint32_t lastcapture; /* Last capture encountered */
- uint32_t *parsed_pattern; /* Parsed pattern buffer */
- uint32_t *parsed_pattern_end; /* Parsed pattern should not get here */
- uint32_t *groupinfo; /* Group info vector */
- uint32_t top_backref; /* Maximum back reference */
- uint32_t backref_map; /* Bitmap of low back refs */
- uint32_t nltype; /* Newline type */
- uint32_t nllen; /* Newline string length */
- uint32_t class_range_start; /* Overall class range start */
- uint32_t class_range_end; /* Overall class range end */
- PCRE2_UCHAR nl[4]; /* Newline string when fixed length */
- uint32_t req_varyopt; /* "After variable item" flag for reqbyte */
- int max_lookbehind; /* Maximum lookbehind (characters) */
- BOOL had_accept; /* (*ACCEPT) encountered */
- BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */
- BOOL had_recurse; /* Had a recursion or subroutine call */
- BOOL dupnames; /* Duplicate names exist */
-} compile_block;
-
-/* Structure for keeping the properties of the in-memory stack used
-by the JIT matcher. */
-
-typedef struct pcre2_real_jit_stack {
- pcre2_memctl memctl;
- void* stack;
-} pcre2_real_jit_stack;
-
-/* Structure for items in a linked list that represents an explicit recursive
-call within the pattern when running pcre2_dfa_match(). */
-
-typedef struct dfa_recursion_info {
- struct dfa_recursion_info *prevrec;
- PCRE2_SPTR subject_position;
- uint32_t group_num;
-} dfa_recursion_info;
-
-/* Structure for "stack" frames that are used for remembering backtracking
-positions during matching. As these are used in a vector, with the ovector item
-being extended, the size of the structure must be a multiple of PCRE2_SIZE. The
-only way to check this at compile time is to force an error by generating an
-array with a negative size. By putting this in a typedef (which is never used),
-we don't generate any code when all is well. */
-
-typedef struct heapframe {
-
- /* The first set of fields are variables that have to be preserved over calls
- to RRMATCH(), but which do not need to be copied to new frames. */
-
- PCRE2_SPTR ecode; /* The current position in the pattern */
- PCRE2_SPTR temp_sptr[2]; /* Used for short-term PCRE_SPTR values */
- PCRE2_SIZE length; /* Used for character, string, or code lengths */
- PCRE2_SIZE back_frame; /* Amount to subtract on RRETURN */
- PCRE2_SIZE temp_size; /* Used for short-term PCRE2_SIZE values */
- uint32_t rdepth; /* "Recursion" depth */
- uint32_t group_frame_type; /* Type information for group frames */
- uint32_t temp_32[4]; /* Used for short-term 32-bit or BOOL values */
- uint8_t return_id; /* Where to go on in internal "return" */
- uint8_t op; /* Processing opcode */
-
- /* At this point, the structure is 16-bit aligned. On most architectures
- the alignment requirement for a pointer will ensure that the eptr field below
- is 32-bit or 64-bit aligned. However, on m68k it is fine to have a pointer
- that is 16-bit aligned. We must therefore ensure that what comes between here
- and eptr is an odd multiple of 16 bits so as to get back into 32-bit
- alignment. This happens naturally when PCRE2_UCHAR is 8 bits wide, but needs
- fudges in the other cases. In the 32-bit case the padding comes first so that
- the occu field itself is 32-bit aligned. Without the padding, this structure
- is no longer a multiple of PCRE2_SIZE on m68k, and the check below fails. */
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
- PCRE2_UCHAR occu[6]; /* Used for other case code units */
-#elif PCRE2_CODE_UNIT_WIDTH == 16
- PCRE2_UCHAR occu[2]; /* Used for other case code units */
- uint8_t unused[2]; /* Ensure 32-bit alignment (see above) */
-#else
- uint8_t unused[2]; /* Ensure 32-bit alignment (see above) */
- PCRE2_UCHAR occu[1]; /* Used for other case code units */
-#endif
-
- /* The rest have to be copied from the previous frame whenever a new frame
- becomes current. The final field is specified as a large vector so that
- runtime array bound checks don't catch references to it. However, for any
- specific call to pcre2_match() the memory allocated for each frame structure
- allows for exactly the right size ovector for the number of capturing
- parentheses. (See also the comment for pcre2_real_match_data above.) */
-
- PCRE2_SPTR eptr; /* MUST BE FIRST */
- PCRE2_SPTR start_match; /* Can be adjusted by \K */
- PCRE2_SPTR mark; /* Most recent mark on the success path */
- uint32_t current_recurse; /* Current (deepest) recursion number */
- uint32_t capture_last; /* Most recent capture */
- PCRE2_SIZE last_group_offset; /* Saved offset to most recent group frame */
- PCRE2_SIZE offset_top; /* Offset after highest capture */
- PCRE2_SIZE ovector[131072]; /* Must be last in the structure */
-} heapframe;
-
-/* This typedef is a check that the size of the heapframe structure is a
-multiple of PCRE2_SIZE. See various comments above. */
-
-typedef char check_heapframe_size[
- ((sizeof(heapframe) % sizeof(PCRE2_SIZE)) == 0)? (+1):(-1)];
-
-/* Structure for computing the alignment of heapframe. */
-
-typedef struct heapframe_align {
- char unalign; /* Completely unalign the current offset */
- heapframe frame; /* Offset is its alignment */
-} heapframe_align;
-
-/* This define is the minimum alignment required for a heapframe, in bytes. */
-
-#define HEAPFRAME_ALIGNMENT offsetof(heapframe_align, frame)
-
-/* Structure for passing "static" information around between the functions
-doing traditional NFA matching (pcre2_match() and friends). */
-
-typedef struct match_block {
- pcre2_memctl memctl; /* For general use */
- PCRE2_SIZE heap_limit; /* As it says */
- uint32_t match_limit; /* As it says */
- uint32_t match_limit_depth; /* As it says */
- uint32_t match_call_count; /* Number of times a new frame is created */
- BOOL hitend; /* Hit the end of the subject at some point */
- BOOL hasthen; /* Pattern contains (*THEN) */
- BOOL allowemptypartial; /* Allow empty hard partial */
- const uint8_t *lcc; /* Points to lower casing table */
- const uint8_t *fcc; /* Points to case-flipping table */
- const uint8_t *ctypes; /* Points to table of type maps */
- PCRE2_SIZE start_offset; /* The start offset value */
- PCRE2_SIZE end_offset_top; /* Highwater mark at end of match */
- uint16_t partial; /* PARTIAL options */
- uint16_t bsr_convention; /* \R interpretation */
- uint16_t name_count; /* Number of names in name table */
- uint16_t name_entry_size; /* Size of entry in names table */
- PCRE2_SPTR name_table; /* Table of group names */
- PCRE2_SPTR start_code; /* For use when recursing */
- PCRE2_SPTR start_subject; /* Start of the subject string */
- PCRE2_SPTR check_subject; /* Where UTF-checked from */
- PCRE2_SPTR end_subject; /* End of the subject string */
- PCRE2_SPTR end_match_ptr; /* Subject position at end match */
- PCRE2_SPTR start_used_ptr; /* Earliest consulted character */
- PCRE2_SPTR last_used_ptr; /* Latest consulted character */
- PCRE2_SPTR mark; /* Mark pointer to pass back on success */
- PCRE2_SPTR nomatch_mark; /* Mark pointer to pass back on failure */
- PCRE2_SPTR verb_ecode_ptr; /* For passing back info */
- PCRE2_SPTR verb_skip_ptr; /* For passing back a (*SKIP) name */
- uint32_t verb_current_recurse; /* Current recurse when (*VERB) happens */
- uint32_t moptions; /* Match options */
- uint32_t poptions; /* Pattern options */
- uint32_t skip_arg_count; /* For counting SKIP_ARGs */
- uint32_t ignore_skip_arg; /* For re-run when SKIP arg name not found */
- uint32_t nltype; /* Newline type */
- uint32_t nllen; /* Newline string length */
- PCRE2_UCHAR nl[4]; /* Newline string when fixed */
- pcre2_callout_block *cb; /* Points to a callout block */
- void *callout_data; /* To pass back to callouts */
- int (*callout)(pcre2_callout_block *,void *); /* Callout function or NULL */
-} match_block;
-
-/* A similar structure is used for the same purpose by the DFA matching
-functions. */
-
-typedef struct dfa_match_block {
- pcre2_memctl memctl; /* For general use */
- PCRE2_SPTR start_code; /* Start of the compiled pattern */
- PCRE2_SPTR start_subject ; /* Start of the subject string */
- PCRE2_SPTR end_subject; /* End of subject string */
- PCRE2_SPTR start_used_ptr; /* Earliest consulted character */
- PCRE2_SPTR last_used_ptr; /* Latest consulted character */
- const uint8_t *tables; /* Character tables */
- PCRE2_SIZE start_offset; /* The start offset value */
- PCRE2_SIZE heap_limit; /* As it says */
- PCRE2_SIZE heap_used; /* As it says */
- uint32_t match_limit; /* As it says */
- uint32_t match_limit_depth; /* As it says */
- uint32_t match_call_count; /* Number of calls of internal function */
- uint32_t moptions; /* Match options */
- uint32_t poptions; /* Pattern options */
- uint32_t nltype; /* Newline type */
- uint32_t nllen; /* Newline string length */
- BOOL allowemptypartial; /* Allow empty hard partial */
- PCRE2_UCHAR nl[4]; /* Newline string when fixed */
- uint16_t bsr_convention; /* \R interpretation */
- pcre2_callout_block *cb; /* Points to a callout block */
- void *callout_data; /* To pass back to callouts */
- int (*callout)(pcre2_callout_block *,void *); /* Callout function or NULL */
- dfa_recursion_info *recursive; /* Linked list of recursion data */
-} dfa_match_block;
-
-#endif /* PCRE2_PCRE2TEST */
-
-/* End of pcre2_intmodedep.h */
diff --git a/contrib/libs/pcre2/src/pcre2_jit_compile.c b/contrib/libs/pcre2/src/pcre2_jit_compile.c
deleted file mode 100644
index 3fb93ff659..0000000000
--- a/contrib/libs/pcre2/src/pcre2_jit_compile.c
+++ /dev/null
@@ -1,14507 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- This module by Zoltan Herczeg
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2021 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-#include "pcre2_internal.h"
-
-#ifdef SUPPORT_JIT
-
-/* All-in-one: Since we use the JIT compiler only from here,
-we just include it. This way we don't need to touch the build
-system files. */
-
-#define SLJIT_CONFIG_AUTO 1
-#define SLJIT_CONFIG_STATIC 1
-#define SLJIT_VERBOSE 0
-
-#ifdef PCRE2_DEBUG
-#define SLJIT_DEBUG 1
-#else
-#define SLJIT_DEBUG 0
-#endif
-
-#define SLJIT_MALLOC(size, allocator_data) pcre2_jit_malloc(size, allocator_data)
-#define SLJIT_FREE(ptr, allocator_data) pcre2_jit_free(ptr, allocator_data)
-
-static void * pcre2_jit_malloc(size_t size, void *allocator_data)
-{
-pcre2_memctl *allocator = ((pcre2_memctl*)allocator_data);
-return allocator->malloc(size, allocator->memory_data);
-}
-
-static void pcre2_jit_free(void *ptr, void *allocator_data)
-{
-pcre2_memctl *allocator = ((pcre2_memctl*)allocator_data);
-allocator->free(ptr, allocator->memory_data);
-}
-
-#include "sljit/sljitLir.c"
-
-#if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
-#error Unsupported architecture
-#endif
-
-/* Defines for debugging purposes. */
-
-/* 1 - Use unoptimized capturing brackets.
- 2 - Enable capture_last_ptr (includes option 1). */
-/* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */
-
-/* 1 - Always have a control head. */
-/* #define DEBUG_FORCE_CONTROL_HEAD 1 */
-
-/* Allocate memory for the regex stack on the real machine stack.
-Fast, but limited size. */
-#define MACHINE_STACK_SIZE 32768
-
-/* Growth rate for stack allocated by the OS. Should be the multiply
-of page size. */
-#define STACK_GROWTH_RATE 8192
-
-/* Enable to check that the allocation could destroy temporaries. */
-#if defined SLJIT_DEBUG && SLJIT_DEBUG
-#define DESTROY_REGISTERS 1
-#endif
-
-/*
-Short summary about the backtracking mechanism empolyed by the jit code generator:
-
-The code generator follows the recursive nature of the PERL compatible regular
-expressions. The basic blocks of regular expressions are condition checkers
-whose execute different commands depending on the result of the condition check.
-The relationship between the operators can be horizontal (concatenation) and
-vertical (sub-expression) (See struct backtrack_common for more details).
-
- 'ab' - 'a' and 'b' regexps are concatenated
- 'a+' - 'a' is the sub-expression of the '+' operator
-
-The condition checkers are boolean (true/false) checkers. Machine code is generated
-for the checker itself and for the actions depending on the result of the checker.
-The 'true' case is called as the matching path (expected path), and the other is called as
-the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken
-branches on the matching path.
-
- Greedy star operator (*) :
- Matching path: match happens.
- Backtrack path: match failed.
- Non-greedy star operator (*?) :
- Matching path: no need to perform a match.
- Backtrack path: match is required.
-
-The following example shows how the code generated for a capturing bracket
-with two alternatives. Let A, B, C, D are arbirary regular expressions, and
-we have the following regular expression:
-
- A(B|C)D
-
-The generated code will be the following:
-
- A matching path
- '(' matching path (pushing arguments to the stack)
- B matching path
- ')' matching path (pushing arguments to the stack)
- D matching path
- return with successful match
-
- D backtrack path
- ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")
- B backtrack path
- C expected path
- jump to D matching path
- C backtrack path
- A backtrack path
-
- Notice, that the order of backtrack code paths are the opposite of the fast
- code paths. In this way the topmost value on the stack is always belong
- to the current backtrack code path. The backtrack path must check
- whether there is a next alternative. If so, it needs to jump back to
- the matching path eventually. Otherwise it needs to clear out its own stack
- frame and continue the execution on the backtrack code paths.
-*/
-
-/*
-Saved stack frames:
-
-Atomic blocks and asserts require reloading the values of private data
-when the backtrack mechanism performed. Because of OP_RECURSE, the data
-are not necessarly known in compile time, thus we need a dynamic restore
-mechanism.
-
-The stack frames are stored in a chain list, and have the following format:
-([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
-
-Thus we can restore the private data to a particular point in the stack.
-*/
-
-typedef struct jit_arguments {
- /* Pointers first. */
- struct sljit_stack *stack;
- PCRE2_SPTR str;
- PCRE2_SPTR begin;
- PCRE2_SPTR end;
- pcre2_match_data *match_data;
- PCRE2_SPTR startchar_ptr;
- PCRE2_UCHAR *mark_ptr;
- int (*callout)(pcre2_callout_block *, void *);
- void *callout_data;
- /* Everything else after. */
- sljit_uw offset_limit;
- sljit_u32 limit_match;
- sljit_u32 oveccount;
- sljit_u32 options;
-} jit_arguments;
-
-#define JIT_NUMBER_OF_COMPILE_MODES 3
-
-typedef struct executable_functions {
- void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
- void *read_only_data_heads[JIT_NUMBER_OF_COMPILE_MODES];
- sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
- sljit_u32 top_bracket;
- sljit_u32 limit_match;
-} executable_functions;
-
-typedef struct jump_list {
- struct sljit_jump *jump;
- struct jump_list *next;
-} jump_list;
-
-typedef struct stub_list {
- struct sljit_jump *start;
- struct sljit_label *quit;
- struct stub_list *next;
-} stub_list;
-
-enum frame_types {
- no_frame = -1,
- no_stack = -2
-};
-
-enum control_types {
- type_mark = 0,
- type_then_trap = 1
-};
-
-enum early_fail_types {
- type_skip = 0,
- type_fail = 1,
- type_fail_range = 2
-};
-
-typedef int (SLJIT_FUNC *jit_function)(jit_arguments *args);
-
-/* The following structure is the key data type for the recursive
-code generator. It is allocated by compile_matchingpath, and contains
-the arguments for compile_backtrackingpath. Must be the first member
-of its descendants. */
-typedef struct backtrack_common {
- /* Concatenation stack. */
- struct backtrack_common *prev;
- jump_list *nextbacktracks;
- /* Internal stack (for component operators). */
- struct backtrack_common *top;
- jump_list *topbacktracks;
- /* Opcode pointer. */
- PCRE2_SPTR cc;
-} backtrack_common;
-
-typedef struct assert_backtrack {
- backtrack_common common;
- jump_list *condfailed;
- /* Less than 0 if a frame is not needed. */
- int framesize;
- /* Points to our private memory word on the stack. */
- int private_data_ptr;
- /* For iterators. */
- struct sljit_label *matchingpath;
-} assert_backtrack;
-
-typedef struct bracket_backtrack {
- backtrack_common common;
- /* Where to coninue if an alternative is successfully matched. */
- struct sljit_label *alternative_matchingpath;
- /* For rmin and rmax iterators. */
- struct sljit_label *recursive_matchingpath;
- /* For greedy ? operator. */
- struct sljit_label *zero_matchingpath;
- /* Contains the branches of a failed condition. */
- union {
- /* Both for OP_COND, OP_SCOND. */
- jump_list *condfailed;
- assert_backtrack *assert;
- /* For OP_ONCE. Less than 0 if not needed. */
- int framesize;
- /* For brackets with >3 alternatives. */
- struct sljit_put_label *matching_put_label;
- } u;
- /* Points to our private memory word on the stack. */
- int private_data_ptr;
-} bracket_backtrack;
-
-typedef struct bracketpos_backtrack {
- backtrack_common common;
- /* Points to our private memory word on the stack. */
- int private_data_ptr;
- /* Reverting stack is needed. */
- int framesize;
- /* Allocated stack size. */
- int stacksize;
-} bracketpos_backtrack;
-
-typedef struct braminzero_backtrack {
- backtrack_common common;
- struct sljit_label *matchingpath;
-} braminzero_backtrack;
-
-typedef struct char_iterator_backtrack {
- backtrack_common common;
- /* Next iteration. */
- struct sljit_label *matchingpath;
- union {
- jump_list *backtracks;
- struct {
- unsigned int othercasebit;
- PCRE2_UCHAR chr;
- BOOL enabled;
- } charpos;
- } u;
-} char_iterator_backtrack;
-
-typedef struct ref_iterator_backtrack {
- backtrack_common common;
- /* Next iteration. */
- struct sljit_label *matchingpath;
-} ref_iterator_backtrack;
-
-typedef struct recurse_entry {
- struct recurse_entry *next;
- /* Contains the function entry label. */
- struct sljit_label *entry_label;
- /* Contains the function entry label. */
- struct sljit_label *backtrack_label;
- /* Collects the entry calls until the function is not created. */
- jump_list *entry_calls;
- /* Collects the backtrack calls until the function is not created. */
- jump_list *backtrack_calls;
- /* Points to the starting opcode. */
- sljit_sw start;
-} recurse_entry;
-
-typedef struct recurse_backtrack {
- backtrack_common common;
- /* Return to the matching path. */
- struct sljit_label *matchingpath;
- /* Recursive pattern. */
- recurse_entry *entry;
- /* Pattern is inlined. */
- BOOL inlined_pattern;
-} recurse_backtrack;
-
-#define OP_THEN_TRAP OP_TABLE_LENGTH
-
-typedef struct then_trap_backtrack {
- backtrack_common common;
- /* If then_trap is not NULL, this structure contains the real
- then_trap for the backtracking path. */
- struct then_trap_backtrack *then_trap;
- /* Points to the starting opcode. */
- sljit_sw start;
- /* Exit point for the then opcodes of this alternative. */
- jump_list *quit;
- /* Frame size of the current alternative. */
- int framesize;
-} then_trap_backtrack;
-
-#define MAX_N_CHARS 12
-#define MAX_DIFF_CHARS 5
-
-typedef struct fast_forward_char_data {
- /* Number of characters in the chars array, 255 for any character. */
- sljit_u8 count;
- /* Number of last UTF-8 characters in the chars array. */
- sljit_u8 last_count;
- /* Available characters in the current position. */
- PCRE2_UCHAR chars[MAX_DIFF_CHARS];
-} fast_forward_char_data;
-
-#define MAX_CLASS_RANGE_SIZE 4
-#define MAX_CLASS_CHARS_SIZE 3
-
-typedef struct compiler_common {
- /* The sljit ceneric compiler. */
- struct sljit_compiler *compiler;
- /* Compiled regular expression. */
- pcre2_real_code *re;
- /* First byte code. */
- PCRE2_SPTR start;
- /* Maps private data offset to each opcode. */
- sljit_s32 *private_data_ptrs;
- /* Chain list of read-only data ptrs. */
- void *read_only_data_head;
- /* Tells whether the capturing bracket is optimized. */
- sljit_u8 *optimized_cbracket;
- /* Tells whether the starting offset is a target of then. */
- sljit_u8 *then_offsets;
- /* Current position where a THEN must jump. */
- then_trap_backtrack *then_trap;
- /* Starting offset of private data for capturing brackets. */
- sljit_s32 cbra_ptr;
- /* Output vector starting point. Must be divisible by 2. */
- sljit_s32 ovector_start;
- /* Points to the starting character of the current match. */
- sljit_s32 start_ptr;
- /* Last known position of the requested byte. */
- sljit_s32 req_char_ptr;
- /* Head of the last recursion. */
- sljit_s32 recursive_head_ptr;
- /* First inspected character for partial matching.
- (Needed for avoiding zero length partial matches.) */
- sljit_s32 start_used_ptr;
- /* Starting pointer for partial soft matches. */
- sljit_s32 hit_start;
- /* Pointer of the match end position. */
- sljit_s32 match_end_ptr;
- /* Points to the marked string. */
- sljit_s32 mark_ptr;
- /* Recursive control verb management chain. */
- sljit_s32 control_head_ptr;
- /* Points to the last matched capture block index. */
- sljit_s32 capture_last_ptr;
- /* Fast forward skipping byte code pointer. */
- PCRE2_SPTR fast_forward_bc_ptr;
- /* Locals used by fast fail optimization. */
- sljit_s32 early_fail_start_ptr;
- sljit_s32 early_fail_end_ptr;
- /* Variables used by recursive call generator. */
- sljit_s32 recurse_bitset_size;
- uint8_t *recurse_bitset;
-
- /* Flipped and lower case tables. */
- const sljit_u8 *fcc;
- sljit_sw lcc;
- /* Mode can be PCRE2_JIT_COMPLETE and others. */
- int mode;
- /* TRUE, when empty match is accepted for partial matching. */
- BOOL allow_empty_partial;
- /* TRUE, when minlength is greater than 0. */
- BOOL might_be_empty;
- /* \K is found in the pattern. */
- BOOL has_set_som;
- /* (*SKIP:arg) is found in the pattern. */
- BOOL has_skip_arg;
- /* (*THEN) is found in the pattern. */
- BOOL has_then;
- /* (*SKIP) or (*SKIP:arg) is found in lookbehind assertion. */
- BOOL has_skip_in_assert_back;
- /* Quit is redirected by recurse, negative assertion, or positive assertion in conditional block. */
- BOOL local_quit_available;
- /* Currently in a positive assertion. */
- BOOL in_positive_assertion;
- /* Newline control. */
- int nltype;
- sljit_u32 nlmax;
- sljit_u32 nlmin;
- int newline;
- int bsr_nltype;
- sljit_u32 bsr_nlmax;
- sljit_u32 bsr_nlmin;
- /* Dollar endonly. */
- int endonly;
- /* Tables. */
- sljit_sw ctypes;
- /* Named capturing brackets. */
- PCRE2_SPTR name_table;
- sljit_sw name_count;
- sljit_sw name_entry_size;
-
- /* Labels and jump lists. */
- struct sljit_label *partialmatchlabel;
- struct sljit_label *quit_label;
- struct sljit_label *abort_label;
- struct sljit_label *accept_label;
- struct sljit_label *ff_newline_shortcut;
- stub_list *stubs;
- recurse_entry *entries;
- recurse_entry *currententry;
- jump_list *partialmatch;
- jump_list *quit;
- jump_list *positive_assertion_quit;
- jump_list *abort;
- jump_list *failed_match;
- jump_list *accept;
- jump_list *calllimit;
- jump_list *stackalloc;
- jump_list *revertframes;
- jump_list *wordboundary;
- jump_list *anynewline;
- jump_list *hspace;
- jump_list *vspace;
- jump_list *casefulcmp;
- jump_list *caselesscmp;
- jump_list *reset_match;
- BOOL unset_backref;
- BOOL alt_circumflex;
-#ifdef SUPPORT_UNICODE
- BOOL utf;
- BOOL invalid_utf;
- BOOL ucp;
- /* Points to saving area for iref. */
- sljit_s32 iref_ptr;
- jump_list *getucd;
- jump_list *getucdtype;
-#if PCRE2_CODE_UNIT_WIDTH == 8
- jump_list *utfreadchar;
- jump_list *utfreadtype8;
- jump_list *utfpeakcharback;
-#endif
-#if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16
- jump_list *utfreadchar_invalid;
- jump_list *utfreadnewline_invalid;
- jump_list *utfmoveback_invalid;
- jump_list *utfpeakcharback_invalid;
-#endif
-#endif /* SUPPORT_UNICODE */
-} compiler_common;
-
-/* For byte_sequence_compare. */
-
-typedef struct compare_context {
- int length;
- int sourcereg;
-#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
- int ucharptr;
- union {
- sljit_s32 asint;
- sljit_u16 asushort;
-#if PCRE2_CODE_UNIT_WIDTH == 8
- sljit_u8 asbyte;
- sljit_u8 asuchars[4];
-#elif PCRE2_CODE_UNIT_WIDTH == 16
- sljit_u16 asuchars[2];
-#elif PCRE2_CODE_UNIT_WIDTH == 32
- sljit_u32 asuchars[1];
-#endif
- } c;
- union {
- sljit_s32 asint;
- sljit_u16 asushort;
-#if PCRE2_CODE_UNIT_WIDTH == 8
- sljit_u8 asbyte;
- sljit_u8 asuchars[4];
-#elif PCRE2_CODE_UNIT_WIDTH == 16
- sljit_u16 asuchars[2];
-#elif PCRE2_CODE_UNIT_WIDTH == 32
- sljit_u32 asuchars[1];
-#endif
- } oc;
-#endif
-} compare_context;
-
-/* Undefine sljit macros. */
-#undef CMP
-
-/* Used for accessing the elements of the stack. */
-#define STACK(i) ((i) * SSIZE_OF(sw))
-
-#ifdef SLJIT_PREF_SHIFT_REG
-#if SLJIT_PREF_SHIFT_REG == SLJIT_R2
-/* Nothing. */
-#elif SLJIT_PREF_SHIFT_REG == SLJIT_R3
-#define SHIFT_REG_IS_R3
-#else
-#error "Unsupported shift register"
-#endif
-#endif
-
-#define TMP1 SLJIT_R0
-#ifdef SHIFT_REG_IS_R3
-#define TMP2 SLJIT_R3
-#define TMP3 SLJIT_R2
-#else
-#define TMP2 SLJIT_R2
-#define TMP3 SLJIT_R3
-#endif
-#define STR_PTR SLJIT_R1
-#define STR_END SLJIT_S0
-#define STACK_TOP SLJIT_S1
-#define STACK_LIMIT SLJIT_S2
-#define COUNT_MATCH SLJIT_S3
-#define ARGUMENTS SLJIT_S4
-#define RETURN_ADDR SLJIT_R4
-
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-#define HAS_VIRTUAL_REGISTERS 1
-#else
-#define HAS_VIRTUAL_REGISTERS 0
-#endif
-
-/* Local space layout. */
-/* These two locals can be used by the current opcode. */
-#define LOCALS0 (0 * sizeof(sljit_sw))
-#define LOCALS1 (1 * sizeof(sljit_sw))
-/* Two local variables for possessive quantifiers (char1 cannot use them). */
-#define POSSESSIVE0 (2 * sizeof(sljit_sw))
-#define POSSESSIVE1 (3 * sizeof(sljit_sw))
-/* Max limit of recursions. */
-#define LIMIT_MATCH (4 * sizeof(sljit_sw))
-/* The output vector is stored on the stack, and contains pointers
-to characters. The vector data is divided into two groups: the first
-group contains the start / end character pointers, and the second is
-the start pointers when the end of the capturing group has not yet reached. */
-#define OVECTOR_START (common->ovector_start)
-#define OVECTOR(i) (OVECTOR_START + (i) * SSIZE_OF(sw))
-#define OVECTOR_PRIV(i) (common->cbra_ptr + (i) * SSIZE_OF(sw))
-#define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
-#define MOV_UCHAR SLJIT_MOV_U8
-#define IN_UCHARS(x) (x)
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-#define MOV_UCHAR SLJIT_MOV_U16
-#define UCHAR_SHIFT (1)
-#define IN_UCHARS(x) ((x) * 2)
-#elif PCRE2_CODE_UNIT_WIDTH == 32
-#define MOV_UCHAR SLJIT_MOV_U32
-#define UCHAR_SHIFT (2)
-#define IN_UCHARS(x) ((x) * 4)
-#else
-#error Unsupported compiling mode
-#endif
-
-/* Shortcuts. */
-#define DEFINE_COMPILER \
- struct sljit_compiler *compiler = common->compiler
-#define OP1(op, dst, dstw, src, srcw) \
- sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw))
-#define OP2(op, dst, dstw, src1, src1w, src2, src2w) \
- sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w))
-#define OP2U(op, src1, src1w, src2, src2w) \
- sljit_emit_op2u(compiler, (op), (src1), (src1w), (src2), (src2w))
-#define OP_SRC(op, src, srcw) \
- sljit_emit_op_src(compiler, (op), (src), (srcw))
-#define LABEL() \
- sljit_emit_label(compiler)
-#define JUMP(type) \
- sljit_emit_jump(compiler, (type))
-#define JUMPTO(type, label) \
- sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
-#define JUMPHERE(jump) \
- sljit_set_label((jump), sljit_emit_label(compiler))
-#define SET_LABEL(jump, label) \
- sljit_set_label((jump), (label))
-#define CMP(type, src1, src1w, src2, src2w) \
- sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
-#define CMPTO(type, src1, src1w, src2, src2w, label) \
- sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))
-#define OP_FLAGS(op, dst, dstw, type) \
- sljit_emit_op_flags(compiler, (op), (dst), (dstw), (type))
-#define CMOV(type, dst_reg, src, srcw) \
- sljit_emit_cmov(compiler, (type), (dst_reg), (src), (srcw))
-#define GET_LOCAL_BASE(dst, dstw, offset) \
- sljit_get_local_base(compiler, (dst), (dstw), (offset))
-
-#define READ_CHAR_MAX 0x7fffffff
-
-#define INVALID_UTF_CHAR -1
-#define UNASSIGNED_UTF_CHAR 888
-
-#if defined SUPPORT_UNICODE
-#if PCRE2_CODE_UNIT_WIDTH == 8
-
-#define GETCHARINC_INVALID(c, ptr, end, invalid_action) \
- { \
- if (ptr[0] <= 0x7f) \
- c = *ptr++; \
- else if (ptr + 1 < end && ptr[1] >= 0x80 && ptr[1] < 0xc0) \
- { \
- c = ptr[1] - 0x80; \
- \
- if (ptr[0] >= 0xc2 && ptr[0] <= 0xdf) \
- { \
- c |= (ptr[0] - 0xc0) << 6; \
- ptr += 2; \
- } \
- else if (ptr + 2 < end && ptr[2] >= 0x80 && ptr[2] < 0xc0) \
- { \
- c = c << 6 | (ptr[2] - 0x80); \
- \
- if (ptr[0] >= 0xe0 && ptr[0] <= 0xef) \
- { \
- c |= (ptr[0] - 0xe0) << 12; \
- ptr += 3; \
- \
- if (c < 0x800 || (c >= 0xd800 && c < 0xe000)) \
- { \
- invalid_action; \
- } \
- } \
- else if (ptr + 3 < end && ptr[3] >= 0x80 && ptr[3] < 0xc0) \
- { \
- c = c << 6 | (ptr[3] - 0x80); \
- \
- if (ptr[0] >= 0xf0 && ptr[0] <= 0xf4) \
- { \
- c |= (ptr[0] - 0xf0) << 18; \
- ptr += 4; \
- \
- if (c >= 0x110000 || c < 0x10000) \
- { \
- invalid_action; \
- } \
- } \
- else \
- { \
- invalid_action; \
- } \
- } \
- else \
- { \
- invalid_action; \
- } \
- } \
- else \
- { \
- invalid_action; \
- } \
- } \
- else \
- { \
- invalid_action; \
- } \
- }
-
-#define GETCHARBACK_INVALID(c, ptr, start, invalid_action) \
- { \
- c = ptr[-1]; \
- if (c <= 0x7f) \
- ptr--; \
- else if (ptr - 1 > start && ptr[-1] >= 0x80 && ptr[-1] < 0xc0) \
- { \
- c -= 0x80; \
- \
- if (ptr[-2] >= 0xc2 && ptr[-2] <= 0xdf) \
- { \
- c |= (ptr[-2] - 0xc0) << 6; \
- ptr -= 2; \
- } \
- else if (ptr - 2 > start && ptr[-2] >= 0x80 && ptr[-2] < 0xc0) \
- { \
- c = c << 6 | (ptr[-2] - 0x80); \
- \
- if (ptr[-3] >= 0xe0 && ptr[-3] <= 0xef) \
- { \
- c |= (ptr[-3] - 0xe0) << 12; \
- ptr -= 3; \
- \
- if (c < 0x800 || (c >= 0xd800 && c < 0xe000)) \
- { \
- invalid_action; \
- } \
- } \
- else if (ptr - 3 > start && ptr[-3] >= 0x80 && ptr[-3] < 0xc0) \
- { \
- c = c << 6 | (ptr[-3] - 0x80); \
- \
- if (ptr[-4] >= 0xf0 && ptr[-4] <= 0xf4) \
- { \
- c |= (ptr[-4] - 0xf0) << 18; \
- ptr -= 4; \
- \
- if (c >= 0x110000 || c < 0x10000) \
- { \
- invalid_action; \
- } \
- } \
- else \
- { \
- invalid_action; \
- } \
- } \
- else \
- { \
- invalid_action; \
- } \
- } \
- else \
- { \
- invalid_action; \
- } \
- } \
- else \
- { \
- invalid_action; \
- } \
- }
-
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-
-#define GETCHARINC_INVALID(c, ptr, end, invalid_action) \
- { \
- if (ptr[0] < 0xd800 || ptr[0] >= 0xe000) \
- c = *ptr++; \
- else if (ptr[0] < 0xdc00 && ptr + 1 < end && ptr[1] >= 0xdc00 && ptr[1] < 0xe000) \
- { \
- c = (((ptr[0] - 0xd800) << 10) | (ptr[1] - 0xdc00)) + 0x10000; \
- ptr += 2; \
- } \
- else \
- { \
- invalid_action; \
- } \
- }
-
-#define GETCHARBACK_INVALID(c, ptr, start, invalid_action) \
- { \
- c = ptr[-1]; \
- if (c < 0xd800 || c >= 0xe000) \
- ptr--; \
- else if (c >= 0xdc00 && ptr - 1 > start && ptr[-2] >= 0xd800 && ptr[-2] < 0xdc00) \
- { \
- c = (((ptr[-2] - 0xd800) << 10) | (c - 0xdc00)) + 0x10000; \
- ptr -= 2; \
- } \
- else \
- { \
- invalid_action; \
- } \
- }
-
-
-#elif PCRE2_CODE_UNIT_WIDTH == 32
-
-#define GETCHARINC_INVALID(c, ptr, end, invalid_action) \
- { \
- if (ptr[0] < 0xd800 || (ptr[0] >= 0xe000 && ptr[0] < 0x110000)) \
- c = *ptr++; \
- else \
- { \
- invalid_action; \
- } \
- }
-
-#define GETCHARBACK_INVALID(c, ptr, start, invalid_action) \
- { \
- c = ptr[-1]; \
- if (ptr[-1] < 0xd800 || (ptr[-1] >= 0xe000 && ptr[-1] < 0x110000)) \
- ptr--; \
- else \
- { \
- invalid_action; \
- } \
- }
-
-#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */
-#endif /* SUPPORT_UNICODE */
-
-static PCRE2_SPTR bracketend(PCRE2_SPTR cc)
-{
-SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
-do cc += GET(cc, 1); while (*cc == OP_ALT);
-SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);
-cc += 1 + LINK_SIZE;
-return cc;
-}
-
-static int no_alternatives(PCRE2_SPTR cc)
-{
-int count = 0;
-SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
-do
- {
- cc += GET(cc, 1);
- count++;
- }
-while (*cc == OP_ALT);
-SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);
-return count;
-}
-
-/* Functions whose might need modification for all new supported opcodes:
- next_opcode
- check_opcode_types
- set_private_data_ptrs
- get_framesize
- init_frame
- get_recurse_data_length
- copy_recurse_data
- compile_matchingpath
- compile_backtrackingpath
-*/
-
-static PCRE2_SPTR next_opcode(compiler_common *common, PCRE2_SPTR cc)
-{
-SLJIT_UNUSED_ARG(common);
-switch(*cc)
- {
- case OP_SOD:
- case OP_SOM:
- case OP_SET_SOM:
- case OP_NOT_WORD_BOUNDARY:
- case OP_WORD_BOUNDARY:
- case OP_NOT_DIGIT:
- case OP_DIGIT:
- case OP_NOT_WHITESPACE:
- case OP_WHITESPACE:
- case OP_NOT_WORDCHAR:
- case OP_WORDCHAR:
- case OP_ANY:
- case OP_ALLANY:
- case OP_NOTPROP:
- case OP_PROP:
- case OP_ANYNL:
- case OP_NOT_HSPACE:
- case OP_HSPACE:
- case OP_NOT_VSPACE:
- case OP_VSPACE:
- case OP_EXTUNI:
- case OP_EODN:
- case OP_EOD:
- case OP_CIRC:
- case OP_CIRCM:
- case OP_DOLL:
- case OP_DOLLM:
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- case OP_CRPOSSTAR:
- case OP_CRPOSPLUS:
- case OP_CRPOSQUERY:
- case OP_CRPOSRANGE:
- case OP_CLASS:
- case OP_NCLASS:
- case OP_REF:
- case OP_REFI:
- case OP_DNREF:
- case OP_DNREFI:
- case OP_RECURSE:
- case OP_CALLOUT:
- case OP_ALT:
- case OP_KET:
- case OP_KETRMAX:
- case OP_KETRMIN:
- case OP_KETRPOS:
- case OP_REVERSE:
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- case OP_ASSERT_NA:
- case OP_ASSERTBACK_NA:
- case OP_ONCE:
- case OP_SCRIPT_RUN:
- case OP_BRA:
- case OP_BRAPOS:
- case OP_CBRA:
- case OP_CBRAPOS:
- case OP_COND:
- case OP_SBRA:
- case OP_SBRAPOS:
- case OP_SCBRA:
- case OP_SCBRAPOS:
- case OP_SCOND:
- case OP_CREF:
- case OP_DNCREF:
- case OP_RREF:
- case OP_DNRREF:
- case OP_FALSE:
- case OP_TRUE:
- case OP_BRAZERO:
- case OP_BRAMINZERO:
- case OP_BRAPOSZERO:
- case OP_PRUNE:
- case OP_SKIP:
- case OP_THEN:
- case OP_COMMIT:
- case OP_FAIL:
- case OP_ACCEPT:
- case OP_ASSERT_ACCEPT:
- case OP_CLOSE:
- case OP_SKIPZERO:
- return cc + PRIV(OP_lengths)[*cc];
-
- case OP_CHAR:
- case OP_CHARI:
- case OP_NOT:
- case OP_NOTI:
- case OP_STAR:
- case OP_MINSTAR:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_EXACT:
- case OP_POSSTAR:
- case OP_POSPLUS:
- case OP_POSQUERY:
- case OP_POSUPTO:
- case OP_STARI:
- case OP_MINSTARI:
- case OP_PLUSI:
- case OP_MINPLUSI:
- case OP_QUERYI:
- case OP_MINQUERYI:
- case OP_UPTOI:
- case OP_MINUPTOI:
- case OP_EXACTI:
- case OP_POSSTARI:
- case OP_POSPLUSI:
- case OP_POSQUERYI:
- case OP_POSUPTOI:
- case OP_NOTSTAR:
- case OP_NOTMINSTAR:
- case OP_NOTPLUS:
- case OP_NOTMINPLUS:
- case OP_NOTQUERY:
- case OP_NOTMINQUERY:
- case OP_NOTUPTO:
- case OP_NOTMINUPTO:
- case OP_NOTEXACT:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSPLUS:
- case OP_NOTPOSQUERY:
- case OP_NOTPOSUPTO:
- case OP_NOTSTARI:
- case OP_NOTMINSTARI:
- case OP_NOTPLUSI:
- case OP_NOTMINPLUSI:
- case OP_NOTQUERYI:
- case OP_NOTMINQUERYI:
- case OP_NOTUPTOI:
- case OP_NOTMINUPTOI:
- case OP_NOTEXACTI:
- case OP_NOTPOSSTARI:
- case OP_NOTPOSPLUSI:
- case OP_NOTPOSQUERYI:
- case OP_NOTPOSUPTOI:
- cc += PRIV(OP_lengths)[*cc];
-#ifdef SUPPORT_UNICODE
- if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- return cc;
-
- /* Special cases. */
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEEXACT:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSPLUS:
- case OP_TYPEPOSQUERY:
- case OP_TYPEPOSUPTO:
- return cc + PRIV(OP_lengths)[*cc] - 1;
-
- case OP_ANYBYTE:
-#ifdef SUPPORT_UNICODE
- if (common->utf) return NULL;
-#endif
- return cc + 1;
-
- case OP_CALLOUT_STR:
- return cc + GET(cc, 1 + 2*LINK_SIZE);
-
-#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
- case OP_XCLASS:
- return cc + GET(cc, 1);
-#endif
-
- case OP_MARK:
- case OP_COMMIT_ARG:
- case OP_PRUNE_ARG:
- case OP_SKIP_ARG:
- case OP_THEN_ARG:
- return cc + 1 + 2 + cc[1];
-
- default:
- SLJIT_UNREACHABLE();
- return NULL;
- }
-}
-
-static BOOL check_opcode_types(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend)
-{
-int count;
-PCRE2_SPTR slot;
-PCRE2_SPTR assert_back_end = cc - 1;
-PCRE2_SPTR assert_na_end = cc - 1;
-
-/* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
-while (cc < ccend)
- {
- switch(*cc)
- {
- case OP_SET_SOM:
- common->has_set_som = TRUE;
- common->might_be_empty = TRUE;
- cc += 1;
- break;
-
- case OP_REFI:
-#ifdef SUPPORT_UNICODE
- if (common->iref_ptr == 0)
- {
- common->iref_ptr = common->ovector_start;
- common->ovector_start += 3 * sizeof(sljit_sw);
- }
-#endif /* SUPPORT_UNICODE */
- /* Fall through. */
- case OP_REF:
- common->optimized_cbracket[GET2(cc, 1)] = 0;
- cc += 1 + IMM2_SIZE;
- break;
-
- case OP_ASSERT_NA:
- case OP_ASSERTBACK_NA:
- slot = bracketend(cc);
- if (slot > assert_na_end)
- assert_na_end = slot;
- cc += 1 + LINK_SIZE;
- break;
-
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
- cc += 1 + LINK_SIZE + IMM2_SIZE;
- break;
-
- case OP_COND:
- case OP_SCOND:
- /* Only AUTO_CALLOUT can insert this opcode. We do
- not intend to support this case. */
- if (cc[1 + LINK_SIZE] == OP_CALLOUT || cc[1 + LINK_SIZE] == OP_CALLOUT_STR)
- return FALSE;
- cc += 1 + LINK_SIZE;
- break;
-
- case OP_CREF:
- common->optimized_cbracket[GET2(cc, 1)] = 0;
- cc += 1 + IMM2_SIZE;
- break;
-
- case OP_DNREF:
- case OP_DNREFI:
- case OP_DNCREF:
- count = GET2(cc, 1 + IMM2_SIZE);
- slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
- while (count-- > 0)
- {
- common->optimized_cbracket[GET2(slot, 0)] = 0;
- slot += common->name_entry_size;
- }
- cc += 1 + 2 * IMM2_SIZE;
- break;
-
- case OP_RECURSE:
- /* Set its value only once. */
- if (common->recursive_head_ptr == 0)
- {
- common->recursive_head_ptr = common->ovector_start;
- common->ovector_start += sizeof(sljit_sw);
- }
- cc += 1 + LINK_SIZE;
- break;
-
- case OP_CALLOUT:
- case OP_CALLOUT_STR:
- if (common->capture_last_ptr == 0)
- {
- common->capture_last_ptr = common->ovector_start;
- common->ovector_start += sizeof(sljit_sw);
- }
- cc += (*cc == OP_CALLOUT) ? PRIV(OP_lengths)[OP_CALLOUT] : GET(cc, 1 + 2*LINK_SIZE);
- break;
-
- case OP_ASSERTBACK:
- slot = bracketend(cc);
- if (slot > assert_back_end)
- assert_back_end = slot;
- cc += 1 + LINK_SIZE;
- break;
-
- case OP_THEN_ARG:
- common->has_then = TRUE;
- common->control_head_ptr = 1;
- /* Fall through. */
-
- case OP_COMMIT_ARG:
- case OP_PRUNE_ARG:
- if (cc < assert_na_end)
- return FALSE;
- /* Fall through */
- case OP_MARK:
- if (common->mark_ptr == 0)
- {
- common->mark_ptr = common->ovector_start;
- common->ovector_start += sizeof(sljit_sw);
- }
- cc += 1 + 2 + cc[1];
- break;
-
- case OP_THEN:
- common->has_then = TRUE;
- common->control_head_ptr = 1;
- cc += 1;
- break;
-
- case OP_SKIP:
- if (cc < assert_back_end)
- common->has_skip_in_assert_back = TRUE;
- if (cc < assert_na_end)
- return FALSE;
- cc += 1;
- break;
-
- case OP_SKIP_ARG:
- common->control_head_ptr = 1;
- common->has_skip_arg = TRUE;
- if (cc < assert_back_end)
- common->has_skip_in_assert_back = TRUE;
- if (cc < assert_na_end)
- return FALSE;
- cc += 1 + 2 + cc[1];
- break;
-
- case OP_PRUNE:
- case OP_COMMIT:
- case OP_ASSERT_ACCEPT:
- if (cc < assert_na_end)
- return FALSE;
- cc++;
- break;
-
- default:
- cc = next_opcode(common, cc);
- if (cc == NULL)
- return FALSE;
- break;
- }
- }
-return TRUE;
-}
-
-#define EARLY_FAIL_ENHANCE_MAX (1 + 3)
-
-/*
-start:
- 0 - skip / early fail allowed
- 1 - only early fail with range allowed
- >1 - (start - 1) early fail is processed
-
-return: current number of iterators enhanced with fast fail
-*/
-static int detect_early_fail(compiler_common *common, PCRE2_SPTR cc, int *private_data_start,
- sljit_s32 depth, int start, BOOL fast_forward_allowed)
-{
-PCRE2_SPTR begin = cc;
-PCRE2_SPTR next_alt;
-PCRE2_SPTR end;
-PCRE2_SPTR accelerated_start;
-BOOL prev_fast_forward_allowed;
-int result = 0;
-int count;
-
-SLJIT_ASSERT(*cc == OP_ONCE || *cc == OP_BRA || *cc == OP_CBRA);
-SLJIT_ASSERT(*cc != OP_CBRA || common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] != 0);
-SLJIT_ASSERT(start < EARLY_FAIL_ENHANCE_MAX);
-
-next_alt = cc + GET(cc, 1);
-if (*next_alt == OP_ALT)
- fast_forward_allowed = FALSE;
-
-do
- {
- count = start;
- cc += 1 + LINK_SIZE + ((*cc == OP_CBRA) ? IMM2_SIZE : 0);
-
- while (TRUE)
- {
- accelerated_start = NULL;
-
- switch(*cc)
- {
- case OP_SOD:
- case OP_SOM:
- case OP_SET_SOM:
- case OP_NOT_WORD_BOUNDARY:
- case OP_WORD_BOUNDARY:
- case OP_EODN:
- case OP_EOD:
- case OP_CIRC:
- case OP_CIRCM:
- case OP_DOLL:
- case OP_DOLLM:
- /* Zero width assertions. */
- cc++;
- continue;
-
- case OP_NOT_DIGIT:
- case OP_DIGIT:
- case OP_NOT_WHITESPACE:
- case OP_WHITESPACE:
- case OP_NOT_WORDCHAR:
- case OP_WORDCHAR:
- case OP_ANY:
- case OP_ALLANY:
- case OP_ANYBYTE:
- case OP_NOT_HSPACE:
- case OP_HSPACE:
- case OP_NOT_VSPACE:
- case OP_VSPACE:
- fast_forward_allowed = FALSE;
- cc++;
- continue;
-
- case OP_ANYNL:
- case OP_EXTUNI:
- fast_forward_allowed = FALSE;
- if (count == 0)
- count = 1;
- cc++;
- continue;
-
- case OP_NOTPROP:
- case OP_PROP:
- fast_forward_allowed = FALSE;
- cc += 1 + 2;
- continue;
-
- case OP_CHAR:
- case OP_CHARI:
- case OP_NOT:
- case OP_NOTI:
- fast_forward_allowed = FALSE;
- cc += 2;
-#ifdef SUPPORT_UNICODE
- if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- continue;
-
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSPLUS:
- /* The type or prop opcode is skipped in the next iteration. */
- cc += 1;
-
- if (cc[0] != OP_ANYNL && cc[0] != OP_EXTUNI)
- {
- accelerated_start = cc - 1;
- break;
- }
-
- if (count == 0)
- count = 1;
- fast_forward_allowed = FALSE;
- continue;
-
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEEXACT:
- case OP_TYPEPOSUPTO:
- cc += IMM2_SIZE;
- /* Fall through */
-
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSQUERY:
- /* The type or prop opcode is skipped in the next iteration. */
- fast_forward_allowed = FALSE;
- if (count == 0)
- count = 1;
- cc += 1;
- continue;
-
- case OP_STAR:
- case OP_MINSTAR:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_POSSTAR:
- case OP_POSPLUS:
-
- case OP_STARI:
- case OP_MINSTARI:
- case OP_PLUSI:
- case OP_MINPLUSI:
- case OP_POSSTARI:
- case OP_POSPLUSI:
-
- case OP_NOTSTAR:
- case OP_NOTMINSTAR:
- case OP_NOTPLUS:
- case OP_NOTMINPLUS:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSPLUS:
-
- case OP_NOTSTARI:
- case OP_NOTMINSTARI:
- case OP_NOTPLUSI:
- case OP_NOTMINPLUSI:
- case OP_NOTPOSSTARI:
- case OP_NOTPOSPLUSI:
- accelerated_start = cc;
- cc += 2;
-#ifdef SUPPORT_UNICODE
- if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- break;
-
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_EXACT:
- case OP_POSUPTO:
- case OP_UPTOI:
- case OP_MINUPTOI:
- case OP_EXACTI:
- case OP_POSUPTOI:
- case OP_NOTUPTO:
- case OP_NOTMINUPTO:
- case OP_NOTEXACT:
- case OP_NOTPOSUPTO:
- case OP_NOTUPTOI:
- case OP_NOTMINUPTOI:
- case OP_NOTEXACTI:
- case OP_NOTPOSUPTOI:
- cc += IMM2_SIZE;
- /* Fall through */
-
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_POSQUERY:
- case OP_QUERYI:
- case OP_MINQUERYI:
- case OP_POSQUERYI:
- case OP_NOTQUERY:
- case OP_NOTMINQUERY:
- case OP_NOTPOSQUERY:
- case OP_NOTQUERYI:
- case OP_NOTMINQUERYI:
- case OP_NOTPOSQUERYI:
- fast_forward_allowed = FALSE;
- if (count == 0)
- count = 1;
- cc += 2;
-#ifdef SUPPORT_UNICODE
- if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- continue;
-
- case OP_CLASS:
- case OP_NCLASS:
-#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
- case OP_XCLASS:
- accelerated_start = cc;
- cc += ((*cc == OP_XCLASS) ? GET(cc, 1) : (unsigned int)(1 + (32 / sizeof(PCRE2_UCHAR))));
-#else
- accelerated_start = cc;
- cc += (1 + (32 / sizeof(PCRE2_UCHAR)));
-#endif
-
- switch (*cc)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRPOSSTAR:
- case OP_CRPOSPLUS:
- cc++;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- case OP_CRPOSRANGE:
- cc += 2 * IMM2_SIZE;
- /* Fall through */
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- case OP_CRPOSQUERY:
- cc++;
- if (count == 0)
- count = 1;
- /* Fall through */
- default:
- accelerated_start = NULL;
- fast_forward_allowed = FALSE;
- continue;
- }
- break;
-
- case OP_ONCE:
- case OP_BRA:
- case OP_CBRA:
- end = cc + GET(cc, 1);
-
- prev_fast_forward_allowed = fast_forward_allowed;
- fast_forward_allowed = FALSE;
- if (depth >= 4)
- break;
-
- end = bracketend(cc) - (1 + LINK_SIZE);
- if (*end != OP_KET || (*cc == OP_CBRA && common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0))
- break;
-
- count = detect_early_fail(common, cc, private_data_start, depth + 1, count, prev_fast_forward_allowed);
-
- if (PRIVATE_DATA(cc) != 0)
- common->private_data_ptrs[begin - common->start] = 1;
-
- if (count < EARLY_FAIL_ENHANCE_MAX)
- {
- cc = end + (1 + LINK_SIZE);
- continue;
- }
- break;
-
- case OP_KET:
- SLJIT_ASSERT(PRIVATE_DATA(cc) == 0);
- if (cc >= next_alt)
- break;
- cc += 1 + LINK_SIZE;
- continue;
- }
-
- if (accelerated_start != NULL)
- {
- if (count == 0)
- {
- count++;
-
- if (fast_forward_allowed)
- {
- common->fast_forward_bc_ptr = accelerated_start;
- common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_skip;
- *private_data_start += sizeof(sljit_sw);
- }
- else
- {
- common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_fail;
-
- if (common->early_fail_start_ptr == 0)
- common->early_fail_start_ptr = *private_data_start;
-
- *private_data_start += sizeof(sljit_sw);
- common->early_fail_end_ptr = *private_data_start;
-
- if (*private_data_start > SLJIT_MAX_LOCAL_SIZE)
- return EARLY_FAIL_ENHANCE_MAX;
- }
- }
- else
- {
- common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_fail_range;
-
- if (common->early_fail_start_ptr == 0)
- common->early_fail_start_ptr = *private_data_start;
-
- *private_data_start += 2 * sizeof(sljit_sw);
- common->early_fail_end_ptr = *private_data_start;
-
- if (*private_data_start > SLJIT_MAX_LOCAL_SIZE)
- return EARLY_FAIL_ENHANCE_MAX;
- }
-
- /* Cannot be part of a repeat. */
- common->private_data_ptrs[begin - common->start] = 1;
- count++;
-
- if (count < EARLY_FAIL_ENHANCE_MAX)
- continue;
- }
-
- break;
- }
-
- if (*cc != OP_ALT && *cc != OP_KET)
- result = EARLY_FAIL_ENHANCE_MAX;
- else if (result < count)
- result = count;
-
- cc = next_alt;
- next_alt = cc + GET(cc, 1);
- }
-while (*cc == OP_ALT);
-
-return result;
-}
-
-static int get_class_iterator_size(PCRE2_SPTR cc)
-{
-sljit_u32 min;
-sljit_u32 max;
-switch(*cc)
- {
- case OP_CRSTAR:
- case OP_CRPLUS:
- return 2;
-
- case OP_CRMINSTAR:
- case OP_CRMINPLUS:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- return 1;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- min = GET2(cc, 1);
- max = GET2(cc, 1 + IMM2_SIZE);
- if (max == 0)
- return (*cc == OP_CRRANGE) ? 2 : 1;
- max -= min;
- if (max > 2)
- max = 2;
- return max;
-
- default:
- return 0;
- }
-}
-
-static BOOL detect_repeat(compiler_common *common, PCRE2_SPTR begin)
-{
-PCRE2_SPTR end = bracketend(begin);
-PCRE2_SPTR next;
-PCRE2_SPTR next_end;
-PCRE2_SPTR max_end;
-PCRE2_UCHAR type;
-sljit_sw length = end - begin;
-sljit_s32 min, max, i;
-
-/* Detect fixed iterations first. */
-if (end[-(1 + LINK_SIZE)] != OP_KET || PRIVATE_DATA(begin) != 0)
- return FALSE;
-
-/* /(?:AB){4,6}/ is currently converted to /(?:AB){3}(?AB){1,3}/
- * Skip the check of the second part. */
-if (PRIVATE_DATA(end - LINK_SIZE) != 0)
- return TRUE;
-
-next = end;
-min = 1;
-while (1)
- {
- if (*next != *begin)
- break;
- next_end = bracketend(next);
- if (next_end - next != length || memcmp(begin, next, IN_UCHARS(length)) != 0)
- break;
- next = next_end;
- min++;
- }
-
-if (min == 2)
- return FALSE;
-
-max = 0;
-max_end = next;
-if (*next == OP_BRAZERO || *next == OP_BRAMINZERO)
- {
- type = *next;
- while (1)
- {
- if (next[0] != type || next[1] != OP_BRA || next[2 + LINK_SIZE] != *begin)
- break;
- next_end = bracketend(next + 2 + LINK_SIZE);
- if (next_end - next != (length + 2 + LINK_SIZE) || memcmp(begin, next + 2 + LINK_SIZE, IN_UCHARS(length)) != 0)
- break;
- next = next_end;
- max++;
- }
-
- if (next[0] == type && next[1] == *begin && max >= 1)
- {
- next_end = bracketend(next + 1);
- if (next_end - next == (length + 1) && memcmp(begin, next + 1, IN_UCHARS(length)) == 0)
- {
- for (i = 0; i < max; i++, next_end += 1 + LINK_SIZE)
- if (*next_end != OP_KET)
- break;
-
- if (i == max)
- {
- common->private_data_ptrs[max_end - common->start - LINK_SIZE] = next_end - max_end;
- common->private_data_ptrs[max_end - common->start - LINK_SIZE + 1] = (type == OP_BRAZERO) ? OP_UPTO : OP_MINUPTO;
- /* +2 the original and the last. */
- common->private_data_ptrs[max_end - common->start - LINK_SIZE + 2] = max + 2;
- if (min == 1)
- return TRUE;
- min--;
- max_end -= (1 + LINK_SIZE) + GET(max_end, -LINK_SIZE);
- }
- }
- }
- }
-
-if (min >= 3)
- {
- common->private_data_ptrs[end - common->start - LINK_SIZE] = max_end - end;
- common->private_data_ptrs[end - common->start - LINK_SIZE + 1] = OP_EXACT;
- common->private_data_ptrs[end - common->start - LINK_SIZE + 2] = min;
- return TRUE;
- }
-
-return FALSE;
-}
-
-#define CASE_ITERATOR_PRIVATE_DATA_1 \
- case OP_MINSTAR: \
- case OP_MINPLUS: \
- case OP_QUERY: \
- case OP_MINQUERY: \
- case OP_MINSTARI: \
- case OP_MINPLUSI: \
- case OP_QUERYI: \
- case OP_MINQUERYI: \
- case OP_NOTMINSTAR: \
- case OP_NOTMINPLUS: \
- case OP_NOTQUERY: \
- case OP_NOTMINQUERY: \
- case OP_NOTMINSTARI: \
- case OP_NOTMINPLUSI: \
- case OP_NOTQUERYI: \
- case OP_NOTMINQUERYI:
-
-#define CASE_ITERATOR_PRIVATE_DATA_2A \
- case OP_STAR: \
- case OP_PLUS: \
- case OP_STARI: \
- case OP_PLUSI: \
- case OP_NOTSTAR: \
- case OP_NOTPLUS: \
- case OP_NOTSTARI: \
- case OP_NOTPLUSI:
-
-#define CASE_ITERATOR_PRIVATE_DATA_2B \
- case OP_UPTO: \
- case OP_MINUPTO: \
- case OP_UPTOI: \
- case OP_MINUPTOI: \
- case OP_NOTUPTO: \
- case OP_NOTMINUPTO: \
- case OP_NOTUPTOI: \
- case OP_NOTMINUPTOI:
-
-#define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
- case OP_TYPEMINSTAR: \
- case OP_TYPEMINPLUS: \
- case OP_TYPEQUERY: \
- case OP_TYPEMINQUERY:
-
-#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
- case OP_TYPESTAR: \
- case OP_TYPEPLUS:
-
-#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
- case OP_TYPEUPTO: \
- case OP_TYPEMINUPTO:
-
-static void set_private_data_ptrs(compiler_common *common, int *private_data_start, PCRE2_SPTR ccend)
-{
-PCRE2_SPTR cc = common->start;
-PCRE2_SPTR alternative;
-PCRE2_SPTR end = NULL;
-int private_data_ptr = *private_data_start;
-int space, size, bracketlen;
-BOOL repeat_check = TRUE;
-
-while (cc < ccend)
- {
- space = 0;
- size = 0;
- bracketlen = 0;
- if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE)
- break;
-
- /* When the bracket is prefixed by a zero iteration, skip the repeat check (at this point). */
- if (repeat_check && (*cc == OP_ONCE || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND))
- {
- if (detect_repeat(common, cc))
- {
- /* These brackets are converted to repeats, so no global
- based single character repeat is allowed. */
- if (cc >= end)
- end = bracketend(cc);
- }
- }
- repeat_check = TRUE;
-
- switch(*cc)
- {
- case OP_KET:
- if (common->private_data_ptrs[cc + 1 - common->start] != 0)
- {
- common->private_data_ptrs[cc - common->start] = private_data_ptr;
- private_data_ptr += sizeof(sljit_sw);
- cc += common->private_data_ptrs[cc + 1 - common->start];
- }
- cc += 1 + LINK_SIZE;
- break;
-
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- case OP_ASSERT_NA:
- case OP_ASSERTBACK_NA:
- case OP_ONCE:
- case OP_SCRIPT_RUN:
- case OP_BRAPOS:
- case OP_SBRA:
- case OP_SBRAPOS:
- case OP_SCOND:
- common->private_data_ptrs[cc - common->start] = private_data_ptr;
- private_data_ptr += sizeof(sljit_sw);
- bracketlen = 1 + LINK_SIZE;
- break;
-
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- common->private_data_ptrs[cc - common->start] = private_data_ptr;
- private_data_ptr += sizeof(sljit_sw);
- bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
- break;
-
- case OP_COND:
- /* Might be a hidden SCOND. */
- common->private_data_ptrs[cc - common->start] = 0;
- alternative = cc + GET(cc, 1);
- if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
- {
- common->private_data_ptrs[cc - common->start] = private_data_ptr;
- private_data_ptr += sizeof(sljit_sw);
- }
- bracketlen = 1 + LINK_SIZE;
- break;
-
- case OP_BRA:
- bracketlen = 1 + LINK_SIZE;
- break;
-
- case OP_CBRA:
- case OP_SCBRA:
- bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
- break;
-
- case OP_BRAZERO:
- case OP_BRAMINZERO:
- case OP_BRAPOSZERO:
- size = 1;
- repeat_check = FALSE;
- break;
-
- CASE_ITERATOR_PRIVATE_DATA_1
- size = -2;
- space = 1;
- break;
-
- CASE_ITERATOR_PRIVATE_DATA_2A
- size = -2;
- space = 2;
- break;
-
- CASE_ITERATOR_PRIVATE_DATA_2B
- size = -(2 + IMM2_SIZE);
- space = 2;
- break;
-
- CASE_ITERATOR_TYPE_PRIVATE_DATA_1
- size = 1;
- space = 1;
- break;
-
- CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
- size = 1;
- if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
- space = 2;
- break;
-
- case OP_TYPEUPTO:
- size = 1 + IMM2_SIZE;
- if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
- space = 2;
- break;
-
- case OP_TYPEMINUPTO:
- size = 1 + IMM2_SIZE;
- space = 2;
- break;
-
- case OP_CLASS:
- case OP_NCLASS:
- size = 1 + 32 / sizeof(PCRE2_UCHAR);
- space = get_class_iterator_size(cc + size);
- break;
-
-#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
- case OP_XCLASS:
- size = GET(cc, 1);
- space = get_class_iterator_size(cc + size);
- break;
-#endif
-
- default:
- cc = next_opcode(common, cc);
- SLJIT_ASSERT(cc != NULL);
- break;
- }
-
- /* Character iterators, which are not inside a repeated bracket,
- gets a private slot instead of allocating it on the stack. */
- if (space > 0 && cc >= end)
- {
- common->private_data_ptrs[cc - common->start] = private_data_ptr;
- private_data_ptr += sizeof(sljit_sw) * space;
- }
-
- if (size != 0)
- {
- if (size < 0)
- {
- cc += -size;
-#ifdef SUPPORT_UNICODE
- if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- }
- else
- cc += size;
- }
-
- if (bracketlen > 0)
- {
- if (cc >= end)
- {
- end = bracketend(cc);
- if (end[-1 - LINK_SIZE] == OP_KET)
- end = NULL;
- }
- cc += bracketlen;
- }
- }
-*private_data_start = private_data_ptr;
-}
-
-/* Returns with a frame_types (always < 0) if no need for frame. */
-static int get_framesize(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, BOOL recursive, BOOL *needs_control_head)
-{
-int length = 0;
-int possessive = 0;
-BOOL stack_restore = FALSE;
-BOOL setsom_found = recursive;
-BOOL setmark_found = recursive;
-/* The last capture is a local variable even for recursions. */
-BOOL capture_last_found = FALSE;
-
-#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
-SLJIT_ASSERT(common->control_head_ptr != 0);
-*needs_control_head = TRUE;
-#else
-*needs_control_head = FALSE;
-#endif
-
-if (ccend == NULL)
- {
- ccend = bracketend(cc) - (1 + LINK_SIZE);
- if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
- {
- possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
- /* This is correct regardless of common->capture_last_ptr. */
- capture_last_found = TRUE;
- }
- cc = next_opcode(common, cc);
- }
-
-SLJIT_ASSERT(cc != NULL);
-while (cc < ccend)
- switch(*cc)
- {
- case OP_SET_SOM:
- SLJIT_ASSERT(common->has_set_som);
- stack_restore = TRUE;
- if (!setsom_found)
- {
- length += 2;
- setsom_found = TRUE;
- }
- cc += 1;
- break;
-
- case OP_MARK:
- case OP_COMMIT_ARG:
- case OP_PRUNE_ARG:
- case OP_THEN_ARG:
- SLJIT_ASSERT(common->mark_ptr != 0);
- stack_restore = TRUE;
- if (!setmark_found)
- {
- length += 2;
- setmark_found = TRUE;
- }
- if (common->control_head_ptr != 0)
- *needs_control_head = TRUE;
- cc += 1 + 2 + cc[1];
- break;
-
- case OP_RECURSE:
- stack_restore = TRUE;
- if (common->has_set_som && !setsom_found)
- {
- length += 2;
- setsom_found = TRUE;
- }
- if (common->mark_ptr != 0 && !setmark_found)
- {
- length += 2;
- setmark_found = TRUE;
- }
- if (common->capture_last_ptr != 0 && !capture_last_found)
- {
- length += 2;
- capture_last_found = TRUE;
- }
- cc += 1 + LINK_SIZE;
- break;
-
- case OP_CBRA:
- case OP_CBRAPOS:
- case OP_SCBRA:
- case OP_SCBRAPOS:
- stack_restore = TRUE;
- if (common->capture_last_ptr != 0 && !capture_last_found)
- {
- length += 2;
- capture_last_found = TRUE;
- }
- length += 3;
- cc += 1 + LINK_SIZE + IMM2_SIZE;
- break;
-
- case OP_THEN:
- stack_restore = TRUE;
- if (common->control_head_ptr != 0)
- *needs_control_head = TRUE;
- cc ++;
- break;
-
- default:
- stack_restore = TRUE;
- /* Fall through. */
-
- case OP_NOT_WORD_BOUNDARY:
- case OP_WORD_BOUNDARY:
- case OP_NOT_DIGIT:
- case OP_DIGIT:
- case OP_NOT_WHITESPACE:
- case OP_WHITESPACE:
- case OP_NOT_WORDCHAR:
- case OP_WORDCHAR:
- case OP_ANY:
- case OP_ALLANY:
- case OP_ANYBYTE:
- case OP_NOTPROP:
- case OP_PROP:
- case OP_ANYNL:
- case OP_NOT_HSPACE:
- case OP_HSPACE:
- case OP_NOT_VSPACE:
- case OP_VSPACE:
- case OP_EXTUNI:
- case OP_EODN:
- case OP_EOD:
- case OP_CIRC:
- case OP_CIRCM:
- case OP_DOLL:
- case OP_DOLLM:
- case OP_CHAR:
- case OP_CHARI:
- case OP_NOT:
- case OP_NOTI:
-
- case OP_EXACT:
- case OP_POSSTAR:
- case OP_POSPLUS:
- case OP_POSQUERY:
- case OP_POSUPTO:
-
- case OP_EXACTI:
- case OP_POSSTARI:
- case OP_POSPLUSI:
- case OP_POSQUERYI:
- case OP_POSUPTOI:
-
- case OP_NOTEXACT:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSPLUS:
- case OP_NOTPOSQUERY:
- case OP_NOTPOSUPTO:
-
- case OP_NOTEXACTI:
- case OP_NOTPOSSTARI:
- case OP_NOTPOSPLUSI:
- case OP_NOTPOSQUERYI:
- case OP_NOTPOSUPTOI:
-
- case OP_TYPEEXACT:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSPLUS:
- case OP_TYPEPOSQUERY:
- case OP_TYPEPOSUPTO:
-
- case OP_CLASS:
- case OP_NCLASS:
- case OP_XCLASS:
-
- case OP_CALLOUT:
- case OP_CALLOUT_STR:
-
- cc = next_opcode(common, cc);
- SLJIT_ASSERT(cc != NULL);
- break;
- }
-
-/* Possessive quantifiers can use a special case. */
-if (SLJIT_UNLIKELY(possessive == length))
- return stack_restore ? no_frame : no_stack;
-
-if (length > 0)
- return length + 1;
-return stack_restore ? no_frame : no_stack;
-}
-
-static void init_frame(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, int stackpos, int stacktop)
-{
-DEFINE_COMPILER;
-BOOL setsom_found = FALSE;
-BOOL setmark_found = FALSE;
-/* The last capture is a local variable even for recursions. */
-BOOL capture_last_found = FALSE;
-int offset;
-
-/* >= 1 + shortest item size (2) */
-SLJIT_UNUSED_ARG(stacktop);
-SLJIT_ASSERT(stackpos >= stacktop + 2);
-
-stackpos = STACK(stackpos);
-if (ccend == NULL)
- {
- ccend = bracketend(cc) - (1 + LINK_SIZE);
- if (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS)
- cc = next_opcode(common, cc);
- }
-
-SLJIT_ASSERT(cc != NULL);
-while (cc < ccend)
- switch(*cc)
- {
- case OP_SET_SOM:
- SLJIT_ASSERT(common->has_set_som);
- if (!setsom_found)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
- stackpos -= SSIZE_OF(sw);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
- stackpos -= SSIZE_OF(sw);
- setsom_found = TRUE;
- }
- cc += 1;
- break;
-
- case OP_MARK:
- case OP_COMMIT_ARG:
- case OP_PRUNE_ARG:
- case OP_THEN_ARG:
- SLJIT_ASSERT(common->mark_ptr != 0);
- if (!setmark_found)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
- stackpos -= SSIZE_OF(sw);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
- stackpos -= SSIZE_OF(sw);
- setmark_found = TRUE;
- }
- cc += 1 + 2 + cc[1];
- break;
-
- case OP_RECURSE:
- if (common->has_set_som && !setsom_found)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
- stackpos -= SSIZE_OF(sw);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
- stackpos -= SSIZE_OF(sw);
- setsom_found = TRUE;
- }
- if (common->mark_ptr != 0 && !setmark_found)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
- stackpos -= SSIZE_OF(sw);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
- stackpos -= SSIZE_OF(sw);
- setmark_found = TRUE;
- }
- if (common->capture_last_ptr != 0 && !capture_last_found)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
- stackpos -= SSIZE_OF(sw);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
- stackpos -= SSIZE_OF(sw);
- capture_last_found = TRUE;
- }
- cc += 1 + LINK_SIZE;
- break;
-
- case OP_CBRA:
- case OP_CBRAPOS:
- case OP_SCBRA:
- case OP_SCBRAPOS:
- if (common->capture_last_ptr != 0 && !capture_last_found)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
- stackpos -= SSIZE_OF(sw);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
- stackpos -= SSIZE_OF(sw);
- capture_last_found = TRUE;
- }
- offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
- stackpos -= SSIZE_OF(sw);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
- stackpos -= SSIZE_OF(sw);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
- stackpos -= SSIZE_OF(sw);
-
- cc += 1 + LINK_SIZE + IMM2_SIZE;
- break;
-
- default:
- cc = next_opcode(common, cc);
- SLJIT_ASSERT(cc != NULL);
- break;
- }
-
-OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0);
-SLJIT_ASSERT(stackpos == STACK(stacktop));
-}
-
-#define RECURSE_TMP_REG_COUNT 3
-
-typedef struct delayed_mem_copy_status {
- struct sljit_compiler *compiler;
- int store_bases[RECURSE_TMP_REG_COUNT];
- int store_offsets[RECURSE_TMP_REG_COUNT];
- int tmp_regs[RECURSE_TMP_REG_COUNT];
- int saved_tmp_regs[RECURSE_TMP_REG_COUNT];
- int next_tmp_reg;
-} delayed_mem_copy_status;
-
-static void delayed_mem_copy_init(delayed_mem_copy_status *status, compiler_common *common)
-{
-int i;
-
-for (i = 0; i < RECURSE_TMP_REG_COUNT; i++)
- {
- SLJIT_ASSERT(status->tmp_regs[i] >= 0);
- SLJIT_ASSERT(sljit_get_register_index(status->saved_tmp_regs[i]) < 0 || status->tmp_regs[i] == status->saved_tmp_regs[i]);
-
- status->store_bases[i] = -1;
- }
-status->next_tmp_reg = 0;
-status->compiler = common->compiler;
-}
-
-static void delayed_mem_copy_move(delayed_mem_copy_status *status, int load_base, sljit_sw load_offset,
- int store_base, sljit_sw store_offset)
-{
-struct sljit_compiler *compiler = status->compiler;
-int next_tmp_reg = status->next_tmp_reg;
-int tmp_reg = status->tmp_regs[next_tmp_reg];
-
-SLJIT_ASSERT(load_base > 0 && store_base > 0);
-
-if (status->store_bases[next_tmp_reg] == -1)
- {
- /* Preserve virtual registers. */
- if (sljit_get_register_index(status->saved_tmp_regs[next_tmp_reg]) < 0)
- OP1(SLJIT_MOV, status->saved_tmp_regs[next_tmp_reg], 0, tmp_reg, 0);
- }
-else
- OP1(SLJIT_MOV, SLJIT_MEM1(status->store_bases[next_tmp_reg]), status->store_offsets[next_tmp_reg], tmp_reg, 0);
-
-OP1(SLJIT_MOV, tmp_reg, 0, SLJIT_MEM1(load_base), load_offset);
-status->store_bases[next_tmp_reg] = store_base;
-status->store_offsets[next_tmp_reg] = store_offset;
-
-status->next_tmp_reg = (next_tmp_reg + 1) % RECURSE_TMP_REG_COUNT;
-}
-
-static void delayed_mem_copy_finish(delayed_mem_copy_status *status)
-{
-struct sljit_compiler *compiler = status->compiler;
-int next_tmp_reg = status->next_tmp_reg;
-int tmp_reg, saved_tmp_reg, i;
-
-for (i = 0; i < RECURSE_TMP_REG_COUNT; i++)
- {
- if (status->store_bases[next_tmp_reg] != -1)
- {
- tmp_reg = status->tmp_regs[next_tmp_reg];
- saved_tmp_reg = status->saved_tmp_regs[next_tmp_reg];
-
- OP1(SLJIT_MOV, SLJIT_MEM1(status->store_bases[next_tmp_reg]), status->store_offsets[next_tmp_reg], tmp_reg, 0);
-
- /* Restore virtual registers. */
- if (sljit_get_register_index(saved_tmp_reg) < 0)
- OP1(SLJIT_MOV, tmp_reg, 0, saved_tmp_reg, 0);
- }
-
- next_tmp_reg = (next_tmp_reg + 1) % RECURSE_TMP_REG_COUNT;
- }
-}
-
-#undef RECURSE_TMP_REG_COUNT
-
-static BOOL recurse_check_bit(compiler_common *common, sljit_sw bit_index)
-{
-uint8_t *byte;
-uint8_t mask;
-
-SLJIT_ASSERT((bit_index & (sizeof(sljit_sw) - 1)) == 0);
-
-bit_index >>= SLJIT_WORD_SHIFT;
-
-SLJIT_ASSERT((bit_index >> 3) < common->recurse_bitset_size);
-
-mask = 1 << (bit_index & 0x7);
-byte = common->recurse_bitset + (bit_index >> 3);
-
-if (*byte & mask)
- return FALSE;
-
-*byte |= mask;
-return TRUE;
-}
-
-enum get_recurse_flags {
- recurse_flag_quit_found = (1 << 0),
- recurse_flag_accept_found = (1 << 1),
- recurse_flag_setsom_found = (1 << 2),
- recurse_flag_setmark_found = (1 << 3),
- recurse_flag_control_head_found = (1 << 4),
-};
-
-static int get_recurse_data_length(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, uint32_t *result_flags)
-{
-int length = 1;
-int size, offset;
-PCRE2_SPTR alternative;
-uint32_t recurse_flags = 0;
-
-memset(common->recurse_bitset, 0, common->recurse_bitset_size);
-
-#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
-SLJIT_ASSERT(common->control_head_ptr != 0);
-recurse_flags |= recurse_flag_control_head_found;
-#endif
-
-/* Calculate the sum of the private machine words. */
-while (cc < ccend)
- {
- size = 0;
- switch(*cc)
- {
- case OP_SET_SOM:
- SLJIT_ASSERT(common->has_set_som);
- recurse_flags |= recurse_flag_setsom_found;
- cc += 1;
- break;
-
- case OP_RECURSE:
- if (common->has_set_som)
- recurse_flags |= recurse_flag_setsom_found;
- if (common->mark_ptr != 0)
- recurse_flags |= recurse_flag_setmark_found;
- if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
- length++;
- cc += 1 + LINK_SIZE;
- break;
-
- case OP_KET:
- offset = PRIVATE_DATA(cc);
- if (offset != 0)
- {
- if (recurse_check_bit(common, offset))
- length++;
- SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0);
- cc += PRIVATE_DATA(cc + 1);
- }
- cc += 1 + LINK_SIZE;
- break;
-
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- case OP_ASSERT_NA:
- case OP_ASSERTBACK_NA:
- case OP_ONCE:
- case OP_SCRIPT_RUN:
- case OP_BRAPOS:
- case OP_SBRA:
- case OP_SBRAPOS:
- case OP_SCOND:
- SLJIT_ASSERT(PRIVATE_DATA(cc) != 0);
- if (recurse_check_bit(common, PRIVATE_DATA(cc)))
- length++;
- cc += 1 + LINK_SIZE;
- break;
-
- case OP_CBRA:
- case OP_SCBRA:
- offset = GET2(cc, 1 + LINK_SIZE);
- if (recurse_check_bit(common, OVECTOR(offset << 1)))
- {
- SLJIT_ASSERT(recurse_check_bit(common, OVECTOR((offset << 1) + 1)));
- length += 2;
- }
- if (common->optimized_cbracket[offset] == 0 && recurse_check_bit(common, OVECTOR_PRIV(offset)))
- length++;
- if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
- length++;
- cc += 1 + LINK_SIZE + IMM2_SIZE;
- break;
-
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- offset = GET2(cc, 1 + LINK_SIZE);
- if (recurse_check_bit(common, OVECTOR(offset << 1)))
- {
- SLJIT_ASSERT(recurse_check_bit(common, OVECTOR((offset << 1) + 1)));
- length += 2;
- }
- if (recurse_check_bit(common, OVECTOR_PRIV(offset)))
- length++;
- if (recurse_check_bit(common, PRIVATE_DATA(cc)))
- length++;
- if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
- length++;
- cc += 1 + LINK_SIZE + IMM2_SIZE;
- break;
-
- case OP_COND:
- /* Might be a hidden SCOND. */
- alternative = cc + GET(cc, 1);
- if ((*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) && recurse_check_bit(common, PRIVATE_DATA(cc)))
- length++;
- cc += 1 + LINK_SIZE;
- break;
-
- CASE_ITERATOR_PRIVATE_DATA_1
- offset = PRIVATE_DATA(cc);
- if (offset != 0 && recurse_check_bit(common, offset))
- length++;
- cc += 2;
-#ifdef SUPPORT_UNICODE
- if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- break;
-
- CASE_ITERATOR_PRIVATE_DATA_2A
- offset = PRIVATE_DATA(cc);
- if (offset != 0 && recurse_check_bit(common, offset))
- {
- SLJIT_ASSERT(recurse_check_bit(common, offset + sizeof(sljit_sw)));
- length += 2;
- }
- cc += 2;
-#ifdef SUPPORT_UNICODE
- if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- break;
-
- CASE_ITERATOR_PRIVATE_DATA_2B
- offset = PRIVATE_DATA(cc);
- if (offset != 0 && recurse_check_bit(common, offset))
- {
- SLJIT_ASSERT(recurse_check_bit(common, offset + sizeof(sljit_sw)));
- length += 2;
- }
- cc += 2 + IMM2_SIZE;
-#ifdef SUPPORT_UNICODE
- if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- break;
-
- CASE_ITERATOR_TYPE_PRIVATE_DATA_1
- offset = PRIVATE_DATA(cc);
- if (offset != 0 && recurse_check_bit(common, offset))
- length++;
- cc += 1;
- break;
-
- CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
- offset = PRIVATE_DATA(cc);
- if (offset != 0 && recurse_check_bit(common, offset))
- {
- SLJIT_ASSERT(recurse_check_bit(common, offset + sizeof(sljit_sw)));
- length += 2;
- }
- cc += 1;
- break;
-
- CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
- offset = PRIVATE_DATA(cc);
- if (offset != 0 && recurse_check_bit(common, offset))
- {
- SLJIT_ASSERT(recurse_check_bit(common, offset + sizeof(sljit_sw)));
- length += 2;
- }
- cc += 1 + IMM2_SIZE;
- break;
-
- case OP_CLASS:
- case OP_NCLASS:
-#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
- case OP_XCLASS:
- size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(PCRE2_UCHAR);
-#else
- size = 1 + 32 / (int)sizeof(PCRE2_UCHAR);
-#endif
-
- offset = PRIVATE_DATA(cc);
- if (offset != 0 && recurse_check_bit(common, offset))
- length += get_class_iterator_size(cc + size);
- cc += size;
- break;
-
- case OP_MARK:
- case OP_COMMIT_ARG:
- case OP_PRUNE_ARG:
- case OP_THEN_ARG:
- SLJIT_ASSERT(common->mark_ptr != 0);
- recurse_flags |= recurse_flag_setmark_found;
- if (common->control_head_ptr != 0)
- recurse_flags |= recurse_flag_control_head_found;
- if (*cc != OP_MARK)
- recurse_flags |= recurse_flag_quit_found;
-
- cc += 1 + 2 + cc[1];
- break;
-
- case OP_PRUNE:
- case OP_SKIP:
- case OP_COMMIT:
- recurse_flags |= recurse_flag_quit_found;
- cc++;
- break;
-
- case OP_SKIP_ARG:
- recurse_flags |= recurse_flag_quit_found;
- cc += 1 + 2 + cc[1];
- break;
-
- case OP_THEN:
- SLJIT_ASSERT(common->control_head_ptr != 0);
- recurse_flags |= recurse_flag_quit_found | recurse_flag_control_head_found;
- cc++;
- break;
-
- case OP_ACCEPT:
- case OP_ASSERT_ACCEPT:
- recurse_flags |= recurse_flag_accept_found;
- cc++;
- break;
-
- default:
- cc = next_opcode(common, cc);
- SLJIT_ASSERT(cc != NULL);
- break;
- }
- }
-SLJIT_ASSERT(cc == ccend);
-
-if (recurse_flags & recurse_flag_control_head_found)
- length++;
-if (recurse_flags & recurse_flag_quit_found)
- {
- if (recurse_flags & recurse_flag_setsom_found)
- length++;
- if (recurse_flags & recurse_flag_setmark_found)
- length++;
- }
-
-*result_flags = recurse_flags;
-return length;
-}
-
-enum copy_recurse_data_types {
- recurse_copy_from_global,
- recurse_copy_private_to_global,
- recurse_copy_shared_to_global,
- recurse_copy_kept_shared_to_global,
- recurse_swap_global
-};
-
-static void copy_recurse_data(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend,
- int type, int stackptr, int stacktop, uint32_t recurse_flags)
-{
-delayed_mem_copy_status status;
-PCRE2_SPTR alternative;
-sljit_sw private_srcw[2];
-sljit_sw shared_srcw[3];
-sljit_sw kept_shared_srcw[2];
-int private_count, shared_count, kept_shared_count;
-int from_sp, base_reg, offset, i;
-
-memset(common->recurse_bitset, 0, common->recurse_bitset_size);
-
-#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
-SLJIT_ASSERT(common->control_head_ptr != 0);
-recurse_check_bit(common, common->control_head_ptr);
-#endif
-
-switch (type)
- {
- case recurse_copy_from_global:
- from_sp = TRUE;
- base_reg = STACK_TOP;
- break;
-
- case recurse_copy_private_to_global:
- case recurse_copy_shared_to_global:
- case recurse_copy_kept_shared_to_global:
- from_sp = FALSE;
- base_reg = STACK_TOP;
- break;
-
- default:
- SLJIT_ASSERT(type == recurse_swap_global);
- from_sp = FALSE;
- base_reg = TMP2;
- break;
- }
-
-stackptr = STACK(stackptr);
-stacktop = STACK(stacktop);
-
-status.tmp_regs[0] = TMP1;
-status.saved_tmp_regs[0] = TMP1;
-
-if (base_reg != TMP2)
- {
- status.tmp_regs[1] = TMP2;
- status.saved_tmp_regs[1] = TMP2;
- }
-else
- {
- status.saved_tmp_regs[1] = RETURN_ADDR;
- if (HAS_VIRTUAL_REGISTERS)
- status.tmp_regs[1] = STR_PTR;
- else
- status.tmp_regs[1] = RETURN_ADDR;
- }
-
-status.saved_tmp_regs[2] = TMP3;
-if (HAS_VIRTUAL_REGISTERS)
- status.tmp_regs[2] = STR_END;
-else
- status.tmp_regs[2] = TMP3;
-
-delayed_mem_copy_init(&status, common);
-
-if (type != recurse_copy_shared_to_global && type != recurse_copy_kept_shared_to_global)
- {
- SLJIT_ASSERT(type == recurse_copy_from_global || type == recurse_copy_private_to_global || type == recurse_swap_global);
-
- if (!from_sp)
- delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, common->recursive_head_ptr);
-
- if (from_sp || type == recurse_swap_global)
- delayed_mem_copy_move(&status, SLJIT_SP, common->recursive_head_ptr, base_reg, stackptr);
- }
-
-stackptr += sizeof(sljit_sw);
-
-#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
-if (type != recurse_copy_shared_to_global)
- {
- if (!from_sp)
- delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, common->control_head_ptr);
-
- if (from_sp || type == recurse_swap_global)
- delayed_mem_copy_move(&status, SLJIT_SP, common->control_head_ptr, base_reg, stackptr);
- }
-
-stackptr += sizeof(sljit_sw);
-#endif
-
-while (cc < ccend)
- {
- private_count = 0;
- shared_count = 0;
- kept_shared_count = 0;
-
- switch(*cc)
- {
- case OP_SET_SOM:
- SLJIT_ASSERT(common->has_set_som);
- if ((recurse_flags & recurse_flag_quit_found) && recurse_check_bit(common, OVECTOR(0)))
- {
- kept_shared_srcw[0] = OVECTOR(0);
- kept_shared_count = 1;
- }
- cc += 1;
- break;
-
- case OP_RECURSE:
- if (recurse_flags & recurse_flag_quit_found)
- {
- if (common->has_set_som && recurse_check_bit(common, OVECTOR(0)))
- {
- kept_shared_srcw[0] = OVECTOR(0);
- kept_shared_count = 1;
- }
- if (common->mark_ptr != 0 && recurse_check_bit(common, common->mark_ptr))
- {
- kept_shared_srcw[kept_shared_count] = common->mark_ptr;
- kept_shared_count++;
- }
- }
- if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
- {
- shared_srcw[0] = common->capture_last_ptr;
- shared_count = 1;
- }
- cc += 1 + LINK_SIZE;
- break;
-
- case OP_KET:
- private_srcw[0] = PRIVATE_DATA(cc);
- if (private_srcw[0] != 0)
- {
- if (recurse_check_bit(common, private_srcw[0]))
- private_count = 1;
- SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0);
- cc += PRIVATE_DATA(cc + 1);
- }
- cc += 1 + LINK_SIZE;
- break;
-
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- case OP_ASSERT_NA:
- case OP_ASSERTBACK_NA:
- case OP_ONCE:
- case OP_SCRIPT_RUN:
- case OP_BRAPOS:
- case OP_SBRA:
- case OP_SBRAPOS:
- case OP_SCOND:
- private_srcw[0] = PRIVATE_DATA(cc);
- if (recurse_check_bit(common, private_srcw[0]))
- private_count = 1;
- cc += 1 + LINK_SIZE;
- break;
-
- case OP_CBRA:
- case OP_SCBRA:
- offset = GET2(cc, 1 + LINK_SIZE);
- shared_srcw[0] = OVECTOR(offset << 1);
- if (recurse_check_bit(common, shared_srcw[0]))
- {
- shared_srcw[1] = shared_srcw[0] + sizeof(sljit_sw);
- SLJIT_ASSERT(recurse_check_bit(common, shared_srcw[1]));
- shared_count = 2;
- }
-
- if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
- {
- shared_srcw[shared_count] = common->capture_last_ptr;
- shared_count++;
- }
-
- if (common->optimized_cbracket[offset] == 0)
- {
- private_srcw[0] = OVECTOR_PRIV(offset);
- if (recurse_check_bit(common, private_srcw[0]))
- private_count = 1;
- }
-
- cc += 1 + LINK_SIZE + IMM2_SIZE;
- break;
-
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- offset = GET2(cc, 1 + LINK_SIZE);
- shared_srcw[0] = OVECTOR(offset << 1);
- if (recurse_check_bit(common, shared_srcw[0]))
- {
- shared_srcw[1] = shared_srcw[0] + sizeof(sljit_sw);
- SLJIT_ASSERT(recurse_check_bit(common, shared_srcw[1]));
- shared_count = 2;
- }
-
- if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
- {
- shared_srcw[shared_count] = common->capture_last_ptr;
- shared_count++;
- }
-
- private_srcw[0] = PRIVATE_DATA(cc);
- if (recurse_check_bit(common, private_srcw[0]))
- private_count = 1;
-
- offset = OVECTOR_PRIV(offset);
- if (recurse_check_bit(common, offset))
- {
- private_srcw[private_count] = offset;
- private_count++;
- }
- cc += 1 + LINK_SIZE + IMM2_SIZE;
- break;
-
- case OP_COND:
- /* Might be a hidden SCOND. */
- alternative = cc + GET(cc, 1);
- if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
- {
- private_srcw[0] = PRIVATE_DATA(cc);
- if (recurse_check_bit(common, private_srcw[0]))
- private_count = 1;
- }
- cc += 1 + LINK_SIZE;
- break;
-
- CASE_ITERATOR_PRIVATE_DATA_1
- private_srcw[0] = PRIVATE_DATA(cc);
- if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
- private_count = 1;
- cc += 2;
-#ifdef SUPPORT_UNICODE
- if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- break;
-
- CASE_ITERATOR_PRIVATE_DATA_2A
- private_srcw[0] = PRIVATE_DATA(cc);
- if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
- {
- private_count = 2;
- private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
- SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));
- }
- cc += 2;
-#ifdef SUPPORT_UNICODE
- if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- break;
-
- CASE_ITERATOR_PRIVATE_DATA_2B
- private_srcw[0] = PRIVATE_DATA(cc);
- if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
- {
- private_count = 2;
- private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
- SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));
- }
- cc += 2 + IMM2_SIZE;
-#ifdef SUPPORT_UNICODE
- if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- break;
-
- CASE_ITERATOR_TYPE_PRIVATE_DATA_1
- private_srcw[0] = PRIVATE_DATA(cc);
- if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
- private_count = 1;
- cc += 1;
- break;
-
- CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
- private_srcw[0] = PRIVATE_DATA(cc);
- if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
- {
- private_count = 2;
- private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
- SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));
- }
- cc += 1;
- break;
-
- CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
- private_srcw[0] = PRIVATE_DATA(cc);
- if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
- {
- private_count = 2;
- private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
- SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));
- }
- cc += 1 + IMM2_SIZE;
- break;
-
- case OP_CLASS:
- case OP_NCLASS:
-#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
- case OP_XCLASS:
- i = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(PCRE2_UCHAR);
-#else
- i = 1 + 32 / (int)sizeof(PCRE2_UCHAR);
-#endif
- if (PRIVATE_DATA(cc) != 0)
- {
- private_count = 1;
- private_srcw[0] = PRIVATE_DATA(cc);
- switch(get_class_iterator_size(cc + i))
- {
- case 1:
- break;
-
- case 2:
- if (recurse_check_bit(common, private_srcw[0]))
- {
- private_count = 2;
- private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
- SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));
- }
- break;
-
- default:
- SLJIT_UNREACHABLE();
- break;
- }
- }
- cc += i;
- break;
-
- case OP_MARK:
- case OP_COMMIT_ARG:
- case OP_PRUNE_ARG:
- case OP_THEN_ARG:
- SLJIT_ASSERT(common->mark_ptr != 0);
- if ((recurse_flags & recurse_flag_quit_found) && recurse_check_bit(common, common->mark_ptr))
- {
- kept_shared_srcw[0] = common->mark_ptr;
- kept_shared_count = 1;
- }
- if (common->control_head_ptr != 0 && recurse_check_bit(common, common->control_head_ptr))
- {
- private_srcw[0] = common->control_head_ptr;
- private_count = 1;
- }
- cc += 1 + 2 + cc[1];
- break;
-
- case OP_THEN:
- SLJIT_ASSERT(common->control_head_ptr != 0);
- if (recurse_check_bit(common, common->control_head_ptr))
- {
- private_srcw[0] = common->control_head_ptr;
- private_count = 1;
- }
- cc++;
- break;
-
- default:
- cc = next_opcode(common, cc);
- SLJIT_ASSERT(cc != NULL);
- continue;
- }
-
- if (type != recurse_copy_shared_to_global && type != recurse_copy_kept_shared_to_global)
- {
- SLJIT_ASSERT(type == recurse_copy_from_global || type == recurse_copy_private_to_global || type == recurse_swap_global);
-
- for (i = 0; i < private_count; i++)
- {
- SLJIT_ASSERT(private_srcw[i] != 0);
-
- if (!from_sp)
- delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, private_srcw[i]);
-
- if (from_sp || type == recurse_swap_global)
- delayed_mem_copy_move(&status, SLJIT_SP, private_srcw[i], base_reg, stackptr);
-
- stackptr += sizeof(sljit_sw);
- }
- }
- else
- stackptr += sizeof(sljit_sw) * private_count;
-
- if (type != recurse_copy_private_to_global && type != recurse_copy_kept_shared_to_global)
- {
- SLJIT_ASSERT(type == recurse_copy_from_global || type == recurse_copy_shared_to_global || type == recurse_swap_global);
-
- for (i = 0; i < shared_count; i++)
- {
- SLJIT_ASSERT(shared_srcw[i] != 0);
-
- if (!from_sp)
- delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, shared_srcw[i]);
-
- if (from_sp || type == recurse_swap_global)
- delayed_mem_copy_move(&status, SLJIT_SP, shared_srcw[i], base_reg, stackptr);
-
- stackptr += sizeof(sljit_sw);
- }
- }
- else
- stackptr += sizeof(sljit_sw) * shared_count;
-
- if (type != recurse_copy_private_to_global && type != recurse_swap_global)
- {
- SLJIT_ASSERT(type == recurse_copy_from_global || type == recurse_copy_shared_to_global || type == recurse_copy_kept_shared_to_global);
-
- for (i = 0; i < kept_shared_count; i++)
- {
- SLJIT_ASSERT(kept_shared_srcw[i] != 0);
-
- if (!from_sp)
- delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, kept_shared_srcw[i]);
-
- if (from_sp || type == recurse_swap_global)
- delayed_mem_copy_move(&status, SLJIT_SP, kept_shared_srcw[i], base_reg, stackptr);
-
- stackptr += sizeof(sljit_sw);
- }
- }
- else
- stackptr += sizeof(sljit_sw) * kept_shared_count;
- }
-
-SLJIT_ASSERT(cc == ccend && stackptr == stacktop);
-
-delayed_mem_copy_finish(&status);
-}
-
-static SLJIT_INLINE PCRE2_SPTR set_then_offsets(compiler_common *common, PCRE2_SPTR cc, sljit_u8 *current_offset)
-{
-PCRE2_SPTR end = bracketend(cc);
-BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;
-
-/* Assert captures then. */
-if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA)
- current_offset = NULL;
-/* Conditional block does not. */
-if (*cc == OP_COND || *cc == OP_SCOND)
- has_alternatives = FALSE;
-
-cc = next_opcode(common, cc);
-if (has_alternatives)
- current_offset = common->then_offsets + (cc - common->start);
-
-while (cc < end)
- {
- if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA) || (*cc >= OP_ONCE && *cc <= OP_SCOND))
- cc = set_then_offsets(common, cc, current_offset);
- else
- {
- if (*cc == OP_ALT && has_alternatives)
- current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start);
- if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL)
- *current_offset = 1;
- cc = next_opcode(common, cc);
- }
- }
-
-return end;
-}
-
-#undef CASE_ITERATOR_PRIVATE_DATA_1
-#undef CASE_ITERATOR_PRIVATE_DATA_2A
-#undef CASE_ITERATOR_PRIVATE_DATA_2B
-#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
-#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
-#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
-
-static SLJIT_INLINE BOOL is_powerof2(unsigned int value)
-{
-return (value & (value - 1)) == 0;
-}
-
-static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label)
-{
-while (list)
- {
- /* sljit_set_label is clever enough to do nothing
- if either the jump or the label is NULL. */
- SET_LABEL(list->jump, label);
- list = list->next;
- }
-}
-
-static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump *jump)
-{
-jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list));
-if (list_item)
- {
- list_item->next = *list;
- list_item->jump = jump;
- *list = list_item;
- }
-}
-
-static void add_stub(compiler_common *common, struct sljit_jump *start)
-{
-DEFINE_COMPILER;
-stub_list *list_item = sljit_alloc_memory(compiler, sizeof(stub_list));
-
-if (list_item)
- {
- list_item->start = start;
- list_item->quit = LABEL();
- list_item->next = common->stubs;
- common->stubs = list_item;
- }
-}
-
-static void flush_stubs(compiler_common *common)
-{
-DEFINE_COMPILER;
-stub_list *list_item = common->stubs;
-
-while (list_item)
- {
- JUMPHERE(list_item->start);
- add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
- JUMPTO(SLJIT_JUMP, list_item->quit);
- list_item = list_item->next;
- }
-common->stubs = NULL;
-}
-
-static SLJIT_INLINE void count_match(compiler_common *common)
-{
-DEFINE_COMPILER;
-
-OP2(SLJIT_SUB | SLJIT_SET_Z, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1);
-add_jump(compiler, &common->calllimit, JUMP(SLJIT_ZERO));
-}
-
-static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)
-{
-/* May destroy all locals and registers except TMP2. */
-DEFINE_COMPILER;
-
-SLJIT_ASSERT(size > 0);
-OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * SSIZE_OF(sw));
-#ifdef DESTROY_REGISTERS
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
-OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
-OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, TMP1, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0);
-#endif
-add_stub(common, CMP(SLJIT_LESS, STACK_TOP, 0, STACK_LIMIT, 0));
-}
-
-static SLJIT_INLINE void free_stack(compiler_common *common, int size)
-{
-DEFINE_COMPILER;
-
-SLJIT_ASSERT(size > 0);
-OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * SSIZE_OF(sw));
-}
-
-static sljit_uw * allocate_read_only_data(compiler_common *common, sljit_uw size)
-{
-DEFINE_COMPILER;
-sljit_uw *result;
-
-if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- return NULL;
-
-result = (sljit_uw *)SLJIT_MALLOC(size + sizeof(sljit_uw), compiler->allocator_data);
-if (SLJIT_UNLIKELY(result == NULL))
- {
- sljit_set_compiler_memory_error(compiler);
- return NULL;
- }
-
-*(void**)result = common->read_only_data_head;
-common->read_only_data_head = (void *)result;
-return result + 1;
-}
-
-static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
-{
-DEFINE_COMPILER;
-struct sljit_label *loop;
-sljit_s32 i;
-
-/* At this point we can freely use all temporary registers. */
-SLJIT_ASSERT(length > 1);
-/* TMP1 returns with begin - 1. */
-OP2(SLJIT_SUB, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_S0), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
-if (length < 8)
- {
- for (i = 1; i < length; i++)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), SLJIT_R0, 0);
- }
-else
- {
- if (sljit_emit_mem_update(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_STORE | SLJIT_MEM_PRE, SLJIT_R0, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw)) == SLJIT_SUCCESS)
- {
- GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START);
- OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1);
- loop = LABEL();
- sljit_emit_mem_update(compiler, SLJIT_MOV | SLJIT_MEM_STORE | SLJIT_MEM_PRE, SLJIT_R0, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw));
- OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1);
- JUMPTO(SLJIT_NOT_ZERO, loop);
- }
- else
- {
- GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START + sizeof(sljit_sw));
- OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1);
- loop = LABEL();
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), 0, SLJIT_R0, 0);
- OP2(SLJIT_ADD, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, sizeof(sljit_sw));
- OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1);
- JUMPTO(SLJIT_NOT_ZERO, loop);
- }
- }
-}
-
-static SLJIT_INLINE void reset_early_fail(compiler_common *common)
-{
-DEFINE_COMPILER;
-sljit_u32 size = (sljit_u32)(common->early_fail_end_ptr - common->early_fail_start_ptr);
-sljit_u32 uncleared_size;
-sljit_s32 src = SLJIT_IMM;
-sljit_s32 i;
-struct sljit_label *loop;
-
-SLJIT_ASSERT(common->early_fail_start_ptr < common->early_fail_end_ptr);
-
-if (size == sizeof(sljit_sw))
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->early_fail_start_ptr, SLJIT_IMM, 0);
- return;
- }
-
-if (sljit_get_register_index(TMP3) >= 0 && !sljit_has_cpu_feature(SLJIT_HAS_ZERO_REGISTER))
- {
- OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
- src = TMP3;
- }
-
-if (size <= 6 * sizeof(sljit_sw))
- {
- for (i = common->early_fail_start_ptr; i < common->early_fail_end_ptr; i += sizeof(sljit_sw))
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), i, src, 0);
- return;
- }
-
-GET_LOCAL_BASE(TMP1, 0, common->early_fail_start_ptr);
-
-uncleared_size = ((size / sizeof(sljit_sw)) % 3) * sizeof(sljit_sw);
-
-OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, size - uncleared_size);
-
-loop = LABEL();
-OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), 0, src, 0);
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_sw));
-OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), -2 * SSIZE_OF(sw), src, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), -1 * SSIZE_OF(sw), src, 0);
-CMPTO(SLJIT_LESS, TMP1, 0, TMP2, 0, loop);
-
-if (uncleared_size >= sizeof(sljit_sw))
- OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), 0, src, 0);
-
-if (uncleared_size >= 2 * sizeof(sljit_sw))
- OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), sizeof(sljit_sw), src, 0);
-}
-
-static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)
-{
-DEFINE_COMPILER;
-struct sljit_label *loop;
-int i;
-
-SLJIT_ASSERT(length > 1);
-/* OVECTOR(1) contains the "string begin - 1" constant. */
-if (length > 2)
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
-if (length < 8)
- {
- for (i = 2; i < length; i++)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), TMP1, 0);
- }
-else
- {
- if (sljit_emit_mem_update(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_STORE | SLJIT_MEM_PRE, TMP1, SLJIT_MEM1(TMP2), sizeof(sljit_sw)) == SLJIT_SUCCESS)
- {
- GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
- loop = LABEL();
- sljit_emit_mem_update(compiler, SLJIT_MOV | SLJIT_MEM_STORE | SLJIT_MEM_PRE, TMP1, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
- OP2(SLJIT_SUB | SLJIT_SET_Z, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
- JUMPTO(SLJIT_NOT_ZERO, loop);
- }
- else
- {
- GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + 2 * sizeof(sljit_sw));
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
- loop = LABEL();
- OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, TMP1, 0);
- OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, sizeof(sljit_sw));
- OP2(SLJIT_SUB | SLJIT_SET_Z, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
- JUMPTO(SLJIT_NOT_ZERO, loop);
- }
- }
-
-if (!HAS_VIRTUAL_REGISTERS)
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, stack));
-else
- OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
-
-if (common->mark_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0);
-if (common->control_head_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
-if (HAS_VIRTUAL_REGISTERS)
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
-
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
-OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, end));
-}
-
-static sljit_sw SLJIT_FUNC do_search_mark(sljit_sw *current, PCRE2_SPTR skip_arg)
-{
-while (current != NULL)
- {
- switch (current[1])
- {
- case type_then_trap:
- break;
-
- case type_mark:
- if (PRIV(strcmp)(skip_arg, (PCRE2_SPTR)current[2]) == 0)
- return current[3];
- break;
-
- default:
- SLJIT_UNREACHABLE();
- break;
- }
- SLJIT_ASSERT(current[0] == 0 || current < (sljit_sw*)current[0]);
- current = (sljit_sw*)current[0];
- }
-return 0;
-}
-
-static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
-{
-DEFINE_COMPILER;
-struct sljit_label *loop;
-BOOL has_pre;
-
-/* At this point we can freely use all registers. */
-OP1(SLJIT_MOV, SLJIT_S2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(1), STR_PTR, 0);
-
-if (HAS_VIRTUAL_REGISTERS)
- {
- OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
- if (common->mark_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
- OP1(SLJIT_MOV_U32, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, oveccount));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_S0, 0);
- if (common->mark_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R2, 0);
- OP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, match_data),
- SLJIT_IMM, SLJIT_OFFSETOF(pcre2_match_data, ovector) - sizeof(PCRE2_SIZE));
- }
-else
- {
- OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
- OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, match_data));
- if (common->mark_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
- OP1(SLJIT_MOV_U32, SLJIT_R1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, oveccount));
- OP1(SLJIT_MOV, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_S0, 0);
- if (common->mark_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R0, 0);
- OP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, SLJIT_OFFSETOF(pcre2_match_data, ovector) - sizeof(PCRE2_SIZE));
- }
-
-has_pre = sljit_emit_mem_update(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, SLJIT_S1, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw)) == SLJIT_SUCCESS;
-
-GET_LOCAL_BASE(SLJIT_S0, 0, OVECTOR_START - (has_pre ? sizeof(sljit_sw) : 0));
-OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(HAS_VIRTUAL_REGISTERS ? SLJIT_R0 : ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
-
-loop = LABEL();
-
-if (has_pre)
- sljit_emit_mem_update(compiler, SLJIT_MOV | SLJIT_MEM_PRE, SLJIT_S1, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw));
-else
- {
- OP1(SLJIT_MOV, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_S0), 0);
- OP2(SLJIT_ADD, SLJIT_S0, 0, SLJIT_S0, 0, SLJIT_IMM, sizeof(sljit_sw));
- }
-
-OP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, sizeof(PCRE2_SIZE));
-OP2(SLJIT_SUB, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_R0, 0);
-/* Copy the integer value to the output buffer */
-#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
-OP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, UCHAR_SHIFT);
-#endif
-
-SLJIT_ASSERT(sizeof(PCRE2_SIZE) == 4 || sizeof(PCRE2_SIZE) == 8);
-OP1(((sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_U32 : SLJIT_MOV), SLJIT_MEM1(SLJIT_R2), 0, SLJIT_S1, 0);
-
-OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
-JUMPTO(SLJIT_NOT_ZERO, loop);
-
-/* Calculate the return value, which is the maximum ovector value. */
-if (topbracket > 1)
- {
- if (sljit_emit_mem_update(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, SLJIT_R2, SLJIT_MEM1(SLJIT_R0), -(2 * SSIZE_OF(sw))) == SLJIT_SUCCESS)
- {
- GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));
- OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1);
-
- /* OVECTOR(0) is never equal to SLJIT_S2. */
- loop = LABEL();
- sljit_emit_mem_update(compiler, SLJIT_MOV | SLJIT_MEM_PRE, SLJIT_R2, SLJIT_MEM1(SLJIT_R0), -(2 * SSIZE_OF(sw)));
- OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
- CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop);
- OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_R1, 0);
- }
- else
- {
- GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + (topbracket - 1) * 2 * sizeof(sljit_sw));
- OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1);
-
- /* OVECTOR(0) is never equal to SLJIT_S2. */
- loop = LABEL();
- OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), 0);
- OP2(SLJIT_SUB, SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, 2 * SSIZE_OF(sw));
- OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
- CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop);
- OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_R1, 0);
- }
- }
-else
- OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
-}
-
-static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)
-{
-DEFINE_COMPILER;
-sljit_s32 mov_opcode;
-sljit_s32 arguments_reg = !HAS_VIRTUAL_REGISTERS ? ARGUMENTS : SLJIT_R1;
-
-SLJIT_COMPILE_ASSERT(STR_END == SLJIT_S0, str_end_must_be_saved_reg0);
-SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0
- && (common->mode == PCRE2_JIT_PARTIAL_SOFT ? common->hit_start != 0 : common->hit_start == 0));
-
-if (arguments_reg != ARGUMENTS)
- OP1(SLJIT_MOV, arguments_reg, 0, ARGUMENTS, 0);
-OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP),
- common->mode == PCRE2_JIT_PARTIAL_SOFT ? common->hit_start : common->start_ptr);
-OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_PARTIAL);
-
-/* Store match begin and end. */
-OP1(SLJIT_MOV, SLJIT_S1, 0, SLJIT_MEM1(arguments_reg), SLJIT_OFFSETOF(jit_arguments, begin));
-OP1(SLJIT_MOV, SLJIT_MEM1(arguments_reg), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_R2, 0);
-OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_MEM1(arguments_reg), SLJIT_OFFSETOF(jit_arguments, match_data));
-
-mov_opcode = (sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_U32 : SLJIT_MOV;
-
-OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_S1, 0);
-#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
-OP2(SLJIT_ASHR, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, UCHAR_SHIFT);
-#endif
-OP1(mov_opcode, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(pcre2_match_data, ovector), SLJIT_R2, 0);
-
-OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_S1, 0);
-#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
-OP2(SLJIT_ASHR, STR_END, 0, STR_END, 0, SLJIT_IMM, UCHAR_SHIFT);
-#endif
-OP1(mov_opcode, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(pcre2_match_data, ovector) + sizeof(PCRE2_SIZE), STR_END, 0);
-
-JUMPTO(SLJIT_JUMP, quit);
-}
-
-static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
-{
-/* May destroy TMP1. */
-DEFINE_COMPILER;
-struct sljit_jump *jump;
-
-if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
- {
- /* The value of -1 must be kept for start_used_ptr! */
- OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, 1);
- /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
- is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
- jump = CMP(SLJIT_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
- JUMPHERE(jump);
- }
-else if (common->mode == PCRE2_JIT_PARTIAL_HARD)
- {
- jump = CMP(SLJIT_LESS_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
- JUMPHERE(jump);
- }
-}
-
-static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, PCRE2_SPTR cc)
-{
-/* Detects if the character has an othercase. */
-unsigned int c;
-
-#ifdef SUPPORT_UNICODE
-if (common->utf || common->ucp)
- {
- if (common->utf)
- {
- GETCHAR(c, cc);
- }
- else
- c = *cc;
-
- if (c > 127)
- return c != UCD_OTHERCASE(c);
-
- return common->fcc[c] != c;
- }
-else
-#endif
- c = *cc;
-return MAX_255(c) ? common->fcc[c] != c : FALSE;
-}
-
-static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c)
-{
-/* Returns with the othercase. */
-#ifdef SUPPORT_UNICODE
-if ((common->utf || common->ucp) && c > 127)
- return UCD_OTHERCASE(c);
-#endif
-return TABLE_GET(c, common->fcc, c);
-}
-
-static unsigned int char_get_othercase_bit(compiler_common *common, PCRE2_SPTR cc)
-{
-/* Detects if the character and its othercase has only 1 bit difference. */
-unsigned int c, oc, bit;
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
-int n;
-#endif
-
-#ifdef SUPPORT_UNICODE
-if (common->utf || common->ucp)
- {
- if (common->utf)
- {
- GETCHAR(c, cc);
- }
- else
- c = *cc;
-
- if (c <= 127)
- oc = common->fcc[c];
- else
- oc = UCD_OTHERCASE(c);
- }
-else
- {
- c = *cc;
- oc = TABLE_GET(c, common->fcc, c);
- }
-#else
-c = *cc;
-oc = TABLE_GET(c, common->fcc, c);
-#endif
-
-SLJIT_ASSERT(c != oc);
-
-bit = c ^ oc;
-/* Optimized for English alphabet. */
-if (c <= 127 && bit == 0x20)
- return (0 << 8) | 0x20;
-
-/* Since c != oc, they must have at least 1 bit difference. */
-if (!is_powerof2(bit))
- return 0;
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
-
-#ifdef SUPPORT_UNICODE
-if (common->utf && c > 127)
- {
- n = GET_EXTRALEN(*cc);
- while ((bit & 0x3f) == 0)
- {
- n--;
- bit >>= 6;
- }
- return (n << 8) | bit;
- }
-#endif /* SUPPORT_UNICODE */
-return (0 << 8) | bit;
-
-#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
-
-#ifdef SUPPORT_UNICODE
-if (common->utf && c > 65535)
- {
- if (bit >= (1u << 10))
- bit >>= 10;
- else
- return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
- }
-#endif /* SUPPORT_UNICODE */
-return (bit < 256) ? ((0u << 8) | bit) : ((1u << 8) | (bit >> 8));
-
-#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */
-}
-
-static void check_partial(compiler_common *common, BOOL force)
-{
-/* Checks whether a partial matching is occurred. Does not modify registers. */
-DEFINE_COMPILER;
-struct sljit_jump *jump = NULL;
-
-SLJIT_ASSERT(!force || common->mode != PCRE2_JIT_COMPLETE);
-
-if (common->mode == PCRE2_JIT_COMPLETE)
- return;
-
-if (!force && !common->allow_empty_partial)
- jump = CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
-else if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
- jump = CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1);
-
-if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
-else
- {
- if (common->partialmatchlabel != NULL)
- JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
- else
- add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
- }
-
-if (jump != NULL)
- JUMPHERE(jump);
-}
-
-static void check_str_end(compiler_common *common, jump_list **end_reached)
-{
-/* Does not affect registers. Usually used in a tight spot. */
-DEFINE_COMPILER;
-struct sljit_jump *jump;
-
-if (common->mode == PCRE2_JIT_COMPLETE)
- {
- add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
- return;
- }
-
-jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
-if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
- {
- add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
- add_jump(compiler, end_reached, JUMP(SLJIT_JUMP));
- }
-else
- {
- add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
- if (common->partialmatchlabel != NULL)
- JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
- else
- add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
- }
-JUMPHERE(jump);
-}
-
-static void detect_partial_match(compiler_common *common, jump_list **backtracks)
-{
-DEFINE_COMPILER;
-struct sljit_jump *jump;
-
-if (common->mode == PCRE2_JIT_COMPLETE)
- {
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
- return;
- }
-
-/* Partial matching mode. */
-jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
-if (!common->allow_empty_partial)
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
-else if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1));
-
-if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
- add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
- }
-else
- {
- if (common->partialmatchlabel != NULL)
- JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
- else
- add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
- }
-JUMPHERE(jump);
-}
-
-static void process_partial_match(compiler_common *common)
-{
-DEFINE_COMPILER;
-struct sljit_jump *jump;
-
-/* Partial matching mode. */
-if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
- {
- jump = CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
- JUMPHERE(jump);
- }
-else if (common->mode == PCRE2_JIT_PARTIAL_HARD)
- {
- if (common->partialmatchlabel != NULL)
- CMPTO(SLJIT_LESS, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0, common->partialmatchlabel);
- else
- add_jump(compiler, &common->partialmatch, CMP(SLJIT_LESS, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
- }
-}
-
-static void detect_partial_match_to(compiler_common *common, struct sljit_label *label)
-{
-DEFINE_COMPILER;
-
-CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, label);
-process_partial_match(common);
-}
-
-static void peek_char(compiler_common *common, sljit_u32 max, sljit_s32 dst, sljit_sw dstw, jump_list **backtracks)
-{
-/* Reads the character into TMP1, keeps STR_PTR.
-Does not check STR_END. TMP2, dst, RETURN_ADDR Destroyed. */
-DEFINE_COMPILER;
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-struct sljit_jump *jump;
-#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */
-
-SLJIT_UNUSED_ARG(max);
-SLJIT_UNUSED_ARG(dst);
-SLJIT_UNUSED_ARG(dstw);
-SLJIT_UNUSED_ARG(backtracks);
-
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
-
-#ifdef SUPPORT_UNICODE
-#if PCRE2_CODE_UNIT_WIDTH == 8
-if (common->utf)
- {
- if (max < 128) return;
-
- jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x80);
- OP1(SLJIT_MOV, dst, dstw, STR_PTR, 0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- add_jump(compiler, common->invalid_utf ? &common->utfreadchar_invalid : &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
- OP1(SLJIT_MOV, STR_PTR, 0, dst, dstw);
- if (backtracks && common->invalid_utf)
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));
- JUMPHERE(jump);
- }
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-if (common->utf)
- {
- if (max < 0xd800) return;
-
- OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
-
- if (common->invalid_utf)
- {
- jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800);
- OP1(SLJIT_MOV, dst, dstw, STR_PTR, 0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- add_jump(compiler, &common->utfreadchar_invalid, JUMP(SLJIT_FAST_CALL));
- OP1(SLJIT_MOV, STR_PTR, 0, dst, dstw);
- if (backtracks && common->invalid_utf)
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));
- }
- else
- {
- /* TMP2 contains the high surrogate. */
- jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000 - 0xdc00);
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
- }
-
- JUMPHERE(jump);
- }
-#elif PCRE2_CODE_UNIT_WIDTH == 32
-if (common->invalid_utf)
- {
- if (max < 0xd800) return;
-
- if (backtracks != NULL)
- {
- OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000));
- add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800));
- }
- else
- {
- OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
- OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000);
- CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);
- OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800);
- CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);
- }
- }
-#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */
-#endif /* SUPPORT_UNICODE */
-}
-
-static void peek_char_back(compiler_common *common, sljit_u32 max, jump_list **backtracks)
-{
-/* Reads one character back without moving STR_PTR. TMP2 must
-contain the start of the subject buffer. Affects TMP1, TMP2, and RETURN_ADDR. */
-DEFINE_COMPILER;
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-struct sljit_jump *jump;
-#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */
-
-SLJIT_UNUSED_ARG(max);
-SLJIT_UNUSED_ARG(backtracks);
-
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
-
-#ifdef SUPPORT_UNICODE
-#if PCRE2_CODE_UNIT_WIDTH == 8
-if (common->utf)
- {
- if (max < 128) return;
-
- jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x80);
- if (common->invalid_utf)
- {
- add_jump(compiler, &common->utfpeakcharback_invalid, JUMP(SLJIT_FAST_CALL));
- if (backtracks != NULL)
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));
- }
- else
- add_jump(compiler, &common->utfpeakcharback, JUMP(SLJIT_FAST_CALL));
- JUMPHERE(jump);
- }
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-if (common->utf)
- {
- if (max < 0xd800) return;
-
- if (common->invalid_utf)
- {
- jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
- add_jump(compiler, &common->utfpeakcharback_invalid, JUMP(SLJIT_FAST_CALL));
- if (backtracks != NULL)
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));
- }
- else
- {
- OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
- jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xe000 - 0xdc00);
- /* TMP2 contains the low surrogate. */
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
- OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x10000);
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);
- OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
- }
- JUMPHERE(jump);
- }
-#elif PCRE2_CODE_UNIT_WIDTH == 32
-if (common->invalid_utf)
- {
- OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000));
- add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800));
- }
-#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */
-#endif /* SUPPORT_UNICODE */
-}
-
-#define READ_CHAR_UPDATE_STR_PTR 0x1
-#define READ_CHAR_UTF8_NEWLINE 0x2
-#define READ_CHAR_NEWLINE (READ_CHAR_UPDATE_STR_PTR | READ_CHAR_UTF8_NEWLINE)
-#define READ_CHAR_VALID_UTF 0x4
-
-static void read_char(compiler_common *common, sljit_u32 min, sljit_u32 max,
- jump_list **backtracks, sljit_u32 options)
-{
-/* Reads the precise value of a character into TMP1, if the character is
-between min and max (c >= min && c <= max). Otherwise it returns with a value
-outside the range. Does not check STR_END. */
-DEFINE_COMPILER;
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-struct sljit_jump *jump;
-#endif
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
-struct sljit_jump *jump2;
-#endif
-
-SLJIT_UNUSED_ARG(min);
-SLJIT_UNUSED_ARG(max);
-SLJIT_UNUSED_ARG(backtracks);
-SLJIT_UNUSED_ARG(options);
-SLJIT_ASSERT(min <= max);
-
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
-#ifdef SUPPORT_UNICODE
-#if PCRE2_CODE_UNIT_WIDTH == 8
-if (common->utf)
- {
- if (max < 128 && !(options & READ_CHAR_UPDATE_STR_PTR)) return;
-
- if (common->invalid_utf && !(options & READ_CHAR_VALID_UTF))
- {
- jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x80);
-
- if (options & READ_CHAR_UTF8_NEWLINE)
- add_jump(compiler, &common->utfreadnewline_invalid, JUMP(SLJIT_FAST_CALL));
- else
- add_jump(compiler, &common->utfreadchar_invalid, JUMP(SLJIT_FAST_CALL));
-
- if (backtracks != NULL)
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));
- JUMPHERE(jump);
- return;
- }
-
- jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
- if (min >= 0x10000)
- {
- OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf0);
- if (options & READ_CHAR_UPDATE_STR_PTR)
- OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
- jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x7);
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
- OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
- OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
- OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
- if (!(options & READ_CHAR_UPDATE_STR_PTR))
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
- OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
- OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
- JUMPHERE(jump2);
- if (options & READ_CHAR_UPDATE_STR_PTR)
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
- }
- else if (min >= 0x800 && max <= 0xffff)
- {
- OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xe0);
- if (options & READ_CHAR_UPDATE_STR_PTR)
- OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
- jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xf);
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
- OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
- if (!(options & READ_CHAR_UPDATE_STR_PTR))
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
- OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
- OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
- JUMPHERE(jump2);
- if (options & READ_CHAR_UPDATE_STR_PTR)
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
- }
- else if (max >= 0x800)
- {
- add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
- }
- else if (max < 128)
- {
- OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
- }
- else
- {
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
- if (!(options & READ_CHAR_UPDATE_STR_PTR))
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- else
- OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
- OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
- OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
- OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
- if (options & READ_CHAR_UPDATE_STR_PTR)
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
- }
- JUMPHERE(jump);
- }
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-if (common->utf)
- {
- if (max < 0xd800 && !(options & READ_CHAR_UPDATE_STR_PTR)) return;
-
- if (common->invalid_utf && !(options & READ_CHAR_VALID_UTF))
- {
- OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
- jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800);
-
- if (options & READ_CHAR_UTF8_NEWLINE)
- add_jump(compiler, &common->utfreadnewline_invalid, JUMP(SLJIT_FAST_CALL));
- else
- add_jump(compiler, &common->utfreadchar_invalid, JUMP(SLJIT_FAST_CALL));
-
- if (backtracks != NULL)
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));
- JUMPHERE(jump);
- return;
- }
-
- if (max >= 0x10000)
- {
- OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
- jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800);
- /* TMP2 contains the high surrogate. */
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000 - 0xdc00);
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
- JUMPHERE(jump);
- return;
- }
-
- /* Skip low surrogate if necessary. */
- OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
-
- if (sljit_has_cpu_feature(SLJIT_HAS_CMOV) && !HAS_VIRTUAL_REGISTERS)
- {
- if (options & READ_CHAR_UPDATE_STR_PTR)
- OP2(SLJIT_ADD, RETURN_ADDR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0x400);
- if (options & READ_CHAR_UPDATE_STR_PTR)
- CMOV(SLJIT_LESS, STR_PTR, RETURN_ADDR, 0);
- if (max >= 0xd800)
- CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, 0x10000);
- }
- else
- {
- jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x400);
- if (options & READ_CHAR_UPDATE_STR_PTR)
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- if (max >= 0xd800)
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000);
- JUMPHERE(jump);
- }
- }
-#elif PCRE2_CODE_UNIT_WIDTH == 32
-if (common->invalid_utf)
- {
- if (backtracks != NULL)
- {
- OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000));
- add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800));
- }
- else
- {
- OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
- OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000);
- CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);
- OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800);
- CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);
- }
- }
-#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */
-#endif /* SUPPORT_UNICODE */
-}
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
-
-static BOOL is_char7_bitset(const sljit_u8 *bitset, BOOL nclass)
-{
-/* Tells whether the character codes below 128 are enough
-to determine a match. */
-const sljit_u8 value = nclass ? 0xff : 0;
-const sljit_u8 *end = bitset + 32;
-
-bitset += 16;
-do
- {
- if (*bitset++ != value)
- return FALSE;
- }
-while (bitset < end);
-return TRUE;
-}
-
-static void read_char7_type(compiler_common *common, jump_list **backtracks, BOOL negated)
-{
-/* Reads the precise character type of a character into TMP1, if the character
-is less than 128. Otherwise it returns with zero. Does not check STR_END. The
-full_read argument tells whether characters above max are accepted or not. */
-DEFINE_COMPILER;
-struct sljit_jump *jump;
-
-SLJIT_ASSERT(common->utf);
-
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
-/* All values > 127 are zero in ctypes. */
-OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
-
-if (negated)
- {
- jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0x80);
-
- if (common->invalid_utf)
- {
- add_jump(compiler, &common->utfreadchar_invalid, JUMP(SLJIT_FAST_CALL));
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
- }
- else
- {
- OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
- }
- JUMPHERE(jump);
- }
-}
-
-#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */
-
-static void read_char8_type(compiler_common *common, jump_list **backtracks, BOOL negated)
-{
-/* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
-DEFINE_COMPILER;
-#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
-struct sljit_jump *jump;
-#endif
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
-struct sljit_jump *jump2;
-#endif
-
-SLJIT_UNUSED_ARG(backtracks);
-SLJIT_UNUSED_ARG(negated);
-
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
-if (common->utf)
- {
- /* The result of this read may be unused, but saves an "else" part. */
- OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
- jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0x80);
-
- if (!negated)
- {
- if (common->invalid_utf)
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
-
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2);
- if (common->invalid_utf)
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xe0 - 0xc2));
-
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
- OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x80);
- if (common->invalid_utf)
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40));
-
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
- jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255);
- OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
- JUMPHERE(jump2);
- }
- else if (common->invalid_utf)
- {
- add_jump(compiler, &common->utfreadchar_invalid, JUMP(SLJIT_FAST_CALL));
- OP1(SLJIT_MOV, TMP2, 0, TMP1, 0);
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));
-
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
- jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255);
- OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
- JUMPHERE(jump2);
- }
- else
- add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
-
- JUMPHERE(jump);
- return;
- }
-#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 32
-if (common->invalid_utf && negated)
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x110000));
-#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 32 */
-
-#if PCRE2_CODE_UNIT_WIDTH != 8
-/* The ctypes array contains only 256 values. */
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
-jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255);
-#endif /* PCRE2_CODE_UNIT_WIDTH != 8 */
-OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
-#if PCRE2_CODE_UNIT_WIDTH != 8
-JUMPHERE(jump);
-#endif /* PCRE2_CODE_UNIT_WIDTH != 8 */
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16
-if (common->utf && negated)
- {
- /* Skip low surrogate if necessary. */
- if (!common->invalid_utf)
- {
- OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);
-
- if (sljit_has_cpu_feature(SLJIT_HAS_CMOV) && !HAS_VIRTUAL_REGISTERS)
- {
- OP2(SLJIT_ADD, RETURN_ADDR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0x400);
- CMOV(SLJIT_LESS, STR_PTR, RETURN_ADDR, 0);
- }
- else
- {
- jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x400);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- JUMPHERE(jump);
- }
- return;
- }
-
- OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);
- jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800);
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x400));
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
-
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xdc00);
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x400));
-
- JUMPHERE(jump);
- return;
- }
-#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16 */
-}
-
-static void move_back(compiler_common *common, jump_list **backtracks, BOOL must_be_valid)
-{
-/* Goes one character back. Affects STR_PTR and TMP1. If must_be_valid is TRUE,
-TMP2 is not used. Otherwise TMP2 must contain the start of the subject buffer,
-and it is destroyed. Does not modify STR_PTR for invalid character sequences. */
-DEFINE_COMPILER;
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-struct sljit_jump *jump;
-#endif
-
-#ifdef SUPPORT_UNICODE
-#if PCRE2_CODE_UNIT_WIDTH == 8
-struct sljit_label *label;
-
-if (common->utf)
- {
- if (!must_be_valid && common->invalid_utf)
- {
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x80);
- add_jump(compiler, &common->utfmoveback_invalid, JUMP(SLJIT_FAST_CALL));
- if (backtracks != NULL)
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0));
- JUMPHERE(jump);
- return;
- }
-
- label = LABEL();
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
- CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
- return;
- }
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-if (common->utf)
- {
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
- if (!must_be_valid && common->invalid_utf)
- {
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);
- jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xe000 - 0xd800);
- add_jump(compiler, &common->utfmoveback_invalid, JUMP(SLJIT_FAST_CALL));
- if (backtracks != NULL)
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0));
- JUMPHERE(jump);
- return;
- }
-
- /* Skip low surrogate if necessary. */
- OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0xdc00);
- OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);
- OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
- return;
- }
-#elif PCRE2_CODE_UNIT_WIDTH == 32
-if (common->invalid_utf && !must_be_valid)
- {
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
- if (backtracks != NULL)
- {
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000));
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- return;
- }
-
- OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x110000);
- OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_LESS);
- OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
- return;
- }
-#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */
-#endif /* SUPPORT_UNICODE */
-
-SLJIT_UNUSED_ARG(backtracks);
-SLJIT_UNUSED_ARG(must_be_valid);
-
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-}
-
-static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpifmatch)
-{
-/* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */
-DEFINE_COMPILER;
-struct sljit_jump *jump;
-
-if (nltype == NLTYPE_ANY)
- {
- add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
- sljit_set_current_flags(compiler, SLJIT_SET_Z);
- add_jump(compiler, backtracks, JUMP(jumpifmatch ? SLJIT_NOT_ZERO : SLJIT_ZERO));
- }
-else if (nltype == NLTYPE_ANYCRLF)
- {
- if (jumpifmatch)
- {
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR));
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
- }
- else
- {
- jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
- JUMPHERE(jump);
- }
- }
-else
- {
- SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
- add_jump(compiler, backtracks, CMP(jumpifmatch ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
- }
-}
-
-#ifdef SUPPORT_UNICODE
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
-static void do_utfreadchar(compiler_common *common)
-{
-/* Fast decoding a UTF-8 character. TMP1 contains the first byte
-of the character (>= 0xc0). Return char value in TMP1. */
-DEFINE_COMPILER;
-struct sljit_jump *jump;
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
-OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-
-/* Searching for the first zero. */
-OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x800);
-jump = JUMP(SLJIT_NOT_ZERO);
-/* Two byte sequence. */
-OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3000);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-JUMPHERE(jump);
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
-OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-
-OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x10000);
-jump = JUMP(SLJIT_NOT_ZERO);
-/* Three byte sequence. */
-OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0000);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-/* Four byte sequence. */
-JUMPHERE(jump);
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
-OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xf0000);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
-OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-}
-
-static void do_utfreadtype8(compiler_common *common)
-{
-/* Fast decoding a UTF-8 character type. TMP2 contains the first byte
-of the character (>= 0xc0). Return value in TMP1. */
-DEFINE_COMPILER;
-struct sljit_jump *jump;
-struct sljit_jump *compare;
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-
-OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, 0x20);
-jump = JUMP(SLJIT_NOT_ZERO);
-/* Two byte sequence. */
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
-/* The upper 5 bits are known at this point. */
-compare = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x3);
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
-OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
-OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
-OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-JUMPHERE(compare);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-/* We only have types for characters less than 256. */
-JUMPHERE(jump);
-OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-}
-
-static void do_utfreadchar_invalid(compiler_common *common)
-{
-/* Slow decoding a UTF-8 character. TMP1 contains the first byte
-of the character (>= 0xc0). Return char value in TMP1. STR_PTR is
-undefined for invalid characters. */
-DEFINE_COMPILER;
-sljit_s32 i;
-sljit_s32 has_cmov = sljit_has_cpu_feature(SLJIT_HAS_CMOV);
-struct sljit_jump *jump;
-struct sljit_jump *buffer_end_close;
-struct sljit_label *three_byte_entry;
-struct sljit_label *exit_invalid_label;
-struct sljit_jump *exit_invalid[11];
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc2);
-
-/* Usually more than 3 characters remained in the subject buffer. */
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
-
-/* Not a valid start of a multi-byte sequence, no more bytes read. */
-exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xf5 - 0xc2);
-
-buffer_end_close = CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0);
-
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-3));
-OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
-/* If TMP2 is in 0x80-0xbf range, TMP1 is also increased by (0x2 << 6). */
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
-OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);
-exit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);
-
-OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x800);
-jump = JUMP(SLJIT_NOT_ZERO);
-
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-JUMPHERE(jump);
-
-/* Three-byte sequence. */
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
-OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
-OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-if (has_cmov)
- {
- OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);
- CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, 0x20000);
- exit_invalid[2] = NULL;
- }
-else
- exit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);
-
-OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x10000);
-jump = JUMP(SLJIT_NOT_ZERO);
-
-three_byte_entry = LABEL();
-
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2d800);
-if (has_cmov)
- {
- OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x800);
- CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0xd800);
- exit_invalid[3] = NULL;
- }
-else
- exit_invalid[3] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x800);
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
-if (has_cmov)
- {
- OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x800);
- CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);
- exit_invalid[4] = NULL;
- }
-else
- exit_invalid[4] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x800);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-JUMPHERE(jump);
-
-/* Four-byte sequence. */
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
-OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
-OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-if (has_cmov)
- {
- OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);
- CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, 0);
- exit_invalid[5] = NULL;
- }
-else
- exit_invalid[5] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);
-
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc10000);
-if (has_cmov)
- {
- OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x100000);
- CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0x10000);
- exit_invalid[6] = NULL;
- }
-else
- exit_invalid[6] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x100000);
-
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-JUMPHERE(buffer_end_close);
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
-exit_invalid[7] = CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0);
-
-/* Two-byte sequence. */
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
-OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
-/* If TMP2 is in 0x80-0xbf range, TMP1 is also increased by (0x2 << 6). */
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
-OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);
-exit_invalid[8] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);
-
-OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x800);
-jump = JUMP(SLJIT_NOT_ZERO);
-
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-/* Three-byte sequence. */
-JUMPHERE(jump);
-exit_invalid[9] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
-OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
-OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-if (has_cmov)
- {
- OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);
- CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);
- exit_invalid[10] = NULL;
- }
-else
- exit_invalid[10] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);
-
-/* One will be substracted from STR_PTR later. */
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
-
-/* Four byte sequences are not possible. */
-CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x30000, three_byte_entry);
-
-exit_invalid_label = LABEL();
-for (i = 0; i < 11; i++)
- sljit_set_label(exit_invalid[i], exit_invalid_label);
-
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-}
-
-static void do_utfreadnewline_invalid(compiler_common *common)
-{
-/* Slow decoding a UTF-8 character, specialized for newlines.
-TMP1 contains the first byte of the character (>= 0xc0). Return
-char value in TMP1. */
-DEFINE_COMPILER;
-struct sljit_label *loop;
-struct sljit_label *skip_start;
-struct sljit_label *three_byte_exit;
-struct sljit_jump *jump[5];
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-
-if (common->nltype != NLTYPE_ANY)
- {
- SLJIT_ASSERT(common->nltype != NLTYPE_FIXED || common->newline < 128);
-
- /* All newlines are ascii, just skip intermediate octets. */
- jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- loop = LABEL();
- if (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, TMP2, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)) == SLJIT_SUCCESS)
- sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_POST, TMP2, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
- else
- {
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- }
-
- OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc0);
- CMPTO(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0x80, loop);
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
- JUMPHERE(jump[0]);
-
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);
- OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
- return;
- }
-
-jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
-jump[1] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xc2);
-jump[2] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xe2);
-
-skip_start = LABEL();
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc0);
-jump[3] = CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0x80);
-
-/* Skip intermediate octets. */
-loop = LABEL();
-jump[4] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc0);
-CMPTO(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0x80, loop);
-
-JUMPHERE(jump[3]);
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
-three_byte_exit = LABEL();
-JUMPHERE(jump[0]);
-JUMPHERE(jump[4]);
-
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-/* Two byte long newline: 0x85. */
-JUMPHERE(jump[1]);
-CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0x85, skip_start);
-
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x85);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-/* Three byte long newlines: 0x2028 and 0x2029. */
-JUMPHERE(jump[2]);
-CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0x80, skip_start);
-CMPTO(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0, three_byte_exit);
-
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
-OP2(SLJIT_SUB, TMP1, 0, TMP2, 0, SLJIT_IMM, 0x80);
-CMPTO(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x40, skip_start);
-
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0x2000);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-}
-
-static void do_utfmoveback_invalid(compiler_common *common)
-{
-/* Goes one character back. */
-DEFINE_COMPILER;
-sljit_s32 i;
-struct sljit_jump *jump;
-struct sljit_jump *buffer_start_close;
-struct sljit_label *exit_ok_label;
-struct sljit_label *exit_invalid_label;
-struct sljit_jump *exit_invalid[7];
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
-exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xc0);
-
-/* Two-byte sequence. */
-buffer_start_close = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0);
-
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
-
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
-jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x20);
-
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-/* Three-byte sequence. */
-JUMPHERE(jump);
-exit_invalid[1] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, -0x40);
-
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
-
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0);
-jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x10);
-
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-/* Four-byte sequence. */
-JUMPHERE(jump);
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0 - 0x80);
-exit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x40);
-
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xf0);
-exit_invalid[3] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x05);
-
-exit_ok_label = LABEL();
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-/* Two-byte sequence. */
-JUMPHERE(buffer_start_close);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
-
-exit_invalid[4] = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0);
-
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
-
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
-CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x20, exit_ok_label);
-
-/* Three-byte sequence. */
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-exit_invalid[5] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, -0x40);
-exit_invalid[6] = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0);
-
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
-
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0);
-CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x10, exit_ok_label);
-
-/* Four-byte sequences are not possible. */
-
-exit_invalid_label = LABEL();
-sljit_set_label(exit_invalid[5], exit_invalid_label);
-sljit_set_label(exit_invalid[6], exit_invalid_label);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-JUMPHERE(exit_invalid[4]);
-/* -2 + 4 = 2 */
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
-
-exit_invalid_label = LABEL();
-for (i = 0; i < 4; i++)
- sljit_set_label(exit_invalid[i], exit_invalid_label);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(4));
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-}
-
-static void do_utfpeakcharback(compiler_common *common)
-{
-/* Peak a character back. Does not modify STR_PTR. */
-DEFINE_COMPILER;
-struct sljit_jump *jump[2];
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
-jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x20);
-
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-3));
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0);
-jump[1] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x10);
-
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-4));
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0 - 0x80);
-OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf0);
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-
-JUMPHERE(jump[1]);
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
-OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
-OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-
-JUMPHERE(jump[0]);
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
-OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
-OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-}
-
-static void do_utfpeakcharback_invalid(compiler_common *common)
-{
-/* Peak a character back. Does not modify STR_PTR. */
-DEFINE_COMPILER;
-sljit_s32 i;
-sljit_s32 has_cmov = sljit_has_cpu_feature(SLJIT_HAS_CMOV);
-struct sljit_jump *jump[2];
-struct sljit_label *two_byte_entry;
-struct sljit_label *three_byte_entry;
-struct sljit_label *exit_invalid_label;
-struct sljit_jump *exit_invalid[8];
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-
-OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
-exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xc0);
-jump[0] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, STR_PTR, 0);
-
-/* Two-byte sequence. */
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
-OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2);
-jump[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x1e);
-
-two_byte_entry = LABEL();
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
-/* If TMP1 is in 0x80-0xbf range, TMP1 is also increased by (0x2 << 6). */
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-JUMPHERE(jump[1]);
-OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2 - 0x80);
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x80);
-exit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-
-/* Three-byte sequence. */
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-3));
-OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xe0);
-jump[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x10);
-
-three_byte_entry = LABEL();
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);
-if (has_cmov)
- {
- OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x800);
- CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, -0xd800);
- exit_invalid[2] = NULL;
- }
-else
- exit_invalid[2] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x800);
-
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);
-if (has_cmov)
- {
- OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x800);
- CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);
- exit_invalid[3] = NULL;
- }
-else
- exit_invalid[3] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x800);
-
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-JUMPHERE(jump[1]);
-OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xe0 - 0x80);
-exit_invalid[4] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-
-/* Four-byte sequence. */
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-4));
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
-OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf0);
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 18);
-/* ADD is used instead of OR because of the SUB 0x10000 above. */
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
-
-if (has_cmov)
- {
- OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x100000);
- CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0x10000);
- exit_invalid[5] = NULL;
- }
-else
- exit_invalid[5] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x100000);
-
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-JUMPHERE(jump[0]);
-OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
-jump[0] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, STR_PTR, 0);
-
-/* Two-byte sequence. */
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
-OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2);
-CMPTO(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0x1e, two_byte_entry);
-
-OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2 - 0x80);
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x80);
-exit_invalid[6] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-
-/* Three-byte sequence. */
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-3));
-OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xe0);
-CMPTO(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0x10, three_byte_entry);
-
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-JUMPHERE(jump[0]);
-exit_invalid[7] = CMP(SLJIT_GREATER, TMP2, 0, STR_PTR, 0);
-
-/* Two-byte sequence. */
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
-OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2);
-CMPTO(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0x1e, two_byte_entry);
-
-exit_invalid_label = LABEL();
-for (i = 0; i < 8; i++)
- sljit_set_label(exit_invalid[i], exit_invalid_label);
-
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-}
-
-#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
-
-#if PCRE2_CODE_UNIT_WIDTH == 16
-
-static void do_utfreadchar_invalid(compiler_common *common)
-{
-/* Slow decoding a UTF-16 character. TMP1 contains the first half
-of the character (>= 0xd800). Return char value in TMP1. STR_PTR is
-undefined for invalid characters. */
-DEFINE_COMPILER;
-struct sljit_jump *exit_invalid[3];
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-
-/* TMP2 contains the high surrogate. */
-exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00);
-exit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
-OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x10000);
-exit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x400);
-
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-JUMPHERE(exit_invalid[0]);
-JUMPHERE(exit_invalid[1]);
-JUMPHERE(exit_invalid[2]);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-}
-
-static void do_utfreadnewline_invalid(compiler_common *common)
-{
-/* Slow decoding a UTF-16 character, specialized for newlines.
-TMP1 contains the first half of the character (>= 0xd800). Return
-char value in TMP1. */
-
-DEFINE_COMPILER;
-struct sljit_jump *exit_invalid[2];
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-
-/* TMP2 contains the high surrogate. */
-exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
-exit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00);
-
-OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xdc00);
-OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0x400);
-OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000);
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-JUMPHERE(exit_invalid[0]);
-JUMPHERE(exit_invalid[1]);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-}
-
-static void do_utfmoveback_invalid(compiler_common *common)
-{
-/* Goes one character back. */
-DEFINE_COMPILER;
-struct sljit_jump *exit_invalid[3];
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-
-exit_invalid[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x400);
-exit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, STR_PTR, 0);
-
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);
-exit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x400);
-
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-JUMPHERE(exit_invalid[0]);
-JUMPHERE(exit_invalid[1]);
-JUMPHERE(exit_invalid[2]);
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-}
-
-static void do_utfpeakcharback_invalid(compiler_common *common)
-{
-/* Peak a character back. Does not modify STR_PTR. */
-DEFINE_COMPILER;
-struct sljit_jump *jump;
-struct sljit_jump *exit_invalid[3];
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-
-jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xe000);
-OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
-exit_invalid[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
-exit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, STR_PTR, 0);
-
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000 - 0xdc00);
-OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);
-exit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x400);
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
-
-JUMPHERE(jump);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-JUMPHERE(exit_invalid[0]);
-JUMPHERE(exit_invalid[1]);
-JUMPHERE(exit_invalid[2]);
-
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-}
-
-#endif /* PCRE2_CODE_UNIT_WIDTH == 16 */
-
-/* UCD_BLOCK_SIZE must be 128 (see the assert below). */
-#define UCD_BLOCK_MASK 127
-#define UCD_BLOCK_SHIFT 7
-
-static void do_getucd(compiler_common *common)
-{
-/* Search the UCD record for the character comes in TMP1.
-Returns chartype in TMP1 and UCD offset in TMP2. */
-DEFINE_COMPILER;
-#if PCRE2_CODE_UNIT_WIDTH == 32
-struct sljit_jump *jump;
-#endif
-
-#if defined SLJIT_DEBUG && SLJIT_DEBUG
-/* dummy_ucd_record */
-const ucd_record *record = GET_UCD(UNASSIGNED_UTF_CHAR);
-SLJIT_ASSERT(record->script == ucp_Unknown && record->chartype == ucp_Cn && record->gbprop == ucp_gbOther);
-SLJIT_ASSERT(record->caseset == 0 && record->other_case == 0);
-#endif
-
-SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 12);
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-
-#if PCRE2_CODE_UNIT_WIDTH == 32
-if (!common->utf)
- {
- jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, MAX_UTF_CODE_POINT + 1);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, UNASSIGNED_UTF_CHAR);
- JUMPHERE(jump);
- }
-#endif
-
-OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
-OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));
-OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
-OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-}
-
-static void do_getucdtype(compiler_common *common)
-{
-/* Search the UCD record for the character comes in TMP1.
-Returns chartype in TMP1 and UCD offset in TMP2. */
-DEFINE_COMPILER;
-#if PCRE2_CODE_UNIT_WIDTH == 32
-struct sljit_jump *jump;
-#endif
-
-#if defined SLJIT_DEBUG && SLJIT_DEBUG
-/* dummy_ucd_record */
-const ucd_record *record = GET_UCD(UNASSIGNED_UTF_CHAR);
-SLJIT_ASSERT(record->script == ucp_Unknown && record->chartype == ucp_Cn && record->gbprop == ucp_gbOther);
-SLJIT_ASSERT(record->caseset == 0 && record->other_case == 0);
-#endif
-
-SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 12);
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-
-#if PCRE2_CODE_UNIT_WIDTH == 32
-if (!common->utf)
- {
- jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, MAX_UTF_CODE_POINT + 1);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, UNASSIGNED_UTF_CHAR);
- JUMPHERE(jump);
- }
-#endif
-
-OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
-OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));
-OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
-OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
-
-/* TMP2 is multiplied by 12. Same as (TMP2 << 2) + ((TMP2 << 2) << 1). */
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
-OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 1);
-
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-}
-
-#endif /* SUPPORT_UNICODE */
-
-static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common)
-{
-DEFINE_COMPILER;
-struct sljit_label *mainloop;
-struct sljit_label *newlinelabel = NULL;
-struct sljit_jump *start;
-struct sljit_jump *end = NULL;
-struct sljit_jump *end2 = NULL;
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-struct sljit_label *loop;
-struct sljit_jump *jump;
-#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */
-jump_list *newline = NULL;
-sljit_u32 overall_options = common->re->overall_options;
-BOOL hascrorlf = (common->re->flags & PCRE2_HASCRORLF) != 0;
-BOOL newlinecheck = FALSE;
-BOOL readuchar = FALSE;
-
-if (!(hascrorlf || (overall_options & PCRE2_FIRSTLINE) != 0)
- && (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
- newlinecheck = TRUE;
-
-SLJIT_ASSERT(common->abort_label == NULL);
-
-if ((overall_options & PCRE2_FIRSTLINE) != 0)
- {
- /* Search for the end of the first line. */
- SLJIT_ASSERT(common->match_end_ptr != 0);
- OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
-
- if (common->nltype == NLTYPE_FIXED && common->newline > 255)
- {
- mainloop = LABEL();
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
- CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
- CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
- JUMPHERE(end);
- OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- }
- else
- {
- end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- mainloop = LABEL();
- /* Continual stores does not cause data dependency. */
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0);
- read_char(common, common->nlmin, common->nlmax, NULL, READ_CHAR_NEWLINE);
- check_newlinechar(common, common->nltype, &newline, TRUE);
- CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, mainloop);
- JUMPHERE(end);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0);
- set_jumps(newline, LABEL());
- }
-
- OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
- }
-else if ((overall_options & PCRE2_USE_OFFSET_LIMIT) != 0)
- {
- /* Check whether offset limit is set and valid. */
- SLJIT_ASSERT(common->match_end_ptr != 0);
-
- if (HAS_VIRTUAL_REGISTERS)
- {
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, offset_limit));
- }
- else
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, offset_limit));
-
- OP1(SLJIT_MOV, TMP2, 0, STR_END, 0);
- end = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw) PCRE2_UNSET);
- if (HAS_VIRTUAL_REGISTERS)
- OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
- else
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
-
-#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
- OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
-#endif /* PCRE2_CODE_UNIT_WIDTH == [16|32] */
- if (HAS_VIRTUAL_REGISTERS)
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
-
- OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
- end2 = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0);
- OP1(SLJIT_MOV, TMP2, 0, STR_END, 0);
- JUMPHERE(end2);
- OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);
- add_jump(compiler, &common->abort, CMP(SLJIT_LESS, TMP2, 0, STR_PTR, 0));
- JUMPHERE(end);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, TMP2, 0);
- }
-
-start = JUMP(SLJIT_JUMP);
-
-if (newlinecheck)
- {
- newlinelabel = LABEL();
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
- OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);
-#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
- OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
-#endif /* PCRE2_CODE_UNIT_WIDTH == [16|32] */
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
- end2 = JUMP(SLJIT_JUMP);
- }
-
-mainloop = LABEL();
-
-/* Increasing the STR_PTR here requires one less jump in the most common case. */
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-if (common->utf && !common->invalid_utf) readuchar = TRUE;
-#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */
-if (newlinecheck) readuchar = TRUE;
-
-if (readuchar)
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
-
-if (newlinecheck)
- CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-#if PCRE2_CODE_UNIT_WIDTH == 8
-if (common->invalid_utf)
- {
- /* Skip continuation code units. */
- loop = LABEL();
- jump = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x80);
- CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x40, loop);
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- JUMPHERE(jump);
- }
-else if (common->utf)
- {
- jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
- OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
- JUMPHERE(jump);
- }
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-if (common->invalid_utf)
- {
- /* Skip continuation code units. */
- loop = LABEL();
- jump = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
- CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x400, loop);
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- JUMPHERE(jump);
- }
-else if (common->utf)
- {
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);
-
- if (sljit_has_cpu_feature(SLJIT_HAS_CMOV))
- {
- OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x400);
- CMOV(SLJIT_LESS, STR_PTR, TMP2, 0);
- }
- else
- {
- OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x400);
- OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_LESS);
- OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
- }
- }
-#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */
-#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */
-JUMPHERE(start);
-
-if (newlinecheck)
- {
- JUMPHERE(end);
- JUMPHERE(end2);
- }
-
-return mainloop;
-}
-
-
-static SLJIT_INLINE void add_prefix_char(PCRE2_UCHAR chr, fast_forward_char_data *chars, BOOL last)
-{
-sljit_u32 i, count = chars->count;
-
-if (count == 255)
- return;
-
-if (count == 0)
- {
- chars->count = 1;
- chars->chars[0] = chr;
-
- if (last)
- chars->last_count = 1;
- return;
- }
-
-for (i = 0; i < count; i++)
- if (chars->chars[i] == chr)
- return;
-
-if (count >= MAX_DIFF_CHARS)
- {
- chars->count = 255;
- return;
- }
-
-chars->chars[count] = chr;
-chars->count = count + 1;
-
-if (last)
- chars->last_count++;
-}
-
-static int scan_prefix(compiler_common *common, PCRE2_SPTR cc, fast_forward_char_data *chars, int max_chars, sljit_u32 *rec_count)
-{
-/* Recursive function, which scans prefix literals. */
-BOOL last, any, class, caseless;
-int len, repeat, len_save, consumed = 0;
-sljit_u32 chr; /* Any unicode character. */
-sljit_u8 *bytes, *bytes_end, byte;
-PCRE2_SPTR alternative, cc_save, oc;
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
-PCRE2_UCHAR othercase[4];
-#elif defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16
-PCRE2_UCHAR othercase[2];
-#else
-PCRE2_UCHAR othercase[1];
-#endif
-
-repeat = 1;
-while (TRUE)
- {
- if (*rec_count == 0)
- return 0;
- (*rec_count)--;
-
- last = TRUE;
- any = FALSE;
- class = FALSE;
- caseless = FALSE;
-
- switch (*cc)
- {
- case OP_CHARI:
- caseless = TRUE;
- /* Fall through */
- case OP_CHAR:
- last = FALSE;
- cc++;
- break;
-
- case OP_SOD:
- case OP_SOM:
- case OP_SET_SOM:
- case OP_NOT_WORD_BOUNDARY:
- case OP_WORD_BOUNDARY:
- case OP_EODN:
- case OP_EOD:
- case OP_CIRC:
- case OP_CIRCM:
- case OP_DOLL:
- case OP_DOLLM:
- /* Zero width assertions. */
- cc++;
- continue;
-
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- case OP_ASSERT_NA:
- case OP_ASSERTBACK_NA:
- cc = bracketend(cc);
- continue;
-
- case OP_PLUSI:
- case OP_MINPLUSI:
- case OP_POSPLUSI:
- caseless = TRUE;
- /* Fall through */
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_POSPLUS:
- cc++;
- break;
-
- case OP_EXACTI:
- caseless = TRUE;
- /* Fall through */
- case OP_EXACT:
- repeat = GET2(cc, 1);
- last = FALSE;
- cc += 1 + IMM2_SIZE;
- break;
-
- case OP_QUERYI:
- case OP_MINQUERYI:
- case OP_POSQUERYI:
- caseless = TRUE;
- /* Fall through */
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_POSQUERY:
- len = 1;
- cc++;
-#ifdef SUPPORT_UNICODE
- if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
-#endif
- max_chars = scan_prefix(common, cc + len, chars, max_chars, rec_count);
- if (max_chars == 0)
- return consumed;
- last = FALSE;
- break;
-
- case OP_KET:
- cc += 1 + LINK_SIZE;
- continue;
-
- case OP_ALT:
- cc += GET(cc, 1);
- continue;
-
- case OP_ONCE:
- case OP_BRA:
- case OP_BRAPOS:
- case OP_CBRA:
- case OP_CBRAPOS:
- alternative = cc + GET(cc, 1);
- while (*alternative == OP_ALT)
- {
- max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, max_chars, rec_count);
- if (max_chars == 0)
- return consumed;
- alternative += GET(alternative, 1);
- }
-
- if (*cc == OP_CBRA || *cc == OP_CBRAPOS)
- cc += IMM2_SIZE;
- cc += 1 + LINK_SIZE;
- continue;
-
- case OP_CLASS:
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
- if (common->utf && !is_char7_bitset((const sljit_u8 *)(cc + 1), FALSE))
- return consumed;
-#endif
- class = TRUE;
- break;
-
- case OP_NCLASS:
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (common->utf) return consumed;
-#endif
- class = TRUE;
- break;
-
-#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
- case OP_XCLASS:
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (common->utf) return consumed;
-#endif
- any = TRUE;
- cc += GET(cc, 1);
- break;
-#endif
-
- case OP_DIGIT:
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
- if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_digit, FALSE))
- return consumed;
-#endif
- any = TRUE;
- cc++;
- break;
-
- case OP_WHITESPACE:
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
- if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_space, FALSE))
- return consumed;
-#endif
- any = TRUE;
- cc++;
- break;
-
- case OP_WORDCHAR:
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
- if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_word, FALSE))
- return consumed;
-#endif
- any = TRUE;
- cc++;
- break;
-
- case OP_NOT:
- case OP_NOTI:
- cc++;
- /* Fall through. */
- case OP_NOT_DIGIT:
- case OP_NOT_WHITESPACE:
- case OP_NOT_WORDCHAR:
- case OP_ANY:
- case OP_ALLANY:
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (common->utf) return consumed;
-#endif
- any = TRUE;
- cc++;
- break;
-
-#ifdef SUPPORT_UNICODE
- case OP_NOTPROP:
- case OP_PROP:
-#if PCRE2_CODE_UNIT_WIDTH != 32
- if (common->utf) return consumed;
-#endif
- any = TRUE;
- cc += 1 + 2;
- break;
-#endif
-
- case OP_TYPEEXACT:
- repeat = GET2(cc, 1);
- cc += 1 + IMM2_SIZE;
- continue;
-
- case OP_NOTEXACT:
- case OP_NOTEXACTI:
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (common->utf) return consumed;
-#endif
- any = TRUE;
- repeat = GET2(cc, 1);
- cc += 1 + IMM2_SIZE + 1;
- break;
-
- default:
- return consumed;
- }
-
- if (any)
- {
- do
- {
- chars->count = 255;
-
- consumed++;
- if (--max_chars == 0)
- return consumed;
- chars++;
- }
- while (--repeat > 0);
-
- repeat = 1;
- continue;
- }
-
- if (class)
- {
- bytes = (sljit_u8*) (cc + 1);
- cc += 1 + 32 / sizeof(PCRE2_UCHAR);
-
- switch (*cc)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRPOSSTAR:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- case OP_CRPOSQUERY:
- max_chars = scan_prefix(common, cc + 1, chars, max_chars, rec_count);
- if (max_chars == 0)
- return consumed;
- break;
-
- default:
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRPOSPLUS:
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- case OP_CRPOSRANGE:
- repeat = GET2(cc, 1);
- if (repeat <= 0)
- return consumed;
- break;
- }
-
- do
- {
- if (bytes[31] & 0x80)
- chars->count = 255;
- else if (chars->count != 255)
- {
- bytes_end = bytes + 32;
- chr = 0;
- do
- {
- byte = *bytes++;
- SLJIT_ASSERT((chr & 0x7) == 0);
- if (byte == 0)
- chr += 8;
- else
- {
- do
- {
- if ((byte & 0x1) != 0)
- add_prefix_char(chr, chars, TRUE);
- byte >>= 1;
- chr++;
- }
- while (byte != 0);
- chr = (chr + 7) & ~7;
- }
- }
- while (chars->count != 255 && bytes < bytes_end);
- bytes = bytes_end - 32;
- }
-
- consumed++;
- if (--max_chars == 0)
- return consumed;
- chars++;
- }
- while (--repeat > 0);
-
- switch (*cc)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRPOSSTAR:
- return consumed;
-
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- case OP_CRPOSQUERY:
- cc++;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- case OP_CRPOSRANGE:
- if (GET2(cc, 1) != GET2(cc, 1 + IMM2_SIZE))
- return consumed;
- cc += 1 + 2 * IMM2_SIZE;
- break;
- }
-
- repeat = 1;
- continue;
- }
-
- len = 1;
-#ifdef SUPPORT_UNICODE
- if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
-#endif
-
- if (caseless && char_has_othercase(common, cc))
- {
-#ifdef SUPPORT_UNICODE
- if (common->utf)
- {
- GETCHAR(chr, cc);
- if ((int)PRIV(ord2utf)(char_othercase(common, chr), othercase) != len)
- return consumed;
- }
- else
-#endif
- {
- chr = *cc;
-#ifdef SUPPORT_UNICODE
- if (common->ucp && chr > 127)
- othercase[0] = UCD_OTHERCASE(chr);
- else
-#endif
- othercase[0] = TABLE_GET(chr, common->fcc, chr);
- }
- }
- else
- {
- caseless = FALSE;
- othercase[0] = 0; /* Stops compiler warning - PH */
- }
-
- len_save = len;
- cc_save = cc;
- while (TRUE)
- {
- oc = othercase;
- do
- {
- len--;
- consumed++;
-
- chr = *cc;
- add_prefix_char(*cc, chars, len == 0);
-
- if (caseless)
- add_prefix_char(*oc, chars, len == 0);
-
- if (--max_chars == 0)
- return consumed;
- chars++;
- cc++;
- oc++;
- }
- while (len > 0);
-
- if (--repeat == 0)
- break;
-
- len = len_save;
- cc = cc_save;
- }
-
- repeat = 1;
- if (last)
- return consumed;
- }
-}
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-static void jumpto_if_not_utf_char_start(struct sljit_compiler *compiler, sljit_s32 reg, struct sljit_label *label)
-{
-#if PCRE2_CODE_UNIT_WIDTH == 8
-OP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xc0);
-CMPTO(SLJIT_EQUAL, reg, 0, SLJIT_IMM, 0x80, label);
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-OP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xfc00);
-CMPTO(SLJIT_EQUAL, reg, 0, SLJIT_IMM, 0xdc00, label);
-#else
-#error "Unknown code width"
-#endif
-}
-#endif
-
-#include "pcre2_jit_simd_inc.h"
-
-#ifdef JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD
-
-static BOOL check_fast_forward_char_pair_simd(compiler_common *common, fast_forward_char_data *chars, int max)
-{
- sljit_s32 i, j, max_i = 0, max_j = 0;
- sljit_u32 max_pri = 0;
- PCRE2_UCHAR a1, a2, a_pri, b1, b2, b_pri;
-
- for (i = max - 1; i >= 1; i--)
- {
- if (chars[i].last_count > 2)
- {
- a1 = chars[i].chars[0];
- a2 = chars[i].chars[1];
- a_pri = chars[i].last_count;
-
- j = i - max_fast_forward_char_pair_offset();
- if (j < 0)
- j = 0;
-
- while (j < i)
- {
- b_pri = chars[j].last_count;
- if (b_pri > 2 && (sljit_u32)a_pri + (sljit_u32)b_pri >= max_pri)
- {
- b1 = chars[j].chars[0];
- b2 = chars[j].chars[1];
-
- if (a1 != b1 && a1 != b2 && a2 != b1 && a2 != b2)
- {
- max_pri = a_pri + b_pri;
- max_i = i;
- max_j = j;
- }
- }
- j++;
- }
- }
- }
-
-if (max_pri == 0)
- return FALSE;
-
-fast_forward_char_pair_simd(common, max_i, chars[max_i].chars[0], chars[max_i].chars[1], max_j, chars[max_j].chars[0], chars[max_j].chars[1]);
-return TRUE;
-}
-
-#endif /* JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD */
-
-static void fast_forward_first_char2(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset)
-{
-DEFINE_COMPILER;
-struct sljit_label *start;
-struct sljit_jump *match;
-struct sljit_jump *partial_quit;
-PCRE2_UCHAR mask;
-BOOL has_match_end = (common->match_end_ptr != 0);
-
-SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE || offset == 0);
-
-if (has_match_end)
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
-
-if (offset > 0)
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));
-
-if (has_match_end)
- {
- OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
-
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offset + 1));
- OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_END, 0, TMP1, 0);
- CMOV(SLJIT_GREATER, STR_END, TMP1, 0);
- }
-
-#ifdef JIT_HAS_FAST_FORWARD_CHAR_SIMD
-
-if (JIT_HAS_FAST_FORWARD_CHAR_SIMD)
- {
- fast_forward_char_simd(common, char1, char2, offset);
-
- if (offset > 0)
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));
-
- if (has_match_end)
- OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
- return;
- }
-
-#endif
-
-start = LABEL();
-
-partial_quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-if (common->mode == PCRE2_JIT_COMPLETE)
- add_jump(compiler, &common->failed_match, partial_quit);
-
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
-if (char1 == char2)
- CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, char1, start);
-else
- {
- mask = char1 ^ char2;
- if (is_powerof2(mask))
- {
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, mask);
- CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, char1 | mask, start);
- }
- else
- {
- match = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, char1);
- CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, char2, start);
- JUMPHERE(match);
- }
- }
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-if (common->utf && offset > 0)
- {
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-(offset + 1)));
- jumpto_if_not_utf_char_start(compiler, TMP1, start);
- }
-#endif
-
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset + 1));
-
-if (common->mode != PCRE2_JIT_COMPLETE)
- JUMPHERE(partial_quit);
-
-if (has_match_end)
- OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
-}
-
-static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common)
-{
-DEFINE_COMPILER;
-struct sljit_label *start;
-struct sljit_jump *match;
-fast_forward_char_data chars[MAX_N_CHARS];
-sljit_s32 offset;
-PCRE2_UCHAR mask;
-PCRE2_UCHAR *char_set, *char_set_end;
-int i, max, from;
-int range_right = -1, range_len;
-sljit_u8 *update_table = NULL;
-BOOL in_range;
-sljit_u32 rec_count;
-
-for (i = 0; i < MAX_N_CHARS; i++)
- {
- chars[i].count = 0;
- chars[i].last_count = 0;
- }
-
-rec_count = 10000;
-max = scan_prefix(common, common->start, chars, MAX_N_CHARS, &rec_count);
-
-if (max < 1)
- return FALSE;
-
-/* Convert last_count to priority. */
-for (i = 0; i < max; i++)
- {
- SLJIT_ASSERT(chars[i].count > 0 && chars[i].last_count <= chars[i].count);
-
- if (chars[i].count == 1)
- {
- chars[i].last_count = (chars[i].last_count == 1) ? 7 : 5;
- /* Simplifies algorithms later. */
- chars[i].chars[1] = chars[i].chars[0];
- }
- else if (chars[i].count == 2)
- {
- SLJIT_ASSERT(chars[i].chars[0] != chars[i].chars[1]);
-
- if (is_powerof2(chars[i].chars[0] ^ chars[i].chars[1]))
- chars[i].last_count = (chars[i].last_count == 2) ? 6 : 4;
- else
- chars[i].last_count = (chars[i].last_count == 2) ? 3 : 2;
- }
- else
- chars[i].last_count = (chars[i].count == 255) ? 0 : 1;
- }
-
-#ifdef JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD
-if (JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD && check_fast_forward_char_pair_simd(common, chars, max))
- return TRUE;
-#endif
-
-in_range = FALSE;
-/* Prevent compiler "uninitialized" warning */
-from = 0;
-range_len = 4 /* minimum length */ - 1;
-for (i = 0; i <= max; i++)
- {
- if (in_range && (i - from) > range_len && (chars[i - 1].count < 255))
- {
- range_len = i - from;
- range_right = i - 1;
- }
-
- if (i < max && chars[i].count < 255)
- {
- SLJIT_ASSERT(chars[i].count > 0);
- if (!in_range)
- {
- in_range = TRUE;
- from = i;
- }
- }
- else
- in_range = FALSE;
- }
-
-if (range_right >= 0)
- {
- update_table = (sljit_u8 *)allocate_read_only_data(common, 256);
- if (update_table == NULL)
- return TRUE;
- memset(update_table, IN_UCHARS(range_len), 256);
-
- for (i = 0; i < range_len; i++)
- {
- SLJIT_ASSERT(chars[range_right - i].count > 0 && chars[range_right - i].count < 255);
-
- char_set = chars[range_right - i].chars;
- char_set_end = char_set + chars[range_right - i].count;
- do
- {
- if (update_table[(*char_set) & 0xff] > IN_UCHARS(i))
- update_table[(*char_set) & 0xff] = IN_UCHARS(i);
- char_set++;
- }
- while (char_set < char_set_end);
- }
- }
-
-offset = -1;
-/* Scan forward. */
-for (i = 0; i < max; i++)
- {
- if (range_right == i)
- continue;
-
- if (offset == -1)
- {
- if (chars[i].last_count >= 2)
- offset = i;
- }
- else if (chars[offset].last_count < chars[i].last_count)
- offset = i;
- }
-
-SLJIT_ASSERT(offset == -1 || (chars[offset].count >= 1 && chars[offset].count <= 2));
-
-if (range_right < 0)
- {
- if (offset < 0)
- return FALSE;
- /* Works regardless the value is 1 or 2. */
- fast_forward_first_char2(common, chars[offset].chars[0], chars[offset].chars[1], offset);
- return TRUE;
- }
-
-SLJIT_ASSERT(range_right != offset);
-
-if (common->match_end_ptr != 0)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
- OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
- OP2(SLJIT_SUB | SLJIT_SET_LESS, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
- add_jump(compiler, &common->failed_match, JUMP(SLJIT_LESS));
- OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_END, 0, TMP1, 0);
- CMOV(SLJIT_GREATER, STR_END, TMP1, 0);
- }
-else
- {
- OP2(SLJIT_SUB | SLJIT_SET_LESS, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
- add_jump(compiler, &common->failed_match, JUMP(SLJIT_LESS));
- }
-
-SLJIT_ASSERT(range_right >= 0);
-
-if (!HAS_VIRTUAL_REGISTERS)
- OP1(SLJIT_MOV, RETURN_ADDR, 0, SLJIT_IMM, (sljit_sw)update_table);
-
-start = LABEL();
-add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0));
-
-#if PCRE2_CODE_UNIT_WIDTH == 8 || (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
-OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right));
-#else
-OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right + 1) - 1);
-#endif
-
-if (!HAS_VIRTUAL_REGISTERS)
- OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(RETURN_ADDR, TMP1), 0);
-else
- OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table);
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
-CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, start);
-
-if (offset >= 0)
- {
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offset));
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
- if (chars[offset].count == 1)
- CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset].chars[0], start);
- else
- {
- mask = chars[offset].chars[0] ^ chars[offset].chars[1];
- if (is_powerof2(mask))
- {
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, mask);
- CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset].chars[0] | mask, start);
- }
- else
- {
- match = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset].chars[0]);
- CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset].chars[1], start);
- JUMPHERE(match);
- }
- }
- }
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-if (common->utf && offset != 0)
- {
- if (offset < 0)
- {
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- }
- else
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
-
- jumpto_if_not_utf_char_start(compiler, TMP1, start);
-
- if (offset < 0)
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- }
-#endif
-
-if (offset >= 0)
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
-if (common->match_end_ptr != 0)
- OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
-else
- OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
-return TRUE;
-}
-
-static SLJIT_INLINE void fast_forward_first_char(compiler_common *common)
-{
-PCRE2_UCHAR first_char = (PCRE2_UCHAR)(common->re->first_codeunit);
-PCRE2_UCHAR oc;
-
-oc = first_char;
-if ((common->re->flags & PCRE2_FIRSTCASELESS) != 0)
- {
- oc = TABLE_GET(first_char, common->fcc, first_char);
-#if defined SUPPORT_UNICODE
- if (first_char > 127 && (common->utf || common->ucp))
- oc = UCD_OTHERCASE(first_char);
-#endif
- }
-
-fast_forward_first_char2(common, first_char, oc, 0);
-}
-
-static SLJIT_INLINE void fast_forward_newline(compiler_common *common)
-{
-DEFINE_COMPILER;
-struct sljit_label *loop;
-struct sljit_jump *lastchar = NULL;
-struct sljit_jump *firstchar;
-struct sljit_jump *quit = NULL;
-struct sljit_jump *foundcr = NULL;
-struct sljit_jump *notfoundnl;
-jump_list *newline = NULL;
-
-if (common->match_end_ptr != 0)
- {
- OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
- OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
- }
-
-if (common->nltype == NLTYPE_FIXED && common->newline > 255)
- {
-#ifdef JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD
- if (JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD && common->mode == PCRE2_JIT_COMPLETE)
- {
- if (HAS_VIRTUAL_REGISTERS)
- {
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
- }
- else
- {
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
- }
- firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
-
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- OP2U(SLJIT_SUB | SLJIT_SET_Z, STR_PTR, 0, TMP1, 0);
- OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_NOT_EQUAL);
-#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
- OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
-#endif
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
-
- fast_forward_char_pair_simd(common, 1, common->newline & 0xff, common->newline & 0xff, 0, (common->newline >> 8) & 0xff, (common->newline >> 8) & 0xff);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
- }
- else
-#endif /* JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD */
- {
- lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- if (HAS_VIRTUAL_REGISTERS)
- {
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
- }
- else
- {
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
- }
- firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
-
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
- OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, STR_PTR, 0, TMP1, 0);
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER_EQUAL);
-#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
-#endif
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-
- loop = LABEL();
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
- CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
- CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
-
- JUMPHERE(quit);
- JUMPHERE(lastchar);
- }
-
- JUMPHERE(firstchar);
-
- if (common->match_end_ptr != 0)
- OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
- return;
- }
-
-if (HAS_VIRTUAL_REGISTERS)
- {
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
- }
-else
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));
-
-/* Example: match /^/ to \r\n from offset 1. */
-firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
-
-if (common->nltype == NLTYPE_ANY)
- move_back(common, NULL, FALSE);
-else
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
-loop = LABEL();
-common->ff_newline_shortcut = loop;
-
-#ifdef JIT_HAS_FAST_FORWARD_CHAR_SIMD
-if (JIT_HAS_FAST_FORWARD_CHAR_SIMD && (common->nltype == NLTYPE_FIXED || common->nltype == NLTYPE_ANYCRLF))
- {
- if (common->nltype == NLTYPE_ANYCRLF)
- {
- fast_forward_char_simd(common, CHAR_CR, CHAR_LF, 0);
- if (common->mode != PCRE2_JIT_COMPLETE)
- lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- quit = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
- }
- else
- {
- fast_forward_char_simd(common, common->newline, common->newline, 0);
-
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- if (common->mode != PCRE2_JIT_COMPLETE)
- {
- OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0);
- CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0);
- }
- }
- }
-else
-#endif /* JIT_HAS_FAST_FORWARD_CHAR_SIMD */
- {
- read_char(common, common->nlmin, common->nlmax, NULL, READ_CHAR_NEWLINE);
- lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
- foundcr = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
- check_newlinechar(common, common->nltype, &newline, FALSE);
- set_jumps(newline, loop);
- }
-
-if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
- {
- if (quit == NULL)
- {
- quit = JUMP(SLJIT_JUMP);
- JUMPHERE(foundcr);
- }
-
- notfoundnl = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_NL);
- OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);
-#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
- OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
-#endif
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
- JUMPHERE(notfoundnl);
- JUMPHERE(quit);
- }
-
-if (lastchar)
- JUMPHERE(lastchar);
-JUMPHERE(firstchar);
-
-if (common->match_end_ptr != 0)
- OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
-}
-
-static BOOL optimize_class(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks);
-
-static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common)
-{
-DEFINE_COMPILER;
-const sljit_u8 *start_bits = common->re->start_bitmap;
-struct sljit_label *start;
-struct sljit_jump *partial_quit;
-#if PCRE2_CODE_UNIT_WIDTH != 8
-struct sljit_jump *found = NULL;
-#endif
-jump_list *matches = NULL;
-
-if (common->match_end_ptr != 0)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
- OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
- OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_END, 0, TMP1, 0);
- CMOV(SLJIT_GREATER, STR_END, TMP1, 0);
- }
-
-start = LABEL();
-
-partial_quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-if (common->mode == PCRE2_JIT_COMPLETE)
- add_jump(compiler, &common->failed_match, partial_quit);
-
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
-if (!optimize_class(common, start_bits, (start_bits[31] & 0x80) != 0, FALSE, &matches))
- {
-#if PCRE2_CODE_UNIT_WIDTH != 8
- if ((start_bits[31] & 0x80) != 0)
- found = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 255);
- else
- CMPTO(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 255, start);
-#elif defined SUPPORT_UNICODE
- if (common->utf && is_char7_bitset(start_bits, FALSE))
- CMPTO(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 127, start);
-#endif
- OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
- OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
- OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits);
- if (!HAS_VIRTUAL_REGISTERS)
- {
- OP2(SLJIT_SHL, TMP3, 0, SLJIT_IMM, 1, TMP2, 0);
- OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP3, 0);
- }
- else
- {
- OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
- OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP2, 0);
- }
- JUMPTO(SLJIT_ZERO, start);
- }
-else
- set_jumps(matches, start);
-
-#if PCRE2_CODE_UNIT_WIDTH != 8
-if (found != NULL)
- JUMPHERE(found);
-#endif
-
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
-if (common->mode != PCRE2_JIT_COMPLETE)
- JUMPHERE(partial_quit);
-
-if (common->match_end_ptr != 0)
- OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
-}
-
-static SLJIT_INLINE jump_list *search_requested_char(compiler_common *common, PCRE2_UCHAR req_char, BOOL caseless, BOOL has_firstchar)
-{
-DEFINE_COMPILER;
-struct sljit_label *loop;
-struct sljit_jump *toolong;
-struct sljit_jump *already_found;
-struct sljit_jump *found;
-struct sljit_jump *found_oc = NULL;
-jump_list *not_found = NULL;
-sljit_u32 oc, bit;
-
-SLJIT_ASSERT(common->req_char_ptr != 0);
-OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(REQ_CU_MAX) * 100);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr);
-toolong = CMP(SLJIT_LESS, TMP2, 0, STR_END, 0);
-already_found = CMP(SLJIT_LESS, STR_PTR, 0, TMP1, 0);
-
-if (has_firstchar)
- OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-else
- OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
-
-oc = req_char;
-if (caseless)
- {
- oc = TABLE_GET(req_char, common->fcc, req_char);
-#if defined SUPPORT_UNICODE
- if (req_char > 127 && (common->utf || common->ucp))
- oc = UCD_OTHERCASE(req_char);
-#endif
- }
-
-#ifdef JIT_HAS_FAST_REQUESTED_CHAR_SIMD
-if (JIT_HAS_FAST_REQUESTED_CHAR_SIMD)
- {
- not_found = fast_requested_char_simd(common, req_char, oc);
- }
-else
-#endif
- {
- loop = LABEL();
- add_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));
-
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
-
- if (req_char == oc)
- found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
- else
- {
- bit = req_char ^ oc;
- if (is_powerof2(bit))
- {
- OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
- found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
- }
- else
- {
- found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
- found_oc = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, oc);
- }
- }
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
- JUMPTO(SLJIT_JUMP, loop);
-
- JUMPHERE(found);
- if (found_oc)
- JUMPHERE(found_oc);
- }
-
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, TMP1, 0);
-
-JUMPHERE(already_found);
-JUMPHERE(toolong);
-return not_found;
-}
-
-static void do_revertframes(compiler_common *common)
-{
-DEFINE_COMPILER;
-struct sljit_jump *jump;
-struct sljit_label *mainloop;
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-GET_LOCAL_BASE(TMP1, 0, 0);
-
-/* Drop frames until we reach STACK_TOP. */
-mainloop = LABEL();
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), -SSIZE_OF(sw));
-jump = CMP(SLJIT_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, 0);
-
-OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
-if (HAS_VIRTUAL_REGISTERS)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(STACK_TOP), -(2 * SSIZE_OF(sw)));
- OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(STACK_TOP), -(3 * SSIZE_OF(sw)));
- OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 3 * SSIZE_OF(sw));
- }
-else
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), -(2 * SSIZE_OF(sw)));
- OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(STACK_TOP), -(3 * SSIZE_OF(sw)));
- OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 3 * SSIZE_OF(sw));
- OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, TMP1, 0);
- GET_LOCAL_BASE(TMP1, 0, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP3, 0);
- }
-JUMPTO(SLJIT_JUMP, mainloop);
-
-JUMPHERE(jump);
-jump = CMP(SLJIT_NOT_ZERO /* SIG_LESS */, TMP2, 0, SLJIT_IMM, 0);
-/* End of reverting values. */
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-
-JUMPHERE(jump);
-OP2(SLJIT_SUB, TMP2, 0, SLJIT_IMM, 0, TMP2, 0);
-OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
-if (HAS_VIRTUAL_REGISTERS)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(STACK_TOP), -(2 * SSIZE_OF(sw)));
- OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2 * SSIZE_OF(sw));
- }
-else
- {
- OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(STACK_TOP), -(2 * SSIZE_OF(sw)));
- OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2 * SSIZE_OF(sw));
- OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, TMP3, 0);
- }
-JUMPTO(SLJIT_JUMP, mainloop);
-}
-
-static void check_wordboundary(compiler_common *common)
-{
-DEFINE_COMPILER;
-struct sljit_jump *skipread;
-jump_list *skipread_list = NULL;
-#ifdef SUPPORT_UNICODE
-struct sljit_label *valid_utf;
-jump_list *invalid_utf1 = NULL;
-#endif /* SUPPORT_UNICODE */
-jump_list *invalid_utf2 = NULL;
-#if PCRE2_CODE_UNIT_WIDTH != 8 || defined SUPPORT_UNICODE
-struct sljit_jump *jump;
-#endif /* PCRE2_CODE_UNIT_WIDTH != 8 || SUPPORT_UNICODE */
-
-SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
-
-sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
-/* Get type of the previous char, and put it to TMP3. */
-OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
-OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
-skipread = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
-
-#ifdef SUPPORT_UNICODE
-if (common->invalid_utf)
- {
- peek_char_back(common, READ_CHAR_MAX, &invalid_utf1);
-
- if (common->mode != PCRE2_JIT_COMPLETE)
- {
- OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
- OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
- move_back(common, NULL, TRUE);
- check_start_used_ptr(common);
- OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
- OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0);
- }
- }
-else
-#endif /* SUPPORT_UNICODE */
- {
- if (common->mode == PCRE2_JIT_COMPLETE)
- peek_char_back(common, READ_CHAR_MAX, NULL);
- else
- {
- move_back(common, NULL, TRUE);
- check_start_used_ptr(common);
- read_char(common, 0, READ_CHAR_MAX, NULL, READ_CHAR_UPDATE_STR_PTR);
- }
- }
-
-/* Testing char type. */
-#ifdef SUPPORT_UNICODE
-if (common->ucp)
- {
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
- jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
- add_jump(compiler, &common->getucdtype, JUMP(SLJIT_FAST_CALL));
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
- OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
- OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
- OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
- JUMPHERE(jump);
- OP1(SLJIT_MOV, TMP3, 0, TMP2, 0);
- }
-else
-#endif /* SUPPORT_UNICODE */
- {
-#if PCRE2_CODE_UNIT_WIDTH != 8
- jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
-#elif defined SUPPORT_UNICODE
- /* Here TMP3 has already been zeroed. */
- jump = NULL;
- if (common->utf)
- jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
-#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
- OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
- OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
- OP2(SLJIT_AND, TMP3, 0, TMP1, 0, SLJIT_IMM, 1);
-#if PCRE2_CODE_UNIT_WIDTH != 8
- JUMPHERE(jump);
-#elif defined SUPPORT_UNICODE
- if (jump != NULL)
- JUMPHERE(jump);
-#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
- }
-JUMPHERE(skipread);
-
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
-check_str_end(common, &skipread_list);
-peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCALS1, &invalid_utf2);
-
-/* Testing char type. This is a code duplication. */
-#ifdef SUPPORT_UNICODE
-
-valid_utf = LABEL();
-
-if (common->ucp)
- {
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
- jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
- add_jump(compiler, &common->getucdtype, JUMP(SLJIT_FAST_CALL));
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
- OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
- OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
- OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
- JUMPHERE(jump);
- }
-else
-#endif /* SUPPORT_UNICODE */
- {
-#if PCRE2_CODE_UNIT_WIDTH != 8
- /* TMP2 may be destroyed by peek_char. */
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
- jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
-#elif defined SUPPORT_UNICODE
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
- jump = NULL;
- if (common->utf)
- jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
-#endif
- OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
- OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
- OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
-#if PCRE2_CODE_UNIT_WIDTH != 8
- JUMPHERE(jump);
-#elif defined SUPPORT_UNICODE
- if (jump != NULL)
- JUMPHERE(jump);
-#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
- }
-set_jumps(skipread_list, LABEL());
-
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
-OP2(SLJIT_XOR | SLJIT_SET_Z, TMP2, 0, TMP2, 0, TMP3, 0);
-OP_SRC(SLJIT_FAST_RETURN, TMP1, 0);
-
-#ifdef SUPPORT_UNICODE
-if (common->invalid_utf)
- {
- set_jumps(invalid_utf1, LABEL());
-
- peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCALS1, NULL);
- CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR, valid_utf);
-
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, -1);
- OP_SRC(SLJIT_FAST_RETURN, TMP1, 0);
-
- set_jumps(invalid_utf2, LABEL());
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
- OP1(SLJIT_MOV, TMP2, 0, TMP3, 0);
- OP_SRC(SLJIT_FAST_RETURN, TMP1, 0);
- }
-#endif /* SUPPORT_UNICODE */
-}
-
-static BOOL optimize_class_ranges(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks)
-{
-/* May destroy TMP1. */
-DEFINE_COMPILER;
-int ranges[MAX_CLASS_RANGE_SIZE];
-sljit_u8 bit, cbit, all;
-int i, byte, length = 0;
-
-bit = bits[0] & 0x1;
-/* All bits will be zero or one (since bit is zero or one). */
-all = -bit;
-
-for (i = 0; i < 256; )
- {
- byte = i >> 3;
- if ((i & 0x7) == 0 && bits[byte] == all)
- i += 8;
- else
- {
- cbit = (bits[byte] >> (i & 0x7)) & 0x1;
- if (cbit != bit)
- {
- if (length >= MAX_CLASS_RANGE_SIZE)
- return FALSE;
- ranges[length] = i;
- length++;
- bit = cbit;
- all = -cbit;
- }
- i++;
- }
- }
-
-if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
- {
- if (length >= MAX_CLASS_RANGE_SIZE)
- return FALSE;
- ranges[length] = 256;
- length++;
- }
-
-if (length < 0 || length > 4)
- return FALSE;
-
-bit = bits[0] & 0x1;
-if (invert) bit ^= 0x1;
-
-/* No character is accepted. */
-if (length == 0 && bit == 0)
- add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
-
-switch(length)
- {
- case 0:
- /* When bit != 0, all characters are accepted. */
- return TRUE;
-
- case 1:
- add_jump(compiler, backtracks, CMP(bit == 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
- return TRUE;
-
- case 2:
- if (ranges[0] + 1 != ranges[1])
- {
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
- add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
- }
- else
- add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
- return TRUE;
-
- case 3:
- if (bit != 0)
- {
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
- if (ranges[0] + 1 != ranges[1])
- {
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
- add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
- }
- else
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
- return TRUE;
- }
-
- add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[0]));
- if (ranges[1] + 1 != ranges[2])
- {
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1]);
- add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));
- }
- else
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1]));
- return TRUE;
-
- case 4:
- if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2])
- && (ranges[0] | (ranges[2] - ranges[0])) == ranges[2]
- && (ranges[1] & (ranges[2] - ranges[0])) == 0
- && is_powerof2(ranges[2] - ranges[0]))
- {
- SLJIT_ASSERT((ranges[0] & (ranges[2] - ranges[0])) == 0 && (ranges[2] & ranges[3] & (ranges[2] - ranges[0])) != 0);
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]);
- if (ranges[2] + 1 != ranges[3])
- {
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
- add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
- }
- else
- add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
- return TRUE;
- }
-
- if (bit != 0)
- {
- i = 0;
- if (ranges[0] + 1 != ranges[1])
- {
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
- add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
- i = ranges[0];
- }
- else
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
-
- if (ranges[2] + 1 != ranges[3])
- {
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - i);
- add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
- }
- else
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2] - i));
- return TRUE;
- }
-
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[0]));
- if (ranges[1] + 1 != ranges[2])
- {
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]);
- add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));
- }
- else
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
- return TRUE;
-
- default:
- SLJIT_UNREACHABLE();
- return FALSE;
- }
-}
-
-static BOOL optimize_class_chars(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks)
-{
-/* May destroy TMP1. */
-DEFINE_COMPILER;
-uint16_t char_list[MAX_CLASS_CHARS_SIZE];
-uint8_t byte;
-sljit_s32 type;
-int i, j, k, len, c;
-
-if (!sljit_has_cpu_feature(SLJIT_HAS_CMOV))
- return FALSE;
-
-len = 0;
-
-for (i = 0; i < 32; i++)
- {
- byte = bits[i];
-
- if (nclass)
- byte = ~byte;
-
- j = 0;
- while (byte != 0)
- {
- if (byte & 0x1)
- {
- c = i * 8 + j;
-
- k = len;
-
- if ((c & 0x20) != 0)
- {
- for (k = 0; k < len; k++)
- if (char_list[k] == c - 0x20)
- {
- char_list[k] |= 0x120;
- break;
- }
- }
-
- if (k == len)
- {
- if (len >= MAX_CLASS_CHARS_SIZE)
- return FALSE;
-
- char_list[len++] = (uint16_t) c;
- }
- }
-
- byte >>= 1;
- j++;
- }
- }
-
-if (len == 0) return FALSE; /* Should never occur, but stops analyzers complaining. */
-
-i = 0;
-j = 0;
-
-if (char_list[0] == 0)
- {
- i++;
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0);
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_ZERO);
- }
-else
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
-
-while (i < len)
- {
- if ((char_list[i] & 0x100) != 0)
- j++;
- else
- {
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, char_list[i]);
- CMOV(SLJIT_ZERO, TMP2, TMP1, 0);
- }
- i++;
- }
-
-if (j != 0)
- {
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x20);
-
- for (i = 0; i < len; i++)
- if ((char_list[i] & 0x100) != 0)
- {
- j--;
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, char_list[i] & 0xff);
- CMOV(SLJIT_ZERO, TMP2, TMP1, 0);
- }
- }
-
-if (invert)
- nclass = !nclass;
-
-type = nclass ? SLJIT_NOT_EQUAL : SLJIT_EQUAL;
-add_jump(compiler, backtracks, CMP(type, TMP2, 0, SLJIT_IMM, 0));
-return TRUE;
-}
-
-static BOOL optimize_class(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks)
-{
-/* May destroy TMP1. */
-if (optimize_class_ranges(common, bits, nclass, invert, backtracks))
- return TRUE;
-return optimize_class_chars(common, bits, nclass, invert, backtracks);
-}
-
-static void check_anynewline(compiler_common *common)
-{
-/* Check whether TMP1 contains a newline character. TMP2 destroyed. */
-DEFINE_COMPILER;
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
-OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
-OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
-OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
-#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
-#if PCRE2_CODE_UNIT_WIDTH == 8
-if (common->utf)
- {
-#endif
- OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
-#if PCRE2_CODE_UNIT_WIDTH == 8
- }
-#endif
-#endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */
-OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-}
-
-static void check_hspace(compiler_common *common)
-{
-/* Check whether TMP1 contains a newline character. TMP2 destroyed. */
-DEFINE_COMPILER;
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-
-OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x09);
-OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
-OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x20);
-OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
-OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0xa0);
-#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
-#if PCRE2_CODE_UNIT_WIDTH == 8
-if (common->utf)
- {
-#endif
- OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x1680);
- OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x180e);
- OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
- OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
- OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
- OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);
- OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);
-#if PCRE2_CODE_UNIT_WIDTH == 8
- }
-#endif
-#endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */
-OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);
-
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-}
-
-static void check_vspace(compiler_common *common)
-{
-/* Check whether TMP1 contains a newline character. TMP2 destroyed. */
-DEFINE_COMPILER;
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
-OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
-OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
-OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
-#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
-#if PCRE2_CODE_UNIT_WIDTH == 8
-if (common->utf)
- {
-#endif
- OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
-#if PCRE2_CODE_UNIT_WIDTH == 8
- }
-#endif
-#endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */
-OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);
-
-OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
-}
-
-static void do_casefulcmp(compiler_common *common)
-{
-DEFINE_COMPILER;
-struct sljit_jump *jump;
-struct sljit_label *label;
-int char1_reg;
-int char2_reg;
-
-if (HAS_VIRTUAL_REGISTERS)
- {
- char1_reg = STR_END;
- char2_reg = STACK_TOP;
- }
-else
- {
- char1_reg = TMP3;
- char2_reg = RETURN_ADDR;
- }
-
-sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-
-if (char1_reg == STR_END)
- {
- OP1(SLJIT_MOV, TMP3, 0, char1_reg, 0);
- OP1(SLJIT_MOV, RETURN_ADDR, 0, char2_reg, 0);
- }
-
-if (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
- {
- label = LABEL();
- sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
- sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_POST, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
- jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
- OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
- JUMPTO(SLJIT_NOT_ZERO, label);
-
- JUMPHERE(jump);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
- }
-else if (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
- {
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
- label = LABEL();
- sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
- sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
- jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
- OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
- JUMPTO(SLJIT_NOT_ZERO, label);
-
- JUMPHERE(jump);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- }
-else
- {
- label = LABEL();
- OP1(MOV_UCHAR, char1_reg, 0, SLJIT_MEM1(TMP1), 0);
- OP1(MOV_UCHAR, char2_reg, 0, SLJIT_MEM1(STR_PTR), 0);
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
- OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
- JUMPTO(SLJIT_NOT_ZERO, label);
-
- JUMPHERE(jump);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
- }
-
-if (char1_reg == STR_END)
- {
- OP1(SLJIT_MOV, char1_reg, 0, TMP3, 0);
- OP1(SLJIT_MOV, char2_reg, 0, RETURN_ADDR, 0);
- }
-
-OP_SRC(SLJIT_FAST_RETURN, TMP1, 0);
-}
-
-static void do_caselesscmp(compiler_common *common)
-{
-DEFINE_COMPILER;
-struct sljit_jump *jump;
-struct sljit_label *label;
-int char1_reg = STR_END;
-int char2_reg;
-int lcc_table;
-int opt_type = 0;
-
-if (HAS_VIRTUAL_REGISTERS)
- {
- char2_reg = STACK_TOP;
- lcc_table = STACK_LIMIT;
- }
-else
- {
- char2_reg = RETURN_ADDR;
- lcc_table = TMP3;
- }
-
-if (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
- opt_type = 1;
-else if (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
- opt_type = 2;
-
-sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, char1_reg, 0);
-
-if (char2_reg == STACK_TOP)
- {
- OP1(SLJIT_MOV, TMP3, 0, char2_reg, 0);
- OP1(SLJIT_MOV, RETURN_ADDR, 0, lcc_table, 0);
- }
-
-OP1(SLJIT_MOV, lcc_table, 0, SLJIT_IMM, common->lcc);
-
-if (opt_type == 1)
- {
- label = LABEL();
- sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
- sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_POST, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
- }
-else if (opt_type == 2)
- {
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
- label = LABEL();
- sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
- sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
- }
-else
- {
- label = LABEL();
- OP1(MOV_UCHAR, char1_reg, 0, SLJIT_MEM1(TMP1), 0);
- OP1(MOV_UCHAR, char2_reg, 0, SLJIT_MEM1(STR_PTR), 0);
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
- }
-
-#if PCRE2_CODE_UNIT_WIDTH != 8
-jump = CMP(SLJIT_GREATER, char1_reg, 0, SLJIT_IMM, 255);
-#endif
-OP1(SLJIT_MOV_U8, char1_reg, 0, SLJIT_MEM2(lcc_table, char1_reg), 0);
-#if PCRE2_CODE_UNIT_WIDTH != 8
-JUMPHERE(jump);
-jump = CMP(SLJIT_GREATER, char2_reg, 0, SLJIT_IMM, 255);
-#endif
-OP1(SLJIT_MOV_U8, char2_reg, 0, SLJIT_MEM2(lcc_table, char2_reg), 0);
-#if PCRE2_CODE_UNIT_WIDTH != 8
-JUMPHERE(jump);
-#endif
-
-if (opt_type == 0)
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
-jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
-OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
-JUMPTO(SLJIT_NOT_ZERO, label);
-
-JUMPHERE(jump);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
-
-if (opt_type == 2)
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
-if (char2_reg == STACK_TOP)
- {
- OP1(SLJIT_MOV, char2_reg, 0, TMP3, 0);
- OP1(SLJIT_MOV, lcc_table, 0, RETURN_ADDR, 0);
- }
-
-OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
-OP_SRC(SLJIT_FAST_RETURN, TMP1, 0);
-}
-
-static PCRE2_SPTR byte_sequence_compare(compiler_common *common, BOOL caseless, PCRE2_SPTR cc,
- compare_context *context, jump_list **backtracks)
-{
-DEFINE_COMPILER;
-unsigned int othercasebit = 0;
-PCRE2_SPTR othercasechar = NULL;
-#ifdef SUPPORT_UNICODE
-int utflength;
-#endif
-
-if (caseless && char_has_othercase(common, cc))
- {
- othercasebit = char_get_othercase_bit(common, cc);
- SLJIT_ASSERT(othercasebit);
- /* Extracting bit difference info. */
-#if PCRE2_CODE_UNIT_WIDTH == 8
- othercasechar = cc + (othercasebit >> 8);
- othercasebit &= 0xff;
-#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
- /* Note that this code only handles characters in the BMP. If there
- ever are characters outside the BMP whose othercase differs in only one
- bit from itself (there currently are none), this code will need to be
- revised for PCRE2_CODE_UNIT_WIDTH == 32. */
- othercasechar = cc + (othercasebit >> 9);
- if ((othercasebit & 0x100) != 0)
- othercasebit = (othercasebit & 0xff) << 8;
- else
- othercasebit &= 0xff;
-#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */
- }
-
-if (context->sourcereg == -1)
- {
-#if PCRE2_CODE_UNIT_WIDTH == 8
-#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
- if (context->length >= 4)
- OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
- else if (context->length >= 2)
- OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
- else
-#endif
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
- if (context->length >= 4)
- OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
- else
-#endif
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
-#elif PCRE2_CODE_UNIT_WIDTH == 32
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
-#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */
- context->sourcereg = TMP2;
- }
-
-#ifdef SUPPORT_UNICODE
-utflength = 1;
-if (common->utf && HAS_EXTRALEN(*cc))
- utflength += GET_EXTRALEN(*cc);
-
-do
- {
-#endif
-
- context->length -= IN_UCHARS(1);
-#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16)
-
- /* Unaligned read is supported. */
- if (othercasebit != 0 && othercasechar == cc)
- {
- context->c.asuchars[context->ucharptr] = *cc | othercasebit;
- context->oc.asuchars[context->ucharptr] = othercasebit;
- }
- else
- {
- context->c.asuchars[context->ucharptr] = *cc;
- context->oc.asuchars[context->ucharptr] = 0;
- }
- context->ucharptr++;
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
- if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
-#else
- if (context->ucharptr >= 2 || context->length == 0)
-#endif
- {
- if (context->length >= 4)
- OP1(SLJIT_MOV_S32, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
- else if (context->length >= 2)
- OP1(SLJIT_MOV_U16, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
-#if PCRE2_CODE_UNIT_WIDTH == 8
- else if (context->length >= 1)
- OP1(SLJIT_MOV_U8, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
-#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
- context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
-
- switch(context->ucharptr)
- {
- case 4 / sizeof(PCRE2_UCHAR):
- if (context->oc.asint != 0)
- OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
- break;
-
- case 2 / sizeof(PCRE2_UCHAR):
- if (context->oc.asushort != 0)
- OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));
- break;
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
- case 1:
- if (context->oc.asbyte != 0)
- OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));
- break;
-#endif
-
- default:
- SLJIT_UNREACHABLE();
- break;
- }
- context->ucharptr = 0;
- }
-
-#else
-
- /* Unaligned read is unsupported or in 32 bit mode. */
- if (context->length >= 1)
- OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
-
- context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
-
- if (othercasebit != 0 && othercasechar == cc)
- {
- OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));
- }
- else
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc));
-
-#endif
-
- cc++;
-#ifdef SUPPORT_UNICODE
- utflength--;
- }
-while (utflength > 0);
-#endif
-
-return cc;
-}
-
-#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
-
-#define SET_TYPE_OFFSET(value) \
- if ((value) != typeoffset) \
- { \
- if ((value) < typeoffset) \
- OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \
- else \
- OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \
- } \
- typeoffset = (value);
-
-#define SET_CHAR_OFFSET(value) \
- if ((value) != charoffset) \
- { \
- if ((value) < charoffset) \
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(charoffset - (value))); \
- else \
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)((value) - charoffset)); \
- } \
- charoffset = (value);
-
-static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr);
-
-#ifdef SUPPORT_UNICODE
-#define XCLASS_SAVE_CHAR 0x001
-#define XCLASS_CHAR_SAVED 0x002
-#define XCLASS_HAS_TYPE 0x004
-#define XCLASS_HAS_SCRIPT 0x008
-#define XCLASS_HAS_SCRIPT_EXTENSION 0x010
-#define XCLASS_HAS_BOOL 0x020
-#define XCLASS_HAS_BIDICL 0x040
-#define XCLASS_NEEDS_UCD (XCLASS_HAS_TYPE | XCLASS_HAS_SCRIPT | XCLASS_HAS_SCRIPT_EXTENSION | XCLASS_HAS_BOOL | XCLASS_HAS_BIDICL)
-#define XCLASS_SCRIPT_EXTENSION_NOTPROP 0x080
-#define XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR 0x100
-#define XCLASS_SCRIPT_EXTENSION_RESTORE_LOCALS0 0x200
-
-#endif /* SUPPORT_UNICODE */
-
-static void compile_xclass_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks)
-{
-DEFINE_COMPILER;
-jump_list *found = NULL;
-jump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks;
-sljit_uw c, charoffset, max = 256, min = READ_CHAR_MAX;
-struct sljit_jump *jump = NULL;
-PCRE2_SPTR ccbegin;
-int compares, invertcmp, numberofcmps;
-#if defined SUPPORT_UNICODE && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16)
-BOOL utf = common->utf;
-#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == [8|16] */
-
-#ifdef SUPPORT_UNICODE
-sljit_u32 unicode_status = 0;
-int typereg = TMP1;
-const sljit_u32 *other_cases;
-sljit_uw typeoffset;
-#endif /* SUPPORT_UNICODE */
-
-/* Scanning the necessary info. */
-cc++;
-ccbegin = cc;
-compares = 0;
-
-if (cc[-1] & XCL_MAP)
- {
- min = 0;
- cc += 32 / sizeof(PCRE2_UCHAR);
- }
-
-while (*cc != XCL_END)
- {
- compares++;
- if (*cc == XCL_SINGLE)
- {
- cc ++;
- GETCHARINCTEST(c, cc);
- if (c > max) max = c;
- if (c < min) min = c;
-#ifdef SUPPORT_UNICODE
- unicode_status |= XCLASS_SAVE_CHAR;
-#endif /* SUPPORT_UNICODE */
- }
- else if (*cc == XCL_RANGE)
- {
- cc ++;
- GETCHARINCTEST(c, cc);
- if (c < min) min = c;
- GETCHARINCTEST(c, cc);
- if (c > max) max = c;
-#ifdef SUPPORT_UNICODE
- unicode_status |= XCLASS_SAVE_CHAR;
-#endif /* SUPPORT_UNICODE */
- }
-#ifdef SUPPORT_UNICODE
- else
- {
- SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
- cc++;
- if (*cc == PT_CLIST && cc[-1] == XCL_PROP)
- {
- other_cases = PRIV(ucd_caseless_sets) + cc[1];
- while (*other_cases != NOTACHAR)
- {
- if (*other_cases > max) max = *other_cases;
- if (*other_cases < min) min = *other_cases;
- other_cases++;
- }
- }
- else
- {
- max = READ_CHAR_MAX;
- min = 0;
- }
-
- switch(*cc)
- {
- case PT_ANY:
- /* Any either accepts everything or ignored. */
- if (cc[-1] == XCL_PROP)
- {
- compile_char1_matchingpath(common, OP_ALLANY, cc, backtracks, FALSE);
- if (list == backtracks)
- add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
- return;
- }
- break;
-
- case PT_LAMP:
- case PT_GC:
- case PT_PC:
- case PT_ALNUM:
- unicode_status |= XCLASS_HAS_TYPE;
- break;
-
- case PT_SCX:
- unicode_status |= XCLASS_HAS_SCRIPT_EXTENSION;
- if (cc[-1] == XCL_NOTPROP)
- {
- unicode_status |= XCLASS_SCRIPT_EXTENSION_NOTPROP;
- break;
- }
- compares++;
- /* Fall through */
-
- case PT_SC:
- unicode_status |= XCLASS_HAS_SCRIPT;
- break;
-
- case PT_SPACE:
- case PT_PXSPACE:
- case PT_WORD:
- case PT_PXGRAPH:
- case PT_PXPRINT:
- case PT_PXPUNCT:
- unicode_status |= XCLASS_SAVE_CHAR | XCLASS_HAS_TYPE;
- break;
-
- case PT_CLIST:
- case PT_UCNC:
- unicode_status |= XCLASS_SAVE_CHAR;
- break;
-
- case PT_BOOL:
- unicode_status |= XCLASS_HAS_BOOL;
- break;
-
- case PT_BIDICL:
- unicode_status |= XCLASS_HAS_BIDICL;
- break;
-
- default:
- SLJIT_UNREACHABLE();
- break;
- }
- cc += 2;
- }
-#endif /* SUPPORT_UNICODE */
- }
-SLJIT_ASSERT(compares > 0);
-
-/* We are not necessary in utf mode even in 8 bit mode. */
-cc = ccbegin;
-if ((cc[-1] & XCL_NOT) != 0)
- read_char(common, min, max, backtracks, READ_CHAR_UPDATE_STR_PTR);
-else
- {
-#ifdef SUPPORT_UNICODE
- read_char(common, min, max, (unicode_status & XCLASS_NEEDS_UCD) ? backtracks : NULL, 0);
-#else /* !SUPPORT_UNICODE */
- read_char(common, min, max, NULL, 0);
-#endif /* SUPPORT_UNICODE */
- }
-
-if ((cc[-1] & XCL_HASPROP) == 0)
- {
- if ((cc[-1] & XCL_MAP) != 0)
- {
- jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
- if (!optimize_class(common, (const sljit_u8 *)cc, (((const sljit_u8 *)cc)[31] & 0x80) != 0, TRUE, &found))
- {
- OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
- OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
- OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
- OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
- OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP2, 0);
- add_jump(compiler, &found, JUMP(SLJIT_NOT_ZERO));
- }
-
- add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
- JUMPHERE(jump);
-
- cc += 32 / sizeof(PCRE2_UCHAR);
- }
- else
- {
- OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, min);
- add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, max - min));
- }
- }
-else if ((cc[-1] & XCL_MAP) != 0)
- {
- OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
-#ifdef SUPPORT_UNICODE
- unicode_status |= XCLASS_CHAR_SAVED;
-#endif /* SUPPORT_UNICODE */
- if (!optimize_class(common, (const sljit_u8 *)cc, FALSE, TRUE, list))
- {
-#if PCRE2_CODE_UNIT_WIDTH == 8
- jump = NULL;
- if (common->utf)
-#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
- jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
-
- OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
- OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
- OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
- OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
- OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP2, 0);
- add_jump(compiler, list, JUMP(SLJIT_NOT_ZERO));
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
- if (common->utf)
-#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
- JUMPHERE(jump);
- }
-
- OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
- cc += 32 / sizeof(PCRE2_UCHAR);
- }
-
-#ifdef SUPPORT_UNICODE
-if (unicode_status & XCLASS_NEEDS_UCD)
- {
- if ((unicode_status & (XCLASS_SAVE_CHAR | XCLASS_CHAR_SAVED)) == XCLASS_SAVE_CHAR)
- OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
-
-#if PCRE2_CODE_UNIT_WIDTH == 32
- if (!common->utf)
- {
- jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, MAX_UTF_CODE_POINT + 1);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, UNASSIGNED_UTF_CHAR);
- JUMPHERE(jump);
- }
-#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */
-
- OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
- OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));
- OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
- OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
- OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 3);
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);
- OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
-
- ccbegin = cc;
-
- if (unicode_status & XCLASS_HAS_BIDICL)
- {
- OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, scriptx_bidiclass));
- OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BIDICLASS_SHIFT);
-
- while (*cc != XCL_END)
- {
- if (*cc == XCL_SINGLE)
- {
- cc ++;
- GETCHARINCTEST(c, cc);
- }
- else if (*cc == XCL_RANGE)
- {
- cc ++;
- GETCHARINCTEST(c, cc);
- GETCHARINCTEST(c, cc);
- }
- else
- {
- SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
- cc++;
- if (*cc == PT_BIDICL)
- {
- compares--;
- invertcmp = (compares == 0 && list != backtracks);
- if (cc[-1] == XCL_NOTPROP)
- invertcmp ^= 0x1;
- jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (int)cc[1]);
- add_jump(compiler, compares > 0 ? list : backtracks, jump);
- }
- cc += 2;
- }
- }
-
- cc = ccbegin;
- }
-
- if (unicode_status & XCLASS_HAS_BOOL)
- {
- OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, bprops));
- OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BPROPS_MASK);
- OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);
-
- while (*cc != XCL_END)
- {
- if (*cc == XCL_SINGLE)
- {
- cc ++;
- GETCHARINCTEST(c, cc);
- }
- else if (*cc == XCL_RANGE)
- {
- cc ++;
- GETCHARINCTEST(c, cc);
- GETCHARINCTEST(c, cc);
- }
- else
- {
- SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
- cc++;
- if (*cc == PT_BOOL)
- {
- compares--;
- invertcmp = (compares == 0 && list != backtracks);
- if (cc[-1] == XCL_NOTPROP)
- invertcmp ^= 0x1;
-
- OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), (sljit_sw)(PRIV(ucd_boolprop_sets) + (cc[1] >> 5)), SLJIT_IMM, (sljit_sw)1 << (cc[1] & 0x1f));
- add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp));
- }
- cc += 2;
- }
- }
-
- cc = ccbegin;
- }
-
- if (unicode_status & XCLASS_HAS_SCRIPT)
- {
- OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
-
- while (*cc != XCL_END)
- {
- if (*cc == XCL_SINGLE)
- {
- cc ++;
- GETCHARINCTEST(c, cc);
- }
- else if (*cc == XCL_RANGE)
- {
- cc ++;
- GETCHARINCTEST(c, cc);
- GETCHARINCTEST(c, cc);
- }
- else
- {
- SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
- cc++;
- switch (*cc)
- {
- case PT_SCX:
- if (cc[-1] == XCL_NOTPROP)
- break;
- /* Fall through */
-
- case PT_SC:
- compares--;
- invertcmp = (compares == 0 && list != backtracks);
- if (cc[-1] == XCL_NOTPROP)
- invertcmp ^= 0x1;
-
- add_jump(compiler, compares > 0 ? list : backtracks, CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (int)cc[1]));
- }
- cc += 2;
- }
- }
-
- cc = ccbegin;
- }
-
- if (unicode_status & XCLASS_HAS_SCRIPT_EXTENSION)
- {
- OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, scriptx_bidiclass));
- OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_SCRIPTX_MASK);
- OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);
-
- if (unicode_status & XCLASS_SCRIPT_EXTENSION_NOTPROP)
- {
- if (unicode_status & XCLASS_HAS_TYPE)
- {
- if (unicode_status & XCLASS_SAVE_CHAR)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, TMP2, 0);
- unicode_status |= XCLASS_SCRIPT_EXTENSION_RESTORE_LOCALS0;
- }
- else
- {
- OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP2, 0);
- unicode_status |= XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR;
- }
- }
- OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
- }
-
- while (*cc != XCL_END)
- {
- if (*cc == XCL_SINGLE)
- {
- cc ++;
- GETCHARINCTEST(c, cc);
- }
- else if (*cc == XCL_RANGE)
- {
- cc ++;
- GETCHARINCTEST(c, cc);
- GETCHARINCTEST(c, cc);
- }
- else
- {
- SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
- cc++;
- if (*cc == PT_SCX)
- {
- compares--;
- invertcmp = (compares == 0 && list != backtracks);
-
- jump = NULL;
- if (cc[-1] == XCL_NOTPROP)
- {
- jump = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, (int)cc[1]);
- if (invertcmp)
- {
- add_jump(compiler, backtracks, jump);
- jump = NULL;
- }
- invertcmp ^= 0x1;
- }
-
- OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), (sljit_sw)(PRIV(ucd_script_sets) + (cc[1] >> 5)), SLJIT_IMM, (sljit_sw)1 << (cc[1] & 0x1f));
- add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp));
-
- if (jump != NULL)
- JUMPHERE(jump);
- }
- cc += 2;
- }
- }
-
- if (unicode_status & XCLASS_SCRIPT_EXTENSION_RESTORE_LOCALS0)
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
- else if (unicode_status & XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR)
- OP1(SLJIT_MOV, TMP2, 0, RETURN_ADDR, 0);
- cc = ccbegin;
- }
-
- if (unicode_status & XCLASS_SAVE_CHAR)
- OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
-
- if (unicode_status & XCLASS_HAS_TYPE)
- {
- if (unicode_status & XCLASS_SAVE_CHAR)
- typereg = RETURN_ADDR;
-
- OP1(SLJIT_MOV_U8, typereg, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
- }
- }
-#endif /* SUPPORT_UNICODE */
-
-/* Generating code. */
-charoffset = 0;
-numberofcmps = 0;
-#ifdef SUPPORT_UNICODE
-typeoffset = 0;
-#endif /* SUPPORT_UNICODE */
-
-while (*cc != XCL_END)
- {
- compares--;
- invertcmp = (compares == 0 && list != backtracks);
- jump = NULL;
-
- if (*cc == XCL_SINGLE)
- {
- cc ++;
- GETCHARINCTEST(c, cc);
-
- if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
- {
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
- OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
- numberofcmps++;
- }
- else if (numberofcmps > 0)
- {
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
- OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);
- jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
- numberofcmps = 0;
- }
- else
- {
- jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
- numberofcmps = 0;
- }
- }
- else if (*cc == XCL_RANGE)
- {
- cc ++;
- GETCHARINCTEST(c, cc);
- SET_CHAR_OFFSET(c);
- GETCHARINCTEST(c, cc);
-
- if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
- {
- OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
- OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
- numberofcmps++;
- }
- else if (numberofcmps > 0)
- {
- OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
- OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL);
- jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
- numberofcmps = 0;
- }
- else
- {
- jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
- numberofcmps = 0;
- }
- }
-#ifdef SUPPORT_UNICODE
- else
- {
- SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
- if (*cc == XCL_NOTPROP)
- invertcmp ^= 0x1;
- cc++;
- switch(*cc)
- {
- case PT_ANY:
- if (!invertcmp)
- jump = JUMP(SLJIT_JUMP);
- break;
-
- case PT_LAMP:
- OP2U(SLJIT_SUB | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
- OP2U(SLJIT_SUB | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);
- OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
- OP2U(SLJIT_SUB | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);
- OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);
- jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
- break;
-
- case PT_GC:
- c = PRIV(ucp_typerange)[(int)cc[1] * 2];
- SET_TYPE_OFFSET(c);
- jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c);
- break;
-
- case PT_PC:
- jump = CMP(SLJIT_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset);
- break;
-
- case PT_SC:
- case PT_SCX:
- case PT_BOOL:
- case PT_BIDICL:
- compares++;
- /* Do nothing. */
- break;
-
- case PT_SPACE:
- case PT_PXSPACE:
- SET_CHAR_OFFSET(9);
- OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xd - 0x9);
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
-
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x85 - 0x9);
- OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
-
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x180e - 0x9);
- OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
-
- SET_TYPE_OFFSET(ucp_Zl);
- OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
- OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL);
- jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
- break;
-
- case PT_WORD:
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_UNDERSCORE - charoffset));
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
- /* Fall through. */
-
- case PT_ALNUM:
- SET_TYPE_OFFSET(ucp_Ll);
- OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
- OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
- SET_TYPE_OFFSET(ucp_Nd);
- OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);
- OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL);
- jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
- break;
-
- case PT_CLIST:
- other_cases = PRIV(ucd_caseless_sets) + cc[1];
-
- /* At least three characters are required.
- Otherwise this case would be handled by the normal code path. */
- SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR);
- SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]);
-
- /* Optimizing character pairs, if their difference is power of 2. */
- if (is_powerof2(other_cases[1] ^ other_cases[0]))
- {
- if (charoffset == 0)
- OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
- else
- {
- OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);
- OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
- }
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, other_cases[1]);
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
- other_cases += 2;
- }
- else if (is_powerof2(other_cases[2] ^ other_cases[1]))
- {
- if (charoffset == 0)
- OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]);
- else
- {
- OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);
- OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
- }
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, other_cases[2]);
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
-
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[0] - charoffset));
- OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_Z : 0), TMP2, 0, SLJIT_EQUAL);
-
- other_cases += 3;
- }
- else
- {
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
- }
-
- while (*other_cases != NOTACHAR)
- {
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
- OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_Z : 0), TMP2, 0, SLJIT_EQUAL);
- }
- jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
- break;
-
- case PT_UCNC:
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset));
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset));
- OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset));
- OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
-
- SET_CHAR_OFFSET(0xa0);
- OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset));
- OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
- SET_CHAR_OFFSET(0);
- OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xe000 - 0);
- OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_GREATER_EQUAL);
- jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
- break;
-
- case PT_PXGRAPH:
- /* C and Z groups are the farthest two groups. */
- SET_TYPE_OFFSET(ucp_Ll);
- OP2U(SLJIT_SUB | SLJIT_SET_GREATER, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER);
-
- jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
-
- /* In case of ucp_Cf, we overwrite the result. */
- SET_CHAR_OFFSET(0x2066);
- OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
-
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
- OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
-
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066);
- OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
-
- JUMPHERE(jump);
- jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
- break;
-
- case PT_PXPRINT:
- /* C and Z groups are the farthest two groups. */
- SET_TYPE_OFFSET(ucp_Ll);
- OP2U(SLJIT_SUB | SLJIT_SET_GREATER, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER);
-
- OP2U(SLJIT_SUB | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll);
- OP_FLAGS(SLJIT_AND, TMP2, 0, SLJIT_NOT_EQUAL);
-
- jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
-
- /* In case of ucp_Cf, we overwrite the result. */
- SET_CHAR_OFFSET(0x2066);
- OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
-
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
- OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
-
- JUMPHERE(jump);
- jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
- break;
-
- case PT_PXPUNCT:
- SET_TYPE_OFFSET(ucp_Sc);
- OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc);
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
-
- SET_CHAR_OFFSET(0);
- OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x7f);
- OP_FLAGS(SLJIT_AND, TMP2, 0, SLJIT_LESS_EQUAL);
-
- SET_TYPE_OFFSET(ucp_Pc);
- OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc);
- OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL);
- jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
- break;
-
- default:
- SLJIT_UNREACHABLE();
- break;
- }
- cc += 2;
- }
-#endif /* SUPPORT_UNICODE */
-
- if (jump != NULL)
- add_jump(compiler, compares > 0 ? list : backtracks, jump);
- }
-
-if (found != NULL)
- set_jumps(found, LABEL());
-}
-
-#undef SET_TYPE_OFFSET
-#undef SET_CHAR_OFFSET
-
-#endif
-
-static PCRE2_SPTR compile_simple_assertion_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks)
-{
-DEFINE_COMPILER;
-int length;
-struct sljit_jump *jump[4];
-#ifdef SUPPORT_UNICODE
-struct sljit_label *label;
-#endif /* SUPPORT_UNICODE */
-
-switch(type)
- {
- case OP_SOD:
- if (HAS_VIRTUAL_REGISTERS)
- {
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
- }
- else
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
- return cc;
-
- case OP_SOM:
- if (HAS_VIRTUAL_REGISTERS)
- {
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
- }
- else
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
- return cc;
-
- case OP_NOT_WORD_BOUNDARY:
- case OP_WORD_BOUNDARY:
- add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
-#ifdef SUPPORT_UNICODE
- if (common->invalid_utf)
- {
- add_jump(compiler, backtracks, CMP((type == OP_NOT_WORD_BOUNDARY) ? SLJIT_NOT_EQUAL : SLJIT_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, 0));
- return cc;
- }
-#endif /* SUPPORT_UNICODE */
- sljit_set_current_flags(compiler, SLJIT_SET_Z);
- add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_NOT_ZERO : SLJIT_ZERO));
- return cc;
-
- case OP_EODN:
- /* Requires rather complex checks. */
- jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- if (common->nltype == NLTYPE_FIXED && common->newline > 255)
- {
- OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
- if (common->mode == PCRE2_JIT_COMPLETE)
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0));
- else
- {
- jump[1] = CMP(SLJIT_EQUAL, TMP2, 0, STR_END, 0);
- OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, STR_END, 0);
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS);
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
- OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_NOT_EQUAL);
- add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL));
- check_partial(common, TRUE);
- add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
- JUMPHERE(jump[1]);
- }
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
- }
- else if (common->nltype == NLTYPE_FIXED)
- {
- OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0));
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
- }
- else
- {
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
- jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
- OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
- OP2U(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_GREATER, TMP2, 0, STR_END, 0);
- jump[2] = JUMP(SLJIT_GREATER);
- add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL) /* LESS */);
- /* Equal. */
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
- jump[3] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
- add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
-
- JUMPHERE(jump[1]);
- if (common->nltype == NLTYPE_ANYCRLF)
- {
- OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, STR_END, 0));
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
- }
- else
- {
- OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
- read_char(common, common->nlmin, common->nlmax, backtracks, READ_CHAR_UPDATE_STR_PTR);
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
- add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
- sljit_set_current_flags(compiler, SLJIT_SET_Z);
- add_jump(compiler, backtracks, JUMP(SLJIT_ZERO));
- OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
- }
- JUMPHERE(jump[2]);
- JUMPHERE(jump[3]);
- }
- JUMPHERE(jump[0]);
- if (common->mode != PCRE2_JIT_COMPLETE)
- check_partial(common, TRUE);
- return cc;
-
- case OP_EOD:
- add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));
- if (common->mode != PCRE2_JIT_COMPLETE)
- check_partial(common, TRUE);
- return cc;
-
- case OP_DOLL:
- if (HAS_VIRTUAL_REGISTERS)
- {
- OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
- OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
- }
- else
- OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
- add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
-
- if (!common->endonly)
- compile_simple_assertion_matchingpath(common, OP_EODN, cc, backtracks);
- else
- {
- add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));
- check_partial(common, FALSE);
- }
- return cc;
-
- case OP_DOLLM:
- jump[1] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
- if (HAS_VIRTUAL_REGISTERS)
- {
- OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
- OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
- }
- else
- OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
- add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
- check_partial(common, FALSE);
- jump[0] = JUMP(SLJIT_JUMP);
- JUMPHERE(jump[1]);
-
- if (common->nltype == NLTYPE_FIXED && common->newline > 255)
- {
- OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
- if (common->mode == PCRE2_JIT_COMPLETE)
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0));
- else
- {
- jump[1] = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0);
- /* STR_PTR = STR_END - IN_UCHARS(1) */
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
- check_partial(common, TRUE);
- add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
- JUMPHERE(jump[1]);
- }
-
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
- }
- else
- {
- peek_char(common, common->nlmax, TMP3, 0, NULL);
- check_newlinechar(common, common->nltype, backtracks, FALSE);
- }
- JUMPHERE(jump[0]);
- return cc;
-
- case OP_CIRC:
- if (HAS_VIRTUAL_REGISTERS)
- {
- OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0));
- OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
- add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
- }
- else
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0));
- OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
- add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
- }
- return cc;
-
- case OP_CIRCM:
- /* TMP2 might be used by peek_char_back. */
- if (HAS_VIRTUAL_REGISTERS)
- {
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
- jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0);
- OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
- }
- else
- {
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
- jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0);
- OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
- }
- add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
- jump[0] = JUMP(SLJIT_JUMP);
- JUMPHERE(jump[1]);
-
- if (!common->alt_circumflex)
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
-
- if (common->nltype == NLTYPE_FIXED && common->newline > 255)
- {
- OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
- add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, TMP2, 0));
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
- }
- else
- {
- peek_char_back(common, common->nlmax, backtracks);
- check_newlinechar(common, common->nltype, backtracks, FALSE);
- }
- JUMPHERE(jump[0]);
- return cc;
-
- case OP_REVERSE:
- length = GET(cc, 0);
- if (length == 0)
- return cc + LINK_SIZE;
- if (HAS_VIRTUAL_REGISTERS)
- {
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
- }
- else
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
-#ifdef SUPPORT_UNICODE
- if (common->utf)
- {
- OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, length);
- label = LABEL();
- add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0));
- move_back(common, backtracks, FALSE);
- OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1);
- JUMPTO(SLJIT_NOT_ZERO, label);
- }
- else
-#endif
- {
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
- add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0));
- }
- check_start_used_ptr(common);
- return cc + LINK_SIZE;
- }
-SLJIT_UNREACHABLE();
-return cc;
-}
-
-#ifdef SUPPORT_UNICODE
-
-#if PCRE2_CODE_UNIT_WIDTH != 32
-
-static PCRE2_SPTR SLJIT_FUNC do_extuni_utf(jit_arguments *args, PCRE2_SPTR cc)
-{
-PCRE2_SPTR start_subject = args->begin;
-PCRE2_SPTR end_subject = args->end;
-int lgb, rgb, ricount;
-PCRE2_SPTR prevcc, endcc, bptr;
-BOOL first = TRUE;
-uint32_t c;
-
-prevcc = cc;
-endcc = NULL;
-do
- {
- GETCHARINC(c, cc);
- rgb = UCD_GRAPHBREAK(c);
-
- if (first)
- {
- lgb = rgb;
- endcc = cc;
- first = FALSE;
- continue;
- }
-
- if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0)
- break;
-
- /* Not breaking between Regional Indicators is allowed only if there
- are an even number of preceding RIs. */
-
- if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator)
- {
- ricount = 0;
- bptr = prevcc;
-
- /* bptr is pointing to the left-hand character */
- while (bptr > start_subject)
- {
- bptr--;
- BACKCHAR(bptr);
- GETCHAR(c, bptr);
-
- if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator)
- break;
-
- ricount++;
- }
-
- if ((ricount & 1) != 0) break; /* Grapheme break required */
- }
-
- /* If Extend or ZWJ follows Extended_Pictographic, do not update lgb; this
- allows any number of them before a following Extended_Pictographic. */
-
- if ((rgb != ucp_gbExtend && rgb != ucp_gbZWJ) ||
- lgb != ucp_gbExtended_Pictographic)
- lgb = rgb;
-
- prevcc = endcc;
- endcc = cc;
- }
-while (cc < end_subject);
-
-return endcc;
-}
-
-#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */
-
-static PCRE2_SPTR SLJIT_FUNC do_extuni_utf_invalid(jit_arguments *args, PCRE2_SPTR cc)
-{
-PCRE2_SPTR start_subject = args->begin;
-PCRE2_SPTR end_subject = args->end;
-int lgb, rgb, ricount;
-PCRE2_SPTR prevcc, endcc, bptr;
-BOOL first = TRUE;
-uint32_t c;
-
-prevcc = cc;
-endcc = NULL;
-do
- {
- GETCHARINC_INVALID(c, cc, end_subject, break);
- rgb = UCD_GRAPHBREAK(c);
-
- if (first)
- {
- lgb = rgb;
- endcc = cc;
- first = FALSE;
- continue;
- }
-
- if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0)
- break;
-
- /* Not breaking between Regional Indicators is allowed only if there
- are an even number of preceding RIs. */
-
- if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator)
- {
- ricount = 0;
- bptr = prevcc;
-
- /* bptr is pointing to the left-hand character */
- while (bptr > start_subject)
- {
- GETCHARBACK_INVALID(c, bptr, start_subject, break);
-
- if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator)
- break;
-
- ricount++;
- }
-
- if ((ricount & 1) != 0)
- break; /* Grapheme break required */
- }
-
- /* If Extend or ZWJ follows Extended_Pictographic, do not update lgb; this
- allows any number of them before a following Extended_Pictographic. */
-
- if ((rgb != ucp_gbExtend && rgb != ucp_gbZWJ) ||
- lgb != ucp_gbExtended_Pictographic)
- lgb = rgb;
-
- prevcc = endcc;
- endcc = cc;
- }
-while (cc < end_subject);
-
-return endcc;
-}
-
-static PCRE2_SPTR SLJIT_FUNC do_extuni_no_utf(jit_arguments *args, PCRE2_SPTR cc)
-{
-PCRE2_SPTR start_subject = args->begin;
-PCRE2_SPTR end_subject = args->end;
-int lgb, rgb, ricount;
-PCRE2_SPTR bptr;
-uint32_t c;
-
-/* Patch by PH */
-/* GETCHARINC(c, cc); */
-c = *cc++;
-
-#if PCRE2_CODE_UNIT_WIDTH == 32
-if (c >= 0x110000)
- return NULL;
-#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */
-lgb = UCD_GRAPHBREAK(c);
-
-while (cc < end_subject)
- {
- c = *cc;
-#if PCRE2_CODE_UNIT_WIDTH == 32
- if (c >= 0x110000)
- break;
-#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */
- rgb = UCD_GRAPHBREAK(c);
-
- if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0)
- break;
-
- /* Not breaking between Regional Indicators is allowed only if there
- are an even number of preceding RIs. */
-
- if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator)
- {
- ricount = 0;
- bptr = cc - 1;
-
- /* bptr is pointing to the left-hand character */
- while (bptr > start_subject)
- {
- bptr--;
- c = *bptr;
-#if PCRE2_CODE_UNIT_WIDTH == 32
- if (c >= 0x110000)
- break;
-#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */
-
- if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator) break;
-
- ricount++;
- }
-
- if ((ricount & 1) != 0)
- break; /* Grapheme break required */
- }
-
- /* If Extend or ZWJ follows Extended_Pictographic, do not update lgb; this
- allows any number of them before a following Extended_Pictographic. */
-
- if ((rgb != ucp_gbExtend && rgb != ucp_gbZWJ) ||
- lgb != ucp_gbExtended_Pictographic)
- lgb = rgb;
-
- cc++;
- }
-
-return cc;
-}
-
-#endif /* SUPPORT_UNICODE */
-
-static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr)
-{
-DEFINE_COMPILER;
-int length;
-unsigned int c, oc, bit;
-compare_context context;
-struct sljit_jump *jump[3];
-jump_list *end_list;
-#ifdef SUPPORT_UNICODE
-PCRE2_UCHAR propdata[5];
-#endif /* SUPPORT_UNICODE */
-
-switch(type)
- {
- case OP_NOT_DIGIT:
- case OP_DIGIT:
- /* Digits are usually 0-9, so it is worth to optimize them. */
- if (check_str_ptr)
- detect_partial_match(common, backtracks);
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
- if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_digit, FALSE))
- read_char7_type(common, backtracks, type == OP_NOT_DIGIT);
- else
-#endif
- read_char8_type(common, backtracks, type == OP_NOT_DIGIT);
- /* Flip the starting bit in the negative case. */
- OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, ctype_digit);
- add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_ZERO : SLJIT_NOT_ZERO));
- return cc;
-
- case OP_NOT_WHITESPACE:
- case OP_WHITESPACE:
- if (check_str_ptr)
- detect_partial_match(common, backtracks);
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
- if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_space, FALSE))
- read_char7_type(common, backtracks, type == OP_NOT_WHITESPACE);
- else
-#endif
- read_char8_type(common, backtracks, type == OP_NOT_WHITESPACE);
- OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, ctype_space);
- add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_ZERO : SLJIT_NOT_ZERO));
- return cc;
-
- case OP_NOT_WORDCHAR:
- case OP_WORDCHAR:
- if (check_str_ptr)
- detect_partial_match(common, backtracks);
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
- if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_word, FALSE))
- read_char7_type(common, backtracks, type == OP_NOT_WORDCHAR);
- else
-#endif
- read_char8_type(common, backtracks, type == OP_NOT_WORDCHAR);
- OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, ctype_word);
- add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_ZERO : SLJIT_NOT_ZERO));
- return cc;
-
- case OP_ANY:
- if (check_str_ptr)
- detect_partial_match(common, backtracks);
- read_char(common, common->nlmin, common->nlmax, backtracks, READ_CHAR_UPDATE_STR_PTR);
- if (common->nltype == NLTYPE_FIXED && common->newline > 255)
- {
- jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
- end_list = NULL;
- if (common->mode != PCRE2_JIT_PARTIAL_HARD)
- add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
- else
- check_str_end(common, &end_list);
-
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
- set_jumps(end_list, LABEL());
- JUMPHERE(jump[0]);
- }
- else
- check_newlinechar(common, common->nltype, backtracks, TRUE);
- return cc;
-
- case OP_ALLANY:
- if (check_str_ptr)
- detect_partial_match(common, backtracks);
-#ifdef SUPPORT_UNICODE
- if (common->utf)
- {
- if (common->invalid_utf)
- {
- read_char(common, 0, READ_CHAR_MAX, backtracks, READ_CHAR_UPDATE_STR_PTR);
- return cc;
- }
-
-#if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-#if PCRE2_CODE_UNIT_WIDTH == 8
- jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
- OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
-#elif PCRE2_CODE_UNIT_WIDTH == 16
- jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
- OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0xd800);
- OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);
- OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
-#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
- JUMPHERE(jump[0]);
- return cc;
-#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */
- }
-#endif /* SUPPORT_UNICODE */
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- return cc;
-
- case OP_ANYBYTE:
- if (check_str_ptr)
- detect_partial_match(common, backtracks);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- return cc;
-
-#ifdef SUPPORT_UNICODE
- case OP_NOTPROP:
- case OP_PROP:
- propdata[0] = XCL_HASPROP;
- propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP;
- propdata[2] = cc[0];
- propdata[3] = cc[1];
- propdata[4] = XCL_END;
- if (check_str_ptr)
- detect_partial_match(common, backtracks);
- compile_xclass_matchingpath(common, propdata, backtracks);
- return cc + 2;
-#endif
-
- case OP_ANYNL:
- if (check_str_ptr)
- detect_partial_match(common, backtracks);
- read_char(common, common->bsr_nlmin, common->bsr_nlmax, NULL, 0);
- jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
- /* We don't need to handle soft partial matching case. */
- end_list = NULL;
- if (common->mode != PCRE2_JIT_PARTIAL_HARD)
- add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
- else
- check_str_end(common, &end_list);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
- jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- jump[2] = JUMP(SLJIT_JUMP);
- JUMPHERE(jump[0]);
- check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
- set_jumps(end_list, LABEL());
- JUMPHERE(jump[1]);
- JUMPHERE(jump[2]);
- return cc;
-
- case OP_NOT_HSPACE:
- case OP_HSPACE:
- if (check_str_ptr)
- detect_partial_match(common, backtracks);
-
- if (type == OP_NOT_HSPACE)
- read_char(common, 0x9, 0x3000, backtracks, READ_CHAR_UPDATE_STR_PTR);
- else
- read_char(common, 0x9, 0x3000, NULL, 0);
-
- add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
- sljit_set_current_flags(compiler, SLJIT_SET_Z);
- add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO));
- return cc;
-
- case OP_NOT_VSPACE:
- case OP_VSPACE:
- if (check_str_ptr)
- detect_partial_match(common, backtracks);
-
- if (type == OP_NOT_VSPACE)
- read_char(common, 0xa, 0x2029, backtracks, READ_CHAR_UPDATE_STR_PTR);
- else
- read_char(common, 0xa, 0x2029, NULL, 0);
-
- add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
- sljit_set_current_flags(compiler, SLJIT_SET_Z);
- add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO));
- return cc;
-
-#ifdef SUPPORT_UNICODE
- case OP_EXTUNI:
- if (check_str_ptr)
- detect_partial_match(common, backtracks);
-
- SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
- OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);
-
-#if PCRE2_CODE_UNIT_WIDTH != 32
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM,
- common->utf ? (common->invalid_utf ? SLJIT_FUNC_ADDR(do_extuni_utf_invalid) : SLJIT_FUNC_ADDR(do_extuni_utf)) : SLJIT_FUNC_ADDR(do_extuni_no_utf));
- if (common->invalid_utf)
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
-#else
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM,
- common->invalid_utf ? SLJIT_FUNC_ADDR(do_extuni_utf_invalid) : SLJIT_FUNC_ADDR(do_extuni_no_utf));
- if (!common->utf || common->invalid_utf)
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
-#endif
-
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
-
- if (common->mode == PCRE2_JIT_PARTIAL_HARD)
- {
- jump[0] = CMP(SLJIT_LESS, SLJIT_RETURN_REG, 0, STR_END, 0);
- /* Since we successfully read a char above, partial matching must occure. */
- check_partial(common, TRUE);
- JUMPHERE(jump[0]);
- }
- return cc;
-#endif
-
- case OP_CHAR:
- case OP_CHARI:
- length = 1;
-#ifdef SUPPORT_UNICODE
- if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
-#endif
-
- if (check_str_ptr && common->mode != PCRE2_JIT_COMPLETE)
- detect_partial_match(common, backtracks);
-
- if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)
- {
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
- if (length > 1 || (check_str_ptr && common->mode == PCRE2_JIT_COMPLETE))
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0));
-
- context.length = IN_UCHARS(length);
- context.sourcereg = -1;
-#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
- context.ucharptr = 0;
-#endif
- return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);
- }
-
-#ifdef SUPPORT_UNICODE
- if (common->utf)
- {
- GETCHAR(c, cc);
- }
- else
-#endif
- c = *cc;
-
- SLJIT_ASSERT(type == OP_CHARI && char_has_othercase(common, cc));
-
- if (check_str_ptr && common->mode == PCRE2_JIT_COMPLETE)
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
-
- oc = char_othercase(common, c);
- read_char(common, c < oc ? c : oc, c > oc ? c : oc, NULL, 0);
-
- SLJIT_ASSERT(!is_powerof2(c ^ oc));
-
- if (sljit_has_cpu_feature(SLJIT_HAS_CMOV))
- {
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, oc);
- CMOV(SLJIT_EQUAL, TMP1, SLJIT_IMM, c);
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
- }
- else
- {
- jump[0] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c);
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc));
- JUMPHERE(jump[0]);
- }
- return cc + length;
-
- case OP_NOT:
- case OP_NOTI:
- if (check_str_ptr)
- detect_partial_match(common, backtracks);
-
- length = 1;
-#ifdef SUPPORT_UNICODE
- if (common->utf)
- {
-#if PCRE2_CODE_UNIT_WIDTH == 8
- c = *cc;
- if (c < 128 && !common->invalid_utf)
- {
- OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
- if (type == OP_NOT || !char_has_othercase(common, cc))
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));
- else
- {
- /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */
- OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));
- }
- /* Skip the variable-length character. */
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
- JUMPHERE(jump[0]);
- return cc + 1;
- }
- else
-#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
- {
- GETCHARLEN(c, cc, length);
- }
- }
- else
-#endif /* SUPPORT_UNICODE */
- c = *cc;
-
- if (type == OP_NOT || !char_has_othercase(common, cc))
- {
- read_char(common, c, c, backtracks, READ_CHAR_UPDATE_STR_PTR);
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));
- }
- else
- {
- oc = char_othercase(common, c);
- read_char(common, c < oc ? c : oc, c > oc ? c : oc, backtracks, READ_CHAR_UPDATE_STR_PTR);
- bit = c ^ oc;
- if (is_powerof2(bit))
- {
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
- }
- else
- {
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, oc));
- }
- }
- return cc + length;
-
- case OP_CLASS:
- case OP_NCLASS:
- if (check_str_ptr)
- detect_partial_match(common, backtracks);
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
- bit = (common->utf && is_char7_bitset((const sljit_u8 *)cc, type == OP_NCLASS)) ? 127 : 255;
- if (type == OP_NCLASS)
- read_char(common, 0, bit, backtracks, READ_CHAR_UPDATE_STR_PTR);
- else
- read_char(common, 0, bit, NULL, 0);
-#else
- if (type == OP_NCLASS)
- read_char(common, 0, 255, backtracks, READ_CHAR_UPDATE_STR_PTR);
- else
- read_char(common, 0, 255, NULL, 0);
-#endif
-
- if (optimize_class(common, (const sljit_u8 *)cc, type == OP_NCLASS, FALSE, backtracks))
- return cc + 32 / sizeof(PCRE2_UCHAR);
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
- jump[0] = NULL;
- if (common->utf)
- {
- jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, bit);
- if (type == OP_CLASS)
- {
- add_jump(compiler, backtracks, jump[0]);
- jump[0] = NULL;
- }
- }
-#elif PCRE2_CODE_UNIT_WIDTH != 8
- jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
- if (type == OP_CLASS)
- {
- add_jump(compiler, backtracks, jump[0]);
- jump[0] = NULL;
- }
-#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */
-
- OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
- OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
- OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
- OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
- OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP2, 0);
- add_jump(compiler, backtracks, JUMP(SLJIT_ZERO));
-
-#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
- if (jump[0] != NULL)
- JUMPHERE(jump[0]);
-#endif
- return cc + 32 / sizeof(PCRE2_UCHAR);
-
-#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
- case OP_XCLASS:
- if (check_str_ptr)
- detect_partial_match(common, backtracks);
- compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
- return cc + GET(cc, 0) - 1;
-#endif
- }
-SLJIT_UNREACHABLE();
-return cc;
-}
-
-static SLJIT_INLINE PCRE2_SPTR compile_charn_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, jump_list **backtracks)
-{
-/* This function consumes at least one input character. */
-/* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
-DEFINE_COMPILER;
-PCRE2_SPTR ccbegin = cc;
-compare_context context;
-int size;
-
-context.length = 0;
-do
- {
- if (cc >= ccend)
- break;
-
- if (*cc == OP_CHAR)
- {
- size = 1;
-#ifdef SUPPORT_UNICODE
- if (common->utf && HAS_EXTRALEN(cc[1]))
- size += GET_EXTRALEN(cc[1]);
-#endif
- }
- else if (*cc == OP_CHARI)
- {
- size = 1;
-#ifdef SUPPORT_UNICODE
- if (common->utf)
- {
- if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
- size = 0;
- else if (HAS_EXTRALEN(cc[1]))
- size += GET_EXTRALEN(cc[1]);
- }
- else
-#endif
- if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
- size = 0;
- }
- else
- size = 0;
-
- cc += 1 + size;
- context.length += IN_UCHARS(size);
- }
-while (size > 0 && context.length <= 128);
-
-cc = ccbegin;
-if (context.length > 0)
- {
- /* We have a fixed-length byte sequence. */
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0));
-
- context.sourcereg = -1;
-#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
- context.ucharptr = 0;
-#endif
- do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0);
- return cc;
- }
-
-/* A non-fixed length character will be checked if length == 0. */
-return compile_char1_matchingpath(common, *cc, cc + 1, backtracks, TRUE);
-}
-
-/* Forward definitions. */
-static void compile_matchingpath(compiler_common *, PCRE2_SPTR, PCRE2_SPTR, backtrack_common *);
-static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
-
-#define PUSH_BACKTRACK(size, ccstart, error) \
- do \
- { \
- backtrack = sljit_alloc_memory(compiler, (size)); \
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
- return error; \
- memset(backtrack, 0, size); \
- backtrack->prev = parent->top; \
- backtrack->cc = (ccstart); \
- parent->top = backtrack; \
- } \
- while (0)
-
-#define PUSH_BACKTRACK_NOVALUE(size, ccstart) \
- do \
- { \
- backtrack = sljit_alloc_memory(compiler, (size)); \
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
- return; \
- memset(backtrack, 0, size); \
- backtrack->prev = parent->top; \
- backtrack->cc = (ccstart); \
- parent->top = backtrack; \
- } \
- while (0)
-
-#define BACKTRACK_AS(type) ((type *)backtrack)
-
-static void compile_dnref_search(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks)
-{
-/* The OVECTOR offset goes to TMP2. */
-DEFINE_COMPILER;
-int count = GET2(cc, 1 + IMM2_SIZE);
-PCRE2_SPTR slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
-unsigned int offset;
-jump_list *found = NULL;
-
-SLJIT_ASSERT(*cc == OP_DNREF || *cc == OP_DNREFI);
-
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
-
-count--;
-while (count-- > 0)
- {
- offset = GET2(slot, 0) << 1;
- GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
- add_jump(compiler, &found, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0));
- slot += common->name_entry_size;
- }
-
-offset = GET2(slot, 0) << 1;
-GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
-if (backtracks != NULL && !common->unset_backref)
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0));
-
-set_jumps(found, LABEL());
-}
-
-static void compile_ref_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
-{
-DEFINE_COMPILER;
-BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
-int offset = 0;
-struct sljit_jump *jump = NULL;
-struct sljit_jump *partial;
-struct sljit_jump *nopartial;
-#if defined SUPPORT_UNICODE
-struct sljit_label *loop;
-struct sljit_label *caseless_loop;
-jump_list *no_match = NULL;
-int source_reg = COUNT_MATCH;
-int source_end_reg = ARGUMENTS;
-int char1_reg = STACK_LIMIT;
-#endif /* SUPPORT_UNICODE */
-
-if (ref)
- {
- offset = GET2(cc, 1) << 1;
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
- /* OVECTOR(1) contains the "string begin - 1" constant. */
- if (withchecks && !common->unset_backref)
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));
- }
-else
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
-
-#if defined SUPPORT_UNICODE
-if (common->utf && *cc == OP_REFI)
- {
- SLJIT_ASSERT(common->iref_ptr != 0);
-
- if (ref)
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
- else
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
-
- if (withchecks && emptyfail)
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, TMP2, 0));
-
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->iref_ptr, source_reg, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw), source_end_reg, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw) * 2, char1_reg, 0);
-
- OP1(SLJIT_MOV, source_reg, 0, TMP1, 0);
- OP1(SLJIT_MOV, source_end_reg, 0, TMP2, 0);
-
- loop = LABEL();
- jump = CMP(SLJIT_GREATER_EQUAL, source_reg, 0, source_end_reg, 0);
- partial = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-
- /* Read original character. It must be a valid UTF character. */
- OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
- OP1(SLJIT_MOV, STR_PTR, 0, source_reg, 0);
-
- read_char(common, 0, READ_CHAR_MAX, NULL, READ_CHAR_UPDATE_STR_PTR | READ_CHAR_VALID_UTF);
-
- OP1(SLJIT_MOV, source_reg, 0, STR_PTR, 0);
- OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
- OP1(SLJIT_MOV, char1_reg, 0, TMP1, 0);
-
- /* Read second character. */
- read_char(common, 0, READ_CHAR_MAX, &no_match, READ_CHAR_UPDATE_STR_PTR);
-
- CMPTO(SLJIT_EQUAL, TMP1, 0, char1_reg, 0, loop);
-
- OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
-
- add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
-
- OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 2);
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
- OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
-
- OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records));
-
- OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(ucd_record, other_case));
- OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(ucd_record, caseset));
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP3, 0);
- CMPTO(SLJIT_EQUAL, TMP1, 0, char1_reg, 0, loop);
-
- add_jump(compiler, &no_match, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);
- OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_caseless_sets));
-
- caseless_loop = LABEL();
- OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(TMP2), 0);
- OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, sizeof(uint32_t));
- OP2U(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_LESS, TMP1, 0, char1_reg, 0);
- JUMPTO(SLJIT_EQUAL, loop);
- JUMPTO(SLJIT_LESS, caseless_loop);
-
- set_jumps(no_match, LABEL());
- if (common->mode == PCRE2_JIT_COMPLETE)
- JUMPHERE(partial);
-
- OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr);
- OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw));
- OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw) * 2);
- add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
-
- if (common->mode != PCRE2_JIT_COMPLETE)
- {
- JUMPHERE(partial);
- OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr);
- OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw));
- OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw) * 2);
-
- check_partial(common, FALSE);
- add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
- }
-
- JUMPHERE(jump);
- OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr);
- OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw));
- OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw) * 2);
- return;
- }
-else
-#endif /* SUPPORT_UNICODE */
- {
- if (ref)
- OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0);
- else
- OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
-
- if (withchecks)
- jump = JUMP(SLJIT_ZERO);
-
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
- partial = CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0);
- if (common->mode == PCRE2_JIT_COMPLETE)
- add_jump(compiler, backtracks, partial);
-
- add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
-
- if (common->mode != PCRE2_JIT_COMPLETE)
- {
- nopartial = JUMP(SLJIT_JUMP);
- JUMPHERE(partial);
- /* TMP2 -= STR_END - STR_PTR */
- OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
- OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
- partial = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0);
- OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
- add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
- add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
- JUMPHERE(partial);
- check_partial(common, FALSE);
- add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
- JUMPHERE(nopartial);
- }
- }
-
-if (jump != NULL)
- {
- if (emptyfail)
- add_jump(compiler, backtracks, jump);
- else
- JUMPHERE(jump);
- }
-}
-
-static SLJIT_INLINE PCRE2_SPTR compile_ref_iterator_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
-{
-DEFINE_COMPILER;
-BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
-backtrack_common *backtrack;
-PCRE2_UCHAR type;
-int offset = 0;
-struct sljit_label *label;
-struct sljit_jump *zerolength;
-struct sljit_jump *jump = NULL;
-PCRE2_SPTR ccbegin = cc;
-int min = 0, max = 0;
-BOOL minimize;
-
-PUSH_BACKTRACK(sizeof(ref_iterator_backtrack), cc, NULL);
-
-if (ref)
- offset = GET2(cc, 1) << 1;
-else
- cc += IMM2_SIZE;
-type = cc[1 + IMM2_SIZE];
-
-SLJIT_COMPILE_ASSERT((OP_CRSTAR & 0x1) == 0, crstar_opcode_must_be_even);
-minimize = (type & 0x1) != 0;
-switch(type)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- min = 0;
- max = 0;
- cc += 1 + IMM2_SIZE + 1;
- break;
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- min = 1;
- max = 0;
- cc += 1 + IMM2_SIZE + 1;
- break;
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- min = 0;
- max = 1;
- cc += 1 + IMM2_SIZE + 1;
- break;
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- min = GET2(cc, 1 + IMM2_SIZE + 1);
- max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
- cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
- break;
- default:
- SLJIT_UNREACHABLE();
- break;
- }
-
-if (!minimize)
- {
- if (min == 0)
- {
- allocate_stack(common, 2);
- if (ref)
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
- /* Temporary release of STR_PTR. */
- OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
- /* Handles both invalid and empty cases. Since the minimum repeat,
- is zero the invalid case is basically the same as an empty case. */
- if (ref)
- zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
- else
- {
- compile_dnref_search(common, ccbegin, NULL);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0);
- zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
- }
- /* Restore if not zero length. */
- OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
- }
- else
- {
- allocate_stack(common, 1);
- if (ref)
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- if (ref)
- {
- add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));
- zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
- }
- else
- {
- compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0);
- zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
- }
- }
-
- if (min > 1 || max > 1)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, 0);
-
- label = LABEL();
- if (!ref)
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1);
- compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
-
- if (min > 1 || max > 1)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0);
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0);
- if (min > 1)
- CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, label);
- if (max > 1)
- {
- jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max);
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- JUMPTO(SLJIT_JUMP, label);
- JUMPHERE(jump);
- }
- }
-
- if (max == 0)
- {
- /* Includes min > 1 case as well. */
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- JUMPTO(SLJIT_JUMP, label);
- }
-
- JUMPHERE(zerolength);
- BACKTRACK_AS(ref_iterator_backtrack)->matchingpath = LABEL();
-
- count_match(common);
- return cc;
- }
-
-allocate_stack(common, ref ? 2 : 3);
-if (ref)
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
-OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
-if (type != OP_CRMINSTAR)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
-
-if (min == 0)
- {
- /* Handles both invalid and empty cases. Since the minimum repeat,
- is zero the invalid case is basically the same as an empty case. */
- if (ref)
- zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
- else
- {
- compile_dnref_search(common, ccbegin, NULL);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);
- zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
- }
- /* Length is non-zero, we can match real repeats. */
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- jump = JUMP(SLJIT_JUMP);
- }
-else
- {
- if (ref)
- {
- add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));
- zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
- }
- else
- {
- compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);
- zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
- }
- }
-
-BACKTRACK_AS(ref_iterator_backtrack)->matchingpath = LABEL();
-if (max > 0)
- add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
-
-if (!ref)
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
-compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
-OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
-
-if (min > 1)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
- CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(ref_iterator_backtrack)->matchingpath);
- }
-else if (max > 0)
- OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
-
-if (jump != NULL)
- JUMPHERE(jump);
-JUMPHERE(zerolength);
-
-count_match(common);
-return cc;
-}
-
-static SLJIT_INLINE PCRE2_SPTR compile_recurse_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
-{
-DEFINE_COMPILER;
-backtrack_common *backtrack;
-recurse_entry *entry = common->entries;
-recurse_entry *prev = NULL;
-sljit_sw start = GET(cc, 1);
-PCRE2_SPTR start_cc;
-BOOL needs_control_head;
-
-PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
-
-/* Inlining simple patterns. */
-if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack)
- {
- start_cc = common->start + start;
- compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack);
- BACKTRACK_AS(recurse_backtrack)->inlined_pattern = TRUE;
- return cc + 1 + LINK_SIZE;
- }
-
-while (entry != NULL)
- {
- if (entry->start == start)
- break;
- prev = entry;
- entry = entry->next;
- }
-
-if (entry == NULL)
- {
- entry = sljit_alloc_memory(compiler, sizeof(recurse_entry));
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- return NULL;
- entry->next = NULL;
- entry->entry_label = NULL;
- entry->backtrack_label = NULL;
- entry->entry_calls = NULL;
- entry->backtrack_calls = NULL;
- entry->start = start;
-
- if (prev != NULL)
- prev->next = entry;
- else
- common->entries = entry;
- }
-
-BACKTRACK_AS(recurse_backtrack)->entry = entry;
-
-if (entry->entry_label == NULL)
- add_jump(compiler, &entry->entry_calls, JUMP(SLJIT_FAST_CALL));
-else
- JUMPTO(SLJIT_FAST_CALL, entry->entry_label);
-/* Leave if the match is failed. */
-add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0));
-BACKTRACK_AS(recurse_backtrack)->matchingpath = LABEL();
-return cc + 1 + LINK_SIZE;
-}
-
-static sljit_s32 SLJIT_FUNC do_callout_jit(struct jit_arguments *arguments, pcre2_callout_block *callout_block, PCRE2_SPTR *jit_ovector)
-{
-PCRE2_SPTR begin;
-PCRE2_SIZE *ovector;
-sljit_u32 oveccount, capture_top;
-
-if (arguments->callout == NULL)
- return 0;
-
-SLJIT_COMPILE_ASSERT(sizeof (PCRE2_SIZE) <= sizeof (sljit_sw), pcre2_size_must_be_lower_than_sljit_sw_size);
-
-begin = arguments->begin;
-ovector = (PCRE2_SIZE*)(callout_block + 1);
-oveccount = callout_block->capture_top;
-
-SLJIT_ASSERT(oveccount >= 1);
-
-callout_block->version = 2;
-callout_block->callout_flags = 0;
-
-/* Offsets in subject. */
-callout_block->subject_length = arguments->end - arguments->begin;
-callout_block->start_match = jit_ovector[0] - begin;
-callout_block->current_position = (PCRE2_SPTR)callout_block->offset_vector - begin;
-callout_block->subject = begin;
-
-/* Convert and copy the JIT offset vector to the ovector array. */
-callout_block->capture_top = 1;
-callout_block->offset_vector = ovector;
-
-ovector[0] = PCRE2_UNSET;
-ovector[1] = PCRE2_UNSET;
-ovector += 2;
-jit_ovector += 2;
-capture_top = 1;
-
-/* Convert pointers to sizes. */
-while (--oveccount != 0)
- {
- capture_top++;
-
- ovector[0] = (PCRE2_SIZE)(jit_ovector[0] - begin);
- ovector[1] = (PCRE2_SIZE)(jit_ovector[1] - begin);
-
- if (ovector[0] != PCRE2_UNSET)
- callout_block->capture_top = capture_top;
-
- ovector += 2;
- jit_ovector += 2;
- }
-
-return (arguments->callout)(callout_block, arguments->callout_data);
-}
-
-#define CALLOUT_ARG_OFFSET(arg) \
- SLJIT_OFFSETOF(pcre2_callout_block, arg)
-
-static SLJIT_INLINE PCRE2_SPTR compile_callout_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
-{
-DEFINE_COMPILER;
-backtrack_common *backtrack;
-sljit_s32 mov_opcode;
-unsigned int callout_length = (*cc == OP_CALLOUT)
- ? PRIV(OP_lengths)[OP_CALLOUT] : GET(cc, 1 + 2 * LINK_SIZE);
-sljit_sw value1;
-sljit_sw value2;
-sljit_sw value3;
-sljit_uw callout_arg_size = (common->re->top_bracket + 1) * 2 * SSIZE_OF(sw);
-
-PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
-
-callout_arg_size = (sizeof(pcre2_callout_block) + callout_arg_size + sizeof(sljit_sw) - 1) / sizeof(sljit_sw);
-
-allocate_stack(common, callout_arg_size);
-
-SLJIT_ASSERT(common->capture_last_ptr != 0);
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
-OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
-value1 = (*cc == OP_CALLOUT) ? cc[1 + 2 * LINK_SIZE] : 0;
-OP1(SLJIT_MOV_U32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, value1);
-OP1(SLJIT_MOV_U32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0);
-OP1(SLJIT_MOV_U32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_top), SLJIT_IMM, common->re->top_bracket + 1);
-
-/* These pointer sized fields temporarly stores internal variables. */
-OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(offset_vector), STR_PTR, 0);
-
-if (common->mark_ptr != 0)
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));
-mov_opcode = (sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_U32 : SLJIT_MOV;
-OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 1));
-OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 1 + LINK_SIZE));
-
-if (*cc == OP_CALLOUT)
- {
- value1 = 0;
- value2 = 0;
- value3 = 0;
- }
-else
- {
- value1 = (sljit_sw) (cc + (1 + 4*LINK_SIZE) + 1);
- value2 = (callout_length - (1 + 4*LINK_SIZE + 2));
- value3 = (sljit_sw) (GET(cc, 1 + 3*LINK_SIZE));
- }
-
-OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string), SLJIT_IMM, value1);
-OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string_length), SLJIT_IMM, value2);
-OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string_offset), SLJIT_IMM, value3);
-OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);
-
-SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
-
-/* Needed to save important temporary registers. */
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STR_PTR, 0);
-/* SLJIT_R0 = arguments */
-OP1(SLJIT_MOV, SLJIT_R1, 0, STACK_TOP, 0);
-GET_LOCAL_BASE(SLJIT_R2, 0, OVECTOR_START);
-sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS3(32, W, W, W), SLJIT_IMM, SLJIT_FUNC_ADDR(do_callout_jit));
-OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
-free_stack(common, callout_arg_size);
-
-/* Check return value. */
-OP2U(SLJIT_SUB32 | SLJIT_SET_Z | SLJIT_SET_SIG_GREATER, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
-add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER));
-if (common->abort_label == NULL)
- add_jump(compiler, &common->abort, JUMP(SLJIT_NOT_EQUAL) /* SIG_LESS */);
-else
- JUMPTO(SLJIT_NOT_EQUAL /* SIG_LESS */, common->abort_label);
-return cc + callout_length;
-}
-
-#undef CALLOUT_ARG_SIZE
-#undef CALLOUT_ARG_OFFSET
-
-static SLJIT_INLINE BOOL assert_needs_str_ptr_saving(PCRE2_SPTR cc)
-{
-while (TRUE)
- {
- switch (*cc)
- {
- case OP_CALLOUT_STR:
- cc += GET(cc, 1 + 2*LINK_SIZE);
- break;
-
- case OP_NOT_WORD_BOUNDARY:
- case OP_WORD_BOUNDARY:
- case OP_CIRC:
- case OP_CIRCM:
- case OP_DOLL:
- case OP_DOLLM:
- case OP_CALLOUT:
- case OP_ALT:
- cc += PRIV(OP_lengths)[*cc];
- break;
-
- case OP_KET:
- return FALSE;
-
- default:
- return TRUE;
- }
- }
-}
-
-static PCRE2_SPTR compile_assert_matchingpath(compiler_common *common, PCRE2_SPTR cc, assert_backtrack *backtrack, BOOL conditional)
-{
-DEFINE_COMPILER;
-int framesize;
-int extrasize;
-BOOL local_quit_available = FALSE;
-BOOL needs_control_head;
-int private_data_ptr;
-backtrack_common altbacktrack;
-PCRE2_SPTR ccbegin;
-PCRE2_UCHAR opcode;
-PCRE2_UCHAR bra = OP_BRA;
-jump_list *tmp = NULL;
-jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
-jump_list **found;
-/* Saving previous accept variables. */
-BOOL save_local_quit_available = common->local_quit_available;
-BOOL save_in_positive_assertion = common->in_positive_assertion;
-then_trap_backtrack *save_then_trap = common->then_trap;
-struct sljit_label *save_quit_label = common->quit_label;
-struct sljit_label *save_accept_label = common->accept_label;
-jump_list *save_quit = common->quit;
-jump_list *save_positive_assertion_quit = common->positive_assertion_quit;
-jump_list *save_accept = common->accept;
-struct sljit_jump *jump;
-struct sljit_jump *brajump = NULL;
-
-/* Assert captures then. */
-common->then_trap = NULL;
-
-if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
- {
- SLJIT_ASSERT(!conditional);
- bra = *cc;
- cc++;
- }
-private_data_ptr = PRIVATE_DATA(cc);
-SLJIT_ASSERT(private_data_ptr != 0);
-framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
-backtrack->framesize = framesize;
-backtrack->private_data_ptr = private_data_ptr;
-opcode = *cc;
-SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
-found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
-ccbegin = cc;
-cc += GET(cc, 1);
-
-if (bra == OP_BRAMINZERO)
- {
- /* This is a braminzero backtrack path. */
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
- brajump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
- }
-
-if (framesize < 0)
- {
- extrasize = 1;
- if (bra == OP_BRA && !assert_needs_str_ptr_saving(ccbegin + 1 + LINK_SIZE))
- extrasize = 0;
-
- if (needs_control_head)
- extrasize++;
-
- if (framesize == no_frame)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);
-
- if (extrasize > 0)
- allocate_stack(common, extrasize);
-
- if (needs_control_head)
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
-
- if (extrasize > 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
-
- if (needs_control_head)
- {
- SLJIT_ASSERT(extrasize == 2);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
- }
- }
-else
- {
- extrasize = needs_control_head ? 3 : 2;
- allocate_stack(common, framesize + extrasize);
-
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- OP2(SLJIT_ADD, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);
- if (needs_control_head)
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
-
- if (needs_control_head)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
- }
- else
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
-
- init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize);
- }
-
-memset(&altbacktrack, 0, sizeof(backtrack_common));
-if (conditional || (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT))
- {
- /* Control verbs cannot escape from these asserts. */
- local_quit_available = TRUE;
- common->local_quit_available = TRUE;
- common->quit_label = NULL;
- common->quit = NULL;
- }
-
-common->in_positive_assertion = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK);
-common->positive_assertion_quit = NULL;
-
-while (1)
- {
- common->accept_label = NULL;
- common->accept = NULL;
- altbacktrack.top = NULL;
- altbacktrack.topbacktracks = NULL;
-
- if (*ccbegin == OP_ALT && extrasize > 0)
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
-
- altbacktrack.cc = ccbegin;
- compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- {
- if (local_quit_available)
- {
- common->local_quit_available = save_local_quit_available;
- common->quit_label = save_quit_label;
- common->quit = save_quit;
- }
- common->in_positive_assertion = save_in_positive_assertion;
- common->then_trap = save_then_trap;
- common->accept_label = save_accept_label;
- common->positive_assertion_quit = save_positive_assertion_quit;
- common->accept = save_accept;
- return NULL;
- }
- common->accept_label = LABEL();
- if (common->accept != NULL)
- set_jumps(common->accept, common->accept_label);
-
- /* Reset stack. */
- if (framesize < 0)
- {
- if (framesize == no_frame)
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- else if (extrasize > 0)
- free_stack(common, extrasize);
-
- if (needs_control_head)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(-1));
- }
- else
- {
- if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
- {
- /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
- OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
- if (needs_control_head)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(-1));
- }
- else
- {
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- if (needs_control_head)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(-framesize - 2));
- add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
- OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize - 1) * sizeof(sljit_sw));
- }
- }
-
- if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
- {
- /* We know that STR_PTR was stored on the top of the stack. */
- if (conditional)
- {
- if (extrasize > 0)
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? STACK(-2) : STACK(-1));
- }
- else if (bra == OP_BRAZERO)
- {
- if (framesize < 0)
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-extrasize));
- else
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-framesize - 1));
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-framesize - extrasize));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
- }
- OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- }
- else if (framesize >= 0)
- {
- /* For OP_BRA and OP_BRAMINZERO. */
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(-framesize - 1));
- }
- }
- add_jump(compiler, found, JUMP(SLJIT_JUMP));
-
- compile_backtrackingpath(common, altbacktrack.top);
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- {
- if (local_quit_available)
- {
- common->local_quit_available = save_local_quit_available;
- common->quit_label = save_quit_label;
- common->quit = save_quit;
- }
- common->in_positive_assertion = save_in_positive_assertion;
- common->then_trap = save_then_trap;
- common->accept_label = save_accept_label;
- common->positive_assertion_quit = save_positive_assertion_quit;
- common->accept = save_accept;
- return NULL;
- }
- set_jumps(altbacktrack.topbacktracks, LABEL());
-
- if (*cc != OP_ALT)
- break;
-
- ccbegin = cc;
- cc += GET(cc, 1);
- }
-
-if (local_quit_available)
- {
- SLJIT_ASSERT(common->positive_assertion_quit == NULL);
- /* Makes the check less complicated below. */
- common->positive_assertion_quit = common->quit;
- }
-
-/* None of them matched. */
-if (common->positive_assertion_quit != NULL)
- {
- jump = JUMP(SLJIT_JUMP);
- set_jumps(common->positive_assertion_quit, LABEL());
- SLJIT_ASSERT(framesize != no_stack);
- if (framesize < 0)
- OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));
- else
- {
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
- OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (extrasize + 1) * sizeof(sljit_sw));
- }
- JUMPHERE(jump);
- }
-
-if (needs_control_head)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1));
-
-if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
- {
- /* Assert is failed. */
- if ((conditional && extrasize > 0) || bra == OP_BRAZERO)
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
-
- if (framesize < 0)
- {
- /* The topmost item should be 0. */
- if (bra == OP_BRAZERO)
- {
- if (extrasize == 2)
- free_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- }
- else if (extrasize > 0)
- free_stack(common, extrasize);
- }
- else
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
- /* The topmost item should be 0. */
- if (bra == OP_BRAZERO)
- {
- free_stack(common, framesize + extrasize - 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- }
- else
- free_stack(common, framesize + extrasize);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
- }
- jump = JUMP(SLJIT_JUMP);
- if (bra != OP_BRAZERO)
- add_jump(compiler, target, jump);
-
- /* Assert is successful. */
- set_jumps(tmp, LABEL());
- if (framesize < 0)
- {
- /* We know that STR_PTR was stored on the top of the stack. */
- if (extrasize > 0)
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-extrasize));
-
- /* Keep the STR_PTR on the top of the stack. */
- if (bra == OP_BRAZERO)
- {
- OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
- if (extrasize == 2)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- }
- else if (bra == OP_BRAMINZERO)
- {
- OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- }
- }
- else
- {
- if (bra == OP_BRA)
- {
- /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
- OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-extrasize + 1));
- }
- else
- {
- /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
- OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw));
- if (extrasize == 2)
- {
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- if (bra == OP_BRAMINZERO)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- }
- else
- {
- SLJIT_ASSERT(extrasize == 3);
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-1));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
- }
- }
- }
-
- if (bra == OP_BRAZERO)
- {
- backtrack->matchingpath = LABEL();
- SET_LABEL(jump, backtrack->matchingpath);
- }
- else if (bra == OP_BRAMINZERO)
- {
- JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
- JUMPHERE(brajump);
- if (framesize >= 0)
- {
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-2));
- OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize - 1) * sizeof(sljit_sw));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
- }
- set_jumps(backtrack->common.topbacktracks, LABEL());
- }
- }
-else
- {
- /* AssertNot is successful. */
- if (framesize < 0)
- {
- if (extrasize > 0)
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
-
- if (bra != OP_BRA)
- {
- if (extrasize == 2)
- free_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- }
- else if (extrasize > 0)
- free_stack(common, extrasize);
- }
- else
- {
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
- /* The topmost item should be 0. */
- if (bra != OP_BRA)
- {
- free_stack(common, framesize + extrasize - 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- }
- else
- free_stack(common, framesize + extrasize);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
- }
-
- if (bra == OP_BRAZERO)
- backtrack->matchingpath = LABEL();
- else if (bra == OP_BRAMINZERO)
- {
- JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
- JUMPHERE(brajump);
- }
-
- if (bra != OP_BRA)
- {
- SLJIT_ASSERT(found == &backtrack->common.topbacktracks);
- set_jumps(backtrack->common.topbacktracks, LABEL());
- backtrack->common.topbacktracks = NULL;
- }
- }
-
-if (local_quit_available)
- {
- common->local_quit_available = save_local_quit_available;
- common->quit_label = save_quit_label;
- common->quit = save_quit;
- }
-common->in_positive_assertion = save_in_positive_assertion;
-common->then_trap = save_then_trap;
-common->accept_label = save_accept_label;
-common->positive_assertion_quit = save_positive_assertion_quit;
-common->accept = save_accept;
-return cc + 1 + LINK_SIZE;
-}
-
-static SLJIT_INLINE void match_once_common(compiler_common *common, PCRE2_UCHAR ket, int framesize, int private_data_ptr, BOOL has_alternatives, BOOL needs_control_head)
-{
-DEFINE_COMPILER;
-int stacksize;
-
-if (framesize < 0)
- {
- if (framesize == no_frame)
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- else
- {
- stacksize = needs_control_head ? 1 : 0;
- if (ket != OP_KET || has_alternatives)
- stacksize++;
-
- if (stacksize > 0)
- free_stack(common, stacksize);
- }
-
- if (needs_control_head)
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? STACK(-2) : STACK(-1));
-
- /* TMP2 which is set here used by OP_KETRMAX below. */
- if (ket == OP_KETRMAX)
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(-1));
- else if (ket == OP_KETRMIN)
- {
- /* Move the STR_PTR to the private_data_ptr. */
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(-1));
- }
- }
-else
- {
- stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1;
- OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw));
- if (needs_control_head)
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-1));
-
- if (ket == OP_KETRMAX)
- {
- /* TMP2 which is set here used by OP_KETRMAX below. */
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- }
- }
-if (needs_control_head)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP1, 0);
-}
-
-static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr)
-{
-DEFINE_COMPILER;
-
-if (common->capture_last_ptr != 0)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
- stacksize++;
- }
-if (common->optimized_cbracket[offset >> 1] == 0)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
- stacksize += 2;
- }
-return stacksize;
-}
-
-static PCRE2_SPTR SLJIT_FUNC do_script_run(PCRE2_SPTR ptr, PCRE2_SPTR endptr)
-{
- if (PRIV(script_run)(ptr, endptr, FALSE))
- return endptr;
- return NULL;
-}
-
-#ifdef SUPPORT_UNICODE
-
-static PCRE2_SPTR SLJIT_FUNC do_script_run_utf(PCRE2_SPTR ptr, PCRE2_SPTR endptr)
-{
- if (PRIV(script_run)(ptr, endptr, TRUE))
- return endptr;
- return NULL;
-}
-
-#endif /* SUPPORT_UNICODE */
-
-static SLJIT_INLINE void match_script_run_common(compiler_common *common, int private_data_ptr, backtrack_common *parent)
-{
-DEFINE_COMPILER;
-
-SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
-
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
-#ifdef SUPPORT_UNICODE
-sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM,
- common->utf ? SLJIT_FUNC_ADDR(do_script_run_utf) : SLJIT_FUNC_ADDR(do_script_run));
-#else
-sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, SLJIT_FUNC_ADDR(do_script_run));
-#endif
-
-OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
-add_jump(compiler, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
-}
-
-/*
- Handling bracketed expressions is probably the most complex part.
-
- Stack layout naming characters:
- S - Push the current STR_PTR
- 0 - Push a 0 (NULL)
- A - Push the current STR_PTR. Needed for restoring the STR_PTR
- before the next alternative. Not pushed if there are no alternatives.
- M - Any values pushed by the current alternative. Can be empty, or anything.
- C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack.
- L - Push the previous local (pointed by localptr) to the stack
- () - opional values stored on the stack
- ()* - optonal, can be stored multiple times
-
- The following list shows the regular expression templates, their PCRE byte codes
- and stack layout supported by pcre-sljit.
-
- (?:) OP_BRA | OP_KET A M
- () OP_CBRA | OP_KET C M
- (?:)+ OP_BRA | OP_KETRMAX 0 A M S ( A M S )*
- OP_SBRA | OP_KETRMAX 0 L M S ( L M S )*
- (?:)+? OP_BRA | OP_KETRMIN 0 A M S ( A M S )*
- OP_SBRA | OP_KETRMIN 0 L M S ( L M S )*
- ()+ OP_CBRA | OP_KETRMAX 0 C M S ( C M S )*
- OP_SCBRA | OP_KETRMAX 0 C M S ( C M S )*
- ()+? OP_CBRA | OP_KETRMIN 0 C M S ( C M S )*
- OP_SCBRA | OP_KETRMIN 0 C M S ( C M S )*
- (?:)? OP_BRAZERO | OP_BRA | OP_KET S ( A M 0 )
- (?:)?? OP_BRAMINZERO | OP_BRA | OP_KET S ( A M 0 )
- ()? OP_BRAZERO | OP_CBRA | OP_KET S ( C M 0 )
- ()?? OP_BRAMINZERO | OP_CBRA | OP_KET S ( C M 0 )
- (?:)* OP_BRAZERO | OP_BRA | OP_KETRMAX S 0 ( A M S )*
- OP_BRAZERO | OP_SBRA | OP_KETRMAX S 0 ( L M S )*
- (?:)*? OP_BRAMINZERO | OP_BRA | OP_KETRMIN S 0 ( A M S )*
- OP_BRAMINZERO | OP_SBRA | OP_KETRMIN S 0 ( L M S )*
- ()* OP_BRAZERO | OP_CBRA | OP_KETRMAX S 0 ( C M S )*
- OP_BRAZERO | OP_SCBRA | OP_KETRMAX S 0 ( C M S )*
- ()*? OP_BRAMINZERO | OP_CBRA | OP_KETRMIN S 0 ( C M S )*
- OP_BRAMINZERO | OP_SCBRA | OP_KETRMIN S 0 ( C M S )*
-
-
- Stack layout naming characters:
- A - Push the alternative index (starting from 0) on the stack.
- Not pushed if there is no alternatives.
- M - Any values pushed by the current alternative. Can be empty, or anything.
-
- The next list shows the possible content of a bracket:
- (|) OP_*BRA | OP_ALT ... M A
- (?()|) OP_*COND | OP_ALT M A
- (?>|) OP_ONCE | OP_ALT ... [stack trace] M A
- Or nothing, if trace is unnecessary
-*/
-
-static PCRE2_SPTR compile_bracket_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
-{
-DEFINE_COMPILER;
-backtrack_common *backtrack;
-PCRE2_UCHAR opcode;
-int private_data_ptr = 0;
-int offset = 0;
-int i, stacksize;
-int repeat_ptr = 0, repeat_length = 0;
-int repeat_type = 0, repeat_count = 0;
-PCRE2_SPTR ccbegin;
-PCRE2_SPTR matchingpath;
-PCRE2_SPTR slot;
-PCRE2_UCHAR bra = OP_BRA;
-PCRE2_UCHAR ket;
-assert_backtrack *assert;
-BOOL has_alternatives;
-BOOL needs_control_head = FALSE;
-struct sljit_jump *jump;
-struct sljit_jump *skip;
-struct sljit_label *rmax_label = NULL;
-struct sljit_jump *braminzero = NULL;
-
-PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
-
-if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
- {
- bra = *cc;
- cc++;
- opcode = *cc;
- }
-
-opcode = *cc;
-ccbegin = cc;
-matchingpath = bracketend(cc) - 1 - LINK_SIZE;
-ket = *matchingpath;
-if (ket == OP_KET && PRIVATE_DATA(matchingpath) != 0)
- {
- repeat_ptr = PRIVATE_DATA(matchingpath);
- repeat_length = PRIVATE_DATA(matchingpath + 1);
- repeat_type = PRIVATE_DATA(matchingpath + 2);
- repeat_count = PRIVATE_DATA(matchingpath + 3);
- SLJIT_ASSERT(repeat_length != 0 && repeat_type != 0 && repeat_count != 0);
- if (repeat_type == OP_UPTO)
- ket = OP_KETRMAX;
- if (repeat_type == OP_MINUPTO)
- ket = OP_KETRMIN;
- }
-
-matchingpath = ccbegin + 1 + LINK_SIZE;
-SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
-SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));
-cc += GET(cc, 1);
-
-has_alternatives = *cc == OP_ALT;
-if (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND))
- {
- SLJIT_COMPILE_ASSERT(OP_DNRREF == OP_RREF + 1 && OP_FALSE == OP_RREF + 2 && OP_TRUE == OP_RREF + 3,
- compile_time_checks_must_be_grouped_together);
- has_alternatives = ((*matchingpath >= OP_RREF && *matchingpath <= OP_TRUE) || *matchingpath == OP_FAIL) ? FALSE : TRUE;
- }
-
-if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
- opcode = OP_SCOND;
-
-if (opcode == OP_CBRA || opcode == OP_SCBRA)
- {
- /* Capturing brackets has a pre-allocated space. */
- offset = GET2(ccbegin, 1 + LINK_SIZE);
- if (common->optimized_cbracket[offset] == 0)
- {
- private_data_ptr = OVECTOR_PRIV(offset);
- offset <<= 1;
- }
- else
- {
- offset <<= 1;
- private_data_ptr = OVECTOR(offset);
- }
- BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
- matchingpath += IMM2_SIZE;
- }
-else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_ONCE || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND)
- {
- /* Other brackets simply allocate the next entry. */
- private_data_ptr = PRIVATE_DATA(ccbegin);
- SLJIT_ASSERT(private_data_ptr != 0);
- BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
- if (opcode == OP_ONCE)
- BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, NULL, FALSE, &needs_control_head);
- }
-
-/* Instructions before the first alternative. */
-stacksize = 0;
-if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
- stacksize++;
-if (bra == OP_BRAZERO)
- stacksize++;
-
-if (stacksize > 0)
- allocate_stack(common, stacksize);
-
-stacksize = 0;
-if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
- stacksize++;
- }
-
-if (bra == OP_BRAZERO)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
-
-if (bra == OP_BRAMINZERO)
- {
- /* This is a backtrack path! (Since the try-path of OP_BRAMINZERO matches to the empty string) */
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- if (ket != OP_KETRMIN)
- {
- free_stack(common, 1);
- braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
- }
- else if (opcode == OP_ONCE || opcode >= OP_SBRA)
- {
- jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- /* Nothing stored during the first run. */
- skip = JUMP(SLJIT_JUMP);
- JUMPHERE(jump);
- /* Checking zero-length iteration. */
- if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
- {
- /* When we come from outside, private_data_ptr contains the previous STR_PTR. */
- braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- }
- else
- {
- /* Except when the whole stack frame must be saved. */
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), STACK(-BACKTRACK_AS(bracket_backtrack)->u.framesize - 2));
- }
- JUMPHERE(skip);
- }
- else
- {
- jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- JUMPHERE(jump);
- }
- }
-
-if (repeat_type != 0)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, repeat_count);
- if (repeat_type == OP_EXACT)
- rmax_label = LABEL();
- }
-
-if (ket == OP_KETRMIN)
- BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
-
-if (ket == OP_KETRMAX)
- {
- rmax_label = LABEL();
- if (has_alternatives && opcode >= OP_BRA && opcode < OP_SBRA && repeat_type == 0)
- BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmax_label;
- }
-
-/* Handling capturing brackets and alternatives. */
-if (opcode == OP_ONCE)
- {
- stacksize = 0;
- if (needs_control_head)
- {
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
- stacksize++;
- }
-
- if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
- {
- /* Neither capturing brackets nor recursions are found in the block. */
- if (ket == OP_KETRMIN)
- {
- stacksize += 2;
- if (!needs_control_head)
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- }
- else
- {
- if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);
- if (ket == OP_KETRMAX || has_alternatives)
- stacksize++;
- }
-
- if (stacksize > 0)
- allocate_stack(common, stacksize);
-
- stacksize = 0;
- if (needs_control_head)
- {
- stacksize++;
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
- }
-
- if (ket == OP_KETRMIN)
- {
- if (needs_control_head)
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
- if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
- OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, needs_control_head ? (2 * sizeof(sljit_sw)) : sizeof(sljit_sw));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
- }
- else if (ket == OP_KETRMAX || has_alternatives)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
- }
- else
- {
- if (ket != OP_KET || has_alternatives)
- stacksize++;
-
- stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1;
- allocate_stack(common, stacksize);
-
- if (needs_control_head)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
-
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- OP2(SLJIT_ADD, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
-
- stacksize = needs_control_head ? 1 : 0;
- if (ket != OP_KET || has_alternatives)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);
- stacksize++;
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
- }
- else
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
- }
- init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1);
- }
- }
-else if (opcode == OP_CBRA || opcode == OP_SCBRA)
- {
- /* Saving the previous values. */
- if (common->optimized_cbracket[offset >> 1] != 0)
- {
- SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
- allocate_stack(common, 2);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
- }
- else
- {
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
- }
- }
-else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND)
- {
- /* Saving the previous value. */
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
- }
-else if (has_alternatives)
- {
- /* Pushing the starting string pointer. */
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- }
-
-/* Generating code for the first alternative. */
-if (opcode == OP_COND || opcode == OP_SCOND)
- {
- if (*matchingpath == OP_CREF)
- {
- SLJIT_ASSERT(has_alternatives);
- add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
- CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));
- matchingpath += 1 + IMM2_SIZE;
- }
- else if (*matchingpath == OP_DNCREF)
- {
- SLJIT_ASSERT(has_alternatives);
-
- i = GET2(matchingpath, 1 + IMM2_SIZE);
- slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
- OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
- OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
- slot += common->name_entry_size;
- i--;
- while (i-- > 0)
- {
- OP2(SLJIT_SUB, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
- OP2(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, TMP2, 0, STR_PTR, 0);
- slot += common->name_entry_size;
- }
- OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
- add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_ZERO));
- matchingpath += 1 + 2 * IMM2_SIZE;
- }
- else if ((*matchingpath >= OP_RREF && *matchingpath <= OP_TRUE) || *matchingpath == OP_FAIL)
- {
- /* Never has other case. */
- BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
- SLJIT_ASSERT(!has_alternatives);
-
- if (*matchingpath == OP_TRUE)
- {
- stacksize = 1;
- matchingpath++;
- }
- else if (*matchingpath == OP_FALSE || *matchingpath == OP_FAIL)
- stacksize = 0;
- else if (*matchingpath == OP_RREF)
- {
- stacksize = GET2(matchingpath, 1);
- if (common->currententry == NULL)
- stacksize = 0;
- else if (stacksize == RREF_ANY)
- stacksize = 1;
- else if (common->currententry->start == 0)
- stacksize = stacksize == 0;
- else
- stacksize = stacksize == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
-
- if (stacksize != 0)
- matchingpath += 1 + IMM2_SIZE;
- }
- else
- {
- if (common->currententry == NULL || common->currententry->start == 0)
- stacksize = 0;
- else
- {
- stacksize = GET2(matchingpath, 1 + IMM2_SIZE);
- slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
- i = (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
- while (stacksize > 0)
- {
- if ((int)GET2(slot, 0) == i)
- break;
- slot += common->name_entry_size;
- stacksize--;
- }
- }
-
- if (stacksize != 0)
- matchingpath += 1 + 2 * IMM2_SIZE;
- }
-
- /* The stacksize == 0 is a common "else" case. */
- if (stacksize == 0)
- {
- if (*cc == OP_ALT)
- {
- matchingpath = cc + 1 + LINK_SIZE;
- cc += GET(cc, 1);
- }
- else
- matchingpath = cc;
- }
- }
- else
- {
- SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);
- /* Similar code as PUSH_BACKTRACK macro. */
- assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- return NULL;
- memset(assert, 0, sizeof(assert_backtrack));
- assert->common.cc = matchingpath;
- BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
- matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE);
- }
- }
-
-compile_matchingpath(common, matchingpath, cc, backtrack);
-if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- return NULL;
-
-if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA)
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
-
-if (opcode == OP_ONCE)
- match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);
-
-if (opcode == OP_SCRIPT_RUN)
- match_script_run_common(common, private_data_ptr, backtrack);
-
-stacksize = 0;
-if (repeat_type == OP_MINUPTO)
- {
- /* We need to preserve the counter. TMP2 will be used below. */
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr);
- stacksize++;
- }
-if (ket != OP_KET || bra != OP_BRA)
- stacksize++;
-if (offset != 0)
- {
- if (common->capture_last_ptr != 0)
- stacksize++;
- if (common->optimized_cbracket[offset >> 1] == 0)
- stacksize += 2;
- }
-if (has_alternatives && opcode != OP_ONCE)
- stacksize++;
-
-if (stacksize > 0)
- allocate_stack(common, stacksize);
-
-stacksize = 0;
-if (repeat_type == OP_MINUPTO)
- {
- /* TMP2 was set above. */
- OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
- stacksize++;
- }
-
-if (ket != OP_KET || bra != OP_BRA)
- {
- if (ket != OP_KET)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
- else
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
- stacksize++;
- }
-
-if (offset != 0)
- stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
-
-/* Skip and count the other alternatives. */
-i = 1;
-while (*cc == OP_ALT)
- {
- cc += GET(cc, 1);
- i++;
- }
-
-if (has_alternatives)
- {
- if (opcode != OP_ONCE)
- {
- if (i <= 3)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
- else
- BACKTRACK_AS(bracket_backtrack)->u.matching_put_label = sljit_emit_put_label(compiler, SLJIT_MEM1(STACK_TOP), STACK(stacksize));
- }
- if (ket != OP_KETRMAX)
- BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
- }
-
-/* Must be after the matchingpath label. */
-if (offset != 0 && common->optimized_cbracket[offset >> 1] != 0)
- {
- SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
- }
-
-if (ket == OP_KETRMAX)
- {
- if (repeat_type != 0)
- {
- if (has_alternatives)
- BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
- OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
- JUMPTO(SLJIT_NOT_ZERO, rmax_label);
- /* Drop STR_PTR for greedy plus quantifier. */
- if (opcode != OP_ONCE)
- free_stack(common, 1);
- }
- else if (opcode < OP_BRA || opcode >= OP_SBRA)
- {
- if (has_alternatives)
- BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
-
- /* Checking zero-length iteration. */
- if (opcode != OP_ONCE)
- {
- /* This case includes opcodes such as OP_SCRIPT_RUN. */
- CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0, rmax_label);
- /* Drop STR_PTR for greedy plus quantifier. */
- if (bra != OP_BRAZERO)
- free_stack(common, 1);
- }
- else
- /* TMP2 must contain the starting STR_PTR. */
- CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmax_label);
- }
- else
- JUMPTO(SLJIT_JUMP, rmax_label);
- BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
- }
-
-if (repeat_type == OP_EXACT)
- {
- count_match(common);
- OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
- JUMPTO(SLJIT_NOT_ZERO, rmax_label);
- }
-else if (repeat_type == OP_UPTO)
- {
- /* We need to preserve the counter. */
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr);
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
- }
-
-if (bra == OP_BRAZERO)
- BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
-
-if (bra == OP_BRAMINZERO)
- {
- /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
- JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
- if (braminzero != NULL)
- {
- JUMPHERE(braminzero);
- /* We need to release the end pointer to perform the
- backtrack for the zero-length iteration. When
- framesize is < 0, OP_ONCE will do the release itself. */
- if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
- {
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
- OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize - 1) * sizeof(sljit_sw));
- }
- else if (ket == OP_KETRMIN && opcode != OP_ONCE)
- free_stack(common, 1);
- }
- /* Continue to the normal backtrack. */
- }
-
-if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
- count_match(common);
-
-cc += 1 + LINK_SIZE;
-
-if (opcode == OP_ONCE)
- {
- /* We temporarily encode the needs_control_head in the lowest bit.
- Note: on the target architectures of SLJIT the ((x << 1) >> 1) returns
- the same value for small signed numbers (including negative numbers). */
- BACKTRACK_AS(bracket_backtrack)->u.framesize = (int)((unsigned)BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
- }
-return cc + repeat_length;
-}
-
-static PCRE2_SPTR compile_bracketpos_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
-{
-DEFINE_COMPILER;
-backtrack_common *backtrack;
-PCRE2_UCHAR opcode;
-int private_data_ptr;
-int cbraprivptr = 0;
-BOOL needs_control_head;
-int framesize;
-int stacksize;
-int offset = 0;
-BOOL zero = FALSE;
-PCRE2_SPTR ccbegin = NULL;
-int stack; /* Also contains the offset of control head. */
-struct sljit_label *loop = NULL;
-struct jump_list *emptymatch = NULL;
-
-PUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL);
-if (*cc == OP_BRAPOSZERO)
- {
- zero = TRUE;
- cc++;
- }
-
-opcode = *cc;
-private_data_ptr = PRIVATE_DATA(cc);
-SLJIT_ASSERT(private_data_ptr != 0);
-BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr;
-switch(opcode)
- {
- case OP_BRAPOS:
- case OP_SBRAPOS:
- ccbegin = cc + 1 + LINK_SIZE;
- break;
-
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- offset = GET2(cc, 1 + LINK_SIZE);
- /* This case cannot be optimized in the same was as
- normal capturing brackets. */
- SLJIT_ASSERT(common->optimized_cbracket[offset] == 0);
- cbraprivptr = OVECTOR_PRIV(offset);
- offset <<= 1;
- ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
- break;
-
- default:
- SLJIT_UNREACHABLE();
- break;
- }
-
-framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
-BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
-if (framesize < 0)
- {
- if (offset != 0)
- {
- stacksize = 2;
- if (common->capture_last_ptr != 0)
- stacksize++;
- }
- else
- stacksize = 1;
-
- if (needs_control_head)
- stacksize++;
- if (!zero)
- stacksize++;
-
- BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
- allocate_stack(common, stacksize);
- if (framesize == no_frame)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);
-
- stack = 0;
- if (offset != 0)
- {
- stack = 2;
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
- if (common->capture_last_ptr != 0)
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
- if (needs_control_head)
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
- if (common->capture_last_ptr != 0)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
- stack = 3;
- }
- }
- else
- {
- if (needs_control_head)
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- stack = 1;
- }
-
- if (needs_control_head)
- stack++;
- if (!zero)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), SLJIT_IMM, 1);
- if (needs_control_head)
- {
- stack--;
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
- }
- }
-else
- {
- stacksize = framesize + 1;
- if (!zero)
- stacksize++;
- if (needs_control_head)
- stacksize++;
- if (offset == 0)
- stacksize++;
- BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
-
- allocate_stack(common, stacksize);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- if (needs_control_head)
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
- OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
-
- stack = 0;
- if (!zero)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
- stack = 1;
- }
- if (needs_control_head)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
- stack++;
- }
- if (offset == 0)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
- stack++;
- }
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
- init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize);
- stack -= 1 + (offset == 0);
- }
-
-if (offset != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0);
-
-loop = LABEL();
-while (*cc != OP_KETRPOS)
- {
- backtrack->top = NULL;
- backtrack->topbacktracks = NULL;
- cc += GET(cc, 1);
-
- compile_matchingpath(common, ccbegin, cc, backtrack);
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- return NULL;
-
- if (framesize < 0)
- {
- if (framesize == no_frame)
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
-
- if (offset != 0)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0);
- if (common->capture_last_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
- }
- else
- {
- if (opcode == OP_SBRAPOS)
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- }
-
- /* Even if the match is empty, we need to reset the control head. */
- if (needs_control_head)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
-
- if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
- add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));
-
- if (!zero)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
- }
- else
- {
- if (offset != 0)
- {
- OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_sw));
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0);
- if (common->capture_last_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
- }
- else
- {
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- OP2(SLJIT_SUB, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
- if (opcode == OP_SBRAPOS)
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), STACK(-framesize - 2));
- OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), STACK(-framesize - 2), STR_PTR, 0);
- }
-
- /* Even if the match is empty, we need to reset the control head. */
- if (needs_control_head)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
-
- if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
- add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));
-
- if (!zero)
- {
- if (framesize < 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
- else
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- }
- }
-
- JUMPTO(SLJIT_JUMP, loop);
- flush_stubs(common);
-
- compile_backtrackingpath(common, backtrack->top);
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- return NULL;
- set_jumps(backtrack->topbacktracks, LABEL());
-
- if (framesize < 0)
- {
- if (offset != 0)
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);
- else
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- }
- else
- {
- if (offset != 0)
- {
- /* Last alternative. */
- if (*cc == OP_KETRPOS)
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);
- }
- else
- {
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), STACK(-framesize - 2));
- }
- }
-
- if (*cc == OP_KETRPOS)
- break;
- ccbegin = cc + 1 + LINK_SIZE;
- }
-
-/* We don't have to restore the control head in case of a failed match. */
-
-backtrack->topbacktracks = NULL;
-if (!zero)
- {
- if (framesize < 0)
- add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));
- else /* TMP2 is set to [private_data_ptr] above. */
- add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(TMP2), STACK(-stacksize), SLJIT_IMM, 0));
- }
-
-/* None of them matched. */
-set_jumps(emptymatch, LABEL());
-count_match(common);
-return cc + 1 + LINK_SIZE;
-}
-
-static SLJIT_INLINE PCRE2_SPTR get_iterator_parameters(compiler_common *common, PCRE2_SPTR cc, PCRE2_UCHAR *opcode, PCRE2_UCHAR *type, sljit_u32 *max, sljit_u32 *exact, PCRE2_SPTR *end)
-{
-int class_len;
-
-*opcode = *cc;
-*exact = 0;
-
-if (*opcode >= OP_STAR && *opcode <= OP_POSUPTO)
- {
- cc++;
- *type = OP_CHAR;
- }
-else if (*opcode >= OP_STARI && *opcode <= OP_POSUPTOI)
- {
- cc++;
- *type = OP_CHARI;
- *opcode -= OP_STARI - OP_STAR;
- }
-else if (*opcode >= OP_NOTSTAR && *opcode <= OP_NOTPOSUPTO)
- {
- cc++;
- *type = OP_NOT;
- *opcode -= OP_NOTSTAR - OP_STAR;
- }
-else if (*opcode >= OP_NOTSTARI && *opcode <= OP_NOTPOSUPTOI)
- {
- cc++;
- *type = OP_NOTI;
- *opcode -= OP_NOTSTARI - OP_STAR;
- }
-else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO)
- {
- cc++;
- *opcode -= OP_TYPESTAR - OP_STAR;
- *type = OP_END;
- }
-else
- {
- SLJIT_ASSERT(*opcode == OP_CLASS || *opcode == OP_NCLASS || *opcode == OP_XCLASS);
- *type = *opcode;
- cc++;
- class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(PCRE2_UCHAR))) : GET(cc, 0);
- *opcode = cc[class_len - 1];
-
- if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
- {
- *opcode -= OP_CRSTAR - OP_STAR;
- *end = cc + class_len;
-
- if (*opcode == OP_PLUS || *opcode == OP_MINPLUS)
- {
- *exact = 1;
- *opcode -= OP_PLUS - OP_STAR;
- }
- }
- else if (*opcode >= OP_CRPOSSTAR && *opcode <= OP_CRPOSQUERY)
- {
- *opcode -= OP_CRPOSSTAR - OP_POSSTAR;
- *end = cc + class_len;
-
- if (*opcode == OP_POSPLUS)
- {
- *exact = 1;
- *opcode = OP_POSSTAR;
- }
- }
- else
- {
- SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE || *opcode == OP_CRPOSRANGE);
- *max = GET2(cc, (class_len + IMM2_SIZE));
- *exact = GET2(cc, class_len);
-
- if (*max == 0)
- {
- if (*opcode == OP_CRPOSRANGE)
- *opcode = OP_POSSTAR;
- else
- *opcode -= OP_CRRANGE - OP_STAR;
- }
- else
- {
- *max -= *exact;
- if (*max == 0)
- *opcode = OP_EXACT;
- else if (*max == 1)
- {
- if (*opcode == OP_CRPOSRANGE)
- *opcode = OP_POSQUERY;
- else
- *opcode -= OP_CRRANGE - OP_QUERY;
- }
- else
- {
- if (*opcode == OP_CRPOSRANGE)
- *opcode = OP_POSUPTO;
- else
- *opcode -= OP_CRRANGE - OP_UPTO;
- }
- }
- *end = cc + class_len + 2 * IMM2_SIZE;
- }
- return cc;
- }
-
-switch(*opcode)
- {
- case OP_EXACT:
- *exact = GET2(cc, 0);
- cc += IMM2_SIZE;
- break;
-
- case OP_PLUS:
- case OP_MINPLUS:
- *exact = 1;
- *opcode -= OP_PLUS - OP_STAR;
- break;
-
- case OP_POSPLUS:
- *exact = 1;
- *opcode = OP_POSSTAR;
- break;
-
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_POSUPTO:
- *max = GET2(cc, 0);
- cc += IMM2_SIZE;
- break;
- }
-
-if (*type == OP_END)
- {
- *type = *cc;
- *end = next_opcode(common, cc);
- cc++;
- return cc;
- }
-
-*end = cc + 1;
-#ifdef SUPPORT_UNICODE
-if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);
-#endif
-return cc;
-}
-
-static PCRE2_SPTR compile_iterator_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
-{
-DEFINE_COMPILER;
-backtrack_common *backtrack;
-PCRE2_UCHAR opcode;
-PCRE2_UCHAR type;
-sljit_u32 max = 0, exact;
-sljit_s32 early_fail_ptr = PRIVATE_DATA(cc + 1);
-sljit_s32 early_fail_type;
-BOOL charpos_enabled;
-PCRE2_UCHAR charpos_char;
-unsigned int charpos_othercasebit;
-PCRE2_SPTR end;
-jump_list *no_match = NULL;
-jump_list *no_char1_match = NULL;
-struct sljit_jump *jump = NULL;
-struct sljit_label *label;
-int private_data_ptr = PRIVATE_DATA(cc);
-int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP);
-int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
-int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + SSIZE_OF(sw);
-int tmp_base, tmp_offset;
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-BOOL use_tmp;
-#endif
-
-PUSH_BACKTRACK(sizeof(char_iterator_backtrack), cc, NULL);
-
-early_fail_type = (early_fail_ptr & 0x7);
-early_fail_ptr >>= 3;
-
-/* During recursion, these optimizations are disabled. */
-if (common->early_fail_start_ptr == 0 && common->fast_forward_bc_ptr == NULL)
- {
- early_fail_ptr = 0;
- early_fail_type = type_skip;
- }
-
-SLJIT_ASSERT(common->fast_forward_bc_ptr != NULL || early_fail_ptr == 0
- || (early_fail_ptr >= common->early_fail_start_ptr && early_fail_ptr <= common->early_fail_end_ptr));
-
-if (early_fail_type == type_fail)
- add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr));
-
-cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end);
-
-if (type != OP_EXTUNI)
- {
- tmp_base = TMP3;
- tmp_offset = 0;
- }
-else
- {
- tmp_base = SLJIT_MEM1(SLJIT_SP);
- tmp_offset = POSSESSIVE0;
- }
-
-/* Handle fixed part first. */
-if (exact > 1)
- {
- SLJIT_ASSERT(early_fail_ptr == 0);
-
- if (common->mode == PCRE2_JIT_COMPLETE
-#ifdef SUPPORT_UNICODE
- && !common->utf
-#endif
- && type != OP_ANYNL && type != OP_EXTUNI)
- {
- OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(exact));
- add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER, TMP1, 0, STR_END, 0));
- OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact);
- label = LABEL();
- compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE);
- OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
- JUMPTO(SLJIT_NOT_ZERO, label);
- }
- else
- {
- OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact);
- label = LABEL();
- compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE);
- OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
- JUMPTO(SLJIT_NOT_ZERO, label);
- }
- }
-else if (exact == 1)
- compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE);
-
-if (early_fail_type == type_fail_range)
- {
- /* Range end first, followed by range start. */
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr + SSIZE_OF(sw));
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, TMP2, 0);
- OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, TMP2, 0);
- add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, TMP2, 0, TMP1, 0));
-
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr + SSIZE_OF(sw), STR_PTR, 0);
- }
-
-switch(opcode)
- {
- case OP_STAR:
- case OP_UPTO:
- SLJIT_ASSERT(early_fail_ptr == 0 || opcode == OP_STAR);
-
- if (type == OP_ANYNL || type == OP_EXTUNI)
- {
- SLJIT_ASSERT(private_data_ptr == 0);
- SLJIT_ASSERT(early_fail_ptr == 0);
-
- allocate_stack(common, 2);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
-
- if (opcode == OP_UPTO)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, max);
-
- label = LABEL();
- compile_char1_matchingpath(common, type, cc, &BACKTRACK_AS(char_iterator_backtrack)->u.backtracks, TRUE);
- if (opcode == OP_UPTO)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0);
- OP2(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
- jump = JUMP(SLJIT_ZERO);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0);
- }
-
- /* We cannot use TMP3 because of allocate_stack. */
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- JUMPTO(SLJIT_JUMP, label);
- if (jump != NULL)
- JUMPHERE(jump);
- BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
- break;
- }
-#ifdef SUPPORT_UNICODE
- else if (type == OP_ALLANY && !common->invalid_utf)
-#else
- else if (type == OP_ALLANY)
-#endif
- {
- if (opcode == OP_STAR)
- {
- if (private_data_ptr == 0)
- allocate_stack(common, 2);
-
- OP1(SLJIT_MOV, base, offset0, STR_END, 0);
- OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
-
- OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
- process_partial_match(common);
-
- if (early_fail_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_END, 0);
- BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
- break;
- }
-#ifdef SUPPORT_UNICODE
- else if (!common->utf)
-#else
- else
-#endif
- {
- if (private_data_ptr == 0)
- allocate_stack(common, 2);
-
- OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(max));
-
- if (common->mode == PCRE2_JIT_COMPLETE)
- {
- OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0);
- CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0);
- }
- else
- {
- jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, STR_END, 0);
- process_partial_match(common);
- JUMPHERE(jump);
- }
-
- OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
-
- if (early_fail_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);
- BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
- break;
- }
- }
-
- charpos_enabled = FALSE;
- charpos_char = 0;
- charpos_othercasebit = 0;
-
- if ((type != OP_CHAR && type != OP_CHARI) && (*end == OP_CHAR || *end == OP_CHARI))
- {
-#ifdef SUPPORT_UNICODE
- charpos_enabled = !common->utf || !HAS_EXTRALEN(end[1]);
-#else
- charpos_enabled = TRUE;
-#endif
- if (charpos_enabled && *end == OP_CHARI && char_has_othercase(common, end + 1))
- {
- charpos_othercasebit = char_get_othercase_bit(common, end + 1);
- if (charpos_othercasebit == 0)
- charpos_enabled = FALSE;
- }
-
- if (charpos_enabled)
- {
- charpos_char = end[1];
- /* Consume the OP_CHAR opcode. */
- end += 2;
-#if PCRE2_CODE_UNIT_WIDTH == 8
- SLJIT_ASSERT((charpos_othercasebit >> 8) == 0);
-#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
- SLJIT_ASSERT((charpos_othercasebit >> 9) == 0);
- if ((charpos_othercasebit & 0x100) != 0)
- charpos_othercasebit = (charpos_othercasebit & 0xff) << 8;
-#endif
- if (charpos_othercasebit != 0)
- charpos_char |= charpos_othercasebit;
-
- BACKTRACK_AS(char_iterator_backtrack)->u.charpos.enabled = TRUE;
- BACKTRACK_AS(char_iterator_backtrack)->u.charpos.chr = charpos_char;
- BACKTRACK_AS(char_iterator_backtrack)->u.charpos.othercasebit = charpos_othercasebit;
- }
- }
-
- if (charpos_enabled)
- {
- if (opcode == OP_UPTO)
- OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max + 1);
-
- /* Search the first instance of charpos_char. */
- jump = JUMP(SLJIT_JUMP);
- label = LABEL();
- if (opcode == OP_UPTO)
- {
- OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
- add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_ZERO));
- }
- compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE);
- if (early_fail_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);
- JUMPHERE(jump);
-
- detect_partial_match(common, &backtrack->topbacktracks);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
- if (charpos_othercasebit != 0)
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit);
- CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label);
-
- if (private_data_ptr == 0)
- allocate_stack(common, 2);
- OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
- OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
-
- if (opcode == OP_UPTO)
- {
- OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
- add_jump(compiler, &no_match, JUMP(SLJIT_ZERO));
- }
-
- /* Search the last instance of charpos_char. */
- label = LABEL();
- compile_char1_matchingpath(common, type, cc, &no_match, FALSE);
- if (early_fail_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);
- detect_partial_match(common, &no_match);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
- if (charpos_othercasebit != 0)
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit);
-
- if (opcode == OP_STAR)
- {
- CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label);
- OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
- JUMPTO(SLJIT_JUMP, label);
- }
- else
- {
- jump = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char);
- OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
- JUMPHERE(jump);
- OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
- JUMPTO(SLJIT_NOT_ZERO, label);
- }
-
- set_jumps(no_match, LABEL());
- OP2(SLJIT_ADD, STR_PTR, 0, base, offset0, SLJIT_IMM, IN_UCHARS(1));
- OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
- }
- else
- {
- if (private_data_ptr == 0)
- allocate_stack(common, 2);
-
- OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- use_tmp = (!HAS_VIRTUAL_REGISTERS && opcode == OP_STAR);
- SLJIT_ASSERT(!use_tmp || tmp_base == TMP3);
-
- if (common->utf)
- OP1(SLJIT_MOV, use_tmp ? TMP3 : base, use_tmp ? 0 : offset0, STR_PTR, 0);
-#endif
- if (opcode == OP_UPTO)
- OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
-
- detect_partial_match(common, &no_match);
- label = LABEL();
- compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (common->utf)
- OP1(SLJIT_MOV, use_tmp ? TMP3 : base, use_tmp ? 0 : offset0, STR_PTR, 0);
-#endif
-
- if (opcode == OP_UPTO)
- {
- OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
- add_jump(compiler, &no_match, JUMP(SLJIT_ZERO));
- }
-
- detect_partial_match_to(common, label);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
- set_jumps(no_char1_match, LABEL());
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (common->utf)
- {
- set_jumps(no_match, LABEL());
- if (use_tmp)
- {
- OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
- OP1(SLJIT_MOV, base, offset0, TMP3, 0);
- }
- else
- OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
- }
- else
-#endif
- {
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- set_jumps(no_match, LABEL());
- OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
- }
-
- if (early_fail_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);
- }
-
- BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
- break;
-
- case OP_MINSTAR:
- if (private_data_ptr == 0)
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
- BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
- if (early_fail_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);
- break;
-
- case OP_MINUPTO:
- SLJIT_ASSERT(early_fail_ptr == 0);
- if (private_data_ptr == 0)
- allocate_stack(common, 2);
- OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
- OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, max + 1);
- BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
- break;
-
- case OP_QUERY:
- case OP_MINQUERY:
- SLJIT_ASSERT(early_fail_ptr == 0);
- if (private_data_ptr == 0)
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
- if (opcode == OP_QUERY)
- compile_char1_matchingpath(common, type, cc, &BACKTRACK_AS(char_iterator_backtrack)->u.backtracks, TRUE);
- BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
- break;
-
- case OP_EXACT:
- break;
-
- case OP_POSSTAR:
-#if defined SUPPORT_UNICODE
- if (type == OP_ALLANY && !common->invalid_utf)
-#else
- if (type == OP_ALLANY)
-#endif
- {
- OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
- process_partial_match(common);
- if (early_fail_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_END, 0);
- break;
- }
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (common->utf)
- {
- OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
- detect_partial_match(common, &no_match);
- label = LABEL();
- compile_char1_matchingpath(common, type, cc, &no_match, FALSE);
- OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
- detect_partial_match_to(common, label);
-
- set_jumps(no_match, LABEL());
- OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
- if (early_fail_ptr != 0)
- {
- if (!HAS_VIRTUAL_REGISTERS && tmp_base == TMP3)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, TMP3, 0);
- else
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);
- }
- break;
- }
-#endif
-
- detect_partial_match(common, &no_match);
- label = LABEL();
- compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);
- detect_partial_match_to(common, label);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
- set_jumps(no_char1_match, LABEL());
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- set_jumps(no_match, LABEL());
- if (early_fail_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);
- break;
-
- case OP_POSUPTO:
- SLJIT_ASSERT(early_fail_ptr == 0);
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (common->utf)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0);
- OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
-
- detect_partial_match(common, &no_match);
- label = LABEL();
- compile_char1_matchingpath(common, type, cc, &no_match, FALSE);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0);
- OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
- add_jump(compiler, &no_match, JUMP(SLJIT_ZERO));
- detect_partial_match_to(common, label);
-
- set_jumps(no_match, LABEL());
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1);
- break;
- }
-#endif
-
- if (type == OP_ALLANY)
- {
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(max));
-
- if (common->mode == PCRE2_JIT_COMPLETE)
- {
- OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0);
- CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0);
- }
- else
- {
- jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, STR_END, 0);
- process_partial_match(common);
- JUMPHERE(jump);
- }
- break;
- }
-
- OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
-
- detect_partial_match(common, &no_match);
- label = LABEL();
- compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);
- OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
- add_jump(compiler, &no_match, JUMP(SLJIT_ZERO));
- detect_partial_match_to(common, label);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
- set_jumps(no_char1_match, LABEL());
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- set_jumps(no_match, LABEL());
- break;
-
- case OP_POSQUERY:
- SLJIT_ASSERT(early_fail_ptr == 0);
- OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
- compile_char1_matchingpath(common, type, cc, &no_match, TRUE);
- OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
- set_jumps(no_match, LABEL());
- OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
- break;
-
- default:
- SLJIT_UNREACHABLE();
- break;
- }
-
-count_match(common);
-return end;
-}
-
-static SLJIT_INLINE PCRE2_SPTR compile_fail_accept_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
-{
-DEFINE_COMPILER;
-backtrack_common *backtrack;
-
-PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
-
-if (*cc == OP_FAIL)
- {
- add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
- return cc + 1;
- }
-
-if (*cc == OP_ACCEPT && common->currententry == NULL && (common->re->overall_options & PCRE2_ENDANCHORED) != 0)
- add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
-
-if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL || !common->might_be_empty)
- {
- /* No need to check notempty conditions. */
- if (common->accept_label == NULL)
- add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
- else
- JUMPTO(SLJIT_JUMP, common->accept_label);
- return cc + 1;
- }
-
-if (common->accept_label == NULL)
- add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)));
-else
- CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), common->accept_label);
-
-if (HAS_VIRTUAL_REGISTERS)
- {
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options));
- }
-else
- OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options));
-
-OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY);
-add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_NOT_ZERO));
-OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART);
-if (common->accept_label == NULL)
- add_jump(compiler, &common->accept, JUMP(SLJIT_ZERO));
-else
- JUMPTO(SLJIT_ZERO, common->accept_label);
-
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(HAS_VIRTUAL_REGISTERS ? TMP1 : ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));
-if (common->accept_label == NULL)
- add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0));
-else
- CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->accept_label);
-add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
-return cc + 1;
-}
-
-static SLJIT_INLINE PCRE2_SPTR compile_close_matchingpath(compiler_common *common, PCRE2_SPTR cc)
-{
-DEFINE_COMPILER;
-int offset = GET2(cc, 1);
-BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0;
-
-/* Data will be discarded anyway... */
-if (common->currententry != NULL)
- return cc + 1 + IMM2_SIZE;
-
-if (!optimized_cbracket)
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR_PRIV(offset));
-offset <<= 1;
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
-if (!optimized_cbracket)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
-return cc + 1 + IMM2_SIZE;
-}
-
-static SLJIT_INLINE PCRE2_SPTR compile_control_verb_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
-{
-DEFINE_COMPILER;
-backtrack_common *backtrack;
-PCRE2_UCHAR opcode = *cc;
-PCRE2_SPTR ccend = cc + 1;
-
-if (opcode == OP_COMMIT_ARG || opcode == OP_PRUNE_ARG ||
- opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG)
- ccend += 2 + cc[1];
-
-PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
-
-if (opcode == OP_SKIP)
- {
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- return ccend;
- }
-
-if (opcode == OP_COMMIT_ARG || opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG)
- {
- if (HAS_VIRTUAL_REGISTERS)
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(HAS_VIRTUAL_REGISTERS ? TMP1 : ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
- }
-
-return ccend;
-}
-
-static PCRE2_UCHAR then_trap_opcode[1] = { OP_THEN_TRAP };
-
-static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, backtrack_common *parent)
-{
-DEFINE_COMPILER;
-backtrack_common *backtrack;
-BOOL needs_control_head;
-int size;
-
-PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
-common->then_trap = BACKTRACK_AS(then_trap_backtrack);
-BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
-BACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start);
-BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head);
-
-size = BACKTRACK_AS(then_trap_backtrack)->framesize;
-size = 3 + (size < 0 ? 0 : size);
-
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
-allocate_stack(common, size);
-if (size > 3)
- OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw));
-else
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, BACKTRACK_AS(then_trap_backtrack)->start);
-OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), SLJIT_IMM, type_then_trap);
-OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 3), TMP2, 0);
-
-size = BACKTRACK_AS(then_trap_backtrack)->framesize;
-if (size >= 0)
- init_frame(common, cc, ccend, size - 1, 0);
-}
-
-static void compile_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, backtrack_common *parent)
-{
-DEFINE_COMPILER;
-backtrack_common *backtrack;
-BOOL has_then_trap = FALSE;
-then_trap_backtrack *save_then_trap = NULL;
-
-SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS));
-
-if (common->has_then && common->then_offsets[cc - common->start] != 0)
- {
- SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0);
- has_then_trap = TRUE;
- save_then_trap = common->then_trap;
- /* Tail item on backtrack. */
- compile_then_trap_matchingpath(common, cc, ccend, parent);
- }
-
-while (cc < ccend)
- {
- switch(*cc)
- {
- case OP_SOD:
- case OP_SOM:
- case OP_NOT_WORD_BOUNDARY:
- case OP_WORD_BOUNDARY:
- case OP_EODN:
- case OP_EOD:
- case OP_DOLL:
- case OP_DOLLM:
- case OP_CIRC:
- case OP_CIRCM:
- case OP_REVERSE:
- cc = compile_simple_assertion_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
- break;
-
- case OP_NOT_DIGIT:
- case OP_DIGIT:
- case OP_NOT_WHITESPACE:
- case OP_WHITESPACE:
- case OP_NOT_WORDCHAR:
- case OP_WORDCHAR:
- case OP_ANY:
- case OP_ALLANY:
- case OP_ANYBYTE:
- case OP_NOTPROP:
- case OP_PROP:
- case OP_ANYNL:
- case OP_NOT_HSPACE:
- case OP_HSPACE:
- case OP_NOT_VSPACE:
- case OP_VSPACE:
- case OP_EXTUNI:
- case OP_NOT:
- case OP_NOTI:
- cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);
- break;
-
- case OP_SET_SOM:
- PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
- cc++;
- break;
-
- case OP_CHAR:
- case OP_CHARI:
- if (common->mode == PCRE2_JIT_COMPLETE)
- cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
- else
- cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);
- break;
-
- case OP_STAR:
- case OP_MINSTAR:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_EXACT:
- case OP_POSSTAR:
- case OP_POSPLUS:
- case OP_POSQUERY:
- case OP_POSUPTO:
- case OP_STARI:
- case OP_MINSTARI:
- case OP_PLUSI:
- case OP_MINPLUSI:
- case OP_QUERYI:
- case OP_MINQUERYI:
- case OP_UPTOI:
- case OP_MINUPTOI:
- case OP_EXACTI:
- case OP_POSSTARI:
- case OP_POSPLUSI:
- case OP_POSQUERYI:
- case OP_POSUPTOI:
- case OP_NOTSTAR:
- case OP_NOTMINSTAR:
- case OP_NOTPLUS:
- case OP_NOTMINPLUS:
- case OP_NOTQUERY:
- case OP_NOTMINQUERY:
- case OP_NOTUPTO:
- case OP_NOTMINUPTO:
- case OP_NOTEXACT:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSPLUS:
- case OP_NOTPOSQUERY:
- case OP_NOTPOSUPTO:
- case OP_NOTSTARI:
- case OP_NOTMINSTARI:
- case OP_NOTPLUSI:
- case OP_NOTMINPLUSI:
- case OP_NOTQUERYI:
- case OP_NOTMINQUERYI:
- case OP_NOTUPTOI:
- case OP_NOTMINUPTOI:
- case OP_NOTEXACTI:
- case OP_NOTPOSSTARI:
- case OP_NOTPOSPLUSI:
- case OP_NOTPOSQUERYI:
- case OP_NOTPOSUPTOI:
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEEXACT:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSPLUS:
- case OP_TYPEPOSQUERY:
- case OP_TYPEPOSUPTO:
- cc = compile_iterator_matchingpath(common, cc, parent);
- break;
-
- case OP_CLASS:
- case OP_NCLASS:
- if (cc[1 + (32 / sizeof(PCRE2_UCHAR))] >= OP_CRSTAR && cc[1 + (32 / sizeof(PCRE2_UCHAR))] <= OP_CRPOSRANGE)
- cc = compile_iterator_matchingpath(common, cc, parent);
- else
- cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);
- break;
-
-#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
- case OP_XCLASS:
- if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRPOSRANGE)
- cc = compile_iterator_matchingpath(common, cc, parent);
- else
- cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);
- break;
-#endif
-
- case OP_REF:
- case OP_REFI:
- if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRPOSRANGE)
- cc = compile_ref_iterator_matchingpath(common, cc, parent);
- else
- {
- compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
- cc += 1 + IMM2_SIZE;
- }
- break;
-
- case OP_DNREF:
- case OP_DNREFI:
- if (cc[1 + 2 * IMM2_SIZE] >= OP_CRSTAR && cc[1 + 2 * IMM2_SIZE] <= OP_CRPOSRANGE)
- cc = compile_ref_iterator_matchingpath(common, cc, parent);
- else
- {
- compile_dnref_search(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
- compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
- cc += 1 + 2 * IMM2_SIZE;
- }
- break;
-
- case OP_RECURSE:
- cc = compile_recurse_matchingpath(common, cc, parent);
- break;
-
- case OP_CALLOUT:
- case OP_CALLOUT_STR:
- cc = compile_callout_matchingpath(common, cc, parent);
- break;
-
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
- cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
- break;
-
- case OP_BRAMINZERO:
- PUSH_BACKTRACK_NOVALUE(sizeof(braminzero_backtrack), cc);
- cc = bracketend(cc + 1);
- if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN)
- {
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
- }
- else
- {
- allocate_stack(common, 2);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
- }
- BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
- count_match(common);
- break;
-
- case OP_ASSERT_NA:
- case OP_ASSERTBACK_NA:
- case OP_ONCE:
- case OP_SCRIPT_RUN:
- case OP_BRA:
- case OP_CBRA:
- case OP_COND:
- case OP_SBRA:
- case OP_SCBRA:
- case OP_SCOND:
- cc = compile_bracket_matchingpath(common, cc, parent);
- break;
-
- case OP_BRAZERO:
- if (cc[1] > OP_ASSERTBACK_NOT)
- cc = compile_bracket_matchingpath(common, cc, parent);
- else
- {
- PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
- cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
- }
- break;
-
- case OP_BRAPOS:
- case OP_CBRAPOS:
- case OP_SBRAPOS:
- case OP_SCBRAPOS:
- case OP_BRAPOSZERO:
- cc = compile_bracketpos_matchingpath(common, cc, parent);
- break;
-
- case OP_MARK:
- PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
- SLJIT_ASSERT(common->mark_ptr != 0);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
- allocate_stack(common, common->has_skip_arg ? 5 : 1);
- if (HAS_VIRTUAL_REGISTERS)
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0), TMP2, 0);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(HAS_VIRTUAL_REGISTERS ? TMP1 : ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
- if (common->has_skip_arg)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
- }
- cc += 1 + 2 + cc[1];
- break;
-
- case OP_PRUNE:
- case OP_PRUNE_ARG:
- case OP_SKIP:
- case OP_SKIP_ARG:
- case OP_THEN:
- case OP_THEN_ARG:
- case OP_COMMIT:
- case OP_COMMIT_ARG:
- cc = compile_control_verb_matchingpath(common, cc, parent);
- break;
-
- case OP_FAIL:
- case OP_ACCEPT:
- case OP_ASSERT_ACCEPT:
- cc = compile_fail_accept_matchingpath(common, cc, parent);
- break;
-
- case OP_CLOSE:
- cc = compile_close_matchingpath(common, cc);
- break;
-
- case OP_SKIPZERO:
- cc = bracketend(cc + 1);
- break;
-
- default:
- SLJIT_UNREACHABLE();
- return;
- }
- if (cc == NULL)
- return;
- }
-
-if (has_then_trap)
- {
- /* Head item on backtrack. */
- PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
- BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
- BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap;
- common->then_trap = save_then_trap;
- }
-SLJIT_ASSERT(cc == ccend);
-}
-
-#undef PUSH_BACKTRACK
-#undef PUSH_BACKTRACK_NOVALUE
-#undef BACKTRACK_AS
-
-#define COMPILE_BACKTRACKINGPATH(current) \
- do \
- { \
- compile_backtrackingpath(common, (current)); \
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
- return; \
- } \
- while (0)
-
-#define CURRENT_AS(type) ((type *)current)
-
-static void compile_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
-{
-DEFINE_COMPILER;
-PCRE2_SPTR cc = current->cc;
-PCRE2_UCHAR opcode;
-PCRE2_UCHAR type;
-sljit_u32 max = 0, exact;
-struct sljit_label *label = NULL;
-struct sljit_jump *jump = NULL;
-jump_list *jumplist = NULL;
-PCRE2_SPTR end;
-int private_data_ptr = PRIVATE_DATA(cc);
-int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP);
-int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
-int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + SSIZE_OF(sw);
-
-cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end);
-
-switch(opcode)
- {
- case OP_STAR:
- case OP_UPTO:
- if (type == OP_ANYNL || type == OP_EXTUNI)
- {
- SLJIT_ASSERT(private_data_ptr == 0);
- set_jumps(CURRENT_AS(char_iterator_backtrack)->u.backtracks, LABEL());
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
- CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath);
- }
- else
- {
- if (CURRENT_AS(char_iterator_backtrack)->u.charpos.enabled)
- {
- OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
- OP1(SLJIT_MOV, TMP2, 0, base, offset1);
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
- jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
- label = LABEL();
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
- OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
- if (CURRENT_AS(char_iterator_backtrack)->u.charpos.othercasebit != 0)
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->u.charpos.othercasebit);
- CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->u.charpos.chr, CURRENT_AS(char_iterator_backtrack)->matchingpath);
- move_back(common, NULL, TRUE);
- CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP2, 0, label);
- }
- else
- {
- OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
- jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, base, offset1);
- move_back(common, NULL, TRUE);
- OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
- JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
- }
- JUMPHERE(jump);
- if (private_data_ptr == 0)
- free_stack(common, 2);
- }
- break;
-
- case OP_MINSTAR:
- OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
- compile_char1_matchingpath(common, type, cc, &jumplist, TRUE);
- OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
- JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
- set_jumps(jumplist, LABEL());
- if (private_data_ptr == 0)
- free_stack(common, 1);
- break;
-
- case OP_MINUPTO:
- OP1(SLJIT_MOV, TMP1, 0, base, offset1);
- OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
- OP2(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
- add_jump(compiler, &jumplist, JUMP(SLJIT_ZERO));
-
- OP1(SLJIT_MOV, base, offset1, TMP1, 0);
- compile_char1_matchingpath(common, type, cc, &jumplist, TRUE);
- OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
- JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
-
- set_jumps(jumplist, LABEL());
- if (private_data_ptr == 0)
- free_stack(common, 2);
- break;
-
- case OP_QUERY:
- OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
- OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
- CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath);
- jump = JUMP(SLJIT_JUMP);
- set_jumps(CURRENT_AS(char_iterator_backtrack)->u.backtracks, LABEL());
- OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
- OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
- JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
- JUMPHERE(jump);
- if (private_data_ptr == 0)
- free_stack(common, 1);
- break;
-
- case OP_MINQUERY:
- OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
- OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
- jump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
- compile_char1_matchingpath(common, type, cc, &jumplist, TRUE);
- JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
- set_jumps(jumplist, LABEL());
- JUMPHERE(jump);
- if (private_data_ptr == 0)
- free_stack(common, 1);
- break;
-
- case OP_EXACT:
- case OP_POSSTAR:
- case OP_POSQUERY:
- case OP_POSUPTO:
- break;
-
- default:
- SLJIT_UNREACHABLE();
- break;
- }
-
-set_jumps(current->topbacktracks, LABEL());
-}
-
-static SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
-{
-DEFINE_COMPILER;
-PCRE2_SPTR cc = current->cc;
-BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
-PCRE2_UCHAR type;
-
-type = cc[ref ? 1 + IMM2_SIZE : 1 + 2 * IMM2_SIZE];
-
-if ((type & 0x1) == 0)
- {
- /* Maximize case. */
- set_jumps(current->topbacktracks, LABEL());
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
- CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(ref_iterator_backtrack)->matchingpath);
- return;
- }
-
-OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
-CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(ref_iterator_backtrack)->matchingpath);
-set_jumps(current->topbacktracks, LABEL());
-free_stack(common, ref ? 2 : 3);
-}
-
-static SLJIT_INLINE void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)
-{
-DEFINE_COMPILER;
-recurse_entry *entry;
-
-if (!CURRENT_AS(recurse_backtrack)->inlined_pattern)
- {
- entry = CURRENT_AS(recurse_backtrack)->entry;
- if (entry->backtrack_label == NULL)
- add_jump(compiler, &entry->backtrack_calls, JUMP(SLJIT_FAST_CALL));
- else
- JUMPTO(SLJIT_FAST_CALL, entry->backtrack_label);
- CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(recurse_backtrack)->matchingpath);
- }
-else
- compile_backtrackingpath(common, current->top);
-
-set_jumps(current->topbacktracks, LABEL());
-}
-
-static void compile_assert_backtrackingpath(compiler_common *common, struct backtrack_common *current)
-{
-DEFINE_COMPILER;
-PCRE2_SPTR cc = current->cc;
-PCRE2_UCHAR bra = OP_BRA;
-struct sljit_jump *brajump = NULL;
-
-SLJIT_ASSERT(*cc != OP_BRAMINZERO);
-if (*cc == OP_BRAZERO)
- {
- bra = *cc;
- cc++;
- }
-
-if (bra == OP_BRAZERO)
- {
- SLJIT_ASSERT(current->topbacktracks == NULL);
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- }
-
-if (CURRENT_AS(assert_backtrack)->framesize < 0)
- {
- set_jumps(current->topbacktracks, LABEL());
-
- if (bra == OP_BRAZERO)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath);
- free_stack(common, 1);
- }
- return;
- }
-
-if (bra == OP_BRAZERO)
- {
- if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath);
- free_stack(common, 1);
- return;
- }
- free_stack(common, 1);
- brajump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
- }
-
-if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)
- {
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr);
- add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-2));
- OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (CURRENT_AS(assert_backtrack)->framesize - 1) * sizeof(sljit_sw));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr, TMP1, 0);
-
- set_jumps(current->topbacktracks, LABEL());
- }
-else
- set_jumps(current->topbacktracks, LABEL());
-
-if (bra == OP_BRAZERO)
- {
- /* We know there is enough place on the stack. */
- OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->matchingpath);
- JUMPHERE(brajump);
- }
-}
-
-static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)
-{
-DEFINE_COMPILER;
-int opcode, stacksize, alt_count, alt_max;
-int offset = 0;
-int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
-int repeat_ptr = 0, repeat_type = 0, repeat_count = 0;
-PCRE2_SPTR cc = current->cc;
-PCRE2_SPTR ccbegin;
-PCRE2_SPTR ccprev;
-PCRE2_UCHAR bra = OP_BRA;
-PCRE2_UCHAR ket;
-assert_backtrack *assert;
-BOOL has_alternatives;
-BOOL needs_control_head = FALSE;
-struct sljit_jump *brazero = NULL;
-struct sljit_jump *next_alt = NULL;
-struct sljit_jump *once = NULL;
-struct sljit_jump *cond = NULL;
-struct sljit_label *rmin_label = NULL;
-struct sljit_label *exact_label = NULL;
-struct sljit_put_label *put_label = NULL;
-
-if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
- {
- bra = *cc;
- cc++;
- }
-
-opcode = *cc;
-ccbegin = bracketend(cc) - 1 - LINK_SIZE;
-ket = *ccbegin;
-if (ket == OP_KET && PRIVATE_DATA(ccbegin) != 0)
- {
- repeat_ptr = PRIVATE_DATA(ccbegin);
- repeat_type = PRIVATE_DATA(ccbegin + 2);
- repeat_count = PRIVATE_DATA(ccbegin + 3);
- SLJIT_ASSERT(repeat_type != 0 && repeat_count != 0);
- if (repeat_type == OP_UPTO)
- ket = OP_KETRMAX;
- if (repeat_type == OP_MINUPTO)
- ket = OP_KETRMIN;
- }
-ccbegin = cc;
-cc += GET(cc, 1);
-has_alternatives = *cc == OP_ALT;
-if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
- has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_backtrack)->u.condfailed != NULL;
-if (opcode == OP_CBRA || opcode == OP_SCBRA)
- offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
-if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
- opcode = OP_SCOND;
-
-alt_max = has_alternatives ? no_alternatives(ccbegin) : 0;
-
-/* Decoding the needs_control_head in framesize. */
-if (opcode == OP_ONCE)
- {
- needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0;
- CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;
- }
-
-if (ket != OP_KET && repeat_type != 0)
- {
- /* TMP1 is used in OP_KETRMIN below. */
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
- if (repeat_type == OP_UPTO)
- OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0, SLJIT_IMM, 1);
- else
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0);
- }
-
-if (ket == OP_KETRMAX)
- {
- if (bra == OP_BRAZERO)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
- brazero = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
- }
- }
-else if (ket == OP_KETRMIN)
- {
- if (bra != OP_BRAMINZERO)
- {
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- if (repeat_type != 0)
- {
- /* TMP1 was set a few lines above. */
- CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
- /* Drop STR_PTR for non-greedy plus quantifier. */
- if (opcode != OP_ONCE)
- free_stack(common, 1);
- }
- else if (opcode >= OP_SBRA || opcode == OP_ONCE)
- {
- /* Checking zero-length iteration. */
- if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
- CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
- else
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), STACK(-CURRENT_AS(bracket_backtrack)->u.framesize - 2), CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
- }
- /* Drop STR_PTR for non-greedy plus quantifier. */
- if (opcode != OP_ONCE)
- free_stack(common, 1);
- }
- else
- JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
- }
- rmin_label = LABEL();
- if (repeat_type != 0)
- OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
- }
-else if (bra == OP_BRAZERO)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
- brazero = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
- }
-else if (repeat_type == OP_EXACT)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
- exact_label = LABEL();
- }
-
-if (offset != 0)
- {
- if (common->capture_last_ptr != 0)
- {
- SLJIT_ASSERT(common->optimized_cbracket[offset >> 1] == 0);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
- free_stack(common, 3);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP2, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0);
- }
- else if (common->optimized_cbracket[offset >> 1] == 0)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- free_stack(common, 2);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0);
- }
- }
-
-if (SLJIT_UNLIKELY(opcode == OP_ONCE))
- {
- if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
- {
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
- OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize - 1) * sizeof(sljit_sw));
- }
- once = JUMP(SLJIT_JUMP);
- }
-else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
- {
- if (has_alternatives)
- {
- /* Always exactly one alternative. */
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
-
- alt_max = 2;
- next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
- }
- }
-else if (has_alternatives)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
-
- if (alt_max > 3)
- {
- sljit_emit_ijump(compiler, SLJIT_JUMP, TMP1, 0);
-
- SLJIT_ASSERT(CURRENT_AS(bracket_backtrack)->u.matching_put_label);
- sljit_set_put_label(CURRENT_AS(bracket_backtrack)->u.matching_put_label, LABEL());
- sljit_emit_op0(compiler, SLJIT_ENDBR);
- }
- else
- next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
- }
-
-COMPILE_BACKTRACKINGPATH(current->top);
-if (current->topbacktracks)
- set_jumps(current->topbacktracks, LABEL());
-
-if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
- {
- /* Conditional block always has at most one alternative. */
- if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)
- {
- SLJIT_ASSERT(has_alternatives);
- assert = CURRENT_AS(bracket_backtrack)->u.assert;
- if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))
- {
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr);
- add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-2));
- OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (assert->framesize - 1) * sizeof(sljit_sw));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, TMP1, 0);
- }
- cond = JUMP(SLJIT_JUMP);
- set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());
- }
- else if (CURRENT_AS(bracket_backtrack)->u.condfailed != NULL)
- {
- SLJIT_ASSERT(has_alternatives);
- cond = JUMP(SLJIT_JUMP);
- set_jumps(CURRENT_AS(bracket_backtrack)->u.condfailed, LABEL());
- }
- else
- SLJIT_ASSERT(!has_alternatives);
- }
-
-if (has_alternatives)
- {
- alt_count = 1;
- do
- {
- current->top = NULL;
- current->topbacktracks = NULL;
- current->nextbacktracks = NULL;
- /* Conditional blocks always have an additional alternative, even if it is empty. */
- if (*cc == OP_ALT)
- {
- ccprev = cc + 1 + LINK_SIZE;
- cc += GET(cc, 1);
- if (opcode != OP_COND && opcode != OP_SCOND)
- {
- if (opcode != OP_ONCE)
- {
- if (private_data_ptr != 0)
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
- else
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- }
- else
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(needs_control_head ? 1 : 0));
- }
- compile_matchingpath(common, ccprev, cc, current);
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- return;
-
- if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA)
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
-
- if (opcode == OP_SCRIPT_RUN)
- match_script_run_common(common, private_data_ptr, current);
- }
-
- /* Instructions after the current alternative is successfully matched. */
- /* There is a similar code in compile_bracket_matchingpath. */
- if (opcode == OP_ONCE)
- match_once_common(common, ket, CURRENT_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);
-
- stacksize = 0;
- if (repeat_type == OP_MINUPTO)
- {
- /* We need to preserve the counter. TMP2 will be used below. */
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr);
- stacksize++;
- }
- if (ket != OP_KET || bra != OP_BRA)
- stacksize++;
- if (offset != 0)
- {
- if (common->capture_last_ptr != 0)
- stacksize++;
- if (common->optimized_cbracket[offset >> 1] == 0)
- stacksize += 2;
- }
- if (opcode != OP_ONCE)
- stacksize++;
-
- if (stacksize > 0)
- allocate_stack(common, stacksize);
-
- stacksize = 0;
- if (repeat_type == OP_MINUPTO)
- {
- /* TMP2 was set above. */
- OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
- stacksize++;
- }
-
- if (ket != OP_KET || bra != OP_BRA)
- {
- if (ket != OP_KET)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
- else
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
- stacksize++;
- }
-
- if (offset != 0)
- stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
-
- if (opcode != OP_ONCE)
- {
- if (alt_max <= 3)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, alt_count);
- else
- put_label = sljit_emit_put_label(compiler, SLJIT_MEM1(STACK_TOP), STACK(stacksize));
- }
-
- if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0)
- {
- /* If ket is not OP_KETRMAX, this code path is executed after the jump to alternative_matchingpath. */
- SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
- }
-
- JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);
-
- if (opcode != OP_ONCE)
- {
- if (alt_max <= 3)
- {
- JUMPHERE(next_alt);
- alt_count++;
- if (alt_count < alt_max)
- {
- SLJIT_ASSERT(alt_count == 2 && alt_max == 3);
- next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 1);
- }
- }
- else
- {
- sljit_set_put_label(put_label, LABEL());
- sljit_emit_op0(compiler, SLJIT_ENDBR);
- }
- }
-
- COMPILE_BACKTRACKINGPATH(current->top);
- if (current->topbacktracks)
- set_jumps(current->topbacktracks, LABEL());
- SLJIT_ASSERT(!current->nextbacktracks);
- }
- while (*cc == OP_ALT);
-
- if (cond != NULL)
- {
- SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
- assert = CURRENT_AS(bracket_backtrack)->u.assert;
- if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)
- {
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr);
- add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-2));
- OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (assert->framesize - 1) * sizeof(sljit_sw));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, TMP1, 0);
- }
- JUMPHERE(cond);
- }
-
- /* Free the STR_PTR. */
- if (private_data_ptr == 0)
- free_stack(common, 1);
- }
-
-if (offset != 0)
- {
- /* Using both tmp register is better for instruction scheduling. */
- if (common->optimized_cbracket[offset >> 1] != 0)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- free_stack(common, 2);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0);
- }
- else
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
- }
- }
-else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND)
- {
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
- }
-else if (opcode == OP_ONCE)
- {
- cc = ccbegin + GET(ccbegin, 1);
- stacksize = needs_control_head ? 1 : 0;
-
- if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
- {
- /* Reset head and drop saved frame. */
- stacksize += CURRENT_AS(bracket_backtrack)->u.framesize + ((ket != OP_KET || *cc == OP_ALT) ? 2 : 1);
- }
- else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
- {
- /* The STR_PTR must be released. */
- stacksize++;
- }
-
- if (stacksize > 0)
- free_stack(common, stacksize);
-
- JUMPHERE(once);
- /* Restore previous private_data_ptr */
- if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(-CURRENT_AS(bracket_backtrack)->u.framesize - 1));
- else if (ket == OP_KETRMIN)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- /* See the comment below. */
- free_stack(common, 2);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
- }
- }
-
-if (repeat_type == OP_EXACT)
- {
- OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0);
- CMPTO(SLJIT_LESS_EQUAL, TMP1, 0, SLJIT_IMM, repeat_count, exact_label);
- }
-else if (ket == OP_KETRMAX)
- {
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- if (bra != OP_BRAZERO)
- free_stack(common, 1);
-
- CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
- if (bra == OP_BRAZERO)
- {
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
- JUMPHERE(brazero);
- free_stack(common, 1);
- }
- }
-else if (ket == OP_KETRMIN)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
-
- /* OP_ONCE removes everything in case of a backtrack, so we don't
- need to explicitly release the STR_PTR. The extra release would
- affect badly the free_stack(2) above. */
- if (opcode != OP_ONCE)
- free_stack(common, 1);
- CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rmin_label);
- if (opcode == OP_ONCE)
- free_stack(common, bra == OP_BRAMINZERO ? 2 : 1);
- else if (bra == OP_BRAMINZERO)
- free_stack(common, 1);
- }
-else if (bra == OP_BRAZERO)
- {
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
- JUMPHERE(brazero);
- }
-}
-
-static SLJIT_INLINE void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)
-{
-DEFINE_COMPILER;
-int offset;
-struct sljit_jump *jump;
-
-if (CURRENT_AS(bracketpos_backtrack)->framesize < 0)
- {
- if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS)
- {
- offset = (GET2(current->cc, 1 + LINK_SIZE)) << 1;
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
- if (common->capture_last_ptr != 0)
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0);
- if (common->capture_last_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0);
- }
- set_jumps(current->topbacktracks, LABEL());
- free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
- return;
- }
-
-OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtrack)->private_data_ptr);
-add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
-OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (CURRENT_AS(bracketpos_backtrack)->framesize - 1) * sizeof(sljit_sw));
-
-if (current->topbacktracks)
- {
- jump = JUMP(SLJIT_JUMP);
- set_jumps(current->topbacktracks, LABEL());
- /* Drop the stack frame. */
- free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
- JUMPHERE(jump);
- }
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(-CURRENT_AS(bracketpos_backtrack)->framesize - 1));
-}
-
-static SLJIT_INLINE void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)
-{
-assert_backtrack backtrack;
-
-current->top = NULL;
-current->topbacktracks = NULL;
-current->nextbacktracks = NULL;
-if (current->cc[1] > OP_ASSERTBACK_NOT)
- {
- /* Manual call of compile_bracket_matchingpath and compile_bracket_backtrackingpath. */
- compile_bracket_matchingpath(common, current->cc, current);
- compile_bracket_backtrackingpath(common, current->top);
- }
-else
- {
- memset(&backtrack, 0, sizeof(backtrack));
- backtrack.common.cc = current->cc;
- backtrack.matchingpath = CURRENT_AS(braminzero_backtrack)->matchingpath;
- /* Manual call of compile_assert_matchingpath. */
- compile_assert_matchingpath(common, current->cc, &backtrack, FALSE);
- }
-SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
-}
-
-static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current)
-{
-DEFINE_COMPILER;
-PCRE2_UCHAR opcode = *current->cc;
-struct sljit_label *loop;
-struct sljit_jump *jump;
-
-if (opcode == OP_THEN || opcode == OP_THEN_ARG)
- {
- if (common->then_trap != NULL)
- {
- SLJIT_ASSERT(common->control_head_ptr != 0);
-
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, type_then_trap);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, common->then_trap->start);
- jump = JUMP(SLJIT_JUMP);
-
- loop = LABEL();
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- JUMPHERE(jump);
- CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0, loop);
- CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0, loop);
- add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP));
- return;
- }
- else if (!common->local_quit_available && common->in_positive_assertion)
- {
- add_jump(compiler, &common->positive_assertion_quit, JUMP(SLJIT_JUMP));
- return;
- }
- }
-
-if (common->local_quit_available)
- {
- /* Abort match with a fail. */
- if (common->quit_label == NULL)
- add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
- else
- JUMPTO(SLJIT_JUMP, common->quit_label);
- return;
- }
-
-if (opcode == OP_SKIP_ARG)
- {
- SLJIT_ASSERT(common->control_head_ptr != 0 && TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
- OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, SLJIT_FUNC_ADDR(do_search_mark));
-
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_R0, 0);
- add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, SLJIT_R0, 0, SLJIT_IMM, 0));
- return;
- }
-
-if (opcode == OP_SKIP)
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
-else
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, 0);
-add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP));
-}
-
-static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current)
-{
-DEFINE_COMPILER;
-struct sljit_jump *jump;
-int size;
-
-if (CURRENT_AS(then_trap_backtrack)->then_trap)
- {
- common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap;
- return;
- }
-
-size = CURRENT_AS(then_trap_backtrack)->framesize;
-size = 3 + (size < 0 ? 0 : size);
-
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 3));
-free_stack(common, size);
-jump = JUMP(SLJIT_JUMP);
-
-set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL());
-/* STACK_TOP is set by THEN. */
-if (CURRENT_AS(then_trap_backtrack)->framesize >= 0)
- {
- add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
- OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (CURRENT_AS(then_trap_backtrack)->framesize - 1) * sizeof(sljit_sw));
- }
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
-free_stack(common, 3);
-
-JUMPHERE(jump);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP1, 0);
-}
-
-static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
-{
-DEFINE_COMPILER;
-then_trap_backtrack *save_then_trap = common->then_trap;
-
-while (current)
- {
- if (current->nextbacktracks != NULL)
- set_jumps(current->nextbacktracks, LABEL());
- switch(*current->cc)
- {
- case OP_SET_SOM:
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), TMP1, 0);
- break;
-
- case OP_STAR:
- case OP_MINSTAR:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_EXACT:
- case OP_POSSTAR:
- case OP_POSPLUS:
- case OP_POSQUERY:
- case OP_POSUPTO:
- case OP_STARI:
- case OP_MINSTARI:
- case OP_PLUSI:
- case OP_MINPLUSI:
- case OP_QUERYI:
- case OP_MINQUERYI:
- case OP_UPTOI:
- case OP_MINUPTOI:
- case OP_EXACTI:
- case OP_POSSTARI:
- case OP_POSPLUSI:
- case OP_POSQUERYI:
- case OP_POSUPTOI:
- case OP_NOTSTAR:
- case OP_NOTMINSTAR:
- case OP_NOTPLUS:
- case OP_NOTMINPLUS:
- case OP_NOTQUERY:
- case OP_NOTMINQUERY:
- case OP_NOTUPTO:
- case OP_NOTMINUPTO:
- case OP_NOTEXACT:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSPLUS:
- case OP_NOTPOSQUERY:
- case OP_NOTPOSUPTO:
- case OP_NOTSTARI:
- case OP_NOTMINSTARI:
- case OP_NOTPLUSI:
- case OP_NOTMINPLUSI:
- case OP_NOTQUERYI:
- case OP_NOTMINQUERYI:
- case OP_NOTUPTOI:
- case OP_NOTMINUPTOI:
- case OP_NOTEXACTI:
- case OP_NOTPOSSTARI:
- case OP_NOTPOSPLUSI:
- case OP_NOTPOSQUERYI:
- case OP_NOTPOSUPTOI:
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEEXACT:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSPLUS:
- case OP_TYPEPOSQUERY:
- case OP_TYPEPOSUPTO:
- case OP_CLASS:
- case OP_NCLASS:
-#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
- case OP_XCLASS:
-#endif
- compile_iterator_backtrackingpath(common, current);
- break;
-
- case OP_REF:
- case OP_REFI:
- case OP_DNREF:
- case OP_DNREFI:
- compile_ref_iterator_backtrackingpath(common, current);
- break;
-
- case OP_RECURSE:
- compile_recurse_backtrackingpath(common, current);
- break;
-
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- compile_assert_backtrackingpath(common, current);
- break;
-
- case OP_ASSERT_NA:
- case OP_ASSERTBACK_NA:
- case OP_ONCE:
- case OP_SCRIPT_RUN:
- case OP_BRA:
- case OP_CBRA:
- case OP_COND:
- case OP_SBRA:
- case OP_SCBRA:
- case OP_SCOND:
- compile_bracket_backtrackingpath(common, current);
- break;
-
- case OP_BRAZERO:
- if (current->cc[1] > OP_ASSERTBACK_NOT)
- compile_bracket_backtrackingpath(common, current);
- else
- compile_assert_backtrackingpath(common, current);
- break;
-
- case OP_BRAPOS:
- case OP_CBRAPOS:
- case OP_SBRAPOS:
- case OP_SCBRAPOS:
- case OP_BRAPOSZERO:
- compile_bracketpos_backtrackingpath(common, current);
- break;
-
- case OP_BRAMINZERO:
- compile_braminzero_backtrackingpath(common, current);
- break;
-
- case OP_MARK:
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0));
- if (common->has_skip_arg)
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, common->has_skip_arg ? 5 : 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP1, 0);
- if (common->has_skip_arg)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP2, 0);
- break;
-
- case OP_THEN:
- case OP_THEN_ARG:
- case OP_PRUNE:
- case OP_PRUNE_ARG:
- case OP_SKIP:
- case OP_SKIP_ARG:
- compile_control_verb_backtrackingpath(common, current);
- break;
-
- case OP_COMMIT:
- case OP_COMMIT_ARG:
- if (!common->local_quit_available)
- OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);
- if (common->quit_label == NULL)
- add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
- else
- JUMPTO(SLJIT_JUMP, common->quit_label);
- break;
-
- case OP_CALLOUT:
- case OP_CALLOUT_STR:
- case OP_FAIL:
- case OP_ACCEPT:
- case OP_ASSERT_ACCEPT:
- set_jumps(current->topbacktracks, LABEL());
- break;
-
- case OP_THEN_TRAP:
- /* A virtual opcode for then traps. */
- compile_then_trap_backtrackingpath(common, current);
- break;
-
- default:
- SLJIT_UNREACHABLE();
- break;
- }
- current = current->prev;
- }
-common->then_trap = save_then_trap;
-}
-
-static SLJIT_INLINE void compile_recurse(compiler_common *common)
-{
-DEFINE_COMPILER;
-PCRE2_SPTR cc = common->start + common->currententry->start;
-PCRE2_SPTR ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
-PCRE2_SPTR ccend = bracketend(cc) - (1 + LINK_SIZE);
-uint32_t recurse_flags = 0;
-int private_data_size = get_recurse_data_length(common, ccbegin, ccend, &recurse_flags);
-int alt_count, alt_max, local_size;
-backtrack_common altbacktrack;
-jump_list *match = NULL;
-struct sljit_jump *next_alt = NULL;
-struct sljit_jump *accept_exit = NULL;
-struct sljit_label *quit;
-struct sljit_put_label *put_label = NULL;
-
-/* Recurse captures then. */
-common->then_trap = NULL;
-
-SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
-
-alt_max = no_alternatives(cc);
-alt_count = 0;
-
-/* Matching path. */
-SLJIT_ASSERT(common->currententry->entry_label == NULL && common->recursive_head_ptr != 0);
-common->currententry->entry_label = LABEL();
-set_jumps(common->currententry->entry_calls, common->currententry->entry_label);
-
-sljit_emit_fast_enter(compiler, TMP2, 0);
-count_match(common);
-
-local_size = (alt_max > 1) ? 2 : 1;
-
-/* (Reversed) stack layout:
- [private data][return address][optional: str ptr] ... [optional: alternative index][recursive_head_ptr] */
-
-allocate_stack(common, private_data_size + local_size);
-/* Save return address. */
-OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(local_size - 1), TMP2, 0);
-
-copy_recurse_data(common, ccbegin, ccend, recurse_copy_from_global, local_size, private_data_size + local_size, recurse_flags);
-
-/* This variable is saved and restored all time when we enter or exit from a recursive context. */
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, STACK_TOP, 0);
-
-if (recurse_flags & recurse_flag_control_head_found)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
-
-if (alt_max > 1)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
-
-memset(&altbacktrack, 0, sizeof(backtrack_common));
-common->quit_label = NULL;
-common->accept_label = NULL;
-common->quit = NULL;
-common->accept = NULL;
-altbacktrack.cc = ccbegin;
-cc += GET(cc, 1);
-while (1)
- {
- altbacktrack.top = NULL;
- altbacktrack.topbacktracks = NULL;
-
- if (altbacktrack.cc != ccbegin)
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
-
- compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- return;
-
- allocate_stack(common, (alt_max > 1 || (recurse_flags & recurse_flag_accept_found)) ? 2 : 1);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr);
-
- if (alt_max > 1 || (recurse_flags & recurse_flag_accept_found))
- {
- if (alt_max > 3)
- put_label = sljit_emit_put_label(compiler, SLJIT_MEM1(STACK_TOP), STACK(1));
- else
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, alt_count);
- }
-
- add_jump(compiler, &match, JUMP(SLJIT_JUMP));
-
- if (alt_count == 0)
- {
- /* Backtracking path entry. */
- SLJIT_ASSERT(common->currententry->backtrack_label == NULL);
- common->currententry->backtrack_label = LABEL();
- set_jumps(common->currententry->backtrack_calls, common->currententry->backtrack_label);
-
- sljit_emit_fast_enter(compiler, TMP1, 0);
-
- if (recurse_flags & recurse_flag_accept_found)
- accept_exit = CMP(SLJIT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, -1);
-
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- /* Save return address. */
- OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), STACK(local_size - 1), TMP1, 0);
-
- copy_recurse_data(common, ccbegin, ccend, recurse_swap_global, local_size, private_data_size + local_size, recurse_flags);
-
- if (alt_max > 1)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- free_stack(common, 2);
-
- if (alt_max > 3)
- {
- sljit_emit_ijump(compiler, SLJIT_JUMP, TMP1, 0);
- sljit_set_put_label(put_label, LABEL());
- sljit_emit_op0(compiler, SLJIT_ENDBR);
- }
- else
- next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
- }
- else
- free_stack(common, (recurse_flags & recurse_flag_accept_found) ? 2 : 1);
- }
- else if (alt_max > 3)
- {
- sljit_set_put_label(put_label, LABEL());
- sljit_emit_op0(compiler, SLJIT_ENDBR);
- }
- else
- {
- JUMPHERE(next_alt);
- if (alt_count + 1 < alt_max)
- {
- SLJIT_ASSERT(alt_count == 1 && alt_max == 3);
- next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 1);
- }
- }
-
- alt_count++;
-
- compile_backtrackingpath(common, altbacktrack.top);
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- return;
- set_jumps(altbacktrack.topbacktracks, LABEL());
-
- if (*cc != OP_ALT)
- break;
-
- altbacktrack.cc = cc + 1 + LINK_SIZE;
- cc += GET(cc, 1);
- }
-
-/* No alternative is matched. */
-
-quit = LABEL();
-
-copy_recurse_data(common, ccbegin, ccend, recurse_copy_private_to_global, local_size, private_data_size + local_size, recurse_flags);
-
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(local_size - 1));
-free_stack(common, private_data_size + local_size);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
-OP_SRC(SLJIT_FAST_RETURN, TMP2, 0);
-
-if (common->quit != NULL)
- {
- SLJIT_ASSERT(recurse_flags & recurse_flag_quit_found);
-
- set_jumps(common->quit, LABEL());
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr);
- copy_recurse_data(common, ccbegin, ccend, recurse_copy_shared_to_global, local_size, private_data_size + local_size, recurse_flags);
- JUMPTO(SLJIT_JUMP, quit);
- }
-
-if (recurse_flags & recurse_flag_accept_found)
- {
- JUMPHERE(accept_exit);
- free_stack(common, 2);
-
- /* Save return address. */
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(local_size - 1), TMP1, 0);
-
- copy_recurse_data(common, ccbegin, ccend, recurse_copy_kept_shared_to_global, local_size, private_data_size + local_size, recurse_flags);
-
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(local_size - 1));
- free_stack(common, private_data_size + local_size);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
- OP_SRC(SLJIT_FAST_RETURN, TMP2, 0);
- }
-
-if (common->accept != NULL)
- {
- SLJIT_ASSERT(recurse_flags & recurse_flag_accept_found);
-
- set_jumps(common->accept, LABEL());
-
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr);
- OP1(SLJIT_MOV, TMP2, 0, STACK_TOP, 0);
-
- allocate_stack(common, 2);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, -1);
- }
-
-set_jumps(match, LABEL());
-
-OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
-
-copy_recurse_data(common, ccbegin, ccend, recurse_swap_global, local_size, private_data_size + local_size, recurse_flags);
-
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), STACK(local_size - 1));
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1);
-OP_SRC(SLJIT_FAST_RETURN, TMP2, 0);
-}
-
-#undef COMPILE_BACKTRACKINGPATH
-#undef CURRENT_AS
-
-#define PUBLIC_JIT_COMPILE_CONFIGURATION_OPTIONS \
- (PCRE2_JIT_INVALID_UTF)
-
-static int jit_compile(pcre2_code *code, sljit_u32 mode)
-{
-pcre2_real_code *re = (pcre2_real_code *)code;
-struct sljit_compiler *compiler;
-backtrack_common rootbacktrack;
-compiler_common common_data;
-compiler_common *common = &common_data;
-const sljit_u8 *tables = re->tables;
-void *allocator_data = &re->memctl;
-int private_data_size;
-PCRE2_SPTR ccend;
-executable_functions *functions;
-void *executable_func;
-sljit_uw executable_size;
-sljit_uw total_length;
-struct sljit_label *mainloop_label = NULL;
-struct sljit_label *continue_match_label;
-struct sljit_label *empty_match_found_label = NULL;
-struct sljit_label *empty_match_backtrack_label = NULL;
-struct sljit_label *reset_match_label;
-struct sljit_label *quit_label;
-struct sljit_jump *jump;
-struct sljit_jump *minlength_check_failed = NULL;
-struct sljit_jump *empty_match = NULL;
-struct sljit_jump *end_anchor_failed = NULL;
-jump_list *reqcu_not_found = NULL;
-
-SLJIT_ASSERT(tables);
-
-#if HAS_VIRTUAL_REGISTERS == 1
-SLJIT_ASSERT(sljit_get_register_index(TMP3) < 0 && sljit_get_register_index(ARGUMENTS) < 0 && sljit_get_register_index(RETURN_ADDR) < 0);
-#elif HAS_VIRTUAL_REGISTERS == 0
-SLJIT_ASSERT(sljit_get_register_index(TMP3) >= 0 && sljit_get_register_index(ARGUMENTS) >= 0 && sljit_get_register_index(RETURN_ADDR) >= 0);
-#else
-#error "Invalid value for HAS_VIRTUAL_REGISTERS"
-#endif
-
-memset(&rootbacktrack, 0, sizeof(backtrack_common));
-memset(common, 0, sizeof(compiler_common));
-common->re = re;
-common->name_table = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code));
-rootbacktrack.cc = common->name_table + re->name_count * re->name_entry_size;
-
-#ifdef SUPPORT_UNICODE
-common->invalid_utf = (mode & PCRE2_JIT_INVALID_UTF) != 0;
-#endif /* SUPPORT_UNICODE */
-mode &= ~PUBLIC_JIT_COMPILE_CONFIGURATION_OPTIONS;
-
-common->start = rootbacktrack.cc;
-common->read_only_data_head = NULL;
-common->fcc = tables + fcc_offset;
-common->lcc = (sljit_sw)(tables + lcc_offset);
-common->mode = mode;
-common->might_be_empty = (re->minlength == 0) || (re->flags & PCRE2_MATCH_EMPTY);
-common->allow_empty_partial = (re->max_lookbehind > 0) || (re->flags & PCRE2_MATCH_EMPTY);
-common->nltype = NLTYPE_FIXED;
-switch(re->newline_convention)
- {
- case PCRE2_NEWLINE_CR: common->newline = CHAR_CR; break;
- case PCRE2_NEWLINE_LF: common->newline = CHAR_NL; break;
- case PCRE2_NEWLINE_CRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; break;
- case PCRE2_NEWLINE_ANY: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
- case PCRE2_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
- case PCRE2_NEWLINE_NUL: common->newline = CHAR_NUL; break;
- default: return PCRE2_ERROR_INTERNAL;
- }
-common->nlmax = READ_CHAR_MAX;
-common->nlmin = 0;
-if (re->bsr_convention == PCRE2_BSR_UNICODE)
- common->bsr_nltype = NLTYPE_ANY;
-else if (re->bsr_convention == PCRE2_BSR_ANYCRLF)
- common->bsr_nltype = NLTYPE_ANYCRLF;
-else
- {
-#ifdef BSR_ANYCRLF
- common->bsr_nltype = NLTYPE_ANYCRLF;
-#else
- common->bsr_nltype = NLTYPE_ANY;
-#endif
- }
-common->bsr_nlmax = READ_CHAR_MAX;
-common->bsr_nlmin = 0;
-common->endonly = (re->overall_options & PCRE2_DOLLAR_ENDONLY) != 0;
-common->ctypes = (sljit_sw)(tables + ctypes_offset);
-common->name_count = re->name_count;
-common->name_entry_size = re->name_entry_size;
-common->unset_backref = (re->overall_options & PCRE2_MATCH_UNSET_BACKREF) != 0;
-common->alt_circumflex = (re->overall_options & PCRE2_ALT_CIRCUMFLEX) != 0;
-#ifdef SUPPORT_UNICODE
-/* PCRE_UTF[16|32] have the same value as PCRE_UTF8. */
-common->utf = (re->overall_options & PCRE2_UTF) != 0;
-common->ucp = (re->overall_options & PCRE2_UCP) != 0;
-if (common->utf)
- {
- if (common->nltype == NLTYPE_ANY)
- common->nlmax = 0x2029;
- else if (common->nltype == NLTYPE_ANYCRLF)
- common->nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL;
- else
- {
- /* We only care about the first newline character. */
- common->nlmax = common->newline & 0xff;
- }
-
- if (common->nltype == NLTYPE_FIXED)
- common->nlmin = common->newline & 0xff;
- else
- common->nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL;
-
- if (common->bsr_nltype == NLTYPE_ANY)
- common->bsr_nlmax = 0x2029;
- else
- common->bsr_nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL;
- common->bsr_nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL;
- }
-else
- common->invalid_utf = FALSE;
-#endif /* SUPPORT_UNICODE */
-ccend = bracketend(common->start);
-
-/* Calculate the local space size on the stack. */
-common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw);
-common->optimized_cbracket = (sljit_u8 *)SLJIT_MALLOC(re->top_bracket + 1, allocator_data);
-if (!common->optimized_cbracket)
- return PCRE2_ERROR_NOMEMORY;
-#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1
-memset(common->optimized_cbracket, 0, re->top_bracket + 1);
-#else
-memset(common->optimized_cbracket, 1, re->top_bracket + 1);
-#endif
-
-SLJIT_ASSERT(*common->start == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
-#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2
-common->capture_last_ptr = common->ovector_start;
-common->ovector_start += sizeof(sljit_sw);
-#endif
-if (!check_opcode_types(common, common->start, ccend))
- {
- SLJIT_FREE(common->optimized_cbracket, allocator_data);
- return PCRE2_ERROR_NOMEMORY;
- }
-
-/* Checking flags and updating ovector_start. */
-if (mode == PCRE2_JIT_COMPLETE && (re->flags & PCRE2_LASTSET) != 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
- {
- common->req_char_ptr = common->ovector_start;
- common->ovector_start += sizeof(sljit_sw);
- }
-if (mode != PCRE2_JIT_COMPLETE)
- {
- common->start_used_ptr = common->ovector_start;
- common->ovector_start += sizeof(sljit_sw);
- if (mode == PCRE2_JIT_PARTIAL_SOFT)
- {
- common->hit_start = common->ovector_start;
- common->ovector_start += sizeof(sljit_sw);
- }
- }
-if ((re->overall_options & (PCRE2_FIRSTLINE | PCRE2_USE_OFFSET_LIMIT)) != 0)
- {
- common->match_end_ptr = common->ovector_start;
- common->ovector_start += sizeof(sljit_sw);
- }
-#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
-common->control_head_ptr = 1;
-#endif
-if (common->control_head_ptr != 0)
- {
- common->control_head_ptr = common->ovector_start;
- common->ovector_start += sizeof(sljit_sw);
- }
-if (common->has_set_som)
- {
- /* Saving the real start pointer is necessary. */
- common->start_ptr = common->ovector_start;
- common->ovector_start += sizeof(sljit_sw);
- }
-
-/* Aligning ovector to even number of sljit words. */
-if ((common->ovector_start & sizeof(sljit_sw)) != 0)
- common->ovector_start += sizeof(sljit_sw);
-
-if (common->start_ptr == 0)
- common->start_ptr = OVECTOR(0);
-
-/* Capturing brackets cannot be optimized if callouts are allowed. */
-if (common->capture_last_ptr != 0)
- memset(common->optimized_cbracket, 0, re->top_bracket + 1);
-
-SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
-common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);
-
-total_length = ccend - common->start;
-common->private_data_ptrs = (sljit_s32*)SLJIT_MALLOC(total_length * (sizeof(sljit_s32) + (common->has_then ? 1 : 0)), allocator_data);
-if (!common->private_data_ptrs)
- {
- SLJIT_FREE(common->optimized_cbracket, allocator_data);
- return PCRE2_ERROR_NOMEMORY;
- }
-memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_s32));
-
-private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);
-
-if ((re->overall_options & PCRE2_ANCHORED) == 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0 && !common->has_skip_in_assert_back)
- detect_early_fail(common, common->start, &private_data_size, 0, 0, TRUE);
-
-set_private_data_ptrs(common, &private_data_size, ccend);
-
-SLJIT_ASSERT(common->early_fail_start_ptr <= common->early_fail_end_ptr);
-
-if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
- {
- SLJIT_FREE(common->private_data_ptrs, allocator_data);
- SLJIT_FREE(common->optimized_cbracket, allocator_data);
- return PCRE2_ERROR_NOMEMORY;
- }
-
-if (common->has_then)
- {
- common->then_offsets = (sljit_u8 *)(common->private_data_ptrs + total_length);
- memset(common->then_offsets, 0, total_length);
- set_then_offsets(common, common->start, NULL);
- }
-
-compiler = sljit_create_compiler(allocator_data, NULL);
-if (!compiler)
- {
- SLJIT_FREE(common->optimized_cbracket, allocator_data);
- SLJIT_FREE(common->private_data_ptrs, allocator_data);
- return PCRE2_ERROR_NOMEMORY;
- }
-common->compiler = compiler;
-
-/* Main pcre2_jit_exec entry. */
-SLJIT_ASSERT((private_data_size & (sizeof(sljit_sw) - 1)) == 0);
-sljit_emit_enter(compiler, 0, SLJIT_ARGS1(W, W), 5, 5, 0, 0, private_data_size);
-
-/* Register init. */
-reset_ovector(common, (re->top_bracket + 1) * 2);
-if (common->req_char_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, SLJIT_R0, 0);
-
-OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_S0, 0);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_S0, 0);
-OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
-OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
-OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match));
-OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, end));
-OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, start));
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0);
-
-if (common->early_fail_start_ptr < common->early_fail_end_ptr)
- reset_early_fail(common);
-
-if (mode == PCRE2_JIT_PARTIAL_SOFT)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1);
-if (common->mark_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0);
-if (common->control_head_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
-
-/* Main part of the matching */
-if ((re->overall_options & PCRE2_ANCHORED) == 0)
- {
- mainloop_label = mainloop_entry(common);
- continue_match_label = LABEL();
- /* Forward search if possible. */
- if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
- {
- if (mode == PCRE2_JIT_COMPLETE && fast_forward_first_n_chars(common))
- ;
- else if ((re->flags & PCRE2_FIRSTSET) != 0)
- fast_forward_first_char(common);
- else if ((re->flags & PCRE2_STARTLINE) != 0)
- fast_forward_newline(common);
- else if ((re->flags & PCRE2_FIRSTMAPSET) != 0)
- fast_forward_start_bits(common);
- }
- }
-else
- continue_match_label = LABEL();
-
-if (mode == PCRE2_JIT_COMPLETE && re->minlength > 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
- {
- OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);
- OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(re->minlength));
- minlength_check_failed = CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0);
- }
-if (common->req_char_ptr != 0)
- reqcu_not_found = search_requested_char(common, (PCRE2_UCHAR)(re->last_codeunit), (re->flags & PCRE2_LASTCASELESS) != 0, (re->flags & PCRE2_FIRSTSET) != 0);
-
-/* Store the current STR_PTR in OVECTOR(0). */
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0);
-/* Copy the limit of allowed recursions. */
-OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH);
-if (common->capture_last_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, 0);
-if (common->fast_forward_bc_ptr != NULL)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), PRIVATE_DATA(common->fast_forward_bc_ptr + 1) >> 3, STR_PTR, 0);
-
-if (common->start_ptr != OVECTOR(0))
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_ptr, STR_PTR, 0);
-
-/* Copy the beginning of the string. */
-if (mode == PCRE2_JIT_PARTIAL_SOFT)
- {
- jump = CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
- JUMPHERE(jump);
- }
-else if (mode == PCRE2_JIT_PARTIAL_HARD)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
-
-compile_matchingpath(common, common->start, ccend, &rootbacktrack);
-if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- {
- sljit_free_compiler(compiler);
- SLJIT_FREE(common->optimized_cbracket, allocator_data);
- SLJIT_FREE(common->private_data_ptrs, allocator_data);
- PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);
- return PCRE2_ERROR_NOMEMORY;
- }
-
-if ((re->overall_options & PCRE2_ENDANCHORED) != 0)
- end_anchor_failed = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0);
-
-if (common->might_be_empty)
- {
- empty_match = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
- empty_match_found_label = LABEL();
- }
-
-common->accept_label = LABEL();
-if (common->accept != NULL)
- set_jumps(common->accept, common->accept_label);
-
-/* This means we have a match. Update the ovector. */
-copy_ovector(common, re->top_bracket + 1);
-common->quit_label = common->abort_label = LABEL();
-if (common->quit != NULL)
- set_jumps(common->quit, common->quit_label);
-if (common->abort != NULL)
- set_jumps(common->abort, common->abort_label);
-if (minlength_check_failed != NULL)
- SET_LABEL(minlength_check_failed, common->abort_label);
-
-sljit_emit_op0(compiler, SLJIT_SKIP_FRAMES_BEFORE_RETURN);
-sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
-
-if (common->failed_match != NULL)
- {
- SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE);
- set_jumps(common->failed_match, LABEL());
- OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);
- JUMPTO(SLJIT_JUMP, common->abort_label);
- }
-
-if ((re->overall_options & PCRE2_ENDANCHORED) != 0)
- JUMPHERE(end_anchor_failed);
-
-if (mode != PCRE2_JIT_COMPLETE)
- {
- common->partialmatchlabel = LABEL();
- set_jumps(common->partialmatch, common->partialmatchlabel);
- return_with_partial_match(common, common->quit_label);
- }
-
-if (common->might_be_empty)
- empty_match_backtrack_label = LABEL();
-compile_backtrackingpath(common, rootbacktrack.top);
-if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- {
- sljit_free_compiler(compiler);
- SLJIT_FREE(common->optimized_cbracket, allocator_data);
- SLJIT_FREE(common->private_data_ptrs, allocator_data);
- PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);
- return PCRE2_ERROR_NOMEMORY;
- }
-
-SLJIT_ASSERT(rootbacktrack.prev == NULL);
-reset_match_label = LABEL();
-
-if (mode == PCRE2_JIT_PARTIAL_SOFT)
- {
- /* Update hit_start only in the first time. */
- jump = CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, TMP1, 0);
- JUMPHERE(jump);
- }
-
-/* Check we have remaining characters. */
-if ((re->overall_options & PCRE2_ANCHORED) == 0 && common->match_end_ptr != 0)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
- }
-
-OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP),
- (common->fast_forward_bc_ptr != NULL) ? (PRIVATE_DATA(common->fast_forward_bc_ptr + 1) >> 3) : common->start_ptr);
-
-if ((re->overall_options & PCRE2_ANCHORED) == 0)
- {
- if (common->ff_newline_shortcut != NULL)
- {
- /* There cannot be more newlines if PCRE2_FIRSTLINE is set. */
- if ((re->overall_options & PCRE2_FIRSTLINE) == 0)
- {
- if (common->match_end_ptr != 0)
- {
- OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
- OP1(SLJIT_MOV, STR_END, 0, TMP1, 0);
- CMPTO(SLJIT_LESS, STR_PTR, 0, TMP1, 0, common->ff_newline_shortcut);
- OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
- }
- else
- CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, common->ff_newline_shortcut);
- }
- }
- else
- CMPTO(SLJIT_LESS, STR_PTR, 0, (common->match_end_ptr == 0) ? STR_END : TMP1, 0, mainloop_label);
- }
-
-/* No more remaining characters. */
-if (reqcu_not_found != NULL)
- set_jumps(reqcu_not_found, LABEL());
-
-if (mode == PCRE2_JIT_PARTIAL_SOFT)
- CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1, common->partialmatchlabel);
-
-OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);
-JUMPTO(SLJIT_JUMP, common->quit_label);
-
-flush_stubs(common);
-
-if (common->might_be_empty)
- {
- JUMPHERE(empty_match);
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options));
- OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY);
- JUMPTO(SLJIT_NOT_ZERO, empty_match_backtrack_label);
- OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART);
- JUMPTO(SLJIT_ZERO, empty_match_found_label);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
- CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label);
- JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);
- }
-
-common->fast_forward_bc_ptr = NULL;
-common->early_fail_start_ptr = 0;
-common->early_fail_end_ptr = 0;
-common->currententry = common->entries;
-common->local_quit_available = TRUE;
-quit_label = common->quit_label;
-if (common->currententry != NULL)
- {
- /* A free bit for each private data. */
- common->recurse_bitset_size = ((private_data_size / SSIZE_OF(sw)) + 7) >> 3;
- SLJIT_ASSERT(common->recurse_bitset_size > 0);
- common->recurse_bitset = (sljit_u8*)SLJIT_MALLOC(common->recurse_bitset_size, allocator_data);;
-
- if (common->recurse_bitset != NULL)
- {
- do
- {
- /* Might add new entries. */
- compile_recurse(common);
- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- break;
- flush_stubs(common);
- common->currententry = common->currententry->next;
- }
- while (common->currententry != NULL);
-
- SLJIT_FREE(common->recurse_bitset, allocator_data);
- }
-
- if (common->currententry != NULL)
- {
- /* The common->recurse_bitset has been freed. */
- SLJIT_ASSERT(sljit_get_compiler_error(compiler) || common->recurse_bitset == NULL);
-
- sljit_free_compiler(compiler);
- SLJIT_FREE(common->optimized_cbracket, allocator_data);
- SLJIT_FREE(common->private_data_ptrs, allocator_data);
- PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);
- return PCRE2_ERROR_NOMEMORY;
- }
- }
-common->local_quit_available = FALSE;
-common->quit_label = quit_label;
-
-/* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
-/* This is a (really) rare case. */
-set_jumps(common->stackalloc, LABEL());
-/* RETURN_ADDR is not a saved register. */
-sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
-
-SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
-
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, STR_PTR, 0);
-OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);
-OP2(SLJIT_SUB, SLJIT_R1, 0, STACK_LIMIT, 0, SLJIT_IMM, STACK_GROWTH_RATE);
-OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, stack));
-OP1(SLJIT_MOV, STACK_LIMIT, 0, TMP2, 0);
-
-sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, SLJIT_FUNC_ADDR(sljit_stack_resize));
-
-jump = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
-OP1(SLJIT_MOV, TMP2, 0, STACK_LIMIT, 0);
-OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_RETURN_REG, 0);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
-OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
-OP_SRC(SLJIT_FAST_RETURN, TMP1, 0);
-
-/* Allocation failed. */
-JUMPHERE(jump);
-/* We break the return address cache here, but this is a really rare case. */
-OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_JIT_STACKLIMIT);
-JUMPTO(SLJIT_JUMP, common->quit_label);
-
-/* Call limit reached. */
-set_jumps(common->calllimit, LABEL());
-OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_MATCHLIMIT);
-JUMPTO(SLJIT_JUMP, common->quit_label);
-
-if (common->revertframes != NULL)
- {
- set_jumps(common->revertframes, LABEL());
- do_revertframes(common);
- }
-if (common->wordboundary != NULL)
- {
- set_jumps(common->wordboundary, LABEL());
- check_wordboundary(common);
- }
-if (common->anynewline != NULL)
- {
- set_jumps(common->anynewline, LABEL());
- check_anynewline(common);
- }
-if (common->hspace != NULL)
- {
- set_jumps(common->hspace, LABEL());
- check_hspace(common);
- }
-if (common->vspace != NULL)
- {
- set_jumps(common->vspace, LABEL());
- check_vspace(common);
- }
-if (common->casefulcmp != NULL)
- {
- set_jumps(common->casefulcmp, LABEL());
- do_casefulcmp(common);
- }
-if (common->caselesscmp != NULL)
- {
- set_jumps(common->caselesscmp, LABEL());
- do_caselesscmp(common);
- }
-if (common->reset_match != NULL)
- {
- set_jumps(common->reset_match, LABEL());
- do_reset_match(common, (re->top_bracket + 1) * 2);
- CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label);
- OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
- JUMPTO(SLJIT_JUMP, reset_match_label);
- }
-#ifdef SUPPORT_UNICODE
-#if PCRE2_CODE_UNIT_WIDTH == 8
-if (common->utfreadchar != NULL)
- {
- set_jumps(common->utfreadchar, LABEL());
- do_utfreadchar(common);
- }
-if (common->utfreadtype8 != NULL)
- {
- set_jumps(common->utfreadtype8, LABEL());
- do_utfreadtype8(common);
- }
-if (common->utfpeakcharback != NULL)
- {
- set_jumps(common->utfpeakcharback, LABEL());
- do_utfpeakcharback(common);
- }
-#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
-#if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16
-if (common->utfreadchar_invalid != NULL)
- {
- set_jumps(common->utfreadchar_invalid, LABEL());
- do_utfreadchar_invalid(common);
- }
-if (common->utfreadnewline_invalid != NULL)
- {
- set_jumps(common->utfreadnewline_invalid, LABEL());
- do_utfreadnewline_invalid(common);
- }
-if (common->utfmoveback_invalid)
- {
- set_jumps(common->utfmoveback_invalid, LABEL());
- do_utfmoveback_invalid(common);
- }
-if (common->utfpeakcharback_invalid)
- {
- set_jumps(common->utfpeakcharback_invalid, LABEL());
- do_utfpeakcharback_invalid(common);
- }
-#endif /* PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16 */
-if (common->getucd != NULL)
- {
- set_jumps(common->getucd, LABEL());
- do_getucd(common);
- }
-if (common->getucdtype != NULL)
- {
- set_jumps(common->getucdtype, LABEL());
- do_getucdtype(common);
- }
-#endif /* SUPPORT_UNICODE */
-
-SLJIT_FREE(common->optimized_cbracket, allocator_data);
-SLJIT_FREE(common->private_data_ptrs, allocator_data);
-
-executable_func = sljit_generate_code(compiler);
-executable_size = sljit_get_generated_code_size(compiler);
-sljit_free_compiler(compiler);
-
-if (executable_func == NULL)
- {
- PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);
- return PCRE2_ERROR_NOMEMORY;
- }
-
-/* Reuse the function descriptor if possible. */
-if (re->executable_jit != NULL)
- functions = (executable_functions *)re->executable_jit;
-else
- {
- functions = SLJIT_MALLOC(sizeof(executable_functions), allocator_data);
- if (functions == NULL)
- {
- /* This case is highly unlikely since we just recently
- freed a lot of memory. Not impossible though. */
- sljit_free_code(executable_func, NULL);
- PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);
- return PCRE2_ERROR_NOMEMORY;
- }
- memset(functions, 0, sizeof(executable_functions));
- functions->top_bracket = re->top_bracket + 1;
- functions->limit_match = re->limit_match;
- re->executable_jit = functions;
- }
-
-/* Turn mode into an index. */
-if (mode == PCRE2_JIT_COMPLETE)
- mode = 0;
-else
- mode = (mode == PCRE2_JIT_PARTIAL_SOFT) ? 1 : 2;
-
-SLJIT_ASSERT(mode < JIT_NUMBER_OF_COMPILE_MODES);
-functions->executable_funcs[mode] = executable_func;
-functions->read_only_data_heads[mode] = common->read_only_data_head;
-functions->executable_sizes[mode] = executable_size;
-return 0;
-}
-
-#endif
-
-/*************************************************
-* JIT compile a Regular Expression *
-*************************************************/
-
-/* This function used JIT to convert a previously-compiled pattern into machine
-code.
-
-Arguments:
- code a compiled pattern
- options JIT option bits
-
-Returns: 0: success or (*NOJIT) was used
- <0: an error code
-*/
-
-#define PUBLIC_JIT_COMPILE_OPTIONS \
- (PCRE2_JIT_COMPLETE|PCRE2_JIT_PARTIAL_SOFT|PCRE2_JIT_PARTIAL_HARD|PCRE2_JIT_INVALID_UTF)
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_jit_compile(pcre2_code *code, uint32_t options)
-{
-pcre2_real_code *re = (pcre2_real_code *)code;
-#ifdef SUPPORT_JIT
-executable_functions *functions;
-static int executable_allocator_is_working = -1;
-#endif
-
-if (code == NULL)
- return PCRE2_ERROR_NULL;
-
-if ((options & ~PUBLIC_JIT_COMPILE_OPTIONS) != 0)
- return PCRE2_ERROR_JIT_BADOPTION;
-
-/* Support for invalid UTF was first introduced in JIT, with the option
-PCRE2_JIT_INVALID_UTF. Later, support was added to the interpreter, and the
-compile-time option PCRE2_MATCH_INVALID_UTF was created. This is now the
-preferred feature, with the earlier option deprecated. However, for backward
-compatibility, if the earlier option is set, it forces the new option so that
-if JIT matching falls back to the interpreter, there is still support for
-invalid UTF. However, if this function has already been successfully called
-without PCRE2_JIT_INVALID_UTF and without PCRE2_MATCH_INVALID_UTF (meaning that
-non-invalid-supporting JIT code was compiled), give an error.
-
-If in the future support for PCRE2_JIT_INVALID_UTF is withdrawn, the following
-actions are needed:
-
- 1. Remove the definition from pcre2.h.in and from the list in
- PUBLIC_JIT_COMPILE_OPTIONS above.
-
- 2. Replace PCRE2_JIT_INVALID_UTF with a local flag in this module.
-
- 3. Replace PCRE2_JIT_INVALID_UTF in pcre2_jit_test.c.
-
- 4. Delete the following short block of code. The setting of "re" and
- "functions" can be moved into the JIT-only block below, but if that is
- done, (void)re and (void)functions will be needed in the non-JIT case, to
- avoid compiler warnings.
-*/
-
-#ifdef SUPPORT_JIT
-functions = (executable_functions *)re->executable_jit;
-#endif
-
-if ((options & PCRE2_JIT_INVALID_UTF) != 0)
- {
- if ((re->overall_options & PCRE2_MATCH_INVALID_UTF) == 0)
- {
-#ifdef SUPPORT_JIT
- if (functions != NULL) return PCRE2_ERROR_JIT_BADOPTION;
-#endif
- re->overall_options |= PCRE2_MATCH_INVALID_UTF;
- }
- }
-
-/* The above tests are run with and without JIT support. This means that
-PCRE2_JIT_INVALID_UTF propagates back into the regex options (ensuring
-interpreter support) even in the absence of JIT. But now, if there is no JIT
-support, give an error return. */
-
-#ifndef SUPPORT_JIT
-return PCRE2_ERROR_JIT_BADOPTION;
-#else /* SUPPORT_JIT */
-
-/* There is JIT support. Do the necessary. */
-
-if ((re->flags & PCRE2_NOJIT) != 0) return 0;
-
-if (executable_allocator_is_working == -1)
- {
- /* Checks whether the executable allocator is working. This check
- might run multiple times in multi-threaded environments, but the
- result should not be affected by it. */
- void *ptr = SLJIT_MALLOC_EXEC(32, NULL);
- if (ptr != NULL)
- {
- SLJIT_FREE_EXEC(((sljit_u8*)(ptr)) + SLJIT_EXEC_OFFSET(ptr), NULL);
- executable_allocator_is_working = 1;
- }
- else executable_allocator_is_working = 0;
- }
-
-if (!executable_allocator_is_working)
- return PCRE2_ERROR_NOMEMORY;
-
-if ((re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0)
- options |= PCRE2_JIT_INVALID_UTF;
-
-if ((options & PCRE2_JIT_COMPLETE) != 0 && (functions == NULL
- || functions->executable_funcs[0] == NULL)) {
- uint32_t excluded_options = (PCRE2_JIT_PARTIAL_SOFT | PCRE2_JIT_PARTIAL_HARD);
- int result = jit_compile(code, options & ~excluded_options);
- if (result != 0)
- return result;
- }
-
-if ((options & PCRE2_JIT_PARTIAL_SOFT) != 0 && (functions == NULL
- || functions->executable_funcs[1] == NULL)) {
- uint32_t excluded_options = (PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_HARD);
- int result = jit_compile(code, options & ~excluded_options);
- if (result != 0)
- return result;
- }
-
-if ((options & PCRE2_JIT_PARTIAL_HARD) != 0 && (functions == NULL
- || functions->executable_funcs[2] == NULL)) {
- uint32_t excluded_options = (PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_SOFT);
- int result = jit_compile(code, options & ~excluded_options);
- if (result != 0)
- return result;
- }
-
-return 0;
-
-#endif /* SUPPORT_JIT */
-}
-
-/* JIT compiler uses an all-in-one approach. This improves security,
- since the code generator functions are not exported. */
-
-#define INCLUDED_FROM_PCRE2_JIT_COMPILE
-
-#include "pcre2_jit_match.c"
-#include "pcre2_jit_misc.c"
-
-/* End of pcre2_jit_compile.c */
diff --git a/contrib/libs/pcre2/src/pcre2_jit_match.c b/contrib/libs/pcre2/src/pcre2_jit_match.c
deleted file mode 100644
index 1ab3af073e..0000000000
--- a/contrib/libs/pcre2/src/pcre2_jit_match.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2018 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-#ifndef INCLUDED_FROM_PCRE2_JIT_COMPILE
-#error This file must be included from pcre2_jit_compile.c.
-#endif
-
-#ifdef SUPPORT_JIT
-
-static SLJIT_NOINLINE int jit_machine_stack_exec(jit_arguments *arguments, jit_function executable_func)
-{
-sljit_u8 local_space[MACHINE_STACK_SIZE];
-struct sljit_stack local_stack;
-
-local_stack.min_start = local_space;
-local_stack.start = local_space;
-local_stack.end = local_space + MACHINE_STACK_SIZE;
-local_stack.top = local_space + MACHINE_STACK_SIZE;
-arguments->stack = &local_stack;
-return executable_func(arguments);
-}
-
-#endif
-
-
-/*************************************************
-* Do a JIT pattern match *
-*************************************************/
-
-/* This function runs a JIT pattern match.
-
-Arguments:
- code points to the compiled expression
- subject points to the subject string
- length length of subject string (may contain binary zeros)
- start_offset where to start in the subject string
- options option bits
- match_data points to a match_data block
- mcontext points to a match context
-
-Returns: > 0 => success; value is the number of ovector pairs filled
- = 0 => success, but ovector is not big enough
- -1 => failed to match (PCRE_ERROR_NOMATCH)
- < -1 => some kind of unexpected problem
-*/
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_jit_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length,
- PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data,
- pcre2_match_context *mcontext)
-{
-#ifndef SUPPORT_JIT
-
-(void)code;
-(void)subject;
-(void)length;
-(void)start_offset;
-(void)options;
-(void)match_data;
-(void)mcontext;
-return PCRE2_ERROR_JIT_BADOPTION;
-
-#else /* SUPPORT_JIT */
-
-pcre2_real_code *re = (pcre2_real_code *)code;
-executable_functions *functions = (executable_functions *)re->executable_jit;
-pcre2_jit_stack *jit_stack;
-uint32_t oveccount = match_data->oveccount;
-uint32_t max_oveccount;
-union {
- void *executable_func;
- jit_function call_executable_func;
-} convert_executable_func;
-jit_arguments arguments;
-int rc;
-int index = 0;
-
-if ((options & PCRE2_PARTIAL_HARD) != 0)
- index = 2;
-else if ((options & PCRE2_PARTIAL_SOFT) != 0)
- index = 1;
-
-if (functions == NULL || functions->executable_funcs[index] == NULL)
- return PCRE2_ERROR_JIT_BADOPTION;
-
-/* Sanity checks should be handled by pcre2_match. */
-arguments.str = subject + start_offset;
-arguments.begin = subject;
-arguments.end = subject + length;
-arguments.match_data = match_data;
-arguments.startchar_ptr = subject;
-arguments.mark_ptr = NULL;
-arguments.options = options;
-
-if (mcontext != NULL)
- {
- arguments.callout = mcontext->callout;
- arguments.callout_data = mcontext->callout_data;
- arguments.offset_limit = mcontext->offset_limit;
- arguments.limit_match = (mcontext->match_limit < re->limit_match)?
- mcontext->match_limit : re->limit_match;
- if (mcontext->jit_callback != NULL)
- jit_stack = mcontext->jit_callback(mcontext->jit_callback_data);
- else
- jit_stack = (pcre2_jit_stack *)mcontext->jit_callback_data;
- }
-else
- {
- arguments.callout = NULL;
- arguments.callout_data = NULL;
- arguments.offset_limit = PCRE2_UNSET;
- arguments.limit_match = (MATCH_LIMIT < re->limit_match)?
- MATCH_LIMIT : re->limit_match;
- jit_stack = NULL;
- }
-
-
-max_oveccount = functions->top_bracket;
-if (oveccount > max_oveccount)
- oveccount = max_oveccount;
-arguments.oveccount = oveccount << 1;
-
-
-convert_executable_func.executable_func = functions->executable_funcs[index];
-if (jit_stack != NULL)
- {
- arguments.stack = (struct sljit_stack *)(jit_stack->stack);
- rc = convert_executable_func.call_executable_func(&arguments);
- }
-else
- rc = jit_machine_stack_exec(&arguments, convert_executable_func.call_executable_func);
-
-if (rc > (int)oveccount)
- rc = 0;
-match_data->code = re;
-match_data->subject = (rc >= 0 || rc == PCRE2_ERROR_PARTIAL)? subject : NULL;
-match_data->rc = rc;
-match_data->startchar = arguments.startchar_ptr - subject;
-match_data->leftchar = 0;
-match_data->rightchar = 0;
-match_data->mark = arguments.mark_ptr;
-match_data->matchedby = PCRE2_MATCHEDBY_JIT;
-
-return match_data->rc;
-
-#endif /* SUPPORT_JIT */
-}
-
-/* End of pcre2_jit_match.c */
diff --git a/contrib/libs/pcre2/src/pcre2_jit_misc.c b/contrib/libs/pcre2/src/pcre2_jit_misc.c
deleted file mode 100644
index bb6a5589cb..0000000000
--- a/contrib/libs/pcre2/src/pcre2_jit_misc.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-#ifndef INCLUDED_FROM_PCRE2_JIT_COMPILE
-#error This file must be included from pcre2_jit_compile.c.
-#endif
-
-
-
-/*************************************************
-* Free JIT read-only data *
-*************************************************/
-
-void
-PRIV(jit_free_rodata)(void *current, void *allocator_data)
-{
-#ifndef SUPPORT_JIT
-(void)current;
-(void)allocator_data;
-#else /* SUPPORT_JIT */
-void *next;
-
-SLJIT_UNUSED_ARG(allocator_data);
-
-while (current != NULL)
- {
- next = *(void**)current;
- SLJIT_FREE(current, allocator_data);
- current = next;
- }
-
-#endif /* SUPPORT_JIT */
-}
-
-/*************************************************
-* Free JIT compiled code *
-*************************************************/
-
-void
-PRIV(jit_free)(void *executable_jit, pcre2_memctl *memctl)
-{
-#ifndef SUPPORT_JIT
-(void)executable_jit;
-(void)memctl;
-#else /* SUPPORT_JIT */
-
-executable_functions *functions = (executable_functions *)executable_jit;
-void *allocator_data = memctl;
-int i;
-
-for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
- {
- if (functions->executable_funcs[i] != NULL)
- sljit_free_code(functions->executable_funcs[i], NULL);
- PRIV(jit_free_rodata)(functions->read_only_data_heads[i], allocator_data);
- }
-
-SLJIT_FREE(functions, allocator_data);
-
-#endif /* SUPPORT_JIT */
-}
-
-
-/*************************************************
-* Free unused JIT memory *
-*************************************************/
-
-PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
-pcre2_jit_free_unused_memory(pcre2_general_context *gcontext)
-{
-#ifndef SUPPORT_JIT
-(void)gcontext; /* Suppress warning */
-#else /* SUPPORT_JIT */
-SLJIT_UNUSED_ARG(gcontext);
-#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
-sljit_free_unused_memory_exec();
-#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
-#endif /* SUPPORT_JIT */
-}
-
-
-
-/*************************************************
-* Allocate a JIT stack *
-*************************************************/
-
-PCRE2_EXP_DEFN pcre2_jit_stack * PCRE2_CALL_CONVENTION
-pcre2_jit_stack_create(size_t startsize, size_t maxsize,
- pcre2_general_context *gcontext)
-{
-#ifndef SUPPORT_JIT
-
-(void)gcontext;
-(void)startsize;
-(void)maxsize;
-return NULL;
-
-#else /* SUPPORT_JIT */
-
-pcre2_jit_stack *jit_stack;
-
-if (startsize == 0 || maxsize == 0 || maxsize > SIZE_MAX - STACK_GROWTH_RATE)
- return NULL;
-if (startsize > maxsize)
- startsize = maxsize;
-startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
-maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
-
-jit_stack = PRIV(memctl_malloc)(sizeof(pcre2_real_jit_stack), (pcre2_memctl *)gcontext);
-if (jit_stack == NULL) return NULL;
-jit_stack->stack = sljit_allocate_stack(startsize, maxsize, &jit_stack->memctl);
-if (jit_stack->stack == NULL)
- {
- jit_stack->memctl.free(jit_stack, jit_stack->memctl.memory_data);
- return NULL;
- }
-return jit_stack;
-
-#endif
-}
-
-
-/*************************************************
-* Assign a JIT stack to a pattern *
-*************************************************/
-
-PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
-pcre2_jit_stack_assign(pcre2_match_context *mcontext, pcre2_jit_callback callback,
- void *callback_data)
-{
-#ifndef SUPPORT_JIT
-(void)mcontext;
-(void)callback;
-(void)callback_data;
-#else /* SUPPORT_JIT */
-
-if (mcontext == NULL) return;
-mcontext->jit_callback = callback;
-mcontext->jit_callback_data = callback_data;
-
-#endif /* SUPPORT_JIT */
-}
-
-
-/*************************************************
-* Free a JIT stack *
-*************************************************/
-
-PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
-pcre2_jit_stack_free(pcre2_jit_stack *jit_stack)
-{
-#ifndef SUPPORT_JIT
-(void)jit_stack;
-#else /* SUPPORT_JIT */
-if (jit_stack != NULL)
- {
- sljit_free_stack((struct sljit_stack *)(jit_stack->stack), &jit_stack->memctl);
- jit_stack->memctl.free(jit_stack, jit_stack->memctl.memory_data);
- }
-#endif /* SUPPORT_JIT */
-}
-
-
-/*************************************************
-* Get target CPU type *
-*************************************************/
-
-const char*
-PRIV(jit_get_target)(void)
-{
-#ifndef SUPPORT_JIT
-return "JIT is not supported";
-#else /* SUPPORT_JIT */
-return sljit_get_platform_name();
-#endif /* SUPPORT_JIT */
-}
-
-
-/*************************************************
-* Get size of JIT code *
-*************************************************/
-
-size_t
-PRIV(jit_get_size)(void *executable_jit)
-{
-#ifndef SUPPORT_JIT
-(void)executable_jit;
-return 0;
-#else /* SUPPORT_JIT */
-sljit_uw *executable_sizes = ((executable_functions *)executable_jit)->executable_sizes;
-SLJIT_COMPILE_ASSERT(JIT_NUMBER_OF_COMPILE_MODES == 3, number_of_compile_modes_changed);
-return executable_sizes[0] + executable_sizes[1] + executable_sizes[2];
-#endif
-}
-
-/* End of pcre2_jit_misc.c */
diff --git a/contrib/libs/pcre2/src/pcre2_jit_simd_inc.h b/contrib/libs/pcre2/src/pcre2_jit_simd_inc.h
deleted file mode 100644
index 6fcfac8f13..0000000000
--- a/contrib/libs/pcre2/src/pcre2_jit_simd_inc.h
+++ /dev/null
@@ -1,1858 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- This module by Zoltan Herczeg
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2019 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-#if !(defined SUPPORT_VALGRIND)
-
-#if ((defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
- || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X))
-
-typedef enum {
- vector_compare_match1,
- vector_compare_match1i,
- vector_compare_match2,
-} vector_compare_type;
-
-static SLJIT_INLINE sljit_u32 max_fast_forward_char_pair_offset(void)
-{
-#if PCRE2_CODE_UNIT_WIDTH == 8
-return 15;
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-return 7;
-#elif PCRE2_CODE_UNIT_WIDTH == 32
-return 3;
-#else
-#error "Unsupported unit width"
-#endif
-}
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-static struct sljit_jump *jump_if_utf_char_start(struct sljit_compiler *compiler, sljit_s32 reg)
-{
-#if PCRE2_CODE_UNIT_WIDTH == 8
-OP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xc0);
-return CMP(SLJIT_NOT_EQUAL, reg, 0, SLJIT_IMM, 0x80);
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-OP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xfc00);
-return CMP(SLJIT_NOT_EQUAL, reg, 0, SLJIT_IMM, 0xdc00);
-#else
-#error "Unknown code width"
-#endif
-}
-#endif
-
-#endif /* SLJIT_CONFIG_X86 || SLJIT_CONFIG_S390X */
-
-#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
-
-static sljit_s32 character_to_int32(PCRE2_UCHAR chr)
-{
-sljit_u32 value = chr;
-#if PCRE2_CODE_UNIT_WIDTH == 8
-#define SSE2_COMPARE_TYPE_INDEX 0
-return (sljit_s32)((value << 24) | (value << 16) | (value << 8) | value);
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-#define SSE2_COMPARE_TYPE_INDEX 1
-return (sljit_s32)((value << 16) | value);
-#elif PCRE2_CODE_UNIT_WIDTH == 32
-#define SSE2_COMPARE_TYPE_INDEX 2
-return (sljit_s32)(value);
-#else
-#error "Unsupported unit width"
-#endif
-}
-
-static void load_from_mem_sse2(struct sljit_compiler *compiler, sljit_s32 dst_xmm_reg, sljit_s32 src_general_reg, sljit_s8 offset)
-{
-sljit_u8 instruction[5];
-
-SLJIT_ASSERT(dst_xmm_reg < 8);
-SLJIT_ASSERT(src_general_reg < 8);
-
-/* MOVDQA xmm1, xmm2/m128 */
-instruction[0] = ((sljit_u8)offset & 0xf) == 0 ? 0x66 : 0xf3;
-instruction[1] = 0x0f;
-instruction[2] = 0x6f;
-
-if (offset == 0)
- {
- instruction[3] = (dst_xmm_reg << 3) | src_general_reg;
- sljit_emit_op_custom(compiler, instruction, 4);
- return;
- }
-
-instruction[3] = 0x40 | (dst_xmm_reg << 3) | src_general_reg;
-instruction[4] = (sljit_u8)offset;
-sljit_emit_op_custom(compiler, instruction, 5);
-}
-
-static void fast_forward_char_pair_sse2_compare(struct sljit_compiler *compiler, vector_compare_type compare_type,
- int step, sljit_s32 dst_ind, sljit_s32 cmp1_ind, sljit_s32 cmp2_ind, sljit_s32 tmp_ind)
-{
-sljit_u8 instruction[4];
-instruction[0] = 0x66;
-instruction[1] = 0x0f;
-
-SLJIT_ASSERT(step >= 0 && step <= 3);
-
-if (compare_type != vector_compare_match2)
- {
- if (step == 0)
- {
- if (compare_type == vector_compare_match1i)
- {
- /* POR xmm1, xmm2/m128 */
- /* instruction[0] = 0x66; */
- /* instruction[1] = 0x0f; */
- instruction[2] = 0xeb;
- instruction[3] = 0xc0 | (dst_ind << 3) | cmp2_ind;
- sljit_emit_op_custom(compiler, instruction, 4);
- }
- return;
- }
-
- if (step != 2)
- return;
-
- /* PCMPEQB/W/D xmm1, xmm2/m128 */
- /* instruction[0] = 0x66; */
- /* instruction[1] = 0x0f; */
- instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX;
- instruction[3] = 0xc0 | (dst_ind << 3) | cmp1_ind;
- sljit_emit_op_custom(compiler, instruction, 4);
- return;
- }
-
-switch (step)
- {
- case 0:
- /* MOVDQA xmm1, xmm2/m128 */
- /* instruction[0] = 0x66; */
- /* instruction[1] = 0x0f; */
- instruction[2] = 0x6f;
- instruction[3] = 0xc0 | (tmp_ind << 3) | dst_ind;
- sljit_emit_op_custom(compiler, instruction, 4);
- return;
-
- case 1:
- /* PCMPEQB/W/D xmm1, xmm2/m128 */
- /* instruction[0] = 0x66; */
- /* instruction[1] = 0x0f; */
- instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX;
- instruction[3] = 0xc0 | (dst_ind << 3) | cmp1_ind;
- sljit_emit_op_custom(compiler, instruction, 4);
- return;
-
- case 2:
- /* PCMPEQB/W/D xmm1, xmm2/m128 */
- /* instruction[0] = 0x66; */
- /* instruction[1] = 0x0f; */
- instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX;
- instruction[3] = 0xc0 | (tmp_ind << 3) | cmp2_ind;
- sljit_emit_op_custom(compiler, instruction, 4);
- return;
-
- case 3:
- /* POR xmm1, xmm2/m128 */
- /* instruction[0] = 0x66; */
- /* instruction[1] = 0x0f; */
- instruction[2] = 0xeb;
- instruction[3] = 0xc0 | (dst_ind << 3) | tmp_ind;
- sljit_emit_op_custom(compiler, instruction, 4);
- return;
- }
-}
-
-#define JIT_HAS_FAST_FORWARD_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SSE2))
-
-static void fast_forward_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset)
-{
-DEFINE_COMPILER;
-sljit_u8 instruction[8];
-struct sljit_label *start;
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-struct sljit_label *restart;
-#endif
-struct sljit_jump *quit;
-struct sljit_jump *partial_quit[2];
-vector_compare_type compare_type = vector_compare_match1;
-sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1);
-sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR);
-sljit_s32 data_ind = 0;
-sljit_s32 tmp_ind = 1;
-sljit_s32 cmp1_ind = 2;
-sljit_s32 cmp2_ind = 3;
-sljit_u32 bit = 0;
-int i;
-
-SLJIT_UNUSED_ARG(offset);
-
-if (char1 != char2)
- {
- bit = char1 ^ char2;
- compare_type = vector_compare_match1i;
-
- if (!is_powerof2(bit))
- {
- bit = 0;
- compare_type = vector_compare_match2;
- }
- }
-
-partial_quit[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-if (common->mode == PCRE2_JIT_COMPLETE)
- add_jump(compiler, &common->failed_match, partial_quit[0]);
-
-/* First part (unaligned start) */
-
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1 | bit));
-
-SLJIT_ASSERT(tmp1_reg_ind < 8);
-
-/* MOVD xmm, r/m32 */
-instruction[0] = 0x66;
-instruction[1] = 0x0f;
-instruction[2] = 0x6e;
-instruction[3] = 0xc0 | (cmp1_ind << 3) | tmp1_reg_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-if (char1 != char2)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2));
-
- /* MOVD xmm, r/m32 */
- instruction[3] = 0xc0 | (cmp2_ind << 3) | tmp1_reg_ind;
- sljit_emit_op_custom(compiler, instruction, 4);
- }
-
-OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
-
-/* PSHUFD xmm1, xmm2/m128, imm8 */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0x70;
-instruction[3] = 0xc0 | (cmp1_ind << 3) | cmp1_ind;
-instruction[4] = 0;
-sljit_emit_op_custom(compiler, instruction, 5);
-
-if (char1 != char2)
- {
- /* PSHUFD xmm1, xmm2/m128, imm8 */
- instruction[3] = 0xc0 | (cmp2_ind << 3) | cmp2_ind;
- sljit_emit_op_custom(compiler, instruction, 5);
- }
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-restart = LABEL();
-#endif
-OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf);
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf);
-
-load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0);
-for (i = 0; i < 4; i++)
- fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
-
-/* PMOVMSKB reg, xmm */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0xd7;
-instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);
-
-quit = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0);
-
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-
-/* Second part (aligned) */
-start = LABEL();
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);
-
-partial_quit[1] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-if (common->mode == PCRE2_JIT_COMPLETE)
- add_jump(compiler, &common->failed_match, partial_quit[1]);
-
-load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0);
-for (i = 0; i < 4; i++)
- fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
-
-/* PMOVMSKB reg, xmm */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0xd7;
-instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start);
-
-JUMPHERE(quit);
-
-/* BSF r32, r/m32 */
-instruction[0] = 0x0f;
-instruction[1] = 0xbc;
-instruction[2] = 0xc0 | (tmp1_reg_ind << 3) | tmp1_reg_ind;
-sljit_emit_op_custom(compiler, instruction, 3);
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
-
-if (common->mode != PCRE2_JIT_COMPLETE)
- {
- JUMPHERE(partial_quit[0]);
- JUMPHERE(partial_quit[1]);
- OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0);
- CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0);
- }
-else
- add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-if (common->utf && offset > 0)
- {
- SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE);
-
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset));
-
- quit = jump_if_utf_char_start(compiler, TMP1);
-
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
- OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
- JUMPTO(SLJIT_JUMP, restart);
-
- JUMPHERE(quit);
- }
-#endif
-}
-
-#define JIT_HAS_FAST_REQUESTED_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SSE2))
-
-static jump_list *fast_requested_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2)
-{
-DEFINE_COMPILER;
-sljit_u8 instruction[8];
-struct sljit_label *start;
-struct sljit_jump *quit;
-jump_list *not_found = NULL;
-vector_compare_type compare_type = vector_compare_match1;
-sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1);
-sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR);
-sljit_s32 data_ind = 0;
-sljit_s32 tmp_ind = 1;
-sljit_s32 cmp1_ind = 2;
-sljit_s32 cmp2_ind = 3;
-sljit_u32 bit = 0;
-int i;
-
-if (char1 != char2)
- {
- bit = char1 ^ char2;
- compare_type = vector_compare_match1i;
-
- if (!is_powerof2(bit))
- {
- bit = 0;
- compare_type = vector_compare_match2;
- }
- }
-
-add_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));
-OP1(SLJIT_MOV, TMP2, 0, TMP1, 0);
-OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
-
-/* First part (unaligned start) */
-
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1 | bit));
-
-SLJIT_ASSERT(tmp1_reg_ind < 8);
-
-/* MOVD xmm, r/m32 */
-instruction[0] = 0x66;
-instruction[1] = 0x0f;
-instruction[2] = 0x6e;
-instruction[3] = 0xc0 | (cmp1_ind << 3) | tmp1_reg_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-if (char1 != char2)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2));
-
- /* MOVD xmm, r/m32 */
- instruction[3] = 0xc0 | (cmp2_ind << 3) | tmp1_reg_ind;
- sljit_emit_op_custom(compiler, instruction, 4);
- }
-
-OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0);
-
-/* PSHUFD xmm1, xmm2/m128, imm8 */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0x70;
-instruction[3] = 0xc0 | (cmp1_ind << 3) | cmp1_ind;
-instruction[4] = 0;
-sljit_emit_op_custom(compiler, instruction, 5);
-
-if (char1 != char2)
- {
- /* PSHUFD xmm1, xmm2/m128, imm8 */
- instruction[3] = 0xc0 | (cmp2_ind << 3) | cmp2_ind;
- sljit_emit_op_custom(compiler, instruction, 5);
- }
-
-OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf);
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf);
-
-load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0);
-for (i = 0; i < 4; i++)
- fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
-
-/* PMOVMSKB reg, xmm */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0xd7;
-instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);
-
-quit = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0);
-
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-
-/* Second part (aligned) */
-start = LABEL();
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);
-
-add_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
-
-load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0);
-for (i = 0; i < 4; i++)
- fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
-
-/* PMOVMSKB reg, xmm */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0xd7;
-instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start);
-
-JUMPHERE(quit);
-
-/* BSF r32, r/m32 */
-instruction[0] = 0x0f;
-instruction[1] = 0xbc;
-instruction[2] = 0xc0 | (tmp1_reg_ind << 3) | tmp1_reg_ind;
-sljit_emit_op_custom(compiler, instruction, 3);
-
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, STR_PTR, 0);
-add_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));
-
-OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
-return not_found;
-}
-
-#ifndef _WIN64
-
-#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SSE2))
-
-static void fast_forward_char_pair_simd(compiler_common *common, sljit_s32 offs1,
- PCRE2_UCHAR char1a, PCRE2_UCHAR char1b, sljit_s32 offs2, PCRE2_UCHAR char2a, PCRE2_UCHAR char2b)
-{
-DEFINE_COMPILER;
-sljit_u8 instruction[8];
-vector_compare_type compare1_type = vector_compare_match1;
-vector_compare_type compare2_type = vector_compare_match1;
-sljit_u32 bit1 = 0;
-sljit_u32 bit2 = 0;
-sljit_u32 diff = IN_UCHARS(offs1 - offs2);
-sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1);
-sljit_s32 tmp2_reg_ind = sljit_get_register_index(TMP2);
-sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR);
-sljit_s32 data1_ind = 0;
-sljit_s32 data2_ind = 1;
-sljit_s32 tmp1_ind = 2;
-sljit_s32 tmp2_ind = 3;
-sljit_s32 cmp1a_ind = 4;
-sljit_s32 cmp1b_ind = 5;
-sljit_s32 cmp2a_ind = 6;
-sljit_s32 cmp2b_ind = 7;
-struct sljit_label *start;
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-struct sljit_label *restart;
-#endif
-struct sljit_jump *jump[2];
-int i;
-
-SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2);
-SLJIT_ASSERT(diff <= IN_UCHARS(max_fast_forward_char_pair_offset()));
-SLJIT_ASSERT(tmp1_reg_ind < 8 && tmp2_reg_ind == 1);
-
-/* Initialize. */
-if (common->match_end_ptr != 0)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
- OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1));
-
- OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, STR_END, 0);
- CMOV(SLJIT_LESS, STR_END, TMP1, 0);
- }
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1));
-add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
-
-/* MOVD xmm, r/m32 */
-instruction[0] = 0x66;
-instruction[1] = 0x0f;
-instruction[2] = 0x6e;
-
-if (char1a == char1b)
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a));
-else
- {
- bit1 = char1a ^ char1b;
- if (is_powerof2(bit1))
- {
- compare1_type = vector_compare_match1i;
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a | bit1));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(bit1));
- }
- else
- {
- compare1_type = vector_compare_match2;
- bit1 = 0;
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(char1b));
- }
- }
-
-instruction[3] = 0xc0 | (cmp1a_ind << 3) | tmp1_reg_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-if (char1a != char1b)
- {
- instruction[3] = 0xc0 | (cmp1b_ind << 3) | tmp2_reg_ind;
- sljit_emit_op_custom(compiler, instruction, 4);
- }
-
-if (char2a == char2b)
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a));
-else
- {
- bit2 = char2a ^ char2b;
- if (is_powerof2(bit2))
- {
- compare2_type = vector_compare_match1i;
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a | bit2));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(bit2));
- }
- else
- {
- compare2_type = vector_compare_match2;
- bit2 = 0;
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(char2b));
- }
- }
-
-instruction[3] = 0xc0 | (cmp2a_ind << 3) | tmp1_reg_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-if (char2a != char2b)
- {
- instruction[3] = 0xc0 | (cmp2b_ind << 3) | tmp2_reg_ind;
- sljit_emit_op_custom(compiler, instruction, 4);
- }
-
-/* PSHUFD xmm1, xmm2/m128, imm8 */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0x70;
-instruction[4] = 0;
-
-instruction[3] = 0xc0 | (cmp1a_ind << 3) | cmp1a_ind;
-sljit_emit_op_custom(compiler, instruction, 5);
-
-if (char1a != char1b)
- {
- instruction[3] = 0xc0 | (cmp1b_ind << 3) | cmp1b_ind;
- sljit_emit_op_custom(compiler, instruction, 5);
- }
-
-instruction[3] = 0xc0 | (cmp2a_ind << 3) | cmp2a_ind;
-sljit_emit_op_custom(compiler, instruction, 5);
-
-if (char2a != char2b)
- {
- instruction[3] = 0xc0 | (cmp2b_ind << 3) | cmp2b_ind;
- sljit_emit_op_custom(compiler, instruction, 5);
- }
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-restart = LABEL();
-#endif
-
-OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, diff);
-OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
-OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf);
-
-load_from_mem_sse2(compiler, data1_ind, str_ptr_reg_ind, 0);
-
-jump[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_PTR, 0);
-
-load_from_mem_sse2(compiler, data2_ind, str_ptr_reg_ind, -(sljit_s8)diff);
-jump[1] = JUMP(SLJIT_JUMP);
-
-JUMPHERE(jump[0]);
-
-/* MOVDQA xmm1, xmm2/m128 */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0x6f;
-instruction[3] = 0xc0 | (data2_ind << 3) | data1_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-/* PSLLDQ xmm1, imm8 */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0x73;
-instruction[3] = 0xc0 | (7 << 3) | data2_ind;
-instruction[4] = diff;
-sljit_emit_op_custom(compiler, instruction, 5);
-
-JUMPHERE(jump[1]);
-
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf);
-
-for (i = 0; i < 4; i++)
- {
- fast_forward_char_pair_sse2_compare(compiler, compare2_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp2_ind);
- fast_forward_char_pair_sse2_compare(compiler, compare1_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind);
- }
-
-/* PAND xmm1, xmm2/m128 */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0xdb;
-instruction[3] = 0xc0 | (data1_ind << 3) | data2_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-/* PMOVMSKB reg, xmm */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0xd7;
-instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | 0;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-/* Ignore matches before the first STR_PTR. */
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);
-
-jump[0] = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0);
-
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-
-/* Main loop. */
-start = LABEL();
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);
-add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
-
-load_from_mem_sse2(compiler, data1_ind, str_ptr_reg_ind, 0);
-load_from_mem_sse2(compiler, data2_ind, str_ptr_reg_ind, -(sljit_s8)diff);
-
-for (i = 0; i < 4; i++)
- {
- fast_forward_char_pair_sse2_compare(compiler, compare1_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp2_ind);
- fast_forward_char_pair_sse2_compare(compiler, compare2_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp1_ind);
- }
-
-/* PAND xmm1, xmm2/m128 */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0xdb;
-instruction[3] = 0xc0 | (data1_ind << 3) | data2_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-/* PMOVMSKB reg, xmm */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0xd7;
-instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | 0;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start);
-
-JUMPHERE(jump[0]);
-
-/* BSF r32, r/m32 */
-instruction[0] = 0x0f;
-instruction[1] = 0xbc;
-instruction[2] = 0xc0 | (tmp1_reg_ind << 3) | tmp1_reg_ind;
-sljit_emit_op_custom(compiler, instruction, 3);
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
-
-add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-if (common->utf)
- {
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offs1));
-
- jump[0] = jump_if_utf_char_start(compiler, TMP1);
-
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, restart);
-
- add_jump(compiler, &common->failed_match, JUMP(SLJIT_JUMP));
-
- JUMPHERE(jump[0]);
- }
-#endif
-
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1));
-
-if (common->match_end_ptr != 0)
- OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
-}
-
-#endif /* !_WIN64 */
-
-#undef SSE2_COMPARE_TYPE_INDEX
-
-#endif /* SLJIT_CONFIG_X86 */
-
-#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64 && (defined __ARM_NEON || defined __ARM_NEON__))
-
-#include <arm_neon.h>
-
-typedef union {
- unsigned int x;
- struct { unsigned char c1, c2, c3, c4; } c;
-} int_char;
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-static SLJIT_INLINE int utf_continue(PCRE2_SPTR s)
-{
-#if PCRE2_CODE_UNIT_WIDTH == 8
-return (*s & 0xc0) == 0x80;
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-return (*s & 0xfc00) == 0xdc00;
-#else
-#error "Unknown code width"
-#endif
-}
-#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
-# define VECTOR_FACTOR 16
-# define vect_t uint8x16_t
-# define VLD1Q(X) vld1q_u8((sljit_u8 *)(X))
-# define VCEQQ vceqq_u8
-# define VORRQ vorrq_u8
-# define VST1Q vst1q_u8
-# define VDUPQ vdupq_n_u8
-# define VEXTQ vextq_u8
-# define VANDQ vandq_u8
-typedef union {
- uint8_t mem[16];
- uint64_t dw[2];
-} quad_word;
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-# define VECTOR_FACTOR 8
-# define vect_t uint16x8_t
-# define VLD1Q(X) vld1q_u16((sljit_u16 *)(X))
-# define VCEQQ vceqq_u16
-# define VORRQ vorrq_u16
-# define VST1Q vst1q_u16
-# define VDUPQ vdupq_n_u16
-# define VEXTQ vextq_u16
-# define VANDQ vandq_u16
-typedef union {
- uint16_t mem[8];
- uint64_t dw[2];
-} quad_word;
-#else
-# define VECTOR_FACTOR 4
-# define vect_t uint32x4_t
-# define VLD1Q(X) vld1q_u32((sljit_u32 *)(X))
-# define VCEQQ vceqq_u32
-# define VORRQ vorrq_u32
-# define VST1Q vst1q_u32
-# define VDUPQ vdupq_n_u32
-# define VEXTQ vextq_u32
-# define VANDQ vandq_u32
-typedef union {
- uint32_t mem[4];
- uint64_t dw[2];
-} quad_word;
-#endif
-
-#define FFCS
-#error #include "pcre2_jit_neon_inc.h"
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-# define FF_UTF
-# error #include "pcre2_jit_neon_inc.h"
-# undef FF_UTF
-#endif
-#undef FFCS
-
-#define FFCS_2
-#error #include "pcre2_jit_neon_inc.h"
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-# define FF_UTF
-# error #include "pcre2_jit_neon_inc.h"
-# undef FF_UTF
-#endif
-#undef FFCS_2
-
-#define FFCS_MASK
-#error #include "pcre2_jit_neon_inc.h"
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-# define FF_UTF
-# error #include "pcre2_jit_neon_inc.h"
-# undef FF_UTF
-#endif
-#undef FFCS_MASK
-
-#define JIT_HAS_FAST_FORWARD_CHAR_SIMD 1
-
-static void fast_forward_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset)
-{
-DEFINE_COMPILER;
-int_char ic;
-struct sljit_jump *partial_quit;
-/* Save temporary registers. */
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STR_PTR, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP3, 0);
-
-/* Prepare function arguments */
-OP1(SLJIT_MOV, SLJIT_R0, 0, STR_END, 0);
-OP1(SLJIT_MOV, SLJIT_R1, 0, STR_PTR, 0);
-OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, offset);
-
-if (char1 == char2)
- {
- ic.c.c1 = char1;
- ic.c.c2 = char2;
- OP1(SLJIT_MOV, SLJIT_R4, 0, SLJIT_IMM, ic.x);
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (common->utf && offset > 0)
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcs_utf));
- else
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcs));
-#else
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcs));
-#endif
- }
-else
- {
- PCRE2_UCHAR mask = char1 ^ char2;
- if (is_powerof2(mask))
- {
- ic.c.c1 = char1 | mask;
- ic.c.c2 = mask;
- OP1(SLJIT_MOV, SLJIT_R4, 0, SLJIT_IMM, ic.x);
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (common->utf && offset > 0)
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcs_mask_utf));
- else
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcs_mask));
-#else
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcs_mask));
-#endif
- }
- else
- {
- ic.c.c1 = char1;
- ic.c.c2 = char2;
- OP1(SLJIT_MOV, SLJIT_R4, 0, SLJIT_IMM, ic.x);
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (common->utf && offset > 0)
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcs_2_utf));
- else
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcs_2));
-#else
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcs_2));
-#endif
- }
- }
-/* Restore registers. */
-OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
-OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
-
-/* Check return value. */
-partial_quit = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
-if (common->mode == PCRE2_JIT_COMPLETE)
- add_jump(compiler, &common->failed_match, partial_quit);
-
-/* Fast forward STR_PTR to the result of memchr. */
-OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
-
-if (common->mode != PCRE2_JIT_COMPLETE)
- JUMPHERE(partial_quit);
-}
-
-typedef enum {
- compare_match1,
- compare_match1i,
- compare_match2,
-} compare_type;
-
-static inline vect_t fast_forward_char_pair_compare(compare_type ctype, vect_t dst, vect_t cmp1, vect_t cmp2)
-{
-if (ctype == compare_match2)
- {
- vect_t tmp = dst;
- dst = VCEQQ(dst, cmp1);
- tmp = VCEQQ(tmp, cmp2);
- dst = VORRQ(dst, tmp);
- return dst;
- }
-
-if (ctype == compare_match1i)
- dst = VORRQ(dst, cmp2);
-dst = VCEQQ(dst, cmp1);
-return dst;
-}
-
-static SLJIT_INLINE sljit_u32 max_fast_forward_char_pair_offset(void)
-{
-#if PCRE2_CODE_UNIT_WIDTH == 8
-return 15;
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-return 7;
-#elif PCRE2_CODE_UNIT_WIDTH == 32
-return 3;
-#else
-#error "Unsupported unit width"
-#endif
-}
-
-/* ARM doesn't have a shift left across lanes. */
-static SLJIT_INLINE vect_t shift_left_n_lanes(vect_t a, sljit_u8 n)
-{
-vect_t zero = VDUPQ(0);
-SLJIT_ASSERT(0 < n && n < VECTOR_FACTOR);
-/* VEXTQ takes an immediate as last argument. */
-#define C(X) case X: return VEXTQ(zero, a, VECTOR_FACTOR - X);
-switch (n)
- {
- C(1); C(2); C(3);
-#if PCRE2_CODE_UNIT_WIDTH != 32
- C(4); C(5); C(6); C(7);
-# if PCRE2_CODE_UNIT_WIDTH != 16
- C(8); C(9); C(10); C(11); C(12); C(13); C(14); C(15);
-# endif
-#endif
- default:
- /* Based on the ASSERT(0 < n && n < VECTOR_FACTOR) above, this won't
- happen. The return is still here for compilers to not warn. */
- return a;
- }
-}
-
-#define FFCPS
-#define FFCPS_DIFF1
-#define FFCPS_CHAR1A2A
-
-#define FFCPS_0
-#error #include "pcre2_jit_neon_inc.h"
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-# define FF_UTF
-# error #include "pcre2_jit_neon_inc.h"
-# undef FF_UTF
-#endif
-#undef FFCPS_0
-
-#undef FFCPS_CHAR1A2A
-
-#define FFCPS_1
-#error #include "pcre2_jit_neon_inc.h"
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-# define FF_UTF
-# error #include "pcre2_jit_neon_inc.h"
-# undef FF_UTF
-#endif
-#undef FFCPS_1
-
-#undef FFCPS_DIFF1
-
-#define FFCPS_DEFAULT
-#error #include "pcre2_jit_neon_inc.h"
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-# define FF_UTF
-# error #include "pcre2_jit_neon_inc.h"
-# undef FF_UTF
-#endif
-#undef FFCPS
-
-#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD 1
-
-static void fast_forward_char_pair_simd(compiler_common *common, sljit_s32 offs1,
- PCRE2_UCHAR char1a, PCRE2_UCHAR char1b, sljit_s32 offs2, PCRE2_UCHAR char2a, PCRE2_UCHAR char2b)
-{
-DEFINE_COMPILER;
-sljit_u32 diff = IN_UCHARS(offs1 - offs2);
-struct sljit_jump *partial_quit;
-int_char ic;
-SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2);
-SLJIT_ASSERT(diff <= IN_UCHARS(max_fast_forward_char_pair_offset()));
-SLJIT_ASSERT(compiler->scratches == 5);
-
-/* Save temporary register STR_PTR. */
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STR_PTR, 0);
-
-/* Prepare arguments for the function call. */
-if (common->match_end_ptr == 0)
- OP1(SLJIT_MOV, SLJIT_R0, 0, STR_END, 0);
-else
- {
- OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
- OP2(SLJIT_ADD, SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1));
-
- OP2U(SLJIT_SUB | SLJIT_SET_LESS, STR_END, 0, SLJIT_R0, 0);
- CMOV(SLJIT_LESS, SLJIT_R0, STR_END, 0);
- }
-
-OP1(SLJIT_MOV, SLJIT_R1, 0, STR_PTR, 0);
-OP1(SLJIT_MOV_S32, SLJIT_R2, 0, SLJIT_IMM, offs1);
-OP1(SLJIT_MOV_S32, SLJIT_R3, 0, SLJIT_IMM, offs2);
-ic.c.c1 = char1a;
-ic.c.c2 = char1b;
-ic.c.c3 = char2a;
-ic.c.c4 = char2b;
-OP1(SLJIT_MOV_U32, SLJIT_R4, 0, SLJIT_IMM, ic.x);
-
-if (diff == 1) {
- if (char1a == char1b && char2a == char2b) {
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (common->utf)
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcps_0_utf));
- else
-#endif
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcps_0));
- } else {
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (common->utf)
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcps_1_utf));
- else
-#endif
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcps_1));
- }
-} else {
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (common->utf)
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcps_default_utf));
- else
-#endif
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcps_default));
-}
-
-/* Restore STR_PTR register. */
-OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
-
-/* Check return value. */
-partial_quit = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
-add_jump(compiler, &common->failed_match, partial_quit);
-
-/* Fast forward STR_PTR to the result of memchr. */
-OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
-
-JUMPHERE(partial_quit);
-}
-
-#endif /* SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64 */
-
-#if (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
-#define VECTOR_ELEMENT_SIZE 0
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-#define VECTOR_ELEMENT_SIZE 1
-#elif PCRE2_CODE_UNIT_WIDTH == 32
-#define VECTOR_ELEMENT_SIZE 2
-#else
-#error "Unsupported unit width"
-#endif
-
-static void load_from_mem_vector(struct sljit_compiler *compiler, BOOL vlbb, sljit_s32 dst_vreg,
- sljit_s32 base_reg, sljit_s32 index_reg)
-{
-sljit_u16 instruction[3];
-
-instruction[0] = (sljit_u16)(0xe700 | (dst_vreg << 4) | index_reg);
-instruction[1] = (sljit_u16)(base_reg << 12);
-instruction[2] = (sljit_u16)((0x8 << 8) | (vlbb ? 0x07 : 0x06));
-
-sljit_emit_op_custom(compiler, instruction, 6);
-}
-
-#if PCRE2_CODE_UNIT_WIDTH == 32
-
-static void replicate_imm_vector(struct sljit_compiler *compiler, int step, sljit_s32 dst_vreg,
- PCRE2_UCHAR chr, sljit_s32 tmp_general_reg)
-{
-sljit_u16 instruction[3];
-
-SLJIT_ASSERT(step >= 0 && step <= 1);
-
-if (chr < 0x7fff)
- {
- if (step == 1)
- return;
-
- /* VREPI */
- instruction[0] = (sljit_u16)(0xe700 | (dst_vreg << 4));
- instruction[1] = (sljit_u16)chr;
- instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0x8 << 8) | 0x45);
- sljit_emit_op_custom(compiler, instruction, 6);
- return;
- }
-
-if (step == 0)
- {
- OP1(SLJIT_MOV, tmp_general_reg, 0, SLJIT_IMM, chr);
-
- /* VLVG */
- instruction[0] = (sljit_u16)(0xe700 | (dst_vreg << 4) | sljit_get_register_index(tmp_general_reg));
- instruction[1] = 0;
- instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0x8 << 8) | 0x22);
- sljit_emit_op_custom(compiler, instruction, 6);
- return;
- }
-
-/* VREP */
-instruction[0] = (sljit_u16)(0xe700 | (dst_vreg << 4) | dst_vreg);
-instruction[1] = 0;
-instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0xc << 8) | 0x4d);
-sljit_emit_op_custom(compiler, instruction, 6);
-}
-
-#endif
-
-static void fast_forward_char_pair_sse2_compare(struct sljit_compiler *compiler, vector_compare_type compare_type,
- int step, sljit_s32 dst_ind, sljit_s32 cmp1_ind, sljit_s32 cmp2_ind, sljit_s32 tmp_ind)
-{
-sljit_u16 instruction[3];
-
-SLJIT_ASSERT(step >= 0 && step <= 2);
-
-if (step == 1)
- {
- /* VCEQ */
- instruction[0] = (sljit_u16)(0xe700 | (dst_ind << 4) | dst_ind);
- instruction[1] = (sljit_u16)(cmp1_ind << 12);
- instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0xe << 8) | 0xf8);
- sljit_emit_op_custom(compiler, instruction, 6);
- return;
- }
-
-if (compare_type != vector_compare_match2)
- {
- if (step == 0 && compare_type == vector_compare_match1i)
- {
- /* VO */
- instruction[0] = (sljit_u16)(0xe700 | (dst_ind << 4) | dst_ind);
- instruction[1] = (sljit_u16)(cmp2_ind << 12);
- instruction[2] = (sljit_u16)((0xe << 8) | 0x6a);
- sljit_emit_op_custom(compiler, instruction, 6);
- }
- return;
- }
-
-switch (step)
- {
- case 0:
- /* VCEQ */
- instruction[0] = (sljit_u16)(0xe700 | (tmp_ind << 4) | dst_ind);
- instruction[1] = (sljit_u16)(cmp2_ind << 12);
- instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0xe << 8) | 0xf8);
- sljit_emit_op_custom(compiler, instruction, 6);
- return;
-
- case 2:
- /* VO */
- instruction[0] = (sljit_u16)(0xe700 | (dst_ind << 4) | dst_ind);
- instruction[1] = (sljit_u16)(tmp_ind << 12);
- instruction[2] = (sljit_u16)((0xe << 8) | 0x6a);
- sljit_emit_op_custom(compiler, instruction, 6);
- return;
- }
-}
-
-#define JIT_HAS_FAST_FORWARD_CHAR_SIMD 1
-
-static void fast_forward_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset)
-{
-DEFINE_COMPILER;
-sljit_u16 instruction[3];
-struct sljit_label *start;
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-struct sljit_label *restart;
-#endif
-struct sljit_jump *quit;
-struct sljit_jump *partial_quit[2];
-vector_compare_type compare_type = vector_compare_match1;
-sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1);
-sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR);
-sljit_s32 data_ind = 0;
-sljit_s32 tmp_ind = 1;
-sljit_s32 cmp1_ind = 2;
-sljit_s32 cmp2_ind = 3;
-sljit_s32 zero_ind = 4;
-sljit_u32 bit = 0;
-int i;
-
-SLJIT_UNUSED_ARG(offset);
-
-if (char1 != char2)
- {
- bit = char1 ^ char2;
- compare_type = vector_compare_match1i;
-
- if (!is_powerof2(bit))
- {
- bit = 0;
- compare_type = vector_compare_match2;
- }
- }
-
-partial_quit[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-if (common->mode == PCRE2_JIT_COMPLETE)
- add_jump(compiler, &common->failed_match, partial_quit[0]);
-
-/* First part (unaligned start) */
-
-OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 16);
-
-#if PCRE2_CODE_UNIT_WIDTH != 32
-
-/* VREPI */
-instruction[0] = (sljit_u16)(0xe700 | (cmp1_ind << 4));
-instruction[1] = (sljit_u16)(char1 | bit);
-instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0x8 << 8) | 0x45);
-sljit_emit_op_custom(compiler, instruction, 6);
-
-if (char1 != char2)
- {
- /* VREPI */
- instruction[0] = (sljit_u16)(0xe700 | (cmp2_ind << 4));
- instruction[1] = (sljit_u16)(bit != 0 ? bit : char2);
- /* instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0x8 << 8) | 0x45); */
- sljit_emit_op_custom(compiler, instruction, 6);
- }
-
-#else /* PCRE2_CODE_UNIT_WIDTH == 32 */
-
-for (int i = 0; i < 2; i++)
- {
- replicate_imm_vector(compiler, i, cmp1_ind, char1 | bit, TMP1);
-
- if (char1 != char2)
- replicate_imm_vector(compiler, i, cmp2_ind, bit != 0 ? bit : char2, TMP1);
- }
-
-#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */
-
-if (compare_type == vector_compare_match2)
- {
- /* VREPI */
- instruction[0] = (sljit_u16)(0xe700 | (zero_ind << 4));
- instruction[1] = 0;
- instruction[2] = (sljit_u16)((0x8 << 8) | 0x45);
- sljit_emit_op_custom(compiler, instruction, 6);
- }
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-restart = LABEL();
-#endif
-
-load_from_mem_vector(compiler, TRUE, data_ind, str_ptr_reg_ind, 0);
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, ~15);
-
-if (compare_type != vector_compare_match2)
- {
- if (compare_type == vector_compare_match1i)
- fast_forward_char_pair_sse2_compare(compiler, compare_type, 0, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
-
- /* VFEE */
- instruction[0] = (sljit_u16)(0xe700 | (data_ind << 4) | data_ind);
- instruction[1] = (sljit_u16)((cmp1_ind << 12) | (1 << 4));
- instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0xe << 8) | 0x80);
- sljit_emit_op_custom(compiler, instruction, 6);
- }
-else
- {
- for (i = 0; i < 3; i++)
- fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
-
- /* VFENE */
- instruction[0] = (sljit_u16)(0xe700 | (data_ind << 4) | data_ind);
- instruction[1] = (sljit_u16)((zero_ind << 12) | (1 << 4));
- instruction[2] = (sljit_u16)((0xe << 8) | 0x81);
- sljit_emit_op_custom(compiler, instruction, 6);
- }
-
-/* VLGVB */
-instruction[0] = (sljit_u16)(0xe700 | (tmp1_reg_ind << 4) | data_ind);
-instruction[1] = 7;
-instruction[2] = (sljit_u16)((0x4 << 8) | 0x21);
-sljit_emit_op_custom(compiler, instruction, 6);
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
-quit = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0);
-
-OP2(SLJIT_SUB, STR_PTR, 0, TMP2, 0, SLJIT_IMM, 16);
-
-/* Second part (aligned) */
-start = LABEL();
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);
-
-partial_quit[1] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-if (common->mode == PCRE2_JIT_COMPLETE)
- add_jump(compiler, &common->failed_match, partial_quit[1]);
-
-load_from_mem_vector(compiler, TRUE, data_ind, str_ptr_reg_ind, 0);
-
-if (compare_type != vector_compare_match2)
- {
- if (compare_type == vector_compare_match1i)
- fast_forward_char_pair_sse2_compare(compiler, compare_type, 0, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
-
- /* VFEE */
- instruction[0] = (sljit_u16)(0xe700 | (data_ind << 4) | data_ind);
- instruction[1] = (sljit_u16)((cmp1_ind << 12) | (1 << 4));
- instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0xe << 8) | 0x80);
- sljit_emit_op_custom(compiler, instruction, 6);
- }
-else
- {
- for (i = 0; i < 3; i++)
- fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
-
- /* VFENE */
- instruction[0] = (sljit_u16)(0xe700 | (data_ind << 4) | data_ind);
- instruction[1] = (sljit_u16)((zero_ind << 12) | (1 << 4));
- instruction[2] = (sljit_u16)((0xe << 8) | 0x81);
- sljit_emit_op_custom(compiler, instruction, 6);
- }
-
-sljit_set_current_flags(compiler, SLJIT_SET_OVERFLOW);
-JUMPTO(SLJIT_OVERFLOW, start);
-
-/* VLGVB */
-instruction[0] = (sljit_u16)(0xe700 | (tmp1_reg_ind << 4) | data_ind);
-instruction[1] = 7;
-instruction[2] = (sljit_u16)((0x4 << 8) | 0x21);
-sljit_emit_op_custom(compiler, instruction, 6);
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
-
-JUMPHERE(quit);
-
-if (common->mode != PCRE2_JIT_COMPLETE)
- {
- JUMPHERE(partial_quit[0]);
- JUMPHERE(partial_quit[1]);
- OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0);
- CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0);
- }
-else
- add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-if (common->utf && offset > 0)
- {
- SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE);
-
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset));
-
- quit = jump_if_utf_char_start(compiler, TMP1);
-
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
-
- OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 16);
- JUMPTO(SLJIT_JUMP, restart);
-
- JUMPHERE(quit);
- }
-#endif
-}
-
-#define JIT_HAS_FAST_REQUESTED_CHAR_SIMD 1
-
-static jump_list *fast_requested_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2)
-{
-DEFINE_COMPILER;
-sljit_u16 instruction[3];
-struct sljit_label *start;
-struct sljit_jump *quit;
-jump_list *not_found = NULL;
-vector_compare_type compare_type = vector_compare_match1;
-sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1);
-sljit_s32 tmp3_reg_ind = sljit_get_register_index(TMP3);
-sljit_s32 data_ind = 0;
-sljit_s32 tmp_ind = 1;
-sljit_s32 cmp1_ind = 2;
-sljit_s32 cmp2_ind = 3;
-sljit_s32 zero_ind = 4;
-sljit_u32 bit = 0;
-int i;
-
-if (char1 != char2)
- {
- bit = char1 ^ char2;
- compare_type = vector_compare_match1i;
-
- if (!is_powerof2(bit))
- {
- bit = 0;
- compare_type = vector_compare_match2;
- }
- }
-
-add_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));
-
-/* First part (unaligned start) */
-
-OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, 16);
-
-#if PCRE2_CODE_UNIT_WIDTH != 32
-
-/* VREPI */
-instruction[0] = (sljit_u16)(0xe700 | (cmp1_ind << 4));
-instruction[1] = (sljit_u16)(char1 | bit);
-instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0x8 << 8) | 0x45);
-sljit_emit_op_custom(compiler, instruction, 6);
-
-if (char1 != char2)
- {
- /* VREPI */
- instruction[0] = (sljit_u16)(0xe700 | (cmp2_ind << 4));
- instruction[1] = (sljit_u16)(bit != 0 ? bit : char2);
- /* instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0x8 << 8) | 0x45); */
- sljit_emit_op_custom(compiler, instruction, 6);
- }
-
-#else /* PCRE2_CODE_UNIT_WIDTH == 32 */
-
-for (int i = 0; i < 2; i++)
- {
- replicate_imm_vector(compiler, i, cmp1_ind, char1 | bit, TMP3);
-
- if (char1 != char2)
- replicate_imm_vector(compiler, i, cmp2_ind, bit != 0 ? bit : char2, TMP3);
- }
-
-#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */
-
-if (compare_type == vector_compare_match2)
- {
- /* VREPI */
- instruction[0] = (sljit_u16)(0xe700 | (zero_ind << 4));
- instruction[1] = 0;
- instruction[2] = (sljit_u16)((0x8 << 8) | 0x45);
- sljit_emit_op_custom(compiler, instruction, 6);
- }
-
-load_from_mem_vector(compiler, TRUE, data_ind, tmp1_reg_ind, 0);
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, ~15);
-
-if (compare_type != vector_compare_match2)
- {
- if (compare_type == vector_compare_match1i)
- fast_forward_char_pair_sse2_compare(compiler, compare_type, 0, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
-
- /* VFEE */
- instruction[0] = (sljit_u16)(0xe700 | (data_ind << 4) | data_ind);
- instruction[1] = (sljit_u16)((cmp1_ind << 12) | (1 << 4));
- instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0xe << 8) | 0x80);
- sljit_emit_op_custom(compiler, instruction, 6);
- }
-else
- {
- for (i = 0; i < 3; i++)
- fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
-
- /* VFENE */
- instruction[0] = (sljit_u16)(0xe700 | (data_ind << 4) | data_ind);
- instruction[1] = (sljit_u16)((zero_ind << 12) | (1 << 4));
- instruction[2] = (sljit_u16)((0xe << 8) | 0x81);
- sljit_emit_op_custom(compiler, instruction, 6);
- }
-
-/* VLGVB */
-instruction[0] = (sljit_u16)(0xe700 | (tmp3_reg_ind << 4) | data_ind);
-instruction[1] = 7;
-instruction[2] = (sljit_u16)((0x4 << 8) | 0x21);
-sljit_emit_op_custom(compiler, instruction, 6);
-
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP3, 0);
-quit = CMP(SLJIT_LESS, TMP1, 0, TMP2, 0);
-
-OP2(SLJIT_SUB, TMP1, 0, TMP2, 0, SLJIT_IMM, 16);
-
-/* Second part (aligned) */
-start = LABEL();
-
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 16);
-
-add_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));
-
-load_from_mem_vector(compiler, TRUE, data_ind, tmp1_reg_ind, 0);
-
-if (compare_type != vector_compare_match2)
- {
- if (compare_type == vector_compare_match1i)
- fast_forward_char_pair_sse2_compare(compiler, compare_type, 0, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
-
- /* VFEE */
- instruction[0] = (sljit_u16)(0xe700 | (data_ind << 4) | data_ind);
- instruction[1] = (sljit_u16)((cmp1_ind << 12) | (1 << 4));
- instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0xe << 8) | 0x80);
- sljit_emit_op_custom(compiler, instruction, 6);
- }
-else
- {
- for (i = 0; i < 3; i++)
- fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
-
- /* VFENE */
- instruction[0] = (sljit_u16)(0xe700 | (data_ind << 4) | data_ind);
- instruction[1] = (sljit_u16)((zero_ind << 12) | (1 << 4));
- instruction[2] = (sljit_u16)((0xe << 8) | 0x81);
- sljit_emit_op_custom(compiler, instruction, 6);
- }
-
-sljit_set_current_flags(compiler, SLJIT_SET_OVERFLOW);
-JUMPTO(SLJIT_OVERFLOW, start);
-
-/* VLGVB */
-instruction[0] = (sljit_u16)(0xe700 | (tmp3_reg_ind << 4) | data_ind);
-instruction[1] = 7;
-instruction[2] = (sljit_u16)((0x4 << 8) | 0x21);
-sljit_emit_op_custom(compiler, instruction, 6);
-
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP3, 0);
-
-JUMPHERE(quit);
-add_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));
-
-return not_found;
-}
-
-#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD 1
-
-static void fast_forward_char_pair_simd(compiler_common *common, sljit_s32 offs1,
- PCRE2_UCHAR char1a, PCRE2_UCHAR char1b, sljit_s32 offs2, PCRE2_UCHAR char2a, PCRE2_UCHAR char2b)
-{
-DEFINE_COMPILER;
-sljit_u16 instruction[3];
-struct sljit_label *start;
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-struct sljit_label *restart;
-#endif
-struct sljit_jump *quit;
-struct sljit_jump *jump[2];
-vector_compare_type compare1_type = vector_compare_match1;
-vector_compare_type compare2_type = vector_compare_match1;
-sljit_u32 bit1 = 0;
-sljit_u32 bit2 = 0;
-sljit_s32 diff = IN_UCHARS(offs2 - offs1);
-sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1);
-sljit_s32 tmp2_reg_ind = sljit_get_register_index(TMP2);
-sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR);
-sljit_s32 data1_ind = 0;
-sljit_s32 data2_ind = 1;
-sljit_s32 tmp1_ind = 2;
-sljit_s32 tmp2_ind = 3;
-sljit_s32 cmp1a_ind = 4;
-sljit_s32 cmp1b_ind = 5;
-sljit_s32 cmp2a_ind = 6;
-sljit_s32 cmp2b_ind = 7;
-sljit_s32 zero_ind = 8;
-int i;
-
-SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2);
-SLJIT_ASSERT(-diff <= (sljit_s32)IN_UCHARS(max_fast_forward_char_pair_offset()));
-SLJIT_ASSERT(tmp1_reg_ind != 0 && tmp2_reg_ind != 0);
-
-if (char1a != char1b)
- {
- bit1 = char1a ^ char1b;
- compare1_type = vector_compare_match1i;
-
- if (!is_powerof2(bit1))
- {
- bit1 = 0;
- compare1_type = vector_compare_match2;
- }
- }
-
-if (char2a != char2b)
- {
- bit2 = char2a ^ char2b;
- compare2_type = vector_compare_match1i;
-
- if (!is_powerof2(bit2))
- {
- bit2 = 0;
- compare2_type = vector_compare_match2;
- }
- }
-
-/* Initialize. */
-if (common->match_end_ptr != 0)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
- OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1));
-
- OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, STR_END, 0);
- CMOV(SLJIT_LESS, STR_END, TMP1, 0);
- }
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1));
-add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
-OP2(SLJIT_AND, TMP2, 0, STR_PTR, 0, SLJIT_IMM, ~15);
-
-#if PCRE2_CODE_UNIT_WIDTH != 32
-
-OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, -diff);
-
-/* VREPI */
-instruction[0] = (sljit_u16)(0xe700 | (cmp1a_ind << 4));
-instruction[1] = (sljit_u16)(char1a | bit1);
-instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0x8 << 8) | 0x45);
-sljit_emit_op_custom(compiler, instruction, 6);
-
-if (char1a != char1b)
- {
- /* VREPI */
- instruction[0] = (sljit_u16)(0xe700 | (cmp1b_ind << 4));
- instruction[1] = (sljit_u16)(bit1 != 0 ? bit1 : char1b);
- /* instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0x8 << 8) | 0x45); */
- sljit_emit_op_custom(compiler, instruction, 6);
- }
-
-/* VREPI */
-instruction[0] = (sljit_u16)(0xe700 | (cmp2a_ind << 4));
-instruction[1] = (sljit_u16)(char2a | bit2);
-/* instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0x8 << 8) | 0x45); */
-sljit_emit_op_custom(compiler, instruction, 6);
-
-if (char2a != char2b)
- {
- /* VREPI */
- instruction[0] = (sljit_u16)(0xe700 | (cmp2b_ind << 4));
- instruction[1] = (sljit_u16)(bit2 != 0 ? bit2 : char2b);
- /* instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0x8 << 8) | 0x45); */
- sljit_emit_op_custom(compiler, instruction, 6);
- }
-
-#else /* PCRE2_CODE_UNIT_WIDTH == 32 */
-
-for (int i = 0; i < 2; i++)
- {
- replicate_imm_vector(compiler, i, cmp1a_ind, char1a | bit1, TMP1);
-
- if (char1a != char1b)
- replicate_imm_vector(compiler, i, cmp1b_ind, bit1 != 0 ? bit1 : char1b, TMP1);
-
- replicate_imm_vector(compiler, i, cmp2a_ind, char2a | bit2, TMP1);
-
- if (char2a != char2b)
- replicate_imm_vector(compiler, i, cmp2b_ind, bit2 != 0 ? bit2 : char2b, TMP1);
- }
-
-OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, -diff);
-
-#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */
-
-/* VREPI */
-instruction[0] = (sljit_u16)(0xe700 | (zero_ind << 4));
-instruction[1] = 0;
-instruction[2] = (sljit_u16)((0x8 << 8) | 0x45);
-sljit_emit_op_custom(compiler, instruction, 6);
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-restart = LABEL();
-#endif
-
-jump[0] = CMP(SLJIT_LESS, TMP1, 0, TMP2, 0);
-load_from_mem_vector(compiler, TRUE, data2_ind, tmp1_reg_ind, 0);
-jump[1] = JUMP(SLJIT_JUMP);
-JUMPHERE(jump[0]);
-load_from_mem_vector(compiler, FALSE, data2_ind, tmp1_reg_ind, 0);
-JUMPHERE(jump[1]);
-
-load_from_mem_vector(compiler, TRUE, data1_ind, str_ptr_reg_ind, 0);
-OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 16);
-
-for (i = 0; i < 3; i++)
- {
- fast_forward_char_pair_sse2_compare(compiler, compare1_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind);
- fast_forward_char_pair_sse2_compare(compiler, compare2_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp2_ind);
- }
-
-/* VN */
-instruction[0] = (sljit_u16)(0xe700 | (data1_ind << 4) | data1_ind);
-instruction[1] = (sljit_u16)(data2_ind << 12);
-instruction[2] = (sljit_u16)((0xe << 8) | 0x68);
-sljit_emit_op_custom(compiler, instruction, 6);
-
-/* VFENE */
-instruction[0] = (sljit_u16)(0xe700 | (data1_ind << 4) | data1_ind);
-instruction[1] = (sljit_u16)((zero_ind << 12) | (1 << 4));
-instruction[2] = (sljit_u16)((0xe << 8) | 0x81);
-sljit_emit_op_custom(compiler, instruction, 6);
-
-/* VLGVB */
-instruction[0] = (sljit_u16)(0xe700 | (tmp1_reg_ind << 4) | data1_ind);
-instruction[1] = 7;
-instruction[2] = (sljit_u16)((0x4 << 8) | 0x21);
-sljit_emit_op_custom(compiler, instruction, 6);
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
-quit = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0);
-
-OP2(SLJIT_SUB, STR_PTR, 0, TMP2, 0, SLJIT_IMM, 16);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, diff);
-
-/* Main loop. */
-start = LABEL();
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);
-add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
-
-load_from_mem_vector(compiler, FALSE, data1_ind, str_ptr_reg_ind, 0);
-load_from_mem_vector(compiler, FALSE, data2_ind, str_ptr_reg_ind, tmp1_reg_ind);
-
-for (i = 0; i < 3; i++)
- {
- fast_forward_char_pair_sse2_compare(compiler, compare1_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind);
- fast_forward_char_pair_sse2_compare(compiler, compare2_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp2_ind);
- }
-
-/* VN */
-instruction[0] = (sljit_u16)(0xe700 | (data1_ind << 4) | data1_ind);
-instruction[1] = (sljit_u16)(data2_ind << 12);
-instruction[2] = (sljit_u16)((0xe << 8) | 0x68);
-sljit_emit_op_custom(compiler, instruction, 6);
-
-/* VFENE */
-instruction[0] = (sljit_u16)(0xe700 | (data1_ind << 4) | data1_ind);
-instruction[1] = (sljit_u16)((zero_ind << 12) | (1 << 4));
-instruction[2] = (sljit_u16)((0xe << 8) | 0x81);
-sljit_emit_op_custom(compiler, instruction, 6);
-
-sljit_set_current_flags(compiler, SLJIT_SET_OVERFLOW);
-JUMPTO(SLJIT_OVERFLOW, start);
-
-/* VLGVB */
-instruction[0] = (sljit_u16)(0xe700 | (tmp2_reg_ind << 4) | data1_ind);
-instruction[1] = 7;
-instruction[2] = (sljit_u16)((0x4 << 8) | 0x21);
-sljit_emit_op_custom(compiler, instruction, 6);
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-
-JUMPHERE(quit);
-
-add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-if (common->utf)
- {
- SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE);
-
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offs1));
-
- quit = jump_if_utf_char_start(compiler, TMP1);
-
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
-
- /* TMP1 contains diff. */
- OP2(SLJIT_AND, TMP2, 0, STR_PTR, 0, SLJIT_IMM, ~15);
- OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, -diff);
- JUMPTO(SLJIT_JUMP, restart);
-
- JUMPHERE(quit);
- }
-#endif
-
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1));
-
-if (common->match_end_ptr != 0)
- OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
-}
-
-#endif /* SLJIT_CONFIG_S390X */
-
-#endif /* !SUPPORT_VALGRIND */
diff --git a/contrib/libs/pcre2/src/pcre2_maketables.c b/contrib/libs/pcre2/src/pcre2_maketables.c
deleted file mode 100644
index 3a4c47d00a..0000000000
--- a/contrib/libs/pcre2/src/pcre2_maketables.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2020 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains the external function pcre2_maketables(), which builds
-character tables for PCRE2 in the current locale. The file is compiled on its
-own as part of the PCRE2 library. It is also included in the compilation of
-pcre2_dftables.c as a freestanding program, in which case the macro
-PCRE2_DFTABLES is defined. */
-
-#ifndef PCRE2_DFTABLES /* Compiling the library */
-# ifdef HAVE_CONFIG_H
-# include <pcre2_config.h>
-# endif
-# include "pcre2_internal.h"
-#endif
-
-
-
-/*************************************************
-* Create PCRE2 character tables *
-*************************************************/
-
-/* This function builds a set of character tables for use by PCRE2 and returns
-a pointer to them. They are build using the ctype functions, and consequently
-their contents will depend upon the current locale setting. When compiled as
-part of the library, the store is obtained via a general context malloc, if
-supplied, but when PCRE2_DFTABLES is defined (when compiling the pcre2_dftables
-freestanding auxiliary program) malloc() is used, and the function has a
-different name so as not to clash with the prototype in pcre2.h.
-
-Arguments: none when PCRE2_DFTABLES is defined
- else a PCRE2 general context or NULL
-Returns: pointer to the contiguous block of data
- else NULL if memory allocation failed
-*/
-
-#ifdef PCRE2_DFTABLES /* Included in freestanding pcre2_dftables program */
-static const uint8_t *maketables(void)
-{
-uint8_t *yield = (uint8_t *)malloc(TABLES_LENGTH);
-
-#else /* Not PCRE2_DFTABLES, that is, compiling the library */
-PCRE2_EXP_DEFN const uint8_t * PCRE2_CALL_CONVENTION
-pcre2_maketables(pcre2_general_context *gcontext)
-{
-uint8_t *yield = (uint8_t *)((gcontext != NULL)?
- gcontext->memctl.malloc(TABLES_LENGTH, gcontext->memctl.memory_data) :
- malloc(TABLES_LENGTH));
-#endif /* PCRE2_DFTABLES */
-
-int i;
-uint8_t *p;
-
-if (yield == NULL) return NULL;
-p = yield;
-
-/* First comes the lower casing table */
-
-for (i = 0; i < 256; i++) *p++ = tolower(i);
-
-/* Next the case-flipping table */
-
-for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i);
-
-/* Then the character class tables. Don't try to be clever and save effort on
-exclusive ones - in some locales things may be different.
-
-Note that the table for "space" includes everything "isspace" gives, including
-VT in the default locale. This makes it work for the POSIX class [:space:].
-From PCRE1 release 8.34 and for all PCRE2 releases it is also correct for Perl
-space, because Perl added VT at release 5.18.
-
-Note also that it is possible for a character to be alnum or alpha without
-being lower or upper, such as "male and female ordinals" (\xAA and \xBA) in the
-fr_FR locale (at least under Debian Linux's locales as of 12/2005). So we must
-test for alnum specially. */
-
-memset(p, 0, cbit_length);
-for (i = 0; i < 256; i++)
- {
- if (isdigit(i)) p[cbit_digit + i/8] |= 1u << (i&7);
- if (isupper(i)) p[cbit_upper + i/8] |= 1u << (i&7);
- if (islower(i)) p[cbit_lower + i/8] |= 1u << (i&7);
- if (isalnum(i)) p[cbit_word + i/8] |= 1u << (i&7);
- if (i == '_') p[cbit_word + i/8] |= 1u << (i&7);
- if (isspace(i)) p[cbit_space + i/8] |= 1u << (i&7);
- if (isxdigit(i)) p[cbit_xdigit + i/8] |= 1u << (i&7);
- if (isgraph(i)) p[cbit_graph + i/8] |= 1u << (i&7);
- if (isprint(i)) p[cbit_print + i/8] |= 1u << (i&7);
- if (ispunct(i)) p[cbit_punct + i/8] |= 1u << (i&7);
- if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1u << (i&7);
- }
-p += cbit_length;
-
-/* Finally, the character type table. In this, we used to exclude VT from the
-white space chars, because Perl didn't recognize it as such for \s and for
-comments within regexes. However, Perl changed at release 5.18, so PCRE1
-changed at release 8.34 and it's always been this way for PCRE2. */
-
-for (i = 0; i < 256; i++)
- {
- int x = 0;
- if (isspace(i)) x += ctype_space;
- if (isalpha(i)) x += ctype_letter;
- if (islower(i)) x += ctype_lcletter;
- if (isdigit(i)) x += ctype_digit;
- if (isalnum(i) || i == '_') x += ctype_word;
- *p++ = x;
- }
-
-return yield;
-}
-
-#ifndef PCRE2_DFTABLES /* Compiling the library */
-PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
-pcre2_maketables_free(pcre2_general_context *gcontext, const uint8_t *tables)
-{
- if (gcontext)
- gcontext->memctl.free((void *)tables, gcontext->memctl.memory_data);
- else
- free((void *)tables);
-}
-#endif
-
-/* End of pcre2_maketables.c */
diff --git a/contrib/libs/pcre2/src/pcre2_match.c b/contrib/libs/pcre2/src/pcre2_match.c
deleted file mode 100644
index 80255bbe17..0000000000
--- a/contrib/libs/pcre2/src/pcre2_match.c
+++ /dev/null
@@ -1,7544 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2015-2022 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-/* These defines enable debugging code */
-
-/* #define DEBUG_FRAMES_DISPLAY */
-/* #define DEBUG_SHOW_OPS */
-/* #define DEBUG_SHOW_RMATCH */
-
-#ifdef DEBUG_FRAMES_DISPLAY
-#include <stdarg.h>
-#endif
-
-/* These defines identify the name of the block containing "static"
-information, and fields within it. */
-
-#define NLBLOCK mb /* Block containing newline information */
-#define PSSTART start_subject /* Field containing processed string start */
-#define PSEND end_subject /* Field containing processed string end */
-
-#include "pcre2_internal.h"
-
-#define RECURSE_UNSET 0xffffffffu /* Bigger than max group number */
-
-/* Masks for identifying the public options that are permitted at match time. */
-
-#define PUBLIC_MATCH_OPTIONS \
- (PCRE2_ANCHORED|PCRE2_ENDANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \
- PCRE2_NOTEMPTY_ATSTART|PCRE2_NO_UTF_CHECK|PCRE2_PARTIAL_HARD| \
- PCRE2_PARTIAL_SOFT|PCRE2_NO_JIT|PCRE2_COPY_MATCHED_SUBJECT)
-
-#define PUBLIC_JIT_MATCH_OPTIONS \
- (PCRE2_NO_UTF_CHECK|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY|\
- PCRE2_NOTEMPTY_ATSTART|PCRE2_PARTIAL_SOFT|PCRE2_PARTIAL_HARD|\
- PCRE2_COPY_MATCHED_SUBJECT)
-
-/* Non-error returns from and within the match() function. Error returns are
-externally defined PCRE2_ERROR_xxx codes, which are all negative. */
-
-#define MATCH_MATCH 1
-#define MATCH_NOMATCH 0
-
-/* Special internal returns used in the match() function. Make them
-sufficiently negative to avoid the external error codes. */
-
-#define MATCH_ACCEPT (-999)
-#define MATCH_KETRPOS (-998)
-/* The next 5 must be kept together and in sequence so that a test that checks
-for any one of them can use a range. */
-#define MATCH_COMMIT (-997)
-#define MATCH_PRUNE (-996)
-#define MATCH_SKIP (-995)
-#define MATCH_SKIP_ARG (-994)
-#define MATCH_THEN (-993)
-#define MATCH_BACKTRACK_MAX MATCH_THEN
-#define MATCH_BACKTRACK_MIN MATCH_COMMIT
-
-/* Group frame type values. Zero means the frame is not a group frame. The
-lower 16 bits are used for data (e.g. the capture number). Group frames are
-used for most groups so that information about the start is easily available at
-the end without having to scan back through intermediate frames (backtrack
-points). */
-
-#define GF_CAPTURE 0x00010000u
-#define GF_NOCAPTURE 0x00020000u
-#define GF_CONDASSERT 0x00030000u
-#define GF_RECURSE 0x00040000u
-
-/* Masks for the identity and data parts of the group frame type. */
-
-#define GF_IDMASK(a) ((a) & 0xffff0000u)
-#define GF_DATAMASK(a) ((a) & 0x0000ffffu)
-
-/* Repetition types */
-
-enum { REPTYPE_MIN, REPTYPE_MAX, REPTYPE_POS };
-
-/* Min and max values for the common repeats; a maximum of UINT32_MAX =>
-infinity. */
-
-static const uint32_t rep_min[] = {
- 0, 0, /* * and *? */
- 1, 1, /* + and +? */
- 0, 0, /* ? and ?? */
- 0, 0, /* dummy placefillers for OP_CR[MIN]RANGE */
- 0, 1, 0 }; /* OP_CRPOS{STAR, PLUS, QUERY} */
-
-static const uint32_t rep_max[] = {
- UINT32_MAX, UINT32_MAX, /* * and *? */
- UINT32_MAX, UINT32_MAX, /* + and +? */
- 1, 1, /* ? and ?? */
- 0, 0, /* dummy placefillers for OP_CR[MIN]RANGE */
- UINT32_MAX, UINT32_MAX, 1 }; /* OP_CRPOS{STAR, PLUS, QUERY} */
-
-/* Repetition types - must include OP_CRPOSRANGE (not needed above) */
-
-static const uint32_t rep_typ[] = {
- REPTYPE_MAX, REPTYPE_MIN, /* * and *? */
- REPTYPE_MAX, REPTYPE_MIN, /* + and +? */
- REPTYPE_MAX, REPTYPE_MIN, /* ? and ?? */
- REPTYPE_MAX, REPTYPE_MIN, /* OP_CRRANGE and OP_CRMINRANGE */
- REPTYPE_POS, REPTYPE_POS, /* OP_CRPOSSTAR, OP_CRPOSPLUS */
- REPTYPE_POS, REPTYPE_POS }; /* OP_CRPOSQUERY, OP_CRPOSRANGE */
-
-/* Numbers for RMATCH calls at backtracking points. When these lists are
-changed, the code at RETURN_SWITCH below must be updated in sync. */
-
-enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10,
- RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20,
- RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,
- RM31, RM32, RM33, RM34, RM35, RM36 };
-
-#ifdef SUPPORT_WIDE_CHARS
-enum { RM100=100, RM101 };
-#endif
-
-#ifdef SUPPORT_UNICODE
-enum { RM200=200, RM201, RM202, RM203, RM204, RM205, RM206, RM207,
- RM208, RM209, RM210, RM211, RM212, RM213, RM214, RM215,
- RM216, RM217, RM218, RM219, RM220, RM221, RM222, RM223,
- RM224, RM225 };
-#endif
-
-/* Define short names for general fields in the current backtrack frame, which
-is always pointed to by the F variable. Occasional references to fields in
-other frames are written out explicitly. There are also some fields in the
-current frame whose names start with "temp" that are used for short-term,
-localised backtracking memory. These are #defined with Lxxx names at the point
-of use and undefined afterwards. */
-
-#define Fback_frame F->back_frame
-#define Fcapture_last F->capture_last
-#define Fcurrent_recurse F->current_recurse
-#define Fecode F->ecode
-#define Feptr F->eptr
-#define Fgroup_frame_type F->group_frame_type
-#define Flast_group_offset F->last_group_offset
-#define Flength F->length
-#define Fmark F->mark
-#define Frdepth F->rdepth
-#define Fstart_match F->start_match
-#define Foffset_top F->offset_top
-#define Foccu F->occu
-#define Fop F->op
-#define Fovector F->ovector
-#define Freturn_id F->return_id
-
-
-#ifdef DEBUG_FRAMES_DISPLAY
-/*************************************************
-* Display current frames and contents *
-*************************************************/
-
-/* This debugging function displays the current set of frames and their
-contents. It is not called automatically from anywhere, the intention being
-that calls can be inserted where necessary when debugging frame-related
-problems.
-
-Arguments:
- f the file to write to
- F the current top frame
- P a previous frame of interest
- frame_size the frame size
- mb points to the match block
- match_data points to the match data block
- s identification text
-
-Returns: nothing
-*/
-
-static void
-display_frames(FILE *f, heapframe *F, heapframe *P, PCRE2_SIZE frame_size,
- match_block *mb, pcre2_match_data *match_data, const char *s, ...)
-{
-uint32_t i;
-heapframe *Q;
-va_list ap;
-va_start(ap, s);
-
-fprintf(f, "FRAMES ");
-vfprintf(f, s, ap);
-va_end(ap);
-
-if (P != NULL) fprintf(f, " P=%lu",
- ((char *)P - (char *)(match_data->heapframes))/frame_size);
-fprintf(f, "\n");
-
-for (i = 0, Q = match_data->heapframes;
- Q <= F;
- i++, Q = (heapframe *)((char *)Q + frame_size))
- {
- fprintf(f, "Frame %d type=%x subj=%lu code=%d back=%lu id=%d",
- i, Q->group_frame_type, Q->eptr - mb->start_subject, *(Q->ecode),
- Q->back_frame, Q->return_id);
-
- if (Q->last_group_offset == PCRE2_UNSET)
- fprintf(f, " lgoffset=unset\n");
- else
- fprintf(f, " lgoffset=%lu\n", Q->last_group_offset/frame_size);
- }
-}
-
-#endif
-
-
-
-/*************************************************
-* Process a callout *
-*************************************************/
-
-/* This function is called for all callouts, whether "standalone" or at the
-start of a conditional group. Feptr will be pointing to either OP_CALLOUT or
-OP_CALLOUT_STR. A callout block is allocated in pcre2_match() and initialized
-with fixed values.
-
-Arguments:
- F points to the current backtracking frame
- mb points to the match block
- lengthptr where to return the length of the callout item
-
-Returns: the return from the callout
- or 0 if no callout function exists
-*/
-
-static int
-do_callout(heapframe *F, match_block *mb, PCRE2_SIZE *lengthptr)
-{
-int rc;
-PCRE2_SIZE save0, save1;
-PCRE2_SIZE *callout_ovector;
-pcre2_callout_block *cb;
-
-*lengthptr = (*Fecode == OP_CALLOUT)?
- PRIV(OP_lengths)[OP_CALLOUT] : GET(Fecode, 1 + 2*LINK_SIZE);
-
-if (mb->callout == NULL) return 0; /* No callout function provided */
-
-/* The original matching code (pre 10.30) worked directly with the ovector
-passed by the user, and this was passed to callouts. Now that the working
-ovector is in the backtracking frame, it no longer needs to reserve space for
-the overall match offsets (which would waste space in the frame). For backward
-compatibility, however, we pass capture_top and offset_vector to the callout as
-if for the extended ovector, and we ensure that the first two slots are unset
-by preserving and restoring their current contents. Picky compilers complain if
-references such as Fovector[-2] are use directly, so we set up a separate
-pointer. */
-
-callout_ovector = (PCRE2_SIZE *)(Fovector) - 2;
-
-/* The cb->version, cb->subject, cb->subject_length, and cb->start_match fields
-are set externally. The first 3 never change; the last is updated for each
-bumpalong. */
-
-cb = mb->cb;
-cb->capture_top = (uint32_t)Foffset_top/2 + 1;
-cb->capture_last = Fcapture_last;
-cb->offset_vector = callout_ovector;
-cb->mark = mb->nomatch_mark;
-cb->current_position = (PCRE2_SIZE)(Feptr - mb->start_subject);
-cb->pattern_position = GET(Fecode, 1);
-cb->next_item_length = GET(Fecode, 1 + LINK_SIZE);
-
-if (*Fecode == OP_CALLOUT) /* Numerical callout */
- {
- cb->callout_number = Fecode[1 + 2*LINK_SIZE];
- cb->callout_string_offset = 0;
- cb->callout_string = NULL;
- cb->callout_string_length = 0;
- }
-else /* String callout */
- {
- cb->callout_number = 0;
- cb->callout_string_offset = GET(Fecode, 1 + 3*LINK_SIZE);
- cb->callout_string = Fecode + (1 + 4*LINK_SIZE) + 1;
- cb->callout_string_length =
- *lengthptr - (1 + 4*LINK_SIZE) - 2;
- }
-
-save0 = callout_ovector[0];
-save1 = callout_ovector[1];
-callout_ovector[0] = callout_ovector[1] = PCRE2_UNSET;
-rc = mb->callout(cb, mb->callout_data);
-callout_ovector[0] = save0;
-callout_ovector[1] = save1;
-cb->callout_flags = 0;
-return rc;
-}
-
-
-
-/*************************************************
-* Match a back-reference *
-*************************************************/
-
-/* This function is called only when it is known that the offset lies within
-the offsets that have so far been used in the match. Note that in caseless
-UTF-8 mode, the number of subject bytes matched may be different to the number
-of reference bytes. (In theory this could also happen in UTF-16 mode, but it
-seems unlikely.)
-
-Arguments:
- offset index into the offset vector
- caseless TRUE if caseless
- F the current backtracking frame pointer
- mb points to match block
- lengthptr pointer for returning the length matched
-
-Returns: = 0 sucessful match; number of code units matched is set
- < 0 no match
- > 0 partial match
-*/
-
-static int
-match_ref(PCRE2_SIZE offset, BOOL caseless, heapframe *F, match_block *mb,
- PCRE2_SIZE *lengthptr)
-{
-PCRE2_SPTR p;
-PCRE2_SIZE length;
-PCRE2_SPTR eptr;
-PCRE2_SPTR eptr_start;
-
-/* Deal with an unset group. The default is no match, but there is an option to
-match an empty string. */
-
-if (offset >= Foffset_top || Fovector[offset] == PCRE2_UNSET)
- {
- if ((mb->poptions & PCRE2_MATCH_UNSET_BACKREF) != 0)
- {
- *lengthptr = 0;
- return 0; /* Match */
- }
- else return -1; /* No match */
- }
-
-/* Separate the caseless and UTF cases for speed. */
-
-eptr = eptr_start = Feptr;
-p = mb->start_subject + Fovector[offset];
-length = Fovector[offset+1] - Fovector[offset];
-
-if (caseless)
- {
-#if defined SUPPORT_UNICODE
- BOOL utf = (mb->poptions & PCRE2_UTF) != 0;
-
- if (utf || (mb->poptions & PCRE2_UCP) != 0)
- {
- PCRE2_SPTR endptr = p + length;
-
- /* Match characters up to the end of the reference. NOTE: the number of
- code units matched may differ, because in UTF-8 there are some characters
- whose upper and lower case codes have different numbers of bytes. For
- example, U+023A (2 bytes in UTF-8) is the upper case version of U+2C65 (3
- bytes in UTF-8); a sequence of 3 of the former uses 6 bytes, as does a
- sequence of two of the latter. It is important, therefore, to check the
- length along the reference, not along the subject (earlier code did this
- wrong). UCP without uses Unicode properties but without UTF encoding. */
-
- while (p < endptr)
- {
- uint32_t c, d;
- const ucd_record *ur;
- if (eptr >= mb->end_subject) return 1; /* Partial match */
-
- if (utf)
- {
- GETCHARINC(c, eptr);
- GETCHARINC(d, p);
- }
- else
- {
- c = *eptr++;
- d = *p++;
- }
-
- ur = GET_UCD(d);
- if (c != d && c != (uint32_t)((int)d + ur->other_case))
- {
- const uint32_t *pp = PRIV(ucd_caseless_sets) + ur->caseset;
- for (;;)
- {
- if (c < *pp) return -1; /* No match */
- if (c == *pp++) break;
- }
- }
- }
- }
- else
-#endif
-
- /* Not in UTF or UCP mode */
- {
- for (; length > 0; length--)
- {
- uint32_t cc, cp;
- if (eptr >= mb->end_subject) return 1; /* Partial match */
- cc = UCHAR21TEST(eptr);
- cp = UCHAR21TEST(p);
- if (TABLE_GET(cp, mb->lcc, cp) != TABLE_GET(cc, mb->lcc, cc))
- return -1; /* No match */
- p++;
- eptr++;
- }
- }
- }
-
-/* In the caseful case, we can just compare the code units, whether or not we
-are in UTF and/or UCP mode. When partial matching, we have to do this unit by
-unit. */
-
-else
- {
- if (mb->partial != 0)
- {
- for (; length > 0; length--)
- {
- if (eptr >= mb->end_subject) return 1; /* Partial match */
- if (UCHAR21INCTEST(p) != UCHAR21INCTEST(eptr)) return -1; /* No match */
- }
- }
-
- /* Not partial matching */
-
- else
- {
- if ((PCRE2_SIZE)(mb->end_subject - eptr) < length) return 1; /* Partial */
- if (memcmp(p, eptr, CU2BYTES(length)) != 0) return -1; /* No match */
- eptr += length;
- }
- }
-
-*lengthptr = eptr - eptr_start;
-return 0; /* Match */
-}
-
-
-
-/******************************************************************************
-*******************************************************************************
- "Recursion" in the match() function
-
-The original match() function was highly recursive, but this proved to be the
-source of a number of problems over the years, mostly because of the relatively
-small system stacks that are commonly found. As new features were added to
-patterns, various kludges were invented to reduce the amount of stack used,
-making the code hard to understand in places.
-
-A version did exist that used individual frames on the heap instead of calling
-match() recursively, but this ran substantially slower. The current version is
-a refactoring that uses a vector of frames to remember backtracking points.
-This runs no slower, and possibly even a bit faster than the original recursive
-implementation.
-
-At first, an initial vector of size START_FRAMES_SIZE (enough for maybe 50
-frames) was allocated on the system stack. If this was not big enough, the heap
-was used for a larger vector. However, it turns out that there are environments
-where taking as little as 20KiB from the system stack is an embarrassment.
-After another refactoring, the heap is used exclusively, but a pointer the
-frames vector and its size are cached in the match_data block, so that there is
-no new memory allocation if the same match_data block is used for multiple
-matches (unless the frames vector has to be extended).
-*******************************************************************************
-******************************************************************************/
-
-
-
-
-/*************************************************
-* Macros for the match() function *
-*************************************************/
-
-/* These macros pack up tests that are used for partial matching several times
-in the code. The second one is used when we already know we are past the end of
-the subject. We set the "hit end" flag if the pointer is at the end of the
-subject and either (a) the pointer is past the earliest inspected character
-(i.e. something has been matched, even if not part of the actual matched
-string), or (b) the pattern contains a lookbehind. These are the conditions for
-which adding more characters may allow the current match to continue.
-
-For hard partial matching, we immediately return a partial match. Otherwise,
-carrying on means that a complete match on the current subject will be sought.
-A partial match is returned only if no complete match can be found. */
-
-#define CHECK_PARTIAL()\
- if (Feptr >= mb->end_subject) \
- { \
- SCHECK_PARTIAL(); \
- }
-
-#define SCHECK_PARTIAL()\
- if (mb->partial != 0 && \
- (Feptr > mb->start_used_ptr || mb->allowemptypartial)) \
- { \
- mb->hitend = TRUE; \
- if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; \
- }
-
-
-/* These macros are used to implement backtracking. They simulate a recursive
-call to the match() function by means of a local vector of frames which
-remember the backtracking points. */
-
-#define RMATCH(ra,rb)\
- {\
- start_ecode = ra;\
- Freturn_id = rb;\
- goto MATCH_RECURSE;\
- L_##rb:;\
- }
-
-#define RRETURN(ra)\
- {\
- rrc = ra;\
- goto RETURN_SWITCH;\
- }
-
-
-
-/*************************************************
-* Match from current position *
-*************************************************/
-
-/* This function is called to run one match attempt at a single starting point
-in the subject.
-
-Performance note: It might be tempting to extract commonly used fields from the
-mb structure (e.g. end_subject) into individual variables to improve
-performance. Tests using gcc on a SPARC disproved this; in the first case, it
-made performance worse.
-
-Arguments:
- start_eptr starting character in subject
- start_ecode starting position in compiled code
- top_bracket number of capturing parentheses in the pattern
- frame_size size of each backtracking frame
- match_data pointer to the match_data block
- mb pointer to "static" variables block
-
-Returns: MATCH_MATCH if matched ) these values are >= 0
- MATCH_NOMATCH if failed to match )
- negative MATCH_xxx value for PRUNE, SKIP, etc
- negative PCRE2_ERROR_xxx value if aborted by an error condition
- (e.g. stopped by repeated call or depth limit)
-*/
-
-static int
-match(PCRE2_SPTR start_eptr, PCRE2_SPTR start_ecode, uint16_t top_bracket,
- PCRE2_SIZE frame_size, pcre2_match_data *match_data, match_block *mb)
-{
-/* Frame-handling variables */
-
-heapframe *F; /* Current frame pointer */
-heapframe *N = NULL; /* Temporary frame pointers */
-heapframe *P = NULL;
-
-heapframe *frames_top; /* End of frames vector */
-heapframe *assert_accept_frame = NULL; /* For passing back a frame with captures */
-PCRE2_SIZE heapframes_size; /* Usable size of frames vector */
-PCRE2_SIZE frame_copy_size; /* Amount to copy when creating a new frame */
-
-/* Local variables that do not need to be preserved over calls to RRMATCH(). */
-
-PCRE2_SPTR bracode; /* Temp pointer to start of group */
-PCRE2_SIZE offset; /* Used for group offsets */
-PCRE2_SIZE length; /* Used for various length calculations */
-
-int rrc; /* Return from functions & backtracking "recursions" */
-#ifdef SUPPORT_UNICODE
-int proptype; /* Type of character property */
-#endif
-
-uint32_t i; /* Used for local loops */
-uint32_t fc; /* Character values */
-uint32_t number; /* Used for group and other numbers */
-uint32_t reptype = 0; /* Type of repetition (0 to avoid compiler warning) */
-uint32_t group_frame_type; /* Specifies type for new group frames */
-
-BOOL condition; /* Used in conditional groups */
-BOOL cur_is_word; /* Used in "word" tests */
-BOOL prev_is_word; /* Used in "word" tests */
-
-/* UTF and UCP flags */
-
-#ifdef SUPPORT_UNICODE
-BOOL utf = (mb->poptions & PCRE2_UTF) != 0;
-BOOL ucp = (mb->poptions & PCRE2_UCP) != 0;
-#else
-BOOL utf = FALSE; /* Required for convenience even when no Unicode support */
-#endif
-
-/* This is the length of the last part of a backtracking frame that must be
-copied when a new frame is created. */
-
-frame_copy_size = frame_size - offsetof(heapframe, eptr);
-
-/* Set up the first frame and the end of the frames vector. We set the local
-heapframes_size to the usuable amount of the vector, that is, a whole number of
-frames. */
-
-F = match_data->heapframes;
-heapframes_size = (match_data->heapframes_size / frame_size) * frame_size;
-frames_top = (heapframe *)((char *)F + heapframes_size);
-
-Frdepth = 0; /* "Recursion" depth */
-Fcapture_last = 0; /* Number of most recent capture */
-Fcurrent_recurse = RECURSE_UNSET; /* Not pattern recursing. */
-Fstart_match = Feptr = start_eptr; /* Current data pointer and start match */
-Fmark = NULL; /* Most recent mark */
-Foffset_top = 0; /* End of captures within the frame */
-Flast_group_offset = PCRE2_UNSET; /* Saved frame of most recent group */
-group_frame_type = 0; /* Not a start of group frame */
-goto NEW_FRAME; /* Start processing with this frame */
-
-/* Come back here when we want to create a new frame for remembering a
-backtracking point. */
-
-MATCH_RECURSE:
-
-/* Set up a new backtracking frame. If the vector is full, get a new one,
-doubling the size, but constrained by the heap limit (which is in KiB). */
-
-N = (heapframe *)((char *)F + frame_size);
-if (N >= frames_top)
- {
- heapframe *new;
- PCRE2_SIZE newsize = match_data->heapframes_size * 2;
-
- if (newsize > mb->heap_limit)
- {
- PCRE2_SIZE maxsize = (mb->heap_limit/frame_size) * frame_size;
- if (match_data->heapframes_size >= maxsize) return PCRE2_ERROR_HEAPLIMIT;
- newsize = maxsize;
- }
-
- new = match_data->memctl.malloc(newsize, match_data->memctl.memory_data);
- if (new == NULL) return PCRE2_ERROR_NOMEMORY;
- memcpy(new, match_data->heapframes, heapframes_size);
-
- F = (heapframe *)((char *)new + ((char *)F - (char *)match_data->heapframes));
- N = (heapframe *)((char *)F + frame_size);
-
- match_data->memctl.free(match_data->heapframes, match_data->memctl.memory_data);
- match_data->heapframes = new;
- match_data->heapframes_size = newsize;
-
- heapframes_size = (newsize / frame_size) * frame_size;
- frames_top = (heapframe *)((char *)new + heapframes_size);
- }
-
-#ifdef DEBUG_SHOW_RMATCH
-fprintf(stderr, "++ RMATCH %2d frame=%d", Freturn_id, Frdepth + 1);
-if (group_frame_type != 0)
- {
- fprintf(stderr, " type=%x ", group_frame_type);
- switch (GF_IDMASK(group_frame_type))
- {
- case GF_CAPTURE:
- fprintf(stderr, "capture=%d", GF_DATAMASK(group_frame_type));
- break;
-
- case GF_NOCAPTURE:
- fprintf(stderr, "nocapture op=%d", GF_DATAMASK(group_frame_type));
- break;
-
- case GF_CONDASSERT:
- fprintf(stderr, "condassert op=%d", GF_DATAMASK(group_frame_type));
- break;
-
- case GF_RECURSE:
- fprintf(stderr, "recurse=%d", GF_DATAMASK(group_frame_type));
- break;
-
- default:
- fprintf(stderr, "*** unknown ***");
- break;
- }
- }
-fprintf(stderr, "\n");
-#endif
-
-/* Copy those fields that must be copied into the new frame, increase the
-"recursion" depth (i.e. the new frame's index) and then make the new frame
-current. */
-
-memcpy((char *)N + offsetof(heapframe, eptr),
- (char *)F + offsetof(heapframe, eptr),
- frame_copy_size);
-
-N->rdepth = Frdepth + 1;
-F = N;
-
-/* Carry on processing with a new frame. */
-
-NEW_FRAME:
-Fgroup_frame_type = group_frame_type;
-Fecode = start_ecode; /* Starting code pointer */
-Fback_frame = frame_size; /* Default is go back one frame */
-
-/* If this is a special type of group frame, remember its offset for quick
-access at the end of the group. If this is a recursion, set a new current
-recursion value. */
-
-if (group_frame_type != 0)
- {
- Flast_group_offset = (char *)F - (char *)match_data->heapframes;
- if (GF_IDMASK(group_frame_type) == GF_RECURSE)
- Fcurrent_recurse = GF_DATAMASK(group_frame_type);
- group_frame_type = 0;
- }
-
-
-/* ========================================================================= */
-/* This is the main processing loop. First check that we haven't recorded too
-many backtracks (search tree is too large), or that we haven't exceeded the
-recursive depth limit (used too many backtracking frames). If not, process the
-opcodes. */
-
-if (mb->match_call_count++ >= mb->match_limit) return PCRE2_ERROR_MATCHLIMIT;
-if (Frdepth >= mb->match_limit_depth) return PCRE2_ERROR_DEPTHLIMIT;
-
-for (;;)
- {
-#ifdef DEBUG_SHOW_OPS
-fprintf(stderr, "++ op=%d\n", *Fecode);
-#endif
-
- Fop = (uint8_t)(*Fecode); /* Cast needed for 16-bit and 32-bit modes */
- switch(Fop)
- {
- /* ===================================================================== */
- /* Before OP_ACCEPT there may be any number of OP_CLOSE opcodes, to close
- any currently open capturing brackets. Unlike reaching the end of a group,
- where we know the starting frame is at the top of the chained frames, in
- this case we have to search back for the relevant frame in case other types
- of group that use chained frames have intervened. Multiple OP_CLOSEs always
- come innermost first, which matches the chain order. We can ignore this in
- a recursion, because captures are not passed out of recursions. */
-
- case OP_CLOSE:
- if (Fcurrent_recurse == RECURSE_UNSET)
- {
- number = GET2(Fecode, 1);
- offset = Flast_group_offset;
- for(;;)
- {
- if (offset == PCRE2_UNSET) return PCRE2_ERROR_INTERNAL;
- N = (heapframe *)((char *)match_data->heapframes + offset);
- P = (heapframe *)((char *)N - frame_size);
- if (N->group_frame_type == (GF_CAPTURE | number)) break;
- offset = P->last_group_offset;
- }
- offset = (number << 1) - 2;
- Fcapture_last = number;
- Fovector[offset] = P->eptr - mb->start_subject;
- Fovector[offset+1] = Feptr - mb->start_subject;
- if (offset >= Foffset_top) Foffset_top = offset + 2;
- }
- Fecode += PRIV(OP_lengths)[*Fecode];
- break;
-
-
- /* ===================================================================== */
- /* Real or forced end of the pattern, assertion, or recursion. In an
- assertion ACCEPT, update the last used pointer and remember the current
- frame so that the captures and mark can be fished out of it. */
-
- case OP_ASSERT_ACCEPT:
- if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;
- assert_accept_frame = F;
- RRETURN(MATCH_ACCEPT);
-
- /* If recursing, we have to find the most recent recursion. */
-
- case OP_ACCEPT:
- case OP_END:
-
- /* Handle end of a recursion. */
-
- if (Fcurrent_recurse != RECURSE_UNSET)
- {
- offset = Flast_group_offset;
- for(;;)
- {
- if (offset == PCRE2_UNSET) return PCRE2_ERROR_INTERNAL;
- N = (heapframe *)((char *)match_data->heapframes + offset);
- P = (heapframe *)((char *)N - frame_size);
- if (GF_IDMASK(N->group_frame_type) == GF_RECURSE) break;
- offset = P->last_group_offset;
- }
-
- /* N is now the frame of the recursion; the previous frame is at the
- OP_RECURSE position. Go back there, copying the current subject position
- and mark, and the start_match position (\K might have changed it), and
- then move on past the OP_RECURSE. */
-
- P->eptr = Feptr;
- P->mark = Fmark;
- P->start_match = Fstart_match;
- F = P;
- Fecode += 1 + LINK_SIZE;
- continue;
- }
-
- /* Not a recursion. Fail for an empty string match if either PCRE2_NOTEMPTY
- is set, or if PCRE2_NOTEMPTY_ATSTART is set and we have matched at the
- start of the subject. In both cases, backtracking will then try other
- alternatives, if any. */
-
- if (Feptr == Fstart_match &&
- ((mb->moptions & PCRE2_NOTEMPTY) != 0 ||
- ((mb->moptions & PCRE2_NOTEMPTY_ATSTART) != 0 &&
- Fstart_match == mb->start_subject + mb->start_offset)))
- RRETURN(MATCH_NOMATCH);
-
- /* Also fail if PCRE2_ENDANCHORED is set and the end of the match is not
- the end of the subject. After (*ACCEPT) we fail the entire match (at this
- position) but backtrack on reaching the end of the pattern. */
-
- if (Feptr < mb->end_subject &&
- ((mb->moptions | mb->poptions) & PCRE2_ENDANCHORED) != 0)
- {
- if (Fop == OP_END) RRETURN(MATCH_NOMATCH);
- return MATCH_NOMATCH;
- }
-
- /* We have a successful match of the whole pattern. Record the result and
- then do a direct return from the function. If there is space in the offset
- vector, set any pairs that follow the highest-numbered captured string but
- are less than the number of capturing groups in the pattern to PCRE2_UNSET.
- It is documented that this happens. "Gaps" are set to PCRE2_UNSET
- dynamically. It is only those at the end that need setting here. */
-
- mb->end_match_ptr = Feptr; /* Record where we ended */
- mb->end_offset_top = Foffset_top; /* and how many extracts were taken */
- mb->mark = Fmark; /* and the last success mark */
- if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;
-
- match_data->ovector[0] = Fstart_match - mb->start_subject;
- match_data->ovector[1] = Feptr - mb->start_subject;
-
- /* Set i to the smaller of the sizes of the external and frame ovectors. */
-
- i = 2 * ((top_bracket + 1 > match_data->oveccount)?
- match_data->oveccount : top_bracket + 1);
- memcpy(match_data->ovector + 2, Fovector, (i - 2) * sizeof(PCRE2_SIZE));
- while (--i >= Foffset_top + 2) match_data->ovector[i] = PCRE2_UNSET;
- return MATCH_MATCH; /* Note: NOT RRETURN */
-
-
- /*===================================================================== */
- /* Match any single character type except newline; have to take care with
- CRLF newlines and partial matching. */
-
- case OP_ANY:
- if (IS_NEWLINE(Feptr)) RRETURN(MATCH_NOMATCH);
- if (mb->partial != 0 &&
- Feptr == mb->end_subject - 1 &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- UCHAR21TEST(Feptr) == NLBLOCK->nl[0])
- {
- mb->hitend = TRUE;
- if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
- }
- /* Fall through */
-
- /* Match any single character whatsoever. */
-
- case OP_ALLANY:
- if (Feptr >= mb->end_subject) /* DO NOT merge the Feptr++ here; it must */
- { /* not be updated before SCHECK_PARTIAL. */
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- Feptr++;
-#ifdef SUPPORT_UNICODE
- if (utf) ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);
-#endif
- Fecode++;
- break;
-
-
- /* ===================================================================== */
- /* Match a single code unit, even in UTF mode. This opcode really does
- match any code unit, even newline. (It really should be called ANYCODEUNIT,
- of course - the byte name is from pre-16 bit days.) */
-
- case OP_ANYBYTE:
- if (Feptr >= mb->end_subject) /* DO NOT merge the Feptr++ here; it must */
- { /* not be updated before SCHECK_PARTIAL. */
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- Feptr++;
- Fecode++;
- break;
-
-
- /* ===================================================================== */
- /* Match a single character, casefully */
-
- case OP_CHAR:
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- Flength = 1;
- Fecode++;
- GETCHARLEN(fc, Fecode, Flength);
- if (Flength > (PCRE2_SIZE)(mb->end_subject - Feptr))
- {
- CHECK_PARTIAL(); /* Not SCHECK_PARTIAL() */
- RRETURN(MATCH_NOMATCH);
- }
- for (; Flength > 0; Flength--)
- {
- if (*Fecode++ != UCHAR21INC(Feptr)) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif
-
- /* Not UTF mode */
- {
- if (mb->end_subject - Feptr < 1)
- {
- SCHECK_PARTIAL(); /* This one can use SCHECK_PARTIAL() */
- RRETURN(MATCH_NOMATCH);
- }
- if (Fecode[1] != *Feptr++) RRETURN(MATCH_NOMATCH);
- Fecode += 2;
- }
- break;
-
-
- /* ===================================================================== */
- /* Match a single character, caselessly. If we are at the end of the
- subject, give up immediately. We get here only when the pattern character
- has at most one other case. Characters with more than two cases are coded
- as OP_PROP with the pseudo-property PT_CLIST. */
-
- case OP_CHARI:
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
-
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- Flength = 1;
- Fecode++;
- GETCHARLEN(fc, Fecode, Flength);
-
- /* If the pattern character's value is < 128, we know that its other case
- (if any) is also < 128 (and therefore only one code unit long in all
- code-unit widths), so we can use the fast lookup table. We checked above
- that there is at least one character left in the subject. */
-
- if (fc < 128)
- {
- uint32_t cc = UCHAR21(Feptr);
- if (mb->lcc[fc] != TABLE_GET(cc, mb->lcc, cc)) RRETURN(MATCH_NOMATCH);
- Fecode++;
- Feptr++;
- }
-
- /* Otherwise we must pick up the subject character and use Unicode
- property support to test its other case. Note that we cannot use the
- value of "Flength" to check for sufficient bytes left, because the other
- case of the character may have more or fewer code units. */
-
- else
- {
- uint32_t dc;
- GETCHARINC(dc, Feptr);
- Fecode += Flength;
- if (dc != fc && dc != UCD_OTHERCASE(fc)) RRETURN(MATCH_NOMATCH);
- }
- }
-
- /* If UCP is set without UTF we must do the same as above, but with one
- character per code unit. */
-
- else if (ucp)
- {
- uint32_t cc = UCHAR21(Feptr);
- fc = Fecode[1];
- if (fc < 128)
- {
- if (mb->lcc[fc] != TABLE_GET(cc, mb->lcc, cc)) RRETURN(MATCH_NOMATCH);
- }
- else
- {
- if (cc != fc && cc != UCD_OTHERCASE(fc)) RRETURN(MATCH_NOMATCH);
- }
- Feptr++;
- Fecode += 2;
- }
-
- else
-#endif /* SUPPORT_UNICODE */
-
- /* Not UTF or UCP mode; use the table for characters < 256. */
- {
- if (TABLE_GET(Fecode[1], mb->lcc, Fecode[1])
- != TABLE_GET(*Feptr, mb->lcc, *Feptr)) RRETURN(MATCH_NOMATCH);
- Feptr++;
- Fecode += 2;
- }
- break;
-
-
- /* ===================================================================== */
- /* Match not a single character. */
-
- case OP_NOT:
- case OP_NOTI:
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
-
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- uint32_t ch;
- Fecode++;
- GETCHARINC(ch, Fecode);
- GETCHARINC(fc, Feptr);
- if (ch == fc)
- {
- RRETURN(MATCH_NOMATCH); /* Caseful match */
- }
- else if (Fop == OP_NOTI) /* If caseless */
- {
- if (ch > 127)
- ch = UCD_OTHERCASE(ch);
- else
- ch = (mb->fcc)[ch];
- if (ch == fc) RRETURN(MATCH_NOMATCH);
- }
- }
-
- /* UCP without UTF is as above, but with one character per code unit. */
-
- else if (ucp)
- {
- uint32_t ch;
- fc = UCHAR21INC(Feptr);
- ch = Fecode[1];
- Fecode += 2;
-
- if (ch == fc)
- {
- RRETURN(MATCH_NOMATCH); /* Caseful match */
- }
- else if (Fop == OP_NOTI) /* If caseless */
- {
- if (ch > 127)
- ch = UCD_OTHERCASE(ch);
- else
- ch = (mb->fcc)[ch];
- if (ch == fc) RRETURN(MATCH_NOMATCH);
- }
- }
-
- else
-#endif /* SUPPORT_UNICODE */
-
- /* Neither UTF nor UCP is set */
-
- {
- uint32_t ch = Fecode[1];
- fc = UCHAR21INC(Feptr);
- if (ch == fc || (Fop == OP_NOTI && TABLE_GET(ch, mb->fcc, ch) == fc))
- RRETURN(MATCH_NOMATCH);
- Fecode += 2;
- }
- break;
-
-
- /* ===================================================================== */
- /* Match a single character repeatedly. */
-
-#define Loclength F->temp_size
-#define Lstart_eptr F->temp_sptr[0]
-#define Lcharptr F->temp_sptr[1]
-#define Lmin F->temp_32[0]
-#define Lmax F->temp_32[1]
-#define Lc F->temp_32[2]
-#define Loc F->temp_32[3]
-
- case OP_EXACT:
- case OP_EXACTI:
- Lmin = Lmax = GET2(Fecode, 1);
- Fecode += 1 + IMM2_SIZE;
- goto REPEATCHAR;
-
- case OP_POSUPTO:
- case OP_POSUPTOI:
- reptype = REPTYPE_POS;
- Lmin = 0;
- Lmax = GET2(Fecode, 1);
- Fecode += 1 + IMM2_SIZE;
- goto REPEATCHAR;
-
- case OP_UPTO:
- case OP_UPTOI:
- reptype = REPTYPE_MAX;
- Lmin = 0;
- Lmax = GET2(Fecode, 1);
- Fecode += 1 + IMM2_SIZE;
- goto REPEATCHAR;
-
- case OP_MINUPTO:
- case OP_MINUPTOI:
- reptype = REPTYPE_MIN;
- Lmin = 0;
- Lmax = GET2(Fecode, 1);
- Fecode += 1 + IMM2_SIZE;
- goto REPEATCHAR;
-
- case OP_POSSTAR:
- case OP_POSSTARI:
- reptype = REPTYPE_POS;
- Lmin = 0;
- Lmax = UINT32_MAX;
- Fecode++;
- goto REPEATCHAR;
-
- case OP_POSPLUS:
- case OP_POSPLUSI:
- reptype = REPTYPE_POS;
- Lmin = 1;
- Lmax = UINT32_MAX;
- Fecode++;
- goto REPEATCHAR;
-
- case OP_POSQUERY:
- case OP_POSQUERYI:
- reptype = REPTYPE_POS;
- Lmin = 0;
- Lmax = 1;
- Fecode++;
- goto REPEATCHAR;
-
- case OP_STAR:
- case OP_STARI:
- case OP_MINSTAR:
- case OP_MINSTARI:
- case OP_PLUS:
- case OP_PLUSI:
- case OP_MINPLUS:
- case OP_MINPLUSI:
- case OP_QUERY:
- case OP_QUERYI:
- case OP_MINQUERY:
- case OP_MINQUERYI:
- fc = *Fecode++ - ((Fop < OP_STARI)? OP_STAR : OP_STARI);
- Lmin = rep_min[fc];
- Lmax = rep_max[fc];
- reptype = rep_typ[fc];
-
- /* Common code for all repeated single-character matches. We first check
- for the minimum number of characters. If the minimum equals the maximum, we
- are done. Otherwise, if minimizing, check the rest of the pattern for a
- match; if there isn't one, advance up to the maximum, one character at a
- time.
-
- If maximizing, advance up to the maximum number of matching characters,
- until Feptr is past the end of the maximum run. If possessive, we are
- then done (no backing up). Otherwise, match at this position; anything
- other than no match is immediately returned. For nomatch, back up one
- character, unless we are matching \R and the last thing matched was
- \r\n, in which case, back up two code units until we reach the first
- optional character position.
-
- The various UTF/non-UTF and caseful/caseless cases are handled separately,
- for speed. */
-
- REPEATCHAR:
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- Flength = 1;
- Lcharptr = Fecode;
- GETCHARLEN(fc, Fecode, Flength);
- Fecode += Flength;
-
- /* Handle multi-code-unit character matching, caseful and caseless. */
-
- if (Flength > 1)
- {
- uint32_t othercase;
-
- if (Fop >= OP_STARI && /* Caseless */
- (othercase = UCD_OTHERCASE(fc)) != fc)
- Loclength = PRIV(ord2utf)(othercase, Foccu);
- else Loclength = 0;
-
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr <= mb->end_subject - Flength &&
- memcmp(Feptr, Lcharptr, CU2BYTES(Flength)) == 0) Feptr += Flength;
- else if (Loclength > 0 &&
- Feptr <= mb->end_subject - Loclength &&
- memcmp(Feptr, Foccu, CU2BYTES(Loclength)) == 0)
- Feptr += Loclength;
- else
- {
- CHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- }
-
- if (Lmin == Lmax) continue;
-
- if (reptype == REPTYPE_MIN)
- {
- for (;;)
- {
- RMATCH(Fecode, RM202);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr <= mb->end_subject - Flength &&
- memcmp(Feptr, Lcharptr, CU2BYTES(Flength)) == 0) Feptr += Flength;
- else if (Loclength > 0 &&
- Feptr <= mb->end_subject - Loclength &&
- memcmp(Feptr, Foccu, CU2BYTES(Loclength)) == 0)
- Feptr += Loclength;
- else
- {
- CHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- }
- /* Control never gets here */
- }
-
- else /* Maximize */
- {
- Lstart_eptr = Feptr;
- for (i = Lmin; i < Lmax; i++)
- {
- if (Feptr <= mb->end_subject - Flength &&
- memcmp(Feptr, Lcharptr, CU2BYTES(Flength)) == 0)
- Feptr += Flength;
- else if (Loclength > 0 &&
- Feptr <= mb->end_subject - Loclength &&
- memcmp(Feptr, Foccu, CU2BYTES(Loclength)) == 0)
- Feptr += Loclength;
- else
- {
- CHECK_PARTIAL();
- break;
- }
- }
-
- /* After \C in UTF mode, Lstart_eptr might be in the middle of a
- Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't
- go too far. */
-
- if (reptype != REPTYPE_POS) for(;;)
- {
- if (Feptr <= Lstart_eptr) break;
- RMATCH(Fecode, RM203);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- Feptr--;
- BACKCHAR(Feptr);
- }
- }
- break; /* End of repeated wide character handling */
- }
-
- /* Length of UTF character is 1. Put it into the preserved variable and
- fall through to the non-UTF code. */
-
- Lc = fc;
- }
- else
-#endif /* SUPPORT_UNICODE */
-
- /* When not in UTF mode, load a single-code-unit character. Then proceed as
- above, using Unicode casing if either UTF or UCP is set. */
-
- Lc = *Fecode++;
-
- /* Caseless comparison */
-
- if (Fop >= OP_STARI)
- {
-#if PCRE2_CODE_UNIT_WIDTH == 8
-#ifdef SUPPORT_UNICODE
- if (ucp && !utf && Lc > 127) Loc = UCD_OTHERCASE(Lc);
- else
-#endif /* SUPPORT_UNICODE */
- /* Lc will be < 128 in UTF-8 mode. */
- Loc = mb->fcc[Lc];
-#else /* 16-bit & 32-bit */
-#ifdef SUPPORT_UNICODE
- if ((utf || ucp) && Lc > 127) Loc = UCD_OTHERCASE(Lc);
- else
-#endif /* SUPPORT_UNICODE */
- Loc = TABLE_GET(Lc, mb->fcc, Lc);
-#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
-
- for (i = 1; i <= Lmin; i++)
- {
- uint32_t cc; /* Faster than PCRE2_UCHAR */
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- cc = UCHAR21TEST(Feptr);
- if (Lc != cc && Loc != cc) RRETURN(MATCH_NOMATCH);
- Feptr++;
- }
- if (Lmin == Lmax) continue;
-
- if (reptype == REPTYPE_MIN)
- {
- for (;;)
- {
- uint32_t cc; /* Faster than PCRE2_UCHAR */
- RMATCH(Fecode, RM25);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- cc = UCHAR21TEST(Feptr);
- if (Lc != cc && Loc != cc) RRETURN(MATCH_NOMATCH);
- Feptr++;
- }
- /* Control never gets here */
- }
-
- else /* Maximize */
- {
- Lstart_eptr = Feptr;
- for (i = Lmin; i < Lmax; i++)
- {
- uint32_t cc; /* Faster than PCRE2_UCHAR */
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- cc = UCHAR21TEST(Feptr);
- if (Lc != cc && Loc != cc) break;
- Feptr++;
- }
- if (reptype != REPTYPE_POS) for (;;)
- {
- if (Feptr == Lstart_eptr) break;
- RMATCH(Fecode, RM26);
- Feptr--;
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- }
- }
- }
-
- /* Caseful comparisons (includes all multi-byte characters) */
-
- else
- {
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (Lc != UCHAR21INCTEST(Feptr)) RRETURN(MATCH_NOMATCH);
- }
-
- if (Lmin == Lmax) continue;
-
- if (reptype == REPTYPE_MIN)
- {
- for (;;)
- {
- RMATCH(Fecode, RM27);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (Lc != UCHAR21INCTEST(Feptr)) RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
- }
- else /* Maximize */
- {
- Lstart_eptr = Feptr;
- for (i = Lmin; i < Lmax; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
-
- if (Lc != UCHAR21TEST(Feptr)) break;
- Feptr++;
- }
-
- if (reptype != REPTYPE_POS) for (;;)
- {
- if (Feptr <= Lstart_eptr) break;
- RMATCH(Fecode, RM28);
- Feptr--;
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- }
- }
- }
- break;
-
-#undef Loclength
-#undef Lstart_eptr
-#undef Lcharptr
-#undef Lmin
-#undef Lmax
-#undef Lc
-#undef Loc
-
-
- /* ===================================================================== */
- /* Match a negated single one-byte character repeatedly. This is almost a
- repeat of the code for a repeated single character, but I haven't found a
- nice way of commoning these up that doesn't require a test of the
- positive/negative option for each character match. Maybe that wouldn't add
- very much to the time taken, but character matching *is* what this is all
- about... */
-
-#define Lstart_eptr F->temp_sptr[0]
-#define Lmin F->temp_32[0]
-#define Lmax F->temp_32[1]
-#define Lc F->temp_32[2]
-#define Loc F->temp_32[3]
-
- case OP_NOTEXACT:
- case OP_NOTEXACTI:
- Lmin = Lmax = GET2(Fecode, 1);
- Fecode += 1 + IMM2_SIZE;
- goto REPEATNOTCHAR;
-
- case OP_NOTUPTO:
- case OP_NOTUPTOI:
- Lmin = 0;
- Lmax = GET2(Fecode, 1);
- reptype = REPTYPE_MAX;
- Fecode += 1 + IMM2_SIZE;
- goto REPEATNOTCHAR;
-
- case OP_NOTMINUPTO:
- case OP_NOTMINUPTOI:
- Lmin = 0;
- Lmax = GET2(Fecode, 1);
- reptype = REPTYPE_MIN;
- Fecode += 1 + IMM2_SIZE;
- goto REPEATNOTCHAR;
-
- case OP_NOTPOSSTAR:
- case OP_NOTPOSSTARI:
- reptype = REPTYPE_POS;
- Lmin = 0;
- Lmax = UINT32_MAX;
- Fecode++;
- goto REPEATNOTCHAR;
-
- case OP_NOTPOSPLUS:
- case OP_NOTPOSPLUSI:
- reptype = REPTYPE_POS;
- Lmin = 1;
- Lmax = UINT32_MAX;
- Fecode++;
- goto REPEATNOTCHAR;
-
- case OP_NOTPOSQUERY:
- case OP_NOTPOSQUERYI:
- reptype = REPTYPE_POS;
- Lmin = 0;
- Lmax = 1;
- Fecode++;
- goto REPEATNOTCHAR;
-
- case OP_NOTPOSUPTO:
- case OP_NOTPOSUPTOI:
- reptype = REPTYPE_POS;
- Lmin = 0;
- Lmax = GET2(Fecode, 1);
- Fecode += 1 + IMM2_SIZE;
- goto REPEATNOTCHAR;
-
- case OP_NOTSTAR:
- case OP_NOTSTARI:
- case OP_NOTMINSTAR:
- case OP_NOTMINSTARI:
- case OP_NOTPLUS:
- case OP_NOTPLUSI:
- case OP_NOTMINPLUS:
- case OP_NOTMINPLUSI:
- case OP_NOTQUERY:
- case OP_NOTQUERYI:
- case OP_NOTMINQUERY:
- case OP_NOTMINQUERYI:
- fc = *Fecode++ - ((Fop >= OP_NOTSTARI)? OP_NOTSTARI: OP_NOTSTAR);
- Lmin = rep_min[fc];
- Lmax = rep_max[fc];
- reptype = rep_typ[fc];
-
- /* Common code for all repeated single-character non-matches. */
-
- REPEATNOTCHAR:
- GETCHARINCTEST(Lc, Fecode);
-
- /* The code is duplicated for the caseless and caseful cases, for speed,
- since matching characters is likely to be quite common. First, ensure the
- minimum number of matches are present. If Lmin = Lmax, we are done.
- Otherwise, if minimizing, keep trying the rest of the expression and
- advancing one matching character if failing, up to the maximum.
- Alternatively, if maximizing, find the maximum number of characters and
- work backwards. */
-
- if (Fop >= OP_NOTSTARI) /* Caseless */
- {
-#ifdef SUPPORT_UNICODE
- if ((utf || ucp) && Lc > 127)
- Loc = UCD_OTHERCASE(Lc);
- else
-#endif /* SUPPORT_UNICODE */
-
- Loc = TABLE_GET(Lc, mb->fcc, Lc); /* Other case from table */
-
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- uint32_t d;
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(d, Feptr);
- if (Lc == d || Loc == d) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif /* SUPPORT_UNICODE */
-
- /* Not UTF mode */
- {
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (Lc == *Feptr || Loc == *Feptr) RRETURN(MATCH_NOMATCH);
- Feptr++;
- }
- }
-
- if (Lmin == Lmax) continue; /* Finished for exact count */
-
- if (reptype == REPTYPE_MIN)
- {
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- uint32_t d;
- for (;;)
- {
- RMATCH(Fecode, RM204);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(d, Feptr);
- if (Lc == d || Loc == d) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif /*SUPPORT_UNICODE */
-
- /* Not UTF mode */
- {
- for (;;)
- {
- RMATCH(Fecode, RM29);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (Lc == *Feptr || Loc == *Feptr) RRETURN(MATCH_NOMATCH);
- Feptr++;
- }
- }
- /* Control never gets here */
- }
-
- /* Maximize case */
-
- else
- {
- Lstart_eptr = Feptr;
-
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- uint32_t d;
- for (i = Lmin; i < Lmax; i++)
- {
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(d, Feptr, len);
- if (Lc == d || Loc == d) break;
- Feptr += len;
- }
-
- /* After \C in UTF mode, Lstart_eptr might be in the middle of a
- Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't
- go too far. */
-
- if (reptype != REPTYPE_POS) for(;;)
- {
- if (Feptr <= Lstart_eptr) break;
- RMATCH(Fecode, RM205);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- Feptr--;
- BACKCHAR(Feptr);
- }
- }
- else
-#endif /* SUPPORT_UNICODE */
-
- /* Not UTF mode */
- {
- for (i = Lmin; i < Lmax; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (Lc == *Feptr || Loc == *Feptr) break;
- Feptr++;
- }
- if (reptype != REPTYPE_POS) for (;;)
- {
- if (Feptr == Lstart_eptr) break;
- RMATCH(Fecode, RM30);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- Feptr--;
- }
- }
- }
- }
-
- /* Caseful comparisons */
-
- else
- {
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- uint32_t d;
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(d, Feptr);
- if (Lc == d) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (Lc == *Feptr++) RRETURN(MATCH_NOMATCH);
- }
- }
-
- if (Lmin == Lmax) continue;
-
- if (reptype == REPTYPE_MIN)
- {
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- uint32_t d;
- for (;;)
- {
- RMATCH(Fecode, RM206);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(d, Feptr);
- if (Lc == d) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (;;)
- {
- RMATCH(Fecode, RM31);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (Lc == *Feptr++) RRETURN(MATCH_NOMATCH);
- }
- }
- /* Control never gets here */
- }
-
- /* Maximize case */
-
- else
- {
- Lstart_eptr = Feptr;
-
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- uint32_t d;
- for (i = Lmin; i < Lmax; i++)
- {
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(d, Feptr, len);
- if (Lc == d) break;
- Feptr += len;
- }
-
- /* After \C in UTF mode, Lstart_eptr might be in the middle of a
- Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't
- go too far. */
-
- if (reptype != REPTYPE_POS) for(;;)
- {
- if (Feptr <= Lstart_eptr) break;
- RMATCH(Fecode, RM207);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- Feptr--;
- BACKCHAR(Feptr);
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (i = Lmin; i < Lmax; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (Lc == *Feptr) break;
- Feptr++;
- }
- if (reptype != REPTYPE_POS) for (;;)
- {
- if (Feptr == Lstart_eptr) break;
- RMATCH(Fecode, RM32);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- Feptr--;
- }
- }
- }
- }
- break;
-
-#undef Lstart_eptr
-#undef Lmin
-#undef Lmax
-#undef Lc
-#undef Loc
-
-
- /* ===================================================================== */
- /* Match a bit-mapped character class, possibly repeatedly. These opcodes
- are used when all the characters in the class have values in the range
- 0-255, and either the matching is caseful, or the characters are in the
- range 0-127 when UTF processing is enabled. The only difference between
- OP_CLASS and OP_NCLASS occurs when a data character outside the range is
- encountered. */
-
-#define Lmin F->temp_32[0]
-#define Lmax F->temp_32[1]
-#define Lstart_eptr F->temp_sptr[0]
-#define Lbyte_map_address F->temp_sptr[1]
-#define Lbyte_map ((unsigned char *)Lbyte_map_address)
-
- case OP_NCLASS:
- case OP_CLASS:
- {
- Lbyte_map_address = Fecode + 1; /* Save for matching */
- Fecode += 1 + (32 / sizeof(PCRE2_UCHAR)); /* Advance past the item */
-
- /* Look past the end of the item to see if there is repeat information
- following. Then obey similar code to character type repeats. */
-
- switch (*Fecode)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- case OP_CRPOSSTAR:
- case OP_CRPOSPLUS:
- case OP_CRPOSQUERY:
- fc = *Fecode++ - OP_CRSTAR;
- Lmin = rep_min[fc];
- Lmax = rep_max[fc];
- reptype = rep_typ[fc];
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- case OP_CRPOSRANGE:
- Lmin = GET2(Fecode, 1);
- Lmax = GET2(Fecode, 1 + IMM2_SIZE);
- if (Lmax == 0) Lmax = UINT32_MAX; /* Max 0 => infinity */
- reptype = rep_typ[*Fecode - OP_CRSTAR];
- Fecode += 1 + 2 * IMM2_SIZE;
- break;
-
- default: /* No repeat follows */
- Lmin = Lmax = 1;
- break;
- }
-
- /* First, ensure the minimum number of matches are present. */
-
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(fc, Feptr);
- if (fc > 255)
- {
- if (Fop == OP_CLASS) RRETURN(MATCH_NOMATCH);
- }
- else
- if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- fc = *Feptr++;
-#if PCRE2_CODE_UNIT_WIDTH != 8
- if (fc > 255)
- {
- if (Fop == OP_CLASS) RRETURN(MATCH_NOMATCH);
- }
- else
-#endif
- if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) RRETURN(MATCH_NOMATCH);
- }
- }
-
- /* If Lmax == Lmin we are done. Continue with main loop. */
-
- if (Lmin == Lmax) continue;
-
- /* If minimizing, keep testing the rest of the expression and advancing
- the pointer while it matches the class. */
-
- if (reptype == REPTYPE_MIN)
- {
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- for (;;)
- {
- RMATCH(Fecode, RM200);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(fc, Feptr);
- if (fc > 255)
- {
- if (Fop == OP_CLASS) RRETURN(MATCH_NOMATCH);
- }
- else
- if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (;;)
- {
- RMATCH(Fecode, RM23);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- fc = *Feptr++;
-#if PCRE2_CODE_UNIT_WIDTH != 8
- if (fc > 255)
- {
- if (Fop == OP_CLASS) RRETURN(MATCH_NOMATCH);
- }
- else
-#endif
- if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) RRETURN(MATCH_NOMATCH);
- }
- }
- /* Control never gets here */
- }
-
- /* If maximizing, find the longest possible run, then work backwards. */
-
- else
- {
- Lstart_eptr = Feptr;
-
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- for (i = Lmin; i < Lmax; i++)
- {
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(fc, Feptr, len);
- if (fc > 255)
- {
- if (Fop == OP_CLASS) break;
- }
- else
- if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) break;
- Feptr += len;
- }
-
- if (reptype == REPTYPE_POS) continue; /* No backtracking */
-
- /* After \C in UTF mode, Lstart_eptr might be in the middle of a
- Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't
- go too far. */
-
- for (;;)
- {
- RMATCH(Fecode, RM201);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Feptr-- <= Lstart_eptr) break; /* Tried at original position */
- BACKCHAR(Feptr);
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (i = Lmin; i < Lmax; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- fc = *Feptr;
-#if PCRE2_CODE_UNIT_WIDTH != 8
- if (fc > 255)
- {
- if (Fop == OP_CLASS) break;
- }
- else
-#endif
- if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) break;
- Feptr++;
- }
-
- if (reptype == REPTYPE_POS) continue; /* No backtracking */
-
- while (Feptr >= Lstart_eptr)
- {
- RMATCH(Fecode, RM24);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- Feptr--;
- }
- }
-
- RRETURN(MATCH_NOMATCH);
- }
- }
- /* Control never gets here */
-
-#undef Lbyte_map_address
-#undef Lbyte_map
-#undef Lstart_eptr
-#undef Lmin
-#undef Lmax
-
-
- /* ===================================================================== */
- /* Match an extended character class. In the 8-bit library, this opcode is
- encountered only when UTF-8 mode mode is supported. In the 16-bit and
- 32-bit libraries, codepoints greater than 255 may be encountered even when
- UTF is not supported. */
-
-#define Lstart_eptr F->temp_sptr[0]
-#define Lxclass_data F->temp_sptr[1]
-#define Lmin F->temp_32[0]
-#define Lmax F->temp_32[1]
-
-#ifdef SUPPORT_WIDE_CHARS
- case OP_XCLASS:
- {
- Lxclass_data = Fecode + 1 + LINK_SIZE; /* Save for matching */
- Fecode += GET(Fecode, 1); /* Advance past the item */
-
- switch (*Fecode)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- case OP_CRPOSSTAR:
- case OP_CRPOSPLUS:
- case OP_CRPOSQUERY:
- fc = *Fecode++ - OP_CRSTAR;
- Lmin = rep_min[fc];
- Lmax = rep_max[fc];
- reptype = rep_typ[fc];
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- case OP_CRPOSRANGE:
- Lmin = GET2(Fecode, 1);
- Lmax = GET2(Fecode, 1 + IMM2_SIZE);
- if (Lmax == 0) Lmax = UINT32_MAX; /* Max 0 => infinity */
- reptype = rep_typ[*Fecode - OP_CRSTAR];
- Fecode += 1 + 2 * IMM2_SIZE;
- break;
-
- default: /* No repeat follows */
- Lmin = Lmax = 1;
- break;
- }
-
- /* First, ensure the minimum number of matches are present. */
-
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- if (!PRIV(xclass)(fc, Lxclass_data, utf)) RRETURN(MATCH_NOMATCH);
- }
-
- /* If Lmax == Lmin we can just continue with the main loop. */
-
- if (Lmin == Lmax) continue;
-
- /* If minimizing, keep testing the rest of the expression and advancing
- the pointer while it matches the class. */
-
- if (reptype == REPTYPE_MIN)
- {
- for (;;)
- {
- RMATCH(Fecode, RM100);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- if (!PRIV(xclass)(fc, Lxclass_data, utf)) RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
- }
-
- /* If maximizing, find the longest possible run, then work backwards. */
-
- else
- {
- Lstart_eptr = Feptr;
- for (i = Lmin; i < Lmax; i++)
- {
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
-#ifdef SUPPORT_UNICODE
- GETCHARLENTEST(fc, Feptr, len);
-#else
- fc = *Feptr;
-#endif
- if (!PRIV(xclass)(fc, Lxclass_data, utf)) break;
- Feptr += len;
- }
-
- if (reptype == REPTYPE_POS) continue; /* No backtracking */
-
- /* After \C in UTF mode, Lstart_eptr might be in the middle of a
- Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't
- go too far. */
-
- for(;;)
- {
- RMATCH(Fecode, RM101);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Feptr-- <= Lstart_eptr) break; /* Tried at original position */
-#ifdef SUPPORT_UNICODE
- if (utf) BACKCHAR(Feptr);
-#endif
- }
- RRETURN(MATCH_NOMATCH);
- }
-
- /* Control never gets here */
- }
-#endif /* SUPPORT_WIDE_CHARS: end of XCLASS */
-
-#undef Lstart_eptr
-#undef Lxclass_data
-#undef Lmin
-#undef Lmax
-
-
- /* ===================================================================== */
- /* Match various character types when PCRE2_UCP is not set. These opcodes
- are not generated when PCRE2_UCP is set - instead appropriate property
- tests are compiled. */
-
- case OP_NOT_DIGIT:
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- if (CHMAX_255(fc) && (mb->ctypes[fc] & ctype_digit) != 0)
- RRETURN(MATCH_NOMATCH);
- Fecode++;
- break;
-
- case OP_DIGIT:
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- if (!CHMAX_255(fc) || (mb->ctypes[fc] & ctype_digit) == 0)
- RRETURN(MATCH_NOMATCH);
- Fecode++;
- break;
-
- case OP_NOT_WHITESPACE:
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- if (CHMAX_255(fc) && (mb->ctypes[fc] & ctype_space) != 0)
- RRETURN(MATCH_NOMATCH);
- Fecode++;
- break;
-
- case OP_WHITESPACE:
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- if (!CHMAX_255(fc) || (mb->ctypes[fc] & ctype_space) == 0)
- RRETURN(MATCH_NOMATCH);
- Fecode++;
- break;
-
- case OP_NOT_WORDCHAR:
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- if (CHMAX_255(fc) && (mb->ctypes[fc] & ctype_word) != 0)
- RRETURN(MATCH_NOMATCH);
- Fecode++;
- break;
-
- case OP_WORDCHAR:
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- if (!CHMAX_255(fc) || (mb->ctypes[fc] & ctype_word) == 0)
- RRETURN(MATCH_NOMATCH);
- Fecode++;
- break;
-
- case OP_ANYNL:
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- switch(fc)
- {
- default: RRETURN(MATCH_NOMATCH);
-
- case CHAR_CR:
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- }
- else if (UCHAR21TEST(Feptr) == CHAR_LF) Feptr++;
- break;
-
- case CHAR_LF:
- break;
-
- case CHAR_VT:
- case CHAR_FF:
- case CHAR_NEL:
-#ifndef EBCDIC
- case 0x2028:
- case 0x2029:
-#endif /* Not EBCDIC */
- if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH);
- break;
- }
- Fecode++;
- break;
-
- case OP_NOT_HSPACE:
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- switch(fc)
- {
- HSPACE_CASES: RRETURN(MATCH_NOMATCH); /* Byte and multibyte cases */
- default: break;
- }
- Fecode++;
- break;
-
- case OP_HSPACE:
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- switch(fc)
- {
- HSPACE_CASES: break; /* Byte and multibyte cases */
- default: RRETURN(MATCH_NOMATCH);
- }
- Fecode++;
- break;
-
- case OP_NOT_VSPACE:
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- switch(fc)
- {
- VSPACE_CASES: RRETURN(MATCH_NOMATCH);
- default: break;
- }
- Fecode++;
- break;
-
- case OP_VSPACE:
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- switch(fc)
- {
- VSPACE_CASES: break;
- default: RRETURN(MATCH_NOMATCH);
- }
- Fecode++;
- break;
-
-
-#ifdef SUPPORT_UNICODE
-
- /* ===================================================================== */
- /* Check the next character by Unicode property. We will get here only
- if the support is in the binary; otherwise a compile-time error occurs. */
-
- case OP_PROP:
- case OP_NOTPROP:
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- {
- const uint32_t *cp;
- const ucd_record *prop = GET_UCD(fc);
- BOOL notmatch = Fop == OP_NOTPROP;
-
- switch(Fecode[1])
- {
- case PT_ANY:
- if (notmatch) RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_LAMP:
- if ((prop->chartype == ucp_Lu ||
- prop->chartype == ucp_Ll ||
- prop->chartype == ucp_Lt) == notmatch)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_GC:
- if ((Fecode[2] == PRIV(ucp_gentype)[prop->chartype]) == notmatch)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_PC:
- if ((Fecode[2] == prop->chartype) == notmatch)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_SC:
- if ((Fecode[2] == prop->script) == notmatch)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_SCX:
- {
- BOOL ok = (Fecode[2] == prop->script ||
- MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), Fecode[2]) != 0);
- if (ok == notmatch) RRETURN(MATCH_NOMATCH);
- }
- break;
-
- /* These are specials */
-
- case PT_ALNUM:
- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N) == notmatch)
- RRETURN(MATCH_NOMATCH);
- break;
-
- /* Perl space used to exclude VT, but from Perl 5.18 it is included,
- which means that Perl space and POSIX space are now identical. PCRE
- was changed at release 8.34. */
-
- case PT_SPACE: /* Perl space */
- case PT_PXSPACE: /* POSIX space */
- switch(fc)
- {
- HSPACE_CASES:
- VSPACE_CASES:
- if (notmatch) RRETURN(MATCH_NOMATCH);
- break;
-
- default:
- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == notmatch)
- RRETURN(MATCH_NOMATCH);
- break;
- }
- break;
-
- case PT_WORD:
- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
- fc == CHAR_UNDERSCORE) == notmatch)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_CLIST:
- cp = PRIV(ucd_caseless_sets) + Fecode[2];
- for (;;)
- {
- if (fc < *cp)
- { if (notmatch) break; else { RRETURN(MATCH_NOMATCH); } }
- if (fc == *cp++)
- { if (notmatch) { RRETURN(MATCH_NOMATCH); } else break; }
- }
- break;
-
- case PT_UCNC:
- if ((fc == CHAR_DOLLAR_SIGN || fc == CHAR_COMMERCIAL_AT ||
- fc == CHAR_GRAVE_ACCENT || (fc >= 0xa0 && fc <= 0xd7ff) ||
- fc >= 0xe000) == notmatch)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_BIDICL:
- if ((UCD_BIDICLASS_PROP(prop) == Fecode[2]) == notmatch)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_BOOL:
- {
- BOOL ok = MAPBIT(PRIV(ucd_boolprop_sets) +
- UCD_BPROPS_PROP(prop), Fecode[2]) != 0;
- if (ok == notmatch) RRETURN(MATCH_NOMATCH);
- }
- break;
-
- /* This should never occur */
-
- default:
- return PCRE2_ERROR_INTERNAL;
- }
-
- Fecode += 3;
- }
- break;
-
-
- /* ===================================================================== */
- /* Match an extended Unicode sequence. We will get here only if the support
- is in the binary; otherwise a compile-time error occurs. */
-
- case OP_EXTUNI:
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- else
- {
- GETCHARINCTEST(fc, Feptr);
- Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject, mb->end_subject, utf,
- NULL);
- }
- CHECK_PARTIAL();
- Fecode++;
- break;
-
-#endif /* SUPPORT_UNICODE */
-
-
- /* ===================================================================== */
- /* Match a single character type repeatedly. Note that the property type
- does not need to be in a stack frame as it is not used within an RMATCH()
- loop. */
-
-#define Lstart_eptr F->temp_sptr[0]
-#define Lmin F->temp_32[0]
-#define Lmax F->temp_32[1]
-#define Lctype F->temp_32[2]
-#define Lpropvalue F->temp_32[3]
-
- case OP_TYPEEXACT:
- Lmin = Lmax = GET2(Fecode, 1);
- Fecode += 1 + IMM2_SIZE;
- goto REPEATTYPE;
-
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- Lmin = 0;
- Lmax = GET2(Fecode, 1);
- reptype = (*Fecode == OP_TYPEMINUPTO)? REPTYPE_MIN : REPTYPE_MAX;
- Fecode += 1 + IMM2_SIZE;
- goto REPEATTYPE;
-
- case OP_TYPEPOSSTAR:
- reptype = REPTYPE_POS;
- Lmin = 0;
- Lmax = UINT32_MAX;
- Fecode++;
- goto REPEATTYPE;
-
- case OP_TYPEPOSPLUS:
- reptype = REPTYPE_POS;
- Lmin = 1;
- Lmax = UINT32_MAX;
- Fecode++;
- goto REPEATTYPE;
-
- case OP_TYPEPOSQUERY:
- reptype = REPTYPE_POS;
- Lmin = 0;
- Lmax = 1;
- Fecode++;
- goto REPEATTYPE;
-
- case OP_TYPEPOSUPTO:
- reptype = REPTYPE_POS;
- Lmin = 0;
- Lmax = GET2(Fecode, 1);
- Fecode += 1 + IMM2_SIZE;
- goto REPEATTYPE;
-
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- fc = *Fecode++ - OP_TYPESTAR;
- Lmin = rep_min[fc];
- Lmax = rep_max[fc];
- reptype = rep_typ[fc];
-
- /* Common code for all repeated character type matches. */
-
- REPEATTYPE:
- Lctype = *Fecode++; /* Code for the character type */
-
-#ifdef SUPPORT_UNICODE
- if (Lctype == OP_PROP || Lctype == OP_NOTPROP)
- {
- proptype = *Fecode++;
- Lpropvalue = *Fecode++;
- }
- else proptype = -1;
-#endif
-
- /* First, ensure the minimum number of matches are present. Use inline
- code for maximizing the speed, and do the type test once at the start
- (i.e. keep it out of the loops). As there are no calls to RMATCH in the
- loops, we can use an ordinary variable for "notmatch". The code for UTF
- mode is separated out for tidiness, except for Unicode property tests. */
-
- if (Lmin > 0)
- {
-#ifdef SUPPORT_UNICODE
- if (proptype >= 0) /* Property tests in all modes */
- {
- BOOL notmatch = Lctype == OP_NOTPROP;
- switch(proptype)
- {
- case PT_ANY:
- if (notmatch) RRETURN(MATCH_NOMATCH);
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- }
- break;
-
- case PT_LAMP:
- for (i = 1; i <= Lmin; i++)
- {
- int chartype;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- chartype = UCD_CHARTYPE(fc);
- if ((chartype == ucp_Lu ||
- chartype == ucp_Ll ||
- chartype == ucp_Lt) == notmatch)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_GC:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- if ((UCD_CATEGORY(fc) == Lpropvalue) == notmatch)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_PC:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- if ((UCD_CHARTYPE(fc) == Lpropvalue) == notmatch)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_SC:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- if ((UCD_SCRIPT(fc) == Lpropvalue) == notmatch)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_SCX:
- for (i = 1; i <= Lmin; i++)
- {
- BOOL ok;
- const ucd_record *prop;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- prop = GET_UCD(fc);
- ok = (prop->script == Lpropvalue ||
- MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), Lpropvalue) != 0);
- if (ok == notmatch)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_ALNUM:
- for (i = 1; i <= Lmin; i++)
- {
- int category;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- category = UCD_CATEGORY(fc);
- if ((category == ucp_L || category == ucp_N) == notmatch)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- /* Perl space used to exclude VT, but from Perl 5.18 it is included,
- which means that Perl space and POSIX space are now identical. PCRE
- was changed at release 8.34. */
-
- case PT_SPACE: /* Perl space */
- case PT_PXSPACE: /* POSIX space */
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- switch(fc)
- {
- HSPACE_CASES:
- VSPACE_CASES:
- if (notmatch) RRETURN(MATCH_NOMATCH);
- break;
-
- default:
- if ((UCD_CATEGORY(fc) == ucp_Z) == notmatch)
- RRETURN(MATCH_NOMATCH);
- break;
- }
- }
- break;
-
- case PT_WORD:
- for (i = 1; i <= Lmin; i++)
- {
- int category;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- category = UCD_CATEGORY(fc);
- if ((category == ucp_L || category == ucp_N ||
- fc == CHAR_UNDERSCORE) == notmatch)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_CLIST:
- for (i = 1; i <= Lmin; i++)
- {
- const uint32_t *cp;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- cp = PRIV(ucd_caseless_sets) + Lpropvalue;
- for (;;)
- {
- if (fc < *cp)
- {
- if (notmatch) break;
- RRETURN(MATCH_NOMATCH);
- }
- if (fc == *cp++)
- {
- if (notmatch) RRETURN(MATCH_NOMATCH);
- break;
- }
- }
- }
- break;
-
- case PT_UCNC:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- if ((fc == CHAR_DOLLAR_SIGN || fc == CHAR_COMMERCIAL_AT ||
- fc == CHAR_GRAVE_ACCENT || (fc >= 0xa0 && fc <= 0xd7ff) ||
- fc >= 0xe000) == notmatch)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_BIDICL:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- if ((UCD_BIDICLASS(fc) == Lpropvalue) == notmatch)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_BOOL:
- for (i = 1; i <= Lmin; i++)
- {
- BOOL ok;
- const ucd_record *prop;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- prop = GET_UCD(fc);
- ok = MAPBIT(PRIV(ucd_boolprop_sets) +
- UCD_BPROPS_PROP(prop), Lpropvalue) != 0;
- if (ok == notmatch)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- /* This should not occur */
-
- default:
- return PCRE2_ERROR_INTERNAL;
- }
- }
-
- /* Match extended Unicode sequences. We will get here only if the
- support is in the binary; otherwise a compile-time error occurs. */
-
- else if (Lctype == OP_EXTUNI)
- {
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- else
- {
- GETCHARINCTEST(fc, Feptr);
- Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject,
- mb->end_subject, utf, NULL);
- }
- CHECK_PARTIAL();
- }
- }
- else
-#endif /* SUPPORT_UNICODE */
-
-/* Handle all other cases in UTF mode */
-
-#ifdef SUPPORT_UNICODE
- if (utf) switch(Lctype)
- {
- case OP_ANY:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (IS_NEWLINE(Feptr)) RRETURN(MATCH_NOMATCH);
- if (mb->partial != 0 &&
- Feptr + 1 >= mb->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- UCHAR21(Feptr) == NLBLOCK->nl[0])
- {
- mb->hitend = TRUE;
- if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
- }
- Feptr++;
- ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);
- }
- break;
-
- case OP_ALLANY:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- Feptr++;
- ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);
- }
- break;
-
- case OP_ANYBYTE:
- if (Feptr > mb->end_subject - Lmin) RRETURN(MATCH_NOMATCH);
- Feptr += Lmin;
- break;
-
- case OP_ANYNL:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(fc, Feptr);
- switch(fc)
- {
- default: RRETURN(MATCH_NOMATCH);
-
- case CHAR_CR:
- if (Feptr < mb->end_subject && UCHAR21(Feptr) == CHAR_LF) Feptr++;
- break;
-
- case CHAR_LF:
- break;
-
- case CHAR_VT:
- case CHAR_FF:
- case CHAR_NEL:
-#ifndef EBCDIC
- case 0x2028:
- case 0x2029:
-#endif /* Not EBCDIC */
- if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH);
- break;
- }
- }
- break;
-
- case OP_NOT_HSPACE:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(fc, Feptr);
- switch(fc)
- {
- HSPACE_CASES: RRETURN(MATCH_NOMATCH);
- default: break;
- }
- }
- break;
-
- case OP_HSPACE:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(fc, Feptr);
- switch(fc)
- {
- HSPACE_CASES: break;
- default: RRETURN(MATCH_NOMATCH);
- }
- }
- break;
-
- case OP_NOT_VSPACE:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(fc, Feptr);
- switch(fc)
- {
- VSPACE_CASES: RRETURN(MATCH_NOMATCH);
- default: break;
- }
- }
- break;
-
- case OP_VSPACE:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(fc, Feptr);
- switch(fc)
- {
- VSPACE_CASES: break;
- default: RRETURN(MATCH_NOMATCH);
- }
- }
- break;
-
- case OP_NOT_DIGIT:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(fc, Feptr);
- if (fc < 128 && (mb->ctypes[fc] & ctype_digit) != 0)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case OP_DIGIT:
- for (i = 1; i <= Lmin; i++)
- {
- uint32_t cc;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- cc = UCHAR21(Feptr);
- if (cc >= 128 || (mb->ctypes[cc] & ctype_digit) == 0)
- RRETURN(MATCH_NOMATCH);
- Feptr++;
- /* No need to skip more code units - we know it has only one. */
- }
- break;
-
- case OP_NOT_WHITESPACE:
- for (i = 1; i <= Lmin; i++)
- {
- uint32_t cc;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- cc = UCHAR21(Feptr);
- if (cc < 128 && (mb->ctypes[cc] & ctype_space) != 0)
- RRETURN(MATCH_NOMATCH);
- Feptr++;
- ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);
- }
- break;
-
- case OP_WHITESPACE:
- for (i = 1; i <= Lmin; i++)
- {
- uint32_t cc;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- cc = UCHAR21(Feptr);
- if (cc >= 128 || (mb->ctypes[cc] & ctype_space) == 0)
- RRETURN(MATCH_NOMATCH);
- Feptr++;
- /* No need to skip more code units - we know it has only one. */
- }
- break;
-
- case OP_NOT_WORDCHAR:
- for (i = 1; i <= Lmin; i++)
- {
- uint32_t cc;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- cc = UCHAR21(Feptr);
- if (cc < 128 && (mb->ctypes[cc] & ctype_word) != 0)
- RRETURN(MATCH_NOMATCH);
- Feptr++;
- ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);
- }
- break;
-
- case OP_WORDCHAR:
- for (i = 1; i <= Lmin; i++)
- {
- uint32_t cc;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- cc = UCHAR21(Feptr);
- if (cc >= 128 || (mb->ctypes[cc] & ctype_word) == 0)
- RRETURN(MATCH_NOMATCH);
- Feptr++;
- /* No need to skip more code units - we know it has only one. */
- }
- break;
-
- default:
- return PCRE2_ERROR_INTERNAL;
- } /* End switch(Lctype) */
-
- else
-#endif /* SUPPORT_UNICODE */
-
- /* Code for the non-UTF case for minimum matching of operators other
- than OP_PROP and OP_NOTPROP. */
-
- switch(Lctype)
- {
- case OP_ANY:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (IS_NEWLINE(Feptr)) RRETURN(MATCH_NOMATCH);
- if (mb->partial != 0 &&
- Feptr + 1 >= mb->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- *Feptr == NLBLOCK->nl[0])
- {
- mb->hitend = TRUE;
- if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
- }
- Feptr++;
- }
- break;
-
- case OP_ALLANY:
- if (Feptr > mb->end_subject - Lmin)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- Feptr += Lmin;
- break;
-
- /* This OP_ANYBYTE case will never be reached because \C gets turned
- into OP_ALLANY in non-UTF mode. Cut out the code so that coverage
- reports don't complain about it's never being used. */
-
-/* case OP_ANYBYTE:
-* if (Feptr > mb->end_subject - Lmin)
-* {
-* SCHECK_PARTIAL();
-* RRETURN(MATCH_NOMATCH);
-* }
-* Feptr += Lmin;
-* break;
-*/
- case OP_ANYNL:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- switch(*Feptr++)
- {
- default: RRETURN(MATCH_NOMATCH);
-
- case CHAR_CR:
- if (Feptr < mb->end_subject && *Feptr == CHAR_LF) Feptr++;
- break;
-
- case CHAR_LF:
- break;
-
- case CHAR_VT:
- case CHAR_FF:
- case CHAR_NEL:
-#if PCRE2_CODE_UNIT_WIDTH != 8
- case 0x2028:
- case 0x2029:
-#endif
- if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH);
- break;
- }
- }
- break;
-
- case OP_NOT_HSPACE:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- switch(*Feptr++)
- {
- default: break;
- HSPACE_BYTE_CASES:
-#if PCRE2_CODE_UNIT_WIDTH != 8
- HSPACE_MULTIBYTE_CASES:
-#endif
- RRETURN(MATCH_NOMATCH);
- }
- }
- break;
-
- case OP_HSPACE:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- switch(*Feptr++)
- {
- default: RRETURN(MATCH_NOMATCH);
- HSPACE_BYTE_CASES:
-#if PCRE2_CODE_UNIT_WIDTH != 8
- HSPACE_MULTIBYTE_CASES:
-#endif
- break;
- }
- }
- break;
-
- case OP_NOT_VSPACE:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- switch(*Feptr++)
- {
- VSPACE_BYTE_CASES:
-#if PCRE2_CODE_UNIT_WIDTH != 8
- VSPACE_MULTIBYTE_CASES:
-#endif
- RRETURN(MATCH_NOMATCH);
- default: break;
- }
- }
- break;
-
- case OP_VSPACE:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- switch(*Feptr++)
- {
- default: RRETURN(MATCH_NOMATCH);
- VSPACE_BYTE_CASES:
-#if PCRE2_CODE_UNIT_WIDTH != 8
- VSPACE_MULTIBYTE_CASES:
-#endif
- break;
- }
- }
- break;
-
- case OP_NOT_DIGIT:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_digit) != 0)
- RRETURN(MATCH_NOMATCH);
- Feptr++;
- }
- break;
-
- case OP_DIGIT:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_digit) == 0)
- RRETURN(MATCH_NOMATCH);
- Feptr++;
- }
- break;
-
- case OP_NOT_WHITESPACE:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_space) != 0)
- RRETURN(MATCH_NOMATCH);
- Feptr++;
- }
- break;
-
- case OP_WHITESPACE:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_space) == 0)
- RRETURN(MATCH_NOMATCH);
- Feptr++;
- }
- break;
-
- case OP_NOT_WORDCHAR:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_word) != 0)
- RRETURN(MATCH_NOMATCH);
- Feptr++;
- }
- break;
-
- case OP_WORDCHAR:
- for (i = 1; i <= Lmin; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_word) == 0)
- RRETURN(MATCH_NOMATCH);
- Feptr++;
- }
- break;
-
- default:
- return PCRE2_ERROR_INTERNAL;
- }
- }
-
- /* If Lmin = Lmax we are done. Continue with the main loop. */
-
- if (Lmin == Lmax) continue;
-
- /* If minimizing, we have to test the rest of the pattern before each
- subsequent match. This means we cannot use a local "notmatch" variable as
- in the other cases. As all 4 temporary 32-bit values in the frame are
- already in use, just test the type each time. */
-
- if (reptype == REPTYPE_MIN)
- {
-#ifdef SUPPORT_UNICODE
- if (proptype >= 0)
- {
- switch(proptype)
- {
- case PT_ANY:
- for (;;)
- {
- RMATCH(Fecode, RM208);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- if (Lctype == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_LAMP:
- for (;;)
- {
- int chartype;
- RMATCH(Fecode, RM209);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- chartype = UCD_CHARTYPE(fc);
- if ((chartype == ucp_Lu ||
- chartype == ucp_Ll ||
- chartype == ucp_Lt) == (Lctype == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_GC:
- for (;;)
- {
- RMATCH(Fecode, RM210);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- if ((UCD_CATEGORY(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_PC:
- for (;;)
- {
- RMATCH(Fecode, RM211);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- if ((UCD_CHARTYPE(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_SC:
- for (;;)
- {
- RMATCH(Fecode, RM212);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- if ((UCD_SCRIPT(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_SCX:
- for (;;)
- {
- BOOL ok;
- const ucd_record *prop;
- RMATCH(Fecode, RM225);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- prop = GET_UCD(fc);
- ok = (prop->script == Lpropvalue
- || MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), Lpropvalue) != 0);
- if (ok == (Lctype == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_ALNUM:
- for (;;)
- {
- int category;
- RMATCH(Fecode, RM213);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- category = UCD_CATEGORY(fc);
- if ((category == ucp_L || category == ucp_N) == (Lctype == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- /* Perl space used to exclude VT, but from Perl 5.18 it is included,
- which means that Perl space and POSIX space are now identical. PCRE
- was changed at release 8.34. */
-
- case PT_SPACE: /* Perl space */
- case PT_PXSPACE: /* POSIX space */
- for (;;)
- {
- RMATCH(Fecode, RM214);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- switch(fc)
- {
- HSPACE_CASES:
- VSPACE_CASES:
- if (Lctype == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
- break;
-
- default:
- if ((UCD_CATEGORY(fc) == ucp_Z) == (Lctype == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- break;
- }
- }
- /* Control never gets here */
-
- case PT_WORD:
- for (;;)
- {
- int category;
- RMATCH(Fecode, RM215);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- category = UCD_CATEGORY(fc);
- if ((category == ucp_L ||
- category == ucp_N ||
- fc == CHAR_UNDERSCORE) == (Lctype == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_CLIST:
- for (;;)
- {
- const uint32_t *cp;
- RMATCH(Fecode, RM216);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- cp = PRIV(ucd_caseless_sets) + Lpropvalue;
- for (;;)
- {
- if (fc < *cp)
- {
- if (Lctype == OP_NOTPROP) break;
- RRETURN(MATCH_NOMATCH);
- }
- if (fc == *cp++)
- {
- if (Lctype == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
- break;
- }
- }
- }
- /* Control never gets here */
-
- case PT_UCNC:
- for (;;)
- {
- RMATCH(Fecode, RM217);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- if ((fc == CHAR_DOLLAR_SIGN || fc == CHAR_COMMERCIAL_AT ||
- fc == CHAR_GRAVE_ACCENT || (fc >= 0xa0 && fc <= 0xd7ff) ||
- fc >= 0xe000) == (Lctype == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_BIDICL:
- for (;;)
- {
- RMATCH(Fecode, RM224);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- if ((UCD_BIDICLASS(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_BOOL:
- for (;;)
- {
- BOOL ok;
- const ucd_record *prop;
- RMATCH(Fecode, RM223);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(fc, Feptr);
- prop = GET_UCD(fc);
- ok = MAPBIT(PRIV(ucd_boolprop_sets) +
- UCD_BPROPS_PROP(prop), Lpropvalue) != 0;
- if (ok == (Lctype == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- /* This should never occur */
- default:
- return PCRE2_ERROR_INTERNAL;
- }
- }
-
- /* Match extended Unicode sequences. We will get here only if the
- support is in the binary; otherwise a compile-time error occurs. */
-
- else if (Lctype == OP_EXTUNI)
- {
- for (;;)
- {
- RMATCH(Fecode, RM218);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- else
- {
- GETCHARINCTEST(fc, Feptr);
- Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject, mb->end_subject,
- utf, NULL);
- }
- CHECK_PARTIAL();
- }
- }
- else
-#endif /* SUPPORT_UNICODE */
-
- /* UTF mode for non-property testing character types. */
-
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- for (;;)
- {
- RMATCH(Fecode, RM219);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (Lctype == OP_ANY && IS_NEWLINE(Feptr)) RRETURN(MATCH_NOMATCH);
- GETCHARINC(fc, Feptr);
- switch(Lctype)
- {
- case OP_ANY: /* This is the non-NL case */
- if (mb->partial != 0 && /* Take care with CRLF partial */
- Feptr >= mb->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- fc == NLBLOCK->nl[0])
- {
- mb->hitend = TRUE;
- if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
- }
- break;
-
- case OP_ALLANY:
- case OP_ANYBYTE:
- break;
-
- case OP_ANYNL:
- switch(fc)
- {
- default: RRETURN(MATCH_NOMATCH);
-
- case CHAR_CR:
- if (Feptr < mb->end_subject && UCHAR21(Feptr) == CHAR_LF) Feptr++;
- break;
-
- case CHAR_LF:
- break;
-
- case CHAR_VT:
- case CHAR_FF:
- case CHAR_NEL:
-#ifndef EBCDIC
- case 0x2028:
- case 0x2029:
-#endif /* Not EBCDIC */
- if (mb->bsr_convention == PCRE2_BSR_ANYCRLF)
- RRETURN(MATCH_NOMATCH);
- break;
- }
- break;
-
- case OP_NOT_HSPACE:
- switch(fc)
- {
- HSPACE_CASES: RRETURN(MATCH_NOMATCH);
- default: break;
- }
- break;
-
- case OP_HSPACE:
- switch(fc)
- {
- HSPACE_CASES: break;
- default: RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case OP_NOT_VSPACE:
- switch(fc)
- {
- VSPACE_CASES: RRETURN(MATCH_NOMATCH);
- default: break;
- }
- break;
-
- case OP_VSPACE:
- switch(fc)
- {
- VSPACE_CASES: break;
- default: RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case OP_NOT_DIGIT:
- if (fc < 256 && (mb->ctypes[fc] & ctype_digit) != 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_DIGIT:
- if (fc >= 256 || (mb->ctypes[fc] & ctype_digit) == 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_NOT_WHITESPACE:
- if (fc < 256 && (mb->ctypes[fc] & ctype_space) != 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_WHITESPACE:
- if (fc >= 256 || (mb->ctypes[fc] & ctype_space) == 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_NOT_WORDCHAR:
- if (fc < 256 && (mb->ctypes[fc] & ctype_word) != 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_WORDCHAR:
- if (fc >= 256 || (mb->ctypes[fc] & ctype_word) == 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- default:
- return PCRE2_ERROR_INTERNAL;
- }
- }
- }
- else
-#endif /* SUPPORT_UNICODE */
-
- /* Not UTF mode */
- {
- for (;;)
- {
- RMATCH(Fecode, RM33);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (Lctype == OP_ANY && IS_NEWLINE(Feptr))
- RRETURN(MATCH_NOMATCH);
- fc = *Feptr++;
- switch(Lctype)
- {
- case OP_ANY: /* This is the non-NL case */
- if (mb->partial != 0 && /* Take care with CRLF partial */
- Feptr >= mb->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- fc == NLBLOCK->nl[0])
- {
- mb->hitend = TRUE;
- if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
- }
- break;
-
- case OP_ALLANY:
- case OP_ANYBYTE:
- break;
-
- case OP_ANYNL:
- switch(fc)
- {
- default: RRETURN(MATCH_NOMATCH);
-
- case CHAR_CR:
- if (Feptr < mb->end_subject && *Feptr == CHAR_LF) Feptr++;
- break;
-
- case CHAR_LF:
- break;
-
- case CHAR_VT:
- case CHAR_FF:
- case CHAR_NEL:
-#if PCRE2_CODE_UNIT_WIDTH != 8
- case 0x2028:
- case 0x2029:
-#endif
- if (mb->bsr_convention == PCRE2_BSR_ANYCRLF)
- RRETURN(MATCH_NOMATCH);
- break;
- }
- break;
-
- case OP_NOT_HSPACE:
- switch(fc)
- {
- default: break;
- HSPACE_BYTE_CASES:
-#if PCRE2_CODE_UNIT_WIDTH != 8
- HSPACE_MULTIBYTE_CASES:
-#endif
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case OP_HSPACE:
- switch(fc)
- {
- default: RRETURN(MATCH_NOMATCH);
- HSPACE_BYTE_CASES:
-#if PCRE2_CODE_UNIT_WIDTH != 8
- HSPACE_MULTIBYTE_CASES:
-#endif
- break;
- }
- break;
-
- case OP_NOT_VSPACE:
- switch(fc)
- {
- default: break;
- VSPACE_BYTE_CASES:
-#if PCRE2_CODE_UNIT_WIDTH != 8
- VSPACE_MULTIBYTE_CASES:
-#endif
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case OP_VSPACE:
- switch(fc)
- {
- default: RRETURN(MATCH_NOMATCH);
- VSPACE_BYTE_CASES:
-#if PCRE2_CODE_UNIT_WIDTH != 8
- VSPACE_MULTIBYTE_CASES:
-#endif
- break;
- }
- break;
-
- case OP_NOT_DIGIT:
- if (MAX_255(fc) && (mb->ctypes[fc] & ctype_digit) != 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_DIGIT:
- if (!MAX_255(fc) || (mb->ctypes[fc] & ctype_digit) == 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_NOT_WHITESPACE:
- if (MAX_255(fc) && (mb->ctypes[fc] & ctype_space) != 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_WHITESPACE:
- if (!MAX_255(fc) || (mb->ctypes[fc] & ctype_space) == 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_NOT_WORDCHAR:
- if (MAX_255(fc) && (mb->ctypes[fc] & ctype_word) != 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_WORDCHAR:
- if (!MAX_255(fc) || (mb->ctypes[fc] & ctype_word) == 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- default:
- return PCRE2_ERROR_INTERNAL;
- }
- }
- }
- /* Control never gets here */
- }
-
- /* If maximizing, it is worth using inline code for speed, doing the type
- test once at the start (i.e. keep it out of the loops). Once again,
- "notmatch" can be an ordinary local variable because the loops do not call
- RMATCH. */
-
- else
- {
- Lstart_eptr = Feptr; /* Remember where we started */
-
-#ifdef SUPPORT_UNICODE
- if (proptype >= 0)
- {
- BOOL notmatch = Lctype == OP_NOTPROP;
- switch(proptype)
- {
- case PT_ANY:
- for (i = Lmin; i < Lmax; i++)
- {
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(fc, Feptr, len);
- if (notmatch) break;
- Feptr+= len;
- }
- break;
-
- case PT_LAMP:
- for (i = Lmin; i < Lmax; i++)
- {
- int chartype;
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(fc, Feptr, len);
- chartype = UCD_CHARTYPE(fc);
- if ((chartype == ucp_Lu ||
- chartype == ucp_Ll ||
- chartype == ucp_Lt) == notmatch)
- break;
- Feptr+= len;
- }
- break;
-
- case PT_GC:
- for (i = Lmin; i < Lmax; i++)
- {
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(fc, Feptr, len);
- if ((UCD_CATEGORY(fc) == Lpropvalue) == notmatch) break;
- Feptr+= len;
- }
- break;
-
- case PT_PC:
- for (i = Lmin; i < Lmax; i++)
- {
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(fc, Feptr, len);
- if ((UCD_CHARTYPE(fc) == Lpropvalue) == notmatch) break;
- Feptr+= len;
- }
- break;
-
- case PT_SC:
- for (i = Lmin; i < Lmax; i++)
- {
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(fc, Feptr, len);
- if ((UCD_SCRIPT(fc) == Lpropvalue) == notmatch) break;
- Feptr+= len;
- }
- break;
-
- case PT_SCX:
- for (i = Lmin; i < Lmax; i++)
- {
- BOOL ok;
- const ucd_record *prop;
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(fc, Feptr, len);
- prop = GET_UCD(fc);
- ok = (prop->script == Lpropvalue ||
- MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), Lpropvalue) != 0);
- if (ok == notmatch) break;
- Feptr+= len;
- }
- break;
-
- case PT_ALNUM:
- for (i = Lmin; i < Lmax; i++)
- {
- int category;
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(fc, Feptr, len);
- category = UCD_CATEGORY(fc);
- if ((category == ucp_L || category == ucp_N) == notmatch)
- break;
- Feptr+= len;
- }
- break;
-
- /* Perl space used to exclude VT, but from Perl 5.18 it is included,
- which means that Perl space and POSIX space are now identical. PCRE
- was changed at release 8.34. */
-
- case PT_SPACE: /* Perl space */
- case PT_PXSPACE: /* POSIX space */
- for (i = Lmin; i < Lmax; i++)
- {
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(fc, Feptr, len);
- switch(fc)
- {
- HSPACE_CASES:
- VSPACE_CASES:
- if (notmatch) goto ENDLOOP99; /* Break the loop */
- break;
-
- default:
- if ((UCD_CATEGORY(fc) == ucp_Z) == notmatch)
- goto ENDLOOP99; /* Break the loop */
- break;
- }
- Feptr+= len;
- }
- ENDLOOP99:
- break;
-
- case PT_WORD:
- for (i = Lmin; i < Lmax; i++)
- {
- int category;
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(fc, Feptr, len);
- category = UCD_CATEGORY(fc);
- if ((category == ucp_L || category == ucp_N ||
- fc == CHAR_UNDERSCORE) == notmatch)
- break;
- Feptr+= len;
- }
- break;
-
- case PT_CLIST:
- for (i = Lmin; i < Lmax; i++)
- {
- const uint32_t *cp;
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(fc, Feptr, len);
- cp = PRIV(ucd_caseless_sets) + Lpropvalue;
- for (;;)
- {
- if (fc < *cp)
- { if (notmatch) break; else goto GOT_MAX; }
- if (fc == *cp++)
- { if (notmatch) goto GOT_MAX; else break; }
- }
- Feptr += len;
- }
- GOT_MAX:
- break;
-
- case PT_UCNC:
- for (i = Lmin; i < Lmax; i++)
- {
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(fc, Feptr, len);
- if ((fc == CHAR_DOLLAR_SIGN || fc == CHAR_COMMERCIAL_AT ||
- fc == CHAR_GRAVE_ACCENT || (fc >= 0xa0 && fc <= 0xd7ff) ||
- fc >= 0xe000) == notmatch)
- break;
- Feptr += len;
- }
- break;
-
- case PT_BIDICL:
- for (i = Lmin; i < Lmax; i++)
- {
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(fc, Feptr, len);
- if ((UCD_BIDICLASS(fc) == Lpropvalue) == notmatch) break;
- Feptr+= len;
- }
- break;
-
- case PT_BOOL:
- for (i = Lmin; i < Lmax; i++)
- {
- BOOL ok;
- const ucd_record *prop;
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(fc, Feptr, len);
- prop = GET_UCD(fc);
- ok = MAPBIT(PRIV(ucd_boolprop_sets) +
- UCD_BPROPS_PROP(prop), Lpropvalue) != 0;
- if (ok == notmatch) break;
- Feptr+= len;
- }
- break;
-
- default:
- return PCRE2_ERROR_INTERNAL;
- }
-
- /* Feptr is now past the end of the maximum run */
-
- if (reptype == REPTYPE_POS) continue; /* No backtracking */
-
- /* After \C in UTF mode, Lstart_eptr might be in the middle of a
- Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't
- go too far. */
-
- for(;;)
- {
- if (Feptr <= Lstart_eptr) break;
- RMATCH(Fecode, RM222);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- Feptr--;
- if (utf) BACKCHAR(Feptr);
- }
- }
-
- /* Match extended Unicode grapheme clusters. We will get here only if the
- support is in the binary; otherwise a compile-time error occurs. */
-
- else if (Lctype == OP_EXTUNI)
- {
- for (i = Lmin; i < Lmax; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- else
- {
- GETCHARINCTEST(fc, Feptr);
- Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject, mb->end_subject,
- utf, NULL);
- }
- CHECK_PARTIAL();
- }
-
- /* Feptr is now past the end of the maximum run */
-
- if (reptype == REPTYPE_POS) continue; /* No backtracking */
-
- /* We use <= Lstart_eptr rather than == Lstart_eptr to detect the start
- of the run while backtracking because the use of \C in UTF mode can
- cause BACKCHAR to move back past Lstart_eptr. This is just palliative;
- the use of \C in UTF mode is fraught with danger. */
-
- for(;;)
- {
- int lgb, rgb;
- PCRE2_SPTR fptr;
-
- if (Feptr <= Lstart_eptr) break; /* At start of char run */
- RMATCH(Fecode, RM220);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-
- /* Backtracking over an extended grapheme cluster involves inspecting
- the previous two characters (if present) to see if a break is
- permitted between them. */
-
- Feptr--;
- if (!utf) fc = *Feptr; else
- {
- BACKCHAR(Feptr);
- GETCHAR(fc, Feptr);
- }
- rgb = UCD_GRAPHBREAK(fc);
-
- for (;;)
- {
- if (Feptr <= Lstart_eptr) break; /* At start of char run */
- fptr = Feptr - 1;
- if (!utf) fc = *fptr; else
- {
- BACKCHAR(fptr);
- GETCHAR(fc, fptr);
- }
- lgb = UCD_GRAPHBREAK(fc);
- if ((PRIV(ucp_gbtable)[lgb] & (1u << rgb)) == 0) break;
- Feptr = fptr;
- rgb = lgb;
- }
- }
- }
-
- else
-#endif /* SUPPORT_UNICODE */
-
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- switch(Lctype)
- {
- case OP_ANY:
- for (i = Lmin; i < Lmax; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (IS_NEWLINE(Feptr)) break;
- if (mb->partial != 0 && /* Take care with CRLF partial */
- Feptr + 1 >= mb->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- UCHAR21(Feptr) == NLBLOCK->nl[0])
- {
- mb->hitend = TRUE;
- if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
- }
- Feptr++;
- ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);
- }
- break;
-
- case OP_ALLANY:
- if (Lmax < UINT32_MAX)
- {
- for (i = Lmin; i < Lmax; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- Feptr++;
- ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);
- }
- }
- else
- {
- Feptr = mb->end_subject; /* Unlimited UTF-8 repeat */
- SCHECK_PARTIAL();
- }
- break;
-
- /* The "byte" (i.e. "code unit") case is the same as non-UTF */
-
- case OP_ANYBYTE:
- fc = Lmax - Lmin;
- if (fc > (uint32_t)(mb->end_subject - Feptr))
- {
- Feptr = mb->end_subject;
- SCHECK_PARTIAL();
- }
- else Feptr += fc;
- break;
-
- case OP_ANYNL:
- for (i = Lmin; i < Lmax; i++)
- {
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(fc, Feptr, len);
- if (fc == CHAR_CR)
- {
- if (++Feptr >= mb->end_subject) break;
- if (UCHAR21(Feptr) == CHAR_LF) Feptr++;
- }
- else
- {
- if (fc != CHAR_LF &&
- (mb->bsr_convention == PCRE2_BSR_ANYCRLF ||
- (fc != CHAR_VT && fc != CHAR_FF && fc != CHAR_NEL
-#ifndef EBCDIC
- && fc != 0x2028 && fc != 0x2029
-#endif /* Not EBCDIC */
- )))
- break;
- Feptr += len;
- }
- }
- break;
-
- case OP_NOT_HSPACE:
- case OP_HSPACE:
- for (i = Lmin; i < Lmax; i++)
- {
- BOOL gotspace;
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(fc, Feptr, len);
- switch(fc)
- {
- HSPACE_CASES: gotspace = TRUE; break;
- default: gotspace = FALSE; break;
- }
- if (gotspace == (Lctype == OP_NOT_HSPACE)) break;
- Feptr += len;
- }
- break;
-
- case OP_NOT_VSPACE:
- case OP_VSPACE:
- for (i = Lmin; i < Lmax; i++)
- {
- BOOL gotspace;
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(fc, Feptr, len);
- switch(fc)
- {
- VSPACE_CASES: gotspace = TRUE; break;
- default: gotspace = FALSE; break;
- }
- if (gotspace == (Lctype == OP_NOT_VSPACE)) break;
- Feptr += len;
- }
- break;
-
- case OP_NOT_DIGIT:
- for (i = Lmin; i < Lmax; i++)
- {
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(fc, Feptr, len);
- if (fc < 256 && (mb->ctypes[fc] & ctype_digit) != 0) break;
- Feptr+= len;
- }
- break;
-
- case OP_DIGIT:
- for (i = Lmin; i < Lmax; i++)
- {
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(fc, Feptr, len);
- if (fc >= 256 ||(mb->ctypes[fc] & ctype_digit) == 0) break;
- Feptr+= len;
- }
- break;
-
- case OP_NOT_WHITESPACE:
- for (i = Lmin; i < Lmax; i++)
- {
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(fc, Feptr, len);
- if (fc < 256 && (mb->ctypes[fc] & ctype_space) != 0) break;
- Feptr+= len;
- }
- break;
-
- case OP_WHITESPACE:
- for (i = Lmin; i < Lmax; i++)
- {
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(fc, Feptr, len);
- if (fc >= 256 ||(mb->ctypes[fc] & ctype_space) == 0) break;
- Feptr+= len;
- }
- break;
-
- case OP_NOT_WORDCHAR:
- for (i = Lmin; i < Lmax; i++)
- {
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(fc, Feptr, len);
- if (fc < 256 && (mb->ctypes[fc] & ctype_word) != 0) break;
- Feptr+= len;
- }
- break;
-
- case OP_WORDCHAR:
- for (i = Lmin; i < Lmax; i++)
- {
- int len = 1;
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(fc, Feptr, len);
- if (fc >= 256 || (mb->ctypes[fc] & ctype_word) == 0) break;
- Feptr+= len;
- }
- break;
-
- default:
- return PCRE2_ERROR_INTERNAL;
- }
-
- if (reptype == REPTYPE_POS) continue; /* No backtracking */
-
- /* After \C in UTF mode, Lstart_eptr might be in the middle of a
- Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't go
- too far. */
-
- for(;;)
- {
- if (Feptr <= Lstart_eptr) break;
- RMATCH(Fecode, RM221);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- Feptr--;
- BACKCHAR(Feptr);
- if (Lctype == OP_ANYNL && Feptr > Lstart_eptr &&
- UCHAR21(Feptr) == CHAR_NL && UCHAR21(Feptr - 1) == CHAR_CR)
- Feptr--;
- }
- }
- else
-#endif /* SUPPORT_UNICODE */
-
- /* Not UTF mode */
- {
- switch(Lctype)
- {
- case OP_ANY:
- for (i = Lmin; i < Lmax; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (IS_NEWLINE(Feptr)) break;
- if (mb->partial != 0 && /* Take care with CRLF partial */
- Feptr + 1 >= mb->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- *Feptr == NLBLOCK->nl[0])
- {
- mb->hitend = TRUE;
- if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
- }
- Feptr++;
- }
- break;
-
- case OP_ALLANY:
- case OP_ANYBYTE:
- fc = Lmax - Lmin;
- if (fc > (uint32_t)(mb->end_subject - Feptr))
- {
- Feptr = mb->end_subject;
- SCHECK_PARTIAL();
- }
- else Feptr += fc;
- break;
-
- case OP_ANYNL:
- for (i = Lmin; i < Lmax; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- fc = *Feptr;
- if (fc == CHAR_CR)
- {
- if (++Feptr >= mb->end_subject) break;
- if (*Feptr == CHAR_LF) Feptr++;
- }
- else
- {
- if (fc != CHAR_LF && (mb->bsr_convention == PCRE2_BSR_ANYCRLF ||
- (fc != CHAR_VT && fc != CHAR_FF && fc != CHAR_NEL
-#if PCRE2_CODE_UNIT_WIDTH != 8
- && fc != 0x2028 && fc != 0x2029
-#endif
- ))) break;
- Feptr++;
- }
- }
- break;
-
- case OP_NOT_HSPACE:
- for (i = Lmin; i < Lmax; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- switch(*Feptr)
- {
- default: Feptr++; break;
- HSPACE_BYTE_CASES:
-#if PCRE2_CODE_UNIT_WIDTH != 8
- HSPACE_MULTIBYTE_CASES:
-#endif
- goto ENDLOOP00;
- }
- }
- ENDLOOP00:
- break;
-
- case OP_HSPACE:
- for (i = Lmin; i < Lmax; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- switch(*Feptr)
- {
- default: goto ENDLOOP01;
- HSPACE_BYTE_CASES:
-#if PCRE2_CODE_UNIT_WIDTH != 8
- HSPACE_MULTIBYTE_CASES:
-#endif
- Feptr++; break;
- }
- }
- ENDLOOP01:
- break;
-
- case OP_NOT_VSPACE:
- for (i = Lmin; i < Lmax; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- switch(*Feptr)
- {
- default: Feptr++; break;
- VSPACE_BYTE_CASES:
-#if PCRE2_CODE_UNIT_WIDTH != 8
- VSPACE_MULTIBYTE_CASES:
-#endif
- goto ENDLOOP02;
- }
- }
- ENDLOOP02:
- break;
-
- case OP_VSPACE:
- for (i = Lmin; i < Lmax; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- switch(*Feptr)
- {
- default: goto ENDLOOP03;
- VSPACE_BYTE_CASES:
-#if PCRE2_CODE_UNIT_WIDTH != 8
- VSPACE_MULTIBYTE_CASES:
-#endif
- Feptr++; break;
- }
- }
- ENDLOOP03:
- break;
-
- case OP_NOT_DIGIT:
- for (i = Lmin; i < Lmax; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_digit) != 0)
- break;
- Feptr++;
- }
- break;
-
- case OP_DIGIT:
- for (i = Lmin; i < Lmax; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_digit) == 0)
- break;
- Feptr++;
- }
- break;
-
- case OP_NOT_WHITESPACE:
- for (i = Lmin; i < Lmax; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_space) != 0)
- break;
- Feptr++;
- }
- break;
-
- case OP_WHITESPACE:
- for (i = Lmin; i < Lmax; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_space) == 0)
- break;
- Feptr++;
- }
- break;
-
- case OP_NOT_WORDCHAR:
- for (i = Lmin; i < Lmax; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_word) != 0)
- break;
- Feptr++;
- }
- break;
-
- case OP_WORDCHAR:
- for (i = Lmin; i < Lmax; i++)
- {
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_word) == 0)
- break;
- Feptr++;
- }
- break;
-
- default:
- return PCRE2_ERROR_INTERNAL;
- }
-
- if (reptype == REPTYPE_POS) continue; /* No backtracking */
-
- for (;;)
- {
- if (Feptr == Lstart_eptr) break;
- RMATCH(Fecode, RM34);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- Feptr--;
- if (Lctype == OP_ANYNL && Feptr > Lstart_eptr && *Feptr == CHAR_LF &&
- Feptr[-1] == CHAR_CR) Feptr--;
- }
- }
- }
- break; /* End of repeat character type processing */
-
-#undef Lstart_eptr
-#undef Lmin
-#undef Lmax
-#undef Lctype
-#undef Lpropvalue
-
-
- /* ===================================================================== */
- /* Match a back reference, possibly repeatedly. Look past the end of the
- item to see if there is repeat information following. The OP_REF and
- OP_REFI opcodes are used for a reference to a numbered group or to a
- non-duplicated named group. For a duplicated named group, OP_DNREF and
- OP_DNREFI are used. In this case we must scan the list of groups to which
- the name refers, and use the first one that is set. */
-
-#define Lmin F->temp_32[0]
-#define Lmax F->temp_32[1]
-#define Lcaseless F->temp_32[2]
-#define Lstart F->temp_sptr[0]
-#define Loffset F->temp_size
-
- case OP_DNREF:
- case OP_DNREFI:
- Lcaseless = (Fop == OP_DNREFI);
- {
- int count = GET2(Fecode, 1+IMM2_SIZE);
- PCRE2_SPTR slot = mb->name_table + GET2(Fecode, 1) * mb->name_entry_size;
- Fecode += 1 + 2*IMM2_SIZE;
-
- while (count-- > 0)
- {
- Loffset = (GET2(slot, 0) << 1) - 2;
- if (Loffset < Foffset_top && Fovector[Loffset] != PCRE2_UNSET) break;
- slot += mb->name_entry_size;
- }
- }
- goto REF_REPEAT;
-
- case OP_REF:
- case OP_REFI:
- Lcaseless = (Fop == OP_REFI);
- Loffset = (GET2(Fecode, 1) << 1) - 2;
- Fecode += 1 + IMM2_SIZE;
-
- /* Set up for repetition, or handle the non-repeated case. The maximum and
- minimum must be in the heap frame, but as they are short-term values, we
- use temporary fields. */
-
- REF_REPEAT:
- switch (*Fecode)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- fc = *Fecode++ - OP_CRSTAR;
- Lmin = rep_min[fc];
- Lmax = rep_max[fc];
- reptype = rep_typ[fc];
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- Lmin = GET2(Fecode, 1);
- Lmax = GET2(Fecode, 1 + IMM2_SIZE);
- reptype = rep_typ[*Fecode - OP_CRSTAR];
- if (Lmax == 0) Lmax = UINT32_MAX; /* Max 0 => infinity */
- Fecode += 1 + 2 * IMM2_SIZE;
- break;
-
- default: /* No repeat follows */
- {
- rrc = match_ref(Loffset, Lcaseless, F, mb, &length);
- if (rrc != 0)
- {
- if (rrc > 0) Feptr = mb->end_subject; /* Partial match */
- CHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- }
- Feptr += length;
- continue; /* With the main loop */
- }
-
- /* Handle repeated back references. If a set group has length zero, just
- continue with the main loop, because it matches however many times. For an
- unset reference, if the minimum is zero, we can also just continue. We can
- also continue if PCRE2_MATCH_UNSET_BACKREF is set, because this makes unset
- group behave as a zero-length group. For any other unset cases, carrying
- on will result in NOMATCH. */
-
- if (Loffset < Foffset_top && Fovector[Loffset] != PCRE2_UNSET)
- {
- if (Fovector[Loffset] == Fovector[Loffset + 1]) continue;
- }
- else /* Group is not set */
- {
- if (Lmin == 0 || (mb->poptions & PCRE2_MATCH_UNSET_BACKREF) != 0)
- continue;
- }
-
- /* First, ensure the minimum number of matches are present. */
-
- for (i = 1; i <= Lmin; i++)
- {
- PCRE2_SIZE slength;
- rrc = match_ref(Loffset, Lcaseless, F, mb, &slength);
- if (rrc != 0)
- {
- if (rrc > 0) Feptr = mb->end_subject; /* Partial match */
- CHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- Feptr += slength;
- }
-
- /* If min = max, we are done. They are not both allowed to be zero. */
-
- if (Lmin == Lmax) continue;
-
- /* If minimizing, keep trying and advancing the pointer. */
-
- if (reptype == REPTYPE_MIN)
- {
- for (;;)
- {
- PCRE2_SIZE slength;
- RMATCH(Fecode, RM20);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
- rrc = match_ref(Loffset, Lcaseless, F, mb, &slength);
- if (rrc != 0)
- {
- if (rrc > 0) Feptr = mb->end_subject; /* Partial match */
- CHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- Feptr += slength;
- }
- /* Control never gets here */
- }
-
- /* If maximizing, find the longest string and work backwards, as long as
- the matched lengths for each iteration are the same. */
-
- else
- {
- BOOL samelengths = TRUE;
- Lstart = Feptr; /* Starting position */
- Flength = Fovector[Loffset+1] - Fovector[Loffset];
-
- for (i = Lmin; i < Lmax; i++)
- {
- PCRE2_SIZE slength;
- rrc = match_ref(Loffset, Lcaseless, F, mb, &slength);
- if (rrc != 0)
- {
- /* Can't use CHECK_PARTIAL because we don't want to update Feptr in
- the soft partial matching case. */
-
- if (rrc > 0 && mb->partial != 0 &&
- mb->end_subject > mb->start_used_ptr)
- {
- mb->hitend = TRUE;
- if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
- }
- break;
- }
-
- if (slength != Flength) samelengths = FALSE;
- Feptr += slength;
- }
-
- /* If the length matched for each repetition is the same as the length of
- the captured group, we can easily work backwards. This is the normal
- case. However, in caseless UTF-8 mode there are pairs of case-equivalent
- characters whose lengths (in terms of code units) differ. However, this
- is very rare, so we handle it by re-matching fewer and fewer times. */
-
- if (samelengths)
- {
- while (Feptr >= Lstart)
- {
- RMATCH(Fecode, RM21);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- Feptr -= Flength;
- }
- }
-
- /* The rare case of non-matching lengths. Re-scan the repetition for each
- iteration. We know that match_ref() will succeed every time. */
-
- else
- {
- Lmax = i;
- for (;;)
- {
- RMATCH(Fecode, RM22);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (Feptr == Lstart) break; /* Failed after minimal repetition */
- Feptr = Lstart;
- Lmax--;
- for (i = Lmin; i < Lmax; i++)
- {
- PCRE2_SIZE slength;
- (void)match_ref(Loffset, Lcaseless, F, mb, &slength);
- Feptr += slength;
- }
- }
- }
-
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
-#undef Lcaseless
-#undef Lmin
-#undef Lmax
-#undef Lstart
-#undef Loffset
-
-
-
-/* ========================================================================= */
-/* Opcodes for the start of various parenthesized items */
-/* ========================================================================= */
-
- /* In all cases, if the result of RMATCH() is MATCH_THEN, check whether the
- (*THEN) is within the current branch by comparing the address of OP_THEN
- that is passed back with the end of the branch. If (*THEN) is within the
- current branch, and the branch is one of two or more alternatives (it
- either starts or ends with OP_ALT), we have reached the limit of THEN's
- action, so convert the return code to NOMATCH, which will cause normal
- backtracking to happen from now on. Otherwise, THEN is passed back to an
- outer alternative. This implements Perl's treatment of parenthesized
- groups, where a group not containing | does not affect the current
- alternative, that is, (X) is NOT the same as (X|(*F)). */
-
-
- /* ===================================================================== */
- /* BRAZERO, BRAMINZERO and SKIPZERO occur just before a non-possessive
- bracket group, indicating that it may occur zero times. It may repeat
- infinitely, or not at all - i.e. it could be ()* or ()? or even (){0} in
- the pattern. Brackets with fixed upper repeat limits are compiled as a
- number of copies, with the optional ones preceded by BRAZERO or BRAMINZERO.
- Possessive groups with possible zero repeats are preceded by BRAPOSZERO. */
-
-#define Lnext_ecode F->temp_sptr[0]
-
- case OP_BRAZERO:
- Lnext_ecode = Fecode + 1;
- RMATCH(Lnext_ecode, RM9);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- do Lnext_ecode += GET(Lnext_ecode, 1); while (*Lnext_ecode == OP_ALT);
- Fecode = Lnext_ecode + 1 + LINK_SIZE;
- break;
-
- case OP_BRAMINZERO:
- Lnext_ecode = Fecode + 1;
- do Lnext_ecode += GET(Lnext_ecode, 1); while (*Lnext_ecode == OP_ALT);
- RMATCH(Lnext_ecode + 1 + LINK_SIZE, RM10);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- Fecode++;
- break;
-
-#undef Lnext_ecode
-
- case OP_SKIPZERO:
- Fecode++;
- do Fecode += GET(Fecode,1); while (*Fecode == OP_ALT);
- Fecode += 1 + LINK_SIZE;
- break;
-
-
- /* ===================================================================== */
- /* Handle possessive brackets with an unlimited repeat. The end of these
- brackets will always be OP_KETRPOS, which returns MATCH_KETRPOS without
- going further in the pattern. */
-
-#define Lframe_type F->temp_32[0]
-#define Lmatched_once F->temp_32[1]
-#define Lzero_allowed F->temp_32[2]
-#define Lstart_eptr F->temp_sptr[0]
-#define Lstart_group F->temp_sptr[1]
-
- case OP_BRAPOSZERO:
- Lzero_allowed = TRUE; /* Zero repeat is allowed */
- Fecode += 1;
- if (*Fecode == OP_CBRAPOS || *Fecode == OP_SCBRAPOS)
- goto POSSESSIVE_CAPTURE;
- goto POSSESSIVE_NON_CAPTURE;
-
- case OP_BRAPOS:
- case OP_SBRAPOS:
- Lzero_allowed = FALSE; /* Zero repeat not allowed */
-
- POSSESSIVE_NON_CAPTURE:
- Lframe_type = GF_NOCAPTURE; /* Remembered frame type */
- goto POSSESSIVE_GROUP;
-
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- Lzero_allowed = FALSE; /* Zero repeat not allowed */
-
- POSSESSIVE_CAPTURE:
- number = GET2(Fecode, 1+LINK_SIZE);
- Lframe_type = GF_CAPTURE | number; /* Remembered frame type */
-
- POSSESSIVE_GROUP:
- Lmatched_once = FALSE; /* Never matched */
- Lstart_group = Fecode; /* Start of this group */
-
- for (;;)
- {
- Lstart_eptr = Feptr; /* Position at group start */
- group_frame_type = Lframe_type;
- RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM8);
- if (rrc == MATCH_KETRPOS)
- {
- Lmatched_once = TRUE; /* Matched at least once */
- if (Feptr == Lstart_eptr) /* Empty match; skip to end */
- {
- do Fecode += GET(Fecode, 1); while (*Fecode == OP_ALT);
- break;
- }
-
- Fecode = Lstart_group;
- continue;
- }
-
- /* See comment above about handling THEN. */
-
- if (rrc == MATCH_THEN)
- {
- PCRE2_SPTR next_ecode = Fecode + GET(Fecode,1);
- if (mb->verb_ecode_ptr < next_ecode &&
- (*Fecode == OP_ALT || *next_ecode == OP_ALT))
- rrc = MATCH_NOMATCH;
- }
-
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- Fecode += GET(Fecode, 1);
- if (*Fecode != OP_ALT) break;
- }
-
- /* Success if matched something or zero repeat allowed */
-
- if (Lmatched_once || Lzero_allowed)
- {
- Fecode += 1 + LINK_SIZE;
- break;
- }
-
- RRETURN(MATCH_NOMATCH);
-
-#undef Lmatched_once
-#undef Lzero_allowed
-#undef Lframe_type
-#undef Lstart_eptr
-#undef Lstart_group
-
-
- /* ===================================================================== */
- /* Handle non-capturing brackets that cannot match an empty string. When we
- get to the final alternative within the brackets, as long as there are no
- THEN's in the pattern, we can optimize by not recording a new backtracking
- point. (Ideally we should test for a THEN within this group, but we don't
- have that information.) Don't do this if we are at the very top level,
- however, because that would make handling assertions and once-only brackets
- messier when there is nothing to go back to. */
-
-#define Lframe_type F->temp_32[0] /* Set for all that use GROUPLOOP */
-#define Lnext_branch F->temp_sptr[0] /* Used only in OP_BRA handling */
-
- case OP_BRA:
- if (mb->hasthen || Frdepth == 0)
- {
- Lframe_type = 0;
- goto GROUPLOOP;
- }
-
- for (;;)
- {
- Lnext_branch = Fecode + GET(Fecode, 1);
- if (*Lnext_branch != OP_ALT) break;
-
- /* This is never the final branch. We do not need to test for MATCH_THEN
- here because this code is not used when there is a THEN in the pattern. */
-
- RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM1);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- Fecode = Lnext_branch;
- }
-
- /* Hit the start of the final branch. Continue at this level. */
-
- Fecode += PRIV(OP_lengths)[*Fecode];
- break;
-
-#undef Lnext_branch
-
-
- /* ===================================================================== */
- /* Handle a capturing bracket, other than those that are possessive with an
- unlimited repeat. */
-
- case OP_CBRA:
- case OP_SCBRA:
- Lframe_type = GF_CAPTURE | GET2(Fecode, 1+LINK_SIZE);
- goto GROUPLOOP;
-
-
- /* ===================================================================== */
- /* Atomic groups and non-capturing brackets that can match an empty string
- must record a backtracking point and also set up a chained frame. */
-
- case OP_ONCE:
- case OP_SCRIPT_RUN:
- case OP_SBRA:
- Lframe_type = GF_NOCAPTURE | Fop;
-
- GROUPLOOP:
- for (;;)
- {
- group_frame_type = Lframe_type;
- RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM2);
- if (rrc == MATCH_THEN)
- {
- PCRE2_SPTR next_ecode = Fecode + GET(Fecode,1);
- if (mb->verb_ecode_ptr < next_ecode &&
- (*Fecode == OP_ALT || *next_ecode == OP_ALT))
- rrc = MATCH_NOMATCH;
- }
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- Fecode += GET(Fecode, 1);
- if (*Fecode != OP_ALT) RRETURN(MATCH_NOMATCH);
- }
- /* Control never reaches here. */
-
-#undef Lframe_type
-
-
- /* ===================================================================== */
- /* Recursion either matches the current regex, or some subexpression. The
- offset data is the offset to the starting bracket from the start of the
- whole pattern. (This is so that it works from duplicated subpatterns.) */
-
-#define Lframe_type F->temp_32[0]
-#define Lstart_branch F->temp_sptr[0]
-
- case OP_RECURSE:
- bracode = mb->start_code + GET(Fecode, 1);
- number = (bracode == mb->start_code)? 0 : GET2(bracode, 1 + LINK_SIZE);
-
- /* If we are already in a recursion, check for repeating the same one
- without advancing the subject pointer. This should catch convoluted mutual
- recursions. (Some simple cases are caught at compile time.) */
-
- if (Fcurrent_recurse != RECURSE_UNSET)
- {
- offset = Flast_group_offset;
- while (offset != PCRE2_UNSET)
- {
- N = (heapframe *)((char *)match_data->heapframes + offset);
- P = (heapframe *)((char *)N - frame_size);
- if (N->group_frame_type == (GF_RECURSE | number))
- {
- if (Feptr == P->eptr) return PCRE2_ERROR_RECURSELOOP;
- break;
- }
- offset = P->last_group_offset;
- }
- }
-
- /* Now run the recursion, branch by branch. */
-
- Lstart_branch = bracode;
- Lframe_type = GF_RECURSE | number;
-
- for (;;)
- {
- PCRE2_SPTR next_ecode;
-
- group_frame_type = Lframe_type;
- RMATCH(Lstart_branch + PRIV(OP_lengths)[*Lstart_branch], RM11);
- next_ecode = Lstart_branch + GET(Lstart_branch,1);
-
- /* Handle backtracking verbs, which are defined in a range that can
- easily be tested for. PCRE does not allow THEN, SKIP, PRUNE or COMMIT to
- escape beyond a recursion; they cause a NOMATCH for the entire recursion.
-
- When one of these verbs triggers, the current recursion group number is
- recorded. If it matches the recursion we are processing, the verb
- happened within the recursion and we must deal with it. Otherwise it must
- have happened after the recursion completed, and so has to be passed
- back. See comment above about handling THEN. */
-
- if (rrc >= MATCH_BACKTRACK_MIN && rrc <= MATCH_BACKTRACK_MAX &&
- mb->verb_current_recurse == (Lframe_type ^ GF_RECURSE))
- {
- if (rrc == MATCH_THEN && mb->verb_ecode_ptr < next_ecode &&
- (*Lstart_branch == OP_ALT || *next_ecode == OP_ALT))
- rrc = MATCH_NOMATCH;
- else RRETURN(MATCH_NOMATCH);
- }
-
- /* Note that carrying on after (*ACCEPT) in a recursion is handled in the
- OP_ACCEPT code. Nothing needs to be done here. */
-
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- Lstart_branch = next_ecode;
- if (*Lstart_branch != OP_ALT) RRETURN(MATCH_NOMATCH);
- }
- /* Control never reaches here. */
-
-#undef Lframe_type
-#undef Lstart_branch
-
-
- /* ===================================================================== */
- /* Positive assertions are like other groups except that PCRE doesn't allow
- the effect of (*THEN) to escape beyond an assertion; it is therefore
- treated as NOMATCH. (*ACCEPT) is treated as successful assertion, with its
- captures and mark retained. Any other return is an error. */
-
-#define Lframe_type F->temp_32[0]
-
- case OP_ASSERT:
- case OP_ASSERTBACK:
- case OP_ASSERT_NA:
- case OP_ASSERTBACK_NA:
- Lframe_type = GF_NOCAPTURE | Fop;
- for (;;)
- {
- group_frame_type = Lframe_type;
- RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM3);
- if (rrc == MATCH_ACCEPT)
- {
- memcpy(Fovector,
- (char *)assert_accept_frame + offsetof(heapframe, ovector),
- assert_accept_frame->offset_top * sizeof(PCRE2_SIZE));
- Foffset_top = assert_accept_frame->offset_top;
- Fmark = assert_accept_frame->mark;
- break;
- }
- if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
- Fecode += GET(Fecode, 1);
- if (*Fecode != OP_ALT) RRETURN(MATCH_NOMATCH);
- }
-
- do Fecode += GET(Fecode, 1); while (*Fecode == OP_ALT);
- Fecode += 1 + LINK_SIZE;
- break;
-
-#undef Lframe_type
-
-
- /* ===================================================================== */
- /* Handle negative assertions. Loop for each non-matching branch as for
- positive assertions. */
-
-#define Lframe_type F->temp_32[0]
-
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK_NOT:
- Lframe_type = GF_NOCAPTURE | Fop;
-
- for (;;)
- {
- group_frame_type = Lframe_type;
- RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM4);
- switch(rrc)
- {
- case MATCH_ACCEPT: /* Assertion matched, therefore it fails. */
- case MATCH_MATCH:
- RRETURN (MATCH_NOMATCH);
-
- case MATCH_NOMATCH: /* Branch failed, try next if present. */
- case MATCH_THEN:
- Fecode += GET(Fecode, 1);
- if (*Fecode != OP_ALT) goto ASSERT_NOT_FAILED;
- break;
-
- case MATCH_COMMIT: /* Assertion forced to fail, therefore continue. */
- case MATCH_SKIP:
- case MATCH_PRUNE:
- do Fecode += GET(Fecode, 1); while (*Fecode == OP_ALT);
- goto ASSERT_NOT_FAILED;
-
- default: /* Pass back any other return */
- RRETURN(rrc);
- }
- }
-
- /* None of the branches have matched or there was a backtrack to (*COMMIT),
- (*SKIP), (*PRUNE), or (*THEN) in the last branch. This is success for a
- negative assertion, so carry on. */
-
- ASSERT_NOT_FAILED:
- Fecode += 1 + LINK_SIZE;
- break;
-
-#undef Lframe_type
-
-
- /* ===================================================================== */
- /* The callout item calls an external function, if one is provided, passing
- details of the match so far. This is mainly for debugging, though the
- function is able to force a failure. */
-
- case OP_CALLOUT:
- case OP_CALLOUT_STR:
- rrc = do_callout(F, mb, &length);
- if (rrc > 0) RRETURN(MATCH_NOMATCH);
- if (rrc < 0) RRETURN(rrc);
- Fecode += length;
- break;
-
-
- /* ===================================================================== */
- /* Conditional group: compilation checked that there are no more than two
- branches. If the condition is false, skipping the first branch takes us
- past the end of the item if there is only one branch, but that's exactly
- what we want. */
-
- case OP_COND:
- case OP_SCOND:
-
- /* The variable Flength will be added to Fecode when the condition is
- false, to get to the second branch. Setting it to the offset to the ALT or
- KET, then incrementing Fecode achieves this effect. However, if the second
- branch is non-existent, we must point to the KET so that the end of the
- group is correctly processed. We now have Fecode pointing to the condition
- or callout. */
-
- Flength = GET(Fecode, 1); /* Offset to the second branch */
- if (Fecode[Flength] != OP_ALT) Flength -= 1 + LINK_SIZE;
- Fecode += 1 + LINK_SIZE; /* From this opcode */
-
- /* Because of the way auto-callout works during compile, a callout item is
- inserted between OP_COND and an assertion condition. Such a callout can
- also be inserted manually. */
-
- if (*Fecode == OP_CALLOUT || *Fecode == OP_CALLOUT_STR)
- {
- rrc = do_callout(F, mb, &length);
- if (rrc > 0) RRETURN(MATCH_NOMATCH);
- if (rrc < 0) RRETURN(rrc);
-
- /* Advance Fecode past the callout, so it now points to the condition. We
- must adjust Flength so that the value of Fecode+Flength is unchanged. */
-
- Fecode += length;
- Flength -= length;
- }
-
- /* Test the various possible conditions */
-
- condition = FALSE;
- switch(*Fecode)
- {
- case OP_RREF: /* Group recursion test */
- if (Fcurrent_recurse != RECURSE_UNSET)
- {
- number = GET2(Fecode, 1);
- condition = (number == RREF_ANY || number == Fcurrent_recurse);
- }
- break;
-
- case OP_DNRREF: /* Duplicate named group recursion test */
- if (Fcurrent_recurse != RECURSE_UNSET)
- {
- int count = GET2(Fecode, 1 + IMM2_SIZE);
- PCRE2_SPTR slot = mb->name_table + GET2(Fecode, 1) * mb->name_entry_size;
- while (count-- > 0)
- {
- number = GET2(slot, 0);
- condition = number == Fcurrent_recurse;
- if (condition) break;
- slot += mb->name_entry_size;
- }
- }
- break;
-
- case OP_CREF: /* Numbered group used test */
- offset = (GET2(Fecode, 1) << 1) - 2; /* Doubled ref number */
- condition = offset < Foffset_top && Fovector[offset] != PCRE2_UNSET;
- break;
-
- case OP_DNCREF: /* Duplicate named group used test */
- {
- int count = GET2(Fecode, 1 + IMM2_SIZE);
- PCRE2_SPTR slot = mb->name_table + GET2(Fecode, 1) * mb->name_entry_size;
- while (count-- > 0)
- {
- offset = (GET2(slot, 0) << 1) - 2;
- condition = offset < Foffset_top && Fovector[offset] != PCRE2_UNSET;
- if (condition) break;
- slot += mb->name_entry_size;
- }
- }
- break;
-
- case OP_FALSE:
- case OP_FAIL: /* The assertion (?!) becomes OP_FAIL */
- break;
-
- case OP_TRUE:
- condition = TRUE;
- break;
-
- /* The condition is an assertion. Run code similar to the assertion code
- above. */
-
-#define Lpositive F->temp_32[0]
-#define Lstart_branch F->temp_sptr[0]
-
- default:
- Lpositive = (*Fecode == OP_ASSERT || *Fecode == OP_ASSERTBACK);
- Lstart_branch = Fecode;
-
- for (;;)
- {
- group_frame_type = GF_CONDASSERT | *Fecode;
- RMATCH(Lstart_branch + PRIV(OP_lengths)[*Lstart_branch], RM5);
-
- switch(rrc)
- {
- case MATCH_ACCEPT: /* Save captures */
- memcpy(Fovector,
- (char *)assert_accept_frame + offsetof(heapframe, ovector),
- assert_accept_frame->offset_top * sizeof(PCRE2_SIZE));
- Foffset_top = assert_accept_frame->offset_top;
-
- /* Fall through */
- /* In the case of a match, the captures have already been put into
- the current frame. */
-
- case MATCH_MATCH:
- condition = Lpositive; /* TRUE for positive assertion */
- break;
-
- /* PCRE doesn't allow the effect of (*THEN) to escape beyond an
- assertion; it is therefore always treated as NOMATCH. */
-
- case MATCH_NOMATCH:
- case MATCH_THEN:
- Lstart_branch += GET(Lstart_branch, 1);
- if (*Lstart_branch == OP_ALT) continue; /* Try next branch */
- condition = !Lpositive; /* TRUE for negative assertion */
- break;
-
- /* These force no match without checking other branches. */
-
- case MATCH_COMMIT:
- case MATCH_SKIP:
- case MATCH_PRUNE:
- condition = !Lpositive;
- break;
-
- default:
- RRETURN(rrc);
- }
- break; /* Out of the branch loop */
- }
-
- /* If the condition is true, find the end of the assertion so that
- advancing past it gets us to the start of the first branch. */
-
- if (condition)
- {
- do Fecode += GET(Fecode, 1); while (*Fecode == OP_ALT);
- }
- break; /* End of assertion condition */
- }
-
-#undef Lpositive
-#undef Lstart_branch
-
- /* Choose branch according to the condition. */
-
- Fecode += condition? PRIV(OP_lengths)[*Fecode] : Flength;
-
- /* If the opcode is OP_SCOND it means we are at a repeated conditional
- group that might match an empty string. We must therefore descend a level
- so that the start is remembered for checking. For OP_COND we can just
- continue at this level. */
-
- if (Fop == OP_SCOND)
- {
- group_frame_type = GF_NOCAPTURE | Fop;
- RMATCH(Fecode, RM35);
- RRETURN(rrc);
- }
- break;
-
-
-
-/* ========================================================================= */
-/* End of start of parenthesis opcodes */
-/* ========================================================================= */
-
-
- /* ===================================================================== */
- /* Move the subject pointer back. This occurs only at the start of each
- branch of a lookbehind assertion. If we are too close to the start to move
- back, fail. When working with UTF-8 we move back a number of characters,
- not bytes. */
-
- case OP_REVERSE:
- number = GET(Fecode, 1);
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- while (number-- > 0)
- {
- if (Feptr <= mb->check_subject) RRETURN(MATCH_NOMATCH);
- Feptr--;
- BACKCHAR(Feptr);
- }
- }
- else
-#endif
-
- /* No UTF-8 support, or not in UTF-8 mode: count is code unit count */
-
- {
- if ((ptrdiff_t)number > Feptr - mb->start_subject) RRETURN(MATCH_NOMATCH);
- Feptr -= number;
- }
-
- /* Save the earliest consulted character, then skip to next opcode */
-
- if (Feptr < mb->start_used_ptr) mb->start_used_ptr = Feptr;
- Fecode += 1 + LINK_SIZE;
- break;
-
-
- /* ===================================================================== */
- /* An alternation is the end of a branch; scan along to find the end of the
- bracketed group. */
-
- case OP_ALT:
- do Fecode += GET(Fecode,1); while (*Fecode == OP_ALT);
- break;
-
-
- /* ===================================================================== */
- /* The end of a parenthesized group. For all but OP_BRA and OP_COND, the
- starting frame was added to the chained frames in order to remember the
- starting subject position for the group. */
-
- case OP_KET:
- case OP_KETRMIN:
- case OP_KETRMAX:
- case OP_KETRPOS:
-
- bracode = Fecode - GET(Fecode, 1);
-
- /* Point N to the frame at the start of the most recent group.
- Remember the subject pointer at the start of the group. */
-
- if (*bracode != OP_BRA && *bracode != OP_COND)
- {
- N = (heapframe *)((char *)match_data->heapframes + Flast_group_offset);
- P = (heapframe *)((char *)N - frame_size);
- Flast_group_offset = P->last_group_offset;
-
-#ifdef DEBUG_SHOW_RMATCH
- fprintf(stderr, "++ KET for frame=%d type=%x prev char offset=%lu\n",
- N->rdepth, N->group_frame_type,
- (char *)P->eptr - (char *)mb->start_subject);
-#endif
-
- /* If we are at the end of an assertion that is a condition, return a
- match, discarding any intermediate backtracking points. Copy back the
- mark setting and the captures into the frame before N so that they are
- set on return. Doing this for all assertions, both positive and negative,
- seems to match what Perl does. */
-
- if (GF_IDMASK(N->group_frame_type) == GF_CONDASSERT)
- {
- memcpy((char *)P + offsetof(heapframe, ovector), Fovector,
- Foffset_top * sizeof(PCRE2_SIZE));
- P->offset_top = Foffset_top;
- P->mark = Fmark;
- Fback_frame = (char *)F - (char *)P;
- RRETURN(MATCH_MATCH);
- }
- }
- else P = NULL; /* Indicates starting frame not recorded */
-
- /* The group was not a conditional assertion. */
-
- switch (*bracode)
- {
- case OP_BRA: /* No need to do anything for these */
- case OP_COND:
- case OP_SCOND:
- break;
-
- /* Non-atomic positive assertions are like OP_BRA, except that the
- subject pointer must be put back to where it was at the start of the
- assertion. */
-
- case OP_ASSERT_NA:
- case OP_ASSERTBACK_NA:
- if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;
- Feptr = P->eptr;
- break;
-
- /* Atomic positive assertions are like OP_ONCE, except that in addition
- the subject pointer must be put back to where it was at the start of the
- assertion. */
-
- case OP_ASSERT:
- case OP_ASSERTBACK:
- if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;
- Feptr = P->eptr;
- /* Fall through */
-
- /* For an atomic group, discard internal backtracking points. We must
- also ensure that any remaining branches within the top-level of the group
- are not tried. Do this by adjusting the code pointer within the backtrack
- frame so that it points to the final branch. */
-
- case OP_ONCE:
- Fback_frame = ((char *)F - (char *)P);
- for (;;)
- {
- uint32_t y = GET(P->ecode,1);
- if ((P->ecode)[y] != OP_ALT) break;
- P->ecode += y;
- }
- break;
-
- /* A matching negative assertion returns MATCH, which is turned into
- NOMATCH at the assertion level. */
-
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK_NOT:
- RRETURN(MATCH_MATCH);
-
- /* At the end of a script run, apply the script-checking rules. This code
- will never by exercised if Unicode support it not compiled, because in
- that environment script runs cause an error at compile time. */
-
- case OP_SCRIPT_RUN:
- if (!PRIV(script_run)(P->eptr, Feptr, utf)) RRETURN(MATCH_NOMATCH);
- break;
-
- /* Whole-pattern recursion is coded as a recurse into group 0, so it
- won't be picked up here. Instead, we catch it when the OP_END is reached.
- Other recursion is handled here. */
-
- case OP_CBRA:
- case OP_CBRAPOS:
- case OP_SCBRA:
- case OP_SCBRAPOS:
- number = GET2(bracode, 1+LINK_SIZE);
-
- /* Handle a recursively called group. We reinstate the previous set of
- captures and then carry on after the recursion call. */
-
- if (Fcurrent_recurse == number)
- {
- P = (heapframe *)((char *)N - frame_size);
- memcpy((char *)F + offsetof(heapframe, ovector), P->ovector,
- P->offset_top * sizeof(PCRE2_SIZE));
- Foffset_top = P->offset_top;
- Fcapture_last = P->capture_last;
- Fcurrent_recurse = P->current_recurse;
- Fecode = P->ecode + 1 + LINK_SIZE;
- continue; /* With next opcode */
- }
-
- /* Deal with actual capturing. */
-
- offset = (number << 1) - 2;
- Fcapture_last = number;
- Fovector[offset] = P->eptr - mb->start_subject;
- Fovector[offset+1] = Feptr - mb->start_subject;
- if (offset >= Foffset_top) Foffset_top = offset + 2;
- break;
- } /* End actions relating to the starting opcode */
-
- /* OP_KETRPOS is a possessive repeating ket. Remember the current position,
- and return the MATCH_KETRPOS. This makes it possible to do the repeats one
- at a time from the outer level. This must precede the empty string test -
- in this case that test is done at the outer level. */
-
- if (*Fecode == OP_KETRPOS)
- {
- memcpy((char *)P + offsetof(heapframe, eptr),
- (char *)F + offsetof(heapframe, eptr),
- frame_copy_size);
- RRETURN(MATCH_KETRPOS);
- }
-
- /* Handle the different kinds of closing brackets. A non-repeating ket
- needs no special action, just continuing at this level. This also happens
- for the repeating kets if the group matched no characters, in order to
- forcibly break infinite loops. Otherwise, the repeating kets try the rest
- of the pattern or restart from the preceding bracket, in the appropriate
- order. */
-
- if (Fop != OP_KET && (P == NULL || Feptr != P->eptr))
- {
- if (Fop == OP_KETRMIN)
- {
- RMATCH(Fecode + 1 + LINK_SIZE, RM6);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- Fecode -= GET(Fecode, 1);
- break; /* End of ket processing */
- }
-
- /* Repeat the maximum number of times (KETRMAX) */
-
- RMATCH(bracode, RM7);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- }
-
- /* Carry on at this level for a non-repeating ket, or after matching an
- empty string, or after repeating for a maximum number of times. */
-
- Fecode += 1 + LINK_SIZE;
- break;
-
-
- /* ===================================================================== */
- /* Start and end of line assertions, not multiline mode. */
-
- case OP_CIRC: /* Start of line, unless PCRE2_NOTBOL is set. */
- if (Feptr != mb->start_subject || (mb->moptions & PCRE2_NOTBOL) != 0)
- RRETURN(MATCH_NOMATCH);
- Fecode++;
- break;
-
- case OP_SOD: /* Unconditional start of subject */
- if (Feptr != mb->start_subject) RRETURN(MATCH_NOMATCH);
- Fecode++;
- break;
-
- /* When PCRE2_NOTEOL is unset, assert before the subject end, or a
- terminating newline unless PCRE2_DOLLAR_ENDONLY is set. */
-
- case OP_DOLL:
- if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH);
- if ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0) goto ASSERT_NL_OR_EOS;
-
- /* Fall through */
- /* Unconditional end of subject assertion (\z) */
-
- case OP_EOD:
- if (Feptr < mb->end_subject) RRETURN(MATCH_NOMATCH);
- if (mb->partial != 0)
- {
- mb->hitend = TRUE;
- if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
- }
- Fecode++;
- break;
-
- /* End of subject or ending \n assertion (\Z) */
-
- case OP_EODN:
- ASSERT_NL_OR_EOS:
- if (Feptr < mb->end_subject &&
- (!IS_NEWLINE(Feptr) || Feptr != mb->end_subject - mb->nllen))
- {
- if (mb->partial != 0 &&
- Feptr + 1 >= mb->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- UCHAR21TEST(Feptr) == NLBLOCK->nl[0])
- {
- mb->hitend = TRUE;
- if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
- }
- RRETURN(MATCH_NOMATCH);
- }
-
- /* Either at end of string or \n before end. */
-
- if (mb->partial != 0)
- {
- mb->hitend = TRUE;
- if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
- }
- Fecode++;
- break;
-
-
- /* ===================================================================== */
- /* Start and end of line assertions, multiline mode. */
-
- /* Start of subject unless notbol, or after any newline except for one at
- the very end, unless PCRE2_ALT_CIRCUMFLEX is set. */
-
- case OP_CIRCM:
- if ((mb->moptions & PCRE2_NOTBOL) != 0 && Feptr == mb->start_subject)
- RRETURN(MATCH_NOMATCH);
- if (Feptr != mb->start_subject &&
- ((Feptr == mb->end_subject &&
- (mb->poptions & PCRE2_ALT_CIRCUMFLEX) == 0) ||
- !WAS_NEWLINE(Feptr)))
- RRETURN(MATCH_NOMATCH);
- Fecode++;
- break;
-
- /* Assert before any newline, or before end of subject unless noteol is
- set. */
-
- case OP_DOLLM:
- if (Feptr < mb->end_subject)
- {
- if (!IS_NEWLINE(Feptr))
- {
- if (mb->partial != 0 &&
- Feptr + 1 >= mb->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- UCHAR21TEST(Feptr) == NLBLOCK->nl[0])
- {
- mb->hitend = TRUE;
- if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
- }
- RRETURN(MATCH_NOMATCH);
- }
- }
- else
- {
- if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH);
- SCHECK_PARTIAL();
- }
- Fecode++;
- break;
-
-
- /* ===================================================================== */
- /* Start of match assertion */
-
- case OP_SOM:
- if (Feptr != mb->start_subject + mb->start_offset) RRETURN(MATCH_NOMATCH);
- Fecode++;
- break;
-
-
- /* ===================================================================== */
- /* Reset the start of match point */
-
- case OP_SET_SOM:
- Fstart_match = Feptr;
- Fecode++;
- break;
-
-
- /* ===================================================================== */
- /* Word boundary assertions. Find out if the previous and current
- characters are "word" characters. It takes a bit more work in UTF mode.
- Characters > 255 are assumed to be "non-word" characters when PCRE2_UCP is
- not set. When it is set, use Unicode properties if available, even when not
- in UTF mode. Remember the earliest and latest consulted characters. */
-
- case OP_NOT_WORD_BOUNDARY:
- case OP_WORD_BOUNDARY:
- if (Feptr == mb->check_subject) prev_is_word = FALSE; else
- {
- PCRE2_SPTR lastptr = Feptr - 1;
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- BACKCHAR(lastptr);
- GETCHAR(fc, lastptr);
- }
- else
-#endif /* SUPPORT_UNICODE */
- fc = *lastptr;
- if (lastptr < mb->start_used_ptr) mb->start_used_ptr = lastptr;
-#ifdef SUPPORT_UNICODE
- if ((mb->poptions & PCRE2_UCP) != 0)
- {
- if (fc == '_') prev_is_word = TRUE; else
- {
- int cat = UCD_CATEGORY(fc);
- prev_is_word = (cat == ucp_L || cat == ucp_N);
- }
- }
- else
-#endif /* SUPPORT_UNICODE */
- prev_is_word = CHMAX_255(fc) && (mb->ctypes[fc] & ctype_word) != 0;
- }
-
- /* Get status of next character */
-
- if (Feptr >= mb->end_subject)
- {
- SCHECK_PARTIAL();
- cur_is_word = FALSE;
- }
- else
- {
- PCRE2_SPTR nextptr = Feptr + 1;
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- FORWARDCHARTEST(nextptr, mb->end_subject);
- GETCHAR(fc, Feptr);
- }
- else
-#endif /* SUPPORT_UNICODE */
- fc = *Feptr;
- if (nextptr > mb->last_used_ptr) mb->last_used_ptr = nextptr;
-#ifdef SUPPORT_UNICODE
- if ((mb->poptions & PCRE2_UCP) != 0)
- {
- if (fc == '_') cur_is_word = TRUE; else
- {
- int cat = UCD_CATEGORY(fc);
- cur_is_word = (cat == ucp_L || cat == ucp_N);
- }
- }
- else
-#endif /* SUPPORT_UNICODE */
- cur_is_word = CHMAX_255(fc) && (mb->ctypes[fc] & ctype_word) != 0;
- }
-
- /* Now see if the situation is what we want */
-
- if ((*Fecode++ == OP_WORD_BOUNDARY)?
- cur_is_word == prev_is_word : cur_is_word != prev_is_word)
- RRETURN(MATCH_NOMATCH);
- break;
-
-
- /* ===================================================================== */
- /* Backtracking (*VERB)s, with and without arguments. Note that if the
- pattern is successfully matched, we do not come back from RMATCH. */
-
- case OP_MARK:
- Fmark = mb->nomatch_mark = Fecode + 2;
- RMATCH(Fecode + PRIV(OP_lengths)[*Fecode] + Fecode[1], RM12);
-
- /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an
- argument, and we must check whether that argument matches this MARK's
- argument. It is passed back in mb->verb_skip_ptr. If it does match, we
- return MATCH_SKIP with mb->verb_skip_ptr now pointing to the subject
- position that corresponds to this mark. Otherwise, pass back the return
- code unaltered. */
-
- if (rrc == MATCH_SKIP_ARG &&
- PRIV(strcmp)(Fecode + 2, mb->verb_skip_ptr) == 0)
- {
- mb->verb_skip_ptr = Feptr; /* Pass back current position */
- RRETURN(MATCH_SKIP);
- }
- RRETURN(rrc);
-
- case OP_FAIL:
- RRETURN(MATCH_NOMATCH);
-
- /* Record the current recursing group number in mb->verb_current_recurse
- when a backtracking return such as MATCH_COMMIT is given. This enables the
- recurse processing to catch verbs from within the recursion. */
-
- case OP_COMMIT:
- RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM13);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- mb->verb_current_recurse = Fcurrent_recurse;
- RRETURN(MATCH_COMMIT);
-
- case OP_COMMIT_ARG:
- Fmark = mb->nomatch_mark = Fecode + 2;
- RMATCH(Fecode + PRIV(OP_lengths)[*Fecode] + Fecode[1], RM36);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- mb->verb_current_recurse = Fcurrent_recurse;
- RRETURN(MATCH_COMMIT);
-
- case OP_PRUNE:
- RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM14);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- mb->verb_current_recurse = Fcurrent_recurse;
- RRETURN(MATCH_PRUNE);
-
- case OP_PRUNE_ARG:
- Fmark = mb->nomatch_mark = Fecode + 2;
- RMATCH(Fecode + PRIV(OP_lengths)[*Fecode] + Fecode[1], RM15);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- mb->verb_current_recurse = Fcurrent_recurse;
- RRETURN(MATCH_PRUNE);
-
- case OP_SKIP:
- RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM16);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- mb->verb_skip_ptr = Feptr; /* Pass back current position */
- mb->verb_current_recurse = Fcurrent_recurse;
- RRETURN(MATCH_SKIP);
-
- /* Note that, for Perl compatibility, SKIP with an argument does NOT set
- nomatch_mark. When a pattern match ends with a SKIP_ARG for which there was
- not a matching mark, we have to re-run the match, ignoring the SKIP_ARG
- that failed and any that precede it (either they also failed, or were not
- triggered). To do this, we maintain a count of executed SKIP_ARGs. If a
- SKIP_ARG gets to top level, the match is re-run with mb->ignore_skip_arg
- set to the count of the one that failed. */
-
- case OP_SKIP_ARG:
- mb->skip_arg_count++;
- if (mb->skip_arg_count <= mb->ignore_skip_arg)
- {
- Fecode += PRIV(OP_lengths)[*Fecode] + Fecode[1];
- break;
- }
- RMATCH(Fecode + PRIV(OP_lengths)[*Fecode] + Fecode[1], RM17);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-
- /* Pass back the current skip name and return the special MATCH_SKIP_ARG
- return code. This will either be caught by a matching MARK, or get to the
- top, where it causes a rematch with mb->ignore_skip_arg set to the value of
- mb->skip_arg_count. */
-
- mb->verb_skip_ptr = Fecode + 2;
- mb->verb_current_recurse = Fcurrent_recurse;
- RRETURN(MATCH_SKIP_ARG);
-
- /* For THEN (and THEN_ARG) we pass back the address of the opcode, so that
- the branch in which it occurs can be determined. */
-
- case OP_THEN:
- RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM18);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- mb->verb_ecode_ptr = Fecode;
- mb->verb_current_recurse = Fcurrent_recurse;
- RRETURN(MATCH_THEN);
-
- case OP_THEN_ARG:
- Fmark = mb->nomatch_mark = Fecode + 2;
- RMATCH(Fecode + PRIV(OP_lengths)[*Fecode] + Fecode[1], RM19);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- mb->verb_ecode_ptr = Fecode;
- mb->verb_current_recurse = Fcurrent_recurse;
- RRETURN(MATCH_THEN);
-
-
- /* ===================================================================== */
- /* There's been some horrible disaster. Arrival here can only mean there is
- something seriously wrong in the code above or the OP_xxx definitions. */
-
- default:
- return PCRE2_ERROR_INTERNAL;
- }
-
- /* Do not insert any code in here without much thought; it is assumed
- that "continue" in the code above comes out to here to repeat the main
- loop. */
-
- } /* End of main loop */
-/* Control never reaches here */
-
-
-/* ========================================================================= */
-/* The RRETURN() macro jumps here. The number that is saved in Freturn_id
-indicates which label we actually want to return to. The value in Frdepth is
-the index number of the frame in the vector. The return value has been placed
-in rrc. */
-
-#define LBL(val) case val: goto L_RM##val;
-
-RETURN_SWITCH:
-if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;
-if (Frdepth == 0) return rrc; /* Exit from the top level */
-F = (heapframe *)((char *)F - Fback_frame); /* Backtrack */
-mb->cb->callout_flags |= PCRE2_CALLOUT_BACKTRACK; /* Note for callouts */
-
-#ifdef DEBUG_SHOW_RMATCH
-fprintf(stderr, "++ RETURN %d to %d\n", rrc, Freturn_id);
-#endif
-
-switch (Freturn_id)
- {
- LBL( 1) LBL( 2) LBL( 3) LBL( 4) LBL( 5) LBL( 6) LBL( 7) LBL( 8)
- LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(16)
- LBL(17) LBL(18) LBL(19) LBL(20) LBL(21) LBL(22) LBL(23) LBL(24)
- LBL(25) LBL(26) LBL(27) LBL(28) LBL(29) LBL(30) LBL(31) LBL(32)
- LBL(33) LBL(34) LBL(35) LBL(36)
-
-#ifdef SUPPORT_WIDE_CHARS
- LBL(100) LBL(101)
-#endif
-
-#ifdef SUPPORT_UNICODE
- LBL(200) LBL(201) LBL(202) LBL(203) LBL(204) LBL(205) LBL(206)
- LBL(207) LBL(208) LBL(209) LBL(210) LBL(211) LBL(212) LBL(213)
- LBL(214) LBL(215) LBL(216) LBL(217) LBL(218) LBL(219) LBL(220)
- LBL(221) LBL(222) LBL(223) LBL(224) LBL(225)
-#endif
-
- default:
- return PCRE2_ERROR_INTERNAL;
- }
-#undef LBL
-}
-
-
-/*************************************************
-* Match a Regular Expression *
-*************************************************/
-
-/* This function applies a compiled pattern to a subject string and picks out
-portions of the string if it matches. Two elements in the vector are set for
-each substring: the offsets to the start and end of the substring.
-
-Arguments:
- code points to the compiled expression
- subject points to the subject string
- length length of subject string (may contain binary zeros)
- start_offset where to start in the subject string
- options option bits
- match_data points to a match_data block
- mcontext points a PCRE2 context
-
-Returns: > 0 => success; value is the number of ovector pairs filled
- = 0 => success, but ovector is not big enough
- = -1 => failed to match (PCRE2_ERROR_NOMATCH)
- = -2 => partial match (PCRE2_ERROR_PARTIAL)
- < -2 => some kind of unexpected problem
-*/
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length,
- PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data,
- pcre2_match_context *mcontext)
-{
-int rc;
-int was_zero_terminated = 0;
-const uint8_t *start_bits = NULL;
-const pcre2_real_code *re = (const pcre2_real_code *)code;
-
-BOOL anchored;
-BOOL firstline;
-BOOL has_first_cu = FALSE;
-BOOL has_req_cu = FALSE;
-BOOL startline;
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
-PCRE2_SPTR memchr_found_first_cu;
-PCRE2_SPTR memchr_found_first_cu2;
-#endif
-
-PCRE2_UCHAR first_cu = 0;
-PCRE2_UCHAR first_cu2 = 0;
-PCRE2_UCHAR req_cu = 0;
-PCRE2_UCHAR req_cu2 = 0;
-
-PCRE2_SPTR bumpalong_limit;
-PCRE2_SPTR end_subject;
-PCRE2_SPTR true_end_subject;
-PCRE2_SPTR start_match;
-PCRE2_SPTR req_cu_ptr;
-PCRE2_SPTR start_partial;
-PCRE2_SPTR match_partial;
-
-#ifdef SUPPORT_JIT
-BOOL use_jit;
-#endif
-
-/* This flag is needed even when Unicode is not supported for convenience
-(it is used by the IS_NEWLINE macro). */
-
-BOOL utf = FALSE;
-
-#ifdef SUPPORT_UNICODE
-BOOL ucp = FALSE;
-BOOL allow_invalid;
-uint32_t fragment_options = 0;
-#ifdef SUPPORT_JIT
-BOOL jit_checked_utf = FALSE;
-#endif
-#endif /* SUPPORT_UNICODE */
-
-PCRE2_SIZE frame_size;
-PCRE2_SIZE heapframes_size;
-
-/* We need to have mb as a pointer to a match block, because the IS_NEWLINE
-macro is used below, and it expects NLBLOCK to be defined as a pointer. */
-
-pcre2_callout_block cb;
-match_block actual_match_block;
-match_block *mb = &actual_match_block;
-
-/* Recognize NULL, length 0 as an empty string. */
-
-if (subject == NULL && length == 0) subject = (PCRE2_SPTR)"";
-
-/* Plausibility checks */
-
-if ((options & ~PUBLIC_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION;
-if (code == NULL || subject == NULL || match_data == NULL)
- return PCRE2_ERROR_NULL;
-
-start_match = subject + start_offset;
-req_cu_ptr = start_match - 1;
-if (length == PCRE2_ZERO_TERMINATED)
- {
- length = PRIV(strlen)(subject);
- was_zero_terminated = 1;
- }
-true_end_subject = end_subject = subject + length;
-
-if (start_offset > length) return PCRE2_ERROR_BADOFFSET;
-
-/* Check that the first field in the block is the magic number. */
-
-if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;
-
-/* Check the code unit width. */
-
-if ((re->flags & PCRE2_MODE_MASK) != PCRE2_CODE_UNIT_WIDTH/8)
- return PCRE2_ERROR_BADMODE;
-
-/* PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART are match-time flags in the
-options variable for this function. Users of PCRE2 who are not calling the
-function directly would like to have a way of setting these flags, in the same
-way that they can set pcre2_compile() flags like PCRE2_NO_AUTOPOSSESS with
-constructions like (*NO_AUTOPOSSESS). To enable this, (*NOTEMPTY) and
-(*NOTEMPTY_ATSTART) set bits in the pattern's "flag" function which we now
-transfer to the options for this function. The bits are guaranteed to be
-adjacent, but do not have the same values. This bit of Boolean trickery assumes
-that the match-time bits are not more significant than the flag bits. If by
-accident this is not the case, a compile-time division by zero error will
-occur. */
-
-#define FF (PCRE2_NOTEMPTY_SET|PCRE2_NE_ATST_SET)
-#define OO (PCRE2_NOTEMPTY|PCRE2_NOTEMPTY_ATSTART)
-options |= (re->flags & FF) / ((FF & (~FF+1)) / (OO & (~OO+1)));
-#undef FF
-#undef OO
-
-/* If the pattern was successfully studied with JIT support, we will run the
-JIT executable instead of the rest of this function. Most options must be set
-at compile time for the JIT code to be usable. */
-
-#ifdef SUPPORT_JIT
-use_jit = (re->executable_jit != NULL &&
- (options & ~PUBLIC_JIT_MATCH_OPTIONS) == 0);
-#endif
-
-/* Initialize UTF/UCP parameters. */
-
-#ifdef SUPPORT_UNICODE
-utf = (re->overall_options & PCRE2_UTF) != 0;
-allow_invalid = (re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0;
-ucp = (re->overall_options & PCRE2_UCP) != 0;
-#endif /* SUPPORT_UNICODE */
-
-/* Convert the partial matching flags into an integer. */
-
-mb->partial = ((options & PCRE2_PARTIAL_HARD) != 0)? 2 :
- ((options & PCRE2_PARTIAL_SOFT) != 0)? 1 : 0;
-
-/* Partial matching and PCRE2_ENDANCHORED are currently not allowed at the same
-time. */
-
-if (mb->partial != 0 &&
- ((re->overall_options | options) & PCRE2_ENDANCHORED) != 0)
- return PCRE2_ERROR_BADOPTION;
-
-/* It is an error to set an offset limit without setting the flag at compile
-time. */
-
-if (mcontext != NULL && mcontext->offset_limit != PCRE2_UNSET &&
- (re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0)
- return PCRE2_ERROR_BADOFFSETLIMIT;
-
-/* If the match data block was previously used with PCRE2_COPY_MATCHED_SUBJECT,
-free the memory that was obtained. Set the field to NULL for no match cases. */
-
-if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0)
- {
- match_data->memctl.free((void *)match_data->subject,
- match_data->memctl.memory_data);
- match_data->flags &= ~PCRE2_MD_COPIED_SUBJECT;
- }
-match_data->subject = NULL;
-
-/* Zero the error offset in case the first code unit is invalid UTF. */
-
-match_data->startchar = 0;
-
-
-/* ============================= JIT matching ============================== */
-
-/* Prepare for JIT matching. Check a UTF string for validity unless no check is
-requested or invalid UTF can be handled. We check only the portion of the
-subject that might be be inspected during matching - from the offset minus the
-maximum lookbehind to the given length. This saves time when a small part of a
-large subject is being matched by the use of a starting offset. Note that the
-maximum lookbehind is a number of characters, not code units. */
-
-#ifdef SUPPORT_JIT
-if (use_jit)
- {
-#ifdef SUPPORT_UNICODE
- if (utf && (options & PCRE2_NO_UTF_CHECK) == 0 && !allow_invalid)
- {
-#if PCRE2_CODE_UNIT_WIDTH != 32
- unsigned int i;
-#endif
-
- /* For 8-bit and 16-bit UTF, check that the first code unit is a valid
- character start. */
-
-#if PCRE2_CODE_UNIT_WIDTH != 32
- if (start_match < end_subject && NOT_FIRSTCU(*start_match))
- {
- if (start_offset > 0) return PCRE2_ERROR_BADUTFOFFSET;
-#if PCRE2_CODE_UNIT_WIDTH == 8
- return PCRE2_ERROR_UTF8_ERR20; /* Isolated 0x80 byte */
-#else
- return PCRE2_ERROR_UTF16_ERR3; /* Isolated low surrogate */
-#endif
- }
-#endif /* WIDTH != 32 */
-
- /* Move back by the maximum lookbehind, just in case it happens at the very
- start of matching. */
-
-#if PCRE2_CODE_UNIT_WIDTH != 32
- for (i = re->max_lookbehind; i > 0 && start_match > subject; i--)
- {
- start_match--;
- while (start_match > subject &&
-#if PCRE2_CODE_UNIT_WIDTH == 8
- (*start_match & 0xc0) == 0x80)
-#else /* 16-bit */
- (*start_match & 0xfc00) == 0xdc00)
-#endif
- start_match--;
- }
-#else /* PCRE2_CODE_UNIT_WIDTH != 32 */
-
- /* In the 32-bit library, one code unit equals one character. However,
- we cannot just subtract the lookbehind and then compare pointers, because
- a very large lookbehind could create an invalid pointer. */
-
- if (start_offset >= re->max_lookbehind)
- start_match -= re->max_lookbehind;
- else
- start_match = subject;
-#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */
-
- /* Validate the relevant portion of the subject. Adjust the offset of an
- invalid code point to be an absolute offset in the whole string. */
-
- match_data->rc = PRIV(valid_utf)(start_match,
- length - (start_match - subject), &(match_data->startchar));
- if (match_data->rc != 0)
- {
- match_data->startchar += start_match - subject;
- return match_data->rc;
- }
- jit_checked_utf = TRUE;
- }
-#endif /* SUPPORT_UNICODE */
-
- /* If JIT returns BADOPTION, which means that the selected complete or
- partial matching mode was not compiled, fall through to the interpreter. */
-
- rc = pcre2_jit_match(code, subject, length, start_offset, options,
- match_data, mcontext);
- if (rc != PCRE2_ERROR_JIT_BADOPTION)
- {
- if (rc >= 0 && (options & PCRE2_COPY_MATCHED_SUBJECT) != 0)
- {
- length = CU2BYTES(length + was_zero_terminated);
- match_data->subject = match_data->memctl.malloc(length,
- match_data->memctl.memory_data);
- if (match_data->subject == NULL) return PCRE2_ERROR_NOMEMORY;
- memcpy((void *)match_data->subject, subject, length);
- match_data->flags |= PCRE2_MD_COPIED_SUBJECT;
- }
- return rc;
- }
- }
-#endif /* SUPPORT_JIT */
-
-/* ========================= End of JIT matching ========================== */
-
-
-/* Proceed with non-JIT matching. The default is to allow lookbehinds to the
-start of the subject. A UTF check when there is a non-zero offset may change
-this. */
-
-mb->check_subject = subject;
-
-/* If a UTF subject string was not checked for validity in the JIT code above,
-check it here, and handle support for invalid UTF strings. The check above
-happens only when invalid UTF is not supported and PCRE2_NO_CHECK_UTF is unset.
-If we get here in those circumstances, it means the subject string is valid,
-but for some reason JIT matching was not successful. There is no need to check
-the subject again.
-
-We check only the portion of the subject that might be be inspected during
-matching - from the offset minus the maximum lookbehind to the given length.
-This saves time when a small part of a large subject is being matched by the
-use of a starting offset. Note that the maximum lookbehind is a number of
-characters, not code units.
-
-Note also that support for invalid UTF forces a check, overriding the setting
-of PCRE2_NO_CHECK_UTF. */
-
-#ifdef SUPPORT_UNICODE
-if (utf &&
-#ifdef SUPPORT_JIT
- !jit_checked_utf &&
-#endif
- ((options & PCRE2_NO_UTF_CHECK) == 0 || allow_invalid))
- {
-#if PCRE2_CODE_UNIT_WIDTH != 32
- BOOL skipped_bad_start = FALSE;
-#endif
-
- /* For 8-bit and 16-bit UTF, check that the first code unit is a valid
- character start. If we are handling invalid UTF, just skip over such code
- units. Otherwise, give an appropriate error. */
-
-#if PCRE2_CODE_UNIT_WIDTH != 32
- if (allow_invalid)
- {
- while (start_match < end_subject && NOT_FIRSTCU(*start_match))
- {
- start_match++;
- skipped_bad_start = TRUE;
- }
- }
- else if (start_match < end_subject && NOT_FIRSTCU(*start_match))
- {
- if (start_offset > 0) return PCRE2_ERROR_BADUTFOFFSET;
-#if PCRE2_CODE_UNIT_WIDTH == 8
- return PCRE2_ERROR_UTF8_ERR20; /* Isolated 0x80 byte */
-#else
- return PCRE2_ERROR_UTF16_ERR3; /* Isolated low surrogate */
-#endif
- }
-#endif /* WIDTH != 32 */
-
- /* The mb->check_subject field points to the start of UTF checking;
- lookbehinds can go back no further than this. */
-
- mb->check_subject = start_match;
-
- /* Move back by the maximum lookbehind, just in case it happens at the very
- start of matching, but don't do this if we skipped bad 8-bit or 16-bit code
- units above. */
-
-#if PCRE2_CODE_UNIT_WIDTH != 32
- if (!skipped_bad_start)
- {
- unsigned int i;
- for (i = re->max_lookbehind; i > 0 && mb->check_subject > subject; i--)
- {
- mb->check_subject--;
- while (mb->check_subject > subject &&
-#if PCRE2_CODE_UNIT_WIDTH == 8
- (*mb->check_subject & 0xc0) == 0x80)
-#else /* 16-bit */
- (*mb->check_subject & 0xfc00) == 0xdc00)
-#endif
- mb->check_subject--;
- }
- }
-#else /* PCRE2_CODE_UNIT_WIDTH != 32 */
-
- /* In the 32-bit library, one code unit equals one character. However,
- we cannot just subtract the lookbehind and then compare pointers, because
- a very large lookbehind could create an invalid pointer. */
-
- if (start_offset >= re->max_lookbehind)
- mb->check_subject -= re->max_lookbehind;
- else
- mb->check_subject = subject;
-#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */
-
- /* Validate the relevant portion of the subject. There's a loop in case we
- encounter bad UTF in the characters preceding start_match which we are
- scanning because of a lookbehind. */
-
- for (;;)
- {
- match_data->rc = PRIV(valid_utf)(mb->check_subject,
- length - (mb->check_subject - subject), &(match_data->startchar));
-
- if (match_data->rc == 0) break; /* Valid UTF string */
-
- /* Invalid UTF string. Adjust the offset to be an absolute offset in the
- whole string. If we are handling invalid UTF strings, set end_subject to
- stop before the bad code unit, and set the options to "not end of line".
- Otherwise return the error. */
-
- match_data->startchar += mb->check_subject - subject;
- if (!allow_invalid || match_data->rc > 0) return match_data->rc;
- end_subject = subject + match_data->startchar;
-
- /* If the end precedes start_match, it means there is invalid UTF in the
- extra code units we reversed over because of a lookbehind. Advance past the
- first bad code unit, and then skip invalid character starting code units in
- 8-bit and 16-bit modes, and try again with the original end point. */
-
- if (end_subject < start_match)
- {
- mb->check_subject = end_subject + 1;
-#if PCRE2_CODE_UNIT_WIDTH != 32
- while (mb->check_subject < start_match && NOT_FIRSTCU(*mb->check_subject))
- mb->check_subject++;
-#endif
- end_subject = true_end_subject;
- }
-
- /* Otherwise, set the not end of line option, and do the match. */
-
- else
- {
- fragment_options = PCRE2_NOTEOL;
- break;
- }
- }
- }
-#endif /* SUPPORT_UNICODE */
-
-/* A NULL match context means "use a default context", but we take the memory
-control functions from the pattern. */
-
-if (mcontext == NULL)
- {
- mcontext = (pcre2_match_context *)(&PRIV(default_match_context));
- mb->memctl = re->memctl;
- }
-else mb->memctl = mcontext->memctl;
-
-anchored = ((re->overall_options | options) & PCRE2_ANCHORED) != 0;
-firstline = (re->overall_options & PCRE2_FIRSTLINE) != 0;
-startline = (re->flags & PCRE2_STARTLINE) != 0;
-bumpalong_limit = (mcontext->offset_limit == PCRE2_UNSET)?
- true_end_subject : subject + mcontext->offset_limit;
-
-/* Initialize and set up the fixed fields in the callout block, with a pointer
-in the match block. */
-
-mb->cb = &cb;
-cb.version = 2;
-cb.subject = subject;
-cb.subject_length = (PCRE2_SIZE)(end_subject - subject);
-cb.callout_flags = 0;
-
-/* Fill in the remaining fields in the match block, except for moptions, which
-gets set later. */
-
-mb->callout = mcontext->callout;
-mb->callout_data = mcontext->callout_data;
-
-mb->start_subject = subject;
-mb->start_offset = start_offset;
-mb->end_subject = end_subject;
-mb->hasthen = (re->flags & PCRE2_HASTHEN) != 0;
-mb->allowemptypartial = (re->max_lookbehind > 0) ||
- (re->flags & PCRE2_MATCH_EMPTY) != 0;
-mb->poptions = re->overall_options; /* Pattern options */
-mb->ignore_skip_arg = 0;
-mb->mark = mb->nomatch_mark = NULL; /* In case never set */
-
-/* The name table is needed for finding all the numbers associated with a
-given name, for condition testing. The code follows the name table. */
-
-mb->name_table = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code));
-mb->name_count = re->name_count;
-mb->name_entry_size = re->name_entry_size;
-mb->start_code = mb->name_table + re->name_count * re->name_entry_size;
-
-/* Process the \R and newline settings. */
-
-mb->bsr_convention = re->bsr_convention;
-mb->nltype = NLTYPE_FIXED;
-switch(re->newline_convention)
- {
- case PCRE2_NEWLINE_CR:
- mb->nllen = 1;
- mb->nl[0] = CHAR_CR;
- break;
-
- case PCRE2_NEWLINE_LF:
- mb->nllen = 1;
- mb->nl[0] = CHAR_NL;
- break;
-
- case PCRE2_NEWLINE_NUL:
- mb->nllen = 1;
- mb->nl[0] = CHAR_NUL;
- break;
-
- case PCRE2_NEWLINE_CRLF:
- mb->nllen = 2;
- mb->nl[0] = CHAR_CR;
- mb->nl[1] = CHAR_NL;
- break;
-
- case PCRE2_NEWLINE_ANY:
- mb->nltype = NLTYPE_ANY;
- break;
-
- case PCRE2_NEWLINE_ANYCRLF:
- mb->nltype = NLTYPE_ANYCRLF;
- break;
-
- default: return PCRE2_ERROR_INTERNAL;
- }
-
-/* The backtracking frames have fixed data at the front, and a PCRE2_SIZE
-vector at the end, whose size depends on the number of capturing parentheses in
-the pattern. It is not used at all if there are no capturing parentheses.
-
- frame_size is the total size of each frame
- match_data->heapframes is the pointer to the frames vector
- match_data->heapframes_size is the total size of the vector
-
-We must pad the frame_size for alignment to ensure subsequent frames are as
-aligned as heapframe. Whilst ovector is word-aligned due to being a PCRE2_SIZE
-array, that does not guarantee it is suitably aligned for pointers, as some
-architectures have pointers that are larger than a size_t. */
-
-frame_size = (offsetof(heapframe, ovector) +
- re->top_bracket * 2 * sizeof(PCRE2_SIZE) + HEAPFRAME_ALIGNMENT - 1) &
- ~(HEAPFRAME_ALIGNMENT - 1);
-
-/* Limits set in the pattern override the match context only if they are
-smaller. */
-
-mb->heap_limit = ((mcontext->heap_limit < re->limit_heap)?
- mcontext->heap_limit : re->limit_heap) * 1024;
-
-mb->match_limit = (mcontext->match_limit < re->limit_match)?
- mcontext->match_limit : re->limit_match;
-
-mb->match_limit_depth = (mcontext->depth_limit < re->limit_depth)?
- mcontext->depth_limit : re->limit_depth;
-
-/* If a pattern has very many capturing parentheses, the frame size may be very
-large. Set the initial frame vector size to ensure that there are at least 10
-available frames, but enforce a minimum of START_FRAMES_SIZE. If this is
-greater than the heap limit, get as large a vector as possible. Always round
-the size to a multiple of the frame size. */
-
-heapframes_size = frame_size * 10;
-if (heapframes_size < START_FRAMES_SIZE) heapframes_size = START_FRAMES_SIZE;
-if (heapframes_size > mb->heap_limit)
- {
- if (frame_size > mb->heap_limit ) return PCRE2_ERROR_HEAPLIMIT;
- heapframes_size = mb->heap_limit;
- }
-
-/* If an existing frame vector in the match_data block is large enough, we can
-use it.Otherwise, free any pre-existing vector and get a new one. */
-
-if (match_data->heapframes_size < heapframes_size)
- {
- match_data->memctl.free(match_data->heapframes,
- match_data->memctl.memory_data);
- match_data->heapframes = match_data->memctl.malloc(heapframes_size,
- match_data->memctl.memory_data);
- if (match_data->heapframes == NULL)
- {
- match_data->heapframes_size = 0;
- return PCRE2_ERROR_NOMEMORY;
- }
- match_data->heapframes_size = heapframes_size;
- }
-
-/* Write to the ovector within the first frame to mark every capture unset and
-to avoid uninitialized memory read errors when it is copied to a new frame. */
-
-memset((char *)(match_data->heapframes) + offsetof(heapframe, ovector), 0xff,
- frame_size - offsetof(heapframe, ovector));
-
-/* Pointers to the individual character tables */
-
-mb->lcc = re->tables + lcc_offset;
-mb->fcc = re->tables + fcc_offset;
-mb->ctypes = re->tables + ctypes_offset;
-
-/* Set up the first code unit to match, if available. If there's no first code
-unit there may be a bitmap of possible first characters. */
-
-if ((re->flags & PCRE2_FIRSTSET) != 0)
- {
- has_first_cu = TRUE;
- first_cu = first_cu2 = (PCRE2_UCHAR)(re->first_codeunit);
- if ((re->flags & PCRE2_FIRSTCASELESS) != 0)
- {
- first_cu2 = TABLE_GET(first_cu, mb->fcc, first_cu);
-#ifdef SUPPORT_UNICODE
-#if PCRE2_CODE_UNIT_WIDTH == 8
- if (first_cu > 127 && ucp && !utf) first_cu2 = UCD_OTHERCASE(first_cu);
-#else
- if (first_cu > 127 && (utf || ucp)) first_cu2 = UCD_OTHERCASE(first_cu);
-#endif
-#endif /* SUPPORT_UNICODE */
- }
- }
-else
- if (!startline && (re->flags & PCRE2_FIRSTMAPSET) != 0)
- start_bits = re->start_bitmap;
-
-/* There may also be a "last known required character" set. */
-
-if ((re->flags & PCRE2_LASTSET) != 0)
- {
- has_req_cu = TRUE;
- req_cu = req_cu2 = (PCRE2_UCHAR)(re->last_codeunit);
- if ((re->flags & PCRE2_LASTCASELESS) != 0)
- {
- req_cu2 = TABLE_GET(req_cu, mb->fcc, req_cu);
-#ifdef SUPPORT_UNICODE
-#if PCRE2_CODE_UNIT_WIDTH == 8
- if (req_cu > 127 && ucp && !utf) req_cu2 = UCD_OTHERCASE(req_cu);
-#else
- if (req_cu > 127 && (utf || ucp)) req_cu2 = UCD_OTHERCASE(req_cu);
-#endif
-#endif /* SUPPORT_UNICODE */
- }
- }
-
-
-/* ==========================================================================*/
-
-/* Loop for handling unanchored repeated matching attempts; for anchored regexs
-the loop runs just once. */
-
-#ifdef SUPPORT_UNICODE
-FRAGMENT_RESTART:
-#endif
-
-start_partial = match_partial = NULL;
-mb->hitend = FALSE;
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
-memchr_found_first_cu = NULL;
-memchr_found_first_cu2 = NULL;
-#endif
-
-for(;;)
- {
- PCRE2_SPTR new_start_match;
-
- /* ----------------- Start of match optimizations ---------------- */
-
- /* There are some optimizations that avoid running the match if a known
- starting point is not found, or if a known later code unit is not present.
- However, there is an option (settable at compile time) that disables these,
- for testing and for ensuring that all callouts do actually occur. */
-
- if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
- {
- /* If firstline is TRUE, the start of the match is constrained to the first
- line of a multiline string. That is, the match must be before or at the
- first newline following the start of matching. Temporarily adjust
- end_subject so that we stop the scans for a first code unit at a newline.
- If the match fails at the newline, later code breaks the loop. */
-
- if (firstline)
- {
- PCRE2_SPTR t = start_match;
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- while (t < end_subject && !IS_NEWLINE(t))
- {
- t++;
- ACROSSCHAR(t < end_subject, t, t++);
- }
- }
- else
-#endif
- while (t < end_subject && !IS_NEWLINE(t)) t++;
- end_subject = t;
- }
-
- /* Anchored: check the first code unit if one is recorded. This may seem
- pointless but it can help in detecting a no match case without scanning for
- the required code unit. */
-
- if (anchored)
- {
- if (has_first_cu || start_bits != NULL)
- {
- BOOL ok = start_match < end_subject;
- if (ok)
- {
- PCRE2_UCHAR c = UCHAR21TEST(start_match);
- ok = has_first_cu && (c == first_cu || c == first_cu2);
- if (!ok && start_bits != NULL)
- {
-#if PCRE2_CODE_UNIT_WIDTH != 8
- if (c > 255) c = 255;
-#endif
- ok = (start_bits[c/8] & (1u << (c&7))) != 0;
- }
- }
- if (!ok)
- {
- rc = MATCH_NOMATCH;
- break;
- }
- }
- }
-
- /* Not anchored. Advance to a unique first code unit if there is one. */
-
- else
- {
- if (has_first_cu)
- {
- if (first_cu != first_cu2) /* Caseless */
- {
- /* In 16-bit and 32_bit modes we have to do our own search, so can
- look for both cases at once. */
-
-#if PCRE2_CODE_UNIT_WIDTH != 8
- PCRE2_UCHAR smc;
- while (start_match < end_subject &&
- (smc = UCHAR21TEST(start_match)) != first_cu &&
- smc != first_cu2)
- start_match++;
-#else
- /* In 8-bit mode, the use of memchr() gives a big speed up, even
- though we have to call it twice in order to find the earliest
- occurrence of the code unit in either of its cases. Caching is used
- to remember the positions of previously found code units. This can
- make a huge difference when the strings are very long and only one
- case is actually present. */
-
- PCRE2_SPTR pp1 = NULL;
- PCRE2_SPTR pp2 = NULL;
- PCRE2_SIZE searchlength = end_subject - start_match;
-
- /* If we haven't got a previously found position for first_cu, or if
- the current starting position is later, we need to do a search. If
- the code unit is not found, set it to the end. */
-
- if (memchr_found_first_cu == NULL ||
- start_match > memchr_found_first_cu)
- {
- pp1 = memchr(start_match, first_cu, searchlength);
- memchr_found_first_cu = (pp1 == NULL)? end_subject : pp1;
- }
-
- /* If the start is before a previously found position, use the
- previous position, or NULL if a previous search failed. */
-
- else pp1 = (memchr_found_first_cu == end_subject)? NULL :
- memchr_found_first_cu;
-
- /* Do the same thing for the other case. */
-
- if (memchr_found_first_cu2 == NULL ||
- start_match > memchr_found_first_cu2)
- {
- pp2 = memchr(start_match, first_cu2, searchlength);
- memchr_found_first_cu2 = (pp2 == NULL)? end_subject : pp2;
- }
-
- else pp2 = (memchr_found_first_cu2 == end_subject)? NULL :
- memchr_found_first_cu2;
-
- /* Set the start to the end of the subject if neither case was found.
- Otherwise, use the earlier found point. */
-
- if (pp1 == NULL)
- start_match = (pp2 == NULL)? end_subject : pp2;
- else
- start_match = (pp2 == NULL || pp1 < pp2)? pp1 : pp2;
-
-#endif /* 8-bit handling */
- }
-
- /* The caseful case is much simpler. */
-
- else
- {
-#if PCRE2_CODE_UNIT_WIDTH != 8
- while (start_match < end_subject && UCHAR21TEST(start_match) !=
- first_cu)
- start_match++;
-#else
- start_match = memchr(start_match, first_cu, end_subject - start_match);
- if (start_match == NULL) start_match = end_subject;
-#endif
- }
-
- /* If we can't find the required first code unit, having reached the
- true end of the subject, break the bumpalong loop, to force a match
- failure, except when doing partial matching, when we let the next cycle
- run at the end of the subject. To see why, consider the pattern
- /(?<=abc)def/, which partially matches "abc", even though the string
- does not contain the starting character "d". If we have not reached the
- true end of the subject (PCRE2_FIRSTLINE caused end_subject to be
- temporarily modified) we also let the cycle run, because the matching
- string is legitimately allowed to start with the first code unit of a
- newline. */
-
- if (mb->partial == 0 && start_match >= mb->end_subject)
- {
- rc = MATCH_NOMATCH;
- break;
- }
- }
-
- /* If there's no first code unit, advance to just after a linebreak for a
- multiline match if required. */
-
- else if (startline)
- {
- if (start_match > mb->start_subject + start_offset)
- {
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- while (start_match < end_subject && !WAS_NEWLINE(start_match))
- {
- start_match++;
- ACROSSCHAR(start_match < end_subject, start_match, start_match++);
- }
- }
- else
-#endif
- while (start_match < end_subject && !WAS_NEWLINE(start_match))
- start_match++;
-
- /* If we have just passed a CR and the newline option is ANY or
- ANYCRLF, and we are now at a LF, advance the match position by one
- more code unit. */
-
- if (start_match[-1] == CHAR_CR &&
- (mb->nltype == NLTYPE_ANY || mb->nltype == NLTYPE_ANYCRLF) &&
- start_match < end_subject &&
- UCHAR21TEST(start_match) == CHAR_NL)
- start_match++;
- }
- }
-
- /* If there's no first code unit or a requirement for a multiline line
- start, advance to a non-unique first code unit if any have been
- identified. The bitmap contains only 256 bits. When code units are 16 or
- 32 bits wide, all code units greater than 254 set the 255 bit. */
-
- else if (start_bits != NULL)
- {
- while (start_match < end_subject)
- {
- uint32_t c = UCHAR21TEST(start_match);
-#if PCRE2_CODE_UNIT_WIDTH != 8
- if (c > 255) c = 255;
-#endif
- if ((start_bits[c/8] & (1u << (c&7))) != 0) break;
- start_match++;
- }
-
- /* See comment above in first_cu checking about the next few lines. */
-
- if (mb->partial == 0 && start_match >= mb->end_subject)
- {
- rc = MATCH_NOMATCH;
- break;
- }
- }
- } /* End first code unit handling */
-
- /* Restore fudged end_subject */
-
- end_subject = mb->end_subject;
-
- /* The following two optimizations must be disabled for partial matching. */
-
- if (mb->partial == 0)
- {
- PCRE2_SPTR p;
-
- /* The minimum matching length is a lower bound; no string of that length
- may actually match the pattern. Although the value is, strictly, in
- characters, we treat it as code units to avoid spending too much time in
- this optimization. */
-
- if (end_subject - start_match < re->minlength)
- {
- rc = MATCH_NOMATCH;
- break;
- }
-
- /* If req_cu is set, we know that that code unit must appear in the
- subject for the (non-partial) match to succeed. If the first code unit is
- set, req_cu must be later in the subject; otherwise the test starts at
- the match point. This optimization can save a huge amount of backtracking
- in patterns with nested unlimited repeats that aren't going to match.
- Writing separate code for caseful/caseless versions makes it go faster,
- as does using an autoincrement and backing off on a match. As in the case
- of the first code unit, using memchr() in the 8-bit library gives a big
- speed up. Unlike the first_cu check above, we do not need to call
- memchr() twice in the caseless case because we only need to check for the
- presence of the character in either case, not find the first occurrence.
-
- The search can be skipped if the code unit was found later than the
- current starting point in a previous iteration of the bumpalong loop.
-
- HOWEVER: when the subject string is very, very long, searching to its end
- can take a long time, and give bad performance on quite ordinary
- anchored patterns. This showed up when somebody was matching something
- like /^\d+C/ on a 32-megabyte string... so we don't do this when the
- string is sufficiently long, but it's worth searching a lot more for
- unanchored patterns. */
-
- p = start_match + (has_first_cu? 1:0);
- if (has_req_cu && p > req_cu_ptr)
- {
- PCRE2_SIZE check_length = end_subject - start_match;
-
- if (check_length < REQ_CU_MAX ||
- (!anchored && check_length < REQ_CU_MAX * 1000))
- {
- if (req_cu != req_cu2) /* Caseless */
- {
-#if PCRE2_CODE_UNIT_WIDTH != 8
- while (p < end_subject)
- {
- uint32_t pp = UCHAR21INCTEST(p);
- if (pp == req_cu || pp == req_cu2) { p--; break; }
- }
-#else /* 8-bit code units */
- PCRE2_SPTR pp = p;
- p = memchr(pp, req_cu, end_subject - pp);
- if (p == NULL)
- {
- p = memchr(pp, req_cu2, end_subject - pp);
- if (p == NULL) p = end_subject;
- }
-#endif /* PCRE2_CODE_UNIT_WIDTH != 8 */
- }
-
- /* The caseful case */
-
- else
- {
-#if PCRE2_CODE_UNIT_WIDTH != 8
- while (p < end_subject)
- {
- if (UCHAR21INCTEST(p) == req_cu) { p--; break; }
- }
-
-#else /* 8-bit code units */
- p = memchr(p, req_cu, end_subject - p);
- if (p == NULL) p = end_subject;
-#endif
- }
-
- /* If we can't find the required code unit, break the bumpalong loop,
- forcing a match failure. */
-
- if (p >= end_subject)
- {
- rc = MATCH_NOMATCH;
- break;
- }
-
- /* If we have found the required code unit, save the point where we
- found it, so that we don't search again next time round the bumpalong
- loop if the start hasn't yet passed this code unit. */
-
- req_cu_ptr = p;
- }
- }
- }
- }
-
- /* ------------ End of start of match optimizations ------------ */
-
- /* Give no match if we have passed the bumpalong limit. */
-
- if (start_match > bumpalong_limit)
- {
- rc = MATCH_NOMATCH;
- break;
- }
-
- /* OK, we can now run the match. If "hitend" is set afterwards, remember the
- first starting point for which a partial match was found. */
-
- cb.start_match = (PCRE2_SIZE)(start_match - subject);
- cb.callout_flags |= PCRE2_CALLOUT_STARTMATCH;
-
- mb->start_used_ptr = start_match;
- mb->last_used_ptr = start_match;
-#ifdef SUPPORT_UNICODE
- mb->moptions = options | fragment_options;
-#else
- mb->moptions = options;
-#endif
- mb->match_call_count = 0;
- mb->end_offset_top = 0;
- mb->skip_arg_count = 0;
-
- rc = match(start_match, mb->start_code, re->top_bracket, frame_size,
- match_data, mb);
-
- if (mb->hitend && start_partial == NULL)
- {
- start_partial = mb->start_used_ptr;
- match_partial = start_match;
- }
-
- switch(rc)
- {
- /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched
- the SKIP's arg was not found. In this circumstance, Perl ignores the SKIP
- entirely. The only way we can do that is to re-do the match at the same
- point, with a flag to force SKIP with an argument to be ignored. Just
- treating this case as NOMATCH does not work because it does not check other
- alternatives in patterns such as A(*SKIP:A)B|AC when the subject is AC. */
-
- case MATCH_SKIP_ARG:
- new_start_match = start_match;
- mb->ignore_skip_arg = mb->skip_arg_count;
- break;
-
- /* SKIP passes back the next starting point explicitly, but if it is no
- greater than the match we have just done, treat it as NOMATCH. */
-
- case MATCH_SKIP:
- if (mb->verb_skip_ptr > start_match)
- {
- new_start_match = mb->verb_skip_ptr;
- break;
- }
- /* Fall through */
-
- /* NOMATCH and PRUNE advance by one character. THEN at this level acts
- exactly like PRUNE. Unset ignore SKIP-with-argument. */
-
- case MATCH_NOMATCH:
- case MATCH_PRUNE:
- case MATCH_THEN:
- mb->ignore_skip_arg = 0;
- new_start_match = start_match + 1;
-#ifdef SUPPORT_UNICODE
- if (utf)
- ACROSSCHAR(new_start_match < end_subject, new_start_match,
- new_start_match++);
-#endif
- break;
-
- /* COMMIT disables the bumpalong, but otherwise behaves as NOMATCH. */
-
- case MATCH_COMMIT:
- rc = MATCH_NOMATCH;
- goto ENDLOOP;
-
- /* Any other return is either a match, or some kind of error. */
-
- default:
- goto ENDLOOP;
- }
-
- /* Control reaches here for the various types of "no match at this point"
- result. Reset the code to MATCH_NOMATCH for subsequent checking. */
-
- rc = MATCH_NOMATCH;
-
- /* If PCRE2_FIRSTLINE is set, the match must happen before or at the first
- newline in the subject (though it may continue over the newline). Therefore,
- if we have just failed to match, starting at a newline, do not continue. */
-
- if (firstline && IS_NEWLINE(start_match)) break;
-
- /* Advance to new matching position */
-
- start_match = new_start_match;
-
- /* Break the loop if the pattern is anchored or if we have passed the end of
- the subject. */
-
- if (anchored || start_match > end_subject) break;
-
- /* If we have just passed a CR and we are now at a LF, and the pattern does
- not contain any explicit matches for \r or \n, and the newline option is CRLF
- or ANY or ANYCRLF, advance the match position by one more code unit. In
- normal matching start_match will aways be greater than the first position at
- this stage, but a failed *SKIP can cause a return at the same point, which is
- why the first test exists. */
-
- if (start_match > subject + start_offset &&
- start_match[-1] == CHAR_CR &&
- start_match < end_subject &&
- *start_match == CHAR_NL &&
- (re->flags & PCRE2_HASCRORLF) == 0 &&
- (mb->nltype == NLTYPE_ANY ||
- mb->nltype == NLTYPE_ANYCRLF ||
- mb->nllen == 2))
- start_match++;
-
- mb->mark = NULL; /* Reset for start of next match attempt */
- } /* End of for(;;) "bumpalong" loop */
-
-/* ==========================================================================*/
-
-/* When we reach here, one of the following stopping conditions is true:
-
-(1) The match succeeded, either completely, or partially;
-
-(2) The pattern is anchored or the match was failed after (*COMMIT);
-
-(3) We are past the end of the subject or the bumpalong limit;
-
-(4) PCRE2_FIRSTLINE is set and we have failed to match at a newline, because
- this option requests that a match occur at or before the first newline in
- the subject.
-
-(5) Some kind of error occurred.
-
-*/
-
-ENDLOOP:
-
-/* If end_subject != true_end_subject, it means we are handling invalid UTF,
-and have just processed a non-terminal fragment. If this resulted in no match
-or a partial match we must carry on to the next fragment (a partial match is
-returned to the caller only at the very end of the subject). A loop is used to
-avoid trying to match against empty fragments; if the pattern can match an
-empty string it would have done so already. */
-
-#ifdef SUPPORT_UNICODE
-if (utf && end_subject != true_end_subject &&
- (rc == MATCH_NOMATCH || rc == PCRE2_ERROR_PARTIAL))
- {
- for (;;)
- {
- /* Advance past the first bad code unit, and then skip invalid character
- starting code units in 8-bit and 16-bit modes. */
-
- start_match = end_subject + 1;
-
-#if PCRE2_CODE_UNIT_WIDTH != 32
- while (start_match < true_end_subject && NOT_FIRSTCU(*start_match))
- start_match++;
-#endif
-
- /* If we have hit the end of the subject, there isn't another non-empty
- fragment, so give up. */
-
- if (start_match >= true_end_subject)
- {
- rc = MATCH_NOMATCH; /* In case it was partial */
- break;
- }
-
- /* Check the rest of the subject */
-
- mb->check_subject = start_match;
- rc = PRIV(valid_utf)(start_match, length - (start_match - subject),
- &(match_data->startchar));
-
- /* The rest of the subject is valid UTF. */
-
- if (rc == 0)
- {
- mb->end_subject = end_subject = true_end_subject;
- fragment_options = PCRE2_NOTBOL;
- goto FRAGMENT_RESTART;
- }
-
- /* A subsequent UTF error has been found; if the next fragment is
- non-empty, set up to process it. Otherwise, let the loop advance. */
-
- else if (rc < 0)
- {
- mb->end_subject = end_subject = start_match + match_data->startchar;
- if (end_subject > start_match)
- {
- fragment_options = PCRE2_NOTBOL|PCRE2_NOTEOL;
- goto FRAGMENT_RESTART;
- }
- }
- }
- }
-#endif /* SUPPORT_UNICODE */
-
-/* Fill in fields that are always returned in the match data. */
-
-match_data->code = re;
-match_data->mark = mb->mark;
-match_data->matchedby = PCRE2_MATCHEDBY_INTERPRETER;
-
-/* Handle a fully successful match. Set the return code to the number of
-captured strings, or 0 if there were too many to fit into the ovector, and then
-set the remaining returned values before returning. Make a copy of the subject
-string if requested. */
-
-if (rc == MATCH_MATCH)
- {
- match_data->rc = ((int)mb->end_offset_top >= 2 * match_data->oveccount)?
- 0 : (int)mb->end_offset_top/2 + 1;
- match_data->startchar = start_match - subject;
- match_data->leftchar = mb->start_used_ptr - subject;
- match_data->rightchar = ((mb->last_used_ptr > mb->end_match_ptr)?
- mb->last_used_ptr : mb->end_match_ptr) - subject;
- if ((options & PCRE2_COPY_MATCHED_SUBJECT) != 0)
- {
- length = CU2BYTES(length + was_zero_terminated);
- match_data->subject = match_data->memctl.malloc(length,
- match_data->memctl.memory_data);
- if (match_data->subject == NULL) return PCRE2_ERROR_NOMEMORY;
- memcpy((void *)match_data->subject, subject, length);
- match_data->flags |= PCRE2_MD_COPIED_SUBJECT;
- }
- else match_data->subject = subject;
- return match_data->rc;
- }
-
-/* Control gets here if there has been a partial match, an error, or if the
-overall match attempt has failed at all permitted starting positions. Any mark
-data is in the nomatch_mark field. */
-
-match_data->mark = mb->nomatch_mark;
-
-/* For anything other than nomatch or partial match, just return the code. */
-
-if (rc != MATCH_NOMATCH && rc != PCRE2_ERROR_PARTIAL) match_data->rc = rc;
-
-/* Handle a partial match. If a "soft" partial match was requested, searching
-for a complete match will have continued, and the value of rc at this point
-will be MATCH_NOMATCH. For a "hard" partial match, it will already be
-PCRE2_ERROR_PARTIAL. */
-
-else if (match_partial != NULL)
- {
- match_data->subject = subject;
- match_data->ovector[0] = match_partial - subject;
- match_data->ovector[1] = end_subject - subject;
- match_data->startchar = match_partial - subject;
- match_data->leftchar = start_partial - subject;
- match_data->rightchar = end_subject - subject;
- match_data->rc = PCRE2_ERROR_PARTIAL;
- }
-
-/* Else this is the classic nomatch case. */
-
-else match_data->rc = PCRE2_ERROR_NOMATCH;
-
-return match_data->rc;
-}
-
-/* These #undefs are here to enable unity builds with CMake. */
-
-#undef NLBLOCK /* Block containing newline information */
-#undef PSSTART /* Field containing processed string start */
-#undef PSEND /* Field containing processed string end */
-
-/* End of pcre2_match.c */
diff --git a/contrib/libs/pcre2/src/pcre2_match_data.c b/contrib/libs/pcre2/src/pcre2_match_data.c
deleted file mode 100644
index 1b66359620..0000000000
--- a/contrib/libs/pcre2/src/pcre2_match_data.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2022 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-#include "pcre2_internal.h"
-
-
-
-/*************************************************
-* Create a match data block given ovector size *
-*************************************************/
-
-/* A minimum of 1 is imposed on the number of ovector pairs. A maximum is also
-imposed because the oveccount field in a match data block is uintt6_t. */
-
-PCRE2_EXP_DEFN pcre2_match_data * PCRE2_CALL_CONVENTION
-pcre2_match_data_create(uint32_t oveccount, pcre2_general_context *gcontext)
-{
-pcre2_match_data *yield;
-if (oveccount < 1) oveccount = 1;
-if (oveccount > UINT16_MAX) oveccount = UINT16_MAX;
-yield = PRIV(memctl_malloc)(
- offsetof(pcre2_match_data, ovector) + 2*oveccount*sizeof(PCRE2_SIZE),
- (pcre2_memctl *)gcontext);
-if (yield == NULL) return NULL;
-yield->oveccount = oveccount;
-yield->flags = 0;
-yield->heapframes = NULL;
-yield->heapframes_size = 0;
-return yield;
-}
-
-
-
-/*************************************************
-* Create a match data block using pattern data *
-*************************************************/
-
-/* If no context is supplied, use the memory allocator from the code. */
-
-PCRE2_EXP_DEFN pcre2_match_data * PCRE2_CALL_CONVENTION
-pcre2_match_data_create_from_pattern(const pcre2_code *code,
- pcre2_general_context *gcontext)
-{
-if (gcontext == NULL) gcontext = (pcre2_general_context *)code;
-return pcre2_match_data_create(((pcre2_real_code *)code)->top_bracket + 1,
- gcontext);
-}
-
-
-
-/*************************************************
-* Free a match data block *
-*************************************************/
-
-PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
-pcre2_match_data_free(pcre2_match_data *match_data)
-{
-if (match_data != NULL)
- {
- if (match_data->heapframes != NULL)
- match_data->memctl.free(match_data->heapframes,
- match_data->memctl.memory_data);
- if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0)
- match_data->memctl.free((void *)match_data->subject,
- match_data->memctl.memory_data);
- match_data->memctl.free(match_data, match_data->memctl.memory_data);
- }
-}
-
-
-
-/*************************************************
-* Get last mark in match *
-*************************************************/
-
-PCRE2_EXP_DEFN PCRE2_SPTR PCRE2_CALL_CONVENTION
-pcre2_get_mark(pcre2_match_data *match_data)
-{
-return match_data->mark;
-}
-
-
-
-/*************************************************
-* Get pointer to ovector *
-*************************************************/
-
-PCRE2_EXP_DEFN PCRE2_SIZE * PCRE2_CALL_CONVENTION
-pcre2_get_ovector_pointer(pcre2_match_data *match_data)
-{
-return match_data->ovector;
-}
-
-
-
-/*************************************************
-* Get number of ovector slots *
-*************************************************/
-
-PCRE2_EXP_DEFN uint32_t PCRE2_CALL_CONVENTION
-pcre2_get_ovector_count(pcre2_match_data *match_data)
-{
-return match_data->oveccount;
-}
-
-
-
-/*************************************************
-* Get starting code unit in match *
-*************************************************/
-
-PCRE2_EXP_DEFN PCRE2_SIZE PCRE2_CALL_CONVENTION
-pcre2_get_startchar(pcre2_match_data *match_data)
-{
-return match_data->startchar;
-}
-
-
-
-/*************************************************
-* Get size of match data block *
-*************************************************/
-
-PCRE2_EXP_DEFN PCRE2_SIZE PCRE2_CALL_CONVENTION
-pcre2_get_match_data_size(pcre2_match_data *match_data)
-{
-return offsetof(pcre2_match_data, ovector) +
- 2 * (match_data->oveccount) * sizeof(PCRE2_SIZE);
-}
-
-/* End of pcre2_match_data.c */
diff --git a/contrib/libs/pcre2/src/pcre2_newline.c b/contrib/libs/pcre2/src/pcre2_newline.c
deleted file mode 100644
index ae830b38df..0000000000
--- a/contrib/libs/pcre2/src/pcre2_newline.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains internal functions for testing newlines when more than
-one kind of newline is to be recognized. When a newline is found, its length is
-returned. In principle, we could implement several newline "types", each
-referring to a different set of newline characters. At present, PCRE2 supports
-only NLTYPE_FIXED, which gets handled without these functions, NLTYPE_ANYCRLF,
-and NLTYPE_ANY. The full list of Unicode newline characters is taken from
-http://unicode.org/unicode/reports/tr18/. */
-
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-#include "pcre2_internal.h"
-
-
-
-/*************************************************
-* Check for newline at given position *
-*************************************************/
-
-/* This function is called only via the IS_NEWLINE macro, which does so only
-when the newline type is NLTYPE_ANY or NLTYPE_ANYCRLF. The case of a fixed
-newline (NLTYPE_FIXED) is handled inline. It is guaranteed that the code unit
-pointed to by ptr is less than the end of the string.
-
-Arguments:
- ptr pointer to possible newline
- type the newline type
- endptr pointer to the end of the string
- lenptr where to return the length
- utf TRUE if in utf mode
-
-Returns: TRUE or FALSE
-*/
-
-BOOL
-PRIV(is_newline)(PCRE2_SPTR ptr, uint32_t type, PCRE2_SPTR endptr,
- uint32_t *lenptr, BOOL utf)
-{
-uint32_t c;
-
-#ifdef SUPPORT_UNICODE
-if (utf) { GETCHAR(c, ptr); } else c = *ptr;
-#else
-(void)utf;
-c = *ptr;
-#endif /* SUPPORT_UNICODE */
-
-if (type == NLTYPE_ANYCRLF) switch(c)
- {
- case CHAR_LF:
- *lenptr = 1;
- return TRUE;
-
- case CHAR_CR:
- *lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1;
- return TRUE;
-
- default:
- return FALSE;
- }
-
-/* NLTYPE_ANY */
-
-else switch(c)
- {
-#ifdef EBCDIC
- case CHAR_NEL:
-#endif
- case CHAR_LF:
- case CHAR_VT:
- case CHAR_FF:
- *lenptr = 1;
- return TRUE;
-
- case CHAR_CR:
- *lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1;
- return TRUE;
-
-#ifndef EBCDIC
-#if PCRE2_CODE_UNIT_WIDTH == 8
- case CHAR_NEL:
- *lenptr = utf? 2 : 1;
- return TRUE;
-
- case 0x2028: /* LS */
- case 0x2029: /* PS */
- *lenptr = 3;
- return TRUE;
-
-#else /* 16-bit or 32-bit code units */
- case CHAR_NEL:
- case 0x2028: /* LS */
- case 0x2029: /* PS */
- *lenptr = 1;
- return TRUE;
-#endif
-#endif /* Not EBCDIC */
-
- default:
- return FALSE;
- }
-}
-
-
-
-/*************************************************
-* Check for newline at previous position *
-*************************************************/
-
-/* This function is called only via the WAS_NEWLINE macro, which does so only
-when the newline type is NLTYPE_ANY or NLTYPE_ANYCRLF. The case of a fixed
-newline (NLTYPE_FIXED) is handled inline. It is guaranteed that the initial
-value of ptr is greater than the start of the string that is being processed.
-
-Arguments:
- ptr pointer to possible newline
- type the newline type
- startptr pointer to the start of the string
- lenptr where to return the length
- utf TRUE if in utf mode
-
-Returns: TRUE or FALSE
-*/
-
-BOOL
-PRIV(was_newline)(PCRE2_SPTR ptr, uint32_t type, PCRE2_SPTR startptr,
- uint32_t *lenptr, BOOL utf)
-{
-uint32_t c;
-ptr--;
-
-#ifdef SUPPORT_UNICODE
-if (utf)
- {
- BACKCHAR(ptr);
- GETCHAR(c, ptr);
- }
-else c = *ptr;
-#else
-(void)utf;
-c = *ptr;
-#endif /* SUPPORT_UNICODE */
-
-if (type == NLTYPE_ANYCRLF) switch(c)
- {
- case CHAR_LF:
- *lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1;
- return TRUE;
-
- case CHAR_CR:
- *lenptr = 1;
- return TRUE;
-
- default:
- return FALSE;
- }
-
-/* NLTYPE_ANY */
-
-else switch(c)
- {
- case CHAR_LF:
- *lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1;
- return TRUE;
-
-#ifdef EBCDIC
- case CHAR_NEL:
-#endif
- case CHAR_VT:
- case CHAR_FF:
- case CHAR_CR:
- *lenptr = 1;
- return TRUE;
-
-#ifndef EBCDIC
-#if PCRE2_CODE_UNIT_WIDTH == 8
- case CHAR_NEL:
- *lenptr = utf? 2 : 1;
- return TRUE;
-
- case 0x2028: /* LS */
- case 0x2029: /* PS */
- *lenptr = 3;
- return TRUE;
-
-#else /* 16-bit or 32-bit code units */
- case CHAR_NEL:
- case 0x2028: /* LS */
- case 0x2029: /* PS */
- *lenptr = 1;
- return TRUE;
-#endif
-#endif /* Not EBCDIC */
-
- default:
- return FALSE;
- }
-}
-
-/* End of pcre2_newline.c */
diff --git a/contrib/libs/pcre2/src/pcre2_ord2utf.c b/contrib/libs/pcre2/src/pcre2_ord2utf.c
deleted file mode 100644
index c2cf6e9856..0000000000
--- a/contrib/libs/pcre2/src/pcre2_ord2utf.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This file contains a function that converts a Unicode character code point
-into a UTF string. The behaviour is different for each code unit width. */
-
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-#include "pcre2_internal.h"
-
-
-/* If SUPPORT_UNICODE is not defined, this function will never be called.
-Supply a dummy function because some compilers do not like empty source
-modules. */
-
-#ifndef SUPPORT_UNICODE
-unsigned int
-PRIV(ord2utf)(uint32_t cvalue, PCRE2_UCHAR *buffer)
-{
-(void)(cvalue);
-(void)(buffer);
-return 0;
-}
-#else /* SUPPORT_UNICODE */
-
-
-/*************************************************
-* Convert code point to UTF *
-*************************************************/
-
-/*
-Arguments:
- cvalue the character value
- buffer pointer to buffer for result
-
-Returns: number of code units placed in the buffer
-*/
-
-unsigned int
-PRIV(ord2utf)(uint32_t cvalue, PCRE2_UCHAR *buffer)
-{
-/* Convert to UTF-8 */
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
-int i, j;
-for (i = 0; i < PRIV(utf8_table1_size); i++)
- if ((int)cvalue <= PRIV(utf8_table1)[i]) break;
-buffer += i;
-for (j = i; j > 0; j--)
- {
- *buffer-- = 0x80 | (cvalue & 0x3f);
- cvalue >>= 6;
- }
-*buffer = PRIV(utf8_table2)[i] | cvalue;
-return i + 1;
-
-/* Convert to UTF-16 */
-
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-if (cvalue <= 0xffff)
- {
- *buffer = (PCRE2_UCHAR)cvalue;
- return 1;
- }
-cvalue -= 0x10000;
-*buffer++ = 0xd800 | (cvalue >> 10);
-*buffer = 0xdc00 | (cvalue & 0x3ff);
-return 2;
-
-/* Convert to UTF-32 */
-
-#else
-*buffer = (PCRE2_UCHAR)cvalue;
-return 1;
-#endif
-}
-#endif /* SUPPORT_UNICODE */
-
-/* End of pcre_ord2utf.c */
diff --git a/contrib/libs/pcre2/src/pcre2_pattern_info.c b/contrib/libs/pcre2/src/pcre2_pattern_info.c
deleted file mode 100644
index 6d3ad3c1ec..0000000000
--- a/contrib/libs/pcre2/src/pcre2_pattern_info.c
+++ /dev/null
@@ -1,432 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2018 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-#include "pcre2_internal.h"
-
-
-/*************************************************
-* Return info about compiled pattern *
-*************************************************/
-
-/*
-Arguments:
- code points to compiled code
- what what information is required
- where where to put the information; if NULL, return length
-
-Returns: 0 when data returned
- > 0 when length requested
- < 0 on error or unset value
-*/
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_pattern_info(const pcre2_code *code, uint32_t what, void *where)
-{
-const pcre2_real_code *re = (pcre2_real_code *)code;
-
-if (where == NULL) /* Requests field length */
- {
- switch(what)
- {
- case PCRE2_INFO_ALLOPTIONS:
- case PCRE2_INFO_ARGOPTIONS:
- case PCRE2_INFO_BACKREFMAX:
- case PCRE2_INFO_BSR:
- case PCRE2_INFO_CAPTURECOUNT:
- case PCRE2_INFO_DEPTHLIMIT:
- case PCRE2_INFO_EXTRAOPTIONS:
- case PCRE2_INFO_FIRSTCODETYPE:
- case PCRE2_INFO_FIRSTCODEUNIT:
- case PCRE2_INFO_HASBACKSLASHC:
- case PCRE2_INFO_HASCRORLF:
- case PCRE2_INFO_HEAPLIMIT:
- case PCRE2_INFO_JCHANGED:
- case PCRE2_INFO_LASTCODETYPE:
- case PCRE2_INFO_LASTCODEUNIT:
- case PCRE2_INFO_MATCHEMPTY:
- case PCRE2_INFO_MATCHLIMIT:
- case PCRE2_INFO_MAXLOOKBEHIND:
- case PCRE2_INFO_MINLENGTH:
- case PCRE2_INFO_NAMEENTRYSIZE:
- case PCRE2_INFO_NAMECOUNT:
- case PCRE2_INFO_NEWLINE:
- return sizeof(uint32_t);
-
- case PCRE2_INFO_FIRSTBITMAP:
- return sizeof(const uint8_t *);
-
- case PCRE2_INFO_JITSIZE:
- case PCRE2_INFO_SIZE:
- case PCRE2_INFO_FRAMESIZE:
- return sizeof(size_t);
-
- case PCRE2_INFO_NAMETABLE:
- return sizeof(PCRE2_SPTR);
- }
- }
-
-if (re == NULL) return PCRE2_ERROR_NULL;
-
-/* Check that the first field in the block is the magic number. If it is not,
-return with PCRE2_ERROR_BADMAGIC. */
-
-if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;
-
-/* Check that this pattern was compiled in the correct bit mode */
-
-if ((re->flags & (PCRE2_CODE_UNIT_WIDTH/8)) == 0) return PCRE2_ERROR_BADMODE;
-
-switch(what)
- {
- case PCRE2_INFO_ALLOPTIONS:
- *((uint32_t *)where) = re->overall_options;
- break;
-
- case PCRE2_INFO_ARGOPTIONS:
- *((uint32_t *)where) = re->compile_options;
- break;
-
- case PCRE2_INFO_BACKREFMAX:
- *((uint32_t *)where) = re->top_backref;
- break;
-
- case PCRE2_INFO_BSR:
- *((uint32_t *)where) = re->bsr_convention;
- break;
-
- case PCRE2_INFO_CAPTURECOUNT:
- *((uint32_t *)where) = re->top_bracket;
- break;
-
- case PCRE2_INFO_DEPTHLIMIT:
- *((uint32_t *)where) = re->limit_depth;
- if (re->limit_depth == UINT32_MAX) return PCRE2_ERROR_UNSET;
- break;
-
- case PCRE2_INFO_EXTRAOPTIONS:
- *((uint32_t *)where) = re->extra_options;
- break;
-
- case PCRE2_INFO_FIRSTCODETYPE:
- *((uint32_t *)where) = ((re->flags & PCRE2_FIRSTSET) != 0)? 1 :
- ((re->flags & PCRE2_STARTLINE) != 0)? 2 : 0;
- break;
-
- case PCRE2_INFO_FIRSTCODEUNIT:
- *((uint32_t *)where) = ((re->flags & PCRE2_FIRSTSET) != 0)?
- re->first_codeunit : 0;
- break;
-
- case PCRE2_INFO_FIRSTBITMAP:
- *((const uint8_t **)where) = ((re->flags & PCRE2_FIRSTMAPSET) != 0)?
- &(re->start_bitmap[0]) : NULL;
- break;
-
- case PCRE2_INFO_FRAMESIZE:
- *((size_t *)where) = offsetof(heapframe, ovector) +
- re->top_bracket * 2 * sizeof(PCRE2_SIZE);
- break;
-
- case PCRE2_INFO_HASBACKSLASHC:
- *((uint32_t *)where) = (re->flags & PCRE2_HASBKC) != 0;
- break;
-
- case PCRE2_INFO_HASCRORLF:
- *((uint32_t *)where) = (re->flags & PCRE2_HASCRORLF) != 0;
- break;
-
- case PCRE2_INFO_HEAPLIMIT:
- *((uint32_t *)where) = re->limit_heap;
- if (re->limit_heap == UINT32_MAX) return PCRE2_ERROR_UNSET;
- break;
-
- case PCRE2_INFO_JCHANGED:
- *((uint32_t *)where) = (re->flags & PCRE2_JCHANGED) != 0;
- break;
-
- case PCRE2_INFO_JITSIZE:
-#ifdef SUPPORT_JIT
- *((size_t *)where) = (re->executable_jit != NULL)?
- PRIV(jit_get_size)(re->executable_jit) : 0;
-#else
- *((size_t *)where) = 0;
-#endif
- break;
-
- case PCRE2_INFO_LASTCODETYPE:
- *((uint32_t *)where) = ((re->flags & PCRE2_LASTSET) != 0)? 1 : 0;
- break;
-
- case PCRE2_INFO_LASTCODEUNIT:
- *((uint32_t *)where) = ((re->flags & PCRE2_LASTSET) != 0)?
- re->last_codeunit : 0;
- break;
-
- case PCRE2_INFO_MATCHEMPTY:
- *((uint32_t *)where) = (re->flags & PCRE2_MATCH_EMPTY) != 0;
- break;
-
- case PCRE2_INFO_MATCHLIMIT:
- *((uint32_t *)where) = re->limit_match;
- if (re->limit_match == UINT32_MAX) return PCRE2_ERROR_UNSET;
- break;
-
- case PCRE2_INFO_MAXLOOKBEHIND:
- *((uint32_t *)where) = re->max_lookbehind;
- break;
-
- case PCRE2_INFO_MINLENGTH:
- *((uint32_t *)where) = re->minlength;
- break;
-
- case PCRE2_INFO_NAMEENTRYSIZE:
- *((uint32_t *)where) = re->name_entry_size;
- break;
-
- case PCRE2_INFO_NAMECOUNT:
- *((uint32_t *)where) = re->name_count;
- break;
-
- case PCRE2_INFO_NAMETABLE:
- *((PCRE2_SPTR *)where) = (PCRE2_SPTR)((char *)re + sizeof(pcre2_real_code));
- break;
-
- case PCRE2_INFO_NEWLINE:
- *((uint32_t *)where) = re->newline_convention;
- break;
-
- case PCRE2_INFO_SIZE:
- *((size_t *)where) = re->blocksize;
- break;
-
- default: return PCRE2_ERROR_BADOPTION;
- }
-
-return 0;
-}
-
-
-
-/*************************************************
-* Callout enumerator *
-*************************************************/
-
-/*
-Arguments:
- code points to compiled code
- callback function called for each callout block
- callout_data user data passed to the callback
-
-Returns: 0 when successfully completed
- < 0 on local error
- != 0 for callback error
-*/
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_callout_enumerate(const pcre2_code *code,
- int (*callback)(pcre2_callout_enumerate_block *, void *), void *callout_data)
-{
-pcre2_real_code *re = (pcre2_real_code *)code;
-pcre2_callout_enumerate_block cb;
-PCRE2_SPTR cc;
-#ifdef SUPPORT_UNICODE
-BOOL utf;
-#endif
-
-if (re == NULL) return PCRE2_ERROR_NULL;
-
-#ifdef SUPPORT_UNICODE
-utf = (re->overall_options & PCRE2_UTF) != 0;
-#endif
-
-/* Check that the first field in the block is the magic number. If it is not,
-return with PCRE2_ERROR_BADMAGIC. */
-
-if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;
-
-/* Check that this pattern was compiled in the correct bit mode */
-
-if ((re->flags & (PCRE2_CODE_UNIT_WIDTH/8)) == 0) return PCRE2_ERROR_BADMODE;
-
-cb.version = 0;
-cc = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code))
- + re->name_count * re->name_entry_size;
-
-while (TRUE)
- {
- int rc;
- switch (*cc)
- {
- case OP_END:
- return 0;
-
- case OP_CHAR:
- case OP_CHARI:
- case OP_NOT:
- case OP_NOTI:
- case OP_STAR:
- case OP_MINSTAR:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_EXACT:
- case OP_POSSTAR:
- case OP_POSPLUS:
- case OP_POSQUERY:
- case OP_POSUPTO:
- case OP_STARI:
- case OP_MINSTARI:
- case OP_PLUSI:
- case OP_MINPLUSI:
- case OP_QUERYI:
- case OP_MINQUERYI:
- case OP_UPTOI:
- case OP_MINUPTOI:
- case OP_EXACTI:
- case OP_POSSTARI:
- case OP_POSPLUSI:
- case OP_POSQUERYI:
- case OP_POSUPTOI:
- case OP_NOTSTAR:
- case OP_NOTMINSTAR:
- case OP_NOTPLUS:
- case OP_NOTMINPLUS:
- case OP_NOTQUERY:
- case OP_NOTMINQUERY:
- case OP_NOTUPTO:
- case OP_NOTMINUPTO:
- case OP_NOTEXACT:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSPLUS:
- case OP_NOTPOSQUERY:
- case OP_NOTPOSUPTO:
- case OP_NOTSTARI:
- case OP_NOTMINSTARI:
- case OP_NOTPLUSI:
- case OP_NOTMINPLUSI:
- case OP_NOTQUERYI:
- case OP_NOTMINQUERYI:
- case OP_NOTUPTOI:
- case OP_NOTMINUPTOI:
- case OP_NOTEXACTI:
- case OP_NOTPOSSTARI:
- case OP_NOTPOSPLUSI:
- case OP_NOTPOSQUERYI:
- case OP_NOTPOSUPTOI:
- cc += PRIV(OP_lengths)[*cc];
-#ifdef SUPPORT_UNICODE
- if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- break;
-
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEEXACT:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSPLUS:
- case OP_TYPEPOSQUERY:
- case OP_TYPEPOSUPTO:
- cc += PRIV(OP_lengths)[*cc];
-#ifdef SUPPORT_UNICODE
- if (cc[-1] == OP_PROP || cc[-1] == OP_NOTPROP) cc += 2;
-#endif
- break;
-
-#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
- case OP_XCLASS:
- cc += GET(cc, 1);
- break;
-#endif
-
- case OP_MARK:
- case OP_COMMIT_ARG:
- case OP_PRUNE_ARG:
- case OP_SKIP_ARG:
- case OP_THEN_ARG:
- cc += PRIV(OP_lengths)[*cc] + cc[1];
- break;
-
- case OP_CALLOUT:
- cb.pattern_position = GET(cc, 1);
- cb.next_item_length = GET(cc, 1 + LINK_SIZE);
- cb.callout_number = cc[1 + 2*LINK_SIZE];
- cb.callout_string_offset = 0;
- cb.callout_string_length = 0;
- cb.callout_string = NULL;
- rc = callback(&cb, callout_data);
- if (rc != 0) return rc;
- cc += PRIV(OP_lengths)[*cc];
- break;
-
- case OP_CALLOUT_STR:
- cb.pattern_position = GET(cc, 1);
- cb.next_item_length = GET(cc, 1 + LINK_SIZE);
- cb.callout_number = 0;
- cb.callout_string_offset = GET(cc, 1 + 3*LINK_SIZE);
- cb.callout_string_length =
- GET(cc, 1 + 2*LINK_SIZE) - (1 + 4*LINK_SIZE) - 2;
- cb.callout_string = cc + (1 + 4*LINK_SIZE) + 1;
- rc = callback(&cb, callout_data);
- if (rc != 0) return rc;
- cc += GET(cc, 1 + 2*LINK_SIZE);
- break;
-
- default:
- cc += PRIV(OP_lengths)[*cc];
- break;
- }
- }
-}
-
-/* End of pcre2_pattern_info.c */
diff --git a/contrib/libs/pcre2/src/pcre2_script_run.c b/contrib/libs/pcre2/src/pcre2_script_run.c
deleted file mode 100644
index 1ac2985b49..0000000000
--- a/contrib/libs/pcre2/src/pcre2_script_run.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2021 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-/* This module contains the function for checking a script run. */
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-#include "pcre2_internal.h"
-
-
-/*************************************************
-* Check script run *
-*************************************************/
-
-/* A script run is conceptually a sequence of characters all in the same
-Unicode script. However, it isn't quite that simple. There are special rules
-for scripts that are commonly used together, and also special rules for digits.
-This function implements the appropriate checks, which is possible only when
-PCRE2 is compiled with Unicode support. The function returns TRUE if there is
-no Unicode support; however, it should never be called in that circumstance
-because an error is given by pcre2_compile() if a script run is called for in a
-version of PCRE2 compiled without Unicode support.
-
-Arguments:
- pgr point to the first character
- endptr point after the last character
- utf TRUE if in UTF mode
-
-Returns: TRUE if this is a valid script run
-*/
-
-/* These are states in the checking process. */
-
-enum { SCRIPT_UNSET, /* Requirement as yet unknown */
- SCRIPT_MAP, /* Bitmap contains acceptable scripts */
- SCRIPT_HANPENDING, /* Have had only Han characters */
- SCRIPT_HANHIRAKATA, /* Expect Han or Hirikata */
- SCRIPT_HANBOPOMOFO, /* Expect Han or Bopomofo */
- SCRIPT_HANHANGUL /* Expect Han or Hangul */
- };
-
-#define UCD_MAPSIZE (ucp_Unknown/32 + 1)
-#define FULL_MAPSIZE (ucp_Script_Count/32 + 1)
-
-BOOL
-PRIV(script_run)(PCRE2_SPTR ptr, PCRE2_SPTR endptr, BOOL utf)
-{
-#ifdef SUPPORT_UNICODE
-uint32_t require_state = SCRIPT_UNSET;
-uint32_t require_map[FULL_MAPSIZE];
-uint32_t map[FULL_MAPSIZE];
-uint32_t require_digitset = 0;
-uint32_t c;
-
-#if PCRE2_CODE_UNIT_WIDTH == 32
-(void)utf; /* Avoid compiler warning */
-#endif
-
-/* Any string containing fewer than 2 characters is a valid script run. */
-
-if (ptr >= endptr) return TRUE;
-GETCHARINCTEST(c, ptr);
-if (ptr >= endptr) return TRUE;
-
-/* Initialize the require map. This is a full-size bitmap that has a bit for
-every script, as opposed to the maps in ucd_script_sets, which only have bits
-for scripts less than ucp_Unknown - those that appear in script extension
-lists. */
-
-for (int i = 0; i < FULL_MAPSIZE; i++) require_map[i] = 0;
-
-/* Scan strings of two or more characters, checking the Unicode characteristics
-of each code point. There is special code for scripts that can be combined with
-characters from the Han Chinese script. This may be used in conjunction with
-four other scripts in these combinations:
-
-. Han with Hiragana and Katakana is allowed (for Japanese).
-. Han with Bopomofo is allowed (for Taiwanese Mandarin).
-. Han with Hangul is allowed (for Korean).
-
-If the first significant character's script is one of the four, the required
-script type is immediately known. However, if the first significant
-character's script is Han, we have to keep checking for a non-Han character.
-Hence the SCRIPT_HANPENDING state. */
-
-for (;;)
- {
- const ucd_record *ucd = GET_UCD(c);
- uint32_t script = ucd->script;
-
- /* If the script is Unknown, the string is not a valid script run. Such
- characters can only form script runs of length one (see test above). */
-
- if (script == ucp_Unknown) return FALSE;
-
- /* A character without any script extensions whose script is Inherited or
- Common is always accepted with any script. If there are extensions, the
- following processing happens for all scripts. */
-
- if (UCD_SCRIPTX_PROP(ucd) != 0 || (script != ucp_Inherited && script != ucp_Common))
- {
- BOOL OK;
-
- /* Set up a full-sized map for this character that can include bits for all
- scripts. Copy the scriptx map for this character (which covers those
- scripts that appear in script extension lists), set the remaining values to
- zero, and then, except for Common or Inherited, add this script's bit to
- the map. */
-
- memcpy(map, PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(ucd), UCD_MAPSIZE * sizeof(uint32_t));
- memset(map + UCD_MAPSIZE, 0, (FULL_MAPSIZE - UCD_MAPSIZE) * sizeof(uint32_t));
- if (script != ucp_Common && script != ucp_Inherited) MAPSET(map, script);
-
- /* Handle the different checking states */
-
- switch(require_state)
- {
- /* First significant character - it might follow Common or Inherited
- characters that do not have any script extensions. */
-
- case SCRIPT_UNSET:
- switch(script)
- {
- case ucp_Han:
- require_state = SCRIPT_HANPENDING;
- break;
-
- case ucp_Hiragana:
- case ucp_Katakana:
- require_state = SCRIPT_HANHIRAKATA;
- break;
-
- case ucp_Bopomofo:
- require_state = SCRIPT_HANBOPOMOFO;
- break;
-
- case ucp_Hangul:
- require_state = SCRIPT_HANHANGUL;
- break;
-
- default:
- memcpy(require_map, map, FULL_MAPSIZE * sizeof(uint32_t));
- require_state = SCRIPT_MAP;
- break;
- }
- break;
-
- /* The first significant character was Han. An inspection of the Unicode
- 11.0.0 files shows that there are the following types of Script Extension
- list that involve the Han, Bopomofo, Hiragana, Katakana, and Hangul
- scripts:
-
- . Bopomofo + Han
- . Han + Hiragana + Katakana
- . Hiragana + Katakana
- . Bopopmofo + Hangul + Han + Hiragana + Katakana
-
- The following code tries to make sense of this. */
-
-#define FOUND_BOPOMOFO 1
-#define FOUND_HIRAGANA 2
-#define FOUND_KATAKANA 4
-#define FOUND_HANGUL 8
-
- case SCRIPT_HANPENDING:
- if (script != ucp_Han) /* Another Han does nothing */
- {
- uint32_t chspecial = 0;
-
- if (MAPBIT(map, ucp_Bopomofo) != 0) chspecial |= FOUND_BOPOMOFO;
- if (MAPBIT(map, ucp_Hiragana) != 0) chspecial |= FOUND_HIRAGANA;
- if (MAPBIT(map, ucp_Katakana) != 0) chspecial |= FOUND_KATAKANA;
- if (MAPBIT(map, ucp_Hangul) != 0) chspecial |= FOUND_HANGUL;
-
- if (chspecial == 0) return FALSE; /* Not allowed with Han */
-
- if (chspecial == FOUND_BOPOMOFO)
- require_state = SCRIPT_HANBOPOMOFO;
- else if (chspecial == (FOUND_HIRAGANA|FOUND_KATAKANA))
- require_state = SCRIPT_HANHIRAKATA;
-
- /* Otherwise this character must be allowed with all of them, so remain
- in the pending state. */
- }
- break;
-
- /* Previously encountered one of the "with Han" scripts. Check that
- this character is appropriate. */
-
- case SCRIPT_HANHIRAKATA:
- if (MAPBIT(map, ucp_Han) + MAPBIT(map, ucp_Hiragana) +
- MAPBIT(map, ucp_Katakana) == 0) return FALSE;
- break;
-
- case SCRIPT_HANBOPOMOFO:
- if (MAPBIT(map, ucp_Han) + MAPBIT(map, ucp_Bopomofo) == 0) return FALSE;
- break;
-
- case SCRIPT_HANHANGUL:
- if (MAPBIT(map, ucp_Han) + MAPBIT(map, ucp_Hangul) == 0) return FALSE;
- break;
-
- /* Previously encountered one or more characters that are allowed with a
- list of scripts. */
-
- case SCRIPT_MAP:
- OK = FALSE;
-
- for (int i = 0; i < FULL_MAPSIZE; i++)
- {
- if ((require_map[i] & map[i]) != 0)
- {
- OK = TRUE;
- break;
- }
- }
-
- if (!OK) return FALSE;
-
- /* The rest of the string must be in this script, but we have to
- allow for the Han complications. */
-
- switch(script)
- {
- case ucp_Han:
- require_state = SCRIPT_HANPENDING;
- break;
-
- case ucp_Hiragana:
- case ucp_Katakana:
- require_state = SCRIPT_HANHIRAKATA;
- break;
-
- case ucp_Bopomofo:
- require_state = SCRIPT_HANBOPOMOFO;
- break;
-
- case ucp_Hangul:
- require_state = SCRIPT_HANHANGUL;
- break;
-
- /* Compute the intersection of the required list of scripts and the
- allowed scripts for this character. */
-
- default:
- for (int i = 0; i < FULL_MAPSIZE; i++) require_map[i] &= map[i];
- break;
- }
-
- break;
- }
- } /* End checking character's script and extensions. */
-
- /* The character is in an acceptable script. We must now ensure that all
- decimal digits in the string come from the same set. Some scripts (e.g.
- Common, Arabic) have more than one set of decimal digits. This code does
- not allow mixing sets, even within the same script. The vector called
- PRIV(ucd_digit_sets)[] contains, in its first element, the number of
- following elements, and then, in ascending order, the code points of the
- '9' characters in every set of 10 digits. Each set is identified by the
- offset in the vector of its '9' character. An initial check of the first
- value picks up ASCII digits quickly. Otherwise, a binary chop is used. */
-
- if (ucd->chartype == ucp_Nd)
- {
- uint32_t digitset;
-
- if (c <= PRIV(ucd_digit_sets)[1]) digitset = 1; else
- {
- int mid;
- int bot = 1;
- int top = PRIV(ucd_digit_sets)[0];
- for (;;)
- {
- if (top <= bot + 1) /* <= rather than == is paranoia */
- {
- digitset = top;
- break;
- }
- mid = (top + bot) / 2;
- if (c <= PRIV(ucd_digit_sets)[mid]) top = mid; else bot = mid;
- }
- }
-
- /* A required value of 0 means "unset". */
-
- if (require_digitset == 0) require_digitset = digitset;
- else if (digitset != require_digitset) return FALSE;
- } /* End digit handling */
-
- /* If we haven't yet got to the end, pick up the next character. */
-
- if (ptr >= endptr) return TRUE;
- GETCHARINCTEST(c, ptr);
- } /* End checking loop */
-
-#else /* NOT SUPPORT_UNICODE */
-(void)ptr;
-(void)endptr;
-(void)utf;
-return TRUE;
-#endif /* SUPPORT_UNICODE */
-}
-
-/* End of pcre2_script_run.c */
diff --git a/contrib/libs/pcre2/src/pcre2_serialize.c b/contrib/libs/pcre2/src/pcre2_serialize.c
deleted file mode 100644
index 6d5c44b038..0000000000
--- a/contrib/libs/pcre2/src/pcre2_serialize.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2020 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-/* This module contains functions for serializing and deserializing
-a sequence of compiled codes. */
-
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-
-#include "pcre2_internal.h"
-
-/* Magic number to provide a small check against being handed junk. */
-
-#define SERIALIZED_DATA_MAGIC 0x50523253u
-
-/* Deserialization is limited to the current PCRE version and
-character width. */
-
-#define SERIALIZED_DATA_VERSION \
- ((PCRE2_MAJOR) | ((PCRE2_MINOR) << 16))
-
-#define SERIALIZED_DATA_CONFIG \
- (sizeof(PCRE2_UCHAR) | ((sizeof(void*)) << 8) | ((sizeof(PCRE2_SIZE)) << 16))
-
-
-
-/*************************************************
-* Serialize compiled patterns *
-*************************************************/
-
-PCRE2_EXP_DEFN int32_t PCRE2_CALL_CONVENTION
-pcre2_serialize_encode(const pcre2_code **codes, int32_t number_of_codes,
- uint8_t **serialized_bytes, PCRE2_SIZE *serialized_size,
- pcre2_general_context *gcontext)
-{
-uint8_t *bytes;
-uint8_t *dst_bytes;
-int32_t i;
-PCRE2_SIZE total_size;
-const pcre2_real_code *re;
-const uint8_t *tables;
-pcre2_serialized_data *data;
-
-const pcre2_memctl *memctl = (gcontext != NULL) ?
- &gcontext->memctl : &PRIV(default_compile_context).memctl;
-
-if (codes == NULL || serialized_bytes == NULL || serialized_size == NULL)
- return PCRE2_ERROR_NULL;
-
-if (number_of_codes <= 0) return PCRE2_ERROR_BADDATA;
-
-/* Compute total size. */
-total_size = sizeof(pcre2_serialized_data) + TABLES_LENGTH;
-tables = NULL;
-
-for (i = 0; i < number_of_codes; i++)
- {
- if (codes[i] == NULL) return PCRE2_ERROR_NULL;
- re = (const pcre2_real_code *)(codes[i]);
- if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;
- if (tables == NULL)
- tables = re->tables;
- else if (tables != re->tables)
- return PCRE2_ERROR_MIXEDTABLES;
- total_size += re->blocksize;
- }
-
-/* Initialize the byte stream. */
-bytes = memctl->malloc(total_size + sizeof(pcre2_memctl), memctl->memory_data);
-if (bytes == NULL) return PCRE2_ERROR_NOMEMORY;
-
-/* The controller is stored as a hidden parameter. */
-memcpy(bytes, memctl, sizeof(pcre2_memctl));
-bytes += sizeof(pcre2_memctl);
-
-data = (pcre2_serialized_data *)bytes;
-data->magic = SERIALIZED_DATA_MAGIC;
-data->version = SERIALIZED_DATA_VERSION;
-data->config = SERIALIZED_DATA_CONFIG;
-data->number_of_codes = number_of_codes;
-
-/* Copy all compiled code data. */
-dst_bytes = bytes + sizeof(pcre2_serialized_data);
-memcpy(dst_bytes, tables, TABLES_LENGTH);
-dst_bytes += TABLES_LENGTH;
-
-for (i = 0; i < number_of_codes; i++)
- {
- re = (const pcre2_real_code *)(codes[i]);
- (void)memcpy(dst_bytes, (char *)re, re->blocksize);
-
- /* Certain fields in the compiled code block are re-set during
- deserialization. In order to ensure that the serialized data stream is always
- the same for the same pattern, set them to zero here. We can't assume the
- copy of the pattern is correctly aligned for accessing the fields as part of
- a structure. Note the use of sizeof(void *) in the second of these, to
- specify the size of a pointer. If sizeof(uint8_t *) is used (tables is a
- pointer to uint8_t), gcc gives a warning because the first argument is also a
- pointer to uint8_t. Casting the first argument to (void *) can stop this, but
- it didn't stop Coverity giving the same complaint. */
-
- (void)memset(dst_bytes + offsetof(pcre2_real_code, memctl), 0,
- sizeof(pcre2_memctl));
- (void)memset(dst_bytes + offsetof(pcre2_real_code, tables), 0,
- sizeof(void *));
- (void)memset(dst_bytes + offsetof(pcre2_real_code, executable_jit), 0,
- sizeof(void *));
-
- dst_bytes += re->blocksize;
- }
-
-*serialized_bytes = bytes;
-*serialized_size = total_size;
-return number_of_codes;
-}
-
-
-/*************************************************
-* Deserialize compiled patterns *
-*************************************************/
-
-PCRE2_EXP_DEFN int32_t PCRE2_CALL_CONVENTION
-pcre2_serialize_decode(pcre2_code **codes, int32_t number_of_codes,
- const uint8_t *bytes, pcre2_general_context *gcontext)
-{
-const pcre2_serialized_data *data = (const pcre2_serialized_data *)bytes;
-const pcre2_memctl *memctl = (gcontext != NULL) ?
- &gcontext->memctl : &PRIV(default_compile_context).memctl;
-
-const uint8_t *src_bytes;
-pcre2_real_code *dst_re;
-uint8_t *tables;
-int32_t i, j;
-
-/* Sanity checks. */
-
-if (data == NULL || codes == NULL) return PCRE2_ERROR_NULL;
-if (number_of_codes <= 0) return PCRE2_ERROR_BADDATA;
-if (data->number_of_codes <= 0) return PCRE2_ERROR_BADSERIALIZEDDATA;
-if (data->magic != SERIALIZED_DATA_MAGIC) return PCRE2_ERROR_BADMAGIC;
-if (data->version != SERIALIZED_DATA_VERSION) return PCRE2_ERROR_BADMODE;
-if (data->config != SERIALIZED_DATA_CONFIG) return PCRE2_ERROR_BADMODE;
-
-if (number_of_codes > data->number_of_codes)
- number_of_codes = data->number_of_codes;
-
-src_bytes = bytes + sizeof(pcre2_serialized_data);
-
-/* Decode tables. The reference count for the tables is stored immediately
-following them. */
-
-tables = memctl->malloc(TABLES_LENGTH + sizeof(PCRE2_SIZE), memctl->memory_data);
-if (tables == NULL) return PCRE2_ERROR_NOMEMORY;
-
-memcpy(tables, src_bytes, TABLES_LENGTH);
-*(PCRE2_SIZE *)(tables + TABLES_LENGTH) = number_of_codes;
-src_bytes += TABLES_LENGTH;
-
-/* Decode the byte stream. We must not try to read the size from the compiled
-code block in the stream, because it might be unaligned, which causes errors on
-hardware such as Sparc-64 that doesn't like unaligned memory accesses. The type
-of the blocksize field is given its own name to ensure that it is the same here
-as in the block. */
-
-for (i = 0; i < number_of_codes; i++)
- {
- CODE_BLOCKSIZE_TYPE blocksize;
- memcpy(&blocksize, src_bytes + offsetof(pcre2_real_code, blocksize),
- sizeof(CODE_BLOCKSIZE_TYPE));
- if (blocksize <= sizeof(pcre2_real_code))
- return PCRE2_ERROR_BADSERIALIZEDDATA;
-
- /* The allocator provided by gcontext replaces the original one. */
-
- dst_re = (pcre2_real_code *)PRIV(memctl_malloc)(blocksize,
- (pcre2_memctl *)gcontext);
- if (dst_re == NULL)
- {
- memctl->free(tables, memctl->memory_data);
- for (j = 0; j < i; j++)
- {
- memctl->free(codes[j], memctl->memory_data);
- codes[j] = NULL;
- }
- return PCRE2_ERROR_NOMEMORY;
- }
-
- /* The new allocator must be preserved. */
-
- memcpy(((uint8_t *)dst_re) + sizeof(pcre2_memctl),
- src_bytes + sizeof(pcre2_memctl), blocksize - sizeof(pcre2_memctl));
- if (dst_re->magic_number != MAGIC_NUMBER ||
- dst_re->name_entry_size > MAX_NAME_SIZE + IMM2_SIZE + 1 ||
- dst_re->name_count > MAX_NAME_COUNT)
- {
- memctl->free(dst_re, memctl->memory_data);
- return PCRE2_ERROR_BADSERIALIZEDDATA;
- }
-
- /* At the moment only one table is supported. */
-
- dst_re->tables = tables;
- dst_re->executable_jit = NULL;
- dst_re->flags |= PCRE2_DEREF_TABLES;
-
- codes[i] = dst_re;
- src_bytes += blocksize;
- }
-
-return number_of_codes;
-}
-
-
-/*************************************************
-* Get the number of serialized patterns *
-*************************************************/
-
-PCRE2_EXP_DEFN int32_t PCRE2_CALL_CONVENTION
-pcre2_serialize_get_number_of_codes(const uint8_t *bytes)
-{
-const pcre2_serialized_data *data = (const pcre2_serialized_data *)bytes;
-
-if (data == NULL) return PCRE2_ERROR_NULL;
-if (data->magic != SERIALIZED_DATA_MAGIC) return PCRE2_ERROR_BADMAGIC;
-if (data->version != SERIALIZED_DATA_VERSION) return PCRE2_ERROR_BADMODE;
-if (data->config != SERIALIZED_DATA_CONFIG) return PCRE2_ERROR_BADMODE;
-
-return data->number_of_codes;
-}
-
-
-/*************************************************
-* Free the allocated stream *
-*************************************************/
-
-PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
-pcre2_serialize_free(uint8_t *bytes)
-{
-if (bytes != NULL)
- {
- pcre2_memctl *memctl = (pcre2_memctl *)(bytes - sizeof(pcre2_memctl));
- memctl->free(memctl, memctl->memory_data);
- }
-}
-
-/* End of pcre2_serialize.c */
diff --git a/contrib/libs/pcre2/src/pcre2_string_utils.c b/contrib/libs/pcre2/src/pcre2_string_utils.c
deleted file mode 100644
index 3230919d51..0000000000
--- a/contrib/libs/pcre2/src/pcre2_string_utils.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2018-2021 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-/* This module contains internal functions for comparing and finding the length
-of strings. These are used instead of strcmp() etc because the standard
-functions work only on 8-bit data. */
-
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-#include "pcre2_internal.h"
-
-
-/*************************************************
-* Emulated memmove() for systems without it *
-*************************************************/
-
-/* This function can make use of bcopy() if it is available. Otherwise do it by
-steam, as there some non-Unix environments that lack both memmove() and
-bcopy(). */
-
-#if !defined(VPCOMPAT) && !defined(HAVE_MEMMOVE)
-void *
-PRIV(memmove)(void *d, const void *s, size_t n)
-{
-#ifdef HAVE_BCOPY
-bcopy(s, d, n);
-return d;
-#else
-size_t i;
-unsigned char *dest = (unsigned char *)d;
-const unsigned char *src = (const unsigned char *)s;
-if (dest > src)
- {
- dest += n;
- src += n;
- for (i = 0; i < n; ++i) *(--dest) = *(--src);
- return (void *)dest;
- }
-else
- {
- for (i = 0; i < n; ++i) *dest++ = *src++;
- return (void *)(dest - n);
- }
-#endif /* not HAVE_BCOPY */
-}
-#endif /* not VPCOMPAT && not HAVE_MEMMOVE */
-
-
-/*************************************************
-* Compare two zero-terminated PCRE2 strings *
-*************************************************/
-
-/*
-Arguments:
- str1 first string
- str2 second string
-
-Returns: 0, 1, or -1
-*/
-
-int
-PRIV(strcmp)(PCRE2_SPTR str1, PCRE2_SPTR str2)
-{
-PCRE2_UCHAR c1, c2;
-while (*str1 != '\0' || *str2 != '\0')
- {
- c1 = *str1++;
- c2 = *str2++;
- if (c1 != c2) return ((c1 > c2) << 1) - 1;
- }
-return 0;
-}
-
-
-/*************************************************
-* Compare zero-terminated PCRE2 & 8-bit strings *
-*************************************************/
-
-/* As the 8-bit string is almost always a literal, its type is specified as
-const char *.
-
-Arguments:
- str1 first string
- str2 second string
-
-Returns: 0, 1, or -1
-*/
-
-int
-PRIV(strcmp_c8)(PCRE2_SPTR str1, const char *str2)
-{
-PCRE2_UCHAR c1, c2;
-while (*str1 != '\0' || *str2 != '\0')
- {
- c1 = *str1++;
- c2 = *str2++;
- if (c1 != c2) return ((c1 > c2) << 1) - 1;
- }
-return 0;
-}
-
-
-/*************************************************
-* Compare two PCRE2 strings, given a length *
-*************************************************/
-
-/*
-Arguments:
- str1 first string
- str2 second string
- len the length
-
-Returns: 0, 1, or -1
-*/
-
-int
-PRIV(strncmp)(PCRE2_SPTR str1, PCRE2_SPTR str2, size_t len)
-{
-PCRE2_UCHAR c1, c2;
-for (; len > 0; len--)
- {
- c1 = *str1++;
- c2 = *str2++;
- if (c1 != c2) return ((c1 > c2) << 1) - 1;
- }
-return 0;
-}
-
-
-/*************************************************
-* Compare PCRE2 string to 8-bit string by length *
-*************************************************/
-
-/* As the 8-bit string is almost always a literal, its type is specified as
-const char *.
-
-Arguments:
- str1 first string
- str2 second string
- len the length
-
-Returns: 0, 1, or -1
-*/
-
-int
-PRIV(strncmp_c8)(PCRE2_SPTR str1, const char *str2, size_t len)
-{
-PCRE2_UCHAR c1, c2;
-for (; len > 0; len--)
- {
- c1 = *str1++;
- c2 = *str2++;
- if (c1 != c2) return ((c1 > c2) << 1) - 1;
- }
-return 0;
-}
-
-
-/*************************************************
-* Find the length of a PCRE2 string *
-*************************************************/
-
-/*
-Argument: the string
-Returns: the length
-*/
-
-PCRE2_SIZE
-PRIV(strlen)(PCRE2_SPTR str)
-{
-PCRE2_SIZE c = 0;
-while (*str++ != 0) c++;
-return c;
-}
-
-
-/*************************************************
-* Copy 8-bit 0-terminated string to PCRE2 string *
-*************************************************/
-
-/* Arguments:
- str1 buffer to receive the string
- str2 8-bit string to be copied
-
-Returns: the number of code units used (excluding trailing zero)
-*/
-
-PCRE2_SIZE
-PRIV(strcpy_c8)(PCRE2_UCHAR *str1, const char *str2)
-{
-PCRE2_UCHAR *t = str1;
-while (*str2 != 0) *t++ = *str2++;
-*t = 0;
-return t - str1;
-}
-
-/* End of pcre2_string_utils.c */
diff --git a/contrib/libs/pcre2/src/pcre2_study.c b/contrib/libs/pcre2/src/pcre2_study.c
deleted file mode 100644
index b259d246eb..0000000000
--- a/contrib/libs/pcre2/src/pcre2_study.c
+++ /dev/null
@@ -1,1825 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2021 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-/* This module contains functions for scanning a compiled pattern and
-collecting data (e.g. minimum matching length). */
-
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-#include "pcre2_internal.h"
-
-/* The maximum remembered capturing brackets minimum. */
-
-#define MAX_CACHE_BACKREF 128
-
-/* Set a bit in the starting code unit bit map. */
-
-#define SET_BIT(c) re->start_bitmap[(c)/8] |= (1u << ((c)&7))
-
-/* Returns from set_start_bits() */
-
-enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE, SSB_UNKNOWN, SSB_TOODEEP };
-
-
-/*************************************************
-* Find the minimum subject length for a group *
-*************************************************/
-
-/* Scan a parenthesized group and compute the minimum length of subject that
-is needed to match it. This is a lower bound; it does not mean there is a
-string of that length that matches. In UTF mode, the result is in characters
-rather than code units. The field in a compiled pattern for storing the minimum
-length is 16-bits long (on the grounds that anything longer than that is
-pathological), so we give up when we reach that amount. This also means that
-integer overflow for really crazy patterns cannot happen.
-
-Backreference minimum lengths are cached to speed up multiple references. This
-function is called only when the highest back reference in the pattern is less
-than or equal to MAX_CACHE_BACKREF, which is one less than the size of the
-caching vector. The zeroth element contains the number of the highest set
-value.
-
-Arguments:
- re compiled pattern block
- code pointer to start of group (the bracket)
- startcode pointer to start of the whole pattern's code
- utf UTF flag
- recurses chain of recurse_check to catch mutual recursion
- countptr pointer to call count (to catch over complexity)
- backref_cache vector for caching back references.
-
-This function is no longer called when the pattern contains (*ACCEPT); however,
-the old code for returning -1 is retained, just in case.
-
-Returns: the minimum length
- -1 \C in UTF-8 mode
- or (*ACCEPT)
- or pattern too complicated
- -2 internal error (missing capturing bracket)
- -3 internal error (opcode not listed)
-*/
-
-static int
-find_minlength(const pcre2_real_code *re, PCRE2_SPTR code,
- PCRE2_SPTR startcode, BOOL utf, recurse_check *recurses, int *countptr,
- int *backref_cache)
-{
-int length = -1;
-int branchlength = 0;
-int prev_cap_recno = -1;
-int prev_cap_d = 0;
-int prev_recurse_recno = -1;
-int prev_recurse_d = 0;
-uint32_t once_fudge = 0;
-BOOL had_recurse = FALSE;
-BOOL dupcapused = (re->flags & PCRE2_DUPCAPUSED) != 0;
-PCRE2_SPTR nextbranch = code + GET(code, 1);
-PCRE2_UCHAR *cc = (PCRE2_UCHAR *)code + 1 + LINK_SIZE;
-recurse_check this_recurse;
-
-/* If this is a "could be empty" group, its minimum length is 0. */
-
-if (*code >= OP_SBRA && *code <= OP_SCOND) return 0;
-
-/* Skip over capturing bracket number */
-
-if (*code == OP_CBRA || *code == OP_CBRAPOS) cc += IMM2_SIZE;
-
-/* A large and/or complex regex can take too long to process. */
-
-if ((*countptr)++ > 1000) return -1;
-
-/* Scan along the opcodes for this branch. If we get to the end of the branch,
-check the length against that of the other branches. If the accumulated length
-passes 16-bits, reset to that value and skip the rest of the branch. */
-
-for (;;)
- {
- int d, min, recno;
- PCRE2_UCHAR op, *cs, *ce;
-
- if (branchlength >= UINT16_MAX)
- {
- branchlength = UINT16_MAX;
- cc = (PCRE2_UCHAR *)nextbranch;
- }
-
- op = *cc;
- switch (op)
- {
- case OP_COND:
- case OP_SCOND:
-
- /* If there is only one branch in a condition, the implied branch has zero
- length, so we don't add anything. This covers the DEFINE "condition"
- automatically. If there are two branches we can treat it the same as any
- other non-capturing subpattern. */
-
- cs = cc + GET(cc, 1);
- if (*cs != OP_ALT)
- {
- cc = cs + 1 + LINK_SIZE;
- break;
- }
- goto PROCESS_NON_CAPTURE;
-
- case OP_BRA:
- /* There's a special case of OP_BRA, when it is wrapped round a repeated
- OP_RECURSE. We'd like to process the latter at this level so that
- remembering the value works for repeated cases. So we do nothing, but
- set a fudge value to skip over the OP_KET after the recurse. */
-
- if (cc[1+LINK_SIZE] == OP_RECURSE && cc[2*(1+LINK_SIZE)] == OP_KET)
- {
- once_fudge = 1 + LINK_SIZE;
- cc += 1 + LINK_SIZE;
- break;
- }
- /* Fall through */
-
- case OP_ONCE:
- case OP_SCRIPT_RUN:
- case OP_SBRA:
- case OP_BRAPOS:
- case OP_SBRAPOS:
- PROCESS_NON_CAPTURE:
- d = find_minlength(re, cc, startcode, utf, recurses, countptr,
- backref_cache);
- if (d < 0) return d;
- branchlength += d;
- do cc += GET(cc, 1); while (*cc == OP_ALT);
- cc += 1 + LINK_SIZE;
- break;
-
- /* To save time for repeated capturing subpatterns, we remember the
- length of the previous one. Unfortunately we can't do the same for
- the unnumbered ones above. Nor can we do this if (?| is present in the
- pattern because captures with the same number are not then identical. */
-
- case OP_CBRA:
- case OP_SCBRA:
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- recno = (int)GET2(cc, 1+LINK_SIZE);
- if (dupcapused || recno != prev_cap_recno)
- {
- prev_cap_recno = recno;
- prev_cap_d = find_minlength(re, cc, startcode, utf, recurses, countptr,
- backref_cache);
- if (prev_cap_d < 0) return prev_cap_d;
- }
- branchlength += prev_cap_d;
- do cc += GET(cc, 1); while (*cc == OP_ALT);
- cc += 1 + LINK_SIZE;
- break;
-
- /* ACCEPT makes things far too complicated; we have to give up. In fact,
- from 10.34 onwards, if a pattern contains (*ACCEPT), this function is not
- used. However, leave the code in place, just in case. */
-
- case OP_ACCEPT:
- case OP_ASSERT_ACCEPT:
- return -1;
-
- /* Reached end of a branch; if it's a ket it is the end of a nested
- call. If it's ALT it is an alternation in a nested call. If it is END it's
- the end of the outer call. All can be handled by the same code. If the
- length of any branch is zero, there is no need to scan any subsequent
- branches. */
-
- case OP_ALT:
- case OP_KET:
- case OP_KETRMAX:
- case OP_KETRMIN:
- case OP_KETRPOS:
- case OP_END:
- if (length < 0 || (!had_recurse && branchlength < length))
- length = branchlength;
- if (op != OP_ALT || length == 0) return length;
- nextbranch = cc + GET(cc, 1);
- cc += 1 + LINK_SIZE;
- branchlength = 0;
- had_recurse = FALSE;
- break;
-
- /* Skip over assertive subpatterns */
-
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- case OP_ASSERT_NA:
- case OP_ASSERTBACK_NA:
- do cc += GET(cc, 1); while (*cc == OP_ALT);
- /* Fall through */
-
- /* Skip over things that don't match chars */
-
- case OP_REVERSE:
- case OP_CREF:
- case OP_DNCREF:
- case OP_RREF:
- case OP_DNRREF:
- case OP_FALSE:
- case OP_TRUE:
- case OP_CALLOUT:
- case OP_SOD:
- case OP_SOM:
- case OP_EOD:
- case OP_EODN:
- case OP_CIRC:
- case OP_CIRCM:
- case OP_DOLL:
- case OP_DOLLM:
- case OP_NOT_WORD_BOUNDARY:
- case OP_WORD_BOUNDARY:
- cc += PRIV(OP_lengths)[*cc];
- break;
-
- case OP_CALLOUT_STR:
- cc += GET(cc, 1 + 2*LINK_SIZE);
- break;
-
- /* Skip over a subpattern that has a {0} or {0,x} quantifier */
-
- case OP_BRAZERO:
- case OP_BRAMINZERO:
- case OP_BRAPOSZERO:
- case OP_SKIPZERO:
- cc += PRIV(OP_lengths)[*cc];
- do cc += GET(cc, 1); while (*cc == OP_ALT);
- cc += 1 + LINK_SIZE;
- break;
-
- /* Handle literal characters and + repetitions */
-
- case OP_CHAR:
- case OP_CHARI:
- case OP_NOT:
- case OP_NOTI:
- case OP_PLUS:
- case OP_PLUSI:
- case OP_MINPLUS:
- case OP_MINPLUSI:
- case OP_POSPLUS:
- case OP_POSPLUSI:
- case OP_NOTPLUS:
- case OP_NOTPLUSI:
- case OP_NOTMINPLUS:
- case OP_NOTMINPLUSI:
- case OP_NOTPOSPLUS:
- case OP_NOTPOSPLUSI:
- branchlength++;
- cc += 2;
-#ifdef SUPPORT_UNICODE
- if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- break;
-
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEPOSPLUS:
- branchlength++;
- cc += (cc[1] == OP_PROP || cc[1] == OP_NOTPROP)? 4 : 2;
- break;
-
- /* Handle exact repetitions. The count is already in characters, but we
- may need to skip over a multibyte character in UTF mode. */
-
- case OP_EXACT:
- case OP_EXACTI:
- case OP_NOTEXACT:
- case OP_NOTEXACTI:
- branchlength += GET2(cc,1);
- cc += 2 + IMM2_SIZE;
-#ifdef SUPPORT_UNICODE
- if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- break;
-
- case OP_TYPEEXACT:
- branchlength += GET2(cc,1);
- cc += 2 + IMM2_SIZE + ((cc[1 + IMM2_SIZE] == OP_PROP
- || cc[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0);
- break;
-
- /* Handle single-char non-literal matchers */
-
- case OP_PROP:
- case OP_NOTPROP:
- cc += 2;
- /* Fall through */
-
- case OP_NOT_DIGIT:
- case OP_DIGIT:
- case OP_NOT_WHITESPACE:
- case OP_WHITESPACE:
- case OP_NOT_WORDCHAR:
- case OP_WORDCHAR:
- case OP_ANY:
- case OP_ALLANY:
- case OP_EXTUNI:
- case OP_HSPACE:
- case OP_NOT_HSPACE:
- case OP_VSPACE:
- case OP_NOT_VSPACE:
- branchlength++;
- cc++;
- break;
-
- /* "Any newline" might match two characters, but it also might match just
- one. */
-
- case OP_ANYNL:
- branchlength += 1;
- cc++;
- break;
-
- /* The single-byte matcher means we can't proceed in UTF mode. (In
- non-UTF mode \C will actually be turned into OP_ALLANY, so won't ever
- appear, but leave the code, just in case.) */
-
- case OP_ANYBYTE:
-#ifdef SUPPORT_UNICODE
- if (utf) return -1;
-#endif
- branchlength++;
- cc++;
- break;
-
- /* For repeated character types, we have to test for \p and \P, which have
- an extra two bytes of parameters. */
-
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSQUERY:
- if (cc[1] == OP_PROP || cc[1] == OP_NOTPROP) cc += 2;
- cc += PRIV(OP_lengths)[op];
- break;
-
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEPOSUPTO:
- if (cc[1 + IMM2_SIZE] == OP_PROP
- || cc[1 + IMM2_SIZE] == OP_NOTPROP) cc += 2;
- cc += PRIV(OP_lengths)[op];
- break;
-
- /* Check a class for variable quantification */
-
- case OP_CLASS:
- case OP_NCLASS:
-#ifdef SUPPORT_WIDE_CHARS
- case OP_XCLASS:
- /* The original code caused an unsigned overflow in 64 bit systems,
- so now we use a conditional statement. */
- if (op == OP_XCLASS)
- cc += GET(cc, 1);
- else
- cc += PRIV(OP_lengths)[OP_CLASS];
-#else
- cc += PRIV(OP_lengths)[OP_CLASS];
-#endif
-
- switch (*cc)
- {
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRPOSPLUS:
- branchlength++;
- /* Fall through */
-
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- case OP_CRPOSSTAR:
- case OP_CRPOSQUERY:
- cc++;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- case OP_CRPOSRANGE:
- branchlength += GET2(cc,1);
- cc += 1 + 2 * IMM2_SIZE;
- break;
-
- default:
- branchlength++;
- break;
- }
- break;
-
- /* Backreferences and subroutine calls (OP_RECURSE) are treated in the same
- way: we find the minimum length for the subpattern. A recursion
- (backreference or subroutine) causes an a flag to be set that causes the
- length of this branch to be ignored. The logic is that a recursion can only
- make sense if there is another alternative that stops the recursing. That
- will provide the minimum length (when no recursion happens).
-
- If PCRE2_MATCH_UNSET_BACKREF is set, a backreference to an unset bracket
- matches an empty string (by default it causes a matching failure), so in
- that case we must set the minimum length to zero.
-
- For backreferenes, if duplicate numbers are present in the pattern we check
- for a reference to a duplicate. If it is, we don't know which version will
- be referenced, so we have to set the minimum length to zero. */
-
- /* Duplicate named pattern back reference. */
-
- case OP_DNREF:
- case OP_DNREFI:
- if (!dupcapused && (re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0)
- {
- int count = GET2(cc, 1+IMM2_SIZE);
- PCRE2_UCHAR *slot =
- (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) +
- GET2(cc, 1) * re->name_entry_size;
-
- d = INT_MAX;
-
- /* Scan all groups with the same name; find the shortest. */
-
- while (count-- > 0)
- {
- int dd, i;
- recno = GET2(slot, 0);
-
- if (recno <= backref_cache[0] && backref_cache[recno] >= 0)
- dd = backref_cache[recno];
- else
- {
- ce = cs = (PCRE2_UCHAR *)PRIV(find_bracket)(startcode, utf, recno);
- if (cs == NULL) return -2;
- do ce += GET(ce, 1); while (*ce == OP_ALT);
-
- dd = 0;
- if (!dupcapused ||
- (PCRE2_UCHAR *)PRIV(find_bracket)(ce, utf, recno) == NULL)
- {
- if (cc > cs && cc < ce) /* Simple recursion */
- {
- had_recurse = TRUE;
- }
- else
- {
- recurse_check *r = recurses;
- for (r = recurses; r != NULL; r = r->prev)
- if (r->group == cs) break;
- if (r != NULL) /* Mutual recursion */
- {
- had_recurse = TRUE;
- }
- else
- {
- this_recurse.prev = recurses; /* No recursion */
- this_recurse.group = cs;
- dd = find_minlength(re, cs, startcode, utf, &this_recurse,
- countptr, backref_cache);
- if (dd < 0) return dd;
- }
- }
- }
-
- backref_cache[recno] = dd;
- for (i = backref_cache[0] + 1; i < recno; i++) backref_cache[i] = -1;
- backref_cache[0] = recno;
- }
-
- if (dd < d) d = dd;
- if (d <= 0) break; /* No point looking at any more */
- slot += re->name_entry_size;
- }
- }
- else d = 0;
- cc += 1 + 2*IMM2_SIZE;
- goto REPEAT_BACK_REFERENCE;
-
- /* Single back reference by number. References by name are converted to by
- number when there is no duplication. */
-
- case OP_REF:
- case OP_REFI:
- recno = GET2(cc, 1);
- if (recno <= backref_cache[0] && backref_cache[recno] >= 0)
- d = backref_cache[recno];
- else
- {
- int i;
- d = 0;
-
- if ((re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0)
- {
- ce = cs = (PCRE2_UCHAR *)PRIV(find_bracket)(startcode, utf, recno);
- if (cs == NULL) return -2;
- do ce += GET(ce, 1); while (*ce == OP_ALT);
-
- if (!dupcapused ||
- (PCRE2_UCHAR *)PRIV(find_bracket)(ce, utf, recno) == NULL)
- {
- if (cc > cs && cc < ce) /* Simple recursion */
- {
- had_recurse = TRUE;
- }
- else
- {
- recurse_check *r = recurses;
- for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break;
- if (r != NULL) /* Mutual recursion */
- {
- had_recurse = TRUE;
- }
- else /* No recursion */
- {
- this_recurse.prev = recurses;
- this_recurse.group = cs;
- d = find_minlength(re, cs, startcode, utf, &this_recurse, countptr,
- backref_cache);
- if (d < 0) return d;
- }
- }
- }
- }
-
- backref_cache[recno] = d;
- for (i = backref_cache[0] + 1; i < recno; i++) backref_cache[i] = -1;
- backref_cache[0] = recno;
- }
-
- cc += 1 + IMM2_SIZE;
-
- /* Handle repeated back references */
-
- REPEAT_BACK_REFERENCE:
- switch (*cc)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- case OP_CRPOSSTAR:
- case OP_CRPOSQUERY:
- min = 0;
- cc++;
- break;
-
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRPOSPLUS:
- min = 1;
- cc++;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- case OP_CRPOSRANGE:
- min = GET2(cc, 1);
- cc += 1 + 2 * IMM2_SIZE;
- break;
-
- default:
- min = 1;
- break;
- }
-
- /* Take care not to overflow: (1) min and d are ints, so check that their
- product is not greater than INT_MAX. (2) branchlength is limited to
- UINT16_MAX (checked at the top of the loop). */
-
- if ((d > 0 && (INT_MAX/d) < min) || UINT16_MAX - branchlength < min*d)
- branchlength = UINT16_MAX;
- else branchlength += min * d;
- break;
-
- /* Recursion always refers to the first occurrence of a subpattern with a
- given number. Therefore, we can always make use of caching, even when the
- pattern contains multiple subpatterns with the same number. */
-
- case OP_RECURSE:
- cs = ce = (PCRE2_UCHAR *)startcode + GET(cc, 1);
- recno = GET2(cs, 1+LINK_SIZE);
- if (recno == prev_recurse_recno)
- {
- branchlength += prev_recurse_d;
- }
- else
- {
- do ce += GET(ce, 1); while (*ce == OP_ALT);
- if (cc > cs && cc < ce) /* Simple recursion */
- had_recurse = TRUE;
- else
- {
- recurse_check *r = recurses;
- for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break;
- if (r != NULL) /* Mutual recursion */
- had_recurse = TRUE;
- else
- {
- this_recurse.prev = recurses;
- this_recurse.group = cs;
- prev_recurse_d = find_minlength(re, cs, startcode, utf, &this_recurse,
- countptr, backref_cache);
- if (prev_recurse_d < 0) return prev_recurse_d;
- prev_recurse_recno = recno;
- branchlength += prev_recurse_d;
- }
- }
- }
- cc += 1 + LINK_SIZE + once_fudge;
- once_fudge = 0;
- break;
-
- /* Anything else does not or need not match a character. We can get the
- item's length from the table, but for those that can match zero occurrences
- of a character, we must take special action for UTF-8 characters. As it
- happens, the "NOT" versions of these opcodes are used at present only for
- ASCII characters, so they could be omitted from this list. However, in
- future that may change, so we include them here so as not to leave a
- gotcha for a future maintainer. */
-
- case OP_UPTO:
- case OP_UPTOI:
- case OP_NOTUPTO:
- case OP_NOTUPTOI:
- case OP_MINUPTO:
- case OP_MINUPTOI:
- case OP_NOTMINUPTO:
- case OP_NOTMINUPTOI:
- case OP_POSUPTO:
- case OP_POSUPTOI:
- case OP_NOTPOSUPTO:
- case OP_NOTPOSUPTOI:
-
- case OP_STAR:
- case OP_STARI:
- case OP_NOTSTAR:
- case OP_NOTSTARI:
- case OP_MINSTAR:
- case OP_MINSTARI:
- case OP_NOTMINSTAR:
- case OP_NOTMINSTARI:
- case OP_POSSTAR:
- case OP_POSSTARI:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSSTARI:
-
- case OP_QUERY:
- case OP_QUERYI:
- case OP_NOTQUERY:
- case OP_NOTQUERYI:
- case OP_MINQUERY:
- case OP_MINQUERYI:
- case OP_NOTMINQUERY:
- case OP_NOTMINQUERYI:
- case OP_POSQUERY:
- case OP_POSQUERYI:
- case OP_NOTPOSQUERY:
- case OP_NOTPOSQUERYI:
-
- cc += PRIV(OP_lengths)[op];
-#ifdef SUPPORT_UNICODE
- if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- break;
-
- /* Skip these, but we need to add in the name length. */
-
- case OP_MARK:
- case OP_COMMIT_ARG:
- case OP_PRUNE_ARG:
- case OP_SKIP_ARG:
- case OP_THEN_ARG:
- cc += PRIV(OP_lengths)[op] + cc[1];
- break;
-
- /* The remaining opcodes are just skipped over. */
-
- case OP_CLOSE:
- case OP_COMMIT:
- case OP_FAIL:
- case OP_PRUNE:
- case OP_SET_SOM:
- case OP_SKIP:
- case OP_THEN:
- cc += PRIV(OP_lengths)[op];
- break;
-
- /* This should not occur: we list all opcodes explicitly so that when
- new ones get added they are properly considered. */
-
- default:
- return -3;
- }
- }
-/* Control never gets here */
-}
-
-
-
-/*************************************************
-* Set a bit and maybe its alternate case *
-*************************************************/
-
-/* Given a character, set its first code unit's bit in the table, and also the
-corresponding bit for the other version of a letter if we are caseless.
-
-Arguments:
- re points to the regex block
- p points to the first code unit of the character
- caseless TRUE if caseless
- utf TRUE for UTF mode
- ucp TRUE for UCP mode
-
-Returns: pointer after the character
-*/
-
-static PCRE2_SPTR
-set_table_bit(pcre2_real_code *re, PCRE2_SPTR p, BOOL caseless, BOOL utf,
- BOOL ucp)
-{
-uint32_t c = *p++; /* First code unit */
-
-(void)utf; /* Stop compiler warnings when UTF not supported */
-(void)ucp;
-
-/* In 16-bit and 32-bit modes, code units greater than 0xff set the bit for
-0xff. */
-
-#if PCRE2_CODE_UNIT_WIDTH != 8
-if (c > 0xff) SET_BIT(0xff); else
-#endif
-
-SET_BIT(c);
-
-/* In UTF-8 or UTF-16 mode, pick up the remaining code units in order to find
-the end of the character, even when caseless. */
-
-#ifdef SUPPORT_UNICODE
-if (utf)
- {
-#if PCRE2_CODE_UNIT_WIDTH == 8
- if (c >= 0xc0) GETUTF8INC(c, p);
-#elif PCRE2_CODE_UNIT_WIDTH == 16
- if ((c & 0xfc00) == 0xd800) GETUTF16INC(c, p);
-#endif
- }
-#endif /* SUPPORT_UNICODE */
-
-/* If caseless, handle the other case of the character. */
-
-if (caseless)
- {
-#ifdef SUPPORT_UNICODE
- if (utf || ucp)
- {
- c = UCD_OTHERCASE(c);
-#if PCRE2_CODE_UNIT_WIDTH == 8
- if (utf)
- {
- PCRE2_UCHAR buff[6];
- (void)PRIV(ord2utf)(c, buff);
- SET_BIT(buff[0]);
- }
- else if (c < 256) SET_BIT(c);
-#else /* 16-bit or 32-bit mode */
- if (c > 0xff) SET_BIT(0xff); else SET_BIT(c);
-#endif
- }
-
- else
-#endif /* SUPPORT_UNICODE */
-
- /* Not UTF or UCP */
-
- if (MAX_255(c)) SET_BIT(re->tables[fcc_offset + c]);
- }
-
-return p;
-}
-
-
-
-/*************************************************
-* Set bits for a positive character type *
-*************************************************/
-
-/* This function sets starting bits for a character type. In UTF-8 mode, we can
-only do a direct setting for bytes less than 128, as otherwise there can be
-confusion with bytes in the middle of UTF-8 characters. In a "traditional"
-environment, the tables will only recognize ASCII characters anyway, but in at
-least one Windows environment, some higher bytes bits were set in the tables.
-So we deal with that case by considering the UTF-8 encoding.
-
-Arguments:
- re the regex block
- cbit type the type of character wanted
- table_limit 32 for non-UTF-8; 16 for UTF-8
-
-Returns: nothing
-*/
-
-static void
-set_type_bits(pcre2_real_code *re, int cbit_type, unsigned int table_limit)
-{
-uint32_t c;
-for (c = 0; c < table_limit; c++)
- re->start_bitmap[c] |= re->tables[c+cbits_offset+cbit_type];
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
-if (table_limit == 32) return;
-for (c = 128; c < 256; c++)
- {
- if ((re->tables[cbits_offset + c/8] & (1u << (c&7))) != 0)
- {
- PCRE2_UCHAR buff[6];
- (void)PRIV(ord2utf)(c, buff);
- SET_BIT(buff[0]);
- }
- }
-#endif /* UTF-8 */
-}
-
-
-/*************************************************
-* Set bits for a negative character type *
-*************************************************/
-
-/* This function sets starting bits for a negative character type such as \D.
-In UTF-8 mode, we can only do a direct setting for bytes less than 128, as
-otherwise there can be confusion with bytes in the middle of UTF-8 characters.
-Unlike in the positive case, where we can set appropriate starting bits for
-specific high-valued UTF-8 characters, in this case we have to set the bits for
-all high-valued characters. The lowest is 0xc2, but we overkill by starting at
-0xc0 (192) for simplicity.
-
-Arguments:
- re the regex block
- cbit type the type of character wanted
- table_limit 32 for non-UTF-8; 16 for UTF-8
-
-Returns: nothing
-*/
-
-static void
-set_nottype_bits(pcre2_real_code *re, int cbit_type, unsigned int table_limit)
-{
-uint32_t c;
-for (c = 0; c < table_limit; c++)
- re->start_bitmap[c] |= (uint8_t)(~(re->tables[c+cbits_offset+cbit_type]));
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
-if (table_limit != 32) for (c = 24; c < 32; c++) re->start_bitmap[c] = 0xff;
-#endif
-}
-
-
-
-/*************************************************
-* Create bitmap of starting code units *
-*************************************************/
-
-/* This function scans a compiled unanchored expression recursively and
-attempts to build a bitmap of the set of possible starting code units whose
-values are less than 256. In 16-bit and 32-bit mode, values above 255 all cause
-the 255 bit to be set. When calling set[_not]_type_bits() in UTF-8 (sic) mode
-we pass a value of 16 rather than 32 as the final argument. (See comments in
-those functions for the reason.)
-
-The SSB_CONTINUE return is useful for parenthesized groups in patterns such as
-(a*)b where the group provides some optional starting code units but scanning
-must continue at the outer level to find at least one mandatory code unit. At
-the outermost level, this function fails unless the result is SSB_DONE.
-
-We restrict recursion (for nested groups) to 1000 to avoid stack overflow
-issues.
-
-Arguments:
- re points to the compiled regex block
- code points to an expression
- utf TRUE if in UTF mode
- ucp TRUE if in UCP mode
- depthptr pointer to recurse depth
-
-Returns: SSB_FAIL => Failed to find any starting code units
- SSB_DONE => Found mandatory starting code units
- SSB_CONTINUE => Found optional starting code units
- SSB_UNKNOWN => Hit an unrecognized opcode
- SSB_TOODEEP => Recursion is too deep
-*/
-
-static int
-set_start_bits(pcre2_real_code *re, PCRE2_SPTR code, BOOL utf, BOOL ucp,
- int *depthptr)
-{
-uint32_t c;
-int yield = SSB_DONE;
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
-int table_limit = utf? 16:32;
-#else
-int table_limit = 32;
-#endif
-
-*depthptr += 1;
-if (*depthptr > 1000) return SSB_TOODEEP;
-
-do
- {
- BOOL try_next = TRUE;
- PCRE2_SPTR tcode = code + 1 + LINK_SIZE;
-
- if (*code == OP_CBRA || *code == OP_SCBRA ||
- *code == OP_CBRAPOS || *code == OP_SCBRAPOS) tcode += IMM2_SIZE;
-
- while (try_next) /* Loop for items in this branch */
- {
- int rc;
- uint8_t *classmap = NULL;
-#ifdef SUPPORT_WIDE_CHARS
- PCRE2_UCHAR xclassflags;
-#endif
-
- switch(*tcode)
- {
- /* If we reach something we don't understand, it means a new opcode has
- been created that hasn't been added to this function. Hopefully this
- problem will be discovered during testing. */
-
- default:
- return SSB_UNKNOWN;
-
- /* Fail for a valid opcode that implies no starting bits. */
-
- case OP_ACCEPT:
- case OP_ASSERT_ACCEPT:
- case OP_ALLANY:
- case OP_ANY:
- case OP_ANYBYTE:
- case OP_CIRCM:
- case OP_CLOSE:
- case OP_COMMIT:
- case OP_COMMIT_ARG:
- case OP_COND:
- case OP_CREF:
- case OP_FALSE:
- case OP_TRUE:
- case OP_DNCREF:
- case OP_DNREF:
- case OP_DNREFI:
- case OP_DNRREF:
- case OP_DOLL:
- case OP_DOLLM:
- case OP_END:
- case OP_EOD:
- case OP_EODN:
- case OP_EXTUNI:
- case OP_FAIL:
- case OP_MARK:
- case OP_NOT:
- case OP_NOTEXACT:
- case OP_NOTEXACTI:
- case OP_NOTI:
- case OP_NOTMINPLUS:
- case OP_NOTMINPLUSI:
- case OP_NOTMINQUERY:
- case OP_NOTMINQUERYI:
- case OP_NOTMINSTAR:
- case OP_NOTMINSTARI:
- case OP_NOTMINUPTO:
- case OP_NOTMINUPTOI:
- case OP_NOTPLUS:
- case OP_NOTPLUSI:
- case OP_NOTPOSPLUS:
- case OP_NOTPOSPLUSI:
- case OP_NOTPOSQUERY:
- case OP_NOTPOSQUERYI:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSSTARI:
- case OP_NOTPOSUPTO:
- case OP_NOTPOSUPTOI:
- case OP_NOTPROP:
- case OP_NOTQUERY:
- case OP_NOTQUERYI:
- case OP_NOTSTAR:
- case OP_NOTSTARI:
- case OP_NOTUPTO:
- case OP_NOTUPTOI:
- case OP_NOT_HSPACE:
- case OP_NOT_VSPACE:
- case OP_PRUNE:
- case OP_PRUNE_ARG:
- case OP_RECURSE:
- case OP_REF:
- case OP_REFI:
- case OP_REVERSE:
- case OP_RREF:
- case OP_SCOND:
- case OP_SET_SOM:
- case OP_SKIP:
- case OP_SKIP_ARG:
- case OP_SOD:
- case OP_SOM:
- case OP_THEN:
- case OP_THEN_ARG:
- return SSB_FAIL;
-
- /* OP_CIRC happens only at the start of an anchored branch (multiline ^
- uses OP_CIRCM). Skip over it. */
-
- case OP_CIRC:
- tcode += PRIV(OP_lengths)[OP_CIRC];
- break;
-
- /* A "real" property test implies no starting bits, but the fake property
- PT_CLIST identifies a list of characters. These lists are short, as they
- are used for characters with more than one "other case", so there is no
- point in recognizing them for OP_NOTPROP. */
-
- case OP_PROP:
- if (tcode[1] != PT_CLIST) return SSB_FAIL;
- {
- const uint32_t *p = PRIV(ucd_caseless_sets) + tcode[2];
- while ((c = *p++) < NOTACHAR)
- {
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
- if (utf)
- {
- PCRE2_UCHAR buff[6];
- (void)PRIV(ord2utf)(c, buff);
- c = buff[0];
- }
-#endif
- if (c > 0xff) SET_BIT(0xff); else SET_BIT(c);
- }
- }
- try_next = FALSE;
- break;
-
- /* We can ignore word boundary tests. */
-
- case OP_WORD_BOUNDARY:
- case OP_NOT_WORD_BOUNDARY:
- tcode++;
- break;
-
- /* If we hit a bracket or a positive lookahead assertion, recurse to set
- bits from within the subpattern. If it can't find anything, we have to
- give up. If it finds some mandatory character(s), we are done for this
- branch. Otherwise, carry on scanning after the subpattern. */
-
- case OP_BRA:
- case OP_SBRA:
- case OP_CBRA:
- case OP_SCBRA:
- case OP_BRAPOS:
- case OP_SBRAPOS:
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- case OP_ONCE:
- case OP_SCRIPT_RUN:
- case OP_ASSERT:
- case OP_ASSERT_NA:
- rc = set_start_bits(re, tcode, utf, ucp, depthptr);
- if (rc == SSB_DONE)
- {
- try_next = FALSE;
- }
- else if (rc == SSB_CONTINUE)
- {
- do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
- tcode += 1 + LINK_SIZE;
- }
- else return rc; /* FAIL, UNKNOWN, or TOODEEP */
- break;
-
- /* If we hit ALT or KET, it means we haven't found anything mandatory in
- this branch, though we might have found something optional. For ALT, we
- continue with the next alternative, but we have to arrange that the final
- result from subpattern is SSB_CONTINUE rather than SSB_DONE. For KET,
- return SSB_CONTINUE: if this is the top level, that indicates failure,
- but after a nested subpattern, it causes scanning to continue. */
-
- case OP_ALT:
- yield = SSB_CONTINUE;
- try_next = FALSE;
- break;
-
- case OP_KET:
- case OP_KETRMAX:
- case OP_KETRMIN:
- case OP_KETRPOS:
- return SSB_CONTINUE;
-
- /* Skip over callout */
-
- case OP_CALLOUT:
- tcode += PRIV(OP_lengths)[OP_CALLOUT];
- break;
-
- case OP_CALLOUT_STR:
- tcode += GET(tcode, 1 + 2*LINK_SIZE);
- break;
-
- /* Skip over lookbehind and negative lookahead assertions */
-
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- case OP_ASSERTBACK_NA:
- do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
- tcode += 1 + LINK_SIZE;
- break;
-
- /* BRAZERO does the bracket, but carries on. */
-
- case OP_BRAZERO:
- case OP_BRAMINZERO:
- case OP_BRAPOSZERO:
- rc = set_start_bits(re, ++tcode, utf, ucp, depthptr);
- if (rc == SSB_FAIL || rc == SSB_UNKNOWN || rc == SSB_TOODEEP) return rc;
- do tcode += GET(tcode,1); while (*tcode == OP_ALT);
- tcode += 1 + LINK_SIZE;
- break;
-
- /* SKIPZERO skips the bracket. */
-
- case OP_SKIPZERO:
- tcode++;
- do tcode += GET(tcode,1); while (*tcode == OP_ALT);
- tcode += 1 + LINK_SIZE;
- break;
-
- /* Single-char * or ? sets the bit and tries the next item */
-
- case OP_STAR:
- case OP_MINSTAR:
- case OP_POSSTAR:
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_POSQUERY:
- tcode = set_table_bit(re, tcode + 1, FALSE, utf, ucp);
- break;
-
- case OP_STARI:
- case OP_MINSTARI:
- case OP_POSSTARI:
- case OP_QUERYI:
- case OP_MINQUERYI:
- case OP_POSQUERYI:
- tcode = set_table_bit(re, tcode + 1, TRUE, utf, ucp);
- break;
-
- /* Single-char upto sets the bit and tries the next */
-
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_POSUPTO:
- tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, FALSE, utf, ucp);
- break;
-
- case OP_UPTOI:
- case OP_MINUPTOI:
- case OP_POSUPTOI:
- tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, TRUE, utf, ucp);
- break;
-
- /* At least one single char sets the bit and stops */
-
- case OP_EXACT:
- tcode += IMM2_SIZE;
- /* Fall through */
- case OP_CHAR:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_POSPLUS:
- (void)set_table_bit(re, tcode + 1, FALSE, utf, ucp);
- try_next = FALSE;
- break;
-
- case OP_EXACTI:
- tcode += IMM2_SIZE;
- /* Fall through */
- case OP_CHARI:
- case OP_PLUSI:
- case OP_MINPLUSI:
- case OP_POSPLUSI:
- (void)set_table_bit(re, tcode + 1, TRUE, utf, ucp);
- try_next = FALSE;
- break;
-
- /* Special spacing and line-terminating items. These recognize specific
- lists of characters. The difference between VSPACE and ANYNL is that the
- latter can match the two-character CRLF sequence, but that is not
- relevant for finding the first character, so their code here is
- identical. */
-
- case OP_HSPACE:
- SET_BIT(CHAR_HT);
- SET_BIT(CHAR_SPACE);
-
- /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set
- the bits for 0xA0 and for code units >= 255, independently of UTF. */
-
-#if PCRE2_CODE_UNIT_WIDTH != 8
- SET_BIT(0xA0);
- SET_BIT(0xFF);
-#else
- /* For the 8-bit library in UTF-8 mode, set the bits for the first code
- units of horizontal space characters. */
-
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- SET_BIT(0xC2); /* For U+00A0 */
- SET_BIT(0xE1); /* For U+1680, U+180E */
- SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */
- SET_BIT(0xE3); /* For U+3000 */
- }
- else
-#endif
- /* For the 8-bit library not in UTF-8 mode, set the bit for 0xA0, unless
- the code is EBCDIC. */
- {
-#ifndef EBCDIC
- SET_BIT(0xA0);
-#endif /* Not EBCDIC */
- }
-#endif /* 8-bit support */
-
- try_next = FALSE;
- break;
-
- case OP_ANYNL:
- case OP_VSPACE:
- SET_BIT(CHAR_LF);
- SET_BIT(CHAR_VT);
- SET_BIT(CHAR_FF);
- SET_BIT(CHAR_CR);
-
- /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set
- the bits for NEL and for code units >= 255, independently of UTF. */
-
-#if PCRE2_CODE_UNIT_WIDTH != 8
- SET_BIT(CHAR_NEL);
- SET_BIT(0xFF);
-#else
- /* For the 8-bit library in UTF-8 mode, set the bits for the first code
- units of vertical space characters. */
-
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- SET_BIT(0xC2); /* For U+0085 (NEL) */
- SET_BIT(0xE2); /* For U+2028, U+2029 */
- }
- else
-#endif
- /* For the 8-bit library not in UTF-8 mode, set the bit for NEL. */
- {
- SET_BIT(CHAR_NEL);
- }
-#endif /* 8-bit support */
-
- try_next = FALSE;
- break;
-
- /* Single character types set the bits and stop. Note that if PCRE2_UCP
- is set, we do not see these opcodes because \d etc are converted to
- properties. Therefore, these apply in the case when only characters less
- than 256 are recognized to match the types. */
-
- case OP_NOT_DIGIT:
- set_nottype_bits(re, cbit_digit, table_limit);
- try_next = FALSE;
- break;
-
- case OP_DIGIT:
- set_type_bits(re, cbit_digit, table_limit);
- try_next = FALSE;
- break;
-
- case OP_NOT_WHITESPACE:
- set_nottype_bits(re, cbit_space, table_limit);
- try_next = FALSE;
- break;
-
- case OP_WHITESPACE:
- set_type_bits(re, cbit_space, table_limit);
- try_next = FALSE;
- break;
-
- case OP_NOT_WORDCHAR:
- set_nottype_bits(re, cbit_word, table_limit);
- try_next = FALSE;
- break;
-
- case OP_WORDCHAR:
- set_type_bits(re, cbit_word, table_limit);
- try_next = FALSE;
- break;
-
- /* One or more character type fudges the pointer and restarts, knowing
- it will hit a single character type and stop there. */
-
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEPOSPLUS:
- tcode++;
- break;
-
- case OP_TYPEEXACT:
- tcode += 1 + IMM2_SIZE;
- break;
-
- /* Zero or more repeats of character types set the bits and then
- try again. */
-
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEPOSUPTO:
- tcode += IMM2_SIZE; /* Fall through */
-
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPOSSTAR:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSQUERY:
- switch(tcode[1])
- {
- default:
- case OP_ANY:
- case OP_ALLANY:
- return SSB_FAIL;
-
- case OP_HSPACE:
- SET_BIT(CHAR_HT);
- SET_BIT(CHAR_SPACE);
-
- /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set
- the bits for 0xA0 and for code units >= 255, independently of UTF. */
-
-#if PCRE2_CODE_UNIT_WIDTH != 8
- SET_BIT(0xA0);
- SET_BIT(0xFF);
-#else
- /* For the 8-bit library in UTF-8 mode, set the bits for the first code
- units of horizontal space characters. */
-
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- SET_BIT(0xC2); /* For U+00A0 */
- SET_BIT(0xE1); /* For U+1680, U+180E */
- SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */
- SET_BIT(0xE3); /* For U+3000 */
- }
- else
-#endif
- /* For the 8-bit library not in UTF-8 mode, set the bit for 0xA0, unless
- the code is EBCDIC. */
- {
-#ifndef EBCDIC
- SET_BIT(0xA0);
-#endif /* Not EBCDIC */
- }
-#endif /* 8-bit support */
- break;
-
- case OP_ANYNL:
- case OP_VSPACE:
- SET_BIT(CHAR_LF);
- SET_BIT(CHAR_VT);
- SET_BIT(CHAR_FF);
- SET_BIT(CHAR_CR);
-
- /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set
- the bits for NEL and for code units >= 255, independently of UTF. */
-
-#if PCRE2_CODE_UNIT_WIDTH != 8
- SET_BIT(CHAR_NEL);
- SET_BIT(0xFF);
-#else
- /* For the 8-bit library in UTF-8 mode, set the bits for the first code
- units of vertical space characters. */
-
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- SET_BIT(0xC2); /* For U+0085 (NEL) */
- SET_BIT(0xE2); /* For U+2028, U+2029 */
- }
- else
-#endif
- /* For the 8-bit library not in UTF-8 mode, set the bit for NEL. */
- {
- SET_BIT(CHAR_NEL);
- }
-#endif /* 8-bit support */
- break;
-
- case OP_NOT_DIGIT:
- set_nottype_bits(re, cbit_digit, table_limit);
- break;
-
- case OP_DIGIT:
- set_type_bits(re, cbit_digit, table_limit);
- break;
-
- case OP_NOT_WHITESPACE:
- set_nottype_bits(re, cbit_space, table_limit);
- break;
-
- case OP_WHITESPACE:
- set_type_bits(re, cbit_space, table_limit);
- break;
-
- case OP_NOT_WORDCHAR:
- set_nottype_bits(re, cbit_word, table_limit);
- break;
-
- case OP_WORDCHAR:
- set_type_bits(re, cbit_word, table_limit);
- break;
- }
-
- tcode += 2;
- break;
-
- /* Extended class: if there are any property checks, or if this is a
- negative XCLASS without a map, give up. If there are no property checks,
- there must be wide characters on the XCLASS list, because otherwise an
- XCLASS would not have been created. This means that code points >= 255
- are potential starters. In the UTF-8 case we can scan them and set bits
- for the relevant leading bytes. */
-
-#ifdef SUPPORT_WIDE_CHARS
- case OP_XCLASS:
- xclassflags = tcode[1 + LINK_SIZE];
- if ((xclassflags & XCL_HASPROP) != 0 ||
- (xclassflags & (XCL_MAP|XCL_NOT)) == XCL_NOT)
- return SSB_FAIL;
-
- /* We have a positive XCLASS or a negative one without a map. Set up the
- map pointer if there is one, and fall through. */
-
- classmap = ((xclassflags & XCL_MAP) == 0)? NULL :
- (uint8_t *)(tcode + 1 + LINK_SIZE + 1);
-
- /* In UTF-8 mode, scan the character list and set bits for leading bytes,
- then jump to handle the map. */
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
- if (utf && (xclassflags & XCL_NOT) == 0)
- {
- PCRE2_UCHAR b, e;
- PCRE2_SPTR p = tcode + 1 + LINK_SIZE + 1 + ((classmap == NULL)? 0:32);
- tcode += GET(tcode, 1);
-
- for (;;) switch (*p++)
- {
- case XCL_SINGLE:
- b = *p++;
- while ((*p & 0xc0) == 0x80) p++;
- re->start_bitmap[b/8] |= (1u << (b&7));
- break;
-
- case XCL_RANGE:
- b = *p++;
- while ((*p & 0xc0) == 0x80) p++;
- e = *p++;
- while ((*p & 0xc0) == 0x80) p++;
- for (; b <= e; b++)
- re->start_bitmap[b/8] |= (1u << (b&7));
- break;
-
- case XCL_END:
- goto HANDLE_CLASSMAP;
-
- default:
- return SSB_UNKNOWN; /* Internal error, should not occur */
- }
- }
-#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */
-#endif /* SUPPORT_WIDE_CHARS */
-
- /* It seems that the fall through comment must be outside the #ifdef if
- it is to avoid the gcc compiler warning. */
-
- /* Fall through */
-
- /* Enter here for a negative non-XCLASS. In the 8-bit library, if we are
- in UTF mode, any byte with a value >= 0xc4 is a potentially valid starter
- because it starts a character with a value > 255. In 8-bit non-UTF mode,
- there is no difference between CLASS and NCLASS. In all other wide
- character modes, set the 0xFF bit to indicate code units >= 255. */
-
- case OP_NCLASS:
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
- if (utf)
- {
- re->start_bitmap[24] |= 0xf0; /* Bits for 0xc4 - 0xc8 */
- memset(re->start_bitmap+25, 0xff, 7); /* Bits for 0xc9 - 0xff */
- }
-#elif PCRE2_CODE_UNIT_WIDTH != 8
- SET_BIT(0xFF); /* For characters >= 255 */
-#endif
- /* Fall through */
-
- /* Enter here for a positive non-XCLASS. If we have fallen through from
- an XCLASS, classmap will already be set; just advance the code pointer.
- Otherwise, set up classmap for a a non-XCLASS and advance past it. */
-
- case OP_CLASS:
- if (*tcode == OP_XCLASS) tcode += GET(tcode, 1); else
- {
- classmap = (uint8_t *)(++tcode);
- tcode += 32 / sizeof(PCRE2_UCHAR);
- }
-
- /* When wide characters are supported, classmap may be NULL. In UTF-8
- (sic) mode, the bits in a class bit map correspond to character values,
- not to byte values. However, the bit map we are constructing is for byte
- values. So we have to do a conversion for characters whose code point is
- greater than 127. In fact, there are only two possible starting bytes for
- characters in the range 128 - 255. */
-
-#if defined SUPPORT_WIDE_CHARS && PCRE2_CODE_UNIT_WIDTH == 8
- HANDLE_CLASSMAP:
-#endif
- if (classmap != NULL)
- {
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
- if (utf)
- {
- for (c = 0; c < 16; c++) re->start_bitmap[c] |= classmap[c];
- for (c = 128; c < 256; c++)
- {
- if ((classmap[c/8] & (1u << (c&7))) != 0)
- {
- int d = (c >> 6) | 0xc0; /* Set bit for this starter */
- re->start_bitmap[d/8] |= (1u << (d&7)); /* and then skip on to the */
- c = (c & 0xc0) + 0x40 - 1; /* next relevant character. */
- }
- }
- }
- else
-#endif
- /* In all modes except UTF-8, the two bit maps are compatible. */
-
- {
- for (c = 0; c < 32; c++) re->start_bitmap[c] |= classmap[c];
- }
- }
-
- /* Act on what follows the class. For a zero minimum repeat, continue;
- otherwise stop processing. */
-
- switch (*tcode)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- case OP_CRPOSSTAR:
- case OP_CRPOSQUERY:
- tcode++;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- case OP_CRPOSRANGE:
- if (GET2(tcode, 1) == 0) tcode += 1 + 2 * IMM2_SIZE;
- else try_next = FALSE;
- break;
-
- default:
- try_next = FALSE;
- break;
- }
- break; /* End of class handling case */
- } /* End of switch for opcodes */
- } /* End of try_next loop */
-
- code += GET(code, 1); /* Advance to next branch */
- }
-while (*code == OP_ALT);
-
-return yield;
-}
-
-
-
-/*************************************************
-* Study a compiled expression *
-*************************************************/
-
-/* This function is handed a compiled expression that it must study to produce
-information that will speed up the matching.
-
-Argument:
- re points to the compiled expression
-
-Returns: 0 normally; non-zero should never normally occur
- 1 unknown opcode in set_start_bits
- 2 missing capturing bracket
- 3 unknown opcode in find_minlength
-*/
-
-int
-PRIV(study)(pcre2_real_code *re)
-{
-int count = 0;
-PCRE2_UCHAR *code;
-BOOL utf = (re->overall_options & PCRE2_UTF) != 0;
-BOOL ucp = (re->overall_options & PCRE2_UCP) != 0;
-
-/* Find start of compiled code */
-
-code = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) +
- re->name_entry_size * re->name_count;
-
-/* For a pattern that has a first code unit, or a multiline pattern that
-matches only at "line start", there is no point in seeking a list of starting
-code units. */
-
-if ((re->flags & (PCRE2_FIRSTSET|PCRE2_STARTLINE)) == 0)
- {
- int depth = 0;
- int rc = set_start_bits(re, code, utf, ucp, &depth);
- if (rc == SSB_UNKNOWN) return 1;
-
- /* If a list of starting code units was set up, scan the list to see if only
- one or two were listed. Having only one listed is rare because usually a
- single starting code unit will have been recognized and PCRE2_FIRSTSET set.
- If two are listed, see if they are caseless versions of the same character;
- if so we can replace the list with a caseless first code unit. This gives
- better performance and is plausibly worth doing for patterns such as [Ww]ord
- or (word|WORD). */
-
- if (rc == SSB_DONE)
- {
- int i;
- int a = -1;
- int b = -1;
- uint8_t *p = re->start_bitmap;
- uint32_t flags = PCRE2_FIRSTMAPSET;
-
- for (i = 0; i < 256; p++, i += 8)
- {
- uint8_t x = *p;
- if (x != 0)
- {
- int c;
- uint8_t y = x & (~x + 1); /* Least significant bit */
- if (y != x) goto DONE; /* More than one bit set */
-
- /* In the 16-bit and 32-bit libraries, the bit for 0xff means "0xff and
- all wide characters", so we cannot use it here. */
-
-#if PCRE2_CODE_UNIT_WIDTH != 8
- if (i == 248 && x == 0x80) goto DONE;
-#endif
-
- /* Compute the character value */
-
- c = i;
- switch (x)
- {
- case 1: break;
- case 2: c += 1; break; case 4: c += 2; break;
- case 8: c += 3; break; case 16: c += 4; break;
- case 32: c += 5; break; case 64: c += 6; break;
- case 128: c += 7; break;
- }
-
- /* c contains the code unit value, in the range 0-255. In 8-bit UTF
- mode, only values < 128 can be used. In all the other cases, c is a
- character value. */
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
- if (utf && c > 127) goto DONE;
-#endif
- if (a < 0) a = c; /* First one found, save in a */
- else if (b < 0) /* Second one found */
- {
- int d = TABLE_GET((unsigned int)c, re->tables + fcc_offset, c);
-
-#ifdef SUPPORT_UNICODE
- if (utf || ucp)
- {
- if (UCD_CASESET(c) != 0) goto DONE; /* Multiple case set */
- if (c > 127) d = UCD_OTHERCASE(c);
- }
-#endif /* SUPPORT_UNICODE */
-
- if (d != a) goto DONE; /* Not the other case of a */
- b = c; /* Save second in b */
- }
- else goto DONE; /* More than two characters found */
- }
- }
-
- /* Replace the start code unit bits with a first code unit, but only if it
- is not the same as a required later code unit. This is because a search for
- a required code unit starts after an explicit first code unit, but at a
- code unit found from the bitmap. Patterns such as /a*a/ don't work
- if both the start unit and required unit are the same. */
-
- if (a >= 0 &&
- (
- (re->flags & PCRE2_LASTSET) == 0 ||
- (
- re->last_codeunit != (uint32_t)a &&
- (b < 0 || re->last_codeunit != (uint32_t)b)
- )
- ))
- {
- re->first_codeunit = a;
- flags = PCRE2_FIRSTSET;
- if (b >= 0) flags |= PCRE2_FIRSTCASELESS;
- }
-
- DONE:
- re->flags |= flags;
- }
- }
-
-/* Find the minimum length of subject string. If the pattern can match an empty
-string, the minimum length is already known. If the pattern contains (*ACCEPT)
-all bets are off, and we don't even try to find a minimum length. If there are
-more back references than the size of the vector we are going to cache them in,
-do nothing. A pattern that complicated will probably take a long time to
-analyze and may in any case turn out to be too complicated. Note that back
-reference minima are held as 16-bit numbers. */
-
-if ((re->flags & (PCRE2_MATCH_EMPTY|PCRE2_HASACCEPT)) == 0 &&
- re->top_backref <= MAX_CACHE_BACKREF)
- {
- int min;
- int backref_cache[MAX_CACHE_BACKREF+1];
- backref_cache[0] = 0; /* Highest one that is set */
- min = find_minlength(re, code, code, utf, NULL, &count, backref_cache);
- switch(min)
- {
- case -1: /* \C in UTF mode or over-complex regex */
- break; /* Leave minlength unchanged (will be zero) */
-
- case -2:
- return 2; /* missing capturing bracket */
-
- case -3:
- return 3; /* unrecognized opcode */
-
- default:
- re->minlength = (min > UINT16_MAX)? UINT16_MAX : min;
- break;
- }
- }
-
-return 0;
-}
-
-/* End of pcre2_study.c */
diff --git a/contrib/libs/pcre2/src/pcre2_substitute.c b/contrib/libs/pcre2/src/pcre2_substitute.c
deleted file mode 100644
index d667d02f11..0000000000
--- a/contrib/libs/pcre2/src/pcre2_substitute.c
+++ /dev/null
@@ -1,1009 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2022 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-#include "pcre2_internal.h"
-
-#define PTR_STACK_SIZE 20
-
-#define SUBSTITUTE_OPTIONS \
- (PCRE2_SUBSTITUTE_EXTENDED|PCRE2_SUBSTITUTE_GLOBAL| \
- PCRE2_SUBSTITUTE_LITERAL|PCRE2_SUBSTITUTE_MATCHED| \
- PCRE2_SUBSTITUTE_OVERFLOW_LENGTH|PCRE2_SUBSTITUTE_REPLACEMENT_ONLY| \
- PCRE2_SUBSTITUTE_UNKNOWN_UNSET|PCRE2_SUBSTITUTE_UNSET_EMPTY)
-
-
-
-/*************************************************
-* Find end of substitute text *
-*************************************************/
-
-/* In extended mode, we recognize ${name:+set text:unset text} and similar
-constructions. This requires the identification of unescaped : and }
-characters. This function scans for such. It must deal with nested ${
-constructions. The pointer to the text is updated, either to the required end
-character, or to where an error was detected.
-
-Arguments:
- code points to the compiled expression (for options)
- ptrptr points to the pointer to the start of the text (updated)
- ptrend end of the whole string
- last TRUE if the last expected string (only } recognized)
-
-Returns: 0 on success
- negative error code on failure
-*/
-
-static int
-find_text_end(const pcre2_code *code, PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend,
- BOOL last)
-{
-int rc = 0;
-uint32_t nestlevel = 0;
-BOOL literal = FALSE;
-PCRE2_SPTR ptr = *ptrptr;
-
-for (; ptr < ptrend; ptr++)
- {
- if (literal)
- {
- if (ptr[0] == CHAR_BACKSLASH && ptr < ptrend - 1 && ptr[1] == CHAR_E)
- {
- literal = FALSE;
- ptr += 1;
- }
- }
-
- else if (*ptr == CHAR_RIGHT_CURLY_BRACKET)
- {
- if (nestlevel == 0) goto EXIT;
- nestlevel--;
- }
-
- else if (*ptr == CHAR_COLON && !last && nestlevel == 0) goto EXIT;
-
- else if (*ptr == CHAR_DOLLAR_SIGN)
- {
- if (ptr < ptrend - 1 && ptr[1] == CHAR_LEFT_CURLY_BRACKET)
- {
- nestlevel++;
- ptr += 1;
- }
- }
-
- else if (*ptr == CHAR_BACKSLASH)
- {
- int erc;
- int errorcode;
- uint32_t ch;
-
- if (ptr < ptrend - 1) switch (ptr[1])
- {
- case CHAR_L:
- case CHAR_l:
- case CHAR_U:
- case CHAR_u:
- ptr += 1;
- continue;
- }
-
- ptr += 1; /* Must point after \ */
- erc = PRIV(check_escape)(&ptr, ptrend, &ch, &errorcode,
- code->overall_options, code->extra_options, FALSE, NULL);
- ptr -= 1; /* Back to last code unit of escape */
- if (errorcode != 0)
- {
- rc = errorcode;
- goto EXIT;
- }
-
- switch(erc)
- {
- case 0: /* Data character */
- case ESC_E: /* Isolated \E is ignored */
- break;
-
- case ESC_Q:
- literal = TRUE;
- break;
-
- default:
- rc = PCRE2_ERROR_BADREPESCAPE;
- goto EXIT;
- }
- }
- }
-
-rc = PCRE2_ERROR_REPMISSINGBRACE; /* Terminator not found */
-
-EXIT:
-*ptrptr = ptr;
-return rc;
-}
-
-
-
-/*************************************************
-* Match and substitute *
-*************************************************/
-
-/* This function applies a compiled re to a subject string and creates a new
-string with substitutions. The first 7 arguments are the same as for
-pcre2_match(). Either string length may be PCRE2_ZERO_TERMINATED.
-
-Arguments:
- code points to the compiled expression
- subject points to the subject string
- length length of subject string (may contain binary zeros)
- start_offset where to start in the subject string
- options option bits
- match_data points to a match_data block, or is NULL
- context points a PCRE2 context
- replacement points to the replacement string
- rlength length of replacement string
- buffer where to put the substituted string
- blength points to length of buffer; updated to length of string
-
-Returns: >= 0 number of substitutions made
- < 0 an error code
- PCRE2_ERROR_BADREPLACEMENT means invalid use of $
-*/
-
-/* This macro checks for space in the buffer before copying into it. On
-overflow, either give an error immediately, or keep on, accumulating the
-length. */
-
-#define CHECKMEMCPY(from,length) \
- { \
- if (!overflowed && lengthleft < length) \
- { \
- if ((suboptions & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) == 0) goto NOROOM; \
- overflowed = TRUE; \
- extra_needed = length - lengthleft; \
- } \
- else if (overflowed) \
- { \
- extra_needed += length; \
- } \
- else \
- { \
- memcpy(buffer + buff_offset, from, CU2BYTES(length)); \
- buff_offset += length; \
- lengthleft -= length; \
- } \
- }
-
-/* Here's the function */
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_substitute(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length,
- PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data,
- pcre2_match_context *mcontext, PCRE2_SPTR replacement, PCRE2_SIZE rlength,
- PCRE2_UCHAR *buffer, PCRE2_SIZE *blength)
-{
-int rc;
-int subs;
-int forcecase = 0;
-int forcecasereset = 0;
-uint32_t ovector_count;
-uint32_t goptions = 0;
-uint32_t suboptions;
-pcre2_match_data *internal_match_data = NULL;
-BOOL escaped_literal = FALSE;
-BOOL overflowed = FALSE;
-BOOL use_existing_match;
-BOOL replacement_only;
-#ifdef SUPPORT_UNICODE
-BOOL utf = (code->overall_options & PCRE2_UTF) != 0;
-BOOL ucp = (code->overall_options & PCRE2_UCP) != 0;
-#endif
-PCRE2_UCHAR temp[6];
-PCRE2_SPTR ptr;
-PCRE2_SPTR repend;
-PCRE2_SIZE extra_needed = 0;
-PCRE2_SIZE buff_offset, buff_length, lengthleft, fraglength;
-PCRE2_SIZE *ovector;
-PCRE2_SIZE ovecsave[3];
-pcre2_substitute_callout_block scb;
-
-/* General initialization */
-
-buff_offset = 0;
-lengthleft = buff_length = *blength;
-*blength = PCRE2_UNSET;
-ovecsave[0] = ovecsave[1] = ovecsave[2] = PCRE2_UNSET;
-
-/* Partial matching is not valid. This must come after setting *blength to
-PCRE2_UNSET, so as not to imply an offset in the replacement. */
-
-if ((options & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0)
- return PCRE2_ERROR_BADOPTION;
-
-/* Validate length and find the end of the replacement. A NULL replacement of
-zero length is interpreted as an empty string. */
-
-if (replacement == NULL)
- {
- if (rlength != 0) return PCRE2_ERROR_NULL;
- replacement = (PCRE2_SPTR)"";
- }
-
-if (rlength == PCRE2_ZERO_TERMINATED) rlength = PRIV(strlen)(replacement);
-repend = replacement + rlength;
-
-/* Check for using a match that has already happened. Note that the subject
-pointer in the match data may be NULL after a no-match. */
-
-use_existing_match = ((options & PCRE2_SUBSTITUTE_MATCHED) != 0);
-replacement_only = ((options & PCRE2_SUBSTITUTE_REPLACEMENT_ONLY) != 0);
-
-/* If starting from an existing match, there must be an externally provided
-match data block. We create an internal match_data block in two cases: (a) an
-external one is not supplied (and we are not starting from an existing match);
-(b) an existing match is to be used for the first substitution. In the latter
-case, we copy the existing match into the internal block, except for any cached
-heap frame size and pointer. This ensures that no changes are made to the
-external match data block. */
-
-if (match_data == NULL)
- {
- pcre2_general_context *gcontext;
- if (use_existing_match) return PCRE2_ERROR_NULL;
- gcontext = (mcontext == NULL)?
- (pcre2_general_context *)code :
- (pcre2_general_context *)mcontext;
- match_data = internal_match_data =
- pcre2_match_data_create_from_pattern(code, gcontext);
- if (internal_match_data == NULL) return PCRE2_ERROR_NOMEMORY;
- }
-
-else if (use_existing_match)
- {
- pcre2_general_context *gcontext = (mcontext == NULL)?
- (pcre2_general_context *)code :
- (pcre2_general_context *)mcontext;
- int pairs = (code->top_bracket + 1 < match_data->oveccount)?
- code->top_bracket + 1 : match_data->oveccount;
- internal_match_data = pcre2_match_data_create(match_data->oveccount,
- gcontext);
- if (internal_match_data == NULL) return PCRE2_ERROR_NOMEMORY;
- memcpy(internal_match_data, match_data, offsetof(pcre2_match_data, ovector)
- + 2*pairs*sizeof(PCRE2_SIZE));
- internal_match_data->heapframes = NULL;
- internal_match_data->heapframes_size = 0;
- match_data = internal_match_data;
- }
-
-/* Remember ovector details */
-
-ovector = pcre2_get_ovector_pointer(match_data);
-ovector_count = pcre2_get_ovector_count(match_data);
-
-/* Fixed things in the callout block */
-
-scb.version = 0;
-scb.input = subject;
-scb.output = (PCRE2_SPTR)buffer;
-scb.ovector = ovector;
-
-/* A NULL subject of zero length is treated as an empty string. */
-
-if (subject == NULL)
- {
- if (length != 0) return PCRE2_ERROR_NULL;
- subject = (PCRE2_SPTR)"";
- }
-
-/* Find length of zero-terminated subject */
-
-if (length == PCRE2_ZERO_TERMINATED)
- length = subject? PRIV(strlen)(subject) : 0;
-
-/* Check UTF replacement string if necessary. */
-
-#ifdef SUPPORT_UNICODE
-if (utf && (options & PCRE2_NO_UTF_CHECK) == 0)
- {
- rc = PRIV(valid_utf)(replacement, rlength, &(match_data->startchar));
- if (rc != 0)
- {
- match_data->leftchar = 0;
- goto EXIT;
- }
- }
-#endif /* SUPPORT_UNICODE */
-
-/* Save the substitute options and remove them from the match options. */
-
-suboptions = options & SUBSTITUTE_OPTIONS;
-options &= ~SUBSTITUTE_OPTIONS;
-
-/* Error if the start match offset is greater than the length of the subject. */
-
-if (start_offset > length)
- {
- match_data->leftchar = 0;
- rc = PCRE2_ERROR_BADOFFSET;
- goto EXIT;
- }
-
-/* Copy up to the start offset, unless only the replacement is required. */
-
-if (!replacement_only) CHECKMEMCPY(subject, start_offset);
-
-/* Loop for global substituting. If PCRE2_SUBSTITUTE_MATCHED is set, the first
-match is taken from the match_data that was passed in. */
-
-subs = 0;
-do
- {
- PCRE2_SPTR ptrstack[PTR_STACK_SIZE];
- uint32_t ptrstackptr = 0;
-
- if (use_existing_match)
- {
- rc = match_data->rc;
- use_existing_match = FALSE;
- }
- else rc = pcre2_match(code, subject, length, start_offset, options|goptions,
- match_data, mcontext);
-
-#ifdef SUPPORT_UNICODE
- if (utf) options |= PCRE2_NO_UTF_CHECK; /* Only need to check once */
-#endif
-
- /* Any error other than no match returns the error code. No match when not
- doing the special after-empty-match global rematch, or when at the end of the
- subject, breaks the global loop. Otherwise, advance the starting point by one
- character, copying it to the output, and try again. */
-
- if (rc < 0)
- {
- PCRE2_SIZE save_start;
-
- if (rc != PCRE2_ERROR_NOMATCH) goto EXIT;
- if (goptions == 0 || start_offset >= length) break;
-
- /* Advance by one code point. Then, if CRLF is a valid newline sequence and
- we have advanced into the middle of it, advance one more code point. In
- other words, do not start in the middle of CRLF, even if CR and LF on their
- own are valid newlines. */
-
- save_start = start_offset++;
- if (subject[start_offset-1] == CHAR_CR &&
- code->newline_convention != PCRE2_NEWLINE_CR &&
- code->newline_convention != PCRE2_NEWLINE_LF &&
- start_offset < length &&
- subject[start_offset] == CHAR_LF)
- start_offset++;
-
- /* Otherwise, in UTF mode, advance past any secondary code points. */
-
- else if ((code->overall_options & PCRE2_UTF) != 0)
- {
-#if PCRE2_CODE_UNIT_WIDTH == 8
- while (start_offset < length && (subject[start_offset] & 0xc0) == 0x80)
- start_offset++;
-#elif PCRE2_CODE_UNIT_WIDTH == 16
- while (start_offset < length &&
- (subject[start_offset] & 0xfc00) == 0xdc00)
- start_offset++;
-#endif
- }
-
- /* Copy what we have advanced past (unless not required), reset the special
- global options, and continue to the next match. */
-
- fraglength = start_offset - save_start;
- if (!replacement_only) CHECKMEMCPY(subject + save_start, fraglength);
- goptions = 0;
- continue;
- }
-
- /* Handle a successful match. Matches that use \K to end before they start
- or start before the current point in the subject are not supported. */
-
- if (ovector[1] < ovector[0] || ovector[0] < start_offset)
- {
- rc = PCRE2_ERROR_BADSUBSPATTERN;
- goto EXIT;
- }
-
- /* Check for the same match as previous. This is legitimate after matching an
- empty string that starts after the initial match offset. We have tried again
- at the match point in case the pattern is one like /(?<=\G.)/ which can never
- match at its starting point, so running the match achieves the bumpalong. If
- we do get the same (null) match at the original match point, it isn't such a
- pattern, so we now do the empty string magic. In all other cases, a repeat
- match should never occur. */
-
- if (ovecsave[0] == ovector[0] && ovecsave[1] == ovector[1])
- {
- if (ovector[0] == ovector[1] && ovecsave[2] != start_offset)
- {
- goptions = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;
- ovecsave[2] = start_offset;
- continue; /* Back to the top of the loop */
- }
- rc = PCRE2_ERROR_INTERNAL_DUPMATCH;
- goto EXIT;
- }
-
- /* Count substitutions with a paranoid check for integer overflow; surely no
- real call to this function would ever hit this! */
-
- if (subs == INT_MAX)
- {
- rc = PCRE2_ERROR_TOOMANYREPLACE;
- goto EXIT;
- }
- subs++;
-
- /* Copy the text leading up to the match (unless not required), and remember
- where the insert begins and how many ovector pairs are set. */
-
- if (rc == 0) rc = ovector_count;
- fraglength = ovector[0] - start_offset;
- if (!replacement_only) CHECKMEMCPY(subject + start_offset, fraglength);
- scb.output_offsets[0] = buff_offset;
- scb.oveccount = rc;
-
- /* Process the replacement string. If the entire replacement is literal, just
- copy it with length check. */
-
- ptr = replacement;
- if ((suboptions & PCRE2_SUBSTITUTE_LITERAL) != 0)
- {
- CHECKMEMCPY(ptr, rlength);
- }
-
- /* Within a non-literal replacement, which must be scanned character by
- character, local literal mode can be set by \Q, but only in extended mode
- when backslashes are being interpreted. In extended mode we must handle
- nested substrings that are to be reprocessed. */
-
- else for (;;)
- {
- uint32_t ch;
- unsigned int chlen;
-
- /* If at the end of a nested substring, pop the stack. */
-
- if (ptr >= repend)
- {
- if (ptrstackptr == 0) break; /* End of replacement string */
- repend = ptrstack[--ptrstackptr];
- ptr = ptrstack[--ptrstackptr];
- continue;
- }
-
- /* Handle the next character */
-
- if (escaped_literal)
- {
- if (ptr[0] == CHAR_BACKSLASH && ptr < repend - 1 && ptr[1] == CHAR_E)
- {
- escaped_literal = FALSE;
- ptr += 2;
- continue;
- }
- goto LOADLITERAL;
- }
-
- /* Not in literal mode. */
-
- if (*ptr == CHAR_DOLLAR_SIGN)
- {
- int group, n;
- uint32_t special = 0;
- BOOL inparens;
- BOOL star;
- PCRE2_SIZE sublength;
- PCRE2_SPTR text1_start = NULL;
- PCRE2_SPTR text1_end = NULL;
- PCRE2_SPTR text2_start = NULL;
- PCRE2_SPTR text2_end = NULL;
- PCRE2_UCHAR next;
- PCRE2_UCHAR name[33];
-
- if (++ptr >= repend) goto BAD;
- if ((next = *ptr) == CHAR_DOLLAR_SIGN) goto LOADLITERAL;
-
- group = -1;
- n = 0;
- inparens = FALSE;
- star = FALSE;
-
- if (next == CHAR_LEFT_CURLY_BRACKET)
- {
- if (++ptr >= repend) goto BAD;
- next = *ptr;
- inparens = TRUE;
- }
-
- if (next == CHAR_ASTERISK)
- {
- if (++ptr >= repend) goto BAD;
- next = *ptr;
- star = TRUE;
- }
-
- if (!star && next >= CHAR_0 && next <= CHAR_9)
- {
- group = next - CHAR_0;
- while (++ptr < repend)
- {
- next = *ptr;
- if (next < CHAR_0 || next > CHAR_9) break;
- group = group * 10 + next - CHAR_0;
-
- /* A check for a number greater than the hightest captured group
- is sufficient here; no need for a separate overflow check. If unknown
- groups are to be treated as unset, just skip over any remaining
- digits and carry on. */
-
- if (group > code->top_bracket)
- {
- if ((suboptions & PCRE2_SUBSTITUTE_UNKNOWN_UNSET) != 0)
- {
- while (++ptr < repend && *ptr >= CHAR_0 && *ptr <= CHAR_9);
- break;
- }
- else
- {
- rc = PCRE2_ERROR_NOSUBSTRING;
- goto PTREXIT;
- }
- }
- }
- }
- else
- {
- const uint8_t *ctypes = code->tables + ctypes_offset;
- while (MAX_255(next) && (ctypes[next] & ctype_word) != 0)
- {
- name[n++] = next;
- if (n > 32) goto BAD;
- if (++ptr >= repend) break;
- next = *ptr;
- }
- if (n == 0) goto BAD;
- name[n] = 0;
- }
-
- /* In extended mode we recognize ${name:+set text:unset text} and
- ${name:-default text}. */
-
- if (inparens)
- {
- if ((suboptions & PCRE2_SUBSTITUTE_EXTENDED) != 0 &&
- !star && ptr < repend - 2 && next == CHAR_COLON)
- {
- special = *(++ptr);
- if (special != CHAR_PLUS && special != CHAR_MINUS)
- {
- rc = PCRE2_ERROR_BADSUBSTITUTION;
- goto PTREXIT;
- }
-
- text1_start = ++ptr;
- rc = find_text_end(code, &ptr, repend, special == CHAR_MINUS);
- if (rc != 0) goto PTREXIT;
- text1_end = ptr;
-
- if (special == CHAR_PLUS && *ptr == CHAR_COLON)
- {
- text2_start = ++ptr;
- rc = find_text_end(code, &ptr, repend, TRUE);
- if (rc != 0) goto PTREXIT;
- text2_end = ptr;
- }
- }
-
- else
- {
- if (ptr >= repend || *ptr != CHAR_RIGHT_CURLY_BRACKET)
- {
- rc = PCRE2_ERROR_REPMISSINGBRACE;
- goto PTREXIT;
- }
- }
-
- ptr++;
- }
-
- /* Have found a syntactically correct group number or name, or *name.
- Only *MARK is currently recognized. */
-
- if (star)
- {
- if (PRIV(strcmp_c8)(name, STRING_MARK) == 0)
- {
- PCRE2_SPTR mark = pcre2_get_mark(match_data);
- if (mark != NULL)
- {
- PCRE2_SPTR mark_start = mark;
- while (*mark != 0) mark++;
- fraglength = mark - mark_start;
- CHECKMEMCPY(mark_start, fraglength);
- }
- }
- else goto BAD;
- }
-
- /* Substitute the contents of a group. We don't use substring_copy
- functions any more, in order to support case forcing. */
-
- else
- {
- PCRE2_SPTR subptr, subptrend;
-
- /* Find a number for a named group. In case there are duplicate names,
- search for the first one that is set. If the name is not found when
- PCRE2_SUBSTITUTE_UNKNOWN_EMPTY is set, set the group number to a
- non-existent group. */
-
- if (group < 0)
- {
- PCRE2_SPTR first, last, entry;
- rc = pcre2_substring_nametable_scan(code, name, &first, &last);
- if (rc == PCRE2_ERROR_NOSUBSTRING &&
- (suboptions & PCRE2_SUBSTITUTE_UNKNOWN_UNSET) != 0)
- {
- group = code->top_bracket + 1;
- }
- else
- {
- if (rc < 0) goto PTREXIT;
- for (entry = first; entry <= last; entry += rc)
- {
- uint32_t ng = GET2(entry, 0);
- if (ng < ovector_count)
- {
- if (group < 0) group = ng; /* First in ovector */
- if (ovector[ng*2] != PCRE2_UNSET)
- {
- group = ng; /* First that is set */
- break;
- }
- }
- }
-
- /* If group is still negative, it means we did not find a group
- that is in the ovector. Just set the first group. */
-
- if (group < 0) group = GET2(first, 0);
- }
- }
-
- /* We now have a group that is identified by number. Find the length of
- the captured string. If a group in a non-special substitution is unset
- when PCRE2_SUBSTITUTE_UNSET_EMPTY is set, substitute nothing. */
-
- rc = pcre2_substring_length_bynumber(match_data, group, &sublength);
- if (rc < 0)
- {
- if (rc == PCRE2_ERROR_NOSUBSTRING &&
- (suboptions & PCRE2_SUBSTITUTE_UNKNOWN_UNSET) != 0)
- {
- rc = PCRE2_ERROR_UNSET;
- }
- if (rc != PCRE2_ERROR_UNSET) goto PTREXIT; /* Non-unset errors */
- if (special == 0) /* Plain substitution */
- {
- if ((suboptions & PCRE2_SUBSTITUTE_UNSET_EMPTY) != 0) continue;
- goto PTREXIT; /* Else error */
- }
- }
-
- /* If special is '+' we have a 'set' and possibly an 'unset' text,
- both of which are reprocessed when used. If special is '-' we have a
- default text for when the group is unset; it must be reprocessed. */
-
- if (special != 0)
- {
- if (special == CHAR_MINUS)
- {
- if (rc == 0) goto LITERAL_SUBSTITUTE;
- text2_start = text1_start;
- text2_end = text1_end;
- }
-
- if (ptrstackptr >= PTR_STACK_SIZE) goto BAD;
- ptrstack[ptrstackptr++] = ptr;
- ptrstack[ptrstackptr++] = repend;
-
- if (rc == 0)
- {
- ptr = text1_start;
- repend = text1_end;
- }
- else
- {
- ptr = text2_start;
- repend = text2_end;
- }
- continue;
- }
-
- /* Otherwise we have a literal substitution of a group's contents. */
-
- LITERAL_SUBSTITUTE:
- subptr = subject + ovector[group*2];
- subptrend = subject + ovector[group*2 + 1];
-
- /* Substitute a literal string, possibly forcing alphabetic case. */
-
- while (subptr < subptrend)
- {
- GETCHARINCTEST(ch, subptr);
- if (forcecase != 0)
- {
-#ifdef SUPPORT_UNICODE
- if (utf || ucp)
- {
- uint32_t type = UCD_CHARTYPE(ch);
- if (PRIV(ucp_gentype)[type] == ucp_L &&
- type != ((forcecase > 0)? ucp_Lu : ucp_Ll))
- ch = UCD_OTHERCASE(ch);
- }
- else
-#endif
- {
- if (((code->tables + cbits_offset +
- ((forcecase > 0)? cbit_upper:cbit_lower)
- )[ch/8] & (1u << (ch%8))) == 0)
- ch = (code->tables + fcc_offset)[ch];
- }
- forcecase = forcecasereset;
- }
-
-#ifdef SUPPORT_UNICODE
- if (utf) chlen = PRIV(ord2utf)(ch, temp); else
-#endif
- {
- temp[0] = ch;
- chlen = 1;
- }
- CHECKMEMCPY(temp, chlen);
- }
- }
- }
-
- /* Handle an escape sequence in extended mode. We can use check_escape()
- to process \Q, \E, \c, \o, \x and \ followed by non-alphanumerics, but
- the case-forcing escapes are not supported in pcre2_compile() so must be
- recognized here. */
-
- else if ((suboptions & PCRE2_SUBSTITUTE_EXTENDED) != 0 &&
- *ptr == CHAR_BACKSLASH)
- {
- int errorcode;
-
- if (ptr < repend - 1) switch (ptr[1])
- {
- case CHAR_L:
- forcecase = forcecasereset = -1;
- ptr += 2;
- continue;
-
- case CHAR_l:
- forcecase = -1;
- forcecasereset = 0;
- ptr += 2;
- continue;
-
- case CHAR_U:
- forcecase = forcecasereset = 1;
- ptr += 2;
- continue;
-
- case CHAR_u:
- forcecase = 1;
- forcecasereset = 0;
- ptr += 2;
- continue;
-
- default:
- break;
- }
-
- ptr++; /* Point after \ */
- rc = PRIV(check_escape)(&ptr, repend, &ch, &errorcode,
- code->overall_options, code->extra_options, FALSE, NULL);
- if (errorcode != 0) goto BADESCAPE;
-
- switch(rc)
- {
- case ESC_E:
- forcecase = forcecasereset = 0;
- continue;
-
- case ESC_Q:
- escaped_literal = TRUE;
- continue;
-
- case 0: /* Data character */
- goto LITERAL;
-
- default:
- goto BADESCAPE;
- }
- }
-
- /* Handle a literal code unit */
-
- else
- {
- LOADLITERAL:
- GETCHARINCTEST(ch, ptr); /* Get character value, increment pointer */
-
- LITERAL:
- if (forcecase != 0)
- {
-#ifdef SUPPORT_UNICODE
- if (utf || ucp)
- {
- uint32_t type = UCD_CHARTYPE(ch);
- if (PRIV(ucp_gentype)[type] == ucp_L &&
- type != ((forcecase > 0)? ucp_Lu : ucp_Ll))
- ch = UCD_OTHERCASE(ch);
- }
- else
-#endif
- {
- if (((code->tables + cbits_offset +
- ((forcecase > 0)? cbit_upper:cbit_lower)
- )[ch/8] & (1u << (ch%8))) == 0)
- ch = (code->tables + fcc_offset)[ch];
- }
- forcecase = forcecasereset;
- }
-
-#ifdef SUPPORT_UNICODE
- if (utf) chlen = PRIV(ord2utf)(ch, temp); else
-#endif
- {
- temp[0] = ch;
- chlen = 1;
- }
- CHECKMEMCPY(temp, chlen);
- } /* End handling a literal code unit */
- } /* End of loop for scanning the replacement. */
-
- /* The replacement has been copied to the output, or its size has been
- remembered. Do the callout if there is one and we have done an actual
- replacement. */
-
- if (!overflowed && mcontext != NULL && mcontext->substitute_callout != NULL)
- {
- scb.subscount = subs;
- scb.output_offsets[1] = buff_offset;
- rc = mcontext->substitute_callout(&scb, mcontext->substitute_callout_data);
-
- /* A non-zero return means cancel this substitution. Instead, copy the
- matched string fragment. */
-
- if (rc != 0)
- {
- PCRE2_SIZE newlength = scb.output_offsets[1] - scb.output_offsets[0];
- PCRE2_SIZE oldlength = ovector[1] - ovector[0];
-
- buff_offset -= newlength;
- lengthleft += newlength;
- if (!replacement_only) CHECKMEMCPY(subject + ovector[0], oldlength);
-
- /* A negative return means do not do any more. */
-
- if (rc < 0) suboptions &= (~PCRE2_SUBSTITUTE_GLOBAL);
- }
- }
-
- /* Save the details of this match. See above for how this data is used. If we
- matched an empty string, do the magic for global matches. Update the start
- offset to point to the rest of the subject string. If we re-used an existing
- match for the first match, switch to the internal match data block. */
-
- ovecsave[0] = ovector[0];
- ovecsave[1] = ovector[1];
- ovecsave[2] = start_offset;
-
- goptions = (ovector[0] != ovector[1] || ovector[0] > start_offset)? 0 :
- PCRE2_ANCHORED|PCRE2_NOTEMPTY_ATSTART;
- start_offset = ovector[1];
- } while ((suboptions & PCRE2_SUBSTITUTE_GLOBAL) != 0); /* Repeat "do" loop */
-
-/* Copy the rest of the subject unless not required, and terminate the output
-with a binary zero. */
-
-if (!replacement_only)
- {
- fraglength = length - start_offset;
- CHECKMEMCPY(subject + start_offset, fraglength);
- }
-
-temp[0] = 0;
-CHECKMEMCPY(temp, 1);
-
-/* If overflowed is set it means the PCRE2_SUBSTITUTE_OVERFLOW_LENGTH is set,
-and matching has carried on after a full buffer, in order to compute the length
-needed. Otherwise, an overflow generates an immediate error return. */
-
-if (overflowed)
- {
- rc = PCRE2_ERROR_NOMEMORY;
- *blength = buff_length + extra_needed;
- }
-
-/* After a successful execution, return the number of substitutions and set the
-length of buffer used, excluding the trailing zero. */
-
-else
- {
- rc = subs;
- *blength = buff_offset - 1;
- }
-
-EXIT:
-if (internal_match_data != NULL) pcre2_match_data_free(internal_match_data);
- else match_data->rc = rc;
-return rc;
-
-NOROOM:
-rc = PCRE2_ERROR_NOMEMORY;
-goto EXIT;
-
-BAD:
-rc = PCRE2_ERROR_BADREPLACEMENT;
-goto PTREXIT;
-
-BADESCAPE:
-rc = PCRE2_ERROR_BADREPESCAPE;
-
-PTREXIT:
-*blength = (PCRE2_SIZE)(ptr - replacement);
-goto EXIT;
-}
-
-/* End of pcre2_substitute.c */
diff --git a/contrib/libs/pcre2/src/pcre2_substring.c b/contrib/libs/pcre2/src/pcre2_substring.c
deleted file mode 100644
index 62b509da7b..0000000000
--- a/contrib/libs/pcre2/src/pcre2_substring.c
+++ /dev/null
@@ -1,547 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2018 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-#include "pcre2_internal.h"
-
-
-
-/*************************************************
-* Copy named captured string to given buffer *
-*************************************************/
-
-/* This function copies a single captured substring into a given buffer,
-identifying it by name. If the regex permits duplicate names, the first
-substring that is set is chosen.
-
-Arguments:
- match_data points to the match data
- stringname the name of the required substring
- buffer where to put the substring
- sizeptr the size of the buffer, updated to the size of the substring
-
-Returns: if successful: zero
- if not successful, a negative error code:
- (1) an error from nametable_scan()
- (2) an error from copy_bynumber()
- (3) PCRE2_ERROR_UNAVAILABLE: no group is in ovector
- (4) PCRE2_ERROR_UNSET: all named groups in ovector are unset
-*/
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_substring_copy_byname(pcre2_match_data *match_data, PCRE2_SPTR stringname,
- PCRE2_UCHAR *buffer, PCRE2_SIZE *sizeptr)
-{
-PCRE2_SPTR first, last, entry;
-int failrc, entrysize;
-if (match_data->matchedby == PCRE2_MATCHEDBY_DFA_INTERPRETER)
- return PCRE2_ERROR_DFA_UFUNC;
-entrysize = pcre2_substring_nametable_scan(match_data->code, stringname,
- &first, &last);
-if (entrysize < 0) return entrysize;
-failrc = PCRE2_ERROR_UNAVAILABLE;
-for (entry = first; entry <= last; entry += entrysize)
- {
- uint32_t n = GET2(entry, 0);
- if (n < match_data->oveccount)
- {
- if (match_data->ovector[n*2] != PCRE2_UNSET)
- return pcre2_substring_copy_bynumber(match_data, n, buffer, sizeptr);
- failrc = PCRE2_ERROR_UNSET;
- }
- }
-return failrc;
-}
-
-
-
-/*************************************************
-* Copy numbered captured string to given buffer *
-*************************************************/
-
-/* This function copies a single captured substring into a given buffer,
-identifying it by number.
-
-Arguments:
- match_data points to the match data
- stringnumber the number of the required substring
- buffer where to put the substring
- sizeptr the size of the buffer, updated to the size of the substring
-
-Returns: if successful: 0
- if not successful, a negative error code:
- PCRE2_ERROR_NOMEMORY: buffer too small
- PCRE2_ERROR_NOSUBSTRING: no such substring
- PCRE2_ERROR_UNAVAILABLE: ovector too small
- PCRE2_ERROR_UNSET: substring is not set
-*/
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_substring_copy_bynumber(pcre2_match_data *match_data,
- uint32_t stringnumber, PCRE2_UCHAR *buffer, PCRE2_SIZE *sizeptr)
-{
-int rc;
-PCRE2_SIZE size;
-rc = pcre2_substring_length_bynumber(match_data, stringnumber, &size);
-if (rc < 0) return rc;
-if (size + 1 > *sizeptr) return PCRE2_ERROR_NOMEMORY;
-memcpy(buffer, match_data->subject + match_data->ovector[stringnumber*2],
- CU2BYTES(size));
-buffer[size] = 0;
-*sizeptr = size;
-return 0;
-}
-
-
-
-/*************************************************
-* Extract named captured string *
-*************************************************/
-
-/* This function copies a single captured substring, identified by name, into
-new memory. If the regex permits duplicate names, the first substring that is
-set is chosen.
-
-Arguments:
- match_data pointer to match_data
- stringname the name of the required substring
- stringptr where to put the pointer to the new memory
- sizeptr where to put the length of the substring
-
-Returns: if successful: zero
- if not successful, a negative value:
- (1) an error from nametable_scan()
- (2) an error from get_bynumber()
- (3) PCRE2_ERROR_UNAVAILABLE: no group is in ovector
- (4) PCRE2_ERROR_UNSET: all named groups in ovector are unset
-*/
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_substring_get_byname(pcre2_match_data *match_data,
- PCRE2_SPTR stringname, PCRE2_UCHAR **stringptr, PCRE2_SIZE *sizeptr)
-{
-PCRE2_SPTR first, last, entry;
-int failrc, entrysize;
-if (match_data->matchedby == PCRE2_MATCHEDBY_DFA_INTERPRETER)
- return PCRE2_ERROR_DFA_UFUNC;
-entrysize = pcre2_substring_nametable_scan(match_data->code, stringname,
- &first, &last);
-if (entrysize < 0) return entrysize;
-failrc = PCRE2_ERROR_UNAVAILABLE;
-for (entry = first; entry <= last; entry += entrysize)
- {
- uint32_t n = GET2(entry, 0);
- if (n < match_data->oveccount)
- {
- if (match_data->ovector[n*2] != PCRE2_UNSET)
- return pcre2_substring_get_bynumber(match_data, n, stringptr, sizeptr);
- failrc = PCRE2_ERROR_UNSET;
- }
- }
-return failrc;
-}
-
-
-
-/*************************************************
-* Extract captured string to new memory *
-*************************************************/
-
-/* This function copies a single captured substring into a piece of new
-memory.
-
-Arguments:
- match_data points to match data
- stringnumber the number of the required substring
- stringptr where to put a pointer to the new memory
- sizeptr where to put the size of the substring
-
-Returns: if successful: 0
- if not successful, a negative error code:
- PCRE2_ERROR_NOMEMORY: failed to get memory
- PCRE2_ERROR_NOSUBSTRING: no such substring
- PCRE2_ERROR_UNAVAILABLE: ovector too small
- PCRE2_ERROR_UNSET: substring is not set
-*/
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_substring_get_bynumber(pcre2_match_data *match_data,
- uint32_t stringnumber, PCRE2_UCHAR **stringptr, PCRE2_SIZE *sizeptr)
-{
-int rc;
-PCRE2_SIZE size;
-PCRE2_UCHAR *yield;
-rc = pcre2_substring_length_bynumber(match_data, stringnumber, &size);
-if (rc < 0) return rc;
-yield = PRIV(memctl_malloc)(sizeof(pcre2_memctl) +
- (size + 1)*PCRE2_CODE_UNIT_WIDTH, (pcre2_memctl *)match_data);
-if (yield == NULL) return PCRE2_ERROR_NOMEMORY;
-yield = (PCRE2_UCHAR *)(((char *)yield) + sizeof(pcre2_memctl));
-memcpy(yield, match_data->subject + match_data->ovector[stringnumber*2],
- CU2BYTES(size));
-yield[size] = 0;
-*stringptr = yield;
-*sizeptr = size;
-return 0;
-}
-
-
-
-/*************************************************
-* Free memory obtained by get_substring *
-*************************************************/
-
-/*
-Argument: the result of a previous pcre2_substring_get_byxxx()
-Returns: nothing
-*/
-
-PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
-pcre2_substring_free(PCRE2_UCHAR *string)
-{
-if (string != NULL)
- {
- pcre2_memctl *memctl = (pcre2_memctl *)((char *)string - sizeof(pcre2_memctl));
- memctl->free(memctl, memctl->memory_data);
- }
-}
-
-
-
-/*************************************************
-* Get length of a named substring *
-*************************************************/
-
-/* This function returns the length of a named captured substring. If the regex
-permits duplicate names, the first substring that is set is chosen.
-
-Arguments:
- match_data pointer to match data
- stringname the name of the required substring
- sizeptr where to put the length
-
-Returns: 0 if successful, else a negative error number
-*/
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_substring_length_byname(pcre2_match_data *match_data,
- PCRE2_SPTR stringname, PCRE2_SIZE *sizeptr)
-{
-PCRE2_SPTR first, last, entry;
-int failrc, entrysize;
-if (match_data->matchedby == PCRE2_MATCHEDBY_DFA_INTERPRETER)
- return PCRE2_ERROR_DFA_UFUNC;
-entrysize = pcre2_substring_nametable_scan(match_data->code, stringname,
- &first, &last);
-if (entrysize < 0) return entrysize;
-failrc = PCRE2_ERROR_UNAVAILABLE;
-for (entry = first; entry <= last; entry += entrysize)
- {
- uint32_t n = GET2(entry, 0);
- if (n < match_data->oveccount)
- {
- if (match_data->ovector[n*2] != PCRE2_UNSET)
- return pcre2_substring_length_bynumber(match_data, n, sizeptr);
- failrc = PCRE2_ERROR_UNSET;
- }
- }
-return failrc;
-}
-
-
-
-/*************************************************
-* Get length of a numbered substring *
-*************************************************/
-
-/* This function returns the length of a captured substring. If the start is
-beyond the end (which can happen when \K is used in an assertion), it sets the
-length to zero.
-
-Arguments:
- match_data pointer to match data
- stringnumber the number of the required substring
- sizeptr where to put the length, if not NULL
-
-Returns: if successful: 0
- if not successful, a negative error code:
- PCRE2_ERROR_NOSUBSTRING: no such substring
- PCRE2_ERROR_UNAVAILABLE: ovector is too small
- PCRE2_ERROR_UNSET: substring is not set
-*/
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_substring_length_bynumber(pcre2_match_data *match_data,
- uint32_t stringnumber, PCRE2_SIZE *sizeptr)
-{
-PCRE2_SIZE left, right;
-int count = match_data->rc;
-if (count == PCRE2_ERROR_PARTIAL)
- {
- if (stringnumber > 0) return PCRE2_ERROR_PARTIAL;
- count = 0;
- }
-else if (count < 0) return count; /* Match failed */
-
-if (match_data->matchedby != PCRE2_MATCHEDBY_DFA_INTERPRETER)
- {
- if (stringnumber > match_data->code->top_bracket)
- return PCRE2_ERROR_NOSUBSTRING;
- if (stringnumber >= match_data->oveccount)
- return PCRE2_ERROR_UNAVAILABLE;
- if (match_data->ovector[stringnumber*2] == PCRE2_UNSET)
- return PCRE2_ERROR_UNSET;
- }
-else /* Matched using pcre2_dfa_match() */
- {
- if (stringnumber >= match_data->oveccount) return PCRE2_ERROR_UNAVAILABLE;
- if (count != 0 && stringnumber >= (uint32_t)count) return PCRE2_ERROR_UNSET;
- }
-
-left = match_data->ovector[stringnumber*2];
-right = match_data->ovector[stringnumber*2+1];
-if (sizeptr != NULL) *sizeptr = (left > right)? 0 : right - left;
-return 0;
-}
-
-
-
-/*************************************************
-* Extract all captured strings to new memory *
-*************************************************/
-
-/* This function gets one chunk of memory and builds a list of pointers and all
-the captured substrings in it. A NULL pointer is put on the end of the list.
-The substrings are zero-terminated, but also, if the final argument is
-non-NULL, a list of lengths is also returned. This allows binary data to be
-handled.
-
-Arguments:
- match_data points to the match data
- listptr set to point to the list of pointers
- lengthsptr set to point to the list of lengths (may be NULL)
-
-Returns: if successful: 0
- if not successful, a negative error code:
- PCRE2_ERROR_NOMEMORY: failed to get memory,
- or a match failure code
-*/
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_substring_list_get(pcre2_match_data *match_data, PCRE2_UCHAR ***listptr,
- PCRE2_SIZE **lengthsptr)
-{
-int i, count, count2;
-PCRE2_SIZE size;
-PCRE2_SIZE *lensp;
-pcre2_memctl *memp;
-PCRE2_UCHAR **listp;
-PCRE2_UCHAR *sp;
-PCRE2_SIZE *ovector;
-
-if ((count = match_data->rc) < 0) return count; /* Match failed */
-if (count == 0) count = match_data->oveccount; /* Ovector too small */
-
-count2 = 2*count;
-ovector = match_data->ovector;
-size = sizeof(pcre2_memctl) + sizeof(PCRE2_UCHAR *); /* For final NULL */
-if (lengthsptr != NULL) size += sizeof(PCRE2_SIZE) * count; /* For lengths */
-
-for (i = 0; i < count2; i += 2)
- {
- size += sizeof(PCRE2_UCHAR *) + CU2BYTES(1);
- if (ovector[i+1] > ovector[i]) size += CU2BYTES(ovector[i+1] - ovector[i]);
- }
-
-memp = PRIV(memctl_malloc)(size, (pcre2_memctl *)match_data);
-if (memp == NULL) return PCRE2_ERROR_NOMEMORY;
-
-*listptr = listp = (PCRE2_UCHAR **)((char *)memp + sizeof(pcre2_memctl));
-lensp = (PCRE2_SIZE *)((char *)listp + sizeof(PCRE2_UCHAR *) * (count + 1));
-
-if (lengthsptr == NULL)
- {
- sp = (PCRE2_UCHAR *)lensp;
- lensp = NULL;
- }
-else
- {
- *lengthsptr = lensp;
- sp = (PCRE2_UCHAR *)((char *)lensp + sizeof(PCRE2_SIZE) * count);
- }
-
-for (i = 0; i < count2; i += 2)
- {
- size = (ovector[i+1] > ovector[i])? (ovector[i+1] - ovector[i]) : 0;
-
- /* Size == 0 includes the case when the capture is unset. Avoid adding
- PCRE2_UNSET to match_data->subject because it overflows, even though with
- zero size calling memcpy() is harmless. */
-
- if (size != 0) memcpy(sp, match_data->subject + ovector[i], CU2BYTES(size));
- *listp++ = sp;
- if (lensp != NULL) *lensp++ = size;
- sp += size;
- *sp++ = 0;
- }
-
-*listp = NULL;
-return 0;
-}
-
-
-
-/*************************************************
-* Free memory obtained by substring_list_get *
-*************************************************/
-
-/*
-Argument: the result of a previous pcre2_substring_list_get()
-Returns: nothing
-*/
-
-PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
-pcre2_substring_list_free(PCRE2_SPTR *list)
-{
-if (list != NULL)
- {
- pcre2_memctl *memctl = (pcre2_memctl *)((char *)list - sizeof(pcre2_memctl));
- memctl->free(memctl, memctl->memory_data);
- }
-}
-
-
-
-/*************************************************
-* Find (multiple) entries for named string *
-*************************************************/
-
-/* This function scans the nametable for a given name, using binary chop. It
-returns either two pointers to the entries in the table, or, if no pointers are
-given, the number of a unique group with the given name. If duplicate names are
-permitted, and the name is not unique, an error is generated.
-
-Arguments:
- code the compiled regex
- stringname the name whose entries required
- firstptr where to put the pointer to the first entry
- lastptr where to put the pointer to the last entry
-
-Returns: PCRE2_ERROR_NOSUBSTRING if the name is not found
- otherwise, if firstptr and lastptr are NULL:
- a group number for a unique substring
- else PCRE2_ERROR_NOUNIQUESUBSTRING
- otherwise:
- the length of each entry, having set firstptr and lastptr
-*/
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_substring_nametable_scan(const pcre2_code *code, PCRE2_SPTR stringname,
- PCRE2_SPTR *firstptr, PCRE2_SPTR *lastptr)
-{
-uint16_t bot = 0;
-uint16_t top = code->name_count;
-uint16_t entrysize = code->name_entry_size;
-PCRE2_SPTR nametable = (PCRE2_SPTR)((char *)code + sizeof(pcre2_real_code));
-
-while (top > bot)
- {
- uint16_t mid = (top + bot) / 2;
- PCRE2_SPTR entry = nametable + entrysize*mid;
- int c = PRIV(strcmp)(stringname, entry + IMM2_SIZE);
- if (c == 0)
- {
- PCRE2_SPTR first;
- PCRE2_SPTR last;
- PCRE2_SPTR lastentry;
- lastentry = nametable + entrysize * (code->name_count - 1);
- first = last = entry;
- while (first > nametable)
- {
- if (PRIV(strcmp)(stringname, (first - entrysize + IMM2_SIZE)) != 0) break;
- first -= entrysize;
- }
- while (last < lastentry)
- {
- if (PRIV(strcmp)(stringname, (last + entrysize + IMM2_SIZE)) != 0) break;
- last += entrysize;
- }
- if (firstptr == NULL) return (first == last)?
- (int)GET2(entry, 0) : PCRE2_ERROR_NOUNIQUESUBSTRING;
- *firstptr = first;
- *lastptr = last;
- return entrysize;
- }
- if (c > 0) bot = mid + 1; else top = mid;
- }
-
-return PCRE2_ERROR_NOSUBSTRING;
-}
-
-
-/*************************************************
-* Find number for named string *
-*************************************************/
-
-/* This function is a convenience wrapper for pcre2_substring_nametable_scan()
-when it is known that names are unique. If there are duplicate names, it is not
-defined which number is returned.
-
-Arguments:
- code the compiled regex
- stringname the name whose number is required
-
-Returns: the number of the named parenthesis, or a negative number
- PCRE2_ERROR_NOSUBSTRING if not found
- PCRE2_ERROR_NOUNIQUESUBSTRING if not unique
-*/
-
-PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_substring_number_from_name(const pcre2_code *code,
- PCRE2_SPTR stringname)
-{
-return pcre2_substring_nametable_scan(code, stringname, NULL, NULL);
-}
-
-/* End of pcre2_substring.c */
diff --git a/contrib/libs/pcre2/src/pcre2_tables.c b/contrib/libs/pcre2/src/pcre2_tables.c
deleted file mode 100644
index 701a4f7c01..0000000000
--- a/contrib/libs/pcre2/src/pcre2_tables.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2021 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-/* This module contains some fixed tables that are used by more than one of the
-PCRE2 code modules. The tables are also #included by the pcre2test program,
-which uses macros to change their names from _pcre2_xxx to xxxx, thereby
-avoiding name clashes with the library. In this case, PCRE2_PCRE2TEST is
-defined. */
-
-#ifndef PCRE2_PCRE2TEST /* We're compiling the library */
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-#include "pcre2_internal.h"
-#endif /* PCRE2_PCRE2TEST */
-
-/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that
-the definition is next to the definition of the opcodes in pcre2_internal.h.
-This is mode-dependent, so it is skipped when this file is included by
-pcre2test. */
-
-#ifndef PCRE2_PCRE2TEST
-const uint8_t PRIV(OP_lengths)[] = { OP_LENGTHS };
-#endif
-
-/* Tables of horizontal and vertical whitespace characters, suitable for
-adding to classes. */
-
-const uint32_t PRIV(hspace_list)[] = { HSPACE_LIST };
-const uint32_t PRIV(vspace_list)[] = { VSPACE_LIST };
-
-/* These tables are the pairs of delimiters that are valid for callout string
-arguments. For each starting delimiter there must be a matching ending
-delimiter, which in fact is different only for bracket-like delimiters. */
-
-const uint32_t PRIV(callout_start_delims)[] = {
- CHAR_GRAVE_ACCENT, CHAR_APOSTROPHE, CHAR_QUOTATION_MARK,
- CHAR_CIRCUMFLEX_ACCENT, CHAR_PERCENT_SIGN, CHAR_NUMBER_SIGN,
- CHAR_DOLLAR_SIGN, CHAR_LEFT_CURLY_BRACKET, 0 };
-
-const uint32_t PRIV(callout_end_delims[]) = {
- CHAR_GRAVE_ACCENT, CHAR_APOSTROPHE, CHAR_QUOTATION_MARK,
- CHAR_CIRCUMFLEX_ACCENT, CHAR_PERCENT_SIGN, CHAR_NUMBER_SIGN,
- CHAR_DOLLAR_SIGN, CHAR_RIGHT_CURLY_BRACKET, 0 };
-
-
-/*************************************************
-* Tables for UTF-8 support *
-*************************************************/
-
-/* These tables are required by pcre2test in 16- or 32-bit mode, as well
-as for the library in 8-bit mode, because pcre2test uses UTF-8 internally for
-handling wide characters. */
-
-#if defined PCRE2_PCRE2TEST || \
- (defined SUPPORT_UNICODE && \
- defined PCRE2_CODE_UNIT_WIDTH && \
- PCRE2_CODE_UNIT_WIDTH == 8)
-
-/* These are the breakpoints for different numbers of bytes in a UTF-8
-character. */
-
-const int PRIV(utf8_table1)[] =
- { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff};
-
-const int PRIV(utf8_table1_size) = sizeof(PRIV(utf8_table1)) / sizeof(int);
-
-/* These are the indicator bits and the mask for the data bits to set in the
-first byte of a character, indexed by the number of additional bytes. */
-
-const int PRIV(utf8_table2)[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc};
-const int PRIV(utf8_table3)[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
-
-/* Table of the number of extra bytes, indexed by the first byte masked with
-0x3f. The highest number for a valid UTF-8 first byte is in fact 0x3d. */
-
-const uint8_t PRIV(utf8_table4)[] = {
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
- 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };
-
-#endif /* UTF-8 support needed */
-
-/* Tables concerned with Unicode properties are relevant only when Unicode
-support is enabled. See also the pcre2_ucptables.c file, which is generated by
-a Python script from Unicode data files. */
-
-#ifdef SUPPORT_UNICODE
-
-/* Table to translate from particular type value to the general value. */
-
-const uint32_t PRIV(ucp_gentype)[] = {
- ucp_C, ucp_C, ucp_C, ucp_C, ucp_C, /* Cc, Cf, Cn, Co, Cs */
- ucp_L, ucp_L, ucp_L, ucp_L, ucp_L, /* Ll, Lu, Lm, Lo, Lt */
- ucp_M, ucp_M, ucp_M, /* Mc, Me, Mn */
- ucp_N, ucp_N, ucp_N, /* Nd, Nl, No */
- ucp_P, ucp_P, ucp_P, ucp_P, ucp_P, /* Pc, Pd, Pe, Pf, Pi */
- ucp_P, ucp_P, /* Ps, Po */
- ucp_S, ucp_S, ucp_S, ucp_S, /* Sc, Sk, Sm, So */
- ucp_Z, ucp_Z, ucp_Z /* Zl, Zp, Zs */
-};
-
-/* This table encodes the rules for finding the end of an extended grapheme
-cluster. Every code point has a grapheme break property which is one of the
-ucp_gbXX values defined in pcre2_ucp.h. These changed between Unicode versions
-10 and 11. The 2-dimensional table is indexed by the properties of two adjacent
-code points. The left property selects a word from the table, and the right
-property selects a bit from that word like this:
-
- PRIV(ucp_gbtable)[left-property] & (1u << right-property)
-
-The value is non-zero if a grapheme break is NOT permitted between the relevant
-two code points. The breaking rules are as follows:
-
-1. Break at the start and end of text (pretty obviously).
-
-2. Do not break between a CR and LF; otherwise, break before and after
- controls.
-
-3. Do not break Hangul syllable sequences, the rules for which are:
-
- L may be followed by L, V, LV or LVT
- LV or V may be followed by V or T
- LVT or T may be followed by T
-
-4. Do not break before extending characters or zero-width-joiner (ZWJ).
-
-The following rules are only for extended grapheme clusters (but that's what we
-are implementing).
-
-5. Do not break before SpacingMarks.
-
-6. Do not break after Prepend characters.
-
-7. Do not break within emoji modifier sequences or emoji zwj sequences. That
- is, do not break between characters with the Extended_Pictographic property.
- Extend and ZWJ characters are allowed between the characters; this cannot be
- represented in this table, the code has to deal with it.
-
-8. Do not break within emoji flag sequences. That is, do not break between
- regional indicator (RI) symbols if there are an odd number of RI characters
- before the break point. This table encodes "join RI characters"; the code
- has to deal with checking for previous adjoining RIs.
-
-9. Otherwise, break everywhere.
-*/
-
-#define ESZ (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbZWJ)
-
-const uint32_t PRIV(ucp_gbtable)[] = {
- (1u<<ucp_gbLF), /* 0 CR */
- 0, /* 1 LF */
- 0, /* 2 Control */
- ESZ, /* 3 Extend */
- ESZ|(1u<<ucp_gbPrepend)| /* 4 Prepend */
- (1u<<ucp_gbL)|(1u<<ucp_gbV)|(1u<<ucp_gbT)|
- (1u<<ucp_gbLV)|(1u<<ucp_gbLVT)|(1u<<ucp_gbOther)|
- (1u<<ucp_gbRegional_Indicator),
- ESZ, /* 5 SpacingMark */
- ESZ|(1u<<ucp_gbL)|(1u<<ucp_gbV)|(1u<<ucp_gbLV)| /* 6 L */
- (1u<<ucp_gbLVT),
- ESZ|(1u<<ucp_gbV)|(1u<<ucp_gbT), /* 7 V */
- ESZ|(1u<<ucp_gbT), /* 8 T */
- ESZ|(1u<<ucp_gbV)|(1u<<ucp_gbT), /* 9 LV */
- ESZ|(1u<<ucp_gbT), /* 10 LVT */
- (1u<<ucp_gbRegional_Indicator), /* 11 Regional Indicator */
- ESZ, /* 12 Other */
- ESZ, /* 13 ZWJ */
- ESZ|(1u<<ucp_gbExtended_Pictographic) /* 14 Extended Pictographic */
-};
-
-#undef ESZ
-
-#ifdef SUPPORT_JIT
-/* This table reverses PRIV(ucp_gentype). We can save the cost
-of a memory load. */
-
-const int PRIV(ucp_typerange)[] = {
- ucp_Cc, ucp_Cs,
- ucp_Ll, ucp_Lu,
- ucp_Mc, ucp_Mn,
- ucp_Nd, ucp_No,
- ucp_Pc, ucp_Ps,
- ucp_Sc, ucp_So,
- ucp_Zl, ucp_Zs,
-};
-#endif /* SUPPORT_JIT */
-
-/* Finally, include the tables that are auto-generated from the Unicode data
-files. */
-
-#include "pcre2_ucptables.c"
-
-#endif /* SUPPORT_UNICODE */
-
-/* End of pcre2_tables.c */
diff --git a/contrib/libs/pcre2/src/pcre2_ucd.c b/contrib/libs/pcre2/src/pcre2_ucd.c
deleted file mode 100644
index 496c231915..0000000000
--- a/contrib/libs/pcre2/src/pcre2_ucd.c
+++ /dev/null
@@ -1,5396 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2022 University of Cambridge
-
-This module is auto-generated from Unicode data files. DO NOT EDIT MANUALLY!
-Instead, modify the maint/GenerateUcd.py script and run it to generate
-a new version of this code.
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-/* This file contains tables of Unicode properties that are extracted from
-Unicode data files. See the comments at the start of maint/GenerateUcd.py for
-details.
-
-As well as being part of the PCRE2 library, this file is #included by the
-pcre2test program, which redefines the PRIV macro to change table names from
-_pcre2_xxx to xxxx, thereby avoiding name clashes with the library. At present,
-just one of these tables is actually needed. When compiling the library, some
-headers are needed. */
-
-#ifndef PCRE2_PCRE2TEST
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-#include "pcre2_internal.h"
-#endif /* PCRE2_PCRE2TEST */
-
-/* The tables herein are needed only when UCP support is built, and in PCRE2
-that happens automatically with UTF support. This module should not be
-referenced otherwise, so it should not matter whether it is compiled or not.
-However a comment was received about space saving - maybe the guy linked all
-the modules rather than using a library - so we include a condition to cut out
-the tables when not needed. But don't leave a totally empty module because some
-compilers barf at that. Instead, just supply some small dummy tables. */
-
-#ifndef SUPPORT_UNICODE
-const ucd_record PRIV(ucd_records)[] = {{0,0,0,0,0,0,0 }};
-const uint16_t PRIV(ucd_stage1)[] = {0};
-const uint16_t PRIV(ucd_stage2)[] = {0};
-const uint32_t PRIV(ucd_caseless_sets)[] = {0};
-#else
-
-/* Total size: 111116 bytes, block size: 128. */
-
-const char *PRIV(unicode_version) = "14.0.0";
-
-/* When recompiling tables with a new Unicode version, please check the types
-in this structure definition with those in pcre2_internal.h (the actual field
-names will be different).
-
-typedef struct {
-uint8_t property_0;
-uint8_t property_1;
-uint8_t property_2;
-uint8_t property_3;
-int32_t property_4;
-uint16_t property_5;
-uint16_t property_6;
-} ucd_record;
-*/
-
-/* If the 32-bit library is run in non-32-bit mode, character values greater
-than 0x10ffff may be encountered. For these we set up a special record. */
-
-#if PCRE2_CODE_UNIT_WIDTH == 32
-const ucd_record PRIV(dummy_ucd_record)[] = {{
- ucp_Unknown, /* script */
- ucp_Cn, /* type unassigned */
- ucp_gbOther, /* grapheme break property */
- 0, /* case set */
- 0, /* other case */
- 0 | (ucp_bidiL << UCD_BIDICLASS_SHIFT), /* script extension and bidi class */
- 0, /* bool properties offset */
- }};
-#endif
-
-/* This table contains lists of characters that are caseless sets of
-more than one character. Each list is terminated by NOTACHAR. */
-
-const uint32_t PRIV(ucd_caseless_sets)[] = {
- NOTACHAR,
- 0x0053, 0x0073, 0x017f, NOTACHAR,
- 0x01c4, 0x01c5, 0x01c6, NOTACHAR,
- 0x01c7, 0x01c8, 0x01c9, NOTACHAR,
- 0x01ca, 0x01cb, 0x01cc, NOTACHAR,
- 0x01f1, 0x01f2, 0x01f3, NOTACHAR,
- 0x0345, 0x0399, 0x03b9, 0x1fbe, NOTACHAR,
- 0x00b5, 0x039c, 0x03bc, NOTACHAR,
- 0x03a3, 0x03c2, 0x03c3, NOTACHAR,
- 0x0392, 0x03b2, 0x03d0, NOTACHAR,
- 0x0398, 0x03b8, 0x03d1, 0x03f4, NOTACHAR,
- 0x03a6, 0x03c6, 0x03d5, NOTACHAR,
- 0x03a0, 0x03c0, 0x03d6, NOTACHAR,
- 0x039a, 0x03ba, 0x03f0, NOTACHAR,
- 0x03a1, 0x03c1, 0x03f1, NOTACHAR,
- 0x0395, 0x03b5, 0x03f5, NOTACHAR,
- 0x0412, 0x0432, 0x1c80, NOTACHAR,
- 0x0414, 0x0434, 0x1c81, NOTACHAR,
- 0x041e, 0x043e, 0x1c82, NOTACHAR,
- 0x0421, 0x0441, 0x1c83, NOTACHAR,
- 0x0422, 0x0442, 0x1c84, 0x1c85, NOTACHAR,
- 0x042a, 0x044a, 0x1c86, NOTACHAR,
- 0x0462, 0x0463, 0x1c87, NOTACHAR,
- 0x1e60, 0x1e61, 0x1e9b, NOTACHAR,
- 0x03a9, 0x03c9, 0x2126, NOTACHAR,
- 0x004b, 0x006b, 0x212a, NOTACHAR,
- 0x00c5, 0x00e5, 0x212b, NOTACHAR,
- 0x1c88, 0xa64a, 0xa64b, NOTACHAR,
-};
-
-/* When #included in pcre2test, we don't need the table of digit sets, nor the
-the large main UCD tables. */
-
-#ifndef PCRE2_PCRE2TEST
-
-/* This table lists the code points for the '9' characters in each set of
-decimal digits. It is used to ensure that all the digits in a script run come
-from the same set. */
-
-const uint32_t PRIV(ucd_digit_sets)[] = {
- 66, /* Number of subsequent values */
- 0x00039, 0x00669, 0x006f9, 0x007c9, 0x0096f, 0x009ef, 0x00a6f, 0x00aef,
- 0x00b6f, 0x00bef, 0x00c6f, 0x00cef, 0x00d6f, 0x00def, 0x00e59, 0x00ed9,
- 0x00f29, 0x01049, 0x01099, 0x017e9, 0x01819, 0x0194f, 0x019d9, 0x01a89,
- 0x01a99, 0x01b59, 0x01bb9, 0x01c49, 0x01c59, 0x0a629, 0x0a8d9, 0x0a909,
- 0x0a9d9, 0x0a9f9, 0x0aa59, 0x0abf9, 0x0ff19, 0x104a9, 0x10d39, 0x1106f,
- 0x110f9, 0x1113f, 0x111d9, 0x112f9, 0x11459, 0x114d9, 0x11659, 0x116c9,
- 0x11739, 0x118e9, 0x11959, 0x11c59, 0x11d59, 0x11da9, 0x16a69, 0x16ac9,
- 0x16b59, 0x1d7d7, 0x1d7e1, 0x1d7eb, 0x1d7f5, 0x1d7ff, 0x1e149, 0x1e2f9,
- 0x1e959, 0x1fbf9,
-};
-
-/* This vector is a list of script bitsets for the Script Extension property.
-The number of 32-bit words in each bitset is #defined in pcre2_ucp.h as
-ucd_script_sets_item_size. */
-
-const uint32_t PRIV(ucd_script_sets)[] = {
- 0x00000000u, 0x00000000u, 0x00000000u,
- 0x00000080u, 0x00000000u, 0x00000000u,
- 0x00000040u, 0x00000000u, 0x00000000u,
- 0x00000000u, 0x00004000u, 0x00000000u,
- 0x00000002u, 0x00000000u, 0x00000000u,
- 0x00800000u, 0x00000000u, 0x00000000u,
- 0x00000001u, 0x00000000u, 0x00000000u,
- 0x00000000u, 0x00000000u, 0x00000001u,
- 0x00000010u, 0x00000000u, 0x00000000u,
- 0x00000008u, 0x00000004u, 0x00000000u,
- 0x00000008u, 0x40000000u, 0x00000000u,
- 0x00000008u, 0x00000040u, 0x00000000u,
- 0x00000018u, 0x00000000u, 0x00000000u,
- 0x00000028u, 0x00000000u, 0x00000000u,
- 0x000000c0u, 0x00000000u, 0x00000000u,
- 0x00c00000u, 0x00000000u, 0x00000000u,
- 0x00000000u, 0x00000102u, 0x00000000u,
- 0x80000000u, 0x00000001u, 0x00000000u,
- 0x00000004u, 0x00000008u, 0x00000000u,
- 0x00000005u, 0x00000000u, 0x00000000u,
- 0x00000004u, 0x00200000u, 0x00000000u,
- 0x00000014u, 0x00000000u, 0x00000000u,
- 0x00000040u, 0x00008000u, 0x00000000u,
- 0x00000040u, 0x00000000u, 0x00000001u,
- 0x00000040u, 0x00001000u, 0x00000000u,
- 0x00000840u, 0x00000000u, 0x00000000u,
- 0x00020001u, 0x00000000u, 0x00000000u,
- 0x00000800u, 0x00008000u, 0x00000000u,
- 0x00000200u, 0x00010000u, 0x00000000u,
- 0x00000100u, 0x02000000u, 0x00000000u,
- 0x00800001u, 0x00000000u, 0x00000000u,
- 0x00300000u, 0x00000000u, 0x00000000u,
- 0x00002000u, 0x00000000u, 0x00000001u,
- 0x00080001u, 0x00000000u, 0x00000000u,
- 0x00000000u, 0x00080000u, 0x00000008u,
- 0x00080000u, 0x00000020u, 0x00000000u,
- 0x00000038u, 0x00000000u, 0x00000000u,
- 0x00000028u, 0x00000000u, 0x00000002u,
- 0x00000080u, 0x00000810u, 0x00000000u,
- 0x40010000u, 0x00000800u, 0x00000000u,
- 0x80000000u, 0x00000001u, 0x00000004u,
- 0x80000000u, 0x00020001u, 0x00000000u,
- 0x00002040u, 0x00008000u, 0x00000000u,
- 0x00000041u, 0x00008000u, 0x00000000u,
- 0x00b00000u, 0x00000000u, 0x00000000u,
- 0x00010001u, 0x00000080u, 0x00000000u,
- 0x000020c0u, 0x00008000u, 0x00000000u,
- 0x1e000000u, 0x00000000u, 0x00000000u,
- 0x00000040u, 0x10040200u, 0x00000000u,
- 0x00f40000u, 0x00000000u, 0x00000000u,
- 0x00000038u, 0x40000040u, 0x00000002u,
- 0x01f40000u, 0x00000000u, 0x00000000u,
- 0x00007c40u, 0x00000000u, 0x00000000u,
- 0x00000038u, 0x44000040u, 0x00000002u,
- 0x000034c0u, 0x01008000u, 0x00000001u,
- 0x00000018u, 0xc4480400u, 0x00000008u,
- 0x00000340u, 0x11952200u, 0x00000000u,
- 0x00007fc1u, 0x01008000u, 0x00000000u,
- 0x00007fc1u, 0x01009000u, 0x00000000u,
- 0x00002340u, 0x11952200u, 0x00000001u,
- 0x00006340u, 0x11952200u, 0x00000001u,
- 0x0000ffc0u, 0x3984a010u, 0x00000001u,
- 0x2000ffc0u, 0x3984a010u, 0x00000001u,
-};
-
-/* This vector is a list of bitsets for Boolean properties. The number of
-32_bit words in each bitset is #defined as ucd_boolprop_sets_item_size in
-pcre2_ucp.h. */
-
-const uint32_t PRIV(ucd_boolprop_sets)[] = {
- 0x00000000u, 0x00000000u,
- 0x00000001u, 0x00000000u,
- 0x00000001u, 0x00020040u,
- 0x00800001u, 0x00020040u,
- 0x00800001u, 0x00002820u,
- 0x00800001u, 0x00000120u,
- 0x00830001u, 0x00000020u,
- 0x00800001u, 0x00000020u,
- 0x00800021u, 0x00000120u,
- 0x00800011u, 0x00000020u,
- 0x00800001u, 0x00000028u,
- 0x00800001u, 0x00002020u,
- 0x00801001u, 0x00000020u,
- 0x00800021u, 0x00002820u,
- 0x24830003u, 0x00040000u,
- 0x00800021u, 0x00002020u,
- 0x00800011u, 0x00000028u,
- 0x648003c7u, 0x000c8000u,
- 0x608003c5u, 0x000c8000u,
- 0x00808021u, 0x00000028u,
- 0x20800001u, 0x00040000u,
- 0x00808021u, 0x00000020u,
- 0x64800d47u, 0x000c0004u,
- 0x60800d45u, 0x000c0004u,
- 0x60800d45u, 0x000c1004u,
- 0x00000000u, 0x00020040u,
- 0x00800000u, 0x00020000u,
- 0x00800000u, 0x00000020u,
- 0x00808020u, 0x00000000u,
- 0x00a10000u, 0x00000020u,
- 0x60800044u, 0x000c0004u,
- 0x00800010u, 0x00000120u,
- 0x00800000u, 0x00000028u,
- 0x00002020u, 0x00000000u,
- 0x00800000u, 0x00000000u,
- 0x60800dc4u, 0x000c0004u,
- 0x20c08020u, 0x00040000u,
- 0x608003c4u, 0x000c8000u,
- 0x60800d44u, 0x000c0004u,
- 0x60800d44u, 0x000c1004u,
- 0x60804dc4u, 0x000c0004u,
- 0x60800004u, 0x000c0000u,
- 0x608007c4u, 0x000c8000u,
- 0x60800bc4u, 0x000c0000u,
- 0x60808064u, 0x000c0004u,
- 0x60808064u, 0x000c1004u,
- 0x60808024u, 0x000c0000u,
- 0x60c08024u, 0x000c0000u,
- 0x21008020u, 0x00040000u,
- 0x21008de4u, 0x00040004u,
- 0x21002020u, 0x00040000u,
- 0x21000020u, 0x00040000u,
- 0x60808064u, 0x00000004u,
- 0x00800000u, 0x00002000u,
- 0x20800020u, 0x00042000u,
- 0x60800dc4u, 0x000c000cu,
- 0x60800044u, 0x000c8008u,
- 0x60800044u, 0x000c8000u,
- 0x608003c4u, 0x000c8008u,
- 0x00800000u, 0x00000008u,
- 0x01000020u, 0x00000000u,
- 0x00800020u, 0x00000000u,
- 0x00800000u, 0x00002800u,
- 0x00801000u, 0x00000000u,
- 0x21008024u, 0x00040000u,
- 0x21000024u, 0x00040000u,
- 0x00000020u, 0x00000080u,
- 0x00002028u, 0x00000000u,
- 0x60c00024u, 0x000c0000u,
- 0x20800000u, 0x00040000u,
- 0x60804004u, 0x000c0000u,
- 0x60800024u, 0x000c0000u,
- 0x20800004u, 0x00040000u,
- 0x23008020u, 0x00040000u,
- 0x21000004u, 0x00040000u,
- 0x21408020u, 0x00040000u,
- 0x60800004u, 0x00040000u,
- 0x23000024u, 0x00040000u,
- 0x60800004u, 0x000c0002u,
- 0x00800010u, 0x00000000u,
- 0x20808000u, 0x00040000u,
- 0x21004024u, 0x00040000u,
- 0x20808004u, 0x00040000u,
- 0x60800944u, 0x000c0004u,
- 0x60802004u, 0x000c0000u,
- 0x60800344u, 0x000c8000u,
- 0x22808000u, 0x00040000u,
- 0x22800000u, 0x00040000u,
- 0x00c00000u, 0x00000000u,
- 0x21002020u, 0x00050000u,
- 0x61000024u, 0x000c0000u,
- 0x23000020u, 0x00040000u,
- 0x01008020u, 0x00000000u,
- 0x21408024u, 0x00040000u,
- 0x00808000u, 0x00000000u,
- 0x60800064u, 0x000c0004u,
- 0x60800044u, 0x000c1004u,
- 0x60800064u, 0x000c1004u,
- 0x01002020u, 0x00000001u,
- 0x00022020u, 0x00000001u,
- 0x00002028u, 0x00000040u,
- 0x00801000u, 0x00000020u,
- 0x00800020u, 0x00000120u,
- 0x00800000u, 0x00000120u,
- 0x00800020u, 0x00000020u,
- 0x00a10000u, 0x00002820u,
- 0x00800000u, 0x00002820u,
- 0x20800000u, 0x00040008u,
- 0x00800010u, 0x00000020u,
- 0x00002020u, 0x00000008u,
- 0x00002000u, 0x00000000u,
- 0x00006020u, 0x00000000u,
- 0x00801000u, 0x00000008u,
- 0x00800010u, 0x00000008u,
- 0x21000020u, 0x00040008u,
- 0x01020020u, 0x00000000u,
- 0x60800044u, 0x000c000cu,
- 0x60800000u, 0x000c0008u,
- 0x00a10000u, 0x00000000u,
- 0x60800000u, 0x000c0000u,
- 0x60800004u, 0x000c0008u,
- 0x60a10044u, 0x000c0004u,
- 0x60800044u, 0x000c100cu,
- 0x00a10000u, 0x00000028u,
- 0x00800010u, 0x00000028u,
- 0x00801000u, 0x00000028u,
- 0x00b10000u, 0x00000020u,
- 0x00804010u, 0x00000020u,
- 0x00a00000u, 0x00000020u,
- 0x00000000u, 0x00000020u,
- 0x008003c4u, 0x00008000u,
- 0x00a103c4u, 0x00008000u,
- 0x00800d44u, 0x00000004u,
- 0x00b10000u, 0x00000028u,
- 0x00a00000u, 0x00000028u,
- 0x00a90000u, 0x00000020u,
- 0x00b90000u, 0x00000020u,
- 0x00808024u, 0x00000020u,
- 0x00800000u, 0x00002020u,
- 0x00800000u, 0x00000200u,
- 0x08800000u, 0x00000000u,
- 0x10800000u, 0x00000000u,
- 0xe0800004u, 0x000c0000u,
- 0x21008000u, 0x00040000u,
- 0x00a11000u, 0x00000020u,
- 0x60808020u, 0x00000000u,
- 0xe0800004u, 0x000c4000u,
- 0x60808004u, 0x000c0000u,
- 0x60800004u, 0x00000000u,
- 0x00000000u, 0x00000010u,
- 0x21022020u, 0x00050000u,
- 0x00800000u, 0x00000100u,
- 0x00800020u, 0x00002800u,
- 0x00800020u, 0x00002000u,
- 0x00800020u, 0x00000100u,
- 0x24800000u, 0x00040000u,
- 0x648003c4u, 0x000c8000u,
- 0x00808020u, 0x00000008u,
- 0x64800d44u, 0x000c0004u,
- 0x00800010u, 0x00000100u,
- 0x61008024u, 0x00040000u,
- 0x00000020u, 0x00000000u,
- 0x60c00004u, 0x000c0000u,
- 0x21400020u, 0x00040000u,
- 0xa1000020u, 0x00040000u,
- 0x21000000u, 0x00040000u,
- 0x00a00000u, 0x00000000u,
- 0x00b10000u, 0x00000000u,
- 0x00200000u, 0x00000000u,
- 0x00800044u, 0x00008000u,
- 0x00a10044u, 0x00008000u,
- 0x00930000u, 0x00000400u,
- 0x00b90000u, 0x00000000u,
- 0x00a90000u, 0x00000000u,
- 0x00970020u, 0x00000000u,
- 0x00b30000u, 0x00000000u,
- 0x01022020u, 0x00000000u,
-};
-
-/* These are the main two-stage UCD tables. The fields in each record are:
-script (8 bits), character type (8 bits), grapheme break property (8 bits),
-offset to multichar other cases or zero (8 bits), offset to other case or zero
-(32 bits, signed), bidi class (5 bits) and script extension (11 bits) packed
-into a 16-bit field, and offset in binary properties table (16 bits). */
-
-const ucd_record PRIV(ucd_records)[] = { /* 16908 bytes, record size 12 */
- { 69, 0, 2, 0, 0, 6144, 2, }, /* 0 */
- { 69, 0, 2, 0, 0, 43008, 4, }, /* 1 */
- { 69, 0, 1, 0, 0, 4096, 4, }, /* 2 */
- { 69, 0, 2, 0, 0, 45056, 4, }, /* 3 */
- { 69, 0, 0, 0, 0, 4096, 4, }, /* 4 */
- { 69, 0, 2, 0, 0, 4096, 2, }, /* 5 */
- { 69, 0, 2, 0, 0, 43008, 2, }, /* 6 */
- { 69, 29, 12, 0, 0, 45056, 6, }, /* 7 */
- { 69, 21, 12, 0, 0, 28672, 8, }, /* 8 */
- { 69, 21, 12, 0, 0, 28672, 10, }, /* 9 */
- { 69, 21, 12, 0, 0, 14336, 12, }, /* 10 */
- { 69, 23, 12, 0, 0, 14336, 14, }, /* 11 */
- { 69, 21, 12, 0, 0, 14336, 14, }, /* 12 */
- { 69, 21, 12, 0, 0, 28672, 14, }, /* 13 */
- { 69, 21, 12, 0, 0, 28672, 16, }, /* 14 */
- { 69, 22, 12, 0, 0, 28672, 18, }, /* 15 */
- { 69, 18, 12, 0, 0, 28672, 18, }, /* 16 */
- { 69, 21, 12, 0, 0, 28672, 12, }, /* 17 */
- { 69, 25, 12, 0, 0, 12288, 20, }, /* 18 */
- { 69, 21, 12, 0, 0, 8192, 22, }, /* 19 */
- { 69, 17, 12, 0, 0, 12288, 24, }, /* 20 */
- { 69, 21, 12, 0, 0, 8192, 26, }, /* 21 */
- { 69, 21, 12, 0, 0, 8192, 14, }, /* 22 */
- { 69, 13, 12, 0, 0, 10240, 28, }, /* 23 */
- { 69, 21, 12, 0, 0, 8192, 30, }, /* 24 */
- { 69, 21, 12, 0, 0, 28672, 22, }, /* 25 */
- { 69, 25, 12, 0, 0, 28672, 32, }, /* 26 */
- { 69, 25, 12, 0, 0, 28672, 20, }, /* 27 */
- { 0, 9, 12, 0, 32, 18432, 34, }, /* 28 */
- { 0, 9, 12, 0, 32, 18432, 36, }, /* 29 */
- { 0, 9, 12, 100, 32, 18432, 36, }, /* 30 */
- { 0, 9, 12, 1, 32, 18432, 36, }, /* 31 */
- { 69, 24, 12, 0, 0, 28672, 38, }, /* 32 */
- { 69, 16, 12, 0, 0, 28672, 40, }, /* 33 */
- { 69, 24, 12, 0, 0, 28672, 42, }, /* 34 */
- { 0, 5, 12, 0, -32, 18432, 44, }, /* 35 */
- { 0, 5, 12, 0, -32, 18432, 46, }, /* 36 */
- { 0, 5, 12, 0, -32, 18432, 48, }, /* 37 */
- { 0, 5, 12, 100, -32, 18432, 46, }, /* 38 */
- { 0, 5, 12, 1, -32, 18432, 46, }, /* 39 */
- { 69, 0, 2, 0, 0, 6144, 0, }, /* 40 */
- { 69, 0, 2, 0, 0, 4096, 50, }, /* 41 */
- { 69, 29, 12, 0, 0, 8192, 52, }, /* 42 */
- { 69, 21, 12, 0, 0, 28672, 54, }, /* 43 */
- { 69, 23, 12, 0, 0, 14336, 54, }, /* 44 */
- { 69, 26, 12, 0, 0, 28672, 54, }, /* 45 */
- { 69, 24, 12, 0, 0, 28672, 56, }, /* 46 */
- { 69, 26, 14, 0, 0, 28672, 58, }, /* 47 */
- { 0, 7, 12, 0, 0, 18432, 60, }, /* 48 */
- { 69, 20, 12, 0, 0, 28672, 62, }, /* 49 */
- { 69, 25, 12, 0, 0, 28672, 64, }, /* 50 */
- { 69, 1, 2, 0, 0, 6144, 66, }, /* 51 */
- { 69, 26, 12, 0, 0, 14336, 54, }, /* 52 */
- { 69, 25, 12, 0, 0, 14336, 64, }, /* 53 */
- { 69, 15, 12, 0, 0, 10240, 68, }, /* 54 */
- { 69, 5, 12, 26, 775, 18432, 70, }, /* 55 */
- { 69, 21, 12, 0, 0, 28672, 72, }, /* 56 */
- { 69, 19, 12, 0, 0, 28672, 62, }, /* 57 */
- { 69, 15, 12, 0, 0, 28672, 68, }, /* 58 */
- { 0, 9, 12, 0, 32, 18432, 74, }, /* 59 */
- { 0, 9, 12, 104, 32, 18432, 74, }, /* 60 */
- { 0, 5, 12, 0, 7615, 18432, 70, }, /* 61 */
- { 0, 5, 12, 0, -32, 18432, 76, }, /* 62 */
- { 0, 5, 12, 104, -32, 18432, 76, }, /* 63 */
- { 0, 5, 12, 0, 121, 18432, 76, }, /* 64 */
- { 0, 9, 12, 0, 1, 18432, 74, }, /* 65 */
- { 0, 5, 12, 0, -1, 18432, 76, }, /* 66 */
- { 0, 5, 12, 0, -1, 18432, 78, }, /* 67 */
- { 0, 9, 12, 0, 0, 18432, 74, }, /* 68 */
- { 0, 5, 12, 0, 0, 18432, 76, }, /* 69 */
- { 0, 5, 12, 0, 0, 18432, 60, }, /* 70 */
- { 0, 5, 12, 0, 0, 18432, 80, }, /* 71 */
- { 0, 9, 12, 0, -121, 18432, 74, }, /* 72 */
- { 0, 5, 12, 1, -268, 18432, 70, }, /* 73 */
- { 0, 5, 12, 0, 195, 18432, 76, }, /* 74 */
- { 0, 9, 12, 0, 210, 18432, 74, }, /* 75 */
- { 0, 9, 12, 0, 206, 18432, 74, }, /* 76 */
- { 0, 9, 12, 0, 205, 18432, 74, }, /* 77 */
- { 0, 9, 12, 0, 79, 18432, 74, }, /* 78 */
- { 0, 9, 12, 0, 202, 18432, 74, }, /* 79 */
- { 0, 9, 12, 0, 203, 18432, 74, }, /* 80 */
- { 0, 9, 12, 0, 207, 18432, 74, }, /* 81 */
- { 0, 5, 12, 0, 97, 18432, 76, }, /* 82 */
- { 0, 9, 12, 0, 211, 18432, 74, }, /* 83 */
- { 0, 9, 12, 0, 209, 18432, 74, }, /* 84 */
- { 0, 5, 12, 0, 163, 18432, 76, }, /* 85 */
- { 0, 9, 12, 0, 213, 18432, 74, }, /* 86 */
- { 0, 5, 12, 0, 130, 18432, 76, }, /* 87 */
- { 0, 9, 12, 0, 214, 18432, 74, }, /* 88 */
- { 0, 9, 12, 0, 218, 18432, 74, }, /* 89 */
- { 0, 9, 12, 0, 217, 18432, 74, }, /* 90 */
- { 0, 9, 12, 0, 219, 18432, 74, }, /* 91 */
- { 0, 7, 12, 0, 0, 18432, 82, }, /* 92 */
- { 0, 5, 12, 0, 56, 18432, 76, }, /* 93 */
- { 0, 9, 12, 5, 2, 18432, 84, }, /* 94 */
- { 0, 8, 12, 5, 1, 18432, 86, }, /* 95 */
- { 0, 5, 12, 5, -2, 18432, 76, }, /* 96 */
- { 0, 9, 12, 9, 2, 18432, 84, }, /* 97 */
- { 0, 8, 12, 9, 1, 18432, 86, }, /* 98 */
- { 0, 5, 12, 9, -2, 18432, 76, }, /* 99 */
- { 0, 9, 12, 13, 2, 18432, 84, }, /* 100 */
- { 0, 8, 12, 13, 1, 18432, 86, }, /* 101 */
- { 0, 5, 12, 13, -2, 18432, 76, }, /* 102 */
- { 0, 5, 12, 0, -79, 18432, 76, }, /* 103 */
- { 0, 9, 12, 17, 2, 18432, 84, }, /* 104 */
- { 0, 8, 12, 17, 1, 18432, 86, }, /* 105 */
- { 0, 5, 12, 17, -2, 18432, 76, }, /* 106 */
- { 0, 9, 12, 0, -97, 18432, 74, }, /* 107 */
- { 0, 9, 12, 0, -56, 18432, 74, }, /* 108 */
- { 0, 9, 12, 0, -130, 18432, 74, }, /* 109 */
- { 0, 9, 12, 0, 10795, 18432, 74, }, /* 110 */
- { 0, 9, 12, 0, -163, 18432, 74, }, /* 111 */
- { 0, 9, 12, 0, 10792, 18432, 74, }, /* 112 */
- { 0, 5, 12, 0, 10815, 18432, 76, }, /* 113 */
- { 0, 9, 12, 0, -195, 18432, 74, }, /* 114 */
- { 0, 9, 12, 0, 69, 18432, 74, }, /* 115 */
- { 0, 9, 12, 0, 71, 18432, 74, }, /* 116 */
- { 0, 5, 12, 0, 10783, 18432, 76, }, /* 117 */
- { 0, 5, 12, 0, 10780, 18432, 76, }, /* 118 */
- { 0, 5, 12, 0, 10782, 18432, 76, }, /* 119 */
- { 0, 5, 12, 0, -210, 18432, 76, }, /* 120 */
- { 0, 5, 12, 0, -206, 18432, 76, }, /* 121 */
- { 0, 5, 12, 0, -205, 18432, 76, }, /* 122 */
- { 0, 5, 12, 0, -202, 18432, 76, }, /* 123 */
- { 0, 5, 12, 0, -203, 18432, 76, }, /* 124 */
- { 0, 5, 12, 0, 42319, 18432, 76, }, /* 125 */
- { 0, 5, 12, 0, 42315, 18432, 76, }, /* 126 */
- { 0, 5, 12, 0, -207, 18432, 76, }, /* 127 */
- { 0, 5, 12, 0, 42280, 18432, 76, }, /* 128 */
- { 0, 5, 12, 0, 42308, 18432, 76, }, /* 129 */
- { 0, 5, 12, 0, -209, 18432, 78, }, /* 130 */
- { 0, 5, 12, 0, -211, 18432, 76, }, /* 131 */
- { 0, 5, 12, 0, 10743, 18432, 76, }, /* 132 */
- { 0, 5, 12, 0, 42305, 18432, 76, }, /* 133 */
- { 0, 5, 12, 0, 10749, 18432, 76, }, /* 134 */
- { 0, 5, 12, 0, -213, 18432, 76, }, /* 135 */
- { 0, 5, 12, 0, -214, 18432, 76, }, /* 136 */
- { 0, 5, 12, 0, 10727, 18432, 76, }, /* 137 */
- { 0, 5, 12, 0, -218, 18432, 76, }, /* 138 */
- { 0, 5, 12, 0, 42307, 18432, 76, }, /* 139 */
- { 0, 5, 12, 0, 42282, 18432, 76, }, /* 140 */
- { 0, 5, 12, 0, -69, 18432, 76, }, /* 141 */
- { 0, 5, 12, 0, -217, 18432, 76, }, /* 142 */
- { 0, 5, 12, 0, -71, 18432, 76, }, /* 143 */
- { 0, 5, 12, 0, -219, 18432, 76, }, /* 144 */
- { 0, 5, 12, 0, 42261, 18432, 78, }, /* 145 */
- { 0, 5, 12, 0, 42258, 18432, 76, }, /* 146 */
- { 0, 6, 12, 0, 0, 18432, 88, }, /* 147 */
- { 0, 6, 12, 0, 0, 18432, 90, }, /* 148 */
- { 69, 6, 12, 0, 0, 28672, 92, }, /* 149 */
- { 69, 6, 12, 0, 0, 18432, 92, }, /* 150 */
- { 69, 6, 12, 0, 0, 18432, 88, }, /* 151 */
- { 69, 6, 12, 0, 0, 18432, 94, }, /* 152 */
- { 22, 24, 12, 0, 0, 28672, 56, }, /* 153 */
- { 84, 12, 3, 0, 0, 26624, 96, }, /* 154 */
- { 84, 12, 3, 0, 0, 26636, 96, }, /* 155 */
- { 84, 12, 3, 21, 116, 26636, 98, }, /* 156 */
- { 84, 12, 3, 0, 0, 26624, 100, }, /* 157 */
- { 84, 12, 3, 0, 0, 26624, 102, }, /* 158 */
- { 84, 12, 3, 0, 0, 26642, 102, }, /* 159 */
- { 1, 9, 12, 0, 1, 18432, 74, }, /* 160 */
- { 1, 5, 12, 0, -1, 18432, 76, }, /* 161 */
- { 1, 24, 12, 0, 0, 28672, 56, }, /* 162 */
- { 68, 2, 12, 0, 0, 18432, 0, }, /* 163 */
- { 1, 6, 12, 0, 0, 18432, 104, }, /* 164 */
- { 1, 5, 12, 0, 130, 18432, 76, }, /* 165 */
- { 69, 21, 12, 0, 0, 28672, 106, }, /* 166 */
- { 1, 9, 12, 0, 116, 18432, 74, }, /* 167 */
- { 1, 9, 12, 0, 38, 18432, 74, }, /* 168 */
- { 69, 21, 12, 0, 0, 28672, 108, }, /* 169 */
- { 1, 9, 12, 0, 37, 18432, 74, }, /* 170 */
- { 1, 9, 12, 0, 64, 18432, 74, }, /* 171 */
- { 1, 9, 12, 0, 63, 18432, 74, }, /* 172 */
- { 1, 5, 12, 0, 0, 18432, 76, }, /* 173 */
- { 1, 9, 12, 0, 32, 18432, 74, }, /* 174 */
- { 1, 9, 12, 34, 32, 18432, 74, }, /* 175 */
- { 1, 9, 12, 59, 32, 18432, 74, }, /* 176 */
- { 1, 9, 12, 38, 32, 18432, 74, }, /* 177 */
- { 1, 9, 12, 21, 32, 18432, 74, }, /* 178 */
- { 1, 9, 12, 51, 32, 18432, 74, }, /* 179 */
- { 1, 9, 12, 26, 32, 18432, 74, }, /* 180 */
- { 1, 9, 12, 47, 32, 18432, 74, }, /* 181 */
- { 1, 9, 12, 55, 32, 18432, 74, }, /* 182 */
- { 1, 9, 12, 30, 32, 18432, 74, }, /* 183 */
- { 1, 9, 12, 43, 32, 18432, 74, }, /* 184 */
- { 1, 9, 12, 96, 32, 18432, 74, }, /* 185 */
- { 1, 5, 12, 0, -38, 18432, 76, }, /* 186 */
- { 1, 5, 12, 0, -37, 18432, 76, }, /* 187 */
- { 1, 5, 12, 0, -32, 18432, 76, }, /* 188 */
- { 1, 5, 12, 34, -32, 18432, 76, }, /* 189 */
- { 1, 5, 12, 59, -32, 18432, 76, }, /* 190 */
- { 1, 5, 12, 38, -32, 18432, 76, }, /* 191 */
- { 1, 5, 12, 21, -116, 18432, 76, }, /* 192 */
- { 1, 5, 12, 51, -32, 18432, 76, }, /* 193 */
- { 1, 5, 12, 26, -775, 18432, 76, }, /* 194 */
- { 1, 5, 12, 47, -32, 18432, 76, }, /* 195 */
- { 1, 5, 12, 55, -32, 18432, 76, }, /* 196 */
- { 1, 5, 12, 30, 1, 18432, 70, }, /* 197 */
- { 1, 5, 12, 30, -32, 18432, 76, }, /* 198 */
- { 1, 5, 12, 43, -32, 18432, 76, }, /* 199 */
- { 1, 5, 12, 96, -32, 18432, 76, }, /* 200 */
- { 1, 5, 12, 0, -64, 18432, 76, }, /* 201 */
- { 1, 5, 12, 0, -63, 18432, 76, }, /* 202 */
- { 1, 9, 12, 0, 8, 18432, 74, }, /* 203 */
- { 1, 5, 12, 34, -30, 18432, 110, }, /* 204 */
- { 1, 5, 12, 38, -25, 18432, 110, }, /* 205 */
- { 1, 9, 12, 0, 0, 18432, 112, }, /* 206 */
- { 1, 9, 12, 0, 0, 18432, 114, }, /* 207 */
- { 1, 5, 12, 43, -15, 18432, 110, }, /* 208 */
- { 1, 5, 12, 47, -22, 18432, 70, }, /* 209 */
- { 1, 5, 12, 0, -8, 18432, 76, }, /* 210 */
- { 34, 9, 12, 0, 1, 18432, 74, }, /* 211 */
- { 34, 5, 12, 0, -1, 18432, 76, }, /* 212 */
- { 1, 5, 12, 51, -54, 18432, 110, }, /* 213 */
- { 1, 5, 12, 55, -48, 18432, 110, }, /* 214 */
- { 1, 5, 12, 0, 7, 18432, 76, }, /* 215 */
- { 1, 5, 12, 0, -116, 18432, 78, }, /* 216 */
- { 1, 9, 12, 38, -60, 18432, 116, }, /* 217 */
- { 1, 5, 12, 59, -64, 18432, 110, }, /* 218 */
- { 1, 25, 12, 0, 0, 28672, 118, }, /* 219 */
- { 1, 9, 12, 0, -7, 18432, 74, }, /* 220 */
- { 1, 5, 12, 0, 0, 18432, 60, }, /* 221 */
- { 1, 9, 12, 0, -130, 18432, 74, }, /* 222 */
- { 2, 9, 12, 0, 80, 18432, 74, }, /* 223 */
- { 2, 9, 12, 0, 32, 18432, 74, }, /* 224 */
- { 2, 9, 12, 63, 32, 18432, 74, }, /* 225 */
- { 2, 9, 12, 67, 32, 18432, 74, }, /* 226 */
- { 2, 9, 12, 71, 32, 18432, 74, }, /* 227 */
- { 2, 9, 12, 75, 32, 18432, 74, }, /* 228 */
- { 2, 9, 12, 79, 32, 18432, 74, }, /* 229 */
- { 2, 9, 12, 84, 32, 18432, 74, }, /* 230 */
- { 2, 5, 12, 0, -32, 18432, 76, }, /* 231 */
- { 2, 5, 12, 63, -32, 18432, 76, }, /* 232 */
- { 2, 5, 12, 67, -32, 18432, 76, }, /* 233 */
- { 2, 5, 12, 71, -32, 18432, 76, }, /* 234 */
- { 2, 5, 12, 75, -32, 18432, 76, }, /* 235 */
- { 2, 5, 12, 79, -32, 18432, 76, }, /* 236 */
- { 2, 5, 12, 84, -32, 18432, 76, }, /* 237 */
- { 2, 5, 12, 0, -80, 18432, 76, }, /* 238 */
- { 2, 5, 12, 0, -80, 18432, 78, }, /* 239 */
- { 2, 9, 12, 0, 1, 18432, 74, }, /* 240 */
- { 2, 5, 12, 0, -1, 18432, 76, }, /* 241 */
- { 2, 9, 12, 88, 1, 18432, 74, }, /* 242 */
- { 2, 5, 12, 88, -1, 18432, 76, }, /* 243 */
- { 2, 26, 12, 0, 0, 18432, 68, }, /* 244 */
- { 2, 12, 3, 0, 0, 26684, 96, }, /* 245 */
- { 2, 12, 3, 0, 0, 26678, 96, }, /* 246 */
- { 84, 12, 3, 0, 0, 26681, 96, }, /* 247 */
- { 2, 11, 3, 0, 0, 26624, 120, }, /* 248 */
- { 2, 9, 12, 0, 15, 18432, 74, }, /* 249 */
- { 2, 5, 12, 0, -15, 18432, 76, }, /* 250 */
- { 70, 9, 12, 0, 48, 18432, 74, }, /* 251 */
- { 70, 6, 12, 0, 0, 18432, 92, }, /* 252 */
- { 70, 21, 12, 0, 0, 18432, 68, }, /* 253 */
- { 70, 21, 12, 0, 0, 18432, 122, }, /* 254 */
- { 70, 5, 12, 0, 0, 18432, 60, }, /* 255 */
- { 70, 5, 12, 0, -48, 18432, 76, }, /* 256 */
- { 70, 5, 12, 0, 0, 18432, 70, }, /* 257 */
- { 70, 21, 12, 0, 0, 18432, 124, }, /* 258 */
- { 70, 17, 12, 0, 0, 28672, 126, }, /* 259 */
- { 70, 26, 12, 0, 0, 28672, 68, }, /* 260 */
- { 70, 23, 12, 0, 0, 14336, 68, }, /* 261 */
- { 68, 2, 12, 0, 0, 34816, 0, }, /* 262 */
- { 71, 12, 3, 0, 0, 26624, 96, }, /* 263 */
- { 71, 12, 3, 0, 0, 26624, 102, }, /* 264 */
- { 71, 12, 3, 0, 0, 26624, 128, }, /* 265 */
- { 71, 17, 12, 0, 0, 34816, 126, }, /* 266 */
- { 71, 21, 12, 0, 0, 34816, 68, }, /* 267 */
- { 71, 21, 12, 0, 0, 34816, 106, }, /* 268 */
- { 71, 12, 3, 0, 0, 26624, 130, }, /* 269 */
- { 71, 7, 12, 0, 0, 34816, 82, }, /* 270 */
- { 71, 21, 12, 0, 0, 34816, 122, }, /* 271 */
- { 3, 1, 4, 0, 0, 2048, 132, }, /* 272 */
- { 69, 1, 4, 0, 0, 2048, 132, }, /* 273 */
- { 3, 25, 12, 0, 0, 28672, 118, }, /* 274 */
- { 3, 25, 12, 0, 0, 0, 118, }, /* 275 */
- { 3, 21, 12, 0, 0, 14336, 68, }, /* 276 */
- { 3, 23, 12, 0, 0, 0, 68, }, /* 277 */
- { 69, 21, 12, 0, 0, 8342, 106, }, /* 278 */
- { 3, 21, 12, 0, 0, 0, 68, }, /* 279 */
- { 3, 26, 12, 0, 0, 28672, 68, }, /* 280 */
- { 3, 12, 3, 0, 0, 26624, 130, }, /* 281 */
- { 69, 21, 12, 0, 0, 150, 106, }, /* 282 */
- { 3, 1, 2, 0, 0, 108, 134, }, /* 283 */
- { 3, 21, 12, 0, 0, 0, 124, }, /* 284 */
- { 69, 21, 12, 0, 0, 159, 124, }, /* 285 */
- { 3, 7, 12, 0, 0, 0, 82, }, /* 286 */
- { 69, 6, 12, 0, 0, 165, 136, }, /* 287 */
- { 84, 12, 3, 0, 0, 26660, 128, }, /* 288 */
- { 84, 12, 3, 0, 0, 26660, 130, }, /* 289 */
- { 3, 12, 3, 0, 0, 26624, 128, }, /* 290 */
- { 3, 12, 3, 0, 0, 26624, 96, }, /* 291 */
- { 3, 13, 12, 0, 0, 2159, 138, }, /* 292 */
- { 3, 21, 12, 0, 0, 2048, 68, }, /* 293 */
- { 3, 7, 12, 0, 0, 0, 140, }, /* 294 */
- { 3, 21, 12, 0, 0, 30, 124, }, /* 295 */
- { 3, 6, 12, 0, 0, 0, 92, }, /* 296 */
- { 3, 13, 12, 0, 0, 10240, 138, }, /* 297 */
- { 3, 26, 12, 0, 0, 0, 68, }, /* 298 */
- { 4, 21, 12, 0, 0, 0, 124, }, /* 299 */
- { 4, 21, 12, 0, 0, 0, 106, }, /* 300 */
- { 4, 21, 12, 0, 0, 0, 68, }, /* 301 */
- { 68, 2, 12, 0, 0, 0, 0, }, /* 302 */
- { 4, 1, 4, 0, 0, 0, 132, }, /* 303 */
- { 4, 7, 12, 0, 0, 0, 82, }, /* 304 */
- { 4, 12, 3, 0, 0, 26624, 130, }, /* 305 */
- { 4, 12, 3, 0, 0, 26624, 128, }, /* 306 */
- { 4, 12, 3, 0, 0, 26624, 96, }, /* 307 */
- { 5, 7, 12, 0, 0, 0, 82, }, /* 308 */
- { 5, 12, 3, 0, 0, 26624, 128, }, /* 309 */
- { 38, 13, 12, 0, 0, 34816, 138, }, /* 310 */
- { 38, 7, 12, 0, 0, 34816, 82, }, /* 311 */
- { 38, 12, 3, 0, 0, 26624, 96, }, /* 312 */
- { 38, 6, 12, 0, 0, 34816, 92, }, /* 313 */
- { 38, 26, 12, 0, 0, 28672, 68, }, /* 314 */
- { 38, 21, 12, 0, 0, 28672, 68, }, /* 315 */
- { 38, 21, 12, 0, 0, 28672, 106, }, /* 316 */
- { 38, 21, 12, 0, 0, 28672, 124, }, /* 317 */
- { 38, 6, 12, 0, 0, 34816, 136, }, /* 318 */
- { 38, 12, 3, 0, 0, 26624, 102, }, /* 319 */
- { 38, 23, 12, 0, 0, 34816, 68, }, /* 320 */
- { 110, 7, 12, 0, 0, 34816, 82, }, /* 321 */
- { 110, 12, 3, 0, 0, 26624, 130, }, /* 322 */
- { 110, 12, 3, 0, 0, 26624, 96, }, /* 323 */
- { 110, 6, 12, 0, 0, 34816, 142, }, /* 324 */
- { 110, 12, 3, 0, 0, 26624, 102, }, /* 325 */
- { 110, 21, 12, 0, 0, 34816, 106, }, /* 326 */
- { 110, 21, 12, 0, 0, 34816, 124, }, /* 327 */
- { 42, 7, 12, 0, 0, 34816, 82, }, /* 328 */
- { 42, 12, 3, 0, 0, 26624, 102, }, /* 329 */
- { 42, 21, 12, 0, 0, 34816, 106, }, /* 330 */
- { 3, 24, 12, 0, 0, 0, 122, }, /* 331 */
- { 3, 12, 3, 0, 0, 26624, 102, }, /* 332 */
- { 6, 12, 3, 0, 0, 26624, 130, }, /* 333 */
- { 6, 10, 5, 0, 0, 18432, 144, }, /* 334 */
- { 6, 7, 12, 0, 0, 18432, 82, }, /* 335 */
- { 6, 12, 3, 0, 0, 26624, 96, }, /* 336 */
- { 6, 12, 3, 0, 0, 26624, 146, }, /* 337 */
- { 84, 12, 3, 0, 0, 26798, 96, }, /* 338 */
- { 84, 12, 3, 0, 0, 26795, 96, }, /* 339 */
- { 69, 21, 12, 0, 0, 18615, 124, }, /* 340 */
- { 69, 21, 12, 0, 0, 18618, 124, }, /* 341 */
- { 6, 13, 12, 0, 0, 18576, 138, }, /* 342 */
- { 6, 21, 12, 0, 0, 18432, 68, }, /* 343 */
- { 6, 6, 12, 0, 0, 18432, 92, }, /* 344 */
- { 7, 7, 12, 0, 0, 18432, 82, }, /* 345 */
- { 7, 12, 3, 0, 0, 26624, 130, }, /* 346 */
- { 7, 10, 5, 0, 0, 18432, 144, }, /* 347 */
- { 7, 12, 3, 0, 0, 26624, 96, }, /* 348 */
- { 7, 10, 3, 0, 0, 18432, 148, }, /* 349 */
- { 7, 12, 3, 0, 0, 26624, 146, }, /* 350 */
- { 7, 13, 12, 0, 0, 18546, 138, }, /* 351 */
- { 7, 23, 12, 0, 0, 14336, 68, }, /* 352 */
- { 7, 15, 12, 0, 0, 18432, 68, }, /* 353 */
- { 7, 26, 12, 0, 0, 18432, 68, }, /* 354 */
- { 7, 21, 12, 0, 0, 18432, 68, }, /* 355 */
- { 7, 12, 3, 0, 0, 26624, 102, }, /* 356 */
- { 8, 12, 3, 0, 0, 26624, 130, }, /* 357 */
- { 8, 10, 5, 0, 0, 18432, 144, }, /* 358 */
- { 8, 7, 12, 0, 0, 18432, 82, }, /* 359 */
- { 8, 12, 3, 0, 0, 26624, 96, }, /* 360 */
- { 8, 12, 3, 0, 0, 26624, 146, }, /* 361 */
- { 8, 13, 12, 0, 0, 18519, 138, }, /* 362 */
- { 8, 21, 12, 0, 0, 18432, 68, }, /* 363 */
- { 9, 12, 3, 0, 0, 26624, 130, }, /* 364 */
- { 9, 10, 5, 0, 0, 18432, 144, }, /* 365 */
- { 9, 7, 12, 0, 0, 18432, 82, }, /* 366 */
- { 9, 12, 3, 0, 0, 26624, 96, }, /* 367 */
- { 9, 12, 3, 0, 0, 26624, 146, }, /* 368 */
- { 9, 13, 12, 0, 0, 18516, 138, }, /* 369 */
- { 9, 21, 12, 0, 0, 18432, 68, }, /* 370 */
- { 9, 23, 12, 0, 0, 14336, 68, }, /* 371 */
- { 10, 12, 3, 0, 0, 26624, 130, }, /* 372 */
- { 10, 10, 5, 0, 0, 18432, 144, }, /* 373 */
- { 10, 7, 12, 0, 0, 18432, 82, }, /* 374 */
- { 10, 12, 3, 0, 0, 26624, 96, }, /* 375 */
- { 10, 10, 3, 0, 0, 18432, 148, }, /* 376 */
- { 10, 12, 3, 0, 0, 26624, 146, }, /* 377 */
- { 10, 12, 3, 0, 0, 26624, 150, }, /* 378 */
- { 10, 13, 12, 0, 0, 18432, 138, }, /* 379 */
- { 10, 26, 12, 0, 0, 18432, 68, }, /* 380 */
- { 10, 15, 12, 0, 0, 18432, 68, }, /* 381 */
- { 11, 12, 3, 0, 0, 26624, 130, }, /* 382 */
- { 11, 7, 12, 0, 0, 18432, 82, }, /* 383 */
- { 11, 10, 3, 0, 0, 18432, 148, }, /* 384 */
- { 11, 10, 5, 0, 0, 18432, 144, }, /* 385 */
- { 11, 12, 3, 0, 0, 26624, 146, }, /* 386 */
- { 11, 13, 12, 0, 0, 18513, 138, }, /* 387 */
- { 11, 15, 12, 0, 0, 18513, 68, }, /* 388 */
- { 11, 26, 12, 0, 0, 28753, 68, }, /* 389 */
- { 11, 26, 12, 0, 0, 28672, 68, }, /* 390 */
- { 11, 23, 12, 0, 0, 14336, 68, }, /* 391 */
- { 12, 12, 3, 0, 0, 26624, 130, }, /* 392 */
- { 12, 10, 5, 0, 0, 18432, 144, }, /* 393 */
- { 12, 12, 3, 0, 0, 26624, 102, }, /* 394 */
- { 12, 7, 12, 0, 0, 18432, 82, }, /* 395 */
- { 12, 12, 3, 0, 0, 26624, 96, }, /* 396 */
- { 12, 12, 3, 0, 0, 26624, 146, }, /* 397 */
- { 12, 13, 12, 0, 0, 18432, 138, }, /* 398 */
- { 12, 21, 12, 0, 0, 18432, 68, }, /* 399 */
- { 12, 15, 12, 0, 0, 28672, 68, }, /* 400 */
- { 12, 26, 12, 0, 0, 18432, 68, }, /* 401 */
- { 13, 7, 12, 0, 0, 18432, 82, }, /* 402 */
- { 13, 12, 3, 0, 0, 26624, 130, }, /* 403 */
- { 13, 10, 5, 0, 0, 18432, 144, }, /* 404 */
- { 13, 21, 12, 0, 0, 18432, 68, }, /* 405 */
- { 13, 12, 3, 0, 0, 26624, 96, }, /* 406 */
- { 13, 12, 3, 0, 0, 18432, 130, }, /* 407 */
- { 13, 10, 3, 0, 0, 18432, 148, }, /* 408 */
- { 13, 12, 3, 0, 0, 26624, 146, }, /* 409 */
- { 13, 13, 12, 0, 0, 18528, 138, }, /* 410 */
- { 14, 12, 3, 0, 0, 26624, 130, }, /* 411 */
- { 14, 10, 5, 0, 0, 18432, 144, }, /* 412 */
- { 14, 7, 12, 0, 0, 18432, 82, }, /* 413 */
- { 14, 12, 3, 0, 0, 26624, 146, }, /* 414 */
- { 14, 10, 3, 0, 0, 18432, 148, }, /* 415 */
- { 14, 7, 4, 0, 0, 18432, 82, }, /* 416 */
- { 14, 26, 12, 0, 0, 18432, 68, }, /* 417 */
- { 14, 15, 12, 0, 0, 18432, 68, }, /* 418 */
- { 14, 13, 12, 0, 0, 18432, 138, }, /* 419 */
- { 15, 12, 3, 0, 0, 26624, 130, }, /* 420 */
- { 15, 10, 5, 0, 0, 18432, 144, }, /* 421 */
- { 15, 7, 12, 0, 0, 18432, 82, }, /* 422 */
- { 15, 12, 3, 0, 0, 26624, 146, }, /* 423 */
- { 15, 10, 3, 0, 0, 18432, 148, }, /* 424 */
- { 15, 13, 12, 0, 0, 18432, 138, }, /* 425 */
- { 15, 21, 12, 0, 0, 18432, 68, }, /* 426 */
- { 72, 7, 12, 0, 0, 18432, 82, }, /* 427 */
- { 72, 12, 3, 0, 0, 26624, 130, }, /* 428 */
- { 72, 7, 5, 0, 0, 18432, 152, }, /* 429 */
- { 72, 12, 3, 0, 0, 26624, 154, }, /* 430 */
- { 69, 23, 12, 0, 0, 14336, 68, }, /* 431 */
- { 72, 7, 12, 0, 0, 18432, 156, }, /* 432 */
- { 72, 6, 12, 0, 0, 18432, 136, }, /* 433 */
- { 72, 12, 3, 0, 0, 26624, 96, }, /* 434 */
- { 72, 21, 12, 0, 0, 18432, 68, }, /* 435 */
- { 72, 13, 12, 0, 0, 18432, 138, }, /* 436 */
- { 72, 21, 12, 0, 0, 18432, 106, }, /* 437 */
- { 73, 7, 12, 0, 0, 18432, 82, }, /* 438 */
- { 73, 12, 3, 0, 0, 26624, 130, }, /* 439 */
- { 73, 7, 5, 0, 0, 18432, 152, }, /* 440 */
- { 73, 12, 3, 0, 0, 26624, 146, }, /* 441 */
- { 73, 7, 12, 0, 0, 18432, 156, }, /* 442 */
- { 73, 6, 12, 0, 0, 18432, 136, }, /* 443 */
- { 73, 12, 3, 0, 0, 26624, 96, }, /* 444 */
- { 73, 13, 12, 0, 0, 18432, 138, }, /* 445 */
- { 74, 7, 12, 0, 0, 18432, 82, }, /* 446 */
- { 74, 26, 12, 0, 0, 18432, 68, }, /* 447 */
- { 74, 21, 12, 0, 0, 18432, 68, }, /* 448 */
- { 74, 21, 12, 0, 0, 18432, 106, }, /* 449 */
- { 74, 12, 3, 0, 0, 26624, 96, }, /* 450 */
- { 74, 13, 12, 0, 0, 18432, 138, }, /* 451 */
- { 74, 15, 12, 0, 0, 18432, 68, }, /* 452 */
- { 74, 22, 12, 0, 0, 28672, 158, }, /* 453 */
- { 74, 18, 12, 0, 0, 28672, 158, }, /* 454 */
- { 74, 10, 5, 0, 0, 18432, 160, }, /* 455 */
- { 74, 12, 3, 0, 0, 26624, 130, }, /* 456 */
- { 74, 12, 3, 0, 0, 26624, 162, }, /* 457 */
- { 74, 10, 5, 0, 0, 18432, 144, }, /* 458 */
- { 74, 12, 3, 0, 0, 26624, 146, }, /* 459 */
- { 69, 26, 12, 0, 0, 18432, 68, }, /* 460 */
- { 16, 7, 12, 0, 0, 18432, 82, }, /* 461 */
- { 16, 10, 12, 0, 0, 18432, 144, }, /* 462 */
- { 16, 12, 3, 0, 0, 26624, 130, }, /* 463 */
- { 16, 10, 5, 0, 0, 18432, 144, }, /* 464 */
- { 16, 12, 3, 0, 0, 26624, 96, }, /* 465 */
- { 16, 12, 3, 0, 0, 26624, 146, }, /* 466 */
- { 16, 13, 12, 0, 0, 18549, 138, }, /* 467 */
- { 16, 21, 12, 0, 0, 18432, 124, }, /* 468 */
- { 16, 21, 12, 0, 0, 18432, 68, }, /* 469 */
- { 16, 10, 12, 0, 0, 18432, 164, }, /* 470 */
- { 16, 12, 3, 0, 0, 26624, 128, }, /* 471 */
- { 16, 13, 12, 0, 0, 18432, 138, }, /* 472 */
- { 16, 26, 12, 0, 0, 18432, 68, }, /* 473 */
- { 17, 9, 12, 0, 7264, 18432, 74, }, /* 474 */
- { 17, 5, 12, 0, 3008, 18432, 166, }, /* 475 */
- { 69, 21, 12, 0, 0, 18510, 68, }, /* 476 */
- { 17, 6, 12, 0, 0, 18432, 142, }, /* 477 */
- { 18, 7, 6, 0, 0, 18432, 82, }, /* 478 */
- { 18, 7, 6, 0, 0, 18432, 168, }, /* 479 */
- { 18, 7, 7, 0, 0, 18432, 168, }, /* 480 */
- { 18, 7, 7, 0, 0, 18432, 82, }, /* 481 */
- { 18, 7, 8, 0, 0, 18432, 82, }, /* 482 */
- { 75, 7, 12, 0, 0, 18432, 82, }, /* 483 */
- { 75, 12, 3, 0, 0, 26624, 96, }, /* 484 */
- { 75, 21, 12, 0, 0, 18432, 68, }, /* 485 */
- { 75, 21, 12, 0, 0, 18432, 106, }, /* 486 */
- { 75, 21, 12, 0, 0, 18432, 124, }, /* 487 */
- { 75, 15, 12, 0, 0, 18432, 138, }, /* 488 */
- { 75, 15, 12, 0, 0, 18432, 68, }, /* 489 */
- { 75, 26, 12, 0, 0, 28672, 68, }, /* 490 */
- { 76, 9, 12, 0, 38864, 18432, 170, }, /* 491 */
- { 76, 9, 12, 0, 8, 18432, 170, }, /* 492 */
- { 76, 5, 12, 0, -8, 18432, 70, }, /* 493 */
- { 77, 17, 12, 0, 0, 28672, 126, }, /* 494 */
- { 77, 7, 12, 0, 0, 18432, 82, }, /* 495 */
- { 77, 26, 12, 0, 0, 18432, 68, }, /* 496 */
- { 77, 21, 12, 0, 0, 18432, 124, }, /* 497 */
- { 78, 29, 12, 0, 0, 45056, 52, }, /* 498 */
- { 78, 7, 12, 0, 0, 18432, 82, }, /* 499 */
- { 78, 22, 12, 0, 0, 28672, 158, }, /* 500 */
- { 78, 18, 12, 0, 0, 28672, 158, }, /* 501 */
- { 79, 7, 12, 0, 0, 18432, 82, }, /* 502 */
- { 69, 21, 12, 0, 0, 18432, 106, }, /* 503 */
- { 79, 14, 12, 0, 0, 18432, 82, }, /* 504 */
- { 25, 7, 12, 0, 0, 18432, 82, }, /* 505 */
- { 25, 12, 3, 0, 0, 26624, 130, }, /* 506 */
- { 25, 12, 3, 0, 0, 26624, 146, }, /* 507 */
- { 25, 10, 5, 0, 0, 18432, 172, }, /* 508 */
- { 26, 7, 12, 0, 0, 18432, 82, }, /* 509 */
- { 26, 12, 3, 0, 0, 26624, 130, }, /* 510 */
- { 26, 10, 5, 0, 0, 18432, 174, }, /* 511 */
- { 69, 21, 12, 0, 0, 18573, 124, }, /* 512 */
- { 27, 7, 12, 0, 0, 18432, 82, }, /* 513 */
- { 27, 12, 3, 0, 0, 26624, 130, }, /* 514 */
- { 28, 7, 12, 0, 0, 18432, 82, }, /* 515 */
- { 28, 12, 3, 0, 0, 26624, 130, }, /* 516 */
- { 80, 7, 12, 0, 0, 18432, 82, }, /* 517 */
- { 80, 7, 12, 0, 0, 18432, 140, }, /* 518 */
- { 80, 12, 3, 0, 0, 26624, 100, }, /* 519 */
- { 80, 10, 5, 0, 0, 18432, 144, }, /* 520 */
- { 80, 12, 3, 0, 0, 26624, 130, }, /* 521 */
- { 80, 12, 3, 0, 0, 26624, 96, }, /* 522 */
- { 80, 12, 3, 0, 0, 26624, 146, }, /* 523 */
- { 80, 21, 12, 0, 0, 18432, 106, }, /* 524 */
- { 80, 6, 12, 0, 0, 18432, 142, }, /* 525 */
- { 80, 21, 12, 0, 0, 18432, 68, }, /* 526 */
- { 80, 23, 12, 0, 0, 14336, 68, }, /* 527 */
- { 80, 13, 12, 0, 0, 18432, 138, }, /* 528 */
- { 80, 15, 12, 0, 0, 28672, 68, }, /* 529 */
- { 19, 21, 12, 0, 0, 28672, 68, }, /* 530 */
- { 69, 21, 12, 0, 0, 28777, 106, }, /* 531 */
- { 69, 21, 12, 0, 0, 28777, 124, }, /* 532 */
- { 19, 21, 12, 0, 0, 28672, 106, }, /* 533 */
- { 19, 17, 12, 0, 0, 28672, 126, }, /* 534 */
- { 19, 21, 12, 0, 0, 28672, 124, }, /* 535 */
- { 19, 21, 12, 0, 0, 28672, 176, }, /* 536 */
- { 19, 12, 3, 0, 0, 26624, 178, }, /* 537 */
- { 19, 1, 2, 0, 0, 6144, 66, }, /* 538 */
- { 19, 13, 12, 0, 0, 18432, 138, }, /* 539 */
- { 19, 7, 12, 0, 0, 18432, 82, }, /* 540 */
- { 19, 6, 12, 0, 0, 18432, 136, }, /* 541 */
- { 19, 12, 3, 0, 0, 26624, 180, }, /* 542 */
- { 19, 12, 3, 0, 0, 26624, 130, }, /* 543 */
- { 29, 7, 12, 0, 0, 18432, 82, }, /* 544 */
- { 29, 12, 3, 0, 0, 26624, 130, }, /* 545 */
- { 29, 10, 5, 0, 0, 18432, 144, }, /* 546 */
- { 29, 12, 3, 0, 0, 26624, 96, }, /* 547 */
- { 29, 26, 12, 0, 0, 28672, 68, }, /* 548 */
- { 29, 21, 12, 0, 0, 28672, 124, }, /* 549 */
- { 29, 13, 12, 0, 0, 18432, 138, }, /* 550 */
- { 30, 7, 12, 0, 0, 18432, 82, }, /* 551 */
- { 89, 7, 12, 0, 0, 18432, 82, }, /* 552 */
- { 89, 7, 12, 0, 0, 18432, 156, }, /* 553 */
- { 89, 13, 12, 0, 0, 18432, 138, }, /* 554 */
- { 89, 15, 12, 0, 0, 18432, 138, }, /* 555 */
- { 89, 26, 12, 0, 0, 28672, 68, }, /* 556 */
- { 80, 26, 12, 0, 0, 28672, 68, }, /* 557 */
- { 33, 7, 12, 0, 0, 18432, 82, }, /* 558 */
- { 33, 12, 3, 0, 0, 26624, 130, }, /* 559 */
- { 33, 10, 5, 0, 0, 18432, 144, }, /* 560 */
- { 33, 21, 12, 0, 0, 18432, 68, }, /* 561 */
- { 106, 7, 12, 0, 0, 18432, 82, }, /* 562 */
- { 106, 10, 5, 0, 0, 18432, 144, }, /* 563 */
- { 106, 12, 3, 0, 0, 26624, 130, }, /* 564 */
- { 106, 12, 3, 0, 0, 26624, 182, }, /* 565 */
- { 106, 10, 12, 0, 0, 18432, 144, }, /* 566 */
- { 106, 12, 3, 0, 0, 26624, 96, }, /* 567 */
- { 106, 13, 12, 0, 0, 18432, 138, }, /* 568 */
- { 106, 21, 12, 0, 0, 18432, 68, }, /* 569 */
- { 106, 6, 12, 0, 0, 18432, 136, }, /* 570 */
- { 106, 21, 12, 0, 0, 18432, 124, }, /* 571 */
- { 84, 11, 3, 0, 0, 26624, 184, }, /* 572 */
- { 84, 12, 3, 0, 0, 26624, 130, }, /* 573 */
- { 93, 12, 3, 0, 0, 26624, 130, }, /* 574 */
- { 93, 10, 5, 0, 0, 18432, 144, }, /* 575 */
- { 93, 7, 12, 0, 0, 18432, 82, }, /* 576 */
- { 93, 12, 3, 0, 0, 26624, 96, }, /* 577 */
- { 93, 10, 3, 0, 0, 18432, 148, }, /* 578 */
- { 93, 10, 5, 0, 0, 18432, 172, }, /* 579 */
- { 93, 13, 12, 0, 0, 18432, 138, }, /* 580 */
- { 93, 21, 12, 0, 0, 18432, 124, }, /* 581 */
- { 93, 21, 12, 0, 0, 18432, 68, }, /* 582 */
- { 93, 21, 12, 0, 0, 18432, 106, }, /* 583 */
- { 93, 26, 12, 0, 0, 18432, 68, }, /* 584 */
- { 96, 12, 3, 0, 0, 26624, 130, }, /* 585 */
- { 96, 10, 5, 0, 0, 18432, 144, }, /* 586 */
- { 96, 7, 12, 0, 0, 18432, 82, }, /* 587 */
- { 96, 10, 5, 0, 0, 18432, 172, }, /* 588 */
- { 96, 12, 3, 0, 0, 26624, 146, }, /* 589 */
- { 96, 13, 12, 0, 0, 18432, 138, }, /* 590 */
- { 119, 7, 12, 0, 0, 18432, 82, }, /* 591 */
- { 119, 12, 3, 0, 0, 26624, 102, }, /* 592 */
- { 119, 10, 5, 0, 0, 18432, 144, }, /* 593 */
- { 119, 12, 3, 0, 0, 26624, 130, }, /* 594 */
- { 119, 10, 5, 0, 0, 18432, 174, }, /* 595 */
- { 119, 21, 12, 0, 0, 18432, 68, }, /* 596 */
- { 97, 7, 12, 0, 0, 18432, 82, }, /* 597 */
- { 97, 10, 5, 0, 0, 18432, 144, }, /* 598 */
- { 97, 12, 3, 0, 0, 26624, 130, }, /* 599 */
- { 97, 12, 3, 0, 0, 26624, 186, }, /* 600 */
- { 97, 12, 3, 0, 0, 26624, 96, }, /* 601 */
- { 97, 21, 12, 0, 0, 18432, 124, }, /* 602 */
- { 97, 21, 12, 0, 0, 18432, 106, }, /* 603 */
- { 97, 13, 12, 0, 0, 18432, 138, }, /* 604 */
- { 98, 13, 12, 0, 0, 18432, 138, }, /* 605 */
- { 98, 7, 12, 0, 0, 18432, 82, }, /* 606 */
- { 98, 6, 12, 0, 0, 18432, 92, }, /* 607 */
- { 98, 6, 12, 0, 0, 18432, 94, }, /* 608 */
- { 98, 21, 12, 0, 0, 18432, 124, }, /* 609 */
- { 2, 5, 12, 63, -6222, 18432, 70, }, /* 610 */
- { 2, 5, 12, 67, -6221, 18432, 70, }, /* 611 */
- { 2, 5, 12, 71, -6212, 18432, 70, }, /* 612 */
- { 2, 5, 12, 75, -6210, 18432, 70, }, /* 613 */
- { 2, 5, 12, 79, -6210, 18432, 70, }, /* 614 */
- { 2, 5, 12, 79, -6211, 18432, 70, }, /* 615 */
- { 2, 5, 12, 84, -6204, 18432, 70, }, /* 616 */
- { 2, 5, 12, 88, -6180, 18432, 70, }, /* 617 */
- { 2, 5, 12, 108, 35267, 18432, 70, }, /* 618 */
- { 17, 9, 12, 0, -3008, 18432, 74, }, /* 619 */
- { 96, 21, 12, 0, 0, 18432, 68, }, /* 620 */
- { 84, 12, 3, 0, 0, 26762, 96, }, /* 621 */
- { 84, 12, 3, 0, 0, 26630, 96, }, /* 622 */
- { 69, 21, 12, 0, 0, 18498, 188, }, /* 623 */
- { 84, 12, 3, 0, 0, 26666, 96, }, /* 624 */
- { 84, 12, 3, 0, 0, 26696, 96, }, /* 625 */
- { 84, 12, 3, 0, 0, 26780, 96, }, /* 626 */
- { 69, 10, 5, 0, 0, 18474, 160, }, /* 627 */
- { 69, 7, 12, 0, 0, 18501, 82, }, /* 628 */
- { 69, 7, 12, 0, 0, 18474, 82, }, /* 629 */
- { 69, 7, 12, 0, 0, 18438, 82, }, /* 630 */
- { 69, 7, 12, 0, 0, 18594, 82, }, /* 631 */
- { 69, 7, 12, 0, 0, 18498, 82, }, /* 632 */
- { 84, 12, 3, 0, 0, 26750, 96, }, /* 633 */
- { 69, 10, 5, 0, 0, 18435, 160, }, /* 634 */
- { 84, 12, 3, 0, 0, 26690, 96, }, /* 635 */
- { 69, 7, 12, 0, 0, 18453, 82, }, /* 636 */
- { 2, 5, 12, 0, 0, 18432, 60, }, /* 637 */
- { 1, 6, 12, 0, 0, 18432, 88, }, /* 638 */
- { 2, 6, 12, 0, 0, 18432, 190, }, /* 639 */
- { 0, 5, 12, 0, 35332, 18432, 76, }, /* 640 */
- { 0, 5, 12, 0, 3814, 18432, 76, }, /* 641 */
- { 0, 5, 12, 0, 35384, 18432, 76, }, /* 642 */
- { 0, 5, 12, 0, 0, 18432, 192, }, /* 643 */
- { 0, 6, 12, 0, 0, 18432, 190, }, /* 644 */
- { 0, 6, 12, 0, 0, 18432, 194, }, /* 645 */
- { 1, 6, 12, 0, 0, 18432, 190, }, /* 646 */
- { 84, 12, 3, 0, 0, 26636, 102, }, /* 647 */
- { 84, 12, 3, 0, 0, 26687, 96, }, /* 648 */
- { 84, 12, 3, 0, 0, 26648, 96, }, /* 649 */
- { 0, 9, 12, 92, 1, 18432, 74, }, /* 650 */
- { 0, 5, 12, 92, -1, 18432, 76, }, /* 651 */
- { 0, 5, 12, 0, 0, 18432, 70, }, /* 652 */
- { 0, 5, 12, 92, -58, 18432, 70, }, /* 653 */
- { 0, 9, 12, 0, -7615, 18432, 74, }, /* 654 */
- { 1, 5, 12, 0, 8, 18432, 76, }, /* 655 */
- { 1, 9, 12, 0, -8, 18432, 74, }, /* 656 */
- { 1, 5, 12, 0, 74, 18432, 76, }, /* 657 */
- { 1, 5, 12, 0, 86, 18432, 76, }, /* 658 */
- { 1, 5, 12, 0, 100, 18432, 76, }, /* 659 */
- { 1, 5, 12, 0, 128, 18432, 76, }, /* 660 */
- { 1, 5, 12, 0, 112, 18432, 76, }, /* 661 */
- { 1, 5, 12, 0, 126, 18432, 76, }, /* 662 */
- { 1, 5, 12, 0, 8, 18432, 70, }, /* 663 */
- { 1, 8, 12, 0, -8, 18432, 86, }, /* 664 */
- { 1, 5, 12, 0, 0, 18432, 70, }, /* 665 */
- { 1, 5, 12, 0, 9, 18432, 70, }, /* 666 */
- { 1, 9, 12, 0, -74, 18432, 74, }, /* 667 */
- { 1, 8, 12, 0, -9, 18432, 86, }, /* 668 */
- { 1, 5, 12, 21, -7173, 18432, 76, }, /* 669 */
- { 1, 9, 12, 0, -86, 18432, 74, }, /* 670 */
- { 1, 9, 12, 0, -100, 18432, 74, }, /* 671 */
- { 1, 9, 12, 0, -112, 18432, 74, }, /* 672 */
- { 1, 9, 12, 0, -128, 18432, 74, }, /* 673 */
- { 1, 9, 12, 0, -126, 18432, 74, }, /* 674 */
- { 69, 29, 12, 0, 0, 45056, 52, }, /* 675 */
- { 84, 1, 3, 0, 0, 6144, 196, }, /* 676 */
- { 84, 1, 13, 0, 0, 6144, 198, }, /* 677 */
- { 69, 1, 2, 0, 0, 18432, 200, }, /* 678 */
- { 69, 1, 2, 0, 0, 34816, 200, }, /* 679 */
- { 69, 17, 12, 0, 0, 28672, 202, }, /* 680 */
- { 69, 21, 12, 0, 0, 28672, 64, }, /* 681 */
- { 69, 20, 12, 0, 0, 28672, 204, }, /* 682 */
- { 69, 19, 12, 0, 0, 28672, 204, }, /* 683 */
- { 69, 22, 12, 0, 0, 28672, 206, }, /* 684 */
- { 69, 20, 12, 0, 0, 28672, 206, }, /* 685 */
- { 69, 19, 12, 0, 0, 28672, 206, }, /* 686 */
- { 69, 21, 12, 0, 0, 28672, 208, }, /* 687 */
- { 69, 27, 2, 0, 0, 45056, 50, }, /* 688 */
- { 69, 28, 2, 0, 0, 4096, 50, }, /* 689 */
- { 69, 1, 2, 0, 0, 20480, 134, }, /* 690 */
- { 69, 1, 2, 0, 0, 36864, 134, }, /* 691 */
- { 69, 1, 2, 0, 0, 30720, 134, }, /* 692 */
- { 69, 1, 2, 0, 0, 24576, 134, }, /* 693 */
- { 69, 1, 2, 0, 0, 40960, 134, }, /* 694 */
- { 69, 29, 12, 0, 0, 8291, 52, }, /* 695 */
- { 69, 21, 12, 0, 0, 14336, 54, }, /* 696 */
- { 69, 21, 12, 0, 0, 14336, 64, }, /* 697 */
- { 69, 21, 14, 0, 0, 28672, 210, }, /* 698 */
- { 69, 21, 12, 0, 0, 28672, 212, }, /* 699 */
- { 69, 16, 12, 0, 0, 28672, 138, }, /* 700 */
- { 69, 16, 12, 0, 0, 28672, 214, }, /* 701 */
- { 69, 25, 12, 0, 0, 8192, 64, }, /* 702 */
- { 69, 22, 12, 0, 0, 28672, 216, }, /* 703 */
- { 69, 18, 12, 0, 0, 28672, 216, }, /* 704 */
- { 69, 21, 12, 0, 0, 28672, 202, }, /* 705 */
- { 69, 1, 2, 0, 0, 6144, 218, }, /* 706 */
- { 68, 2, 2, 0, 0, 6144, 220, }, /* 707 */
- { 69, 1, 2, 0, 0, 22528, 134, }, /* 708 */
- { 69, 1, 2, 0, 0, 38912, 134, }, /* 709 */
- { 69, 1, 2, 0, 0, 16384, 134, }, /* 710 */
- { 69, 1, 2, 0, 0, 32768, 134, }, /* 711 */
- { 69, 1, 2, 0, 0, 6144, 222, }, /* 712 */
- { 69, 25, 12, 0, 0, 12288, 118, }, /* 713 */
- { 69, 25, 12, 0, 0, 12288, 224, }, /* 714 */
- { 69, 25, 12, 0, 0, 28672, 118, }, /* 715 */
- { 69, 22, 12, 0, 0, 28672, 226, }, /* 716 */
- { 69, 18, 12, 0, 0, 28672, 226, }, /* 717 */
- { 68, 2, 12, 0, 0, 14336, 0, }, /* 718 */
- { 84, 12, 3, 0, 0, 26624, 228, }, /* 719 */
- { 84, 11, 3, 0, 0, 26624, 120, }, /* 720 */
- { 84, 11, 3, 0, 0, 26624, 230, }, /* 721 */
- { 84, 12, 3, 0, 0, 26753, 102, }, /* 722 */
- { 69, 26, 12, 0, 0, 28672, 68, }, /* 723 */
- { 69, 9, 12, 0, 0, 18432, 112, }, /* 724 */
- { 69, 5, 12, 0, 0, 18432, 232, }, /* 725 */
- { 69, 25, 12, 0, 0, 28672, 234, }, /* 726 */
- { 69, 26, 14, 0, 0, 28672, 236, }, /* 727 */
- { 1, 9, 12, 96, -7517, 18432, 74, }, /* 728 */
- { 69, 26, 12, 0, 0, 28672, 118, }, /* 729 */
- { 0, 9, 12, 100, -8383, 18432, 74, }, /* 730 */
- { 0, 9, 12, 104, -8262, 18432, 74, }, /* 731 */
- { 69, 26, 12, 0, 0, 14336, 238, }, /* 732 */
- { 0, 9, 12, 0, 28, 18432, 74, }, /* 733 */
- { 69, 7, 12, 0, 0, 18432, 240, }, /* 734 */
- { 69, 5, 14, 0, 0, 18432, 242, }, /* 735 */
- { 69, 5, 12, 0, 0, 18432, 244, }, /* 736 */
- { 0, 5, 12, 0, -28, 18432, 76, }, /* 737 */
- { 0, 14, 12, 0, 16, 18432, 74, }, /* 738 */
- { 0, 14, 12, 0, -16, 18432, 76, }, /* 739 */
- { 0, 14, 12, 0, 0, 18432, 82, }, /* 740 */
- { 69, 25, 14, 0, 0, 28672, 246, }, /* 741 */
- { 69, 26, 14, 0, 0, 28672, 246, }, /* 742 */
- { 69, 26, 12, 0, 0, 28672, 64, }, /* 743 */
- { 69, 25, 12, 0, 0, 28672, 248, }, /* 744 */
- { 69, 25, 12, 0, 0, 12288, 250, }, /* 745 */
- { 69, 22, 12, 0, 0, 28672, 248, }, /* 746 */
- { 69, 18, 12, 0, 0, 28672, 248, }, /* 747 */
- { 69, 26, 14, 0, 0, 28672, 252, }, /* 748 */
- { 69, 22, 12, 0, 0, 28672, 254, }, /* 749 */
- { 69, 18, 12, 0, 0, 28672, 254, }, /* 750 */
- { 69, 26, 12, 0, 0, 18432, 54, }, /* 751 */
- { 69, 26, 14, 0, 0, 28672, 256, }, /* 752 */
- { 68, 2, 12, 0, 0, 18432, 258, }, /* 753 */
- { 69, 26, 12, 0, 26, 18432, 260, }, /* 754 */
- { 69, 26, 14, 0, 26, 18432, 262, }, /* 755 */
- { 69, 26, 12, 0, -26, 18432, 264, }, /* 756 */
- { 69, 25, 14, 0, 0, 28672, 266, }, /* 757 */
- { 69, 26, 14, 0, 0, 28672, 268, }, /* 758 */
- { 69, 26, 14, 0, 0, 28672, 270, }, /* 759 */
- { 69, 25, 14, 0, 0, 28672, 268, }, /* 760 */
- { 69, 26, 14, 0, 0, 18432, 256, }, /* 761 */
- { 69, 26, 14, 0, 0, 28672, 272, }, /* 762 */
- { 88, 26, 12, 0, 0, 18432, 54, }, /* 763 */
- { 69, 26, 12, 0, 0, 28672, 216, }, /* 764 */
- { 35, 9, 12, 0, 48, 18432, 74, }, /* 765 */
- { 35, 5, 12, 0, -48, 18432, 76, }, /* 766 */
- { 0, 9, 12, 0, -10743, 18432, 74, }, /* 767 */
- { 0, 9, 12, 0, -3814, 18432, 74, }, /* 768 */
- { 0, 9, 12, 0, -10727, 18432, 74, }, /* 769 */
- { 0, 5, 12, 0, -10795, 18432, 76, }, /* 770 */
- { 0, 5, 12, 0, -10792, 18432, 76, }, /* 771 */
- { 0, 9, 12, 0, -10780, 18432, 74, }, /* 772 */
- { 0, 9, 12, 0, -10749, 18432, 74, }, /* 773 */
- { 0, 9, 12, 0, -10783, 18432, 74, }, /* 774 */
- { 0, 9, 12, 0, -10782, 18432, 74, }, /* 775 */
- { 0, 9, 12, 0, -10815, 18432, 74, }, /* 776 */
- { 34, 5, 12, 0, 0, 18432, 60, }, /* 777 */
- { 34, 26, 12, 0, 0, 28672, 68, }, /* 778 */
- { 34, 12, 3, 0, 0, 26624, 96, }, /* 779 */
- { 34, 21, 12, 0, 0, 28672, 68, }, /* 780 */
- { 34, 15, 12, 0, 0, 28672, 68, }, /* 781 */
- { 17, 5, 12, 0, -7264, 18432, 76, }, /* 782 */
- { 90, 7, 12, 0, 0, 18432, 82, }, /* 783 */
- { 90, 6, 12, 0, 0, 18432, 142, }, /* 784 */
- { 90, 21, 12, 0, 0, 18432, 68, }, /* 785 */
- { 90, 12, 3, 0, 0, 26624, 182, }, /* 786 */
- { 2, 12, 3, 0, 0, 26624, 130, }, /* 787 */
- { 69, 20, 12, 0, 0, 28672, 216, }, /* 788 */
- { 69, 19, 12, 0, 0, 28672, 216, }, /* 789 */
- { 69, 6, 12, 0, 0, 28672, 274, }, /* 790 */
- { 69, 21, 12, 0, 0, 28672, 276, }, /* 791 */
- { 69, 21, 12, 0, 0, 28726, 54, }, /* 792 */
- { 23, 26, 12, 0, 0, 28672, 278, }, /* 793 */
- { 69, 26, 12, 0, 0, 28672, 280, }, /* 794 */
- { 69, 26, 12, 0, 0, 28672, 282, }, /* 795 */
- { 69, 21, 12, 0, 0, 28825, 276, }, /* 796 */
- { 69, 21, 12, 0, 0, 28825, 212, }, /* 797 */
- { 69, 21, 12, 0, 0, 28819, 54, }, /* 798 */
- { 23, 6, 12, 0, 0, 18432, 136, }, /* 799 */
- { 69, 7, 12, 0, 0, 18447, 284, }, /* 800 */
- { 23, 14, 12, 0, 0, 18432, 284, }, /* 801 */
- { 69, 22, 12, 0, 0, 28825, 216, }, /* 802 */
- { 69, 18, 12, 0, 0, 28825, 216, }, /* 803 */
- { 69, 22, 12, 0, 0, 28825, 62, }, /* 804 */
- { 69, 18, 12, 0, 0, 28825, 62, }, /* 805 */
- { 69, 26, 12, 0, 0, 28819, 54, }, /* 806 */
- { 69, 17, 12, 0, 0, 28819, 202, }, /* 807 */
- { 69, 22, 12, 0, 0, 28819, 206, }, /* 808 */
- { 69, 18, 12, 0, 0, 28819, 206, }, /* 809 */
- { 84, 12, 3, 0, 0, 26669, 96, }, /* 810 */
- { 18, 10, 3, 0, 0, 18432, 286, }, /* 811 */
- { 69, 17, 14, 0, 0, 28819, 288, }, /* 812 */
- { 69, 6, 12, 0, 0, 18525, 136, }, /* 813 */
- { 69, 26, 12, 0, 0, 28819, 68, }, /* 814 */
- { 23, 6, 12, 0, 0, 18432, 142, }, /* 815 */
- { 69, 7, 12, 0, 0, 18564, 82, }, /* 816 */
- { 69, 21, 14, 0, 0, 28804, 236, }, /* 817 */
- { 69, 26, 12, 0, 0, 28687, 68, }, /* 818 */
- { 20, 7, 12, 0, 0, 18432, 82, }, /* 819 */
- { 84, 12, 3, 0, 0, 26717, 96, }, /* 820 */
- { 69, 24, 12, 0, 0, 28765, 290, }, /* 821 */
- { 20, 6, 12, 0, 0, 18432, 136, }, /* 822 */
- { 69, 17, 12, 0, 0, 28765, 126, }, /* 823 */
- { 21, 7, 12, 0, 0, 18432, 82, }, /* 824 */
- { 69, 21, 12, 0, 0, 28825, 68, }, /* 825 */
- { 69, 6, 12, 0, 0, 18525, 94, }, /* 826 */
- { 21, 6, 12, 0, 0, 18432, 136, }, /* 827 */
- { 22, 7, 12, 0, 0, 18432, 82, }, /* 828 */
- { 18, 7, 12, 0, 0, 18432, 82, }, /* 829 */
- { 18, 7, 12, 0, 0, 18432, 168, }, /* 830 */
- { 69, 26, 12, 0, 0, 18447, 68, }, /* 831 */
- { 69, 15, 12, 0, 0, 18447, 68, }, /* 832 */
- { 18, 26, 12, 0, 0, 18432, 68, }, /* 833 */
- { 18, 26, 12, 0, 0, 28672, 68, }, /* 834 */
- { 69, 15, 12, 0, 0, 18432, 68, }, /* 835 */
- { 69, 26, 14, 0, 0, 18447, 236, }, /* 836 */
- { 21, 26, 12, 0, 0, 18432, 68, }, /* 837 */
- { 23, 7, 12, 0, 0, 18432, 292, }, /* 838 */
- { 24, 7, 12, 0, 0, 18432, 82, }, /* 839 */
- { 24, 6, 12, 0, 0, 18432, 136, }, /* 840 */
- { 24, 26, 12, 0, 0, 28672, 68, }, /* 841 */
- { 111, 7, 12, 0, 0, 18432, 82, }, /* 842 */
- { 111, 6, 12, 0, 0, 18432, 142, }, /* 843 */
- { 111, 21, 12, 0, 0, 18432, 106, }, /* 844 */
- { 111, 21, 12, 0, 0, 18432, 124, }, /* 845 */
- { 99, 7, 12, 0, 0, 18432, 82, }, /* 846 */
- { 99, 6, 12, 0, 0, 18432, 136, }, /* 847 */
- { 99, 21, 12, 0, 0, 28672, 106, }, /* 848 */
- { 99, 21, 12, 0, 0, 28672, 124, }, /* 849 */
- { 99, 13, 12, 0, 0, 18432, 138, }, /* 850 */
- { 2, 9, 12, 108, 1, 18432, 74, }, /* 851 */
- { 2, 5, 12, 108, -35267, 18432, 76, }, /* 852 */
- { 2, 7, 12, 0, 0, 18432, 82, }, /* 853 */
- { 2, 21, 12, 0, 0, 28672, 68, }, /* 854 */
- { 2, 12, 3, 0, 0, 26624, 96, }, /* 855 */
- { 2, 6, 12, 0, 0, 28672, 92, }, /* 856 */
- { 2, 6, 12, 0, 0, 18432, 88, }, /* 857 */
- { 112, 7, 12, 0, 0, 18432, 82, }, /* 858 */
- { 112, 14, 12, 0, 0, 18432, 82, }, /* 859 */
- { 112, 12, 3, 0, 0, 26624, 96, }, /* 860 */
- { 112, 21, 12, 0, 0, 18432, 68, }, /* 861 */
- { 112, 21, 12, 0, 0, 18432, 124, }, /* 862 */
- { 112, 21, 12, 0, 0, 18432, 106, }, /* 863 */
- { 69, 24, 12, 0, 0, 28762, 56, }, /* 864 */
- { 0, 9, 12, 0, -35332, 18432, 74, }, /* 865 */
- { 69, 24, 12, 0, 0, 18432, 56, }, /* 866 */
- { 0, 9, 12, 0, -42280, 18432, 74, }, /* 867 */
- { 0, 5, 12, 0, 48, 18432, 76, }, /* 868 */
- { 0, 9, 12, 0, -42308, 18432, 74, }, /* 869 */
- { 0, 9, 12, 0, -42319, 18432, 74, }, /* 870 */
- { 0, 9, 12, 0, -42315, 18432, 74, }, /* 871 */
- { 0, 9, 12, 0, -42305, 18432, 74, }, /* 872 */
- { 0, 9, 12, 0, -42258, 18432, 74, }, /* 873 */
- { 0, 9, 12, 0, -42282, 18432, 74, }, /* 874 */
- { 0, 9, 12, 0, -42261, 18432, 74, }, /* 875 */
- { 0, 9, 12, 0, 928, 18432, 74, }, /* 876 */
- { 0, 9, 12, 0, -48, 18432, 74, }, /* 877 */
- { 0, 9, 12, 0, -42307, 18432, 74, }, /* 878 */
- { 0, 9, 12, 0, -35384, 18432, 74, }, /* 879 */
- { 0, 6, 12, 0, 0, 18432, 142, }, /* 880 */
- { 36, 7, 12, 0, 0, 18432, 82, }, /* 881 */
- { 36, 12, 3, 0, 0, 26624, 130, }, /* 882 */
- { 36, 12, 3, 0, 0, 26624, 182, }, /* 883 */
- { 36, 10, 5, 0, 0, 18432, 144, }, /* 884 */
- { 36, 26, 12, 0, 0, 28672, 68, }, /* 885 */
- { 69, 15, 12, 0, 0, 18612, 68, }, /* 886 */
- { 69, 15, 12, 0, 0, 18609, 68, }, /* 887 */
- { 69, 26, 12, 0, 0, 18600, 68, }, /* 888 */
- { 69, 23, 12, 0, 0, 14504, 68, }, /* 889 */
- { 69, 26, 12, 0, 0, 14504, 68, }, /* 890 */
- { 37, 7, 12, 0, 0, 18432, 82, }, /* 891 */
- { 37, 21, 12, 0, 0, 28672, 68, }, /* 892 */
- { 37, 21, 12, 0, 0, 28672, 124, }, /* 893 */
- { 100, 10, 5, 0, 0, 18432, 144, }, /* 894 */
- { 100, 7, 12, 0, 0, 18432, 82, }, /* 895 */
- { 100, 12, 3, 0, 0, 26624, 146, }, /* 896 */
- { 100, 12, 3, 0, 0, 26624, 130, }, /* 897 */
- { 100, 21, 12, 0, 0, 18432, 124, }, /* 898 */
- { 100, 13, 12, 0, 0, 18432, 138, }, /* 899 */
- { 6, 12, 3, 0, 0, 26666, 96, }, /* 900 */
- { 6, 7, 12, 0, 0, 18507, 82, }, /* 901 */
- { 39, 13, 12, 0, 0, 18432, 138, }, /* 902 */
- { 39, 7, 12, 0, 0, 18432, 82, }, /* 903 */
- { 39, 12, 3, 0, 0, 26624, 130, }, /* 904 */
- { 39, 12, 3, 0, 0, 26624, 96, }, /* 905 */
- { 69, 21, 12, 0, 0, 18567, 188, }, /* 906 */
- { 39, 21, 12, 0, 0, 18432, 124, }, /* 907 */
- { 101, 7, 12, 0, 0, 18432, 82, }, /* 908 */
- { 101, 12, 3, 0, 0, 26624, 130, }, /* 909 */
- { 101, 10, 5, 0, 0, 18432, 144, }, /* 910 */
- { 101, 10, 5, 0, 0, 18432, 172, }, /* 911 */
- { 101, 21, 12, 0, 0, 18432, 68, }, /* 912 */
- { 40, 12, 3, 0, 0, 26624, 130, }, /* 913 */
- { 40, 10, 5, 0, 0, 18432, 144, }, /* 914 */
- { 40, 7, 12, 0, 0, 18432, 82, }, /* 915 */
- { 40, 12, 3, 0, 0, 26624, 96, }, /* 916 */
- { 40, 10, 5, 0, 0, 18432, 172, }, /* 917 */
- { 40, 21, 12, 0, 0, 18432, 68, }, /* 918 */
- { 40, 21, 12, 0, 0, 18432, 106, }, /* 919 */
- { 40, 21, 12, 0, 0, 18432, 124, }, /* 920 */
- { 69, 6, 12, 0, 0, 18480, 136, }, /* 921 */
- { 40, 13, 12, 0, 0, 18432, 138, }, /* 922 */
- { 16, 6, 12, 0, 0, 18432, 136, }, /* 923 */
- { 105, 7, 12, 0, 0, 18432, 82, }, /* 924 */
- { 105, 12, 3, 0, 0, 26624, 130, }, /* 925 */
- { 105, 10, 5, 0, 0, 18432, 144, }, /* 926 */
- { 105, 13, 12, 0, 0, 18432, 138, }, /* 927 */
- { 105, 21, 12, 0, 0, 18432, 68, }, /* 928 */
- { 105, 21, 12, 0, 0, 18432, 124, }, /* 929 */
- { 107, 7, 12, 0, 0, 18432, 82, }, /* 930 */
- { 107, 12, 3, 0, 0, 26624, 130, }, /* 931 */
- { 107, 7, 12, 0, 0, 18432, 156, }, /* 932 */
- { 107, 12, 3, 0, 0, 26624, 96, }, /* 933 */
- { 107, 7, 12, 0, 0, 18432, 294, }, /* 934 */
- { 107, 6, 12, 0, 0, 18432, 136, }, /* 935 */
- { 107, 21, 12, 0, 0, 18432, 68, }, /* 936 */
- { 107, 21, 12, 0, 0, 18432, 106, }, /* 937 */
- { 113, 7, 12, 0, 0, 18432, 82, }, /* 938 */
- { 113, 10, 5, 0, 0, 18432, 144, }, /* 939 */
- { 113, 12, 3, 0, 0, 26624, 130, }, /* 940 */
- { 113, 21, 12, 0, 0, 18432, 124, }, /* 941 */
- { 113, 6, 12, 0, 0, 18432, 136, }, /* 942 */
- { 113, 12, 3, 0, 0, 26624, 146, }, /* 943 */
- { 0, 5, 12, 0, -928, 18432, 76, }, /* 944 */
- { 0, 6, 12, 0, 0, 18432, 92, }, /* 945 */
- { 76, 5, 12, 0, -38864, 18432, 70, }, /* 946 */
- { 113, 10, 5, 0, 0, 18432, 160, }, /* 947 */
- { 113, 13, 12, 0, 0, 18432, 138, }, /* 948 */
- { 18, 7, 9, 0, 0, 18432, 82, }, /* 949 */
- { 18, 7, 10, 0, 0, 18432, 82, }, /* 950 */
- { 68, 4, 12, 0, 0, 18432, 0, }, /* 951 */
- { 68, 3, 12, 0, 0, 18432, 0, }, /* 952 */
- { 23, 7, 12, 0, 0, 18432, 284, }, /* 953 */
- { 71, 25, 12, 0, 0, 12288, 118, }, /* 954 */
- { 3, 7, 12, 0, 0, 0, 296, }, /* 955 */
- { 69, 18, 12, 0, 0, 28705, 54, }, /* 956 */
- { 69, 22, 12, 0, 0, 28705, 54, }, /* 957 */
- { 68, 2, 12, 0, 0, 6144, 298, }, /* 958 */
- { 3, 7, 12, 0, 0, 39, 82, }, /* 959 */
- { 3, 26, 12, 0, 0, 28711, 68, }, /* 960 */
- { 84, 12, 3, 0, 0, 26624, 178, }, /* 961 */
- { 84, 12, 3, 0, 0, 26624, 300, }, /* 962 */
- { 69, 21, 12, 0, 0, 28672, 68, }, /* 963 */
- { 69, 21, 12, 0, 0, 28672, 122, }, /* 964 */
- { 69, 22, 12, 0, 0, 28672, 68, }, /* 965 */
- { 69, 18, 12, 0, 0, 28672, 68, }, /* 966 */
- { 69, 17, 12, 0, 0, 28672, 126, }, /* 967 */
- { 69, 22, 12, 0, 0, 28672, 302, }, /* 968 */
- { 69, 18, 12, 0, 0, 28672, 302, }, /* 969 */
- { 69, 21, 12, 0, 0, 8192, 106, }, /* 970 */
- { 69, 21, 12, 0, 0, 8192, 304, }, /* 971 */
- { 69, 21, 12, 0, 0, 8192, 306, }, /* 972 */
- { 69, 21, 12, 0, 0, 28672, 124, }, /* 973 */
- { 69, 22, 12, 0, 0, 28672, 158, }, /* 974 */
- { 69, 18, 12, 0, 0, 28672, 158, }, /* 975 */
- { 69, 21, 12, 0, 0, 14336, 68, }, /* 976 */
- { 69, 21, 12, 0, 0, 28672, 118, }, /* 977 */
- { 69, 17, 12, 0, 0, 12288, 224, }, /* 978 */
- { 69, 25, 12, 0, 0, 28672, 226, }, /* 979 */
- { 69, 21, 12, 0, 0, 28672, 302, }, /* 980 */
- { 69, 21, 12, 0, 0, 28672, 308, }, /* 981 */
- { 69, 17, 12, 0, 0, 12288, 126, }, /* 982 */
- { 69, 21, 12, 0, 0, 8192, 68, }, /* 983 */
- { 69, 13, 12, 0, 0, 10240, 310, }, /* 984 */
- { 0, 9, 12, 0, 32, 18432, 312, }, /* 985 */
- { 69, 24, 12, 0, 0, 28672, 314, }, /* 986 */
- { 0, 5, 12, 0, -32, 18432, 316, }, /* 987 */
- { 69, 21, 12, 0, 0, 28825, 124, }, /* 988 */
- { 69, 22, 12, 0, 0, 28825, 318, }, /* 989 */
- { 69, 18, 12, 0, 0, 28825, 318, }, /* 990 */
- { 69, 21, 12, 0, 0, 28825, 106, }, /* 991 */
- { 69, 6, 3, 0, 0, 18525, 320, }, /* 992 */
- { 69, 1, 2, 0, 0, 28672, 322, }, /* 993 */
- { 31, 7, 12, 0, 0, 18432, 82, }, /* 994 */
- { 69, 21, 12, 0, 0, 18552, 68, }, /* 995 */
- { 69, 21, 12, 0, 0, 28792, 68, }, /* 996 */
- { 69, 21, 12, 0, 0, 18483, 68, }, /* 997 */
- { 69, 15, 12, 0, 0, 18555, 68, }, /* 998 */
- { 69, 26, 12, 0, 0, 18483, 68, }, /* 999 */
- { 1, 14, 12, 0, 0, 28672, 82, }, /* 1000 */
- { 1, 15, 12, 0, 0, 28672, 68, }, /* 1001 */
- { 1, 26, 12, 0, 0, 28672, 68, }, /* 1002 */
- { 1, 26, 12, 0, 0, 18432, 68, }, /* 1003 */
- { 102, 7, 12, 0, 0, 18432, 82, }, /* 1004 */
- { 103, 7, 12, 0, 0, 18432, 82, }, /* 1005 */
- { 84, 12, 3, 0, 0, 26651, 96, }, /* 1006 */
- { 69, 15, 12, 0, 0, 10267, 68, }, /* 1007 */
- { 81, 7, 12, 0, 0, 18432, 82, }, /* 1008 */
- { 81, 15, 12, 0, 0, 18432, 68, }, /* 1009 */
- { 82, 7, 12, 0, 0, 18432, 82, }, /* 1010 */
- { 82, 14, 12, 0, 0, 18432, 82, }, /* 1011 */
- { 53, 7, 12, 0, 0, 18432, 82, }, /* 1012 */
- { 53, 12, 3, 0, 0, 26624, 130, }, /* 1013 */
- { 85, 7, 12, 0, 0, 18432, 82, }, /* 1014 */
- { 85, 21, 12, 0, 0, 18432, 106, }, /* 1015 */
- { 91, 7, 12, 0, 0, 18432, 82, }, /* 1016 */
- { 91, 21, 12, 0, 0, 18432, 106, }, /* 1017 */
- { 91, 14, 12, 0, 0, 18432, 82, }, /* 1018 */
- { 83, 9, 12, 0, 40, 18432, 74, }, /* 1019 */
- { 83, 5, 12, 0, -40, 18432, 76, }, /* 1020 */
- { 86, 7, 12, 0, 0, 18432, 82, }, /* 1021 */
- { 87, 7, 12, 0, 0, 18432, 82, }, /* 1022 */
- { 87, 13, 12, 0, 0, 18432, 138, }, /* 1023 */
- { 145, 9, 12, 0, 40, 18432, 74, }, /* 1024 */
- { 145, 5, 12, 0, -40, 18432, 76, }, /* 1025 */
- { 127, 7, 12, 0, 0, 18432, 82, }, /* 1026 */
- { 125, 7, 12, 0, 0, 18432, 82, }, /* 1027 */
- { 125, 21, 12, 0, 0, 18432, 68, }, /* 1028 */
- { 161, 9, 12, 0, 39, 18432, 74, }, /* 1029 */
- { 161, 5, 12, 0, -39, 18432, 76, }, /* 1030 */
- { 49, 7, 12, 0, 0, 18432, 82, }, /* 1031 */
- { 0, 6, 12, 0, 0, 18432, 94, }, /* 1032 */
- { 32, 7, 12, 0, 0, 34816, 82, }, /* 1033 */
- { 114, 7, 12, 0, 0, 34816, 82, }, /* 1034 */
- { 114, 21, 12, 0, 0, 34816, 106, }, /* 1035 */
- { 114, 15, 12, 0, 0, 34816, 68, }, /* 1036 */
- { 133, 7, 12, 0, 0, 34816, 82, }, /* 1037 */
- { 133, 26, 12, 0, 0, 34816, 68, }, /* 1038 */
- { 133, 15, 12, 0, 0, 34816, 68, }, /* 1039 */
- { 132, 7, 12, 0, 0, 34816, 82, }, /* 1040 */
- { 132, 15, 12, 0, 0, 34816, 68, }, /* 1041 */
- { 139, 7, 12, 0, 0, 34816, 82, }, /* 1042 */
- { 139, 15, 12, 0, 0, 34816, 68, }, /* 1043 */
- { 95, 7, 12, 0, 0, 34816, 82, }, /* 1044 */
- { 95, 15, 12, 0, 0, 34816, 68, }, /* 1045 */
- { 95, 21, 12, 0, 0, 28672, 106, }, /* 1046 */
- { 104, 7, 12, 0, 0, 34816, 82, }, /* 1047 */
- { 104, 21, 12, 0, 0, 34816, 68, }, /* 1048 */
- { 122, 7, 12, 0, 0, 34816, 82, }, /* 1049 */
- { 121, 7, 12, 0, 0, 34816, 82, }, /* 1050 */
- { 121, 15, 12, 0, 0, 34816, 68, }, /* 1051 */
- { 92, 7, 12, 0, 0, 34816, 82, }, /* 1052 */
- { 92, 12, 3, 0, 0, 26624, 130, }, /* 1053 */
- { 92, 12, 3, 0, 0, 26624, 102, }, /* 1054 */
- { 92, 12, 3, 0, 0, 26624, 182, }, /* 1055 */
- { 92, 15, 12, 0, 0, 34816, 68, }, /* 1056 */
- { 92, 21, 12, 0, 0, 34816, 68, }, /* 1057 */
- { 92, 21, 12, 0, 0, 34816, 124, }, /* 1058 */
- { 115, 7, 12, 0, 0, 34816, 82, }, /* 1059 */
- { 115, 15, 12, 0, 0, 34816, 68, }, /* 1060 */
- { 115, 21, 12, 0, 0, 34816, 68, }, /* 1061 */
- { 131, 7, 12, 0, 0, 34816, 82, }, /* 1062 */
- { 131, 15, 12, 0, 0, 34816, 68, }, /* 1063 */
- { 51, 7, 12, 0, 0, 34816, 82, }, /* 1064 */
- { 51, 26, 12, 0, 0, 34816, 68, }, /* 1065 */
- { 51, 12, 3, 0, 0, 26624, 96, }, /* 1066 */
- { 51, 15, 12, 0, 0, 34816, 68, }, /* 1067 */
- { 51, 21, 12, 0, 0, 34816, 106, }, /* 1068 */
- { 51, 21, 12, 0, 0, 34918, 106, }, /* 1069 */
- { 51, 21, 12, 0, 0, 34816, 68, }, /* 1070 */
- { 108, 7, 12, 0, 0, 34816, 82, }, /* 1071 */
- { 108, 21, 12, 0, 0, 28672, 68, }, /* 1072 */
- { 108, 21, 12, 0, 0, 28672, 106, }, /* 1073 */
- { 116, 7, 12, 0, 0, 34816, 82, }, /* 1074 */
- { 116, 15, 12, 0, 0, 34816, 68, }, /* 1075 */
- { 117, 7, 12, 0, 0, 34816, 82, }, /* 1076 */
- { 117, 15, 12, 0, 0, 34816, 68, }, /* 1077 */
- { 54, 7, 12, 0, 0, 34816, 82, }, /* 1078 */
- { 54, 21, 12, 0, 0, 34816, 106, }, /* 1079 */
- { 54, 15, 12, 0, 0, 34816, 68, }, /* 1080 */
- { 118, 7, 12, 0, 0, 34816, 82, }, /* 1081 */
- { 140, 9, 12, 0, 64, 34816, 74, }, /* 1082 */
- { 140, 5, 12, 0, -64, 34816, 76, }, /* 1083 */
- { 140, 15, 12, 0, 0, 34816, 68, }, /* 1084 */
- { 62, 7, 12, 0, 0, 0, 82, }, /* 1085 */
- { 62, 7, 12, 0, 0, 0, 294, }, /* 1086 */
- { 62, 12, 3, 0, 0, 26624, 128, }, /* 1087 */
- { 62, 13, 12, 0, 0, 2048, 138, }, /* 1088 */
- { 3, 15, 12, 0, 0, 2048, 68, }, /* 1089 */
- { 65, 7, 12, 0, 0, 34816, 82, }, /* 1090 */
- { 65, 12, 3, 0, 0, 26624, 130, }, /* 1091 */
- { 65, 17, 12, 0, 0, 34816, 126, }, /* 1092 */
- { 152, 7, 12, 0, 0, 34816, 82, }, /* 1093 */
- { 152, 15, 12, 0, 0, 34816, 68, }, /* 1094 */
- { 63, 7, 12, 0, 0, 0, 82, }, /* 1095 */
- { 63, 12, 3, 0, 0, 26624, 96, }, /* 1096 */
- { 63, 15, 12, 0, 0, 0, 68, }, /* 1097 */
- { 63, 21, 12, 0, 0, 0, 124, }, /* 1098 */
- { 67, 7, 12, 0, 0, 34816, 82, }, /* 1099 */
- { 67, 12, 3, 0, 0, 26624, 96, }, /* 1100 */
- { 67, 21, 12, 0, 0, 34816, 124, }, /* 1101 */
- { 156, 7, 12, 0, 0, 34816, 82, }, /* 1102 */
- { 156, 15, 12, 0, 0, 34816, 68, }, /* 1103 */
- { 153, 7, 12, 0, 0, 34816, 82, }, /* 1104 */
- { 120, 10, 5, 0, 0, 18432, 144, }, /* 1105 */
- { 120, 12, 3, 0, 0, 26624, 130, }, /* 1106 */
- { 120, 7, 12, 0, 0, 18432, 82, }, /* 1107 */
- { 120, 12, 3, 0, 0, 26624, 146, }, /* 1108 */
- { 120, 21, 12, 0, 0, 18432, 124, }, /* 1109 */
- { 120, 21, 12, 0, 0, 18432, 106, }, /* 1110 */
- { 120, 15, 12, 0, 0, 28672, 68, }, /* 1111 */
- { 120, 13, 12, 0, 0, 18432, 138, }, /* 1112 */
- { 120, 12, 3, 0, 0, 26624, 182, }, /* 1113 */
- { 41, 12, 3, 0, 0, 26624, 102, }, /* 1114 */
- { 41, 10, 5, 0, 0, 18432, 144, }, /* 1115 */
- { 41, 7, 12, 0, 0, 18432, 82, }, /* 1116 */
- { 41, 12, 3, 0, 0, 26624, 130, }, /* 1117 */
- { 41, 12, 3, 0, 0, 26624, 146, }, /* 1118 */
- { 41, 12, 3, 0, 0, 26624, 96, }, /* 1119 */
- { 41, 21, 12, 0, 0, 18432, 68, }, /* 1120 */
- { 41, 1, 4, 0, 0, 18432, 132, }, /* 1121 */
- { 41, 21, 12, 0, 0, 18432, 124, }, /* 1122 */
- { 124, 7, 12, 0, 0, 18432, 82, }, /* 1123 */
- { 124, 13, 12, 0, 0, 18432, 138, }, /* 1124 */
- { 43, 12, 3, 0, 0, 26624, 130, }, /* 1125 */
- { 43, 7, 12, 0, 0, 18432, 82, }, /* 1126 */
- { 43, 10, 5, 0, 0, 18432, 144, }, /* 1127 */
- { 43, 12, 3, 0, 0, 26624, 146, }, /* 1128 */
- { 43, 13, 12, 0, 0, 18432, 138, }, /* 1129 */
- { 43, 21, 12, 0, 0, 18432, 68, }, /* 1130 */
- { 43, 21, 12, 0, 0, 18432, 124, }, /* 1131 */
- { 50, 7, 12, 0, 0, 18432, 82, }, /* 1132 */
- { 50, 12, 3, 0, 0, 26624, 96, }, /* 1133 */
- { 50, 21, 12, 0, 0, 18432, 68, }, /* 1134 */
- { 44, 12, 3, 0, 0, 26624, 130, }, /* 1135 */
- { 44, 10, 5, 0, 0, 18432, 144, }, /* 1136 */
- { 44, 7, 12, 0, 0, 18432, 82, }, /* 1137 */
- { 44, 10, 5, 0, 0, 18432, 172, }, /* 1138 */
- { 44, 7, 4, 0, 0, 18432, 82, }, /* 1139 */
- { 44, 21, 12, 0, 0, 18432, 124, }, /* 1140 */
- { 44, 21, 12, 0, 0, 18432, 68, }, /* 1141 */
- { 44, 12, 3, 0, 0, 26624, 102, }, /* 1142 */
- { 44, 12, 3, 0, 0, 26624, 96, }, /* 1143 */
- { 44, 13, 12, 0, 0, 18432, 138, }, /* 1144 */
- { 15, 15, 12, 0, 0, 18432, 68, }, /* 1145 */
- { 48, 7, 12, 0, 0, 18432, 82, }, /* 1146 */
- { 48, 10, 5, 0, 0, 18432, 144, }, /* 1147 */
- { 48, 12, 3, 0, 0, 26624, 130, }, /* 1148 */
- { 48, 10, 5, 0, 0, 18432, 172, }, /* 1149 */
- { 48, 12, 3, 0, 0, 26624, 96, }, /* 1150 */
- { 48, 21, 12, 0, 0, 18432, 124, }, /* 1151 */
- { 48, 21, 12, 0, 0, 18432, 106, }, /* 1152 */
- { 48, 21, 12, 0, 0, 18432, 68, }, /* 1153 */
- { 57, 7, 12, 0, 0, 18432, 82, }, /* 1154 */
- { 57, 21, 12, 0, 0, 18432, 124, }, /* 1155 */
- { 55, 7, 12, 0, 0, 18432, 82, }, /* 1156 */
- { 55, 12, 3, 0, 0, 26624, 130, }, /* 1157 */
- { 55, 10, 5, 0, 0, 18432, 144, }, /* 1158 */
- { 55, 12, 3, 0, 0, 26624, 96, }, /* 1159 */
- { 55, 12, 3, 0, 0, 26624, 146, }, /* 1160 */
- { 55, 13, 12, 0, 0, 18432, 138, }, /* 1161 */
- { 47, 12, 3, 0, 0, 26624, 130, }, /* 1162 */
- { 47, 12, 3, 0, 0, 26705, 130, }, /* 1163 */
- { 47, 10, 5, 0, 0, 18432, 144, }, /* 1164 */
- { 47, 10, 5, 0, 0, 18513, 144, }, /* 1165 */
- { 47, 7, 12, 0, 0, 18432, 82, }, /* 1166 */
- { 84, 12, 3, 0, 0, 26705, 102, }, /* 1167 */
- { 47, 12, 3, 0, 0, 26705, 96, }, /* 1168 */
- { 47, 10, 3, 0, 0, 18432, 148, }, /* 1169 */
- { 47, 10, 5, 0, 0, 18432, 172, }, /* 1170 */
- { 47, 7, 12, 0, 0, 18432, 324, }, /* 1171 */
- { 47, 12, 3, 0, 0, 26624, 96, }, /* 1172 */
- { 144, 7, 12, 0, 0, 18432, 82, }, /* 1173 */
- { 144, 10, 5, 0, 0, 18432, 144, }, /* 1174 */
- { 144, 12, 3, 0, 0, 26624, 130, }, /* 1175 */
- { 144, 12, 3, 0, 0, 26624, 146, }, /* 1176 */
- { 144, 12, 3, 0, 0, 26624, 96, }, /* 1177 */
- { 144, 21, 12, 0, 0, 18432, 124, }, /* 1178 */
- { 144, 21, 12, 0, 0, 18432, 106, }, /* 1179 */
- { 144, 21, 12, 0, 0, 18432, 68, }, /* 1180 */
- { 144, 13, 12, 0, 0, 18432, 138, }, /* 1181 */
- { 144, 12, 3, 0, 0, 26624, 102, }, /* 1182 */
- { 56, 7, 12, 0, 0, 18432, 82, }, /* 1183 */
- { 56, 10, 3, 0, 0, 18432, 148, }, /* 1184 */
- { 56, 10, 5, 0, 0, 18432, 144, }, /* 1185 */
- { 56, 12, 3, 0, 0, 26624, 130, }, /* 1186 */
- { 56, 12, 3, 0, 0, 26624, 146, }, /* 1187 */
- { 56, 12, 3, 0, 0, 26624, 96, }, /* 1188 */
- { 56, 21, 12, 0, 0, 18432, 68, }, /* 1189 */
- { 56, 13, 12, 0, 0, 18432, 138, }, /* 1190 */
- { 135, 7, 12, 0, 0, 18432, 82, }, /* 1191 */
- { 135, 10, 3, 0, 0, 18432, 148, }, /* 1192 */
- { 135, 10, 5, 0, 0, 18432, 144, }, /* 1193 */
- { 135, 12, 3, 0, 0, 26624, 130, }, /* 1194 */
- { 135, 12, 3, 0, 0, 26624, 146, }, /* 1195 */
- { 135, 12, 3, 0, 0, 26624, 96, }, /* 1196 */
- { 135, 21, 12, 0, 0, 18432, 68, }, /* 1197 */
- { 135, 21, 12, 0, 0, 18432, 124, }, /* 1198 */
- { 135, 21, 12, 0, 0, 18432, 106, }, /* 1199 */
- { 135, 21, 12, 0, 0, 18432, 176, }, /* 1200 */
- { 52, 7, 12, 0, 0, 18432, 82, }, /* 1201 */
- { 52, 10, 5, 0, 0, 18432, 144, }, /* 1202 */
- { 52, 12, 3, 0, 0, 26624, 130, }, /* 1203 */
- { 52, 12, 3, 0, 0, 26624, 146, }, /* 1204 */
- { 52, 21, 12, 0, 0, 18432, 124, }, /* 1205 */
- { 52, 21, 12, 0, 0, 18432, 68, }, /* 1206 */
- { 52, 13, 12, 0, 0, 18432, 138, }, /* 1207 */
- { 45, 7, 12, 0, 0, 18432, 82, }, /* 1208 */
- { 45, 12, 3, 0, 0, 26624, 130, }, /* 1209 */
- { 45, 10, 5, 0, 0, 18432, 144, }, /* 1210 */
- { 45, 10, 5, 0, 0, 18432, 172, }, /* 1211 */
- { 45, 12, 3, 0, 0, 26624, 96, }, /* 1212 */
- { 45, 21, 12, 0, 0, 18432, 68, }, /* 1213 */
- { 45, 13, 12, 0, 0, 18432, 138, }, /* 1214 */
- { 137, 7, 12, 0, 0, 18432, 82, }, /* 1215 */
- { 137, 12, 3, 0, 0, 26624, 130, }, /* 1216 */
- { 137, 10, 12, 0, 0, 18432, 144, }, /* 1217 */
- { 137, 10, 5, 0, 0, 18432, 144, }, /* 1218 */
- { 137, 12, 3, 0, 0, 26624, 146, }, /* 1219 */
- { 137, 13, 12, 0, 0, 18432, 138, }, /* 1220 */
- { 137, 15, 12, 0, 0, 18432, 68, }, /* 1221 */
- { 137, 21, 12, 0, 0, 18432, 124, }, /* 1222 */
- { 137, 26, 12, 0, 0, 18432, 68, }, /* 1223 */
- { 60, 7, 12, 0, 0, 18432, 82, }, /* 1224 */
- { 60, 10, 5, 0, 0, 18432, 144, }, /* 1225 */
- { 60, 12, 3, 0, 0, 26624, 130, }, /* 1226 */
- { 60, 12, 3, 0, 0, 26624, 146, }, /* 1227 */
- { 60, 12, 3, 0, 0, 26624, 96, }, /* 1228 */
- { 60, 21, 12, 0, 0, 18432, 68, }, /* 1229 */
- { 136, 9, 12, 0, 32, 18432, 74, }, /* 1230 */
- { 136, 5, 12, 0, -32, 18432, 76, }, /* 1231 */
- { 136, 13, 12, 0, 0, 18432, 138, }, /* 1232 */
- { 136, 15, 12, 0, 0, 18432, 68, }, /* 1233 */
- { 136, 7, 12, 0, 0, 18432, 82, }, /* 1234 */
- { 157, 7, 12, 0, 0, 18432, 82, }, /* 1235 */
- { 157, 10, 3, 0, 0, 18432, 148, }, /* 1236 */
- { 157, 10, 5, 0, 0, 18432, 144, }, /* 1237 */
- { 157, 12, 3, 0, 0, 26624, 130, }, /* 1238 */
- { 157, 10, 5, 0, 0, 18432, 172, }, /* 1239 */
- { 157, 12, 3, 0, 0, 26624, 146, }, /* 1240 */
- { 157, 7, 4, 0, 0, 18432, 82, }, /* 1241 */
- { 157, 12, 3, 0, 0, 26624, 96, }, /* 1242 */
- { 157, 21, 12, 0, 0, 18432, 124, }, /* 1243 */
- { 157, 21, 12, 0, 0, 18432, 68, }, /* 1244 */
- { 157, 13, 12, 0, 0, 18432, 138, }, /* 1245 */
- { 64, 7, 12, 0, 0, 18432, 82, }, /* 1246 */
- { 64, 10, 5, 0, 0, 18432, 144, }, /* 1247 */
- { 64, 12, 3, 0, 0, 26624, 130, }, /* 1248 */
- { 64, 12, 3, 0, 0, 26624, 146, }, /* 1249 */
- { 64, 21, 12, 0, 0, 18432, 68, }, /* 1250 */
- { 149, 7, 12, 0, 0, 18432, 82, }, /* 1251 */
- { 149, 12, 3, 0, 0, 26624, 130, }, /* 1252 */
- { 149, 12, 3, 0, 0, 18432, 130, }, /* 1253 */
- { 149, 12, 3, 0, 0, 26624, 102, }, /* 1254 */
- { 149, 12, 3, 0, 0, 26624, 146, }, /* 1255 */
- { 149, 10, 5, 0, 0, 18432, 144, }, /* 1256 */
- { 149, 7, 4, 0, 0, 18432, 82, }, /* 1257 */
- { 149, 21, 12, 0, 0, 18432, 68, }, /* 1258 */
- { 149, 21, 12, 0, 0, 18432, 124, }, /* 1259 */
- { 148, 7, 12, 0, 0, 18432, 82, }, /* 1260 */
- { 148, 12, 3, 0, 0, 26624, 130, }, /* 1261 */
- { 148, 10, 5, 0, 0, 18432, 144, }, /* 1262 */
- { 148, 7, 4, 0, 0, 18432, 82, }, /* 1263 */
- { 148, 12, 3, 0, 0, 26624, 326, }, /* 1264 */
- { 148, 12, 3, 0, 0, 26624, 146, }, /* 1265 */
- { 148, 21, 12, 0, 0, 18432, 68, }, /* 1266 */
- { 148, 21, 12, 0, 0, 18432, 124, }, /* 1267 */
- { 148, 21, 12, 0, 0, 18432, 106, }, /* 1268 */
- { 134, 7, 12, 0, 0, 18432, 82, }, /* 1269 */
- { 142, 7, 12, 0, 0, 18432, 82, }, /* 1270 */
- { 142, 10, 5, 0, 0, 18432, 144, }, /* 1271 */
- { 142, 12, 3, 0, 0, 26624, 130, }, /* 1272 */
- { 142, 12, 3, 0, 0, 18432, 146, }, /* 1273 */
- { 142, 21, 12, 0, 0, 18432, 124, }, /* 1274 */
- { 142, 21, 12, 0, 0, 18432, 106, }, /* 1275 */
- { 142, 21, 12, 0, 0, 18432, 68, }, /* 1276 */
- { 142, 13, 12, 0, 0, 18432, 138, }, /* 1277 */
- { 142, 15, 12, 0, 0, 18432, 68, }, /* 1278 */
- { 143, 21, 12, 0, 0, 18432, 68, }, /* 1279 */
- { 143, 21, 12, 0, 0, 18432, 106, }, /* 1280 */
- { 143, 7, 12, 0, 0, 18432, 82, }, /* 1281 */
- { 143, 12, 3, 0, 0, 26624, 130, }, /* 1282 */
- { 143, 10, 5, 0, 0, 18432, 144, }, /* 1283 */
- { 59, 7, 12, 0, 0, 18432, 82, }, /* 1284 */
- { 59, 12, 3, 0, 0, 26624, 130, }, /* 1285 */
- { 59, 12, 3, 0, 0, 26624, 96, }, /* 1286 */
- { 59, 12, 3, 0, 0, 26624, 146, }, /* 1287 */
- { 59, 7, 4, 0, 0, 18432, 82, }, /* 1288 */
- { 59, 13, 12, 0, 0, 18432, 138, }, /* 1289 */
- { 61, 7, 12, 0, 0, 18432, 82, }, /* 1290 */
- { 61, 10, 5, 0, 0, 18432, 144, }, /* 1291 */
- { 61, 12, 3, 0, 0, 26624, 130, }, /* 1292 */
- { 61, 12, 3, 0, 0, 26624, 146, }, /* 1293 */
- { 61, 13, 12, 0, 0, 18432, 138, }, /* 1294 */
- { 150, 7, 12, 0, 0, 18432, 82, }, /* 1295 */
- { 150, 12, 3, 0, 0, 26624, 130, }, /* 1296 */
- { 150, 10, 5, 0, 0, 18432, 144, }, /* 1297 */
- { 150, 21, 12, 0, 0, 18432, 124, }, /* 1298 */
- { 11, 15, 12, 0, 0, 18432, 68, }, /* 1299 */
- { 11, 21, 12, 0, 0, 18432, 68, }, /* 1300 */
- { 94, 7, 12, 0, 0, 18432, 82, }, /* 1301 */
- { 94, 14, 12, 0, 0, 18432, 82, }, /* 1302 */
- { 94, 21, 12, 0, 0, 18432, 106, }, /* 1303 */
- { 66, 7, 12, 0, 0, 18432, 82, }, /* 1304 */
- { 66, 21, 12, 0, 0, 18432, 68, }, /* 1305 */
- { 109, 7, 12, 0, 0, 18432, 82, }, /* 1306 */
- { 109, 1, 2, 0, 0, 18432, 322, }, /* 1307 */
- { 138, 7, 12, 0, 0, 18432, 82, }, /* 1308 */
- { 130, 7, 12, 0, 0, 18432, 82, }, /* 1309 */
- { 130, 13, 12, 0, 0, 18432, 138, }, /* 1310 */
- { 130, 21, 12, 0, 0, 18432, 124, }, /* 1311 */
- { 159, 7, 12, 0, 0, 18432, 82, }, /* 1312 */
- { 159, 13, 12, 0, 0, 18432, 138, }, /* 1313 */
- { 126, 7, 12, 0, 0, 18432, 82, }, /* 1314 */
- { 126, 12, 3, 0, 0, 26624, 96, }, /* 1315 */
- { 126, 21, 12, 0, 0, 18432, 124, }, /* 1316 */
- { 128, 7, 12, 0, 0, 18432, 82, }, /* 1317 */
- { 128, 12, 3, 0, 0, 26624, 96, }, /* 1318 */
- { 128, 21, 12, 0, 0, 18432, 124, }, /* 1319 */
- { 128, 21, 12, 0, 0, 18432, 106, }, /* 1320 */
- { 128, 21, 12, 0, 0, 18432, 68, }, /* 1321 */
- { 128, 26, 12, 0, 0, 18432, 68, }, /* 1322 */
- { 128, 6, 12, 0, 0, 18432, 142, }, /* 1323 */
- { 128, 6, 12, 0, 0, 18432, 136, }, /* 1324 */
- { 128, 13, 12, 0, 0, 18432, 138, }, /* 1325 */
- { 128, 15, 12, 0, 0, 18432, 68, }, /* 1326 */
- { 151, 9, 12, 0, 32, 18432, 74, }, /* 1327 */
- { 151, 5, 12, 0, -32, 18432, 76, }, /* 1328 */
- { 151, 15, 12, 0, 0, 18432, 68, }, /* 1329 */
- { 151, 21, 12, 0, 0, 18432, 106, }, /* 1330 */
- { 151, 21, 12, 0, 0, 18432, 124, }, /* 1331 */
- { 151, 21, 12, 0, 0, 18432, 68, }, /* 1332 */
- { 123, 7, 12, 0, 0, 18432, 82, }, /* 1333 */
- { 123, 12, 3, 0, 0, 26624, 130, }, /* 1334 */
- { 123, 10, 5, 0, 0, 18432, 144, }, /* 1335 */
- { 123, 12, 3, 0, 0, 26624, 128, }, /* 1336 */
- { 123, 6, 12, 0, 0, 18432, 92, }, /* 1337 */
- { 146, 6, 12, 0, 0, 18432, 136, }, /* 1338 */
- { 147, 6, 12, 0, 0, 18432, 136, }, /* 1339 */
- { 23, 21, 12, 0, 0, 28672, 68, }, /* 1340 */
- { 158, 12, 3, 0, 0, 26624, 328, }, /* 1341 */
- { 23, 10, 5, 0, 0, 18432, 164, }, /* 1342 */
- { 146, 7, 12, 0, 0, 18432, 284, }, /* 1343 */
- { 158, 7, 12, 0, 0, 18432, 284, }, /* 1344 */
- { 21, 6, 12, 0, 0, 18432, 92, }, /* 1345 */
- { 147, 7, 12, 0, 0, 18432, 284, }, /* 1346 */
- { 46, 7, 12, 0, 0, 18432, 82, }, /* 1347 */
- { 46, 26, 12, 0, 0, 18432, 68, }, /* 1348 */
- { 46, 12, 3, 0, 0, 26624, 102, }, /* 1349 */
- { 46, 12, 3, 0, 0, 26624, 130, }, /* 1350 */
- { 46, 21, 12, 0, 0, 18432, 124, }, /* 1351 */
- { 69, 1, 2, 0, 0, 6153, 66, }, /* 1352 */
- { 69, 10, 3, 0, 0, 18432, 330, }, /* 1353 */
- { 69, 10, 5, 0, 0, 18432, 138, }, /* 1354 */
- { 69, 10, 5, 0, 0, 18432, 160, }, /* 1355 */
- { 69, 10, 3, 0, 0, 18432, 286, }, /* 1356 */
- { 1, 12, 3, 0, 0, 26624, 102, }, /* 1357 */
- { 69, 25, 12, 0, 0, 18432, 118, }, /* 1358 */
- { 69, 13, 12, 0, 0, 10240, 214, }, /* 1359 */
- { 141, 26, 12, 0, 0, 18432, 68, }, /* 1360 */
- { 141, 12, 3, 0, 0, 26624, 102, }, /* 1361 */
- { 141, 21, 12, 0, 0, 18432, 106, }, /* 1362 */
- { 141, 21, 12, 0, 0, 18432, 124, }, /* 1363 */
- { 141, 21, 12, 0, 0, 18432, 68, }, /* 1364 */
- { 35, 12, 3, 0, 0, 26624, 130, }, /* 1365 */
- { 154, 7, 12, 0, 0, 18432, 82, }, /* 1366 */
- { 154, 12, 3, 0, 0, 26624, 96, }, /* 1367 */
- { 154, 6, 12, 0, 0, 18432, 142, }, /* 1368 */
- { 154, 6, 12, 0, 0, 18432, 136, }, /* 1369 */
- { 154, 13, 12, 0, 0, 18432, 138, }, /* 1370 */
- { 154, 26, 12, 0, 0, 18432, 68, }, /* 1371 */
- { 160, 7, 12, 0, 0, 18432, 82, }, /* 1372 */
- { 160, 12, 3, 0, 0, 26624, 96, }, /* 1373 */
- { 155, 7, 12, 0, 0, 18432, 82, }, /* 1374 */
- { 155, 12, 3, 0, 0, 26624, 96, }, /* 1375 */
- { 155, 13, 12, 0, 0, 18432, 138, }, /* 1376 */
- { 155, 23, 12, 0, 0, 14336, 68, }, /* 1377 */
- { 129, 7, 12, 0, 0, 34816, 82, }, /* 1378 */
- { 129, 15, 12, 0, 0, 34816, 68, }, /* 1379 */
- { 129, 12, 3, 0, 0, 26624, 96, }, /* 1380 */
- { 58, 9, 12, 0, 34, 34816, 74, }, /* 1381 */
- { 58, 5, 12, 0, -34, 34816, 76, }, /* 1382 */
- { 58, 12, 3, 0, 0, 26624, 150, }, /* 1383 */
- { 58, 12, 3, 0, 0, 26624, 130, }, /* 1384 */
- { 58, 12, 3, 0, 0, 26624, 96, }, /* 1385 */
- { 58, 6, 12, 0, 0, 34816, 142, }, /* 1386 */
- { 58, 13, 12, 0, 0, 34816, 138, }, /* 1387 */
- { 58, 21, 12, 0, 0, 34816, 68, }, /* 1388 */
- { 69, 15, 12, 0, 0, 0, 68, }, /* 1389 */
- { 69, 26, 12, 0, 0, 0, 68, }, /* 1390 */
- { 69, 23, 12, 0, 0, 0, 68, }, /* 1391 */
- { 3, 7, 12, 0, 0, 0, 240, }, /* 1392 */
- { 69, 26, 14, 0, 0, 28672, 332, }, /* 1393 */
- { 69, 26, 14, 0, 0, 28672, 334, }, /* 1394 */
- { 68, 2, 14, 0, 0, 18432, 336, }, /* 1395 */
- { 69, 26, 12, 0, 0, 18432, 338, }, /* 1396 */
- { 69, 26, 14, 0, 0, 18432, 340, }, /* 1397 */
- { 69, 26, 14, 0, 0, 18432, 334, }, /* 1398 */
- { 69, 26, 11, 0, 0, 18432, 342, }, /* 1399 */
- { 20, 26, 12, 0, 0, 18432, 68, }, /* 1400 */
- { 69, 26, 14, 0, 0, 18432, 236, }, /* 1401 */
- { 69, 26, 14, 0, 0, 18447, 334, }, /* 1402 */
- { 69, 26, 14, 0, 0, 28672, 344, }, /* 1403 */
- { 69, 26, 14, 0, 0, 28672, 346, }, /* 1404 */
- { 69, 24, 3, 0, 0, 28672, 348, }, /* 1405 */
- { 69, 26, 14, 0, 0, 28672, 350, }, /* 1406 */
- { 69, 13, 12, 0, 0, 10240, 138, }, /* 1407 */
- { 69, 1, 3, 0, 0, 6144, 352, }, /* 1408 */
-};
-
-const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* U+0000 */
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* U+0800 */
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 41, 41, 42, 43, 44, 45, /* U+1000 */
- 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, /* U+1800 */
- 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, /* U+2000 */
- 78, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, /* U+2800 */
- 93, 94, 95, 96, 97, 98, 99,100,101,101,101,101,101,101,101,101, /* U+3000 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+3800 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+4000 */
-101,101,101,101,101,101,101,101,101,101,101,102,101,101,101,101, /* U+4800 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+5000 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+5800 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+6000 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+6800 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+7000 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+7800 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+8000 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+8800 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+9000 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+9800 */
-103,104,104,104,104,104,104,104,104,105,106,106,107,108,109,110, /* U+A000 */
-111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,119, /* U+A800 */
-120,121,122,123,124,125,119,120,121,122,123,124,125,119,120,121, /* U+B000 */
-122,123,124,125,119,120,121,122,123,124,125,119,120,121,122,123, /* U+B800 */
-124,125,119,120,121,122,123,124,125,119,120,121,122,123,124,125, /* U+C000 */
-119,120,121,122,123,124,125,119,120,121,122,123,124,125,119,120, /* U+C800 */
-121,122,123,124,125,119,120,121,122,123,124,125,119,120,121,126, /* U+D000 */
-127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, /* U+D800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+E000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+E800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F000 */
-128,128,129,129,130,131,132,133,134,135,136,137,138,139,140,141, /* U+F800 */
-142,143,144,145,146,147,148,149,150,151,152,153,154,154,155,156, /* U+10000 */
-157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172, /* U+10800 */
-173,174,175,176,177,178,179,146,180,181,146,182,183,184,185,146, /* U+11000 */
-186,187,188,189,190,191,146,146,192,193,194,195,146,196,146,197, /* U+11800 */
-198,198,198,198,198,198,198,199,200,198,201,146,146,146,146,146, /* U+12000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,202, /* U+12800 */
-203,203,203,203,203,203,203,203,204,146,146,146,146,146,146,146, /* U+13000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+13800 */
-146,146,146,146,146,146,146,146,205,205,205,205,206,146,146,146, /* U+14000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+14800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+15000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+15800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+16000 */
-207,207,207,207,208,209,210,211,146,146,146,146,212,213,214,215, /* U+16800 */
-216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, /* U+17000 */
-216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, /* U+17800 */
-216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,217, /* U+18000 */
-216,216,216,216,216,216,218,218,218,219,220,146,146,146,146,146, /* U+18800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+19000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+19800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+1A000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,221, /* U+1A800 */
-222,223,224,225,225,226,146,146,146,146,146,146,146,146,146,146, /* U+1B000 */
-146,146,146,146,146,146,146,146,227,228,146,146,146,146,146,146, /* U+1B800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+1C000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,229,230, /* U+1C800 */
-231,232,233,234,235,236,237,146,238,239,240,241,242,243,244,245, /* U+1D000 */
-246,246,246,246,247,248,146,146,146,146,146,146,146,146,249,146, /* U+1D800 */
-250,146,251,146,146,252,146,146,146,146,146,146,146,146,146,253, /* U+1E000 */
-254,255,256,168,168,168,168,168,257,258,259,168,260,261,168,168, /* U+1E800 */
-262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277, /* U+1F000 */
-278,279,280,281,282,283,284,285,267,267,267,267,267,267,267,286, /* U+1F800 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+20000 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+20800 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+21000 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+21800 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+22000 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+22800 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+23000 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+23800 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+24000 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+24800 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+25000 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+25800 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+26000 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+26800 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+27000 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+27800 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+28000 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+28800 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+29000 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+29800 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,287,101,101, /* U+2A000 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2A800 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,288,101, /* U+2B000 */
-289,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2B800 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2C000 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,290,101,101, /* U+2C800 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2D000 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2D800 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2E000 */
-101,101,101,101,101,101,101,291,146,146,146,146,146,146,146,146, /* U+2E800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+2F000 */
-129,129,129,129,292,146,146,146,146,146,146,146,146,146,146,293, /* U+2F800 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+30000 */
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+30800 */
-101,101,101,101,101,101,294,146,146,146,146,146,146,146,146,146, /* U+31000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+31800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+32000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+32800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+33000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+33800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+34000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+34800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+35000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+35800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+36000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+36800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+37000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+37800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+38000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+38800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+39000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+39800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3A000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3A800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3B000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3B800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3C000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3C800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3D000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3D800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3E000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3E800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3F000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+3F800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+40000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+40800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+41000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+41800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+42000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+42800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+43000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+43800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+44000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+44800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+45000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+45800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+46000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+46800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+47000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+47800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+48000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+48800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+49000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+49800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4A000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4A800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4B000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4B800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4C000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4C800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4D000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4D800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4E000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4E800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4F000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+4F800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+50000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+50800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+51000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+51800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+52000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+52800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+53000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+53800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+54000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+54800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+55000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+55800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+56000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+56800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+57000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+57800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+58000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+58800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+59000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+59800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5A000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5A800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5B000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5B800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5C000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5C800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5D000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5D800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5E000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5E800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5F000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+5F800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+60000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+60800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+61000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+61800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+62000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+62800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+63000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+63800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+64000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+64800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+65000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+65800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+66000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+66800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+67000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+67800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+68000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+68800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+69000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+69800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6A000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6A800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6B000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6B800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6C000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6C800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6D000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6D800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6E000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6E800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6F000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+6F800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+70000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+70800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+71000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+71800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+72000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+72800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+73000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+73800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+74000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+74800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+75000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+75800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+76000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+76800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+77000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+77800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+78000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+78800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+79000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+79800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7A000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7A800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7B000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7B800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7C000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7C800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7D000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7D800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7E000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7E800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7F000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+7F800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+80000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+80800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+81000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+81800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+82000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+82800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+83000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+83800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+84000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+84800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+85000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+85800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+86000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+86800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+87000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+87800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+88000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+88800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+89000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+89800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8A000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8A800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8B000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8B800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8C000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8C800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8D000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8D800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8E000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8E800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8F000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+8F800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+90000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+90800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+91000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+91800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+92000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+92800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+93000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+93800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+94000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+94800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+95000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+95800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+96000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+96800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+97000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+97800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+98000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+98800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+99000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+99800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9A000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9A800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9B000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9B800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9C000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9C800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9D000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9D800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9E000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9E800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9F000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+9F800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A0000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A0800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A1000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A1800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A2000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A2800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A3000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A3800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A4000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A4800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A5000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A5800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A6000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A6800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A7000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A7800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A8000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A8800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A9000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A9800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AA000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AA800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AB000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AB800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AC000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AC800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AD000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AD800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AE000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AE800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AF000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+AF800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B0000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B0800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B1000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B1800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B2000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B2800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B3000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B3800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B4000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B4800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B5000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B5800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B6000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B6800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B7000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B7800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B8000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B8800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B9000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B9800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BA000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BA800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BB000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BB800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BC000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BC800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BD000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BD800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BE000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BE800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BF000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+BF800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C0000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C0800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C1000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C1800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C2000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C2800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C3000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C3800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C4000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C4800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C5000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C5800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C6000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C6800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C7000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C7800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C8000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C8800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C9000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C9800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CA000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CA800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CB000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CB800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CC000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CC800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CD000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CD800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CE000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CE800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CF000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+CF800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D0000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D0800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D1000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D1800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D2000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D2800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D3000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D3800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D4000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D4800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D5000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D5800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D6000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D6800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D7000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D7800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D8000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D8800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D9000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D9800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DA000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DA800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DB000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DB800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DC000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DC800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DD000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DD800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DE000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DE800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DF000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+DF800 */
-295,296,297,298,296,296,296,296,296,296,296,296,296,296,296,296, /* U+E0000 */
-296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296, /* U+E0800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E1000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E1800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E2000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E2800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E3000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E3800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E4000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E4800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E5000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E5800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E6000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E6800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E7000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E7800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E8000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E8800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E9000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E9800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EA000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EA800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EB000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EB800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EC000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EC800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+ED000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+ED800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EE000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EE800 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EF000 */
-146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+EF800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F0000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F0800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F1000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F1800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F2000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F2800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F3000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F3800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F4000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F4800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F5000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F5800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F6000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F6800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F7000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F7800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F8000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F8800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F9000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F9800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FA000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FA800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FB000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FB800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FC000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FC800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FD000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FD800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FE000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FE800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FF000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,299, /* U+FF800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+100000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+100800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+101000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+101800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+102000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+102800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+103000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+103800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+104000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+104800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+105000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+105800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+106000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+106800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+107000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+107800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+108000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+108800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+109000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+109800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10A000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10A800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10B000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10B800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10C000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10C800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10D000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10D800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10E000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10E800 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10F000 */
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,299, /* U+10F800 */
-};
-
-const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */
-
-/* block 0 */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 3, 4, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 6,
- 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 25, 26, 27, 26, 8,
- 13, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 30, 29, 29, 29, 29,
- 29, 29, 29, 31, 29, 29, 29, 29, 29, 29, 29, 15, 13, 16, 32, 33,
- 34, 35, 35, 35, 35, 35, 35, 36, 36, 37, 37, 38, 36, 36, 36, 36,
- 36, 36, 36, 39, 36, 36, 36, 36, 36, 36, 36, 15, 27, 16, 27, 0,
-
-/* block 1 */
- 40, 40, 40, 40, 40, 41, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- 42, 43, 44, 44, 44, 44, 45, 43, 46, 47, 48, 49, 50, 51, 47, 46,
- 52, 53, 54, 54, 46, 55, 43, 56, 46, 54, 48, 57, 58, 58, 58, 43,
- 59, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
- 59, 59, 59, 59, 59, 59, 59, 50, 59, 59, 59, 59, 59, 59, 59, 61,
- 62, 62, 62, 62, 62, 63, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
- 62, 62, 62, 62, 62, 62, 62, 50, 62, 62, 62, 62, 62, 62, 62, 64,
-
-/* block 2 */
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 67,
- 68, 69, 65, 66, 65, 66, 65, 66, 70, 65, 66, 65, 66, 65, 66, 65,
- 66, 65, 66, 65, 66, 65, 66, 65, 66, 71, 65, 66, 65, 66, 65, 66,
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 65, 66, 65, 66, 65, 66, 65, 66, 72, 65, 66, 65, 66, 65, 66, 73,
-
-/* block 3 */
- 74, 75, 65, 66, 65, 66, 76, 65, 66, 77, 77, 65, 66, 70, 78, 79,
- 80, 65, 66, 77, 81, 82, 83, 84, 65, 66, 85, 70, 83, 86, 87, 88,
- 65, 66, 65, 66, 65, 66, 89, 65, 66, 89, 70, 70, 65, 66, 89, 65,
- 66, 90, 90, 65, 66, 65, 66, 91, 65, 66, 70, 92, 65, 66, 70, 93,
- 92, 92, 92, 92, 94, 95, 96, 97, 98, 99,100,101,102, 65, 66, 65,
- 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,103, 65, 66,
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 69,104,105,106, 65, 66,107,108, 65, 66, 65, 66, 65, 66, 65, 66,
-
-/* block 4 */
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
-109, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 65, 66, 65, 66, 70, 70, 70, 70, 70, 70,110, 65, 66,111,112,113,
-113, 65, 66,114,115,116, 65, 66, 65, 67, 65, 66, 65, 66, 65, 66,
-117,118,119,120,121, 70,122,122, 70,123, 70,124,125, 70, 70, 70,
-122,126, 70,127, 70,128,129, 70,130,131,129,132,133, 70, 70,131,
- 70,134,135, 70, 70,136, 70, 70, 70, 70, 70, 70, 70,137, 70, 70,
-
-/* block 5 */
-138, 70,139,138, 70, 70, 70,140,138,141,142,142,143, 70, 70, 70,
- 70, 70,144, 70, 92, 70, 70, 70, 70, 70, 70, 70, 70,145,146, 70,
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-147,147,148,147,147,147,147,147,147,149,149,150,150,150,150,150,
-151,151, 46, 46, 46, 46,149,149,149,149,149,149,149,149,149,149,
-152,152, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
-147,147,147,147,147, 46, 46, 46, 46, 46,153,153,149, 46,150, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
-
-/* block 6 */
-154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
-154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
-154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
-154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
-154,154,155,154,154,156,154,154,154,154,154,154,154,154,154,157,
-154,154,154,154,154,154,154,154,158,158,158,158,158,154,154,154,
-154,154,154,159,159,159,159,159,159,159,159,159,159,159,159,159,
-160,161,160,161,149,162,160,161,163,163,164,165,165,165,166,167,
-
-/* block 7 */
-163,163,163,163,162, 46,168,169,170,170,170,163,171,163,172,172,
-173,174,175,174,174,176,174,174,177,178,179,174,180,174,174,174,
-181,182,163,183,174,174,184,174,174,185,174,174,186,187,187,187,
-173,188,189,188,188,190,188,188,191,192,193,188,194,188,188,188,
-195,196,197,198,188,188,199,188,188,200,188,188,201,202,202,203,
-204,205,206,207,207,208,209,210,160,161,160,161,160,161,160,161,
-160,161,211,212,211,212,211,212,211,212,211,212,211,212,211,212,
-213,214,215,216,217,218,219,160,161,220,160,161,221,222,222,222,
-
-/* block 8 */
-223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
-224,224,225,224,226,224,224,224,224,224,224,224,224,224,227,224,
-224,228,229,224,224,224,224,224,224,224,230,224,224,224,224,224,
-231,231,232,231,233,231,231,231,231,231,231,231,231,231,234,231,
-231,235,236,231,231,231,231,231,231,231,237,231,231,231,231,231,
-238,238,238,238,238,238,239,238,239,238,238,238,238,238,238,238,
-240,241,242,243,240,241,240,241,240,241,240,241,240,241,240,241,
-240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241,
-
-/* block 9 */
-240,241,244,245,246,247,247,246,248,248,240,241,240,241,240,241,
-240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241,
-240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241,
-240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241,
-249,240,241,240,241,240,241,240,241,240,241,240,241,240,241,250,
-240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241,
-240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241,
-240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241,
-
-/* block 10 */
-240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241,
-240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241,
-240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241,
-163,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
-251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
-251,251,251,251,251,251,251,163,163,252,253,253,253,253,253,254,
-255,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,
-256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,
-
-/* block 11 */
-256,256,256,256,256,256,256,257,255,258,259,163,163,260,260,261,
-262,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,
-263,263,264,263,263,263,263,263,263,263,263,263,263,263,263,263,
-265,265,265,265,265,265,265,265,265,265,265,265,265,265,266,265,
-267,265,265,268,265,269,267,269,262,262,262,262,262,262,262,262,
-270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,
-270,270,270,270,270,270,270,270,270,270,270,262,262,262,262,270,
-270,270,270,267,271,262,262,262,262,262,262,262,262,262,262,262,
-
-/* block 12 */
-272,272,272,272,272,273,274,274,275,276,276,277,278,279,280,280,
-281,281,281,281,281,281,281,281,281,281,281,282,283,284,284,285,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-287,286,286,286,286,286,286,286,286,286,286,288,288,288,288,288,
-288,288,288,289,289,289,281,290,291,281,281,281,281,281,281,281,
-292,292,292,292,292,292,292,292,292,292,276,293,293,279,286,286,
-289,286,286,294,286,286,286,286,286,286,286,286,286,286,286,286,
-
-/* block 13 */
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,295,286,281,281,281,281,281,281,281,273,280,291,
-291,281,281,281,281,296,296,281,281,280,291,291,291,281,286,286,
-297,297,297,297,297,297,297,297,297,297,286,286,286,298,298,286,
-
-/* block 14 */
-299,299,299,300,300,300,300,300,300,300,300,301,300,301,302,303,
-304,305,304,304,304,304,304,304,304,304,304,304,304,304,304,304,
-304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,
-306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,
-307,307,307,307,307,307,307,307,307,307,307,302,302,304,304,304,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-
-/* block 15 */
-308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,
-308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,
-308,308,308,308,308,308,309,309,309,309,309,309,309,309,309,309,
-309,308,302,302,302,302,302,302,302,302,302,302,302,302,302,302,
-310,310,310,310,310,310,310,310,310,310,311,311,311,311,311,311,
-311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,
-311,311,311,311,311,311,311,311,311,311,311,312,312,312,312,312,
-312,312,312,312,313,313,314,315,316,317,318,262,262,319,320,320,
-
-/* block 16 */
-321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,
-321,321,321,321,321,321,322,322,323,323,324,322,322,322,322,322,
-322,322,322,322,324,322,322,322,324,322,322,322,322,325,262,262,
-326,326,326,326,326,326,326,327,326,327,326,326,326,327,327,262,
-328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,
-328,328,328,328,328,328,328,328,328,329,329,329,262,262,330,262,
-304,304,304,304,304,304,304,304,304,304,304,302,302,302,302,302,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-
-/* block 17 */
-286,286,286,286,286,286,286,286,331,286,286,286,286,286,286,302,
-272,272,302,302,302,302,302,302,291,291,291,291,291,291,291,291,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,296,291,291,291,291,291,291,
-291,291,291,332,281,281,281,281,281,281,281,281,281,281,281,281,
-332,332,273,290,290,290,290,290,290,290,291,291,291,291,291,291,
-290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,281,
-
-/* block 18 */
-333,333,333,334,335,335,335,335,335,335,335,335,335,335,335,335,
-335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,
-335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,
-335,335,335,335,335,335,335,335,335,335,333,334,336,335,334,334,
-334,333,333,333,333,333,333,333,333,334,334,334,334,337,334,334,
-335,338,339,154,154,333,333,333,335,335,335,335,335,335,335,335,
-335,335,333,333,340,341,342,342,342,342,342,342,342,342,342,342,
-343,344,335,335,335,335,335,335,335,335,335,335,335,335,335,335,
-
-/* block 19 */
-345,346,347,347,163,345,345,345,345,345,345,345,345,163,163,345,
-345,163,163,345,345,345,345,345,345,345,345,345,345,345,345,345,
-345,345,345,345,345,345,345,345,345,163,345,345,345,345,345,345,
-345,163,345,163,163,163,345,345,345,345,163,163,348,345,349,347,
-347,346,346,346,346,163,163,347,347,163,163,347,347,350,345,163,
-163,163,163,163,163,163,163,349,163,163,163,163,345,345,163,345,
-345,345,346,346,163,163,351,351,351,351,351,351,351,351,351,351,
-345,345,352,352,353,353,353,353,353,353,354,352,345,355,356,163,
-
-/* block 20 */
-163,357,357,358,163,359,359,359,359,359,359,163,163,163,163,359,
-359,163,163,359,359,359,359,359,359,359,359,359,359,359,359,359,
-359,359,359,359,359,359,359,359,359,163,359,359,359,359,359,359,
-359,163,359,359,163,359,359,163,359,359,163,163,360,163,358,358,
-358,357,357,163,163,163,163,357,357,163,163,357,357,361,163,163,
-163,357,163,163,163,163,163,163,163,359,359,359,359,163,359,163,
-163,163,163,163,163,163,362,362,362,362,362,362,362,362,362,362,
-357,357,359,359,359,357,363,163,163,163,163,163,163,163,163,163,
-
-/* block 21 */
-163,364,364,365,163,366,366,366,366,366,366,366,366,366,163,366,
-366,366,163,366,366,366,366,366,366,366,366,366,366,366,366,366,
-366,366,366,366,366,366,366,366,366,163,366,366,366,366,366,366,
-366,163,366,366,163,366,366,366,366,366,163,163,367,366,365,365,
-365,364,364,364,364,364,163,364,364,365,163,365,365,368,163,163,
-366,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-366,366,364,364,163,163,369,369,369,369,369,369,369,369,369,369,
-370,371,163,163,163,163,163,163,163,366,364,364,364,367,367,367,
-
-/* block 22 */
-163,372,373,373,163,374,374,374,374,374,374,374,374,163,163,374,
-374,163,163,374,374,374,374,374,374,374,374,374,374,374,374,374,
-374,374,374,374,374,374,374,374,374,163,374,374,374,374,374,374,
-374,163,374,374,163,374,374,374,374,374,163,163,375,374,376,372,
-373,372,372,372,372,163,163,373,373,163,163,373,373,377,163,163,
-163,163,163,163,163,378,372,376,163,163,163,163,374,374,163,374,
-374,374,372,372,163,163,379,379,379,379,379,379,379,379,379,379,
-380,374,381,381,381,381,381,381,163,163,163,163,163,163,163,163,
-
-/* block 23 */
-163,163,382,383,163,383,383,383,383,383,383,163,163,163,383,383,
-383,163,383,383,383,383,163,163,163,383,383,163,383,163,383,383,
-163,163,163,383,383,163,163,163,383,383,383,163,163,163,383,383,
-383,383,383,383,383,383,383,383,383,383,163,163,163,163,384,385,
-382,385,385,163,163,163,385,385,385,163,385,385,385,386,163,163,
-383,163,163,163,163,163,163,384,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,387,387,387,387,387,387,387,387,387,387,
-388,388,388,389,390,390,390,390,390,391,390,163,163,163,163,163,
-
-/* block 24 */
-392,393,393,393,394,395,395,395,395,395,395,395,395,163,395,395,
-395,163,395,395,395,395,395,395,395,395,395,395,395,395,395,395,
-395,395,395,395,395,395,395,395,395,163,395,395,395,395,395,395,
-395,395,395,395,395,395,395,395,395,395,163,163,396,395,392,392,
-392,393,393,393,393,163,392,392,392,163,392,392,392,397,163,163,
-163,163,163,163,163,392,392,163,395,395,395,163,163,395,163,163,
-395,395,392,392,163,163,398,398,398,398,398,398,398,398,398,398,
-163,163,163,163,163,163,163,399,400,400,400,400,400,400,400,401,
-
-/* block 25 */
-402,403,404,404,405,402,402,402,402,402,402,402,402,163,402,402,
-402,163,402,402,402,402,402,402,402,402,402,402,402,402,402,402,
-402,402,402,402,402,402,402,402,402,163,402,402,402,402,402,402,
-402,402,402,402,163,402,402,402,402,402,163,163,406,402,404,407,
-404,404,408,404,404,163,407,404,404,163,404,404,403,409,163,163,
-163,163,163,163,163,408,408,163,163,163,163,163,163,402,402,163,
-402,402,403,403,163,163,410,410,410,410,410,410,410,410,410,410,
-163,402,402,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 26 */
-411,411,412,412,413,413,413,413,413,413,413,413,413,163,413,413,
-413,163,413,413,413,413,413,413,413,413,413,413,413,413,413,413,
-413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,
-413,413,413,413,413,413,413,413,413,413,413,414,414,413,415,412,
-412,411,411,411,411,163,412,412,412,163,412,412,412,414,416,417,
-163,163,163,163,413,413,413,415,418,418,418,418,418,418,418,413,
-413,413,411,411,163,163,419,419,419,419,419,419,419,419,419,419,
-418,418,418,418,418,418,418,418,418,417,413,413,413,413,413,413,
-
-/* block 27 */
-163,420,421,421,163,422,422,422,422,422,422,422,422,422,422,422,
-422,422,422,422,422,422,422,163,163,163,422,422,422,422,422,422,
-422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
-422,422,163,422,422,422,422,422,422,422,422,422,163,422,163,163,
-422,422,422,422,422,422,422,163,163,163,423,163,163,163,163,424,
-421,421,420,420,420,163,420,163,421,421,421,421,421,421,421,424,
-163,163,163,163,163,163,425,425,425,425,425,425,425,425,425,425,
-163,163,421,421,426,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 28 */
-163,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427,
-427,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427,
-427,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427,
-427,428,427,429,428,428,428,428,428,428,430,163,163,163,163,431,
-432,432,432,432,432,427,433,434,434,434,434,434,434,428,434,435,
-436,436,436,436,436,436,436,436,436,436,437,437,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 29 */
-163,438,438,163,438,163,438,438,438,438,438,163,438,438,438,438,
-438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
-438,438,438,438,163,438,163,438,438,438,438,438,438,438,438,438,
-438,439,438,440,439,439,439,439,439,439,441,439,439,438,163,163,
-442,442,442,442,442,163,443,163,444,444,444,444,444,439,163,163,
-445,445,445,445,445,445,445,445,445,445,163,163,438,438,438,438,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 30 */
-446,447,447,447,448,448,448,448,449,448,448,448,448,449,449,449,
-449,449,449,447,448,447,447,447,450,450,447,447,447,447,447,447,
-451,451,451,451,451,451,451,451,451,451,452,452,452,452,452,452,
-452,452,452,452,447,450,447,450,447,450,453,454,453,454,455,455,
-446,446,446,446,446,446,446,446,163,446,446,446,446,446,446,446,
-446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,
-446,446,446,446,446,446,446,446,446,446,446,446,446,163,163,163,
-163,456,456,456,456,456,456,457,456,457,456,456,456,456,456,458,
-
-/* block 31 */
-456,456,450,450,459,448,450,450,446,446,446,446,446,456,456,456,
-456,456,456,456,456,456,456,456,163,456,456,456,456,456,456,456,
-456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,
-456,456,456,456,456,456,456,456,456,456,456,456,456,163,447,447,
-447,447,447,447,447,447,450,447,447,447,447,447,447,163,447,447,
-448,448,448,448,448,460,460,460,460,448,448,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 32 */
-461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,
-461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,
-461,461,461,461,461,461,461,461,461,461,461,462,462,463,463,463,
-463,464,463,463,463,463,463,465,462,466,466,464,464,463,463,461,
-467,467,467,467,467,467,467,467,467,467,468,468,469,469,469,469,
-461,461,461,461,461,461,464,464,463,463,461,461,461,461,463,463,
-463,461,462,470,470,461,461,462,462,470,470,470,470,470,461,461,
-461,463,463,463,463,461,461,461,461,461,461,461,461,461,461,461,
-
-/* block 33 */
-461,461,463,462,464,463,463,470,470,470,470,470,470,471,461,470,
-472,472,472,472,472,472,472,472,472,472,470,470,462,463,473,473,
-474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,
-474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,
-474,474,474,474,474,474,163,474,163,163,163,163,163,474,163,163,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,476,477,475,475,475,
-
-/* block 34 */
-478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,
-478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,
-478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,
-478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,
-478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,
-478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,479,
-480,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
-481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
-
-/* block 35 */
-481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
-481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
-481,481,481,481,481,481,481,481,482,482,482,482,482,482,482,482,
-482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
-482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
-482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
-482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
-482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
-
-/* block 36 */
-483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
-483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
-483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
-483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
-483,483,483,483,483,483,483,483,483,163,483,483,483,483,163,163,
-483,483,483,483,483,483,483,163,483,163,483,483,483,483,163,163,
-483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
-483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
-
-/* block 37 */
-483,483,483,483,483,483,483,483,483,163,483,483,483,483,163,163,
-483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
-483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
-483,163,483,483,483,483,163,163,483,483,483,483,483,483,483,163,
-483,163,483,483,483,483,163,163,483,483,483,483,483,483,483,483,
-483,483,483,483,483,483,483,163,483,483,483,483,483,483,483,483,
-483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
-483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
-
-/* block 38 */
-483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
-483,163,483,483,483,483,163,163,483,483,483,483,483,483,483,483,
-483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
-483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
-483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
-483,483,483,483,483,483,483,483,483,483,483,163,163,484,484,484,
-485,486,487,486,486,486,486,487,487,488,488,488,488,488,488,488,
-488,488,489,489,489,489,489,489,489,489,489,489,489,163,163,163,
-
-/* block 39 */
-483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
-490,490,490,490,490,490,490,490,490,490,163,163,163,163,163,163,
-491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,
-491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,
-491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,
-491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,
-491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,
-492,492,492,492,492,492,163,163,493,493,493,493,493,493,163,163,
-
-/* block 40 */
-494,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-
-/* block 41 */
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-
-/* block 42 */
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,496,497,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-
-/* block 43 */
-498,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,
-499,499,499,499,499,499,499,499,499,499,499,500,501,163,163,163,
-502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,
-502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,
-502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,
-502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,
-502,502,502,502,502,502,502,502,502,502,502,503,503,503,504,504,
-504,502,502,502,502,502,502,502,502,163,163,163,163,163,163,163,
-
-/* block 44 */
-505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
-505,505,506,506,507,508,163,163,163,163,163,163,163,163,163,505,
-509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,
-509,509,510,510,511,512,512,163,163,163,163,163,163,163,163,163,
-513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
-513,513,514,514,163,163,163,163,163,163,163,163,163,163,163,163,
-515,515,515,515,515,515,515,515,515,515,515,515,515,163,515,515,
-515,163,516,516,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 45 */
-517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,
-517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,
-517,517,517,518,518,517,517,517,517,517,517,517,517,517,517,517,
-517,517,517,517,519,519,520,521,521,521,521,521,521,521,520,520,
-520,520,520,520,520,520,521,520,520,522,522,522,522,522,522,522,
-522,522,523,522,524,524,524,525,526,526,524,527,517,522,163,163,
-528,528,528,528,528,528,528,528,528,528,163,163,163,163,163,163,
-529,529,529,529,529,529,529,529,529,529,163,163,163,163,163,163,
-
-/* block 46 */
-530,530,531,532,533,531,534,530,533,535,536,537,537,537,538,537,
-539,539,539,539,539,539,539,539,539,539,163,163,163,163,163,163,
-540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,
-540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,
-540,540,540,541,540,540,540,540,540,540,540,540,540,540,540,540,
-540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,
-540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,
-540,540,540,540,540,540,540,540,540,163,163,163,163,163,163,163,
-
-/* block 47 */
-540,540,540,540,540,542,542,540,540,540,540,540,540,540,540,540,
-540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,
-540,540,540,540,540,540,540,540,540,543,540,163,163,163,163,163,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,495,495,495,163,163,163,163,163,163,163,163,163,163,
-
-/* block 48 */
-544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,
-544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,163,
-545,545,545,546,546,546,546,545,545,546,546,546,163,163,163,163,
-546,546,545,546,546,546,546,546,546,547,547,547,163,163,163,163,
-548,163,163,163,549,549,550,550,550,550,550,550,550,550,550,550,
-551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,
-551,551,551,551,551,551,551,551,551,551,551,551,551,551,163,163,
-551,551,551,551,551,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 49 */
-552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,
-552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,
-552,552,552,552,552,552,552,552,552,552,552,552,163,163,163,163,
-552,552,552,552,552,553,553,553,552,552,553,552,552,552,552,552,
-552,552,552,552,552,552,552,552,552,552,163,163,163,163,163,163,
-554,554,554,554,554,554,554,554,554,554,555,163,163,163,556,556,
-557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
-557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
-
-/* block 50 */
-558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,
-558,558,558,558,558,558,558,559,559,560,560,559,163,163,561,561,
-562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,
-562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,
-562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,
-562,562,562,562,562,563,564,563,564,564,564,564,564,564,564,163,
-565,566,564,566,566,564,564,564,564,564,564,564,564,563,563,563,
-563,563,563,564,564,567,567,567,567,567,567,567,567,163,163,567,
-
-/* block 51 */
-568,568,568,568,568,568,568,568,568,568,163,163,163,163,163,163,
-568,568,568,568,568,568,568,568,568,568,163,163,163,163,163,163,
-569,569,569,569,569,569,569,570,571,571,571,571,569,569,163,163,
-154,154,154,154,154,154,154,154,154,154,154,154,154,154,572,573,
-573,154,154,154,154,154,154,154,154,154,154,154,573,573,573,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 52 */
-574,574,574,574,575,576,576,576,576,576,576,576,576,576,576,576,
-576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,
-576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,
-576,576,576,576,577,578,574,574,574,574,574,575,574,575,575,575,
-575,575,574,575,579,576,576,576,576,576,576,576,576,163,163,163,
-580,580,580,580,580,580,580,580,580,580,581,581,582,583,581,581,
-582,584,584,584,584,584,584,584,584,584,584,577,577,577,577,577,
-577,577,577,577,584,584,584,584,584,584,584,584,584,581,581,163,
-
-/* block 53 */
-585,585,586,587,587,587,587,587,587,587,587,587,587,587,587,587,
-587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
-587,586,585,585,585,585,586,586,585,585,588,589,585,585,587,587,
-590,590,590,590,590,590,590,590,590,590,587,587,587,587,587,587,
-591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,
-591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,
-591,591,591,591,591,591,592,593,594,594,593,593,593,594,593,594,
-594,594,595,595,163,163,163,163,163,163,163,163,596,596,596,596,
-
-/* block 54 */
-597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,
-597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,
-597,597,597,597,598,598,598,598,598,598,598,598,599,599,599,599,
-599,599,599,599,598,598,600,601,163,163,163,602,602,603,603,603,
-604,604,604,604,604,604,604,604,604,604,163,163,163,597,597,597,
-605,605,605,605,605,605,605,605,605,605,606,606,606,606,606,606,
-606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,
-606,606,606,606,606,606,606,606,607,607,607,608,607,607,609,609,
-
-/* block 55 */
-610,611,612,613,614,615,616,617,618,163,163,163,163,163,163,163,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,163,163,619,619,619,
-620,620,620,620,620,620,620,620,163,163,163,163,163,163,163,163,
-621,622,621,623,622,624,624,625,624,625,626,622,625,625,622,622,
-625,627,622,622,622,622,622,622,622,628,629,630,630,624,630,630,
-630,630,631,632,633,629,629,634,635,635,636,163,163,163,163,163,
-
-/* block 56 */
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
- 70, 70, 70, 70, 70, 70,221,221,221,221,221,637,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,638,638,638,
-638,638,148,147,147,147,638,638,638,638,638, 70, 70, 70, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 70,639,640, 70, 70, 70,641, 70, 70,
-
-/* block 57 */
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,642, 70,
- 70, 70, 70, 70, 70, 70,643, 70, 70, 70, 70,644,644,644,644,644,
-644,644,644,644,645,644,644,644,645,644,644,644,644,644,644,644,
-644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,646,
-647,647,158,158,154,154,154,154,154,154,154,154,154,154,154,154,
-158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
-158,158,158,158,158,158,158,573,573,573,573,573,573,573,573,573,
-573,573,573,573,573,154,154,154,648,154,649,154,154,154,154,154,
-
-/* block 58 */
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 67, 65, 66,
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
-650,651, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
-
-/* block 59 */
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 65, 66, 65, 66, 65, 66, 69, 69, 69, 69,652,653, 70, 70,654, 70,
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 67, 65, 66, 65, 66,
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
-
-/* block 60 */
-655,655,655,655,655,655,655,655,656,656,656,656,656,656,656,656,
-655,655,655,655,655,655,163,163,656,656,656,656,656,656,163,163,
-655,655,655,655,655,655,655,655,656,656,656,656,656,656,656,656,
-655,655,655,655,655,655,655,655,656,656,656,656,656,656,656,656,
-655,655,655,655,655,655,163,163,656,656,656,656,656,656,163,163,
-173,655,173,655,173,655,173,655,163,656,163,656,163,656,163,656,
-655,655,655,655,655,655,655,655,656,656,656,656,656,656,656,656,
-657,657,658,658,658,658,659,659,660,660,661,661,662,662,163,163,
-
-/* block 61 */
-663,663,663,663,663,663,663,663,664,664,664,664,664,664,664,664,
-663,663,663,663,663,663,663,663,664,664,664,664,664,664,664,664,
-663,663,663,663,663,663,663,663,664,664,664,664,664,664,664,664,
-655,655,665,666,665,163,173,665,656,656,667,667,668,162,669,162,
-162,162,665,666,665,163,173,665,670,670,670,670,668,162,162,162,
-655,655,173,173,163,163,173,173,656,656,671,671,163,162,162,162,
-655,655,173,173,173,215,173,173,656,656,672,672,220,162,162,162,
-163,163,665,666,665,163,173,665,673,673,674,674,668,162,162,163,
-
-/* block 62 */
-675,675,675,675,675,675,675,675,675,675,675, 51,676,677,678,679,
-680,680,680,680,680,680,681, 43,682,683,684,685,685,686,684,685,
- 43, 43, 43, 43,687, 43, 43,687,688,689,690,691,692,693,694,695,
-696,696,697,697,697, 43, 43, 43, 43, 49, 57, 43,698,699, 43,700,
-701, 43, 43, 43,702,703,704,699,699,698, 43, 43, 43, 43, 43, 43,
- 43, 43, 50,705,700, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,675,
- 51,706,706,706,706,707,708,709,710,711,712,712,712,712,712,712,
- 54,645,163,163, 54, 54, 54, 54, 54, 54,713,714,715,716,717,644,
-
-/* block 63 */
- 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,713,714,715,716,717,163,
-644,644,644,644,644,644,644,644,644,644,644,644,644,163,163,163,
-431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,
-431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,
-431,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,
-719,719,719,719,719,719,719,719,719,719,719,719,719,720,720,720,
-720,719,720,721,720,719,719,158,158,158,158,719,719,719,719,719,
-722,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 64 */
-723,723,724,723,723,723,723,724,723,723,725,724,724,724,725,725,
-724,724,724,725,723,724,723,723,726,724,724,724,724,724,723,723,
-723,723,727,723,724,723,728,723,724,729,730,731,724,724,732,725,
-724,724,733,724,725,734,734,734,734,735,723,723,725,725,724,724,
-715,715,715,715,715,724,725,725,736,736,723,715,723,723,737,460,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
-738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,
-739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
-
-/* block 65 */
-740,740,740, 65, 66,740,740,740,740, 58,723,723,163,163,163,163,
- 50, 50, 50, 50,741,742,742,742,742,742, 50, 50,743,743,743,743,
- 50,743,743, 50,743,743, 50,743, 45,742,742,743,743,743, 50, 45,
-743,743, 45, 45, 45, 45,743,743, 45, 45, 45, 45,743,743,743,743,
-743,743,743,743,743,743,743,743,743,743,743,743,743,743, 50, 50,
-743,743, 50,743, 50,743,743,743,743,743,743,743, 45,743, 45, 45,
- 45, 45, 45, 45,743,743, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
-
-/* block 66 */
- 50, 50, 50, 50, 50, 50, 50, 50,744,744,744,744,744,744, 50, 50,
- 50, 50,745, 53, 50,744, 50, 50, 50, 50, 50, 50, 50, 50, 50,744,
-744,744,744, 50,744, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,744,744, 50, 50,
- 50, 50, 50,744, 50,744, 50, 50, 50, 50, 50, 50,744, 50, 50, 50,
- 50, 50,744,744,744,744, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50,744,744,744,744,744,744,744,744, 50, 50,744,744,
-744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,
-
-/* block 67 */
-744,744,744,744,744,744,744,744,744,744,744,744, 50, 50, 50,744,
-744,744,744, 50, 50, 50, 50, 50,744, 50, 50, 50, 50, 50, 50, 50,
- 50, 50,744,744, 50, 50,744, 50,744,744, 50,744, 50, 50, 50, 50,
-744,744,744,744,744,744,744,744,744, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50, 50,744,744,744,744,744, 50, 50,
-744,744, 50, 50, 50, 50,744,744,744,744,744,744,744,744,744,744,
-744,744,744,744,744,744,744,744,744,744,744,744,744,744, 50, 50,
-744,744,744,744,744, 50,744,744, 50, 50,744,744,744,744,744, 50,
-
-/* block 68 */
- 45, 45, 45, 45, 45, 45, 45, 45,746,747,746,747, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,748,748, 45, 45, 45, 45,
- 50, 50, 45, 45, 45, 45, 45, 45, 47,749,750, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45,751,751,751,751,751,751,751,751,751,751,
-751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,
-751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,
-751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,
-751,751,751,751,751,751,751,751,751,751,751, 45, 50, 45, 45, 45,
-
-/* block 69 */
- 45, 45, 45, 45, 45, 45, 45, 45,752, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45,751, 45, 45, 45, 45, 45, 50, 50, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50,743,743, 45,743, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 47,
-743, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50, 50,
- 50, 50,743, 45, 45, 45, 45, 45, 45,748,748,748,748, 47, 47, 47,
-748, 47, 47,748, 45, 45, 45, 45, 47, 47, 47, 45, 45, 45, 45, 45,
-
-/* block 70 */
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45,753,753,753,753,753,753,753,753,753,
-753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,753,753,753,753,753,
-753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
-
-/* block 71 */
- 58, 58, 58, 58, 58, 58, 58, 58, 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,754,754,754,754,754,754,754,754,754,754,
-754,754,755,754,754,754,754,754,754,754,754,754,754,754,754,754,
-756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,
-756,756,756,756,756,756,756,756,756,756, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
-
-/* block 72 */
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
-
-/* block 73 */
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
-743,743, 45, 45, 45, 45, 45, 45, 45, 45, 47, 47, 45, 45,743,743,
-743,743,743,743,743,743,742, 50, 45, 45, 45, 45,743,743,743,743,
-742, 50, 45, 45, 45, 45,743,743, 45, 45,743,743, 45, 45, 45,743,
-743,743,743,743, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45,743, 45,743, 45, 45,743,743,743,743,743,743, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50,741,741,757,757, 50,
-
-/* block 74 */
- 47, 47, 47, 47, 47,758,743,752,752,752,752,752,752,752, 47,752,
-752, 47,752, 45,748,748,752,752, 47,752,752,752,752,759,752,752,
- 47,752, 47, 47,752,752, 47,752,752,752, 47,752,752,752, 47, 47,
-752,752,752,752,752,752,752,752, 47, 47, 47,752,752,752,752,752,
-742,752,742,752,752,752,752,752,748,748,748,748,748,748,748,748,
-748,748,748,748,752,752,752,752,752,752,752,752,752,752,752, 47,
-742,758,758,742,752, 47, 47,752, 47,752,752,752,752,758,758,760,
-752,752,752,752,752,752,752,752,752,752,752, 47,752,752, 47,748,
-
-/* block 75 */
-752,752,752,752,752,752, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
-752,752, 47,748, 47, 47, 47, 47,752, 47,752, 47, 47,752,752,752,
- 47,748,752,752,752,752,752, 47,752,752,748,748,761,752,752,752,
- 47, 47,752,752,752,752,752,752,752,752,752,752,752,748,748,752,
-752,752,752,752,748,748,752,752, 47,752,752,752,752,752,748, 47,
-752, 47,752, 47,748,752,752,752,752,752,752,752,752,752,752,752,
-752,752,752,752,752,752,752,752,752, 47,748,752,752,752,752,752,
- 47, 47,748,748, 47,748,752, 47, 47,759,748,752,752,748,752,752,
-
-/* block 76 */
-752,752, 47,752,752,748, 45, 45, 47, 47,762,762,759,759,752, 47,
-752,752, 47, 45, 47, 45, 47, 45, 45, 45, 45, 45, 45, 47, 45, 45,
- 45, 47, 45, 45, 45, 45, 45, 45,748, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 47, 47, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 47, 45, 45, 47, 45, 45, 45, 45,748, 45,748, 45,
- 45, 45, 45,748,748,748, 45,748, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 47, 47,752,752,752,703,704,703,704,703,704,703,704,
-703,704,703,704,703,704, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
-
-/* block 77 */
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 45,748,748,748, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 47, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
-748, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,748,
- 50, 50, 50,744,744,746,747, 50,744,744, 50,744, 50,744, 50, 50,
- 50, 50, 50, 50, 50,744,744, 50, 50, 50, 50, 50,744,744,744, 50,
- 50, 50,744,744,744,744,746,747,746,747,746,747,746,747,746,747,
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
-
-/* block 78 */
-763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,
-763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,
-763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,
-763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,
-763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,
-763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,
-763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,
-763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,
-
-/* block 79 */
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50,741,741, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
-
-/* block 80 */
- 50, 50, 50,746,747,746,747,746,747,746,747,746,747,746,747,746,
-747,746,747,746,747,746,747,746,747, 50, 50,744, 50, 50, 50, 50,
-744, 50, 50,744,744,744, 50, 50,744,744,744,744,744,744,744,744,
- 50, 50, 50, 50, 50, 50, 50, 50,744, 50, 50, 50, 50, 50, 50, 50,
-744,744, 50, 50,744,744, 50, 50, 50, 50, 50, 50, 50, 50, 50,744,
-744,744,744, 50,744,744, 50, 50,746,747,746,747, 50, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50,744,744, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50, 50,744, 50, 50,744,744, 50, 50,746,747, 50, 50,
-
-/* block 81 */
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,744,744,744,744, 50,
- 50, 50, 50, 50,744,744, 50, 50, 50, 50, 50, 50,744,744, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50,744,744, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50, 50,744,744,744,744,744,744,744,
-
-/* block 82 */
-744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,
-744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,
-744,744,744, 50, 50, 50,744,744,744,744,744,744,744,744, 50,744,
-744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,
-744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,
-744,744,744,744,744,744,744, 50, 50, 50, 50, 50, 50, 50,744, 50,
- 50, 50, 50,744,744,744, 50, 50, 50, 50, 50, 50,744,744,744, 50,
- 50, 50, 50, 50, 50, 50, 50,744,744,744,744, 50, 50, 50, 50, 50,
-
-/* block 83 */
- 45, 45, 45, 45, 45, 47, 47, 47, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,748,748, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50, 50, 45, 45, 50, 50, 50, 50, 50, 50, 45, 45, 45,
-748, 45, 45, 45, 45,748, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45,753,753, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
-
-/* block 84 */
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45,753, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,764, 45,
-
-/* block 85 */
-765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,
-765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,
-765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,
-766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,
-766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,
-766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,
- 65, 66,767,768,769,770,771, 65, 66, 65, 66, 65, 66,772,773,774,
-775, 70, 65, 66, 70, 65, 66, 70, 70, 70, 70, 70,645,644,776,776,
-
-/* block 86 */
-211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212,
-211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212,
-211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212,
-211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212,
-211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212,
-211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212,
-211,212,211,212,777,778,778,778,778,778,778,211,212,211,212,779,
-779,779,211,212,163,163,163,163,163,780,780,780,780,781,780,780,
-
-/* block 87 */
-782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,
-782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,
-782,782,782,782,782,782,163,782,163,163,163,163,163,782,163,163,
-783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,
-783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,
-783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,
-783,783,783,783,783,783,783,783,163,163,163,163,163,163,163,784,
-785,163,163,163,163,163,163,163,163,163,163,163,163,163,163,786,
-
-/* block 88 */
-483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
-483,483,483,483,483,483,483,163,163,163,163,163,163,163,163,163,
-483,483,483,483,483,483,483,163,483,483,483,483,483,483,483,163,
-483,483,483,483,483,483,483,163,483,483,483,483,483,483,483,163,
-483,483,483,483,483,483,483,163,483,483,483,483,483,483,483,163,
-483,483,483,483,483,483,483,163,483,483,483,483,483,483,483,163,
-787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,
-787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,
-
-/* block 89 */
- 43, 43,788,789,788,789, 43, 43, 43,788,789, 43,788,789, 43, 43,
- 43, 43, 43, 43, 43, 43, 43,680, 43, 43,680, 43,788,789, 43, 43,
-788,789,703,704,703,704,703,704,703,704, 43, 43, 43, 43,699,790,
- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,680,680,699, 43, 43, 43,
-680,791,684,792, 43, 43, 43, 43, 43, 43, 43, 43,791, 43,791,791,
- 45, 45, 43,699,699,703,704,703,704,703,704,703,704,680,753,753,
-753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,
-753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,
-
-/* block 90 */
-793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,
-793,793,793,793,793,793,793,793,793,793,163,793,793,793,793,793,
-793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,
-793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,
-793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,
-793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,
-793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,
-793,793,793,793,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 91 */
-793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,
-793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,
-793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,
-793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,
-793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,
-793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,
-793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,
-793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,
-
-/* block 92 */
-793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,
-793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,
-793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,
-793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,
-793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,
-793,793,793,793,793,793,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-794,794,795,795,794,794,794,794,794,794,794,794,163,163,163,163,
-
-/* block 93 */
-675,796,797,798,723,799,800,801,802,803,802,803,804,805,804,805,
-802,803, 45,806,802,803,802,803,802,803,802,803,807,808,809,809,
- 45,801,801,801,801,801,801,801,801,801,810,810,810,810,811,811,
-812,813,813,813,813,813,723,814,801,801,801,815,816,817,818,818,
-163,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-
-/* block 94 */
-819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-819,819,819,819,819,819,819,163,163,820,820,821,821,822,822,819,
-823,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,
-824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,
-824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,
-824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,
-824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,
-824,824,824,824,824,824,824,824,824,824,824,825,826,827,827,824,
-
-/* block 95 */
-163,163,163,163,163,828,828,828,828,828,828,828,828,828,828,828,
-828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,
-828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,
-163,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,
-829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,
-829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,
-829,829,829,829,830,829,829,829,829,829,829,829,829,829,829,829,
-829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,
-
-/* block 96 */
-829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,163,
-831,831,832,832,832,832,831,831,831,831,831,831,831,831,831,831,
-828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,
-828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,
-818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,
-818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,
-818,818,818,818,163,163,163,163,163,163,163,163,163,163,163,163,
-824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,
-
-/* block 97 */
-833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,
-833,833,833,833,833,833,833,833,833,833,833,833,833,834,834,163,
-832,832,832,832,832,832,832,832,832,832,831,831,831,831,831,831,
-831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,
-831,831,831,831,831,831,831,831,835,835,835,835,835,835,835,835,
-723, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
-833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,
-833,833,833,833,833,833,833,833,833,833,833,833,834,834,834,460,
-
-/* block 98 */
-832,832,832,832,832,832,832,832,832,832,831,831,831,831,831,831,
-831,831,831,831,831,831,831,836,831,836,831,831,831,831,831,831,
-831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,
-831, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
-831,831,831,831,831,831,831,831,831,831,831,831,723,723,723,723,
-837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,
-837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,
-837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,831,
-
-/* block 99 */
-837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,
-837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,
-837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,
-837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,
-837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,
-837,837,837,837,837,837,837,837,831,831,831,831,831,831,831,831,
-831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,
-831,460,460,460,460,460,460,723,723,723,723,831,831,831,831,831,
-
-/* block 100 */
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,723,723,
-831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,
-831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,723,
-
-/* block 101 */
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-
-/* block 102 */
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-
-/* block 103 */
-839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,
-839,839,839,839,839,840,839,839,839,839,839,839,839,839,839,839,
-839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,
-839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,
-839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,
-839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,
-839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,
-839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,
-
-/* block 104 */
-839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,
-839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,
-839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,
-839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,
-839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,
-839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,
-839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,
-839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,
-
-/* block 105 */
-839,839,839,839,839,839,839,839,839,839,839,839,839,163,163,163,
-841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,
-841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,
-841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,
-841,841,841,841,841,841,841,163,163,163,163,163,163,163,163,163,
-842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,
-842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,
-842,842,842,842,842,842,842,842,843,843,843,843,843,843,844,845,
-
-/* block 106 */
-846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,
-846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,
-846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,
-846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,
-846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,
-846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,
-846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,
-846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,
-
-/* block 107 */
-846,846,846,846,846,846,846,846,846,846,846,846,847,848,849,849,
-846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,
-850,850,850,850,850,850,850,850,850,850,846,846,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-240,241,240,241,240,241,240,241,240,241,851,852,240,241,240,241,
-240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241,
-240,241,240,241,240,241,240,241,240,241,240,241,240,241,853,246,
-248,248,248,854,787,787,787,787,787,787,787,787,855,855,854,856,
-
-/* block 108 */
-240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241,
-240,241,240,241,240,241,240,241,240,241,240,241,857,857,787,787,
-858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
-858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
-858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
-858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
-858,858,858,858,858,858,859,859,859,859,859,859,859,859,859,859,
-860,860,861,862,863,863,863,862,163,163,163,163,163,163,163,163,
-
-/* block 109 */
-864,864,864,864,864,864,864,864, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46,149,149,149,149,149,149,149,149,149,
- 46, 46, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 70, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
-644, 70, 70, 70, 70, 70, 70, 70, 70, 65, 66, 65, 66,865, 65, 66,
-
-/* block 110 */
- 65, 66, 65, 66, 65, 66, 65, 66,149,866,866, 65, 66,867, 70, 92,
- 65, 66, 65, 66,868, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,869,870,871,872,869, 70,
-873,874,875,876, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,
- 65, 66, 65, 66,877,878,879, 65, 66, 65, 66,163,163,163,163,163,
- 65, 66,163, 70,163, 70, 65, 66, 65, 66,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,880,880,880, 65, 66, 92,147,147, 70, 92, 92, 92, 92, 92,
-
-/* block 111 */
-881,881,882,881,881,881,883,881,881,881,881,882,881,881,881,881,
-881,881,881,881,881,881,881,881,881,881,881,881,881,881,881,881,
-881,881,881,884,884,882,882,884,885,885,885,885,883,163,163,163,
-886,886,886,887,887,887,888,888,889,890,163,163,163,163,163,163,
-891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,
-891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,
-891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,
-891,891,891,891,892,892,893,893,163,163,163,163,163,163,163,163,
-
-/* block 112 */
-894,894,895,895,895,895,895,895,895,895,895,895,895,895,895,895,
-895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,
-895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,
-895,895,895,895,894,894,894,894,894,894,894,894,894,894,894,894,
-894,894,894,894,896,897,163,163,163,163,163,163,163,163,898,898,
-899,899,899,899,899,899,899,899,899,899,163,163,163,163,163,163,
-336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,
-336,900,335,901,335,335,335,335,343,343,343,335,343,335,335,333,
-
-/* block 113 */
-902,902,902,902,902,902,902,902,902,902,903,903,903,903,903,903,
-903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,
-903,903,903,903,903,903,904,904,904,904,904,905,905,905,906,907,
-908,908,908,908,908,908,908,908,908,908,908,908,908,908,908,908,
-908,908,908,908,908,908,908,909,909,909,909,909,909,909,909,909,
-909,909,910,911,163,163,163,163,163,163,163,163,163,163,163,912,
-478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,
-478,478,478,478,478,478,478,478,478,478,478,478,478,163,163,163,
-
-/* block 114 */
-913,913,913,914,915,915,915,915,915,915,915,915,915,915,915,915,
-915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,
-915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,
-915,915,915,916,914,914,913,913,913,913,914,914,913,913,914,914,
-917,918,918,918,918,918,918,919,920,920,918,918,918,918,163,921,
-922,922,922,922,922,922,922,922,922,922,163,163,163,163,918,918,
-461,461,461,461,461,471,923,461,461,461,461,461,461,461,461,461,
-472,472,472,472,472,472,472,472,472,472,461,461,461,461,461,163,
-
-/* block 115 */
-924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,
-924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,
-924,924,924,924,924,924,924,924,924,925,925,925,925,925,925,926,
-926,925,925,926,926,925,925,163,163,163,163,163,163,163,163,163,
-924,924,924,925,924,924,924,924,924,924,924,924,925,926,163,163,
-927,927,927,927,927,927,927,927,927,927,163,163,928,929,929,929,
-461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,
-923,461,461,461,461,461,461,473,473,473,461,470,471,470,461,461,
-
-/* block 116 */
-930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,
-930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,
-930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,
-931,930,931,931,931,932,932,931,931,932,930,932,932,930,931,933,
-934,933,934,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,930,930,935,936,937,
-938,938,938,938,938,938,938,938,938,938,938,939,940,940,939,939,
-941,941,938,942,942,939,943,163,163,163,163,163,163,163,163,163,
-
-/* block 117 */
-163,483,483,483,483,483,483,163,163,483,483,483,483,483,483,163,
-163,483,483,483,483,483,483,163,163,163,163,163,163,163,163,163,
-483,483,483,483,483,483,483,163,483,483,483,483,483,483,483,163,
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
- 70, 70, 70,944, 70, 70, 70, 70, 70, 70, 70,866,147,147,147,147,
- 70, 70, 70, 70, 70,221, 70, 70, 70,945, 46, 46,163,163,163,163,
-946,946,946,946,946,946,946,946,946,946,946,946,946,946,946,946,
-
-/* block 118 */
-946,946,946,946,946,946,946,946,946,946,946,946,946,946,946,946,
-946,946,946,946,946,946,946,946,946,946,946,946,946,946,946,946,
-946,946,946,946,946,946,946,946,946,946,946,946,946,946,946,946,
-946,946,946,946,946,946,946,946,946,946,946,946,946,946,946,946,
-938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,
-938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,
-938,938,938,939,939,940,939,939,940,939,939,941,947,943,163,163,
-948,948,948,948,948,948,948,948,948,948,163,163,163,163,163,163,
-
-/* block 119 */
-949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-
-/* block 120 */
-950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950,
-
-/* block 121 */
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-
-/* block 122 */
-950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950,
-
-/* block 123 */
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-
-/* block 124 */
-950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950,
-
-/* block 125 */
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-
-/* block 126 */
-950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950,
-950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,
-950,950,950,950,163,163,163,163,163,163,163,163,163,163,163,163,
-481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
-481,481,481,481,481,481,481,163,163,163,163,482,482,482,482,482,
-482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
-482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
-482,482,482,482,482,482,482,482,482,482,482,482,163,163,163,163,
-
-/* block 127 */
-951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,
-951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,
-951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,
-951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,
-951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,
-951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,
-951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,
-951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,
-
-/* block 128 */
-952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,
-952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,
-952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,
-952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,
-952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,
-952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,
-952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,
-952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,
-
-/* block 129 */
-953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,
-953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,
-953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,
-953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,
-953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,
-953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,
-953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,
-953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,
-
-/* block 130 */
-953,953,953,953,953,953,953,953,953,953,953,953,953,953,838,838,
-953,838,953,838,838,953,953,953,953,953,953,953,953,953,953,838,
-953,838,953,838,838,953,953,838,838,838,953,953,953,953,953,953,
-953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,
-953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,
-953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,
-953,953,953,953,953,953,953,953,953,953,953,953,953,953,163,163,
-953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,
-
-/* block 131 */
-953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,
-953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,
-953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,
-953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,
-953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,
-953,953,953,953,953,953,953,953,953,953,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 132 */
-652,652,652,652,652,652,652,163,163,163,163,163,163,163,163,163,
-163,163,163,257,257,257,257,257,163,163,163,163,163,270,265,270,
-270,270,270,270,270,270,270,270,270,954,270,270,270,270,270,270,
-270,270,270,270,270,270,270,262,270,270,270,270,270,262,270,262,
-270,270,262,270,270,262,270,270,270,270,270,270,270,270,270,270,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-
-/* block 133 */
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,331,331,331,331,331,331,331,331,331,331,331,331,331,331,
-331,331,331,302,302,302,302,302,302,302,302,302,302,302,302,302,
-302,302,302,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-
-/* block 134 */
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,955,955,
-955,955,955,955,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-
-/* block 135 */
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-
-/* block 136 */
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,956,957,
-280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-
-/* block 137 */
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-302,302,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,302,302,302,302,302,302,302,280,
-958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,
-958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,
-286,286,959,286,286,286,286,286,286,286,955,955,277,960,280,280,
-
-/* block 138 */
-961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,962,
-963,963,963,964,963,963,963,965,966,963,163,163,163,163,163,163,
-154,154,154,154,154,154,154,154,154,154,154,154,154,154,855,855,
-963,967,967,700,700,965,966,965,966,965,966,965,966,965,966,965,
-966,968,969,968,969,798,798,965,966,963,963,963,963,700,700,700,
-970,166,971,163,166,972,973,973,967,974,975,974,975,974,975,976,
-963,977,713,978,979,979,715,163,977,431,976,963,163,163,163,163,
-955,286,955,286,955,302,955,286,955,286,955,286,955,286,955,286,
-
-/* block 139 */
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,302,302, 51,
-
-/* block 140 */
-163,973,980,976,431,976,963,981,974,975,963,713,970,982,971,983,
-984,984,984,984,984,984,984,984,984,984,972,166,979,715,979,973,
-963,985,985,985,985,985,985, 59, 59, 59, 59, 59, 59, 59, 59, 59,
- 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,974,977,975,986,700,
- 46,987,987,987,987,987,987, 62, 62, 62, 62, 62, 62, 62, 62, 62,
- 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,974,715,975,715,974,
-975,988,989,990,991,825,824,824,824,824,824,824,824,824,824,824,
-826,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,
-
-/* block 141 */
-824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,
-824,824,824,824,824,824,824,824,824,824,824,824,824,824,992,992,
-830,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,
-829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,163,
-163,163,829,829,829,829,829,829,163,163,829,829,829,829,829,829,
-163,163,829,829,829,829,829,829,163,163,829,829,829,163,163,163,
-431,431,715, 46,723,431,431,163,723,715,715,715,715,723,723,163,
-707,707,707,707,707,707,707,707,707,993,993,993,723,723,958,958,
-
-/* block 142 */
-994,994,994,994,994,994,994,994,994,994,994,994,163,994,994,994,
-994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,
-994,994,994,994,994,994,994,163,994,994,994,994,994,994,994,994,
-994,994,994,994,994,994,994,994,994,994,994,163,994,994,163,994,
-994,994,994,994,994,994,994,994,994,994,994,994,994,994,163,163,
-994,994,994,994,994,994,994,994,994,994,994,994,994,994,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 143 */
-994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,
-994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,
-994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,
-994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,
-994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,
-994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,
-994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,
-994,994,994,994,994,994,994,994,994,994,994,163,163,163,163,163,
-
-/* block 144 */
-995,996,997,163,163,163,163,998,998,998,998,998,998,998,998,998,
-998,998,998,998,998,998,998,998,998,998,998,998,998,998,998,998,
-998,998,998,998,998,998,998,998,998,998,998,998,998,998,998,998,
-998,998,998,998,163,163,163,999,999,999,999,999,999,999,999,999,
-1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,
-1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,
-1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,
-1000,1000,1000,1000,1000,1001,1001,1001,1001,1002,1002,1002,1002,1002,1002,1002,
-
-/* block 145 */
-1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1001,1001,1002,1003,1003,163,
-723,723,723,723,723,723,723,723,723,723,723,723,723,163,163,163,
-1002,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,158,163,163,
-
-/* block 146 */
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 147 */
-1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,
-1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,163,163,163,
-1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,
-1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,
-1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,
-1005,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-1006,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,
-1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,163,163,163,163,
-
-/* block 148 */
-1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,
-1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,
-1009,1009,1009,1009,163,163,163,163,163,163,163,163,163,1008,1008,1008,
-1010,1010,1010,1010,1010,1010,1010,1010,1010,1010,1010,1010,1010,1010,1010,1010,
-1010,1011,1010,1010,1010,1010,1010,1010,1010,1010,1011,163,163,163,163,163,
-1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,
-1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,
-1012,1012,1012,1012,1012,1012,1013,1013,1013,1013,1013,163,163,163,163,163,
-
-/* block 149 */
-1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,
-1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,163,1015,
-1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,
-1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,
-1016,1016,1016,1016,163,163,163,163,1016,1016,1016,1016,1016,1016,1016,1016,
-1017,1018,1018,1018,1018,1018,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 150 */
-1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,
-1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,
-1019,1019,1019,1019,1019,1019,1019,1019,1020,1020,1020,1020,1020,1020,1020,1020,
-1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,
-1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,
-1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,
-1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,
-1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,
-
-/* block 151 */
-1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,
-1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,163,163,
-1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,163,163,163,163,163,163,
-1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,
-1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,
-1024,1024,1024,1024,163,163,163,163,1025,1025,1025,1025,1025,1025,1025,1025,
-1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,
-1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,163,163,163,163,
-
-/* block 152 */
-1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,
-1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,
-1026,1026,1026,1026,1026,1026,1026,1026,163,163,163,163,163,163,163,163,
-1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,
-1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,
-1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,
-1027,1027,1027,1027,163,163,163,163,163,163,163,163,163,163,163,1028,
-1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,163,1029,1029,1029,1029,
-
-/* block 153 */
-1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,163,1029,1029,1029,1029,
-1029,1029,1029,163,1029,1029,163,1030,1030,1030,1030,1030,1030,1030,1030,1030,
-1030,1030,163,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,
-1030,1030,163,1030,1030,1030,1030,1030,1030,1030,163,1030,1030,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 154 */
-1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,
-1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,
-1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,
-1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,
-1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,
-1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,
-1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,
-1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,
-
-/* block 155 */
-1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,
-1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,
-1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,
-1031,1031,1031,1031,1031,1031,1031,163,163,163,163,163,163,163,163,163,
-1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,
-1031,1031,1031,1031,1031,1031,163,163,163,163,163,163,163,163,163,163,
-1031,1031,1031,1031,1031,1031,1031,1031,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 156 */
-147,1032,1032,147,147,147,163,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,163,147,147,147,147,147,147,147,147,147,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 157 */
-1033,1033,1033,1033,1033,1033,262,262,1033,262,1033,1033,1033,1033,1033,1033,
-1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,
-1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,
-1033,1033,1033,1033,1033,1033,262,1033,1033,262,262,262,1033,262,262,1033,
-1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,
-1034,1034,1034,1034,1034,1034,262,1035,1036,1036,1036,1036,1036,1036,1036,1036,
-1037,1037,1037,1037,1037,1037,1037,1037,1037,1037,1037,1037,1037,1037,1037,1037,
-1037,1037,1037,1037,1037,1037,1037,1038,1038,1039,1039,1039,1039,1039,1039,1039,
-
-/* block 158 */
-1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,
-1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,262,
-262,262,262,262,262,262,262,1041,1041,1041,1041,1041,1041,1041,1041,1041,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-1042,1042,1042,1042,1042,1042,1042,1042,1042,1042,1042,1042,1042,1042,1042,1042,
-1042,1042,1042,262,1042,1042,262,262,262,262,262,1043,1043,1043,1043,1043,
-
-/* block 159 */
-1044,1044,1044,1044,1044,1044,1044,1044,1044,1044,1044,1044,1044,1044,1044,1044,
-1044,1044,1044,1044,1044,1044,1045,1045,1045,1045,1045,1045,262,262,262,1046,
-1047,1047,1047,1047,1047,1047,1047,1047,1047,1047,1047,1047,1047,1047,1047,1047,
-1047,1047,1047,1047,1047,1047,1047,1047,1047,1047,262,262,262,262,262,1048,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-
-/* block 160 */
-1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,
-1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,
-1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,
-1050,1050,1050,1050,1050,1050,1050,1050,262,262,262,262,1051,1051,1050,1050,
-1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,
-262,262,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,
-1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,
-1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,
-
-/* block 161 */
-1052,1053,1053,1053,262,1053,1053,262,262,262,262,262,1053,1053,1053,1053,
-1052,1052,1052,1052,262,1052,1052,1052,262,1052,1052,1052,1052,1052,1052,1052,
-1052,1052,1052,1052,1052,1052,1052,1052,1052,1052,1052,1052,1052,1052,1052,1052,
-1052,1052,1052,1052,1052,1052,262,262,1054,1054,1054,262,262,262,262,1055,
-1056,1056,1056,1056,1056,1056,1056,1056,1056,262,262,262,262,262,262,262,
-1057,1057,1057,1057,1057,1057,1058,1058,1057,262,262,262,262,262,262,262,
-1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,
-1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1060,1060,1061,
-
-/* block 162 */
-1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,
-1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1063,1063,1063,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-1064,1064,1064,1064,1064,1064,1064,1064,1065,1064,1064,1064,1064,1064,1064,1064,
-1064,1064,1064,1064,1064,1064,1064,1064,1064,1064,1064,1064,1064,1064,1064,1064,
-1064,1064,1064,1064,1064,1066,1066,262,262,262,262,1067,1067,1067,1067,1067,
-1068,1068,1069,1068,1068,1068,1070,262,262,262,262,262,262,262,262,262,
-
-/* block 163 */
-1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,
-1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,
-1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,
-1071,1071,1071,1071,1071,1071,262,262,262,1072,1073,1073,1073,1073,1073,1073,
-1074,1074,1074,1074,1074,1074,1074,1074,1074,1074,1074,1074,1074,1074,1074,1074,
-1074,1074,1074,1074,1074,1074,262,262,1075,1075,1075,1075,1075,1075,1075,1075,
-1076,1076,1076,1076,1076,1076,1076,1076,1076,1076,1076,1076,1076,1076,1076,1076,
-1076,1076,1076,262,262,262,262,262,1077,1077,1077,1077,1077,1077,1077,1077,
-
-/* block 164 */
-1078,1078,1078,1078,1078,1078,1078,1078,1078,1078,1078,1078,1078,1078,1078,1078,
-1078,1078,262,262,262,262,262,262,262,1079,1079,1079,1079,262,262,262,
-262,262,262,262,262,262,262,262,262,1080,1080,1080,1080,1080,1080,1080,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-
-/* block 165 */
-1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,
-1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,
-1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,
-1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,
-1081,1081,1081,1081,1081,1081,1081,1081,1081,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-
-/* block 166 */
-1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,
-1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,
-1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,
-1082,1082,1082,262,262,262,262,262,262,262,262,262,262,262,262,262,
-1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,
-1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,
-1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,
-1083,1083,1083,262,262,262,262,262,262,262,1084,1084,1084,1084,1084,1084,
-
-/* block 167 */
-1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,
-1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,
-1085,1085,1086,1086,1087,1087,1087,1087,302,302,302,302,302,302,302,302,
-1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,302,302,302,302,302,302,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-
-/* block 168 */
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-
-/* block 169 */
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,
-1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,262,
-
-/* block 170 */
-1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,
-1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,
-1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,262,1091,1091,1092,262,262,
-1090,1090,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-
-/* block 171 */
-1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,
-1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1094,1094,1094,
-1094,1094,1094,1094,1094,1094,1094,1093,262,262,262,262,262,262,262,262,
-1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,
-1095,1095,1095,1095,1095,1095,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,
-1096,1097,1097,1097,1097,1098,1098,1098,1098,1098,302,302,302,302,302,302,
-302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,
-1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,
-
-/* block 172 */
-1099,1099,1100,1100,1100,1100,1101,1101,1101,1101,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,
-1102,1102,1102,1102,1102,1103,1103,1103,1103,1103,1103,1103,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,
-1104,1104,1104,1104,1104,1104,1104,262,262,262,262,262,262,262,262,262,
-
-/* block 173 */
-1105,1106,1105,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,
-1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,
-1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,
-1107,1107,1107,1107,1107,1107,1107,1107,1106,1106,1106,1106,1106,1106,1106,1106,
-1106,1106,1106,1106,1106,1106,1108,1109,1109,1110,1110,1110,1110,1110,163,163,
-163,163,1111,1111,1111,1111,1111,1111,1111,1111,1111,1111,1111,1111,1111,1111,
-1111,1111,1111,1111,1111,1111,1112,1112,1112,1112,1112,1112,1112,1112,1112,1112,
-1108,1107,1107,1106,1106,1107,163,163,163,163,163,163,163,163,163,1113,
-
-/* block 174 */
-1114,1114,1115,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,
-1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,
-1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,
-1115,1115,1115,1117,1117,1117,1117,1115,1115,1118,1119,1120,1120,1121,1122,1122,
-1122,1122,1117,163,163,163,163,163,163,163,163,163,163,1121,163,163,
-1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,
-1123,1123,1123,1123,1123,1123,1123,1123,1123,163,163,163,163,163,163,163,
-1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,163,163,163,163,163,163,
-
-/* block 175 */
-1125,1125,1125,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,
-1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,
-1126,1126,1126,1126,1126,1126,1126,1125,1125,1125,1125,1125,1127,1125,1125,1125,
-1125,1125,1125,1128,1128,163,1129,1129,1129,1129,1129,1129,1129,1129,1129,1129,
-1130,1131,1131,1131,1126,1127,1127,1126,163,163,163,163,163,163,163,163,
-1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,
-1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,
-1132,1132,1132,1133,1134,1134,1132,163,163,163,163,163,163,163,163,163,
-
-/* block 176 */
-1135,1135,1136,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,
-1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,
-1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,
-1137,1137,1137,1136,1136,1136,1135,1135,1135,1135,1135,1135,1135,1135,1135,1136,
-1138,1137,1139,1139,1137,1140,1140,1141,1141,1142,1143,1143,1143,1140,1136,1135,
-1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1137,1141,1137,1141,1140,1140,
-163,1145,1145,1145,1145,1145,1145,1145,1145,1145,1145,1145,1145,1145,1145,1145,
-1145,1145,1145,1145,1145,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 177 */
-1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,
-1146,1146,163,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,
-1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1147,1147,1147,1148,
-1148,1148,1147,1147,1148,1149,1150,1148,1151,1151,1152,1151,1151,1153,1148,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 178 */
-1154,1154,1154,1154,1154,1154,1154,163,1154,163,1154,1154,1154,1154,163,1154,
-1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,163,1154,
-1154,1154,1154,1154,1154,1154,1154,1154,1154,1155,163,163,163,163,163,163,
-1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,
-1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,
-1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1157,
-1158,1158,1158,1157,1157,1157,1157,1157,1157,1159,1160,163,163,163,163,163,
-1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,163,163,163,163,163,163,
-
-/* block 179 */
-1162,1163,1164,1165,163,1166,1166,1166,1166,1166,1166,1166,1166,163,163,1166,
-1166,163,163,1166,1166,1166,1166,1166,1166,1166,1166,1166,1166,1166,1166,1166,
-1166,1166,1166,1166,1166,1166,1166,1166,1166,163,1166,1166,1166,1166,1166,1166,
-1166,163,1166,1166,163,1166,1166,1166,1166,1166,163,1167,1168,1166,1169,1164,
-1162,1164,1164,1164,1164,163,163,1164,1164,163,163,1164,1164,1170,163,163,
-1166,163,163,163,163,163,163,1169,163,163,163,163,163,1171,1166,1166,
-1166,1166,1164,1164,163,163,1172,1172,1172,1172,1172,1172,1172,163,163,163,
-1172,1172,1172,1172,1172,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 180 */
-1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,
-1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,
-1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,
-1173,1173,1173,1173,1173,1174,1174,1174,1175,1175,1175,1175,1175,1175,1175,1175,
-1174,1174,1176,1175,1175,1174,1177,1173,1173,1173,1173,1178,1178,1179,1180,1180,
-1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1179,1179,163,1180,1182,1173,
-1173,1173,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 181 */
-1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,
-1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,
-1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,
-1184,1185,1185,1186,1186,1186,1186,1186,1186,1185,1186,1185,1185,1184,1185,1186,
-1186,1185,1187,1188,1183,1183,1189,1183,163,163,163,163,163,163,163,163,
-1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 182 */
-1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,
-1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,
-1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1192,
-1193,1193,1194,1194,1194,1194,163,163,1193,1193,1193,1193,1194,1194,1193,1195,
-1196,1197,1198,1198,1199,1199,1200,1200,1200,1198,1198,1198,1198,1198,1198,1198,
-1198,1198,1198,1198,1198,1198,1198,1198,1191,1191,1191,1191,1194,1194,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 183 */
-1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,
-1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,
-1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,
-1202,1202,1202,1203,1203,1203,1203,1203,1203,1203,1203,1202,1202,1203,1202,1204,
-1203,1205,1205,1206,1201,163,163,163,163,163,163,163,163,163,163,163,
-1207,1207,1207,1207,1207,1207,1207,1207,1207,1207,163,163,163,163,163,163,
-530,530,530,530,530,530,530,530,530,530,530,530,530,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 184 */
-1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,
-1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,
-1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1209,1210,1209,1210,1210,
-1209,1209,1209,1209,1209,1209,1211,1212,1208,1213,163,163,163,163,163,163,
-1214,1214,1214,1214,1214,1214,1214,1214,1214,1214,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 185 */
-1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,
-1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,163,163,1216,1216,1216,
-1217,1217,1216,1216,1216,1216,1218,1216,1216,1216,1216,1219,163,163,163,163,
-1220,1220,1220,1220,1220,1220,1220,1220,1220,1220,1221,1221,1222,1222,1222,1223,
-1215,1215,1215,1215,1215,1215,1215,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 186 */
-1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,
-1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,
-1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1225,1225,1225,1226,
-1226,1226,1226,1226,1226,1226,1226,1226,1225,1227,1228,1229,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 187 */
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,
-1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,
-1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,
-1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,
-1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1233,1233,1233,1233,1233,1233,
-1233,1233,1233,163,163,163,163,163,163,163,163,163,163,163,163,1234,
-
-/* block 188 */
-1235,1235,1235,1235,1235,1235,1235,163,163,1235,163,163,1235,1235,1235,1235,
-1235,1235,1235,1235,163,1235,1235,163,1235,1235,1235,1235,1235,1235,1235,1235,
-1235,1235,1235,1235,1235,1235,1235,1235,1235,1235,1235,1235,1235,1235,1235,1235,
-1236,1237,1237,1237,1237,1237,163,1237,1237,163,163,1238,1238,1239,1240,1241,
-1237,1241,1237,1242,1243,1244,1243,163,163,163,163,163,163,163,163,163,
-1245,1245,1245,1245,1245,1245,1245,1245,1245,1245,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 189 */
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-1246,1246,1246,1246,1246,1246,1246,1246,163,163,1246,1246,1246,1246,1246,1246,
-1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,
-1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,
-1246,1247,1247,1247,1248,1248,1248,1248,163,163,1248,1248,1247,1247,1247,1247,
-1249,1246,1250,1246,1247,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 190 */
-1251,1252,1252,1252,1252,1252,1252,1253,1253,1252,1252,1251,1251,1251,1251,1251,
-1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,
-1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,
-1251,1251,1251,1254,1255,1252,1252,1252,1252,1256,1257,1252,1252,1252,1252,1258,
-1258,1258,1259,1259,1258,1258,1258,1255,163,163,163,163,163,163,163,163,
-1260,1261,1261,1261,1261,1261,1261,1262,1262,1261,1261,1261,1260,1260,1260,1260,
-1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,
-1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,
-
-/* block 191 */
-1260,1260,1260,1260,1263,1263,1263,1263,1263,1263,1261,1261,1261,1261,1261,1261,
-1261,1261,1261,1261,1261,1261,1261,1262,1264,1265,1266,1267,1267,1260,1266,1266,
-1266,1268,1268,163,163,163,163,163,163,163,163,163,163,163,163,163,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,
-1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,
-1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,
-1269,1269,1269,1269,1269,1269,1269,1269,1269,163,163,163,163,163,163,163,
-
-/* block 192 */
-1270,1270,1270,1270,1270,1270,1270,1270,1270,163,1270,1270,1270,1270,1270,1270,
-1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,
-1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1271,
-1272,1272,1272,1272,1272,1272,1272,163,1272,1272,1272,1272,1272,1272,1271,1273,
-1270,1274,1274,1275,1276,1276,163,163,163,163,163,163,163,163,163,163,
-1277,1277,1277,1277,1277,1277,1277,1277,1277,1277,1278,1278,1278,1278,1278,1278,
-1278,1278,1278,1278,1278,1278,1278,1278,1278,1278,1278,1278,1278,163,163,163,
-1279,1280,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,
-
-/* block 193 */
-1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,
-163,163,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,
-1282,1282,1282,1282,1282,1282,1282,1282,163,1283,1282,1282,1282,1282,1282,1282,
-1282,1283,1282,1282,1283,1282,1282,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 194 */
-1284,1284,1284,1284,1284,1284,1284,163,1284,1284,163,1284,1284,1284,1284,1284,
-1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,
-1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,
-1284,1285,1285,1285,1285,1285,1285,163,163,163,1285,163,1285,1285,163,1285,
-1285,1285,1286,1285,1287,1287,1288,1285,163,163,163,163,163,163,163,163,
-1289,1289,1289,1289,1289,1289,1289,1289,1289,1289,163,163,163,163,163,163,
-1290,1290,1290,1290,1290,1290,163,1290,1290,163,1290,1290,1290,1290,1290,1290,
-1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,
-
-/* block 195 */
-1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1291,1291,1291,1291,1291,163,
-1292,1292,163,1291,1291,1292,1291,1293,1290,163,163,163,163,163,163,163,
-1294,1294,1294,1294,1294,1294,1294,1294,1294,1294,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 196 */
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-1295,1295,1295,1295,1295,1295,1295,1295,1295,1295,1295,1295,1295,1295,1295,1295,
-1295,1295,1295,1296,1296,1297,1297,1298,1298,163,163,163,163,163,163,163,
-
-/* block 197 */
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-842,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-1299,1299,1299,1299,1299,1299,1299,1299,1299,1299,1299,1299,1299,1299,1299,1299,
-388,388,1299,388,1299,390,390,390,390,390,390,390,390,391,391,391,
-391,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,
-390,390,163,163,163,163,163,163,163,163,163,163,163,163,163,1300,
-
-/* block 198 */
-1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,
-1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,
-1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,
-1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,
-1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,
-1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,
-1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,
-1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,
-
-/* block 199 */
-1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,
-1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 200 */
-1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,
-1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,
-1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,
-1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,
-1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,
-1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,
-1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,163,
-1303,1303,1303,1303,1303,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 201 */
-1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,
-1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,
-1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,
-1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,
-1301,1301,1301,1301,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 202 */
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,
-1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,
-1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,
-1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,
-1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,
-1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,
-1304,1305,1305,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 203 */
-1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,
-1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,
-1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,
-1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,
-1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,
-1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,
-1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,
-1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,
-
-/* block 204 */
-1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,
-1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,
-1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,163,
-1307,1307,1307,1307,1307,1307,1307,1307,1307,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 205 */
-1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,
-1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,
-1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,
-1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,
-1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,
-1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,
-1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,
-1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,
-
-/* block 206 */
-1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,
-1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,
-1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,
-1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,
-1308,1308,1308,1308,1308,1308,1308,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 207 */
-858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
-858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
-858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
-858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
-858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
-858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
-858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
-858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
-
-/* block 208 */
-858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
-858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
-858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
-858,858,858,858,858,858,858,858,858,163,163,163,163,163,163,163,
-1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,
-1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,163,
-1310,1310,1310,1310,1310,1310,1310,1310,1310,1310,163,163,163,163,1311,1311,
-1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,
-
-/* block 209 */
-1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,
-1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,
-1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,
-1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,163,
-1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,163,163,163,163,163,163,
-1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,
-1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,163,163,
-1315,1315,1315,1315,1315,1316,163,163,163,163,163,163,163,163,163,163,
-
-/* block 210 */
-1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,
-1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,
-1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,
-1318,1318,1318,1318,1318,1318,1318,1319,1319,1320,1321,1321,1322,1322,1322,1322,
-1323,1323,1324,1324,1319,1322,163,163,163,163,163,163,163,163,163,163,
-1325,1325,1325,1325,1325,1325,1325,1325,1325,1325,163,1326,1326,1326,1326,1326,
-1326,1326,163,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,
-1317,1317,1317,1317,1317,1317,1317,1317,163,163,163,163,163,1317,1317,1317,
-
-/* block 211 */
-1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 212 */
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,
-1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,
-1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,
-1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,
-
-/* block 213 */
-1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,
-1329,1329,1329,1329,1329,1329,1329,1330,1331,1332,1332,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 214 */
-1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,
-1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,
-1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,
-1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,
-1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,163,163,163,163,1334,
-1333,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,
-1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,
-1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,
-
-/* block 215 */
-1335,1335,1335,1335,1335,1335,1335,1335,163,163,163,163,163,163,163,1336,
-1336,1336,1336,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-1338,1339,1340,799,1341,163,163,163,163,163,163,163,163,163,163,163,
-1342,1342,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 216 */
-1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,
-1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,
-1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,
-1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,
-1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,
-1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,
-1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,
-1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,
-
-/* block 217 */
-1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,
-1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,
-1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,
-1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,
-1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,
-1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,
-1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,
-1343,1343,1343,1343,1343,1343,1343,1343,163,163,163,163,163,163,163,163,
-
-/* block 218 */
-1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,
-1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,
-1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,
-1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,
-1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,
-1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,
-1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,
-1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,
-
-/* block 219 */
-1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,
-1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,
-1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,
-1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,
-1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,
-1344,1344,1344,1344,1344,1344,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 220 */
-1343,1343,1343,1343,1343,1343,1343,1343,1343,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 221 */
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-1345,1345,1345,1345,163,1345,1345,1345,1345,1345,1345,1345,163,1345,1345,163,
-
-/* block 222 */
-824,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-
-/* block 223 */
-819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-
-/* block 224 */
-819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
-824,824,824,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-819,819,819,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,824,824,824,824,163,163,163,163,163,163,163,163,
-1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,
-
-/* block 225 */
-1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,
-1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,
-1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,
-1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,
-1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,
-1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,
-1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,
-1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,
-
-/* block 226 */
-1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,
-1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,
-1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,
-1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,
-1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,
-1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,
-1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,
-1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,163,163,163,163,
-
-/* block 227 */
-1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,
-1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,
-1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,
-1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,
-1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,
-1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,
-1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,163,163,163,163,163,
-1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,163,163,163,
-
-/* block 228 */
-1347,1347,1347,1347,1347,1347,1347,1347,1347,163,163,163,163,163,163,163,
-1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,163,163,1348,1349,1350,1351,
-1352,1352,1352,1352,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 229 */
-154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
-154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
-154,154,154,154,154,154,154,154,154,154,154,154,154,154,163,163,
-154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
-154,154,154,154,154,154,154,163,163,163,163,163,163,163,163,163,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-
-/* block 230 */
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 231 */
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-
-/* block 232 */
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,163,163,163,163,163,163,163,163,163,163,
-
-/* block 233 */
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,163,163,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,1353,1354,154,154,154,460,460,460,1355,1356,1356,
-1356,1356,1356, 51, 51, 51, 51, 51, 51, 51, 51,154,154,154,154,154,
-
-/* block 234 */
-154,154,154,460,460,154,154,154,154,154,154,154,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,154,154,154,154,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,723,723,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 235 */
-1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,
-1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,
-1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,
-1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,
-1002,1002,1357,1357,1357,1002,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 236 */
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,
-835,835,835,835,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 237 */
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,163,163,163,163,163,163,163,163,163,
-832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,
-832,832,835,835,835,835,835,835,835,163,163,163,163,163,163,163,
-
-/* block 238 */
-724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,
-724,724,724,724,724,724,724,724,724,724,725,725,725,725,725,725,
-725,725,736,736,725,725,725,725,725,725,725,725,725,725,725,725,
-725,725,725,725,724,724,724,724,724,724,724,724,724,724,724,724,
-724,724,724,724,724,724,724,724,724,724,724,724,724,724,725,725,
-725,725,725,725,725,163,736,736,725,725,725,725,725,725,725,725,
-725,725,725,725,725,725,725,725,724,724,724,724,724,724,724,724,
-724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,
-
-/* block 239 */
-724,724,725,725,725,725,725,725,725,725,736,736,725,725,725,725,
-725,725,725,725,725,725,725,725,725,725,725,725,724,163,724,724,
-163,163,724,163,163,724,724,163,163,724,724,724,724,163,724,724,
-724,724,724,724,724,724,725,725,725,725,163,725,163,725,736,736,
-725,725,725,725,163,725,725,725,725,725,725,725,725,725,725,725,
-724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,
-724,724,724,724,724,724,724,724,724,724,725,725,725,725,725,725,
-725,725,736,736,725,725,725,725,725,725,725,725,725,725,725,725,
-
-/* block 240 */
-725,725,725,725,724,724,163,724,724,724,724,163,163,724,724,724,
-724,724,724,724,724,163,724,724,724,724,724,724,724,163,725,725,
-725,725,725,725,725,725,736,736,725,725,725,725,725,725,725,725,
-725,725,725,725,725,725,725,725,724,724,163,724,724,724,724,163,
-724,724,724,724,724,163,724,163,163,163,724,724,724,724,724,724,
-724,163,725,725,725,725,725,725,725,725,736,736,725,725,725,725,
-725,725,725,725,725,725,725,725,725,725,725,725,724,724,724,724,
-724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,
-
-/* block 241 */
-724,724,724,724,724,724,725,725,725,725,725,725,725,725,736,736,
-725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,
-724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,
-724,724,724,724,724,724,724,724,724,724,725,725,725,725,725,725,
-725,725,736,736,725,725,725,725,725,725,725,725,725,725,725,725,
-725,725,725,725,724,724,724,724,724,724,724,724,724,724,724,724,
-724,724,724,724,724,724,724,724,724,724,724,724,724,724,725,725,
-725,725,725,725,725,725,736,736,725,725,725,725,725,725,725,725,
-
-/* block 242 */
-725,725,725,725,725,725,725,725,724,724,724,724,724,724,724,724,
-724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,
-724,724,725,725,725,725,725,725,725,725,736,736,725,725,725,725,
-725,725,725,725,725,725,725,725,725,725,725,725,724,724,724,724,
-724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,
-724,724,724,724,724,724,725,725,725,725,725,725,725,725,736,736,
-725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,
-724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,
-
-/* block 243 */
-724,724,724,724,724,724,724,724,724,724,725,725,725,725,725,725,
-725,725,736,736,725,725,725,725,725,725,725,725,725,725,725,725,
-725,725,725,725,725,725,163,163,724,724,724,724,724,724,724,724,
-724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,
-724,1358,725,725,725,725,725,725,725,725,725,725,725,725,725,725,
-725,725,725,725,725,725,725,725,725,725,725,715,725,725,725,725,
-725,725,724,724,724,724,724,724,724,724,724,724,724,724,724,724,
-724,724,724,724,724,724,724,724,724,724,724,1358,725,725,725,725,
-
-/* block 244 */
-725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,
-725,725,725,725,725,715,725,725,725,725,725,725,724,724,724,724,
-724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,
-724,724,724,724,724,1358,725,725,725,725,725,725,725,725,725,725,
-725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,715,
-725,725,725,725,725,725,724,724,724,724,724,724,724,724,724,724,
-724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,1358,
-725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,
-
-/* block 245 */
-725,725,725,725,725,725,725,725,725,715,725,725,725,725,725,725,
-724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,
-724,724,724,724,724,724,724,724,724,1358,725,725,725,725,725,725,
-725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,
-725,725,725,715,725,725,725,725,725,725,724,725,163,163,1359,1359,
-1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,
-1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,
-1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,
-
-/* block 246 */
-1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,
-1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,
-1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,
-1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,
-1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,
-1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,
-1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,
-1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,
-
-/* block 247 */
-1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,
-1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,
-1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,
-1361,1361,1361,1361,1361,1361,1361,1360,1360,1360,1360,1361,1361,1361,1361,1361,
-1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,
-1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,
-1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1360,1360,1360,
-1360,1360,1360,1360,1360,1361,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,
-
-/* block 248 */
-1360,1360,1360,1360,1361,1360,1360,1362,1363,1362,1362,1364,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,1361,1361,1361,1361,1361,
-163,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 249 */
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 92, 70, 70, 70, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,643, 70, 70, 70, 70,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 250 */
-1365,1365,1365,1365,1365,1365,1365,163,1365,1365,1365,1365,1365,1365,1365,1365,
-1365,1365,1365,1365,1365,1365,1365,1365,1365,163,163,1365,1365,1365,1365,1365,
-1365,1365,163,1365,1365,163,1365,1365,1365,1365,1365,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 251 */
-1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,
-1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,
-1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,163,163,163,
-1367,1367,1367,1367,1367,1367,1367,1368,1368,1368,1368,1368,1369,1369,163,163,
-1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,163,163,163,163,1366,1371,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 252 */
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,
-1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1373,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,
-1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,
-1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1375,1375,1375,1375,
-1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,163,163,163,163,163,1377,
-
-/* block 253 */
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-483,483,483,483,483,483,483,163,483,483,483,483,163,483,483,163,
-483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,163,
-
-/* block 254 */
-1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,
-1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,
-1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,
-1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,
-1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,
-1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,
-1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,
-1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,
-
-/* block 255 */
-1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,
-1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,
-1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,
-1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,
-1378,1378,1378,1378,1378,262,262,1379,1379,1379,1379,1379,1379,1379,1379,1379,
-1380,1380,1380,1380,1380,1380,1380,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-
-/* block 256 */
-1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,
-1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,
-1381,1381,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,
-1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,
-1382,1382,1382,1382,1383,1383,1383,1384,1385,1385,1385,1386,262,262,262,262,
-1387,1387,1387,1387,1387,1387,1387,1387,1387,1387,262,262,262,262,1388,1388,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-
-/* block 257 */
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-302,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,
-
-/* block 258 */
-1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,
-1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,
-1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1390,1389,1389,1389,
-1391,1389,1389,1389,1389,302,302,302,302,302,302,302,302,302,302,302,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-
-/* block 259 */
-302,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,
-1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,
-1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1390,1389,
-1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,302,302,
-302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,
-
-/* block 260 */
-1392,1392,1392,1392,302,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,
-1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,
-302,1392,1392,302,1392,302,302,1392,302,1392,1392,1392,1392,1392,1392,1392,
-1392,1392,1392,302,1392,1392,1392,1392,302,1392,302,1392,302,302,302,302,
-302,302,1392,302,302,302,302,1392,302,1392,302,1392,302,1392,1392,1392,
-302,1392,1392,302,1392,302,302,1392,302,1392,302,1392,302,1392,302,1392,
-302,1392,1392,302,1392,302,302,1392,1392,1392,1392,302,1392,1392,1392,1392,
-1392,1392,1392,302,1392,1392,1392,1392,302,1392,1392,1392,1392,302,1392,302,
-
-/* block 261 */
-1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,302,1392,1392,1392,1392,1392,
-1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,302,302,302,302,
-302,1392,1392,1392,302,1392,1392,1392,1392,1392,302,1392,1392,1392,1392,1392,
-1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,302,302,302,302,
-302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,
-302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,
-302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,
-274,274,302,302,302,302,302,302,302,302,302,302,302,302,302,302,
-
-/* block 262 */
-1393,1393,1393,1393,1394,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,
-1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,
-1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1395,1395,1395,1395,
-1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,
-1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,
-1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,
-1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,
-1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,
-
-/* block 263 */
-1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,
-1393,1393,1393,1393,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1395,
-1395,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,
-1395,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1394,
-1395,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,
-1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,
-1393,1393,1393,1393,1393,1393,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-
-/* block 264 */
- 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 58, 58,1393,1393,1393,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,1393,
-1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,
-1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,460,460,460,460,460,460,
-1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,
-1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,723,723,1393,1393,1393,1393,
-1397,1397,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1397,1397,
-
-/* block 265 */
-1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,460,460,460,460,1398,460,
-460,1398,1398,1398,1398,1398,1398,1398,1398,1398,1398,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,1393,1395,1395,
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1395,1395,1395,1395,1395,1395,1399,1399,1399,1399,1399,1399,1399,1399,1399,1399,
-1399,1399,1399,1399,1399,1399,1399,1399,1399,1399,1399,1399,1399,1399,1399,1399,
-
-/* block 266 */
-1400,1398,1401,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-460,460,460,460,460,460,460,460,460,460,1398,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,1398,
-460,460,1398,1398,1398,1398,1398,1401,1398,1398,1398,460,1395,1395,1395,1395,
-460,460,460,460,460,460,460,460,460,1395,1395,1395,1395,1395,1395,1395,
-1402,1402,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1393,1393,1393,1393,1393,1393,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-
-/* block 267 */
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-
-/* block 268 */
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,727,1393,1393,727,727,727,727,727,727,727,727,727,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,727,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,727,1394,1394,
-
-/* block 269 */
-1394,1394,1394,1394,1394,1403,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1393,1393,727,727,1393,727,727,727,1393,1393,727,727,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1403,1403,1403,1394,1394,1403,1394,1394,1403,1404,1404,727,727,1394,
-1394,1394,1394,1394,727,727,727,727,727,727,727,727,727,727,727,727,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1393,1393,727,1394,727,1393,727,1394,1394,1394,1405,1405,1405,1405,1405,
-
-/* block 270 */
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,727,
-1394,727,1403,1403,1394,1394,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,
-1403,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,
-1403,1403,1403,1403,1403,1403,1403,1403,1403,1394,1394,1394,1403,1394,1394,1394,
-
-/* block 271 */
-1394,1403,1403,1403,1394,1403,1403,1403,1394,1394,1394,1394,1394,1394,1394,1403,
-1394,1403,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1403,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,727,1393,1394,
-
-/* block 272 */
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,723,723,
-723,723,723,723,723,723,1393,1393,1393,727,727,1394,1394,1394,1394,1393,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1393,1393,1393,1393,1393,1393,1393,727,
-727,1393,1393,727,1404,1404,727,727,727,727,1403,1393,1393,1393,1393,1393,
-
-/* block 273 */
-1393,1393,1393,1393,1393,1393,1393,727,1393,1393,727,727,727,727,1393,1393,
-1404,1393,1393,1393,1393,1403,1403,1393,1393,1393,1393,1393,1393,1393,1393,1393,
-1393,1393,1393,1393,1394,727,1393,1393,727,1393,1393,1393,1393,1393,1393,1393,
-1393,727,727,1393,1393,1393,1393,1393,1393,1393,1393,1393,727,1393,1393,1393,
-1393,1393,727,727,727,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,
-1393,727,727,727,1393,1393,1393,1393,1393,1393,1393,1393,727,727,727,1393,
-1393,727,1393,727,1393,1393,1393,1393,727,1393,1393,1393,1393,1393,1393,727,
-1393,1393,1393,727,1393,1393,1393,1393,1393,1393,727,1394,1394,1394,1394,1394,
-
-/* block 274 */
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1403,1403,1403,1394,1394,1394,1403,1403,1403,1403,1403,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-
-/* block 275 */
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1403,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1403,1403,1403,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1403,1394,1394,1394,1394,1394,1393,1393,1393,1393,1393,727,1403,727,727,727,
-1394,1394,1394,1393,1393,1394,1394,1394,1395,1395,1395,1395,1395,1394,1394,1394,
-727,727,727,727,727,727,1393,1393,1393,727,1393,1394,1394,1395,1395,1395,
-727,1393,1393,727,1394,1394,1394,1394,1394,1394,1394,1394,1394,1395,1395,1395,
-
-/* block 276 */
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-
-/* block 277 */
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,1393,1393,1393,1393,1395,1395,1395,1395,1395,1395,1395,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1395,1395,1395,1395,
-1394,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-
-/* block 278 */
-723,723,723,723,723,723,723,723,723,723,723,723,1395,1395,1395,1395,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,1395,1395,1395,1395,1395,1395,1395,1395,
-723,723,723,723,723,723,723,723,723,723,1395,1395,1395,1395,1395,1395,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-
-/* block 279 */
-723,723,723,723,723,723,723,723,1395,1395,1395,1395,1395,1395,1395,1395,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,1395,1395,
-1393,1393,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-
-/* block 280 */
-723,723,723,723,723,723,723,723,723,723,723,723,1403,1394,1394,1403,
-1394,1394,1394,1394,1394,1394,1394,1394,1403,1403,1403,1403,1403,1403,1403,1403,
-1394,1394,1394,1394,1394,1394,1403,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1394,723,1403,1403,1403,1394,
-1394,1394,1394,1394,1394,1394,723,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1403,1394,1394,1394,1394,1394,1394,1394,1394,
-
-/* block 281 */
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1406,1406,1406,1406,1394,1403,1403,1394,1403,1403,1394,1403,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1403,1403,1403,
-1394,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-
-/* block 282 */
-1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,
-1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,
-1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,
-1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,
-1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,
-1393,1393,1393,1393,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1395,1395,
-1394,1394,1394,1394,1394,1395,1395,1395,1394,1394,1394,1394,1394,1395,1395,1395,
-
-/* block 283 */
-1394,1394,1394,1394,1394,1394,1394,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1395,1395,1395,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1395,1395,1395,1395,1395,
-1394,1394,1394,1403,1403,1403,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1395,1395,1395,1395,1395,1395,
-1394,1394,1394,1394,1394,1394,1394,1394,1395,1395,1395,1395,1395,1395,1395,1395,
-1403,1403,1403,1403,1403,1403,1403,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-
-/* block 284 */
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-
-/* block 285 */
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,163,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
-723,723,723,723,723,723,723,723,723,723,723,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,163,163,163,163,163,163,
-
-/* block 286 */
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,
-1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,958,958,
-
-/* block 287 */
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 288 */
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,163,163,163,163,163,163,163,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-
-/* block 289 */
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,163,163,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-
-/* block 290 */
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-
-/* block 291 */
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 292 */
-953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,
-953,953,953,953,953,953,953,953,953,953,953,953,953,953,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 293 */
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,958,958,
-
-/* block 294 */
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-
-/* block 295 */
-707,712,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
-707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
-1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,
-1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,
-1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,
-1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,
-1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,
-1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,
-
-/* block 296 */
-707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
-707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
-707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
-707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
-707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
-707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
-707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
-707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
-
-/* block 297 */
-961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
-961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
-961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
-961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
-961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
-961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
-961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
-961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
-
-/* block 298 */
-961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
-961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
-961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
-961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
-961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
-961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
-961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
-707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
-
-/* block 299 */
-952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,
-952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,
-952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,
-952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,
-952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,
-952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,
-952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,
-952,952,952,952,952,952,952,952,952,952,952,952,952,952,958,958,
-};
-
-#if UCD_BLOCK_SIZE != 128
-#error Please correct UCD_BLOCK_SIZE in pcre2_internal.h
-#endif
-#endif /* SUPPORT_UNICODE */
-
-#endif /* PCRE2_PCRE2TEST */
-
-/* End of pcre2_ucd.c */
diff --git a/contrib/libs/pcre2/src/pcre2_ucp.h b/contrib/libs/pcre2/src/pcre2_ucp.h
deleted file mode 100644
index 282238982d..0000000000
--- a/contrib/libs/pcre2/src/pcre2_ucp.h
+++ /dev/null
@@ -1,394 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2022 University of Cambridge
-
-This module is auto-generated from Unicode data files. DO NOT EDIT MANUALLY!
-Instead, modify the maint/GenerateUcpHeader.py script and run it to generate
-a new version of this code.
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-#ifndef PCRE2_UCP_H_IDEMPOTENT_GUARD
-#define PCRE2_UCP_H_IDEMPOTENT_GUARD
-
-/* This file contains definitions of the Unicode property values that are
-returned by the UCD access macros and used throughout PCRE2.
-
-IMPORTANT: The specific values of the first two enums (general and particular
-character categories) are assumed by the table called catposstab in the file
-pcre2_auto_possess.c. They are unlikely to change, but should be checked after
-an update. */
-
-/* These are the general character categories. */
-
-enum {
- ucp_C,
- ucp_L,
- ucp_M,
- ucp_N,
- ucp_P,
- ucp_S,
- ucp_Z,
-};
-
-/* These are the particular character categories. */
-
-enum {
- ucp_Cc, /* Control */
- ucp_Cf, /* Format */
- ucp_Cn, /* Unassigned */
- ucp_Co, /* Private use */
- ucp_Cs, /* Surrogate */
- ucp_Ll, /* Lower case letter */
- ucp_Lm, /* Modifier letter */
- ucp_Lo, /* Other letter */
- ucp_Lt, /* Title case letter */
- ucp_Lu, /* Upper case letter */
- ucp_Mc, /* Spacing mark */
- ucp_Me, /* Enclosing mark */
- ucp_Mn, /* Non-spacing mark */
- ucp_Nd, /* Decimal number */
- ucp_Nl, /* Letter number */
- ucp_No, /* Other number */
- ucp_Pc, /* Connector punctuation */
- ucp_Pd, /* Dash punctuation */
- ucp_Pe, /* Close punctuation */
- ucp_Pf, /* Final punctuation */
- ucp_Pi, /* Initial punctuation */
- ucp_Po, /* Other punctuation */
- ucp_Ps, /* Open punctuation */
- ucp_Sc, /* Currency symbol */
- ucp_Sk, /* Modifier symbol */
- ucp_Sm, /* Mathematical symbol */
- ucp_So, /* Other symbol */
- ucp_Zl, /* Line separator */
- ucp_Zp, /* Paragraph separator */
- ucp_Zs, /* Space separator */
-};
-
-/* These are Boolean properties. */
-
-enum {
- ucp_ASCII,
- ucp_ASCII_Hex_Digit,
- ucp_Alphabetic,
- ucp_Bidi_Control,
- ucp_Bidi_Mirrored,
- ucp_Case_Ignorable,
- ucp_Cased,
- ucp_Changes_When_Casefolded,
- ucp_Changes_When_Casemapped,
- ucp_Changes_When_Lowercased,
- ucp_Changes_When_Titlecased,
- ucp_Changes_When_Uppercased,
- ucp_Dash,
- ucp_Default_Ignorable_Code_Point,
- ucp_Deprecated,
- ucp_Diacritic,
- ucp_Emoji,
- ucp_Emoji_Component,
- ucp_Emoji_Modifier,
- ucp_Emoji_Modifier_Base,
- ucp_Emoji_Presentation,
- ucp_Extended_Pictographic,
- ucp_Extender,
- ucp_Grapheme_Base,
- ucp_Grapheme_Extend,
- ucp_Grapheme_Link,
- ucp_Hex_Digit,
- ucp_IDS_Binary_Operator,
- ucp_IDS_Trinary_Operator,
- ucp_ID_Continue,
- ucp_ID_Start,
- ucp_Ideographic,
- ucp_Join_Control,
- ucp_Logical_Order_Exception,
- ucp_Lowercase,
- ucp_Math,
- ucp_Noncharacter_Code_Point,
- ucp_Pattern_Syntax,
- ucp_Pattern_White_Space,
- ucp_Prepended_Concatenation_Mark,
- ucp_Quotation_Mark,
- ucp_Radical,
- ucp_Regional_Indicator,
- ucp_Sentence_Terminal,
- ucp_Soft_Dotted,
- ucp_Terminal_Punctuation,
- ucp_Unified_Ideograph,
- ucp_Uppercase,
- ucp_Variation_Selector,
- ucp_White_Space,
- ucp_XID_Continue,
- ucp_XID_Start,
- /* This must be last */
- ucp_Bprop_Count
-};
-
-/* Size of entries in ucd_boolprop_sets[] */
-
-#define ucd_boolprop_sets_item_size 2
-
-/* These are the bidi class values. */
-
-enum {
- ucp_bidiAL, /* Arabic letter */
- ucp_bidiAN, /* Arabic number */
- ucp_bidiB, /* Paragraph separator */
- ucp_bidiBN, /* Boundary neutral */
- ucp_bidiCS, /* Common separator */
- ucp_bidiEN, /* European number */
- ucp_bidiES, /* European separator */
- ucp_bidiET, /* European terminator */
- ucp_bidiFSI, /* First strong isolate */
- ucp_bidiL, /* Left to right */
- ucp_bidiLRE, /* Left to right embedding */
- ucp_bidiLRI, /* Left to right isolate */
- ucp_bidiLRO, /* Left to right override */
- ucp_bidiNSM, /* Non-spacing mark */
- ucp_bidiON, /* Other neutral */
- ucp_bidiPDF, /* Pop directional format */
- ucp_bidiPDI, /* Pop directional isolate */
- ucp_bidiR, /* Right to left */
- ucp_bidiRLE, /* Right to left embedding */
- ucp_bidiRLI, /* Right to left isolate */
- ucp_bidiRLO, /* Right to left override */
- ucp_bidiS, /* Segment separator */
- ucp_bidiWS, /* White space */
-};
-
-/* These are grapheme break properties. The Extended Pictographic property
-comes from the emoji-data.txt file. */
-
-enum {
- ucp_gbCR, /* 0 */
- ucp_gbLF, /* 1 */
- ucp_gbControl, /* 2 */
- ucp_gbExtend, /* 3 */
- ucp_gbPrepend, /* 4 */
- ucp_gbSpacingMark, /* 5 */
- ucp_gbL, /* 6 Hangul syllable type L */
- ucp_gbV, /* 7 Hangul syllable type V */
- ucp_gbT, /* 8 Hangul syllable type T */
- ucp_gbLV, /* 9 Hangul syllable type LV */
- ucp_gbLVT, /* 10 Hangul syllable type LVT */
- ucp_gbRegional_Indicator, /* 11 */
- ucp_gbOther, /* 12 */
- ucp_gbZWJ, /* 13 */
- ucp_gbExtended_Pictographic, /* 14 */
-};
-
-/* These are the script identifications. */
-
-enum {
- /* Scripts which has characters in other scripts. */
- ucp_Latin,
- ucp_Greek,
- ucp_Cyrillic,
- ucp_Arabic,
- ucp_Syriac,
- ucp_Thaana,
- ucp_Devanagari,
- ucp_Bengali,
- ucp_Gurmukhi,
- ucp_Gujarati,
- ucp_Oriya,
- ucp_Tamil,
- ucp_Telugu,
- ucp_Kannada,
- ucp_Malayalam,
- ucp_Sinhala,
- ucp_Myanmar,
- ucp_Georgian,
- ucp_Hangul,
- ucp_Mongolian,
- ucp_Hiragana,
- ucp_Katakana,
- ucp_Bopomofo,
- ucp_Han,
- ucp_Yi,
- ucp_Tagalog,
- ucp_Hanunoo,
- ucp_Buhid,
- ucp_Tagbanwa,
- ucp_Limbu,
- ucp_Tai_Le,
- ucp_Linear_B,
- ucp_Cypriot,
- ucp_Buginese,
- ucp_Coptic,
- ucp_Glagolitic,
- ucp_Syloti_Nagri,
- ucp_Phags_Pa,
- ucp_Nko,
- ucp_Kayah_Li,
- ucp_Javanese,
- ucp_Kaithi,
- ucp_Mandaic,
- ucp_Chakma,
- ucp_Sharada,
- ucp_Takri,
- ucp_Duployan,
- ucp_Grantha,
- ucp_Khojki,
- ucp_Linear_A,
- ucp_Mahajani,
- ucp_Manichaean,
- ucp_Modi,
- ucp_Old_Permic,
- ucp_Psalter_Pahlavi,
- ucp_Khudawadi,
- ucp_Tirhuta,
- ucp_Multani,
- ucp_Adlam,
- ucp_Masaram_Gondi,
- ucp_Dogra,
- ucp_Gunjala_Gondi,
- ucp_Hanifi_Rohingya,
- ucp_Sogdian,
- ucp_Nandinagari,
- ucp_Yezidi,
- ucp_Cypro_Minoan,
- ucp_Old_Uyghur,
-
- /* Scripts which has no characters in other scripts. */
- ucp_Unknown,
- ucp_Common,
- ucp_Armenian,
- ucp_Hebrew,
- ucp_Thai,
- ucp_Lao,
- ucp_Tibetan,
- ucp_Ethiopic,
- ucp_Cherokee,
- ucp_Canadian_Aboriginal,
- ucp_Ogham,
- ucp_Runic,
- ucp_Khmer,
- ucp_Old_Italic,
- ucp_Gothic,
- ucp_Deseret,
- ucp_Inherited,
- ucp_Ugaritic,
- ucp_Shavian,
- ucp_Osmanya,
- ucp_Braille,
- ucp_New_Tai_Lue,
- ucp_Tifinagh,
- ucp_Old_Persian,
- ucp_Kharoshthi,
- ucp_Balinese,
- ucp_Cuneiform,
- ucp_Phoenician,
- ucp_Sundanese,
- ucp_Lepcha,
- ucp_Ol_Chiki,
- ucp_Vai,
- ucp_Saurashtra,
- ucp_Rejang,
- ucp_Lycian,
- ucp_Carian,
- ucp_Lydian,
- ucp_Cham,
- ucp_Tai_Tham,
- ucp_Tai_Viet,
- ucp_Avestan,
- ucp_Egyptian_Hieroglyphs,
- ucp_Samaritan,
- ucp_Lisu,
- ucp_Bamum,
- ucp_Meetei_Mayek,
- ucp_Imperial_Aramaic,
- ucp_Old_South_Arabian,
- ucp_Inscriptional_Parthian,
- ucp_Inscriptional_Pahlavi,
- ucp_Old_Turkic,
- ucp_Batak,
- ucp_Brahmi,
- ucp_Meroitic_Cursive,
- ucp_Meroitic_Hieroglyphs,
- ucp_Miao,
- ucp_Sora_Sompeng,
- ucp_Caucasian_Albanian,
- ucp_Bassa_Vah,
- ucp_Elbasan,
- ucp_Pahawh_Hmong,
- ucp_Mende_Kikakui,
- ucp_Mro,
- ucp_Old_North_Arabian,
- ucp_Nabataean,
- ucp_Palmyrene,
- ucp_Pau_Cin_Hau,
- ucp_Siddham,
- ucp_Warang_Citi,
- ucp_Ahom,
- ucp_Anatolian_Hieroglyphs,
- ucp_Hatran,
- ucp_Old_Hungarian,
- ucp_SignWriting,
- ucp_Bhaiksuki,
- ucp_Marchen,
- ucp_Newa,
- ucp_Osage,
- ucp_Tangut,
- ucp_Nushu,
- ucp_Soyombo,
- ucp_Zanabazar_Square,
- ucp_Makasar,
- ucp_Medefaidrin,
- ucp_Old_Sogdian,
- ucp_Elymaic,
- ucp_Nyiakeng_Puachue_Hmong,
- ucp_Wancho,
- ucp_Chorasmian,
- ucp_Dives_Akuru,
- ucp_Khitan_Small_Script,
- ucp_Tangsa,
- ucp_Toto,
- ucp_Vithkuqi,
-
- /* This must be last */
- ucp_Script_Count
-};
-
-/* Size of entries in ucd_script_sets[] */
-
-#define ucd_script_sets_item_size 3
-
-#endif /* PCRE2_UCP_H_IDEMPOTENT_GUARD */
-
-/* End of pcre2_ucp.h */
diff --git a/contrib/libs/pcre2/src/pcre2_ucptables.c b/contrib/libs/pcre2/src/pcre2_ucptables.c
deleted file mode 100644
index bd1b67a9f1..0000000000
--- a/contrib/libs/pcre2/src/pcre2_ucptables.c
+++ /dev/null
@@ -1,1524 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2022 University of Cambridge
-
-This module is auto-generated from Unicode data files. DO NOT EDIT MANUALLY!
-Instead, modify the maint/GenerateUcpTables.py script and run it to generate
-a new version of this code.
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-#ifdef SUPPORT_UNICODE
-
-/* The PRIV(utt)[] table below translates Unicode property names into type and
-code values. It is searched by binary chop, so must be in collating sequence of
-name. Originally, the table contained pointers to the name strings in the first
-field of each entry. However, that leads to a large number of relocations when
-a shared library is dynamically loaded. A significant reduction is made by
-putting all the names into a single, large string and using offsets instead.
-All letters are lower cased, and underscores are removed, in accordance with
-the "loose matching" rules that Unicode advises and Perl uses. */
-
-#define STRING_adlam0 STR_a STR_d STR_l STR_a STR_m "\0"
-#define STRING_adlm0 STR_a STR_d STR_l STR_m "\0"
-#define STRING_aghb0 STR_a STR_g STR_h STR_b "\0"
-#define STRING_ahex0 STR_a STR_h STR_e STR_x "\0"
-#define STRING_ahom0 STR_a STR_h STR_o STR_m "\0"
-#define STRING_alpha0 STR_a STR_l STR_p STR_h STR_a "\0"
-#define STRING_alphabetic0 STR_a STR_l STR_p STR_h STR_a STR_b STR_e STR_t STR_i STR_c "\0"
-#define STRING_anatolianhieroglyphs0 STR_a STR_n STR_a STR_t STR_o STR_l STR_i STR_a STR_n STR_h STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0"
-#define STRING_any0 STR_a STR_n STR_y "\0"
-#define STRING_arab0 STR_a STR_r STR_a STR_b "\0"
-#define STRING_arabic0 STR_a STR_r STR_a STR_b STR_i STR_c "\0"
-#define STRING_armenian0 STR_a STR_r STR_m STR_e STR_n STR_i STR_a STR_n "\0"
-#define STRING_armi0 STR_a STR_r STR_m STR_i "\0"
-#define STRING_armn0 STR_a STR_r STR_m STR_n "\0"
-#define STRING_ascii0 STR_a STR_s STR_c STR_i STR_i "\0"
-#define STRING_asciihexdigit0 STR_a STR_s STR_c STR_i STR_i STR_h STR_e STR_x STR_d STR_i STR_g STR_i STR_t "\0"
-#define STRING_avestan0 STR_a STR_v STR_e STR_s STR_t STR_a STR_n "\0"
-#define STRING_avst0 STR_a STR_v STR_s STR_t "\0"
-#define STRING_bali0 STR_b STR_a STR_l STR_i "\0"
-#define STRING_balinese0 STR_b STR_a STR_l STR_i STR_n STR_e STR_s STR_e "\0"
-#define STRING_bamu0 STR_b STR_a STR_m STR_u "\0"
-#define STRING_bamum0 STR_b STR_a STR_m STR_u STR_m "\0"
-#define STRING_bass0 STR_b STR_a STR_s STR_s "\0"
-#define STRING_bassavah0 STR_b STR_a STR_s STR_s STR_a STR_v STR_a STR_h "\0"
-#define STRING_batak0 STR_b STR_a STR_t STR_a STR_k "\0"
-#define STRING_batk0 STR_b STR_a STR_t STR_k "\0"
-#define STRING_beng0 STR_b STR_e STR_n STR_g "\0"
-#define STRING_bengali0 STR_b STR_e STR_n STR_g STR_a STR_l STR_i "\0"
-#define STRING_bhaiksuki0 STR_b STR_h STR_a STR_i STR_k STR_s STR_u STR_k STR_i "\0"
-#define STRING_bhks0 STR_b STR_h STR_k STR_s "\0"
-#define STRING_bidial0 STR_b STR_i STR_d STR_i STR_a STR_l "\0"
-#define STRING_bidian0 STR_b STR_i STR_d STR_i STR_a STR_n "\0"
-#define STRING_bidib0 STR_b STR_i STR_d STR_i STR_b "\0"
-#define STRING_bidibn0 STR_b STR_i STR_d STR_i STR_b STR_n "\0"
-#define STRING_bidic0 STR_b STR_i STR_d STR_i STR_c "\0"
-#define STRING_bidicontrol0 STR_b STR_i STR_d STR_i STR_c STR_o STR_n STR_t STR_r STR_o STR_l "\0"
-#define STRING_bidics0 STR_b STR_i STR_d STR_i STR_c STR_s "\0"
-#define STRING_bidien0 STR_b STR_i STR_d STR_i STR_e STR_n "\0"
-#define STRING_bidies0 STR_b STR_i STR_d STR_i STR_e STR_s "\0"
-#define STRING_bidiet0 STR_b STR_i STR_d STR_i STR_e STR_t "\0"
-#define STRING_bidifsi0 STR_b STR_i STR_d STR_i STR_f STR_s STR_i "\0"
-#define STRING_bidil0 STR_b STR_i STR_d STR_i STR_l "\0"
-#define STRING_bidilre0 STR_b STR_i STR_d STR_i STR_l STR_r STR_e "\0"
-#define STRING_bidilri0 STR_b STR_i STR_d STR_i STR_l STR_r STR_i "\0"
-#define STRING_bidilro0 STR_b STR_i STR_d STR_i STR_l STR_r STR_o "\0"
-#define STRING_bidim0 STR_b STR_i STR_d STR_i STR_m "\0"
-#define STRING_bidimirrored0 STR_b STR_i STR_d STR_i STR_m STR_i STR_r STR_r STR_o STR_r STR_e STR_d "\0"
-#define STRING_bidinsm0 STR_b STR_i STR_d STR_i STR_n STR_s STR_m "\0"
-#define STRING_bidion0 STR_b STR_i STR_d STR_i STR_o STR_n "\0"
-#define STRING_bidipdf0 STR_b STR_i STR_d STR_i STR_p STR_d STR_f "\0"
-#define STRING_bidipdi0 STR_b STR_i STR_d STR_i STR_p STR_d STR_i "\0"
-#define STRING_bidir0 STR_b STR_i STR_d STR_i STR_r "\0"
-#define STRING_bidirle0 STR_b STR_i STR_d STR_i STR_r STR_l STR_e "\0"
-#define STRING_bidirli0 STR_b STR_i STR_d STR_i STR_r STR_l STR_i "\0"
-#define STRING_bidirlo0 STR_b STR_i STR_d STR_i STR_r STR_l STR_o "\0"
-#define STRING_bidis0 STR_b STR_i STR_d STR_i STR_s "\0"
-#define STRING_bidiws0 STR_b STR_i STR_d STR_i STR_w STR_s "\0"
-#define STRING_bopo0 STR_b STR_o STR_p STR_o "\0"
-#define STRING_bopomofo0 STR_b STR_o STR_p STR_o STR_m STR_o STR_f STR_o "\0"
-#define STRING_brah0 STR_b STR_r STR_a STR_h "\0"
-#define STRING_brahmi0 STR_b STR_r STR_a STR_h STR_m STR_i "\0"
-#define STRING_brai0 STR_b STR_r STR_a STR_i "\0"
-#define STRING_braille0 STR_b STR_r STR_a STR_i STR_l STR_l STR_e "\0"
-#define STRING_bugi0 STR_b STR_u STR_g STR_i "\0"
-#define STRING_buginese0 STR_b STR_u STR_g STR_i STR_n STR_e STR_s STR_e "\0"
-#define STRING_buhd0 STR_b STR_u STR_h STR_d "\0"
-#define STRING_buhid0 STR_b STR_u STR_h STR_i STR_d "\0"
-#define STRING_c0 STR_c "\0"
-#define STRING_cakm0 STR_c STR_a STR_k STR_m "\0"
-#define STRING_canadianaboriginal0 STR_c STR_a STR_n STR_a STR_d STR_i STR_a STR_n STR_a STR_b STR_o STR_r STR_i STR_g STR_i STR_n STR_a STR_l "\0"
-#define STRING_cans0 STR_c STR_a STR_n STR_s "\0"
-#define STRING_cari0 STR_c STR_a STR_r STR_i "\0"
-#define STRING_carian0 STR_c STR_a STR_r STR_i STR_a STR_n "\0"
-#define STRING_cased0 STR_c STR_a STR_s STR_e STR_d "\0"
-#define STRING_caseignorable0 STR_c STR_a STR_s STR_e STR_i STR_g STR_n STR_o STR_r STR_a STR_b STR_l STR_e "\0"
-#define STRING_caucasianalbanian0 STR_c STR_a STR_u STR_c STR_a STR_s STR_i STR_a STR_n STR_a STR_l STR_b STR_a STR_n STR_i STR_a STR_n "\0"
-#define STRING_cc0 STR_c STR_c "\0"
-#define STRING_cf0 STR_c STR_f "\0"
-#define STRING_chakma0 STR_c STR_h STR_a STR_k STR_m STR_a "\0"
-#define STRING_cham0 STR_c STR_h STR_a STR_m "\0"
-#define STRING_changeswhencasefolded0 STR_c STR_h STR_a STR_n STR_g STR_e STR_s STR_w STR_h STR_e STR_n STR_c STR_a STR_s STR_e STR_f STR_o STR_l STR_d STR_e STR_d "\0"
-#define STRING_changeswhencasemapped0 STR_c STR_h STR_a STR_n STR_g STR_e STR_s STR_w STR_h STR_e STR_n STR_c STR_a STR_s STR_e STR_m STR_a STR_p STR_p STR_e STR_d "\0"
-#define STRING_changeswhenlowercased0 STR_c STR_h STR_a STR_n STR_g STR_e STR_s STR_w STR_h STR_e STR_n STR_l STR_o STR_w STR_e STR_r STR_c STR_a STR_s STR_e STR_d "\0"
-#define STRING_changeswhentitlecased0 STR_c STR_h STR_a STR_n STR_g STR_e STR_s STR_w STR_h STR_e STR_n STR_t STR_i STR_t STR_l STR_e STR_c STR_a STR_s STR_e STR_d "\0"
-#define STRING_changeswhenuppercased0 STR_c STR_h STR_a STR_n STR_g STR_e STR_s STR_w STR_h STR_e STR_n STR_u STR_p STR_p STR_e STR_r STR_c STR_a STR_s STR_e STR_d "\0"
-#define STRING_cher0 STR_c STR_h STR_e STR_r "\0"
-#define STRING_cherokee0 STR_c STR_h STR_e STR_r STR_o STR_k STR_e STR_e "\0"
-#define STRING_chorasmian0 STR_c STR_h STR_o STR_r STR_a STR_s STR_m STR_i STR_a STR_n "\0"
-#define STRING_chrs0 STR_c STR_h STR_r STR_s "\0"
-#define STRING_ci0 STR_c STR_i "\0"
-#define STRING_cn0 STR_c STR_n "\0"
-#define STRING_co0 STR_c STR_o "\0"
-#define STRING_common0 STR_c STR_o STR_m STR_m STR_o STR_n "\0"
-#define STRING_copt0 STR_c STR_o STR_p STR_t "\0"
-#define STRING_coptic0 STR_c STR_o STR_p STR_t STR_i STR_c "\0"
-#define STRING_cpmn0 STR_c STR_p STR_m STR_n "\0"
-#define STRING_cprt0 STR_c STR_p STR_r STR_t "\0"
-#define STRING_cs0 STR_c STR_s "\0"
-#define STRING_cuneiform0 STR_c STR_u STR_n STR_e STR_i STR_f STR_o STR_r STR_m "\0"
-#define STRING_cwcf0 STR_c STR_w STR_c STR_f "\0"
-#define STRING_cwcm0 STR_c STR_w STR_c STR_m "\0"
-#define STRING_cwl0 STR_c STR_w STR_l "\0"
-#define STRING_cwt0 STR_c STR_w STR_t "\0"
-#define STRING_cwu0 STR_c STR_w STR_u "\0"
-#define STRING_cypriot0 STR_c STR_y STR_p STR_r STR_i STR_o STR_t "\0"
-#define STRING_cyprominoan0 STR_c STR_y STR_p STR_r STR_o STR_m STR_i STR_n STR_o STR_a STR_n "\0"
-#define STRING_cyrillic0 STR_c STR_y STR_r STR_i STR_l STR_l STR_i STR_c "\0"
-#define STRING_cyrl0 STR_c STR_y STR_r STR_l "\0"
-#define STRING_dash0 STR_d STR_a STR_s STR_h "\0"
-#define STRING_defaultignorablecodepoint0 STR_d STR_e STR_f STR_a STR_u STR_l STR_t STR_i STR_g STR_n STR_o STR_r STR_a STR_b STR_l STR_e STR_c STR_o STR_d STR_e STR_p STR_o STR_i STR_n STR_t "\0"
-#define STRING_dep0 STR_d STR_e STR_p "\0"
-#define STRING_deprecated0 STR_d STR_e STR_p STR_r STR_e STR_c STR_a STR_t STR_e STR_d "\0"
-#define STRING_deseret0 STR_d STR_e STR_s STR_e STR_r STR_e STR_t "\0"
-#define STRING_deva0 STR_d STR_e STR_v STR_a "\0"
-#define STRING_devanagari0 STR_d STR_e STR_v STR_a STR_n STR_a STR_g STR_a STR_r STR_i "\0"
-#define STRING_di0 STR_d STR_i "\0"
-#define STRING_dia0 STR_d STR_i STR_a "\0"
-#define STRING_diacritic0 STR_d STR_i STR_a STR_c STR_r STR_i STR_t STR_i STR_c "\0"
-#define STRING_diak0 STR_d STR_i STR_a STR_k "\0"
-#define STRING_divesakuru0 STR_d STR_i STR_v STR_e STR_s STR_a STR_k STR_u STR_r STR_u "\0"
-#define STRING_dogr0 STR_d STR_o STR_g STR_r "\0"
-#define STRING_dogra0 STR_d STR_o STR_g STR_r STR_a "\0"
-#define STRING_dsrt0 STR_d STR_s STR_r STR_t "\0"
-#define STRING_dupl0 STR_d STR_u STR_p STR_l "\0"
-#define STRING_duployan0 STR_d STR_u STR_p STR_l STR_o STR_y STR_a STR_n "\0"
-#define STRING_ebase0 STR_e STR_b STR_a STR_s STR_e "\0"
-#define STRING_ecomp0 STR_e STR_c STR_o STR_m STR_p "\0"
-#define STRING_egyp0 STR_e STR_g STR_y STR_p "\0"
-#define STRING_egyptianhieroglyphs0 STR_e STR_g STR_y STR_p STR_t STR_i STR_a STR_n STR_h STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0"
-#define STRING_elba0 STR_e STR_l STR_b STR_a "\0"
-#define STRING_elbasan0 STR_e STR_l STR_b STR_a STR_s STR_a STR_n "\0"
-#define STRING_elym0 STR_e STR_l STR_y STR_m "\0"
-#define STRING_elymaic0 STR_e STR_l STR_y STR_m STR_a STR_i STR_c "\0"
-#define STRING_emod0 STR_e STR_m STR_o STR_d "\0"
-#define STRING_emoji0 STR_e STR_m STR_o STR_j STR_i "\0"
-#define STRING_emojicomponent0 STR_e STR_m STR_o STR_j STR_i STR_c STR_o STR_m STR_p STR_o STR_n STR_e STR_n STR_t "\0"
-#define STRING_emojimodifier0 STR_e STR_m STR_o STR_j STR_i STR_m STR_o STR_d STR_i STR_f STR_i STR_e STR_r "\0"
-#define STRING_emojimodifierbase0 STR_e STR_m STR_o STR_j STR_i STR_m STR_o STR_d STR_i STR_f STR_i STR_e STR_r STR_b STR_a STR_s STR_e "\0"
-#define STRING_emojipresentation0 STR_e STR_m STR_o STR_j STR_i STR_p STR_r STR_e STR_s STR_e STR_n STR_t STR_a STR_t STR_i STR_o STR_n "\0"
-#define STRING_epres0 STR_e STR_p STR_r STR_e STR_s "\0"
-#define STRING_ethi0 STR_e STR_t STR_h STR_i "\0"
-#define STRING_ethiopic0 STR_e STR_t STR_h STR_i STR_o STR_p STR_i STR_c "\0"
-#define STRING_ext0 STR_e STR_x STR_t "\0"
-#define STRING_extendedpictographic0 STR_e STR_x STR_t STR_e STR_n STR_d STR_e STR_d STR_p STR_i STR_c STR_t STR_o STR_g STR_r STR_a STR_p STR_h STR_i STR_c "\0"
-#define STRING_extender0 STR_e STR_x STR_t STR_e STR_n STR_d STR_e STR_r "\0"
-#define STRING_extpict0 STR_e STR_x STR_t STR_p STR_i STR_c STR_t "\0"
-#define STRING_geor0 STR_g STR_e STR_o STR_r "\0"
-#define STRING_georgian0 STR_g STR_e STR_o STR_r STR_g STR_i STR_a STR_n "\0"
-#define STRING_glag0 STR_g STR_l STR_a STR_g "\0"
-#define STRING_glagolitic0 STR_g STR_l STR_a STR_g STR_o STR_l STR_i STR_t STR_i STR_c "\0"
-#define STRING_gong0 STR_g STR_o STR_n STR_g "\0"
-#define STRING_gonm0 STR_g STR_o STR_n STR_m "\0"
-#define STRING_goth0 STR_g STR_o STR_t STR_h "\0"
-#define STRING_gothic0 STR_g STR_o STR_t STR_h STR_i STR_c "\0"
-#define STRING_gran0 STR_g STR_r STR_a STR_n "\0"
-#define STRING_grantha0 STR_g STR_r STR_a STR_n STR_t STR_h STR_a "\0"
-#define STRING_graphemebase0 STR_g STR_r STR_a STR_p STR_h STR_e STR_m STR_e STR_b STR_a STR_s STR_e "\0"
-#define STRING_graphemeextend0 STR_g STR_r STR_a STR_p STR_h STR_e STR_m STR_e STR_e STR_x STR_t STR_e STR_n STR_d "\0"
-#define STRING_graphemelink0 STR_g STR_r STR_a STR_p STR_h STR_e STR_m STR_e STR_l STR_i STR_n STR_k "\0"
-#define STRING_grbase0 STR_g STR_r STR_b STR_a STR_s STR_e "\0"
-#define STRING_greek0 STR_g STR_r STR_e STR_e STR_k "\0"
-#define STRING_grek0 STR_g STR_r STR_e STR_k "\0"
-#define STRING_grext0 STR_g STR_r STR_e STR_x STR_t "\0"
-#define STRING_grlink0 STR_g STR_r STR_l STR_i STR_n STR_k "\0"
-#define STRING_gujarati0 STR_g STR_u STR_j STR_a STR_r STR_a STR_t STR_i "\0"
-#define STRING_gujr0 STR_g STR_u STR_j STR_r "\0"
-#define STRING_gunjalagondi0 STR_g STR_u STR_n STR_j STR_a STR_l STR_a STR_g STR_o STR_n STR_d STR_i "\0"
-#define STRING_gurmukhi0 STR_g STR_u STR_r STR_m STR_u STR_k STR_h STR_i "\0"
-#define STRING_guru0 STR_g STR_u STR_r STR_u "\0"
-#define STRING_han0 STR_h STR_a STR_n "\0"
-#define STRING_hang0 STR_h STR_a STR_n STR_g "\0"
-#define STRING_hangul0 STR_h STR_a STR_n STR_g STR_u STR_l "\0"
-#define STRING_hani0 STR_h STR_a STR_n STR_i "\0"
-#define STRING_hanifirohingya0 STR_h STR_a STR_n STR_i STR_f STR_i STR_r STR_o STR_h STR_i STR_n STR_g STR_y STR_a "\0"
-#define STRING_hano0 STR_h STR_a STR_n STR_o "\0"
-#define STRING_hanunoo0 STR_h STR_a STR_n STR_u STR_n STR_o STR_o "\0"
-#define STRING_hatr0 STR_h STR_a STR_t STR_r "\0"
-#define STRING_hatran0 STR_h STR_a STR_t STR_r STR_a STR_n "\0"
-#define STRING_hebr0 STR_h STR_e STR_b STR_r "\0"
-#define STRING_hebrew0 STR_h STR_e STR_b STR_r STR_e STR_w "\0"
-#define STRING_hex0 STR_h STR_e STR_x "\0"
-#define STRING_hexdigit0 STR_h STR_e STR_x STR_d STR_i STR_g STR_i STR_t "\0"
-#define STRING_hira0 STR_h STR_i STR_r STR_a "\0"
-#define STRING_hiragana0 STR_h STR_i STR_r STR_a STR_g STR_a STR_n STR_a "\0"
-#define STRING_hluw0 STR_h STR_l STR_u STR_w "\0"
-#define STRING_hmng0 STR_h STR_m STR_n STR_g "\0"
-#define STRING_hmnp0 STR_h STR_m STR_n STR_p "\0"
-#define STRING_hung0 STR_h STR_u STR_n STR_g "\0"
-#define STRING_idc0 STR_i STR_d STR_c "\0"
-#define STRING_idcontinue0 STR_i STR_d STR_c STR_o STR_n STR_t STR_i STR_n STR_u STR_e "\0"
-#define STRING_ideo0 STR_i STR_d STR_e STR_o "\0"
-#define STRING_ideographic0 STR_i STR_d STR_e STR_o STR_g STR_r STR_a STR_p STR_h STR_i STR_c "\0"
-#define STRING_ids0 STR_i STR_d STR_s "\0"
-#define STRING_idsb0 STR_i STR_d STR_s STR_b "\0"
-#define STRING_idsbinaryoperator0 STR_i STR_d STR_s STR_b STR_i STR_n STR_a STR_r STR_y STR_o STR_p STR_e STR_r STR_a STR_t STR_o STR_r "\0"
-#define STRING_idst0 STR_i STR_d STR_s STR_t "\0"
-#define STRING_idstart0 STR_i STR_d STR_s STR_t STR_a STR_r STR_t "\0"
-#define STRING_idstrinaryoperator0 STR_i STR_d STR_s STR_t STR_r STR_i STR_n STR_a STR_r STR_y STR_o STR_p STR_e STR_r STR_a STR_t STR_o STR_r "\0"
-#define STRING_imperialaramaic0 STR_i STR_m STR_p STR_e STR_r STR_i STR_a STR_l STR_a STR_r STR_a STR_m STR_a STR_i STR_c "\0"
-#define STRING_inherited0 STR_i STR_n STR_h STR_e STR_r STR_i STR_t STR_e STR_d "\0"
-#define STRING_inscriptionalpahlavi0 STR_i STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_p STR_a STR_h STR_l STR_a STR_v STR_i "\0"
-#define STRING_inscriptionalparthian0 STR_i STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_p STR_a STR_r STR_t STR_h STR_i STR_a STR_n "\0"
-#define STRING_ital0 STR_i STR_t STR_a STR_l "\0"
-#define STRING_java0 STR_j STR_a STR_v STR_a "\0"
-#define STRING_javanese0 STR_j STR_a STR_v STR_a STR_n STR_e STR_s STR_e "\0"
-#define STRING_joinc0 STR_j STR_o STR_i STR_n STR_c "\0"
-#define STRING_joincontrol0 STR_j STR_o STR_i STR_n STR_c STR_o STR_n STR_t STR_r STR_o STR_l "\0"
-#define STRING_kaithi0 STR_k STR_a STR_i STR_t STR_h STR_i "\0"
-#define STRING_kali0 STR_k STR_a STR_l STR_i "\0"
-#define STRING_kana0 STR_k STR_a STR_n STR_a "\0"
-#define STRING_kannada0 STR_k STR_a STR_n STR_n STR_a STR_d STR_a "\0"
-#define STRING_katakana0 STR_k STR_a STR_t STR_a STR_k STR_a STR_n STR_a "\0"
-#define STRING_kayahli0 STR_k STR_a STR_y STR_a STR_h STR_l STR_i "\0"
-#define STRING_khar0 STR_k STR_h STR_a STR_r "\0"
-#define STRING_kharoshthi0 STR_k STR_h STR_a STR_r STR_o STR_s STR_h STR_t STR_h STR_i "\0"
-#define STRING_khitansmallscript0 STR_k STR_h STR_i STR_t STR_a STR_n STR_s STR_m STR_a STR_l STR_l STR_s STR_c STR_r STR_i STR_p STR_t "\0"
-#define STRING_khmer0 STR_k STR_h STR_m STR_e STR_r "\0"
-#define STRING_khmr0 STR_k STR_h STR_m STR_r "\0"
-#define STRING_khoj0 STR_k STR_h STR_o STR_j "\0"
-#define STRING_khojki0 STR_k STR_h STR_o STR_j STR_k STR_i "\0"
-#define STRING_khudawadi0 STR_k STR_h STR_u STR_d STR_a STR_w STR_a STR_d STR_i "\0"
-#define STRING_kits0 STR_k STR_i STR_t STR_s "\0"
-#define STRING_knda0 STR_k STR_n STR_d STR_a "\0"
-#define STRING_kthi0 STR_k STR_t STR_h STR_i "\0"
-#define STRING_l0 STR_l "\0"
-#define STRING_l_AMPERSAND0 STR_l STR_AMPERSAND "\0"
-#define STRING_lana0 STR_l STR_a STR_n STR_a "\0"
-#define STRING_lao0 STR_l STR_a STR_o "\0"
-#define STRING_laoo0 STR_l STR_a STR_o STR_o "\0"
-#define STRING_latin0 STR_l STR_a STR_t STR_i STR_n "\0"
-#define STRING_latn0 STR_l STR_a STR_t STR_n "\0"
-#define STRING_lc0 STR_l STR_c "\0"
-#define STRING_lepc0 STR_l STR_e STR_p STR_c "\0"
-#define STRING_lepcha0 STR_l STR_e STR_p STR_c STR_h STR_a "\0"
-#define STRING_limb0 STR_l STR_i STR_m STR_b "\0"
-#define STRING_limbu0 STR_l STR_i STR_m STR_b STR_u "\0"
-#define STRING_lina0 STR_l STR_i STR_n STR_a "\0"
-#define STRING_linb0 STR_l STR_i STR_n STR_b "\0"
-#define STRING_lineara0 STR_l STR_i STR_n STR_e STR_a STR_r STR_a "\0"
-#define STRING_linearb0 STR_l STR_i STR_n STR_e STR_a STR_r STR_b "\0"
-#define STRING_lisu0 STR_l STR_i STR_s STR_u "\0"
-#define STRING_ll0 STR_l STR_l "\0"
-#define STRING_lm0 STR_l STR_m "\0"
-#define STRING_lo0 STR_l STR_o "\0"
-#define STRING_loe0 STR_l STR_o STR_e "\0"
-#define STRING_logicalorderexception0 STR_l STR_o STR_g STR_i STR_c STR_a STR_l STR_o STR_r STR_d STR_e STR_r STR_e STR_x STR_c STR_e STR_p STR_t STR_i STR_o STR_n "\0"
-#define STRING_lower0 STR_l STR_o STR_w STR_e STR_r "\0"
-#define STRING_lowercase0 STR_l STR_o STR_w STR_e STR_r STR_c STR_a STR_s STR_e "\0"
-#define STRING_lt0 STR_l STR_t "\0"
-#define STRING_lu0 STR_l STR_u "\0"
-#define STRING_lyci0 STR_l STR_y STR_c STR_i "\0"
-#define STRING_lycian0 STR_l STR_y STR_c STR_i STR_a STR_n "\0"
-#define STRING_lydi0 STR_l STR_y STR_d STR_i "\0"
-#define STRING_lydian0 STR_l STR_y STR_d STR_i STR_a STR_n "\0"
-#define STRING_m0 STR_m "\0"
-#define STRING_mahajani0 STR_m STR_a STR_h STR_a STR_j STR_a STR_n STR_i "\0"
-#define STRING_mahj0 STR_m STR_a STR_h STR_j "\0"
-#define STRING_maka0 STR_m STR_a STR_k STR_a "\0"
-#define STRING_makasar0 STR_m STR_a STR_k STR_a STR_s STR_a STR_r "\0"
-#define STRING_malayalam0 STR_m STR_a STR_l STR_a STR_y STR_a STR_l STR_a STR_m "\0"
-#define STRING_mand0 STR_m STR_a STR_n STR_d "\0"
-#define STRING_mandaic0 STR_m STR_a STR_n STR_d STR_a STR_i STR_c "\0"
-#define STRING_mani0 STR_m STR_a STR_n STR_i "\0"
-#define STRING_manichaean0 STR_m STR_a STR_n STR_i STR_c STR_h STR_a STR_e STR_a STR_n "\0"
-#define STRING_marc0 STR_m STR_a STR_r STR_c "\0"
-#define STRING_marchen0 STR_m STR_a STR_r STR_c STR_h STR_e STR_n "\0"
-#define STRING_masaramgondi0 STR_m STR_a STR_s STR_a STR_r STR_a STR_m STR_g STR_o STR_n STR_d STR_i "\0"
-#define STRING_math0 STR_m STR_a STR_t STR_h "\0"
-#define STRING_mc0 STR_m STR_c "\0"
-#define STRING_me0 STR_m STR_e "\0"
-#define STRING_medefaidrin0 STR_m STR_e STR_d STR_e STR_f STR_a STR_i STR_d STR_r STR_i STR_n "\0"
-#define STRING_medf0 STR_m STR_e STR_d STR_f "\0"
-#define STRING_meeteimayek0 STR_m STR_e STR_e STR_t STR_e STR_i STR_m STR_a STR_y STR_e STR_k "\0"
-#define STRING_mend0 STR_m STR_e STR_n STR_d "\0"
-#define STRING_mendekikakui0 STR_m STR_e STR_n STR_d STR_e STR_k STR_i STR_k STR_a STR_k STR_u STR_i "\0"
-#define STRING_merc0 STR_m STR_e STR_r STR_c "\0"
-#define STRING_mero0 STR_m STR_e STR_r STR_o "\0"
-#define STRING_meroiticcursive0 STR_m STR_e STR_r STR_o STR_i STR_t STR_i STR_c STR_c STR_u STR_r STR_s STR_i STR_v STR_e "\0"
-#define STRING_meroitichieroglyphs0 STR_m STR_e STR_r STR_o STR_i STR_t STR_i STR_c STR_h STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0"
-#define STRING_miao0 STR_m STR_i STR_a STR_o "\0"
-#define STRING_mlym0 STR_m STR_l STR_y STR_m "\0"
-#define STRING_mn0 STR_m STR_n "\0"
-#define STRING_modi0 STR_m STR_o STR_d STR_i "\0"
-#define STRING_mong0 STR_m STR_o STR_n STR_g "\0"
-#define STRING_mongolian0 STR_m STR_o STR_n STR_g STR_o STR_l STR_i STR_a STR_n "\0"
-#define STRING_mro0 STR_m STR_r STR_o "\0"
-#define STRING_mroo0 STR_m STR_r STR_o STR_o "\0"
-#define STRING_mtei0 STR_m STR_t STR_e STR_i "\0"
-#define STRING_mult0 STR_m STR_u STR_l STR_t "\0"
-#define STRING_multani0 STR_m STR_u STR_l STR_t STR_a STR_n STR_i "\0"
-#define STRING_myanmar0 STR_m STR_y STR_a STR_n STR_m STR_a STR_r "\0"
-#define STRING_mymr0 STR_m STR_y STR_m STR_r "\0"
-#define STRING_n0 STR_n "\0"
-#define STRING_nabataean0 STR_n STR_a STR_b STR_a STR_t STR_a STR_e STR_a STR_n "\0"
-#define STRING_nand0 STR_n STR_a STR_n STR_d "\0"
-#define STRING_nandinagari0 STR_n STR_a STR_n STR_d STR_i STR_n STR_a STR_g STR_a STR_r STR_i "\0"
-#define STRING_narb0 STR_n STR_a STR_r STR_b "\0"
-#define STRING_nbat0 STR_n STR_b STR_a STR_t "\0"
-#define STRING_nchar0 STR_n STR_c STR_h STR_a STR_r "\0"
-#define STRING_nd0 STR_n STR_d "\0"
-#define STRING_newa0 STR_n STR_e STR_w STR_a "\0"
-#define STRING_newtailue0 STR_n STR_e STR_w STR_t STR_a STR_i STR_l STR_u STR_e "\0"
-#define STRING_nko0 STR_n STR_k STR_o "\0"
-#define STRING_nkoo0 STR_n STR_k STR_o STR_o "\0"
-#define STRING_nl0 STR_n STR_l "\0"
-#define STRING_no0 STR_n STR_o "\0"
-#define STRING_noncharactercodepoint0 STR_n STR_o STR_n STR_c STR_h STR_a STR_r STR_a STR_c STR_t STR_e STR_r STR_c STR_o STR_d STR_e STR_p STR_o STR_i STR_n STR_t "\0"
-#define STRING_nshu0 STR_n STR_s STR_h STR_u "\0"
-#define STRING_nushu0 STR_n STR_u STR_s STR_h STR_u "\0"
-#define STRING_nyiakengpuachuehmong0 STR_n STR_y STR_i STR_a STR_k STR_e STR_n STR_g STR_p STR_u STR_a STR_c STR_h STR_u STR_e STR_h STR_m STR_o STR_n STR_g "\0"
-#define STRING_ogam0 STR_o STR_g STR_a STR_m "\0"
-#define STRING_ogham0 STR_o STR_g STR_h STR_a STR_m "\0"
-#define STRING_olchiki0 STR_o STR_l STR_c STR_h STR_i STR_k STR_i "\0"
-#define STRING_olck0 STR_o STR_l STR_c STR_k "\0"
-#define STRING_oldhungarian0 STR_o STR_l STR_d STR_h STR_u STR_n STR_g STR_a STR_r STR_i STR_a STR_n "\0"
-#define STRING_olditalic0 STR_o STR_l STR_d STR_i STR_t STR_a STR_l STR_i STR_c "\0"
-#define STRING_oldnortharabian0 STR_o STR_l STR_d STR_n STR_o STR_r STR_t STR_h STR_a STR_r STR_a STR_b STR_i STR_a STR_n "\0"
-#define STRING_oldpermic0 STR_o STR_l STR_d STR_p STR_e STR_r STR_m STR_i STR_c "\0"
-#define STRING_oldpersian0 STR_o STR_l STR_d STR_p STR_e STR_r STR_s STR_i STR_a STR_n "\0"
-#define STRING_oldsogdian0 STR_o STR_l STR_d STR_s STR_o STR_g STR_d STR_i STR_a STR_n "\0"
-#define STRING_oldsoutharabian0 STR_o STR_l STR_d STR_s STR_o STR_u STR_t STR_h STR_a STR_r STR_a STR_b STR_i STR_a STR_n "\0"
-#define STRING_oldturkic0 STR_o STR_l STR_d STR_t STR_u STR_r STR_k STR_i STR_c "\0"
-#define STRING_olduyghur0 STR_o STR_l STR_d STR_u STR_y STR_g STR_h STR_u STR_r "\0"
-#define STRING_oriya0 STR_o STR_r STR_i STR_y STR_a "\0"
-#define STRING_orkh0 STR_o STR_r STR_k STR_h "\0"
-#define STRING_orya0 STR_o STR_r STR_y STR_a "\0"
-#define STRING_osage0 STR_o STR_s STR_a STR_g STR_e "\0"
-#define STRING_osge0 STR_o STR_s STR_g STR_e "\0"
-#define STRING_osma0 STR_o STR_s STR_m STR_a "\0"
-#define STRING_osmanya0 STR_o STR_s STR_m STR_a STR_n STR_y STR_a "\0"
-#define STRING_ougr0 STR_o STR_u STR_g STR_r "\0"
-#define STRING_p0 STR_p "\0"
-#define STRING_pahawhhmong0 STR_p STR_a STR_h STR_a STR_w STR_h STR_h STR_m STR_o STR_n STR_g "\0"
-#define STRING_palm0 STR_p STR_a STR_l STR_m "\0"
-#define STRING_palmyrene0 STR_p STR_a STR_l STR_m STR_y STR_r STR_e STR_n STR_e "\0"
-#define STRING_patsyn0 STR_p STR_a STR_t STR_s STR_y STR_n "\0"
-#define STRING_patternsyntax0 STR_p STR_a STR_t STR_t STR_e STR_r STR_n STR_s STR_y STR_n STR_t STR_a STR_x "\0"
-#define STRING_patternwhitespace0 STR_p STR_a STR_t STR_t STR_e STR_r STR_n STR_w STR_h STR_i STR_t STR_e STR_s STR_p STR_a STR_c STR_e "\0"
-#define STRING_patws0 STR_p STR_a STR_t STR_w STR_s "\0"
-#define STRING_pauc0 STR_p STR_a STR_u STR_c "\0"
-#define STRING_paucinhau0 STR_p STR_a STR_u STR_c STR_i STR_n STR_h STR_a STR_u "\0"
-#define STRING_pc0 STR_p STR_c "\0"
-#define STRING_pcm0 STR_p STR_c STR_m "\0"
-#define STRING_pd0 STR_p STR_d "\0"
-#define STRING_pe0 STR_p STR_e "\0"
-#define STRING_perm0 STR_p STR_e STR_r STR_m "\0"
-#define STRING_pf0 STR_p STR_f "\0"
-#define STRING_phag0 STR_p STR_h STR_a STR_g "\0"
-#define STRING_phagspa0 STR_p STR_h STR_a STR_g STR_s STR_p STR_a "\0"
-#define STRING_phli0 STR_p STR_h STR_l STR_i "\0"
-#define STRING_phlp0 STR_p STR_h STR_l STR_p "\0"
-#define STRING_phnx0 STR_p STR_h STR_n STR_x "\0"
-#define STRING_phoenician0 STR_p STR_h STR_o STR_e STR_n STR_i STR_c STR_i STR_a STR_n "\0"
-#define STRING_pi0 STR_p STR_i "\0"
-#define STRING_plrd0 STR_p STR_l STR_r STR_d "\0"
-#define STRING_po0 STR_p STR_o "\0"
-#define STRING_prependedconcatenationmark0 STR_p STR_r STR_e STR_p STR_e STR_n STR_d STR_e STR_d STR_c STR_o STR_n STR_c STR_a STR_t STR_e STR_n STR_a STR_t STR_i STR_o STR_n STR_m STR_a STR_r STR_k "\0"
-#define STRING_prti0 STR_p STR_r STR_t STR_i "\0"
-#define STRING_ps0 STR_p STR_s "\0"
-#define STRING_psalterpahlavi0 STR_p STR_s STR_a STR_l STR_t STR_e STR_r STR_p STR_a STR_h STR_l STR_a STR_v STR_i "\0"
-#define STRING_qaac0 STR_q STR_a STR_a STR_c "\0"
-#define STRING_qaai0 STR_q STR_a STR_a STR_i "\0"
-#define STRING_qmark0 STR_q STR_m STR_a STR_r STR_k "\0"
-#define STRING_quotationmark0 STR_q STR_u STR_o STR_t STR_a STR_t STR_i STR_o STR_n STR_m STR_a STR_r STR_k "\0"
-#define STRING_radical0 STR_r STR_a STR_d STR_i STR_c STR_a STR_l "\0"
-#define STRING_regionalindicator0 STR_r STR_e STR_g STR_i STR_o STR_n STR_a STR_l STR_i STR_n STR_d STR_i STR_c STR_a STR_t STR_o STR_r "\0"
-#define STRING_rejang0 STR_r STR_e STR_j STR_a STR_n STR_g "\0"
-#define STRING_ri0 STR_r STR_i "\0"
-#define STRING_rjng0 STR_r STR_j STR_n STR_g "\0"
-#define STRING_rohg0 STR_r STR_o STR_h STR_g "\0"
-#define STRING_runic0 STR_r STR_u STR_n STR_i STR_c "\0"
-#define STRING_runr0 STR_r STR_u STR_n STR_r "\0"
-#define STRING_s0 STR_s "\0"
-#define STRING_samaritan0 STR_s STR_a STR_m STR_a STR_r STR_i STR_t STR_a STR_n "\0"
-#define STRING_samr0 STR_s STR_a STR_m STR_r "\0"
-#define STRING_sarb0 STR_s STR_a STR_r STR_b "\0"
-#define STRING_saur0 STR_s STR_a STR_u STR_r "\0"
-#define STRING_saurashtra0 STR_s STR_a STR_u STR_r STR_a STR_s STR_h STR_t STR_r STR_a "\0"
-#define STRING_sc0 STR_s STR_c "\0"
-#define STRING_sd0 STR_s STR_d "\0"
-#define STRING_sentenceterminal0 STR_s STR_e STR_n STR_t STR_e STR_n STR_c STR_e STR_t STR_e STR_r STR_m STR_i STR_n STR_a STR_l "\0"
-#define STRING_sgnw0 STR_s STR_g STR_n STR_w "\0"
-#define STRING_sharada0 STR_s STR_h STR_a STR_r STR_a STR_d STR_a "\0"
-#define STRING_shavian0 STR_s STR_h STR_a STR_v STR_i STR_a STR_n "\0"
-#define STRING_shaw0 STR_s STR_h STR_a STR_w "\0"
-#define STRING_shrd0 STR_s STR_h STR_r STR_d "\0"
-#define STRING_sidd0 STR_s STR_i STR_d STR_d "\0"
-#define STRING_siddham0 STR_s STR_i STR_d STR_d STR_h STR_a STR_m "\0"
-#define STRING_signwriting0 STR_s STR_i STR_g STR_n STR_w STR_r STR_i STR_t STR_i STR_n STR_g "\0"
-#define STRING_sind0 STR_s STR_i STR_n STR_d "\0"
-#define STRING_sinh0 STR_s STR_i STR_n STR_h "\0"
-#define STRING_sinhala0 STR_s STR_i STR_n STR_h STR_a STR_l STR_a "\0"
-#define STRING_sk0 STR_s STR_k "\0"
-#define STRING_sm0 STR_s STR_m "\0"
-#define STRING_so0 STR_s STR_o "\0"
-#define STRING_softdotted0 STR_s STR_o STR_f STR_t STR_d STR_o STR_t STR_t STR_e STR_d "\0"
-#define STRING_sogd0 STR_s STR_o STR_g STR_d "\0"
-#define STRING_sogdian0 STR_s STR_o STR_g STR_d STR_i STR_a STR_n "\0"
-#define STRING_sogo0 STR_s STR_o STR_g STR_o "\0"
-#define STRING_sora0 STR_s STR_o STR_r STR_a "\0"
-#define STRING_sorasompeng0 STR_s STR_o STR_r STR_a STR_s STR_o STR_m STR_p STR_e STR_n STR_g "\0"
-#define STRING_soyo0 STR_s STR_o STR_y STR_o "\0"
-#define STRING_soyombo0 STR_s STR_o STR_y STR_o STR_m STR_b STR_o "\0"
-#define STRING_space0 STR_s STR_p STR_a STR_c STR_e "\0"
-#define STRING_sterm0 STR_s STR_t STR_e STR_r STR_m "\0"
-#define STRING_sund0 STR_s STR_u STR_n STR_d "\0"
-#define STRING_sundanese0 STR_s STR_u STR_n STR_d STR_a STR_n STR_e STR_s STR_e "\0"
-#define STRING_sylo0 STR_s STR_y STR_l STR_o "\0"
-#define STRING_sylotinagri0 STR_s STR_y STR_l STR_o STR_t STR_i STR_n STR_a STR_g STR_r STR_i "\0"
-#define STRING_syrc0 STR_s STR_y STR_r STR_c "\0"
-#define STRING_syriac0 STR_s STR_y STR_r STR_i STR_a STR_c "\0"
-#define STRING_tagalog0 STR_t STR_a STR_g STR_a STR_l STR_o STR_g "\0"
-#define STRING_tagb0 STR_t STR_a STR_g STR_b "\0"
-#define STRING_tagbanwa0 STR_t STR_a STR_g STR_b STR_a STR_n STR_w STR_a "\0"
-#define STRING_taile0 STR_t STR_a STR_i STR_l STR_e "\0"
-#define STRING_taitham0 STR_t STR_a STR_i STR_t STR_h STR_a STR_m "\0"
-#define STRING_taiviet0 STR_t STR_a STR_i STR_v STR_i STR_e STR_t "\0"
-#define STRING_takr0 STR_t STR_a STR_k STR_r "\0"
-#define STRING_takri0 STR_t STR_a STR_k STR_r STR_i "\0"
-#define STRING_tale0 STR_t STR_a STR_l STR_e "\0"
-#define STRING_talu0 STR_t STR_a STR_l STR_u "\0"
-#define STRING_tamil0 STR_t STR_a STR_m STR_i STR_l "\0"
-#define STRING_taml0 STR_t STR_a STR_m STR_l "\0"
-#define STRING_tang0 STR_t STR_a STR_n STR_g "\0"
-#define STRING_tangsa0 STR_t STR_a STR_n STR_g STR_s STR_a "\0"
-#define STRING_tangut0 STR_t STR_a STR_n STR_g STR_u STR_t "\0"
-#define STRING_tavt0 STR_t STR_a STR_v STR_t "\0"
-#define STRING_telu0 STR_t STR_e STR_l STR_u "\0"
-#define STRING_telugu0 STR_t STR_e STR_l STR_u STR_g STR_u "\0"
-#define STRING_term0 STR_t STR_e STR_r STR_m "\0"
-#define STRING_terminalpunctuation0 STR_t STR_e STR_r STR_m STR_i STR_n STR_a STR_l STR_p STR_u STR_n STR_c STR_t STR_u STR_a STR_t STR_i STR_o STR_n "\0"
-#define STRING_tfng0 STR_t STR_f STR_n STR_g "\0"
-#define STRING_tglg0 STR_t STR_g STR_l STR_g "\0"
-#define STRING_thaa0 STR_t STR_h STR_a STR_a "\0"
-#define STRING_thaana0 STR_t STR_h STR_a STR_a STR_n STR_a "\0"
-#define STRING_thai0 STR_t STR_h STR_a STR_i "\0"
-#define STRING_tibetan0 STR_t STR_i STR_b STR_e STR_t STR_a STR_n "\0"
-#define STRING_tibt0 STR_t STR_i STR_b STR_t "\0"
-#define STRING_tifinagh0 STR_t STR_i STR_f STR_i STR_n STR_a STR_g STR_h "\0"
-#define STRING_tirh0 STR_t STR_i STR_r STR_h "\0"
-#define STRING_tirhuta0 STR_t STR_i STR_r STR_h STR_u STR_t STR_a "\0"
-#define STRING_tnsa0 STR_t STR_n STR_s STR_a "\0"
-#define STRING_toto0 STR_t STR_o STR_t STR_o "\0"
-#define STRING_ugar0 STR_u STR_g STR_a STR_r "\0"
-#define STRING_ugaritic0 STR_u STR_g STR_a STR_r STR_i STR_t STR_i STR_c "\0"
-#define STRING_uideo0 STR_u STR_i STR_d STR_e STR_o "\0"
-#define STRING_unifiedideograph0 STR_u STR_n STR_i STR_f STR_i STR_e STR_d STR_i STR_d STR_e STR_o STR_g STR_r STR_a STR_p STR_h "\0"
-#define STRING_unknown0 STR_u STR_n STR_k STR_n STR_o STR_w STR_n "\0"
-#define STRING_upper0 STR_u STR_p STR_p STR_e STR_r "\0"
-#define STRING_uppercase0 STR_u STR_p STR_p STR_e STR_r STR_c STR_a STR_s STR_e "\0"
-#define STRING_vai0 STR_v STR_a STR_i "\0"
-#define STRING_vaii0 STR_v STR_a STR_i STR_i "\0"
-#define STRING_variationselector0 STR_v STR_a STR_r STR_i STR_a STR_t STR_i STR_o STR_n STR_s STR_e STR_l STR_e STR_c STR_t STR_o STR_r "\0"
-#define STRING_vith0 STR_v STR_i STR_t STR_h "\0"
-#define STRING_vithkuqi0 STR_v STR_i STR_t STR_h STR_k STR_u STR_q STR_i "\0"
-#define STRING_vs0 STR_v STR_s "\0"
-#define STRING_wancho0 STR_w STR_a STR_n STR_c STR_h STR_o "\0"
-#define STRING_wara0 STR_w STR_a STR_r STR_a "\0"
-#define STRING_warangciti0 STR_w STR_a STR_r STR_a STR_n STR_g STR_c STR_i STR_t STR_i "\0"
-#define STRING_wcho0 STR_w STR_c STR_h STR_o "\0"
-#define STRING_whitespace0 STR_w STR_h STR_i STR_t STR_e STR_s STR_p STR_a STR_c STR_e "\0"
-#define STRING_wspace0 STR_w STR_s STR_p STR_a STR_c STR_e "\0"
-#define STRING_xan0 STR_x STR_a STR_n "\0"
-#define STRING_xidc0 STR_x STR_i STR_d STR_c "\0"
-#define STRING_xidcontinue0 STR_x STR_i STR_d STR_c STR_o STR_n STR_t STR_i STR_n STR_u STR_e "\0"
-#define STRING_xids0 STR_x STR_i STR_d STR_s "\0"
-#define STRING_xidstart0 STR_x STR_i STR_d STR_s STR_t STR_a STR_r STR_t "\0"
-#define STRING_xpeo0 STR_x STR_p STR_e STR_o "\0"
-#define STRING_xps0 STR_x STR_p STR_s "\0"
-#define STRING_xsp0 STR_x STR_s STR_p "\0"
-#define STRING_xsux0 STR_x STR_s STR_u STR_x "\0"
-#define STRING_xuc0 STR_x STR_u STR_c "\0"
-#define STRING_xwd0 STR_x STR_w STR_d "\0"
-#define STRING_yezi0 STR_y STR_e STR_z STR_i "\0"
-#define STRING_yezidi0 STR_y STR_e STR_z STR_i STR_d STR_i "\0"
-#define STRING_yi0 STR_y STR_i "\0"
-#define STRING_yiii0 STR_y STR_i STR_i STR_i "\0"
-#define STRING_z0 STR_z "\0"
-#define STRING_zanabazarsquare0 STR_z STR_a STR_n STR_a STR_b STR_a STR_z STR_a STR_r STR_s STR_q STR_u STR_a STR_r STR_e "\0"
-#define STRING_zanb0 STR_z STR_a STR_n STR_b "\0"
-#define STRING_zinh0 STR_z STR_i STR_n STR_h "\0"
-#define STRING_zl0 STR_z STR_l "\0"
-#define STRING_zp0 STR_z STR_p "\0"
-#define STRING_zs0 STR_z STR_s "\0"
-#define STRING_zyyy0 STR_z STR_y STR_y STR_y "\0"
-#define STRING_zzzz0 STR_z STR_z STR_z STR_z "\0"
-
-const char PRIV(utt_names)[] =
- STRING_adlam0
- STRING_adlm0
- STRING_aghb0
- STRING_ahex0
- STRING_ahom0
- STRING_alpha0
- STRING_alphabetic0
- STRING_anatolianhieroglyphs0
- STRING_any0
- STRING_arab0
- STRING_arabic0
- STRING_armenian0
- STRING_armi0
- STRING_armn0
- STRING_ascii0
- STRING_asciihexdigit0
- STRING_avestan0
- STRING_avst0
- STRING_bali0
- STRING_balinese0
- STRING_bamu0
- STRING_bamum0
- STRING_bass0
- STRING_bassavah0
- STRING_batak0
- STRING_batk0
- STRING_beng0
- STRING_bengali0
- STRING_bhaiksuki0
- STRING_bhks0
- STRING_bidial0
- STRING_bidian0
- STRING_bidib0
- STRING_bidibn0
- STRING_bidic0
- STRING_bidicontrol0
- STRING_bidics0
- STRING_bidien0
- STRING_bidies0
- STRING_bidiet0
- STRING_bidifsi0
- STRING_bidil0
- STRING_bidilre0
- STRING_bidilri0
- STRING_bidilro0
- STRING_bidim0
- STRING_bidimirrored0
- STRING_bidinsm0
- STRING_bidion0
- STRING_bidipdf0
- STRING_bidipdi0
- STRING_bidir0
- STRING_bidirle0
- STRING_bidirli0
- STRING_bidirlo0
- STRING_bidis0
- STRING_bidiws0
- STRING_bopo0
- STRING_bopomofo0
- STRING_brah0
- STRING_brahmi0
- STRING_brai0
- STRING_braille0
- STRING_bugi0
- STRING_buginese0
- STRING_buhd0
- STRING_buhid0
- STRING_c0
- STRING_cakm0
- STRING_canadianaboriginal0
- STRING_cans0
- STRING_cari0
- STRING_carian0
- STRING_cased0
- STRING_caseignorable0
- STRING_caucasianalbanian0
- STRING_cc0
- STRING_cf0
- STRING_chakma0
- STRING_cham0
- STRING_changeswhencasefolded0
- STRING_changeswhencasemapped0
- STRING_changeswhenlowercased0
- STRING_changeswhentitlecased0
- STRING_changeswhenuppercased0
- STRING_cher0
- STRING_cherokee0
- STRING_chorasmian0
- STRING_chrs0
- STRING_ci0
- STRING_cn0
- STRING_co0
- STRING_common0
- STRING_copt0
- STRING_coptic0
- STRING_cpmn0
- STRING_cprt0
- STRING_cs0
- STRING_cuneiform0
- STRING_cwcf0
- STRING_cwcm0
- STRING_cwl0
- STRING_cwt0
- STRING_cwu0
- STRING_cypriot0
- STRING_cyprominoan0
- STRING_cyrillic0
- STRING_cyrl0
- STRING_dash0
- STRING_defaultignorablecodepoint0
- STRING_dep0
- STRING_deprecated0
- STRING_deseret0
- STRING_deva0
- STRING_devanagari0
- STRING_di0
- STRING_dia0
- STRING_diacritic0
- STRING_diak0
- STRING_divesakuru0
- STRING_dogr0
- STRING_dogra0
- STRING_dsrt0
- STRING_dupl0
- STRING_duployan0
- STRING_ebase0
- STRING_ecomp0
- STRING_egyp0
- STRING_egyptianhieroglyphs0
- STRING_elba0
- STRING_elbasan0
- STRING_elym0
- STRING_elymaic0
- STRING_emod0
- STRING_emoji0
- STRING_emojicomponent0
- STRING_emojimodifier0
- STRING_emojimodifierbase0
- STRING_emojipresentation0
- STRING_epres0
- STRING_ethi0
- STRING_ethiopic0
- STRING_ext0
- STRING_extendedpictographic0
- STRING_extender0
- STRING_extpict0
- STRING_geor0
- STRING_georgian0
- STRING_glag0
- STRING_glagolitic0
- STRING_gong0
- STRING_gonm0
- STRING_goth0
- STRING_gothic0
- STRING_gran0
- STRING_grantha0
- STRING_graphemebase0
- STRING_graphemeextend0
- STRING_graphemelink0
- STRING_grbase0
- STRING_greek0
- STRING_grek0
- STRING_grext0
- STRING_grlink0
- STRING_gujarati0
- STRING_gujr0
- STRING_gunjalagondi0
- STRING_gurmukhi0
- STRING_guru0
- STRING_han0
- STRING_hang0
- STRING_hangul0
- STRING_hani0
- STRING_hanifirohingya0
- STRING_hano0
- STRING_hanunoo0
- STRING_hatr0
- STRING_hatran0
- STRING_hebr0
- STRING_hebrew0
- STRING_hex0
- STRING_hexdigit0
- STRING_hira0
- STRING_hiragana0
- STRING_hluw0
- STRING_hmng0
- STRING_hmnp0
- STRING_hung0
- STRING_idc0
- STRING_idcontinue0
- STRING_ideo0
- STRING_ideographic0
- STRING_ids0
- STRING_idsb0
- STRING_idsbinaryoperator0
- STRING_idst0
- STRING_idstart0
- STRING_idstrinaryoperator0
- STRING_imperialaramaic0
- STRING_inherited0
- STRING_inscriptionalpahlavi0
- STRING_inscriptionalparthian0
- STRING_ital0
- STRING_java0
- STRING_javanese0
- STRING_joinc0
- STRING_joincontrol0
- STRING_kaithi0
- STRING_kali0
- STRING_kana0
- STRING_kannada0
- STRING_katakana0
- STRING_kayahli0
- STRING_khar0
- STRING_kharoshthi0
- STRING_khitansmallscript0
- STRING_khmer0
- STRING_khmr0
- STRING_khoj0
- STRING_khojki0
- STRING_khudawadi0
- STRING_kits0
- STRING_knda0
- STRING_kthi0
- STRING_l0
- STRING_l_AMPERSAND0
- STRING_lana0
- STRING_lao0
- STRING_laoo0
- STRING_latin0
- STRING_latn0
- STRING_lc0
- STRING_lepc0
- STRING_lepcha0
- STRING_limb0
- STRING_limbu0
- STRING_lina0
- STRING_linb0
- STRING_lineara0
- STRING_linearb0
- STRING_lisu0
- STRING_ll0
- STRING_lm0
- STRING_lo0
- STRING_loe0
- STRING_logicalorderexception0
- STRING_lower0
- STRING_lowercase0
- STRING_lt0
- STRING_lu0
- STRING_lyci0
- STRING_lycian0
- STRING_lydi0
- STRING_lydian0
- STRING_m0
- STRING_mahajani0
- STRING_mahj0
- STRING_maka0
- STRING_makasar0
- STRING_malayalam0
- STRING_mand0
- STRING_mandaic0
- STRING_mani0
- STRING_manichaean0
- STRING_marc0
- STRING_marchen0
- STRING_masaramgondi0
- STRING_math0
- STRING_mc0
- STRING_me0
- STRING_medefaidrin0
- STRING_medf0
- STRING_meeteimayek0
- STRING_mend0
- STRING_mendekikakui0
- STRING_merc0
- STRING_mero0
- STRING_meroiticcursive0
- STRING_meroitichieroglyphs0
- STRING_miao0
- STRING_mlym0
- STRING_mn0
- STRING_modi0
- STRING_mong0
- STRING_mongolian0
- STRING_mro0
- STRING_mroo0
- STRING_mtei0
- STRING_mult0
- STRING_multani0
- STRING_myanmar0
- STRING_mymr0
- STRING_n0
- STRING_nabataean0
- STRING_nand0
- STRING_nandinagari0
- STRING_narb0
- STRING_nbat0
- STRING_nchar0
- STRING_nd0
- STRING_newa0
- STRING_newtailue0
- STRING_nko0
- STRING_nkoo0
- STRING_nl0
- STRING_no0
- STRING_noncharactercodepoint0
- STRING_nshu0
- STRING_nushu0
- STRING_nyiakengpuachuehmong0
- STRING_ogam0
- STRING_ogham0
- STRING_olchiki0
- STRING_olck0
- STRING_oldhungarian0
- STRING_olditalic0
- STRING_oldnortharabian0
- STRING_oldpermic0
- STRING_oldpersian0
- STRING_oldsogdian0
- STRING_oldsoutharabian0
- STRING_oldturkic0
- STRING_olduyghur0
- STRING_oriya0
- STRING_orkh0
- STRING_orya0
- STRING_osage0
- STRING_osge0
- STRING_osma0
- STRING_osmanya0
- STRING_ougr0
- STRING_p0
- STRING_pahawhhmong0
- STRING_palm0
- STRING_palmyrene0
- STRING_patsyn0
- STRING_patternsyntax0
- STRING_patternwhitespace0
- STRING_patws0
- STRING_pauc0
- STRING_paucinhau0
- STRING_pc0
- STRING_pcm0
- STRING_pd0
- STRING_pe0
- STRING_perm0
- STRING_pf0
- STRING_phag0
- STRING_phagspa0
- STRING_phli0
- STRING_phlp0
- STRING_phnx0
- STRING_phoenician0
- STRING_pi0
- STRING_plrd0
- STRING_po0
- STRING_prependedconcatenationmark0
- STRING_prti0
- STRING_ps0
- STRING_psalterpahlavi0
- STRING_qaac0
- STRING_qaai0
- STRING_qmark0
- STRING_quotationmark0
- STRING_radical0
- STRING_regionalindicator0
- STRING_rejang0
- STRING_ri0
- STRING_rjng0
- STRING_rohg0
- STRING_runic0
- STRING_runr0
- STRING_s0
- STRING_samaritan0
- STRING_samr0
- STRING_sarb0
- STRING_saur0
- STRING_saurashtra0
- STRING_sc0
- STRING_sd0
- STRING_sentenceterminal0
- STRING_sgnw0
- STRING_sharada0
- STRING_shavian0
- STRING_shaw0
- STRING_shrd0
- STRING_sidd0
- STRING_siddham0
- STRING_signwriting0
- STRING_sind0
- STRING_sinh0
- STRING_sinhala0
- STRING_sk0
- STRING_sm0
- STRING_so0
- STRING_softdotted0
- STRING_sogd0
- STRING_sogdian0
- STRING_sogo0
- STRING_sora0
- STRING_sorasompeng0
- STRING_soyo0
- STRING_soyombo0
- STRING_space0
- STRING_sterm0
- STRING_sund0
- STRING_sundanese0
- STRING_sylo0
- STRING_sylotinagri0
- STRING_syrc0
- STRING_syriac0
- STRING_tagalog0
- STRING_tagb0
- STRING_tagbanwa0
- STRING_taile0
- STRING_taitham0
- STRING_taiviet0
- STRING_takr0
- STRING_takri0
- STRING_tale0
- STRING_talu0
- STRING_tamil0
- STRING_taml0
- STRING_tang0
- STRING_tangsa0
- STRING_tangut0
- STRING_tavt0
- STRING_telu0
- STRING_telugu0
- STRING_term0
- STRING_terminalpunctuation0
- STRING_tfng0
- STRING_tglg0
- STRING_thaa0
- STRING_thaana0
- STRING_thai0
- STRING_tibetan0
- STRING_tibt0
- STRING_tifinagh0
- STRING_tirh0
- STRING_tirhuta0
- STRING_tnsa0
- STRING_toto0
- STRING_ugar0
- STRING_ugaritic0
- STRING_uideo0
- STRING_unifiedideograph0
- STRING_unknown0
- STRING_upper0
- STRING_uppercase0
- STRING_vai0
- STRING_vaii0
- STRING_variationselector0
- STRING_vith0
- STRING_vithkuqi0
- STRING_vs0
- STRING_wancho0
- STRING_wara0
- STRING_warangciti0
- STRING_wcho0
- STRING_whitespace0
- STRING_wspace0
- STRING_xan0
- STRING_xidc0
- STRING_xidcontinue0
- STRING_xids0
- STRING_xidstart0
- STRING_xpeo0
- STRING_xps0
- STRING_xsp0
- STRING_xsux0
- STRING_xuc0
- STRING_xwd0
- STRING_yezi0
- STRING_yezidi0
- STRING_yi0
- STRING_yiii0
- STRING_z0
- STRING_zanabazarsquare0
- STRING_zanb0
- STRING_zinh0
- STRING_zl0
- STRING_zp0
- STRING_zs0
- STRING_zyyy0
- STRING_zzzz0;
-
-const ucp_type_table PRIV(utt)[] = {
- { 0, PT_SCX, ucp_Adlam },
- { 6, PT_SCX, ucp_Adlam },
- { 11, PT_SC, ucp_Caucasian_Albanian },
- { 16, PT_BOOL, ucp_ASCII_Hex_Digit },
- { 21, PT_SC, ucp_Ahom },
- { 26, PT_BOOL, ucp_Alphabetic },
- { 32, PT_BOOL, ucp_Alphabetic },
- { 43, PT_SC, ucp_Anatolian_Hieroglyphs },
- { 64, PT_ANY, 0 },
- { 68, PT_SCX, ucp_Arabic },
- { 73, PT_SCX, ucp_Arabic },
- { 80, PT_SC, ucp_Armenian },
- { 89, PT_SC, ucp_Imperial_Aramaic },
- { 94, PT_SC, ucp_Armenian },
- { 99, PT_BOOL, ucp_ASCII },
- { 105, PT_BOOL, ucp_ASCII_Hex_Digit },
- { 119, PT_SC, ucp_Avestan },
- { 127, PT_SC, ucp_Avestan },
- { 132, PT_SC, ucp_Balinese },
- { 137, PT_SC, ucp_Balinese },
- { 146, PT_SC, ucp_Bamum },
- { 151, PT_SC, ucp_Bamum },
- { 157, PT_SC, ucp_Bassa_Vah },
- { 162, PT_SC, ucp_Bassa_Vah },
- { 171, PT_SC, ucp_Batak },
- { 177, PT_SC, ucp_Batak },
- { 182, PT_SCX, ucp_Bengali },
- { 187, PT_SCX, ucp_Bengali },
- { 195, PT_SC, ucp_Bhaiksuki },
- { 205, PT_SC, ucp_Bhaiksuki },
- { 210, PT_BIDICL, ucp_bidiAL },
- { 217, PT_BIDICL, ucp_bidiAN },
- { 224, PT_BIDICL, ucp_bidiB },
- { 230, PT_BIDICL, ucp_bidiBN },
- { 237, PT_BOOL, ucp_Bidi_Control },
- { 243, PT_BOOL, ucp_Bidi_Control },
- { 255, PT_BIDICL, ucp_bidiCS },
- { 262, PT_BIDICL, ucp_bidiEN },
- { 269, PT_BIDICL, ucp_bidiES },
- { 276, PT_BIDICL, ucp_bidiET },
- { 283, PT_BIDICL, ucp_bidiFSI },
- { 291, PT_BIDICL, ucp_bidiL },
- { 297, PT_BIDICL, ucp_bidiLRE },
- { 305, PT_BIDICL, ucp_bidiLRI },
- { 313, PT_BIDICL, ucp_bidiLRO },
- { 321, PT_BOOL, ucp_Bidi_Mirrored },
- { 327, PT_BOOL, ucp_Bidi_Mirrored },
- { 340, PT_BIDICL, ucp_bidiNSM },
- { 348, PT_BIDICL, ucp_bidiON },
- { 355, PT_BIDICL, ucp_bidiPDF },
- { 363, PT_BIDICL, ucp_bidiPDI },
- { 371, PT_BIDICL, ucp_bidiR },
- { 377, PT_BIDICL, ucp_bidiRLE },
- { 385, PT_BIDICL, ucp_bidiRLI },
- { 393, PT_BIDICL, ucp_bidiRLO },
- { 401, PT_BIDICL, ucp_bidiS },
- { 407, PT_BIDICL, ucp_bidiWS },
- { 414, PT_SCX, ucp_Bopomofo },
- { 419, PT_SCX, ucp_Bopomofo },
- { 428, PT_SC, ucp_Brahmi },
- { 433, PT_SC, ucp_Brahmi },
- { 440, PT_SC, ucp_Braille },
- { 445, PT_SC, ucp_Braille },
- { 453, PT_SCX, ucp_Buginese },
- { 458, PT_SCX, ucp_Buginese },
- { 467, PT_SCX, ucp_Buhid },
- { 472, PT_SCX, ucp_Buhid },
- { 478, PT_GC, ucp_C },
- { 480, PT_SCX, ucp_Chakma },
- { 485, PT_SC, ucp_Canadian_Aboriginal },
- { 504, PT_SC, ucp_Canadian_Aboriginal },
- { 509, PT_SC, ucp_Carian },
- { 514, PT_SC, ucp_Carian },
- { 521, PT_BOOL, ucp_Cased },
- { 527, PT_BOOL, ucp_Case_Ignorable },
- { 541, PT_SC, ucp_Caucasian_Albanian },
- { 559, PT_PC, ucp_Cc },
- { 562, PT_PC, ucp_Cf },
- { 565, PT_SCX, ucp_Chakma },
- { 572, PT_SC, ucp_Cham },
- { 577, PT_BOOL, ucp_Changes_When_Casefolded },
- { 599, PT_BOOL, ucp_Changes_When_Casemapped },
- { 621, PT_BOOL, ucp_Changes_When_Lowercased },
- { 643, PT_BOOL, ucp_Changes_When_Titlecased },
- { 665, PT_BOOL, ucp_Changes_When_Uppercased },
- { 687, PT_SC, ucp_Cherokee },
- { 692, PT_SC, ucp_Cherokee },
- { 701, PT_SC, ucp_Chorasmian },
- { 712, PT_SC, ucp_Chorasmian },
- { 717, PT_BOOL, ucp_Case_Ignorable },
- { 720, PT_PC, ucp_Cn },
- { 723, PT_PC, ucp_Co },
- { 726, PT_SC, ucp_Common },
- { 733, PT_SCX, ucp_Coptic },
- { 738, PT_SCX, ucp_Coptic },
- { 745, PT_SCX, ucp_Cypro_Minoan },
- { 750, PT_SCX, ucp_Cypriot },
- { 755, PT_PC, ucp_Cs },
- { 758, PT_SC, ucp_Cuneiform },
- { 768, PT_BOOL, ucp_Changes_When_Casefolded },
- { 773, PT_BOOL, ucp_Changes_When_Casemapped },
- { 778, PT_BOOL, ucp_Changes_When_Lowercased },
- { 782, PT_BOOL, ucp_Changes_When_Titlecased },
- { 786, PT_BOOL, ucp_Changes_When_Uppercased },
- { 790, PT_SCX, ucp_Cypriot },
- { 798, PT_SCX, ucp_Cypro_Minoan },
- { 810, PT_SCX, ucp_Cyrillic },
- { 819, PT_SCX, ucp_Cyrillic },
- { 824, PT_BOOL, ucp_Dash },
- { 829, PT_BOOL, ucp_Default_Ignorable_Code_Point },
- { 855, PT_BOOL, ucp_Deprecated },
- { 859, PT_BOOL, ucp_Deprecated },
- { 870, PT_SC, ucp_Deseret },
- { 878, PT_SCX, ucp_Devanagari },
- { 883, PT_SCX, ucp_Devanagari },
- { 894, PT_BOOL, ucp_Default_Ignorable_Code_Point },
- { 897, PT_BOOL, ucp_Diacritic },
- { 901, PT_BOOL, ucp_Diacritic },
- { 911, PT_SC, ucp_Dives_Akuru },
- { 916, PT_SC, ucp_Dives_Akuru },
- { 927, PT_SCX, ucp_Dogra },
- { 932, PT_SCX, ucp_Dogra },
- { 938, PT_SC, ucp_Deseret },
- { 943, PT_SCX, ucp_Duployan },
- { 948, PT_SCX, ucp_Duployan },
- { 957, PT_BOOL, ucp_Emoji_Modifier_Base },
- { 963, PT_BOOL, ucp_Emoji_Component },
- { 969, PT_SC, ucp_Egyptian_Hieroglyphs },
- { 974, PT_SC, ucp_Egyptian_Hieroglyphs },
- { 994, PT_SC, ucp_Elbasan },
- { 999, PT_SC, ucp_Elbasan },
- { 1007, PT_SC, ucp_Elymaic },
- { 1012, PT_SC, ucp_Elymaic },
- { 1020, PT_BOOL, ucp_Emoji_Modifier },
- { 1025, PT_BOOL, ucp_Emoji },
- { 1031, PT_BOOL, ucp_Emoji_Component },
- { 1046, PT_BOOL, ucp_Emoji_Modifier },
- { 1060, PT_BOOL, ucp_Emoji_Modifier_Base },
- { 1078, PT_BOOL, ucp_Emoji_Presentation },
- { 1096, PT_BOOL, ucp_Emoji_Presentation },
- { 1102, PT_SC, ucp_Ethiopic },
- { 1107, PT_SC, ucp_Ethiopic },
- { 1116, PT_BOOL, ucp_Extender },
- { 1120, PT_BOOL, ucp_Extended_Pictographic },
- { 1141, PT_BOOL, ucp_Extender },
- { 1150, PT_BOOL, ucp_Extended_Pictographic },
- { 1158, PT_SCX, ucp_Georgian },
- { 1163, PT_SCX, ucp_Georgian },
- { 1172, PT_SCX, ucp_Glagolitic },
- { 1177, PT_SCX, ucp_Glagolitic },
- { 1188, PT_SCX, ucp_Gunjala_Gondi },
- { 1193, PT_SCX, ucp_Masaram_Gondi },
- { 1198, PT_SC, ucp_Gothic },
- { 1203, PT_SC, ucp_Gothic },
- { 1210, PT_SCX, ucp_Grantha },
- { 1215, PT_SCX, ucp_Grantha },
- { 1223, PT_BOOL, ucp_Grapheme_Base },
- { 1236, PT_BOOL, ucp_Grapheme_Extend },
- { 1251, PT_BOOL, ucp_Grapheme_Link },
- { 1264, PT_BOOL, ucp_Grapheme_Base },
- { 1271, PT_SCX, ucp_Greek },
- { 1277, PT_SCX, ucp_Greek },
- { 1282, PT_BOOL, ucp_Grapheme_Extend },
- { 1288, PT_BOOL, ucp_Grapheme_Link },
- { 1295, PT_SCX, ucp_Gujarati },
- { 1304, PT_SCX, ucp_Gujarati },
- { 1309, PT_SCX, ucp_Gunjala_Gondi },
- { 1322, PT_SCX, ucp_Gurmukhi },
- { 1331, PT_SCX, ucp_Gurmukhi },
- { 1336, PT_SCX, ucp_Han },
- { 1340, PT_SCX, ucp_Hangul },
- { 1345, PT_SCX, ucp_Hangul },
- { 1352, PT_SCX, ucp_Han },
- { 1357, PT_SCX, ucp_Hanifi_Rohingya },
- { 1372, PT_SCX, ucp_Hanunoo },
- { 1377, PT_SCX, ucp_Hanunoo },
- { 1385, PT_SC, ucp_Hatran },
- { 1390, PT_SC, ucp_Hatran },
- { 1397, PT_SC, ucp_Hebrew },
- { 1402, PT_SC, ucp_Hebrew },
- { 1409, PT_BOOL, ucp_Hex_Digit },
- { 1413, PT_BOOL, ucp_Hex_Digit },
- { 1422, PT_SCX, ucp_Hiragana },
- { 1427, PT_SCX, ucp_Hiragana },
- { 1436, PT_SC, ucp_Anatolian_Hieroglyphs },
- { 1441, PT_SC, ucp_Pahawh_Hmong },
- { 1446, PT_SC, ucp_Nyiakeng_Puachue_Hmong },
- { 1451, PT_SC, ucp_Old_Hungarian },
- { 1456, PT_BOOL, ucp_ID_Continue },
- { 1460, PT_BOOL, ucp_ID_Continue },
- { 1471, PT_BOOL, ucp_Ideographic },
- { 1476, PT_BOOL, ucp_Ideographic },
- { 1488, PT_BOOL, ucp_ID_Start },
- { 1492, PT_BOOL, ucp_IDS_Binary_Operator },
- { 1497, PT_BOOL, ucp_IDS_Binary_Operator },
- { 1515, PT_BOOL, ucp_IDS_Trinary_Operator },
- { 1520, PT_BOOL, ucp_ID_Start },
- { 1528, PT_BOOL, ucp_IDS_Trinary_Operator },
- { 1547, PT_SC, ucp_Imperial_Aramaic },
- { 1563, PT_SC, ucp_Inherited },
- { 1573, PT_SC, ucp_Inscriptional_Pahlavi },
- { 1594, PT_SC, ucp_Inscriptional_Parthian },
- { 1616, PT_SC, ucp_Old_Italic },
- { 1621, PT_SCX, ucp_Javanese },
- { 1626, PT_SCX, ucp_Javanese },
- { 1635, PT_BOOL, ucp_Join_Control },
- { 1641, PT_BOOL, ucp_Join_Control },
- { 1653, PT_SCX, ucp_Kaithi },
- { 1660, PT_SCX, ucp_Kayah_Li },
- { 1665, PT_SCX, ucp_Katakana },
- { 1670, PT_SCX, ucp_Kannada },
- { 1678, PT_SCX, ucp_Katakana },
- { 1687, PT_SCX, ucp_Kayah_Li },
- { 1695, PT_SC, ucp_Kharoshthi },
- { 1700, PT_SC, ucp_Kharoshthi },
- { 1711, PT_SC, ucp_Khitan_Small_Script },
- { 1729, PT_SC, ucp_Khmer },
- { 1735, PT_SC, ucp_Khmer },
- { 1740, PT_SCX, ucp_Khojki },
- { 1745, PT_SCX, ucp_Khojki },
- { 1752, PT_SCX, ucp_Khudawadi },
- { 1762, PT_SC, ucp_Khitan_Small_Script },
- { 1767, PT_SCX, ucp_Kannada },
- { 1772, PT_SCX, ucp_Kaithi },
- { 1777, PT_GC, ucp_L },
- { 1779, PT_LAMP, 0 },
- { 1782, PT_SC, ucp_Tai_Tham },
- { 1787, PT_SC, ucp_Lao },
- { 1791, PT_SC, ucp_Lao },
- { 1796, PT_SCX, ucp_Latin },
- { 1802, PT_SCX, ucp_Latin },
- { 1807, PT_LAMP, 0 },
- { 1810, PT_SC, ucp_Lepcha },
- { 1815, PT_SC, ucp_Lepcha },
- { 1822, PT_SCX, ucp_Limbu },
- { 1827, PT_SCX, ucp_Limbu },
- { 1833, PT_SCX, ucp_Linear_A },
- { 1838, PT_SCX, ucp_Linear_B },
- { 1843, PT_SCX, ucp_Linear_A },
- { 1851, PT_SCX, ucp_Linear_B },
- { 1859, PT_SC, ucp_Lisu },
- { 1864, PT_PC, ucp_Ll },
- { 1867, PT_PC, ucp_Lm },
- { 1870, PT_PC, ucp_Lo },
- { 1873, PT_BOOL, ucp_Logical_Order_Exception },
- { 1877, PT_BOOL, ucp_Logical_Order_Exception },
- { 1899, PT_BOOL, ucp_Lowercase },
- { 1905, PT_BOOL, ucp_Lowercase },
- { 1915, PT_PC, ucp_Lt },
- { 1918, PT_PC, ucp_Lu },
- { 1921, PT_SC, ucp_Lycian },
- { 1926, PT_SC, ucp_Lycian },
- { 1933, PT_SC, ucp_Lydian },
- { 1938, PT_SC, ucp_Lydian },
- { 1945, PT_GC, ucp_M },
- { 1947, PT_SCX, ucp_Mahajani },
- { 1956, PT_SCX, ucp_Mahajani },
- { 1961, PT_SC, ucp_Makasar },
- { 1966, PT_SC, ucp_Makasar },
- { 1974, PT_SCX, ucp_Malayalam },
- { 1984, PT_SCX, ucp_Mandaic },
- { 1989, PT_SCX, ucp_Mandaic },
- { 1997, PT_SCX, ucp_Manichaean },
- { 2002, PT_SCX, ucp_Manichaean },
- { 2013, PT_SC, ucp_Marchen },
- { 2018, PT_SC, ucp_Marchen },
- { 2026, PT_SCX, ucp_Masaram_Gondi },
- { 2039, PT_BOOL, ucp_Math },
- { 2044, PT_PC, ucp_Mc },
- { 2047, PT_PC, ucp_Me },
- { 2050, PT_SC, ucp_Medefaidrin },
- { 2062, PT_SC, ucp_Medefaidrin },
- { 2067, PT_SC, ucp_Meetei_Mayek },
- { 2079, PT_SC, ucp_Mende_Kikakui },
- { 2084, PT_SC, ucp_Mende_Kikakui },
- { 2097, PT_SC, ucp_Meroitic_Cursive },
- { 2102, PT_SC, ucp_Meroitic_Hieroglyphs },
- { 2107, PT_SC, ucp_Meroitic_Cursive },
- { 2123, PT_SC, ucp_Meroitic_Hieroglyphs },
- { 2143, PT_SC, ucp_Miao },
- { 2148, PT_SCX, ucp_Malayalam },
- { 2153, PT_PC, ucp_Mn },
- { 2156, PT_SCX, ucp_Modi },
- { 2161, PT_SCX, ucp_Mongolian },
- { 2166, PT_SCX, ucp_Mongolian },
- { 2176, PT_SC, ucp_Mro },
- { 2180, PT_SC, ucp_Mro },
- { 2185, PT_SC, ucp_Meetei_Mayek },
- { 2190, PT_SCX, ucp_Multani },
- { 2195, PT_SCX, ucp_Multani },
- { 2203, PT_SCX, ucp_Myanmar },
- { 2211, PT_SCX, ucp_Myanmar },
- { 2216, PT_GC, ucp_N },
- { 2218, PT_SC, ucp_Nabataean },
- { 2228, PT_SCX, ucp_Nandinagari },
- { 2233, PT_SCX, ucp_Nandinagari },
- { 2245, PT_SC, ucp_Old_North_Arabian },
- { 2250, PT_SC, ucp_Nabataean },
- { 2255, PT_BOOL, ucp_Noncharacter_Code_Point },
- { 2261, PT_PC, ucp_Nd },
- { 2264, PT_SC, ucp_Newa },
- { 2269, PT_SC, ucp_New_Tai_Lue },
- { 2279, PT_SCX, ucp_Nko },
- { 2283, PT_SCX, ucp_Nko },
- { 2288, PT_PC, ucp_Nl },
- { 2291, PT_PC, ucp_No },
- { 2294, PT_BOOL, ucp_Noncharacter_Code_Point },
- { 2316, PT_SC, ucp_Nushu },
- { 2321, PT_SC, ucp_Nushu },
- { 2327, PT_SC, ucp_Nyiakeng_Puachue_Hmong },
- { 2348, PT_SC, ucp_Ogham },
- { 2353, PT_SC, ucp_Ogham },
- { 2359, PT_SC, ucp_Ol_Chiki },
- { 2367, PT_SC, ucp_Ol_Chiki },
- { 2372, PT_SC, ucp_Old_Hungarian },
- { 2385, PT_SC, ucp_Old_Italic },
- { 2395, PT_SC, ucp_Old_North_Arabian },
- { 2411, PT_SCX, ucp_Old_Permic },
- { 2421, PT_SC, ucp_Old_Persian },
- { 2432, PT_SC, ucp_Old_Sogdian },
- { 2443, PT_SC, ucp_Old_South_Arabian },
- { 2459, PT_SC, ucp_Old_Turkic },
- { 2469, PT_SCX, ucp_Old_Uyghur },
- { 2479, PT_SCX, ucp_Oriya },
- { 2485, PT_SC, ucp_Old_Turkic },
- { 2490, PT_SCX, ucp_Oriya },
- { 2495, PT_SC, ucp_Osage },
- { 2501, PT_SC, ucp_Osage },
- { 2506, PT_SC, ucp_Osmanya },
- { 2511, PT_SC, ucp_Osmanya },
- { 2519, PT_SCX, ucp_Old_Uyghur },
- { 2524, PT_GC, ucp_P },
- { 2526, PT_SC, ucp_Pahawh_Hmong },
- { 2538, PT_SC, ucp_Palmyrene },
- { 2543, PT_SC, ucp_Palmyrene },
- { 2553, PT_BOOL, ucp_Pattern_Syntax },
- { 2560, PT_BOOL, ucp_Pattern_Syntax },
- { 2574, PT_BOOL, ucp_Pattern_White_Space },
- { 2592, PT_BOOL, ucp_Pattern_White_Space },
- { 2598, PT_SC, ucp_Pau_Cin_Hau },
- { 2603, PT_SC, ucp_Pau_Cin_Hau },
- { 2613, PT_PC, ucp_Pc },
- { 2616, PT_BOOL, ucp_Prepended_Concatenation_Mark },
- { 2620, PT_PC, ucp_Pd },
- { 2623, PT_PC, ucp_Pe },
- { 2626, PT_SCX, ucp_Old_Permic },
- { 2631, PT_PC, ucp_Pf },
- { 2634, PT_SCX, ucp_Phags_Pa },
- { 2639, PT_SCX, ucp_Phags_Pa },
- { 2647, PT_SC, ucp_Inscriptional_Pahlavi },
- { 2652, PT_SCX, ucp_Psalter_Pahlavi },
- { 2657, PT_SC, ucp_Phoenician },
- { 2662, PT_SC, ucp_Phoenician },
- { 2673, PT_PC, ucp_Pi },
- { 2676, PT_SC, ucp_Miao },
- { 2681, PT_PC, ucp_Po },
- { 2684, PT_BOOL, ucp_Prepended_Concatenation_Mark },
- { 2711, PT_SC, ucp_Inscriptional_Parthian },
- { 2716, PT_PC, ucp_Ps },
- { 2719, PT_SCX, ucp_Psalter_Pahlavi },
- { 2734, PT_SCX, ucp_Coptic },
- { 2739, PT_SC, ucp_Inherited },
- { 2744, PT_BOOL, ucp_Quotation_Mark },
- { 2750, PT_BOOL, ucp_Quotation_Mark },
- { 2764, PT_BOOL, ucp_Radical },
- { 2772, PT_BOOL, ucp_Regional_Indicator },
- { 2790, PT_SC, ucp_Rejang },
- { 2797, PT_BOOL, ucp_Regional_Indicator },
- { 2800, PT_SC, ucp_Rejang },
- { 2805, PT_SCX, ucp_Hanifi_Rohingya },
- { 2810, PT_SC, ucp_Runic },
- { 2816, PT_SC, ucp_Runic },
- { 2821, PT_GC, ucp_S },
- { 2823, PT_SC, ucp_Samaritan },
- { 2833, PT_SC, ucp_Samaritan },
- { 2838, PT_SC, ucp_Old_South_Arabian },
- { 2843, PT_SC, ucp_Saurashtra },
- { 2848, PT_SC, ucp_Saurashtra },
- { 2859, PT_PC, ucp_Sc },
- { 2862, PT_BOOL, ucp_Soft_Dotted },
- { 2865, PT_BOOL, ucp_Sentence_Terminal },
- { 2882, PT_SC, ucp_SignWriting },
- { 2887, PT_SCX, ucp_Sharada },
- { 2895, PT_SC, ucp_Shavian },
- { 2903, PT_SC, ucp_Shavian },
- { 2908, PT_SCX, ucp_Sharada },
- { 2913, PT_SC, ucp_Siddham },
- { 2918, PT_SC, ucp_Siddham },
- { 2926, PT_SC, ucp_SignWriting },
- { 2938, PT_SCX, ucp_Khudawadi },
- { 2943, PT_SCX, ucp_Sinhala },
- { 2948, PT_SCX, ucp_Sinhala },
- { 2956, PT_PC, ucp_Sk },
- { 2959, PT_PC, ucp_Sm },
- { 2962, PT_PC, ucp_So },
- { 2965, PT_BOOL, ucp_Soft_Dotted },
- { 2976, PT_SCX, ucp_Sogdian },
- { 2981, PT_SCX, ucp_Sogdian },
- { 2989, PT_SC, ucp_Old_Sogdian },
- { 2994, PT_SC, ucp_Sora_Sompeng },
- { 2999, PT_SC, ucp_Sora_Sompeng },
- { 3011, PT_SC, ucp_Soyombo },
- { 3016, PT_SC, ucp_Soyombo },
- { 3024, PT_BOOL, ucp_White_Space },
- { 3030, PT_BOOL, ucp_Sentence_Terminal },
- { 3036, PT_SC, ucp_Sundanese },
- { 3041, PT_SC, ucp_Sundanese },
- { 3051, PT_SCX, ucp_Syloti_Nagri },
- { 3056, PT_SCX, ucp_Syloti_Nagri },
- { 3068, PT_SCX, ucp_Syriac },
- { 3073, PT_SCX, ucp_Syriac },
- { 3080, PT_SCX, ucp_Tagalog },
- { 3088, PT_SCX, ucp_Tagbanwa },
- { 3093, PT_SCX, ucp_Tagbanwa },
- { 3102, PT_SCX, ucp_Tai_Le },
- { 3108, PT_SC, ucp_Tai_Tham },
- { 3116, PT_SC, ucp_Tai_Viet },
- { 3124, PT_SCX, ucp_Takri },
- { 3129, PT_SCX, ucp_Takri },
- { 3135, PT_SCX, ucp_Tai_Le },
- { 3140, PT_SC, ucp_New_Tai_Lue },
- { 3145, PT_SCX, ucp_Tamil },
- { 3151, PT_SCX, ucp_Tamil },
- { 3156, PT_SC, ucp_Tangut },
- { 3161, PT_SC, ucp_Tangsa },
- { 3168, PT_SC, ucp_Tangut },
- { 3175, PT_SC, ucp_Tai_Viet },
- { 3180, PT_SCX, ucp_Telugu },
- { 3185, PT_SCX, ucp_Telugu },
- { 3192, PT_BOOL, ucp_Terminal_Punctuation },
- { 3197, PT_BOOL, ucp_Terminal_Punctuation },
- { 3217, PT_SC, ucp_Tifinagh },
- { 3222, PT_SCX, ucp_Tagalog },
- { 3227, PT_SCX, ucp_Thaana },
- { 3232, PT_SCX, ucp_Thaana },
- { 3239, PT_SC, ucp_Thai },
- { 3244, PT_SC, ucp_Tibetan },
- { 3252, PT_SC, ucp_Tibetan },
- { 3257, PT_SC, ucp_Tifinagh },
- { 3266, PT_SCX, ucp_Tirhuta },
- { 3271, PT_SCX, ucp_Tirhuta },
- { 3279, PT_SC, ucp_Tangsa },
- { 3284, PT_SC, ucp_Toto },
- { 3289, PT_SC, ucp_Ugaritic },
- { 3294, PT_SC, ucp_Ugaritic },
- { 3303, PT_BOOL, ucp_Unified_Ideograph },
- { 3309, PT_BOOL, ucp_Unified_Ideograph },
- { 3326, PT_SC, ucp_Unknown },
- { 3334, PT_BOOL, ucp_Uppercase },
- { 3340, PT_BOOL, ucp_Uppercase },
- { 3350, PT_SC, ucp_Vai },
- { 3354, PT_SC, ucp_Vai },
- { 3359, PT_BOOL, ucp_Variation_Selector },
- { 3377, PT_SC, ucp_Vithkuqi },
- { 3382, PT_SC, ucp_Vithkuqi },
- { 3391, PT_BOOL, ucp_Variation_Selector },
- { 3394, PT_SC, ucp_Wancho },
- { 3401, PT_SC, ucp_Warang_Citi },
- { 3406, PT_SC, ucp_Warang_Citi },
- { 3417, PT_SC, ucp_Wancho },
- { 3422, PT_BOOL, ucp_White_Space },
- { 3433, PT_BOOL, ucp_White_Space },
- { 3440, PT_ALNUM, 0 },
- { 3444, PT_BOOL, ucp_XID_Continue },
- { 3449, PT_BOOL, ucp_XID_Continue },
- { 3461, PT_BOOL, ucp_XID_Start },
- { 3466, PT_BOOL, ucp_XID_Start },
- { 3475, PT_SC, ucp_Old_Persian },
- { 3480, PT_PXSPACE, 0 },
- { 3484, PT_SPACE, 0 },
- { 3488, PT_SC, ucp_Cuneiform },
- { 3493, PT_UCNC, 0 },
- { 3497, PT_WORD, 0 },
- { 3501, PT_SCX, ucp_Yezidi },
- { 3506, PT_SCX, ucp_Yezidi },
- { 3513, PT_SCX, ucp_Yi },
- { 3516, PT_SCX, ucp_Yi },
- { 3521, PT_GC, ucp_Z },
- { 3523, PT_SC, ucp_Zanabazar_Square },
- { 3539, PT_SC, ucp_Zanabazar_Square },
- { 3544, PT_SC, ucp_Inherited },
- { 3549, PT_PC, ucp_Zl },
- { 3552, PT_PC, ucp_Zp },
- { 3555, PT_PC, ucp_Zs },
- { 3558, PT_SC, ucp_Common },
- { 3563, PT_SC, ucp_Unknown }
-};
-
-const size_t PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table);
-
-#endif /* SUPPORT_UNICODE */
-
-/* End of pcre2_ucptables.c */
diff --git a/contrib/libs/pcre2/src/pcre2_valid_utf.c b/contrib/libs/pcre2/src/pcre2_valid_utf.c
deleted file mode 100644
index 9373f71099..0000000000
--- a/contrib/libs/pcre2/src/pcre2_valid_utf.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2020 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains an internal function for validating UTF character
-strings. This file is also #included by the pcre2test program, which uses
-macros to change names from _pcre2_xxx to xxxx, thereby avoiding name clashes
-with the library. In this case, PCRE2_PCRE2TEST is defined. */
-
-#ifndef PCRE2_PCRE2TEST /* We're compiling the library */
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-#include "pcre2_internal.h"
-#endif /* PCRE2_PCRE2TEST */
-
-
-#ifndef SUPPORT_UNICODE
-/*************************************************
-* Dummy function when Unicode is not supported *
-*************************************************/
-
-/* This function should never be called when Unicode is not supported. */
-
-int
-PRIV(valid_utf)(PCRE2_SPTR string, PCRE2_SIZE length, PCRE2_SIZE *erroroffset)
-{
-(void)string;
-(void)length;
-(void)erroroffset;
-return 0;
-}
-#else /* UTF is supported */
-
-
-
-/*************************************************
-* Validate a UTF string *
-*************************************************/
-
-/* This function is called (optionally) at the start of compile or match, to
-check that a supposed UTF string is actually valid. The early check means
-that subsequent code can assume it is dealing with a valid string. The check
-can be turned off for maximum performance, but the consequences of supplying an
-invalid string are then undefined.
-
-Arguments:
- string points to the string
- length length of string
- errp pointer to an error position offset variable
-
-Returns: == 0 if the string is a valid UTF string
- != 0 otherwise, setting the offset of the bad character
-*/
-
-int
-PRIV(valid_utf)(PCRE2_SPTR string, PCRE2_SIZE length, PCRE2_SIZE *erroroffset)
-{
-PCRE2_SPTR p;
-uint32_t c;
-
-/* ----------------- Check a UTF-8 string ----------------- */
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
-
-/* Originally, this function checked according to RFC 2279, allowing for values
-in the range 0 to 0x7fffffff, up to 6 bytes long, but ensuring that they were
-in the canonical format. Once somebody had pointed out RFC 3629 to me (it
-obsoletes 2279), additional restrictions were applied. The values are now
-limited to be between 0 and 0x0010ffff, no more than 4 bytes long, and the
-subrange 0xd000 to 0xdfff is excluded. However, the format of 5-byte and 6-byte
-characters is still checked. Error returns are as follows:
-
-PCRE2_ERROR_UTF8_ERR1 Missing 1 byte at the end of the string
-PCRE2_ERROR_UTF8_ERR2 Missing 2 bytes at the end of the string
-PCRE2_ERROR_UTF8_ERR3 Missing 3 bytes at the end of the string
-PCRE2_ERROR_UTF8_ERR4 Missing 4 bytes at the end of the string
-PCRE2_ERROR_UTF8_ERR5 Missing 5 bytes at the end of the string
-PCRE2_ERROR_UTF8_ERR6 2nd-byte's two top bits are not 0x80
-PCRE2_ERROR_UTF8_ERR7 3rd-byte's two top bits are not 0x80
-PCRE2_ERROR_UTF8_ERR8 4th-byte's two top bits are not 0x80
-PCRE2_ERROR_UTF8_ERR9 5th-byte's two top bits are not 0x80
-PCRE2_ERROR_UTF8_ERR10 6th-byte's two top bits are not 0x80
-PCRE2_ERROR_UTF8_ERR11 5-byte character is not permitted by RFC 3629
-PCRE2_ERROR_UTF8_ERR12 6-byte character is not permitted by RFC 3629
-PCRE2_ERROR_UTF8_ERR13 4-byte character with value > 0x10ffff is not permitted
-PCRE2_ERROR_UTF8_ERR14 3-byte character with value 0xd800-0xdfff is not permitted
-PCRE2_ERROR_UTF8_ERR15 Overlong 2-byte sequence
-PCRE2_ERROR_UTF8_ERR16 Overlong 3-byte sequence
-PCRE2_ERROR_UTF8_ERR17 Overlong 4-byte sequence
-PCRE2_ERROR_UTF8_ERR18 Overlong 5-byte sequence (won't ever occur)
-PCRE2_ERROR_UTF8_ERR19 Overlong 6-byte sequence (won't ever occur)
-PCRE2_ERROR_UTF8_ERR20 Isolated 0x80 byte (not within UTF-8 character)
-PCRE2_ERROR_UTF8_ERR21 Byte with the illegal value 0xfe or 0xff
-*/
-
-for (p = string; length > 0; p++)
- {
- uint32_t ab, d;
-
- c = *p;
- length--;
-
- if (c < 128) continue; /* ASCII character */
-
- if (c < 0xc0) /* Isolated 10xx xxxx byte */
- {
- *erroroffset = (PCRE2_SIZE)(p - string);
- return PCRE2_ERROR_UTF8_ERR20;
- }
-
- if (c >= 0xfe) /* Invalid 0xfe or 0xff bytes */
- {
- *erroroffset = (PCRE2_SIZE)(p - string);
- return PCRE2_ERROR_UTF8_ERR21;
- }
-
- ab = PRIV(utf8_table4)[c & 0x3f]; /* Number of additional bytes (1-5) */
- if (length < ab) /* Missing bytes */
- {
- *erroroffset = (PCRE2_SIZE)(p - string);
- switch(ab - length)
- {
- case 1: return PCRE2_ERROR_UTF8_ERR1;
- case 2: return PCRE2_ERROR_UTF8_ERR2;
- case 3: return PCRE2_ERROR_UTF8_ERR3;
- case 4: return PCRE2_ERROR_UTF8_ERR4;
- case 5: return PCRE2_ERROR_UTF8_ERR5;
- }
- }
- length -= ab; /* Length remaining */
-
- /* Check top bits in the second byte */
-
- if (((d = *(++p)) & 0xc0) != 0x80)
- {
- *erroroffset = (int)(p - string) - 1;
- return PCRE2_ERROR_UTF8_ERR6;
- }
-
- /* For each length, check that the remaining bytes start with the 0x80 bit
- set and not the 0x40 bit. Then check for an overlong sequence, and for the
- excluded range 0xd800 to 0xdfff. */
-
- switch (ab)
- {
- /* 2-byte character. No further bytes to check for 0x80. Check first byte
- for for xx00 000x (overlong sequence). */
-
- case 1: if ((c & 0x3e) == 0)
- {
- *erroroffset = (int)(p - string) - 1;
- return PCRE2_ERROR_UTF8_ERR15;
- }
- break;
-
- /* 3-byte character. Check third byte for 0x80. Then check first 2 bytes
- for 1110 0000, xx0x xxxx (overlong sequence) or
- 1110 1101, 1010 xxxx (0xd800 - 0xdfff) */
-
- case 2:
- if ((*(++p) & 0xc0) != 0x80) /* Third byte */
- {
- *erroroffset = (int)(p - string) - 2;
- return PCRE2_ERROR_UTF8_ERR7;
- }
- if (c == 0xe0 && (d & 0x20) == 0)
- {
- *erroroffset = (int)(p - string) - 2;
- return PCRE2_ERROR_UTF8_ERR16;
- }
- if (c == 0xed && d >= 0xa0)
- {
- *erroroffset = (int)(p - string) - 2;
- return PCRE2_ERROR_UTF8_ERR14;
- }
- break;
-
- /* 4-byte character. Check 3rd and 4th bytes for 0x80. Then check first 2
- bytes for for 1111 0000, xx00 xxxx (overlong sequence), then check for a
- character greater than 0x0010ffff (f4 8f bf bf) */
-
- case 3:
- if ((*(++p) & 0xc0) != 0x80) /* Third byte */
- {
- *erroroffset = (int)(p - string) - 2;
- return PCRE2_ERROR_UTF8_ERR7;
- }
- if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
- {
- *erroroffset = (int)(p - string) - 3;
- return PCRE2_ERROR_UTF8_ERR8;
- }
- if (c == 0xf0 && (d & 0x30) == 0)
- {
- *erroroffset = (int)(p - string) - 3;
- return PCRE2_ERROR_UTF8_ERR17;
- }
- if (c > 0xf4 || (c == 0xf4 && d > 0x8f))
- {
- *erroroffset = (int)(p - string) - 3;
- return PCRE2_ERROR_UTF8_ERR13;
- }
- break;
-
- /* 5-byte and 6-byte characters are not allowed by RFC 3629, and will be
- rejected by the length test below. However, we do the appropriate tests
- here so that overlong sequences get diagnosed, and also in case there is
- ever an option for handling these larger code points. */
-
- /* 5-byte character. Check 3rd, 4th, and 5th bytes for 0x80. Then check for
- 1111 1000, xx00 0xxx */
-
- case 4:
- if ((*(++p) & 0xc0) != 0x80) /* Third byte */
- {
- *erroroffset = (int)(p - string) - 2;
- return PCRE2_ERROR_UTF8_ERR7;
- }
- if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
- {
- *erroroffset = (int)(p - string) - 3;
- return PCRE2_ERROR_UTF8_ERR8;
- }
- if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */
- {
- *erroroffset = (int)(p - string) - 4;
- return PCRE2_ERROR_UTF8_ERR9;
- }
- if (c == 0xf8 && (d & 0x38) == 0)
- {
- *erroroffset = (int)(p - string) - 4;
- return PCRE2_ERROR_UTF8_ERR18;
- }
- break;
-
- /* 6-byte character. Check 3rd-6th bytes for 0x80. Then check for
- 1111 1100, xx00 00xx. */
-
- case 5:
- if ((*(++p) & 0xc0) != 0x80) /* Third byte */
- {
- *erroroffset = (int)(p - string) - 2;
- return PCRE2_ERROR_UTF8_ERR7;
- }
- if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
- {
- *erroroffset = (int)(p - string) - 3;
- return PCRE2_ERROR_UTF8_ERR8;
- }
- if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */
- {
- *erroroffset = (int)(p - string) - 4;
- return PCRE2_ERROR_UTF8_ERR9;
- }
- if ((*(++p) & 0xc0) != 0x80) /* Sixth byte */
- {
- *erroroffset = (int)(p - string) - 5;
- return PCRE2_ERROR_UTF8_ERR10;
- }
- if (c == 0xfc && (d & 0x3c) == 0)
- {
- *erroroffset = (int)(p - string) - 5;
- return PCRE2_ERROR_UTF8_ERR19;
- }
- break;
- }
-
- /* Character is valid under RFC 2279, but 4-byte and 5-byte characters are
- excluded by RFC 3629. The pointer p is currently at the last byte of the
- character. */
-
- if (ab > 3)
- {
- *erroroffset = (int)(p - string) - ab;
- return (ab == 4)? PCRE2_ERROR_UTF8_ERR11 : PCRE2_ERROR_UTF8_ERR12;
- }
- }
-return 0;
-
-
-/* ----------------- Check a UTF-16 string ----------------- */
-
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-
-/* There's not so much work, nor so many errors, for UTF-16.
-PCRE2_ERROR_UTF16_ERR1 Missing low surrogate at the end of the string
-PCRE2_ERROR_UTF16_ERR2 Invalid low surrogate
-PCRE2_ERROR_UTF16_ERR3 Isolated low surrogate
-*/
-
-for (p = string; length > 0; p++)
- {
- c = *p;
- length--;
-
- if ((c & 0xf800) != 0xd800)
- {
- /* Normal UTF-16 code point. Neither high nor low surrogate. */
- }
- else if ((c & 0x0400) == 0)
- {
- /* High surrogate. Must be a followed by a low surrogate. */
- if (length == 0)
- {
- *erroroffset = p - string;
- return PCRE2_ERROR_UTF16_ERR1;
- }
- p++;
- length--;
- if ((*p & 0xfc00) != 0xdc00)
- {
- *erroroffset = p - string - 1;
- return PCRE2_ERROR_UTF16_ERR2;
- }
- }
- else
- {
- /* Isolated low surrogate. Always an error. */
- *erroroffset = p - string;
- return PCRE2_ERROR_UTF16_ERR3;
- }
- }
-return 0;
-
-
-
-/* ----------------- Check a UTF-32 string ----------------- */
-
-#else
-
-/* There is very little to do for a UTF-32 string.
-PCRE2_ERROR_UTF32_ERR1 Surrogate character
-PCRE2_ERROR_UTF32_ERR2 Character > 0x10ffff
-*/
-
-for (p = string; length > 0; length--, p++)
- {
- c = *p;
- if ((c & 0xfffff800u) != 0xd800u)
- {
- /* Normal UTF-32 code point. Neither high nor low surrogate. */
- if (c > 0x10ffffu)
- {
- *erroroffset = p - string;
- return PCRE2_ERROR_UTF32_ERR2;
- }
- }
- else
- {
- /* A surrogate */
- *erroroffset = p - string;
- return PCRE2_ERROR_UTF32_ERR1;
- }
- }
-return 0;
-#endif /* CODE_UNIT_WIDTH */
-}
-#endif /* SUPPORT_UNICODE */
-
-/* End of pcre2_valid_utf.c */
diff --git a/contrib/libs/pcre2/src/pcre2_xclass.c b/contrib/libs/pcre2/src/pcre2_xclass.c
deleted file mode 100644
index cd9331c33b..0000000000
--- a/contrib/libs/pcre2/src/pcre2_xclass.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2022 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-/* This module contains an internal function that is used to match an extended
-class. It is used by pcre2_auto_possessify() and by both pcre2_match() and
-pcre2_def_match(). */
-
-
-#ifdef HAVE_CONFIG_H
-#include <pcre2_config.h>
-#endif
-
-
-#include "pcre2_internal.h"
-
-/*************************************************
-* Match character against an XCLASS *
-*************************************************/
-
-/* This function is called to match a character against an extended class that
-might contain codepoints above 255 and/or Unicode properties.
-
-Arguments:
- c the character
- data points to the flag code unit of the XCLASS data
- utf TRUE if in UTF mode
-
-Returns: TRUE if character matches, else FALSE
-*/
-
-BOOL
-PRIV(xclass)(uint32_t c, PCRE2_SPTR data, BOOL utf)
-{
-PCRE2_UCHAR t;
-BOOL negated = (*data & XCL_NOT) != 0;
-
-#if PCRE2_CODE_UNIT_WIDTH == 8
-/* In 8 bit mode, this must always be TRUE. Help the compiler to know that. */
-utf = TRUE;
-#endif
-
-/* Code points < 256 are matched against a bitmap, if one is present. If not,
-we still carry on, because there may be ranges that start below 256 in the
-additional data. */
-
-if (c < 256)
- {
- if ((*data & XCL_HASPROP) == 0)
- {
- if ((*data & XCL_MAP) == 0) return negated;
- return (((uint8_t *)(data + 1))[c/8] & (1u << (c&7))) != 0;
- }
- if ((*data & XCL_MAP) != 0 &&
- (((uint8_t *)(data + 1))[c/8] & (1u << (c&7))) != 0)
- return !negated; /* char found */
- }
-
-/* First skip the bit map if present. Then match against the list of Unicode
-properties or large chars or ranges that end with a large char. We won't ever
-encounter XCL_PROP or XCL_NOTPROP when UTF support is not compiled. */
-
-if ((*data++ & XCL_MAP) != 0) data += 32 / sizeof(PCRE2_UCHAR);
-
-while ((t = *data++) != XCL_END)
- {
- uint32_t x, y;
- if (t == XCL_SINGLE)
- {
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- GETCHARINC(x, data); /* macro generates multiple statements */
- }
- else
-#endif
- x = *data++;
- if (c == x) return !negated;
- }
- else if (t == XCL_RANGE)
- {
-#ifdef SUPPORT_UNICODE
- if (utf)
- {
- GETCHARINC(x, data); /* macro generates multiple statements */
- GETCHARINC(y, data); /* macro generates multiple statements */
- }
- else
-#endif
- {
- x = *data++;
- y = *data++;
- }
- if (c >= x && c <= y) return !negated;
- }
-
-#ifdef SUPPORT_UNICODE
- else /* XCL_PROP & XCL_NOTPROP */
- {
- const ucd_record *prop = GET_UCD(c);
- BOOL isprop = t == XCL_PROP;
- BOOL ok;
-
- switch(*data)
- {
- case PT_ANY:
- if (isprop) return !negated;
- break;
-
- case PT_LAMP:
- if ((prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
- prop->chartype == ucp_Lt) == isprop) return !negated;
- break;
-
- case PT_GC:
- if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == isprop)
- return !negated;
- break;
-
- case PT_PC:
- if ((data[1] == prop->chartype) == isprop) return !negated;
- break;
-
- case PT_SC:
- if ((data[1] == prop->script) == isprop) return !negated;
- break;
-
- case PT_SCX:
- ok = (data[1] == prop->script ||
- MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), data[1]) != 0);
- if (ok == isprop) return !negated;
- break;
-
- case PT_ALNUM:
- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N) == isprop)
- return !negated;
- break;
-
- /* Perl space used to exclude VT, but from Perl 5.18 it is included,
- which means that Perl space and POSIX space are now identical. PCRE
- was changed at release 8.34. */
-
- case PT_SPACE: /* Perl space */
- case PT_PXSPACE: /* POSIX space */
- switch(c)
- {
- HSPACE_CASES:
- VSPACE_CASES:
- if (isprop) return !negated;
- break;
-
- default:
- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == isprop)
- return !negated;
- break;
- }
- break;
-
- case PT_WORD:
- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE)
- == isprop)
- return !negated;
- break;
-
- case PT_UCNC:
- if (c < 0xa0)
- {
- if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
- c == CHAR_GRAVE_ACCENT) == isprop)
- return !negated;
- }
- else
- {
- if ((c < 0xd800 || c > 0xdfff) == isprop)
- return !negated;
- }
- break;
-
- case PT_BIDICL:
- if ((UCD_BIDICLASS_PROP(prop) == data[1]) == isprop)
- return !negated;
- break;
-
- case PT_BOOL:
- ok = MAPBIT(PRIV(ucd_boolprop_sets) +
- UCD_BPROPS_PROP(prop), data[1]) != 0;
- if (ok == isprop) return !negated;
- break;
-
- /* The following three properties can occur only in an XCLASS, as there
- is no \p or \P coding for them. */
-
- /* Graphic character. Implement this as not Z (space or separator) and
- not C (other), except for Cf (format) with a few exceptions. This seems
- to be what Perl does. The exceptional characters are:
-
- U+061C Arabic Letter Mark
- U+180E Mongolian Vowel Separator
- U+2066 - U+2069 Various "isolate"s
- */
-
- case PT_PXGRAPH:
- if ((PRIV(ucp_gentype)[prop->chartype] != ucp_Z &&
- (PRIV(ucp_gentype)[prop->chartype] != ucp_C ||
- (prop->chartype == ucp_Cf &&
- c != 0x061c && c != 0x180e && (c < 0x2066 || c > 0x2069))
- )) == isprop)
- return !negated;
- break;
-
- /* Printable character: same as graphic, with the addition of Zs, i.e.
- not Zl and not Zp, and U+180E. */
-
- case PT_PXPRINT:
- if ((prop->chartype != ucp_Zl &&
- prop->chartype != ucp_Zp &&
- (PRIV(ucp_gentype)[prop->chartype] != ucp_C ||
- (prop->chartype == ucp_Cf &&
- c != 0x061c && (c < 0x2066 || c > 0x2069))
- )) == isprop)
- return !negated;
- break;
-
- /* Punctuation: all Unicode punctuation, plus ASCII characters that
- Unicode treats as symbols rather than punctuation, for Perl
- compatibility (these are $+<=>^`|~). */
-
- case PT_PXPUNCT:
- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_P ||
- (c < 128 && PRIV(ucp_gentype)[prop->chartype] == ucp_S)) == isprop)
- return !negated;
- break;
-
- /* This should never occur, but compilers may mutter if there is no
- default. */
-
- default:
- return FALSE;
- }
-
- data += 2;
- }
-#else
- (void)utf; /* Avoid compiler warning */
-#endif /* SUPPORT_UNICODE */
- }
-
-return negated; /* char did not match */
-}
-
-/* End of pcre2_xclass.c */
diff --git a/contrib/libs/pcre2/src/sljit/sljitConfig.h b/contrib/libs/pcre2/src/sljit/sljitConfig.h
deleted file mode 100644
index 5fba7aa638..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitConfig.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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.
- */
-
-#ifndef SLJIT_CONFIG_H_
-#define SLJIT_CONFIG_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- This file contains the basic configuration options for the SLJIT compiler
- and their default values. These options can be overridden in the
- sljitConfigPre.h header file when SLJIT_HAVE_CONFIG_PRE is set to a
- non-zero value.
-*/
-
-/* --------------------------------------------------------------------- */
-/* Architecture */
-/* --------------------------------------------------------------------- */
-
-/* Architecture selection. */
-/* #define SLJIT_CONFIG_X86_32 1 */
-/* #define SLJIT_CONFIG_X86_64 1 */
-/* #define SLJIT_CONFIG_ARM_V5 1 */
-/* #define SLJIT_CONFIG_ARM_V7 1 */
-/* #define SLJIT_CONFIG_ARM_THUMB2 1 */
-/* #define SLJIT_CONFIG_ARM_64 1 */
-/* #define SLJIT_CONFIG_PPC_32 1 */
-/* #define SLJIT_CONFIG_PPC_64 1 */
-/* #define SLJIT_CONFIG_MIPS_32 1 */
-/* #define SLJIT_CONFIG_MIPS_64 1 */
-/* #define SLJIT_CONFIG_RISCV_32 1 */
-/* #define SLJIT_CONFIG_RISCV_64 1 */
-/* #define SLJIT_CONFIG_S390X 1 */
-
-/* #define SLJIT_CONFIG_AUTO 1 */
-/* #define SLJIT_CONFIG_UNSUPPORTED 1 */
-
-/* --------------------------------------------------------------------- */
-/* Utilities */
-/* --------------------------------------------------------------------- */
-
-/* Implements a stack like data structure (by using mmap / VirtualAlloc */
-/* or a custom allocator). */
-#ifndef SLJIT_UTIL_STACK
-/* Enabled by default */
-#define SLJIT_UTIL_STACK 1
-#endif
-
-/* Uses user provided allocator to allocate the stack (see SLJIT_UTIL_STACK) */
-#ifndef SLJIT_UTIL_SIMPLE_STACK_ALLOCATION
-/* Disabled by default */
-#define SLJIT_UTIL_SIMPLE_STACK_ALLOCATION 0
-#endif
-
-/* Single threaded application. Does not require any locks. */
-#ifndef SLJIT_SINGLE_THREADED
-/* Disabled by default. */
-#define SLJIT_SINGLE_THREADED 0
-#endif
-
-/* --------------------------------------------------------------------- */
-/* Configuration */
-/* --------------------------------------------------------------------- */
-
-/* If SLJIT_STD_MACROS_DEFINED is not defined, the application should
- define SLJIT_MALLOC, SLJIT_FREE, SLJIT_MEMCPY, and NULL. */
-#ifndef SLJIT_STD_MACROS_DEFINED
-/* Disabled by default. */
-#define SLJIT_STD_MACROS_DEFINED 0
-#endif
-
-/* Executable code allocation:
- If SLJIT_EXECUTABLE_ALLOCATOR is not defined, the application should
- define SLJIT_MALLOC_EXEC, SLJIT_FREE_EXEC, and SLJIT_EXEC_OFFSET. */
-#ifndef SLJIT_EXECUTABLE_ALLOCATOR
-/* Enabled by default. */
-#define SLJIT_EXECUTABLE_ALLOCATOR 1
-
-/* When SLJIT_PROT_EXECUTABLE_ALLOCATOR is enabled SLJIT uses
- an allocator which does not set writable and executable
- permission flags at the same time.
- Instead, it creates a shared memory segment (usually backed by a file)
- and maps it twice, with different permissions, depending on the use
- case.
- The trade-off is increased use of virtual memory, incompatibility with
- fork(), and some possible additional security risks by the use of
- publicly accessible files for the generated code. */
-#ifndef SLJIT_PROT_EXECUTABLE_ALLOCATOR
-/* Disabled by default. */
-#define SLJIT_PROT_EXECUTABLE_ALLOCATOR 0
-#endif
-
-/* When SLJIT_WX_EXECUTABLE_ALLOCATOR is enabled SLJIT uses an
- allocator which does not set writable and executable permission
- flags at the same time.
- Instead, it creates a new independent map on each invocation and
- switches permissions at the underlying pages as needed.
- The trade-off is increased memory use and degraded performance. */
-#ifndef SLJIT_WX_EXECUTABLE_ALLOCATOR
-/* Disabled by default. */
-#define SLJIT_WX_EXECUTABLE_ALLOCATOR 0
-#endif
-
-#endif /* !SLJIT_EXECUTABLE_ALLOCATOR */
-
-/* Return with error when an invalid argument is passed. */
-#ifndef SLJIT_ARGUMENT_CHECKS
-/* Disabled by default */
-#define SLJIT_ARGUMENT_CHECKS 0
-#endif
-
-/* Debug checks (assertions, etc.). */
-#ifndef SLJIT_DEBUG
-/* Enabled by default */
-#define SLJIT_DEBUG 1
-#endif
-
-/* Verbose operations. */
-#ifndef SLJIT_VERBOSE
-/* Enabled by default */
-#define SLJIT_VERBOSE 1
-#endif
-
-/*
- SLJIT_IS_FPU_AVAILABLE
- The availability of the FPU can be controlled by SLJIT_IS_FPU_AVAILABLE.
- zero value - FPU is NOT present.
- nonzero value - FPU is present.
-*/
-
-/* For further configurations, see the beginning of sljitConfigInternal.h */
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* SLJIT_CONFIG_H_ */
diff --git a/contrib/libs/pcre2/src/sljit/sljitConfigInternal.h b/contrib/libs/pcre2/src/sljit/sljitConfigInternal.h
deleted file mode 100644
index cd3ce69734..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitConfigInternal.h
+++ /dev/null
@@ -1,851 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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.
- */
-
-#ifndef SLJIT_CONFIG_INTERNAL_H_
-#define SLJIT_CONFIG_INTERNAL_H_
-
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
- || (defined SLJIT_DEBUG && SLJIT_DEBUG && (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE)))
-#include <stdio.h>
-#endif
-
-#if (defined SLJIT_DEBUG && SLJIT_DEBUG \
- && (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE) || !defined(SLJIT_HALT_PROCESS)))
-#include <stdlib.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- SLJIT defines the following architecture dependent types and macros:
-
- Types:
- sljit_s8, sljit_u8 : signed and unsigned 8 bit integer type
- sljit_s16, sljit_u16 : signed and unsigned 16 bit integer type
- sljit_s32, sljit_u32 : signed and unsigned 32 bit integer type
- sljit_sw, sljit_uw : signed and unsigned machine word, enough to store a pointer
- sljit_p : unsgined pointer value (usually the same as sljit_uw, but
- some 64 bit ABIs may use 32 bit pointers)
- sljit_f32 : 32 bit single precision floating point value
- sljit_f64 : 64 bit double precision floating point value
-
- Macros for feature detection (boolean):
- SLJIT_32BIT_ARCHITECTURE : 32 bit architecture
- SLJIT_64BIT_ARCHITECTURE : 64 bit architecture
- SLJIT_LITTLE_ENDIAN : little endian architecture
- SLJIT_BIG_ENDIAN : big endian architecture
- SLJIT_UNALIGNED : unaligned memory accesses for non-fpu operations are supported
- SLJIT_FPU_UNALIGNED : unaligned memory accesses for fpu operations are supported
- SLJIT_INDIRECT_CALL : see SLJIT_FUNC_ADDR() for more information
-
- Constants:
- SLJIT_NUMBER_OF_REGISTERS : number of available registers
- SLJIT_NUMBER_OF_SCRATCH_REGISTERS : number of available scratch registers
- SLJIT_NUMBER_OF_SAVED_REGISTERS : number of available saved registers
- SLJIT_NUMBER_OF_FLOAT_REGISTERS : number of available floating point registers
- SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS : number of available floating point scratch registers
- SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS : number of available floating point saved registers
- SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_sw/sljit_uw array by index
- SLJIT_F32_SHIFT : the shift required to apply when accessing
- a single precision floating point array by index
- SLJIT_F64_SHIFT : the shift required to apply when accessing
- a double precision floating point array by index
- SLJIT_PREF_SHIFT_REG : x86 systems prefers ecx for shifting by register
- the scratch register index of ecx is stored in this variable
- SLJIT_LOCALS_OFFSET : local space starting offset (SLJIT_SP + SLJIT_LOCALS_OFFSET)
- SLJIT_RETURN_ADDRESS_OFFSET : a return instruction always adds this offset to the return address
-
- Other macros:
- SLJIT_FUNC : calling convention attribute for both calling JIT from C and C calling back from JIT
- SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (platform independent helper)
-*/
-
-/*****************/
-/* Sanity check. */
-/*****************/
-
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
- + (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
- + (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
- + (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
- + (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
- + (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
- + (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
- + (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
- + (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
- + (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
- + (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) \
- + (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \
- + (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
- + (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \
- + (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2
-#error "Multiple architectures are selected"
-#endif
-
-#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
- && !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
- && !(defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
- && !(defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
- && !(defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
- && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
- && !(defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
- && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
- && !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
- && !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
- && !(defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) \
- && !(defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \
- && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
- && !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) \
- && !(defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO)
-#if defined SLJIT_CONFIG_AUTO && !SLJIT_CONFIG_AUTO
-#error "An architecture must be selected"
-#else /* SLJIT_CONFIG_AUTO */
-#define SLJIT_CONFIG_AUTO 1
-#endif /* !SLJIT_CONFIG_AUTO */
-#endif /* !SLJIT_CONFIG */
-
-/********************************************************/
-/* Automatic CPU detection (requires compiler support). */
-/********************************************************/
-
-#if (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO)
-
-#ifndef _WIN32
-
-#if defined(__i386__) || defined(__i386)
-#define SLJIT_CONFIG_X86_32 1
-#elif defined(__x86_64__)
-#define SLJIT_CONFIG_X86_64 1
-#elif defined(__arm__) || defined(__ARM__)
-#ifdef __thumb2__
-#define SLJIT_CONFIG_ARM_THUMB2 1
-#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__)
-#define SLJIT_CONFIG_ARM_V7 1
-#else
-#define SLJIT_CONFIG_ARM_V5 1
-#endif
-#elif defined (__aarch64__)
-#define SLJIT_CONFIG_ARM_64 1
-#elif defined(__ppc64__) || defined(__powerpc64__) || (defined(_ARCH_PPC64) && defined(__64BIT__)) || (defined(_POWER) && defined(__64BIT__))
-#define SLJIT_CONFIG_PPC_64 1
-#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(_ARCH_PWR) || defined(_ARCH_PWR2) || defined(_POWER)
-#define SLJIT_CONFIG_PPC_32 1
-#elif defined(__mips__) && !defined(_LP64)
-#define SLJIT_CONFIG_MIPS_32 1
-#elif defined(__mips64)
-#define SLJIT_CONFIG_MIPS_64 1
-#elif defined (__riscv_xlen) && (__riscv_xlen == 32)
-#define SLJIT_CONFIG_RISCV_32 1
-#elif defined (__riscv_xlen) && (__riscv_xlen == 64)
-#define SLJIT_CONFIG_RISCV_64 1
-#elif defined(__s390x__)
-#define SLJIT_CONFIG_S390X 1
-#else
-/* Unsupported architecture */
-#define SLJIT_CONFIG_UNSUPPORTED 1
-#endif
-
-#else /* _WIN32 */
-
-#if defined(_M_X64) || defined(__x86_64__)
-#define SLJIT_CONFIG_X86_64 1
-#elif (defined(_M_ARM) && _M_ARM >= 7 && defined(_M_ARMT)) || defined(__thumb2__)
-#define SLJIT_CONFIG_ARM_THUMB2 1
-#elif (defined(_M_ARM) && _M_ARM >= 7)
-#define SLJIT_CONFIG_ARM_V7 1
-#elif defined(_ARM_)
-#define SLJIT_CONFIG_ARM_V5 1
-#elif defined(_M_ARM64) || defined(__aarch64__)
-#define SLJIT_CONFIG_ARM_64 1
-#else
-#define SLJIT_CONFIG_X86_32 1
-#endif
-
-#endif /* !_WIN32 */
-#endif /* SLJIT_CONFIG_AUTO */
-
-#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
-#undef SLJIT_EXECUTABLE_ALLOCATOR
-#endif
-
-/******************************/
-/* CPU family type detection. */
-/******************************/
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
- || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
-#define SLJIT_CONFIG_ARM_32 1
-#endif
-
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-#define SLJIT_CONFIG_X86 1
-#elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
-#define SLJIT_CONFIG_ARM 1
-#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
-#define SLJIT_CONFIG_PPC 1
-#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
-#define SLJIT_CONFIG_MIPS 1
-#elif (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) || (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
-#define SLJIT_CONFIG_RISCV 1
-#endif
-
-/***********************************************************/
-/* Intel Control-flow Enforcement Technology (CET) spport. */
-/***********************************************************/
-
-#ifdef SLJIT_CONFIG_X86
-
-#if defined(__CET__) && !(defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET)
-#define SLJIT_CONFIG_X86_CET 1
-#endif
-
-#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined(__GNUC__)
-#include <x86intrin.h>
-#endif
-
-#endif /* SLJIT_CONFIG_X86 */
-
-/**********************************/
-/* External function definitions. */
-/**********************************/
-
-/* General macros:
- Note: SLJIT is designed to be independent from them as possible.
-
- In release mode (SLJIT_DEBUG is not defined) only the following
- external functions are needed:
-*/
-
-#ifndef SLJIT_MALLOC
-#define SLJIT_MALLOC(size, allocator_data) malloc(size)
-#endif
-
-#ifndef SLJIT_FREE
-#define SLJIT_FREE(ptr, allocator_data) free(ptr)
-#endif
-
-#ifndef SLJIT_MEMCPY
-#define SLJIT_MEMCPY(dest, src, len) memcpy(dest, src, len)
-#endif
-
-#ifndef SLJIT_MEMMOVE
-#define SLJIT_MEMMOVE(dest, src, len) memmove(dest, src, len)
-#endif
-
-#ifndef SLJIT_ZEROMEM
-#define SLJIT_ZEROMEM(dest, len) memset(dest, 0, len)
-#endif
-
-/***************************/
-/* Compiler helper macros. */
-/***************************/
-
-#if !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY)
-
-#if defined(__GNUC__) && (__GNUC__ >= 3)
-#define SLJIT_LIKELY(x) __builtin_expect((x), 1)
-#define SLJIT_UNLIKELY(x) __builtin_expect((x), 0)
-#else
-#define SLJIT_LIKELY(x) (x)
-#define SLJIT_UNLIKELY(x) (x)
-#endif
-
-#endif /* !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY) */
-
-#ifndef SLJIT_INLINE
-/* Inline functions. Some old compilers do not support them. */
-#ifdef __SUNPRO_C
-#if __SUNPRO_C < 0x560
-#define SLJIT_INLINE
-#else
-#define SLJIT_INLINE inline
-#endif /* __SUNPRO_C */
-#else
-#define SLJIT_INLINE __inline
-#endif
-#endif /* !SLJIT_INLINE */
-
-#ifndef SLJIT_NOINLINE
-/* Not inline functions. */
-#if defined(__GNUC__)
-#define SLJIT_NOINLINE __attribute__ ((noinline))
-#else
-#define SLJIT_NOINLINE
-#endif
-#endif /* !SLJIT_INLINE */
-
-#ifndef SLJIT_UNUSED_ARG
-/* Unused arguments. */
-#define SLJIT_UNUSED_ARG(arg) (void)arg
-#endif
-
-/*********************************/
-/* Type of public API functions. */
-/*********************************/
-
-#ifndef SLJIT_API_FUNC_ATTRIBUTE
-#if (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC)
-/* Static ABI functions. For all-in-one programs. */
-
-#if defined(__GNUC__)
-/* Disable unused warnings in gcc. */
-#define SLJIT_API_FUNC_ATTRIBUTE static __attribute__((unused))
-#else
-#define SLJIT_API_FUNC_ATTRIBUTE static
-#endif
-
-#else
-#define SLJIT_API_FUNC_ATTRIBUTE
-#endif /* (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC) */
-#endif /* defined SLJIT_API_FUNC_ATTRIBUTE */
-
-/****************************/
-/* Instruction cache flush. */
-/****************************/
-
-/*
- * TODO:
- *
- * clang >= 15 could be safe to enable below
- * older versions are known to abort in some targets
- * https://github.com/PhilipHazel/pcre2/issues/92
- *
- * beware some vendors (ex: Microsoft, Apple) are known to have
- * removed the code to support this builtin even if the call for
- * __has_builtin reports it is available.
- *
- * make sure linking doesn't fail because __clear_cache() is
- * missing before changing it or add an exception so that the
- * system provided method that should be defined below is used
- * instead.
- */
-#if (!defined SLJIT_CACHE_FLUSH && defined __has_builtin)
-#if __has_builtin(__builtin___clear_cache) && !defined(__clang__)
-
-/*
- * https://gcc.gnu.org/bugzilla//show_bug.cgi?id=91248
- * https://gcc.gnu.org/bugzilla//show_bug.cgi?id=93811
- * gcc's clear_cache builtin for power is broken
- */
-#if !defined(SLJIT_CONFIG_PPC)
-#define SLJIT_CACHE_FLUSH(from, to) \
- __builtin___clear_cache((char*)(from), (char*)(to))
-#endif
-
-#endif /* gcc >= 10 */
-#endif /* (!defined SLJIT_CACHE_FLUSH && defined __has_builtin) */
-
-#ifndef SLJIT_CACHE_FLUSH
-
-#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
- || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
-
-/* Not required to implement on archs with unified caches. */
-#define SLJIT_CACHE_FLUSH(from, to)
-
-#elif defined __APPLE__
-
-/* Supported by all macs since Mac OS 10.5.
- However, it does not work on non-jailbroken iOS devices,
- although the compilation is successful. */
-#include <libkern/OSCacheControl.h>
-#define SLJIT_CACHE_FLUSH(from, to) \
- sys_icache_invalidate((void*)(from), (size_t)((char*)(to) - (char*)(from)))
-
-#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
-
-/* The __clear_cache() implementation of GCC is a dummy function on PowerPC. */
-#define SLJIT_CACHE_FLUSH(from, to) \
- ppc_cache_flush((from), (to))
-#define SLJIT_CACHE_FLUSH_OWN_IMPL 1
-
-#elif defined(_WIN32)
-
-#define SLJIT_CACHE_FLUSH(from, to) \
- FlushInstructionCache(GetCurrentProcess(), (void*)(from), (char*)(to) - (char*)(from))
-
-#elif (defined(__GNUC__) && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || defined(__clang__)
-
-#define SLJIT_CACHE_FLUSH(from, to) \
- __builtin___clear_cache((char*)(from), (char*)(to))
-
-#elif defined __ANDROID__
-
-/* Android ARMv7 with gcc lacks __clear_cache; use cacheflush instead. */
-#include <sys/cachectl.h>
-#define SLJIT_CACHE_FLUSH(from, to) \
- cacheflush((long)(from), (long)(to), 0)
-
-#else
-
-/* Call __ARM_NR_cacheflush on ARM-Linux or the corresponding MIPS syscall. */
-#define SLJIT_CACHE_FLUSH(from, to) \
- __clear_cache((char*)(from), (char*)(to))
-
-#endif
-
-#endif /* !SLJIT_CACHE_FLUSH */
-
-/******************************************************/
-/* Integer and floating point type definitions. */
-/******************************************************/
-
-/* 8 bit byte type. */
-typedef unsigned char sljit_u8;
-typedef signed char sljit_s8;
-
-/* 16 bit half-word type. */
-typedef unsigned short int sljit_u16;
-typedef signed short int sljit_s16;
-
-/* 32 bit integer type. */
-typedef unsigned int sljit_u32;
-typedef signed int sljit_s32;
-
-/* Machine word type. Enough for storing a pointer.
- 32 bit for 32 bit machines.
- 64 bit for 64 bit machines. */
-#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
-/* Just to have something. */
-#define SLJIT_WORD_SHIFT 0
-typedef unsigned long int sljit_uw;
-typedef long int sljit_sw;
-#elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
- && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
- && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
- && !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
- && !(defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \
- && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
-#define SLJIT_32BIT_ARCHITECTURE 1
-#define SLJIT_WORD_SHIFT 2
-typedef unsigned int sljit_uw;
-typedef int sljit_sw;
-#else
-#define SLJIT_64BIT_ARCHITECTURE 1
-#define SLJIT_WORD_SHIFT 3
-#ifdef _WIN32
-#ifdef __GNUC__
-/* These types do not require windows.h */
-typedef unsigned long long sljit_uw;
-typedef long long sljit_sw;
-#else
-typedef unsigned __int64 sljit_uw;
-typedef __int64 sljit_sw;
-#endif
-#else /* !_WIN32 */
-typedef unsigned long int sljit_uw;
-typedef long int sljit_sw;
-#endif /* _WIN32 */
-#endif
-
-typedef sljit_uw sljit_p;
-
-/* Floating point types. */
-typedef float sljit_f32;
-typedef double sljit_f64;
-
-/* Shift for pointer sized data. */
-#define SLJIT_POINTER_SHIFT SLJIT_WORD_SHIFT
-
-/* Shift for double precision sized data. */
-#define SLJIT_F32_SHIFT 2
-#define SLJIT_F64_SHIFT 3
-
-#ifndef SLJIT_W
-
-/* Defining long constants. */
-#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
-#define SLJIT_W(w) (w##l)
-#elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
-#ifdef _WIN64
-#define SLJIT_W(w) (w##ll)
-#else /* !windows */
-#define SLJIT_W(w) (w##l)
-#endif /* windows */
-#else /* 32 bit */
-#define SLJIT_W(w) (w)
-#endif /* unknown */
-
-#endif /* !SLJIT_W */
-
-/*************************/
-/* Endianness detection. */
-/*************************/
-
-#if !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN)
-
-/* These macros are mostly useful for the applications. */
-#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
-
-#ifdef __LITTLE_ENDIAN__
-#define SLJIT_LITTLE_ENDIAN 1
-#else
-#define SLJIT_BIG_ENDIAN 1
-#endif
-
-#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
-
-#ifdef __MIPSEL__
-#define SLJIT_LITTLE_ENDIAN 1
-#else
-#define SLJIT_BIG_ENDIAN 1
-#endif
-
-#ifndef SLJIT_MIPS_REV
-
-/* Auto detecting mips revision. */
-#if (defined __mips_isa_rev) && (__mips_isa_rev >= 6)
-#define SLJIT_MIPS_REV 6
-#elif (defined __mips_isa_rev && __mips_isa_rev >= 1) \
- || (defined __clang__ && defined _MIPS_ARCH_OCTEON) \
- || (defined __clang__ && defined _MIPS_ARCH_P5600)
-/* clang either forgets to define (clang-7) __mips_isa_rev at all
- * or sets it to zero (clang-8,-9) for -march=octeon (MIPS64 R2+)
- * and -march=p5600 (MIPS32 R5).
- * It also sets the __mips macro to 64 or 32 for -mipsN when N <= 5
- * (should be set to N exactly) so we cannot rely on this too.
- */
-#define SLJIT_MIPS_REV 1
-#endif
-
-#endif /* !SLJIT_MIPS_REV */
-
-#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
-
-#define SLJIT_BIG_ENDIAN 1
-
-#else
-#define SLJIT_LITTLE_ENDIAN 1
-#endif
-
-#endif /* !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN) */
-
-/* Sanity check. */
-#if (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
-#error "Exactly one endianness must be selected"
-#endif
-
-#if !(defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && !(defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
-#error "Exactly one endianness must be selected"
-#endif
-
-#ifndef SLJIT_UNALIGNED
-
-#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
- || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
- || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
- || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
- || (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \
- || (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \
- || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
-#define SLJIT_UNALIGNED 1
-#endif
-
-#endif /* !SLJIT_UNALIGNED */
-
-#ifndef SLJIT_FPU_UNALIGNED
-
-#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
- || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
- || (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \
- || (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \
- || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
-#define SLJIT_FPU_UNALIGNED 1
-#endif
-
-#endif /* !SLJIT_FPU_UNALIGNED */
-
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-/* Auto detect SSE2 support using CPUID.
- On 64 bit x86 cpus, sse2 must be present. */
-#define SLJIT_DETECT_SSE2 1
-#endif
-
-/*****************************************************************************************/
-/* Calling convention of functions generated by SLJIT or called from the generated code. */
-/*****************************************************************************************/
-
-#ifndef SLJIT_FUNC
-#define SLJIT_FUNC
-#endif /* !SLJIT_FUNC */
-
-#ifndef SLJIT_INDIRECT_CALL
-#if ((defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) && (!defined _CALL_ELF || _CALL_ELF == 1)) \
- || ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && defined _AIX)
-/* It seems certain ppc compilers use an indirect addressing for functions
- which makes things complicated. */
-#define SLJIT_INDIRECT_CALL 1
-#endif
-#endif /* SLJIT_INDIRECT_CALL */
-
-/* The offset which needs to be subtracted from the return address to
-determine the next executed instruction after return. */
-#ifndef SLJIT_RETURN_ADDRESS_OFFSET
-#define SLJIT_RETURN_ADDRESS_OFFSET 0
-#endif /* SLJIT_RETURN_ADDRESS_OFFSET */
-
-/***************************************************/
-/* Functions of the built-in executable allocator. */
-/***************************************************/
-
-#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size);
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr);
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void);
-#define SLJIT_BUILTIN_MALLOC_EXEC(size, exec_allocator_data) sljit_malloc_exec(size)
-#define SLJIT_BUILTIN_FREE_EXEC(ptr, exec_allocator_data) sljit_free_exec(ptr)
-
-#ifndef SLJIT_MALLOC_EXEC
-#define SLJIT_MALLOC_EXEC(size, exec_allocator_data) SLJIT_BUILTIN_MALLOC_EXEC((size), (exec_allocator_data))
-#endif /* SLJIT_MALLOC_EXEC */
-
-#ifndef SLJIT_FREE_EXEC
-#define SLJIT_FREE_EXEC(ptr, exec_allocator_data) SLJIT_BUILTIN_FREE_EXEC((ptr), (exec_allocator_data))
-#endif /* SLJIT_FREE_EXEC */
-
-#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
-SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
-#define SLJIT_EXEC_OFFSET(ptr) sljit_exec_offset(ptr)
-#else
-#define SLJIT_EXEC_OFFSET(ptr) 0
-#endif
-
-#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
-
-/**********************************************/
-/* Registers and locals offset determination. */
-/**********************************************/
-
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-
-#define SLJIT_NUMBER_OF_REGISTERS 12
-#define SLJIT_NUMBER_OF_SAVED_REGISTERS 7
-#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 7
-#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0
-#define SLJIT_LOCALS_OFFSET_BASE (8 * SSIZE_OF(sw))
-#define SLJIT_PREF_SHIFT_REG SLJIT_R2
-
-#elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-
-#define SLJIT_NUMBER_OF_REGISTERS 13
-#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 15
-#ifndef _WIN64
-#define SLJIT_NUMBER_OF_SAVED_REGISTERS 6
-#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0
-#define SLJIT_LOCALS_OFFSET_BASE 0
-#else /* _WIN64 */
-#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
-#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 10
-#define SLJIT_LOCALS_OFFSET_BASE (4 * SSIZE_OF(sw))
-#endif /* !_WIN64 */
-#define SLJIT_PREF_SHIFT_REG SLJIT_R3
-
-#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
-
-#define SLJIT_NUMBER_OF_REGISTERS 12
-#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
-#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 14
-#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
-#define SLJIT_LOCALS_OFFSET_BASE 0
-
-#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
-
-#define SLJIT_NUMBER_OF_REGISTERS 12
-#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
-#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 14
-#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
-#define SLJIT_LOCALS_OFFSET_BASE 0
-
-#elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
-
-#define SLJIT_NUMBER_OF_REGISTERS 26
-#define SLJIT_NUMBER_OF_SAVED_REGISTERS 10
-#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30
-#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
-#define SLJIT_LOCALS_OFFSET_BASE (2 * (sljit_s32)sizeof(sljit_sw))
-
-#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
-
-#define SLJIT_NUMBER_OF_REGISTERS 23
-#define SLJIT_NUMBER_OF_SAVED_REGISTERS 17
-#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30
-#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 18
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) || (defined _AIX)
-#define SLJIT_LOCALS_OFFSET_BASE ((6 + 8) * (sljit_s32)sizeof(sljit_sw))
-#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
-/* Add +1 for double alignment. */
-#define SLJIT_LOCALS_OFFSET_BASE ((3 + 1) * (sljit_s32)sizeof(sljit_sw))
-#else
-#define SLJIT_LOCALS_OFFSET_BASE (3 * (sljit_s32)sizeof(sljit_sw))
-#endif /* SLJIT_CONFIG_PPC_64 || _AIX */
-
-#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
-
-#define SLJIT_NUMBER_OF_REGISTERS 21
-#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
-#define SLJIT_LOCALS_OFFSET_BASE (4 * (sljit_s32)sizeof(sljit_sw))
-#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 13
-#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 6
-#else
-#define SLJIT_LOCALS_OFFSET_BASE 0
-#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 29
-#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
-#endif
-
-#elif (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
-
-#define SLJIT_NUMBER_OF_REGISTERS 23
-#define SLJIT_NUMBER_OF_SAVED_REGISTERS 12
-#define SLJIT_LOCALS_OFFSET_BASE 0
-#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30
-#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 12
-
-#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
-
-/*
- * https://refspecs.linuxbase.org/ELF/zSeries/lzsabi0_zSeries.html#STACKFRAME
- *
- * 160
- * .. FR6
- * .. FR4
- * .. FR2
- * 128 FR0
- * 120 R15 (used for SP)
- * 112 R14
- * 104 R13
- * 96 R12
- * ..
- * 48 R6
- * ..
- * 16 R2
- * 8 RESERVED
- * 0 SP
- */
-#define SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE 160
-
-#define SLJIT_NUMBER_OF_REGISTERS 12
-#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
-#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 15
-#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
-#define SLJIT_LOCALS_OFFSET_BASE SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE
-
-#elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
-
-#define SLJIT_NUMBER_OF_REGISTERS 0
-#define SLJIT_NUMBER_OF_SAVED_REGISTERS 0
-#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 0
-#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0
-#define SLJIT_LOCALS_OFFSET_BASE 0
-
-#endif
-
-#define SLJIT_LOCALS_OFFSET (SLJIT_LOCALS_OFFSET_BASE)
-
-#define SLJIT_NUMBER_OF_SCRATCH_REGISTERS \
- (SLJIT_NUMBER_OF_REGISTERS - SLJIT_NUMBER_OF_SAVED_REGISTERS)
-
-#define SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS \
- (SLJIT_NUMBER_OF_FLOAT_REGISTERS - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS)
-
-/********************************/
-/* CPU status flags management. */
-/********************************/
-
-#if (defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM) \
- || (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \
- || (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) \
- || (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \
- || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
-#define SLJIT_HAS_STATUS_FLAGS_STATE 1
-#endif
-
-/*************************************/
-/* Debug and verbose related macros. */
-/*************************************/
-
-#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
-
-#if !defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE)
-
-/* SLJIT_HALT_PROCESS must halt the process. */
-#ifndef SLJIT_HALT_PROCESS
-#define SLJIT_HALT_PROCESS() \
- abort();
-#endif /* !SLJIT_HALT_PROCESS */
-
-#endif /* !SLJIT_ASSERT || !SLJIT_UNREACHABLE */
-
-/* Feel free to redefine these two macros. */
-#ifndef SLJIT_ASSERT
-
-#define SLJIT_ASSERT(x) \
- do { \
- if (SLJIT_UNLIKELY(!(x))) { \
- printf("Assertion failed at " __FILE__ ":%d\n", __LINE__); \
- SLJIT_HALT_PROCESS(); \
- } \
- } while (0)
-
-#endif /* !SLJIT_ASSERT */
-
-#ifndef SLJIT_UNREACHABLE
-
-#define SLJIT_UNREACHABLE() \
- do { \
- printf("Should never been reached " __FILE__ ":%d\n", __LINE__); \
- SLJIT_HALT_PROCESS(); \
- } while (0)
-
-#endif /* !SLJIT_UNREACHABLE */
-
-#else /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */
-
-/* Forcing empty, but valid statements. */
-#undef SLJIT_ASSERT
-#undef SLJIT_UNREACHABLE
-
-#define SLJIT_ASSERT(x) \
- do { } while (0)
-#define SLJIT_UNREACHABLE() \
- do { } while (0)
-
-#endif /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */
-
-#ifndef SLJIT_COMPILE_ASSERT
-
-#define SLJIT_COMPILE_ASSERT(x, description) \
- switch(0) { case 0: case ((x) ? 1 : 0): break; }
-
-#endif /* !SLJIT_COMPILE_ASSERT */
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* SLJIT_CONFIG_INTERNAL_H_ */
diff --git a/contrib/libs/pcre2/src/sljit/sljitExecAllocator.c b/contrib/libs/pcre2/src/sljit/sljitExecAllocator.c
deleted file mode 100644
index 92d940ddc2..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitExecAllocator.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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.
- */
-
-/*
- This file contains a simple executable memory allocator
-
- It is assumed, that executable code blocks are usually medium (or sometimes
- large) memory blocks, and the allocator is not too frequently called (less
- optimized than other allocators). Thus, using it as a generic allocator is
- not suggested.
-
- How does it work:
- Memory is allocated in continuous memory areas called chunks by alloc_chunk()
- Chunk format:
- [ block ][ block ] ... [ block ][ block terminator ]
-
- All blocks and the block terminator is started with block_header. The block
- header contains the size of the previous and the next block. These sizes
- can also contain special values.
- Block size:
- 0 - The block is a free_block, with a different size member.
- 1 - The block is a block terminator.
- n - The block is used at the moment, and the value contains its size.
- Previous block size:
- 0 - This is the first block of the memory chunk.
- n - The size of the previous block.
-
- Using these size values we can go forward or backward on the block chain.
- The unused blocks are stored in a chain list pointed by free_blocks. This
- list is useful if we need to find a suitable memory area when the allocator
- is called.
-
- When a block is freed, the new free block is connected to its adjacent free
- blocks if possible.
-
- [ free block ][ used block ][ free block ]
- and "used block" is freed, the three blocks are connected together:
- [ one big free block ]
-*/
-
-/* --------------------------------------------------------------------- */
-/* System (OS) functions */
-/* --------------------------------------------------------------------- */
-
-/* 64 KByte. */
-#define CHUNK_SIZE (sljit_uw)0x10000u
-
-/*
- alloc_chunk / free_chunk :
- * allocate executable system memory chunks
- * the size is always divisible by CHUNK_SIZE
- SLJIT_ALLOCATOR_LOCK / SLJIT_ALLOCATOR_UNLOCK :
- * provided as part of sljitUtils
- * only the allocator requires this lock, sljit is fully thread safe
- as it only uses local variables
-*/
-
-#ifdef _WIN32
-#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
-
-static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
-{
- return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
-}
-
-static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
-{
- SLJIT_UNUSED_ARG(size);
- VirtualFree(chunk, 0, MEM_RELEASE);
-}
-
-#else /* POSIX */
-
-#if defined(__APPLE__) && defined(MAP_JIT)
-/*
- On macOS systems, returns MAP_JIT if it is defined _and_ we're running on a
- version where it's OK to have more than one JIT block or where MAP_JIT is
- required.
- On non-macOS systems, returns MAP_JIT if it is defined.
-*/
-#include <TargetConditionals.h>
-#if TARGET_OS_OSX
-#if defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86
-#ifdef MAP_ANON
-#include <sys/utsname.h>
-#include <stdlib.h>
-
-#define SLJIT_MAP_JIT (get_map_jit_flag())
-
-static SLJIT_INLINE int get_map_jit_flag()
-{
- size_t page_size;
- void *ptr;
- struct utsname name;
- static int map_jit_flag = -1;
-
- if (map_jit_flag < 0) {
- map_jit_flag = 0;
- uname(&name);
-
- /* Kernel version for 10.14.0 (Mojave) or later */
- if (atoi(name.release) >= 18) {
- page_size = get_page_alignment() + 1;
- /* Only use MAP_JIT if a hardened runtime is used */
- ptr = mmap(NULL, page_size, PROT_WRITE | PROT_EXEC,
- MAP_PRIVATE | MAP_ANON, -1, 0);
-
- if (ptr != MAP_FAILED)
- munmap(ptr, page_size);
- else
- map_jit_flag = MAP_JIT;
- }
- }
- return map_jit_flag;
-}
-#endif /* MAP_ANON */
-#else /* !SLJIT_CONFIG_X86 */
-#if !(defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM)
-#error "Unsupported architecture"
-#endif /* SLJIT_CONFIG_ARM */
-#include <AvailabilityMacros.h>
-#include <pthread.h>
-
-#define SLJIT_MAP_JIT (MAP_JIT)
-#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \
- apple_update_wx_flags(enable_exec)
-
-static SLJIT_INLINE void apple_update_wx_flags(sljit_s32 enable_exec)
-{
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= 110000
- pthread_jit_write_protect_np(enable_exec);
-#else
-#error "Must target Big Sur or newer"
-#endif /* BigSur */
-}
-#endif /* SLJIT_CONFIG_X86 */
-#else /* !TARGET_OS_OSX */
-#define SLJIT_MAP_JIT (MAP_JIT)
-#endif /* TARGET_OS_OSX */
-#endif /* __APPLE__ && MAP_JIT */
-#ifndef SLJIT_UPDATE_WX_FLAGS
-#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
-#endif /* !SLJIT_UPDATE_WX_FLAGS */
-#ifndef SLJIT_MAP_JIT
-#define SLJIT_MAP_JIT (0)
-#endif /* !SLJIT_MAP_JIT */
-
-static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
-{
- void *retval;
- int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
- int flags = MAP_PRIVATE;
- int fd = -1;
-
-#ifdef PROT_MAX
- prot |= PROT_MAX(prot);
-#endif
-
-#ifdef MAP_ANON
- flags |= MAP_ANON | SLJIT_MAP_JIT;
-#else /* !MAP_ANON */
- if (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero()))
- return NULL;
-
- fd = dev_zero;
-#endif /* MAP_ANON */
-
- retval = mmap(NULL, size, prot, flags, fd, 0);
- if (retval == MAP_FAILED)
- return NULL;
-
-#ifdef __FreeBSD__
- /* HardenedBSD's mmap lies, so check permissions again */
- if (mprotect(retval, size, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) {
- munmap(retval, size);
- return NULL;
- }
-#endif /* FreeBSD */
-
- SLJIT_UPDATE_WX_FLAGS(retval, (uint8_t *)retval + size, 0);
-
- return retval;
-}
-
-static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
-{
- munmap(chunk, size);
-}
-
-#endif /* windows */
-
-/* --------------------------------------------------------------------- */
-/* Common functions */
-/* --------------------------------------------------------------------- */
-
-#define CHUNK_MASK (~(CHUNK_SIZE - 1))
-
-struct block_header {
- sljit_uw size;
- sljit_uw prev_size;
-};
-
-struct free_block {
- struct block_header header;
- struct free_block *next;
- struct free_block *prev;
- sljit_uw size;
-};
-
-#define AS_BLOCK_HEADER(base, offset) \
- ((struct block_header*)(((sljit_u8*)base) + offset))
-#define AS_FREE_BLOCK(base, offset) \
- ((struct free_block*)(((sljit_u8*)base) + offset))
-#define MEM_START(base) ((void*)(((sljit_u8*)base) + sizeof(struct block_header)))
-#define ALIGN_SIZE(size) (((size) + sizeof(struct block_header) + 7u) & ~(sljit_uw)7)
-
-static struct free_block* free_blocks;
-static sljit_uw allocated_size;
-static sljit_uw total_size;
-
-static SLJIT_INLINE void sljit_insert_free_block(struct free_block *free_block, sljit_uw size)
-{
- free_block->header.size = 0;
- free_block->size = size;
-
- free_block->next = free_blocks;
- free_block->prev = NULL;
- if (free_blocks)
- free_blocks->prev = free_block;
- free_blocks = free_block;
-}
-
-static SLJIT_INLINE void sljit_remove_free_block(struct free_block *free_block)
-{
- if (free_block->next)
- free_block->next->prev = free_block->prev;
-
- if (free_block->prev)
- free_block->prev->next = free_block->next;
- else {
- SLJIT_ASSERT(free_blocks == free_block);
- free_blocks = free_block->next;
- }
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
-{
- struct block_header *header;
- struct block_header *next_header;
- struct free_block *free_block;
- sljit_uw chunk_size;
-
- SLJIT_ALLOCATOR_LOCK();
- if (size < (64 - sizeof(struct block_header)))
- size = (64 - sizeof(struct block_header));
- size = ALIGN_SIZE(size);
-
- free_block = free_blocks;
- while (free_block) {
- if (free_block->size >= size) {
- chunk_size = free_block->size;
- SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0);
- if (chunk_size > size + 64) {
- /* We just cut a block from the end of the free block. */
- chunk_size -= size;
- free_block->size = chunk_size;
- header = AS_BLOCK_HEADER(free_block, chunk_size);
- header->prev_size = chunk_size;
- AS_BLOCK_HEADER(header, size)->prev_size = size;
- }
- else {
- sljit_remove_free_block(free_block);
- header = (struct block_header*)free_block;
- size = chunk_size;
- }
- allocated_size += size;
- header->size = size;
- SLJIT_ALLOCATOR_UNLOCK();
- return MEM_START(header);
- }
- free_block = free_block->next;
- }
-
- chunk_size = (size + sizeof(struct block_header) + CHUNK_SIZE - 1) & CHUNK_MASK;
- header = (struct block_header*)alloc_chunk(chunk_size);
- if (!header) {
- SLJIT_ALLOCATOR_UNLOCK();
- return NULL;
- }
-
- chunk_size -= sizeof(struct block_header);
- total_size += chunk_size;
-
- header->prev_size = 0;
- if (chunk_size > size + 64) {
- /* Cut the allocated space into a free and a used block. */
- allocated_size += size;
- header->size = size;
- chunk_size -= size;
-
- free_block = AS_FREE_BLOCK(header, size);
- free_block->header.prev_size = size;
- sljit_insert_free_block(free_block, chunk_size);
- next_header = AS_BLOCK_HEADER(free_block, chunk_size);
- }
- else {
- /* All space belongs to this allocation. */
- allocated_size += chunk_size;
- header->size = chunk_size;
- next_header = AS_BLOCK_HEADER(header, chunk_size);
- }
- next_header->size = 1;
- next_header->prev_size = chunk_size;
- SLJIT_ALLOCATOR_UNLOCK();
- return MEM_START(header);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
-{
- struct block_header *header;
- struct free_block* free_block;
-
- SLJIT_ALLOCATOR_LOCK();
- header = AS_BLOCK_HEADER(ptr, -(sljit_sw)sizeof(struct block_header));
- allocated_size -= header->size;
-
- /* Connecting free blocks together if possible. */
- SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0);
-
- /* If header->prev_size == 0, free_block will equal to header.
- In this case, free_block->header.size will be > 0. */
- free_block = AS_FREE_BLOCK(header, -(sljit_sw)header->prev_size);
- if (SLJIT_UNLIKELY(!free_block->header.size)) {
- free_block->size += header->size;
- header = AS_BLOCK_HEADER(free_block, free_block->size);
- header->prev_size = free_block->size;
- }
- else {
- free_block = (struct free_block*)header;
- sljit_insert_free_block(free_block, header->size);
- }
-
- header = AS_BLOCK_HEADER(free_block, free_block->size);
- if (SLJIT_UNLIKELY(!header->size)) {
- free_block->size += ((struct free_block*)header)->size;
- sljit_remove_free_block((struct free_block*)header);
- header = AS_BLOCK_HEADER(free_block, free_block->size);
- header->prev_size = free_block->size;
- }
-
- /* The whole chunk is free. */
- if (SLJIT_UNLIKELY(!free_block->header.prev_size && header->size == 1)) {
- /* If this block is freed, we still have (allocated_size / 2) free space. */
- if (total_size - free_block->size > (allocated_size * 3 / 2)) {
- total_size -= free_block->size;
- sljit_remove_free_block(free_block);
- free_chunk(free_block, free_block->size + sizeof(struct block_header));
- }
- }
-
- SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 1);
- SLJIT_ALLOCATOR_UNLOCK();
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
-{
- struct free_block* free_block;
- struct free_block* next_free_block;
-
- SLJIT_ALLOCATOR_LOCK();
- SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0);
-
- free_block = free_blocks;
- while (free_block) {
- next_free_block = free_block->next;
- if (!free_block->header.prev_size &&
- AS_BLOCK_HEADER(free_block, free_block->size)->size == 1) {
- total_size -= free_block->size;
- sljit_remove_free_block(free_block);
- free_chunk(free_block, free_block->size + sizeof(struct block_header));
- }
- free_block = next_free_block;
- }
-
- SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks));
- SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 1);
- SLJIT_ALLOCATOR_UNLOCK();
-}
diff --git a/contrib/libs/pcre2/src/sljit/sljitLir.c b/contrib/libs/pcre2/src/sljit/sljitLir.c
deleted file mode 100644
index abafe1add9..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitLir.c
+++ /dev/null
@@ -1,3136 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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 "sljitLir.h"
-
-#ifdef _WIN32
-
-#include <windows.h>
-
-#endif /* _WIN32 */
-
-#if !(defined SLJIT_STD_MACROS_DEFINED && SLJIT_STD_MACROS_DEFINED)
-
-/* These libraries are needed for the macros below. */
-#include <stdlib.h>
-#include <string.h>
-
-#endif /* SLJIT_STD_MACROS_DEFINED */
-
-#define CHECK_ERROR() \
- do { \
- if (SLJIT_UNLIKELY(compiler->error)) \
- return compiler->error; \
- } while (0)
-
-#define CHECK_ERROR_PTR() \
- do { \
- if (SLJIT_UNLIKELY(compiler->error)) \
- return NULL; \
- } while (0)
-
-#define FAIL_IF(expr) \
- do { \
- if (SLJIT_UNLIKELY(expr)) \
- return compiler->error; \
- } while (0)
-
-#define PTR_FAIL_IF(expr) \
- do { \
- if (SLJIT_UNLIKELY(expr)) \
- return NULL; \
- } while (0)
-
-#define FAIL_IF_NULL(ptr) \
- do { \
- if (SLJIT_UNLIKELY(!(ptr))) { \
- compiler->error = SLJIT_ERR_ALLOC_FAILED; \
- return SLJIT_ERR_ALLOC_FAILED; \
- } \
- } while (0)
-
-#define PTR_FAIL_IF_NULL(ptr) \
- do { \
- if (SLJIT_UNLIKELY(!(ptr))) { \
- compiler->error = SLJIT_ERR_ALLOC_FAILED; \
- return NULL; \
- } \
- } while (0)
-
-#define PTR_FAIL_WITH_EXEC_IF(ptr) \
- do { \
- if (SLJIT_UNLIKELY(!(ptr))) { \
- compiler->error = SLJIT_ERR_EX_ALLOC_FAILED; \
- return NULL; \
- } \
- } while (0)
-
-#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
-
-#define SSIZE_OF(type) ((sljit_s32)sizeof(sljit_ ## type))
-
-#define VARIABLE_FLAG_SHIFT (10)
-#define VARIABLE_FLAG_MASK (0x3f << VARIABLE_FLAG_SHIFT)
-#define GET_FLAG_TYPE(op) ((op) >> VARIABLE_FLAG_SHIFT)
-
-#define GET_OPCODE(op) \
- ((op) & ~(SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK))
-
-#define HAS_FLAGS(op) \
- ((op) & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))
-
-#define GET_ALL_FLAGS(op) \
- ((op) & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK))
-
-#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
-#define TYPE_CAST_NEEDED(op) \
- ((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S32)
-#else /* !SLJIT_64BIT_ARCHITECTURE */
-#define TYPE_CAST_NEEDED(op) \
- ((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S16)
-#endif /* SLJIT_64BIT_ARCHITECTURE */
-
-#define BUF_SIZE 4096
-
-#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
-#define ABUF_SIZE 2048
-#else
-#define ABUF_SIZE 4096
-#endif
-
-/* Parameter parsing. */
-#define REG_MASK 0x3f
-#define OFFS_REG(reg) (((reg) >> 8) & REG_MASK)
-#define OFFS_REG_MASK (REG_MASK << 8)
-#define TO_OFFS_REG(reg) ((reg) << 8)
-/* When reg cannot be unused. */
-#define FAST_IS_REG(reg) ((reg) <= REG_MASK)
-
-/* Mask for argument types. */
-#define SLJIT_ARG_MASK 0x7
-#define SLJIT_ARG_FULL_MASK (SLJIT_ARG_MASK | SLJIT_ARG_TYPE_SCRATCH_REG)
-
-/* Mask for sljit_emit_mem. */
-#define REG_PAIR_MASK 0xff00
-#define REG_PAIR_FIRST(reg) ((reg) & 0xff)
-#define REG_PAIR_SECOND(reg) ((reg) >> 8)
-
-/* Mask for sljit_emit_enter. */
-#define SLJIT_KEPT_SAVEDS_COUNT(options) ((options) & 0x3)
-
-/* Jump flags. */
-#define JUMP_LABEL 0x1
-#define JUMP_ADDR 0x2
-/* SLJIT_REWRITABLE_JUMP is 0x1000. */
-
-#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
-# define PATCH_MB 0x4
-# define PATCH_MW 0x8
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-# define PATCH_MD 0x10
-#endif
-# define TYPE_SHIFT 13
-#endif /* SLJIT_CONFIG_X86 */
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
-# define IS_BL 0x4
-# define PATCH_B 0x8
-#endif /* SLJIT_CONFIG_ARM_V5 || SLJIT_CONFIG_ARM_V7 */
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
-# define CPOOL_SIZE 512
-#endif /* SLJIT_CONFIG_ARM_V5 */
-
-#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
-# define IS_COND 0x04
-# define IS_BL 0x08
- /* conditional + imm8 */
-# define PATCH_TYPE1 0x10
- /* conditional + imm20 */
-# define PATCH_TYPE2 0x20
- /* IT + imm24 */
-# define PATCH_TYPE3 0x30
- /* imm11 */
-# define PATCH_TYPE4 0x40
- /* imm24 */
-# define PATCH_TYPE5 0x50
- /* BL + imm24 */
-# define PATCH_BL 0x60
- /* 0xf00 cc code for branches */
-#endif /* SLJIT_CONFIG_ARM_THUMB2 */
-
-#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
-# define IS_COND 0x004
-# define IS_CBZ 0x008
-# define IS_BL 0x010
-# define PATCH_B 0x020
-# define PATCH_COND 0x040
-# define PATCH_ABS48 0x080
-# define PATCH_ABS64 0x100
-#endif /* SLJIT_CONFIG_ARM_64 */
-
-#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
-# define IS_COND 0x004
-# define IS_CALL 0x008
-# define PATCH_B 0x010
-# define PATCH_ABS_B 0x020
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
-# define PATCH_ABS32 0x040
-# define PATCH_ABS48 0x080
-#endif /* SLJIT_CONFIG_PPC_64 */
-# define REMOVE_COND 0x100
-#endif /* SLJIT_CONFIG_PPC */
-
-#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
-# define IS_MOVABLE 0x004
-# define IS_JAL 0x008
-# define IS_CALL 0x010
-# define IS_BIT26_COND 0x020
-# define IS_BIT16_COND 0x040
-# define IS_BIT23_COND 0x080
-
-# define IS_COND (IS_BIT26_COND | IS_BIT16_COND | IS_BIT23_COND)
-
-# define PATCH_B 0x100
-# define PATCH_J 0x200
-
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
-# define PATCH_ABS32 0x400
-# define PATCH_ABS48 0x800
-#endif /* SLJIT_CONFIG_MIPS_64 */
-
- /* instruction types */
-# define MOVABLE_INS 0
- /* 1 - 31 last destination register */
- /* no destination (i.e: store) */
-# define UNMOVABLE_INS 32
- /* FPU status register */
-# define FCSR_FCC 33
-#endif /* SLJIT_CONFIG_MIPS */
-
-#if (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
-# define IS_COND 0x004
-# define IS_CALL 0x008
-
-# define PATCH_B 0x010
-# define PATCH_J 0x020
-
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
-# define PATCH_REL32 0x040
-# define PATCH_ABS32 0x080
-# define PATCH_ABS44 0x100
-# define PATCH_ABS52 0x200
-#else /* !SLJIT_CONFIG_RISCV_64 */
-# define PATCH_REL32 0x0
-#endif /* SLJIT_CONFIG_RISCV_64 */
-#endif /* SLJIT_CONFIG_RISCV */
-
-/* Stack management. */
-
-#define GET_SAVED_REGISTERS_SIZE(scratches, saveds, extra) \
- (((scratches < SLJIT_NUMBER_OF_SCRATCH_REGISTERS ? 0 : (scratches - SLJIT_NUMBER_OF_SCRATCH_REGISTERS)) + \
- (saveds) + (sljit_s32)(extra)) * (sljit_s32)sizeof(sljit_sw))
-
-#define GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, size) \
- (((fscratches < SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS ? 0 : (fscratches - SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS)) + \
- (fsaveds)) * (sljit_s32)(size))
-
-#define ADJUST_LOCAL_OFFSET(p, i) \
- if ((p) == (SLJIT_MEM1(SLJIT_SP))) \
- (i) += SLJIT_LOCALS_OFFSET;
-
-#endif /* !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) */
-
-/* Utils can still be used even if SLJIT_CONFIG_UNSUPPORTED is set. */
-#include "sljitUtils.c"
-
-#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
-
-#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
-
-#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
-#include "sljitProtExecAllocator.c"
-#elif (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)
-#include "sljitWXExecAllocator.c"
-#else
-#include "sljitExecAllocator.c"
-#endif
-
-#endif
-
-#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
-#define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr) + (exec_offset))
-#else
-#define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr))
-#endif
-
-#ifndef SLJIT_UPDATE_WX_FLAGS
-#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
-#endif
-
-/* Argument checking features. */
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
-
-/* Returns with error when an invalid argument is passed. */
-
-#define CHECK_ARGUMENT(x) \
- do { \
- if (SLJIT_UNLIKELY(!(x))) \
- return 1; \
- } while (0)
-
-#define CHECK_RETURN_TYPE sljit_s32
-#define CHECK_RETURN_OK return 0
-
-#define CHECK(x) \
- do { \
- if (SLJIT_UNLIKELY(x)) { \
- compiler->error = SLJIT_ERR_BAD_ARGUMENT; \
- return SLJIT_ERR_BAD_ARGUMENT; \
- } \
- } while (0)
-
-#define CHECK_PTR(x) \
- do { \
- if (SLJIT_UNLIKELY(x)) { \
- compiler->error = SLJIT_ERR_BAD_ARGUMENT; \
- return NULL; \
- } \
- } while (0)
-
-#define CHECK_REG_INDEX(x) \
- do { \
- if (SLJIT_UNLIKELY(x)) { \
- return -2; \
- } \
- } while (0)
-
-#elif (defined SLJIT_DEBUG && SLJIT_DEBUG)
-
-/* Assertion failure occures if an invalid argument is passed. */
-#undef SLJIT_ARGUMENT_CHECKS
-#define SLJIT_ARGUMENT_CHECKS 1
-
-#define CHECK_ARGUMENT(x) SLJIT_ASSERT(x)
-#define CHECK_RETURN_TYPE void
-#define CHECK_RETURN_OK return
-#define CHECK(x) x
-#define CHECK_PTR(x) x
-#define CHECK_REG_INDEX(x) x
-
-#elif (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
-
-/* Arguments are not checked. */
-#define CHECK_RETURN_TYPE void
-#define CHECK_RETURN_OK return
-#define CHECK(x) x
-#define CHECK_PTR(x) x
-#define CHECK_REG_INDEX(x) x
-
-#else
-
-/* Arguments are not checked. */
-#define CHECK(x)
-#define CHECK_PTR(x)
-#define CHECK_REG_INDEX(x)
-
-#endif /* SLJIT_ARGUMENT_CHECKS */
-
-/* --------------------------------------------------------------------- */
-/* Public functions */
-/* --------------------------------------------------------------------- */
-
-#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
-#define SLJIT_NEEDS_COMPILER_INIT 1
-static sljit_s32 compiler_initialized = 0;
-/* A thread safe initialization. */
-static void init_compiler(void);
-#endif
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data)
-{
- struct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler), allocator_data);
- if (!compiler)
- return NULL;
- SLJIT_ZEROMEM(compiler, sizeof(struct sljit_compiler));
-
- SLJIT_COMPILE_ASSERT(
- sizeof(sljit_s8) == 1 && sizeof(sljit_u8) == 1
- && sizeof(sljit_s16) == 2 && sizeof(sljit_u16) == 2
- && sizeof(sljit_s32) == 4 && sizeof(sljit_u32) == 4
- && (sizeof(sljit_p) == 4 || sizeof(sljit_p) == 8)
- && sizeof(sljit_p) <= sizeof(sljit_sw)
- && (sizeof(sljit_sw) == 4 || sizeof(sljit_sw) == 8)
- && (sizeof(sljit_uw) == 4 || sizeof(sljit_uw) == 8),
- invalid_integer_types);
- SLJIT_COMPILE_ASSERT(SLJIT_REWRITABLE_JUMP != SLJIT_32,
- rewritable_jump_and_single_op_must_not_be_the_same);
- SLJIT_COMPILE_ASSERT(!(SLJIT_EQUAL & 0x1) && !(SLJIT_LESS & 0x1) && !(SLJIT_F_EQUAL & 0x1) && !(SLJIT_JUMP & 0x1),
- conditional_flags_must_be_even_numbers);
-
- /* Only the non-zero members must be set. */
- compiler->error = SLJIT_SUCCESS;
-
- compiler->allocator_data = allocator_data;
- compiler->exec_allocator_data = exec_allocator_data;
- compiler->buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, allocator_data);
- compiler->abuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, allocator_data);
-
- if (!compiler->buf || !compiler->abuf) {
- if (compiler->buf)
- SLJIT_FREE(compiler->buf, allocator_data);
- if (compiler->abuf)
- SLJIT_FREE(compiler->abuf, allocator_data);
- SLJIT_FREE(compiler, allocator_data);
- return NULL;
- }
-
- compiler->buf->next = NULL;
- compiler->buf->used_size = 0;
- compiler->abuf->next = NULL;
- compiler->abuf->used_size = 0;
-
- compiler->scratches = -1;
- compiler->saveds = -1;
- compiler->fscratches = -1;
- compiler->fsaveds = -1;
- compiler->local_size = -1;
-
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- compiler->args_size = -1;
-#endif
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- compiler->cpool = (sljit_uw*)SLJIT_MALLOC(CPOOL_SIZE * sizeof(sljit_uw)
- + CPOOL_SIZE * sizeof(sljit_u8), allocator_data);
- if (!compiler->cpool) {
- SLJIT_FREE(compiler->buf, allocator_data);
- SLJIT_FREE(compiler->abuf, allocator_data);
- SLJIT_FREE(compiler, allocator_data);
- return NULL;
- }
- compiler->cpool_unique = (sljit_u8*)(compiler->cpool + CPOOL_SIZE);
- compiler->cpool_diff = 0xffffffff;
-#endif
-
-#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
- compiler->delay_slot = UNMOVABLE_INS;
-#endif
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
- || (defined SLJIT_DEBUG && SLJIT_DEBUG)
- compiler->last_flags = 0;
- compiler->last_return = -1;
- compiler->logical_local_size = 0;
-#endif
-
-#if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT)
- if (!compiler_initialized) {
- init_compiler();
- compiler_initialized = 1;
- }
-#endif
-
- return compiler;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)
-{
- struct sljit_memory_fragment *buf;
- struct sljit_memory_fragment *curr;
- void *allocator_data = compiler->allocator_data;
- SLJIT_UNUSED_ARG(allocator_data);
-
- buf = compiler->buf;
- while (buf) {
- curr = buf;
- buf = buf->next;
- SLJIT_FREE(curr, allocator_data);
- }
-
- buf = compiler->abuf;
- while (buf) {
- curr = buf;
- buf = buf->next;
- SLJIT_FREE(curr, allocator_data);
- }
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- SLJIT_FREE(compiler->cpool, allocator_data);
-#endif
- SLJIT_FREE(compiler, allocator_data);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler)
-{
- if (compiler->error == SLJIT_SUCCESS)
- compiler->error = SLJIT_ERR_ALLOC_FAILED;
-}
-
-#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
-{
- SLJIT_UNUSED_ARG(exec_allocator_data);
-
- /* Remove thumb mode flag. */
- SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~(sljit_uw)0x1), exec_allocator_data);
-}
-#elif (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
-{
- SLJIT_UNUSED_ARG(exec_allocator_data);
-
- /* Resolve indirection. */
- code = (void*)(*(sljit_uw*)code);
- SLJIT_FREE_EXEC(code, exec_allocator_data);
-}
-#else
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
-{
- SLJIT_UNUSED_ARG(exec_allocator_data);
-
- SLJIT_FREE_EXEC(code, exec_allocator_data);
-}
-#endif
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)
-{
- if (SLJIT_LIKELY(!!jump) && SLJIT_LIKELY(!!label)) {
- jump->flags &= (sljit_uw)~JUMP_ADDR;
- jump->flags |= JUMP_LABEL;
- jump->u.label = label;
- }
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
-{
- if (SLJIT_LIKELY(!!jump)) {
- jump->flags &= (sljit_uw)~JUMP_LABEL;
- jump->flags |= JUMP_ADDR;
- jump->u.target = target;
- }
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label)
-{
- if (SLJIT_LIKELY(!!put_label))
- put_label->label = label;
-}
-
-#define SLJIT_CURRENT_FLAGS_ALL \
- (SLJIT_CURRENT_FLAGS_32 | SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB | SLJIT_CURRENT_FLAGS_COMPARE)
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler, sljit_s32 current_flags)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(current_flags);
-
-#if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE)
- compiler->status_flags_state = current_flags;
-#endif
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- compiler->last_flags = 0;
- if ((current_flags & ~(VARIABLE_FLAG_MASK | SLJIT_SET_Z | SLJIT_CURRENT_FLAGS_ALL)) == 0) {
- compiler->last_flags = GET_FLAG_TYPE(current_flags) | (current_flags & (SLJIT_32 | SLJIT_SET_Z));
- }
-#endif
-}
-
-/* --------------------------------------------------------------------- */
-/* Private functions */
-/* --------------------------------------------------------------------- */
-
-static void* ensure_buf(struct sljit_compiler *compiler, sljit_uw size)
-{
- sljit_u8 *ret;
- struct sljit_memory_fragment *new_frag;
-
- SLJIT_ASSERT(size <= 256);
- if (compiler->buf->used_size + size <= (BUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) {
- ret = compiler->buf->memory + compiler->buf->used_size;
- compiler->buf->used_size += size;
- return ret;
- }
- new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, compiler->allocator_data);
- PTR_FAIL_IF_NULL(new_frag);
- new_frag->next = compiler->buf;
- compiler->buf = new_frag;
- new_frag->used_size = size;
- return new_frag->memory;
-}
-
-static void* ensure_abuf(struct sljit_compiler *compiler, sljit_uw size)
-{
- sljit_u8 *ret;
- struct sljit_memory_fragment *new_frag;
-
- SLJIT_ASSERT(size <= 256);
- if (compiler->abuf->used_size + size <= (ABUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) {
- ret = compiler->abuf->memory + compiler->abuf->used_size;
- compiler->abuf->used_size += size;
- return ret;
- }
- new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, compiler->allocator_data);
- PTR_FAIL_IF_NULL(new_frag);
- new_frag->next = compiler->abuf;
- compiler->abuf = new_frag;
- new_frag->used_size = size;
- return new_frag->memory;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size)
-{
- CHECK_ERROR_PTR();
-
-#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
- if (size <= 0 || size > 128)
- return NULL;
- size = (size + 7) & ~7;
-#else
- if (size <= 0 || size > 64)
- return NULL;
- size = (size + 3) & ~3;
-#endif
- return ensure_abuf(compiler, (sljit_uw)size);
-}
-
-static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler)
-{
- struct sljit_memory_fragment *buf = compiler->buf;
- struct sljit_memory_fragment *prev = NULL;
- struct sljit_memory_fragment *tmp;
-
- do {
- tmp = buf->next;
- buf->next = prev;
- prev = buf;
- buf = tmp;
- } while (buf != NULL);
-
- compiler->buf = prev;
-}
-
-/* Only used in RISC architectures where the instruction size is constant */
-#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
- && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
-
-static SLJIT_INLINE sljit_uw compute_next_addr(struct sljit_label *label, struct sljit_jump *jump,
- struct sljit_const *const_, struct sljit_put_label *put_label)
-{
- sljit_uw result = ~(sljit_uw)0;
-
- if (label)
- result = label->size;
-
- if (jump && jump->addr < result)
- result = jump->addr;
-
- if (const_ && const_->addr < result)
- result = const_->addr;
-
- if (put_label && put_label->addr < result)
- result = put_label->addr;
-
- return result;
-}
-
-#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_S390X */
-
-static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- SLJIT_UNUSED_ARG(args);
- SLJIT_UNUSED_ARG(local_size);
-
- compiler->options = options;
- compiler->scratches = scratches;
- compiler->saveds = saveds;
- compiler->fscratches = fscratches;
- compiler->fsaveds = fsaveds;
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- compiler->last_return = args & SLJIT_ARG_MASK;
- compiler->logical_local_size = local_size;
-#endif
-}
-
-static SLJIT_INLINE void set_set_context(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- SLJIT_UNUSED_ARG(args);
- SLJIT_UNUSED_ARG(local_size);
-
- compiler->options = options;
- compiler->scratches = scratches;
- compiler->saveds = saveds;
- compiler->fscratches = fscratches;
- compiler->fsaveds = fsaveds;
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- compiler->last_return = args & SLJIT_ARG_MASK;
- compiler->logical_local_size = local_size;
-#endif
-}
-
-static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compiler *compiler)
-{
- label->next = NULL;
- label->size = compiler->size;
- if (compiler->last_label)
- compiler->last_label->next = label;
- else
- compiler->labels = label;
- compiler->last_label = label;
-}
-
-static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_u32 flags)
-{
- jump->next = NULL;
- jump->flags = flags;
- if (compiler->last_jump)
- compiler->last_jump->next = jump;
- else
- compiler->jumps = jump;
- compiler->last_jump = jump;
-}
-
-static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_compiler *compiler)
-{
- const_->next = NULL;
- const_->addr = compiler->size;
- if (compiler->last_const)
- compiler->last_const->next = const_;
- else
- compiler->consts = const_;
- compiler->last_const = const_;
-}
-
-static SLJIT_INLINE void set_put_label(struct sljit_put_label *put_label, struct sljit_compiler *compiler, sljit_uw offset)
-{
- put_label->next = NULL;
- put_label->label = NULL;
- put_label->addr = compiler->size - offset;
- put_label->flags = 0;
- if (compiler->last_put_label)
- compiler->last_put_label->next = put_label;
- else
- compiler->put_labels = put_label;
- compiler->last_put_label = put_label;
-}
-
-#define ADDRESSING_DEPENDS_ON(exp, reg) \
- (((exp) & SLJIT_MEM) && (((exp) & REG_MASK) == reg || OFFS_REG(exp) == reg))
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
-
-static sljit_s32 function_check_arguments(sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, sljit_s32 fscratches)
-{
- sljit_s32 word_arg_count, scratch_arg_end, saved_arg_count, float_arg_count, curr_type;
-
- curr_type = (arg_types & SLJIT_ARG_FULL_MASK);
-
- if (curr_type >= SLJIT_ARG_TYPE_F64) {
- if (curr_type > SLJIT_ARG_TYPE_F32 || fscratches == 0)
- return 0;
- } else if (curr_type >= SLJIT_ARG_TYPE_W) {
- if (scratches == 0)
- return 0;
- }
-
- arg_types >>= SLJIT_ARG_SHIFT;
-
- word_arg_count = 0;
- scratch_arg_end = 0;
- saved_arg_count = 0;
- float_arg_count = 0;
- while (arg_types != 0) {
- if (word_arg_count + float_arg_count >= 4)
- return 0;
-
- curr_type = (arg_types & SLJIT_ARG_MASK);
-
- if (arg_types & SLJIT_ARG_TYPE_SCRATCH_REG) {
- if (saveds == -1 || curr_type < SLJIT_ARG_TYPE_W || curr_type > SLJIT_ARG_TYPE_P)
- return 0;
-
- word_arg_count++;
- scratch_arg_end = word_arg_count;
- } else {
- if (curr_type < SLJIT_ARG_TYPE_W || curr_type > SLJIT_ARG_TYPE_F32)
- return 0;
-
- if (curr_type < SLJIT_ARG_TYPE_F64) {
- word_arg_count++;
- saved_arg_count++;
- } else
- float_arg_count++;
- }
-
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- if (saveds == -1)
- return (word_arg_count <= scratches && float_arg_count <= fscratches);
-
- return (saved_arg_count <= saveds && scratch_arg_end <= scratches && float_arg_count <= fscratches);
-}
-
-#define FUNCTION_CHECK_IS_REG(r) \
- (((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) \
- || ((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0))
-
-#define FUNCTION_CHECK_IS_FREG(fr) \
- (((fr) >= SLJIT_FR0 && (fr) < (SLJIT_FR0 + compiler->fscratches)) \
- || ((fr) > (SLJIT_FS0 - compiler->fsaveds) && (fr) <= SLJIT_FS0))
-
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-#define CHECK_IF_VIRTUAL_REGISTER(p) ((p) <= SLJIT_S3 && (p) >= SLJIT_S8)
-#else
-#define CHECK_IF_VIRTUAL_REGISTER(p) 0
-#endif
-
-static sljit_s32 function_check_src_mem(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
-{
- if (compiler->scratches == -1 || compiler->saveds == -1)
- return 0;
-
- if (!(p & SLJIT_MEM))
- return 0;
-
- if (p == SLJIT_MEM1(SLJIT_SP))
- return (i >= 0 && i < compiler->logical_local_size);
-
- if (!(!(p & REG_MASK) || FUNCTION_CHECK_IS_REG(p & REG_MASK)))
- return 0;
-
- if (CHECK_IF_VIRTUAL_REGISTER(p & REG_MASK))
- return 0;
-
- if (p & OFFS_REG_MASK) {
- if (!(p & REG_MASK))
- return 0;
-
- if (!(FUNCTION_CHECK_IS_REG(OFFS_REG(p))))
- return 0;
-
- if (CHECK_IF_VIRTUAL_REGISTER(OFFS_REG(p)))
- return 0;
-
- if ((i & ~0x3) != 0)
- return 0;
- }
-
- return (p & ~(SLJIT_MEM | REG_MASK | OFFS_REG_MASK)) == 0;
-}
-
-#define FUNCTION_CHECK_SRC_MEM(p, i) \
- CHECK_ARGUMENT(function_check_src_mem(compiler, p, i));
-
-static sljit_s32 function_check_src(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
-{
- if (compiler->scratches == -1 || compiler->saveds == -1)
- return 0;
-
- if (FUNCTION_CHECK_IS_REG(p))
- return (i == 0);
-
- if (p == SLJIT_IMM)
- return 1;
-
- return function_check_src_mem(compiler, p, i);
-}
-
-#define FUNCTION_CHECK_SRC(p, i) \
- CHECK_ARGUMENT(function_check_src(compiler, p, i));
-
-static sljit_s32 function_check_dst(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
-{
- if (compiler->scratches == -1 || compiler->saveds == -1)
- return 0;
-
- if (FUNCTION_CHECK_IS_REG(p))
- return (i == 0);
-
- return function_check_src_mem(compiler, p, i);
-}
-
-#define FUNCTION_CHECK_DST(p, i) \
- CHECK_ARGUMENT(function_check_dst(compiler, p, i));
-
-static sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
-{
- if (compiler->scratches == -1 || compiler->saveds == -1)
- return 0;
-
- if (FUNCTION_CHECK_IS_FREG(p))
- return (i == 0);
-
- return function_check_src_mem(compiler, p, i);
-}
-
-#define FUNCTION_FCHECK(p, i) \
- CHECK_ARGUMENT(function_fcheck(compiler, p, i));
-
-#endif /* SLJIT_ARGUMENT_CHECKS */
-
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose)
-{
- compiler->verbose = verbose;
-}
-
-#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
-#ifdef _WIN64
-#ifdef __GNUC__
-# define SLJIT_PRINT_D "ll"
-#else
-# define SLJIT_PRINT_D "I64"
-#endif
-#else
-# define SLJIT_PRINT_D "l"
-#endif
-#else
-# define SLJIT_PRINT_D ""
-#endif
-
-static void sljit_verbose_reg(struct sljit_compiler *compiler, sljit_s32 r)
-{
- if (r < (SLJIT_R0 + compiler->scratches))
- fprintf(compiler->verbose, "r%d", r - SLJIT_R0);
- else if (r != SLJIT_SP)
- fprintf(compiler->verbose, "s%d", SLJIT_NUMBER_OF_REGISTERS - r);
- else
- fprintf(compiler->verbose, "sp");
-}
-
-static void sljit_verbose_freg(struct sljit_compiler *compiler, sljit_s32 r)
-{
- if (r < (SLJIT_FR0 + compiler->fscratches))
- fprintf(compiler->verbose, "fr%d", r - SLJIT_FR0);
- else
- fprintf(compiler->verbose, "fs%d", SLJIT_NUMBER_OF_FLOAT_REGISTERS - r);
-}
-
-static void sljit_verbose_param(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
-{
- if ((p) & SLJIT_IMM)
- fprintf(compiler->verbose, "#%" SLJIT_PRINT_D "d", (i));
- else if ((p) & SLJIT_MEM) {
- if ((p) & REG_MASK) {
- fputc('[', compiler->verbose);
- sljit_verbose_reg(compiler, (p) & REG_MASK);
- if ((p) & OFFS_REG_MASK) {
- fprintf(compiler->verbose, " + ");
- sljit_verbose_reg(compiler, OFFS_REG(p));
- if (i)
- fprintf(compiler->verbose, " * %d", 1 << (i));
- }
- else if (i)
- fprintf(compiler->verbose, " + %" SLJIT_PRINT_D "d", (i));
- fputc(']', compiler->verbose);
- }
- else
- fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i));
- } else
- sljit_verbose_reg(compiler, p);
-}
-
-static void sljit_verbose_fparam(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
-{
- if ((p) & SLJIT_MEM) {
- if ((p) & REG_MASK) {
- fputc('[', compiler->verbose);
- sljit_verbose_reg(compiler, (p) & REG_MASK);
- if ((p) & OFFS_REG_MASK) {
- fprintf(compiler->verbose, " + ");
- sljit_verbose_reg(compiler, OFFS_REG(p));
- if (i)
- fprintf(compiler->verbose, "%d", 1 << (i));
- }
- else if (i)
- fprintf(compiler->verbose, " + %" SLJIT_PRINT_D "d", (i));
- fputc(']', compiler->verbose);
- }
- else
- fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i));
- }
- else
- sljit_verbose_freg(compiler, p);
-}
-
-static const char* op0_names[] = {
- "breakpoint", "nop", "lmul.uw", "lmul.sw",
- "divmod.u", "divmod.s", "div.u", "div.s",
- "endbr", "skip_frames_before_return"
-};
-
-static const char* op1_names[] = {
- "", ".u8", ".s8", ".u16",
- ".s16", ".u32", ".s32", "32",
- ".p", "not", "clz", "ctz"
-};
-
-static const char* op2_names[] = {
- "add", "addc", "sub", "subc",
- "mul", "and", "or", "xor",
- "shl", "mshl", "lshr", "mlshr",
- "ashr", "mashr", "rotl", "rotr"
-};
-
-static const char* op_src_names[] = {
- "fast_return", "skip_frames_before_fast_return",
- "prefetch_l1", "prefetch_l2",
- "prefetch_l3", "prefetch_once",
-};
-
-static const char* fop1_names[] = {
- "mov", "conv", "conv", "conv",
- "conv", "conv", "cmp", "neg",
- "abs",
-};
-
-static const char* fop2_names[] = {
- "add", "sub", "mul", "div"
-};
-
-static const char* jump_names[] = {
- "equal", "not_equal",
- "less", "greater_equal",
- "greater", "less_equal",
- "sig_less", "sig_greater_equal",
- "sig_greater", "sig_less_equal",
- "overflow", "not_overflow",
- "carry", "",
- "f_equal", "f_not_equal",
- "f_less", "f_greater_equal",
- "f_greater", "f_less_equal",
- "unordered", "ordered",
- "ordered_equal", "unordered_or_not_equal",
- "ordered_less", "unordered_or_greater_equal",
- "ordered_greater", "unordered_or_less_equal",
- "unordered_or_equal", "ordered_not_equal",
- "unordered_or_less", "ordered_greater_equal",
- "unordered_or_greater", "ordered_less_equal",
- "jump", "fast_call",
- "call", "call_reg_arg"
-};
-
-static const char* call_arg_names[] = {
- "void", "w", "32", "p", "f64", "f32"
-};
-
-#endif /* SLJIT_VERBOSE */
-
-/* --------------------------------------------------------------------- */
-/* Arch dependent */
-/* --------------------------------------------------------------------- */
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
- || (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
-
-#define SLJIT_SKIP_CHECKS(compiler) (compiler)->skip_checks = 1
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_compiler *compiler)
-{
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- struct sljit_jump *jump;
-#endif
-
- SLJIT_UNUSED_ARG(compiler);
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(compiler->size > 0);
- jump = compiler->jumps;
- while (jump) {
- /* All jumps have target. */
- CHECK_ARGUMENT(jump->flags & (JUMP_LABEL | JUMP_ADDR));
- jump = jump->next;
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- SLJIT_UNUSED_ARG(compiler);
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- if (options & SLJIT_ENTER_REG_ARG) {
- CHECK_ARGUMENT(!(options & ~(0x3 | SLJIT_ENTER_REG_ARG)));
- } else {
- CHECK_ARGUMENT(options == 0);
- }
- CHECK_ARGUMENT(SLJIT_KEPT_SAVEDS_COUNT(options) <= 3 && SLJIT_KEPT_SAVEDS_COUNT(options) <= saveds);
- CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS);
- CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS);
- CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS);
- CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
- CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS);
- CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
- CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
- CHECK_ARGUMENT((arg_types & SLJIT_ARG_FULL_MASK) <= SLJIT_ARG_TYPE_F32);
- CHECK_ARGUMENT(function_check_arguments(arg_types, scratches, (options & SLJIT_ENTER_REG_ARG) ? 0 : saveds, fscratches));
-
- compiler->last_flags = 0;
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " enter ret[%s", call_arg_names[arg_types & SLJIT_ARG_MASK]);
-
- arg_types >>= SLJIT_ARG_SHIFT;
- if (arg_types) {
- fprintf(compiler->verbose, "], args[");
- do {
- fprintf(compiler->verbose, "%s%s", call_arg_names[arg_types & SLJIT_ARG_MASK],
- (arg_types & SLJIT_ARG_TYPE_SCRATCH_REG) ? "_r" : "");
- arg_types >>= SLJIT_ARG_SHIFT;
- if (arg_types)
- fprintf(compiler->verbose, ",");
- } while (arg_types);
- }
-
- fprintf(compiler->verbose, "],");
-
- if (options & SLJIT_ENTER_REG_ARG) {
- fprintf(compiler->verbose, " enter:reg_arg,");
-
- if (SLJIT_KEPT_SAVEDS_COUNT(options) > 0)
- fprintf(compiler->verbose, " keep:%d,", SLJIT_KEPT_SAVEDS_COUNT(options));
- }
-
- fprintf(compiler->verbose, "scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, local_size:%d\n",
- scratches, saveds, fscratches, fsaveds, local_size);
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- SLJIT_UNUSED_ARG(compiler);
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- if (options & SLJIT_ENTER_REG_ARG) {
- CHECK_ARGUMENT(!(options & ~(0x3 | SLJIT_ENTER_REG_ARG)));
- } else {
- CHECK_ARGUMENT(options == 0);
- }
- CHECK_ARGUMENT(SLJIT_KEPT_SAVEDS_COUNT(options) <= 3 && SLJIT_KEPT_SAVEDS_COUNT(options) <= saveds);
- CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS);
- CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS);
- CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS);
- CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
- CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS);
- CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
- CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
- CHECK_ARGUMENT((arg_types & SLJIT_ARG_FULL_MASK) < SLJIT_ARG_TYPE_F64);
- CHECK_ARGUMENT(function_check_arguments(arg_types, scratches, (options & SLJIT_ENTER_REG_ARG) ? 0 : saveds, fscratches));
-
- compiler->last_flags = 0;
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " set_context ret[%s", call_arg_names[arg_types & SLJIT_ARG_MASK]);
-
- arg_types >>= SLJIT_ARG_SHIFT;
- if (arg_types) {
- fprintf(compiler->verbose, "], args[");
- do {
- fprintf(compiler->verbose, "%s%s", call_arg_names[arg_types & SLJIT_ARG_MASK],
- (arg_types & SLJIT_ARG_TYPE_SCRATCH_REG) ? "_r" : "");
- arg_types >>= SLJIT_ARG_SHIFT;
- if (arg_types)
- fprintf(compiler->verbose, ",");
- } while (arg_types);
- }
-
- fprintf(compiler->verbose, "],");
-
- if (options & SLJIT_ENTER_REG_ARG) {
- fprintf(compiler->verbose, " enter:reg_arg,");
-
- if (SLJIT_KEPT_SAVEDS_COUNT(options) > 0)
- fprintf(compiler->verbose, " keep:%d,", SLJIT_KEPT_SAVEDS_COUNT(options));
- }
-
- fprintf(compiler->verbose, " scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, local_size:%d\n",
- scratches, saveds, fscratches, fsaveds, local_size);
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return_void(struct sljit_compiler *compiler)
-{
- if (SLJIT_UNLIKELY(compiler->skip_checks)) {
- compiler->skip_checks = 0;
- CHECK_RETURN_OK;
- }
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(compiler->last_return == SLJIT_ARG_TYPE_VOID);
-#endif
-
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " return_void\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
-{
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(compiler->scratches >= 0);
-
- switch (compiler->last_return) {
- case SLJIT_ARG_TYPE_W:
- CHECK_ARGUMENT(op >= SLJIT_MOV && op <= SLJIT_MOV_S32);
- break;
- case SLJIT_ARG_TYPE_32:
- CHECK_ARGUMENT(op == SLJIT_MOV32 || (op >= SLJIT_MOV32_U8 && op <= SLJIT_MOV32_S16));
- break;
- case SLJIT_ARG_TYPE_P:
- CHECK_ARGUMENT(op == SLJIT_MOV_P);
- break;
- case SLJIT_ARG_TYPE_F64:
- CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
- CHECK_ARGUMENT(op == SLJIT_MOV_F64);
- break;
- case SLJIT_ARG_TYPE_F32:
- CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
- CHECK_ARGUMENT(op == SLJIT_MOV_F32);
- break;
- default:
- /* Context not initialized, void, etc. */
- CHECK_ARGUMENT(0);
- break;
- }
-
- if (GET_OPCODE(op) < SLJIT_MOV_F64) {
- FUNCTION_CHECK_SRC(src, srcw);
- } else {
- FUNCTION_FCHECK(src, srcw);
- }
- compiler->last_flags = 0;
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- if (GET_OPCODE(op) < SLJIT_MOV_F64) {
- fprintf(compiler->verbose, " return%s%s ", !(op & SLJIT_32) ? "" : "32",
- op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE]);
- sljit_verbose_param(compiler, src, srcw);
- } else {
- fprintf(compiler->verbose, " return%s ", !(op & SLJIT_32) ? ".f64" : ".f32");
- sljit_verbose_fparam(compiler, src, srcw);
- }
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return_to(struct sljit_compiler *compiler,
- sljit_s32 src, sljit_sw srcw)
-{
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- FUNCTION_CHECK_SRC(src, srcw);
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " return_to ");
- sljit_verbose_param(compiler, src, srcw);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
-{
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- FUNCTION_CHECK_DST(dst, dstw);
- compiler->last_flags = 0;
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " fast_enter ");
- sljit_verbose_param(compiler, dst, dstw);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
-{
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LMUL_SW)
- || ((op & ~SLJIT_32) >= SLJIT_DIVMOD_UW && (op & ~SLJIT_32) <= SLJIT_DIV_SW)
- || (op >= SLJIT_ENDBR && op <= SLJIT_SKIP_FRAMES_BEFORE_RETURN));
- CHECK_ARGUMENT(GET_OPCODE(op) < SLJIT_LMUL_UW || GET_OPCODE(op) >= SLJIT_ENDBR || compiler->scratches >= 2);
- if ((GET_OPCODE(op) >= SLJIT_LMUL_UW && GET_OPCODE(op) <= SLJIT_DIV_SW) || op == SLJIT_SKIP_FRAMES_BEFORE_RETURN)
- compiler->last_flags = 0;
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose))
- {
- fprintf(compiler->verbose, " %s", op0_names[GET_OPCODE(op) - SLJIT_OP0_BASE]);
- if (GET_OPCODE(op) >= SLJIT_DIVMOD_UW && GET_OPCODE(op) <= SLJIT_DIV_SW) {
- fprintf(compiler->verbose, (op & SLJIT_32) ? "32" : "w");
- }
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- if (SLJIT_UNLIKELY(compiler->skip_checks)) {
- compiler->skip_checks = 0;
- CHECK_RETURN_OK;
- }
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_CTZ);
-
- switch (GET_OPCODE(op)) {
- case SLJIT_NOT:
- /* Only SLJIT_32 and SLJIT_SET_Z are allowed. */
- CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK));
- break;
- case SLJIT_MOV:
- case SLJIT_MOV_U32:
- case SLJIT_MOV_P:
- /* Nothing allowed */
- CHECK_ARGUMENT(!(op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
- break;
- default:
- /* Only SLJIT_32 is allowed. */
- CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
- break;
- }
-
- FUNCTION_CHECK_DST(dst, dstw);
- FUNCTION_CHECK_SRC(src, srcw);
-
- if (GET_OPCODE(op) >= SLJIT_NOT) {
- CHECK_ARGUMENT(src != SLJIT_IMM);
- compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_32 | SLJIT_SET_Z));
- }
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- if (GET_OPCODE(op) <= SLJIT_MOV_P)
- {
- fprintf(compiler->verbose, " mov%s%s ", !(op & SLJIT_32) ? "" : "32",
- op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE]);
- }
- else
- {
- fprintf(compiler->verbose, " %s%s%s%s%s ", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], !(op & SLJIT_32) ? "" : "32",
- !(op & SLJIT_SET_Z) ? "" : ".z", !(op & VARIABLE_FLAG_MASK) ? "" : ".",
- !(op & VARIABLE_FLAG_MASK) ? "" : jump_names[GET_FLAG_TYPE(op)]);
- }
-
- sljit_verbose_param(compiler, dst, dstw);
- fprintf(compiler->verbose, ", ");
- sljit_verbose_param(compiler, src, srcw);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 unset,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- if (SLJIT_UNLIKELY(compiler->skip_checks)) {
- compiler->skip_checks = 0;
- CHECK_RETURN_OK;
- }
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD && GET_OPCODE(op) <= SLJIT_ROTR);
-
- switch (GET_OPCODE(op)) {
- case SLJIT_AND:
- case SLJIT_OR:
- case SLJIT_XOR:
- case SLJIT_SHL:
- case SLJIT_MSHL:
- case SLJIT_LSHR:
- case SLJIT_MLSHR:
- case SLJIT_ASHR:
- case SLJIT_MASHR:
- CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK));
- break;
- case SLJIT_MUL:
- CHECK_ARGUMENT(!(op & SLJIT_SET_Z));
- CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
- || GET_FLAG_TYPE(op) == SLJIT_OVERFLOW);
- break;
- case SLJIT_ADD:
- CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
- || GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY)
- || GET_FLAG_TYPE(op) == SLJIT_OVERFLOW);
- break;
- case SLJIT_SUB:
- CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
- || (GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_OVERFLOW)
- || GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
- break;
- case SLJIT_ADDC:
- case SLJIT_SUBC:
- CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
- || GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
- CHECK_ARGUMENT((compiler->last_flags & 0xff) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
- CHECK_ARGUMENT((op & SLJIT_32) == (compiler->last_flags & SLJIT_32));
- break;
- case SLJIT_ROTL:
- case SLJIT_ROTR:
- CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
- break;
- default:
- SLJIT_UNREACHABLE();
- break;
- }
-
- if (unset) {
- CHECK_ARGUMENT(HAS_FLAGS(op));
- } else {
- FUNCTION_CHECK_DST(dst, dstw);
- }
- FUNCTION_CHECK_SRC(src1, src1w);
- FUNCTION_CHECK_SRC(src2, src2w);
- compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_32 | SLJIT_SET_Z));
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " %s%s%s%s%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_32) ? "" : "32",
- !(op & SLJIT_SET_Z) ? "" : ".z", !(op & VARIABLE_FLAG_MASK) ? "" : ".",
- !(op & VARIABLE_FLAG_MASK) ? "" : jump_names[GET_FLAG_TYPE(op)]);
- if (unset)
- fprintf(compiler->verbose, "unset");
- else
- sljit_verbose_param(compiler, dst, dstw);
- fprintf(compiler->verbose, ", ");
- sljit_verbose_param(compiler, src1, src1w);
- fprintf(compiler->verbose, ", ");
- sljit_verbose_param(compiler, src2, src2w);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src_dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_LSHR
- || GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR);
- CHECK_ARGUMENT((op & ~(0xff | SLJIT_32 | SLJIT_SHIFT_INTO_NON_ZERO)) == 0);
- CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src_dst));
- FUNCTION_CHECK_SRC(src1, src1w);
- FUNCTION_CHECK_SRC(src2, src2w);
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " %s%s.into%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_32) ? "" : "32",
- (op & SLJIT_SHIFT_INTO_NON_ZERO) ? ".nz" : "");
-
- sljit_verbose_reg(compiler, src_dst);
- fprintf(compiler->verbose, ", ");
- sljit_verbose_param(compiler, src1, src1w);
- fprintf(compiler->verbose, ", ");
- sljit_verbose_param(compiler, src2, src2w);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src, sljit_sw srcw)
-{
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(op >= SLJIT_FAST_RETURN && op <= SLJIT_PREFETCH_ONCE);
- FUNCTION_CHECK_SRC(src, srcw);
-
- if (op == SLJIT_FAST_RETURN || op == SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN)
- {
- CHECK_ARGUMENT(src != SLJIT_IMM);
- compiler->last_flags = 0;
- }
- else if (op >= SLJIT_PREFETCH_L1 && op <= SLJIT_PREFETCH_ONCE)
- {
- CHECK_ARGUMENT(src & SLJIT_MEM);
- }
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " %s ", op_src_names[op - SLJIT_OP_SRC_BASE]);
- sljit_verbose_param(compiler, src, srcw);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_s32 reg)
-{
- SLJIT_UNUSED_ARG(reg);
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(reg > 0 && reg <= SLJIT_NUMBER_OF_REGISTERS);
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_float_register_index(sljit_s32 reg)
-{
- SLJIT_UNUSED_ARG(reg);
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(reg > 0 && reg <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_compiler *compiler,
- void *instruction, sljit_u32 size)
-{
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- sljit_u32 i;
-#endif
-
- SLJIT_UNUSED_ARG(compiler);
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(instruction);
-
-#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
- CHECK_ARGUMENT(size > 0 && size < 16);
-#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
- CHECK_ARGUMENT((size == 2 && (((sljit_sw)instruction) & 0x1) == 0)
- || (size == 4 && (((sljit_sw)instruction) & 0x3) == 0));
-#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
- CHECK_ARGUMENT(size == 2 || size == 4 || size == 6);
-#else
- CHECK_ARGUMENT(size == 4 && (((sljit_sw)instruction) & 0x3) == 0);
-#endif
-
- compiler->last_flags = 0;
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " op_custom");
- for (i = 0; i < size; i++)
- fprintf(compiler->verbose, " 0x%x", ((sljit_u8*)instruction)[i]);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- if (SLJIT_UNLIKELY(compiler->skip_checks)) {
- compiler->skip_checks = 0;
- CHECK_RETURN_OK;
- }
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
- CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV_F64 && GET_OPCODE(op) <= SLJIT_ABS_F64);
- CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
- FUNCTION_FCHECK(src, srcw);
- FUNCTION_FCHECK(dst, dstw);
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
- fprintf(compiler->verbose, " %s%s ", fop1_names[SLJIT_CONV_F64_FROM_F32 - SLJIT_FOP1_BASE],
- (op & SLJIT_32) ? ".f32.from.f64" : ".f64.from.f32");
- else
- fprintf(compiler->verbose, " %s%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],
- (op & SLJIT_32) ? ".f32" : ".f64");
-
- sljit_verbose_fparam(compiler, dst, dstw);
- fprintf(compiler->verbose, ", ");
- sljit_verbose_fparam(compiler, src, srcw);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- compiler->last_flags = GET_FLAG_TYPE(op) | (op & SLJIT_32);
-#endif
-
- if (SLJIT_UNLIKELY(compiler->skip_checks)) {
- compiler->skip_checks = 0;
- CHECK_RETURN_OK;
- }
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
- CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_CMP_F64);
- CHECK_ARGUMENT(!(op & SLJIT_SET_Z));
- CHECK_ARGUMENT((op & VARIABLE_FLAG_MASK)
- || (GET_FLAG_TYPE(op) >= SLJIT_F_EQUAL && GET_FLAG_TYPE(op) <= SLJIT_ORDERED_LESS_EQUAL));
- FUNCTION_FCHECK(src1, src1w);
- FUNCTION_FCHECK(src2, src2w);
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " %s%s", fop1_names[SLJIT_CMP_F64 - SLJIT_FOP1_BASE], (op & SLJIT_32) ? ".f32" : ".f64");
- if (op & VARIABLE_FLAG_MASK) {
- fprintf(compiler->verbose, ".%s", jump_names[GET_FLAG_TYPE(op)]);
- }
- fprintf(compiler->verbose, " ");
- sljit_verbose_fparam(compiler, src1, src1w);
- fprintf(compiler->verbose, ", ");
- sljit_verbose_fparam(compiler, src2, src2w);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- if (SLJIT_UNLIKELY(compiler->skip_checks)) {
- compiler->skip_checks = 0;
- CHECK_RETURN_OK;
- }
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
- CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CONV_S32_FROM_F64);
- CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
- FUNCTION_FCHECK(src, srcw);
- FUNCTION_CHECK_DST(dst, dstw);
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],
- (GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) ? ".s32" : ".sw",
- (op & SLJIT_32) ? ".f32" : ".f64");
- sljit_verbose_param(compiler, dst, dstw);
- fprintf(compiler->verbose, ", ");
- sljit_verbose_fparam(compiler, src, srcw);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- if (SLJIT_UNLIKELY(compiler->skip_checks)) {
- compiler->skip_checks = 0;
- CHECK_RETURN_OK;
- }
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
- CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONV_F64_FROM_SW && GET_OPCODE(op) <= SLJIT_CONV_F64_FROM_S32);
- CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
- FUNCTION_CHECK_SRC(src, srcw);
- FUNCTION_FCHECK(dst, dstw);
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],
- (op & SLJIT_32) ? ".f32" : ".f64",
- (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) ? ".s32" : ".sw");
- sljit_verbose_fparam(compiler, dst, dstw);
- fprintf(compiler->verbose, ", ");
- sljit_verbose_param(compiler, src, srcw);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
- CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD_F64 && GET_OPCODE(op) <= SLJIT_DIV_F64);
- CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
- FUNCTION_FCHECK(src1, src1w);
- FUNCTION_FCHECK(src2, src2w);
- FUNCTION_FCHECK(dst, dstw);
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " %s%s ", fop2_names[GET_OPCODE(op) - SLJIT_FOP2_BASE], (op & SLJIT_32) ? ".f32" : ".f64");
- sljit_verbose_fparam(compiler, dst, dstw);
- fprintf(compiler->verbose, ", ");
- sljit_verbose_fparam(compiler, src1, src1w);
- fprintf(compiler->verbose, ", ");
- sljit_verbose_fparam(compiler, src2, src2w);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compiler *compiler)
-{
- SLJIT_UNUSED_ARG(compiler);
-
- if (SLJIT_UNLIKELY(compiler->skip_checks)) {
- compiler->skip_checks = 0;
- CHECK_RETURN_OK;
- }
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- compiler->last_flags = 0;
-#endif
-
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose))
- fprintf(compiler->verbose, "label:\n");
-#endif
- CHECK_RETURN_OK;
-}
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
-#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
- || (defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM)
-#define CHECK_UNORDERED(type, last_flags) \
- ((((type) & 0xff) == SLJIT_UNORDERED || ((type) & 0xff) == SLJIT_ORDERED) && \
- ((last_flags) & 0xff) >= SLJIT_UNORDERED && ((last_flags) & 0xff) <= SLJIT_ORDERED_LESS_EQUAL)
-#else
-#define CHECK_UNORDERED(type, last_flags) 0
-#endif
-#endif /* SLJIT_ARGUMENT_CHECKS */
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
-{
- if (SLJIT_UNLIKELY(compiler->skip_checks)) {
- compiler->skip_checks = 0;
- CHECK_RETURN_OK;
- }
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP)));
- CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_FAST_CALL);
-
- if ((type & 0xff) < SLJIT_JUMP) {
- if ((type & 0xff) <= SLJIT_NOT_ZERO)
- CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
- else if ((compiler->last_flags & 0xff) == SLJIT_CARRY) {
- CHECK_ARGUMENT((type & 0xff) == SLJIT_CARRY || (type & 0xff) == SLJIT_NOT_CARRY);
- compiler->last_flags = 0;
- } else
- CHECK_ARGUMENT((type & 0xff) == (compiler->last_flags & 0xff)
- || ((type & 0xff) == SLJIT_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_OVERFLOW)
- || CHECK_UNORDERED(type, compiler->last_flags));
- }
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose))
- fprintf(compiler->verbose, " jump%s %s\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",
- jump_names[type & 0xff]);
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types)
-{
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_CALL_RETURN)));
- CHECK_ARGUMENT((type & 0xff) >= SLJIT_CALL && (type & 0xff) <= SLJIT_CALL_REG_ARG);
- CHECK_ARGUMENT(function_check_arguments(arg_types, compiler->scratches, -1, compiler->fscratches));
-
- if (type & SLJIT_CALL_RETURN) {
- CHECK_ARGUMENT((arg_types & SLJIT_ARG_MASK) == compiler->last_return);
-
- if (compiler->options & SLJIT_ENTER_REG_ARG) {
- CHECK_ARGUMENT((type & 0xff) == SLJIT_CALL_REG_ARG);
- } else {
- CHECK_ARGUMENT((type & 0xff) != SLJIT_CALL_REG_ARG);
- }
- }
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " %s%s%s ret[%s", jump_names[type & 0xff],
- !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",
- !(type & SLJIT_CALL_RETURN) ? "" : ".ret",
- call_arg_names[arg_types & SLJIT_ARG_MASK]);
-
- arg_types >>= SLJIT_ARG_SHIFT;
- if (arg_types) {
- fprintf(compiler->verbose, "], args[");
- do {
- fprintf(compiler->verbose, "%s", call_arg_names[arg_types & SLJIT_ARG_MASK]);
- arg_types >>= SLJIT_ARG_SHIFT;
- if (arg_types)
- fprintf(compiler->verbose, ",");
- } while (arg_types);
- }
- fprintf(compiler->verbose, "]\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_32)));
- CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_SIG_LESS_EQUAL);
- FUNCTION_CHECK_SRC(src1, src1w);
- FUNCTION_CHECK_SRC(src2, src2w);
- compiler->last_flags = 0;
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " cmp%s%s %s, ", (type & SLJIT_32) ? "32" : "",
- !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]);
- sljit_verbose_param(compiler, src1, src1w);
- fprintf(compiler->verbose, ", ");
- sljit_verbose_param(compiler, src2, src2w);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
- CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_32)));
- CHECK_ARGUMENT((type & 0xff) >= SLJIT_F_EQUAL && (type & 0xff) <= SLJIT_ORDERED_LESS_EQUAL
- && ((type & 0xff) <= SLJIT_ORDERED || sljit_cmp_info(type & 0xff)));
- FUNCTION_FCHECK(src1, src1w);
- FUNCTION_FCHECK(src2, src2w);
- compiler->last_flags = 0;
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " fcmp%s%s %s, ", (type & SLJIT_32) ? ".f32" : ".f64",
- !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]);
- sljit_verbose_fparam(compiler, src1, src1w);
- fprintf(compiler->verbose, ", ");
- sljit_verbose_fparam(compiler, src2, src2w);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 src, sljit_sw srcw)
-{
- if (SLJIT_UNLIKELY(compiler->skip_checks)) {
- compiler->skip_checks = 0;
- CHECK_RETURN_OK;
- }
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(type >= SLJIT_JUMP && type <= SLJIT_FAST_CALL);
- FUNCTION_CHECK_SRC(src, srcw);
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " ijump.%s ", jump_names[type]);
- sljit_verbose_param(compiler, src, srcw);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types,
- sljit_s32 src, sljit_sw srcw)
-{
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_CALL_RETURN)));
- CHECK_ARGUMENT((type & 0xff) >= SLJIT_CALL && (type & 0xff) <= SLJIT_CALL_REG_ARG);
- CHECK_ARGUMENT(function_check_arguments(arg_types, compiler->scratches, -1, compiler->fscratches));
- FUNCTION_CHECK_SRC(src, srcw);
-
- if (type & SLJIT_CALL_RETURN) {
- CHECK_ARGUMENT((arg_types & SLJIT_ARG_MASK) == compiler->last_return);
-
- if (compiler->options & SLJIT_ENTER_REG_ARG) {
- CHECK_ARGUMENT((type & 0xff) == SLJIT_CALL_REG_ARG);
- } else {
- CHECK_ARGUMENT((type & 0xff) != SLJIT_CALL_REG_ARG);
- }
- }
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " i%s%s ret[%s", jump_names[type & 0xff],
- !(type & SLJIT_CALL_RETURN) ? "" : ".ret",
- call_arg_names[arg_types & SLJIT_ARG_MASK]);
-
- arg_types >>= SLJIT_ARG_SHIFT;
- if (arg_types) {
- fprintf(compiler->verbose, "], args[");
- do {
- fprintf(compiler->verbose, "%s", call_arg_names[arg_types & SLJIT_ARG_MASK]);
- arg_types >>= SLJIT_ARG_SHIFT;
- if (arg_types)
- fprintf(compiler->verbose, ",");
- } while (arg_types);
- }
- fprintf(compiler->verbose, "], ");
- sljit_verbose_param(compiler, src, srcw);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 type)
-{
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(type >= SLJIT_EQUAL && type <= SLJIT_ORDERED_LESS_EQUAL);
- CHECK_ARGUMENT(op == SLJIT_MOV || op == SLJIT_MOV32
- || (GET_OPCODE(op) >= SLJIT_AND && GET_OPCODE(op) <= SLJIT_XOR));
- CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK));
-
- if (type <= SLJIT_NOT_ZERO)
- CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
- else
- CHECK_ARGUMENT(type == (compiler->last_flags & 0xff)
- || (type == SLJIT_NOT_CARRY && (compiler->last_flags & 0xff) == SLJIT_CARRY)
- || (type == SLJIT_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_OVERFLOW)
- || CHECK_UNORDERED(type, compiler->last_flags));
-
- FUNCTION_CHECK_DST(dst, dstw);
-
- if (GET_OPCODE(op) >= SLJIT_ADD)
- compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_32 | SLJIT_SET_Z));
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " flags.%s%s%s ",
- GET_OPCODE(op) < SLJIT_OP2_BASE ? "mov" : op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE],
- GET_OPCODE(op) < SLJIT_OP2_BASE ? op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE] : ((op & SLJIT_32) ? "32" : ""),
- !(op & SLJIT_SET_Z) ? "" : ".z");
- sljit_verbose_param(compiler, dst, dstw);
- fprintf(compiler->verbose, ", %s\n", jump_names[type]);
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 dst_reg,
- sljit_s32 src, sljit_sw srcw)
-{
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- sljit_s32 cond = type & ~SLJIT_32;
-
- CHECK_ARGUMENT(cond >= SLJIT_EQUAL && cond <= SLJIT_ORDERED_LESS_EQUAL);
-
- CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1);
- CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg));
- if (src != SLJIT_IMM) {
- CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src));
- CHECK_ARGUMENT(srcw == 0);
- }
-
- if (cond <= SLJIT_NOT_ZERO)
- CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
- else
- CHECK_ARGUMENT(cond == (compiler->last_flags & 0xff)
- || (cond == SLJIT_NOT_CARRY && (compiler->last_flags & 0xff) == SLJIT_CARRY)
- || (cond == SLJIT_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_OVERFLOW)
- || CHECK_UNORDERED(cond, compiler->last_flags));
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " cmov%s %s, ",
- !(type & SLJIT_32) ? "" : "32",
- jump_names[type & ~SLJIT_32]);
- sljit_verbose_reg(compiler, dst_reg);
- fprintf(compiler->verbose, ", ");
- sljit_verbose_param(compiler, src, srcw);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 reg,
- sljit_s32 mem, sljit_sw memw)
-{
- if (SLJIT_UNLIKELY(compiler->skip_checks)) {
- compiler->skip_checks = 0;
- CHECK_RETURN_OK;
- }
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- sljit_s32 allowed_flags;
-
- if (type & SLJIT_MEM_UNALIGNED) {
- CHECK_ARGUMENT(!(type & (SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32)));
- } else if (type & SLJIT_MEM_UNALIGNED_16) {
- CHECK_ARGUMENT(!(type & SLJIT_MEM_UNALIGNED_32));
- } else {
- CHECK_ARGUMENT((reg & REG_PAIR_MASK) || (type & SLJIT_MEM_UNALIGNED_32));
- }
-
- allowed_flags = SLJIT_MEM_UNALIGNED;
-
- switch (type & 0xff) {
- case SLJIT_MOV_U32:
- case SLJIT_MOV_S32:
- case SLJIT_MOV32:
- allowed_flags = SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16;
- break;
- case SLJIT_MOV:
- case SLJIT_MOV_P:
- allowed_flags = SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32;
- break;
- }
-
- CHECK_ARGUMENT((type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | allowed_flags)) == 0);
-
- if (reg & REG_PAIR_MASK) {
- CHECK_ARGUMENT((type & 0xff) == SLJIT_MOV);
- CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(REG_PAIR_FIRST(reg)));
- CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(REG_PAIR_SECOND(reg)));
- CHECK_ARGUMENT(REG_PAIR_FIRST(reg) != REG_PAIR_SECOND(reg));
- } else {
- CHECK_ARGUMENT((type & 0xff) >= SLJIT_MOV && (type & 0xff) <= SLJIT_MOV_P);
- CHECK_ARGUMENT(!(type & SLJIT_32) || ((type & 0xff) >= SLJIT_MOV_U8 && (type & 0xff) <= SLJIT_MOV_S16));
- CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg));
- }
-
- FUNCTION_CHECK_SRC_MEM(mem, memw);
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- if ((type & 0xff) == SLJIT_MOV32)
- fprintf(compiler->verbose, " %s32",
- (type & SLJIT_MEM_STORE) ? "store" : "load");
- else
- fprintf(compiler->verbose, " %s%s%s",
- (type & SLJIT_MEM_STORE) ? "store" : "load",
- !(type & SLJIT_32) ? "" : "32",
- op1_names[(type & 0xff) - SLJIT_OP1_BASE]);
-
- if (type & SLJIT_MEM_UNALIGNED)
- printf(".un");
- else if (type & SLJIT_MEM_UNALIGNED_16)
- printf(".un16");
- else if (type & SLJIT_MEM_UNALIGNED_32)
- printf(".un32");
-
- if (reg & REG_PAIR_MASK) {
- fprintf(compiler->verbose, " {");
- sljit_verbose_reg(compiler, REG_PAIR_FIRST(reg));
- fprintf(compiler->verbose, ", ");
- sljit_verbose_reg(compiler, REG_PAIR_SECOND(reg));
- fprintf(compiler->verbose, "}, ");
- } else {
- fprintf(compiler->verbose, " ");
- sljit_verbose_reg(compiler, reg);
- fprintf(compiler->verbose, ", ");
- }
- sljit_verbose_param(compiler, mem, memw);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 reg,
- sljit_s32 mem, sljit_sw memw)
-{
- if (SLJIT_UNLIKELY(compiler->skip_checks)) {
- compiler->skip_checks = 0;
- CHECK_RETURN_OK;
- }
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT((type & 0xff) >= SLJIT_MOV && (type & 0xff) <= SLJIT_MOV_P);
- CHECK_ARGUMENT((type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_SUPP | SLJIT_MEM_POST)) == 0);
- CHECK_ARGUMENT((mem & REG_MASK) != 0 && (mem & REG_MASK) != reg);
-
- FUNCTION_CHECK_SRC_MEM(mem, memw);
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- if (type & SLJIT_MEM_SUPP)
- CHECK_RETURN_OK;
- if (sljit_emit_mem_update(compiler, type | SLJIT_MEM_SUPP, reg, mem, memw) == SLJIT_ERR_UNSUPPORTED) {
- fprintf(compiler->verbose, " # mem: unsupported form, no instructions are emitted\n");
- CHECK_RETURN_OK;
- }
-
- if ((type & 0xff) == SLJIT_MOV32)
- fprintf(compiler->verbose, " %s32.%s ",
- (type & SLJIT_MEM_STORE) ? "store" : "load",
- (type & SLJIT_MEM_POST) ? "post" : "pre");
- else
- fprintf(compiler->verbose, " %s%s%s.%s ",
- (type & SLJIT_MEM_STORE) ? "store" : "load",
- !(type & SLJIT_32) ? "" : "32",
- op1_names[(type & 0xff) - SLJIT_OP1_BASE],
- (type & SLJIT_MEM_POST) ? "post" : "pre");
-
- sljit_verbose_reg(compiler, reg);
- fprintf(compiler->verbose, ", ");
- sljit_verbose_param(compiler, mem, memw);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 freg,
- sljit_s32 mem, sljit_sw memw)
-{
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT((type & 0xff) == SLJIT_MOV_F64);
-
- if (type & SLJIT_MEM_UNALIGNED) {
- CHECK_ARGUMENT(!(type & (SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32)));
- } else if (type & SLJIT_MEM_UNALIGNED_16) {
- CHECK_ARGUMENT(!(type & SLJIT_MEM_UNALIGNED_32));
- } else {
- CHECK_ARGUMENT(type & SLJIT_MEM_UNALIGNED_32);
- CHECK_ARGUMENT(!(type & SLJIT_32));
- }
-
- CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32)));
- CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg));
- FUNCTION_CHECK_SRC_MEM(mem, memw);
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " %s.%s",
- (type & SLJIT_MEM_STORE) ? "store" : "load",
- !(type & SLJIT_32) ? "f64" : "f32");
-
- if (type & SLJIT_MEM_UNALIGNED)
- printf(".un");
- else if (type & SLJIT_MEM_UNALIGNED_16)
- printf(".un16");
- else if (type & SLJIT_MEM_UNALIGNED_32)
- printf(".un32");
-
- fprintf(compiler->verbose, " ");
- sljit_verbose_freg(compiler, freg);
- fprintf(compiler->verbose, ", ");
- sljit_verbose_param(compiler, mem, memw);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem_update(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 freg,
- sljit_s32 mem, sljit_sw memw)
-{
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT((type & 0xff) == SLJIT_MOV_F64);
- CHECK_ARGUMENT((type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_SUPP | SLJIT_MEM_POST)) == 0);
- FUNCTION_CHECK_SRC_MEM(mem, memw);
- CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg));
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- if (type & SLJIT_MEM_SUPP)
- CHECK_RETURN_OK;
- if (sljit_emit_fmem_update(compiler, type | SLJIT_MEM_SUPP, freg, mem, memw) == SLJIT_ERR_UNSUPPORTED) {
- fprintf(compiler->verbose, " # fmem: unsupported form, no instructions are emitted\n");
- CHECK_RETURN_OK;
- }
-
- fprintf(compiler->verbose, " %s.%s.%s ",
- (type & SLJIT_MEM_STORE) ? "store" : "load",
- !(type & SLJIT_32) ? "f64" : "f32",
- (type & SLJIT_MEM_POST) ? "post" : "pre");
-
- sljit_verbose_freg(compiler, freg);
- fprintf(compiler->verbose, ", ");
- sljit_verbose_param(compiler, mem, memw);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
-{
- /* Any offset is allowed. */
- SLJIT_UNUSED_ARG(offset);
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- FUNCTION_CHECK_DST(dst, dstw);
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " local_base ");
- sljit_verbose_param(compiler, dst, dstw);
- fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", offset);
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
-{
- SLJIT_UNUSED_ARG(init_value);
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- FUNCTION_CHECK_DST(dst, dstw);
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " const ");
- sljit_verbose_param(compiler, dst, dstw);
- fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", init_value);
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
-{
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- FUNCTION_CHECK_DST(dst, dstw);
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " put_label ");
- sljit_verbose_param(compiler, dst, dstw);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
-#else /* !SLJIT_ARGUMENT_CHECKS && !SLJIT_VERBOSE */
-
-#define SLJIT_SKIP_CHECKS(compiler)
-
-#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */
-
-#define SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw) \
- SLJIT_COMPILE_ASSERT(!(SLJIT_CONV_SW_FROM_F64 & 0x1) && !(SLJIT_CONV_F64_FROM_SW & 0x1), \
- invalid_float_opcodes); \
- if (GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CMP_F64) { \
- if (GET_OPCODE(op) == SLJIT_CMP_F64) { \
- CHECK(check_sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw)); \
- ADJUST_LOCAL_OFFSET(dst, dstw); \
- ADJUST_LOCAL_OFFSET(src, srcw); \
- return sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw); \
- } \
- if ((GET_OPCODE(op) | 0x1) == SLJIT_CONV_S32_FROM_F64) { \
- CHECK(check_sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw)); \
- ADJUST_LOCAL_OFFSET(dst, dstw); \
- ADJUST_LOCAL_OFFSET(src, srcw); \
- return sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw); \
- } \
- CHECK(check_sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw)); \
- ADJUST_LOCAL_OFFSET(dst, dstw); \
- ADJUST_LOCAL_OFFSET(src, srcw); \
- return sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw); \
- } \
- CHECK(check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw)); \
- ADJUST_LOCAL_OFFSET(dst, dstw); \
- ADJUST_LOCAL_OFFSET(src, srcw);
-
-#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
- || (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \
- || ((defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) && !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)) \
- || (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \
- || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
-
-static SLJIT_INLINE sljit_s32 sljit_emit_cmov_generic(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 dst_reg,
- sljit_s32 src, sljit_sw srcw)
-{
- struct sljit_label *label;
- struct sljit_jump *jump;
- sljit_s32 op = (type & SLJIT_32) ? SLJIT_MOV32 : SLJIT_MOV;
-
- SLJIT_SKIP_CHECKS(compiler);
- jump = sljit_emit_jump(compiler, (type & ~SLJIT_32) ^ 0x1);
- FAIL_IF(!jump);
-
- SLJIT_SKIP_CHECKS(compiler);
- FAIL_IF(sljit_emit_op1(compiler, op, dst_reg, 0, src, srcw));
-
- SLJIT_SKIP_CHECKS(compiler);
- label = sljit_emit_label(compiler);
- FAIL_IF(!label);
-
- sljit_set_label(jump, label);
- return SLJIT_SUCCESS;
-}
-
-#endif
-
-#if (!(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) || (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)) \
- && !(defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
-
-static sljit_s32 sljit_emit_mem_unaligned(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 reg,
- sljit_s32 mem, sljit_sw memw)
-{
- SLJIT_SKIP_CHECKS(compiler);
-
- if (type & SLJIT_MEM_STORE)
- return sljit_emit_op1(compiler, type & (0xff | SLJIT_32), mem, memw, reg, 0);
- return sljit_emit_op1(compiler, type & (0xff | SLJIT_32), reg, 0, mem, memw);
-}
-
-#endif /* (!SLJIT_CONFIG_MIPS || SLJIT_MIPS_REV >= 6) && !SLJIT_CONFIG_ARM_V5 */
-
-#if (!(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) || (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)) \
- && !(defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32)
-
-static sljit_s32 sljit_emit_fmem_unaligned(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 freg,
- sljit_s32 mem, sljit_sw memw)
-{
- SLJIT_SKIP_CHECKS(compiler);
-
- if (type & SLJIT_MEM_STORE)
- return sljit_emit_fop1(compiler, type & (0xff | SLJIT_32), mem, memw, freg, 0);
- return sljit_emit_fop1(compiler, type & (0xff | SLJIT_32), freg, 0, mem, memw);
-}
-
-#endif /* (!SLJIT_CONFIG_MIPS || SLJIT_MIPS_REV >= 6) && !SLJIT_CONFIG_ARM */
-
-/* CPU description section */
-
-#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
-#define SLJIT_CPUINFO_PART1 " 32bit ("
-#elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
-#define SLJIT_CPUINFO_PART1 " 64bit ("
-#else
-#error "Internal error: CPU type info missing"
-#endif
-
-#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
-#define SLJIT_CPUINFO_PART2 "little endian + "
-#elif (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN)
-#define SLJIT_CPUINFO_PART2 "big endian + "
-#else
-#error "Internal error: CPU type info missing"
-#endif
-
-#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED)
-#define SLJIT_CPUINFO_PART3 "unaligned)"
-#else
-#define SLJIT_CPUINFO_PART3 "aligned)"
-#endif
-
-#define SLJIT_CPUINFO SLJIT_CPUINFO_PART1 SLJIT_CPUINFO_PART2 SLJIT_CPUINFO_PART3
-
-#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
-# include "sljitNativeX86_common.c"
-#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
-# include "sljitNativeARM_32.c"
-#elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
-# include "sljitNativeARM_32.c"
-#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
-# include "sljitNativeARM_T2_32.c"
-#elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
-# include "sljitNativeARM_64.c"
-#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
-# include "sljitNativePPC_common.c"
-#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
-# include "sljitNativeMIPS_common.c"
-#elif (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
-# include "sljitNativeRISCV_common.c"
-#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
-# include "sljitNativeS390X.c"
-#endif
-
-static SLJIT_INLINE sljit_s32 emit_mov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
-{
-#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
- /* At the moment the pointer size is always equal to sljit_sw. May be changed in the future. */
- if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_P))
- return SLJIT_SUCCESS;
-#else
- if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_U32 || op == SLJIT_MOV_S32 || op == SLJIT_MOV_P))
- return SLJIT_SUCCESS;
-#endif
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_op1(compiler, op, SLJIT_RETURN_REG, 0, src, srcw);
-}
-
-#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
- && !((defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && defined __SOFTFP__)
-
-static SLJIT_INLINE sljit_s32 emit_fmov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
-{
- if (src == SLJIT_FR0)
- return SLJIT_SUCCESS;
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_fop1(compiler, op, SLJIT_RETURN_FREG, 0, src, srcw);
-}
-
-#endif /* !SLJIT_CONFIG_X86_32 && !(SLJIT_CONFIG_ARM_32 && __SOFTFP__) */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_return(compiler, op, src, srcw));
-
- if (GET_OPCODE(op) < SLJIT_MOV_F64) {
- FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
- } else {
- FAIL_IF(emit_fmov_before_return(compiler, op, src, srcw));
- }
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_return_void(compiler);
-}
-
-#if !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) \
- && !(defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- /* Default compare for most architectures. */
- sljit_s32 flags, tmp_src, condition;
- sljit_sw tmp_srcw;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
-
- condition = type & 0xff;
-#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
- if ((condition == SLJIT_EQUAL || condition == SLJIT_NOT_EQUAL)) {
- if ((src1 & SLJIT_IMM) && !src1w) {
- src1 = src2;
- src1w = src2w;
- src2 = SLJIT_IMM;
- src2w = 0;
- }
- if ((src2 & SLJIT_IMM) && !src2w)
- return emit_cmp_to0(compiler, type, src1, src1w);
- }
-#endif
-
- if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) {
- /* Immediate is preferred as second argument by most architectures. */
- switch (condition) {
- case SLJIT_LESS:
- condition = SLJIT_GREATER;
- break;
- case SLJIT_GREATER_EQUAL:
- condition = SLJIT_LESS_EQUAL;
- break;
- case SLJIT_GREATER:
- condition = SLJIT_LESS;
- break;
- case SLJIT_LESS_EQUAL:
- condition = SLJIT_GREATER_EQUAL;
- break;
- case SLJIT_SIG_LESS:
- condition = SLJIT_SIG_GREATER;
- break;
- case SLJIT_SIG_GREATER_EQUAL:
- condition = SLJIT_SIG_LESS_EQUAL;
- break;
- case SLJIT_SIG_GREATER:
- condition = SLJIT_SIG_LESS;
- break;
- case SLJIT_SIG_LESS_EQUAL:
- condition = SLJIT_SIG_GREATER_EQUAL;
- break;
- }
-
- type = condition | (type & (SLJIT_32 | SLJIT_REWRITABLE_JUMP));
- tmp_src = src1;
- src1 = src2;
- src2 = tmp_src;
- tmp_srcw = src1w;
- src1w = src2w;
- src2w = tmp_srcw;
- }
-
- if (condition <= SLJIT_NOT_ZERO)
- flags = SLJIT_SET_Z;
- else
- flags = condition << VARIABLE_FLAG_SHIFT;
-
- SLJIT_SKIP_CHECKS(compiler);
- PTR_FAIL_IF(sljit_emit_op2u(compiler,
- SLJIT_SUB | flags | (type & SLJIT_32), src1, src1w, src2, src2w));
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_jump(compiler, condition | (type & (SLJIT_REWRITABLE_JUMP | SLJIT_32)));
-}
-
-#endif /* !SLJIT_CONFIG_MIPS */
-
-#if (defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM)
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)
-{
- if (type < SLJIT_UNORDERED || type > SLJIT_ORDERED_LESS_EQUAL)
- return 0;
-
- switch (type) {
- case SLJIT_UNORDERED_OR_EQUAL:
- case SLJIT_ORDERED_NOT_EQUAL:
- return 0;
- }
-
- return 1;
-}
-
-#endif /* SLJIT_CONFIG_ARM */
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w));
-
- SLJIT_SKIP_CHECKS(compiler);
- sljit_emit_fop1(compiler, SLJIT_CMP_F64 | ((type & 0xff) << VARIABLE_FLAG_SHIFT) | (type & SLJIT_32), src1, src1w, src2, src2w);
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_jump(compiler, type);
-}
-
-#if !(defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM) \
- && !(defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 reg,
- sljit_s32 mem, sljit_sw memw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_mem_update(compiler, type, reg, mem, memw));
- SLJIT_UNUSED_ARG(type);
- SLJIT_UNUSED_ARG(reg);
- SLJIT_UNUSED_ARG(mem);
- SLJIT_UNUSED_ARG(memw);
-
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-#endif /* !SLJIT_CONFIG_ARM && !SLJIT_CONFIG_PPC */
-
-#if !(defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \
- && !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 freg,
- sljit_s32 mem, sljit_sw memw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
-
- return sljit_emit_fmem_unaligned(compiler, type, freg, mem, memw);
-}
-
-#endif /* !SLJIT_CONFIG_ARM_32 && !SLJIT_CONFIG_MIPS */
-
-#if !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
- && !(defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 freg,
- sljit_s32 mem, sljit_sw memw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_fmem_update(compiler, type, freg, mem, memw));
- SLJIT_UNUSED_ARG(type);
- SLJIT_UNUSED_ARG(freg);
- SLJIT_UNUSED_ARG(mem);
- SLJIT_UNUSED_ARG(memw);
-
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-#endif /* !SLJIT_CONFIG_ARM_64 && !SLJIT_CONFIG_PPC */
-
-#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
- && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
-{
- CHECK_ERROR();
- CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset));
-
- ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset);
-
- SLJIT_SKIP_CHECKS(compiler);
-
- if (offset != 0)
- return sljit_emit_op2(compiler, SLJIT_ADD, dst, dstw, SLJIT_SP, 0, SLJIT_IMM, offset);
- return sljit_emit_op1(compiler, SLJIT_MOV, dst, dstw, SLJIT_SP, 0);
-}
-
-#endif
-
-#else /* SLJIT_CONFIG_UNSUPPORTED */
-
-/* Empty function bodies for those machines, which are not (yet) supported. */
-
-SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
-{
- return "unsupported";
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data)
-{
- SLJIT_UNUSED_ARG(allocator_data);
- SLJIT_UNUSED_ARG(exec_allocator_data);
- SLJIT_UNREACHABLE();
- return NULL;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNREACHABLE();
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNREACHABLE();
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(size);
- SLJIT_UNREACHABLE();
- return NULL;
-}
-
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
-SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(verbose);
- SLJIT_UNREACHABLE();
-}
-#endif
-
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNREACHABLE();
- return NULL;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
-{
- SLJIT_UNUSED_ARG(feature_type);
- SLJIT_UNREACHABLE();
- return 0;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)
-{
- SLJIT_UNUSED_ARG(type);
- SLJIT_UNREACHABLE();
- return 0;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
-{
- SLJIT_UNUSED_ARG(code);
- SLJIT_UNUSED_ARG(exec_allocator_data);
- SLJIT_UNREACHABLE();
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(options);
- SLJIT_UNUSED_ARG(arg_types);
- SLJIT_UNUSED_ARG(scratches);
- SLJIT_UNUSED_ARG(saveds);
- SLJIT_UNUSED_ARG(fscratches);
- SLJIT_UNUSED_ARG(fsaveds);
- SLJIT_UNUSED_ARG(local_size);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(options);
- SLJIT_UNUSED_ARG(arg_types);
- SLJIT_UNUSED_ARG(scratches);
- SLJIT_UNUSED_ARG(saveds);
- SLJIT_UNUSED_ARG(fscratches);
- SLJIT_UNUSED_ARG(fsaveds);
- SLJIT_UNUSED_ARG(local_size);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(op);
- SLJIT_UNUSED_ARG(src);
- SLJIT_UNUSED_ARG(srcw);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(src);
- SLJIT_UNUSED_ARG(srcw);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(dst);
- SLJIT_UNUSED_ARG(dstw);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(op);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(op);
- SLJIT_UNUSED_ARG(dst);
- SLJIT_UNUSED_ARG(dstw);
- SLJIT_UNUSED_ARG(src);
- SLJIT_UNUSED_ARG(srcw);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(op);
- SLJIT_UNUSED_ARG(dst);
- SLJIT_UNUSED_ARG(dstw);
- SLJIT_UNUSED_ARG(src1);
- SLJIT_UNUSED_ARG(src1w);
- SLJIT_UNUSED_ARG(src2);
- SLJIT_UNUSED_ARG(src2w);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(op);
- SLJIT_UNUSED_ARG(src1);
- SLJIT_UNUSED_ARG(src1w);
- SLJIT_UNUSED_ARG(src2);
- SLJIT_UNUSED_ARG(src2w);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src_dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(op);
- SLJIT_UNUSED_ARG(src_dst);
- SLJIT_UNUSED_ARG(src1);
- SLJIT_UNUSED_ARG(src1w);
- SLJIT_UNUSED_ARG(src2);
- SLJIT_UNUSED_ARG(src2w);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src, sljit_sw srcw)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(op);
- SLJIT_UNUSED_ARG(src);
- SLJIT_UNUSED_ARG(srcw);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
-{
- SLJIT_UNREACHABLE();
- return reg;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
- void *instruction, sljit_u32 size)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(instruction);
- SLJIT_UNUSED_ARG(size);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler, sljit_s32 current_flags)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(current_flags);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(op);
- SLJIT_UNUSED_ARG(dst);
- SLJIT_UNUSED_ARG(dstw);
- SLJIT_UNUSED_ARG(src);
- SLJIT_UNUSED_ARG(srcw);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(op);
- SLJIT_UNUSED_ARG(dst);
- SLJIT_UNUSED_ARG(dstw);
- SLJIT_UNUSED_ARG(src1);
- SLJIT_UNUSED_ARG(src1w);
- SLJIT_UNUSED_ARG(src2);
- SLJIT_UNUSED_ARG(src2w);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNREACHABLE();
- return NULL;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(type);
- SLJIT_UNREACHABLE();
- return NULL;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(type);
- SLJIT_UNUSED_ARG(arg_types);
- SLJIT_UNREACHABLE();
- return NULL;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(type);
- SLJIT_UNUSED_ARG(src1);
- SLJIT_UNUSED_ARG(src1w);
- SLJIT_UNUSED_ARG(src2);
- SLJIT_UNUSED_ARG(src2w);
- SLJIT_UNREACHABLE();
- return NULL;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(type);
- SLJIT_UNUSED_ARG(src1);
- SLJIT_UNUSED_ARG(src1w);
- SLJIT_UNUSED_ARG(src2);
- SLJIT_UNUSED_ARG(src2w);
- SLJIT_UNREACHABLE();
- return NULL;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)
-{
- SLJIT_UNUSED_ARG(jump);
- SLJIT_UNUSED_ARG(label);
- SLJIT_UNREACHABLE();
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
-{
- SLJIT_UNUSED_ARG(jump);
- SLJIT_UNUSED_ARG(target);
- SLJIT_UNREACHABLE();
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label)
-{
- SLJIT_UNUSED_ARG(put_label);
- SLJIT_UNUSED_ARG(label);
- SLJIT_UNREACHABLE();
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(type);
- SLJIT_UNUSED_ARG(src);
- SLJIT_UNUSED_ARG(srcw);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types,
- sljit_s32 src, sljit_sw srcw)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(type);
- SLJIT_UNUSED_ARG(arg_types);
- SLJIT_UNUSED_ARG(src);
- SLJIT_UNUSED_ARG(srcw);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 type)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(op);
- SLJIT_UNUSED_ARG(dst);
- SLJIT_UNUSED_ARG(dstw);
- SLJIT_UNUSED_ARG(type);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 dst_reg,
- sljit_s32 src, sljit_sw srcw)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(type);
- SLJIT_UNUSED_ARG(dst_reg);
- SLJIT_UNUSED_ARG(src);
- SLJIT_UNUSED_ARG(srcw);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 reg, sljit_s32 mem, sljit_sw memw)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(type);
- SLJIT_UNUSED_ARG(reg);
- SLJIT_UNUSED_ARG(mem);
- SLJIT_UNUSED_ARG(memw);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 reg, sljit_s32 mem, sljit_sw memw)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(type);
- SLJIT_UNUSED_ARG(reg);
- SLJIT_UNUSED_ARG(mem);
- SLJIT_UNUSED_ARG(memw);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 freg, sljit_s32 mem, sljit_sw memw)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(type);
- SLJIT_UNUSED_ARG(freg);
- SLJIT_UNUSED_ARG(mem);
- SLJIT_UNUSED_ARG(memw);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 freg, sljit_s32 mem, sljit_sw memw)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(type);
- SLJIT_UNUSED_ARG(freg);
- SLJIT_UNUSED_ARG(mem);
- SLJIT_UNUSED_ARG(memw);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(dst);
- SLJIT_UNUSED_ARG(dstw);
- SLJIT_UNUSED_ARG(offset);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw initval)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(dst);
- SLJIT_UNUSED_ARG(dstw);
- SLJIT_UNUSED_ARG(initval);
- SLJIT_UNREACHABLE();
- return NULL;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(dst);
- SLJIT_UNUSED_ARG(dstw);
- return NULL;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
-{
- SLJIT_UNUSED_ARG(addr);
- SLJIT_UNUSED_ARG(new_target);
- SLJIT_UNUSED_ARG(executable_offset);
- SLJIT_UNREACHABLE();
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
-{
- SLJIT_UNUSED_ARG(addr);
- SLJIT_UNUSED_ARG(new_constant);
- SLJIT_UNUSED_ARG(executable_offset);
- SLJIT_UNREACHABLE();
-}
-
-#endif /* !SLJIT_CONFIG_UNSUPPORTED */
diff --git a/contrib/libs/pcre2/src/sljit/sljitLir.h b/contrib/libs/pcre2/src/sljit/sljitLir.h
deleted file mode 100644
index a666a2643f..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitLir.h
+++ /dev/null
@@ -1,1823 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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.
- */
-
-#ifndef SLJIT_LIR_H_
-#define SLJIT_LIR_H_
-
-/*
- ------------------------------------------------------------------------
- Stack-Less JIT compiler for multiple architectures (x86, ARM, PowerPC)
- ------------------------------------------------------------------------
-
- Short description
- Advantages:
- - The execution can be continued from any LIR instruction. In other
- words, it is possible to jump to any label from anywhere, even from
- a code fragment, which is compiled later, as long as the compiling
- context is the same. See sljit_emit_enter for more details.
- - Supports self modifying code: target of any jump and call
- instructions and some constant values can be dynamically modified
- during runtime. See SLJIT_REWRITABLE_JUMP.
- - although it is not suggested to do it frequently
- - can be used for inline caching: save an important value once
- in the instruction stream
- - A fixed stack space can be allocated for local variables
- - The compiler is thread-safe
- - The compiler is highly configurable through preprocessor macros.
- You can disable unneeded features (multithreading in single
- threaded applications), and you can use your own system functions
- (including memory allocators). See sljitConfig.h.
- Disadvantages:
- - The compiler is more like a platform independent assembler, so
- there is no built-in variable management. Registers and stack must
- be managed manually (the name of the compiler refers to this).
- In practice:
- - This approach is very effective for interpreters
- - One of the saved registers typically points to a stack interface
- - It can jump to any exception handler anytime (even if it belongs
- to another function)
- - Hot paths can be modified during runtime reflecting the changes
- of the fastest execution path of the dynamic language
- - SLJIT supports complex memory addressing modes
- - mainly position and context independent code (except some cases)
-
- For valgrind users:
- - pass --smc-check=all argument to valgrind, since JIT is a "self-modifying code"
-*/
-
-#if (defined SLJIT_HAVE_CONFIG_PRE && SLJIT_HAVE_CONFIG_PRE)
-#error #include "sljitConfigPre.h"
-#endif /* SLJIT_HAVE_CONFIG_PRE */
-
-#include "sljitConfig.h"
-
-/* The following header file defines useful macros for fine tuning
-SLJIT based code generators. They are listed in the beginning
-of sljitConfigInternal.h */
-
-#include "sljitConfigInternal.h"
-
-#if (defined SLJIT_HAVE_CONFIG_POST && SLJIT_HAVE_CONFIG_POST)
-#error #include "sljitConfigPost.h"
-#endif /* SLJIT_HAVE_CONFIG_POST */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Version numbers. */
-#define SLJIT_MAJOR_VERSION 0
-#define SLJIT_MINOR_VERSION 95
-
-/* --------------------------------------------------------------------- */
-/* Error codes */
-/* --------------------------------------------------------------------- */
-
-/* Indicates no error. */
-#define SLJIT_SUCCESS 0
-/* After the call of sljit_generate_code(), the error code of the compiler
- is set to this value to avoid further code generation.
- The complier should be freed after sljit_generate_code(). */
-#define SLJIT_ERR_COMPILED 1
-/* Cannot allocate non-executable memory. */
-#define SLJIT_ERR_ALLOC_FAILED 2
-/* Cannot allocate executable memory.
- Only sljit_generate_code() returns with this error code. */
-#define SLJIT_ERR_EX_ALLOC_FAILED 3
-/* Return value for SLJIT_CONFIG_UNSUPPORTED placeholder architecture. */
-#define SLJIT_ERR_UNSUPPORTED 4
-/* An ivalid argument is passed to any SLJIT function. */
-#define SLJIT_ERR_BAD_ARGUMENT 5
-
-/* --------------------------------------------------------------------- */
-/* Registers */
-/* --------------------------------------------------------------------- */
-
-/*
- Scratch (R) registers: registers which may not preserve their values
- across function calls.
-
- Saved (S) registers: registers which preserve their values across
- function calls.
-
- The scratch and saved register sets overlap. The last scratch register
- is the first saved register, the one before the last is the second saved
- register, and so on.
-
- If an architecture provides two scratch and three saved registers,
- its scratch and saved register sets are the following:
-
- R0 | | R0 is always a scratch register
- R1 | | R1 is always a scratch register
- [R2] | S2 | R2 and S2 represent the same physical register
- [R3] | S1 | R3 and S1 represent the same physical register
- [R4] | S0 | R4 and S0 represent the same physical register
-
- Note: SLJIT_NUMBER_OF_SCRATCH_REGISTERS would be 2 and
- SLJIT_NUMBER_OF_SAVED_REGISTERS would be 3 for this architecture.
-
- Note: On all supported architectures SLJIT_NUMBER_OF_REGISTERS >= 12
- and SLJIT_NUMBER_OF_SAVED_REGISTERS >= 6. However, 6 registers
- are virtual on x86-32. See below.
-
- The purpose of this definition is convenience: saved registers can
- be used as extra scratch registers. For example four registers can
- be specified as scratch registers and the fifth one as saved register
- on the CPU above and any user code which requires four scratch
- registers can run unmodified. The SLJIT compiler automatically saves
- the content of the two extra scratch register on the stack. Scratch
- registers can also be preserved by saving their value on the stack
- but this needs to be done manually.
-
- Note: To emphasize that registers assigned to R2-R4 are saved
- registers, they are enclosed by square brackets.
-
- Note: sljit_emit_enter and sljit_set_context defines whether a register
- is S or R register. E.g: when 3 scratches and 1 saved is mapped
- by sljit_emit_enter, the allowed register set will be: R0-R2 and
- S0. Although S2 is mapped to the same position as R2, it does not
- available in the current configuration. Furthermore the S1 register
- is not available at all.
-*/
-
-/* Scratch registers. */
-#define SLJIT_R0 1
-#define SLJIT_R1 2
-#define SLJIT_R2 3
-/* Note: on x86-32, R3 - R6 (same as S3 - S6) are emulated (they
- are allocated on the stack). These registers are called virtual
- and cannot be used for memory addressing (cannot be part of
- any SLJIT_MEM1, SLJIT_MEM2 construct). There is no such
- limitation on other CPUs. See sljit_get_register_index(). */
-#define SLJIT_R3 4
-#define SLJIT_R4 5
-#define SLJIT_R5 6
-#define SLJIT_R6 7
-#define SLJIT_R7 8
-#define SLJIT_R8 9
-#define SLJIT_R9 10
-/* All R registers provided by the architecture can be accessed by SLJIT_R(i)
- The i parameter must be >= 0 and < SLJIT_NUMBER_OF_REGISTERS. */
-#define SLJIT_R(i) (1 + (i))
-
-/* Saved registers. */
-#define SLJIT_S0 (SLJIT_NUMBER_OF_REGISTERS)
-#define SLJIT_S1 (SLJIT_NUMBER_OF_REGISTERS - 1)
-#define SLJIT_S2 (SLJIT_NUMBER_OF_REGISTERS - 2)
-/* Note: on x86-32, S3 - S6 (same as R3 - R6) are emulated (they
- are allocated on the stack). These registers are called virtual
- and cannot be used for memory addressing (cannot be part of
- any SLJIT_MEM1, SLJIT_MEM2 construct). There is no such
- limitation on other CPUs. See sljit_get_register_index(). */
-#define SLJIT_S3 (SLJIT_NUMBER_OF_REGISTERS - 3)
-#define SLJIT_S4 (SLJIT_NUMBER_OF_REGISTERS - 4)
-#define SLJIT_S5 (SLJIT_NUMBER_OF_REGISTERS - 5)
-#define SLJIT_S6 (SLJIT_NUMBER_OF_REGISTERS - 6)
-#define SLJIT_S7 (SLJIT_NUMBER_OF_REGISTERS - 7)
-#define SLJIT_S8 (SLJIT_NUMBER_OF_REGISTERS - 8)
-#define SLJIT_S9 (SLJIT_NUMBER_OF_REGISTERS - 9)
-/* All S registers provided by the architecture can be accessed by SLJIT_S(i)
- The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_REGISTERS. */
-#define SLJIT_S(i) (SLJIT_NUMBER_OF_REGISTERS - (i))
-
-/* Registers >= SLJIT_FIRST_SAVED_REG are saved registers. */
-#define SLJIT_FIRST_SAVED_REG (SLJIT_S0 - SLJIT_NUMBER_OF_SAVED_REGISTERS + 1)
-
-/* The SLJIT_SP provides direct access to the linear stack space allocated by
- sljit_emit_enter. It can only be used in the following form: SLJIT_MEM1(SLJIT_SP).
- The immediate offset is extended by the relative stack offset automatically.
- The sljit_get_local_base can be used to obtain the real address of a value. */
-#define SLJIT_SP (SLJIT_NUMBER_OF_REGISTERS + 1)
-
-/* Return with machine word. */
-
-#define SLJIT_RETURN_REG SLJIT_R0
-
-/* --------------------------------------------------------------------- */
-/* Floating point registers */
-/* --------------------------------------------------------------------- */
-
-/* Each floating point register can store a 32 or a 64 bit precision
- value. The FR and FS register sets are overlap in the same way as R
- and S register sets. See above. */
-
-/* Floating point scratch registers. */
-#define SLJIT_FR0 1
-#define SLJIT_FR1 2
-#define SLJIT_FR2 3
-#define SLJIT_FR3 4
-#define SLJIT_FR4 5
-#define SLJIT_FR5 6
-/* All FR registers provided by the architecture can be accessed by SLJIT_FR(i)
- The i parameter must be >= 0 and < SLJIT_NUMBER_OF_FLOAT_REGISTERS. */
-#define SLJIT_FR(i) (1 + (i))
-
-/* Floating point saved registers. */
-#define SLJIT_FS0 (SLJIT_NUMBER_OF_FLOAT_REGISTERS)
-#define SLJIT_FS1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 1)
-#define SLJIT_FS2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 2)
-#define SLJIT_FS3 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 3)
-#define SLJIT_FS4 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 4)
-#define SLJIT_FS5 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 5)
-/* All S registers provided by the architecture can be accessed by SLJIT_FS(i)
- The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS. */
-#define SLJIT_FS(i) (SLJIT_NUMBER_OF_FLOAT_REGISTERS - (i))
-
-/* Float registers >= SLJIT_FIRST_SAVED_FLOAT_REG are saved registers. */
-#define SLJIT_FIRST_SAVED_FLOAT_REG (SLJIT_FS0 - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS + 1)
-
-/* Return with floating point arg. */
-
-#define SLJIT_RETURN_FREG SLJIT_FR0
-
-/* --------------------------------------------------------------------- */
-/* Argument type definitions */
-/* --------------------------------------------------------------------- */
-
-/* The following argument type definitions are used by sljit_emit_enter,
- sljit_set_context, sljit_emit_call, and sljit_emit_icall functions.
-
- As for sljit_emit_call and sljit_emit_icall, the first integer argument
- must be placed into SLJIT_R0, the second one into SLJIT_R1, and so on.
- Similarly the first floating point argument must be placed into SLJIT_FR0,
- the second one into SLJIT_FR1, and so on.
-
- As for sljit_emit_enter, the integer arguments can be stored in scratch
- or saved registers. The first integer argument without _R postfix is
- stored in SLJIT_S0, the next one in SLJIT_S1, and so on. The integer
- arguments with _R postfix are placed into scratch registers. The index
- of the scratch register is the count of the previous integer arguments
- starting from SLJIT_R0. The floating point arguments are always placed
- into SLJIT_FR0, SLJIT_FR1, and so on.
-
- Note: if a function is called by sljit_emit_call/sljit_emit_icall and
- an argument is stored in a scratch register by sljit_emit_enter,
- that argument uses the same scratch register index for both
- integer and floating point arguments.
-
- Example function definition:
- sljit_f32 SLJIT_FUNC example_c_callback(void *arg_a,
- sljit_f64 arg_b, sljit_u32 arg_c, sljit_f32 arg_d);
-
- Argument type definition:
- SLJIT_ARG_RETURN(SLJIT_ARG_TYPE_F32)
- | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_P, 1) | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_F64, 2)
- | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_32, 3) | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_F32, 4)
-
- Short form of argument type definition:
- SLJIT_ARGS4(32, P, F64, 32, F32)
-
- Argument passing:
- arg_a must be placed in SLJIT_R0
- arg_c must be placed in SLJIT_R1
- arg_b must be placed in SLJIT_FR0
- arg_d must be placed in SLJIT_FR1
-
- Examples for argument processing by sljit_emit_enter:
- SLJIT_ARGS4(VOID, P, 32_R, F32, W)
- Arguments are placed into: SLJIT_S0, SLJIT_R1, SLJIT_FR0, SLJIT_S1
-
- SLJIT_ARGS4(VOID, W, W_R, W, W_R)
- Arguments are placed into: SLJIT_S0, SLJIT_R1, SLJIT_S1, SLJIT_R3
-
- SLJIT_ARGS4(VOID, F64, W, F32, W_R)
- Arguments are placed into: SLJIT_FR0, SLJIT_S0, SLJIT_FR1, SLJIT_R1
-
- Note: it is recommended to pass the scratch arguments first
- followed by the saved arguments:
-
- SLJIT_ARGS4(VOID, W_R, W_R, W, W)
- Arguments are placed into: SLJIT_R0, SLJIT_R1, SLJIT_S0, SLJIT_S1
-*/
-
-/* The following flag is only allowed for the integer arguments of
- sljit_emit_enter. When the flag is set, the integer argument is
- stored in a scratch register instead of a saved register. */
-#define SLJIT_ARG_TYPE_SCRATCH_REG 0x8
-
-/* Void result, can only be used by SLJIT_ARG_RETURN. */
-#define SLJIT_ARG_TYPE_VOID 0
-/* Machine word sized integer argument or result. */
-#define SLJIT_ARG_TYPE_W 1
-#define SLJIT_ARG_TYPE_W_R (SLJIT_ARG_TYPE_W | SLJIT_ARG_TYPE_SCRATCH_REG)
-/* 32 bit integer argument or result. */
-#define SLJIT_ARG_TYPE_32 2
-#define SLJIT_ARG_TYPE_32_R (SLJIT_ARG_TYPE_32 | SLJIT_ARG_TYPE_SCRATCH_REG)
-/* Pointer sized integer argument or result. */
-#define SLJIT_ARG_TYPE_P 3
-#define SLJIT_ARG_TYPE_P_R (SLJIT_ARG_TYPE_P | SLJIT_ARG_TYPE_SCRATCH_REG)
-/* 64 bit floating point argument or result. */
-#define SLJIT_ARG_TYPE_F64 4
-/* 32 bit floating point argument or result. */
-#define SLJIT_ARG_TYPE_F32 5
-
-#define SLJIT_ARG_SHIFT 4
-#define SLJIT_ARG_RETURN(type) (type)
-#define SLJIT_ARG_VALUE(type, idx) ((type) << ((idx) * SLJIT_ARG_SHIFT))
-
-/* Simplified argument list definitions.
-
- The following definition:
- SLJIT_ARG_RETURN(SLJIT_ARG_TYPE_W) | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_F32, 1)
-
- can be shortened to:
- SLJIT_ARGS1(W, F32)
-*/
-
-#define SLJIT_ARG_TO_TYPE(type) SLJIT_ARG_TYPE_ ## type
-
-#define SLJIT_ARGS0(ret) \
- SLJIT_ARG_RETURN(SLJIT_ARG_TO_TYPE(ret))
-
-#define SLJIT_ARGS1(ret, arg1) \
- (SLJIT_ARGS0(ret) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg1), 1))
-
-#define SLJIT_ARGS2(ret, arg1, arg2) \
- (SLJIT_ARGS1(ret, arg1) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg2), 2))
-
-#define SLJIT_ARGS3(ret, arg1, arg2, arg3) \
- (SLJIT_ARGS2(ret, arg1, arg2) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg3), 3))
-
-#define SLJIT_ARGS4(ret, arg1, arg2, arg3, arg4) \
- (SLJIT_ARGS3(ret, arg1, arg2, arg3) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg4), 4))
-
-/* --------------------------------------------------------------------- */
-/* Main structures and functions */
-/* --------------------------------------------------------------------- */
-
-/*
- The following structures are private, and can be changed in the
- future. Keeping them here allows code inlining.
-*/
-
-struct sljit_memory_fragment {
- struct sljit_memory_fragment *next;
- sljit_uw used_size;
- /* Must be aligned to sljit_sw. */
- sljit_u8 memory[1];
-};
-
-struct sljit_label {
- struct sljit_label *next;
- sljit_uw addr;
- /* The maximum size difference. */
- sljit_uw size;
-};
-
-struct sljit_jump {
- struct sljit_jump *next;
- sljit_uw addr;
- /* Architecture dependent flags. */
- sljit_uw flags;
- union {
- sljit_uw target;
- struct sljit_label *label;
- } u;
-};
-
-struct sljit_put_label {
- struct sljit_put_label *next;
- struct sljit_label *label;
- sljit_uw addr;
- sljit_uw flags;
-};
-
-struct sljit_const {
- struct sljit_const *next;
- sljit_uw addr;
-};
-
-struct sljit_compiler {
- sljit_s32 error;
- sljit_s32 options;
-
- struct sljit_label *labels;
- struct sljit_jump *jumps;
- struct sljit_put_label *put_labels;
- struct sljit_const *consts;
- struct sljit_label *last_label;
- struct sljit_jump *last_jump;
- struct sljit_const *last_const;
- struct sljit_put_label *last_put_label;
-
- void *allocator_data;
- void *exec_allocator_data;
- struct sljit_memory_fragment *buf;
- struct sljit_memory_fragment *abuf;
-
- /* Available scratch registers. */
- sljit_s32 scratches;
- /* Available saved registers. */
- sljit_s32 saveds;
- /* Available float scratch registers. */
- sljit_s32 fscratches;
- /* Available float saved registers. */
- sljit_s32 fsaveds;
- /* Local stack size. */
- sljit_s32 local_size;
- /* Maximum code size. */
- sljit_uw size;
- /* Relative offset of the executable mapping from the writable mapping. */
- sljit_sw executable_offset;
- /* Executable size for statistical purposes. */
- sljit_uw executable_size;
-
-#if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE)
- sljit_s32 status_flags_state;
-#endif
-
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- sljit_s32 args_size;
-#endif
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- sljit_s32 mode32;
-#endif
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- /* Constant pool handling. */
- sljit_uw *cpool;
- sljit_u8 *cpool_unique;
- sljit_uw cpool_diff;
- sljit_uw cpool_fill;
- /* Other members. */
- /* Contains pointer, "ldr pc, [...]" pairs. */
- sljit_uw patches;
-#endif
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
- /* Temporary fields. */
- sljit_uw shift_imm;
-#endif /* SLJIT_CONFIG_ARM_V5 || SLJIT_CONFIG_ARM_V7 */
-
-#if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && (defined __SOFTFP__)
- sljit_uw args_size;
-#endif
-
-#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
- sljit_u32 imm;
-#endif
-
-#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
- sljit_s32 delay_slot;
- sljit_s32 cache_arg;
- sljit_sw cache_argw;
-#endif
-
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- sljit_uw args_size;
-#endif
-
-#if (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
- sljit_s32 cache_arg;
- sljit_sw cache_argw;
-#endif
-
-#if (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
- /* Need to allocate register save area to make calls. */
- sljit_s32 mode;
-#endif
-
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- FILE* verbose;
-#endif
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
- || (defined SLJIT_DEBUG && SLJIT_DEBUG)
- /* Flags specified by the last arithmetic instruction.
- It contains the type of the variable flag. */
- sljit_s32 last_flags;
- /* Return value type set by entry functions. */
- sljit_s32 last_return;
- /* Local size passed to entry functions. */
- sljit_s32 logical_local_size;
-#endif
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
- || (defined SLJIT_DEBUG && SLJIT_DEBUG) \
- || (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- /* Trust arguments when an API function is called.
- Used internally for calling API functions. */
- sljit_s32 skip_checks;
-#endif
-};
-
-/* --------------------------------------------------------------------- */
-/* Main functions */
-/* --------------------------------------------------------------------- */
-
-/* Creates an SLJIT compiler. The allocator_data is required by some
- custom memory managers. This pointer is passed to SLJIT_MALLOC
- and SLJIT_FREE macros. Most allocators (including the default
- one) ignores this value, and it is recommended to pass NULL
- as a dummy value for allocator_data. The exec_allocator_data
- has the same purpose but this one is passed to SLJIT_MALLOC_EXEC /
- SLJIT_MALLOC_FREE functions.
-
- Returns NULL if failed. */
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data);
-
-/* Frees everything except the compiled machine code. */
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler);
-
-/* Returns the current error code. If an error occurres, future calls
- which uses the same compiler argument returns early with the same
- error code. Thus there is no need for checking the error after every
- call, it is enough to do it after the code is compiled. Removing
- these checks increases the performance of the compiling process. */
-static SLJIT_INLINE sljit_s32 sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; }
-
-/* Sets the compiler error code to SLJIT_ERR_ALLOC_FAILED except
- if an error was detected before. After the error code is set
- the compiler behaves as if the allocation failure happened
- during an SLJIT function call. This can greatly simplify error
- checking, since it is enough to check the compiler status
- after the code is compiled. */
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler);
-
-/*
- Allocate a small amount of memory. The size must be <= 64 bytes on 32 bit,
- and <= 128 bytes on 64 bit architectures. The memory area is owned by the
- compiler, and freed by sljit_free_compiler. The returned pointer is
- sizeof(sljit_sw) aligned. Excellent for allocating small blocks during
- compiling, and no need to worry about freeing them. The size is enough
- to contain at most 16 pointers. If the size is outside of the range,
- the function will return with NULL. However, this return value does not
- indicate that there is no more memory (does not set the current error code
- of the compiler to out-of-memory status).
-*/
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size);
-
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
-/* Passing NULL disables verbose. */
-SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose);
-#endif
-
-/*
- Create executable code from the instruction stream. This is the final step
- of the code generation so no more instructions can be emitted after this call.
-*/
-
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler);
-
-/* Free executable code. */
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data);
-
-/*
- When the protected executable allocator is used the JIT code is mapped
- twice. The first mapping has read/write and the second mapping has read/exec
- permissions. This function returns with the relative offset of the executable
- mapping using the writable mapping as the base after the machine code is
- successfully generated. The returned value is always 0 for the normal executable
- allocator, since it uses only one mapping with read/write/exec permissions.
- Dynamic code modifications requires this value.
-
- Before a successful code generation, this function returns with 0.
-*/
-static SLJIT_INLINE sljit_sw sljit_get_executable_offset(struct sljit_compiler *compiler) { return compiler->executable_offset; }
-
-/*
- The executable memory consumption of the generated code can be retrieved by
- this function. The returned value can be used for statistical purposes.
-
- Before a successful code generation, this function returns with 0.
-*/
-static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler *compiler) { return compiler->executable_size; }
-
-/* Returns with non-zero if the feature or limitation type passed as its
- argument is present on the current CPU. The return value is one, if a
- feature is fully supported, and it is two, if partially supported.
-
- Some features (e.g. floating point operations) require hardware (CPU)
- support while others (e.g. move with update) are emulated if not available.
- However, even when a feature is emulated, specialized code paths may be
- faster than the emulation. Some limitations are emulated as well so their
- general case is supported but it has extra performance costs. */
-
-/* [Not emulated] Floating-point support is available. */
-#define SLJIT_HAS_FPU 0
-/* [Limitation] Some registers are virtual registers. */
-#define SLJIT_HAS_VIRTUAL_REGISTERS 1
-/* [Emulated] Has zero register (setting a memory location to zero is efficient). */
-#define SLJIT_HAS_ZERO_REGISTER 2
-/* [Emulated] Count leading zero is supported. */
-#define SLJIT_HAS_CLZ 3
-/* [Emulated] Count trailing zero is supported. */
-#define SLJIT_HAS_CTZ 4
-/* [Emulated] Rotate left/right is supported. */
-#define SLJIT_HAS_ROT 5
-/* [Emulated] Conditional move is supported. */
-#define SLJIT_HAS_CMOV 6
-/* [Emulated] Prefetch instruction is available (emulated as a nop). */
-#define SLJIT_HAS_PREFETCH 7
-
-#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
-/* [Not emulated] SSE2 support is available on x86. */
-#define SLJIT_HAS_SSE2 100
-#endif
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type);
-
-/* If type is between SLJIT_ORDERED_EQUAL and SLJIT_ORDERED_LESS_EQUAL,
- sljit_cmp_info returns one, if the cpu supports the passed floating
- point comparison type.
-
- If type is SLJIT_UNORDERED or SLJIT_ORDERED, sljit_cmp_info returns
- one, if the cpu supports checking the unordered comparison result
- regardless of the comparison type passed to the comparison instruction.
- The returned value is always one, if there is at least one type between
- SLJIT_ORDERED_EQUAL and SLJIT_ORDERED_LESS_EQUAL where sljit_cmp_info
- returns with a zero value.
-
- Otherwise it returns zero. */
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type);
-
-/* The following functions generate machine code. If there is no
- error, they return with SLJIT_SUCCESS, otherwise they return
- with an error code. */
-
-/*
- The executable code is a function from the viewpoint of the C
- language. The function calls must obey to the ABI (Application
- Binary Interface) of the platform, which specify the purpose of
- machine registers and stack handling among other things. The
- sljit_emit_enter function emits the necessary instructions for
- setting up a new context for the executable code. This is often
- called as function prologue. Furthermore the options argument
- can be used to pass configuration options to the compiler. The
- available options are listed before sljit_emit_enter.
-
- The function argument list is specified by the SLJIT_ARGSx
- (SLJIT_ARGS0 .. SLJIT_ARGS4) macros. Currently maximum four
- arguments are supported. See the description of SLJIT_ARGSx
- macros about argument passing. Furthermore the register set
- used by the function must be declared as well. The number of
- scratch and saved registers available to the function must
- be passed to sljit_emit_enter. Only R registers between R0
- and "scratches" argument can be used later. E.g. if "scratches"
- is set to two, the scratch register set will be limited to
- SLJIT_R0 and SLJIT_R1. The S registers and the floating point
- registers ("fscratches" and "fsaveds") are specified in a
- similar manner. The sljit_emit_enter is also capable of
- allocating a stack space for local data. The "local_size"
- argument contains the size in bytes of this local area, and
- it can be accessed using SLJIT_MEM1(SLJIT_SP). The memory
- area between SLJIT_SP (inclusive) and SLJIT_SP + local_size
- (exclusive) can be modified freely until the function returns.
- The stack space is not initialized to zero.
-
- Note: the following conditions must met:
- 0 <= scratches <= SLJIT_NUMBER_OF_REGISTERS
- 0 <= saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS
- scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS
- 0 <= fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS
- 0 <= fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS
- fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS
-
- Note: the compiler can use saved registers as scratch registers,
- but the opposite is not supported
-
- Note: every call of sljit_emit_enter and sljit_set_context
- overwrites the previous context.
-*/
-
-/* Saved registers between SLJIT_S0 and SLJIT_S(n - 1) (inclusive)
- are not saved / restored on function enter / return. Instead,
- these registers can be used to pass / return data (such as
- global / local context pointers) across function calls. The
- value of n must be between 1 and 3. This option is only
- supported by SLJIT_ENTER_REG_ARG calling convention. */
-#define SLJIT_ENTER_KEEP(n) (n)
-
-/* The compiled function uses an SLJIT specific register argument
- calling convention. This is a lightweight function call type where
- both the caller and the called functions must be compiled by
- SLJIT. The type argument of the call must be SLJIT_CALL_REG_ARG
- and all arguments must be stored in scratch registers. */
-#define SLJIT_ENTER_REG_ARG 0x00000004
-
-/* The local_size must be >= 0 and <= SLJIT_MAX_LOCAL_SIZE. */
-#define SLJIT_MAX_LOCAL_SIZE 65536
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size);
-
-/* The SLJIT compiler has a current context (which contains the local
- stack space size, number of used registers, etc.) which is initialized
- by sljit_emit_enter. Several functions (such as sljit_emit_return)
- requires this context to be able to generate the appropriate code.
- However, some code fragments (compiled separately) may have no
- normal entry point so their context is unknown for the compiler.
-
- The sljit_set_context and sljit_emit_enter have the same arguments,
- but sljit_set_context does not generate any machine code.
-
- Note: every call of sljit_emit_enter and sljit_set_context overwrites
- the previous context. */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size);
-
-/* Return to the caller function. The sljit_emit_return_void function
- does not return with any value. The sljit_emit_return function returns
- with a single value loaded from its source operand. The load operation
- can be between SLJIT_MOV and SLJIT_MOV_P (see sljit_emit_op1) and
- SLJIT_MOV_F32/SLJIT_MOV_F64 (see sljit_emit_fop1) depending on the
- return value specified by sljit_emit_enter/sljit_set_context. */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler);
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src, sljit_sw srcw);
-
-/* Restores the saved registers and free the stack area, then the execution
- continues from the address specified by the source operand. This
- operation is similar to sljit_emit_return, but it ignores the return
- address. The code where the exection continues should use the same context
- as the caller function (see sljit_set_context). A word (pointer) value
- can be passed in the SLJIT_RETURN_REG register. This function can be used
- to jump to exception handlers. */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,
- sljit_s32 src, sljit_sw srcw);
-
-/* Generating entry and exit points for fast call functions (see SLJIT_FAST_CALL).
- Both sljit_emit_fast_enter and SLJIT_FAST_RETURN operations preserve the
- values of all registers and stack frame. The return address is stored in the
- dst argument of sljit_emit_fast_enter, and this return address can be passed
- to SLJIT_FAST_RETURN to continue the execution after the fast call.
-
- Fast calls are cheap operations (usually only a single call instruction is
- emitted) but they do not preserve any registers. However the callee function
- can freely use / update any registers and the local area which can be
- efficiently exploited by various optimizations. Registers can be saved
- and restored manually if needed.
-
- Although returning to different address by SLJIT_FAST_RETURN is possible,
- this address usually cannot be predicted by the return address predictor of
- modern CPUs which may reduce performance. Furthermore certain security
- enhancement technologies such as Intel Control-flow Enforcement Technology
- (CET) may disallow returning to a different address.
-
- Flags: - (does not modify flags). */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw);
-
-/*
- Source and destination operands for arithmetical instructions
- imm - a simple immediate value (cannot be used as a destination)
- reg - any of the available registers (immediate argument must be 0)
- [imm] - absolute memory address
- [reg+imm] - indirect memory address
- [reg+(reg<<imm)] - indirect indexed memory address (shift must be between 0 and 3)
- useful for accessing arrays (fully supported by both x86 and
- ARM architectures, and cheap operation on others)
-*/
-
-/*
- IMPORTANT NOTE: memory accesses MUST be naturally aligned unless
- SLJIT_UNALIGNED macro is defined and its value is 1.
-
- length | alignment
- ---------+-----------
- byte | 1 byte (any physical_address is accepted)
- half | 2 byte (physical_address & 0x1 == 0)
- int | 4 byte (physical_address & 0x3 == 0)
- word | 4 byte if SLJIT_32BIT_ARCHITECTURE is defined and its value is 1
- | 8 byte if SLJIT_64BIT_ARCHITECTURE is defined and its value is 1
- pointer | size of sljit_p type (4 byte on 32 bit machines, 4 or 8 byte
- | on 64 bit machines)
-
- Note: Different architectures have different addressing limitations.
- A single instruction is enough for the following addressing
- modes. Other adrressing modes are emulated by instruction
- sequences. This information could help to improve those code
- generators which focuses only a few architectures.
-
- x86: [reg+imm], -2^32+1 <= imm <= 2^32-1 (full address space on x86-32)
- [reg+(reg<<imm)] is supported
- [imm], -2^32+1 <= imm <= 2^32-1 is supported
- Write-back is not supported
- arm: [reg+imm], -4095 <= imm <= 4095 or -255 <= imm <= 255 for signed
- bytes, any halfs or floating point values)
- [reg+(reg<<imm)] is supported
- Write-back is supported
- arm-t2: [reg+imm], -255 <= imm <= 4095
- [reg+(reg<<imm)] is supported
- Write back is supported only for [reg+imm], where -255 <= imm <= 255
- arm64: [reg+imm], -256 <= imm <= 255, 0 <= aligned imm <= 4095 * alignment
- [reg+(reg<<imm)] is supported
- Write back is supported only for [reg+imm], where -256 <= imm <= 255
- ppc: [reg+imm], -65536 <= imm <= 65535. 64 bit loads/stores and 32 bit
- signed load on 64 bit requires immediates divisible by 4.
- [reg+imm] is not supported for signed 8 bit values.
- [reg+reg] is supported
- Write-back is supported except for one instruction: 32 bit signed
- load with [reg+imm] addressing mode on 64 bit.
- mips: [reg+imm], -65536 <= imm <= 65535
- Write-back is not supported
- riscv: [reg+imm], -2048 <= imm <= 2047
- Write-back is not supported
- s390x: [reg+imm], -2^19 <= imm < 2^19
- [reg+reg] is supported
- Write-back is not supported
-*/
-
-/* Macros for specifying operand types. */
-#define SLJIT_MEM 0x80
-#define SLJIT_MEM0() (SLJIT_MEM)
-#define SLJIT_MEM1(r1) (SLJIT_MEM | (r1))
-#define SLJIT_MEM2(r1, r2) (SLJIT_MEM | (r1) | ((r2) << 8))
-#define SLJIT_IMM 0x40
-#define SLJIT_REG_PAIR(r1, r2) ((r1) | ((r2) << 8))
-
-/* Sets 32 bit operation mode on 64 bit CPUs. This option is ignored on
- 32 bit CPUs. When this option is set for an arithmetic operation, only
- the lower 32 bits of the input registers are used, and the CPU status
- flags are set according to the 32 bit result. Although the higher 32 bit
- of the input and the result registers are not defined by SLJIT, it might
- be defined by the CPU architecture (e.g. MIPS). To satisfy these CPU
- requirements all source registers must be the result of those operations
- where this option was also set. Memory loads read 32 bit values rather
- than 64 bit ones. In other words 32 bit and 64 bit operations cannot be
- mixed. The only exception is SLJIT_MOV32 which source register can hold
- any 32 or 64 bit value, and it is converted to a 32 bit compatible format
- first. When the source and destination registers are the same, this
- conversion is free (no instructions are emitted) on most CPUs. A 32 bit
- value can also be converted to a 64 bit value by SLJIT_MOV_S32
- (sign extension) or SLJIT_MOV_U32 (zero extension).
-
- As for floating-point operations, this option sets 32 bit single
- precision mode. Similar to the integer operations, all register arguments
- must be the result of those operations where this option was also set.
-
- Note: memory addressing always uses 64 bit values on 64 bit systems so
- the result of a 32 bit operation must not be used with SLJIT_MEMx
- macros.
-
- This option is part of the instruction name, so there is no need to
- manually set it. E.g:
-
- SLJIT_ADD32 == (SLJIT_ADD | SLJIT_32) */
-#define SLJIT_32 0x100
-
-/* Many CPUs (x86, ARM, PPC) have status flag bits which can be set according
- to the result of an operation. Other CPUs (MIPS) do not have status
- flag bits, and results must be stored in registers. To cover both
- architecture types efficiently only two flags are defined by SLJIT:
-
- * Zero (equal) flag: it is set if the result is zero
- * Variable flag: its value is defined by the arithmetic operation
-
- SLJIT instructions can set any or both of these flags. The value of
- these flags is undefined if the instruction does not specify their
- value. The description of each instruction contains the list of
- allowed flag types.
-
- Note: the logical or operation can be used to set flags.
-
- Example: SLJIT_ADD can set the Z, OVERFLOW, CARRY flags hence
-
- sljit_op2(..., SLJIT_ADD, ...)
- Both the zero and variable flags are undefined so they can
- have any value after the operation is completed.
-
- sljit_op2(..., SLJIT_ADD | SLJIT_SET_Z, ...)
- Sets the zero flag if the result is zero, clears it otherwise.
- The variable flag is undefined.
-
- sljit_op2(..., SLJIT_ADD | SLJIT_SET_OVERFLOW, ...)
- Sets the variable flag if an integer overflow occurs, clears
- it otherwise. The zero flag is undefined.
-
- sljit_op2(..., SLJIT_ADD | SLJIT_SET_Z | SLJIT_SET_CARRY, ...)
- Sets the zero flag if the result is zero, clears it otherwise.
- Sets the variable flag if unsigned overflow (carry) occurs,
- clears it otherwise.
-
- Certain instructions (e.g. SLJIT_MOV) does not modify flags, so
- status flags are unchanged.
-
- Example:
-
- sljit_op2(..., SLJIT_ADD | SLJIT_SET_Z, ...)
- sljit_op1(..., SLJIT_MOV, ...)
- Zero flag is set according to the result of SLJIT_ADD.
-
- sljit_op2(..., SLJIT_ADD | SLJIT_SET_Z, ...)
- sljit_op2(..., SLJIT_ADD, ...)
- Zero flag has unknown value.
-
- These flags can be used for code optimization. E.g. a fast loop can be
- implemented by decreasing a counter register and set the zero flag
- using a single instruction. The zero register can be used by a
- conditional jump to restart the loop. A single comparison can set a
- zero and less flags to check if a value is less, equal, or greater
- than another value.
-
- Motivation: although some CPUs can set a large number of flag bits,
- usually their values are ignored or only a few of them are used. Emulating
- a large number of flags on systems without a flag register is complicated
- so SLJIT instructions must specify the flag they want to use and only
- that flag is computed. The last arithmetic instruction can be repeated if
- multiple flags need to be checked.
-*/
-
-/* Set Zero status flag. */
-#define SLJIT_SET_Z 0x0200
-/* Set the variable status flag if condition is true.
- See comparison types (e.g. SLJIT_SET_LESS, SLJIT_SET_F_EQUAL). */
-#define SLJIT_SET(condition) ((condition) << 10)
-
-/* Starting index of opcodes for sljit_emit_op0. */
-#define SLJIT_OP0_BASE 0
-
-/* Flags: - (does not modify flags)
- Note: breakpoint instruction is not supported by all architectures (e.g. ppc)
- It falls back to SLJIT_NOP in those cases. */
-#define SLJIT_BREAKPOINT (SLJIT_OP0_BASE + 0)
-/* Flags: - (does not modify flags)
- Note: may or may not cause an extra cycle wait
- it can even decrease the runtime in a few cases. */
-#define SLJIT_NOP (SLJIT_OP0_BASE + 1)
-/* Flags: - (may destroy flags)
- Unsigned multiplication of SLJIT_R0 and SLJIT_R1.
- Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */
-#define SLJIT_LMUL_UW (SLJIT_OP0_BASE + 2)
-/* Flags: - (may destroy flags)
- Signed multiplication of SLJIT_R0 and SLJIT_R1.
- Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */
-#define SLJIT_LMUL_SW (SLJIT_OP0_BASE + 3)
-/* Flags: - (may destroy flags)
- Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1.
- The result is placed into SLJIT_R0 and the remainder into SLJIT_R1.
- Note: if SLJIT_R1 is 0, the behaviour is undefined. */
-#define SLJIT_DIVMOD_UW (SLJIT_OP0_BASE + 4)
-#define SLJIT_DIVMOD_U32 (SLJIT_DIVMOD_UW | SLJIT_32)
-/* Flags: - (may destroy flags)
- Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1.
- The result is placed into SLJIT_R0 and the remainder into SLJIT_R1.
- Note: if SLJIT_R1 is 0, the behaviour is undefined.
- Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00),
- the behaviour is undefined. */
-#define SLJIT_DIVMOD_SW (SLJIT_OP0_BASE + 5)
-#define SLJIT_DIVMOD_S32 (SLJIT_DIVMOD_SW | SLJIT_32)
-/* Flags: - (may destroy flags)
- Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1.
- The result is placed into SLJIT_R0. SLJIT_R1 preserves its value.
- Note: if SLJIT_R1 is 0, the behaviour is undefined. */
-#define SLJIT_DIV_UW (SLJIT_OP0_BASE + 6)
-#define SLJIT_DIV_U32 (SLJIT_DIV_UW | SLJIT_32)
-/* Flags: - (may destroy flags)
- Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1.
- The result is placed into SLJIT_R0. SLJIT_R1 preserves its value.
- Note: if SLJIT_R1 is 0, the behaviour is undefined.
- Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00),
- the behaviour is undefined. */
-#define SLJIT_DIV_SW (SLJIT_OP0_BASE + 7)
-#define SLJIT_DIV_S32 (SLJIT_DIV_SW | SLJIT_32)
-/* Flags: - (does not modify flags)
- ENDBR32 instruction for x86-32 and ENDBR64 instruction for x86-64
- when Intel Control-flow Enforcement Technology (CET) is enabled.
- No instructions are emitted for other architectures. */
-#define SLJIT_ENDBR (SLJIT_OP0_BASE + 8)
-/* Flags: - (may destroy flags)
- Skip stack frames before return when Intel Control-flow
- Enforcement Technology (CET) is enabled. No instructions
- are emitted for other architectures. */
-#define SLJIT_SKIP_FRAMES_BEFORE_RETURN (SLJIT_OP0_BASE + 9)
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op);
-
-/* Starting index of opcodes for sljit_emit_op1. */
-#define SLJIT_OP1_BASE 32
-
-/* The MOV instruction transfers data from source to destination.
-
- MOV instruction suffixes:
-
- U8 - unsigned 8 bit data transfer
- S8 - signed 8 bit data transfer
- U16 - unsigned 16 bit data transfer
- S16 - signed 16 bit data transfer
- U32 - unsigned int (32 bit) data transfer
- S32 - signed int (32 bit) data transfer
- P - pointer (sljit_p) data transfer
-*/
-
-/* Flags: - (does not modify flags) */
-#define SLJIT_MOV (SLJIT_OP1_BASE + 0)
-/* Flags: - (does not modify flags) */
-#define SLJIT_MOV_U8 (SLJIT_OP1_BASE + 1)
-#define SLJIT_MOV32_U8 (SLJIT_MOV_U8 | SLJIT_32)
-/* Flags: - (does not modify flags) */
-#define SLJIT_MOV_S8 (SLJIT_OP1_BASE + 2)
-#define SLJIT_MOV32_S8 (SLJIT_MOV_S8 | SLJIT_32)
-/* Flags: - (does not modify flags) */
-#define SLJIT_MOV_U16 (SLJIT_OP1_BASE + 3)
-#define SLJIT_MOV32_U16 (SLJIT_MOV_U16 | SLJIT_32)
-/* Flags: - (does not modify flags) */
-#define SLJIT_MOV_S16 (SLJIT_OP1_BASE + 4)
-#define SLJIT_MOV32_S16 (SLJIT_MOV_S16 | SLJIT_32)
-/* Flags: - (does not modify flags)
- Note: no SLJIT_MOV32_U32 form, since it is the same as SLJIT_MOV32 */
-#define SLJIT_MOV_U32 (SLJIT_OP1_BASE + 5)
-/* Flags: - (does not modify flags)
- Note: no SLJIT_MOV32_S32 form, since it is the same as SLJIT_MOV32 */
-#define SLJIT_MOV_S32 (SLJIT_OP1_BASE + 6)
-/* Flags: - (does not modify flags) */
-#define SLJIT_MOV32 (SLJIT_OP1_BASE + 7)
-/* Flags: - (does not modify flags)
- Note: loads a pointer sized data, useful on x32 mode (a 64 bit mode
- on x86-64 which uses 32 bit pointers) or similar compiling modes */
-#define SLJIT_MOV_P (SLJIT_OP1_BASE + 8)
-/* Flags: Z
- Note: immediate source argument is not supported */
-#define SLJIT_NOT (SLJIT_OP1_BASE + 9)
-#define SLJIT_NOT32 (SLJIT_NOT | SLJIT_32)
-/* Count leading zeroes
- Flags: - (may destroy flags)
- Note: immediate source argument is not supported */
-#define SLJIT_CLZ (SLJIT_OP1_BASE + 10)
-#define SLJIT_CLZ32 (SLJIT_CLZ | SLJIT_32)
-/* Count trailing zeroes
- Flags: - (may destroy flags)
- Note: immediate source argument is not supported */
-#define SLJIT_CTZ (SLJIT_OP1_BASE + 11)
-#define SLJIT_CTZ32 (SLJIT_CTZ | SLJIT_32)
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw);
-
-/* Starting index of opcodes for sljit_emit_op2. */
-#define SLJIT_OP2_BASE 96
-
-/* Flags: Z | OVERFLOW | CARRY */
-#define SLJIT_ADD (SLJIT_OP2_BASE + 0)
-#define SLJIT_ADD32 (SLJIT_ADD | SLJIT_32)
-/* Flags: CARRY */
-#define SLJIT_ADDC (SLJIT_OP2_BASE + 1)
-#define SLJIT_ADDC32 (SLJIT_ADDC | SLJIT_32)
-/* Flags: Z | LESS | GREATER_EQUAL | GREATER | LESS_EQUAL
- SIG_LESS | SIG_GREATER_EQUAL | SIG_GREATER
- SIG_LESS_EQUAL | OVERFLOW | CARRY */
-#define SLJIT_SUB (SLJIT_OP2_BASE + 2)
-#define SLJIT_SUB32 (SLJIT_SUB | SLJIT_32)
-/* Flags: CARRY */
-#define SLJIT_SUBC (SLJIT_OP2_BASE + 3)
-#define SLJIT_SUBC32 (SLJIT_SUBC | SLJIT_32)
-/* Note: integer mul
- Flags: OVERFLOW */
-#define SLJIT_MUL (SLJIT_OP2_BASE + 4)
-#define SLJIT_MUL32 (SLJIT_MUL | SLJIT_32)
-/* Flags: Z */
-#define SLJIT_AND (SLJIT_OP2_BASE + 5)
-#define SLJIT_AND32 (SLJIT_AND | SLJIT_32)
-/* Flags: Z */
-#define SLJIT_OR (SLJIT_OP2_BASE + 6)
-#define SLJIT_OR32 (SLJIT_OR | SLJIT_32)
-/* Flags: Z */
-#define SLJIT_XOR (SLJIT_OP2_BASE + 7)
-#define SLJIT_XOR32 (SLJIT_XOR | SLJIT_32)
-/* Flags: Z
- Let bit_length be the length of the shift operation: 32 or 64.
- If src2 is immediate, src2w is masked by (bit_length - 1).
- Otherwise, if the content of src2 is outside the range from 0
- to bit_length - 1, the result is undefined. */
-#define SLJIT_SHL (SLJIT_OP2_BASE + 8)
-#define SLJIT_SHL32 (SLJIT_SHL | SLJIT_32)
-/* Flags: Z
- Same as SLJIT_SHL, except the the second operand is
- always masked by the length of the shift operation. */
-#define SLJIT_MSHL (SLJIT_OP2_BASE + 9)
-#define SLJIT_MSHL32 (SLJIT_MSHL | SLJIT_32)
-/* Flags: Z
- Let bit_length be the length of the shift operation: 32 or 64.
- If src2 is immediate, src2w is masked by (bit_length - 1).
- Otherwise, if the content of src2 is outside the range from 0
- to bit_length - 1, the result is undefined. */
-#define SLJIT_LSHR (SLJIT_OP2_BASE + 10)
-#define SLJIT_LSHR32 (SLJIT_LSHR | SLJIT_32)
-/* Flags: Z
- Same as SLJIT_LSHR, except the the second operand is
- always masked by the length of the shift operation. */
-#define SLJIT_MLSHR (SLJIT_OP2_BASE + 11)
-#define SLJIT_MLSHR32 (SLJIT_MLSHR | SLJIT_32)
-/* Flags: Z
- Let bit_length be the length of the shift operation: 32 or 64.
- If src2 is immediate, src2w is masked by (bit_length - 1).
- Otherwise, if the content of src2 is outside the range from 0
- to bit_length - 1, the result is undefined. */
-#define SLJIT_ASHR (SLJIT_OP2_BASE + 12)
-#define SLJIT_ASHR32 (SLJIT_ASHR | SLJIT_32)
-/* Flags: Z
- Same as SLJIT_ASHR, except the the second operand is
- always masked by the length of the shift operation. */
-#define SLJIT_MASHR (SLJIT_OP2_BASE + 13)
-#define SLJIT_MASHR32 (SLJIT_MASHR | SLJIT_32)
-/* Flags: - (may destroy flags)
- Let bit_length be the length of the rotate operation: 32 or 64.
- The second operand is always masked by (bit_length - 1). */
-#define SLJIT_ROTL (SLJIT_OP2_BASE + 14)
-#define SLJIT_ROTL32 (SLJIT_ROTL | SLJIT_32)
-/* Flags: - (may destroy flags)
- Let bit_length be the length of the rotate operation: 32 or 64.
- The second operand is always masked by (bit_length - 1). */
-#define SLJIT_ROTR (SLJIT_OP2_BASE + 15)
-#define SLJIT_ROTR32 (SLJIT_ROTR | SLJIT_32)
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w);
-
-/* The sljit_emit_op2u function is the same as sljit_emit_op2
- except the result is discarded. */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w);
-
-/* Emit a left or right shift operation, where the bits shifted
- in comes from a separate source operand. All operands are
- interpreted as unsigned integers.
-
- In the followings the value_mask variable is 31 for 32 bit
- operations and word_size - 1 otherwise.
-
- op must be one of the following operations:
- SLJIT_SHL or SLJIT_SHL32:
- src_dst <<= src2
- src_dst |= ((src1 >> 1) >> (src2 ^ value_mask))
- SLJIT_MSHL or SLJIT_MSHL32:
- src2 &= value_mask
- perform the SLJIT_SHL or SLJIT_SHL32 operation
- SLJIT_LSHR or SLJIT_LSHR32:
- src_dst >>= src2
- src_dst |= ((src1 << 1) << (src2 ^ value_mask))
- SLJIT_MLSHR or SLJIT_MLSHR32:
- src2 &= value_mask
- perform the SLJIT_LSHR or SLJIT_LSHR32 operation
-
- op can be combined (or'ed) with SLJIT_SHIFT_INTO_NON_ZERO
-
- src_dst must be a register which content is updated after
- the operation is completed
- src1 / src1w contains the bits which shifted into src_dst
- src2 / src2w contains the shift amount
-
- Note: a rotate operation can be performed if src_dst and
- src1 are set to the same register
-
- Flags: - (may destroy flags) */
-
-/* The src2 contains a non-zero value. Improves the generated
- code on certain architectures, which provides a small
- performance improvement. */
-#define SLJIT_SHIFT_INTO_NON_ZERO 0x200
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src_dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w);
-
-/* Starting index of opcodes for sljit_emit_op2. */
-#define SLJIT_OP_SRC_BASE 128
-
-/* Note: src cannot be an immedate value
- Flags: - (does not modify flags) */
-#define SLJIT_FAST_RETURN (SLJIT_OP_SRC_BASE + 0)
-/* Skip stack frames before fast return.
- Note: src cannot be an immedate value
- Flags: may destroy flags. */
-#define SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN (SLJIT_OP_SRC_BASE + 1)
-/* Prefetch value into the level 1 data cache
- Note: if the target CPU does not support data prefetch,
- no instructions are emitted.
- Note: this instruction never fails, even if the memory address is invalid.
- Flags: - (does not modify flags) */
-#define SLJIT_PREFETCH_L1 (SLJIT_OP_SRC_BASE + 2)
-/* Prefetch value into the level 2 data cache
- Note: same as SLJIT_PREFETCH_L1 if the target CPU
- does not support this instruction form.
- Note: this instruction never fails, even if the memory address is invalid.
- Flags: - (does not modify flags) */
-#define SLJIT_PREFETCH_L2 (SLJIT_OP_SRC_BASE + 3)
-/* Prefetch value into the level 3 data cache
- Note: same as SLJIT_PREFETCH_L2 if the target CPU
- does not support this instruction form.
- Note: this instruction never fails, even if the memory address is invalid.
- Flags: - (does not modify flags) */
-#define SLJIT_PREFETCH_L3 (SLJIT_OP_SRC_BASE + 4)
-/* Prefetch a value which is only used once (and can be discarded afterwards)
- Note: same as SLJIT_PREFETCH_L1 if the target CPU
- does not support this instruction form.
- Note: this instruction never fails, even if the memory address is invalid.
- Flags: - (does not modify flags) */
-#define SLJIT_PREFETCH_ONCE (SLJIT_OP_SRC_BASE + 5)
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src, sljit_sw srcw);
-
-/* Starting index of opcodes for sljit_emit_fop1. */
-#define SLJIT_FOP1_BASE 160
-
-/* Flags: - (does not modify flags) */
-#define SLJIT_MOV_F64 (SLJIT_FOP1_BASE + 0)
-#define SLJIT_MOV_F32 (SLJIT_MOV_F64 | SLJIT_32)
-/* Convert opcodes: CONV[DST_TYPE].FROM[SRC_TYPE]
- SRC/DST TYPE can be: F64, F32, S32, SW
- Rounding mode when the destination is SW or S32: round towards zero. */
-/* Flags: - (may destroy flags) */
-#define SLJIT_CONV_F64_FROM_F32 (SLJIT_FOP1_BASE + 1)
-#define SLJIT_CONV_F32_FROM_F64 (SLJIT_CONV_F64_FROM_F32 | SLJIT_32)
-/* Flags: - (may destroy flags) */
-#define SLJIT_CONV_SW_FROM_F64 (SLJIT_FOP1_BASE + 2)
-#define SLJIT_CONV_SW_FROM_F32 (SLJIT_CONV_SW_FROM_F64 | SLJIT_32)
-/* Flags: - (may destroy flags) */
-#define SLJIT_CONV_S32_FROM_F64 (SLJIT_FOP1_BASE + 3)
-#define SLJIT_CONV_S32_FROM_F32 (SLJIT_CONV_S32_FROM_F64 | SLJIT_32)
-/* Flags: - (may destroy flags) */
-#define SLJIT_CONV_F64_FROM_SW (SLJIT_FOP1_BASE + 4)
-#define SLJIT_CONV_F32_FROM_SW (SLJIT_CONV_F64_FROM_SW | SLJIT_32)
-/* Flags: - (may destroy flags) */
-#define SLJIT_CONV_F64_FROM_S32 (SLJIT_FOP1_BASE + 5)
-#define SLJIT_CONV_F32_FROM_S32 (SLJIT_CONV_F64_FROM_S32 | SLJIT_32)
-/* Note: dst is the left and src is the right operand for SLJIT_CMP_F32/64.
- Flags: EQUAL_F | LESS_F | GREATER_EQUAL_F | GREATER_F | LESS_EQUAL_F */
-#define SLJIT_CMP_F64 (SLJIT_FOP1_BASE + 6)
-#define SLJIT_CMP_F32 (SLJIT_CMP_F64 | SLJIT_32)
-/* Flags: - (may destroy flags) */
-#define SLJIT_NEG_F64 (SLJIT_FOP1_BASE + 7)
-#define SLJIT_NEG_F32 (SLJIT_NEG_F64 | SLJIT_32)
-/* Flags: - (may destroy flags) */
-#define SLJIT_ABS_F64 (SLJIT_FOP1_BASE + 8)
-#define SLJIT_ABS_F32 (SLJIT_ABS_F64 | SLJIT_32)
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw);
-
-/* Starting index of opcodes for sljit_emit_fop2. */
-#define SLJIT_FOP2_BASE 192
-
-/* Flags: - (may destroy flags) */
-#define SLJIT_ADD_F64 (SLJIT_FOP2_BASE + 0)
-#define SLJIT_ADD_F32 (SLJIT_ADD_F64 | SLJIT_32)
-/* Flags: - (may destroy flags) */
-#define SLJIT_SUB_F64 (SLJIT_FOP2_BASE + 1)
-#define SLJIT_SUB_F32 (SLJIT_SUB_F64 | SLJIT_32)
-/* Flags: - (may destroy flags) */
-#define SLJIT_MUL_F64 (SLJIT_FOP2_BASE + 2)
-#define SLJIT_MUL_F32 (SLJIT_MUL_F64 | SLJIT_32)
-/* Flags: - (may destroy flags) */
-#define SLJIT_DIV_F64 (SLJIT_FOP2_BASE + 3)
-#define SLJIT_DIV_F32 (SLJIT_DIV_F64 | SLJIT_32)
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w);
-
-/* Label and jump instructions. */
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler);
-
-/* Invert (negate) conditional type: xor (^) with 0x1 */
-
-/* Integer comparison types. */
-#define SLJIT_EQUAL 0
-#define SLJIT_ZERO SLJIT_EQUAL
-#define SLJIT_NOT_EQUAL 1
-#define SLJIT_NOT_ZERO SLJIT_NOT_EQUAL
-
-#define SLJIT_LESS 2
-#define SLJIT_SET_LESS SLJIT_SET(SLJIT_LESS)
-#define SLJIT_GREATER_EQUAL 3
-#define SLJIT_SET_GREATER_EQUAL SLJIT_SET(SLJIT_GREATER_EQUAL)
-#define SLJIT_GREATER 4
-#define SLJIT_SET_GREATER SLJIT_SET(SLJIT_GREATER)
-#define SLJIT_LESS_EQUAL 5
-#define SLJIT_SET_LESS_EQUAL SLJIT_SET(SLJIT_LESS_EQUAL)
-#define SLJIT_SIG_LESS 6
-#define SLJIT_SET_SIG_LESS SLJIT_SET(SLJIT_SIG_LESS)
-#define SLJIT_SIG_GREATER_EQUAL 7
-#define SLJIT_SET_SIG_GREATER_EQUAL SLJIT_SET(SLJIT_SIG_GREATER_EQUAL)
-#define SLJIT_SIG_GREATER 8
-#define SLJIT_SET_SIG_GREATER SLJIT_SET(SLJIT_SIG_GREATER)
-#define SLJIT_SIG_LESS_EQUAL 9
-#define SLJIT_SET_SIG_LESS_EQUAL SLJIT_SET(SLJIT_SIG_LESS_EQUAL)
-
-#define SLJIT_OVERFLOW 10
-#define SLJIT_SET_OVERFLOW SLJIT_SET(SLJIT_OVERFLOW)
-#define SLJIT_NOT_OVERFLOW 11
-
-/* Unlike other flags, sljit_emit_jump may destroy the carry flag. */
-#define SLJIT_CARRY 12
-#define SLJIT_SET_CARRY SLJIT_SET(SLJIT_CARRY)
-#define SLJIT_NOT_CARRY 13
-
-/* Basic floating point comparison types.
-
- Note: when the comparison result is unordered, their behaviour is unspecified. */
-
-#define SLJIT_F_EQUAL 14
-#define SLJIT_SET_F_EQUAL SLJIT_SET(SLJIT_F_EQUAL)
-#define SLJIT_F_NOT_EQUAL 15
-#define SLJIT_SET_F_NOT_EQUAL SLJIT_SET(SLJIT_F_NOT_EQUAL)
-#define SLJIT_F_LESS 16
-#define SLJIT_SET_F_LESS SLJIT_SET(SLJIT_F_LESS)
-#define SLJIT_F_GREATER_EQUAL 17
-#define SLJIT_SET_F_GREATER_EQUAL SLJIT_SET(SLJIT_F_GREATER_EQUAL)
-#define SLJIT_F_GREATER 18
-#define SLJIT_SET_F_GREATER SLJIT_SET(SLJIT_F_GREATER)
-#define SLJIT_F_LESS_EQUAL 19
-#define SLJIT_SET_F_LESS_EQUAL SLJIT_SET(SLJIT_F_LESS_EQUAL)
-
-/* Jumps when either argument contains a NaN value. */
-#define SLJIT_UNORDERED 20
-#define SLJIT_SET_UNORDERED SLJIT_SET(SLJIT_UNORDERED)
-/* Jumps when neither argument contains a NaN value. */
-#define SLJIT_ORDERED 21
-#define SLJIT_SET_ORDERED SLJIT_SET(SLJIT_ORDERED)
-
-/* Ordered / unordered floating point comparison types.
-
- Note: each comparison type has an ordered and unordered form. Some
- architectures supports only either of them (see: sljit_cmp_info). */
-
-#define SLJIT_ORDERED_EQUAL 22
-#define SLJIT_SET_ORDERED_EQUAL SLJIT_SET(SLJIT_ORDERED_EQUAL)
-#define SLJIT_UNORDERED_OR_NOT_EQUAL 23
-#define SLJIT_SET_UNORDERED_OR_NOT_EQUAL SLJIT_SET(SLJIT_UNORDERED_OR_NOT_EQUAL)
-#define SLJIT_ORDERED_LESS 24
-#define SLJIT_SET_ORDERED_LESS SLJIT_SET(SLJIT_ORDERED_LESS)
-#define SLJIT_UNORDERED_OR_GREATER_EQUAL 25
-#define SLJIT_SET_UNORDERED_OR_GREATER_EQUAL SLJIT_SET(SLJIT_UNORDERED_OR_GREATER_EQUAL)
-#define SLJIT_ORDERED_GREATER 26
-#define SLJIT_SET_ORDERED_GREATER SLJIT_SET(SLJIT_ORDERED_GREATER)
-#define SLJIT_UNORDERED_OR_LESS_EQUAL 27
-#define SLJIT_SET_UNORDERED_OR_LESS_EQUAL SLJIT_SET(SLJIT_UNORDERED_OR_LESS_EQUAL)
-
-#define SLJIT_UNORDERED_OR_EQUAL 28
-#define SLJIT_SET_UNORDERED_OR_EQUAL SLJIT_SET(SLJIT_UNORDERED_OR_EQUAL)
-#define SLJIT_ORDERED_NOT_EQUAL 29
-#define SLJIT_SET_ORDERED_NOT_EQUAL SLJIT_SET(SLJIT_ORDERED_NOT_EQUAL)
-#define SLJIT_UNORDERED_OR_LESS 30
-#define SLJIT_SET_UNORDERED_OR_LESS SLJIT_SET(SLJIT_UNORDERED_OR_LESS)
-#define SLJIT_ORDERED_GREATER_EQUAL 31
-#define SLJIT_SET_ORDERED_GREATER_EQUAL SLJIT_SET(SLJIT_ORDERED_GREATER_EQUAL)
-#define SLJIT_UNORDERED_OR_GREATER 32
-#define SLJIT_SET_UNORDERED_OR_GREATER SLJIT_SET(SLJIT_UNORDERED_OR_GREATER)
-#define SLJIT_ORDERED_LESS_EQUAL 33
-#define SLJIT_SET_ORDERED_LESS_EQUAL SLJIT_SET(SLJIT_ORDERED_LESS_EQUAL)
-
-/* Unconditional jump types. */
-#define SLJIT_JUMP 34
-/* Fast calling method. See sljit_emit_fast_enter / SLJIT_FAST_RETURN. */
-#define SLJIT_FAST_CALL 35
-/* Default C calling convention. */
-#define SLJIT_CALL 36
-/* Called function must be compiled by SLJIT.
- See SLJIT_ENTER_REG_ARG option. */
-#define SLJIT_CALL_REG_ARG 37
-
-/* The target can be changed during runtime (see: sljit_set_jump_addr). */
-#define SLJIT_REWRITABLE_JUMP 0x1000
-/* When this flag is passed, the execution of the current function ends and
- the called function returns to the caller of the current function. The
- stack usage is reduced before the call, but it is not necessarily reduced
- to zero. In the latter case the compiler needs to allocate space for some
- arguments and the return address must be stored on the stack as well. */
-#define SLJIT_CALL_RETURN 0x2000
-
-/* Emit a jump instruction. The destination is not set, only the type of the jump.
- type must be between SLJIT_EQUAL and SLJIT_FAST_CALL
- type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
-
- Flags: does not modify flags. */
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type);
-
-/* Emit a C compiler (ABI) compatible function call.
- type must be SLJIT_CALL or SLJIT_CALL_REG_ARG
- type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP and/or SLJIT_CALL_RETURN
- arg_types can be specified by SLJIT_ARGSx (SLJIT_ARG_RETURN / SLJIT_ARG_VALUE) macros
-
- Flags: destroy all flags. */
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 arg_types);
-
-/* Basic arithmetic comparison. In most architectures it is implemented as
- a compare operation followed by a sljit_emit_jump. However some
- architectures (i.e: ARM64 or MIPS) may employ special optimizations
- here. It is suggested to use this comparison form when appropriate.
- type must be between SLJIT_EQUAL and SLJIT_SIG_LESS_EQUAL
- type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
-
- Flags: may destroy flags. */
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w);
-
-/* Basic floating point comparison. In most architectures it is implemented as
- a SLJIT_CMP_F32/64 operation (setting appropriate flags) followed by a
- sljit_emit_jump. However some architectures (i.e: MIPS) may employ
- special optimizations here. It is suggested to use this comparison form
- when appropriate.
- type must be between SLJIT_F_EQUAL and SLJIT_ORDERED_LESS_EQUAL
- type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
- Flags: destroy flags.
- Note: when an operand is NaN the behaviour depends on the comparison type. */
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w);
-
-/* Set the destination of the jump to this label. */
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label);
-/* Set the destination address of the jump to this label. */
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target);
-
-/* Emit an indirect jump or fast call.
- Direct form: set src to SLJIT_IMM() and srcw to the address
- Indirect form: any other valid addressing mode
- type must be between SLJIT_JUMP and SLJIT_FAST_CALL
-
- Flags: does not modify flags. */
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw);
-
-/* Emit a C compiler (ABI) compatible function call.
- Direct form: set src to SLJIT_IMM() and srcw to the address
- Indirect form: any other valid addressing mode
- type must be SLJIT_CALL or SLJIT_CALL_REG_ARG
- type can be combined (or'ed) with SLJIT_CALL_RETURN
- arg_types can be specified by SLJIT_ARGSx (SLJIT_ARG_RETURN / SLJIT_ARG_VALUE) macros
-
- Flags: destroy all flags. */
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 arg_types, sljit_s32 src, sljit_sw srcw);
-
-/* Perform an operation using the conditional flags as the second argument.
- Type must always be between SLJIT_EQUAL and SLJIT_ORDERED_LESS_EQUAL.
- The value represented by the type is 1, if the condition represented
- by the type is fulfilled, and 0 otherwise.
-
- When op is SLJIT_MOV or SLJIT_MOV32:
- Set dst to the value represented by the type (0 or 1).
- Flags: - (does not modify flags)
- When op is SLJIT_AND, SLJIT_AND32, SLJIT_OR, SLJIT_OR32, SLJIT_XOR, or SLJIT_XOR32
- Performs the binary operation using dst as the first, and the value
- represented by type as the second argument. Result is written into dst.
- Flags: Z (may destroy flags) */
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 type);
-
-/* Emit a conditional mov instruction which moves source to destination,
- if the condition is satisfied. Unlike other arithmetic operations this
- instruction does not support memory access.
-
- type must be between SLJIT_EQUAL and SLJIT_ORDERED_LESS_EQUAL
- type can be combined (or'ed) with SLJIT_32
- dst_reg must be a valid register
- src must be a valid register or immediate (SLJIT_IMM)
-
- Flags: - (does not modify flags) */
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 dst_reg,
- sljit_s32 src, sljit_sw srcw);
-
-/* The following flags are used by sljit_emit_mem(), sljit_emit_mem_update(),
- sljit_emit_fmem(), and sljit_emit_fmem_update(). */
-
-/* Memory load operation. This is the default. */
-#define SLJIT_MEM_LOAD 0x000000
-/* Memory store operation. */
-#define SLJIT_MEM_STORE 0x000200
-
-/* The following flags are used by sljit_emit_mem() and sljit_emit_fmem(). */
-
-/* Load or stora data from an unaligned (byte aligned) address. */
-#define SLJIT_MEM_UNALIGNED 0x000400
-/* Load or stora data from a 16 bit aligned address. */
-#define SLJIT_MEM_UNALIGNED_16 0x000800
-/* Load or stora data from a 32 bit aligned address. */
-#define SLJIT_MEM_UNALIGNED_32 0x001000
-
-/* The following flags are used by sljit_emit_mem_update(),
- and sljit_emit_fmem_update(). */
-
-/* Base register is updated before the memory access (default). */
-#define SLJIT_MEM_PRE 0x000000
-/* Base register is updated after the memory access. */
-#define SLJIT_MEM_POST 0x000400
-
-/* When SLJIT_MEM_SUPP is passed, no instructions are emitted.
- Instead the function returns with SLJIT_SUCCESS if the instruction
- form is supported and SLJIT_ERR_UNSUPPORTED otherwise. This flag
- allows runtime checking of available instruction forms. */
-#define SLJIT_MEM_SUPP 0x000800
-
-/* The sljit_emit_mem emits instructions for various memory operations:
-
- When SLJIT_MEM_UNALIGNED / SLJIT_MEM_UNALIGNED_16 /
- SLJIT_MEM_UNALIGNED_32 is set in type argument:
- Emit instructions for unaligned memory loads or stores. When
- SLJIT_UNALIGNED is not defined, the only way to access unaligned
- memory data is using sljit_emit_mem. Otherwise all operations (e.g.
- sljit_emit_op1/2, or sljit_emit_fop1/2) supports unaligned access.
- In general, the performance of unaligned memory accesses are often
- lower than aligned and should be avoided.
-
- When a pair of registers is passed in reg argument:
- Emit instructions for moving data between a register pair and
- memory. The register pair can be specified by the SLJIT_REG_PAIR
- macro. The first register is loaded from or stored into the
- location specified by the mem/memw arguments, and the end address
- of this operation is the starting address of the data transfer
- between the second register and memory. The type argument must
- be SLJIT_MOV. The SLJIT_MEM_UNALIGNED* options are allowed for
- this operation.
-
- type must be between SLJIT_MOV and SLJIT_MOV_P and can be
- combined (or'ed) with SLJIT_MEM_* flags
- reg is a register or register pair, which is the source or
- destination of the operation
- mem must be a memory operand
-
- Flags: - (does not modify flags) */
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 reg,
- sljit_s32 mem, sljit_sw memw);
-
-/* Emit a single memory load or store with update instruction.
- When the requested instruction form is not supported by the CPU,
- it returns with SLJIT_ERR_UNSUPPORTED instead of emulating the
- instruction. This allows specializing tight loops based on
- the supported instruction forms (see SLJIT_MEM_SUPP flag).
- Absolute address (SLJIT_MEM0) forms are never supported
- and the base (first) register specified by the mem argument
- must not be SLJIT_SP and must also be different from the
- register specified by the reg argument.
-
- type must be between SLJIT_MOV and SLJIT_MOV_P and can be
- combined (or'ed) with SLJIT_MEM_* flags
- reg is the source or destination register of the operation
- mem must be a memory operand
-
- Flags: - (does not modify flags) */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 reg,
- sljit_s32 mem, sljit_sw memw);
-
-/* Same as sljit_emit_mem except the followings:
-
- Loading or storing a pair of registers is not supported.
-
- type must be SLJIT_MOV_F64 or SLJIT_MOV_F32 and can be
- combined (or'ed) with SLJIT_MEM_* flags.
- freg is the source or destination floating point register
- of the operation
- mem must be a memory operand
-
- Flags: - (does not modify flags) */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 freg,
- sljit_s32 mem, sljit_sw memw);
-
-/* Same as sljit_emit_mem_update except the followings:
-
- type must be SLJIT_MOV_F64 or SLJIT_MOV_F32 and can be
- combined (or'ed) with SLJIT_MEM_* flags
- freg is the source or destination floating point register
- of the operation
- mem must be a memory operand
-
- Flags: - (does not modify flags) */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 freg,
- sljit_s32 mem, sljit_sw memw);
-
-/* Copies the base address of SLJIT_SP + offset to dst. The offset can
- represent the starting address of a value in the local data (stack).
- The offset is not limited by the local data limits, it can be any value.
- For example if an array of bytes are stored on the stack from
- offset 0x40, and R0 contains the offset of an array item plus 0x120,
- this item can be changed by two SLJIT instructions:
-
- sljit_get_local_base(compiler, SLJIT_R1, 0, 0x40 - 0x120);
- sljit_emit_op1(compiler, SLJIT_MOV_U8, SLJIT_MEM2(SLJIT_R1, SLJIT_R0), 0, SLJIT_IMM, 0x5);
-
- Flags: - (may destroy flags) */
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset);
-
-/* Store a value that can be changed runtime (see: sljit_get_const_addr / sljit_set_const)
- Flags: - (does not modify flags) */
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value);
-
-/* Store the value of a label (see: sljit_set_put_label)
- Flags: - (does not modify flags) */
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw);
-
-/* Set the value stored by put_label to this label. */
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label);
-
-/* After the code generation the address for label, jump and const instructions
- are computed. Since these structures are freed by sljit_free_compiler, the
- addresses must be preserved by the user program elsewere. */
-static SLJIT_INLINE sljit_uw sljit_get_label_addr(struct sljit_label *label) { return label->addr; }
-static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; }
-static SLJIT_INLINE sljit_uw sljit_get_const_addr(struct sljit_const *const_) { return const_->addr; }
-
-/* Only the address and executable offset are required to perform dynamic
- code modifications. See sljit_get_executable_offset function. */
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset);
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset);
-
-/* --------------------------------------------------------------------- */
-/* CPU specific functions */
-/* --------------------------------------------------------------------- */
-
-/* The following function is a helper function for sljit_emit_op_custom.
- It returns with the real machine register index ( >=0 ) of any SLJIT_R,
- SLJIT_S and SLJIT_SP registers.
-
- Note: it returns with -1 for virtual registers (only on x86-32). */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg);
-
-/* The following function is a helper function for sljit_emit_op_custom.
- It returns with the real machine register ( >= 0 ) index of any SLJIT_FR,
- and SLJIT_FS register.
-
- Note: the index is always an even number on ARM-32, MIPS. */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg);
-
-/* Any instruction can be inserted into the instruction stream by
- sljit_emit_op_custom. It has a similar purpose as inline assembly.
- The size parameter must match to the instruction size of the target
- architecture:
-
- x86: 0 < size <= 15. The instruction argument can be byte aligned.
- Thumb2: if size == 2, the instruction argument must be 2 byte aligned.
- if size == 4, the instruction argument must be 4 byte aligned.
- Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
- void *instruction, sljit_u32 size);
-
-/* Flags were set by a 32 bit operation. */
-#define SLJIT_CURRENT_FLAGS_32 SLJIT_32
-
-/* Flags were set by an ADD or ADDC operations. */
-#define SLJIT_CURRENT_FLAGS_ADD 0x01
-/* Flags were set by a SUB, SUBC, or NEG operation. */
-#define SLJIT_CURRENT_FLAGS_SUB 0x02
-
-/* Flags were set by sljit_emit_op2u with SLJIT_SUB opcode.
- Must be combined with SLJIT_CURRENT_FLAGS_SUB. */
-#define SLJIT_CURRENT_FLAGS_COMPARE 0x04
-
-/* Define the currently available CPU status flags. It is usually used after
- an sljit_emit_label or sljit_emit_op_custom operations to define which CPU
- status flags are available.
-
- The current_flags must be a valid combination of SLJIT_SET_* and
- SLJIT_CURRENT_FLAGS_* constants. */
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler,
- sljit_s32 current_flags);
-
-/* --------------------------------------------------------------------- */
-/* Miscellaneous utility functions */
-/* --------------------------------------------------------------------- */
-
-/* Get the human readable name of the platform. Can be useful on platforms
- like ARM, where ARM and Thumb2 functions can be mixed, and it is useful
- to know the type of the code generator. */
-SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void);
-
-/* Portable helper function to get an offset of a member. */
-#define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((base*)0x10)->member) - 0x10)
-
-#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
-
-/* The sljit_stack structure and its manipulation functions provides
- an implementation for a top-down stack. The stack top is stored
- in the end field of the sljit_stack structure and the stack goes
- down to the min_start field, so the memory region reserved for
- this stack is between min_start (inclusive) and end (exclusive)
- fields. However the application can only use the region between
- start (inclusive) and end (exclusive) fields. The sljit_stack_resize
- function can be used to extend this region up to min_start.
-
- This feature uses the "address space reserve" feature of modern
- operating systems. Instead of allocating a large memory block
- applications can allocate a small memory region and extend it
- later without moving the content of the memory area. Therefore
- after a successful resize by sljit_stack_resize all pointers into
- this region are still valid.
-
- Note:
- this structure may not be supported by all operating systems.
- end and max_limit fields are aligned to PAGE_SIZE bytes (usually
- 4 Kbyte or more).
- stack should grow in larger steps, e.g. 4Kbyte, 16Kbyte or more. */
-
-struct sljit_stack {
- /* User data, anything can be stored here.
- Initialized to the same value as the end field. */
- sljit_u8 *top;
-/* These members are read only. */
- /* End address of the stack */
- sljit_u8 *end;
- /* Current start address of the stack. */
- sljit_u8 *start;
- /* Lowest start address of the stack. */
- sljit_u8 *min_start;
-};
-
-/* Allocates a new stack. Returns NULL if unsuccessful.
- Note: see sljit_create_compiler for the explanation of allocator_data. */
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data);
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data);
-
-/* Can be used to increase (extend) or decrease (shrink) the stack
- memory area. Returns with new_start if successful and NULL otherwise.
- It always fails if new_start is less than min_start or greater or equal
- than end fields. The fields of the stack are not changed if the returned
- value is NULL (the current memory content is never lost). */
-SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start);
-
-#endif /* (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) */
-
-#if !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
-
-/* Get the entry address of a given function (signed, unsigned result). */
-#define SLJIT_FUNC_ADDR(func_name) ((sljit_sw)func_name)
-#define SLJIT_FUNC_UADDR(func_name) ((sljit_uw)func_name)
-
-#else /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */
-
-/* All JIT related code should be placed in the same context (library, binary, etc.). */
-
-/* Get the entry address of a given function (signed, unsigned result). */
-#define SLJIT_FUNC_ADDR(func_name) (*(sljit_sw*)(void*)func_name)
-#define SLJIT_FUNC_UADDR(func_name) (*(sljit_uw*)(void*)func_name)
-
-/* For powerpc64, the function pointers point to a context descriptor. */
-struct sljit_function_context {
- sljit_uw addr;
- sljit_uw r2;
- sljit_uw r11;
-};
-
-/* Fill the context arguments using the addr and the function.
- If func_ptr is NULL, it will not be set to the address of context
- If addr is NULL, the function address also comes from the func pointer. */
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_uw addr, void* func);
-
-#endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */
-
-#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
-/* Free unused executable memory. The allocator keeps some free memory
- around to reduce the number of OS executable memory allocations.
- This improves performance since these calls are costly. However
- it is sometimes desired to free all unused memory regions, e.g.
- before the application terminates. */
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void);
-#endif
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* SLJIT_LIR_H_ */
diff --git a/contrib/libs/pcre2/src/sljit/sljitNativeARM_32.c b/contrib/libs/pcre2/src/sljit/sljitNativeARM_32.c
deleted file mode 100644
index 54b8ade063..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitNativeARM_32.c
+++ /dev/null
@@ -1,3700 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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.
- */
-
-#ifdef __SOFTFP__
-#define ARM_ABI_INFO " ABI:softfp"
-#else
-#define ARM_ABI_INFO " ABI:hardfp"
-#endif
-
-SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
-{
-#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
- return "ARMv7" SLJIT_CPUINFO ARM_ABI_INFO;
-#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- return "ARMv5" SLJIT_CPUINFO ARM_ABI_INFO;
-#else
-#error "Internal error: Unknown ARM architecture"
-#endif
-}
-
-/* Last register + 1. */
-#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
-#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
-#define TMP_PC (SLJIT_NUMBER_OF_REGISTERS + 4)
-
-#define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
-#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
-
-/* In ARM instruction words.
- Cache lines are usually 32 byte aligned. */
-#define CONST_POOL_ALIGNMENT 8
-#define CONST_POOL_EMPTY 0xffffffff
-
-#define ALIGN_INSTRUCTION(ptr) \
- (sljit_uw*)(((sljit_uw)(ptr) + (CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1) & ~((CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1))
-#define MAX_DIFFERENCE(max_diff) \
- (((max_diff) / (sljit_s32)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1))
-
-/* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */
-static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
- 0, 0, 1, 2, 3, 11, 10, 9, 8, 7, 6, 5, 4, 13, 12, 14, 15
-};
-
-static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
- 0, 0, 1, 2, 3, 4, 5, 15, 14, 13, 12, 11, 10, 9, 8, 6, 7
-};
-
-#define RM(rm) ((sljit_uw)reg_map[rm])
-#define RM8(rm) ((sljit_uw)reg_map[rm] << 8)
-#define RD(rd) ((sljit_uw)reg_map[rd] << 12)
-#define RN(rn) ((sljit_uw)reg_map[rn] << 16)
-
-#define VM(rm) ((sljit_uw)freg_map[rm])
-#define VD(rd) ((sljit_uw)freg_map[rd] << 12)
-#define VN(rn) ((sljit_uw)freg_map[rn] << 16)
-
-/* --------------------------------------------------------------------- */
-/* Instrucion forms */
-/* --------------------------------------------------------------------- */
-
-/* The instruction includes the AL condition.
- INST_NAME - CONDITIONAL remove this flag. */
-#define COND_MASK 0xf0000000
-#define CONDITIONAL 0xe0000000
-#define PUSH_POOL 0xff000000
-
-#define ADC 0xe0a00000
-#define ADD 0xe0800000
-#define AND 0xe0000000
-#define B 0xea000000
-#define BIC 0xe1c00000
-#define BL 0xeb000000
-#define BLX 0xe12fff30
-#define BX 0xe12fff10
-#define CLZ 0xe16f0f10
-#define CMN 0xe1600000
-#define CMP 0xe1400000
-#define BKPT 0xe1200070
-#define EOR 0xe0200000
-#define LDR 0xe5100000
-#define LDR_POST 0xe4100000
-#define MOV 0xe1a00000
-#define MUL 0xe0000090
-#define MVN 0xe1e00000
-#define NOP 0xe1a00000
-#define ORR 0xe1800000
-#define PUSH 0xe92d0000
-#define POP 0xe8bd0000
-#define RBIT 0xe6ff0f30
-#define RSB 0xe0600000
-#define RSC 0xe0e00000
-#define SBC 0xe0c00000
-#define SMULL 0xe0c00090
-#define STR 0xe5000000
-#define SUB 0xe0400000
-#define TST 0xe1000000
-#define UMULL 0xe0800090
-#define VABS_F32 0xeeb00ac0
-#define VADD_F32 0xee300a00
-#define VCMP_F32 0xeeb40a40
-#define VCVT_F32_S32 0xeeb80ac0
-#define VCVT_F64_F32 0xeeb70ac0
-#define VCVT_S32_F32 0xeebd0ac0
-#define VDIV_F32 0xee800a00
-#define VLDR_F32 0xed100a00
-#define VMOV_F32 0xeeb00a40
-#define VMOV 0xee000a10
-#define VMOV2 0xec400a10
-#define VMRS 0xeef1fa10
-#define VMUL_F32 0xee200a00
-#define VNEG_F32 0xeeb10a40
-#define VPOP 0xecbd0b00
-#define VPUSH 0xed2d0b00
-#define VSTR_F32 0xed000a00
-#define VSUB_F32 0xee300a40
-
-#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
-/* Arm v7 specific instructions. */
-#define MOVW 0xe3000000
-#define MOVT 0xe3400000
-#define SXTB 0xe6af0070
-#define SXTH 0xe6bf0070
-#define UXTB 0xe6ef0070
-#define UXTH 0xe6ff0070
-#endif
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
-
-static sljit_s32 push_cpool(struct sljit_compiler *compiler)
-{
- /* Pushing the constant pool into the instruction stream. */
- sljit_uw* inst;
- sljit_uw* cpool_ptr;
- sljit_uw* cpool_end;
- sljit_s32 i;
-
- /* The label could point the address after the constant pool. */
- if (compiler->last_label && compiler->last_label->size == compiler->size)
- compiler->last_label->size += compiler->cpool_fill + (CONST_POOL_ALIGNMENT - 1) + 1;
-
- SLJIT_ASSERT(compiler->cpool_fill > 0 && compiler->cpool_fill <= CPOOL_SIZE);
- inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
- FAIL_IF(!inst);
- compiler->size++;
- *inst = 0xff000000 | compiler->cpool_fill;
-
- for (i = 0; i < CONST_POOL_ALIGNMENT - 1; i++) {
- inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
- FAIL_IF(!inst);
- compiler->size++;
- *inst = 0;
- }
-
- cpool_ptr = compiler->cpool;
- cpool_end = cpool_ptr + compiler->cpool_fill;
- while (cpool_ptr < cpool_end) {
- inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
- FAIL_IF(!inst);
- compiler->size++;
- *inst = *cpool_ptr++;
- }
- compiler->cpool_diff = CONST_POOL_EMPTY;
- compiler->cpool_fill = 0;
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_uw inst)
-{
- sljit_uw* ptr;
-
- if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)))
- FAIL_IF(push_cpool(compiler));
-
- ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
- FAIL_IF(!ptr);
- compiler->size++;
- *ptr = inst;
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 push_inst_with_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal)
-{
- sljit_uw* ptr;
- sljit_uw cpool_index = CPOOL_SIZE;
- sljit_uw* cpool_ptr;
- sljit_uw* cpool_end;
- sljit_u8* cpool_unique_ptr;
-
- if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)))
- FAIL_IF(push_cpool(compiler));
- else if (compiler->cpool_fill > 0) {
- cpool_ptr = compiler->cpool;
- cpool_end = cpool_ptr + compiler->cpool_fill;
- cpool_unique_ptr = compiler->cpool_unique;
- do {
- if ((*cpool_ptr == literal) && !(*cpool_unique_ptr)) {
- cpool_index = (sljit_uw)(cpool_ptr - compiler->cpool);
- break;
- }
- cpool_ptr++;
- cpool_unique_ptr++;
- } while (cpool_ptr < cpool_end);
- }
-
- if (cpool_index == CPOOL_SIZE) {
- /* Must allocate a new entry in the literal pool. */
- if (compiler->cpool_fill < CPOOL_SIZE) {
- cpool_index = compiler->cpool_fill;
- compiler->cpool_fill++;
- }
- else {
- FAIL_IF(push_cpool(compiler));
- cpool_index = 0;
- compiler->cpool_fill = 1;
- }
- }
-
- SLJIT_ASSERT((inst & 0xfff) == 0);
- ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
- FAIL_IF(!ptr);
- compiler->size++;
- *ptr = inst | cpool_index;
-
- compiler->cpool[cpool_index] = literal;
- compiler->cpool_unique[cpool_index] = 0;
- if (compiler->cpool_diff == CONST_POOL_EMPTY)
- compiler->cpool_diff = compiler->size;
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 push_inst_with_unique_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal)
-{
- sljit_uw* ptr;
- if (SLJIT_UNLIKELY((compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)) || compiler->cpool_fill >= CPOOL_SIZE))
- FAIL_IF(push_cpool(compiler));
-
- SLJIT_ASSERT(compiler->cpool_fill < CPOOL_SIZE && (inst & 0xfff) == 0);
- ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
- FAIL_IF(!ptr);
- compiler->size++;
- *ptr = inst | compiler->cpool_fill;
-
- compiler->cpool[compiler->cpool_fill] = literal;
- compiler->cpool_unique[compiler->cpool_fill] = 1;
- compiler->cpool_fill++;
- if (compiler->cpool_diff == CONST_POOL_EMPTY)
- compiler->cpool_diff = compiler->size;
- return SLJIT_SUCCESS;
-}
-
-static SLJIT_INLINE sljit_s32 prepare_blx(struct sljit_compiler *compiler)
-{
- /* Place for at least two instruction (doesn't matter whether the first has a literal). */
- if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4088)))
- return push_cpool(compiler);
- return SLJIT_SUCCESS;
-}
-
-static SLJIT_INLINE sljit_s32 emit_blx(struct sljit_compiler *compiler)
-{
- /* Must follow tightly the previous instruction (to be able to convert it to bl instruction). */
- SLJIT_ASSERT(compiler->cpool_diff == CONST_POOL_EMPTY || compiler->size - compiler->cpool_diff < MAX_DIFFERENCE(4092));
- SLJIT_ASSERT(reg_map[TMP_REG1] != 14);
-
- return push_inst(compiler, BLX | RM(TMP_REG1));
-}
-
-static sljit_uw patch_pc_relative_loads(sljit_uw *last_pc_patch, sljit_uw *code_ptr, sljit_uw* const_pool, sljit_uw cpool_size)
-{
- sljit_uw diff;
- sljit_uw ind;
- sljit_uw counter = 0;
- sljit_uw* clear_const_pool = const_pool;
- sljit_uw* clear_const_pool_end = const_pool + cpool_size;
-
- SLJIT_ASSERT(const_pool - code_ptr <= CONST_POOL_ALIGNMENT);
- /* Set unused flag for all literals in the constant pool.
- I.e.: unused literals can belong to branches, which can be encoded as B or BL.
- We can "compress" the constant pool by discarding these literals. */
- while (clear_const_pool < clear_const_pool_end)
- *clear_const_pool++ = (sljit_uw)(-1);
-
- while (last_pc_patch < code_ptr) {
- /* Data transfer instruction with Rn == r15. */
- if ((*last_pc_patch & 0x0c0f0000) == 0x040f0000) {
- diff = (sljit_uw)(const_pool - last_pc_patch);
- ind = (*last_pc_patch) & 0xfff;
-
- /* Must be a load instruction with immediate offset. */
- SLJIT_ASSERT(ind < cpool_size && !(*last_pc_patch & (1 << 25)) && (*last_pc_patch & (1 << 20)));
- if ((sljit_s32)const_pool[ind] < 0) {
- const_pool[ind] = counter;
- ind = counter;
- counter++;
- }
- else
- ind = const_pool[ind];
-
- SLJIT_ASSERT(diff >= 1);
- if (diff >= 2 || ind > 0) {
- diff = (diff + (sljit_uw)ind - 2) << 2;
- SLJIT_ASSERT(diff <= 0xfff);
- *last_pc_patch = (*last_pc_patch & ~(sljit_uw)0xfff) | diff;
- }
- else
- *last_pc_patch = (*last_pc_patch & ~(sljit_uw)(0xfff | (1 << 23))) | 0x004;
- }
- last_pc_patch++;
- }
- return counter;
-}
-
-/* In some rare ocasions we may need future patches. The probability is close to 0 in practice. */
-struct future_patch {
- struct future_patch* next;
- sljit_s32 index;
- sljit_s32 value;
-};
-
-static sljit_s32 resolve_const_pool_index(struct sljit_compiler *compiler, struct future_patch **first_patch, sljit_uw cpool_current_index, sljit_uw *cpool_start_address, sljit_uw *buf_ptr)
-{
- sljit_u32 value;
- struct future_patch *curr_patch, *prev_patch;
-
- SLJIT_UNUSED_ARG(compiler);
-
- /* Using the values generated by patch_pc_relative_loads. */
- if (!*first_patch)
- value = cpool_start_address[cpool_current_index];
- else {
- curr_patch = *first_patch;
- prev_patch = NULL;
- while (1) {
- if (!curr_patch) {
- value = cpool_start_address[cpool_current_index];
- break;
- }
- if ((sljit_uw)curr_patch->index == cpool_current_index) {
- value = (sljit_uw)curr_patch->value;
- if (prev_patch)
- prev_patch->next = curr_patch->next;
- else
- *first_patch = curr_patch->next;
- SLJIT_FREE(curr_patch, compiler->allocator_data);
- break;
- }
- prev_patch = curr_patch;
- curr_patch = curr_patch->next;
- }
- }
-
- if ((sljit_sw)value >= 0) {
- if (value > cpool_current_index) {
- curr_patch = (struct future_patch*)SLJIT_MALLOC(sizeof(struct future_patch), compiler->allocator_data);
- if (!curr_patch) {
- while (*first_patch) {
- curr_patch = *first_patch;
- *first_patch = (*first_patch)->next;
- SLJIT_FREE(curr_patch, compiler->allocator_data);
- }
- return SLJIT_ERR_ALLOC_FAILED;
- }
- curr_patch->next = *first_patch;
- curr_patch->index = (sljit_sw)value;
- curr_patch->value = (sljit_sw)cpool_start_address[value];
- *first_patch = curr_patch;
- }
- cpool_start_address[value] = *buf_ptr;
- }
- return SLJIT_SUCCESS;
-}
-
-#else
-
-static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_uw inst)
-{
- sljit_uw* ptr;
-
- ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
- FAIL_IF(!ptr);
- compiler->size++;
- *ptr = inst;
- return SLJIT_SUCCESS;
-}
-
-static SLJIT_INLINE sljit_s32 emit_imm(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)
-{
- FAIL_IF(push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | ((sljit_u32)imm & 0xfff)));
- return push_inst(compiler, MOVT | RD(reg) | ((imm >> 12) & 0xf0000) | (((sljit_u32)imm >> 16) & 0xfff));
-}
-
-#endif
-
-static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code, sljit_sw executable_offset)
-{
- sljit_sw diff;
-
- if (jump->flags & SLJIT_REWRITABLE_JUMP)
- return 0;
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- if (jump->flags & IS_BL)
- code_ptr--;
-
- if (jump->flags & JUMP_ADDR)
- diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2) - executable_offset);
- else {
- SLJIT_ASSERT(jump->flags & JUMP_LABEL);
- diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2));
- }
-
- /* Branch to Thumb code has not been optimized yet. */
- if (diff & 0x3)
- return 0;
-
- if (jump->flags & IS_BL) {
- if (diff <= 0x01ffffff && diff >= -0x02000000) {
- *code_ptr = (BL - CONDITIONAL) | (*(code_ptr + 1) & COND_MASK);
- jump->flags |= PATCH_B;
- return 1;
- }
- }
- else {
- if (diff <= 0x01ffffff && diff >= -0x02000000) {
- *code_ptr = (B - CONDITIONAL) | (*code_ptr & COND_MASK);
- jump->flags |= PATCH_B;
- }
- }
-#else
- if (jump->flags & JUMP_ADDR)
- diff = ((sljit_sw)jump->u.target - (sljit_sw)code_ptr - executable_offset);
- else {
- SLJIT_ASSERT(jump->flags & JUMP_LABEL);
- diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)code_ptr);
- }
-
- /* Branch to Thumb code has not been optimized yet. */
- if (diff & 0x3)
- return 0;
-
- if (diff <= 0x01ffffff && diff >= -0x02000000) {
- code_ptr -= 2;
- *code_ptr = ((jump->flags & IS_BL) ? (BL - CONDITIONAL) : (B - CONDITIONAL)) | (code_ptr[2] & COND_MASK);
- jump->flags |= PATCH_B;
- return 1;
- }
-#endif
- return 0;
-}
-
-static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw executable_offset, sljit_uw new_addr, sljit_s32 flush_cache)
-{
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- sljit_uw *ptr = (sljit_uw *)jump_ptr;
- sljit_uw *inst = (sljit_uw *)ptr[0];
- sljit_uw mov_pc = ptr[1];
- sljit_s32 bl = (mov_pc & 0x0000f000) != RD(TMP_PC);
- sljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(inst + 2) - executable_offset) >> 2);
-
- SLJIT_UNUSED_ARG(executable_offset);
-
- if (diff <= 0x7fffff && diff >= -0x800000) {
- /* Turn to branch. */
- if (!bl) {
- if (flush_cache) {
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);
- }
- inst[0] = (mov_pc & COND_MASK) | (B - CONDITIONAL) | (diff & 0xffffff);
- if (flush_cache) {
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
- inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 1);
- }
- } else {
- if (flush_cache) {
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
- }
- inst[0] = (mov_pc & COND_MASK) | (BL - CONDITIONAL) | (diff & 0xffffff);
- inst[1] = NOP;
- if (flush_cache) {
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
- inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 2);
- }
- }
- } else {
- /* Get the position of the constant. */
- if (mov_pc & (1 << 23))
- ptr = inst + ((mov_pc & 0xfff) >> 2) + 2;
- else
- ptr = inst + 1;
-
- if (*inst != mov_pc) {
- if (flush_cache) {
- SLJIT_UPDATE_WX_FLAGS(inst, inst + (!bl ? 1 : 2), 0);
- }
- inst[0] = mov_pc;
- if (!bl) {
- if (flush_cache) {
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
- inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 1);
- }
- } else {
- inst[1] = BLX | RM(TMP_REG1);
- if (flush_cache) {
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
- inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 2);
- }
- }
- }
-
- if (flush_cache) {
- SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 0);
- }
-
- *ptr = new_addr;
-
- if (flush_cache) {
- SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1);
- }
- }
-#else
- sljit_uw *inst = (sljit_uw*)jump_ptr;
-
- SLJIT_UNUSED_ARG(executable_offset);
-
- SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);
-
- if (flush_cache) {
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
- }
-
- inst[0] = MOVW | (inst[0] & 0xf000) | ((new_addr << 4) & 0xf0000) | (new_addr & 0xfff);
- inst[1] = MOVT | (inst[1] & 0xf000) | ((new_addr >> 12) & 0xf0000) | ((new_addr >> 16) & 0xfff);
-
- if (flush_cache) {
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
- inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 2);
- }
-#endif
-}
-
-static sljit_uw get_imm(sljit_uw imm);
-static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_uw imm);
-static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg);
-
-static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_offset, sljit_uw new_constant, sljit_s32 flush_cache)
-{
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- sljit_uw *ptr = (sljit_uw*)addr;
- sljit_uw *inst = (sljit_uw*)ptr[0];
- sljit_uw ldr_literal = ptr[1];
- sljit_uw src2;
-
- SLJIT_UNUSED_ARG(executable_offset);
-
- src2 = get_imm(new_constant);
- if (src2) {
- if (flush_cache) {
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);
- }
-
- *inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2;
-
- if (flush_cache) {
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
- inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 1);
- }
- return;
- }
-
- src2 = get_imm(~new_constant);
- if (src2) {
- if (flush_cache) {
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);
- }
-
- *inst = 0xe3e00000 | (ldr_literal & 0xf000) | src2;
-
- if (flush_cache) {
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
- inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 1);
- }
- return;
- }
-
- if (ldr_literal & (1 << 23))
- ptr = inst + ((ldr_literal & 0xfff) >> 2) + 2;
- else
- ptr = inst + 1;
-
- if (*inst != ldr_literal) {
- if (flush_cache) {
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);
- }
-
- *inst = ldr_literal;
-
- if (flush_cache) {
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
- inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 1);
- }
- }
-
- if (flush_cache) {
- SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 0);
- }
-
- *ptr = new_constant;
-
- if (flush_cache) {
- SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1);
- }
-#else
- sljit_uw *inst = (sljit_uw*)addr;
-
- SLJIT_UNUSED_ARG(executable_offset);
-
- SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);
-
- if (flush_cache) {
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
- }
-
- inst[0] = MOVW | (inst[0] & 0xf000) | ((new_constant << 4) & 0xf0000) | (new_constant & 0xfff);
- inst[1] = MOVT | (inst[1] & 0xf000) | ((new_constant >> 12) & 0xf0000) | ((new_constant >> 16) & 0xfff);
-
- if (flush_cache) {
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
- inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 2);
- }
-#endif
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
-{
- struct sljit_memory_fragment *buf;
- sljit_uw *code;
- sljit_uw *code_ptr;
- sljit_uw *buf_ptr;
- sljit_uw *buf_end;
- sljit_uw size;
- sljit_uw word_count;
- sljit_uw next_addr;
- sljit_sw executable_offset;
- sljit_uw addr;
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- sljit_uw cpool_size;
- sljit_uw cpool_skip_alignment;
- sljit_uw cpool_current_index;
- sljit_uw *cpool_start_address;
- sljit_uw *last_pc_patch;
- struct future_patch *first_patch;
-#endif
-
- struct sljit_label *label;
- struct sljit_jump *jump;
- struct sljit_const *const_;
- struct sljit_put_label *put_label;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_generate_code(compiler));
- reverse_buf(compiler);
-
- /* Second code generation pass. */
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- size = compiler->size + (compiler->patches << 1);
- if (compiler->cpool_fill > 0)
- size += compiler->cpool_fill + CONST_POOL_ALIGNMENT - 1;
-#else
- size = compiler->size;
-#endif
- code = (sljit_uw*)SLJIT_MALLOC_EXEC(size * sizeof(sljit_uw), compiler->exec_allocator_data);
- PTR_FAIL_WITH_EXEC_IF(code);
- buf = compiler->buf;
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- cpool_size = 0;
- cpool_skip_alignment = 0;
- cpool_current_index = 0;
- cpool_start_address = NULL;
- first_patch = NULL;
- last_pc_patch = code;
-#endif
-
- code_ptr = code;
- word_count = 0;
- next_addr = 1;
- executable_offset = SLJIT_EXEC_OFFSET(code);
-
- label = compiler->labels;
- jump = compiler->jumps;
- const_ = compiler->consts;
- put_label = compiler->put_labels;
-
- if (label && label->size == 0) {
- label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
- label = label->next;
- }
-
- do {
- buf_ptr = (sljit_uw*)buf->memory;
- buf_end = buf_ptr + (buf->used_size >> 2);
- do {
- word_count++;
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- if (cpool_size > 0) {
- if (cpool_skip_alignment > 0) {
- buf_ptr++;
- cpool_skip_alignment--;
- }
- else {
- if (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {
- SLJIT_FREE_EXEC(code, compiler->exec_allocator_data);
- compiler->error = SLJIT_ERR_ALLOC_FAILED;
- return NULL;
- }
- buf_ptr++;
- if (++cpool_current_index >= cpool_size) {
- SLJIT_ASSERT(!first_patch);
- cpool_size = 0;
- if (label && label->size == word_count) {
- /* Points after the current instruction. */
- label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
- label->size = (sljit_uw)(code_ptr - code);
- label = label->next;
-
- next_addr = compute_next_addr(label, jump, const_, put_label);
- }
- }
- }
- }
- else if ((*buf_ptr & 0xff000000) != PUSH_POOL) {
-#endif
- *code_ptr = *buf_ptr++;
- if (next_addr == word_count) {
- SLJIT_ASSERT(!label || label->size >= word_count);
- SLJIT_ASSERT(!jump || jump->addr >= word_count);
- SLJIT_ASSERT(!const_ || const_->addr >= word_count);
- SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
-
- /* These structures are ordered by their address. */
- if (jump && jump->addr == word_count) {
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- if (detect_jump_type(jump, code_ptr, code, executable_offset))
- code_ptr--;
- jump->addr = (sljit_uw)code_ptr;
-#else
- jump->addr = (sljit_uw)(code_ptr - 2);
- if (detect_jump_type(jump, code_ptr, code, executable_offset))
- code_ptr -= 2;
-#endif
- jump = jump->next;
- }
- if (label && label->size == word_count) {
- /* code_ptr can be affected above. */
- label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr + 1, executable_offset);
- label->size = (sljit_uw)((code_ptr + 1) - code);
- label = label->next;
- }
- if (const_ && const_->addr == word_count) {
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- const_->addr = (sljit_uw)code_ptr;
-#else
- const_->addr = (sljit_uw)(code_ptr - 1);
-#endif
- const_ = const_->next;
- }
- if (put_label && put_label->addr == word_count) {
- SLJIT_ASSERT(put_label->label);
- put_label->addr = (sljit_uw)code_ptr;
- put_label = put_label->next;
- }
- next_addr = compute_next_addr(label, jump, const_, put_label);
- }
- code_ptr++;
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- }
- else {
- /* Fortunately, no need to shift. */
- cpool_size = *buf_ptr++ & ~PUSH_POOL;
- SLJIT_ASSERT(cpool_size > 0);
- cpool_start_address = ALIGN_INSTRUCTION(code_ptr + 1);
- cpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, cpool_size);
- if (cpool_current_index > 0) {
- /* Unconditional branch. */
- *code_ptr = B | (((sljit_uw)(cpool_start_address - code_ptr) + cpool_current_index - 2) & ~PUSH_POOL);
- code_ptr = (sljit_uw*)(cpool_start_address + cpool_current_index);
- }
- cpool_skip_alignment = CONST_POOL_ALIGNMENT - 1;
- cpool_current_index = 0;
- last_pc_patch = code_ptr;
- }
-#endif
- } while (buf_ptr < buf_end);
- buf = buf->next;
- } while (buf);
-
- SLJIT_ASSERT(!label);
- SLJIT_ASSERT(!jump);
- SLJIT_ASSERT(!const_);
- SLJIT_ASSERT(!put_label);
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- SLJIT_ASSERT(cpool_size == 0);
- if (compiler->cpool_fill > 0) {
- cpool_start_address = ALIGN_INSTRUCTION(code_ptr);
- cpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, compiler->cpool_fill);
- if (cpool_current_index > 0)
- code_ptr = (sljit_uw*)(cpool_start_address + cpool_current_index);
-
- buf_ptr = compiler->cpool;
- buf_end = buf_ptr + compiler->cpool_fill;
- cpool_current_index = 0;
- while (buf_ptr < buf_end) {
- if (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {
- SLJIT_FREE_EXEC(code, compiler->exec_allocator_data);
- compiler->error = SLJIT_ERR_ALLOC_FAILED;
- return NULL;
- }
- buf_ptr++;
- cpool_current_index++;
- }
- SLJIT_ASSERT(!first_patch);
- }
-#endif
-
- jump = compiler->jumps;
- while (jump) {
- buf_ptr = (sljit_uw *)jump->addr;
-
- if (jump->flags & PATCH_B) {
- addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset);
- if (!(jump->flags & JUMP_ADDR)) {
- SLJIT_ASSERT(jump->flags & JUMP_LABEL);
- SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - addr) <= 0x01ffffff && (sljit_sw)(jump->u.label->addr - addr) >= -0x02000000);
- *buf_ptr |= ((jump->u.label->addr - addr) >> 2) & 0x00ffffff;
- }
- else {
- SLJIT_ASSERT((sljit_sw)(jump->u.target - addr) <= 0x01ffffff && (sljit_sw)(jump->u.target - addr) >= -0x02000000);
- *buf_ptr |= ((jump->u.target - addr) >> 2) & 0x00ffffff;
- }
- }
- else if (jump->flags & SLJIT_REWRITABLE_JUMP) {
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- jump->addr = (sljit_uw)code_ptr;
- code_ptr[0] = (sljit_uw)buf_ptr;
- code_ptr[1] = *buf_ptr;
- inline_set_jump_addr((sljit_uw)code_ptr, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
- code_ptr += 2;
-#else
- inline_set_jump_addr((sljit_uw)buf_ptr, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
-#endif
- }
- else {
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- if (jump->flags & IS_BL)
- buf_ptr--;
- if (*buf_ptr & (1 << 23))
- buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2;
- else
- buf_ptr += 1;
- *buf_ptr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
-#else
- inline_set_jump_addr((sljit_uw)buf_ptr, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
-#endif
- }
- jump = jump->next;
- }
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- const_ = compiler->consts;
- while (const_) {
- buf_ptr = (sljit_uw*)const_->addr;
- const_->addr = (sljit_uw)code_ptr;
-
- code_ptr[0] = (sljit_uw)buf_ptr;
- code_ptr[1] = *buf_ptr;
- if (*buf_ptr & (1 << 23))
- buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2;
- else
- buf_ptr += 1;
- /* Set the value again (can be a simple constant). */
- inline_set_const((sljit_uw)code_ptr, executable_offset, *buf_ptr, 0);
- code_ptr += 2;
-
- const_ = const_->next;
- }
-#endif
-
- put_label = compiler->put_labels;
- while (put_label) {
- addr = put_label->label->addr;
- buf_ptr = (sljit_uw*)put_label->addr;
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- SLJIT_ASSERT((buf_ptr[0] & 0xffff0000) == 0xe59f0000);
- buf_ptr[((buf_ptr[0] & 0xfff) >> 2) + 2] = addr;
-#else
- SLJIT_ASSERT((buf_ptr[-1] & 0xfff00000) == MOVW && (buf_ptr[0] & 0xfff00000) == MOVT);
- buf_ptr[-1] |= ((addr << 4) & 0xf0000) | (addr & 0xfff);
- buf_ptr[0] |= ((addr >> 12) & 0xf0000) | ((addr >> 16) & 0xfff);
-#endif
- put_label = put_label->next;
- }
-
- SLJIT_ASSERT(code_ptr - code <= (sljit_s32)size);
-
- compiler->error = SLJIT_ERR_COMPILED;
- compiler->executable_offset = executable_offset;
- compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_uw);
-
- code = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
- code_ptr = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
-
- SLJIT_CACHE_FLUSH(code, code_ptr);
- SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
- return code;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
-{
- switch (feature_type) {
- case SLJIT_HAS_FPU:
-#ifdef SLJIT_IS_FPU_AVAILABLE
- return SLJIT_IS_FPU_AVAILABLE;
-#else
- /* Available by default. */
- return 1;
-#endif
-
- case SLJIT_HAS_CLZ:
- case SLJIT_HAS_ROT:
- case SLJIT_HAS_CMOV:
-#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
- case SLJIT_HAS_CTZ:
- case SLJIT_HAS_PREFETCH:
-#endif
- return 1;
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- case SLJIT_HAS_CTZ:
- return 2;
-#endif
-
- default:
- return 0;
- }
-}
-
-/* --------------------------------------------------------------------- */
-/* Entry, exit */
-/* --------------------------------------------------------------------- */
-
-/* Creates an index in data_transfer_insts array. */
-#define WORD_SIZE 0x00
-#define BYTE_SIZE 0x01
-#define HALF_SIZE 0x02
-#define PRELOAD 0x03
-#define SIGNED 0x04
-#define LOAD_DATA 0x08
-
-/* Flag bits for emit_op. */
-#define ALLOW_IMM 0x10
-#define ALLOW_INV_IMM 0x20
-#define ALLOW_ANY_IMM (ALLOW_IMM | ALLOW_INV_IMM)
-#define ALLOW_NEG_IMM 0x40
-
-/* s/l - store/load (1 bit)
- u/s - signed/unsigned (1 bit)
- w/b/h/N - word/byte/half/NOT allowed (2 bit)
- Storing signed and unsigned values are the same operations. */
-
-static const sljit_uw data_transfer_insts[16] = {
-/* s u w */ 0xe5000000 /* str */,
-/* s u b */ 0xe5400000 /* strb */,
-/* s u h */ 0xe10000b0 /* strh */,
-/* s u N */ 0x00000000 /* not allowed */,
-/* s s w */ 0xe5000000 /* str */,
-/* s s b */ 0xe5400000 /* strb */,
-/* s s h */ 0xe10000b0 /* strh */,
-/* s s N */ 0x00000000 /* not allowed */,
-
-/* l u w */ 0xe5100000 /* ldr */,
-/* l u b */ 0xe5500000 /* ldrb */,
-/* l u h */ 0xe11000b0 /* ldrh */,
-/* l u p */ 0xf5500000 /* preload */,
-/* l s w */ 0xe5100000 /* ldr */,
-/* l s b */ 0xe11000d0 /* ldrsb */,
-/* l s h */ 0xe11000f0 /* ldrsh */,
-/* l s N */ 0x00000000 /* not allowed */,
-};
-
-#define EMIT_DATA_TRANSFER(type, add, target_reg, base_reg, arg) \
- (data_transfer_insts[(type) & 0xf] | ((add) << 23) | RD(target_reg) | RN(base_reg) | (sljit_uw)(arg))
-
-/* Normal ldr/str instruction.
- Type2: ldrsb, ldrh, ldrsh */
-#define IS_TYPE1_TRANSFER(type) \
- (data_transfer_insts[(type) & 0xf] & 0x04000000)
-#define TYPE2_TRANSFER_IMM(imm) \
- (((imm) & 0xf) | (((imm) & 0xf0) << 4) | (1 << 22))
-
-#define EMIT_FPU_OPERATION(opcode, mode, dst, src1, src2) \
- ((sljit_uw)(opcode) | (sljit_uw)(mode) | VD(dst) | VM(src1) | VN(src2))
-
-/* Flags for emit_op: */
- /* Arguments are swapped. */
-#define ARGS_SWAPPED 0x01
- /* Inverted immediate. */
-#define INV_IMM 0x02
- /* Source and destination is register. */
-#define MOVE_REG_CONV 0x04
- /* Unused return value. */
-#define UNUSED_RETURN 0x08
-/* SET_FLAGS must be (1 << 20) as it is also the value of S bit (can be used for optimization). */
-#define SET_FLAGS (1 << 20)
-/* dst: reg
- src1: reg
- src2: reg or imm (if allowed)
- SRC2_IMM must be (1 << 25) as it is also the value of I bit (can be used for optimization). */
-#define SRC2_IMM (1 << 25)
-
-static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 inp_flags,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w);
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- sljit_uw imm, offset;
- sljit_s32 i, tmp, size, word_arg_count;
- sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options);
-#ifdef __SOFTFP__
- sljit_u32 float_arg_count;
-#else
- sljit_u32 old_offset, f32_offset;
- sljit_u32 remap[3];
- sljit_u32 *remap_ptr = remap;
-#endif
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
- set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
-
- imm = 0;
-
- tmp = SLJIT_S0 - saveds;
- for (i = SLJIT_S0 - saved_arg_count; i > tmp; i--)
- imm |= (sljit_uw)1 << reg_map[i];
-
- for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--)
- imm |= (sljit_uw)1 << reg_map[i];
-
- SLJIT_ASSERT(reg_map[TMP_REG2] == 14);
-
- /* Push saved and temporary registers
- multiple registers: stmdb sp!, {..., lr}
- single register: str reg, [sp, #-4]! */
- if (imm != 0)
- FAIL_IF(push_inst(compiler, PUSH | (1 << 14) | imm));
- else
- FAIL_IF(push_inst(compiler, 0xe52d0004 | RD(TMP_REG2)));
-
- /* Stack must be aligned to 8 bytes: */
- size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1);
-
- if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
- if ((size & SSIZE_OF(sw)) != 0) {
- FAIL_IF(push_inst(compiler, SUB | RD(SLJIT_SP) | RN(SLJIT_SP) | SRC2_IMM | sizeof(sljit_sw)));
- size += SSIZE_OF(sw);
- }
-
- if (fsaveds + fscratches >= SLJIT_NUMBER_OF_FLOAT_REGISTERS) {
- FAIL_IF(push_inst(compiler, VPUSH | VD(SLJIT_FS0) | ((sljit_uw)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1)));
- } else {
- if (fsaveds > 0)
- FAIL_IF(push_inst(compiler, VPUSH | VD(SLJIT_FS0) | ((sljit_uw)fsaveds << 1)));
- if (fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG)
- FAIL_IF(push_inst(compiler, VPUSH | VD(fscratches) | ((sljit_uw)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1)));
- }
- }
-
- local_size = ((size + local_size + 0x7) & ~0x7) - size;
- compiler->local_size = local_size;
-
- if (options & SLJIT_ENTER_REG_ARG)
- arg_types = 0;
-
- arg_types >>= SLJIT_ARG_SHIFT;
- word_arg_count = 0;
- saved_arg_count = 0;
-#ifdef __SOFTFP__
- SLJIT_COMPILE_ASSERT(SLJIT_FR0 == 1, float_register_index_start);
-
- offset = 0;
- float_arg_count = 0;
-
- while (arg_types) {
- switch (arg_types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- if (offset & 0x7)
- offset += sizeof(sljit_sw);
-
- if (offset < 4 * sizeof(sljit_sw))
- FAIL_IF(push_inst(compiler, VMOV2 | (offset << 10) | ((offset + sizeof(sljit_sw)) << 14) | float_arg_count));
- else
- FAIL_IF(push_inst(compiler, VLDR_F32 | 0x800100 | RN(SLJIT_SP)
- | (float_arg_count << 12) | ((offset + (sljit_uw)size - 4 * sizeof(sljit_sw)) >> 2)));
- float_arg_count++;
- offset += sizeof(sljit_f64) - sizeof(sljit_sw);
- break;
- case SLJIT_ARG_TYPE_F32:
- if (offset < 4 * sizeof(sljit_sw))
- FAIL_IF(push_inst(compiler, VMOV | (float_arg_count << 16) | (offset << 10)));
- else
- FAIL_IF(push_inst(compiler, VLDR_F32 | 0x800000 | RN(SLJIT_SP)
- | (float_arg_count << 12) | ((offset + (sljit_uw)size - 4 * sizeof(sljit_sw)) >> 2)));
- float_arg_count++;
- break;
- default:
- word_arg_count++;
-
- if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {
- tmp = SLJIT_S0 - saved_arg_count;
- saved_arg_count++;
- } else if (word_arg_count - 1 != (sljit_s32)(offset >> 2))
- tmp = word_arg_count;
- else
- break;
-
- if (offset < 4 * sizeof(sljit_sw))
- FAIL_IF(push_inst(compiler, MOV | RD(tmp) | (offset >> 2)));
- else
- FAIL_IF(push_inst(compiler, LDR | 0x800000 | RN(SLJIT_SP) | RD(tmp) | (offset + (sljit_uw)size - 4 * sizeof(sljit_sw))));
- break;
- }
-
- offset += sizeof(sljit_sw);
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- compiler->args_size = offset;
-#else
- offset = SLJIT_FR0;
- old_offset = SLJIT_FR0;
- f32_offset = 0;
-
- while (arg_types) {
- switch (arg_types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- if (offset != old_offset)
- *remap_ptr++ = EMIT_FPU_OPERATION(VMOV_F32, SLJIT_32, offset, old_offset, 0);
- old_offset++;
- offset++;
- break;
- case SLJIT_ARG_TYPE_F32:
- if (f32_offset != 0) {
- *remap_ptr++ = EMIT_FPU_OPERATION(VMOV_F32, 0x20, offset, f32_offset, 0);
- f32_offset = 0;
- } else {
- if (offset != old_offset)
- *remap_ptr++ = EMIT_FPU_OPERATION(VMOV_F32, 0, offset, old_offset, 0);
- f32_offset = old_offset;
- old_offset++;
- }
- offset++;
- break;
- default:
- if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {
- FAIL_IF(push_inst(compiler, MOV | RD(SLJIT_S0 - saved_arg_count) | RM(SLJIT_R0 + word_arg_count)));
- saved_arg_count++;
- }
-
- word_arg_count++;
- break;
- }
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- SLJIT_ASSERT((sljit_uw)(remap_ptr - remap) <= sizeof(remap));
-
- while (remap_ptr > remap)
- FAIL_IF(push_inst(compiler, *(--remap_ptr)));
-#endif
-
- if (local_size > 0)
- FAIL_IF(emit_op(compiler, SLJIT_SUB, ALLOW_IMM, SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size));
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- sljit_s32 size;
-
- CHECK_ERROR();
- CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
- set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
-
- size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1);
-
- if ((size & SSIZE_OF(sw)) != 0 && (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG))
- size += SSIZE_OF(sw);
-
- compiler->local_size = ((size + local_size + 0x7) & ~0x7) - size;
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_add_sp(struct sljit_compiler *compiler, sljit_uw imm)
-{
- sljit_uw imm2 = get_imm(imm);
-
- if (imm2 == 0) {
- imm2 = (imm & ~(sljit_uw)0x3ff) >> 10;
- imm = (imm & 0x3ff) >> 2;
-
- FAIL_IF(push_inst(compiler, ADD | SRC2_IMM | RD(SLJIT_SP) | RN(SLJIT_SP) | 0xb00 | imm2));
- return push_inst(compiler, ADD | SRC2_IMM | RD(SLJIT_SP) | RN(SLJIT_SP) | 0xf00 | (imm & 0xff));
- }
-
- return push_inst(compiler, ADD | RD(SLJIT_SP) | RN(SLJIT_SP) | imm2);
-}
-
-static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size)
-{
- sljit_s32 local_size, fscratches, fsaveds, i, tmp;
- sljit_s32 restored_reg = 0;
- sljit_s32 lr_dst = TMP_PC;
- sljit_uw reg_list = 0;
-
- SLJIT_ASSERT(reg_map[TMP_REG2] == 14 && frame_size <= 128);
-
- local_size = compiler->local_size;
- fscratches = compiler->fscratches;
- fsaveds = compiler->fsaveds;
-
- if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
- if (local_size > 0)
- FAIL_IF(emit_add_sp(compiler, (sljit_uw)local_size));
-
- if (fsaveds + fscratches >= SLJIT_NUMBER_OF_FLOAT_REGISTERS) {
- FAIL_IF(push_inst(compiler, VPOP | VD(SLJIT_FS0) | ((sljit_uw)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1)));
- } else {
- if (fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG)
- FAIL_IF(push_inst(compiler, VPOP | VD(fscratches) | ((sljit_uw)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1)));
- if (fsaveds > 0)
- FAIL_IF(push_inst(compiler, VPOP | VD(SLJIT_FS0) | ((sljit_uw)fsaveds << 1)));
- }
-
- local_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1) & 0x7;
- }
-
- if (frame_size < 0) {
- lr_dst = TMP_REG2;
- frame_size = 0;
- } else if (frame_size > 0) {
- SLJIT_ASSERT(frame_size == 1 || (frame_size & 0x7) == 0);
- lr_dst = 0;
- frame_size &= ~0x7;
- }
-
- if (lr_dst != 0)
- reg_list |= (sljit_uw)1 << reg_map[lr_dst];
-
- tmp = SLJIT_S0 - compiler->saveds;
- i = SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options);
- if (tmp < i) {
- restored_reg = i;
- do {
- reg_list |= (sljit_uw)1 << reg_map[i];
- } while (--i > tmp);
- }
-
- i = compiler->scratches;
- if (i >= SLJIT_FIRST_SAVED_REG) {
- restored_reg = i;
- do {
- reg_list |= (sljit_uw)1 << reg_map[i];
- } while (--i >= SLJIT_FIRST_SAVED_REG);
- }
-
- if (lr_dst == TMP_REG2 && reg_list == 0) {
- restored_reg = TMP_REG2;
- lr_dst = 0;
- }
-
- if (lr_dst == 0 && (reg_list & (reg_list - 1)) == 0) {
- /* The local_size does not include the saved registers. */
- tmp = 0;
- if (reg_list != 0) {
- tmp = 2;
- if (local_size <= 0xfff) {
- if (local_size == 0) {
- SLJIT_ASSERT(restored_reg != TMP_REG2);
- if (frame_size == 0)
- return push_inst(compiler, LDR_POST | RN(SLJIT_SP) | RD(restored_reg) | 0x800008);
- if (frame_size > 2 * SSIZE_OF(sw))
- return push_inst(compiler, LDR_POST | RN(SLJIT_SP) | RD(restored_reg) | (sljit_uw)(frame_size - (2 * SSIZE_OF(sw))));
- }
-
- FAIL_IF(push_inst(compiler, LDR | 0x800000 | RN(SLJIT_SP) | RD(restored_reg) | (sljit_uw)local_size));
- tmp = 1;
- } else if (frame_size == 0) {
- frame_size = (restored_reg == TMP_REG2) ? SSIZE_OF(sw) : 2 * SSIZE_OF(sw);
- tmp = 3;
- }
-
- /* Place for the saved register. */
- if (restored_reg != TMP_REG2)
- local_size += SSIZE_OF(sw);
- }
-
- /* Place for the lr register. */
- local_size += SSIZE_OF(sw);
-
- if (frame_size > local_size)
- FAIL_IF(push_inst(compiler, SUB | RD(SLJIT_SP) | RN(SLJIT_SP) | (1 << 25) | (sljit_uw)(frame_size - local_size)));
- else if (frame_size < local_size)
- FAIL_IF(emit_add_sp(compiler, (sljit_uw)(local_size - frame_size)));
-
- if (tmp <= 1)
- return SLJIT_SUCCESS;
-
- if (tmp == 2) {
- frame_size -= SSIZE_OF(sw);
- if (restored_reg != TMP_REG2)
- frame_size -= SSIZE_OF(sw);
-
- return push_inst(compiler, LDR | 0x800000 | RN(SLJIT_SP) | RD(restored_reg) | (sljit_uw)frame_size);
- }
-
- tmp = (restored_reg == TMP_REG2) ? 0x800004 : 0x800008;
- return push_inst(compiler, LDR_POST | RN(SLJIT_SP) | RD(restored_reg) | (sljit_uw)tmp);
- }
-
- if (local_size > 0)
- FAIL_IF(emit_add_sp(compiler, (sljit_uw)local_size));
-
- /* Pop saved and temporary registers
- multiple registers: ldmia sp!, {...}
- single register: ldr reg, [sp], #4 */
- if ((reg_list & (reg_list - 1)) == 0) {
- SLJIT_ASSERT(lr_dst != 0);
- SLJIT_ASSERT(reg_list == (sljit_uw)1 << reg_map[lr_dst]);
-
- return push_inst(compiler, LDR_POST | RN(SLJIT_SP) | RD(lr_dst) | 0x800004);
- }
-
- FAIL_IF(push_inst(compiler, POP | reg_list));
-
- if (frame_size > 0)
- return push_inst(compiler, SUB | RD(SLJIT_SP) | RN(SLJIT_SP) | (1 << 25) | ((sljit_uw)frame_size - sizeof(sljit_sw)));
-
- if (lr_dst != 0)
- return SLJIT_SUCCESS;
-
- return push_inst(compiler, ADD | RD(SLJIT_SP) | RN(SLJIT_SP) | (1 << 25) | sizeof(sljit_sw));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_return_void(compiler));
-
- return emit_stack_frame_release(compiler, 0);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,
- sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_return_to(compiler, src, srcw));
-
- if (src & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
- src = TMP_REG1;
- srcw = 0;
- } else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
- FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | RM(src)));
- src = TMP_REG1;
- srcw = 0;
- }
-
- FAIL_IF(emit_stack_frame_release(compiler, 1));
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);
-}
-
-/* --------------------------------------------------------------------- */
-/* Operators */
-/* --------------------------------------------------------------------- */
-
-static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
- sljit_uw dst, sljit_uw src1, sljit_uw src2)
-{
- sljit_s32 is_masked;
- sljit_uw shift_type;
-
- switch (GET_OPCODE(op)) {
- case SLJIT_MOV:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));
- if (dst != src2) {
- if (src2 & SRC2_IMM) {
- return push_inst(compiler, ((flags & INV_IMM) ? MVN : MOV) | RD(dst) | src2);
- }
- return push_inst(compiler, MOV | RD(dst) | RM(src2));
- }
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_U8:
- case SLJIT_MOV_S8:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));
- if (flags & MOVE_REG_CONV) {
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- if (op == SLJIT_MOV_U8)
- return push_inst(compiler, AND | RD(dst) | RN(src2) | SRC2_IMM | 0xff);
- FAIL_IF(push_inst(compiler, MOV | RD(dst) | (24 << 7) | RM(src2)));
- return push_inst(compiler, MOV | RD(dst) | (24 << 7) | (op == SLJIT_MOV_U8 ? 0x20 : 0x40) | RM(dst));
-#else
- return push_inst(compiler, (op == SLJIT_MOV_U8 ? UXTB : SXTB) | RD(dst) | RM(src2));
-#endif
- }
- else if (dst != src2) {
- SLJIT_ASSERT(src2 & SRC2_IMM);
- return push_inst(compiler, ((flags & INV_IMM) ? MVN : MOV) | RD(dst) | src2);
- }
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_U16:
- case SLJIT_MOV_S16:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));
- if (flags & MOVE_REG_CONV) {
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- FAIL_IF(push_inst(compiler, MOV | RD(dst) | (16 << 7) | RM(src2)));
- return push_inst(compiler, MOV | RD(dst) | (16 << 7) | (op == SLJIT_MOV_U16 ? 0x20 : 0x40) | RM(dst));
-#else
- return push_inst(compiler, (op == SLJIT_MOV_U16 ? UXTH : SXTH) | RD(dst) | RM(src2));
-#endif
- }
- else if (dst != src2) {
- SLJIT_ASSERT(src2 & SRC2_IMM);
- return push_inst(compiler, ((flags & INV_IMM) ? MVN : MOV) | RD(dst) | src2);
- }
- return SLJIT_SUCCESS;
-
- case SLJIT_NOT:
- if (src2 & SRC2_IMM)
- return push_inst(compiler, ((flags & INV_IMM) ? MOV : MVN) | (flags & SET_FLAGS) | RD(dst) | src2);
-
- return push_inst(compiler, MVN | (flags & SET_FLAGS) | RD(dst) | RM(src2));
-
- case SLJIT_CLZ:
- SLJIT_ASSERT(!(flags & INV_IMM) && !(src2 & SRC2_IMM));
- FAIL_IF(push_inst(compiler, CLZ | RD(dst) | RM(src2)));
- return SLJIT_SUCCESS;
-
- case SLJIT_CTZ:
- SLJIT_ASSERT(!(flags & INV_IMM) && !(src2 & SRC2_IMM));
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- FAIL_IF(push_inst(compiler, RSB | SRC2_IMM | RD(TMP_REG1) | RN(src2) | 0));
- FAIL_IF(push_inst(compiler, AND | RD(TMP_REG2) | RN(src2) | RM(TMP_REG1)));
- FAIL_IF(push_inst(compiler, CLZ | RD(dst) | RM(TMP_REG2)));
- FAIL_IF(push_inst(compiler, CMP | SET_FLAGS | SRC2_IMM | RN(dst) | 32));
- return push_inst(compiler, (EOR ^ 0xf0000000) | SRC2_IMM | RD(dst) | RN(dst) | 0x1f);
-#else /* !SLJIT_CONFIG_ARM_V5 */
- FAIL_IF(push_inst(compiler, RBIT | RD(dst) | RM(src2)));
- return push_inst(compiler, CLZ | RD(dst) | RM(dst));
-#endif /* SLJIT_CONFIG_ARM_V5 */
-
- case SLJIT_ADD:
- SLJIT_ASSERT(!(flags & INV_IMM));
-
- if ((flags & (UNUSED_RETURN | ARGS_SWAPPED)) == UNUSED_RETURN)
- return push_inst(compiler, CMN | SET_FLAGS | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));
- return push_inst(compiler, ADD | (flags & SET_FLAGS) | RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));
-
- case SLJIT_ADDC:
- SLJIT_ASSERT(!(flags & INV_IMM));
- return push_inst(compiler, ADC | (flags & SET_FLAGS) | RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));
-
- case SLJIT_SUB:
- SLJIT_ASSERT(!(flags & INV_IMM));
-
- if ((flags & (UNUSED_RETURN | ARGS_SWAPPED)) == UNUSED_RETURN)
- return push_inst(compiler, CMP | SET_FLAGS | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));
-
- return push_inst(compiler, (!(flags & ARGS_SWAPPED) ? SUB : RSB) | (flags & SET_FLAGS)
- | RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));
-
- case SLJIT_SUBC:
- SLJIT_ASSERT(!(flags & INV_IMM));
- return push_inst(compiler, (!(flags & ARGS_SWAPPED) ? SBC : RSC) | (flags & SET_FLAGS)
- | RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));
-
- case SLJIT_MUL:
- SLJIT_ASSERT(!(flags & INV_IMM));
- SLJIT_ASSERT(!(src2 & SRC2_IMM));
- compiler->status_flags_state = 0;
-
- if (!HAS_FLAGS(op))
- return push_inst(compiler, MUL | RN(dst) | RM8(src2) | RM(src1));
-
- FAIL_IF(push_inst(compiler, SMULL | RN(TMP_REG1) | RD(dst) | RM8(src2) | RM(src1)));
-
- /* cmp TMP_REG1, dst asr #31. */
- return push_inst(compiler, CMP | SET_FLAGS | RN(TMP_REG1) | RM(dst) | 0xfc0);
-
- case SLJIT_AND:
- if ((flags & (UNUSED_RETURN | INV_IMM)) == UNUSED_RETURN)
- return push_inst(compiler, TST | SET_FLAGS | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));
- return push_inst(compiler, (!(flags & INV_IMM) ? AND : BIC) | (flags & SET_FLAGS)
- | RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));
-
- case SLJIT_OR:
- SLJIT_ASSERT(!(flags & INV_IMM));
- return push_inst(compiler, ORR | (flags & SET_FLAGS) | RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));
-
- case SLJIT_XOR:
- SLJIT_ASSERT(!(flags & INV_IMM));
- return push_inst(compiler, EOR | (flags & SET_FLAGS) | RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));
-
- case SLJIT_SHL:
- case SLJIT_MSHL:
- shift_type = 0;
- is_masked = GET_OPCODE(op) == SLJIT_MSHL;
- break;
-
- case SLJIT_LSHR:
- case SLJIT_MLSHR:
- shift_type = 1;
- is_masked = GET_OPCODE(op) == SLJIT_MLSHR;
- break;
-
- case SLJIT_ASHR:
- case SLJIT_MASHR:
- shift_type = 2;
- is_masked = GET_OPCODE(op) == SLJIT_MASHR;
- break;
-
- case SLJIT_ROTL:
- if (compiler->shift_imm == 0x20) {
- FAIL_IF(push_inst(compiler, RSB | SRC2_IMM | RD(TMP_REG2) | RN(src2) | 0));
- src2 = TMP_REG2;
- } else
- compiler->shift_imm = (sljit_uw)(-(sljit_sw)compiler->shift_imm) & 0x1f;
- /* fallthrough */
-
- case SLJIT_ROTR:
- shift_type = 3;
- is_masked = 0;
- break;
-
- default:
- SLJIT_UNREACHABLE();
- return SLJIT_SUCCESS;
- }
-
- SLJIT_ASSERT(!(flags & ARGS_SWAPPED) && !(flags & INV_IMM) && !(src2 & SRC2_IMM));
-
- if (compiler->shift_imm != 0x20) {
- SLJIT_ASSERT(src1 == TMP_REG1);
-
- if (compiler->shift_imm != 0)
- return push_inst(compiler, MOV | (flags & SET_FLAGS) |
- RD(dst) | (compiler->shift_imm << 7) | (shift_type << 5) | RM(src2));
- return push_inst(compiler, MOV | (flags & SET_FLAGS) | RD(dst) | RM(src2));
- }
-
- SLJIT_ASSERT(src1 != TMP_REG2);
-
- if (is_masked) {
- FAIL_IF(push_inst(compiler, AND | RD(TMP_REG2) | RN(src2) | SRC2_IMM | 0x1f));
- src2 = TMP_REG2;
- }
-
- return push_inst(compiler, MOV | (flags & SET_FLAGS) | RD(dst)
- | RM8(src2) | (sljit_uw)(shift_type << 5) | 0x10 | RM(src1));
-}
-
-#undef EMIT_SHIFT_INS_AND_RETURN
-
-/* Tests whether the immediate can be stored in the 12 bit imm field.
- Returns with 0 if not possible. */
-static sljit_uw get_imm(sljit_uw imm)
-{
- sljit_u32 rol;
-
- if (imm <= 0xff)
- return SRC2_IMM | imm;
-
- if (!(imm & 0xff000000)) {
- imm <<= 8;
- rol = 8;
- }
- else {
- imm = (imm << 24) | (imm >> 8);
- rol = 0;
- }
-
- if (!(imm & 0xff000000)) {
- imm <<= 8;
- rol += 4;
- }
-
- if (!(imm & 0xf0000000)) {
- imm <<= 4;
- rol += 2;
- }
-
- if (!(imm & 0xc0000000)) {
- imm <<= 2;
- rol += 1;
- }
-
- if (!(imm & 0x00ffffff))
- return SRC2_IMM | (imm >> 24) | (rol << 8);
- else
- return 0;
-}
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
-static sljit_s32 generate_int(struct sljit_compiler *compiler, sljit_s32 reg, sljit_uw imm, sljit_s32 positive)
-{
- sljit_uw mask;
- sljit_uw imm1;
- sljit_uw imm2;
- sljit_uw rol;
-
- /* Step1: Search a zero byte (8 continous zero bit). */
- mask = 0xff000000;
- rol = 8;
- while(1) {
- if (!(imm & mask)) {
- /* Rol imm by rol. */
- imm = (imm << rol) | (imm >> (32 - rol));
- /* Calculate arm rol. */
- rol = 4 + (rol >> 1);
- break;
- }
- rol += 2;
- mask >>= 2;
- if (mask & 0x3) {
- /* rol by 8. */
- imm = (imm << 8) | (imm >> 24);
- mask = 0xff00;
- rol = 24;
- while (1) {
- if (!(imm & mask)) {
- /* Rol imm by rol. */
- imm = (imm << rol) | (imm >> (32 - rol));
- /* Calculate arm rol. */
- rol = (rol >> 1) - 8;
- break;
- }
- rol += 2;
- mask >>= 2;
- if (mask & 0x3)
- return 0;
- }
- break;
- }
- }
-
- /* The low 8 bit must be zero. */
- SLJIT_ASSERT(!(imm & 0xff));
-
- if (!(imm & 0xff000000)) {
- imm1 = SRC2_IMM | ((imm >> 16) & 0xff) | (((rol + 4) & 0xf) << 8);
- imm2 = SRC2_IMM | ((imm >> 8) & 0xff) | (((rol + 8) & 0xf) << 8);
- }
- else if (imm & 0xc0000000) {
- imm1 = SRC2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8);
- imm <<= 8;
- rol += 4;
-
- if (!(imm & 0xff000000)) {
- imm <<= 8;
- rol += 4;
- }
-
- if (!(imm & 0xf0000000)) {
- imm <<= 4;
- rol += 2;
- }
-
- if (!(imm & 0xc0000000)) {
- imm <<= 2;
- rol += 1;
- }
-
- if (!(imm & 0x00ffffff))
- imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8);
- else
- return 0;
- }
- else {
- if (!(imm & 0xf0000000)) {
- imm <<= 4;
- rol += 2;
- }
-
- if (!(imm & 0xc0000000)) {
- imm <<= 2;
- rol += 1;
- }
-
- imm1 = SRC2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8);
- imm <<= 8;
- rol += 4;
-
- if (!(imm & 0xf0000000)) {
- imm <<= 4;
- rol += 2;
- }
-
- if (!(imm & 0xc0000000)) {
- imm <<= 2;
- rol += 1;
- }
-
- if (!(imm & 0x00ffffff))
- imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8);
- else
- return 0;
- }
-
- FAIL_IF(push_inst(compiler, (positive ? MOV : MVN) | RD(reg) | imm1));
- FAIL_IF(push_inst(compiler, (positive ? ORR : BIC) | RD(reg) | RN(reg) | imm2));
- return 1;
-}
-#endif
-
-static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_uw imm)
-{
- sljit_uw tmp;
-
-#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
- if (!(imm & ~(sljit_uw)0xffff))
- return push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff));
-#endif
-
- /* Create imm by 1 inst. */
- tmp = get_imm(imm);
- if (tmp)
- return push_inst(compiler, MOV | RD(reg) | tmp);
-
- tmp = get_imm(~imm);
- if (tmp)
- return push_inst(compiler, MVN | RD(reg) | tmp);
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- /* Create imm by 2 inst. */
- FAIL_IF(generate_int(compiler, reg, imm, 1));
- FAIL_IF(generate_int(compiler, reg, ~imm, 0));
-
- /* Load integer. */
- return push_inst_with_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, reg, TMP_PC, 0), imm);
-#else
- FAIL_IF(push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff)));
- if (imm <= 0xffff)
- return SLJIT_SUCCESS;
- return push_inst(compiler, MOVT | RD(reg) | ((imm >> 12) & 0xf0000) | ((imm >> 16) & 0xfff));
-#endif
-}
-
-static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg,
- sljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg)
-{
- sljit_uw imm, offset_reg, tmp;
- sljit_sw mask = IS_TYPE1_TRANSFER(flags) ? 0xfff : 0xff;
- sljit_sw sign = IS_TYPE1_TRANSFER(flags) ? 0x1000 : 0x100;
-
- SLJIT_ASSERT(arg & SLJIT_MEM);
- SLJIT_ASSERT((arg & REG_MASK) != tmp_reg || (arg == SLJIT_MEM1(tmp_reg) && argw >= -mask && argw <= mask));
-
- if (SLJIT_UNLIKELY(!(arg & REG_MASK))) {
- tmp = (sljit_uw)(argw & (sign | mask));
- tmp = (sljit_uw)((argw + (tmp <= (sljit_uw)sign ? 0 : sign)) & ~mask);
-
- FAIL_IF(load_immediate(compiler, tmp_reg, tmp));
-
- argw -= (sljit_sw)tmp;
- tmp = 1;
-
- if (argw < 0) {
- argw = -argw;
- tmp = 0;
- }
-
- return push_inst(compiler, EMIT_DATA_TRANSFER(flags, tmp, reg, tmp_reg,
- (mask == 0xff) ? TYPE2_TRANSFER_IMM(argw) : argw));
- }
-
- if (arg & OFFS_REG_MASK) {
- offset_reg = OFFS_REG(arg);
- arg &= REG_MASK;
- argw &= 0x3;
-
- if (argw != 0 && (mask == 0xff)) {
- FAIL_IF(push_inst(compiler, ADD | RD(tmp_reg) | RN(arg) | RM(offset_reg) | ((sljit_uw)argw << 7)));
- return push_inst(compiler, EMIT_DATA_TRANSFER(flags, 1, reg, tmp_reg, TYPE2_TRANSFER_IMM(0)));
- }
-
- /* Bit 25: RM is offset. */
- return push_inst(compiler, EMIT_DATA_TRANSFER(flags, 1, reg, arg,
- RM(offset_reg) | (mask == 0xff ? 0 : (1 << 25)) | ((sljit_uw)argw << 7)));
- }
-
- arg &= REG_MASK;
-
- if (argw > mask) {
- tmp = (sljit_uw)(argw & (sign | mask));
- tmp = (sljit_uw)((argw + (tmp <= (sljit_uw)sign ? 0 : sign)) & ~mask);
- imm = get_imm(tmp);
-
- if (imm) {
- FAIL_IF(push_inst(compiler, ADD | RD(tmp_reg) | RN(arg) | imm));
- argw -= (sljit_sw)tmp;
- arg = tmp_reg;
-
- SLJIT_ASSERT(argw >= -mask && argw <= mask);
- }
- } else if (argw < -mask) {
- tmp = (sljit_uw)(-argw & (sign | mask));
- tmp = (sljit_uw)((-argw + (tmp <= (sljit_uw)sign ? 0 : sign)) & ~mask);
- imm = get_imm(tmp);
-
- if (imm) {
- FAIL_IF(push_inst(compiler, SUB | RD(tmp_reg) | RN(arg) | imm));
- argw += (sljit_sw)tmp;
- arg = tmp_reg;
-
- SLJIT_ASSERT(argw >= -mask && argw <= mask);
- }
- }
-
- if (argw <= mask && argw >= -mask) {
- if (argw >= 0) {
- if (mask == 0xff)
- argw = TYPE2_TRANSFER_IMM(argw);
- return push_inst(compiler, EMIT_DATA_TRANSFER(flags, 1, reg, arg, argw));
- }
-
- argw = -argw;
-
- if (mask == 0xff)
- argw = TYPE2_TRANSFER_IMM(argw);
-
- return push_inst(compiler, EMIT_DATA_TRANSFER(flags, 0, reg, arg, argw));
- }
-
- FAIL_IF(load_immediate(compiler, tmp_reg, (sljit_uw)argw));
- return push_inst(compiler, EMIT_DATA_TRANSFER(flags, 1, reg, arg,
- RM(tmp_reg) | (mask == 0xff ? 0 : (1 << 25))));
-}
-
-static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 inp_flags,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- /* src1 is reg or TMP_REG1
- src2 is reg, TMP_REG2, or imm
- result goes to TMP_REG2, so put result can use TMP_REG1. */
-
- /* We prefers register and simple consts. */
- sljit_s32 dst_reg;
- sljit_s32 src1_reg;
- sljit_s32 src2_reg = 0;
- sljit_s32 flags = HAS_FLAGS(op) ? SET_FLAGS : 0;
- sljit_s32 neg_op = 0;
-
- if (dst == TMP_REG2)
- flags |= UNUSED_RETURN;
-
- SLJIT_ASSERT(!(inp_flags & ALLOW_INV_IMM) || (inp_flags & ALLOW_IMM));
-
- if (inp_flags & ALLOW_NEG_IMM) {
- switch (GET_OPCODE(op)) {
- case SLJIT_ADD:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;
- neg_op = SLJIT_SUB;
- break;
- case SLJIT_ADDC:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;
- neg_op = SLJIT_SUBC;
- break;
- case SLJIT_SUB:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;
- neg_op = SLJIT_ADD;
- break;
- case SLJIT_SUBC:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;
- neg_op = SLJIT_ADDC;
- break;
- }
- }
-
- do {
- if (!(inp_flags & ALLOW_IMM))
- break;
-
- if (src2 & SLJIT_IMM) {
- src2_reg = (sljit_s32)get_imm((sljit_uw)src2w);
- if (src2_reg)
- break;
- if (inp_flags & ALLOW_INV_IMM) {
- src2_reg = (sljit_s32)get_imm(~(sljit_uw)src2w);
- if (src2_reg) {
- flags |= INV_IMM;
- break;
- }
- }
- if (neg_op != 0) {
- src2_reg = (sljit_s32)get_imm((sljit_uw)-src2w);
- if (src2_reg) {
- op = neg_op | GET_ALL_FLAGS(op);
- break;
- }
- }
- }
-
- if (src1 & SLJIT_IMM) {
- src2_reg = (sljit_s32)get_imm((sljit_uw)src1w);
- if (src2_reg) {
- flags |= ARGS_SWAPPED;
- src1 = src2;
- src1w = src2w;
- break;
- }
- if (inp_flags & ALLOW_INV_IMM) {
- src2_reg = (sljit_s32)get_imm(~(sljit_uw)src1w);
- if (src2_reg) {
- flags |= ARGS_SWAPPED | INV_IMM;
- src1 = src2;
- src1w = src2w;
- break;
- }
- }
- if (neg_op >= SLJIT_SUB) {
- /* Note: additive operation (commutative). */
- src2_reg = (sljit_s32)get_imm((sljit_uw)-src1w);
- if (src2_reg) {
- src1 = src2;
- src1w = src2w;
- op = neg_op | GET_ALL_FLAGS(op);
- break;
- }
- }
- }
- } while(0);
-
- /* Source 1. */
- if (FAST_IS_REG(src1))
- src1_reg = src1;
- else if (src1 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, TMP_REG1));
- src1_reg = TMP_REG1;
- }
- else {
- FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w));
- src1_reg = TMP_REG1;
- }
-
- /* Destination. */
- dst_reg = FAST_IS_REG(dst) ? dst : TMP_REG2;
-
- if (op <= SLJIT_MOV_P) {
- if (dst & SLJIT_MEM) {
- if (inp_flags & BYTE_SIZE)
- inp_flags &= ~SIGNED;
-
- if (FAST_IS_REG(src2))
- return emit_op_mem(compiler, inp_flags, src2, dst, dstw, TMP_REG2);
- }
-
- if (FAST_IS_REG(src2) && dst_reg != TMP_REG2)
- flags |= MOVE_REG_CONV;
- }
-
- /* Source 2. */
- if (src2_reg == 0) {
- src2_reg = (op <= SLJIT_MOV_P) ? dst_reg : TMP_REG2;
-
- if (FAST_IS_REG(src2))
- src2_reg = src2;
- else if (src2 & SLJIT_MEM)
- FAIL_IF(emit_op_mem(compiler, inp_flags | LOAD_DATA, src2_reg, src2, src2w, TMP_REG2));
- else
- FAIL_IF(load_immediate(compiler, src2_reg, (sljit_uw)src2w));
- }
-
- FAIL_IF(emit_single_op(compiler, op, flags, (sljit_uw)dst_reg, (sljit_uw)src1_reg, (sljit_uw)src2_reg));
-
- if (!(dst & SLJIT_MEM))
- return SLJIT_SUCCESS;
-
- return emit_op_mem(compiler, inp_flags, dst_reg, dst, dstw, TMP_REG1);
-}
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined(__GNUC__)
-extern unsigned int __aeabi_uidivmod(unsigned int numerator, unsigned int denominator);
-extern int __aeabi_idivmod(int numerator, int denominator);
-#else
-#error "Software divmod functions are needed"
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
-{
- sljit_uw saved_reg_list[3];
- sljit_sw saved_reg_count;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op0(compiler, op));
-
- op = GET_OPCODE(op);
- switch (op) {
- case SLJIT_BREAKPOINT:
- FAIL_IF(push_inst(compiler, BKPT));
- break;
- case SLJIT_NOP:
- FAIL_IF(push_inst(compiler, NOP));
- break;
- case SLJIT_LMUL_UW:
- case SLJIT_LMUL_SW:
- return push_inst(compiler, (op == SLJIT_LMUL_UW ? UMULL : SMULL)
- | RN(SLJIT_R1) | RD(SLJIT_R0) | RM8(SLJIT_R0) | RM(SLJIT_R1));
- case SLJIT_DIVMOD_UW:
- case SLJIT_DIVMOD_SW:
- case SLJIT_DIV_UW:
- case SLJIT_DIV_SW:
- SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
- SLJIT_ASSERT(reg_map[2] == 1 && reg_map[3] == 2 && reg_map[4] == 3);
-
- saved_reg_count = 0;
- if (compiler->scratches >= 4)
- saved_reg_list[saved_reg_count++] = 3;
- if (compiler->scratches >= 3)
- saved_reg_list[saved_reg_count++] = 2;
- if (op >= SLJIT_DIV_UW)
- saved_reg_list[saved_reg_count++] = 1;
-
- if (saved_reg_count > 0) {
- FAIL_IF(push_inst(compiler, STR | 0x2d0000 | (saved_reg_count >= 3 ? 16 : 8)
- | (saved_reg_list[0] << 12) /* str rX, [sp, #-8/-16]! */));
- if (saved_reg_count >= 2) {
- SLJIT_ASSERT(saved_reg_list[1] < 8);
- FAIL_IF(push_inst(compiler, STR | 0x8d0004 | (saved_reg_list[1] << 12) /* str rX, [sp, #4] */));
- }
- if (saved_reg_count >= 3) {
- SLJIT_ASSERT(saved_reg_list[2] < 8);
- FAIL_IF(push_inst(compiler, STR | 0x8d0008 | (saved_reg_list[2] << 12) /* str rX, [sp, #8] */));
- }
- }
-
-#if defined(__GNUC__)
- FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,
- ((op | 0x2) == SLJIT_DIV_UW ? SLJIT_FUNC_ADDR(__aeabi_uidivmod) : SLJIT_FUNC_ADDR(__aeabi_idivmod))));
-#else
-#error "Software divmod functions are needed"
-#endif
-
- if (saved_reg_count > 0) {
- if (saved_reg_count >= 3) {
- SLJIT_ASSERT(saved_reg_list[2] < 8);
- FAIL_IF(push_inst(compiler, LDR | 0x8d0008 | (saved_reg_list[2] << 12) /* ldr rX, [sp, #8] */));
- }
- if (saved_reg_count >= 2) {
- SLJIT_ASSERT(saved_reg_list[1] < 8);
- FAIL_IF(push_inst(compiler, LDR | 0x8d0004 | (saved_reg_list[1] << 12) /* ldr rX, [sp, #4] */));
- }
- return push_inst(compiler, (LDR ^ (1 << 24)) | 0x8d0000 | (sljit_uw)(saved_reg_count >= 3 ? 16 : 8)
- | (saved_reg_list[0] << 12) /* ldr rX, [sp], #8/16 */);
- }
- return SLJIT_SUCCESS;
- case SLJIT_ENDBR:
- case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
- return SLJIT_SUCCESS;
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- switch (GET_OPCODE(op)) {
- case SLJIT_MOV:
- case SLJIT_MOV_U32:
- case SLJIT_MOV_S32:
- case SLJIT_MOV32:
- case SLJIT_MOV_P:
- return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw);
-
- case SLJIT_MOV_U8:
- return emit_op(compiler, SLJIT_MOV_U8, ALLOW_ANY_IMM | BYTE_SIZE, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
-
- case SLJIT_MOV_S8:
- return emit_op(compiler, SLJIT_MOV_S8, ALLOW_ANY_IMM | SIGNED | BYTE_SIZE, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
-
- case SLJIT_MOV_U16:
- return emit_op(compiler, SLJIT_MOV_U16, ALLOW_ANY_IMM | HALF_SIZE, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
-
- case SLJIT_MOV_S16:
- return emit_op(compiler, SLJIT_MOV_S16, ALLOW_ANY_IMM | SIGNED | HALF_SIZE, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
-
- case SLJIT_NOT:
- return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw);
-
- case SLJIT_CLZ:
- case SLJIT_CTZ:
- return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw);
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- switch (GET_OPCODE(op)) {
- case SLJIT_ADD:
- case SLJIT_ADDC:
- case SLJIT_SUB:
- case SLJIT_SUBC:
- return emit_op(compiler, op, ALLOW_IMM | ALLOW_NEG_IMM, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_OR:
- case SLJIT_XOR:
- return emit_op(compiler, op, ALLOW_IMM, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_MUL:
- return emit_op(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_AND:
- return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_SHL:
- case SLJIT_MSHL:
- case SLJIT_LSHR:
- case SLJIT_MLSHR:
- case SLJIT_ASHR:
- case SLJIT_MASHR:
- case SLJIT_ROTL:
- case SLJIT_ROTR:
- if (src2 & SLJIT_IMM) {
- compiler->shift_imm = src2w & 0x1f;
- return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src1, src1w);
- } else {
- compiler->shift_imm = 0x20;
- return emit_op(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w);
- }
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_op2(compiler, op, TMP_REG2, 0, src1, src1w, src2, src2w);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src_dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 is_left;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w));
-
- op = GET_OPCODE(op);
- is_left = (op == SLJIT_SHL || op == SLJIT_MSHL);
-
- if (src_dst == src1) {
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_op2(compiler, is_left ? SLJIT_ROTL : SLJIT_ROTR, src_dst, 0, src_dst, 0, src2, src2w);
- }
-
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- /* Shift type of ROR is 3. */
- if (src2 & SLJIT_IMM) {
- src2w &= 0x1f;
-
- if (src2w == 0)
- return SLJIT_SUCCESS;
- } else if (src2 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, src2, src2w, TMP_REG2));
- src2 = TMP_REG2;
- }
-
- if (src1 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG1, src1, src1w, TMP_REG1));
- src1 = TMP_REG1;
- } else if (src1 & SLJIT_IMM) {
- FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w));
- src1 = TMP_REG1;
- }
-
- if (src2 & SLJIT_IMM) {
- FAIL_IF(push_inst(compiler, MOV | RD(src_dst) | RM(src_dst) | ((sljit_uw)(is_left ? 0 : 1) << 5) | ((sljit_uw)src2w << 7)));
- src2w = (src2w ^ 0x1f) + 1;
- return push_inst(compiler, ORR | RD(src_dst) | RN(src_dst) | RM(src1) | ((sljit_uw)(is_left ? 1 : 0) << 5) | ((sljit_uw)src2w << 7));
- }
-
- if (op == SLJIT_MSHL || op == SLJIT_MLSHR) {
- FAIL_IF(push_inst(compiler, AND | SRC2_IMM | RD(TMP_REG2) | RN(src2) | 0x1f));
- src2 = TMP_REG2;
- }
-
- FAIL_IF(push_inst(compiler, MOV | RD(src_dst) | RM8(src2) | ((sljit_uw)(is_left ? 0 : 1) << 5) | 0x10 | RM(src_dst)));
- FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | RM(src1) | ((sljit_uw)(is_left ? 1 : 0) << 5) | (1 << 7)));
- FAIL_IF(push_inst(compiler, EOR | SRC2_IMM | RD(TMP_REG2) | RN(src2) | 0x1f));
- return push_inst(compiler, ORR | RD(src_dst) | RN(src_dst) | RM(TMP_REG1) | ((sljit_uw)(is_left ? 1 : 0) << 5) | 0x10 | RM8(TMP_REG2));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- switch (op) {
- case SLJIT_FAST_RETURN:
- SLJIT_ASSERT(reg_map[TMP_REG2] == 14);
-
- if (FAST_IS_REG(src))
- FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(src)));
- else
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, src, srcw, TMP_REG1));
-
- return push_inst(compiler, BX | RM(TMP_REG2));
- case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
- return SLJIT_SUCCESS;
- case SLJIT_PREFETCH_L1:
- case SLJIT_PREFETCH_L2:
- case SLJIT_PREFETCH_L3:
- case SLJIT_PREFETCH_ONCE:
-#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
- SLJIT_ASSERT(src & SLJIT_MEM);
- return emit_op_mem(compiler, PRELOAD | LOAD_DATA, TMP_PC, src, srcw, TMP_REG1);
-#else /* !SLJIT_CONFIG_ARM_V7 */
- return SLJIT_SUCCESS;
-#endif /* SLJIT_CONFIG_ARM_V7 */
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
-{
- CHECK_REG_INDEX(check_sljit_get_register_index(reg));
- return reg_map[reg];
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
-{
- CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
- return (freg_map[reg] << 1);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
- void *instruction, sljit_u32 size)
-{
- SLJIT_UNUSED_ARG(size);
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
-
- return push_inst(compiler, *(sljit_uw*)instruction);
-}
-
-/* --------------------------------------------------------------------- */
-/* Floating point operators */
-/* --------------------------------------------------------------------- */
-
-#define FPU_LOAD (1 << 20)
-#define EMIT_FPU_DATA_TRANSFER(inst, add, base, freg, offs) \
- ((inst) | (sljit_uw)((add) << 23) | RN(base) | VD(freg) | (sljit_uw)(offs))
-
-static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
-{
- sljit_uw imm;
- sljit_uw inst = VSTR_F32 | (flags & (SLJIT_32 | FPU_LOAD));
-
- SLJIT_ASSERT(arg & SLJIT_MEM);
- arg &= ~SLJIT_MEM;
-
- if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
- FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG2) | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (((sljit_uw)argw & 0x3) << 7)));
- arg = TMP_REG2;
- argw = 0;
- }
-
- /* Fast loads and stores. */
- if (arg) {
- if (!(argw & ~0x3fc))
- return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, arg & REG_MASK, reg, argw >> 2));
- if (!(-argw & ~0x3fc))
- return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, arg & REG_MASK, reg, (-argw) >> 2));
-
- imm = get_imm((sljit_uw)argw & ~(sljit_uw)0x3fc);
- if (imm) {
- FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG2) | RN(arg & REG_MASK) | imm));
- return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG2, reg, (argw & 0x3fc) >> 2));
- }
- imm = get_imm((sljit_uw)-argw & ~(sljit_uw)0x3fc);
- if (imm) {
- argw = -argw;
- FAIL_IF(push_inst(compiler, SUB | RD(TMP_REG2) | RN(arg & REG_MASK) | imm));
- return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, TMP_REG2, reg, (argw & 0x3fc) >> 2));
- }
- }
-
- if (arg) {
- FAIL_IF(load_immediate(compiler, TMP_REG2, (sljit_uw)argw));
- FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG2) | RN(arg & REG_MASK) | RM(TMP_REG2)));
- }
- else
- FAIL_IF(load_immediate(compiler, TMP_REG2, (sljit_uw)argw));
-
- return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG2, reg, 0));
-}
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- op ^= SLJIT_32;
-
- if (src & SLJIT_MEM) {
- FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG1, src, srcw));
- src = TMP_FREG1;
- }
-
- FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_S32_F32, op & SLJIT_32, TMP_FREG1, src, 0)));
-
- if (FAST_IS_REG(dst))
- return push_inst(compiler, VMOV | (1 << 20) | RD(dst) | VN(TMP_FREG1));
-
- /* Store the integer value from a VFP register. */
- return emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw);
-}
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
-
- op ^= SLJIT_32;
-
- if (FAST_IS_REG(src))
- FAIL_IF(push_inst(compiler, VMOV | RD(src) | VN(TMP_FREG1)));
- else if (src & SLJIT_MEM) {
- /* Load the integer value into a VFP register. */
- FAIL_IF(emit_fop_mem(compiler, FPU_LOAD, TMP_FREG1, src, srcw));
- }
- else {
- FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcw));
- FAIL_IF(push_inst(compiler, VMOV | RD(TMP_REG1) | VN(TMP_FREG1)));
- }
-
- FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F32_S32, op & SLJIT_32, dst_r, TMP_FREG1, 0)));
-
- if (dst & SLJIT_MEM)
- return emit_fop_mem(compiler, (op & SLJIT_32), TMP_FREG1, dst, dstw);
- return SLJIT_SUCCESS;
-}
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- op ^= SLJIT_32;
-
- if (src1 & SLJIT_MEM) {
- FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG1, src1, src1w));
- src1 = TMP_FREG1;
- }
-
- if (src2 & SLJIT_MEM) {
- FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG2, src2, src2w));
- src2 = TMP_FREG2;
- }
-
- FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCMP_F32, op & SLJIT_32, src1, src2, 0)));
- return push_inst(compiler, VMRS);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 dst_r;
-
- CHECK_ERROR();
-
- SLJIT_COMPILE_ASSERT((SLJIT_32 == 0x100), float_transfer_bit_error);
- SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
-
- if (GET_OPCODE(op) != SLJIT_CONV_F64_FROM_F32)
- op ^= SLJIT_32;
-
- if (src & SLJIT_MEM) {
- FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, dst_r, src, srcw));
- src = dst_r;
- }
-
- switch (GET_OPCODE(op)) {
- case SLJIT_MOV_F64:
- if (src != dst_r) {
- if (dst_r != TMP_FREG1)
- FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32, op & SLJIT_32, dst_r, src, 0)));
- else
- dst_r = src;
- }
- break;
- case SLJIT_NEG_F64:
- FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VNEG_F32, op & SLJIT_32, dst_r, src, 0)));
- break;
- case SLJIT_ABS_F64:
- FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VABS_F32, op & SLJIT_32, dst_r, src, 0)));
- break;
- case SLJIT_CONV_F64_FROM_F32:
- FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F64_F32, op & SLJIT_32, dst_r, src, 0)));
- op ^= SLJIT_32;
- break;
- }
-
- if (dst & SLJIT_MEM)
- return emit_fop_mem(compiler, (op & SLJIT_32), dst_r, dst, dstw);
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 dst_r;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- op ^= SLJIT_32;
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
-
- if (src2 & SLJIT_MEM) {
- FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG2, src2, src2w));
- src2 = TMP_FREG2;
- }
-
- if (src1 & SLJIT_MEM) {
- FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG1, src1, src1w));
- src1 = TMP_FREG1;
- }
-
- switch (GET_OPCODE(op)) {
- case SLJIT_ADD_F64:
- FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VADD_F32, op & SLJIT_32, dst_r, src2, src1)));
- break;
-
- case SLJIT_SUB_F64:
- FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VSUB_F32, op & SLJIT_32, dst_r, src2, src1)));
- break;
-
- case SLJIT_MUL_F64:
- FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMUL_F32, op & SLJIT_32, dst_r, src2, src1)));
- break;
-
- case SLJIT_DIV_F64:
- FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VDIV_F32, op & SLJIT_32, dst_r, src2, src1)));
- break;
- }
-
- if (dst_r == TMP_FREG1)
- FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32), TMP_FREG1, dst, dstw));
-
- return SLJIT_SUCCESS;
-}
-
-#undef EMIT_FPU_DATA_TRANSFER
-
-/* --------------------------------------------------------------------- */
-/* Other instructions */
-/* --------------------------------------------------------------------- */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- SLJIT_ASSERT(reg_map[TMP_REG2] == 14);
-
- if (FAST_IS_REG(dst))
- return push_inst(compiler, MOV | RD(dst) | RM(TMP_REG2));
-
- /* Memory. */
- return emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1);
-}
-
-/* --------------------------------------------------------------------- */
-/* Conditional instructions */
-/* --------------------------------------------------------------------- */
-
-static sljit_uw get_cc(struct sljit_compiler *compiler, sljit_s32 type)
-{
- switch (type) {
- case SLJIT_EQUAL:
- case SLJIT_F_EQUAL:
- case SLJIT_ORDERED_EQUAL:
- case SLJIT_UNORDERED_OR_EQUAL: /* Not supported. */
- return 0x00000000;
-
- case SLJIT_NOT_EQUAL:
- case SLJIT_F_NOT_EQUAL:
- case SLJIT_UNORDERED_OR_NOT_EQUAL:
- case SLJIT_ORDERED_NOT_EQUAL: /* Not supported. */
- return 0x10000000;
-
- case SLJIT_CARRY:
- if (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_ADD)
- return 0x20000000;
- /* fallthrough */
-
- case SLJIT_LESS:
- return 0x30000000;
-
- case SLJIT_NOT_CARRY:
- if (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_ADD)
- return 0x30000000;
- /* fallthrough */
-
- case SLJIT_GREATER_EQUAL:
- return 0x20000000;
-
- case SLJIT_GREATER:
- case SLJIT_UNORDERED_OR_GREATER:
- return 0x80000000;
-
- case SLJIT_LESS_EQUAL:
- case SLJIT_F_LESS_EQUAL:
- case SLJIT_ORDERED_LESS_EQUAL:
- return 0x90000000;
-
- case SLJIT_SIG_LESS:
- case SLJIT_UNORDERED_OR_LESS:
- return 0xb0000000;
-
- case SLJIT_SIG_GREATER_EQUAL:
- case SLJIT_F_GREATER_EQUAL:
- case SLJIT_ORDERED_GREATER_EQUAL:
- return 0xa0000000;
-
- case SLJIT_SIG_GREATER:
- case SLJIT_F_GREATER:
- case SLJIT_ORDERED_GREATER:
- return 0xc0000000;
-
- case SLJIT_SIG_LESS_EQUAL:
- case SLJIT_UNORDERED_OR_LESS_EQUAL:
- return 0xd0000000;
-
- case SLJIT_OVERFLOW:
- if (!(compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)))
- return 0x10000000;
- /* fallthrough */
-
- case SLJIT_UNORDERED:
- return 0x60000000;
-
- case SLJIT_NOT_OVERFLOW:
- if (!(compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)))
- return 0x00000000;
- /* fallthrough */
-
- case SLJIT_ORDERED:
- return 0x70000000;
-
- case SLJIT_F_LESS:
- case SLJIT_ORDERED_LESS:
- return 0x40000000;
-
- case SLJIT_UNORDERED_OR_GREATER_EQUAL:
- return 0x50000000;
-
- default:
- SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL_REG_ARG);
- return 0xe0000000;
- }
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
-{
- struct sljit_label *label;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_label(compiler));
-
- if (compiler->last_label && compiler->last_label->size == compiler->size)
- return compiler->last_label;
-
- label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
- PTR_FAIL_IF(!label);
- set_label(label, compiler);
- return label;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
-{
- struct sljit_jump *jump;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_jump(compiler, type));
-
- jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
- PTR_FAIL_IF(!jump);
- set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
- type &= 0xff;
-
- SLJIT_ASSERT(reg_map[TMP_REG1] != 14);
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- if (type >= SLJIT_FAST_CALL)
- PTR_FAIL_IF(prepare_blx(compiler));
- PTR_FAIL_IF(push_inst_with_unique_literal(compiler, ((EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1,
- type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0)) & ~COND_MASK) | get_cc(compiler, type), 0));
-
- if (jump->flags & SLJIT_REWRITABLE_JUMP) {
- jump->addr = compiler->size;
- compiler->patches++;
- }
-
- if (type >= SLJIT_FAST_CALL) {
- jump->flags |= IS_BL;
- PTR_FAIL_IF(emit_blx(compiler));
- }
-
- if (!(jump->flags & SLJIT_REWRITABLE_JUMP))
- jump->addr = compiler->size;
-#else
- if (type >= SLJIT_FAST_CALL)
- jump->flags |= IS_BL;
- PTR_FAIL_IF(emit_imm(compiler, TMP_REG1, 0));
- PTR_FAIL_IF(push_inst(compiler, (((type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1)) & ~COND_MASK) | get_cc(compiler, type)));
- jump->addr = compiler->size;
-#endif
- return jump;
-}
-
-#ifdef __SOFTFP__
-
-static sljit_s32 softfloat_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src, sljit_u32 *extra_space)
-{
- sljit_u32 is_tail_call = *extra_space & SLJIT_CALL_RETURN;
- sljit_u32 offset = 0;
- sljit_u32 word_arg_offset = 0;
- sljit_u32 src_offset = 4 * sizeof(sljit_sw);
- sljit_u32 float_arg_count = 0;
- sljit_s32 types = 0;
- sljit_u8 offsets[4];
- sljit_u8 *offset_ptr = offsets;
-
- if (src && FAST_IS_REG(*src))
- src_offset = (sljit_uw)reg_map[*src] * sizeof(sljit_sw);
-
- arg_types >>= SLJIT_ARG_SHIFT;
-
- while (arg_types) {
- types = (types << SLJIT_ARG_SHIFT) | (arg_types & SLJIT_ARG_MASK);
-
- switch (arg_types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- if (offset & 0x7)
- offset += sizeof(sljit_sw);
- *offset_ptr++ = (sljit_u8)offset;
- offset += sizeof(sljit_f64);
- float_arg_count++;
- break;
- case SLJIT_ARG_TYPE_F32:
- *offset_ptr++ = (sljit_u8)offset;
- offset += sizeof(sljit_f32);
- float_arg_count++;
- break;
- default:
- *offset_ptr++ = (sljit_u8)offset;
- offset += sizeof(sljit_sw);
- word_arg_offset += sizeof(sljit_sw);
- break;
- }
-
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- if (offset > 4 * sizeof(sljit_sw) && (!is_tail_call || offset > compiler->args_size)) {
- /* Keep lr register on the stack. */
- if (is_tail_call)
- offset += sizeof(sljit_sw);
-
- offset = ((offset - 4 * sizeof(sljit_sw)) + 0x7) & ~(sljit_uw)0x7;
-
- *extra_space = offset;
-
- if (is_tail_call)
- FAIL_IF(emit_stack_frame_release(compiler, (sljit_s32)offset));
- else
- FAIL_IF(push_inst(compiler, SUB | RD(SLJIT_SP) | RN(SLJIT_SP) | SRC2_IMM | offset));
- } else {
- if (is_tail_call)
- FAIL_IF(emit_stack_frame_release(compiler, -1));
- *extra_space = 0;
- }
-
- /* Process arguments in reversed direction. */
- while (types) {
- switch (types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- float_arg_count--;
- offset = *(--offset_ptr);
-
- SLJIT_ASSERT((offset & 0x7) == 0);
-
- if (offset < 4 * sizeof(sljit_sw)) {
- if (src_offset == offset || src_offset == offset + sizeof(sljit_sw)) {
- FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | (src_offset >> 2)));
- *src = TMP_REG1;
- }
- FAIL_IF(push_inst(compiler, VMOV2 | 0x100000 | (offset << 10) | ((offset + sizeof(sljit_sw)) << 14) | float_arg_count));
- } else
- FAIL_IF(push_inst(compiler, VSTR_F32 | 0x800100 | RN(SLJIT_SP)
- | (float_arg_count << 12) | ((offset - 4 * sizeof(sljit_sw)) >> 2)));
- break;
- case SLJIT_ARG_TYPE_F32:
- float_arg_count--;
- offset = *(--offset_ptr);
-
- if (offset < 4 * sizeof(sljit_sw)) {
- if (src_offset == offset) {
- FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | (src_offset >> 2)));
- *src = TMP_REG1;
- }
- FAIL_IF(push_inst(compiler, VMOV | 0x100000 | (float_arg_count << 16) | (offset << 10)));
- } else
- FAIL_IF(push_inst(compiler, VSTR_F32 | 0x800000 | RN(SLJIT_SP)
- | (float_arg_count << 12) | ((offset - 4 * sizeof(sljit_sw)) >> 2)));
- break;
- default:
- word_arg_offset -= sizeof(sljit_sw);
- offset = *(--offset_ptr);
-
- SLJIT_ASSERT(offset >= word_arg_offset);
-
- if (offset != word_arg_offset) {
- if (offset < 4 * sizeof(sljit_sw)) {
- if (src_offset == offset) {
- FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | (src_offset >> 2)));
- *src = TMP_REG1;
- }
- else if (src_offset == word_arg_offset) {
- *src = (sljit_s32)(SLJIT_R0 + (offset >> 2));
- src_offset = offset;
- }
- FAIL_IF(push_inst(compiler, MOV | (offset << 10) | (word_arg_offset >> 2)));
- } else
- FAIL_IF(push_inst(compiler, STR | 0x800000 | RN(SLJIT_SP) | (word_arg_offset << 10) | (offset - 4 * sizeof(sljit_sw))));
- }
- break;
- }
-
- types >>= SLJIT_ARG_SHIFT;
- }
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 softfloat_post_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types)
-{
- if ((arg_types & SLJIT_ARG_MASK) == SLJIT_ARG_TYPE_F64)
- FAIL_IF(push_inst(compiler, VMOV2 | (1 << 16) | (0 << 12) | 0));
- if ((arg_types & SLJIT_ARG_MASK) == SLJIT_ARG_TYPE_F32)
- FAIL_IF(push_inst(compiler, VMOV | (0 << 16) | (0 << 12)));
-
- return SLJIT_SUCCESS;
-}
-
-#else /* !__SOFTFP__ */
-
-static sljit_s32 hardfloat_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types)
-{
- sljit_u32 offset = SLJIT_FR0;
- sljit_u32 new_offset = SLJIT_FR0;
- sljit_u32 f32_offset = 0;
-
- /* Remove return value. */
- arg_types >>= SLJIT_ARG_SHIFT;
-
- while (arg_types) {
- switch (arg_types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- if (offset != new_offset)
- FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32,
- SLJIT_32, new_offset, offset, 0)));
-
- new_offset++;
- offset++;
- break;
- case SLJIT_ARG_TYPE_F32:
- if (f32_offset != 0) {
- FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32,
- 0x400000, f32_offset, offset, 0)));
- f32_offset = 0;
- } else {
- if (offset != new_offset)
- FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32,
- 0, new_offset, offset, 0)));
- f32_offset = new_offset;
- new_offset++;
- }
- offset++;
- break;
- }
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- return SLJIT_SUCCESS;
-}
-
-#endif /* __SOFTFP__ */
-
-#undef EMIT_FPU_OPERATION
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types)
-{
-#ifdef __SOFTFP__
- struct sljit_jump *jump;
- sljit_u32 extra_space = (sljit_u32)type;
-#endif
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
-
-#ifdef __SOFTFP__
- if ((type & 0xff) != SLJIT_CALL_REG_ARG) {
- PTR_FAIL_IF(softfloat_call_with_args(compiler, arg_types, NULL, &extra_space));
- SLJIT_ASSERT((extra_space & 0x7) == 0);
-
- if ((type & SLJIT_CALL_RETURN) && extra_space == 0)
- type = SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP);
-
- SLJIT_SKIP_CHECKS(compiler);
- jump = sljit_emit_jump(compiler, type);
- PTR_FAIL_IF(jump == NULL);
-
- if (extra_space > 0) {
- if (type & SLJIT_CALL_RETURN)
- PTR_FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1,
- TMP_REG2, SLJIT_SP, extra_space - sizeof(sljit_sw))));
-
- PTR_FAIL_IF(push_inst(compiler, ADD | RD(SLJIT_SP) | RN(SLJIT_SP) | SRC2_IMM | extra_space));
-
- if (type & SLJIT_CALL_RETURN) {
- PTR_FAIL_IF(push_inst(compiler, BX | RM(TMP_REG2)));
- return jump;
- }
- }
-
- SLJIT_ASSERT(!(type & SLJIT_CALL_RETURN));
- PTR_FAIL_IF(softfloat_post_call_with_args(compiler, arg_types));
- return jump;
- }
-#endif /* __SOFTFP__ */
-
- if (type & SLJIT_CALL_RETURN) {
- PTR_FAIL_IF(emit_stack_frame_release(compiler, -1));
- type = SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP);
- }
-
-#ifndef __SOFTFP__
- if ((type & 0xff) != SLJIT_CALL_REG_ARG)
- PTR_FAIL_IF(hardfloat_call_with_args(compiler, arg_types));
-#endif /* !__SOFTFP__ */
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_jump(compiler, type);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
-{
- struct sljit_jump *jump;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- SLJIT_ASSERT(reg_map[TMP_REG1] != 14);
-
- if (!(src & SLJIT_IMM)) {
- if (FAST_IS_REG(src)) {
- SLJIT_ASSERT(reg_map[src] != 14);
- return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(src));
- }
-
- SLJIT_ASSERT(src & SLJIT_MEM);
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
- return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1));
- }
-
- /* These jumps are converted to jump/call instructions when possible. */
- jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
- FAIL_IF(!jump);
- set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0));
- jump->u.target = (sljit_uw)srcw;
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- if (type >= SLJIT_FAST_CALL)
- FAIL_IF(prepare_blx(compiler));
- FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0), 0));
- if (type >= SLJIT_FAST_CALL)
- FAIL_IF(emit_blx(compiler));
-#else
- FAIL_IF(emit_imm(compiler, TMP_REG1, 0));
- FAIL_IF(push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1)));
-#endif
- jump->addr = compiler->size;
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types,
- sljit_s32 src, sljit_sw srcw)
-{
-#ifdef __SOFTFP__
- sljit_u32 extra_space = (sljit_u32)type;
-#endif
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
-
- if (src & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
- src = TMP_REG1;
- }
-
- if ((type & SLJIT_CALL_RETURN) && (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options)))) {
- FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | RM(src)));
- src = TMP_REG1;
- }
-
-#ifdef __SOFTFP__
- if ((type & 0xff) != SLJIT_CALL_REG_ARG) {
- FAIL_IF(softfloat_call_with_args(compiler, arg_types, &src, &extra_space));
- SLJIT_ASSERT((extra_space & 0x7) == 0);
-
- if ((type & SLJIT_CALL_RETURN) && extra_space == 0)
- type = SLJIT_JUMP;
-
- SLJIT_SKIP_CHECKS(compiler);
- FAIL_IF(sljit_emit_ijump(compiler, type, src, srcw));
-
- if (extra_space > 0) {
- if (type & SLJIT_CALL_RETURN)
- FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1,
- TMP_REG2, SLJIT_SP, extra_space - sizeof(sljit_sw))));
-
- FAIL_IF(push_inst(compiler, ADD | RD(SLJIT_SP) | RN(SLJIT_SP) | SRC2_IMM | extra_space));
-
- if (type & SLJIT_CALL_RETURN)
- return push_inst(compiler, BX | RM(TMP_REG2));
- }
-
- SLJIT_ASSERT(!(type & SLJIT_CALL_RETURN));
- return softfloat_post_call_with_args(compiler, arg_types);
- }
-#endif /* __SOFTFP__ */
-
- if (type & SLJIT_CALL_RETURN) {
- FAIL_IF(emit_stack_frame_release(compiler, -1));
- type = SLJIT_JUMP;
- }
-
-#ifndef __SOFTFP__
- if ((type & 0xff) != SLJIT_CALL_REG_ARG)
- FAIL_IF(hardfloat_call_with_args(compiler, arg_types));
-#endif /* !__SOFTFP__ */
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_ijump(compiler, type, src, srcw);
-}
-
-#ifdef __SOFTFP__
-
-static SLJIT_INLINE sljit_s32 emit_fmov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
-{
- if (compiler->options & SLJIT_ENTER_REG_ARG) {
- if (src == SLJIT_FR0)
- return SLJIT_SUCCESS;
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_fop1(compiler, op, SLJIT_RETURN_FREG, 0, src, srcw);
- }
-
- if (FAST_IS_REG(src)) {
- if (op & SLJIT_32)
- return push_inst(compiler, VMOV | (1 << 20) | RD(SLJIT_R0) | VN(src));
- return push_inst(compiler, VMOV2 | (1 << 20) | RD(SLJIT_R0) | RN(SLJIT_R1) | VM(src));
- }
-
- SLJIT_SKIP_CHECKS(compiler);
-
- if (op & SLJIT_32)
- return sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R0, 0, src, srcw);
- return sljit_emit_mem(compiler, SLJIT_MOV, SLJIT_REG_PAIR(SLJIT_R0, SLJIT_R1), src, srcw);
-}
-
-#endif /* __SOFTFP__ */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 type)
-{
- sljit_s32 dst_reg, flags = GET_ALL_FLAGS(op);
- sljit_uw cc, ins;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- op = GET_OPCODE(op);
- cc = get_cc(compiler, type);
- dst_reg = FAST_IS_REG(dst) ? dst : TMP_REG1;
-
- if (op < SLJIT_ADD) {
- FAIL_IF(push_inst(compiler, MOV | RD(dst_reg) | SRC2_IMM | 0));
- FAIL_IF(push_inst(compiler, ((MOV | RD(dst_reg) | SRC2_IMM | 1) & ~COND_MASK) | cc));
- if (dst & SLJIT_MEM)
- return emit_op_mem(compiler, WORD_SIZE, TMP_REG1, dst, dstw, TMP_REG2);
- return SLJIT_SUCCESS;
- }
-
- ins = (op == SLJIT_AND ? AND : (op == SLJIT_OR ? ORR : EOR));
-
- if (dst & SLJIT_MEM)
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG1, dst, dstw, TMP_REG2));
-
- FAIL_IF(push_inst(compiler, ((ins | RD(dst_reg) | RN(dst_reg) | SRC2_IMM | 1) & ~COND_MASK) | cc));
-
- if (op == SLJIT_AND)
- FAIL_IF(push_inst(compiler, ((ins | RD(dst_reg) | RN(dst_reg) | SRC2_IMM | 0) & ~COND_MASK) | (cc ^ 0x10000000)));
-
- if (dst & SLJIT_MEM)
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, dst, dstw, TMP_REG2));
-
- if (flags & SLJIT_SET_Z)
- return push_inst(compiler, MOV | SET_FLAGS | RD(TMP_REG2) | RM(dst_reg));
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 dst_reg,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_uw cc, tmp;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
-
- cc = get_cc(compiler, type & ~SLJIT_32);
-
- if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
- tmp = get_imm((sljit_uw)srcw);
- if (tmp)
- return push_inst(compiler, ((MOV | RD(dst_reg) | tmp) & ~COND_MASK) | cc);
-
- tmp = get_imm(~(sljit_uw)srcw);
- if (tmp)
- return push_inst(compiler, ((MVN | RD(dst_reg) | tmp) & ~COND_MASK) | cc);
-
-#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
- tmp = (sljit_uw)srcw;
- FAIL_IF(push_inst(compiler, (MOVW & ~COND_MASK) | cc | RD(dst_reg) | ((tmp << 4) & 0xf0000) | (tmp & 0xfff)));
- if (tmp <= 0xffff)
- return SLJIT_SUCCESS;
- return push_inst(compiler, (MOVT & ~COND_MASK) | cc | RD(dst_reg) | ((tmp >> 12) & 0xf0000) | ((tmp >> 16) & 0xfff));
-#else
- FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcw));
- src = TMP_REG1;
-#endif
- }
-
- return push_inst(compiler, ((MOV | RD(dst_reg) | RM(src)) & ~COND_MASK) | cc);
-}
-
-static sljit_s32 update_mem_addr(struct sljit_compiler *compiler, sljit_s32 *mem, sljit_sw *memw, sljit_s32 max_offset)
-{
- sljit_s32 arg = *mem;
- sljit_sw argw = *memw;
- sljit_uw imm, tmp;
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- sljit_sw mask = max_offset >= 0xf00 ? 0xfff : 0xff;
- sljit_sw sign = max_offset >= 0xf00 ? 0x1000 : 0x100;
-#else /* !SLJIT_CONFIG_ARM_V5 */
- sljit_sw mask = 0xfff;
- sljit_sw sign = 0x1000;
-
- SLJIT_ASSERT(max_offset >= 0xf00);
-#endif /* SLJIT_CONFIG_ARM_V5 */
-
- *mem = TMP_REG1;
-
- if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
- *memw = 0;
- return push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | ((sljit_uw)(argw & 0x3) << 7));
- }
-
- arg &= REG_MASK;
-
- if (arg) {
- if (argw <= max_offset && argw >= -mask) {
- *mem = arg;
- return SLJIT_SUCCESS;
- }
-
- if (argw >= 0) {
- tmp = (sljit_uw)(argw & (sign | mask));
- tmp = (sljit_uw)((argw + ((tmp <= (sljit_uw)max_offset || tmp == (sljit_uw)sign) ? 0 : sign)) & ~mask);
- imm = get_imm(tmp);
-
- if (imm) {
- *memw = argw - (sljit_sw)tmp;
- SLJIT_ASSERT(*memw >= -mask && *memw <= max_offset);
-
- return push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg) | imm);
- }
- } else {
- tmp = (sljit_uw)(-argw & (sign | mask));
- tmp = (sljit_uw)((-argw + ((tmp <= (sljit_uw)((sign << 1) - max_offset - 1)) ? 0 : sign)) & ~mask);
- imm = get_imm(tmp);
-
- if (imm) {
- *memw = argw + (sljit_sw)tmp;
- SLJIT_ASSERT(*memw >= -mask && *memw <= max_offset);
-
- return push_inst(compiler, SUB | RD(TMP_REG1) | RN(arg) | imm);
- }
- }
- }
-
- tmp = (sljit_uw)(argw & (sign | mask));
- tmp = (sljit_uw)((argw + ((tmp <= (sljit_uw)max_offset || tmp == (sljit_uw)sign) ? 0 : sign)) & ~mask);
- *memw = argw - (sljit_sw)tmp;
-
- FAIL_IF(load_immediate(compiler, TMP_REG1, tmp));
-
- if (arg == 0)
- return SLJIT_SUCCESS;
-
- return push_inst(compiler, ADD | RD(TMP_REG1) | RN(TMP_REG1) | RM(arg));
-}
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
-
-static sljit_s32 sljit_emit_mem_unaligned(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 reg,
- sljit_s32 mem, sljit_sw memw)
-{
- sljit_s32 flags, steps, tmp_reg;
- sljit_uw add, shift;
-
- switch (type & 0xff) {
- case SLJIT_MOV_U8:
- case SLJIT_MOV_S8:
- flags = BYTE_SIZE;
- if (!(type & SLJIT_MEM_STORE))
- flags |= LOAD_DATA;
- if ((type & 0xff) == SLJIT_MOV_S8)
- flags |= SIGNED;
-
- return emit_op_mem(compiler, flags, reg, mem, memw, TMP_REG1);
-
- case SLJIT_MOV_U16:
- FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xfff - 1));
- flags = BYTE_SIZE;
- steps = 1;
- break;
-
- case SLJIT_MOV_S16:
- FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xff - 1));
- flags = BYTE_SIZE | SIGNED;
- steps = 1;
- break;
-
- default:
- if (type & SLJIT_MEM_UNALIGNED_32) {
- flags = WORD_SIZE;
- if (!(type & SLJIT_MEM_STORE))
- flags |= LOAD_DATA;
-
- return emit_op_mem(compiler, flags, reg, mem, memw, TMP_REG1);
- }
-
- if (!(type & SLJIT_MEM_UNALIGNED_16)) {
- FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xfff - 3));
- flags = BYTE_SIZE;
- steps = 3;
- break;
- }
-
- FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xff - 2));
-
- add = 1;
- if (memw < 0) {
- add = 0;
- memw = -memw;
- }
-
- tmp_reg = reg;
-
- if (type & SLJIT_MEM_STORE) {
- FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(HALF_SIZE, add, reg, mem, TYPE2_TRANSFER_IMM(memw))));
- FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(reg) | (16 << 7) | (2 << 4)));
- } else {
- if (reg == mem) {
- SLJIT_ASSERT(reg != TMP_REG1);
- tmp_reg = TMP_REG1;
- }
-
- FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(HALF_SIZE | LOAD_DATA, add, tmp_reg, mem, TYPE2_TRANSFER_IMM(memw))));
- }
-
- if (!add) {
- memw -= 2;
- if (memw <= 0) {
- memw = -memw;
- add = 1;
- }
- } else
- memw += 2;
-
- if (type & SLJIT_MEM_STORE)
- return push_inst(compiler, EMIT_DATA_TRANSFER(HALF_SIZE, add, TMP_REG2, mem, TYPE2_TRANSFER_IMM(memw)));
-
- FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(HALF_SIZE | LOAD_DATA, add, TMP_REG2, mem, TYPE2_TRANSFER_IMM(memw))));
- return push_inst(compiler, ORR | RD(reg) | RN(tmp_reg) | RM(TMP_REG2) | (16 << 7));
- }
-
- SLJIT_ASSERT(steps > 0);
-
- add = 1;
- if (memw < 0) {
- add = 0;
- memw = -memw;
- }
-
- if (type & SLJIT_MEM_STORE) {
- FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(BYTE_SIZE, add, reg, mem, memw)));
- FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(reg) | (8 << 7) | (2 << 4)));
-
- while (1) {
- if (!add) {
- memw -= 1;
- if (memw == 0)
- add = 1;
- } else
- memw += 1;
-
- FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(BYTE_SIZE, add, TMP_REG2, mem, memw)));
-
- if (--steps == 0)
- return SLJIT_SUCCESS;
-
- FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(TMP_REG2) | (8 << 7) | (2 << 4)));
- }
- }
-
- tmp_reg = reg;
-
- if (reg == mem) {
- SLJIT_ASSERT(reg != TMP_REG1);
- tmp_reg = TMP_REG1;
- }
-
- shift = 8;
- FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(BYTE_SIZE | LOAD_DATA, add, tmp_reg, mem, memw)));
-
- do {
- if (!add) {
- memw -= 1;
- if (memw == 0)
- add = 1;
- } else
- memw += 1;
-
- if (steps > 1) {
- FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(BYTE_SIZE | LOAD_DATA, add, TMP_REG2, mem, memw)));
- FAIL_IF(push_inst(compiler, ORR | RD(tmp_reg) | RN(tmp_reg) | RM(TMP_REG2) | (shift << 7)));
- shift += 8;
- }
- } while (--steps != 0);
-
- flags |= LOAD_DATA;
-
- if (flags & SIGNED)
- FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(flags, add, TMP_REG2, mem, TYPE2_TRANSFER_IMM(memw))));
- else
- FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(flags, add, TMP_REG2, mem, memw)));
-
- return push_inst(compiler, ORR | RD(reg) | RN(tmp_reg) | RM(TMP_REG2) | (shift << 7));
-}
-
-#endif /* SLJIT_CONFIG_ARM_V5 */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 reg,
- sljit_s32 mem, sljit_sw memw)
-{
- sljit_s32 flags;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
-
- if (!(reg & REG_PAIR_MASK)) {
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- ADJUST_LOCAL_OFFSET(mem, memw);
-#endif /* SLJIT_CONFIG_ARM_V5 */
-
- return sljit_emit_mem_unaligned(compiler, type, reg, mem, memw);
- }
-
- ADJUST_LOCAL_OFFSET(mem, memw);
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- if (type & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16)) {
- FAIL_IF(update_mem_addr(compiler, &mem, &memw, (type & SLJIT_MEM_UNALIGNED_16) ? 0xfff - 6 : 0xfff - 7));
-
- if (!(type & SLJIT_MEM_STORE) && REG_PAIR_FIRST(reg) == (mem & REG_MASK)) {
- FAIL_IF(sljit_emit_mem_unaligned(compiler, type, REG_PAIR_SECOND(reg), SLJIT_MEM1(mem), memw + SSIZE_OF(sw)));
- return sljit_emit_mem_unaligned(compiler, type, REG_PAIR_FIRST(reg), SLJIT_MEM1(mem), memw);
- }
-
- FAIL_IF(sljit_emit_mem_unaligned(compiler, type, REG_PAIR_FIRST(reg), SLJIT_MEM1(mem), memw));
- return sljit_emit_mem_unaligned(compiler, type, REG_PAIR_SECOND(reg), SLJIT_MEM1(mem), memw + SSIZE_OF(sw));
- }
-#endif /* SLJIT_CONFIG_ARM_V5 */
-
- FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xfff - 4));
-
- flags = WORD_SIZE;
-
- if (!(type & SLJIT_MEM_STORE)) {
- if (REG_PAIR_FIRST(reg) == (mem & REG_MASK)) {
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, REG_PAIR_SECOND(reg), SLJIT_MEM1(mem), memw + SSIZE_OF(sw), TMP_REG1));
- return emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, REG_PAIR_FIRST(reg), SLJIT_MEM1(mem), memw, TMP_REG1);
- }
-
- flags = WORD_SIZE | LOAD_DATA;
- }
-
- FAIL_IF(emit_op_mem(compiler, flags, REG_PAIR_FIRST(reg), SLJIT_MEM1(mem), memw, TMP_REG1));
- return emit_op_mem(compiler, flags, REG_PAIR_SECOND(reg), SLJIT_MEM1(mem), memw + SSIZE_OF(sw), TMP_REG1);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 reg,
- sljit_s32 mem, sljit_sw memw)
-{
- sljit_s32 flags;
- sljit_uw is_type1_transfer, inst;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_mem_update(compiler, type, reg, mem, memw));
-
- is_type1_transfer = 1;
-
- switch (type & 0xff) {
- case SLJIT_MOV:
- case SLJIT_MOV_U32:
- case SLJIT_MOV_S32:
- case SLJIT_MOV32:
- case SLJIT_MOV_P:
- flags = WORD_SIZE;
- break;
- case SLJIT_MOV_U8:
- flags = BYTE_SIZE;
- break;
- case SLJIT_MOV_S8:
- if (!(type & SLJIT_MEM_STORE))
- is_type1_transfer = 0;
- flags = BYTE_SIZE | SIGNED;
- break;
- case SLJIT_MOV_U16:
- is_type1_transfer = 0;
- flags = HALF_SIZE;
- break;
- case SLJIT_MOV_S16:
- is_type1_transfer = 0;
- flags = HALF_SIZE | SIGNED;
- break;
- default:
- SLJIT_UNREACHABLE();
- flags = WORD_SIZE;
- break;
- }
-
- if (!(type & SLJIT_MEM_STORE))
- flags |= LOAD_DATA;
-
- SLJIT_ASSERT(is_type1_transfer == !!IS_TYPE1_TRANSFER(flags));
-
- if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
- if (!is_type1_transfer && memw != 0)
- return SLJIT_ERR_UNSUPPORTED;
- } else {
- if (is_type1_transfer) {
- if (memw > 4095 || memw < -4095)
- return SLJIT_ERR_UNSUPPORTED;
- } else if (memw > 255 || memw < -255)
- return SLJIT_ERR_UNSUPPORTED;
- }
-
- if (type & SLJIT_MEM_SUPP)
- return SLJIT_SUCCESS;
-
- if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
- memw &= 0x3;
-
- inst = EMIT_DATA_TRANSFER(flags, 1, reg, mem & REG_MASK, RM(OFFS_REG(mem)) | ((sljit_uw)memw << 7));
-
- if (is_type1_transfer)
- inst |= (1 << 25);
-
- if (type & SLJIT_MEM_POST)
- inst ^= (1 << 24);
- else
- inst |= (1 << 21);
-
- return push_inst(compiler, inst);
- }
-
- inst = EMIT_DATA_TRANSFER(flags, 0, reg, mem & REG_MASK, 0);
-
- if (type & SLJIT_MEM_POST)
- inst ^= (1 << 24);
- else
- inst |= (1 << 21);
-
- if (is_type1_transfer) {
- if (memw >= 0)
- inst |= (1 << 23);
- else
- memw = -memw;
-
- return push_inst(compiler, inst | (sljit_uw)memw);
- }
-
- if (memw >= 0)
- inst |= (1 << 23);
- else
- memw = -memw;
-
- return push_inst(compiler, inst | TYPE2_TRANSFER_IMM((sljit_uw)memw));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 freg,
- sljit_s32 mem, sljit_sw memw)
-{
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- sljit_s32 max_offset;
- sljit_s32 dst;
-#endif /* SLJIT_CONFIG_ARM_V5 */
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
-
- if (type & SLJIT_MEM_UNALIGNED_32)
- return emit_fop_mem(compiler, ((type ^ SLJIT_32) & SLJIT_32) | ((type & SLJIT_MEM_STORE) ? 0 : FPU_LOAD), freg, mem, memw);
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- if (type & SLJIT_MEM_STORE) {
- FAIL_IF(push_inst(compiler, VMOV | (1 << 20) | VN(freg) | RD(TMP_REG2)));
-
- if (type & SLJIT_32)
- return sljit_emit_mem_unaligned(compiler, SLJIT_MOV | SLJIT_MEM_STORE | (type & SLJIT_MEM_UNALIGNED_16), TMP_REG2, mem, memw);
-
- max_offset = 0xfff - 7;
- if (type & SLJIT_MEM_UNALIGNED_16)
- max_offset++;
-
- FAIL_IF(update_mem_addr(compiler, &mem, &memw, max_offset));
- mem |= SLJIT_MEM;
-
- FAIL_IF(sljit_emit_mem_unaligned(compiler, SLJIT_MOV | SLJIT_MEM_STORE | (type & SLJIT_MEM_UNALIGNED_16), TMP_REG2, mem, memw));
-
- FAIL_IF(push_inst(compiler, VMOV | (1 << 20) | VN(freg) | 0x80 | RD(TMP_REG2)));
- return sljit_emit_mem_unaligned(compiler, SLJIT_MOV | SLJIT_MEM_STORE | (type & SLJIT_MEM_UNALIGNED_16), TMP_REG2, mem, memw + 4);
- }
-
- max_offset = (type & SLJIT_32) ? 0xfff - 3 : 0xfff - 7;
- if (type & SLJIT_MEM_UNALIGNED_16)
- max_offset++;
-
- FAIL_IF(update_mem_addr(compiler, &mem, &memw, max_offset));
-
- dst = TMP_REG1;
-
- /* Stack offset adjustment is not needed because dst
- is not stored on the stack when mem is SLJIT_SP. */
-
- if (mem == TMP_REG1) {
- dst = SLJIT_R3;
-
- if (compiler->scratches >= 4)
- FAIL_IF(push_inst(compiler, STR | (1 << 21) | RN(SLJIT_SP) | RD(SLJIT_R3) | 8));
- }
-
- mem |= SLJIT_MEM;
-
- FAIL_IF(sljit_emit_mem_unaligned(compiler, SLJIT_MOV | (type & SLJIT_MEM_UNALIGNED_16), dst, mem, memw));
- FAIL_IF(push_inst(compiler, VMOV | VN(freg) | RD(dst)));
-
- if (!(type & SLJIT_32)) {
- FAIL_IF(sljit_emit_mem_unaligned(compiler, SLJIT_MOV | (type & SLJIT_MEM_UNALIGNED_16), dst, mem, memw + 4));
- FAIL_IF(push_inst(compiler, VMOV | VN(freg) | 0x80 | RD(dst)));
- }
-
- if (dst == SLJIT_R3 && compiler->scratches >= 4)
- FAIL_IF(push_inst(compiler, (LDR ^ (0x1 << 24)) | (0x1 << 23) | RN(SLJIT_SP) | RD(SLJIT_R3) | 8));
- return SLJIT_SUCCESS;
-#else /* !SLJIT_CONFIG_ARM_V5 */
- if (type & SLJIT_MEM_STORE) {
- FAIL_IF(push_inst(compiler, VMOV | (1 << 20) | VN(freg) | RD(TMP_REG2)));
-
- if (type & SLJIT_32)
- return emit_op_mem(compiler, WORD_SIZE, TMP_REG2, mem, memw, TMP_REG1);
-
- FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xfff - 4));
- mem |= SLJIT_MEM;
-
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, mem, memw, TMP_REG1));
- FAIL_IF(push_inst(compiler, VMOV | (1 << 20) | VN(freg) | 0x80 | RD(TMP_REG2)));
- return emit_op_mem(compiler, WORD_SIZE, TMP_REG2, mem, memw + 4, TMP_REG1);
- }
-
- if (type & SLJIT_32) {
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, mem, memw, TMP_REG1));
- return push_inst(compiler, VMOV | VN(freg) | RD(TMP_REG2));
- }
-
- FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xfff - 4));
- mem |= SLJIT_MEM;
-
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, mem, memw, TMP_REG1));
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG1, mem, memw + 4, TMP_REG1));
- return push_inst(compiler, VMOV2 | VM(freg) | RD(TMP_REG2) | RN(TMP_REG1));
-#endif /* SLJIT_CONFIG_ARM_V5 */
-}
-
-#undef FPU_LOAD
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
-{
- struct sljit_const *const_;
- sljit_s32 dst_r;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- PTR_FAIL_IF(push_inst_with_unique_literal(compiler,
- EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), (sljit_uw)init_value));
- compiler->patches++;
-#else
- PTR_FAIL_IF(emit_imm(compiler, dst_r, init_value));
-#endif
-
- const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
- PTR_FAIL_IF(!const_);
- set_const(const_, compiler);
-
- if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1));
- return const_;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
-{
- struct sljit_put_label *put_label;
- sljit_s32 dst_r;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
-
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), 0));
- compiler->patches++;
-#else
- PTR_FAIL_IF(emit_imm(compiler, dst_r, 0));
-#endif
-
- put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
- PTR_FAIL_IF(!put_label);
- set_put_label(put_label, compiler, 0);
-
- if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1));
- return put_label;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
-{
- inline_set_jump_addr(addr, executable_offset, new_target, 1);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
-{
- inline_set_const(addr, executable_offset, (sljit_uw)new_constant, 1);
-}
diff --git a/contrib/libs/pcre2/src/sljit/sljitNativeARM_64.c b/contrib/libs/pcre2/src/sljit/sljitNativeARM_64.c
deleted file mode 100644
index 89f747e7c8..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitNativeARM_64.c
+++ /dev/null
@@ -1,2417 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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.
- */
-
-SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
-{
- return "ARM-64" SLJIT_CPUINFO;
-}
-
-/* Length of an instruction word */
-typedef sljit_u32 sljit_ins;
-
-#define TMP_ZERO (0)
-
-#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
-#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
-#define TMP_LR (SLJIT_NUMBER_OF_REGISTERS + 4)
-#define TMP_FP (SLJIT_NUMBER_OF_REGISTERS + 5)
-
-#define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
-#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
-
-/* r18 - platform register, currently not used */
-static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 8] = {
- 31, 0, 1, 2, 3, 4, 5, 6, 7, 11, 12, 13, 14, 15, 16, 17, 8, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 31, 9, 10, 30, 29
-};
-
-static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
- 0, 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 15, 14, 13, 12, 11, 10, 9, 8, 30, 31
-};
-
-#define W_OP ((sljit_ins)1 << 31)
-#define RD(rd) ((sljit_ins)reg_map[rd])
-#define RT(rt) ((sljit_ins)reg_map[rt])
-#define RN(rn) ((sljit_ins)reg_map[rn] << 5)
-#define RT2(rt2) ((sljit_ins)reg_map[rt2] << 10)
-#define RM(rm) ((sljit_ins)reg_map[rm] << 16)
-#define VD(vd) ((sljit_ins)freg_map[vd])
-#define VT(vt) ((sljit_ins)freg_map[vt])
-#define VT2(vt) ((sljit_ins)freg_map[vt] << 10)
-#define VN(vn) ((sljit_ins)freg_map[vn] << 5)
-#define VM(vm) ((sljit_ins)freg_map[vm] << 16)
-
-/* --------------------------------------------------------------------- */
-/* Instrucion forms */
-/* --------------------------------------------------------------------- */
-
-#define ADC 0x9a000000
-#define ADD 0x8b000000
-#define ADDE 0x8b200000
-#define ADDI 0x91000000
-#define AND 0x8a000000
-#define ANDI 0x92000000
-#define ASRV 0x9ac02800
-#define B 0x14000000
-#define B_CC 0x54000000
-#define BL 0x94000000
-#define BLR 0xd63f0000
-#define BR 0xd61f0000
-#define BRK 0xd4200000
-#define CBZ 0xb4000000
-#define CLZ 0xdac01000
-#define CSEL 0x9a800000
-#define CSINC 0x9a800400
-#define EOR 0xca000000
-#define EORI 0xd2000000
-#define EXTR 0x93c00000
-#define FABS 0x1e60c000
-#define FADD 0x1e602800
-#define FCMP 0x1e602000
-#define FCVT 0x1e224000
-#define FCVTZS 0x9e780000
-#define FDIV 0x1e601800
-#define FMOV 0x1e604000
-#define FMUL 0x1e600800
-#define FNEG 0x1e614000
-#define FSUB 0x1e603800
-#define LDRI 0xf9400000
-#define LDRI_F64 0xfd400000
-#define LDRI_POST 0xf8400400
-#define LDP 0xa9400000
-#define LDP_F64 0x6d400000
-#define LDP_POST 0xa8c00000
-#define LDR_PRE 0xf8400c00
-#define LSLV 0x9ac02000
-#define LSRV 0x9ac02400
-#define MADD 0x9b000000
-#define MOVK 0xf2800000
-#define MOVN 0x92800000
-#define MOVZ 0xd2800000
-#define NOP 0xd503201f
-#define ORN 0xaa200000
-#define ORR 0xaa000000
-#define ORRI 0xb2000000
-#define RBIT 0xdac00000
-#define RET 0xd65f0000
-#define RORV 0x9ac02c00
-#define SBC 0xda000000
-#define SBFM 0x93000000
-#define SCVTF 0x9e620000
-#define SDIV 0x9ac00c00
-#define SMADDL 0x9b200000
-#define SMULH 0x9b403c00
-#define STP 0xa9000000
-#define STP_F64 0x6d000000
-#define STP_PRE 0xa9800000
-#define STRB 0x38206800
-#define STRBI 0x39000000
-#define STRI 0xf9000000
-#define STRI_F64 0xfd000000
-#define STR_FI 0x3d000000
-#define STR_FR 0x3c206800
-#define STUR_FI 0x3c000000
-#define STURBI 0x38000000
-#define SUB 0xcb000000
-#define SUBI 0xd1000000
-#define SUBS 0xeb000000
-#define UBFM 0xd3000000
-#define UDIV 0x9ac00800
-#define UMULH 0x9bc03c00
-
-static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)
-{
- sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
- FAIL_IF(!ptr);
- *ptr = ins;
- compiler->size++;
- return SLJIT_SUCCESS;
-}
-
-static SLJIT_INLINE sljit_s32 emit_imm64_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm)
-{
- FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((sljit_ins)(imm & 0xffff) << 5)));
- FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((sljit_ins)(imm >> 16) & 0xffff) << 5) | (1 << 21)));
- FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((sljit_ins)(imm >> 32) & 0xffff) << 5) | (2 << 21)));
- return push_inst(compiler, MOVK | RD(dst) | ((sljit_ins)(imm >> 48) << 5) | (3 << 21));
-}
-
-static SLJIT_INLINE sljit_sw detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
-{
- sljit_sw diff;
- sljit_uw target_addr;
-
- if (jump->flags & SLJIT_REWRITABLE_JUMP) {
- jump->flags |= PATCH_ABS64;
- return 0;
- }
-
- if (jump->flags & JUMP_ADDR)
- target_addr = jump->u.target;
- else {
- SLJIT_ASSERT(jump->flags & JUMP_LABEL);
- target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
- }
-
- diff = (sljit_sw)target_addr - (sljit_sw)(code_ptr + 4) - executable_offset;
-
- if (jump->flags & IS_COND) {
- diff += SSIZE_OF(ins);
- if (diff <= 0xfffff && diff >= -0x100000) {
- code_ptr[-5] ^= (jump->flags & IS_CBZ) ? (0x1 << 24) : 0x1;
- jump->addr -= sizeof(sljit_ins);
- jump->flags |= PATCH_COND;
- return 5;
- }
- diff -= SSIZE_OF(ins);
- }
-
- if (diff <= 0x7ffffff && diff >= -0x8000000) {
- jump->flags |= PATCH_B;
- return 4;
- }
-
- if (target_addr < 0x100000000l) {
- if (jump->flags & IS_COND)
- code_ptr[-5] -= (2 << 5);
- code_ptr[-2] = code_ptr[0];
- return 2;
- }
-
- if (target_addr < 0x1000000000000l) {
- if (jump->flags & IS_COND)
- code_ptr[-5] -= (1 << 5);
- jump->flags |= PATCH_ABS48;
- code_ptr[-1] = code_ptr[0];
- return 1;
- }
-
- jump->flags |= PATCH_ABS64;
- return 0;
-}
-
-static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label)
-{
- if (max_label < 0x100000000l) {
- put_label->flags = 0;
- return 2;
- }
-
- if (max_label < 0x1000000000000l) {
- put_label->flags = 1;
- return 1;
- }
-
- put_label->flags = 2;
- return 0;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
-{
- struct sljit_memory_fragment *buf;
- sljit_ins *code;
- sljit_ins *code_ptr;
- sljit_ins *buf_ptr;
- sljit_ins *buf_end;
- sljit_uw word_count;
- sljit_uw next_addr;
- sljit_sw executable_offset;
- sljit_sw addr;
- sljit_u32 dst;
-
- struct sljit_label *label;
- struct sljit_jump *jump;
- struct sljit_const *const_;
- struct sljit_put_label *put_label;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_generate_code(compiler));
- reverse_buf(compiler);
-
- code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
- PTR_FAIL_WITH_EXEC_IF(code);
- buf = compiler->buf;
-
- code_ptr = code;
- word_count = 0;
- next_addr = 0;
- executable_offset = SLJIT_EXEC_OFFSET(code);
-
- label = compiler->labels;
- jump = compiler->jumps;
- const_ = compiler->consts;
- put_label = compiler->put_labels;
-
- do {
- buf_ptr = (sljit_ins*)buf->memory;
- buf_end = buf_ptr + (buf->used_size >> 2);
- do {
- *code_ptr = *buf_ptr++;
- if (next_addr == word_count) {
- SLJIT_ASSERT(!label || label->size >= word_count);
- SLJIT_ASSERT(!jump || jump->addr >= word_count);
- SLJIT_ASSERT(!const_ || const_->addr >= word_count);
- SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
-
- /* These structures are ordered by their address. */
- if (label && label->size == word_count) {
- label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
- label->size = (sljit_uw)(code_ptr - code);
- label = label->next;
- }
- if (jump && jump->addr == word_count) {
- jump->addr = (sljit_uw)(code_ptr - 4);
- code_ptr -= detect_jump_type(jump, code_ptr, code, executable_offset);
- jump = jump->next;
- }
- if (const_ && const_->addr == word_count) {
- const_->addr = (sljit_uw)code_ptr;
- const_ = const_->next;
- }
- if (put_label && put_label->addr == word_count) {
- SLJIT_ASSERT(put_label->label);
- put_label->addr = (sljit_uw)(code_ptr - 3);
- code_ptr -= put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));
- put_label = put_label->next;
- }
- next_addr = compute_next_addr(label, jump, const_, put_label);
- }
- code_ptr++;
- word_count++;
- } while (buf_ptr < buf_end);
-
- buf = buf->next;
- } while (buf);
-
- if (label && label->size == word_count) {
- label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
- label->size = (sljit_uw)(code_ptr - code);
- label = label->next;
- }
-
- SLJIT_ASSERT(!label);
- SLJIT_ASSERT(!jump);
- SLJIT_ASSERT(!const_);
- SLJIT_ASSERT(!put_label);
- SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
-
- jump = compiler->jumps;
- while (jump) {
- do {
- addr = (sljit_sw)((jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target);
- buf_ptr = (sljit_ins *)jump->addr;
-
- if (jump->flags & PATCH_B) {
- addr = (addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
- SLJIT_ASSERT(addr <= 0x1ffffff && addr >= -0x2000000);
- buf_ptr[0] = ((jump->flags & IS_BL) ? BL : B) | (sljit_ins)(addr & 0x3ffffff);
- if (jump->flags & IS_COND)
- buf_ptr[-1] -= (4 << 5);
- break;
- }
- if (jump->flags & PATCH_COND) {
- addr = (addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
- SLJIT_ASSERT(addr <= 0x3ffff && addr >= -0x40000);
- buf_ptr[0] = (buf_ptr[0] & ~(sljit_ins)0xffffe0) | (sljit_ins)((addr & 0x7ffff) << 5);
- break;
- }
-
- SLJIT_ASSERT((jump->flags & (PATCH_ABS48 | PATCH_ABS64)) || (sljit_uw)addr <= (sljit_uw)0xffffffff);
- SLJIT_ASSERT((jump->flags & PATCH_ABS64) || (sljit_uw)addr <= (sljit_uw)0xffffffffffff);
-
- dst = buf_ptr[0] & 0x1f;
- buf_ptr[0] = MOVZ | dst | (((sljit_ins)addr & 0xffff) << 5);
- buf_ptr[1] = MOVK | dst | (((sljit_ins)(addr >> 16) & 0xffff) << 5) | (1 << 21);
- if (jump->flags & (PATCH_ABS48 | PATCH_ABS64))
- buf_ptr[2] = MOVK | dst | (((sljit_ins)(addr >> 32) & 0xffff) << 5) | (2 << 21);
- if (jump->flags & PATCH_ABS64)
- buf_ptr[3] = MOVK | dst | ((sljit_ins)(addr >> 48) << 5) | (3 << 21);
- } while (0);
- jump = jump->next;
- }
-
- put_label = compiler->put_labels;
- while (put_label) {
- addr = (sljit_sw)put_label->label->addr;
- buf_ptr = (sljit_ins*)put_label->addr;
-
- buf_ptr[0] |= ((sljit_ins)addr & 0xffff) << 5;
- buf_ptr[1] |= ((sljit_ins)(addr >> 16) & 0xffff) << 5;
-
- if (put_label->flags >= 1)
- buf_ptr[2] |= ((sljit_ins)(addr >> 32) & 0xffff) << 5;
-
- if (put_label->flags >= 2)
- buf_ptr[3] |= (sljit_ins)(addr >> 48) << 5;
-
- put_label = put_label->next;
- }
-
- compiler->error = SLJIT_ERR_COMPILED;
- compiler->executable_offset = executable_offset;
- compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins);
-
- code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
- code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
-
- SLJIT_CACHE_FLUSH(code, code_ptr);
- SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
- return code;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
-{
- switch (feature_type) {
- case SLJIT_HAS_FPU:
-#ifdef SLJIT_IS_FPU_AVAILABLE
- return SLJIT_IS_FPU_AVAILABLE;
-#else
- /* Available by default. */
- return 1;
-#endif
-
- case SLJIT_HAS_CLZ:
- case SLJIT_HAS_CTZ:
- case SLJIT_HAS_ROT:
- case SLJIT_HAS_CMOV:
- case SLJIT_HAS_PREFETCH:
- return 1;
-
- default:
- return 0;
- }
-}
-
-/* --------------------------------------------------------------------- */
-/* Core code generator functions. */
-/* --------------------------------------------------------------------- */
-
-#define COUNT_TRAILING_ZERO(value, result) \
- result = 0; \
- if (!(value & 0xffffffff)) { \
- result += 32; \
- value >>= 32; \
- } \
- if (!(value & 0xffff)) { \
- result += 16; \
- value >>= 16; \
- } \
- if (!(value & 0xff)) { \
- result += 8; \
- value >>= 8; \
- } \
- if (!(value & 0xf)) { \
- result += 4; \
- value >>= 4; \
- } \
- if (!(value & 0x3)) { \
- result += 2; \
- value >>= 2; \
- } \
- if (!(value & 0x1)) { \
- result += 1; \
- value >>= 1; \
- }
-
-#define LOGICAL_IMM_CHECK (sljit_ins)0x100
-
-static sljit_ins logical_imm(sljit_sw imm, sljit_u32 len)
-{
- sljit_s32 negated;
- sljit_u32 ones, right;
- sljit_uw mask, uimm;
- sljit_ins ins;
-
- if (len & LOGICAL_IMM_CHECK) {
- len &= ~LOGICAL_IMM_CHECK;
- if (len == 32 && (imm == 0 || imm == -1))
- return 0;
- if (len == 16 && ((sljit_s32)imm == 0 || (sljit_s32)imm == -1))
- return 0;
- }
-
- SLJIT_ASSERT((len == 32 && imm != 0 && imm != -1)
- || (len == 16 && (sljit_s32)imm != 0 && (sljit_s32)imm != -1));
-
- uimm = (sljit_uw)imm;
- while (1) {
- if (len <= 0) {
- SLJIT_UNREACHABLE();
- return 0;
- }
-
- mask = ((sljit_uw)1 << len) - 1;
- if ((uimm & mask) != ((uimm >> len) & mask))
- break;
- len >>= 1;
- }
-
- len <<= 1;
-
- negated = 0;
- if (uimm & 0x1) {
- negated = 1;
- uimm = ~uimm;
- }
-
- if (len < 64)
- uimm &= ((sljit_uw)1 << len) - 1;
-
- /* Unsigned right shift. */
- COUNT_TRAILING_ZERO(uimm, right);
-
- /* Signed shift. We also know that the highest bit is set. */
- imm = (sljit_sw)~uimm;
- SLJIT_ASSERT(imm < 0);
-
- COUNT_TRAILING_ZERO(imm, ones);
-
- if (~imm)
- return 0;
-
- if (len == 64)
- ins = 1 << 22;
- else
- ins = (0x3f - ((len << 1) - 1)) << 10;
-
- if (negated)
- return ins | ((len - ones - 1) << 10) | ((len - ones - right) << 16);
-
- return ins | ((ones - 1) << 10) | ((len - right) << 16);
-}
-
-#undef COUNT_TRAILING_ZERO
-
-static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw simm)
-{
- sljit_uw imm = (sljit_uw)simm;
- sljit_u32 i, zeros, ones, first;
- sljit_ins bitmask;
-
- /* Handling simple immediates first. */
- if (imm <= 0xffff)
- return push_inst(compiler, MOVZ | RD(dst) | ((sljit_ins)imm << 5));
-
- if (simm < 0 && simm >= -0x10000)
- return push_inst(compiler, MOVN | RD(dst) | (((sljit_ins)~imm & 0xffff) << 5));
-
- if (imm <= 0xffffffffl) {
- if ((imm & 0xffff) == 0)
- return push_inst(compiler, MOVZ | RD(dst) | ((sljit_ins)(imm >> 16) << 5) | (1 << 21));
- if ((imm & 0xffff0000l) == 0xffff0000)
- return push_inst(compiler, (MOVN ^ W_OP) | RD(dst) | (((sljit_ins)~imm & 0xffff) << 5));
- if ((imm & 0xffff) == 0xffff)
- return push_inst(compiler, (MOVN ^ W_OP) | RD(dst) | (((sljit_ins)~imm & 0xffff0000u) >> (16 - 5)) | (1 << 21));
-
- bitmask = logical_imm(simm, 16);
- if (bitmask != 0)
- return push_inst(compiler, (ORRI ^ W_OP) | RD(dst) | RN(TMP_ZERO) | bitmask);
-
- FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | (((sljit_ins)imm & 0xffff) << 5)));
- return push_inst(compiler, MOVK | RD(dst) | (((sljit_ins)imm & 0xffff0000u) >> (16 - 5)) | (1 << 21));
- }
-
- bitmask = logical_imm(simm, 32);
- if (bitmask != 0)
- return push_inst(compiler, ORRI | RD(dst) | RN(TMP_ZERO) | bitmask);
-
- if (simm < 0 && simm >= -0x100000000l) {
- if ((imm & 0xffff) == 0xffff)
- return push_inst(compiler, MOVN | RD(dst) | (((sljit_ins)~imm & 0xffff0000u) >> (16 - 5)) | (1 << 21));
-
- FAIL_IF(push_inst(compiler, MOVN | RD(dst) | (((sljit_ins)~imm & 0xffff) << 5)));
- return push_inst(compiler, MOVK | RD(dst) | (((sljit_ins)imm & 0xffff0000u) >> (16 - 5)) | (1 << 21));
- }
-
- /* A large amount of number can be constructed from ORR and MOVx, but computing them is costly. */
-
- zeros = 0;
- ones = 0;
- for (i = 4; i > 0; i--) {
- if ((simm & 0xffff) == 0)
- zeros++;
- if ((simm & 0xffff) == 0xffff)
- ones++;
- simm >>= 16;
- }
-
- simm = (sljit_sw)imm;
- first = 1;
- if (ones > zeros) {
- simm = ~simm;
- for (i = 0; i < 4; i++) {
- if (!(simm & 0xffff)) {
- simm >>= 16;
- continue;
- }
- if (first) {
- first = 0;
- FAIL_IF(push_inst(compiler, MOVN | RD(dst) | (((sljit_ins)simm & 0xffff) << 5) | (i << 21)));
- }
- else
- FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((sljit_ins)~simm & 0xffff) << 5) | (i << 21)));
- simm >>= 16;
- }
- return SLJIT_SUCCESS;
- }
-
- for (i = 0; i < 4; i++) {
- if (!(simm & 0xffff)) {
- simm >>= 16;
- continue;
- }
- if (first) {
- first = 0;
- FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | (((sljit_ins)simm & 0xffff) << 5) | (i << 21)));
- }
- else
- FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((sljit_ins)simm & 0xffff) << 5) | (i << 21)));
- simm >>= 16;
- }
- return SLJIT_SUCCESS;
-}
-
-#define ARG1_IMM 0x0010000
-#define ARG2_IMM 0x0020000
-#define INT_OP 0x0040000
-#define SET_FLAGS 0x0080000
-#define UNUSED_RETURN 0x0100000
-
-#define CHECK_FLAGS(flag_bits) \
- if (flags & SET_FLAGS) { \
- inv_bits |= flag_bits; \
- if (flags & UNUSED_RETURN) \
- dst = TMP_ZERO; \
- }
-
-static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 dst, sljit_sw arg1, sljit_sw arg2)
-{
- /* dst must be register, TMP_REG1
- arg1 must be register, TMP_REG1, imm
- arg2 must be register, TMP_REG2, imm */
- sljit_ins inv_bits = (flags & INT_OP) ? W_OP : 0;
- sljit_ins inst_bits;
- sljit_s32 op = (flags & 0xffff);
- sljit_s32 reg;
- sljit_sw imm, nimm;
-
- if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) {
- /* Both are immediates. */
- flags &= ~ARG1_IMM;
- if (arg1 == 0 && op != SLJIT_ADD && op != SLJIT_SUB)
- arg1 = TMP_ZERO;
- else {
- FAIL_IF(load_immediate(compiler, TMP_REG1, arg1));
- arg1 = TMP_REG1;
- }
- }
-
- if (flags & (ARG1_IMM | ARG2_IMM)) {
- reg = (sljit_s32)((flags & ARG2_IMM) ? arg1 : arg2);
- imm = (flags & ARG2_IMM) ? arg2 : arg1;
-
- switch (op) {
- case SLJIT_MUL:
- case SLJIT_CLZ:
- case SLJIT_CTZ:
- case SLJIT_ADDC:
- case SLJIT_SUBC:
- /* No form with immediate operand (except imm 0, which
- is represented by a ZERO register). */
- break;
- case SLJIT_MOV:
- SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG1);
- return load_immediate(compiler, dst, imm);
- case SLJIT_NOT:
- SLJIT_ASSERT(flags & ARG2_IMM);
- FAIL_IF(load_immediate(compiler, dst, (flags & INT_OP) ? (~imm & 0xffffffff) : ~imm));
- goto set_flags;
- case SLJIT_SUB:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;
- if (flags & ARG1_IMM)
- break;
- imm = -imm;
- /* Fall through. */
- case SLJIT_ADD:
- if (op != SLJIT_SUB)
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;
-
- if (imm == 0) {
- CHECK_FLAGS(1 << 29);
- return push_inst(compiler, ((op == SLJIT_ADD ? ADDI : SUBI) ^ inv_bits) | RD(dst) | RN(reg));
- }
- if (imm > 0 && imm <= 0xfff) {
- CHECK_FLAGS(1 << 29);
- return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | ((sljit_ins)imm << 10));
- }
- nimm = -imm;
- if (nimm > 0 && nimm <= 0xfff) {
- CHECK_FLAGS(1 << 29);
- return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | ((sljit_ins)nimm << 10));
- }
- if (imm > 0 && imm <= 0xffffff && !(imm & 0xfff)) {
- CHECK_FLAGS(1 << 29);
- return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | (((sljit_ins)imm >> 12) << 10) | (1 << 22));
- }
- if (nimm > 0 && nimm <= 0xffffff && !(nimm & 0xfff)) {
- CHECK_FLAGS(1 << 29);
- return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | (((sljit_ins)nimm >> 12) << 10) | (1 << 22));
- }
- if (imm > 0 && imm <= 0xffffff && !(flags & SET_FLAGS)) {
- FAIL_IF(push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | (((sljit_ins)imm >> 12) << 10) | (1 << 22)));
- return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(dst) | (((sljit_ins)imm & 0xfff) << 10));
- }
- if (nimm > 0 && nimm <= 0xffffff && !(flags & SET_FLAGS)) {
- FAIL_IF(push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | (((sljit_ins)nimm >> 12) << 10) | (1 << 22)));
- return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(dst) | (((sljit_ins)nimm & 0xfff) << 10));
- }
- break;
- case SLJIT_AND:
- inst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32));
- if (!inst_bits)
- break;
- CHECK_FLAGS(3 << 29);
- return push_inst(compiler, (ANDI ^ inv_bits) | RD(dst) | RN(reg) | inst_bits);
- case SLJIT_OR:
- case SLJIT_XOR:
- inst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32));
- if (!inst_bits)
- break;
- if (op == SLJIT_OR)
- inst_bits |= ORRI;
- else
- inst_bits |= EORI;
- FAIL_IF(push_inst(compiler, (inst_bits ^ inv_bits) | RD(dst) | RN(reg)));
- goto set_flags;
- case SLJIT_SHL:
- case SLJIT_MSHL:
- if (flags & ARG1_IMM)
- break;
-
- if (flags & INT_OP) {
- imm &= 0x1f;
- inst_bits = (((sljit_ins)-imm & 0x1f) << 16) | ((31 - (sljit_ins)imm) << 10);
- } else {
- imm &= 0x3f;
- inst_bits = ((sljit_ins)1 << 22) | (((sljit_ins)-imm & 0x3f) << 16) | ((63 - (sljit_ins)imm) << 10);
- }
-
- FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | inst_bits));
- goto set_flags;
- case SLJIT_LSHR:
- case SLJIT_MLSHR:
- case SLJIT_ASHR:
- case SLJIT_MASHR:
- if (flags & ARG1_IMM)
- break;
-
- if (op >= SLJIT_ASHR)
- inv_bits |= 1 << 30;
-
- if (flags & INT_OP) {
- imm &= 0x1f;
- inst_bits = ((sljit_ins)imm << 16) | (31 << 10);
- } else {
- imm &= 0x3f;
- inst_bits = ((sljit_ins)1 << 22) | ((sljit_ins)imm << 16) | (63 << 10);
- }
-
- FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | inst_bits));
- goto set_flags;
- case SLJIT_ROTL:
- case SLJIT_ROTR:
- if (flags & ARG1_IMM)
- break;
-
- if (op == SLJIT_ROTL)
- imm = -imm;
-
- imm &= (flags & INT_OP) ? 0x1f : 0x3f;
- return push_inst(compiler, (EXTR ^ (inv_bits | (inv_bits >> 9))) | RD(dst) | RN(arg1) | RM(arg1) | ((sljit_ins)imm << 10));
- default:
- SLJIT_UNREACHABLE();
- break;
- }
-
- if (flags & ARG2_IMM) {
- if (arg2 == 0)
- arg2 = TMP_ZERO;
- else {
- FAIL_IF(load_immediate(compiler, TMP_REG2, arg2));
- arg2 = TMP_REG2;
- }
- }
- else {
- if (arg1 == 0)
- arg1 = TMP_ZERO;
- else {
- FAIL_IF(load_immediate(compiler, TMP_REG1, arg1));
- arg1 = TMP_REG1;
- }
- }
- }
-
- /* Both arguments are registers. */
- switch (op) {
- case SLJIT_MOV:
- case SLJIT_MOV_P:
- SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
- if (dst == arg2)
- return SLJIT_SUCCESS;
- return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(arg2));
- case SLJIT_MOV_U8:
- SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
- return push_inst(compiler, (UBFM ^ W_OP) | RD(dst) | RN(arg2) | (7 << 10));
- case SLJIT_MOV_S8:
- SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
- if (!(flags & INT_OP))
- inv_bits |= 1 << 22;
- return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (7 << 10));
- case SLJIT_MOV_U16:
- SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
- return push_inst(compiler, (UBFM ^ W_OP) | RD(dst) | RN(arg2) | (15 << 10));
- case SLJIT_MOV_S16:
- SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
- if (!(flags & INT_OP))
- inv_bits |= 1 << 22;
- return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (15 << 10));
- case SLJIT_MOV32:
- SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
- if (dst == arg2)
- return SLJIT_SUCCESS;
- /* fallthrough */
- case SLJIT_MOV_U32:
- SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
- return push_inst(compiler, (ORR ^ W_OP) | RD(dst) | RN(TMP_ZERO) | RM(arg2));
- case SLJIT_MOV_S32:
- SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
- return push_inst(compiler, SBFM | (1 << 22) | RD(dst) | RN(arg2) | (31 << 10));
- case SLJIT_NOT:
- SLJIT_ASSERT(arg1 == TMP_REG1);
- FAIL_IF(push_inst(compiler, (ORN ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(arg2)));
- break; /* Set flags. */
- case SLJIT_CLZ:
- SLJIT_ASSERT(arg1 == TMP_REG1);
- return push_inst(compiler, (CLZ ^ inv_bits) | RD(dst) | RN(arg2));
- case SLJIT_CTZ:
- SLJIT_ASSERT(arg1 == TMP_REG1);
- FAIL_IF(push_inst(compiler, (RBIT ^ inv_bits) | RD(dst) | RN(arg2)));
- return push_inst(compiler, (CLZ ^ inv_bits) | RD(dst) | RN(dst));
- case SLJIT_ADD:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;
- CHECK_FLAGS(1 << 29);
- return push_inst(compiler, (ADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
- case SLJIT_ADDC:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;
- CHECK_FLAGS(1 << 29);
- return push_inst(compiler, (ADC ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
- case SLJIT_SUB:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;
- CHECK_FLAGS(1 << 29);
- return push_inst(compiler, (SUB ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
- case SLJIT_SUBC:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;
- CHECK_FLAGS(1 << 29);
- return push_inst(compiler, (SBC ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
- case SLJIT_MUL:
- compiler->status_flags_state = 0;
- if (!(flags & SET_FLAGS))
- return push_inst(compiler, (MADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2) | RT2(TMP_ZERO));
- if (flags & INT_OP) {
- FAIL_IF(push_inst(compiler, SMADDL | RD(dst) | RN(arg1) | RM(arg2) | (31 << 10)));
- FAIL_IF(push_inst(compiler, ADD | RD(TMP_LR) | RN(TMP_ZERO) | RM(dst) | (2 << 22) | (31 << 10)));
- return push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_LR) | RM(dst) | (2 << 22) | (63 << 10));
- }
- FAIL_IF(push_inst(compiler, SMULH | RD(TMP_LR) | RN(arg1) | RM(arg2)));
- FAIL_IF(push_inst(compiler, MADD | RD(dst) | RN(arg1) | RM(arg2) | RT2(TMP_ZERO)));
- return push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_LR) | RM(dst) | (2 << 22) | (63 << 10));
- case SLJIT_AND:
- CHECK_FLAGS(3 << 29);
- return push_inst(compiler, (AND ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
- case SLJIT_OR:
- FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
- break; /* Set flags. */
- case SLJIT_XOR:
- FAIL_IF(push_inst(compiler, (EOR ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
- break; /* Set flags. */
- case SLJIT_SHL:
- case SLJIT_MSHL:
- FAIL_IF(push_inst(compiler, (LSLV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
- break; /* Set flags. */
- case SLJIT_LSHR:
- case SLJIT_MLSHR:
- FAIL_IF(push_inst(compiler, (LSRV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
- break; /* Set flags. */
- case SLJIT_ASHR:
- case SLJIT_MASHR:
- FAIL_IF(push_inst(compiler, (ASRV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
- break; /* Set flags. */
- case SLJIT_ROTL:
- FAIL_IF(push_inst(compiler, (SUB ^ inv_bits) | RD(TMP_REG2) | RN(TMP_ZERO) | RM(arg2)));
- arg2 = TMP_REG2;
- /* fallthrough */
- case SLJIT_ROTR:
- return push_inst(compiler, (RORV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
- default:
- SLJIT_UNREACHABLE();
- return SLJIT_SUCCESS;
- }
-
-set_flags:
- if (flags & SET_FLAGS)
- return push_inst(compiler, (SUBS ^ inv_bits) | RD(TMP_ZERO) | RN(dst) | RM(TMP_ZERO));
- return SLJIT_SUCCESS;
-}
-
-#define STORE 0x10
-#define SIGNED 0x20
-
-#define BYTE_SIZE 0x0
-#define HALF_SIZE 0x1
-#define INT_SIZE 0x2
-#define WORD_SIZE 0x3
-
-#define MEM_SIZE_SHIFT(flags) ((sljit_ins)(flags) & 0x3)
-
-static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg,
- sljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg)
-{
- sljit_u32 shift = MEM_SIZE_SHIFT(flags);
- sljit_u32 type = (shift << 30);
-
- if (!(flags & STORE))
- type |= (flags & SIGNED) ? 0x00800000 : 0x00400000;
-
- SLJIT_ASSERT(arg & SLJIT_MEM);
-
- if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
- argw &= 0x3;
-
- if (argw == 0 || argw == shift)
- return push_inst(compiler, STRB | type | RT(reg)
- | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw ? (1 << 12) : 0));
-
- FAIL_IF(push_inst(compiler, ADD | RD(tmp_reg) | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | ((sljit_ins)argw << 10)));
- return push_inst(compiler, STRBI | type | RT(reg) | RN(tmp_reg));
- }
-
- arg &= REG_MASK;
-
- if (!arg) {
- FAIL_IF(load_immediate(compiler, tmp_reg, argw & ~(0xfff << shift)));
-
- argw = (argw >> shift) & 0xfff;
-
- return push_inst(compiler, STRBI | type | RT(reg) | RN(tmp_reg) | ((sljit_ins)argw << 10));
- }
-
- if ((argw & ((1 << shift) - 1)) == 0) {
- if (argw >= 0) {
- if ((argw >> shift) <= 0xfff)
- return push_inst(compiler, STRBI | type | RT(reg) | RN(arg) | ((sljit_ins)argw << (10 - shift)));
-
- if (argw <= 0xffffff) {
- FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(tmp_reg) | RN(arg) | (((sljit_ins)argw >> 12) << 10)));
-
- argw = ((argw & 0xfff) >> shift);
- return push_inst(compiler, STRBI | type | RT(reg) | RN(tmp_reg) | ((sljit_ins)argw << 10));
- }
- } else if (argw < -256 && argw >= -0xfff000) {
- FAIL_IF(push_inst(compiler, SUBI | (1 << 22) | RD(tmp_reg) | RN(arg) | (((sljit_ins)(-argw + 0xfff) >> 12) << 10)));
- argw = ((0x1000 + argw) & 0xfff) >> shift;
- return push_inst(compiler, STRBI | type | RT(reg) | RN(tmp_reg) | ((sljit_ins)argw << 10));
- }
- }
-
- if (argw <= 0xff && argw >= -0x100)
- return push_inst(compiler, STURBI | type | RT(reg) | RN(arg) | (((sljit_ins)argw & 0x1ff) << 12));
-
- if (argw >= 0) {
- if (argw <= 0xfff0ff && ((argw + 0x100) & 0xfff) <= 0x1ff) {
- FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(tmp_reg) | RN(arg) | (((sljit_ins)argw >> 12) << 10)));
- return push_inst(compiler, STURBI | type | RT(reg) | RN(tmp_reg) | (((sljit_ins)argw & 0x1ff) << 12));
- }
- } else if (argw >= -0xfff100 && ((-argw + 0xff) & 0xfff) <= 0x1ff) {
- FAIL_IF(push_inst(compiler, SUBI | (1 << 22) | RD(tmp_reg) | RN(arg) | (((sljit_ins)-argw >> 12) << 10)));
- return push_inst(compiler, STURBI | type | RT(reg) | RN(tmp_reg) | (((sljit_ins)argw & 0x1ff) << 12));
- }
-
- FAIL_IF(load_immediate(compiler, tmp_reg, argw));
-
- return push_inst(compiler, STRB | type | RT(reg) | RN(arg) | RM(tmp_reg));
-}
-
-/* --------------------------------------------------------------------- */
-/* Entry, exit */
-/* --------------------------------------------------------------------- */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- sljit_s32 prev, fprev, saved_regs_size, i, tmp;
- sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options);
- sljit_ins offs;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
- set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
-
- saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 2);
- saved_regs_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, SSIZE_OF(f64));
-
- local_size = (local_size + saved_regs_size + 0xf) & ~0xf;
- compiler->local_size = local_size;
-
- if (local_size <= 512) {
- FAIL_IF(push_inst(compiler, STP_PRE | RT(TMP_FP) | RT2(TMP_LR)
- | RN(SLJIT_SP) | (sljit_ins)((-(local_size >> 3) & 0x7f) << 15)));
- offs = (sljit_ins)(local_size - 2 * SSIZE_OF(sw)) << (15 - 3);
- local_size = 0;
- } else {
- saved_regs_size = ((saved_regs_size - 2 * SSIZE_OF(sw)) + 0xf) & ~0xf;
-
- FAIL_IF(push_inst(compiler, SUBI | RD(SLJIT_SP) | RN(SLJIT_SP) | ((sljit_ins)saved_regs_size << 10)));
- offs = (sljit_ins)(saved_regs_size - 2 * SSIZE_OF(sw)) << (15 - 3);
- local_size -= saved_regs_size;
- SLJIT_ASSERT(local_size > 0);
- }
-
- prev = -1;
-
- tmp = SLJIT_S0 - saveds;
- for (i = SLJIT_S0 - saved_arg_count; i > tmp; i--) {
- if (prev == -1) {
- prev = i;
- continue;
- }
- FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(SLJIT_SP) | offs));
- offs -= (sljit_ins)2 << 15;
- prev = -1;
- }
-
- for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
- if (prev == -1) {
- prev = i;
- continue;
- }
- FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(SLJIT_SP) | offs));
- offs -= (sljit_ins)2 << 15;
- prev = -1;
- }
-
- fprev = -1;
-
- tmp = SLJIT_FS0 - fsaveds;
- for (i = SLJIT_FS0; i > tmp; i--) {
- if (fprev == -1) {
- fprev = i;
- continue;
- }
- FAIL_IF(push_inst(compiler, STP_F64 | VT(fprev) | VT2(i) | RN(SLJIT_SP) | offs));
- offs -= (sljit_ins)2 << 15;
- fprev = -1;
- }
-
- for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
- if (fprev == -1) {
- fprev = i;
- continue;
- }
- FAIL_IF(push_inst(compiler, STP_F64 | VT(fprev) | VT2(i) | RN(SLJIT_SP) | offs));
- offs -= (sljit_ins)2 << 15;
- fprev = -1;
- }
-
- if (fprev != -1)
- FAIL_IF(push_inst(compiler, STRI_F64 | VT(fprev) | RN(SLJIT_SP) | (offs >> 5) | (1 << 10)));
-
- if (prev != -1)
- FAIL_IF(push_inst(compiler, STRI | RT(prev) | RN(SLJIT_SP) | (offs >> 5) | ((fprev == -1) ? (1 << 10) : 0)));
-
-
-#ifdef _WIN32
- if (local_size > 4096)
- FAIL_IF(push_inst(compiler, SUBI | RD(SLJIT_SP) | RN(SLJIT_SP) | (1 << 10) | (1 << 22)));
-#endif /* _WIN32 */
-
- if (!(options & SLJIT_ENTER_REG_ARG)) {
- arg_types >>= SLJIT_ARG_SHIFT;
- saved_arg_count = 0;
- tmp = SLJIT_R0;
-
- while (arg_types) {
- if ((arg_types & SLJIT_ARG_MASK) < SLJIT_ARG_TYPE_F64) {
- if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {
- FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S0 - saved_arg_count) | RN(TMP_ZERO) | RM(tmp)));
- saved_arg_count++;
- }
- tmp++;
- }
- arg_types >>= SLJIT_ARG_SHIFT;
- }
- }
-
-#ifdef _WIN32
- if (local_size > 4096) {
- if (local_size < 4 * 4096) {
- /* No need for a loop. */
-
- if (local_size >= 2 * 4096) {
- if (local_size >= 3 * 4096) {
- FAIL_IF(push_inst(compiler, LDRI | RT(TMP_ZERO) | RN(SLJIT_SP)));
- FAIL_IF(push_inst(compiler, SUBI | RD(SLJIT_SP) | RN(SLJIT_SP) | (1 << 10) | (1 << 22)));
- }
-
- FAIL_IF(push_inst(compiler, LDRI | RT(TMP_ZERO) | RN(SLJIT_SP)));
- FAIL_IF(push_inst(compiler, SUBI | RD(SLJIT_SP) | RN(SLJIT_SP) | (1 << 10) | (1 << 22)));
- }
- }
- else {
- FAIL_IF(push_inst(compiler, MOVZ | RD(TMP_REG1) | ((((sljit_ins)local_size >> 12) - 1) << 5)));
- FAIL_IF(push_inst(compiler, LDRI | RT(TMP_ZERO) | RN(SLJIT_SP)));
- FAIL_IF(push_inst(compiler, SUBI | RD(SLJIT_SP) | RN(SLJIT_SP) | (1 << 10) | (1 << 22)));
- FAIL_IF(push_inst(compiler, SUBI | (1 << 29) | RD(TMP_REG1) | RN(TMP_REG1) | (1 << 10)));
- FAIL_IF(push_inst(compiler, B_CC | ((((sljit_ins) -3) & 0x7ffff) << 5) | 0x1 /* not-equal */));
- }
-
- local_size &= 0xfff;
-
- if (local_size > 0)
- FAIL_IF(push_inst(compiler, LDRI | RT(TMP_ZERO) | RN(SLJIT_SP)));
- else
- FAIL_IF(push_inst(compiler, STP | RT(TMP_FP) | RT2(TMP_LR) | RN(SLJIT_SP)));
- }
-
- if (local_size > 0) {
- if (local_size <= 512)
- FAIL_IF(push_inst(compiler, STP_PRE | RT(TMP_FP) | RT2(TMP_LR)
- | RN(SLJIT_SP) | (sljit_ins)((-(local_size >> 3) & 0x7f) << 15)));
- else {
- if (local_size >= 4096)
- local_size = (1 << (22 - 10));
-
- FAIL_IF(push_inst(compiler, SUBI | RD(SLJIT_SP) | RN(SLJIT_SP) | ((sljit_ins)local_size << 10)));
- FAIL_IF(push_inst(compiler, STP | RT(TMP_FP) | RT2(TMP_LR) | RN(SLJIT_SP)));
- }
- }
-
-#else /* !_WIN32 */
-
- /* The local_size does not include saved registers size. */
- if (local_size != 0) {
- if (local_size > 0xfff) {
- FAIL_IF(push_inst(compiler, SUBI | RD(SLJIT_SP) | RN(SLJIT_SP) | (((sljit_ins)local_size >> 12) << 10) | (1 << 22)));
- local_size &= 0xfff;
- }
-
- if (local_size > 512 || local_size == 0) {
- if (local_size != 0)
- FAIL_IF(push_inst(compiler, SUBI | RD(SLJIT_SP) | RN(SLJIT_SP) | ((sljit_ins)local_size << 10)));
-
- FAIL_IF(push_inst(compiler, STP | RT(TMP_FP) | RT2(TMP_LR) | RN(SLJIT_SP)));
- } else
- FAIL_IF(push_inst(compiler, STP_PRE | RT(TMP_FP) | RT2(TMP_LR)
- | RN(SLJIT_SP) | (sljit_ins)((-(local_size >> 3) & 0x7f) << 15)));
- }
-
-#endif /* _WIN32 */
-
- return push_inst(compiler, ADDI | RD(TMP_FP) | RN(SLJIT_SP) | (0 << 10));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- sljit_s32 saved_regs_size;
-
- CHECK_ERROR();
- CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
- set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
-
- saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 2);
- saved_regs_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, SSIZE_OF(f64));
-
- compiler->local_size = (local_size + saved_regs_size + 0xf) & ~0xf;
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 is_return_to)
-{
- sljit_s32 local_size, prev, fprev, i, tmp;
- sljit_ins offs;
-
- local_size = compiler->local_size;
-
- if (!is_return_to) {
- if (local_size > 512 && local_size <= 512 + 496) {
- FAIL_IF(push_inst(compiler, LDP_POST | RT(TMP_FP) | RT2(TMP_LR)
- | RN(SLJIT_SP) | ((sljit_ins)(local_size - 512) << (15 - 3))));
- local_size = 512;
- } else
- FAIL_IF(push_inst(compiler, LDP | RT(TMP_FP) | RT2(TMP_LR) | RN(SLJIT_SP)));
- } else {
- if (local_size > 512 && local_size <= 512 + 248) {
- FAIL_IF(push_inst(compiler, LDRI_POST | RT(TMP_FP) | RN(SLJIT_SP) | ((sljit_ins)(local_size - 512) << 12)));
- local_size = 512;
- } else
- FAIL_IF(push_inst(compiler, LDRI | RT(TMP_FP) | RN(SLJIT_SP) | 0));
- }
-
- if (local_size > 512) {
- local_size -= 512;
- if (local_size > 0xfff) {
- FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(SLJIT_SP)
- | (((sljit_ins)local_size >> 12) << 10) | (1 << 22)));
- local_size &= 0xfff;
- }
-
- FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(SLJIT_SP) | ((sljit_ins)local_size << 10)));
- local_size = 512;
- }
-
- offs = (sljit_ins)(local_size - 2 * SSIZE_OF(sw)) << (15 - 3);
- prev = -1;
-
- tmp = SLJIT_S0 - compiler->saveds;
- for (i = SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options); i > tmp; i--) {
- if (prev == -1) {
- prev = i;
- continue;
- }
- FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(SLJIT_SP) | offs));
- offs -= (sljit_ins)2 << 15;
- prev = -1;
- }
-
- for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
- if (prev == -1) {
- prev = i;
- continue;
- }
- FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(SLJIT_SP) | offs));
- offs -= (sljit_ins)2 << 15;
- prev = -1;
- }
-
- fprev = -1;
-
- tmp = SLJIT_FS0 - compiler->fsaveds;
- for (i = SLJIT_FS0; i > tmp; i--) {
- if (fprev == -1) {
- fprev = i;
- continue;
- }
- FAIL_IF(push_inst(compiler, LDP_F64 | VT(fprev) | VT2(i) | RN(SLJIT_SP) | offs));
- offs -= (sljit_ins)2 << 15;
- fprev = -1;
- }
-
- for (i = compiler->fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
- if (fprev == -1) {
- fprev = i;
- continue;
- }
- FAIL_IF(push_inst(compiler, LDP_F64 | VT(fprev) | VT2(i) | RN(SLJIT_SP) | offs));
- offs -= (sljit_ins)2 << 15;
- fprev = -1;
- }
-
- if (fprev != -1)
- FAIL_IF(push_inst(compiler, LDRI_F64 | VT(fprev) | RN(SLJIT_SP) | (offs >> 5) | (1 << 10)));
-
- if (prev != -1)
- FAIL_IF(push_inst(compiler, LDRI | RT(prev) | RN(SLJIT_SP) | (offs >> 5) | ((fprev == -1) ? (1 << 10) : 0)));
-
- /* This and the next call/jump instruction can be executed parallelly. */
- return push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(SLJIT_SP) | (sljit_ins)(local_size << 10));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_return_void(compiler));
-
- FAIL_IF(emit_stack_frame_release(compiler, 0));
-
- return push_inst(compiler, RET | RN(TMP_LR));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,
- sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_return_to(compiler, src, srcw));
-
- if (src & SLJIT_MEM) {
- ADJUST_LOCAL_OFFSET(src, srcw);
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1));
- src = TMP_REG1;
- srcw = 0;
- } else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
- FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(src)));
- src = TMP_REG1;
- srcw = 0;
- }
-
- FAIL_IF(emit_stack_frame_release(compiler, 1));
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);
-}
-
-/* --------------------------------------------------------------------- */
-/* Operators */
-/* --------------------------------------------------------------------- */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
-{
- sljit_ins inv_bits = (op & SLJIT_32) ? W_OP : 0;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op0(compiler, op));
-
- op = GET_OPCODE(op);
- switch (op) {
- case SLJIT_BREAKPOINT:
- return push_inst(compiler, BRK);
- case SLJIT_NOP:
- return push_inst(compiler, NOP);
- case SLJIT_LMUL_UW:
- case SLJIT_LMUL_SW:
- FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0)));
- FAIL_IF(push_inst(compiler, MADD | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO)));
- return push_inst(compiler, (op == SLJIT_LMUL_UW ? UMULH : SMULH) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));
- case SLJIT_DIVMOD_UW:
- case SLJIT_DIVMOD_SW:
- FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0)));
- FAIL_IF(push_inst(compiler, ((op == SLJIT_DIVMOD_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)));
- FAIL_IF(push_inst(compiler, (MADD ^ inv_bits) | RD(SLJIT_R1) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO)));
- return push_inst(compiler, (SUB ^ inv_bits) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));
- case SLJIT_DIV_UW:
- case SLJIT_DIV_SW:
- return push_inst(compiler, ((op == SLJIT_DIV_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1));
- case SLJIT_ENDBR:
- case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
- return SLJIT_SUCCESS;
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 dst_r, flags, mem_flags;
- sljit_s32 op_flags = GET_ALL_FLAGS(op);
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
-
- op = GET_OPCODE(op);
- if (op >= SLJIT_MOV && op <= SLJIT_MOV_P) {
- /* Both operands are registers. */
- if (dst_r != TMP_REG1 && FAST_IS_REG(src))
- return emit_op_imm(compiler, op | ((op_flags & SLJIT_32) ? INT_OP : 0), dst_r, TMP_REG1, src);
-
- switch (op) {
- case SLJIT_MOV:
- case SLJIT_MOV_P:
- mem_flags = WORD_SIZE;
- break;
- case SLJIT_MOV_U8:
- mem_flags = BYTE_SIZE;
- if (src & SLJIT_IMM)
- srcw = (sljit_u8)srcw;
- break;
- case SLJIT_MOV_S8:
- mem_flags = BYTE_SIZE | SIGNED;
- if (src & SLJIT_IMM)
- srcw = (sljit_s8)srcw;
- break;
- case SLJIT_MOV_U16:
- mem_flags = HALF_SIZE;
- if (src & SLJIT_IMM)
- srcw = (sljit_u16)srcw;
- break;
- case SLJIT_MOV_S16:
- mem_flags = HALF_SIZE | SIGNED;
- if (src & SLJIT_IMM)
- srcw = (sljit_s16)srcw;
- break;
- case SLJIT_MOV_U32:
- mem_flags = INT_SIZE;
- if (src & SLJIT_IMM)
- srcw = (sljit_u32)srcw;
- break;
- case SLJIT_MOV_S32:
- case SLJIT_MOV32:
- mem_flags = INT_SIZE | SIGNED;
- if (src & SLJIT_IMM)
- srcw = (sljit_s32)srcw;
- break;
- default:
- SLJIT_UNREACHABLE();
- mem_flags = 0;
- break;
- }
-
- if (src & SLJIT_IMM)
- FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG1, srcw));
- else if (!(src & SLJIT_MEM))
- dst_r = src;
- else
- FAIL_IF(emit_op_mem(compiler, mem_flags, dst_r, src, srcw, TMP_REG1));
-
- if (dst & SLJIT_MEM)
- return emit_op_mem(compiler, mem_flags | STORE, dst_r, dst, dstw, TMP_REG2);
- return SLJIT_SUCCESS;
- }
-
- flags = HAS_FLAGS(op_flags) ? SET_FLAGS : 0;
- mem_flags = WORD_SIZE;
-
- if (op_flags & SLJIT_32) {
- flags |= INT_OP;
- mem_flags = INT_SIZE;
- }
-
- if (src & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, mem_flags, TMP_REG2, src, srcw, TMP_REG2));
- src = TMP_REG2;
- }
-
- emit_op_imm(compiler, flags | op, dst_r, TMP_REG1, src);
-
- if (SLJIT_UNLIKELY(dst & SLJIT_MEM))
- return emit_op_mem(compiler, mem_flags | STORE, dst_r, dst, dstw, TMP_REG2);
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 dst_r, flags, mem_flags;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
- flags = HAS_FLAGS(op) ? SET_FLAGS : 0;
- mem_flags = WORD_SIZE;
-
- if (op & SLJIT_32) {
- flags |= INT_OP;
- mem_flags = INT_SIZE;
- }
-
- if (dst == TMP_REG1)
- flags |= UNUSED_RETURN;
-
- if (src1 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, mem_flags, TMP_REG1, src1, src1w, TMP_REG1));
- src1 = TMP_REG1;
- }
-
- if (src2 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, mem_flags, TMP_REG2, src2, src2w, TMP_REG2));
- src2 = TMP_REG2;
- }
-
- if (src1 & SLJIT_IMM)
- flags |= ARG1_IMM;
- else
- src1w = src1;
-
- if (src2 & SLJIT_IMM)
- flags |= ARG2_IMM;
- else
- src2w = src2;
-
- emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src1w, src2w);
-
- if (dst & SLJIT_MEM)
- return emit_op_mem(compiler, mem_flags | STORE, dst_r, dst, dstw, TMP_REG2);
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_op2(compiler, op, TMP_REG1, 0, src1, src1w, src2, src2w);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src_dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_ins inv_bits, imm;
- sljit_s32 is_left;
- sljit_sw mask;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w));
-
- is_left = (GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_MSHL);
-
- if (src_dst == src1) {
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), src_dst, 0, src_dst, 0, src2, src2w);
- }
-
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- inv_bits = (op & SLJIT_32) ? W_OP : 0;
- mask = inv_bits ? 0x1f : 0x3f;
-
- if (src2 & SLJIT_IMM) {
- src2w &= mask;
-
- if (src2w == 0)
- return SLJIT_SUCCESS;
- } else if (src2 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, inv_bits ? INT_SIZE : WORD_SIZE, TMP_REG2, src2, src2w, TMP_REG2));
- src2 = TMP_REG2;
- }
-
- if (src1 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, inv_bits ? INT_SIZE : WORD_SIZE, TMP_REG1, src1, src1w, TMP_REG1));
- src1 = TMP_REG1;
- } else if (src1 & SLJIT_IMM) {
- FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
- src1 = TMP_REG1;
- }
-
- if (src2 & SLJIT_IMM) {
- if (is_left)
- src2w = (src2w ^ mask) + 1;
-
- return push_inst(compiler, (EXTR ^ (inv_bits | (inv_bits >> 9))) | RD(src_dst)
- | RN(is_left ? src_dst : src1) | RM(is_left ? src1 : src_dst) | ((sljit_ins)src2w << 10));
- }
-
- FAIL_IF(push_inst(compiler, ((is_left ? LSLV : LSRV) ^ inv_bits) | RD(src_dst) | RN(src_dst) | RM(src2)));
-
- if (!(op & SLJIT_SHIFT_INTO_NON_ZERO)) {
- /* Shift left/right by 1. */
- if (is_left)
- imm = (sljit_ins)(inv_bits ? ((1 << 16) | (31 << 10)) : ((1 << 16) | (63 << 10) | (1 << 22)));
- else
- imm = (sljit_ins)(inv_bits ? ((31 << 16) | (30 << 10)) : ((63 << 16) | (62 << 10) | (1 << 22)));
-
- FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(TMP_REG1) | RN(src1) | imm));
-
- /* Set imm to mask. */
- imm = (sljit_ins)(inv_bits ? (4 << 10) : ((5 << 10) | (1 << 22)));
- FAIL_IF(push_inst(compiler, (EORI ^ inv_bits) | RD(TMP_REG2) | RN(src2) | imm));
-
- src1 = TMP_REG1;
- } else
- FAIL_IF(push_inst(compiler, (SUB ^ inv_bits) | RD(TMP_REG2) | RN(TMP_ZERO) | RM(src2)));
-
- FAIL_IF(push_inst(compiler, ((is_left ? LSRV : LSLV) ^ inv_bits) | RD(TMP_REG1) | RN(src1) | RM(TMP_REG2)));
- return push_inst(compiler, (ORR ^ inv_bits) | RD(src_dst) | RN(src_dst) | RM(TMP_REG1));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- switch (op) {
- case SLJIT_FAST_RETURN:
- if (FAST_IS_REG(src))
- FAIL_IF(push_inst(compiler, ORR | RD(TMP_LR) | RN(TMP_ZERO) | RM(src)));
- else
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_LR, src, srcw, TMP_REG1));
-
- return push_inst(compiler, RET | RN(TMP_LR));
- case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
- return SLJIT_SUCCESS;
- case SLJIT_PREFETCH_L1:
- case SLJIT_PREFETCH_L2:
- case SLJIT_PREFETCH_L3:
- case SLJIT_PREFETCH_ONCE:
- SLJIT_ASSERT(reg_map[1] == 0 && reg_map[3] == 2 && reg_map[5] == 4);
-
- /* The reg_map[op] should provide the appropriate constant. */
- if (op == SLJIT_PREFETCH_L1)
- op = 1;
- else if (op == SLJIT_PREFETCH_L2)
- op = 3;
- else if (op == SLJIT_PREFETCH_L3)
- op = 5;
- else
- op = 2;
-
- /* Signed word sized load is the prefetch instruction. */
- return emit_op_mem(compiler, WORD_SIZE | SIGNED, op, src, srcw, TMP_REG1);
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
-{
- CHECK_REG_INDEX(check_sljit_get_register_index(reg));
- return reg_map[reg];
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
-{
- CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
- return freg_map[reg];
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
- void *instruction, sljit_u32 size)
-{
- SLJIT_UNUSED_ARG(size);
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
-
- return push_inst(compiler, *(sljit_ins*)instruction);
-}
-
-/* --------------------------------------------------------------------- */
-/* Floating point operators */
-/* --------------------------------------------------------------------- */
-
-static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
-{
- sljit_u32 shift = MEM_SIZE_SHIFT(flags);
- sljit_ins type = (shift << 30);
-
- SLJIT_ASSERT(arg & SLJIT_MEM);
-
- if (!(flags & STORE))
- type |= 0x00400000;
-
- if (arg & OFFS_REG_MASK) {
- argw &= 3;
- if (argw == 0 || argw == shift)
- return push_inst(compiler, STR_FR | type | VT(reg)
- | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw ? (1 << 12) : 0));
-
- FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | ((sljit_ins)argw << 10)));
- return push_inst(compiler, STR_FI | type | VT(reg) | RN(TMP_REG1));
- }
-
- arg &= REG_MASK;
-
- if (!arg) {
- FAIL_IF(load_immediate(compiler, TMP_REG1, argw & ~(0xfff << shift)));
-
- argw = (argw >> shift) & 0xfff;
-
- return push_inst(compiler, STR_FI | type | VT(reg) | RN(TMP_REG1) | ((sljit_ins)argw << 10));
- }
-
- if (argw >= 0 && (argw & ((1 << shift) - 1)) == 0) {
- if ((argw >> shift) <= 0xfff)
- return push_inst(compiler, STR_FI | type | VT(reg) | RN(arg) | ((sljit_ins)argw << (10 - shift)));
-
- if (argw <= 0xffffff) {
- FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(TMP_REG1) | RN(arg) | (((sljit_ins)argw >> 12) << 10)));
-
- argw = ((argw & 0xfff) >> shift);
- return push_inst(compiler, STR_FI | type | VT(reg) | RN(TMP_REG1) | ((sljit_ins)argw << 10));
- }
- }
-
- if (argw <= 255 && argw >= -256)
- return push_inst(compiler, STUR_FI | type | VT(reg) | RN(arg) | (((sljit_ins)argw & 0x1ff) << 12));
-
- FAIL_IF(load_immediate(compiler, TMP_REG1, argw));
- return push_inst(compiler, STR_FR | type | VT(reg) | RN(arg) | RM(TMP_REG1));
-}
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
- sljit_ins inv_bits = (op & SLJIT_32) ? (1 << 22) : 0;
-
- if (GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64)
- inv_bits |= W_OP;
-
- if (src & SLJIT_MEM) {
- emit_fop_mem(compiler, (op & SLJIT_32) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src, srcw);
- src = TMP_FREG1;
- }
-
- FAIL_IF(push_inst(compiler, (FCVTZS ^ inv_bits) | RD(dst_r) | VN(src)));
-
- if (dst & SLJIT_MEM)
- return emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) ? INT_SIZE : WORD_SIZE) | STORE, TMP_REG1, dst, dstw, TMP_REG2);
- return SLJIT_SUCCESS;
-}
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
- sljit_ins inv_bits = (op & SLJIT_32) ? (1 << 22) : 0;
-
- if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
- inv_bits |= W_OP;
-
- if (src & SLJIT_MEM) {
- emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) ? INT_SIZE : WORD_SIZE), TMP_REG1, src, srcw, TMP_REG1);
- src = TMP_REG1;
- } else if (src & SLJIT_IMM) {
- if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
- srcw = (sljit_s32)srcw;
-
- FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
- src = TMP_REG1;
- }
-
- FAIL_IF(push_inst(compiler, (SCVTF ^ inv_bits) | VD(dst_r) | RN(src)));
-
- if (dst & SLJIT_MEM)
- return emit_fop_mem(compiler, ((op & SLJIT_32) ? INT_SIZE : WORD_SIZE) | STORE, TMP_FREG1, dst, dstw);
- return SLJIT_SUCCESS;
-}
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 mem_flags = (op & SLJIT_32) ? INT_SIZE : WORD_SIZE;
- sljit_ins inv_bits = (op & SLJIT_32) ? (1 << 22) : 0;
-
- if (src1 & SLJIT_MEM) {
- emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w);
- src1 = TMP_FREG1;
- }
-
- if (src2 & SLJIT_MEM) {
- emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w);
- src2 = TMP_FREG2;
- }
-
- return push_inst(compiler, (FCMP ^ inv_bits) | VN(src1) | VM(src2));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 dst_r, mem_flags = (op & SLJIT_32) ? INT_SIZE : WORD_SIZE;
- sljit_ins inv_bits;
-
- CHECK_ERROR();
-
- SLJIT_COMPILE_ASSERT((INT_SIZE ^ 0x1) == WORD_SIZE, must_be_one_bit_difference);
- SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
-
- inv_bits = (op & SLJIT_32) ? (1 << 22) : 0;
- dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
-
- if (src & SLJIT_MEM) {
- emit_fop_mem(compiler, (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) ? (mem_flags ^ 0x1) : mem_flags, dst_r, src, srcw);
- src = dst_r;
- }
-
- switch (GET_OPCODE(op)) {
- case SLJIT_MOV_F64:
- if (src != dst_r) {
- if (dst_r != TMP_FREG1)
- FAIL_IF(push_inst(compiler, (FMOV ^ inv_bits) | VD(dst_r) | VN(src)));
- else
- dst_r = src;
- }
- break;
- case SLJIT_NEG_F64:
- FAIL_IF(push_inst(compiler, (FNEG ^ inv_bits) | VD(dst_r) | VN(src)));
- break;
- case SLJIT_ABS_F64:
- FAIL_IF(push_inst(compiler, (FABS ^ inv_bits) | VD(dst_r) | VN(src)));
- break;
- case SLJIT_CONV_F64_FROM_F32:
- FAIL_IF(push_inst(compiler, FCVT | (sljit_ins)((op & SLJIT_32) ? (1 << 22) : (1 << 15)) | VD(dst_r) | VN(src)));
- break;
- }
-
- if (dst & SLJIT_MEM)
- return emit_fop_mem(compiler, mem_flags | STORE, dst_r, dst, dstw);
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 dst_r, mem_flags = (op & SLJIT_32) ? INT_SIZE : WORD_SIZE;
- sljit_ins inv_bits = (op & SLJIT_32) ? (1 << 22) : 0;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
- if (src1 & SLJIT_MEM) {
- emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w);
- src1 = TMP_FREG1;
- }
- if (src2 & SLJIT_MEM) {
- emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w);
- src2 = TMP_FREG2;
- }
-
- switch (GET_OPCODE(op)) {
- case SLJIT_ADD_F64:
- FAIL_IF(push_inst(compiler, (FADD ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
- break;
- case SLJIT_SUB_F64:
- FAIL_IF(push_inst(compiler, (FSUB ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
- break;
- case SLJIT_MUL_F64:
- FAIL_IF(push_inst(compiler, (FMUL ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
- break;
- case SLJIT_DIV_F64:
- FAIL_IF(push_inst(compiler, (FDIV ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
- break;
- }
-
- if (!(dst & SLJIT_MEM))
- return SLJIT_SUCCESS;
- return emit_fop_mem(compiler, mem_flags | STORE, TMP_FREG1, dst, dstw);
-}
-
-/* --------------------------------------------------------------------- */
-/* Other instructions */
-/* --------------------------------------------------------------------- */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- if (FAST_IS_REG(dst))
- return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(TMP_LR));
-
- /* Memory. */
- return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_LR, dst, dstw, TMP_REG1);
-}
-
-/* --------------------------------------------------------------------- */
-/* Conditional instructions */
-/* --------------------------------------------------------------------- */
-
-static sljit_ins get_cc(struct sljit_compiler *compiler, sljit_s32 type)
-{
- switch (type) {
- case SLJIT_EQUAL:
- case SLJIT_F_EQUAL:
- case SLJIT_ORDERED_EQUAL:
- case SLJIT_UNORDERED_OR_EQUAL: /* Not supported. */
- return 0x1;
-
- case SLJIT_NOT_EQUAL:
- case SLJIT_F_NOT_EQUAL:
- case SLJIT_UNORDERED_OR_NOT_EQUAL:
- case SLJIT_ORDERED_NOT_EQUAL: /* Not supported. */
- return 0x0;
-
- case SLJIT_CARRY:
- if (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_ADD)
- return 0x3;
- /* fallthrough */
-
- case SLJIT_LESS:
- return 0x2;
-
- case SLJIT_NOT_CARRY:
- if (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_ADD)
- return 0x2;
- /* fallthrough */
-
- case SLJIT_GREATER_EQUAL:
- return 0x3;
-
- case SLJIT_GREATER:
- case SLJIT_UNORDERED_OR_GREATER:
- return 0x9;
-
- case SLJIT_LESS_EQUAL:
- case SLJIT_F_LESS_EQUAL:
- case SLJIT_ORDERED_LESS_EQUAL:
- return 0x8;
-
- case SLJIT_SIG_LESS:
- case SLJIT_UNORDERED_OR_LESS:
- return 0xa;
-
- case SLJIT_SIG_GREATER_EQUAL:
- case SLJIT_F_GREATER_EQUAL:
- case SLJIT_ORDERED_GREATER_EQUAL:
- return 0xb;
-
- case SLJIT_SIG_GREATER:
- case SLJIT_F_GREATER:
- case SLJIT_ORDERED_GREATER:
- return 0xd;
-
- case SLJIT_SIG_LESS_EQUAL:
- case SLJIT_UNORDERED_OR_LESS_EQUAL:
- return 0xc;
-
- case SLJIT_OVERFLOW:
- if (!(compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)))
- return 0x0;
- /* fallthrough */
-
- case SLJIT_UNORDERED:
- return 0x7;
-
- case SLJIT_NOT_OVERFLOW:
- if (!(compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)))
- return 0x1;
- /* fallthrough */
-
- case SLJIT_ORDERED:
- return 0x6;
-
- case SLJIT_F_LESS:
- case SLJIT_ORDERED_LESS:
- return 0x5;
-
- case SLJIT_UNORDERED_OR_GREATER_EQUAL:
- return 0x4;
-
- default:
- SLJIT_UNREACHABLE();
- return 0xe;
- }
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
-{
- struct sljit_label *label;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_label(compiler));
-
- if (compiler->last_label && compiler->last_label->size == compiler->size)
- return compiler->last_label;
-
- label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
- PTR_FAIL_IF(!label);
- set_label(label, compiler);
- return label;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
-{
- struct sljit_jump *jump;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_jump(compiler, type));
-
- jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
- PTR_FAIL_IF(!jump);
- set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
- type &= 0xff;
-
- if (type < SLJIT_JUMP) {
- jump->flags |= IS_COND;
- PTR_FAIL_IF(push_inst(compiler, B_CC | (6 << 5) | get_cc(compiler, type)));
- }
- else if (type >= SLJIT_FAST_CALL)
- jump->flags |= IS_BL;
-
- PTR_FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0));
- jump->addr = compiler->size;
- PTR_FAIL_IF(push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1)));
-
- return jump;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types)
-{
- SLJIT_UNUSED_ARG(arg_types);
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
-
- if (type & SLJIT_CALL_RETURN) {
- PTR_FAIL_IF(emit_stack_frame_release(compiler, 0));
- type = SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP);
- }
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_jump(compiler, type);
-}
-
-static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 src, sljit_sw srcw)
-{
- struct sljit_jump *jump;
- sljit_ins inv_bits = (type & SLJIT_32) ? W_OP : 0;
-
- SLJIT_ASSERT((type & 0xff) == SLJIT_EQUAL || (type & 0xff) == SLJIT_NOT_EQUAL);
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
- PTR_FAIL_IF(!jump);
- set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
- jump->flags |= IS_CBZ | IS_COND;
-
- if (src & SLJIT_MEM) {
- PTR_FAIL_IF(emit_op_mem(compiler, inv_bits ? INT_SIZE : WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1));
- src = TMP_REG1;
- }
- else if (src & SLJIT_IMM) {
- PTR_FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
- src = TMP_REG1;
- }
-
- SLJIT_ASSERT(FAST_IS_REG(src));
-
- if ((type & 0xff) == SLJIT_EQUAL)
- inv_bits |= 1 << 24;
-
- PTR_FAIL_IF(push_inst(compiler, (CBZ ^ inv_bits) | (6 << 5) | RT(src)));
- PTR_FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0));
- jump->addr = compiler->size;
- PTR_FAIL_IF(push_inst(compiler, BR | RN(TMP_REG1)));
- return jump;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
-{
- struct sljit_jump *jump;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
-
- if (!(src & SLJIT_IMM)) {
- if (src & SLJIT_MEM) {
- ADJUST_LOCAL_OFFSET(src, srcw);
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1));
- src = TMP_REG1;
- }
- return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(src));
- }
-
- /* These jumps are converted to jump/call instructions when possible. */
- jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
- FAIL_IF(!jump);
- set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0));
- jump->u.target = (sljit_uw)srcw;
-
- FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0));
- jump->addr = compiler->size;
- return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types,
- sljit_s32 src, sljit_sw srcw)
-{
- SLJIT_UNUSED_ARG(arg_types);
- CHECK_ERROR();
- CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
-
- if (src & SLJIT_MEM) {
- ADJUST_LOCAL_OFFSET(src, srcw);
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1));
- src = TMP_REG1;
- }
-
- if (type & SLJIT_CALL_RETURN) {
- if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
- FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(src)));
- src = TMP_REG1;
- }
-
- FAIL_IF(emit_stack_frame_release(compiler, 0));
- type = SLJIT_JUMP;
- }
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_ijump(compiler, type, src, srcw);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 type)
-{
- sljit_s32 dst_r, src_r, flags, mem_flags;
- sljit_ins cc;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- cc = get_cc(compiler, type);
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
-
- if (GET_OPCODE(op) < SLJIT_ADD) {
- FAIL_IF(push_inst(compiler, CSINC | (cc << 12) | RD(dst_r) | RN(TMP_ZERO) | RM(TMP_ZERO)));
-
- if (dst_r == TMP_REG1) {
- mem_flags = (GET_OPCODE(op) == SLJIT_MOV ? WORD_SIZE : INT_SIZE) | STORE;
- return emit_op_mem(compiler, mem_flags, TMP_REG1, dst, dstw, TMP_REG2);
- }
-
- return SLJIT_SUCCESS;
- }
-
- flags = HAS_FLAGS(op) ? SET_FLAGS : 0;
- mem_flags = WORD_SIZE;
-
- if (op & SLJIT_32) {
- flags |= INT_OP;
- mem_flags = INT_SIZE;
- }
-
- src_r = dst;
-
- if (dst & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, mem_flags, TMP_REG1, dst, dstw, TMP_REG1));
- src_r = TMP_REG1;
- }
-
- FAIL_IF(push_inst(compiler, CSINC | (cc << 12) | RD(TMP_REG2) | RN(TMP_ZERO) | RM(TMP_ZERO)));
- emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src_r, TMP_REG2);
-
- if (dst & SLJIT_MEM)
- return emit_op_mem(compiler, mem_flags | STORE, TMP_REG1, dst, dstw, TMP_REG2);
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 dst_reg,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_ins inv_bits = (type & SLJIT_32) ? W_OP : 0;
- sljit_ins cc;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
-
- if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
- if (type & SLJIT_32)
- srcw = (sljit_s32)srcw;
- FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
- src = TMP_REG1;
- srcw = 0;
- }
-
- cc = get_cc(compiler, type & ~SLJIT_32);
-
- return push_inst(compiler, (CSEL ^ inv_bits) | (cc << 12) | RD(dst_reg) | RN(dst_reg) | RM(src));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 reg,
- sljit_s32 mem, sljit_sw memw)
-{
- sljit_u32 inst;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
-
- if (!(reg & REG_PAIR_MASK))
- return sljit_emit_mem_unaligned(compiler, type, reg, mem, memw);
-
- ADJUST_LOCAL_OFFSET(mem, memw);
-
- if (!(mem & REG_MASK)) {
- FAIL_IF(load_immediate(compiler, TMP_REG1, memw & ~0x1f8));
-
- mem = SLJIT_MEM1(TMP_REG1);
- memw &= 0x1f8;
- } else if (mem & OFFS_REG_MASK) {
- FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RN(mem & REG_MASK) | RM(OFFS_REG(mem)) | ((sljit_ins)(memw & 0x3) << 10)));
-
- mem = SLJIT_MEM1(TMP_REG1);
- memw = 0;
- } else if ((memw & 0x7) != 0 || memw > 0x1f8 || memw < -0x200) {
- inst = ADDI;
-
- if (memw < 0) {
- /* Remains negative for integer min. */
- memw = -memw;
- inst = SUBI;
- } else if ((memw & 0x7) == 0 && memw <= 0x7ff0) {
- if (!(type & SLJIT_MEM_STORE) && (mem & REG_MASK) == REG_PAIR_FIRST(reg)) {
- FAIL_IF(push_inst(compiler, LDRI | RD(REG_PAIR_SECOND(reg)) | RN(mem & REG_MASK) | ((sljit_ins)memw << 7)));
- return push_inst(compiler, LDRI | RD(REG_PAIR_FIRST(reg)) | RN(mem & REG_MASK) | ((sljit_ins)(memw + 0x8) << 7));
- }
-
- inst = (type & SLJIT_MEM_STORE) ? STRI : LDRI;
-
- FAIL_IF(push_inst(compiler, inst | RD(REG_PAIR_FIRST(reg)) | RN(mem & REG_MASK) | ((sljit_ins)memw << 7)));
- return push_inst(compiler, inst | RD(REG_PAIR_SECOND(reg)) | RN(mem & REG_MASK) | ((sljit_ins)(memw + 0x8) << 7));
- }
-
- if ((sljit_uw)memw <= 0xfff) {
- FAIL_IF(push_inst(compiler, inst | RD(TMP_REG1) | RN(mem & REG_MASK) | ((sljit_ins)memw << 10)));
- memw = 0;
- } else if ((sljit_uw)memw <= 0xffffff) {
- FAIL_IF(push_inst(compiler, inst | (1 << 22) | RD(TMP_REG1) | RN(mem & REG_MASK) | (((sljit_ins)memw >> 12) << 10)));
-
- if ((memw & 0xe07) != 0) {
- FAIL_IF(push_inst(compiler, inst | RD(TMP_REG1) | RN(TMP_REG1) | (((sljit_ins)memw & 0xfff) << 10)));
- memw = 0;
- } else {
- memw &= 0xfff;
- }
- } else {
- FAIL_IF(load_immediate(compiler, TMP_REG1, memw));
- FAIL_IF(push_inst(compiler, (inst == ADDI ? ADD : SUB) | RD(TMP_REG1) | RN(mem & REG_MASK) | RM(TMP_REG1)));
- memw = 0;
- }
-
- mem = SLJIT_MEM1(TMP_REG1);
-
- if (inst == SUBI)
- memw = -memw;
- }
-
- SLJIT_ASSERT((memw & 0x7) == 0 && memw <= 0x1f8 && memw >= -0x200);
- return push_inst(compiler, ((type & SLJIT_MEM_STORE) ? STP : LDP) | RT(REG_PAIR_FIRST(reg)) | RT2(REG_PAIR_SECOND(reg)) | RN(mem & REG_MASK) | (sljit_ins)((memw & 0x3f8) << 12));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 reg,
- sljit_s32 mem, sljit_sw memw)
-{
- sljit_u32 sign = 0, inst;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_mem_update(compiler, type, reg, mem, memw));
-
- if ((mem & OFFS_REG_MASK) || (memw > 255 || memw < -256))
- return SLJIT_ERR_UNSUPPORTED;
-
- if (type & SLJIT_MEM_SUPP)
- return SLJIT_SUCCESS;
-
- switch (type & 0xff) {
- case SLJIT_MOV:
- case SLJIT_MOV_P:
- inst = STURBI | (MEM_SIZE_SHIFT(WORD_SIZE) << 30) | 0x400;
- break;
- case SLJIT_MOV_S8:
- sign = 1;
- /* fallthrough */
- case SLJIT_MOV_U8:
- inst = STURBI | (MEM_SIZE_SHIFT(BYTE_SIZE) << 30) | 0x400;
- break;
- case SLJIT_MOV_S16:
- sign = 1;
- /* fallthrough */
- case SLJIT_MOV_U16:
- inst = STURBI | (MEM_SIZE_SHIFT(HALF_SIZE) << 30) | 0x400;
- break;
- case SLJIT_MOV_S32:
- sign = 1;
- /* fallthrough */
- case SLJIT_MOV_U32:
- case SLJIT_MOV32:
- inst = STURBI | (MEM_SIZE_SHIFT(INT_SIZE) << 30) | 0x400;
- break;
- default:
- SLJIT_UNREACHABLE();
- inst = STURBI | (MEM_SIZE_SHIFT(WORD_SIZE) << 30) | 0x400;
- break;
- }
-
- if (!(type & SLJIT_MEM_STORE))
- inst |= sign ? 0x00800000 : 0x00400000;
-
- if (!(type & SLJIT_MEM_POST))
- inst |= 0x800;
-
- return push_inst(compiler, inst | RT(reg) | RN(mem & REG_MASK) | (sljit_ins)((memw & 0x1ff) << 12));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 freg,
- sljit_s32 mem, sljit_sw memw)
-{
- sljit_u32 inst;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_fmem_update(compiler, type, freg, mem, memw));
-
- if ((mem & OFFS_REG_MASK) || (memw > 255 || memw < -256))
- return SLJIT_ERR_UNSUPPORTED;
-
- if (type & SLJIT_MEM_SUPP)
- return SLJIT_SUCCESS;
-
- inst = STUR_FI | 0x80000400;
-
- if (!(type & SLJIT_32))
- inst |= 0x40000000;
-
- if (!(type & SLJIT_MEM_STORE))
- inst |= 0x00400000;
-
- if (!(type & SLJIT_MEM_POST))
- inst |= 0x800;
-
- return push_inst(compiler, inst | VT(freg) | RN(mem & REG_MASK) | (sljit_ins)((memw & 0x1ff) << 12));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
-{
- sljit_s32 dst_reg;
- sljit_ins ins;
-
- CHECK_ERROR();
- CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset));
- ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset);
-
- dst_reg = FAST_IS_REG(dst) ? dst : TMP_REG1;
-
- /* Not all instruction forms support accessing SP register. */
- if (offset <= 0xffffff && offset >= -0xffffff) {
- ins = ADDI;
- if (offset < 0) {
- offset = -offset;
- ins = SUBI;
- }
-
- if (offset <= 0xfff)
- FAIL_IF(push_inst(compiler, ins | RD(dst_reg) | RN(SLJIT_SP) | (sljit_ins)(offset << 10)));
- else {
- FAIL_IF(push_inst(compiler, ins | RD(dst_reg) | RN(SLJIT_SP) | (sljit_ins)((offset & 0xfff000) >> (12 - 10)) | (1 << 22)));
-
- offset &= 0xfff;
- if (offset != 0)
- FAIL_IF(push_inst(compiler, ins | RD(dst_reg) | RN(dst_reg) | (sljit_ins)(offset << 10)));
- }
- }
- else {
- FAIL_IF(load_immediate (compiler, dst_reg, offset));
- /* Add extended register form. */
- FAIL_IF(push_inst(compiler, ADDE | (0x3 << 13) | RD(dst_reg) | RN(SLJIT_SP) | RM(dst_reg)));
- }
-
- if (SLJIT_UNLIKELY(dst & SLJIT_MEM))
- return emit_op_mem(compiler, WORD_SIZE | STORE, dst_reg, dst, dstw, TMP_REG1);
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
-{
- struct sljit_const *const_;
- sljit_s32 dst_r;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
- PTR_FAIL_IF(!const_);
- set_const(const_, compiler);
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
- PTR_FAIL_IF(emit_imm64_const(compiler, dst_r, (sljit_uw)init_value));
-
- if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2));
- return const_;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
-{
- struct sljit_put_label *put_label;
- sljit_s32 dst_r;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
- PTR_FAIL_IF(emit_imm64_const(compiler, dst_r, 0));
-
- put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
- PTR_FAIL_IF(!put_label);
- set_put_label(put_label, compiler, 1);
-
- if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2));
-
- return put_label;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
-{
- sljit_ins* inst = (sljit_ins*)addr;
- sljit_u32 dst;
- SLJIT_UNUSED_ARG(executable_offset);
-
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 0);
-
- dst = inst[0] & 0x1f;
- SLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ && (inst[1] & 0xffe00000) == (MOVK | (1 << 21)));
- inst[0] = MOVZ | dst | (((sljit_u32)new_target & 0xffff) << 5);
- inst[1] = MOVK | dst | (((sljit_u32)(new_target >> 16) & 0xffff) << 5) | (1 << 21);
- inst[2] = MOVK | dst | (((sljit_u32)(new_target >> 32) & 0xffff) << 5) | (2 << 21);
- inst[3] = MOVK | dst | ((sljit_u32)(new_target >> 48) << 5) | (3 << 21);
-
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 1);
- inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 4);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
-{
- sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
-}
diff --git a/contrib/libs/pcre2/src/sljit/sljitNativeARM_T2_32.c b/contrib/libs/pcre2/src/sljit/sljitNativeARM_T2_32.c
deleted file mode 100644
index 7d6bac077e..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitNativeARM_T2_32.c
+++ /dev/null
@@ -1,3150 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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.
- */
-
-SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
-{
-#ifdef __SOFTFP__
- return "ARM-Thumb2" SLJIT_CPUINFO " ABI:softfp";
-#else
- return "ARM-Thumb2" SLJIT_CPUINFO " ABI:hardfp";
-#endif
-}
-
-/* Length of an instruction word. */
-typedef sljit_u32 sljit_ins;
-
-/* Last register + 1. */
-#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
-#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
-#define TMP_PC (SLJIT_NUMBER_OF_REGISTERS + 4)
-
-#define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
-#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
-
-/* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */
-static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
- 0, 0, 1, 2, 3, 11, 10, 9, 8, 7, 6, 5, 4, 13, 12, 14, 15
-};
-
-static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
- 0, 0, 1, 2, 3, 4, 5, 15, 14, 13, 12, 11, 10, 9, 8, 6, 7
-};
-
-#define COPY_BITS(src, from, to, bits) \
- ((from >= to ? ((sljit_ins)(src) >> (from - to)) : ((sljit_ins)(src) << (to - from))) & (((1 << bits) - 1) << to))
-
-#define NEGATE(uimm) ((sljit_uw)-(sljit_sw)(uimm))
-
-/* Thumb16 encodings. */
-#define RD3(rd) ((sljit_ins)reg_map[rd])
-#define RN3(rn) ((sljit_ins)reg_map[rn] << 3)
-#define RM3(rm) ((sljit_ins)reg_map[rm] << 6)
-#define RDN3(rdn) ((sljit_ins)reg_map[rdn] << 8)
-#define IMM3(imm) ((sljit_ins)imm << 6)
-#define IMM8(imm) ((sljit_ins)imm)
-
-/* Thumb16 helpers. */
-#define SET_REGS44(rd, rn) \
- (((sljit_ins)reg_map[rn] << 3) | ((sljit_ins)reg_map[rd] & 0x7) | (((sljit_ins)reg_map[rd] & 0x8) << 4))
-#define IS_2_LO_REGS(reg1, reg2) \
- (reg_map[reg1] <= 7 && reg_map[reg2] <= 7)
-#define IS_3_LO_REGS(reg1, reg2, reg3) \
- (reg_map[reg1] <= 7 && reg_map[reg2] <= 7 && reg_map[reg3] <= 7)
-
-/* Thumb32 encodings. */
-#define RD4(rd) ((sljit_ins)reg_map[rd] << 8)
-#define RN4(rn) ((sljit_ins)reg_map[rn] << 16)
-#define RM4(rm) ((sljit_ins)reg_map[rm])
-#define RT4(rt) ((sljit_ins)reg_map[rt] << 12)
-#define DD4(dd) ((sljit_ins)freg_map[dd] << 12)
-#define DN4(dn) ((sljit_ins)freg_map[dn] << 16)
-#define DM4(dm) ((sljit_ins)freg_map[dm])
-#define IMM5(imm) \
- (COPY_BITS(imm, 2, 12, 3) | (((sljit_ins)imm & 0x3) << 6))
-#define IMM12(imm) \
- (COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | ((sljit_ins)imm & 0xff))
-
-/* --------------------------------------------------------------------- */
-/* Instrucion forms */
-/* --------------------------------------------------------------------- */
-
-/* dot '.' changed to _
- I immediate form (possibly followed by number of immediate bits). */
-#define ADCI 0xf1400000
-#define ADCS 0x4140
-#define ADC_W 0xeb400000
-#define ADD 0x4400
-#define ADDS 0x1800
-#define ADDSI3 0x1c00
-#define ADDSI8 0x3000
-#define ADDWI 0xf2000000
-#define ADD_SP 0x4485
-#define ADD_SP_I 0xb000
-#define ADD_W 0xeb000000
-#define ADD_WI 0xf1000000
-#define ANDI 0xf0000000
-#define ANDS 0x4000
-#define AND_W 0xea000000
-#define ASRS 0x4100
-#define ASRSI 0x1000
-#define ASR_W 0xfa40f000
-#define ASR_WI 0xea4f0020
-#define BCC 0xd000
-#define BICI 0xf0200000
-#define BKPT 0xbe00
-#define BLX 0x4780
-#define BX 0x4700
-#define CLZ 0xfab0f080
-#define CMNI_W 0xf1100f00
-#define CMP 0x4280
-#define CMPI 0x2800
-#define CMPI_W 0xf1b00f00
-#define CMP_X 0x4500
-#define CMP_W 0xebb00f00
-#define EORI 0xf0800000
-#define EORS 0x4040
-#define EOR_W 0xea800000
-#define IT 0xbf00
-#define LDR_SP 0x9800
-#define LDR 0xf8d00000
-#define LDRD 0xe9500000
-#define LDRI 0xf8500800
-#define LSLS 0x4080
-#define LSLSI 0x0000
-#define LSL_W 0xfa00f000
-#define LSL_WI 0xea4f0000
-#define LSRS 0x40c0
-#define LSRSI 0x0800
-#define LSR_W 0xfa20f000
-#define LSR_WI 0xea4f0010
-#define MOV 0x4600
-#define MOVS 0x0000
-#define MOVSI 0x2000
-#define MOVT 0xf2c00000
-#define MOVW 0xf2400000
-#define MOV_W 0xea4f0000
-#define MOV_WI 0xf04f0000
-#define MUL 0xfb00f000
-#define MVNS 0x43c0
-#define MVN_W 0xea6f0000
-#define MVN_WI 0xf06f0000
-#define NOP 0xbf00
-#define ORNI 0xf0600000
-#define ORRI 0xf0400000
-#define ORRS 0x4300
-#define ORR_W 0xea400000
-#define POP 0xbc00
-#define POP_W 0xe8bd0000
-#define PUSH 0xb400
-#define PUSH_W 0xe92d0000
-#define RBIT 0xfa90f0a0
-#define RORS 0x41c0
-#define ROR_W 0xfa60f000
-#define ROR_WI 0xea4f0030
-#define RSB_WI 0xf1c00000
-#define RSBSI 0x4240
-#define SBCI 0xf1600000
-#define SBCS 0x4180
-#define SBC_W 0xeb600000
-#define SDIV 0xfb90f0f0
-#define SMULL 0xfb800000
-#define STRD 0xe9400000
-#define STR_SP 0x9000
-#define SUBS 0x1a00
-#define SUBSI3 0x1e00
-#define SUBSI8 0x3800
-#define SUB_W 0xeba00000
-#define SUBWI 0xf2a00000
-#define SUB_SP_I 0xb080
-#define SUB_WI 0xf1a00000
-#define SXTB 0xb240
-#define SXTB_W 0xfa4ff080
-#define SXTH 0xb200
-#define SXTH_W 0xfa0ff080
-#define TST 0x4200
-#define TSTI 0xf0000f00
-#define TST_W 0xea000f00
-#define UDIV 0xfbb0f0f0
-#define UMULL 0xfba00000
-#define UXTB 0xb2c0
-#define UXTB_W 0xfa5ff080
-#define UXTH 0xb280
-#define UXTH_W 0xfa1ff080
-#define VABS_F32 0xeeb00ac0
-#define VADD_F32 0xee300a00
-#define VCMP_F32 0xeeb40a40
-#define VCVT_F32_S32 0xeeb80ac0
-#define VCVT_F64_F32 0xeeb70ac0
-#define VCVT_S32_F32 0xeebd0ac0
-#define VDIV_F32 0xee800a00
-#define VLDR_F32 0xed100a00
-#define VMOV_F32 0xeeb00a40
-#define VMOV 0xee000a10
-#define VMOV2 0xec400a10
-#define VMRS 0xeef1fa10
-#define VMUL_F32 0xee200a00
-#define VNEG_F32 0xeeb10a40
-#define VPOP 0xecbd0b00
-#define VPUSH 0xed2d0b00
-#define VSTR_F32 0xed000a00
-#define VSUB_F32 0xee300a40
-
-static sljit_s32 push_inst16(struct sljit_compiler *compiler, sljit_ins inst)
-{
- sljit_u16 *ptr;
- SLJIT_ASSERT(!(inst & 0xffff0000));
-
- ptr = (sljit_u16*)ensure_buf(compiler, sizeof(sljit_u16));
- FAIL_IF(!ptr);
- *ptr = (sljit_u16)(inst);
- compiler->size++;
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 push_inst32(struct sljit_compiler *compiler, sljit_ins inst)
-{
- sljit_u16 *ptr = (sljit_u16*)ensure_buf(compiler, sizeof(sljit_ins));
- FAIL_IF(!ptr);
- *ptr++ = (sljit_u16)(inst >> 16);
- *ptr = (sljit_u16)(inst);
- compiler->size += 2;
- return SLJIT_SUCCESS;
-}
-
-static SLJIT_INLINE sljit_s32 emit_imm32_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm)
-{
- FAIL_IF(push_inst32(compiler, MOVW | RD4(dst)
- | COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)));
- return push_inst32(compiler, MOVT | RD4(dst)
- | COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16));
-}
-
-static SLJIT_INLINE void modify_imm32_const(sljit_u16 *inst, sljit_uw new_imm)
-{
- sljit_ins dst = inst[1] & 0x0f00;
- SLJIT_ASSERT(((inst[0] & 0xfbf0) == (MOVW >> 16)) && ((inst[2] & 0xfbf0) == (MOVT >> 16)) && dst == (inst[3] & 0x0f00));
- inst[0] = (sljit_u16)((MOVW >> 16) | COPY_BITS(new_imm, 12, 0, 4) | COPY_BITS(new_imm, 11, 10, 1));
- inst[1] = (sljit_u16)(dst | COPY_BITS(new_imm, 8, 12, 3) | (new_imm & 0xff));
- inst[2] = (sljit_u16)((MOVT >> 16) | COPY_BITS(new_imm, 12 + 16, 0, 4) | COPY_BITS(new_imm, 11 + 16, 10, 1));
- inst[3] = (sljit_u16)(dst | COPY_BITS(new_imm, 8 + 16, 12, 3) | ((new_imm & 0xff0000) >> 16));
-}
-
-static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code, sljit_sw executable_offset)
-{
- sljit_sw diff;
-
- if (jump->flags & SLJIT_REWRITABLE_JUMP)
- return 0;
-
- if (jump->flags & JUMP_ADDR) {
- /* Branch to ARM code is not optimized yet. */
- if (!(jump->u.target & 0x1))
- return 0;
- diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2) - executable_offset) >> 1;
- }
- else {
- SLJIT_ASSERT(jump->flags & JUMP_LABEL);
- diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2)) >> 1;
- }
-
- if (jump->flags & IS_COND) {
- SLJIT_ASSERT(!(jump->flags & IS_BL));
- if (diff <= 127 && diff >= -128) {
- jump->flags |= PATCH_TYPE1;
- return 5;
- }
- if (diff <= 524287 && diff >= -524288) {
- jump->flags |= PATCH_TYPE2;
- return 4;
- }
- /* +1 comes from the prefix IT instruction. */
- diff--;
- if (diff <= 8388607 && diff >= -8388608) {
- jump->flags |= PATCH_TYPE3;
- return 3;
- }
- }
- else if (jump->flags & IS_BL) {
- if (diff <= 8388607 && diff >= -8388608) {
- jump->flags |= PATCH_BL;
- return 3;
- }
- }
- else {
- if (diff <= 1023 && diff >= -1024) {
- jump->flags |= PATCH_TYPE4;
- return 4;
- }
- if (diff <= 8388607 && diff >= -8388608) {
- jump->flags |= PATCH_TYPE5;
- return 3;
- }
- }
-
- return 0;
-}
-
-static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump, sljit_sw executable_offset)
-{
- sljit_s32 type = (jump->flags >> 4) & 0xf;
- sljit_sw diff;
- sljit_u16 *jump_inst;
- sljit_s32 s, j1, j2;
-
- if (SLJIT_UNLIKELY(type == 0)) {
- modify_imm32_const((sljit_u16*)jump->addr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target);
- return;
- }
-
- if (jump->flags & JUMP_ADDR) {
- SLJIT_ASSERT(jump->u.target & 0x1);
- diff = ((sljit_sw)jump->u.target - (sljit_sw)(jump->addr + sizeof(sljit_u32)) - executable_offset) >> 1;
- }
- else {
- SLJIT_ASSERT(jump->u.label->addr & 0x1);
- diff = ((sljit_sw)(jump->u.label->addr) - (sljit_sw)(jump->addr + sizeof(sljit_u32)) - executable_offset) >> 1;
- }
- jump_inst = (sljit_u16*)jump->addr;
-
- switch (type) {
- case 1:
- /* Encoding T1 of 'B' instruction */
- SLJIT_ASSERT(diff <= 127 && diff >= -128 && (jump->flags & IS_COND));
- jump_inst[0] = (sljit_u16)(0xd000 | (jump->flags & 0xf00) | ((sljit_ins)diff & 0xff));
- return;
- case 2:
- /* Encoding T3 of 'B' instruction */
- SLJIT_ASSERT(diff <= 524287 && diff >= -524288 && (jump->flags & IS_COND));
- jump_inst[0] = (sljit_u16)(0xf000 | COPY_BITS(jump->flags, 8, 6, 4) | COPY_BITS(diff, 11, 0, 6) | COPY_BITS(diff, 19, 10, 1));
- jump_inst[1] = (sljit_u16)(0x8000 | COPY_BITS(diff, 17, 13, 1) | COPY_BITS(diff, 18, 11, 1) | ((sljit_ins)diff & 0x7ff));
- return;
- case 3:
- SLJIT_ASSERT(jump->flags & IS_COND);
- *jump_inst++ = (sljit_u16)(IT | ((jump->flags >> 4) & 0xf0) | 0x8);
- diff--;
- type = 5;
- break;
- case 4:
- /* Encoding T2 of 'B' instruction */
- SLJIT_ASSERT(diff <= 1023 && diff >= -1024 && !(jump->flags & IS_COND));
- jump_inst[0] = (sljit_u16)(0xe000 | (diff & 0x7ff));
- return;
- }
-
- SLJIT_ASSERT(diff <= 8388607 && diff >= -8388608);
-
- /* Really complex instruction form for branches. */
- s = (diff >> 23) & 0x1;
- j1 = (~(diff >> 22) ^ s) & 0x1;
- j2 = (~(diff >> 21) ^ s) & 0x1;
- jump_inst[0] = (sljit_u16)(0xf000 | ((sljit_ins)s << 10) | COPY_BITS(diff, 11, 0, 10));
- jump_inst[1] = (sljit_u16)((j1 << 13) | (j2 << 11) | (diff & 0x7ff));
-
- /* The others have a common form. */
- if (type == 5) /* Encoding T4 of 'B' instruction */
- jump_inst[1] |= 0x9000;
- else if (type == 6) /* Encoding T1 of 'BL' instruction */
- jump_inst[1] |= 0xd000;
- else
- SLJIT_UNREACHABLE();
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
-{
- struct sljit_memory_fragment *buf;
- sljit_u16 *code;
- sljit_u16 *code_ptr;
- sljit_u16 *buf_ptr;
- sljit_u16 *buf_end;
- sljit_uw half_count;
- sljit_uw next_addr;
- sljit_sw executable_offset;
-
- struct sljit_label *label;
- struct sljit_jump *jump;
- struct sljit_const *const_;
- struct sljit_put_label *put_label;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_generate_code(compiler));
- reverse_buf(compiler);
-
- code = (sljit_u16*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_u16), compiler->exec_allocator_data);
- PTR_FAIL_WITH_EXEC_IF(code);
- buf = compiler->buf;
-
- code_ptr = code;
- half_count = 0;
- next_addr = 0;
- executable_offset = SLJIT_EXEC_OFFSET(code);
-
- label = compiler->labels;
- jump = compiler->jumps;
- const_ = compiler->consts;
- put_label = compiler->put_labels;
-
- do {
- buf_ptr = (sljit_u16*)buf->memory;
- buf_end = buf_ptr + (buf->used_size >> 1);
- do {
- *code_ptr = *buf_ptr++;
- if (next_addr == half_count) {
- SLJIT_ASSERT(!label || label->size >= half_count);
- SLJIT_ASSERT(!jump || jump->addr >= half_count);
- SLJIT_ASSERT(!const_ || const_->addr >= half_count);
- SLJIT_ASSERT(!put_label || put_label->addr >= half_count);
-
- /* These structures are ordered by their address. */
- if (label && label->size == half_count) {
- label->addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;
- label->size = (sljit_uw)(code_ptr - code);
- label = label->next;
- }
- if (jump && jump->addr == half_count) {
- jump->addr = (sljit_uw)code_ptr - ((jump->flags & IS_COND) ? 10 : 8);
- code_ptr -= detect_jump_type(jump, code_ptr, code, executable_offset);
- jump = jump->next;
- }
- if (const_ && const_->addr == half_count) {
- const_->addr = (sljit_uw)code_ptr;
- const_ = const_->next;
- }
- if (put_label && put_label->addr == half_count) {
- SLJIT_ASSERT(put_label->label);
- put_label->addr = (sljit_uw)code_ptr;
- put_label = put_label->next;
- }
- next_addr = compute_next_addr(label, jump, const_, put_label);
- }
- code_ptr++;
- half_count++;
- } while (buf_ptr < buf_end);
-
- buf = buf->next;
- } while (buf);
-
- if (label && label->size == half_count) {
- label->addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;
- label->size = (sljit_uw)(code_ptr - code);
- label = label->next;
- }
-
- SLJIT_ASSERT(!label);
- SLJIT_ASSERT(!jump);
- SLJIT_ASSERT(!const_);
- SLJIT_ASSERT(!put_label);
- SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
-
- jump = compiler->jumps;
- while (jump) {
- set_jump_instruction(jump, executable_offset);
- jump = jump->next;
- }
-
- put_label = compiler->put_labels;
- while (put_label) {
- modify_imm32_const((sljit_u16 *)put_label->addr, put_label->label->addr);
- put_label = put_label->next;
- }
-
- compiler->error = SLJIT_ERR_COMPILED;
- compiler->executable_offset = executable_offset;
- compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_u16);
-
- code = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
- code_ptr = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
-
- SLJIT_CACHE_FLUSH(code, code_ptr);
- SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
-
- /* Set thumb mode flag. */
- return (void*)((sljit_uw)code | 0x1);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
-{
- switch (feature_type) {
- case SLJIT_HAS_FPU:
-#ifdef SLJIT_IS_FPU_AVAILABLE
- return SLJIT_IS_FPU_AVAILABLE;
-#else
- /* Available by default. */
- return 1;
-#endif
-
- case SLJIT_HAS_CLZ:
- case SLJIT_HAS_CTZ:
- case SLJIT_HAS_ROT:
- case SLJIT_HAS_CMOV:
- case SLJIT_HAS_PREFETCH:
- return 1;
-
- default:
- return 0;
- }
-}
-
-/* --------------------------------------------------------------------- */
-/* Core code generator functions. */
-/* --------------------------------------------------------------------- */
-
-#define INVALID_IMM 0x80000000
-static sljit_uw get_imm(sljit_uw imm)
-{
- /* Thumb immediate form. */
- sljit_s32 counter;
-
- if (imm <= 0xff)
- return imm;
-
- if ((imm & 0xffff) == (imm >> 16)) {
- /* Some special cases. */
- if (!(imm & 0xff00))
- return (1 << 12) | (imm & 0xff);
- if (!(imm & 0xff))
- return (2 << 12) | ((imm >> 8) & 0xff);
- if ((imm & 0xff00) == ((imm & 0xff) << 8))
- return (3 << 12) | (imm & 0xff);
- }
-
- /* Assembly optimization: count leading zeroes? */
- counter = 8;
- if (!(imm & 0xffff0000)) {
- counter += 16;
- imm <<= 16;
- }
- if (!(imm & 0xff000000)) {
- counter += 8;
- imm <<= 8;
- }
- if (!(imm & 0xf0000000)) {
- counter += 4;
- imm <<= 4;
- }
- if (!(imm & 0xc0000000)) {
- counter += 2;
- imm <<= 2;
- }
- if (!(imm & 0x80000000)) {
- counter += 1;
- imm <<= 1;
- }
- /* Since imm >= 128, this must be true. */
- SLJIT_ASSERT(counter <= 31);
-
- if (imm & 0x00ffffff)
- return INVALID_IMM; /* Cannot be encoded. */
-
- return ((imm >> 24) & 0x7f) | COPY_BITS(counter, 4, 26, 1) | COPY_BITS(counter, 1, 12, 3) | COPY_BITS(counter, 0, 7, 1);
-}
-
-static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm)
-{
- sljit_uw tmp;
-
- /* MOVS cannot be used since it destroy flags. */
-
- if (imm >= 0x10000) {
- tmp = get_imm(imm);
- if (tmp != INVALID_IMM)
- return push_inst32(compiler, MOV_WI | RD4(dst) | tmp);
- tmp = get_imm(~imm);
- if (tmp != INVALID_IMM)
- return push_inst32(compiler, MVN_WI | RD4(dst) | tmp);
- }
-
- /* set low 16 bits, set hi 16 bits to 0. */
- FAIL_IF(push_inst32(compiler, MOVW | RD4(dst)
- | COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)));
-
- /* set hi 16 bit if needed. */
- if (imm >= 0x10000)
- return push_inst32(compiler, MOVT | RD4(dst)
- | COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16));
- return SLJIT_SUCCESS;
-}
-
-#define ARG1_IMM 0x0010000
-#define ARG2_IMM 0x0020000
-/* SET_FLAGS must be 0x100000 as it is also the value of S bit (can be used for optimization). */
-#define SET_FLAGS 0x0100000
-#define UNUSED_RETURN 0x0200000
-
-static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 dst, sljit_uw arg1, sljit_uw arg2)
-{
- /* dst must be register, TMP_REG1
- arg1 must be register, imm
- arg2 must be register, imm */
- sljit_s32 reg;
- sljit_uw imm, imm2;
-
- if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) {
- /* Both are immediates, no temporaries are used. */
- flags &= ~ARG1_IMM;
- FAIL_IF(load_immediate(compiler, TMP_REG1, arg1));
- arg1 = TMP_REG1;
- }
-
- if (flags & (ARG1_IMM | ARG2_IMM)) {
- reg = (sljit_s32)((flags & ARG2_IMM) ? arg1 : arg2);
- imm = (flags & ARG2_IMM) ? arg2 : arg1;
-
- switch (flags & 0xffff) {
- case SLJIT_CLZ:
- case SLJIT_CTZ:
- case SLJIT_MUL:
- /* No form with immediate operand. */
- break;
- case SLJIT_MOV:
- SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG2);
- return load_immediate(compiler, dst, imm);
- case SLJIT_NOT:
- if (!(flags & SET_FLAGS))
- return load_immediate(compiler, dst, ~imm);
- /* Since the flags should be set, we just fallback to the register mode.
- Although some clever things could be done here, "NOT IMM" does not worth the efforts. */
- break;
- case SLJIT_ADD:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;
- imm2 = NEGATE(imm);
- if (IS_2_LO_REGS(reg, dst)) {
- if (imm <= 0x7)
- return push_inst16(compiler, ADDSI3 | IMM3(imm) | RD3(dst) | RN3(reg));
- if (imm2 <= 0x7)
- return push_inst16(compiler, SUBSI3 | IMM3(imm2) | RD3(dst) | RN3(reg));
- if (reg == dst) {
- if (imm <= 0xff)
- return push_inst16(compiler, ADDSI8 | IMM8(imm) | RDN3(dst));
- if (imm2 <= 0xff)
- return push_inst16(compiler, SUBSI8 | IMM8(imm2) | RDN3(dst));
- }
- }
- if (!(flags & SET_FLAGS)) {
- if (imm <= 0xfff)
- return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(imm));
- if (imm2 <= 0xfff)
- return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(imm2));
- }
- imm2 = get_imm(imm);
- if (imm2 != INVALID_IMM)
- return push_inst32(compiler, ADD_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm2);
- imm = get_imm(NEGATE(imm));
- if (imm != INVALID_IMM)
- return push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
- break;
- case SLJIT_ADDC:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;
- imm = get_imm(imm);
- if (imm != INVALID_IMM)
- return push_inst32(compiler, ADCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
- break;
- case SLJIT_SUB:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;
- if (flags & ARG1_IMM) {
- if (imm == 0 && IS_2_LO_REGS(reg, dst))
- return push_inst16(compiler, RSBSI | RD3(dst) | RN3(reg));
- imm = get_imm(imm);
- if (imm != INVALID_IMM)
- return push_inst32(compiler, RSB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
- break;
- }
- if (flags & UNUSED_RETURN) {
- if (imm <= 0xff && reg_map[reg] <= 7)
- return push_inst16(compiler, CMPI | IMM8(imm) | RDN3(reg));
- imm2 = get_imm(imm);
- if (imm2 != INVALID_IMM)
- return push_inst32(compiler, CMPI_W | RN4(reg) | imm2);
- imm = get_imm(NEGATE(imm));
- if (imm != INVALID_IMM)
- return push_inst32(compiler, CMNI_W | RN4(reg) | imm);
- break;
- }
- imm2 = NEGATE(imm);
- if (IS_2_LO_REGS(reg, dst)) {
- if (imm <= 0x7)
- return push_inst16(compiler, SUBSI3 | IMM3(imm) | RD3(dst) | RN3(reg));
- if (imm2 <= 0x7)
- return push_inst16(compiler, ADDSI3 | IMM3(imm2) | RD3(dst) | RN3(reg));
- if (reg == dst) {
- if (imm <= 0xff)
- return push_inst16(compiler, SUBSI8 | IMM8(imm) | RDN3(dst));
- if (imm2 <= 0xff)
- return push_inst16(compiler, ADDSI8 | IMM8(imm2) | RDN3(dst));
- }
- }
- if (!(flags & SET_FLAGS)) {
- if (imm <= 0xfff)
- return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(imm));
- if (imm2 <= 0xfff)
- return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(imm2));
- }
- imm2 = get_imm(imm);
- if (imm2 != INVALID_IMM)
- return push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm2);
- imm = get_imm(NEGATE(imm));
- if (imm != INVALID_IMM)
- return push_inst32(compiler, ADD_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
- break;
- case SLJIT_SUBC:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;
- if (flags & ARG1_IMM)
- break;
- imm = get_imm(imm);
- if (imm != INVALID_IMM)
- return push_inst32(compiler, SBCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
- break;
- case SLJIT_AND:
- imm2 = get_imm(imm);
- if (imm2 != INVALID_IMM)
- return push_inst32(compiler, ((flags & UNUSED_RETURN) ? TSTI : ANDI) | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm2);
- imm = get_imm(~imm);
- if (imm != INVALID_IMM)
- return push_inst32(compiler, BICI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
- break;
- case SLJIT_OR:
- imm2 = get_imm(imm);
- if (imm2 != INVALID_IMM)
- return push_inst32(compiler, ORRI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm2);
- imm = get_imm(~imm);
- if (imm != INVALID_IMM)
- return push_inst32(compiler, ORNI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
- break;
- case SLJIT_XOR:
- imm = get_imm(imm);
- if (imm != INVALID_IMM)
- return push_inst32(compiler, EORI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
- break;
- case SLJIT_SHL:
- case SLJIT_MSHL:
- case SLJIT_LSHR:
- case SLJIT_MLSHR:
- case SLJIT_ASHR:
- case SLJIT_MASHR:
- case SLJIT_ROTL:
- case SLJIT_ROTR:
- if (flags & ARG1_IMM)
- break;
- imm &= 0x1f;
-
- if (imm == 0) {
- if (!(flags & SET_FLAGS))
- return push_inst16(compiler, MOV | SET_REGS44(dst, reg));
- if (IS_2_LO_REGS(dst, reg))
- return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg));
- return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg));
- }
-
- switch (flags & 0xffff) {
- case SLJIT_SHL:
- case SLJIT_MSHL:
- if (IS_2_LO_REGS(dst, reg))
- return push_inst16(compiler, LSLSI | RD3(dst) | RN3(reg) | (imm << 6));
- return push_inst32(compiler, LSL_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));
- case SLJIT_LSHR:
- case SLJIT_MLSHR:
- if (IS_2_LO_REGS(dst, reg))
- return push_inst16(compiler, LSRSI | RD3(dst) | RN3(reg) | (imm << 6));
- return push_inst32(compiler, LSR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));
- case SLJIT_ASHR:
- case SLJIT_MASHR:
- if (IS_2_LO_REGS(dst, reg))
- return push_inst16(compiler, ASRSI | RD3(dst) | RN3(reg) | (imm << 6));
- return push_inst32(compiler, ASR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));
- case SLJIT_ROTL:
- imm = (imm ^ 0x1f) + 1;
- /* fallthrough */
- default: /* SLJIT_ROTR */
- return push_inst32(compiler, ROR_WI | RD4(dst) | RM4(reg) | IMM5(imm));
- }
- default:
- SLJIT_UNREACHABLE();
- break;
- }
-
- if (flags & ARG2_IMM) {
- imm = arg2;
- arg2 = (arg1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;
- FAIL_IF(load_immediate(compiler, (sljit_s32)arg2, imm));
- }
- else {
- imm = arg1;
- arg1 = (arg2 == TMP_REG1) ? TMP_REG2 : TMP_REG1;
- FAIL_IF(load_immediate(compiler, (sljit_s32)arg1, imm));
- }
-
- SLJIT_ASSERT(arg1 != arg2);
- }
-
- /* Both arguments are registers. */
- switch (flags & 0xffff) {
- case SLJIT_MOV:
- case SLJIT_MOV_U32:
- case SLJIT_MOV_S32:
- case SLJIT_MOV32:
- case SLJIT_MOV_P:
- SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG2);
- if (dst == (sljit_s32)arg2)
- return SLJIT_SUCCESS;
- return push_inst16(compiler, MOV | SET_REGS44(dst, arg2));
- case SLJIT_MOV_U8:
- SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG2);
- if (IS_2_LO_REGS(dst, arg2))
- return push_inst16(compiler, UXTB | RD3(dst) | RN3(arg2));
- return push_inst32(compiler, UXTB_W | RD4(dst) | RM4(arg2));
- case SLJIT_MOV_S8:
- SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG2);
- if (IS_2_LO_REGS(dst, arg2))
- return push_inst16(compiler, SXTB | RD3(dst) | RN3(arg2));
- return push_inst32(compiler, SXTB_W | RD4(dst) | RM4(arg2));
- case SLJIT_MOV_U16:
- SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG2);
- if (IS_2_LO_REGS(dst, arg2))
- return push_inst16(compiler, UXTH | RD3(dst) | RN3(arg2));
- return push_inst32(compiler, UXTH_W | RD4(dst) | RM4(arg2));
- case SLJIT_MOV_S16:
- SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG2);
- if (IS_2_LO_REGS(dst, arg2))
- return push_inst16(compiler, SXTH | RD3(dst) | RN3(arg2));
- return push_inst32(compiler, SXTH_W | RD4(dst) | RM4(arg2));
- case SLJIT_NOT:
- SLJIT_ASSERT(arg1 == TMP_REG2);
- if (IS_2_LO_REGS(dst, arg2))
- return push_inst16(compiler, MVNS | RD3(dst) | RN3(arg2));
- return push_inst32(compiler, MVN_W | (flags & SET_FLAGS) | RD4(dst) | RM4(arg2));
- case SLJIT_CLZ:
- SLJIT_ASSERT(arg1 == TMP_REG2);
- return push_inst32(compiler, CLZ | RN4(arg2) | RD4(dst) | RM4(arg2));
- case SLJIT_CTZ:
- SLJIT_ASSERT(arg1 == TMP_REG2);
- FAIL_IF(push_inst32(compiler, RBIT | RN4(arg2) | RD4(dst) | RM4(arg2)));
- return push_inst32(compiler, CLZ | RN4(dst) | RD4(dst) | RM4(dst));
- case SLJIT_ADD:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;
- if (IS_3_LO_REGS(dst, arg1, arg2))
- return push_inst16(compiler, ADDS | RD3(dst) | RN3(arg1) | RM3(arg2));
- if (dst == (sljit_s32)arg1 && !(flags & SET_FLAGS))
- return push_inst16(compiler, ADD | SET_REGS44(dst, arg2));
- return push_inst32(compiler, ADD_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
- case SLJIT_ADDC:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;
- if (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))
- return push_inst16(compiler, ADCS | RD3(dst) | RN3(arg2));
- return push_inst32(compiler, ADC_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
- case SLJIT_SUB:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;
- if (flags & UNUSED_RETURN) {
- if (IS_2_LO_REGS(arg1, arg2))
- return push_inst16(compiler, CMP | RD3(arg1) | RN3(arg2));
- return push_inst16(compiler, CMP_X | SET_REGS44(arg1, arg2));
- }
- if (IS_3_LO_REGS(dst, arg1, arg2))
- return push_inst16(compiler, SUBS | RD3(dst) | RN3(arg1) | RM3(arg2));
- return push_inst32(compiler, SUB_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
- case SLJIT_SUBC:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;
- if (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))
- return push_inst16(compiler, SBCS | RD3(dst) | RN3(arg2));
- return push_inst32(compiler, SBC_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
- case SLJIT_MUL:
- compiler->status_flags_state = 0;
- if (!(flags & SET_FLAGS))
- return push_inst32(compiler, MUL | RD4(dst) | RN4(arg1) | RM4(arg2));
- SLJIT_ASSERT(dst != TMP_REG2);
- FAIL_IF(push_inst32(compiler, SMULL | RT4(dst) | RD4(TMP_REG2) | RN4(arg1) | RM4(arg2)));
- /* cmp TMP_REG2, dst asr #31. */
- return push_inst32(compiler, CMP_W | RN4(TMP_REG2) | 0x70e0 | RM4(dst));
- case SLJIT_AND:
- if (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))
- return push_inst16(compiler, ANDS | RD3(dst) | RN3(arg2));
- if ((flags & UNUSED_RETURN) && IS_2_LO_REGS(arg1, arg2))
- return push_inst16(compiler, TST | RD3(arg1) | RN3(arg2));
- return push_inst32(compiler, ((flags & UNUSED_RETURN) ? TST_W : AND_W) | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
- case SLJIT_OR:
- if (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))
- return push_inst16(compiler, ORRS | RD3(dst) | RN3(arg2));
- return push_inst32(compiler, ORR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
- case SLJIT_XOR:
- if (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))
- return push_inst16(compiler, EORS | RD3(dst) | RN3(arg2));
- return push_inst32(compiler, EOR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
- case SLJIT_MSHL:
- FAIL_IF(push_inst32(compiler, ANDI | RD4(TMP_REG2) | RN4(arg2) | 0x1f));
- arg2 = TMP_REG2;
- /* fallthrough */
- case SLJIT_SHL:
- if (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))
- return push_inst16(compiler, LSLS | RD3(dst) | RN3(arg2));
- return push_inst32(compiler, LSL_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
- case SLJIT_MLSHR:
- FAIL_IF(push_inst32(compiler, ANDI | RD4(TMP_REG2) | RN4(arg2) | 0x1f));
- arg2 = TMP_REG2;
- /* fallthrough */
- case SLJIT_LSHR:
- if (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))
- return push_inst16(compiler, LSRS | RD3(dst) | RN3(arg2));
- return push_inst32(compiler, LSR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
- case SLJIT_MASHR:
- FAIL_IF(push_inst32(compiler, ANDI | RD4(TMP_REG2) | RN4(arg2) | 0x1f));
- arg2 = TMP_REG2;
- /* fallthrough */
- case SLJIT_ASHR:
- if (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))
- return push_inst16(compiler, ASRS | RD3(dst) | RN3(arg2));
- return push_inst32(compiler, ASR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
- case SLJIT_ROTL:
- FAIL_IF(push_inst32(compiler, RSB_WI | RD4(TMP_REG2) | RN4(arg2) | 0));
- arg2 = TMP_REG2;
- /* fallthrough */
- case SLJIT_ROTR:
- if (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))
- return push_inst16(compiler, RORS | RD3(dst) | RN3(arg2));
- return push_inst32(compiler, ROR_W | RD4(dst) | RN4(arg1) | RM4(arg2));
- }
-
- SLJIT_UNREACHABLE();
- return SLJIT_SUCCESS;
-}
-
-#define STORE 0x01
-#define SIGNED 0x02
-
-#define WORD_SIZE 0x00
-#define BYTE_SIZE 0x04
-#define HALF_SIZE 0x08
-#define PRELOAD 0x0c
-
-#define IS_WORD_SIZE(flags) (!((flags) & (BYTE_SIZE | HALF_SIZE)))
-#define ALIGN_CHECK(argw, imm, shift) (!((argw) & ~((imm) << (shift))))
-
-/*
- 1st letter:
- w = word
- b = byte
- h = half
-
- 2nd letter:
- s = signed
- u = unsigned
-
- 3rd letter:
- l = load
- s = store
-*/
-
-static const sljit_ins sljit_mem16[12] = {
-/* w u l */ 0x5800 /* ldr */,
-/* w u s */ 0x5000 /* str */,
-/* w s l */ 0x5800 /* ldr */,
-/* w s s */ 0x5000 /* str */,
-
-/* b u l */ 0x5c00 /* ldrb */,
-/* b u s */ 0x5400 /* strb */,
-/* b s l */ 0x5600 /* ldrsb */,
-/* b s s */ 0x5400 /* strb */,
-
-/* h u l */ 0x5a00 /* ldrh */,
-/* h u s */ 0x5200 /* strh */,
-/* h s l */ 0x5e00 /* ldrsh */,
-/* h s s */ 0x5200 /* strh */,
-};
-
-static const sljit_ins sljit_mem16_imm5[12] = {
-/* w u l */ 0x6800 /* ldr imm5 */,
-/* w u s */ 0x6000 /* str imm5 */,
-/* w s l */ 0x6800 /* ldr imm5 */,
-/* w s s */ 0x6000 /* str imm5 */,
-
-/* b u l */ 0x7800 /* ldrb imm5 */,
-/* b u s */ 0x7000 /* strb imm5 */,
-/* b s l */ 0x0000 /* not allowed */,
-/* b s s */ 0x7000 /* strb imm5 */,
-
-/* h u l */ 0x8800 /* ldrh imm5 */,
-/* h u s */ 0x8000 /* strh imm5 */,
-/* h s l */ 0x0000 /* not allowed */,
-/* h s s */ 0x8000 /* strh imm5 */,
-};
-
-#define MEM_IMM8 0xc00
-#define MEM_IMM12 0x800000
-static const sljit_ins sljit_mem32[13] = {
-/* w u l */ 0xf8500000 /* ldr.w */,
-/* w u s */ 0xf8400000 /* str.w */,
-/* w s l */ 0xf8500000 /* ldr.w */,
-/* w s s */ 0xf8400000 /* str.w */,
-
-/* b u l */ 0xf8100000 /* ldrb.w */,
-/* b u s */ 0xf8000000 /* strb.w */,
-/* b s l */ 0xf9100000 /* ldrsb.w */,
-/* b s s */ 0xf8000000 /* strb.w */,
-
-/* h u l */ 0xf8300000 /* ldrh.w */,
-/* h u s */ 0xf8200000 /* strsh.w */,
-/* h s l */ 0xf9300000 /* ldrsh.w */,
-/* h s s */ 0xf8200000 /* strsh.w */,
-
-/* p u l */ 0xf8100000 /* pld */,
-};
-
-/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */
-static sljit_s32 emit_set_delta(struct sljit_compiler *compiler, sljit_s32 dst, sljit_s32 reg, sljit_sw value)
-{
- sljit_uw imm;
-
- if (value >= 0) {
- if (value <= 0xfff)
- return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(value));
- imm = get_imm((sljit_uw)value);
- if (imm != INVALID_IMM)
- return push_inst32(compiler, ADD_WI | RD4(dst) | RN4(reg) | imm);
- }
- else {
- value = -value;
- if (value <= 0xfff)
- return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(value));
- imm = get_imm((sljit_uw)value);
- if (imm != INVALID_IMM)
- return push_inst32(compiler, SUB_WI | RD4(dst) | RN4(reg) | imm);
- }
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg,
- sljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg)
-{
- sljit_s32 other_r;
- sljit_uw imm, tmp;
-
- SLJIT_ASSERT(arg & SLJIT_MEM);
- SLJIT_ASSERT((arg & REG_MASK) != tmp_reg || (arg == SLJIT_MEM1(tmp_reg) && argw >= -0xff && argw <= 0xfff));
-
- if (SLJIT_UNLIKELY(!(arg & REG_MASK))) {
- imm = get_imm((sljit_uw)argw & ~(sljit_uw)0xfff);
- if (imm != INVALID_IMM) {
- FAIL_IF(push_inst32(compiler, MOV_WI | RD4(tmp_reg) | imm));
- return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(tmp_reg) | (argw & 0xfff));
- }
-
- FAIL_IF(load_immediate(compiler, tmp_reg, (sljit_uw)argw));
- if (IS_2_LO_REGS(reg, tmp_reg) && sljit_mem16_imm5[flags])
- return push_inst16(compiler, sljit_mem16_imm5[flags] | RD3(reg) | RN3(tmp_reg));
- return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(tmp_reg));
- }
-
- if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
- argw &= 0x3;
- other_r = OFFS_REG(arg);
- arg &= REG_MASK;
-
- if (!argw && IS_3_LO_REGS(reg, arg, other_r))
- return push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(other_r));
- return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(other_r) | ((sljit_ins)argw << 4));
- }
-
- arg &= REG_MASK;
-
- if (argw > 0xfff) {
- imm = get_imm((sljit_uw)(argw & ~0xfff));
- if (imm != INVALID_IMM) {
- push_inst32(compiler, ADD_WI | RD4(tmp_reg) | RN4(arg) | imm);
- arg = tmp_reg;
- argw = argw & 0xfff;
- }
- }
- else if (argw < -0xff) {
- tmp = (sljit_uw)((-argw + 0xfff) & ~0xfff);
- SLJIT_ASSERT(tmp >= (sljit_uw)-argw);
- imm = get_imm(tmp);
-
- if (imm != INVALID_IMM) {
- push_inst32(compiler, SUB_WI | RD4(tmp_reg) | RN4(arg) | imm);
- arg = tmp_reg;
- argw += (sljit_sw)tmp;
-
- SLJIT_ASSERT(argw >= 0 && argw <= 0xfff);
- }
- }
-
- /* 16 bit instruction forms. */
- if (IS_2_LO_REGS(reg, arg) && sljit_mem16_imm5[flags]) {
- tmp = 3;
- if (IS_WORD_SIZE(flags)) {
- if (ALIGN_CHECK(argw, 0x1f, 2))
- tmp = 2;
- }
- else if (flags & BYTE_SIZE)
- {
- if (ALIGN_CHECK(argw, 0x1f, 0))
- tmp = 0;
- }
- else {
- SLJIT_ASSERT(flags & HALF_SIZE);
- if (ALIGN_CHECK(argw, 0x1f, 1))
- tmp = 1;
- }
-
- if (tmp < 3)
- return push_inst16(compiler, sljit_mem16_imm5[flags] | RD3(reg) | RN3(arg) | ((sljit_ins)argw << (6 - tmp)));
- }
- else if (SLJIT_UNLIKELY(arg == SLJIT_SP) && IS_WORD_SIZE(flags) && ALIGN_CHECK(argw, 0xff, 2) && reg_map[reg] <= 7) {
- /* SP based immediate. */
- return push_inst16(compiler, STR_SP | (sljit_ins)((flags & STORE) ? 0 : 0x800) | RDN3(reg) | ((sljit_ins)argw >> 2));
- }
-
- if (argw >= 0 && argw <= 0xfff)
- return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(arg) | (sljit_ins)argw);
- else if (argw < 0 && argw >= -0xff)
- return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(arg) | (sljit_ins)-argw);
-
- SLJIT_ASSERT(arg != tmp_reg);
-
- FAIL_IF(load_immediate(compiler, tmp_reg, (sljit_uw)argw));
- if (IS_3_LO_REGS(reg, arg, tmp_reg))
- return push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(tmp_reg));
- return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(tmp_reg));
-}
-
-#undef ALIGN_CHECK
-#undef IS_WORD_SIZE
-
-/* --------------------------------------------------------------------- */
-/* Entry, exit */
-/* --------------------------------------------------------------------- */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- sljit_s32 size, i, tmp, word_arg_count;
- sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options);
- sljit_uw offset;
- sljit_uw imm = 0;
-#ifdef __SOFTFP__
- sljit_u32 float_arg_count;
-#else
- sljit_u32 old_offset, f32_offset;
- sljit_u32 remap[3];
- sljit_u32 *remap_ptr = remap;
-#endif
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
- set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
-
- tmp = SLJIT_S0 - saveds;
- for (i = SLJIT_S0 - saved_arg_count; i > tmp; i--)
- imm |= (sljit_uw)1 << reg_map[i];
-
- for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--)
- imm |= (sljit_uw)1 << reg_map[i];
-
- /* At least two registers must be set for PUSH_W and one for PUSH instruction. */
- FAIL_IF((imm & 0xff00)
- ? push_inst32(compiler, PUSH_W | (1 << 14) | imm)
- : push_inst16(compiler, PUSH | (1 << 8) | imm));
-
- /* Stack must be aligned to 8 bytes: (LR, R4) */
- size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1);
-
- if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
- if ((size & SSIZE_OF(sw)) != 0) {
- FAIL_IF(push_inst16(compiler, SUB_SP_I | (sizeof(sljit_sw) >> 2)));
- size += SSIZE_OF(sw);
- }
-
- if (fsaveds + fscratches >= SLJIT_NUMBER_OF_FLOAT_REGISTERS) {
- FAIL_IF(push_inst32(compiler, VPUSH | DD4(SLJIT_FS0) | ((sljit_uw)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1)));
- } else {
- if (fsaveds > 0)
- FAIL_IF(push_inst32(compiler, VPUSH | DD4(SLJIT_FS0) | ((sljit_uw)fsaveds << 1)));
- if (fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG)
- FAIL_IF(push_inst32(compiler, VPUSH | DD4(fscratches) | ((sljit_uw)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1)));
- }
- }
-
- local_size = ((size + local_size + 0x7) & ~0x7) - size;
- compiler->local_size = local_size;
-
- if (options & SLJIT_ENTER_REG_ARG)
- arg_types = 0;
-
- arg_types >>= SLJIT_ARG_SHIFT;
- word_arg_count = 0;
- saved_arg_count = 0;
-#ifdef __SOFTFP__
- SLJIT_COMPILE_ASSERT(SLJIT_FR0 == 1, float_register_index_start);
-
- offset = 0;
- float_arg_count = 0;
-
- while (arg_types) {
- switch (arg_types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- if (offset & 0x7)
- offset += sizeof(sljit_sw);
-
- if (offset < 4 * sizeof(sljit_sw))
- FAIL_IF(push_inst32(compiler, VMOV2 | (offset << 10) | ((offset + sizeof(sljit_sw)) << 14) | float_arg_count));
- else
- FAIL_IF(push_inst32(compiler, VLDR_F32 | 0x800100 | RN4(SLJIT_SP)
- | (float_arg_count << 12) | ((offset + (sljit_uw)size - 4 * sizeof(sljit_sw)) >> 2)));
- float_arg_count++;
- offset += sizeof(sljit_f64) - sizeof(sljit_sw);
- break;
- case SLJIT_ARG_TYPE_F32:
- if (offset < 4 * sizeof(sljit_sw))
- FAIL_IF(push_inst32(compiler, VMOV | (float_arg_count << 16) | (offset << 10)));
- else
- FAIL_IF(push_inst32(compiler, VLDR_F32 | 0x800000 | RN4(SLJIT_SP)
- | (float_arg_count << 12) | ((offset + (sljit_uw)size - 4 * sizeof(sljit_sw)) >> 2)));
- float_arg_count++;
- break;
- default:
- word_arg_count++;
-
- if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {
- tmp = SLJIT_S0 - saved_arg_count;
- saved_arg_count++;
- } else if (word_arg_count - 1 != (sljit_s32)(offset >> 2))
- tmp = word_arg_count;
- else
- break;
-
- if (offset < 4 * sizeof(sljit_sw))
- FAIL_IF(push_inst16(compiler, MOV | ((sljit_ins)reg_map[tmp] & 0x7) | (((sljit_ins)reg_map[tmp] & 0x8) << 4) | (offset << 1)));
- else if (reg_map[tmp] <= 7)
- FAIL_IF(push_inst16(compiler, LDR_SP | RDN3(tmp)
- | ((offset + (sljit_uw)size - 4 * sizeof(sljit_sw)) >> 2)));
- else
- FAIL_IF(push_inst32(compiler, LDR | RT4(tmp) | RN4(SLJIT_SP)
- | ((offset + (sljit_uw)size - 4 * sizeof(sljit_sw)))));
- break;
- }
-
- offset += sizeof(sljit_sw);
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- compiler->args_size = offset;
-#else
- offset = SLJIT_FR0;
- old_offset = SLJIT_FR0;
- f32_offset = 0;
-
- while (arg_types) {
- switch (arg_types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- if (offset != old_offset)
- *remap_ptr++ = VMOV_F32 | SLJIT_32 | DD4(offset) | DM4(old_offset);
- old_offset++;
- offset++;
- break;
- case SLJIT_ARG_TYPE_F32:
- if (f32_offset != 0) {
- *remap_ptr++ = VMOV_F32 | 0x20 | DD4(offset) | DM4(f32_offset);
- f32_offset = 0;
- } else {
- if (offset != old_offset)
- *remap_ptr++ = VMOV_F32 | DD4(offset) | DM4(old_offset);
- f32_offset = old_offset;
- old_offset++;
- }
- offset++;
- break;
- default:
- if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {
- FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_S0 - saved_arg_count, SLJIT_R0 + word_arg_count)));
- saved_arg_count++;
- }
-
- word_arg_count++;
- break;
- }
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- SLJIT_ASSERT((sljit_uw)(remap_ptr - remap) <= sizeof(remap));
-
- while (remap_ptr > remap)
- FAIL_IF(push_inst32(compiler, *(--remap_ptr)));
-#endif
-
-#ifdef _WIN32
- if (local_size >= 4096) {
- imm = get_imm(4096);
- SLJIT_ASSERT(imm != INVALID_IMM);
-
- FAIL_IF(push_inst32(compiler, SUB_WI | RD4(SLJIT_SP) | RN4(SLJIT_SP) | imm));
-
- if (local_size < 4 * 4096) {
- if (local_size > 2 * 4096) {
- if (local_size > 3 * 4096) {
- FAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG1) | RN4(SLJIT_SP)));
- FAIL_IF(push_inst32(compiler, SUB_WI | RD4(SLJIT_SP) | RN4(SLJIT_SP) | imm));
- }
-
- FAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG1) | RN4(SLJIT_SP)));
- FAIL_IF(push_inst32(compiler, SUB_WI | RD4(SLJIT_SP) | RN4(SLJIT_SP) | imm));
- }
- } else {
- FAIL_IF(load_immediate(compiler, TMP_REG2, ((sljit_uw)local_size >> 12) - 1));
- FAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG1) | RN4(SLJIT_SP)));
- FAIL_IF(push_inst32(compiler, SUB_WI | RD4(SLJIT_SP) | RN4(SLJIT_SP) | imm));
- FAIL_IF(push_inst32(compiler, SUB_WI | SET_FLAGS | RD4(TMP_REG2) | RN4(TMP_REG2) | 1));
- FAIL_IF(push_inst16(compiler, BCC | (0x1 << 8) /* not-equal */ | (-8 & 0xff)));
- }
-
- FAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG1) | RN4(SLJIT_SP)));
- local_size &= 0xfff;
- }
-
- if (local_size >= 256) {
- SLJIT_ASSERT(local_size < 4096);
-
- if (local_size <= (127 << 2))
- FAIL_IF(push_inst16(compiler, SUB_SP_I | ((sljit_uw)local_size >> 2)));
- else
- FAIL_IF(emit_op_imm(compiler, SLJIT_SUB | ARG2_IMM, SLJIT_SP, SLJIT_SP, (sljit_uw)local_size));
-
- FAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG1) | RN4(SLJIT_SP)));
- } else if (local_size > 0)
- FAIL_IF(push_inst32(compiler, LDRI | 0x500 | RT4(TMP_REG1) | RN4(SLJIT_SP) | (sljit_uw)local_size));
-#else /* !_WIN32 */
- if (local_size > 0) {
- if (local_size <= (127 << 2))
- FAIL_IF(push_inst16(compiler, SUB_SP_I | ((sljit_uw)local_size >> 2)));
- else
- FAIL_IF(emit_op_imm(compiler, SLJIT_SUB | ARG2_IMM, SLJIT_SP, SLJIT_SP, (sljit_uw)local_size));
- }
-#endif /* _WIN32 */
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- sljit_s32 size;
-
- CHECK_ERROR();
- CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
- set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
-
- size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1);
-
- if ((size & SSIZE_OF(sw)) != 0 && (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG))
- size += SSIZE_OF(sw);
-
- compiler->local_size = ((size + local_size + 0x7) & ~0x7) - size;
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_add_sp(struct sljit_compiler *compiler, sljit_uw imm)
-{
- sljit_uw imm2;
-
- /* The TMP_REG1 register must keep its value. */
- if (imm <= (127u << 2))
- return push_inst16(compiler, ADD_SP_I | (imm >> 2));
-
- if (imm <= 0xfff)
- return push_inst32(compiler, ADDWI | RD4(SLJIT_SP) | RN4(SLJIT_SP) | IMM12(imm));
-
- imm2 = get_imm(imm);
-
- if (imm2 != INVALID_IMM)
- return push_inst32(compiler, ADD_WI | RD4(SLJIT_SP) | RN4(SLJIT_SP) | imm2);
-
- FAIL_IF(load_immediate(compiler, TMP_REG2, imm));
- return push_inst16(compiler, ADD_SP | RN3(TMP_REG2));
-}
-
-static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size)
-{
- sljit_s32 local_size, fscratches, fsaveds, i, tmp;
- sljit_s32 restored_reg = 0;
- sljit_s32 lr_dst = TMP_PC;
- sljit_uw reg_list = 0;
-
- SLJIT_ASSERT(reg_map[TMP_REG2] == 14 && frame_size <= 128);
-
- local_size = compiler->local_size;
- fscratches = compiler->fscratches;
- fsaveds = compiler->fsaveds;
-
- if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
- if (local_size > 0)
- FAIL_IF(emit_add_sp(compiler, (sljit_uw)local_size));
-
- if (fsaveds + fscratches >= SLJIT_NUMBER_OF_FLOAT_REGISTERS) {
- FAIL_IF(push_inst32(compiler, VPOP | DD4(SLJIT_FS0) | ((sljit_uw)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1)));
- } else {
- if (fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG)
- FAIL_IF(push_inst32(compiler, VPOP | DD4(fscratches) | ((sljit_uw)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1)));
- if (fsaveds > 0)
- FAIL_IF(push_inst32(compiler, VPOP | DD4(SLJIT_FS0) | ((sljit_uw)fsaveds << 1)));
- }
-
- local_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1) & 0x7;
- }
-
- if (frame_size < 0) {
- lr_dst = TMP_REG2;
- frame_size = 0;
- } else if (frame_size > 0) {
- SLJIT_ASSERT(frame_size == 1 || (frame_size & 0x7) == 0);
- lr_dst = 0;
- frame_size &= ~0x7;
- }
-
- tmp = SLJIT_S0 - compiler->saveds;
- i = SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options);
- if (tmp < i) {
- restored_reg = i;
- do {
- reg_list |= (sljit_uw)1 << reg_map[i];
- } while (--i > tmp);
- }
-
- i = compiler->scratches;
- if (i >= SLJIT_FIRST_SAVED_REG) {
- restored_reg = i;
- do {
- reg_list |= (sljit_uw)1 << reg_map[i];
- } while (--i >= SLJIT_FIRST_SAVED_REG);
- }
-
- if (lr_dst == TMP_REG2 && reg_list == 0) {
- reg_list |= (sljit_uw)1 << reg_map[TMP_REG2];
- restored_reg = TMP_REG2;
- lr_dst = 0;
- }
-
- if (lr_dst == 0 && (reg_list & (reg_list - 1)) == 0) {
- /* The local_size does not include the saved registers. */
- tmp = 0;
- if (reg_list != 0) {
- tmp = 2;
- if (local_size <= 0xfff) {
- if (local_size == 0) {
- SLJIT_ASSERT(restored_reg != TMP_REG2);
- if (frame_size == 0)
- return push_inst32(compiler, LDRI | RT4(restored_reg) | RN4(SLJIT_SP) | 0x308);
- if (frame_size > 2 * SSIZE_OF(sw))
- return push_inst32(compiler, LDRI | RT4(restored_reg) | RN4(SLJIT_SP) | 0x100 | (sljit_ins)(frame_size - (2 * SSIZE_OF(sw))));
- }
-
- if (reg_map[restored_reg] <= 7 && local_size <= 0x3fc)
- FAIL_IF(push_inst16(compiler, STR_SP | 0x800 | RDN3(restored_reg) | (sljit_ins)(local_size >> 2)));
- else
- FAIL_IF(push_inst32(compiler, LDR | RT4(restored_reg) | RN4(SLJIT_SP) | (sljit_ins)local_size));
- tmp = 1;
- } else if (frame_size == 0) {
- frame_size = (restored_reg == TMP_REG2) ? SSIZE_OF(sw) : 2 * SSIZE_OF(sw);
- tmp = 3;
- }
-
- /* Place for the saved register. */
- if (restored_reg != TMP_REG2)
- local_size += SSIZE_OF(sw);
- }
-
- /* Place for the lr register. */
- local_size += SSIZE_OF(sw);
-
- if (frame_size > local_size)
- FAIL_IF(push_inst16(compiler, SUB_SP_I | ((sljit_ins)(frame_size - local_size) >> 2)));
- else if (frame_size < local_size)
- FAIL_IF(emit_add_sp(compiler, (sljit_uw)(local_size - frame_size)));
-
- if (tmp <= 1)
- return SLJIT_SUCCESS;
-
- if (tmp == 2) {
- frame_size -= SSIZE_OF(sw);
- if (restored_reg != TMP_REG2)
- frame_size -= SSIZE_OF(sw);
-
- if (reg_map[restored_reg] <= 7)
- return push_inst16(compiler, STR_SP | 0x800 | RDN3(restored_reg) | (sljit_ins)(frame_size >> 2));
-
- return push_inst32(compiler, LDR | RT4(restored_reg) | RN4(SLJIT_SP) | (sljit_ins)frame_size);
- }
-
- tmp = (restored_reg == TMP_REG2) ? 0x304 : 0x308;
- return push_inst32(compiler, LDRI | RT4(restored_reg) | RN4(SLJIT_SP) | (sljit_ins)tmp);
- }
-
- if (local_size > 0)
- FAIL_IF(emit_add_sp(compiler, (sljit_uw)local_size));
-
- if (!(reg_list & 0xff00) && lr_dst != TMP_REG2) {
- if (lr_dst == TMP_PC)
- reg_list |= 1u << 8;
-
- /* At least one register must be set for POP instruction. */
- SLJIT_ASSERT(reg_list != 0);
-
- FAIL_IF(push_inst16(compiler, POP | reg_list));
- } else {
- if (lr_dst != 0)
- reg_list |= (sljit_uw)1 << reg_map[lr_dst];
-
- /* At least two registers must be set for POP_W instruction. */
- SLJIT_ASSERT((reg_list & (reg_list - 1)) != 0);
-
- FAIL_IF(push_inst32(compiler, POP_W | reg_list));
- }
-
- if (frame_size > 0)
- return push_inst16(compiler, SUB_SP_I | (((sljit_ins)frame_size - sizeof(sljit_sw)) >> 2));
-
- if (lr_dst != 0)
- return SLJIT_SUCCESS;
-
- return push_inst16(compiler, ADD_SP_I | 1);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_return_void(compiler));
-
- return emit_stack_frame_release(compiler, 0);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,
- sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_return_to(compiler, src, srcw));
-
- if (src & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1));
- src = TMP_REG1;
- srcw = 0;
- } else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
- FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG1, src)));
- src = TMP_REG1;
- srcw = 0;
- }
-
- FAIL_IF(emit_stack_frame_release(compiler, 1));
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);
-}
-
-/* --------------------------------------------------------------------- */
-/* Operators */
-/* --------------------------------------------------------------------- */
-
-#if !(defined __ARM_FEATURE_IDIV) && !(defined __ARM_ARCH_EXT_IDIV__)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef _WIN32
-extern unsigned long long __rt_udiv(unsigned int denominator, unsigned int numerator);
-extern long long __rt_sdiv(int denominator, int numerator);
-#elif defined(__GNUC__)
-extern unsigned int __aeabi_uidivmod(unsigned int numerator, int unsigned denominator);
-extern int __aeabi_idivmod(int numerator, int denominator);
-#else
-#error "Software divmod functions are needed"
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !__ARM_FEATURE_IDIV && !__ARM_ARCH_EXT_IDIV__ */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
-{
-#if !(defined __ARM_FEATURE_IDIV) && !(defined __ARM_ARCH_EXT_IDIV__)
- sljit_uw saved_reg_list[3];
- sljit_uw saved_reg_count;
-#endif
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op0(compiler, op));
-
- op = GET_OPCODE(op);
- switch (op) {
- case SLJIT_BREAKPOINT:
- return push_inst16(compiler, BKPT);
- case SLJIT_NOP:
- return push_inst16(compiler, NOP);
- case SLJIT_LMUL_UW:
- case SLJIT_LMUL_SW:
- return push_inst32(compiler, (op == SLJIT_LMUL_UW ? UMULL : SMULL)
- | RD4(SLJIT_R1) | RT4(SLJIT_R0) | RN4(SLJIT_R0) | RM4(SLJIT_R1));
-#if (defined __ARM_FEATURE_IDIV) || (defined __ARM_ARCH_EXT_IDIV__)
- case SLJIT_DIVMOD_UW:
- case SLJIT_DIVMOD_SW:
- FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG1, SLJIT_R0)));
- FAIL_IF(push_inst32(compiler, (op == SLJIT_DIVMOD_UW ? UDIV : SDIV) | RD4(SLJIT_R0) | RN4(SLJIT_R0) | RM4(SLJIT_R1)));
- FAIL_IF(push_inst32(compiler, MUL | RD4(SLJIT_R1) | RN4(SLJIT_R0) | RM4(SLJIT_R1)));
- return push_inst32(compiler, SUB_W | RD4(SLJIT_R1) | RN4(TMP_REG1) | RM4(SLJIT_R1));
- case SLJIT_DIV_UW:
- case SLJIT_DIV_SW:
- return push_inst32(compiler, (op == SLJIT_DIV_UW ? UDIV : SDIV) | RD4(SLJIT_R0) | RN4(SLJIT_R0) | RM4(SLJIT_R1));
-#else /* !__ARM_FEATURE_IDIV && !__ARM_ARCH_EXT_IDIV__ */
- case SLJIT_DIVMOD_UW:
- case SLJIT_DIVMOD_SW:
- case SLJIT_DIV_UW:
- case SLJIT_DIV_SW:
- SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
- SLJIT_ASSERT(reg_map[2] == 1 && reg_map[3] == 2 && reg_map[4] == 3);
-
- saved_reg_count = 0;
- if (compiler->scratches >= 4)
- saved_reg_list[saved_reg_count++] = 3;
- if (compiler->scratches >= 3)
- saved_reg_list[saved_reg_count++] = 2;
- if (op >= SLJIT_DIV_UW)
- saved_reg_list[saved_reg_count++] = 1;
-
- if (saved_reg_count > 0) {
- FAIL_IF(push_inst32(compiler, 0xf84d0d00 | (saved_reg_count >= 3 ? 16 : 8)
- | (saved_reg_list[0] << 12) /* str rX, [sp, #-8/-16]! */));
- if (saved_reg_count >= 2) {
- SLJIT_ASSERT(saved_reg_list[1] < 8);
- FAIL_IF(push_inst16(compiler, 0x9001 | (saved_reg_list[1] << 8) /* str rX, [sp, #4] */));
- }
- if (saved_reg_count >= 3) {
- SLJIT_ASSERT(saved_reg_list[2] < 8);
- FAIL_IF(push_inst16(compiler, 0x9002 | (saved_reg_list[2] << 8) /* str rX, [sp, #8] */));
- }
- }
-
-#ifdef _WIN32
- FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG1, SLJIT_R0)));
- FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_R0, SLJIT_R1)));
- FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_R1, TMP_REG1)));
- FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,
- ((op | 0x2) == SLJIT_DIV_UW ? SLJIT_FUNC_ADDR(__rt_udiv) : SLJIT_FUNC_ADDR(__rt_sdiv))));
-#elif defined(__GNUC__)
- FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,
- ((op | 0x2) == SLJIT_DIV_UW ? SLJIT_FUNC_ADDR(__aeabi_uidivmod) : SLJIT_FUNC_ADDR(__aeabi_idivmod))));
-#else
-#error "Software divmod functions are needed"
-#endif
-
- if (saved_reg_count > 0) {
- if (saved_reg_count >= 3) {
- SLJIT_ASSERT(saved_reg_list[2] < 8);
- FAIL_IF(push_inst16(compiler, 0x9802 | (saved_reg_list[2] << 8) /* ldr rX, [sp, #8] */));
- }
- if (saved_reg_count >= 2) {
- SLJIT_ASSERT(saved_reg_list[1] < 8);
- FAIL_IF(push_inst16(compiler, 0x9801 | (saved_reg_list[1] << 8) /* ldr rX, [sp, #4] */));
- }
- return push_inst32(compiler, 0xf85d0b00 | (saved_reg_count >= 3 ? 16 : 8)
- | (saved_reg_list[0] << 12) /* ldr rX, [sp], #8/16 */);
- }
- return SLJIT_SUCCESS;
-#endif /* __ARM_FEATURE_IDIV || __ARM_ARCH_EXT_IDIV__ */
- case SLJIT_ENDBR:
- case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
- return SLJIT_SUCCESS;
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 dst_r, flags;
- sljit_s32 op_flags = GET_ALL_FLAGS(op);
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
-
- op = GET_OPCODE(op);
- if (op >= SLJIT_MOV && op <= SLJIT_MOV_P) {
- switch (op) {
- case SLJIT_MOV:
- case SLJIT_MOV_U32:
- case SLJIT_MOV_S32:
- case SLJIT_MOV32:
- case SLJIT_MOV_P:
- flags = WORD_SIZE;
- break;
- case SLJIT_MOV_U8:
- flags = BYTE_SIZE;
- if (src & SLJIT_IMM)
- srcw = (sljit_u8)srcw;
- break;
- case SLJIT_MOV_S8:
- flags = BYTE_SIZE | SIGNED;
- if (src & SLJIT_IMM)
- srcw = (sljit_s8)srcw;
- break;
- case SLJIT_MOV_U16:
- flags = HALF_SIZE;
- if (src & SLJIT_IMM)
- srcw = (sljit_u16)srcw;
- break;
- case SLJIT_MOV_S16:
- flags = HALF_SIZE | SIGNED;
- if (src & SLJIT_IMM)
- srcw = (sljit_s16)srcw;
- break;
- default:
- SLJIT_UNREACHABLE();
- flags = 0;
- break;
- }
-
- if (src & SLJIT_IMM)
- FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG2, (sljit_uw)srcw));
- else if (src & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, flags, dst_r, src, srcw, TMP_REG1));
- } else {
- if (dst_r != TMP_REG1)
- return emit_op_imm(compiler, op, dst_r, TMP_REG2, (sljit_uw)src);
- dst_r = src;
- }
-
- if (!(dst & SLJIT_MEM))
- return SLJIT_SUCCESS;
-
- return emit_op_mem(compiler, flags | STORE, dst_r, dst, dstw, TMP_REG2);
- }
-
- flags = HAS_FLAGS(op_flags) ? SET_FLAGS : 0;
-
- if (src & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1));
- src = TMP_REG1;
- }
-
- emit_op_imm(compiler, flags | op, dst_r, TMP_REG2, (sljit_uw)src);
-
- if (SLJIT_UNLIKELY(dst & SLJIT_MEM))
- return emit_op_mem(compiler, flags | STORE, dst_r, dst, dstw, TMP_REG2);
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 dst_reg, flags, src2_reg;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- dst_reg = FAST_IS_REG(dst) ? dst : TMP_REG1;
- flags = HAS_FLAGS(op) ? SET_FLAGS : 0;
-
- if (dst == TMP_REG1)
- flags |= UNUSED_RETURN;
-
- if (src1 & SLJIT_IMM)
- flags |= ARG1_IMM;
- else if (src1 & SLJIT_MEM) {
- emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src1, src1w, TMP_REG1);
- src1w = TMP_REG1;
- }
- else
- src1w = src1;
-
- if (src2 & SLJIT_IMM)
- flags |= ARG2_IMM;
- else if (src2 & SLJIT_MEM) {
- src2_reg = (!(flags & ARG1_IMM) && (src1w == TMP_REG1)) ? TMP_REG2 : TMP_REG1;
- emit_op_mem(compiler, WORD_SIZE, src2_reg, src2, src2w, src2_reg);
- src2w = src2_reg;
- }
- else
- src2w = src2;
-
- emit_op_imm(compiler, flags | GET_OPCODE(op), dst_reg, (sljit_uw)src1w, (sljit_uw)src2w);
-
- if (!(dst & SLJIT_MEM))
- return SLJIT_SUCCESS;
- return emit_op_mem(compiler, WORD_SIZE | STORE, dst_reg, dst, dstw, TMP_REG2);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_op2(compiler, op, TMP_REG1, 0, src1, src1w, src2, src2w);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src_dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 is_left;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w));
-
- op = GET_OPCODE(op);
- is_left = (op == SLJIT_SHL || op == SLJIT_MSHL);
-
- if (src_dst == src1) {
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_op2(compiler, is_left ? SLJIT_ROTL : SLJIT_ROTR, src_dst, 0, src_dst, 0, src2, src2w);
- }
-
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- if (src2 & SLJIT_IMM) {
- src2w &= 0x1f;
-
- if (src2w == 0)
- return SLJIT_SUCCESS;
- } else if (src2 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src2, src2w, TMP_REG2));
- src2 = TMP_REG2;
- }
-
- if (src1 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src1, src1w, TMP_REG1));
- src1 = TMP_REG1;
- } else if (src1 & SLJIT_IMM) {
- FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w));
- src1 = TMP_REG1;
- }
-
- if (src2 & SLJIT_IMM) {
- if (reg_map[src_dst] <= 7)
- FAIL_IF(push_inst16(compiler, (is_left ? LSLSI : LSRSI) | RD3(src_dst) | RN3(src_dst) | ((sljit_ins)src2w << 6)));
- else
- FAIL_IF(push_inst32(compiler, (is_left ? LSL_WI : LSR_WI) | RD4(src_dst) | RM4(src_dst) | IMM5(src2w)));
-
- src2w = (src2w ^ 0x1f) + 1;
- return push_inst32(compiler, ORR_W | RD4(src_dst) | RN4(src_dst) | RM4(src1) | (is_left ? 0x10 : 0x0) | IMM5(src2w));
- }
-
- if (op == SLJIT_MSHL || op == SLJIT_MLSHR) {
- FAIL_IF(push_inst32(compiler, ANDI | RD4(TMP_REG2) | RN4(src2) | 0x1f));
- src2 = TMP_REG2;
- }
-
- if (IS_2_LO_REGS(src_dst, src2))
- FAIL_IF(push_inst16(compiler, (is_left ? LSLS : LSRS) | RD3(src_dst) | RN3(src2)));
- else
- FAIL_IF(push_inst32(compiler, (is_left ? LSL_W : LSR_W) | RD4(src_dst) | RN4(src_dst) | RM4(src2)));
-
- FAIL_IF(push_inst32(compiler, (is_left ? LSR_WI : LSL_WI) | RD4(TMP_REG1) | RM4(src1) | (1 << 6)));
- FAIL_IF(push_inst32(compiler, EORI | RD4(TMP_REG2) | RN4(src2) | 0x1f));
- FAIL_IF(push_inst32(compiler, (is_left ? LSR_W : LSL_W) | RD4(TMP_REG1) | RN4(TMP_REG1) | RM4(TMP_REG2)));
- return push_inst32(compiler, ORR_W | RD4(src_dst) | RN4(src_dst) | RM4(TMP_REG1));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- switch (op) {
- case SLJIT_FAST_RETURN:
- SLJIT_ASSERT(reg_map[TMP_REG2] == 14);
-
- if (FAST_IS_REG(src))
- FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, src)));
- else
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src, srcw, TMP_REG2));
-
- return push_inst16(compiler, BX | RN3(TMP_REG2));
- case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
- return SLJIT_SUCCESS;
- case SLJIT_PREFETCH_L1:
- case SLJIT_PREFETCH_L2:
- case SLJIT_PREFETCH_L3:
- case SLJIT_PREFETCH_ONCE:
- return emit_op_mem(compiler, PRELOAD, TMP_PC, src, srcw, TMP_REG1);
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
-{
- CHECK_REG_INDEX(check_sljit_get_register_index(reg));
- return reg_map[reg];
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
-{
- CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
- return (freg_map[reg] << 1);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
- void *instruction, sljit_u32 size)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
-
- if (size == 2)
- return push_inst16(compiler, *(sljit_u16*)instruction);
- return push_inst32(compiler, *(sljit_ins*)instruction);
-}
-
-/* --------------------------------------------------------------------- */
-/* Floating point operators */
-/* --------------------------------------------------------------------- */
-
-#define FPU_LOAD (1 << 20)
-
-static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
-{
- sljit_uw imm;
- sljit_ins inst = VSTR_F32 | (flags & (SLJIT_32 | FPU_LOAD));
-
- SLJIT_ASSERT(arg & SLJIT_MEM);
-
- /* Fast loads and stores. */
- if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
- FAIL_IF(push_inst32(compiler, ADD_W | RD4(TMP_REG1) | RN4(arg & REG_MASK) | RM4(OFFS_REG(arg)) | (((sljit_uw)argw & 0x3) << 6)));
- arg = SLJIT_MEM | TMP_REG1;
- argw = 0;
- }
-
- if ((arg & REG_MASK) && (argw & 0x3) == 0) {
- if (!(argw & ~0x3fc))
- return push_inst32(compiler, inst | 0x800000 | RN4(arg & REG_MASK) | DD4(reg) | ((sljit_uw)argw >> 2));
- if (!(-argw & ~0x3fc))
- return push_inst32(compiler, inst | RN4(arg & REG_MASK) | DD4(reg) | ((sljit_uw)-argw >> 2));
- }
-
- if (arg & REG_MASK) {
- if (emit_set_delta(compiler, TMP_REG1, arg & REG_MASK, argw) != SLJIT_ERR_UNSUPPORTED) {
- FAIL_IF(compiler->error);
- return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg));
- }
-
- imm = get_imm((sljit_uw)argw & ~(sljit_uw)0x3fc);
- if (imm != INVALID_IMM) {
- FAIL_IF(push_inst32(compiler, ADD_WI | RD4(TMP_REG1) | RN4(arg & REG_MASK) | imm));
- return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg) | (((sljit_uw)argw & 0x3fc) >> 2));
- }
-
- imm = get_imm((sljit_uw)-argw & ~(sljit_uw)0x3fc);
- if (imm != INVALID_IMM) {
- argw = -argw;
- FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(arg & REG_MASK) | imm));
- return push_inst32(compiler, inst | RN4(TMP_REG1) | DD4(reg) | (((sljit_uw)argw & 0x3fc) >> 2));
- }
- }
-
- FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)argw));
- if (arg & REG_MASK)
- FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG1, (arg & REG_MASK))));
- return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg));
-}
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- op ^= SLJIT_32;
-
- if (src & SLJIT_MEM) {
- FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG1, src, srcw));
- src = TMP_FREG1;
- }
-
- FAIL_IF(push_inst32(compiler, VCVT_S32_F32 | (op & SLJIT_32) | DD4(TMP_FREG1) | DM4(src)));
-
- if (FAST_IS_REG(dst))
- return push_inst32(compiler, VMOV | (1 << 20) | RT4(dst) | DN4(TMP_FREG1));
-
- /* Store the integer value from a VFP register. */
- return emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw);
-}
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
-
- op ^= SLJIT_32;
-
- if (FAST_IS_REG(src))
- FAIL_IF(push_inst32(compiler, VMOV | RT4(src) | DN4(TMP_FREG1)));
- else if (src & SLJIT_MEM) {
- /* Load the integer value into a VFP register. */
- FAIL_IF(emit_fop_mem(compiler, FPU_LOAD, TMP_FREG1, src, srcw));
- }
- else {
- FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcw));
- FAIL_IF(push_inst32(compiler, VMOV | RT4(TMP_REG1) | DN4(TMP_FREG1)));
- }
-
- FAIL_IF(push_inst32(compiler, VCVT_F32_S32 | (op & SLJIT_32) | DD4(dst_r) | DM4(TMP_FREG1)));
-
- if (dst & SLJIT_MEM)
- return emit_fop_mem(compiler, (op & SLJIT_32), TMP_FREG1, dst, dstw);
- return SLJIT_SUCCESS;
-}
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- op ^= SLJIT_32;
-
- if (src1 & SLJIT_MEM) {
- emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG1, src1, src1w);
- src1 = TMP_FREG1;
- }
-
- if (src2 & SLJIT_MEM) {
- emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG2, src2, src2w);
- src2 = TMP_FREG2;
- }
-
- FAIL_IF(push_inst32(compiler, VCMP_F32 | (op & SLJIT_32) | DD4(src1) | DM4(src2)));
- return push_inst32(compiler, VMRS);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 dst_r;
-
- CHECK_ERROR();
-
- SLJIT_COMPILE_ASSERT((SLJIT_32 == 0x100), float_transfer_bit_error);
- SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
-
- if (GET_OPCODE(op) != SLJIT_CONV_F64_FROM_F32)
- op ^= SLJIT_32;
-
- if (src & SLJIT_MEM) {
- emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, dst_r, src, srcw);
- src = dst_r;
- }
-
- switch (GET_OPCODE(op)) {
- case SLJIT_MOV_F64:
- if (src != dst_r) {
- if (dst_r != TMP_FREG1)
- FAIL_IF(push_inst32(compiler, VMOV_F32 | (op & SLJIT_32) | DD4(dst_r) | DM4(src)));
- else
- dst_r = src;
- }
- break;
- case SLJIT_NEG_F64:
- FAIL_IF(push_inst32(compiler, VNEG_F32 | (op & SLJIT_32) | DD4(dst_r) | DM4(src)));
- break;
- case SLJIT_ABS_F64:
- FAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_32) | DD4(dst_r) | DM4(src)));
- break;
- case SLJIT_CONV_F64_FROM_F32:
- FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | (op & SLJIT_32) | DD4(dst_r) | DM4(src)));
- op ^= SLJIT_32;
- break;
- }
-
- if (dst & SLJIT_MEM)
- return emit_fop_mem(compiler, (op & SLJIT_32), dst_r, dst, dstw);
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 dst_r;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- op ^= SLJIT_32;
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
- if (src1 & SLJIT_MEM) {
- emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG1, src1, src1w);
- src1 = TMP_FREG1;
- }
- if (src2 & SLJIT_MEM) {
- emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG2, src2, src2w);
- src2 = TMP_FREG2;
- }
-
- switch (GET_OPCODE(op)) {
- case SLJIT_ADD_F64:
- FAIL_IF(push_inst32(compiler, VADD_F32 | (op & SLJIT_32) | DD4(dst_r) | DN4(src1) | DM4(src2)));
- break;
- case SLJIT_SUB_F64:
- FAIL_IF(push_inst32(compiler, VSUB_F32 | (op & SLJIT_32) | DD4(dst_r) | DN4(src1) | DM4(src2)));
- break;
- case SLJIT_MUL_F64:
- FAIL_IF(push_inst32(compiler, VMUL_F32 | (op & SLJIT_32) | DD4(dst_r) | DN4(src1) | DM4(src2)));
- break;
- case SLJIT_DIV_F64:
- FAIL_IF(push_inst32(compiler, VDIV_F32 | (op & SLJIT_32) | DD4(dst_r) | DN4(src1) | DM4(src2)));
- break;
- }
-
- if (!(dst & SLJIT_MEM))
- return SLJIT_SUCCESS;
- return emit_fop_mem(compiler, (op & SLJIT_32), TMP_FREG1, dst, dstw);
-}
-
-/* --------------------------------------------------------------------- */
-/* Other instructions */
-/* --------------------------------------------------------------------- */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- SLJIT_ASSERT(reg_map[TMP_REG2] == 14);
-
- if (FAST_IS_REG(dst))
- return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG2));
-
- /* Memory. */
- return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, TMP_REG1);
-}
-
-/* --------------------------------------------------------------------- */
-/* Conditional instructions */
-/* --------------------------------------------------------------------- */
-
-static sljit_uw get_cc(struct sljit_compiler *compiler, sljit_s32 type)
-{
- switch (type) {
- case SLJIT_EQUAL:
- case SLJIT_F_EQUAL:
- case SLJIT_ORDERED_EQUAL:
- case SLJIT_UNORDERED_OR_EQUAL: /* Not supported. */
- return 0x0;
-
- case SLJIT_NOT_EQUAL:
- case SLJIT_F_NOT_EQUAL:
- case SLJIT_UNORDERED_OR_NOT_EQUAL:
- case SLJIT_ORDERED_NOT_EQUAL: /* Not supported. */
- return 0x1;
-
- case SLJIT_CARRY:
- if (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_ADD)
- return 0x2;
- /* fallthrough */
-
- case SLJIT_LESS:
- return 0x3;
-
- case SLJIT_NOT_CARRY:
- if (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_ADD)
- return 0x3;
- /* fallthrough */
-
- case SLJIT_GREATER_EQUAL:
- return 0x2;
-
- case SLJIT_GREATER:
- case SLJIT_UNORDERED_OR_GREATER:
- return 0x8;
-
- case SLJIT_LESS_EQUAL:
- case SLJIT_F_LESS_EQUAL:
- case SLJIT_ORDERED_LESS_EQUAL:
- return 0x9;
-
- case SLJIT_SIG_LESS:
- case SLJIT_UNORDERED_OR_LESS:
- return 0xb;
-
- case SLJIT_SIG_GREATER_EQUAL:
- case SLJIT_F_GREATER_EQUAL:
- case SLJIT_ORDERED_GREATER_EQUAL:
- return 0xa;
-
- case SLJIT_SIG_GREATER:
- case SLJIT_F_GREATER:
- case SLJIT_ORDERED_GREATER:
- return 0xc;
-
- case SLJIT_SIG_LESS_EQUAL:
- case SLJIT_UNORDERED_OR_LESS_EQUAL:
- return 0xd;
-
- case SLJIT_OVERFLOW:
- if (!(compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)))
- return 0x1;
- /* fallthrough */
-
- case SLJIT_UNORDERED:
- return 0x6;
-
- case SLJIT_NOT_OVERFLOW:
- if (!(compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)))
- return 0x0;
- /* fallthrough */
-
- case SLJIT_ORDERED:
- return 0x7;
-
- case SLJIT_F_LESS:
- case SLJIT_ORDERED_LESS:
- return 0x4;
-
- case SLJIT_UNORDERED_OR_GREATER_EQUAL:
- return 0x5;
-
- default: /* SLJIT_JUMP */
- SLJIT_UNREACHABLE();
- return 0xe;
- }
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
-{
- struct sljit_label *label;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_label(compiler));
-
- if (compiler->last_label && compiler->last_label->size == compiler->size)
- return compiler->last_label;
-
- label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
- PTR_FAIL_IF(!label);
- set_label(label, compiler);
- return label;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
-{
- struct sljit_jump *jump;
- sljit_ins cc;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_jump(compiler, type));
-
- jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
- PTR_FAIL_IF(!jump);
- set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
- type &= 0xff;
-
- PTR_FAIL_IF(emit_imm32_const(compiler, TMP_REG1, 0));
- if (type < SLJIT_JUMP) {
- jump->flags |= IS_COND;
- cc = get_cc(compiler, type);
- jump->flags |= cc << 8;
- PTR_FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
- }
-
- jump->addr = compiler->size;
- if (type <= SLJIT_JUMP)
- PTR_FAIL_IF(push_inst16(compiler, BX | RN3(TMP_REG1)));
- else {
- jump->flags |= IS_BL;
- PTR_FAIL_IF(push_inst16(compiler, BLX | RN3(TMP_REG1)));
- }
-
- return jump;
-}
-
-#ifdef __SOFTFP__
-
-static sljit_s32 softfloat_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src, sljit_u32 *extra_space)
-{
- sljit_u32 is_tail_call = *extra_space & SLJIT_CALL_RETURN;
- sljit_u32 offset = 0;
- sljit_u32 word_arg_offset = 0;
- sljit_u32 float_arg_count = 0;
- sljit_s32 types = 0;
- sljit_u32 src_offset = 4 * sizeof(sljit_sw);
- sljit_u8 offsets[4];
- sljit_u8 *offset_ptr = offsets;
-
- if (src && FAST_IS_REG(*src))
- src_offset = (sljit_u32)reg_map[*src] * sizeof(sljit_sw);
-
- arg_types >>= SLJIT_ARG_SHIFT;
-
- while (arg_types) {
- types = (types << SLJIT_ARG_SHIFT) | (arg_types & SLJIT_ARG_MASK);
-
- switch (arg_types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- if (offset & 0x7)
- offset += sizeof(sljit_sw);
- *offset_ptr++ = (sljit_u8)offset;
- offset += sizeof(sljit_f64);
- float_arg_count++;
- break;
- case SLJIT_ARG_TYPE_F32:
- *offset_ptr++ = (sljit_u8)offset;
- offset += sizeof(sljit_f32);
- float_arg_count++;
- break;
- default:
- *offset_ptr++ = (sljit_u8)offset;
- offset += sizeof(sljit_sw);
- word_arg_offset += sizeof(sljit_sw);
- break;
- }
-
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- if (offset > 4 * sizeof(sljit_sw) && (!is_tail_call || offset > compiler->args_size)) {
- /* Keep lr register on the stack. */
- if (is_tail_call)
- offset += sizeof(sljit_sw);
-
- offset = ((offset - 4 * sizeof(sljit_sw)) + 0x7) & ~(sljit_uw)0x7;
-
- *extra_space = offset;
-
- if (is_tail_call)
- FAIL_IF(emit_stack_frame_release(compiler, (sljit_s32)offset));
- else
- FAIL_IF(push_inst16(compiler, SUB_SP_I | (offset >> 2)));
- } else {
- if (is_tail_call)
- FAIL_IF(emit_stack_frame_release(compiler, -1));
- *extra_space = 0;
- }
-
- SLJIT_ASSERT(reg_map[TMP_REG1] == 12);
-
- /* Process arguments in reversed direction. */
- while (types) {
- switch (types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- float_arg_count--;
- offset = *(--offset_ptr);
-
- SLJIT_ASSERT((offset & 0x7) == 0);
-
- if (offset < 4 * sizeof(sljit_sw)) {
- if (src_offset == offset || src_offset == offset + sizeof(sljit_sw)) {
- FAIL_IF(push_inst16(compiler, MOV | (src_offset << 1) | 4 | (1 << 7)));
- *src = TMP_REG1;
- }
- FAIL_IF(push_inst32(compiler, VMOV2 | 0x100000 | (offset << 10) | ((offset + sizeof(sljit_sw)) << 14) | float_arg_count));
- } else
- FAIL_IF(push_inst32(compiler, VSTR_F32 | 0x800100 | RN4(SLJIT_SP)
- | (float_arg_count << 12) | ((offset - 4 * sizeof(sljit_sw)) >> 2)));
- break;
- case SLJIT_ARG_TYPE_F32:
- float_arg_count--;
- offset = *(--offset_ptr);
-
- if (offset < 4 * sizeof(sljit_sw)) {
- if (src_offset == offset) {
- FAIL_IF(push_inst16(compiler, MOV | (src_offset << 1) | 4 | (1 << 7)));
- *src = TMP_REG1;
- }
- FAIL_IF(push_inst32(compiler, VMOV | 0x100000 | (float_arg_count << 16) | (offset << 10)));
- } else
- FAIL_IF(push_inst32(compiler, VSTR_F32 | 0x800000 | RN4(SLJIT_SP)
- | (float_arg_count << 12) | ((offset - 4 * sizeof(sljit_sw)) >> 2)));
- break;
- default:
- word_arg_offset -= sizeof(sljit_sw);
- offset = *(--offset_ptr);
-
- SLJIT_ASSERT(offset >= word_arg_offset);
-
- if (offset != word_arg_offset) {
- if (offset < 4 * sizeof(sljit_sw)) {
- if (src_offset == offset) {
- FAIL_IF(push_inst16(compiler, MOV | (src_offset << 1) | 4 | (1 << 7)));
- *src = TMP_REG1;
- }
- else if (src_offset == word_arg_offset) {
- *src = (sljit_s32)(1 + (offset >> 2));
- src_offset = offset;
- }
- FAIL_IF(push_inst16(compiler, MOV | (offset >> 2) | (word_arg_offset << 1)));
- } else
- FAIL_IF(push_inst16(compiler, STR_SP | (word_arg_offset << 6) | ((offset - 4 * sizeof(sljit_sw)) >> 2)));
- }
- break;
- }
-
- types >>= SLJIT_ARG_SHIFT;
- }
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 softfloat_post_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types)
-{
- if ((arg_types & SLJIT_ARG_MASK) == SLJIT_ARG_TYPE_F64)
- FAIL_IF(push_inst32(compiler, VMOV2 | (1 << 16) | (0 << 12) | 0));
- if ((arg_types & SLJIT_ARG_MASK) == SLJIT_ARG_TYPE_F32)
- FAIL_IF(push_inst32(compiler, VMOV | (0 << 16) | (0 << 12)));
-
- return SLJIT_SUCCESS;
-}
-
-#else
-
-static sljit_s32 hardfloat_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types)
-{
- sljit_u32 offset = SLJIT_FR0;
- sljit_u32 new_offset = SLJIT_FR0;
- sljit_u32 f32_offset = 0;
-
- /* Remove return value. */
- arg_types >>= SLJIT_ARG_SHIFT;
-
- while (arg_types) {
- switch (arg_types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- if (offset != new_offset)
- FAIL_IF(push_inst32(compiler, VMOV_F32 | SLJIT_32 | DD4(new_offset) | DM4(offset)));
-
- new_offset++;
- offset++;
- break;
- case SLJIT_ARG_TYPE_F32:
- if (f32_offset != 0) {
- FAIL_IF(push_inst32(compiler, VMOV_F32 | 0x400000 | DD4(f32_offset) | DM4(offset)));
- f32_offset = 0;
- } else {
- if (offset != new_offset)
- FAIL_IF(push_inst32(compiler, VMOV_F32 | 0x400000 | DD4(new_offset) | DM4(offset)));
- f32_offset = new_offset;
- new_offset++;
- }
- offset++;
- break;
- }
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- return SLJIT_SUCCESS;
-}
-
-#endif
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types)
-{
-#ifdef __SOFTFP__
- struct sljit_jump *jump;
- sljit_u32 extra_space = (sljit_u32)type;
-#endif
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
-
-#ifdef __SOFTFP__
- if ((type & 0xff) != SLJIT_CALL_REG_ARG) {
- PTR_FAIL_IF(softfloat_call_with_args(compiler, arg_types, NULL, &extra_space));
- SLJIT_ASSERT((extra_space & 0x7) == 0);
-
- if ((type & SLJIT_CALL_RETURN) && extra_space == 0)
- type = SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP);
-
- SLJIT_SKIP_CHECKS(compiler);
- jump = sljit_emit_jump(compiler, type);
- PTR_FAIL_IF(jump == NULL);
-
- if (extra_space > 0) {
- if (type & SLJIT_CALL_RETURN)
- PTR_FAIL_IF(push_inst32(compiler, LDR | RT4(TMP_REG2)
- | RN4(SLJIT_SP) | (extra_space - sizeof(sljit_sw))));
-
- PTR_FAIL_IF(push_inst16(compiler, ADD_SP_I | (extra_space >> 2)));
-
- if (type & SLJIT_CALL_RETURN) {
- PTR_FAIL_IF(push_inst16(compiler, BX | RN3(TMP_REG2)));
- return jump;
- }
- }
-
- SLJIT_ASSERT(!(type & SLJIT_CALL_RETURN));
- PTR_FAIL_IF(softfloat_post_call_with_args(compiler, arg_types));
- return jump;
- }
-#endif /* __SOFTFP__ */
-
- if (type & SLJIT_CALL_RETURN) {
- /* ldmia sp!, {..., lr} */
- PTR_FAIL_IF(emit_stack_frame_release(compiler, -1));
- type = SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP);
- }
-
-#ifndef __SOFTFP__
- if ((type & 0xff) != SLJIT_CALL_REG_ARG)
- PTR_FAIL_IF(hardfloat_call_with_args(compiler, arg_types));
-#endif /* !__SOFTFP__ */
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_jump(compiler, type);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
-{
- struct sljit_jump *jump;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- SLJIT_ASSERT(reg_map[TMP_REG1] != 14);
-
- if (!(src & SLJIT_IMM)) {
- if (FAST_IS_REG(src)) {
- SLJIT_ASSERT(reg_map[src] != 14);
- return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(src));
- }
-
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, src, srcw, TMP_REG1));
- if (type >= SLJIT_FAST_CALL)
- return push_inst16(compiler, BLX | RN3(TMP_REG1));
- }
-
- /* These jumps are converted to jump/call instructions when possible. */
- jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
- FAIL_IF(!jump);
- set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0));
- jump->u.target = (sljit_uw)srcw;
-
- FAIL_IF(emit_imm32_const(compiler, TMP_REG1, 0));
- jump->addr = compiler->size;
- return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(TMP_REG1));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types,
- sljit_s32 src, sljit_sw srcw)
-{
-#ifdef __SOFTFP__
- sljit_u32 extra_space = (sljit_u32)type;
-#endif
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
-
- if (src & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1));
- src = TMP_REG1;
- }
-
- if ((type & SLJIT_CALL_RETURN) && (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options)))) {
- FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG1, src)));
- src = TMP_REG1;
- }
-
-#ifdef __SOFTFP__
- if ((type & 0xff) != SLJIT_CALL_REG_ARG) {
- FAIL_IF(softfloat_call_with_args(compiler, arg_types, &src, &extra_space));
- SLJIT_ASSERT((extra_space & 0x7) == 0);
-
- if ((type & SLJIT_CALL_RETURN) && extra_space == 0)
- type = SLJIT_JUMP;
-
- SLJIT_SKIP_CHECKS(compiler);
- FAIL_IF(sljit_emit_ijump(compiler, type, src, srcw));
-
- if (extra_space > 0) {
- if (type & SLJIT_CALL_RETURN)
- FAIL_IF(push_inst32(compiler, LDR | RT4(TMP_REG2)
- | RN4(SLJIT_SP) | (extra_space - sizeof(sljit_sw))));
-
- FAIL_IF(push_inst16(compiler, ADD_SP_I | (extra_space >> 2)));
-
- if (type & SLJIT_CALL_RETURN)
- return push_inst16(compiler, BX | RN3(TMP_REG2));
- }
-
- SLJIT_ASSERT(!(type & SLJIT_CALL_RETURN));
- return softfloat_post_call_with_args(compiler, arg_types);
- }
-#endif /* __SOFTFP__ */
-
- if (type & SLJIT_CALL_RETURN) {
- /* ldmia sp!, {..., lr} */
- FAIL_IF(emit_stack_frame_release(compiler, -1));
- type = SLJIT_JUMP;
- }
-
-#ifndef __SOFTFP__
- if ((type & 0xff) != SLJIT_CALL_REG_ARG)
- FAIL_IF(hardfloat_call_with_args(compiler, arg_types));
-#endif /* !__SOFTFP__ */
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_ijump(compiler, type, src, srcw);
-}
-
-#ifdef __SOFTFP__
-
-static SLJIT_INLINE sljit_s32 emit_fmov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
-{
- if (compiler->options & SLJIT_ENTER_REG_ARG) {
- if (src == SLJIT_FR0)
- return SLJIT_SUCCESS;
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_fop1(compiler, op, SLJIT_RETURN_FREG, 0, src, srcw);
- }
-
- if (FAST_IS_REG(src)) {
- if (op & SLJIT_32)
- return push_inst32(compiler, VMOV | (1 << 20) | DN4(src) | RT4(SLJIT_R0));
- return push_inst32(compiler, VMOV2 | (1 << 20) | DM4(src) | RT4(SLJIT_R0) | RN4(SLJIT_R1));
- }
-
- SLJIT_SKIP_CHECKS(compiler);
-
- if (op & SLJIT_32)
- return sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R0, 0, src, srcw);
- return sljit_emit_mem(compiler, SLJIT_MOV, SLJIT_REG_PAIR(SLJIT_R0, SLJIT_R1), src, srcw);
-}
-
-#endif /* __SOFTFP__ */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 type)
-{
- sljit_s32 dst_r, flags = GET_ALL_FLAGS(op);
- sljit_ins cc;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- op = GET_OPCODE(op);
- cc = get_cc(compiler, type);
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
-
- if (op < SLJIT_ADD) {
- FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4));
- if (reg_map[dst_r] > 7) {
- FAIL_IF(push_inst32(compiler, MOV_WI | RD4(dst_r) | 1));
- FAIL_IF(push_inst32(compiler, MOV_WI | RD4(dst_r) | 0));
- } else {
- /* The movsi (immediate) instruction does not set flags in IT block. */
- FAIL_IF(push_inst16(compiler, MOVSI | RDN3(dst_r) | 1));
- FAIL_IF(push_inst16(compiler, MOVSI | RDN3(dst_r) | 0));
- }
- if (!(dst & SLJIT_MEM))
- return SLJIT_SUCCESS;
- return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG1, dst, dstw, TMP_REG2);
- }
-
- if (dst & SLJIT_MEM)
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, dst, dstw, TMP_REG2));
-
- if (op == SLJIT_AND) {
- FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4));
- FAIL_IF(push_inst32(compiler, ANDI | RN4(dst_r) | RD4(dst_r) | 1));
- FAIL_IF(push_inst32(compiler, ANDI | RN4(dst_r) | RD4(dst_r) | 0));
- }
- else {
- FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
- FAIL_IF(push_inst32(compiler, ((op == SLJIT_OR) ? ORRI : EORI) | RN4(dst_r) | RD4(dst_r) | 1));
- }
-
- if (dst & SLJIT_MEM)
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG1, dst, dstw, TMP_REG2));
-
- if (!(flags & SLJIT_SET_Z))
- return SLJIT_SUCCESS;
-
- /* The condition must always be set, even if the ORR/EORI is not executed above. */
- return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(TMP_REG1) | RM4(dst_r));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 dst_reg,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_uw cc, tmp;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
-
- cc = get_cc(compiler, type & ~SLJIT_32);
-
- if (!(src & SLJIT_IMM)) {
- FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
- return push_inst16(compiler, MOV | SET_REGS44(dst_reg, src));
- }
-
- tmp = (sljit_uw) srcw;
-
- if (tmp < 0x10000) {
- /* set low 16 bits, set hi 16 bits to 0. */
- FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
- return push_inst32(compiler, MOVW | RD4(dst_reg)
- | COPY_BITS(tmp, 12, 16, 4) | COPY_BITS(tmp, 11, 26, 1) | COPY_BITS(tmp, 8, 12, 3) | (tmp & 0xff));
- }
-
- tmp = get_imm((sljit_uw)srcw);
- if (tmp != INVALID_IMM) {
- FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
- return push_inst32(compiler, MOV_WI | RD4(dst_reg) | tmp);
- }
-
- tmp = get_imm(~(sljit_uw)srcw);
- if (tmp != INVALID_IMM) {
- FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
- return push_inst32(compiler, MVN_WI | RD4(dst_reg) | tmp);
- }
-
- FAIL_IF(push_inst16(compiler, IT | (cc << 4) | ((cc & 0x1) << 3) | 0x4));
-
- tmp = (sljit_uw) srcw;
- FAIL_IF(push_inst32(compiler, MOVW | RD4(dst_reg)
- | COPY_BITS(tmp, 12, 16, 4) | COPY_BITS(tmp, 11, 26, 1) | COPY_BITS(tmp, 8, 12, 3) | (tmp & 0xff)));
- return push_inst32(compiler, MOVT | RD4(dst_reg)
- | COPY_BITS(tmp, 12 + 16, 16, 4) | COPY_BITS(tmp, 11 + 16, 26, 1) | COPY_BITS(tmp, 8 + 16, 12, 3) | ((tmp & 0xff0000) >> 16));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 reg,
- sljit_s32 mem, sljit_sw memw)
-{
- sljit_s32 flags;
- sljit_uw imm, tmp;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
-
- if (!(reg & REG_PAIR_MASK))
- return sljit_emit_mem_unaligned(compiler, type, reg, mem, memw);
-
- if (type & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32)) {
- if ((mem & REG_MASK) == 0) {
- if ((memw & 0xfff) >= (0x1000 - SSIZE_OF(sw))) {
- imm = get_imm((sljit_uw)((memw + 0x1000) & ~0xfff));
-
- if (imm != INVALID_IMM)
- memw = (memw & 0xfff) - 0x1000;
- } else {
- imm = get_imm((sljit_uw)(memw & ~0xfff));
-
- if (imm != INVALID_IMM)
- memw &= 0xff;
- }
-
- if (imm == INVALID_IMM) {
- FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)memw));
- memw = 0;
- } else
- FAIL_IF(push_inst32(compiler, MOV_WI | RD4(TMP_REG1) | imm));
-
- mem = SLJIT_MEM1(TMP_REG1);
- } else if (mem & OFFS_REG_MASK) {
- FAIL_IF(push_inst32(compiler, ADD_W | RD4(TMP_REG1) | RN4(mem & REG_MASK) | RM4(OFFS_REG(mem)) | ((sljit_uw)(memw & 0x3) << 6)));
- memw = 0;
- mem = SLJIT_MEM1(TMP_REG1);
- } else if (memw < -0xff) {
- /* Zero value can be included in the first case. */
- if ((-memw & 0xfff) <= SSIZE_OF(sw))
- tmp = (sljit_uw)((-memw + 0x7ff) & ~0x7ff);
- else
- tmp = (sljit_uw)((-memw + 0xfff) & ~0xfff);
-
- SLJIT_ASSERT(tmp >= (sljit_uw)-memw);
- imm = get_imm(tmp);
-
- if (imm != INVALID_IMM) {
- FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(mem & REG_MASK) | imm));
- memw += (sljit_sw)tmp;
- SLJIT_ASSERT(memw >= 0 && memw <= 0xfff - SSIZE_OF(sw));
- } else {
- FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)memw));
- FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG1, mem & REG_MASK)));
- memw = 0;
- }
-
- mem = SLJIT_MEM1(TMP_REG1);
- } else if (memw >= (0x1000 - SSIZE_OF(sw))) {
- if ((memw & 0xfff) >= (0x1000 - SSIZE_OF(sw))) {
- imm = get_imm((sljit_uw)((memw + 0x1000) & ~0xfff));
-
- if (imm != INVALID_IMM)
- memw = (memw & 0xfff) - 0x1000;
- } else {
- imm = get_imm((sljit_uw)(memw & ~0xfff));
-
- if (imm != INVALID_IMM)
- memw &= 0xfff;
- }
-
- if (imm != INVALID_IMM) {
- SLJIT_ASSERT(memw >= -0xff && memw <= 0xfff);
- FAIL_IF(push_inst32(compiler, ADD_WI | RD4(TMP_REG1) | RN4(mem & REG_MASK) | imm));
- } else {
- FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)memw));
- FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG1, mem & REG_MASK)));
- memw = 0;
- }
-
- mem = SLJIT_MEM1(TMP_REG1);
- }
-
- flags = WORD_SIZE;
-
- SLJIT_ASSERT(memw <= 0xfff - SSIZE_OF(sw) && memw >= -0xff);
-
- if (type & SLJIT_MEM_STORE) {
- flags |= STORE;
- } else if (REG_PAIR_FIRST(reg) == (mem & REG_MASK)) {
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE, REG_PAIR_SECOND(reg), mem, memw + SSIZE_OF(sw), TMP_REG2));
- return emit_op_mem(compiler, WORD_SIZE, REG_PAIR_FIRST(reg), mem, memw, TMP_REG2);
- }
-
- FAIL_IF(emit_op_mem(compiler, flags, REG_PAIR_FIRST(reg), mem, memw, TMP_REG2));
- return emit_op_mem(compiler, flags, REG_PAIR_SECOND(reg), mem, memw + SSIZE_OF(sw), TMP_REG2);
- }
-
- flags = 1 << 23;
-
- if ((mem & REG_MASK) == 0) {
- tmp = (sljit_uw)(memw & 0x7fc);
- imm = get_imm((sljit_uw)((memw + (tmp <= 0x400 ? 0 : 0x400)) & ~0x3fc));
-
- if (imm == INVALID_IMM) {
- FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)memw));
- memw = 0;
- } else {
- FAIL_IF(push_inst32(compiler, MOV_WI | RD4(TMP_REG1) | imm));
- memw = (memw & 0x3fc) >> 2;
-
- if (tmp > 0x400) {
- memw = 0x100 - memw;
- flags = 0;
- }
-
- SLJIT_ASSERT(memw >= 0 && memw <= 0xff);
- }
-
- mem = SLJIT_MEM1(TMP_REG1);
- } else if (mem & OFFS_REG_MASK) {
- FAIL_IF(push_inst32(compiler, ADD_W | RD4(TMP_REG1) | RN4(mem & REG_MASK) | RM4(OFFS_REG(mem)) | ((sljit_uw)(memw & 0x3) << 6)));
- memw = 0;
- mem = SLJIT_MEM1(TMP_REG1);
- } else if (memw < 0) {
- if ((-memw & ~0x3fc) == 0) {
- flags = 0;
- memw = -memw >> 2;
- } else {
- tmp = (sljit_uw)(-memw & 0x7fc);
- imm = get_imm((sljit_uw)((-memw + (tmp <= 0x400 ? 0 : 0x400)) & ~0x3fc));
-
- if (imm != INVALID_IMM) {
- FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(mem & REG_MASK) | imm));
- memw = (-memw & 0x3fc) >> 2;
-
- if (tmp <= 0x400)
- flags = 0;
- else
- memw = 0x100 - memw;
- } else {
- FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)memw));
- FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG1, mem & REG_MASK)));
- memw = 0;
- }
-
- mem = SLJIT_MEM1(TMP_REG1);
- }
- } else if ((memw & ~0x3fc) != 0) {
- tmp = (sljit_uw)(memw & 0x7fc);
- imm = get_imm((sljit_uw)((memw + (tmp <= 0x400 ? 0 : 0x400)) & ~0x3fc));
-
- if (imm != INVALID_IMM) {
- FAIL_IF(push_inst32(compiler, ADD_WI | RD4(TMP_REG1) | RN4(mem & REG_MASK) | imm));
- memw = (memw & 0x3fc) >> 2;
-
- if (tmp > 0x400) {
- memw = 0x100 - memw;
- flags = 0;
- }
- } else {
- FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)memw));
- FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG1, mem & REG_MASK)));
- memw = 0;
- }
-
- mem = SLJIT_MEM1(TMP_REG1);
- } else
- memw >>= 2;
-
- SLJIT_ASSERT(memw >= 0 && memw <= 0xff);
- return push_inst32(compiler, ((type & SLJIT_MEM_STORE) ? STRD : LDRD) | (sljit_ins)flags | RN4(mem & REG_MASK) | RT4(REG_PAIR_FIRST(reg)) | RD4(REG_PAIR_SECOND(reg)) | (sljit_ins)memw);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 reg,
- sljit_s32 mem, sljit_sw memw)
-{
- sljit_s32 flags;
- sljit_ins inst;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_mem_update(compiler, type, reg, mem, memw));
-
- if ((mem & OFFS_REG_MASK) || (memw > 255 || memw < -255))
- return SLJIT_ERR_UNSUPPORTED;
-
- if (type & SLJIT_MEM_SUPP)
- return SLJIT_SUCCESS;
-
- switch (type & 0xff) {
- case SLJIT_MOV:
- case SLJIT_MOV_U32:
- case SLJIT_MOV_S32:
- case SLJIT_MOV32:
- case SLJIT_MOV_P:
- flags = WORD_SIZE;
- break;
- case SLJIT_MOV_U8:
- flags = BYTE_SIZE;
- break;
- case SLJIT_MOV_S8:
- flags = BYTE_SIZE | SIGNED;
- break;
- case SLJIT_MOV_U16:
- flags = HALF_SIZE;
- break;
- case SLJIT_MOV_S16:
- flags = HALF_SIZE | SIGNED;
- break;
- default:
- SLJIT_UNREACHABLE();
- flags = WORD_SIZE;
- break;
- }
-
- if (type & SLJIT_MEM_STORE)
- flags |= STORE;
-
- inst = sljit_mem32[flags] | 0x900;
-
- if (!(type & SLJIT_MEM_POST))
- inst |= 0x400;
-
- if (memw >= 0)
- inst |= 0x200;
- else
- memw = -memw;
-
- return push_inst32(compiler, inst | RT4(reg) | RN4(mem & REG_MASK) | (sljit_ins)memw);
-}
-
-static sljit_s32 update_mem_addr(struct sljit_compiler *compiler, sljit_s32 *mem, sljit_sw *memw, sljit_s32 max_offset)
-{
- sljit_s32 arg = *mem;
- sljit_sw argw = *memw;
- sljit_uw imm;
-
- *mem = TMP_REG1;
-
- if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
- *memw = 0;
- return push_inst32(compiler, ADD_W | RD4(TMP_REG1) | RN4(arg & REG_MASK) | RM4(OFFS_REG(arg)) | ((sljit_uw)(argw & 0x3) << 6));
- }
-
- arg &= REG_MASK;
-
- if (arg) {
- if (argw <= max_offset && argw >= -0xff) {
- *mem = arg;
- return SLJIT_SUCCESS;
- }
-
- if (argw < 0) {
- imm = get_imm((sljit_uw)(-argw & ~0xff));
-
- if (imm) {
- *memw = -(-argw & 0xff);
- return push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(arg) | imm);
- }
- } else if ((argw & 0xfff) <= max_offset) {
- imm = get_imm((sljit_uw)(argw & ~0xfff));
-
- if (imm) {
- *memw = argw & 0xfff;
- return push_inst32(compiler, ADD_WI | RD4(TMP_REG1) | RN4(arg) | imm);
- }
- } else {
- imm = get_imm((sljit_uw)((argw | 0xfff) + 1));
-
- if (imm) {
- *memw = (argw & 0xfff) - 0x1000;
- return push_inst32(compiler, ADD_WI | RD4(TMP_REG1) | RN4(arg) | imm);
- }
- }
- }
-
- imm = (sljit_uw)(argw & ~0xfff);
-
- if ((argw & 0xfff) > max_offset) {
- imm += 0x1000;
- *memw = (argw & 0xfff) - 0x1000;
- } else
- *memw = argw & 0xfff;
-
- FAIL_IF(load_immediate(compiler, TMP_REG1, imm));
-
- if (arg == 0)
- return SLJIT_SUCCESS;
-
- return push_inst16(compiler, ADD | SET_REGS44(TMP_REG1, arg));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 freg,
- sljit_s32 mem, sljit_sw memw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
-
- if (type & SLJIT_MEM_UNALIGNED_32)
- return emit_fop_mem(compiler, ((type ^ SLJIT_32) & SLJIT_32) | ((type & SLJIT_MEM_STORE) ? 0 : FPU_LOAD), freg, mem, memw);
-
- if (type & SLJIT_MEM_STORE) {
- FAIL_IF(push_inst32(compiler, VMOV | (1 << 20) | DN4(freg) | RT4(TMP_REG2)));
-
- if (type & SLJIT_32)
- return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, mem, memw, TMP_REG1);
-
- FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xfff - 4));
- mem |= SLJIT_MEM;
-
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, mem, memw, TMP_REG1));
- FAIL_IF(push_inst32(compiler, VMOV | (1 << 20) | DN4(freg) | 0x80 | RT4(TMP_REG2)));
- return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, mem, memw + 4, TMP_REG1);
- }
-
- if (type & SLJIT_32) {
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, mem, memw, TMP_REG1));
- return push_inst32(compiler, VMOV | DN4(freg) | RT4(TMP_REG2));
- }
-
- FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xfff - 4));
- mem |= SLJIT_MEM;
-
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, mem, memw, TMP_REG1));
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, mem, memw + 4, TMP_REG1));
- return push_inst32(compiler, VMOV2 | DM4(freg) | RT4(TMP_REG2) | RN4(TMP_REG1));
-}
-
-#undef FPU_LOAD
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
-{
- struct sljit_const *const_;
- sljit_s32 dst_r;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
- PTR_FAIL_IF(!const_);
- set_const(const_, compiler);
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
- PTR_FAIL_IF(emit_imm32_const(compiler, dst_r, (sljit_uw)init_value));
-
- if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2));
- return const_;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
-{
- struct sljit_put_label *put_label;
- sljit_s32 dst_r;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
- PTR_FAIL_IF(!put_label);
- set_put_label(put_label, compiler, 0);
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
- PTR_FAIL_IF(emit_imm32_const(compiler, dst_r, 0));
-
- if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2));
- return put_label;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
-{
- sljit_u16 *inst = (sljit_u16*)addr;
- SLJIT_UNUSED_ARG(executable_offset);
-
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 0);
- modify_imm32_const(inst, new_target);
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 1);
- inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 4);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
-{
- sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
-}
diff --git a/contrib/libs/pcre2/src/sljit/sljitNativeMIPS_32.c b/contrib/libs/pcre2/src/sljit/sljitNativeMIPS_32.c
deleted file mode 100644
index e6853c98f6..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitNativeMIPS_32.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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.
- */
-
-/* mips 32-bit arch dependent functions. */
-
-static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm)
-{
- if (!(imm & ~0xffff))
- return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);
-
- if (imm < 0 && imm >= SIMM_MIN)
- return push_inst(compiler, ADDIU | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);
-
- FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(imm >> 16), dst_ar));
- return (imm & 0xffff) ? push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar) : SLJIT_SUCCESS;
-}
-
-static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value)
-{
- FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 16), DR(dst)));
- return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
-{
- sljit_ins *inst = (sljit_ins *)addr;
- SLJIT_UNUSED_ARG(executable_offset);
-
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
- SLJIT_ASSERT((inst[0] & 0xffe00000) == LUI && (inst[1] & 0xfc000000) == ORI);
- inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);
- inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
- inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 2);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
-{
- sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
-}
-
-static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_ins *ins_ptr, sljit_u32 *extra_space)
-{
- sljit_u32 is_tail_call = *extra_space & SLJIT_CALL_RETURN;
- sljit_u32 offset = 0;
- sljit_s32 float_arg_count = 0;
- sljit_s32 word_arg_count = 0;
- sljit_s32 types = 0;
- sljit_ins prev_ins = NOP;
- sljit_ins ins = NOP;
- sljit_u8 offsets[4];
- sljit_u8 *offsets_ptr = offsets;
-
- SLJIT_ASSERT(reg_map[TMP_REG1] == 4 && freg_map[TMP_FREG1] == 12);
-
- arg_types >>= SLJIT_ARG_SHIFT;
-
- /* See ABI description in sljit_emit_enter. */
-
- while (arg_types) {
- types = (types << SLJIT_ARG_SHIFT) | (arg_types & SLJIT_ARG_MASK);
- *offsets_ptr = (sljit_u8)offset;
-
- switch (arg_types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- if (offset & 0x7) {
- offset += sizeof(sljit_sw);
- *offsets_ptr = (sljit_u8)offset;
- }
-
- if (word_arg_count == 0 && float_arg_count <= 1)
- *offsets_ptr = (sljit_u8)(254 + float_arg_count);
-
- offset += sizeof(sljit_f64);
- float_arg_count++;
- break;
- case SLJIT_ARG_TYPE_F32:
- if (word_arg_count == 0 && float_arg_count <= 1)
- *offsets_ptr = (sljit_u8)(254 + float_arg_count);
-
- offset += sizeof(sljit_f32);
- float_arg_count++;
- break;
- default:
- offset += sizeof(sljit_sw);
- word_arg_count++;
- break;
- }
-
- arg_types >>= SLJIT_ARG_SHIFT;
- offsets_ptr++;
- }
-
- /* Stack is aligned to 16 bytes. */
- SLJIT_ASSERT(offset <= 8 * sizeof(sljit_sw));
-
- if (offset > 4 * sizeof(sljit_sw) && (!is_tail_call || offset > compiler->args_size)) {
- if (is_tail_call) {
- offset = (offset + sizeof(sljit_sw) + 15) & ~(sljit_uw)0xf;
- FAIL_IF(emit_stack_frame_release(compiler, (sljit_s32)offset, &prev_ins));
- *extra_space = offset;
- } else {
- FAIL_IF(push_inst(compiler, ADDIU | S(SLJIT_SP) | T(SLJIT_SP) | IMM(-16), DR(SLJIT_SP)));
- *extra_space = 16;
- }
- } else {
- if (is_tail_call)
- FAIL_IF(emit_stack_frame_release(compiler, 0, &prev_ins));
- *extra_space = 0;
- }
-
- while (types) {
- --offsets_ptr;
-
- switch (types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- if (*offsets_ptr < 4 * sizeof (sljit_sw)) {
- if (prev_ins != NOP)
- FAIL_IF(push_inst(compiler, prev_ins, MOVABLE_INS));
-
- /* Must be preceded by at least one other argument,
- * and its starting offset must be 8 because of alignment. */
- SLJIT_ASSERT((*offsets_ptr >> 2) == 2);
-
- prev_ins = MFC1 | TA(6) | FS(float_arg_count) | (1 << 11);
- ins = MFC1 | TA(7) | FS(float_arg_count);
- } else if (*offsets_ptr < 254)
- ins = SDC1 | S(SLJIT_SP) | FT(float_arg_count) | IMM(*offsets_ptr);
- else if (*offsets_ptr == 254)
- ins = MOV_S | FMT_D | FS(SLJIT_FR0) | FD(TMP_FREG1);
-
- float_arg_count--;
- break;
- case SLJIT_ARG_TYPE_F32:
- if (*offsets_ptr < 4 * sizeof (sljit_sw))
- ins = MFC1 | TA(4 + (*offsets_ptr >> 2)) | FS(float_arg_count);
- else if (*offsets_ptr < 254)
- ins = SWC1 | S(SLJIT_SP) | FT(float_arg_count) | IMM(*offsets_ptr);
- else if (*offsets_ptr == 254)
- ins = MOV_S | FMT_S | FS(SLJIT_FR0) | FD(TMP_FREG1);
-
- float_arg_count--;
- break;
- default:
- if (*offsets_ptr >= 4 * sizeof (sljit_sw))
- ins = SW | S(SLJIT_SP) | T(word_arg_count) | IMM(*offsets_ptr);
- else if ((*offsets_ptr >> 2) != word_arg_count - 1)
- ins = ADDU | S(word_arg_count) | TA(0) | DA(4 + (*offsets_ptr >> 2));
- else if (*offsets_ptr == 0)
- ins = ADDU | S(SLJIT_R0) | TA(0) | DA(4);
-
- word_arg_count--;
- break;
- }
-
- if (ins != NOP) {
- if (prev_ins != NOP)
- FAIL_IF(push_inst(compiler, prev_ins, MOVABLE_INS));
- prev_ins = ins;
- ins = NOP;
- }
-
- types >>= SLJIT_ARG_SHIFT;
- }
-
- *ins_ptr = prev_ins;
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types)
-{
- struct sljit_jump *jump;
- sljit_u32 extra_space = 0;
- sljit_ins ins = NOP;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
-
- jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
- PTR_FAIL_IF(!jump);
- set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
-
- if ((type & 0xff) != SLJIT_CALL_REG_ARG) {
- extra_space = (sljit_u32)type;
- PTR_FAIL_IF(call_with_args(compiler, arg_types, &ins, &extra_space));
- } else if (type & SLJIT_CALL_RETURN)
- PTR_FAIL_IF(emit_stack_frame_release(compiler, 0, &ins));
-
- SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
-
- if (ins == NOP && compiler->delay_slot != UNMOVABLE_INS)
- jump->flags |= IS_MOVABLE;
-
- if (!(type & SLJIT_CALL_RETURN) || extra_space > 0) {
- jump->flags |= IS_JAL;
-
- if ((type & 0xff) != SLJIT_CALL_REG_ARG)
- jump->flags |= IS_CALL;
-
- PTR_FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
- } else
- PTR_FAIL_IF(push_inst(compiler, JR | S(PIC_ADDR_REG), UNMOVABLE_INS));
-
- jump->addr = compiler->size;
- PTR_FAIL_IF(push_inst(compiler, ins, UNMOVABLE_INS));
-
- /* Maximum number of instructions required for generating a constant. */
- compiler->size += 2;
-
- if (extra_space == 0)
- return jump;
-
- if (type & SLJIT_CALL_RETURN)
- PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG,
- SLJIT_MEM1(SLJIT_SP), (sljit_sw)(extra_space - sizeof(sljit_sw))));
-
- if (type & SLJIT_CALL_RETURN)
- PTR_FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
-
- PTR_FAIL_IF(push_inst(compiler, ADDIU | S(SLJIT_SP) | T(SLJIT_SP) | IMM(extra_space),
- (type & SLJIT_CALL_RETURN) ? UNMOVABLE_INS : DR(SLJIT_SP)));
- return jump;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_u32 extra_space = (sljit_u32)type;
- sljit_ins ins;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
-
- if (src & SLJIT_MEM) {
- ADJUST_LOCAL_OFFSET(src, srcw);
- FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(PIC_ADDR_REG), src, srcw));
- src = PIC_ADDR_REG;
- srcw = 0;
- }
-
- if ((type & 0xff) == SLJIT_CALL_REG_ARG) {
- if (type & SLJIT_CALL_RETURN) {
- if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
- FAIL_IF(push_inst(compiler, ADDU | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));
- src = PIC_ADDR_REG;
- srcw = 0;
- }
-
- FAIL_IF(emit_stack_frame_release(compiler, 0, &ins));
-
- if (ins != NOP)
- FAIL_IF(push_inst(compiler, ins, MOVABLE_INS));
- }
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_ijump(compiler, type, src, srcw);
- }
-
- SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
-
- if (src & SLJIT_IMM)
- FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw));
- else if (src != PIC_ADDR_REG)
- FAIL_IF(push_inst(compiler, ADDU | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));
-
- FAIL_IF(call_with_args(compiler, arg_types, &ins, &extra_space));
-
- /* Register input. */
- if (!(type & SLJIT_CALL_RETURN) || extra_space > 0)
- FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
- else
- FAIL_IF(push_inst(compiler, JR | S(PIC_ADDR_REG), UNMOVABLE_INS));
- FAIL_IF(push_inst(compiler, ins, UNMOVABLE_INS));
-
- if (extra_space == 0)
- return SLJIT_SUCCESS;
-
- if (type & SLJIT_CALL_RETURN)
- FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG,
- SLJIT_MEM1(SLJIT_SP), (sljit_sw)(extra_space - sizeof(sljit_sw))));
-
- if (type & SLJIT_CALL_RETURN)
- FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
-
- return push_inst(compiler, ADDIU | S(SLJIT_SP) | T(SLJIT_SP) | IMM(extra_space),
- (type & SLJIT_CALL_RETURN) ? UNMOVABLE_INS : DR(SLJIT_SP));
-}
diff --git a/contrib/libs/pcre2/src/sljit/sljitNativeMIPS_64.c b/contrib/libs/pcre2/src/sljit/sljitNativeMIPS_64.c
deleted file mode 100644
index d2a5924f8e..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitNativeMIPS_64.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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.
- */
-
-/* mips 64-bit arch dependent functions. */
-
-static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm)
-{
- sljit_s32 shift = 32;
- sljit_s32 shift2;
- sljit_s32 inv = 0;
- sljit_ins ins;
- sljit_uw uimm;
-
- if (!(imm & ~0xffff))
- return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);
-
- if (imm < 0 && imm >= SIMM_MIN)
- return push_inst(compiler, ADDIU | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);
-
- if (imm <= 0x7fffffffl && imm >= -0x80000000l) {
- FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(imm >> 16), dst_ar));
- return (imm & 0xffff) ? push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar) : SLJIT_SUCCESS;
- }
-
- /* Zero extended number. */
- uimm = (sljit_uw)imm;
- if (imm < 0) {
- uimm = ~(sljit_uw)imm;
- inv = 1;
- }
-
- while (!(uimm & 0xff00000000000000l)) {
- shift -= 8;
- uimm <<= 8;
- }
-
- if (!(uimm & 0xf000000000000000l)) {
- shift -= 4;
- uimm <<= 4;
- }
-
- if (!(uimm & 0xc000000000000000l)) {
- shift -= 2;
- uimm <<= 2;
- }
-
- if ((sljit_sw)uimm < 0) {
- uimm >>= 1;
- shift += 1;
- }
- SLJIT_ASSERT(((uimm & 0xc000000000000000l) == 0x4000000000000000l) && (shift > 0) && (shift <= 32));
-
- if (inv)
- uimm = ~uimm;
-
- FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(uimm >> 48), dst_ar));
- if (uimm & 0x0000ffff00000000l)
- FAIL_IF(push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(uimm >> 32), dst_ar));
-
- imm &= (1l << shift) - 1;
- if (!(imm & ~0xffff)) {
- ins = (shift == 32) ? DSLL32 : DSLL;
- if (shift < 32)
- ins |= SH_IMM(shift);
- FAIL_IF(push_inst(compiler, ins | TA(dst_ar) | DA(dst_ar), dst_ar));
- return !(imm & 0xffff) ? SLJIT_SUCCESS : push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar);
- }
-
- /* Double shifts needs to be performed. */
- uimm <<= 32;
- shift2 = shift - 16;
-
- while (!(uimm & 0xf000000000000000l)) {
- shift2 -= 4;
- uimm <<= 4;
- }
-
- if (!(uimm & 0xc000000000000000l)) {
- shift2 -= 2;
- uimm <<= 2;
- }
-
- if (!(uimm & 0x8000000000000000l)) {
- shift2--;
- uimm <<= 1;
- }
-
- SLJIT_ASSERT((uimm & 0x8000000000000000l) && (shift2 > 0) && (shift2 <= 16));
-
- FAIL_IF(push_inst(compiler, DSLL | TA(dst_ar) | DA(dst_ar) | SH_IMM(shift - shift2), dst_ar));
- FAIL_IF(push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(uimm >> 48), dst_ar));
- FAIL_IF(push_inst(compiler, DSLL | TA(dst_ar) | DA(dst_ar) | SH_IMM(shift2), dst_ar));
-
- imm &= (1l << shift2) - 1;
- return !(imm & 0xffff) ? SLJIT_SUCCESS : push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar);
-}
-
-static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value)
-{
- FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 48), DR(dst)));
- FAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 32), DR(dst)));
- FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst)));
- FAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 16), DR(dst)));
- FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst)));
- return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
-{
- sljit_ins *inst = (sljit_ins *)addr;
- SLJIT_UNUSED_ARG(executable_offset);
-
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 6, 0);
- inst[0] = (inst[0] & 0xffff0000) | ((sljit_ins)(new_target >> 48) & 0xffff);
- inst[1] = (inst[1] & 0xffff0000) | ((sljit_ins)(new_target >> 32) & 0xffff);
- inst[3] = (inst[3] & 0xffff0000) | ((sljit_ins)(new_target >> 16) & 0xffff);
- inst[5] = (inst[5] & 0xffff0000) | ((sljit_ins)new_target & 0xffff);
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 6, 1);
- inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 6);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
-{
- sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
-}
-
-static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_ins *ins_ptr)
-{
- sljit_s32 arg_count = 0;
- sljit_s32 word_arg_count = 0;
- sljit_s32 float_arg_count = 0;
- sljit_s32 types = 0;
- sljit_ins prev_ins = *ins_ptr;
- sljit_ins ins = NOP;
-
- SLJIT_ASSERT(reg_map[TMP_REG1] == 4 && freg_map[TMP_FREG1] == 12);
-
- arg_types >>= SLJIT_ARG_SHIFT;
-
- while (arg_types) {
- types = (types << SLJIT_ARG_SHIFT) | (arg_types & SLJIT_ARG_MASK);
-
- switch (arg_types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- case SLJIT_ARG_TYPE_F32:
- arg_count++;
- float_arg_count++;
- break;
- default:
- arg_count++;
- word_arg_count++;
- break;
- }
-
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- while (types) {
- switch (types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- if (arg_count != float_arg_count)
- ins = MOV_S | FMT_D | FS(float_arg_count) | FD(arg_count);
- else if (arg_count == 1)
- ins = MOV_S | FMT_D | FS(SLJIT_FR0) | FD(TMP_FREG1);
- arg_count--;
- float_arg_count--;
- break;
- case SLJIT_ARG_TYPE_F32:
- if (arg_count != float_arg_count)
- ins = MOV_S | FMT_S | FS(float_arg_count) | FD(arg_count);
- else if (arg_count == 1)
- ins = MOV_S | FMT_S | FS(SLJIT_FR0) | FD(TMP_FREG1);
- arg_count--;
- float_arg_count--;
- break;
- default:
- if (arg_count != word_arg_count)
- ins = DADDU | S(word_arg_count) | TA(0) | D(arg_count);
- else if (arg_count == 1)
- ins = DADDU | S(SLJIT_R0) | TA(0) | DA(4);
- arg_count--;
- word_arg_count--;
- break;
- }
-
- if (ins != NOP) {
- if (prev_ins != NOP)
- FAIL_IF(push_inst(compiler, prev_ins, MOVABLE_INS));
- prev_ins = ins;
- ins = NOP;
- }
-
- types >>= SLJIT_ARG_SHIFT;
- }
-
- *ins_ptr = prev_ins;
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types)
-{
- struct sljit_jump *jump;
- sljit_ins ins = NOP;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
-
- jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
- PTR_FAIL_IF(!jump);
- set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
-
- if (type & SLJIT_CALL_RETURN)
- PTR_FAIL_IF(emit_stack_frame_release(compiler, 0, &ins));
-
- if ((type & 0xff) != SLJIT_CALL_REG_ARG)
- PTR_FAIL_IF(call_with_args(compiler, arg_types, &ins));
-
- SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
-
- if (ins == NOP && compiler->delay_slot != UNMOVABLE_INS)
- jump->flags |= IS_MOVABLE;
-
- if (!(type & SLJIT_CALL_RETURN)) {
- jump->flags |= IS_JAL;
-
- if ((type & 0xff) != SLJIT_CALL_REG_ARG)
- jump->flags |= IS_CALL;
-
- PTR_FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
- } else
- PTR_FAIL_IF(push_inst(compiler, JR | S(PIC_ADDR_REG), UNMOVABLE_INS));
-
- jump->addr = compiler->size;
- PTR_FAIL_IF(push_inst(compiler, ins, UNMOVABLE_INS));
-
- /* Maximum number of instructions required for generating a constant. */
- compiler->size += 6;
- return jump;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_ins ins = NOP;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
-
- if (src & SLJIT_MEM) {
- ADJUST_LOCAL_OFFSET(src, srcw);
- FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(PIC_ADDR_REG), src, srcw));
- src = PIC_ADDR_REG;
- srcw = 0;
- }
-
- if ((type & 0xff) == SLJIT_CALL_REG_ARG) {
- if (type & SLJIT_CALL_RETURN) {
- if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
- FAIL_IF(push_inst(compiler, DADDU | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));
- src = PIC_ADDR_REG;
- srcw = 0;
- }
-
- FAIL_IF(emit_stack_frame_release(compiler, 0, &ins));
-
- if (ins != NOP)
- FAIL_IF(push_inst(compiler, ins, MOVABLE_INS));
- }
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_ijump(compiler, type, src, srcw);
- }
-
- SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
-
- if (src & SLJIT_IMM)
- FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw));
- else if (src != PIC_ADDR_REG)
- FAIL_IF(push_inst(compiler, DADDU | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));
-
- if (type & SLJIT_CALL_RETURN)
- FAIL_IF(emit_stack_frame_release(compiler, 0, &ins));
-
- FAIL_IF(call_with_args(compiler, arg_types, &ins));
-
- /* Register input. */
- if (!(type & SLJIT_CALL_RETURN))
- FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
- else
- FAIL_IF(push_inst(compiler, JR | S(PIC_ADDR_REG), UNMOVABLE_INS));
- return push_inst(compiler, ins, UNMOVABLE_INS);
-}
diff --git a/contrib/libs/pcre2/src/sljit/sljitNativeMIPS_common.c b/contrib/libs/pcre2/src/sljit/sljitNativeMIPS_common.c
deleted file mode 100644
index 9afe901c38..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitNativeMIPS_common.c
+++ /dev/null
@@ -1,3720 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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.
- */
-
-/* Latest MIPS architecture. */
-
-#ifndef __mips_hard_float
-/* Disable automatic detection, covers both -msoft-float and -mno-float */
-#undef SLJIT_IS_FPU_AVAILABLE
-#define SLJIT_IS_FPU_AVAILABLE 0
-#endif
-
-SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
-{
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
-
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- return "MIPS32-R6" SLJIT_CPUINFO;
-#else /* !SLJIT_CONFIG_MIPS_32 */
- return "MIPS64-R6" SLJIT_CPUINFO;
-#endif /* SLJIT_CONFIG_MIPS_32 */
-
-#elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
-
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- return "MIPS32-R2" SLJIT_CPUINFO;
-#else /* !SLJIT_CONFIG_MIPS_32 */
- return "MIPS64-R2" SLJIT_CPUINFO;
-#endif /* SLJIT_CONFIG_MIPS_32 */
-
-#elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
-
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- return "MIPS32-R1" SLJIT_CPUINFO;
-#else /* !SLJIT_CONFIG_MIPS_32 */
- return "MIPS64-R1" SLJIT_CPUINFO;
-#endif /* SLJIT_CONFIG_MIPS_32 */
-
-#else /* SLJIT_MIPS_REV < 1 */
- return "MIPS III" SLJIT_CPUINFO;
-#endif /* SLJIT_MIPS_REV >= 6 */
-}
-
-/* Length of an instruction word
- Both for mips-32 and mips-64 */
-typedef sljit_u32 sljit_ins;
-
-#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
-#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
-#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
-
-/* For position independent code, t9 must contain the function address. */
-#define PIC_ADDR_REG TMP_REG2
-
-/* Floating point status register. */
-#define FCSR_REG 31
-/* Return address register. */
-#define RETURN_ADDR_REG 31
-
-/* Flags are kept in volatile registers. */
-#define EQUAL_FLAG 3
-#define OTHER_FLAG 1
-
-#define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
-#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
-#define TMP_FREG3 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3)
-
-static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
- 0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 4, 25, 31
-};
-
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
-
-static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
- 0, 0, 14, 2, 4, 6, 8, 18, 30, 28, 26, 24, 22, 20, 12, 10, 16
-};
-
-#else
-
-static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
- 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 1, 2, 3, 4, 5, 6, 7, 8, 9, 31, 30, 29, 28, 27, 26, 25, 24, 12, 11, 10
-};
-
-#endif
-
-/* --------------------------------------------------------------------- */
-/* Instrucion forms */
-/* --------------------------------------------------------------------- */
-
-#define S(s) ((sljit_ins)reg_map[s] << 21)
-#define T(t) ((sljit_ins)reg_map[t] << 16)
-#define D(d) ((sljit_ins)reg_map[d] << 11)
-#define FT(t) ((sljit_ins)freg_map[t] << 16)
-#define FS(s) ((sljit_ins)freg_map[s] << 11)
-#define FD(d) ((sljit_ins)freg_map[d] << 6)
-/* Absolute registers. */
-#define SA(s) ((sljit_ins)(s) << 21)
-#define TA(t) ((sljit_ins)(t) << 16)
-#define DA(d) ((sljit_ins)(d) << 11)
-#define IMM(imm) ((sljit_ins)(imm) & 0xffff)
-#define SH_IMM(imm) ((sljit_ins)(imm) << 6)
-
-#define DR(dr) (reg_map[dr])
-#define FR(dr) (freg_map[dr])
-#define HI(opcode) ((sljit_ins)(opcode) << 26)
-#define LO(opcode) ((sljit_ins)(opcode))
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
-/* CMP.cond.fmt */
-/* S = (20 << 21) D = (21 << 21) */
-#define CMP_FMT_S (20 << 21)
-#endif /* SLJIT_MIPS_REV >= 6 */
-/* S = (16 << 21) D = (17 << 21) */
-#define FMT_S (16 << 21)
-#define FMT_D (17 << 21)
-
-#define ABS_S (HI(17) | FMT_S | LO(5))
-#define ADD_S (HI(17) | FMT_S | LO(0))
-#define ADDIU (HI(9))
-#define ADDU (HI(0) | LO(33))
-#define AND (HI(0) | LO(36))
-#define ANDI (HI(12))
-#define B (HI(4))
-#define BAL (HI(1) | (17 << 16))
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
-#define BC1EQZ (HI(17) | (9 << 21) | FT(TMP_FREG3))
-#define BC1NEZ (HI(17) | (13 << 21) | FT(TMP_FREG3))
-#else /* SLJIT_MIPS_REV < 6 */
-#define BC1F (HI(17) | (8 << 21))
-#define BC1T (HI(17) | (8 << 21) | (1 << 16))
-#endif /* SLJIT_MIPS_REV >= 6 */
-#define BEQ (HI(4))
-#define BGEZ (HI(1) | (1 << 16))
-#define BGTZ (HI(7))
-#define BLEZ (HI(6))
-#define BLTZ (HI(1) | (0 << 16))
-#define BNE (HI(5))
-#define BREAK (HI(0) | LO(13))
-#define CFC1 (HI(17) | (2 << 21))
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
-#define C_EQ_S (HI(17) | CMP_FMT_S | LO(2))
-#define C_OLE_S (HI(17) | CMP_FMT_S | LO(6))
-#define C_OLT_S (HI(17) | CMP_FMT_S | LO(4))
-#define C_UEQ_S (HI(17) | CMP_FMT_S | LO(3))
-#define C_ULE_S (HI(17) | CMP_FMT_S | LO(7))
-#define C_ULT_S (HI(17) | CMP_FMT_S | LO(5))
-#define C_UN_S (HI(17) | CMP_FMT_S | LO(1))
-#define C_FD (FD(TMP_FREG3))
-#else /* SLJIT_MIPS_REV < 6 */
-#define C_EQ_S (HI(17) | FMT_S | LO(50))
-#define C_OLE_S (HI(17) | FMT_S | LO(54))
-#define C_OLT_S (HI(17) | FMT_S | LO(52))
-#define C_UEQ_S (HI(17) | FMT_S | LO(51))
-#define C_ULE_S (HI(17) | FMT_S | LO(55))
-#define C_ULT_S (HI(17) | FMT_S | LO(53))
-#define C_UN_S (HI(17) | FMT_S | LO(49))
-#define C_FD (0)
-#endif /* SLJIT_MIPS_REV >= 6 */
-#define CVT_S_S (HI(17) | FMT_S | LO(32))
-#define DADDIU (HI(25))
-#define DADDU (HI(0) | LO(45))
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
-#define DDIV (HI(0) | (2 << 6) | LO(30))
-#define DDIVU (HI(0) | (2 << 6) | LO(31))
-#define DMOD (HI(0) | (3 << 6) | LO(30))
-#define DMODU (HI(0) | (3 << 6) | LO(31))
-#define DIV (HI(0) | (2 << 6) | LO(26))
-#define DIVU (HI(0) | (2 << 6) | LO(27))
-#define DMUH (HI(0) | (3 << 6) | LO(28))
-#define DMUHU (HI(0) | (3 << 6) | LO(29))
-#define DMUL (HI(0) | (2 << 6) | LO(28))
-#define DMULU (HI(0) | (2 << 6) | LO(29))
-#else /* SLJIT_MIPS_REV < 6 */
-#define DDIV (HI(0) | LO(30))
-#define DDIVU (HI(0) | LO(31))
-#define DIV (HI(0) | LO(26))
-#define DIVU (HI(0) | LO(27))
-#define DMULT (HI(0) | LO(28))
-#define DMULTU (HI(0) | LO(29))
-#endif /* SLJIT_MIPS_REV >= 6 */
-#define DIV_S (HI(17) | FMT_S | LO(3))
-#define DINSU (HI(31) | LO(6))
-#define DROTR (HI(0) | (1 << 21) | LO(58))
-#define DROTR32 (HI(0) | (1 << 21) | LO(62))
-#define DROTRV (HI(0) | (1 << 6) | LO(22))
-#define DSLL (HI(0) | LO(56))
-#define DSLL32 (HI(0) | LO(60))
-#define DSLLV (HI(0) | LO(20))
-#define DSRA (HI(0) | LO(59))
-#define DSRA32 (HI(0) | LO(63))
-#define DSRAV (HI(0) | LO(23))
-#define DSRL (HI(0) | LO(58))
-#define DSRL32 (HI(0) | LO(62))
-#define DSRLV (HI(0) | LO(22))
-#define DSUBU (HI(0) | LO(47))
-#define J (HI(2))
-#define JAL (HI(3))
-#define JALR (HI(0) | LO(9))
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
-#define JR (HI(0) | LO(9))
-#else /* SLJIT_MIPS_REV < 6 */
-#define JR (HI(0) | LO(8))
-#endif /* SLJIT_MIPS_REV >= 6 */
-#define LD (HI(55))
-#define LDL (HI(26))
-#define LDR (HI(27))
-#define LDC1 (HI(53))
-#define LUI (HI(15))
-#define LW (HI(35))
-#define LWL (HI(34))
-#define LWR (HI(38))
-#define LWC1 (HI(49))
-#define MFC1 (HI(17))
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
-#define MOD (HI(0) | (3 << 6) | LO(26))
-#define MODU (HI(0) | (3 << 6) | LO(27))
-#else /* SLJIT_MIPS_REV < 6 */
-#define MFHI (HI(0) | LO(16))
-#define MFLO (HI(0) | LO(18))
-#endif /* SLJIT_MIPS_REV >= 6 */
-#define MOV_S (HI(17) | FMT_S | LO(6))
-#define MTC1 (HI(17) | (4 << 21))
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
-#define MUH (HI(0) | (3 << 6) | LO(24))
-#define MUHU (HI(0) | (3 << 6) | LO(25))
-#define MUL (HI(0) | (2 << 6) | LO(24))
-#define MULU (HI(0) | (2 << 6) | LO(25))
-#else /* SLJIT_MIPS_REV < 6 */
-#define MULT (HI(0) | LO(24))
-#define MULTU (HI(0) | LO(25))
-#endif /* SLJIT_MIPS_REV >= 6 */
-#define MUL_S (HI(17) | FMT_S | LO(2))
-#define NEG_S (HI(17) | FMT_S | LO(7))
-#define NOP (HI(0) | LO(0))
-#define NOR (HI(0) | LO(39))
-#define OR (HI(0) | LO(37))
-#define ORI (HI(13))
-#define ROTR (HI(0) | (1 << 21) | LO(2))
-#define ROTRV (HI(0) | (1 << 6) | LO(6))
-#define SD (HI(63))
-#define SDL (HI(44))
-#define SDR (HI(45))
-#define SDC1 (HI(61))
-#define SLT (HI(0) | LO(42))
-#define SLTI (HI(10))
-#define SLTIU (HI(11))
-#define SLTU (HI(0) | LO(43))
-#define SLL (HI(0) | LO(0))
-#define SLLV (HI(0) | LO(4))
-#define SRL (HI(0) | LO(2))
-#define SRLV (HI(0) | LO(6))
-#define SRA (HI(0) | LO(3))
-#define SRAV (HI(0) | LO(7))
-#define SUB_S (HI(17) | FMT_S | LO(1))
-#define SUBU (HI(0) | LO(35))
-#define SW (HI(43))
-#define SWL (HI(42))
-#define SWR (HI(46))
-#define SWC1 (HI(57))
-#define TRUNC_W_S (HI(17) | FMT_S | LO(13))
-#define XOR (HI(0) | LO(38))
-#define XORI (HI(14))
-
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
-#define CLZ (HI(28) | LO(32))
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
-#define DCLZ (LO(18))
-#else /* SLJIT_MIPS_REV < 6 */
-#define DCLZ (HI(28) | LO(36))
-#define MOVF (HI(0) | (0 << 16) | LO(1))
-#define MOVN (HI(0) | LO(11))
-#define MOVT (HI(0) | (1 << 16) | LO(1))
-#define MOVZ (HI(0) | LO(10))
-#define MUL (HI(28) | LO(2))
-#endif /* SLJIT_MIPS_REV >= 6 */
-#define PREF (HI(51))
-#define PREFX (HI(19) | LO(15))
-#define SEB (HI(31) | (16 << 6) | LO(32))
-#define SEH (HI(31) | (24 << 6) | LO(32))
-#endif /* SLJIT_MIPS_REV >= 1 */
-
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
-#define ADDU_W ADDU
-#define ADDIU_W ADDIU
-#define SLL_W SLL
-#define SRA_W SRA
-#define SUBU_W SUBU
-#define STORE_W SW
-#define LOAD_W LW
-#else
-#define ADDU_W DADDU
-#define ADDIU_W DADDIU
-#define SLL_W DSLL
-#define SRA_W DSRA
-#define SUBU_W DSUBU
-#define STORE_W SD
-#define LOAD_W LD
-#endif
-
-#define SIMM_MAX (0x7fff)
-#define SIMM_MIN (-0x8000)
-#define UIMM_MAX (0xffff)
-
-/* dest_reg is the absolute name of the register
- Useful for reordering instructions in the delay slot. */
-static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 delay_slot)
-{
- sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
- SLJIT_ASSERT(delay_slot == MOVABLE_INS || delay_slot >= UNMOVABLE_INS
- || (sljit_ins)delay_slot == ((ins >> 11) & 0x1f)
- || (sljit_ins)delay_slot == ((ins >> 16) & 0x1f));
- FAIL_IF(!ptr);
- *ptr = ins;
- compiler->size++;
- compiler->delay_slot = delay_slot;
- return SLJIT_SUCCESS;
-}
-
-static SLJIT_INLINE sljit_ins invert_branch(sljit_uw flags)
-{
- if (flags & IS_BIT26_COND)
- return (1 << 26);
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
- if (flags & IS_BIT23_COND)
- return (1 << 23);
-#endif /* SLJIT_MIPS_REV >= 6 */
- return (1 << 16);
-}
-
-static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code, sljit_sw executable_offset)
-{
- sljit_sw diff;
- sljit_uw target_addr;
- sljit_ins *inst;
- sljit_ins saved_inst;
-
- inst = (sljit_ins *)jump->addr;
-
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL))
- goto exit;
-#else
- if (jump->flags & SLJIT_REWRITABLE_JUMP)
- goto exit;
-#endif
-
- if (jump->flags & JUMP_ADDR)
- target_addr = jump->u.target;
- else {
- SLJIT_ASSERT(jump->flags & JUMP_LABEL);
- target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
- }
-
- if (jump->flags & IS_COND)
- inst--;
-
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
- if (jump->flags & IS_CALL)
- goto preserve_addr;
-#endif
-
- /* B instructions. */
- if (jump->flags & IS_MOVABLE) {
- diff = ((sljit_sw)target_addr - (sljit_sw)inst - executable_offset) >> 2;
- if (diff <= SIMM_MAX && diff >= SIMM_MIN) {
- jump->flags |= PATCH_B;
-
- if (!(jump->flags & IS_COND)) {
- inst[0] = inst[-1];
- inst[-1] = (jump->flags & IS_JAL) ? BAL : B;
- jump->addr -= sizeof(sljit_ins);
- return inst;
- }
- saved_inst = inst[0];
- inst[0] = inst[-1];
- inst[-1] = saved_inst ^ invert_branch(jump->flags);
- jump->addr -= 2 * sizeof(sljit_ins);
- return inst;
- }
- } else {
- diff = ((sljit_sw)target_addr - (sljit_sw)(inst + 1) - executable_offset) >> 2;
- if (diff <= SIMM_MAX && diff >= SIMM_MIN) {
- jump->flags |= PATCH_B;
-
- if (!(jump->flags & IS_COND)) {
- inst[0] = (jump->flags & IS_JAL) ? BAL : B;
- /* Keep inst[1] */
- return inst + 1;
- }
- inst[0] ^= invert_branch(jump->flags);
- inst[1] = NOP;
- jump->addr -= sizeof(sljit_ins);
- return inst + 1;
- }
- }
-
- if (jump->flags & IS_COND) {
- if ((jump->flags & IS_MOVABLE) && (target_addr & ~(sljit_uw)0xfffffff) == ((jump->addr + 2 * sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff)) {
- jump->flags |= PATCH_J;
- saved_inst = inst[0];
- inst[0] = inst[-1];
- inst[-1] = (saved_inst & 0xffff0000) | 3;
- inst[1] = J;
- inst[2] = NOP;
- return inst + 2;
- }
- else if ((target_addr & ~(sljit_uw)0xfffffff) == ((jump->addr + 3 * sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff)) {
- jump->flags |= PATCH_J;
- inst[0] = (inst[0] & 0xffff0000) | 3;
- inst[1] = NOP;
- inst[2] = J;
- inst[3] = NOP;
- jump->addr += sizeof(sljit_ins);
- return inst + 3;
- }
- }
- else {
- /* J instuctions. */
- if ((jump->flags & IS_MOVABLE) && (target_addr & ~(sljit_uw)0xfffffff) == (jump->addr & ~(sljit_uw)0xfffffff)) {
- jump->flags |= PATCH_J;
- inst[0] = inst[-1];
- inst[-1] = (jump->flags & IS_JAL) ? JAL : J;
- jump->addr -= sizeof(sljit_ins);
- return inst;
- }
-
- if ((target_addr & ~(sljit_uw)0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff)) {
- jump->flags |= PATCH_J;
- inst[0] = (jump->flags & IS_JAL) ? JAL : J;
- /* Keep inst[1] */
- return inst + 1;
- }
- }
-
- if (jump->flags & IS_COND)
- inst++;
-
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
-preserve_addr:
- if (target_addr <= 0x7fffffff) {
- jump->flags |= PATCH_ABS32;
- if (jump->flags & IS_COND)
- inst[-1] -= 4;
-
- inst[2] = inst[0];
- inst[3] = inst[1];
- return inst + 3;
- }
- if (target_addr <= 0x7fffffffffffl) {
- jump->flags |= PATCH_ABS48;
- if (jump->flags & IS_COND)
- inst[-1] -= 2;
-
- inst[4] = inst[0];
- inst[5] = inst[1];
- return inst + 5;
- }
-#endif
-
-exit:
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- inst[2] = inst[0];
- inst[3] = inst[1];
- return inst + 3;
-#else
- inst[6] = inst[0];
- inst[7] = inst[1];
- return inst + 7;
-#endif
-}
-
-#ifdef __GNUC__
-static __attribute__ ((noinline)) void sljit_cache_flush(void* code, void* code_ptr)
-{
- SLJIT_CACHE_FLUSH(code, code_ptr);
-}
-#endif
-
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
-
-static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label)
-{
- if (max_label < 0x80000000l) {
- put_label->flags = PATCH_ABS32;
- return 1;
- }
-
- if (max_label < 0x800000000000l) {
- put_label->flags = PATCH_ABS48;
- return 3;
- }
-
- put_label->flags = 0;
- return 5;
-}
-
-#endif /* SLJIT_CONFIG_MIPS_64 */
-
-static SLJIT_INLINE void load_addr_to_reg(void *dst, sljit_u32 reg)
-{
- struct sljit_jump *jump;
- struct sljit_put_label *put_label;
- sljit_uw flags;
- sljit_ins *inst;
- sljit_uw addr;
-
- if (reg != 0) {
- jump = (struct sljit_jump*)dst;
- flags = jump->flags;
- inst = (sljit_ins*)jump->addr;
- addr = (flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
- } else {
- put_label = (struct sljit_put_label*)dst;
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
- flags = put_label->flags;
-#endif
- inst = (sljit_ins*)put_label->addr;
- addr = put_label->label->addr;
- reg = *inst;
- }
-
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- inst[0] = LUI | T(reg) | IMM(addr >> 16);
-#else /* !SLJIT_CONFIG_MIPS_32 */
- if (flags & PATCH_ABS32) {
- SLJIT_ASSERT(addr < 0x80000000l);
- inst[0] = LUI | T(reg) | IMM(addr >> 16);
- }
- else if (flags & PATCH_ABS48) {
- SLJIT_ASSERT(addr < 0x800000000000l);
- inst[0] = LUI | T(reg) | IMM(addr >> 32);
- inst[1] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);
- inst[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);
- inst += 2;
- }
- else {
- inst[0] = LUI | T(reg) | IMM(addr >> 48);
- inst[1] = ORI | S(reg) | T(reg) | IMM((addr >> 32) & 0xffff);
- inst[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);
- inst[3] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);
- inst[4] = DSLL | T(reg) | D(reg) | SH_IMM(16);
- inst += 4;
- }
-#endif /* SLJIT_CONFIG_MIPS_32 */
-
- inst[1] = ORI | S(reg) | T(reg) | IMM(addr & 0xffff);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
-{
- struct sljit_memory_fragment *buf;
- sljit_ins *code;
- sljit_ins *code_ptr;
- sljit_ins *buf_ptr;
- sljit_ins *buf_end;
- sljit_uw word_count;
- sljit_uw next_addr;
- sljit_sw executable_offset;
- sljit_uw addr;
-
- struct sljit_label *label;
- struct sljit_jump *jump;
- struct sljit_const *const_;
- struct sljit_put_label *put_label;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_generate_code(compiler));
- reverse_buf(compiler);
-
- code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
- PTR_FAIL_WITH_EXEC_IF(code);
- buf = compiler->buf;
-
- code_ptr = code;
- word_count = 0;
- next_addr = 0;
- executable_offset = SLJIT_EXEC_OFFSET(code);
-
- label = compiler->labels;
- jump = compiler->jumps;
- const_ = compiler->consts;
- put_label = compiler->put_labels;
-
- do {
- buf_ptr = (sljit_ins*)buf->memory;
- buf_end = buf_ptr + (buf->used_size >> 2);
- do {
- *code_ptr = *buf_ptr++;
- if (next_addr == word_count) {
- SLJIT_ASSERT(!label || label->size >= word_count);
- SLJIT_ASSERT(!jump || jump->addr >= word_count);
- SLJIT_ASSERT(!const_ || const_->addr >= word_count);
- SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
-
- /* These structures are ordered by their address. */
- if (label && label->size == word_count) {
- label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
- label->size = (sljit_uw)(code_ptr - code);
- label = label->next;
- }
- if (jump && jump->addr == word_count) {
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- word_count += 2;
-#else
- word_count += 6;
-#endif
- jump->addr = (sljit_uw)(code_ptr - 1);
- code_ptr = detect_jump_type(jump, code, executable_offset);
- jump = jump->next;
- }
- if (const_ && const_->addr == word_count) {
- const_->addr = (sljit_uw)code_ptr;
- const_ = const_->next;
- }
- if (put_label && put_label->addr == word_count) {
- SLJIT_ASSERT(put_label->label);
- put_label->addr = (sljit_uw)code_ptr;
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- code_ptr += 1;
- word_count += 1;
-#else
- code_ptr += put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));
- word_count += 5;
-#endif
- put_label = put_label->next;
- }
- next_addr = compute_next_addr(label, jump, const_, put_label);
- }
- code_ptr++;
- word_count++;
- } while (buf_ptr < buf_end);
-
- buf = buf->next;
- } while (buf);
-
- if (label && label->size == word_count) {
- label->addr = (sljit_uw)code_ptr;
- label->size = (sljit_uw)(code_ptr - code);
- label = label->next;
- }
-
- SLJIT_ASSERT(!label);
- SLJIT_ASSERT(!jump);
- SLJIT_ASSERT(!const_);
- SLJIT_ASSERT(!put_label);
- SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
-
- jump = compiler->jumps;
- while (jump) {
- do {
- addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
- buf_ptr = (sljit_ins *)jump->addr;
-
- if (jump->flags & PATCH_B) {
- addr = (sljit_uw)((sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) - sizeof(sljit_ins)) >> 2);
- SLJIT_ASSERT((sljit_sw)addr <= SIMM_MAX && (sljit_sw)addr >= SIMM_MIN);
- buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((sljit_ins)addr & 0xffff);
- break;
- }
- if (jump->flags & PATCH_J) {
- SLJIT_ASSERT((addr & ~(sljit_uw)0xfffffff)
- == (((sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) + sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff));
- buf_ptr[0] |= (sljit_ins)(addr >> 2) & 0x03ffffff;
- break;
- }
-
- load_addr_to_reg(jump, PIC_ADDR_REG);
- } while (0);
- jump = jump->next;
- }
-
- put_label = compiler->put_labels;
- while (put_label) {
- load_addr_to_reg(put_label, 0);
- put_label = put_label->next;
- }
-
- compiler->error = SLJIT_ERR_COMPILED;
- compiler->executable_offset = executable_offset;
- compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins);
-
- code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
- code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
-
-#ifndef __GNUC__
- SLJIT_CACHE_FLUSH(code, code_ptr);
-#else
- /* GCC workaround for invalid code generation with -O2. */
- sljit_cache_flush(code, code_ptr);
-#endif
- SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
- return code;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
-{
-#if defined(__GNUC__) && !defined(SLJIT_IS_FPU_AVAILABLE)
- sljit_sw fir = 0;
-#endif /* __GNUC__ && !SLJIT_IS_FPU_AVAILABLE */
-
- switch (feature_type) {
- case SLJIT_HAS_FPU:
-#ifdef SLJIT_IS_FPU_AVAILABLE
- return SLJIT_IS_FPU_AVAILABLE;
-#elif defined(__GNUC__)
- __asm__ ("cfc1 %0, $0" : "=r"(fir));
- return (fir >> 22) & 0x1;
-#else
-#error "FIR check is not implemented for this architecture"
-#endif
- case SLJIT_HAS_ZERO_REGISTER:
- return 1;
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
- case SLJIT_HAS_CLZ:
- case SLJIT_HAS_CMOV:
- case SLJIT_HAS_PREFETCH:
- return 1;
-
- case SLJIT_HAS_CTZ:
- return 2;
-#endif /* SLJIT_MIPS_REV >= 1 */
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
- case SLJIT_HAS_ROT:
- return 1;
-#endif /* SLJIT_MIPS_REV >= 2 */
- default:
- return 0;
- }
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)
-{
- return (type >= SLJIT_ORDERED_EQUAL && type <= SLJIT_ORDERED_LESS_EQUAL);
-}
-
-/* --------------------------------------------------------------------- */
-/* Entry, exit */
-/* --------------------------------------------------------------------- */
-
-/* Creates an index in data_transfer_insts array. */
-#define LOAD_DATA 0x01
-#define WORD_DATA 0x00
-#define BYTE_DATA 0x02
-#define HALF_DATA 0x04
-#define INT_DATA 0x06
-#define SIGNED_DATA 0x08
-/* Separates integer and floating point registers */
-#define GPR_REG 0x0f
-#define DOUBLE_DATA 0x10
-#define SINGLE_DATA 0x12
-
-#define MEM_MASK 0x1f
-
-#define ARG_TEST 0x00020
-#define ALT_KEEP_CACHE 0x00040
-#define CUMULATIVE_OP 0x00080
-#define LOGICAL_OP 0x00100
-#define IMM_OP 0x00200
-#define MOVE_OP 0x00400
-#define SRC2_IMM 0x00800
-
-#define UNUSED_DEST 0x01000
-#define REG_DEST 0x02000
-#define REG1_SOURCE 0x04000
-#define REG2_SOURCE 0x08000
-#define SLOW_SRC1 0x10000
-#define SLOW_SRC2 0x20000
-#define SLOW_DEST 0x40000
-
-static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw);
-static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size, sljit_ins *ins_ptr);
-
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
-#include "sljitNativeMIPS_32.c"
-#else
-#include "sljitNativeMIPS_64.c"
-#endif
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- sljit_ins base;
- sljit_s32 i, tmp, offset;
- sljit_s32 arg_count, word_arg_count, float_arg_count;
- sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options);
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
- set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
-
- local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1);
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
- if ((local_size & SSIZE_OF(sw)) != 0)
- local_size += SSIZE_OF(sw);
- local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
- }
-
- local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;
-#else
- local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
- local_size = (local_size + SLJIT_LOCALS_OFFSET + 31) & ~0x1f;
-#endif
- compiler->local_size = local_size;
-
- offset = 0;
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- if (!(options & SLJIT_ENTER_REG_ARG)) {
- tmp = arg_types >> SLJIT_ARG_SHIFT;
- arg_count = 0;
-
- while (tmp) {
- offset = arg_count;
- if ((tmp & SLJIT_ARG_MASK) == SLJIT_ARG_TYPE_F64) {
- if ((arg_count & 0x1) != 0)
- arg_count++;
- arg_count++;
- }
-
- arg_count++;
- tmp >>= SLJIT_ARG_SHIFT;
- }
-
- compiler->args_size = (sljit_uw)arg_count << 2;
- offset = (offset >= 4) ? (offset << 2) : 0;
- }
-#endif /* SLJIT_CONFIG_MIPS_32 */
-
- if (local_size + offset <= -SIMM_MIN) {
- /* Frequent case. */
- FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(-local_size), DR(SLJIT_SP)));
- base = S(SLJIT_SP);
- offset = local_size - SSIZE_OF(sw);
- } else {
- FAIL_IF(load_immediate(compiler, OTHER_FLAG, local_size));
- FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
- FAIL_IF(push_inst(compiler, SUBU_W | S(SLJIT_SP) | TA(OTHER_FLAG) | D(SLJIT_SP), DR(SLJIT_SP)));
- base = S(TMP_REG2);
- offset = -SSIZE_OF(sw);
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- local_size = 0;
-#endif
- }
-
- FAIL_IF(push_inst(compiler, STORE_W | base | TA(RETURN_ADDR_REG) | IMM(offset), UNMOVABLE_INS));
-
- tmp = SLJIT_S0 - saveds;
- for (i = SLJIT_S0 - saved_arg_count; i > tmp; i--) {
- offset -= SSIZE_OF(sw);
- FAIL_IF(push_inst(compiler, STORE_W | base | T(i) | IMM(offset), MOVABLE_INS));
- }
-
- for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
- offset -= SSIZE_OF(sw);
- FAIL_IF(push_inst(compiler, STORE_W | base | T(i) | IMM(offset), MOVABLE_INS));
- }
-
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- /* This alignment is valid because offset is not used after storing FPU regs. */
- if ((offset & SSIZE_OF(sw)) != 0)
- offset -= SSIZE_OF(sw);
-#endif
-
- tmp = SLJIT_FS0 - fsaveds;
- for (i = SLJIT_FS0; i > tmp; i--) {
- offset -= SSIZE_OF(f64);
- FAIL_IF(push_inst(compiler, SDC1 | base | FT(i) | IMM(offset), MOVABLE_INS));
- }
-
- for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
- offset -= SSIZE_OF(f64);
- FAIL_IF(push_inst(compiler, SDC1 | base | FT(i) | IMM(offset), MOVABLE_INS));
- }
-
- if (options & SLJIT_ENTER_REG_ARG)
- return SLJIT_SUCCESS;
-
- arg_types >>= SLJIT_ARG_SHIFT;
- arg_count = 0;
- word_arg_count = 0;
- float_arg_count = 0;
-
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- /* The first maximum two floating point arguments are passed in floating point
- registers if no integer argument precedes them. The first 16 byte data is
- passed in four integer registers, the rest is placed onto the stack.
- The floating point registers are also part of the first 16 byte data, so
- their corresponding integer registers are not used when they are present. */
-
- while (arg_types) {
- switch (arg_types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- float_arg_count++;
- if ((arg_count & 0x1) != 0)
- arg_count++;
-
- if (word_arg_count == 0 && float_arg_count <= 2) {
- if (float_arg_count == 1)
- FAIL_IF(push_inst(compiler, MOV_S | FMT_D | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
- } else if (arg_count < 4) {
- FAIL_IF(push_inst(compiler, MTC1 | TA(4 + arg_count) | FS(float_arg_count), MOVABLE_INS));
- FAIL_IF(push_inst(compiler, MTC1 | TA(5 + arg_count) | FS(float_arg_count) | (1 << 11), MOVABLE_INS));
- } else
- FAIL_IF(push_inst(compiler, LDC1 | base | FT(float_arg_count) | IMM(local_size + (arg_count << 2)), MOVABLE_INS));
- arg_count++;
- break;
- case SLJIT_ARG_TYPE_F32:
- float_arg_count++;
-
- if (word_arg_count == 0 && float_arg_count <= 2) {
- if (float_arg_count == 1)
- FAIL_IF(push_inst(compiler, MOV_S | FMT_S | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
- } else if (arg_count < 4)
- FAIL_IF(push_inst(compiler, MTC1 | TA(4 + arg_count) | FS(float_arg_count), MOVABLE_INS));
- else
- FAIL_IF(push_inst(compiler, LWC1 | base | FT(float_arg_count) | IMM(local_size + (arg_count << 2)), MOVABLE_INS));
- break;
- default:
- word_arg_count++;
-
- if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {
- tmp = SLJIT_S0 - saved_arg_count;
- saved_arg_count++;
- } else if (word_arg_count != arg_count + 1 || arg_count == 0)
- tmp = word_arg_count;
- else
- break;
-
- if (arg_count < 4)
- FAIL_IF(push_inst(compiler, ADDU_W | SA(4 + arg_count) | TA(0) | D(tmp), DR(tmp)));
- else
- FAIL_IF(push_inst(compiler, LW | base | T(tmp) | IMM(local_size + (arg_count << 2)), DR(tmp)));
- break;
- }
- arg_count++;
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- SLJIT_ASSERT(compiler->args_size == (sljit_uw)arg_count << 2);
-#else /* !SLJIT_CONFIG_MIPS_32 */
- while (arg_types) {
- arg_count++;
- switch (arg_types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- float_arg_count++;
- if (arg_count != float_arg_count)
- FAIL_IF(push_inst(compiler, MOV_S | FMT_D | FS(arg_count) | FD(float_arg_count), MOVABLE_INS));
- else if (arg_count == 1)
- FAIL_IF(push_inst(compiler, MOV_S | FMT_D | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
- break;
- case SLJIT_ARG_TYPE_F32:
- float_arg_count++;
- if (arg_count != float_arg_count)
- FAIL_IF(push_inst(compiler, MOV_S | FMT_S | FS(arg_count) | FD(float_arg_count), MOVABLE_INS));
- else if (arg_count == 1)
- FAIL_IF(push_inst(compiler, MOV_S | FMT_S | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
- break;
- default:
- word_arg_count++;
-
- if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {
- tmp = SLJIT_S0 - saved_arg_count;
- saved_arg_count++;
- } else if (word_arg_count != arg_count || word_arg_count <= 1)
- tmp = word_arg_count;
- else
- break;
-
- FAIL_IF(push_inst(compiler, ADDU_W | SA(3 + arg_count) | TA(0) | D(tmp), DR(tmp)));
- break;
- }
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-#endif /* SLJIT_CONFIG_MIPS_32 */
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- CHECK_ERROR();
- CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
- set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
-
- local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1);
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
- if ((local_size & SSIZE_OF(sw)) != 0)
- local_size += SSIZE_OF(sw);
- local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
- }
-
- compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;
-#else
- local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
- compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 31) & ~0x1f;
-#endif
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size, sljit_ins *ins_ptr)
-{
- sljit_s32 local_size, i, tmp, offset;
- sljit_s32 load_return_addr = (frame_size == 0);
- sljit_s32 scratches = compiler->scratches;
- sljit_s32 saveds = compiler->saveds;
- sljit_s32 fsaveds = compiler->fsaveds;
- sljit_s32 fscratches = compiler->fscratches;
- sljit_s32 kept_saveds_count = SLJIT_KEPT_SAVEDS_COUNT(compiler->options);
-
- SLJIT_ASSERT(frame_size == 1 || (frame_size & 0xf) == 0);
- frame_size &= ~0xf;
-
- local_size = compiler->local_size;
-
- tmp = GET_SAVED_REGISTERS_SIZE(scratches, saveds - kept_saveds_count, 1);
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
- if ((tmp & SSIZE_OF(sw)) != 0)
- tmp += SSIZE_OF(sw);
- tmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
- }
-#else
- tmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
-#endif
-
- if (local_size <= SIMM_MAX) {
- if (local_size < frame_size) {
- FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(local_size - frame_size), DR(SLJIT_SP)));
- local_size = frame_size;
- }
- } else {
- if (tmp < frame_size)
- tmp = frame_size;
-
- FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size - tmp));
- FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | T(TMP_REG1) | D(SLJIT_SP), DR(SLJIT_SP)));
- local_size = tmp;
- }
-
- SLJIT_ASSERT(local_size >= frame_size);
-
- offset = local_size - SSIZE_OF(sw);
- if (load_return_addr)
- FAIL_IF(push_inst(compiler, LOAD_W | S(SLJIT_SP) | TA(RETURN_ADDR_REG) | IMM(offset), RETURN_ADDR_REG));
-
- tmp = SLJIT_S0 - saveds;
- for (i = SLJIT_S0 - kept_saveds_count; i > tmp; i--) {
- offset -= SSIZE_OF(sw);
- FAIL_IF(push_inst(compiler, LOAD_W | S(SLJIT_SP) | T(i) | IMM(offset), MOVABLE_INS));
- }
-
- for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
- offset -= SSIZE_OF(sw);
- FAIL_IF(push_inst(compiler, LOAD_W | S(SLJIT_SP) | T(i) | IMM(offset), MOVABLE_INS));
- }
-
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- /* This alignment is valid because offset is not used after storing FPU regs. */
- if ((offset & SSIZE_OF(sw)) != 0)
- offset -= SSIZE_OF(sw);
-#endif
-
- tmp = SLJIT_FS0 - fsaveds;
- for (i = SLJIT_FS0; i > tmp; i--) {
- offset -= SSIZE_OF(f64);
- FAIL_IF(push_inst(compiler, LDC1 | S(SLJIT_SP) | FT(i) | IMM(offset), MOVABLE_INS));
- }
-
- for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
- offset -= SSIZE_OF(f64);
- FAIL_IF(push_inst(compiler, LDC1 | S(SLJIT_SP) | FT(i) | IMM(offset), MOVABLE_INS));
- }
-
- if (local_size > frame_size)
- *ins_ptr = ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(local_size - frame_size);
- else
- *ins_ptr = NOP;
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)
-{
- sljit_ins ins;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_return_void(compiler));
-
- emit_stack_frame_release(compiler, 0, &ins);
-
- FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
- return push_inst(compiler, ins, UNMOVABLE_INS);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_ins ins;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_return_to(compiler, src, srcw));
-
- if (src & SLJIT_MEM) {
- ADJUST_LOCAL_OFFSET(src, srcw);
- FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(PIC_ADDR_REG), src, srcw));
- src = PIC_ADDR_REG;
- srcw = 0;
- } else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
- FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));
- src = PIC_ADDR_REG;
- srcw = 0;
- }
-
- FAIL_IF(emit_stack_frame_release(compiler, 1, &ins));
-
- if (!(src & SLJIT_IMM)) {
- FAIL_IF(push_inst(compiler, JR | S(src), UNMOVABLE_INS));
- return push_inst(compiler, ins, UNMOVABLE_INS);
- }
-
- if (ins != NOP)
- FAIL_IF(push_inst(compiler, ins, MOVABLE_INS));
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);
-}
-
-/* --------------------------------------------------------------------- */
-/* Operators */
-/* --------------------------------------------------------------------- */
-
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
-#define ARCH_32_64(a, b) a
-#else
-#define ARCH_32_64(a, b) b
-#endif
-
-static const sljit_ins data_transfer_insts[16 + 4] = {
-/* u w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */),
-/* u w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */),
-/* u b s */ HI(40) /* sb */,
-/* u b l */ HI(36) /* lbu */,
-/* u h s */ HI(41) /* sh */,
-/* u h l */ HI(37) /* lhu */,
-/* u i s */ HI(43) /* sw */,
-/* u i l */ ARCH_32_64(HI(35) /* lw */, HI(39) /* lwu */),
-
-/* s w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */),
-/* s w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */),
-/* s b s */ HI(40) /* sb */,
-/* s b l */ HI(32) /* lb */,
-/* s h s */ HI(41) /* sh */,
-/* s h l */ HI(33) /* lh */,
-/* s i s */ HI(43) /* sw */,
-/* s i l */ HI(35) /* lw */,
-
-/* d s */ HI(61) /* sdc1 */,
-/* d l */ HI(53) /* ldc1 */,
-/* s s */ HI(57) /* swc1 */,
-/* s l */ HI(49) /* lwc1 */,
-};
-
-#undef ARCH_32_64
-
-/* reg_ar is an absoulute register! */
-
-/* Can perform an operation using at most 1 instruction. */
-static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
-{
- SLJIT_ASSERT(arg & SLJIT_MEM);
-
- if (!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN) {
- /* Works for both absoulte and relative addresses. */
- if (SLJIT_UNLIKELY(flags & ARG_TEST))
- return 1;
- FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(arg & REG_MASK)
- | TA(reg_ar) | IMM(argw), ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? reg_ar : MOVABLE_INS));
- return -1;
- }
- return 0;
-}
-
-#define TO_ARGW_HI(argw) (((argw) & ~0xffff) + (((argw) & 0x8000) ? 0x10000 : 0))
-
-/* See getput_arg below.
- Note: can_cache is called only for binary operators. */
-static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
-{
- SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
-
- /* Simple operation except for updates. */
- if (arg & OFFS_REG_MASK) {
- argw &= 0x3;
- next_argw &= 0x3;
- if (argw && argw == next_argw && (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK)))
- return 1;
- return 0;
- }
-
- if (arg == next_arg) {
- if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN)
- || TO_ARGW_HI(argw) == TO_ARGW_HI(next_argw))
- return 1;
- return 0;
- }
-
- return 0;
-}
-
-/* Emit the necessary instructions. See can_cache above. */
-static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
-{
- sljit_s32 tmp_ar, base, delay_slot;
- sljit_sw offset, argw_hi;
-
- SLJIT_ASSERT(arg & SLJIT_MEM);
- if (!(next_arg & SLJIT_MEM)) {
- next_arg = 0;
- next_argw = 0;
- }
-
- /* Since tmp can be the same as base or offset registers,
- * these might be unavailable after modifying tmp. */
- if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) {
- tmp_ar = reg_ar;
- delay_slot = reg_ar;
- }
- else {
- tmp_ar = DR(TMP_REG1);
- delay_slot = MOVABLE_INS;
- }
- base = arg & REG_MASK;
-
- if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
- argw &= 0x3;
-
- /* Using the cache. */
- if (argw == compiler->cache_argw) {
- if (arg == compiler->cache_arg)
- return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
-
- if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {
- if (arg == next_arg && argw == (next_argw & 0x3)) {
- compiler->cache_arg = arg;
- compiler->cache_argw = argw;
- FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));
- return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
- }
- FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | DA(tmp_ar), tmp_ar));
- return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
- }
- }
-
- if (SLJIT_UNLIKELY(argw)) {
- compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);
- compiler->cache_argw = argw;
- FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | D(TMP_REG3) | SH_IMM(argw), DR(TMP_REG3)));
- }
-
- if (arg == next_arg && argw == (next_argw & 0x3)) {
- compiler->cache_arg = arg;
- compiler->cache_argw = argw;
- FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));
- tmp_ar = DR(TMP_REG3);
- }
- else
- FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | DA(tmp_ar), tmp_ar));
- return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
- }
-
- if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN)
- return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar) | IMM(argw - compiler->cache_argw), delay_slot);
-
- if (compiler->cache_arg == SLJIT_MEM && (argw - compiler->cache_argw) <= SIMM_MAX && (argw - compiler->cache_argw) >= SIMM_MIN) {
- offset = argw - compiler->cache_argw;
- } else {
- compiler->cache_arg = SLJIT_MEM;
-
- argw_hi = TO_ARGW_HI(argw);
-
- if (next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN && argw_hi != TO_ARGW_HI(next_argw)) {
- FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw));
- compiler->cache_argw = argw;
- offset = 0;
- } else {
- FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw_hi));
- compiler->cache_argw = argw_hi;
- offset = argw & 0xffff;
- argw = argw_hi;
- }
- }
-
- if (!base)
- return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar) | IMM(offset), delay_slot);
-
- if (arg == next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN) {
- compiler->cache_arg = arg;
- FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | D(TMP_REG3), DR(TMP_REG3)));
- return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar) | IMM(offset), delay_slot);
- }
-
- FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | DA(tmp_ar), tmp_ar));
- return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar) | IMM(offset), delay_slot);
-}
-
-static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
-{
- sljit_s32 tmp_ar, base, delay_slot;
-
- if (getput_arg_fast(compiler, flags, reg_ar, arg, argw))
- return compiler->error;
-
- if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) {
- tmp_ar = reg_ar;
- delay_slot = reg_ar;
- }
- else {
- tmp_ar = DR(TMP_REG1);
- delay_slot = MOVABLE_INS;
- }
- base = arg & REG_MASK;
-
- if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
- argw &= 0x3;
-
- if (SLJIT_UNLIKELY(argw)) {
- FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | DA(tmp_ar) | SH_IMM(argw), tmp_ar));
- FAIL_IF(push_inst(compiler, ADDU_W | SA(tmp_ar) | T(base) | DA(tmp_ar), tmp_ar));
- }
- else
- FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(OFFS_REG(arg)) | DA(tmp_ar), tmp_ar));
- return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
- }
-
- FAIL_IF(load_immediate(compiler, tmp_ar, TO_ARGW_HI(argw)));
-
- if (base != 0)
- FAIL_IF(push_inst(compiler, ADDU_W | SA(tmp_ar) | T(base) | DA(tmp_ar), tmp_ar));
-
- return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar) | IMM(argw), delay_slot);
-}
-
-static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
-{
- if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
- return compiler->error;
- return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
-}
-
-#define EMIT_LOGICAL(op_imm, op_reg) \
- if (flags & SRC2_IMM) { \
- if (op & SLJIT_SET_Z) \
- FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \
- if (!(flags & UNUSED_DEST)) \
- FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \
- } \
- else { \
- if (op & SLJIT_SET_Z) \
- FAIL_IF(push_inst(compiler, op_reg | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
- if (!(flags & UNUSED_DEST)) \
- FAIL_IF(push_inst(compiler, op_reg | S(src1) | T(src2) | D(dst), DR(dst))); \
- }
-
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
-
-#define SELECT_OP(a, b) (b)
-
-#define EMIT_SHIFT(dimm, dimm32, imm, dv, v) \
- op_imm = (imm); \
- op_v = (v);
-
-#else /* !SLJIT_CONFIG_MIPS_32 */
-
-#define SELECT_OP(a, b) \
- (!(op & SLJIT_32) ? a : b)
-
-#define EMIT_SHIFT(dimm, dimm32, imm, dv, v) \
- op_dimm = (dimm); \
- op_dimm32 = (dimm32); \
- op_imm = (imm); \
- op_dv = (dv); \
- op_v = (v);
-
-#endif /* SLJIT_CONFIG_MIPS_32 */
-
-#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV < 1)
-
-static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src)
-{
- sljit_s32 is_clz = (GET_OPCODE(op) == SLJIT_CLZ);
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
- sljit_ins max = (op & SLJIT_32) ? 32 : 64;
-#else /* !SLJIT_CONFIG_RISCV_64 */
- sljit_ins max = 32;
-#endif /* SLJIT_CONFIG_RISCV_64 */
-
- /* The TMP_REG2 is the next value. */
- if (src != TMP_REG2)
- FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
-
- FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG2) | TA(0) | IMM(is_clz ? 13 : 14), UNMOVABLE_INS));
- /* The OTHER_FLAG is the counter. Delay slot. */
- FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OTHER_FLAG) | IMM(max), OTHER_FLAG));
-
- if (!is_clz) {
- FAIL_IF(push_inst(compiler, ANDI | S(TMP_REG2) | T(TMP_REG1) | IMM(1), DR(TMP_REG1)));
- FAIL_IF(push_inst(compiler, BNE | S(TMP_REG1) | TA(0) | IMM(11), UNMOVABLE_INS));
- } else
- FAIL_IF(push_inst(compiler, BLTZ | S(TMP_REG2) | TA(0) | IMM(11), UNMOVABLE_INS));
-
- /* Delay slot. */
- FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OTHER_FLAG) | IMM(0), OTHER_FLAG));
-
- /* The TMP_REG1 is the next shift. */
- FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | T(TMP_REG1) | IMM(max), DR(TMP_REG1)));
-
- FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(TMP_REG2) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
- FAIL_IF(push_inst(compiler, SELECT_OP(DSRL, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1)));
-
- FAIL_IF(push_inst(compiler, (is_clz ? SELECT_OP(DSRLV, SRLV) : SELECT_OP(DSLLV, SLLV)) | S(TMP_REG1) | TA(EQUAL_FLAG) | D(TMP_REG2), DR(TMP_REG2)));
- FAIL_IF(push_inst(compiler, BNE | S(TMP_REG2) | TA(0) | IMM(-4), UNMOVABLE_INS));
- /* Delay slot. */
- FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
-
- FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(TMP_REG1) | T(TMP_REG2) | IMM(-1), DR(TMP_REG2)));
- FAIL_IF(push_inst(compiler, (is_clz ? SELECT_OP(DSRLV, SRLV) : SELECT_OP(DSLLV, SLLV)) | S(TMP_REG2) | TA(EQUAL_FLAG) | D(TMP_REG2), DR(TMP_REG2)));
-
- FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG2) | TA(0) | IMM(-7), UNMOVABLE_INS));
- /* Delay slot. */
- FAIL_IF(push_inst(compiler, OR | SA(OTHER_FLAG) | T(TMP_REG1) | DA(OTHER_FLAG), OTHER_FLAG));
-
- return push_inst(compiler, SELECT_OP(DADDU, ADDU) | SA(OTHER_FLAG) | TA(0) | D(dst), DR(dst));
-}
-
-#endif /* SLJIT_MIPS_REV < 1 */
-
-static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
- sljit_s32 dst, sljit_s32 src1, sljit_sw src2)
-{
- sljit_s32 is_overflow, is_carry, carry_src_ar, is_handled;
- sljit_ins op_imm, op_v;
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
- sljit_ins ins, op_dimm, op_dimm32, op_dv;
-#endif
-
- switch (GET_OPCODE(op)) {
- case SLJIT_MOV:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if (dst != src2)
- return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(dst), DR(dst));
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_U8:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
- return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
- SLJIT_ASSERT(dst == src2);
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_S8:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
- return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
-#else /* SLJIT_MIPS_REV < 1 */
- FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
- return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst));
-#endif /* SLJIT_MIPS_REV >= 1 */
-#else /* !SLJIT_CONFIG_MIPS_32 */
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
- if (op & SLJIT_32)
- return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
-#endif /* SLJIT_MIPS_REV >= 1 */
- FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
- return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(24), DR(dst));
-#endif /* SLJIT_CONFIG_MIPS_32 */
- }
- SLJIT_ASSERT(dst == src2);
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_U16:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
- return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
- SLJIT_ASSERT(dst == src2);
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_S16:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
- return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
-#else /* SLJIT_MIPS_REV < 1 */
- FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
- return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst));
-#endif /* SLJIT_MIPS_REV >= 1 */
-#else /* !SLJIT_CONFIG_MIPS_32 */
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
- if (op & SLJIT_32)
- return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
-#endif /* SLJIT_MIPS_REV >= 1 */
- FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
- return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(16), DR(dst));
-#endif /* SLJIT_CONFIG_MIPS_32 */
- }
- SLJIT_ASSERT(dst == src2);
- return SLJIT_SUCCESS;
-
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
- case SLJIT_MOV_U32:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && !(op & SLJIT_32));
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
- if (dst == src2)
- return push_inst(compiler, DINSU | T(src2) | SA(0) | (31 << 11) | (0 << 11), DR(dst));
-#endif /* SLJIT_MIPS_REV >= 2 */
- FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(0), DR(dst)));
- return push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst));
- }
- SLJIT_ASSERT(dst == src2);
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_S32:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && !(op & SLJIT_32));
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
- return push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(0), DR(dst));
- }
- SLJIT_ASSERT(dst == src2);
- return SLJIT_SUCCESS;
-#endif /* SLJIT_CONFIG_MIPS_64 */
-
- case SLJIT_NOT:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
- if (!(flags & UNUSED_DEST))
- FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst)));
- return SLJIT_SUCCESS;
-
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
- case SLJIT_CLZ:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
- return push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | D(dst), DR(dst));
-#else /* SLJIT_MIPS_REV < 6 */
- return push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | T(dst) | D(dst), DR(dst));
-#endif /* SLJIT_MIPS_REV >= 6 */
- case SLJIT_CTZ:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src2) | D(TMP_REG1), DR(TMP_REG1)));
- FAIL_IF(push_inst(compiler, AND | S(src2) | T(TMP_REG1) | D(dst), DR(dst)));
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
- FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(dst) | D(dst), DR(dst)));
-#else /* SLJIT_MIPS_REV < 6 */
- FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(dst) | T(dst) | D(dst), DR(dst)));
-#endif /* SLJIT_MIPS_REV >= 6 */
- FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(dst) | T(TMP_REG1) | IMM(SELECT_OP(-64, -32)), DR(TMP_REG1)));
- FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(SELECT_OP(26, 27)), DR(TMP_REG1)));
- return push_inst(compiler, XOR | S(dst) | T(TMP_REG1) | D(dst), DR(dst));
-#else /* SLJIT_MIPS_REV < 1 */
- case SLJIT_CLZ:
- case SLJIT_CTZ:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- return emit_clz_ctz(compiler, op, dst, src2);
-#endif /* SLJIT_MIPS_REV >= 1 */
-
- case SLJIT_ADD:
- /* Overflow computation (both add and sub): overflow = src1_sign ^ src2_sign ^ result_sign ^ carry_flag */
- is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;
- carry_src_ar = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);
-
- if (flags & SRC2_IMM) {
- if (is_overflow) {
- if (src2 >= 0)
- FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
- else
- FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
- }
- else if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
-
- /* Only the zero flag is needed. */
- if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
- FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst)));
- }
- else {
- if (is_overflow)
- FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
- else if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
-
- if (is_overflow || carry_src_ar != 0) {
- if (src1 != dst)
- carry_src_ar = DR(src1);
- else if (src2 != dst)
- carry_src_ar = DR(src2);
- else {
- FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | TA(0) | DA(OTHER_FLAG), OTHER_FLAG));
- carry_src_ar = OTHER_FLAG;
- }
- }
-
- /* Only the zero flag is needed. */
- if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
- FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst)));
- }
-
- /* Carry is zero if a + b >= a or a + b >= b, otherwise it is 1. */
- if (is_overflow || carry_src_ar != 0) {
- if (flags & SRC2_IMM)
- FAIL_IF(push_inst(compiler, SLTIU | S(dst) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
- else
- FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(carry_src_ar) | DA(OTHER_FLAG), OTHER_FLAG));
- }
-
- if (!is_overflow)
- return SLJIT_SUCCESS;
-
- FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(EQUAL_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
- if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
- FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
- return push_inst(compiler, XOR | S(TMP_REG1) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
-
- case SLJIT_ADDC:
- carry_src_ar = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);
-
- if (flags & SRC2_IMM) {
- FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst)));
- } else {
- if (carry_src_ar != 0) {
- if (src1 != dst)
- carry_src_ar = DR(src1);
- else if (src2 != dst)
- carry_src_ar = DR(src2);
- else {
- FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
- carry_src_ar = EQUAL_FLAG;
- }
- }
-
- FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst)));
- }
-
- /* Carry is zero if a + b >= a or a + b >= b, otherwise it is 1. */
- if (carry_src_ar != 0) {
- if (flags & SRC2_IMM)
- FAIL_IF(push_inst(compiler, SLTIU | S(dst) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
- else
- FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(carry_src_ar) | DA(EQUAL_FLAG), EQUAL_FLAG));
- }
-
- FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
-
- if (carry_src_ar == 0)
- return SLJIT_SUCCESS;
-
- /* Set ULESS_FLAG (dst == 0) && (OTHER_FLAG == 1). */
- FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG));
- /* Set carry flag. */
- return push_inst(compiler, OR | SA(OTHER_FLAG) | TA(EQUAL_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
-
- case SLJIT_SUB:
- if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
- FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
- src2 = TMP_REG2;
- flags &= ~SRC2_IMM;
- }
-
- is_handled = 0;
-
- if (flags & SRC2_IMM) {
- if (GET_FLAG_TYPE(op) == SLJIT_LESS || GET_FLAG_TYPE(op) == SLJIT_GREATER_EQUAL) {
- FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
- is_handled = 1;
- }
- else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS || GET_FLAG_TYPE(op) == SLJIT_SIG_GREATER_EQUAL) {
- FAIL_IF(push_inst(compiler, SLTI | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
- is_handled = 1;
- }
- }
-
- if (!is_handled && GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL) {
- is_handled = 1;
-
- if (flags & SRC2_IMM) {
- FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
- src2 = TMP_REG2;
- flags &= ~SRC2_IMM;
- }
-
- switch (GET_FLAG_TYPE(op)) {
- case SLJIT_LESS:
- case SLJIT_GREATER_EQUAL:
- FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
- break;
- case SLJIT_GREATER:
- case SLJIT_LESS_EQUAL:
- FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
- break;
- case SLJIT_SIG_LESS:
- case SLJIT_SIG_GREATER_EQUAL:
- FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
- break;
- case SLJIT_SIG_GREATER:
- case SLJIT_SIG_LESS_EQUAL:
- FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
- break;
- }
- }
-
- if (is_handled) {
- if (flags & SRC2_IMM) {
- if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
- if (!(flags & UNUSED_DEST))
- return push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst));
- }
- else {
- if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
- if (!(flags & UNUSED_DEST))
- return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst));
- }
- return SLJIT_SUCCESS;
- }
-
- is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;
- is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);
-
- if (flags & SRC2_IMM) {
- if (is_overflow) {
- if (src2 >= 0)
- FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
- else
- FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
- }
- else if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
-
- if (is_overflow || is_carry)
- FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
-
- /* Only the zero flag is needed. */
- if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
- FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst)));
- }
- else {
- if (is_overflow)
- FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
- else if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
-
- if (is_overflow || is_carry)
- FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
-
- /* Only the zero flag is needed. */
- if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
- FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst)));
- }
-
- if (!is_overflow)
- return SLJIT_SUCCESS;
-
- FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(EQUAL_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
- if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
- FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
- return push_inst(compiler, XOR | S(TMP_REG1) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
-
- case SLJIT_SUBC:
- if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
- FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
- src2 = TMP_REG2;
- flags &= ~SRC2_IMM;
- }
-
- is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);
-
- if (flags & SRC2_IMM) {
- if (is_carry)
- FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
-
- FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst)));
- }
- else {
- if (is_carry)
- FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
-
- FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst)));
- }
-
- if (is_carry)
- FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
-
- FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
-
- if (!is_carry)
- return SLJIT_SUCCESS;
-
- return push_inst(compiler, OR | SA(EQUAL_FLAG) | T(TMP_REG1) | DA(OTHER_FLAG), OTHER_FLAG);
-
- case SLJIT_MUL:
- SLJIT_ASSERT(!(flags & SRC2_IMM));
-
- if (GET_FLAG_TYPE(op) != SLJIT_OVERFLOW) {
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
- return push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst));
-#elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
-#else /* !SLJIT_CONFIG_MIPS_32 */
- if (op & SLJIT_32)
- return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
- FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS));
- return push_inst(compiler, MFLO | D(dst), DR(dst));
-#endif /* SLJIT_CONFIG_MIPS_32 */
-#else /* SLJIT_MIPS_REV < 1 */
- FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
- return push_inst(compiler, MFLO | D(dst), DR(dst));
-#endif /* SLJIT_MIPS_REV >= 6 */
- }
-
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
- FAIL_IF(push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst)));
- FAIL_IF(push_inst(compiler, SELECT_OP(DMUH, MUH) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
-#else /* SLJIT_MIPS_REV < 6 */
- FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
- FAIL_IF(push_inst(compiler, MFHI | DA(EQUAL_FLAG), EQUAL_FLAG));
- FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
-#endif /* SLJIT_MIPS_REV >= 6 */
- FAIL_IF(push_inst(compiler, SELECT_OP(DSRA32, SRA) | T(dst) | DA(OTHER_FLAG) | SH_IMM(31), OTHER_FLAG));
- return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(EQUAL_FLAG) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
-
- case SLJIT_AND:
- EMIT_LOGICAL(ANDI, AND);
- return SLJIT_SUCCESS;
-
- case SLJIT_OR:
- EMIT_LOGICAL(ORI, OR);
- return SLJIT_SUCCESS;
-
- case SLJIT_XOR:
- EMIT_LOGICAL(XORI, XOR);
- return SLJIT_SUCCESS;
-
- case SLJIT_SHL:
- case SLJIT_MSHL:
- EMIT_SHIFT(DSLL, DSLL32, SLL, DSLLV, SLLV);
- break;
-
- case SLJIT_LSHR:
- case SLJIT_MLSHR:
- EMIT_SHIFT(DSRL, DSRL32, SRL, DSRLV, SRLV);
- break;
-
- case SLJIT_ASHR:
- case SLJIT_MASHR:
- EMIT_SHIFT(DSRA, DSRA32, SRA, DSRAV, SRAV);
- break;
-
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
- case SLJIT_ROTL:
- if ((flags & SRC2_IMM) || src2 == 0) {
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- src2 = -src2 & 0x1f;
-#else /* !SLJIT_CONFIG_MIPS_32 */
- src2 = -src2 & ((op & SLJIT_32) ? 0x1f : 0x3f);
-#endif /* SLJIT_CONFIG_MIPS_32 */
- } else {
- FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src2) | D(TMP_REG2), DR(TMP_REG2)));
- src2 = TMP_REG2;
- }
- /* fallthrough */
-
- case SLJIT_ROTR:
- EMIT_SHIFT(DROTR, DROTR32, ROTR, DROTRV, ROTRV);
- break;
-#else /* SLJIT_MIPS_REV < 1 */
- case SLJIT_ROTL:
- case SLJIT_ROTR:
- if (flags & SRC2_IMM) {
- SLJIT_ASSERT(src2 != 0);
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
- if (!(op & SLJIT_32)) {
- if (GET_OPCODE(op) == SLJIT_ROTL)
- op_imm = ((src2 < 32) ? DSLL : DSLL32);
- else
- op_imm = ((src2 < 32) ? DSRL : DSRL32);
-
- FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(OTHER_FLAG) | (((sljit_ins)src2 & 0x1f) << 6), OTHER_FLAG));
-
- src2 = 64 - src2;
- if (GET_OPCODE(op) == SLJIT_ROTL)
- op_imm = ((src2 < 32) ? DSRL : DSRL32);
- else
- op_imm = ((src2 < 32) ? DSLL : DSLL32);
-
- FAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | (((sljit_ins)src2 & 0x1f) << 6), DR(dst)));
- return push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));
- }
-#endif /* SLJIT_CONFIG_MIPS_64 */
-
- op_imm = (GET_OPCODE(op) == SLJIT_ROTL) ? SLL : SRL;
- FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(OTHER_FLAG) | ((sljit_ins)src2 << 6), OTHER_FLAG));
-
- src2 = 32 - src2;
- op_imm = (GET_OPCODE(op) == SLJIT_ROTL) ? SRL : SLL;
- FAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | (((sljit_ins)src2 & 0x1f) << 6), DR(dst)));
- return push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));
- }
-
- if (src2 == 0) {
- if (dst != src1)
- return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | TA(0) | D(dst), DR(dst));
- return SLJIT_SUCCESS;
- }
-
- FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
-
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
- if (!(op & SLJIT_32)) {
- op_v = (GET_OPCODE(op) == SLJIT_ROTL) ? DSLLV : DSRLV;
- FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
- op_v = (GET_OPCODE(op) == SLJIT_ROTL) ? DSRLV : DSLLV;
- FAIL_IF(push_inst(compiler, op_v | SA(EQUAL_FLAG) | T(src1) | D(dst), DR(dst)));
- return push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));
- }
-#endif /* SLJIT_CONFIG_MIPS_64 */
-
- op_v = (GET_OPCODE(op) == SLJIT_ROTL) ? SLLV : SRLV;
- FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
- op_v = (GET_OPCODE(op) == SLJIT_ROTL) ? SRLV : SLLV;
- FAIL_IF(push_inst(compiler, op_v | SA(EQUAL_FLAG) | T(src1) | D(dst), DR(dst)));
- return push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));
-#endif /* SLJIT_MIPS_REV >= 2 */
-
- default:
- SLJIT_UNREACHABLE();
- return SLJIT_SUCCESS;
- }
-
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- if ((flags & SRC2_IMM) || src2 == 0) {
- if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG));
-
- if (flags & UNUSED_DEST)
- return SLJIT_SUCCESS;
- return push_inst(compiler, op_imm | T(src1) | D(dst) | SH_IMM(src2), DR(dst));
- }
-
- if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
-
- if (flags & UNUSED_DEST)
- return SLJIT_SUCCESS;
- return push_inst(compiler, op_v | S(src2) | T(src1) | D(dst), DR(dst));
-#else /* !SLJIT_CONFIG_MIPS_32 */
- if ((flags & SRC2_IMM) || src2 == 0) {
- if (src2 >= 32) {
- SLJIT_ASSERT(!(op & SLJIT_32));
- ins = op_dimm32;
- src2 -= 32;
- }
- else
- ins = (op & SLJIT_32) ? op_imm : op_dimm;
-
- if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, ins | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG));
-
- if (flags & UNUSED_DEST)
- return SLJIT_SUCCESS;
- return push_inst(compiler, ins | T(src1) | D(dst) | SH_IMM(src2), DR(dst));
- }
-
- ins = (op & SLJIT_32) ? op_v : op_dv;
- if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
-
- if (flags & UNUSED_DEST)
- return SLJIT_SUCCESS;
- return push_inst(compiler, ins | S(src2) | T(src1) | D(dst), DR(dst));
-#endif /* SLJIT_CONFIG_MIPS_32 */
-}
-
-#define CHECK_IMM(flags, srcw) \
- ((!((flags) & LOGICAL_OP) && ((srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN)) \
- || (((flags) & LOGICAL_OP) && !((srcw) & ~UIMM_MAX)))
-
-static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- /* arg1 goes to TMP_REG1 or src reg
- arg2 goes to TMP_REG2, imm or src reg
- TMP_REG3 can be used for caching
- result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
- sljit_s32 dst_r = TMP_REG2;
- sljit_s32 src1_r;
- sljit_sw src2_r = 0;
- sljit_s32 sugg_src2_r = TMP_REG2;
-
- if (!(flags & ALT_KEEP_CACHE)) {
- compiler->cache_arg = 0;
- compiler->cache_argw = 0;
- }
-
- if (dst == TMP_REG2) {
- SLJIT_ASSERT(HAS_FLAGS(op));
- flags |= UNUSED_DEST;
- }
- else if (FAST_IS_REG(dst)) {
- dst_r = dst;
- flags |= REG_DEST;
- if (flags & MOVE_OP)
- sugg_src2_r = dst_r;
- }
- else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw))
- flags |= SLOW_DEST;
-
- if (flags & IMM_OP) {
- if ((src2 & SLJIT_IMM) && src2w != 0 && CHECK_IMM(flags, src2w)) {
- flags |= SRC2_IMM;
- src2_r = src2w;
- } else if ((flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w != 0 && CHECK_IMM(flags, src1w)) {
- flags |= SRC2_IMM;
- src2_r = src1w;
-
- /* And swap arguments. */
- src1 = src2;
- src1w = src2w;
- src2 = SLJIT_IMM;
- /* src2w = src2_r unneeded. */
- }
- }
-
- /* Source 1. */
- if (FAST_IS_REG(src1)) {
- src1_r = src1;
- flags |= REG1_SOURCE;
- }
- else if (src1 & SLJIT_IMM) {
- if (src1w) {
- FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));
- src1_r = TMP_REG1;
- }
- else
- src1_r = 0;
- }
- else {
- if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w))
- FAIL_IF(compiler->error);
- else
- flags |= SLOW_SRC1;
- src1_r = TMP_REG1;
- }
-
- /* Source 2. */
- if (FAST_IS_REG(src2)) {
- src2_r = src2;
- flags |= REG2_SOURCE;
- if ((flags & (REG_DEST | MOVE_OP)) == MOVE_OP)
- dst_r = (sljit_s32)src2_r;
- }
- else if (src2 & SLJIT_IMM) {
- if (!(flags & SRC2_IMM)) {
- if (src2w) {
- FAIL_IF(load_immediate(compiler, DR(sugg_src2_r), src2w));
- src2_r = sugg_src2_r;
- }
- else {
- src2_r = 0;
- if (flags & MOVE_OP) {
- if (dst & SLJIT_MEM)
- dst_r = 0;
- else
- op = SLJIT_MOV;
- }
- }
- }
- }
- else {
- if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w))
- FAIL_IF(compiler->error);
- else
- flags |= SLOW_SRC2;
- src2_r = sugg_src2_r;
- }
-
- if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
- SLJIT_ASSERT(src2_r == TMP_REG2);
- if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, src1, src1w));
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));
- }
- else {
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, src2, src2w));
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, dst, dstw));
- }
- }
- else if (flags & SLOW_SRC1)
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));
- else if (flags & SLOW_SRC2)
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w, dst, dstw));
-
- FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
-
- if (dst & SLJIT_MEM) {
- if (!(flags & SLOW_DEST)) {
- getput_arg_fast(compiler, flags, DR(dst_r), dst, dstw);
- return compiler->error;
- }
- return getput_arg(compiler, flags, DR(dst_r), dst, dstw, 0, 0);
- }
-
- return SLJIT_SUCCESS;
-}
-
-#undef CHECK_IMM
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
-{
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
- sljit_s32 int_op = op & SLJIT_32;
-#endif
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op0(compiler, op));
-
- op = GET_OPCODE(op);
- switch (op) {
- case SLJIT_BREAKPOINT:
- return push_inst(compiler, BREAK, UNMOVABLE_INS);
- case SLJIT_NOP:
- return push_inst(compiler, NOP, UNMOVABLE_INS);
- case SLJIT_LMUL_UW:
- case SLJIT_LMUL_SW:
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
- FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULU : DMUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
- FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMUHU : DMUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
-#else /* !SLJIT_CONFIG_MIPS_64 */
- FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULU : MUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
- FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MUHU : MUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
-#endif /* SLJIT_CONFIG_MIPS_64 */
- FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));
- return push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));
-#else /* SLJIT_MIPS_REV < 6 */
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
- FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULTU : DMULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
-#else /* !SLJIT_CONFIG_MIPS_64 */
- FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULTU : MULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
-#endif /* SLJIT_CONFIG_MIPS_64 */
- FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
- return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
-#endif /* SLJIT_MIPS_REV >= 6 */
- case SLJIT_DIVMOD_UW:
- case SLJIT_DIVMOD_SW:
- case SLJIT_DIV_UW:
- case SLJIT_DIV_SW:
- SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
- if (int_op) {
- FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
- FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? MODU : MOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
- }
- else {
- FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
- FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DMODU : DMOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
- }
-#else /* !SLJIT_CONFIG_MIPS_64 */
- FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
- FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? MODU : MOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
-#endif /* SLJIT_CONFIG_MIPS_64 */
- FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));
- return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));
-#else /* SLJIT_MIPS_REV < 6 */
-#if !(defined SLJIT_MIPS_REV)
- FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
- FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
-#endif /* !SLJIT_MIPS_REV */
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
- if (int_op)
- FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
- else
- FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
-#else /* !SLJIT_CONFIG_MIPS_64 */
- FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
-#endif /* SLJIT_CONFIG_MIPS_64 */
- FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
- return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
-#endif /* SLJIT_MIPS_REV >= 6 */
- case SLJIT_ENDBR:
- case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
- return SLJIT_SUCCESS;
- }
-
- return SLJIT_SUCCESS;
-}
-
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
-static sljit_s32 emit_prefetch(struct sljit_compiler *compiler,
- sljit_s32 src, sljit_sw srcw)
-{
- if (!(src & OFFS_REG_MASK)) {
- if (srcw <= SIMM_MAX && srcw >= SIMM_MIN)
- return push_inst(compiler, PREF | S(src & REG_MASK) | IMM(srcw), MOVABLE_INS);
-
- FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));
- return push_inst(compiler, PREFX | S(src & REG_MASK) | T(TMP_REG1), MOVABLE_INS);
- }
-
- srcw &= 0x3;
-
- if (SLJIT_UNLIKELY(srcw != 0)) {
- FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(src)) | D(TMP_REG1) | SH_IMM(srcw), DR(TMP_REG1)));
- return push_inst(compiler, PREFX | S(src & REG_MASK) | T(TMP_REG1), MOVABLE_INS);
- }
-
- return push_inst(compiler, PREFX | S(src & REG_MASK) | T(OFFS_REG(src)), MOVABLE_INS);
-}
-#endif /* SLJIT_MIPS_REV >= 1 */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 flags = 0;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src, srcw);
-
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
- if (op & SLJIT_32)
- flags = INT_DATA | SIGNED_DATA;
-#endif
-
- switch (GET_OPCODE(op)) {
- case SLJIT_MOV:
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- case SLJIT_MOV_U32:
- case SLJIT_MOV_S32:
- case SLJIT_MOV32:
-#endif
- case SLJIT_MOV_P:
- return emit_op(compiler, SLJIT_MOV, WORD_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, srcw);
-
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
- case SLJIT_MOV_U32:
- return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u32)srcw : srcw);
-
- case SLJIT_MOV_S32:
- case SLJIT_MOV32:
- return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s32)srcw : srcw);
-#endif
-
- case SLJIT_MOV_U8:
- return emit_op(compiler, op, BYTE_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
-
- case SLJIT_MOV_S8:
- return emit_op(compiler, op, BYTE_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
-
- case SLJIT_MOV_U16:
- return emit_op(compiler, op, HALF_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
-
- case SLJIT_MOV_S16:
- return emit_op(compiler, op, HALF_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
-
- case SLJIT_NOT:
- return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
-
- case SLJIT_CLZ:
- case SLJIT_CTZ:
- return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
- }
-
- SLJIT_UNREACHABLE();
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 flags = 0;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
- if (op & SLJIT_32) {
- flags |= INT_DATA | SIGNED_DATA;
- if (src1 & SLJIT_IMM)
- src1w = (sljit_s32)src1w;
- if (src2 & SLJIT_IMM)
- src2w = (sljit_s32)src2w;
- }
-#endif
-
- switch (GET_OPCODE(op)) {
- case SLJIT_ADD:
- case SLJIT_ADDC:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;
- return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_SUB:
- case SLJIT_SUBC:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;
- return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_MUL:
- compiler->status_flags_state = 0;
- return emit_op(compiler, op, flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_AND:
- case SLJIT_OR:
- case SLJIT_XOR:
- return emit_op(compiler, op, flags | CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_SHL:
- case SLJIT_MSHL:
- case SLJIT_LSHR:
- case SLJIT_MLSHR:
- case SLJIT_ASHR:
- case SLJIT_MASHR:
- case SLJIT_ROTL:
- case SLJIT_ROTR:
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- if (src2 & SLJIT_IMM)
- src2w &= 0x1f;
-#else
- if (src2 & SLJIT_IMM) {
- if (op & SLJIT_32)
- src2w &= 0x1f;
- else
- src2w &= 0x3f;
- }
-#endif
- return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
- }
-
- SLJIT_UNREACHABLE();
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_op2(compiler, op, TMP_REG2, 0, src1, src1w, src2, src2w);
-}
-
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
-#define SELECT_OP3(op, src2w, D, D32, W) (((op & SLJIT_32) ? (W) : ((src2w) < 32) ? (D) : (D32)) | (((sljit_ins)src2w & 0x1f) << 6))
-#define SELECT_OP2(op, D, W) ((op & SLJIT_32) ? (W) : (D))
-#else /* !SLJIT_CONFIG_MIPS_64 */
-#define SELECT_OP3(op, src2w, D, D32, W) ((W) | ((sljit_ins)(src2w) << 6))
-#define SELECT_OP2(op, D, W) (W)
-#endif /* SLJIT_CONFIG_MIPS_64 */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src_dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 is_left;
- sljit_ins ins1, ins2, ins3;
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
- sljit_s32 inp_flags = ((op & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;
- sljit_sw bit_length = (op & SLJIT_32) ? 32 : 64;
-#else /* !SLJIT_CONFIG_MIPS_64 */
- sljit_s32 inp_flags = WORD_DATA | LOAD_DATA;
- sljit_sw bit_length = 32;
-#endif /* SLJIT_CONFIG_MIPS_64 */
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w));
-
- is_left = (GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_MSHL);
-
- if (src_dst == src1) {
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), src_dst, 0, src_dst, 0, src2, src2w);
- }
-
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- if (src2 & SLJIT_IMM) {
- src2w &= bit_length - 1;
-
- if (src2w == 0)
- return SLJIT_SUCCESS;
- } else if (src2 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG2), src2, src2w));
- src2 = TMP_REG2;
- }
-
- if (src1 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG1), src1, src1w));
- src1 = TMP_REG1;
- } else if (src1 & SLJIT_IMM) {
- FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));
- src1 = TMP_REG1;
- }
-
- if (src2 & SLJIT_IMM) {
- if (is_left) {
- ins1 = SELECT_OP3(op, src2w, DSLL, DSLL32, SLL);
- src2w = bit_length - src2w;
- ins2 = SELECT_OP3(op, src2w, DSRL, DSRL32, SRL);
- } else {
- ins1 = SELECT_OP3(op, src2w, DSRL, DSRL32, SRL);
- src2w = bit_length - src2w;
- ins2 = SELECT_OP3(op, src2w, DSLL, DSLL32, SLL);
- }
-
- FAIL_IF(push_inst(compiler, ins1 | T(src_dst) | D(src_dst), DR(src_dst)));
- FAIL_IF(push_inst(compiler, ins2 | T(src1) | D(TMP_REG1), DR(TMP_REG1)));
- return push_inst(compiler, OR | S(src_dst) | T(TMP_REG1) | D(src_dst), DR(src_dst));
- }
-
- if (is_left) {
- ins1 = SELECT_OP2(op, DSRL, SRL);
- ins2 = SELECT_OP2(op, DSLLV, SLLV);
- ins3 = SELECT_OP2(op, DSRLV, SRLV);
- } else {
- ins1 = SELECT_OP2(op, DSLL, SLL);
- ins2 = SELECT_OP2(op, DSRLV, SRLV);
- ins3 = SELECT_OP2(op, DSLLV, SLLV);
- }
-
- FAIL_IF(push_inst(compiler, ins2 | S(src2) | T(src_dst) | D(src_dst), DR(src_dst)));
-
- if (!(op & SLJIT_SHIFT_INTO_NON_ZERO)) {
- FAIL_IF(push_inst(compiler, ins1 | T(src1) | D(TMP_REG1) | (1 << 6), DR(TMP_REG1)));
- FAIL_IF(push_inst(compiler, XORI | S(src2) | T(TMP_REG2) | ((sljit_ins)bit_length - 1), DR(TMP_REG2)));
- src1 = TMP_REG1;
- } else
- FAIL_IF(push_inst(compiler, SELECT_OP2(op, DSUBU, SUBU) | SA(0) | T(src2) | D(TMP_REG2), DR(TMP_REG2)));
-
- FAIL_IF(push_inst(compiler, ins3 | S(TMP_REG2) | T(src1) | D(TMP_REG1), DR(TMP_REG1)));
- return push_inst(compiler, OR | S(src_dst) | T(TMP_REG1) | D(src_dst), DR(src_dst));
-}
-
-#undef SELECT_OP3
-#undef SELECT_OP2
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- switch (op) {
- case SLJIT_FAST_RETURN:
- if (FAST_IS_REG(src))
- FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG));
- else
- FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw));
-
- FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
- return push_inst(compiler, NOP, UNMOVABLE_INS);
- case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
- return SLJIT_SUCCESS;
- case SLJIT_PREFETCH_L1:
- case SLJIT_PREFETCH_L2:
- case SLJIT_PREFETCH_L3:
- case SLJIT_PREFETCH_ONCE:
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
- return emit_prefetch(compiler, src, srcw);
-#else /* SLJIT_MIPS_REV < 1 */
- return SLJIT_SUCCESS;
-#endif /* SLJIT_MIPS_REV >= 1 */
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
-{
- CHECK_REG_INDEX(check_sljit_get_register_index(reg));
- return reg_map[reg];
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
-{
- CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
- return FR(reg);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
- void *instruction, sljit_u32 size)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
-
- return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS);
-}
-
-/* --------------------------------------------------------------------- */
-/* Floating point operators */
-/* --------------------------------------------------------------------- */
-
-#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_32) >> 7))
-#define FMT(op) ((((sljit_ins)op & SLJIT_32) ^ SLJIT_32) << (21 - 8))
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
-# define flags (sljit_u32)0
-#else
- sljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64)) << 21;
-#endif
-
- if (src & SLJIT_MEM) {
- FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src, srcw, dst, dstw));
- src = TMP_FREG1;
- }
-
- FAIL_IF(push_inst(compiler, (TRUNC_W_S ^ (flags >> 19)) | FMT(op) | FS(src) | FD(TMP_FREG1), MOVABLE_INS));
-
- if (FAST_IS_REG(dst)) {
- FAIL_IF(push_inst(compiler, MFC1 | flags | T(dst) | FS(TMP_FREG1), MOVABLE_INS));
-#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
- FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
-#endif
- return SLJIT_SUCCESS;
- }
-
- /* Store the integer value from a VFP register. */
- return emit_op_mem2(compiler, flags ? DOUBLE_DATA : SINGLE_DATA, FR(TMP_FREG1), dst, dstw, 0, 0);
-
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
-# undef flags
-#endif
-}
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
-# define flags (sljit_u32)0
-#else
- sljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW)) << 21;
-#endif
-
- sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
-
- if (FAST_IS_REG(src)) {
- FAIL_IF(push_inst(compiler, MTC1 | flags | T(src) | FS(TMP_FREG1), MOVABLE_INS));
-#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
- FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
-#endif
- } else if (src & SLJIT_MEM) {
- /* Load the integer value into a VFP register. */
- FAIL_IF(emit_op_mem2(compiler, (flags ? DOUBLE_DATA : SINGLE_DATA) | LOAD_DATA, FR(TMP_FREG1), src, srcw, dst, dstw));
- }
- else {
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
- if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
- srcw = (sljit_s32)srcw;
-#endif
- FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));
- FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG1) | FS(TMP_FREG1), MOVABLE_INS));
-#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
- FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
-#endif
- }
-
- FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((((sljit_ins)op & SLJIT_32) ^ SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS));
-
- if (dst & SLJIT_MEM)
- return emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0);
- return SLJIT_SUCCESS;
-
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
-# undef flags
-#endif
-}
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_ins inst;
-
- if (src1 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, src2, src2w));
- src1 = TMP_FREG1;
- }
-
- if (src2 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, 0, 0));
- src2 = TMP_FREG2;
- }
-
- switch (GET_FLAG_TYPE(op)) {
- case SLJIT_F_EQUAL:
- case SLJIT_ORDERED_EQUAL:
- case SLJIT_UNORDERED_OR_NOT_EQUAL:
- inst = C_EQ_S;
- break;
- case SLJIT_F_NOT_EQUAL:
- case SLJIT_UNORDERED_OR_EQUAL:
- case SLJIT_ORDERED_NOT_EQUAL:
- inst = C_UEQ_S;
- break;
- case SLJIT_F_LESS:
- case SLJIT_ORDERED_LESS:
- case SLJIT_UNORDERED_OR_GREATER_EQUAL:
- inst = C_OLT_S;
- break;
- case SLJIT_F_GREATER_EQUAL:
- case SLJIT_UNORDERED_OR_LESS:
- case SLJIT_ORDERED_GREATER_EQUAL:
- inst = C_ULT_S;
- break;
- case SLJIT_F_GREATER:
- case SLJIT_ORDERED_GREATER:
- case SLJIT_UNORDERED_OR_LESS_EQUAL:
- inst = C_ULE_S;
- break;
- case SLJIT_F_LESS_EQUAL:
- case SLJIT_UNORDERED_OR_GREATER:
- case SLJIT_ORDERED_LESS_EQUAL:
- inst = C_OLE_S;
- break;
- default:
- SLJIT_ASSERT(GET_FLAG_TYPE(op) == SLJIT_UNORDERED || GET_FLAG_TYPE(op) == SLJIT_ORDERED);
- inst = C_UN_S;
- break;
- }
- return push_inst(compiler, inst | FMT(op) | FT(src2) | FS(src1) | C_FD, UNMOVABLE_INS);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 dst_r;
-
- CHECK_ERROR();
- compiler->cache_arg = 0;
- compiler->cache_argw = 0;
-
- SLJIT_COMPILE_ASSERT((SLJIT_32 == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);
- SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
-
- if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
- op ^= SLJIT_32;
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
-
- if (src & SLJIT_MEM) {
- FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(dst_r), src, srcw, dst, dstw));
- src = dst_r;
- }
-
- switch (GET_OPCODE(op)) {
- case SLJIT_MOV_F64:
- if (src != dst_r) {
- if (dst_r != TMP_FREG1)
- FAIL_IF(push_inst(compiler, MOV_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS));
- else
- dst_r = src;
- }
- break;
- case SLJIT_NEG_F64:
- FAIL_IF(push_inst(compiler, NEG_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS));
- break;
- case SLJIT_ABS_F64:
- FAIL_IF(push_inst(compiler, ABS_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS));
- break;
- case SLJIT_CONV_F64_FROM_F32:
- /* The SLJIT_32 bit is inverted because sljit_f32 needs to be loaded from the memory. */
- FAIL_IF(push_inst(compiler, CVT_S_S | (sljit_ins)((op & SLJIT_32) ? 1 : (1 << 21)) | FS(src) | FD(dst_r), MOVABLE_INS));
- op ^= SLJIT_32;
- break;
- }
-
- if (dst & SLJIT_MEM)
- return emit_op_mem2(compiler, FLOAT_DATA(op), FR(dst_r), dst, dstw, 0, 0);
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 dst_r, flags = 0;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- compiler->cache_arg = 0;
- compiler->cache_argw = 0;
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;
-
- if (src1 & SLJIT_MEM) {
- if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w)) {
- FAIL_IF(compiler->error);
- src1 = TMP_FREG1;
- } else
- flags |= SLOW_SRC1;
- }
-
- if (src2 & SLJIT_MEM) {
- if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w)) {
- FAIL_IF(compiler->error);
- src2 = TMP_FREG2;
- } else
- flags |= SLOW_SRC2;
- }
-
- if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
- if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
- FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, src1, src1w));
- FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, dst, dstw));
- }
- else {
- FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, src2, src2w));
- FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, dst, dstw));
- }
- }
- else if (flags & SLOW_SRC1)
- FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, dst, dstw));
- else if (flags & SLOW_SRC2)
- FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, dst, dstw));
-
- if (flags & SLOW_SRC1)
- src1 = TMP_FREG1;
- if (flags & SLOW_SRC2)
- src2 = TMP_FREG2;
-
- switch (GET_OPCODE(op)) {
- case SLJIT_ADD_F64:
- FAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
- break;
-
- case SLJIT_SUB_F64:
- FAIL_IF(push_inst(compiler, SUB_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
- break;
-
- case SLJIT_MUL_F64:
- FAIL_IF(push_inst(compiler, MUL_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
- break;
-
- case SLJIT_DIV_F64:
- FAIL_IF(push_inst(compiler, DIV_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
- break;
- }
-
- if (dst_r == TMP_FREG2)
- FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG2), dst, dstw, 0, 0));
-
- return SLJIT_SUCCESS;
-}
-
-#undef FLOAT_DATA
-#undef FMT
-
-/* --------------------------------------------------------------------- */
-/* Other instructions */
-/* --------------------------------------------------------------------- */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- if (FAST_IS_REG(dst))
- return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), UNMOVABLE_INS);
-
- /* Memory. */
- FAIL_IF(emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw));
- compiler->delay_slot = UNMOVABLE_INS;
- return SLJIT_SUCCESS;
-}
-
-/* --------------------------------------------------------------------- */
-/* Conditional instructions */
-/* --------------------------------------------------------------------- */
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
-{
- struct sljit_label *label;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_label(compiler));
-
- if (compiler->last_label && compiler->last_label->size == compiler->size)
- return compiler->last_label;
-
- label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
- PTR_FAIL_IF(!label);
- set_label(label, compiler);
- compiler->delay_slot = UNMOVABLE_INS;
- return label;
-}
-
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
-#define BRANCH_LENGTH 4
-#else
-#define BRANCH_LENGTH 8
-#endif
-
-#define BR_Z(src) \
- inst = BEQ | SA(src) | TA(0) | BRANCH_LENGTH; \
- flags = IS_BIT26_COND; \
- delay_check = src;
-
-#define BR_NZ(src) \
- inst = BNE | SA(src) | TA(0) | BRANCH_LENGTH; \
- flags = IS_BIT26_COND; \
- delay_check = src;
-
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
-
-#define BR_T() \
- inst = BC1NEZ; \
- flags = IS_BIT23_COND; \
- delay_check = FCSR_FCC;
-#define BR_F() \
- inst = BC1EQZ; \
- flags = IS_BIT23_COND; \
- delay_check = FCSR_FCC;
-
-#else /* SLJIT_MIPS_REV < 6 */
-
-#define BR_T() \
- inst = BC1T | BRANCH_LENGTH; \
- flags = IS_BIT16_COND; \
- delay_check = FCSR_FCC;
-#define BR_F() \
- inst = BC1F | BRANCH_LENGTH; \
- flags = IS_BIT16_COND; \
- delay_check = FCSR_FCC;
-
-#endif /* SLJIT_MIPS_REV >= 6 */
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
-{
- struct sljit_jump *jump;
- sljit_ins inst;
- sljit_u32 flags = 0;
- sljit_s32 delay_check = UNMOVABLE_INS;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_jump(compiler, type));
-
- jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
- PTR_FAIL_IF(!jump);
- set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
- type &= 0xff;
-
- switch (type) {
- case SLJIT_EQUAL:
- BR_NZ(EQUAL_FLAG);
- break;
- case SLJIT_NOT_EQUAL:
- BR_Z(EQUAL_FLAG);
- break;
- case SLJIT_LESS:
- case SLJIT_GREATER:
- case SLJIT_SIG_LESS:
- case SLJIT_SIG_GREATER:
- case SLJIT_OVERFLOW:
- case SLJIT_CARRY:
- BR_Z(OTHER_FLAG);
- break;
- case SLJIT_GREATER_EQUAL:
- case SLJIT_LESS_EQUAL:
- case SLJIT_SIG_GREATER_EQUAL:
- case SLJIT_SIG_LESS_EQUAL:
- case SLJIT_NOT_OVERFLOW:
- case SLJIT_NOT_CARRY:
- BR_NZ(OTHER_FLAG);
- break;
- case SLJIT_F_NOT_EQUAL:
- case SLJIT_F_GREATER_EQUAL:
- case SLJIT_F_GREATER:
- case SLJIT_UNORDERED_OR_NOT_EQUAL:
- case SLJIT_ORDERED_NOT_EQUAL:
- case SLJIT_UNORDERED_OR_GREATER_EQUAL:
- case SLJIT_ORDERED_GREATER_EQUAL:
- case SLJIT_ORDERED_GREATER:
- case SLJIT_UNORDERED_OR_GREATER:
- case SLJIT_ORDERED:
- BR_T();
- break;
- case SLJIT_F_EQUAL:
- case SLJIT_F_LESS:
- case SLJIT_F_LESS_EQUAL:
- case SLJIT_ORDERED_EQUAL:
- case SLJIT_UNORDERED_OR_EQUAL:
- case SLJIT_ORDERED_LESS:
- case SLJIT_UNORDERED_OR_LESS:
- case SLJIT_UNORDERED_OR_LESS_EQUAL:
- case SLJIT_ORDERED_LESS_EQUAL:
- case SLJIT_UNORDERED:
- BR_F();
- break;
- default:
- /* Not conditional branch. */
- inst = 0;
- break;
- }
-
- jump->flags |= flags;
- if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != delay_check))
- jump->flags |= IS_MOVABLE;
-
- if (inst)
- PTR_FAIL_IF(push_inst(compiler, inst, UNMOVABLE_INS));
-
- if (type <= SLJIT_JUMP)
- PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS));
- else {
- jump->flags |= IS_JAL;
- PTR_FAIL_IF(push_inst(compiler, JALR | S(TMP_REG2) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
- }
-
- jump->addr = compiler->size;
- PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
-
- /* Maximum number of instructions required for generating a constant. */
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- compiler->size += 2;
-#else
- compiler->size += 6;
-#endif
- return jump;
-}
-
-#define RESOLVE_IMM1() \
- if (src1 & SLJIT_IMM) { \
- if (src1w) { \
- PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); \
- src1 = TMP_REG1; \
- } \
- else \
- src1 = 0; \
- }
-
-#define RESOLVE_IMM2() \
- if (src2 & SLJIT_IMM) { \
- if (src2w) { \
- PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG2), src2w)); \
- src2 = TMP_REG2; \
- } \
- else \
- src2 = 0; \
- }
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- struct sljit_jump *jump;
- sljit_s32 flags;
- sljit_ins inst;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- compiler->cache_arg = 0;
- compiler->cache_argw = 0;
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- flags = WORD_DATA | LOAD_DATA;
-#else /* !SLJIT_CONFIG_MIPS_32 */
- flags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;
-#endif /* SLJIT_CONFIG_MIPS_32 */
-
- if (src1 & SLJIT_MEM) {
- PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG1), src1, src1w, src2, src2w));
- src1 = TMP_REG1;
- }
-
- if (src2 & SLJIT_MEM) {
- PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG2), src2, src2w, 0, 0));
- src2 = TMP_REG2;
- }
-
- jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
- PTR_FAIL_IF(!jump);
- set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
- type &= 0xff;
-
- if (type <= SLJIT_NOT_EQUAL) {
- RESOLVE_IMM1();
- RESOLVE_IMM2();
- jump->flags |= IS_BIT26_COND;
- if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != DR(src1) && compiler->delay_slot != DR(src2)))
- jump->flags |= IS_MOVABLE;
- PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(src1) | T(src2) | BRANCH_LENGTH, UNMOVABLE_INS));
- }
- else if (type >= SLJIT_SIG_LESS && (((src1 & SLJIT_IMM) && (src1w == 0)) || ((src2 & SLJIT_IMM) && (src2w == 0)))) {
- inst = NOP;
- if ((src1 & SLJIT_IMM) && (src1w == 0)) {
- RESOLVE_IMM2();
- switch (type) {
- case SLJIT_SIG_LESS:
- inst = BLEZ;
- jump->flags |= IS_BIT26_COND;
- break;
- case SLJIT_SIG_GREATER_EQUAL:
- inst = BGTZ;
- jump->flags |= IS_BIT26_COND;
- break;
- case SLJIT_SIG_GREATER:
- inst = BGEZ;
- jump->flags |= IS_BIT16_COND;
- break;
- case SLJIT_SIG_LESS_EQUAL:
- inst = BLTZ;
- jump->flags |= IS_BIT16_COND;
- break;
- }
- src1 = src2;
- }
- else {
- RESOLVE_IMM1();
- switch (type) {
- case SLJIT_SIG_LESS:
- inst = BGEZ;
- jump->flags |= IS_BIT16_COND;
- break;
- case SLJIT_SIG_GREATER_EQUAL:
- inst = BLTZ;
- jump->flags |= IS_BIT16_COND;
- break;
- case SLJIT_SIG_GREATER:
- inst = BLEZ;
- jump->flags |= IS_BIT26_COND;
- break;
- case SLJIT_SIG_LESS_EQUAL:
- inst = BGTZ;
- jump->flags |= IS_BIT26_COND;
- break;
- }
- }
- PTR_FAIL_IF(push_inst(compiler, inst | S(src1) | BRANCH_LENGTH, UNMOVABLE_INS));
- }
- else {
- if (type == SLJIT_LESS || type == SLJIT_GREATER_EQUAL || type == SLJIT_SIG_LESS || type == SLJIT_SIG_GREATER_EQUAL) {
- RESOLVE_IMM1();
- if ((src2 & SLJIT_IMM) && src2w <= SIMM_MAX && src2w >= SIMM_MIN)
- PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src1) | T(TMP_REG1) | IMM(src2w), DR(TMP_REG1)));
- else {
- RESOLVE_IMM2();
- PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTU : SLT) | S(src1) | T(src2) | D(TMP_REG1), DR(TMP_REG1)));
- }
- type = (type == SLJIT_LESS || type == SLJIT_SIG_LESS) ? SLJIT_NOT_EQUAL : SLJIT_EQUAL;
- }
- else {
- RESOLVE_IMM2();
- if ((src1 & SLJIT_IMM) && src1w <= SIMM_MAX && src1w >= SIMM_MIN)
- PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src2) | T(TMP_REG1) | IMM(src1w), DR(TMP_REG1)));
- else {
- RESOLVE_IMM1();
- PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTU : SLT) | S(src2) | T(src1) | D(TMP_REG1), DR(TMP_REG1)));
- }
- type = (type == SLJIT_GREATER || type == SLJIT_SIG_GREATER) ? SLJIT_NOT_EQUAL : SLJIT_EQUAL;
- }
-
- jump->flags |= IS_BIT26_COND;
- PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(TMP_REG1) | TA(0) | BRANCH_LENGTH, UNMOVABLE_INS));
- }
-
- PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS));
- jump->addr = compiler->size;
- PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
-
- /* Maximum number of instructions required for generating a constant. */
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- compiler->size += 2;
-#else
- compiler->size += 6;
-#endif
- return jump;
-}
-
-#undef RESOLVE_IMM1
-#undef RESOLVE_IMM2
-
-#undef BRANCH_LENGTH
-#undef BR_Z
-#undef BR_NZ
-#undef BR_T
-#undef BR_F
-
-#undef FLOAT_DATA
-#undef FMT
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
-{
- struct sljit_jump *jump = NULL;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
-
- if (src & SLJIT_IMM) {
- jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
- FAIL_IF(!jump);
- set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0));
- jump->u.target = (sljit_uw)srcw;
-
- if (compiler->delay_slot != UNMOVABLE_INS)
- jump->flags |= IS_MOVABLE;
-
- src = TMP_REG2;
- } else if (src & SLJIT_MEM) {
- ADJUST_LOCAL_OFFSET(src, srcw);
- FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(TMP_REG2), src, srcw));
- src = TMP_REG2;
- }
-
- if (type <= SLJIT_JUMP)
- FAIL_IF(push_inst(compiler, JR | S(src), UNMOVABLE_INS));
- else
- FAIL_IF(push_inst(compiler, JALR | S(src) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
-
- if (jump != NULL) {
- jump->addr = compiler->size;
-
- /* Maximum number of instructions required for generating a constant. */
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- compiler->size += 2;
-#else
- compiler->size += 6;
-#endif
- }
-
- FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 type)
-{
- sljit_s32 src_ar, dst_ar, invert;
- sljit_s32 saved_op = op;
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- sljit_s32 mem_type = WORD_DATA;
-#else
- sljit_s32 mem_type = ((op & SLJIT_32) || op == SLJIT_MOV32) ? (INT_DATA | SIGNED_DATA) : WORD_DATA;
-#endif
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- op = GET_OPCODE(op);
- dst_ar = DR((op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2);
-
- compiler->cache_arg = 0;
- compiler->cache_argw = 0;
-
- if (op >= SLJIT_ADD && (dst & SLJIT_MEM))
- FAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, DR(TMP_REG1), dst, dstw, dst, dstw));
-
- if (type < SLJIT_F_EQUAL) {
- src_ar = OTHER_FLAG;
- invert = type & 0x1;
-
- switch (type) {
- case SLJIT_EQUAL:
- case SLJIT_NOT_EQUAL:
- FAIL_IF(push_inst(compiler, SLTIU | SA(EQUAL_FLAG) | TA(dst_ar) | IMM(1), dst_ar));
- src_ar = dst_ar;
- break;
- case SLJIT_OVERFLOW:
- case SLJIT_NOT_OVERFLOW:
- if (compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)) {
- src_ar = OTHER_FLAG;
- break;
- }
- FAIL_IF(push_inst(compiler, SLTIU | SA(OTHER_FLAG) | TA(dst_ar) | IMM(1), dst_ar));
- src_ar = dst_ar;
- invert ^= 0x1;
- break;
- }
- } else {
- invert = 0;
-
- switch (type) {
- case SLJIT_F_NOT_EQUAL:
- case SLJIT_F_GREATER_EQUAL:
- case SLJIT_F_GREATER:
- case SLJIT_UNORDERED_OR_NOT_EQUAL:
- case SLJIT_ORDERED_NOT_EQUAL:
- case SLJIT_UNORDERED_OR_GREATER_EQUAL:
- case SLJIT_ORDERED_GREATER_EQUAL:
- case SLJIT_ORDERED_GREATER:
- case SLJIT_UNORDERED_OR_GREATER:
- case SLJIT_ORDERED:
- invert = 1;
- break;
- }
-
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
- FAIL_IF(push_inst(compiler, MFC1 | TA(dst_ar) | FS(TMP_FREG3), dst_ar));
-#else /* SLJIT_MIPS_REV < 6 */
- FAIL_IF(push_inst(compiler, CFC1 | TA(dst_ar) | DA(FCSR_REG), dst_ar));
-#endif /* SLJIT_MIPS_REV >= 6 */
- FAIL_IF(push_inst(compiler, SRL | TA(dst_ar) | DA(dst_ar) | SH_IMM(23), dst_ar));
- FAIL_IF(push_inst(compiler, ANDI | SA(dst_ar) | TA(dst_ar) | IMM(1), dst_ar));
- src_ar = dst_ar;
- }
-
- if (invert) {
- FAIL_IF(push_inst(compiler, XORI | SA(src_ar) | TA(dst_ar) | IMM(1), dst_ar));
- src_ar = dst_ar;
- }
-
- if (op < SLJIT_ADD) {
- if (dst & SLJIT_MEM)
- return emit_op_mem(compiler, mem_type, src_ar, dst, dstw);
-
- if (src_ar != dst_ar)
- return push_inst(compiler, ADDU_W | SA(src_ar) | TA(0) | DA(dst_ar), dst_ar);
- return SLJIT_SUCCESS;
- }
-
- /* OTHER_FLAG cannot be specified as src2 argument at the moment. */
- if (DR(TMP_REG2) != src_ar)
- FAIL_IF(push_inst(compiler, ADDU_W | SA(src_ar) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
-
- mem_type |= CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE;
-
- if (dst & SLJIT_MEM)
- return emit_op(compiler, saved_op, mem_type, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
- return emit_op(compiler, saved_op, mem_type, dst, dstw, dst, dstw, TMP_REG2, 0);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 dst_reg,
- sljit_s32 src, sljit_sw srcw)
-{
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
- sljit_ins ins;
-#endif /* SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6 */
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
-
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
-
- if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
- if (type & SLJIT_32)
- srcw = (sljit_s32)srcw;
-#endif
- FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));
- src = TMP_REG1;
- srcw = 0;
- }
-
- switch (type & ~SLJIT_32) {
- case SLJIT_EQUAL:
- ins = MOVZ | TA(EQUAL_FLAG);
- break;
- case SLJIT_NOT_EQUAL:
- ins = MOVN | TA(EQUAL_FLAG);
- break;
- case SLJIT_LESS:
- case SLJIT_GREATER:
- case SLJIT_SIG_LESS:
- case SLJIT_SIG_GREATER:
- case SLJIT_OVERFLOW:
- ins = MOVN | TA(OTHER_FLAG);
- break;
- case SLJIT_GREATER_EQUAL:
- case SLJIT_LESS_EQUAL:
- case SLJIT_SIG_GREATER_EQUAL:
- case SLJIT_SIG_LESS_EQUAL:
- case SLJIT_NOT_OVERFLOW:
- ins = MOVZ | TA(OTHER_FLAG);
- break;
- case SLJIT_F_EQUAL:
- case SLJIT_F_LESS:
- case SLJIT_F_LESS_EQUAL:
- case SLJIT_ORDERED_EQUAL:
- case SLJIT_UNORDERED_OR_EQUAL:
- case SLJIT_ORDERED_LESS:
- case SLJIT_UNORDERED_OR_LESS:
- case SLJIT_UNORDERED_OR_LESS_EQUAL:
- case SLJIT_ORDERED_LESS_EQUAL:
- case SLJIT_UNORDERED:
- ins = MOVT;
- break;
- case SLJIT_F_NOT_EQUAL:
- case SLJIT_F_GREATER_EQUAL:
- case SLJIT_F_GREATER:
- case SLJIT_UNORDERED_OR_NOT_EQUAL:
- case SLJIT_ORDERED_NOT_EQUAL:
- case SLJIT_UNORDERED_OR_GREATER_EQUAL:
- case SLJIT_ORDERED_GREATER_EQUAL:
- case SLJIT_ORDERED_GREATER:
- case SLJIT_UNORDERED_OR_GREATER:
- case SLJIT_ORDERED:
- ins = MOVF;
- break;
- default:
- ins = MOVZ | TA(OTHER_FLAG);
- SLJIT_UNREACHABLE();
- break;
- }
-
- return push_inst(compiler, ins | S(src) | D(dst_reg), DR(dst_reg));
-
-#else /* SLJIT_MIPS_REV < 1 || SLJIT_MIPS_REV >= 6 */
- return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);
-#endif /* SLJIT_MIPS_REV >= 1 */
-}
-
-static sljit_s32 update_mem_addr(struct sljit_compiler *compiler, sljit_s32 *mem, sljit_sw *memw, sljit_s16 max_offset)
-{
- sljit_s32 arg = *mem;
- sljit_sw argw = *memw;
-
- if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
- argw &= 0x3;
-
- if (SLJIT_UNLIKELY(argw)) {
- FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | D(TMP_REG1) | SH_IMM(argw), DR(TMP_REG1)));
- FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG1) | T(arg & REG_MASK) | D(TMP_REG1), DR(TMP_REG1)));
- } else
- FAIL_IF(push_inst(compiler, ADDU_W | S(arg & REG_MASK) | T(OFFS_REG(arg)) | D(TMP_REG1), DR(TMP_REG1)));
-
- *mem = TMP_REG1;
- *memw = 0;
-
- return SLJIT_SUCCESS;
- }
-
- if (argw <= max_offset && argw >= SIMM_MIN) {
- *mem = arg & REG_MASK;
- return SLJIT_SUCCESS;
- }
-
- *mem = TMP_REG1;
-
- if ((sljit_s16)argw > max_offset) {
- FAIL_IF(load_immediate(compiler, DR(TMP_REG1), argw));
- *memw = 0;
- } else {
- FAIL_IF(load_immediate(compiler, DR(TMP_REG1), TO_ARGW_HI(argw)));
- *memw = (sljit_s16)argw;
- }
-
- if ((arg & REG_MASK) == 0)
- return SLJIT_SUCCESS;
-
- return push_inst(compiler, ADDU_W | S(TMP_REG1) | T(arg & REG_MASK) | D(TMP_REG1), DR(TMP_REG1));
-}
-
-#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
-#define MEM16_IMM_FIRST(memw) IMM((memw) + 1)
-#define MEM16_IMM_SECOND(memw) IMM(memw)
-#define MEMF64_FS_FIRST(freg) FS(freg)
-#define MEMF64_FS_SECOND(freg) (FS(freg) | ((sljit_ins)1 << 11))
-#else /* !SLJIT_LITTLE_ENDIAN */
-#define MEM16_IMM_FIRST(memw) IMM(memw)
-#define MEM16_IMM_SECOND(memw) IMM((memw) + 1)
-#define MEMF64_FS_FIRST(freg) (FS(freg) | ((sljit_ins)1 << 11))
-#define MEMF64_FS_SECOND(freg) FS(freg)
-#endif /* SLJIT_LITTLE_ENDIAN */
-
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
-#define MEM_CHECK_UNALIGNED(type) ((type) & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16))
-#else /* !SLJIT_CONFIG_MIPS_32 */
-#define MEM_CHECK_UNALIGNED(type) ((type) & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32))
-#endif /* SLJIT_CONFIG_MIPS_32 */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 reg,
- sljit_s32 mem, sljit_sw memw)
-{
- sljit_s32 op = type & 0xff;
- sljit_s32 flags = 0;
- sljit_ins ins;
-#if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
- sljit_ins ins_right;
-#endif /* !(SLJIT_MIPS_REV >= 6) */
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
-
- if (reg & REG_PAIR_MASK) {
- ADJUST_LOCAL_OFFSET(mem, memw);
-
-#if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
- if (MEM_CHECK_UNALIGNED(type)) {
- FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - (2 * SSIZE_OF(sw) - 1)));
-
- if (!(type & SLJIT_MEM_STORE) && (mem == REG_PAIR_FIRST(reg) || mem == REG_PAIR_SECOND(reg))) {
- FAIL_IF(push_inst(compiler, ADDU_W | S(mem) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
- mem = TMP_REG1;
- }
-
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- ins = ((type & SLJIT_MEM_STORE) ? SWL : LWL) | S(mem);
- ins_right = ((type & SLJIT_MEM_STORE) ? SWR : LWR) | S(mem);
-#else /* !SLJIT_CONFIG_MIPS_32 */
- ins = ((type & SLJIT_MEM_STORE) ? SDL : LDL) | S(mem);
- ins_right = ((type & SLJIT_MEM_STORE) ? SDR : LDR) | S(mem);
-#endif /* SLJIT_CONFIG_MIPS_32 */
-
- FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_FIRST(reg)) | IMM(memw), DR(REG_PAIR_FIRST(reg))));
- FAIL_IF(push_inst(compiler, ins_right | T(REG_PAIR_FIRST(reg)) | IMM(memw + (SSIZE_OF(sw) - 1)), DR(REG_PAIR_FIRST(reg))));
- FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_SECOND(reg)) | IMM(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg))));
- return push_inst(compiler, ins_right | T(REG_PAIR_SECOND(reg)) | IMM((memw + 2 * SSIZE_OF(sw) - 1)), DR(REG_PAIR_SECOND(reg)));
- }
-#endif /* !(SLJIT_MIPS_REV >= 6) */
-
- FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - SSIZE_OF(sw)));
-
- ins = ((type & SLJIT_MEM_STORE) ? STORE_W : LOAD_W) | S(mem);
-
- if (!(type & SLJIT_MEM_STORE) && mem == REG_PAIR_FIRST(reg)) {
- FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_SECOND(reg)) | IMM(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg))));
- return push_inst(compiler, ins | T(REG_PAIR_FIRST(reg)) | IMM(memw), DR(REG_PAIR_FIRST(reg)));
- }
-
- FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_FIRST(reg)) | IMM(memw), DR(REG_PAIR_FIRST(reg))));
- return push_inst(compiler, ins | T(REG_PAIR_SECOND(reg)) | IMM(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg)));
- }
-
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
- return sljit_emit_mem_unaligned(compiler, type, reg, mem, memw);
-#else /* !(SLJIT_MIPS_REV >= 6) */
- ADJUST_LOCAL_OFFSET(mem, memw);
-
- switch (op) {
- case SLJIT_MOV_U8:
- case SLJIT_MOV_S8:
- flags = BYTE_DATA;
- if (!(type & SLJIT_MEM_STORE))
- flags |= LOAD_DATA;
-
- if (op == SLJIT_MOV_S8)
- flags |= SIGNED_DATA;
-
- return emit_op_mem(compiler, flags, DR(reg), mem, memw);
-
- case SLJIT_MOV_U16:
- case SLJIT_MOV_S16:
- FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - 1));
- SLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2);
-
- if (type & SLJIT_MEM_STORE) {
- FAIL_IF(push_inst(compiler, SRA_W | T(reg) | D(TMP_REG2) | SH_IMM(8), DR(TMP_REG2)));
- FAIL_IF(push_inst(compiler, data_transfer_insts[BYTE_DATA] | S(mem) | T(TMP_REG2) | MEM16_IMM_FIRST(memw), MOVABLE_INS));
- return push_inst(compiler, data_transfer_insts[BYTE_DATA] | S(mem) | T(reg) | MEM16_IMM_SECOND(memw), MOVABLE_INS);
- }
-
- flags = BYTE_DATA | LOAD_DATA;
-
- if (op == SLJIT_MOV_S16)
- flags |= SIGNED_DATA;
-
- FAIL_IF(push_inst(compiler, data_transfer_insts[flags] | S(mem) | T(TMP_REG2) | MEM16_IMM_FIRST(memw), DR(TMP_REG2)));
- FAIL_IF(push_inst(compiler, data_transfer_insts[BYTE_DATA | LOAD_DATA] | S(mem) | T(reg) | MEM16_IMM_SECOND(memw), DR(reg)));
- FAIL_IF(push_inst(compiler, SLL_W | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(8), DR(TMP_REG2)));
- return push_inst(compiler, OR | S(reg) | T(TMP_REG2) | D(reg), DR(reg));
-
- case SLJIT_MOV:
- case SLJIT_MOV_P:
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- if (type & SLJIT_MEM_UNALIGNED_32) {
- flags = WORD_DATA;
- if (!(type & SLJIT_MEM_STORE))
- flags |= LOAD_DATA;
-
- return emit_op_mem(compiler, flags, DR(reg), mem, memw);
- }
-#else /* !SLJIT_CONFIG_MIPS_32 */
- FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - 7));
- SLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2);
-
- if (type & SLJIT_MEM_STORE) {
- FAIL_IF(push_inst(compiler, SDL | S(mem) | T(reg) | IMM(memw), MOVABLE_INS));
- return push_inst(compiler, SDR | S(mem) | T(reg) | IMM(memw + 7), MOVABLE_INS);
- }
-
- if (mem == reg) {
- FAIL_IF(push_inst(compiler, ADDU_W | S(mem) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
- mem = TMP_REG1;
- }
-
- FAIL_IF(push_inst(compiler, LDL | S(mem) | T(reg) | IMM(memw), DR(reg)));
- return push_inst(compiler, LDR | S(mem) | T(reg) | IMM(memw + 7), DR(reg));
-#endif /* SLJIT_CONFIG_MIPS_32 */
- }
-
- FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - 3));
- SLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2);
-
- if (type & SLJIT_MEM_STORE) {
- FAIL_IF(push_inst(compiler, SWL | S(mem) | T(reg) | IMM(memw), MOVABLE_INS));
- return push_inst(compiler, SWR | S(mem) | T(reg) | IMM(memw + 3), MOVABLE_INS);
- }
-
- if (mem == reg) {
- FAIL_IF(push_inst(compiler, ADDU_W | S(mem) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
- mem = TMP_REG1;
- }
-
- FAIL_IF(push_inst(compiler, LWL | S(mem) | T(reg) | IMM(memw), DR(reg)));
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- return push_inst(compiler, LWR | S(mem) | T(reg) | IMM(memw + 3), DR(reg));
-#else /* !SLJIT_CONFIG_MIPS_32 */
- FAIL_IF(push_inst(compiler, LWR | S(mem) | T(reg) | IMM(memw + 3), DR(reg)));
-
- if (op != SLJIT_MOV_U32)
- return SLJIT_SUCCESS;
-
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
- return push_inst(compiler, DINSU | T(reg) | SA(0) | (31 << 11) | (0 << 11), DR(reg));
-#else /* SLJIT_MIPS_REV < 1 */
- FAIL_IF(push_inst(compiler, DSLL32 | T(reg) | D(reg) | SH_IMM(0), DR(reg)));
- return push_inst(compiler, DSRL32 | T(reg) | D(reg) | SH_IMM(0), DR(reg));
-#endif /* SLJIT_MIPS_REV >= 2 */
-#endif /* SLJIT_CONFIG_MIPS_32 */
-#endif /* SLJIT_MIPS_REV >= 6 */
-}
-
-#if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 freg,
- sljit_s32 mem, sljit_sw memw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
-
- FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - (type & SLJIT_32) ? 3 : 7));
- SLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2);
-
- if (type & SLJIT_MEM_STORE) {
- if (type & SLJIT_32) {
- FAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | FS(freg), DR(TMP_REG2)));
-#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
- FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
-#endif
- FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM(memw), MOVABLE_INS));
- return push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM(memw + 3), MOVABLE_INS);
- }
-
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- FAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | MEMF64_FS_FIRST(freg), DR(TMP_REG2)));
-#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
- FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
-#endif
- FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM(memw), MOVABLE_INS));
- FAIL_IF(push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM(memw + 3), MOVABLE_INS));
-
- FAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | MEMF64_FS_SECOND(freg), DR(TMP_REG2)));
-#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
- FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
-#endif
- FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM(memw + 4), MOVABLE_INS));
- return push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM(memw + 7), MOVABLE_INS);
-#else /* !SLJIT_CONFIG_MIPS_32 */
- FAIL_IF(push_inst(compiler, MFC1 | (1 << 21) | T(TMP_REG2) | FS(freg), DR(TMP_REG2)));
-#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
- FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
-#endif
- FAIL_IF(push_inst(compiler, SDL | S(mem) | T(TMP_REG2) | IMM(memw), MOVABLE_INS));
- return push_inst(compiler, SDR | S(mem) | T(TMP_REG2) | IMM(memw + 7), MOVABLE_INS);
-#endif /* SLJIT_CONFIG_MIPS_32 */
- }
-
- if (type & SLJIT_32) {
- FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM(memw), DR(TMP_REG2)));
- FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM(memw + 3), DR(TMP_REG2)));
-
- FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | FS(freg), MOVABLE_INS));
-#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
- FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
-#endif
- return SLJIT_SUCCESS;
- }
-
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM(memw), DR(TMP_REG2)));
- FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM(memw + 3), DR(TMP_REG2)));
- FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | MEMF64_FS_FIRST(freg), MOVABLE_INS));
-
- FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM(memw + 4), DR(TMP_REG2)));
- FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM(memw + 7), DR(TMP_REG2)));
- FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | MEMF64_FS_SECOND(freg), MOVABLE_INS));
-#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
- FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
-#endif
-#else /* !SLJIT_CONFIG_MIPS_32 */
- FAIL_IF(push_inst(compiler, LDL | S(mem) | T(TMP_REG2) | IMM(memw), DR(TMP_REG2)));
- FAIL_IF(push_inst(compiler, LDR | S(mem) | T(TMP_REG2) | IMM(memw + 7), DR(TMP_REG2)));
-
- FAIL_IF(push_inst(compiler, MTC1 | (1 << 21) | T(TMP_REG2) | FS(freg), MOVABLE_INS));
-#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3)
- FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
-#endif
-#endif /* SLJIT_CONFIG_MIPS_32 */
- return SLJIT_SUCCESS;
-}
-
-#endif /* !SLJIT_MIPS_REV || SLJIT_MIPS_REV < 6 */
-
-#undef MEM16_IMM_FIRST
-#undef MEM16_IMM_SECOND
-#undef MEMF64_FS_FIRST
-#undef MEMF64_FS_SECOND
-#undef MEM_CHECK_UNALIGNED
-
-#undef TO_ARGW_HI
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
-{
- struct sljit_const *const_;
- sljit_s32 dst_r;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
- PTR_FAIL_IF(!const_);
- set_const(const_, compiler);
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
- PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));
-
- if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, DR(TMP_REG2), dst, dstw));
-
- return const_;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
-{
- struct sljit_put_label *put_label;
- sljit_s32 dst_r;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
- PTR_FAIL_IF(!put_label);
- set_put_label(put_label, compiler, 0);
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
- PTR_FAIL_IF(push_inst(compiler, (sljit_ins)dst_r, UNMOVABLE_INS));
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- compiler->size += 1;
-#else
- compiler->size += 5;
-#endif
-
- if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, DR(TMP_REG2), dst, dstw));
-
- return put_label;
-}
diff --git a/contrib/libs/pcre2/src/sljit/sljitNativePPC_32.c b/contrib/libs/pcre2/src/sljit/sljitNativePPC_32.c
deleted file mode 100644
index 9449e4b9d7..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitNativePPC_32.c
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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.
- */
-
-/* ppc 32-bit arch dependent functions. */
-
-static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)
-{
- if (imm <= SIMM_MAX && imm >= SIMM_MIN)
- return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm));
-
- if (!(imm & ~0xffff))
- return push_inst(compiler, ORI | S(TMP_ZERO) | A(reg) | IMM(imm));
-
- FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16)));
- return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS;
-}
-
-/* Simplified mnemonics: clrlwi. */
-#define INS_CLEAR_LEFT(dst, src, from) \
- (RLWINM | S(src) | A(dst) | RLWI_MBE(from, 31))
-
-static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
- sljit_s32 dst, sljit_s32 src1, sljit_s32 src2)
-{
- sljit_u32 imm;
-
- switch (op) {
- case SLJIT_MOV:
- case SLJIT_MOV_U32:
- case SLJIT_MOV_S32:
- case SLJIT_MOV_P:
- SLJIT_ASSERT(src1 == TMP_REG1);
- if (dst != src2)
- return push_inst(compiler, OR | S(src2) | A(dst) | B(src2));
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_U8:
- case SLJIT_MOV_S8:
- SLJIT_ASSERT(src1 == TMP_REG1);
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
- if (op == SLJIT_MOV_S8)
- return push_inst(compiler, EXTSB | S(src2) | A(dst));
- return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24));
- }
- else if ((flags & REG_DEST) && op == SLJIT_MOV_S8)
- return push_inst(compiler, EXTSB | S(src2) | A(dst));
- else {
- SLJIT_ASSERT(dst == src2);
- }
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_U16:
- case SLJIT_MOV_S16:
- SLJIT_ASSERT(src1 == TMP_REG1);
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
- if (op == SLJIT_MOV_S16)
- return push_inst(compiler, EXTSH | S(src2) | A(dst));
- return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16));
- }
- else {
- SLJIT_ASSERT(dst == src2);
- }
- return SLJIT_SUCCESS;
-
- case SLJIT_NOT:
- SLJIT_ASSERT(src1 == TMP_REG1);
- return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));
-
- case SLJIT_CLZ:
- SLJIT_ASSERT(src1 == TMP_REG1);
- return push_inst(compiler, CNTLZW | S(src2) | A(dst));
-
- case SLJIT_CTZ:
- SLJIT_ASSERT(src1 == TMP_REG1);
- FAIL_IF(push_inst(compiler, NEG | D(TMP_REG1) | A(src2)));
- FAIL_IF(push_inst(compiler, AND | S(src2) | A(dst) | B(TMP_REG1)));
- FAIL_IF(push_inst(compiler, CNTLZW | S(dst) | A(dst)));
- FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG1) | A(dst) | IMM(-32)));
- /* The highest bits are set, if dst < 32, zero otherwise. */
- FAIL_IF(push_inst(compiler, SRWI(27) | S(TMP_REG1) | A(TMP_REG1)));
- return push_inst(compiler, XOR | S(dst) | A(dst) | B(TMP_REG1));
-
- case SLJIT_ADD:
- if (flags & ALT_FORM1) {
- /* Setting XER SO is not enough, CR SO is also needed. */
- return push_inst(compiler, ADD | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));
- }
-
- if (flags & ALT_FORM2) {
- /* Flags does not set: BIN_IMM_EXTS unnecessary. */
- SLJIT_ASSERT(src2 == TMP_REG2);
-
- if (flags & ALT_FORM3)
- return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm);
-
- imm = compiler->imm;
-
- if (flags & ALT_FORM4) {
- FAIL_IF(push_inst(compiler, ADDIS | D(dst) | A(src1) | (((imm >> 16) & 0xffff) + ((imm >> 15) & 0x1))));
- src1 = dst;
- }
-
- return push_inst(compiler, ADDI | D(dst) | A(src1) | (imm & 0xffff));
- }
- if (flags & ALT_FORM3) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm);
- }
- SLJIT_ASSERT(!(flags & ALT_FORM4));
- if (!(flags & ALT_SET_FLAGS))
- return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2));
- if (flags & ALT_FORM5)
- return push_inst(compiler, ADDC | RC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));
- return push_inst(compiler, ADD | RC(flags) | D(dst) | A(src1) | B(src2));
-
- case SLJIT_ADDC:
- return push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2));
-
- case SLJIT_SUB:
- if (flags & ALT_FORM1) {
- if (flags & ALT_FORM2) {
- FAIL_IF(push_inst(compiler, CMPLI | CRD(0) | A(src1) | compiler->imm));
- if (!(flags & ALT_FORM3))
- return SLJIT_SUCCESS;
- return push_inst(compiler, ADDI | D(dst) | A(src1) | (-compiler->imm & 0xffff));
- }
- FAIL_IF(push_inst(compiler, CMPL | CRD(0) | A(src1) | B(src2)));
- if (!(flags & ALT_FORM3))
- return SLJIT_SUCCESS;
- return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
- }
-
- if (flags & ALT_FORM2) {
- if (flags & ALT_FORM3) {
- FAIL_IF(push_inst(compiler, CMPI | CRD(0) | A(src1) | compiler->imm));
- if (!(flags & ALT_FORM4))
- return SLJIT_SUCCESS;
- return push_inst(compiler, ADDI | D(dst) | A(src1) | (-compiler->imm & 0xffff));
- }
- FAIL_IF(push_inst(compiler, CMP | CRD(0) | A(src1) | B(src2)));
- if (!(flags & ALT_FORM4))
- return SLJIT_SUCCESS;
- return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
- }
-
- if (flags & ALT_FORM3) {
- /* Setting XER SO is not enough, CR SO is also needed. */
- if (src1 != TMP_ZERO)
- return push_inst(compiler, SUBF | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
- return push_inst(compiler, NEG | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src2));
- }
-
- if (flags & ALT_FORM4) {
- /* Flags does not set: BIN_IMM_EXTS unnecessary. */
- SLJIT_ASSERT(src2 == TMP_REG2);
- return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm);
- }
-
- if (!(flags & ALT_SET_FLAGS)) {
- SLJIT_ASSERT(src1 != TMP_ZERO);
- return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
- }
-
- if (flags & ALT_FORM5)
- return push_inst(compiler, SUBFC | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
-
- if (src1 != TMP_ZERO)
- return push_inst(compiler, SUBF | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
- return push_inst(compiler, NEG | RC(ALT_SET_FLAGS) | D(dst) | A(src2));
-
- case SLJIT_SUBC:
- return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1));
-
- case SLJIT_MUL:
- if (flags & ALT_FORM1) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm);
- }
- return push_inst(compiler, MULLW | OE(flags) | RC(flags) | D(dst) | A(src2) | B(src1));
-
- case SLJIT_AND:
- if (flags & ALT_FORM1) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- return push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm);
- }
- if (flags & ALT_FORM2) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- return push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm);
- }
- return push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2));
-
- case SLJIT_OR:
- if (flags & ALT_FORM1) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- return push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm);
- }
- if (flags & ALT_FORM2) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- return push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm);
- }
- if (flags & ALT_FORM3) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- imm = compiler->imm;
-
- FAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(imm)));
- return push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(imm >> 16));
- }
- return push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2));
-
- case SLJIT_XOR:
- if (flags & ALT_FORM1) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- return push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm);
- }
- if (flags & ALT_FORM2) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- return push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm);
- }
- if (flags & ALT_FORM3) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- imm = compiler->imm;
-
- FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(imm)));
- return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(imm >> 16));
- }
- return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2));
-
- case SLJIT_SHL:
- case SLJIT_MSHL:
- if (flags & ALT_FORM1) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- imm = compiler->imm & 0x1f;
- return push_inst(compiler, SLWI(imm) | RC(flags) | S(src1) | A(dst));
- }
-
- if (op == SLJIT_MSHL) {
- FAIL_IF(push_inst(compiler, ANDI | S(src2) | A(TMP_REG2) | 0x1f));
- src2 = TMP_REG2;
- }
-
- return push_inst(compiler, SLW | RC(flags) | S(src1) | A(dst) | B(src2));
-
- case SLJIT_LSHR:
- case SLJIT_MLSHR:
- if (flags & ALT_FORM1) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- imm = compiler->imm & 0x1f;
- /* Since imm can be 0, SRWI() cannot be used. */
- return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | RLWI_SH((32 - imm) & 0x1f) | RLWI_MBE(imm, 31));
- }
-
- if (op == SLJIT_MLSHR) {
- FAIL_IF(push_inst(compiler, ANDI | S(src2) | A(TMP_REG2) | 0x1f));
- src2 = TMP_REG2;
- }
-
- return push_inst(compiler, SRW | RC(flags) | S(src1) | A(dst) | B(src2));
-
- case SLJIT_ASHR:
- case SLJIT_MASHR:
- if (flags & ALT_FORM1) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- imm = compiler->imm & 0x1f;
- return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (imm << 11));
- }
-
- if (op == SLJIT_MASHR) {
- FAIL_IF(push_inst(compiler, ANDI | S(src2) | A(TMP_REG2) | 0x1f));
- src2 = TMP_REG2;
- }
-
- return push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2));
-
- case SLJIT_ROTL:
- case SLJIT_ROTR:
- if (flags & ALT_FORM1) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- imm = compiler->imm;
-
- if (op == SLJIT_ROTR)
- imm = (sljit_u32)(-(sljit_s32)imm);
-
- imm &= 0x1f;
- return push_inst(compiler, RLWINM | S(src1) | A(dst) | RLWI_SH(imm) | RLWI_MBE(0, 31));
- }
-
- if (op == SLJIT_ROTR) {
- FAIL_IF(push_inst(compiler, SUBFIC | D(TMP_REG2) | A(src2) | 0));
- src2 = TMP_REG2;
- }
-
- return push_inst(compiler, RLWNM | S(src1) | A(dst) | B(src2) | RLWI_MBE(0, 31));
- }
-
- SLJIT_UNREACHABLE();
- return SLJIT_SUCCESS;
-}
-
-static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw init_value)
-{
- FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 16)));
- return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
-{
- sljit_ins *inst = (sljit_ins *)addr;
- SLJIT_UNUSED_ARG(executable_offset);
-
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
- SLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDIS && (inst[1] & 0xfc000000) == ORI);
- inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);
- inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
- inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 2);
-}
diff --git a/contrib/libs/pcre2/src/sljit/sljitNativePPC_64.c b/contrib/libs/pcre2/src/sljit/sljitNativePPC_64.c
deleted file mode 100644
index 80549108bf..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitNativePPC_64.c
+++ /dev/null
@@ -1,579 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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.
- */
-
-/* ppc 64-bit arch dependent functions. */
-
-#if defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM)
-#define ASM_SLJIT_CLZ(src, dst) \
- __asm__ volatile ( "cntlzd %0, %1" : "=r"(dst) : "r"(src) )
-#elif defined(__xlc__)
-#error "Please enable GCC syntax for inline assembly statements"
-#else
-#error "Must implement count leading zeroes"
-#endif
-
-/* Computes SLDI(63 - shift). */
-#define PUSH_SLDI_NEG(reg, shift) \
- push_inst(compiler, RLDICR | S(reg) | A(reg) | RLDI_SH(63 - shift) | RLDI_ME(shift))
-
-static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)
-{
- sljit_uw tmp;
- sljit_uw shift;
- sljit_uw tmp2;
- sljit_uw shift2;
-
- if (imm <= SIMM_MAX && imm >= SIMM_MIN)
- return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm));
-
- if (!(imm & ~0xffff))
- return push_inst(compiler, ORI | S(TMP_ZERO) | A(reg) | IMM(imm));
-
- if (imm <= 0x7fffffffl && imm >= -0x80000000l) {
- FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16)));
- return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS;
- }
-
- /* Count leading zeroes. */
- tmp = (sljit_uw)((imm >= 0) ? imm : ~imm);
- ASM_SLJIT_CLZ(tmp, shift);
- SLJIT_ASSERT(shift > 0);
- shift--;
- tmp = ((sljit_uw)imm << shift);
-
- if ((tmp & ~0xffff000000000000ul) == 0) {
- FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | (sljit_ins)(tmp >> 48)));
- shift += 15;
- return PUSH_SLDI_NEG(reg, shift);
- }
-
- if ((tmp & ~0xffffffff00000000ul) == 0) {
- FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | (sljit_ins)(tmp >> 48)));
- FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp >> 32)));
- shift += 31;
- return PUSH_SLDI_NEG(reg, shift);
- }
-
- /* Cut out the 16 bit from immediate. */
- shift += 15;
- tmp2 = (sljit_uw)imm & (((sljit_uw)1 << (63 - shift)) - 1);
-
- if (tmp2 <= 0xffff) {
- FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | (sljit_ins)(tmp >> 48)));
- FAIL_IF(PUSH_SLDI_NEG(reg, shift));
- return push_inst(compiler, ORI | S(reg) | A(reg) | (sljit_ins)tmp2);
- }
-
- if (tmp2 <= 0xffffffff) {
- FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));
- FAIL_IF(PUSH_SLDI_NEG(reg, shift));
- FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | (sljit_ins)(tmp2 >> 16)));
- return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp2)) : SLJIT_SUCCESS;
- }
-
- ASM_SLJIT_CLZ(tmp2, shift2);
- tmp2 <<= shift2;
-
- if ((tmp2 & ~0xffff000000000000ul) == 0) {
- FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | (sljit_ins)(tmp >> 48)));
- shift2 += 15;
- shift += (63 - shift2);
- FAIL_IF(PUSH_SLDI_NEG(reg, shift));
- FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | (sljit_ins)(tmp2 >> 48)));
- return PUSH_SLDI_NEG(reg, shift2);
- }
-
- /* The general version. */
- FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | (sljit_ins)((sljit_uw)imm >> 48)));
- FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm >> 32)));
- FAIL_IF(PUSH_SLDI_NEG(reg, 31));
- FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(imm >> 16)));
- return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm));
-}
-
-#undef PUSH_SLDI_NEG
-
-#define CLRLDI(dst, src, n) \
- (RLDICL | S(src) | A(dst) | RLDI_SH(0) | RLDI_MB(n))
-
-/* Sign extension for integer operations. */
-#define UN_EXTS() \
- if ((flags & (ALT_SIGN_EXT | REG2_SOURCE)) == (ALT_SIGN_EXT | REG2_SOURCE)) { \
- FAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \
- src2 = TMP_REG2; \
- }
-
-#define BIN_EXTS() \
- if (flags & ALT_SIGN_EXT) { \
- if (flags & REG1_SOURCE) { \
- FAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \
- src1 = TMP_REG1; \
- } \
- if (flags & REG2_SOURCE) { \
- FAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \
- src2 = TMP_REG2; \
- } \
- }
-
-#define BIN_IMM_EXTS() \
- if ((flags & (ALT_SIGN_EXT | REG1_SOURCE)) == (ALT_SIGN_EXT | REG1_SOURCE)) { \
- FAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \
- src1 = TMP_REG1; \
- }
-
-static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
- sljit_s32 dst, sljit_s32 src1, sljit_s32 src2)
-{
- sljit_u32 imm;
-
- switch (op) {
- case SLJIT_MOV:
- case SLJIT_MOV_P:
- SLJIT_ASSERT(src1 == TMP_REG1);
- if (dst != src2)
- return push_inst(compiler, OR | S(src2) | A(dst) | B(src2));
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_U32:
- case SLJIT_MOV_S32:
- SLJIT_ASSERT(src1 == TMP_REG1);
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
- if (op == SLJIT_MOV_S32)
- return push_inst(compiler, EXTSW | S(src2) | A(dst));
- return push_inst(compiler, CLRLDI(dst, src2, 32));
- }
- else {
- SLJIT_ASSERT(dst == src2);
- }
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_U8:
- case SLJIT_MOV_S8:
- SLJIT_ASSERT(src1 == TMP_REG1);
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
- if (op == SLJIT_MOV_S8)
- return push_inst(compiler, EXTSB | S(src2) | A(dst));
- return push_inst(compiler, CLRLDI(dst, src2, 56));
- }
- else if ((flags & REG_DEST) && op == SLJIT_MOV_S8)
- return push_inst(compiler, EXTSB | S(src2) | A(dst));
- else {
- SLJIT_ASSERT(dst == src2);
- }
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_U16:
- case SLJIT_MOV_S16:
- SLJIT_ASSERT(src1 == TMP_REG1);
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
- if (op == SLJIT_MOV_S16)
- return push_inst(compiler, EXTSH | S(src2) | A(dst));
- return push_inst(compiler, CLRLDI(dst, src2, 48));
- }
- else {
- SLJIT_ASSERT(dst == src2);
- }
- return SLJIT_SUCCESS;
-
- case SLJIT_NOT:
- SLJIT_ASSERT(src1 == TMP_REG1);
- UN_EXTS();
- return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));
-
- case SLJIT_CLZ:
- SLJIT_ASSERT(src1 == TMP_REG1);
- return push_inst(compiler, ((flags & ALT_FORM1) ? CNTLZW : CNTLZD) | S(src2) | A(dst));
-
- case SLJIT_CTZ:
- SLJIT_ASSERT(src1 == TMP_REG1);
- FAIL_IF(push_inst(compiler, NEG | D(TMP_REG1) | A(src2)));
- FAIL_IF(push_inst(compiler, AND | S(src2) | A(dst) | B(TMP_REG1)));
- FAIL_IF(push_inst(compiler, ((flags & ALT_FORM1) ? CNTLZW : CNTLZD) | S(dst) | A(dst)));
- FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG1) | A(dst) | IMM((flags & ALT_FORM1) ? -32 : -64)));
- /* The highest bits are set, if dst < bit width, zero otherwise. */
- FAIL_IF(push_inst(compiler, ((flags & ALT_FORM1) ? SRWI(27) : SRDI(58)) | S(TMP_REG1) | A(TMP_REG1)));
- return push_inst(compiler, XOR | S(dst) | A(dst) | B(TMP_REG1));
-
- case SLJIT_ADD:
- if (flags & ALT_FORM1) {
- if (flags & ALT_SIGN_EXT) {
- FAIL_IF(push_inst(compiler, SLDI(32) | S(src1) | A(TMP_REG1)));
- src1 = TMP_REG1;
- FAIL_IF(push_inst(compiler, SLDI(32) | S(src2) | A(TMP_REG2)));
- src2 = TMP_REG2;
- }
- /* Setting XER SO is not enough, CR SO is also needed. */
- FAIL_IF(push_inst(compiler, ADD | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2)));
- if (flags & ALT_SIGN_EXT)
- return push_inst(compiler, SRDI(32) | S(dst) | A(dst));
- return SLJIT_SUCCESS;
- }
-
- if (flags & ALT_FORM2) {
- /* Flags does not set: BIN_IMM_EXTS unnecessary. */
- SLJIT_ASSERT(src2 == TMP_REG2);
-
- if (flags & ALT_FORM3)
- return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm);
-
- imm = compiler->imm;
-
- if (flags & ALT_FORM4) {
- FAIL_IF(push_inst(compiler, ADDIS | D(dst) | A(src1) | (((imm >> 16) & 0xffff) + ((imm >> 15) & 0x1))));
- src1 = dst;
- }
-
- return push_inst(compiler, ADDI | D(dst) | A(src1) | (imm & 0xffff));
- }
- if (flags & ALT_FORM3) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- BIN_IMM_EXTS();
- return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm);
- }
- if (flags & ALT_FORM4) {
- if (flags & ALT_FORM5)
- FAIL_IF(push_inst(compiler, ADDI | D(dst) | A(src1) | compiler->imm));
- else
- FAIL_IF(push_inst(compiler, ADD | D(dst) | A(src1) | B(src2)));
- return push_inst(compiler, CMPI | A(dst) | 0);
- }
- if (!(flags & ALT_SET_FLAGS))
- return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2));
- BIN_EXTS();
- if (flags & ALT_FORM5)
- return push_inst(compiler, ADDC | RC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));
- return push_inst(compiler, ADD | RC(flags) | D(dst) | A(src1) | B(src2));
-
- case SLJIT_ADDC:
- BIN_EXTS();
- return push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2));
-
- case SLJIT_SUB:
- if (flags & ALT_FORM1) {
- if (flags & ALT_FORM2) {
- FAIL_IF(push_inst(compiler, CMPLI | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm));
- if (!(flags & ALT_FORM3))
- return SLJIT_SUCCESS;
- return push_inst(compiler, ADDI | D(dst) | A(src1) | (-compiler->imm & 0xffff));
- }
- FAIL_IF(push_inst(compiler, CMPL | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2)));
- if (!(flags & ALT_FORM3))
- return SLJIT_SUCCESS;
- return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
- }
-
- if (flags & ALT_FORM2) {
- if (flags & ALT_FORM3) {
- FAIL_IF(push_inst(compiler, CMPI | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm));
- if (!(flags & ALT_FORM4))
- return SLJIT_SUCCESS;
- return push_inst(compiler, ADDI | D(dst) | A(src1) | (-compiler->imm & 0xffff));
- }
- FAIL_IF(push_inst(compiler, CMP | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2)));
- if (!(flags & ALT_FORM4))
- return SLJIT_SUCCESS;
- return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
- }
-
- if (flags & ALT_FORM3) {
- if (flags & ALT_SIGN_EXT) {
- if (src1 != TMP_ZERO) {
- FAIL_IF(push_inst(compiler, SLDI(32) | S(src1) | A(TMP_REG1)));
- src1 = TMP_REG1;
- }
- if (src2 != TMP_ZERO) {
- FAIL_IF(push_inst(compiler, SLDI(32) | S(src2) | A(TMP_REG2)));
- src2 = TMP_REG2;
- }
- }
-
- /* Setting XER SO is not enough, CR SO is also needed. */
- if (src1 != TMP_ZERO)
- FAIL_IF(push_inst(compiler, SUBF | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1)));
- else
- FAIL_IF(push_inst(compiler, NEG | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src2)));
-
- if (flags & ALT_SIGN_EXT)
- return push_inst(compiler, SRDI(32) | S(dst) | A(dst));
- return SLJIT_SUCCESS;
- }
-
- if (flags & ALT_FORM4) {
- /* Flags does not set: BIN_IMM_EXTS unnecessary. */
- SLJIT_ASSERT(src2 == TMP_REG2);
- return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm);
- }
-
- if (!(flags & ALT_SET_FLAGS)) {
- SLJIT_ASSERT(src1 != TMP_ZERO);
- return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
- }
-
- BIN_EXTS();
- if (flags & ALT_FORM5)
- return push_inst(compiler, SUBFC | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
-
- if (src1 != TMP_ZERO)
- return push_inst(compiler, SUBF | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
- return push_inst(compiler, NEG | RC(ALT_SET_FLAGS) | D(dst) | A(src2));
-
- case SLJIT_SUBC:
- BIN_EXTS();
- return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1));
-
- case SLJIT_MUL:
- if (flags & ALT_FORM1) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm);
- }
- BIN_EXTS();
- if (flags & ALT_FORM2)
- return push_inst(compiler, MULLW | OE(flags) | RC(flags) | D(dst) | A(src2) | B(src1));
- return push_inst(compiler, MULLD | OE(flags) | RC(flags) | D(dst) | A(src2) | B(src1));
-
- case SLJIT_AND:
- if (flags & ALT_FORM1) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- return push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm);
- }
- if (flags & ALT_FORM2) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- return push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm);
- }
- return push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2));
-
- case SLJIT_OR:
- if (flags & ALT_FORM1) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- return push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm);
- }
- if (flags & ALT_FORM2) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- return push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm);
- }
- if (flags & ALT_FORM3) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- imm = compiler->imm;
-
- FAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(imm)));
- return push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(imm >> 16));
- }
- return push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2));
-
- case SLJIT_XOR:
- if (flags & ALT_FORM1) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- return push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm);
- }
- if (flags & ALT_FORM2) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- return push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm);
- }
- if (flags & ALT_FORM3) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- imm = compiler->imm;
-
- FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(imm)));
- return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(imm >> 16));
- }
- return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2));
-
- case SLJIT_SHL:
- case SLJIT_MSHL:
- if (flags & ALT_FORM1) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- imm = compiler->imm;
-
- if (flags & ALT_FORM2) {
- imm &= 0x1f;
- return push_inst(compiler, SLWI(imm) | RC(flags) | S(src1) | A(dst));
- }
-
- imm &= 0x3f;
- return push_inst(compiler, SLDI(imm) | RC(flags) | S(src1) | A(dst));
- }
-
- if (op == SLJIT_MSHL) {
- FAIL_IF(push_inst(compiler, ANDI | S(src2) | A(TMP_REG2) | ((flags & ALT_FORM2) ? 0x1f : 0x3f)));
- src2 = TMP_REG2;
- }
-
- return push_inst(compiler, ((flags & ALT_FORM2) ? SLW : SLD) | RC(flags) | S(src1) | A(dst) | B(src2));
-
- case SLJIT_LSHR:
- case SLJIT_MLSHR:
- if (flags & ALT_FORM1) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- imm = compiler->imm;
-
- if (flags & ALT_FORM2) {
- imm &= 0x1f;
- /* Since imm can be 0, SRWI() cannot be used. */
- return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | RLWI_SH((32 - imm) & 0x1f) | RLWI_MBE(imm, 31));
- }
-
- imm &= 0x3f;
- /* Since imm can be 0, SRDI() cannot be used. */
- return push_inst(compiler, RLDICL | RC(flags) | S(src1) | A(dst) | RLDI_SH((64 - imm) & 0x3f) | RLDI_MB(imm));
- }
-
- if (op == SLJIT_MLSHR) {
- FAIL_IF(push_inst(compiler, ANDI | S(src2) | A(TMP_REG2) | ((flags & ALT_FORM2) ? 0x1f : 0x3f)));
- src2 = TMP_REG2;
- }
-
- return push_inst(compiler, ((flags & ALT_FORM2) ? SRW : SRD) | RC(flags) | S(src1) | A(dst) | B(src2));
-
- case SLJIT_ASHR:
- case SLJIT_MASHR:
- if (flags & ALT_FORM1) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- imm = compiler->imm;
-
- if (flags & ALT_FORM2) {
- imm &= 0x1f;
- return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (imm << 11));
- }
-
- imm &= 0x3f;
- return push_inst(compiler, SRADI | RC(flags) | S(src1) | A(dst) | RLDI_SH(imm));
- }
-
- if (op == SLJIT_MASHR) {
- FAIL_IF(push_inst(compiler, ANDI | S(src2) | A(TMP_REG2) | ((flags & ALT_FORM2) ? 0x1f : 0x3f)));
- src2 = TMP_REG2;
- }
-
- return push_inst(compiler, ((flags & ALT_FORM2) ? SRAW : SRAD) | RC(flags) | S(src1) | A(dst) | B(src2));
-
- case SLJIT_ROTL:
- case SLJIT_ROTR:
- if (flags & ALT_FORM1) {
- SLJIT_ASSERT(src2 == TMP_REG2);
- imm = compiler->imm;
-
- if (op == SLJIT_ROTR)
- imm = (sljit_u32)(-(sljit_s32)imm);
-
- if (flags & ALT_FORM2) {
- imm &= 0x1f;
- return push_inst(compiler, RLWINM | S(src1) | A(dst) | RLWI_SH(imm) | RLWI_MBE(0, 31));
- }
-
- imm &= 0x3f;
- return push_inst(compiler, RLDICL | S(src1) | A(dst) | RLDI_SH(imm));
- }
-
- if (op == SLJIT_ROTR) {
- FAIL_IF(push_inst(compiler, SUBFIC | D(TMP_REG2) | A(src2) | 0));
- src2 = TMP_REG2;
- }
-
- return push_inst(compiler, ((flags & ALT_FORM2) ? (RLWNM | RLWI_MBE(0, 31)) : (RLDCL | RLDI_MB(0))) | S(src1) | A(dst) | B(src2));
- }
-
- SLJIT_UNREACHABLE();
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src)
-{
- sljit_s32 arg_count = 0;
- sljit_s32 word_arg_count = 0;
- sljit_s32 types = 0;
- sljit_s32 reg = 0;
-
- if (src)
- reg = *src & REG_MASK;
-
- arg_types >>= SLJIT_ARG_SHIFT;
-
- while (arg_types) {
- types = (types << SLJIT_ARG_SHIFT) | (arg_types & SLJIT_ARG_MASK);
-
- switch (arg_types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- case SLJIT_ARG_TYPE_F32:
- arg_count++;
- break;
- default:
- arg_count++;
- word_arg_count++;
-
- if (arg_count != word_arg_count && arg_count == reg) {
- FAIL_IF(push_inst(compiler, OR | S(reg) | A(TMP_CALL_REG) | B(reg)));
- *src = TMP_CALL_REG;
- }
- break;
- }
-
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- while (types) {
- switch (types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- case SLJIT_ARG_TYPE_F32:
- arg_count--;
- break;
- default:
- if (arg_count != word_arg_count)
- FAIL_IF(push_inst(compiler, OR | S(word_arg_count) | A(arg_count) | B(word_arg_count)));
-
- arg_count--;
- word_arg_count--;
- break;
- }
-
- types >>= SLJIT_ARG_SHIFT;
- }
-
- return SLJIT_SUCCESS;
-}
-
-static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw init_value)
-{
- FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 48)));
- FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value >> 32)));
- FAIL_IF(push_inst(compiler, SLDI(32) | S(reg) | A(reg)));
- FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(init_value >> 16)));
- return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
-{
- sljit_ins *inst = (sljit_ins*)addr;
- SLJIT_UNUSED_ARG(executable_offset);
-
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 0);
- inst[0] = (inst[0] & 0xffff0000u) | ((sljit_ins)(new_target >> 48) & 0xffff);
- inst[1] = (inst[1] & 0xffff0000u) | ((sljit_ins)(new_target >> 32) & 0xffff);
- inst[3] = (inst[3] & 0xffff0000u) | ((sljit_ins)(new_target >> 16) & 0xffff);
- inst[4] = (inst[4] & 0xffff0000u) | ((sljit_ins)new_target & 0xffff);
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 1);
- inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 5);
-}
diff --git a/contrib/libs/pcre2/src/sljit/sljitNativePPC_common.c b/contrib/libs/pcre2/src/sljit/sljitNativePPC_common.c
deleted file mode 100644
index 790faffe46..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitNativePPC_common.c
+++ /dev/null
@@ -1,2851 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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.
- */
-
-SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
-{
- return "PowerPC" SLJIT_CPUINFO;
-}
-
-/* Length of an instruction word.
- Both for ppc-32 and ppc-64. */
-typedef sljit_u32 sljit_ins;
-
-#if ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && (defined _AIX)) \
- || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
-#define SLJIT_PPC_STACK_FRAME_V2 1
-#endif
-
-#ifdef _AIX
-#error #include <sys/cache.h>
-#endif
-
-#if (defined _CALL_ELF && _CALL_ELF == 2)
-#define SLJIT_PASS_ENTRY_ADDR_TO_CALL 1
-#endif
-
-#if (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL)
-
-static void ppc_cache_flush(sljit_ins *from, sljit_ins *to)
-{
-#ifdef _AIX
- _sync_cache_range((caddr_t)from, (int)((size_t)to - (size_t)from));
-#elif defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM)
-# if defined(_ARCH_PWR) || defined(_ARCH_PWR2)
- /* Cache flush for POWER architecture. */
- while (from < to) {
- __asm__ volatile (
- "clf 0, %0\n"
- "dcs\n"
- : : "r"(from)
- );
- from++;
- }
- __asm__ volatile ( "ics" );
-# elif defined(_ARCH_COM) && !defined(_ARCH_PPC)
-# error "Cache flush is not implemented for PowerPC/POWER common mode."
-# else
- /* Cache flush for PowerPC architecture. */
- while (from < to) {
- __asm__ volatile (
- "dcbf 0, %0\n"
- "sync\n"
- "icbi 0, %0\n"
- : : "r"(from)
- );
- from++;
- }
- __asm__ volatile ( "isync" );
-# endif
-# ifdef __xlc__
-# warning "This file may fail to compile if -qfuncsect is used"
-# endif
-#elif defined(__xlc__)
-#error "Please enable GCC syntax for inline assembly statements with -qasm=gcc"
-#else
-#error "This platform requires a cache flush implementation."
-#endif /* _AIX */
-}
-
-#endif /* (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) */
-
-#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
-#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
-#define TMP_ZERO (SLJIT_NUMBER_OF_REGISTERS + 4)
-
-#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
-#define TMP_CALL_REG (SLJIT_NUMBER_OF_REGISTERS + 5)
-#else
-#define TMP_CALL_REG TMP_REG2
-#endif
-
-#define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
-#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
-
-static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = {
- 0, 3, 4, 5, 6, 7, 8, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 1, 9, 10, 31, 12
-};
-
-static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 0, 13
-};
-
-/* --------------------------------------------------------------------- */
-/* Instrucion forms */
-/* --------------------------------------------------------------------- */
-#define D(d) ((sljit_ins)reg_map[d] << 21)
-#define S(s) ((sljit_ins)reg_map[s] << 21)
-#define A(a) ((sljit_ins)reg_map[a] << 16)
-#define B(b) ((sljit_ins)reg_map[b] << 11)
-#define C(c) ((sljit_ins)reg_map[c] << 6)
-#define FD(fd) ((sljit_ins)freg_map[fd] << 21)
-#define FS(fs) ((sljit_ins)freg_map[fs] << 21)
-#define FA(fa) ((sljit_ins)freg_map[fa] << 16)
-#define FB(fb) ((sljit_ins)freg_map[fb] << 11)
-#define FC(fc) ((sljit_ins)freg_map[fc] << 6)
-#define IMM(imm) ((sljit_ins)(imm) & 0xffff)
-#define CRD(d) ((sljit_ins)(d) << 21)
-
-/* Instruction bit sections.
- OE and Rc flag (see ALT_SET_FLAGS). */
-#define OE(flags) ((flags) & ALT_SET_FLAGS)
-/* Rc flag (see ALT_SET_FLAGS). */
-#define RC(flags) (((flags) & ALT_SET_FLAGS) >> 10)
-#define HI(opcode) ((sljit_ins)(opcode) << 26)
-#define LO(opcode) ((sljit_ins)(opcode) << 1)
-
-#define ADD (HI(31) | LO(266))
-#define ADDC (HI(31) | LO(10))
-#define ADDE (HI(31) | LO(138))
-#define ADDI (HI(14))
-#define ADDIC (HI(13))
-#define ADDIS (HI(15))
-#define ADDME (HI(31) | LO(234))
-#define AND (HI(31) | LO(28))
-#define ANDI (HI(28))
-#define ANDIS (HI(29))
-#define Bx (HI(18))
-#define BCx (HI(16))
-#define BCCTR (HI(19) | LO(528) | (3 << 11))
-#define BLR (HI(19) | LO(16) | (0x14 << 21))
-#define CNTLZD (HI(31) | LO(58))
-#define CNTLZW (HI(31) | LO(26))
-#define CMP (HI(31) | LO(0))
-#define CMPI (HI(11))
-#define CMPL (HI(31) | LO(32))
-#define CMPLI (HI(10))
-#define CROR (HI(19) | LO(449))
-#define DCBT (HI(31) | LO(278))
-#define DIVD (HI(31) | LO(489))
-#define DIVDU (HI(31) | LO(457))
-#define DIVW (HI(31) | LO(491))
-#define DIVWU (HI(31) | LO(459))
-#define EXTSB (HI(31) | LO(954))
-#define EXTSH (HI(31) | LO(922))
-#define EXTSW (HI(31) | LO(986))
-#define FABS (HI(63) | LO(264))
-#define FADD (HI(63) | LO(21))
-#define FADDS (HI(59) | LO(21))
-#define FCFID (HI(63) | LO(846))
-#define FCMPU (HI(63) | LO(0))
-#define FCTIDZ (HI(63) | LO(815))
-#define FCTIWZ (HI(63) | LO(15))
-#define FDIV (HI(63) | LO(18))
-#define FDIVS (HI(59) | LO(18))
-#define FMR (HI(63) | LO(72))
-#define FMUL (HI(63) | LO(25))
-#define FMULS (HI(59) | LO(25))
-#define FNEG (HI(63) | LO(40))
-#define FRSP (HI(63) | LO(12))
-#define FSUB (HI(63) | LO(20))
-#define FSUBS (HI(59) | LO(20))
-#define LD (HI(58) | 0)
-#define LFD (HI(50))
-#define LWZ (HI(32))
-#define MFCR (HI(31) | LO(19))
-#define MFLR (HI(31) | LO(339) | 0x80000)
-#define MFXER (HI(31) | LO(339) | 0x10000)
-#define MTCTR (HI(31) | LO(467) | 0x90000)
-#define MTLR (HI(31) | LO(467) | 0x80000)
-#define MTXER (HI(31) | LO(467) | 0x10000)
-#define MULHD (HI(31) | LO(73))
-#define MULHDU (HI(31) | LO(9))
-#define MULHW (HI(31) | LO(75))
-#define MULHWU (HI(31) | LO(11))
-#define MULLD (HI(31) | LO(233))
-#define MULLI (HI(7))
-#define MULLW (HI(31) | LO(235))
-#define NEG (HI(31) | LO(104))
-#define NOP (HI(24))
-#define NOR (HI(31) | LO(124))
-#define OR (HI(31) | LO(444))
-#define ORI (HI(24))
-#define ORIS (HI(25))
-#define RLDCL (HI(30) | LO(8))
-#define RLDICL (HI(30) | LO(0 << 1))
-#define RLDICR (HI(30) | LO(1 << 1))
-#define RLDIMI (HI(30) | LO(3 << 1))
-#define RLWIMI (HI(20))
-#define RLWINM (HI(21))
-#define RLWNM (HI(23))
-#define SLD (HI(31) | LO(27))
-#define SLW (HI(31) | LO(24))
-#define SRAD (HI(31) | LO(794))
-#define SRADI (HI(31) | LO(413 << 1))
-#define SRAW (HI(31) | LO(792))
-#define SRAWI (HI(31) | LO(824))
-#define SRD (HI(31) | LO(539))
-#define SRW (HI(31) | LO(536))
-#define STD (HI(62) | 0)
-#define STDU (HI(62) | 1)
-#define STDUX (HI(31) | LO(181))
-#define STFD (HI(54))
-#define STFIWX (HI(31) | LO(983))
-#define STW (HI(36))
-#define STWU (HI(37))
-#define STWUX (HI(31) | LO(183))
-#define SUBF (HI(31) | LO(40))
-#define SUBFC (HI(31) | LO(8))
-#define SUBFE (HI(31) | LO(136))
-#define SUBFIC (HI(8))
-#define XOR (HI(31) | LO(316))
-#define XORI (HI(26))
-#define XORIS (HI(27))
-
-#define SIMM_MAX (0x7fff)
-#define SIMM_MIN (-0x8000)
-#define UIMM_MAX (0xffff)
-
-/* Shift helpers. */
-#define RLWI_SH(sh) ((sljit_ins)(sh) << 11)
-#define RLWI_MBE(mb, me) (((sljit_ins)(mb) << 6) | ((sljit_ins)(me) << 1))
-#define RLDI_SH(sh) ((((sljit_ins)(sh) & 0x1f) << 11) | (((sljit_ins)(sh) & 0x20) >> 4))
-#define RLDI_MB(mb) ((((sljit_ins)(mb) & 0x1f) << 6) | ((sljit_ins)(mb) & 0x20))
-#define RLDI_ME(me) RLDI_MB(me)
-
-#define SLWI(shift) (RLWINM | RLWI_SH(shift) | RLWI_MBE(0, 31 - (shift)))
-#define SLDI(shift) (RLDICR | RLDI_SH(shift) | RLDI_ME(63 - (shift)))
-/* shift > 0 */
-#define SRWI(shift) (RLWINM | RLWI_SH(32 - (shift)) | RLWI_MBE((shift), 31))
-#define SRDI(shift) (RLDICL | RLDI_SH(64 - (shift)) | RLDI_MB(shift))
-
-#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
-#define SLWI_W(shift) SLWI(shift)
-#else /* !SLJIT_CONFIG_PPC_32 */
-#define SLWI_W(shift) SLDI(shift)
-#endif /* SLJIT_CONFIG_PPC_32 */
-
-#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_uw addr, void* func)
-{
- sljit_uw* ptrs;
-
- if (func_ptr)
- *func_ptr = (void*)context;
-
- ptrs = (sljit_uw*)func;
- context->addr = addr ? addr : ptrs[0];
- context->r2 = ptrs[1];
- context->r11 = ptrs[2];
-}
-#endif
-
-static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)
-{
- sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
- FAIL_IF(!ptr);
- *ptr = ins;
- compiler->size++;
- return SLJIT_SUCCESS;
-}
-
-static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
-{
- sljit_sw diff;
- sljit_uw target_addr;
- sljit_uw extra_jump_flags;
-
-#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
- if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL))
- return 0;
-#else
- if (jump->flags & SLJIT_REWRITABLE_JUMP)
- return 0;
-#endif
-
- if (jump->flags & JUMP_ADDR)
- target_addr = jump->u.target;
- else {
- SLJIT_ASSERT(jump->flags & JUMP_LABEL);
- target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
- }
-
-#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- if (jump->flags & IS_CALL)
- goto keep_address;
-#endif
-
- diff = ((sljit_sw)target_addr - (sljit_sw)(code_ptr) - executable_offset) & ~0x3l;
-
- extra_jump_flags = 0;
- if (jump->flags & IS_COND) {
- if (diff <= 0x7fff && diff >= -0x8000) {
- jump->flags |= PATCH_B;
- return 1;
- }
- if (target_addr <= 0xffff) {
- jump->flags |= PATCH_B | PATCH_ABS_B;
- return 1;
- }
- extra_jump_flags = REMOVE_COND;
-
- diff -= SSIZE_OF(ins);
- }
-
- if (diff <= 0x01ffffff && diff >= -0x02000000) {
- jump->flags |= PATCH_B | extra_jump_flags;
- return 1;
- }
-
- if (target_addr <= 0x03ffffff) {
- jump->flags |= PATCH_B | PATCH_ABS_B | extra_jump_flags;
- return 1;
- }
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
-#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
-keep_address:
-#endif
- if (target_addr <= 0x7fffffff) {
- jump->flags |= PATCH_ABS32;
- return 1;
- }
-
- if (target_addr <= 0x7fffffffffffl) {
- jump->flags |= PATCH_ABS48;
- return 1;
- }
-#endif
-
- return 0;
-}
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
-
-static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label)
-{
- if (max_label < 0x100000000l) {
- put_label->flags = 0;
- return 1;
- }
-
- if (max_label < 0x1000000000000l) {
- put_label->flags = 1;
- return 3;
- }
-
- put_label->flags = 2;
- return 4;
-}
-
-static SLJIT_INLINE void put_label_set(struct sljit_put_label *put_label)
-{
- sljit_uw addr = put_label->label->addr;
- sljit_ins *inst = (sljit_ins *)put_label->addr;
- sljit_u32 reg = *inst;
-
- if (put_label->flags == 0) {
- SLJIT_ASSERT(addr < 0x100000000l);
- inst[0] = ORIS | S(TMP_ZERO) | A(reg) | IMM(addr >> 16);
- }
- else {
- if (put_label->flags == 1) {
- SLJIT_ASSERT(addr < 0x1000000000000l);
- inst[0] = ORI | S(TMP_ZERO) | A(reg) | IMM(addr >> 32);
- }
- else {
- inst[0] = ORIS | S(TMP_ZERO) | A(reg) | IMM(addr >> 48);
- inst[1] = ORI | S(reg) | A(reg) | IMM((addr >> 32) & 0xffff);
- inst++;
- }
-
- inst[1] = SLDI(32) | S(reg) | A(reg);
- inst[2] = ORIS | S(reg) | A(reg) | IMM((addr >> 16) & 0xffff);
- inst += 2;
- }
-
- inst[1] = ORI | S(reg) | A(reg) | IMM(addr & 0xffff);
-}
-
-#endif /* SLJIT_CONFIG_PPC_64 */
-
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
-{
- struct sljit_memory_fragment *buf;
- sljit_ins *code;
- sljit_ins *code_ptr;
- sljit_ins *buf_ptr;
- sljit_ins *buf_end;
- sljit_uw word_count;
- sljit_uw next_addr;
- sljit_sw executable_offset;
- sljit_uw addr;
-
- struct sljit_label *label;
- struct sljit_jump *jump;
- struct sljit_const *const_;
- struct sljit_put_label *put_label;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_generate_code(compiler));
- reverse_buf(compiler);
-
-#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- compiler->size += (compiler->size & 0x1) + (sizeof(struct sljit_function_context) / sizeof(sljit_ins));
-#else
- compiler->size += (sizeof(struct sljit_function_context) / sizeof(sljit_ins));
-#endif
-#endif
- code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
- PTR_FAIL_WITH_EXEC_IF(code);
- buf = compiler->buf;
-
- code_ptr = code;
- word_count = 0;
- next_addr = 0;
- executable_offset = SLJIT_EXEC_OFFSET(code);
-
- label = compiler->labels;
- jump = compiler->jumps;
- const_ = compiler->consts;
- put_label = compiler->put_labels;
-
- do {
- buf_ptr = (sljit_ins*)buf->memory;
- buf_end = buf_ptr + (buf->used_size >> 2);
- do {
- *code_ptr = *buf_ptr++;
- if (next_addr == word_count) {
- SLJIT_ASSERT(!label || label->size >= word_count);
- SLJIT_ASSERT(!jump || jump->addr >= word_count);
- SLJIT_ASSERT(!const_ || const_->addr >= word_count);
- SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
-
- /* These structures are ordered by their address. */
- if (label && label->size == word_count) {
- /* Just recording the address. */
- label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
- label->size = (sljit_uw)(code_ptr - code);
- label = label->next;
- }
- if (jump && jump->addr == word_count) {
-#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
- jump->addr = (sljit_uw)(code_ptr - 3);
-#else
- jump->addr = (sljit_uw)(code_ptr - 6);
-#endif
- if (detect_jump_type(jump, code_ptr, code, executable_offset)) {
-#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
- code_ptr[-3] = code_ptr[0];
- code_ptr -= 3;
-#else
- if (jump->flags & PATCH_ABS32) {
- code_ptr -= 3;
- code_ptr[-1] = code_ptr[2];
- code_ptr[0] = code_ptr[3];
- }
- else if (jump->flags & PATCH_ABS48) {
- code_ptr--;
- code_ptr[-1] = code_ptr[0];
- code_ptr[0] = code_ptr[1];
- /* rldicr rX,rX,32,31 -> rX,rX,16,47 */
- SLJIT_ASSERT((code_ptr[-3] & 0xfc00ffff) == 0x780007c6);
- code_ptr[-3] ^= 0x8422;
- /* oris -> ori */
- code_ptr[-2] ^= 0x4000000;
- }
- else {
- code_ptr[-6] = code_ptr[0];
- code_ptr -= 6;
- }
-#endif
- if (jump->flags & REMOVE_COND) {
- code_ptr[0] = BCx | (2 << 2) | ((code_ptr[0] ^ (8 << 21)) & 0x03ff0001);
- code_ptr++;
- jump->addr += sizeof(sljit_ins);
- code_ptr[0] = Bx;
- jump->flags -= IS_COND;
- }
- }
- jump = jump->next;
- }
- if (const_ && const_->addr == word_count) {
- const_->addr = (sljit_uw)code_ptr;
- const_ = const_->next;
- }
- if (put_label && put_label->addr == word_count) {
- SLJIT_ASSERT(put_label->label);
- put_label->addr = (sljit_uw)code_ptr;
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- code_ptr += put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));
- word_count += 4;
-#endif
- put_label = put_label->next;
- }
- next_addr = compute_next_addr(label, jump, const_, put_label);
- }
- code_ptr++;
- word_count++;
- } while (buf_ptr < buf_end);
-
- buf = buf->next;
- } while (buf);
-
- if (label && label->size == word_count) {
- label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
- label->size = (sljit_uw)(code_ptr - code);
- label = label->next;
- }
-
- SLJIT_ASSERT(!label);
- SLJIT_ASSERT(!jump);
- SLJIT_ASSERT(!const_);
- SLJIT_ASSERT(!put_label);
-
-#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
- SLJIT_ASSERT(code_ptr - code <= (sljit_sw)(compiler->size - (sizeof(struct sljit_function_context) / sizeof(sljit_ins))));
-#else
- SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
-#endif
-
- jump = compiler->jumps;
- while (jump) {
- do {
- addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
- buf_ptr = (sljit_ins *)jump->addr;
-
- if (jump->flags & PATCH_B) {
- if (jump->flags & IS_COND) {
- if (!(jump->flags & PATCH_ABS_B)) {
- addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset);
- SLJIT_ASSERT((sljit_sw)addr <= 0x7fff && (sljit_sw)addr >= -0x8000);
- *buf_ptr = BCx | ((sljit_ins)addr & 0xfffc) | ((*buf_ptr) & 0x03ff0001);
- }
- else {
- SLJIT_ASSERT(addr <= 0xffff);
- *buf_ptr = BCx | ((sljit_ins)addr & 0xfffc) | 0x2 | ((*buf_ptr) & 0x03ff0001);
- }
- }
- else {
- if (!(jump->flags & PATCH_ABS_B)) {
- addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset);
- SLJIT_ASSERT((sljit_sw)addr <= 0x01ffffff && (sljit_sw)addr >= -0x02000000);
- *buf_ptr = Bx | ((sljit_ins)addr & 0x03fffffc) | ((*buf_ptr) & 0x1);
- }
- else {
- SLJIT_ASSERT(addr <= 0x03ffffff);
- *buf_ptr = Bx | ((sljit_ins)addr & 0x03fffffc) | 0x2 | ((*buf_ptr) & 0x1);
- }
- }
- break;
- }
-
- /* Set the fields of immediate loads. */
-#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
- SLJIT_ASSERT(((buf_ptr[0] | buf_ptr[1]) & 0xffff) == 0);
- buf_ptr[0] |= (sljit_ins)(addr >> 16) & 0xffff;
- buf_ptr[1] |= (sljit_ins)addr & 0xffff;
-#else
- if (jump->flags & PATCH_ABS32) {
- SLJIT_ASSERT(addr <= 0x7fffffff);
- SLJIT_ASSERT(((buf_ptr[0] | buf_ptr[1]) & 0xffff) == 0);
- buf_ptr[0] |= (sljit_ins)(addr >> 16) & 0xffff;
- buf_ptr[1] |= (sljit_ins)addr & 0xffff;
- break;
- }
-
- if (jump->flags & PATCH_ABS48) {
- SLJIT_ASSERT(addr <= 0x7fffffffffff);
- SLJIT_ASSERT(((buf_ptr[0] | buf_ptr[1] | buf_ptr[3]) & 0xffff) == 0);
- buf_ptr[0] |= (sljit_ins)(addr >> 32) & 0xffff;
- buf_ptr[1] |= (sljit_ins)(addr >> 16) & 0xffff;
- buf_ptr[3] |= (sljit_ins)addr & 0xffff;
- break;
- }
-
- SLJIT_ASSERT(((buf_ptr[0] | buf_ptr[1] | buf_ptr[3] | buf_ptr[4]) & 0xffff) == 0);
- buf_ptr[0] |= (sljit_ins)(addr >> 48) & 0xffff;
- buf_ptr[1] |= (sljit_ins)(addr >> 32) & 0xffff;
- buf_ptr[3] |= (sljit_ins)(addr >> 16) & 0xffff;
- buf_ptr[4] |= (sljit_ins)addr & 0xffff;
-#endif
- } while (0);
- jump = jump->next;
- }
-
- put_label = compiler->put_labels;
- while (put_label) {
-#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
- addr = put_label->label->addr;
- buf_ptr = (sljit_ins *)put_label->addr;
-
- SLJIT_ASSERT((buf_ptr[0] & 0xfc1f0000) == ADDIS && (buf_ptr[1] & 0xfc000000) == ORI);
- buf_ptr[0] |= (addr >> 16) & 0xffff;
- buf_ptr[1] |= addr & 0xffff;
-#else
- put_label_set(put_label);
-#endif
- put_label = put_label->next;
- }
-
- compiler->error = SLJIT_ERR_COMPILED;
- compiler->executable_offset = executable_offset;
- compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins);
-
- code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
-
-#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- if (((sljit_sw)code_ptr) & 0x4)
- code_ptr++;
-#endif
- sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_uw)code, (void*)sljit_generate_code);
-#endif
-
- code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
-
- SLJIT_CACHE_FLUSH(code, code_ptr);
- SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
-
-#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
- return code_ptr;
-#else
- return code;
-#endif
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
-{
- switch (feature_type) {
- case SLJIT_HAS_FPU:
-#ifdef SLJIT_IS_FPU_AVAILABLE
- return SLJIT_IS_FPU_AVAILABLE;
-#else
- /* Available by default. */
- return 1;
-#endif
-
- /* A saved register is set to a zero value. */
- case SLJIT_HAS_ZERO_REGISTER:
- case SLJIT_HAS_CLZ:
- case SLJIT_HAS_ROT:
- case SLJIT_HAS_PREFETCH:
- return 1;
-
- case SLJIT_HAS_CTZ:
- return 2;
-
- default:
- return 0;
- }
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)
-{
- return (type >= SLJIT_UNORDERED && type <= SLJIT_ORDERED_LESS_EQUAL);
-}
-
-/* --------------------------------------------------------------------- */
-/* Entry, exit */
-/* --------------------------------------------------------------------- */
-
-/* inp_flags: */
-
-/* Creates an index in data_transfer_insts array. */
-#define LOAD_DATA 0x01
-#define INDEXED 0x02
-#define SIGNED_DATA 0x04
-
-#define WORD_DATA 0x00
-#define BYTE_DATA 0x08
-#define HALF_DATA 0x10
-#define INT_DATA 0x18
-/* Separates integer and floating point registers */
-#define GPR_REG 0x1f
-#define DOUBLE_DATA 0x20
-
-#define MEM_MASK 0x7f
-
-/* Other inp_flags. */
-
-/* Integer opertion and set flags -> requires exts on 64 bit systems. */
-#define ALT_SIGN_EXT 0x000100
-/* This flag affects the RC() and OERC() macros. */
-#define ALT_SET_FLAGS 0x000400
-#define ALT_FORM1 0x001000
-#define ALT_FORM2 0x002000
-#define ALT_FORM3 0x004000
-#define ALT_FORM4 0x008000
-#define ALT_FORM5 0x010000
-
-/* Source and destination is register. */
-#define REG_DEST 0x000001
-#define REG1_SOURCE 0x000002
-#define REG2_SOURCE 0x000004
-/*
-ALT_SIGN_EXT 0x000100
-ALT_SET_FLAGS 0x000200
-ALT_FORM1 0x001000
-...
-ALT_FORM5 0x010000 */
-
-#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
-#include "sljitNativePPC_32.c"
-#else
-#include "sljitNativePPC_64.c"
-#endif
-
-#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
-#define STACK_STORE STW
-#define STACK_LOAD LWZ
-#else
-#define STACK_STORE STD
-#define STACK_LOAD LD
-#endif
-
-#if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)
-#define LR_SAVE_OFFSET 2 * SSIZE_OF(sw)
-#else
-#define LR_SAVE_OFFSET SSIZE_OF(sw)
-#endif
-
-#define STACK_MAX_DISTANCE (0x8000 - SSIZE_OF(sw) - LR_SAVE_OFFSET)
-
-static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg,
- sljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg);
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- sljit_s32 i, tmp, base, offset;
- sljit_s32 word_arg_count = 0;
- sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options);
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- sljit_s32 arg_count = 0;
-#endif
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
- set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
-
- local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 0)
- + GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
-
- if (!(options & SLJIT_ENTER_REG_ARG))
- local_size += SSIZE_OF(sw);
-
- local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;
- compiler->local_size = local_size;
-
- FAIL_IF(push_inst(compiler, MFLR | D(0)));
-
- base = SLJIT_SP;
- offset = local_size;
-
- if (local_size <= STACK_MAX_DISTANCE) {
-#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
- FAIL_IF(push_inst(compiler, STWU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size)));
-#else
- FAIL_IF(push_inst(compiler, STDU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size)));
-#endif
- } else {
- base = TMP_REG1;
- FAIL_IF(push_inst(compiler, OR | S(SLJIT_SP) | A(TMP_REG1) | B(SLJIT_SP)));
- FAIL_IF(load_immediate(compiler, TMP_REG2, -local_size));
-#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
- FAIL_IF(push_inst(compiler, STWUX | S(SLJIT_SP) | A(SLJIT_SP) | B(TMP_REG2)));
-#else
- FAIL_IF(push_inst(compiler, STDUX | S(SLJIT_SP) | A(SLJIT_SP) | B(TMP_REG2)));
-#endif
- local_size = 0;
- offset = 0;
- }
-
- tmp = SLJIT_FS0 - fsaveds;
- for (i = SLJIT_FS0; i > tmp; i--) {
- offset -= SSIZE_OF(f64);
- FAIL_IF(push_inst(compiler, STFD | FS(i) | A(base) | IMM(offset)));
- }
-
- for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
- offset -= SSIZE_OF(f64);
- FAIL_IF(push_inst(compiler, STFD | FS(i) | A(base) | IMM(offset)));
- }
-
- if (!(options & SLJIT_ENTER_REG_ARG)) {
- offset -= SSIZE_OF(sw);
- FAIL_IF(push_inst(compiler, STACK_STORE | S(TMP_ZERO) | A(base) | IMM(offset)));
- }
-
- tmp = SLJIT_S0 - saveds;
- for (i = SLJIT_S0 - saved_arg_count; i > tmp; i--) {
- offset -= SSIZE_OF(sw);
- FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(base) | IMM(offset)));
- }
-
- for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
- offset -= SSIZE_OF(sw);
- FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(base) | IMM(offset)));
- }
-
- FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(base) | IMM(local_size + LR_SAVE_OFFSET)));
-
- if (options & SLJIT_ENTER_REG_ARG)
- return SLJIT_SUCCESS;
-
- FAIL_IF(push_inst(compiler, ADDI | D(TMP_ZERO) | A(0) | 0));
-
- arg_types >>= SLJIT_ARG_SHIFT;
- saved_arg_count = 0;
-
- while (arg_types > 0) {
- if ((arg_types & SLJIT_ARG_MASK) < SLJIT_ARG_TYPE_F64) {
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- do {
- if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {
- tmp = SLJIT_S0 - saved_arg_count;
- saved_arg_count++;
- } else if (arg_count != word_arg_count)
- tmp = SLJIT_R0 + word_arg_count;
- else
- break;
-
- FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0 + arg_count) | A(tmp) | B(SLJIT_R0 + arg_count)));
- } while (0);
-#else
- if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {
- FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0 + word_arg_count) | A(SLJIT_S0 - saved_arg_count) | B(SLJIT_R0 + word_arg_count)));
- saved_arg_count++;
- }
-#endif
- word_arg_count++;
- }
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- arg_count++;
-#endif
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- CHECK_ERROR();
- CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
- set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
-
- local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 0)
- + GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
-
- if (!(options & SLJIT_ENTER_REG_ARG))
- local_size += SSIZE_OF(sw);
-
- compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 is_return_to)
-{
- sljit_s32 i, tmp, base, offset;
- sljit_s32 local_size = compiler->local_size;
-
- base = SLJIT_SP;
- if (local_size > STACK_MAX_DISTANCE) {
- base = TMP_REG1;
- if (local_size > 2 * STACK_MAX_DISTANCE + LR_SAVE_OFFSET) {
- FAIL_IF(push_inst(compiler, STACK_LOAD | D(base) | A(SLJIT_SP) | IMM(0)));
- local_size = 0;
- } else {
- FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG1) | A(SLJIT_SP) | IMM(local_size - STACK_MAX_DISTANCE)));
- local_size = STACK_MAX_DISTANCE;
- }
- }
-
- offset = local_size;
- if (!is_return_to)
- FAIL_IF(push_inst(compiler, STACK_LOAD | S(0) | A(base) | IMM(offset + LR_SAVE_OFFSET)));
-
- tmp = SLJIT_FS0 - compiler->fsaveds;
- for (i = SLJIT_FS0; i > tmp; i--) {
- offset -= SSIZE_OF(f64);
- FAIL_IF(push_inst(compiler, LFD | FS(i) | A(base) | IMM(offset)));
- }
-
- for (i = compiler->fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
- offset -= SSIZE_OF(f64);
- FAIL_IF(push_inst(compiler, LFD | FS(i) | A(base) | IMM(offset)));
- }
-
- if (!(compiler->options & SLJIT_ENTER_REG_ARG)) {
- offset -= SSIZE_OF(sw);
- FAIL_IF(push_inst(compiler, STACK_LOAD | S(TMP_ZERO) | A(base) | IMM(offset)));
- }
-
- tmp = SLJIT_S0 - compiler->saveds;
- for (i = SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options); i > tmp; i--) {
- offset -= SSIZE_OF(sw);
- FAIL_IF(push_inst(compiler, STACK_LOAD | S(i) | A(base) | IMM(offset)));
- }
-
- for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
- offset -= SSIZE_OF(sw);
- FAIL_IF(push_inst(compiler, STACK_LOAD | S(i) | A(base) | IMM(offset)));
- }
-
- if (!is_return_to)
- push_inst(compiler, MTLR | S(0));
-
- if (local_size > 0)
- return push_inst(compiler, ADDI | D(SLJIT_SP) | A(base) | IMM(local_size));
-
- SLJIT_ASSERT(base == TMP_REG1);
- return push_inst(compiler, OR | S(base) | A(SLJIT_SP) | B(base));
-}
-
-#undef STACK_STORE
-#undef STACK_LOAD
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_return_void(compiler));
-
- FAIL_IF(emit_stack_frame_release(compiler, 0));
- return push_inst(compiler, BLR);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,
- sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_return_to(compiler, src, srcw));
-
- if (src & SLJIT_MEM) {
- ADJUST_LOCAL_OFFSET(src, srcw);
- FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_CALL_REG, src, srcw, TMP_CALL_REG));
- src = TMP_CALL_REG;
- srcw = 0;
- } else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
- FAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src)));
- src = TMP_CALL_REG;
- srcw = 0;
- }
-
- FAIL_IF(emit_stack_frame_release(compiler, 1));
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);
-}
-
-/* --------------------------------------------------------------------- */
-/* Operators */
-/* --------------------------------------------------------------------- */
-
-/* s/l - store/load (1 bit)
- i/x - immediate/indexed form
- u/s - signed/unsigned (1 bit)
- w/b/h/i - word/byte/half/int allowed (2 bit)
-
- Some opcodes are repeated (e.g. store signed / unsigned byte is the same instruction). */
-
-/* 64 bit only: [reg+imm] must be aligned to 4 bytes. */
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
-#define INT_ALIGNED 0x10000
-#endif
-
-#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
-#define ARCH_32_64(a, b) a
-#define INST_CODE_AND_DST(inst, flags, reg) \
- ((sljit_ins)(inst) | (sljit_ins)(((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
-#else
-#define ARCH_32_64(a, b) b
-#define INST_CODE_AND_DST(inst, flags, reg) \
- (((sljit_ins)(inst) & ~(sljit_ins)INT_ALIGNED) | (sljit_ins)(((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
-#endif
-
-static const sljit_ins data_transfer_insts[64 + 16] = {
-
-/* -------- Integer -------- */
-
-/* Word. */
-
-/* w u i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */),
-/* w u i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */),
-/* w u x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
-/* w u x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
-
-/* w s i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */),
-/* w s i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */),
-/* w s x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
-/* w s x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
-
-/* Byte. */
-
-/* b u i s */ HI(38) /* stb */,
-/* b u i l */ HI(34) /* lbz */,
-/* b u x s */ HI(31) | LO(215) /* stbx */,
-/* b u x l */ HI(31) | LO(87) /* lbzx */,
-
-/* b s i s */ HI(38) /* stb */,
-/* b s i l */ HI(34) /* lbz */ /* EXTS_REQ */,
-/* b s x s */ HI(31) | LO(215) /* stbx */,
-/* b s x l */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */,
-
-/* Half. */
-
-/* h u i s */ HI(44) /* sth */,
-/* h u i l */ HI(40) /* lhz */,
-/* h u x s */ HI(31) | LO(407) /* sthx */,
-/* h u x l */ HI(31) | LO(279) /* lhzx */,
-
-/* h s i s */ HI(44) /* sth */,
-/* h s i l */ HI(42) /* lha */,
-/* h s x s */ HI(31) | LO(407) /* sthx */,
-/* h s x l */ HI(31) | LO(343) /* lhax */,
-
-/* Int. */
-
-/* i u i s */ HI(36) /* stw */,
-/* i u i l */ HI(32) /* lwz */,
-/* i u x s */ HI(31) | LO(151) /* stwx */,
-/* i u x l */ HI(31) | LO(23) /* lwzx */,
-
-/* i s i s */ HI(36) /* stw */,
-/* i s i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x2 /* lwa */),
-/* i s x s */ HI(31) | LO(151) /* stwx */,
-/* i s x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */),
-
-/* -------- Floating point -------- */
-
-/* d i s */ HI(54) /* stfd */,
-/* d i l */ HI(50) /* lfd */,
-/* d x s */ HI(31) | LO(727) /* stfdx */,
-/* d x l */ HI(31) | LO(599) /* lfdx */,
-
-/* s i s */ HI(52) /* stfs */,
-/* s i l */ HI(48) /* lfs */,
-/* s x s */ HI(31) | LO(663) /* stfsx */,
-/* s x l */ HI(31) | LO(535) /* lfsx */,
-};
-
-static const sljit_ins updated_data_transfer_insts[64] = {
-
-/* -------- Integer -------- */
-
-/* Word. */
-
-/* w u i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */),
-/* w u i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */),
-/* w u x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
-/* w u x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
-
-/* w s i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */),
-/* w s i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */),
-/* w s x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
-/* w s x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
-
-/* Byte. */
-
-/* b u i s */ HI(39) /* stbu */,
-/* b u i l */ HI(35) /* lbzu */,
-/* b u x s */ HI(31) | LO(247) /* stbux */,
-/* b u x l */ HI(31) | LO(119) /* lbzux */,
-
-/* b s i s */ HI(39) /* stbu */,
-/* b s i l */ 0 /* no such instruction */,
-/* b s x s */ HI(31) | LO(247) /* stbux */,
-/* b s x l */ 0 /* no such instruction */,
-
-/* Half. */
-
-/* h u i s */ HI(45) /* sthu */,
-/* h u i l */ HI(41) /* lhzu */,
-/* h u x s */ HI(31) | LO(439) /* sthux */,
-/* h u x l */ HI(31) | LO(311) /* lhzux */,
-
-/* h s i s */ HI(45) /* sthu */,
-/* h s i l */ HI(43) /* lhau */,
-/* h s x s */ HI(31) | LO(439) /* sthux */,
-/* h s x l */ HI(31) | LO(375) /* lhaux */,
-
-/* Int. */
-
-/* i u i s */ HI(37) /* stwu */,
-/* i u i l */ HI(33) /* lwzu */,
-/* i u x s */ HI(31) | LO(183) /* stwux */,
-/* i u x l */ HI(31) | LO(55) /* lwzux */,
-
-/* i s i s */ HI(37) /* stwu */,
-/* i s i l */ ARCH_32_64(HI(33) /* lwzu */, 0 /* no such instruction */),
-/* i s x s */ HI(31) | LO(183) /* stwux */,
-/* i s x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */),
-
-/* -------- Floating point -------- */
-
-/* d i s */ HI(55) /* stfdu */,
-/* d i l */ HI(51) /* lfdu */,
-/* d x s */ HI(31) | LO(759) /* stfdux */,
-/* d x l */ HI(31) | LO(631) /* lfdux */,
-
-/* s i s */ HI(53) /* stfsu */,
-/* s i l */ HI(49) /* lfsu */,
-/* s x s */ HI(31) | LO(695) /* stfsux */,
-/* s x l */ HI(31) | LO(567) /* lfsux */,
-};
-
-#undef ARCH_32_64
-
-/* Simple cases, (no caching is required). */
-static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg,
- sljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg)
-{
- sljit_ins inst;
- sljit_s32 offs_reg;
-
- /* Should work when (arg & REG_MASK) == 0. */
- SLJIT_ASSERT(A(0) == 0);
- SLJIT_ASSERT(arg & SLJIT_MEM);
-
- if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
- argw &= 0x3;
- offs_reg = OFFS_REG(arg);
-
- if (argw != 0) {
- FAIL_IF(push_inst(compiler, SLWI_W(argw) | S(OFFS_REG(arg)) | A(tmp_reg)));
- offs_reg = tmp_reg;
- }
-
- inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- SLJIT_ASSERT(!(inst & INT_ALIGNED));
-#endif /* SLJIT_CONFIG_PPC_64 */
-
- return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(offs_reg));
- }
-
- inst = data_transfer_insts[inp_flags & MEM_MASK];
- arg &= REG_MASK;
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- if ((inst & INT_ALIGNED) && (argw & 0x3) != 0) {
- FAIL_IF(load_immediate(compiler, tmp_reg, argw));
-
- inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
- return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg) | B(tmp_reg));
- }
-#endif /* SLJIT_CONFIG_PPC_64 */
-
- if (argw <= SIMM_MAX && argw >= SIMM_MIN)
- return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg) | IMM(argw));
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- if (argw <= 0x7fff7fffl && argw >= -0x80000000l) {
-#endif /* SLJIT_CONFIG_PPC_64 */
- FAIL_IF(push_inst(compiler, ADDIS | D(tmp_reg) | A(arg) | IMM((argw + 0x8000) >> 16)));
- return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_reg) | IMM(argw));
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- }
-
- FAIL_IF(load_immediate(compiler, tmp_reg, argw));
-
- inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
- return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg) | B(tmp_reg));
-#endif /* SLJIT_CONFIG_PPC_64 */
-}
-
-static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 input_flags,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- /* arg1 goes to TMP_REG1 or src reg
- arg2 goes to TMP_REG2, imm or src reg
- result goes to TMP_REG2, so put result can use TMP_REG1. */
- sljit_s32 dst_r = TMP_REG2;
- sljit_s32 src1_r;
- sljit_s32 src2_r;
- sljit_s32 sugg_src2_r = TMP_REG2;
- sljit_s32 flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_SIGN_EXT | ALT_SET_FLAGS);
-
- /* Destination check. */
- if (FAST_IS_REG(dst)) {
- dst_r = dst;
- /* The REG_DEST is only used by SLJIT_MOV operations, although
- * it is set for op2 operations with unset destination. */
- flags |= REG_DEST;
-
- if (op >= SLJIT_MOV && op <= SLJIT_MOV_P)
- sugg_src2_r = dst_r;
- }
-
- /* Source 1. */
- if (FAST_IS_REG(src1)) {
- src1_r = src1;
- flags |= REG1_SOURCE;
- }
- else if (src1 & SLJIT_IMM) {
- src1_r = TMP_ZERO;
- if (src1w != 0) {
- FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
- src1_r = TMP_REG1;
- }
- }
- else {
- FAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, TMP_REG1));
- src1_r = TMP_REG1;
- }
-
- /* Source 2. */
- if (FAST_IS_REG(src2)) {
- src2_r = src2;
- flags |= REG2_SOURCE;
-
- if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOV_P)
- dst_r = src2_r;
- }
- else if (src2 & SLJIT_IMM) {
- src2_r = TMP_ZERO;
- if (src2w != 0) {
- FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w));
- src2_r = sugg_src2_r;
- }
- }
- else {
- FAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, TMP_REG2));
- src2_r = sugg_src2_r;
- }
-
- FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
-
- if (!(dst & SLJIT_MEM))
- return SLJIT_SUCCESS;
-
- return emit_op_mem(compiler, input_flags, dst_r, dst, dstw, TMP_REG1);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
-{
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- sljit_s32 int_op = op & SLJIT_32;
-#endif
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op0(compiler, op));
-
- op = GET_OPCODE(op);
- switch (op) {
- case SLJIT_BREAKPOINT:
- case SLJIT_NOP:
- return push_inst(compiler, NOP);
- case SLJIT_LMUL_UW:
- case SLJIT_LMUL_SW:
- FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0)));
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
- return push_inst(compiler, (op == SLJIT_LMUL_UW ? MULHDU : MULHD) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1));
-#else
- FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
- return push_inst(compiler, (op == SLJIT_LMUL_UW ? MULHWU : MULHW) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1));
-#endif
- case SLJIT_DIVMOD_UW:
- case SLJIT_DIVMOD_SW:
- FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0)));
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- FAIL_IF(push_inst(compiler, (int_op ? (op == SLJIT_DIVMOD_UW ? DIVWU : DIVW) : (op == SLJIT_DIVMOD_UW ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)));
- FAIL_IF(push_inst(compiler, (int_op ? MULLW : MULLD) | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
-#else
- FAIL_IF(push_inst(compiler, (op == SLJIT_DIVMOD_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)));
- FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
-#endif
- return push_inst(compiler, SUBF | D(SLJIT_R1) | A(SLJIT_R1) | B(TMP_REG1));
- case SLJIT_DIV_UW:
- case SLJIT_DIV_SW:
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- return push_inst(compiler, (int_op ? (op == SLJIT_DIV_UW ? DIVWU : DIVW) : (op == SLJIT_DIV_UW ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1));
-#else
- return push_inst(compiler, (op == SLJIT_DIV_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1));
-#endif
- case SLJIT_ENDBR:
- case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
- return SLJIT_SUCCESS;
- }
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_prefetch(struct sljit_compiler *compiler,
- sljit_s32 src, sljit_sw srcw)
-{
- if (!(src & OFFS_REG_MASK)) {
- if (srcw == 0 && (src & REG_MASK))
- return push_inst(compiler, DCBT | A(0) | B(src & REG_MASK));
-
- FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
- /* Works with SLJIT_MEM0() case as well. */
- return push_inst(compiler, DCBT | A(src & REG_MASK) | B(TMP_REG1));
- }
-
- srcw &= 0x3;
-
- if (srcw == 0)
- return push_inst(compiler, DCBT | A(src & REG_MASK) | B(OFFS_REG(src)));
-
- FAIL_IF(push_inst(compiler, SLWI_W(srcw) | S(OFFS_REG(src)) | A(TMP_REG1)));
- return push_inst(compiler, DCBT | A(src & REG_MASK) | B(TMP_REG1));
-}
-
-#define EMIT_MOV(type, type_flags, type_cast) \
- emit_op(compiler, (src & SLJIT_IMM) ? SLJIT_MOV : type, flags | (type_flags), dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? type_cast srcw : srcw)
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 flags = HAS_FLAGS(op) ? ALT_SET_FLAGS : 0;
- sljit_s32 op_flags = GET_ALL_FLAGS(op);
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- op = GET_OPCODE(op);
-
- if (GET_FLAG_TYPE(op_flags) == SLJIT_OVERFLOW)
- FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));
-
- if (op < SLJIT_NOT && FAST_IS_REG(src) && src == dst) {
- if (!TYPE_CAST_NEEDED(op))
- return SLJIT_SUCCESS;
- }
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- if (op_flags & SLJIT_32) {
- if (op < SLJIT_NOT) {
- if (src & SLJIT_MEM) {
- if (op == SLJIT_MOV_S32)
- op = SLJIT_MOV_U32;
- }
- else if (src & SLJIT_IMM) {
- if (op == SLJIT_MOV_U32)
- op = SLJIT_MOV_S32;
- }
- }
- else {
- /* Most operations expect sign extended arguments. */
- flags |= INT_DATA | SIGNED_DATA;
- if (HAS_FLAGS(op_flags))
- flags |= ALT_SIGN_EXT;
- }
- }
-#endif
-
- switch (op) {
- case SLJIT_MOV:
-#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
- case SLJIT_MOV_U32:
- case SLJIT_MOV_S32:
- case SLJIT_MOV32:
-#endif
- case SLJIT_MOV_P:
- return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- case SLJIT_MOV_U32:
- return EMIT_MOV(SLJIT_MOV_U32, INT_DATA, (sljit_u32));
-
- case SLJIT_MOV_S32:
- case SLJIT_MOV32:
- return EMIT_MOV(SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, (sljit_s32));
-#endif
-
- case SLJIT_MOV_U8:
- return EMIT_MOV(SLJIT_MOV_U8, BYTE_DATA, (sljit_u8));
-
- case SLJIT_MOV_S8:
- return EMIT_MOV(SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, (sljit_s8));
-
- case SLJIT_MOV_U16:
- return EMIT_MOV(SLJIT_MOV_U16, HALF_DATA, (sljit_u16));
-
- case SLJIT_MOV_S16:
- return EMIT_MOV(SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, (sljit_s16));
-
- case SLJIT_NOT:
- return emit_op(compiler, SLJIT_NOT, flags, dst, dstw, TMP_REG1, 0, src, srcw);
-
- case SLJIT_CLZ:
- case SLJIT_CTZ:
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- return emit_op(compiler, op, flags | (!(op_flags & SLJIT_32) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw);
-#else
- return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
-#endif
- }
-
- return SLJIT_SUCCESS;
-}
-
-#undef EMIT_MOV
-
-#define TEST_SL_IMM(src, srcw) \
- (((src) & SLJIT_IMM) && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN)
-
-#define TEST_UL_IMM(src, srcw) \
- (((src) & SLJIT_IMM) && !((srcw) & ~0xffff))
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
-#define TEST_SH_IMM(src, srcw) \
- (((src) & SLJIT_IMM) && !((srcw) & 0xffff) && (srcw) <= 0x7fffffffl && (srcw) >= -0x80000000l)
-#else
-#define TEST_SH_IMM(src, srcw) \
- (((src) & SLJIT_IMM) && !((srcw) & 0xffff))
-#endif
-
-#define TEST_UH_IMM(src, srcw) \
- (((src) & SLJIT_IMM) && !((srcw) & ~(sljit_sw)0xffff0000))
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
-#define TEST_ADD_IMM(src, srcw) \
- (((src) & SLJIT_IMM) && (srcw) <= 0x7fff7fffl && (srcw) >= -0x80000000l)
-#else
-#define TEST_ADD_IMM(src, srcw) \
- ((src) & SLJIT_IMM)
-#endif
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
-#define TEST_UI_IMM(src, srcw) \
- (((src) & SLJIT_IMM) && !((srcw) & ~0xffffffff))
-#else
-#define TEST_UI_IMM(src, srcw) \
- ((src) & SLJIT_IMM)
-#endif
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
-#define TEST_ADD_FORM1(op) \
- (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW \
- || (op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == (SLJIT_32 | SLJIT_SET_Z | SLJIT_SET_CARRY))
-#define TEST_SUB_FORM2(op) \
- ((GET_FLAG_TYPE(op) >= SLJIT_SIG_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL) \
- || (op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == (SLJIT_32 | SLJIT_SET_Z))
-#define TEST_SUB_FORM3(op) \
- (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW \
- || (op & (SLJIT_32 | SLJIT_SET_Z)) == (SLJIT_32 | SLJIT_SET_Z))
-#else
-#define TEST_ADD_FORM1(op) \
- (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
-#define TEST_SUB_FORM2(op) \
- (GET_FLAG_TYPE(op) >= SLJIT_SIG_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL)
-#define TEST_SUB_FORM3(op) \
- (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
-#endif
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 flags = HAS_FLAGS(op) ? ALT_SET_FLAGS : 0;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- if (op & SLJIT_32) {
- /* Most operations expect sign extended arguments. */
- flags |= INT_DATA | SIGNED_DATA;
- if (src1 & SLJIT_IMM)
- src1w = (sljit_s32)(src1w);
- if (src2 & SLJIT_IMM)
- src2w = (sljit_s32)(src2w);
- if (HAS_FLAGS(op))
- flags |= ALT_SIGN_EXT;
- }
-#endif
- if (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
- FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));
-
- switch (GET_OPCODE(op)) {
- case SLJIT_ADD:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;
-
- if (TEST_ADD_FORM1(op))
- return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, src2, src2w);
-
- if (!HAS_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
- if (TEST_SL_IMM(src2, src2w)) {
- compiler->imm = (sljit_ins)src2w & 0xffff;
- return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
- }
- if (TEST_SL_IMM(src1, src1w)) {
- compiler->imm = (sljit_ins)src1w & 0xffff;
- return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
- }
- if (TEST_SH_IMM(src2, src2w)) {
- compiler->imm = (sljit_ins)(src2w >> 16) & 0xffff;
- return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
- }
- if (TEST_SH_IMM(src1, src1w)) {
- compiler->imm = (sljit_ins)(src1w >> 16) & 0xffff;
- return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
- }
- /* Range between -1 and -32768 is covered above. */
- if (TEST_ADD_IMM(src2, src2w)) {
- compiler->imm = (sljit_ins)src2w & 0xffffffff;
- return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
- }
- if (TEST_ADD_IMM(src1, src1w)) {
- compiler->imm = (sljit_ins)src1w & 0xffffffff;
- return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0);
- }
- }
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- if ((op & (SLJIT_32 | SLJIT_SET_Z)) == (SLJIT_32 | SLJIT_SET_Z)) {
- if (TEST_SL_IMM(src2, src2w)) {
- compiler->imm = (sljit_ins)src2w & 0xffff;
- return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4 | ALT_FORM5, dst, dstw, src1, src1w, TMP_REG2, 0);
- }
- if (TEST_SL_IMM(src1, src1w)) {
- compiler->imm = (sljit_ins)src1w & 0xffff;
- return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4 | ALT_FORM5, dst, dstw, src2, src2w, TMP_REG2, 0);
- }
- return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w);
- }
-#endif
- if (HAS_FLAGS(op)) {
- if (TEST_SL_IMM(src2, src2w)) {
- compiler->imm = (sljit_ins)src2w & 0xffff;
- return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
- }
- if (TEST_SL_IMM(src1, src1w)) {
- compiler->imm = (sljit_ins)src1w & 0xffff;
- return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
- }
- }
- return emit_op(compiler, SLJIT_ADD, flags | ((GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY)) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_ADDC:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;
- return emit_op(compiler, SLJIT_ADDC, flags, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_SUB:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;
-
- if (GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_LESS_EQUAL) {
- if (dst == TMP_REG2) {
- if (TEST_UL_IMM(src2, src2w)) {
- compiler->imm = (sljit_ins)src2w & 0xffff;
- return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
- }
- return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1, dst, dstw, src1, src1w, src2, src2w);
- }
-
- if ((src2 & SLJIT_IMM) && src2w >= 0 && src2w <= (SIMM_MAX + 1)) {
- compiler->imm = (sljit_ins)src2w;
- return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
- }
- return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM3, dst, dstw, src1, src1w, src2, src2w);
- }
-
- if (dst == TMP_REG2 && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL) {
- if (TEST_SL_IMM(src2, src2w)) {
- compiler->imm = (sljit_ins)src2w & 0xffff;
- return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
- }
- return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src1, src1w, src2, src2w);
- }
-
- if (TEST_SUB_FORM2(op)) {
- if ((src2 & SLJIT_IMM) && src2w >= -SIMM_MAX && src2w <= SIMM_MAX) {
- compiler->imm = (sljit_ins)src2w & 0xffff;
- return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2 | ALT_FORM3 | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
- }
- return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w);
- }
-
- if (TEST_SUB_FORM3(op))
- return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM3, dst, dstw, src1, src1w, src2, src2w);
-
- if (TEST_SL_IMM(src2, -src2w)) {
- compiler->imm = (sljit_ins)(-src2w) & 0xffff;
- return emit_op(compiler, SLJIT_ADD, flags | (!HAS_FLAGS(op) ? ALT_FORM2 : ALT_FORM3), dst, dstw, src1, src1w, TMP_REG2, 0);
- }
-
- if (TEST_SL_IMM(src1, src1w) && !(op & SLJIT_SET_Z)) {
- compiler->imm = (sljit_ins)src1w & 0xffff;
- return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0);
- }
-
- if (!HAS_FLAGS(op)) {
- if (TEST_SH_IMM(src2, -src2w)) {
- compiler->imm = (sljit_ins)((-src2w) >> 16) & 0xffff;
- return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
- }
- /* Range between -1 and -32768 is covered above. */
- if (TEST_ADD_IMM(src2, -src2w)) {
- compiler->imm = (sljit_ins)-src2w;
- return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
- }
- }
-
- /* We know ALT_SIGN_EXT is set if it is an SLJIT_32 on 64 bit systems. */
- return emit_op(compiler, SLJIT_SUB, flags | ((GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY)) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_SUBC:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;
- return emit_op(compiler, SLJIT_SUBC, flags, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_MUL:
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- if (op & SLJIT_32)
- flags |= ALT_FORM2;
-#endif
- if (!HAS_FLAGS(op)) {
- if (TEST_SL_IMM(src2, src2w)) {
- compiler->imm = (sljit_ins)src2w & 0xffff;
- return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
- }
- if (TEST_SL_IMM(src1, src1w)) {
- compiler->imm = (sljit_ins)src1w & 0xffff;
- return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
- }
- }
- else
- FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));
- return emit_op(compiler, SLJIT_MUL, flags, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_AND:
- case SLJIT_OR:
- case SLJIT_XOR:
- /* Commutative unsigned operations. */
- if (!HAS_FLAGS(op) || GET_OPCODE(op) == SLJIT_AND) {
- if (TEST_UL_IMM(src2, src2w)) {
- compiler->imm = (sljit_ins)src2w;
- return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
- }
- if (TEST_UL_IMM(src1, src1w)) {
- compiler->imm = (sljit_ins)src1w;
- return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
- }
- if (TEST_UH_IMM(src2, src2w)) {
- compiler->imm = (sljit_ins)(src2w >> 16) & 0xffff;
- return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
- }
- if (TEST_UH_IMM(src1, src1w)) {
- compiler->imm = (sljit_ins)(src1w >> 16) & 0xffff;
- return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
- }
- }
- if (!HAS_FLAGS(op) && GET_OPCODE(op) != SLJIT_AND) {
- /* Unlike or and xor, the and resets unwanted bits as well. */
- if (TEST_UI_IMM(src2, src2w)) {
- compiler->imm = (sljit_ins)src2w;
- return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
- }
- if (TEST_UI_IMM(src1, src1w)) {
- compiler->imm = (sljit_ins)src1w;
- return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
- }
- }
- return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_SHL:
- case SLJIT_MSHL:
- case SLJIT_LSHR:
- case SLJIT_MLSHR:
- case SLJIT_ASHR:
- case SLJIT_MASHR:
- case SLJIT_ROTL:
- case SLJIT_ROTR:
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- if (op & SLJIT_32)
- flags |= ALT_FORM2;
-#endif
- if (src2 & SLJIT_IMM) {
- compiler->imm = (sljit_ins)src2w;
- return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
- }
- return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w);
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_op2(compiler, op, TMP_REG2, 0, src1, src1w, src2, src2w);
-}
-
-#undef TEST_ADD_FORM1
-#undef TEST_SUB_FORM2
-#undef TEST_SUB_FORM3
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src_dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 is_right;
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- sljit_s32 inp_flags = ((op & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;
- sljit_sw bit_length = (op & SLJIT_32) ? 32 : 64;
-#else /* !SLJIT_CONFIG_PPC_64 */
- sljit_s32 inp_flags = WORD_DATA | LOAD_DATA;
- sljit_sw bit_length = 32;
-#endif /* SLJIT_CONFIG_PPC_64 */
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w));
-
- is_right = (GET_OPCODE(op) == SLJIT_LSHR || GET_OPCODE(op) == SLJIT_MLSHR);
-
- if (src_dst == src1) {
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_op2(compiler, (is_right ? SLJIT_ROTR : SLJIT_ROTL) | (op & SLJIT_32), src_dst, 0, src_dst, 0, src2, src2w);
- }
-
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- if (src2 & SLJIT_IMM) {
- src2w &= bit_length - 1;
-
- if (src2w == 0)
- return SLJIT_SUCCESS;
- } else if (src2 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG2, src2, src2w, TMP_REG2));
- src2 = TMP_REG2;
- }
-
- if (src1 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG1, src1, src1w, TMP_REG1));
- src1 = TMP_REG1;
- } else if (src1 & SLJIT_IMM) {
- FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
- src1 = TMP_REG1;
- }
-
- if (src2 & SLJIT_IMM) {
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- if (!(op & SLJIT_32)) {
- if (is_right) {
- FAIL_IF(push_inst(compiler, SRDI(src2w) | S(src_dst) | A(src_dst)));
- return push_inst(compiler, RLDIMI | S(src1) | A(src_dst) | RLDI_SH(64 - src2w) | RLDI_MB(0));
- }
-
- FAIL_IF(push_inst(compiler, SLDI(src2w) | S(src_dst) | A(src_dst)));
- /* Computes SRDI(64 - src2w). */
- FAIL_IF(push_inst(compiler, RLDICL | S(src1) | A(TMP_REG1) | RLDI_SH(src2w) | RLDI_MB(64 - src2w)));
- return push_inst(compiler, OR | S(src_dst) | A(src_dst) | B(TMP_REG1));
- }
-#endif /* SLJIT_CONFIG_PPC_64 */
-
- if (is_right) {
- FAIL_IF(push_inst(compiler, SRWI(src2w) | S(src_dst) | A(src_dst)));
- return push_inst(compiler, RLWIMI | S(src1) | A(src_dst) | RLWI_SH(32 - src2w) | RLWI_MBE(0, src2w - 1));
- }
-
- FAIL_IF(push_inst(compiler, SLWI(src2w) | S(src_dst) | A(src_dst)));
- return push_inst(compiler, RLWIMI | S(src1) | A(src_dst) | RLWI_SH(src2w) | RLWI_MBE(32 - src2w, 31));
- }
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- if (!(op & SLJIT_32)) {
- if (GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR) {
- FAIL_IF(push_inst(compiler, ANDI | S(src2) | A(TMP_REG2) | 0x3f));
- src2 = TMP_REG2;
- }
-
- FAIL_IF(push_inst(compiler, (is_right ? SRD : SLD) | S(src_dst) | A(src_dst) | B(src2)));
- FAIL_IF(push_inst(compiler, (is_right ? SLDI(1) : SRDI(1)) | S(src1) | A(TMP_REG1)));
- FAIL_IF(push_inst(compiler, XORI | S(src2) | A(TMP_REG2) | 0x3f));
- FAIL_IF(push_inst(compiler, (is_right ? SLD : SRD) | S(TMP_REG1) | A(TMP_REG1) | B(TMP_REG2)));
- return push_inst(compiler, OR | S(src_dst) | A(src_dst) | B(TMP_REG1));
- }
-#endif /* SLJIT_CONFIG_PPC_64 */
-
- if (GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR) {
- FAIL_IF(push_inst(compiler, ANDI | S(src2) | A(TMP_REG2) | 0x1f));
- src2 = TMP_REG2;
- }
-
- FAIL_IF(push_inst(compiler, (is_right ? SRW : SLW) | S(src_dst) | A(src_dst) | B(src2)));
- FAIL_IF(push_inst(compiler, (is_right ? SLWI(1) : SRWI(1)) | S(src1) | A(TMP_REG1)));
- FAIL_IF(push_inst(compiler, XORI | S(src2) | A(TMP_REG2) | 0x1f));
- FAIL_IF(push_inst(compiler, (is_right ? SLW : SRW) | S(TMP_REG1) | A(TMP_REG1) | B(TMP_REG2)));
- return push_inst(compiler, OR | S(src_dst) | A(src_dst) | B(TMP_REG1));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- switch (op) {
- case SLJIT_FAST_RETURN:
- if (FAST_IS_REG(src))
- FAIL_IF(push_inst(compiler, MTLR | S(src)));
- else {
- FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw, TMP_REG2));
- FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2)));
- }
-
- return push_inst(compiler, BLR);
- case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
- return SLJIT_SUCCESS;
- case SLJIT_PREFETCH_L1:
- case SLJIT_PREFETCH_L2:
- case SLJIT_PREFETCH_L3:
- case SLJIT_PREFETCH_ONCE:
- return emit_prefetch(compiler, src, srcw);
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
-{
- CHECK_REG_INDEX(check_sljit_get_register_index(reg));
- return reg_map[reg];
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
-{
- CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
- return freg_map[reg];
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
- void *instruction, sljit_u32 size)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
-
- return push_inst(compiler, *(sljit_ins*)instruction);
-}
-
-/* --------------------------------------------------------------------- */
-/* Floating point operators */
-/* --------------------------------------------------------------------- */
-
-#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_32) >> 6))
-#define SELECT_FOP(op, single, double) ((sljit_ins)((op & SLJIT_32) ? single : double))
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
-#define FLOAT_TMP_MEM_OFFSET (6 * sizeof(sljit_sw))
-#else
-#define FLOAT_TMP_MEM_OFFSET (2 * sizeof(sljit_sw))
-
-#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
-#define FLOAT_TMP_MEM_OFFSET_LOW (2 * sizeof(sljit_sw))
-#define FLOAT_TMP_MEM_OFFSET_HI (3 * sizeof(sljit_sw))
-#else
-#define FLOAT_TMP_MEM_OFFSET_LOW (3 * sizeof(sljit_sw))
-#define FLOAT_TMP_MEM_OFFSET_HI (2 * sizeof(sljit_sw))
-#endif
-
-#endif /* SLJIT_CONFIG_PPC_64 */
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- if (src & SLJIT_MEM) {
- /* We can ignore the temporary data store on the stack from caching point of view. */
- FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, TMP_REG1));
- src = TMP_FREG1;
- }
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- op = GET_OPCODE(op);
- FAIL_IF(push_inst(compiler, (op == SLJIT_CONV_S32_FROM_F64 ? FCTIWZ : FCTIDZ) | FD(TMP_FREG1) | FB(src)));
-
- if (op == SLJIT_CONV_SW_FROM_F64) {
- if (FAST_IS_REG(dst)) {
- FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
- return emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1);
- }
- return emit_op_mem(compiler, DOUBLE_DATA, TMP_FREG1, dst, dstw, TMP_REG1);
- }
-#else
- FAIL_IF(push_inst(compiler, FCTIWZ | FD(TMP_FREG1) | FB(src)));
-#endif
-
- if (FAST_IS_REG(dst)) {
- FAIL_IF(load_immediate(compiler, TMP_REG1, FLOAT_TMP_MEM_OFFSET));
- FAIL_IF(push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(SLJIT_SP) | B(TMP_REG1)));
- return emit_op_mem(compiler, INT_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1);
- }
-
- SLJIT_ASSERT(dst & SLJIT_MEM);
-
- if (dst & OFFS_REG_MASK) {
- dstw &= 0x3;
- if (dstw) {
- FAIL_IF(push_inst(compiler, SLWI_W(dstw) | S(OFFS_REG(dst)) | A(TMP_REG1)));
- dstw = TMP_REG1;
- }
- else
- dstw = OFFS_REG(dst);
- }
- else {
- if ((dst & REG_MASK) && !dstw) {
- dstw = dst & REG_MASK;
- dst = 0;
- }
- else {
- /* This works regardless we have SLJIT_MEM1 or SLJIT_MEM0. */
- FAIL_IF(load_immediate(compiler, TMP_REG1, dstw));
- dstw = TMP_REG1;
- }
- }
-
- return push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(dst & REG_MASK) | B(dstw));
-}
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
-
- sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
-
- if (src & SLJIT_IMM) {
- if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
- srcw = (sljit_s32)srcw;
-
- FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
- src = TMP_REG1;
- }
- else if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) {
- if (FAST_IS_REG(src))
- FAIL_IF(push_inst(compiler, EXTSW | S(src) | A(TMP_REG1)));
- else
- FAIL_IF(emit_op_mem(compiler, INT_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
- src = TMP_REG1;
- }
-
- if (FAST_IS_REG(src)) {
- FAIL_IF(emit_op_mem(compiler, WORD_DATA, src, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
- FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
- }
- else
- FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, TMP_REG1));
-
- FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1)));
-
- if (dst & SLJIT_MEM)
- return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1);
- if (op & SLJIT_32)
- return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r));
- return SLJIT_SUCCESS;
-
-#else
-
- sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
- sljit_s32 invert_sign = 1;
-
- if (src & SLJIT_IMM) {
- FAIL_IF(load_immediate(compiler, TMP_REG1, srcw ^ (sljit_sw)0x80000000));
- src = TMP_REG1;
- invert_sign = 0;
- }
- else if (!FAST_IS_REG(src)) {
- FAIL_IF(emit_op_mem(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
- src = TMP_REG1;
- }
-
- /* First, a special double floating point value is constructed: (2^53 + (input xor (2^31)))
- The double precision format has exactly 53 bit precision, so the lower 32 bit represents
- the lower 32 bit of such value. The result of xor 2^31 is the same as adding 0x80000000
- to the input, which shifts it into the 0 - 0xffffffff range. To get the converted floating
- point value, we need to subtract 2^53 + 2^31 from the constructed value. */
- FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330));
- if (invert_sign)
- FAIL_IF(push_inst(compiler, XORIS | S(src) | A(TMP_REG1) | 0x8000));
- FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_HI, TMP_REG1));
- FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, TMP_REG2));
- FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG1) | A(0) | 0x8000));
- FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
- FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, TMP_REG2));
- FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
-
- FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2)));
-
- if (dst & SLJIT_MEM)
- return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1);
- if (op & SLJIT_32)
- return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r));
- return SLJIT_SUCCESS;
-
-#endif
-}
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- if (src1 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, TMP_REG1));
- src1 = TMP_FREG1;
- }
-
- if (src2 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, TMP_REG2));
- src2 = TMP_FREG2;
- }
-
- FAIL_IF(push_inst(compiler, FCMPU | CRD(4) | FA(src1) | FB(src2)));
-
- switch (GET_FLAG_TYPE(op)) {
- case SLJIT_UNORDERED_OR_EQUAL:
- case SLJIT_ORDERED_NOT_EQUAL:
- return push_inst(compiler, CROR | ((4 + 2) << 21) | ((4 + 2) << 16) | ((4 + 3) << 11));
- case SLJIT_UNORDERED_OR_LESS:
- case SLJIT_ORDERED_GREATER_EQUAL:
- return push_inst(compiler, CROR | ((4 + 0) << 21) | ((4 + 0) << 16) | ((4 + 3) << 11));
- case SLJIT_UNORDERED_OR_GREATER:
- case SLJIT_ORDERED_LESS_EQUAL:
- return push_inst(compiler, CROR | ((4 + 1) << 21) | ((4 + 1) << 16) | ((4 + 3) << 11));
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 dst_r;
-
- CHECK_ERROR();
-
- SLJIT_COMPILE_ASSERT((SLJIT_32 == 0x100) && !(DOUBLE_DATA & 0x4), float_transfer_bit_error);
- SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
-
- if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
- op ^= SLJIT_32;
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
-
- if (src & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, TMP_REG1));
- src = dst_r;
- }
-
- switch (GET_OPCODE(op)) {
- case SLJIT_CONV_F64_FROM_F32:
- op ^= SLJIT_32;
- if (op & SLJIT_32) {
- FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(src)));
- break;
- }
- /* Fall through. */
- case SLJIT_MOV_F64:
- if (src != dst_r) {
- if (dst_r != TMP_FREG1)
- FAIL_IF(push_inst(compiler, FMR | FD(dst_r) | FB(src)));
- else
- dst_r = src;
- }
- break;
- case SLJIT_NEG_F64:
- FAIL_IF(push_inst(compiler, FNEG | FD(dst_r) | FB(src)));
- break;
- case SLJIT_ABS_F64:
- FAIL_IF(push_inst(compiler, FABS | FD(dst_r) | FB(src)));
- break;
- }
-
- if (dst & SLJIT_MEM)
- FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op), dst_r, dst, dstw, TMP_REG1));
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 dst_r;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;
-
- if (src1 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, TMP_REG1));
- src1 = TMP_FREG1;
- }
-
- if (src2 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, TMP_REG2));
- src2 = TMP_FREG2;
- }
-
- switch (GET_OPCODE(op)) {
- case SLJIT_ADD_F64:
- FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADD) | FD(dst_r) | FA(src1) | FB(src2)));
- break;
-
- case SLJIT_SUB_F64:
- FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUB) | FD(dst_r) | FA(src1) | FB(src2)));
- break;
-
- case SLJIT_MUL_F64:
- FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMUL) | FD(dst_r) | FA(src1) | FC(src2) /* FMUL use FC as src2 */));
- break;
-
- case SLJIT_DIV_F64:
- FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIV) | FD(dst_r) | FA(src1) | FB(src2)));
- break;
- }
-
- if (dst & SLJIT_MEM)
- FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, TMP_REG1));
-
- return SLJIT_SUCCESS;
-}
-
-#undef SELECT_FOP
-
-/* --------------------------------------------------------------------- */
-/* Other instructions */
-/* --------------------------------------------------------------------- */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- if (FAST_IS_REG(dst))
- return push_inst(compiler, MFLR | D(dst));
-
- /* Memory. */
- FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2)));
- return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
-}
-
-/* --------------------------------------------------------------------- */
-/* Conditional instructions */
-/* --------------------------------------------------------------------- */
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
-{
- struct sljit_label *label;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_label(compiler));
-
- if (compiler->last_label && compiler->last_label->size == compiler->size)
- return compiler->last_label;
-
- label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
- PTR_FAIL_IF(!label);
- set_label(label, compiler);
- return label;
-}
-
-static sljit_ins get_bo_bi_flags(struct sljit_compiler *compiler, sljit_s32 type)
-{
- switch (type) {
- case SLJIT_NOT_CARRY:
- if (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_SUB)
- return (4 << 21) | (2 << 16);
- /* fallthrough */
-
- case SLJIT_EQUAL:
- return (12 << 21) | (2 << 16);
-
- case SLJIT_CARRY:
- if (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_SUB)
- return (12 << 21) | (2 << 16);
- /* fallthrough */
-
- case SLJIT_NOT_EQUAL:
- return (4 << 21) | (2 << 16);
-
- case SLJIT_LESS:
- case SLJIT_SIG_LESS:
- return (12 << 21) | (0 << 16);
-
- case SLJIT_GREATER_EQUAL:
- case SLJIT_SIG_GREATER_EQUAL:
- return (4 << 21) | (0 << 16);
-
- case SLJIT_GREATER:
- case SLJIT_SIG_GREATER:
- return (12 << 21) | (1 << 16);
-
- case SLJIT_LESS_EQUAL:
- case SLJIT_SIG_LESS_EQUAL:
- return (4 << 21) | (1 << 16);
-
- case SLJIT_OVERFLOW:
- return (12 << 21) | (3 << 16);
-
- case SLJIT_NOT_OVERFLOW:
- return (4 << 21) | (3 << 16);
-
- case SLJIT_F_LESS:
- case SLJIT_ORDERED_LESS:
- case SLJIT_UNORDERED_OR_LESS:
- return (12 << 21) | ((4 + 0) << 16);
-
- case SLJIT_F_GREATER_EQUAL:
- case SLJIT_ORDERED_GREATER_EQUAL:
- case SLJIT_UNORDERED_OR_GREATER_EQUAL:
- return (4 << 21) | ((4 + 0) << 16);
-
- case SLJIT_F_GREATER:
- case SLJIT_ORDERED_GREATER:
- case SLJIT_UNORDERED_OR_GREATER:
- return (12 << 21) | ((4 + 1) << 16);
-
- case SLJIT_F_LESS_EQUAL:
- case SLJIT_ORDERED_LESS_EQUAL:
- case SLJIT_UNORDERED_OR_LESS_EQUAL:
- return (4 << 21) | ((4 + 1) << 16);
-
- case SLJIT_F_EQUAL:
- case SLJIT_ORDERED_EQUAL:
- case SLJIT_UNORDERED_OR_EQUAL:
- return (12 << 21) | ((4 + 2) << 16);
-
- case SLJIT_F_NOT_EQUAL:
- case SLJIT_ORDERED_NOT_EQUAL:
- case SLJIT_UNORDERED_OR_NOT_EQUAL:
- return (4 << 21) | ((4 + 2) << 16);
-
- case SLJIT_UNORDERED:
- return (12 << 21) | ((4 + 3) << 16);
-
- case SLJIT_ORDERED:
- return (4 << 21) | ((4 + 3) << 16);
-
- default:
- SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL_REG_ARG);
- return (20 << 21);
- }
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
-{
- struct sljit_jump *jump;
- sljit_ins bo_bi_flags;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_jump(compiler, type));
-
- bo_bi_flags = get_bo_bi_flags(compiler, type & 0xff);
- if (!bo_bi_flags)
- return NULL;
-
- jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
- PTR_FAIL_IF(!jump);
- set_jump(jump, compiler, (sljit_u32)type & SLJIT_REWRITABLE_JUMP);
- type &= 0xff;
-
- if (type == SLJIT_CARRY || type == SLJIT_NOT_CARRY)
- PTR_FAIL_IF(push_inst(compiler, ADDE | RC(ALT_SET_FLAGS) | D(TMP_REG1) | A(TMP_ZERO) | B(TMP_ZERO)));
-
- /* In PPC, we don't need to touch the arguments. */
- if (type < SLJIT_JUMP)
- jump->flags |= IS_COND;
-#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
- if (type >= SLJIT_CALL)
- jump->flags |= IS_CALL;
-#endif
-
- PTR_FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0));
- PTR_FAIL_IF(push_inst(compiler, MTCTR | S(TMP_CALL_REG)));
- jump->addr = compiler->size;
- PTR_FAIL_IF(push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0)));
- return jump;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types)
-{
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- if ((type & 0xff) != SLJIT_CALL_REG_ARG)
- PTR_FAIL_IF(call_with_args(compiler, arg_types, NULL));
-#endif
-
- if (type & SLJIT_CALL_RETURN) {
- PTR_FAIL_IF(emit_stack_frame_release(compiler, 0));
- type = SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP);
- }
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_jump(compiler, type);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
-{
- struct sljit_jump *jump = NULL;
- sljit_s32 src_r;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
-
- if (FAST_IS_REG(src)) {
-#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
- if (type >= SLJIT_CALL && src != TMP_CALL_REG) {
- FAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src)));
- src_r = TMP_CALL_REG;
- }
- else
- src_r = src;
-#else /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */
- src_r = src;
-#endif /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */
- } else if (src & SLJIT_IMM) {
- /* These jumps are converted to jump/call instructions when possible. */
- jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
- FAIL_IF(!jump);
- set_jump(jump, compiler, JUMP_ADDR);
- jump->u.target = (sljit_uw)srcw;
-
-#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
- if (type >= SLJIT_CALL)
- jump->flags |= IS_CALL;
-#endif /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */
-
- FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0));
- src_r = TMP_CALL_REG;
- } else {
- ADJUST_LOCAL_OFFSET(src, srcw);
- FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_CALL_REG, src, srcw, TMP_CALL_REG));
- src_r = TMP_CALL_REG;
- }
-
- FAIL_IF(push_inst(compiler, MTCTR | S(src_r)));
- if (jump)
- jump->addr = compiler->size;
- return push_inst(compiler, BCCTR | (20 << 21) | (type >= SLJIT_FAST_CALL ? 1 : 0));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types,
- sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
-
- if (src & SLJIT_MEM) {
- ADJUST_LOCAL_OFFSET(src, srcw);
- FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_CALL_REG, src, srcw, TMP_CALL_REG));
- src = TMP_CALL_REG;
- }
-
- if (type & SLJIT_CALL_RETURN) {
- if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
- FAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src)));
- src = TMP_CALL_REG;
- }
-
- FAIL_IF(emit_stack_frame_release(compiler, 0));
- type = SLJIT_JUMP;
- }
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- if ((type & 0xff) != SLJIT_CALL_REG_ARG)
- FAIL_IF(call_with_args(compiler, arg_types, &src));
-#endif
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_ijump(compiler, type, src, srcw);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 type)
-{
- sljit_s32 reg, invert;
- sljit_u32 bit, from_xer;
- sljit_s32 saved_op = op;
- sljit_sw saved_dstw = dstw;
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- sljit_s32 input_flags = ((op & SLJIT_32) || op == SLJIT_MOV32) ? INT_DATA : WORD_DATA;
-#else
- sljit_s32 input_flags = WORD_DATA;
-#endif
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- op = GET_OPCODE(op);
- reg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2;
-
- if (op >= SLJIT_ADD && (dst & SLJIT_MEM))
- FAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, TMP_REG1, dst, dstw, TMP_REG1));
-
- invert = 0;
- bit = 0;
- from_xer = 0;
-
- switch (type) {
- case SLJIT_LESS:
- case SLJIT_SIG_LESS:
- break;
-
- case SLJIT_GREATER_EQUAL:
- case SLJIT_SIG_GREATER_EQUAL:
- invert = 1;
- break;
-
- case SLJIT_GREATER:
- case SLJIT_SIG_GREATER:
- bit = 1;
- break;
-
- case SLJIT_LESS_EQUAL:
- case SLJIT_SIG_LESS_EQUAL:
- bit = 1;
- invert = 1;
- break;
-
- case SLJIT_EQUAL:
- bit = 2;
- break;
-
- case SLJIT_NOT_EQUAL:
- bit = 2;
- invert = 1;
- break;
-
- case SLJIT_OVERFLOW:
- from_xer = 1;
- bit = 1;
- break;
-
- case SLJIT_NOT_OVERFLOW:
- from_xer = 1;
- bit = 1;
- invert = 1;
- break;
-
- case SLJIT_CARRY:
- from_xer = 1;
- bit = 2;
- invert = (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_SUB) != 0;
- break;
-
- case SLJIT_NOT_CARRY:
- from_xer = 1;
- bit = 2;
- invert = (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_ADD) != 0;
- break;
-
- case SLJIT_F_LESS:
- case SLJIT_ORDERED_LESS:
- case SLJIT_UNORDERED_OR_LESS:
- bit = 4 + 0;
- break;
-
- case SLJIT_F_GREATER_EQUAL:
- case SLJIT_ORDERED_GREATER_EQUAL:
- case SLJIT_UNORDERED_OR_GREATER_EQUAL:
- bit = 4 + 0;
- invert = 1;
- break;
-
- case SLJIT_F_GREATER:
- case SLJIT_ORDERED_GREATER:
- case SLJIT_UNORDERED_OR_GREATER:
- bit = 4 + 1;
- break;
-
- case SLJIT_F_LESS_EQUAL:
- case SLJIT_ORDERED_LESS_EQUAL:
- case SLJIT_UNORDERED_OR_LESS_EQUAL:
- bit = 4 + 1;
- invert = 1;
- break;
-
- case SLJIT_F_EQUAL:
- case SLJIT_ORDERED_EQUAL:
- case SLJIT_UNORDERED_OR_EQUAL:
- bit = 4 + 2;
- break;
-
- case SLJIT_F_NOT_EQUAL:
- case SLJIT_ORDERED_NOT_EQUAL:
- case SLJIT_UNORDERED_OR_NOT_EQUAL:
- bit = 4 + 2;
- invert = 1;
- break;
-
- case SLJIT_UNORDERED:
- bit = 4 + 3;
- break;
-
- case SLJIT_ORDERED:
- bit = 4 + 3;
- invert = 1;
- break;
-
- default:
- SLJIT_UNREACHABLE();
- break;
- }
-
- FAIL_IF(push_inst(compiler, (from_xer ? MFXER : MFCR) | D(reg)));
- /* Simplified mnemonics: extrwi. */
- FAIL_IF(push_inst(compiler, RLWINM | S(reg) | A(reg) | RLWI_SH(1 + bit) | RLWI_MBE(31, 31)));
-
- if (invert)
- FAIL_IF(push_inst(compiler, XORI | S(reg) | A(reg) | 0x1));
-
- if (op < SLJIT_ADD) {
- if (!(dst & SLJIT_MEM))
- return SLJIT_SUCCESS;
- return emit_op_mem(compiler, input_flags, reg, dst, dstw, TMP_REG1);
- }
-
- SLJIT_SKIP_CHECKS(compiler);
-
- if (dst & SLJIT_MEM)
- return sljit_emit_op2(compiler, saved_op, dst, saved_dstw, TMP_REG1, 0, TMP_REG2, 0);
- return sljit_emit_op2(compiler, saved_op, dst, 0, dst, 0, TMP_REG2, 0);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 dst_reg,
- sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
-
- return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);;
-}
-
-#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
-
-#define EMIT_MEM_LOAD_IMM(inst, mem, memw) \
- ((sljit_s16)(memw) > SIMM_MAX - SSIZE_OF(sw))
-
-#else /* !SLJIT_CONFIG_PPC_32 */
-
-#define EMIT_MEM_LOAD_IMM(inst, mem, memw) \
- ((((inst) & INT_ALIGNED) && ((memw) & 0x3) != 0) \
- || ((sljit_s16)(memw) > SIMM_MAX - SSIZE_OF(sw)) \
- || ((memw) > 0x7fff7fffl || (memw) < -0x80000000l)) \
-
-#endif /* SLJIT_CONFIG_PPC_32 */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 reg,
- sljit_s32 mem, sljit_sw memw)
-{
- sljit_ins inst;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
-
- if (!(reg & REG_PAIR_MASK))
- return sljit_emit_mem_unaligned(compiler, type, reg, mem, memw);
-
- ADJUST_LOCAL_OFFSET(mem, memw);
-
- inst = data_transfer_insts[WORD_DATA | ((type & SLJIT_MEM_STORE) ? 0 : LOAD_DATA)];
-
- if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
- memw &= 0x3;
-
- if (memw != 0) {
- FAIL_IF(push_inst(compiler, SLWI_W(memw) | S(OFFS_REG(mem)) | A(TMP_REG1)));
- FAIL_IF(push_inst(compiler, ADD | D(TMP_REG1) | A(TMP_REG1) | B(mem & REG_MASK)));
- } else
- FAIL_IF(push_inst(compiler, ADD | D(TMP_REG1) | A(mem & REG_MASK) | B(OFFS_REG(mem))));
-
- mem = TMP_REG1;
- memw = 0;
- } else {
- if (EMIT_MEM_LOAD_IMM(inst, mem, memw)) {
- if ((mem & REG_MASK) != 0) {
- SLJIT_SKIP_CHECKS(compiler);
- FAIL_IF(sljit_emit_op2(compiler, SLJIT_ADD, TMP_REG1, 0, mem & REG_MASK, 0, SLJIT_IMM, memw));
- } else
- FAIL_IF(load_immediate(compiler, TMP_REG1, memw));
-
- memw = 0;
- mem = TMP_REG1;
- } else if (memw > SIMM_MAX || memw < SIMM_MIN) {
- FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG1) | A(mem & REG_MASK) | IMM((memw + 0x8000) >> 16)));
-
- memw &= 0xffff;
- mem = TMP_REG1;
- } else {
- memw &= 0xffff;
- mem &= REG_MASK;
- }
- }
-
- SLJIT_ASSERT((memw >= 0 && memw <= SIMM_MAX - SSIZE_OF(sw)) || (memw >= 0x8000 && memw <= 0xffff));
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- inst &= (sljit_ins)~INT_ALIGNED;
-#endif /* SLJIT_CONFIG_PPC_64 */
-
- if (!(type & SLJIT_MEM_STORE) && mem == REG_PAIR_FIRST(reg)) {
- FAIL_IF(push_inst(compiler, inst | D(REG_PAIR_SECOND(reg)) | A(mem) | IMM(memw + SSIZE_OF(sw))));
- return push_inst(compiler, inst | D(REG_PAIR_FIRST(reg)) | A(mem) | IMM(memw));
- }
-
- FAIL_IF(push_inst(compiler, inst | D(REG_PAIR_FIRST(reg)) | A(mem) | IMM(memw)));
- return push_inst(compiler, inst | D(REG_PAIR_SECOND(reg)) | A(mem) | IMM(memw + SSIZE_OF(sw)));
-}
-
-#undef EMIT_MEM_LOAD_IMM
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 reg,
- sljit_s32 mem, sljit_sw memw)
-{
- sljit_s32 mem_flags;
- sljit_ins inst;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_mem_update(compiler, type, reg, mem, memw));
-
- if (type & SLJIT_MEM_POST)
- return SLJIT_ERR_UNSUPPORTED;
-
- switch (type & 0xff) {
- case SLJIT_MOV:
- case SLJIT_MOV_P:
-#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
- case SLJIT_MOV_U32:
- case SLJIT_MOV_S32:
- case SLJIT_MOV32:
-#endif
- mem_flags = WORD_DATA;
- break;
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- case SLJIT_MOV_U32:
- case SLJIT_MOV32:
- mem_flags = INT_DATA;
- break;
-
- case SLJIT_MOV_S32:
- mem_flags = INT_DATA;
-
- if (!(type & SLJIT_MEM_STORE) && !(type & SLJIT_32)) {
- if (mem & OFFS_REG_MASK)
- mem_flags |= SIGNED_DATA;
- else
- return SLJIT_ERR_UNSUPPORTED;
- }
- break;
-#endif
-
- case SLJIT_MOV_U8:
- case SLJIT_MOV_S8:
- mem_flags = BYTE_DATA;
- break;
-
- case SLJIT_MOV_U16:
- mem_flags = HALF_DATA;
- break;
-
- case SLJIT_MOV_S16:
- mem_flags = HALF_DATA | SIGNED_DATA;
- break;
-
- default:
- SLJIT_UNREACHABLE();
- mem_flags = WORD_DATA;
- break;
- }
-
- if (!(type & SLJIT_MEM_STORE))
- mem_flags |= LOAD_DATA;
-
- if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
- if (memw != 0)
- return SLJIT_ERR_UNSUPPORTED;
-
- if (type & SLJIT_MEM_SUPP)
- return SLJIT_SUCCESS;
-
- inst = updated_data_transfer_insts[mem_flags | INDEXED];
- FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, 0, reg) | A(mem & REG_MASK) | B(OFFS_REG(mem))));
- }
- else {
- if (memw > SIMM_MAX || memw < SIMM_MIN)
- return SLJIT_ERR_UNSUPPORTED;
-
- inst = updated_data_transfer_insts[mem_flags];
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- if ((inst & INT_ALIGNED) && (memw & 0x3) != 0)
- return SLJIT_ERR_UNSUPPORTED;
-#endif
-
- if (type & SLJIT_MEM_SUPP)
- return SLJIT_SUCCESS;
-
- FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, 0, reg) | A(mem & REG_MASK) | IMM(memw)));
- }
-
- if ((mem_flags & LOAD_DATA) && (type & 0xff) == SLJIT_MOV_S8)
- return push_inst(compiler, EXTSB | S(reg) | A(reg));
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 freg,
- sljit_s32 mem, sljit_sw memw)
-{
- sljit_s32 mem_flags;
- sljit_ins inst;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_fmem_update(compiler, type, freg, mem, memw));
-
- if (type & SLJIT_MEM_POST)
- return SLJIT_ERR_UNSUPPORTED;
-
- if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
- if (memw != 0)
- return SLJIT_ERR_UNSUPPORTED;
- }
- else {
- if (memw > SIMM_MAX || memw < SIMM_MIN)
- return SLJIT_ERR_UNSUPPORTED;
- }
-
- if (type & SLJIT_MEM_SUPP)
- return SLJIT_SUCCESS;
-
- mem_flags = FLOAT_DATA(type);
-
- if (!(type & SLJIT_MEM_STORE))
- mem_flags |= LOAD_DATA;
-
- if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
- inst = updated_data_transfer_insts[mem_flags | INDEXED];
- return push_inst(compiler, INST_CODE_AND_DST(inst, DOUBLE_DATA, freg) | A(mem & REG_MASK) | B(OFFS_REG(mem)));
- }
-
- inst = updated_data_transfer_insts[mem_flags];
- return push_inst(compiler, INST_CODE_AND_DST(inst, DOUBLE_DATA, freg) | A(mem & REG_MASK) | IMM(memw));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
-{
- struct sljit_const *const_;
- sljit_s32 dst_r;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
- PTR_FAIL_IF(!const_);
- set_const(const_, compiler);
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
- PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));
-
- if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
-
- return const_;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
-{
- struct sljit_put_label *put_label;
- sljit_s32 dst_r;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
- PTR_FAIL_IF(!put_label);
- set_put_label(put_label, compiler, 0);
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
-#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
- PTR_FAIL_IF(emit_const(compiler, dst_r, 0));
-#else
- PTR_FAIL_IF(push_inst(compiler, (sljit_ins)dst_r));
- compiler->size += 4;
-#endif
-
- if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
-
- return put_label;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
-{
- sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
-}
diff --git a/contrib/libs/pcre2/src/sljit/sljitNativeRISCV_32.c b/contrib/libs/pcre2/src/sljit/sljitNativeRISCV_32.c
deleted file mode 100644
index b38e6924c8..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitNativeRISCV_32.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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.
- */
-
-static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r, sljit_sw imm, sljit_s32 tmp_r)
-{
- SLJIT_UNUSED_ARG(tmp_r);
- SLJIT_ASSERT(dst_r != tmp_r);
-
- if (imm <= SIMM_MAX && imm >= SIMM_MIN)
- return push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm));
-
- if (imm & 0x800)
- imm += 0x1000;
-
- FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(imm & ~0xfff)));
-
- if ((imm & 0xfff) == 0)
- return SLJIT_SUCCESS;
-
- return push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm));
-}
-
-static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value, sljit_ins last_ins)
-{
- if ((init_value & 0x800) != 0)
- init_value += 0x1000;
-
- FAIL_IF(push_inst(compiler, LUI | RD(dst) | (sljit_ins)(init_value & ~0xfff)));
- return push_inst(compiler, last_ins | RS1(dst) | IMM_I(init_value));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
-{
- sljit_ins *inst = (sljit_ins*)addr;
- SLJIT_UNUSED_ARG(executable_offset);
-
- if ((new_target & 0x800) != 0)
- new_target += 0x1000;
-
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 0);
-
- SLJIT_ASSERT((inst[0] & 0x7f) == LUI);
- inst[0] = (inst[0] & 0xfff) | (sljit_ins)((sljit_sw)new_target & ~0xfff);
- SLJIT_ASSERT((inst[1] & 0x707f) == ADDI || (inst[1] & 0x707f) == JALR);
- inst[1] = (inst[1] & 0xfffff) | IMM_I(new_target);
-
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 1);
- inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 5);
-}
diff --git a/contrib/libs/pcre2/src/sljit/sljitNativeRISCV_64.c b/contrib/libs/pcre2/src/sljit/sljitNativeRISCV_64.c
deleted file mode 100644
index 32cec7848d..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitNativeRISCV_64.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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.
- */
-
-static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r, sljit_sw imm, sljit_s32 tmp_r)
-{
- sljit_sw high;
-
- SLJIT_ASSERT(dst_r != tmp_r);
-
- if (imm <= SIMM_MAX && imm >= SIMM_MIN)
- return push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm));
-
- if (imm <= 0x7fffffffl && imm >= S32_MIN) {
- if (imm > S32_MAX) {
- SLJIT_ASSERT((imm & 0x800) != 0);
- FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)0x80000000u));
- return push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(imm));
- }
-
- if ((imm & 0x800) != 0)
- imm += 0x1000;
-
- FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(imm & ~0xfff)));
-
- if ((imm & 0xfff) == 0)
- return SLJIT_SUCCESS;
-
- return push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm));
- }
-
- /* Trailing zeroes could be used to produce shifted immediates. */
-
- if (imm <= 0x7ffffffffffl && imm >= -0x80000000000l) {
- high = imm >> 12;
-
- if (imm & 0x800)
- high = ~high;
-
- if (high > S32_MAX) {
- SLJIT_ASSERT((high & 0x800) != 0);
- FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)0x80000000u));
- FAIL_IF(push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(high)));
- } else {
- if ((high & 0x800) != 0)
- high += 0x1000;
-
- FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(high & ~0xfff)));
-
- if ((high & 0xfff) != 0)
- FAIL_IF(push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(high)));
- }
-
- FAIL_IF(push_inst(compiler, SLLI | RD(dst_r) | RS1(dst_r) | IMM_I(12)));
-
- if ((imm & 0xfff) != 0)
- return push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(imm));
-
- return SLJIT_SUCCESS;
- }
-
- high = imm >> 32;
- imm = (sljit_s32)imm;
-
- if ((imm & 0x80000000l) != 0)
- high = ~high;
-
- if (high <= 0x7ffff && high >= -0x80000) {
- FAIL_IF(push_inst(compiler, LUI | RD(tmp_r) | (sljit_ins)(high << 12)));
- high = 0x1000;
- } else {
- if ((high & 0x800) != 0)
- high += 0x1000;
-
- FAIL_IF(push_inst(compiler, LUI | RD(tmp_r) | (sljit_ins)(high & ~0xfff)));
- high &= 0xfff;
- }
-
- if (imm <= SIMM_MAX && imm >= SIMM_MIN) {
- FAIL_IF(push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm)));
- imm = 0;
- } else if (imm > S32_MAX) {
- SLJIT_ASSERT((imm & 0x800) != 0);
-
- FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)0x80000000u));
- imm = 0x1000 | (imm & 0xfff);
- } else {
- if ((imm & 0x800) != 0)
- imm += 0x1000;
-
- FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(imm & ~0xfff)));
- imm &= 0xfff;
- }
-
- if ((high & 0xfff) != 0)
- FAIL_IF(push_inst(compiler, ADDI | RD(tmp_r) | RS1(tmp_r) | IMM_I(high)));
-
- if (imm & 0x1000)
- FAIL_IF(push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(imm)));
- else if (imm != 0)
- FAIL_IF(push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm)));
-
- FAIL_IF(push_inst(compiler, SLLI | RD(tmp_r) | RS1(tmp_r) | IMM_I((high & 0x1000) ? 20 : 32)));
- return push_inst(compiler, XOR | RD(dst_r) | RS1(dst_r) | RS2(tmp_r));
-}
-
-static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value, sljit_ins last_ins)
-{
- sljit_sw high;
-
- if ((init_value & 0x800) != 0)
- init_value += 0x1000;
-
- high = init_value >> 32;
-
- if ((init_value & 0x80000000l) != 0)
- high = ~high;
-
- if ((high & 0x800) != 0)
- high += 0x1000;
-
- FAIL_IF(push_inst(compiler, LUI | RD(TMP_REG3) | (sljit_ins)(high & ~0xfff)));
- FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I(high)));
- FAIL_IF(push_inst(compiler, LUI | RD(dst) | (sljit_ins)(init_value & ~0xfff)));
- FAIL_IF(push_inst(compiler, SLLI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I(32)));
- FAIL_IF(push_inst(compiler, XOR | RD(dst) | RS1(dst) | RS2(TMP_REG3)));
- return push_inst(compiler, last_ins | RS1(dst) | IMM_I(init_value));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
-{
- sljit_ins *inst = (sljit_ins*)addr;
- sljit_sw high;
- SLJIT_UNUSED_ARG(executable_offset);
-
- if ((new_target & 0x800) != 0)
- new_target += 0x1000;
-
- high = (sljit_sw)new_target >> 32;
-
- if ((new_target & 0x80000000l) != 0)
- high = ~high;
-
- if ((high & 0x800) != 0)
- high += 0x1000;
-
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 0);
-
- SLJIT_ASSERT((inst[0] & 0x7f) == LUI);
- inst[0] = (inst[0] & 0xfff) | (sljit_ins)(high & ~0xfff);
- SLJIT_ASSERT((inst[1] & 0x707f) == ADDI);
- inst[1] = (inst[1] & 0xfffff) | IMM_I(high);
- SLJIT_ASSERT((inst[2] & 0x7f) == LUI);
- inst[2] = (inst[2] & 0xfff) | (sljit_ins)((sljit_sw)new_target & ~0xfff);
- SLJIT_ASSERT((inst[5] & 0x707f) == ADDI || (inst[5] & 0x707f) == JALR);
- inst[5] = (inst[5] & 0xfffff) | IMM_I(new_target);
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 1);
-
- inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 5);
-}
diff --git a/contrib/libs/pcre2/src/sljit/sljitNativeRISCV_common.c b/contrib/libs/pcre2/src/sljit/sljitNativeRISCV_common.c
deleted file mode 100644
index 58a48c649c..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitNativeRISCV_common.c
+++ /dev/null
@@ -1,2762 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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.
- */
-
-SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
-{
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- return "RISC-V-32" SLJIT_CPUINFO;
-#else /* !SLJIT_CONFIG_RISCV_32 */
- return "RISC-V-64" SLJIT_CPUINFO;
-#endif /* SLJIT_CONFIG_RISCV_32 */
-}
-
-/* Length of an instruction word
- Both for riscv-32 and riscv-64 */
-typedef sljit_u32 sljit_ins;
-
-#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
-#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
-#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
-#define TMP_ZERO 0
-
-/* Flags are kept in volatile registers. */
-#define EQUAL_FLAG (SLJIT_NUMBER_OF_REGISTERS + 5)
-#define RETURN_ADDR_REG TMP_REG2
-#define OTHER_FLAG (SLJIT_NUMBER_OF_REGISTERS + 6)
-
-#define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
-#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
-
-static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = {
- 0, 10, 11, 12, 13, 14, 15, 16, 17, 29, 30, 31, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 9, 8, 2, 6, 1, 7, 5, 28
-};
-
-static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
- 0, 10, 11, 12, 13, 14, 15, 16, 17, 2, 3, 4, 5, 6, 7, 28, 29, 30, 31, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 9, 8, 0, 1,
-};
-
-/* --------------------------------------------------------------------- */
-/* Instrucion forms */
-/* --------------------------------------------------------------------- */
-
-#define RD(rd) ((sljit_ins)reg_map[rd] << 7)
-#define RS1(rs1) ((sljit_ins)reg_map[rs1] << 15)
-#define RS2(rs2) ((sljit_ins)reg_map[rs2] << 20)
-#define FRD(rd) ((sljit_ins)freg_map[rd] << 7)
-#define FRS1(rs1) ((sljit_ins)freg_map[rs1] << 15)
-#define FRS2(rs2) ((sljit_ins)freg_map[rs2] << 20)
-#define IMM_I(imm) ((sljit_ins)(imm) << 20)
-#define IMM_S(imm) ((((sljit_ins)(imm) & 0xfe0) << 20) | (((sljit_ins)(imm) & 0x1f) << 7))
-
-/* Represents funct(i) parts of the instructions. */
-#define OPC(o) ((sljit_ins)(o))
-#define F3(f) ((sljit_ins)(f) << 12)
-#define F12(f) ((sljit_ins)(f) << 20)
-#define F7(f) ((sljit_ins)(f) << 25)
-
-#define ADD (F7(0x0) | F3(0x0) | OPC(0x33))
-#define ADDI (F3(0x0) | OPC(0x13))
-#define AND (F7(0x0) | F3(0x7) | OPC(0x33))
-#define ANDI (F3(0x7) | OPC(0x13))
-#define AUIPC (OPC(0x17))
-#define BEQ (F3(0x0) | OPC(0x63))
-#define BNE (F3(0x1) | OPC(0x63))
-#define BLT (F3(0x4) | OPC(0x63))
-#define BGE (F3(0x5) | OPC(0x63))
-#define BLTU (F3(0x6) | OPC(0x63))
-#define BGEU (F3(0x7) | OPC(0x63))
-#define DIV (F7(0x1) | F3(0x4) | OPC(0x33))
-#define DIVU (F7(0x1) | F3(0x5) | OPC(0x33))
-#define EBREAK (F12(0x1) | F3(0x0) | OPC(0x73))
-#define FADD_S (F7(0x0) | F3(0x7) | OPC(0x53))
-#define FDIV_S (F7(0xc) | F3(0x7) | OPC(0x53))
-#define FEQ_S (F7(0x50) | F3(0x2) | OPC(0x53))
-#define FLD (F3(0x3) | OPC(0x7))
-#define FLE_S (F7(0x50) | F3(0x0) | OPC(0x53))
-#define FLT_S (F7(0x50) | F3(0x1) | OPC(0x53))
-#define FSD (F3(0x3) | OPC(0x27))
-/* These conversion opcodes are partly defined. */
-#define FCVT_S_D (F7(0x20) | OPC(0x53))
-#define FCVT_S_W (F7(0x68) | OPC(0x53))
-#define FCVT_W_S (F7(0x60) | F3(0x1) | OPC(0x53))
-#define FMUL_S (F7(0x8) | F3(0x7) | OPC(0x53))
-#define FSGNJ_S (F7(0x10) | F3(0x0) | OPC(0x53))
-#define FSGNJN_S (F7(0x10) | F3(0x1) | OPC(0x53))
-#define FSGNJX_S (F7(0x10) | F3(0x2) | OPC(0x53))
-#define FSUB_S (F7(0x4) | F3(0x7) | OPC(0x53))
-#define JAL (OPC(0x6f))
-#define JALR (F3(0x0) | OPC(0x67))
-#define LD (F3(0x3) | OPC(0x3))
-#define LUI (OPC(0x37))
-#define LW (F3(0x2) | OPC(0x3))
-#define MUL (F7(0x1) | F3(0x0) | OPC(0x33))
-#define MULH (F7(0x1) | F3(0x1) | OPC(0x33))
-#define MULHU (F7(0x1) | F3(0x3) | OPC(0x33))
-#define OR (F7(0x0) | F3(0x6) | OPC(0x33))
-#define ORI (F3(0x6) | OPC(0x13))
-#define REM (F7(0x1) | F3(0x6) | OPC(0x33))
-#define REMU (F7(0x1) | F3(0x7) | OPC(0x33))
-#define SD (F3(0x3) | OPC(0x23))
-#define SLL (F7(0x0) | F3(0x1) | OPC(0x33))
-#define SLLI (IMM_I(0x0) | F3(0x1) | OPC(0x13))
-#define SLT (F7(0x0) | F3(0x2) | OPC(0x33))
-#define SLTI (F3(0x2) | OPC(0x13))
-#define SLTU (F7(0x0) | F3(0x3) | OPC(0x33))
-#define SLTUI (F3(0x3) | OPC(0x13))
-#define SRL (F7(0x0) | F3(0x5) | OPC(0x33))
-#define SRLI (IMM_I(0x0) | F3(0x5) | OPC(0x13))
-#define SRA (F7(0x20) | F3(0x5) | OPC(0x33))
-#define SRAI (IMM_I(0x400) | F3(0x5) | OPC(0x13))
-#define SUB (F7(0x20) | F3(0x0) | OPC(0x33))
-#define SW (F3(0x2) | OPC(0x23))
-#define XOR (F7(0x0) | F3(0x4) | OPC(0x33))
-#define XORI (F3(0x4) | OPC(0x13))
-
-#define SIMM_MAX (0x7ff)
-#define SIMM_MIN (-0x800)
-#define BRANCH_MAX (0xfff)
-#define BRANCH_MIN (-0x1000)
-#define JUMP_MAX (0xfffff)
-#define JUMP_MIN (-0x100000)
-
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
-#define S32_MAX (0x7ffff7ffl)
-#define S32_MIN (-0x80000000l)
-#define S44_MAX (0x7fffffff7ffl)
-#define S52_MAX (0x7ffffffffffffl)
-#endif
-
-static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)
-{
- sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
- FAIL_IF(!ptr);
- *ptr = ins;
- compiler->size++;
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 push_imm_s_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_sw imm)
-{
- return push_inst(compiler, ins | IMM_S(imm));
-}
-
-static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code, sljit_sw executable_offset)
-{
- sljit_sw diff;
- sljit_uw target_addr;
- sljit_ins *inst;
-
- inst = (sljit_ins *)jump->addr;
-
- if (jump->flags & SLJIT_REWRITABLE_JUMP)
- goto exit;
-
- if (jump->flags & JUMP_ADDR)
- target_addr = jump->u.target;
- else {
- SLJIT_ASSERT(jump->flags & JUMP_LABEL);
- target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
- }
-
- diff = (sljit_sw)target_addr - (sljit_sw)inst - executable_offset;
-
- if (jump->flags & IS_COND) {
- inst--;
- diff += SSIZE_OF(ins);
-
- if (diff >= BRANCH_MIN && diff <= BRANCH_MAX) {
- jump->flags |= PATCH_B;
- inst[0] = (inst[0] & 0x1fff07f) ^ 0x1000;
- jump->addr = (sljit_uw)inst;
- return inst;
- }
-
- inst++;
- diff -= SSIZE_OF(ins);
- }
-
- if (diff >= JUMP_MIN && diff <= JUMP_MAX) {
- if (jump->flags & IS_COND) {
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- inst[-1] -= (sljit_ins)(1 * sizeof(sljit_ins)) << 7;
-#else
- inst[-1] -= (sljit_ins)(5 * sizeof(sljit_ins)) << 7;
-#endif
- }
-
- jump->flags |= PATCH_J;
- return inst;
- }
-
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
- if (diff >= S32_MIN && diff <= S32_MAX) {
- if (jump->flags & IS_COND)
- inst[-1] -= (sljit_ins)(4 * sizeof(sljit_ins)) << 7;
-
- jump->flags |= PATCH_REL32;
- inst[1] = inst[0];
- return inst + 1;
- }
-
- if (target_addr <= (sljit_uw)S32_MAX) {
- if (jump->flags & IS_COND)
- inst[-1] -= (sljit_ins)(4 * sizeof(sljit_ins)) << 7;
-
- jump->flags |= PATCH_ABS32;
- inst[1] = inst[0];
- return inst + 1;
- }
-
- if (target_addr <= S44_MAX) {
- if (jump->flags & IS_COND)
- inst[-1] -= (sljit_ins)(2 * sizeof(sljit_ins)) << 7;
-
- jump->flags |= PATCH_ABS44;
- inst[3] = inst[0];
- return inst + 3;
- }
-
- if (target_addr <= S52_MAX) {
- if (jump->flags & IS_COND)
- inst[-1] -= (sljit_ins)(1 * sizeof(sljit_ins)) << 7;
-
- jump->flags |= PATCH_ABS52;
- inst[4] = inst[0];
- return inst + 4;
- }
-#endif
-
-exit:
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- inst[1] = inst[0];
- return inst + 1;
-#else
- inst[5] = inst[0];
- return inst + 5;
-#endif
-}
-
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
-
-static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label)
-{
- if (max_label <= (sljit_uw)S32_MAX) {
- put_label->flags = PATCH_ABS32;
- return 1;
- }
-
- if (max_label <= S44_MAX) {
- put_label->flags = PATCH_ABS44;
- return 3;
- }
-
- if (max_label <= S52_MAX) {
- put_label->flags = PATCH_ABS52;
- return 4;
- }
-
- put_label->flags = 0;
- return 5;
-}
-
-#endif /* SLJIT_CONFIG_RISCV_64 */
-
-static SLJIT_INLINE void load_addr_to_reg(void *dst, sljit_u32 reg)
-{
- struct sljit_jump *jump = NULL;
- struct sljit_put_label *put_label;
- sljit_uw flags;
- sljit_ins *inst;
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
- sljit_sw high;
-#endif
- sljit_uw addr;
-
- if (reg != 0) {
- jump = (struct sljit_jump*)dst;
- flags = jump->flags;
- inst = (sljit_ins*)jump->addr;
- addr = (flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
- } else {
- put_label = (struct sljit_put_label*)dst;
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
- flags = put_label->flags;
-#endif
- inst = (sljit_ins*)put_label->addr;
- addr = put_label->label->addr;
- reg = *inst;
- }
-
- if ((addr & 0x800) != 0)
- addr += 0x1000;
-
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- inst[0] = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff);
-#else /* !SLJIT_CONFIG_RISCV_32 */
-
- if (flags & PATCH_ABS32) {
- SLJIT_ASSERT(addr <= S32_MAX);
- inst[0] = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff);
- } else if (flags & PATCH_ABS44) {
- high = (sljit_sw)addr >> 12;
- SLJIT_ASSERT((sljit_uw)high <= 0x7fffffff);
-
- if (high > S32_MAX) {
- SLJIT_ASSERT((high & 0x800) != 0);
- inst[0] = LUI | RD(reg) | (sljit_ins)0x80000000u;
- inst[1] = XORI | RD(reg) | RS1(reg) | IMM_I(high);
- } else {
- if ((high & 0x800) != 0)
- high += 0x1000;
-
- inst[0] = LUI | RD(reg) | (sljit_ins)(high & ~0xfff);
- inst[1] = ADDI | RD(reg) | RS1(reg) | IMM_I(high);
- }
-
- inst[2] = SLLI | RD(reg) | RS1(reg) | IMM_I(12);
- inst += 2;
- } else {
- high = (sljit_sw)addr >> 32;
-
- if ((addr & 0x80000000l) != 0)
- high = ~high;
-
- if ((high & 0x800) != 0)
- high += 0x1000;
-
- if (flags & PATCH_ABS52) {
- SLJIT_ASSERT(addr <= S52_MAX);
- inst[0] = LUI | RD(TMP_REG3) | (sljit_ins)(high << 12);
- } else {
- inst[0] = LUI | RD(TMP_REG3) | (sljit_ins)(high & ~0xfff);
- inst[1] = ADDI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I(high);
- inst++;
- }
-
- inst[1] = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff);
- inst[2] = SLLI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I((flags & PATCH_ABS52) ? 20 : 32);
- inst[3] = XOR | RD(reg) | RS1(reg) | RS2(TMP_REG3);
- inst += 3;
- }
-#endif /* !SLJIT_CONFIG_RISCV_32 */
-
- if (jump != NULL) {
- SLJIT_ASSERT((inst[1] & 0x707f) == JALR);
- inst[1] = (inst[1] & 0xfffff) | IMM_I(addr);
- } else
- inst[1] = ADDI | RD(reg) | RS1(reg) | IMM_I(addr);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
-{
- struct sljit_memory_fragment *buf;
- sljit_ins *code;
- sljit_ins *code_ptr;
- sljit_ins *buf_ptr;
- sljit_ins *buf_end;
- sljit_uw word_count;
- sljit_uw next_addr;
- sljit_sw executable_offset;
- sljit_uw addr;
-
- struct sljit_label *label;
- struct sljit_jump *jump;
- struct sljit_const *const_;
- struct sljit_put_label *put_label;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_generate_code(compiler));
- reverse_buf(compiler);
-
- code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
- PTR_FAIL_WITH_EXEC_IF(code);
- buf = compiler->buf;
-
- code_ptr = code;
- word_count = 0;
- next_addr = 0;
- executable_offset = SLJIT_EXEC_OFFSET(code);
-
- label = compiler->labels;
- jump = compiler->jumps;
- const_ = compiler->consts;
- put_label = compiler->put_labels;
-
- do {
- buf_ptr = (sljit_ins*)buf->memory;
- buf_end = buf_ptr + (buf->used_size >> 2);
- do {
- *code_ptr = *buf_ptr++;
- if (next_addr == word_count) {
- SLJIT_ASSERT(!label || label->size >= word_count);
- SLJIT_ASSERT(!jump || jump->addr >= word_count);
- SLJIT_ASSERT(!const_ || const_->addr >= word_count);
- SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
-
- /* These structures are ordered by their address. */
- if (label && label->size == word_count) {
- label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
- label->size = (sljit_uw)(code_ptr - code);
- label = label->next;
- }
- if (jump && jump->addr == word_count) {
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- word_count += 1;
-#else
- word_count += 5;
-#endif
- jump->addr = (sljit_uw)code_ptr;
- code_ptr = detect_jump_type(jump, code, executable_offset);
- jump = jump->next;
- }
- if (const_ && const_->addr == word_count) {
- const_->addr = (sljit_uw)code_ptr;
- const_ = const_->next;
- }
- if (put_label && put_label->addr == word_count) {
- SLJIT_ASSERT(put_label->label);
- put_label->addr = (sljit_uw)code_ptr;
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- code_ptr += 1;
- word_count += 1;
-#else
- code_ptr += put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));
- word_count += 5;
-#endif
- put_label = put_label->next;
- }
- next_addr = compute_next_addr(label, jump, const_, put_label);
- }
- code_ptr++;
- word_count++;
- } while (buf_ptr < buf_end);
-
- buf = buf->next;
- } while (buf);
-
- if (label && label->size == word_count) {
- label->addr = (sljit_uw)code_ptr;
- label->size = (sljit_uw)(code_ptr - code);
- label = label->next;
- }
-
- SLJIT_ASSERT(!label);
- SLJIT_ASSERT(!jump);
- SLJIT_ASSERT(!const_);
- SLJIT_ASSERT(!put_label);
- SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
-
- jump = compiler->jumps;
- while (jump) {
- do {
- if (!(jump->flags & (PATCH_B | PATCH_J | PATCH_REL32))) {
- load_addr_to_reg(jump, TMP_REG1);
- break;
- }
-
- addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
- buf_ptr = (sljit_ins *)jump->addr;
- addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset);
-
- if (jump->flags & PATCH_B) {
- SLJIT_ASSERT((sljit_sw)addr >= BRANCH_MIN && (sljit_sw)addr <= BRANCH_MAX);
- addr = ((addr & 0x800) >> 4) | ((addr & 0x1e) << 7) | ((addr & 0x7e0) << 20) | ((addr & 0x1000) << 19);
- buf_ptr[0] |= (sljit_ins)addr;
- break;
- }
-
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
- if (jump->flags & PATCH_REL32) {
- SLJIT_ASSERT((sljit_sw)addr >= S32_MIN && (sljit_sw)addr <= S32_MAX);
-
- if ((addr & 0x800) != 0)
- addr += 0x1000;
-
- buf_ptr[0] = AUIPC | RD(TMP_REG1) | (sljit_ins)((sljit_sw)addr & ~0xfff);
- SLJIT_ASSERT((buf_ptr[1] & 0x707f) == JALR);
- buf_ptr[1] |= IMM_I(addr);
- break;
- }
-#endif
-
- SLJIT_ASSERT((sljit_sw)addr >= JUMP_MIN && (sljit_sw)addr <= JUMP_MAX);
- addr = (addr & 0xff000) | ((addr & 0x800) << 9) | ((addr & 0x7fe) << 20) | ((addr & 0x100000) << 11);
- buf_ptr[0] = JAL | RD((jump->flags & IS_CALL) ? RETURN_ADDR_REG : TMP_ZERO) | (sljit_ins)addr;
- } while (0);
- jump = jump->next;
- }
-
- put_label = compiler->put_labels;
- while (put_label) {
- load_addr_to_reg(put_label, 0);
- put_label = put_label->next;
- }
-
- compiler->error = SLJIT_ERR_COMPILED;
- compiler->executable_offset = executable_offset;
- compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins);
-
- code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
- code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
-
- SLJIT_CACHE_FLUSH(code, code_ptr);
- SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
- return code;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
-{
- switch (feature_type) {
- case SLJIT_HAS_FPU:
- case SLJIT_HAS_ZERO_REGISTER:
- return 1;
- default:
- return 0;
- }
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)
-{
- return (type >= SLJIT_ORDERED_EQUAL && type <= SLJIT_ORDERED_LESS_EQUAL);
-}
-
-/* --------------------------------------------------------------------- */
-/* Entry, exit */
-/* --------------------------------------------------------------------- */
-
-/* Creates an index in data_transfer_insts array. */
-#define LOAD_DATA 0x01
-#define WORD_DATA 0x00
-#define BYTE_DATA 0x02
-#define HALF_DATA 0x04
-#define INT_DATA 0x06
-#define SIGNED_DATA 0x08
-/* Separates integer and floating point registers */
-#define GPR_REG 0x0f
-#define DOUBLE_DATA 0x10
-#define SINGLE_DATA 0x12
-
-#define MEM_MASK 0x1f
-
-#define ARG_TEST 0x00020
-#define ALT_KEEP_CACHE 0x00040
-#define CUMULATIVE_OP 0x00080
-#define IMM_OP 0x00100
-#define MOVE_OP 0x00200
-#define SRC2_IMM 0x00400
-
-#define UNUSED_DEST 0x00800
-#define REG_DEST 0x01000
-#define REG1_SOURCE 0x02000
-#define REG2_SOURCE 0x04000
-#define SLOW_SRC1 0x08000
-#define SLOW_SRC2 0x10000
-#define SLOW_DEST 0x20000
-
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
-#define STACK_STORE SW
-#define STACK_LOAD LW
-#else
-#define STACK_STORE SD
-#define STACK_LOAD LD
-#endif
-
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
-#include "sljitNativeRISCV_32.c"
-#else
-#include "sljitNativeRISCV_64.c"
-#endif
-
-#define STACK_MAX_DISTANCE (-SIMM_MIN)
-
-static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw);
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- sljit_s32 i, tmp, offset;
- sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options);
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
- set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
-
- local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1);
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
- if ((local_size & SSIZE_OF(sw)) != 0)
- local_size += SSIZE_OF(sw);
- local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
- }
-#else
- local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
-#endif
- local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;
- compiler->local_size = local_size;
-
- if (local_size <= STACK_MAX_DISTANCE) {
- /* Frequent case. */
- FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(-local_size)));
- offset = local_size - SSIZE_OF(sw);
- local_size = 0;
- } else {
- FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(STACK_MAX_DISTANCE)));
- local_size -= STACK_MAX_DISTANCE;
-
- if (local_size > STACK_MAX_DISTANCE)
- FAIL_IF(load_immediate(compiler, TMP_REG1, local_size, TMP_REG3));
- offset = STACK_MAX_DISTANCE - SSIZE_OF(sw);
- }
-
- FAIL_IF(push_imm_s_inst(compiler, STACK_STORE | RS1(SLJIT_SP) | RS2(RETURN_ADDR_REG), offset));
-
- tmp = SLJIT_S0 - saveds;
- for (i = SLJIT_S0 - saved_arg_count; i > tmp; i--) {
- offset -= SSIZE_OF(sw);
- FAIL_IF(push_imm_s_inst(compiler, STACK_STORE | RS1(SLJIT_SP) | RS2(i), offset));
- }
-
- for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
- offset -= SSIZE_OF(sw);
- FAIL_IF(push_imm_s_inst(compiler, STACK_STORE | RS1(SLJIT_SP) | RS2(i), offset));
- }
-
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- /* This alignment is valid because offset is not used after storing FPU regs. */
- if ((offset & SSIZE_OF(sw)) != 0)
- offset -= SSIZE_OF(sw);
-#endif
-
- tmp = SLJIT_FS0 - fsaveds;
- for (i = SLJIT_FS0; i > tmp; i--) {
- offset -= SSIZE_OF(f64);
- FAIL_IF(push_imm_s_inst(compiler, FSD | RS1(SLJIT_SP) | FRS2(i), offset));
- }
-
- for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
- offset -= SSIZE_OF(f64);
- FAIL_IF(push_imm_s_inst(compiler, FSD | RS1(SLJIT_SP) | FRS2(i), offset));
- }
-
- if (local_size > STACK_MAX_DISTANCE)
- FAIL_IF(push_inst(compiler, SUB | RD(SLJIT_SP) | RS1(SLJIT_SP) | RS2(TMP_REG1)));
- else if (local_size > 0)
- FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(-local_size)));
-
- if (options & SLJIT_ENTER_REG_ARG)
- return SLJIT_SUCCESS;
-
- arg_types >>= SLJIT_ARG_SHIFT;
- saved_arg_count = 0;
- tmp = SLJIT_R0;
-
- while (arg_types > 0) {
- if ((arg_types & SLJIT_ARG_MASK) < SLJIT_ARG_TYPE_F64) {
- if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {
- FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_S0 - saved_arg_count) | RS1(tmp) | IMM_I(0)));
- saved_arg_count++;
- }
- tmp++;
- }
-
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- return SLJIT_SUCCESS;
-}
-
-#undef STACK_MAX_DISTANCE
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- CHECK_ERROR();
- CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
- set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
-
- local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1);
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
- if ((local_size & SSIZE_OF(sw)) != 0)
- local_size += SSIZE_OF(sw);
- local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
- }
-#else
- local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
-#endif
- compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;
-
- return SLJIT_SUCCESS;
-}
-
-#define STACK_MAX_DISTANCE (-SIMM_MIN - 16)
-
-static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 is_return_to)
-{
- sljit_s32 i, tmp, offset;
- sljit_s32 local_size = compiler->local_size;
-
- if (local_size > STACK_MAX_DISTANCE) {
- local_size -= STACK_MAX_DISTANCE;
-
- if (local_size > STACK_MAX_DISTANCE) {
- FAIL_IF(load_immediate(compiler, TMP_REG2, local_size, TMP_REG3));
- FAIL_IF(push_inst(compiler, ADD | RD(SLJIT_SP) | RS1(SLJIT_SP) | RS2(TMP_REG2)));
- } else
- FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(local_size)));
-
- local_size = STACK_MAX_DISTANCE;
- }
-
- SLJIT_ASSERT(local_size > 0);
-
- offset = local_size - SSIZE_OF(sw);
- if (!is_return_to)
- FAIL_IF(push_inst(compiler, STACK_LOAD | RD(RETURN_ADDR_REG) | RS1(SLJIT_SP) | IMM_I(offset)));
-
- tmp = SLJIT_S0 - compiler->saveds;
- for (i = SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options); i > tmp; i--) {
- offset -= SSIZE_OF(sw);
- FAIL_IF(push_inst(compiler, STACK_LOAD | RD(i) | RS1(SLJIT_SP) | IMM_I(offset)));
- }
-
- for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
- offset -= SSIZE_OF(sw);
- FAIL_IF(push_inst(compiler, STACK_LOAD | RD(i) | RS1(SLJIT_SP) | IMM_I(offset)));
- }
-
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- /* This alignment is valid because offset is not used after storing FPU regs. */
- if ((offset & SSIZE_OF(sw)) != 0)
- offset -= SSIZE_OF(sw);
-#endif
-
- tmp = SLJIT_FS0 - compiler->fsaveds;
- for (i = SLJIT_FS0; i > tmp; i--) {
- offset -= SSIZE_OF(f64);
- FAIL_IF(push_inst(compiler, FLD | FRD(i) | RS1(SLJIT_SP) | IMM_I(offset)));
- }
-
- for (i = compiler->fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
- offset -= SSIZE_OF(f64);
- FAIL_IF(push_inst(compiler, FLD | FRD(i) | RS1(SLJIT_SP) | IMM_I(offset)));
- }
-
- return push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(local_size));
-}
-
-#undef STACK_MAX_DISTANCE
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_return_void(compiler));
-
- FAIL_IF(emit_stack_frame_release(compiler, 0));
- return push_inst(compiler, JALR | RD(TMP_ZERO) | RS1(RETURN_ADDR_REG) | IMM_I(0));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,
- sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_return_to(compiler, src, srcw));
-
- if (src & SLJIT_MEM) {
- ADJUST_LOCAL_OFFSET(src, srcw);
- FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw));
- src = TMP_REG1;
- srcw = 0;
- } else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
- FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(src) | IMM_I(0)));
- src = TMP_REG1;
- srcw = 0;
- }
-
- FAIL_IF(emit_stack_frame_release(compiler, 1));
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);
-}
-
-/* --------------------------------------------------------------------- */
-/* Operators */
-/* --------------------------------------------------------------------- */
-
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
-#define ARCH_32_64(a, b) a
-#else
-#define ARCH_32_64(a, b) b
-#endif
-
-static const sljit_ins data_transfer_insts[16 + 4] = {
-/* u w s */ ARCH_32_64(F3(0x2) | OPC(0x23) /* sw */, F3(0x3) | OPC(0x23) /* sd */),
-/* u w l */ ARCH_32_64(F3(0x2) | OPC(0x3) /* lw */, F3(0x3) | OPC(0x3) /* ld */),
-/* u b s */ F3(0x0) | OPC(0x23) /* sb */,
-/* u b l */ F3(0x4) | OPC(0x3) /* lbu */,
-/* u h s */ F3(0x1) | OPC(0x23) /* sh */,
-/* u h l */ F3(0x5) | OPC(0x3) /* lhu */,
-/* u i s */ F3(0x2) | OPC(0x23) /* sw */,
-/* u i l */ ARCH_32_64(F3(0x2) | OPC(0x3) /* lw */, F3(0x6) | OPC(0x3) /* lwu */),
-
-/* s w s */ ARCH_32_64(F3(0x2) | OPC(0x23) /* sw */, F3(0x3) | OPC(0x23) /* sd */),
-/* s w l */ ARCH_32_64(F3(0x2) | OPC(0x3) /* lw */, F3(0x3) | OPC(0x3) /* ld */),
-/* s b s */ F3(0x0) | OPC(0x23) /* sb */,
-/* s b l */ F3(0x0) | OPC(0x3) /* lb */,
-/* s h s */ F3(0x1) | OPC(0x23) /* sh */,
-/* s h l */ F3(0x1) | OPC(0x3) /* lh */,
-/* s i s */ F3(0x2) | OPC(0x23) /* sw */,
-/* s i l */ F3(0x2) | OPC(0x3) /* lw */,
-
-/* d s */ F3(0x3) | OPC(0x27) /* fsd */,
-/* d l */ F3(0x3) | OPC(0x7) /* fld */,
-/* s s */ F3(0x2) | OPC(0x27) /* fsw */,
-/* s l */ F3(0x2) | OPC(0x7) /* flw */,
-};
-
-#undef ARCH_32_64
-
-static sljit_s32 push_mem_inst(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 base, sljit_sw offset)
-{
- sljit_ins ins;
-
- SLJIT_ASSERT(FAST_IS_REG(base) && offset <= 0xfff && offset >= SIMM_MIN);
-
- ins = data_transfer_insts[flags & MEM_MASK] | RS1(base);
- if (flags & LOAD_DATA)
- ins |= ((flags & MEM_MASK) <= GPR_REG ? RD(reg) : FRD(reg)) | IMM_I(offset);
- else
- ins |= ((flags & MEM_MASK) <= GPR_REG ? RS2(reg) : FRS2(reg)) | IMM_S(offset);
-
- return push_inst(compiler, ins);
-}
-
-/* Can perform an operation using at most 1 instruction. */
-static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
-{
-
- SLJIT_ASSERT(arg & SLJIT_MEM);
-
- if (!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN) {
- /* Works for both absoulte and relative addresses. */
- if (SLJIT_UNLIKELY(flags & ARG_TEST))
- return 1;
-
- FAIL_IF(push_mem_inst(compiler, flags, reg, arg & REG_MASK, argw));
- return -1;
- }
- return 0;
-}
-
-#define TO_ARGW_HI(argw) (((argw) & ~0xfff) + (((argw) & 0x800) ? 0x1000 : 0))
-
-/* See getput_arg below.
- Note: can_cache is called only for binary operators. */
-static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
-{
- SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
-
- /* Simple operation except for updates. */
- if (arg & OFFS_REG_MASK) {
- argw &= 0x3;
- next_argw &= 0x3;
- if (argw && argw == next_argw && (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK)))
- return 1;
- return 0;
- }
-
- if (arg == next_arg) {
- if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN)
- || TO_ARGW_HI(argw) == TO_ARGW_HI(next_argw))
- return 1;
- return 0;
- }
-
- return 0;
-}
-
-/* Emit the necessary instructions. See can_cache above. */
-static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
-{
- sljit_s32 base = arg & REG_MASK;
- sljit_s32 tmp_r = TMP_REG1;
- sljit_sw offset, argw_hi;
-
- SLJIT_ASSERT(arg & SLJIT_MEM);
- if (!(next_arg & SLJIT_MEM)) {
- next_arg = 0;
- next_argw = 0;
- }
-
- /* Since tmp can be the same as base or offset registers,
- * these might be unavailable after modifying tmp. */
- if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA))
- tmp_r = reg;
-
- if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
- argw &= 0x3;
-
- /* Using the cache. */
- if (argw == compiler->cache_argw) {
- if (arg == compiler->cache_arg)
- return push_mem_inst(compiler, flags, reg, TMP_REG3, 0);
-
- if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {
- if (arg == next_arg && argw == (next_argw & 0x3)) {
- compiler->cache_arg = arg;
- compiler->cache_argw = argw;
- FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG3) | RS1(TMP_REG3) | RS2(base)));
- return push_mem_inst(compiler, flags, reg, TMP_REG3, 0);
- }
- FAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RS1(base) | RS2(TMP_REG3)));
- return push_mem_inst(compiler, flags, reg, tmp_r, 0);
- }
- }
-
- if (SLJIT_UNLIKELY(argw)) {
- compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);
- compiler->cache_argw = argw;
- FAIL_IF(push_inst(compiler, SLLI | RD(TMP_REG3) | RS1(OFFS_REG(arg)) | IMM_I(argw)));
- }
-
- if (arg == next_arg && argw == (next_argw & 0x3)) {
- compiler->cache_arg = arg;
- compiler->cache_argw = argw;
- FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG3) | RS1(base) | RS2(!argw ? OFFS_REG(arg) : TMP_REG3)));
- tmp_r = TMP_REG3;
- }
- else
- FAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RS1(base) | RS2(!argw ? OFFS_REG(arg) : TMP_REG3)));
- return push_mem_inst(compiler, flags, reg, tmp_r, 0);
- }
-
- if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN)
- return push_mem_inst(compiler, flags, reg, TMP_REG3, argw - compiler->cache_argw);
-
- if (compiler->cache_arg == SLJIT_MEM && (argw - compiler->cache_argw <= SIMM_MAX) && (argw - compiler->cache_argw >= SIMM_MIN)) {
- offset = argw - compiler->cache_argw;
- } else {
- compiler->cache_arg = SLJIT_MEM;
-
- argw_hi = TO_ARGW_HI(argw);
-
- if (next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN && argw_hi != TO_ARGW_HI(next_argw)) {
- FAIL_IF(load_immediate(compiler, TMP_REG3, argw, tmp_r));
- compiler->cache_argw = argw;
- offset = 0;
- } else {
- FAIL_IF(load_immediate(compiler, TMP_REG3, argw_hi, tmp_r));
- compiler->cache_argw = argw_hi;
- offset = argw & 0xfff;
- argw = argw_hi;
- }
- }
-
- if (!base)
- return push_mem_inst(compiler, flags, reg, TMP_REG3, offset);
-
- if (arg == next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN) {
- compiler->cache_arg = arg;
- FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG3) | RS1(TMP_REG3) | RS2(base)));
- return push_mem_inst(compiler, flags, reg, TMP_REG3, offset);
- }
-
- FAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RS1(TMP_REG3) | RS2(base)));
- return push_mem_inst(compiler, flags, reg, tmp_r, offset);
-}
-
-static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
-{
- sljit_s32 base = arg & REG_MASK;
- sljit_s32 tmp_r = TMP_REG1;
-
- if (getput_arg_fast(compiler, flags, reg, arg, argw))
- return compiler->error;
-
- if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA))
- tmp_r = reg;
-
- if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
- argw &= 0x3;
-
- if (SLJIT_UNLIKELY(argw)) {
- FAIL_IF(push_inst(compiler, SLLI | RD(tmp_r) | RS1(OFFS_REG(arg)) | IMM_I(argw)));
- FAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RS1(tmp_r) | RS2(base)));
- }
- else
- FAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RS1(base) | RS2(OFFS_REG(arg))));
-
- argw = 0;
- } else {
- FAIL_IF(load_immediate(compiler, tmp_r, TO_ARGW_HI(argw), TMP_REG3));
-
- if (base != 0)
- FAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RS1(tmp_r) | RS2(base)));
- }
-
- return push_mem_inst(compiler, flags, reg, tmp_r, argw & 0xfff);
-}
-
-static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
-{
- if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
- return compiler->error;
- return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
-}
-
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
-#define WORD 0
-#define IMM_EXTEND(v) (IMM_I(v))
-#else /* !SLJIT_CONFIG_RISCV_32 */
-#define WORD word
-#define IMM_EXTEND(v) (IMM_I((op & SLJIT_32) ? (v) : (32 + (v))))
-#endif /* SLJIT_CONFIG_RISCV_32 */
-
-static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src)
-{
- sljit_s32 is_clz = (GET_OPCODE(op) == SLJIT_CLZ);
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
- sljit_ins word = (op & SLJIT_32) >> 5;
- sljit_ins max = (op & SLJIT_32) ? 32 : 64;
-#else /* !SLJIT_CONFIG_RISCV_64 */
- sljit_ins max = 32;
-#endif /* SLJIT_CONFIG_RISCV_64 */
-
- SLJIT_ASSERT(WORD == 0 || WORD == 0x8);
-
- /* The OTHER_FLAG is the counter. */
- FAIL_IF(push_inst(compiler, ADDI | WORD | RD(OTHER_FLAG) | RS1(TMP_ZERO) | IMM_I(max)));
-
- /* The TMP_REG2 is the next value. */
- if (src != TMP_REG2)
- FAIL_IF(push_inst(compiler, ADDI | WORD | RD(TMP_REG2) | RS1(src) | IMM_I(0)));
-
- FAIL_IF(push_inst(compiler, BEQ | RS1(TMP_REG2) | RS2(TMP_ZERO) | ((sljit_ins)((is_clz ? 4 : 5) * SSIZE_OF(ins)) << 7) | ((sljit_ins)(8 * SSIZE_OF(ins)) << 20)));
-
- FAIL_IF(push_inst(compiler, ADDI | WORD | RD(OTHER_FLAG) | RS1(TMP_ZERO) | IMM_I(0)));
- if (!is_clz) {
- FAIL_IF(push_inst(compiler, ANDI | RD(TMP_REG1) | RS1(TMP_REG2) | IMM_I(1)));
- FAIL_IF(push_inst(compiler, BNE | RS1(TMP_REG1) | RS2(TMP_ZERO) | ((sljit_ins)(2 * SSIZE_OF(ins)) << 7) | ((sljit_ins)(8 * SSIZE_OF(ins)) << 20)));
- } else
- FAIL_IF(push_inst(compiler, BLT | RS1(TMP_REG2) | RS2(TMP_ZERO) | ((sljit_ins)(2 * SSIZE_OF(ins)) << 7) | ((sljit_ins)(8 * SSIZE_OF(ins)) << 20)));
-
- /* The TMP_REG1 is the next shift. */
- FAIL_IF(push_inst(compiler, ADDI | WORD | RD(TMP_REG1) | RS1(TMP_ZERO) | IMM_I(max)));
-
- FAIL_IF(push_inst(compiler, ADDI | WORD | RD(EQUAL_FLAG) | RS1(TMP_REG2) | IMM_I(0)));
- FAIL_IF(push_inst(compiler, SRLI | WORD | RD(TMP_REG1) | RS1(TMP_REG1) | IMM_I(1)));
-
- FAIL_IF(push_inst(compiler, (is_clz ? SRL : SLL) | WORD | RD(TMP_REG2) | RS1(EQUAL_FLAG) | RS2(TMP_REG1)));
- FAIL_IF(push_inst(compiler, BNE | RS1(TMP_REG2) | RS2(TMP_ZERO) | ((sljit_ins)0xfe000e80 - ((2 * SSIZE_OF(ins)) << 7))));
- FAIL_IF(push_inst(compiler, ADDI | WORD | RD(TMP_REG2) | RS1(TMP_REG1) | IMM_I(-1)));
- FAIL_IF(push_inst(compiler, (is_clz ? SRL : SLL) | WORD | RD(TMP_REG2) | RS1(EQUAL_FLAG) | RS2(TMP_REG2)));
- FAIL_IF(push_inst(compiler, OR | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | RS2(TMP_REG1)));
- FAIL_IF(push_inst(compiler, BEQ | RS1(TMP_REG2) | RS2(TMP_ZERO) | ((sljit_ins)0xfe000e80 - ((5 * SSIZE_OF(ins)) << 7))));
-
- return push_inst(compiler, ADDI | WORD | RD(dst) | RS1(OTHER_FLAG) | IMM_I(0));
-}
-
-#define EMIT_LOGICAL(op_imm, op_reg) \
- if (flags & SRC2_IMM) { \
- if (op & SLJIT_SET_Z) \
- FAIL_IF(push_inst(compiler, op_imm | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(src2))); \
- if (!(flags & UNUSED_DEST)) \
- FAIL_IF(push_inst(compiler, op_imm | RD(dst) | RS1(src1) | IMM_I(src2))); \
- } \
- else { \
- if (op & SLJIT_SET_Z) \
- FAIL_IF(push_inst(compiler, op_reg | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2))); \
- if (!(flags & UNUSED_DEST)) \
- FAIL_IF(push_inst(compiler, op_reg | RD(dst) | RS1(src1) | RS2(src2))); \
- }
-
-#define EMIT_SHIFT(imm, reg) \
- op_imm = (imm); \
- op_reg = (reg);
-
-static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
- sljit_s32 dst, sljit_s32 src1, sljit_sw src2)
-{
- sljit_s32 is_overflow, is_carry, carry_src_r, is_handled;
- sljit_ins op_imm, op_reg;
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
- sljit_ins word = (op & SLJIT_32) >> 5;
-#endif /* SLJIT_CONFIG_RISCV_64 */
-
- SLJIT_ASSERT(WORD == 0 || WORD == 0x8);
-
- switch (GET_OPCODE(op)) {
- case SLJIT_MOV:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if (dst != src2)
- return push_inst(compiler, ADDI | RD(dst) | RS1(src2) | IMM_I(0));
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_U8:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
- return push_inst(compiler, ANDI | RD(dst) | RS1(src2) | IMM_I(0xff));
- SLJIT_ASSERT(dst == src2);
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_S8:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
- FAIL_IF(push_inst(compiler, SLLI | WORD | RD(dst) | RS1(src2) | IMM_EXTEND(24)));
- return push_inst(compiler, SRAI | WORD | RD(dst) | RS1(dst) | IMM_EXTEND(24));
- }
- SLJIT_ASSERT(dst == src2);
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_U16:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
- FAIL_IF(push_inst(compiler, SLLI | WORD | RD(dst) | RS1(src2) | IMM_EXTEND(16)));
- return push_inst(compiler, SRLI | WORD | RD(dst) | RS1(dst) | IMM_EXTEND(16));
- }
- SLJIT_ASSERT(dst == src2);
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_S16:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
- FAIL_IF(push_inst(compiler, SLLI | WORD | RD(dst) | RS1(src2) | IMM_EXTEND(16)));
- return push_inst(compiler, SRAI | WORD | RD(dst) | RS1(dst) | IMM_EXTEND(16));
- }
- SLJIT_ASSERT(dst == src2);
- return SLJIT_SUCCESS;
-
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
- case SLJIT_MOV_U32:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
- FAIL_IF(push_inst(compiler, SLLI | RD(dst) | RS1(src2) | IMM_I(32)));
- return push_inst(compiler, SRLI | RD(dst) | RS1(dst) | IMM_I(32));
- }
- SLJIT_ASSERT(dst == src2);
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_S32:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
- return push_inst(compiler, ADDI | 0x8 | RD(dst) | RS1(src2) | IMM_I(0));
- SLJIT_ASSERT(dst == src2);
- return SLJIT_SUCCESS;
-#endif /* SLJIT_CONFIG_RISCV_64 */
-
- case SLJIT_CLZ:
- case SLJIT_CTZ:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- return emit_clz_ctz(compiler, op, dst, src2);
-
- case SLJIT_ADD:
- /* Overflow computation (both add and sub): overflow = src1_sign ^ src2_sign ^ result_sign ^ carry_flag */
- is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;
- carry_src_r = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);
-
- if (flags & SRC2_IMM) {
- if (is_overflow) {
- if (src2 >= 0)
- FAIL_IF(push_inst(compiler, ADDI | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(0)));
- else
- FAIL_IF(push_inst(compiler, XORI | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(-1)));
- }
- else if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, ADDI | WORD | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(src2)));
-
- /* Only the zero flag is needed. */
- if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
- FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(src2)));
- }
- else {
- if (is_overflow)
- FAIL_IF(push_inst(compiler, XOR | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2)));
- else if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, ADD | WORD | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2)));
-
- if (is_overflow || carry_src_r != 0) {
- if (src1 != dst)
- carry_src_r = (sljit_s32)src1;
- else if (src2 != dst)
- carry_src_r = (sljit_s32)src2;
- else {
- FAIL_IF(push_inst(compiler, ADDI | RD(OTHER_FLAG) | RS1(src1) | IMM_I(0)));
- carry_src_r = OTHER_FLAG;
- }
- }
-
- /* Only the zero flag is needed. */
- if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
- FAIL_IF(push_inst(compiler, ADD | WORD | RD(dst) | RS1(src1) | RS2(src2)));
- }
-
- /* Carry is zero if a + b >= a or a + b >= b, otherwise it is 1. */
- if (is_overflow || carry_src_r != 0) {
- if (flags & SRC2_IMM)
- FAIL_IF(push_inst(compiler, SLTUI | RD(OTHER_FLAG) | RS1(dst) | IMM_I(src2)));
- else
- FAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RS1(dst) | RS2(carry_src_r)));
- }
-
- if (!is_overflow)
- return SLJIT_SUCCESS;
-
- FAIL_IF(push_inst(compiler, XOR | RD(TMP_REG1) | RS1(dst) | RS2(EQUAL_FLAG)));
- if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, ADDI | RD(EQUAL_FLAG) | RS1(dst) | IMM_I(0)));
- FAIL_IF(push_inst(compiler, SRLI | WORD | RD(TMP_REG1) | RS1(TMP_REG1) | IMM_EXTEND(31)));
- return push_inst(compiler, XOR | RD(OTHER_FLAG) | RS1(TMP_REG1) | RS2(OTHER_FLAG));
-
- case SLJIT_ADDC:
- carry_src_r = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);
-
- if (flags & SRC2_IMM) {
- FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(src2)));
- } else {
- if (carry_src_r != 0) {
- if (src1 != dst)
- carry_src_r = (sljit_s32)src1;
- else if (src2 != dst)
- carry_src_r = (sljit_s32)src2;
- else {
- FAIL_IF(push_inst(compiler, ADDI | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(0)));
- carry_src_r = EQUAL_FLAG;
- }
- }
-
- FAIL_IF(push_inst(compiler, ADD | WORD | RD(dst) | RS1(src1) | RS2(src2)));
- }
-
- /* Carry is zero if a + b >= a or a + b >= b, otherwise it is 1. */
- if (carry_src_r != 0) {
- if (flags & SRC2_IMM)
- FAIL_IF(push_inst(compiler, SLTUI | RD(EQUAL_FLAG) | RS1(dst) | IMM_I(src2)));
- else
- FAIL_IF(push_inst(compiler, SLTU | RD(EQUAL_FLAG) | RS1(dst) | RS2(carry_src_r)));
- }
-
- FAIL_IF(push_inst(compiler, ADD | WORD | RD(dst) | RS1(dst) | RS2(OTHER_FLAG)));
-
- if (carry_src_r == 0)
- return SLJIT_SUCCESS;
-
- /* Set ULESS_FLAG (dst == 0) && (OTHER_FLAG == 1). */
- FAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RS1(dst) | RS2(OTHER_FLAG)));
- /* Set carry flag. */
- return push_inst(compiler, OR | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | RS2(EQUAL_FLAG));
-
- case SLJIT_SUB:
- if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
- FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG2) | RS1(TMP_ZERO) | IMM_I(src2)));
- src2 = TMP_REG2;
- flags &= ~SRC2_IMM;
- }
-
- is_handled = 0;
-
- if (flags & SRC2_IMM) {
- if (GET_FLAG_TYPE(op) == SLJIT_LESS || GET_FLAG_TYPE(op) == SLJIT_GREATER_EQUAL) {
- FAIL_IF(push_inst(compiler, SLTUI | RD(OTHER_FLAG) | RS1(src1) | IMM_I(src2)));
- is_handled = 1;
- }
- else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS || GET_FLAG_TYPE(op) == SLJIT_SIG_GREATER_EQUAL) {
- FAIL_IF(push_inst(compiler, SLTI | RD(OTHER_FLAG) | RS1(src1) | IMM_I(src2)));
- is_handled = 1;
- }
- }
-
- if (!is_handled && GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL) {
- is_handled = 1;
-
- if (flags & SRC2_IMM) {
- FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG2) | RS1(TMP_ZERO) | IMM_I(src2)));
- src2 = TMP_REG2;
- flags &= ~SRC2_IMM;
- }
-
- switch (GET_FLAG_TYPE(op)) {
- case SLJIT_LESS:
- case SLJIT_GREATER_EQUAL:
- FAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RS1(src1) | RS2(src2)));
- break;
- case SLJIT_GREATER:
- case SLJIT_LESS_EQUAL:
- FAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RS1(src2) | RS2(src1)));
- break;
- case SLJIT_SIG_LESS:
- case SLJIT_SIG_GREATER_EQUAL:
- FAIL_IF(push_inst(compiler, SLT | RD(OTHER_FLAG) | RS1(src1) | RS2(src2)));
- break;
- case SLJIT_SIG_GREATER:
- case SLJIT_SIG_LESS_EQUAL:
- FAIL_IF(push_inst(compiler, SLT | RD(OTHER_FLAG) | RS1(src2) | RS2(src1)));
- break;
- }
- }
-
- if (is_handled) {
- if (flags & SRC2_IMM) {
- if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, ADDI | WORD | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(-src2)));
- if (!(flags & UNUSED_DEST))
- return push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(-src2));
- }
- else {
- if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, SUB | WORD | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2)));
- if (!(flags & UNUSED_DEST))
- return push_inst(compiler, SUB | WORD | RD(dst) | RS1(src1) | RS2(src2));
- }
- return SLJIT_SUCCESS;
- }
-
- is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;
- is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);
-
- if (flags & SRC2_IMM) {
- if (is_overflow) {
- if (src2 >= 0)
- FAIL_IF(push_inst(compiler, ADDI | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(0)));
- else
- FAIL_IF(push_inst(compiler, XORI | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(-1)));
- }
- else if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, ADDI | WORD | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(-src2)));
-
- if (is_overflow || is_carry)
- FAIL_IF(push_inst(compiler, SLTUI | RD(OTHER_FLAG) | RS1(src1) | IMM_I(src2)));
-
- /* Only the zero flag is needed. */
- if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
- FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(-src2)));
- }
- else {
- if (is_overflow)
- FAIL_IF(push_inst(compiler, XOR | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2)));
- else if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, SUB | WORD | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2)));
-
- if (is_overflow || is_carry)
- FAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RS1(src1) | RS2(src2)));
-
- /* Only the zero flag is needed. */
- if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
- FAIL_IF(push_inst(compiler, SUB | WORD | RD(dst) | RS1(src1) | RS2(src2)));
- }
-
- if (!is_overflow)
- return SLJIT_SUCCESS;
-
- FAIL_IF(push_inst(compiler, XOR | RD(TMP_REG1) | RS1(dst) | RS2(EQUAL_FLAG)));
- if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, ADDI | RD(EQUAL_FLAG) | RS1(dst) | IMM_I(0)));
- FAIL_IF(push_inst(compiler, SRLI | WORD | RD(TMP_REG1) | RS1(TMP_REG1) | IMM_EXTEND(31)));
- return push_inst(compiler, XOR | RD(OTHER_FLAG) | RS1(TMP_REG1) | RS2(OTHER_FLAG));
-
- case SLJIT_SUBC:
- if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
- FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG2) | RS1(TMP_ZERO) | IMM_I(src2)));
- src2 = TMP_REG2;
- flags &= ~SRC2_IMM;
- }
-
- is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);
-
- if (flags & SRC2_IMM) {
- if (is_carry)
- FAIL_IF(push_inst(compiler, SLTUI | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(src2)));
-
- FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(-src2)));
- }
- else {
- if (is_carry)
- FAIL_IF(push_inst(compiler, SLTU | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2)));
-
- FAIL_IF(push_inst(compiler, SUB | WORD | RD(dst) | RS1(src1) | RS2(src2)));
- }
-
- if (is_carry)
- FAIL_IF(push_inst(compiler, SLTU | RD(TMP_REG1) | RS1(dst) | RS2(OTHER_FLAG)));
-
- FAIL_IF(push_inst(compiler, SUB | WORD | RD(dst) | RS1(dst) | RS2(OTHER_FLAG)));
-
- if (!is_carry)
- return SLJIT_SUCCESS;
-
- return push_inst(compiler, OR | RD(OTHER_FLAG) | RS1(EQUAL_FLAG) | RS2(TMP_REG1));
-
- case SLJIT_MUL:
- SLJIT_ASSERT(!(flags & SRC2_IMM));
-
- if (GET_FLAG_TYPE(op) != SLJIT_OVERFLOW)
- return push_inst(compiler, MUL | WORD | RD(dst) | RS1(src1) | RS2(src2));
-
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
- if (word) {
- FAIL_IF(push_inst(compiler, MUL | RD(OTHER_FLAG) | RS1(src1) | RS2(src2)));
- FAIL_IF(push_inst(compiler, MUL | 0x8 | RD(dst) | RS1(src1) | RS2(src2)));
- return push_inst(compiler, SUB | RD(OTHER_FLAG) | RS1(dst) | RS2(OTHER_FLAG));
- }
-#endif /* SLJIT_CONFIG_RISCV_64 */
-
- FAIL_IF(push_inst(compiler, MULH | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2)));
- FAIL_IF(push_inst(compiler, MUL | RD(dst) | RS1(src1) | RS2(src2)));
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- FAIL_IF(push_inst(compiler, SRAI | RD(OTHER_FLAG) | RS1(dst) | IMM_I(31)));
-#else /* !SLJIT_CONFIG_RISCV_32 */
- FAIL_IF(push_inst(compiler, SRAI | RD(OTHER_FLAG) | RS1(dst) | IMM_I(63)));
-#endif /* SLJIT_CONFIG_RISCV_32 */
- return push_inst(compiler, SUB | RD(OTHER_FLAG) | RS1(EQUAL_FLAG) | RS2(OTHER_FLAG));
-
- case SLJIT_AND:
- EMIT_LOGICAL(ANDI, AND);
- return SLJIT_SUCCESS;
-
- case SLJIT_OR:
- EMIT_LOGICAL(ORI, OR);
- return SLJIT_SUCCESS;
-
- case SLJIT_XOR:
- EMIT_LOGICAL(XORI, XOR);
- return SLJIT_SUCCESS;
-
- case SLJIT_SHL:
- case SLJIT_MSHL:
- EMIT_SHIFT(SLLI, SLL);
- break;
-
- case SLJIT_LSHR:
- case SLJIT_MLSHR:
- EMIT_SHIFT(SRLI, SRL);
- break;
-
- case SLJIT_ASHR:
- case SLJIT_MASHR:
- EMIT_SHIFT(SRAI, SRA);
- break;
-
- case SLJIT_ROTL:
- case SLJIT_ROTR:
- if (flags & SRC2_IMM) {
- SLJIT_ASSERT(src2 != 0);
-
- op_imm = (GET_OPCODE(op) == SLJIT_ROTL) ? SLLI : SRLI;
- FAIL_IF(push_inst(compiler, op_imm | WORD | RD(OTHER_FLAG) | RS1(src1) | IMM_I(src2)));
-
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
- src2 = ((op & SLJIT_32) ? 32 : 64) - src2;
-#else /* !SLJIT_CONFIG_RISCV_64 */
- src2 = 32 - src2;
-#endif /* SLJIT_CONFIG_RISCV_64 */
- op_imm = (GET_OPCODE(op) == SLJIT_ROTL) ? SRLI : SLLI;
- FAIL_IF(push_inst(compiler, op_imm | WORD | RD(dst) | RS1(src1) | IMM_I(src2)));
- return push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(OTHER_FLAG));
- }
-
- if (src2 == TMP_ZERO) {
- if (dst != src1)
- return push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(0));
- return SLJIT_SUCCESS;
- }
-
- FAIL_IF(push_inst(compiler, SUB | WORD | RD(EQUAL_FLAG) | RS1(TMP_ZERO) | RS2(src2)));
- op_reg = (GET_OPCODE(op) == SLJIT_ROTL) ? SLL : SRL;
- FAIL_IF(push_inst(compiler, op_reg | WORD | RD(OTHER_FLAG) | RS1(src1) | RS2(src2)));
- op_reg = (GET_OPCODE(op) == SLJIT_ROTL) ? SRL : SLL;
- FAIL_IF(push_inst(compiler, op_reg | WORD | RD(dst) | RS1(src1) | RS2(EQUAL_FLAG)));
- return push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(OTHER_FLAG));
-
- default:
- SLJIT_UNREACHABLE();
- return SLJIT_SUCCESS;
- }
-
- if (flags & SRC2_IMM) {
- if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, op_imm | WORD | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(src2)));
-
- if (flags & UNUSED_DEST)
- return SLJIT_SUCCESS;
- return push_inst(compiler, op_imm | WORD | RD(dst) | RS1(src1) | IMM_I(src2));
- }
-
- if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, op_reg | WORD | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2)));
-
- if (flags & UNUSED_DEST)
- return SLJIT_SUCCESS;
- return push_inst(compiler, op_reg | WORD | RD(dst) | RS1(src1) | RS2(src2));
-}
-
-#undef IMM_EXTEND
-
-static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- /* arg1 goes to TMP_REG1 or src reg
- arg2 goes to TMP_REG2, imm or src reg
- TMP_REG3 can be used for caching
- result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
- sljit_s32 dst_r = TMP_REG2;
- sljit_s32 src1_r;
- sljit_sw src2_r = 0;
- sljit_s32 sugg_src2_r = TMP_REG2;
-
- if (!(flags & ALT_KEEP_CACHE)) {
- compiler->cache_arg = 0;
- compiler->cache_argw = 0;
- }
-
- if (dst == TMP_REG2) {
- SLJIT_ASSERT(HAS_FLAGS(op));
- flags |= UNUSED_DEST;
- }
- else if (FAST_IS_REG(dst)) {
- dst_r = dst;
- flags |= REG_DEST;
- if (flags & MOVE_OP)
- sugg_src2_r = dst_r;
- }
- else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw))
- flags |= SLOW_DEST;
-
- if (flags & IMM_OP) {
- if ((src2 & SLJIT_IMM) && src2w != 0 && src2w <= SIMM_MAX && src2w >= SIMM_MIN) {
- flags |= SRC2_IMM;
- src2_r = src2w;
- }
- else if ((flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w != 0 && src1w <= SIMM_MAX && src1w >= SIMM_MIN) {
- flags |= SRC2_IMM;
- src2_r = src1w;
-
- /* And swap arguments. */
- src1 = src2;
- src1w = src2w;
- src2 = SLJIT_IMM;
- /* src2w = src2_r unneeded. */
- }
- }
-
- /* Source 1. */
- if (FAST_IS_REG(src1)) {
- src1_r = src1;
- flags |= REG1_SOURCE;
- }
- else if (src1 & SLJIT_IMM) {
- if (src1w) {
- FAIL_IF(load_immediate(compiler, TMP_REG1, src1w, TMP_REG3));
- src1_r = TMP_REG1;
- }
- else
- src1_r = TMP_ZERO;
- }
- else {
- if (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w))
- FAIL_IF(compiler->error);
- else
- flags |= SLOW_SRC1;
- src1_r = TMP_REG1;
- }
-
- /* Source 2. */
- if (FAST_IS_REG(src2)) {
- src2_r = src2;
- flags |= REG2_SOURCE;
- if ((flags & (REG_DEST | MOVE_OP)) == MOVE_OP)
- dst_r = (sljit_s32)src2_r;
- }
- else if (src2 & SLJIT_IMM) {
- if (!(flags & SRC2_IMM)) {
- if (src2w) {
- FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w, TMP_REG3));
- src2_r = sugg_src2_r;
- }
- else {
- src2_r = TMP_ZERO;
- if (flags & MOVE_OP) {
- if (dst & SLJIT_MEM)
- dst_r = 0;
- else
- op = SLJIT_MOV;
- }
- }
- }
- }
- else {
- if (getput_arg_fast(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w))
- FAIL_IF(compiler->error);
- else
- flags |= SLOW_SRC2;
- src2_r = sugg_src2_r;
- }
-
- if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
- SLJIT_ASSERT(src2_r == TMP_REG2);
- if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w));
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
- }
- else {
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw));
- }
- }
- else if (flags & SLOW_SRC1)
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
- else if (flags & SLOW_SRC2)
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw));
-
- FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
-
- if (dst & SLJIT_MEM) {
- if (!(flags & SLOW_DEST)) {
- getput_arg_fast(compiler, flags, dst_r, dst, dstw);
- return compiler->error;
- }
- return getput_arg(compiler, flags, dst_r, dst, dstw, 0, 0);
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
-{
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
- sljit_ins word = (op & SLJIT_32) >> 5;
-
- SLJIT_ASSERT(word == 0 || word == 0x8);
-#endif /* SLJIT_CONFIG_RISCV_64 */
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op0(compiler, op));
-
- switch (GET_OPCODE(op)) {
- case SLJIT_BREAKPOINT:
- return push_inst(compiler, EBREAK);
- case SLJIT_NOP:
- return push_inst(compiler, ADDI | RD(TMP_ZERO) | RS1(TMP_ZERO) | IMM_I(0));
- case SLJIT_LMUL_UW:
- FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(SLJIT_R1) | IMM_I(0)));
- FAIL_IF(push_inst(compiler, MULHU | RD(SLJIT_R1) | RS1(SLJIT_R0) | RS2(SLJIT_R1)));
- return push_inst(compiler, MUL | RD(SLJIT_R0) | RS1(SLJIT_R0) | RS2(TMP_REG1));
- case SLJIT_LMUL_SW:
- FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(SLJIT_R1) | IMM_I(0)));
- FAIL_IF(push_inst(compiler, MULH | RD(SLJIT_R1) | RS1(SLJIT_R0) | RS2(SLJIT_R1)));
- return push_inst(compiler, MUL | RD(SLJIT_R0) | RS1(SLJIT_R0) | RS2(TMP_REG1));
- case SLJIT_DIVMOD_UW:
- FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(SLJIT_R0) | IMM_I(0)));
- FAIL_IF(push_inst(compiler, DIVU | WORD | RD(SLJIT_R0) | RS1(SLJIT_R0) | RS2(SLJIT_R1)));
- return push_inst(compiler, REMU | WORD | RD(SLJIT_R1) | RS1(TMP_REG1) | RS2(SLJIT_R1));
- case SLJIT_DIVMOD_SW:
- FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(SLJIT_R0) | IMM_I(0)));
- FAIL_IF(push_inst(compiler, DIV | WORD | RD(SLJIT_R0) | RS1(SLJIT_R0) | RS2(SLJIT_R1)));
- return push_inst(compiler, REM | WORD | RD(SLJIT_R1) | RS1(TMP_REG1) | RS2(SLJIT_R1));
- case SLJIT_DIV_UW:
- return push_inst(compiler, DIVU | WORD | RD(SLJIT_R0) | RS1(SLJIT_R0) | RS2(SLJIT_R1));
- case SLJIT_DIV_SW:
- return push_inst(compiler, DIV | WORD | RD(SLJIT_R0) | RS1(SLJIT_R0) | RS2(SLJIT_R1));
- case SLJIT_ENDBR:
- case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
- return SLJIT_SUCCESS;
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 flags = 0;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src, srcw);
-
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
- if (op & SLJIT_32)
- flags = INT_DATA | SIGNED_DATA;
-#endif
-
- switch (GET_OPCODE(op)) {
- case SLJIT_MOV:
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- case SLJIT_MOV_U32:
- case SLJIT_MOV_S32:
- case SLJIT_MOV32:
-#endif
- case SLJIT_MOV_P:
- return emit_op(compiler, SLJIT_MOV, WORD_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, srcw);
-
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
- case SLJIT_MOV_U32:
- return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u32)srcw : srcw);
-
- case SLJIT_MOV_S32:
- /* Logical operators have no W variant, so sign extended input is necessary for them. */
- case SLJIT_MOV32:
- return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s32)srcw : srcw);
-#endif
-
- case SLJIT_MOV_U8:
- return emit_op(compiler, op, BYTE_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
-
- case SLJIT_MOV_S8:
- return emit_op(compiler, op, BYTE_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
-
- case SLJIT_MOV_U16:
- return emit_op(compiler, op, HALF_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
-
- case SLJIT_MOV_S16:
- return emit_op(compiler, op, HALF_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
-
- case SLJIT_NOT:
- return emit_op(compiler, SLJIT_XOR | (op & (SLJIT_32 | SLJIT_SET_Z)), flags, dst, dstw, src, srcw, SLJIT_IMM, -1);
-
- case SLJIT_CLZ:
- case SLJIT_CTZ:
- return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
- }
-
- SLJIT_UNREACHABLE();
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 flags = 0;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
- if (op & SLJIT_32) {
- flags |= INT_DATA | SIGNED_DATA;
- if (src1 & SLJIT_IMM)
- src1w = (sljit_s32)src1w;
- if (src2 & SLJIT_IMM)
- src2w = (sljit_s32)src2w;
- }
-#endif
-
- switch (GET_OPCODE(op)) {
- case SLJIT_ADD:
- case SLJIT_ADDC:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;
- return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_SUB:
- case SLJIT_SUBC:
- compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;
- return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_MUL:
- compiler->status_flags_state = 0;
- return emit_op(compiler, op, flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_AND:
- case SLJIT_OR:
- case SLJIT_XOR:
- return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_SHL:
- case SLJIT_MSHL:
- case SLJIT_LSHR:
- case SLJIT_MLSHR:
- case SLJIT_ASHR:
- case SLJIT_MASHR:
- case SLJIT_ROTL:
- case SLJIT_ROTR:
- if (src2 & SLJIT_IMM) {
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- src2w &= 0x1f;
-#else /* !SLJIT_CONFIG_RISCV_32 */
- if (op & SLJIT_32)
- src2w &= 0x1f;
- else
- src2w &= 0x3f;
-#endif /* SLJIT_CONFIG_RISCV_32 */
- }
-
- return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
- }
-
- SLJIT_UNREACHABLE();
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_op2(compiler, op, TMP_REG2, 0, src1, src1w, src2, src2w);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src_dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 is_left;
- sljit_ins ins1, ins2, ins3;
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
- sljit_ins word = (op & SLJIT_32) >> 5;
- sljit_s32 inp_flags = ((op & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;
- sljit_sw bit_length = (op & SLJIT_32) ? 32 : 64;
-#else /* !SLJIT_CONFIG_RISCV_64 */
- sljit_s32 inp_flags = WORD_DATA | LOAD_DATA;
- sljit_sw bit_length = 32;
-#endif /* SLJIT_CONFIG_RISCV_64 */
-
- SLJIT_ASSERT(WORD == 0 || WORD == 0x8);
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w));
-
- is_left = (GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_MSHL);
-
- if (src_dst == src1) {
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), src_dst, 0, src_dst, 0, src2, src2w);
- }
-
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- if (src2 & SLJIT_IMM) {
- src2w &= bit_length - 1;
-
- if (src2w == 0)
- return SLJIT_SUCCESS;
- } else if (src2 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG2, src2, src2w));
- src2 = TMP_REG2;
- }
-
- if (src1 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG1, src1, src1w));
- src1 = TMP_REG1;
- } else if (src1 & SLJIT_IMM) {
- FAIL_IF(load_immediate(compiler, TMP_REG1, src1w, TMP_REG3));
- src1 = TMP_REG1;
- }
-
- if (src2 & SLJIT_IMM) {
- if (is_left) {
- ins1 = SLLI | WORD | IMM_I(src2w);
- src2w = bit_length - src2w;
- ins2 = SRLI | WORD | IMM_I(src2w);
- } else {
- ins1 = SRLI | WORD | IMM_I(src2w);
- src2w = bit_length - src2w;
- ins2 = SLLI | WORD | IMM_I(src2w);
- }
-
- FAIL_IF(push_inst(compiler, ins1 | RD(src_dst) | RS1(src_dst)));
- FAIL_IF(push_inst(compiler, ins2 | RD(TMP_REG1) | RS1(src1)));
- return push_inst(compiler, OR | RD(src_dst) | RS1(src_dst) | RS2(TMP_REG1));
- }
-
- if (is_left) {
- ins1 = SLL;
- ins2 = SRLI;
- ins3 = SRL;
- } else {
- ins1 = SRL;
- ins2 = SLLI;
- ins3 = SLL;
- }
-
- FAIL_IF(push_inst(compiler, ins1 | WORD | RD(src_dst) | RS1(src_dst) | RS2(src2)));
-
- if (!(op & SLJIT_SHIFT_INTO_NON_ZERO)) {
- FAIL_IF(push_inst(compiler, ins2 | WORD | RD(TMP_REG1) | RS1(src1) | IMM_I(1)));
- FAIL_IF(push_inst(compiler, XORI | RD(TMP_REG2) | RS1(src2) | IMM_I((sljit_ins)bit_length - 1)));
- src1 = TMP_REG1;
- } else
- FAIL_IF(push_inst(compiler, SUB | WORD | RD(TMP_REG2) | RS1(TMP_ZERO) | RS2(src2)));
-
- FAIL_IF(push_inst(compiler, ins3 | WORD | RD(TMP_REG1) | RS1(src1) | RS2(TMP_REG2)));
- return push_inst(compiler, OR | RD(src_dst) | RS1(src_dst) | RS2(TMP_REG1));
-}
-
-#undef WORD
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- switch (op) {
- case SLJIT_FAST_RETURN:
- if (FAST_IS_REG(src))
- FAIL_IF(push_inst(compiler, ADDI | RD(RETURN_ADDR_REG) | RS1(src) | IMM_I(0)));
- else
- FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw));
-
- return push_inst(compiler, JALR | RD(TMP_ZERO) | RS1(RETURN_ADDR_REG) | IMM_I(0));
- case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
- return SLJIT_SUCCESS;
- case SLJIT_PREFETCH_L1:
- case SLJIT_PREFETCH_L2:
- case SLJIT_PREFETCH_L3:
- case SLJIT_PREFETCH_ONCE:
- return SLJIT_SUCCESS;
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
-{
- CHECK_REG_INDEX(check_sljit_get_register_index(reg));
- return reg_map[reg];
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
-{
- CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
- return freg_map[reg];
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
- void *instruction, sljit_u32 size)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
-
- return push_inst(compiler, *(sljit_ins*)instruction);
-}
-
-/* --------------------------------------------------------------------- */
-/* Floating point operators */
-/* --------------------------------------------------------------------- */
-
-#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_32) >> 7))
-#define FMT(op) ((sljit_ins)((op & SLJIT_32) ^ SLJIT_32) << 17)
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
-# define flags (sljit_u32)0
-#else
- sljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64)) << 21;
-#endif
- sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
-
- if (src & SLJIT_MEM) {
- FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
- src = TMP_FREG1;
- }
-
- FAIL_IF(push_inst(compiler, FCVT_W_S | FMT(op) | flags | RD(dst_r) | FRS1(src)));
-
- /* Store the integer value from a VFP register. */
- if (dst & SLJIT_MEM) {
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- return emit_op_mem2(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0);
-#else
- return emit_op_mem2(compiler, flags ? WORD_DATA : INT_DATA, TMP_REG2, dst, dstw, 0, 0);
-#endif
- }
- return SLJIT_SUCCESS;
-
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
-# undef flags
-#endif
-}
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_ins inst;
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
- sljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW)) << 21;
-#endif
-
- sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
-
- if (src & SLJIT_MEM) {
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw));
-#else
- FAIL_IF(emit_op_mem2(compiler, (flags ? WORD_DATA : INT_DATA) | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw));
-#endif
- src = TMP_REG1;
- } else if (src & SLJIT_IMM) {
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
- if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
- srcw = (sljit_s32)srcw;
-#endif
-
- FAIL_IF(load_immediate(compiler, TMP_REG1, srcw, TMP_REG3));
- src = TMP_REG1;
- }
-
- inst = FCVT_S_W | FMT(op) | FRD(dst_r) | RS1(src);
-
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- if (op & SLJIT_32)
- inst |= F3(0x7);
-#else
- inst |= flags;
-
- if (op != SLJIT_CONV_F64_FROM_S32)
- inst |= F3(0x7);
-#endif
-
- FAIL_IF(push_inst(compiler, inst));
-
- if (dst & SLJIT_MEM)
- return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);
- return SLJIT_SUCCESS;
-}
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_ins inst;
-
- if (src1 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
- src1 = TMP_FREG1;
- }
-
- if (src2 & SLJIT_MEM) {
- FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0));
- src2 = TMP_FREG2;
- }
-
- switch (GET_FLAG_TYPE(op)) {
- case SLJIT_F_EQUAL:
- case SLJIT_F_NOT_EQUAL:
- case SLJIT_ORDERED_EQUAL:
- case SLJIT_UNORDERED_OR_NOT_EQUAL:
- inst = FEQ_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src1) | FRS2(src2);
- break;
- case SLJIT_F_LESS:
- case SLJIT_F_GREATER_EQUAL:
- case SLJIT_ORDERED_LESS:
- case SLJIT_UNORDERED_OR_GREATER_EQUAL:
- inst = FLT_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src1) | FRS2(src2);
- break;
- case SLJIT_ORDERED_GREATER:
- case SLJIT_UNORDERED_OR_LESS_EQUAL:
- inst = FLT_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src2) | FRS2(src1);
- break;
- case SLJIT_F_GREATER:
- case SLJIT_F_LESS_EQUAL:
- case SLJIT_UNORDERED_OR_GREATER:
- case SLJIT_ORDERED_LESS_EQUAL:
- inst = FLE_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src1) | FRS2(src2);
- break;
- case SLJIT_UNORDERED_OR_LESS:
- case SLJIT_ORDERED_GREATER_EQUAL:
- inst = FLE_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src2) | FRS2(src1);
- break;
- case SLJIT_UNORDERED_OR_EQUAL: /* Not supported. */
- case SLJIT_ORDERED_NOT_EQUAL: /* Not supported. */
- FAIL_IF(push_inst(compiler, FLT_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src1) | FRS2(src2)));
- FAIL_IF(push_inst(compiler, FLT_S | FMT(op) | RD(TMP_REG1) | FRS1(src2) | FRS2(src1)));
- inst = OR | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | RS2(TMP_REG1);
- break;
- default: /* SLJIT_UNORDERED, SLJIT_ORDERED */
- FAIL_IF(push_inst(compiler, FADD_S | FMT(op) | FRD(TMP_FREG1) | FRS1(src1) | FRS2(src2)));
- inst = FEQ_S | FMT(op) | RD(OTHER_FLAG) | FRS1(TMP_FREG1) | FRS2(TMP_FREG1);
- break;
- }
-
- return push_inst(compiler, inst);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 dst_r;
-
- CHECK_ERROR();
- compiler->cache_arg = 0;
- compiler->cache_argw = 0;
-
- SLJIT_COMPILE_ASSERT((SLJIT_32 == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);
- SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
-
- if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
- op ^= SLJIT_32;
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
-
- if (src & SLJIT_MEM) {
- FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw));
- src = dst_r;
- }
-
- switch (GET_OPCODE(op)) {
- case SLJIT_MOV_F64:
- if (src != dst_r) {
- if (dst_r != TMP_FREG1)
- FAIL_IF(push_inst(compiler, FSGNJ_S | FMT(op) | FRD(dst_r) | FRS1(src) | FRS2(src)));
- else
- dst_r = src;
- }
- break;
- case SLJIT_NEG_F64:
- FAIL_IF(push_inst(compiler, FSGNJN_S | FMT(op) | FRD(dst_r) | FRS1(src) | FRS2(src)));
- break;
- case SLJIT_ABS_F64:
- FAIL_IF(push_inst(compiler, FSGNJX_S | FMT(op) | FRD(dst_r) | FRS1(src) | FRS2(src)));
- break;
- case SLJIT_CONV_F64_FROM_F32:
- /* The SLJIT_32 bit is inverted because sljit_f32 needs to be loaded from the memory. */
- FAIL_IF(push_inst(compiler, FCVT_S_D | ((op & SLJIT_32) ? (1 << 25) : ((1 << 20) | F3(7))) | FRD(dst_r) | FRS1(src)));
- op ^= SLJIT_32;
- break;
- }
-
- if (dst & SLJIT_MEM)
- return emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0);
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 dst_r, flags = 0;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- compiler->cache_arg = 0;
- compiler->cache_argw = 0;
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;
-
- if (src1 & SLJIT_MEM) {
- if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) {
- FAIL_IF(compiler->error);
- src1 = TMP_FREG1;
- } else
- flags |= SLOW_SRC1;
- }
-
- if (src2 & SLJIT_MEM) {
- if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) {
- FAIL_IF(compiler->error);
- src2 = TMP_FREG2;
- } else
- flags |= SLOW_SRC2;
- }
-
- if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
- if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
- FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w));
- FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
- }
- else {
- FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
- FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
- }
- }
- else if (flags & SLOW_SRC1)
- FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
- else if (flags & SLOW_SRC2)
- FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
-
- if (flags & SLOW_SRC1)
- src1 = TMP_FREG1;
- if (flags & SLOW_SRC2)
- src2 = TMP_FREG2;
-
- switch (GET_OPCODE(op)) {
- case SLJIT_ADD_F64:
- FAIL_IF(push_inst(compiler, FADD_S | FMT(op) | FRD(dst_r) | FRS1(src1) | FRS2(src2)));
- break;
-
- case SLJIT_SUB_F64:
- FAIL_IF(push_inst(compiler, FSUB_S | FMT(op) | FRD(dst_r) | FRS1(src1) | FRS2(src2)));
- break;
-
- case SLJIT_MUL_F64:
- FAIL_IF(push_inst(compiler, FMUL_S | FMT(op) | FRD(dst_r) | FRS1(src1) | FRS2(src2)));
- break;
-
- case SLJIT_DIV_F64:
- FAIL_IF(push_inst(compiler, FDIV_S | FMT(op) | FRD(dst_r) | FRS1(src1) | FRS2(src2)));
- break;
- }
-
- if (dst_r == TMP_FREG2)
- FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0));
-
- return SLJIT_SUCCESS;
-}
-
-#undef FLOAT_DATA
-#undef FMT
-
-/* --------------------------------------------------------------------- */
-/* Other instructions */
-/* --------------------------------------------------------------------- */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- if (FAST_IS_REG(dst))
- return push_inst(compiler, ADDI | RD(dst) | RS1(RETURN_ADDR_REG) | IMM_I(0));
-
- /* Memory. */
- return emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw);
-}
-
-/* --------------------------------------------------------------------- */
-/* Conditional instructions */
-/* --------------------------------------------------------------------- */
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
-{
- struct sljit_label *label;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_label(compiler));
-
- if (compiler->last_label && compiler->last_label->size == compiler->size)
- return compiler->last_label;
-
- label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
- PTR_FAIL_IF(!label);
- set_label(label, compiler);
- return label;
-}
-
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
-#define BRANCH_LENGTH ((sljit_ins)(3 * sizeof(sljit_ins)) << 7)
-#else
-#define BRANCH_LENGTH ((sljit_ins)(7 * sizeof(sljit_ins)) << 7)
-#endif
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
-{
- struct sljit_jump *jump;
- sljit_ins inst;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_jump(compiler, type));
-
- jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
- PTR_FAIL_IF(!jump);
- set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
- type &= 0xff;
-
- switch (type) {
- case SLJIT_EQUAL:
- inst = BNE | RS1(EQUAL_FLAG) | RS2(TMP_ZERO) | BRANCH_LENGTH;
- break;
- case SLJIT_NOT_EQUAL:
- inst = BEQ | RS1(EQUAL_FLAG) | RS2(TMP_ZERO) | BRANCH_LENGTH;
- break;
- case SLJIT_LESS:
- case SLJIT_GREATER:
- case SLJIT_SIG_LESS:
- case SLJIT_SIG_GREATER:
- case SLJIT_OVERFLOW:
- case SLJIT_CARRY:
- case SLJIT_F_EQUAL:
- case SLJIT_ORDERED_EQUAL:
- case SLJIT_ORDERED_NOT_EQUAL: /* Not supported. */
- case SLJIT_F_LESS:
- case SLJIT_ORDERED_LESS:
- case SLJIT_ORDERED_GREATER:
- case SLJIT_F_LESS_EQUAL:
- case SLJIT_ORDERED_LESS_EQUAL:
- case SLJIT_ORDERED_GREATER_EQUAL:
- case SLJIT_ORDERED:
- inst = BEQ | RS1(OTHER_FLAG) | RS2(TMP_ZERO) | BRANCH_LENGTH;
- break;
- case SLJIT_GREATER_EQUAL:
- case SLJIT_LESS_EQUAL:
- case SLJIT_SIG_GREATER_EQUAL:
- case SLJIT_SIG_LESS_EQUAL:
- case SLJIT_NOT_OVERFLOW:
- case SLJIT_NOT_CARRY:
- case SLJIT_F_NOT_EQUAL:
- case SLJIT_UNORDERED_OR_NOT_EQUAL:
- case SLJIT_UNORDERED_OR_EQUAL: /* Not supported. */
- case SLJIT_F_GREATER_EQUAL:
- case SLJIT_UNORDERED_OR_GREATER_EQUAL:
- case SLJIT_UNORDERED_OR_LESS_EQUAL:
- case SLJIT_F_GREATER:
- case SLJIT_UNORDERED_OR_GREATER:
- case SLJIT_UNORDERED_OR_LESS:
- case SLJIT_UNORDERED:
- inst = BNE | RS1(OTHER_FLAG) | RS2(TMP_ZERO) | BRANCH_LENGTH;
- break;
- default:
- /* Not conditional branch. */
- inst = 0;
- break;
- }
-
- if (inst != 0) {
- PTR_FAIL_IF(push_inst(compiler, inst));
- jump->flags |= IS_COND;
- }
-
- jump->addr = compiler->size;
- inst = JALR | RS1(TMP_REG1) | IMM_I(0);
-
- if (type >= SLJIT_FAST_CALL) {
- jump->flags |= IS_CALL;
- inst |= RD(RETURN_ADDR_REG);
- }
-
- PTR_FAIL_IF(push_inst(compiler, inst));
-
- /* Maximum number of instructions required for generating a constant. */
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- compiler->size += 1;
-#else
- compiler->size += 5;
-#endif
- return jump;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types)
-{
- SLJIT_UNUSED_ARG(arg_types);
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
-
- if (type & SLJIT_CALL_RETURN) {
- PTR_FAIL_IF(emit_stack_frame_release(compiler, 0));
- type = SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP);
- }
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_jump(compiler, type);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- struct sljit_jump *jump;
- sljit_s32 flags;
- sljit_ins inst;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- compiler->cache_arg = 0;
- compiler->cache_argw = 0;
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- flags = WORD_DATA | LOAD_DATA;
-#else /* !SLJIT_CONFIG_RISCV_32 */
- flags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;
-#endif /* SLJIT_CONFIG_RISCV_32 */
-
- if (src1 & SLJIT_MEM) {
- PTR_FAIL_IF(emit_op_mem2(compiler, flags, TMP_REG1, src1, src1w, src2, src2w));
- src1 = TMP_REG1;
- }
-
- if (src2 & SLJIT_MEM) {
- PTR_FAIL_IF(emit_op_mem2(compiler, flags, TMP_REG2, src2, src2w, 0, 0));
- src2 = TMP_REG2;
- }
-
- if (src1 & SLJIT_IMM) {
- if (src1w != 0) {
- PTR_FAIL_IF(load_immediate(compiler, TMP_REG1, src1w, TMP_REG3));
- src1 = TMP_REG1;
- }
- else
- src1 = TMP_ZERO;
- }
-
- if (src2 & SLJIT_IMM) {
- if (src2w != 0) {
- PTR_FAIL_IF(load_immediate(compiler, TMP_REG2, src2w, TMP_REG3));
- src2 = TMP_REG2;
- }
- else
- src2 = TMP_ZERO;
- }
-
- jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
- PTR_FAIL_IF(!jump);
- set_jump(jump, compiler, (sljit_u32)((type & SLJIT_REWRITABLE_JUMP) | IS_COND));
- type &= 0xff;
-
- switch (type) {
- case SLJIT_EQUAL:
- inst = BNE | RS1(src1) | RS2(src2) | BRANCH_LENGTH;
- break;
- case SLJIT_NOT_EQUAL:
- inst = BEQ | RS1(src1) | RS2(src2) | BRANCH_LENGTH;
- break;
- case SLJIT_LESS:
- inst = BGEU | RS1(src1) | RS2(src2) | BRANCH_LENGTH;
- break;
- case SLJIT_GREATER_EQUAL:
- inst = BLTU | RS1(src1) | RS2(src2) | BRANCH_LENGTH;
- break;
- case SLJIT_GREATER:
- inst = BGEU | RS1(src2) | RS2(src1) | BRANCH_LENGTH;
- break;
- case SLJIT_LESS_EQUAL:
- inst = BLTU | RS1(src2) | RS2(src1) | BRANCH_LENGTH;
- break;
- case SLJIT_SIG_LESS:
- inst = BGE | RS1(src1) | RS2(src2) | BRANCH_LENGTH;
- break;
- case SLJIT_SIG_GREATER_EQUAL:
- inst = BLT | RS1(src1) | RS2(src2) | BRANCH_LENGTH;
- break;
- case SLJIT_SIG_GREATER:
- inst = BGE | RS1(src2) | RS2(src1) | BRANCH_LENGTH;
- break;
- case SLJIT_SIG_LESS_EQUAL:
- inst = BLT | RS1(src2) | RS2(src1) | BRANCH_LENGTH;
- break;
- }
-
- PTR_FAIL_IF(push_inst(compiler, inst));
-
- jump->addr = compiler->size;
- PTR_FAIL_IF(push_inst(compiler, JALR | RD(TMP_ZERO) | RS1(TMP_REG1) | IMM_I(0)));
-
- /* Maximum number of instructions required for generating a constant. */
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- compiler->size += 1;
-#else
- compiler->size += 5;
-#endif
- return jump;
-}
-
-#undef BRANCH_LENGTH
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
-{
- struct sljit_jump *jump;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
-
- if (!(src & SLJIT_IMM)) {
- if (src & SLJIT_MEM) {
- ADJUST_LOCAL_OFFSET(src, srcw);
- FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw));
- src = TMP_REG1;
- }
- return push_inst(compiler, JALR | RD((type >= SLJIT_FAST_CALL) ? RETURN_ADDR_REG : TMP_ZERO) | RS1(src) | IMM_I(0));
- }
-
- /* These jumps are converted to jump/call instructions when possible. */
- jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
- FAIL_IF(!jump);
- set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_CALL : 0));
- jump->u.target = (sljit_uw)srcw;
-
- jump->addr = compiler->size;
- FAIL_IF(push_inst(compiler, JALR | RD((type >= SLJIT_FAST_CALL) ? RETURN_ADDR_REG : TMP_ZERO) | RS1(TMP_REG1) | IMM_I(0)));
-
- /* Maximum number of instructions required for generating a constant. */
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- compiler->size += 1;
-#else
- compiler->size += 5;
-#endif
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types,
- sljit_s32 src, sljit_sw srcw)
-{
- SLJIT_UNUSED_ARG(arg_types);
- CHECK_ERROR();
- CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
-
- if (src & SLJIT_MEM) {
- ADJUST_LOCAL_OFFSET(src, srcw);
- FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw));
- src = TMP_REG1;
- }
-
- if (type & SLJIT_CALL_RETURN) {
- if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
- FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(src) | IMM_I(0)));
- src = TMP_REG1;
- }
-
- FAIL_IF(emit_stack_frame_release(compiler, 0));
- type = SLJIT_JUMP;
- }
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_ijump(compiler, type, src, srcw);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 type)
-{
- sljit_s32 src_r, dst_r, invert;
- sljit_s32 saved_op = op;
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- sljit_s32 mem_type = WORD_DATA;
-#else
- sljit_s32 mem_type = ((op & SLJIT_32) || op == SLJIT_MOV32) ? (INT_DATA | SIGNED_DATA) : WORD_DATA;
-#endif
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- op = GET_OPCODE(op);
- dst_r = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2;
-
- compiler->cache_arg = 0;
- compiler->cache_argw = 0;
-
- if (op >= SLJIT_ADD && (dst & SLJIT_MEM))
- FAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, TMP_REG1, dst, dstw, dst, dstw));
-
- if (type < SLJIT_F_EQUAL) {
- src_r = OTHER_FLAG;
- invert = type & 0x1;
-
- switch (type) {
- case SLJIT_EQUAL:
- case SLJIT_NOT_EQUAL:
- FAIL_IF(push_inst(compiler, SLTUI | RD(dst_r) | RS1(EQUAL_FLAG) | IMM_I(1)));
- src_r = dst_r;
- break;
- case SLJIT_OVERFLOW:
- case SLJIT_NOT_OVERFLOW:
- if (compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)) {
- src_r = OTHER_FLAG;
- break;
- }
- FAIL_IF(push_inst(compiler, SLTUI | RD(dst_r) | RS1(OTHER_FLAG) | IMM_I(1)));
- src_r = dst_r;
- invert ^= 0x1;
- break;
- }
- } else {
- invert = 0;
- src_r = OTHER_FLAG;
-
- switch (type) {
- case SLJIT_F_NOT_EQUAL:
- case SLJIT_UNORDERED_OR_NOT_EQUAL:
- case SLJIT_UNORDERED_OR_EQUAL: /* Not supported. */
- case SLJIT_F_GREATER_EQUAL:
- case SLJIT_UNORDERED_OR_GREATER_EQUAL:
- case SLJIT_UNORDERED_OR_LESS_EQUAL:
- case SLJIT_F_GREATER:
- case SLJIT_UNORDERED_OR_GREATER:
- case SLJIT_UNORDERED_OR_LESS:
- case SLJIT_UNORDERED:
- invert = 1;
- break;
- }
- }
-
- if (invert) {
- FAIL_IF(push_inst(compiler, XORI | RD(dst_r) | RS1(src_r) | IMM_I(1)));
- src_r = dst_r;
- }
-
- if (op < SLJIT_ADD) {
- if (dst & SLJIT_MEM)
- return emit_op_mem(compiler, mem_type, src_r, dst, dstw);
-
- if (src_r != dst_r)
- return push_inst(compiler, ADDI | RD(dst_r) | RS1(src_r) | IMM_I(0));
- return SLJIT_SUCCESS;
- }
-
- mem_type |= CUMULATIVE_OP | IMM_OP | ALT_KEEP_CACHE;
-
- if (dst & SLJIT_MEM)
- return emit_op(compiler, saved_op, mem_type, dst, dstw, TMP_REG1, 0, src_r, 0);
- return emit_op(compiler, saved_op, mem_type, dst, dstw, dst, dstw, src_r, 0);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 dst_reg,
- sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
-
- return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 reg,
- sljit_s32 mem, sljit_sw memw)
-{
- sljit_s32 flags;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
-
- if (!(reg & REG_PAIR_MASK))
- return sljit_emit_mem_unaligned(compiler, type, reg, mem, memw);
-
- if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
- memw &= 0x3;
-
- if (SLJIT_UNLIKELY(memw != 0)) {
- FAIL_IF(push_inst(compiler, SLLI | RD(TMP_REG1) | RS1(OFFS_REG(mem)) | IMM_I(memw)));
- FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RS1(TMP_REG1) | RS2(mem & REG_MASK)));
- } else
- FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RS1(mem & REG_MASK) | RS2(OFFS_REG(mem))));
-
- mem = TMP_REG1;
- memw = 0;
- } else if (memw > SIMM_MAX - SSIZE_OF(sw) || memw < SIMM_MIN) {
- if (((memw + 0x800) & 0xfff) <= 0xfff - SSIZE_OF(sw)) {
- FAIL_IF(load_immediate(compiler, TMP_REG1, TO_ARGW_HI(memw), TMP_REG3));
- memw &= 0xfff;
- } else {
- FAIL_IF(load_immediate(compiler, TMP_REG1, memw, TMP_REG3));
- memw = 0;
- }
-
- if (mem & REG_MASK)
- FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RS1(TMP_REG1) | RS2(mem & REG_MASK)));
-
- mem = TMP_REG1;
- } else {
- mem &= REG_MASK;
- memw &= 0xfff;
- }
-
- SLJIT_ASSERT((memw >= 0 && memw <= SIMM_MAX - SSIZE_OF(sw)) || (memw > SIMM_MAX && memw <= 0xfff));
-
- if (!(type & SLJIT_MEM_STORE) && mem == REG_PAIR_FIRST(reg)) {
- FAIL_IF(push_mem_inst(compiler, WORD_DATA | LOAD_DATA, REG_PAIR_SECOND(reg), mem, (memw + SSIZE_OF(sw)) & 0xfff));
- return push_mem_inst(compiler, WORD_DATA | LOAD_DATA, REG_PAIR_FIRST(reg), mem, memw);
- }
-
- flags = WORD_DATA | (!(type & SLJIT_MEM_STORE) ? LOAD_DATA : 0);
-
- FAIL_IF(push_mem_inst(compiler, flags, REG_PAIR_FIRST(reg), mem, memw));
- return push_mem_inst(compiler, flags, REG_PAIR_SECOND(reg), mem, (memw + SSIZE_OF(sw)) & 0xfff);
-}
-
-#undef TO_ARGW_HI
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
-{
- struct sljit_const *const_;
- sljit_s32 dst_r;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
- PTR_FAIL_IF(!const_);
- set_const(const_, compiler);
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
- PTR_FAIL_IF(emit_const(compiler, dst_r, init_value, ADDI | RD(dst_r)));
-
- if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));
-
- return const_;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
-{
- struct sljit_put_label *put_label;
- sljit_s32 dst_r;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
- PTR_FAIL_IF(!put_label);
- set_put_label(put_label, compiler, 0);
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
- PTR_FAIL_IF(push_inst(compiler, (sljit_ins)dst_r));
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- compiler->size += 1;
-#else
- compiler->size += 5;
-#endif
-
- if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));
-
- return put_label;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
-{
- sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
-}
diff --git a/contrib/libs/pcre2/src/sljit/sljitNativeS390X.c b/contrib/libs/pcre2/src/sljit/sljitNativeS390X.c
deleted file mode 100644
index 8b51bad9bc..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitNativeS390X.c
+++ /dev/null
@@ -1,3747 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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 <sys/auxv.h>
-
-#ifdef __ARCH__
-#define ENABLE_STATIC_FACILITY_DETECTION 1
-#else
-#define ENABLE_STATIC_FACILITY_DETECTION 0
-#endif
-#define ENABLE_DYNAMIC_FACILITY_DETECTION 1
-
-SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
-{
- return "s390x" SLJIT_CPUINFO;
-}
-
-/* Instructions. */
-typedef sljit_uw sljit_ins;
-
-/* Instruction tags (most significant halfword). */
-static const sljit_ins sljit_ins_const = (sljit_ins)1 << 48;
-
-#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
-#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
-
-static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 4] = {
- 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 0, 1
-};
-
-/* there are also a[2-15] available, but they are slower to access and
- * their use is limited as mundaym explained:
- * https://github.com/zherczeg/sljit/pull/91#discussion_r486895689
- */
-
-/* General Purpose Registers [0-15]. */
-typedef sljit_uw sljit_gpr;
-
-/*
- * WARNING
- * the following code is non standard and should be improved for
- * consistency, but doesn't use SLJIT_NUMBER_OF_REGISTERS based
- * registers because r0 and r1 are the ABI recommended volatiles.
- * there is a gpr() function that maps sljit to physical register numbers
- * that should be used instead of the usual index into reg_map[] and
- * will be retired ASAP (TODO: carenas)
- */
-
-static const sljit_gpr r0 = 0; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 2]: 0 in address calculations; reserved */
-static const sljit_gpr r1 = 1; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 3]: reserved */
-static const sljit_gpr r2 = 2; /* reg_map[1]: 1st argument */
-static const sljit_gpr r3 = 3; /* reg_map[2]: 2nd argument */
-static const sljit_gpr r4 = 4; /* reg_map[3]: 3rd argument */
-static const sljit_gpr r5 = 5; /* reg_map[4]: 4th argument */
-static const sljit_gpr r6 = 6; /* reg_map[5]: 5th argument; 1st saved register */
-static const sljit_gpr r7 = 7; /* reg_map[6] */
-static const sljit_gpr r8 = 8; /* reg_map[7] */
-static const sljit_gpr r9 = 9; /* reg_map[8] */
-static const sljit_gpr r10 = 10; /* reg_map[9] */
-static const sljit_gpr r11 = 11; /* reg_map[10] */
-static const sljit_gpr r12 = 12; /* reg_map[11]: GOT */
-static const sljit_gpr r13 = 13; /* reg_map[12]: Literal Pool pointer */
-static const sljit_gpr r14 = 14; /* reg_map[0]: return address and flag register */
-static const sljit_gpr r15 = 15; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 1]: stack pointer */
-
-/* WARNING: r12 and r13 shouldn't be used as per ABI recommendation */
-/* TODO(carenas): r12 might conflict in PIC code, reserve? */
-/* TODO(carenas): r13 is usually pointed to "pool" per ABI, using a tmp
- * like we do know might be faster though, reserve?
- */
-
-/* TODO(carenas): should be named TMP_REG[1-2] for consistency */
-#define tmp0 r0
-#define tmp1 r1
-
-/* TODO(carenas): flags should move to a different register so that
- * link register doesn't need to change
- */
-
-/* When reg cannot be unused. */
-#define IS_GPR_REG(reg) ((reg > 0) && (reg) <= SLJIT_SP)
-
-/* Link register. */
-static const sljit_gpr link_r = 14; /* r14 */
-
-#define TMP_FREG1 (0)
-
-static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = {
- 1, 0, 2, 4, 6, 3, 5, 7, 15, 14, 13, 12, 11, 10, 9, 8,
-};
-
-#define R0A(r) (r)
-#define R4A(r) ((r) << 4)
-#define R8A(r) ((r) << 8)
-#define R12A(r) ((r) << 12)
-#define R16A(r) ((r) << 16)
-#define R20A(r) ((r) << 20)
-#define R28A(r) ((r) << 28)
-#define R32A(r) ((r) << 32)
-#define R36A(r) ((r) << 36)
-
-#define R0(r) ((sljit_ins)reg_map[r])
-
-#define F0(r) ((sljit_ins)freg_map[r])
-#define F4(r) (R4A((sljit_ins)freg_map[r]))
-#define F20(r) (R20A((sljit_ins)freg_map[r]))
-#define F36(r) (R36A((sljit_ins)freg_map[r]))
-
-struct sljit_s390x_const {
- struct sljit_const const_; /* must be first */
- sljit_sw init_value; /* required to build literal pool */
-};
-
-/* Convert SLJIT register to hardware register. */
-static SLJIT_INLINE sljit_gpr gpr(sljit_s32 r)
-{
- SLJIT_ASSERT(r >= 0 && r < (sljit_s32)(sizeof(reg_map) / sizeof(reg_map[0])));
- return reg_map[r];
-}
-
-static SLJIT_INLINE sljit_gpr fgpr(sljit_s32 r)
-{
- SLJIT_ASSERT(r >= 0 && r < (sljit_s32)(sizeof(freg_map) / sizeof(freg_map[0])));
- return freg_map[r];
-}
-
-/* Size of instruction in bytes. Tags must already be cleared. */
-static SLJIT_INLINE sljit_uw sizeof_ins(sljit_ins ins)
-{
- /* keep faulting instructions */
- if (ins == 0)
- return 2;
-
- if ((ins & 0x00000000ffffL) == ins)
- return 2;
- if ((ins & 0x0000ffffffffL) == ins)
- return 4;
- if ((ins & 0xffffffffffffL) == ins)
- return 6;
-
- SLJIT_UNREACHABLE();
- return (sljit_uw)-1;
-}
-
-static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)
-{
- sljit_ins *ibuf = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins));
- FAIL_IF(!ibuf);
- *ibuf = ins;
- compiler->size++;
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 encode_inst(void **ptr, sljit_ins ins)
-{
- sljit_u16 *ibuf = (sljit_u16 *)*ptr;
- sljit_uw size = sizeof_ins(ins);
-
- SLJIT_ASSERT((size & 6) == size);
- switch (size) {
- case 6:
- *ibuf++ = (sljit_u16)(ins >> 32);
- /* fallthrough */
- case 4:
- *ibuf++ = (sljit_u16)(ins >> 16);
- /* fallthrough */
- case 2:
- *ibuf++ = (sljit_u16)(ins);
- }
- *ptr = (void*)ibuf;
- return SLJIT_SUCCESS;
-}
-
-#define SLJIT_ADD_SUB_NO_COMPARE(status_flags_state) \
- (((status_flags_state) & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)) \
- && !((status_flags_state) & SLJIT_CURRENT_FLAGS_COMPARE))
-
-/* Map the given type to a 4-bit condition code mask. */
-static SLJIT_INLINE sljit_u8 get_cc(struct sljit_compiler *compiler, sljit_s32 type) {
- const sljit_u8 cc0 = 1 << 3; /* equal {,to zero} */
- const sljit_u8 cc1 = 1 << 2; /* less than {,zero} */
- const sljit_u8 cc2 = 1 << 1; /* greater than {,zero} */
- const sljit_u8 cc3 = 1 << 0; /* {overflow,NaN} */
-
- switch (type) {
- case SLJIT_EQUAL:
- if (SLJIT_ADD_SUB_NO_COMPARE(compiler->status_flags_state)) {
- sljit_s32 type = GET_FLAG_TYPE(compiler->status_flags_state);
- if (type >= SLJIT_SIG_LESS && type <= SLJIT_SIG_LESS_EQUAL)
- return cc0;
- if (type == SLJIT_OVERFLOW)
- return (cc0 | cc3);
- return (cc0 | cc2);
- }
- /* fallthrough */
-
- case SLJIT_F_EQUAL:
- case SLJIT_ORDERED_EQUAL:
- return cc0;
-
- case SLJIT_NOT_EQUAL:
- if (SLJIT_ADD_SUB_NO_COMPARE(compiler->status_flags_state)) {
- sljit_s32 type = GET_FLAG_TYPE(compiler->status_flags_state);
- if (type >= SLJIT_SIG_LESS && type <= SLJIT_SIG_LESS_EQUAL)
- return (cc1 | cc2 | cc3);
- if (type == SLJIT_OVERFLOW)
- return (cc1 | cc2);
- return (cc1 | cc3);
- }
- /* fallthrough */
-
- case SLJIT_UNORDERED_OR_NOT_EQUAL:
- return (cc1 | cc2 | cc3);
-
- case SLJIT_LESS:
- return cc1;
-
- case SLJIT_GREATER_EQUAL:
- case SLJIT_UNORDERED_OR_GREATER_EQUAL:
- return (cc0 | cc2 | cc3);
-
- case SLJIT_GREATER:
- if (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_COMPARE)
- return cc2;
- return cc3;
-
- case SLJIT_LESS_EQUAL:
- if (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_COMPARE)
- return (cc0 | cc1);
- return (cc0 | cc1 | cc2);
-
- case SLJIT_SIG_LESS:
- case SLJIT_F_LESS:
- case SLJIT_ORDERED_LESS:
- return cc1;
-
- case SLJIT_NOT_CARRY:
- if (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_SUB)
- return (cc2 | cc3);
- /* fallthrough */
-
- case SLJIT_SIG_LESS_EQUAL:
- case SLJIT_F_LESS_EQUAL:
- case SLJIT_ORDERED_LESS_EQUAL:
- return (cc0 | cc1);
-
- case SLJIT_CARRY:
- if (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_SUB)
- return (cc0 | cc1);
- /* fallthrough */
-
- case SLJIT_SIG_GREATER:
- case SLJIT_UNORDERED_OR_GREATER:
- /* Overflow is considered greater, see SLJIT_SUB. */
- return cc2 | cc3;
-
- case SLJIT_SIG_GREATER_EQUAL:
- return (cc0 | cc2 | cc3);
-
- case SLJIT_OVERFLOW:
- if (compiler->status_flags_state & SLJIT_SET_Z)
- return (cc2 | cc3);
- /* fallthrough */
-
- case SLJIT_UNORDERED:
- return cc3;
-
- case SLJIT_NOT_OVERFLOW:
- if (compiler->status_flags_state & SLJIT_SET_Z)
- return (cc0 | cc1);
- /* fallthrough */
-
- case SLJIT_ORDERED:
- return (cc0 | cc1 | cc2);
-
- case SLJIT_F_NOT_EQUAL:
- case SLJIT_ORDERED_NOT_EQUAL:
- return (cc1 | cc2);
-
- case SLJIT_F_GREATER:
- case SLJIT_ORDERED_GREATER:
- return cc2;
-
- case SLJIT_F_GREATER_EQUAL:
- case SLJIT_ORDERED_GREATER_EQUAL:
- return (cc0 | cc2);
-
- case SLJIT_UNORDERED_OR_LESS_EQUAL:
- return (cc0 | cc1 | cc3);
-
- case SLJIT_UNORDERED_OR_EQUAL:
- return (cc0 | cc3);
-
- case SLJIT_UNORDERED_OR_LESS:
- return (cc1 | cc3);
- }
-
- SLJIT_UNREACHABLE();
- return (sljit_u8)-1;
-}
-
-/* Facility to bit index mappings.
- Note: some facilities share the same bit index. */
-typedef sljit_uw facility_bit;
-#define STORE_FACILITY_LIST_EXTENDED_FACILITY 7
-#define FAST_LONG_DISPLACEMENT_FACILITY 19
-#define EXTENDED_IMMEDIATE_FACILITY 21
-#define GENERAL_INSTRUCTION_EXTENSION_FACILITY 34
-#define DISTINCT_OPERAND_FACILITY 45
-#define HIGH_WORD_FACILITY 45
-#define POPULATION_COUNT_FACILITY 45
-#define LOAD_STORE_ON_CONDITION_1_FACILITY 45
-#define MISCELLANEOUS_INSTRUCTION_EXTENSIONS_1_FACILITY 49
-#define LOAD_STORE_ON_CONDITION_2_FACILITY 53
-#define MISCELLANEOUS_INSTRUCTION_EXTENSIONS_2_FACILITY 58
-#define VECTOR_FACILITY 129
-#define VECTOR_ENHANCEMENTS_1_FACILITY 135
-
-/* Report whether a facility is known to be present due to the compiler
- settings. This function should always be compiled to a constant
- value given a constant argument. */
-static SLJIT_INLINE int have_facility_static(facility_bit x)
-{
-#if ENABLE_STATIC_FACILITY_DETECTION
- switch (x) {
- case FAST_LONG_DISPLACEMENT_FACILITY:
- return (__ARCH__ >= 6 /* z990 */);
- case EXTENDED_IMMEDIATE_FACILITY:
- case STORE_FACILITY_LIST_EXTENDED_FACILITY:
- return (__ARCH__ >= 7 /* z9-109 */);
- case GENERAL_INSTRUCTION_EXTENSION_FACILITY:
- return (__ARCH__ >= 8 /* z10 */);
- case DISTINCT_OPERAND_FACILITY:
- return (__ARCH__ >= 9 /* z196 */);
- case MISCELLANEOUS_INSTRUCTION_EXTENSIONS_1_FACILITY:
- return (__ARCH__ >= 10 /* zEC12 */);
- case LOAD_STORE_ON_CONDITION_2_FACILITY:
- case VECTOR_FACILITY:
- return (__ARCH__ >= 11 /* z13 */);
- case MISCELLANEOUS_INSTRUCTION_EXTENSIONS_2_FACILITY:
- case VECTOR_ENHANCEMENTS_1_FACILITY:
- return (__ARCH__ >= 12 /* z14 */);
- default:
- SLJIT_UNREACHABLE();
- }
-#endif
- return 0;
-}
-
-static SLJIT_INLINE unsigned long get_hwcap()
-{
- static unsigned long hwcap = 0;
- if (SLJIT_UNLIKELY(!hwcap)) {
- hwcap = getauxval(AT_HWCAP);
- SLJIT_ASSERT(hwcap != 0);
- }
- return hwcap;
-}
-
-static SLJIT_INLINE int have_stfle()
-{
- if (have_facility_static(STORE_FACILITY_LIST_EXTENDED_FACILITY))
- return 1;
-
- return (get_hwcap() & HWCAP_S390_STFLE);
-}
-
-/* Report whether the given facility is available. This function always
- performs a runtime check. */
-static int have_facility_dynamic(facility_bit x)
-{
-#if ENABLE_DYNAMIC_FACILITY_DETECTION
- static struct {
- sljit_uw bits[4];
- } cpu_features;
- size_t size = sizeof(cpu_features);
- const sljit_uw word_index = x >> 6;
- const sljit_uw bit_index = ((1UL << 63) >> (x & 63));
-
- SLJIT_ASSERT(x < size * 8);
- if (SLJIT_UNLIKELY(!have_stfle()))
- return 0;
-
- if (SLJIT_UNLIKELY(cpu_features.bits[0] == 0)) {
- __asm__ __volatile__ (
- "lgr %%r0, %0;"
- "stfle 0(%1);"
- /* outputs */:
- /* inputs */: "d" ((size / 8) - 1), "a" (&cpu_features)
- /* clobbers */: "r0", "cc", "memory"
- );
- SLJIT_ASSERT(cpu_features.bits[0] != 0);
- }
- return (cpu_features.bits[word_index] & bit_index) != 0;
-#else
- return 0;
-#endif
-}
-
-#define HAVE_FACILITY(name, bit) \
-static SLJIT_INLINE int name() \
-{ \
- static int have = -1; \
- /* Static check first. May allow the function to be optimized away. */ \
- if (have_facility_static(bit)) \
- have = 1; \
- else if (SLJIT_UNLIKELY(have < 0)) \
- have = have_facility_dynamic(bit) ? 1 : 0; \
-\
- return have; \
-}
-
-HAVE_FACILITY(have_eimm, EXTENDED_IMMEDIATE_FACILITY)
-HAVE_FACILITY(have_ldisp, FAST_LONG_DISPLACEMENT_FACILITY)
-HAVE_FACILITY(have_genext, GENERAL_INSTRUCTION_EXTENSION_FACILITY)
-HAVE_FACILITY(have_lscond1, LOAD_STORE_ON_CONDITION_1_FACILITY)
-HAVE_FACILITY(have_lscond2, LOAD_STORE_ON_CONDITION_2_FACILITY)
-HAVE_FACILITY(have_misc2, MISCELLANEOUS_INSTRUCTION_EXTENSIONS_2_FACILITY)
-#undef HAVE_FACILITY
-
-#define is_u12(d) (0 <= (d) && (d) <= 0x00000fffL)
-#define is_u32(d) (0 <= (d) && (d) <= 0xffffffffL)
-
-#define CHECK_SIGNED(v, bitlen) \
- ((v) >= -(1 << ((bitlen) - 1)) && (v) < (1 << ((bitlen) - 1)))
-
-#define is_s8(d) CHECK_SIGNED((d), 8)
-#define is_s16(d) CHECK_SIGNED((d), 16)
-#define is_s20(d) CHECK_SIGNED((d), 20)
-#define is_s32(d) ((d) == (sljit_s32)(d))
-
-static SLJIT_INLINE sljit_ins disp_s20(sljit_s32 d)
-{
- SLJIT_ASSERT(is_s20(d));
-
- sljit_uw dh = (d >> 12) & 0xff;
- sljit_uw dl = (d << 8) & 0xfff00;
- return (dh | dl) << 8;
-}
-
-/* TODO(carenas): variadic macro is not strictly needed */
-#define SLJIT_S390X_INSTRUCTION(op, ...) \
-static SLJIT_INLINE sljit_ins op(__VA_ARGS__)
-
-/* RR form instructions. */
-#define SLJIT_S390X_RR(name, pattern) \
-SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src) \
-{ \
- return (pattern) | ((dst & 0xf) << 4) | (src & 0xf); \
-}
-
-/* AND */
-SLJIT_S390X_RR(nr, 0x1400)
-
-/* BRANCH AND SAVE */
-SLJIT_S390X_RR(basr, 0x0d00)
-
-/* BRANCH ON CONDITION */
-SLJIT_S390X_RR(bcr, 0x0700) /* TODO(mundaym): type for mask? */
-
-/* DIVIDE */
-SLJIT_S390X_RR(dr, 0x1d00)
-
-/* EXCLUSIVE OR */
-SLJIT_S390X_RR(xr, 0x1700)
-
-/* LOAD */
-SLJIT_S390X_RR(lr, 0x1800)
-
-/* LOAD COMPLEMENT */
-SLJIT_S390X_RR(lcr, 0x1300)
-
-/* OR */
-SLJIT_S390X_RR(or, 0x1600)
-
-#undef SLJIT_S390X_RR
-
-/* RRE form instructions */
-#define SLJIT_S390X_RRE(name, pattern) \
-SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src) \
-{ \
- return (pattern) | R4A(dst) | R0A(src); \
-}
-
-/* AND */
-SLJIT_S390X_RRE(ngr, 0xb9800000)
-
-/* DIVIDE LOGICAL */
-SLJIT_S390X_RRE(dlr, 0xb9970000)
-SLJIT_S390X_RRE(dlgr, 0xb9870000)
-
-/* DIVIDE SINGLE */
-SLJIT_S390X_RRE(dsgr, 0xb90d0000)
-
-/* EXCLUSIVE OR */
-SLJIT_S390X_RRE(xgr, 0xb9820000)
-
-/* LOAD */
-SLJIT_S390X_RRE(lgr, 0xb9040000)
-SLJIT_S390X_RRE(lgfr, 0xb9140000)
-
-/* LOAD BYTE */
-SLJIT_S390X_RRE(lbr, 0xb9260000)
-SLJIT_S390X_RRE(lgbr, 0xb9060000)
-
-/* LOAD COMPLEMENT */
-SLJIT_S390X_RRE(lcgr, 0xb9030000)
-
-/* LOAD HALFWORD */
-SLJIT_S390X_RRE(lhr, 0xb9270000)
-SLJIT_S390X_RRE(lghr, 0xb9070000)
-
-/* LOAD LOGICAL */
-SLJIT_S390X_RRE(llgfr, 0xb9160000)
-
-/* LOAD LOGICAL CHARACTER */
-SLJIT_S390X_RRE(llcr, 0xb9940000)
-SLJIT_S390X_RRE(llgcr, 0xb9840000)
-
-/* LOAD LOGICAL HALFWORD */
-SLJIT_S390X_RRE(llhr, 0xb9950000)
-SLJIT_S390X_RRE(llghr, 0xb9850000)
-
-/* MULTIPLY LOGICAL */
-SLJIT_S390X_RRE(mlgr, 0xb9860000)
-
-/* MULTIPLY SINGLE */
-SLJIT_S390X_RRE(msgfr, 0xb91c0000)
-
-/* OR */
-SLJIT_S390X_RRE(ogr, 0xb9810000)
-
-/* SUBTRACT */
-SLJIT_S390X_RRE(sgr, 0xb9090000)
-
-#undef SLJIT_S390X_RRE
-
-/* RI-a form instructions */
-#define SLJIT_S390X_RIA(name, pattern, imm_type) \
-SLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, imm_type imm) \
-{ \
- return (pattern) | R20A(reg) | (imm & 0xffff); \
-}
-
-/* ADD HALFWORD IMMEDIATE */
-SLJIT_S390X_RIA(aghi, 0xa70b0000, sljit_s16)
-
-/* LOAD HALFWORD IMMEDIATE */
-SLJIT_S390X_RIA(lhi, 0xa7080000, sljit_s16)
-SLJIT_S390X_RIA(lghi, 0xa7090000, sljit_s16)
-
-/* LOAD LOGICAL IMMEDIATE */
-SLJIT_S390X_RIA(llihh, 0xa50c0000, sljit_u16)
-SLJIT_S390X_RIA(llihl, 0xa50d0000, sljit_u16)
-SLJIT_S390X_RIA(llilh, 0xa50e0000, sljit_u16)
-SLJIT_S390X_RIA(llill, 0xa50f0000, sljit_u16)
-
-/* MULTIPLY HALFWORD IMMEDIATE */
-SLJIT_S390X_RIA(mhi, 0xa70c0000, sljit_s16)
-SLJIT_S390X_RIA(mghi, 0xa70d0000, sljit_s16)
-
-/* OR IMMEDIATE */
-SLJIT_S390X_RIA(oilh, 0xa50a0000, sljit_u16)
-
-#undef SLJIT_S390X_RIA
-
-/* RIL-a form instructions (requires extended immediate facility) */
-#define SLJIT_S390X_RILA(name, pattern, imm_type) \
-SLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, imm_type imm) \
-{ \
- SLJIT_ASSERT(have_eimm()); \
- return (pattern) | R36A(reg) | ((sljit_ins)imm & 0xffffffffu); \
-}
-
-/* ADD IMMEDIATE */
-SLJIT_S390X_RILA(agfi, 0xc20800000000, sljit_s32)
-
-/* ADD IMMEDIATE HIGH */
-SLJIT_S390X_RILA(aih, 0xcc0800000000, sljit_s32) /* TODO(mundaym): high-word facility? */
-
-/* AND IMMEDIATE */
-SLJIT_S390X_RILA(nihf, 0xc00a00000000, sljit_u32)
-
-/* EXCLUSIVE OR IMMEDIATE */
-SLJIT_S390X_RILA(xilf, 0xc00700000000, sljit_u32)
-
-/* INSERT IMMEDIATE */
-SLJIT_S390X_RILA(iihf, 0xc00800000000, sljit_u32)
-SLJIT_S390X_RILA(iilf, 0xc00900000000, sljit_u32)
-
-/* LOAD IMMEDIATE */
-SLJIT_S390X_RILA(lgfi, 0xc00100000000, sljit_s32)
-
-/* LOAD LOGICAL IMMEDIATE */
-SLJIT_S390X_RILA(llihf, 0xc00e00000000, sljit_u32)
-SLJIT_S390X_RILA(llilf, 0xc00f00000000, sljit_u32)
-
-/* SUBTRACT LOGICAL IMMEDIATE */
-SLJIT_S390X_RILA(slfi, 0xc20500000000, sljit_u32)
-
-#undef SLJIT_S390X_RILA
-
-/* RX-a form instructions */
-#define SLJIT_S390X_RXA(name, pattern) \
-SLJIT_S390X_INSTRUCTION(name, sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b) \
-{ \
- SLJIT_ASSERT((d & 0xfff) == d); \
-\
- return (pattern) | R20A(r) | R16A(x) | R12A(b) | (sljit_ins)(d & 0xfff); \
-}
-
-/* LOAD */
-SLJIT_S390X_RXA(l, 0x58000000)
-
-/* LOAD ADDRESS */
-SLJIT_S390X_RXA(la, 0x41000000)
-
-/* LOAD HALFWORD */
-SLJIT_S390X_RXA(lh, 0x48000000)
-
-/* MULTIPLY SINGLE */
-SLJIT_S390X_RXA(ms, 0x71000000)
-
-/* STORE */
-SLJIT_S390X_RXA(st, 0x50000000)
-
-/* STORE CHARACTER */
-SLJIT_S390X_RXA(stc, 0x42000000)
-
-/* STORE HALFWORD */
-SLJIT_S390X_RXA(sth, 0x40000000)
-
-#undef SLJIT_S390X_RXA
-
-/* RXY-a instructions */
-#define SLJIT_S390X_RXYA(name, pattern, cond) \
-SLJIT_S390X_INSTRUCTION(name, sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b) \
-{ \
- SLJIT_ASSERT(cond); \
-\
- return (pattern) | R36A(r) | R32A(x) | R28A(b) | disp_s20(d); \
-}
-
-/* LOAD */
-SLJIT_S390X_RXYA(ly, 0xe30000000058, have_ldisp())
-SLJIT_S390X_RXYA(lg, 0xe30000000004, 1)
-SLJIT_S390X_RXYA(lgf, 0xe30000000014, 1)
-
-/* LOAD BYTE */
-SLJIT_S390X_RXYA(lb, 0xe30000000076, have_ldisp())
-SLJIT_S390X_RXYA(lgb, 0xe30000000077, have_ldisp())
-
-/* LOAD HALFWORD */
-SLJIT_S390X_RXYA(lhy, 0xe30000000078, have_ldisp())
-SLJIT_S390X_RXYA(lgh, 0xe30000000015, 1)
-
-/* LOAD LOGICAL */
-SLJIT_S390X_RXYA(llgf, 0xe30000000016, 1)
-
-/* LOAD LOGICAL CHARACTER */
-SLJIT_S390X_RXYA(llc, 0xe30000000094, have_eimm())
-SLJIT_S390X_RXYA(llgc, 0xe30000000090, 1)
-
-/* LOAD LOGICAL HALFWORD */
-SLJIT_S390X_RXYA(llh, 0xe30000000095, have_eimm())
-SLJIT_S390X_RXYA(llgh, 0xe30000000091, 1)
-
-/* MULTIPLY SINGLE */
-SLJIT_S390X_RXYA(msy, 0xe30000000051, have_ldisp())
-SLJIT_S390X_RXYA(msg, 0xe3000000000c, 1)
-
-/* STORE */
-SLJIT_S390X_RXYA(sty, 0xe30000000050, have_ldisp())
-SLJIT_S390X_RXYA(stg, 0xe30000000024, 1)
-
-/* STORE CHARACTER */
-SLJIT_S390X_RXYA(stcy, 0xe30000000072, have_ldisp())
-
-/* STORE HALFWORD */
-SLJIT_S390X_RXYA(sthy, 0xe30000000070, have_ldisp())
-
-#undef SLJIT_S390X_RXYA
-
-/* RSY-a instructions */
-#define SLJIT_S390X_RSYA(name, pattern, cond) \
-SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src, sljit_s32 d, sljit_gpr b) \
-{ \
- SLJIT_ASSERT(cond); \
-\
- return (pattern) | R36A(dst) | R32A(src) | R28A(b) | disp_s20(d); \
-}
-
-/* LOAD MULTIPLE */
-SLJIT_S390X_RSYA(lmg, 0xeb0000000004, 1)
-
-/* SHIFT LEFT LOGICAL */
-SLJIT_S390X_RSYA(sllg, 0xeb000000000d, 1)
-
-/* SHIFT RIGHT SINGLE */
-SLJIT_S390X_RSYA(srag, 0xeb000000000a, 1)
-
-/* STORE MULTIPLE */
-SLJIT_S390X_RSYA(stmg, 0xeb0000000024, 1)
-
-#undef SLJIT_S390X_RSYA
-
-/* RIE-f instructions (require general-instructions-extension facility) */
-#define SLJIT_S390X_RIEF(name, pattern) \
-SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src, sljit_u8 start, sljit_u8 end, sljit_u8 rot) \
-{ \
- sljit_ins i3, i4, i5; \
-\
- SLJIT_ASSERT(have_genext()); \
- i3 = (sljit_ins)start << 24; \
- i4 = (sljit_ins)end << 16; \
- i5 = (sljit_ins)rot << 8; \
-\
- return (pattern) | R36A(dst & 0xf) | R32A(src & 0xf) | i3 | i4 | i5; \
-}
-
-/* ROTATE THEN AND SELECTED BITS */
-/* SLJIT_S390X_RIEF(rnsbg, 0xec0000000054) */
-
-/* ROTATE THEN EXCLUSIVE OR SELECTED BITS */
-/* SLJIT_S390X_RIEF(rxsbg, 0xec0000000057) */
-
-/* ROTATE THEN OR SELECTED BITS */
-SLJIT_S390X_RIEF(rosbg, 0xec0000000056)
-
-/* ROTATE THEN INSERT SELECTED BITS */
-/* SLJIT_S390X_RIEF(risbg, 0xec0000000055) */
-/* SLJIT_S390X_RIEF(risbgn, 0xec0000000059) */
-
-/* ROTATE THEN INSERT SELECTED BITS HIGH */
-SLJIT_S390X_RIEF(risbhg, 0xec000000005d)
-
-/* ROTATE THEN INSERT SELECTED BITS LOW */
-/* SLJIT_S390X_RIEF(risblg, 0xec0000000051) */
-
-#undef SLJIT_S390X_RIEF
-
-/* RRF-c instructions (require load/store-on-condition 1 facility) */
-#define SLJIT_S390X_RRFC(name, pattern) \
-SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src, sljit_uw mask) \
-{ \
- sljit_ins m3; \
-\
- SLJIT_ASSERT(have_lscond1()); \
- m3 = (sljit_ins)(mask & 0xf) << 12; \
-\
- return (pattern) | m3 | R4A(dst) | R0A(src); \
-}
-
-/* LOAD HALFWORD IMMEDIATE ON CONDITION */
-SLJIT_S390X_RRFC(locr, 0xb9f20000)
-SLJIT_S390X_RRFC(locgr, 0xb9e20000)
-
-#undef SLJIT_S390X_RRFC
-
-/* RIE-g instructions (require load/store-on-condition 2 facility) */
-#define SLJIT_S390X_RIEG(name, pattern) \
-SLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, sljit_sw imm, sljit_uw mask) \
-{ \
- sljit_ins m3, i2; \
-\
- SLJIT_ASSERT(have_lscond2()); \
- m3 = (sljit_ins)(mask & 0xf) << 32; \
- i2 = (sljit_ins)(imm & 0xffffL) << 16; \
-\
- return (pattern) | R36A(reg) | m3 | i2; \
-}
-
-/* LOAD HALFWORD IMMEDIATE ON CONDITION */
-SLJIT_S390X_RIEG(lochi, 0xec0000000042)
-SLJIT_S390X_RIEG(locghi, 0xec0000000046)
-
-#undef SLJIT_S390X_RIEG
-
-#define SLJIT_S390X_RILB(name, pattern, cond) \
-SLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, sljit_sw ri) \
-{ \
- SLJIT_ASSERT(cond); \
-\
- return (pattern) | R36A(reg) | (sljit_ins)(ri & 0xffffffff); \
-}
-
-/* BRANCH RELATIVE AND SAVE LONG */
-SLJIT_S390X_RILB(brasl, 0xc00500000000, 1)
-
-/* LOAD ADDRESS RELATIVE LONG */
-SLJIT_S390X_RILB(larl, 0xc00000000000, 1)
-
-/* LOAD RELATIVE LONG */
-SLJIT_S390X_RILB(lgrl, 0xc40800000000, have_genext())
-
-#undef SLJIT_S390X_RILB
-
-SLJIT_S390X_INSTRUCTION(br, sljit_gpr target)
-{
- return 0x07f0 | target;
-}
-
-SLJIT_S390X_INSTRUCTION(brc, sljit_uw mask, sljit_sw target)
-{
- sljit_ins m1 = (sljit_ins)(mask & 0xf) << 20;
- sljit_ins ri2 = (sljit_ins)target & 0xffff;
- return 0xa7040000L | m1 | ri2;
-}
-
-SLJIT_S390X_INSTRUCTION(brcl, sljit_uw mask, sljit_sw target)
-{
- sljit_ins m1 = (sljit_ins)(mask & 0xf) << 36;
- sljit_ins ri2 = (sljit_ins)target & 0xffffffff;
- return 0xc00400000000L | m1 | ri2;
-}
-
-SLJIT_S390X_INSTRUCTION(flogr, sljit_gpr dst, sljit_gpr src)
-{
- SLJIT_ASSERT(have_eimm());
- return 0xb9830000 | R8A(dst) | R0A(src);
-}
-
-/* INSERT PROGRAM MASK */
-SLJIT_S390X_INSTRUCTION(ipm, sljit_gpr dst)
-{
- return 0xb2220000 | R4A(dst);
-}
-
-/* SET PROGRAM MASK */
-SLJIT_S390X_INSTRUCTION(spm, sljit_gpr dst)
-{
- return 0x0400 | R4A(dst);
-}
-
-/* ROTATE THEN INSERT SELECTED BITS HIGH (ZERO) */
-SLJIT_S390X_INSTRUCTION(risbhgz, sljit_gpr dst, sljit_gpr src, sljit_u8 start, sljit_u8 end, sljit_u8 rot)
-{
- return risbhg(dst, src, start, 0x8 | end, rot);
-}
-
-#undef SLJIT_S390X_INSTRUCTION
-
-static sljit_s32 update_zero_overflow(struct sljit_compiler *compiler, sljit_s32 op, sljit_gpr dst_r)
-{
- /* Condition codes: bits 18 and 19.
- Transformation:
- 0 (zero and no overflow) : unchanged
- 1 (non-zero and no overflow) : unchanged
- 2 (zero and overflow) : decreased by 1
- 3 (non-zero and overflow) : decreased by 1 if non-zero */
- FAIL_IF(push_inst(compiler, brc(0xc, 2 + 2 + ((op & SLJIT_32) ? 1 : 2) + 2 + 3 + 1)));
- FAIL_IF(push_inst(compiler, ipm(tmp1)));
- FAIL_IF(push_inst(compiler, (op & SLJIT_32) ? or(dst_r, dst_r) : ogr(dst_r, dst_r)));
- FAIL_IF(push_inst(compiler, brc(0x8, 2 + 3)));
- FAIL_IF(push_inst(compiler, slfi(tmp1, 0x10000000)));
- FAIL_IF(push_inst(compiler, spm(tmp1)));
- return SLJIT_SUCCESS;
-}
-
-/* load 64-bit immediate into register without clobbering flags */
-static sljit_s32 push_load_imm_inst(struct sljit_compiler *compiler, sljit_gpr target, sljit_sw v)
-{
- /* 4 byte instructions */
- if (is_s16(v))
- return push_inst(compiler, lghi(target, (sljit_s16)v));
-
- if (((sljit_uw)v & ~(sljit_uw)0x000000000000ffff) == 0)
- return push_inst(compiler, llill(target, (sljit_u16)v));
-
- if (((sljit_uw)v & ~(sljit_uw)0x00000000ffff0000) == 0)
- return push_inst(compiler, llilh(target, (sljit_u16)(v >> 16)));
-
- if (((sljit_uw)v & ~(sljit_uw)0x0000ffff00000000) == 0)
- return push_inst(compiler, llihl(target, (sljit_u16)(v >> 32)));
-
- if (((sljit_uw)v & ~(sljit_uw)0xffff000000000000) == 0)
- return push_inst(compiler, llihh(target, (sljit_u16)(v >> 48)));
-
- /* 6 byte instructions (requires extended immediate facility) */
- if (have_eimm()) {
- if (is_s32(v))
- return push_inst(compiler, lgfi(target, (sljit_s32)v));
-
- if (((sljit_uw)v >> 32) == 0)
- return push_inst(compiler, llilf(target, (sljit_u32)v));
-
- if (((sljit_uw)v << 32) == 0)
- return push_inst(compiler, llihf(target, (sljit_u32)((sljit_uw)v >> 32)));
-
- FAIL_IF(push_inst(compiler, llilf(target, (sljit_u32)v)));
- return push_inst(compiler, iihf(target, (sljit_u32)(v >> 32)));
- }
-
- /* TODO(mundaym): instruction sequences that don't use extended immediates */
- abort();
-}
-
-struct addr {
- sljit_gpr base;
- sljit_gpr index;
- sljit_s32 offset;
-};
-
-/* transform memory operand into D(X,B) form with a signed 20-bit offset */
-static sljit_s32 make_addr_bxy(struct sljit_compiler *compiler,
- struct addr *addr, sljit_s32 mem, sljit_sw off,
- sljit_gpr tmp /* clobbered, must not be r0 */)
-{
- sljit_gpr base = r0;
- sljit_gpr index = r0;
-
- SLJIT_ASSERT(tmp != r0);
- if (mem & REG_MASK)
- base = gpr(mem & REG_MASK);
-
- if (mem & OFFS_REG_MASK) {
- index = gpr(OFFS_REG(mem));
- if (off != 0) {
- /* shift and put the result into tmp */
- SLJIT_ASSERT(0 <= off && off < 64);
- FAIL_IF(push_inst(compiler, sllg(tmp, index, (sljit_s32)off, 0)));
- index = tmp;
- off = 0; /* clear offset */
- }
- }
- else if (!is_s20(off)) {
- FAIL_IF(push_load_imm_inst(compiler, tmp, off));
- index = tmp;
- off = 0; /* clear offset */
- }
- addr->base = base;
- addr->index = index;
- addr->offset = (sljit_s32)off;
- return SLJIT_SUCCESS;
-}
-
-/* transform memory operand into D(X,B) form with an unsigned 12-bit offset */
-static sljit_s32 make_addr_bx(struct sljit_compiler *compiler,
- struct addr *addr, sljit_s32 mem, sljit_sw off,
- sljit_gpr tmp /* clobbered, must not be r0 */)
-{
- sljit_gpr base = r0;
- sljit_gpr index = r0;
-
- SLJIT_ASSERT(tmp != r0);
- if (mem & REG_MASK)
- base = gpr(mem & REG_MASK);
-
- if (mem & OFFS_REG_MASK) {
- index = gpr(OFFS_REG(mem));
- if (off != 0) {
- /* shift and put the result into tmp */
- SLJIT_ASSERT(0 <= off && off < 64);
- FAIL_IF(push_inst(compiler, sllg(tmp, index, (sljit_s32)off, 0)));
- index = tmp;
- off = 0; /* clear offset */
- }
- }
- else if (!is_u12(off)) {
- FAIL_IF(push_load_imm_inst(compiler, tmp, off));
- index = tmp;
- off = 0; /* clear offset */
- }
- addr->base = base;
- addr->index = index;
- addr->offset = (sljit_s32)off;
- return SLJIT_SUCCESS;
-}
-
-#define EVAL(op, r, addr) op(r, addr.offset, addr.index, addr.base)
-#define WHEN(cond, r, i1, i2, addr) \
- (cond) ? EVAL(i1, r, addr) : EVAL(i2, r, addr)
-
-/* May clobber tmp1. */
-static sljit_s32 load_word(struct sljit_compiler *compiler, sljit_gpr dst_r,
- sljit_s32 src, sljit_sw srcw,
- sljit_s32 is_32bit)
-{
- struct addr addr;
- sljit_ins ins;
-
- SLJIT_ASSERT(src & SLJIT_MEM);
-
- if (is_32bit && ((src & OFFS_REG_MASK) || is_u12(srcw) || !is_s20(srcw))) {
- FAIL_IF(make_addr_bx(compiler, &addr, src, srcw, tmp1));
- return push_inst(compiler, 0x58000000 /* l */ | R20A(dst_r) | R16A(addr.index) | R12A(addr.base) | (sljit_ins)addr.offset);
- }
-
- FAIL_IF(make_addr_bxy(compiler, &addr, src, srcw, tmp1));
-
- ins = is_32bit ? 0xe30000000058 /* ly */ : 0xe30000000004 /* lg */;
- return push_inst(compiler, ins | R36A(dst_r) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset));
-}
-
-/* May clobber tmp1. */
-static sljit_s32 load_unsigned_word(struct sljit_compiler *compiler, sljit_gpr dst_r,
- sljit_s32 src, sljit_sw srcw,
- sljit_s32 is_32bit)
-{
- struct addr addr;
- sljit_ins ins;
-
- SLJIT_ASSERT(src & SLJIT_MEM);
-
- FAIL_IF(make_addr_bxy(compiler, &addr, src, srcw, tmp1));
-
- ins = is_32bit ? 0xe30000000016 /* llgf */ : 0xe30000000004 /* lg */;
- return push_inst(compiler, ins | R36A(dst_r) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset));
-}
-
-/* May clobber tmp1. */
-static sljit_s32 store_word(struct sljit_compiler *compiler, sljit_gpr src_r,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 is_32bit)
-{
- struct addr addr;
- sljit_ins ins;
-
- SLJIT_ASSERT(dst & SLJIT_MEM);
-
- if (is_32bit && ((dst & OFFS_REG_MASK) || is_u12(dstw) || !is_s20(dstw))) {
- FAIL_IF(make_addr_bx(compiler, &addr, dst, dstw, tmp1));
- return push_inst(compiler, 0x50000000 /* st */ | R20A(src_r) | R16A(addr.index) | R12A(addr.base) | (sljit_ins)addr.offset);
- }
-
- FAIL_IF(make_addr_bxy(compiler, &addr, dst, dstw, tmp1));
-
- ins = is_32bit ? 0xe30000000050 /* sty */ : 0xe30000000024 /* stg */;
- return push_inst(compiler, ins | R36A(src_r) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset));
-}
-
-#undef WHEN
-
-static sljit_s32 emit_move(struct sljit_compiler *compiler,
- sljit_gpr dst_r,
- sljit_s32 src, sljit_sw srcw)
-{
- SLJIT_ASSERT(!IS_GPR_REG(src) || dst_r != gpr(src & REG_MASK));
-
- if (src & SLJIT_IMM)
- return push_load_imm_inst(compiler, dst_r, srcw);
-
- if (src & SLJIT_MEM)
- return load_word(compiler, dst_r, src, srcw, (compiler->mode & SLJIT_32) != 0);
-
- sljit_gpr src_r = gpr(src & REG_MASK);
- return push_inst(compiler, (compiler->mode & SLJIT_32) ? lr(dst_r, src_r) : lgr(dst_r, src_r));
-}
-
-static sljit_s32 emit_rr(struct sljit_compiler *compiler, sljit_ins ins,
- sljit_s32 dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_gpr dst_r = tmp0;
- sljit_gpr src_r = tmp1;
- sljit_s32 needs_move = 1;
-
- if (FAST_IS_REG(dst)) {
- dst_r = gpr(dst);
-
- if (dst == src1)
- needs_move = 0;
- else if (dst == src2) {
- dst_r = tmp0;
- needs_move = 2;
- }
- }
-
- if (needs_move)
- FAIL_IF(emit_move(compiler, dst_r, src1, src1w));
-
- if (FAST_IS_REG(src2))
- src_r = gpr(src2);
- else
- FAIL_IF(emit_move(compiler, tmp1, src2, src2w));
-
- FAIL_IF(push_inst(compiler, ins | R4A(dst_r) | R0A(src_r)));
-
- if (needs_move != 2)
- return SLJIT_SUCCESS;
-
- dst_r = gpr(dst & REG_MASK);
- return push_inst(compiler, (compiler->mode & SLJIT_32) ? lr(dst_r, tmp0) : lgr(dst_r, tmp0));
-}
-
-static sljit_s32 emit_rr1(struct sljit_compiler *compiler, sljit_ins ins,
- sljit_s32 dst,
- sljit_s32 src1, sljit_sw src1w)
-{
- sljit_gpr dst_r = FAST_IS_REG(dst) ? gpr(dst) : tmp0;
- sljit_gpr src_r = tmp1;
-
- if (FAST_IS_REG(src1))
- src_r = gpr(src1);
- else
- FAIL_IF(emit_move(compiler, tmp1, src1, src1w));
-
- return push_inst(compiler, ins | R4A(dst_r) | R0A(src_r));
-}
-
-static sljit_s32 emit_rrf(struct sljit_compiler *compiler, sljit_ins ins,
- sljit_s32 dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_gpr dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;
- sljit_gpr src1_r = tmp0;
- sljit_gpr src2_r = tmp1;
-
- if (FAST_IS_REG(src1))
- src1_r = gpr(src1);
- else
- FAIL_IF(emit_move(compiler, tmp0, src1, src1w));
-
- if (FAST_IS_REG(src2))
- src2_r = gpr(src2);
- else
- FAIL_IF(emit_move(compiler, tmp1, src2, src2w));
-
- return push_inst(compiler, ins | R4A(dst_r) | R0A(src1_r) | R12A(src2_r));
-}
-
-typedef enum {
- RI_A,
- RIL_A,
-} emit_ril_type;
-
-static sljit_s32 emit_ri(struct sljit_compiler *compiler, sljit_ins ins,
- sljit_s32 dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_sw src2w,
- emit_ril_type type)
-{
- sljit_gpr dst_r = tmp0;
- sljit_s32 needs_move = 1;
-
- if (FAST_IS_REG(dst)) {
- dst_r = gpr(dst);
-
- if (dst == src1)
- needs_move = 0;
- }
-
- if (needs_move)
- FAIL_IF(emit_move(compiler, dst_r, src1, src1w));
-
- if (type == RIL_A)
- return push_inst(compiler, ins | R36A(dst_r) | (src2w & 0xffffffff));
- return push_inst(compiler, ins | R20A(dst_r) | (src2w & 0xffff));
-}
-
-static sljit_s32 emit_rie_d(struct sljit_compiler *compiler, sljit_ins ins,
- sljit_s32 dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_sw src2w)
-{
- sljit_gpr dst_r = FAST_IS_REG(dst) ? gpr(dst) : tmp0;
- sljit_gpr src_r = tmp0;
-
- if (!FAST_IS_REG(src1))
- FAIL_IF(emit_move(compiler, tmp0, src1, src1w));
- else
- src_r = gpr(src1 & REG_MASK);
-
- return push_inst(compiler, ins | R36A(dst_r) | R32A(src_r) | (sljit_ins)(src2w & 0xffff) << 16);
-}
-
-typedef enum {
- RX_A,
- RXY_A,
-} emit_rx_type;
-
-static sljit_s32 emit_rx(struct sljit_compiler *compiler, sljit_ins ins,
- sljit_s32 dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w,
- emit_rx_type type)
-{
- sljit_gpr dst_r = tmp0;
- sljit_s32 needs_move = 1;
- sljit_gpr base, index;
-
- SLJIT_ASSERT(src2 & SLJIT_MEM);
-
- if (FAST_IS_REG(dst)) {
- dst_r = gpr(dst);
-
- if (dst == src1)
- needs_move = 0;
- else if (dst == (src2 & REG_MASK) || (dst == OFFS_REG(src2))) {
- dst_r = tmp0;
- needs_move = 2;
- }
- }
-
- if (needs_move)
- FAIL_IF(emit_move(compiler, dst_r, src1, src1w));
-
- base = gpr(src2 & REG_MASK);
- index = tmp0;
-
- if (src2 & OFFS_REG_MASK) {
- index = gpr(OFFS_REG(src2));
-
- if (src2w != 0) {
- FAIL_IF(push_inst(compiler, sllg(tmp1, index, src2w & 0x3, 0)));
- src2w = 0;
- index = tmp1;
- }
- } else if ((type == RX_A && !is_u12(src2w)) || (type == RXY_A && !is_s20(src2w))) {
- FAIL_IF(push_load_imm_inst(compiler, tmp1, src2w));
-
- if (src2 & REG_MASK)
- index = tmp1;
- else
- base = tmp1;
- src2w = 0;
- }
-
- if (type == RX_A)
- ins |= R20A(dst_r) | R16A(index) | R12A(base) | (sljit_ins)src2w;
- else
- ins |= R36A(dst_r) | R32A(index) | R28A(base) | disp_s20((sljit_s32)src2w);
-
- FAIL_IF(push_inst(compiler, ins));
-
- if (needs_move != 2)
- return SLJIT_SUCCESS;
-
- dst_r = gpr(dst);
- return push_inst(compiler, (compiler->mode & SLJIT_32) ? lr(dst_r, tmp0) : lgr(dst_r, tmp0));
-}
-
-static sljit_s32 emit_siy(struct sljit_compiler *compiler, sljit_ins ins,
- sljit_s32 dst, sljit_sw dstw,
- sljit_sw srcw)
-{
- SLJIT_ASSERT(dst & SLJIT_MEM);
-
- sljit_gpr dst_r = tmp1;
-
- if (dst & OFFS_REG_MASK) {
- sljit_gpr index = tmp1;
-
- if ((dstw & 0x3) == 0)
- index = gpr(OFFS_REG(dst));
- else
- FAIL_IF(push_inst(compiler, sllg(tmp1, index, dstw & 0x3, 0)));
-
- FAIL_IF(push_inst(compiler, la(tmp1, 0, dst_r, index)));
- dstw = 0;
- }
- else if (!is_s20(dstw)) {
- FAIL_IF(push_load_imm_inst(compiler, tmp1, dstw));
-
- if (dst & REG_MASK)
- FAIL_IF(push_inst(compiler, la(tmp1, 0, dst_r, tmp1)));
-
- dstw = 0;
- }
- else
- dst_r = gpr(dst & REG_MASK);
-
- return push_inst(compiler, ins | ((sljit_ins)(srcw & 0xff) << 32) | R28A(dst_r) | disp_s20((sljit_s32)dstw));
-}
-
-struct ins_forms {
- sljit_ins op_r;
- sljit_ins op_gr;
- sljit_ins op_rk;
- sljit_ins op_grk;
- sljit_ins op;
- sljit_ins op_y;
- sljit_ins op_g;
-};
-
-static sljit_s32 emit_commutative(struct sljit_compiler *compiler, const struct ins_forms *forms,
- sljit_s32 dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 mode = compiler->mode;
- sljit_ins ins, ins_k;
-
- if ((src1 | src2) & SLJIT_MEM) {
- sljit_ins ins12, ins20;
-
- if (mode & SLJIT_32) {
- ins12 = forms->op;
- ins20 = forms->op_y;
- }
- else {
- ins12 = 0;
- ins20 = forms->op_g;
- }
-
- if (ins12 && ins20) {
- /* Extra instructions needed for address computation can be executed independently. */
- if ((src2 & SLJIT_MEM) && (!(src1 & SLJIT_MEM)
- || ((src1 & OFFS_REG_MASK) ? (src1w & 0x3) == 0 : is_s20(src1w)))) {
- if ((src2 & OFFS_REG_MASK) || is_u12(src2w) || !is_s20(src2w))
- return emit_rx(compiler, ins12, dst, src1, src1w, src2, src2w, RX_A);
-
- return emit_rx(compiler, ins20, dst, src1, src1w, src2, src2w, RXY_A);
- }
-
- if (src1 & SLJIT_MEM) {
- if ((src1 & OFFS_REG_MASK) || is_u12(src1w) || !is_s20(src1w))
- return emit_rx(compiler, ins12, dst, src2, src2w, src1, src1w, RX_A);
-
- return emit_rx(compiler, ins20, dst, src2, src2w, src1, src1w, RXY_A);
- }
- }
- else if (ins12 || ins20) {
- emit_rx_type rx_type;
-
- if (ins12) {
- rx_type = RX_A;
- ins = ins12;
- }
- else {
- rx_type = RXY_A;
- ins = ins20;
- }
-
- if ((src2 & SLJIT_MEM) && (!(src1 & SLJIT_MEM)
- || ((src1 & OFFS_REG_MASK) ? (src1w & 0x3) == 0 : (rx_type == RX_A ? is_u12(src1w) : is_s20(src1w)))))
- return emit_rx(compiler, ins, dst, src1, src1w, src2, src2w, rx_type);
-
- if (src1 & SLJIT_MEM)
- return emit_rx(compiler, ins, dst, src2, src2w, src1, src1w, rx_type);
- }
- }
-
- if (mode & SLJIT_32) {
- ins = forms->op_r;
- ins_k = forms->op_rk;
- }
- else {
- ins = forms->op_gr;
- ins_k = forms->op_grk;
- }
-
- SLJIT_ASSERT(ins != 0 || ins_k != 0);
-
- if (ins && FAST_IS_REG(dst)) {
- if (dst == src1)
- return emit_rr(compiler, ins, dst, src1, src1w, src2, src2w);
-
- if (dst == src2)
- return emit_rr(compiler, ins, dst, src2, src2w, src1, src1w);
- }
-
- if (ins_k == 0)
- return emit_rr(compiler, ins, dst, src1, src1w, src2, src2w);
-
- return emit_rrf(compiler, ins_k, dst, src1, src1w, src2, src2w);
-}
-
-static sljit_s32 emit_non_commutative(struct sljit_compiler *compiler, const struct ins_forms *forms,
- sljit_s32 dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 mode = compiler->mode;
- sljit_ins ins;
-
- if (src2 & SLJIT_MEM) {
- sljit_ins ins12, ins20;
-
- if (mode & SLJIT_32) {
- ins12 = forms->op;
- ins20 = forms->op_y;
- }
- else {
- ins12 = 0;
- ins20 = forms->op_g;
- }
-
- if (ins12 && ins20) {
- if ((src2 & OFFS_REG_MASK) || is_u12(src2w) || !is_s20(src2w))
- return emit_rx(compiler, ins12, dst, src1, src1w, src2, src2w, RX_A);
-
- return emit_rx(compiler, ins20, dst, src1, src1w, src2, src2w, RXY_A);
- }
- else if (ins12)
- return emit_rx(compiler, ins12, dst, src1, src1w, src2, src2w, RX_A);
- else if (ins20)
- return emit_rx(compiler, ins20, dst, src1, src1w, src2, src2w, RXY_A);
- }
-
- ins = (mode & SLJIT_32) ? forms->op_rk : forms->op_grk;
-
- if (ins == 0 || (FAST_IS_REG(dst) && dst == src1))
- return emit_rr(compiler, (mode & SLJIT_32) ? forms->op_r : forms->op_gr, dst, src1, src1w, src2, src2w);
-
- return emit_rrf(compiler, ins, dst, src1, src1w, src2, src2w);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
-{
- struct sljit_label *label;
- struct sljit_jump *jump;
- struct sljit_s390x_const *const_;
- struct sljit_put_label *put_label;
- sljit_sw executable_offset;
- sljit_uw ins_size = 0; /* instructions */
- sljit_uw pool_size = 0; /* literal pool */
- sljit_uw pad_size;
- sljit_uw i, j = 0;
- struct sljit_memory_fragment *buf;
- void *code, *code_ptr;
- sljit_uw *pool, *pool_ptr;
- sljit_sw source, offset; /* TODO(carenas): only need 32 bit */
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_generate_code(compiler));
- reverse_buf(compiler);
-
- /* branch handling */
- label = compiler->labels;
- jump = compiler->jumps;
- put_label = compiler->put_labels;
-
- /* TODO(carenas): compiler->executable_size could be calculated
- * before to avoid the following loop (except for
- * pool_size)
- */
- /* calculate the size of the code */
- for (buf = compiler->buf; buf != NULL; buf = buf->next) {
- sljit_uw len = buf->used_size / sizeof(sljit_ins);
- sljit_ins *ibuf = (sljit_ins *)buf->memory;
- for (i = 0; i < len; ++i, ++j) {
- sljit_ins ins = ibuf[i];
-
- /* TODO(carenas): instruction tag vs size/addr == j
- * using instruction tags for const is creative
- * but unlike all other architectures, and is not
- * done consistently for all other objects.
- * This might need reviewing later.
- */
- if (ins & sljit_ins_const) {
- pool_size += sizeof(*pool);
- ins &= ~sljit_ins_const;
- }
- if (label && label->size == j) {
- label->size = ins_size;
- label = label->next;
- }
- if (jump && jump->addr == j) {
- if ((jump->flags & SLJIT_REWRITABLE_JUMP) || (jump->flags & JUMP_ADDR)) {
- /* encoded: */
- /* brasl %r14, <rel_addr> (or brcl <mask>, <rel_addr>) */
- /* replace with: */
- /* lgrl %r1, <pool_addr> */
- /* bras %r14, %r1 (or bcr <mask>, %r1) */
- pool_size += sizeof(*pool);
- ins_size += 2;
- }
- jump = jump->next;
- }
- if (put_label && put_label->addr == j) {
- pool_size += sizeof(*pool);
- put_label = put_label->next;
- }
- ins_size += sizeof_ins(ins);
- }
- }
-
- /* emit trailing label */
- if (label && label->size == j) {
- label->size = ins_size;
- label = label->next;
- }
-
- SLJIT_ASSERT(!label);
- SLJIT_ASSERT(!jump);
- SLJIT_ASSERT(!put_label);
-
- /* pad code size to 8 bytes so is accessible with half word offsets */
- /* the literal pool needs to be doubleword aligned */
- pad_size = ((ins_size + 7UL) & ~7UL) - ins_size;
- SLJIT_ASSERT(pad_size < 8UL);
-
- /* allocate target buffer */
- code = SLJIT_MALLOC_EXEC(ins_size + pad_size + pool_size,
- compiler->exec_allocator_data);
- PTR_FAIL_WITH_EXEC_IF(code);
- code_ptr = code;
- executable_offset = SLJIT_EXEC_OFFSET(code);
-
- /* TODO(carenas): pool is optional, and the ABI recommends it to
- * be created before the function code, instead of
- * globally; if generated code is too big could
- * need offsets bigger than 32bit words and asser()
- */
- pool = (sljit_uw *)((sljit_uw)code + ins_size + pad_size);
- pool_ptr = pool;
- const_ = (struct sljit_s390x_const *)compiler->consts;
-
- /* update label addresses */
- label = compiler->labels;
- while (label) {
- label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(
- (sljit_uw)code_ptr + label->size, executable_offset);
- label = label->next;
- }
-
- /* reset jumps */
- jump = compiler->jumps;
- put_label = compiler->put_labels;
-
- /* emit the code */
- j = 0;
- for (buf = compiler->buf; buf != NULL; buf = buf->next) {
- sljit_uw len = buf->used_size / sizeof(sljit_ins);
- sljit_ins *ibuf = (sljit_ins *)buf->memory;
- for (i = 0; i < len; ++i, ++j) {
- sljit_ins ins = ibuf[i];
- if (ins & sljit_ins_const) {
- /* clear the const tag */
- ins &= ~sljit_ins_const;
-
- /* update instruction with relative address of constant */
- source = (sljit_sw)code_ptr;
- offset = (sljit_sw)pool_ptr - source;
-
- SLJIT_ASSERT(!(offset & 1));
- offset >>= 1; /* halfword (not byte) offset */
- SLJIT_ASSERT(is_s32(offset));
-
- ins |= (sljit_ins)offset & 0xffffffff;
-
- /* update address */
- const_->const_.addr = (sljit_uw)pool_ptr;
-
- /* store initial value into pool and update pool address */
- *(pool_ptr++) = (sljit_uw)const_->init_value;
-
- /* move to next constant */
- const_ = (struct sljit_s390x_const *)const_->const_.next;
- }
- if (jump && jump->addr == j) {
- sljit_sw target = (sljit_sw)((jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target);
- if ((jump->flags & SLJIT_REWRITABLE_JUMP) || (jump->flags & JUMP_ADDR)) {
- jump->addr = (sljit_uw)pool_ptr;
-
- /* load address into tmp1 */
- source = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
- offset = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(pool_ptr, executable_offset) - source;
-
- SLJIT_ASSERT(!(offset & 1));
- offset >>= 1;
- SLJIT_ASSERT(is_s32(offset));
-
- encode_inst(&code_ptr, lgrl(tmp1, offset & 0xffffffff));
-
- /* store jump target into pool and update pool address */
- *(pool_ptr++) = (sljit_uw)target;
-
- /* branch to tmp1 */
- sljit_ins op = (ins >> 32) & 0xf;
- sljit_ins arg = (ins >> 36) & 0xf;
- switch (op) {
- case 4: /* brcl -> bcr */
- ins = bcr(arg, tmp1);
- break;
- case 5: /* brasl -> basr */
- ins = basr(arg, tmp1);
- break;
- default:
- abort();
- }
- }
- else {
- jump->addr = (sljit_uw)code_ptr + 2;
- source = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
- offset = target - source;
-
- /* offset must be halfword aligned */
- SLJIT_ASSERT(!(offset & 1));
- offset >>= 1;
- SLJIT_ASSERT(is_s32(offset)); /* TODO(mundaym): handle arbitrary offsets */
-
- /* patch jump target */
- ins |= (sljit_ins)offset & 0xffffffff;
- }
- jump = jump->next;
- }
- if (put_label && put_label->addr == j) {
- source = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
-
- SLJIT_ASSERT(put_label->label);
- put_label->addr = (sljit_uw)code_ptr;
-
- /* store target into pool */
- *pool_ptr = put_label->label->addr;
- offset = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(pool_ptr, executable_offset) - source;
- pool_ptr++;
-
- SLJIT_ASSERT(!(offset & 1));
- offset >>= 1;
- SLJIT_ASSERT(is_s32(offset));
- ins |= (sljit_ins)offset & 0xffffffff;
-
- put_label = put_label->next;
- }
- encode_inst(&code_ptr, ins);
- }
- }
- SLJIT_ASSERT((sljit_u8 *)code + ins_size == code_ptr);
- SLJIT_ASSERT((sljit_u8 *)pool + pool_size == (sljit_u8 *)pool_ptr);
-
- compiler->error = SLJIT_ERR_COMPILED;
- compiler->executable_offset = executable_offset;
- compiler->executable_size = ins_size;
- code = SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
- code_ptr = SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
- SLJIT_CACHE_FLUSH(code, code_ptr);
- SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
- return code;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
-{
- /* TODO(mundaym): implement all */
- switch (feature_type) {
- case SLJIT_HAS_FPU:
- case SLJIT_HAS_CLZ:
- case SLJIT_HAS_ROT:
- case SLJIT_HAS_PREFETCH:
- return 1;
- case SLJIT_HAS_CTZ:
- return 2;
- case SLJIT_HAS_CMOV:
- return have_lscond1() ? 1 : 0;
- }
- return 0;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)
-{
- return (type >= SLJIT_UNORDERED && type <= SLJIT_ORDERED_LESS_EQUAL);
-}
-
-/* --------------------------------------------------------------------- */
-/* Entry, exit */
-/* --------------------------------------------------------------------- */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options);
- sljit_s32 offset, i, tmp;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
- set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
-
- /* Saved registers are stored in callee allocated save area. */
- SLJIT_ASSERT(gpr(SLJIT_FIRST_SAVED_REG) == r6 && gpr(SLJIT_S0) == r13);
-
- offset = 2 * SSIZE_OF(sw);
- if (saveds + scratches >= SLJIT_NUMBER_OF_REGISTERS) {
- if (saved_arg_count == 0) {
- FAIL_IF(push_inst(compiler, stmg(r6, r14, offset, r15)));
- offset += 9 * SSIZE_OF(sw);
- } else {
- FAIL_IF(push_inst(compiler, stmg(r6, r13 - (sljit_gpr)saved_arg_count, offset, r15)));
- offset += (8 - saved_arg_count) * SSIZE_OF(sw);
- }
- } else {
- if (scratches == SLJIT_FIRST_SAVED_REG) {
- FAIL_IF(push_inst(compiler, stg(r6, offset, 0, r15)));
- offset += SSIZE_OF(sw);
- } else if (scratches > SLJIT_FIRST_SAVED_REG) {
- FAIL_IF(push_inst(compiler, stmg(r6, r6 + (sljit_gpr)(scratches - SLJIT_FIRST_SAVED_REG), offset, r15)));
- offset += (scratches - (SLJIT_FIRST_SAVED_REG - 1)) * SSIZE_OF(sw);
- }
-
- if (saved_arg_count == 0) {
- if (saveds == 0) {
- FAIL_IF(push_inst(compiler, stg(r14, offset, 0, r15)));
- offset += SSIZE_OF(sw);
- } else {
- FAIL_IF(push_inst(compiler, stmg(r14 - (sljit_gpr)saveds, r14, offset, r15)));
- offset += (saveds + 1) * SSIZE_OF(sw);
- }
- } else if (saveds > saved_arg_count) {
- if (saveds == saved_arg_count + 1) {
- FAIL_IF(push_inst(compiler, stg(r14 - (sljit_gpr)saveds, offset, 0, r15)));
- offset += SSIZE_OF(sw);
- } else {
- FAIL_IF(push_inst(compiler, stmg(r14 - (sljit_gpr)saveds, r13 - (sljit_gpr)saved_arg_count, offset, r15)));
- offset += (saveds - saved_arg_count) * SSIZE_OF(sw);
- }
- }
- }
-
- if (saved_arg_count > 0) {
- FAIL_IF(push_inst(compiler, stg(r14, offset, 0, r15)));
- offset += SSIZE_OF(sw);
- }
-
- tmp = SLJIT_FS0 - fsaveds;
- for (i = SLJIT_FS0; i > tmp; i--) {
- FAIL_IF(push_inst(compiler, 0x60000000 /* std */ | F20(i) | R12A(r15) | (sljit_ins)offset));
- offset += SSIZE_OF(sw);
- }
-
- for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
- FAIL_IF(push_inst(compiler, 0x60000000 /* std */ | F20(i) | R12A(r15) | (sljit_ins)offset));
- offset += SSIZE_OF(sw);
- }
-
- local_size = (local_size + SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE + 0xf) & ~0xf;
- compiler->local_size = local_size;
-
- FAIL_IF(push_inst(compiler, 0xe30000000071 /* lay */ | R36A(r15) | R28A(r15) | disp_s20(-local_size)));
-
- if (options & SLJIT_ENTER_REG_ARG)
- return SLJIT_SUCCESS;
-
- arg_types >>= SLJIT_ARG_SHIFT;
- saved_arg_count = 0;
- tmp = 0;
- while (arg_types > 0) {
- if ((arg_types & SLJIT_ARG_MASK) < SLJIT_ARG_TYPE_F64) {
- if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {
- FAIL_IF(push_inst(compiler, lgr(gpr(SLJIT_S0 - saved_arg_count), gpr(SLJIT_R0 + tmp))));
- saved_arg_count++;
- }
- tmp++;
- }
-
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- CHECK_ERROR();
- CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
- set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
-
- compiler->local_size = (local_size + SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE + 0xf) & ~0xf;
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_gpr last_reg)
-{
- sljit_s32 offset, i, tmp;
- sljit_s32 local_size = compiler->local_size;
- sljit_s32 saveds = compiler->saveds;
- sljit_s32 scratches = compiler->scratches;
- sljit_s32 kept_saveds_count = SLJIT_KEPT_SAVEDS_COUNT(compiler->options);
-
- if (is_u12(local_size))
- FAIL_IF(push_inst(compiler, 0x41000000 /* ly */ | R20A(r15) | R12A(r15) | (sljit_ins)local_size));
- else
- FAIL_IF(push_inst(compiler, 0xe30000000071 /* lay */ | R36A(r15) | R28A(r15) | disp_s20(local_size)));
-
- offset = 2 * SSIZE_OF(sw);
- if (saveds + scratches >= SLJIT_NUMBER_OF_REGISTERS) {
- if (kept_saveds_count == 0) {
- FAIL_IF(push_inst(compiler, lmg(r6, last_reg, offset, r15)));
- offset += 9 * SSIZE_OF(sw);
- } else {
- FAIL_IF(push_inst(compiler, lmg(r6, r13 - (sljit_gpr)kept_saveds_count, offset, r15)));
- offset += (8 - kept_saveds_count) * SSIZE_OF(sw);
- }
- } else {
- if (scratches == SLJIT_FIRST_SAVED_REG) {
- FAIL_IF(push_inst(compiler, lg(r6, offset, 0, r15)));
- offset += SSIZE_OF(sw);
- } else if (scratches > SLJIT_FIRST_SAVED_REG) {
- FAIL_IF(push_inst(compiler, lmg(r6, r6 + (sljit_gpr)(scratches - SLJIT_FIRST_SAVED_REG), offset, r15)));
- offset += (scratches - (SLJIT_FIRST_SAVED_REG - 1)) * SSIZE_OF(sw);
- }
-
- if (kept_saveds_count == 0) {
- if (saveds == 0) {
- if (last_reg == r14)
- FAIL_IF(push_inst(compiler, lg(r14, offset, 0, r15)));
- offset += SSIZE_OF(sw);
- } else if (saveds == 1 && last_reg == r13) {
- FAIL_IF(push_inst(compiler, lg(r13, offset, 0, r15)));
- offset += 2 * SSIZE_OF(sw);
- } else {
- FAIL_IF(push_inst(compiler, lmg(r14 - (sljit_gpr)saveds, last_reg, offset, r15)));
- offset += (saveds + 1) * SSIZE_OF(sw);
- }
- } else if (saveds > kept_saveds_count) {
- if (saveds == kept_saveds_count + 1) {
- FAIL_IF(push_inst(compiler, lg(r14 - (sljit_gpr)saveds, offset, 0, r15)));
- offset += SSIZE_OF(sw);
- } else {
- FAIL_IF(push_inst(compiler, lmg(r14 - (sljit_gpr)saveds, r13 - (sljit_gpr)kept_saveds_count, offset, r15)));
- offset += (saveds - kept_saveds_count) * SSIZE_OF(sw);
- }
- }
- }
-
- if (kept_saveds_count > 0) {
- if (last_reg == r14)
- FAIL_IF(push_inst(compiler, lg(r14, offset, 0, r15)));
- offset += SSIZE_OF(sw);
- }
-
- tmp = SLJIT_FS0 - compiler->fsaveds;
- for (i = SLJIT_FS0; i > tmp; i--) {
- FAIL_IF(push_inst(compiler, 0x68000000 /* ld */ | F20(i) | R12A(r15) | (sljit_ins)offset));
- offset += SSIZE_OF(sw);
- }
-
- for (i = compiler->fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
- FAIL_IF(push_inst(compiler, 0x68000000 /* ld */ | F20(i) | R12A(r15) | (sljit_ins)offset));
- offset += SSIZE_OF(sw);
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_return_void(compiler));
-
- FAIL_IF(emit_stack_frame_release(compiler, r14));
- return push_inst(compiler, br(r14)); /* return */
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,
- sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_return_to(compiler, src, srcw));
-
- if (src & SLJIT_MEM) {
- ADJUST_LOCAL_OFFSET(src, srcw);
- FAIL_IF(load_word(compiler, tmp1, src, srcw, 0 /* 64-bit */));
- src = TMP_REG2;
- srcw = 0;
- } else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
- FAIL_IF(push_inst(compiler, lgr(tmp1, gpr(src))));
- src = TMP_REG2;
- srcw = 0;
- }
-
- FAIL_IF(emit_stack_frame_release(compiler, r13));
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);
-}
-
-/* --------------------------------------------------------------------- */
-/* Operators */
-/* --------------------------------------------------------------------- */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
-{
- sljit_gpr arg0 = gpr(SLJIT_R0);
- sljit_gpr arg1 = gpr(SLJIT_R1);
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op0(compiler, op));
-
- op = GET_OPCODE(op) | (op & SLJIT_32);
- switch (op) {
- case SLJIT_BREAKPOINT:
- /* The following invalid instruction is emitted by gdb. */
- return push_inst(compiler, 0x0001 /* 2-byte trap */);
- case SLJIT_NOP:
- return push_inst(compiler, 0x0700 /* 2-byte nop */);
- case SLJIT_LMUL_UW:
- FAIL_IF(push_inst(compiler, mlgr(arg0, arg0)));
- break;
- case SLJIT_LMUL_SW:
- /* signed multiplication from: */
- /* Hacker's Delight, Second Edition: Chapter 8-3. */
- FAIL_IF(push_inst(compiler, srag(tmp0, arg0, 63, 0)));
- FAIL_IF(push_inst(compiler, srag(tmp1, arg1, 63, 0)));
- FAIL_IF(push_inst(compiler, ngr(tmp0, arg1)));
- FAIL_IF(push_inst(compiler, ngr(tmp1, arg0)));
-
- /* unsigned multiplication */
- FAIL_IF(push_inst(compiler, mlgr(arg0, arg0)));
-
- FAIL_IF(push_inst(compiler, sgr(arg0, tmp0)));
- FAIL_IF(push_inst(compiler, sgr(arg0, tmp1)));
- break;
- case SLJIT_DIV_U32:
- case SLJIT_DIVMOD_U32:
- FAIL_IF(push_inst(compiler, lhi(tmp0, 0)));
- FAIL_IF(push_inst(compiler, lr(tmp1, arg0)));
- FAIL_IF(push_inst(compiler, dlr(tmp0, arg1)));
- FAIL_IF(push_inst(compiler, lr(arg0, tmp1))); /* quotient */
- if (op == SLJIT_DIVMOD_U32)
- return push_inst(compiler, lr(arg1, tmp0)); /* remainder */
-
- return SLJIT_SUCCESS;
- case SLJIT_DIV_S32:
- case SLJIT_DIVMOD_S32:
- FAIL_IF(push_inst(compiler, lhi(tmp0, 0)));
- FAIL_IF(push_inst(compiler, lr(tmp1, arg0)));
- FAIL_IF(push_inst(compiler, dr(tmp0, arg1)));
- FAIL_IF(push_inst(compiler, lr(arg0, tmp1))); /* quotient */
- if (op == SLJIT_DIVMOD_S32)
- return push_inst(compiler, lr(arg1, tmp0)); /* remainder */
-
- return SLJIT_SUCCESS;
- case SLJIT_DIV_UW:
- case SLJIT_DIVMOD_UW:
- FAIL_IF(push_inst(compiler, lghi(tmp0, 0)));
- FAIL_IF(push_inst(compiler, lgr(tmp1, arg0)));
- FAIL_IF(push_inst(compiler, dlgr(tmp0, arg1)));
- FAIL_IF(push_inst(compiler, lgr(arg0, tmp1))); /* quotient */
- if (op == SLJIT_DIVMOD_UW)
- return push_inst(compiler, lgr(arg1, tmp0)); /* remainder */
-
- return SLJIT_SUCCESS;
- case SLJIT_DIV_SW:
- case SLJIT_DIVMOD_SW:
- FAIL_IF(push_inst(compiler, lgr(tmp1, arg0)));
- FAIL_IF(push_inst(compiler, dsgr(tmp0, arg1)));
- FAIL_IF(push_inst(compiler, lgr(arg0, tmp1))); /* quotient */
- if (op == SLJIT_DIVMOD_SW)
- return push_inst(compiler, lgr(arg1, tmp0)); /* remainder */
-
- return SLJIT_SUCCESS;
- case SLJIT_ENDBR:
- return SLJIT_SUCCESS;
- case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
- return SLJIT_SUCCESS;
- default:
- SLJIT_UNREACHABLE();
- }
- /* swap result registers */
- FAIL_IF(push_inst(compiler, lgr(tmp0, arg0)));
- FAIL_IF(push_inst(compiler, lgr(arg0, arg1)));
- return push_inst(compiler, lgr(arg1, tmp0));
-}
-
-static sljit_s32 sljit_emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, sljit_gpr dst_r, sljit_gpr src_r)
-{
- sljit_s32 is_ctz = (GET_OPCODE(op) == SLJIT_CTZ);
-
- if ((op & SLJIT_32) && src_r != tmp0) {
- FAIL_IF(push_inst(compiler, 0xb9160000 /* llgfr */ | R4A(tmp0) | R0A(src_r)));
- src_r = tmp0;
- }
-
- if (is_ctz) {
- FAIL_IF(push_inst(compiler, ((op & SLJIT_32) ? 0x1300 /* lcr */ : 0xb9030000 /* lcgr */) | R4A(tmp1) | R0A(src_r)));
-
- if (src_r == tmp0)
- FAIL_IF(push_inst(compiler, ((op & SLJIT_32) ? 0x1400 /* nr */ : 0xb9800000 /* ngr */) | R4A(tmp0) | R0A(tmp1)));
- else
- FAIL_IF(push_inst(compiler, 0xb9e40000 /* ngrk */ | R12A(tmp1) | R4A(tmp0) | R0A(src_r)));
-
- src_r = tmp0;
- }
-
- FAIL_IF(push_inst(compiler, 0xb9830000 /* flogr */ | R4A(tmp0) | R0A(src_r)));
-
- if (is_ctz)
- FAIL_IF(push_inst(compiler, 0xec00000000d9 /* aghik */ | R36A(tmp1) | R32A(tmp0) | ((sljit_ins)(-64 & 0xffff) << 16)));
-
- if (op & SLJIT_32) {
- if (!is_ctz && dst_r != tmp0)
- return push_inst(compiler, 0xec00000000d9 /* aghik */ | R36A(dst_r) | R32A(tmp0) | ((sljit_ins)(-32 & 0xffff) << 16));
-
- FAIL_IF(push_inst(compiler, 0xc20800000000 /* agfi */ | R36A(tmp0) | (sljit_u32)-32));
- }
-
- if (is_ctz)
- FAIL_IF(push_inst(compiler, 0xec0000000057 /* rxsbg */ | R36A(tmp0) | R32A(tmp1) | ((sljit_ins)((op & SLJIT_32) ? 59 : 58) << 24) | (63 << 16) | ((sljit_ins)((op & SLJIT_32) ? 5 : 6) << 8)));
-
- if (dst_r == tmp0)
- return SLJIT_SUCCESS;
-
- return push_inst(compiler, ((op & SLJIT_32) ? 0x1800 /* lr */ : 0xb9040000 /* lgr */) | R4A(dst_r) | R0A(tmp0));
-}
-
-/* LEVAL will be defined later with different parameters as needed */
-#define WHEN2(cond, i1, i2) (cond) ? LEVAL(i1) : LEVAL(i2)
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_ins ins;
- struct addr mem;
- sljit_gpr dst_r;
- sljit_gpr src_r;
- sljit_s32 opcode = GET_OPCODE(op);
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- if (opcode >= SLJIT_MOV && opcode <= SLJIT_MOV_P) {
- /* LOAD REGISTER */
- if (FAST_IS_REG(dst) && FAST_IS_REG(src)) {
- dst_r = gpr(dst);
- src_r = gpr(src);
- switch (opcode | (op & SLJIT_32)) {
- /* 32-bit */
- case SLJIT_MOV32_U8:
- ins = llcr(dst_r, src_r);
- break;
- case SLJIT_MOV32_S8:
- ins = lbr(dst_r, src_r);
- break;
- case SLJIT_MOV32_U16:
- ins = llhr(dst_r, src_r);
- break;
- case SLJIT_MOV32_S16:
- ins = lhr(dst_r, src_r);
- break;
- case SLJIT_MOV32:
- if (dst_r == src_r)
- return SLJIT_SUCCESS;
- ins = lr(dst_r, src_r);
- break;
- /* 64-bit */
- case SLJIT_MOV_U8:
- ins = llgcr(dst_r, src_r);
- break;
- case SLJIT_MOV_S8:
- ins = lgbr(dst_r, src_r);
- break;
- case SLJIT_MOV_U16:
- ins = llghr(dst_r, src_r);
- break;
- case SLJIT_MOV_S16:
- ins = lghr(dst_r, src_r);
- break;
- case SLJIT_MOV_U32:
- ins = llgfr(dst_r, src_r);
- break;
- case SLJIT_MOV_S32:
- ins = lgfr(dst_r, src_r);
- break;
- case SLJIT_MOV:
- case SLJIT_MOV_P:
- if (dst_r == src_r)
- return SLJIT_SUCCESS;
- ins = lgr(dst_r, src_r);
- break;
- default:
- ins = 0;
- SLJIT_UNREACHABLE();
- break;
- }
- FAIL_IF(push_inst(compiler, ins));
- return SLJIT_SUCCESS;
- }
- /* LOAD IMMEDIATE */
- if (FAST_IS_REG(dst) && (src & SLJIT_IMM)) {
- switch (opcode) {
- case SLJIT_MOV_U8:
- srcw = (sljit_sw)((sljit_u8)(srcw));
- break;
- case SLJIT_MOV_S8:
- srcw = (sljit_sw)((sljit_s8)(srcw));
- break;
- case SLJIT_MOV_U16:
- srcw = (sljit_sw)((sljit_u16)(srcw));
- break;
- case SLJIT_MOV_S16:
- srcw = (sljit_sw)((sljit_s16)(srcw));
- break;
- case SLJIT_MOV_U32:
- srcw = (sljit_sw)((sljit_u32)(srcw));
- break;
- case SLJIT_MOV_S32:
- case SLJIT_MOV32:
- srcw = (sljit_sw)((sljit_s32)(srcw));
- break;
- }
- return push_load_imm_inst(compiler, gpr(dst), srcw);
- }
- /* LOAD */
- /* TODO(carenas): avoid reg being defined later */
- #define LEVAL(i) EVAL(i, reg, mem)
- if (FAST_IS_REG(dst) && (src & SLJIT_MEM)) {
- sljit_gpr reg = gpr(dst);
-
- FAIL_IF(make_addr_bxy(compiler, &mem, src, srcw, tmp1));
- /* TODO(carenas): convert all calls below to LEVAL */
- switch (opcode | (op & SLJIT_32)) {
- case SLJIT_MOV32_U8:
- ins = llc(reg, mem.offset, mem.index, mem.base);
- break;
- case SLJIT_MOV32_S8:
- ins = lb(reg, mem.offset, mem.index, mem.base);
- break;
- case SLJIT_MOV32_U16:
- ins = llh(reg, mem.offset, mem.index, mem.base);
- break;
- case SLJIT_MOV32_S16:
- ins = WHEN2(is_u12(mem.offset), lh, lhy);
- break;
- case SLJIT_MOV32:
- ins = WHEN2(is_u12(mem.offset), l, ly);
- break;
- case SLJIT_MOV_U8:
- ins = LEVAL(llgc);
- break;
- case SLJIT_MOV_S8:
- ins = lgb(reg, mem.offset, mem.index, mem.base);
- break;
- case SLJIT_MOV_U16:
- ins = LEVAL(llgh);
- break;
- case SLJIT_MOV_S16:
- ins = lgh(reg, mem.offset, mem.index, mem.base);
- break;
- case SLJIT_MOV_U32:
- ins = LEVAL(llgf);
- break;
- case SLJIT_MOV_S32:
- ins = lgf(reg, mem.offset, mem.index, mem.base);
- break;
- case SLJIT_MOV_P:
- case SLJIT_MOV:
- ins = lg(reg, mem.offset, mem.index, mem.base);
- break;
- default:
- ins = 0;
- SLJIT_UNREACHABLE();
- break;
- }
- FAIL_IF(push_inst(compiler, ins));
- return SLJIT_SUCCESS;
- }
- /* STORE and STORE IMMEDIATE */
- if ((dst & SLJIT_MEM)
- && (FAST_IS_REG(src) || (src & SLJIT_IMM))) {
- sljit_gpr reg = FAST_IS_REG(src) ? gpr(src) : tmp0;
- if (src & SLJIT_IMM) {
- /* TODO(mundaym): MOVE IMMEDIATE? */
- FAIL_IF(push_load_imm_inst(compiler, reg, srcw));
- }
- struct addr mem;
- FAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1));
- switch (opcode) {
- case SLJIT_MOV_U8:
- case SLJIT_MOV_S8:
- return push_inst(compiler,
- WHEN2(is_u12(mem.offset), stc, stcy));
- case SLJIT_MOV_U16:
- case SLJIT_MOV_S16:
- return push_inst(compiler,
- WHEN2(is_u12(mem.offset), sth, sthy));
- case SLJIT_MOV_U32:
- case SLJIT_MOV_S32:
- case SLJIT_MOV32:
- return push_inst(compiler,
- WHEN2(is_u12(mem.offset), st, sty));
- case SLJIT_MOV_P:
- case SLJIT_MOV:
- FAIL_IF(push_inst(compiler, LEVAL(stg)));
- return SLJIT_SUCCESS;
- default:
- SLJIT_UNREACHABLE();
- }
- }
- #undef LEVAL
- /* MOVE CHARACTERS */
- if ((dst & SLJIT_MEM) && (src & SLJIT_MEM)) {
- struct addr mem;
- FAIL_IF(make_addr_bxy(compiler, &mem, src, srcw, tmp1));
- switch (opcode) {
- case SLJIT_MOV_U8:
- case SLJIT_MOV_S8:
- FAIL_IF(push_inst(compiler,
- EVAL(llgc, tmp0, mem)));
- FAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1));
- return push_inst(compiler,
- EVAL(stcy, tmp0, mem));
- case SLJIT_MOV_U16:
- case SLJIT_MOV_S16:
- FAIL_IF(push_inst(compiler,
- EVAL(llgh, tmp0, mem)));
- FAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1));
- return push_inst(compiler,
- EVAL(sthy, tmp0, mem));
- case SLJIT_MOV_U32:
- case SLJIT_MOV_S32:
- case SLJIT_MOV32:
- FAIL_IF(push_inst(compiler,
- EVAL(ly, tmp0, mem)));
- FAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1));
- return push_inst(compiler,
- EVAL(sty, tmp0, mem));
- case SLJIT_MOV_P:
- case SLJIT_MOV:
- FAIL_IF(push_inst(compiler,
- EVAL(lg, tmp0, mem)));
- FAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1));
- FAIL_IF(push_inst(compiler,
- EVAL(stg, tmp0, mem)));
- return SLJIT_SUCCESS;
- default:
- SLJIT_UNREACHABLE();
- }
- }
- SLJIT_UNREACHABLE();
- }
-
- SLJIT_ASSERT((src & SLJIT_IMM) == 0); /* no immediates */
-
- dst_r = FAST_IS_REG(dst) ? gpr(REG_MASK & dst) : tmp0;
- src_r = FAST_IS_REG(src) ? gpr(REG_MASK & src) : tmp0;
-
- compiler->status_flags_state = op & (VARIABLE_FLAG_MASK | SLJIT_SET_Z);
-
- /* TODO(mundaym): optimize loads and stores */
- switch (opcode) {
- case SLJIT_NOT:
- if (src & SLJIT_MEM)
- FAIL_IF(load_word(compiler, src_r, src, srcw, op & SLJIT_32));
-
- /* emulate ~x with x^-1 */
- if (!(op & SLJIT_32)) {
- FAIL_IF(push_load_imm_inst(compiler, tmp1, -1));
- if (src_r != dst_r)
- FAIL_IF(push_inst(compiler, lgr(dst_r, src_r)));
-
- FAIL_IF(push_inst(compiler, xgr(dst_r, tmp1)));
- break;
- }
-
- if (have_eimm())
- FAIL_IF(push_inst(compiler, xilf(dst_r, 0xffffffff)));
- else {
- FAIL_IF(push_load_imm_inst(compiler, tmp1, -1));
- if (src_r != dst_r)
- FAIL_IF(push_inst(compiler, lr(dst_r, src_r)));
-
- FAIL_IF(push_inst(compiler, xr(dst_r, tmp1)));
- }
- break;
- case SLJIT_CLZ:
- case SLJIT_CTZ:
- if (src & SLJIT_MEM)
- FAIL_IF(load_unsigned_word(compiler, src_r, src, srcw, op & SLJIT_32));
-
- FAIL_IF(sljit_emit_clz_ctz(compiler, op, dst_r, src_r));
- break;
- default:
- SLJIT_UNREACHABLE();
- }
-
- if ((op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == (SLJIT_SET_Z | SLJIT_SET_OVERFLOW))
- FAIL_IF(update_zero_overflow(compiler, op, dst_r));
-
- if (dst & SLJIT_MEM)
- return store_word(compiler, dst_r, dst, dstw, op & SLJIT_32);
-
- return SLJIT_SUCCESS;
-}
-
-static SLJIT_INLINE int is_commutative(sljit_s32 op)
-{
- switch (GET_OPCODE(op)) {
- case SLJIT_ADD:
- case SLJIT_ADDC:
- case SLJIT_MUL:
- case SLJIT_AND:
- case SLJIT_OR:
- case SLJIT_XOR:
- return 1;
- }
- return 0;
-}
-
-static const struct ins_forms add_forms = {
- 0x1a00, /* ar */
- 0xb9080000, /* agr */
- 0xb9f80000, /* ark */
- 0xb9e80000, /* agrk */
- 0x5a000000, /* a */
- 0xe3000000005a, /* ay */
- 0xe30000000008, /* ag */
-};
-
-static const struct ins_forms logical_add_forms = {
- 0x1e00, /* alr */
- 0xb90a0000, /* algr */
- 0xb9fa0000, /* alrk */
- 0xb9ea0000, /* algrk */
- 0x5e000000, /* al */
- 0xe3000000005e, /* aly */
- 0xe3000000000a, /* alg */
-};
-
-static sljit_s32 sljit_emit_add(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- int sets_overflow = (op & VARIABLE_FLAG_MASK) == SLJIT_SET_OVERFLOW;
- int sets_zero_overflow = (op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == (SLJIT_SET_Z | SLJIT_SET_OVERFLOW);
- const struct ins_forms *forms;
- sljit_ins ins;
-
- if (src2 & SLJIT_IMM) {
- if (!sets_zero_overflow && is_s8(src2w) && (src1 & SLJIT_MEM) && (dst == src1 && dstw == src1w)) {
- if (sets_overflow)
- ins = (op & SLJIT_32) ? 0xeb000000006a /* asi */ : 0xeb000000007a /* agsi */;
- else
- ins = (op & SLJIT_32) ? 0xeb000000006e /* alsi */ : 0xeb000000007e /* algsi */;
- return emit_siy(compiler, ins, dst, dstw, src2w);
- }
-
- if (is_s16(src2w)) {
- if (sets_overflow)
- ins = (op & SLJIT_32) ? 0xec00000000d8 /* ahik */ : 0xec00000000d9 /* aghik */;
- else
- ins = (op & SLJIT_32) ? 0xec00000000da /* alhsik */ : 0xec00000000db /* alghsik */;
- FAIL_IF(emit_rie_d(compiler, ins, dst, src1, src1w, src2w));
- goto done;
- }
-
- if (!sets_overflow) {
- if ((op & SLJIT_32) || is_u32(src2w)) {
- ins = (op & SLJIT_32) ? 0xc20b00000000 /* alfi */ : 0xc20a00000000 /* algfi */;
- FAIL_IF(emit_ri(compiler, ins, dst, src1, src1w, src2w, RIL_A));
- goto done;
- }
- if (is_u32(-src2w)) {
- FAIL_IF(emit_ri(compiler, 0xc20400000000 /* slgfi */, dst, src1, src1w, -src2w, RIL_A));
- goto done;
- }
- }
- else if ((op & SLJIT_32) || is_s32(src2w)) {
- ins = (op & SLJIT_32) ? 0xc20900000000 /* afi */ : 0xc20800000000 /* agfi */;
- FAIL_IF(emit_ri(compiler, ins, dst, src1, src1w, src2w, RIL_A));
- goto done;
- }
- }
-
- forms = sets_overflow ? &add_forms : &logical_add_forms;
- FAIL_IF(emit_commutative(compiler, forms, dst, src1, src1w, src2, src2w));
-
-done:
- if (sets_zero_overflow)
- FAIL_IF(update_zero_overflow(compiler, op, FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0));
-
- if (dst & SLJIT_MEM)
- return store_word(compiler, tmp0, dst, dstw, op & SLJIT_32);
-
- return SLJIT_SUCCESS;
-}
-
-static const struct ins_forms sub_forms = {
- 0x1b00, /* sr */
- 0xb9090000, /* sgr */
- 0xb9f90000, /* srk */
- 0xb9e90000, /* sgrk */
- 0x5b000000, /* s */
- 0xe3000000005b, /* sy */
- 0xe30000000009, /* sg */
-};
-
-static const struct ins_forms logical_sub_forms = {
- 0x1f00, /* slr */
- 0xb90b0000, /* slgr */
- 0xb9fb0000, /* slrk */
- 0xb9eb0000, /* slgrk */
- 0x5f000000, /* sl */
- 0xe3000000005f, /* sly */
- 0xe3000000000b, /* slg */
-};
-
-static sljit_s32 sljit_emit_sub(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 flag_type = GET_FLAG_TYPE(op);
- int sets_signed = (flag_type >= SLJIT_SIG_LESS && flag_type <= SLJIT_NOT_OVERFLOW);
- int sets_zero_overflow = (op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == (SLJIT_SET_Z | SLJIT_SET_OVERFLOW);
- const struct ins_forms *forms;
- sljit_ins ins;
-
- if (dst == (sljit_s32)tmp0 && flag_type <= SLJIT_SIG_LESS_EQUAL) {
- int compare_signed = flag_type >= SLJIT_SIG_LESS;
-
- compiler->status_flags_state |= SLJIT_CURRENT_FLAGS_COMPARE;
-
- if (src2 & SLJIT_IMM) {
- if (compare_signed || ((op & VARIABLE_FLAG_MASK) == 0 && is_s32(src2w)))
- {
- if ((op & SLJIT_32) || is_s32(src2w)) {
- ins = (op & SLJIT_32) ? 0xc20d00000000 /* cfi */ : 0xc20c00000000 /* cgfi */;
- return emit_ri(compiler, ins, src1, src1, src1w, src2w, RIL_A);
- }
- }
- else {
- if ((op & SLJIT_32) || is_u32(src2w)) {
- ins = (op & SLJIT_32) ? 0xc20f00000000 /* clfi */ : 0xc20e00000000 /* clgfi */;
- return emit_ri(compiler, ins, src1, src1, src1w, src2w, RIL_A);
- }
- if (is_s16(src2w))
- return emit_rie_d(compiler, 0xec00000000db /* alghsik */, (sljit_s32)tmp0, src1, src1w, src2w);
- }
- }
- else if (src2 & SLJIT_MEM) {
- if ((op & SLJIT_32) && ((src2 & OFFS_REG_MASK) || is_u12(src2w))) {
- ins = compare_signed ? 0x59000000 /* c */ : 0x55000000 /* cl */;
- return emit_rx(compiler, ins, src1, src1, src1w, src2, src2w, RX_A);
- }
-
- if (compare_signed)
- ins = (op & SLJIT_32) ? 0xe30000000059 /* cy */ : 0xe30000000020 /* cg */;
- else
- ins = (op & SLJIT_32) ? 0xe30000000055 /* cly */ : 0xe30000000021 /* clg */;
- return emit_rx(compiler, ins, src1, src1, src1w, src2, src2w, RXY_A);
- }
-
- if (compare_signed)
- ins = (op & SLJIT_32) ? 0x1900 /* cr */ : 0xb9200000 /* cgr */;
- else
- ins = (op & SLJIT_32) ? 0x1500 /* clr */ : 0xb9210000 /* clgr */;
- return emit_rr(compiler, ins, src1, src1, src1w, src2, src2w);
- }
-
- if (src1 == SLJIT_IMM && src1w == 0 && (flag_type == 0 || sets_signed)) {
- ins = (op & SLJIT_32) ? 0x1300 /* lcr */ : 0xb9030000 /* lcgr */;
- FAIL_IF(emit_rr1(compiler, ins, dst, src2, src2w));
- goto done;
- }
-
- if (src2 & SLJIT_IMM) {
- sljit_sw neg_src2w = -src2w;
-
- if (sets_signed || neg_src2w != 0 || (op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == 0) {
- if (!sets_zero_overflow && is_s8(neg_src2w) && (src1 & SLJIT_MEM) && (dst == src1 && dstw == src1w)) {
- if (sets_signed)
- ins = (op & SLJIT_32) ? 0xeb000000006a /* asi */ : 0xeb000000007a /* agsi */;
- else
- ins = (op & SLJIT_32) ? 0xeb000000006e /* alsi */ : 0xeb000000007e /* algsi */;
- return emit_siy(compiler, ins, dst, dstw, neg_src2w);
- }
-
- if (is_s16(neg_src2w)) {
- if (sets_signed)
- ins = (op & SLJIT_32) ? 0xec00000000d8 /* ahik */ : 0xec00000000d9 /* aghik */;
- else
- ins = (op & SLJIT_32) ? 0xec00000000da /* alhsik */ : 0xec00000000db /* alghsik */;
- FAIL_IF(emit_rie_d(compiler, ins, dst, src1, src1w, neg_src2w));
- goto done;
- }
- }
-
- if (!sets_signed) {
- if ((op & SLJIT_32) || is_u32(src2w)) {
- ins = (op & SLJIT_32) ? 0xc20500000000 /* slfi */ : 0xc20400000000 /* slgfi */;
- FAIL_IF(emit_ri(compiler, ins, dst, src1, src1w, src2w, RIL_A));
- goto done;
- }
- if (is_u32(neg_src2w)) {
- FAIL_IF(emit_ri(compiler, 0xc20a00000000 /* algfi */, dst, src1, src1w, neg_src2w, RIL_A));
- goto done;
- }
- }
- else if ((op & SLJIT_32) || is_s32(neg_src2w)) {
- ins = (op & SLJIT_32) ? 0xc20900000000 /* afi */ : 0xc20800000000 /* agfi */;
- FAIL_IF(emit_ri(compiler, ins, dst, src1, src1w, neg_src2w, RIL_A));
- goto done;
- }
- }
-
- forms = sets_signed ? &sub_forms : &logical_sub_forms;
- FAIL_IF(emit_non_commutative(compiler, forms, dst, src1, src1w, src2, src2w));
-
-done:
- if (sets_signed) {
- sljit_gpr dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;
-
- if ((op & VARIABLE_FLAG_MASK) != SLJIT_SET_OVERFLOW) {
- /* In case of overflow, the sign bit of the two source operands must be different, and
- - the first operand is greater if the sign bit of the result is set
- - the first operand is less if the sign bit of the result is not set
- The -result operation sets the corrent sign, because the result cannot be zero.
- The overflow is considered greater, since the result must be equal to INT_MIN so its sign bit is set. */
- FAIL_IF(push_inst(compiler, brc(0xe, 2 + 2)));
- FAIL_IF(push_inst(compiler, (op & SLJIT_32) ? lcr(tmp1, dst_r) : lcgr(tmp1, dst_r)));
- }
- else if (op & SLJIT_SET_Z)
- FAIL_IF(update_zero_overflow(compiler, op, dst_r));
- }
-
- if (dst & SLJIT_MEM)
- return store_word(compiler, tmp0, dst, dstw, op & SLJIT_32);
-
- return SLJIT_SUCCESS;
-}
-
-static const struct ins_forms multiply_forms = {
- 0xb2520000, /* msr */
- 0xb90c0000, /* msgr */
- 0xb9fd0000, /* msrkc */
- 0xb9ed0000, /* msgrkc */
- 0x71000000, /* ms */
- 0xe30000000051, /* msy */
- 0xe3000000000c, /* msg */
-};
-
-static const struct ins_forms multiply_overflow_forms = {
- 0,
- 0,
- 0xb9fd0000, /* msrkc */
- 0xb9ed0000, /* msgrkc */
- 0,
- 0xe30000000053, /* msc */
- 0xe30000000083, /* msgc */
-};
-
-static sljit_s32 sljit_emit_multiply(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_ins ins;
-
- if (HAS_FLAGS(op)) {
- /* if have_misc2 fails, this operation should be emulated. 32 bit emulation:
- FAIL_IF(push_inst(compiler, lgfr(tmp0, src1_r)));
- FAIL_IF(push_inst(compiler, msgfr(tmp0, src2_r)));
- if (dst_r != tmp0) {
- FAIL_IF(push_inst(compiler, lr(dst_r, tmp0)));
- }
- FAIL_IF(push_inst(compiler, aih(tmp0, 1)));
- FAIL_IF(push_inst(compiler, nihf(tmp0, ~1U)));
- FAIL_IF(push_inst(compiler, ipm(tmp1)));
- FAIL_IF(push_inst(compiler, oilh(tmp1, 0x2000))); */
-
- return emit_commutative(compiler, &multiply_overflow_forms, dst, src1, src1w, src2, src2w);
- }
-
- if (src2 & SLJIT_IMM) {
- if (is_s16(src2w)) {
- ins = (op & SLJIT_32) ? 0xa70c0000 /* mhi */ : 0xa70d0000 /* mghi */;
- return emit_ri(compiler, ins, dst, src1, src1w, src2w, RI_A);
- }
-
- if (is_s32(src2w)) {
- ins = (op & SLJIT_32) ? 0xc20100000000 /* msfi */ : 0xc20000000000 /* msgfi */;
- return emit_ri(compiler, ins, dst, src1, src1w, src2w, RIL_A);
- }
- }
-
- return emit_commutative(compiler, &multiply_forms, dst, src1, src1w, src2, src2w);
-}
-
-static sljit_s32 sljit_emit_bitwise_imm(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_uw imm, sljit_s32 count16)
-{
- sljit_s32 mode = compiler->mode;
- sljit_gpr dst_r = tmp0;
- sljit_s32 needs_move = 1;
-
- if (IS_GPR_REG(dst)) {
- dst_r = gpr(dst & REG_MASK);
- if (dst == src1)
- needs_move = 0;
- }
-
- if (needs_move)
- FAIL_IF(emit_move(compiler, dst_r, src1, src1w));
-
- if (type == SLJIT_AND) {
- if (!(mode & SLJIT_32))
- FAIL_IF(push_inst(compiler, 0xc00a00000000 /* nihf */ | R36A(dst_r) | (imm >> 32)));
- return push_inst(compiler, 0xc00b00000000 /* nilf */ | R36A(dst_r) | (imm & 0xffffffff));
- }
- else if (type == SLJIT_OR) {
- if (count16 >= 3) {
- FAIL_IF(push_inst(compiler, 0xc00c00000000 /* oihf */ | R36A(dst_r) | (imm >> 32)));
- return push_inst(compiler, 0xc00d00000000 /* oilf */ | R36A(dst_r) | (imm & 0xffffffff));
- }
-
- if (count16 >= 2) {
- if ((imm & 0x00000000ffffffffull) == 0)
- return push_inst(compiler, 0xc00c00000000 /* oihf */ | R36A(dst_r) | (imm >> 32));
- if ((imm & 0xffffffff00000000ull) == 0)
- return push_inst(compiler, 0xc00d00000000 /* oilf */ | R36A(dst_r) | (imm & 0xffffffff));
- }
-
- if ((imm & 0xffff000000000000ull) != 0)
- FAIL_IF(push_inst(compiler, 0xa5080000 /* oihh */ | R20A(dst_r) | (imm >> 48)));
- if ((imm & 0x0000ffff00000000ull) != 0)
- FAIL_IF(push_inst(compiler, 0xa5090000 /* oihl */ | R20A(dst_r) | ((imm >> 32) & 0xffff)));
- if ((imm & 0x00000000ffff0000ull) != 0)
- FAIL_IF(push_inst(compiler, 0xa50a0000 /* oilh */ | R20A(dst_r) | ((imm >> 16) & 0xffff)));
- if ((imm & 0x000000000000ffffull) != 0 || imm == 0)
- return push_inst(compiler, 0xa50b0000 /* oill */ | R20A(dst_r) | (imm & 0xffff));
- return SLJIT_SUCCESS;
- }
-
- if ((imm & 0xffffffff00000000ull) != 0)
- FAIL_IF(push_inst(compiler, 0xc00600000000 /* xihf */ | R36A(dst_r) | (imm >> 32)));
- if ((imm & 0x00000000ffffffffull) != 0 || imm == 0)
- return push_inst(compiler, 0xc00700000000 /* xilf */ | R36A(dst_r) | (imm & 0xffffffff));
- return SLJIT_SUCCESS;
-}
-
-static const struct ins_forms bitwise_and_forms = {
- 0x1400, /* nr */
- 0xb9800000, /* ngr */
- 0xb9f40000, /* nrk */
- 0xb9e40000, /* ngrk */
- 0x54000000, /* n */
- 0xe30000000054, /* ny */
- 0xe30000000080, /* ng */
-};
-
-static const struct ins_forms bitwise_or_forms = {
- 0x1600, /* or */
- 0xb9810000, /* ogr */
- 0xb9f60000, /* ork */
- 0xb9e60000, /* ogrk */
- 0x56000000, /* o */
- 0xe30000000056, /* oy */
- 0xe30000000081, /* og */
-};
-
-static const struct ins_forms bitwise_xor_forms = {
- 0x1700, /* xr */
- 0xb9820000, /* xgr */
- 0xb9f70000, /* xrk */
- 0xb9e70000, /* xgrk */
- 0x57000000, /* x */
- 0xe30000000057, /* xy */
- 0xe30000000082, /* xg */
-};
-
-static sljit_s32 sljit_emit_bitwise(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 type = GET_OPCODE(op);
- const struct ins_forms *forms;
-
- if ((src2 & SLJIT_IMM) && (!(op & SLJIT_SET_Z) || (type == SLJIT_AND && dst == (sljit_s32)tmp0))) {
- sljit_s32 count16 = 0;
- sljit_uw imm = (sljit_uw)src2w;
-
- if (op & SLJIT_32)
- imm &= 0xffffffffull;
-
- if ((imm & 0x000000000000ffffull) != 0 || imm == 0)
- count16++;
- if ((imm & 0x00000000ffff0000ull) != 0)
- count16++;
- if ((imm & 0x0000ffff00000000ull) != 0)
- count16++;
- if ((imm & 0xffff000000000000ull) != 0)
- count16++;
-
- if (type == SLJIT_AND && dst == (sljit_s32)tmp0 && count16 == 1) {
- sljit_gpr src_r = tmp0;
-
- if (FAST_IS_REG(src1))
- src_r = gpr(src1 & REG_MASK);
- else
- FAIL_IF(emit_move(compiler, tmp0, src1, src1w));
-
- if ((imm & 0x000000000000ffffull) != 0 || imm == 0)
- return push_inst(compiler, 0xa7010000 | R20A(src_r) | imm);
- if ((imm & 0x00000000ffff0000ull) != 0)
- return push_inst(compiler, 0xa7000000 | R20A(src_r) | (imm >> 16));
- if ((imm & 0x0000ffff00000000ull) != 0)
- return push_inst(compiler, 0xa7030000 | R20A(src_r) | (imm >> 32));
- return push_inst(compiler, 0xa7020000 | R20A(src_r) | (imm >> 48));
- }
-
- if (!(op & SLJIT_SET_Z))
- return sljit_emit_bitwise_imm(compiler, type, dst, src1, src1w, imm, count16);
- }
-
- if (type == SLJIT_AND)
- forms = &bitwise_and_forms;
- else if (type == SLJIT_OR)
- forms = &bitwise_or_forms;
- else
- forms = &bitwise_xor_forms;
-
- return emit_commutative(compiler, forms, dst, src1, src1w, src2, src2w);
-}
-
-static sljit_s32 sljit_emit_shift(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 type = GET_OPCODE(op);
- sljit_gpr dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;
- sljit_gpr src_r = tmp0;
- sljit_gpr base_r = tmp0;
- sljit_ins imm = 0;
- sljit_ins ins;
-
- if (FAST_IS_REG(src1))
- src_r = gpr(src1);
- else
- FAIL_IF(emit_move(compiler, tmp0, src1, src1w));
-
- if (!(src2 & SLJIT_IMM)) {
- if (FAST_IS_REG(src2))
- base_r = gpr(src2);
- else {
- FAIL_IF(emit_move(compiler, tmp1, src2, src2w));
- base_r = tmp1;
- }
-
- if ((op & SLJIT_32) && (type == SLJIT_MSHL || type == SLJIT_MLSHR || type == SLJIT_MASHR)) {
- if (base_r != tmp1) {
- FAIL_IF(push_inst(compiler, 0xec0000000055 /* risbg */ | R36A(tmp1) | R32A(base_r) | (59 << 24) | (1 << 23) | (63 << 16)));
- base_r = tmp1;
- } else
- FAIL_IF(push_inst(compiler, 0xa5070000 /* nill */ | R20A(tmp1) | 0x1f));
- }
- } else
- imm = (sljit_ins)(src2w & ((op & SLJIT_32) ? 0x1f : 0x3f));
-
- if ((op & SLJIT_32) && dst_r == src_r) {
- if (type == SLJIT_SHL || type == SLJIT_MSHL)
- ins = 0x89000000 /* sll */;
- else if (type == SLJIT_LSHR || type == SLJIT_MLSHR)
- ins = 0x88000000 /* srl */;
- else
- ins = 0x8a000000 /* sra */;
-
- FAIL_IF(push_inst(compiler, ins | R20A(dst_r) | R12A(base_r) | imm));
- } else {
- if (type == SLJIT_SHL || type == SLJIT_MSHL)
- ins = (op & SLJIT_32) ? 0xeb00000000df /* sllk */ : 0xeb000000000d /* sllg */;
- else if (type == SLJIT_LSHR || type == SLJIT_MLSHR)
- ins = (op & SLJIT_32) ? 0xeb00000000de /* srlk */ : 0xeb000000000c /* srlg */;
- else
- ins = (op & SLJIT_32) ? 0xeb00000000dc /* srak */ : 0xeb000000000a /* srag */;
-
- FAIL_IF(push_inst(compiler, ins | R36A(dst_r) | R32A(src_r) | R28A(base_r) | (imm << 16)));
- }
-
- if ((op & SLJIT_SET_Z) && type != SLJIT_ASHR)
- return push_inst(compiler, (op & SLJIT_32) ? or(dst_r, dst_r) : ogr(dst_r, dst_r));
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 sljit_emit_rotate(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_gpr dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;
- sljit_gpr src_r = tmp0;
- sljit_gpr base_r = tmp0;
- sljit_ins imm = 0;
- sljit_ins ins;
-
- if (FAST_IS_REG(src1))
- src_r = gpr(src1);
- else
- FAIL_IF(emit_move(compiler, tmp0, src1, src1w));
-
- if (!(src2 & SLJIT_IMM)) {
- if (FAST_IS_REG(src2))
- base_r = gpr(src2);
- else {
- FAIL_IF(emit_move(compiler, tmp1, src2, src2w));
- base_r = tmp1;
- }
- }
-
- if (GET_OPCODE(op) == SLJIT_ROTR) {
- if (!(src2 & SLJIT_IMM)) {
- ins = (op & SLJIT_32) ? 0x1300 /* lcr */ : 0xb9030000 /* lcgr */;
- FAIL_IF(push_inst(compiler, ins | R4A(tmp1) | R0A(base_r)));
- base_r = tmp1;
- } else
- src2w = -src2w;
- }
-
- if (src2 & SLJIT_IMM)
- imm = (sljit_ins)(src2w & ((op & SLJIT_32) ? 0x1f : 0x3f));
-
- ins = (op & SLJIT_32) ? 0xeb000000001d /* rll */ : 0xeb000000001c /* rllg */;
- return push_inst(compiler, ins | R36A(dst_r) | R32A(src_r) | R28A(base_r) | (imm << 16));
-}
-
-static const struct ins_forms addc_forms = {
- 0xb9980000, /* alcr */
- 0xb9880000, /* alcgr */
- 0,
- 0,
- 0,
- 0xe30000000098, /* alc */
- 0xe30000000088, /* alcg */
-};
-
-static const struct ins_forms subc_forms = {
- 0xb9990000, /* slbr */
- 0xb9890000, /* slbgr */
- 0,
- 0,
- 0,
- 0xe30000000099, /* slb */
- 0xe30000000089, /* slbg */
-};
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- compiler->mode = op & SLJIT_32;
- compiler->status_flags_state = op & (VARIABLE_FLAG_MASK | SLJIT_SET_Z);
-
- if (is_commutative(op) && (src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM)) {
- src1 ^= src2;
- src2 ^= src1;
- src1 ^= src2;
-
- src1w ^= src2w;
- src2w ^= src1w;
- src1w ^= src2w;
- }
-
- switch (GET_OPCODE(op)) {
- case SLJIT_ADD:
- compiler->status_flags_state |= SLJIT_CURRENT_FLAGS_ADD;
- return sljit_emit_add(compiler, op, dst, dstw, src1, src1w, src2, src2w);
- case SLJIT_ADDC:
- compiler->status_flags_state |= SLJIT_CURRENT_FLAGS_ADD;
- FAIL_IF(emit_commutative(compiler, &addc_forms, dst, src1, src1w, src2, src2w));
- if (dst & SLJIT_MEM)
- return store_word(compiler, tmp0, dst, dstw, op & SLJIT_32);
- return SLJIT_SUCCESS;
- case SLJIT_SUB:
- compiler->status_flags_state |= SLJIT_CURRENT_FLAGS_SUB;
- return sljit_emit_sub(compiler, op, dst, dstw, src1, src1w, src2, src2w);
- case SLJIT_SUBC:
- compiler->status_flags_state |= SLJIT_CURRENT_FLAGS_SUB;
- FAIL_IF(emit_non_commutative(compiler, &subc_forms, dst, src1, src1w, src2, src2w));
- if (dst & SLJIT_MEM)
- return store_word(compiler, tmp0, dst, dstw, op & SLJIT_32);
- return SLJIT_SUCCESS;
- case SLJIT_MUL:
- FAIL_IF(sljit_emit_multiply(compiler, op, dst, src1, src1w, src2, src2w));
- break;
- case SLJIT_AND:
- case SLJIT_OR:
- case SLJIT_XOR:
- FAIL_IF(sljit_emit_bitwise(compiler, op, dst, src1, src1w, src2, src2w));
- break;
- case SLJIT_SHL:
- case SLJIT_MSHL:
- case SLJIT_LSHR:
- case SLJIT_MLSHR:
- case SLJIT_ASHR:
- case SLJIT_MASHR:
- FAIL_IF(sljit_emit_shift(compiler, op, dst, src1, src1w, src2, src2w));
- break;
- case SLJIT_ROTL:
- case SLJIT_ROTR:
- FAIL_IF(sljit_emit_rotate(compiler, op, dst, src1, src1w, src2, src2w));
- break;
- }
-
- if (dst & SLJIT_MEM)
- return store_word(compiler, tmp0, dst, dstw, op & SLJIT_32);
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_op2(compiler, op, (sljit_s32)tmp0, 0, src1, src1w, src2, src2w);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src_dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 is_right;
- sljit_sw bit_length = (op & SLJIT_32) ? 32 : 64;
- sljit_gpr src_dst_r = gpr(src_dst);
- sljit_gpr src1_r = tmp0;
- sljit_gpr src2_r = tmp1;
- sljit_ins ins;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w));
-
- is_right = (GET_OPCODE(op) == SLJIT_LSHR || GET_OPCODE(op) == SLJIT_MLSHR);
-
- if (src_dst == src1) {
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_op2(compiler, (is_right ? SLJIT_ROTR : SLJIT_ROTL) | (op & SLJIT_32), src_dst, 0, src_dst, 0, src2, src2w);
- }
-
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- if (src1 & SLJIT_MEM)
- FAIL_IF(load_word(compiler, tmp0, src1, src1w, op & SLJIT_32));
- else if (src1 & SLJIT_IMM)
- FAIL_IF(push_load_imm_inst(compiler, tmp0, src1w));
- else
- src1_r = gpr(src1);
-
- if (src2 & SLJIT_IMM) {
- src2w &= bit_length - 1;
-
- if (src2w == 0)
- return SLJIT_SUCCESS;
- } else if (!(src2 & SLJIT_MEM))
- src2_r = gpr(src2);
- else
- FAIL_IF(load_word(compiler, tmp1, src2, src2w, op & SLJIT_32));
-
- if (src2 & SLJIT_IMM) {
- if (op & SLJIT_32) {
- ins = is_right ? 0x88000000 /* srl */ : 0x89000000 /* sll */;
- FAIL_IF(push_inst(compiler, ins | R20A(src_dst_r) | (sljit_ins)src2w));
- } else {
- ins = is_right ? 0xeb000000000c /* srlg */ : 0xeb000000000d /* sllg */;
- FAIL_IF(push_inst(compiler, ins | R36A(src_dst_r) | R32A(src_dst_r) | ((sljit_ins)src2w << 16)));
- }
-
- ins = 0xec0000000055 /* risbg */;
-
- if (is_right) {
- src2w = bit_length - src2w;
- ins |= ((sljit_ins)(64 - bit_length) << 24) | ((sljit_ins)(63 - src2w) << 16) | ((sljit_ins)src2w << 8);
- } else
- ins |= ((sljit_ins)(64 - src2w) << 24) | ((sljit_ins)63 << 16) | ((sljit_ins)src2w << 8);
-
- return push_inst(compiler, ins | R36A(src_dst_r) | R32A(src1_r));
- }
-
- if (op & SLJIT_32) {
- if (GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR) {
- if (src2_r != tmp1) {
- FAIL_IF(push_inst(compiler, 0xec0000000055 /* risbg */ | R36A(tmp1) | R32A(src2_r) | (59 << 24) | (1 << 23) | (63 << 16)));
- src2_r = tmp1;
- } else
- FAIL_IF(push_inst(compiler, 0xa5070000 /* nill */ | R20A(tmp1) | 0x1f));
- }
-
- ins = is_right ? 0x88000000 /* srl */ : 0x89000000 /* sll */;
- FAIL_IF(push_inst(compiler, ins | R20A(src_dst_r) | R12A(src2_r)));
-
- if (src2_r != tmp1) {
- FAIL_IF(push_inst(compiler, 0xa50f0000 /* llill */ | R20A(tmp1) | 0x1f));
- FAIL_IF(push_inst(compiler, 0x1700 /* xr */ | R4A(tmp1) | R0A(src2_r)));
- } else
- FAIL_IF(push_inst(compiler, 0xc00700000000 /* xilf */ | R36A(tmp1) | 0x1f));
-
- if (src1_r == tmp0) {
- ins = is_right ? 0x89000000 /* sll */ : 0x88000000 /* srl */;
- FAIL_IF(push_inst(compiler, ins | R20A(tmp0) | R12A(tmp1) | 0x1));
- } else {
- ins = is_right ? 0xeb00000000df /* sllk */ : 0xeb00000000de /* srlk */;
- FAIL_IF(push_inst(compiler, ins | R36A(tmp0) | R32A(src1_r) | R28A(tmp1) | (0x1 << 16)));
- }
-
- return push_inst(compiler, 0x1600 /* or */ | R4A(src_dst_r) | R0A(tmp0));
- }
-
- ins = is_right ? 0xeb000000000c /* srlg */ : 0xeb000000000d /* sllg */;
- FAIL_IF(push_inst(compiler, ins | R36A(src_dst_r) | R32A(src_dst_r) | R28A(src2_r)));
-
- ins = is_right ? 0xeb000000000d /* sllg */ : 0xeb000000000c /* srlg */;
-
- if (!(op & SLJIT_SHIFT_INTO_NON_ZERO)) {
- if (src2_r != tmp1)
- FAIL_IF(push_inst(compiler, 0xa50f0000 /* llill */ | R20A(tmp1) | 0x3f));
-
- FAIL_IF(push_inst(compiler, ins | R36A(tmp0) | R32A(src1_r) | (0x1 << 16)));
- src1_r = tmp0;
-
- if (src2_r != tmp1)
- FAIL_IF(push_inst(compiler, 0xb9820000 /* xgr */ | R4A(tmp1) | R0A(src2_r)));
- else
- FAIL_IF(push_inst(compiler, 0xc00700000000 /* xilf */ | R36A(tmp1) | 0x3f));
- } else
- FAIL_IF(push_inst(compiler, 0xb9030000 /* lcgr */ | R4A(tmp1) | R0A(src2_r)));
-
- FAIL_IF(push_inst(compiler, ins | R36A(tmp0) | R32A(src1_r) | R28A(tmp1)));
- return push_inst(compiler, 0xb9810000 /* ogr */ | R4A(src_dst_r) | R0A(tmp0));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(
- struct sljit_compiler *compiler,
- sljit_s32 op, sljit_s32 src, sljit_sw srcw)
-{
- sljit_gpr src_r;
- struct addr addr;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- switch (op) {
- case SLJIT_FAST_RETURN:
- src_r = FAST_IS_REG(src) ? gpr(src) : tmp1;
- if (src & SLJIT_MEM)
- FAIL_IF(load_word(compiler, tmp1, src, srcw, 0));
-
- return push_inst(compiler, br(src_r));
- case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
- return SLJIT_SUCCESS;
- case SLJIT_PREFETCH_L1:
- case SLJIT_PREFETCH_L2:
- case SLJIT_PREFETCH_L3:
- case SLJIT_PREFETCH_ONCE:
- FAIL_IF(make_addr_bxy(compiler, &addr, src, srcw, tmp1));
- return push_inst(compiler, 0xe31000000036 /* pfd */ | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset));
- default:
- return SLJIT_SUCCESS;
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
-{
- CHECK_REG_INDEX(check_sljit_get_register_index(reg));
- return (sljit_s32)gpr(reg);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
-{
- CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
- return (sljit_s32)fgpr(reg);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
- void *instruction, sljit_u32 size)
-{
- sljit_ins ins = 0;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
-
- memcpy((sljit_u8 *)&ins + sizeof(ins) - size, instruction, size);
- return push_inst(compiler, ins);
-}
-
-/* --------------------------------------------------------------------- */
-/* Floating point operators */
-/* --------------------------------------------------------------------- */
-
-#define FLOAT_LOAD 0
-#define FLOAT_STORE 1
-
-static sljit_s32 float_mem(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 reg,
- sljit_s32 mem, sljit_sw memw)
-{
- struct addr addr;
- sljit_ins ins;
-
- SLJIT_ASSERT(mem & SLJIT_MEM);
-
- if ((mem & OFFS_REG_MASK) || is_u12(memw) || !is_s20(memw)) {
- FAIL_IF(make_addr_bx(compiler, &addr, mem, memw, tmp1));
-
- if (op & FLOAT_STORE)
- ins = (op & SLJIT_32) ? 0x70000000 /* ste */ : 0x60000000 /* std */;
- else
- ins = (op & SLJIT_32) ? 0x78000000 /* le */ : 0x68000000 /* ld */;
-
- return push_inst(compiler, ins | F20(reg) | R16A(addr.index) | R12A(addr.base) | (sljit_ins)addr.offset);
- }
-
- FAIL_IF(make_addr_bxy(compiler, &addr, mem, memw, tmp1));
-
- if (op & FLOAT_STORE)
- ins = (op & SLJIT_32) ? 0xed0000000066 /* stey */ : 0xed0000000067 /* stdy */;
- else
- ins = (op & SLJIT_32) ? 0xed0000000064 /* ley */ : 0xed0000000065 /* ldy */;
-
- return push_inst(compiler, ins | F36(reg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset));
-}
-
-static sljit_s32 emit_float(struct sljit_compiler *compiler, sljit_ins ins_r, sljit_ins ins,
- sljit_s32 reg,
- sljit_s32 src, sljit_sw srcw)
-{
- struct addr addr;
-
- if (!(src & SLJIT_MEM))
- return push_inst(compiler, ins_r | F4(reg) | F0(src));
-
- FAIL_IF(make_addr_bx(compiler, &addr, src, srcw, tmp1));
- return push_inst(compiler, ins | F36(reg) | R32A(addr.index) | R28A(addr.base) | ((sljit_ins)addr.offset << 16));
-}
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_ins dst_r = FAST_IS_REG(dst) ? gpr(dst) : tmp0;
- sljit_ins ins;
-
- if (src & SLJIT_MEM) {
- FAIL_IF(float_mem(compiler, FLOAT_LOAD | (op & SLJIT_32), TMP_FREG1, src, srcw));
- src = TMP_FREG1;
- }
-
- /* M3 is set to 5 */
- if (GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64)
- ins = (op & SLJIT_32) ? 0xb3a85000 /* cgebr */ : 0xb3a95000 /* cgdbr */;
- else
- ins = (op & SLJIT_32) ? 0xb3985000 /* cfebr */ : 0xb3995000 /* cfdbr */;
-
- FAIL_IF(push_inst(compiler, ins | R4A(dst_r) | F0(src)));
-
- if (dst & SLJIT_MEM)
- return store_word(compiler, dst_r, dst, dstw, GET_OPCODE(op) >= SLJIT_CONV_S32_FROM_F64);
-
- return SLJIT_SUCCESS;
-}
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
- sljit_ins ins;
-
- if (src & SLJIT_IMM) {
- FAIL_IF(push_load_imm_inst(compiler, tmp0, srcw));
- src = (sljit_s32)tmp0;
- }
- else if (src & SLJIT_MEM) {
- FAIL_IF(load_word(compiler, tmp0, src, srcw, GET_OPCODE(op) >= SLJIT_CONV_F64_FROM_S32));
- src = (sljit_s32)tmp0;
- }
-
- if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW)
- ins = (op & SLJIT_32) ? 0xb3a40000 /* cegbr */ : 0xb3a50000 /* cdgbr */;
- else
- ins = (op & SLJIT_32) ? 0xb3940000 /* cefbr */ : 0xb3950000 /* cdfbr */;
-
- FAIL_IF(push_inst(compiler, ins | F4(dst_r) | R0(src)));
-
- if (dst & SLJIT_MEM)
- return float_mem(compiler, FLOAT_STORE | (op & SLJIT_32), TMP_FREG1, dst, dstw);
-
- return SLJIT_SUCCESS;
-}
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_ins ins_r, ins;
-
- if (src1 & SLJIT_MEM) {
- FAIL_IF(float_mem(compiler, FLOAT_LOAD | (op & SLJIT_32), TMP_FREG1, src1, src1w));
- src1 = TMP_FREG1;
- }
-
- if (op & SLJIT_32) {
- ins_r = 0xb3090000 /* cebr */;
- ins = 0xed0000000009 /* ceb */;
- } else {
- ins_r = 0xb3190000 /* cdbr */;
- ins = 0xed0000000019 /* cdb */;
- }
-
- return emit_float(compiler, ins_r, ins, src1, src2, src2w);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 dst_r;
- sljit_ins ins;
-
- CHECK_ERROR();
-
- SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
-
- if (op == SLJIT_CONV_F64_FROM_F32)
- FAIL_IF(emit_float(compiler, 0xb3040000 /* ldebr */, 0xed0000000004 /* ldeb */, dst_r, src, srcw));
- else {
- if (src & SLJIT_MEM) {
- FAIL_IF(float_mem(compiler, FLOAT_LOAD | (op == SLJIT_CONV_F32_FROM_F64 ? 0 : (op & SLJIT_32)), dst_r, src, srcw));
- src = dst_r;
- }
-
- switch (GET_OPCODE(op)) {
- case SLJIT_MOV_F64:
- if (FAST_IS_REG(dst)) {
- if (dst == src)
- return SLJIT_SUCCESS;
-
- ins = (op & SLJIT_32) ? 0x3800 /* ler */ : 0x2800 /* ldr */;
- break;
- }
- return float_mem(compiler, FLOAT_STORE | (op & SLJIT_32), src, dst, dstw);
- case SLJIT_CONV_F64_FROM_F32:
- /* Only SLJIT_CONV_F32_FROM_F64. */
- ins = 0xb3440000 /* ledbr */;
- break;
- case SLJIT_NEG_F64:
- ins = (op & SLJIT_32) ? 0xb3030000 /* lcebr */ : 0xb3130000 /* lcdbr */;
- break;
- default:
- SLJIT_ASSERT(GET_OPCODE(op) == SLJIT_ABS_F64);
- ins = (op & SLJIT_32) ? 0xb3000000 /* lpebr */ : 0xb3100000 /* lpdbr */;
- break;
- }
-
- FAIL_IF(push_inst(compiler, ins | F4(dst_r) | F0(src)));
- }
-
- if (!(dst & SLJIT_MEM))
- return SLJIT_SUCCESS;
-
- SLJIT_ASSERT(dst_r == TMP_FREG1);
-
- return float_mem(compiler, FLOAT_STORE | (op & SLJIT_32), TMP_FREG1, dst, dstw);
-}
-
-#define FLOAT_MOV(op, dst_r, src_r) \
- (((op & SLJIT_32) ? 0x3800 /* ler */ : 0x2800 /* ldr */) | F4(dst_r) | F0(src_r))
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 dst_r = TMP_FREG1;
- sljit_ins ins_r, ins;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- do {
- if (FAST_IS_REG(dst)) {
- dst_r = dst;
-
- if (dst == src1)
- break;
-
- if (dst == src2) {
- if (GET_OPCODE(op) == SLJIT_ADD_F64 || GET_OPCODE(op) == SLJIT_MUL_F64) {
- src2 = src1;
- src2w = src1w;
- src1 = dst;
- break;
- }
-
- FAIL_IF(push_inst(compiler, FLOAT_MOV(op, TMP_FREG1, src2)));
- src2 = TMP_FREG1;
- }
- }
-
- if (src1 & SLJIT_MEM)
- FAIL_IF(float_mem(compiler, FLOAT_LOAD | (op & SLJIT_32), dst_r, src1, src1w));
- else
- FAIL_IF(push_inst(compiler, FLOAT_MOV(op, dst_r, src1)));
- } while (0);
-
- switch (GET_OPCODE(op)) {
- case SLJIT_ADD_F64:
- ins_r = (op & SLJIT_32) ? 0xb30a0000 /* aebr */ : 0xb31a0000 /* adbr */;
- ins = (op & SLJIT_32) ? 0xed000000000a /* aeb */ : 0xed000000001a /* adb */;
- break;
- case SLJIT_SUB_F64:
- ins_r = (op & SLJIT_32) ? 0xb30b0000 /* sebr */ : 0xb31b0000 /* sdbr */;
- ins = (op & SLJIT_32) ? 0xed000000000b /* seb */ : 0xed000000001b /* sdb */;
- break;
- case SLJIT_MUL_F64:
- ins_r = (op & SLJIT_32) ? 0xb3170000 /* meebr */ : 0xb31c0000 /* mdbr */;
- ins = (op & SLJIT_32) ? 0xed0000000017 /* meeb */ : 0xed000000001c /* mdb */;
- break;
- default:
- SLJIT_ASSERT(GET_OPCODE(op) == SLJIT_DIV_F64);
- ins_r = (op & SLJIT_32) ? 0xb30d0000 /* debr */ : 0xb31d0000 /* ddbr */;
- ins = (op & SLJIT_32) ? 0xed000000000d /* deb */ : 0xed000000001d /* ddb */;
- break;
- }
-
- FAIL_IF(emit_float(compiler, ins_r, ins, dst_r, src2, src2w));
-
- if (dst & SLJIT_MEM)
- return float_mem(compiler, FLOAT_STORE | (op & SLJIT_32), TMP_FREG1, dst, dstw);
-
- SLJIT_ASSERT(dst_r != TMP_FREG1);
- return SLJIT_SUCCESS;
-}
-
-/* --------------------------------------------------------------------- */
-/* Other instructions */
-/* --------------------------------------------------------------------- */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- if (FAST_IS_REG(dst))
- return push_inst(compiler, lgr(gpr(dst), link_r));
-
- /* memory */
- return store_word(compiler, link_r, dst, dstw, 0);
-}
-
-/* --------------------------------------------------------------------- */
-/* Conditional instructions */
-/* --------------------------------------------------------------------- */
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
-{
- struct sljit_label *label;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_label(compiler));
-
- if (compiler->last_label && compiler->last_label->size == compiler->size)
- return compiler->last_label;
-
- label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
- PTR_FAIL_IF(!label);
- set_label(label, compiler);
- return label;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
-{
- sljit_u8 mask = ((type & 0xff) < SLJIT_JUMP) ? get_cc(compiler, type & 0xff) : 0xf;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_jump(compiler, type));
-
- /* record jump */
- struct sljit_jump *jump = (struct sljit_jump *)
- ensure_abuf(compiler, sizeof(struct sljit_jump));
- PTR_FAIL_IF(!jump);
- set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
- jump->addr = compiler->size;
-
- /* emit jump instruction */
- type &= 0xff;
- if (type >= SLJIT_FAST_CALL)
- PTR_FAIL_IF(push_inst(compiler, brasl(link_r, 0)));
- else
- PTR_FAIL_IF(push_inst(compiler, brcl(mask, 0)));
-
- return jump;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types)
-{
- SLJIT_UNUSED_ARG(arg_types);
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
-
- if (type & SLJIT_CALL_RETURN) {
- PTR_FAIL_IF(emit_stack_frame_release(compiler, r14));
- type = SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP);
- }
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_jump(compiler, type);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
-{
- sljit_gpr src_r = FAST_IS_REG(src) ? gpr(src) : tmp1;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
-
- if (src & SLJIT_IMM) {
- SLJIT_ASSERT(!(srcw & 1)); /* target address must be even */
- FAIL_IF(push_load_imm_inst(compiler, src_r, srcw));
- }
- else if (src & SLJIT_MEM) {
- ADJUST_LOCAL_OFFSET(src, srcw);
- FAIL_IF(load_word(compiler, src_r, src, srcw, 0 /* 64-bit */));
- }
-
- /* emit jump instruction */
- if (type >= SLJIT_FAST_CALL)
- return push_inst(compiler, basr(link_r, src_r));
-
- return push_inst(compiler, br(src_r));
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types,
- sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
-
- SLJIT_ASSERT(gpr(TMP_REG2) == tmp1);
-
- if (src & SLJIT_MEM) {
- ADJUST_LOCAL_OFFSET(src, srcw);
- FAIL_IF(load_word(compiler, tmp1, src, srcw, 0 /* 64-bit */));
- src = TMP_REG2;
- srcw = 0;
- }
-
- if (type & SLJIT_CALL_RETURN) {
- if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
- FAIL_IF(push_inst(compiler, lgr(tmp1, gpr(src))));
- src = TMP_REG2;
- srcw = 0;
- }
-
- FAIL_IF(emit_stack_frame_release(compiler, r14));
- type = SLJIT_JUMP;
- }
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_ijump(compiler, type, src, srcw);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 type)
-{
- sljit_u8 mask = get_cc(compiler, type);
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
-
- sljit_gpr dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;
- sljit_gpr loc_r = tmp1;
- switch (GET_OPCODE(op)) {
- case SLJIT_AND:
- case SLJIT_OR:
- case SLJIT_XOR:
- compiler->status_flags_state = op & SLJIT_SET_Z;
-
- /* dst is also source operand */
- if (dst & SLJIT_MEM)
- FAIL_IF(load_word(compiler, dst_r, dst, dstw, op & SLJIT_32));
-
- break;
- case SLJIT_MOV32:
- op |= SLJIT_32;
- /* fallthrough */
- case SLJIT_MOV:
- /* can write straight into destination */
- loc_r = dst_r;
- break;
- default:
- SLJIT_UNREACHABLE();
- }
-
- /* TODO(mundaym): fold into cmov helper function? */
- #define LEVAL(i) i(loc_r, 1, mask)
- if (have_lscond2()) {
- FAIL_IF(push_load_imm_inst(compiler, loc_r, 0));
- FAIL_IF(push_inst(compiler,
- WHEN2(op & SLJIT_32, lochi, locghi)));
- } else {
- /* TODO(mundaym): no load/store-on-condition 2 facility (ipm? branch-and-set?) */
- abort();
- }
- #undef LEVAL
-
- /* apply bitwise op and set condition codes */
- switch (GET_OPCODE(op)) {
- #define LEVAL(i) i(dst_r, loc_r)
- case SLJIT_AND:
- FAIL_IF(push_inst(compiler,
- WHEN2(op & SLJIT_32, nr, ngr)));
- break;
- case SLJIT_OR:
- FAIL_IF(push_inst(compiler,
- WHEN2(op & SLJIT_32, or, ogr)));
- break;
- case SLJIT_XOR:
- FAIL_IF(push_inst(compiler,
- WHEN2(op & SLJIT_32, xr, xgr)));
- break;
- #undef LEVAL
- }
-
- /* store result to memory if required */
- if (dst & SLJIT_MEM)
- return store_word(compiler, dst_r, dst, dstw, (op & SLJIT_32));
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 dst_reg,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_ins mask = get_cc(compiler, type & ~SLJIT_32);
- sljit_gpr src_r;
- sljit_ins ins;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
-
- if (type & SLJIT_32)
- srcw = (sljit_s32)srcw;
-
- if (have_lscond2() && (src & SLJIT_IMM) && is_s16(srcw)) {
- ins = (type & SLJIT_32) ? 0xec0000000042 /* lochi */ : 0xec0000000046 /* locghi */;
- return push_inst(compiler, ins | R36A(gpr(dst_reg)) | (mask << 32) | (sljit_ins)(srcw & 0xffff) << 16);
- }
-
- if (src & SLJIT_IMM) {
- FAIL_IF(push_load_imm_inst(compiler, tmp0, srcw));
- src_r = tmp0;
- } else
- src_r = gpr(src);
-
- if (have_lscond1()) {
- ins = (type & SLJIT_32) ? 0xb9f20000 /* locr */ : 0xb9e20000 /* locgr */;
- return push_inst(compiler, ins | (mask << 12) | R4A(gpr(dst_reg)) | R0A(src_r));
- }
-
- return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 reg,
- sljit_s32 mem, sljit_sw memw)
-{
- sljit_ins ins, reg1, reg2, base, offs = 0;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
-
- if (!(reg & REG_PAIR_MASK))
- return sljit_emit_mem_unaligned(compiler, type, reg, mem, memw);
-
- ADJUST_LOCAL_OFFSET(mem, memw);
-
- base = gpr(mem & REG_MASK);
- reg1 = gpr(REG_PAIR_FIRST(reg));
- reg2 = gpr(REG_PAIR_SECOND(reg));
-
- if (mem & OFFS_REG_MASK) {
- memw &= 0x3;
- offs = gpr(OFFS_REG(mem));
-
- if (memw != 0) {
- FAIL_IF(push_inst(compiler, 0xeb000000000d /* sllg */ | R36A(tmp1) | R32A(offs) | ((sljit_ins)memw << 16)));
- offs = tmp1;
- } else if (!(type & SLJIT_MEM_STORE) && (base == reg1 || base == reg2) && (offs == reg1 || offs == reg2)) {
- FAIL_IF(push_inst(compiler, 0xb9f80000 | R12A(tmp1) | R4A(base) | R0A(offs)));
- base = tmp1;
- offs = 0;
- }
-
- memw = 0;
- } else if (memw < -0x80000 || memw > 0x7ffff - ((reg2 == reg1 + 1) ? 0 : SSIZE_OF(sw))) {
- FAIL_IF(push_load_imm_inst(compiler, tmp1, memw));
-
- if (base == 0)
- base = tmp1;
- else
- offs = tmp1;
-
- memw = 0;
- }
-
- if (offs == 0 && reg2 == (reg1 + 1)) {
- ins = (type & SLJIT_MEM_STORE) ? 0xeb0000000024 /* stmg */ : 0xeb0000000004 /* lmg */;
- return push_inst(compiler, ins | R36A(reg1) | R32A(reg2) | R28A(base) | disp_s20((sljit_s32)memw));
- }
-
- ins = ((type & SLJIT_MEM_STORE) ? 0xe30000000024 /* stg */ : 0xe30000000004 /* lg */) | R32A(offs) | R28A(base);
-
- if (!(type & SLJIT_MEM_STORE) && base == reg1) {
- FAIL_IF(push_inst(compiler, ins | R36A(reg2) | disp_s20((sljit_s32)memw + SSIZE_OF(sw))));
- return push_inst(compiler, ins | R36A(reg1) | disp_s20((sljit_s32)memw));
- }
-
- FAIL_IF(push_inst(compiler, ins | R36A(reg1) | disp_s20((sljit_s32)memw)));
- return push_inst(compiler, ins | R36A(reg2) | disp_s20((sljit_s32)memw + SSIZE_OF(sw)));
-}
-
-/* --------------------------------------------------------------------- */
-/* Other instructions */
-/* --------------------------------------------------------------------- */
-
-/* On s390x we build a literal pool to hold constants. This has two main
- advantages:
-
- 1. we only need one instruction in the instruction stream (LGRL)
- 2. we can store 64 bit addresses and use 32 bit offsets
-
- To retrofit the extra information needed to build the literal pool we
- add a new sljit_s390x_const struct that contains the initial value but
- can still be cast to a sljit_const. */
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
-{
- struct sljit_s390x_const *const_;
- sljit_gpr dst_r;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
-
- const_ = (struct sljit_s390x_const*)ensure_abuf(compiler,
- sizeof(struct sljit_s390x_const));
- PTR_FAIL_IF(!const_);
- set_const((struct sljit_const*)const_, compiler);
- const_->init_value = init_value;
-
- dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;
- if (have_genext())
- PTR_FAIL_IF(push_inst(compiler, sljit_ins_const | lgrl(dst_r, 0)));
- else {
- PTR_FAIL_IF(push_inst(compiler, sljit_ins_const | larl(tmp1, 0)));
- PTR_FAIL_IF(push_inst(compiler, lg(dst_r, 0, r0, tmp1)));
- }
-
- if (dst & SLJIT_MEM)
- PTR_FAIL_IF(store_word(compiler, dst_r, dst, dstw, 0 /* always 64-bit */));
-
- return (struct sljit_const*)const_;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
-{
- /* Update the constant pool. */
- sljit_uw *ptr = (sljit_uw *)addr;
- SLJIT_UNUSED_ARG(executable_offset);
-
- SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 0);
- *ptr = new_target;
- SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1);
- SLJIT_CACHE_FLUSH(ptr, ptr + 1);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
-{
- sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label *sljit_emit_put_label(
- struct sljit_compiler *compiler,
- sljit_s32 dst, sljit_sw dstw)
-{
- struct sljit_put_label *put_label;
- sljit_gpr dst_r;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
- PTR_FAIL_IF(!put_label);
- set_put_label(put_label, compiler, 0);
-
- dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;
-
- if (have_genext())
- PTR_FAIL_IF(push_inst(compiler, lgrl(dst_r, 0)));
- else {
- PTR_FAIL_IF(push_inst(compiler, larl(tmp1, 0)));
- PTR_FAIL_IF(push_inst(compiler, lg(dst_r, 0, r0, tmp1)));
- }
-
- if (dst & SLJIT_MEM)
- PTR_FAIL_IF(store_word(compiler, dst_r, dst, dstw, 0));
-
- return put_label;
-}
-
-/* TODO(carenas): EVAL probably should move up or be refactored */
-#undef WHEN2
-#undef EVAL
-
-#undef tmp1
-#undef tmp0
-
-/* TODO(carenas): undef other macros that spill like is_u12? */
diff --git a/contrib/libs/pcre2/src/sljit/sljitNativeX86_32.c b/contrib/libs/pcre2/src/sljit/sljitNativeX86_32.c
deleted file mode 100644
index 08da03026d..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitNativeX86_32.c
+++ /dev/null
@@ -1,1298 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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.
- */
-
-/* x86 32-bit arch dependent functions. */
-
-/* --------------------------------------------------------------------- */
-/* Operators */
-/* --------------------------------------------------------------------- */
-
-static sljit_s32 emit_do_imm(struct sljit_compiler *compiler, sljit_u8 opcode, sljit_sw imm)
-{
- sljit_u8 *inst;
-
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_sw));
- FAIL_IF(!inst);
- INC_SIZE(1 + sizeof(sljit_sw));
- *inst++ = opcode;
- sljit_unaligned_store_sw(inst, imm);
- return SLJIT_SUCCESS;
-}
-
-/* Size contains the flags as well. */
-static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw size,
- /* The register or immediate operand. */
- sljit_s32 a, sljit_sw imma,
- /* The general operand (not immediate). */
- sljit_s32 b, sljit_sw immb)
-{
- sljit_u8 *inst;
- sljit_u8 *buf_ptr;
- sljit_u8 reg_map_b;
- sljit_uw flags = size;
- sljit_uw inst_size;
-
- /* Both cannot be switched on. */
- SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));
- /* Size flags not allowed for typed instructions. */
- SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0);
- /* Both size flags cannot be switched on. */
- SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG));
- /* SSE2 and immediate is not possible. */
- SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));
- SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3)
- && (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66)
- && (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66));
-
- size &= 0xf;
- inst_size = size;
-
- if (flags & (EX86_PREF_F2 | EX86_PREF_F3))
- inst_size++;
- if (flags & EX86_PREF_66)
- inst_size++;
-
- /* Calculate size of b. */
- inst_size += 1; /* mod r/m byte. */
- if (b & SLJIT_MEM) {
- if (!(b & REG_MASK))
- inst_size += sizeof(sljit_sw);
- else {
- if (immb != 0 && !(b & OFFS_REG_MASK)) {
- /* Immediate operand. */
- if (immb <= 127 && immb >= -128)
- inst_size += sizeof(sljit_s8);
- else
- inst_size += sizeof(sljit_sw);
- }
- else if (reg_map[b & REG_MASK] == 5) {
- /* Swap registers if possible. */
- if ((b & OFFS_REG_MASK) && (immb & 0x3) == 0 && reg_map[OFFS_REG(b)] != 5)
- b = SLJIT_MEM | OFFS_REG(b) | TO_OFFS_REG(b & REG_MASK);
- else
- inst_size += sizeof(sljit_s8);
- }
-
- if (reg_map[b & REG_MASK] == 4 && !(b & OFFS_REG_MASK))
- b |= TO_OFFS_REG(SLJIT_SP);
-
- if (b & OFFS_REG_MASK)
- inst_size += 1; /* SIB byte. */
- }
- }
-
- /* Calculate size of a. */
- if (a & SLJIT_IMM) {
- if (flags & EX86_BIN_INS) {
- if (imma <= 127 && imma >= -128) {
- inst_size += 1;
- flags |= EX86_BYTE_ARG;
- } else
- inst_size += 4;
- }
- else if (flags & EX86_SHIFT_INS) {
- SLJIT_ASSERT(imma <= 0x1f);
- if (imma != 1) {
- inst_size++;
- flags |= EX86_BYTE_ARG;
- }
- } else if (flags & EX86_BYTE_ARG)
- inst_size++;
- else if (flags & EX86_HALF_ARG)
- inst_size += sizeof(short);
- else
- inst_size += sizeof(sljit_sw);
- }
- else
- SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
-
- inst = (sljit_u8*)ensure_buf(compiler, 1 + inst_size);
- PTR_FAIL_IF(!inst);
-
- /* Encoding the byte. */
- INC_SIZE(inst_size);
- if (flags & EX86_PREF_F2)
- *inst++ = 0xf2;
- if (flags & EX86_PREF_F3)
- *inst++ = 0xf3;
- if (flags & EX86_PREF_66)
- *inst++ = 0x66;
-
- buf_ptr = inst + size;
-
- /* Encode mod/rm byte. */
- if (!(flags & EX86_SHIFT_INS)) {
- if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
- *inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81;
-
- if (a & SLJIT_IMM)
- *buf_ptr = 0;
- else if (!(flags & EX86_SSE2_OP1))
- *buf_ptr = U8(reg_map[a] << 3);
- else
- *buf_ptr = U8(a << 3);
- }
- else {
- if (a & SLJIT_IMM) {
- if (imma == 1)
- *inst = GROUP_SHIFT_1;
- else
- *inst = GROUP_SHIFT_N;
- } else
- *inst = GROUP_SHIFT_CL;
- *buf_ptr = 0;
- }
-
- if (!(b & SLJIT_MEM)) {
- *buf_ptr = U8(*buf_ptr | MOD_REG | (!(flags & EX86_SSE2_OP2) ? reg_map[b] : b));
- buf_ptr++;
- } else if (b & REG_MASK) {
- reg_map_b = reg_map[b & REG_MASK];
-
- if (!(b & OFFS_REG_MASK) || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP)) {
- if (immb != 0 || reg_map_b == 5) {
- if (immb <= 127 && immb >= -128)
- *buf_ptr |= 0x40;
- else
- *buf_ptr |= 0x80;
- }
-
- if (!(b & OFFS_REG_MASK))
- *buf_ptr++ |= reg_map_b;
- else {
- *buf_ptr++ |= 0x04;
- *buf_ptr++ = U8(reg_map_b | (reg_map[OFFS_REG(b)] << 3));
- }
-
- if (immb != 0 || reg_map_b == 5) {
- if (immb <= 127 && immb >= -128)
- *buf_ptr++ = U8(immb); /* 8 bit displacement. */
- else {
- sljit_unaligned_store_sw(buf_ptr, immb); /* 32 bit displacement. */
- buf_ptr += sizeof(sljit_sw);
- }
- }
- }
- else {
- if (reg_map_b == 5)
- *buf_ptr |= 0x40;
-
- *buf_ptr++ |= 0x04;
- *buf_ptr++ = U8(reg_map_b | (reg_map[OFFS_REG(b)] << 3) | (immb << 6));
-
- if (reg_map_b == 5)
- *buf_ptr++ = 0;
- }
- }
- else {
- *buf_ptr++ |= 0x05;
- sljit_unaligned_store_sw(buf_ptr, immb); /* 32 bit displacement. */
- buf_ptr += sizeof(sljit_sw);
- }
-
- if (a & SLJIT_IMM) {
- if (flags & EX86_BYTE_ARG)
- *buf_ptr = U8(imma);
- else if (flags & EX86_HALF_ARG)
- sljit_unaligned_store_s16(buf_ptr, (sljit_s16)imma);
- else if (!(flags & EX86_SHIFT_INS))
- sljit_unaligned_store_sw(buf_ptr, imma);
- }
-
- return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1);
-}
-
-/* --------------------------------------------------------------------- */
-/* Enter / return */
-/* --------------------------------------------------------------------- */
-
-static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_sw executable_offset)
-{
- sljit_uw type = jump->flags >> TYPE_SHIFT;
-
- if (type == SLJIT_JUMP) {
- *code_ptr++ = JMP_i32;
- jump->addr++;
- }
- else if (type >= SLJIT_FAST_CALL) {
- *code_ptr++ = CALL_i32;
- jump->addr++;
- }
- else {
- *code_ptr++ = GROUP_0F;
- *code_ptr++ = get_jump_code(type);
- jump->addr += 2;
- }
-
- if (jump->flags & JUMP_LABEL)
- jump->flags |= PATCH_MW;
- else
- sljit_unaligned_store_sw(code_ptr, (sljit_sw)(jump->u.target - (jump->addr + 4) - (sljit_uw)executable_offset));
- code_ptr += 4;
-
- return code_ptr;
-}
-
-#define ENTER_TMP_TO_R4 0x00001
-#define ENTER_TMP_TO_S 0x00002
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- sljit_s32 word_arg_count, saved_arg_count, float_arg_count;
- sljit_s32 size, args_size, types, status;
- sljit_s32 kept_saveds_count = SLJIT_KEPT_SAVEDS_COUNT(options);
- sljit_u8 *inst;
-#ifdef _WIN32
- sljit_s32 r2_offset = -1;
-#endif
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
- set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
-
- /* Emit ENDBR32 at function entry if needed. */
- FAIL_IF(emit_endbranch(compiler));
-
- SLJIT_COMPILE_ASSERT(SLJIT_FR0 == 1, float_register_index_start);
-
- arg_types >>= SLJIT_ARG_SHIFT;
- word_arg_count = 0;
- status = 0;
-
- if (options & SLJIT_ENTER_REG_ARG) {
- args_size = 3 * SSIZE_OF(sw);
-
- while (arg_types) {
- if ((arg_types & SLJIT_ARG_MASK) < SLJIT_ARG_TYPE_F64) {
- word_arg_count++;
- if (word_arg_count >= 4)
- status |= ENTER_TMP_TO_R4;
- }
-
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- compiler->args_size = 0;
- } else {
- types = arg_types;
- saved_arg_count = 0;
- float_arg_count = 0;
- args_size = SSIZE_OF(sw);
- while (types) {
- switch (types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- float_arg_count++;
- FAIL_IF(emit_sse2_load(compiler, 0, float_arg_count, SLJIT_MEM1(SLJIT_SP), args_size));
- args_size += SSIZE_OF(f64);
- break;
- case SLJIT_ARG_TYPE_F32:
- float_arg_count++;
- FAIL_IF(emit_sse2_load(compiler, 1, float_arg_count, SLJIT_MEM1(SLJIT_SP), args_size));
- args_size += SSIZE_OF(f32);
- break;
- default:
- word_arg_count++;
-
- if (!(types & SLJIT_ARG_TYPE_SCRATCH_REG))
- saved_arg_count++;
-
- if (word_arg_count == 4) {
- if (types & SLJIT_ARG_TYPE_SCRATCH_REG) {
- status |= ENTER_TMP_TO_R4;
- arg_types &= ~(SLJIT_ARG_FULL_MASK << 3 * SLJIT_ARG_SHIFT);
- } else if (saved_arg_count == 4) {
- status |= ENTER_TMP_TO_S;
- arg_types &= ~(SLJIT_ARG_FULL_MASK << 3 * SLJIT_ARG_SHIFT);
- }
- }
-
- args_size += SSIZE_OF(sw);
- break;
- }
- types >>= SLJIT_ARG_SHIFT;
- }
-
- args_size -= SSIZE_OF(sw);
- compiler->args_size = args_size;
- }
-
- size = (scratches > 9 ? (scratches - 9) : 0) + (saveds <= 3 ? saveds : 3) - kept_saveds_count;
- if (!(options & SLJIT_ENTER_REG_ARG))
- size++;
-
- if (size != 0) {
- inst = (sljit_u8*)ensure_buf(compiler, (sljit_uw)(size + 1));
- FAIL_IF(!inst);
-
- INC_SIZE((sljit_uw)size);
-
- if (!(options & SLJIT_ENTER_REG_ARG))
- PUSH_REG(reg_map[TMP_REG1]);
-
- if ((saveds > 2 && kept_saveds_count <= 2) || scratches > 9)
- PUSH_REG(reg_map[SLJIT_S2]);
- if ((saveds > 1 && kept_saveds_count <= 1) || scratches > 10)
- PUSH_REG(reg_map[SLJIT_S1]);
- if ((saveds > 0 && kept_saveds_count == 0) || scratches > 11)
- PUSH_REG(reg_map[SLJIT_S0]);
-
- size *= SSIZE_OF(sw);
- }
-
- if (status & (ENTER_TMP_TO_R4 | ENTER_TMP_TO_S))
- EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), args_size + size);
-
- size += SSIZE_OF(sw);
-
- local_size = ((SLJIT_LOCALS_OFFSET_BASE + local_size + size + 0xf) & ~0xf) - size;
- compiler->local_size = local_size;
-
- word_arg_count = 0;
- saved_arg_count = 0;
- args_size = size;
- while (arg_types) {
- switch (arg_types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- args_size += SSIZE_OF(f64);
- break;
- case SLJIT_ARG_TYPE_F32:
- args_size += SSIZE_OF(f32);
- break;
- default:
- word_arg_count++;
- SLJIT_ASSERT(word_arg_count <= 3 || (word_arg_count == 4 && !(status & (ENTER_TMP_TO_R4 | ENTER_TMP_TO_S))));
-
- if (arg_types & SLJIT_ARG_TYPE_SCRATCH_REG) {
-#ifdef _WIN32
- if (word_arg_count == 3 && local_size > 4 * 4096)
- r2_offset = local_size + args_size;
- else
-#endif
- EMIT_MOV(compiler, word_arg_count, 0, SLJIT_MEM1(SLJIT_SP), args_size);
-
- } else {
- EMIT_MOV(compiler, SLJIT_S0 - saved_arg_count, 0, SLJIT_MEM1(SLJIT_SP), args_size);
- saved_arg_count++;
- }
-
- args_size += SSIZE_OF(sw);
- break;
- }
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- SLJIT_ASSERT(SLJIT_LOCALS_OFFSET > 0);
-
-#ifdef _WIN32
- SLJIT_ASSERT(r2_offset == -1 || local_size > 4 * 4096);
-
- if (local_size > 4096) {
- if (local_size <= 4 * 4096) {
- BINARY_IMM32(OR, 0, SLJIT_MEM1(SLJIT_SP), -4096);
-
- if (local_size > 2 * 4096)
- BINARY_IMM32(OR, 0, SLJIT_MEM1(SLJIT_SP), -4096 * 2);
- if (local_size > 3 * 4096)
- BINARY_IMM32(OR, 0, SLJIT_MEM1(SLJIT_SP), -4096 * 3);
- }
- else {
- if (options & SLJIT_ENTER_REG_ARG) {
- SLJIT_ASSERT(r2_offset == -1);
-
- inst = (sljit_u8*)ensure_buf(compiler, (sljit_uw)(1 + 1));
- FAIL_IF(!inst);
- INC_SIZE(1);
- PUSH_REG(reg_map[SLJIT_R2]);
-
- local_size -= SSIZE_OF(sw);
- r2_offset = local_size;
- }
-
- EMIT_MOV(compiler, SLJIT_R2, 0, SLJIT_IMM, local_size >> 12);
-
- BINARY_IMM32(OR, 0, SLJIT_MEM1(SLJIT_SP), -4096);
- BINARY_IMM32(SUB, 4096, SLJIT_SP, 0);
-
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);
- FAIL_IF(!inst);
-
- INC_SIZE(2);
- inst[0] = LOOP_i8;
- inst[1] = (sljit_u8)-16;
- local_size &= 0xfff;
- }
- }
-
- if (local_size > 0) {
- BINARY_IMM32(OR, 0, SLJIT_MEM1(SLJIT_SP), -local_size);
- BINARY_IMM32(SUB, local_size, SLJIT_SP, 0);
- }
-
- if (r2_offset != -1)
- EMIT_MOV(compiler, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), r2_offset);
-
-#else /* !_WIN32 */
-
- SLJIT_ASSERT(local_size > 0);
-
- BINARY_IMM32(SUB, local_size, SLJIT_SP, 0);
-
-#endif /* _WIN32 */
-
- size = SLJIT_LOCALS_OFFSET_BASE - SSIZE_OF(sw);
- kept_saveds_count = SLJIT_R3 - kept_saveds_count;
-
- while (saved_arg_count > 3) {
- EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), size, kept_saveds_count, 0);
- kept_saveds_count++;
- size -= SSIZE_OF(sw);
- saved_arg_count--;
- }
-
- if (status & (ENTER_TMP_TO_R4 | ENTER_TMP_TO_S)) {
- if (status & ENTER_TMP_TO_R4)
- size = 2 * SSIZE_OF(sw);
-
- EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), size, TMP_REG1, 0);
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- sljit_s32 args_size;
-
- CHECK_ERROR();
- CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
- set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
-
- arg_types >>= SLJIT_ARG_SHIFT;
- args_size = 0;
-
- if (!(options & SLJIT_ENTER_REG_ARG)) {
- while (arg_types) {
- switch (arg_types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- args_size += SSIZE_OF(f64);
- break;
- case SLJIT_ARG_TYPE_F32:
- args_size += SSIZE_OF(f32);
- break;
- default:
- args_size += SSIZE_OF(sw);
- break;
- }
- arg_types >>= SLJIT_ARG_SHIFT;
- }
- }
-
- compiler->args_size = args_size;
-
- /* [esp+0] for saving temporaries and for function calls. */
-
- saveds = (1 + (scratches > 9 ? (scratches - 9) : 0) + (saveds <= 3 ? saveds : 3) - SLJIT_KEPT_SAVEDS_COUNT(options)) * SSIZE_OF(sw);
-
- /* Saving ebp. */
- if (!(options & SLJIT_ENTER_REG_ARG))
- saveds += SSIZE_OF(sw);
-
- compiler->local_size = ((SLJIT_LOCALS_OFFSET_BASE + local_size + saveds + 0xf) & ~0xf) - saveds;
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 is_return_to)
-{
- sljit_s32 kept_saveds_count = SLJIT_KEPT_SAVEDS_COUNT(compiler->options);
- sljit_s32 local_size, saveds;
- sljit_uw size;
- sljit_u8 *inst;
-
- size = (sljit_uw)((compiler->scratches > 9 ? (compiler->scratches - 9) : 0) +
- (compiler->saveds <= 3 ? compiler->saveds : 3) - kept_saveds_count);
-
- local_size = compiler->local_size;
-
- if (!(compiler->options & SLJIT_ENTER_REG_ARG))
- size++;
- else if (is_return_to && size == 0) {
- local_size += SSIZE_OF(sw);
- is_return_to = 0;
- }
-
- if (local_size > 0)
- BINARY_IMM32(ADD, local_size, SLJIT_SP, 0);
-
- if (size == 0)
- return SLJIT_SUCCESS;
-
- inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
- FAIL_IF(!inst);
-
- INC_SIZE(size);
-
- saveds = compiler->saveds;
-
- if ((saveds > 0 && kept_saveds_count == 0) || compiler->scratches > 11)
- POP_REG(reg_map[SLJIT_S0]);
- if ((saveds > 1 && kept_saveds_count <= 1) || compiler->scratches > 10)
- POP_REG(reg_map[SLJIT_S1]);
- if ((saveds > 2 && kept_saveds_count <= 2) || compiler->scratches > 9)
- POP_REG(reg_map[SLJIT_S2]);
-
- if (!(compiler->options & SLJIT_ENTER_REG_ARG))
- POP_REG(reg_map[TMP_REG1]);
-
- if (is_return_to)
- BINARY_IMM32(ADD, sizeof(sljit_sw), SLJIT_SP, 0);
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)
-{
- sljit_u8 *inst;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_return_void(compiler));
-
- SLJIT_ASSERT(compiler->args_size >= 0);
- SLJIT_ASSERT(compiler->local_size > 0);
-
- FAIL_IF(emit_stack_frame_release(compiler, 0));
-
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
- FAIL_IF(!inst);
- INC_SIZE(1);
- RET();
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 src_r;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_return_to(compiler, src, srcw));
-
- if ((src & SLJIT_MEM) || (src > SLJIT_R2 && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options)))) {
- ADJUST_LOCAL_OFFSET(src, srcw);
- CHECK_EXTRA_REGS(src, srcw, (void)0);
-
- src_r = (compiler->options & SLJIT_ENTER_REG_ARG) ? TMP_REG1 : SLJIT_R1;
-
- EMIT_MOV(compiler, src_r, 0, src, srcw);
- src = src_r;
- srcw = 0;
- }
-
- FAIL_IF(emit_stack_frame_release(compiler, 1));
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);
-}
-
-/* --------------------------------------------------------------------- */
-/* Call / return instructions */
-/* --------------------------------------------------------------------- */
-
-static sljit_s32 call_get_stack_size(sljit_s32 arg_types, sljit_s32 *word_arg_count_ptr)
-{
- sljit_sw stack_size = 0;
- sljit_s32 word_arg_count = 0;
-
- arg_types >>= SLJIT_ARG_SHIFT;
-
- while (arg_types) {
- switch (arg_types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- stack_size += SSIZE_OF(f64);
- break;
- case SLJIT_ARG_TYPE_F32:
- stack_size += SSIZE_OF(f32);
- break;
- default:
- word_arg_count++;
- stack_size += SSIZE_OF(sw);
- break;
- }
-
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- if (word_arg_count_ptr)
- *word_arg_count_ptr = word_arg_count;
-
- if (stack_size <= 4 * SSIZE_OF(sw))
- return 0;
-
- return ((stack_size - (4 * SSIZE_OF(sw)) + 0xf) & ~0xf);
-}
-
-static sljit_s32 call_with_args(struct sljit_compiler *compiler,
- sljit_s32 arg_types, sljit_sw stack_size, sljit_s32 word_arg_count, sljit_s32 keep_tmp1)
-{
- sljit_s32 float_arg_count = 0, arg4_reg = 0, arg_offset;
- sljit_u8 *inst;
-
- if (word_arg_count >= 4) {
- arg4_reg = SLJIT_R0;
-
- if (!keep_tmp1) {
- EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), 2 * SSIZE_OF(sw));
- arg4_reg = TMP_REG1;
- }
- }
-
- if (stack_size > 0)
- BINARY_IMM32(SUB, stack_size, SLJIT_SP, 0);
-
- arg_offset = 0;
- word_arg_count = 0;
- arg_types >>= SLJIT_ARG_SHIFT;
-
- while (arg_types) {
- switch (arg_types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- float_arg_count++;
- FAIL_IF(emit_sse2_store(compiler, 0, SLJIT_MEM1(SLJIT_SP), arg_offset, float_arg_count));
- arg_offset += SSIZE_OF(f64);
- break;
- case SLJIT_ARG_TYPE_F32:
- float_arg_count++;
- FAIL_IF(emit_sse2_store(compiler, 1, SLJIT_MEM1(SLJIT_SP), arg_offset, float_arg_count));
- arg_offset += SSIZE_OF(f32);
- break;
- default:
- word_arg_count++;
- EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), arg_offset, (word_arg_count >= 4) ? arg4_reg : word_arg_count, 0);
-
- if (word_arg_count == 1 && arg4_reg == SLJIT_R0)
- EMIT_MOV(compiler, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_SP), 2 * SSIZE_OF(sw) + stack_size);
-
- arg_offset += SSIZE_OF(sw);
- break;
- }
-
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 post_call_with_args(struct sljit_compiler *compiler,
- sljit_s32 arg_types, sljit_s32 stack_size)
-{
- sljit_u8 *inst;
- sljit_s32 single;
-
- if (stack_size > 0)
- BINARY_IMM32(ADD, stack_size, SLJIT_SP, 0);
-
- if ((arg_types & SLJIT_ARG_MASK) < SLJIT_ARG_TYPE_F64)
- return SLJIT_SUCCESS;
-
- single = ((arg_types & SLJIT_ARG_MASK) == SLJIT_ARG_TYPE_F32);
-
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 3);
- FAIL_IF(!inst);
- INC_SIZE(3);
- inst[0] = single ? FSTPS : FSTPD;
- inst[1] = (0x03 << 3) | 0x04;
- inst[2] = (0x04 << 3) | reg_map[SLJIT_SP];
-
- return emit_sse2_load(compiler, single, SLJIT_FR0, SLJIT_MEM1(SLJIT_SP), 0);
-}
-
-static sljit_s32 tail_call_with_args(struct sljit_compiler *compiler,
- sljit_s32 *extra_space, sljit_s32 arg_types,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_sw args_size, saved_regs_size;
- sljit_sw types, word_arg_count, float_arg_count;
- sljit_sw stack_size, prev_stack_size, min_size, offset;
- sljit_sw word_arg4_offset;
- sljit_u8 r2_offset = 0;
- sljit_s32 kept_saveds_count = SLJIT_KEPT_SAVEDS_COUNT(compiler->options);
- sljit_u8* inst;
-
- ADJUST_LOCAL_OFFSET(src, srcw);
- CHECK_EXTRA_REGS(src, srcw, (void)0);
-
- saved_regs_size = (1 + (compiler->scratches > 9 ? (compiler->scratches - 9) : 0)
- + (compiler->saveds <= 3 ? compiler->saveds : 3) - kept_saveds_count) * SSIZE_OF(sw);
-
- word_arg_count = 0;
- float_arg_count = 0;
- arg_types >>= SLJIT_ARG_SHIFT;
- types = 0;
- args_size = 0;
-
- while (arg_types != 0) {
- types = (types << SLJIT_ARG_SHIFT) | (arg_types & SLJIT_ARG_MASK);
-
- switch (arg_types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- args_size += SSIZE_OF(f64);
- float_arg_count++;
- break;
- case SLJIT_ARG_TYPE_F32:
- args_size += SSIZE_OF(f32);
- float_arg_count++;
- break;
- default:
- word_arg_count++;
- args_size += SSIZE_OF(sw);
- break;
- }
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- if (args_size <= compiler->args_size) {
- *extra_space = 0;
- stack_size = args_size + SSIZE_OF(sw) + saved_regs_size;
-
- offset = stack_size + compiler->local_size;
-
- if (!(src & SLJIT_IMM) && src != SLJIT_R0) {
- if (word_arg_count >= 1) {
- EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_R0, 0);
- r2_offset = sizeof(sljit_sw);
- }
- EMIT_MOV(compiler, SLJIT_R0, 0, src, srcw);
- }
-
- while (types != 0) {
- switch (types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- offset -= SSIZE_OF(f64);
- FAIL_IF(emit_sse2_store(compiler, 0, SLJIT_MEM1(SLJIT_SP), offset, float_arg_count));
- float_arg_count--;
- break;
- case SLJIT_ARG_TYPE_F32:
- offset -= SSIZE_OF(f32);
- FAIL_IF(emit_sse2_store(compiler, 0, SLJIT_MEM1(SLJIT_SP), offset, float_arg_count));
- float_arg_count--;
- break;
- default:
- switch (word_arg_count) {
- case 1:
- offset -= SSIZE_OF(sw);
- if (r2_offset != 0) {
- EMIT_MOV(compiler, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), 0);
- EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), offset, SLJIT_R2, 0);
- } else
- EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), offset, SLJIT_R0, 0);
- break;
- case 2:
- offset -= SSIZE_OF(sw);
- EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), offset, SLJIT_R1, 0);
- break;
- case 3:
- offset -= SSIZE_OF(sw);
- break;
- case 4:
- offset -= SSIZE_OF(sw);
- EMIT_MOV(compiler, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), 2 * SSIZE_OF(sw));
- EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), offset, SLJIT_R2, 0);
- break;
- }
- word_arg_count--;
- break;
- }
- types >>= SLJIT_ARG_SHIFT;
- }
-
- return emit_stack_frame_release(compiler, 0);
- }
-
- stack_size = args_size + SSIZE_OF(sw);
-
- if (word_arg_count >= 1 && !(src & SLJIT_IMM) && src != SLJIT_R0) {
- r2_offset = SSIZE_OF(sw);
- stack_size += SSIZE_OF(sw);
- }
-
- if (word_arg_count >= 3)
- stack_size += SSIZE_OF(sw);
-
- prev_stack_size = SSIZE_OF(sw) + saved_regs_size;
- min_size = prev_stack_size + compiler->local_size;
-
- word_arg4_offset = 2 * SSIZE_OF(sw);
-
- if (stack_size > min_size) {
- BINARY_IMM32(SUB, stack_size - min_size, SLJIT_SP, 0);
- if (src == SLJIT_MEM1(SLJIT_SP))
- srcw += stack_size - min_size;
- word_arg4_offset += stack_size - min_size;
- }
- else
- stack_size = min_size;
-
- if (word_arg_count >= 3) {
- EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), r2_offset, SLJIT_R2, 0);
-
- if (word_arg_count >= 4)
- EMIT_MOV(compiler, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), word_arg4_offset);
- }
-
- if (!(src & SLJIT_IMM) && src != SLJIT_R0) {
- if (word_arg_count >= 1) {
- SLJIT_ASSERT(r2_offset == sizeof(sljit_sw));
- EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_R0, 0);
- }
- EMIT_MOV(compiler, SLJIT_R0, 0, src, srcw);
- }
-
- /* Restore saved registers. */
- offset = stack_size - 2 * SSIZE_OF(sw);
- EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), offset);
-
- if (compiler->saveds > 2 || compiler->scratches > 9) {
- offset -= SSIZE_OF(sw);
- EMIT_MOV(compiler, SLJIT_S2, 0, SLJIT_MEM1(SLJIT_SP), offset);
- }
- if ((compiler->saveds > 1 && kept_saveds_count <= 1) || compiler->scratches > 10) {
- offset -= SSIZE_OF(sw);
- EMIT_MOV(compiler, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_SP), offset);
- }
- if ((compiler->saveds > 0 && kept_saveds_count == 0) || compiler->scratches > 11) {
- offset -= SSIZE_OF(sw);
- EMIT_MOV(compiler, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_SP), offset);
- }
-
- /* Copy fourth argument and return address. */
- offset = stack_size - SSIZE_OF(sw);
- *extra_space = args_size;
-
- if (word_arg_count >= 4) {
- offset -= SSIZE_OF(sw);
- EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), offset, SLJIT_R2, 0);
- }
-
- while (types != 0) {
- switch (types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- offset -= SSIZE_OF(f64);
- FAIL_IF(emit_sse2_store(compiler, 0, SLJIT_MEM1(SLJIT_SP), offset, float_arg_count));
- float_arg_count--;
- break;
- case SLJIT_ARG_TYPE_F32:
- offset -= SSIZE_OF(f32);
- FAIL_IF(emit_sse2_store(compiler, 0, SLJIT_MEM1(SLJIT_SP), offset, float_arg_count));
- float_arg_count--;
- break;
- default:
- switch (word_arg_count) {
- case 1:
- offset -= SSIZE_OF(sw);
- if (r2_offset != 0) {
- EMIT_MOV(compiler, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), 0);
- EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), offset, SLJIT_R2, 0);
- } else
- EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), offset, SLJIT_R0, 0);
- break;
- case 2:
- offset -= SSIZE_OF(sw);
- EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), offset, SLJIT_R1, 0);
- break;
- case 3:
- offset -= SSIZE_OF(sw);
- EMIT_MOV(compiler, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), r2_offset);
- EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), offset, SLJIT_R2, 0);
- break;
- }
- word_arg_count--;
- break;
- }
- types >>= SLJIT_ARG_SHIFT;
- }
-
- SLJIT_ASSERT(offset >= 0);
-
- if (offset == 0)
- return SLJIT_SUCCESS;
-
- BINARY_IMM32(ADD, offset, SLJIT_SP, 0);
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_tail_call_end(struct sljit_compiler *compiler, sljit_s32 extra_space)
-{
- /* Called when stack consumption cannot be reduced to 0. */
- sljit_u8 *inst;
-
- BINARY_IMM32(ADD, extra_space, SLJIT_SP, 0);
-
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
- FAIL_IF(!inst);
- INC_SIZE(1);
- RET();
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 tail_call_reg_arg_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types)
-{
- sljit_s32 word_arg_count = 0;
- sljit_s32 kept_saveds_count, offset;
-
- arg_types >>= SLJIT_ARG_SHIFT;
-
- while (arg_types) {
- if ((arg_types & SLJIT_ARG_MASK) < SLJIT_ARG_TYPE_F64)
- word_arg_count++;
-
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- if (word_arg_count < 4)
- return SLJIT_SUCCESS;
-
- EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), 2 * SSIZE_OF(sw));
-
- kept_saveds_count = SLJIT_KEPT_SAVEDS_COUNT(compiler->options);
- offset = compiler->local_size + 3 * SSIZE_OF(sw);
-
- if ((compiler->saveds > 0 && kept_saveds_count == 0) || compiler->scratches > 11)
- offset += SSIZE_OF(sw);
- if ((compiler->saveds > 1 && kept_saveds_count <= 1) || compiler->scratches > 10)
- offset += SSIZE_OF(sw);
- if ((compiler->saveds > 2 && kept_saveds_count <= 2) || compiler->scratches > 9)
- offset += SSIZE_OF(sw);
-
- return emit_mov(compiler, SLJIT_MEM1(SLJIT_SP), offset, TMP_REG1, 0);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types)
-{
- struct sljit_jump *jump;
- sljit_sw stack_size = 0;
- sljit_s32 word_arg_count;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
-
- if (type & SLJIT_CALL_RETURN) {
- if ((type & 0xff) == SLJIT_CALL_REG_ARG) {
- PTR_FAIL_IF(tail_call_reg_arg_with_args(compiler, arg_types));
- PTR_FAIL_IF(emit_stack_frame_release(compiler, 0));
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_jump(compiler, SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP));
- }
-
- stack_size = type;
- PTR_FAIL_IF(tail_call_with_args(compiler, &stack_size, arg_types, SLJIT_IMM, 0));
-
- SLJIT_SKIP_CHECKS(compiler);
-
- if (stack_size == 0)
- return sljit_emit_jump(compiler, SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP));
-
- jump = sljit_emit_jump(compiler, type);
- PTR_FAIL_IF(jump == NULL);
-
- PTR_FAIL_IF(emit_tail_call_end(compiler, stack_size));
- return jump;
- }
-
- if ((type & 0xff) == SLJIT_CALL_REG_ARG) {
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_jump(compiler, type);
- }
-
- stack_size = call_get_stack_size(arg_types, &word_arg_count);
- PTR_FAIL_IF(call_with_args(compiler, arg_types, stack_size, word_arg_count, 0));
-
- SLJIT_SKIP_CHECKS(compiler);
- jump = sljit_emit_jump(compiler, type);
- PTR_FAIL_IF(jump == NULL);
-
- PTR_FAIL_IF(post_call_with_args(compiler, arg_types, stack_size));
- return jump;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_sw stack_size = 0;
- sljit_s32 word_arg_count;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
-
- if (type & SLJIT_CALL_RETURN) {
- if ((type & 0xff) == SLJIT_CALL_REG_ARG) {
- FAIL_IF(tail_call_reg_arg_with_args(compiler, arg_types));
-
- if ((src & SLJIT_MEM) || (src > SLJIT_R2 && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options)))) {
- ADJUST_LOCAL_OFFSET(src, srcw);
- CHECK_EXTRA_REGS(src, srcw, (void)0);
-
- EMIT_MOV(compiler, TMP_REG1, 0, src, srcw);
- src = TMP_REG1;
- srcw = 0;
- }
-
- FAIL_IF(emit_stack_frame_release(compiler, 0));
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);
- }
-
- stack_size = type;
- FAIL_IF(tail_call_with_args(compiler, &stack_size, arg_types, src, srcw));
-
- if (!(src & SLJIT_IMM)) {
- src = SLJIT_R0;
- srcw = 0;
- }
-
- SLJIT_SKIP_CHECKS(compiler);
-
- if (stack_size == 0)
- return sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);
-
- FAIL_IF(sljit_emit_ijump(compiler, type, src, srcw));
- return emit_tail_call_end(compiler, stack_size);
- }
-
- if ((type & 0xff) == SLJIT_CALL_REG_ARG) {
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_ijump(compiler, type, src, srcw);
- }
-
- ADJUST_LOCAL_OFFSET(src, srcw);
- CHECK_EXTRA_REGS(src, srcw, (void)0);
-
- if (src & SLJIT_MEM) {
- EMIT_MOV(compiler, TMP_REG1, 0, src, srcw);
- src = TMP_REG1;
- srcw = 0;
- }
-
- stack_size = call_get_stack_size(arg_types, &word_arg_count);
- FAIL_IF(call_with_args(compiler, arg_types, stack_size, word_arg_count, src == TMP_REG1));
-
- if (stack_size > 0 && src == SLJIT_MEM1(SLJIT_SP))
- srcw += stack_size;
-
- SLJIT_SKIP_CHECKS(compiler);
- FAIL_IF(sljit_emit_ijump(compiler, type, src, srcw));
-
- return post_call_with_args(compiler, arg_types, stack_size);
-}
-
-static SLJIT_INLINE sljit_s32 emit_fmov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
-{
- sljit_u8* inst;
-
- if (compiler->options & SLJIT_ENTER_REG_ARG) {
- if (src == SLJIT_FR0)
- return SLJIT_SUCCESS;
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_fop1(compiler, op, SLJIT_RETURN_FREG, 0, src, srcw);
- }
-
- if (FAST_IS_REG(src)) {
- FAIL_IF(emit_sse2_store(compiler, op & SLJIT_32, SLJIT_MEM1(SLJIT_SP), 0, src));
-
- src = SLJIT_MEM1(SLJIT_SP);
- srcw = 0;
- } else {
- ADJUST_LOCAL_OFFSET(src, srcw);
- }
-
- inst = emit_x86_instruction(compiler, 1 | EX86_SSE2_OP1, 0, 0, src, srcw);
- *inst = (op & SLJIT_32) ? FLDS : FLDL;
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
-{
- sljit_u8 *inst;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- CHECK_EXTRA_REGS(dst, dstw, (void)0);
-
- if (FAST_IS_REG(dst)) {
- /* Unused dest is possible here. */
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
- FAIL_IF(!inst);
-
- INC_SIZE(1);
- POP_REG(reg_map[dst]);
- return SLJIT_SUCCESS;
- }
-
- /* Memory. */
- inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
- FAIL_IF(!inst);
- *inst++ = POP_rm;
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
-{
- sljit_u8 *inst;
-
- CHECK_EXTRA_REGS(src, srcw, (void)0);
-
- if (FAST_IS_REG(src)) {
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 1);
- FAIL_IF(!inst);
-
- INC_SIZE(1 + 1);
- PUSH_REG(reg_map[src]);
- }
- else {
- inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
- FAIL_IF(!inst);
- *inst++ = GROUP_FF;
- *inst |= PUSH_rm;
-
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
- FAIL_IF(!inst);
- INC_SIZE(1);
- }
-
- RET();
- return SLJIT_SUCCESS;
-}
-
-/* --------------------------------------------------------------------- */
-/* Other operations */
-/* --------------------------------------------------------------------- */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 reg,
- sljit_s32 mem, sljit_sw memw)
-{
- sljit_u8* inst;
- sljit_s32 i, next, reg_idx, offset;
- sljit_u8 regs[2];
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
-
- if (!(reg & REG_PAIR_MASK))
- return sljit_emit_mem_unaligned(compiler, type, reg, mem, memw);
-
- ADJUST_LOCAL_OFFSET(mem, memw);
-
- regs[0] = U8(REG_PAIR_FIRST(reg));
- regs[1] = U8(REG_PAIR_SECOND(reg));
-
- next = SSIZE_OF(sw);
-
- if (!(type & SLJIT_MEM_STORE) && (regs[0] == (mem & REG_MASK) || regs[0] == OFFS_REG(mem))) {
- if (regs[1] == (mem & REG_MASK) || regs[1] == OFFS_REG(mem)) {
- /* None of them are virtual register so TMP_REG1 will not be used. */
- EMIT_MOV(compiler, TMP_REG1, 0, OFFS_REG(mem), 0);
-
- if (regs[1] == OFFS_REG(mem))
- next = -SSIZE_OF(sw);
-
- mem = (mem & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG1);
- } else {
- next = -SSIZE_OF(sw);
-
- if (!(mem & OFFS_REG_MASK))
- memw += SSIZE_OF(sw);
- }
- }
-
- for (i = 0; i < 2; i++) {
- reg_idx = next > 0 ? i : (i ^ 0x1);
- reg = regs[reg_idx];
-
- offset = -1;
-
- if (reg >= SLJIT_R3 && reg <= SLJIT_S3) {
- offset = (2 * SSIZE_OF(sw)) + ((reg) - SLJIT_R3) * SSIZE_OF(sw);
- reg = TMP_REG1;
-
- if (type & SLJIT_MEM_STORE)
- EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), offset);
- }
-
- if ((mem & OFFS_REG_MASK) && (reg_idx == 1)) {
- inst = (sljit_u8*)ensure_buf(compiler, (sljit_uw)(1 + 4));
- FAIL_IF(!inst);
-
- INC_SIZE(4);
-
- inst[0] = (type & SLJIT_MEM_STORE) ? MOV_rm_r : MOV_r_rm;
- inst[1] = 0x44 | U8(reg_map[reg] << 3);
- inst[2] = U8(memw << 6) | U8(reg_map[OFFS_REG(mem)] << 3) | reg_map[mem & REG_MASK];
- inst[3] = sizeof(sljit_sw);
- } else if (type & SLJIT_MEM_STORE) {
- EMIT_MOV(compiler, mem, memw, reg, 0);
- } else {
- EMIT_MOV(compiler, reg, 0, mem, memw);
- }
-
- if (!(mem & OFFS_REG_MASK))
- memw += next;
-
- if (!(type & SLJIT_MEM_STORE) && offset != -1)
- EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), offset, TMP_REG1, 0);
- }
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 skip_frames_before_return(struct sljit_compiler *compiler)
-{
- sljit_sw size;
-
- /* Don't adjust shadow stack if it isn't enabled. */
- if (!cpu_has_shadow_stack())
- return SLJIT_SUCCESS;
-
- SLJIT_ASSERT(compiler->args_size >= 0);
- SLJIT_ASSERT(compiler->local_size > 0);
-
- size = compiler->local_size;
- size += (1 + (compiler->scratches > 9 ? (compiler->scratches - 9) : 0)
- + (compiler->saveds <= 3 ? compiler->saveds : 3)) * SSIZE_OF(sw);
-
- return adjust_shadow_stack(compiler, SLJIT_MEM1(SLJIT_SP), size);
-}
diff --git a/contrib/libs/pcre2/src/sljit/sljitNativeX86_64.c b/contrib/libs/pcre2/src/sljit/sljitNativeX86_64.c
deleted file mode 100644
index 4e938ffcf3..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitNativeX86_64.c
+++ /dev/null
@@ -1,1092 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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.
- */
-
-/* x86 64-bit arch dependent functions. */
-
-/* --------------------------------------------------------------------- */
-/* Operators */
-/* --------------------------------------------------------------------- */
-
-static sljit_s32 emit_load_imm64(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)
-{
- sljit_u8 *inst;
-
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_sw));
- FAIL_IF(!inst);
- INC_SIZE(2 + sizeof(sljit_sw));
- *inst++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B);
- *inst++ = U8(MOV_r_i32 | (reg_map[reg] & 0x7));
- sljit_unaligned_store_sw(inst, imm);
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_do_imm32(struct sljit_compiler *compiler, sljit_u8 rex, sljit_u8 opcode, sljit_sw imm)
-{
- sljit_u8 *inst;
- sljit_uw length = (rex ? 2 : 1) + sizeof(sljit_s32);
-
- inst = (sljit_u8*)ensure_buf(compiler, 1 + length);
- FAIL_IF(!inst);
- INC_SIZE(length);
- if (rex)
- *inst++ = rex;
- *inst++ = opcode;
- sljit_unaligned_store_s32(inst, (sljit_s32)imm);
- return SLJIT_SUCCESS;
-}
-
-static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw size,
- /* The register or immediate operand. */
- sljit_s32 a, sljit_sw imma,
- /* The general operand (not immediate). */
- sljit_s32 b, sljit_sw immb)
-{
- sljit_u8 *inst;
- sljit_u8 *buf_ptr;
- sljit_u8 rex = 0;
- sljit_u8 reg_lmap_b;
- sljit_uw flags = size;
- sljit_uw inst_size;
-
- /* The immediate operand must be 32 bit. */
- SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma));
- /* Both cannot be switched on. */
- SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));
- /* Size flags not allowed for typed instructions. */
- SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0);
- /* Both size flags cannot be switched on. */
- SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG));
- /* SSE2 and immediate is not possible. */
- SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));
- SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3)
- && (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66)
- && (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66));
-
- size &= 0xf;
- inst_size = size;
-
- if (!compiler->mode32 && !(flags & EX86_NO_REXW))
- rex |= REX_W;
- else if (flags & EX86_REX)
- rex |= REX;
-
- if (flags & (EX86_PREF_F2 | EX86_PREF_F3))
- inst_size++;
- if (flags & EX86_PREF_66)
- inst_size++;
-
- /* Calculate size of b. */
- inst_size += 1; /* mod r/m byte. */
- if (b & SLJIT_MEM) {
- if (!(b & OFFS_REG_MASK) && NOT_HALFWORD(immb)) {
- PTR_FAIL_IF(emit_load_imm64(compiler, TMP_REG2, immb));
- immb = 0;
- if (b & REG_MASK)
- b |= TO_OFFS_REG(TMP_REG2);
- else
- b |= TMP_REG2;
- }
-
- if (!(b & REG_MASK))
- inst_size += 1 + sizeof(sljit_s32); /* SIB byte required to avoid RIP based addressing. */
- else {
- if (immb != 0 && !(b & OFFS_REG_MASK)) {
- /* Immediate operand. */
- if (immb <= 127 && immb >= -128)
- inst_size += sizeof(sljit_s8);
- else
- inst_size += sizeof(sljit_s32);
- }
- else if (reg_lmap[b & REG_MASK] == 5) {
- /* Swap registers if possible. */
- if ((b & OFFS_REG_MASK) && (immb & 0x3) == 0 && reg_lmap[OFFS_REG(b)] != 5)
- b = SLJIT_MEM | OFFS_REG(b) | TO_OFFS_REG(b & REG_MASK);
- else
- inst_size += sizeof(sljit_s8);
- }
-
- if (reg_map[b & REG_MASK] >= 8)
- rex |= REX_B;
-
- if (reg_lmap[b & REG_MASK] == 4 && !(b & OFFS_REG_MASK))
- b |= TO_OFFS_REG(SLJIT_SP);
-
- if (b & OFFS_REG_MASK) {
- inst_size += 1; /* SIB byte. */
- if (reg_map[OFFS_REG(b)] >= 8)
- rex |= REX_X;
- }
- }
- }
- else if (!(flags & EX86_SSE2_OP2)) {
- if (reg_map[b] >= 8)
- rex |= REX_B;
- }
- else if (freg_map[b] >= 8)
- rex |= REX_B;
-
- if (a & SLJIT_IMM) {
- if (flags & EX86_BIN_INS) {
- if (imma <= 127 && imma >= -128) {
- inst_size += 1;
- flags |= EX86_BYTE_ARG;
- } else
- inst_size += 4;
- }
- else if (flags & EX86_SHIFT_INS) {
- SLJIT_ASSERT(imma <= (compiler->mode32 ? 0x1f : 0x3f));
- if (imma != 1) {
- inst_size++;
- flags |= EX86_BYTE_ARG;
- }
- } else if (flags & EX86_BYTE_ARG)
- inst_size++;
- else if (flags & EX86_HALF_ARG)
- inst_size += sizeof(short);
- else
- inst_size += sizeof(sljit_s32);
- }
- else {
- SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
- /* reg_map[SLJIT_PREF_SHIFT_REG] is less than 8. */
- if (!(flags & EX86_SSE2_OP1)) {
- if (reg_map[a] >= 8)
- rex |= REX_R;
- }
- else if (freg_map[a] >= 8)
- rex |= REX_R;
- }
-
- if (rex)
- inst_size++;
-
- inst = (sljit_u8*)ensure_buf(compiler, 1 + inst_size);
- PTR_FAIL_IF(!inst);
-
- /* Encoding the byte. */
- INC_SIZE(inst_size);
- if (flags & EX86_PREF_F2)
- *inst++ = 0xf2;
- if (flags & EX86_PREF_F3)
- *inst++ = 0xf3;
- if (flags & EX86_PREF_66)
- *inst++ = 0x66;
- if (rex)
- *inst++ = rex;
- buf_ptr = inst + size;
-
- /* Encode mod/rm byte. */
- if (!(flags & EX86_SHIFT_INS)) {
- if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
- *inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81;
-
- if (a & SLJIT_IMM)
- *buf_ptr = 0;
- else if (!(flags & EX86_SSE2_OP1))
- *buf_ptr = U8(reg_lmap[a] << 3);
- else
- *buf_ptr = U8(freg_lmap[a] << 3);
- }
- else {
- if (a & SLJIT_IMM) {
- if (imma == 1)
- *inst = GROUP_SHIFT_1;
- else
- *inst = GROUP_SHIFT_N;
- } else
- *inst = GROUP_SHIFT_CL;
- *buf_ptr = 0;
- }
-
- if (!(b & SLJIT_MEM)) {
- *buf_ptr = U8(*buf_ptr | MOD_REG | (!(flags & EX86_SSE2_OP2) ? reg_lmap[b] : freg_lmap[b]));
- buf_ptr++;
- } else if (b & REG_MASK) {
- reg_lmap_b = reg_lmap[b & REG_MASK];
-
- if (!(b & OFFS_REG_MASK) || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP)) {
- if (immb != 0 || reg_lmap_b == 5) {
- if (immb <= 127 && immb >= -128)
- *buf_ptr |= 0x40;
- else
- *buf_ptr |= 0x80;
- }
-
- if (!(b & OFFS_REG_MASK))
- *buf_ptr++ |= reg_lmap_b;
- else {
- *buf_ptr++ |= 0x04;
- *buf_ptr++ = U8(reg_lmap_b | (reg_lmap[OFFS_REG(b)] << 3));
- }
-
- if (immb != 0 || reg_lmap_b == 5) {
- if (immb <= 127 && immb >= -128)
- *buf_ptr++ = U8(immb); /* 8 bit displacement. */
- else {
- sljit_unaligned_store_s32(buf_ptr, (sljit_s32)immb); /* 32 bit displacement. */
- buf_ptr += sizeof(sljit_s32);
- }
- }
- }
- else {
- if (reg_lmap_b == 5)
- *buf_ptr |= 0x40;
-
- *buf_ptr++ |= 0x04;
- *buf_ptr++ = U8(reg_lmap_b | (reg_lmap[OFFS_REG(b)] << 3) | (immb << 6));
-
- if (reg_lmap_b == 5)
- *buf_ptr++ = 0;
- }
- }
- else {
- *buf_ptr++ |= 0x04;
- *buf_ptr++ = 0x25;
- sljit_unaligned_store_s32(buf_ptr, (sljit_s32)immb); /* 32 bit displacement. */
- buf_ptr += sizeof(sljit_s32);
- }
-
- if (a & SLJIT_IMM) {
- if (flags & EX86_BYTE_ARG)
- *buf_ptr = U8(imma);
- else if (flags & EX86_HALF_ARG)
- sljit_unaligned_store_s16(buf_ptr, (sljit_s16)imma);
- else if (!(flags & EX86_SHIFT_INS))
- sljit_unaligned_store_s32(buf_ptr, (sljit_s32)imma);
- }
-
- return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1);
-}
-
-/* --------------------------------------------------------------------- */
-/* Enter / return */
-/* --------------------------------------------------------------------- */
-
-static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr)
-{
- sljit_uw type = jump->flags >> TYPE_SHIFT;
-
- int short_addr = !(jump->flags & SLJIT_REWRITABLE_JUMP) && !(jump->flags & JUMP_LABEL) && (jump->u.target <= 0xffffffff);
-
- /* The relative jump below specialized for this case. */
- SLJIT_ASSERT(reg_map[TMP_REG2] >= 8);
-
- if (type < SLJIT_JUMP) {
- /* Invert type. */
- *code_ptr++ = U8(get_jump_code(type ^ 0x1) - 0x10);
- *code_ptr++ = short_addr ? (6 + 3) : (10 + 3);
- }
-
- *code_ptr++ = short_addr ? REX_B : (REX_W | REX_B);
- *code_ptr++ = MOV_r_i32 | reg_lmap[TMP_REG2];
- jump->addr = (sljit_uw)code_ptr;
-
- if (jump->flags & JUMP_LABEL)
- jump->flags |= PATCH_MD;
- else if (short_addr)
- sljit_unaligned_store_s32(code_ptr, (sljit_s32)jump->u.target);
- else
- sljit_unaligned_store_sw(code_ptr, (sljit_sw)jump->u.target);
-
- code_ptr += short_addr ? sizeof(sljit_s32) : sizeof(sljit_sw);
-
- *code_ptr++ = REX_B;
- *code_ptr++ = GROUP_FF;
- *code_ptr++ = U8(MOD_REG | (type >= SLJIT_FAST_CALL ? CALL_rm : JMP_rm) | reg_lmap[TMP_REG2]);
-
- return code_ptr;
-}
-
-static sljit_u8* generate_put_label_code(struct sljit_put_label *put_label, sljit_u8 *code_ptr, sljit_uw max_label)
-{
- if (max_label > HALFWORD_MAX) {
- put_label->addr -= put_label->flags;
- put_label->flags = PATCH_MD;
- return code_ptr;
- }
-
- if (put_label->flags == 0) {
- /* Destination is register. */
- code_ptr = (sljit_u8*)put_label->addr - 2 - sizeof(sljit_uw);
-
- SLJIT_ASSERT((code_ptr[0] & 0xf8) == REX_W);
- SLJIT_ASSERT((code_ptr[1] & 0xf8) == MOV_r_i32);
-
- if ((code_ptr[0] & 0x07) != 0) {
- code_ptr[0] = U8(code_ptr[0] & ~0x08);
- code_ptr += 2 + sizeof(sljit_s32);
- }
- else {
- code_ptr[0] = code_ptr[1];
- code_ptr += 1 + sizeof(sljit_s32);
- }
-
- put_label->addr = (sljit_uw)code_ptr;
- return code_ptr;
- }
-
- code_ptr -= put_label->flags + (2 + sizeof(sljit_uw));
- SLJIT_MEMMOVE(code_ptr, code_ptr + (2 + sizeof(sljit_uw)), put_label->flags);
-
- SLJIT_ASSERT((code_ptr[0] & 0xf8) == REX_W);
-
- if ((code_ptr[1] & 0xf8) == MOV_r_i32) {
- code_ptr += 2 + sizeof(sljit_uw);
- SLJIT_ASSERT((code_ptr[0] & 0xf8) == REX_W);
- }
-
- SLJIT_ASSERT(code_ptr[1] == MOV_rm_r);
-
- code_ptr[0] = U8(code_ptr[0] & ~0x4);
- code_ptr[1] = MOV_rm_i32;
- code_ptr[2] = U8(code_ptr[2] & ~(0x7 << 3));
-
- code_ptr = (sljit_u8*)(put_label->addr - (2 + sizeof(sljit_uw)) + sizeof(sljit_s32));
- put_label->addr = (sljit_uw)code_ptr;
- put_label->flags = 0;
- return code_ptr;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- sljit_uw size;
- sljit_s32 word_arg_count = 0;
- sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options);
- sljit_s32 saved_regs_size, tmp, i;
-#ifdef _WIN64
- sljit_s32 saved_float_regs_size;
- sljit_s32 saved_float_regs_offset = 0;
- sljit_s32 float_arg_count = 0;
-#endif /* _WIN64 */
- sljit_u8 *inst;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
- set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
-
- if (options & SLJIT_ENTER_REG_ARG)
- arg_types = 0;
-
- /* Emit ENDBR64 at function entry if needed. */
- FAIL_IF(emit_endbranch(compiler));
-
- compiler->mode32 = 0;
-
- /* Including the return address saved by the call instruction. */
- saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1);
-
- tmp = SLJIT_S0 - saveds;
- for (i = SLJIT_S0 - saved_arg_count; i > tmp; i--) {
- size = reg_map[i] >= 8 ? 2 : 1;
- inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
- FAIL_IF(!inst);
- INC_SIZE(size);
- if (reg_map[i] >= 8)
- *inst++ = REX_B;
- PUSH_REG(reg_lmap[i]);
- }
-
- for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
- size = reg_map[i] >= 8 ? 2 : 1;
- inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
- FAIL_IF(!inst);
- INC_SIZE(size);
- if (reg_map[i] >= 8)
- *inst++ = REX_B;
- PUSH_REG(reg_lmap[i]);
- }
-
-#ifdef _WIN64
- local_size += SLJIT_LOCALS_OFFSET;
- saved_float_regs_size = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, 16);
-
- if (saved_float_regs_size > 0) {
- saved_float_regs_offset = ((local_size + 0xf) & ~0xf);
- local_size = saved_float_regs_offset + saved_float_regs_size;
- }
-#else /* !_WIN64 */
- SLJIT_ASSERT(SLJIT_LOCALS_OFFSET == 0);
-#endif /* _WIN64 */
-
- arg_types >>= SLJIT_ARG_SHIFT;
-
- while (arg_types > 0) {
- if ((arg_types & SLJIT_ARG_MASK) < SLJIT_ARG_TYPE_F64) {
- tmp = 0;
-#ifndef _WIN64
- switch (word_arg_count) {
- case 0:
- tmp = SLJIT_R2;
- break;
- case 1:
- tmp = SLJIT_R1;
- break;
- case 2:
- tmp = TMP_REG1;
- break;
- default:
- tmp = SLJIT_R3;
- break;
- }
-#else /* !_WIN64 */
- switch (word_arg_count + float_arg_count) {
- case 0:
- tmp = SLJIT_R3;
- break;
- case 1:
- tmp = SLJIT_R1;
- break;
- case 2:
- tmp = SLJIT_R2;
- break;
- default:
- tmp = TMP_REG1;
- break;
- }
-#endif /* _WIN64 */
- if (arg_types & SLJIT_ARG_TYPE_SCRATCH_REG) {
- if (tmp != SLJIT_R0 + word_arg_count)
- EMIT_MOV(compiler, SLJIT_R0 + word_arg_count, 0, tmp, 0);
- } else {
- EMIT_MOV(compiler, SLJIT_S0 - saved_arg_count, 0, tmp, 0);
- saved_arg_count++;
- }
- word_arg_count++;
- } else {
-#ifdef _WIN64
- SLJIT_COMPILE_ASSERT(SLJIT_FR0 == 1, float_register_index_start);
- float_arg_count++;
- if (float_arg_count != float_arg_count + word_arg_count)
- FAIL_IF(emit_sse2_load(compiler, (arg_types & SLJIT_ARG_MASK) == SLJIT_ARG_TYPE_F32,
- float_arg_count, float_arg_count + word_arg_count, 0));
-#endif /* _WIN64 */
- }
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- local_size = ((local_size + saved_regs_size + 0xf) & ~0xf) - saved_regs_size;
- compiler->local_size = local_size;
-
-#ifdef _WIN64
- if (local_size > 0) {
- if (local_size <= 4 * 4096) {
- if (local_size > 4096)
- EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096);
- if (local_size > 2 * 4096)
- EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096 * 2);
- if (local_size > 3 * 4096)
- EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096 * 3);
- }
- else {
- EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, local_size >> 12);
-
- EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_MEM1(SLJIT_SP), -4096);
- BINARY_IMM32(SUB, 4096, SLJIT_SP, 0);
- BINARY_IMM32(SUB, 1, TMP_REG1, 0);
-
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);
- FAIL_IF(!inst);
-
- INC_SIZE(2);
- inst[0] = JNE_i8;
- inst[1] = (sljit_u8)-21;
- local_size &= 0xfff;
- }
-
- if (local_size > 0)
- EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -local_size);
- }
-#endif /* _WIN64 */
-
- if (local_size > 0)
- BINARY_IMM32(SUB, local_size, SLJIT_SP, 0);
-
-#ifdef _WIN64
- if (saved_float_regs_size > 0) {
- compiler->mode32 = 1;
-
- tmp = SLJIT_FS0 - fsaveds;
- for (i = SLJIT_FS0; i > tmp; i--) {
- inst = emit_x86_instruction(compiler, 2 | EX86_SSE2, i, 0, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset);
- *inst++ = GROUP_0F;
- *inst = MOVAPS_xm_x;
- saved_float_regs_offset += 16;
- }
-
- for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
- inst = emit_x86_instruction(compiler, 2 | EX86_SSE2, i, 0, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset);
- *inst++ = GROUP_0F;
- *inst = MOVAPS_xm_x;
- saved_float_regs_offset += 16;
- }
- }
-#endif /* _WIN64 */
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- sljit_s32 saved_regs_size;
-#ifdef _WIN64
- sljit_s32 saved_float_regs_size;
-#endif /* _WIN64 */
-
- CHECK_ERROR();
- CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
- set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
-
-#ifdef _WIN64
- local_size += SLJIT_LOCALS_OFFSET;
- saved_float_regs_size = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, 16);
-
- if (saved_float_regs_size > 0)
- local_size = ((local_size + 0xf) & ~0xf) + saved_float_regs_size;
-#else /* !_WIN64 */
- SLJIT_ASSERT(SLJIT_LOCALS_OFFSET == 0);
-#endif /* _WIN64 */
-
- /* Including the return address saved by the call instruction. */
- saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1);
- compiler->local_size = ((local_size + saved_regs_size + 0xf) & ~0xf) - saved_regs_size;
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 is_return_to)
-{
- sljit_uw size;
- sljit_s32 local_size, i, tmp;
- sljit_u8 *inst;
-#ifdef _WIN64
- sljit_s32 saved_float_regs_offset;
- sljit_s32 fscratches = compiler->fscratches;
- sljit_s32 fsaveds = compiler->fsaveds;
-#endif /* _WIN64 */
-
-#ifdef _WIN64
- saved_float_regs_offset = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, 16);
-
- if (saved_float_regs_offset > 0) {
- compiler->mode32 = 1;
- saved_float_regs_offset = (compiler->local_size - saved_float_regs_offset) & ~0xf;
-
- tmp = SLJIT_FS0 - fsaveds;
- for (i = SLJIT_FS0; i > tmp; i--) {
- inst = emit_x86_instruction(compiler, 2 | EX86_SSE2, i, 0, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset);
- *inst++ = GROUP_0F;
- *inst = MOVAPS_x_xm;
- saved_float_regs_offset += 16;
- }
-
- for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
- inst = emit_x86_instruction(compiler, 2 | EX86_SSE2, i, 0, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset);
- *inst++ = GROUP_0F;
- *inst = MOVAPS_x_xm;
- saved_float_regs_offset += 16;
- }
-
- compiler->mode32 = 0;
- }
-#endif /* _WIN64 */
-
- local_size = compiler->local_size;
-
- if (is_return_to && compiler->scratches < SLJIT_FIRST_SAVED_REG && (compiler->saveds == SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
- local_size += SSIZE_OF(sw);
- is_return_to = 0;
- }
-
- if (local_size > 0)
- BINARY_IMM32(ADD, local_size, SLJIT_SP, 0);
-
- tmp = compiler->scratches;
- for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) {
- size = reg_map[i] >= 8 ? 2 : 1;
- inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
- FAIL_IF(!inst);
- INC_SIZE(size);
- if (reg_map[i] >= 8)
- *inst++ = REX_B;
- POP_REG(reg_lmap[i]);
- }
-
- tmp = SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options);
- for (i = SLJIT_S0 + 1 - compiler->saveds; i <= tmp; i++) {
- size = reg_map[i] >= 8 ? 2 : 1;
- inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
- FAIL_IF(!inst);
- INC_SIZE(size);
- if (reg_map[i] >= 8)
- *inst++ = REX_B;
- POP_REG(reg_lmap[i]);
- }
-
- if (is_return_to)
- BINARY_IMM32(ADD, sizeof(sljit_sw), SLJIT_SP, 0);
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)
-{
- sljit_u8 *inst;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_return_void(compiler));
-
- compiler->mode32 = 0;
-
- FAIL_IF(emit_stack_frame_release(compiler, 0));
-
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
- FAIL_IF(!inst);
- INC_SIZE(1);
- RET();
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,
- sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_return_to(compiler, src, srcw));
-
- compiler->mode32 = 0;
-
- if ((src & SLJIT_MEM) || (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options)))) {
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- EMIT_MOV(compiler, TMP_REG2, 0, src, srcw);
- src = TMP_REG2;
- srcw = 0;
- }
-
- FAIL_IF(emit_stack_frame_release(compiler, 1));
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);
-}
-
-/* --------------------------------------------------------------------- */
-/* Call / return instructions */
-/* --------------------------------------------------------------------- */
-
-#ifndef _WIN64
-
-static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src_ptr)
-{
- sljit_s32 src = src_ptr ? (*src_ptr) : 0;
- sljit_s32 word_arg_count = 0;
-
- SLJIT_ASSERT(reg_map[SLJIT_R1] == 6 && reg_map[SLJIT_R3] == 1 && reg_map[TMP_REG1] == 2);
- SLJIT_ASSERT(!(src & SLJIT_MEM));
-
- /* Remove return value. */
- arg_types >>= SLJIT_ARG_SHIFT;
-
- while (arg_types) {
- if ((arg_types & SLJIT_ARG_MASK) < SLJIT_ARG_TYPE_F64)
- word_arg_count++;
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- if (word_arg_count == 0)
- return SLJIT_SUCCESS;
-
- if (word_arg_count >= 3) {
- if (src == SLJIT_R2)
- *src_ptr = TMP_REG1;
- EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R2, 0);
- }
-
- return emit_mov(compiler, SLJIT_R2, 0, SLJIT_R0, 0);
-}
-
-#else
-
-static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src_ptr)
-{
- sljit_s32 src = src_ptr ? (*src_ptr) : 0;
- sljit_s32 arg_count = 0;
- sljit_s32 word_arg_count = 0;
- sljit_s32 float_arg_count = 0;
- sljit_s32 types = 0;
- sljit_s32 data_trandfer = 0;
- static sljit_u8 word_arg_regs[5] = { 0, SLJIT_R3, SLJIT_R1, SLJIT_R2, TMP_REG1 };
-
- SLJIT_ASSERT(reg_map[SLJIT_R3] == 1 && reg_map[SLJIT_R1] == 2 && reg_map[SLJIT_R2] == 8 && reg_map[TMP_REG1] == 9);
- SLJIT_ASSERT(!(src & SLJIT_MEM));
-
- arg_types >>= SLJIT_ARG_SHIFT;
-
- while (arg_types) {
- types = (types << SLJIT_ARG_SHIFT) | (arg_types & SLJIT_ARG_MASK);
-
- switch (arg_types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- case SLJIT_ARG_TYPE_F32:
- arg_count++;
- float_arg_count++;
-
- if (arg_count != float_arg_count)
- data_trandfer = 1;
- break;
- default:
- arg_count++;
- word_arg_count++;
-
- if (arg_count != word_arg_count || arg_count != word_arg_regs[arg_count]) {
- data_trandfer = 1;
-
- if (src == word_arg_regs[arg_count]) {
- EMIT_MOV(compiler, TMP_REG2, 0, src, 0);
- *src_ptr = TMP_REG2;
- }
- }
- break;
- }
-
- arg_types >>= SLJIT_ARG_SHIFT;
- }
-
- if (!data_trandfer)
- return SLJIT_SUCCESS;
-
- while (types) {
- switch (types & SLJIT_ARG_MASK) {
- case SLJIT_ARG_TYPE_F64:
- if (arg_count != float_arg_count)
- FAIL_IF(emit_sse2_load(compiler, 0, arg_count, float_arg_count, 0));
- arg_count--;
- float_arg_count--;
- break;
- case SLJIT_ARG_TYPE_F32:
- if (arg_count != float_arg_count)
- FAIL_IF(emit_sse2_load(compiler, 1, arg_count, float_arg_count, 0));
- arg_count--;
- float_arg_count--;
- break;
- default:
- if (arg_count != word_arg_count || arg_count != word_arg_regs[arg_count])
- EMIT_MOV(compiler, word_arg_regs[arg_count], 0, word_arg_count, 0);
- arg_count--;
- word_arg_count--;
- break;
- }
-
- types >>= SLJIT_ARG_SHIFT;
- }
-
- return SLJIT_SUCCESS;
-}
-
-#endif
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types)
-{
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
-
- compiler->mode32 = 0;
-
- if ((type & 0xff) != SLJIT_CALL_REG_ARG)
- PTR_FAIL_IF(call_with_args(compiler, arg_types, NULL));
-
- if (type & SLJIT_CALL_RETURN) {
- PTR_FAIL_IF(emit_stack_frame_release(compiler, 0));
- type = SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP);
- }
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_jump(compiler, type);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 arg_types,
- sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
-
- compiler->mode32 = 0;
-
- if (src & SLJIT_MEM) {
- ADJUST_LOCAL_OFFSET(src, srcw);
- EMIT_MOV(compiler, TMP_REG2, 0, src, srcw);
- src = TMP_REG2;
- }
-
- if (type & SLJIT_CALL_RETURN) {
- if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
- EMIT_MOV(compiler, TMP_REG2, 0, src, srcw);
- src = TMP_REG2;
- }
-
- FAIL_IF(emit_stack_frame_release(compiler, 0));
- }
-
- if ((type & 0xff) != SLJIT_CALL_REG_ARG)
- FAIL_IF(call_with_args(compiler, arg_types, &src));
-
- if (type & SLJIT_CALL_RETURN)
- type = SLJIT_JUMP;
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_ijump(compiler, type, src, srcw);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
-{
- sljit_u8 *inst;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- if (FAST_IS_REG(dst)) {
- if (reg_map[dst] < 8) {
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
- FAIL_IF(!inst);
- INC_SIZE(1);
- POP_REG(reg_lmap[dst]);
- return SLJIT_SUCCESS;
- }
-
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);
- FAIL_IF(!inst);
- INC_SIZE(2);
- *inst++ = REX_B;
- POP_REG(reg_lmap[dst]);
- return SLJIT_SUCCESS;
- }
-
- /* REX_W is not necessary (src is not immediate). */
- compiler->mode32 = 1;
- inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
- FAIL_IF(!inst);
- *inst++ = POP_rm;
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
-{
- sljit_u8 *inst;
-
- if (FAST_IS_REG(src)) {
- if (reg_map[src] < 8) {
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 1);
- FAIL_IF(!inst);
-
- INC_SIZE(1 + 1);
- PUSH_REG(reg_lmap[src]);
- }
- else {
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + 1);
- FAIL_IF(!inst);
-
- INC_SIZE(2 + 1);
- *inst++ = REX_B;
- PUSH_REG(reg_lmap[src]);
- }
- }
- else {
- /* REX_W is not necessary (src is not immediate). */
- compiler->mode32 = 1;
- inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
- FAIL_IF(!inst);
- *inst++ = GROUP_FF;
- *inst |= PUSH_rm;
-
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
- FAIL_IF(!inst);
- INC_SIZE(1);
- }
-
- RET();
- return SLJIT_SUCCESS;
-}
-
-/* --------------------------------------------------------------------- */
-/* Other operations */
-/* --------------------------------------------------------------------- */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 reg,
- sljit_s32 mem, sljit_sw memw)
-{
- sljit_u8* inst;
- sljit_s32 i, next, reg_idx;
- sljit_u8 regs[2];
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
-
- if (!(reg & REG_PAIR_MASK))
- return sljit_emit_mem_unaligned(compiler, type, reg, mem, memw);
-
- ADJUST_LOCAL_OFFSET(mem, memw);
-
- compiler->mode32 = 0;
-
- if ((mem & REG_MASK) == 0) {
- EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, memw);
-
- mem = SLJIT_MEM1(TMP_REG1);
- memw = 0;
- } else if (!(mem & OFFS_REG_MASK) && ((memw < HALFWORD_MIN) || (memw > HALFWORD_MAX - SSIZE_OF(sw)))) {
- EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, memw);
-
- mem = SLJIT_MEM2(mem & REG_MASK, TMP_REG1);
- memw = 0;
- }
-
- regs[0] = U8(REG_PAIR_FIRST(reg));
- regs[1] = U8(REG_PAIR_SECOND(reg));
-
- next = SSIZE_OF(sw);
-
- if (!(type & SLJIT_MEM_STORE) && (regs[0] == (mem & REG_MASK) || regs[0] == OFFS_REG(mem))) {
- if (regs[1] == (mem & REG_MASK) || regs[1] == OFFS_REG(mem)) {
- /* Base and offset cannot be TMP_REG1. */
- EMIT_MOV(compiler, TMP_REG1, 0, OFFS_REG(mem), 0);
-
- if (regs[1] == OFFS_REG(mem))
- next = -SSIZE_OF(sw);
-
- mem = (mem & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG1);
- } else {
- next = -SSIZE_OF(sw);
-
- if (!(mem & OFFS_REG_MASK))
- memw += SSIZE_OF(sw);
- }
- }
-
- for (i = 0; i < 2; i++) {
- reg_idx = next > 0 ? i : (i ^ 0x1);
- reg = regs[reg_idx];
-
- if ((mem & OFFS_REG_MASK) && (reg_idx == 1)) {
- inst = (sljit_u8*)ensure_buf(compiler, (sljit_uw)(1 + 5));
- FAIL_IF(!inst);
-
- INC_SIZE(5);
-
- inst[0] = U8(REX_W | ((reg_map[reg] >= 8) ? REX_R : 0) | ((reg_map[mem & REG_MASK] >= 8) ? REX_B : 0) | ((reg_map[OFFS_REG(mem)] >= 8) ? REX_X : 0));
- inst[1] = (type & SLJIT_MEM_STORE) ? MOV_rm_r : MOV_r_rm;
- inst[2] = 0x44 | U8(reg_lmap[reg] << 3);
- inst[3] = U8(memw << 6) | U8(reg_lmap[OFFS_REG(mem)] << 3) | reg_lmap[mem & REG_MASK];
- inst[4] = sizeof(sljit_sw);
- } else if (type & SLJIT_MEM_STORE) {
- EMIT_MOV(compiler, mem, memw, reg, 0);
- } else {
- EMIT_MOV(compiler, reg, 0, mem, memw);
- }
-
- if (!(mem & OFFS_REG_MASK))
- memw += next;
- }
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_mov_int(struct sljit_compiler *compiler, sljit_s32 sign,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_u8* inst;
- sljit_s32 dst_r;
-
- compiler->mode32 = 0;
-
- if (src & SLJIT_IMM) {
- if (FAST_IS_REG(dst)) {
- if (sign || ((sljit_uw)srcw <= 0x7fffffff)) {
- inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_s32)srcw, dst, dstw);
- FAIL_IF(!inst);
- *inst = MOV_rm_i32;
- return SLJIT_SUCCESS;
- }
- return emit_load_imm64(compiler, dst, srcw);
- }
- compiler->mode32 = 1;
- inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_s32)srcw, dst, dstw);
- FAIL_IF(!inst);
- *inst = MOV_rm_i32;
- compiler->mode32 = 0;
- return SLJIT_SUCCESS;
- }
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
-
- if ((dst & SLJIT_MEM) && FAST_IS_REG(src))
- dst_r = src;
- else {
- if (sign) {
- inst = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw);
- FAIL_IF(!inst);
- *inst++ = MOVSXD_r_rm;
- } else {
- compiler->mode32 = 1;
- FAIL_IF(emit_mov(compiler, dst_r, 0, src, srcw));
- compiler->mode32 = 0;
- }
- }
-
- if (dst & SLJIT_MEM) {
- compiler->mode32 = 1;
- inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
- FAIL_IF(!inst);
- *inst = MOV_rm_r;
- compiler->mode32 = 0;
- }
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 skip_frames_before_return(struct sljit_compiler *compiler)
-{
- sljit_s32 tmp, size;
-
- /* Don't adjust shadow stack if it isn't enabled. */
- if (!cpu_has_shadow_stack())
- return SLJIT_SUCCESS;
-
- size = compiler->local_size;
- tmp = compiler->scratches;
- if (tmp >= SLJIT_FIRST_SAVED_REG)
- size += (tmp - SLJIT_FIRST_SAVED_REG + 1) * SSIZE_OF(sw);
- tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
- if (SLJIT_S0 >= tmp)
- size += (SLJIT_S0 - tmp + 1) * SSIZE_OF(sw);
-
- return adjust_shadow_stack(compiler, SLJIT_MEM1(SLJIT_SP), size);
-}
diff --git a/contrib/libs/pcre2/src/sljit/sljitNativeX86_common.c b/contrib/libs/pcre2/src/sljit/sljitNativeX86_common.c
deleted file mode 100644
index 651942be80..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitNativeX86_common.c
+++ /dev/null
@@ -1,3422 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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.
- */
-
-SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
-{
- return "x86" SLJIT_CPUINFO;
-}
-
-/*
- 32b register indexes:
- 0 - EAX
- 1 - ECX
- 2 - EDX
- 3 - EBX
- 4 - ESP
- 5 - EBP
- 6 - ESI
- 7 - EDI
-*/
-
-/*
- 64b register indexes:
- 0 - RAX
- 1 - RCX
- 2 - RDX
- 3 - RBX
- 4 - RSP
- 5 - RBP
- 6 - RSI
- 7 - RDI
- 8 - R8 - From now on REX prefix is required
- 9 - R9
- 10 - R10
- 11 - R11
- 12 - R12
- 13 - R13
- 14 - R14
- 15 - R15
-*/
-
-#define TMP_FREG (0)
-
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-
-/* Last register + 1. */
-#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
-
-static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 3] = {
- 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 7, 6, 3, 4, 5
-};
-
-#define CHECK_EXTRA_REGS(p, w, do) \
- if (p >= SLJIT_R3 && p <= SLJIT_S3) { \
- w = (2 * SSIZE_OF(sw)) + ((p) - SLJIT_R3) * SSIZE_OF(sw); \
- p = SLJIT_MEM1(SLJIT_SP); \
- do; \
- }
-
-#else /* SLJIT_CONFIG_X86_32 */
-
-/* Last register + 1. */
-#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
-#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
-
-/* Note: r12 & 0x7 == 0b100, which decoded as SIB byte present
- Note: avoid to use r12 and r13 for memory addessing
- therefore r12 is better to be a higher saved register. */
-#ifndef _WIN64
-/* Args: rdi(=7), rsi(=6), rdx(=2), rcx(=1), r8, r9. Scratches: rax(=0), r10, r11 */
-static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 4] = {
- 0, 0, 6, 7, 1, 8, 11, 10, 12, 5, 13, 14, 15, 3, 4, 2, 9
-};
-/* low-map. reg_map & 0x7. */
-static const sljit_u8 reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 4] = {
- 0, 0, 6, 7, 1, 0, 3, 2, 4, 5, 5, 6, 7, 3, 4, 2, 1
-};
-#else
-/* Args: rcx(=1), rdx(=2), r8, r9. Scratches: rax(=0), r10, r11 */
-static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 4] = {
- 0, 0, 2, 8, 1, 11, 12, 5, 13, 14, 15, 7, 6, 3, 4, 9, 10
-};
-/* low-map. reg_map & 0x7. */
-static const sljit_u8 reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 4] = {
- 0, 0, 2, 0, 1, 3, 4, 5, 5, 6, 7, 7, 6, 3, 4, 1, 2
-};
-#endif
-
-/* Args: xmm0-xmm3 */
-static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = {
- 4, 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
-};
-/* low-map. freg_map & 0x7. */
-static const sljit_u8 freg_lmap[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = {
- 4, 0, 1, 2, 3, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7
-};
-
-#define REX_W 0x48
-#define REX_R 0x44
-#define REX_X 0x42
-#define REX_B 0x41
-#define REX 0x40
-
-#ifndef _WIN64
-#define HALFWORD_MAX 0x7fffffffl
-#define HALFWORD_MIN -0x80000000l
-#else
-#define HALFWORD_MAX 0x7fffffffll
-#define HALFWORD_MIN -0x80000000ll
-#endif
-
-#define IS_HALFWORD(x) ((x) <= HALFWORD_MAX && (x) >= HALFWORD_MIN)
-#define NOT_HALFWORD(x) ((x) > HALFWORD_MAX || (x) < HALFWORD_MIN)
-
-#define CHECK_EXTRA_REGS(p, w, do)
-
-#endif /* SLJIT_CONFIG_X86_32 */
-
-#define U8(v) ((sljit_u8)(v))
-
-
-/* Size flags for emit_x86_instruction: */
-#define EX86_BIN_INS 0x0010
-#define EX86_SHIFT_INS 0x0020
-#define EX86_REX 0x0040
-#define EX86_NO_REXW 0x0080
-#define EX86_BYTE_ARG 0x0100
-#define EX86_HALF_ARG 0x0200
-#define EX86_PREF_66 0x0400
-#define EX86_PREF_F2 0x0800
-#define EX86_PREF_F3 0x1000
-#define EX86_SSE2_OP1 0x2000
-#define EX86_SSE2_OP2 0x4000
-#define EX86_SSE2 (EX86_SSE2_OP1 | EX86_SSE2_OP2)
-
-/* --------------------------------------------------------------------- */
-/* Instrucion forms */
-/* --------------------------------------------------------------------- */
-
-#define ADD (/* BINARY */ 0 << 3)
-#define ADD_EAX_i32 0x05
-#define ADD_r_rm 0x03
-#define ADD_rm_r 0x01
-#define ADDSD_x_xm 0x58
-#define ADC (/* BINARY */ 2 << 3)
-#define ADC_EAX_i32 0x15
-#define ADC_r_rm 0x13
-#define ADC_rm_r 0x11
-#define AND (/* BINARY */ 4 << 3)
-#define AND_EAX_i32 0x25
-#define AND_r_rm 0x23
-#define AND_rm_r 0x21
-#define ANDPD_x_xm 0x54
-#define BSR_r_rm (/* GROUP_0F */ 0xbd)
-#define BSF_r_rm (/* GROUP_0F */ 0xbc)
-#define CALL_i32 0xe8
-#define CALL_rm (/* GROUP_FF */ 2 << 3)
-#define CDQ 0x99
-#define CMOVE_r_rm (/* GROUP_0F */ 0x44)
-#define CMP (/* BINARY */ 7 << 3)
-#define CMP_EAX_i32 0x3d
-#define CMP_r_rm 0x3b
-#define CMP_rm_r 0x39
-#define CVTPD2PS_x_xm 0x5a
-#define CVTSI2SD_x_rm 0x2a
-#define CVTTSD2SI_r_xm 0x2c
-#define DIV (/* GROUP_F7 */ 6 << 3)
-#define DIVSD_x_xm 0x5e
-#define FLDS 0xd9
-#define FLDL 0xdd
-#define FSTPS 0xd9
-#define FSTPD 0xdd
-#define INT3 0xcc
-#define IDIV (/* GROUP_F7 */ 7 << 3)
-#define IMUL (/* GROUP_F7 */ 5 << 3)
-#define IMUL_r_rm (/* GROUP_0F */ 0xaf)
-#define IMUL_r_rm_i8 0x6b
-#define IMUL_r_rm_i32 0x69
-#define JE_i8 0x74
-#define JNE_i8 0x75
-#define JMP_i8 0xeb
-#define JMP_i32 0xe9
-#define JMP_rm (/* GROUP_FF */ 4 << 3)
-#define LEA_r_m 0x8d
-#define LOOP_i8 0xe2
-#define LZCNT_r_rm (/* GROUP_F3 */ /* GROUP_0F */ 0xbd)
-#define MOV_r_rm 0x8b
-#define MOV_r_i32 0xb8
-#define MOV_rm_r 0x89
-#define MOV_rm_i32 0xc7
-#define MOV_rm8_i8 0xc6
-#define MOV_rm8_r8 0x88
-#define MOVAPS_x_xm 0x28
-#define MOVAPS_xm_x 0x29
-#define MOVSD_x_xm 0x10
-#define MOVSD_xm_x 0x11
-#define MOVSXD_r_rm 0x63
-#define MOVSX_r_rm8 (/* GROUP_0F */ 0xbe)
-#define MOVSX_r_rm16 (/* GROUP_0F */ 0xbf)
-#define MOVZX_r_rm8 (/* GROUP_0F */ 0xb6)
-#define MOVZX_r_rm16 (/* GROUP_0F */ 0xb7)
-#define MUL (/* GROUP_F7 */ 4 << 3)
-#define MULSD_x_xm 0x59
-#define NEG_rm (/* GROUP_F7 */ 3 << 3)
-#define NOP 0x90
-#define NOT_rm (/* GROUP_F7 */ 2 << 3)
-#define OR (/* BINARY */ 1 << 3)
-#define OR_r_rm 0x0b
-#define OR_EAX_i32 0x0d
-#define OR_rm_r 0x09
-#define OR_rm8_r8 0x08
-#define POP_r 0x58
-#define POP_rm 0x8f
-#define POPF 0x9d
-#define PREFETCH 0x18
-#define PUSH_i32 0x68
-#define PUSH_r 0x50
-#define PUSH_rm (/* GROUP_FF */ 6 << 3)
-#define PUSHF 0x9c
-#define ROL (/* SHIFT */ 0 << 3)
-#define ROR (/* SHIFT */ 1 << 3)
-#define RET_near 0xc3
-#define RET_i16 0xc2
-#define SBB (/* BINARY */ 3 << 3)
-#define SBB_EAX_i32 0x1d
-#define SBB_r_rm 0x1b
-#define SBB_rm_r 0x19
-#define SAR (/* SHIFT */ 7 << 3)
-#define SHL (/* SHIFT */ 4 << 3)
-#define SHLD (/* GROUP_0F */ 0xa5)
-#define SHRD (/* GROUP_0F */ 0xad)
-#define SHR (/* SHIFT */ 5 << 3)
-#define SUB (/* BINARY */ 5 << 3)
-#define SUB_EAX_i32 0x2d
-#define SUB_r_rm 0x2b
-#define SUB_rm_r 0x29
-#define SUBSD_x_xm 0x5c
-#define TEST_EAX_i32 0xa9
-#define TEST_rm_r 0x85
-#define TZCNT_r_rm (/* GROUP_F3 */ /* GROUP_0F */ 0xbc)
-#define UCOMISD_x_xm 0x2e
-#define UNPCKLPD_x_xm 0x14
-#define XCHG_EAX_r 0x90
-#define XCHG_r_rm 0x87
-#define XOR (/* BINARY */ 6 << 3)
-#define XOR_EAX_i32 0x35
-#define XOR_r_rm 0x33
-#define XOR_rm_r 0x31
-#define XORPD_x_xm 0x57
-
-#define GROUP_0F 0x0f
-#define GROUP_F3 0xf3
-#define GROUP_F7 0xf7
-#define GROUP_FF 0xff
-#define GROUP_BINARY_81 0x81
-#define GROUP_BINARY_83 0x83
-#define GROUP_SHIFT_1 0xd1
-#define GROUP_SHIFT_N 0xc1
-#define GROUP_SHIFT_CL 0xd3
-
-#define MOD_REG 0xc0
-#define MOD_DISP8 0x40
-
-#define INC_SIZE(s) (*inst++ = U8(s), compiler->size += (s))
-
-#define PUSH_REG(r) (*inst++ = U8(PUSH_r + (r)))
-#define POP_REG(r) (*inst++ = U8(POP_r + (r)))
-#define RET() (*inst++ = RET_near)
-#define RET_I16(n) (*inst++ = RET_i16, *inst++ = U8(n), *inst++ = 0)
-
-/* Multithreading does not affect these static variables, since they store
- built-in CPU features. Therefore they can be overwritten by different threads
- if they detect the CPU features in the same time. */
-#define CPU_FEATURE_DETECTED 0x001
-#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
-#define CPU_FEATURE_SSE2 0x002
-#endif
-#define CPU_FEATURE_LZCNT 0x004
-#define CPU_FEATURE_TZCNT 0x008
-#define CPU_FEATURE_CMOV 0x010
-
-static sljit_u32 cpu_feature_list = 0;
-
-#ifdef _WIN32_WCE
-#include <cmnintrin.h>
-#elif defined(_MSC_VER) && _MSC_VER >= 1400
-#include <intrin.h>
-#endif
-
-/******************************************************/
-/* Unaligned-store functions */
-/******************************************************/
-
-static SLJIT_INLINE void sljit_unaligned_store_s16(void *addr, sljit_s16 value)
-{
- SLJIT_MEMCPY(addr, &value, sizeof(value));
-}
-
-static SLJIT_INLINE void sljit_unaligned_store_s32(void *addr, sljit_s32 value)
-{
- SLJIT_MEMCPY(addr, &value, sizeof(value));
-}
-
-static SLJIT_INLINE void sljit_unaligned_store_sw(void *addr, sljit_sw value)
-{
- SLJIT_MEMCPY(addr, &value, sizeof(value));
-}
-
-/******************************************************/
-/* Utility functions */
-/******************************************************/
-
-static void get_cpu_features(void)
-{
- sljit_u32 feature_list = CPU_FEATURE_DETECTED;
- sljit_u32 value;
-
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-
- int CPUInfo[4];
-
- __cpuid(CPUInfo, 0);
- if (CPUInfo[0] >= 7) {
- __cpuidex(CPUInfo, 7, 0);
- if (CPUInfo[1] & 0x8)
- feature_list |= CPU_FEATURE_TZCNT;
- }
-
- __cpuid(CPUInfo, (int)0x80000001);
- if (CPUInfo[2] & 0x20)
- feature_list |= CPU_FEATURE_LZCNT;
-
- __cpuid(CPUInfo, 1);
- value = (sljit_u32)CPUInfo[3];
-
-#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C)
-
- /* AT&T syntax. */
- __asm__ (
- "movl $0x0, %%eax\n"
- "lzcnt %%eax, %%eax\n"
- "setnz %%al\n"
- "movl %%eax, %0\n"
- : "=g" (value)
- :
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- : "eax"
-#else
- : "rax"
-#endif
- );
-
- if (value & 0x1)
- feature_list |= CPU_FEATURE_LZCNT;
-
- __asm__ (
- "movl $0x0, %%eax\n"
- "tzcnt %%eax, %%eax\n"
- "setnz %%al\n"
- "movl %%eax, %0\n"
- : "=g" (value)
- :
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- : "eax"
-#else
- : "rax"
-#endif
- );
-
- if (value & 0x1)
- feature_list |= CPU_FEATURE_TZCNT;
-
- __asm__ (
- "movl $0x1, %%eax\n"
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- /* On x86-32, there is no red zone, so this
- should work (no need for a local variable). */
- "push %%ebx\n"
-#endif
- "cpuid\n"
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- "pop %%ebx\n"
-#endif
- "movl %%edx, %0\n"
- : "=g" (value)
- :
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- : "%eax", "%ecx", "%edx"
-#else
- : "%rax", "%rbx", "%rcx", "%rdx"
-#endif
- );
-
-#else /* _MSC_VER && _MSC_VER >= 1400 */
-
- /* Intel syntax. */
- __asm {
- mov eax, 0
- lzcnt eax, eax
- setnz al
- mov value, eax
- }
-
- if (value & 0x1)
- feature_list |= CPU_FEATURE_LZCNT;
-
- __asm {
- mov eax, 0
- tzcnt eax, eax
- setnz al
- mov value, eax
- }
-
- if (value & 0x1)
- feature_list |= CPU_FEATURE_TZCNT;
-
- __asm {
- mov eax, 1
- cpuid
- mov value, edx
- }
-
-#endif /* _MSC_VER && _MSC_VER >= 1400 */
-
-#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
- if (value & 0x4000000)
- feature_list |= CPU_FEATURE_SSE2;
-#endif
- if (value & 0x8000)
- feature_list |= CPU_FEATURE_CMOV;
-
- cpu_feature_list = feature_list;
-}
-
-static sljit_u8 get_jump_code(sljit_uw type)
-{
- switch (type) {
- case SLJIT_EQUAL:
- case SLJIT_F_EQUAL:
- case SLJIT_UNORDERED_OR_EQUAL:
- case SLJIT_ORDERED_EQUAL: /* Not supported. */
- return 0x84 /* je */;
-
- case SLJIT_NOT_EQUAL:
- case SLJIT_F_NOT_EQUAL:
- case SLJIT_ORDERED_NOT_EQUAL:
- case SLJIT_UNORDERED_OR_NOT_EQUAL: /* Not supported. */
- return 0x85 /* jne */;
-
- case SLJIT_LESS:
- case SLJIT_CARRY:
- case SLJIT_F_LESS:
- case SLJIT_UNORDERED_OR_LESS:
- case SLJIT_UNORDERED_OR_GREATER:
- return 0x82 /* jc */;
-
- case SLJIT_GREATER_EQUAL:
- case SLJIT_NOT_CARRY:
- case SLJIT_F_GREATER_EQUAL:
- case SLJIT_ORDERED_GREATER_EQUAL:
- case SLJIT_ORDERED_LESS_EQUAL:
- return 0x83 /* jae */;
-
- case SLJIT_GREATER:
- case SLJIT_F_GREATER:
- case SLJIT_ORDERED_LESS:
- case SLJIT_ORDERED_GREATER:
- return 0x87 /* jnbe */;
-
- case SLJIT_LESS_EQUAL:
- case SLJIT_F_LESS_EQUAL:
- case SLJIT_UNORDERED_OR_GREATER_EQUAL:
- case SLJIT_UNORDERED_OR_LESS_EQUAL:
- return 0x86 /* jbe */;
-
- case SLJIT_SIG_LESS:
- return 0x8c /* jl */;
-
- case SLJIT_SIG_GREATER_EQUAL:
- return 0x8d /* jnl */;
-
- case SLJIT_SIG_GREATER:
- return 0x8f /* jnle */;
-
- case SLJIT_SIG_LESS_EQUAL:
- return 0x8e /* jle */;
-
- case SLJIT_OVERFLOW:
- return 0x80 /* jo */;
-
- case SLJIT_NOT_OVERFLOW:
- return 0x81 /* jno */;
-
- case SLJIT_UNORDERED:
- return 0x8a /* jp */;
-
- case SLJIT_ORDERED:
- return 0x8b /* jpo */;
- }
- return 0;
-}
-
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_sw executable_offset);
-#else
-static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr);
-static sljit_u8* generate_put_label_code(struct sljit_put_label *put_label, sljit_u8 *code_ptr, sljit_uw max_label);
-#endif
-
-static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_sw executable_offset)
-{
- sljit_uw type = jump->flags >> TYPE_SHIFT;
- sljit_s32 short_jump;
- sljit_uw label_addr;
-
- if (jump->flags & JUMP_LABEL)
- label_addr = (sljit_uw)(code + jump->u.label->size);
- else
- label_addr = jump->u.target - (sljit_uw)executable_offset;
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if ((sljit_sw)(label_addr - (jump->addr + 1)) > HALFWORD_MAX || (sljit_sw)(label_addr - (jump->addr + 1)) < HALFWORD_MIN)
- return generate_far_jump_code(jump, code_ptr);
-#endif
-
- short_jump = (sljit_sw)(label_addr - (jump->addr + 2)) >= -128 && (sljit_sw)(label_addr - (jump->addr + 2)) <= 127;
-
- if (type == SLJIT_JUMP) {
- if (short_jump)
- *code_ptr++ = JMP_i8;
- else
- *code_ptr++ = JMP_i32;
- jump->addr++;
- }
- else if (type >= SLJIT_FAST_CALL) {
- short_jump = 0;
- *code_ptr++ = CALL_i32;
- jump->addr++;
- }
- else if (short_jump) {
- *code_ptr++ = U8(get_jump_code(type) - 0x10);
- jump->addr++;
- }
- else {
- *code_ptr++ = GROUP_0F;
- *code_ptr++ = get_jump_code(type);
- jump->addr += 2;
- }
-
- if (short_jump) {
- jump->flags |= PATCH_MB;
- code_ptr += sizeof(sljit_s8);
- } else {
- jump->flags |= PATCH_MW;
- code_ptr += sizeof(sljit_s32);
- }
-
- return code_ptr;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
-{
- struct sljit_memory_fragment *buf;
- sljit_u8 *code;
- sljit_u8 *code_ptr;
- sljit_u8 *buf_ptr;
- sljit_u8 *buf_end;
- sljit_u8 len;
- sljit_sw executable_offset;
- sljit_uw jump_addr;
-
- struct sljit_label *label;
- struct sljit_jump *jump;
- struct sljit_const *const_;
- struct sljit_put_label *put_label;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_generate_code(compiler));
- reverse_buf(compiler);
-
- /* Second code generation pass. */
- code = (sljit_u8*)SLJIT_MALLOC_EXEC(compiler->size, compiler->exec_allocator_data);
- PTR_FAIL_WITH_EXEC_IF(code);
- buf = compiler->buf;
-
- code_ptr = code;
- label = compiler->labels;
- jump = compiler->jumps;
- const_ = compiler->consts;
- put_label = compiler->put_labels;
- executable_offset = SLJIT_EXEC_OFFSET(code);
-
- do {
- buf_ptr = buf->memory;
- buf_end = buf_ptr + buf->used_size;
- do {
- len = *buf_ptr++;
- if (len > 0) {
- /* The code is already generated. */
- SLJIT_MEMCPY(code_ptr, buf_ptr, len);
- code_ptr += len;
- buf_ptr += len;
- }
- else {
- switch (*buf_ptr) {
- case 0:
- label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
- label->size = (sljit_uw)(code_ptr - code);
- label = label->next;
- break;
- case 1:
- jump->addr = (sljit_uw)code_ptr;
- if (!(jump->flags & SLJIT_REWRITABLE_JUMP))
- code_ptr = generate_near_jump_code(jump, code_ptr, code, executable_offset);
- else {
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- code_ptr = generate_far_jump_code(jump, code_ptr, executable_offset);
-#else
- code_ptr = generate_far_jump_code(jump, code_ptr);
-#endif
- }
- jump = jump->next;
- break;
- case 2:
- const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_sw);
- const_ = const_->next;
- break;
- default:
- SLJIT_ASSERT(*buf_ptr == 3);
- SLJIT_ASSERT(put_label->label);
- put_label->addr = (sljit_uw)code_ptr;
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- code_ptr = generate_put_label_code(put_label, code_ptr, (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size);
-#endif
- put_label = put_label->next;
- break;
- }
- buf_ptr++;
- }
- } while (buf_ptr < buf_end);
- SLJIT_ASSERT(buf_ptr == buf_end);
- buf = buf->next;
- } while (buf);
-
- SLJIT_ASSERT(!label);
- SLJIT_ASSERT(!jump);
- SLJIT_ASSERT(!const_);
- SLJIT_ASSERT(!put_label);
- SLJIT_ASSERT(code_ptr <= code + compiler->size);
-
- jump = compiler->jumps;
- while (jump) {
- if (jump->flags & (PATCH_MB | PATCH_MW)) {
- if (jump->flags & JUMP_LABEL)
- jump_addr = jump->u.label->addr;
- else
- jump_addr = jump->u.target;
-
- jump_addr -= jump->addr + (sljit_uw)executable_offset;
-
- if (jump->flags & PATCH_MB) {
- jump_addr -= sizeof(sljit_s8);
- SLJIT_ASSERT((sljit_sw)jump_addr >= -128 && (sljit_sw)jump_addr <= 127);
- *(sljit_u8*)jump->addr = U8(jump_addr);
- } else {
- jump_addr -= sizeof(sljit_s32);
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- sljit_unaligned_store_sw((void*)jump->addr, (sljit_sw)jump_addr);
-#else
- SLJIT_ASSERT((sljit_sw)jump_addr >= HALFWORD_MIN && (sljit_sw)jump_addr <= HALFWORD_MAX);
- sljit_unaligned_store_s32((void*)jump->addr, (sljit_s32)jump_addr);
-#endif
- }
- }
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- else if (jump->flags & PATCH_MD) {
- SLJIT_ASSERT(jump->flags & JUMP_LABEL);
- sljit_unaligned_store_sw((void*)jump->addr, (sljit_sw)jump->u.label->addr);
- }
-#endif
-
- jump = jump->next;
- }
-
- put_label = compiler->put_labels;
- while (put_label) {
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- sljit_unaligned_store_sw((void*)(put_label->addr - sizeof(sljit_sw)), (sljit_sw)put_label->label->addr);
-#else
- if (put_label->flags & PATCH_MD) {
- SLJIT_ASSERT(put_label->label->addr > HALFWORD_MAX);
- sljit_unaligned_store_sw((void*)(put_label->addr - sizeof(sljit_sw)), (sljit_sw)put_label->label->addr);
- }
- else {
- SLJIT_ASSERT(put_label->label->addr <= HALFWORD_MAX);
- sljit_unaligned_store_s32((void*)(put_label->addr - sizeof(sljit_s32)), (sljit_s32)put_label->label->addr);
- }
-#endif
-
- put_label = put_label->next;
- }
-
- compiler->error = SLJIT_ERR_COMPILED;
- compiler->executable_offset = executable_offset;
- compiler->executable_size = (sljit_uw)(code_ptr - code);
-
- code = (sljit_u8*)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
-
- SLJIT_UPDATE_WX_FLAGS(code, (sljit_u8*)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset), 1);
- return (void*)code;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
-{
- switch (feature_type) {
- case SLJIT_HAS_FPU:
-#ifdef SLJIT_IS_FPU_AVAILABLE
- return SLJIT_IS_FPU_AVAILABLE;
-#elif (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
- if (cpu_feature_list == 0)
- get_cpu_features();
- return (cpu_feature_list & CPU_FEATURE_SSE2) != 0;
-#else /* SLJIT_DETECT_SSE2 */
- return 1;
-#endif /* SLJIT_DETECT_SSE2 */
-
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- case SLJIT_HAS_VIRTUAL_REGISTERS:
- return 1;
-#endif /* SLJIT_CONFIG_X86_32 */
-
- case SLJIT_HAS_CLZ:
- if (cpu_feature_list == 0)
- get_cpu_features();
-
- return (cpu_feature_list & CPU_FEATURE_LZCNT) ? 1 : 2;
-
- case SLJIT_HAS_CTZ:
- if (cpu_feature_list == 0)
- get_cpu_features();
-
- return (cpu_feature_list & CPU_FEATURE_TZCNT) ? 1 : 2;
-
- case SLJIT_HAS_CMOV:
- if (cpu_feature_list == 0)
- get_cpu_features();
- return (cpu_feature_list & CPU_FEATURE_CMOV) != 0;
-
- case SLJIT_HAS_ROT:
- case SLJIT_HAS_PREFETCH:
- return 1;
-
- case SLJIT_HAS_SSE2:
-#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
- if (cpu_feature_list == 0)
- get_cpu_features();
- return (cpu_feature_list & CPU_FEATURE_SSE2) != 0;
-#else /* !SLJIT_DETECT_SSE2 */
- return 1;
-#endif /* SLJIT_DETECT_SSE2 */
-
- default:
- return 0;
- }
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)
-{
- if (type < SLJIT_UNORDERED || type > SLJIT_ORDERED_LESS_EQUAL)
- return 0;
-
- switch (type) {
- case SLJIT_ORDERED_EQUAL:
- case SLJIT_UNORDERED_OR_NOT_EQUAL:
- return 0;
- }
-
- return 1;
-}
-
-/* --------------------------------------------------------------------- */
-/* Operators */
-/* --------------------------------------------------------------------- */
-
-#define BINARY_OPCODE(opcode) (((opcode ## _EAX_i32) << 24) | ((opcode ## _r_rm) << 16) | ((opcode ## _rm_r) << 8) | (opcode))
-
-#define BINARY_IMM32(op_imm, immw, arg, argw) \
- do { \
- inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \
- FAIL_IF(!inst); \
- *(inst + 1) |= (op_imm); \
- } while (0)
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-
-#define BINARY_IMM(op_imm, op_mr, immw, arg, argw) \
- do { \
- if (IS_HALFWORD(immw) || compiler->mode32) { \
- BINARY_IMM32(op_imm, immw, arg, argw); \
- } \
- else { \
- FAIL_IF(emit_load_imm64(compiler, (arg == TMP_REG1) ? TMP_REG2 : TMP_REG1, immw)); \
- inst = emit_x86_instruction(compiler, 1, (arg == TMP_REG1) ? TMP_REG2 : TMP_REG1, 0, arg, argw); \
- FAIL_IF(!inst); \
- *inst = (op_mr); \
- } \
- } while (0)
-
-#define BINARY_EAX_IMM(op_eax_imm, immw) \
- FAIL_IF(emit_do_imm32(compiler, (!compiler->mode32) ? REX_W : 0, (op_eax_imm), immw))
-
-#else /* !SLJIT_CONFIG_X86_64 */
-
-#define BINARY_IMM(op_imm, op_mr, immw, arg, argw) \
- BINARY_IMM32(op_imm, immw, arg, argw)
-
-#define BINARY_EAX_IMM(op_eax_imm, immw) \
- FAIL_IF(emit_do_imm(compiler, (op_eax_imm), immw))
-
-#endif /* SLJIT_CONFIG_X86_64 */
-
-static sljit_s32 emit_mov(struct sljit_compiler *compiler,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw);
-
-#define EMIT_MOV(compiler, dst, dstw, src, srcw) \
- FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));
-
-static SLJIT_INLINE sljit_s32 emit_sse2_store(struct sljit_compiler *compiler,
- sljit_s32 single, sljit_s32 dst, sljit_sw dstw, sljit_s32 src);
-
-static SLJIT_INLINE sljit_s32 emit_sse2_load(struct sljit_compiler *compiler,
- sljit_s32 single, sljit_s32 dst, sljit_s32 src, sljit_sw srcw);
-
-static sljit_s32 emit_cmp_binary(struct sljit_compiler *compiler,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w);
-
-static SLJIT_INLINE sljit_s32 emit_endbranch(struct sljit_compiler *compiler)
-{
-#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET)
- /* Emit endbr32/endbr64 when CET is enabled. */
- sljit_u8 *inst;
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
- FAIL_IF(!inst);
- INC_SIZE(4);
- *inst++ = 0xf3;
- *inst++ = 0x0f;
- *inst++ = 0x1e;
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- *inst = 0xfb;
-#else
- *inst = 0xfa;
-#endif
-#else /* !SLJIT_CONFIG_X86_CET */
- SLJIT_UNUSED_ARG(compiler);
-#endif /* SLJIT_CONFIG_X86_CET */
- return SLJIT_SUCCESS;
-}
-
-#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined (__SHSTK__)
-
-static SLJIT_INLINE sljit_s32 emit_rdssp(struct sljit_compiler *compiler, sljit_s32 reg)
-{
- sljit_u8 *inst;
- sljit_s32 size;
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- size = 5;
-#else
- size = 4;
-#endif
-
- inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
- FAIL_IF(!inst);
- INC_SIZE(size);
- *inst++ = 0xf3;
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- *inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : REX_B);
-#endif
- *inst++ = 0x0f;
- *inst++ = 0x1e;
- *inst = (0x3 << 6) | (0x1 << 3) | (reg_map[reg] & 0x7);
- return SLJIT_SUCCESS;
-}
-
-static SLJIT_INLINE sljit_s32 emit_incssp(struct sljit_compiler *compiler, sljit_s32 reg)
-{
- sljit_u8 *inst;
- sljit_s32 size;
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- size = 5;
-#else
- size = 4;
-#endif
-
- inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
- FAIL_IF(!inst);
- INC_SIZE(size);
- *inst++ = 0xf3;
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- *inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : REX_B);
-#endif
- *inst++ = 0x0f;
- *inst++ = 0xae;
- *inst = (0x3 << 6) | (0x5 << 3) | (reg_map[reg] & 0x7);
- return SLJIT_SUCCESS;
-}
-
-#endif /* SLJIT_CONFIG_X86_CET && __SHSTK__ */
-
-static SLJIT_INLINE sljit_s32 cpu_has_shadow_stack(void)
-{
-#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined (__SHSTK__)
- return _get_ssp() != 0;
-#else /* !SLJIT_CONFIG_X86_CET || !__SHSTK__ */
- return 0;
-#endif /* SLJIT_CONFIG_X86_CET && __SHSTK__ */
-}
-
-static SLJIT_INLINE sljit_s32 adjust_shadow_stack(struct sljit_compiler *compiler,
- sljit_s32 src, sljit_sw srcw)
-{
-#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined (__SHSTK__)
- sljit_u8 *inst, *jz_after_cmp_inst;
- sljit_uw size_jz_after_cmp_inst;
-
- sljit_uw size_before_rdssp_inst = compiler->size;
-
- /* Generate "RDSSP TMP_REG1". */
- FAIL_IF(emit_rdssp(compiler, TMP_REG1));
-
- /* Load return address on shadow stack into TMP_REG1. */
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- SLJIT_ASSERT(reg_map[TMP_REG1] == 5);
-
- /* Hand code unsupported "mov 0x0(%ebp),%ebp". */
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 3);
- FAIL_IF(!inst);
- INC_SIZE(3);
- *inst++ = 0x8b;
- *inst++ = 0x6d;
- *inst = 0;
-#else /* !SLJIT_CONFIG_X86_32 */
- EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(TMP_REG1), 0);
-#endif /* SLJIT_CONFIG_X86_32 */
-
- /* Compare return address against TMP_REG1. */
- FAIL_IF(emit_cmp_binary (compiler, TMP_REG1, 0, src, srcw));
-
- /* Generate JZ to skip shadow stack ajdustment when shadow
- stack matches normal stack. */
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);
- FAIL_IF(!inst);
- INC_SIZE(2);
- *inst++ = get_jump_code(SLJIT_EQUAL) - 0x10;
- size_jz_after_cmp_inst = compiler->size;
- jz_after_cmp_inst = inst;
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- /* REX_W is not necessary. */
- compiler->mode32 = 1;
-#endif
- /* Load 1 into TMP_REG1. */
- EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, 1);
-
- /* Generate "INCSSP TMP_REG1". */
- FAIL_IF(emit_incssp(compiler, TMP_REG1));
-
- /* Jump back to "RDSSP TMP_REG1" to check shadow stack again. */
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);
- FAIL_IF(!inst);
- INC_SIZE(2);
- *inst++ = JMP_i8;
- *inst = size_before_rdssp_inst - compiler->size;
-
- *jz_after_cmp_inst = compiler->size - size_jz_after_cmp_inst;
-#else /* !SLJIT_CONFIG_X86_CET || !__SHSTK__ */
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(src);
- SLJIT_UNUSED_ARG(srcw);
-#endif /* SLJIT_CONFIG_X86_CET && __SHSTK__ */
- return SLJIT_SUCCESS;
-}
-
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-#include "sljitNativeX86_32.c"
-#else
-#include "sljitNativeX86_64.c"
-#endif
-
-static sljit_s32 emit_mov(struct sljit_compiler *compiler,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_u8* inst;
-
- if (FAST_IS_REG(src)) {
- inst = emit_x86_instruction(compiler, 1, src, 0, dst, dstw);
- FAIL_IF(!inst);
- *inst = MOV_rm_r;
- return SLJIT_SUCCESS;
- }
- if (src & SLJIT_IMM) {
- if (FAST_IS_REG(dst)) {
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- return emit_do_imm(compiler, MOV_r_i32 | reg_map[dst], srcw);
-#else
- if (!compiler->mode32) {
- if (NOT_HALFWORD(srcw))
- return emit_load_imm64(compiler, dst, srcw);
- }
- else
- return emit_do_imm32(compiler, (reg_map[dst] >= 8) ? REX_B : 0, U8(MOV_r_i32 | reg_lmap[dst]), srcw);
-#endif
- }
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if (!compiler->mode32 && NOT_HALFWORD(srcw)) {
- /* Immediate to memory move. Only SLJIT_MOV operation copies
- an immediate directly into memory so TMP_REG1 can be used. */
- FAIL_IF(emit_load_imm64(compiler, TMP_REG1, srcw));
- inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw);
- FAIL_IF(!inst);
- *inst = MOV_rm_r;
- return SLJIT_SUCCESS;
- }
-#endif
- inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, dstw);
- FAIL_IF(!inst);
- *inst = MOV_rm_i32;
- return SLJIT_SUCCESS;
- }
- if (FAST_IS_REG(dst)) {
- inst = emit_x86_instruction(compiler, 1, dst, 0, src, srcw);
- FAIL_IF(!inst);
- *inst = MOV_r_rm;
- return SLJIT_SUCCESS;
- }
-
- /* Memory to memory move. Only SLJIT_MOV operation copies
- data from memory to memory so TMP_REG1 can be used. */
- inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src, srcw);
- FAIL_IF(!inst);
- *inst = MOV_r_rm;
- inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw);
- FAIL_IF(!inst);
- *inst = MOV_rm_r;
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
-{
- sljit_u8 *inst;
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- sljit_uw size;
-#endif
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op0(compiler, op));
-
- switch (GET_OPCODE(op)) {
- case SLJIT_BREAKPOINT:
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
- FAIL_IF(!inst);
- INC_SIZE(1);
- *inst = INT3;
- break;
- case SLJIT_NOP:
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
- FAIL_IF(!inst);
- INC_SIZE(1);
- *inst = NOP;
- break;
- case SLJIT_LMUL_UW:
- case SLJIT_LMUL_SW:
- case SLJIT_DIVMOD_UW:
- case SLJIT_DIVMOD_SW:
- case SLJIT_DIV_UW:
- case SLJIT_DIV_SW:
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-#ifdef _WIN64
- SLJIT_ASSERT(
- reg_map[SLJIT_R0] == 0
- && reg_map[SLJIT_R1] == 2
- && reg_map[TMP_REG1] > 7);
-#else
- SLJIT_ASSERT(
- reg_map[SLJIT_R0] == 0
- && reg_map[SLJIT_R1] < 7
- && reg_map[TMP_REG1] == 2);
-#endif
- compiler->mode32 = op & SLJIT_32;
-#endif
- SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
-
- op = GET_OPCODE(op);
- if ((op | 0x2) == SLJIT_DIV_UW) {
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)
- EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0);
- inst = emit_x86_instruction(compiler, 1, SLJIT_R1, 0, SLJIT_R1, 0);
-#else
- inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG1, 0);
-#endif
- FAIL_IF(!inst);
- *inst = XOR_r_rm;
- }
-
- if ((op | 0x2) == SLJIT_DIV_SW) {
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)
- EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0);
-#endif
-
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
- FAIL_IF(!inst);
- INC_SIZE(1);
- *inst = CDQ;
-#else
- if (compiler->mode32) {
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
- FAIL_IF(!inst);
- INC_SIZE(1);
- *inst = CDQ;
- } else {
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);
- FAIL_IF(!inst);
- INC_SIZE(2);
- *inst++ = REX_W;
- *inst = CDQ;
- }
-#endif
- }
-
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);
- FAIL_IF(!inst);
- INC_SIZE(2);
- *inst++ = GROUP_F7;
- *inst = MOD_REG | ((op >= SLJIT_DIVMOD_UW) ? reg_map[TMP_REG1] : reg_map[SLJIT_R1]);
-#else
-#ifdef _WIN64
- size = (!compiler->mode32 || op >= SLJIT_DIVMOD_UW) ? 3 : 2;
-#else
- size = (!compiler->mode32) ? 3 : 2;
-#endif
- inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
- FAIL_IF(!inst);
- INC_SIZE(size);
-#ifdef _WIN64
- if (!compiler->mode32)
- *inst++ = REX_W | ((op >= SLJIT_DIVMOD_UW) ? REX_B : 0);
- else if (op >= SLJIT_DIVMOD_UW)
- *inst++ = REX_B;
- *inst++ = GROUP_F7;
- *inst = MOD_REG | ((op >= SLJIT_DIVMOD_UW) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_R1]);
-#else
- if (!compiler->mode32)
- *inst++ = REX_W;
- *inst++ = GROUP_F7;
- *inst = MOD_REG | reg_map[SLJIT_R1];
-#endif
-#endif
- switch (op) {
- case SLJIT_LMUL_UW:
- *inst |= MUL;
- break;
- case SLJIT_LMUL_SW:
- *inst |= IMUL;
- break;
- case SLJIT_DIVMOD_UW:
- case SLJIT_DIV_UW:
- *inst |= DIV;
- break;
- case SLJIT_DIVMOD_SW:
- case SLJIT_DIV_SW:
- *inst |= IDIV;
- break;
- }
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64)
- if (op <= SLJIT_DIVMOD_SW)
- EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0);
-#else
- if (op >= SLJIT_DIV_UW)
- EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0);
-#endif
- break;
- case SLJIT_ENDBR:
- return emit_endbranch(compiler);
- case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
- return skip_frames_before_return(compiler);
- }
-
- return SLJIT_SUCCESS;
-}
-
-#define ENCODE_PREFIX(prefix) \
- do { \
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); \
- FAIL_IF(!inst); \
- INC_SIZE(1); \
- *inst = U8(prefix); \
- } while (0)
-
-static sljit_s32 emit_mov_byte(struct sljit_compiler *compiler, sljit_s32 sign,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_u8* inst;
- sljit_s32 dst_r;
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- sljit_s32 work_r;
-#endif
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = 0;
-#endif
-
- if (src & SLJIT_IMM) {
- if (FAST_IS_REG(dst)) {
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- return emit_do_imm(compiler, MOV_r_i32 | reg_map[dst], srcw);
-#else
- inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, 0);
- FAIL_IF(!inst);
- *inst = MOV_rm_i32;
- return SLJIT_SUCCESS;
-#endif
- }
- inst = emit_x86_instruction(compiler, 1 | EX86_BYTE_ARG | EX86_NO_REXW, SLJIT_IMM, srcw, dst, dstw);
- FAIL_IF(!inst);
- *inst = MOV_rm8_i8;
- return SLJIT_SUCCESS;
- }
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
-
- if ((dst & SLJIT_MEM) && FAST_IS_REG(src)) {
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- if (reg_map[src] >= 4) {
- SLJIT_ASSERT(dst_r == TMP_REG1);
- EMIT_MOV(compiler, TMP_REG1, 0, src, 0);
- } else
- dst_r = src;
-#else
- dst_r = src;
-#endif
- }
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- else if (FAST_IS_REG(src) && reg_map[src] >= 4) {
- /* src, dst are registers. */
- SLJIT_ASSERT(FAST_IS_REG(dst));
- if (reg_map[dst] < 4) {
- if (dst != src)
- EMIT_MOV(compiler, dst, 0, src, 0);
- inst = emit_x86_instruction(compiler, 2, dst, 0, dst, 0);
- FAIL_IF(!inst);
- *inst++ = GROUP_0F;
- *inst = sign ? MOVSX_r_rm8 : MOVZX_r_rm8;
- }
- else {
- if (dst != src)
- EMIT_MOV(compiler, dst, 0, src, 0);
- if (sign) {
- /* shl reg, 24 */
- inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0);
- FAIL_IF(!inst);
- *inst |= SHL;
- /* sar reg, 24 */
- inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0);
- FAIL_IF(!inst);
- *inst |= SAR;
- }
- else {
- inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 0xff, dst, 0);
- FAIL_IF(!inst);
- *(inst + 1) |= AND;
- }
- }
- return SLJIT_SUCCESS;
- }
-#endif
- else {
- /* src can be memory addr or reg_map[src] < 4 on x86_32 architectures. */
- inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw);
- FAIL_IF(!inst);
- *inst++ = GROUP_0F;
- *inst = sign ? MOVSX_r_rm8 : MOVZX_r_rm8;
- }
-
- if (dst & SLJIT_MEM) {
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- if (dst_r == TMP_REG1) {
- /* Find a non-used register, whose reg_map[src] < 4. */
- if ((dst & REG_MASK) == SLJIT_R0) {
- if ((dst & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_R1))
- work_r = SLJIT_R2;
- else
- work_r = SLJIT_R1;
- }
- else {
- if ((dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_R0))
- work_r = SLJIT_R0;
- else if ((dst & REG_MASK) == SLJIT_R1)
- work_r = SLJIT_R2;
- else
- work_r = SLJIT_R1;
- }
-
- if (work_r == SLJIT_R0) {
- ENCODE_PREFIX(XCHG_EAX_r | reg_map[TMP_REG1]);
- }
- else {
- inst = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0);
- FAIL_IF(!inst);
- *inst = XCHG_r_rm;
- }
-
- inst = emit_x86_instruction(compiler, 1, work_r, 0, dst, dstw);
- FAIL_IF(!inst);
- *inst = MOV_rm8_r8;
-
- if (work_r == SLJIT_R0) {
- ENCODE_PREFIX(XCHG_EAX_r | reg_map[TMP_REG1]);
- }
- else {
- inst = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0);
- FAIL_IF(!inst);
- *inst = XCHG_r_rm;
- }
- }
- else {
- inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
- FAIL_IF(!inst);
- *inst = MOV_rm8_r8;
- }
-#else
- inst = emit_x86_instruction(compiler, 1 | EX86_REX | EX86_NO_REXW, dst_r, 0, dst, dstw);
- FAIL_IF(!inst);
- *inst = MOV_rm8_r8;
-#endif
- }
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_prefetch(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_u8* inst;
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = 1;
-#endif
-
- inst = emit_x86_instruction(compiler, 2, 0, 0, src, srcw);
- FAIL_IF(!inst);
- *inst++ = GROUP_0F;
- *inst++ = PREFETCH;
-
- if (op == SLJIT_PREFETCH_L1)
- *inst |= (1 << 3);
- else if (op == SLJIT_PREFETCH_L2)
- *inst |= (2 << 3);
- else if (op == SLJIT_PREFETCH_L3)
- *inst |= (3 << 3);
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_mov_half(struct sljit_compiler *compiler, sljit_s32 sign,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_u8* inst;
- sljit_s32 dst_r;
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = 0;
-#endif
-
- if (src & SLJIT_IMM) {
- if (FAST_IS_REG(dst)) {
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- return emit_do_imm(compiler, MOV_r_i32 | reg_map[dst], srcw);
-#else
- inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, 0);
- FAIL_IF(!inst);
- *inst = MOV_rm_i32;
- return SLJIT_SUCCESS;
-#endif
- }
- inst = emit_x86_instruction(compiler, 1 | EX86_HALF_ARG | EX86_NO_REXW | EX86_PREF_66, SLJIT_IMM, srcw, dst, dstw);
- FAIL_IF(!inst);
- *inst = MOV_rm_i32;
- return SLJIT_SUCCESS;
- }
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
-
- if ((dst & SLJIT_MEM) && FAST_IS_REG(src))
- dst_r = src;
- else {
- inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw);
- FAIL_IF(!inst);
- *inst++ = GROUP_0F;
- *inst = sign ? MOVSX_r_rm16 : MOVZX_r_rm16;
- }
-
- if (dst & SLJIT_MEM) {
- inst = emit_x86_instruction(compiler, 1 | EX86_NO_REXW | EX86_PREF_66, dst_r, 0, dst, dstw);
- FAIL_IF(!inst);
- *inst = MOV_rm_r;
- }
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_unary(struct sljit_compiler *compiler, sljit_u8 opcode,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_u8* inst;
-
- if (dst == src && dstw == srcw) {
- /* Same input and output */
- inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
- FAIL_IF(!inst);
- *inst++ = GROUP_F7;
- *inst |= opcode;
- return SLJIT_SUCCESS;
- }
-
- if (FAST_IS_REG(dst)) {
- EMIT_MOV(compiler, dst, 0, src, srcw);
- inst = emit_x86_instruction(compiler, 1, 0, 0, dst, 0);
- FAIL_IF(!inst);
- *inst++ = GROUP_F7;
- *inst |= opcode;
- return SLJIT_SUCCESS;
- }
-
- EMIT_MOV(compiler, TMP_REG1, 0, src, srcw);
- inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0);
- FAIL_IF(!inst);
- *inst++ = GROUP_F7;
- *inst |= opcode;
- EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_not_with_flags(struct sljit_compiler *compiler,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_u8* inst;
-
- if (FAST_IS_REG(dst)) {
- EMIT_MOV(compiler, dst, 0, src, srcw);
- inst = emit_x86_instruction(compiler, 1, 0, 0, dst, 0);
- FAIL_IF(!inst);
- *inst++ = GROUP_F7;
- *inst |= NOT_rm;
- inst = emit_x86_instruction(compiler, 1, dst, 0, dst, 0);
- FAIL_IF(!inst);
- *inst = OR_r_rm;
- return SLJIT_SUCCESS;
- }
-
- EMIT_MOV(compiler, TMP_REG1, 0, src, srcw);
- inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0);
- FAIL_IF(!inst);
- *inst++ = GROUP_F7;
- *inst |= NOT_rm;
- inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG1, 0);
- FAIL_IF(!inst);
- *inst = OR_r_rm;
- EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);
- return SLJIT_SUCCESS;
-}
-
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-static const sljit_sw emit_clz_arg = 32 + 31;
-static const sljit_sw emit_ctz_arg = 32;
-#endif
-
-static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 is_clz,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_u8* inst;
- sljit_s32 dst_r;
- sljit_sw max;
-
- if (cpu_feature_list == 0)
- get_cpu_features();
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
-
- if (is_clz ? (cpu_feature_list & CPU_FEATURE_LZCNT) : (cpu_feature_list & CPU_FEATURE_TZCNT)) {
- /* Group prefix added separately. */
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
- FAIL_IF(!inst);
- INC_SIZE(1);
- *inst++ = GROUP_F3;
-
- inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw);
- FAIL_IF(!inst);
- *inst++ = GROUP_0F;
- *inst = is_clz ? LZCNT_r_rm : TZCNT_r_rm;
-
- if (dst & SLJIT_MEM)
- EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);
- return SLJIT_SUCCESS;
- }
-
- inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw);
- FAIL_IF(!inst);
- *inst++ = GROUP_0F;
- *inst = is_clz ? BSR_r_rm : BSF_r_rm;
-
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- max = is_clz ? (32 + 31) : 32;
-
- if (cpu_feature_list & CPU_FEATURE_CMOV) {
- if (dst_r != TMP_REG1) {
- EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, max);
- inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG1, 0);
- }
- else
- inst = emit_x86_instruction(compiler, 2, dst_r, 0, SLJIT_MEM0(), is_clz ? (sljit_sw)&emit_clz_arg : (sljit_sw)&emit_ctz_arg);
-
- FAIL_IF(!inst);
- *inst++ = GROUP_0F;
- *inst = CMOVE_r_rm;
- }
- else
- FAIL_IF(sljit_emit_cmov_generic(compiler, SLJIT_EQUAL, dst_r, SLJIT_IMM, max));
-
- if (is_clz) {
- inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 31, dst_r, 0);
- FAIL_IF(!inst);
- *(inst + 1) |= XOR;
- }
-#else
- if (is_clz)
- max = compiler->mode32 ? (32 + 31) : (64 + 63);
- else
- max = compiler->mode32 ? 32 : 64;
-
- if (cpu_feature_list & CPU_FEATURE_CMOV) {
- EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, max);
-
- inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0);
- FAIL_IF(!inst);
- *inst++ = GROUP_0F;
- *inst = CMOVE_r_rm;
- }
- else
- FAIL_IF(sljit_emit_cmov_generic(compiler, SLJIT_EQUAL, dst_r, SLJIT_IMM, max));
-
- if (is_clz) {
- inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, max >> 1, dst_r, 0);
- FAIL_IF(!inst);
- *(inst + 1) |= XOR;
- }
-#endif
-
- if (dst & SLJIT_MEM)
- EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 op_flags = GET_ALL_FLAGS(op);
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- sljit_s32 dst_is_ereg = 0;
-#endif
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1);
- CHECK_EXTRA_REGS(src, srcw, (void)0);
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = op_flags & SLJIT_32;
-#endif
-
- op = GET_OPCODE(op);
-
- if (op >= SLJIT_MOV && op <= SLJIT_MOV_P) {
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = 0;
-#endif
-
- if (FAST_IS_REG(src) && src == dst) {
- if (!TYPE_CAST_NEEDED(op))
- return SLJIT_SUCCESS;
- }
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if (op_flags & SLJIT_32) {
- if (src & SLJIT_MEM) {
- if (op == SLJIT_MOV_S32)
- op = SLJIT_MOV_U32;
- }
- else if (src & SLJIT_IMM) {
- if (op == SLJIT_MOV_U32)
- op = SLJIT_MOV_S32;
- }
- }
-#endif
-
- if (src & SLJIT_IMM) {
- switch (op) {
- case SLJIT_MOV_U8:
- srcw = (sljit_u8)srcw;
- break;
- case SLJIT_MOV_S8:
- srcw = (sljit_s8)srcw;
- break;
- case SLJIT_MOV_U16:
- srcw = (sljit_u16)srcw;
- break;
- case SLJIT_MOV_S16:
- srcw = (sljit_s16)srcw;
- break;
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- case SLJIT_MOV_U32:
- srcw = (sljit_u32)srcw;
- break;
- case SLJIT_MOV_S32:
- srcw = (sljit_s32)srcw;
- break;
-#endif
- }
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- if (SLJIT_UNLIKELY(dst_is_ereg))
- return emit_mov(compiler, dst, dstw, src, srcw);
-#endif
- }
-
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- if (SLJIT_UNLIKELY(dst_is_ereg) && (!(op == SLJIT_MOV || op == SLJIT_MOV_U32 || op == SLJIT_MOV_S32 || op == SLJIT_MOV_P) || (src & SLJIT_MEM))) {
- SLJIT_ASSERT(dst == SLJIT_MEM1(SLJIT_SP));
- dst = TMP_REG1;
- }
-#endif
-
- switch (op) {
- case SLJIT_MOV:
- case SLJIT_MOV_P:
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- case SLJIT_MOV_U32:
- case SLJIT_MOV_S32:
- case SLJIT_MOV32:
-#endif
- EMIT_MOV(compiler, dst, dstw, src, srcw);
- break;
- case SLJIT_MOV_U8:
- FAIL_IF(emit_mov_byte(compiler, 0, dst, dstw, src, srcw));
- break;
- case SLJIT_MOV_S8:
- FAIL_IF(emit_mov_byte(compiler, 1, dst, dstw, src, srcw));
- break;
- case SLJIT_MOV_U16:
- FAIL_IF(emit_mov_half(compiler, 0, dst, dstw, src, srcw));
- break;
- case SLJIT_MOV_S16:
- FAIL_IF(emit_mov_half(compiler, 1, dst, dstw, src, srcw));
- break;
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- case SLJIT_MOV_U32:
- FAIL_IF(emit_mov_int(compiler, 0, dst, dstw, src, srcw));
- break;
- case SLJIT_MOV_S32:
- FAIL_IF(emit_mov_int(compiler, 1, dst, dstw, src, srcw));
- break;
- case SLJIT_MOV32:
- compiler->mode32 = 1;
- EMIT_MOV(compiler, dst, dstw, src, srcw);
- compiler->mode32 = 0;
- break;
-#endif
- }
-
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- if (SLJIT_UNLIKELY(dst_is_ereg) && dst == TMP_REG1)
- return emit_mov(compiler, SLJIT_MEM1(SLJIT_SP), dstw, TMP_REG1, 0);
-#endif
- return SLJIT_SUCCESS;
- }
-
- switch (op) {
- case SLJIT_NOT:
- if (SLJIT_UNLIKELY(op_flags & SLJIT_SET_Z))
- return emit_not_with_flags(compiler, dst, dstw, src, srcw);
- return emit_unary(compiler, NOT_rm, dst, dstw, src, srcw);
-
- case SLJIT_CLZ:
- case SLJIT_CTZ:
- return emit_clz_ctz(compiler, (op == SLJIT_CLZ), dst, dstw, src, srcw);
- }
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_cum_binary(struct sljit_compiler *compiler,
- sljit_u32 op_types,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_u8* inst;
- sljit_u8 op_eax_imm = U8(op_types >> 24);
- sljit_u8 op_rm = U8((op_types >> 16) & 0xff);
- sljit_u8 op_mr = U8((op_types >> 8) & 0xff);
- sljit_u8 op_imm = U8(op_types & 0xff);
-
- if (dst == src1 && dstw == src1w) {
- if (src2 & SLJIT_IMM) {
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
-#else
- if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128)) {
-#endif
- BINARY_EAX_IMM(op_eax_imm, src2w);
- }
- else {
- BINARY_IMM(op_imm, op_mr, src2w, dst, dstw);
- }
- }
- else if (FAST_IS_REG(dst)) {
- inst = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w);
- FAIL_IF(!inst);
- *inst = op_rm;
- }
- else if (FAST_IS_REG(src2)) {
- /* Special exception for sljit_emit_op_flags. */
- inst = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw);
- FAIL_IF(!inst);
- *inst = op_mr;
- }
- else {
- EMIT_MOV(compiler, TMP_REG1, 0, src2, src2w);
- inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw);
- FAIL_IF(!inst);
- *inst = op_mr;
- }
- return SLJIT_SUCCESS;
- }
-
- /* Only for cumulative operations. */
- if (dst == src2 && dstw == src2w) {
- if (src1 & SLJIT_IMM) {
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if ((dst == SLJIT_R0) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {
-#else
- if ((dst == SLJIT_R0) && (src1w > 127 || src1w < -128)) {
-#endif
- BINARY_EAX_IMM(op_eax_imm, src1w);
- }
- else {
- BINARY_IMM(op_imm, op_mr, src1w, dst, dstw);
- }
- }
- else if (FAST_IS_REG(dst)) {
- inst = emit_x86_instruction(compiler, 1, dst, dstw, src1, src1w);
- FAIL_IF(!inst);
- *inst = op_rm;
- }
- else if (FAST_IS_REG(src1)) {
- inst = emit_x86_instruction(compiler, 1, src1, src1w, dst, dstw);
- FAIL_IF(!inst);
- *inst = op_mr;
- }
- else {
- EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
- inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw);
- FAIL_IF(!inst);
- *inst = op_mr;
- }
- return SLJIT_SUCCESS;
- }
-
- /* General version. */
- if (FAST_IS_REG(dst)) {
- EMIT_MOV(compiler, dst, 0, src1, src1w);
- if (src2 & SLJIT_IMM) {
- BINARY_IMM(op_imm, op_mr, src2w, dst, 0);
- }
- else {
- inst = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w);
- FAIL_IF(!inst);
- *inst = op_rm;
- }
- }
- else {
- /* This version requires less memory writing. */
- EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
- if (src2 & SLJIT_IMM) {
- BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0);
- }
- else {
- inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);
- FAIL_IF(!inst);
- *inst = op_rm;
- }
- EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);
- }
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_non_cum_binary(struct sljit_compiler *compiler,
- sljit_u32 op_types,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_u8* inst;
- sljit_u8 op_eax_imm = U8(op_types >> 24);
- sljit_u8 op_rm = U8((op_types >> 16) & 0xff);
- sljit_u8 op_mr = U8((op_types >> 8) & 0xff);
- sljit_u8 op_imm = U8(op_types & 0xff);
-
- if (dst == src1 && dstw == src1w) {
- if (src2 & SLJIT_IMM) {
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
-#else
- if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128)) {
-#endif
- BINARY_EAX_IMM(op_eax_imm, src2w);
- }
- else {
- BINARY_IMM(op_imm, op_mr, src2w, dst, dstw);
- }
- }
- else if (FAST_IS_REG(dst)) {
- inst = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w);
- FAIL_IF(!inst);
- *inst = op_rm;
- }
- else if (FAST_IS_REG(src2)) {
- inst = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw);
- FAIL_IF(!inst);
- *inst = op_mr;
- }
- else {
- EMIT_MOV(compiler, TMP_REG1, 0, src2, src2w);
- inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw);
- FAIL_IF(!inst);
- *inst = op_mr;
- }
- return SLJIT_SUCCESS;
- }
-
- /* General version. */
- if (FAST_IS_REG(dst) && dst != src2) {
- EMIT_MOV(compiler, dst, 0, src1, src1w);
- if (src2 & SLJIT_IMM) {
- BINARY_IMM(op_imm, op_mr, src2w, dst, 0);
- }
- else {
- inst = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w);
- FAIL_IF(!inst);
- *inst = op_rm;
- }
- }
- else {
- /* This version requires less memory writing. */
- EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
- if (src2 & SLJIT_IMM) {
- BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0);
- }
- else {
- inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);
- FAIL_IF(!inst);
- *inst = op_rm;
- }
- EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);
- }
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_mul(struct sljit_compiler *compiler,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_u8* inst;
- sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
-
- /* Register destination. */
- if (dst_r == src1 && !(src2 & SLJIT_IMM)) {
- inst = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w);
- FAIL_IF(!inst);
- *inst++ = GROUP_0F;
- *inst = IMUL_r_rm;
- }
- else if (dst_r == src2 && !(src1 & SLJIT_IMM)) {
- inst = emit_x86_instruction(compiler, 2, dst_r, 0, src1, src1w);
- FAIL_IF(!inst);
- *inst++ = GROUP_0F;
- *inst = IMUL_r_rm;
- }
- else if (src1 & SLJIT_IMM) {
- if (src2 & SLJIT_IMM) {
- EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, src2w);
- src2 = dst_r;
- src2w = 0;
- }
-
- if (src1w <= 127 && src1w >= -128) {
- inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
- FAIL_IF(!inst);
- *inst = IMUL_r_rm_i8;
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
- FAIL_IF(!inst);
- INC_SIZE(1);
- *inst = U8(src1w);
- }
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- else {
- inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
- FAIL_IF(!inst);
- *inst = IMUL_r_rm_i32;
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
- FAIL_IF(!inst);
- INC_SIZE(4);
- sljit_unaligned_store_sw(inst, src1w);
- }
-#else
- else if (IS_HALFWORD(src1w)) {
- inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
- FAIL_IF(!inst);
- *inst = IMUL_r_rm_i32;
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
- FAIL_IF(!inst);
- INC_SIZE(4);
- sljit_unaligned_store_s32(inst, (sljit_s32)src1w);
- }
- else {
- if (dst_r != src2)
- EMIT_MOV(compiler, dst_r, 0, src2, src2w);
- FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src1w));
- inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0);
- FAIL_IF(!inst);
- *inst++ = GROUP_0F;
- *inst = IMUL_r_rm;
- }
-#endif
- }
- else if (src2 & SLJIT_IMM) {
- /* Note: src1 is NOT immediate. */
-
- if (src2w <= 127 && src2w >= -128) {
- inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
- FAIL_IF(!inst);
- *inst = IMUL_r_rm_i8;
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
- FAIL_IF(!inst);
- INC_SIZE(1);
- *inst = U8(src2w);
- }
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- else {
- inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
- FAIL_IF(!inst);
- *inst = IMUL_r_rm_i32;
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
- FAIL_IF(!inst);
- INC_SIZE(4);
- sljit_unaligned_store_sw(inst, src2w);
- }
-#else
- else if (IS_HALFWORD(src2w)) {
- inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
- FAIL_IF(!inst);
- *inst = IMUL_r_rm_i32;
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
- FAIL_IF(!inst);
- INC_SIZE(4);
- sljit_unaligned_store_s32(inst, (sljit_s32)src2w);
- }
- else {
- if (dst_r != src1)
- EMIT_MOV(compiler, dst_r, 0, src1, src1w);
- FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));
- inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0);
- FAIL_IF(!inst);
- *inst++ = GROUP_0F;
- *inst = IMUL_r_rm;
- }
-#endif
- }
- else {
- /* Neither argument is immediate. */
- if (ADDRESSING_DEPENDS_ON(src2, dst_r))
- dst_r = TMP_REG1;
- EMIT_MOV(compiler, dst_r, 0, src1, src1w);
- inst = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w);
- FAIL_IF(!inst);
- *inst++ = GROUP_0F;
- *inst = IMUL_r_rm;
- }
-
- if (dst & SLJIT_MEM)
- EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_lea_binary(struct sljit_compiler *compiler,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_u8* inst;
- sljit_s32 dst_r, done = 0;
-
- /* These cases better be left to handled by normal way. */
- if (dst == src1 && dstw == src1w)
- return SLJIT_ERR_UNSUPPORTED;
- if (dst == src2 && dstw == src2w)
- return SLJIT_ERR_UNSUPPORTED;
-
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
-
- if (FAST_IS_REG(src1)) {
- if (FAST_IS_REG(src2)) {
- inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0);
- FAIL_IF(!inst);
- *inst = LEA_r_m;
- done = 1;
- }
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if ((src2 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src2w))) {
- inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), (sljit_s32)src2w);
-#else
- if (src2 & SLJIT_IMM) {
- inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), src2w);
-#endif
- FAIL_IF(!inst);
- *inst = LEA_r_m;
- done = 1;
- }
- }
- else if (FAST_IS_REG(src2)) {
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if ((src1 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src1w))) {
- inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (sljit_s32)src1w);
-#else
- if (src1 & SLJIT_IMM) {
- inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), src1w);
-#endif
- FAIL_IF(!inst);
- *inst = LEA_r_m;
- done = 1;
- }
- }
-
- if (done) {
- if (dst_r == TMP_REG1)
- return emit_mov(compiler, dst, dstw, TMP_REG1, 0);
- return SLJIT_SUCCESS;
- }
- return SLJIT_ERR_UNSUPPORTED;
-}
-
-static sljit_s32 emit_cmp_binary(struct sljit_compiler *compiler,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_u8* inst;
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
-#else
- if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) {
-#endif
- BINARY_EAX_IMM(CMP_EAX_i32, src2w);
- return SLJIT_SUCCESS;
- }
-
- if (FAST_IS_REG(src1)) {
- if (src2 & SLJIT_IMM) {
- BINARY_IMM(CMP, CMP_rm_r, src2w, src1, 0);
- }
- else {
- inst = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w);
- FAIL_IF(!inst);
- *inst = CMP_r_rm;
- }
- return SLJIT_SUCCESS;
- }
-
- if (FAST_IS_REG(src2) && !(src1 & SLJIT_IMM)) {
- inst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w);
- FAIL_IF(!inst);
- *inst = CMP_rm_r;
- return SLJIT_SUCCESS;
- }
-
- if (src2 & SLJIT_IMM) {
- if (src1 & SLJIT_IMM) {
- EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
- src1 = TMP_REG1;
- src1w = 0;
- }
- BINARY_IMM(CMP, CMP_rm_r, src2w, src1, src1w);
- }
- else {
- EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
- inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);
- FAIL_IF(!inst);
- *inst = CMP_r_rm;
- }
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_test_binary(struct sljit_compiler *compiler,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_u8* inst;
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
-#else
- if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) {
-#endif
- BINARY_EAX_IMM(TEST_EAX_i32, src2w);
- return SLJIT_SUCCESS;
- }
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if (src2 == SLJIT_R0 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {
-#else
- if (src2 == SLJIT_R0 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128)) {
-#endif
- BINARY_EAX_IMM(TEST_EAX_i32, src1w);
- return SLJIT_SUCCESS;
- }
-
- if (!(src1 & SLJIT_IMM)) {
- if (src2 & SLJIT_IMM) {
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if (IS_HALFWORD(src2w) || compiler->mode32) {
- inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, src1w);
- FAIL_IF(!inst);
- *inst = GROUP_F7;
- }
- else {
- FAIL_IF(emit_load_imm64(compiler, TMP_REG1, src2w));
- inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src1, src1w);
- FAIL_IF(!inst);
- *inst = TEST_rm_r;
- }
-#else
- inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, src1w);
- FAIL_IF(!inst);
- *inst = GROUP_F7;
-#endif
- return SLJIT_SUCCESS;
- }
- else if (FAST_IS_REG(src1)) {
- inst = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w);
- FAIL_IF(!inst);
- *inst = TEST_rm_r;
- return SLJIT_SUCCESS;
- }
- }
-
- if (!(src2 & SLJIT_IMM)) {
- if (src1 & SLJIT_IMM) {
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if (IS_HALFWORD(src1w) || compiler->mode32) {
- inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, src2w);
- FAIL_IF(!inst);
- *inst = GROUP_F7;
- }
- else {
- FAIL_IF(emit_load_imm64(compiler, TMP_REG1, src1w));
- inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);
- FAIL_IF(!inst);
- *inst = TEST_rm_r;
- }
-#else
- inst = emit_x86_instruction(compiler, 1, src1, src1w, src2, src2w);
- FAIL_IF(!inst);
- *inst = GROUP_F7;
-#endif
- return SLJIT_SUCCESS;
- }
- else if (FAST_IS_REG(src2)) {
- inst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w);
- FAIL_IF(!inst);
- *inst = TEST_rm_r;
- return SLJIT_SUCCESS;
- }
- }
-
- EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
- if (src2 & SLJIT_IMM) {
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if (IS_HALFWORD(src2w) || compiler->mode32) {
- inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REG1, 0);
- FAIL_IF(!inst);
- *inst = GROUP_F7;
- }
- else {
- FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));
- inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, TMP_REG1, 0);
- FAIL_IF(!inst);
- *inst = TEST_rm_r;
- }
-#else
- inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REG1, 0);
- FAIL_IF(!inst);
- *inst = GROUP_F7;
-#endif
- }
- else {
- inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);
- FAIL_IF(!inst);
- *inst = TEST_rm_r;
- }
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_shift(struct sljit_compiler *compiler,
- sljit_u8 mode,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- sljit_s32 mode32;
-#endif
- sljit_u8* inst;
-
- if ((src2 & SLJIT_IMM) || (src2 == SLJIT_PREF_SHIFT_REG)) {
- if (dst == src1 && dstw == src1w) {
- inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, dstw);
- FAIL_IF(!inst);
- *inst |= mode;
- return SLJIT_SUCCESS;
- }
- if (dst == SLJIT_PREF_SHIFT_REG && src2 == SLJIT_PREF_SHIFT_REG) {
- EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
- inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
- FAIL_IF(!inst);
- *inst |= mode;
- EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
- return SLJIT_SUCCESS;
- }
- if (FAST_IS_REG(dst)) {
- EMIT_MOV(compiler, dst, 0, src1, src1w);
- inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, 0);
- FAIL_IF(!inst);
- *inst |= mode;
- return SLJIT_SUCCESS;
- }
-
- EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
- inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REG1, 0);
- FAIL_IF(!inst);
- *inst |= mode;
- EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);
- return SLJIT_SUCCESS;
- }
-
- if (dst == SLJIT_PREF_SHIFT_REG) {
- EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
- EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
- inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
- FAIL_IF(!inst);
- *inst |= mode;
- return emit_mov(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
- }
-
- if (FAST_IS_REG(dst) && dst != src2 && dst != TMP_REG1 && !ADDRESSING_DEPENDS_ON(src2, dst)) {
- if (src1 != dst)
- EMIT_MOV(compiler, dst, 0, src1, src1w);
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- mode32 = compiler->mode32;
- compiler->mode32 = 0;
-#endif
- EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_PREF_SHIFT_REG, 0);
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = mode32;
-#endif
- EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
- inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, dst, 0);
- FAIL_IF(!inst);
- *inst |= mode;
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = 0;
-#endif
- EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = mode32;
-#endif
- return SLJIT_SUCCESS;
- }
-
- /* This case is complex since ecx itself may be used for
- addressing, and this case must be supported as well. */
- EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_PREF_SHIFT_REG, 0);
-#else /* !SLJIT_CONFIG_X86_32 */
- mode32 = compiler->mode32;
- compiler->mode32 = 0;
- EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);
- compiler->mode32 = mode32;
-#endif /* SLJIT_CONFIG_X86_32 */
-
- EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
- inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
- FAIL_IF(!inst);
- *inst |= mode;
-
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_SP), 0);
-#else
- compiler->mode32 = 0;
- EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0);
- compiler->mode32 = mode32;
-#endif /* SLJIT_CONFIG_X86_32 */
-
- if (dst != TMP_REG1)
- return emit_mov(compiler, dst, dstw, TMP_REG1, 0);
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_shift_with_flags(struct sljit_compiler *compiler,
- sljit_u8 mode, sljit_s32 set_flags,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- /* The CPU does not set flags if the shift count is 0. */
- if (src2 & SLJIT_IMM) {
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- src2w &= compiler->mode32 ? 0x1f : 0x3f;
-#else /* !SLJIT_CONFIG_X86_64 */
- src2w &= 0x1f;
-#endif /* SLJIT_CONFIG_X86_64 */
- if (src2w != 0)
- return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
-
- if (!set_flags)
- return emit_mov(compiler, dst, dstw, src1, src1w);
- /* OR dst, src, 0 */
- return emit_cum_binary(compiler, BINARY_OPCODE(OR),
- dst, dstw, src1, src1w, SLJIT_IMM, 0);
- }
-
- if (!set_flags)
- return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
-
- if (!FAST_IS_REG(dst))
- FAIL_IF(emit_cmp_binary(compiler, src1, src1w, SLJIT_IMM, 0));
-
- FAIL_IF(emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w));
-
- if (FAST_IS_REG(dst))
- return emit_cmp_binary(compiler, dst, dstw, SLJIT_IMM, 0);
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- CHECK_EXTRA_REGS(dst, dstw, (void)0);
- CHECK_EXTRA_REGS(src1, src1w, (void)0);
- CHECK_EXTRA_REGS(src2, src2w, (void)0);
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = op & SLJIT_32;
-#endif
-
- SLJIT_ASSERT(dst != TMP_REG1 || HAS_FLAGS(op));
-
- switch (GET_OPCODE(op)) {
- case SLJIT_ADD:
- if (!HAS_FLAGS(op)) {
- if (emit_lea_binary(compiler, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED)
- return compiler->error;
- }
- return emit_cum_binary(compiler, BINARY_OPCODE(ADD),
- dst, dstw, src1, src1w, src2, src2w);
- case SLJIT_ADDC:
- return emit_cum_binary(compiler, BINARY_OPCODE(ADC),
- dst, dstw, src1, src1w, src2, src2w);
- case SLJIT_SUB:
- if (src1 == SLJIT_IMM && src1w == 0)
- return emit_unary(compiler, NEG_rm, dst, dstw, src2, src2w);
-
- if (!HAS_FLAGS(op)) {
- if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED)
- return compiler->error;
- if (FAST_IS_REG(dst) && src2 == dst) {
- FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB), dst, 0, dst, 0, src1, src1w));
- return emit_unary(compiler, NEG_rm, dst, 0, dst, 0);
- }
- }
-
- return emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),
- dst, dstw, src1, src1w, src2, src2w);
- case SLJIT_SUBC:
- return emit_non_cum_binary(compiler, BINARY_OPCODE(SBB),
- dst, dstw, src1, src1w, src2, src2w);
- case SLJIT_MUL:
- return emit_mul(compiler, dst, dstw, src1, src1w, src2, src2w);
- case SLJIT_AND:
- return emit_cum_binary(compiler, BINARY_OPCODE(AND),
- dst, dstw, src1, src1w, src2, src2w);
- case SLJIT_OR:
- return emit_cum_binary(compiler, BINARY_OPCODE(OR),
- dst, dstw, src1, src1w, src2, src2w);
- case SLJIT_XOR:
- return emit_cum_binary(compiler, BINARY_OPCODE(XOR),
- dst, dstw, src1, src1w, src2, src2w);
- case SLJIT_SHL:
- case SLJIT_MSHL:
- return emit_shift_with_flags(compiler, SHL, HAS_FLAGS(op),
- dst, dstw, src1, src1w, src2, src2w);
- case SLJIT_LSHR:
- case SLJIT_MLSHR:
- return emit_shift_with_flags(compiler, SHR, HAS_FLAGS(op),
- dst, dstw, src1, src1w, src2, src2w);
- case SLJIT_ASHR:
- case SLJIT_MASHR:
- return emit_shift_with_flags(compiler, SAR, HAS_FLAGS(op),
- dst, dstw, src1, src1w, src2, src2w);
- case SLJIT_ROTL:
- return emit_shift_with_flags(compiler, ROL, 0,
- dst, dstw, src1, src1w, src2, src2w);
- case SLJIT_ROTR:
- return emit_shift_with_flags(compiler, ROR, 0,
- dst, dstw, src1, src1w, src2, src2w);
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 opcode = GET_OPCODE(op);
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));
-
- if (opcode != SLJIT_SUB && opcode != SLJIT_AND) {
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_op2(compiler, op, TMP_REG1, 0, src1, src1w, src2, src2w);
- }
-
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- CHECK_EXTRA_REGS(src1, src1w, (void)0);
- CHECK_EXTRA_REGS(src2, src2w, (void)0);
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = op & SLJIT_32;
-#endif
-
- if (opcode == SLJIT_SUB) {
- return emit_cmp_binary(compiler, src1, src1w, src2, src2w);
- }
- return emit_test_binary(compiler, src1, src1w, src2, src2w);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src_dst,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 restore_ecx = 0;
- sljit_s32 is_rotate, is_left;
- sljit_u8* inst;
- sljit_sw dstw = 0;
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- sljit_s32 tmp2 = SLJIT_MEM1(SLJIT_SP);
-#else /* !SLJIT_CONFIG_X86_32 */
- sljit_s32 tmp2 = TMP_REG2;
-#endif /* SLJIT_CONFIG_X86_32 */
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w));
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- CHECK_EXTRA_REGS(src1, src1w, (void)0);
- CHECK_EXTRA_REGS(src2, src2w, (void)0);
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = op & SLJIT_32;
-#endif
-
- if (src2 & SLJIT_IMM) {
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- src2w &= 0x1f;
-#else /* !SLJIT_CONFIG_X86_32 */
- src2w &= (op & SLJIT_32) ? 0x1f : 0x3f;
-#endif /* SLJIT_CONFIG_X86_32 */
-
- if (src2w == 0)
- return SLJIT_SUCCESS;
- }
-
- is_left = (GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_MSHL);
-
- is_rotate = (src_dst == src1);
- CHECK_EXTRA_REGS(src_dst, dstw, (void)0);
-
- if (is_rotate)
- return emit_shift(compiler, is_left ? ROL : ROR, src_dst, dstw, src1, src1w, src2, src2w);
-
- if ((src2 & SLJIT_IMM) || src2 == SLJIT_PREF_SHIFT_REG) {
- if (!FAST_IS_REG(src1)) {
- EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
- src1 = TMP_REG1;
- }
- } else if (FAST_IS_REG(src1)) {
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = 0;
-#endif
- EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_PREF_SHIFT_REG, 0);
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = op & SLJIT_32;
-#endif
- EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
-
- if (src1 == SLJIT_PREF_SHIFT_REG)
- src1 = TMP_REG1;
-
- if (src_dst == SLJIT_PREF_SHIFT_REG)
- src_dst = TMP_REG1;
-
- restore_ecx = 1;
- } else {
- EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = 0;
-#endif
- EMIT_MOV(compiler, tmp2, 0, SLJIT_PREF_SHIFT_REG, 0);
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = op & SLJIT_32;
-#endif
- EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
-
- src1 = TMP_REG1;
-
- if (src_dst == SLJIT_PREF_SHIFT_REG) {
- src_dst = tmp2;
- SLJIT_ASSERT(dstw == 0);
- }
-
- restore_ecx = 2;
- }
-
- inst = emit_x86_instruction(compiler, 2, src1, 0, src_dst, dstw);
- FAIL_IF(!inst);
- inst[0] = GROUP_0F;
-
- if (src2 & SLJIT_IMM) {
- inst[1] = U8((is_left ? SHLD : SHRD) - 1);
-
- /* Immedate argument is added separately. */
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
- FAIL_IF(!inst);
- INC_SIZE(1);
- *inst = U8(src2w);
- } else
- inst[1] = U8(is_left ? SHLD : SHRD);
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = 0;
-#endif
-
- if (restore_ecx == 1)
- return emit_mov(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
- if (restore_ecx == 2)
- return emit_mov(compiler, SLJIT_PREF_SHIFT_REG, 0, tmp2, 0);
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- CHECK_EXTRA_REGS(src, srcw, (void)0);
-
- switch (op) {
- case SLJIT_FAST_RETURN:
- return emit_fast_return(compiler, src, srcw);
- case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
- /* Don't adjust shadow stack if it isn't enabled. */
- if (!cpu_has_shadow_stack ())
- return SLJIT_SUCCESS;
- return adjust_shadow_stack(compiler, src, srcw);
- case SLJIT_PREFETCH_L1:
- case SLJIT_PREFETCH_L2:
- case SLJIT_PREFETCH_L3:
- case SLJIT_PREFETCH_ONCE:
- return emit_prefetch(compiler, op, src, srcw);
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
-{
- CHECK_REG_INDEX(check_sljit_get_register_index(reg));
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- if (reg >= SLJIT_R3 && reg <= SLJIT_R8)
- return -1;
-#endif
- return reg_map[reg];
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
-{
- CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- return reg;
-#else
- return freg_map[reg];
-#endif
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
- void *instruction, sljit_u32 size)
-{
- sljit_u8 *inst;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
-
- inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
- FAIL_IF(!inst);
- INC_SIZE(size);
- SLJIT_MEMCPY(inst, instruction, size);
- return SLJIT_SUCCESS;
-}
-
-/* --------------------------------------------------------------------- */
-/* Floating point operators */
-/* --------------------------------------------------------------------- */
-
-/* Alignment(3) + 4 * 16 bytes. */
-static sljit_u32 sse2_data[3 + (4 * 4)];
-static sljit_u32 *sse2_buffer;
-
-static void init_compiler(void)
-{
- /* Align to 16 bytes. */
- sse2_buffer = (sljit_u32*)(((sljit_uw)sse2_data + 15) & ~(sljit_uw)0xf);
-
- /* Single precision constants (each constant is 16 byte long). */
- sse2_buffer[0] = 0x80000000;
- sse2_buffer[4] = 0x7fffffff;
- /* Double precision constants (each constant is 16 byte long). */
- sse2_buffer[8] = 0;
- sse2_buffer[9] = 0x80000000;
- sse2_buffer[12] = 0xffffffff;
- sse2_buffer[13] = 0x7fffffff;
-}
-
-static sljit_s32 emit_sse2(struct sljit_compiler *compiler, sljit_u8 opcode,
- sljit_s32 single, sljit_s32 xmm1, sljit_s32 xmm2, sljit_sw xmm2w)
-{
- sljit_u8 *inst;
-
- inst = emit_x86_instruction(compiler, 2 | (single ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, xmm1, 0, xmm2, xmm2w);
- FAIL_IF(!inst);
- *inst++ = GROUP_0F;
- *inst = opcode;
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_sse2_logic(struct sljit_compiler *compiler, sljit_u8 opcode,
- sljit_s32 pref66, sljit_s32 xmm1, sljit_s32 xmm2, sljit_sw xmm2w)
-{
- sljit_u8 *inst;
-
- inst = emit_x86_instruction(compiler, 2 | (pref66 ? EX86_PREF_66 : 0) | EX86_SSE2, xmm1, 0, xmm2, xmm2w);
- FAIL_IF(!inst);
- *inst++ = GROUP_0F;
- *inst = opcode;
- return SLJIT_SUCCESS;
-}
-
-static SLJIT_INLINE sljit_s32 emit_sse2_load(struct sljit_compiler *compiler,
- sljit_s32 single, sljit_s32 dst, sljit_s32 src, sljit_sw srcw)
-{
- return emit_sse2(compiler, MOVSD_x_xm, single, dst, src, srcw);
-}
-
-static SLJIT_INLINE sljit_s32 emit_sse2_store(struct sljit_compiler *compiler,
- sljit_s32 single, sljit_s32 dst, sljit_sw dstw, sljit_s32 src)
-{
- return emit_sse2(compiler, MOVSD_xm_x, single, src, dst, dstw);
-}
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
- sljit_u8 *inst;
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if (GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64)
- compiler->mode32 = 0;
-#endif
-
- inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_32) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP2, dst_r, 0, src, srcw);
- FAIL_IF(!inst);
- *inst++ = GROUP_0F;
- *inst = CVTTSD2SI_r_xm;
-
- if (dst & SLJIT_MEM)
- return emit_mov(compiler, dst, dstw, TMP_REG1, 0);
- return SLJIT_SUCCESS;
-}
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG;
- sljit_u8 *inst;
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW)
- compiler->mode32 = 0;
-#endif
-
- if (src & SLJIT_IMM) {
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
- srcw = (sljit_s32)srcw;
-#endif
- EMIT_MOV(compiler, TMP_REG1, 0, src, srcw);
- src = TMP_REG1;
- srcw = 0;
- }
-
- inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_32) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP1, dst_r, 0, src, srcw);
- FAIL_IF(!inst);
- *inst++ = GROUP_0F;
- *inst = CVTSI2SD_x_rm;
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = 1;
-#endif
- if (dst_r == TMP_FREG)
- return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG);
- return SLJIT_SUCCESS;
-}
-
-static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- switch (GET_FLAG_TYPE(op)) {
- case SLJIT_ORDERED_LESS:
- case SLJIT_UNORDERED_OR_GREATER_EQUAL:
- case SLJIT_UNORDERED_OR_GREATER:
- case SLJIT_ORDERED_LESS_EQUAL:
- if (!FAST_IS_REG(src2)) {
- FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src2, src2w));
- src2 = TMP_FREG;
- }
-
- return emit_sse2_logic(compiler, UCOMISD_x_xm, !(op & SLJIT_32), src2, src1, src1w);
- }
-
- if (!FAST_IS_REG(src1)) {
- FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src1, src1w));
- src1 = TMP_FREG;
- }
-
- return emit_sse2_logic(compiler, UCOMISD_x_xm, !(op & SLJIT_32), src1, src2, src2w);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 dst_r;
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = 1;
-#endif
-
- CHECK_ERROR();
- SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
-
- if (GET_OPCODE(op) == SLJIT_MOV_F64) {
- if (FAST_IS_REG(dst))
- return emit_sse2_load(compiler, op & SLJIT_32, dst, src, srcw);
- if (FAST_IS_REG(src))
- return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, src);
- FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src, srcw));
- return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG);
- }
-
- if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) {
- dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG;
- if (FAST_IS_REG(src)) {
- /* We overwrite the high bits of source. From SLJIT point of view,
- this is not an issue.
- Note: In SSE3, we could also use MOVDDUP and MOVSLDUP. */
- FAIL_IF(emit_sse2_logic(compiler, UNPCKLPD_x_xm, op & SLJIT_32, src, src, 0));
- }
- else {
- FAIL_IF(emit_sse2_load(compiler, !(op & SLJIT_32), TMP_FREG, src, srcw));
- src = TMP_FREG;
- }
-
- FAIL_IF(emit_sse2_logic(compiler, CVTPD2PS_x_xm, op & SLJIT_32, dst_r, src, 0));
- if (dst_r == TMP_FREG)
- return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG);
- return SLJIT_SUCCESS;
- }
-
- if (FAST_IS_REG(dst)) {
- dst_r = dst;
- if (dst != src)
- FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, dst_r, src, srcw));
- }
- else {
- dst_r = TMP_FREG;
- FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, dst_r, src, srcw));
- }
-
- switch (GET_OPCODE(op)) {
- case SLJIT_NEG_F64:
- FAIL_IF(emit_sse2_logic(compiler, XORPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_32 ? sse2_buffer : sse2_buffer + 8)));
- break;
-
- case SLJIT_ABS_F64:
- FAIL_IF(emit_sse2_logic(compiler, ANDPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_32 ? sse2_buffer + 4 : sse2_buffer + 12)));
- break;
- }
-
- if (dst_r == TMP_FREG)
- return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG);
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- sljit_s32 dst_r;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = 1;
-#endif
-
- if (FAST_IS_REG(dst)) {
- dst_r = dst;
- if (dst == src1)
- ; /* Do nothing here. */
- else if (dst == src2 && (op == SLJIT_ADD_F64 || op == SLJIT_MUL_F64)) {
- /* Swap arguments. */
- src2 = src1;
- src2w = src1w;
- }
- else if (dst != src2)
- FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, dst_r, src1, src1w));
- else {
- dst_r = TMP_FREG;
- FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src1, src1w));
- }
- }
- else {
- dst_r = TMP_FREG;
- FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src1, src1w));
- }
-
- switch (GET_OPCODE(op)) {
- case SLJIT_ADD_F64:
- FAIL_IF(emit_sse2(compiler, ADDSD_x_xm, op & SLJIT_32, dst_r, src2, src2w));
- break;
-
- case SLJIT_SUB_F64:
- FAIL_IF(emit_sse2(compiler, SUBSD_x_xm, op & SLJIT_32, dst_r, src2, src2w));
- break;
-
- case SLJIT_MUL_F64:
- FAIL_IF(emit_sse2(compiler, MULSD_x_xm, op & SLJIT_32, dst_r, src2, src2w));
- break;
-
- case SLJIT_DIV_F64:
- FAIL_IF(emit_sse2(compiler, DIVSD_x_xm, op & SLJIT_32, dst_r, src2, src2w));
- break;
- }
-
- if (dst_r == TMP_FREG)
- return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG);
- return SLJIT_SUCCESS;
-}
-
-/* --------------------------------------------------------------------- */
-/* Conditional instructions */
-/* --------------------------------------------------------------------- */
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
-{
- sljit_u8 *inst;
- struct sljit_label *label;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_label(compiler));
-
- if (compiler->last_label && compiler->last_label->size == compiler->size)
- return compiler->last_label;
-
- label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
- PTR_FAIL_IF(!label);
- set_label(label, compiler);
-
- inst = (sljit_u8*)ensure_buf(compiler, 2);
- PTR_FAIL_IF(!inst);
-
- *inst++ = 0;
- *inst++ = 0;
-
- return label;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
-{
- sljit_u8 *inst;
- struct sljit_jump *jump;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_jump(compiler, type));
-
- jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
- PTR_FAIL_IF_NULL(jump);
- set_jump(jump, compiler, (sljit_u32)((type & SLJIT_REWRITABLE_JUMP) | ((type & 0xff) << TYPE_SHIFT)));
- type &= 0xff;
-
- /* Worst case size. */
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- compiler->size += (type >= SLJIT_JUMP) ? 5 : 6;
-#else
- compiler->size += (type >= SLJIT_JUMP) ? (10 + 3) : (2 + 10 + 3);
-#endif
-
- inst = (sljit_u8*)ensure_buf(compiler, 2);
- PTR_FAIL_IF_NULL(inst);
-
- *inst++ = 0;
- *inst++ = 1;
- return jump;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
-{
- sljit_u8 *inst;
- struct sljit_jump *jump;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- CHECK_EXTRA_REGS(src, srcw, (void)0);
-
- if (src == SLJIT_IMM) {
- jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
- FAIL_IF_NULL(jump);
- set_jump(jump, compiler, (sljit_u32)(JUMP_ADDR | (type << TYPE_SHIFT)));
- jump->u.target = (sljit_uw)srcw;
-
- /* Worst case size. */
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- compiler->size += 5;
-#else
- compiler->size += 10 + 3;
-#endif
-
- inst = (sljit_u8*)ensure_buf(compiler, 2);
- FAIL_IF_NULL(inst);
-
- *inst++ = 0;
- *inst++ = 1;
- }
- else {
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- /* REX_W is not necessary (src is not immediate). */
- compiler->mode32 = 1;
-#endif
- inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
- FAIL_IF(!inst);
- *inst++ = GROUP_FF;
- *inst = U8(*inst | ((type >= SLJIT_FAST_CALL) ? CALL_rm : JMP_rm));
- }
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 type)
-{
- sljit_u8 *inst;
- sljit_u8 cond_set = 0;
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- sljit_s32 reg;
-#endif
- /* ADJUST_LOCAL_OFFSET and CHECK_EXTRA_REGS might overwrite these values. */
- sljit_s32 dst_save = dst;
- sljit_sw dstw_save = dstw;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
-
- ADJUST_LOCAL_OFFSET(dst, dstw);
- CHECK_EXTRA_REGS(dst, dstw, (void)0);
-
- /* setcc = jcc + 0x10. */
- cond_set = U8(get_jump_code((sljit_uw)type) + 0x10);
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst)) {
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 + 3);
- FAIL_IF(!inst);
- INC_SIZE(4 + 3);
- /* Set low register to conditional flag. */
- *inst++ = (reg_map[TMP_REG1] <= 7) ? REX : REX_B;
- *inst++ = GROUP_0F;
- *inst++ = cond_set;
- *inst++ = MOD_REG | reg_lmap[TMP_REG1];
- *inst++ = U8(REX | (reg_map[TMP_REG1] <= 7 ? 0 : REX_R) | (reg_map[dst] <= 7 ? 0 : REX_B));
- *inst++ = OR_rm8_r8;
- *inst++ = U8(MOD_REG | (reg_lmap[TMP_REG1] << 3) | reg_lmap[dst]);
- return SLJIT_SUCCESS;
- }
-
- reg = (GET_OPCODE(op) < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG1;
-
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 + 4);
- FAIL_IF(!inst);
- INC_SIZE(4 + 4);
- /* Set low register to conditional flag. */
- *inst++ = (reg_map[reg] <= 7) ? REX : REX_B;
- *inst++ = GROUP_0F;
- *inst++ = cond_set;
- *inst++ = MOD_REG | reg_lmap[reg];
- *inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R));
- /* The movzx instruction does not affect flags. */
- *inst++ = GROUP_0F;
- *inst++ = MOVZX_r_rm8;
- *inst = U8(MOD_REG | (reg_lmap[reg] << 3) | reg_lmap[reg]);
-
- if (reg != TMP_REG1)
- return SLJIT_SUCCESS;
-
- if (GET_OPCODE(op) < SLJIT_ADD) {
- compiler->mode32 = GET_OPCODE(op) != SLJIT_MOV;
- return emit_mov(compiler, dst, dstw, TMP_REG1, 0);
- }
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REG1, 0);
-
-#else
- /* The SLJIT_CONFIG_X86_32 code path starts here. */
- if (GET_OPCODE(op) < SLJIT_ADD && FAST_IS_REG(dst)) {
- if (reg_map[dst] <= 4) {
- /* Low byte is accessible. */
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 3 + 3);
- FAIL_IF(!inst);
- INC_SIZE(3 + 3);
- /* Set low byte to conditional flag. */
- *inst++ = GROUP_0F;
- *inst++ = cond_set;
- *inst++ = U8(MOD_REG | reg_map[dst]);
-
- *inst++ = GROUP_0F;
- *inst++ = MOVZX_r_rm8;
- *inst = U8(MOD_REG | (reg_map[dst] << 3) | reg_map[dst]);
- return SLJIT_SUCCESS;
- }
-
- /* Low byte is not accessible. */
- if (cpu_feature_list == 0)
- get_cpu_features();
-
- if (cpu_feature_list & CPU_FEATURE_CMOV) {
- EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, 1);
- /* a xor reg, reg operation would overwrite the flags. */
- EMIT_MOV(compiler, dst, 0, SLJIT_IMM, 0);
-
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 3);
- FAIL_IF(!inst);
- INC_SIZE(3);
-
- *inst++ = GROUP_0F;
- /* cmovcc = setcc - 0x50. */
- *inst++ = U8(cond_set - 0x50);
- *inst++ = U8(MOD_REG | (reg_map[dst] << 3) | reg_map[TMP_REG1]);
- return SLJIT_SUCCESS;
- }
-
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1);
- FAIL_IF(!inst);
- INC_SIZE(1 + 3 + 3 + 1);
- *inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]);
- /* Set al to conditional flag. */
- *inst++ = GROUP_0F;
- *inst++ = cond_set;
- *inst++ = MOD_REG | 0 /* eax */;
-
- *inst++ = GROUP_0F;
- *inst++ = MOVZX_r_rm8;
- *inst++ = U8(MOD_REG | (reg_map[dst] << 3) | 0 /* eax */);
- *inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]);
- return SLJIT_SUCCESS;
- }
-
- if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst) && reg_map[dst] <= 4) {
- SLJIT_ASSERT(reg_map[SLJIT_R0] == 0);
-
- if (dst != SLJIT_R0) {
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 2 + 1);
- FAIL_IF(!inst);
- INC_SIZE(1 + 3 + 2 + 1);
- /* Set low register to conditional flag. */
- *inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]);
- *inst++ = GROUP_0F;
- *inst++ = cond_set;
- *inst++ = MOD_REG | 0 /* eax */;
- *inst++ = OR_rm8_r8;
- *inst++ = MOD_REG | (0 /* eax */ << 3) | reg_map[dst];
- *inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]);
- }
- else {
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + 3 + 2 + 2);
- FAIL_IF(!inst);
- INC_SIZE(2 + 3 + 2 + 2);
- /* Set low register to conditional flag. */
- *inst++ = XCHG_r_rm;
- *inst++ = U8(MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REG1]);
- *inst++ = GROUP_0F;
- *inst++ = cond_set;
- *inst++ = MOD_REG | 1 /* ecx */;
- *inst++ = OR_rm8_r8;
- *inst++ = MOD_REG | (1 /* ecx */ << 3) | 0 /* eax */;
- *inst++ = XCHG_r_rm;
- *inst++ = U8(MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REG1]);
- }
- return SLJIT_SUCCESS;
- }
-
- /* Set TMP_REG1 to the bit. */
- inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1);
- FAIL_IF(!inst);
- INC_SIZE(1 + 3 + 3 + 1);
- *inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]);
- /* Set al to conditional flag. */
- *inst++ = GROUP_0F;
- *inst++ = cond_set;
- *inst++ = MOD_REG | 0 /* eax */;
-
- *inst++ = GROUP_0F;
- *inst++ = MOVZX_r_rm8;
- *inst++ = MOD_REG | (0 << 3) /* eax */ | 0 /* eax */;
-
- *inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]);
-
- if (GET_OPCODE(op) < SLJIT_ADD)
- return emit_mov(compiler, dst, dstw, TMP_REG1, 0);
-
- SLJIT_SKIP_CHECKS(compiler);
- return sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REG1, 0);
-#endif /* SLJIT_CONFIG_X86_64 */
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
- sljit_s32 dst_reg,
- sljit_s32 src, sljit_sw srcw)
-{
- sljit_u8* inst;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
-
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- type &= ~SLJIT_32;
-
- if (!sljit_has_cpu_feature(SLJIT_HAS_CMOV) || (dst_reg >= SLJIT_R3 && dst_reg <= SLJIT_S3))
- return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);
-#else
- if (!sljit_has_cpu_feature(SLJIT_HAS_CMOV))
- return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);
-#endif
-
- /* ADJUST_LOCAL_OFFSET is not needed. */
- CHECK_EXTRA_REGS(src, srcw, (void)0);
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = type & SLJIT_32;
- type &= ~SLJIT_32;
-#endif
-
- if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
- EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcw);
- src = TMP_REG1;
- srcw = 0;
- }
-
- inst = emit_x86_instruction(compiler, 2, dst_reg, 0, src, srcw);
- FAIL_IF(!inst);
- *inst++ = GROUP_0F;
- *inst = U8(get_jump_code((sljit_uw)type) - 0x40);
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
-{
- CHECK_ERROR();
- CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- CHECK_EXTRA_REGS(dst, dstw, (void)0);
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = 0;
-#endif
-
- ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset);
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if (NOT_HALFWORD(offset)) {
- FAIL_IF(emit_load_imm64(compiler, TMP_REG1, offset));
-#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
- SLJIT_ASSERT(emit_lea_binary(compiler, dst, dstw, SLJIT_SP, 0, TMP_REG1, 0) != SLJIT_ERR_UNSUPPORTED);
- return compiler->error;
-#else
- return emit_lea_binary(compiler, dst, dstw, SLJIT_SP, 0, TMP_REG1, 0);
-#endif
- }
-#endif
-
- if (offset != 0)
- return emit_lea_binary(compiler, dst, dstw, SLJIT_SP, 0, SLJIT_IMM, offset);
- return emit_mov(compiler, dst, dstw, SLJIT_SP, 0);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
-{
- sljit_u8 *inst;
- struct sljit_const *const_;
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- sljit_s32 reg;
-#endif
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- CHECK_EXTRA_REGS(dst, dstw, (void)0);
-
- const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
- PTR_FAIL_IF(!const_);
- set_const(const_, compiler);
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = 0;
- reg = FAST_IS_REG(dst) ? dst : TMP_REG1;
-
- if (emit_load_imm64(compiler, reg, init_value))
- return NULL;
-#else
- if (emit_mov(compiler, dst, dstw, SLJIT_IMM, init_value))
- return NULL;
-#endif
-
- inst = (sljit_u8*)ensure_buf(compiler, 2);
- PTR_FAIL_IF(!inst);
-
- *inst++ = 0;
- *inst++ = 2;
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if (dst & SLJIT_MEM)
- if (emit_mov(compiler, dst, dstw, TMP_REG1, 0))
- return NULL;
-#endif
-
- return const_;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
-{
- struct sljit_put_label *put_label;
- sljit_u8 *inst;
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- sljit_s32 reg;
- sljit_uw start_size;
-#endif
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- CHECK_EXTRA_REGS(dst, dstw, (void)0);
-
- put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
- PTR_FAIL_IF(!put_label);
- set_put_label(put_label, compiler, 0);
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = 0;
- reg = FAST_IS_REG(dst) ? dst : TMP_REG1;
-
- if (emit_load_imm64(compiler, reg, 0))
- return NULL;
-#else
- if (emit_mov(compiler, dst, dstw, SLJIT_IMM, 0))
- return NULL;
-#endif
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if (dst & SLJIT_MEM) {
- start_size = compiler->size;
- if (emit_mov(compiler, dst, dstw, TMP_REG1, 0))
- return NULL;
- put_label->flags = compiler->size - start_size;
- }
-#endif
-
- inst = (sljit_u8*)ensure_buf(compiler, 2);
- PTR_FAIL_IF(!inst);
-
- *inst++ = 0;
- *inst++ = 3;
-
- return put_label;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
-{
- SLJIT_UNUSED_ARG(executable_offset);
-
- SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_uw)), 0);
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- sljit_unaligned_store_sw((void*)addr, (sljit_sw)(new_target - (addr + 4) - (sljit_uw)executable_offset));
-#else
- sljit_unaligned_store_sw((void*)addr, (sljit_sw)new_target);
-#endif
- SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_uw)), 1);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
-{
- SLJIT_UNUSED_ARG(executable_offset);
-
- SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_sw)), 0);
- sljit_unaligned_store_sw((void*)addr, new_constant);
- SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_sw)), 1);
-}
diff --git a/contrib/libs/pcre2/src/sljit/sljitProtExecAllocator.c b/contrib/libs/pcre2/src/sljit/sljitProtExecAllocator.c
deleted file mode 100644
index 915411fbed..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitProtExecAllocator.c
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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.
- */
-
-/*
- This file contains a simple executable memory allocator
-
- It is assumed, that executable code blocks are usually medium (or sometimes
- large) memory blocks, and the allocator is not too frequently called (less
- optimized than other allocators). Thus, using it as a generic allocator is
- not suggested.
-
- How does it work:
- Memory is allocated in continuous memory areas called chunks by alloc_chunk()
- Chunk format:
- [ block ][ block ] ... [ block ][ block terminator ]
-
- All blocks and the block terminator is started with block_header. The block
- header contains the size of the previous and the next block. These sizes
- can also contain special values.
- Block size:
- 0 - The block is a free_block, with a different size member.
- 1 - The block is a block terminator.
- n - The block is used at the moment, and the value contains its size.
- Previous block size:
- 0 - This is the first block of the memory chunk.
- n - The size of the previous block.
-
- Using these size values we can go forward or backward on the block chain.
- The unused blocks are stored in a chain list pointed by free_blocks. This
- list is useful if we need to find a suitable memory area when the allocator
- is called.
-
- When a block is freed, the new free block is connected to its adjacent free
- blocks if possible.
-
- [ free block ][ used block ][ free block ]
- and "used block" is freed, the three blocks are connected together:
- [ one big free block ]
-*/
-
-/* --------------------------------------------------------------------- */
-/* System (OS) functions */
-/* --------------------------------------------------------------------- */
-
-/* 64 KByte. */
-#define CHUNK_SIZE (sljit_uw)0x10000
-
-struct chunk_header {
- void *executable;
-};
-
-/*
- alloc_chunk / free_chunk :
- * allocate executable system memory chunks
- * the size is always divisible by CHUNK_SIZE
- SLJIT_ALLOCATOR_LOCK / SLJIT_ALLOCATOR_UNLOCK :
- * provided as part of sljitUtils
- * only the allocator requires this lock, sljit is fully thread safe
- as it only uses local variables
-*/
-
-#ifndef __NetBSD__
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifndef O_NOATIME
-#define O_NOATIME 0
-#endif
-
-/* this is a linux extension available since kernel 3.11 */
-#ifndef O_TMPFILE
-#define O_TMPFILE 020200000
-#endif
-
-#ifndef _GNU_SOURCE
-char *secure_getenv(const char *name);
-int mkostemp(char *template, int flags);
-#endif
-
-static SLJIT_INLINE int create_tempfile(void)
-{
- int fd;
- char tmp_name[256];
- size_t tmp_name_len = 0;
- char *dir;
- struct stat st;
-#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED
- mode_t mode;
-#endif
-
-#ifdef HAVE_MEMFD_CREATE
- /* this is a GNU extension, make sure to use -D_GNU_SOURCE */
- fd = memfd_create("sljit", MFD_CLOEXEC);
- if (fd != -1) {
- fchmod(fd, 0);
- return fd;
- }
-#endif
-
- dir = secure_getenv("TMPDIR");
-
- if (dir) {
- tmp_name_len = strlen(dir);
- if (tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name)) {
- if ((stat(dir, &st) == 0) && S_ISDIR(st.st_mode))
- strcpy(tmp_name, dir);
- }
- }
-
-#ifdef P_tmpdir
- if (!tmp_name_len) {
- tmp_name_len = strlen(P_tmpdir);
- if (tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name))
- strcpy(tmp_name, P_tmpdir);
- }
-#endif
- if (!tmp_name_len) {
- strcpy(tmp_name, "/tmp");
- tmp_name_len = 4;
- }
-
- SLJIT_ASSERT(tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name));
-
- if (tmp_name[tmp_name_len - 1] == '/')
- tmp_name[--tmp_name_len] = '\0';
-
-#ifdef __linux__
- /*
- * the previous trimming might had left an empty string if TMPDIR="/"
- * so work around the problem below
- */
- fd = open(tmp_name_len ? tmp_name : "/",
- O_TMPFILE | O_EXCL | O_RDWR | O_NOATIME | O_CLOEXEC, 0);
- if (fd != -1)
- return fd;
-#endif
-
- if (tmp_name_len + 7 >= sizeof(tmp_name))
- return -1;
-
- strcpy(tmp_name + tmp_name_len, "/XXXXXX");
-#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED
- mode = umask(0777);
-#endif
- fd = mkostemp(tmp_name, O_CLOEXEC | O_NOATIME);
-#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED
- umask(mode);
-#else
- fchmod(fd, 0);
-#endif
-
- if (fd == -1)
- return -1;
-
- if (unlink(tmp_name)) {
- close(fd);
- return -1;
- }
-
- return fd;
-}
-
-static SLJIT_INLINE struct chunk_header* alloc_chunk(sljit_uw size)
-{
- struct chunk_header *retval;
- int fd;
-
- fd = create_tempfile();
- if (fd == -1)
- return NULL;
-
- if (ftruncate(fd, (off_t)size)) {
- close(fd);
- return NULL;
- }
-
- retval = (struct chunk_header *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
-
- if (retval == MAP_FAILED) {
- close(fd);
- return NULL;
- }
-
- retval->executable = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0);
-
- if (retval->executable == MAP_FAILED) {
- munmap((void *)retval, size);
- close(fd);
- return NULL;
- }
-
- close(fd);
- return retval;
-}
-#else
-/*
- * MAP_REMAPDUP is a NetBSD extension available sinde 8.0, make sure to
- * adjust your feature macros (ex: -D_NETBSD_SOURCE) as needed
- */
-static SLJIT_INLINE struct chunk_header* alloc_chunk(sljit_uw size)
-{
- struct chunk_header *retval;
-
- retval = (struct chunk_header *)mmap(NULL, size,
- PROT_READ | PROT_WRITE | PROT_MPROTECT(PROT_EXEC),
- MAP_ANON | MAP_SHARED, -1, 0);
-
- if (retval == MAP_FAILED)
- return NULL;
-
- retval->executable = mremap(retval, size, NULL, size, MAP_REMAPDUP);
- if (retval->executable == MAP_FAILED) {
- munmap((void *)retval, size);
- return NULL;
- }
-
- if (mprotect(retval->executable, size, PROT_READ | PROT_EXEC) == -1) {
- munmap(retval->executable, size);
- munmap((void *)retval, size);
- return NULL;
- }
-
- return retval;
-}
-#endif /* NetBSD */
-
-static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
-{
- struct chunk_header *header = ((struct chunk_header *)chunk) - 1;
-
- munmap(header->executable, size);
- munmap((void *)header, size);
-}
-
-/* --------------------------------------------------------------------- */
-/* Common functions */
-/* --------------------------------------------------------------------- */
-
-#define CHUNK_MASK (~(CHUNK_SIZE - 1))
-
-struct block_header {
- sljit_uw size;
- sljit_uw prev_size;
- sljit_sw executable_offset;
-};
-
-struct free_block {
- struct block_header header;
- struct free_block *next;
- struct free_block *prev;
- sljit_uw size;
-};
-
-#define AS_BLOCK_HEADER(base, offset) \
- ((struct block_header*)(((sljit_u8*)base) + offset))
-#define AS_FREE_BLOCK(base, offset) \
- ((struct free_block*)(((sljit_u8*)base) + offset))
-#define MEM_START(base) ((void*)((base) + 1))
-#define ALIGN_SIZE(size) (((size) + sizeof(struct block_header) + 7u) & ~(sljit_uw)7)
-
-static struct free_block* free_blocks;
-static sljit_uw allocated_size;
-static sljit_uw total_size;
-
-static SLJIT_INLINE void sljit_insert_free_block(struct free_block *free_block, sljit_uw size)
-{
- free_block->header.size = 0;
- free_block->size = size;
-
- free_block->next = free_blocks;
- free_block->prev = NULL;
- if (free_blocks)
- free_blocks->prev = free_block;
- free_blocks = free_block;
-}
-
-static SLJIT_INLINE void sljit_remove_free_block(struct free_block *free_block)
-{
- if (free_block->next)
- free_block->next->prev = free_block->prev;
-
- if (free_block->prev)
- free_block->prev->next = free_block->next;
- else {
- SLJIT_ASSERT(free_blocks == free_block);
- free_blocks = free_block->next;
- }
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
-{
- struct chunk_header *chunk_header;
- struct block_header *header;
- struct block_header *next_header;
- struct free_block *free_block;
- sljit_uw chunk_size;
- sljit_sw executable_offset;
-
- SLJIT_ALLOCATOR_LOCK();
- if (size < (64 - sizeof(struct block_header)))
- size = (64 - sizeof(struct block_header));
- size = ALIGN_SIZE(size);
-
- free_block = free_blocks;
- while (free_block) {
- if (free_block->size >= size) {
- chunk_size = free_block->size;
- if (chunk_size > size + 64) {
- /* We just cut a block from the end of the free block. */
- chunk_size -= size;
- free_block->size = chunk_size;
- header = AS_BLOCK_HEADER(free_block, chunk_size);
- header->prev_size = chunk_size;
- header->executable_offset = free_block->header.executable_offset;
- AS_BLOCK_HEADER(header, size)->prev_size = size;
- }
- else {
- sljit_remove_free_block(free_block);
- header = (struct block_header*)free_block;
- size = chunk_size;
- }
- allocated_size += size;
- header->size = size;
- SLJIT_ALLOCATOR_UNLOCK();
- return MEM_START(header);
- }
- free_block = free_block->next;
- }
-
- chunk_size = sizeof(struct chunk_header) + sizeof(struct block_header);
- chunk_size = (chunk_size + size + CHUNK_SIZE - 1) & CHUNK_MASK;
-
- chunk_header = alloc_chunk(chunk_size);
- if (!chunk_header) {
- SLJIT_ALLOCATOR_UNLOCK();
- return NULL;
- }
-
- executable_offset = (sljit_sw)((sljit_u8*)chunk_header->executable - (sljit_u8*)chunk_header);
-
- chunk_size -= sizeof(struct chunk_header) + sizeof(struct block_header);
- total_size += chunk_size;
-
- header = (struct block_header *)(chunk_header + 1);
-
- header->prev_size = 0;
- header->executable_offset = executable_offset;
- if (chunk_size > size + 64) {
- /* Cut the allocated space into a free and a used block. */
- allocated_size += size;
- header->size = size;
- chunk_size -= size;
-
- free_block = AS_FREE_BLOCK(header, size);
- free_block->header.prev_size = size;
- free_block->header.executable_offset = executable_offset;
- sljit_insert_free_block(free_block, chunk_size);
- next_header = AS_BLOCK_HEADER(free_block, chunk_size);
- }
- else {
- /* All space belongs to this allocation. */
- allocated_size += chunk_size;
- header->size = chunk_size;
- next_header = AS_BLOCK_HEADER(header, chunk_size);
- }
- next_header->size = 1;
- next_header->prev_size = chunk_size;
- next_header->executable_offset = executable_offset;
- SLJIT_ALLOCATOR_UNLOCK();
- return MEM_START(header);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
-{
- struct block_header *header;
- struct free_block* free_block;
-
- SLJIT_ALLOCATOR_LOCK();
- header = AS_BLOCK_HEADER(ptr, -(sljit_sw)sizeof(struct block_header));
- header = AS_BLOCK_HEADER(header, -header->executable_offset);
- allocated_size -= header->size;
-
- /* Connecting free blocks together if possible. */
-
- /* If header->prev_size == 0, free_block will equal to header.
- In this case, free_block->header.size will be > 0. */
- free_block = AS_FREE_BLOCK(header, -(sljit_sw)header->prev_size);
- if (SLJIT_UNLIKELY(!free_block->header.size)) {
- free_block->size += header->size;
- header = AS_BLOCK_HEADER(free_block, free_block->size);
- header->prev_size = free_block->size;
- }
- else {
- free_block = (struct free_block*)header;
- sljit_insert_free_block(free_block, header->size);
- }
-
- header = AS_BLOCK_HEADER(free_block, free_block->size);
- if (SLJIT_UNLIKELY(!header->size)) {
- free_block->size += ((struct free_block*)header)->size;
- sljit_remove_free_block((struct free_block*)header);
- header = AS_BLOCK_HEADER(free_block, free_block->size);
- header->prev_size = free_block->size;
- }
-
- /* The whole chunk is free. */
- if (SLJIT_UNLIKELY(!free_block->header.prev_size && header->size == 1)) {
- /* If this block is freed, we still have (allocated_size / 2) free space. */
- if (total_size - free_block->size > (allocated_size * 3 / 2)) {
- total_size -= free_block->size;
- sljit_remove_free_block(free_block);
- free_chunk(free_block, free_block->size +
- sizeof(struct chunk_header) +
- sizeof(struct block_header));
- }
- }
-
- SLJIT_ALLOCATOR_UNLOCK();
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
-{
- struct free_block* free_block;
- struct free_block* next_free_block;
-
- SLJIT_ALLOCATOR_LOCK();
-
- free_block = free_blocks;
- while (free_block) {
- next_free_block = free_block->next;
- if (!free_block->header.prev_size &&
- AS_BLOCK_HEADER(free_block, free_block->size)->size == 1) {
- total_size -= free_block->size;
- sljit_remove_free_block(free_block);
- free_chunk(free_block, free_block->size +
- sizeof(struct chunk_header) +
- sizeof(struct block_header));
- }
- free_block = next_free_block;
- }
-
- SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks));
- SLJIT_ALLOCATOR_UNLOCK();
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr)
-{
- return ((struct block_header *)(ptr))[-1].executable_offset;
-}
diff --git a/contrib/libs/pcre2/src/sljit/sljitUtils.c b/contrib/libs/pcre2/src/sljit/sljitUtils.c
deleted file mode 100644
index 967593b157..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitUtils.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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.
- */
-
-/* ------------------------------------------------------------------------ */
-/* Locks */
-/* ------------------------------------------------------------------------ */
-
-/* Executable Allocator */
-
-#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) \
- && !(defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)
-#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
-#define SLJIT_ALLOCATOR_LOCK()
-#define SLJIT_ALLOCATOR_UNLOCK()
-#elif !(defined _WIN32)
-#include <pthread.h>
-
-static pthread_mutex_t allocator_lock = PTHREAD_MUTEX_INITIALIZER;
-
-#define SLJIT_ALLOCATOR_LOCK() pthread_mutex_lock(&allocator_lock)
-#define SLJIT_ALLOCATOR_UNLOCK() pthread_mutex_unlock(&allocator_lock)
-#else /* windows */
-static HANDLE allocator_lock;
-
-static SLJIT_INLINE void allocator_grab_lock(void)
-{
- HANDLE lock;
- if (SLJIT_UNLIKELY(!InterlockedCompareExchangePointer(&allocator_lock, NULL, NULL))) {
- lock = CreateMutex(NULL, FALSE, NULL);
- if (InterlockedCompareExchangePointer(&allocator_lock, lock, NULL))
- CloseHandle(lock);
- }
- WaitForSingleObject(allocator_lock, INFINITE);
-}
-
-#define SLJIT_ALLOCATOR_LOCK() allocator_grab_lock()
-#define SLJIT_ALLOCATOR_UNLOCK() ReleaseMutex(allocator_lock)
-#endif /* thread implementation */
-#endif /* SLJIT_EXECUTABLE_ALLOCATOR && !SLJIT_WX_EXECUTABLE_ALLOCATOR */
-
-/* ------------------------------------------------------------------------ */
-/* Stack */
-/* ------------------------------------------------------------------------ */
-
-#if ((defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) \
- && !(defined SLJIT_UTIL_SIMPLE_STACK_ALLOCATION && SLJIT_UTIL_SIMPLE_STACK_ALLOCATION)) \
- || ((defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) \
- && !((defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR) \
- || (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)))
-
-#ifndef _WIN32
-/* Provides mmap function. */
-#include <sys/types.h>
-#include <sys/mman.h>
-
-#ifndef MAP_ANON
-#ifdef MAP_ANONYMOUS
-#define MAP_ANON MAP_ANONYMOUS
-#endif /* MAP_ANONYMOUS */
-#endif /* !MAP_ANON */
-
-#ifndef MAP_ANON
-
-#include <fcntl.h>
-
-#ifdef O_CLOEXEC
-#define SLJIT_CLOEXEC O_CLOEXEC
-#else /* !O_CLOEXEC */
-#define SLJIT_CLOEXEC 0
-#endif /* O_CLOEXEC */
-
-/* Some old systems do not have MAP_ANON. */
-static int dev_zero = -1;
-
-#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
-
-static SLJIT_INLINE int open_dev_zero(void)
-{
- dev_zero = open("/dev/zero", O_RDWR | SLJIT_CLOEXEC);
-
- return dev_zero < 0;
-}
-
-#else /* !SLJIT_SINGLE_THREADED */
-
-#include <pthread.h>
-
-static pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-static SLJIT_INLINE int open_dev_zero(void)
-{
- pthread_mutex_lock(&dev_zero_mutex);
- if (SLJIT_UNLIKELY(dev_zero < 0))
- dev_zero = open("/dev/zero", O_RDWR | SLJIT_CLOEXEC);
-
- pthread_mutex_unlock(&dev_zero_mutex);
- return dev_zero < 0;
-}
-
-#endif /* SLJIT_SINGLE_THREADED */
-#undef SLJIT_CLOEXEC
-#endif /* !MAP_ANON */
-#endif /* !_WIN32 */
-#endif /* open_dev_zero */
-
-#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) \
- || (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
-
-#ifdef _WIN32
-
-static SLJIT_INLINE sljit_uw get_page_alignment(void) {
- SYSTEM_INFO si;
- static sljit_uw sljit_page_align = 0;
- if (!sljit_page_align) {
- GetSystemInfo(&si);
- sljit_page_align = (sljit_uw)si.dwPageSize - 1;
- }
- return sljit_page_align;
-}
-
-#else
-
-#include <unistd.h>
-
-static SLJIT_INLINE sljit_uw get_page_alignment(void) {
- static sljit_uw sljit_page_align = 0;
-
- sljit_sw align;
-
- if (!sljit_page_align) {
-#ifdef _SC_PAGESIZE
- align = sysconf(_SC_PAGESIZE);
-#else
- align = getpagesize();
-#endif
- /* Should never happen. */
- if (align < 0)
- align = 4096;
- sljit_page_align = (sljit_uw)align - 1;
- }
- return sljit_page_align;
-}
-
-#endif /* _WIN32 */
-
-#endif /* get_page_alignment() */
-
-#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
-
-#if (defined SLJIT_UTIL_SIMPLE_STACK_ALLOCATION && SLJIT_UTIL_SIMPLE_STACK_ALLOCATION)
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data)
-{
- struct sljit_stack *stack;
- void *ptr;
-
- SLJIT_UNUSED_ARG(allocator_data);
-
- if (start_size > max_size || start_size < 1)
- return NULL;
-
- stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data);
- if (stack == NULL)
- return NULL;
-
- ptr = SLJIT_MALLOC(max_size, allocator_data);
- if (ptr == NULL) {
- SLJIT_FREE(stack, allocator_data);
- return NULL;
- }
-
- stack->min_start = (sljit_u8 *)ptr;
- stack->end = stack->min_start + max_size;
- stack->start = stack->end - start_size;
- stack->top = stack->end;
- return stack;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
-{
- SLJIT_UNUSED_ARG(allocator_data);
- SLJIT_FREE((void*)stack->min_start, allocator_data);
- SLJIT_FREE(stack, allocator_data);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start)
-{
- if ((new_start < stack->min_start) || (new_start >= stack->end))
- return NULL;
- stack->start = new_start;
- return new_start;
-}
-
-#else /* !SLJIT_UTIL_SIMPLE_STACK_ALLOCATION */
-
-#ifdef _WIN32
-
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
-{
- SLJIT_UNUSED_ARG(allocator_data);
- VirtualFree((void*)stack->min_start, 0, MEM_RELEASE);
- SLJIT_FREE(stack, allocator_data);
-}
-
-#else /* !_WIN32 */
-
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
-{
- SLJIT_UNUSED_ARG(allocator_data);
- munmap((void*)stack->min_start, (size_t)(stack->end - stack->min_start));
- SLJIT_FREE(stack, allocator_data);
-}
-
-#endif /* _WIN32 */
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data)
-{
- struct sljit_stack *stack;
- void *ptr;
- sljit_uw page_align;
-
- SLJIT_UNUSED_ARG(allocator_data);
-
- if (start_size > max_size || start_size < 1)
- return NULL;
-
- stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data);
- if (stack == NULL)
- return NULL;
-
- /* Align max_size. */
- page_align = get_page_alignment();
- max_size = (max_size + page_align) & ~page_align;
-
-#ifdef _WIN32
- ptr = VirtualAlloc(NULL, max_size, MEM_RESERVE, PAGE_READWRITE);
- if (!ptr) {
- SLJIT_FREE(stack, allocator_data);
- return NULL;
- }
-
- stack->min_start = (sljit_u8 *)ptr;
- stack->end = stack->min_start + max_size;
- stack->start = stack->end;
-
- if (sljit_stack_resize(stack, stack->end - start_size) == NULL) {
- sljit_free_stack(stack, allocator_data);
- return NULL;
- }
-#else /* !_WIN32 */
-#ifdef MAP_ANON
- ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
-#else /* !MAP_ANON */
- if (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero())) {
- SLJIT_FREE(stack, allocator_data);
- return NULL;
- }
- ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0);
-#endif /* MAP_ANON */
- if (ptr == MAP_FAILED) {
- SLJIT_FREE(stack, allocator_data);
- return NULL;
- }
- stack->min_start = (sljit_u8 *)ptr;
- stack->end = stack->min_start + max_size;
- stack->start = stack->end - start_size;
-#endif /* _WIN32 */
-
- stack->top = stack->end;
- return stack;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start)
-{
-#if defined _WIN32 || defined(POSIX_MADV_DONTNEED)
- sljit_uw aligned_old_start;
- sljit_uw aligned_new_start;
- sljit_uw page_align;
-#endif
-
- if ((new_start < stack->min_start) || (new_start >= stack->end))
- return NULL;
-
-#ifdef _WIN32
- page_align = get_page_alignment();
-
- aligned_new_start = (sljit_uw)new_start & ~page_align;
- aligned_old_start = ((sljit_uw)stack->start) & ~page_align;
- if (aligned_new_start != aligned_old_start) {
- if (aligned_new_start < aligned_old_start) {
- if (!VirtualAlloc((void*)aligned_new_start, aligned_old_start - aligned_new_start, MEM_COMMIT, PAGE_READWRITE))
- return NULL;
- }
- else {
- if (!VirtualFree((void*)aligned_old_start, aligned_new_start - aligned_old_start, MEM_DECOMMIT))
- return NULL;
- }
- }
-#elif defined(POSIX_MADV_DONTNEED)
- if (stack->start < new_start) {
- page_align = get_page_alignment();
-
- aligned_new_start = (sljit_uw)new_start & ~page_align;
- aligned_old_start = ((sljit_uw)stack->start) & ~page_align;
-
- if (aligned_new_start > aligned_old_start) {
- posix_madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, POSIX_MADV_DONTNEED);
-#ifdef MADV_FREE
- madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, MADV_FREE);
-#endif /* MADV_FREE */
- }
- }
-#endif /* _WIN32 */
-
- stack->start = new_start;
- return new_start;
-}
-
-#endif /* SLJIT_UTIL_SIMPLE_STACK_ALLOCATION */
-
-#endif /* SLJIT_UTIL_STACK */
diff --git a/contrib/libs/pcre2/src/sljit/sljitWXExecAllocator.c b/contrib/libs/pcre2/src/sljit/sljitWXExecAllocator.c
deleted file mode 100644
index 6893813155..0000000000
--- a/contrib/libs/pcre2/src/sljit/sljitWXExecAllocator.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) 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.
- */
-
-/*
- This file contains a simple W^X executable memory allocator for POSIX
- like systems and Windows
-
- In *NIX, MAP_ANON is required (that is considered a feature) so make
- sure to set the right availability macros for your system or the code
- will fail to build.
-
- If your system doesn't support mapping of anonymous pages (ex: IRIX) it
- is also likely that it doesn't need this allocator and should be using
- the standard one instead.
-
- It allocates a separate map for each code block and may waste a lot of
- memory, because whatever was requested, will be rounded up to the page
- size (minimum 4KB, but could be even bigger).
-
- It changes the page permissions (RW <-> RX) as needed and therefore, if you
- will be updating the code after it has been generated, need to make sure to
- block any concurrent execution, or could result in a SIGBUS, that could
- even manifest itself at a different address than the one that was being
- modified.
-
- Only use if you are unable to use the regular allocator because of security
- restrictions and adding exceptions to your application or the system are
- not possible.
-*/
-
-#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \
- sljit_update_wx_flags((from), (to), (enable_exec))
-
-#ifndef _WIN32
-#include <sys/types.h>
-#include <sys/mman.h>
-
-#ifdef __NetBSD__
-#define SLJIT_PROT_WX PROT_MPROTECT(PROT_EXEC)
-#define check_se_protected(ptr, size) (0)
-#else /* POSIX */
-#if !(defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
-#include <pthread.h>
-#define SLJIT_SE_LOCK() pthread_mutex_lock(&se_lock)
-#define SLJIT_SE_UNLOCK() pthread_mutex_unlock(&se_lock)
-#endif /* !SLJIT_SINGLE_THREADED */
-
-#define check_se_protected(ptr, size) generic_se_protected(ptr, size)
-
-static SLJIT_INLINE int generic_se_protected(void *ptr, sljit_uw size)
-{
- if (SLJIT_LIKELY(!mprotect(ptr, size, PROT_EXEC)))
- return mprotect(ptr, size, PROT_READ | PROT_WRITE);
-
- return -1;
-}
-#endif /* NetBSD */
-
-#ifndef SLJIT_SE_LOCK
-#define SLJIT_SE_LOCK()
-#endif
-#ifndef SLJIT_SE_UNLOCK
-#define SLJIT_SE_UNLOCK()
-#endif
-#ifndef SLJIT_PROT_WX
-#define SLJIT_PROT_WX 0
-#endif
-
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
-{
-#if !(defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) \
- && !defined(__NetBSD__)
- static pthread_mutex_t se_lock = PTHREAD_MUTEX_INITIALIZER;
-#endif
- static int se_protected = !SLJIT_PROT_WX;
- int prot = PROT_READ | PROT_WRITE | SLJIT_PROT_WX;
- sljit_uw* ptr;
-
- if (SLJIT_UNLIKELY(se_protected < 0))
- return NULL;
-
-#ifdef PROT_MAX
- prot |= PROT_MAX(PROT_READ | PROT_WRITE | PROT_EXEC);
-#endif
-
- size += sizeof(sljit_uw);
- ptr = (sljit_uw*)mmap(NULL, size, prot, MAP_PRIVATE | MAP_ANON, -1, 0);
-
- if (ptr == MAP_FAILED)
- return NULL;
-
- if (SLJIT_UNLIKELY(se_protected > 0)) {
- SLJIT_SE_LOCK();
- se_protected = check_se_protected(ptr, size);
- SLJIT_SE_UNLOCK();
- if (SLJIT_UNLIKELY(se_protected < 0)) {
- munmap((void *)ptr, size);
- return NULL;
- }
- }
-
- *ptr++ = size;
- return ptr;
-}
-
-#undef SLJIT_PROT_WX
-#undef SLJIT_SE_UNLOCK
-#undef SLJIT_SE_LOCK
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
-{
- sljit_uw *start_ptr = ((sljit_uw*)ptr) - 1;
- munmap((void*)start_ptr, *start_ptr);
-}
-
-static void sljit_update_wx_flags(void *from, void *to, sljit_s32 enable_exec)
-{
- sljit_uw page_mask = (sljit_uw)get_page_alignment();
- sljit_uw start = (sljit_uw)from;
- sljit_uw end = (sljit_uw)to;
- int prot = PROT_READ | (enable_exec ? PROT_EXEC : PROT_WRITE);
-
- SLJIT_ASSERT(start < end);
-
- start &= ~page_mask;
- end = (end + page_mask) & ~page_mask;
-
- mprotect((void*)start, end - start, prot);
-}
-
-#else /* windows */
-
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
-{
- sljit_uw *ptr;
-
- size += sizeof(sljit_uw);
- ptr = (sljit_uw*)VirtualAlloc(NULL, size,
- MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
-
- if (!ptr)
- return NULL;
-
- *ptr++ = size;
-
- return ptr;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
-{
- sljit_uw start = (sljit_uw)ptr - sizeof(sljit_uw);
-#if defined(SLJIT_DEBUG) && SLJIT_DEBUG
- sljit_uw page_mask = (sljit_uw)get_page_alignment();
-
- SLJIT_ASSERT(!(start & page_mask));
-#endif
- VirtualFree((void*)start, 0, MEM_RELEASE);
-}
-
-static void sljit_update_wx_flags(void *from, void *to, sljit_s32 enable_exec)
-{
- DWORD oldprot;
- sljit_uw page_mask = (sljit_uw)get_page_alignment();
- sljit_uw start = (sljit_uw)from;
- sljit_uw end = (sljit_uw)to;
- DWORD prot = enable_exec ? PAGE_EXECUTE : PAGE_READWRITE;
-
- SLJIT_ASSERT(start < end);
-
- start &= ~page_mask;
- end = (end + page_mask) & ~page_mask;
-
- VirtualProtect((void*)start, end - start, prot, &oldprot);
-}
-
-#endif /* !windows */
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
-{
- /* This allocator does not keep unused memory for future allocations. */
-}
diff --git a/contrib/libs/pcre2/ya.make b/contrib/libs/pcre2/ya.make
deleted file mode 100644
index 27d3962e4b..0000000000
--- a/contrib/libs/pcre2/ya.make
+++ /dev/null
@@ -1,70 +0,0 @@
-# Generated by devtools/yamaker from nixpkgs 22.05.
-
-LIBRARY()
-
-VERSION(10.42)
-
-ORIGINAL_SOURCE(https://github.com/PCRE2Project/pcre2/archive/pcre2-10.42.tar.gz)
-
-LICENSE(
- BSD-2-Clause AND
- BSD-3-Clause AND
- FSFAP AND
- GPL-1.0-or-later AND
- LicenseRef-scancode-pcre AND
- LicenseRef-scancode-unknown-license-reference AND
- Public-Domain
-)
-
-LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-
-ADDINCL(
- contrib/libs/pcre2
- contrib/libs/pcre2/src
-)
-
-NO_COMPILER_WARNINGS()
-
-NO_RUNTIME()
-
-CFLAGS(
- -DHAVE_CONFIG_H
- -DPCRE2_CODE_UNIT_WIDTH=8
-)
-
-SRCS(
- src/pcre2_auto_possess.c
- src/pcre2_chartables.c
- src/pcre2_compile.c
- src/pcre2_config.c
- src/pcre2_context.c
- src/pcre2_convert.c
- src/pcre2_dfa_match.c
- src/pcre2_error.c
- src/pcre2_extuni.c
- src/pcre2_find_bracket.c
- src/pcre2_jit_compile.c
- src/pcre2_maketables.c
- src/pcre2_match.c
- src/pcre2_match_data.c
- src/pcre2_newline.c
- src/pcre2_ord2utf.c
- src/pcre2_pattern_info.c
- src/pcre2_script_run.c
- src/pcre2_serialize.c
- src/pcre2_string_utils.c
- src/pcre2_study.c
- src/pcre2_substitute.c
- src/pcre2_substring.c
- src/pcre2_tables.c
- src/pcre2_ucd.c
- src/pcre2_valid_utf.c
- src/pcre2_xclass.c
-)
-
-END()
-
-RECURSE(
- pcre2-16
- pcre2-32
-)
diff --git a/contrib/python/distro/py2/.dist-info/METADATA b/contrib/python/distro/py2/.dist-info/METADATA
deleted file mode 100644
index bc42dfcf16..0000000000
--- a/contrib/python/distro/py2/.dist-info/METADATA
+++ /dev/null
@@ -1,169 +0,0 @@
-Metadata-Version: 2.1
-Name: distro
-Version: 1.6.0
-Summary: Distro - an OS platform information API
-Home-page: https://github.com/python-distro/distro
-Author: Nir Cohen
-Author-email: nir36g@gmail.com
-License: Apache License, Version 2.0
-Platform: All
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: Intended Audience :: System Administrators
-Classifier: License :: OSI Approved :: Apache Software License
-Classifier: Operating System :: POSIX :: Linux
-Classifier: Operating System :: POSIX :: BSD
-Classifier: Operating System :: POSIX :: BSD :: FreeBSD
-Classifier: Operating System :: POSIX :: BSD :: NetBSD
-Classifier: Operating System :: POSIX :: BSD :: OpenBSD
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
-Classifier: Programming Language :: Python :: 3.6
-Classifier: Programming Language :: Python :: 3.7
-Classifier: Programming Language :: Python :: 3.8
-Classifier: Programming Language :: Python :: 3.9
-Classifier: Topic :: Software Development :: Libraries :: Python Modules
-Classifier: Topic :: System :: Operating System
-Description-Content-Type: text/markdown
-License-File: LICENSE
-
-Distro - an OS platform information API
-=======================================
-
-[![CI Status](https://github.com/python-distro/distro/workflows/CI/badge.svg)](https://github.com/python-distro/distro/actions/workflows/ci.yaml)
-[![PyPI version](http://img.shields.io/pypi/v/distro.svg)](https://pypi.python.org/pypi/distro)
-[![Supported Python Versions](https://img.shields.io/pypi/pyversions/distro.svg)](https://img.shields.io/pypi/pyversions/distro.svg)
-[![Code Coverage](https://codecov.io/github/python-distro/distro/coverage.svg?branch=master)](https://codecov.io/github/python-distro/distro?branch=master)
-[![Is Wheel](https://img.shields.io/pypi/wheel/distro.svg?style=flat)](https://pypi.python.org/pypi/distro)
-[![Latest Github Release](https://readthedocs.org/projects/distro/badge/?version=stable)](http://distro.readthedocs.io/en/latest/)
-[![Join the chat at https://gitter.im/python-distro/distro](https://badges.gitter.im/python-distro/distro.svg)](https://gitter.im/python-distro/distro?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-
-`distro` provides information about the
-OS distribution it runs on, such as a reliable machine-readable ID, or
-version information.
-
-It is the recommended replacement for Python's original
-[`platform.linux_distribution`](https://docs.python.org/3.7/library/platform.html#platform.linux_distribution)
-function (removed in Python 3.8). It also provides much more functionality
-which isn't necessarily Python bound, like a command-line interface.
-
-Distro currently supports Linux and BSD based systems but [Windows and OS X support](https://github.com/python-distro/distro/issues/177) is also planned.
-
-For Python 2.6 support, see https://github.com/python-distro/distro/tree/python2.6-support
-
-## Installation
-
-Installation of the latest released version from PyPI:
-
-```shell
-pip install distro
-```
-
-Installation of the latest development version:
-
-```shell
-pip install https://github.com/python-distro/distro/archive/master.tar.gz
-```
-
-
-## Usage
-
-```bash
-$ distro
-Name: Antergos Linux
-Version: 2015.10 (ISO-Rolling)
-Codename: ISO-Rolling
-
-$ distro -j
-{
- "codename": "ISO-Rolling",
- "id": "antergos",
- "like": "arch",
- "version": "16.9",
- "version_parts": {
- "build_number": "",
- "major": "16",
- "minor": "9"
- }
-}
-
-
-$ python
->>> import distro
->>> distro.linux_distribution(full_distribution_name=False)
-('centos', '7.1.1503', 'Core')
-```
-
-
-## Documentation
-
-On top of the aforementioned API, several more functions are available. For a complete description of the
-API, see the [latest API documentation](http://distro.readthedocs.org/en/latest/).
-
-## Background
-
-An alternative implementation became necessary because Python 3.5 deprecated
-this function, and Python 3.8 removed it altogether. Its predecessor function
-[`platform.dist`](https://docs.python.org/3.7/library/platform.html#platform.dist)
-was already deprecated since Python 2.6 and removed in Python 3.8. Still, there
-are many cases in which access to that information is needed. See [Python issue
-1322](https://bugs.python.org/issue1322) for more information.
-
-The `distro` package implements a robust and inclusive way of retrieving the
-information about a distribution based on new standards and old methods,
-namely from these data sources (from high to low precedence):
-
-* The os-release file `/etc/os-release` if present, with a fall-back on `/usr/lib/os-release` if needed.
-* The output of the `lsb_release` command, if available.
-* The distro release file (`/etc/*(-|_)(release|version)`), if present.
-* The `uname` command for BSD based distrubtions.
-
-
-## Python and Distribution Support
-
-`distro` is supported and tested on Python 2.7, 3.4+ and PyPy and on
-any distribution that provides one or more of the data sources
-covered.
-
-This package is tested with test data that mimics the exact behavior of the data sources of [a number of Linux distributions](https://github.com/python-distro/distro/tree/master/tests/resources/distros).
-
-
-## Testing
-
-```shell
-git clone git@github.com:python-distro/distro.git
-cd distro
-pip install tox
-tox
-```
-
-
-## Contributions
-
-Pull requests are always welcome to deal with specific distributions or just
-for general merriment.
-
-See [CONTRIBUTIONS](https://github.com/python-distro/distro/blob/master/CONTRIBUTING.md) for contribution info.
-
-Reference implementations for supporting additional distributions and file
-formats can be found here:
-
-* https://github.com/saltstack/salt/blob/develop/salt/grains/core.py#L1172
-* https://github.com/chef/ohai/blob/master/lib/ohai/plugins/linux/platform.rb
-* https://github.com/ansible/ansible/blob/devel/lib/ansible/module_utils/facts/system/distribution.py
-* https://github.com/puppetlabs/facter/blob/master/lib/src/facts/linux/os_linux.cc
-
-## Package manager distributions
-
-* https://src.fedoraproject.org/rpms/python-distro
-* https://www.archlinux.org/packages/community/any/python-distro/
-* https://launchpad.net/ubuntu/+source/python-distro
-* https://packages.debian.org/sid/python-distro
-* https://packages.gentoo.org/packages/dev-python/distro
-* https://pkgs.org/download/python2-distro
-* https://slackbuilds.org/repository/14.2/python/python-distro/
-
-
diff --git a/contrib/python/distro/py2/.dist-info/entry_points.txt b/contrib/python/distro/py2/.dist-info/entry_points.txt
deleted file mode 100644
index dd4023997f..0000000000
--- a/contrib/python/distro/py2/.dist-info/entry_points.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-[console_scripts]
-distro = distro:main
-
diff --git a/contrib/python/distro/py2/.dist-info/top_level.txt b/contrib/python/distro/py2/.dist-info/top_level.txt
deleted file mode 100644
index 0e0933171d..0000000000
--- a/contrib/python/distro/py2/.dist-info/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-distro
diff --git a/contrib/python/distro/py2/LICENSE b/contrib/python/distro/py2/LICENSE
deleted file mode 100644
index e06d208186..0000000000
--- a/contrib/python/distro/py2/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "{}"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright {yyyy} {name of copyright owner}
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
diff --git a/contrib/python/distro/py2/README.md b/contrib/python/distro/py2/README.md
deleted file mode 100644
index 76eaef244d..0000000000
--- a/contrib/python/distro/py2/README.md
+++ /dev/null
@@ -1,135 +0,0 @@
-Distro - an OS platform information API
-=======================================
-
-[![CI Status](https://github.com/python-distro/distro/workflows/CI/badge.svg)](https://github.com/python-distro/distro/actions/workflows/ci.yaml)
-[![PyPI version](http://img.shields.io/pypi/v/distro.svg)](https://pypi.python.org/pypi/distro)
-[![Supported Python Versions](https://img.shields.io/pypi/pyversions/distro.svg)](https://img.shields.io/pypi/pyversions/distro.svg)
-[![Code Coverage](https://codecov.io/github/python-distro/distro/coverage.svg?branch=master)](https://codecov.io/github/python-distro/distro?branch=master)
-[![Is Wheel](https://img.shields.io/pypi/wheel/distro.svg?style=flat)](https://pypi.python.org/pypi/distro)
-[![Latest Github Release](https://readthedocs.org/projects/distro/badge/?version=stable)](http://distro.readthedocs.io/en/latest/)
-[![Join the chat at https://gitter.im/python-distro/distro](https://badges.gitter.im/python-distro/distro.svg)](https://gitter.im/python-distro/distro?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-
-`distro` provides information about the
-OS distribution it runs on, such as a reliable machine-readable ID, or
-version information.
-
-It is the recommended replacement for Python's original
-[`platform.linux_distribution`](https://docs.python.org/3.7/library/platform.html#platform.linux_distribution)
-function (removed in Python 3.8). It also provides much more functionality
-which isn't necessarily Python bound, like a command-line interface.
-
-Distro currently supports Linux and BSD based systems but [Windows and OS X support](https://github.com/python-distro/distro/issues/177) is also planned.
-
-For Python 2.6 support, see https://github.com/python-distro/distro/tree/python2.6-support
-
-## Installation
-
-Installation of the latest released version from PyPI:
-
-```shell
-pip install distro
-```
-
-Installation of the latest development version:
-
-```shell
-pip install https://github.com/python-distro/distro/archive/master.tar.gz
-```
-
-
-## Usage
-
-```bash
-$ distro
-Name: Antergos Linux
-Version: 2015.10 (ISO-Rolling)
-Codename: ISO-Rolling
-
-$ distro -j
-{
- "codename": "ISO-Rolling",
- "id": "antergos",
- "like": "arch",
- "version": "16.9",
- "version_parts": {
- "build_number": "",
- "major": "16",
- "minor": "9"
- }
-}
-
-
-$ python
->>> import distro
->>> distro.linux_distribution(full_distribution_name=False)
-('centos', '7.1.1503', 'Core')
-```
-
-
-## Documentation
-
-On top of the aforementioned API, several more functions are available. For a complete description of the
-API, see the [latest API documentation](http://distro.readthedocs.org/en/latest/).
-
-## Background
-
-An alternative implementation became necessary because Python 3.5 deprecated
-this function, and Python 3.8 removed it altogether. Its predecessor function
-[`platform.dist`](https://docs.python.org/3.7/library/platform.html#platform.dist)
-was already deprecated since Python 2.6 and removed in Python 3.8. Still, there
-are many cases in which access to that information is needed. See [Python issue
-1322](https://bugs.python.org/issue1322) for more information.
-
-The `distro` package implements a robust and inclusive way of retrieving the
-information about a distribution based on new standards and old methods,
-namely from these data sources (from high to low precedence):
-
-* The os-release file `/etc/os-release` if present, with a fall-back on `/usr/lib/os-release` if needed.
-* The output of the `lsb_release` command, if available.
-* The distro release file (`/etc/*(-|_)(release|version)`), if present.
-* The `uname` command for BSD based distrubtions.
-
-
-## Python and Distribution Support
-
-`distro` is supported and tested on Python 2.7, 3.4+ and PyPy and on
-any distribution that provides one or more of the data sources
-covered.
-
-This package is tested with test data that mimics the exact behavior of the data sources of [a number of Linux distributions](https://github.com/python-distro/distro/tree/master/tests/resources/distros).
-
-
-## Testing
-
-```shell
-git clone git@github.com:python-distro/distro.git
-cd distro
-pip install tox
-tox
-```
-
-
-## Contributions
-
-Pull requests are always welcome to deal with specific distributions or just
-for general merriment.
-
-See [CONTRIBUTIONS](https://github.com/python-distro/distro/blob/master/CONTRIBUTING.md) for contribution info.
-
-Reference implementations for supporting additional distributions and file
-formats can be found here:
-
-* https://github.com/saltstack/salt/blob/develop/salt/grains/core.py#L1172
-* https://github.com/chef/ohai/blob/master/lib/ohai/plugins/linux/platform.rb
-* https://github.com/ansible/ansible/blob/devel/lib/ansible/module_utils/facts/system/distribution.py
-* https://github.com/puppetlabs/facter/blob/master/lib/src/facts/linux/os_linux.cc
-
-## Package manager distributions
-
-* https://src.fedoraproject.org/rpms/python-distro
-* https://www.archlinux.org/packages/community/any/python-distro/
-* https://launchpad.net/ubuntu/+source/python-distro
-* https://packages.debian.org/sid/python-distro
-* https://packages.gentoo.org/packages/dev-python/distro
-* https://pkgs.org/download/python2-distro
-* https://slackbuilds.org/repository/14.2/python/python-distro/
diff --git a/contrib/python/distro/py2/distro.py b/contrib/python/distro/py2/distro.py
deleted file mode 100644
index 7892741347..0000000000
--- a/contrib/python/distro/py2/distro.py
+++ /dev/null
@@ -1,1386 +0,0 @@
-# Copyright 2015,2016,2017 Nir Cohen
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""
-The ``distro`` package (``distro`` stands for Linux Distribution) provides
-information about the Linux distribution it runs on, such as a reliable
-machine-readable distro ID, or version information.
-
-It is the recommended replacement for Python's original
-:py:func:`platform.linux_distribution` function, but it provides much more
-functionality. An alternative implementation became necessary because Python
-3.5 deprecated this function, and Python 3.8 removed it altogether. Its
-predecessor function :py:func:`platform.dist` was already deprecated since
-Python 2.6 and removed in Python 3.8. Still, there are many cases in which
-access to OS distribution information is needed. See `Python issue 1322
-<https://bugs.python.org/issue1322>`_ for more information.
-"""
-
-import argparse
-import json
-import logging
-import os
-import re
-import shlex
-import subprocess
-import sys
-import warnings
-
-__version__ = "1.6.0"
-
-# Use `if False` to avoid an ImportError on Python 2. After dropping Python 2
-# support, can use typing.TYPE_CHECKING instead. See:
-# https://docs.python.org/3/library/typing.html#typing.TYPE_CHECKING
-if False: # pragma: nocover
- from typing import (
- Any,
- Callable,
- Dict,
- Iterable,
- Optional,
- Sequence,
- TextIO,
- Tuple,
- Type,
- TypedDict,
- Union,
- )
-
- VersionDict = TypedDict(
- "VersionDict", {"major": str, "minor": str, "build_number": str}
- )
- InfoDict = TypedDict(
- "InfoDict",
- {
- "id": str,
- "version": str,
- "version_parts": VersionDict,
- "like": str,
- "codename": str,
- },
- )
-
-
-_UNIXCONFDIR = os.environ.get("UNIXCONFDIR", "/etc")
-_UNIXUSRLIBDIR = os.environ.get("UNIXUSRLIBDIR", "/usr/lib")
-_OS_RELEASE_BASENAME = "os-release"
-
-#: Translation table for normalizing the "ID" attribute defined in os-release
-#: files, for use by the :func:`distro.id` method.
-#:
-#: * Key: Value as defined in the os-release file, translated to lower case,
-#: with blanks translated to underscores.
-#:
-#: * Value: Normalized value.
-NORMALIZED_OS_ID = {
- "ol": "oracle", # Oracle Linux
-}
-
-#: Translation table for normalizing the "Distributor ID" attribute returned by
-#: the lsb_release command, for use by the :func:`distro.id` method.
-#:
-#: * Key: Value as returned by the lsb_release command, translated to lower
-#: case, with blanks translated to underscores.
-#:
-#: * Value: Normalized value.
-NORMALIZED_LSB_ID = {
- "enterpriseenterpriseas": "oracle", # Oracle Enterprise Linux 4
- "enterpriseenterpriseserver": "oracle", # Oracle Linux 5
- "redhatenterpriseworkstation": "rhel", # RHEL 6, 7 Workstation
- "redhatenterpriseserver": "rhel", # RHEL 6, 7 Server
- "redhatenterprisecomputenode": "rhel", # RHEL 6 ComputeNode
-}
-
-#: Translation table for normalizing the distro ID derived from the file name
-#: of distro release files, for use by the :func:`distro.id` method.
-#:
-#: * Key: Value as derived from the file name of a distro release file,
-#: translated to lower case, with blanks translated to underscores.
-#:
-#: * Value: Normalized value.
-NORMALIZED_DISTRO_ID = {
- "redhat": "rhel", # RHEL 6.x, 7.x
-}
-
-# Pattern for content of distro release file (reversed)
-_DISTRO_RELEASE_CONTENT_REVERSED_PATTERN = re.compile(
- r"(?:[^)]*\)(.*)\()? *(?:STL )?([\d.+\-a-z]*\d) *(?:esaeler *)?(.+)"
-)
-
-# Pattern for base file name of distro release file
-_DISTRO_RELEASE_BASENAME_PATTERN = re.compile(r"(\w+)[-_](release|version)$")
-
-# Base file names to be ignored when searching for distro release file
-_DISTRO_RELEASE_IGNORE_BASENAMES = (
- "debian_version",
- "lsb-release",
- "oem-release",
- _OS_RELEASE_BASENAME,
- "system-release",
- "plesk-release",
- "iredmail-release",
-)
-
-
-def linux_distribution(full_distribution_name=True):
- # type: (bool) -> Tuple[str, str, str]
- """
- .. deprecated:: 1.6.0
-
- :func:`distro.linux_distribution()` is deprecated. It should only be
- used as a compatibility shim with Python's
- :py:func:`platform.linux_distribution()`. Please use :func:`distro.id`,
- :func:`distro.version` and :func:`distro.name` instead.
-
- Return information about the current OS distribution as a tuple
- ``(id_name, version, codename)`` with items as follows:
-
- * ``id_name``: If *full_distribution_name* is false, the result of
- :func:`distro.id`. Otherwise, the result of :func:`distro.name`.
-
- * ``version``: The result of :func:`distro.version`.
-
- * ``codename``: The result of :func:`distro.codename`.
-
- The interface of this function is compatible with the original
- :py:func:`platform.linux_distribution` function, supporting a subset of
- its parameters.
-
- The data it returns may not exactly be the same, because it uses more data
- sources than the original function, and that may lead to different data if
- the OS distribution is not consistent across multiple data sources it
- provides (there are indeed such distributions ...).
-
- Another reason for differences is the fact that the :func:`distro.id`
- method normalizes the distro ID string to a reliable machine-readable value
- for a number of popular OS distributions.
- """
- warnings.warn(
- "distro.linux_distribution() is deprecated. It should only be used as a "
- "compatibility shim with Python's platform.linux_distribution(). Please use "
- "distro.id(), distro.version() and distro.name() instead.",
- DeprecationWarning,
- stacklevel=2,
- )
- return _distro.linux_distribution(full_distribution_name)
-
-
-def id():
- # type: () -> str
- """
- Return the distro ID of the current distribution, as a
- machine-readable string.
-
- For a number of OS distributions, the returned distro ID value is
- *reliable*, in the sense that it is documented and that it does not change
- across releases of the distribution.
-
- This package maintains the following reliable distro ID values:
-
- ============== =========================================
- Distro ID Distribution
- ============== =========================================
- "ubuntu" Ubuntu
- "debian" Debian
- "rhel" RedHat Enterprise Linux
- "centos" CentOS
- "fedora" Fedora
- "sles" SUSE Linux Enterprise Server
- "opensuse" openSUSE
- "amazon" Amazon Linux
- "arch" Arch Linux
- "cloudlinux" CloudLinux OS
- "exherbo" Exherbo Linux
- "gentoo" GenToo Linux
- "ibm_powerkvm" IBM PowerKVM
- "kvmibm" KVM for IBM z Systems
- "linuxmint" Linux Mint
- "mageia" Mageia
- "mandriva" Mandriva Linux
- "parallels" Parallels
- "pidora" Pidora
- "raspbian" Raspbian
- "oracle" Oracle Linux (and Oracle Enterprise Linux)
- "scientific" Scientific Linux
- "slackware" Slackware
- "xenserver" XenServer
- "openbsd" OpenBSD
- "netbsd" NetBSD
- "freebsd" FreeBSD
- "midnightbsd" MidnightBSD
- ============== =========================================
-
- If you have a need to get distros for reliable IDs added into this set,
- or if you find that the :func:`distro.id` function returns a different
- distro ID for one of the listed distros, please create an issue in the
- `distro issue tracker`_.
-
- **Lookup hierarchy and transformations:**
-
- First, the ID is obtained from the following sources, in the specified
- order. The first available and non-empty value is used:
-
- * the value of the "ID" attribute of the os-release file,
-
- * the value of the "Distributor ID" attribute returned by the lsb_release
- command,
-
- * the first part of the file name of the distro release file,
-
- The so determined ID value then passes the following transformations,
- before it is returned by this method:
-
- * it is translated to lower case,
-
- * blanks (which should not be there anyway) are translated to underscores,
-
- * a normalization of the ID is performed, based upon
- `normalization tables`_. The purpose of this normalization is to ensure
- that the ID is as reliable as possible, even across incompatible changes
- in the OS distributions. A common reason for an incompatible change is
- the addition of an os-release file, or the addition of the lsb_release
- command, with ID values that differ from what was previously determined
- from the distro release file name.
- """
- return _distro.id()
-
-
-def name(pretty=False):
- # type: (bool) -> str
- """
- Return the name of the current OS distribution, as a human-readable
- string.
-
- If *pretty* is false, the name is returned without version or codename.
- (e.g. "CentOS Linux")
-
- If *pretty* is true, the version and codename are appended.
- (e.g. "CentOS Linux 7.1.1503 (Core)")
-
- **Lookup hierarchy:**
-
- The name is obtained from the following sources, in the specified order.
- The first available and non-empty value is used:
-
- * If *pretty* is false:
-
- - the value of the "NAME" attribute of the os-release file,
-
- - the value of the "Distributor ID" attribute returned by the lsb_release
- command,
-
- - the value of the "<name>" field of the distro release file.
-
- * If *pretty* is true:
-
- - the value of the "PRETTY_NAME" attribute of the os-release file,
-
- - the value of the "Description" attribute returned by the lsb_release
- command,
-
- - the value of the "<name>" field of the distro release file, appended
- with the value of the pretty version ("<version_id>" and "<codename>"
- fields) of the distro release file, if available.
- """
- return _distro.name(pretty)
-
-
-def version(pretty=False, best=False):
- # type: (bool, bool) -> str
- """
- Return the version of the current OS distribution, as a human-readable
- string.
-
- If *pretty* is false, the version is returned without codename (e.g.
- "7.0").
-
- If *pretty* is true, the codename in parenthesis is appended, if the
- codename is non-empty (e.g. "7.0 (Maipo)").
-
- Some distributions provide version numbers with different precisions in
- the different sources of distribution information. Examining the different
- sources in a fixed priority order does not always yield the most precise
- version (e.g. for Debian 8.2, or CentOS 7.1).
-
- The *best* parameter can be used to control the approach for the returned
- version:
-
- If *best* is false, the first non-empty version number in priority order of
- the examined sources is returned.
-
- If *best* is true, the most precise version number out of all examined
- sources is returned.
-
- **Lookup hierarchy:**
-
- In all cases, the version number is obtained from the following sources.
- If *best* is false, this order represents the priority order:
-
- * the value of the "VERSION_ID" attribute of the os-release file,
- * the value of the "Release" attribute returned by the lsb_release
- command,
- * the version number parsed from the "<version_id>" field of the first line
- of the distro release file,
- * the version number parsed from the "PRETTY_NAME" attribute of the
- os-release file, if it follows the format of the distro release files.
- * the version number parsed from the "Description" attribute returned by
- the lsb_release command, if it follows the format of the distro release
- files.
- """
- return _distro.version(pretty, best)
-
-
-def version_parts(best=False):
- # type: (bool) -> Tuple[str, str, str]
- """
- Return the version of the current OS distribution as a tuple
- ``(major, minor, build_number)`` with items as follows:
-
- * ``major``: The result of :func:`distro.major_version`.
-
- * ``minor``: The result of :func:`distro.minor_version`.
-
- * ``build_number``: The result of :func:`distro.build_number`.
-
- For a description of the *best* parameter, see the :func:`distro.version`
- method.
- """
- return _distro.version_parts(best)
-
-
-def major_version(best=False):
- # type: (bool) -> str
- """
- Return the major version of the current OS distribution, as a string,
- if provided.
- Otherwise, the empty string is returned. The major version is the first
- part of the dot-separated version string.
-
- For a description of the *best* parameter, see the :func:`distro.version`
- method.
- """
- return _distro.major_version(best)
-
-
-def minor_version(best=False):
- # type: (bool) -> str
- """
- Return the minor version of the current OS distribution, as a string,
- if provided.
- Otherwise, the empty string is returned. The minor version is the second
- part of the dot-separated version string.
-
- For a description of the *best* parameter, see the :func:`distro.version`
- method.
- """
- return _distro.minor_version(best)
-
-
-def build_number(best=False):
- # type: (bool) -> str
- """
- Return the build number of the current OS distribution, as a string,
- if provided.
- Otherwise, the empty string is returned. The build number is the third part
- of the dot-separated version string.
-
- For a description of the *best* parameter, see the :func:`distro.version`
- method.
- """
- return _distro.build_number(best)
-
-
-def like():
- # type: () -> str
- """
- Return a space-separated list of distro IDs of distributions that are
- closely related to the current OS distribution in regards to packaging
- and programming interfaces, for example distributions the current
- distribution is a derivative from.
-
- **Lookup hierarchy:**
-
- This information item is only provided by the os-release file.
- For details, see the description of the "ID_LIKE" attribute in the
- `os-release man page
- <http://www.freedesktop.org/software/systemd/man/os-release.html>`_.
- """
- return _distro.like()
-
-
-def codename():
- # type: () -> str
- """
- Return the codename for the release of the current OS distribution,
- as a string.
-
- If the distribution does not have a codename, an empty string is returned.
-
- Note that the returned codename is not always really a codename. For
- example, openSUSE returns "x86_64". This function does not handle such
- cases in any special way and just returns the string it finds, if any.
-
- **Lookup hierarchy:**
-
- * the codename within the "VERSION" attribute of the os-release file, if
- provided,
-
- * the value of the "Codename" attribute returned by the lsb_release
- command,
-
- * the value of the "<codename>" field of the distro release file.
- """
- return _distro.codename()
-
-
-def info(pretty=False, best=False):
- # type: (bool, bool) -> InfoDict
- """
- Return certain machine-readable information items about the current OS
- distribution in a dictionary, as shown in the following example:
-
- .. sourcecode:: python
-
- {
- 'id': 'rhel',
- 'version': '7.0',
- 'version_parts': {
- 'major': '7',
- 'minor': '0',
- 'build_number': ''
- },
- 'like': 'fedora',
- 'codename': 'Maipo'
- }
-
- The dictionary structure and keys are always the same, regardless of which
- information items are available in the underlying data sources. The values
- for the various keys are as follows:
-
- * ``id``: The result of :func:`distro.id`.
-
- * ``version``: The result of :func:`distro.version`.
-
- * ``version_parts -> major``: The result of :func:`distro.major_version`.
-
- * ``version_parts -> minor``: The result of :func:`distro.minor_version`.
-
- * ``version_parts -> build_number``: The result of
- :func:`distro.build_number`.
-
- * ``like``: The result of :func:`distro.like`.
-
- * ``codename``: The result of :func:`distro.codename`.
-
- For a description of the *pretty* and *best* parameters, see the
- :func:`distro.version` method.
- """
- return _distro.info(pretty, best)
-
-
-def os_release_info():
- # type: () -> Dict[str, str]
- """
- Return a dictionary containing key-value pairs for the information items
- from the os-release file data source of the current OS distribution.
-
- See `os-release file`_ for details about these information items.
- """
- return _distro.os_release_info()
-
-
-def lsb_release_info():
- # type: () -> Dict[str, str]
- """
- Return a dictionary containing key-value pairs for the information items
- from the lsb_release command data source of the current OS distribution.
-
- See `lsb_release command output`_ for details about these information
- items.
- """
- return _distro.lsb_release_info()
-
-
-def distro_release_info():
- # type: () -> Dict[str, str]
- """
- Return a dictionary containing key-value pairs for the information items
- from the distro release file data source of the current OS distribution.
-
- See `distro release file`_ for details about these information items.
- """
- return _distro.distro_release_info()
-
-
-def uname_info():
- # type: () -> Dict[str, str]
- """
- Return a dictionary containing key-value pairs for the information items
- from the distro release file data source of the current OS distribution.
- """
- return _distro.uname_info()
-
-
-def os_release_attr(attribute):
- # type: (str) -> str
- """
- Return a single named information item from the os-release file data source
- of the current OS distribution.
-
- Parameters:
-
- * ``attribute`` (string): Key of the information item.
-
- Returns:
-
- * (string): Value of the information item, if the item exists.
- The empty string, if the item does not exist.
-
- See `os-release file`_ for details about these information items.
- """
- return _distro.os_release_attr(attribute)
-
-
-def lsb_release_attr(attribute):
- # type: (str) -> str
- """
- Return a single named information item from the lsb_release command output
- data source of the current OS distribution.
-
- Parameters:
-
- * ``attribute`` (string): Key of the information item.
-
- Returns:
-
- * (string): Value of the information item, if the item exists.
- The empty string, if the item does not exist.
-
- See `lsb_release command output`_ for details about these information
- items.
- """
- return _distro.lsb_release_attr(attribute)
-
-
-def distro_release_attr(attribute):
- # type: (str) -> str
- """
- Return a single named information item from the distro release file
- data source of the current OS distribution.
-
- Parameters:
-
- * ``attribute`` (string): Key of the information item.
-
- Returns:
-
- * (string): Value of the information item, if the item exists.
- The empty string, if the item does not exist.
-
- See `distro release file`_ for details about these information items.
- """
- return _distro.distro_release_attr(attribute)
-
-
-def uname_attr(attribute):
- # type: (str) -> str
- """
- Return a single named information item from the distro release file
- data source of the current OS distribution.
-
- Parameters:
-
- * ``attribute`` (string): Key of the information item.
-
- Returns:
-
- * (string): Value of the information item, if the item exists.
- The empty string, if the item does not exist.
- """
- return _distro.uname_attr(attribute)
-
-
-try:
- from functools import cached_property
-except ImportError:
- # Python < 3.8
- class cached_property(object): # type: ignore
- """A version of @property which caches the value. On access, it calls the
- underlying function and sets the value in `__dict__` so future accesses
- will not re-call the property.
- """
-
- def __init__(self, f):
- # type: (Callable[[Any], Any]) -> None
- self._fname = f.__name__
- self._f = f
-
- def __get__(self, obj, owner):
- # type: (Any, Type[Any]) -> Any
- assert obj is not None, "call {} on an instance".format(self._fname)
- ret = obj.__dict__[self._fname] = self._f(obj)
- return ret
-
-
-class LinuxDistribution(object):
- """
- Provides information about a OS distribution.
-
- This package creates a private module-global instance of this class with
- default initialization arguments, that is used by the
- `consolidated accessor functions`_ and `single source accessor functions`_.
- By using default initialization arguments, that module-global instance
- returns data about the current OS distribution (i.e. the distro this
- package runs on).
-
- Normally, it is not necessary to create additional instances of this class.
- However, in situations where control is needed over the exact data sources
- that are used, instances of this class can be created with a specific
- distro release file, or a specific os-release file, or without invoking the
- lsb_release command.
- """
-
- def __init__(
- self,
- include_lsb=True,
- os_release_file="",
- distro_release_file="",
- include_uname=True,
- root_dir=None,
- ):
- # type: (bool, str, str, bool, Optional[str]) -> None
- """
- The initialization method of this class gathers information from the
- available data sources, and stores that in private instance attributes.
- Subsequent access to the information items uses these private instance
- attributes, so that the data sources are read only once.
-
- Parameters:
-
- * ``include_lsb`` (bool): Controls whether the
- `lsb_release command output`_ is included as a data source.
-
- If the lsb_release command is not available in the program execution
- path, the data source for the lsb_release command will be empty.
-
- * ``os_release_file`` (string): The path name of the
- `os-release file`_ that is to be used as a data source.
-
- An empty string (the default) will cause the default path name to
- be used (see `os-release file`_ for details).
-
- If the specified or defaulted os-release file does not exist, the
- data source for the os-release file will be empty.
-
- * ``distro_release_file`` (string): The path name of the
- `distro release file`_ that is to be used as a data source.
-
- An empty string (the default) will cause a default search algorithm
- to be used (see `distro release file`_ for details).
-
- If the specified distro release file does not exist, or if no default
- distro release file can be found, the data source for the distro
- release file will be empty.
-
- * ``include_uname`` (bool): Controls whether uname command output is
- included as a data source. If the uname command is not available in
- the program execution path the data source for the uname command will
- be empty.
-
- * ``root_dir`` (string): The absolute path to the root directory to use
- to find distro-related information files.
-
- Public instance attributes:
-
- * ``os_release_file`` (string): The path name of the
- `os-release file`_ that is actually used as a data source. The
- empty string if no distro release file is used as a data source.
-
- * ``distro_release_file`` (string): The path name of the
- `distro release file`_ that is actually used as a data source. The
- empty string if no distro release file is used as a data source.
-
- * ``include_lsb`` (bool): The result of the ``include_lsb`` parameter.
- This controls whether the lsb information will be loaded.
-
- * ``include_uname`` (bool): The result of the ``include_uname``
- parameter. This controls whether the uname information will
- be loaded.
-
- Raises:
-
- * :py:exc:`IOError`: Some I/O issue with an os-release file or distro
- release file.
-
- * :py:exc:`subprocess.CalledProcessError`: The lsb_release command had
- some issue (other than not being available in the program execution
- path).
-
- * :py:exc:`UnicodeError`: A data source has unexpected characters or
- uses an unexpected encoding.
- """
- self.root_dir = root_dir
- self.etc_dir = os.path.join(root_dir, "etc") if root_dir else _UNIXCONFDIR
- self.usr_lib_dir = (
- os.path.join(root_dir, "usr/lib") if root_dir else _UNIXUSRLIBDIR
- )
-
- if os_release_file:
- self.os_release_file = os_release_file
- else:
- etc_dir_os_release_file = os.path.join(self.etc_dir, _OS_RELEASE_BASENAME)
- usr_lib_os_release_file = os.path.join(
- self.usr_lib_dir, _OS_RELEASE_BASENAME
- )
-
- # NOTE: The idea is to respect order **and** have it set
- # at all times for API backwards compatibility.
- if os.path.isfile(etc_dir_os_release_file) or not os.path.isfile(
- usr_lib_os_release_file
- ):
- self.os_release_file = etc_dir_os_release_file
- else:
- self.os_release_file = usr_lib_os_release_file
-
- self.distro_release_file = distro_release_file or "" # updated later
- self.include_lsb = include_lsb
- self.include_uname = include_uname
-
- def __repr__(self):
- # type: () -> str
- """Return repr of all info"""
- return (
- "LinuxDistribution("
- "os_release_file={self.os_release_file!r}, "
- "distro_release_file={self.distro_release_file!r}, "
- "include_lsb={self.include_lsb!r}, "
- "include_uname={self.include_uname!r}, "
- "_os_release_info={self._os_release_info!r}, "
- "_lsb_release_info={self._lsb_release_info!r}, "
- "_distro_release_info={self._distro_release_info!r}, "
- "_uname_info={self._uname_info!r})".format(self=self)
- )
-
- def linux_distribution(self, full_distribution_name=True):
- # type: (bool) -> Tuple[str, str, str]
- """
- Return information about the OS distribution that is compatible
- with Python's :func:`platform.linux_distribution`, supporting a subset
- of its parameters.
-
- For details, see :func:`distro.linux_distribution`.
- """
- return (
- self.name() if full_distribution_name else self.id(),
- self.version(),
- self.codename(),
- )
-
- def id(self):
- # type: () -> str
- """Return the distro ID of the OS distribution, as a string.
-
- For details, see :func:`distro.id`.
- """
-
- def normalize(distro_id, table):
- # type: (str, Dict[str, str]) -> str
- distro_id = distro_id.lower().replace(" ", "_")
- return table.get(distro_id, distro_id)
-
- distro_id = self.os_release_attr("id")
- if distro_id:
- return normalize(distro_id, NORMALIZED_OS_ID)
-
- distro_id = self.lsb_release_attr("distributor_id")
- if distro_id:
- return normalize(distro_id, NORMALIZED_LSB_ID)
-
- distro_id = self.distro_release_attr("id")
- if distro_id:
- return normalize(distro_id, NORMALIZED_DISTRO_ID)
-
- distro_id = self.uname_attr("id")
- if distro_id:
- return normalize(distro_id, NORMALIZED_DISTRO_ID)
-
- return ""
-
- def name(self, pretty=False):
- # type: (bool) -> str
- """
- Return the name of the OS distribution, as a string.
-
- For details, see :func:`distro.name`.
- """
- name = (
- self.os_release_attr("name")
- or self.lsb_release_attr("distributor_id")
- or self.distro_release_attr("name")
- or self.uname_attr("name")
- )
- if pretty:
- name = self.os_release_attr("pretty_name") or self.lsb_release_attr(
- "description"
- )
- if not name:
- name = self.distro_release_attr("name") or self.uname_attr("name")
- version = self.version(pretty=True)
- if version:
- name = name + " " + version
- return name or ""
-
- def version(self, pretty=False, best=False):
- # type: (bool, bool) -> str
- """
- Return the version of the OS distribution, as a string.
-
- For details, see :func:`distro.version`.
- """
- versions = [
- self.os_release_attr("version_id"),
- self.lsb_release_attr("release"),
- self.distro_release_attr("version_id"),
- self._parse_distro_release_content(self.os_release_attr("pretty_name")).get(
- "version_id", ""
- ),
- self._parse_distro_release_content(
- self.lsb_release_attr("description")
- ).get("version_id", ""),
- self.uname_attr("release"),
- ]
- version = ""
- if best:
- # This algorithm uses the last version in priority order that has
- # the best precision. If the versions are not in conflict, that
- # does not matter; otherwise, using the last one instead of the
- # first one might be considered a surprise.
- for v in versions:
- if v.count(".") > version.count(".") or version == "":
- version = v
- else:
- for v in versions:
- if v != "":
- version = v
- break
- if pretty and version and self.codename():
- version = "{0} ({1})".format(version, self.codename())
- return version
-
- def version_parts(self, best=False):
- # type: (bool) -> Tuple[str, str, str]
- """
- Return the version of the OS distribution, as a tuple of version
- numbers.
-
- For details, see :func:`distro.version_parts`.
- """
- version_str = self.version(best=best)
- if version_str:
- version_regex = re.compile(r"(\d+)\.?(\d+)?\.?(\d+)?")
- matches = version_regex.match(version_str)
- if matches:
- major, minor, build_number = matches.groups()
- return major, minor or "", build_number or ""
- return "", "", ""
-
- def major_version(self, best=False):
- # type: (bool) -> str
- """
- Return the major version number of the current distribution.
-
- For details, see :func:`distro.major_version`.
- """
- return self.version_parts(best)[0]
-
- def minor_version(self, best=False):
- # type: (bool) -> str
- """
- Return the minor version number of the current distribution.
-
- For details, see :func:`distro.minor_version`.
- """
- return self.version_parts(best)[1]
-
- def build_number(self, best=False):
- # type: (bool) -> str
- """
- Return the build number of the current distribution.
-
- For details, see :func:`distro.build_number`.
- """
- return self.version_parts(best)[2]
-
- def like(self):
- # type: () -> str
- """
- Return the IDs of distributions that are like the OS distribution.
-
- For details, see :func:`distro.like`.
- """
- return self.os_release_attr("id_like") or ""
-
- def codename(self):
- # type: () -> str
- """
- Return the codename of the OS distribution.
-
- For details, see :func:`distro.codename`.
- """
- try:
- # Handle os_release specially since distros might purposefully set
- # this to empty string to have no codename
- return self._os_release_info["codename"]
- except KeyError:
- return (
- self.lsb_release_attr("codename")
- or self.distro_release_attr("codename")
- or ""
- )
-
- def info(self, pretty=False, best=False):
- # type: (bool, bool) -> InfoDict
- """
- Return certain machine-readable information about the OS
- distribution.
-
- For details, see :func:`distro.info`.
- """
- return dict(
- id=self.id(),
- version=self.version(pretty, best),
- version_parts=dict(
- major=self.major_version(best),
- minor=self.minor_version(best),
- build_number=self.build_number(best),
- ),
- like=self.like(),
- codename=self.codename(),
- )
-
- def os_release_info(self):
- # type: () -> Dict[str, str]
- """
- Return a dictionary containing key-value pairs for the information
- items from the os-release file data source of the OS distribution.
-
- For details, see :func:`distro.os_release_info`.
- """
- return self._os_release_info
-
- def lsb_release_info(self):
- # type: () -> Dict[str, str]
- """
- Return a dictionary containing key-value pairs for the information
- items from the lsb_release command data source of the OS
- distribution.
-
- For details, see :func:`distro.lsb_release_info`.
- """
- return self._lsb_release_info
-
- def distro_release_info(self):
- # type: () -> Dict[str, str]
- """
- Return a dictionary containing key-value pairs for the information
- items from the distro release file data source of the OS
- distribution.
-
- For details, see :func:`distro.distro_release_info`.
- """
- return self._distro_release_info
-
- def uname_info(self):
- # type: () -> Dict[str, str]
- """
- Return a dictionary containing key-value pairs for the information
- items from the uname command data source of the OS distribution.
-
- For details, see :func:`distro.uname_info`.
- """
- return self._uname_info
-
- def os_release_attr(self, attribute):
- # type: (str) -> str
- """
- Return a single named information item from the os-release file data
- source of the OS distribution.
-
- For details, see :func:`distro.os_release_attr`.
- """
- return self._os_release_info.get(attribute, "")
-
- def lsb_release_attr(self, attribute):
- # type: (str) -> str
- """
- Return a single named information item from the lsb_release command
- output data source of the OS distribution.
-
- For details, see :func:`distro.lsb_release_attr`.
- """
- return self._lsb_release_info.get(attribute, "")
-
- def distro_release_attr(self, attribute):
- # type: (str) -> str
- """
- Return a single named information item from the distro release file
- data source of the OS distribution.
-
- For details, see :func:`distro.distro_release_attr`.
- """
- return self._distro_release_info.get(attribute, "")
-
- def uname_attr(self, attribute):
- # type: (str) -> str
- """
- Return a single named information item from the uname command
- output data source of the OS distribution.
-
- For details, see :func:`distro.uname_attr`.
- """
- return self._uname_info.get(attribute, "")
-
- @cached_property
- def _os_release_info(self):
- # type: () -> Dict[str, str]
- """
- Get the information items from the specified os-release file.
-
- Returns:
- A dictionary containing all information items.
- """
- if os.path.isfile(self.os_release_file):
- with open(self.os_release_file) as release_file:
- return self._parse_os_release_content(release_file)
- return {}
-
- @staticmethod
- def _parse_os_release_content(lines):
- # type: (TextIO) -> Dict[str, str]
- """
- Parse the lines of an os-release file.
-
- Parameters:
-
- * lines: Iterable through the lines in the os-release file.
- Each line must be a unicode string or a UTF-8 encoded byte
- string.
-
- Returns:
- A dictionary containing all information items.
- """
- props = {}
- lexer = shlex.shlex(lines, posix=True)
- lexer.whitespace_split = True
-
- # The shlex module defines its `wordchars` variable using literals,
- # making it dependent on the encoding of the Python source file.
- # In Python 2.6 and 2.7, the shlex source file is encoded in
- # 'iso-8859-1', and the `wordchars` variable is defined as a byte
- # string. This causes a UnicodeDecodeError to be raised when the
- # parsed content is a unicode object. The following fix resolves that
- # (... but it should be fixed in shlex...):
- if sys.version_info[0] == 2 and isinstance(lexer.wordchars, bytes):
- lexer.wordchars = lexer.wordchars.decode("iso-8859-1")
-
- tokens = list(lexer)
- for token in tokens:
- # At this point, all shell-like parsing has been done (i.e.
- # comments processed, quotes and backslash escape sequences
- # processed, multi-line values assembled, trailing newlines
- # stripped, etc.), so the tokens are now either:
- # * variable assignments: var=value
- # * commands or their arguments (not allowed in os-release)
- if "=" in token:
- k, v = token.split("=", 1)
- props[k.lower()] = v
- else:
- # Ignore any tokens that are not variable assignments
- pass
-
- if "version_codename" in props:
- # os-release added a version_codename field. Use that in
- # preference to anything else Note that some distros purposefully
- # do not have code names. They should be setting
- # version_codename=""
- props["codename"] = props["version_codename"]
- elif "ubuntu_codename" in props:
- # Same as above but a non-standard field name used on older Ubuntus
- props["codename"] = props["ubuntu_codename"]
- elif "version" in props:
- # If there is no version_codename, parse it from the version
- match = re.search(r"(\(\D+\))|,(\s+)?\D+", props["version"])
- if match:
- codename = match.group()
- codename = codename.strip("()")
- codename = codename.strip(",")
- codename = codename.strip()
- # codename appears within paranthese.
- props["codename"] = codename
-
- return props
-
- @cached_property
- def _lsb_release_info(self):
- # type: () -> Dict[str, str]
- """
- Get the information items from the lsb_release command output.
-
- Returns:
- A dictionary containing all information items.
- """
- if not self.include_lsb:
- return {}
- with open(os.devnull, "wb") as devnull:
- try:
- cmd = ("lsb_release", "-a")
- stdout = subprocess.check_output(cmd, stderr=devnull)
- # Command not found or lsb_release returned error
- except (OSError, subprocess.CalledProcessError):
- return {}
- content = self._to_str(stdout).splitlines()
- return self._parse_lsb_release_content(content)
-
- @staticmethod
- def _parse_lsb_release_content(lines):
- # type: (Iterable[str]) -> Dict[str, str]
- """
- Parse the output of the lsb_release command.
-
- Parameters:
-
- * lines: Iterable through the lines of the lsb_release output.
- Each line must be a unicode string or a UTF-8 encoded byte
- string.
-
- Returns:
- A dictionary containing all information items.
- """
- props = {}
- for line in lines:
- kv = line.strip("\n").split(":", 1)
- if len(kv) != 2:
- # Ignore lines without colon.
- continue
- k, v = kv
- props.update({k.replace(" ", "_").lower(): v.strip()})
- return props
-
- @cached_property
- def _uname_info(self):
- # type: () -> Dict[str, str]
- with open(os.devnull, "wb") as devnull:
- try:
- cmd = ("uname", "-rs")
- stdout = subprocess.check_output(cmd, stderr=devnull)
- except OSError:
- return {}
- content = self._to_str(stdout).splitlines()
- return self._parse_uname_content(content)
-
- @staticmethod
- def _parse_uname_content(lines):
- # type: (Sequence[str]) -> Dict[str, str]
- props = {}
- match = re.search(r"^([^\s]+)\s+([\d\.]+)", lines[0].strip())
- if match:
- name, version = match.groups()
-
- # This is to prevent the Linux kernel version from
- # appearing as the 'best' version on otherwise
- # identifiable distributions.
- if name == "Linux":
- return {}
- props["id"] = name.lower()
- props["name"] = name
- props["release"] = version
- return props
-
- @staticmethod
- def _to_str(text):
- # type: (Union[bytes, str]) -> str
- encoding = sys.getfilesystemencoding()
- encoding = "utf-8" if encoding == "ascii" else encoding
-
- if sys.version_info[0] >= 3:
- if isinstance(text, bytes):
- return text.decode(encoding)
- else:
- if isinstance(text, unicode): # noqa
- return text.encode(encoding)
-
- return text
-
- @cached_property
- def _distro_release_info(self):
- # type: () -> Dict[str, str]
- """
- Get the information items from the specified distro release file.
-
- Returns:
- A dictionary containing all information items.
- """
- if self.distro_release_file:
- # If it was specified, we use it and parse what we can, even if
- # its file name or content does not match the expected pattern.
- distro_info = self._parse_distro_release_file(self.distro_release_file)
- basename = os.path.basename(self.distro_release_file)
- # The file name pattern for user-specified distro release files
- # is somewhat more tolerant (compared to when searching for the
- # file), because we want to use what was specified as best as
- # possible.
- match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename)
- if "name" in distro_info and "cloudlinux" in distro_info["name"].lower():
- distro_info["id"] = "cloudlinux"
- elif match:
- distro_info["id"] = match.group(1)
- return distro_info
- else:
- try:
- basenames = os.listdir(self.etc_dir)
- # We sort for repeatability in cases where there are multiple
- # distro specific files; e.g. CentOS, Oracle, Enterprise all
- # containing `redhat-release` on top of their own.
- basenames.sort()
- except OSError:
- # This may occur when /etc is not readable but we can't be
- # sure about the *-release files. Check common entries of
- # /etc for information. If they turn out to not be there the
- # error is handled in `_parse_distro_release_file()`.
- basenames = [
- "SuSE-release",
- "arch-release",
- "base-release",
- "centos-release",
- "fedora-release",
- "gentoo-release",
- "mageia-release",
- "mandrake-release",
- "mandriva-release",
- "mandrivalinux-release",
- "manjaro-release",
- "oracle-release",
- "redhat-release",
- "sl-release",
- "slackware-version",
- ]
- for basename in basenames:
- if basename in _DISTRO_RELEASE_IGNORE_BASENAMES:
- continue
- match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename)
- if match:
- filepath = os.path.join(self.etc_dir, basename)
- distro_info = self._parse_distro_release_file(filepath)
- if "name" in distro_info:
- # The name is always present if the pattern matches
- self.distro_release_file = filepath
- distro_info["id"] = match.group(1)
- if "cloudlinux" in distro_info["name"].lower():
- distro_info["id"] = "cloudlinux"
- return distro_info
- return {}
-
- def _parse_distro_release_file(self, filepath):
- # type: (str) -> Dict[str, str]
- """
- Parse a distro release file.
-
- Parameters:
-
- * filepath: Path name of the distro release file.
-
- Returns:
- A dictionary containing all information items.
- """
- try:
- with open(filepath) as fp:
- # Only parse the first line. For instance, on SLES there
- # are multiple lines. We don't want them...
- return self._parse_distro_release_content(fp.readline())
- except (OSError, IOError):
- # Ignore not being able to read a specific, seemingly version
- # related file.
- # See https://github.com/python-distro/distro/issues/162
- return {}
-
- @staticmethod
- def _parse_distro_release_content(line):
- # type: (str) -> Dict[str, str]
- """
- Parse a line from a distro release file.
-
- Parameters:
- * line: Line from the distro release file. Must be a unicode string
- or a UTF-8 encoded byte string.
-
- Returns:
- A dictionary containing all information items.
- """
- matches = _DISTRO_RELEASE_CONTENT_REVERSED_PATTERN.match(line.strip()[::-1])
- distro_info = {}
- if matches:
- # regexp ensures non-None
- distro_info["name"] = matches.group(3)[::-1]
- if matches.group(2):
- distro_info["version_id"] = matches.group(2)[::-1]
- if matches.group(1):
- distro_info["codename"] = matches.group(1)[::-1]
- elif line:
- distro_info["name"] = line.strip()
- return distro_info
-
-
-_distro = LinuxDistribution()
-
-
-def main():
- # type: () -> None
- logger = logging.getLogger(__name__)
- logger.setLevel(logging.DEBUG)
- logger.addHandler(logging.StreamHandler(sys.stdout))
-
- parser = argparse.ArgumentParser(description="OS distro info tool")
- parser.add_argument(
- "--json", "-j", help="Output in machine readable format", action="store_true"
- )
-
- parser.add_argument(
- "--root-dir",
- "-r",
- type=str,
- dest="root_dir",
- help="Path to the root filesystem directory (defaults to /)",
- )
-
- args = parser.parse_args()
-
- if args.root_dir:
- dist = LinuxDistribution(
- include_lsb=False, include_uname=False, root_dir=args.root_dir
- )
- else:
- dist = _distro
-
- if args.json:
- logger.info(json.dumps(dist.info(), indent=4, sort_keys=True))
- else:
- logger.info("Name: %s", dist.name(pretty=True))
- distribution_version = dist.version(pretty=True)
- logger.info("Version: %s", distribution_version)
- distribution_codename = dist.codename()
- logger.info("Codename: %s", distribution_codename)
-
-
-if __name__ == "__main__":
- main()
diff --git a/contrib/python/distro/py2/ya.make b/contrib/python/distro/py2/ya.make
deleted file mode 100644
index e271753611..0000000000
--- a/contrib/python/distro/py2/ya.make
+++ /dev/null
@@ -1,31 +0,0 @@
-# Generated by devtools/yamaker (pypi).
-
-PY2_LIBRARY()
-
-VERSION(1.6.0)
-
-LICENSE(Apache-2.0)
-
-NO_LINT()
-
-PY_SRCS(
- TOP_LEVEL
- distro.py
-)
-
-RESOURCE_FILES(
- PREFIX contrib/python/distro/py2/
- .dist-info/METADATA
- .dist-info/entry_points.txt
- .dist-info/top_level.txt
-)
-
-END()
-
-RECURSE(
- bin
-)
-
-RECURSE_FOR_TESTS(
- tests
-)
diff --git a/contrib/python/distro/py3/LICENSE b/contrib/python/distro/py3/LICENSE
deleted file mode 100644
index e06d208186..0000000000
--- a/contrib/python/distro/py3/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "{}"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright {yyyy} {name of copyright owner}
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
diff --git a/contrib/python/distro/py3/README.md b/contrib/python/distro/py3/README.md
deleted file mode 100644
index de6f3c79d3..0000000000
--- a/contrib/python/distro/py3/README.md
+++ /dev/null
@@ -1,152 +0,0 @@
-Distro - an OS platform information API
-=======================================
-
-[![CI Status](https://github.com/python-distro/distro/workflows/CI/badge.svg)](https://github.com/python-distro/distro/actions/workflows/ci.yaml)
-[![PyPI version](http://img.shields.io/pypi/v/distro.svg)](https://pypi.python.org/pypi/distro)
-[![Supported Python Versions](https://img.shields.io/pypi/pyversions/distro.svg)](https://img.shields.io/pypi/pyversions/distro.svg)
-[![Code Coverage](https://codecov.io/github/python-distro/distro/coverage.svg?branch=master)](https://codecov.io/github/python-distro/distro?branch=master)
-[![Is Wheel](https://img.shields.io/pypi/wheel/distro.svg?style=flat)](https://pypi.python.org/pypi/distro)
-[![Latest Github Release](https://readthedocs.org/projects/distro/badge/?version=stable)](http://distro.readthedocs.io/en/latest/)
-[![Join the chat at https://gitter.im/python-distro/distro](https://badges.gitter.im/python-distro/distro.svg)](https://gitter.im/python-distro/distro?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-
-`distro` provides information about the
-OS distribution it runs on, such as a reliable machine-readable ID, or
-version information.
-
-It is the recommended replacement for Python's original
-[`platform.linux_distribution`](https://docs.python.org/3.7/library/platform.html#platform.linux_distribution)
-function (removed in Python 3.8). It also provides much more functionality
-which isn't necessarily Python bound, like a command-line interface.
-
-Distro currently supports Linux and BSD based systems but [Windows and OS X support](https://github.com/python-distro/distro/issues/177) is also planned.
-
-For Python 2.6 support, see https://github.com/python-distro/distro/tree/python2.6-support
-
-## Installation
-
-Installation of the latest released version from PyPI:
-
-```shell
-pip install distro
-```
-
-Installation of the latest development version:
-
-```shell
-pip install https://github.com/python-distro/distro/archive/master.tar.gz
-```
-
-To use as a standalone script, download `distro.py` directly:
-
-```shell
-curl -O https://raw.githubusercontent.com/python-distro/distro/master/src/distro/distro.py
-python distro.py
-```
-
-``distro`` is safe to vendor within projects that do not wish to add
-dependencies.
-
-```shell
-cd myproject
-curl -O https://raw.githubusercontent.com/python-distro/distro/master/src/distro/distro.py
-```
-
-## Usage
-
-```bash
-$ distro
-Name: Antergos Linux
-Version: 2015.10 (ISO-Rolling)
-Codename: ISO-Rolling
-
-$ distro -j
-{
- "codename": "ISO-Rolling",
- "id": "antergos",
- "like": "arch",
- "version": "16.9",
- "version_parts": {
- "build_number": "",
- "major": "16",
- "minor": "9"
- }
-}
-
-
-$ python
->>> import distro
->>> distro.name(pretty=True)
-'CentOS Linux 8'
->>> distro.id()
-'centos'
->>> distro.version(best=True)
-'8.4.2105'
-```
-
-
-## Documentation
-
-On top of the aforementioned API, several more functions are available. For a complete description of the
-API, see the [latest API documentation](http://distro.readthedocs.org/en/latest/).
-
-## Background
-
-An alternative implementation became necessary because Python 3.5 deprecated
-this function, and Python 3.8 removed it altogether. Its predecessor function
-[`platform.dist`](https://docs.python.org/3.7/library/platform.html#platform.dist)
-was already deprecated since Python 2.6 and removed in Python 3.8. Still, there
-are many cases in which access to that information is needed. See [Python issue
-1322](https://bugs.python.org/issue1322) for more information.
-
-The `distro` package implements a robust and inclusive way of retrieving the
-information about a distribution based on new standards and old methods,
-namely from these data sources (from high to low precedence):
-
-* The os-release file `/etc/os-release` if present, with a fall-back on `/usr/lib/os-release` if needed.
-* The output of the `lsb_release` command, if available.
-* The distro release file (`/etc/*(-|_)(release|version)`), if present.
-* The `uname` command for BSD based distrubtions.
-
-
-## Python and Distribution Support
-
-`distro` is supported and tested on Python 3.6+ and PyPy and on any
-distribution that provides one or more of the data sources covered.
-
-This package is tested with test data that mimics the exact behavior of the data sources of [a number of Linux distributions](https://github.com/python-distro/distro/tree/master/tests/resources/distros).
-
-
-## Testing
-
-```shell
-git clone git@github.com:python-distro/distro.git
-cd distro
-pip install tox
-tox
-```
-
-
-## Contributions
-
-Pull requests are always welcome to deal with specific distributions or just
-for general merriment.
-
-See [CONTRIBUTIONS](https://github.com/python-distro/distro/blob/master/CONTRIBUTING.md) for contribution info.
-
-Reference implementations for supporting additional distributions and file
-formats can be found here:
-
-* https://github.com/saltstack/salt/blob/develop/salt/grains/core.py#L1172
-* https://github.com/chef/ohai/blob/master/lib/ohai/plugins/linux/platform.rb
-* https://github.com/ansible/ansible/blob/devel/lib/ansible/module_utils/facts/system/distribution.py
-* https://github.com/puppetlabs/facter/blob/master/lib/src/facts/linux/os_linux.cc
-
-## Package manager distributions
-
-* https://src.fedoraproject.org/rpms/python-distro
-* https://www.archlinux.org/packages/community/any/python-distro/
-* https://launchpad.net/ubuntu/+source/python-distro
-* https://packages.debian.org/stable/python3-distro
-* https://packages.gentoo.org/packages/dev-python/distro
-* https://pkgs.org/download/python3-distro
-* https://slackbuilds.org/repository/14.2/python/python-distro/
diff --git a/contrib/python/distro/ya.make b/contrib/python/distro/ya.make
deleted file mode 100644
index 82a91a17a2..0000000000
--- a/contrib/python/distro/ya.make
+++ /dev/null
@@ -1,18 +0,0 @@
-PY23_LIBRARY()
-
-LICENSE(Service-Py23-Proxy)
-
-IF (PYTHON2)
- PEERDIR(contrib/python/distro/py2)
-ELSE()
- PEERDIR(contrib/python/distro/py3)
-ENDIF()
-
-NO_LINT()
-
-END()
-
-RECURSE(
- py2
- py3
-)
diff --git a/contrib/python/portalocker/py2/.dist-info/METADATA b/contrib/python/portalocker/py2/.dist-info/METADATA
deleted file mode 100644
index d01a6203e0..0000000000
--- a/contrib/python/portalocker/py2/.dist-info/METADATA
+++ /dev/null
@@ -1,136 +0,0 @@
-Metadata-Version: 2.1
-Name: portalocker
-Version: 1.7.1
-Summary: Wraps the portalocker recipe for easy usage
-Home-page: https://github.com/WoLpH/portalocker
-Author: Rick van Hattem
-Author-email: wolph@wol.ph
-License: PSF
-Keywords: locking,locks,with statement,windows,linux,unix
-Platform: any
-Classifier: Intended Audience :: Developers
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3.3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
-Classifier: Programming Language :: Python :: 3.6
-Classifier: Programming Language :: Python :: Implementation :: CPython
-Classifier: Programming Language :: Python :: Implementation :: PyPy
-Requires-Dist: pywin32 (!=226) ; platform_system == "Windows"
-Provides-Extra: docs
-Requires-Dist: sphinx (>=1.7.1) ; extra == 'docs'
-Provides-Extra: tests
-Requires-Dist: pytest (>=4.6.9) ; extra == 'tests'
-Requires-Dist: pytest-cov (>=2.8.1) ; extra == 'tests'
-Requires-Dist: sphinx (>=1.8.5) ; extra == 'tests'
-Requires-Dist: pytest-flake8 (>=1.0.5) ; extra == 'tests'
-
-############################################
-portalocker - Cross-platform locking library
-############################################
-
-.. image:: https://travis-ci.org/WoLpH/portalocker.svg?branch=master
- :alt: Linux Test Status
- :target: https://travis-ci.org/WoLpH/portalocker
-
-.. image:: https://ci.appveyor.com/api/projects/status/mgqry98hgpy4prhh?svg=true
- :alt: Windows Tests Status
- :target: https://ci.appveyor.com/project/WoLpH/portalocker
-
-.. image:: https://coveralls.io/repos/WoLpH/portalocker/badge.svg?branch=master
- :alt: Coverage Status
- :target: https://coveralls.io/r/WoLpH/portalocker?branch=master
-
-Overview
---------
-
-Portalocker is a library to provide an easy API to file locking.
-
-An important detail to note is that on Linux and Unix systems the locks are
-advisory by default. By specifying the `-o mand` option to the mount command it
-is possible to enable mandatory file locking on Linux. This is generally not
-recommended however. For more information about the subject:
-
- - https://en.wikipedia.org/wiki/File_locking
- - http://stackoverflow.com/questions/39292051/portalocker-does-not-seem-to-lock
- - https://stackoverflow.com/questions/12062466/mandatory-file-lock-on-linux
-
-The module is currently maintained by Rick van Hattem <Wolph@wol.ph>.
-The project resides at https://github.com/WoLpH/portalocker . Bugs and feature
-requests can be submitted there. Patches are also very welcome.
-
-Tips
-----
-
-On some networked filesystems it might be needed to force a `os.fsync()` before
-closing the file so it's actually written before another client reads the file.
-Effectively this comes down to:
-
-::
-
- with portalocker.Lock('some_file', 'rb+', timeout=60) as fh:
- # do what you need to do
- ...
-
- # flush and sync to filesystem
- fh.flush()
- os.fsync(fh.fileno())
-
-Links
------
-
-* Documentation
- - http://portalocker.readthedocs.org/en/latest/
-* Source
- - https://github.com/WoLpH/portalocker
-* Bug reports
- - https://github.com/WoLpH/portalocker/issues
-* Package homepage
- - https://pypi.python.org/pypi/portalocker
-* My blog
- - http://w.wol.ph/
-
-Examples
---------
-
-To make sure your cache generation scripts don't race, use the `Lock` class:
-
->>> import portalocker
->>> with portalocker.Lock('somefile', timeout=1) as fh:
- print >>fh, 'writing some stuff to my cache...'
-
-To customize the opening and locking a manual approach is also possible:
-
->>> import portalocker
->>> file = open('somefile', 'r+')
->>> portalocker.lock(file, portalocker.LOCK_EX)
->>> file.seek(12)
->>> file.write('foo')
->>> file.close()
-
-Explicitly unlocking might not be needed in all cases:
-https://github.com/AzureAD/microsoft-authentication-extensions-for-python/issues/42#issuecomment-601108266
-
-But can be done through:
-
->>> portalocker.unlock(file)
-
-Do note that your data might still be in a buffer so it is possible that your
-data is not available until you `flush()` or `close()`.
-
-More examples can be found in the
-`tests <http://portalocker.readthedocs.io/en/latest/_modules/tests/tests.html>`_.
-
-Changelog
----------
-
-See the `changelog <http://portalocker.readthedocs.io/en/latest/changelog.html>`_ page.
-
-License
--------
-
-See the `LICENSE <https://github.com/WoLpH/portalocker/blob/develop/LICENSE>`_ file.
-
-
-
diff --git a/contrib/python/portalocker/py2/.dist-info/top_level.txt b/contrib/python/portalocker/py2/.dist-info/top_level.txt
deleted file mode 100644
index 7bbc14e6fa..0000000000
--- a/contrib/python/portalocker/py2/.dist-info/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-portalocker
diff --git a/contrib/python/portalocker/py2/LICENSE b/contrib/python/portalocker/py2/LICENSE
deleted file mode 100644
index adb8038169..0000000000
--- a/contrib/python/portalocker/py2/LICENSE
+++ /dev/null
@@ -1,48 +0,0 @@
-PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
---------------------------------------------
-
-1. This LICENSE AGREEMENT is between the Python Software Foundation
-("PSF"), and the Individual or Organization ("Licensee") accessing and
-otherwise using this software ("Python") in source or binary form and
-its associated documentation.
-
-2. Subject to the terms and conditions of this License Agreement, PSF hereby
-grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
-analyze, test, perform and/or display publicly, prepare derivative works,
-distribute, and otherwise use Python alone or in any derivative version,
-provided, however, that PSF's License Agreement and PSF's notice of copyright,
-i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-Python Software Foundation; All Rights Reserved" are retained in Python alone or
-in any derivative version prepared by Licensee.
-
-3. In the event Licensee prepares a derivative work that is based on
-or incorporates Python or any part thereof, and wants to make
-the derivative work available to others as provided herein, then
-Licensee hereby agrees to include in any such work a brief summary of
-the changes made to Python.
-
-4. PSF is making Python available to Licensee on an "AS IS"
-basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
-INFRINGE ANY THIRD PARTY RIGHTS.
-
-5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
-FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
-A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
-OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-6. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-7. Nothing in this License Agreement shall be deemed to create any
-relationship of agency, partnership, or joint venture between PSF and
-Licensee. This License Agreement does not grant permission to use PSF
-trademarks or trade name in a trademark sense to endorse or promote
-products or services of Licensee, or any third party.
-
-8. By copying, installing or otherwise using Python, Licensee
-agrees to be bound by the terms and conditions of this License
-Agreement.
-
diff --git a/contrib/python/portalocker/py2/README.rst b/contrib/python/portalocker/py2/README.rst
deleted file mode 100644
index c013490c76..0000000000
--- a/contrib/python/portalocker/py2/README.rst
+++ /dev/null
@@ -1,106 +0,0 @@
-############################################
-portalocker - Cross-platform locking library
-############################################
-
-.. image:: https://travis-ci.org/WoLpH/portalocker.svg?branch=master
- :alt: Linux Test Status
- :target: https://travis-ci.org/WoLpH/portalocker
-
-.. image:: https://ci.appveyor.com/api/projects/status/mgqry98hgpy4prhh?svg=true
- :alt: Windows Tests Status
- :target: https://ci.appveyor.com/project/WoLpH/portalocker
-
-.. image:: https://coveralls.io/repos/WoLpH/portalocker/badge.svg?branch=master
- :alt: Coverage Status
- :target: https://coveralls.io/r/WoLpH/portalocker?branch=master
-
-Overview
---------
-
-Portalocker is a library to provide an easy API to file locking.
-
-An important detail to note is that on Linux and Unix systems the locks are
-advisory by default. By specifying the `-o mand` option to the mount command it
-is possible to enable mandatory file locking on Linux. This is generally not
-recommended however. For more information about the subject:
-
- - https://en.wikipedia.org/wiki/File_locking
- - http://stackoverflow.com/questions/39292051/portalocker-does-not-seem-to-lock
- - https://stackoverflow.com/questions/12062466/mandatory-file-lock-on-linux
-
-The module is currently maintained by Rick van Hattem <Wolph@wol.ph>.
-The project resides at https://github.com/WoLpH/portalocker . Bugs and feature
-requests can be submitted there. Patches are also very welcome.
-
-Tips
-----
-
-On some networked filesystems it might be needed to force a `os.fsync()` before
-closing the file so it's actually written before another client reads the file.
-Effectively this comes down to:
-
-::
-
- with portalocker.Lock('some_file', 'rb+', timeout=60) as fh:
- # do what you need to do
- ...
-
- # flush and sync to filesystem
- fh.flush()
- os.fsync(fh.fileno())
-
-Links
------
-
-* Documentation
- - http://portalocker.readthedocs.org/en/latest/
-* Source
- - https://github.com/WoLpH/portalocker
-* Bug reports
- - https://github.com/WoLpH/portalocker/issues
-* Package homepage
- - https://pypi.python.org/pypi/portalocker
-* My blog
- - http://w.wol.ph/
-
-Examples
---------
-
-To make sure your cache generation scripts don't race, use the `Lock` class:
-
->>> import portalocker
->>> with portalocker.Lock('somefile', timeout=1) as fh:
- print >>fh, 'writing some stuff to my cache...'
-
-To customize the opening and locking a manual approach is also possible:
-
->>> import portalocker
->>> file = open('somefile', 'r+')
->>> portalocker.lock(file, portalocker.LOCK_EX)
->>> file.seek(12)
->>> file.write('foo')
->>> file.close()
-
-Explicitly unlocking might not be needed in all cases:
-https://github.com/AzureAD/microsoft-authentication-extensions-for-python/issues/42#issuecomment-601108266
-
-But can be done through:
-
->>> portalocker.unlock(file)
-
-Do note that your data might still be in a buffer so it is possible that your
-data is not available until you `flush()` or `close()`.
-
-More examples can be found in the
-`tests <http://portalocker.readthedocs.io/en/latest/_modules/tests/tests.html>`_.
-
-Changelog
----------
-
-See the `changelog <http://portalocker.readthedocs.io/en/latest/changelog.html>`_ page.
-
-License
--------
-
-See the `LICENSE <https://github.com/WoLpH/portalocker/blob/develop/LICENSE>`_ file.
-
diff --git a/contrib/python/portalocker/py2/portalocker/__about__.py b/contrib/python/portalocker/py2/portalocker/__about__.py
deleted file mode 100644
index f16fe0cdf7..0000000000
--- a/contrib/python/portalocker/py2/portalocker/__about__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-__package_name__ = 'portalocker'
-__author__ = 'Rick van Hattem'
-__email__ = 'wolph@wol.ph'
-__version__ = '1.7.1'
-__description__ = '''Wraps the portalocker recipe for easy usage'''
-__url__ = 'https://github.com/WoLpH/portalocker'
-
diff --git a/contrib/python/portalocker/py2/portalocker/__init__.py b/contrib/python/portalocker/py2/portalocker/__init__.py
deleted file mode 100644
index 9bf27fee0f..0000000000
--- a/contrib/python/portalocker/py2/portalocker/__init__.py
+++ /dev/null
@@ -1,67 +0,0 @@
-from . import __about__
-from . import constants
-from . import exceptions
-from . import portalocker
-from . import utils
-
-#: The package name on Pypi
-__package_name__ = __about__.__package_name__
-#: Current author and maintainer, view the git history for the previous ones
-__author__ = __about__.__author__
-#: Current author's email address
-__email__ = __about__.__email__
-#: Version number
-__version__ = '1.7.1'
-#: Package description for Pypi
-__description__ = __about__.__description__
-#: Package homepage
-__url__ = __about__.__url__
-
-
-#: Exception thrown when the file is already locked by someone else
-AlreadyLocked = exceptions.AlreadyLocked
-#: Exception thrown if an error occurred during locking
-LockException = exceptions.LockException
-
-
-#: Lock a file. Note that this is an advisory lock on Linux/Unix systems
-lock = portalocker.lock
-#: Unlock a file
-unlock = portalocker.unlock
-
-#: Place an exclusive lock.
-#: Only one process may hold an exclusive lock for a given file at a given
-#: time.
-LOCK_EX = constants.LOCK_EX
-
-#: Place a shared lock.
-#: More than one process may hold a shared lock for a given file at a given
-#: time.
-LOCK_SH = constants.LOCK_SH
-
-#: Acquire the lock in a non-blocking fashion.
-LOCK_NB = constants.LOCK_NB
-
-#: Remove an existing lock held by this process.
-LOCK_UN = constants.LOCK_UN
-
-#: Locking utility class to automatically handle opening with timeouts and
-#: context wrappers
-Lock = utils.Lock
-RLock = utils.RLock
-TemporaryFileLock = utils.TemporaryFileLock
-open_atomic = utils.open_atomic
-
-__all__ = [
- 'lock',
- 'unlock',
- 'LOCK_EX',
- 'LOCK_SH',
- 'LOCK_NB',
- 'LOCK_UN',
- 'LockException',
- 'Lock',
- 'AlreadyLocked',
- 'open_atomic',
-]
-
diff --git a/contrib/python/portalocker/py2/portalocker/constants.py b/contrib/python/portalocker/py2/portalocker/constants.py
deleted file mode 100644
index fb0927e2da..0000000000
--- a/contrib/python/portalocker/py2/portalocker/constants.py
+++ /dev/null
@@ -1,39 +0,0 @@
-'''
-Locking constants
-
-Lock types:
-
-- `LOCK_EX` exclusive lock
-- `LOCK_SH` shared lock
-
-Lock flags:
-
-- `LOCK_NB` non-blocking
-
-Manually unlock, only needed internally
-
-- `LOCK_UN` unlock
-'''
-import os
-
-# The actual tests will execute the code anyhow so the following code can
-# safely be ignored from the coverage tests
-if os.name == 'nt': # pragma: no cover
- import msvcrt
-
- LOCK_EX = 0x1 #: exclusive lock
- LOCK_SH = 0x2 #: shared lock
- LOCK_NB = 0x4 #: non-blocking
- LOCK_UN = msvcrt.LK_UNLCK #: unlock
-
-elif os.name == 'posix': # pragma: no cover
- import fcntl
-
- LOCK_EX = fcntl.LOCK_EX #: exclusive lock
- LOCK_SH = fcntl.LOCK_SH #: shared lock
- LOCK_NB = fcntl.LOCK_NB #: non-blocking
- LOCK_UN = fcntl.LOCK_UN #: unlock
-
-else: # pragma: no cover
- raise RuntimeError('PortaLocker only defined for nt and posix platforms')
-
diff --git a/contrib/python/portalocker/py2/portalocker/exceptions.py b/contrib/python/portalocker/py2/portalocker/exceptions.py
deleted file mode 100644
index bb2b35eb7b..0000000000
--- a/contrib/python/portalocker/py2/portalocker/exceptions.py
+++ /dev/null
@@ -1,19 +0,0 @@
-class BaseLockException(Exception):
- # Error codes:
- LOCK_FAILED = 1
-
- def __init__(self, *args, **kwargs):
- self.fh = kwargs.pop('fh', None)
- Exception.__init__(self, *args, **kwargs)
-
-
-class LockException(BaseLockException):
- pass
-
-
-class AlreadyLocked(BaseLockException):
- pass
-
-
-class FileToLarge(BaseLockException):
- pass
diff --git a/contrib/python/portalocker/py2/portalocker/portalocker.py b/contrib/python/portalocker/py2/portalocker/portalocker.py
deleted file mode 100644
index 460cf06e47..0000000000
--- a/contrib/python/portalocker/py2/portalocker/portalocker.py
+++ /dev/null
@@ -1,148 +0,0 @@
-import os
-import sys
-from . import exceptions
-from . import constants
-
-
-if os.name == 'nt': # pragma: no cover
- import win32con
- import win32file
- import pywintypes
- import winerror
- import msvcrt
- __overlapped = pywintypes.OVERLAPPED()
-
- if sys.version_info.major == 2:
- lock_length = -1
- else:
- lock_length = int(2**31 - 1)
-
- def lock(file_, flags):
- if flags & constants.LOCK_SH:
- if sys.version_info.major == 2:
- if flags & constants.LOCK_NB:
- mode = win32con.LOCKFILE_FAIL_IMMEDIATELY
- else:
- mode = 0
-
- else:
- if flags & constants.LOCK_NB:
- mode = msvcrt.LK_NBRLCK
- else:
- mode = msvcrt.LK_RLCK
-
- # is there any reason not to reuse the following structure?
- hfile = win32file._get_osfhandle(file_.fileno())
- try:
- win32file.LockFileEx(hfile, mode, 0, -0x10000, __overlapped)
- except pywintypes.error as exc_value:
- # error: (33, 'LockFileEx', 'The process cannot access the file
- # because another process has locked a portion of the file.')
- if exc_value.winerror == winerror.ERROR_LOCK_VIOLATION:
- raise exceptions.LockException(
- exceptions.LockException.LOCK_FAILED,
- exc_value.strerror,
- fh=file_)
- else:
- # Q: Are there exceptions/codes we should be dealing with
- # here?
- raise
- else:
- mode = win32con.LOCKFILE_EXCLUSIVE_LOCK
- if flags & constants.LOCK_NB:
- mode |= win32con.LOCKFILE_FAIL_IMMEDIATELY
-
- if flags & constants.LOCK_NB:
- mode = msvcrt.LK_NBLCK
- else:
- mode = msvcrt.LK_LOCK
-
- # windows locks byte ranges, so make sure to lock from file start
- try:
- savepos = file_.tell()
- if savepos:
- # [ ] test exclusive lock fails on seek here
- # [ ] test if shared lock passes this point
- file_.seek(0)
- # [x] check if 0 param locks entire file (not documented in
- # Python)
- # [x] fails with "IOError: [Errno 13] Permission denied",
- # but -1 seems to do the trick
-
- try:
- msvcrt.locking(file_.fileno(), mode, lock_length)
- except IOError as exc_value:
- # [ ] be more specific here
- raise exceptions.LockException(
- exceptions.LockException.LOCK_FAILED,
- exc_value.strerror,
- fh=file_)
- finally:
- if savepos:
- file_.seek(savepos)
- except IOError as exc_value:
- raise exceptions.LockException(
- exceptions.LockException.LOCK_FAILED, exc_value.strerror,
- fh=file_)
-
- def unlock(file_):
- try:
- savepos = file_.tell()
- if savepos:
- file_.seek(0)
-
- try:
- msvcrt.locking(file_.fileno(), constants.LOCK_UN, lock_length)
- except IOError as exc_value:
- if exc_value.strerror == 'Permission denied':
- hfile = win32file._get_osfhandle(file_.fileno())
- try:
- win32file.UnlockFileEx(
- hfile, 0, -0x10000, __overlapped)
- except pywintypes.error as exc_value:
- if exc_value.winerror == winerror.ERROR_NOT_LOCKED:
- # error: (158, 'UnlockFileEx',
- # 'The segment is already unlocked.')
- # To match the 'posix' implementation, silently
- # ignore this error
- pass
- else:
- # Q: Are there exceptions/codes we should be
- # dealing with here?
- raise
- else:
- raise exceptions.LockException(
- exceptions.LockException.LOCK_FAILED,
- exc_value.strerror,
- fh=file_)
- finally:
- if savepos:
- file_.seek(savepos)
- except IOError as exc_value:
- raise exceptions.LockException(
- exceptions.LockException.LOCK_FAILED, exc_value.strerror,
- fh=file_)
-
-elif os.name == 'posix': # pragma: no cover
- import fcntl
-
- def lock(file_, flags):
- locking_exceptions = IOError,
- try: # pragma: no cover
- locking_exceptions += BlockingIOError,
- except NameError: # pragma: no cover
- pass
-
- try:
- fcntl.flock(file_.fileno(), flags)
- except locking_exceptions as exc_value:
- # The exception code varies on different systems so we'll catch
- # every IO error
- raise exceptions.LockException(exc_value, fh=file_)
-
- def unlock(file_):
- fcntl.flock(file_.fileno(), constants.LOCK_UN)
-
-else: # pragma: no cover
- raise RuntimeError('PortaLocker only defined for nt and posix platforms')
-
diff --git a/contrib/python/portalocker/py2/portalocker/utils.py b/contrib/python/portalocker/py2/portalocker/utils.py
deleted file mode 100644
index 8baebc2b20..0000000000
--- a/contrib/python/portalocker/py2/portalocker/utils.py
+++ /dev/null
@@ -1,256 +0,0 @@
-import os
-import time
-import atexit
-import tempfile
-import contextlib
-from . import exceptions
-from . import constants
-from . import portalocker
-
-current_time = getattr(time, "monotonic", time.time)
-
-DEFAULT_TIMEOUT = 5
-DEFAULT_CHECK_INTERVAL = 0.25
-LOCK_METHOD = constants.LOCK_EX | constants.LOCK_NB
-
-__all__ = [
- 'Lock',
- 'open_atomic',
-]
-
-
-@contextlib.contextmanager
-def open_atomic(filename, binary=True):
- '''Open a file for atomic writing. Instead of locking this method allows
- you to write the entire file and move it to the actual location. Note that
- this makes the assumption that a rename is atomic on your platform which
- is generally the case but not a guarantee.
-
- http://docs.python.org/library/os.html#os.rename
-
- >>> filename = 'test_file.txt'
- >>> if os.path.exists(filename):
- ... os.remove(filename)
-
- >>> with open_atomic(filename) as fh:
- ... written = fh.write(b'test')
- >>> assert os.path.exists(filename)
- >>> os.remove(filename)
-
- '''
- assert not os.path.exists(filename), '%r exists' % filename
- path, name = os.path.split(filename)
-
- # Create the parent directory if it doesn't exist
- if path and not os.path.isdir(path): # pragma: no cover
- os.makedirs(path)
-
- temp_fh = tempfile.NamedTemporaryFile(
- mode=binary and 'wb' or 'w',
- dir=path,
- delete=False,
- )
- yield temp_fh
- temp_fh.flush()
- os.fsync(temp_fh.fileno())
- temp_fh.close()
- try:
- os.rename(temp_fh.name, filename)
- finally:
- try:
- os.remove(temp_fh.name)
- except Exception:
- pass
-
-
-class Lock(object):
-
- def __init__(
- self, filename, mode='a', timeout=DEFAULT_TIMEOUT,
- check_interval=DEFAULT_CHECK_INTERVAL, fail_when_locked=False,
- flags=LOCK_METHOD, **file_open_kwargs):
- '''Lock manager with build-in timeout
-
- filename -- filename
- mode -- the open mode, 'a' or 'ab' should be used for writing
- truncate -- use truncate to emulate 'w' mode, None is disabled, 0 is
- truncate to 0 bytes
- timeout -- timeout when trying to acquire a lock
- check_interval -- check interval while waiting
- fail_when_locked -- after the initial lock failed, return an error
- or lock the file
- **file_open_kwargs -- The kwargs for the `open(...)` call
-
- fail_when_locked is useful when multiple threads/processes can race
- when creating a file. If set to true than the system will wait till
- the lock was acquired and then return an AlreadyLocked exception.
-
- Note that the file is opened first and locked later. So using 'w' as
- mode will result in truncate _BEFORE_ the lock is checked.
- '''
-
- if 'w' in mode:
- truncate = True
- mode = mode.replace('w', 'a')
- else:
- truncate = False
-
- self.fh = None
- self.filename = filename
- self.mode = mode
- self.truncate = truncate
- self.timeout = timeout
- self.check_interval = check_interval
- self.fail_when_locked = fail_when_locked
- self.flags = flags
- self.file_open_kwargs = file_open_kwargs
-
- def acquire(
- self, timeout=None, check_interval=None, fail_when_locked=None):
- '''Acquire the locked filehandle'''
- if timeout is None:
- timeout = self.timeout
- if timeout is None:
- timeout = 0
-
- if check_interval is None:
- check_interval = self.check_interval
-
- if fail_when_locked is None:
- fail_when_locked = self.fail_when_locked
-
- # If we already have a filehandle, return it
- fh = self.fh
- if fh:
- return fh
-
- # Get a new filehandler
- fh = self._get_fh()
- try:
- # Try to lock
- fh = self._get_lock(fh)
- except exceptions.LockException as exception:
- # Try till the timeout has passed
- timeoutend = current_time() + timeout
- while timeoutend > current_time():
- # Wait a bit
- time.sleep(check_interval)
-
- # Try again
- try:
-
- # We already tried to the get the lock
- # If fail_when_locked is true, then stop trying
- if fail_when_locked:
- raise exceptions.AlreadyLocked(exception)
-
- else: # pragma: no cover
- # We've got the lock
- fh = self._get_lock(fh)
- break
-
- except exceptions.LockException:
- pass
-
- else:
- fh.close()
- # We got a timeout... reraising
- raise exceptions.LockException(exception)
-
- # Prepare the filehandle (truncate if needed)
- fh = self._prepare_fh(fh)
-
- self.fh = fh
- return fh
-
- def release(self):
- '''Releases the currently locked file handle'''
- if self.fh:
- portalocker.unlock(self.fh)
- self.fh.close()
- self.fh = None
-
- def _get_fh(self):
- '''Get a new filehandle'''
- return open(self.filename, self.mode, **self.file_open_kwargs)
-
- def _get_lock(self, fh):
- '''
- Try to lock the given filehandle
-
- returns LockException if it fails'''
- portalocker.lock(fh, self.flags)
- return fh
-
- def _prepare_fh(self, fh):
- '''
- Prepare the filehandle for usage
-
- If truncate is a number, the file will be truncated to that amount of
- bytes
- '''
- if self.truncate:
- fh.seek(0)
- fh.truncate(0)
-
- return fh
-
- def __enter__(self):
- return self.acquire()
-
- def __exit__(self, type_, value, tb):
- self.release()
-
- def __delete__(self, instance): # pragma: no cover
- instance.release()
-
-
-class RLock(Lock):
- """
- A reentrant lock, functions in a similar way to threading.RLock in that it
- can be acquired multiple times. When the corresponding number of release()
- calls are made the lock will finally release the underlying file lock.
- """
- def __init__(
- self, filename, mode='a', timeout=DEFAULT_TIMEOUT,
- check_interval=DEFAULT_CHECK_INTERVAL, fail_when_locked=False,
- flags=LOCK_METHOD):
- super(RLock, self).__init__(filename, mode, timeout, check_interval,
- fail_when_locked, flags)
- self._acquire_count = 0
-
- def acquire(
- self, timeout=None, check_interval=None, fail_when_locked=None):
- if self._acquire_count >= 1:
- fh = self.fh
- else:
- fh = super(RLock, self).acquire(timeout, check_interval,
- fail_when_locked)
- self._acquire_count += 1
- return fh
-
- def release(self):
- if self._acquire_count == 0:
- raise exceptions.LockException(
- "Cannot release more times than acquired")
-
- if self._acquire_count == 1:
- super(RLock, self).release()
- self._acquire_count -= 1
-
-
-class TemporaryFileLock(Lock):
-
- def __init__(self, filename='.lock', timeout=DEFAULT_TIMEOUT,
- check_interval=DEFAULT_CHECK_INTERVAL, fail_when_locked=True,
- flags=LOCK_METHOD):
-
- Lock.__init__(self, filename=filename, mode='w', timeout=timeout,
- check_interval=check_interval,
- fail_when_locked=fail_when_locked, flags=flags)
- atexit.register(self.release)
-
- def release(self):
- Lock.release(self)
- if os.path.isfile(self.filename): # pragma: no branch
- os.unlink(self.filename)
diff --git a/contrib/python/portalocker/py2/ya.make b/contrib/python/portalocker/py2/ya.make
deleted file mode 100644
index 0cf6513704..0000000000
--- a/contrib/python/portalocker/py2/ya.make
+++ /dev/null
@@ -1,31 +0,0 @@
-# Generated by devtools/yamaker (pypi).
-
-PY2_LIBRARY()
-
-VERSION(1.7.1)
-
-LICENSE(PSF-2.0)
-
-NO_LINT()
-
-PY_SRCS(
- TOP_LEVEL
- portalocker/__about__.py
- portalocker/__init__.py
- portalocker/constants.py
- portalocker/exceptions.py
- portalocker/portalocker.py
- portalocker/utils.py
-)
-
-RESOURCE_FILES(
- PREFIX contrib/python/portalocker/py2/
- .dist-info/METADATA
- .dist-info/top_level.txt
-)
-
-END()
-
-RECURSE(
- tests
-)
diff --git a/contrib/python/portalocker/py3/LICENSE b/contrib/python/portalocker/py3/LICENSE
deleted file mode 100644
index b638bda0d3..0000000000
--- a/contrib/python/portalocker/py3/LICENSE
+++ /dev/null
@@ -1,11 +0,0 @@
-Copyright 2022 Rick van Hattem
-
-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.
-
-3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
diff --git a/contrib/python/portalocker/py3/README.rst b/contrib/python/portalocker/py3/README.rst
deleted file mode 100644
index c5ef42f614..0000000000
--- a/contrib/python/portalocker/py3/README.rst
+++ /dev/null
@@ -1,193 +0,0 @@
-############################################
-portalocker - Cross-platform locking library
-############################################
-
-.. image:: https://github.com/WoLpH/portalocker/actions/workflows/python-package.yml/badge.svg?branch=master
- :alt: Linux Test Status
- :target: https://github.com/WoLpH/portalocker/actions/
-
-.. image:: https://ci.appveyor.com/api/projects/status/mgqry98hgpy4prhh?svg=true
- :alt: Windows Tests Status
- :target: https://ci.appveyor.com/project/WoLpH/portalocker
-
-.. image:: https://coveralls.io/repos/WoLpH/portalocker/badge.svg?branch=master
- :alt: Coverage Status
- :target: https://coveralls.io/r/WoLpH/portalocker?branch=master
-
-Overview
---------
-
-Portalocker is a library to provide an easy API to file locking.
-
-An important detail to note is that on Linux and Unix systems the locks are
-advisory by default. By specifying the `-o mand` option to the mount command it
-is possible to enable mandatory file locking on Linux. This is generally not
-recommended however. For more information about the subject:
-
- - https://en.wikipedia.org/wiki/File_locking
- - http://stackoverflow.com/questions/39292051/portalocker-does-not-seem-to-lock
- - https://stackoverflow.com/questions/12062466/mandatory-file-lock-on-linux
-
-The module is currently maintained by Rick van Hattem <Wolph@wol.ph>.
-The project resides at https://github.com/WoLpH/portalocker . Bugs and feature
-requests can be submitted there. Patches are also very welcome.
-
-Security contact information
-------------------------------------------------------------------------------
-
-To report a security vulnerability, please use the
-`Tidelift security contact <https://tidelift.com/security>`_.
-Tidelift will coordinate the fix and disclosure.
-
-Redis Locks
------------
-
-This library now features a lock based on Redis which allows for locks across
-multiple threads, processes and even distributed locks across multiple
-computers.
-
-It is an extremely reliable Redis lock that is based on pubsub.
-
-As opposed to most Redis locking systems based on key/value pairs,
-this locking method is based on the pubsub system. The big advantage is
-that if the connection gets killed due to network issues, crashing
-processes or otherwise, it will still immediately unlock instead of
-waiting for a lock timeout.
-
-First make sure you have everything installed correctly:
-
-::
-
- pip install "portalocker[redis]"
-
-Usage is really easy:
-
-::
-
- import portalocker
-
- lock = portalocker.RedisLock('some_lock_channel_name')
-
- with lock:
- print('do something here')
-
-The API is essentially identical to the other ``Lock`` classes so in addition
-to the ``with`` statement you can also use ``lock.acquire(...)``.
-
-Python 2
---------
-
-Python 2 was supported in versions before Portalocker 2.0. If you are still
-using
-Python 2,
-you can run this to install:
-
-::
-
- pip install "portalocker<2"
-
-Tips
-----
-
-On some networked filesystems it might be needed to force a `os.fsync()` before
-closing the file so it's actually written before another client reads the file.
-Effectively this comes down to:
-
-::
-
- with portalocker.Lock('some_file', 'rb+', timeout=60) as fh:
- # do what you need to do
- ...
-
- # flush and sync to filesystem
- fh.flush()
- os.fsync(fh.fileno())
-
-Links
------
-
-* Documentation
- - http://portalocker.readthedocs.org/en/latest/
-* Source
- - https://github.com/WoLpH/portalocker
-* Bug reports
- - https://github.com/WoLpH/portalocker/issues
-* Package homepage
- - https://pypi.python.org/pypi/portalocker
-* My blog
- - http://w.wol.ph/
-
-Examples
---------
-
-To make sure your cache generation scripts don't race, use the `Lock` class:
-
->>> import portalocker
->>> with portalocker.Lock('somefile', timeout=1) as fh:
-... print('writing some stuff to my cache...', file=fh)
-
-To customize the opening and locking a manual approach is also possible:
-
->>> import portalocker
->>> file = open('somefile', 'r+')
->>> portalocker.lock(file, portalocker.LockFlags.EXCLUSIVE)
->>> file.seek(12)
->>> file.write('foo')
->>> file.close()
-
-Explicitly unlocking is not needed in most cases but omitting it has been known
-to cause issues:
-https://github.com/AzureAD/microsoft-authentication-extensions-for-python/issues/42#issuecomment-601108266
-
-If needed, it can be done through:
-
->>> portalocker.unlock(file)
-
-Do note that your data might still be in a buffer so it is possible that your
-data is not available until you `flush()` or `close()`.
-
-To create a cross platform bounded semaphore across multiple processes you can
-use the `BoundedSemaphore` class which functions somewhat similar to
-`threading.BoundedSemaphore`:
-
->>> import portalocker
->>> n = 2
->>> timeout = 0.1
-
->>> semaphore_a = portalocker.BoundedSemaphore(n, timeout=timeout)
->>> semaphore_b = portalocker.BoundedSemaphore(n, timeout=timeout)
->>> semaphore_c = portalocker.BoundedSemaphore(n, timeout=timeout)
-
->>> semaphore_a.acquire()
-<portalocker.utils.Lock object at ...>
->>> semaphore_b.acquire()
-<portalocker.utils.Lock object at ...>
->>> semaphore_c.acquire()
-Traceback (most recent call last):
- ...
-portalocker.exceptions.AlreadyLocked
-
-
-More examples can be found in the
-`tests <http://portalocker.readthedocs.io/en/latest/_modules/tests/tests.html>`_.
-
-
-Versioning
-----------
-
-This library follows `Semantic Versioning <http://semver.org/>`_.
-
-
-Changelog
----------
-
-Every release has a ``git tag`` with a commit message for the tag
-explaining what was added and/or changed. The list of tags/releases
-including the commit messages can be found here:
-https://github.com/WoLpH/portalocker/releases
-
-License
--------
-
-See the `LICENSE <https://github.com/WoLpH/portalocker/blob/develop/LICENSE>`_ file.
-
diff --git a/contrib/python/portalocker/ya.make b/contrib/python/portalocker/ya.make
deleted file mode 100644
index 4012370b1c..0000000000
--- a/contrib/python/portalocker/ya.make
+++ /dev/null
@@ -1,18 +0,0 @@
-PY23_LIBRARY()
-
-LICENSE(Service-Py23-Proxy)
-
-IF (PYTHON2)
- PEERDIR(contrib/python/portalocker/py2)
-ELSE()
- PEERDIR(contrib/python/portalocker/py3)
-ENDIF()
-
-NO_LINT()
-
-END()
-
-RECURSE(
- py2
- py3
-)
diff --git a/contrib/python/python-libarchive/libarchive/__init__.py b/contrib/python/python-libarchive/libarchive/__init__.py
deleted file mode 100644
index 0c0c63359a..0000000000
--- a/contrib/python/python-libarchive/libarchive/__init__.py
+++ /dev/null
@@ -1,800 +0,0 @@
-# Copyright (c) 2011, SmartFile <btimby@smartfile.com>
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-# * Neither the name of the organization nor the
-# names of its contributors may be used to endorse or promote products
-# derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
-
-import os
-import stat
-import sys
-import math
-import time
-import logging
-import warnings
-
-import contextlib2
-
-from libarchive import _libarchive
-import six
-
-logger = logging.getLogger(__name__)
-
-# Suggested block size for libarchive. Libarchive may adjust it.
-BLOCK_SIZE = 10240
-
-MTIME_FORMAT = ''
-
-# Default encoding scheme.
-ENCODING = 'utf-8'
-
-if six.PY2:
- def encode(value, encoding):
- if type(value) == str:
- value = value.decode(encoding, errors='ignore')
- return value.encode(encoding)
-else:
- def encode(value, encoding):
- return value.encode(encoding)
-
-
-# Functions to initialize read/write for various libarchive supported formats and filters.
-FORMATS = {
- None: (_libarchive.archive_read_support_format_all, None),
- 'tar': (_libarchive.archive_read_support_format_tar, _libarchive.archive_write_set_format_ustar),
- 'pax': (_libarchive.archive_read_support_format_tar, _libarchive.archive_write_set_format_pax),
- 'gnu': (_libarchive.archive_read_support_format_gnutar, _libarchive.archive_write_set_format_gnutar),
- 'zip': (_libarchive.archive_read_support_format_zip, _libarchive.archive_write_set_format_zip),
- 'rar': (_libarchive.archive_read_support_format_rar, None),
- '7zip': (_libarchive.archive_read_support_format_7zip, None),
- 'ar': (_libarchive.archive_read_support_format_ar, None),
- 'cab': (_libarchive.archive_read_support_format_cab, None),
- 'cpio': (_libarchive.archive_read_support_format_cpio, _libarchive.archive_write_set_format_cpio_newc),
- 'iso': (_libarchive.archive_read_support_format_iso9660, _libarchive.archive_write_set_format_iso9660),
- 'lha': (_libarchive.archive_read_support_format_lha, None),
- 'xar': (_libarchive.archive_read_support_format_xar, _libarchive.archive_write_set_format_xar),
-}
-
-FILTERS = {
- None: (_libarchive.archive_read_support_filter_all, _libarchive.archive_write_add_filter_none),
- 'bzip2': (_libarchive.archive_read_support_filter_bzip2, _libarchive.archive_write_add_filter_bzip2),
- 'gzip': (_libarchive.archive_read_support_filter_gzip, _libarchive.archive_write_add_filter_gzip),
- 'zstd': (_libarchive.archive_read_support_filter_zstd, _libarchive.archive_write_add_filter_zstd),
-}
-
-# Map file extensions to formats and filters. To support quick detection.
-FORMAT_EXTENSIONS = {
- '.tar': 'tar',
- '.zip': 'zip',
- '.rar': 'rar',
- '.7z': '7zip',
- '.ar': 'ar',
- '.cab': 'cab',
- '.rpm': 'cpio',
- '.cpio': 'cpio',
- '.iso': 'iso',
- '.lha': 'lha',
- '.xar': 'xar',
-}
-FILTER_EXTENSIONS = {
- '.bz2': 'bzip2',
- '.gz': 'gzip',
- '.zst': 'zstd',
-}
-
-
-class EOF(Exception):
- '''Raised by ArchiveInfo.from_archive() when unable to read the next
- archive header.'''
- pass
-
-
-def get_error(archive):
- '''Retrieves the last error description for the given archive instance.'''
- return _libarchive.archive_error_string(archive)
-
-
-def call_and_check(func, archive, *args):
- '''Executes a libarchive function and raises an exception when appropriate.'''
- ret = func(*args)
- if ret == _libarchive.ARCHIVE_OK:
- return
- elif ret == _libarchive.ARCHIVE_WARN:
- warnings.warn('Warning executing function: %s.' % get_error(archive), RuntimeWarning)
- elif ret == _libarchive.ARCHIVE_EOF:
- raise EOF()
- else:
- raise Exception('Fatal error executing function, message is: %s.' % get_error(archive))
-
-
-def get_func(name, items, index):
- item = items.get(name, None)
- if item is None:
- return None
- return item[index]
-
-
-def guess_format(filename):
- filename, ext = os.path.splitext(filename)
- filter = FILTER_EXTENSIONS.get(ext)
- if filter:
- filename, ext = os.path.splitext(filename)
- format = FORMAT_EXTENSIONS.get(ext)
- return format, filter
-
-
-def is_archive_name(filename, formats=None):
- '''Quick check to see if the given file has an extension indiciating that it is
- an archive. The format parameter can be used to limit what archive format is acceptable.
- If omitted, all supported archive formats will be checked.
-
- This function will return the name of the most likely archive format, None if the file is
- unlikely to be an archive.'''
- if formats is None:
- formats = FORMAT_EXTENSIONS.values()
- format, filter = guess_format(filename)
- if format in formats:
- return format
-
-
-def is_archive(f, formats=(None, ), filters=(None, )):
- '''Check to see if the given file is actually an archive. The format parameter
- can be used to specify which archive format is acceptable. If ommitted, all supported
- archive formats will be checked. It opens the file using libarchive. If no error is
- received, the file was successfully detected by the libarchive bidding process.
-
- This procedure is quite costly, so you should avoid calling it unless you are reasonably
- sure that the given file is an archive. In other words, you may wish to filter large
- numbers of file names using is_archive_name() before double-checking the positives with
- this function.
-
- This function will return True if the file can be opened as an archive using the given
- format(s)/filter(s).'''
- with contextlib2.ExitStack() as exit_stack:
- if isinstance(f, six.string_types):
- f = exit_stack.enter_context(open(f, 'rb'))
- a = _libarchive.archive_read_new()
- for format in formats:
- format = get_func(format, FORMATS, 0)
- if format is None:
- return False
- format(a)
- for filter in filters:
- filter = get_func(filter, FILTERS, 0)
- if filter is None:
- return False
- filter(a)
- try:
- try:
- call_and_check(_libarchive.archive_read_open_fd, a, a, f.fileno(), BLOCK_SIZE)
- return True
- except:
- return False
- finally:
- _libarchive.archive_read_close(a)
- _libarchive.archive_read_free(a)
-
-
-def get_archive_filter_names(filename):
- with open(filename, 'rb') as afile:
- a = _libarchive.archive_read_new()
- try:
- format_func = get_func(None, FORMATS, 0)
- format_func(a)
- filter_func = get_func(None, FILTERS, 0)
- filter_func(a)
- if _libarchive.archive_read_open_fd(a, afile.fileno(), BLOCK_SIZE) == _libarchive.ARCHIVE_OK:
- try:
- nfilter = _libarchive.archive_filter_count(a)
- return [_libarchive.archive_filter_name(a, i).decode(ENCODING) for i in range(nfilter)]
- finally:
- _libarchive.archive_read_close(a)
- finally:
- _libarchive.archive_read_free(a)
- return []
-
-
-class EntryReadStream(object):
- '''A file-like object for reading an entry from the archive.'''
- def __init__(self, archive, size):
- self.archive = archive
- self.closed = False
- self.size = size
- self.bytes = 0
-
- def __enter__(self):
- return self
-
- def __exit__(self, *args):
- return
-
- def __iter__(self):
- if self.closed:
- return
- while True:
- data = self.read(BLOCK_SIZE)
- if not data:
- break
- yield data
-
- def __len__(self):
- return self.size
-
- def tell(self):
- return self.bytes
-
- def read(self, bytes=-1):
- if self.closed:
- return
- if self.bytes == self.size:
- # EOF already reached.
- return
- if bytes < 0:
- bytes = self.size - self.bytes
- elif self.bytes + bytes > self.size:
- # Limit read to remaining bytes
- bytes = self.size - self.bytes
- # Read requested bytes
- data = _libarchive.archive_read_data_into_str(self.archive._a, bytes)
- self.bytes += len(data)
- return data
-
- def close(self):
- if self.closed:
- return
- # Call archive.close() with _defer True to let it know we have been
- # closed and it is now safe to actually close.
- self.archive.close(_defer=True)
- self.archive = None
- self.closed = True
-
-
-class EntryWriteStream(object):
- '''A file-like object for writing an entry to an archive.
-
- If the size is known ahead of time and provided, then the file contents
- are not buffered but flushed directly to the archive. If size is omitted,
- then the file contents are buffered and flushed in the close() method.'''
- def __init__(self, archive, pathname, size=None):
- self.archive = archive
- self.entry = Entry(pathname=pathname, mtime=time.time(), mode=stat.S_IFREG)
- if size is None:
- self.buffer = six.StringIO()
- else:
- self.buffer = None
- self.entry.size = size
- self.entry.to_archive(self.archive)
- self.bytes = 0
- self.closed = False
-
- def __enter__(self):
- return self
-
- def __exit__(self, *args):
- self.close()
-
- def __del__(self):
- self.close()
-
- def __len__(self):
- return self.bytes
-
- def tell(self):
- return self.bytes
-
- def write(self, data):
- if self.closed:
- raise Exception('Cannot write to closed stream.')
- if self.buffer:
- self.buffer.write(data)
- else:
- _libarchive.archive_write_data_from_str(self.archive._a, data)
- self.bytes += len(data)
-
- def close(self):
- if self.closed:
- return
- if self.buffer:
- self.entry.size = self.buffer.tell()
- self.entry.to_archive(self.archive)
- _libarchive.archive_write_data_from_str(self.archive._a, self.buffer.getvalue())
- _libarchive.archive_write_finish_entry(self.archive._a)
-
- # Call archive.close() with _defer True to let it know we have been
- # closed and it is now safe to actually close.
- self.archive.close(_defer=True)
- self.archive = None
- self.closed = True
-
-
-class Entry(object):
- '''An entry within an archive. Represents the header data and it's location within the archive.'''
- def __init__(self, pathname=None, size=None, mtime=None, mode=None, hpos=None, encoding=ENCODING):
- self.pathname = pathname
- self.size = size
- self.mtime = mtime
- self.mode = mode
- self.hpos = hpos
- self.encoding = encoding
- self.linkname = None
- self.id = None
- self.hardlink = None
-
- @property
- def header_position(self):
- return self.hpos
-
- @classmethod
- def from_archive(cls, archive, encoding=ENCODING):
- '''Instantiates an Entry class and sets all the properties from an archive header.'''
- e = _libarchive.archive_entry_new()
- try:
- call_and_check(_libarchive.archive_read_next_header2, archive._a, archive._a, e)
- mode = _libarchive.archive_entry_filetype(e)
- mode |= _libarchive.archive_entry_perm(e)
- mtime = _libarchive.archive_entry_mtime(e) + _libarchive.archive_entry_mtime_nsec(e) / 1000000000.0
- # use current time as mtime if stored mtime is equal to 0
- mtime = mtime or time.time()
- entry = cls(
- pathname=_libarchive.archive_entry_pathname(e).decode(encoding),
- size=_libarchive.archive_entry_size(e),
- mtime=mtime,
- mode=mode,
- hpos=archive.header_position,
- )
- # check hardlinkness first to processes hardlinks to the symlinks correctly
- hardlink = _libarchive.archive_entry_hardlink(e)
- if hardlink:
- entry.hardlink = hardlink
- elif entry.issym():
- entry.linkname = _libarchive.archive_entry_symlink(e)
- finally:
- _libarchive.archive_entry_free(e)
- return entry
-
- @classmethod
- def from_file(cls, f, entry=None, encoding=ENCODING, mtime=None):
- '''Instantiates an Entry class and sets all the properties from a file on the file system.
- f can be a file-like object or a path.'''
- if entry is None:
- entry = cls(encoding=encoding)
- if entry.pathname is None:
- if isinstance(f, six.string_types):
- st = os.lstat(f)
- entry.pathname = f
- entry.size = st.st_size
- entry.mtime = st.st_mtime if mtime is None else mtime
- entry.mode = st.st_mode
- entry.id = cls.get_entry_id(st)
- if entry.issym():
- entry.linkname = os.readlink(f)
- elif hasattr(f, 'fileno'):
- st = os.fstat(f.fileno())
- entry.pathname = getattr(f, 'name', None)
- entry.size = st.st_size
- entry.mtime = st.st_mtime if mtime is None else mtime
- entry.mode = st.st_mode
- entry.id = cls.get_entry_id(st)
- else:
- entry.pathname = getattr(f, 'pathname', None)
- entry.size = getattr(f, 'size', 0)
- entry.mtime = getattr(f, 'mtime', time.time()) if mtime is None else mtime
- entry.mode = getattr(f, 'mode', stat.S_IFREG)
- return entry
-
- @staticmethod
- def get_entry_id(st):
- # windows doesn't have such information
- if st.st_ino and st.st_dev:
- return (st.st_dev, st.st_ino)
- return None
-
- def to_archive(self, archive):
- '''Creates an archive header and writes it to the given archive.'''
- e = _libarchive.archive_entry_new()
- try:
- _libarchive.archive_entry_set_pathname(e, encode(self.pathname, self.encoding))
- _libarchive.archive_entry_set_filetype(e, stat.S_IFMT(self.mode))
- _libarchive.archive_entry_set_perm(e, stat.S_IMODE(self.mode))
-
- nsec, sec = math.modf(self.mtime)
- nsec *= 1000000000
- _libarchive.archive_entry_set_mtime(e, int(sec), int(nsec))
-
- if self.ishardlink():
- _libarchive.archive_entry_set_size(e, 0)
- _libarchive.archive_entry_set_hardlink(e, encode(self.hardlink, self.encoding))
- elif self.issym():
- _libarchive.archive_entry_set_size(e, 0)
- _libarchive.archive_entry_set_symlink(e, encode(self.linkname, self.encoding))
- else:
- _libarchive.archive_entry_set_size(e, self.size)
- call_and_check(_libarchive.archive_write_header, archive._a, archive._a, e)
- #self.hpos = archive.header_position
- finally:
- _libarchive.archive_entry_free(e)
-
- def isdir(self):
- return stat.S_ISDIR(self.mode)
-
- def isfile(self):
- return stat.S_ISREG(self.mode)
-
- def issym(self):
- return stat.S_ISLNK(self.mode)
-
- def isfifo(self):
- return stat.S_ISFIFO(self.mode)
-
- def ischr(self):
- return stat.S_ISCHR(self.mode)
-
- def isblk(self):
- return stat.S_ISBLK(self.mode)
-
- def ishardlink(self):
- return bool(self.hardlink)
-
-
-class Archive(object):
- '''A low-level archive reader which provides forward-only iteration. Consider
- this a light-weight pythonic libarchive wrapper.'''
- def __init__(self, f, mode='rb', format=None, filter=None, entry_class=Entry, encoding=ENCODING, blocksize=BLOCK_SIZE, filter_opts=None, format_opts=None, fsync=False, fixed_mtime=None):
- if six.PY2:
- assert mode in ('r', 'rb', 'w', 'wb', 'a', 'ab'), 'Mode should be "r[b]", "w[b]" or "a[b]".'
- else:
- assert mode in ('rb', 'wb', 'ab'), 'Mode should be "rb", "wb", or "ab".'
- self._stream = None
- self.encoding = encoding
- self.blocksize = blocksize
- self.file_handle = None
- self.fd = None
- self.filename = None
- self.fsync = fsync
- if isinstance(f, six.string_types):
- self.filename = f
- self.file_handle = open(f, mode)
- self.fd = self.file_handle.fileno()
- # Only close it if we opened it...
- self._defer_close = True
- elif hasattr(f, 'fileno'):
- self.filename = getattr(f, 'name', None)
- self.file_handle = f
- self.fd = self.file_handle.fileno()
- # Leave the fd alone, caller should manage it...
- self._defer_close = False
- elif isinstance(f, int):
- assert f >= 0, f
- self.fd = f
- # Leave the fd alone, caller should manage it...
- self._defer_close = False
- else:
- raise Exception('Provided file is not path or open file.')
- self.mode = mode
- # Guess the format/filter from file name (if not provided)
- if self.filename:
- if format is None:
- format = guess_format(self.filename)[0]
- if filter is None:
- filter = guess_format(self.filename)[1]
- self.format = format
- self.filter = filter
- # The class to use for entries.
- self.entry_class = entry_class
- self.fixed_mtime = fixed_mtime
- # Select filter/format functions.
- if self.mode.startswith('r'):
- self.format_func = get_func(self.format, FORMATS, 0)
- if self.format_func is None:
- raise Exception('Unsupported format %s' % format)
- self.filter_func = get_func(self.filter, FILTERS, 0)
- if self.filter_func is None:
- raise Exception('Unsupported filter %s' % filter)
- else:
- # TODO: how to support appending?
- if self.format is None:
- raise Exception('You must specify a format for writing.')
- self.format_func = get_func(self.format, FORMATS, 1)
- if self.format_func is None:
- raise Exception('Unsupported format %s' % format)
- self.filter_func = get_func(self.filter, FILTERS, 1)
- if self.filter_func is None:
- raise Exception('Unsupported filter %s' % filter)
- # Open the archive, apply filter/format functions.
- self.filter_opts = filter_opts
- self.format_opts = format_opts
- # Stores every added entry's id to handle hardlinks properly
- self.members = {}
- self.init()
-
- def __iter__(self):
- while True:
- try:
- yield self.entry_class.from_archive(self, encoding=self.encoding)
- except EOF:
- break
-
- def __enter__(self):
- return self
-
- def __exit__(self, type, value, traceback):
- self.close()
-
- def __del__(self):
- self.close()
-
- def init(self):
- def _apply_opts(f, opts):
- if opts:
- for opt_name, opt_val in opts.items():
- call_and_check(f, self._a, self._a, None, encode(opt_name, self.encoding), encode(opt_val, self.encoding))
-
- if self.mode.startswith('r'):
- self._a = _libarchive.archive_read_new()
- else:
- self._a = _libarchive.archive_write_new()
- self.format_func(self._a)
- self.filter_func(self._a)
- if self.mode.startswith('r'):
- _apply_opts(_libarchive.archive_read_set_format_option, self.format_opts)
- _apply_opts(_libarchive.archive_read_set_filter_option, self.filter_opts)
- call_and_check(_libarchive.archive_read_open_fd, self._a, self._a, self.fd, self.blocksize)
- else:
- _apply_opts(_libarchive.archive_write_set_format_option, self.format_opts)
- _apply_opts(_libarchive.archive_write_set_filter_option, self.filter_opts)
- call_and_check(_libarchive.archive_write_open_fd, self._a, self._a, self.fd)
- # XXX Don't pad the last block to avoid badly formed archive with zstd filter
- call_and_check(_libarchive.archive_write_set_bytes_in_last_block, self._a, self._a, 1)
-
- def denit(self):
- '''Closes and deallocates the archive reader/writer.'''
- if getattr(self, '_a', None) is None:
- return
- try:
- if self.mode.startswith('r'):
- _libarchive.archive_read_close(self._a)
- _libarchive.archive_read_free(self._a)
- else:
- _libarchive.archive_write_close(self._a)
- _libarchive.archive_write_free(self._a)
- finally:
- # We only want one try at this...
- self._a = None
-
- def close(self, _defer=False):
- # _defer == True is how a stream can notify Archive that the stream is
- # now closed. Calling it directly in not recommended.
- if _defer:
- # This call came from our open stream.
- self._stream = None
- if not self._defer_close:
- # We are not yet ready to close.
- return
- if self._stream is not None:
- # We have a stream open! don't close, but remember we were asked to.
- self._defer_close = True
- return
- self.denit()
- # If there is a file attached...
- if getattr(self, 'file_handle', None):
- # Make sure it is not already closed...
- if getattr(self.file_handle, 'closed', False):
- return
- # Flush it if not read-only...
- if not self.file_handle.mode.startswith('r'):
- self.file_handle.flush()
- if self.fsync:
- os.fsync(self.fd)
- # and then close it, if we opened it...
- if getattr(self, 'close', None):
- self.file_handle.close()
-
- @property
- def header_position(self):
- '''The position within the file.'''
- return _libarchive.archive_read_header_position(self._a)
-
- def iterpaths(self):
- for entry in self:
- yield entry.pathname
-
- def read(self, size):
- '''Read current archive entry contents into string.'''
- return _libarchive.archive_read_data_into_str(self._a, size)
-
- def readpath(self, f):
- '''Write current archive entry contents to file. f can be a file-like object or
- a path.'''
- with contextlib2.ExitStack() as exit_stack:
- if isinstance(f, six.string_types):
- basedir = os.path.basename(f)
- if not os.path.exists(basedir):
- os.makedirs(basedir)
- f = exit_stack.enter_context(open(f, 'wb'))
- return _libarchive.archive_read_data_into_fd(self._a, f.fileno())
-
- def readstream(self, size):
- '''Returns a file-like object for reading current archive entry contents.'''
- self._stream = EntryReadStream(self, size)
- return self._stream
-
- def write(self, member, data=None):
- '''Writes a string buffer to the archive as the given entry.'''
- if isinstance(member, six.string_types):
- if self.fixed_mtime is None:
- mtime = time.time()
- else:
- mtime = self.fixed_mtime
- # Use default mode
- member = self.entry_class(pathname=member, encoding=self.encoding, mtime=mtime, mode=stat.S_IFREG | 0o755)
- if data:
- member.size = len(data)
- member.to_archive(self)
- if data:
- _libarchive.archive_write_data_from_str(self._a, data)
- _libarchive.archive_write_finish_entry(self._a)
-
- def writepath(self, f, pathname=None):
- '''Writes a file to the archive. f can be a file-like object or a path. Uses
- write() to do the actual writing.'''
- member = self.entry_class.from_file(f, encoding=self.encoding, mtime=self.fixed_mtime)
-
- with contextlib2.ExitStack() as exit_stack:
- if isinstance(f, six.string_types):
- if os.path.isfile(f):
- f = exit_stack.enter_context(open(f, 'rb'))
- if pathname:
- member.pathname = pathname
-
- # hardlinks and symlink has no data to be written
- if member.id in self.members:
- member.hardlink = self.members[member.id]
- self.write(member)
- return
- elif member.issym():
- self.write(member)
- elif hasattr(f, 'read') and hasattr(f, 'seek') and hasattr(f, 'tell'):
- self.write_from_file_object(member, f)
- elif hasattr(f, 'read'):
- # TODO: optimize this to write directly from f to archive.
- self.write(member, data=f.read())
- else:
- self.write(member)
-
- if member.id:
- self.members[member.id] = member.pathname
-
- def write_from_file_object(self, member, fileobj):
- if isinstance(member, six.string_types):
- member = self.entry_class(pathname=member, encoding=self.encoding, mtime=self.fixed_mtime)
-
- start = fileobj.tell()
- fileobj.seek(0, os.SEEK_END)
- size = fileobj.tell() - start
- fileobj.seek(start, os.SEEK_SET)
-
- if size:
- member.size = size
- member.to_archive(self)
-
- while size:
- data = fileobj.read(BLOCK_SIZE)
- if not data:
- break
-
- size -= len(data)
- if size < 0:
- msg = "File ({}) size has changed. Can't write more data than was declared in the tar header ({}). " \
- "(probably file was changed during archiving)".format(member.pathname, member.size)
- logger.warning(msg)
- # write rest expected data (size is negative)
- _libarchive.archive_write_data_from_str(self._a, data[:size])
- break
-
- _libarchive.archive_write_data_from_str(self._a, data)
-
- _libarchive.archive_write_finish_entry(self._a)
-
- def writestream(self, pathname, size=None):
- '''Returns a file-like object for writing a new entry.'''
- self._stream = EntryWriteStream(self, pathname, size)
- return self._stream
-
- def printlist(self, s=sys.stdout):
- for entry in self:
- s.write(entry.size)
- s.write('\t')
- s.write(entry.mtime.strftime(MTIME_FORMAT))
- s.write('\t')
- s.write(entry.pathname)
- s.flush()
-
-
-class SeekableArchive(Archive):
- '''A class that provides random-access to archive entries. It does this by using one
- or many Archive instances to seek to the correct location. The best performance will
- occur when reading archive entries in the order in which they appear in the archive.
- Reading out of order will cause the archive to be closed and opened each time a
- reverse seek is needed.'''
- def __init__(self, f, **kwargs):
- self._stream = None
- # Convert file to open file. We need this to reopen the archive.
- mode = kwargs.setdefault('mode', 'rb')
- if isinstance(f, six.string_types):
- f = open(f, mode)
- super(SeekableArchive, self).__init__(f, **kwargs)
- self.entries = []
- self.eof = False
-
- def __iter__(self):
- for entry in self.entries:
- yield entry
- if not self.eof:
- try:
- for entry in super(SeekableArchive, self).__iter__():
- self.entries.append(entry)
- yield entry
- except StopIteration:
- self.eof = True
-
- def reopen(self):
- '''Seeks the underlying fd to 0 position, then opens the archive. If the archive
- is already open, this will effectively re-open it (rewind to the beginning).'''
- self.denit()
- self.file_handle.seek(0)
- self.init()
-
- def getentry(self, pathname):
- '''Take a name or entry object and returns an entry object.'''
- for entry in self:
- if entry.pathname == pathname:
- return entry
- raise KeyError(pathname)
-
- def seek(self, entry):
- '''Seeks the archive to the requested entry. Will reopen if necessary.'''
- move = entry.header_position - self.header_position
- if move != 0:
- if move < 0:
- # can't move back, re-open archive:
- self.reopen()
- # move to proper position in stream
- for curr in super(SeekableArchive, self).__iter__():
- if curr.header_position == entry.header_position:
- break
-
- def read(self, member):
- '''Return the requested archive entry contents as a string.'''
- entry = self.getentry(member)
- self.seek(entry)
- return super(SeekableArchive, self).read(entry.size)
-
- def readpath(self, member, f):
- entry = self.getentry(member)
- self.seek(entry)
- return super(SeekableArchive, self).readpath(f)
-
- def readstream(self, member):
- '''Returns a file-like object for reading requested archive entry contents.'''
- entry = self.getentry(member)
- self.seek(entry)
- self._stream = EntryReadStream(self, entry.size)
- return self._stream
diff --git a/contrib/python/python-libarchive/libarchive/_libarchive.swg b/contrib/python/python-libarchive/libarchive/_libarchive.swg
deleted file mode 100644
index 2fcb05420e..0000000000
--- a/contrib/python/python-libarchive/libarchive/_libarchive.swg
+++ /dev/null
@@ -1,339 +0,0 @@
-/* Copyright (c) 2011, SmartFile <btimby@smartfile.com>
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the organization nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */
-
-%module _libarchive
-
-%{
-#define SWIG_PYTHON_STRICT_BYTE_CHAR
-
-#include <archive.h>
-#include <archive_entry.h>
-%}
-
-%include "typemaps.i"
-
-%typemap(in) time_t
-{
- if (PyLong_Check($input))
- $1 = (time_t) PyLong_AsLong($input);
- else if (PyInt_Check($input))
- $1 = (time_t) PyInt_AsLong($input);
- else if (PyFloat_Check($input))
- $1 = (time_t) PyFloat_AsDouble($input);
- else {
- PyErr_SetString(PyExc_TypeError,"Expected a large number");
- return NULL;
- }
-}
-
-%typemap(out) time_t
-{
- $result = PyLong_FromLong((long)$1);
-}
-
-%typemap(in) int64_t
-{
- if (PyLong_Check($input))
- $1 = (int64_t) PyLong_AsLong($input);
- else if (PyInt_Check($input))
- $1 = (int64_t) PyInt_AsLong($input);
- else if (PyFloat_Check($input))
- $1 = (int64_t) PyFloat_AsDouble($input);
- else {
- PyErr_SetString(PyExc_TypeError,"Expected a large number");
- return NULL;
- }
-}
-
-%typemap(out) int64_t
-{
- $result = PyLong_FromLong((long)$1);
-}
-
-#define __LA_INT64_T long long
-#define __LA_MODE_T int
-
-/* STRUCTURES */
-struct archive;
-struct archive_entry;
-
-/* ARCHIVE READING */
-extern struct archive *archive_read_new(void);
-extern int archive_read_free(struct archive *);
-
-/* opening */
-extern int archive_read_open_filename(struct archive *,
- const char *_filename, size_t _block_size);
-extern int archive_read_open_memory(struct archive *,
- void * buff, size_t size);
-extern int archive_read_open_memory2(struct archive *a, void *buff,
- size_t size, size_t read_size);
-extern int archive_read_open_fd(struct archive *, int _fd,
- size_t _block_size);
-
-/* closing */
-extern int archive_read_close(struct archive *);
-extern int archive_format(struct archive *);
-
-/* headers */
-extern int archive_read_next_header2(struct archive *,
- struct archive_entry *);
-extern const struct stat *archive_entry_stat(struct archive_entry *);
-extern __LA_INT64_T archive_read_header_position(struct archive *);
-
-/* data */
-extern int archive_read_data_skip(struct archive *);
-extern int archive_read_data_into_fd(struct archive *, int fd);
-
-/* FILTERS */
-extern int archive_read_support_filter_all(struct archive *);
-extern int archive_read_support_filter_bzip2(struct archive *);
-extern int archive_read_support_filter_compress(struct archive *);
-extern int archive_read_support_filter_gzip(struct archive *);
-extern int archive_read_support_filter_lzip(struct archive *);
-extern int archive_read_support_filter_lzma(struct archive *);
-extern int archive_read_support_filter_none(struct archive *);
-extern int archive_read_support_filter_rpm(struct archive *);
-extern int archive_read_support_filter_uu(struct archive *);
-extern int archive_read_support_filter_xz(struct archive *);
-extern int archive_read_support_filter_zstd(struct archive *);
-
-extern int archive_filter_count(struct archive *);
-extern const char * archive_filter_name(struct archive *, int);
-
-/* FORMATS */
-extern int archive_read_support_format_all(struct archive *);
-extern int archive_read_support_format_7zip(struct archive *);
-extern int archive_read_support_format_ar(struct archive *);
-extern int archive_read_support_format_cab(struct archive *);
-extern int archive_read_support_format_cpio(struct archive *);
-extern int archive_read_support_format_empty(struct archive *);
-extern int archive_read_support_format_gnutar(struct archive *);
-extern int archive_read_support_format_iso9660(struct archive *);
-extern int archive_read_support_format_lha(struct archive *);
-/*extern int archive_read_support_format_mtree(struct archive *);*/
-extern int archive_read_support_format_rar(struct archive *);
-extern int archive_read_support_format_raw(struct archive *);
-extern int archive_read_support_format_tar(struct archive *);
-extern int archive_read_support_format_xar(struct archive *);
-extern int archive_read_support_format_zip(struct archive *);
-/*extern int archive_read_support_format_by_code(struct archive *, int);*/
-
-/* OPTIONS */
-extern int archive_write_set_bytes_in_last_block(struct archive *_a, int bytes_in_last_block);
-extern int archive_write_set_filter_option(struct archive *_a, const char *m, const char *o, const char *v);
-extern int archive_write_zip_set_compression_deflate(struct archive *_a);
-extern int archive_write_set_format_option(struct archive *_a, const char *m, const char *o, const char *v);
-extern int archive_read_set_filter_option(struct archive *_a, const char *m, const char *o, const char *v);
-extern int archive_read_set_format_option(struct archive *_a, const char *m, const char *o, const char *v);
-
-/* ARCHIVE WRITING */
-extern struct archive *archive_write_new(void);
-extern int archive_write_free(struct archive *);
-
-/* opening */
-extern int archive_write_open(struct archive *, void *,
- archive_open_callback *, archive_write_callback *,
- archive_close_callback *);
-extern int archive_write_open_fd(struct archive *, int _fd);
-extern int archive_write_open_filename(struct archive *, const char *_file);
-extern int archive_write_open_filename_w(struct archive *,
- const wchar_t *_file);
-extern int archive_write_open_memory(struct archive *,
- void *_buffer, size_t _buffSize, size_t *_used);
-
-/* closing */
-extern int archive_write_close(struct archive *);
-
-/* headers */
-extern int archive_write_header(struct archive *,
- struct archive_entry *);
-
-/* data */
-
-/* commit */
-extern int archive_write_finish_entry(struct archive *);
-
-/* FILTERS */
-extern int archive_write_add_filter_bzip2(struct archive *);
-extern int archive_write_add_filter_compress(struct archive *);
-extern int archive_write_add_filter_gzip(struct archive *);
-extern int archive_write_add_filter_lzip(struct archive *);
-extern int archive_write_add_filter_lzma(struct archive *);
-extern int archive_write_add_filter_none(struct archive *);
-extern int archive_write_add_filter_xz(struct archive *);
-extern int archive_write_add_filter_zstd(struct archive *);
-
-
-/* FORMATS */
-/* A convenience function to set the format based on the code or name. */
-extern int archive_write_set_format(struct archive *, int format_code);
-extern int archive_write_set_format_by_name(struct archive *,
- const char *name);
-/* To minimize link pollution, use one or more of the following. */
-extern int archive_write_set_format_ar_bsd(struct archive *);
-extern int archive_write_set_format_ar_svr4(struct archive *);
-extern int archive_write_set_format_cpio(struct archive *);
-extern int archive_write_set_format_cpio_newc(struct archive *);
-extern int archive_write_set_format_gnutar(struct archive *);
-extern int archive_write_set_format_iso9660(struct archive *);
-/*extern int archive_write_set_format_mtree(struct archive *);*/
-/* TODO: int archive_write_set_format_old_tar(struct archive *); */
-extern int archive_write_set_format_pax(struct archive *);
-extern int archive_write_set_format_pax_restricted(struct archive *);
-extern int archive_write_set_format_shar(struct archive *);
-extern int archive_write_set_format_shar_dump(struct archive *);
-extern int archive_write_set_format_ustar(struct archive *);
-extern int archive_write_set_format_xar(struct archive *);
-extern int archive_write_set_format_zip(struct archive *);
-
-/* ARCHIVE ENTRY */
-extern struct archive_entry *archive_entry_new(void);
-extern void archive_entry_free(struct archive_entry *);
-extern const char *archive_entry_symlink(struct archive_entry *);
-extern void archive_entry_set_symlink(struct archive_entry *, const char *);
-extern const char *archive_entry_hardlink(struct archive_entry *);
-extern void archive_entry_set_hardlink(struct archive_entry *, const char *);
-
-/* ARCHIVE ENTRY PROPERTY ACCESS */
-/* reading */
-extern const char *archive_entry_pathname(struct archive_entry *);
-extern const wchar_t *archive_entry_pathname_w(struct archive_entry *);
-extern __LA_INT64_T archive_entry_size(struct archive_entry *);
-extern time_t archive_entry_mtime(struct archive_entry *);
-extern time_t archive_entry_mtime_nsec(struct archive_entry *);
-extern __LA_MODE_T archive_entry_filetype(struct archive_entry *);
-extern __LA_MODE_T archive_entry_perm(struct archive_entry *);
-
-/* writing */
-extern void archive_entry_set_pathname(struct archive_entry *, const char *);
-extern void archive_entry_set_size(struct archive_entry *, __LA_INT64_T);
-extern void archive_entry_set_mtime(struct archive_entry *, time_t, long);
-extern void archive_entry_set_filetype(struct archive_entry *, unsigned int);
-extern void archive_entry_set_perm(struct archive_entry *, __LA_MODE_T);
-
-
-/* ERROR HANDLING */
-extern int archive_errno(struct archive *);
-extern const char *archive_error_string(struct archive *);
-
-
-/* CONSTANTS */
-#define ARCHIVE_VERSION_NUMBER 3000001
-#define ARCHIVE_VERSION_STRING "libarchive 3.0.1b"
-#define ARCHIVE_EOF 1 /* Found end of archive. */
-#define ARCHIVE_OK 0 /* Operation was successful. */
-#define ARCHIVE_RETRY (-10) /* Retry might succeed. */
-#define ARCHIVE_WARN (-20) /* Partial success. */
-#define ARCHIVE_FAILED (-25) /* Current operation cannot complete. */
-#define ARCHIVE_FATAL (-30) /* No more operations are possible. */
-
-#define ARCHIVE_FILTER_NONE 0
-#define ARCHIVE_FILTER_GZIP 1
-#define ARCHIVE_FILTER_BZIP2 2
-#define ARCHIVE_FILTER_COMPRESS 3
-#define ARCHIVE_FILTER_PROGRAM 4
-#define ARCHIVE_FILTER_LZMA 5
-#define ARCHIVE_FILTER_XZ 6
-#define ARCHIVE_FILTER_UU 7
-#define ARCHIVE_FILTER_RPM 8
-#define ARCHIVE_FILTER_LZIP 9
-
-#define ARCHIVE_FORMAT_BASE_MASK 0xff0000
-#define ARCHIVE_FORMAT_CPIO 0x10000
-#define ARCHIVE_FORMAT_CPIO_POSIX (ARCHIVE_FORMAT_CPIO | 1)
-#define ARCHIVE_FORMAT_CPIO_BIN_LE (ARCHIVE_FORMAT_CPIO | 2)
-#define ARCHIVE_FORMAT_CPIO_BIN_BE (ARCHIVE_FORMAT_CPIO | 3)
-#define ARCHIVE_FORMAT_CPIO_SVR4_NOCRC (ARCHIVE_FORMAT_CPIO | 4)
-#define ARCHIVE_FORMAT_CPIO_SVR4_CRC (ARCHIVE_FORMAT_CPIO | 5)
-#define ARCHIVE_FORMAT_CPIO_AFIO_LARGE (ARCHIVE_FORMAT_CPIO | 6)
-#define ARCHIVE_FORMAT_SHAR 0x20000
-#define ARCHIVE_FORMAT_SHAR_BASE (ARCHIVE_FORMAT_SHAR | 1)
-#define ARCHIVE_FORMAT_SHAR_DUMP (ARCHIVE_FORMAT_SHAR | 2)
-#define ARCHIVE_FORMAT_TAR 0x30000
-#define ARCHIVE_FORMAT_TAR_USTAR (ARCHIVE_FORMAT_TAR | 1)
-#define ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE (ARCHIVE_FORMAT_TAR | 2)
-#define ARCHIVE_FORMAT_TAR_PAX_RESTRICTED (ARCHIVE_FORMAT_TAR | 3)
-#define ARCHIVE_FORMAT_TAR_GNUTAR (ARCHIVE_FORMAT_TAR | 4)
-#define ARCHIVE_FORMAT_ISO9660 0x40000
-#define ARCHIVE_FORMAT_ISO9660_ROCKRIDGE (ARCHIVE_FORMAT_ISO9660 | 1)
-#define ARCHIVE_FORMAT_ZIP 0x50000
-#define ARCHIVE_FORMAT_EMPTY 0x60000
-#define ARCHIVE_FORMAT_AR 0x70000
-#define ARCHIVE_FORMAT_AR_GNU (ARCHIVE_FORMAT_AR | 1)
-#define ARCHIVE_FORMAT_AR_BSD (ARCHIVE_FORMAT_AR | 2)
-#define ARCHIVE_FORMAT_MTREE 0x80000
-#define ARCHIVE_FORMAT_RAW 0x90000
-#define ARCHIVE_FORMAT_XAR 0xA0000
-#define ARCHIVE_FORMAT_LHA 0xB0000
-#define ARCHIVE_FORMAT_CAB 0xC0000
-#define ARCHIVE_FORMAT_RAR 0xD0000
-#define ARCHIVE_FORMAT_7ZIP 0xE0000
-
-#define ARCHIVE_EXTRACT_OWNER (0x0001)
-#define ARCHIVE_EXTRACT_PERM (0x0002)
-#define ARCHIVE_EXTRACT_TIME (0x0004)
-#define ARCHIVE_EXTRACT_NO_OVERWRITE (0x0008)
-#define ARCHIVE_EXTRACT_UNLINK (0x0010)
-#define ARCHIVE_EXTRACT_ACL (0x0020)
-#define ARCHIVE_EXTRACT_FFLAGS (0x0040)
-#define ARCHIVE_EXTRACT_XATTR (0x0080)
-#define ARCHIVE_EXTRACT_SECURE_SYMLINKS (0x0100)
-#define ARCHIVE_EXTRACT_SECURE_NODOTDOT (0x0200)
-#define ARCHIVE_EXTRACT_NO_AUTODIR (0x0400)
-#define ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER (0x0800)
-#define ARCHIVE_EXTRACT_SPARSE (0x1000)
-#define ARCHIVE_EXTRACT_MAC_METADATA (0x2000)
-
-%inline %{
-PyObject *archive_read_data_into_str(struct archive *archive, int len) {
- PyObject *str = NULL;
- if (!(str = PyBytes_FromStringAndSize(NULL, len))) {
- PyErr_SetString(PyExc_MemoryError, "could not allocate string.");
- return NULL;
- }
- if (len != archive_read_data(archive, PyBytes_AS_STRING(str), len)) {
- PyErr_SetString(PyExc_RuntimeError, "could not read requested data.");
- return NULL;
- }
- return str;
-}
-
-PyObject *archive_write_data_from_str(struct archive *archive, PyObject *str) {
- int len = PyBytes_Size(str);
- if (len == 0)
- return PyInt_FromLong(len);
- int ret = archive_write_data(archive, PyBytes_AS_STRING(str), len);
- if (ret == ARCHIVE_FATAL) {
- PyErr_Format(PyExc_RuntimeError, "Could not write requested data - most likely no space left on device (error code: %d)", ret);
- return NULL;
- }
- else if (ret <= 0) {
- PyErr_Format(PyExc_RuntimeError, "Could not write requested data (error code: %d)", ret);
- return NULL;
- }
- return PyInt_FromLong(len);
-}
-%}
diff --git a/contrib/python/python-libarchive/libarchive/tar.py b/contrib/python/python-libarchive/libarchive/tar.py
deleted file mode 100644
index f14149804b..0000000000
--- a/contrib/python/python-libarchive/libarchive/tar.py
+++ /dev/null
@@ -1,135 +0,0 @@
-# Copyright (c) 2011, SmartFile <btimby@smartfile.com>
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-# * Neither the name of the organization nor the
-# names of its contributors may be used to endorse or promote products
-# derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
-
-import time
-from libarchive import is_archive, Entry, SeekableArchive
-from tarfile import DEFAULT_FORMAT, USTAR_FORMAT, GNU_FORMAT, PAX_FORMAT, ENCODING
-from tarfile import REGTYPE, AREGTYPE, LNKTYPE, SYMTYPE, DIRTYPE, FIFOTYPE, CONTTYPE, CHRTYPE, BLKTYPE, GNUTYPE_SPARSE
-
-FORMAT_CONVERSION = {
- USTAR_FORMAT: 'tar',
- GNU_FORMAT: 'gnu',
- PAX_FORMAT: 'pax',
-}
-
-
-def is_tarfile(filename):
- return is_archive(filename, formats=('tar', 'gnu', 'pax'))
-
-
-def open(**kwargs):
- return TarFile(**kwargs)
-
-
-class TarInfo(Entry):
- def __init__(self, name):
- super(TarInfo, self).__init__(pathname=name)
-
- fromtarfile = Entry.from_archive
-
- def get_name(self):
- return self.pathname
-
- def set_name(self, value):
- self.pathname = value
-
- name = property(get_name, set_name)
-
- @property
- def get_type(self):
- for attr, type in (
- ('isdir', DIRTYPE), ('isfile', REGTYPE), ('issym', SYMTYPE),
- ('isfifo', FIFOTYPE), ('ischr', CHRTYPE), ('isblk', BLKTYPE),
- ):
- if getattr(self, attr)():
- return type
-
- def _get_missing(self):
- raise NotImplemented()
-
- def _set_missing(self, value):
- raise NotImplemented()
-
- pax_headers = property(_get_missing, _set_missing)
-
-
-class TarFile(SeekableArchive):
- def __init__(self, name=None, mode='r', fileobj=None, format=DEFAULT_FORMAT, tarinfo=TarInfo, encoding=ENCODING):
- if name:
- f = name
- elif fileobj:
- f = fileobj
- try:
- format = FORMAT_CONVERSON.get(format)
- except KeyError:
- raise Exception('Invalid tar format: %s' % format)
- super(TarFile, self).__init__(f, mode=mode, format=format, entry_class=tarinfo, encoding=encoding)
-
- getmember = SeekableArchive.getentry
- list = SeekableArchive.printlist
- extract = SeekableArchive.readpath
- extractfile = SeekableArchive.readstream
-
- def getmembers(self):
- return list(self)
-
- def getnames(self):
- return list(self.iterpaths)
-
- def next(self):
- pass # TODO: how to do this?
-
- def extract(self, member, path=None):
- if path is None:
- path = os.getcwd()
- if isinstance(member, basestring):
- f = os.path.join(path, member)
- else:
- f = os.path.join(path, member.pathname)
- return self.readpath(member, f)
-
- def add(self, name, arcname, recursive=True, exclude=None, filter=None):
- pass # TODO: implement this.
-
- def addfile(tarinfo, fileobj):
- return self.writepath(fileobj, tarinfo)
-
- def gettarinfo(name=None, arcname=None, fileobj=None):
- if name:
- f = name
- elif fileobj:
- f = fileobj
- entry = self.entry_class.from_file(f)
- if arcname:
- entry.pathname = arcname
- return entry
-
- def _get_missing(self):
- raise NotImplemented()
-
- def _set_missing(self, value):
- raise NotImplemented()
-
- pax_headers = property(_get_missing, _set_missing)
diff --git a/contrib/python/python-libarchive/libarchive/zip.py b/contrib/python/python-libarchive/libarchive/zip.py
deleted file mode 100644
index 539f6dbcc4..0000000000
--- a/contrib/python/python-libarchive/libarchive/zip.py
+++ /dev/null
@@ -1,151 +0,0 @@
-# Copyright (c) 2011, SmartFile <btimby@smartfile.com>
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-# * Neither the name of the organization nor the
-# names of its contributors may be used to endorse or promote products
-# derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
-
-import os, time
-from libarchive import is_archive, Entry, SeekableArchive
-from zipfile import ZIP_STORED, ZIP_DEFLATED
-
-
-def is_zipfile(filename):
- return is_archive(filename, formats=('zip', ))
-
-
-class ZipEntry(Entry):
- def __init__(self, *args, **kwargs):
- super(ZipEntry, self).__init__(*args, **kwargs)
-
- def get_filename(self):
- return self.pathname
-
- def set_filename(self, value):
- self.pathname = value
-
- filename = property(get_filename, set_filename)
-
- def get_file_size(self):
- return self.size
-
- def set_file_size(self, value):
- assert isinstance(size, (int, long)), 'Please provide size as int or long.'
- self.size = value
-
- file_size = property(get_file_size, set_file_size)
-
- def get_date_time(self):
- return time.localtime(self.mtime)[0:6]
-
- def set_date_time(self, value):
- assert isinstance(value, tuple), 'mtime should be tuple (year, month, day, hour, minute, second).'
- assert len(value) == 6, 'mtime should be tuple (year, month, day, hour, minute, second).'
- self.mtime = time.mktime(value + (0, 0, 0))
-
- date_time = property(get_date_time, set_date_time)
-
- header_offset = Entry.header_position
-
- def _get_missing(self):
- raise NotImplemented()
-
- def _set_missing(self, value):
- raise NotImplemented()
-
- compress_type = property(_get_missing, _set_missing)
- comment = property(_get_missing, _set_missing)
- extra = property(_get_missing, _set_missing)
- create_system = property(_get_missing, _set_missing)
- create_version = property(_get_missing, _set_missing)
- extract_version = property(_get_missing, _set_missing)
- reserved = property(_get_missing, _set_missing)
- flag_bits = property(_get_missing, _set_missing)
- volume = property(_get_missing, _set_missing)
- internal_attr = property(_get_missing, _set_missing)
- external_attr = property(_get_missing, _set_missing)
- CRC = property(_get_missing, _set_missing)
- compress_size = property(_get_missing, _set_missing)
-
-
-class ZipFile(SeekableArchive):
- def __init__(self, f, mode='r', compression=ZIP_DEFLATED, allowZip64=False):
- super(ZipFile, self).__init__(f, mode=mode, format='zip', entry_class=ZipEntry, encoding='CP437')
- if mode == 'w' and compression == ZIP_STORED:
- # Disable compression for writing.
- _libarchive.archive_write_set_format_option(self.archive._a, "zip", "compression", "store")
- self.compression = compression
-
- getinfo = SeekableArchive.getentry
-
- def namelist(self):
- return list(self.iterpaths)
-
- def infolist(self):
- return list(self)
-
- def open(self, name, mode, pwd=None):
- if pwd:
- raise NotImplemented('Encryption not supported.')
- if mode == 'r':
- return self.readstream(name)
- else:
- return self.writestream(name)
-
- def extract(self, name, path=None, pwd=None):
- if pwd:
- raise NotImplemented('Encryption not supported.')
- if not path:
- path = os.getcwd()
- return self.readpath(name, os.path.join(path, name))
-
- def extractall(self, path, names=None, pwd=None):
- if pwd:
- raise NotImplemented('Encryption not supported.')
- if not names:
- names = self.namelist()
- if names:
- for name in names:
- self.extract(name, path)
-
- def read(self, name, pwd=None):
- if pwd:
- raise NotImplemented('Encryption not supported.')
- return self.read(name)
-
- def writestr(self, member, data, compress_type=None):
- if compress_type != self.compression:
- raise Exception('Cannot change compression type for individual entries.')
- return self.write(member, data)
-
- def setpassword(self, pwd):
- raise NotImplemented('Encryption not supported.')
-
- def testzip(self):
- raise NotImplemented()
-
- def _get_missing(self):
- raise NotImplemented()
-
- def _set_missing(self, value):
- raise NotImplemented()
-
- comment = property(_get_missing, _set_missing)
diff --git a/contrib/python/python-libarchive/ya.make b/contrib/python/python-libarchive/ya.make
deleted file mode 100644
index db042fa679..0000000000
--- a/contrib/python/python-libarchive/ya.make
+++ /dev/null
@@ -1,28 +0,0 @@
-PY23_LIBRARY()
-
-LICENSE(BSD-3-Clause)
-
-VERSION(3.1.2.post1)
-
-PEERDIR(
- contrib/libs/libarchive
- contrib/python/contextlib2
- contrib/python/six
-)
-
-ADDINCL(
- contrib/libs/libarchive/libarchive
-)
-
-NO_LINT()
-
-PY_SRCS(
- SWIG_C
- TOP_LEVEL
- libarchive/__init__.py
- libarchive/tar.py
- libarchive/zip.py
- libarchive/_libarchive.swg
-)
-
-END()
diff --git a/contrib/python/simplejson/.dist-info/METADATA b/contrib/python/simplejson/.dist-info/METADATA
deleted file mode 100644
index 030823c2a1..0000000000
--- a/contrib/python/simplejson/.dist-info/METADATA
+++ /dev/null
@@ -1,68 +0,0 @@
-Metadata-Version: 2.1
-Name: simplejson
-Version: 3.18.4
-Summary: Simple, fast, extensible JSON encoder/decoder for Python
-Home-page: https://github.com/simplejson/simplejson
-Author: Bob Ippolito
-Author-email: bob@redivi.com
-License: MIT License
-Platform: any
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: MIT License
-Classifier: License :: OSI Approved :: Academic Free License (AFL)
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.5
-Classifier: Programming Language :: Python :: 2.6
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
-Classifier: Programming Language :: Python :: 3.6
-Classifier: Programming Language :: Python :: 3.7
-Classifier: Programming Language :: Python :: 3.8
-Classifier: Programming Language :: Python :: 3.9
-Classifier: Programming Language :: Python :: 3.10
-Classifier: Programming Language :: Python :: 3.11
-Classifier: Programming Language :: Python :: Implementation :: CPython
-Classifier: Programming Language :: Python :: Implementation :: PyPy
-Classifier: Topic :: Software Development :: Libraries :: Python Modules
-Requires-Python: >=2.5, !=3.0.*, !=3.1.*, !=3.2.*
-License-File: LICENSE.txt
-
-simplejson
-----------
-
-simplejson is a simple, fast, complete, correct and extensible
-JSON <http://json.org> encoder and decoder for Python 3.3+
-with legacy support for Python 2.5+. It is pure Python code
-with no dependencies, but includes an optional C extension
-for a serious speed boost.
-
-The latest documentation for simplejson can be read online here:
-https://simplejson.readthedocs.io/
-
-simplejson is the externally maintained development version of the
-json library included with Python (since 2.6). This version is tested
-with the latest Python 3.8 and maintains backwards compatibility
-with Python 3.3+ and the legacy Python 2.5 - Python 2.7 releases.
-
-The encoder can be specialized to provide serialization in any kind of
-situation, without any special support by the objects to be serialized
-(somewhat like pickle). This is best done with the ``default`` kwarg
-to dumps.
-
-The decoder can handle incoming JSON strings of any specified encoding
-(UTF-8 by default). It can also be specialized to post-process JSON
-objects with the ``object_hook`` or ``object_pairs_hook`` kwargs. This
-is particularly useful for implementing protocols such as JSON-RPC
-that have a richer type system than JSON itself.
-
-For those of you that have legacy systems to maintain, there is a
-very old fork of simplejson in the `python2.2`_ branch that supports
-Python 2.2. This is based on a very old version of simplejson,
-is not maintained, and should only be used as a last resort.
-
-.. _python2.2: https://github.com/simplejson/simplejson/tree/python2.2
diff --git a/contrib/python/simplejson/.dist-info/top_level.txt b/contrib/python/simplejson/.dist-info/top_level.txt
deleted file mode 100644
index 322630ee75..0000000000
--- a/contrib/python/simplejson/.dist-info/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-simplejson
diff --git a/contrib/python/simplejson/LICENSE.txt b/contrib/python/simplejson/LICENSE.txt
deleted file mode 100644
index e05f49c3fd..0000000000
--- a/contrib/python/simplejson/LICENSE.txt
+++ /dev/null
@@ -1,79 +0,0 @@
-simplejson is dual-licensed software. It is available under the terms
-of the MIT license, or the Academic Free License version 2.1. The full
-text of each license agreement is included below. This code is also
-licensed to the Python Software Foundation (PSF) under a Contributor
-Agreement.
-
-MIT License
-===========
-
-Copyright (c) 2006 Bob Ippolito
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-Academic Free License v. 2.1
-============================
-
-Copyright (c) 2006 Bob Ippolito. All rights reserved.
-
-This Academic Free License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following notice immediately following the copyright notice for the Original Work:
-
-Licensed under the Academic Free License version 2.1
-
-1) Grant of Copyright License. Licensor hereby grants You a world-wide, royalty-free, non-exclusive, perpetual, sublicenseable license to do the following:
-
-a) to reproduce the Original Work in copies;
-
-b) to prepare derivative works ("Derivative Works") based upon the Original Work;
-
-c) to distribute copies of the Original Work and Derivative Works to the public;
-
-d) to perform the Original Work publicly; and
-
-e) to display the Original Work publicly.
-
-2) Grant of Patent License. Licensor hereby grants You a world-wide, royalty-free, non-exclusive, perpetual, sublicenseable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, to make, use, sell and offer for sale the Original Work and Derivative Works.
-
-3) Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor hereby agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work, and by publishing the address of that information repository in a notice immediately following the copyright notice that applies to the Original Work.
-
-4) Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior written permission of the Licensor. Nothing in this License shall be deemed to grant any rights to trademarks, copyrights, patents, trade secrets or any other intellectual property of Licensor except as expressly stated herein. No patent license is granted to make, use, sell or offer to sell embodiments of any patent claims other than the licensed claims defined in Section 2. No right is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under different terms from this License any Original Work that Licensor otherwise would have a right to license.
-
-5) This section intentionally omitted.
-
-6) Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work.
-
-7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately proceeding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to Original Work is granted hereunder except under this disclaimer.
-
-8) Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to any person for any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to liability for death or personal injury resulting from Licensor's negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You.
-
-9) Acceptance and Termination. If You distribute copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. Nothing else but this License (or another written agreement between Licensor and You) grants You permission to create Derivative Works based upon the Original Work or to exercise any of the rights granted in Section 1 herein, and any attempt to do so except under the terms of this License (or another written agreement between Licensor and You) is expressly prohibited by U.S. copyright law, the equivalent laws of other countries, and by international treaty. Therefore, by exercising any of the rights granted to You in Section 1 herein, You indicate Your acceptance of this License and all of its terms and conditions.
-
-10) Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware.
-
-11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of the U.S. Copyright Act, 17 U.S.C. § 101 et seq., the equivalent laws of other countries, and international treaty. This section shall survive the termination of this License.
-
-12) Attorneys Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License.
-
-13) Miscellaneous. This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable.
-
-14) Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
-
-15) Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You.
-
-This license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights reserved. Permission is hereby granted to copy and distribute this license without modification. This license may not be modified without the express written permission of its copyright owner.
diff --git a/contrib/python/simplejson/README.rst b/contrib/python/simplejson/README.rst
deleted file mode 100644
index 6580ddac89..0000000000
--- a/contrib/python/simplejson/README.rst
+++ /dev/null
@@ -1,34 +0,0 @@
-simplejson
-----------
-
-simplejson is a simple, fast, complete, correct and extensible
-JSON <http://json.org> encoder and decoder for Python 3.3+
-with legacy support for Python 2.5+. It is pure Python code
-with no dependencies, but includes an optional C extension
-for a serious speed boost.
-
-The latest documentation for simplejson can be read online here:
-https://simplejson.readthedocs.io/
-
-simplejson is the externally maintained development version of the
-json library included with Python (since 2.6). This version is tested
-with the latest Python 3.8 and maintains backwards compatibility
-with Python 3.3+ and the legacy Python 2.5 - Python 2.7 releases.
-
-The encoder can be specialized to provide serialization in any kind of
-situation, without any special support by the objects to be serialized
-(somewhat like pickle). This is best done with the ``default`` kwarg
-to dumps.
-
-The decoder can handle incoming JSON strings of any specified encoding
-(UTF-8 by default). It can also be specialized to post-process JSON
-objects with the ``object_hook`` or ``object_pairs_hook`` kwargs. This
-is particularly useful for implementing protocols such as JSON-RPC
-that have a richer type system than JSON itself.
-
-For those of you that have legacy systems to maintain, there is a
-very old fork of simplejson in the `python2.2`_ branch that supports
-Python 2.2. This is based on a very old version of simplejson,
-is not maintained, and should only be used as a last resort.
-
-.. _python2.2: https://github.com/simplejson/simplejson/tree/python2.2
diff --git a/contrib/python/simplejson/simplejson/__init__.py b/contrib/python/simplejson/simplejson/__init__.py
deleted file mode 100644
index 47e49a318d..0000000000
--- a/contrib/python/simplejson/simplejson/__init__.py
+++ /dev/null
@@ -1,584 +0,0 @@
-r"""JSON (JavaScript Object Notation) <http://json.org> is a subset of
-JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data
-interchange format.
-
-:mod:`simplejson` exposes an API familiar to users of the standard library
-:mod:`marshal` and :mod:`pickle` modules. It is the externally maintained
-version of the :mod:`json` library contained in Python 2.6, but maintains
-compatibility back to Python 2.5 and (currently) has significant performance
-advantages, even without using the optional C extension for speedups.
-
-Encoding basic Python object hierarchies::
-
- >>> import simplejson as json
- >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
- '["foo", {"bar": ["baz", null, 1.0, 2]}]'
- >>> print(json.dumps("\"foo\bar"))
- "\"foo\bar"
- >>> print(json.dumps(u'\u1234'))
- "\u1234"
- >>> print(json.dumps('\\'))
- "\\"
- >>> print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True))
- {"a": 0, "b": 0, "c": 0}
- >>> from simplejson.compat import StringIO
- >>> io = StringIO()
- >>> json.dump(['streaming API'], io)
- >>> io.getvalue()
- '["streaming API"]'
-
-Compact encoding::
-
- >>> import simplejson as json
- >>> obj = [1,2,3,{'4': 5, '6': 7}]
- >>> json.dumps(obj, separators=(',',':'), sort_keys=True)
- '[1,2,3,{"4":5,"6":7}]'
-
-Pretty printing::
-
- >>> import simplejson as json
- >>> print(json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=' '))
- {
- "4": 5,
- "6": 7
- }
-
-Decoding JSON::
-
- >>> import simplejson as json
- >>> obj = [u'foo', {u'bar': [u'baz', None, 1.0, 2]}]
- >>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj
- True
- >>> json.loads('"\\"foo\\bar"') == u'"foo\x08ar'
- True
- >>> from simplejson.compat import StringIO
- >>> io = StringIO('["streaming API"]')
- >>> json.load(io)[0] == 'streaming API'
- True
-
-Specializing JSON object decoding::
-
- >>> import simplejson as json
- >>> def as_complex(dct):
- ... if '__complex__' in dct:
- ... return complex(dct['real'], dct['imag'])
- ... return dct
- ...
- >>> json.loads('{"__complex__": true, "real": 1, "imag": 2}',
- ... object_hook=as_complex)
- (1+2j)
- >>> from decimal import Decimal
- >>> json.loads('1.1', parse_float=Decimal) == Decimal('1.1')
- True
-
-Specializing JSON object encoding::
-
- >>> import simplejson as json
- >>> def encode_complex(obj):
- ... if isinstance(obj, complex):
- ... return [obj.real, obj.imag]
- ... raise TypeError('Object of type %s is not JSON serializable' %
- ... obj.__class__.__name__)
- ...
- >>> json.dumps(2 + 1j, default=encode_complex)
- '[2.0, 1.0]'
- >>> json.JSONEncoder(default=encode_complex).encode(2 + 1j)
- '[2.0, 1.0]'
- >>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j))
- '[2.0, 1.0]'
-
-Using simplejson.tool from the shell to validate and pretty-print::
-
- $ echo '{"json":"obj"}' | python -m simplejson.tool
- {
- "json": "obj"
- }
- $ echo '{ 1.2:3.4}' | python -m simplejson.tool
- Expecting property name: line 1 column 3 (char 2)
-
-Parsing multiple documents serialized as JSON lines (newline-delimited JSON)::
-
- >>> import simplejson as json
- >>> def loads_lines(docs):
- ... for doc in docs.splitlines():
- ... yield json.loads(doc)
- ...
- >>> sum(doc["count"] for doc in loads_lines('{"count":1}\n{"count":2}\n{"count":3}\n'))
- 6
-
-Serializing multiple objects to JSON lines (newline-delimited JSON)::
-
- >>> import simplejson as json
- >>> def dumps_lines(objs):
- ... for obj in objs:
- ... yield json.dumps(obj, separators=(',',':')) + '\n'
- ...
- >>> ''.join(dumps_lines([{'count': 1}, {'count': 2}, {'count': 3}]))
- '{"count":1}\n{"count":2}\n{"count":3}\n'
-
-"""
-from __future__ import absolute_import
-__version__ = '3.18.4'
-__all__ = [
- 'dump', 'dumps', 'load', 'loads',
- 'JSONDecoder', 'JSONDecodeError', 'JSONEncoder',
- 'OrderedDict', 'simple_first', 'RawJSON'
-]
-
-__author__ = 'Bob Ippolito <bob@redivi.com>'
-
-from decimal import Decimal
-
-from .errors import JSONDecodeError
-from .raw_json import RawJSON
-from .decoder import JSONDecoder
-from .encoder import JSONEncoder, JSONEncoderForHTML
-def _import_OrderedDict():
- import collections
- try:
- return collections.OrderedDict
- except AttributeError:
- from . import ordered_dict
- return ordered_dict.OrderedDict
-OrderedDict = _import_OrderedDict()
-
-def _import_c_make_encoder():
- try:
- from ._speedups import make_encoder
- return make_encoder
- except ImportError:
- return None
-
-_default_encoder = JSONEncoder(
- skipkeys=False,
- ensure_ascii=True,
- check_circular=True,
- allow_nan=True,
- indent=None,
- separators=None,
- encoding='utf-8',
- default=None,
- use_decimal=True,
- namedtuple_as_object=True,
- tuple_as_array=True,
- iterable_as_array=False,
- bigint_as_string=False,
- item_sort_key=None,
- for_json=False,
- ignore_nan=False,
- int_as_string_bitcount=None,
-)
-
-def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
- allow_nan=True, cls=None, indent=None, separators=None,
- encoding='utf-8', default=None, use_decimal=True,
- namedtuple_as_object=True, tuple_as_array=True,
- bigint_as_string=False, sort_keys=False, item_sort_key=None,
- for_json=False, ignore_nan=False, int_as_string_bitcount=None,
- iterable_as_array=False, **kw):
- """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a
- ``.write()``-supporting file-like object).
-
- If *skipkeys* is true then ``dict`` keys that are not basic types
- (``str``, ``int``, ``long``, ``float``, ``bool``, ``None``)
- will be skipped instead of raising a ``TypeError``.
-
- If *ensure_ascii* is false (default: ``True``), then the output may
- contain non-ASCII characters, so long as they do not need to be escaped
- by JSON. When it is true, all non-ASCII characters are escaped.
-
- If *allow_nan* is false, then it will be a ``ValueError`` to
- serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``)
- in strict compliance of the original JSON specification, instead of using
- the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). See
- *ignore_nan* for ECMA-262 compliant behavior.
-
- If *indent* is a string, then JSON array elements and object members
- will be pretty-printed with a newline followed by that string repeated
- for each level of nesting. ``None`` (the default) selects the most compact
- representation without any newlines.
-
- If specified, *separators* should be an
- ``(item_separator, key_separator)`` tuple. The default is ``(', ', ': ')``
- if *indent* is ``None`` and ``(',', ': ')`` otherwise. To get the most
- compact JSON representation, you should specify ``(',', ':')`` to eliminate
- whitespace.
-
- *encoding* is the character encoding for str instances, default is UTF-8.
-
- *default(obj)* is a function that should return a serializable version
- of obj or raise ``TypeError``. The default simply raises ``TypeError``.
-
- If *use_decimal* is true (default: ``True``) then decimal.Decimal
- will be natively serialized to JSON with full precision.
-
- If *namedtuple_as_object* is true (default: ``True``),
- :class:`tuple` subclasses with ``_asdict()`` methods will be encoded
- as JSON objects.
-
- If *tuple_as_array* is true (default: ``True``),
- :class:`tuple` (and subclasses) will be encoded as JSON arrays.
-
- If *iterable_as_array* is true (default: ``False``),
- any object not in the above table that implements ``__iter__()``
- will be encoded as a JSON array.
-
- If *bigint_as_string* is true (default: ``False``), ints 2**53 and higher
- or lower than -2**53 will be encoded as strings. This is to avoid the
- rounding that happens in Javascript otherwise. Note that this is still a
- lossy operation that will not round-trip correctly and should be used
- sparingly.
-
- If *int_as_string_bitcount* is a positive number (n), then int of size
- greater than or equal to 2**n or lower than or equal to -2**n will be
- encoded as strings.
-
- If specified, *item_sort_key* is a callable used to sort the items in
- each dictionary. This is useful if you want to sort items other than
- in alphabetical order by key. This option takes precedence over
- *sort_keys*.
-
- If *sort_keys* is true (default: ``False``), the output of dictionaries
- will be sorted by item.
-
- If *for_json* is true (default: ``False``), objects with a ``for_json()``
- method will use the return value of that method for encoding as JSON
- instead of the object.
-
- If *ignore_nan* is true (default: ``False``), then out of range
- :class:`float` values (``nan``, ``inf``, ``-inf``) will be serialized as
- ``null`` in compliance with the ECMA-262 specification. If true, this will
- override *allow_nan*.
-
- To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
- ``.default()`` method to serialize additional types), specify it with
- the ``cls`` kwarg. NOTE: You should use *default* or *for_json* instead
- of subclassing whenever possible.
-
- """
- # cached encoder
- if (not skipkeys and ensure_ascii and
- check_circular and allow_nan and
- cls is None and indent is None and separators is None and
- encoding == 'utf-8' and default is None and use_decimal
- and namedtuple_as_object and tuple_as_array and not iterable_as_array
- and not bigint_as_string and not sort_keys
- and not item_sort_key and not for_json
- and not ignore_nan and int_as_string_bitcount is None
- and not kw
- ):
- iterable = _default_encoder.iterencode(obj)
- else:
- if cls is None:
- cls = JSONEncoder
- iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii,
- check_circular=check_circular, allow_nan=allow_nan, indent=indent,
- separators=separators, encoding=encoding,
- default=default, use_decimal=use_decimal,
- namedtuple_as_object=namedtuple_as_object,
- tuple_as_array=tuple_as_array,
- iterable_as_array=iterable_as_array,
- bigint_as_string=bigint_as_string,
- sort_keys=sort_keys,
- item_sort_key=item_sort_key,
- for_json=for_json,
- ignore_nan=ignore_nan,
- int_as_string_bitcount=int_as_string_bitcount,
- **kw).iterencode(obj)
- # could accelerate with writelines in some versions of Python, at
- # a debuggability cost
- for chunk in iterable:
- fp.write(chunk)
-
-
-def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
- allow_nan=True, cls=None, indent=None, separators=None,
- encoding='utf-8', default=None, use_decimal=True,
- namedtuple_as_object=True, tuple_as_array=True,
- bigint_as_string=False, sort_keys=False, item_sort_key=None,
- for_json=False, ignore_nan=False, int_as_string_bitcount=None,
- iterable_as_array=False, **kw):
- """Serialize ``obj`` to a JSON formatted ``str``.
-
- If ``skipkeys`` is true then ``dict`` keys that are not basic types
- (``str``, ``int``, ``long``, ``float``, ``bool``, ``None``)
- will be skipped instead of raising a ``TypeError``.
-
- If *ensure_ascii* is false (default: ``True``), then the output may
- contain non-ASCII characters, so long as they do not need to be escaped
- by JSON. When it is true, all non-ASCII characters are escaped.
-
- If ``check_circular`` is false, then the circular reference check
- for container types will be skipped and a circular reference will
- result in an ``OverflowError`` (or worse).
-
- If ``allow_nan`` is false, then it will be a ``ValueError`` to
- serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in
- strict compliance of the JSON specification, instead of using the
- JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
-
- If ``indent`` is a string, then JSON array elements and object members
- will be pretty-printed with a newline followed by that string repeated
- for each level of nesting. ``None`` (the default) selects the most compact
- representation without any newlines. For backwards compatibility with
- versions of simplejson earlier than 2.1.0, an integer is also accepted
- and is converted to a string with that many spaces.
-
- If specified, ``separators`` should be an
- ``(item_separator, key_separator)`` tuple. The default is ``(', ', ': ')``
- if *indent* is ``None`` and ``(',', ': ')`` otherwise. To get the most
- compact JSON representation, you should specify ``(',', ':')`` to eliminate
- whitespace.
-
- ``encoding`` is the character encoding for bytes instances, default is
- UTF-8.
-
- ``default(obj)`` is a function that should return a serializable version
- of obj or raise TypeError. The default simply raises TypeError.
-
- If *use_decimal* is true (default: ``True``) then decimal.Decimal
- will be natively serialized to JSON with full precision.
-
- If *namedtuple_as_object* is true (default: ``True``),
- :class:`tuple` subclasses with ``_asdict()`` methods will be encoded
- as JSON objects.
-
- If *tuple_as_array* is true (default: ``True``),
- :class:`tuple` (and subclasses) will be encoded as JSON arrays.
-
- If *iterable_as_array* is true (default: ``False``),
- any object not in the above table that implements ``__iter__()``
- will be encoded as a JSON array.
-
- If *bigint_as_string* is true (not the default), ints 2**53 and higher
- or lower than -2**53 will be encoded as strings. This is to avoid the
- rounding that happens in Javascript otherwise.
-
- If *int_as_string_bitcount* is a positive number (n), then int of size
- greater than or equal to 2**n or lower than or equal to -2**n will be
- encoded as strings.
-
- If specified, *item_sort_key* is a callable used to sort the items in
- each dictionary. This is useful if you want to sort items other than
- in alphabetical order by key. This option takes precedence over
- *sort_keys*.
-
- If *sort_keys* is true (default: ``False``), the output of dictionaries
- will be sorted by item.
-
- If *for_json* is true (default: ``False``), objects with a ``for_json()``
- method will use the return value of that method for encoding as JSON
- instead of the object.
-
- If *ignore_nan* is true (default: ``False``), then out of range
- :class:`float` values (``nan``, ``inf``, ``-inf``) will be serialized as
- ``null`` in compliance with the ECMA-262 specification. If true, this will
- override *allow_nan*.
-
- To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
- ``.default()`` method to serialize additional types), specify it with
- the ``cls`` kwarg. NOTE: You should use *default* instead of subclassing
- whenever possible.
-
- """
- # cached encoder
- if (not skipkeys and ensure_ascii and
- check_circular and allow_nan and
- cls is None and indent is None and separators is None and
- encoding == 'utf-8' and default is None and use_decimal
- and namedtuple_as_object and tuple_as_array and not iterable_as_array
- and not bigint_as_string and not sort_keys
- and not item_sort_key and not for_json
- and not ignore_nan and int_as_string_bitcount is None
- and not kw
- ):
- return _default_encoder.encode(obj)
- if cls is None:
- cls = JSONEncoder
- return cls(
- skipkeys=skipkeys, ensure_ascii=ensure_ascii,
- check_circular=check_circular, allow_nan=allow_nan, indent=indent,
- separators=separators, encoding=encoding, default=default,
- use_decimal=use_decimal,
- namedtuple_as_object=namedtuple_as_object,
- tuple_as_array=tuple_as_array,
- iterable_as_array=iterable_as_array,
- bigint_as_string=bigint_as_string,
- sort_keys=sort_keys,
- item_sort_key=item_sort_key,
- for_json=for_json,
- ignore_nan=ignore_nan,
- int_as_string_bitcount=int_as_string_bitcount,
- **kw).encode(obj)
-
-
-_default_decoder = JSONDecoder(encoding=None, object_hook=None,
- object_pairs_hook=None)
-
-
-def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None,
- parse_int=None, parse_constant=None, object_pairs_hook=None,
- use_decimal=False, namedtuple_as_object=True, tuple_as_array=True,
- **kw):
- """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing
- a JSON document as `str` or `bytes`) to a Python object.
-
- *encoding* determines the encoding used to interpret any
- `bytes` objects decoded by this instance (``'utf-8'`` by
- default). It has no effect when decoding `str` objects.
-
- *object_hook*, if specified, will be called with the result of every
- JSON object decoded and its return value will be used in place of the
- given :class:`dict`. This can be used to provide custom
- deserializations (e.g. to support JSON-RPC class hinting).
-
- *object_pairs_hook* is an optional function that will be called with
- the result of any object literal decode with an ordered list of pairs.
- The return value of *object_pairs_hook* will be used instead of the
- :class:`dict`. This feature can be used to implement custom decoders
- that rely on the order that the key and value pairs are decoded (for
- example, :func:`collections.OrderedDict` will remember the order of
- insertion). If *object_hook* is also defined, the *object_pairs_hook*
- takes priority.
-
- *parse_float*, if specified, will be called with the string of every
- JSON float to be decoded. By default, this is equivalent to
- ``float(num_str)``. This can be used to use another datatype or parser
- for JSON floats (e.g. :class:`decimal.Decimal`).
-
- *parse_int*, if specified, will be called with the string of every
- JSON int to be decoded. By default, this is equivalent to
- ``int(num_str)``. This can be used to use another datatype or parser
- for JSON integers (e.g. :class:`float`).
-
- *parse_constant*, if specified, will be called with one of the
- following strings: ``'-Infinity'``, ``'Infinity'``, ``'NaN'``. This
- can be used to raise an exception if invalid JSON numbers are
- encountered.
-
- If *use_decimal* is true (default: ``False``) then it implies
- parse_float=decimal.Decimal for parity with ``dump``.
-
- To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
- kwarg. NOTE: You should use *object_hook* or *object_pairs_hook* instead
- of subclassing whenever possible.
-
- """
- return loads(fp.read(),
- encoding=encoding, cls=cls, object_hook=object_hook,
- parse_float=parse_float, parse_int=parse_int,
- parse_constant=parse_constant, object_pairs_hook=object_pairs_hook,
- use_decimal=use_decimal, **kw)
-
-
-def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None,
- parse_int=None, parse_constant=None, object_pairs_hook=None,
- use_decimal=False, **kw):
- """Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a JSON
- document) to a Python object.
-
- *encoding* determines the encoding used to interpret any
- :class:`bytes` objects decoded by this instance (``'utf-8'`` by
- default). It has no effect when decoding :class:`unicode` objects.
-
- *object_hook*, if specified, will be called with the result of every
- JSON object decoded and its return value will be used in place of the
- given :class:`dict`. This can be used to provide custom
- deserializations (e.g. to support JSON-RPC class hinting).
-
- *object_pairs_hook* is an optional function that will be called with
- the result of any object literal decode with an ordered list of pairs.
- The return value of *object_pairs_hook* will be used instead of the
- :class:`dict`. This feature can be used to implement custom decoders
- that rely on the order that the key and value pairs are decoded (for
- example, :func:`collections.OrderedDict` will remember the order of
- insertion). If *object_hook* is also defined, the *object_pairs_hook*
- takes priority.
-
- *parse_float*, if specified, will be called with the string of every
- JSON float to be decoded. By default, this is equivalent to
- ``float(num_str)``. This can be used to use another datatype or parser
- for JSON floats (e.g. :class:`decimal.Decimal`).
-
- *parse_int*, if specified, will be called with the string of every
- JSON int to be decoded. By default, this is equivalent to
- ``int(num_str)``. This can be used to use another datatype or parser
- for JSON integers (e.g. :class:`float`).
-
- *parse_constant*, if specified, will be called with one of the
- following strings: ``'-Infinity'``, ``'Infinity'``, ``'NaN'``. This
- can be used to raise an exception if invalid JSON numbers are
- encountered.
-
- If *use_decimal* is true (default: ``False``) then it implies
- parse_float=decimal.Decimal for parity with ``dump``.
-
- To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
- kwarg. NOTE: You should use *object_hook* or *object_pairs_hook* instead
- of subclassing whenever possible.
-
- """
- if (cls is None and encoding is None and object_hook is None and
- parse_int is None and parse_float is None and
- parse_constant is None and object_pairs_hook is None
- and not use_decimal and not kw):
- return _default_decoder.decode(s)
- if cls is None:
- cls = JSONDecoder
- if object_hook is not None:
- kw['object_hook'] = object_hook
- if object_pairs_hook is not None:
- kw['object_pairs_hook'] = object_pairs_hook
- if parse_float is not None:
- kw['parse_float'] = parse_float
- if parse_int is not None:
- kw['parse_int'] = parse_int
- if parse_constant is not None:
- kw['parse_constant'] = parse_constant
- if use_decimal:
- if parse_float is not None:
- raise TypeError("use_decimal=True implies parse_float=Decimal")
- kw['parse_float'] = Decimal
- return cls(encoding=encoding, **kw).decode(s)
-
-
-def _toggle_speedups(enabled):
- from . import decoder as dec
- from . import encoder as enc
- from . import scanner as scan
- c_make_encoder = _import_c_make_encoder()
- if enabled:
- dec.scanstring = dec.c_scanstring or dec.py_scanstring
- enc.c_make_encoder = c_make_encoder
- enc.encode_basestring_ascii = (enc.c_encode_basestring_ascii or
- enc.py_encode_basestring_ascii)
- scan.make_scanner = scan.c_make_scanner or scan.py_make_scanner
- else:
- dec.scanstring = dec.py_scanstring
- enc.c_make_encoder = None
- enc.encode_basestring_ascii = enc.py_encode_basestring_ascii
- scan.make_scanner = scan.py_make_scanner
- dec.make_scanner = scan.make_scanner
- global _default_decoder
- _default_decoder = JSONDecoder(
- encoding=None,
- object_hook=None,
- object_pairs_hook=None,
- )
- global _default_encoder
- _default_encoder = JSONEncoder(
- skipkeys=False,
- ensure_ascii=True,
- check_circular=True,
- allow_nan=True,
- indent=None,
- separators=None,
- encoding='utf-8',
- default=None,
- )
-
-def simple_first(kv):
- """Helper function to pass to item_sort_key to sort simple
- elements to the top, then container elements.
- """
- return (isinstance(kv[1], (list, dict, tuple)), kv[0])
diff --git a/contrib/python/simplejson/simplejson/_speedups.c b/contrib/python/simplejson/simplejson/_speedups.c
deleted file mode 100644
index ec054c7293..0000000000
--- a/contrib/python/simplejson/simplejson/_speedups.c
+++ /dev/null
@@ -1,3402 +0,0 @@
-/* -*- mode: C; c-file-style: "python"; c-basic-offset: 4 -*- */
-#include "Python.h"
-#include "structmember.h"
-
-#if PY_MAJOR_VERSION >= 3
-#define PyInt_FromSsize_t PyLong_FromSsize_t
-#define PyInt_AsSsize_t PyLong_AsSsize_t
-#define PyInt_Check(obj) 0
-#define PyInt_CheckExact(obj) 0
-#define JSON_UNICHR Py_UCS4
-#define JSON_InternFromString PyUnicode_InternFromString
-#define PyString_GET_SIZE PyUnicode_GET_LENGTH
-#define PY2_UNUSED
-#define PY3_UNUSED UNUSED
-#else /* PY_MAJOR_VERSION >= 3 */
-#define PY2_UNUSED UNUSED
-#define PY3_UNUSED
-#define PyBytes_Check PyString_Check
-#define PyUnicode_READY(obj) 0
-#define PyUnicode_KIND(obj) (sizeof(Py_UNICODE))
-#define PyUnicode_DATA(obj) ((void *)(PyUnicode_AS_UNICODE(obj)))
-#define PyUnicode_READ(kind, data, index) ((JSON_UNICHR)((const Py_UNICODE *)(data))[(index)])
-#define PyUnicode_GET_LENGTH PyUnicode_GET_SIZE
-#define JSON_UNICHR Py_UNICODE
-#define JSON_InternFromString PyString_InternFromString
-#endif /* PY_MAJOR_VERSION < 3 */
-
-#if PY_VERSION_HEX < 0x03090000
-#if !defined(PyObject_CallNoArgs)
-#define PyObject_CallNoArgs(callable) PyObject_CallFunctionObjArgs(callable, NULL);
-#endif
-#if !defined(PyObject_CallOneArg)
-#define PyObject_CallOneArg(callable, arg) PyObject_CallFunctionObjArgs(callable, arg, NULL);
-#endif
-#endif /* PY_VERSION_HEX < 0x03090000 */
-
-#if PY_VERSION_HEX < 0x02070000
-#if !defined(PyOS_string_to_double)
-#define PyOS_string_to_double json_PyOS_string_to_double
-static double
-json_PyOS_string_to_double(const char *s, char **endptr, PyObject *overflow_exception);
-static double
-json_PyOS_string_to_double(const char *s, char **endptr, PyObject *overflow_exception)
-{
- double x;
- assert(endptr == NULL);
- assert(overflow_exception == NULL);
- PyFPE_START_PROTECT("json_PyOS_string_to_double", return -1.0;)
- x = PyOS_ascii_atof(s);
- PyFPE_END_PROTECT(x)
- return x;
-}
-#endif
-#endif /* PY_VERSION_HEX < 0x02070000 */
-
-#if PY_VERSION_HEX < 0x02060000
-#if !defined(Py_TYPE)
-#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
-#endif
-#if !defined(Py_SIZE)
-#define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)
-#endif
-#if !defined(PyVarObject_HEAD_INIT)
-#define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
-#endif
-#endif /* PY_VERSION_HEX < 0x02060000 */
-
-#ifdef __GNUC__
-#define UNUSED __attribute__((__unused__))
-#else
-#define UNUSED
-#endif
-
-#define DEFAULT_ENCODING "utf-8"
-
-#define PyScanner_Check(op) PyObject_TypeCheck(op, &PyScannerType)
-#define PyScanner_CheckExact(op) (Py_TYPE(op) == &PyScannerType)
-#define PyEncoder_Check(op) PyObject_TypeCheck(op, &PyEncoderType)
-#define PyEncoder_CheckExact(op) (Py_TYPE(op) == &PyEncoderType)
-
-#define JSON_ALLOW_NAN 1
-#define JSON_IGNORE_NAN 2
-
-static PyObject *JSON_Infinity = NULL;
-static PyObject *JSON_NegInfinity = NULL;
-static PyObject *JSON_NaN = NULL;
-static PyObject *JSON_EmptyUnicode = NULL;
-#if PY_MAJOR_VERSION < 3
-static PyObject *JSON_EmptyStr = NULL;
-#endif
-
-static PyTypeObject PyScannerType;
-static PyTypeObject PyEncoderType;
-
-typedef struct {
- PyObject *large_strings; /* A list of previously accumulated large strings */
- PyObject *small_strings; /* Pending small strings */
-} JSON_Accu;
-
-static int
-JSON_Accu_Init(JSON_Accu *acc);
-static int
-JSON_Accu_Accumulate(JSON_Accu *acc, PyObject *unicode);
-static PyObject *
-JSON_Accu_FinishAsList(JSON_Accu *acc);
-static void
-JSON_Accu_Destroy(JSON_Accu *acc);
-
-#define ERR_EXPECTING_VALUE "Expecting value"
-#define ERR_ARRAY_DELIMITER "Expecting ',' delimiter or ']'"
-#define ERR_ARRAY_VALUE_FIRST "Expecting value or ']'"
-#define ERR_OBJECT_DELIMITER "Expecting ',' delimiter or '}'"
-#define ERR_OBJECT_PROPERTY "Expecting property name enclosed in double quotes"
-#define ERR_OBJECT_PROPERTY_FIRST "Expecting property name enclosed in double quotes or '}'"
-#define ERR_OBJECT_PROPERTY_DELIMITER "Expecting ':' delimiter"
-#define ERR_STRING_UNTERMINATED "Unterminated string starting at"
-#define ERR_STRING_CONTROL "Invalid control character %r at"
-#define ERR_STRING_ESC1 "Invalid \\X escape sequence %r"
-#define ERR_STRING_ESC4 "Invalid \\uXXXX escape sequence"
-#define FOR_JSON_METHOD_NAME "for_json"
-#define ASDICT_METHOD_NAME "_asdict"
-
-
-typedef struct _PyScannerObject {
- PyObject_HEAD
- PyObject *encoding;
- PyObject *strict_bool;
- int strict;
- PyObject *object_hook;
- PyObject *pairs_hook;
- PyObject *parse_float;
- PyObject *parse_int;
- PyObject *parse_constant;
- PyObject *memo;
-} PyScannerObject;
-
-static PyMemberDef scanner_members[] = {
- {"encoding", T_OBJECT, offsetof(PyScannerObject, encoding), READONLY, "encoding"},
- {"strict", T_OBJECT, offsetof(PyScannerObject, strict_bool), READONLY, "strict"},
- {"object_hook", T_OBJECT, offsetof(PyScannerObject, object_hook), READONLY, "object_hook"},
- {"object_pairs_hook", T_OBJECT, offsetof(PyScannerObject, pairs_hook), READONLY, "object_pairs_hook"},
- {"parse_float", T_OBJECT, offsetof(PyScannerObject, parse_float), READONLY, "parse_float"},
- {"parse_int", T_OBJECT, offsetof(PyScannerObject, parse_int), READONLY, "parse_int"},
- {"parse_constant", T_OBJECT, offsetof(PyScannerObject, parse_constant), READONLY, "parse_constant"},
- {NULL}
-};
-
-typedef struct _PyEncoderObject {
- PyObject_HEAD
- PyObject *markers;
- PyObject *defaultfn;
- PyObject *encoder;
- PyObject *indent;
- PyObject *key_separator;
- PyObject *item_separator;
- PyObject *sort_keys;
- PyObject *key_memo;
- PyObject *encoding;
- PyObject *Decimal;
- PyObject *skipkeys_bool;
- int skipkeys;
- int fast_encode;
- /* 0, JSON_ALLOW_NAN, JSON_IGNORE_NAN */
- int allow_or_ignore_nan;
- int use_decimal;
- int namedtuple_as_object;
- int tuple_as_array;
- int iterable_as_array;
- PyObject *max_long_size;
- PyObject *min_long_size;
- PyObject *item_sort_key;
- PyObject *item_sort_kw;
- int for_json;
-} PyEncoderObject;
-
-static PyMemberDef encoder_members[] = {
- {"markers", T_OBJECT, offsetof(PyEncoderObject, markers), READONLY, "markers"},
- {"default", T_OBJECT, offsetof(PyEncoderObject, defaultfn), READONLY, "default"},
- {"encoder", T_OBJECT, offsetof(PyEncoderObject, encoder), READONLY, "encoder"},
- {"encoding", T_OBJECT, offsetof(PyEncoderObject, encoder), READONLY, "encoding"},
- {"indent", T_OBJECT, offsetof(PyEncoderObject, indent), READONLY, "indent"},
- {"key_separator", T_OBJECT, offsetof(PyEncoderObject, key_separator), READONLY, "key_separator"},
- {"item_separator", T_OBJECT, offsetof(PyEncoderObject, item_separator), READONLY, "item_separator"},
- {"sort_keys", T_OBJECT, offsetof(PyEncoderObject, sort_keys), READONLY, "sort_keys"},
- /* Python 2.5 does not support T_BOOl */
- {"skipkeys", T_OBJECT, offsetof(PyEncoderObject, skipkeys_bool), READONLY, "skipkeys"},
- {"key_memo", T_OBJECT, offsetof(PyEncoderObject, key_memo), READONLY, "key_memo"},
- {"item_sort_key", T_OBJECT, offsetof(PyEncoderObject, item_sort_key), READONLY, "item_sort_key"},
- {"max_long_size", T_OBJECT, offsetof(PyEncoderObject, max_long_size), READONLY, "max_long_size"},
- {"min_long_size", T_OBJECT, offsetof(PyEncoderObject, min_long_size), READONLY, "min_long_size"},
- {NULL}
-};
-
-static PyObject *
-join_list_unicode(PyObject *lst);
-static PyObject *
-JSON_ParseEncoding(PyObject *encoding);
-static PyObject *
-maybe_quote_bigint(PyEncoderObject* s, PyObject *encoded, PyObject *obj);
-static Py_ssize_t
-ascii_char_size(JSON_UNICHR c);
-static Py_ssize_t
-ascii_escape_char(JSON_UNICHR c, char *output, Py_ssize_t chars);
-static PyObject *
-ascii_escape_unicode(PyObject *pystr);
-static PyObject *
-ascii_escape_str(PyObject *pystr);
-static PyObject *
-py_encode_basestring_ascii(PyObject* self UNUSED, PyObject *pystr);
-#if PY_MAJOR_VERSION < 3
-static PyObject *
-join_list_string(PyObject *lst);
-static PyObject *
-scan_once_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr);
-static PyObject *
-scanstring_str(PyObject *pystr, Py_ssize_t end, char *encoding, int strict, Py_ssize_t *next_end_ptr);
-static PyObject *
-_parse_object_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr);
-#endif
-static PyObject *
-scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next_end_ptr);
-static PyObject *
-scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr);
-static PyObject *
-_build_rval_index_tuple(PyObject *rval, Py_ssize_t idx);
-static PyObject *
-scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
-static void
-scanner_dealloc(PyObject *self);
-static int
-scanner_clear(PyObject *self);
-static PyObject *
-encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
-static void
-encoder_dealloc(PyObject *self);
-static int
-encoder_clear(PyObject *self);
-static int
-is_raw_json(PyObject *obj);
-static PyObject *
-encoder_stringify_key(PyEncoderObject *s, PyObject *key);
-static int
-encoder_listencode_list(PyEncoderObject *s, JSON_Accu *rval, PyObject *seq, Py_ssize_t indent_level);
-static int
-encoder_listencode_obj(PyEncoderObject *s, JSON_Accu *rval, PyObject *obj, Py_ssize_t indent_level);
-static int
-encoder_listencode_dict(PyEncoderObject *s, JSON_Accu *rval, PyObject *dct, Py_ssize_t indent_level);
-static PyObject *
-_encoded_const(PyObject *obj);
-static void
-raise_errmsg(char *msg, PyObject *s, Py_ssize_t end);
-static PyObject *
-encoder_encode_string(PyEncoderObject *s, PyObject *obj);
-static int
-_convertPyInt_AsSsize_t(PyObject *o, Py_ssize_t *size_ptr);
-static PyObject *
-_convertPyInt_FromSsize_t(Py_ssize_t *size_ptr);
-static int
-_call_json_method(PyObject *obj, const char *method_name, PyObject **result);
-static PyObject *
-encoder_encode_float(PyEncoderObject *s, PyObject *obj);
-static PyObject *
-moduleinit(void);
-
-#define S_CHAR(c) (c >= ' ' && c <= '~' && c != '\\' && c != '"')
-#define IS_WHITESPACE(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\n') || ((c) == '\r'))
-
-#define MIN_EXPANSION 6
-
-static PyObject* RawJSONType = NULL;
-static int
-is_raw_json(PyObject *obj)
-{
- return PyObject_IsInstance(obj, RawJSONType) ? 1 : 0;
-}
-
-static int
-JSON_Accu_Init(JSON_Accu *acc)
-{
- /* Lazily allocated */
- acc->large_strings = NULL;
- acc->small_strings = PyList_New(0);
- if (acc->small_strings == NULL)
- return -1;
- return 0;
-}
-
-static int
-flush_accumulator(JSON_Accu *acc)
-{
- Py_ssize_t nsmall = PyList_GET_SIZE(acc->small_strings);
- if (nsmall) {
- int ret;
- PyObject *joined;
- if (acc->large_strings == NULL) {
- acc->large_strings = PyList_New(0);
- if (acc->large_strings == NULL)
- return -1;
- }
-#if PY_MAJOR_VERSION >= 3
- joined = join_list_unicode(acc->small_strings);
-#else /* PY_MAJOR_VERSION >= 3 */
- joined = join_list_string(acc->small_strings);
-#endif /* PY_MAJOR_VERSION < 3 */
- if (joined == NULL)
- return -1;
- if (PyList_SetSlice(acc->small_strings, 0, nsmall, NULL)) {
- Py_DECREF(joined);
- return -1;
- }
- ret = PyList_Append(acc->large_strings, joined);
- Py_DECREF(joined);
- return ret;
- }
- return 0;
-}
-
-static int
-JSON_Accu_Accumulate(JSON_Accu *acc, PyObject *unicode)
-{
- Py_ssize_t nsmall;
-#if PY_MAJOR_VERSION >= 3
- assert(PyUnicode_Check(unicode));
-#else /* PY_MAJOR_VERSION >= 3 */
- assert(PyString_Check(unicode) || PyUnicode_Check(unicode));
-#endif /* PY_MAJOR_VERSION < 3 */
-
- if (PyList_Append(acc->small_strings, unicode))
- return -1;
- nsmall = PyList_GET_SIZE(acc->small_strings);
- /* Each item in a list of unicode objects has an overhead (in 64-bit
- * builds) of:
- * - 8 bytes for the list slot
- * - 56 bytes for the header of the unicode object
- * that is, 64 bytes. 100000 such objects waste more than 6MB
- * compared to a single concatenated string.
- */
- if (nsmall < 100000)
- return 0;
- return flush_accumulator(acc);
-}
-
-static PyObject *
-JSON_Accu_FinishAsList(JSON_Accu *acc)
-{
- int ret;
- PyObject *res;
-
- ret = flush_accumulator(acc);
- Py_CLEAR(acc->small_strings);
- if (ret) {
- Py_CLEAR(acc->large_strings);
- return NULL;
- }
- res = acc->large_strings;
- acc->large_strings = NULL;
- if (res == NULL)
- return PyList_New(0);
- return res;
-}
-
-static void
-JSON_Accu_Destroy(JSON_Accu *acc)
-{
- Py_CLEAR(acc->small_strings);
- Py_CLEAR(acc->large_strings);
-}
-
-static int
-IS_DIGIT(JSON_UNICHR c)
-{
- return c >= '0' && c <= '9';
-}
-
-static PyObject *
-maybe_quote_bigint(PyEncoderObject* s, PyObject *encoded, PyObject *obj)
-{
- if (s->max_long_size != Py_None && s->min_long_size != Py_None) {
- if (PyObject_RichCompareBool(obj, s->max_long_size, Py_GE) ||
- PyObject_RichCompareBool(obj, s->min_long_size, Py_LE)) {
-#if PY_MAJOR_VERSION >= 3
- PyObject* quoted = PyUnicode_FromFormat("\"%U\"", encoded);
-#else
- PyObject* quoted = PyString_FromFormat("\"%s\"",
- PyString_AsString(encoded));
-#endif
- Py_DECREF(encoded);
- encoded = quoted;
- }
- }
-
- return encoded;
-}
-
-static int
-_call_json_method(PyObject *obj, const char *method_name, PyObject **result)
-{
- int rval = 0;
- PyObject *method = PyObject_GetAttrString(obj, method_name);
- if (method == NULL) {
- PyErr_Clear();
- return 0;
- }
- if (PyCallable_Check(method)) {
- PyObject *tmp = PyObject_CallNoArgs(method);
- if (tmp == NULL && PyErr_ExceptionMatches(PyExc_TypeError)) {
- PyErr_Clear();
- } else {
- // This will set result to NULL if a TypeError occurred,
- // which must be checked by the caller
- *result = tmp;
- rval = 1;
- }
- }
- Py_DECREF(method);
- return rval;
-}
-
-static int
-_convertPyInt_AsSsize_t(PyObject *o, Py_ssize_t *size_ptr)
-{
- /* PyObject to Py_ssize_t converter */
- *size_ptr = PyInt_AsSsize_t(o);
- if (*size_ptr == -1 && PyErr_Occurred())
- return 0;
- return 1;
-}
-
-static PyObject *
-_convertPyInt_FromSsize_t(Py_ssize_t *size_ptr)
-{
- /* Py_ssize_t to PyObject converter */
- return PyInt_FromSsize_t(*size_ptr);
-}
-
-static Py_ssize_t
-ascii_escape_char(JSON_UNICHR c, char *output, Py_ssize_t chars)
-{
- /* Escape unicode code point c to ASCII escape sequences
- in char *output. output must have at least 12 bytes unused to
- accommodate an escaped surrogate pair "\uXXXX\uXXXX" */
- if (S_CHAR(c)) {
- output[chars++] = (char)c;
- }
- else {
- output[chars++] = '\\';
- switch (c) {
- case '\\': output[chars++] = (char)c; break;
- case '"': output[chars++] = (char)c; break;
- case '\b': output[chars++] = 'b'; break;
- case '\f': output[chars++] = 'f'; break;
- case '\n': output[chars++] = 'n'; break;
- case '\r': output[chars++] = 'r'; break;
- case '\t': output[chars++] = 't'; break;
- default:
-#if PY_MAJOR_VERSION >= 3 || defined(Py_UNICODE_WIDE)
- if (c >= 0x10000) {
- /* UTF-16 surrogate pair */
- JSON_UNICHR v = c - 0x10000;
- c = 0xd800 | ((v >> 10) & 0x3ff);
- output[chars++] = 'u';
- output[chars++] = "0123456789abcdef"[(c >> 12) & 0xf];
- output[chars++] = "0123456789abcdef"[(c >> 8) & 0xf];
- output[chars++] = "0123456789abcdef"[(c >> 4) & 0xf];
- output[chars++] = "0123456789abcdef"[(c ) & 0xf];
- c = 0xdc00 | (v & 0x3ff);
- output[chars++] = '\\';
- }
-#endif
- output[chars++] = 'u';
- output[chars++] = "0123456789abcdef"[(c >> 12) & 0xf];
- output[chars++] = "0123456789abcdef"[(c >> 8) & 0xf];
- output[chars++] = "0123456789abcdef"[(c >> 4) & 0xf];
- output[chars++] = "0123456789abcdef"[(c ) & 0xf];
- }
- }
- return chars;
-}
-
-static Py_ssize_t
-ascii_char_size(JSON_UNICHR c)
-{
- if (S_CHAR(c)) {
- return 1;
- }
- else if (c == '\\' ||
- c == '"' ||
- c == '\b' ||
- c == '\f' ||
- c == '\n' ||
- c == '\r' ||
- c == '\t') {
- return 2;
- }
-#if PY_MAJOR_VERSION >= 3 || defined(Py_UNICODE_WIDE)
- else if (c >= 0x10000U) {
- return 2 * MIN_EXPANSION;
- }
-#endif
- else {
- return MIN_EXPANSION;
- }
-}
-
-static PyObject *
-ascii_escape_unicode(PyObject *pystr)
-{
- /* Take a PyUnicode pystr and return a new ASCII-only escaped PyString */
- Py_ssize_t i;
- Py_ssize_t input_chars = PyUnicode_GET_LENGTH(pystr);
- Py_ssize_t output_size = 2;
- Py_ssize_t chars;
- PY2_UNUSED int kind = PyUnicode_KIND(pystr);
- void *data = PyUnicode_DATA(pystr);
- PyObject *rval;
- char *output;
-
- output_size = 2;
- for (i = 0; i < input_chars; i++) {
- output_size += ascii_char_size(PyUnicode_READ(kind, data, i));
- }
-#if PY_MAJOR_VERSION >= 3
- rval = PyUnicode_New(output_size, 127);
- if (rval == NULL) {
- return NULL;
- }
- assert(PyUnicode_KIND(rval) == PyUnicode_1BYTE_KIND);
- output = (char *)PyUnicode_DATA(rval);
-#else
- rval = PyString_FromStringAndSize(NULL, output_size);
- if (rval == NULL) {
- return NULL;
- }
- output = PyString_AS_STRING(rval);
-#endif
- chars = 0;
- output[chars++] = '"';
- for (i = 0; i < input_chars; i++) {
- chars = ascii_escape_char(PyUnicode_READ(kind, data, i), output, chars);
- }
- output[chars++] = '"';
- assert(chars == output_size);
- return rval;
-}
-
-#if PY_MAJOR_VERSION >= 3
-
-static PyObject *
-ascii_escape_str(PyObject *pystr)
-{
- PyObject *rval;
- PyObject *input = PyUnicode_DecodeUTF8(PyBytes_AS_STRING(pystr), PyBytes_GET_SIZE(pystr), NULL);
- if (input == NULL)
- return NULL;
- rval = ascii_escape_unicode(input);
- Py_DECREF(input);
- return rval;
-}
-
-#else /* PY_MAJOR_VERSION >= 3 */
-
-static PyObject *
-ascii_escape_str(PyObject *pystr)
-{
- /* Take a PyString pystr and return a new ASCII-only escaped PyString */
- Py_ssize_t i;
- Py_ssize_t input_chars;
- Py_ssize_t output_size;
- Py_ssize_t chars;
- PyObject *rval;
- char *output;
- char *input_str;
-
- input_chars = PyString_GET_SIZE(pystr);
- input_str = PyString_AS_STRING(pystr);
- output_size = 2;
-
- /* Fast path for a string that's already ASCII */
- for (i = 0; i < input_chars; i++) {
- JSON_UNICHR c = (JSON_UNICHR)input_str[i];
- if (c > 0x7f) {
- /* We hit a non-ASCII character, bail to unicode mode */
- PyObject *uni;
- uni = PyUnicode_DecodeUTF8(input_str, input_chars, "strict");
- if (uni == NULL) {
- return NULL;
- }
- rval = ascii_escape_unicode(uni);
- Py_DECREF(uni);
- return rval;
- }
- output_size += ascii_char_size(c);
- }
-
- rval = PyString_FromStringAndSize(NULL, output_size);
- if (rval == NULL) {
- return NULL;
- }
- chars = 0;
- output = PyString_AS_STRING(rval);
- output[chars++] = '"';
- for (i = 0; i < input_chars; i++) {
- chars = ascii_escape_char((JSON_UNICHR)input_str[i], output, chars);
- }
- output[chars++] = '"';
- assert(chars == output_size);
- return rval;
-}
-#endif /* PY_MAJOR_VERSION < 3 */
-
-static PyObject *
-encoder_stringify_key(PyEncoderObject *s, PyObject *key)
-{
- if (PyUnicode_Check(key)) {
- Py_INCREF(key);
- return key;
- }
-#if PY_MAJOR_VERSION >= 3
- else if (PyBytes_Check(key) && s->encoding != NULL) {
- const char *encoding = PyUnicode_AsUTF8(s->encoding);
- if (encoding == NULL)
- return NULL;
- return PyUnicode_Decode(
- PyBytes_AS_STRING(key),
- PyBytes_GET_SIZE(key),
- encoding,
- NULL);
- }
-#else /* PY_MAJOR_VERSION >= 3 */
- else if (PyString_Check(key)) {
- Py_INCREF(key);
- return key;
- }
-#endif /* PY_MAJOR_VERSION < 3 */
- else if (PyFloat_Check(key)) {
- return encoder_encode_float(s, key);
- }
- else if (key == Py_True || key == Py_False || key == Py_None) {
- /* This must come before the PyInt_Check because
- True and False are also 1 and 0.*/
- return _encoded_const(key);
- }
- else if (PyInt_Check(key) || PyLong_Check(key)) {
- if (!(PyInt_CheckExact(key) || PyLong_CheckExact(key))) {
- /* See #118, do not trust custom str/repr */
- PyObject *res;
- PyObject *tmp = PyObject_CallOneArg((PyObject *)&PyLong_Type, key);
- if (tmp == NULL) {
- return NULL;
- }
- res = PyObject_Str(tmp);
- Py_DECREF(tmp);
- return res;
- }
- else {
- return PyObject_Str(key);
- }
- }
- else if (s->use_decimal && PyObject_TypeCheck(key, (PyTypeObject *)s->Decimal)) {
- return PyObject_Str(key);
- }
- if (s->skipkeys) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- PyErr_Format(PyExc_TypeError,
- "keys must be str, int, float, bool or None, "
- "not %.100s", key->ob_type->tp_name);
- return NULL;
-}
-
-static PyObject *
-encoder_dict_iteritems(PyEncoderObject *s, PyObject *dct)
-{
- PyObject *items;
- PyObject *iter = NULL;
- PyObject *lst = NULL;
- PyObject *item = NULL;
- PyObject *kstr = NULL;
- PyObject *sortfun = NULL;
- PyObject *sortres;
- static PyObject *sortargs = NULL;
-
- if (sortargs == NULL) {
- sortargs = PyTuple_New(0);
- if (sortargs == NULL)
- return NULL;
- }
-
- if (PyDict_CheckExact(dct))
- items = PyDict_Items(dct);
- else
- items = PyMapping_Items(dct);
- if (items == NULL)
- return NULL;
- iter = PyObject_GetIter(items);
- Py_DECREF(items);
- if (iter == NULL)
- return NULL;
- if (s->item_sort_kw == Py_None)
- return iter;
- lst = PyList_New(0);
- if (lst == NULL)
- goto bail;
- while ((item = PyIter_Next(iter))) {
- PyObject *key, *value;
- if (!PyTuple_Check(item) || Py_SIZE(item) != 2) {
- PyErr_SetString(PyExc_ValueError, "items must return 2-tuples");
- goto bail;
- }
- key = PyTuple_GET_ITEM(item, 0);
- if (key == NULL)
- goto bail;
-#if PY_MAJOR_VERSION < 3
- else if (PyString_Check(key)) {
- /* item can be added as-is */
- }
-#endif /* PY_MAJOR_VERSION < 3 */
- else if (PyUnicode_Check(key)) {
- /* item can be added as-is */
- }
- else {
- PyObject *tpl;
- kstr = encoder_stringify_key(s, key);
- if (kstr == NULL)
- goto bail;
- else if (kstr == Py_None) {
- /* skipkeys */
- Py_DECREF(kstr);
- continue;
- }
- value = PyTuple_GET_ITEM(item, 1);
- if (value == NULL)
- goto bail;
- tpl = PyTuple_Pack(2, kstr, value);
- if (tpl == NULL)
- goto bail;
- Py_CLEAR(kstr);
- Py_DECREF(item);
- item = tpl;
- }
- if (PyList_Append(lst, item))
- goto bail;
- Py_DECREF(item);
- }
- Py_CLEAR(iter);
- if (PyErr_Occurred())
- goto bail;
- sortfun = PyObject_GetAttrString(lst, "sort");
- if (sortfun == NULL)
- goto bail;
- sortres = PyObject_Call(sortfun, sortargs, s->item_sort_kw);
- if (!sortres)
- goto bail;
- Py_DECREF(sortres);
- Py_CLEAR(sortfun);
- iter = PyObject_GetIter(lst);
- Py_CLEAR(lst);
- return iter;
-bail:
- Py_XDECREF(sortfun);
- Py_XDECREF(kstr);
- Py_XDECREF(item);
- Py_XDECREF(lst);
- Py_XDECREF(iter);
- return NULL;
-}
-
-/* Use JSONDecodeError exception to raise a nice looking ValueError subclass */
-static PyObject *JSONDecodeError = NULL;
-static void
-raise_errmsg(char *msg, PyObject *s, Py_ssize_t end)
-{
- PyObject *exc = PyObject_CallFunction(JSONDecodeError, "(zOO&)", msg, s, _convertPyInt_FromSsize_t, &end);
- if (exc) {
- PyErr_SetObject(JSONDecodeError, exc);
- Py_DECREF(exc);
- }
-}
-
-static PyObject *
-join_list_unicode(PyObject *lst)
-{
- /* return u''.join(lst) */
- return PyUnicode_Join(JSON_EmptyUnicode, lst);
-}
-
-#if PY_MAJOR_VERSION >= 3
-#define join_list_string join_list_unicode
-#else /* PY_MAJOR_VERSION >= 3 */
-static PyObject *
-join_list_string(PyObject *lst)
-{
- /* return ''.join(lst) */
- static PyObject *joinfn = NULL;
- if (joinfn == NULL) {
- joinfn = PyObject_GetAttrString(JSON_EmptyStr, "join");
- if (joinfn == NULL)
- return NULL;
- }
- return PyObject_CallOneArg(joinfn, lst);
-}
-#endif /* PY_MAJOR_VERSION < 3 */
-
-static PyObject *
-_build_rval_index_tuple(PyObject *rval, Py_ssize_t idx)
-{
- /* return (rval, idx) tuple, stealing reference to rval */
- PyObject *tpl;
- PyObject *pyidx;
- /*
- steal a reference to rval, returns (rval, idx)
- */
- if (rval == NULL) {
- assert(PyErr_Occurred());
- return NULL;
- }
- pyidx = PyInt_FromSsize_t(idx);
- if (pyidx == NULL) {
- Py_DECREF(rval);
- return NULL;
- }
- tpl = PyTuple_New(2);
- if (tpl == NULL) {
- Py_DECREF(pyidx);
- Py_DECREF(rval);
- return NULL;
- }
- PyTuple_SET_ITEM(tpl, 0, rval);
- PyTuple_SET_ITEM(tpl, 1, pyidx);
- return tpl;
-}
-
-#define APPEND_OLD_CHUNK \
- if (chunk != NULL) { \
- if (chunks == NULL) { \
- chunks = PyList_New(0); \
- if (chunks == NULL) { \
- goto bail; \
- } \
- } \
- if (PyList_Append(chunks, chunk)) { \
- goto bail; \
- } \
- Py_CLEAR(chunk); \
- }
-
-#if PY_MAJOR_VERSION < 3
-static PyObject *
-scanstring_str(PyObject *pystr, Py_ssize_t end, char *encoding, int strict, Py_ssize_t *next_end_ptr)
-{
- /* Read the JSON string from PyString pystr.
- end is the index of the first character after the quote.
- encoding is the encoding of pystr (must be an ASCII superset)
- if strict is zero then literal control characters are allowed
- *next_end_ptr is a return-by-reference index of the character
- after the end quote
-
- Return value is a new PyString (if ASCII-only) or PyUnicode
- */
- PyObject *rval;
- Py_ssize_t len = PyString_GET_SIZE(pystr);
- Py_ssize_t begin = end - 1;
- Py_ssize_t next = begin;
- int has_unicode = 0;
- char *buf = PyString_AS_STRING(pystr);
- PyObject *chunks = NULL;
- PyObject *chunk = NULL;
- PyObject *strchunk = NULL;
-
- if (len == end) {
- raise_errmsg(ERR_STRING_UNTERMINATED, pystr, begin);
- goto bail;
- }
- else if (end < 0 || len < end) {
- PyErr_SetString(PyExc_ValueError, "end is out of bounds");
- goto bail;
- }
- while (1) {
- /* Find the end of the string or the next escape */
- Py_UNICODE c = 0;
- for (next = end; next < len; next++) {
- c = (unsigned char)buf[next];
- if (c == '"' || c == '\\') {
- break;
- }
- else if (strict && c <= 0x1f) {
- raise_errmsg(ERR_STRING_CONTROL, pystr, next);
- goto bail;
- }
- else if (c > 0x7f) {
- has_unicode = 1;
- }
- }
- if (!(c == '"' || c == '\\')) {
- raise_errmsg(ERR_STRING_UNTERMINATED, pystr, begin);
- goto bail;
- }
- /* Pick up this chunk if it's not zero length */
- if (next != end) {
- APPEND_OLD_CHUNK
- strchunk = PyString_FromStringAndSize(&buf[end], next - end);
- if (strchunk == NULL) {
- goto bail;
- }
- if (has_unicode) {
- chunk = PyUnicode_FromEncodedObject(strchunk, encoding, NULL);
- Py_DECREF(strchunk);
- if (chunk == NULL) {
- goto bail;
- }
- }
- else {
- chunk = strchunk;
- }
- }
- next++;
- if (c == '"') {
- end = next;
- break;
- }
- if (next == len) {
- raise_errmsg(ERR_STRING_UNTERMINATED, pystr, begin);
- goto bail;
- }
- c = buf[next];
- if (c != 'u') {
- /* Non-unicode backslash escapes */
- end = next + 1;
- switch (c) {
- case '"': break;
- case '\\': break;
- case '/': break;
- case 'b': c = '\b'; break;
- case 'f': c = '\f'; break;
- case 'n': c = '\n'; break;
- case 'r': c = '\r'; break;
- case 't': c = '\t'; break;
- default: c = 0;
- }
- if (c == 0) {
- raise_errmsg(ERR_STRING_ESC1, pystr, end - 2);
- goto bail;
- }
- }
- else {
- c = 0;
- next++;
- end = next + 4;
- if (end >= len) {
- raise_errmsg(ERR_STRING_ESC4, pystr, next - 1);
- goto bail;
- }
- /* Decode 4 hex digits */
- for (; next < end; next++) {
- JSON_UNICHR digit = (JSON_UNICHR)buf[next];
- c <<= 4;
- switch (digit) {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- c |= (digit - '0'); break;
- case 'a': case 'b': case 'c': case 'd': case 'e':
- case 'f':
- c |= (digit - 'a' + 10); break;
- case 'A': case 'B': case 'C': case 'D': case 'E':
- case 'F':
- c |= (digit - 'A' + 10); break;
- default:
- raise_errmsg(ERR_STRING_ESC4, pystr, end - 5);
- goto bail;
- }
- }
-#if defined(Py_UNICODE_WIDE)
- /* Surrogate pair */
- if ((c & 0xfc00) == 0xd800) {
- if (end + 6 < len && buf[next] == '\\' && buf[next+1] == 'u') {
- JSON_UNICHR c2 = 0;
- end += 6;
- /* Decode 4 hex digits */
- for (next += 2; next < end; next++) {
- c2 <<= 4;
- JSON_UNICHR digit = buf[next];
- switch (digit) {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- c2 |= (digit - '0'); break;
- case 'a': case 'b': case 'c': case 'd': case 'e':
- case 'f':
- c2 |= (digit - 'a' + 10); break;
- case 'A': case 'B': case 'C': case 'D': case 'E':
- case 'F':
- c2 |= (digit - 'A' + 10); break;
- default:
- raise_errmsg(ERR_STRING_ESC4, pystr, end - 5);
- goto bail;
- }
- }
- if ((c2 & 0xfc00) != 0xdc00) {
- /* not a low surrogate, rewind */
- end -= 6;
- next = end;
- }
- else {
- c = 0x10000 + (((c - 0xd800) << 10) | (c2 - 0xdc00));
- }
- }
- }
-#endif /* Py_UNICODE_WIDE */
- }
- if (c > 0x7f) {
- has_unicode = 1;
- }
- APPEND_OLD_CHUNK
- if (has_unicode) {
- chunk = PyUnicode_FromOrdinal(c);
- if (chunk == NULL) {
- goto bail;
- }
- }
- else {
- char c_char = Py_CHARMASK(c);
- chunk = PyString_FromStringAndSize(&c_char, 1);
- if (chunk == NULL) {
- goto bail;
- }
- }
- }
-
- if (chunks == NULL) {
- if (chunk != NULL)
- rval = chunk;
- else {
- rval = JSON_EmptyStr;
- Py_INCREF(rval);
- }
- }
- else {
- APPEND_OLD_CHUNK
- rval = join_list_string(chunks);
- if (rval == NULL) {
- goto bail;
- }
- Py_CLEAR(chunks);
- }
-
- *next_end_ptr = end;
- return rval;
-bail:
- *next_end_ptr = -1;
- Py_XDECREF(chunk);
- Py_XDECREF(chunks);
- return NULL;
-}
-#endif /* PY_MAJOR_VERSION < 3 */
-
-static PyObject *
-scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next_end_ptr)
-{
- /* Read the JSON string from PyUnicode pystr.
- end is the index of the first character after the quote.
- if strict is zero then literal control characters are allowed
- *next_end_ptr is a return-by-reference index of the character
- after the end quote
-
- Return value is a new PyUnicode
- */
- PyObject *rval;
- Py_ssize_t begin = end - 1;
- Py_ssize_t next = begin;
- PY2_UNUSED int kind = PyUnicode_KIND(pystr);
- Py_ssize_t len = PyUnicode_GET_LENGTH(pystr);
- void *buf = PyUnicode_DATA(pystr);
- PyObject *chunks = NULL;
- PyObject *chunk = NULL;
-
- if (len == end) {
- raise_errmsg(ERR_STRING_UNTERMINATED, pystr, begin);
- goto bail;
- }
- else if (end < 0 || len < end) {
- PyErr_SetString(PyExc_ValueError, "end is out of bounds");
- goto bail;
- }
- while (1) {
- /* Find the end of the string or the next escape */
- JSON_UNICHR c = 0;
- for (next = end; next < len; next++) {
- c = PyUnicode_READ(kind, buf, next);
- if (c == '"' || c == '\\') {
- break;
- }
- else if (strict && c <= 0x1f) {
- raise_errmsg(ERR_STRING_CONTROL, pystr, next);
- goto bail;
- }
- }
- if (!(c == '"' || c == '\\')) {
- raise_errmsg(ERR_STRING_UNTERMINATED, pystr, begin);
- goto bail;
- }
- /* Pick up this chunk if it's not zero length */
- if (next != end) {
- APPEND_OLD_CHUNK
-#if PY_MAJOR_VERSION < 3
- chunk = PyUnicode_FromUnicode(&((const Py_UNICODE *)buf)[end], next - end);
-#else
- chunk = PyUnicode_Substring(pystr, end, next);
-#endif
- if (chunk == NULL) {
- goto bail;
- }
- }
- next++;
- if (c == '"') {
- end = next;
- break;
- }
- if (next == len) {
- raise_errmsg(ERR_STRING_UNTERMINATED, pystr, begin);
- goto bail;
- }
- c = PyUnicode_READ(kind, buf, next);
- if (c != 'u') {
- /* Non-unicode backslash escapes */
- end = next + 1;
- switch (c) {
- case '"': break;
- case '\\': break;
- case '/': break;
- case 'b': c = '\b'; break;
- case 'f': c = '\f'; break;
- case 'n': c = '\n'; break;
- case 'r': c = '\r'; break;
- case 't': c = '\t'; break;
- default: c = 0;
- }
- if (c == 0) {
- raise_errmsg(ERR_STRING_ESC1, pystr, end - 2);
- goto bail;
- }
- }
- else {
- c = 0;
- next++;
- end = next + 4;
- if (end >= len) {
- raise_errmsg(ERR_STRING_ESC4, pystr, next - 1);
- goto bail;
- }
- /* Decode 4 hex digits */
- for (; next < end; next++) {
- JSON_UNICHR digit = PyUnicode_READ(kind, buf, next);
- c <<= 4;
- switch (digit) {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- c |= (digit - '0'); break;
- case 'a': case 'b': case 'c': case 'd': case 'e':
- case 'f':
- c |= (digit - 'a' + 10); break;
- case 'A': case 'B': case 'C': case 'D': case 'E':
- case 'F':
- c |= (digit - 'A' + 10); break;
- default:
- raise_errmsg(ERR_STRING_ESC4, pystr, end - 5);
- goto bail;
- }
- }
-#if PY_MAJOR_VERSION >= 3 || defined(Py_UNICODE_WIDE)
- /* Surrogate pair */
- if ((c & 0xfc00) == 0xd800) {
- JSON_UNICHR c2 = 0;
- if (end + 6 < len &&
- PyUnicode_READ(kind, buf, next) == '\\' &&
- PyUnicode_READ(kind, buf, next + 1) == 'u') {
- end += 6;
- /* Decode 4 hex digits */
- for (next += 2; next < end; next++) {
- JSON_UNICHR digit = PyUnicode_READ(kind, buf, next);
- c2 <<= 4;
- switch (digit) {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- c2 |= (digit - '0'); break;
- case 'a': case 'b': case 'c': case 'd': case 'e':
- case 'f':
- c2 |= (digit - 'a' + 10); break;
- case 'A': case 'B': case 'C': case 'D': case 'E':
- case 'F':
- c2 |= (digit - 'A' + 10); break;
- default:
- raise_errmsg(ERR_STRING_ESC4, pystr, end - 5);
- goto bail;
- }
- }
- if ((c2 & 0xfc00) != 0xdc00) {
- /* not a low surrogate, rewind */
- end -= 6;
- next = end;
- }
- else {
- c = 0x10000 + (((c - 0xd800) << 10) | (c2 - 0xdc00));
- }
- }
- }
-#endif
- }
- APPEND_OLD_CHUNK
- chunk = PyUnicode_FromOrdinal(c);
- if (chunk == NULL) {
- goto bail;
- }
- }
-
- if (chunks == NULL) {
- if (chunk != NULL)
- rval = chunk;
- else {
- rval = JSON_EmptyUnicode;
- Py_INCREF(rval);
- }
- }
- else {
- APPEND_OLD_CHUNK
- rval = join_list_unicode(chunks);
- if (rval == NULL) {
- goto bail;
- }
- Py_CLEAR(chunks);
- }
- *next_end_ptr = end;
- return rval;
-bail:
- *next_end_ptr = -1;
- Py_XDECREF(chunk);
- Py_XDECREF(chunks);
- return NULL;
-}
-
-PyDoc_STRVAR(pydoc_scanstring,
- "scanstring(basestring, end, encoding, strict=True) -> (str, end)\n"
- "\n"
- "Scan the string s for a JSON string. End is the index of the\n"
- "character in s after the quote that started the JSON string.\n"
- "Unescapes all valid JSON string escape sequences and raises ValueError\n"
- "on attempt to decode an invalid string. If strict is False then literal\n"
- "control characters are allowed in the string.\n"
- "\n"
- "Returns a tuple of the decoded string and the index of the character in s\n"
- "after the end quote."
-);
-
-static PyObject *
-py_scanstring(PyObject* self UNUSED, PyObject *args)
-{
- PyObject *pystr;
- PyObject *rval;
- Py_ssize_t end;
- Py_ssize_t next_end = -1;
- char *encoding = NULL;
- int strict = 1;
- if (!PyArg_ParseTuple(args, "OO&|zi:scanstring", &pystr, _convertPyInt_AsSsize_t, &end, &encoding, &strict)) {
- return NULL;
- }
- if (encoding == NULL) {
- encoding = DEFAULT_ENCODING;
- }
- if (PyUnicode_Check(pystr)) {
- if (PyUnicode_READY(pystr))
- return NULL;
- rval = scanstring_unicode(pystr, end, strict, &next_end);
- }
-#if PY_MAJOR_VERSION < 3
- /* Using a bytes input is unsupported for scanning in Python 3.
- It is coerced to str in the decoder before it gets here. */
- else if (PyString_Check(pystr)) {
- rval = scanstring_str(pystr, end, encoding, strict, &next_end);
- }
-#endif
- else {
- PyErr_Format(PyExc_TypeError,
- "first argument must be a string, not %.80s",
- Py_TYPE(pystr)->tp_name);
- return NULL;
- }
- return _build_rval_index_tuple(rval, next_end);
-}
-
-PyDoc_STRVAR(pydoc_encode_basestring_ascii,
- "encode_basestring_ascii(basestring) -> str\n"
- "\n"
- "Return an ASCII-only JSON representation of a Python string"
-);
-
-static PyObject *
-py_encode_basestring_ascii(PyObject* self UNUSED, PyObject *pystr)
-{
- /* Return an ASCII-only JSON representation of a Python string */
- /* METH_O */
- if (PyBytes_Check(pystr)) {
- return ascii_escape_str(pystr);
- }
- else if (PyUnicode_Check(pystr)) {
- if (PyUnicode_READY(pystr))
- return NULL;
- return ascii_escape_unicode(pystr);
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "first argument must be a string, not %.80s",
- Py_TYPE(pystr)->tp_name);
- return NULL;
- }
-}
-
-static void
-scanner_dealloc(PyObject *self)
-{
- /* bpo-31095: UnTrack is needed before calling any callbacks */
- PyObject_GC_UnTrack(self);
- scanner_clear(self);
- Py_TYPE(self)->tp_free(self);
-}
-
-static int
-scanner_traverse(PyObject *self, visitproc visit, void *arg)
-{
- PyScannerObject *s;
- assert(PyScanner_Check(self));
- s = (PyScannerObject *)self;
- Py_VISIT(s->encoding);
- Py_VISIT(s->strict_bool);
- Py_VISIT(s->object_hook);
- Py_VISIT(s->pairs_hook);
- Py_VISIT(s->parse_float);
- Py_VISIT(s->parse_int);
- Py_VISIT(s->parse_constant);
- Py_VISIT(s->memo);
- return 0;
-}
-
-static int
-scanner_clear(PyObject *self)
-{
- PyScannerObject *s;
- assert(PyScanner_Check(self));
- s = (PyScannerObject *)self;
- Py_CLEAR(s->encoding);
- Py_CLEAR(s->strict_bool);
- Py_CLEAR(s->object_hook);
- Py_CLEAR(s->pairs_hook);
- Py_CLEAR(s->parse_float);
- Py_CLEAR(s->parse_int);
- Py_CLEAR(s->parse_constant);
- Py_CLEAR(s->memo);
- return 0;
-}
-
-#if PY_MAJOR_VERSION < 3
-static PyObject *
-_parse_object_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr)
-{
- /* Read a JSON object from PyString pystr.
- idx is the index of the first character after the opening curly brace.
- *next_idx_ptr is a return-by-reference index to the first character after
- the closing curly brace.
-
- Returns a new PyObject (usually a dict, but object_hook or
- object_pairs_hook can change that)
- */
- char *str = PyString_AS_STRING(pystr);
- Py_ssize_t end_idx = PyString_GET_SIZE(pystr) - 1;
- PyObject *rval = NULL;
- PyObject *pairs = NULL;
- PyObject *item;
- PyObject *key = NULL;
- PyObject *val = NULL;
- char *encoding = PyString_AS_STRING(s->encoding);
- int has_pairs_hook = (s->pairs_hook != Py_None);
- int did_parse = 0;
- Py_ssize_t next_idx;
- if (has_pairs_hook) {
- pairs = PyList_New(0);
- if (pairs == NULL)
- return NULL;
- }
- else {
- rval = PyDict_New();
- if (rval == NULL)
- return NULL;
- }
-
- /* skip whitespace after { */
- while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++;
-
- /* only loop if the object is non-empty */
- if (idx <= end_idx && str[idx] != '}') {
- int trailing_delimiter = 0;
- while (idx <= end_idx) {
- PyObject *memokey;
- trailing_delimiter = 0;
-
- /* read key */
- if (str[idx] != '"') {
- raise_errmsg(ERR_OBJECT_PROPERTY, pystr, idx);
- goto bail;
- }
- key = scanstring_str(pystr, idx + 1, encoding, s->strict, &next_idx);
- if (key == NULL)
- goto bail;
- memokey = PyDict_GetItem(s->memo, key);
- if (memokey != NULL) {
- Py_INCREF(memokey);
- Py_DECREF(key);
- key = memokey;
- }
- else {
- if (PyDict_SetItem(s->memo, key, key) < 0)
- goto bail;
- }
- idx = next_idx;
-
- /* skip whitespace between key and : delimiter, read :, skip whitespace */
- while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++;
- if (idx > end_idx || str[idx] != ':') {
- raise_errmsg(ERR_OBJECT_PROPERTY_DELIMITER, pystr, idx);
- goto bail;
- }
- idx++;
- while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++;
-
- /* read any JSON data type */
- val = scan_once_str(s, pystr, idx, &next_idx);
- if (val == NULL)
- goto bail;
-
- if (has_pairs_hook) {
- item = PyTuple_Pack(2, key, val);
- if (item == NULL)
- goto bail;
- Py_CLEAR(key);
- Py_CLEAR(val);
- if (PyList_Append(pairs, item) == -1) {
- Py_DECREF(item);
- goto bail;
- }
- Py_DECREF(item);
- }
- else {
- if (PyDict_SetItem(rval, key, val) < 0)
- goto bail;
- Py_CLEAR(key);
- Py_CLEAR(val);
- }
- idx = next_idx;
-
- /* skip whitespace before } or , */
- while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++;
-
- /* bail if the object is closed or we didn't get the , delimiter */
- did_parse = 1;
- if (idx > end_idx) break;
- if (str[idx] == '}') {
- break;
- }
- else if (str[idx] != ',') {
- raise_errmsg(ERR_OBJECT_DELIMITER, pystr, idx);
- goto bail;
- }
- idx++;
-
- /* skip whitespace after , delimiter */
- while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++;
- trailing_delimiter = 1;
- }
- if (trailing_delimiter) {
- raise_errmsg(ERR_OBJECT_PROPERTY, pystr, idx);
- goto bail;
- }
- }
- /* verify that idx < end_idx, str[idx] should be '}' */
- if (idx > end_idx || str[idx] != '}') {
- if (did_parse) {
- raise_errmsg(ERR_OBJECT_DELIMITER, pystr, idx);
- } else {
- raise_errmsg(ERR_OBJECT_PROPERTY_FIRST, pystr, idx);
- }
- goto bail;
- }
-
- /* if pairs_hook is not None: rval = object_pairs_hook(pairs) */
- if (s->pairs_hook != Py_None) {
- val = PyObject_CallOneArg(s->pairs_hook, pairs);
- if (val == NULL)
- goto bail;
- Py_DECREF(pairs);
- *next_idx_ptr = idx + 1;
- return val;
- }
-
- /* if object_hook is not None: rval = object_hook(rval) */
- if (s->object_hook != Py_None) {
- val = PyObject_CallOneArg(s->object_hook, rval);
- if (val == NULL)
- goto bail;
- Py_DECREF(rval);
- rval = val;
- val = NULL;
- }
- *next_idx_ptr = idx + 1;
- return rval;
-bail:
- Py_XDECREF(rval);
- Py_XDECREF(key);
- Py_XDECREF(val);
- Py_XDECREF(pairs);
- return NULL;
-}
-#endif /* PY_MAJOR_VERSION < 3 */
-
-static PyObject *
-_parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr)
-{
- /* Read a JSON object from PyUnicode pystr.
- idx is the index of the first character after the opening curly brace.
- *next_idx_ptr is a return-by-reference index to the first character after
- the closing curly brace.
-
- Returns a new PyObject (usually a dict, but object_hook can change that)
- */
- void *str = PyUnicode_DATA(pystr);
- Py_ssize_t end_idx = PyUnicode_GET_LENGTH(pystr) - 1;
- PY2_UNUSED int kind = PyUnicode_KIND(pystr);
- PyObject *rval = NULL;
- PyObject *pairs = NULL;
- PyObject *item;
- PyObject *key = NULL;
- PyObject *val = NULL;
- int has_pairs_hook = (s->pairs_hook != Py_None);
- int did_parse = 0;
- Py_ssize_t next_idx;
-
- if (has_pairs_hook) {
- pairs = PyList_New(0);
- if (pairs == NULL)
- return NULL;
- }
- else {
- rval = PyDict_New();
- if (rval == NULL)
- return NULL;
- }
-
- /* skip whitespace after { */
- while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
-
- /* only loop if the object is non-empty */
- if (idx <= end_idx && PyUnicode_READ(kind, str, idx) != '}') {
- int trailing_delimiter = 0;
- while (idx <= end_idx) {
- PyObject *memokey;
- trailing_delimiter = 0;
-
- /* read key */
- if (PyUnicode_READ(kind, str, idx) != '"') {
- raise_errmsg(ERR_OBJECT_PROPERTY, pystr, idx);
- goto bail;
- }
- key = scanstring_unicode(pystr, idx + 1, s->strict, &next_idx);
- if (key == NULL)
- goto bail;
- memokey = PyDict_GetItem(s->memo, key);
- if (memokey != NULL) {
- Py_INCREF(memokey);
- Py_DECREF(key);
- key = memokey;
- }
- else {
- if (PyDict_SetItem(s->memo, key, key) < 0)
- goto bail;
- }
- idx = next_idx;
-
- /* skip whitespace between key and : delimiter, read :, skip
- whitespace */
- while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
- if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ':') {
- raise_errmsg(ERR_OBJECT_PROPERTY_DELIMITER, pystr, idx);
- goto bail;
- }
- idx++;
- while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
-
- /* read any JSON term */
- val = scan_once_unicode(s, pystr, idx, &next_idx);
- if (val == NULL)
- goto bail;
-
- if (has_pairs_hook) {
- item = PyTuple_Pack(2, key, val);
- if (item == NULL)
- goto bail;
- Py_CLEAR(key);
- Py_CLEAR(val);
- if (PyList_Append(pairs, item) == -1) {
- Py_DECREF(item);
- goto bail;
- }
- Py_DECREF(item);
- }
- else {
- if (PyDict_SetItem(rval, key, val) < 0)
- goto bail;
- Py_CLEAR(key);
- Py_CLEAR(val);
- }
- idx = next_idx;
-
- /* skip whitespace before } or , */
- while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
-
- /* bail if the object is closed or we didn't get the ,
- delimiter */
- did_parse = 1;
- if (idx > end_idx) break;
- if (PyUnicode_READ(kind, str, idx) == '}') {
- break;
- }
- else if (PyUnicode_READ(kind, str, idx) != ',') {
- raise_errmsg(ERR_OBJECT_DELIMITER, pystr, idx);
- goto bail;
- }
- idx++;
-
- /* skip whitespace after , delimiter */
- while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
- trailing_delimiter = 1;
- }
- if (trailing_delimiter) {
- raise_errmsg(ERR_OBJECT_PROPERTY, pystr, idx);
- goto bail;
- }
- }
-
- /* verify that idx < end_idx, str[idx] should be '}' */
- if (idx > end_idx || PyUnicode_READ(kind, str, idx) != '}') {
- if (did_parse) {
- raise_errmsg(ERR_OBJECT_DELIMITER, pystr, idx);
- } else {
- raise_errmsg(ERR_OBJECT_PROPERTY_FIRST, pystr, idx);
- }
- goto bail;
- }
-
- /* if pairs_hook is not None: rval = object_pairs_hook(pairs) */
- if (s->pairs_hook != Py_None) {
- val = PyObject_CallOneArg(s->pairs_hook, pairs);
- if (val == NULL)
- goto bail;
- Py_DECREF(pairs);
- *next_idx_ptr = idx + 1;
- return val;
- }
-
- /* if object_hook is not None: rval = object_hook(rval) */
- if (s->object_hook != Py_None) {
- val = PyObject_CallOneArg(s->object_hook, rval);
- if (val == NULL)
- goto bail;
- Py_DECREF(rval);
- rval = val;
- val = NULL;
- }
- *next_idx_ptr = idx + 1;
- return rval;
-bail:
- Py_XDECREF(rval);
- Py_XDECREF(key);
- Py_XDECREF(val);
- Py_XDECREF(pairs);
- return NULL;
-}
-
-#if PY_MAJOR_VERSION < 3
-static PyObject *
-_parse_array_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr)
-{
- /* Read a JSON array from PyString pystr.
- idx is the index of the first character after the opening brace.
- *next_idx_ptr is a return-by-reference index to the first character after
- the closing brace.
-
- Returns a new PyList
- */
- char *str = PyString_AS_STRING(pystr);
- Py_ssize_t end_idx = PyString_GET_SIZE(pystr) - 1;
- PyObject *val = NULL;
- PyObject *rval = PyList_New(0);
- Py_ssize_t next_idx;
- if (rval == NULL)
- return NULL;
-
- /* skip whitespace after [ */
- while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++;
-
- /* only loop if the array is non-empty */
- if (idx <= end_idx && str[idx] != ']') {
- int trailing_delimiter = 0;
- while (idx <= end_idx) {
- trailing_delimiter = 0;
- /* read any JSON term and de-tuplefy the (rval, idx) */
- val = scan_once_str(s, pystr, idx, &next_idx);
- if (val == NULL) {
- goto bail;
- }
-
- if (PyList_Append(rval, val) == -1)
- goto bail;
-
- Py_CLEAR(val);
- idx = next_idx;
-
- /* skip whitespace between term and , */
- while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++;
-
- /* bail if the array is closed or we didn't get the , delimiter */
- if (idx > end_idx) break;
- if (str[idx] == ']') {
- break;
- }
- else if (str[idx] != ',') {
- raise_errmsg(ERR_ARRAY_DELIMITER, pystr, idx);
- goto bail;
- }
- idx++;
-
- /* skip whitespace after , */
- while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++;
- trailing_delimiter = 1;
- }
- if (trailing_delimiter) {
- raise_errmsg(ERR_EXPECTING_VALUE, pystr, idx);
- goto bail;
- }
- }
-
- /* verify that idx < end_idx, str[idx] should be ']' */
- if (idx > end_idx || str[idx] != ']') {
- if (PyList_GET_SIZE(rval)) {
- raise_errmsg(ERR_ARRAY_DELIMITER, pystr, idx);
- } else {
- raise_errmsg(ERR_ARRAY_VALUE_FIRST, pystr, idx);
- }
- goto bail;
- }
- *next_idx_ptr = idx + 1;
- return rval;
-bail:
- Py_XDECREF(val);
- Py_DECREF(rval);
- return NULL;
-}
-#endif /* PY_MAJOR_VERSION < 3 */
-
-static PyObject *
-_parse_array_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr)
-{
- /* Read a JSON array from PyString pystr.
- idx is the index of the first character after the opening brace.
- *next_idx_ptr is a return-by-reference index to the first character after
- the closing brace.
-
- Returns a new PyList
- */
- PY2_UNUSED int kind = PyUnicode_KIND(pystr);
- void *str = PyUnicode_DATA(pystr);
- Py_ssize_t end_idx = PyUnicode_GET_LENGTH(pystr) - 1;
- PyObject *val = NULL;
- PyObject *rval = PyList_New(0);
- Py_ssize_t next_idx;
- if (rval == NULL)
- return NULL;
-
- /* skip whitespace after [ */
- while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
-
- /* only loop if the array is non-empty */
- if (idx <= end_idx && PyUnicode_READ(kind, str, idx) != ']') {
- int trailing_delimiter = 0;
- while (idx <= end_idx) {
- trailing_delimiter = 0;
- /* read any JSON term */
- val = scan_once_unicode(s, pystr, idx, &next_idx);
- if (val == NULL) {
- goto bail;
- }
-
- if (PyList_Append(rval, val) == -1)
- goto bail;
-
- Py_CLEAR(val);
- idx = next_idx;
-
- /* skip whitespace between term and , */
- while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
-
- /* bail if the array is closed or we didn't get the , delimiter */
- if (idx > end_idx) break;
- if (PyUnicode_READ(kind, str, idx) == ']') {
- break;
- }
- else if (PyUnicode_READ(kind, str, idx) != ',') {
- raise_errmsg(ERR_ARRAY_DELIMITER, pystr, idx);
- goto bail;
- }
- idx++;
-
- /* skip whitespace after , */
- while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
- trailing_delimiter = 1;
- }
- if (trailing_delimiter) {
- raise_errmsg(ERR_EXPECTING_VALUE, pystr, idx);
- goto bail;
- }
- }
-
- /* verify that idx < end_idx, str[idx] should be ']' */
- if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ']') {
- if (PyList_GET_SIZE(rval)) {
- raise_errmsg(ERR_ARRAY_DELIMITER, pystr, idx);
- } else {
- raise_errmsg(ERR_ARRAY_VALUE_FIRST, pystr, idx);
- }
- goto bail;
- }
- *next_idx_ptr = idx + 1;
- return rval;
-bail:
- Py_XDECREF(val);
- Py_DECREF(rval);
- return NULL;
-}
-
-static PyObject *
-_parse_constant(PyScannerObject *s, PyObject *constant, Py_ssize_t idx, Py_ssize_t *next_idx_ptr)
-{
- /* Read a JSON constant from PyString pystr.
- constant is the Python string that was found
- ("NaN", "Infinity", "-Infinity").
- idx is the index of the first character of the constant
- *next_idx_ptr is a return-by-reference index to the first character after
- the constant.
-
- Returns the result of parse_constant
- */
- PyObject *rval;
-
- /* rval = parse_constant(constant) */
- rval = PyObject_CallOneArg(s->parse_constant, constant);
- idx += PyString_GET_SIZE(constant);
- *next_idx_ptr = idx;
- return rval;
-}
-
-#if PY_MAJOR_VERSION < 3
-static PyObject *
-_match_number_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t start, Py_ssize_t *next_idx_ptr)
-{
- /* Read a JSON number from PyString pystr.
- idx is the index of the first character of the number
- *next_idx_ptr is a return-by-reference index to the first character after
- the number.
-
- Returns a new PyObject representation of that number:
- PyInt, PyLong, or PyFloat.
- May return other types if parse_int or parse_float are set
- */
- char *str = PyString_AS_STRING(pystr);
- Py_ssize_t end_idx = PyString_GET_SIZE(pystr) - 1;
- Py_ssize_t idx = start;
- int is_float = 0;
- PyObject *rval;
- PyObject *numstr;
-
- /* read a sign if it's there, make sure it's not the end of the string */
- if (str[idx] == '-') {
- if (idx >= end_idx) {
- raise_errmsg(ERR_EXPECTING_VALUE, pystr, idx);
- return NULL;
- }
- idx++;
- }
-
- /* read as many integer digits as we find as long as it doesn't start with 0 */
- if (str[idx] >= '1' && str[idx] <= '9') {
- idx++;
- while (idx <= end_idx && str[idx] >= '0' && str[idx] <= '9') idx++;
- }
- /* if it starts with 0 we only expect one integer digit */
- else if (str[idx] == '0') {
- idx++;
- }
- /* no integer digits, error */
- else {
- raise_errmsg(ERR_EXPECTING_VALUE, pystr, idx);
- return NULL;
- }
-
- /* if the next char is '.' followed by a digit then read all float digits */
- if (idx < end_idx && str[idx] == '.' && str[idx + 1] >= '0' && str[idx + 1] <= '9') {
- is_float = 1;
- idx += 2;
- while (idx <= end_idx && str[idx] >= '0' && str[idx] <= '9') idx++;
- }
-
- /* if the next char is 'e' or 'E' then maybe read the exponent (or backtrack) */
- if (idx < end_idx && (str[idx] == 'e' || str[idx] == 'E')) {
-
- /* save the index of the 'e' or 'E' just in case we need to backtrack */
- Py_ssize_t e_start = idx;
- idx++;
-
- /* read an exponent sign if present */
- if (idx < end_idx && (str[idx] == '-' || str[idx] == '+')) idx++;
-
- /* read all digits */
- while (idx <= end_idx && str[idx] >= '0' && str[idx] <= '9') idx++;
-
- /* if we got a digit, then parse as float. if not, backtrack */
- if (str[idx - 1] >= '0' && str[idx - 1] <= '9') {
- is_float = 1;
- }
- else {
- idx = e_start;
- }
- }
-
- /* copy the section we determined to be a number */
- numstr = PyString_FromStringAndSize(&str[start], idx - start);
- if (numstr == NULL)
- return NULL;
- if (is_float) {
- /* parse as a float using a fast path if available, otherwise call user defined method */
- if (s->parse_float != (PyObject *)&PyFloat_Type) {
- rval = PyObject_CallOneArg(s->parse_float, numstr);
- }
- else {
- /* rval = PyFloat_FromDouble(PyOS_ascii_atof(PyString_AS_STRING(numstr))); */
- double d = PyOS_string_to_double(PyString_AS_STRING(numstr),
- NULL, NULL);
- if (d == -1.0 && PyErr_Occurred())
- return NULL;
- rval = PyFloat_FromDouble(d);
- }
- }
- else {
- /* parse as an int using a fast path if available, otherwise call user defined method */
- if (s->parse_int != (PyObject *)&PyInt_Type) {
- rval = PyObject_CallOneArg(s->parse_int, numstr);
- }
- else {
- rval = PyInt_FromString(PyString_AS_STRING(numstr), NULL, 10);
- }
- }
- Py_DECREF(numstr);
- *next_idx_ptr = idx;
- return rval;
-}
-#endif /* PY_MAJOR_VERSION < 3 */
-
-static PyObject *
-_match_number_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t start, Py_ssize_t *next_idx_ptr)
-{
- /* Read a JSON number from PyUnicode pystr.
- idx is the index of the first character of the number
- *next_idx_ptr is a return-by-reference index to the first character after
- the number.
-
- Returns a new PyObject representation of that number:
- PyInt, PyLong, or PyFloat.
- May return other types if parse_int or parse_float are set
- */
- PY2_UNUSED int kind = PyUnicode_KIND(pystr);
- void *str = PyUnicode_DATA(pystr);
- Py_ssize_t end_idx = PyUnicode_GET_LENGTH(pystr) - 1;
- Py_ssize_t idx = start;
- int is_float = 0;
- JSON_UNICHR c;
- PyObject *rval;
- PyObject *numstr;
-
- /* read a sign if it's there, make sure it's not the end of the string */
- if (PyUnicode_READ(kind, str, idx) == '-') {
- if (idx >= end_idx) {
- raise_errmsg(ERR_EXPECTING_VALUE, pystr, idx);
- return NULL;
- }
- idx++;
- }
-
- /* read as many integer digits as we find as long as it doesn't start with 0 */
- c = PyUnicode_READ(kind, str, idx);
- if (c == '0') {
- /* if it starts with 0 we only expect one integer digit */
- idx++;
- }
- else if (IS_DIGIT(c)) {
- idx++;
- while (idx <= end_idx && IS_DIGIT(PyUnicode_READ(kind, str, idx))) {
- idx++;
- }
- }
- else {
- /* no integer digits, error */
- raise_errmsg(ERR_EXPECTING_VALUE, pystr, idx);
- return NULL;
- }
-
- /* if the next char is '.' followed by a digit then read all float digits */
- if (idx < end_idx &&
- PyUnicode_READ(kind, str, idx) == '.' &&
- IS_DIGIT(PyUnicode_READ(kind, str, idx + 1))) {
- is_float = 1;
- idx += 2;
- while (idx <= end_idx && IS_DIGIT(PyUnicode_READ(kind, str, idx))) idx++;
- }
-
- /* if the next char is 'e' or 'E' then maybe read the exponent (or backtrack) */
- if (idx < end_idx &&
- (PyUnicode_READ(kind, str, idx) == 'e' ||
- PyUnicode_READ(kind, str, idx) == 'E')) {
- Py_ssize_t e_start = idx;
- idx++;
-
- /* read an exponent sign if present */
- if (idx < end_idx &&
- (PyUnicode_READ(kind, str, idx) == '-' ||
- PyUnicode_READ(kind, str, idx) == '+')) idx++;
-
- /* read all digits */
- while (idx <= end_idx && IS_DIGIT(PyUnicode_READ(kind, str, idx))) idx++;
-
- /* if we got a digit, then parse as float. if not, backtrack */
- if (IS_DIGIT(PyUnicode_READ(kind, str, idx - 1))) {
- is_float = 1;
- }
- else {
- idx = e_start;
- }
- }
-
- /* copy the section we determined to be a number */
-#if PY_MAJOR_VERSION >= 3
- numstr = PyUnicode_Substring(pystr, start, idx);
-#else
- numstr = PyUnicode_FromUnicode(&((Py_UNICODE *)str)[start], idx - start);
-#endif
- if (numstr == NULL)
- return NULL;
- if (is_float) {
- /* parse as a float using a fast path if available, otherwise call user defined method */
- if (s->parse_float != (PyObject *)&PyFloat_Type) {
- rval = PyObject_CallOneArg(s->parse_float, numstr);
- }
- else {
-#if PY_MAJOR_VERSION >= 3
- rval = PyFloat_FromString(numstr);
-#else
- rval = PyFloat_FromString(numstr, NULL);
-#endif
- }
- }
- else {
- /* no fast path for unicode -> int, just call */
- rval = PyObject_CallOneArg(s->parse_int, numstr);
- }
- Py_DECREF(numstr);
- *next_idx_ptr = idx;
- return rval;
-}
-
-#if PY_MAJOR_VERSION < 3
-static PyObject *
-scan_once_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr)
-{
- /* Read one JSON term (of any kind) from PyString pystr.
- idx is the index of the first character of the term
- *next_idx_ptr is a return-by-reference index to the first character after
- the number.
-
- Returns a new PyObject representation of the term.
- */
- char *str = PyString_AS_STRING(pystr);
- Py_ssize_t length = PyString_GET_SIZE(pystr);
- PyObject *rval = NULL;
- int fallthrough = 0;
- if (idx < 0 || idx >= length) {
- raise_errmsg(ERR_EXPECTING_VALUE, pystr, idx);
- return NULL;
- }
- switch (str[idx]) {
- case '"':
- /* string */
- rval = scanstring_str(pystr, idx + 1,
- PyString_AS_STRING(s->encoding),
- s->strict,
- next_idx_ptr);
- break;
- case '{':
- /* object */
- if (Py_EnterRecursiveCall(" while decoding a JSON object "
- "from a string"))
- return NULL;
- rval = _parse_object_str(s, pystr, idx + 1, next_idx_ptr);
- Py_LeaveRecursiveCall();
- break;
- case '[':
- /* array */
- if (Py_EnterRecursiveCall(" while decoding a JSON array "
- "from a string"))
- return NULL;
- rval = _parse_array_str(s, pystr, idx + 1, next_idx_ptr);
- Py_LeaveRecursiveCall();
- break;
- case 'n':
- /* null */
- if ((idx + 3 < length) && str[idx + 1] == 'u' && str[idx + 2] == 'l' && str[idx + 3] == 'l') {
- Py_INCREF(Py_None);
- *next_idx_ptr = idx + 4;
- rval = Py_None;
- }
- else
- fallthrough = 1;
- break;
- case 't':
- /* true */
- if ((idx + 3 < length) && str[idx + 1] == 'r' && str[idx + 2] == 'u' && str[idx + 3] == 'e') {
- Py_INCREF(Py_True);
- *next_idx_ptr = idx + 4;
- rval = Py_True;
- }
- else
- fallthrough = 1;
- break;
- case 'f':
- /* false */
- if ((idx + 4 < length) && str[idx + 1] == 'a' && str[idx + 2] == 'l' && str[idx + 3] == 's' && str[idx + 4] == 'e') {
- Py_INCREF(Py_False);
- *next_idx_ptr = idx + 5;
- rval = Py_False;
- }
- else
- fallthrough = 1;
- break;
- case 'N':
- /* NaN */
- if ((idx + 2 < length) && str[idx + 1] == 'a' && str[idx + 2] == 'N') {
- rval = _parse_constant(s, JSON_NaN, idx, next_idx_ptr);
- }
- else
- fallthrough = 1;
- break;
- case 'I':
- /* Infinity */
- if ((idx + 7 < length) && str[idx + 1] == 'n' && str[idx + 2] == 'f' && str[idx + 3] == 'i' && str[idx + 4] == 'n' && str[idx + 5] == 'i' && str[idx + 6] == 't' && str[idx + 7] == 'y') {
- rval = _parse_constant(s, JSON_Infinity, idx, next_idx_ptr);
- }
- else
- fallthrough = 1;
- break;
- case '-':
- /* -Infinity */
- if ((idx + 8 < length) && str[idx + 1] == 'I' && str[idx + 2] == 'n' && str[idx + 3] == 'f' && str[idx + 4] == 'i' && str[idx + 5] == 'n' && str[idx + 6] == 'i' && str[idx + 7] == 't' && str[idx + 8] == 'y') {
- rval = _parse_constant(s, JSON_NegInfinity, idx, next_idx_ptr);
- }
- else
- fallthrough = 1;
- break;
- default:
- fallthrough = 1;
- }
- /* Didn't find a string, object, array, or named constant. Look for a number. */
- if (fallthrough)
- rval = _match_number_str(s, pystr, idx, next_idx_ptr);
- return rval;
-}
-#endif /* PY_MAJOR_VERSION < 3 */
-
-
-static PyObject *
-scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr)
-{
- /* Read one JSON term (of any kind) from PyUnicode pystr.
- idx is the index of the first character of the term
- *next_idx_ptr is a return-by-reference index to the first character after
- the number.
-
- Returns a new PyObject representation of the term.
- */
- PY2_UNUSED int kind = PyUnicode_KIND(pystr);
- void *str = PyUnicode_DATA(pystr);
- Py_ssize_t length = PyUnicode_GET_LENGTH(pystr);
- PyObject *rval = NULL;
- int fallthrough = 0;
- if (idx < 0 || idx >= length) {
- raise_errmsg(ERR_EXPECTING_VALUE, pystr, idx);
- return NULL;
- }
- switch (PyUnicode_READ(kind, str, idx)) {
- case '"':
- /* string */
- rval = scanstring_unicode(pystr, idx + 1,
- s->strict,
- next_idx_ptr);
- break;
- case '{':
- /* object */
- if (Py_EnterRecursiveCall(" while decoding a JSON object "
- "from a unicode string"))
- return NULL;
- rval = _parse_object_unicode(s, pystr, idx + 1, next_idx_ptr);
- Py_LeaveRecursiveCall();
- break;
- case '[':
- /* array */
- if (Py_EnterRecursiveCall(" while decoding a JSON array "
- "from a unicode string"))
- return NULL;
- rval = _parse_array_unicode(s, pystr, idx + 1, next_idx_ptr);
- Py_LeaveRecursiveCall();
- break;
- case 'n':
- /* null */
- if ((idx + 3 < length) &&
- PyUnicode_READ(kind, str, idx + 1) == 'u' &&
- PyUnicode_READ(kind, str, idx + 2) == 'l' &&
- PyUnicode_READ(kind, str, idx + 3) == 'l') {
- Py_INCREF(Py_None);
- *next_idx_ptr = idx + 4;
- rval = Py_None;
- }
- else
- fallthrough = 1;
- break;
- case 't':
- /* true */
- if ((idx + 3 < length) &&
- PyUnicode_READ(kind, str, idx + 1) == 'r' &&
- PyUnicode_READ(kind, str, idx + 2) == 'u' &&
- PyUnicode_READ(kind, str, idx + 3) == 'e') {
- Py_INCREF(Py_True);
- *next_idx_ptr = idx + 4;
- rval = Py_True;
- }
- else
- fallthrough = 1;
- break;
- case 'f':
- /* false */
- if ((idx + 4 < length) &&
- PyUnicode_READ(kind, str, idx + 1) == 'a' &&
- PyUnicode_READ(kind, str, idx + 2) == 'l' &&
- PyUnicode_READ(kind, str, idx + 3) == 's' &&
- PyUnicode_READ(kind, str, idx + 4) == 'e') {
- Py_INCREF(Py_False);
- *next_idx_ptr = idx + 5;
- rval = Py_False;
- }
- else
- fallthrough = 1;
- break;
- case 'N':
- /* NaN */
- if ((idx + 2 < length) &&
- PyUnicode_READ(kind, str, idx + 1) == 'a' &&
- PyUnicode_READ(kind, str, idx + 2) == 'N') {
- rval = _parse_constant(s, JSON_NaN, idx, next_idx_ptr);
- }
- else
- fallthrough = 1;
- break;
- case 'I':
- /* Infinity */
- if ((idx + 7 < length) &&
- PyUnicode_READ(kind, str, idx + 1) == 'n' &&
- PyUnicode_READ(kind, str, idx + 2) == 'f' &&
- PyUnicode_READ(kind, str, idx + 3) == 'i' &&
- PyUnicode_READ(kind, str, idx + 4) == 'n' &&
- PyUnicode_READ(kind, str, idx + 5) == 'i' &&
- PyUnicode_READ(kind, str, idx + 6) == 't' &&
- PyUnicode_READ(kind, str, idx + 7) == 'y') {
- rval = _parse_constant(s, JSON_Infinity, idx, next_idx_ptr);
- }
- else
- fallthrough = 1;
- break;
- case '-':
- /* -Infinity */
- if ((idx + 8 < length) &&
- PyUnicode_READ(kind, str, idx + 1) == 'I' &&
- PyUnicode_READ(kind, str, idx + 2) == 'n' &&
- PyUnicode_READ(kind, str, idx + 3) == 'f' &&
- PyUnicode_READ(kind, str, idx + 4) == 'i' &&
- PyUnicode_READ(kind, str, idx + 5) == 'n' &&
- PyUnicode_READ(kind, str, idx + 6) == 'i' &&
- PyUnicode_READ(kind, str, idx + 7) == 't' &&
- PyUnicode_READ(kind, str, idx + 8) == 'y') {
- rval = _parse_constant(s, JSON_NegInfinity, idx, next_idx_ptr);
- }
- else
- fallthrough = 1;
- break;
- default:
- fallthrough = 1;
- }
- /* Didn't find a string, object, array, or named constant. Look for a number. */
- if (fallthrough)
- rval = _match_number_unicode(s, pystr, idx, next_idx_ptr);
- return rval;
-}
-
-static PyObject *
-scanner_call(PyObject *self, PyObject *args, PyObject *kwds)
-{
- /* Python callable interface to scan_once_{str,unicode} */
- PyObject *pystr;
- PyObject *rval;
- Py_ssize_t idx;
- Py_ssize_t next_idx = -1;
- static char *kwlist[] = {"string", "idx", NULL};
- PyScannerObject *s;
- assert(PyScanner_Check(self));
- s = (PyScannerObject *)self;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&:scan_once", kwlist, &pystr, _convertPyInt_AsSsize_t, &idx))
- return NULL;
-
- if (PyUnicode_Check(pystr)) {
- if (PyUnicode_READY(pystr))
- return NULL;
- rval = scan_once_unicode(s, pystr, idx, &next_idx);
- }
-#if PY_MAJOR_VERSION < 3
- else if (PyString_Check(pystr)) {
- rval = scan_once_str(s, pystr, idx, &next_idx);
- }
-#endif /* PY_MAJOR_VERSION < 3 */
- else {
- PyErr_Format(PyExc_TypeError,
- "first argument must be a string, not %.80s",
- Py_TYPE(pystr)->tp_name);
- return NULL;
- }
- PyDict_Clear(s->memo);
- return _build_rval_index_tuple(rval, next_idx);
-}
-
-static PyObject *
-JSON_ParseEncoding(PyObject *encoding)
-{
- if (encoding == Py_None)
- return JSON_InternFromString(DEFAULT_ENCODING);
-#if PY_MAJOR_VERSION >= 3
- if (PyUnicode_Check(encoding)) {
- if (PyUnicode_AsUTF8(encoding) == NULL) {
- return NULL;
- }
- Py_INCREF(encoding);
- return encoding;
- }
-#else /* PY_MAJOR_VERSION >= 3 */
- if (PyString_Check(encoding)) {
- Py_INCREF(encoding);
- return encoding;
- }
- if (PyUnicode_Check(encoding))
- return PyUnicode_AsEncodedString(encoding, NULL, NULL);
-#endif /* PY_MAJOR_VERSION >= 3 */
- PyErr_SetString(PyExc_TypeError, "encoding must be a string");
- return NULL;
-}
-
-static PyObject *
-scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- /* Initialize Scanner object */
- PyObject *ctx;
- static char *kwlist[] = {"context", NULL};
- PyScannerObject *s;
- PyObject *encoding;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:make_scanner", kwlist, &ctx))
- return NULL;
-
- s = (PyScannerObject *)type->tp_alloc(type, 0);
- if (s == NULL)
- return NULL;
-
- if (s->memo == NULL) {
- s->memo = PyDict_New();
- if (s->memo == NULL)
- goto bail;
- }
-
- encoding = PyObject_GetAttrString(ctx, "encoding");
- if (encoding == NULL)
- goto bail;
- s->encoding = JSON_ParseEncoding(encoding);
- Py_XDECREF(encoding);
- if (s->encoding == NULL)
- goto bail;
-
- /* All of these will fail "gracefully" so we don't need to verify them */
- s->strict_bool = PyObject_GetAttrString(ctx, "strict");
- if (s->strict_bool == NULL)
- goto bail;
- s->strict = PyObject_IsTrue(s->strict_bool);
- if (s->strict < 0)
- goto bail;
- s->object_hook = PyObject_GetAttrString(ctx, "object_hook");
- if (s->object_hook == NULL)
- goto bail;
- s->pairs_hook = PyObject_GetAttrString(ctx, "object_pairs_hook");
- if (s->pairs_hook == NULL)
- goto bail;
- s->parse_float = PyObject_GetAttrString(ctx, "parse_float");
- if (s->parse_float == NULL)
- goto bail;
- s->parse_int = PyObject_GetAttrString(ctx, "parse_int");
- if (s->parse_int == NULL)
- goto bail;
- s->parse_constant = PyObject_GetAttrString(ctx, "parse_constant");
- if (s->parse_constant == NULL)
- goto bail;
-
- return (PyObject *)s;
-
-bail:
- Py_DECREF(s);
- return NULL;
-}
-
-PyDoc_STRVAR(scanner_doc, "JSON scanner object");
-
-static
-PyTypeObject PyScannerType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "simplejson._speedups.Scanner", /* tp_name */
- sizeof(PyScannerObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- scanner_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- scanner_call, /* tp_call */
- 0, /* tp_str */
- 0,/* PyObject_GenericGetAttr, */ /* tp_getattro */
- 0,/* PyObject_GenericSetAttr, */ /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
- scanner_doc, /* tp_doc */
- scanner_traverse, /* tp_traverse */
- scanner_clear, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- 0, /* tp_methods */
- scanner_members, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0,/* PyType_GenericAlloc, */ /* tp_alloc */
- scanner_new, /* tp_new */
- 0,/* PyObject_GC_Del, */ /* tp_free */
-};
-
-static PyObject *
-encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- static char *kwlist[] = {
- "markers",
- "default",
- "encoder",
- "indent",
- "key_separator",
- "item_separator",
- "sort_keys",
- "skipkeys",
- "allow_nan",
- "key_memo",
- "use_decimal",
- "namedtuple_as_object",
- "tuple_as_array",
- "int_as_string_bitcount",
- "item_sort_key",
- "encoding",
- "for_json",
- "ignore_nan",
- "Decimal",
- "iterable_as_array",
- NULL};
-
- PyEncoderObject *s;
- PyObject *markers, *defaultfn, *encoder, *indent, *key_separator;
- PyObject *item_separator, *sort_keys, *skipkeys, *allow_nan, *key_memo;
- PyObject *use_decimal, *namedtuple_as_object, *tuple_as_array, *iterable_as_array;
- PyObject *int_as_string_bitcount, *item_sort_key, *encoding, *for_json;
- PyObject *ignore_nan, *Decimal;
- int is_true;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOOOOOOOOOOOOOOOOO:make_encoder", kwlist,
- &markers, &defaultfn, &encoder, &indent, &key_separator, &item_separator,
- &sort_keys, &skipkeys, &allow_nan, &key_memo, &use_decimal,
- &namedtuple_as_object, &tuple_as_array,
- &int_as_string_bitcount, &item_sort_key, &encoding, &for_json,
- &ignore_nan, &Decimal, &iterable_as_array))
- return NULL;
-
- s = (PyEncoderObject *)type->tp_alloc(type, 0);
- if (s == NULL)
- return NULL;
-
- Py_INCREF(markers);
- s->markers = markers;
- Py_INCREF(defaultfn);
- s->defaultfn = defaultfn;
- Py_INCREF(encoder);
- s->encoder = encoder;
-#if PY_MAJOR_VERSION >= 3
- if (encoding == Py_None) {
- s->encoding = NULL;
- }
- else
-#endif /* PY_MAJOR_VERSION >= 3 */
- {
- s->encoding = JSON_ParseEncoding(encoding);
- if (s->encoding == NULL)
- goto bail;
- }
- Py_INCREF(indent);
- s->indent = indent;
- Py_INCREF(key_separator);
- s->key_separator = key_separator;
- Py_INCREF(item_separator);
- s->item_separator = item_separator;
- Py_INCREF(skipkeys);
- s->skipkeys_bool = skipkeys;
- s->skipkeys = PyObject_IsTrue(skipkeys);
- if (s->skipkeys < 0)
- goto bail;
- Py_INCREF(key_memo);
- s->key_memo = key_memo;
- s->fast_encode = (PyCFunction_Check(s->encoder) && PyCFunction_GetFunction(s->encoder) == (PyCFunction)py_encode_basestring_ascii);
- is_true = PyObject_IsTrue(ignore_nan);
- if (is_true < 0)
- goto bail;
- s->allow_or_ignore_nan = is_true ? JSON_IGNORE_NAN : 0;
- is_true = PyObject_IsTrue(allow_nan);
- if (is_true < 0)
- goto bail;
- s->allow_or_ignore_nan |= is_true ? JSON_ALLOW_NAN : 0;
- s->use_decimal = PyObject_IsTrue(use_decimal);
- if (s->use_decimal < 0)
- goto bail;
- s->namedtuple_as_object = PyObject_IsTrue(namedtuple_as_object);
- if (s->namedtuple_as_object < 0)
- goto bail;
- s->tuple_as_array = PyObject_IsTrue(tuple_as_array);
- if (s->tuple_as_array < 0)
- goto bail;
- s->iterable_as_array = PyObject_IsTrue(iterable_as_array);
- if (s->iterable_as_array < 0)
- goto bail;
- if (PyInt_Check(int_as_string_bitcount) || PyLong_Check(int_as_string_bitcount)) {
- static const unsigned long long_long_bitsize = SIZEOF_LONG_LONG * 8;
- long int_as_string_bitcount_val = PyLong_AsLong(int_as_string_bitcount);
- if (int_as_string_bitcount_val > 0 && int_as_string_bitcount_val < (long)long_long_bitsize) {
- s->max_long_size = PyLong_FromUnsignedLongLong(1ULL << (int)int_as_string_bitcount_val);
- s->min_long_size = PyLong_FromLongLong(-1LL << (int)int_as_string_bitcount_val);
- if (s->min_long_size == NULL || s->max_long_size == NULL) {
- goto bail;
- }
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "int_as_string_bitcount (%ld) must be greater than 0 and less than the number of bits of a `long long` type (%lu bits)",
- int_as_string_bitcount_val, long_long_bitsize);
- goto bail;
- }
- }
- else if (int_as_string_bitcount == Py_None) {
- Py_INCREF(Py_None);
- s->max_long_size = Py_None;
- Py_INCREF(Py_None);
- s->min_long_size = Py_None;
- }
- else {
- PyErr_SetString(PyExc_TypeError, "int_as_string_bitcount must be None or an integer");
- goto bail;
- }
- if (item_sort_key != Py_None) {
- if (!PyCallable_Check(item_sort_key)) {
- PyErr_SetString(PyExc_TypeError, "item_sort_key must be None or callable");
- goto bail;
- }
- }
- else {
- is_true = PyObject_IsTrue(sort_keys);
- if (is_true < 0)
- goto bail;
- if (is_true) {
- static PyObject *itemgetter0 = NULL;
- if (!itemgetter0) {
- PyObject *operator = PyImport_ImportModule("operator");
- if (!operator)
- goto bail;
- itemgetter0 = PyObject_CallMethod(operator, "itemgetter", "i", 0);
- Py_DECREF(operator);
- }
- item_sort_key = itemgetter0;
- if (!item_sort_key)
- goto bail;
- }
- }
- if (item_sort_key == Py_None) {
- Py_INCREF(Py_None);
- s->item_sort_kw = Py_None;
- }
- else {
- s->item_sort_kw = PyDict_New();
- if (s->item_sort_kw == NULL)
- goto bail;
- if (PyDict_SetItemString(s->item_sort_kw, "key", item_sort_key))
- goto bail;
- }
- Py_INCREF(sort_keys);
- s->sort_keys = sort_keys;
- Py_INCREF(item_sort_key);
- s->item_sort_key = item_sort_key;
- Py_INCREF(Decimal);
- s->Decimal = Decimal;
- s->for_json = PyObject_IsTrue(for_json);
- if (s->for_json < 0)
- goto bail;
-
- return (PyObject *)s;
-
-bail:
- Py_DECREF(s);
- return NULL;
-}
-
-static PyObject *
-encoder_call(PyObject *self, PyObject *args, PyObject *kwds)
-{
- /* Python callable interface to encode_listencode_obj */
- static char *kwlist[] = {"obj", "_current_indent_level", NULL};
- PyObject *obj;
- Py_ssize_t indent_level;
- PyEncoderObject *s;
- JSON_Accu rval;
- assert(PyEncoder_Check(self));
- s = (PyEncoderObject *)self;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&:_iterencode", kwlist,
- &obj, _convertPyInt_AsSsize_t, &indent_level))
- return NULL;
- if (JSON_Accu_Init(&rval))
- return NULL;
- if (encoder_listencode_obj(s, &rval, obj, indent_level)) {
- JSON_Accu_Destroy(&rval);
- return NULL;
- }
- return JSON_Accu_FinishAsList(&rval);
-}
-
-static PyObject *
-_encoded_const(PyObject *obj)
-{
- /* Return the JSON string representation of None, True, False */
- if (obj == Py_None) {
- static PyObject *s_null = NULL;
- if (s_null == NULL) {
- s_null = JSON_InternFromString("null");
- }
- Py_INCREF(s_null);
- return s_null;
- }
- else if (obj == Py_True) {
- static PyObject *s_true = NULL;
- if (s_true == NULL) {
- s_true = JSON_InternFromString("true");
- }
- Py_INCREF(s_true);
- return s_true;
- }
- else if (obj == Py_False) {
- static PyObject *s_false = NULL;
- if (s_false == NULL) {
- s_false = JSON_InternFromString("false");
- }
- Py_INCREF(s_false);
- return s_false;
- }
- else {
- PyErr_SetString(PyExc_ValueError, "not a const");
- return NULL;
- }
-}
-
-static PyObject *
-encoder_encode_float(PyEncoderObject *s, PyObject *obj)
-{
- /* Return the JSON representation of a PyFloat */
- double i = PyFloat_AS_DOUBLE(obj);
- if (!Py_IS_FINITE(i)) {
- if (!s->allow_or_ignore_nan) {
- PyErr_SetString(PyExc_ValueError, "Out of range float values are not JSON compliant");
- return NULL;
- }
- if (s->allow_or_ignore_nan & JSON_IGNORE_NAN) {
- return _encoded_const(Py_None);
- }
- /* JSON_ALLOW_NAN is set */
- else if (i > 0) {
- Py_INCREF(JSON_Infinity);
- return JSON_Infinity;
- }
- else if (i < 0) {
- Py_INCREF(JSON_NegInfinity);
- return JSON_NegInfinity;
- }
- else {
- Py_INCREF(JSON_NaN);
- return JSON_NaN;
- }
- }
- /* Use a better float format here? */
- if (PyFloat_CheckExact(obj)) {
- return PyObject_Repr(obj);
- }
- else {
- /* See #118, do not trust custom str/repr */
- PyObject *res;
- PyObject *tmp = PyObject_CallOneArg((PyObject *)&PyFloat_Type, obj);
- if (tmp == NULL) {
- return NULL;
- }
- res = PyObject_Repr(tmp);
- Py_DECREF(tmp);
- return res;
- }
-}
-
-static PyObject *
-encoder_encode_string(PyEncoderObject *s, PyObject *obj)
-{
- /* Return the JSON representation of a string */
- PyObject *encoded;
-
- if (s->fast_encode) {
- return py_encode_basestring_ascii(NULL, obj);
- }
- encoded = PyObject_CallOneArg(s->encoder, obj);
- if (encoded != NULL &&
-#if PY_MAJOR_VERSION < 3
- !PyString_Check(encoded) &&
-#endif /* PY_MAJOR_VERSION < 3 */
- !PyUnicode_Check(encoded))
- {
- PyErr_Format(PyExc_TypeError,
- "encoder() must return a string, not %.80s",
- Py_TYPE(encoded)->tp_name);
- Py_DECREF(encoded);
- return NULL;
- }
- return encoded;
-}
-
-static int
-_steal_accumulate(JSON_Accu *accu, PyObject *stolen)
-{
- /* Append stolen and then decrement its reference count */
- int rval = JSON_Accu_Accumulate(accu, stolen);
- Py_DECREF(stolen);
- return rval;
-}
-
-static int
-encoder_listencode_obj(PyEncoderObject *s, JSON_Accu *rval, PyObject *obj, Py_ssize_t indent_level)
-{
- /* Encode Python object obj to a JSON term, rval is a PyList */
- int rv = -1;
- do {
- PyObject *newobj;
- if (obj == Py_None || obj == Py_True || obj == Py_False) {
- PyObject *cstr = _encoded_const(obj);
- if (cstr != NULL)
- rv = _steal_accumulate(rval, cstr);
- }
- else if ((PyBytes_Check(obj) && s->encoding != NULL) ||
- PyUnicode_Check(obj))
- {
- PyObject *encoded = encoder_encode_string(s, obj);
- if (encoded != NULL)
- rv = _steal_accumulate(rval, encoded);
- }
- else if (PyInt_Check(obj) || PyLong_Check(obj)) {
- PyObject *encoded;
- if (PyInt_CheckExact(obj) || PyLong_CheckExact(obj)) {
- encoded = PyObject_Str(obj);
- }
- else {
- /* See #118, do not trust custom str/repr */
- PyObject *tmp = PyObject_CallOneArg((PyObject *)&PyLong_Type, obj);
- if (tmp == NULL) {
- encoded = NULL;
- }
- else {
- encoded = PyObject_Str(tmp);
- Py_DECREF(tmp);
- }
- }
- if (encoded != NULL) {
- encoded = maybe_quote_bigint(s, encoded, obj);
- if (encoded == NULL)
- break;
- rv = _steal_accumulate(rval, encoded);
- }
- }
- else if (PyFloat_Check(obj)) {
- PyObject *encoded = encoder_encode_float(s, obj);
- if (encoded != NULL)
- rv = _steal_accumulate(rval, encoded);
- }
- else if (s->for_json && _call_json_method(obj, FOR_JSON_METHOD_NAME, &newobj)) {
- if (newobj == NULL) {
- return -1;
- }
- if (Py_EnterRecursiveCall(" while encoding a JSON object")) {
- Py_DECREF(newobj);
- return rv;
- }
- rv = encoder_listencode_obj(s, rval, newobj, indent_level);
- Py_DECREF(newobj);
- Py_LeaveRecursiveCall();
- }
- else if (s->namedtuple_as_object && _call_json_method(obj, ASDICT_METHOD_NAME, &newobj)) {
- if (newobj == NULL) {
- return -1;
- }
- if (Py_EnterRecursiveCall(" while encoding a JSON object")) {
- Py_DECREF(newobj);
- return rv;
- }
- if (PyDict_Check(newobj)) {
- rv = encoder_listencode_dict(s, rval, newobj, indent_level);
- } else {
- PyErr_Format(
- PyExc_TypeError,
- "_asdict() must return a dict, not %.80s",
- Py_TYPE(newobj)->tp_name
- );
- rv = -1;
- }
- Py_DECREF(newobj);
- Py_LeaveRecursiveCall();
- }
- else if (PyList_Check(obj) || (s->tuple_as_array && PyTuple_Check(obj))) {
- if (Py_EnterRecursiveCall(" while encoding a JSON object"))
- return rv;
- rv = encoder_listencode_list(s, rval, obj, indent_level);
- Py_LeaveRecursiveCall();
- }
- else if (PyDict_Check(obj)) {
- if (Py_EnterRecursiveCall(" while encoding a JSON object"))
- return rv;
- rv = encoder_listencode_dict(s, rval, obj, indent_level);
- Py_LeaveRecursiveCall();
- }
- else if (s->use_decimal && PyObject_TypeCheck(obj, (PyTypeObject *)s->Decimal)) {
- PyObject *encoded = PyObject_Str(obj);
- if (encoded != NULL)
- rv = _steal_accumulate(rval, encoded);
- }
- else if (is_raw_json(obj))
- {
- PyObject *encoded = PyObject_GetAttrString(obj, "encoded_json");
- if (encoded != NULL)
- rv = _steal_accumulate(rval, encoded);
- }
- else {
- PyObject *ident = NULL;
- PyObject *newobj;
- if (s->iterable_as_array) {
- newobj = PyObject_GetIter(obj);
- if (newobj == NULL)
- PyErr_Clear();
- else {
- rv = encoder_listencode_list(s, rval, newobj, indent_level);
- Py_DECREF(newobj);
- break;
- }
- }
- if (s->markers != Py_None) {
- int has_key;
- ident = PyLong_FromVoidPtr(obj);
- if (ident == NULL)
- break;
- has_key = PyDict_Contains(s->markers, ident);
- if (has_key) {
- if (has_key != -1)
- PyErr_SetString(PyExc_ValueError, "Circular reference detected");
- Py_DECREF(ident);
- break;
- }
- if (PyDict_SetItem(s->markers, ident, obj)) {
- Py_DECREF(ident);
- break;
- }
- }
- if (Py_EnterRecursiveCall(" while encoding a JSON object"))
- return rv;
- newobj = PyObject_CallOneArg(s->defaultfn, obj);
- if (newobj == NULL) {
- Py_XDECREF(ident);
- Py_LeaveRecursiveCall();
- break;
- }
- rv = encoder_listencode_obj(s, rval, newobj, indent_level);
- Py_LeaveRecursiveCall();
- Py_DECREF(newobj);
- if (rv) {
- Py_XDECREF(ident);
- rv = -1;
- }
- else if (ident != NULL) {
- if (PyDict_DelItem(s->markers, ident)) {
- Py_XDECREF(ident);
- rv = -1;
- }
- Py_XDECREF(ident);
- }
- }
- } while (0);
- return rv;
-}
-
-static int
-encoder_listencode_dict(PyEncoderObject *s, JSON_Accu *rval, PyObject *dct, Py_ssize_t indent_level)
-{
- /* Encode Python dict dct a JSON term */
- static PyObject *open_dict = NULL;
- static PyObject *close_dict = NULL;
- static PyObject *empty_dict = NULL;
- PyObject *kstr = NULL;
- PyObject *ident = NULL;
- PyObject *iter = NULL;
- PyObject *item = NULL;
- PyObject *items = NULL;
- PyObject *encoded = NULL;
- Py_ssize_t idx;
-
- if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) {
- open_dict = JSON_InternFromString("{");
- close_dict = JSON_InternFromString("}");
- empty_dict = JSON_InternFromString("{}");
- if (open_dict == NULL || close_dict == NULL || empty_dict == NULL)
- return -1;
- }
- if (PyDict_Size(dct) == 0)
- return JSON_Accu_Accumulate(rval, empty_dict);
-
- if (s->markers != Py_None) {
- int has_key;
- ident = PyLong_FromVoidPtr(dct);
- if (ident == NULL)
- goto bail;
- has_key = PyDict_Contains(s->markers, ident);
- if (has_key) {
- if (has_key != -1)
- PyErr_SetString(PyExc_ValueError, "Circular reference detected");
- goto bail;
- }
- if (PyDict_SetItem(s->markers, ident, dct)) {
- goto bail;
- }
- }
-
- if (JSON_Accu_Accumulate(rval, open_dict))
- goto bail;
-
- if (s->indent != Py_None) {
- /* TODO: DOES NOT RUN */
- indent_level += 1;
- /*
- newline_indent = '\n' + (_indent * _current_indent_level)
- separator = _item_separator + newline_indent
- buf += newline_indent
- */
- }
-
- iter = encoder_dict_iteritems(s, dct);
- if (iter == NULL)
- goto bail;
-
- idx = 0;
- while ((item = PyIter_Next(iter))) {
- PyObject *encoded, *key, *value;
- if (!PyTuple_Check(item) || Py_SIZE(item) != 2) {
- PyErr_SetString(PyExc_ValueError, "items must return 2-tuples");
- goto bail;
- }
- key = PyTuple_GET_ITEM(item, 0);
- if (key == NULL)
- goto bail;
- value = PyTuple_GET_ITEM(item, 1);
- if (value == NULL)
- goto bail;
-
- encoded = PyDict_GetItem(s->key_memo, key);
- if (encoded != NULL) {
- Py_INCREF(encoded);
- } else {
- kstr = encoder_stringify_key(s, key);
- if (kstr == NULL)
- goto bail;
- else if (kstr == Py_None) {
- /* skipkeys */
- Py_DECREF(item);
- Py_DECREF(kstr);
- continue;
- }
- }
- if (idx) {
- if (JSON_Accu_Accumulate(rval, s->item_separator))
- goto bail;
- }
- if (encoded == NULL) {
- encoded = encoder_encode_string(s, kstr);
- Py_CLEAR(kstr);
- if (encoded == NULL)
- goto bail;
- if (PyDict_SetItem(s->key_memo, key, encoded))
- goto bail;
- }
- if (JSON_Accu_Accumulate(rval, encoded)) {
- goto bail;
- }
- Py_CLEAR(encoded);
- if (JSON_Accu_Accumulate(rval, s->key_separator))
- goto bail;
- if (encoder_listencode_obj(s, rval, value, indent_level))
- goto bail;
- Py_CLEAR(item);
- idx += 1;
- }
- Py_CLEAR(iter);
- if (PyErr_Occurred())
- goto bail;
- if (ident != NULL) {
- if (PyDict_DelItem(s->markers, ident))
- goto bail;
- Py_CLEAR(ident);
- }
- if (s->indent != Py_None) {
- /* TODO: DOES NOT RUN */
- indent_level -= 1;
- /*
- yield '\n' + (_indent * _current_indent_level)
- */
- }
- if (JSON_Accu_Accumulate(rval, close_dict))
- goto bail;
- return 0;
-
-bail:
- Py_XDECREF(encoded);
- Py_XDECREF(items);
- Py_XDECREF(item);
- Py_XDECREF(iter);
- Py_XDECREF(kstr);
- Py_XDECREF(ident);
- return -1;
-}
-
-
-static int
-encoder_listencode_list(PyEncoderObject *s, JSON_Accu *rval, PyObject *seq, Py_ssize_t indent_level)
-{
- /* Encode Python list seq to a JSON term */
- static PyObject *open_array = NULL;
- static PyObject *close_array = NULL;
- static PyObject *empty_array = NULL;
- PyObject *ident = NULL;
- PyObject *iter = NULL;
- PyObject *obj = NULL;
- int is_true;
- int i = 0;
-
- if (open_array == NULL || close_array == NULL || empty_array == NULL) {
- open_array = JSON_InternFromString("[");
- close_array = JSON_InternFromString("]");
- empty_array = JSON_InternFromString("[]");
- if (open_array == NULL || close_array == NULL || empty_array == NULL)
- return -1;
- }
- ident = NULL;
- is_true = PyObject_IsTrue(seq);
- if (is_true == -1)
- return -1;
- else if (is_true == 0)
- return JSON_Accu_Accumulate(rval, empty_array);
-
- if (s->markers != Py_None) {
- int has_key;
- ident = PyLong_FromVoidPtr(seq);
- if (ident == NULL)
- goto bail;
- has_key = PyDict_Contains(s->markers, ident);
- if (has_key) {
- if (has_key != -1)
- PyErr_SetString(PyExc_ValueError, "Circular reference detected");
- goto bail;
- }
- if (PyDict_SetItem(s->markers, ident, seq)) {
- goto bail;
- }
- }
-
- iter = PyObject_GetIter(seq);
- if (iter == NULL)
- goto bail;
-
- if (JSON_Accu_Accumulate(rval, open_array))
- goto bail;
- if (s->indent != Py_None) {
- /* TODO: DOES NOT RUN */
- indent_level += 1;
- /*
- newline_indent = '\n' + (_indent * _current_indent_level)
- separator = _item_separator + newline_indent
- buf += newline_indent
- */
- }
- while ((obj = PyIter_Next(iter))) {
- if (i) {
- if (JSON_Accu_Accumulate(rval, s->item_separator))
- goto bail;
- }
- if (encoder_listencode_obj(s, rval, obj, indent_level))
- goto bail;
- i++;
- Py_CLEAR(obj);
- }
- Py_CLEAR(iter);
- if (PyErr_Occurred())
- goto bail;
- if (ident != NULL) {
- if (PyDict_DelItem(s->markers, ident))
- goto bail;
- Py_CLEAR(ident);
- }
- if (s->indent != Py_None) {
- /* TODO: DOES NOT RUN */
- indent_level -= 1;
- /*
- yield '\n' + (_indent * _current_indent_level)
- */
- }
- if (JSON_Accu_Accumulate(rval, close_array))
- goto bail;
- return 0;
-
-bail:
- Py_XDECREF(obj);
- Py_XDECREF(iter);
- Py_XDECREF(ident);
- return -1;
-}
-
-static void
-encoder_dealloc(PyObject *self)
-{
- /* bpo-31095: UnTrack is needed before calling any callbacks */
- PyObject_GC_UnTrack(self);
- encoder_clear(self);
- Py_TYPE(self)->tp_free(self);
-}
-
-static int
-encoder_traverse(PyObject *self, visitproc visit, void *arg)
-{
- PyEncoderObject *s;
- assert(PyEncoder_Check(self));
- s = (PyEncoderObject *)self;
- Py_VISIT(s->markers);
- Py_VISIT(s->defaultfn);
- Py_VISIT(s->encoder);
- Py_VISIT(s->encoding);
- Py_VISIT(s->indent);
- Py_VISIT(s->key_separator);
- Py_VISIT(s->item_separator);
- Py_VISIT(s->key_memo);
- Py_VISIT(s->sort_keys);
- Py_VISIT(s->item_sort_kw);
- Py_VISIT(s->item_sort_key);
- Py_VISIT(s->max_long_size);
- Py_VISIT(s->min_long_size);
- Py_VISIT(s->Decimal);
- return 0;
-}
-
-static int
-encoder_clear(PyObject *self)
-{
- /* Deallocate Encoder */
- PyEncoderObject *s;
- assert(PyEncoder_Check(self));
- s = (PyEncoderObject *)self;
- Py_CLEAR(s->markers);
- Py_CLEAR(s->defaultfn);
- Py_CLEAR(s->encoder);
- Py_CLEAR(s->encoding);
- Py_CLEAR(s->indent);
- Py_CLEAR(s->key_separator);
- Py_CLEAR(s->item_separator);
- Py_CLEAR(s->key_memo);
- Py_CLEAR(s->skipkeys_bool);
- Py_CLEAR(s->sort_keys);
- Py_CLEAR(s->item_sort_kw);
- Py_CLEAR(s->item_sort_key);
- Py_CLEAR(s->max_long_size);
- Py_CLEAR(s->min_long_size);
- Py_CLEAR(s->Decimal);
- return 0;
-}
-
-PyDoc_STRVAR(encoder_doc, "_iterencode(obj, _current_indent_level) -> iterable");
-
-static
-PyTypeObject PyEncoderType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "simplejson._speedups.Encoder", /* tp_name */
- sizeof(PyEncoderObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- encoder_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- encoder_call, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
- encoder_doc, /* tp_doc */
- encoder_traverse, /* tp_traverse */
- encoder_clear, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- 0, /* tp_methods */
- encoder_members, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- encoder_new, /* tp_new */
- 0, /* tp_free */
-};
-
-static PyMethodDef speedups_methods[] = {
- {"encode_basestring_ascii",
- (PyCFunction)py_encode_basestring_ascii,
- METH_O,
- pydoc_encode_basestring_ascii},
- {"scanstring",
- (PyCFunction)py_scanstring,
- METH_VARARGS,
- pydoc_scanstring},
- {NULL, NULL, 0, NULL}
-};
-
-PyDoc_STRVAR(module_doc,
-"simplejson speedups\n");
-
-#if PY_MAJOR_VERSION >= 3
-static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "_speedups", /* m_name */
- module_doc, /* m_doc */
- -1, /* m_size */
- speedups_methods, /* m_methods */
- NULL, /* m_reload */
- NULL, /* m_traverse */
- NULL, /* m_clear*/
- NULL, /* m_free */
-};
-#endif
-
-PyObject *
-import_dependency(char *module_name, char *attr_name)
-{
- PyObject *rval;
- PyObject *module = PyImport_ImportModule(module_name);
- if (module == NULL)
- return NULL;
- rval = PyObject_GetAttrString(module, attr_name);
- Py_DECREF(module);
- return rval;
-}
-
-static int
-init_constants(void)
-{
- JSON_NaN = JSON_InternFromString("NaN");
- if (JSON_NaN == NULL)
- return 0;
- JSON_Infinity = JSON_InternFromString("Infinity");
- if (JSON_Infinity == NULL)
- return 0;
- JSON_NegInfinity = JSON_InternFromString("-Infinity");
- if (JSON_NegInfinity == NULL)
- return 0;
-#if PY_MAJOR_VERSION >= 3
- JSON_EmptyUnicode = PyUnicode_New(0, 127);
-#else /* PY_MAJOR_VERSION >= 3 */
- JSON_EmptyStr = PyString_FromString("");
- if (JSON_EmptyStr == NULL)
- return 0;
- JSON_EmptyUnicode = PyUnicode_FromUnicode(NULL, 0);
-#endif /* PY_MAJOR_VERSION >= 3 */
- if (JSON_EmptyUnicode == NULL)
- return 0;
-
- return 1;
-}
-
-static PyObject *
-moduleinit(void)
-{
- PyObject *m;
- if (PyType_Ready(&PyScannerType) < 0)
- return NULL;
- if (PyType_Ready(&PyEncoderType) < 0)
- return NULL;
- if (!init_constants())
- return NULL;
-
-#if PY_MAJOR_VERSION >= 3
- m = PyModule_Create(&moduledef);
-#else
- m = Py_InitModule3("_speedups", speedups_methods, module_doc);
-#endif
- Py_INCREF((PyObject*)&PyScannerType);
- PyModule_AddObject(m, "make_scanner", (PyObject*)&PyScannerType);
- Py_INCREF((PyObject*)&PyEncoderType);
- PyModule_AddObject(m, "make_encoder", (PyObject*)&PyEncoderType);
- RawJSONType = import_dependency("simplejson.raw_json", "RawJSON");
- if (RawJSONType == NULL)
- return NULL;
- JSONDecodeError = import_dependency("simplejson.errors", "JSONDecodeError");
- if (JSONDecodeError == NULL)
- return NULL;
- return m;
-}
-
-#if PY_MAJOR_VERSION >= 3
-PyMODINIT_FUNC
-PyInit__speedups(void)
-{
- return moduleinit();
-}
-#else
-void
-init_speedups(void)
-{
- moduleinit();
-}
-#endif
diff --git a/contrib/python/simplejson/simplejson/compat.py b/contrib/python/simplejson/simplejson/compat.py
deleted file mode 100644
index 5fc1412844..0000000000
--- a/contrib/python/simplejson/simplejson/compat.py
+++ /dev/null
@@ -1,34 +0,0 @@
-"""Python 3 compatibility shims
-"""
-import sys
-if sys.version_info[0] < 3:
- PY3 = False
- def b(s):
- return s
- try:
- from cStringIO import StringIO
- except ImportError:
- from StringIO import StringIO
- BytesIO = StringIO
- text_type = unicode
- binary_type = str
- string_types = (basestring,)
- integer_types = (int, long)
- unichr = unichr
- reload_module = reload
-else:
- PY3 = True
- if sys.version_info[:2] >= (3, 4):
- from importlib import reload as reload_module
- else:
- from imp import reload as reload_module
- def b(s):
- return bytes(s, 'latin1')
- from io import StringIO, BytesIO
- text_type = str
- binary_type = bytes
- string_types = (str,)
- integer_types = (int,)
- unichr = chr
-
-long_type = integer_types[-1]
diff --git a/contrib/python/simplejson/simplejson/decoder.py b/contrib/python/simplejson/simplejson/decoder.py
deleted file mode 100644
index 1a8f772f13..0000000000
--- a/contrib/python/simplejson/simplejson/decoder.py
+++ /dev/null
@@ -1,402 +0,0 @@
-"""Implementation of JSONDecoder
-"""
-from __future__ import absolute_import
-import re
-import sys
-import struct
-from .compat import PY3, unichr
-from .scanner import make_scanner, JSONDecodeError
-
-def _import_c_scanstring():
- try:
- from ._speedups import scanstring
- return scanstring
- except ImportError:
- return None
-c_scanstring = _import_c_scanstring()
-
-# NOTE (3.1.0): JSONDecodeError may still be imported from this module for
-# compatibility, but it was never in the __all__
-__all__ = ['JSONDecoder']
-
-FLAGS = re.VERBOSE | re.MULTILINE | re.DOTALL
-
-def _floatconstants():
- if sys.version_info < (2, 6):
- _BYTES = '7FF80000000000007FF0000000000000'.decode('hex')
- nan, inf = struct.unpack('>dd', _BYTES)
- else:
- nan = float('nan')
- inf = float('inf')
- return nan, inf, -inf
-
-NaN, PosInf, NegInf = _floatconstants()
-
-_CONSTANTS = {
- '-Infinity': NegInf,
- 'Infinity': PosInf,
- 'NaN': NaN,
-}
-
-STRINGCHUNK = re.compile(r'(.*?)(["\\\x00-\x1f])', FLAGS)
-BACKSLASH = {
- '"': u'"', '\\': u'\\', '/': u'/',
- 'b': u'\b', 'f': u'\f', 'n': u'\n', 'r': u'\r', 't': u'\t',
-}
-
-DEFAULT_ENCODING = "utf-8"
-
-def py_scanstring(s, end, encoding=None, strict=True,
- _b=BACKSLASH, _m=STRINGCHUNK.match, _join=u''.join,
- _PY3=PY3, _maxunicode=sys.maxunicode):
- """Scan the string s for a JSON string. End is the index of the
- character in s after the quote that started the JSON string.
- Unescapes all valid JSON string escape sequences and raises ValueError
- on attempt to decode an invalid string. If strict is False then literal
- control characters are allowed in the string.
-
- Returns a tuple of the decoded string and the index of the character in s
- after the end quote."""
- if encoding is None:
- encoding = DEFAULT_ENCODING
- chunks = []
- _append = chunks.append
- begin = end - 1
- while 1:
- chunk = _m(s, end)
- if chunk is None:
- raise JSONDecodeError(
- "Unterminated string starting at", s, begin)
- end = chunk.end()
- content, terminator = chunk.groups()
- # Content is contains zero or more unescaped string characters
- if content:
- if not _PY3 and not isinstance(content, unicode):
- content = unicode(content, encoding)
- _append(content)
- # Terminator is the end of string, a literal control character,
- # or a backslash denoting that an escape sequence follows
- if terminator == '"':
- break
- elif terminator != '\\':
- if strict:
- msg = "Invalid control character %r at"
- raise JSONDecodeError(msg, s, end)
- else:
- _append(terminator)
- continue
- try:
- esc = s[end]
- except IndexError:
- raise JSONDecodeError(
- "Unterminated string starting at", s, begin)
- # If not a unicode escape sequence, must be in the lookup table
- if esc != 'u':
- try:
- char = _b[esc]
- except KeyError:
- msg = "Invalid \\X escape sequence %r"
- raise JSONDecodeError(msg, s, end)
- end += 1
- else:
- # Unicode escape sequence
- msg = "Invalid \\uXXXX escape sequence"
- esc = s[end + 1:end + 5]
- escX = esc[1:2]
- if len(esc) != 4 or escX == 'x' or escX == 'X':
- raise JSONDecodeError(msg, s, end - 1)
- try:
- uni = int(esc, 16)
- except ValueError:
- raise JSONDecodeError(msg, s, end - 1)
- if uni < 0 or uni > _maxunicode:
- raise JSONDecodeError(msg, s, end - 1)
- end += 5
- # Check for surrogate pair on UCS-4 systems
- # Note that this will join high/low surrogate pairs
- # but will also pass unpaired surrogates through
- if (_maxunicode > 65535 and
- uni & 0xfc00 == 0xd800 and
- s[end:end + 2] == '\\u'):
- esc2 = s[end + 2:end + 6]
- escX = esc2[1:2]
- if len(esc2) == 4 and not (escX == 'x' or escX == 'X'):
- try:
- uni2 = int(esc2, 16)
- except ValueError:
- raise JSONDecodeError(msg, s, end)
- if uni2 & 0xfc00 == 0xdc00:
- uni = 0x10000 + (((uni - 0xd800) << 10) |
- (uni2 - 0xdc00))
- end += 6
- char = unichr(uni)
- # Append the unescaped character
- _append(char)
- return _join(chunks), end
-
-
-# Use speedup if available
-scanstring = c_scanstring or py_scanstring
-
-WHITESPACE = re.compile(r'[ \t\n\r]*', FLAGS)
-WHITESPACE_STR = ' \t\n\r'
-
-def JSONObject(state, encoding, strict, scan_once, object_hook,
- object_pairs_hook, memo=None,
- _w=WHITESPACE.match, _ws=WHITESPACE_STR):
- (s, end) = state
- # Backwards compatibility
- if memo is None:
- memo = {}
- memo_get = memo.setdefault
- pairs = []
- # Use a slice to prevent IndexError from being raised, the following
- # check will raise a more specific ValueError if the string is empty
- nextchar = s[end:end + 1]
- # Normally we expect nextchar == '"'
- if nextchar != '"':
- if nextchar in _ws:
- end = _w(s, end).end()
- nextchar = s[end:end + 1]
- # Trivial empty object
- if nextchar == '}':
- if object_pairs_hook is not None:
- result = object_pairs_hook(pairs)
- return result, end + 1
- pairs = {}
- if object_hook is not None:
- pairs = object_hook(pairs)
- return pairs, end + 1
- elif nextchar != '"':
- raise JSONDecodeError(
- "Expecting property name enclosed in double quotes",
- s, end)
- end += 1
- while True:
- key, end = scanstring(s, end, encoding, strict)
- key = memo_get(key, key)
-
- # To skip some function call overhead we optimize the fast paths where
- # the JSON key separator is ": " or just ":".
- if s[end:end + 1] != ':':
- end = _w(s, end).end()
- if s[end:end + 1] != ':':
- raise JSONDecodeError("Expecting ':' delimiter", s, end)
-
- end += 1
-
- try:
- if s[end] in _ws:
- end += 1
- if s[end] in _ws:
- end = _w(s, end + 1).end()
- except IndexError:
- pass
-
- value, end = scan_once(s, end)
- pairs.append((key, value))
-
- try:
- nextchar = s[end]
- if nextchar in _ws:
- end = _w(s, end + 1).end()
- nextchar = s[end]
- except IndexError:
- nextchar = ''
- end += 1
-
- if nextchar == '}':
- break
- elif nextchar != ',':
- raise JSONDecodeError("Expecting ',' delimiter or '}'", s, end - 1)
-
- try:
- nextchar = s[end]
- if nextchar in _ws:
- end += 1
- nextchar = s[end]
- if nextchar in _ws:
- end = _w(s, end + 1).end()
- nextchar = s[end]
- except IndexError:
- nextchar = ''
-
- end += 1
- if nextchar != '"':
- raise JSONDecodeError(
- "Expecting property name enclosed in double quotes",
- s, end - 1)
-
- if object_pairs_hook is not None:
- result = object_pairs_hook(pairs)
- return result, end
- pairs = dict(pairs)
- if object_hook is not None:
- pairs = object_hook(pairs)
- return pairs, end
-
-def JSONArray(state, scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR):
- (s, end) = state
- values = []
- nextchar = s[end:end + 1]
- if nextchar in _ws:
- end = _w(s, end + 1).end()
- nextchar = s[end:end + 1]
- # Look-ahead for trivial empty array
- if nextchar == ']':
- return values, end + 1
- elif nextchar == '':
- raise JSONDecodeError("Expecting value or ']'", s, end)
- _append = values.append
- while True:
- value, end = scan_once(s, end)
- _append(value)
- nextchar = s[end:end + 1]
- if nextchar in _ws:
- end = _w(s, end + 1).end()
- nextchar = s[end:end + 1]
- end += 1
- if nextchar == ']':
- break
- elif nextchar != ',':
- raise JSONDecodeError("Expecting ',' delimiter or ']'", s, end - 1)
-
- try:
- if s[end] in _ws:
- end += 1
- if s[end] in _ws:
- end = _w(s, end + 1).end()
- except IndexError:
- pass
-
- return values, end
-
-class JSONDecoder(object):
- """Simple JSON <http://json.org> decoder
-
- Performs the following translations in decoding by default:
-
- +---------------+-------------------+
- | JSON | Python |
- +===============+===================+
- | object | dict |
- +---------------+-------------------+
- | array | list |
- +---------------+-------------------+
- | string | str, unicode |
- +---------------+-------------------+
- | number (int) | int, long |
- +---------------+-------------------+
- | number (real) | float |
- +---------------+-------------------+
- | true | True |
- +---------------+-------------------+
- | false | False |
- +---------------+-------------------+
- | null | None |
- +---------------+-------------------+
-
- It also understands ``NaN``, ``Infinity``, and ``-Infinity`` as
- their corresponding ``float`` values, which is outside the JSON spec.
-
- """
-
- def __init__(self, encoding=None, object_hook=None, parse_float=None,
- parse_int=None, parse_constant=None, strict=True,
- object_pairs_hook=None):
- """
- *encoding* determines the encoding used to interpret any
- :class:`str` objects decoded by this instance (``'utf-8'`` by
- default). It has no effect when decoding :class:`unicode` objects.
-
- Note that currently only encodings that are a superset of ASCII work,
- strings of other encodings should be passed in as :class:`unicode`.
-
- *object_hook*, if specified, will be called with the result of every
- JSON object decoded and its return value will be used in place of the
- given :class:`dict`. This can be used to provide custom
- deserializations (e.g. to support JSON-RPC class hinting).
-
- *object_pairs_hook* is an optional function that will be called with
- the result of any object literal decode with an ordered list of pairs.
- The return value of *object_pairs_hook* will be used instead of the
- :class:`dict`. This feature can be used to implement custom decoders
- that rely on the order that the key and value pairs are decoded (for
- example, :func:`collections.OrderedDict` will remember the order of
- insertion). If *object_hook* is also defined, the *object_pairs_hook*
- takes priority.
-
- *parse_float*, if specified, will be called with the string of every
- JSON float to be decoded. By default, this is equivalent to
- ``float(num_str)``. This can be used to use another datatype or parser
- for JSON floats (e.g. :class:`decimal.Decimal`).
-
- *parse_int*, if specified, will be called with the string of every
- JSON int to be decoded. By default, this is equivalent to
- ``int(num_str)``. This can be used to use another datatype or parser
- for JSON integers (e.g. :class:`float`).
-
- *parse_constant*, if specified, will be called with one of the
- following strings: ``'-Infinity'``, ``'Infinity'``, ``'NaN'``. This
- can be used to raise an exception if invalid JSON numbers are
- encountered.
-
- *strict* controls the parser's behavior when it encounters an
- invalid control character in a string. The default setting of
- ``True`` means that unescaped control characters are parse errors, if
- ``False`` then control characters will be allowed in strings.
-
- """
- if encoding is None:
- encoding = DEFAULT_ENCODING
- self.encoding = encoding
- self.object_hook = object_hook
- self.object_pairs_hook = object_pairs_hook
- self.parse_float = parse_float or float
- self.parse_int = parse_int or int
- self.parse_constant = parse_constant or _CONSTANTS.__getitem__
- self.strict = strict
- self.parse_object = JSONObject
- self.parse_array = JSONArray
- self.parse_string = scanstring
- self.memo = {}
- self.scan_once = make_scanner(self)
-
- def decode(self, s, _w=WHITESPACE.match, _PY3=PY3):
- """Return the Python representation of ``s`` (a ``str`` or ``unicode``
- instance containing a JSON document)
-
- """
- if _PY3 and isinstance(s, bytes):
- s = str(s, self.encoding)
- obj, end = self.raw_decode(s)
- end = _w(s, end).end()
- if end != len(s):
- raise JSONDecodeError("Extra data", s, end, len(s))
- return obj
-
- def raw_decode(self, s, idx=0, _w=WHITESPACE.match, _PY3=PY3):
- """Decode a JSON document from ``s`` (a ``str`` or ``unicode``
- beginning with a JSON document) and return a 2-tuple of the Python
- representation and the index in ``s`` where the document ended.
- Optionally, ``idx`` can be used to specify an offset in ``s`` where
- the JSON document begins.
-
- This can be used to decode a JSON document from a string that may
- have extraneous data at the end.
-
- """
- if idx < 0:
- # Ensure that raw_decode bails on negative indexes, the regex
- # would otherwise mask this behavior. #98
- raise JSONDecodeError('Expecting value', s, idx)
- if _PY3 and not isinstance(s, str):
- raise TypeError("Input string must be text, not bytes")
- # strip UTF-8 bom
- if len(s) > idx:
- ord0 = ord(s[idx])
- if ord0 == 0xfeff:
- idx += 1
- elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
- idx += 3
- return self.scan_once(s, idx=_w(s, idx).end())
diff --git a/contrib/python/simplejson/simplejson/encoder.py b/contrib/python/simplejson/simplejson/encoder.py
deleted file mode 100644
index e93fe43f42..0000000000
--- a/contrib/python/simplejson/simplejson/encoder.py
+++ /dev/null
@@ -1,740 +0,0 @@
-"""Implementation of JSONEncoder
-"""
-from __future__ import absolute_import
-import re
-from operator import itemgetter
-# Do not import Decimal directly to avoid reload issues
-import decimal
-from .compat import unichr, binary_type, text_type, string_types, integer_types, PY3
-def _import_speedups():
- try:
- from . import _speedups
- return _speedups.encode_basestring_ascii, _speedups.make_encoder
- except ImportError:
- return None, None
-c_encode_basestring_ascii, c_make_encoder = _import_speedups()
-
-from .decoder import PosInf
-from .raw_json import RawJSON
-
-ESCAPE = re.compile(r'[\x00-\x1f\\"]')
-ESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])')
-HAS_UTF8 = re.compile(r'[\x80-\xff]')
-ESCAPE_DCT = {
- '\\': '\\\\',
- '"': '\\"',
- '\b': '\\b',
- '\f': '\\f',
- '\n': '\\n',
- '\r': '\\r',
- '\t': '\\t',
-}
-for i in range(0x20):
- #ESCAPE_DCT.setdefault(chr(i), '\\u{0:04x}'.format(i))
- ESCAPE_DCT.setdefault(chr(i), '\\u%04x' % (i,))
-del i
-
-FLOAT_REPR = repr
-
-def encode_basestring(s, _PY3=PY3, _q=u'"'):
- """Return a JSON representation of a Python string
-
- """
- if _PY3:
- if isinstance(s, bytes):
- s = str(s, 'utf-8')
- elif type(s) is not str:
- # convert an str subclass instance to exact str
- # raise a TypeError otherwise
- s = str.__str__(s)
- else:
- if isinstance(s, str) and HAS_UTF8.search(s) is not None:
- s = unicode(s, 'utf-8')
- elif type(s) not in (str, unicode):
- # convert an str subclass instance to exact str
- # convert a unicode subclass instance to exact unicode
- # raise a TypeError otherwise
- if isinstance(s, str):
- s = str.__str__(s)
- else:
- s = unicode.__getnewargs__(s)[0]
- def replace(match):
- return ESCAPE_DCT[match.group(0)]
- return _q + ESCAPE.sub(replace, s) + _q
-
-
-def py_encode_basestring_ascii(s, _PY3=PY3):
- """Return an ASCII-only JSON representation of a Python string
-
- """
- if _PY3:
- if isinstance(s, bytes):
- s = str(s, 'utf-8')
- elif type(s) is not str:
- # convert an str subclass instance to exact str
- # raise a TypeError otherwise
- s = str.__str__(s)
- else:
- if isinstance(s, str) and HAS_UTF8.search(s) is not None:
- s = unicode(s, 'utf-8')
- elif type(s) not in (str, unicode):
- # convert an str subclass instance to exact str
- # convert a unicode subclass instance to exact unicode
- # raise a TypeError otherwise
- if isinstance(s, str):
- s = str.__str__(s)
- else:
- s = unicode.__getnewargs__(s)[0]
- def replace(match):
- s = match.group(0)
- try:
- return ESCAPE_DCT[s]
- except KeyError:
- n = ord(s)
- if n < 0x10000:
- #return '\\u{0:04x}'.format(n)
- return '\\u%04x' % (n,)
- else:
- # surrogate pair
- n -= 0x10000
- s1 = 0xd800 | ((n >> 10) & 0x3ff)
- s2 = 0xdc00 | (n & 0x3ff)
- #return '\\u{0:04x}\\u{1:04x}'.format(s1, s2)
- return '\\u%04x\\u%04x' % (s1, s2)
- return '"' + str(ESCAPE_ASCII.sub(replace, s)) + '"'
-
-
-encode_basestring_ascii = (
- c_encode_basestring_ascii or py_encode_basestring_ascii)
-
-class JSONEncoder(object):
- """Extensible JSON <http://json.org> encoder for Python data structures.
-
- Supports the following objects and types by default:
-
- +-------------------+---------------+
- | Python | JSON |
- +===================+===============+
- | dict, namedtuple | object |
- +-------------------+---------------+
- | list, tuple | array |
- +-------------------+---------------+
- | str, unicode | string |
- +-------------------+---------------+
- | int, long, float | number |
- +-------------------+---------------+
- | True | true |
- +-------------------+---------------+
- | False | false |
- +-------------------+---------------+
- | None | null |
- +-------------------+---------------+
-
- To extend this to recognize other objects, subclass and implement a
- ``.default()`` method with another method that returns a serializable
- object for ``o`` if possible, otherwise it should call the superclass
- implementation (to raise ``TypeError``).
-
- """
- item_separator = ', '
- key_separator = ': '
-
- def __init__(self, skipkeys=False, ensure_ascii=True,
- check_circular=True, allow_nan=True, sort_keys=False,
- indent=None, separators=None, encoding='utf-8', default=None,
- use_decimal=True, namedtuple_as_object=True,
- tuple_as_array=True, bigint_as_string=False,
- item_sort_key=None, for_json=False, ignore_nan=False,
- int_as_string_bitcount=None, iterable_as_array=False):
- """Constructor for JSONEncoder, with sensible defaults.
-
- If skipkeys is false, then it is a TypeError to attempt
- encoding of keys that are not str, int, long, float or None. If
- skipkeys is True, such items are simply skipped.
-
- If ensure_ascii is true, the output is guaranteed to be str
- objects with all incoming unicode characters escaped. If
- ensure_ascii is false, the output will be unicode object.
-
- If check_circular is true, then lists, dicts, and custom encoded
- objects will be checked for circular references during encoding to
- prevent an infinite recursion (which would cause an OverflowError).
- Otherwise, no such check takes place.
-
- If allow_nan is true, then NaN, Infinity, and -Infinity will be
- encoded as such. This behavior is not JSON specification compliant,
- but is consistent with most JavaScript based encoders and decoders.
- Otherwise, it will be a ValueError to encode such floats.
-
- If sort_keys is true, then the output of dictionaries will be
- sorted by key; this is useful for regression tests to ensure
- that JSON serializations can be compared on a day-to-day basis.
-
- If indent is a string, then JSON array elements and object members
- will be pretty-printed with a newline followed by that string repeated
- for each level of nesting. ``None`` (the default) selects the most compact
- representation without any newlines. For backwards compatibility with
- versions of simplejson earlier than 2.1.0, an integer is also accepted
- and is converted to a string with that many spaces.
-
- If specified, separators should be an (item_separator, key_separator)
- tuple. The default is (', ', ': ') if *indent* is ``None`` and
- (',', ': ') otherwise. To get the most compact JSON representation,
- you should specify (',', ':') to eliminate whitespace.
-
- If specified, default is a function that gets called for objects
- that can't otherwise be serialized. It should return a JSON encodable
- version of the object or raise a ``TypeError``.
-
- If encoding is not None, then all input strings will be
- transformed into unicode using that encoding prior to JSON-encoding.
- The default is UTF-8.
-
- If use_decimal is true (default: ``True``), ``decimal.Decimal`` will
- be supported directly by the encoder. For the inverse, decode JSON
- with ``parse_float=decimal.Decimal``.
-
- If namedtuple_as_object is true (the default), objects with
- ``_asdict()`` methods will be encoded as JSON objects.
-
- If tuple_as_array is true (the default), tuple (and subclasses) will
- be encoded as JSON arrays.
-
- If *iterable_as_array* is true (default: ``False``),
- any object not in the above table that implements ``__iter__()``
- will be encoded as a JSON array.
-
- If bigint_as_string is true (not the default), ints 2**53 and higher
- or lower than -2**53 will be encoded as strings. This is to avoid the
- rounding that happens in Javascript otherwise.
-
- If int_as_string_bitcount is a positive number (n), then int of size
- greater than or equal to 2**n or lower than or equal to -2**n will be
- encoded as strings.
-
- If specified, item_sort_key is a callable used to sort the items in
- each dictionary. This is useful if you want to sort items other than
- in alphabetical order by key.
-
- If for_json is true (not the default), objects with a ``for_json()``
- method will use the return value of that method for encoding as JSON
- instead of the object.
-
- If *ignore_nan* is true (default: ``False``), then out of range
- :class:`float` values (``nan``, ``inf``, ``-inf``) will be serialized
- as ``null`` in compliance with the ECMA-262 specification. If true,
- this will override *allow_nan*.
-
- """
-
- self.skipkeys = skipkeys
- self.ensure_ascii = ensure_ascii
- self.check_circular = check_circular
- self.allow_nan = allow_nan
- self.sort_keys = sort_keys
- self.use_decimal = use_decimal
- self.namedtuple_as_object = namedtuple_as_object
- self.tuple_as_array = tuple_as_array
- self.iterable_as_array = iterable_as_array
- self.bigint_as_string = bigint_as_string
- self.item_sort_key = item_sort_key
- self.for_json = for_json
- self.ignore_nan = ignore_nan
- self.int_as_string_bitcount = int_as_string_bitcount
- if indent is not None and not isinstance(indent, string_types):
- indent = indent * ' '
- self.indent = indent
- if separators is not None:
- self.item_separator, self.key_separator = separators
- elif indent is not None:
- self.item_separator = ','
- if default is not None:
- self.default = default
- self.encoding = encoding
-
- def default(self, o):
- """Implement this method in a subclass such that it returns
- a serializable object for ``o``, or calls the base implementation
- (to raise a ``TypeError``).
-
- For example, to support arbitrary iterators, you could
- implement default like this::
-
- def default(self, o):
- try:
- iterable = iter(o)
- except TypeError:
- pass
- else:
- return list(iterable)
- return JSONEncoder.default(self, o)
-
- """
- raise TypeError('Object of type %s is not JSON serializable' %
- o.__class__.__name__)
-
- def encode(self, o):
- """Return a JSON string representation of a Python data structure.
-
- >>> from simplejson import JSONEncoder
- >>> JSONEncoder().encode({"foo": ["bar", "baz"]})
- '{"foo": ["bar", "baz"]}'
-
- """
- # This is for extremely simple cases and benchmarks.
- if isinstance(o, binary_type):
- _encoding = self.encoding
- if (_encoding is not None and not (_encoding == 'utf-8')):
- o = text_type(o, _encoding)
- if isinstance(o, string_types):
- if self.ensure_ascii:
- return encode_basestring_ascii(o)
- else:
- return encode_basestring(o)
- # This doesn't pass the iterator directly to ''.join() because the
- # exceptions aren't as detailed. The list call should be roughly
- # equivalent to the PySequence_Fast that ''.join() would do.
- chunks = self.iterencode(o, _one_shot=True)
- if not isinstance(chunks, (list, tuple)):
- chunks = list(chunks)
- if self.ensure_ascii:
- return ''.join(chunks)
- else:
- return u''.join(chunks)
-
- def iterencode(self, o, _one_shot=False):
- """Encode the given object and yield each string
- representation as available.
-
- For example::
-
- for chunk in JSONEncoder().iterencode(bigobject):
- mysocket.write(chunk)
-
- """
- if self.check_circular:
- markers = {}
- else:
- markers = None
- if self.ensure_ascii:
- _encoder = encode_basestring_ascii
- else:
- _encoder = encode_basestring
- if self.encoding != 'utf-8' and self.encoding is not None:
- def _encoder(o, _orig_encoder=_encoder, _encoding=self.encoding):
- if isinstance(o, binary_type):
- o = text_type(o, _encoding)
- return _orig_encoder(o)
-
- def floatstr(o, allow_nan=self.allow_nan, ignore_nan=self.ignore_nan,
- _repr=FLOAT_REPR, _inf=PosInf, _neginf=-PosInf):
- # Check for specials. Note that this type of test is processor
- # and/or platform-specific, so do tests which don't depend on
- # the internals.
-
- if o != o:
- text = 'NaN'
- elif o == _inf:
- text = 'Infinity'
- elif o == _neginf:
- text = '-Infinity'
- else:
- if type(o) != float:
- # See #118, do not trust custom str/repr
- o = float(o)
- return _repr(o)
-
- if ignore_nan:
- text = 'null'
- elif not allow_nan:
- raise ValueError(
- "Out of range float values are not JSON compliant: " +
- repr(o))
-
- return text
-
- key_memo = {}
- int_as_string_bitcount = (
- 53 if self.bigint_as_string else self.int_as_string_bitcount)
- if (_one_shot and c_make_encoder is not None
- and self.indent is None):
- _iterencode = c_make_encoder(
- markers, self.default, _encoder, self.indent,
- self.key_separator, self.item_separator, self.sort_keys,
- self.skipkeys, self.allow_nan, key_memo, self.use_decimal,
- self.namedtuple_as_object, self.tuple_as_array,
- int_as_string_bitcount,
- self.item_sort_key, self.encoding, self.for_json,
- self.ignore_nan, decimal.Decimal, self.iterable_as_array)
- else:
- _iterencode = _make_iterencode(
- markers, self.default, _encoder, self.indent, floatstr,
- self.key_separator, self.item_separator, self.sort_keys,
- self.skipkeys, _one_shot, self.use_decimal,
- self.namedtuple_as_object, self.tuple_as_array,
- int_as_string_bitcount,
- self.item_sort_key, self.encoding, self.for_json,
- self.iterable_as_array, Decimal=decimal.Decimal)
- try:
- return _iterencode(o, 0)
- finally:
- key_memo.clear()
-
-
-class JSONEncoderForHTML(JSONEncoder):
- """An encoder that produces JSON safe to embed in HTML.
-
- To embed JSON content in, say, a script tag on a web page, the
- characters &, < and > should be escaped. They cannot be escaped
- with the usual entities (e.g. &amp;) because they are not expanded
- within <script> tags.
-
- This class also escapes the line separator and paragraph separator
- characters U+2028 and U+2029, irrespective of the ensure_ascii setting,
- as these characters are not valid in JavaScript strings (see
- http://timelessrepo.com/json-isnt-a-javascript-subset).
- """
-
- def encode(self, o):
- # Override JSONEncoder.encode because it has hacks for
- # performance that make things more complicated.
- chunks = self.iterencode(o, True)
- if self.ensure_ascii:
- return ''.join(chunks)
- else:
- return u''.join(chunks)
-
- def iterencode(self, o, _one_shot=False):
- chunks = super(JSONEncoderForHTML, self).iterencode(o, _one_shot)
- for chunk in chunks:
- chunk = chunk.replace('&', '\\u0026')
- chunk = chunk.replace('<', '\\u003c')
- chunk = chunk.replace('>', '\\u003e')
-
- if not self.ensure_ascii:
- chunk = chunk.replace(u'\u2028', '\\u2028')
- chunk = chunk.replace(u'\u2029', '\\u2029')
-
- yield chunk
-
-
-def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
- _key_separator, _item_separator, _sort_keys, _skipkeys, _one_shot,
- _use_decimal, _namedtuple_as_object, _tuple_as_array,
- _int_as_string_bitcount, _item_sort_key,
- _encoding,_for_json,
- _iterable_as_array,
- ## HACK: hand-optimized bytecode; turn globals into locals
- _PY3=PY3,
- ValueError=ValueError,
- string_types=string_types,
- Decimal=None,
- dict=dict,
- float=float,
- id=id,
- integer_types=integer_types,
- isinstance=isinstance,
- list=list,
- str=str,
- tuple=tuple,
- iter=iter,
- ):
- if _use_decimal and Decimal is None:
- Decimal = decimal.Decimal
- if _item_sort_key and not callable(_item_sort_key):
- raise TypeError("item_sort_key must be None or callable")
- elif _sort_keys and not _item_sort_key:
- _item_sort_key = itemgetter(0)
-
- if (_int_as_string_bitcount is not None and
- (_int_as_string_bitcount <= 0 or
- not isinstance(_int_as_string_bitcount, integer_types))):
- raise TypeError("int_as_string_bitcount must be a positive integer")
-
- def call_method(obj, method_name):
- method = getattr(obj, method_name, None)
- if callable(method):
- try:
- return (method(),)
- except TypeError:
- pass
- return None
-
- def _encode_int(value):
- skip_quoting = (
- _int_as_string_bitcount is None
- or
- _int_as_string_bitcount < 1
- )
- if type(value) not in integer_types:
- # See #118, do not trust custom str/repr
- value = int(value)
- if (
- skip_quoting or
- (-1 << _int_as_string_bitcount)
- < value <
- (1 << _int_as_string_bitcount)
- ):
- return str(value)
- return '"' + str(value) + '"'
-
- def _iterencode_list(lst, _current_indent_level):
- if not lst:
- yield '[]'
- return
- if markers is not None:
- markerid = id(lst)
- if markerid in markers:
- raise ValueError("Circular reference detected")
- markers[markerid] = lst
- buf = '['
- if _indent is not None:
- _current_indent_level += 1
- newline_indent = '\n' + (_indent * _current_indent_level)
- separator = _item_separator + newline_indent
- buf += newline_indent
- else:
- newline_indent = None
- separator = _item_separator
- first = True
- for value in lst:
- if first:
- first = False
- else:
- buf = separator
- if isinstance(value, string_types):
- yield buf + _encoder(value)
- elif _PY3 and isinstance(value, bytes) and _encoding is not None:
- yield buf + _encoder(value)
- elif isinstance(value, RawJSON):
- yield buf + value.encoded_json
- elif value is None:
- yield buf + 'null'
- elif value is True:
- yield buf + 'true'
- elif value is False:
- yield buf + 'false'
- elif isinstance(value, integer_types):
- yield buf + _encode_int(value)
- elif isinstance(value, float):
- yield buf + _floatstr(value)
- elif _use_decimal and isinstance(value, Decimal):
- yield buf + str(value)
- else:
- yield buf
- for_json = _for_json and call_method(value, 'for_json')
- if for_json:
- chunks = _iterencode(for_json[0], _current_indent_level)
- elif isinstance(value, list):
- chunks = _iterencode_list(value, _current_indent_level)
- else:
- _asdict = _namedtuple_as_object and call_method(value, '_asdict')
- if _asdict:
- dct = _asdict[0]
- if not isinstance(dct, dict):
- raise TypeError("_asdict() must return a dict, not %s" % (type(dct).__name__,))
- chunks = _iterencode_dict(dct,
- _current_indent_level)
- elif _tuple_as_array and isinstance(value, tuple):
- chunks = _iterencode_list(value, _current_indent_level)
- elif isinstance(value, dict):
- chunks = _iterencode_dict(value, _current_indent_level)
- else:
- chunks = _iterencode(value, _current_indent_level)
- for chunk in chunks:
- yield chunk
- if first:
- # iterable_as_array misses the fast path at the top
- yield '[]'
- else:
- if newline_indent is not None:
- _current_indent_level -= 1
- yield '\n' + (_indent * _current_indent_level)
- yield ']'
- if markers is not None:
- del markers[markerid]
-
- def _stringify_key(key):
- if isinstance(key, string_types): # pragma: no cover
- pass
- elif _PY3 and isinstance(key, bytes) and _encoding is not None:
- key = str(key, _encoding)
- elif isinstance(key, float):
- key = _floatstr(key)
- elif key is True:
- key = 'true'
- elif key is False:
- key = 'false'
- elif key is None:
- key = 'null'
- elif isinstance(key, integer_types):
- if type(key) not in integer_types:
- # See #118, do not trust custom str/repr
- key = int(key)
- key = str(key)
- elif _use_decimal and isinstance(key, Decimal):
- key = str(key)
- elif _skipkeys:
- key = None
- else:
- raise TypeError('keys must be str, int, float, bool or None, '
- 'not %s' % key.__class__.__name__)
- return key
-
- def _iterencode_dict(dct, _current_indent_level):
- if not dct:
- yield '{}'
- return
- if markers is not None:
- markerid = id(dct)
- if markerid in markers:
- raise ValueError("Circular reference detected")
- markers[markerid] = dct
- yield '{'
- if _indent is not None:
- _current_indent_level += 1
- newline_indent = '\n' + (_indent * _current_indent_level)
- item_separator = _item_separator + newline_indent
- yield newline_indent
- else:
- newline_indent = None
- item_separator = _item_separator
- first = True
- if _PY3:
- iteritems = dct.items()
- else:
- iteritems = dct.iteritems()
- if _item_sort_key:
- items = []
- for k, v in dct.items():
- if not isinstance(k, string_types):
- k = _stringify_key(k)
- if k is None:
- continue
- items.append((k, v))
- items.sort(key=_item_sort_key)
- else:
- items = iteritems
- for key, value in items:
- if not (_item_sort_key or isinstance(key, string_types)):
- key = _stringify_key(key)
- if key is None:
- # _skipkeys must be True
- continue
- if first:
- first = False
- else:
- yield item_separator
- yield _encoder(key)
- yield _key_separator
- if isinstance(value, string_types):
- yield _encoder(value)
- elif _PY3 and isinstance(value, bytes) and _encoding is not None:
- yield _encoder(value)
- elif isinstance(value, RawJSON):
- yield value.encoded_json
- elif value is None:
- yield 'null'
- elif value is True:
- yield 'true'
- elif value is False:
- yield 'false'
- elif isinstance(value, integer_types):
- yield _encode_int(value)
- elif isinstance(value, float):
- yield _floatstr(value)
- elif _use_decimal and isinstance(value, Decimal):
- yield str(value)
- else:
- for_json = _for_json and call_method(value, 'for_json')
- if for_json:
- chunks = _iterencode(for_json[0], _current_indent_level)
- elif isinstance(value, list):
- chunks = _iterencode_list(value, _current_indent_level)
- else:
- _asdict = _namedtuple_as_object and call_method(value, '_asdict')
- if _asdict:
- dct = _asdict[0]
- if not isinstance(dct, dict):
- raise TypeError("_asdict() must return a dict, not %s" % (type(dct).__name__,))
- chunks = _iterencode_dict(dct,
- _current_indent_level)
- elif _tuple_as_array and isinstance(value, tuple):
- chunks = _iterencode_list(value, _current_indent_level)
- elif isinstance(value, dict):
- chunks = _iterencode_dict(value, _current_indent_level)
- else:
- chunks = _iterencode(value, _current_indent_level)
- for chunk in chunks:
- yield chunk
- if newline_indent is not None:
- _current_indent_level -= 1
- yield '\n' + (_indent * _current_indent_level)
- yield '}'
- if markers is not None:
- del markers[markerid]
-
- def _iterencode(o, _current_indent_level):
- if isinstance(o, string_types):
- yield _encoder(o)
- elif _PY3 and isinstance(o, bytes) and _encoding is not None:
- yield _encoder(o)
- elif isinstance(o, RawJSON):
- yield o.encoded_json
- elif o is None:
- yield 'null'
- elif o is True:
- yield 'true'
- elif o is False:
- yield 'false'
- elif isinstance(o, integer_types):
- yield _encode_int(o)
- elif isinstance(o, float):
- yield _floatstr(o)
- else:
- for_json = _for_json and call_method(o, 'for_json')
- if for_json:
- for chunk in _iterencode(for_json[0], _current_indent_level):
- yield chunk
- elif isinstance(o, list):
- for chunk in _iterencode_list(o, _current_indent_level):
- yield chunk
- else:
- _asdict = _namedtuple_as_object and call_method(o, '_asdict')
- if _asdict:
- dct = _asdict[0]
- if not isinstance(dct, dict):
- raise TypeError("_asdict() must return a dict, not %s" % (type(dct).__name__,))
- for chunk in _iterencode_dict(dct, _current_indent_level):
- yield chunk
- elif (_tuple_as_array and isinstance(o, tuple)):
- for chunk in _iterencode_list(o, _current_indent_level):
- yield chunk
- elif isinstance(o, dict):
- for chunk in _iterencode_dict(o, _current_indent_level):
- yield chunk
- elif _use_decimal and isinstance(o, Decimal):
- yield str(o)
- else:
- while _iterable_as_array:
- # Markers are not checked here because it is valid for
- # an iterable to return self.
- try:
- o = iter(o)
- except TypeError:
- break
- for chunk in _iterencode_list(o, _current_indent_level):
- yield chunk
- return
- if markers is not None:
- markerid = id(o)
- if markerid in markers:
- raise ValueError("Circular reference detected")
- markers[markerid] = o
- o = _default(o)
- for chunk in _iterencode(o, _current_indent_level):
- yield chunk
- if markers is not None:
- del markers[markerid]
-
- return _iterencode
diff --git a/contrib/python/simplejson/simplejson/errors.py b/contrib/python/simplejson/simplejson/errors.py
deleted file mode 100644
index b97ab1e913..0000000000
--- a/contrib/python/simplejson/simplejson/errors.py
+++ /dev/null
@@ -1,53 +0,0 @@
-"""Error classes used by simplejson
-"""
-__all__ = ['JSONDecodeError']
-
-
-def linecol(doc, pos):
- lineno = doc.count('\n', 0, pos) + 1
- if lineno == 1:
- colno = pos + 1
- else:
- colno = pos - doc.rindex('\n', 0, pos)
- return lineno, colno
-
-
-def errmsg(msg, doc, pos, end=None):
- lineno, colno = linecol(doc, pos)
- msg = msg.replace('%r', repr(doc[pos:pos + 1]))
- if end is None:
- fmt = '%s: line %d column %d (char %d)'
- return fmt % (msg, lineno, colno, pos)
- endlineno, endcolno = linecol(doc, end)
- fmt = '%s: line %d column %d - line %d column %d (char %d - %d)'
- return fmt % (msg, lineno, colno, endlineno, endcolno, pos, end)
-
-
-class JSONDecodeError(ValueError):
- """Subclass of ValueError with the following additional properties:
-
- msg: The unformatted error message
- doc: The JSON document being parsed
- pos: The start index of doc where parsing failed
- end: The end index of doc where parsing failed (may be None)
- lineno: The line corresponding to pos
- colno: The column corresponding to pos
- endlineno: The line corresponding to end (may be None)
- endcolno: The column corresponding to end (may be None)
-
- """
- # Note that this exception is used from _speedups
- def __init__(self, msg, doc, pos, end=None):
- ValueError.__init__(self, errmsg(msg, doc, pos, end=end))
- self.msg = msg
- self.doc = doc
- self.pos = pos
- self.end = end
- self.lineno, self.colno = linecol(doc, pos)
- if end is not None:
- self.endlineno, self.endcolno = linecol(doc, end)
- else:
- self.endlineno, self.endcolno = None, None
-
- def __reduce__(self):
- return self.__class__, (self.msg, self.doc, self.pos, self.end)
diff --git a/contrib/python/simplejson/simplejson/ordered_dict.py b/contrib/python/simplejson/simplejson/ordered_dict.py
deleted file mode 100644
index d5a55ebd0f..0000000000
--- a/contrib/python/simplejson/simplejson/ordered_dict.py
+++ /dev/null
@@ -1,103 +0,0 @@
-"""Drop-in replacement for collections.OrderedDict by Raymond Hettinger
-
-http://code.activestate.com/recipes/576693/
-
-"""
-from UserDict import DictMixin
-
-class OrderedDict(dict, DictMixin):
-
- def __init__(self, *args, **kwds):
- if len(args) > 1:
- raise TypeError('expected at most 1 arguments, got %d' % len(args))
- try:
- self.__end
- except AttributeError:
- self.clear()
- self.update(*args, **kwds)
-
- def clear(self):
- self.__end = end = []
- end += [None, end, end] # sentinel node for doubly linked list
- self.__map = {} # key --> [key, prev, next]
- dict.clear(self)
-
- def __setitem__(self, key, value):
- if key not in self:
- end = self.__end
- curr = end[1]
- curr[2] = end[1] = self.__map[key] = [key, curr, end]
- dict.__setitem__(self, key, value)
-
- def __delitem__(self, key):
- dict.__delitem__(self, key)
- key, prev, next = self.__map.pop(key)
- prev[2] = next
- next[1] = prev
-
- def __iter__(self):
- end = self.__end
- curr = end[2]
- while curr is not end:
- yield curr[0]
- curr = curr[2]
-
- def __reversed__(self):
- end = self.__end
- curr = end[1]
- while curr is not end:
- yield curr[0]
- curr = curr[1]
-
- def popitem(self, last=True):
- if not self:
- raise KeyError('dictionary is empty')
- key = reversed(self).next() if last else iter(self).next()
- value = self.pop(key)
- return key, value
-
- def __reduce__(self):
- items = [[k, self[k]] for k in self]
- tmp = self.__map, self.__end
- del self.__map, self.__end
- inst_dict = vars(self).copy()
- self.__map, self.__end = tmp
- if inst_dict:
- return (self.__class__, (items,), inst_dict)
- return self.__class__, (items,)
-
- def keys(self):
- return list(self)
-
- setdefault = DictMixin.setdefault
- update = DictMixin.update
- pop = DictMixin.pop
- values = DictMixin.values
- items = DictMixin.items
- iterkeys = DictMixin.iterkeys
- itervalues = DictMixin.itervalues
- iteritems = DictMixin.iteritems
-
- def __repr__(self):
- if not self:
- return '%s()' % (self.__class__.__name__,)
- return '%s(%r)' % (self.__class__.__name__, self.items())
-
- def copy(self):
- return self.__class__(self)
-
- @classmethod
- def fromkeys(cls, iterable, value=None):
- d = cls()
- for key in iterable:
- d[key] = value
- return d
-
- def __eq__(self, other):
- if isinstance(other, OrderedDict):
- return len(self)==len(other) and \
- all(p==q for p, q in zip(self.items(), other.items()))
- return dict.__eq__(self, other)
-
- def __ne__(self, other):
- return not self == other
diff --git a/contrib/python/simplejson/simplejson/raw_json.py b/contrib/python/simplejson/simplejson/raw_json.py
deleted file mode 100644
index 2071a70206..0000000000
--- a/contrib/python/simplejson/simplejson/raw_json.py
+++ /dev/null
@@ -1,9 +0,0 @@
-"""Implementation of RawJSON
-"""
-
-class RawJSON(object):
- """Wrap an encoded JSON document for direct embedding in the output
-
- """
- def __init__(self, encoded_json):
- self.encoded_json = encoded_json
diff --git a/contrib/python/simplejson/simplejson/scanner.py b/contrib/python/simplejson/simplejson/scanner.py
deleted file mode 100644
index 85e385e147..0000000000
--- a/contrib/python/simplejson/simplejson/scanner.py
+++ /dev/null
@@ -1,85 +0,0 @@
-"""JSON token scanner
-"""
-import re
-from .errors import JSONDecodeError
-def _import_c_make_scanner():
- try:
- from ._speedups import make_scanner
- return make_scanner
- except ImportError:
- return None
-c_make_scanner = _import_c_make_scanner()
-
-__all__ = ['make_scanner', 'JSONDecodeError']
-
-NUMBER_RE = re.compile(
- r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?',
- (re.VERBOSE | re.MULTILINE | re.DOTALL))
-
-
-def py_make_scanner(context):
- parse_object = context.parse_object
- parse_array = context.parse_array
- parse_string = context.parse_string
- match_number = NUMBER_RE.match
- encoding = context.encoding
- strict = context.strict
- parse_float = context.parse_float
- parse_int = context.parse_int
- parse_constant = context.parse_constant
- object_hook = context.object_hook
- object_pairs_hook = context.object_pairs_hook
- memo = context.memo
-
- def _scan_once(string, idx):
- errmsg = 'Expecting value'
- try:
- nextchar = string[idx]
- except IndexError:
- raise JSONDecodeError(errmsg, string, idx)
-
- if nextchar == '"':
- return parse_string(string, idx + 1, encoding, strict)
- elif nextchar == '{':
- return parse_object((string, idx + 1), encoding, strict,
- _scan_once, object_hook, object_pairs_hook, memo)
- elif nextchar == '[':
- return parse_array((string, idx + 1), _scan_once)
- elif nextchar == 'n' and string[idx:idx + 4] == 'null':
- return None, idx + 4
- elif nextchar == 't' and string[idx:idx + 4] == 'true':
- return True, idx + 4
- elif nextchar == 'f' and string[idx:idx + 5] == 'false':
- return False, idx + 5
-
- m = match_number(string, idx)
- if m is not None:
- integer, frac, exp = m.groups()
- if frac or exp:
- res = parse_float(integer + (frac or '') + (exp or ''))
- else:
- res = parse_int(integer)
- return res, m.end()
- elif nextchar == 'N' and string[idx:idx + 3] == 'NaN':
- return parse_constant('NaN'), idx + 3
- elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity':
- return parse_constant('Infinity'), idx + 8
- elif nextchar == '-' and string[idx:idx + 9] == '-Infinity':
- return parse_constant('-Infinity'), idx + 9
- else:
- raise JSONDecodeError(errmsg, string, idx)
-
- def scan_once(string, idx):
- if idx < 0:
- # Ensure the same behavior as the C speedup, otherwise
- # this would work for *some* negative string indices due
- # to the behavior of __getitem__ for strings. #98
- raise JSONDecodeError('Expecting value', string, idx)
- try:
- return _scan_once(string, idx)
- finally:
- memo.clear()
-
- return scan_once
-
-make_scanner = c_make_scanner or py_make_scanner
diff --git a/contrib/python/simplejson/simplejson/tool.py b/contrib/python/simplejson/simplejson/tool.py
deleted file mode 100644
index 062e8e2c18..0000000000
--- a/contrib/python/simplejson/simplejson/tool.py
+++ /dev/null
@@ -1,42 +0,0 @@
-r"""Command-line tool to validate and pretty-print JSON
-
-Usage::
-
- $ echo '{"json":"obj"}' | python -m simplejson.tool
- {
- "json": "obj"
- }
- $ echo '{ 1.2:3.4}' | python -m simplejson.tool
- Expecting property name: line 1 column 2 (char 2)
-
-"""
-from __future__ import with_statement
-import sys
-import simplejson as json
-
-def main():
- if len(sys.argv) == 1:
- infile = sys.stdin
- outfile = sys.stdout
- elif len(sys.argv) == 2:
- infile = open(sys.argv[1], 'r')
- outfile = sys.stdout
- elif len(sys.argv) == 3:
- infile = open(sys.argv[1], 'r')
- outfile = open(sys.argv[2], 'w')
- else:
- raise SystemExit(sys.argv[0] + " [infile [outfile]]")
- with infile:
- try:
- obj = json.load(infile,
- object_pairs_hook=json.OrderedDict,
- use_decimal=True)
- except ValueError:
- raise SystemExit(sys.exc_info()[1])
- with outfile:
- json.dump(obj, outfile, sort_keys=True, indent=' ', use_decimal=True)
- outfile.write('\n')
-
-
-if __name__ == '__main__':
- main()
diff --git a/contrib/python/simplejson/ya.make b/contrib/python/simplejson/ya.make
deleted file mode 100644
index b0890214d7..0000000000
--- a/contrib/python/simplejson/ya.make
+++ /dev/null
@@ -1,48 +0,0 @@
-# Generated by devtools/yamaker (pypi).
-
-PY23_LIBRARY()
-
-VERSION(3.18.4)
-
-LICENSE(MIT)
-
-NO_COMPILER_WARNINGS()
-
-NO_LINT()
-
-NO_CHECK_IMPORTS(
- simplejson.ordered_dict
-)
-
-SRCS(
- simplejson/_speedups.c
-)
-
-PY_REGISTER(
- simplejson._speedups
-)
-
-PY_SRCS(
- TOP_LEVEL
- simplejson/__init__.py
- simplejson/compat.py
- simplejson/decoder.py
- simplejson/encoder.py
- simplejson/errors.py
- simplejson/ordered_dict.py
- simplejson/raw_json.py
- simplejson/scanner.py
- simplejson/tool.py
-)
-
-RESOURCE_FILES(
- PREFIX contrib/python/simplejson/
- .dist-info/METADATA
- .dist-info/top_level.txt
-)
-
-END()
-
-RECURSE_FOR_TESTS(
- tests
-)
diff --git a/contrib/python/toolz/py2/.dist-info/METADATA b/contrib/python/toolz/py2/.dist-info/METADATA
deleted file mode 100644
index c43bc308d4..0000000000
--- a/contrib/python/toolz/py2/.dist-info/METADATA
+++ /dev/null
@@ -1,159 +0,0 @@
-Metadata-Version: 2.1
-Name: toolz
-Version: 0.10.0
-Summary: List processing tools and functional utilities
-Home-page: https://github.com/pytoolz/toolz/
-Author: https://raw.github.com/pytoolz/toolz/master/AUTHORS.md
-Maintainer: Matthew Rocklin
-Maintainer-email: mrocklin@gmail.com
-License: BSD
-Keywords: functional utility itertools functools
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: License :: OSI Approved :: BSD License
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
-Classifier: Programming Language :: Python :: 3.6
-Classifier: Programming Language :: Python :: 3.7
-Classifier: Programming Language :: Python :: Implementation :: CPython
-Classifier: Programming Language :: Python :: Implementation :: PyPy
-Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
-
-Toolz
-=====
-
-|Build Status| |Coverage Status| |Version Status|
-
-A set of utility functions for iterators, functions, and dictionaries.
-
-See the PyToolz documentation at https://toolz.readthedocs.io
-
-LICENSE
--------
-
-New BSD. See `License File <https://github.com/pytoolz/toolz/blob/master/LICENSE.txt>`__.
-
-Install
--------
-
-``toolz`` is on the Python Package Index (PyPI):
-
-::
-
- pip install toolz
-
-Structure and Heritage
-----------------------
-
-``toolz`` is implemented in three parts:
-
-|literal itertoolz|_, for operations on iterables. Examples: ``groupby``,
-``unique``, ``interpose``,
-
-|literal functoolz|_, for higher-order functions. Examples: ``memoize``,
-``curry``, ``compose``,
-
-|literal dicttoolz|_, for operations on dictionaries. Examples: ``assoc``,
-``update-in``, ``merge``.
-
-.. |literal itertoolz| replace:: ``itertoolz``
-.. _literal itertoolz: https://github.com/pytoolz/toolz/blob/master/toolz/itertoolz.py
-
-.. |literal functoolz| replace:: ``functoolz``
-.. _literal functoolz: https://github.com/pytoolz/toolz/blob/master/toolz/functoolz.py
-
-.. |literal dicttoolz| replace:: ``dicttoolz``
-.. _literal dicttoolz: https://github.com/pytoolz/toolz/blob/master/toolz/dicttoolz.py
-
-These functions come from the legacy of functional languages for list
-processing. They interoperate well to accomplish common complex tasks.
-
-Read our `API
-Documentation <https://toolz.readthedocs.io/en/latest/api.html>`__ for
-more details.
-
-Example
--------
-
-This builds a standard wordcount function from pieces within ``toolz``:
-
-.. code:: python
-
- >>> def stem(word):
- ... """ Stem word to primitive form """
- ... return word.lower().rstrip(",.!:;'-\"").lstrip("'\"")
-
- >>> from toolz import compose, frequencies, partial
- >>> from toolz.curried import map
- >>> wordcount = compose(frequencies, map(stem), str.split)
-
- >>> sentence = "This cat jumped over this other cat!"
- >>> wordcount(sentence)
- {'this': 2, 'cat': 2, 'jumped': 1, 'over': 1, 'other': 1}
-
-Dependencies
-------------
-
-``toolz`` supports Python 2.7 and Python 3.4+ with a common codebase.
-It is pure Python and requires no dependencies beyond the standard
-library.
-
-It is, in short, a lightweight dependency.
-
-
-CyToolz
--------
-
-The ``toolz`` project has been reimplemented in `Cython <http://cython.org>`__.
-The ``cytoolz`` project is a drop-in replacement for the Pure Python
-implementation.
-See `CyToolz GitHub Page <https://github.com/pytoolz/cytoolz/>`__ for more
-details.
-
-See Also
---------
-
-- `Underscore.js <https://underscorejs.org/>`__: A similar library for
- JavaScript
-- `Enumerable <https://ruby-doc.org/core-2.0.0/Enumerable.html>`__: A
- similar library for Ruby
-- `Clojure <https://clojure.org/>`__: A functional language whose
- standard library has several counterparts in ``toolz``
-- `itertools <https://docs.python.org/2/library/itertools.html>`__: The
- Python standard library for iterator tools
-- `functools <https://docs.python.org/2/library/functools.html>`__: The
- Python standard library for function tools
-
-Contributions Welcome
----------------------
-
-``toolz`` aims to be a repository for utility functions, particularly
-those that come from the functional programming and list processing
-traditions. We welcome contributions that fall within this scope.
-
-We also try to keep the API small to keep ``toolz`` manageable. The ideal
-contribution is significantly different from existing functions and has
-precedent in a few other functional systems.
-
-Please take a look at our
-`issue page <https://github.com/pytoolz/toolz/issues>`__
-for contribution ideas.
-
-Community
----------
-
-See our `mailing list <https://groups.google.com/forum/#!forum/pytoolz>`__.
-We're friendly.
-
-.. |Build Status| image:: https://travis-ci.org/pytoolz/toolz.svg?branch=master
- :target: https://travis-ci.org/pytoolz/toolz
-.. |Coverage Status| image:: https://coveralls.io/repos/pytoolz/toolz/badge.svg?branch=master
- :target: https://coveralls.io/r/pytoolz/toolz
-.. |Version Status| image:: https://badge.fury.io/py/toolz.svg
- :target: https://badge.fury.io/py/toolz
-
-
diff --git a/contrib/python/toolz/py2/.dist-info/top_level.txt b/contrib/python/toolz/py2/.dist-info/top_level.txt
deleted file mode 100644
index e58ef014ac..0000000000
--- a/contrib/python/toolz/py2/.dist-info/top_level.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-tlz
-toolz
diff --git a/contrib/python/toolz/py2/LICENSE.txt b/contrib/python/toolz/py2/LICENSE.txt
deleted file mode 100644
index eeb91b202c..0000000000
--- a/contrib/python/toolz/py2/LICENSE.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-Copyright (c) 2013 Matthew Rocklin
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- a. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- b. 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.
- c. Neither the name of toolz nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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.
diff --git a/contrib/python/toolz/py2/README.rst b/contrib/python/toolz/py2/README.rst
deleted file mode 100644
index 099c3ff807..0000000000
--- a/contrib/python/toolz/py2/README.rst
+++ /dev/null
@@ -1,132 +0,0 @@
-Toolz
-=====
-
-|Build Status| |Coverage Status| |Version Status|
-
-A set of utility functions for iterators, functions, and dictionaries.
-
-See the PyToolz documentation at https://toolz.readthedocs.io
-
-LICENSE
--------
-
-New BSD. See `License File <https://github.com/pytoolz/toolz/blob/master/LICENSE.txt>`__.
-
-Install
--------
-
-``toolz`` is on the Python Package Index (PyPI):
-
-::
-
- pip install toolz
-
-Structure and Heritage
-----------------------
-
-``toolz`` is implemented in three parts:
-
-|literal itertoolz|_, for operations on iterables. Examples: ``groupby``,
-``unique``, ``interpose``,
-
-|literal functoolz|_, for higher-order functions. Examples: ``memoize``,
-``curry``, ``compose``,
-
-|literal dicttoolz|_, for operations on dictionaries. Examples: ``assoc``,
-``update-in``, ``merge``.
-
-.. |literal itertoolz| replace:: ``itertoolz``
-.. _literal itertoolz: https://github.com/pytoolz/toolz/blob/master/toolz/itertoolz.py
-
-.. |literal functoolz| replace:: ``functoolz``
-.. _literal functoolz: https://github.com/pytoolz/toolz/blob/master/toolz/functoolz.py
-
-.. |literal dicttoolz| replace:: ``dicttoolz``
-.. _literal dicttoolz: https://github.com/pytoolz/toolz/blob/master/toolz/dicttoolz.py
-
-These functions come from the legacy of functional languages for list
-processing. They interoperate well to accomplish common complex tasks.
-
-Read our `API
-Documentation <https://toolz.readthedocs.io/en/latest/api.html>`__ for
-more details.
-
-Example
--------
-
-This builds a standard wordcount function from pieces within ``toolz``:
-
-.. code:: python
-
- >>> def stem(word):
- ... """ Stem word to primitive form """
- ... return word.lower().rstrip(",.!:;'-\"").lstrip("'\"")
-
- >>> from toolz import compose, frequencies, partial
- >>> from toolz.curried import map
- >>> wordcount = compose(frequencies, map(stem), str.split)
-
- >>> sentence = "This cat jumped over this other cat!"
- >>> wordcount(sentence)
- {'this': 2, 'cat': 2, 'jumped': 1, 'over': 1, 'other': 1}
-
-Dependencies
-------------
-
-``toolz`` supports Python 2.7 and Python 3.4+ with a common codebase.
-It is pure Python and requires no dependencies beyond the standard
-library.
-
-It is, in short, a lightweight dependency.
-
-
-CyToolz
--------
-
-The ``toolz`` project has been reimplemented in `Cython <http://cython.org>`__.
-The ``cytoolz`` project is a drop-in replacement for the Pure Python
-implementation.
-See `CyToolz GitHub Page <https://github.com/pytoolz/cytoolz/>`__ for more
-details.
-
-See Also
---------
-
-- `Underscore.js <https://underscorejs.org/>`__: A similar library for
- JavaScript
-- `Enumerable <https://ruby-doc.org/core-2.0.0/Enumerable.html>`__: A
- similar library for Ruby
-- `Clojure <https://clojure.org/>`__: A functional language whose
- standard library has several counterparts in ``toolz``
-- `itertools <https://docs.python.org/2/library/itertools.html>`__: The
- Python standard library for iterator tools
-- `functools <https://docs.python.org/2/library/functools.html>`__: The
- Python standard library for function tools
-
-Contributions Welcome
----------------------
-
-``toolz`` aims to be a repository for utility functions, particularly
-those that come from the functional programming and list processing
-traditions. We welcome contributions that fall within this scope.
-
-We also try to keep the API small to keep ``toolz`` manageable. The ideal
-contribution is significantly different from existing functions and has
-precedent in a few other functional systems.
-
-Please take a look at our
-`issue page <https://github.com/pytoolz/toolz/issues>`__
-for contribution ideas.
-
-Community
----------
-
-See our `mailing list <https://groups.google.com/forum/#!forum/pytoolz>`__.
-We're friendly.
-
-.. |Build Status| image:: https://travis-ci.org/pytoolz/toolz.svg?branch=master
- :target: https://travis-ci.org/pytoolz/toolz
-.. |Coverage Status| image:: https://coveralls.io/repos/pytoolz/toolz/badge.svg?branch=master
- :target: https://coveralls.io/r/pytoolz/toolz
-.. |Version Status| image:: https://badge.fury.io/py/toolz.svg
- :target: https://badge.fury.io/py/toolz
diff --git a/contrib/python/toolz/py2/tlz/__init__.py b/contrib/python/toolz/py2/tlz/__init__.py
deleted file mode 100644
index 9c9c84afe1..0000000000
--- a/contrib/python/toolz/py2/tlz/__init__.py
+++ /dev/null
@@ -1,9 +0,0 @@
-"""``tlz`` mirrors the ``toolz`` API and uses ``cytoolz`` if possible.
-
-The ``tlz`` package is installed when ``toolz`` is installed. It provides
-a convenient way to use functions from ``cytoolz``--a faster Cython
-implementation of ``toolz``--if it is installed, otherwise it uses
-functions from ``toolz``.
-"""
-
-from . import _build_tlz
diff --git a/contrib/python/toolz/py2/tlz/_build_tlz.py b/contrib/python/toolz/py2/tlz/_build_tlz.py
deleted file mode 100644
index 3c017a542c..0000000000
--- a/contrib/python/toolz/py2/tlz/_build_tlz.py
+++ /dev/null
@@ -1,100 +0,0 @@
-import sys
-import types
-import toolz
-from importlib import import_module
-
-
-class TlzLoader(object):
- """ Finds and loads ``tlz`` modules when added to sys.meta_path"""
- def __init__(self):
- self.always_from_toolz = {
- toolz.pipe,
- }
-
- def _load_toolz(self, fullname):
- rv = {}
- package, dot, submodules = fullname.partition('.')
- try:
- module_name = ''.join(['cytoolz', dot, submodules])
- rv['cytoolz'] = import_module(module_name)
- except ImportError:
- pass
- try:
- module_name = ''.join(['toolz', dot, submodules])
- rv['toolz'] = import_module(module_name)
- except ImportError:
- pass
- if not rv:
- raise ImportError(fullname)
- return rv
-
- def find_module(self, fullname, path=None): # pragma: py3 no cover
- package, dot, submodules = fullname.partition('.')
- if package == 'tlz':
- return self
-
- def load_module(self, fullname): # pragma: py3 no cover
- if fullname in sys.modules: # pragma: no cover
- return sys.modules[fullname]
- spec = TlzSpec(fullname, self)
- module = self.create_module(spec)
- sys.modules[fullname] = module
- self.exec_module(module)
- return module
-
- def find_spec(self, fullname, path, target=None): # pragma: no cover
- package, dot, submodules = fullname.partition('.')
- if package == 'tlz':
- return TlzSpec(fullname, self)
-
- def create_module(self, spec):
- return types.ModuleType(spec.name)
-
- def exec_module(self, module):
- toolz_mods = self._load_toolz(module.__name__)
- fast_mod = toolz_mods.get('cytoolz') or toolz_mods['toolz']
- slow_mod = toolz_mods.get('toolz') or toolz_mods['cytoolz']
- module.__dict__.update(toolz.merge(fast_mod.__dict__, module.__dict__))
- package = fast_mod.__package__
- if package is not None:
- package, dot, submodules = package.partition('.')
- module.__package__ = ''.join(['tlz', dot, submodules])
- if not module.__doc__:
- module.__doc__ = fast_mod.__doc__
-
- # show file from toolz during introspection
- module.__file__ = slow_mod.__file__
-
- for k, v in fast_mod.__dict__.items():
- tv = slow_mod.__dict__.get(k)
- try:
- hash(tv)
- except TypeError:
- tv = None
- if tv in self.always_from_toolz:
- module.__dict__[k] = tv
- elif (
- isinstance(v, types.ModuleType)
- and v.__package__ == fast_mod.__name__
- ):
- package, dot, submodules = v.__name__.partition('.')
- module_name = ''.join(['tlz', dot, submodules])
- submodule = import_module(module_name)
- module.__dict__[k] = submodule
-
-
-class TlzSpec(object):
- def __init__(self, name, loader):
- self.name = name
- self.loader = loader
- self.origin = None
- self.submodule_search_locations = []
- self.loader_state = None
- self.cached = None
- self.parent = None
- self.has_location = False
-
-
-tlz_loader = TlzLoader()
-sys.meta_path.append(tlz_loader)
-tlz_loader.exec_module(sys.modules['tlz'])
diff --git a/contrib/python/toolz/py2/toolz/__init__.py b/contrib/python/toolz/py2/toolz/__init__.py
deleted file mode 100644
index 7fa86ab473..0000000000
--- a/contrib/python/toolz/py2/toolz/__init__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-from .itertoolz import *
-
-from .functoolz import *
-
-from .dicttoolz import *
-
-from .recipes import *
-
-from .compatibility import map, filter
-
-from functools import partial, reduce
-
-sorted = sorted
-
-# Aliases
-comp = compose
-
-from . import curried, sandbox
-
-functoolz._sigs.create_signature_registry()
-
-__version__ = '0.10.0'
diff --git a/contrib/python/toolz/py2/toolz/_signatures.py b/contrib/python/toolz/py2/toolz/_signatures.py
deleted file mode 100644
index c55a778b3b..0000000000
--- a/contrib/python/toolz/py2/toolz/_signatures.py
+++ /dev/null
@@ -1,832 +0,0 @@
-"""Internal module for better introspection of builtins.
-
-The main functions are ``is_builtin_valid_args``, ``is_builtin_partial_args``,
-and ``has_unknown_args``. Other functions in this module support these three.
-
-Notably, we create a ``signatures`` registry to enable introspection of
-builtin functions in any Python version. This includes builtins that
-have more than one valid signature. Currently, the registry includes
-builtins from ``builtins``, ``functools``, ``itertools``, and ``operator``
-modules. More can be added as requested. We don't guarantee full coverage.
-
-Everything in this module should be regarded as implementation details.
-Users should try to not use this module directly.
-"""
-import functools
-import inspect
-import itertools
-import operator
-from importlib import import_module
-
-from .compatibility import PY3
-from .functoolz import (is_partial_args, is_arity, has_varargs,
- has_keywords, num_required_args)
-
-if PY3: # pragma: py2 no cover
- import builtins
-else: # pragma: py3 no cover
- import __builtin__ as builtins
-
-# We mock builtin callables using lists of tuples with lambda functions.
-#
-# The tuple spec is (num_position_args, lambda_func, keyword_only_args).
-#
-# num_position_args:
-# - The number of positional-only arguments. If not specified,
-# all positional arguments are considered positional-only.
-#
-# lambda_func:
-# - lambda function that matches a signature of a builtin, but does
-# not include keyword-only arguments.
-#
-# keyword_only_args: (optional)
-# - Tuple of keyword-only argumemts.
-
-module_info = {}
-
-module_info[builtins] = dict(
- abs=[
- lambda x: None],
- all=[
- lambda iterable: None],
- any=[
- lambda iterable: None],
- apply=[
- lambda object: None,
- lambda object, args: None,
- lambda object, args, kwargs: None],
- ascii=[
- lambda obj: None],
- bin=[
- lambda number: None],
- bool=[
- lambda x=False: None],
- buffer=[
- lambda object: None,
- lambda object, offset: None,
- lambda object, offset, size: None],
- bytearray=[
- lambda: None,
- lambda int: None,
- lambda string, encoding='utf8', errors='strict': None],
- callable=[
- lambda obj: None],
- chr=[
- lambda i: None],
- classmethod=[
- lambda function: None],
- cmp=[
- lambda x, y: None],
- coerce=[
- lambda x, y: None],
- complex=[
- lambda real=0, imag=0: None],
- delattr=[
- lambda obj, name: None],
- dict=[
- lambda **kwargs: None,
- lambda mapping, **kwargs: None],
- dir=[
- lambda: None,
- lambda object: None],
- divmod=[
- lambda x, y: None],
- enumerate=[
- (0, lambda iterable, start=0: None)],
- eval=[
- lambda source: None,
- lambda source, globals: None,
- lambda source, globals, locals: None],
- execfile=[
- lambda filename: None,
- lambda filename, globals: None,
- lambda filename, globals, locals: None],
- file=[
- (0, lambda name, mode='r', buffering=-1: None)],
- filter=[
- lambda function, iterable: None],
- float=[
- lambda x=0.0: None],
- format=[
- lambda value: None,
- lambda value, format_spec: None],
- frozenset=[
- lambda: None,
- lambda iterable: None],
- getattr=[
- lambda object, name: None,
- lambda object, name, default: None],
- globals=[
- lambda: None],
- hasattr=[
- lambda obj, name: None],
- hash=[
- lambda obj: None],
- hex=[
- lambda number: None],
- id=[
- lambda obj: None],
- input=[
- lambda: None,
- lambda prompt: None],
- int=[
- lambda x=0: None,
- (0, lambda x, base=10: None)],
- intern=[
- lambda string: None],
- isinstance=[
- lambda obj, class_or_tuple: None],
- issubclass=[
- lambda cls, class_or_tuple: None],
- iter=[
- lambda iterable: None,
- lambda callable, sentinel: None],
- len=[
- lambda obj: None],
- list=[
- lambda: None,
- lambda iterable: None],
- locals=[
- lambda: None],
- long=[
- lambda x=0: None,
- (0, lambda x, base=10: None)],
- map=[
- lambda func, sequence, *iterables: None],
- memoryview=[
- (0, lambda object: None)],
- next=[
- lambda iterator: None,
- lambda iterator, default: None],
- object=[
- lambda: None],
- oct=[
- lambda number: None],
- ord=[
- lambda c: None],
- pow=[
- lambda x, y: None,
- lambda x, y, z: None],
- property=[
- lambda fget=None, fset=None, fdel=None, doc=None: None],
- range=[
- lambda stop: None,
- lambda start, stop: None,
- lambda start, stop, step: None],
- raw_input=[
- lambda: None,
- lambda prompt: None],
- reduce=[
- lambda function, sequence: None,
- lambda function, sequence, initial: None],
- reload=[
- lambda module: None],
- repr=[
- lambda obj: None],
- reversed=[
- lambda sequence: None],
- round=[
- (0, lambda number, ndigits=0: None)],
- set=[
- lambda: None,
- lambda iterable: None],
- setattr=[
- lambda obj, name, value: None],
- slice=[
- lambda stop: None,
- lambda start, stop: None,
- lambda start, stop, step: None],
- staticmethod=[
- lambda function: None],
- sum=[
- lambda iterable: None,
- lambda iterable, start: None],
- super=[
- lambda type: None,
- lambda type, obj: None],
- tuple=[
- lambda: None,
- lambda iterable: None],
- type=[
- lambda object: None,
- lambda name, bases, dict: None],
- unichr=[
- lambda i: None],
- unicode=[
- lambda object: None,
- lambda string='', encoding='utf8', errors='strict': None],
- vars=[
- lambda: None,
- lambda object: None],
- xrange=[
- lambda stop: None,
- lambda start, stop: None,
- lambda start, stop, step: None],
- zip=[
- lambda *iterables: None],
- __build_class__=[
- (2, lambda func, name, *bases, **kwds: None, ('metaclass',))],
- __import__=[
- (0, lambda name, globals=None, locals=None, fromlist=None,
- level=None: None)],
-)
-module_info[builtins]['exec'] = [
- lambda source: None,
- lambda source, globals: None,
- lambda source, globals, locals: None]
-
-if PY3: # pragma: py2 no cover
- module_info[builtins].update(
- breakpoint=[
- lambda *args, **kws: None],
- bytes=[
- lambda: None,
- lambda int: None,
- lambda string, encoding='utf8', errors='strict': None],
- compile=[
- (0, lambda source, filename, mode, flags=0,
- dont_inherit=False, optimize=-1: None)],
- max=[
- (1, lambda iterable: None, ('default', 'key',)),
- (1, lambda arg1, arg2, *args: None, ('key',))],
- min=[
- (1, lambda iterable: None, ('default', 'key',)),
- (1, lambda arg1, arg2, *args: None, ('key',))],
- open=[
- (0, lambda file, mode='r', buffering=-1, encoding=None,
- errors=None, newline=None, closefd=True, opener=None: None)],
- sorted=[
- (1, lambda iterable: None, ('key', 'reverse'))],
- str=[
- lambda object='', encoding='utf', errors='strict': None],
- )
- module_info[builtins]['print'] = [
- (0, lambda *args: None, ('sep', 'end', 'file', 'flush',))]
-
-else: # pragma: py3 no cover
- module_info[builtins].update(
- bytes=[
- lambda object='': None],
- compile=[
- (0, lambda source, filename, mode, flags=0,
- dont_inherit=False: None)],
- max=[
- (1, lambda iterable, *args: None, ('key',))],
- min=[
- (1, lambda iterable, *args: None, ('key',))],
- open=[
- (0, lambda file, mode='r', buffering=-1: None)],
- sorted=[
- lambda iterable, cmp=None, key=None, reverse=False: None],
- str=[
- lambda object='': None],
- )
- module_info[builtins]['print'] = [
- (0, lambda *args: None, ('sep', 'end', 'file',))]
-
-module_info[functools] = dict(
- cmp_to_key=[
- (0, lambda mycmp: None)],
- partial=[
- lambda func, *args, **kwargs: None],
- partialmethod=[
- lambda func, *args, **kwargs: None],
- reduce=[
- lambda function, sequence: None,
- lambda function, sequence, initial: None],
-)
-
-module_info[itertools] = dict(
- accumulate=[
- (0, lambda iterable, func=None: None)],
- chain=[
- lambda *iterables: None],
- combinations=[
- (0, lambda iterable, r: None)],
- combinations_with_replacement=[
- (0, lambda iterable, r: None)],
- compress=[
- (0, lambda data, selectors: None)],
- count=[
- lambda start=0, step=1: None],
- cycle=[
- lambda iterable: None],
- dropwhile=[
- lambda predicate, iterable: None],
- filterfalse=[
- lambda function, sequence: None],
- groupby=[
- (0, lambda iterable, key=None: None)],
- ifilter=[
- lambda function, sequence: None],
- ifilterfalse=[
- lambda function, sequence: None],
- imap=[
- lambda func, sequence, *iterables: None],
- islice=[
- lambda iterable, stop: None,
- lambda iterable, start, stop: None,
- lambda iterable, start, stop, step: None],
- izip=[
- lambda *iterables: None],
- izip_longest=[
- (0, lambda *iterables: None, ('fillvalue',))],
- permutations=[
- (0, lambda iterable, r=0: None)],
- repeat=[
- (0, lambda object, times=0: None)],
- starmap=[
- lambda function, sequence: None],
- takewhile=[
- lambda predicate, iterable: None],
- tee=[
- lambda iterable: None,
- lambda iterable, n: None],
- zip_longest=[
- (0, lambda *iterables: None, ('fillvalue',))],
-)
-
-if PY3: # pragma: py2 no cover
- module_info[itertools].update(
- product=[
- (0, lambda *iterables: None, ('repeat',))],
- )
-else: # pragma: py3 no cover
- module_info[itertools].update(
- product=[
- lambda *iterables: None],
- )
-
-module_info[operator] = dict(
- __abs__=[
- lambda a: None],
- __add__=[
- lambda a, b: None],
- __and__=[
- lambda a, b: None],
- __concat__=[
- lambda a, b: None],
- __contains__=[
- lambda a, b: None],
- __delitem__=[
- lambda a, b: None],
- __delslice__=[
- lambda a, b, c: None],
- __div__=[
- lambda a, b: None],
- __eq__=[
- lambda a, b: None],
- __floordiv__=[
- lambda a, b: None],
- __ge__=[
- lambda a, b: None],
- __getitem__=[
- lambda a, b: None],
- __getslice__=[
- lambda a, b, c: None],
- __gt__=[
- lambda a, b: None],
- __iadd__=[
- lambda a, b: None],
- __iand__=[
- lambda a, b: None],
- __iconcat__=[
- lambda a, b: None],
- __idiv__=[
- lambda a, b: None],
- __ifloordiv__=[
- lambda a, b: None],
- __ilshift__=[
- lambda a, b: None],
- __imatmul__=[
- lambda a, b: None],
- __imod__=[
- lambda a, b: None],
- __imul__=[
- lambda a, b: None],
- __index__=[
- lambda a: None],
- __inv__=[
- lambda a: None],
- __invert__=[
- lambda a: None],
- __ior__=[
- lambda a, b: None],
- __ipow__=[
- lambda a, b: None],
- __irepeat__=[
- lambda a, b: None],
- __irshift__=[
- lambda a, b: None],
- __isub__=[
- lambda a, b: None],
- __itruediv__=[
- lambda a, b: None],
- __ixor__=[
- lambda a, b: None],
- __le__=[
- lambda a, b: None],
- __lshift__=[
- lambda a, b: None],
- __lt__=[
- lambda a, b: None],
- __matmul__=[
- lambda a, b: None],
- __mod__=[
- lambda a, b: None],
- __mul__=[
- lambda a, b: None],
- __ne__=[
- lambda a, b: None],
- __neg__=[
- lambda a: None],
- __not__=[
- lambda a: None],
- __or__=[
- lambda a, b: None],
- __pos__=[
- lambda a: None],
- __pow__=[
- lambda a, b: None],
- __repeat__=[
- lambda a, b: None],
- __rshift__=[
- lambda a, b: None],
- __setitem__=[
- lambda a, b, c: None],
- __setslice__=[
- lambda a, b, c, d: None],
- __sub__=[
- lambda a, b: None],
- __truediv__=[
- lambda a, b: None],
- __xor__=[
- lambda a, b: None],
- _abs=[
- lambda x: None],
- _compare_digest=[
- lambda a, b: None],
- abs=[
- lambda a: None],
- add=[
- lambda a, b: None],
- and_=[
- lambda a, b: None],
- attrgetter=[
- lambda attr, *args: None],
- concat=[
- lambda a, b: None],
- contains=[
- lambda a, b: None],
- countOf=[
- lambda a, b: None],
- delitem=[
- lambda a, b: None],
- delslice=[
- lambda a, b, c: None],
- div=[
- lambda a, b: None],
- eq=[
- lambda a, b: None],
- floordiv=[
- lambda a, b: None],
- ge=[
- lambda a, b: None],
- getitem=[
- lambda a, b: None],
- getslice=[
- lambda a, b, c: None],
- gt=[
- lambda a, b: None],
- iadd=[
- lambda a, b: None],
- iand=[
- lambda a, b: None],
- iconcat=[
- lambda a, b: None],
- idiv=[
- lambda a, b: None],
- ifloordiv=[
- lambda a, b: None],
- ilshift=[
- lambda a, b: None],
- imatmul=[
- lambda a, b: None],
- imod=[
- lambda a, b: None],
- imul=[
- lambda a, b: None],
- index=[
- lambda a: None],
- indexOf=[
- lambda a, b: None],
- inv=[
- lambda a: None],
- invert=[
- lambda a: None],
- ior=[
- lambda a, b: None],
- ipow=[
- lambda a, b: None],
- irepeat=[
- lambda a, b: None],
- irshift=[
- lambda a, b: None],
- is_=[
- lambda a, b: None],
- is_not=[
- lambda a, b: None],
- isCallable=[
- lambda a: None],
- isMappingType=[
- lambda a: None],
- isNumberType=[
- lambda a: None],
- isSequenceType=[
- lambda a: None],
- isub=[
- lambda a, b: None],
- itemgetter=[
- lambda item, *args: None],
- itruediv=[
- lambda a, b: None],
- ixor=[
- lambda a, b: None],
- le=[
- lambda a, b: None],
- length_hint=[
- lambda obj: None,
- lambda obj, default: None],
- lshift=[
- lambda a, b: None],
- lt=[
- lambda a, b: None],
- matmul=[
- lambda a, b: None],
- methodcaller=[
- lambda name, *args, **kwargs: None],
- mod=[
- lambda a, b: None],
- mul=[
- lambda a, b: None],
- ne=[
- lambda a, b: None],
- neg=[
- lambda a: None],
- not_=[
- lambda a: None],
- or_=[
- lambda a, b: None],
- pos=[
- lambda a: None],
- pow=[
- lambda a, b: None],
- repeat=[
- lambda a, b: None],
- rshift=[
- lambda a, b: None],
- sequenceIncludes=[
- lambda a, b: None],
- setitem=[
- lambda a, b, c: None],
- setslice=[
- lambda a, b, c, d: None],
- sub=[
- lambda a, b: None],
- truediv=[
- lambda a, b: None],
- truth=[
- lambda a: None],
- xor=[
- lambda a, b: None],
-)
-
-module_info['toolz'] = dict(
- curry=[
- (0, lambda *args, **kwargs: None)],
- excepts=[
- (0, lambda exc, func, handler=None: None)],
- flip=[
- (0, lambda func=None, a=None, b=None: None)],
- juxt=[
- (0, lambda *funcs: None)],
- memoize=[
- (0, lambda func=None, cache=None, key=None: None)],
-)
-
-module_info['toolz.functoolz'] = dict(
- Compose=[
- (0, lambda funcs: None)],
- InstanceProperty=[
- (0, lambda fget=None, fset=None, fdel=None, doc=None,
- classval=None: None)],
-)
-
-if PY3: # pragma: py2 no cover
- def num_pos_args(sigspec):
- """ Return the number of positional arguments. ``f(x, y=1)`` has 1"""
- return sum(1 for x in sigspec.parameters.values()
- if x.kind == x.POSITIONAL_OR_KEYWORD
- and x.default is x.empty)
-
- def get_exclude_keywords(num_pos_only, sigspec):
- """ Return the names of position-only arguments if func has **kwargs"""
- if num_pos_only == 0:
- return ()
- has_kwargs = any(x.kind == x.VAR_KEYWORD
- for x in sigspec.parameters.values())
- if not has_kwargs:
- return ()
- pos_args = list(sigspec.parameters.values())[:num_pos_only]
- return tuple(x.name for x in pos_args)
-
- def signature_or_spec(func):
- try:
- return inspect.signature(func)
- except (ValueError, TypeError):
- return None
-
-else: # pragma: py3 no cover
- def num_pos_args(sigspec):
- """ Return the number of positional arguments. ``f(x, y=1)`` has 1"""
- if sigspec.defaults:
- return len(sigspec.args) - len(sigspec.defaults)
- return len(sigspec.args)
-
- def get_exclude_keywords(num_pos_only, sigspec):
- """ Return the names of position-only arguments if func has **kwargs"""
- if num_pos_only == 0:
- return ()
- has_kwargs = sigspec.keywords is not None
- if not has_kwargs:
- return ()
- return tuple(sigspec.args[:num_pos_only])
-
- def signature_or_spec(func):
- try:
- return inspect.getargspec(func)
- except TypeError:
- return None
-
-
-def expand_sig(sig):
- """ Convert the signature spec in ``module_info`` to add to ``signatures``
-
- The input signature spec is one of:
- - ``lambda_func``
- - ``(num_position_args, lambda_func)``
- - ``(num_position_args, lambda_func, keyword_only_args)``
-
- The output signature spec is:
- ``(num_position_args, lambda_func, keyword_exclude, sigspec)``
-
- where ``keyword_exclude`` includes keyword only arguments and, if variadic
- keywords is present, the names of position-only argument. The latter is
- included to support builtins such as ``partial(func, *args, **kwargs)``,
- which allows ``func=`` to be used as a keyword even though it's the name
- of a positional argument.
- """
- if isinstance(sig, tuple):
- if len(sig) == 3:
- num_pos_only, func, keyword_only = sig
- assert isinstance(sig[-1], tuple)
- else:
- num_pos_only, func = sig
- keyword_only = ()
- sigspec = signature_or_spec(func)
- else:
- func = sig
- sigspec = signature_or_spec(func)
- num_pos_only = num_pos_args(sigspec)
- keyword_only = ()
- keyword_exclude = get_exclude_keywords(num_pos_only, sigspec)
- return num_pos_only, func, keyword_only + keyword_exclude, sigspec
-
-
-signatures = {}
-
-
-def create_signature_registry(module_info=module_info, signatures=signatures):
- for module, info in module_info.items():
- if isinstance(module, str):
- module = import_module(module)
- for name, sigs in info.items():
- if hasattr(module, name):
- new_sigs = tuple(expand_sig(sig) for sig in sigs)
- signatures[getattr(module, name)] = new_sigs
-
-
-def check_valid(sig, args, kwargs):
- """ Like ``is_valid_args`` for the given signature spec"""
- num_pos_only, func, keyword_exclude, sigspec = sig
- if len(args) < num_pos_only:
- return False
- if keyword_exclude:
- kwargs = dict(kwargs)
- for item in keyword_exclude:
- kwargs.pop(item, None)
- try:
- func(*args, **kwargs)
- return True
- except TypeError:
- return False
-
-
-def _is_valid_args(func, args, kwargs):
- """ Like ``is_valid_args`` for builtins in our ``signatures`` registry"""
- if func not in signatures:
- return None
- sigs = signatures[func]
- return any(check_valid(sig, args, kwargs) for sig in sigs)
-
-
-def check_partial(sig, args, kwargs):
- """ Like ``is_partial_args`` for the given signature spec"""
- num_pos_only, func, keyword_exclude, sigspec = sig
- if len(args) < num_pos_only:
- pad = (None,) * (num_pos_only - len(args))
- args = args + pad
- if keyword_exclude:
- kwargs = dict(kwargs)
- for item in keyword_exclude:
- kwargs.pop(item, None)
- return is_partial_args(func, args, kwargs, sigspec)
-
-
-def _is_partial_args(func, args, kwargs):
- """ Like ``is_partial_args`` for builtins in our ``signatures`` registry"""
- if func not in signatures:
- return None
- sigs = signatures[func]
- return any(check_partial(sig, args, kwargs) for sig in sigs)
-
-
-def check_arity(n, sig):
- num_pos_only, func, keyword_exclude, sigspec = sig
- if keyword_exclude or num_pos_only > n:
- return False
- return is_arity(n, func, sigspec)
-
-
-def _is_arity(n, func):
- if func not in signatures:
- return None
- sigs = signatures[func]
- checks = [check_arity(n, sig) for sig in sigs]
- if all(checks):
- return True
- elif any(checks):
- return None
- return False
-
-
-def check_varargs(sig):
- num_pos_only, func, keyword_exclude, sigspec = sig
- return has_varargs(func, sigspec)
-
-
-def _has_varargs(func):
- if func not in signatures:
- return None
- sigs = signatures[func]
- checks = [check_varargs(sig) for sig in sigs]
- if all(checks):
- return True
- elif any(checks): # pragma: py2 no cover
- return None
- return False
-
-
-def check_keywords(sig):
- num_pos_only, func, keyword_exclude, sigspec = sig
- if keyword_exclude:
- return True
- return has_keywords(func, sigspec)
-
-
-def _has_keywords(func):
- if func not in signatures:
- return None
- sigs = signatures[func]
- checks = [check_keywords(sig) for sig in sigs]
- if all(checks):
- return True
- elif any(checks):
- return None
- return False
-
-
-def check_required_args(sig):
- num_pos_only, func, keyword_exclude, sigspec = sig
- return num_required_args(func, sigspec)
-
-
-def _num_required_args(func):
- if func not in signatures:
- return None
- sigs = signatures[func]
- vals = [check_required_args(sig) for sig in sigs]
- val = vals[0]
- if all(x == val for x in vals):
- return val
- return None
diff --git a/contrib/python/toolz/py2/toolz/compatibility.py b/contrib/python/toolz/py2/toolz/compatibility.py
deleted file mode 100644
index 51e3673fad..0000000000
--- a/contrib/python/toolz/py2/toolz/compatibility.py
+++ /dev/null
@@ -1,34 +0,0 @@
-import operator
-import sys
-PY3 = sys.version_info[0] > 2
-PY34 = sys.version_info[0] == 3 and sys.version_info[1] == 4
-PYPY = hasattr(sys, 'pypy_version_info')
-
-__all__ = ('map', 'filter', 'range', 'zip', 'reduce', 'zip_longest',
- 'iteritems', 'iterkeys', 'itervalues', 'filterfalse',
- 'PY3', 'PY34', 'PYPY')
-
-if PY3:
- map = map
- filter = filter
- range = range
- zip = zip
- from functools import reduce
- from itertools import zip_longest
- from itertools import filterfalse
- iteritems = operator.methodcaller('items')
- iterkeys = operator.methodcaller('keys')
- itervalues = operator.methodcaller('values')
- from collections.abc import Sequence
-else:
- range = xrange
- reduce = reduce
- from itertools import imap as map
- from itertools import ifilter as filter
- from itertools import ifilterfalse as filterfalse
- from itertools import izip as zip
- from itertools import izip_longest as zip_longest
- iteritems = operator.methodcaller('iteritems')
- iterkeys = operator.methodcaller('iterkeys')
- itervalues = operator.methodcaller('itervalues')
- from collections import Sequence
diff --git a/contrib/python/toolz/py2/toolz/curried/__init__.py b/contrib/python/toolz/py2/toolz/curried/__init__.py
deleted file mode 100644
index 356eddbd3b..0000000000
--- a/contrib/python/toolz/py2/toolz/curried/__init__.py
+++ /dev/null
@@ -1,103 +0,0 @@
-"""
-Alternate namespace for toolz such that all functions are curried
-
-Currying provides implicit partial evaluation of all functions
-
-Example:
-
- Get usually requires two arguments, an index and a collection
- >>> from toolz.curried import get
- >>> get(0, ('a', 'b'))
- 'a'
-
- When we use it in higher order functions we often want to pass a partially
- evaluated form
- >>> data = [(1, 2), (11, 22), (111, 222)]
- >>> list(map(lambda seq: get(0, seq), data))
- [1, 11, 111]
-
- The curried version allows simple expression of partial evaluation
- >>> list(map(get(0), data))
- [1, 11, 111]
-
-See Also:
- toolz.functoolz.curry
-"""
-import toolz
-from . import operator
-from toolz import (
- apply,
- comp,
- complement,
- compose,
- compose_left,
- concat,
- concatv,
- count,
- curry,
- diff,
- first,
- flip,
- frequencies,
- identity,
- interleave,
- isdistinct,
- isiterable,
- juxt,
- last,
- memoize,
- merge_sorted,
- peek,
- pipe,
- second,
- thread_first,
- thread_last,
-)
-from .exceptions import merge, merge_with
-
-accumulate = toolz.curry(toolz.accumulate)
-assoc = toolz.curry(toolz.assoc)
-assoc_in = toolz.curry(toolz.assoc_in)
-cons = toolz.curry(toolz.cons)
-countby = toolz.curry(toolz.countby)
-dissoc = toolz.curry(toolz.dissoc)
-do = toolz.curry(toolz.do)
-drop = toolz.curry(toolz.drop)
-excepts = toolz.curry(toolz.excepts)
-filter = toolz.curry(toolz.filter)
-get = toolz.curry(toolz.get)
-get_in = toolz.curry(toolz.get_in)
-groupby = toolz.curry(toolz.groupby)
-interpose = toolz.curry(toolz.interpose)
-itemfilter = toolz.curry(toolz.itemfilter)
-itemmap = toolz.curry(toolz.itemmap)
-iterate = toolz.curry(toolz.iterate)
-join = toolz.curry(toolz.join)
-keyfilter = toolz.curry(toolz.keyfilter)
-keymap = toolz.curry(toolz.keymap)
-map = toolz.curry(toolz.map)
-mapcat = toolz.curry(toolz.mapcat)
-nth = toolz.curry(toolz.nth)
-partial = toolz.curry(toolz.partial)
-partition = toolz.curry(toolz.partition)
-partition_all = toolz.curry(toolz.partition_all)
-partitionby = toolz.curry(toolz.partitionby)
-peekn = toolz.curry(toolz.peekn)
-pluck = toolz.curry(toolz.pluck)
-random_sample = toolz.curry(toolz.random_sample)
-reduce = toolz.curry(toolz.reduce)
-reduceby = toolz.curry(toolz.reduceby)
-remove = toolz.curry(toolz.remove)
-sliding_window = toolz.curry(toolz.sliding_window)
-sorted = toolz.curry(toolz.sorted)
-tail = toolz.curry(toolz.tail)
-take = toolz.curry(toolz.take)
-take_nth = toolz.curry(toolz.take_nth)
-topk = toolz.curry(toolz.topk)
-unique = toolz.curry(toolz.unique)
-update_in = toolz.curry(toolz.update_in)
-valfilter = toolz.curry(toolz.valfilter)
-valmap = toolz.curry(toolz.valmap)
-
-del exceptions
-del toolz
diff --git a/contrib/python/toolz/py2/toolz/curried/exceptions.py b/contrib/python/toolz/py2/toolz/curried/exceptions.py
deleted file mode 100644
index 75a52bbbf2..0000000000
--- a/contrib/python/toolz/py2/toolz/curried/exceptions.py
+++ /dev/null
@@ -1,18 +0,0 @@
-import toolz
-
-
-__all__ = ['merge_with', 'merge']
-
-
-@toolz.curry
-def merge_with(func, d, *dicts, **kwargs):
- return toolz.merge_with(func, d, *dicts, **kwargs)
-
-
-@toolz.curry
-def merge(d, *dicts, **kwargs):
- return toolz.merge(d, *dicts, **kwargs)
-
-
-merge_with.__doc__ = toolz.merge_with.__doc__
-merge.__doc__ = toolz.merge.__doc__
diff --git a/contrib/python/toolz/py2/toolz/curried/operator.py b/contrib/python/toolz/py2/toolz/curried/operator.py
deleted file mode 100644
index 8bc9e52317..0000000000
--- a/contrib/python/toolz/py2/toolz/curried/operator.py
+++ /dev/null
@@ -1,23 +0,0 @@
-from __future__ import absolute_import
-
-import operator
-
-from toolz.functoolz import curry, num_required_args, has_keywords
-
-
-def should_curry(f):
- num = num_required_args(f)
- return num is None or num > 1 or num == 1 and has_keywords(f) is not False
-
-
-locals().update(
- {name: curry(f) if should_curry(f) else f
- for name, f in vars(operator).items() if callable(f)},
-)
-
-# Clean up the namespace.
-del curry
-del num_required_args
-del has_keywords
-del operator
-del should_curry
diff --git a/contrib/python/toolz/py2/toolz/dicttoolz.py b/contrib/python/toolz/py2/toolz/dicttoolz.py
deleted file mode 100644
index 91bff23cef..0000000000
--- a/contrib/python/toolz/py2/toolz/dicttoolz.py
+++ /dev/null
@@ -1,337 +0,0 @@
-import operator
-from toolz.compatibility import (map, zip, iteritems, iterkeys, itervalues,
- reduce)
-
-__all__ = ('merge', 'merge_with', 'valmap', 'keymap', 'itemmap',
- 'valfilter', 'keyfilter', 'itemfilter',
- 'assoc', 'dissoc', 'assoc_in', 'update_in', 'get_in')
-
-
-def _get_factory(f, kwargs):
- factory = kwargs.pop('factory', dict)
- if kwargs:
- raise TypeError("{}() got an unexpected keyword argument "
- "'{}'".format(f.__name__, kwargs.popitem()[0]))
- return factory
-
-
-def merge(*dicts, **kwargs):
- """ Merge a collection of dictionaries
-
- >>> merge({1: 'one'}, {2: 'two'})
- {1: 'one', 2: 'two'}
-
- Later dictionaries have precedence
-
- >>> merge({1: 2, 3: 4}, {3: 3, 4: 4})
- {1: 2, 3: 3, 4: 4}
-
- See Also:
- merge_with
- """
- if len(dicts) == 1 and not isinstance(dicts[0], dict):
- dicts = dicts[0]
- factory = _get_factory(merge, kwargs)
-
- rv = factory()
- for d in dicts:
- rv.update(d)
- return rv
-
-
-def merge_with(func, *dicts, **kwargs):
- """ Merge dictionaries and apply function to combined values
-
- A key may occur in more than one dict, and all values mapped from the key
- will be passed to the function as a list, such as func([val1, val2, ...]).
-
- >>> merge_with(sum, {1: 1, 2: 2}, {1: 10, 2: 20})
- {1: 11, 2: 22}
-
- >>> merge_with(first, {1: 1, 2: 2}, {2: 20, 3: 30}) # doctest: +SKIP
- {1: 1, 2: 2, 3: 30}
-
- See Also:
- merge
- """
- if len(dicts) == 1 and not isinstance(dicts[0], dict):
- dicts = dicts[0]
- factory = _get_factory(merge_with, kwargs)
-
- result = factory()
- for d in dicts:
- for k, v in iteritems(d):
- if k not in result:
- result[k] = [v]
- else:
- result[k].append(v)
- return valmap(func, result, factory)
-
-
-def valmap(func, d, factory=dict):
- """ Apply function to values of dictionary
-
- >>> bills = {"Alice": [20, 15, 30], "Bob": [10, 35]}
- >>> valmap(sum, bills) # doctest: +SKIP
- {'Alice': 65, 'Bob': 45}
-
- See Also:
- keymap
- itemmap
- """
- rv = factory()
- rv.update(zip(iterkeys(d), map(func, itervalues(d))))
- return rv
-
-
-def keymap(func, d, factory=dict):
- """ Apply function to keys of dictionary
-
- >>> bills = {"Alice": [20, 15, 30], "Bob": [10, 35]}
- >>> keymap(str.lower, bills) # doctest: +SKIP
- {'alice': [20, 15, 30], 'bob': [10, 35]}
-
- See Also:
- valmap
- itemmap
- """
- rv = factory()
- rv.update(zip(map(func, iterkeys(d)), itervalues(d)))
- return rv
-
-
-def itemmap(func, d, factory=dict):
- """ Apply function to items of dictionary
-
- >>> accountids = {"Alice": 10, "Bob": 20}
- >>> itemmap(reversed, accountids) # doctest: +SKIP
- {10: "Alice", 20: "Bob"}
-
- See Also:
- keymap
- valmap
- """
- rv = factory()
- rv.update(map(func, iteritems(d)))
- return rv
-
-
-def valfilter(predicate, d, factory=dict):
- """ Filter items in dictionary by value
-
- >>> iseven = lambda x: x % 2 == 0
- >>> d = {1: 2, 2: 3, 3: 4, 4: 5}
- >>> valfilter(iseven, d)
- {1: 2, 3: 4}
-
- See Also:
- keyfilter
- itemfilter
- valmap
- """
- rv = factory()
- for k, v in iteritems(d):
- if predicate(v):
- rv[k] = v
- return rv
-
-
-def keyfilter(predicate, d, factory=dict):
- """ Filter items in dictionary by key
-
- >>> iseven = lambda x: x % 2 == 0
- >>> d = {1: 2, 2: 3, 3: 4, 4: 5}
- >>> keyfilter(iseven, d)
- {2: 3, 4: 5}
-
- See Also:
- valfilter
- itemfilter
- keymap
- """
- rv = factory()
- for k, v in iteritems(d):
- if predicate(k):
- rv[k] = v
- return rv
-
-
-def itemfilter(predicate, d, factory=dict):
- """ Filter items in dictionary by item
-
- >>> def isvalid(item):
- ... k, v = item
- ... return k % 2 == 0 and v < 4
-
- >>> d = {1: 2, 2: 3, 3: 4, 4: 5}
- >>> itemfilter(isvalid, d)
- {2: 3}
-
- See Also:
- keyfilter
- valfilter
- itemmap
- """
- rv = factory()
- for item in iteritems(d):
- if predicate(item):
- k, v = item
- rv[k] = v
- return rv
-
-
-def assoc(d, key, value, factory=dict):
- """ Return a new dict with new key value pair
-
- New dict has d[key] set to value. Does not modify the initial dictionary.
-
- >>> assoc({'x': 1}, 'x', 2)
- {'x': 2}
- >>> assoc({'x': 1}, 'y', 3) # doctest: +SKIP
- {'x': 1, 'y': 3}
- """
- d2 = factory()
- d2.update(d)
- d2[key] = value
- return d2
-
-
-def dissoc(d, *keys, **kwargs):
- """ Return a new dict with the given key(s) removed.
-
- New dict has d[key] deleted for each supplied key.
- Does not modify the initial dictionary.
-
- >>> dissoc({'x': 1, 'y': 2}, 'y')
- {'x': 1}
- >>> dissoc({'x': 1, 'y': 2}, 'y', 'x')
- {}
- >>> dissoc({'x': 1}, 'y') # Ignores missing keys
- {'x': 1}
- """
- factory = _get_factory(dissoc, kwargs)
- d2 = factory()
-
- if len(keys) < len(d) * .6:
- d2.update(d)
- for key in keys:
- if key in d2:
- del d2[key]
- else:
- remaining = set(d)
- remaining.difference_update(keys)
- for k in remaining:
- d2[k] = d[k]
- return d2
-
-
-def assoc_in(d, keys, value, factory=dict):
- """ Return a new dict with new, potentially nested, key value pair
-
- >>> purchase = {'name': 'Alice',
- ... 'order': {'items': ['Apple', 'Orange'],
- ... 'costs': [0.50, 1.25]},
- ... 'credit card': '5555-1234-1234-1234'}
- >>> assoc_in(purchase, ['order', 'costs'], [0.25, 1.00]) # doctest: +SKIP
- {'credit card': '5555-1234-1234-1234',
- 'name': 'Alice',
- 'order': {'costs': [0.25, 1.00], 'items': ['Apple', 'Orange']}}
- """
- return update_in(d, keys, lambda x: value, value, factory)
-
-
-def update_in(d, keys, func, default=None, factory=dict):
- """ Update value in a (potentially) nested dictionary
-
- inputs:
- d - dictionary on which to operate
- keys - list or tuple giving the location of the value to be changed in d
- func - function to operate on that value
-
- If keys == [k0,..,kX] and d[k0]..[kX] == v, update_in returns a copy of the
- original dictionary with v replaced by func(v), but does not mutate the
- original dictionary.
-
- If k0 is not a key in d, update_in creates nested dictionaries to the depth
- specified by the keys, with the innermost value set to func(default).
-
- >>> inc = lambda x: x + 1
- >>> update_in({'a': 0}, ['a'], inc)
- {'a': 1}
-
- >>> transaction = {'name': 'Alice',
- ... 'purchase': {'items': ['Apple', 'Orange'],
- ... 'costs': [0.50, 1.25]},
- ... 'credit card': '5555-1234-1234-1234'}
- >>> update_in(transaction, ['purchase', 'costs'], sum) # doctest: +SKIP
- {'credit card': '5555-1234-1234-1234',
- 'name': 'Alice',
- 'purchase': {'costs': 1.75, 'items': ['Apple', 'Orange']}}
-
- >>> # updating a value when k0 is not in d
- >>> update_in({}, [1, 2, 3], str, default="bar")
- {1: {2: {3: 'bar'}}}
- >>> update_in({1: 'foo'}, [2, 3, 4], inc, 0)
- {1: 'foo', 2: {3: {4: 1}}}
- """
- ks = iter(keys)
- k = next(ks)
-
- rv = inner = factory()
- rv.update(d)
-
- for key in ks:
- if k in d:
- d = d[k]
- dtemp = factory()
- dtemp.update(d)
- else:
- d = dtemp = factory()
-
- inner[k] = inner = dtemp
- k = key
-
- if k in d:
- inner[k] = func(d[k])
- else:
- inner[k] = func(default)
- return rv
-
-
-def get_in(keys, coll, default=None, no_default=False):
- """ Returns coll[i0][i1]...[iX] where [i0, i1, ..., iX]==keys.
-
- If coll[i0][i1]...[iX] cannot be found, returns ``default``, unless
- ``no_default`` is specified, then it raises KeyError or IndexError.
-
- ``get_in`` is a generalization of ``operator.getitem`` for nested data
- structures such as dictionaries and lists.
-
- >>> transaction = {'name': 'Alice',
- ... 'purchase': {'items': ['Apple', 'Orange'],
- ... 'costs': [0.50, 1.25]},
- ... 'credit card': '5555-1234-1234-1234'}
- >>> get_in(['purchase', 'items', 0], transaction)
- 'Apple'
- >>> get_in(['name'], transaction)
- 'Alice'
- >>> get_in(['purchase', 'total'], transaction)
- >>> get_in(['purchase', 'items', 'apple'], transaction)
- >>> get_in(['purchase', 'items', 10], transaction)
- >>> get_in(['purchase', 'total'], transaction, 0)
- 0
- >>> get_in(['y'], {}, no_default=True)
- Traceback (most recent call last):
- ...
- KeyError: 'y'
-
- See Also:
- itertoolz.get
- operator.getitem
- """
- try:
- return reduce(operator.getitem, keys, coll)
- except (KeyError, IndexError, TypeError):
- if no_default:
- raise
- return default
diff --git a/contrib/python/toolz/py2/toolz/functoolz.py b/contrib/python/toolz/py2/toolz/functoolz.py
deleted file mode 100644
index 01d3857a19..0000000000
--- a/contrib/python/toolz/py2/toolz/functoolz.py
+++ /dev/null
@@ -1,1152 +0,0 @@
-from functools import reduce, partial
-import inspect
-import operator
-from operator import attrgetter
-from importlib import import_module
-from textwrap import dedent
-from types import MethodType
-
-from .compatibility import PY3, PY34, PYPY
-from .utils import no_default
-
-
-__all__ = ('identity', 'apply', 'thread_first', 'thread_last', 'memoize',
- 'compose', 'compose_left', 'pipe', 'complement', 'juxt', 'do',
- 'curry', 'flip', 'excepts')
-
-
-def identity(x):
- """ Identity function. Return x
-
- >>> identity(3)
- 3
- """
- return x
-
-
-def apply(*func_and_args, **kwargs):
- """ Applies a function and returns the results
-
- >>> def double(x): return 2*x
- >>> def inc(x): return x + 1
- >>> apply(double, 5)
- 10
-
- >>> tuple(map(apply, [double, inc, double], [10, 500, 8000]))
- (20, 501, 16000)
- """
- if not func_and_args:
- raise TypeError('func argument is required')
- func, args = func_and_args[0], func_and_args[1:]
- return func(*args, **kwargs)
-
-
-def thread_first(val, *forms):
- """ Thread value through a sequence of functions/forms
-
- >>> def double(x): return 2*x
- >>> def inc(x): return x + 1
- >>> thread_first(1, inc, double)
- 4
-
- If the function expects more than one input you can specify those inputs
- in a tuple. The value is used as the first input.
-
- >>> def add(x, y): return x + y
- >>> def pow(x, y): return x**y
- >>> thread_first(1, (add, 4), (pow, 2)) # pow(add(1, 4), 2)
- 25
-
- So in general
- thread_first(x, f, (g, y, z))
- expands to
- g(f(x), y, z)
-
- See Also:
- thread_last
- """
- def evalform_front(val, form):
- if callable(form):
- return form(val)
- if isinstance(form, tuple):
- func, args = form[0], form[1:]
- args = (val,) + args
- return func(*args)
- return reduce(evalform_front, forms, val)
-
-
-def thread_last(val, *forms):
- """ Thread value through a sequence of functions/forms
-
- >>> def double(x): return 2*x
- >>> def inc(x): return x + 1
- >>> thread_last(1, inc, double)
- 4
-
- If the function expects more than one input you can specify those inputs
- in a tuple. The value is used as the last input.
-
- >>> def add(x, y): return x + y
- >>> def pow(x, y): return x**y
- >>> thread_last(1, (add, 4), (pow, 2)) # pow(2, add(4, 1))
- 32
-
- So in general
- thread_last(x, f, (g, y, z))
- expands to
- g(y, z, f(x))
-
- >>> def iseven(x):
- ... return x % 2 == 0
- >>> list(thread_last([1, 2, 3], (map, inc), (filter, iseven)))
- [2, 4]
-
- See Also:
- thread_first
- """
- def evalform_back(val, form):
- if callable(form):
- return form(val)
- if isinstance(form, tuple):
- func, args = form[0], form[1:]
- args = args + (val,)
- return func(*args)
- return reduce(evalform_back, forms, val)
-
-
-def instanceproperty(fget=None, fset=None, fdel=None, doc=None, classval=None):
- """ Like @property, but returns ``classval`` when used as a class attribute
-
- >>> class MyClass(object):
- ... '''The class docstring'''
- ... @instanceproperty(classval=__doc__)
- ... def __doc__(self):
- ... return 'An object docstring'
- ... @instanceproperty
- ... def val(self):
- ... return 42
- ...
- >>> MyClass.__doc__
- 'The class docstring'
- >>> MyClass.val is None
- True
- >>> obj = MyClass()
- >>> obj.__doc__
- 'An object docstring'
- >>> obj.val
- 42
- """
- if fget is None:
- return partial(instanceproperty, fset=fset, fdel=fdel, doc=doc,
- classval=classval)
- return InstanceProperty(fget=fget, fset=fset, fdel=fdel, doc=doc,
- classval=classval)
-
-
-class InstanceProperty(property):
- """ Like @property, but returns ``classval`` when used as a class attribute
-
- Should not be used directly. Use ``instanceproperty`` instead.
- """
- def __init__(self, fget=None, fset=None, fdel=None, doc=None,
- classval=None):
- self.classval = classval
- property.__init__(self, fget=fget, fset=fset, fdel=fdel, doc=doc)
-
- def __get__(self, obj, type=None):
- if obj is None:
- return self.classval
- return property.__get__(self, obj, type)
-
- def __reduce__(self):
- state = (self.fget, self.fset, self.fdel, self.__doc__, self.classval)
- return InstanceProperty, state
-
-
-class curry(object):
- """ Curry a callable function
-
- Enables partial application of arguments through calling a function with an
- incomplete set of arguments.
-
- >>> def mul(x, y):
- ... return x * y
- >>> mul = curry(mul)
-
- >>> double = mul(2)
- >>> double(10)
- 20
-
- Also supports keyword arguments
-
- >>> @curry # Can use curry as a decorator
- ... def f(x, y, a=10):
- ... return a * (x + y)
-
- >>> add = f(a=1)
- >>> add(2, 3)
- 5
-
- See Also:
- toolz.curried - namespace of curried functions
- https://toolz.readthedocs.io/en/latest/curry.html
- """
- def __init__(self, *args, **kwargs):
- if not args:
- raise TypeError('__init__() takes at least 2 arguments (1 given)')
- func, args = args[0], args[1:]
- if not callable(func):
- raise TypeError("Input must be callable")
-
- # curry- or functools.partial-like object? Unpack and merge arguments
- if (
- hasattr(func, 'func')
- and hasattr(func, 'args')
- and hasattr(func, 'keywords')
- and isinstance(func.args, tuple)
- ):
- _kwargs = {}
- if func.keywords:
- _kwargs.update(func.keywords)
- _kwargs.update(kwargs)
- kwargs = _kwargs
- args = func.args + args
- func = func.func
-
- if kwargs:
- self._partial = partial(func, *args, **kwargs)
- else:
- self._partial = partial(func, *args)
-
- self.__doc__ = getattr(func, '__doc__', None)
- self.__name__ = getattr(func, '__name__', '<curry>')
- self.__module__ = getattr(func, '__module__', None)
- self.__qualname__ = getattr(func, '__qualname__', None)
- self._sigspec = None
- self._has_unknown_args = None
-
- @instanceproperty
- def func(self):
- return self._partial.func
-
- if PY3: # pragma: py2 no cover
- @instanceproperty
- def __signature__(self):
- sig = inspect.signature(self.func)
- args = self.args or ()
- keywords = self.keywords or {}
- if is_partial_args(self.func, args, keywords, sig) is False:
- raise TypeError('curry object has incorrect arguments')
-
- params = list(sig.parameters.values())
- skip = 0
- for param in params[:len(args)]:
- if param.kind == param.VAR_POSITIONAL:
- break
- skip += 1
-
- kwonly = False
- newparams = []
- for param in params[skip:]:
- kind = param.kind
- default = param.default
- if kind == param.VAR_KEYWORD:
- pass
- elif kind == param.VAR_POSITIONAL:
- if kwonly:
- continue
- elif param.name in keywords:
- default = keywords[param.name]
- kind = param.KEYWORD_ONLY
- kwonly = True
- else:
- if kwonly:
- kind = param.KEYWORD_ONLY
- if default is param.empty:
- default = no_default
- newparams.append(param.replace(default=default, kind=kind))
-
- return sig.replace(parameters=newparams)
-
- @instanceproperty
- def args(self):
- return self._partial.args
-
- @instanceproperty
- def keywords(self):
- return self._partial.keywords
-
- @instanceproperty
- def func_name(self):
- return self.__name__
-
- def __str__(self):
- return str(self.func)
-
- def __repr__(self):
- return repr(self.func)
-
- def __hash__(self):
- return hash((self.func, self.args,
- frozenset(self.keywords.items()) if self.keywords
- else None))
-
- def __eq__(self, other):
- return (isinstance(other, curry) and self.func == other.func and
- self.args == other.args and self.keywords == other.keywords)
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- def __call__(self, *args, **kwargs):
- try:
- return self._partial(*args, **kwargs)
- except TypeError as exc:
- if self._should_curry(args, kwargs, exc):
- return self.bind(*args, **kwargs)
- raise
-
- def _should_curry(self, args, kwargs, exc=None):
- func = self.func
- args = self.args + args
- if self.keywords:
- kwargs = dict(self.keywords, **kwargs)
- if self._sigspec is None:
- sigspec = self._sigspec = _sigs.signature_or_spec(func)
- self._has_unknown_args = has_varargs(func, sigspec) is not False
- else:
- sigspec = self._sigspec
-
- if is_partial_args(func, args, kwargs, sigspec) is False:
- # Nothing can make the call valid
- return False
- elif self._has_unknown_args:
- # The call may be valid and raised a TypeError, but we curry
- # anyway because the function may have `*args`. This is useful
- # for decorators with signature `func(*args, **kwargs)`.
- return True
- elif not is_valid_args(func, args, kwargs, sigspec):
- # Adding more arguments may make the call valid
- return True
- else:
- # There was a genuine TypeError
- return False
-
- def bind(self, *args, **kwargs):
- return type(self)(self, *args, **kwargs)
-
- def call(self, *args, **kwargs):
- return self._partial(*args, **kwargs)
-
- def __get__(self, instance, owner):
- if instance is None:
- return self
- return curry(self, instance)
-
- def __reduce__(self):
- func = self.func
- modname = getattr(func, '__module__', None)
- qualname = getattr(func, '__qualname__', None)
- if qualname is None: # pragma: py3 no cover
- qualname = getattr(func, '__name__', None)
- is_decorated = None
- if modname and qualname:
- attrs = []
- obj = import_module(modname)
- for attr in qualname.split('.'):
- if isinstance(obj, curry): # pragma: py2 no cover
- attrs.append('func')
- obj = obj.func
- obj = getattr(obj, attr, None)
- if obj is None:
- break
- attrs.append(attr)
- if isinstance(obj, curry) and obj.func is func:
- is_decorated = obj is self
- qualname = '.'.join(attrs)
- func = '%s:%s' % (modname, qualname)
-
- # functools.partial objects can't be pickled
- userdict = tuple((k, v) for k, v in self.__dict__.items()
- if k not in ('_partial', '_sigspec'))
- state = (type(self), func, self.args, self.keywords, userdict,
- is_decorated)
- return _restore_curry, state
-
-
-def _restore_curry(cls, func, args, kwargs, userdict, is_decorated):
- if isinstance(func, str):
- modname, qualname = func.rsplit(':', 1)
- obj = import_module(modname)
- for attr in qualname.split('.'):
- obj = getattr(obj, attr)
- if is_decorated:
- return obj
- func = obj.func
- obj = cls(func, *args, **(kwargs or {}))
- obj.__dict__.update(userdict)
- return obj
-
-
-@curry
-def memoize(func, cache=None, key=None):
- """ Cache a function's result for speedy future evaluation
-
- Considerations:
- Trades memory for speed.
- Only use on pure functions.
-
- >>> def add(x, y): return x + y
- >>> add = memoize(add)
-
- Or use as a decorator
-
- >>> @memoize
- ... def add(x, y):
- ... return x + y
-
- Use the ``cache`` keyword to provide a dict-like object as an initial cache
-
- >>> @memoize(cache={(1, 2): 3})
- ... def add(x, y):
- ... return x + y
-
- Note that the above works as a decorator because ``memoize`` is curried.
-
- It is also possible to provide a ``key(args, kwargs)`` function that
- calculates keys used for the cache, which receives an ``args`` tuple and
- ``kwargs`` dict as input, and must return a hashable value. However,
- the default key function should be sufficient most of the time.
-
- >>> # Use key function that ignores extraneous keyword arguments
- >>> @memoize(key=lambda args, kwargs: args)
- ... def add(x, y, verbose=False):
- ... if verbose:
- ... print('Calculating %s + %s' % (x, y))
- ... return x + y
- """
- if cache is None:
- cache = {}
-
- try:
- may_have_kwargs = has_keywords(func) is not False
- # Is unary function (single arg, no variadic argument or keywords)?
- is_unary = is_arity(1, func)
- except TypeError: # pragma: no cover
- may_have_kwargs = True
- is_unary = False
-
- if key is None:
- if is_unary:
- def key(args, kwargs):
- return args[0]
- elif may_have_kwargs:
- def key(args, kwargs):
- return (
- args or None,
- frozenset(kwargs.items()) if kwargs else None,
- )
- else:
- def key(args, kwargs):
- return args
-
- def memof(*args, **kwargs):
- k = key(args, kwargs)
- try:
- return cache[k]
- except TypeError:
- raise TypeError("Arguments to memoized function must be hashable")
- except KeyError:
- cache[k] = result = func(*args, **kwargs)
- return result
-
- try:
- memof.__name__ = func.__name__
- except AttributeError:
- pass
- memof.__doc__ = func.__doc__
- memof.__wrapped__ = func
- return memof
-
-
-class Compose(object):
- """ A composition of functions
-
- See Also:
- compose
- """
- __slots__ = 'first', 'funcs'
-
- def __init__(self, funcs):
- funcs = tuple(reversed(funcs))
- self.first = funcs[0]
- self.funcs = funcs[1:]
-
- def __call__(self, *args, **kwargs):
- ret = self.first(*args, **kwargs)
- for f in self.funcs:
- ret = f(ret)
- return ret
-
- def __getstate__(self):
- return self.first, self.funcs
-
- def __setstate__(self, state):
- self.first, self.funcs = state
-
- @instanceproperty(classval=__doc__)
- def __doc__(self):
- def composed_doc(*fs):
- """Generate a docstring for the composition of fs.
- """
- if not fs:
- # Argument name for the docstring.
- return '*args, **kwargs'
-
- return '{f}({g})'.format(f=fs[0].__name__, g=composed_doc(*fs[1:]))
-
- try:
- return (
- 'lambda *args, **kwargs: ' +
- composed_doc(*reversed((self.first,) + self.funcs))
- )
- except AttributeError:
- # One of our callables does not have a `__name__`, whatever.
- return 'A composition of functions'
-
- @property
- def __name__(self):
- try:
- return '_of_'.join(
- (f.__name__ for f in reversed((self.first,) + self.funcs))
- )
- except AttributeError:
- return type(self).__name__
-
- def __repr__(self):
- return '{.__class__.__name__}{!r}'.format(
- self, tuple(reversed((self.first, ) + self.funcs)))
-
- def __eq__(self, other):
- if isinstance(other, Compose):
- return other.first == self.first and other.funcs == self.funcs
- return NotImplemented
-
- def __ne__(self, other):
- equality = self.__eq__(other)
- return NotImplemented if equality is NotImplemented else not equality
-
- def __hash__(self):
- return hash(self.first) ^ hash(self.funcs)
-
- # Mimic the descriptor behavior of python functions.
- # i.e. let Compose be called as a method when bound to a class.
- if PY3: # pragma: py2 no cover
- # adapted from
- # docs.python.org/3/howto/descriptor.html#functions-and-methods
- def __get__(self, obj, objtype=None):
- return self if obj is None else MethodType(self, obj)
- else: # pragma: py3 no cover
- # adapted from
- # docs.python.org/2/howto/descriptor.html#functions-and-methods
- def __get__(self, obj, objtype=None):
- return self if obj is None else MethodType(self, obj, objtype)
-
- # introspection with Signature is only possible from py3.3+
- if PY3: # pragma: py2 no cover
- @instanceproperty
- def __signature__(self):
- base = inspect.signature(self.first)
- last = inspect.signature(self.funcs[-1])
- return base.replace(return_annotation=last.return_annotation)
-
- __wrapped__ = instanceproperty(attrgetter('first'))
-
-
-def compose(*funcs):
- """ Compose functions to operate in series.
-
- Returns a function that applies other functions in sequence.
-
- Functions are applied from right to left so that
- ``compose(f, g, h)(x, y)`` is the same as ``f(g(h(x, y)))``.
-
- If no arguments are provided, the identity function (f(x) = x) is returned.
-
- >>> inc = lambda i: i + 1
- >>> compose(str, inc)(3)
- '4'
-
- See Also:
- compose_left
- pipe
- """
- if not funcs:
- return identity
- if len(funcs) == 1:
- return funcs[0]
- else:
- return Compose(funcs)
-
-
-def compose_left(*funcs):
- """ Compose functions to operate in series.
-
- Returns a function that applies other functions in sequence.
-
- Functions are applied from left to right so that
- ``compose_left(f, g, h)(x, y)`` is the same as ``h(g(f(x, y)))``.
-
- If no arguments are provided, the identity function (f(x) = x) is returned.
-
- >>> inc = lambda i: i + 1
- >>> compose_left(inc, str)(3)
- '4'
-
- See Also:
- compose
- pipe
- """
- return compose(*reversed(funcs))
-
-
-def pipe(data, *funcs):
- """ Pipe a value through a sequence of functions
-
- I.e. ``pipe(data, f, g, h)`` is equivalent to ``h(g(f(data)))``
-
- We think of the value as progressing through a pipe of several
- transformations, much like pipes in UNIX
-
- ``$ cat data | f | g | h``
-
- >>> double = lambda i: 2 * i
- >>> pipe(3, double, str)
- '6'
-
- See Also:
- compose
- compose_left
- thread_first
- thread_last
- """
- for func in funcs:
- data = func(data)
- return data
-
-
-def complement(func):
- """ Convert a predicate function to its logical complement.
-
- In other words, return a function that, for inputs that normally
- yield True, yields False, and vice-versa.
-
- >>> def iseven(n): return n % 2 == 0
- >>> isodd = complement(iseven)
- >>> iseven(2)
- True
- >>> isodd(2)
- False
- """
- return compose(operator.not_, func)
-
-
-class juxt(object):
- """ Creates a function that calls several functions with the same arguments
-
- Takes several functions and returns a function that applies its arguments
- to each of those functions then returns a tuple of the results.
-
- Name comes from juxtaposition: the fact of two things being seen or placed
- close together with contrasting effect.
-
- >>> inc = lambda x: x + 1
- >>> double = lambda x: x * 2
- >>> juxt(inc, double)(10)
- (11, 20)
- >>> juxt([inc, double])(10)
- (11, 20)
- """
- __slots__ = ['funcs']
-
- def __init__(self, *funcs):
- if len(funcs) == 1 and not callable(funcs[0]):
- funcs = funcs[0]
- self.funcs = tuple(funcs)
-
- def __call__(self, *args, **kwargs):
- return tuple(func(*args, **kwargs) for func in self.funcs)
-
- def __getstate__(self):
- return self.funcs
-
- def __setstate__(self, state):
- self.funcs = state
-
-
-def do(func, x):
- """ Runs ``func`` on ``x``, returns ``x``
-
- Because the results of ``func`` are not returned, only the side
- effects of ``func`` are relevant.
-
- Logging functions can be made by composing ``do`` with a storage function
- like ``list.append`` or ``file.write``
-
- >>> from toolz import compose
- >>> from toolz.curried import do
-
- >>> log = []
- >>> inc = lambda x: x + 1
- >>> inc = compose(inc, do(log.append))
- >>> inc(1)
- 2
- >>> inc(11)
- 12
- >>> log
- [1, 11]
- """
- func(x)
- return x
-
-
-@curry
-def flip(func, a, b):
- """ Call the function call with the arguments flipped
-
- This function is curried.
-
- >>> def div(a, b):
- ... return a // b
- ...
- >>> flip(div, 2, 6)
- 3
- >>> div_by_two = flip(div, 2)
- >>> div_by_two(4)
- 2
-
- This is particularly useful for built in functions and functions defined
- in C extensions that accept positional only arguments. For example:
- isinstance, issubclass.
-
- >>> data = [1, 'a', 'b', 2, 1.5, object(), 3]
- >>> only_ints = list(filter(flip(isinstance, int), data))
- >>> only_ints
- [1, 2, 3]
- """
- return func(b, a)
-
-
-def return_none(exc):
- """ Returns None.
- """
- return None
-
-
-class excepts(object):
- """A wrapper around a function to catch exceptions and
- dispatch to a handler.
-
- This is like a functional try/except block, in the same way that
- ifexprs are functional if/else blocks.
-
- Examples
- --------
- >>> excepting = excepts(
- ... ValueError,
- ... lambda a: [1, 2].index(a),
- ... lambda _: -1,
- ... )
- >>> excepting(1)
- 0
- >>> excepting(3)
- -1
-
- Multiple exceptions and default except clause.
- >>> excepting = excepts((IndexError, KeyError), lambda a: a[0])
- >>> excepting([])
- >>> excepting([1])
- 1
- >>> excepting({})
- >>> excepting({0: 1})
- 1
- """
- def __init__(self, exc, func, handler=return_none):
- self.exc = exc
- self.func = func
- self.handler = handler
-
- def __call__(self, *args, **kwargs):
- try:
- return self.func(*args, **kwargs)
- except self.exc as e:
- return self.handler(e)
-
- @instanceproperty(classval=__doc__)
- def __doc__(self):
- exc = self.exc
- try:
- if isinstance(exc, tuple):
- exc_name = '(%s)' % ', '.join(
- map(attrgetter('__name__'), exc),
- )
- else:
- exc_name = exc.__name__
-
- return dedent(
- """\
- A wrapper around {inst.func.__name__!r} that will except:
- {exc}
- and handle any exceptions with {inst.handler.__name__!r}.
-
- Docs for {inst.func.__name__!r}:
- {inst.func.__doc__}
-
- Docs for {inst.handler.__name__!r}:
- {inst.handler.__doc__}
- """
- ).format(
- inst=self,
- exc=exc_name,
- )
- except AttributeError:
- return type(self).__doc__
-
- @property
- def __name__(self):
- exc = self.exc
- try:
- if isinstance(exc, tuple):
- exc_name = '_or_'.join(map(attrgetter('__name__'), exc))
- else:
- exc_name = exc.__name__
- return '%s_excepting_%s' % (self.func.__name__, exc_name)
- except AttributeError:
- return 'excepting'
-
-
-if PY3: # pragma: py2 no cover
- def _check_sigspec(sigspec, func, builtin_func, *builtin_args):
- if sigspec is None:
- try:
- sigspec = inspect.signature(func)
- except (ValueError, TypeError) as e:
- sigspec = e
- if isinstance(sigspec, ValueError):
- return None, builtin_func(*builtin_args)
- elif not isinstance(sigspec, inspect.Signature):
- if (
- func in _sigs.signatures
- and ((
- hasattr(func, '__signature__')
- and hasattr(func.__signature__, '__get__')
- ))
- ): # pragma: no cover (not covered in Python 3.4)
- val = builtin_func(*builtin_args)
- return None, val
- return None, False
- return sigspec, None
-
-else: # pragma: py3 no cover
- def _check_sigspec(sigspec, func, builtin_func, *builtin_args):
- if sigspec is None:
- try:
- sigspec = inspect.getargspec(func)
- except TypeError as e:
- sigspec = e
- if isinstance(sigspec, TypeError):
- if not callable(func):
- return None, False
- return None, builtin_func(*builtin_args)
- return sigspec, None
-
-
-if PY34 or PYPY: # pragma: no cover
- _check_sigspec_orig = _check_sigspec
-
- def _check_sigspec(sigspec, func, builtin_func, *builtin_args):
- # Python 3.4 and PyPy may lie, so use our registry for builtins instead
- if func in _sigs.signatures:
- val = builtin_func(*builtin_args)
- return None, val
- return _check_sigspec_orig(sigspec, func, builtin_func, *builtin_args)
-
-_check_sigspec.__doc__ = """ \
-Private function to aid in introspection compatibly across Python versions.
-
-If a callable doesn't have a signature (Python 3) or an argspec (Python 2),
-the signature registry in toolz._signatures is used.
-"""
-
-if PY3: # pragma: py2 no cover
- def num_required_args(func, sigspec=None):
- sigspec, rv = _check_sigspec(sigspec, func, _sigs._num_required_args,
- func)
- if sigspec is None:
- return rv
- return sum(1 for p in sigspec.parameters.values()
- if p.default is p.empty
- and p.kind in (p.POSITIONAL_OR_KEYWORD, p.POSITIONAL_ONLY))
-
- def has_varargs(func, sigspec=None):
- sigspec, rv = _check_sigspec(sigspec, func, _sigs._has_varargs, func)
- if sigspec is None:
- return rv
- return any(p.kind == p.VAR_POSITIONAL
- for p in sigspec.parameters.values())
-
- def has_keywords(func, sigspec=None):
- sigspec, rv = _check_sigspec(sigspec, func, _sigs._has_keywords, func)
- if sigspec is None:
- return rv
- return any(p.default is not p.empty
- or p.kind in (p.KEYWORD_ONLY, p.VAR_KEYWORD)
- for p in sigspec.parameters.values())
-
- def is_valid_args(func, args, kwargs, sigspec=None):
- sigspec, rv = _check_sigspec(sigspec, func, _sigs._is_valid_args,
- func, args, kwargs)
- if sigspec is None:
- return rv
- try:
- sigspec.bind(*args, **kwargs)
- except TypeError:
- return False
- return True
-
- def is_partial_args(func, args, kwargs, sigspec=None):
- sigspec, rv = _check_sigspec(sigspec, func, _sigs._is_partial_args,
- func, args, kwargs)
- if sigspec is None:
- return rv
- try:
- sigspec.bind_partial(*args, **kwargs)
- except TypeError:
- return False
- return True
-
-else: # pragma: py3 no cover
- def num_required_args(func, sigspec=None):
- sigspec, rv = _check_sigspec(sigspec, func, _sigs._num_required_args,
- func)
- if sigspec is None:
- return rv
- num_defaults = len(sigspec.defaults) if sigspec.defaults else 0
- return len(sigspec.args) - num_defaults
-
- def has_varargs(func, sigspec=None):
- sigspec, rv = _check_sigspec(sigspec, func, _sigs._has_varargs, func)
- if sigspec is None:
- return rv
- return sigspec.varargs is not None
-
- def has_keywords(func, sigspec=None):
- sigspec, rv = _check_sigspec(sigspec, func, _sigs._has_keywords, func)
- if sigspec is None:
- return rv
- return sigspec.defaults is not None or sigspec.keywords is not None
-
- def is_valid_args(func, args, kwargs, sigspec=None):
- sigspec, rv = _check_sigspec(sigspec, func, _sigs._is_valid_args,
- func, args, kwargs)
- if sigspec is None:
- return rv
- spec = sigspec
- defaults = spec.defaults or ()
- num_pos = len(spec.args) - len(defaults)
- missing_pos = spec.args[len(args):num_pos]
- if any(arg not in kwargs for arg in missing_pos):
- return False
-
- if spec.varargs is None:
- num_extra_pos = max(0, len(args) - num_pos)
- else:
- num_extra_pos = 0
-
- kwargs = dict(kwargs)
-
- # Add missing keyword arguments (unless already included in `args`)
- missing_kwargs = spec.args[num_pos + num_extra_pos:]
- kwargs.update(zip(missing_kwargs, defaults[num_extra_pos:]))
-
- # Convert call to use positional arguments
- args = args + tuple(kwargs.pop(key) for key in spec.args[len(args):])
-
- if (
- not spec.keywords and kwargs
- or not spec.varargs and len(args) > len(spec.args)
- or set(spec.args[:len(args)]) & set(kwargs)
- ):
- return False
- else:
- return True
-
- def is_partial_args(func, args, kwargs, sigspec=None):
- sigspec, rv = _check_sigspec(sigspec, func, _sigs._is_partial_args,
- func, args, kwargs)
- if sigspec is None:
- return rv
- spec = sigspec
- defaults = spec.defaults or ()
- num_pos = len(spec.args) - len(defaults)
- if spec.varargs is None:
- num_extra_pos = max(0, len(args) - num_pos)
- else:
- num_extra_pos = 0
-
- kwargs = dict(kwargs)
-
- # Add missing keyword arguments (unless already included in `args`)
- missing_kwargs = spec.args[num_pos + num_extra_pos:]
- kwargs.update(zip(missing_kwargs, defaults[num_extra_pos:]))
-
- # Add missing position arguments as keywords (may already be in kwargs)
- missing_args = spec.args[len(args):num_pos + num_extra_pos]
- kwargs.update((x, None) for x in missing_args)
-
- # Convert call to use positional arguments
- args = args + tuple(kwargs.pop(key) for key in spec.args[len(args):])
-
- if (
- not spec.keywords and kwargs
- or not spec.varargs and len(args) > len(spec.args)
- or set(spec.args[:len(args)]) & set(kwargs)
- ):
- return False
- else:
- return True
-
-
-def is_arity(n, func, sigspec=None):
- """ Does a function have only n positional arguments?
-
- This function relies on introspection and does not call the function.
- Returns None if validity can't be determined.
-
- >>> def f(x):
- ... return x
- >>> is_arity(1, f)
- True
- >>> def g(x, y=1):
- ... return x + y
- >>> is_arity(1, g)
- False
- """
- sigspec, rv = _check_sigspec(sigspec, func, _sigs._is_arity, n, func)
- if sigspec is None:
- return rv
- num = num_required_args(func, sigspec)
- if num is not None:
- num = num == n
- if not num:
- return False
- varargs = has_varargs(func, sigspec)
- if varargs:
- return False
- keywords = has_keywords(func, sigspec)
- if keywords:
- return False
- if num is None or varargs is None or keywords is None: # pragma: no cover
- return None
- return True
-
-
-num_required_args.__doc__ = """ \
-Number of required positional arguments
-
- This function relies on introspection and does not call the function.
- Returns None if validity can't be determined.
-
- >>> def f(x, y, z=3):
- ... return x + y + z
- >>> num_required_args(f)
- 2
- >>> def g(*args, **kwargs):
- ... pass
- >>> num_required_args(g)
- 0
- """
-
-has_varargs.__doc__ = """ \
-Does a function have variadic positional arguments?
-
- This function relies on introspection and does not call the function.
- Returns None if validity can't be determined.
-
- >>> def f(*args):
- ... return args
- >>> has_varargs(f)
- True
- >>> def g(**kwargs):
- ... return kwargs
- >>> has_varargs(g)
- False
- """
-
-has_keywords.__doc__ = """ \
-Does a function have keyword arguments?
-
- This function relies on introspection and does not call the function.
- Returns None if validity can't be determined.
-
- >>> def f(x, y=0):
- ... return x + y
-
- >>> has_keywords(f)
- True
- """
-
-is_valid_args.__doc__ = """ \
-Is ``func(*args, **kwargs)`` a valid function call?
-
- This function relies on introspection and does not call the function.
- Returns None if validity can't be determined.
-
- >>> def add(x, y):
- ... return x + y
-
- >>> is_valid_args(add, (1,), {})
- False
- >>> is_valid_args(add, (1, 2), {})
- True
- >>> is_valid_args(map, (), {})
- False
-
- **Implementation notes**
- Python 2 relies on ``inspect.getargspec``, which only works for
- user-defined functions. Python 3 uses ``inspect.signature``, which
- works for many more types of callables.
-
- Many builtins in the standard library are also supported.
- """
-
-is_partial_args.__doc__ = """ \
-Can partial(func, *args, **kwargs)(*args2, **kwargs2) be a valid call?
-
- Returns True *only* if the call is valid or if it is possible for the
- call to become valid by adding more positional or keyword arguments.
-
- This function relies on introspection and does not call the function.
- Returns None if validity can't be determined.
-
- >>> def add(x, y):
- ... return x + y
-
- >>> is_partial_args(add, (1,), {})
- True
- >>> is_partial_args(add, (1, 2), {})
- True
- >>> is_partial_args(add, (1, 2, 3), {})
- False
- >>> is_partial_args(map, (), {})
- True
-
- **Implementation notes**
- Python 2 relies on ``inspect.getargspec``, which only works for
- user-defined functions. Python 3 uses ``inspect.signature``, which
- works for many more types of callables.
-
- Many builtins in the standard library are also supported.
- """
-
-from . import _signatures as _sigs
diff --git a/contrib/python/toolz/py2/toolz/itertoolz.py b/contrib/python/toolz/py2/toolz/itertoolz.py
deleted file mode 100644
index e71f1eeef0..0000000000
--- a/contrib/python/toolz/py2/toolz/itertoolz.py
+++ /dev/null
@@ -1,1056 +0,0 @@
-import itertools
-import heapq
-import collections
-import operator
-from functools import partial
-from random import Random
-from toolz.compatibility import (map, filterfalse, zip, zip_longest, iteritems,
- filter, Sequence)
-from toolz.utils import no_default
-
-
-__all__ = ('remove', 'accumulate', 'groupby', 'merge_sorted', 'interleave',
- 'unique', 'isiterable', 'isdistinct', 'take', 'drop', 'take_nth',
- 'first', 'second', 'nth', 'last', 'get', 'concat', 'concatv',
- 'mapcat', 'cons', 'interpose', 'frequencies', 'reduceby', 'iterate',
- 'sliding_window', 'partition', 'partition_all', 'count', 'pluck',
- 'join', 'tail', 'diff', 'topk', 'peek', 'peekn', 'random_sample')
-
-
-def remove(predicate, seq):
- """ Return those items of sequence for which predicate(item) is False
-
- >>> def iseven(x):
- ... return x % 2 == 0
- >>> list(remove(iseven, [1, 2, 3, 4]))
- [1, 3]
- """
- return filterfalse(predicate, seq)
-
-
-def accumulate(binop, seq, initial=no_default):
- """ Repeatedly apply binary function to a sequence, accumulating results
-
- >>> from operator import add, mul
- >>> list(accumulate(add, [1, 2, 3, 4, 5]))
- [1, 3, 6, 10, 15]
- >>> list(accumulate(mul, [1, 2, 3, 4, 5]))
- [1, 2, 6, 24, 120]
-
- Accumulate is similar to ``reduce`` and is good for making functions like
- cumulative sum:
-
- >>> from functools import partial, reduce
- >>> sum = partial(reduce, add)
- >>> cumsum = partial(accumulate, add)
-
- Accumulate also takes an optional argument that will be used as the first
- value. This is similar to reduce.
-
- >>> list(accumulate(add, [1, 2, 3], -1))
- [-1, 0, 2, 5]
- >>> list(accumulate(add, [], 1))
- [1]
-
- See Also:
- itertools.accumulate : In standard itertools for Python 3.2+
- """
- seq = iter(seq)
- if initial == no_default:
- try:
- result = next(seq)
- except StopIteration:
- return
- else:
- result = initial
- yield result
- for elem in seq:
- result = binop(result, elem)
- yield result
-
-
-def groupby(key, seq):
- """ Group a collection by a key function
-
- >>> names = ['Alice', 'Bob', 'Charlie', 'Dan', 'Edith', 'Frank']
- >>> groupby(len, names) # doctest: +SKIP
- {3: ['Bob', 'Dan'], 5: ['Alice', 'Edith', 'Frank'], 7: ['Charlie']}
-
- >>> iseven = lambda x: x % 2 == 0
- >>> groupby(iseven, [1, 2, 3, 4, 5, 6, 7, 8]) # doctest: +SKIP
- {False: [1, 3, 5, 7], True: [2, 4, 6, 8]}
-
- Non-callable keys imply grouping on a member.
-
- >>> groupby('gender', [{'name': 'Alice', 'gender': 'F'},
- ... {'name': 'Bob', 'gender': 'M'},
- ... {'name': 'Charlie', 'gender': 'M'}]) # doctest:+SKIP
- {'F': [{'gender': 'F', 'name': 'Alice'}],
- 'M': [{'gender': 'M', 'name': 'Bob'},
- {'gender': 'M', 'name': 'Charlie'}]}
-
- Not to be confused with ``itertools.groupby``
-
- See Also:
- countby
- """
- if not callable(key):
- key = getter(key)
- d = collections.defaultdict(lambda: [].append)
- for item in seq:
- d[key(item)](item)
- rv = {}
- for k, v in iteritems(d):
- rv[k] = v.__self__
- return rv
-
-
-def merge_sorted(*seqs, **kwargs):
- """ Merge and sort a collection of sorted collections
-
- This works lazily and only keeps one value from each iterable in memory.
-
- >>> list(merge_sorted([1, 3, 5], [2, 4, 6]))
- [1, 2, 3, 4, 5, 6]
-
- >>> ''.join(merge_sorted('abc', 'abc', 'abc'))
- 'aaabbbccc'
-
- The "key" function used to sort the input may be passed as a keyword.
-
- >>> list(merge_sorted([2, 3], [1, 3], key=lambda x: x // 3))
- [2, 1, 3, 3]
- """
- if len(seqs) == 0:
- return iter([])
- elif len(seqs) == 1:
- return iter(seqs[0])
-
- key = kwargs.get('key', None)
- if key is None:
- return _merge_sorted_binary(seqs)
- else:
- return _merge_sorted_binary_key(seqs, key)
-
-
-def _merge_sorted_binary(seqs):
- mid = len(seqs) // 2
- L1 = seqs[:mid]
- if len(L1) == 1:
- seq1 = iter(L1[0])
- else:
- seq1 = _merge_sorted_binary(L1)
- L2 = seqs[mid:]
- if len(L2) == 1:
- seq2 = iter(L2[0])
- else:
- seq2 = _merge_sorted_binary(L2)
-
- try:
- val2 = next(seq2)
- except StopIteration:
- for val1 in seq1:
- yield val1
- return
-
- for val1 in seq1:
- if val2 < val1:
- yield val2
- for val2 in seq2:
- if val2 < val1:
- yield val2
- else:
- yield val1
- break
- else:
- break
- else:
- yield val1
- else:
- yield val2
- for val2 in seq2:
- yield val2
- return
- yield val1
- for val1 in seq1:
- yield val1
-
-
-def _merge_sorted_binary_key(seqs, key):
- mid = len(seqs) // 2
- L1 = seqs[:mid]
- if len(L1) == 1:
- seq1 = iter(L1[0])
- else:
- seq1 = _merge_sorted_binary_key(L1, key)
- L2 = seqs[mid:]
- if len(L2) == 1:
- seq2 = iter(L2[0])
- else:
- seq2 = _merge_sorted_binary_key(L2, key)
-
- try:
- val2 = next(seq2)
- except StopIteration:
- for val1 in seq1:
- yield val1
- return
- key2 = key(val2)
-
- for val1 in seq1:
- key1 = key(val1)
- if key2 < key1:
- yield val2
- for val2 in seq2:
- key2 = key(val2)
- if key2 < key1:
- yield val2
- else:
- yield val1
- break
- else:
- break
- else:
- yield val1
- else:
- yield val2
- for val2 in seq2:
- yield val2
- return
- yield val1
- for val1 in seq1:
- yield val1
-
-
-def interleave(seqs):
- """ Interleave a sequence of sequences
-
- >>> list(interleave([[1, 2], [3, 4]]))
- [1, 3, 2, 4]
-
- >>> ''.join(interleave(('ABC', 'XY')))
- 'AXBYC'
-
- Both the individual sequences and the sequence of sequences may be infinite
-
- Returns a lazy iterator
- """
- iters = itertools.cycle(map(iter, seqs))
- while True:
- try:
- for itr in iters:
- yield next(itr)
- return
- except StopIteration:
- predicate = partial(operator.is_not, itr)
- iters = itertools.cycle(itertools.takewhile(predicate, iters))
-
-
-def unique(seq, key=None):
- """ Return only unique elements of a sequence
-
- >>> tuple(unique((1, 2, 3)))
- (1, 2, 3)
- >>> tuple(unique((1, 2, 1, 3)))
- (1, 2, 3)
-
- Uniqueness can be defined by key keyword
-
- >>> tuple(unique(['cat', 'mouse', 'dog', 'hen'], key=len))
- ('cat', 'mouse')
- """
- seen = set()
- seen_add = seen.add
- if key is None:
- for item in seq:
- if item not in seen:
- seen_add(item)
- yield item
- else: # calculate key
- for item in seq:
- val = key(item)
- if val not in seen:
- seen_add(val)
- yield item
-
-
-def isiterable(x):
- """ Is x iterable?
-
- >>> isiterable([1, 2, 3])
- True
- >>> isiterable('abc')
- True
- >>> isiterable(5)
- False
- """
- try:
- iter(x)
- return True
- except TypeError:
- return False
-
-
-def isdistinct(seq):
- """ All values in sequence are distinct
-
- >>> isdistinct([1, 2, 3])
- True
- >>> isdistinct([1, 2, 1])
- False
-
- >>> isdistinct("Hello")
- False
- >>> isdistinct("World")
- True
- """
- if iter(seq) is seq:
- seen = set()
- seen_add = seen.add
- for item in seq:
- if item in seen:
- return False
- seen_add(item)
- return True
- else:
- return len(seq) == len(set(seq))
-
-
-def take(n, seq):
- """ The first n elements of a sequence
-
- >>> list(take(2, [10, 20, 30, 40, 50]))
- [10, 20]
-
- See Also:
- drop
- tail
- """
- return itertools.islice(seq, n)
-
-
-def tail(n, seq):
- """ The last n elements of a sequence
-
- >>> tail(2, [10, 20, 30, 40, 50])
- [40, 50]
-
- See Also:
- drop
- take
- """
- try:
- return seq[-n:]
- except (TypeError, KeyError):
- return tuple(collections.deque(seq, n))
-
-
-def drop(n, seq):
- """ The sequence following the first n elements
-
- >>> list(drop(2, [10, 20, 30, 40, 50]))
- [30, 40, 50]
-
- See Also:
- take
- tail
- """
- return itertools.islice(seq, n, None)
-
-
-def take_nth(n, seq):
- """ Every nth item in seq
-
- >>> list(take_nth(2, [10, 20, 30, 40, 50]))
- [10, 30, 50]
- """
- return itertools.islice(seq, 0, None, n)
-
-
-def first(seq):
- """ The first element in a sequence
-
- >>> first('ABC')
- 'A'
- """
- return next(iter(seq))
-
-
-def second(seq):
- """ The second element in a sequence
-
- >>> second('ABC')
- 'B'
- """
- seq = iter(seq)
- next(seq)
- return next(seq)
-
-
-def nth(n, seq):
- """ The nth element in a sequence
-
- >>> nth(1, 'ABC')
- 'B'
- """
- if isinstance(seq, (tuple, list, Sequence)):
- return seq[n]
- else:
- return next(itertools.islice(seq, n, None))
-
-
-def last(seq):
- """ The last element in a sequence
-
- >>> last('ABC')
- 'C'
- """
- return tail(1, seq)[0]
-
-
-rest = partial(drop, 1)
-
-
-def _get(ind, seq, default):
- try:
- return seq[ind]
- except (KeyError, IndexError):
- return default
-
-
-def get(ind, seq, default=no_default):
- """ Get element in a sequence or dict
-
- Provides standard indexing
-
- >>> get(1, 'ABC') # Same as 'ABC'[1]
- 'B'
-
- Pass a list to get multiple values
-
- >>> get([1, 2], 'ABC') # ('ABC'[1], 'ABC'[2])
- ('B', 'C')
-
- Works on any value that supports indexing/getitem
- For example here we see that it works with dictionaries
-
- >>> phonebook = {'Alice': '555-1234',
- ... 'Bob': '555-5678',
- ... 'Charlie':'555-9999'}
- >>> get('Alice', phonebook)
- '555-1234'
-
- >>> get(['Alice', 'Bob'], phonebook)
- ('555-1234', '555-5678')
-
- Provide a default for missing values
-
- >>> get(['Alice', 'Dennis'], phonebook, None)
- ('555-1234', None)
-
- See Also:
- pluck
- """
- try:
- return seq[ind]
- except TypeError: # `ind` may be a list
- if isinstance(ind, list):
- if default == no_default:
- if len(ind) > 1:
- return operator.itemgetter(*ind)(seq)
- elif ind:
- return seq[ind[0]],
- else:
- return ()
- else:
- return tuple(_get(i, seq, default) for i in ind)
- elif default != no_default:
- return default
- else:
- raise
- except (KeyError, IndexError): # we know `ind` is not a list
- if default == no_default:
- raise
- else:
- return default
-
-
-def concat(seqs):
- """ Concatenate zero or more iterables, any of which may be infinite.
-
- An infinite sequence will prevent the rest of the arguments from
- being included.
-
- We use chain.from_iterable rather than ``chain(*seqs)`` so that seqs
- can be a generator.
-
- >>> list(concat([[], [1], [2, 3]]))
- [1, 2, 3]
-
- See also:
- itertools.chain.from_iterable equivalent
- """
- return itertools.chain.from_iterable(seqs)
-
-
-def concatv(*seqs):
- """ Variadic version of concat
-
- >>> list(concatv([], ["a"], ["b", "c"]))
- ['a', 'b', 'c']
-
- See also:
- itertools.chain
- """
- return concat(seqs)
-
-
-def mapcat(func, seqs):
- """ Apply func to each sequence in seqs, concatenating results.
-
- >>> list(mapcat(lambda s: [c.upper() for c in s],
- ... [["a", "b"], ["c", "d", "e"]]))
- ['A', 'B', 'C', 'D', 'E']
- """
- return concat(map(func, seqs))
-
-
-def cons(el, seq):
- """ Add el to beginning of (possibly infinite) sequence seq.
-
- >>> list(cons(1, [2, 3]))
- [1, 2, 3]
- """
- return itertools.chain([el], seq)
-
-
-def interpose(el, seq):
- """ Introduce element between each pair of elements in seq
-
- >>> list(interpose("a", [1, 2, 3]))
- [1, 'a', 2, 'a', 3]
- """
- inposed = concat(zip(itertools.repeat(el), seq))
- next(inposed)
- return inposed
-
-
-def frequencies(seq):
- """ Find number of occurrences of each value in seq
-
- >>> frequencies(['cat', 'cat', 'ox', 'pig', 'pig', 'cat']) #doctest: +SKIP
- {'cat': 3, 'ox': 1, 'pig': 2}
-
- See Also:
- countby
- groupby
- """
- d = collections.defaultdict(int)
- for item in seq:
- d[item] += 1
- return dict(d)
-
-
-def reduceby(key, binop, seq, init=no_default):
- """ Perform a simultaneous groupby and reduction
-
- The computation:
-
- >>> result = reduceby(key, binop, seq, init) # doctest: +SKIP
-
- is equivalent to the following:
-
- >>> def reduction(group): # doctest: +SKIP
- ... return reduce(binop, group, init) # doctest: +SKIP
-
- >>> groups = groupby(key, seq) # doctest: +SKIP
- >>> result = valmap(reduction, groups) # doctest: +SKIP
-
- But the former does not build the intermediate groups, allowing it to
- operate in much less space. This makes it suitable for larger datasets
- that do not fit comfortably in memory
-
- The ``init`` keyword argument is the default initialization of the
- reduction. This can be either a constant value like ``0`` or a callable
- like ``lambda : 0`` as might be used in ``defaultdict``.
-
- Simple Examples
- ---------------
-
- >>> from operator import add, mul
- >>> iseven = lambda x: x % 2 == 0
-
- >>> data = [1, 2, 3, 4, 5]
-
- >>> reduceby(iseven, add, data) # doctest: +SKIP
- {False: 9, True: 6}
-
- >>> reduceby(iseven, mul, data) # doctest: +SKIP
- {False: 15, True: 8}
-
- Complex Example
- ---------------
-
- >>> projects = [{'name': 'build roads', 'state': 'CA', 'cost': 1000000},
- ... {'name': 'fight crime', 'state': 'IL', 'cost': 100000},
- ... {'name': 'help farmers', 'state': 'IL', 'cost': 2000000},
- ... {'name': 'help farmers', 'state': 'CA', 'cost': 200000}]
-
- >>> reduceby('state', # doctest: +SKIP
- ... lambda acc, x: acc + x['cost'],
- ... projects, 0)
- {'CA': 1200000, 'IL': 2100000}
-
- Example Using ``init``
- ----------------------
-
- >>> def set_add(s, i):
- ... s.add(i)
- ... return s
-
- >>> reduceby(iseven, set_add, [1, 2, 3, 4, 1, 2, 3], set) # doctest: +SKIP
- {True: set([2, 4]),
- False: set([1, 3])}
- """
- is_no_default = init == no_default
- if not is_no_default and not callable(init):
- _init = init
- init = lambda: _init
- if not callable(key):
- key = getter(key)
- d = {}
- for item in seq:
- k = key(item)
- if k not in d:
- if is_no_default:
- d[k] = item
- continue
- else:
- d[k] = init()
- d[k] = binop(d[k], item)
- return d
-
-
-def iterate(func, x):
- """ Repeatedly apply a function func onto an original input
-
- Yields x, then func(x), then func(func(x)), then func(func(func(x))), etc..
-
- >>> def inc(x): return x + 1
- >>> counter = iterate(inc, 0)
- >>> next(counter)
- 0
- >>> next(counter)
- 1
- >>> next(counter)
- 2
-
- >>> double = lambda x: x * 2
- >>> powers_of_two = iterate(double, 1)
- >>> next(powers_of_two)
- 1
- >>> next(powers_of_two)
- 2
- >>> next(powers_of_two)
- 4
- >>> next(powers_of_two)
- 8
- """
- while True:
- yield x
- x = func(x)
-
-
-def sliding_window(n, seq):
- """ A sequence of overlapping subsequences
-
- >>> list(sliding_window(2, [1, 2, 3, 4]))
- [(1, 2), (2, 3), (3, 4)]
-
- This function creates a sliding window suitable for transformations like
- sliding means / smoothing
-
- >>> mean = lambda seq: float(sum(seq)) / len(seq)
- >>> list(map(mean, sliding_window(2, [1, 2, 3, 4])))
- [1.5, 2.5, 3.5]
- """
- return zip(*(collections.deque(itertools.islice(it, i), 0) or it
- for i, it in enumerate(itertools.tee(seq, n))))
-
-
-no_pad = '__no__pad__'
-
-
-def partition(n, seq, pad=no_pad):
- """ Partition sequence into tuples of length n
-
- >>> list(partition(2, [1, 2, 3, 4]))
- [(1, 2), (3, 4)]
-
- If the length of ``seq`` is not evenly divisible by ``n``, the final tuple
- is dropped if ``pad`` is not specified, or filled to length ``n`` by pad:
-
- >>> list(partition(2, [1, 2, 3, 4, 5]))
- [(1, 2), (3, 4)]
-
- >>> list(partition(2, [1, 2, 3, 4, 5], pad=None))
- [(1, 2), (3, 4), (5, None)]
-
- See Also:
- partition_all
- """
- args = [iter(seq)] * n
- if pad is no_pad:
- return zip(*args)
- else:
- return zip_longest(*args, fillvalue=pad)
-
-
-def partition_all(n, seq):
- """ Partition all elements of sequence into tuples of length at most n
-
- The final tuple may be shorter to accommodate extra elements.
-
- >>> list(partition_all(2, [1, 2, 3, 4]))
- [(1, 2), (3, 4)]
-
- >>> list(partition_all(2, [1, 2, 3, 4, 5]))
- [(1, 2), (3, 4), (5,)]
-
- See Also:
- partition
- """
- args = [iter(seq)] * n
- it = zip_longest(*args, fillvalue=no_pad)
- try:
- prev = next(it)
- except StopIteration:
- return
- for item in it:
- yield prev
- prev = item
- if prev[-1] is no_pad:
- try:
- # If seq defines __len__, then
- # we can quickly calculate where no_pad starts
- yield prev[:len(seq) % n]
- except TypeError:
- # Get first index of no_pad without using .index()
- # https://github.com/pytoolz/toolz/issues/387
- # Binary search from CPython's bisect module,
- # modified for identity testing.
- lo, hi = 0, n
- while lo < hi:
- mid = (lo + hi) // 2
- if prev[mid] is no_pad:
- hi = mid
- else:
- lo = mid + 1
- yield prev[:lo]
- else:
- yield prev
-
-
-def count(seq):
- """ Count the number of items in seq
-
- Like the builtin ``len`` but works on lazy sequencies.
-
- Not to be confused with ``itertools.count``
-
- See also:
- len
- """
- if hasattr(seq, '__len__'):
- return len(seq)
- return sum(1 for i in seq)
-
-
-def pluck(ind, seqs, default=no_default):
- """ plucks an element or several elements from each item in a sequence.
-
- ``pluck`` maps ``itertoolz.get`` over a sequence and returns one or more
- elements of each item in the sequence.
-
- This is equivalent to running `map(curried.get(ind), seqs)`
-
- ``ind`` can be either a single string/index or a list of strings/indices.
- ``seqs`` should be sequence containing sequences or dicts.
-
- e.g.
-
- >>> data = [{'id': 1, 'name': 'Cheese'}, {'id': 2, 'name': 'Pies'}]
- >>> list(pluck('name', data))
- ['Cheese', 'Pies']
- >>> list(pluck([0, 1], [[1, 2, 3], [4, 5, 7]]))
- [(1, 2), (4, 5)]
-
- See Also:
- get
- map
- """
- if default == no_default:
- get = getter(ind)
- return map(get, seqs)
- elif isinstance(ind, list):
- return (tuple(_get(item, seq, default) for item in ind)
- for seq in seqs)
- return (_get(ind, seq, default) for seq in seqs)
-
-
-def getter(index):
- if isinstance(index, list):
- if len(index) == 1:
- index = index[0]
- return lambda x: (x[index],)
- elif index:
- return operator.itemgetter(*index)
- else:
- return lambda x: ()
- else:
- return operator.itemgetter(index)
-
-
-def join(leftkey, leftseq, rightkey, rightseq,
- left_default=no_default, right_default=no_default):
- """ Join two sequences on common attributes
-
- This is a semi-streaming operation. The LEFT sequence is fully evaluated
- and placed into memory. The RIGHT sequence is evaluated lazily and so can
- be arbitrarily large.
- (Note: If right_default is defined, then unique keys of rightseq
- will also be stored in memory.)
-
- >>> friends = [('Alice', 'Edith'),
- ... ('Alice', 'Zhao'),
- ... ('Edith', 'Alice'),
- ... ('Zhao', 'Alice'),
- ... ('Zhao', 'Edith')]
-
- >>> cities = [('Alice', 'NYC'),
- ... ('Alice', 'Chicago'),
- ... ('Dan', 'Syndey'),
- ... ('Edith', 'Paris'),
- ... ('Edith', 'Berlin'),
- ... ('Zhao', 'Shanghai')]
-
- >>> # Vacation opportunities
- >>> # In what cities do people have friends?
- >>> result = join(second, friends,
- ... first, cities)
- >>> for ((a, b), (c, d)) in sorted(unique(result)):
- ... print((a, d))
- ('Alice', 'Berlin')
- ('Alice', 'Paris')
- ('Alice', 'Shanghai')
- ('Edith', 'Chicago')
- ('Edith', 'NYC')
- ('Zhao', 'Chicago')
- ('Zhao', 'NYC')
- ('Zhao', 'Berlin')
- ('Zhao', 'Paris')
-
- Specify outer joins with keyword arguments ``left_default`` and/or
- ``right_default``. Here is a full outer join in which unmatched elements
- are paired with None.
-
- >>> identity = lambda x: x
- >>> list(join(identity, [1, 2, 3],
- ... identity, [2, 3, 4],
- ... left_default=None, right_default=None))
- [(2, 2), (3, 3), (None, 4), (1, None)]
-
- Usually the key arguments are callables to be applied to the sequences. If
- the keys are not obviously callable then it is assumed that indexing was
- intended, e.g. the following is a legal change.
- The join is implemented as a hash join and the keys of leftseq must be
- hashable. Additionally, if right_default is defined, then keys of rightseq
- must also be hashable.
-
- >>> # result = join(second, friends, first, cities)
- >>> result = join(1, friends, 0, cities) # doctest: +SKIP
- """
- if not callable(leftkey):
- leftkey = getter(leftkey)
- if not callable(rightkey):
- rightkey = getter(rightkey)
-
- d = groupby(leftkey, leftseq)
-
- if left_default == no_default and right_default == no_default:
- # Inner Join
- for item in rightseq:
- key = rightkey(item)
- if key in d:
- for left_match in d[key]:
- yield (left_match, item)
- elif left_default != no_default and right_default == no_default:
- # Right Join
- for item in rightseq:
- key = rightkey(item)
- if key in d:
- for left_match in d[key]:
- yield (left_match, item)
- else:
- yield (left_default, item)
- elif right_default != no_default:
- seen_keys = set()
- seen = seen_keys.add
-
- if left_default == no_default:
- # Left Join
- for item in rightseq:
- key = rightkey(item)
- seen(key)
- if key in d:
- for left_match in d[key]:
- yield (left_match, item)
- else:
- # Full Join
- for item in rightseq:
- key = rightkey(item)
- seen(key)
- if key in d:
- for left_match in d[key]:
- yield (left_match, item)
- else:
- yield (left_default, item)
-
- for key, matches in iteritems(d):
- if key not in seen_keys:
- for match in matches:
- yield (match, right_default)
-
-
-def diff(*seqs, **kwargs):
- """ Return those items that differ between sequences
-
- >>> list(diff([1, 2, 3], [1, 2, 10, 100]))
- [(3, 10)]
-
- Shorter sequences may be padded with a ``default`` value:
-
- >>> list(diff([1, 2, 3], [1, 2, 10, 100], default=None))
- [(3, 10), (None, 100)]
-
- A ``key`` function may also be applied to each item to use during
- comparisons:
-
- >>> list(diff(['apples', 'bananas'], ['Apples', 'Oranges'], key=str.lower))
- [('bananas', 'Oranges')]
- """
- N = len(seqs)
- if N == 1 and isinstance(seqs[0], list):
- seqs = seqs[0]
- N = len(seqs)
- if N < 2:
- raise TypeError('Too few sequences given (min 2 required)')
- default = kwargs.get('default', no_default)
- if default == no_default:
- iters = zip(*seqs)
- else:
- iters = zip_longest(*seqs, fillvalue=default)
- key = kwargs.get('key', None)
- if key is None:
- for items in iters:
- if items.count(items[0]) != N:
- yield items
- else:
- for items in iters:
- vals = tuple(map(key, items))
- if vals.count(vals[0]) != N:
- yield items
-
-
-def topk(k, seq, key=None):
- """ Find the k largest elements of a sequence
-
- Operates lazily in ``n*log(k)`` time
-
- >>> topk(2, [1, 100, 10, 1000])
- (1000, 100)
-
- Use a key function to change sorted order
-
- >>> topk(2, ['Alice', 'Bob', 'Charlie', 'Dan'], key=len)
- ('Charlie', 'Alice')
-
- See also:
- heapq.nlargest
- """
- if key is not None and not callable(key):
- key = getter(key)
- return tuple(heapq.nlargest(k, seq, key=key))
-
-
-def peek(seq):
- """ Retrieve the next element of a sequence
-
- Returns the first element and an iterable equivalent to the original
- sequence, still having the element retrieved.
-
- >>> seq = [0, 1, 2, 3, 4]
- >>> first, seq = peek(seq)
- >>> first
- 0
- >>> list(seq)
- [0, 1, 2, 3, 4]
- """
- iterator = iter(seq)
- item = next(iterator)
- return item, itertools.chain((item,), iterator)
-
-
-def peekn(n, seq):
- """ Retrieve the next n elements of a sequence
-
- Returns a tuple of the first n elements and an iterable equivalent
- to the original, still having the elements retrieved.
-
- >>> seq = [0, 1, 2, 3, 4]
- >>> first_two, seq = peekn(2, seq)
- >>> first_two
- (0, 1)
- >>> list(seq)
- [0, 1, 2, 3, 4]
- """
- iterator = iter(seq)
- peeked = tuple(take(n, iterator))
- return peeked, itertools.chain(iter(peeked), iterator)
-
-
-def random_sample(prob, seq, random_state=None):
- """ Return elements from a sequence with probability of prob
-
- Returns a lazy iterator of random items from seq.
-
- ``random_sample`` considers each item independently and without
- replacement. See below how the first time it returned 13 items and the
- next time it returned 6 items.
-
- >>> seq = list(range(100))
- >>> list(random_sample(0.1, seq)) # doctest: +SKIP
- [6, 9, 19, 35, 45, 50, 58, 62, 68, 72, 78, 86, 95]
- >>> list(random_sample(0.1, seq)) # doctest: +SKIP
- [6, 44, 54, 61, 69, 94]
-
- Providing an integer seed for ``random_state`` will result in
- deterministic sampling. Given the same seed it will return the same sample
- every time.
-
- >>> list(random_sample(0.1, seq, random_state=2016))
- [7, 9, 19, 25, 30, 32, 34, 48, 59, 60, 81, 98]
- >>> list(random_sample(0.1, seq, random_state=2016))
- [7, 9, 19, 25, 30, 32, 34, 48, 59, 60, 81, 98]
-
- ``random_state`` can also be any object with a method ``random`` that
- returns floats between 0.0 and 1.0 (exclusive).
-
- >>> from random import Random
- >>> randobj = Random(2016)
- >>> list(random_sample(0.1, seq, random_state=randobj))
- [7, 9, 19, 25, 30, 32, 34, 48, 59, 60, 81, 98]
- """
- if not hasattr(random_state, 'random'):
- random_state = Random(random_state)
- return filter(lambda _: random_state.random() < prob, seq)
diff --git a/contrib/python/toolz/py2/toolz/recipes.py b/contrib/python/toolz/py2/toolz/recipes.py
deleted file mode 100644
index 08c6c8c1e2..0000000000
--- a/contrib/python/toolz/py2/toolz/recipes.py
+++ /dev/null
@@ -1,47 +0,0 @@
-import itertools
-from .itertoolz import frequencies, pluck, getter
-from .compatibility import map
-
-
-__all__ = ('countby', 'partitionby')
-
-
-def countby(key, seq):
- """ Count elements of a collection by a key function
-
- >>> countby(len, ['cat', 'mouse', 'dog'])
- {3: 2, 5: 1}
-
- >>> def iseven(x): return x % 2 == 0
- >>> countby(iseven, [1, 2, 3]) # doctest:+SKIP
- {True: 1, False: 2}
-
- See Also:
- groupby
- """
- if not callable(key):
- key = getter(key)
- return frequencies(map(key, seq))
-
-
-def partitionby(func, seq):
- """ Partition a sequence according to a function
-
- Partition `s` into a sequence of lists such that, when traversing
- `s`, every time the output of `func` changes a new list is started
- and that and subsequent items are collected into that list.
-
- >>> is_space = lambda c: c == " "
- >>> list(partitionby(is_space, "I have space"))
- [('I',), (' ',), ('h', 'a', 'v', 'e'), (' ',), ('s', 'p', 'a', 'c', 'e')]
-
- >>> is_large = lambda x: x > 10
- >>> list(partitionby(is_large, [1, 2, 1, 99, 88, 33, 99, -1, 5]))
- [(1, 2, 1), (99, 88, 33, 99), (-1, 5)]
-
- See also:
- partition
- groupby
- itertools.groupby
- """
- return map(tuple, pluck(1, itertools.groupby(seq, key=func)))
diff --git a/contrib/python/toolz/py2/toolz/sandbox/__init__.py b/contrib/python/toolz/py2/toolz/sandbox/__init__.py
deleted file mode 100644
index 0abda1cb42..0000000000
--- a/contrib/python/toolz/py2/toolz/sandbox/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-from .core import EqualityHashKey, unzip
-from .parallel import fold
diff --git a/contrib/python/toolz/py2/toolz/sandbox/core.py b/contrib/python/toolz/py2/toolz/sandbox/core.py
deleted file mode 100644
index 915f06c213..0000000000
--- a/contrib/python/toolz/py2/toolz/sandbox/core.py
+++ /dev/null
@@ -1,133 +0,0 @@
-from toolz.itertoolz import getter, cons, pluck
-from itertools import tee, starmap
-
-
-# See #166: https://github.com/pytoolz/toolz/issues/166
-# See #173: https://github.com/pytoolz/toolz/pull/173
-class EqualityHashKey(object):
- """ Create a hash key that uses equality comparisons between items.
-
- This may be used to create hash keys for otherwise unhashable types:
-
- >>> from toolz import curry
- >>> EqualityHashDefault = curry(EqualityHashKey, None)
- >>> set(map(EqualityHashDefault, [[], (), [1], [1]])) # doctest: +SKIP
- {=[]=, =()=, =[1]=}
-
- **Caution:** adding N ``EqualityHashKey`` items to a hash container
- may require O(N**2) operations, not O(N) as for typical hashable types.
- Therefore, a suitable key function such as ``tuple`` or ``frozenset``
- is usually preferred over using ``EqualityHashKey`` if possible.
-
- The ``key`` argument to ``EqualityHashKey`` should be a function or
- index that returns a hashable object that effectively distinguishes
- unequal items. This helps avoid the poor scaling that occurs when
- using the default key. For example, the above example can be improved
- by using a key function that distinguishes items by length or type:
-
- >>> EqualityHashLen = curry(EqualityHashKey, len)
- >>> EqualityHashType = curry(EqualityHashKey, type) # this works too
- >>> set(map(EqualityHashLen, [[], (), [1], [1]])) # doctest: +SKIP
- {=[]=, =()=, =[1]=}
-
- ``EqualityHashKey`` is convenient to use when a suitable key function
- is complicated or unavailable. For example, the following returns all
- unique values based on equality:
-
- >>> from toolz import unique
- >>> vals = [[], [], (), [1], [1], [2], {}, {}, {}]
- >>> list(unique(vals, key=EqualityHashDefault))
- [[], (), [1], [2], {}]
-
- **Warning:** don't change the equality value of an item already in a hash
- containter. Unhashable types are unhashable for a reason. For example:
-
- >>> L1 = [1] ; L2 = [2]
- >>> s = set(map(EqualityHashDefault, [L1, L2]))
- >>> s # doctest: +SKIP
- {=[1]=, =[2]=}
-
- >>> L1[0] = 2 # Don't do this! ``s`` now has duplicate items!
- >>> s # doctest: +SKIP
- {=[2]=, =[2]=}
-
- Although this may appear problematic, immutable data types is a common
- idiom in functional programming, and``EqualityHashKey`` easily allows
- the same idiom to be used by convention rather than strict requirement.
-
- See Also:
- identity
- """
- __slots__ = ['item', 'key']
- _default_hashkey = '__default__hashkey__'
-
- def __init__(self, key, item):
- if key is None:
- self.key = self._default_hashkey
- elif not callable(key):
- self.key = getter(key)
- else:
- self.key = key
- self.item = item
-
- def __hash__(self):
- if self.key == self._default_hashkey:
- val = self.key
- else:
- val = self.key(self.item)
- return hash(val)
-
- def __eq__(self, other):
- try:
- return (self._default_hashkey == other._default_hashkey and
- self.item == other.item)
- except AttributeError:
- return False
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- def __str__(self):
- return '=%s=' % str(self.item)
-
- def __repr__(self):
- return '=%s=' % repr(self.item)
-
-
-# See issue #293: https://github.com/pytoolz/toolz/issues/239
-def unzip(seq):
- """Inverse of ``zip``
-
- >>> a, b = unzip([('a', 1), ('b', 2)])
- >>> list(a)
- ['a', 'b']
- >>> list(b)
- [1, 2]
-
- Unlike the naive implementation ``def unzip(seq): zip(*seq)`` this
- implementation can handle an infinite sequence ``seq``.
-
- Caveats:
-
- * The implementation uses ``tee``, and so can use a significant amount
- of auxiliary storage if the resulting iterators are consumed at
- different times.
-
- * The inner sequence cannot be infinite. In Python 3 ``zip(*seq)`` can be
- used if ``seq`` is a finite sequence of infinite sequences.
-
- """
-
- seq = iter(seq)
-
- # Check how many iterators we need
- try:
- first = tuple(next(seq))
- except StopIteration:
- return tuple()
-
- # and create them
- niters = len(first)
- seqs = tee(cons(first, seq), niters)
-
- return tuple(starmap(pluck, enumerate(seqs)))
diff --git a/contrib/python/toolz/py2/toolz/sandbox/parallel.py b/contrib/python/toolz/py2/toolz/sandbox/parallel.py
deleted file mode 100644
index ef8ed39dbd..0000000000
--- a/contrib/python/toolz/py2/toolz/sandbox/parallel.py
+++ /dev/null
@@ -1,76 +0,0 @@
-import functools
-from toolz.itertoolz import partition_all
-from toolz.compatibility import reduce, map
-from toolz.utils import no_default
-
-
-def _reduce(func, seq, initial=None):
- if initial is None:
- return functools.reduce(func, seq)
- else:
- return functools.reduce(func, seq, initial)
-
-
-def fold(binop, seq, default=no_default, map=map, chunksize=128, combine=None):
- """
- Reduce without guarantee of ordered reduction.
-
- inputs:
-
- ``binop`` - associative operator. The associative property allows us to
- leverage a parallel map to perform reductions in parallel.
- ``seq`` - a sequence to be aggregated
- ``default`` - an identity element like 0 for ``add`` or 1 for mul
-
- ``map`` - an implementation of ``map``. This may be parallel and
- determines how work is distributed.
- ``chunksize`` - Number of elements of ``seq`` that should be handled
- within a single function call
- ``combine`` - Binary operator to combine two intermediate results.
- If ``binop`` is of type (total, item) -> total
- then ``combine`` is of type (total, total) -> total
- Defaults to ``binop`` for common case of operators like add
-
- Fold chunks up the collection into blocks of size ``chunksize`` and then
- feeds each of these to calls to ``reduce``. This work is distributed
- with a call to ``map``, gathered back and then refolded to finish the
- computation. In this way ``fold`` specifies only how to chunk up data but
- leaves the distribution of this work to an externally provided ``map``
- function. This function can be sequential or rely on multithreading,
- multiprocessing, or even distributed solutions.
-
- If ``map`` intends to serialize functions it should be prepared to accept
- and serialize lambdas. Note that the standard ``pickle`` module fails
- here.
-
- Example
- -------
-
- >>> # Provide a parallel map to accomplish a parallel sum
- >>> from operator import add
- >>> fold(add, [1, 2, 3, 4], chunksize=2, map=map)
- 10
- """
- assert chunksize > 1
-
- if combine is None:
- combine = binop
-
- chunks = partition_all(chunksize, seq)
-
- # Evaluate sequence in chunks via map
- if default == no_default:
- results = map(
- functools.partial(_reduce, binop),
- chunks)
- else:
- results = map(
- functools.partial(_reduce, binop, initial=default),
- chunks)
-
- results = list(results) # TODO: Support complete laziness
-
- if len(results) == 1: # Return completed result
- return results[0]
- else: # Recurse to reaggregate intermediate results
- return fold(combine, results, map=map, chunksize=chunksize)
diff --git a/contrib/python/toolz/py2/toolz/utils.py b/contrib/python/toolz/py2/toolz/utils.py
deleted file mode 100644
index 1002c4649f..0000000000
--- a/contrib/python/toolz/py2/toolz/utils.py
+++ /dev/null
@@ -1,9 +0,0 @@
-def raises(err, lamda):
- try:
- lamda()
- return False
- except err:
- return True
-
-
-no_default = '__no__default__'
diff --git a/contrib/python/toolz/py2/ya.make b/contrib/python/toolz/py2/ya.make
deleted file mode 100644
index f64a13da67..0000000000
--- a/contrib/python/toolz/py2/ya.make
+++ /dev/null
@@ -1,41 +0,0 @@
-# Generated by devtools/yamaker (pypi).
-
-PY2_LIBRARY()
-
-VERSION(0.10.0)
-
-LICENSE(BSD-3-Clause)
-
-NO_LINT()
-
-PY_SRCS(
- TOP_LEVEL
- tlz/__init__.py
- tlz/_build_tlz.py
- toolz/__init__.py
- toolz/_signatures.py
- toolz/compatibility.py
- toolz/curried/__init__.py
- toolz/curried/exceptions.py
- toolz/curried/operator.py
- toolz/dicttoolz.py
- toolz/functoolz.py
- toolz/itertoolz.py
- toolz/recipes.py
- toolz/sandbox/__init__.py
- toolz/sandbox/core.py
- toolz/sandbox/parallel.py
- toolz/utils.py
-)
-
-RESOURCE_FILES(
- PREFIX contrib/python/toolz/py2/
- .dist-info/METADATA
- .dist-info/top_level.txt
-)
-
-END()
-
-RECURSE_FOR_TESTS(
- tests
-)
diff --git a/contrib/python/toolz/py3/AUTHORS.md b/contrib/python/toolz/py3/AUTHORS.md
deleted file mode 100644
index bd4a563d9b..0000000000
--- a/contrib/python/toolz/py3/AUTHORS.md
+++ /dev/null
@@ -1,33 +0,0 @@
-[Matthew Rocklin](http://matthewrocklin.com) [@mrocklin](http://github.com/mrocklin/)
-
-[John Jacobsen](http://eigenhombre.com) [@eigenhombre](http://github.com/eigenhombre/)
-
-Erik Welch [@eriknw](https://github.com/eriknw/)
-
-John Crichton [@jcrichton](https://github.com/jcrichton/)
-
-Han Semaj [@microamp](https://github.com/microamp/)
-
-[Graeme Coupar](https://twitter.com/obmarg) [@obmarg](https://github.com/obmarg/)
-
-[Leonid Shvechikov](http://brainstorage.me/shvechikov) [@shvechikov](https://github.com/shvechikov)
-
-Lars Buitinck [@larsmans](http://github.com/larsmans)
-
-José Ricardo [@josericardo](https://github.com/josericardo)
-
-Tom Prince [@tomprince](https://github.com/tomprince)
-
-Bart van Merriënboer [@bartvm](https://github.com/bartvm)
-
-Nikolaos-Digenis Karagiannis [@digenis](https://github.com/digenis/)
-
-[Antonio Lima](https://twitter.com/themiurgo) [@themiurgo](https://github.com/themiurgo/)
-
-Joe Jevnik [@llllllllll](https://github.com/llllllllll)
-
-Rory Kirchner [@roryk](https://github.com/roryk)
-
-[Steven Cutting](http://steven-cutting.github.io) [@steven_cutting](https://github.com/steven-cutting)
-
-Aric Coady [@coady](https://github.com/coady)
diff --git a/contrib/python/toolz/py3/LICENSE.txt b/contrib/python/toolz/py3/LICENSE.txt
deleted file mode 100644
index eeb91b202c..0000000000
--- a/contrib/python/toolz/py3/LICENSE.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-Copyright (c) 2013 Matthew Rocklin
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- a. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- b. 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.
- c. Neither the name of toolz nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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.
diff --git a/contrib/python/toolz/py3/README.rst b/contrib/python/toolz/py3/README.rst
deleted file mode 100644
index e62ac7917e..0000000000
--- a/contrib/python/toolz/py3/README.rst
+++ /dev/null
@@ -1,132 +0,0 @@
-Toolz
-=====
-
-|Build Status| |Coverage Status| |Version Status|
-
-A set of utility functions for iterators, functions, and dictionaries.
-
-See the PyToolz documentation at https://toolz.readthedocs.io
-
-LICENSE
--------
-
-New BSD. See `License File <https://github.com/pytoolz/toolz/blob/master/LICENSE.txt>`__.
-
-Install
--------
-
-``toolz`` is on the Python Package Index (PyPI):
-
-::
-
- pip install toolz
-
-Structure and Heritage
-----------------------
-
-``toolz`` is implemented in three parts:
-
-|literal itertoolz|_, for operations on iterables. Examples: ``groupby``,
-``unique``, ``interpose``,
-
-|literal functoolz|_, for higher-order functions. Examples: ``memoize``,
-``curry``, ``compose``,
-
-|literal dicttoolz|_, for operations on dictionaries. Examples: ``assoc``,
-``update-in``, ``merge``.
-
-.. |literal itertoolz| replace:: ``itertoolz``
-.. _literal itertoolz: https://github.com/pytoolz/toolz/blob/master/toolz/itertoolz.py
-
-.. |literal functoolz| replace:: ``functoolz``
-.. _literal functoolz: https://github.com/pytoolz/toolz/blob/master/toolz/functoolz.py
-
-.. |literal dicttoolz| replace:: ``dicttoolz``
-.. _literal dicttoolz: https://github.com/pytoolz/toolz/blob/master/toolz/dicttoolz.py
-
-These functions come from the legacy of functional languages for list
-processing. They interoperate well to accomplish common complex tasks.
-
-Read our `API
-Documentation <https://toolz.readthedocs.io/en/latest/api.html>`__ for
-more details.
-
-Example
--------
-
-This builds a standard wordcount function from pieces within ``toolz``:
-
-.. code:: python
-
- >>> def stem(word):
- ... """ Stem word to primitive form """
- ... return word.lower().rstrip(",.!:;'-\"").lstrip("'\"")
-
- >>> from toolz import compose, frequencies
- >>> from toolz.curried import map
- >>> wordcount = compose(frequencies, map(stem), str.split)
-
- >>> sentence = "This cat jumped over this other cat!"
- >>> wordcount(sentence)
- {'this': 2, 'cat': 2, 'jumped': 1, 'over': 1, 'other': 1}
-
-Dependencies
-------------
-
-``toolz`` supports Python 3.5+ with a common codebase.
-It is pure Python and requires no dependencies beyond the standard
-library.
-
-It is, in short, a lightweight dependency.
-
-
-CyToolz
--------
-
-The ``toolz`` project has been reimplemented in `Cython <http://cython.org>`__.
-The ``cytoolz`` project is a drop-in replacement for the Pure Python
-implementation.
-See `CyToolz GitHub Page <https://github.com/pytoolz/cytoolz/>`__ for more
-details.
-
-See Also
---------
-
-- `Underscore.js <https://underscorejs.org/>`__: A similar library for
- JavaScript
-- `Enumerable <https://ruby-doc.org/core-2.0.0/Enumerable.html>`__: A
- similar library for Ruby
-- `Clojure <https://clojure.org/>`__: A functional language whose
- standard library has several counterparts in ``toolz``
-- `itertools <https://docs.python.org/2/library/itertools.html>`__: The
- Python standard library for iterator tools
-- `functools <https://docs.python.org/2/library/functools.html>`__: The
- Python standard library for function tools
-
-Contributions Welcome
----------------------
-
-``toolz`` aims to be a repository for utility functions, particularly
-those that come from the functional programming and list processing
-traditions. We welcome contributions that fall within this scope.
-
-We also try to keep the API small to keep ``toolz`` manageable. The ideal
-contribution is significantly different from existing functions and has
-precedent in a few other functional systems.
-
-Please take a look at our
-`issue page <https://github.com/pytoolz/toolz/issues>`__
-for contribution ideas.
-
-Community
----------
-
-See our `mailing list <https://groups.google.com/forum/#!forum/pytoolz>`__.
-We're friendly.
-
-.. |Build Status| image:: https://github.com/pytoolz/toolz/workflows/Test/badge.svg
- :target: https://github.com/pytoolz/toolz/actions
-.. |Coverage Status| image:: https://coveralls.io/repos/pytoolz/toolz/badge.svg?branch=master
- :target: https://coveralls.io/r/pytoolz/toolz
-.. |Version Status| image:: https://badge.fury.io/py/toolz.svg
- :target: https://badge.fury.io/py/toolz
diff --git a/contrib/python/toolz/ya.make b/contrib/python/toolz/ya.make
deleted file mode 100644
index 0c05eedeac..0000000000
--- a/contrib/python/toolz/ya.make
+++ /dev/null
@@ -1,18 +0,0 @@
-PY23_LIBRARY()
-
-LICENSE(Service-Py23-Proxy)
-
-IF (PYTHON2)
- PEERDIR(contrib/python/toolz/py2)
-ELSE()
- PEERDIR(contrib/python/toolz/py3)
-ENDIF()
-
-NO_LINT()
-
-END()
-
-RECURSE(
- py2
- py3
-)
diff --git a/contrib/python/ujson/py2/lib/ultrajson.h b/contrib/python/ujson/py2/lib/ultrajson.h
deleted file mode 100644
index 92902b4910..0000000000
--- a/contrib/python/ujson/py2/lib/ultrajson.h
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
-Developed by ESN, an Electronic Arts Inc. studio.
-Copyright (c) 2014, Electronic Arts Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-* Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-* Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-* Neither the name of ESN, Electronic Arts Inc. nor the
-names of its contributors may be used to endorse or promote products
-derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS INC. 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.
-
-
-Portions of code from MODP_ASCII - Ascii transformations (upper/lower, etc)
-http://code.google.com/p/stringencoders/
-Copyright (c) 2007 Nick Galbreath -- nickg [at] modp [dot] com. All rights reserved.
-
-Numeric decoder derived from from TCL library
-http://www.opensource.apple.com/source/tcl/tcl-14/tcl/license.terms
- * Copyright (c) 1988-1993 The Regents of the University of California.
- * Copyright (c) 1994 Sun Microsystems, Inc.
-*/
-
-/*
-Ultra fast JSON encoder and decoder
-Developed by Jonas Tarnstrom (jonas@esn.me).
-
-Encoder notes:
-------------------
-
-:: Cyclic references ::
-Cyclic referenced objects are not detected.
-Set JSONObjectEncoder.recursionMax to suitable value or make sure input object
-tree doesn't have cyclic references.
-
-*/
-
-#ifndef __ULTRAJSON_H__
-#define __ULTRAJSON_H__
-
-#include <stdio.h>
-#include <wchar.h>
-
-// Don't output any extra whitespaces when encoding
-#define JSON_NO_EXTRA_WHITESPACE
-
-// Max decimals to encode double floating point numbers with
-#ifndef JSON_DOUBLE_MAX_DECIMALS
-#define JSON_DOUBLE_MAX_DECIMALS 15
-#endif
-
-// Max recursion depth, default for encoder
-#ifndef JSON_MAX_RECURSION_DEPTH
-#define JSON_MAX_RECURSION_DEPTH 1024
-#endif
-
-// Max recursion depth, default for decoder
-#ifndef JSON_MAX_OBJECT_DEPTH
-#define JSON_MAX_OBJECT_DEPTH 1024
-#endif
-
-/*
-Dictates and limits how much stack space for buffers UltraJSON will use before resorting to provided heap functions */
-#ifndef JSON_MAX_STACK_BUFFER_SIZE
-#define JSON_MAX_STACK_BUFFER_SIZE 131072
-#endif
-
-#ifdef _WIN32
-
-typedef __int64 JSINT64;
-typedef unsigned __int64 JSUINT64;
-
-typedef __int32 JSINT32;
-typedef unsigned __int32 JSUINT32;
-typedef unsigned __int8 JSUINT8;
-typedef unsigned __int16 JSUTF16;
-typedef unsigned __int32 JSUTF32;
-typedef __int64 JSLONG;
-
-#define EXPORTFUNCTION __declspec(dllexport)
-
-#define FASTCALL_MSVC __fastcall
-#define FASTCALL_ATTR
-#define INLINE_PREFIX __inline
-
-#else
-
-#include <stdint.h>
-typedef int64_t JSINT64;
-typedef uint64_t JSUINT64;
-
-typedef int32_t JSINT32;
-typedef uint32_t JSUINT32;
-
-#define FASTCALL_MSVC
-
-#if !defined __x86_64__
-#define FASTCALL_ATTR __attribute__((fastcall))
-#else
-#define FASTCALL_ATTR
-#endif
-
-
-#if defined(__clang__)
-#define INLINE_PREFIX inline __attribute__((always_inline))
-#else
-#define INLINE_PREFIX static inline
-#endif
-
-typedef uint8_t JSUINT8;
-typedef uint16_t JSUTF16;
-typedef uint32_t JSUTF32;
-
-typedef int64_t JSLONG;
-
-#define EXPORTFUNCTION
-#endif
-
-#if !(defined(__LITTLE_ENDIAN__) || defined(__BIG_ENDIAN__))
-
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-#define __LITTLE_ENDIAN__
-#else
-
-#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-#define __BIG_ENDIAN__
-#endif
-
-#endif
-
-#endif
-
-#if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
-#error "Endianess not supported"
-#endif
-
-enum JSTYPES
-{
- JT_NULL, // NULL
- JT_TRUE, // boolean true
- JT_FALSE, // boolean false
- JT_INT, // (JSINT32 (signed 32-bit))
- JT_LONG, // (JSINT64 (signed 64-bit))
- JT_ULONG, // (JSUINT64 (unsigned 64-bit))
- JT_DOUBLE, // (double)
- JT_UTF8, // (char 8-bit)
- JT_RAW, // (raw char 8-bit)
- JT_ARRAY, // Array structure
- JT_OBJECT, // Key/Value structure
- JT_INVALID, // Internal, do not return nor expect
-};
-
-typedef void * JSOBJ;
-typedef void * JSITER;
-
-typedef struct __JSONTypeContext
-{
- int type;
- void *prv;
- void *encoder_prv;
-} JSONTypeContext;
-
-/*
-Function pointer declarations, suitable for implementing UltraJSON */
-typedef int (*JSPFN_ITERNEXT)(JSOBJ obj, JSONTypeContext *tc);
-typedef void (*JSPFN_ITEREND)(JSOBJ obj, JSONTypeContext *tc);
-typedef JSOBJ (*JSPFN_ITERGETVALUE)(JSOBJ obj, JSONTypeContext *tc);
-typedef char *(*JSPFN_ITERGETNAME)(JSOBJ obj, JSONTypeContext *tc, size_t *outLen);
-typedef void *(*JSPFN_MALLOC)(size_t size);
-typedef void (*JSPFN_FREE)(void *pptr);
-typedef void *(*JSPFN_REALLOC)(void *base, size_t size);
-
-
-struct __JSONObjectEncoder;
-
-typedef struct __JSONObjectEncoder
-{
- void (*beginTypeContext)(JSOBJ obj, JSONTypeContext *tc, struct __JSONObjectEncoder *enc);
- void (*endTypeContext)(JSOBJ obj, JSONTypeContext *tc);
- const char *(*getStringValue)(JSOBJ obj, JSONTypeContext *tc, size_t *_outLen);
- JSINT64 (*getLongValue)(JSOBJ obj, JSONTypeContext *tc);
- JSUINT64 (*getUnsignedLongValue)(JSOBJ obj, JSONTypeContext *tc);
- JSINT32 (*getIntValue)(JSOBJ obj, JSONTypeContext *tc);
- double (*getDoubleValue)(JSOBJ obj, JSONTypeContext *tc);
-
- /*
- Retrieve next object in an iteration. Should return 0 to indicate iteration has reached end or 1 if there are more items.
- Implementor is responsible for keeping state of the iteration. Use ti->prv fields for this
- */
- JSPFN_ITERNEXT iterNext;
-
- /*
- Ends the iteration of an iteratable object.
- Any iteration state stored in ti->prv can be freed here
- */
- JSPFN_ITEREND iterEnd;
-
- /*
- Returns a reference to the value object of an iterator
- The is responsible for the life-cycle of the returned string. Use iterNext/iterEnd and ti->prv to keep track of current object
- */
- JSPFN_ITERGETVALUE iterGetValue;
-
- /*
- Return name of iterator.
- The is responsible for the life-cycle of the returned string. Use iterNext/iterEnd and ti->prv to keep track of current object
- */
- JSPFN_ITERGETNAME iterGetName;
-
- /*
- Release a value as indicated by setting ti->release = 1 in the previous getValue call.
- The ti->prv array should contain the necessary context to release the value
- */
- void (*releaseObject)(JSOBJ obj);
-
- /* Library functions
- Set to NULL to use STDLIB malloc,realloc,free */
- JSPFN_MALLOC malloc;
- JSPFN_REALLOC realloc;
- JSPFN_FREE free;
-
- /*
- Configuration for max recursion, set to 0 to use default (see JSON_MAX_RECURSION_DEPTH)*/
- int recursionMax;
-
- /*
- Configuration for max decimals of double floating point numbers to encode (0-9) */
- int doublePrecision;
-
- /*
- If true output will be ASCII with all characters above 127 encoded as \uXXXX. If false output will be UTF-8 or what ever charset strings are brought as */
- int forceASCII;
-
- /*
- If true, '<', '>', and '&' characters will be encoded as \u003c, \u003e, and \u0026, respectively. If false, no special encoding will be used. */
- int encodeHTMLChars;
-
- /*
- If true, '/' will be encoded as \/. If false, no escaping. */
- int escapeForwardSlashes;
-
- /*
- If true, dictionaries are iterated through in sorted key order. */
- int sortKeys;
-
- /*
- Configuration for spaces of indent */
- int indent;
-
- /*
- Private pointer to be used by the caller. Passed as encoder_prv in JSONTypeContext */
- void *prv;
-
- /*
- Set to an error message if error occured */
- const char *errorMsg;
- JSOBJ errorObj;
-
- /* Buffer stuff */
- char *start;
- char *offset;
- char *end;
- int heap;
- int level;
-
-} JSONObjectEncoder;
-
-
-/*
-Encode an object structure into JSON.
-
-Arguments:
-obj - An anonymous type representing the object
-enc - Function definitions for querying JSOBJ type
-buffer - Preallocated buffer to store result in. If NULL function allocates own buffer
-cbBuffer - Length of buffer (ignored if buffer is NULL)
-
-Returns:
-Encoded JSON object as a null terminated char string.
-
-NOTE:
-If the supplied buffer wasn't enough to hold the result the function will allocate a new buffer.
-Life cycle of the provided buffer must still be handled by caller.
-
-If the return value doesn't equal the specified buffer caller must release the memory using
-JSONObjectEncoder.free or free() as specified when calling this function.
-*/
-EXPORTFUNCTION char *JSON_EncodeObject(JSOBJ obj, JSONObjectEncoder *enc, char *buffer, size_t cbBuffer);
-
-
-
-typedef struct __JSONObjectDecoder
-{
- JSOBJ (*newString)(void *prv, wchar_t *start, wchar_t *end);
- void (*objectAddKey)(void *prv, JSOBJ obj, JSOBJ name, JSOBJ value);
- void (*arrayAddItem)(void *prv, JSOBJ obj, JSOBJ value);
- JSOBJ (*newTrue)(void *prv);
- JSOBJ (*newFalse)(void *prv);
- JSOBJ (*newNull)(void *prv);
- JSOBJ (*newObject)(void *prv);
- JSOBJ (*newArray)(void *prv);
- JSOBJ (*newInt)(void *prv, JSINT32 value);
- JSOBJ (*newLong)(void *prv, JSINT64 value);
- JSOBJ (*newUnsignedLong)(void *prv, JSUINT64 value);
- JSOBJ (*newDouble)(void *prv, double value);
- void (*releaseObject)(void *prv, JSOBJ obj);
- JSPFN_MALLOC malloc;
- JSPFN_FREE free;
- JSPFN_REALLOC realloc;
- char *errorStr;
- char *errorOffset;
- int preciseFloat;
- void *prv;
-} JSONObjectDecoder;
-
-EXPORTFUNCTION JSOBJ JSON_DecodeObject(JSONObjectDecoder *dec, const char *buffer, size_t cbBuffer);
-
-#endif
diff --git a/contrib/python/ujson/py2/lib/ultrajsondec.c b/contrib/python/ujson/py2/lib/ultrajsondec.c
deleted file mode 100644
index 21a732eceb..0000000000
--- a/contrib/python/ujson/py2/lib/ultrajsondec.c
+++ /dev/null
@@ -1,907 +0,0 @@
-/*
-Developed by ESN, an Electronic Arts Inc. studio.
-Copyright (c) 2014, Electronic Arts Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-* Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-* Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-* Neither the name of ESN, Electronic Arts Inc. nor the
-names of its contributors may be used to endorse or promote products
-derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS INC. 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.
-
-
-Portions of code from MODP_ASCII - Ascii transformations (upper/lower, etc)
-http://code.google.com/p/stringencoders/
-Copyright (c) 2007 Nick Galbreath -- nickg [at] modp [dot] com. All rights reserved.
-
-Numeric decoder derived from from TCL library
-http://www.opensource.apple.com/source/tcl/tcl-14/tcl/license.terms
-* Copyright (c) 1988-1993 The Regents of the University of California.
-* Copyright (c) 1994 Sun Microsystems, Inc.
-*/
-
-#include "ultrajson.h"
-#include <math.h>
-#include <assert.h>
-#include <string.h>
-#include <limits.h>
-#include <wchar.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif
-#ifndef NULL
-#define NULL 0
-#endif
-
-struct DecoderState
-{
- char *start;
- char *end;
- wchar_t *escStart;
- wchar_t *escEnd;
- int escHeap;
- int lastType;
- JSUINT32 objDepth;
- void *prv;
- JSONObjectDecoder *dec;
-};
-
-JSOBJ FASTCALL_MSVC decode_any( struct DecoderState *ds) FASTCALL_ATTR;
-typedef JSOBJ (*PFN_DECODER)( struct DecoderState *ds);
-
-static JSOBJ SetError( struct DecoderState *ds, int offset, const char *message)
-{
- ds->dec->errorOffset = ds->start + offset;
- ds->dec->errorStr = (char *) message;
- return NULL;
-}
-
-double createDouble(double intNeg, double intValue, double frcValue, int frcDecimalCount)
-{
- static const double g_pow10[] = {1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001,0.0000001, 0.00000001, 0.000000001, 0.0000000001, 0.00000000001, 0.000000000001, 0.0000000000001, 0.00000000000001, 0.000000000000001};
- return (intValue + (frcValue * g_pow10[frcDecimalCount])) * intNeg;
-}
-
-FASTCALL_ATTR JSOBJ FASTCALL_MSVC decodePreciseFloat(struct DecoderState *ds)
-{
- char *end;
- double value;
- errno = 0;
-
- value = strtod(ds->start, &end);
-
- if (errno == ERANGE)
- {
- return SetError(ds, -1, "Range error when decoding numeric as double");
- }
-
- ds->start = end;
- return ds->dec->newDouble(ds->prv, value);
-}
-
-FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_numeric (struct DecoderState *ds)
-{
- int intNeg = 1;
- int mantSize = 0;
- JSUINT64 intValue;
- JSUINT64 prevIntValue;
- int chr;
- int decimalCount = 0;
- double frcValue = 0.0;
- double expNeg;
- double expValue;
- char *offset = ds->start;
-
- JSUINT64 overflowLimit = LLONG_MAX;
-
- if (*(offset) == '-')
- {
- offset ++;
- intNeg = -1;
- overflowLimit = LLONG_MIN;
- }
-
- // Scan integer part
- intValue = 0;
-
- while (1)
- {
- chr = (int) (unsigned char) *(offset);
-
- switch (chr)
- {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- {
- //PERF: Don't do 64-bit arithmetic here unless we know we have to
- prevIntValue = intValue;
- intValue = intValue * 10ULL + (JSLONG) (chr - 48);
-
- if (intNeg == 1 && prevIntValue > intValue)
- {
- return SetError(ds, -1, "Value is too big!");
- }
- else if (intNeg == -1 && intValue > overflowLimit)
- {
- return SetError(ds, -1, overflowLimit == LLONG_MAX ? "Value is too big!" : "Value is too small");
- }
-
- offset ++;
- mantSize ++;
- break;
- }
- case '.':
- {
- offset ++;
- goto DECODE_FRACTION;
- break;
- }
- case 'e':
- case 'E':
- {
- offset ++;
- goto DECODE_EXPONENT;
- break;
- }
-
- default:
- {
- goto BREAK_INT_LOOP;
- break;
- }
- }
- }
-
-BREAK_INT_LOOP:
-
- ds->lastType = JT_INT;
- ds->start = offset;
-
- if (intNeg == 1 && (intValue & 0x8000000000000000ULL) != 0)
- {
- return ds->dec->newUnsignedLong(ds->prv, intValue);
- }
- else if ((intValue >> 31))
- {
- return ds->dec->newLong(ds->prv, (JSINT64) (intValue * (JSINT64) intNeg));
- }
- else
- {
- return ds->dec->newInt(ds->prv, (JSINT32) (intValue * intNeg));
- }
-
-DECODE_FRACTION:
-
- if (ds->dec->preciseFloat)
- {
- return decodePreciseFloat(ds);
- }
-
- // Scan fraction part
- frcValue = 0.0;
- for (;;)
- {
- chr = (int) (unsigned char) *(offset);
-
- switch (chr)
- {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- {
- if (decimalCount < JSON_DOUBLE_MAX_DECIMALS)
- {
- frcValue = frcValue * 10.0 + (double) (chr - 48);
- decimalCount ++;
- }
- offset ++;
- break;
- }
- case 'e':
- case 'E':
- {
- offset ++;
- goto DECODE_EXPONENT;
- break;
- }
- default:
- {
- goto BREAK_FRC_LOOP;
- }
- }
- }
-
-BREAK_FRC_LOOP:
- //FIXME: Check for arithemtic overflow here
- ds->lastType = JT_DOUBLE;
- ds->start = offset;
- return ds->dec->newDouble (ds->prv, createDouble( (double) intNeg, (double) intValue, frcValue, decimalCount));
-
-DECODE_EXPONENT:
- if (ds->dec->preciseFloat)
- {
- return decodePreciseFloat(ds);
- }
-
- expNeg = 1.0;
-
- if (*(offset) == '-')
- {
- expNeg = -1.0;
- offset ++;
- }
- else
- if (*(offset) == '+')
- {
- expNeg = +1.0;
- offset ++;
- }
-
- expValue = 0.0;
-
- for (;;)
- {
- chr = (int) (unsigned char) *(offset);
-
- switch (chr)
- {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- {
- expValue = expValue * 10.0 + (double) (chr - 48);
- offset ++;
- break;
- }
- default:
- {
- goto BREAK_EXP_LOOP;
- }
- }
- }
-
-BREAK_EXP_LOOP:
- //FIXME: Check for arithemtic overflow here
- ds->lastType = JT_DOUBLE;
- ds->start = offset;
- return ds->dec->newDouble (ds->prv, createDouble( (double) intNeg, (double) intValue , frcValue, decimalCount) * pow(10.0, expValue * expNeg));
-}
-
-FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_true ( struct DecoderState *ds)
-{
- char *offset = ds->start;
- offset ++;
-
- if (*(offset++) != 'r')
- goto SETERROR;
- if (*(offset++) != 'u')
- goto SETERROR;
- if (*(offset++) != 'e')
- goto SETERROR;
-
- ds->lastType = JT_TRUE;
- ds->start = offset;
- return ds->dec->newTrue(ds->prv);
-
-SETERROR:
- return SetError(ds, -1, "Unexpected character found when decoding 'true'");
-}
-
-FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_false ( struct DecoderState *ds)
-{
- char *offset = ds->start;
- offset ++;
-
- if (*(offset++) != 'a')
- goto SETERROR;
- if (*(offset++) != 'l')
- goto SETERROR;
- if (*(offset++) != 's')
- goto SETERROR;
- if (*(offset++) != 'e')
- goto SETERROR;
-
- ds->lastType = JT_FALSE;
- ds->start = offset;
- return ds->dec->newFalse(ds->prv);
-
-SETERROR:
- return SetError(ds, -1, "Unexpected character found when decoding 'false'");
-}
-
-FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_null ( struct DecoderState *ds)
-{
- char *offset = ds->start;
- offset ++;
-
- if (*(offset++) != 'u')
- goto SETERROR;
- if (*(offset++) != 'l')
- goto SETERROR;
- if (*(offset++) != 'l')
- goto SETERROR;
-
- ds->lastType = JT_NULL;
- ds->start = offset;
- return ds->dec->newNull(ds->prv);
-
-SETERROR:
- return SetError(ds, -1, "Unexpected character found when decoding 'null'");
-}
-
-FASTCALL_ATTR void FASTCALL_MSVC SkipWhitespace(struct DecoderState *ds)
-{
- char *offset = ds->start;
-
- for (;;)
- {
- switch (*offset)
- {
- case ' ':
- case '\t':
- case '\r':
- case '\n':
- offset ++;
- break;
-
- default:
- ds->start = offset;
- return;
- }
- }
-}
-
-enum DECODESTRINGSTATE
-{
- DS_ISNULL = 0x32,
- DS_ISQUOTE,
- DS_ISESCAPE,
- DS_UTFLENERROR,
-
-};
-
-static const JSUINT8 g_decoderLookup[256] =
-{
- /* 0x00 */ DS_ISNULL, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- /* 0x10 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- /* 0x20 */ 1, 1, DS_ISQUOTE, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- /* 0x30 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- /* 0x40 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- /* 0x50 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, DS_ISESCAPE, 1, 1, 1,
- /* 0x60 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- /* 0x70 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- /* 0x80 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- /* 0x90 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- /* 0xa0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- /* 0xb0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- /* 0xc0 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- /* 0xd0 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- /* 0xe0 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- /* 0xf0 */ 4, 4, 4, 4, 4, 4, 4, 4, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR,
-};
-
-FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_string ( struct DecoderState *ds)
-{
- JSUTF16 sur[2] = { 0 };
- int iSur = 0;
- int index;
- wchar_t *escOffset;
- wchar_t *escStart;
- size_t escLen = (ds->escEnd - ds->escStart);
- JSUINT8 *inputOffset;
- JSUINT8 oct;
- JSUTF32 ucs;
- ds->lastType = JT_INVALID;
- ds->start ++;
-
- if ( (size_t) (ds->end - ds->start) > escLen)
- {
- size_t newSize = (ds->end - ds->start);
-
- if (ds->escHeap)
- {
- if (newSize > (SIZE_MAX / sizeof(wchar_t)))
- {
- return SetError(ds, -1, "Could not reserve memory block");
- }
- escStart = (wchar_t *)ds->dec->realloc(ds->escStart, newSize * sizeof(wchar_t));
- if (!escStart)
- {
- ds->dec->free(ds->escStart);
- return SetError(ds, -1, "Could not reserve memory block");
- }
- ds->escStart = escStart;
- }
- else
- {
- wchar_t *oldStart = ds->escStart;
- if (newSize > (SIZE_MAX / sizeof(wchar_t)))
- {
- return SetError(ds, -1, "Could not reserve memory block");
- }
- ds->escStart = (wchar_t *) ds->dec->malloc(newSize * sizeof(wchar_t));
- if (!ds->escStart)
- {
- return SetError(ds, -1, "Could not reserve memory block");
- }
- ds->escHeap = 1;
- memcpy(ds->escStart, oldStart, escLen * sizeof(wchar_t));
- }
-
- ds->escEnd = ds->escStart + newSize;
- }
-
- escOffset = ds->escStart;
- inputOffset = (JSUINT8 *) ds->start;
-
- for (;;)
- {
- switch (g_decoderLookup[(JSUINT8)(*inputOffset)])
- {
- case DS_ISNULL:
- {
- return SetError(ds, -1, "Unmatched ''\"' when when decoding 'string'");
- }
- case DS_ISQUOTE:
- {
- ds->lastType = JT_UTF8;
- inputOffset ++;
- ds->start += ( (char *) inputOffset - (ds->start));
- return ds->dec->newString(ds->prv, ds->escStart, escOffset);
- }
- case DS_UTFLENERROR:
- {
- return SetError (ds, -1, "Invalid UTF-8 sequence length when decoding 'string'");
- }
- case DS_ISESCAPE:
- inputOffset ++;
- switch (*inputOffset)
- {
- case '\\': *(escOffset++) = L'\\'; inputOffset++; continue;
- case '\"': *(escOffset++) = L'\"'; inputOffset++; continue;
- case '/': *(escOffset++) = L'/'; inputOffset++; continue;
- case 'b': *(escOffset++) = L'\b'; inputOffset++; continue;
- case 'f': *(escOffset++) = L'\f'; inputOffset++; continue;
- case 'n': *(escOffset++) = L'\n'; inputOffset++; continue;
- case 'r': *(escOffset++) = L'\r'; inputOffset++; continue;
- case 't': *(escOffset++) = L'\t'; inputOffset++; continue;
-
- case 'u':
- {
- int index;
- inputOffset ++;
-
- for (index = 0; index < 4; index ++)
- {
- switch (*inputOffset)
- {
- case '\0': return SetError (ds, -1, "Unterminated unicode escape sequence when decoding 'string'");
- default: return SetError (ds, -1, "Unexpected character in unicode escape sequence when decoding 'string'");
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- sur[iSur] = (sur[iSur] << 4) + (JSUTF16) (*inputOffset - '0');
- break;
-
- case 'a':
- case 'b':
- case 'c':
- case 'd':
- case 'e':
- case 'f':
- sur[iSur] = (sur[iSur] << 4) + 10 + (JSUTF16) (*inputOffset - 'a');
- break;
-
- case 'A':
- case 'B':
- case 'C':
- case 'D':
- case 'E':
- case 'F':
- sur[iSur] = (sur[iSur] << 4) + 10 + (JSUTF16) (*inputOffset - 'A');
- break;
- }
-
- inputOffset ++;
- }
-
- if (iSur == 0)
- {
- if((sur[iSur] & 0xfc00) == 0xd800)
- {
- // First of a surrogate pair, continue parsing
- iSur ++;
- break;
- }
- (*escOffset++) = (wchar_t) sur[iSur];
- iSur = 0;
- }
- else
- {
- // Decode pair
- if ((sur[1] & 0xfc00) != 0xdc00)
- {
- return SetError (ds, -1, "Unpaired high surrogate when decoding 'string'");
- }
-#if WCHAR_MAX == 0xffff
- (*escOffset++) = (wchar_t) sur[0];
- (*escOffset++) = (wchar_t) sur[1];
-#else
- (*escOffset++) = (wchar_t) 0x10000 + (((sur[0] - 0xd800) << 10) | (sur[1] - 0xdc00));
-#endif
- iSur = 0;
- }
- break;
- }
-
- case '\0': return SetError(ds, -1, "Unterminated escape sequence when decoding 'string'");
- default: return SetError(ds, -1, "Unrecognized escape sequence when decoding 'string'");
- }
- break;
-
- case 1:
- {
- *(escOffset++) = (wchar_t) (*inputOffset++);
- break;
- }
-
- case 2:
- {
- ucs = (*inputOffset++) & 0x1f;
- ucs <<= 6;
- if (((*inputOffset) & 0x80) != 0x80)
- {
- return SetError(ds, -1, "Invalid octet in UTF-8 sequence when decoding 'string'");
- }
- ucs |= (*inputOffset++) & 0x3f;
- if (ucs < 0x80) return SetError (ds, -1, "Overlong 2 byte UTF-8 sequence detected when decoding 'string'");
- *(escOffset++) = (wchar_t) ucs;
- break;
- }
-
- case 3:
- {
- JSUTF32 ucs = 0;
- ucs |= (*inputOffset++) & 0x0f;
-
- for (index = 0; index < 2; index ++)
- {
- ucs <<= 6;
- oct = (*inputOffset++);
-
- if ((oct & 0x80) != 0x80)
- {
- return SetError(ds, -1, "Invalid octet in UTF-8 sequence when decoding 'string'");
- }
-
- ucs |= oct & 0x3f;
- }
-
- if (ucs < 0x800) return SetError (ds, -1, "Overlong 3 byte UTF-8 sequence detected when encoding string");
- *(escOffset++) = (wchar_t) ucs;
- break;
- }
-
- case 4:
- {
- JSUTF32 ucs = 0;
- ucs |= (*inputOffset++) & 0x07;
-
- for (index = 0; index < 3; index ++)
- {
- ucs <<= 6;
- oct = (*inputOffset++);
-
- if ((oct & 0x80) != 0x80)
- {
- return SetError(ds, -1, "Invalid octet in UTF-8 sequence when decoding 'string'");
- }
-
- ucs |= oct & 0x3f;
- }
-
- if (ucs < 0x10000) return SetError (ds, -1, "Overlong 4 byte UTF-8 sequence detected when decoding 'string'");
-
-#if WCHAR_MAX == 0xffff
- if (ucs >= 0x10000)
- {
- ucs -= 0x10000;
- *(escOffset++) = (wchar_t) (ucs >> 10) + 0xd800;
- *(escOffset++) = (wchar_t) (ucs & 0x3ff) + 0xdc00;
- }
- else
- {
- *(escOffset++) = (wchar_t) ucs;
- }
-#else
- *(escOffset++) = (wchar_t) ucs;
-#endif
- break;
- }
- }
- }
-}
-
-FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_array(struct DecoderState *ds)
-{
- JSOBJ itemValue;
- JSOBJ newObj;
- int len;
- ds->objDepth++;
- if (ds->objDepth > JSON_MAX_OBJECT_DEPTH) {
- return SetError(ds, -1, "Reached object decoding depth limit");
- }
-
- newObj = ds->dec->newArray(ds->prv);
- len = 0;
-
- ds->lastType = JT_INVALID;
- ds->start ++;
-
- for (;;)
- {
- SkipWhitespace(ds);
-
- if ((*ds->start) == ']')
- {
- ds->objDepth--;
- if (len == 0)
- {
- ds->start ++;
- return newObj;
- }
-
- ds->dec->releaseObject(ds->prv, newObj);
- return SetError(ds, -1, "Unexpected character found when decoding array value (1)");
- }
-
- itemValue = decode_any(ds);
-
- if (itemValue == NULL)
- {
- ds->dec->releaseObject(ds->prv, newObj);
- return NULL;
- }
-
- ds->dec->arrayAddItem (ds->prv, newObj, itemValue);
-
- SkipWhitespace(ds);
-
- switch (*(ds->start++))
- {
- case ']':
- {
- ds->objDepth--;
- return newObj;
- }
- case ',':
- break;
-
- default:
- ds->dec->releaseObject(ds->prv, newObj);
- return SetError(ds, -1, "Unexpected character found when decoding array value (2)");
- }
-
- len ++;
- }
-}
-
-FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_object( struct DecoderState *ds)
-{
- JSOBJ itemName;
- JSOBJ itemValue;
- JSOBJ newObj;
-
- ds->objDepth++;
- if (ds->objDepth > JSON_MAX_OBJECT_DEPTH) {
- return SetError(ds, -1, "Reached object decoding depth limit");
- }
-
- newObj = ds->dec->newObject(ds->prv);
-
- ds->start ++;
-
- for (;;)
- {
- SkipWhitespace(ds);
-
- if ((*ds->start) == '}')
- {
- ds->objDepth--;
- ds->start ++;
- return newObj;
- }
-
- ds->lastType = JT_INVALID;
- itemName = decode_any(ds);
-
- if (itemName == NULL)
- {
- ds->dec->releaseObject(ds->prv, newObj);
- return NULL;
- }
-
- if (ds->lastType != JT_UTF8)
- {
- ds->dec->releaseObject(ds->prv, newObj);
- ds->dec->releaseObject(ds->prv, itemName);
- return SetError(ds, -1, "Key name of object must be 'string' when decoding 'object'");
- }
-
- SkipWhitespace(ds);
-
- if (*(ds->start++) != ':')
- {
- ds->dec->releaseObject(ds->prv, newObj);
- ds->dec->releaseObject(ds->prv, itemName);
- return SetError(ds, -1, "No ':' found when decoding object value");
- }
-
- SkipWhitespace(ds);
-
- itemValue = decode_any(ds);
-
- if (itemValue == NULL)
- {
- ds->dec->releaseObject(ds->prv, newObj);
- ds->dec->releaseObject(ds->prv, itemName);
- return NULL;
- }
-
- ds->dec->objectAddKey (ds->prv, newObj, itemName, itemValue);
-
- SkipWhitespace(ds);
-
- switch (*(ds->start++))
- {
- case '}':
- {
- ds->objDepth--;
- return newObj;
- }
- case ',':
- break;
-
- default:
- ds->dec->releaseObject(ds->prv, newObj);
- return SetError(ds, -1, "Unexpected character in found when decoding object value");
- }
- }
-}
-
-FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_any(struct DecoderState *ds)
-{
- for (;;)
- {
- switch (*ds->start)
- {
- case '\"':
- return decode_string (ds);
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case '-':
- return decode_numeric (ds);
-
- case '[': return decode_array (ds);
- case '{': return decode_object (ds);
- case 't': return decode_true (ds);
- case 'f': return decode_false (ds);
- case 'n': return decode_null (ds);
-
- case ' ':
- case '\t':
- case '\r':
- case '\n':
- // White space
- ds->start ++;
- break;
-
- default:
- return SetError(ds, -1, "Expected object or value");
- }
- }
-}
-
-JSOBJ JSON_DecodeObject(JSONObjectDecoder *dec, const char *buffer, size_t cbBuffer)
-{
- /*
- FIXME: Base the size of escBuffer of that of cbBuffer so that the unicode escaping doesn't run into the wall each time */
- struct DecoderState ds;
- wchar_t escBuffer[(JSON_MAX_STACK_BUFFER_SIZE / sizeof(wchar_t))];
- JSOBJ ret;
-
- ds.start = (char *) buffer;
- ds.end = ds.start + cbBuffer;
-
- ds.escStart = escBuffer;
- ds.escEnd = ds.escStart + (JSON_MAX_STACK_BUFFER_SIZE / sizeof(wchar_t));
- ds.escHeap = 0;
- ds.prv = dec->prv;
- ds.dec = dec;
- ds.dec->errorStr = NULL;
- ds.dec->errorOffset = NULL;
- ds.objDepth = 0;
-
- ds.dec = dec;
-
- ret = decode_any (&ds);
-
- if (ds.escHeap)
- {
- dec->free(ds.escStart);
- }
-
- if (!(dec->errorStr))
- {
- if ((ds.end - ds.start) > 0)
- {
- SkipWhitespace(&ds);
- }
-
- if (ds.start != ds.end && ret)
- {
- dec->releaseObject(ds.prv, ret);
- return SetError(&ds, -1, "Trailing data");
- }
- }
-
- return ret;
-}
diff --git a/contrib/python/ujson/py2/lib/ultrajsonenc.c b/contrib/python/ujson/py2/lib/ultrajsonenc.c
deleted file mode 100644
index ed6645a760..0000000000
--- a/contrib/python/ujson/py2/lib/ultrajsonenc.c
+++ /dev/null
@@ -1,1029 +0,0 @@
-/*
-Developed by ESN, an Electronic Arts Inc. studio.
-Copyright (c) 2014, Electronic Arts Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-* Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-* Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-* Neither the name of ESN, Electronic Arts Inc. nor the
-names of its contributors may be used to endorse or promote products
-derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS INC. 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.
-
-
-Portions of code from MODP_ASCII - Ascii transformations (upper/lower, etc)
-http://code.google.com/p/stringencoders/
-Copyright (c) 2007 Nick Galbreath -- nickg [at] modp [dot] com. All rights reserved.
-
-Numeric decoder derived from from TCL library
-http://www.opensource.apple.com/source/tcl/tcl-14/tcl/license.terms
- * Copyright (c) 1988-1993 The Regents of the University of California.
- * Copyright (c) 1994 Sun Microsystems, Inc.
-*/
-
-#include "ultrajson.h"
-#include <stdio.h>
-#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
-#include <math.h>
-
-#include <float.h>
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#if ( (defined(_WIN32) || defined(WIN32) ) && ( defined(_MSC_VER) ) )
-#define snprintf sprintf_s
-#endif
-
-/*
-Worst cases being:
-
-Control characters (ASCII < 32)
-0x00 (1 byte) input => \u0000 output (6 bytes)
-1 * 6 => 6 (6 bytes required)
-
-or UTF-16 surrogate pairs
-4 bytes input in UTF-8 => \uXXXX\uYYYY (12 bytes).
-
-4 * 6 => 24 bytes (12 bytes required)
-
-The extra 2 bytes are for the quotes around the string
-
-*/
-#define RESERVE_STRING(_len) (2 + ((_len) * 6))
-
-static const double g_pow10[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000};
-static const char g_hexChars[] = "0123456789abcdef";
-static const char g_escapeChars[] = "0123456789\\b\\t\\n\\f\\r\\\"\\\\\\/";
-
-/*
-FIXME: While this is fine dandy and working it's a magic value mess which probably only the author understands.
-Needs a cleanup and more documentation */
-
-/*
-Table for pure ascii output escaping all characters above 127 to \uXXXX */
-static const JSUINT8 g_asciiOutputTable[256] =
-{
-/* 0x00 */ 0, 30, 30, 30, 30, 30, 30, 30, 10, 12, 14, 30, 16, 18, 30, 30,
-/* 0x10 */ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
-/* 0x20 */ 1, 1, 20, 1, 1, 1, 29, 1, 1, 1, 1, 1, 1, 1, 1, 24,
-/* 0x30 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 29, 1, 29, 1,
-/* 0x40 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-/* 0x50 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 22, 1, 1, 1,
-/* 0x60 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-/* 0x70 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-/* 0x80 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-/* 0x90 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-/* 0xa0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-/* 0xb0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-/* 0xc0 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-/* 0xd0 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-/* 0xe0 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-/* 0xf0 */ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1
-};
-
-static void SetError (JSOBJ obj, JSONObjectEncoder *enc, const char *message)
-{
- enc->errorMsg = message;
- enc->errorObj = obj;
-}
-
-/*
-FIXME: Keep track of how big these get across several encoder calls and try to make an estimate
-That way we won't run our head into the wall each call */
-void Buffer_Realloc (JSONObjectEncoder *enc, size_t cbNeeded)
-{
- size_t curSize = enc->end - enc->start;
- size_t newSize = curSize * 2;
- size_t offset = enc->offset - enc->start;
-
- while (newSize < curSize + cbNeeded)
- {
- newSize *= 2;
- }
-
- if (enc->heap)
- {
- enc->start = (char *) enc->realloc (enc->start, newSize);
- if (!enc->start)
- {
- SetError (NULL, enc, "Could not reserve memory block");
- return;
- }
- }
- else
- {
- char *oldStart = enc->start;
- enc->heap = 1;
- enc->start = (char *) enc->malloc (newSize);
- if (!enc->start)
- {
- SetError (NULL, enc, "Could not reserve memory block");
- return;
- }
- memcpy (enc->start, oldStart, offset);
- }
- enc->offset = enc->start + offset;
- enc->end = enc->start + newSize;
-}
-
-FASTCALL_ATTR INLINE_PREFIX void FASTCALL_MSVC Buffer_AppendShortHexUnchecked (char *outputOffset, unsigned short value)
-{
- *(outputOffset++) = g_hexChars[(value & 0xf000) >> 12];
- *(outputOffset++) = g_hexChars[(value & 0x0f00) >> 8];
- *(outputOffset++) = g_hexChars[(value & 0x00f0) >> 4];
- *(outputOffset++) = g_hexChars[(value & 0x000f) >> 0];
-}
-
-int Buffer_EscapeStringUnvalidated (JSONObjectEncoder *enc, const char *io, const char *end)
-{
- char *of = (char *) enc->offset;
-
- for (;;)
- {
- switch (*io)
- {
- case 0x00:
- {
- if (io < end)
- {
- *(of++) = '\\';
- *(of++) = 'u';
- *(of++) = '0';
- *(of++) = '0';
- *(of++) = '0';
- *(of++) = '0';
- break;
- }
- else
- {
- enc->offset += (of - enc->offset);
- return TRUE;
- }
- }
- case '\"': (*of++) = '\\'; (*of++) = '\"'; break;
- case '\\': (*of++) = '\\'; (*of++) = '\\'; break;
- case '\b': (*of++) = '\\'; (*of++) = 'b'; break;
- case '\f': (*of++) = '\\'; (*of++) = 'f'; break;
- case '\n': (*of++) = '\\'; (*of++) = 'n'; break;
- case '\r': (*of++) = '\\'; (*of++) = 'r'; break;
- case '\t': (*of++) = '\\'; (*of++) = 't'; break;
-
- case '/':
- {
- if (enc->escapeForwardSlashes)
- {
- (*of++) = '\\';
- (*of++) = '/';
- }
- else
- {
- // Same as default case below.
- (*of++) = (*io);
- }
- break;
- }
- case 0x26: // '&'
- case 0x3c: // '<'
- case 0x3e: // '>'
- {
- if (enc->encodeHTMLChars)
- {
- // Fall through to \u00XX case below.
- }
- else
- {
- // Same as default case below.
- (*of++) = (*io);
- break;
- }
- }
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x04:
- case 0x05:
- case 0x06:
- case 0x07:
- case 0x0b:
- case 0x0e:
- case 0x0f:
- case 0x10:
- case 0x11:
- case 0x12:
- case 0x13:
- case 0x14:
- case 0x15:
- case 0x16:
- case 0x17:
- case 0x18:
- case 0x19:
- case 0x1a:
- case 0x1b:
- case 0x1c:
- case 0x1d:
- case 0x1e:
- case 0x1f:
- {
- *(of++) = '\\';
- *(of++) = 'u';
- *(of++) = '0';
- *(of++) = '0';
- *(of++) = g_hexChars[ (unsigned char) (((*io) & 0xf0) >> 4)];
- *(of++) = g_hexChars[ (unsigned char) ((*io) & 0x0f)];
- break;
- }
- default: (*of++) = (*io); break;
- }
- io++;
- }
-}
-
-int Buffer_EscapeStringValidated (JSOBJ obj, JSONObjectEncoder *enc, const char *io, const char *end)
-{
- JSUTF32 ucs;
- char *of = (char *) enc->offset;
-
- for (;;)
- {
- JSUINT8 utflen = g_asciiOutputTable[(unsigned char) *io];
-
- switch (utflen)
- {
- case 0:
- {
- if (io < end)
- {
- *(of++) = '\\';
- *(of++) = 'u';
- *(of++) = '0';
- *(of++) = '0';
- *(of++) = '0';
- *(of++) = '0';
- io ++;
- continue;
- }
- else
- {
- enc->offset += (of - enc->offset);
- return TRUE;
- }
- }
-
- case 1:
- {
- *(of++)= (*io++);
- continue;
- }
-
- case 2:
- {
- JSUTF32 in;
- JSUTF16 in16;
-
- if (end - io < 1)
- {
- enc->offset += (of - enc->offset);
- SetError (obj, enc, "Unterminated UTF-8 sequence when encoding string");
- return FALSE;
- }
-
- memcpy(&in16, io, sizeof(JSUTF16));
- in = (JSUTF32) in16;
-
-#ifdef __LITTLE_ENDIAN__
- ucs = ((in & 0x1f) << 6) | ((in >> 8) & 0x3f);
-#else
- ucs = ((in & 0x1f00) >> 2) | (in & 0x3f);
-#endif
-
- if (ucs < 0x80)
- {
- enc->offset += (of - enc->offset);
- SetError (obj, enc, "Overlong 2 byte UTF-8 sequence detected when encoding string");
- return FALSE;
- }
-
- io += 2;
- break;
- }
-
- case 3:
- {
- JSUTF32 in;
- JSUTF16 in16;
- JSUINT8 in8;
-
- if (end - io < 2)
- {
- enc->offset += (of - enc->offset);
- SetError (obj, enc, "Unterminated UTF-8 sequence when encoding string");
- return FALSE;
- }
-
- memcpy(&in16, io, sizeof(JSUTF16));
- memcpy(&in8, io + 2, sizeof(JSUINT8));
-#ifdef __LITTLE_ENDIAN__
- in = (JSUTF32) in16;
- in |= in8 << 16;
- ucs = ((in & 0x0f) << 12) | ((in & 0x3f00) >> 2) | ((in & 0x3f0000) >> 16);
-#else
- in = in16 << 8;
- in |= in8;
- ucs = ((in & 0x0f0000) >> 4) | ((in & 0x3f00) >> 2) | (in & 0x3f);
-#endif
-
- if (ucs < 0x800)
- {
- enc->offset += (of - enc->offset);
- SetError (obj, enc, "Overlong 3 byte UTF-8 sequence detected when encoding string");
- return FALSE;
- }
-
- io += 3;
- break;
- }
- case 4:
- {
- JSUTF32 in;
-
- if (end - io < 3)
- {
- enc->offset += (of - enc->offset);
- SetError (obj, enc, "Unterminated UTF-8 sequence when encoding string");
- return FALSE;
- }
-
- memcpy(&in, io, sizeof(JSUTF32));
-#ifdef __LITTLE_ENDIAN__
- ucs = ((in & 0x07) << 18) | ((in & 0x3f00) << 4) | ((in & 0x3f0000) >> 10) | ((in & 0x3f000000) >> 24);
-#else
- ucs = ((in & 0x07000000) >> 6) | ((in & 0x3f0000) >> 4) | ((in & 0x3f00) >> 2) | (in & 0x3f);
-#endif
- if (ucs < 0x10000)
- {
- enc->offset += (of - enc->offset);
- SetError (obj, enc, "Overlong 4 byte UTF-8 sequence detected when encoding string");
- return FALSE;
- }
-
- io += 4;
- break;
- }
-
-
- case 5:
- case 6:
- {
- enc->offset += (of - enc->offset);
- SetError (obj, enc, "Unsupported UTF-8 sequence length when encoding string");
- return FALSE;
- }
-
- case 29:
- {
- if (enc->encodeHTMLChars)
- {
- // Fall through to \u00XX case 30 below.
- }
- else
- {
- // Same as case 1 above.
- *(of++) = (*io++);
- continue;
- }
- }
-
- case 30:
- {
- // \uXXXX encode
- *(of++) = '\\';
- *(of++) = 'u';
- *(of++) = '0';
- *(of++) = '0';
- *(of++) = g_hexChars[ (unsigned char) (((*io) & 0xf0) >> 4)];
- *(of++) = g_hexChars[ (unsigned char) ((*io) & 0x0f)];
- io ++;
- continue;
- }
- case 10:
- case 12:
- case 14:
- case 16:
- case 18:
- case 20:
- case 22:
- {
- *(of++) = *( (char *) (g_escapeChars + utflen + 0));
- *(of++) = *( (char *) (g_escapeChars + utflen + 1));
- io ++;
- continue;
- }
- case 24:
- {
- if (enc->escapeForwardSlashes)
- {
- *(of++) = *( (char *) (g_escapeChars + utflen + 0));
- *(of++) = *( (char *) (g_escapeChars + utflen + 1));
- io ++;
- }
- else
- {
- // Same as case 1 above.
- *(of++) = (*io++);
- }
- continue;
- }
- // This can never happen, it's here to make L4 VC++ happy
- default:
- {
- ucs = 0;
- break;
- }
- }
-
- /*
- If the character is a UTF8 sequence of length > 1 we end up here */
- if (ucs >= 0x10000)
- {
- ucs -= 0x10000;
- *(of++) = '\\';
- *(of++) = 'u';
- Buffer_AppendShortHexUnchecked(of, (unsigned short) (ucs >> 10) + 0xd800);
- of += 4;
-
- *(of++) = '\\';
- *(of++) = 'u';
- Buffer_AppendShortHexUnchecked(of, (unsigned short) (ucs & 0x3ff) + 0xdc00);
- of += 4;
- }
- else
- {
- *(of++) = '\\';
- *(of++) = 'u';
- Buffer_AppendShortHexUnchecked(of, (unsigned short) ucs);
- of += 4;
- }
- }
-}
-
-#define Buffer_Reserve(__enc, __len) \
- if ( (size_t) ((__enc)->end - (__enc)->offset) < (size_t) (__len)) \
- { \
- Buffer_Realloc((__enc), (__len));\
- } \
-
-
-#define Buffer_AppendCharUnchecked(__enc, __chr) \
- *((__enc)->offset++) = __chr; \
-
-FASTCALL_ATTR INLINE_PREFIX void FASTCALL_MSVC strreverse(char* begin, char* end)
-{
- char aux;
- while (end > begin)
- aux = *end, *end-- = *begin, *begin++ = aux;
-}
-
-void Buffer_AppendIndentNewlineUnchecked(JSONObjectEncoder *enc)
-{
- if (enc->indent > 0) Buffer_AppendCharUnchecked(enc, '\n');
-}
-
-void Buffer_AppendIndentUnchecked(JSONObjectEncoder *enc, JSINT32 value)
-{
- int i;
- if (enc->indent > 0)
- while (value-- > 0)
- for (i = 0; i < enc->indent; i++)
- Buffer_AppendCharUnchecked(enc, ' ');
-}
-
-void Buffer_AppendIntUnchecked(JSONObjectEncoder *enc, JSINT32 value)
-{
- char* wstr;
- JSUINT32 uvalue = (value < 0) ? -value : value;
-
- wstr = enc->offset;
- // Conversion. Number is reversed.
-
- do *wstr++ = (char)(48 + (uvalue % 10)); while(uvalue /= 10);
- if (value < 0) *wstr++ = '-';
-
- // Reverse string
- strreverse(enc->offset,wstr - 1);
- enc->offset += (wstr - (enc->offset));
-}
-
-void Buffer_AppendLongUnchecked(JSONObjectEncoder *enc, JSINT64 value)
-{
- char* wstr;
- JSUINT64 uvalue = (value < 0) ? -value : value;
-
- wstr = enc->offset;
- // Conversion. Number is reversed.
-
- do *wstr++ = (char)(48 + (uvalue % 10ULL)); while(uvalue /= 10ULL);
- if (value < 0) *wstr++ = '-';
-
- // Reverse string
- strreverse(enc->offset,wstr - 1);
- enc->offset += (wstr - (enc->offset));
-}
-
-void Buffer_AppendUnsignedLongUnchecked(JSONObjectEncoder *enc, JSUINT64 value)
-{
- char* wstr;
- JSUINT64 uvalue = value;
-
- wstr = enc->offset;
- // Conversion. Number is reversed.
-
- do *wstr++ = (char)(48 + (uvalue % 10ULL)); while(uvalue /= 10ULL);
-
- // Reverse string
- strreverse(enc->offset,wstr - 1);
- enc->offset += (wstr - (enc->offset));
-}
-
-int Buffer_AppendDoubleUnchecked(JSOBJ obj, JSONObjectEncoder *enc, double value)
-{
- /* if input is larger than thres_max, revert to exponential */
- const double thres_max = (double) 1e16 - 1;
- int count;
- double diff = 0.0;
- char* str = enc->offset;
- char* wstr = str;
- unsigned long long whole;
- double tmp;
- unsigned long long frac;
- int neg;
- double pow10;
-
- if (value == HUGE_VAL || value == -HUGE_VAL)
- {
- SetError (obj, enc, "Invalid Inf value when encoding double");
- return FALSE;
- }
-
- if (!(value == value))
- {
- SetError (obj, enc, "Invalid Nan value when encoding double");
- return FALSE;
- }
-
- /* we'll work in positive values and deal with the
- negative sign issue later */
- neg = 0;
- if (value < 0)
- {
- neg = 1;
- value = -value;
- }
-
- pow10 = g_pow10[enc->doublePrecision];
-
- whole = (unsigned long long) value;
- tmp = (value - whole) * pow10;
- frac = (unsigned long long)(tmp);
- diff = tmp - frac;
-
- if (diff > 0.5)
- {
- ++frac;
- /* handle rollover, e.g. case 0.99 with prec 1 is 1.0 */
- if (frac >= pow10)
- {
- frac = 0;
- ++whole;
- }
- }
- else
- if (diff == 0.5 && ((frac == 0) || (frac & 1)))
- {
- /* if halfway, round up if odd, OR
- if last digit is 0. That last part is strange */
- ++frac;
- }
-
- /* for very large numbers switch back to native sprintf for exponentials.
- anyone want to write code to replace this? */
- /*
- normal printf behavior is to print EVERY whole number digit
- which can be 100s of characters overflowing your buffers == bad
- */
- if (value > thres_max)
- {
- enc->offset += snprintf(str, enc->end - enc->offset, "%.15e", neg ? -value : value);
- return TRUE;
- }
-
- if (enc->doublePrecision == 0)
- {
- diff = value - whole;
-
- if (diff > 0.5)
- {
- /* greater than 0.5, round up, e.g. 1.6 -> 2 */
- ++whole;
- }
- else
- if (diff == 0.5 && (whole & 1))
- {
- /* exactly 0.5 and ODD, then round up */
- /* 1.5 -> 2, but 2.5 -> 2 */
- ++whole;
- }
-
- //vvvvvvvvvvvvvvvvvvv Diff from modp_dto2
- }
- else
- if (frac)
- {
- count = enc->doublePrecision;
- // now do fractional part, as an unsigned number
- // we know it is not 0 but we can have leading zeros, these
- // should be removed
- while (!(frac % 10))
- {
- --count;
- frac /= 10;
- }
- //^^^^^^^^^^^^^^^^^^^ Diff from modp_dto2
-
- // now do fractional part, as an unsigned number
- do
- {
- --count;
- *wstr++ = (char)(48 + (frac % 10));
- } while (frac /= 10);
- // add extra 0s
- while (count-- > 0)
- {
- *wstr++ = '0';
- }
- // add decimal
- *wstr++ = '.';
- }
- else
- {
- *wstr++ = '0';
- *wstr++ = '.';
- }
-
- // do whole part
- // Take care of sign
- // Conversion. Number is reversed.
- do *wstr++ = (char)(48 + (whole % 10)); while (whole /= 10);
-
- if (neg)
- {
- *wstr++ = '-';
- }
- strreverse(str, wstr-1);
- enc->offset += (wstr - (enc->offset));
-
- return TRUE;
-}
-
-/*
-FIXME:
-Handle integration functions returning NULL here */
-
-/*
-FIXME:
-Perhaps implement recursion detection */
-
-void encode(JSOBJ obj, JSONObjectEncoder *enc, const char *name, size_t cbName)
-{
- const char *value;
- char *objName;
- int count;
- JSOBJ iterObj;
- size_t szlen;
- JSONTypeContext tc;
-
- if (enc->level > enc->recursionMax)
- {
- SetError (obj, enc, "Maximum recursion level reached");
- return;
- }
-
- /*
- This reservation must hold
-
- length of _name as encoded worst case +
- maxLength of double to string OR maxLength of JSLONG to string
- */
-
- Buffer_Reserve(enc, 256 + RESERVE_STRING(cbName));
- if (enc->errorMsg)
- {
- return;
- }
-
- if (name)
- {
- Buffer_AppendCharUnchecked(enc, '\"');
-
- if (enc->forceASCII)
- {
- if (!Buffer_EscapeStringValidated(obj, enc, name, name + cbName))
- {
- return;
- }
- }
- else
- {
- if (!Buffer_EscapeStringUnvalidated(enc, name, name + cbName))
- {
- return;
- }
- }
-
- Buffer_AppendCharUnchecked(enc, '\"');
-
- Buffer_AppendCharUnchecked (enc, ':');
-#ifdef JSON_NO_EXTRA_WHITESPACE
- if (enc->indent)
- {
- Buffer_AppendCharUnchecked (enc, ' ');
- }
-#else
- Buffer_AppendCharUnchecked (enc, ' ');
-#endif
- }
-
- tc.encoder_prv = enc->prv;
- enc->beginTypeContext(obj, &tc, enc);
-
- switch (tc.type)
- {
- case JT_INVALID:
- {
- return;
- }
-
- case JT_ARRAY:
- {
- count = 0;
-
- Buffer_AppendCharUnchecked (enc, '[');
- Buffer_AppendIndentNewlineUnchecked (enc);
-
- while (enc->iterNext(obj, &tc))
- {
- if (count > 0)
- {
- Buffer_AppendCharUnchecked (enc, ',');
-#ifndef JSON_NO_EXTRA_WHITESPACE
- Buffer_AppendCharUnchecked (buffer, ' ');
-#endif
- Buffer_AppendIndentNewlineUnchecked (enc);
- }
-
- iterObj = enc->iterGetValue(obj, &tc);
-
- enc->level ++;
- Buffer_AppendIndentUnchecked (enc, enc->level);
- encode (iterObj, enc, NULL, 0);
- count ++;
- }
-
- enc->iterEnd(obj, &tc);
- Buffer_AppendIndentNewlineUnchecked (enc);
- Buffer_AppendIndentUnchecked (enc, enc->level);
- Buffer_AppendCharUnchecked (enc, ']');
- break;
- }
-
- case JT_OBJECT:
- {
- count = 0;
-
- Buffer_AppendCharUnchecked (enc, '{');
- Buffer_AppendIndentNewlineUnchecked (enc);
-
- while (enc->iterNext(obj, &tc))
- {
- if (count > 0)
- {
- Buffer_AppendCharUnchecked (enc, ',');
-#ifndef JSON_NO_EXTRA_WHITESPACE
- Buffer_AppendCharUnchecked (enc, ' ');
-#endif
- Buffer_AppendIndentNewlineUnchecked (enc);
- }
-
- iterObj = enc->iterGetValue(obj, &tc);
- objName = enc->iterGetName(obj, &tc, &szlen);
-
- enc->level ++;
- Buffer_AppendIndentUnchecked (enc, enc->level);
- encode (iterObj, enc, objName, szlen);
- count ++;
- }
-
- enc->iterEnd(obj, &tc);
- Buffer_AppendIndentNewlineUnchecked (enc);
- Buffer_AppendIndentUnchecked (enc, enc->level);
- Buffer_AppendCharUnchecked (enc, '}');
- break;
- }
-
- case JT_LONG:
- {
- Buffer_AppendLongUnchecked (enc, enc->getLongValue(obj, &tc));
- break;
- }
-
- case JT_ULONG:
- {
- Buffer_AppendUnsignedLongUnchecked (enc, enc->getUnsignedLongValue(obj, &tc));
- break;
- }
-
- case JT_INT:
- {
- Buffer_AppendIntUnchecked (enc, enc->getIntValue(obj, &tc));
- break;
- }
-
- case JT_TRUE:
- {
- Buffer_AppendCharUnchecked (enc, 't');
- Buffer_AppendCharUnchecked (enc, 'r');
- Buffer_AppendCharUnchecked (enc, 'u');
- Buffer_AppendCharUnchecked (enc, 'e');
- break;
- }
-
- case JT_FALSE:
- {
- Buffer_AppendCharUnchecked (enc, 'f');
- Buffer_AppendCharUnchecked (enc, 'a');
- Buffer_AppendCharUnchecked (enc, 'l');
- Buffer_AppendCharUnchecked (enc, 's');
- Buffer_AppendCharUnchecked (enc, 'e');
- break;
- }
-
-
- case JT_NULL:
- {
- Buffer_AppendCharUnchecked (enc, 'n');
- Buffer_AppendCharUnchecked (enc, 'u');
- Buffer_AppendCharUnchecked (enc, 'l');
- Buffer_AppendCharUnchecked (enc, 'l');
- break;
- }
-
- case JT_DOUBLE:
- {
- if (!Buffer_AppendDoubleUnchecked (obj, enc, enc->getDoubleValue(obj, &tc)))
- {
- enc->endTypeContext(obj, &tc);
- enc->level --;
- return;
- }
- break;
- }
-
- case JT_UTF8:
- {
- value = enc->getStringValue(obj, &tc, &szlen);
- if(!value)
- {
- SetError(obj, enc, "utf-8 encoding error");
- return;
- }
-
- Buffer_Reserve(enc, RESERVE_STRING(szlen));
- if (enc->errorMsg)
- {
- enc->endTypeContext(obj, &tc);
- return;
- }
- Buffer_AppendCharUnchecked (enc, '\"');
-
- if (enc->forceASCII)
- {
- if (!Buffer_EscapeStringValidated(obj, enc, value, value + szlen))
- {
- enc->endTypeContext(obj, &tc);
- enc->level --;
- return;
- }
- }
- else
- {
- if (!Buffer_EscapeStringUnvalidated(enc, value, value + szlen))
- {
- enc->endTypeContext(obj, &tc);
- enc->level --;
- return;
- }
- }
-
- Buffer_AppendCharUnchecked (enc, '\"');
- break;
- }
-
- case JT_RAW:
- {
- value = enc->getStringValue(obj, &tc, &szlen);
- if(!value)
- {
- SetError(obj, enc, "utf-8 encoding error");
- return;
- }
-
- Buffer_Reserve(enc, RESERVE_STRING(szlen));
- if (enc->errorMsg)
- {
- enc->endTypeContext(obj, &tc);
- return;
- }
-
- memcpy(enc->offset, value, szlen);
- enc->offset += szlen;
-
- break;
- }
- }
-
- enc->endTypeContext(obj, &tc);
- enc->level --;
-}
-
-char *JSON_EncodeObject(JSOBJ obj, JSONObjectEncoder *enc, char *_buffer, size_t _cbBuffer)
-{
- enc->malloc = enc->malloc ? enc->malloc : malloc;
- enc->free = enc->free ? enc->free : free;
- enc->realloc = enc->realloc ? enc->realloc : realloc;
- enc->errorMsg = NULL;
- enc->errorObj = NULL;
- enc->level = 0;
-
- if (enc->recursionMax < 1)
- {
- enc->recursionMax = JSON_MAX_RECURSION_DEPTH;
- }
-
- if (enc->doublePrecision < 0 ||
- enc->doublePrecision > JSON_DOUBLE_MAX_DECIMALS)
- {
- enc->doublePrecision = JSON_DOUBLE_MAX_DECIMALS;
- }
-
- if (_buffer == NULL)
- {
- _cbBuffer = 32768;
- enc->start = (char *) enc->malloc (_cbBuffer);
- if (!enc->start)
- {
- SetError(obj, enc, "Could not reserve memory block");
- return NULL;
- }
- enc->heap = 1;
- }
- else
- {
- enc->start = _buffer;
- enc->heap = 0;
- }
-
- enc->end = enc->start + _cbBuffer;
- enc->offset = enc->start;
-
- encode (obj, enc, NULL, 0);
-
- Buffer_Reserve(enc, 1);
- if (enc->errorMsg)
- {
- return NULL;
- }
- Buffer_AppendCharUnchecked(enc, '\0');
-
- return enc->start;
-}
diff --git a/contrib/python/ujson/py2/python/JSONtoObj.c b/contrib/python/ujson/py2/python/JSONtoObj.c
deleted file mode 100644
index 79d9f1af6e..0000000000
--- a/contrib/python/ujson/py2/python/JSONtoObj.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
-Developed by ESN, an Electronic Arts Inc. studio.
-Copyright (c) 2014, Electronic Arts Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-* Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-* Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-* Neither the name of ESN, Electronic Arts Inc. nor the
-names of its contributors may be used to endorse or promote products
-derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS INC. 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.
-
-
-Portions of code from MODP_ASCII - Ascii transformations (upper/lower, etc)
-http://code.google.com/p/stringencoders/
-Copyright (c) 2007 Nick Galbreath -- nickg [at] modp [dot] com. All rights reserved.
-
-Numeric decoder derived from from TCL library
-http://www.opensource.apple.com/source/tcl/tcl-14/tcl/license.terms
- * Copyright (c) 1988-1993 The Regents of the University of California.
- * Copyright (c) 1994 Sun Microsystems, Inc.
-*/
-
-#include "py_defines.h"
-#include <ultrajson.h>
-
-
-//#define PRINTMARK() fprintf(stderr, "%s: MARK(%d)\n", __FILE__, __LINE__)
-#define PRINTMARK()
-
-void Object_objectAddKey(void *prv, JSOBJ obj, JSOBJ name, JSOBJ value)
-{
- PyDict_SetItem (obj, name, value);
- Py_DECREF( (PyObject *) name);
- Py_DECREF( (PyObject *) value);
- return;
-}
-
-void Object_arrayAddItem(void *prv, JSOBJ obj, JSOBJ value)
-{
- PyList_Append(obj, value);
- Py_DECREF( (PyObject *) value);
- return;
-}
-
-JSOBJ Object_newString(void *prv, wchar_t *start, wchar_t *end)
-{
- return PyUnicode_FromWideChar (start, (end - start));
-}
-
-JSOBJ Object_newTrue(void *prv)
-{
- Py_RETURN_TRUE;
-}
-
-JSOBJ Object_newFalse(void *prv)
-{
- Py_RETURN_FALSE;
-}
-
-JSOBJ Object_newNull(void *prv)
-{
- Py_RETURN_NONE;
-}
-
-JSOBJ Object_newObject(void *prv)
-{
- return PyDict_New();
-}
-
-JSOBJ Object_newArray(void *prv)
-{
- return PyList_New(0);
-}
-
-JSOBJ Object_newInteger(void *prv, JSINT32 value)
-{
- return PyInt_FromLong( (long) value);
-}
-
-JSOBJ Object_newLong(void *prv, JSINT64 value)
-{
- return PyLong_FromLongLong (value);
-}
-
-JSOBJ Object_newUnsignedLong(void *prv, JSUINT64 value)
-{
- return PyLong_FromUnsignedLongLong (value);
-}
-
-JSOBJ Object_newDouble(void *prv, double value)
-{
- return PyFloat_FromDouble(value);
-}
-
-static void Object_releaseObject(void *prv, JSOBJ obj)
-{
- Py_DECREF( ((PyObject *)obj));
-}
-
-static char *g_kwlist[] = {"obj", "precise_float", NULL};
-
-PyObject* JSONToObj(PyObject* self, PyObject *args, PyObject *kwargs)
-{
- PyObject *ret;
- PyObject *sarg;
- PyObject *arg;
- PyObject *opreciseFloat = NULL;
- JSONObjectDecoder decoder =
- {
- Object_newString,
- Object_objectAddKey,
- Object_arrayAddItem,
- Object_newTrue,
- Object_newFalse,
- Object_newNull,
- Object_newObject,
- Object_newArray,
- Object_newInteger,
- Object_newLong,
- Object_newUnsignedLong,
- Object_newDouble,
- Object_releaseObject,
- PyObject_Malloc,
- PyObject_Free,
- PyObject_Realloc
- };
-
- decoder.preciseFloat = 0;
- decoder.prv = NULL;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", g_kwlist, &arg, &opreciseFloat))
- {
- return NULL;
- }
-
- if (opreciseFloat && PyObject_IsTrue(opreciseFloat))
- {
- decoder.preciseFloat = 1;
- }
-
- if (PyString_Check(arg))
- {
- sarg = arg;
- }
- else
- if (PyUnicode_Check(arg))
- {
- sarg = PyUnicode_AsUTF8String(arg);
- if (sarg == NULL)
- {
- //Exception raised above us by codec according to docs
- return NULL;
- }
- }
- else
- {
- PyErr_Format(PyExc_TypeError, "Expected String or Unicode");
- return NULL;
- }
-
- decoder.errorStr = NULL;
- decoder.errorOffset = NULL;
-
- ret = JSON_DecodeObject(&decoder, PyString_AS_STRING(sarg), PyString_GET_SIZE(sarg));
-
- if (sarg != arg)
- {
- Py_DECREF(sarg);
- }
-
- if (decoder.errorStr)
- {
- /*
- FIXME: It's possible to give a much nicer error message here with actual failing element in input etc*/
-
- PyErr_Format (PyExc_ValueError, "%s", decoder.errorStr);
-
- if (ret)
- {
- Py_DECREF( (PyObject *) ret);
- }
-
- return NULL;
- }
-
- return ret;
-}
-
-PyObject* JSONFileToObj(PyObject* self, PyObject *args, PyObject *kwargs)
-{
- PyObject *read;
- PyObject *string;
- PyObject *result;
- PyObject *file = NULL;
- PyObject *argtuple;
-
- if (!PyArg_ParseTuple (args, "O", &file))
- {
- return NULL;
- }
-
- if (!PyObject_HasAttrString (file, "read"))
- {
- PyErr_Format (PyExc_TypeError, "expected file");
- return NULL;
- }
-
- read = PyObject_GetAttrString (file, "read");
-
- if (!PyCallable_Check (read)) {
- Py_XDECREF(read);
- PyErr_Format (PyExc_TypeError, "expected file");
- return NULL;
- }
-
- string = PyObject_CallObject (read, NULL);
- Py_XDECREF(read);
-
- if (string == NULL)
- {
- return NULL;
- }
-
- argtuple = PyTuple_Pack(1, string);
-
- result = JSONToObj (self, argtuple, kwargs);
-
- Py_XDECREF(argtuple);
- Py_XDECREF(string);
-
- if (result == NULL) {
- return NULL;
- }
-
- return result;
-}
diff --git a/contrib/python/ujson/py2/python/objToJSON.c b/contrib/python/ujson/py2/python/objToJSON.c
deleted file mode 100644
index b3a821e7ae..0000000000
--- a/contrib/python/ujson/py2/python/objToJSON.c
+++ /dev/null
@@ -1,1168 +0,0 @@
-/*
-Developed by ESN, an Electronic Arts Inc. studio.
-Copyright (c) 2014, Electronic Arts Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-* Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-* Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-* Neither the name of ESN, Electronic Arts Inc. nor the
-names of its contributors may be used to endorse or promote products
-derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS INC. 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.
-
-
-Portions of code from MODP_ASCII - Ascii transformations (upper/lower, etc)
-http://code.google.com/p/stringencoders/
-Copyright (c) 2007 Nick Galbreath -- nickg [at] modp [dot] com. All rights reserved.
-
-Numeric decoder derived from from TCL library
-http://www.opensource.apple.com/source/tcl/tcl-14/tcl/license.terms
-* Copyright (c) 1988-1993 The Regents of the University of California.
-* Copyright (c) 1994 Sun Microsystems, Inc.
-*/
-
-#include "py_defines.h"
-#include <stdio.h>
-#include <datetime.h>
-#include <ultrajson.h>
-
-#define EPOCH_ORD 719163
-static PyObject* type_decimal = NULL;
-
-typedef void *(*PFN_PyTypeToJSON)(JSOBJ obj, JSONTypeContext *ti, void *outValue, size_t *_outLen);
-
-#if (PY_VERSION_HEX < 0x02050000)
-typedef ssize_t Py_ssize_t;
-#endif
-
-typedef struct __TypeContext
-{
- JSPFN_ITEREND iterEnd;
- JSPFN_ITERNEXT iterNext;
- JSPFN_ITERGETNAME iterGetName;
- JSPFN_ITERGETVALUE iterGetValue;
- PFN_PyTypeToJSON PyTypeToJSON;
- PyObject *newObj;
- PyObject *dictObj;
- Py_ssize_t index;
- Py_ssize_t size;
- PyObject *itemValue;
- PyObject *itemName;
- PyObject *attrList;
- PyObject *iterator;
-
- union
- {
- PyObject *rawJSONValue;
- JSINT64 longValue;
- JSUINT64 unsignedLongValue;
- };
-} TypeContext;
-
-#define GET_TC(__ptrtc) ((TypeContext *)((__ptrtc)->prv))
-
-struct PyDictIterState
-{
- PyObject *keys;
- size_t i;
- size_t sz;
-};
-
-//#define PRINTMARK() fprintf(stderr, "%s: MARK(%d)\n", __FILE__, __LINE__)
-#define PRINTMARK()
-
-void initObjToJSON(void)
-{
- PyObject* mod_decimal = PyImport_ImportModule("decimal");
- if (mod_decimal)
- {
- type_decimal = PyObject_GetAttrString(mod_decimal, "Decimal");
- Py_INCREF(type_decimal);
- Py_DECREF(mod_decimal);
- }
- else
- PyErr_Clear();
-
- PyDateTime_IMPORT;
-}
-
-#ifdef _LP64
-static void *PyIntToINT64(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen)
-{
- PyObject *obj = (PyObject *) _obj;
- *((JSINT64 *) outValue) = PyInt_AS_LONG (obj);
- return NULL;
-}
-#else
-static void *PyIntToINT32(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen)
-{
- PyObject *obj = (PyObject *) _obj;
- *((JSINT32 *) outValue) = PyInt_AS_LONG (obj);
- return NULL;
-}
-#endif
-
-static void *PyLongToINT64(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen)
-{
- *((JSINT64 *) outValue) = GET_TC(tc)->longValue;
- return NULL;
-}
-
-static void *PyLongToUINT64(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen)
-{
- *((JSUINT64 *) outValue) = GET_TC(tc)->unsignedLongValue;
- return NULL;
-}
-
-static void *PyFloatToDOUBLE(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen)
-{
- PyObject *obj = (PyObject *) _obj;
- *((double *) outValue) = PyFloat_AsDouble (obj);
- return NULL;
-}
-
-static void *PyStringToUTF8(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen)
-{
- PyObject *obj = (PyObject *) _obj;
- *_outLen = PyString_GET_SIZE(obj);
- return PyString_AS_STRING(obj);
-}
-
-static void *PyUnicodeToUTF8(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen)
-{
- PyObject *obj = (PyObject *) _obj;
- PyObject *newObj;
-#if (PY_VERSION_HEX >= 0x03030000)
- if(PyUnicode_IS_COMPACT_ASCII(obj))
- {
- Py_ssize_t len;
- char *data = PyUnicode_AsUTF8AndSize(obj, &len);
- *_outLen = len;
- return data;
- }
-#endif
- newObj = PyUnicode_AsUTF8String(obj);
- if(!newObj)
- {
- return NULL;
- }
-
- GET_TC(tc)->newObj = newObj;
-
- *_outLen = PyString_GET_SIZE(newObj);
- return PyString_AS_STRING(newObj);
-}
-
-static void *PyRawJSONToUTF8(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen)
-{
- PyObject *obj = GET_TC(tc)->rawJSONValue;
- if (PyUnicode_Check(obj)) {
- return PyUnicodeToUTF8(obj, tc, outValue, _outLen);
- }
- else {
- return PyStringToUTF8(obj, tc, outValue, _outLen);
- }
-}
-
-static void *PyDateTimeToINT64(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen)
-{
- PyObject *obj = (PyObject *) _obj;
- PyObject *date, *ord, *utcoffset;
- int y, m, d, h, mn, s, days;
-
- utcoffset = PyObject_CallMethod(obj, "utcoffset", NULL);
- if(utcoffset != Py_None){
- obj = PyNumber_Subtract(obj, utcoffset);
- }
-
- y = PyDateTime_GET_YEAR(obj);
- m = PyDateTime_GET_MONTH(obj);
- d = PyDateTime_GET_DAY(obj);
- h = PyDateTime_DATE_GET_HOUR(obj);
- mn = PyDateTime_DATE_GET_MINUTE(obj);
- s = PyDateTime_DATE_GET_SECOND(obj);
-
- date = PyDate_FromDate(y, m, 1);
- ord = PyObject_CallMethod(date, "toordinal", NULL);
- days = PyInt_AS_LONG(ord) - EPOCH_ORD + d - 1;
- Py_DECREF(date);
- Py_DECREF(ord);
- *( (JSINT64 *) outValue) = (((JSINT64) ((days * 24 + h) * 60 + mn)) * 60 + s);
- return NULL;
-}
-
-static void *PyDateToINT64(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen)
-{
- PyObject *obj = (PyObject *) _obj;
- PyObject *date, *ord;
- int y, m, d, days;
-
- y = PyDateTime_GET_YEAR(obj);
- m = PyDateTime_GET_MONTH(obj);
- d = PyDateTime_GET_DAY(obj);
-
- date = PyDate_FromDate(y, m, 1);
- ord = PyObject_CallMethod(date, "toordinal", NULL);
- days = PyInt_AS_LONG(ord) - EPOCH_ORD + d - 1;
- Py_DECREF(date);
- Py_DECREF(ord);
- *( (JSINT64 *) outValue) = ((JSINT64) days * 86400);
-
- return NULL;
-}
-
-int Tuple_iterNext(JSOBJ obj, JSONTypeContext *tc)
-{
- PyObject *item;
-
- if (GET_TC(tc)->index >= GET_TC(tc)->size)
- {
- return 0;
- }
-
- item = PyTuple_GET_ITEM (obj, GET_TC(tc)->index);
-
- GET_TC(tc)->itemValue = item;
- GET_TC(tc)->index ++;
- return 1;
-}
-
-void Tuple_iterEnd(JSOBJ obj, JSONTypeContext *tc)
-{
-}
-
-JSOBJ Tuple_iterGetValue(JSOBJ obj, JSONTypeContext *tc)
-{
- return GET_TC(tc)->itemValue;
-}
-
-char *Tuple_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen)
-{
- return NULL;
-}
-
-int Iter_iterNext(JSOBJ obj, JSONTypeContext *tc)
-{
- PyObject *item;
-
- if (GET_TC(tc)->itemValue)
- {
- Py_DECREF(GET_TC(tc)->itemValue);
- GET_TC(tc)->itemValue = NULL;
- }
-
- if (GET_TC(tc)->iterator == NULL)
- {
- return 0;
- }
-
- item = PyIter_Next(GET_TC(tc)->iterator);
-
- if (item == NULL)
- {
- return 0;
- }
-
- GET_TC(tc)->itemValue = item;
- return 1;
-}
-
-void Iter_iterEnd(JSOBJ obj, JSONTypeContext *tc)
-{
- if (GET_TC(tc)->itemValue)
- {
- Py_DECREF(GET_TC(tc)->itemValue);
- GET_TC(tc)->itemValue = NULL;
- }
-
- if (GET_TC(tc)->iterator)
- {
- Py_DECREF(GET_TC(tc)->iterator);
- GET_TC(tc)->iterator = NULL;
- }
-}
-
-JSOBJ Iter_iterGetValue(JSOBJ obj, JSONTypeContext *tc)
-{
- return GET_TC(tc)->itemValue;
-}
-
-char *Iter_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen)
-{
- return NULL;
-}
-
-void Dir_iterEnd(JSOBJ obj, JSONTypeContext *tc)
-{
- if (GET_TC(tc)->itemValue)
- {
- Py_DECREF(GET_TC(tc)->itemValue);
- GET_TC(tc)->itemValue = NULL;
- }
-
- if (GET_TC(tc)->itemName)
- {
- Py_DECREF(GET_TC(tc)->itemName);
- GET_TC(tc)->itemName = NULL;
- }
-
- Py_DECREF( (PyObject *) GET_TC(tc)->attrList);
- PRINTMARK();
-}
-
-int Dir_iterNext(JSOBJ _obj, JSONTypeContext *tc)
-{
- PyObject *obj = (PyObject *) _obj;
- PyObject *itemValue = GET_TC(tc)->itemValue;
- PyObject *itemName = GET_TC(tc)->itemName;
- PyObject* attr;
- PyObject* attrName;
- char* attrStr;
-
- if (itemValue)
- {
- Py_DECREF(GET_TC(tc)->itemValue);
- GET_TC(tc)->itemValue = itemValue = NULL;
- }
-
- if (itemName)
- {
- Py_DECREF(GET_TC(tc)->itemName);
- GET_TC(tc)->itemName = itemName = NULL;
- }
-
- for (; GET_TC(tc)->index < GET_TC(tc)->size; GET_TC(tc)->index ++)
- {
- attrName = PyList_GET_ITEM(GET_TC(tc)->attrList, GET_TC(tc)->index);
-#if PY_MAJOR_VERSION >= 3
- attr = PyUnicode_AsUTF8String(attrName);
-#else
- attr = attrName;
- Py_INCREF(attr);
-#endif
- attrStr = PyString_AS_STRING(attr);
-
- if (attrStr[0] == '_')
- {
- PRINTMARK();
- Py_DECREF(attr);
- continue;
- }
-
- itemValue = PyObject_GetAttr(obj, attrName);
- if (itemValue == NULL)
- {
- PyErr_Clear();
- Py_DECREF(attr);
- PRINTMARK();
- continue;
- }
-
- if (PyCallable_Check(itemValue))
- {
- Py_DECREF(itemValue);
- Py_DECREF(attr);
- PRINTMARK();
- continue;
- }
-
- PRINTMARK();
- itemName = attr;
- break;
- }
-
- if (itemName == NULL)
- {
- GET_TC(tc)->index = GET_TC(tc)->size;
- GET_TC(tc)->itemValue = NULL;
- return 0;
- }
-
- GET_TC(tc)->itemName = itemName;
- GET_TC(tc)->itemValue = itemValue;
- GET_TC(tc)->index ++;
-
- PRINTMARK();
- return 1;
-}
-
-JSOBJ Dir_iterGetValue(JSOBJ obj, JSONTypeContext *tc)
-{
- PRINTMARK();
- return GET_TC(tc)->itemValue;
-}
-
-char *Dir_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen)
-{
- PRINTMARK();
- *outLen = PyString_GET_SIZE(GET_TC(tc)->itemName);
- return PyString_AS_STRING(GET_TC(tc)->itemName);
-}
-
-int List_iterNext(JSOBJ obj, JSONTypeContext *tc)
-{
- if (GET_TC(tc)->index >= GET_TC(tc)->size)
- {
- PRINTMARK();
- return 0;
- }
-
- GET_TC(tc)->itemValue = PyList_GET_ITEM (obj, GET_TC(tc)->index);
- GET_TC(tc)->index ++;
- return 1;
-}
-
-void List_iterEnd(JSOBJ obj, JSONTypeContext *tc)
-{
-}
-
-JSOBJ List_iterGetValue(JSOBJ obj, JSONTypeContext *tc)
-{
- return GET_TC(tc)->itemValue;
-}
-
-char *List_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen)
-{
- return NULL;
-}
-
-//=============================================================================
-// Dict iteration functions
-// itemName might converted to string (Python_Str). Do refCounting
-// itemValue is borrowed from object (which is dict). No refCounting
-//=============================================================================
-
-int Dict_iterNext(JSOBJ obj, JSONTypeContext *tc)
-{
-#if PY_MAJOR_VERSION >= 3
- PyObject* itemNameTmp;
-#endif
-
- if (GET_TC(tc)->itemName)
- {
- Py_DECREF(GET_TC(tc)->itemName);
- GET_TC(tc)->itemName = NULL;
- }
-
-
- if (!PyDict_Next ( (PyObject *)GET_TC(tc)->dictObj, &GET_TC(tc)->index, &GET_TC(tc)->itemName, &GET_TC(tc)->itemValue))
- {
- PRINTMARK();
- return 0;
- }
-
- if (PyUnicode_Check(GET_TC(tc)->itemName))
- {
- GET_TC(tc)->itemName = PyUnicode_AsUTF8String (GET_TC(tc)->itemName);
- }
- else
- if (!PyString_Check(GET_TC(tc)->itemName))
- {
- GET_TC(tc)->itemName = PyObject_Str(GET_TC(tc)->itemName);
-#if PY_MAJOR_VERSION >= 3
- itemNameTmp = GET_TC(tc)->itemName;
- GET_TC(tc)->itemName = PyUnicode_AsUTF8String (GET_TC(tc)->itemName);
- Py_DECREF(itemNameTmp);
-#endif
- }
- else
- {
- Py_INCREF(GET_TC(tc)->itemName);
- }
- PRINTMARK();
- return 1;
-}
-
-void Dict_iterEnd(JSOBJ obj, JSONTypeContext *tc)
-{
- if (GET_TC(tc)->itemName)
- {
- Py_DECREF(GET_TC(tc)->itemName);
- GET_TC(tc)->itemName = NULL;
- }
- Py_DECREF(GET_TC(tc)->dictObj);
- PRINTMARK();
-}
-
-JSOBJ Dict_iterGetValue(JSOBJ obj, JSONTypeContext *tc)
-{
- return GET_TC(tc)->itemValue;
-}
-
-char *Dict_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen)
-{
- *outLen = PyString_GET_SIZE(GET_TC(tc)->itemName);
- return PyString_AS_STRING(GET_TC(tc)->itemName);
-}
-
-int SortedDict_iterNext(JSOBJ obj, JSONTypeContext *tc)
-{
- PyObject *items = NULL, *item = NULL, *key = NULL, *value = NULL;
- Py_ssize_t i, nitems;
-#if PY_MAJOR_VERSION >= 3
- PyObject* keyTmp;
-#endif
-
- // Upon first call, obtain a list of the keys and sort them. This follows the same logic as the
- // stanard library's _json.c sort_keys handler.
- if (GET_TC(tc)->newObj == NULL)
- {
- // Obtain the list of keys from the dictionary.
- items = PyMapping_Keys(GET_TC(tc)->dictObj);
- if (items == NULL)
- {
- goto error;
- }
- else if (!PyList_Check(items))
- {
- PyErr_SetString(PyExc_ValueError, "keys must return list");
- goto error;
- }
-
- // Sort the list.
- if (PyList_Sort(items) < 0)
- {
- goto error;
- }
-
- // Obtain the value for each key, and pack a list of (key, value) 2-tuples.
- nitems = PyList_GET_SIZE(items);
- for (i = 0; i < nitems; i++)
- {
- key = PyList_GET_ITEM(items, i);
- value = PyDict_GetItem(GET_TC(tc)->dictObj, key);
-
- // Subject the key to the same type restrictions and conversions as in Dict_iterGetValue.
- if (PyUnicode_Check(key))
- {
- key = PyUnicode_AsUTF8String(key);
- }
- else if (!PyString_Check(key))
- {
- key = PyObject_Str(key);
-#if PY_MAJOR_VERSION >= 3
- keyTmp = key;
- key = PyUnicode_AsUTF8String(key);
- Py_DECREF(keyTmp);
-#endif
- }
- else
- {
- Py_INCREF(key);
- }
-
- item = PyTuple_Pack(2, key, value);
- if (item == NULL)
- {
- goto error;
- }
- if (PyList_SetItem(items, i, item))
- {
- goto error;
- }
- Py_DECREF(key);
- }
-
- // Store the sorted list of tuples in the newObj slot.
- GET_TC(tc)->newObj = items;
- GET_TC(tc)->size = nitems;
- }
-
- if (GET_TC(tc)->index >= GET_TC(tc)->size)
- {
- PRINTMARK();
- return 0;
- }
-
- item = PyList_GET_ITEM(GET_TC(tc)->newObj, GET_TC(tc)->index);
- GET_TC(tc)->itemName = PyTuple_GET_ITEM(item, 0);
- GET_TC(tc)->itemValue = PyTuple_GET_ITEM(item, 1);
- GET_TC(tc)->index++;
- return 1;
-
-error:
- Py_XDECREF(item);
- Py_XDECREF(key);
- Py_XDECREF(value);
- Py_XDECREF(items);
- return -1;
-}
-
-void SortedDict_iterEnd(JSOBJ obj, JSONTypeContext *tc)
-{
- GET_TC(tc)->itemName = NULL;
- GET_TC(tc)->itemValue = NULL;
- Py_DECREF(GET_TC(tc)->dictObj);
- PRINTMARK();
-}
-
-JSOBJ SortedDict_iterGetValue(JSOBJ obj, JSONTypeContext *tc)
-{
- return GET_TC(tc)->itemValue;
-}
-
-char *SortedDict_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen)
-{
- *outLen = PyString_GET_SIZE(GET_TC(tc)->itemName);
- return PyString_AS_STRING(GET_TC(tc)->itemName);
-}
-
-
-void SetupDictIter(PyObject *dictObj, TypeContext *pc, JSONObjectEncoder *enc)
-{
- if (enc->sortKeys) {
- pc->iterEnd = SortedDict_iterEnd;
- pc->iterNext = SortedDict_iterNext;
- pc->iterGetValue = SortedDict_iterGetValue;
- pc->iterGetName = SortedDict_iterGetName;
- }
- else {
- pc->iterEnd = Dict_iterEnd;
- pc->iterNext = Dict_iterNext;
- pc->iterGetValue = Dict_iterGetValue;
- pc->iterGetName = Dict_iterGetName;
- }
- pc->dictObj = dictObj;
- pc->index = 0;
-}
-
-void Object_beginTypeContext (JSOBJ _obj, JSONTypeContext *tc, JSONObjectEncoder *enc)
-{
- PyObject *obj, *exc, *iter;
- TypeContext *pc;
- PRINTMARK();
- if (!_obj) {
- tc->type = JT_INVALID;
- return;
- }
-
- obj = (PyObject*) _obj;
-
- tc->prv = PyObject_Malloc(sizeof(TypeContext));
- pc = (TypeContext *) tc->prv;
- if (!pc)
- {
- tc->type = JT_INVALID;
- PyErr_NoMemory();
- return;
- }
- pc->newObj = NULL;
- pc->dictObj = NULL;
- pc->itemValue = NULL;
- pc->itemName = NULL;
- pc->iterator = NULL;
- pc->attrList = NULL;
- pc->index = 0;
- pc->size = 0;
- pc->longValue = 0;
- pc->rawJSONValue = NULL;
-
- if (PyIter_Check(obj))
- {
- PRINTMARK();
- goto ISITERABLE;
- }
-
- if (PyBool_Check(obj))
- {
- PRINTMARK();
- tc->type = (obj == Py_True) ? JT_TRUE : JT_FALSE;
- return;
- }
- else
- if (PyLong_Check(obj))
- {
- PRINTMARK();
- pc->PyTypeToJSON = PyLongToINT64;
- tc->type = JT_LONG;
- GET_TC(tc)->longValue = PyLong_AsLongLong(obj);
-
- exc = PyErr_Occurred();
- if (!exc)
- {
- return;
- }
-
- if (exc && PyErr_ExceptionMatches(PyExc_OverflowError))
- {
- PyErr_Clear();
- pc->PyTypeToJSON = PyLongToUINT64;
- tc->type = JT_ULONG;
- GET_TC(tc)->unsignedLongValue = PyLong_AsUnsignedLongLong(obj);
-
- exc = PyErr_Occurred();
- if (exc && PyErr_ExceptionMatches(PyExc_OverflowError))
- {
- PRINTMARK();
- goto INVALID;
- }
- }
-
- return;
- }
- else
- if (PyInt_Check(obj))
- {
- PRINTMARK();
-#ifdef _LP64
- pc->PyTypeToJSON = PyIntToINT64; tc->type = JT_LONG;
-#else
- pc->PyTypeToJSON = PyIntToINT32; tc->type = JT_INT;
-#endif
- return;
- }
- else
- if (PyString_Check(obj))
- {
- PRINTMARK();
- pc->PyTypeToJSON = PyStringToUTF8; tc->type = JT_UTF8;
- return;
- }
- else
- if (PyUnicode_Check(obj))
- {
- PRINTMARK();
- pc->PyTypeToJSON = PyUnicodeToUTF8; tc->type = JT_UTF8;
- return;
- }
- else
- if (PyFloat_Check(obj) || (type_decimal && PyObject_IsInstance(obj, type_decimal)))
- {
- PRINTMARK();
- pc->PyTypeToJSON = PyFloatToDOUBLE; tc->type = JT_DOUBLE;
- return;
- }
- else
- if (PyDateTime_Check(obj))
- {
- PRINTMARK();
- pc->PyTypeToJSON = PyDateTimeToINT64; tc->type = JT_LONG;
- return;
- }
- else
- if (PyDate_Check(obj))
- {
- PRINTMARK();
- pc->PyTypeToJSON = PyDateToINT64; tc->type = JT_LONG;
- return;
- }
- else
- if (obj == Py_None)
- {
- PRINTMARK();
- tc->type = JT_NULL;
- return;
- }
-
-ISITERABLE:
- if (PyDict_Check(obj))
- {
- PRINTMARK();
- tc->type = JT_OBJECT;
- SetupDictIter(obj, pc, enc);
- Py_INCREF(obj);
- return;
- }
- else
- if (PyList_Check(obj))
- {
- PRINTMARK();
- tc->type = JT_ARRAY;
- pc->iterEnd = List_iterEnd;
- pc->iterNext = List_iterNext;
- pc->iterGetValue = List_iterGetValue;
- pc->iterGetName = List_iterGetName;
- GET_TC(tc)->index = 0;
- GET_TC(tc)->size = PyList_GET_SIZE( (PyObject *) obj);
- return;
- }
- else
- if (PyTuple_Check(obj))
- {
- PRINTMARK();
- tc->type = JT_ARRAY;
- pc->iterEnd = Tuple_iterEnd;
- pc->iterNext = Tuple_iterNext;
- pc->iterGetValue = Tuple_iterGetValue;
- pc->iterGetName = Tuple_iterGetName;
- GET_TC(tc)->index = 0;
- GET_TC(tc)->size = PyTuple_GET_SIZE( (PyObject *) obj);
- GET_TC(tc)->itemValue = NULL;
-
- return;
- }
- /*
- else
- if (PyAnySet_Check(obj))
- {
- PRINTMARK();
- tc->type = JT_ARRAY;
- pc->iterBegin = NULL;
- pc->iterEnd = Iter_iterEnd;
- pc->iterNext = Iter_iterNext;
- pc->iterGetValue = Iter_iterGetValue;
- pc->iterGetName = Iter_iterGetName;
- return;
- }
- */
-
- if (PyObject_HasAttrString(obj, "toDict"))
- {
- PyObject* toDictFunc = PyObject_GetAttrString(obj, "toDict");
- PyObject* tuple = PyTuple_New(0);
- PyObject* toDictResult = PyObject_Call(toDictFunc, tuple, NULL);
- Py_DECREF(tuple);
- Py_DECREF(toDictFunc);
-
- if (toDictResult == NULL)
- {
- goto INVALID;
- }
-
- if (!PyDict_Check(toDictResult))
- {
- Py_DECREF(toDictResult);
- tc->type = JT_NULL;
- return;
- }
-
- PRINTMARK();
- tc->type = JT_OBJECT;
- SetupDictIter(toDictResult, pc, enc);
- return;
- }
- else
- if (PyObject_HasAttrString(obj, "__json__"))
- {
- PyObject* toJSONFunc = PyObject_GetAttrString(obj, "__json__");
- PyObject* tuple = PyTuple_New(0);
- PyObject* toJSONResult = PyObject_Call(toJSONFunc, tuple, NULL);
- Py_DECREF(tuple);
- Py_DECREF(toJSONFunc);
-
- if (toJSONResult == NULL)
- {
- goto INVALID;
- }
-
- if (PyErr_Occurred())
- {
- Py_DECREF(toJSONResult);
- goto INVALID;
- }
-
- if (!PyString_Check(toJSONResult) && !PyUnicode_Check(toJSONResult))
- {
- Py_DECREF(toJSONResult);
- PyErr_Format (PyExc_TypeError, "expected string");
- goto INVALID;
- }
-
- PRINTMARK();
- pc->PyTypeToJSON = PyRawJSONToUTF8;
- tc->type = JT_RAW;
- GET_TC(tc)->rawJSONValue = toJSONResult;
- return;
- }
-
- PRINTMARK();
- PyErr_Clear();
-
- iter = PyObject_GetIter(obj);
-
- if (iter != NULL)
- {
- PRINTMARK();
- tc->type = JT_ARRAY;
- pc->iterator = iter;
- pc->iterEnd = Iter_iterEnd;
- pc->iterNext = Iter_iterNext;
- pc->iterGetValue = Iter_iterGetValue;
- pc->iterGetName = Iter_iterGetName;
- return;
- }
-
- PRINTMARK();
- PyErr_Clear();
-
- PRINTMARK();
- tc->type = JT_OBJECT;
- GET_TC(tc)->attrList = PyObject_Dir(obj);
-
- if (GET_TC(tc)->attrList == NULL)
- {
- PyErr_Clear();
- goto INVALID;
- }
-
- GET_TC(tc)->index = 0;
- GET_TC(tc)->size = PyList_GET_SIZE(GET_TC(tc)->attrList);
- PRINTMARK();
-
- pc->iterEnd = Dir_iterEnd;
- pc->iterNext = Dir_iterNext;
- pc->iterGetValue = Dir_iterGetValue;
- pc->iterGetName = Dir_iterGetName;
- return;
-
-INVALID:
- PRINTMARK();
- tc->type = JT_INVALID;
- PyObject_Free(tc->prv);
- tc->prv = NULL;
- return;
-}
-
-void Object_endTypeContext(JSOBJ obj, JSONTypeContext *tc)
-{
- Py_XDECREF(GET_TC(tc)->newObj);
-
- if (tc->type == JT_RAW)
- {
- Py_XDECREF(GET_TC(tc)->rawJSONValue);
- }
- PyObject_Free(tc->prv);
- tc->prv = NULL;
-}
-
-const char *Object_getStringValue(JSOBJ obj, JSONTypeContext *tc, size_t *_outLen)
-{
- return GET_TC(tc)->PyTypeToJSON (obj, tc, NULL, _outLen);
-}
-
-JSINT64 Object_getLongValue(JSOBJ obj, JSONTypeContext *tc)
-{
- JSINT64 ret;
- GET_TC(tc)->PyTypeToJSON (obj, tc, &ret, NULL);
- return ret;
-}
-
-JSUINT64 Object_getUnsignedLongValue(JSOBJ obj, JSONTypeContext *tc)
-{
- JSUINT64 ret;
- GET_TC(tc)->PyTypeToJSON (obj, tc, &ret, NULL);
- return ret;
-}
-
-JSINT32 Object_getIntValue(JSOBJ obj, JSONTypeContext *tc)
-{
- JSINT32 ret;
- GET_TC(tc)->PyTypeToJSON (obj, tc, &ret, NULL);
- return ret;
-}
-
-double Object_getDoubleValue(JSOBJ obj, JSONTypeContext *tc)
-{
- double ret;
- GET_TC(tc)->PyTypeToJSON (obj, tc, &ret, NULL);
- return ret;
-}
-
-static void Object_releaseObject(JSOBJ _obj)
-{
- Py_DECREF( (PyObject *) _obj);
-}
-
-int Object_iterNext(JSOBJ obj, JSONTypeContext *tc)
-{
- return GET_TC(tc)->iterNext(obj, tc);
-}
-
-void Object_iterEnd(JSOBJ obj, JSONTypeContext *tc)
-{
- GET_TC(tc)->iterEnd(obj, tc);
-}
-
-JSOBJ Object_iterGetValue(JSOBJ obj, JSONTypeContext *tc)
-{
- return GET_TC(tc)->iterGetValue(obj, tc);
-}
-
-char *Object_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen)
-{
- return GET_TC(tc)->iterGetName(obj, tc, outLen);
-}
-
-PyObject* objToJSON(PyObject* self, PyObject *args, PyObject *kwargs)
-{
- static char *kwlist[] = { "obj", "ensure_ascii", "double_precision", "encode_html_chars", "escape_forward_slashes", "sort_keys", "indent", NULL };
-
- char buffer[65536];
- char *ret;
- PyObject *newobj;
- PyObject *oinput = NULL;
- PyObject *oensureAscii = NULL;
- PyObject *oencodeHTMLChars = NULL;
- PyObject *oescapeForwardSlashes = NULL;
- PyObject *osortKeys = NULL;
-
- JSONObjectEncoder encoder =
- {
- Object_beginTypeContext,
- Object_endTypeContext,
- Object_getStringValue,
- Object_getLongValue,
- Object_getUnsignedLongValue,
- Object_getIntValue,
- Object_getDoubleValue,
- Object_iterNext,
- Object_iterEnd,
- Object_iterGetValue,
- Object_iterGetName,
- Object_releaseObject,
- PyObject_Malloc,
- PyObject_Realloc,
- PyObject_Free,
- -1, //recursionMax
- 10, // default double precision setting
- 1, //forceAscii
- 0, //encodeHTMLChars
- 1, //escapeForwardSlashes
- 0, //sortKeys
- 0, //indent
- NULL, //prv
- };
-
-
- PRINTMARK();
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OiOOOi", kwlist, &oinput, &oensureAscii, &encoder.doublePrecision, &oencodeHTMLChars, &oescapeForwardSlashes, &osortKeys, &encoder.indent))
- {
- return NULL;
- }
-
- if (oensureAscii != NULL && !PyObject_IsTrue(oensureAscii))
- {
- encoder.forceASCII = 0;
- }
-
- if (oencodeHTMLChars != NULL && PyObject_IsTrue(oencodeHTMLChars))
- {
- encoder.encodeHTMLChars = 1;
- }
-
- if (oescapeForwardSlashes != NULL && !PyObject_IsTrue(oescapeForwardSlashes))
- {
- encoder.escapeForwardSlashes = 0;
- }
-
- if (osortKeys != NULL && PyObject_IsTrue(osortKeys))
- {
- encoder.sortKeys = 1;
- }
-
- PRINTMARK();
- ret = JSON_EncodeObject (oinput, &encoder, buffer, sizeof (buffer));
- PRINTMARK();
-
- if (PyErr_Occurred())
- {
- return NULL;
- }
-
- if (encoder.errorMsg)
- {
- if (ret != buffer)
- {
- encoder.free (ret);
- }
-
- PyErr_Format (PyExc_OverflowError, "%s", encoder.errorMsg);
- return NULL;
- }
-
- newobj = PyString_FromString (ret);
-
- if (ret != buffer)
- {
- encoder.free (ret);
- }
-
- PRINTMARK();
-
- return newobj;
-}
-
-PyObject* objToJSONFile(PyObject* self, PyObject *args, PyObject *kwargs)
-{
- PyObject *data;
- PyObject *file;
- PyObject *string;
- PyObject *write;
- PyObject *argtuple;
- PyObject *write_result;
-
- PRINTMARK();
-
- if (!PyArg_ParseTuple (args, "OO", &data, &file))
- {
- return NULL;
- }
-
- if (!PyObject_HasAttrString (file, "write"))
- {
- PyErr_Format (PyExc_TypeError, "expected file");
- return NULL;
- }
-
- write = PyObject_GetAttrString (file, "write");
-
- if (!PyCallable_Check (write))
- {
- Py_XDECREF(write);
- PyErr_Format (PyExc_TypeError, "expected file");
- return NULL;
- }
-
- argtuple = PyTuple_Pack(1, data);
-
- string = objToJSON (self, argtuple, kwargs);
-
- if (string == NULL)
- {
- Py_XDECREF(write);
- Py_XDECREF(argtuple);
- return NULL;
- }
-
- Py_XDECREF(argtuple);
-
- argtuple = PyTuple_Pack (1, string);
- if (argtuple == NULL)
- {
- Py_XDECREF(write);
- return NULL;
- }
-
- write_result = PyObject_CallObject (write, argtuple);
- if (write_result == NULL)
- {
- Py_XDECREF(write);
- Py_XDECREF(argtuple);
- return NULL;
- }
-
- Py_DECREF(write_result);
- Py_XDECREF(write);
- Py_DECREF(argtuple);
- Py_XDECREF(string);
-
- PRINTMARK();
-
- Py_RETURN_NONE;
-}
diff --git a/contrib/python/ujson/py2/python/py_defines.h b/contrib/python/ujson/py2/python/py_defines.h
deleted file mode 100644
index 2b38b41bdb..0000000000
--- a/contrib/python/ujson/py2/python/py_defines.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
-Developed by ESN, an Electronic Arts Inc. studio.
-Copyright (c) 2014, Electronic Arts Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-* Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-* Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-* Neither the name of ESN, Electronic Arts Inc. nor the
-names of its contributors may be used to endorse or promote products
-derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS INC. 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.
-
-
-Portions of code from MODP_ASCII - Ascii transformations (upper/lower, etc)
-http://code.google.com/p/stringencoders/
-Copyright (c) 2007 Nick Galbreath -- nickg [at] modp [dot] com. All rights reserved.
-
-Numeric decoder derived from from TCL library
-http://www.opensource.apple.com/source/tcl/tcl-14/tcl/license.terms
- * Copyright (c) 1988-1993 The Regents of the University of California.
- * Copyright (c) 1994 Sun Microsystems, Inc.
-*/
-
-#include <Python.h>
-
-#if PY_MAJOR_VERSION >= 3
-
-#define PyInt_Check PyLong_Check
-#define PyInt_AS_LONG PyLong_AsLong
-#define PyInt_FromLong PyLong_FromLong
-
-#define PyString_Check PyBytes_Check
-#define PyString_GET_SIZE PyBytes_GET_SIZE
-#define PyString_AS_STRING PyBytes_AS_STRING
-
-#define PyString_FromString PyUnicode_FromString
-
-#endif
diff --git a/contrib/python/ujson/py2/python/ujson.c b/contrib/python/ujson/py2/python/ujson.c
deleted file mode 100644
index d0b15c65cf..0000000000
--- a/contrib/python/ujson/py2/python/ujson.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
-Developed by ESN, an Electronic Arts Inc. studio.
-Copyright (c) 2014, Electronic Arts Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-* Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-* Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-* Neither the name of ESN, Electronic Arts Inc. nor the
-names of its contributors may be used to endorse or promote products
-derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS INC. 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.
-
-
-Portions of code from MODP_ASCII - Ascii transformations (upper/lower, etc)
-http://code.google.com/p/stringencoders/
-Copyright (c) 2007 Nick Galbreath -- nickg [at] modp [dot] com. All rights reserved.
-
-Numeric decoder derived from from TCL library
-http://www.opensource.apple.com/source/tcl/tcl-14/tcl/license.terms
-* Copyright (c) 1988-1993 The Regents of the University of California.
-* Copyright (c) 1994 Sun Microsystems, Inc.
-*/
-
-#include "py_defines.h"
-#include "version.h"
-
-/* objToJSON */
-PyObject* objToJSON(PyObject* self, PyObject *args, PyObject *kwargs);
-void initObjToJSON(void);
-
-/* JSONToObj */
-PyObject* JSONToObj(PyObject* self, PyObject *args, PyObject *kwargs);
-
-/* objToJSONFile */
-PyObject* objToJSONFile(PyObject* self, PyObject *args, PyObject *kwargs);
-
-/* JSONFileToObj */
-PyObject* JSONFileToObj(PyObject* self, PyObject *args, PyObject *kwargs);
-
-
-#define ENCODER_HELP_TEXT "Use ensure_ascii=false to output UTF-8. Pass in double_precision to alter the maximum digit precision of doubles. Set encode_html_chars=True to encode < > & as unicode escape sequences. Set escape_forward_slashes=False to prevent escaping / characters."
-
-static PyMethodDef ujsonMethods[] = {
- {"encode", (PyCFunction) objToJSON, METH_VARARGS | METH_KEYWORDS, "Converts arbitrary object recursively into JSON. " ENCODER_HELP_TEXT},
- {"decode", (PyCFunction) JSONToObj, METH_VARARGS | METH_KEYWORDS, "Converts JSON as string to dict object structure. Use precise_float=True to use high precision float decoder."},
- {"dumps", (PyCFunction) objToJSON, METH_VARARGS | METH_KEYWORDS, "Converts arbitrary object recursively into JSON. " ENCODER_HELP_TEXT},
- {"loads", (PyCFunction) JSONToObj, METH_VARARGS | METH_KEYWORDS, "Converts JSON as string to dict object structure. Use precise_float=True to use high precision float decoder."},
- {"dump", (PyCFunction) objToJSONFile, METH_VARARGS | METH_KEYWORDS, "Converts arbitrary object recursively into JSON file. " ENCODER_HELP_TEXT},
- {"load", (PyCFunction) JSONFileToObj, METH_VARARGS | METH_KEYWORDS, "Converts JSON as file to dict object structure. Use precise_float=True to use high precision float decoder."},
- {NULL, NULL, 0, NULL} /* Sentinel */
-};
-
-#if PY_MAJOR_VERSION >= 3
-
-static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "ujson",
- 0, /* m_doc */
- -1, /* m_size */
- ujsonMethods, /* m_methods */
- NULL, /* m_reload */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL /* m_free */
-};
-
-#define PYMODINITFUNC PyObject *PyInit_ujson(void)
-#define PYMODULE_CREATE() PyModule_Create(&moduledef)
-#define MODINITERROR return NULL
-
-#else
-
-#define PYMODINITFUNC PyMODINIT_FUNC initujson(void)
-#define PYMODULE_CREATE() Py_InitModule("ujson", ujsonMethods)
-#define MODINITERROR return
-
-#endif
-
-PYMODINITFUNC
-{
- PyObject *module;
- PyObject *version_string;
-
- initObjToJSON();
- module = PYMODULE_CREATE();
-
- if (module == NULL)
- {
- MODINITERROR;
- }
-
- version_string = PyString_FromString (UJSON_VERSION);
- PyModule_AddObject (module, "__version__", version_string);
-
-#if PY_MAJOR_VERSION >= 3
- return module;
-#endif
-}
diff --git a/contrib/python/ujson/py2/python/version.h b/contrib/python/ujson/py2/python/version.h
deleted file mode 100644
index f0ce6bb733..0000000000
--- a/contrib/python/ujson/py2/python/version.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-Developed by ESN, an Electronic Arts Inc. studio.
-Copyright (c) 2014, Electronic Arts Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-* Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-* Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-* Neither the name of ESN, Electronic Arts Inc. nor the
-names of its contributors may be used to endorse or promote products
-derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS INC. 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.
-
-
-Portions of code from MODP_ASCII - Ascii transformations (upper/lower, etc)
-http://code.google.com/p/stringencoders/
-Copyright (c) 2007 Nick Galbreath -- nickg [at] modp [dot] com. All rights reserved.
-
-Numeric decoder derived from from TCL library
-http://www.opensource.apple.com/source/tcl/tcl-14/tcl/license.terms
- * Copyright (c) 1988-1993 The Regents of the University of California.
- * Copyright (c) 1994 Sun Microsystems, Inc.
-*/
-
-#define UJSON_VERSION "1.35"
diff --git a/contrib/python/ujson/py2/ya.make b/contrib/python/ujson/py2/ya.make
deleted file mode 100644
index 65971c8e9b..0000000000
--- a/contrib/python/ujson/py2/ya.make
+++ /dev/null
@@ -1,30 +0,0 @@
-PY2_LIBRARY()
-
-LICENSE(BSD-3-Clause)
-
-VERSION(1.35+dev)
-
-NO_COMPILER_WARNINGS()
-NO_UTIL()
-
-PY_REGISTER(ujson)
-
-ADDINCL(
- contrib/python/ujson/py2/lib
- contrib/python/ujson/py2/python
-)
-
-SRCS(
- lib/ultrajsondec.c
- lib/ultrajsonenc.c
- python/JSONtoObj.c
- python/objToJSON.c
- python/ujson.c
-)
-
-PY_SRCS(
- TOP_LEVEL
- ujson.pyi
-)
-
-END()
diff --git a/contrib/python/ujson/ya.make b/contrib/python/ujson/ya.make
deleted file mode 100644
index 0503b6b21b..0000000000
--- a/contrib/python/ujson/ya.make
+++ /dev/null
@@ -1,18 +0,0 @@
-PY23_LIBRARY()
-
-LICENSE(Service-Py23-Proxy)
-
-IF (PYTHON2)
- PEERDIR(contrib/python/ujson/py2)
-ELSE()
- PEERDIR(contrib/python/ujson/py3)
-ENDIF()
-
-NO_LINT()
-
-END()
-
-RECURSE(
- py2
- py3
-)
diff --git a/contrib/tools/swig/CHANGES b/contrib/tools/swig/CHANGES
deleted file mode 100644
index 9001d01813..0000000000
--- a/contrib/tools/swig/CHANGES
+++ /dev/null
@@ -1,27992 +0,0 @@
-SWIG (Simplified Wrapper and Interface Generator)
-
-See the CHANGES.current file for changes in the current version.
-See the RELEASENOTES file for a summary of changes in each release.
-Issue # numbers mentioned below can be found on Github. For more details, add
-the issue number to the end of the URL: https://github.com/swig/swig/issues/
-
-Version 4.1.0 (24 Oct 2022)
-===========================
-
-2022-10-24: wsfulton, AndLLA
- [R] #2386 Fix problems in shared_ptr wrappers where the class names
- were not consistent when using the shared_ptr template or the actual
- underlying type.
-
-2022-10-24: wsfulton
- [R] Add support for special variable replacement in the $typemap()
- special variable macro for R specific typemaps (rtype, rtypecheck,
- scoercein, scoereout).
-
-2022-10-24: wsfulton
- [R] Polymorphism in the wrappers was only working for C++ classes,
- now this works for C++ structs too.
-
-2022-10-19: olly
- [Lua] #2126 Fix type resolution between multiple SWIG-wrapped
- modules.
-
-2022-10-17: wsfulton
- [R] #2385 Add support for std::vector<std::vector<std::string>>.
-
-2022-10-14: murillo128
- [Javascript] #2109 Tweak unsigned long and unsigned long long typemaps
- to create a v8::Number instead of v8::Integer if the value exceeds
- the size of v8::Integer. Note that the v8::Number value will be
- imprecise if the value is > MAX_SAFE_INTEGER.
-
-2022-10-14: olly
- [R] Arrange that destructors of local C++ objects in the wrapper
- function get run on SWIG_fail (which calls Rf_error() which calls
- longjmp()).
-
-2022-10-14: olly
- [Lua] Arrange that destructors of local C++ objects in the wrapper
- function get run on SWIG_fail (which calls lua_error() which calls
- longjmp()).
-
-2022-10-13: wsfulton
- [R] Add missing SWIGTYPE *const& typemaps for supporting pointers
- by const reference.
-
-2022-10-10: wsfulton
- #2160 Fix compile error when using templates with more than one template
- parameter and used as an input parameter in a virtual method in a
- director class (problem affecting most of the scripting languages).
-
-2022-10-10: treitmayr, wsfulton
- [Python, Ruby] #1811 #1823 Fix invalid code generated in some cases when
- returning a pointer or reference to a director-enabled class instance.
- This previously only worked in very simple cases, now return types are
- resolved to fix. A bug in template instantiations using pointers also
- works now.
-
-2022-10-06: wsfulton
- [CFFI] #1966 #2200 Remove code for Common Lisp CFFI. We dropped support
- for it in SWIG 4.0.0 by disabling it as the first stage. This is the
- final stage for complete removal as there has been no meaningful
- progress to revive it to the status of experimental language.
-
-2022-10-06: olly
- [Python] #2390 Remove deprecated and apparently useless defarg.swg
-
- The only documentation is in the file itself and describes a Python
- wrapper around the C function defined here, but digging though the
- git history this Python wrapper doesn't seem to have ever actually
- been generated by SWIG.
-
- This file was also marked as deprecated in 2005.
-
-2022-10-06: wsfulton
- [Java] #2048 Fix quoting for doxygen \image command to quote the output
- file name generated into the html src attribute.
-
-2022-10-05: benjamin-sch
- [Python] added an interpreter counter to fix deinitialization
- issues if multiple subinterpreters are used
-
-2022-10-05: olly, wsfulton
- #672 Add support for parsing C++11 final classes such as:
-
- class X final {};
-
- This no longer gives a syntax error.
-
-2022-10-05: wsfulton
- [OCaml] Fix %rename for enum items. Previously the rename had no effect.
-
-2022-10-05: olly
- #1465 Report errors in preprocessor expressions by default
-
- Until now SWIG quietly ignored such errors unless -Wextra (or -Wall
- which implies -Wextra) was passed, but this is unhelpful as it tends
- to hide genuine problems. To illustrate this point, enabling this
- warning by default revealed a typo in the preproc_defined.i
- testcase in SWIG's own testsuite.
-
- If you really don't want to see this warning, you can suppress it
- with command line option -w202 or by using this in your interface
- file:
-
- %warnfilter(SWIGWARN_PP_EVALUATION);
-
- Both will work with older versions of SWIG too.
-
-2022-10-04: olly
- #1050 Consistently define SWIG_VERSION both at SWIG-time and in
- the generated wrapper. Best practice remains to check at SWIG-time
- where possible because that results in smaller generated wrapper
- sources.
-
- SWIGGO and SWIGJAVASCRIPT are now defined in the generated wrappers
- to match behaviour for all other target languages.
-
- The undocumented SWIGVERSION macro is no longer defined.
-
-2022-09-29: olly
- #2303 SWIG's internal hash tables now use a better hash function.
-
- The old hash function only considerd the last five characters
- plus the least significant bit of the last-but-sixth character,
- which as you might guess generated a lot of many-way collisions.
-
- This change seems to give about a 4% reduction in wallclock time
- for processing li_std_list_wrap.i from the testsuite for Python.
- The hash collision rate for this example drops from 39% to 0!
-
-2022-09-29: wsfulton
- #2303 Type tables are now output in a fixed order whereas previously
- the order may change with any minor input code change. This shouldn't
- affect users except SWIG_TypePrettyName may output a different C/C++
- typedef to a type - it's used mostly for showing errors when the type
- passed to a function is wrong.
-
-2022-09-29: olly
- [PHP] Dynamic class properties are no longer supported by default.
-
- Historically PHP has supported dynamic class properties and SWIG
- has implemented them too (because we implement the magic __get(),
- __set() and __isset() methods we need to include explicit
- handling).
-
- PHP 8.2 deprecates dynamic class properties - initially they'll
- warn, and apparently they'll not work by default in PHP 9.0:
- https://wiki.php.net/rfc/deprecate_dynamic_properties
-
- In PHP code dynamic properties can be enabled for a class by
- marking that class with the attribute `#[AllowDynamicProperties]`.
-
- To follow this PHP change, in SWIG you now need to specify
- `%feature("php:allowdynamicproperties", 1) Foo;` (or
- `%feature("php:allowdynamicproperties", 1)` to enable it for
- all wrapped classes). Unknown features are ignored, so you can add
- it unconditionally and it'll work with older SWIG too.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2022-09-19: wsfulton
- #1484 Fixes for class inheritance with the same name in different namespaces
- such as:
-
- namespace A { class Bar {}; }
- namespace B { template<typename T, typename U> class Bar : public A::Bar {}; }
-
-2022-09-19: wsfulton
- #2316 Remove swig.spec file and srcrpm makefile target. These are very out of date
- and don't seem to be used by RPM based Linux distributions which have their
- own version of swig.spec.
-
-2022-09-17: wsfulton
- [Go, Guile, Racket, Scilab] Add throws typemaps for std::string so that thrown
- string exception messages can be seen.
-
-2022-09-17: wsfulton
- [Racket] Add throws typemaps for char * so that thrown string exception
- messages can be seen from Racket.
-
-2022-09-17: wsfulton
- [Javascript, Octave, R] Improve exceptions for %catches and exception
- specifications for native types. String exception messages are shown as
- the exception message instead of just the type of the exception.
-
-2022-09-17: wsfulton
- Add missing typecheck typemaps for std::auto_ptr and std::unique_ptr to
- fix overloading when using these types.
-
-2022-09-17: wsfulton
- [Guile] Add error checking to SWIGTYPE and SWIGTYPE & in typemaps to prevent
- seg faults when passing #nil to these parameter types.
-
-2022-09-16: wsfulton
- #999 Provide SWIGTYPE MOVE typemaps in swigmove.i for implementing full
- move semantics when passing parameters by value.
-
-2022-08-31: wsfulton
- #999 Improve move semantics when using rvalue references.
- The SWIGTYPE && input typemaps now assume the object has been moved.
-
- These typemaps have been changed assuming that after the function call,
- the rvalue reference parameter has been moved. The parameter's proxy class
- that owns the C++ object thus has the underlying pointer set to null
- so that the (moved from, but still valid) C++ object cannot be used again
- and the object is additionally deleted.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2022-08-28: wsfulton
- [Octave] SWIG now marshals a C/C++ NULL pointer into the null matrix, [].
- SWIG has always marshalled the null matrix into a NULL pointer; this remains
- and now we have consistency in representing a NULL pointer.
-
-2022-08-26: wsfulton
- [Racket] SWIG now marshals a C/C++ NULL pointer into a null value by calling
- scheme_make_null(), so that scheme's null? is true for a NULL C/C++ pointer value.
-
-2022-08-18: wsfulton
- [Racket] Add support for std::unique_ptr in std_unique_ptr.i.
- Add support for std::auto_ptr in std_auto_ptr.i.
-
-2022-08-13: wsfulton
- [Guile] Add support for std::unique_ptr in std_unique_ptr.i.
- Add support for std::auto_ptr in std_auto_ptr.i.
-
-2022-08-11: wsfulton
- [Lua] Add support for std::unique_ptr in std_unique_ptr.i.
- Add support for std::auto_ptr in std_auto_ptr.i.
-
-2022-08-05: wsfulton
- [D] Fix occasional undefined behaviour with inheritance hierarchies, particularly
- when using virtual inheritance as the pointers weren't correctly upcast from derived
- class to base class when stored in the base's proxy class.
-
-2022-08-05: wsfulton
- [D] Add support for std::unique_ptr in std_unique_ptr.i.
- Add support for std::auto_ptr in std_auto_ptr.i.
-
-2022-08-03: wsfulton
- [Javascript] Add support for std::unique_ptr in std_unique_ptr.i.
- Add support for std::auto_ptr in std_auto_ptr.i.
-
-2022-08-02: wsfulton
- [Octave] Add support for std::unique_ptr in std_unique_ptr.i.
- Add support for std::auto_ptr in std_auto_ptr.i.
-
-2022-08-01: wsfulton
- [Python] Add initialisers for additional members in PyHeapTypeObject
- (builtin mode) for Python-3.11 - _ht_tpname, _spec_cache.
-
-2022-07-30: wsfulton
- C++20 has deprecated std::basic_string<>::reserve() and the C++11 method
- std::basic_string<>::shrink_to_fit() is a replacement that can be used.
- std_string.i and std_wstring.i provided wrappers for reserve with the following
- template instantiations:
-
- %template(string) std::basic_string<char>;
- %template(wstring) std::basic_string<wchar_t>;
-
- The reserve method is no longer wrapped, however the shrink_to_fit() method
- can be used as an alternative from the target language (the generated wrappers
- call reserve() instead if C++<=20).
-
- Note that std::basic_string<>::reserve(size_t n) is still wrapped unchanged.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2022-07-30: wsfulton
- [Tcl] Add support for std::unique_ptr in std_unique_ptr.i.
- Add support for std::auto_ptr in std_auto_ptr.i.
-
-2022-07-27: ZackerySpytz, olly
- #1678 Support parsing C++20 templated lambdas.
-
-2022-07-27: ZackerySpytz, olly
- #1622 Add support for the C++20 spaceship operator (<=>).
-
-2022-07-26: olly
- [Tcl] https://sourceforge.net/p/swig/bugs/977/
- Fix handling of long long on 32-bit platforms. This fix raises
- SWIG's minimum supported Tcl version to 8.4.0 (which was released
- just under 20 years ago).
-
-2022-07-26: olly
- Fix incorrect operator precedence in preprocessor expressions.
-
-2022-07-25: olly
- Support for C++14 binary integer literals in preprocessor expressions.
-
-2022-07-20: wsfulton
- [C#, Java] Ensure the order of interfaces generated in proxy interfaces for the
- %interface family of macros is the same as that parsed from the bases in C++.
-
-2022-07-20: jicks, Ingener74, olly
- #422 [Python] Fix mishandling of a Python class inheriting from
- multiple SWIG-wrapped director classes.
-
-2022-07-19: wsfulton
- #692 [C#, Java, Perl, Python, Ruby] std::unique_ptr and std::auto_ptr typemaps
- provided for inputs types in std_unique_ptr.i and std_auto_ptr.i.
-
- Now these smart pointers can be used as input parameters to functions. A proxy
- class instance transfers memory ownership of the underlying C++ object from the
- proxy class to a smart pointer instance passed to the wrapped function.
-
-2022-07-19: jschueller
- [Python] #2314 Drop support for Python 3.2.
-
-2022-07-19: olly
- Remove remaining support code for classic macos, which has not been
- supported by Apple for over 20 years now.
-
-2022-07-12: wsfulton
- #999 Performance optimisation for parameters passed by value that are C++11 movable.
- The C++ wrappers create a temporary variable for a parameter to be passed to a
- function. This is initially default constructed and then copy assigned from the
- instance being passed in from the target language. This is unchanged, however,
- when the temporary variable is passed to the wrapped function, it is now done using
- std::move. If the type is move constructible, the move constructor will be used
- instead of the copy constructor.
-
-2022-07-12: wsfulton
- [Perl] Add std::auto_ptr support in std_auto_ptr.i library file.
-
-2022-07-12: erezgeva
- [Perl] Add std::unique_ptr support in std_unique_ptr.i library file.
-
-2022-07-07: jmarrec
- #1158 #2286 Add basic support for C++11 attributes. These are now
- crudely ignored by SWIG's parser's tokeniser, which is better that
- failing with a parse error.
-
-2022-07-05: ianlancetaylor
- [Go] #2245 Handle NULL pointers for string* conversions.
- Rearrange generation of director methods and rename
- receiver argument from p to swig_p.
-
-2022-07-03: wsfulton
- #999 Performance optimisation for directors for classes passed by value. The directorin
- typemaps in the director methods now use std::move on the input parameter when
- copying the object from the stack to the heap prior to the callback into the target
- language, thereby taking advantage of move semantics if available.
-
-2022-07-02: wsfulton
- #1722 [C#, Java, Python, Ruby] Add std::unique_ptr support. Ported from std::auto_ptr.
- Use the %unique_ptr(T) macro as follows for usage std::unique_ptr<T>. For example, for
- a class called Klass:
-
- %include "std_unique_ptr.i"
- %unique_ptr(Klass)
-
- Support is currently limited to only returning a std::unique_ptr from a function.
-
-2022-06-29: wsfulton
- #999 #1044 Enhance SWIGTYPE "out" typemaps to use std::move when copying
- objects, thereby making use of move semantics when wrapping a function returning
- by value if the returned type supports move semantics.
-
- Wrapping functions that return move only types 'by value' now work out the box
- without having to provide custom typemaps.
-
- The implementation removed all casts in the "out" typemaps to allow the compiler to
- appropriately choose calling a move constructor, where possible, otherwise a copy
- constructor. The implementation also required modifying SwigValueWrapper to
- change a cast operator from:
-
- SwigValueWrapper::operator T&() const;
-
- to
-
- #if __cplusplus >=201103L
- SwigValueWrapper::operator T&&() const;
- #else
- SwigValueWrapper::operator T&() const;
- #endif
-
- This is not backwards compatible for C++11 and later when using the valuewrapper feature
- if a cast is explicitly being made in user supplied "out" typemaps. Suggested change
- in custom "out" typemaps for C++11 and later code:
-
- 1. Try remove the cast altogether to let the compiler use an appropriate implicit cast.
- 2. Change the cast, for example, from static_cast<X &> to static_cast<X &&>, using the
- __cplusplus macro if all versions of C++ need to be supported.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2022-06-15: wsfulton
- #2039 Add move assignment operator to SwigValueWrapper used by the
- valuewrapper feature.
-
-2022-06-04: sethrj
- Enhance $typemap to support typemap attributes.
-
- $typemap(method:attribute, typepattern)
-
- For example:
-
- %typemap(cstype, out="object") XClass "XClass"
- %typemap(cscode) BarClass %{
- $typemap(cstype:out, XClass) bar() {
- return null;
- }
-
- which expands to
-
- object bar() {
- return null;
- }
-
-2022-05-30: wsfulton
- [C#, D] Add new special variable expansion: $imfuncname.
- Expands to the function name called in the intermediary class.
-
-2022-05-30: LindleyF
- [Java] #2042 Add new special variable expansion: $imfuncname.
- Expands to the function name called in the intermediary class.
-
-2022-05-28: jkuebart
- [Java] On some versions of Android, specifically Android 6,
- detaching the current thread from the JVM after every invocation
- causes a memory leak.
-
- Offer SWIG_JAVA_DETACH_ON_THREAD_END to configure a behaviour
- where the JVM is only detached in the thread destructor.
-
- See https://developer.android.com/training/articles/perf-jni#threads.
-
-2022-05-27: xypron
- [Python] #2277 Define PY_SSIZE_T_CLEAN macro before #include "Python.h" as
- recommended in Python 3.7 and later.
-
- To avoid this macro definition, add the following to your interface file so
- that SWIG_NO_PY_SSIZE_T_CLEAN is defined at the beginning of the C++ wrappers:
-
- %begin %{
- #define SWIG_NO_PY_SSIZE_T_CLEAN
- %}
-
-2022-05-26: rokups
- [C#] #1323 Modify SwigDerivedClassHasMethod for a more efficient director
- implementation when calling virtual methods that are not overridden.
-
-2022-05-15: erezgeva, eiselekd
- [Lua, Perl, Octave, PHP, Tcl] #2275 #2276 #2283 Add argcargv.i library containing
- (int ARGC, char **ARGV) multi-argument typemaps.
-
- Document this library in Typemaps.html.
-
-2022-05-07: KrisThielemans
- [Python] Fix "too many initializers for 'PyHeapTypeObject'" errors
- using PyPy 3.8 and later.
-
-2022-05-04: wsfulton
- [C#] Add C# wchar_t * director typemaps
-
-2022-04-20: cminyard
- Fix an issue where newlines were not properly generated
- for godirectorin typemaps. If you have a virtual function
- not assigned to zero, in some cases it won't generate a
- newline and you will see errors:
- example.go:1508:3: expected ';', found swig_r
- when compiling the go code.
-
- Also add an example of using goin and godirectorin and add
- a test for this situation.
-
-2022-04-29: jason-daly, JerryJoyce, wsfulton
- [C#] #1233 Add wchar_t * and std::wstring Unicode string support on Linux.
-
-2022-04-11: robinst
- #2257 Fix new Ruby 3.2 warning "undefining the allocator of T_DATA
- class swig_runtime_data".
-
-2022-04-07: olly
- #1750 SWIG now recognises and ignores Doxygen group commands `@{` and `@}`.
-
-2022-04-06: wsfulton
- ./configure now enables C++11 and later C++ standards testing by default (when
- running: 'make check').
-
- The options to control this testing are the same:
-
- ./configure --enable-cpp11-testing
- ./configure --disable-cpp11-testing
-
- But the former is now the default and the latter can be used to turn off C++11 and
- later C++ standards testing.
-
-2022-04-06: wsfulton
- [Python] #1635 The "autodoc" feature no longer overrides Doxygen comments
- in the generated docstring.
-
- If a "docstring" feature is present it will still override a Doxygen comment.
- If the "autodoc" feature is also present, the combined "autodoc" and "docstring"
- will override the Doxygen comment. If no "docstring" is present then the
- "autodoc" feature will not be generated when there is a Doxygen comment.
-
- This way the "autodoc" feature can be specified and used to provide documentation
- for 'missing' Doxygen comments.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2022-04-01: olly
- Remove undocumented and non-functional -browse command line option.
-
-2022-03-26: eltoder
- [Python] #1684 Use different capsule names with and without -builtin
-
- Types generated with and without -builtin are not compatible. Mixing
- them in a common type list leads to crashes. Avoid this by using
- different capsule names: "type_pointer_capsule" without -builtin and
- "type_pointer_capsule_builtin" with.
-
-2022-03-25: wsfulton
- The debug command line options that display parse tree nodes
- (-debug-module, -debug-top, -debug-symtabs) now display previously hidden
- linked list pointers which are useful for debugging parse trees.
-
- Added new command line option -debug-quiet. This suppresses the display
- of most linked list pointers and symbol table pointers in the parse tree nodes.
-
- The keys in the parse tree node are now shown in alphabetical order.
-
-2022-03-24: wsfulton
- #2244 Fix using declaration in derived class bugs when all the base
- class's overloaded methods were overridden in the derived class -
- fixes "multiply defined" errors.
-
-2022-03-23: wsfulton
- [Python] #1779 The -py3 option is deprecated and now has no effect on the
- code generated. Use of this option results in a deprecated warning.
- The related SWIGPYTHON_PY3 macro that this option defined is no longer generated.
-
- Note that %pythonnondynamic feature generates a metaclass that works on both
- Python 2 and Python 3.
-
-2022-03-21: wsfulton
- [Python] #1779 pyabc.i for abstract base classes now supports versions of
- Python prior to 3.3 by using the collection module for these older versions.
- Python-3.3 and later continue to use the collections.abc module.
- The -py3 option no longer has any effect on the %pythonabc feature.
-
-2022-03-21: jschueller, jim-easterbrook, wsfulton
- [Python] #2137 C++ static member functions no longer generate a "flattened"
- name in the Python module. For example:
-
- s = example.Spam()
- s.foo() # Spam::foo() via an instance
- example.Spam.foo() # Spam::foo() using class method
- example.Spam_foo() # Spam::foo() "flattened" name
-
- The "flattened" name is no longer generated, but can be generated
- by using the new -flatstaticmethod option.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2022-03-18: ianlancetaylor
- [Go] #337 Implement %extend base methods in child classes.
-
-2022-03-17: olly
- [Python] #1779 SWIG's Python test-suite and examples are now
- run with Python 3 by default. To run them with Python 2, set
- PY2 to a non-empty value, e.g.:
-
- make check-python-test-suite PY2=1
-
-2022-03-16: olly
- [Go] #683 -intgosize is now optional - if not specified the
- generated C/C++ wrapper code will use ptrdiff_t for intgo and
- size_t for uintgo.
-
-2022-03-15: ianlancetaylor
- [Go] Add typemaps for std::string*.
-
-2022-03-15: ianlancetaylor
- [Go] Don't convert arrays to pointers if there is a "gotype"
- typemap entry.
-
-2022-03-15: ianlancetaylor
- [Go] Add documentation note about Go and C++ exceptions.
-
-2022-03-12: wsfulton
- #1524 %interface family of macros no longer contain the getter/setter
- methods for wrapping variables. The interface only contains
- virtual and non-virtual instance methods, that is, no static methods.
- Enums are also no longer added to the interface (affects Java only where
- they were missing from the proxy class, C# never had them in the interface).
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2022-03-12: wsfulton
- #1277 Fixes for the family of %interface macros, %interface,
- %interface_impl and %interface_custom fixes for overloaded methods
- in an inheritance chain.
-
- When C++ methods are not able to be overloaded in a derived class,
- such as when they differ by just const, or the target language
- parameters types are identical even when the C++ parameter types
- are different, SWIG will ignore one of the overloaded methods with
- a warning. A %ignore is required to explicitly ignore one of the
- overloaded methods to avoid the warning message. Methods added
- in the derived classes due to one of the %interface macros are now
- similarly ignored/not added to the derived class.
-
- The methods added to the derived classes can now also be modified
- via %feature and %rename.
-
-2022-03-08: ianlancetaylor
- [Go] Treat a nil argument as a NULL pointer.
-
-2022-03-08: ianlancetaylor
- [Go] Add documentation notes about thread local storage.
-
-2022-03-08: olly
- #1006 SWIG now copes with an interface filename specified on the
- command line which contains a closing parenthesis `)`, and more
- generally with attributes to `%include` and `%import` which
- are quoted and contain parentheses.
-
-2022-03-07: Omar Medina
- [Tcl] https://sourceforge.net/p/swig/bugs/1290/
- Fix SWIG_AsWCharPtrAndSize() to actually assign to result
- variable. It looks like SWIG/Tcl wide character handling is
- currently fundamentally broken except on systems which use wide
- characters as the system encoding, but this should fix wrapping
- functions which take a wide string as a parameter on Microsoft
- Windows.
-
-2022-03-07: olly
- [Javascript] #682 Fix handling of functions which take void*.
-
-2022-03-06: olly
- SWIG should now reliably exit with status 0 if the run was
- successful and status 1 if there was an error (or a warning and
- -Werror was in effect).
-
- Previously in some situations SWIG would try to exit with the
- status set to the number of errors encountered, but that's
- problematic - for example if there were 256 errors this would
- result in exit status 0 on most platforms. Also some error
- statuses have special meanings e.g. those defined by <sysexits.h>.
- Also SWIG/Javascript tried to exit with status -1 in a few places
- (which typically results in exit status 255).
-
-2022-03-05: wsfulton
- #1441 Fix using declaration in derived class incorrectly introducing a method
- from a base class when the using declaration is declared before the method
- declaration. Problem occurred when within a namespace and the parameter types
- in the method signatures were not fully qualified.
-2022-03-05: ianlancetaylor
- [Go] Treat non-const references as pointers.
-
-2022-03-05: ianlancetaylor
- In SWIG Go testsuite, fail test if "go build" fails.
-
-2022-03-03: olly
- #1901 #2223 SWIG should now always exit cleanly if memory
- allocation fails, including removing any output files created
- during the current run.
-
- Previously most places in the code didn't check for a NULL return
- from malloc()/realloc()/calloc() at all, typically resulting in
- undefined behaviour; some places used assert() to check for a NULL
- return (which is a misuse of assert() and such checks disappear if
- built with NDEBUG defined leaving us back with undefined
- behaviour).
-
-2022-03-03: olly
- #891 Report errors for typemap attributes without a value
- (previously SWIG segfaulted) and for typemap types with a value
- (previously the value was quietly ignored).
-
- The old way of specifying a language name in the typemap attributes
- is no longer supported (it has been deprecated for 16 years).
-
-2022-03-02: geographika, wsfulton
- [Python] #1951 Add Python variable annotations support.
-
- Both function annotations and variable annotations are turned on using the
- "python:annotations" feature. Example:
-
- %feature("python:annotations", "c");
-
- struct V {
- float val;
- };
-
- The generated code contains a variable annotation containing the C float type:
-
- class V(object):
- val: "float" = property(_example.V_val_get, _example.V_val_set)
- ...
-
- Python 3.5 and earlier do not support variable annotations, so variable
- annotations can be turned off with a "python:annotations:novar" feature flag.
- Example turning on function annotations but not variable annotations globally:
-
- %feature("python:annotations", "c");
- %feature("python:annotations:novar");
-
- or via the command line:
-
- -features python:annotations=c,python:annotations:novar
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2022-02-27: wsfulton
- [Python] #735 #1561 Function annotations containing C/C++ types are no longer
- generated when using the -py3 option. Function annotations support has been
- moved to a feature to provide finer grained control. It can be turned on
- globally by adding:
-
- %feature("python:annotations", "c");
-
- or by using the command line argument:
-
- -features python:annotations=c
-
- Also see entry dated 2022-03-02, regarding variable annotations.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2022-02-26: wsfulton
- #655 #1840 Add new warning WARN_LANG_USING_NAME_DIFFERENT to warn when a
- method introduced by a using declaration in a derived class cannot
- be used due to a conflict in names.
-
-2022-02-24: olly
- #1465 An invalid preprocessor expression is reported as a pair of
- warnings with the second giving a more detailed message from the
- expression evaluator. Previously SWIG prefixed the second message
- with "Error:" - that was confusing as it's actually only a warning
- by default so we've now dropped this prefix.
-
- Before:
-
- x.i:1: Warning 202: Could not evaluate expression '1.2'
- x.i:1: Warning 202: Error: 'Floating point constant in preprocessor expression'
-
- Now:
-
- x.i:1: Warning 202: Could not evaluate expression '1.2'
- x.i:1: Warning 202: Floating point constant in preprocessor expression
-
-2022-02-23: olly
- #1384 Fix a preprocessor expression evaluation bug. A
- subexpression in parentheses lost its string/int type flag and
- instead used whatever type was left in the stack entry from
- previous use. In practice we mostly got away with this because
- most preprocessor expressions are integer, but it could have
- resulted in a preprocessor expression incorrectly evaluating as
- zero. If -Wextra was in use you got a warning:
-
- Warning 202: Error: 'Can't mix strings and integers in expression'
-
-2022-02-21: davidcl
- [Scilab] Improve 5.5.2, 6.0.0 and 6.1.0 support.
-
- For Scilab 5, long names are reduced to small names preserving the
- class prefix and accessor suffix (get or set).
-
- For Scilab 6, long names with the class prefix and accessor suffix
- should be used on the user code.
-
- The `-targetversion` option has been removed as the generated code
- now detects the Scilab version in loader.sce or builder.sce.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2022-02-20: wsfulton
- Fix %warnfilter warning suppress for warning 315 SWIGWARN_PARSE_USING_UNDEF.
-
-2022-02-17: olly
- [PHP] https://sourceforge.net/p/swig/bugs/1211/
- Fix to call cleanup code in exception situations and not to invoke
- the freearg typemap twice in certain situations.
-
-2022-02-15: olly
- #300 #368 Improve parser handling of % followed immediately by
- an identifier. If it's not a recognised directive the scanner
- now emits MODULO and then rescans what follows, and if the parser
- then gives a syntax error we report it as an unknown directive.
- This means that `a%b` is now allowed in an expression, and that
- things like `%std::vector<std::string>` now give an error rather
- than being quietly ignored.
-
-2022-02-11: adr26
- [Python] #2154 Fix memory leak.
-
- SWIG python objects were being freed after the corresponding SWIG
- module information was destroyed in Python 3, causing leaks when as
- a result the object destructor could not be invoked. To prevent this
- misordering, SWIG python objects now obtain a reference to the
- Python capsule wrapping the module information, so that the module
- information is correctly destroyed after all SWIG python objects
- have been freed (and corresponding destructors invoked).
-
-2022-02-10: olly
- [Tcl] https://sourceforge.net/p/swig/bugs/1207/
- https://sourceforge.net/p/swig/bugs/1213/
-
- Fix Tcl generic input typemap for std::vector.
-
-2022-02-07: sethrj
- #2196 Add alternative syntax for specifying fragments in typemaps.
-
- New syntax:
- %typemap("in", fragment="frag1", fragment="frag2", fragment="frag3") {...}
- which is equivalent to:
- %typemap(in, fragment="frag1,frag2,frag3") {...}
-
-
-2022-02-07: olly
- #1806 Remove support for the "command" encoder, which was mostly
- intended for use in `%rename` - most uses can be achieved using
- the "regex" encoder, so we recommend using that instead.
-
- The "command" encoder suffers from a number of issues - as the
- documentation for it admitted, "[it] is extremely slow compared to
- all the other [encoders] as it involves spawning a separate process
- and using it for many declarations is not recommended" and that it
- "should generally be avoided because of performance
- considerations".
-
- But it's also not portable. The design assumes that `/bin/sh`
- supports `<<<` but that's a bash-specific feature so it doesn't
- work on platforms where `/bin/sh` is not bash - it fails on
- Debian, Ubuntu and probably some other Linux distros, plus most
- non-Linux platforms. Microsoft Windows doesn't even have a
- /bin/sh as standard.
-
- Finally, no escaping of the passed string is done, so it has
- potential security issues (though at least with %rename the input
- is limited to valid C/C++ symbol names).
-
-2022-02-06: olly
- #2193 -DFOO on the SWIG command line now sets FOO to 1 for
- consistency with C/C++ compiler preprocessors. Previously
- SWIG set FOO to an empty value.
-
- Existing invocations of SWIG with `-DFOO` where the empty value
- matters can be updated to `-DFOO=` which should work with both
- old and new releases of SWIG.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2022-02-06: sethrj
- #2194 Classes that are non-assignable due to const data or const
- reference members are now automatically detected.
-
-2022-02-04: friedrichatgc
- [Octave] #1672 Fix for isobject for Octave 4.4 - 6.0.
-
-2022-02-03: olly
- [C#] #283 #998 Fix memory leak in directorin typemap for
- std::string.
-
-2022-02-03: olly
- [Python] #967 Make `self` parameter available to user typemaps.
-
-2022-02-03: teythoon
- [Python] #801 Fix -Wunused-parameter warnings with builtin,
-
-2022-02-03: teythoon
- #801 Fix -Wstrict-prototypes warnings in generated pointer
- functions.
-
-2022-02-03: olly
- #660 https://sourceforge.net/p/swig/bugs/1081/
- Default parameter values containing method calls are now parsed and
- handled - e.g. `x->foo(3,4)` and `y.z()`.
-
-2022-02-02: olly
- [Ruby] https://sourceforge.net/p/swig/bugs/1136/ Fix remove of prefix
- from method name to only remove it at the start.
-
-2022-02-01: olly
- #231 Handle returning an object by reference in a C++ trailing
- return type.
-
-2022-02-01: davidcl
- [Scilab] #745 use SWIG_<module>_Init() as a C module init function.
-
-2022-02-01: olly
- [OCaml] #2083 Fix to work when CAML_SAFE_STRING is on, which it is
- by default in recent Ocaml releases.
-
-2022-01-31: mreeez
- https://sourceforge.net/p/swig/bugs/1147/
- Fix copyToR() generated for a struct in a namespace.
-
-2022-01-29: fschlimb
- #655 Better handling of using declarations.
-
-2022-01-29: dontpanic92
- [Go] #676 Fix code generated for a C++ class with a non-capitalised
- name.
-
-2022-01-26: trex58
- #1919 #1921 #1923 Various fixes for AIX portability.
-
-2022-01-26: olly
- #1935 Don't crash on an unclosed HTML tag in a doxygen comment
- when -doxygen is specified.
-
-2022-01-25: olly
- Constant expressions now support member access with `.` such as
- `foo.bar`. Previous this only worked in a case like `x->foo.bar`.
-
-2022-01-25: olly
- #2091 Support most cases of `sizeof` applied to an expression
- in constant expressions. Previously there was only support for
- `sizeof(<type>)` and expressions which syntactically look like a
- type (such as `sizeof(foo)`).
-
-2022-01-25: olly
- #80 #635 https://sourceforge.net/p/swig/bugs/1139/
- Add support for parsing common cases of `<` and `>` comparisons
- in constant expressions. Adding full support for these seems hard
- to do without introducing conflicts into the parser grammar, but in
- fact all reported cases have had parentheses around the comparison
- and we can support that with a few restrictions on the left side of
- `<`.
-
-2022-01-25: wsfulton
- New warning 327 for extern templates, eg:
-
- extern template class std::vector<int>;
- extern template void Func<int>();
-
- results in warning
-
- example.i:3: Warning 327: Extern template ignored.
- example.i:4: Warning 327: Extern template ignored.
-
- Extern template classes previously resulted in warning 320.
-
-2022-01-24: romintomasetti
- #2131 #2157 C++11 extern function template parsing error fix.
-
-2022-01-21: wsfulton
- #2120 #2138 Replace legacy PCRE dependency with PCRE2.
- This requires changes for building SWIG from source. See updated
- html documentation in Preface.html and Windows.html. Updated
- instructions are also shown when running ./configure if PCRE2 is not
- found. Note that debian based systems can install PCRE2 using:
-
- apt install libpcre2-dev
-
- Note that https://github.com/swig/swig/wiki/Getting-Started also has
- updated information for building from source.
-
-2022-01-19: olly
- [PHP] #2027 Automatically generate PHP type declarations for PHP 8.
- The generate code still compiles for PHP 7.x, but without type
- declarations since PHP 7.x has much more limited type declaration
- support.
-
-2022-01-18: olly
- [Perl] #1629 Perl 5.8.0 is now the oldest version we aim to support.
-
-2022-01-14: wsfulton
- [Python] Fix %callback and specifying the callback function as a
- static member function using Python staticmethod syntax, such as
- Klass.memberfunction instead of Klass_memberfunction when using
- -builtin and -fastproxy.
-
-2022-01-11: wsfulton
- [Python] Accept keyword arguments accessing static member functions when
- using -builtin and kwargs feature and Python class staticmethod syntax.
- The missing keyword argument support was only when using the
- class staticmethod syntax, such as Klass.memberfunction, and not when
- using the flat static method syntax, such as Klass_memberfunction.
-
-2022-01-04: juierror
- [Go] #2045 Add support for std::array in std_array.i.
-
-2021-12-18: olly
- [PHP] Add PHP keyword 'readonly' (added in 8.1) to the list SWIG
- knows to automatically rename. This keyword is special in that PHP
- allows it to be used as a function (or method) name.
-
-2021-12-07: vstinner
- [Python] #2116 Python 3.11 support: use Py_SET_TYPE()
-
-2021-12-05: rwf1
- [Octave] #2020 #1893 Add support for Octave 6 up to and including 6.4.
- Also add support for compiling with -Bsymbolic which is used by default
- by mkoctfile.
-
-2021-12-02: jsenn
- [Python] #2102 Fixed crashes when using embedded Python interpreters.
-
-2021-11-12: wsfulton
- [Javascript] v8 and node only. Fix mismatched new char[] and free()
- when wrapping C code char arrays. Now calloc is now used instead of
- new char[] in SWIG_AsCharPtrAndSize.
-
-2021-10-03: ajrh1
- [Perl] #2074: Avoid -Wmisleading-indentation in generated code
- when using gcc11.
-
-2021-10-03: jschueller
- [CMake] #2065: Add option to enable or disable PCRE support.
-
-2021-09-16: ianlancetaylor
- [Go] Improved _cgo_panic implementation.
-
-2021-09-16: ianlancetaylor
- [Go] Don't use crosscall2 for panicking. Instead rely on documented
- and exported interfaces.
-
-2021-09-14: ianlancetaylor
- [Go] Remove -no-cgo option (long unsupported in Go)
-
-2021-05-04: olly
- [PHP] #2014 Throw PHP exceptions instead of using PHP errors
-
- PHP exceptions can be caught and handled if desired, but if they
- aren't caught then PHP exits in much the same way as it does for a
- PHP error.
-
- In particular this means parameter type errors and some other cases
- in SWIG-generated wrappers now throw a PHP exception, which matches
- how PHP's native parameter handling deals with similar situations.
-
- `SWIG_ErrorCode()`, `SWIG_ErrorMsg()`, `SWIG_FAIL()` and `goto thrown;`
- are no longer supported (these are really all internal implementation
- details and none are documented aside from brief mentions in CHANGES
- for the first three). I wasn't able to find any uses in user interface
- files at least in FOSS code via code search tools.
-
- If you are using these:
-
- Use `SWIG_PHP_Error(code,msg);` instead of `SWIG_ErrorCode(code);
- SWIG_ErrorMsg(msg);` (which will throw a PHP exception in SWIG >= 4.1
- and do the same as the individual calls in older SWIG).
-
- `SWIG_FAIL();` and `goto thrown;` can typically be replaced with
- `SWIG_fail;`. This will probably also work with older SWIG, but
- please test with your wrappers if this is important to you.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2021-05-17: adr26
- [Python] #1985 Fix memory leaks:
-
- 1. Python object references were being incorrectly retained by
- SwigPyClientData, causing swig_varlink_dealloc() never to run / free
- memory. SwigPyClientData_New() / SwigPyClientData_Del() were updated
- to fix the object reference counting, causing swig_varlink_dealloc()
- to run and the memory swig_varlink owns to be freed.
-
- 2. SwigPyClientData itself was not freed by SwigPyClientData_Del(),
- causing another heap leak. The required free() was added to
- SwigPyClientData_Del()
-
- 3. Fix reference counting/leak of python cached type query
-
- 4. Fix reference counting/leak of SwigPyObject dict (-builtin)
-
- 5. Python object reference counting fixes for out-of-memory
- scenarios were added to: SWIG_Python_RaiseOrModifyTypeError(),
- SWIG_Python_AppendOutput(), SwigPyClientData_New(),
- SwigPyObject_get___dict__() and SwigPyObject_format()
-
- 6. Add error handling for PyModule_AddObject() to
- SWIG_Python_SetModule() (failure could be caused by OOM or a name
- clash caused by malicious code)
-
-2021-05-13: olly
- [UFFI] #2009 Remove code for Common Lisp UFFI. We dropped support
- for it in SWIG 4.0.0 and nobody has stepped forward to revive it in
- over 2 years.
-
-2021-05-13: olly
- [S-EXP] #2009 Remove code for Common Lisp S-Exp. We dropped
- support for it in SWIG 4.0.0 and nobody has stepped forward to
- revive it in over 2 years.
-
-2021-05-13: olly
- [Pike] #2009 Remove code for Pike. We dropped support for it in
- SWIG 4.0.0 and nobody has stepped forward to revive it in over 2
- years.
-
-2021-05-13: olly
- [Modula3] #2009 Remove code for Modula3. We dropped support for it
- in SWIG 4.0.0 and nobody has stepped forward to revive it in over 2
- years.
-
-2021-05-13: olly
- [CLISP] #2009 Remove code for GNU Common Lisp. We dropped support
- for it in SWIG 4.0.0 and nobody has stepped forward to revive it in
- over 2 years.
-
-2021-05-13: olly
- [Chicken] #2009 Remove code for Chicken. We dropped support for it
- in SWIG 4.0.0 and nobody has stepped forward to revive it in over 2
- years.
-
-2021-05-13: olly
- [Allegrocl] #2009 Remove code for Allegro Common Lisp. We dropped
- support for it in SWIG 4.0.0 and nobody has stepped forward to
- revive it in over 2 years.
-
-2021-05-04: olly
- [PHP] #1982 #1457 https://sourceforge.net/p/swig/bugs/1339/
- SWIG now only use PHP's C API to implement its wrappers, and no
- longer generates PHP code to define classes. The wrappers should
- be almost entirely compatible with those generated before, but
- faster and without some previously hard-to-fix bugs.
-
- The main notable difference is SWIG no longer generates a .php
- wrapper at all by default (only if %pragma(php) code=... or
- %pragma(php) include=... are specified in the interface file).
- This also means you need to load the module via extension=...
- in php.ini, rather than letting the dl() in the generated
- .php wrapper load it (but dl() has only worked for command-line
- PHP for some years now).
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2021-04-30: olly
- #1984 Remove support for $source and $target.
- These were officially deprecated in 2001, and attempts to use them have
- resulted in a warning (including a pointer to what to update them to)
- for most if not all of that time.
-
-2021-04-27: wsfulton
- #1987 [Java] Fix %interface family of macros for returning by const
- pointer reference.
-
-2021-04-19: olly
- Fix use of uninitialised variable in the generated code for an
- empty typecheck typemap, such as the dummy one we include for
- std::initializer_list.
-
-2021-04-12: olly
- #1777 [Python] Specifying -py3 now generates a check for Python
- version >= 3.0.
-
-2021-03-26: olly
- [PHP] Add PHP keywords 'fn' (added in 7.4) and 'match' (added in
- 8.0) to the list SWIG knows to automatically rename.
-
-2021-03-23: wsfulton
- #1942 [Python] Fix compilation error in wrappers when using -builtin
- and wrapping varargs in constructors.
-
-2021-03-22: goto40
- #1977 Fix handling of template template parameters.
-
-2021-03-21: olly
- #1929, #1978 [PHP] Add support for PHP 8.
-
-2021-03-19: wsfulton
- #1610 Remove -ansi from default compilation flags.
-
-2021-03-19: dot-asm
- #1934 [Java] Clean up typemaps for long long arrays.
-
-2021-03-19: olly
- #1527 [PHP] Improve PHP object creation in directorin case.
- Reportedly the code we were using in this case gave segfaults in
- PHP 7.2 and later - we've been unable to reproduce these, but the
- new approach is also simpler and should be bit faster too.
-
-2021-03-18: olly
- #1655 [PHP] Fix char* typecheck typemap to accept PHP Null like the
- corresponding in typemap does.
-
-2021-03-18: olly
- #1900, #1905 [PHP] Fix wrapping of overloaded directed methods with
- non-void return.
-
-2021-03-11: murillo128
- #1498 [Javascript] Support type conversion.
-
-2021-03-06: nshmyrev
- #872 [Javascript] Various typemap issues in arrays_javascript.i fixed.
-
-2021-03-03: vaughamhong
- #577 [Javascript] Implemented SetModule/GetModule for JSC to allow type sharing
- across modules.
-
-2021-03-01: xantares, Oliver Buchtala, geographika
- #1040 Add support for building SWIG with CMake. See documentation in Windows.html.
-
-2021-03-01: vadz
- #1952 Fix incorrect warning "Unknown Doxygen command: ."
-
-2021-02-28: p2k
- #969 [Javascript] v8/node - prevent crash calling a constructor without new keyword.
-
-2021-02-28: alecmev
- #405 #1121 [Javascript] Fix OUTPUT typemaps on methods that don't return void.
- The output value is appended to the return value.
-
-2021-02-26: murillo128, wsfulton
- #1269 [Javascript] Fix handling of large positive unsigned long and
- unsigned long long values.
-
-2021-02-24: tomleavy, yegorich, tungntpham
- #1746 [Javascript] Add support for Node v12, v14 and v16.
- SWIG support for Node is now for v6 and later only.
-
-2020-02-09: ZackerySpytz
- #1872 Fix typos in attribute2ref macros.
-
-2020-10-10: wsfulton
- [Javascript] Fix so that ccomplex.i interface to file can be used.
-
-2020-10-10: wsfulton
- #252 complex can now be used as a C identifier and doesn't give a syntax error.
-
-2020-10-10: lpsinger
- #1770 Correct C complex support.
- _Complex is now parsed as a keyword rather than complex as per the C99 standard.
- The complex macro is available in the ccomplex.i library file along with other
- complex number handling provided by the complex.h header.
-
-2020-10-07: ZackerySpytz
- [Python] #1812 Fix the error handling for the PyObject_GetBuffer() calls in
- pybuffer.i.
-
-2020-10-07: treitmayr
- #1824 Add missing space in director method declaration returning
- const pointer.
-
-2020-10-07: adelva1984
- #1859 Remove all (two) exceptions from SWIG executable.
-
-2020-09-25: wsfulton
- [C#, Java] #1874 Add ability to change the modifiers for the interface
- generated when using the %interface macros.
-
- For C# use the 'csinterfacemodifiers' typemap.
- For Java use the 'javainterfacemodifiers' typemap.
-
- For example:
-
- %typemap(csinterfacemodifiers) X "internal interface"
-
-2020-09-24: geefr
- [C#] #1868 Fix wchar_t* csvarout typemap for member variable wrappers.
-
-2020-08-28: wsfulton
- [Java] #1862 Fix crashes in swig_connect_director during director class construction
- when using the director class from multiple threads - a race condition initialising
- block scope static variables. The fix is guaranteed when using C++11, but most
- compilers also fix it when using C++03/C++98.
-
-2020-08-16: wsfulton
- [Python] Add missing initializer for member '_heaptypeobject::ht_module' when using
- -builtin to complete Python 3.9 support.
-
-2020-08-16: wsfulton
- [Python] Remove PyEval_InitThreads() call for Python 3.7 and later as Python calls
- it automatically now. This removes a deprecation warning when using Python 3.9.
-
-2020-08-15: wsfulton
- [Python] All Python examples and tests are written to be Python 2 and Python 3
- compatible, removing the need for 2to3 to run the examples or test-suite.
-
-2020-08-13: wsfulton
- [C#] Add support for void *VOID_INT_PTR for member variables.
-
-2020-07-29: chrisburr
- #1843 [Python] Compilation error fix in SwigPyBuiltin_SetMetaType when using PyPy.
-
-2020-06-14: ZackerySpytz
- #1642 #1809 Fix virtual comparison operators in director classes by removing an
- incorrect space in the function name (for example, operator= = is now operator==).
-
-Version 4.0.2 (8 Jun 2020)
-==========================
-
-2020-06-07 vigsterkr
- [Ruby] #1717 Nil fix mangling strings
-
-2020-06-07 vadz
- #1748 Fix doxygen comments quoting issue
-
-2020-06-07 munoah
- #1800 Escape spaces in file paths for dependencies (-M -MM etc)
-
-2020-06-06 andreas-schwab
- [Ruby] #1801 Fix encoding on big endian systems when wrapping std::wstring.
-
-2020-05-31 kwwette
- [Octave] #1789 error handling improvements and return error code on exit for SWIG wrapped modules.
-
-2020-05-30 msteinbeck
- [D] #1593 Replace broken imports when using newer versions of D.
-
-2020-05-29: ZackerySpytz
- [Python] #1716 Performance improvements when converting strings when using Python >= 3.3.
-
-2020-05-28: ZackerySpytz
- #1776 Quite dramatically decrease run times when generating very large interface files by changing
- some internal memory pool sizes.
-
-2020-05-28: mcfarljm
- #1788 Fix handling of Doxygen \endlink command.
-
-2020-05-24: vapier
- [Javascript] #1796 Fix pkg-config invocation in configure.
-
-2020-04-30: kwwette
- [Octave] Fix exception raising for newer Octave versions
- Since (at least) Octave 5.1.0, the Octave error() function now raises a C++ exception,
- which if uncaught immediately exits a SWIG wrapper function, bypassing any cleanup code
- that may appear after a "fail:" label. This patch adds a "try { ... } catch(...) { }"
- block around the contents of SWIG wrapper functions to first execute the cleanup code
- before rethrowing any exception raised. It is backward compatible with earlier versions
- of Octave where error() does not raise an exception, which will still branch to the
- "fail:" block to execute cleanup code if an error is encountered.
-
- Note that the new "try { ... } catch(...) { }" block will localise any local variables
- used in typemaps that were NOT declared through SWIG's %typemap(...) syntax, so it's
- possible this could break existing SWIG wrappers which were implicitly sharing local
- variables between typemaps. This can be fixed, however, by declaring local variables
- which need to be shared between typemaps through SWIG's %typemap(...) syntax.
-
-2020-02-18: ryannevell
- [Lua] #1728 Add support for LUA lightuserdata to SWIG_Lua_ConvertPtr.
-
-2020-02-18: dmach
- [Ruby] #1725 Fix gcc -Wcatch-value warnings.
-
-2020-02-14: treitmayr
- #1724 Fix wrapping of abstract user-defined conversion operators.
-
-2020-02-13: ddurham2
- [Python] #1512 Fix memleak when using STL containers of shared_ptr objects.
-
-2020-02-06: wsfulton
- [Python] #1673 #1674 Fix setting 'this' when extending a proxy class with __slots__.
-
-2020-01-31: vadz
- [Ruby] #1651 Add std::auto_ptr<> typemaps.
-
-2020-01-31: ZackerySpytz
- [Python] #1700 The Python C API functions PyBytes_AsStringAndSize() and
- PyString_AsStringAndSize() are now checked for failure.
-
-2020-01-31: vadz
- [Python] #1710 Fix crash parsing empty docstrings.
-
-2020-01-30: Alzathar
- [R] #910 #914 Fix R memory leak on exception.
-
-2020-01-30: richardbeare
- [R] #1511 Fix bug wrapping functions. These were previously incorrectly wrapped as if
- they were variables. This happened when 'get' or 'set' was in the name of the function
- or method, but sometimes also in some other circumstances. If you were using R
- attribute syntax to access these methods, you'll need to switch to calling them as R
- methods.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2020-01-24: etse-dignitas, wsfulton
- [C#, D, Java] #1533 Fix upcasting for shared_ptr's of templated types.
-
-2020-01-16: mcfarljm
- #1643 #1654 When using -doxygen, fix segfault when nameless parameters or vararg parameters
- are used.
-
-2020-01-16: mcfarljm
- #1632 #1659 Fix newline handling for doxygen "///" comments.
-
-2020-01-14: mcfarljm
- #1647 #1656 Fix crash handling empty doxygen comments.
-
-2020-01-14: mcfarljm
- #1608 Improve doxygen support.
- - Add support for \param[] commands such as: \param[in].
- - Optional arguments are marked as 'optional' in pydoc.
- - Improve support for \code commands so that other languages are supported as code blocks.
- Support added for java, c and py. For example Python: \code{.py} ... \endcode
- - Fix doxygen handling of \em and \p tags for Python.
-
-2020-01-13: wsfulton
- [Python] #1595 Python -builtin constructors silently ignored keyword arguments.
- Instead of silently ignoring them, now a "TypeError: f() takes no keyword arguments"
- exception is thrown if keyword arguments are used. Hence constructors and normal methods/
- functions behave in the same way. Note, -keyword should be used with -builtin to obtain
- keyword argument support.
-
-2020-01-05: jschueller shadchin
- [Python] #1670 #1696 Add missing field initializers introduced in python 3.8:
- tp_vectorcall and tp_print.
-
-2020-01-05: friedrichatgc
- [Octave] #1688 Change swig_this() to use size_t instead of long for compatibility
- with Windows 64 bit.
-
-2020-01-05: treitmayr
- [Ruby] #1692 #1689 Add support for Ruby 2.7
-
-2019-12-30: treitmayr
- [Ruby] #1653 #1668 Fix code generated when using -globalmodule option.
-
-2019-12-29: ZackerySpytz
- [OCaml] #1686 Fix compilation errors with OCaml 4.09.0.
-
-2019-12-10: wsfulton
- #1679 Fix parsing of C++11 identifiers with special meaning (final and override) when
- they are used as part of the scope name of an identifier, such as a namespace name.
-
-2019-11-26: wsfulton
- [C#] #1628 'out' or 'ref' used in a cstype typemap was not always stripped out in parts
- of director code generation.
-
-2019-11-01: wsfulton
- [Python] #1595 Fix bug in support for keyword arguments (kwargs feature or -keyword)
- when using -builtin. The fix is in the argument error checking when wrapping zero
- argument constructors only.
-
-Version 4.0.1 (21 Aug 2019)
-===========================
-
-2019-08-20: TekuConcept
- [Javascript] #1535 Add %native support to Javascript.
-
-2019-08-20: bkotzz
- [Java] #1616 Add SWIG_JavaIllegalStateException to support throwing
- java.lang.IllegalStateException from JNI code.
-
-2019-08-19: sjml
- [Lua] #1596 tostring output changes to show the underlying C/C++ pointer.
-
-2019-08-08: rokups
- [C#, Java] #1601 Fix invalid code generated for "%constant enum EnumType.
-
-2019-08-07: wsfulton
- [Python] Fix method overloading of methods that take STL containers of different
- types. The following usage (using std::vector) would fail when using -builtin:
-
- %include <std_string.i>
- %include <std_vector.i>
-
- %inline %{
- struct X {};
- %}
-
- %template(VectorX) std::vector<X>;
- %template(VectorInt) std::vector<int>;
-
- %inline %{
- using namespace std;
- string VectorOverload(vector<X> v);
- string VectorOverload(vector<int> v);
- %}
-
- The following would incorrectly fail:
-
- s = VectorOverload([1, 2, 3])
-
- With:
-
- Traceback (most recent call last):
- File "runme3.py", line 20, in <module>
- ret = VectorOverload([1, 2, 3])
- TypeError: Wrong number or type of arguments for overloaded function 'VectorOverload'.
- Possible C/C++ prototypes are:
- VectorOverload(std::vector< Number,std::allocator< Number > >)
- VectorOverload(std::vector< int,std::allocator< int > >)
-
- The problem was due to some error handling that was not cleared during typechecking.
- In this case an error was not cleared when the elements in the list failed the
- typecheck for converting to X. Only occurs in Python 3+.
-
- In some combinations of overloaded methods, the following type of error message would
- occur:
-
- RuntimeError: in sequence element 0
-
- The above exception was the direct cause of the following exception:
-
- Traceback (most recent call last):
- File "runme3.py", line 23, in <module>
- check(VectorOverload(v), "vector<X>")
- SystemError: <built-in function VectorOverload> returned a result with an error set
-
-2019-08-01: wsfulton
- #1602 Fix regression in 4.0.0 where a template function containing a parameter
- with the same name as the function name led to the parameter name used in the
- target language being incorrectly modified.
-
-2019-07-29: wsfulton
- Remove all generated files on error. Previously generated files were not removed,
- potentially breaking Makefiles using file dependencies, especially when -Werror
- (warnings as errors) was used.
-
-2019-07-23: smithx
- [C#] #1530 #1532 Fix marshalling of std::wstring to C#.
-
-2019-07-18: gicmo
- [Python] #1587 Python 3.8 support - remove use of deprecated PyObject_GC_UnTrack.
-
-2019-07-18: cher-nov
- [Python] #1573 Generated Python code uses consistent string quoting style - double
- quotes.
-
-2019-07-16: geefr
- [C#] #616 #1576 Fix C# bool INPUT[], bool OUTPUT[], bool INOUT[] typemaps to marshall
- as 1-byte.
-
-2019-07-12: vadz
- [C#, Java] #1568 #1583 Fix std::set<> typemaps for primitive types.
-
-2019-07-12: vadz
- #1566 #1584 Regression in 4.0.0 - fix missing value for first item of enums with
- trailing comma.
-
-2019-07-11: mcfarljm
- #1548 #1578 Fix segfault in Doxygen parser parsing empty lines in some commands like
- \code.
-
-2019-07-09: IsaacPascual
- [C#, Java] #1570 Fix name of generated C#/Java classes for %interface macros
- in swiginterface.i when wrapping nested C++ classes.
-
-2019-07-05: wsfulton
- [Python] #1547 Whitespace fixes in Doxygen translated comments into pydoc comments
- for Sphinx compatibility.
-
-2019-06-28: wsfulton
- [MzScheme, OCaml] #1559 $arg and $input were incorrectly substituted in the
- argout typemap when two or more arguments were present.
-
-2019-06-24: wsfulton
- [Python, Ruby] #1538 Remove the UnknownExceptionHandler class in order to be
- C++17 compliant as it uses std::unexpected_handler which was removed in C++17.
- This class was intended for director exception handling but was never used by
- SWIG and was never documented.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2019-06-06: bkotzz
- [Java] #1552 Improve performance in Java std::vector constructor wrapper that takes
- a native Java array as input.
-
-2019-06-03: olly
- [Python] Fix regression in implicit_conv handling of tuples,
- introduced in SWIG 4.0.0. Fixes #1553, reported by Alexandre
- Duret-Lutz.
-
-2019-05-24: wsfulton
- [Octave] Fix detection of Octave on MacOS.
-
-2019-05-24: opoplawski
- [Octave] #1522 Adapt OCTAVE_LDFLAGS for Octave 5.1.
-
-2019-05-22: ferdynator
- [PHP] #1528 Don't add a closing '?>' PHP tag to generated files.
- PSR-2 says it MUST be omitted for files containing only PHP.
-
-Version 4.0.0 (27 Apr 2019)
-===========================
-
-2019-04-24: vadz
- #1517 Fix crash if "@return" Doxygen tag was used on a node without any return type.
-
-2019-04-24: vadz
- #1515 Fix parsing of enums with trailing comma when using -doxygen.
-
-2019-04-19: ianlancetaylor
- [Go] #1055 When generating Go code, make -cgo the default. Add new -no-cgo option
- to disable the default.
-
-2019-04-19: pbecherer
- [Tcl] #1508 Fix Visual Studio 2015 and later compilation errors due to snprintf macro
- definition.
-
-2019-04-09: wsfulton
- [C#] Fix FxCop warning CA2002 in SWIGPendingException - a lock on a reference of
- type 'Type'.
-
-2019-03-30: wsfulton
- [Java, D] Add the parameters typemap attribute to the javadestruct,
- javadestruct_derived, ddispose, ddispose_derived typemaps to mirror enhanced
- flexibility in the csdisposing and csdisposing_derived (C#) typemaps. If provided
- the contents are generated as the delete/dispose method's parameters declaration.
-
-2019-03-30: wsfulton
- [C#] #421 Fix FxCop warning CA1063 by implementing the recommended Dispose methods for
- the IDisposable interface. Previously just the Dispose() method was generated.
- Now the Dispose() and Dispose(bool disposing) methods are generated.
- Changes are required if custom "csfinalize", "csdestruct" or "csdestruct_derived"
- typemaps are being used. Details in #421 on Github. SWIG will error out if one of
- the "csfinalize, "csdestruct" or "csdestruct_derived" typemaps are found. Example
- error message:
-
- foo.h:60: Error: A deprecated csfinalize typemap was found for Foo, please remove
- it and replace all csdestruct, csdestruct_derived and csfinalize typemaps by the
- csdispose, csdispose_derived, csdisposing and csdisposing_derived typemaps.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2019-03-25: Liryna
- [C#] #1143 Add std_list.i for std::list support.
- The C# std::list<T> wrappers are made to look and feel like a C#
- System.Collections.Generic.LinkedList<> collection.
- The IEnumerable<> interface is implemented in the proxy class.
- The ICollection<> interface can also be implemented to provide enhanced functionality
- whenever a C++ operator== is available. This is the case for when T is a
- primitive type or a pointer. If T does define an operator==, then use the
- SWIG_STD_LIST_ENHANCED macro to obtain this enhanced functionality, for example:
-
- SWIG_STD_LIST_ENHANCED(SomeNamespace::Klass)
- %template(ListKlass) std::list<SomeNamespace::Klass>;
-
-2019-03-18: richardbeare
- [R] #1328 Non-trivial enums are working now. The enum values are now obtained from
- the C/C++ layer. const reference enums and C++11 enum classes are also now working.
-
-2019-03-14: mochizk
- [Javascript] #1500 Fix compilation errors due to deprecating V8 API in Node.js.
- New V8 API is used if node.js >= v10.12, or if V8 >= v7.0.
-
-2019-03-12: vadz
- [C#] #1495 Add std_set.i for std::set support.
-
-2019-03-11: dirteat,opoplawski
- [Octave] Fix compilation errors in Octave 5.1.
-
- error: format not a string literal and no format arguments [-Werror=format-security]
-
-2019-02-28: wsfulton
- [Java] std::vector improvements for types that do not have a default constructor.
-
- The std::vector wrappers have been changed to work by default for elements that are
- not default insertable, i.e. have no default constructor. This has been achieved by
- not wrapping:
-
- vector(size_type n);
-
- Previously the above had to be ignored via %ignore.
-
- If the above constructor is still required it can be added back in again via %extend:
-
- %extend std::vector {
- vector(size_type count) { return new std::vector< T >(count); }
- }
-
- Alternatively, the following wrapped constructor could be used as it provides near-enough
- equivalent functionality:
-
- vector(jint count, const value_type& value);
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2019-02-25: wsfulton
- [Python] Fix compile errors wrapping overloaded functions/constructors where a vararg
- function is declared after a non-vararg function.
-
-2019-02-23: zphensley42
- Use fully qualified name 'java.lang.Object' instead of 'Object' in generated code to
- avoid clashes with wrapped C++ classes called 'Object'.
-
-2019-02-23: gtbX
- [Java] #1035 Add (const char *STRING, size_t LENGTH) typemaps in addition to the non-const
- typemaps (char *STRING, size_t LENGTH) which does not attempt to write back to the const
- string.
-
-2019-02-22: tamuratak
- [Ruby] #984 Add support for RTypedData introduced in Ruby 1.9.3.
-
-2019-02-22: ZackerySpytz
- #1483 Fix compilation failures when a director class has final methods.
-
-2019-02-21: wsfulton
- [Java] #1240 Suppress Java 9 deprecation warnings on finalize method.
-
-2019-02-21: ZackerySpytz
- #1480 Fix some rejections of valid floating-point literals.
-
-2019-02-19: wsfulton
- #1475 Fix regression parsing gcc preprocessor linemarkers in the form:
-
- # linenum filename flags
-
-2019-02-18: jakecobb
- [Python] #945 #1234 Elements in std::vector memory access fix.
-
- Accessing an element in a std::vector obtains a reference to the element via an
- iterator pointing to the element in the container. If the vector is garbage collected,
- the SWIG wrapper containing the pointer to the element becomes invalid. The fix is
- to obtain a back-reference to the container by the wrapper to the element in the Python
- layer to prevent the garbage collector from destroying the underlying container.
-
-2019-02-17: wsfulton
- Fix typemap matching to expand template parameters when the name contains
- template parameters. In the %typemap below the type is T and the name is X<T>::make
- and the name now expands correctly to X< int >::make
-
- template<typename T> struct X {
- %typemap(out) T X<T>::make "..."
- T make();
- };
-
- %template(Xint) X<int>;
-
-2019-02-16: wsfulton
- Fix parser error containing multiple #define statements inside an enum.
-
- The second #define fails to parse:
-
- enum FooEnum {
- ENUM1 = 0,
- ENUM2 = 1,
-
- #define MACRO_DEF1 "Hello"
- #define MACRO_DEF2 "World!"
-
- ENUM3 = 2,
- ENUM4 = 3,
- };
-
- Bug mentioned at https://sourceforge.net/p/swig/patches/333/
-
-2019-02-14: wsfulton
- Add some missing copy constructors into STL containers.
-
-2019-02-14: bkotzz
- [Java] #1356 Add STL containers:
- std::unordered_map
- std::unordered_set
- std::set
-
-2019-02-14: bkotzz
- [Java] #1356 std::map wrappers have been modified. Now the Java proxy class
- extends java.util.AbstractMap. The std::map container looks and feels much like
- a java.util.HashMap from Java.
-
- A few members have changed their names. If the old method signatures are needed,
- then copy std_map.i from swig-3.0.12 and use that instead. Alternatively,
- add the old missing methods to the new methods by using the following %proxycode:
-
- %extend std::map {
- %proxycode %{
- // Old API
- public boolean empty() {
- return isEmpty();
- }
- public void set($typemap(jboxtype, K) key, $typemap(jboxtype, T) x) {
- put(key, x);
- }
- public void del($typemap(jboxtype, K) key) {
- remove(key);
- }
- public boolean has_key($typemap(jboxtype, K) key) {
- return containsKey(key);
- }
- %}
- }
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2019-02-13: ZackerySpytz
- #1469 Add support for C++17 hexadecimal floating literals.
-
-2019-02-11: wsfulton
- [OCaml] #1437 OCaml has been give the 'Experimental' language status. The examples work
- and most of the test-suite is also working, so it is quite close to being a 'Supported' language.
-
-2019-02-10: ZackerySpytz
- #1464 Add support for C++14 binary integer literals.
-
-2019-02-10: ZackerySpytz
- #1450 Add support for C++11 UCS-2 and UCS-4 character literals. Also, add support for
- C++17 UTF-8 character literals.
-
-2019-02-10: wsfulton
- [MzScheme] #1437 MzScheme/Racket is now an 'Experimental' language. The examples work
- and a large portion of the test-suite is also working.
-
-2019-02-10: wsfulton
- [MzScheme] Destructor wrappers were not being generated.
-
-2019-02-10: wsfulton
- [MzScheme] Static variable wrappers fixed - $argnum was not expanded.
-
-2019-02-10: sethrj
- #1452 Fix %apply for anonymous template instantiations
-
-2019-02-09: olly
- [PHP] Fix access to already released memory during PHP module
- shutdown, which often didn't cause visible problems, but could
- result in segmentation faults, bus errors, etc. Fixes #1170,
- reported by Jitka Plesníková.
-
-2019-02-09: olly
- [PHP] A renamed constructor is now wrapped as a static method in
- PHP.
-
-2019-02-08: olly
- [PHP] Don't generate code which references $r when $r hasn't been
- defined. This could happen in overloaded methods which returned
- void and took at least one const std::string& parameter.
-
-2019-02-08: olly
- [PHP] The generated code is now compatible with PHP 7.3, and the
- testsuite now runs cleanly with this version too.
-
-2019-02-05: wsfulton
- #1437 SWIG now classifies the status of target languages into either 'Experimental' or
- 'Supported'. This status is provided to indicate the level of maturity to expect when using
- a particular target language as not all target languages are fully developed. Details are
- in the Introduction.html chapter of the documentation.
-
-2019-02-04: wsfulton
- [CFFI] #1447 Common Lisp CFFI has been disabled as a target language in SWIG as part of a
- clean up to remove target languages that have been neglected/not functional.
-
-2019-02-04: wsfulton
- [Allegrocl] #1447 Allegro Common Lisp has been disabled as a target language in SWIG as part of a
- clean up to remove target languages that have been neglected/not functional.
-
-2019-02-04: wsfulton
- [Chicken] #1447 CHICKEN has been disabled as a target language in SWIG as part of a
- clean up to remove target languages that have been neglected/not functional.
-
-2019-02-04: wsfulton
- [CLISP] #1447 GNU Common Lisp has been disabled as a target language in SWIG as part of a
- clean up to remove target languages that have been neglected/not functional.
-
-2019-02-04: wsfulton
- [S-EXP] #1447 Common Lisp S-Exp has been disabled as a target language in SWIG as part of a
- clean up to remove target languages that have been neglected/not functional.
-
-2019-02-04: wsfulton
- [UFFI] #1447 Common Lisp UFFI has been disabled as a target language in SWIG as part of a
- clean up to remove target languages that have been neglected/not functional.
-
-2019-02-04: wsfulton
- [Pike] #1447 Pike has been disabled as a target language in SWIG as part of a
- clean up to remove target languages that have been neglected/not functional.
-
-2019-02-04: wsfulton
- [Modula3] #1447 Modula3 has been disabled as a target language in SWIG as part of a
- clean up to remove target languages that have been neglected/not functional.
-
-2019-02-02: ahnolds
- [Python] Documentation enhancements for Python:
-
- #728 Fixed the handling of autodoc when using -fastproxy.
-
- #1367 Added documentation to wrapped member variables using the
- property(... doc="...") construct.
-
- Only show a single documentation entry for functions with default arguments when
- using autodoc.
-
- Fixed a bug where a cached doxygen docstring could be deleted while still in use,
- causing swig to segfault.
-
-2019-01-31: olly
- SWIG now requires a target language to be specified instead of
- defaulting to wrapping for Tcl. Specifying swig --help without
- a target language now just shows the generic help. The -nolang
- option has been removed.
-
-2019-01-28: ZackerySpytz
- [OCaml] #1429 Remove support for OCaml versions < 3.12.0.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2019-01-22: vadz
- [Ruby, Octave] #1424 Improve autodoc parameter naming.
-
-2019-01-22: vadz
- [Python] #1271 #1423 Always include default parameter values in autodoc strings.
-
-2019-01-19: vadz
- #1272, #1421 When a function's parameter is a keyword, the name of the paramater is
- no longer simply changed to argN, where N is the argument number. Instead the
- parameter name is changed to the renaming rules for keywords that normally apply to
- symbols such as classes/functions etc. Note that unlike other symbol renaming,
- parameter renaming does not issue a warning when the parameter is renamed. This
- change only affects languages where the parameter names are actually used, for example,
- Java function parameter lists in the proxy class or Python documentation comments.
-
-2019-01-18: wsfulton
- #1420 Fix gdb debugger functions 'swigprint' and 'locswigprint' from swig.gdb to
- work with newer versions of gdb-8. Fixes errors when debugging SWIG source with gdb:
-
- (gdb) swigprint n
- Undefined command: "Printf". Try "help".
-
-2019-01-16: wsfulton
- Python static method wrapper changes
-
- - Static method wrappers were using the 'fastproxy' approach by default.
- This is inconsistent with instance method wrappers. The fastproxy approach
- is now turned off by default to be consistent with instance methods.
- Static method wrappers can now also be controlled using the -fastproxy and
- -olddefs options.
-
- Example:
-
- struct Klass {
- static int statmethod(int a = 2);
- };
-
- generates by default:
-
- class Klass(object):
- ...
- @staticmethod
- def statmethod(a=2):
- return _example.Klass_statmethod(a)
-
- instead of the following (which can be restored by using -fastproxy):
-
- class Klass(object):
- ...
- statmethod = staticmethod(_example.Klass_statmethod)
-
- - Modernise wrappers for static methods to use decorator syntax - @staticmethod.
-
- - Add missing runtime test for static class methods and using the actual class method.
-
-2019-01-12: ZackerySpytz
- [OCaml] #1403 #1194 Fix compilation problems for OCaml >= 4.03.0 due to OCaml using
- int64_t instead of int64.
-
-2019-01-11: ZackerySpytz
- [OCaml] #1400 Fix the getters and setters of non-static member variables.
-
-2019-01-07: wsfulton
- #358 Add VOID to windows.i
-
-2019-01-05: wsfulton
- #948 #1019 #1273 Fix for C++11 raw strings where the delimiters were mistakenly left
- in the string contents in situations where the string was copied into generated code.
- For example, %constant, the "docstring" feature and for C#/Java/D constants turned on
- with %javaconst/%csconst/%dmanifestconst.
-
-2019-01-05: wsfulton
- [Ruby] #538. Fix Ruby support for %feature("docstring").
-
-2019-01-03: wsfulton
- #1202 Fix overloading of non-pointer class types in scripting languages when overloaded
- with a pointer and a NULL scripting language equivalent is used, eg None in Python.
-
- The implementation changes the SWIGTYPE, SWIGTYPE& and SWIGTYPE&& typecheck typemaps to
- prevent accepting a conversion to a NULL pointer.
-
-2019-01-03: ZackerySpytz
- [OCaml] #1386 Fix the OCaml examples and test suite for out-of-source builds.
-
-2019-01-01: wsfulton
- [Python] #639 remove duplicate proxy method definitions for global function wrappers.
-
- Global functions previously generated two definitions, eg:
-
- def foo():
- return _example.foo()
- foo = _example.foo
-
- The first definition is replaced by the second definition and so the second definition
- is the one used when the method is actually called. Now just the first definition is
- generated by default and if the -fastproxy command line option is used, just the second
- definition is generated. The second definition is faster as it avoids the proxy Python
- method as it calls the low-level C wrapper directly. Using both -fastproxy and -olddefs
- command line options will restore the previously generated code as it will generate both
- method definitions.
-
- With this change, the wrappers for global C/C++ functions and C++ class methods now work
- in the same way wrt to generating just a proxy method by default and control via
- -fastproxy/-olddefs options.
-
-2018-12-20: hasinoff,wsfulton
- [Java] #1334 Set Java thread name to native thread name when using directors.
-
- Default is to use name "Thread-XXX" and is still works like this by default. However,
- adding the following will turn on the thread name setting (works for more recent
- versions of Linux and MacOS):
-
- %begin %{
- #define SWIG_JAVA_USE_THREAD_NAME
- %}
-
-2018-12-20: chlandsi
- [Python] #1357. Fix overriding __new__ in Python 3.6.
-
- Fixes SystemError: Objects/tupleobject.c:81: bad argument to internal function"
-
-2018-12-16: wsfulton
- [Python] #848 #1343 The module import logic has changed to stop obfuscating real ImportError
- problems. Only one import of the low-level C/C++ module from the pure Python module is
- attempted now. Previously a second import of the low-level C/C++ module was attempted
- after an ImportError occurred and was done to support 'split modules'. A 'split module' is
- a configuration where the pure Python module is a module within a Python package and the
- low-level C/C++ module is a global Python module. Now a 'split module' configuration is
- no longer supported by default. This configuration can be supported with a simple
- customization, such as:
-
- %module(package="mypackage", moduleimport="import $module") foo
-
- or if using -builtin:
-
- %module(package="mypackage", moduleimport="from $module import *") foo
-
- instead of
-
- %module(package="mypackage") foo
-
- See the updated Python chapter titled "Location of modules" in the documentation.
-
-2018-12-11: tlby
- [Perl] #1374 repair EXTEND() handling in typemaps
-
-2018-12-06: vadz
- #1359 #1364 Add missing nested class destructor wrapper when the nested class is
- inside a template. Removes associated bogus 'Illegal destructor name' warning. Only
- occurred when the nested class' destructor is explicitly specified.
-
-2018-12-04: adr26
- [Python] #1368 #1369 Access Violation in tp_print caused by mismatched Python/extension
- CRT usage
-
- Remove all use of tp_print, as this API uses a FILE*, which can be
- mismatched when modules are built with different C libraries from
- the main python executable.
-
- This change also brings consistent output between Python 2 and 3 for the 'cvar' SWIG
- object (that contains the global variables) and SWIG packed objects (such as callback
- constants).
-
-2018-12-04: wsfulton
- [Python] #1282 Fix running 'python -m' when using 'swig -builtin'
-
- Similar to the earlier PEP 366 conforming fix for non-builtin.
-
-2018-11-29: adr26
- [Python] #1360 Leak of SWIG var link object
-
- Fix reference counting on _SWIG_globals to allow var link to be freed on module unload.
-
-2018-11-28: wsfulton
- [Python] When using -builtin, the two step C-extension module import is now
- one step and the wrapped API is only available once and not in an underlying
- module attribute like it is without -builtin. To understand this, consider a
- module named 'example' (using: %module example). The C-extension is compiled into
- a Python module called '_example' and a pure Python module provides the actual
- API from the module called 'example'. It was previously possible to additionally
- access the API from the module attribute 'example._example'. The latter was an
- implementation detail and is no longer available. It shouldn't have been used, but
- if necessary it can be resurrected using the moduleimport attribute described in the
- Python chapter of the documentation. If both modules are provided in a Python
- package, try:
-
- %module(moduleimport="from . import _example\nfrom ._example import *") example
- or more generically:
- %module(moduleimport="from . import $module\nfrom .$module import *") example
-
- and if both are provided as global modules, try:
-
- %module(moduleimport="import _example\nfrom _example import *") example
- or more generically:
- %module(moduleimport="import $module\nfrom $module import *") example
-
- The module import code shown will appear in the example.py file.
-
-2018-11-24: vadz
- #1358 Fix handling of abstract base classes nested inside templates
-
- Correct detecting of whether a derived class method overrides a pure virtual
- base class method when both classes are nested inside a template class: this
- notably didn't work correctly for methods taking parameters of the base class
- type.
-
-2018-11-22: rupertnash
- [Python] #1282 Make generated module runnable via python -m (PEP 366 conforming)
-
- Previously any SWIG generated modules in a package would fail with an ImportError
- when using 'python -m' for example 'python -m mypkg.mymodule'.
-
- This fix also allows the SWIG generated module to be placed into a directory and
- then renamed __init__.py to convert the module into a package again. This ability
- stopped working in swig-3.0.9. However, only Python 2.7 or 3.3 and later work. If
- Python 3.2 support is needed, use moduleimport in %module to customise the import
- code.
-
-2018-11-13: wsfulton
- #1340 Remove -cppcast and -nocppcast command line options (this was an option
- available to the scripting language targets).
-
- The -cppcast option is still turned on by default. The -nocppcast option
- to turn off the use of c++ casts (const_cast, static_cast etc) has been
- removed. However, defining SWIG_NO_CPLUSPLUS_CAST will still generate C casts
- instead of C++ casts for C++ wrappers.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2018-11-13: wsfulton
- [Python] #1340 Remove -outputtuple and -nooutputtuple command line options.
-
- Both the command line and %module options of the same name have been
- removed. These were undocumented. The -outputtuple option returned a
- Python tuple instead of a list, mostly typically in the OUTPUT
- typemap implementations.
-
- It unclear why a tuple instead of a list return type is needed and
- hence this option has been removed as part of the simplification of
- the SWIG Python command line options for SWIG 4.
-
-2018-11-13: wsfulton
- [Python] #1340 Remove -noproxyimport command line option.
-
- This option turned off the insertion of Python import statements
- derived from a %import directive. For example given:
-
- %module module_b
- %import "module_a.i"
-
- then module_b.py will contain:
-
- import module_a
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2018-10-29: AlexanderGabriel
- [PHP] The following PHP7 reserved keywords are now only renamed by
- SWIG when used as function names in the API being wrapper:
- __halt_compiler array die echo empty eval exit include include_once
- isset list print require require_once return unset
-
-2018-10-22: olly,wsfulton
- [Python] #1261 #1340 Turn on many optimisation options by default and rationalise the
- number of command line options.
-
- There were an unnecessary number of command line options and many of these have now
- been removed in a drive for simplification. Some were needed to support older versions
- of Python (2.6 and earlier).
-
- Many of the options could be turned on individually and when using -O. Previously -O
- resulted in turning on a set of options:
-
- -modern -fastdispatch -nosafecstrings -fvirtual -noproxydel
- -fastproxy -fastinit -fastunpack -fastquery -modernargs -nobuildnone
-
- Now -O results in turning on this reduced set:
-
- -fastdispatch -fastproxy -fvirtual
-
- The following options are now on by default, a deprecated warning is displayed if they
- are used:
- -fastinit Class initialisation code done in C/C++ rather than in Python code.
- -fastquery Python dictionary used for lookup of types.
- -fastunpack Faster unpacking of function arguments in C/C++ wrappers.
- -modern Use Python 2.3 features such as object and property.
- -modernargs Use Python 2.3 C APIs for unpacking arguments in tuples.
- -noproxydel Stop generating a proxy __del__ method for backwards compatiblity.
- -safecstrings No discernable difference
-
- The following options have been removed altogether:
- -aliasobj0
- -buildnone
- -classptr
- -new_repr
- -newrepr
- -noaliasobj0
- -nobuildnone
- -nocastmode
- -nodirvtable
- -noextranative
- -nofastinit
- -nofastproxy
- -nofastquery
- -nomodern
- -nomodernargs
- -nooutputtuple
- -nosafecstrings
- -old_repr
- -oldrepr
- -proxydel
-
- -new_vwm is no longer supported. Use the -newvwm alias instead.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2018-10-22: olly
- [Python] #1261 Remove command line option no longer needed as Python 2.3 and earlier
- are no longer supported:
-
- -classic
-
-2018-10-09: wsfulton
- [D, Go, Guile, Lua, Mzscheme, Ocaml, Perl5, Php, Scilab, Tcl]
- Allow wrapping of std::map using non-default comparison function.
-
-2018-10-09: vadz
- [Java] #1274 Allow wrapping of std::map using non-default comparison function.
-
-2018-10-04: wsfulton
- [Python] #1126 Fix C default arguments with -builtin and -fastunpack and -modernargs.
- Problem occurred when there is just one (defaulted) parameter in the parameter list.
-
-2018-09-24: wsfulton
- [Python] #1319 C++11 hash tables implementation is finished now (including for -builtin):
- std::unordered_map
- std::unordered_set
- std::unordered_multimap
- std::unordered_multiset
-
-2018-09-21: wsfulton
- [Python] Fix when using -builtin and wrapping std::map, std::set, std::unordered_map or
- std::unordered_set to ensure __contains__ is called. This is a wrapper for the STL
- container's find method. Without it, Python will do its own slower sequence search.
-
-2018-09-19: wsfulton
- [Python] Fix functors (wrapped as __call__) when using -builtin -modern -fastunpack.
-
-2018-09-02: andreas.gaeer,tkrasnukha
- [Python] #1321 Fix assert in PyTuple_GET_SIZE in debug interpreter builds of python-3.7
- when calling tp_new.
-
-2018-09-01: ChristopherHogan
- [Guile] #1288 Fix garbage collection for guile >= 2.0.12.
-
-2018-08-31: wsfulton
- [Python] #1319 C++11 hash tables support:
- std::unordered_map
- std::unordered_set
- std::unordered_multimap
- std::unordered_multiset
- is now compiling and working (sorting using -builtin not fully functional yet though).
-
-2018-08-20: wkalinin
- #1305 Fix nested structure symbol tables in C mode to fix member name conflicts
- in different structs with the same nested struct member name.
-
-2018-08-18: wsfulton
- [Python] #688 Fix makefile recursion when running python test-suite.
-
-2018-08-18: wsfulton
- [Python] #1310 Re-implement Python -fastproxy option.
-
- The previous implementation failed with Python 3 and abstract base clases.
- The new implementation replaces the Python 2 implementation using
- new.instancemethod with the C API PyMethod_New to match the equivalent Python 3
- implementation which uses PyInstanceMethod_New.
-
- The new approach runs slightly faster. See #1310.
-
-2018-08-12: gmazzamuto
- [Python] #1283 Update pybuffer.i library to use new-style Python buffer C API.
-
-2018-08-12: brianhatwood,wsfulton
- [Java] #1303 #1304 Fix crash in directors when using OUTPUT and INOUT typemaps in typemaps.i and
- passing NULL pointers in C++ to director method overloaded and implemented in Java.
-
-2018-08-10: wsfulton
- [Python] #1293 Improve TypeError message inconsistencies between default and fastdispatch
- mode when handling overloaded C++ functions. Previously the error message did not always
- display the possible C/C++ prototypes in fastdispatch mode.
-
-2018-08-02: furylynx,jacobwgillespie,p2k
- [Javascript] #1290, #968. Add support for NodeJS versions 2-10.
-
-2018-07-31: wsfulton
- [Python] #1293 Overloaded C++ function wrappers now raise a TypeError instead
- of NotImplementedError when the types passed are incorrect. This change means
- there is now consistency with non-overloaded function wrappers which have always
- raised TypeError when the incorrect types are passed. The error message remains
- the same and is for example now:
-
- TypeError: Wrong number or type of arguments for overloaded function 'f'.
- Possible C/C++ prototypes are:
- f(int)
- f(char const *)
-
- instead of:
-
- NotImplementedError: Wrong number or type of arguments for overloaded function 'f'.
- Possible C/C++ prototypes are:
- f(int)
- f(char const *)
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2018-06-23: wsfulton
- [Python] #718 Fix pythonnondynamic feature for modern classes
-
- Fixes nondynamic mode when an instance variable is set with the same
- name as a class variable in a class derived from a SWIG proxy class.
- This corner case set an instance variable instead of raising an AttributeError.
-
- Also fix %pythonnondynamic in Python 3 with -modern. The metaclass
- containing the implementation was previously not being applied in Python 3.
-
-2018-07-17: petrmitrichev,wsfulton
- [Python] #1275 #1279 Initialize function-local statics (singletons) that call Python
- code during Python module initialization in order to avoid deadlocks with subsequent
- multi-threaded usage.
-
-2018-06-15: wsfulton
- [Python] Fix seg fault using Python 2 when passing a Python string, containing
- invalid utf-8 content, to a wstring or wchar * parameter. A TypeError is thrown instead, eg:
-
- %include <std_wstring.i>
- void instring(const std::wstring& s);
-
- instring(b"h\xe9llooo") # Python
-
-2018-06-15: wsfulton
- [Python] Python 3.7 support: Replace use of deprecated PyUnicode_GetSize with
- PyUnicode_GetLength to remove deprecated warnings compiling the C/C++ wrappers.
-
-2018-06-12: wsfulton
- [Python] Python 3.7 support: The %pythonabc feature in pyabc.i now uses base classes
- collections.abc.MutableSequence
- collections.abc.MutableMapping
- collections.abc.MutableSet
- instead of
- collections.MutableSequence
- collections.MutableMapping
- collections.MutableSet
- as the latter are deprecated in Python 3.7 and are due to be removed in Python 3.8.
- The classes in collections.abc.* are available from Python 3.3 onwards. If you
- require support for Python 3.2, then copy the pyabc.i file and modify by removing
- the few instances of the .abc sub-module.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2018-06-12: olly,wsfulton
- [Python] #701 Remove support for Python versions < 2.7 and 3.0 and 3.1.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2018-06-11: olly
- [Python] Fix new GCC8 warnings in generated code by avoiding casts
- between incompatible function types where possible, and by
- suppressing the warning when it's due to the design of Python's C
- API. Fixes #1259.
-
-2018-06-08: philippkraft
- [Python] Stop exposing <CLASS>_swigregister to Python. It's not
- useful for user Python code to call this, and it just clutters the
- API unnecessarily. Fixes #1225.
-
-2018-06-07: cmfoil, kabbi, Jamie Kirkpatrick, markok314, vadz, wsfulton, Yann Diorcet
- #170 Doxygen documentation support added. This allows translation of Doxygen comments
- into JavaDoc and PyDoc documentation. It is enabled via the -doxygen command line
- option. See the Doxygen.html chapter in the documentation for further information.
-
-2018-06-07: olly
- [PHP] We've finally removed support for %pragma(php4) which was
- deprecated back in 2008. Use %pragma(php) instead, which has been
- supported since at least 2005.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2018-06-07: olly
- [PHP5] Support for PHP5 has been removed. PHP5 is no longer
- actively supported by the PHP developers and security support for
- it ends completely at the end of 2018, so it doesn't make sense
- to include support for it in the upcoming SWIG 4.0.0 release.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2018-06-06: olly
- [Lua] Improve configure probes for Lua headers and libs used in testsuite.
-
-2018-05-15: kwwette
- [Octave] add support for version 4.4
- - Should not introduce any user-visible incompatibilities
-
-2018-05-15: wsfulton
- [C#, D, Java] Fix lookup of csconstruct, dconstruct and javaconstruct typemaps.
- The C++ namespace was previously ignored when looking up the typemap.
-
-2018-05-15: wsfulton
- [Javascript] Fix generated C++ code when using %nspace on namespaces that are more
- than two levels deep.
-
-2018-05-14: wsfulton
- Issue #1251 Add support for C++17 nested namespace definitions,
- for example:
- namespace A::B { ... }
-
-2018-05-11: wsfulton
- [C#, D, Java] Add support so that the %csmethodmodifiers, %dmethodmodifiers,
- %javamethodmodifiers can modify the method modifiers for the destructor wrappers
- in the proxy class: dispose, Dispose, delete. With this feature, it is now possible
- to make a C# proxy class sealed, eg when wrapping a class X, the virtual method modifiers
- can be removed using:
-
- %typemap(csclassmodifiers) X "public sealed class"
- %csmethodmodifiers X::~X "public /*virtual*/";
-
-2018-04-18: olly
- [Python] Suppress new pycodestyle warning:
- E252 missing whitespace around parameter equals
-
-2018-04-07: goatshriek
- [Ruby] #1213 Fix ruby %alias directive for global C/C++ functions.
-
-2018-04-03: olly
- [Ruby] Fix to pass Qnil instead of NULL to rb_funcall(), which silences GCC
- -Wconversion-null warning (on by default with recent GCC).
-
-2018-03-09: wsfulton
- [Java] #1184 Fix swigReleaseOwnership() and swigTakeOwnership() regression
- for non-director classes. Restores a dynamic_cast which was previously removed.
-
-2018-03-07: llongi
- Github PR #1166 - Fix preprocessor handling of macros with commas
- in a // comment.
-
-2018-02-18: JPEWdev
- Patch #1164 - Add support for a command-line options file, also sometimes
- called a response file. This is useful if the command-line options exceed
- the system command-line length limit. To use, put the command-line options
- into a file, then provide the file name prefixed with @, for example using
- a file called args.txt:
-
- swig @args.txt
-
-2018-02-11: wsfulton
- [Javascript] #1187 Fix compilation error wrapping std::complex via
- std_complex.i.
-
-2018-01-30: smarchetto
- [Scilab] add type name argument in SWIG_ptr() function to cast from pointer address to typed pointers
-
-2018-01-16: wsfulton
- Expressions following a preprocessor directive must now be separated by whitespace
- or non-numeric characters. This syntax change makes the SWIG preprocessor work like
- the C preprocessor in this area.
-
- For example, the following code used be accepted as valid syntax:
- #if1
- #define ABC 123
- #endif
-
- Now you get an error:
- example.h:1: Error: Unknown SWIG preprocessor directive: if1 (if this is a block of
- target language code, delimit it with %{ and %})
- example.h:3: Error: Extraneous #endif.
-
- The following is the correct syntax:
- #if 1
- #define ABC 123
- #endif
-
- The following of course also works:
- #if(1)
- #define ABC 123
- #endif
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2018-01-15: wsfulton
- Fix issue #1183. Floating point exception evaluating preprocessor expressions
- resulting in division by zero.
-
-2018-01-14: wsfulton
- Fix issue #1172. Seg fault parsing invalid exponents in the preprocessor.
-
-2018-01-12: Liryna
- [C#] Patch #1128. Add ToArray function to std::vector wrappers.
-
-2018-01-12: wsfulton
- [Java] Fix issue #1156. Add missing throws clause for interfaces when using the
- %interface family of macros.
-
-2018-01-05: wsfulton
- Fix default arguments using expressions containing -> syntax error. Problem reported on
- swig-user mailing list.
-
-2017-12-30: wsfulton
- [Python] Replace pep8 with pycodestyle for checking the Python code style when
- running Python tests.
-
-2017-12-30: davedissian
- Fixed a symbol lookup issue when encountering a typedef of a symbol from the tag
- namespace to the global namespace when the names are identical, such as 'typedef
- struct Foo Foo;'.
-
-2017-12-13: wsfulton
- [Perl] add missing support for directorfree typemaps.
-
-2017-12-13: wsfulton
- Issue #1167 Fix directorout typemaps which were causing undefined behaviour when
- returning pointers by reference.
-
-2017-12-08: olly
- [PHP] Use ZEND_MODULE_GLOBALS_ACCESSOR to access globals so the
- generated code builds when PHP was built with ZTS enabled.
-
-2017-12-04: wsfulton
- [Python] Add missing checks for failures in calls to PyUnicode_AsUTF8String. Previously a
- seg fault could occur when passing invalid UTF8 strings (low surrogates), eg passing
- u"\udcff" to the C layer (Python 3).
-
-2017-11-24: joequant
- [R] Fix #1124 and return R_NilValue for null pointers
-
-2017-11-29: wsfulton
- [Java] director exception handling improvements.
-
- When a director method throws an exception and it is caught by DirectorException
- and passed back to Java using Swig::DirectorException::throwException, the Java
- stack trace now contains the original source line that threw the exception.
-
- Deprecate Swig::DirectorException::raiseJavaException, please replace usage with
- Swig::DirectorException::throwException.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2017-10-26: wsfulton
- Add support for C++11 ref-qualifiers when using directors.
-
-2017-10-26: wsfulton
- Fix generated code when using directors and methods returning const ref pointers.
-
-2017-10-26: wsfulton
- [C#, D, Java, Octave, R, Scilab] Port director typemaps to these additional languages.
- Issue #700.
-
-2017-10-26: radarsat1
- [Ruby Python] Patch #1029 - Correct handling of null using directors and shared_ptr.
-
-2017-10-10: joequant
- [R] pass enum expressions to R. This will generate
- incorrect files when there is an arithmetic expression
- in the enum, but this is better than silently generating
- incorrect code
-
-2017-10-09: olly
- [PHP] Fix incorrect wrapper code generated when there's a
- combination of overloading, parameters with a default value
- and %newobject. Fixes https://sourceforge.net/p/swig/bugs/1350/
-
-2017-10-09: olly
- Remove GCJ support. It isn't in a good state and doesn't seem to
- be used, and GCC7 dropped GCJ. Closes
- https://sourceforge.net/p/swig/bugs/823/
-
-2017-10-07: olly
- Fix preprocessor handling of empty macro arguments to match that of
- C/C++ compilers. Fixes issue #1111 and
- https://sourceforge.net/p/swig/bugs/826/
-
-2017-10-06: wsfulton
- [Python] Issue #1108. Fix platform inconsistency in Python default argument handling.
- 32 bit and 64 bit compiled versions of SWIG generated different Python files
- when default arguments were outside the range of 32 bit signed integers.
- The default arguments specified in Python are now only those that are in the
- range of a 32 bit signed integer, otherwise the default is obtained from C/C++ code.
-
-2017-10-02: wsfulton
- [C#] Fix std::complex types passed by value.
-
-2017-10-02: wsfulton
- [Javascript, Python, Ruby] Issue #732 - Missing type information for std::complex
- in std_complex.i meant that previously std::complex always had to be fully qualified
- in order to be wrapped with the appropriate typemaps.
-
-2017-10-01: joequant
- allow R package names with docs
- allowing multiple get accessors in R
- fix smart-pointer and NAMESPACE support
- constructors now returning smart pointers (if class
- declared as such)
- smart-pointer classes deriving from parent smart-pointers
-
-2017-09-29: wsfulton
- Issue #1100 - Allow an instantiated template to have the same name in the target
- language as the C++ template name, for example, this is now possible:
-
- template<typename T> struct X { ... };
- %template(X) X<int>;
-
-2017-09-23: wsfulton
- Issue #1098. Fix overloading of shared_ptr with underlying pointer types, eg:
-
- void m(std::shared_ptr<T> p);
- void m(T &p);
- void m(T *p);
-
- Only the first method is wrapped and the others are ignored/shadowed.
- The implementation is done via a new attribute in the 'typecheck' typemap called
- 'equivalent'. If specified, it must contain the equivalent pointer type for overloading
- and can only be used for the special SWIG_TYPECHECK_POINTER precedence level.
- The shared_ptr 'typecheck' typemaps have been modified accordingly.
- Here is a simplified version:
-
- %typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="T *")
- T,
- T CONST &,
- T CONST *,
- T *CONST&,
- std::shared_ptr< T >,
- std::shared_ptr< T > &,
- std::shared_ptr< T > *,
- std::shared_ptr< T > *&
- { ... }
-
- Overloading with any of these types will result in SWIG ignoring all but the first
- overloaded method by default. Without the 'equivalent' attribute, wrapping the overloaded
- methods resulted in types being shadowed (scripting languages) or code that did not
- compile (statically typed languages).
-
-2017-09-19: futatuki
- [Python] #1003 Add --with-2to3=/path/to/2to3 option to configure.
-
-2017-09-18: wsfulton
- Fix type promotion wrapping constant expressions of the form:
- # define EXPR_MIXED1 (0x80 + 11.1) - 1
- This was previously an integral type instead of a floating point type.
-
-2017-09-17: wsfulton
- Fix generated code for constant expressions containing wchar_t L literals such as:
- # define __WCHAR_MAX (0x7fffffff + L'\0')
- # define __WCHAR_MIN (-__WCHAR_MAX - 1)
-
-2017-09-10: mlamarre
- [Python] Patch #1083. Define_DEBUG to 1 to do exactly like Visual Studio
- /LDd, /MDd or /MTd compiler options.
-
-2017-08-25: wsfulton
- Issue #1059. Add support for C++11 ref-qualifiers on non-static member functions.
- Members with lvalue ref-qualifiers such as:
-
- struct RQ {
- void m1(int x) &;
- void m2(int x) const &;
- };
-
- are wrapped like any other member function. Member functions with rvalue ref-qualifiers
- are ignored by default, such as:
-
- struct RQ {
- void m3(int x) &&;
- void m4(int x) const &&;
- };
-
- example.i:7: Warning 405: Method with rvalue ref-qualifier m3(int) && ignored.
- example.i:8: Warning 405: Method with rvalue ref-qualifier m4(int) const && ignored.
-
- These can be unignored and exposed to the target language, see further documentation in
- CPlusPlus11.html.
-
-2017-08-16: wsfulton
- Fix #1063. Add using declarations to templates into typedef table.
-
- Using declarations to templates were missing in SWIG's internal typedef tables.
- This led to a few problems, such as, templates that did not instantiate and generated
- C++ code that did not compile as SWIG did not know what scope the template was
- in. This happened mostly when a using declaration was used on a template type in a
- completely unrelated namespace.
-
-2017-08-16: wsfulton
- Fix type lookup in the presence of using directives and using declarations.
-
- Fix some cases of type lookup failure via a combination of both using directives and
- using declarations resulting in C++ code that did not compile as the generated type was
- not fully qualified for use in the global namespace. Example below:
-
- namespace Space5 {
- namespace SubSpace5 {
- namespace SubSubSpace5 {
- struct F {};
- }
- }
- using namespace SubSpace5;
- using SubSubSpace5::F;
- void func(SubSubSpace5::F f);
- }
-
-2017-08-16: wsfulton
- Issue #1051. %template scope enforcement and class definition fixes.
-
- The scoping rules around %template have been specified and enforced.
- The %template directive for a class template is the equivalent to an
- explicit instantiation of a C++ class template. The scope for a valid
- %template instantiation is now the same as the scope required for a
- valid explicit instantiation of a C++ template. A definition of the
- template for the explicit instantiation must be in scope where the
- instantiation is declared and must not be enclosed within a different
- namespace.
-
- For example, a few %template and C++ explicit instantiations of std::vector
- are shown below:
-
- // valid
- namespace std {
- %template(vin) vector<int>;
- template class vector<int>;
- }
-
- // valid
- using namespace std;
- %template(vin) vector<int>;
- template class vector<int>;
-
- // valid
- using std::vector;
- %template(vin) vector<int>;
- template class vector<int>;
-
- // ill-formed
- namespace unrelated {
- using std::vector;
- %template(vin) vector<int>;
- template class vector<int>;
- }
-
- // ill-formed
- namespace unrelated {
- using namespace std;
- %template(vin) vector<int>;
- template class vector<int>;
- }
-
- // ill-formed
- namespace unrelated {
- namespace std {
- %template(vin) vector<int>;
- template class vector<int>;
- }
- }
-
- // ill-formed
- namespace unrelated {
- %template(vin) std::vector<int>;
- template class std::vector<int>;
- }
-
- When the scope is incorrect, an error now occurs such as:
-
- cpp_template_scope.i:34: Error: 'vector' resolves to 'std::vector' and
- was incorrectly instantiated in scope 'unrelated' instead of within scope 'std'.
-
- Previously SWIG accepted the ill-formed examples above but this led to
- numerous subtle template scope problems especially in the presence of
- using declarations and using directives as well as with %feature and %typemap.
-
- Actually, a valid instantiation is one which conforms to the C++03
- standard as C++11 made a change to disallow using declarations and
- using directives to find a template.
-
- // valid C++03, ill-formed C++11
- using std::vector;
- template class vector<int>;
-
- Similar fixes for defining classes using forward class references have
- also been put in place. For example:
-
- namespace Space1 {
- struct A;
- }
- namespace Space2 {
- struct Space1::A {
- void x();
- }
- }
-
- will now error out with:
-
- cpp_class_definition.i:5: Error: 'Space1::A' resolves to 'Space1::A' and
- was incorrectly instantiated in scope 'Space2' instead of within scope 'Space1'.
-
- Previously some symbols would have been instantiated in the wrong scope and led
- to lots of scope problems involving SWIG typemaps, features, renames etc.
- You will need to correct the scope used in other SWIG directives which do not
- support 'using declarations' and 'using directives'. For example, if you previously had:
-
- %rename(Zap) vector<int>::clear;
- using namespace std;
- %template(VectorInt) vector<int>;
-
- Prior versions of SWIG incorrectly instantiated vector<int> in the global namespace
- and so the %rename matched. Now the template is instantiated in the correct namespace,
- so is fully qualified as std::vector<int>. The other SWIG directives need correcting as
- they do not follow 'using declarations' and 'using directives'. Change it to:
-
- %rename(Zap) std::vector<int>::clear;
- using namespace std;
- %template(vin) vector<int>;
-
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2017-08-16: wsfulton
- Fix scope lookup for template parameters containing unary scope operators.
-
- Fixes cases like:
-
- namespace Alloc {
- template<typename T> struct Rebind {
- typedef int Integer;
- };
- }
- %template(RebindBucket) Alloc::Rebind< Bucket >;
- OR
- %template(RebindBucket) Alloc::Rebind< ::Bucket >;
-
- Alloc::Rebind< Bucket >::Integer Bucket1();
- Alloc::Rebind< ::Bucket >::Integer Bucket2();
- Alloc::Rebind<::template TemplateBucket<double>>::Integer Bucket3();
-
-2017-08-16: wsfulton
- For templates only, the template parameters are fully resolved when
- handling typemaps. Without this, it is too hard to have decent rules
- to apply typemaps when parameter types are typedef'd and template
- parameters have default values.
-
- Fixes %clear for typedefs in templates, eg:
-
- %typemap("in") XXX<int>::Long "..."
- template typename<T> struct XXX {
- typedef long Long;
- };
- %clear XXX<int>::Long;
-
- as the typemap was previously incorrectly stored as a typemap for long
- instead of XXX<int>::Long.
-
-2017-08-05: olly
- [C++11] Allow static_assert at the top level (and disallow it right
- after template<T>). Fixes issue 1031 reported by Artem V L.
-
-2017-08-02: wsfulton
- Fix incorrectly shown warning when an empty template instantiation was used on a
- class used as a base class and that base class was explicitly ignored with %ignore.
- Example of the warning which will no longer appear:
-
- Warning 401: Base class 'Functor< int,int >' has no name as it is an empty
- template instantiated with '%template()'. Ignored.
-
-2017-07-17: fflexo
- [Java] #674 Add std_list.i to add support for std::list containers. The Java proxy
- extends java.util.AbstractSequentialList and makes the C++ std::list container look
- and feel much like a java.util.LinkedList from Java.
-
-2017-07-07: wsfulton
- [Python] Fix display of documented template types when using the autodoc
- feature. For example when wrapping:
-
- %feature("autodoc");
- template<typename X> struct T {};
- %template(TInteger) T<int>;
-
- the generated documentation contains:
- """Proxy of C++ T< int > class."""
- instead of:
- """Proxy of C++ T<(int)> class."""
- and
- """__init__(TInteger self) -> TInteger"""
- instead of
- """__init__(T<(int)> self) -> TInteger"""
-
-2017-06-27: nihaln
- [PHP] Update the OUTPUT Typemap to add return statement to the
- PHP Wrapper.
-
-2017-06-27: nihaln
- [PHP] Update the enum and value examples to use the OO wrappers
- rather than the flat functions produced with -noproxy. There's
- not been a good reason to use -noproxy for since PHP5 OO wrapping
- was fixed back in 2005.
-
-2017-06-23: m7thon
- [Python] fix and improve default argument handling:
-
- 1. Fix negative octals. Currently not handled correctly by `-py3`
- (unusual case, but incorrect).
- 2. Fix arguments of type "octal + something" (e.g. `0640 | 04`).
- Currently drops everything after the first octal. Nasty!
- 3. Fix bool arguments "0 + something" (e.g. `0 | 1`) are always
- "False" (unusual case, but incorrect).
- 4. Remove special handling of "TRUE" and "FALSE" from
- `convertValue` since there's no reason these have to match
- "true" and "false".
- 5. Remove the Python 2 vs. Python 3 distinction based on the
- `-py3` flag. Now the same python code is produced for default
- arguments for Python 2 and Python 3. For this, octal default
- arguments, e.g. 0644, are now wrapped as `int('644', 8)`. This
- is required, as Python 2 and Python 3 have incompatible syntax
- for octal literals.
-
- Fixes #707
-
-2017-06-21: futatuki
- #1004 - Fix ccache-swig executable name to respect configure's --program-prefix and
- --program-suffix values if used.
-
-2017-06-21: tamuratak
- [Ruby] #911 - Add std::wstring support.
-
-2017-06-19: wsfulton
- [Python] Fix handling of rich comparisons when wrapping overloaded operators:
-
- operator< operator<= operator> operator>= operator== operator!=
-
- Previously a TypeError was always thrown if the type was not correct. NotImplemented
- is now returned from these wrapped functions if the type being compared with is
- not correct. The subsequent behaviour varies between different versions of Python
- and the comparison function being used, but is now consistent with normal Python
- behaviour. For example, for the first 4 operator overloads above, a TypeError
- 'unorderable types' is thrown in Python 3, but Python 2 will return True or False.
- NotImplemented should be returned when the comparison cannot be done, see PEP 207 and
- https://docs.python.org/3/library/constants.html#NotImplemented
-
- Note that the bug was only present when overloaded operators did not also have a
- function overload.
-
- Fixes SF bug #1208 (3441262) and SF patch #303.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2017-06-17: fabrice102
- [Go] Fix Go callback example. Fixes github #600, #955, #1000.
-
-2017-06-16: wsfulton
- Make sure warning and error messages are not split up by other processes writing to
- stdout at the same time.
-
-2017-06-16: wsfulton
- [R] Fix wrapping function pointers containing rvalue and lvalue reference parameters.
-
-2017-06-13: olly
- [Perl] Fix testsuite to work without . in @INC - it was removed in
- Perl 5.26 for security reasons, and has also been removed from
- older versions in some distros. Fixes #997 reported by lfam.
-
-2017-06-03: wsfulton
- Fix %import on a file containing a file scope %fragment forced inclusion to not
- generate the fragment contents as %import should not result in code being generated.
- The behaviour is now the same as importing code insertion blocks.
- Wrapping FileC.i in the following example will result in no generated code, whereas
- previously "#include <limits.h>" was generated:
-
- // FileA.i
- %fragment("<limits.h>", "header") %{
- #include <limits.h>
- %}
-
- %{
- #include <stdio.h>
- %}
- %fragment("<limits.h>");
-
- // FileC.i
- %import "FileA.i"
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2017-05-26: Volker Diels-Grabsch, vadz
- [Java] #842 Extend from java.util.AbstractList<> and implement java.util.RandomAccess for
- std::vector wrappers. This notably allows to iterate over wrapped vectors in a natural way.
- Note that boxed types are now used in the Java layer when wrapping vector of C primitive
- types, for example. This may introduce some subtle incompatibilities due to some
- differences in how Java converts boxed types and unboxed types. For example,
-
- int i=0;
- double d1 = i; // ok
- Double d2 = i; // error: incompatible types: int cannot be converted to Double
-
- This can be a problem when calling the add and set functions. A suggested backwards
- compatible workaround is to use something like (shown for std::vector<double>:
-
- #if defined(SWIGJAVA)
- // Add in old api that uses non-boxed types
- %extend std::vector<double> {
- %proxycode %{
- public void add(double x) {
- add(Double.valueOf(x));
- }
- public void set(int i, double val) {
- set(i, Double.valueOf(val));
- }
- %}
- }
- #endif
-
- %include "std_vector.i"
- %template(VectorDouble) std::vector<double>;
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2017-05-30: davidcl
- [Scilab] #994 Undefined symbol error when loading in Scilab 6
-
-2017-05-25: asibross
- [Java] #370 #417 Missing smart pointer handling in Java director extra methods
- swigReleaseOwnership() and swigTakeOwnership().
-
-2017-05-23: wsfulton
- [Java] #230 #759 Fix Java shared_ptr and directors for derived classes java compilation
- error.
-
- For shared_ptr proxy proxy classes, add a protected method swigSetCMemOwn for modifying
- the swigCMemOwn and swigCMemOwnDerived member variables which are used by various other
- methods for controlling memory ownership.
-
-2017-05-21: Sghirate
- [Java, C#, D] #449 Remove unnecessary use of dynamic_cast in directors to enable
- non-RTTI compilation.
-
-2017-05-21: wsfulton
- [Python] #993 Fix handling of default -ve unsigned values, such as:
- void f(unsigned = -1U);
-
-2017-05-20: jschueller
- [Python] #991 Fix E731 PEP8 warning: do not assign a lambda expression
-
-2017-05-16: nihal95
- [PHP] Add %pragma version directive to allow the version of the
- extension to be set. Patch #970, fixes #360.
-
-2017-05-13: yag00
- Patch #975 - Add support for noexcept on director methods.
-
-2017-04-27: redbrain
- Issue #974, Patch #976 - Fix preprocessor handling of macros with commas in a comment.
-
-2017-04-25: jleveque
- [Lua] #959 - Fix Visual Studio C4244 conversion warnings in Lua wrappers.
-
-2017-04-21: tamuratak
- [Ruby] #964 - Add shared_ptr director typemaps.
-
-2017-04-20: wsfulton
- [Ruby] #586, #935 Add assert for invalid NULL type parameter when calling SWIG_Ruby_NewPointerObj.
-
-2017-04-20: tamuratak
- [Ruby] #930, #937 - Fix containers of std::shared_ptr.
- Upcasting, const types (eg vector<shared_ptr<const T>>) and NULL/nullptr support added.
-
-2017-04-12: smarchetto
- [Scilab] New parameter targetversion to specify the Scilab target version (5, 6, ..) for code generation
- With Scilab 6 target specified, identifier names truncation is disabled (no longer necessary)
-
-2017-03-24: tamuratak
- [Ruby] Fix #939 - Wrapping std::vector<bool> fix due to incorrect null checks
- on VALUE obj.
-
-2017-03-17: vadz
- [C#] #947 Add support for std::complex<T>
-
-2017-03-17: wsfulton
- [Go] Fix handling of typedef'd function pointers and typedef'd member function pointers
- such as:
-
- typedef int (*FnPtr_td)(int, int);
- int do_op(int x, int y, FnPtr_td op);
-
-2017-03-16: wsfulton
- Add support for member const function pointers such as:
-
- int fn(short (Funcs::* parm)(bool)) const;
-
- Also fix parsing of references/pointers and qualifiers to member
- pointers such as:
-
- int fn(short (Funcs::* const parm)(bool));
- int fn(short (Funcs::* & parm)(bool));
-
-2017-03-10: wsfulton
- Extend C++11 alternate function syntax parsing to support const and noexcept, such as:
-
- auto sum1(int x, int y) const -> int { return x + y; }
- auto sum2(int x, int y) noexcept -> int { return x + y; }
-
-2017-02-29: tamuratak
- [Ruby] #917 - Add Enumerable module to all container class wrappers. It was missing
- for std::list, std::multiset, std::unordered_multiset and std::unordered_map.
-
-2017-02-27: assambar
- [C++11] Extend parser to support throw specifier in combination
- with override and/or final.
-
-2017-02-10: tamuratak
- [Ruby] #883 - Add support for C++11 hash tables:
- std::unordered_map
- std::unordered_set
- std::unordered_multimap
- std::unordered_multiset
-
-2017-02-08: jcsharp
- [C#] #887 Improve std::vector<T> wrapper constructors -
- Replace constructor taking ICollection with IEnumerable and also add IEnumerable<T>
- constructor to avoid the boxing and unboxing overhead of the original constructor,
- when the type parameter is a value type.
-
-Version 3.0.12 (27 Jan 2017)
-============================
-
-2017-01-27: wsfulton
- [C#] #882 Fix missing filename in error messages when there is a problem
- writing out C# files.
-
-2017-01-27: briancaine
- [Guile] #744 Fix compilation errors in Guile wrappers - regression
- introduced in swig-3.0.11.
-
-2017-01-24: andrey-starodubtsev
- [Java] Apply #704 - director typemap improvements.
- Memory leak fixes, add support for "directorargout" typemap and
- add director support to typemaps.i.
-
-2017-01-24: wsfulton
- Enhance %extend to extend a class with template constructors, eg:
-
- struct Foo {
- %extend {
- template<typename T>
- Foo(int a, T b) {
- ...
- }
- }
- };
- %template(Foo) Foo::Foo<double>;
-
-2017-01-22: wsfulton
- Issue #876 Enhance %extend to extend a class with template methods, eg:
-
- struct Foo {
- %extend {
- template<typename T>
- void do_stuff(int a, T b) {
- ...
- }
- }
- };
- %template(do_stuff_inst) Foo::do_stuff<double>;
-
- Similarly for static template methods.
-
-2017-01-22: kwwette
- [Octave] add support for version 4.2
- - The Octave API now uses some C++11 features. It is recommended to use
- the mkoctfile program supplied by Octave to compile the SWIG-generated
- wrapper code, as mkoctfile will ensure the correct C++ compiler/options
- are used. Otherwise, the value of `mkoctfile -p CXX` should be parsed
- for any -std=* flags which might be present.
- - Octave has dropped support for << and >> operators, so SWIG now
- ignores them.
- - The Octave error() function now raises C++ exceptions to propagate
- Octave errors, so %exception directives may need to be modified.
- For convenience the SWIG_RETHROW_OCTAVE_EXCEPTIONS macro can be used
- to rethrow any Octave exceptions for Octave itself to handle, e.g.:
-
- try {
- $action // may call error()
- }
- SWIG_RETHROW_OCTAVE_EXCEPTIONS // error() exceptions are rethrown
- catch(...) {
- ... // all other exceptions
- }
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2017-01-16: wkalinin
- [C#] Fix #733 regression introduced in swig-3.0.9.
- Missing virtual function override in C# layer when using %import.
-
-2017-01-16: fschlimb
- Fix #813 template symbol name lookup bug when typedef names are the same but in different
- namespaces.
-
-2017-01-15: wsfulton
- [C# D Java]
- The SWIG library no longer uses the javatype, dtype or cstype typemaps, thereby
- completely freeing them up for users to use without having to replicate the library
- code that they previously added. The code previously generated by these typemaps
- has been replaced by the new %proxycode directive. Their use in the library code
- was fairly minimal:
-
- C# cstype: std_array.i std_map.i std_vector.i
- D dtype: std_vector.i
- Java javatype: arrays_java.i
-
-2017-01-14: wsfulton
- The %extend directive can now optionally support one of the 'class', 'struct' or 'union'
- keywords before the identifier name, for example:
-
- struct X { ... };
- %extend struct X { ... }
-
- Previously this had to specified as:
-
- struct X { ... };
- %extend X { ... }
-
-2017-01-13: wsfulton
- [C# D Java] Add new %proxycode directive which is a macro for %insert("proxycode").
- This is a way of adding pure C#/D/Java code into the appropriate proxy class, eg:
-
- %extend Proxy2 {
- %proxycode %{
- public int proxycode2(int i) {
- return i+2;
- }
- %}
- }
-
- %inline %{
- struct Proxy2 {};
- %}
-
- There will then be a pure Java/C#/D method called proxycode2 in the Proxy2 class.
-
-2016-12-31: ajrheading1
- Issue #860 - Remove use of std::unary_function and std::binary_function
- which is deprecated in C++11.
-
-2016-12-30: olly
- [PHP7] Register internal 'swig_runtime_data_type_pointer' constant
- as "CONST_PERSISTENT" to avoid segmentation fault on module unload.
- Fixes #859 reported by Timotheus Pokorra. Thanks also to Javier Torres
- for a minimal reproducer.
-
-Version 3.0.11 (29 Dec 2016)
-============================
-
-2016-12-24: wsfulton
- [C#] Add %feature("csdirectordelegatemodifiers") to enable customization
- of the delegate access modifiers generated in director classes.
- Fixes issue #748.
-
-2016-12-23: wsfulton
- [Python] Fix builtin "python:slot" feature failing for tp_hash when using
- hashfunc closure with a "Wrong type for hash function" for Python 2.
- Issue #843.
-
-2016-12-21: joequamt
- Changed generation of functions so that only functions
- that end in _set generate accessor functions rather than
- looking for "set".
- Change generation of operators to not have underscores
- to start in R. Users need to provide custom names for these operator overloads.
-
-2016-12-21: olly
- Fix isfinite() checks to work with all C++11 compilers.
- Fixes issues #615, #788 and #849.
-
-2016-12-20: wsfulton
- %namewarn unnecessarily caused keyword warnings for non-instantiated template classes
- and duplicate warnings for instantiated template classes when keywords were used.
- Issue #845.
-
-2016-12-18: ezralanglois
- [Python, Ruby, Octave] Memory leak fix on error in std::pair wrappers.
- Issue #851.
-
-2016-12-18: wsfulton
- Zero initialize arrays when using %array_class and %array_functions.
-
-2016-12-18: t-ikegami
- [Python] Fix #446
- Python %array_class of carrays.i failed with -builtin option.
-
-2016-12-16: briancaine
- [Guile] Patch #744 Added support for Guile's native pointer functionality
-
-2016-12-01: wsfulton
- [Python] Issue #769.
- Add optional moduleimport attribute to %module so that the
- default module import code can be overridden. See the "Searching for the wrapper module"
- documentation in Python.html. Example:
-
- %module(moduleimport="import _foo") foo
-
- $module also expands to the low-level C/C++ module name, so the following is the
- same as above
-
- %module(moduleimport="import $module") foo
-
-2016-11-30: olly
- [PHP] Add support for PHP7. PHP5's C extension API has changed
- substantially so you need to use -php7 to specify you want PHP7
- compatible wrappers. The default extension for generated wrappers
- is now .cxx (to match SWIG's default for every other language - to
- generate foo_wrap.cpp you can run SWIG with -cppext cpp). Fixes
- issue #571.
-
- As part of this change, the language subdirectory for PHP5 has
- changed from "php" to "php5" - if you are making use of the search
- path feature where the language subdirectory of each directory
- is also searched, you'll need to update your bindings. A simple
- fix which works for older and newer SWIG is to add a symlink:
- ln -s php php5
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2016-11-30: olly
- [PHP] Only emit one copy of each distinct arginfo. Previously we
- emitted a separate one for every wrapped function, but typically
- many functions have the same number of parameters and combinations
- of parameters passed by reference or not.
-
- This change significantly reduces both the size of the generated
- wrapper, and of the compiled PHP extension module (e.g. by ~6% for
- the stripped extension module for Xapian's PHP7 bindings).
-
-2016-11-28: wsfulton
- Fix %rename override of wildcard %rename for templates. For example:
-
- %rename(GlobalIntOperator) *::operator bool; // wildcard %rename
-
- %rename(XIntOperator) X::operator bool; // fix now overrides first %rename above
- OR
- %rename(XIntOperator) X<int>::operator bool; // fix now overrides first %rename above
-
- template<typename T> struct X {
- operator bool();
- ...
- };
- %template(Xint) X<int>;
-
- This also fixes %rename override of global %rename for templates. For example:
-
- // Global rename to make all functions start with a lower case letter
- %rename("%(firstlowercase)s", %$isfunction ) "";
- %rename(woohoo) W::Woo; // fix now overrides above %rename
-
- template<typename T> struct W {
- W Woo();
- ...
- };
- %template(Wint) W<int>;
-
- The above also introduces a possibly unexpected change. Many of the STL containers
- provided by SWIG use %rename to rename some methods, eg in std::vector, push_back
- is renamed to add in Java. Previously this intended rename did not happen when using
- using global %rename rules and the method would remain as push_back, but is now
- renamed to add. Some more info in issue #856.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2016-11-26: m7thon
- [Python] Issue #709 - improved wrapping of division operators
- 'from __future__ import division' now works in Python 2 whether or not the
- -py3 flag is used.
-
-2016-11-12: joequant
- [R] Issue #697 - fix comma issue with overload methods
-
-2016-11-12: joequant
- [R] Issue #555 - R runtime needs stdio.h
-
-2016-11-02: wsfulton
- [Python] Issue #816 - fix compilation error when using -extranative and -builtin.
-
-2016-11-02: liorgold
- Patch #741 - Add support for C++11 alias templates, see updated CPlusPlus11.html
- documentation.
-
-2016-10-30: myd7349
- [C#] Patch #740 Add std_array.i for C# for wrapping std::array.
-
- Patch also enhances std::vector<std::wstring> C# wrappers with additional functions
- (Contains, IndexOf, LastIndexOf and Remove).
-
-2016-10-30: tobilau
- [Java] Fix wrappers for wstring parameters in director methods to cleanup local
- ref after director callback has finished.
-
-2016-10-23: wsfulton
- [C#] Add missing csdirectorin VOID_INT_PTR and csdirectorout VOID_INT_PTR typemaps.
-
-2016-10-23: jiulongw
- Patch #781 - Fix wrapping of C compound expressions containing char constants
- in quotes such as:
-
- #define H_SUPPRESS_SCALING_MAGIC (('s'<<24) | ('u'<<16) | ('p'<<8) | 'p')
-
- enum DifferentTypes {
- typecharcompound='A'+1,
- typecharcompound2='B' << 2
- };
-
-2016-10-13: wsfulton
- [Python] Issue #808 - fix Python pickling and metaclass for builtin wrappers.
-
- The metaclass (SwigPyObjectType) for SWIG objects was not defined in
- a way that let importlib successfully import the Python wrappers.
- The pickle module previously failed to pickle objects because it couldn't
- determine what module the SWIG wrapped objects were in.
-
-2016-09-29: wsfulton
- [Allegrocl, CFFI, GO, Javascript, Ocaml, R, Scilab]
- Add missing support for the "ret" typemap in a few target languages.
- The documentation also now has info on the "ret" typemap.
-
-2016-09-27: ahmed-usman
- [xml] Handle template parameters correctly.
-
-2016-09-27: dontpanic92
- [Go] Fix argument names in inherited functions taking more than 8
- parameters. Fixes #795.
-
-2016-09-26: smarchetto
- [Scilab] mlists that map pointers can be given a custom type name.
-
-2016-09-25: wsfulton
- Patch #793 from q-p to expand exception handling to include std::bad_cast
- in std_except.i.
-
-2016-09-24: olly
- [PHP] Fix code generated for feature("director:except") -
- previously the return value of call_user_function() was ignored and
- we checked an uninitialised value instead. Fixes #627. Based on
- patch from Sergey Seroshtan.
-
-2016-09-22: wsfulton
- [Python] More flexible python builtin slots for overloaded C++ function.
-
- The closure names used for builtin slots are mangled with their functype so
- that overloaded C++ method names can be used for multiple slots.
- For example:
-
- %feature("python:slot", "mp_subscript", functype="binaryfunc") SimpleArray::__getitem__;
- %feature("python:slot", "sq_item", functype="ssizeargfunc") SimpleArray::__getitem__(Py_ssize_t n);
-
- will generate closures:
-
- SWIGPY_SSIZEARGFUNC_CLOSURE(_wrap_SimpleArray___getitem__) /* defines _wrap_SimpleArray___getitem___ssizeargfunc_closure */
- SWIGPY_BINARYFUNC_CLOSURE(_wrap_SimpleArray___getitem__) /* defines _wrap_SimpleArray___getitem___binaryfunc_closure */
-
- Previously only one name was defined: _wrap_SimpleArray___getitem___closure.
- Hence the overloaded __getitem__ method can be used to support both mp_subscript and sq_item slots.
-
-2016-09-17: wsfulton
- [Python] Fix iterators for containers of NULL pointers (or Python None) when using
- -builtin. Previously iteration would stop at the first element that was NULL.
-
-2016-09-16: olly
- [Javascript] Fix SWIG_exception() macro to return from the current
- function. Fixes #789, reported by Julien Dutriaux.
-
-2016-09-16: olly
- [PHP] Fix SWIG_exception() macro to return from the current function.
- Fixes #240, reported by Sergey Seroshtan.
-
-2016-09-12: xypron
- [C#] Patch #786 Keyword rename to be CLS compliant by adding an underscore
- suffix instead of an underscore prefix to the C symbol name. Please use an explicit
- %rename to rename the symbol with a _ prefix if you want the old symbol name.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2016-09-09: olly
- [Python] Fix import handling for Python 2.6 to work in a frozen
- application. Fixes #145, reported by Thomas Kluyver.
-
-2016-09-02: smarchetto
- [Scilab] Pointers are mapped to mlist instead of tlist
- (mlist better for scilab overloading)
-
-2016-09-02: olly
- [PHP] Fix "out" typemap for member function pointers and "in"
- typemap for char INPUT[ANY].
-
-2016-09-01: wsfulton
- [Python] More efficient Python slicing.
- Call reserve for container types that support it to avoid repeated
- memory reallocations for new slices or slices that grow in size.
-
-2016-09-01: wsfulton
- [Python] #771 - Make builtin types hashable by default.
- Default hash is the underlying C/C++ pointer. This matches up with testing for
- equivalence (Py_EQ in SwigPyObject_richcompare) which compares the pointers.
-
-2016-08-22: wsfulton
- [Python] The following builtin slots can be customized like other slots via the
- "python:<x>" and "python:slot" features where <x> is the appropriate slot name:
- tp_allocs
- tp_bases
- tp_basicsize
- tp_cache
- tp_del
- tp_dealloc
- tp_flags
- tp_frees
- tp_getset
- tp_is_gc
- tp_maxalloc
- tp_methods
- tp_mro
- tp_new
- tp_next
- tp_prev
- tp_richcompare
- tp_subclasses
- tp_weaklist
- was_sq_ass_slice
- was_sq_slice
-
- A few documentation improvements for slot customization.
-
-2016-08-09: joequant
- [R] Patch #765 Fix extern "C" header includes for C++ code.
-
-2016-08-05: olly
- [xml] Fix how the output filename is built to avoid problems when
- it contains the embedded strings ".c", ".cpp" or ".cxx".
- Fixes #540 reported by djack42.
-
-2016-07-01: wsfulton
- Fix corner case of wrapping std::vector of T pointers where a pointer to a pointer of T
- also exists in the wrapped code. SF Bug 2359417 (967).
-
-2016-06-26: wkalinin
- [Java, C#] Patch #681 Fix seg fault when ignoring nested classes.
-
-2016-06-25: mromberg
- [Python] #711 Fix -castmode and conversion of signed and unsigned integer types.
- See 2015-12-23 CHANGES entry for details of these improvements when they were
- implemented for the default options (ie not using -castmode).
-
-2016-06-25: ahnolds
- Patch #730 - Fix %implicitconv for overloaded functions when using
- -castmode or -fastdispatch options.
-
- The result is that in all overload cases where there are multiple possibilities
- with the same number of arguments, the dispatch function will first check for
- exact (aka non implicit) matches, and then subsequently check for implicit
- casting matches. This was already happening in the normal dispatch situation,
- and in the -fastdispatch case two passes through the candidates were happening,
- just with SWIG_POINTER_IMPLICIT_CONV always set. After this patch, it is not set
- on the first pass, and then set on the second pass.
-
-2016-06-25: liorgold
- Patch #727 - Add support for C++11 type aliasing.
-
-Version 3.0.10 (12 Jun 2016)
-============================
-
-2016-06-06: mromberg
- [Python] Patch #698. Add support for -relativeimport for python 2.7, so -py3 is no
- longer also required for relative import support.
-
-2016-06-05: mromberg
- [Python] Patch #694 - Fix package import regressions introduced in swig-3.0.9.
-
- 1) The code in 3.0.9 did not fall back to 'import _foo' if 'import bar._foo' failed
- (assuming bar.foo was the main module). Every place _foo is imported now first tries
- it from the package where foo was found and if that fails tries _foo as a global module.
-
- 2) The separate block of Python code that injected code to pull in the attributes
- from _foo when -builtin is used made use of the -py3 switch to either do
- 'from ._foo import *' or "from _foo import *". This block of code no longer does this
- and instead checks the Python version at runtime to switch between the two syntaxes.
-
- In summary, swig-3.0.10 has been modified to ease the creation of wrapper modules
- that can be fully made part of a Python package. SWIG no longer
- assumes the dynamically linked C module is a global module.
- The dynamic module can now be placed into either the same package as the pure Python
- module or as a global module. Both locations are used by the Python wrapper to
- locate the C module.
-
- However, this could cause a backwards incompatibility with some code
- that was relying on the ability of "from package import _module" to
- pull attributes out of the package directly. If your code populates a
- module (which is also a package) with attributes that are SWIG
- generated modules which were not loaded in a conventional way,
- swig-3.0.8 and earlier may have worked due to 'from package import
- _module' bypassing a real import and pulling your module in as an
- attribute. This will no longer work. Since this is not a common (or
- even recommended) practice, most folk should not be affected.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2016-05-31: wsfulton
- Fix #690 - Smart pointer to %ignored class doesn't expose inherited methods.
- Regression introduced in swig-3.0.9.
-
-Version 3.0.9 (29 May 2016)
-===========================
-
-2016-05-24: mromberg
- [Python] Patch #612 - Add support for Python's implicit namespace packages.
-
-2016-05-23: wsfulton
- [Ruby] Fix #602 - Error handling regression of opaque pointers introduced
- in swig-3.0.8 when C functions explicitly reset a pointer using 'DATA_PTR(self) = 0'.
- An ObjectPreviouslyDeleted error was incorrectly thrown when the pointer was used
- as a parameter.
-
-2016-05-17: tamuratak
- [Ruby] Patch #651 - Correct overloaded function error message when function is
- using %newobject.
-
-2016-05-17: aurelj
- [Ruby] Patch #582 - add support for docstring option in %module()
-
-2016-05-14: wsfulton
- Fix #434 - Passing classes by value as parameters in director methods did not create
- a copy of the argument leading to invalid memory accesses if the object was used
- after the upcall into the target language. Passing arguments by value shouldn't give
- rise to these sorts of memory problems and so the objects are now copied and ownership
- of their lifetime is controlled by the target language.
-
-2016-05-07: wsfulton
- Fix #611. Fix assertion handling defaultargs when using %extend for a template
- class and the extended methods contain default arguments.
-
-2016-05-05: ejulian
- [Python] Patch #617. Fix operator/ wrappers.
-
-2016-05-02: wsfulton
- Fix #669. Don't issue warning about ignoring base classes when the derived class is
- itself ignored.
-
-2016-04-18: ianlancetaylor
- [Go] Fix use of goout typemap when calling base method by
- forcing the "type" attribute to the value we need.
-
-2016-04-17: ianlancetaylor
- [Go] Fixes for Go 1.6: avoid returning Go pointers from
- directors that return string values; add a trailing 0 byte
- when treating Go string as C char*.
-
-2016-04-06: smarchetto
- [Scilab] #552 Make Scilab runtime keep track of pointer types
- Instead of a Scilab pointer which has no type, SWIG Scilab maps a
- pointer to a structure tlist containing the pointer adress and its type.
-
-2016-04-02: ahnolds
- [Python] Apply #598. Fix misleading error message when attempting to read a non-existent
- attribute. The previous cryptic error message:
- AttributeError: type object 'object' has no attribute '__getattr__'
- is now replaced with one mentioning the attribute name, eg:
- AttributeError: 'Foo' object has no attribute 'bar'
-
-2016-04-02: derkuci
- [Python] Patch #610 to fix #607.
- Fix single arguments when using python -builtin -O with %feature("compactdefaultargs")
-
-2016-03-31: wsfulton
- Fixes #594. Fix assertion for some languages when wrapping a C++11 enum class that
- is private in a class.
-
- Also don't wrap private enums for a few languages that attempted to do so.
-
-2016-03-31: wsfulton
- [Java] unsigned long long marshalling improvements when a negative number
- is passed from Java to C. A cast to signed long long in the C layer will now
- result in the expected value. No change for positive numbers passed to C.
- Fixes #623.
-
-2016-03-22: alexwarg
- [Lua] #398 Fix lua __getitem + inheritance
- The new handling of classes in Lua (not merging methods into the derived classes)
- breaks for classes that provide a __getitem function. The __getitem function
- prevents method calls to any method defined in a base class. This fix calls
- __getitem only if the member is not found using recursive lookup.
-
-2016-03-18: ptomulik
- [Python] #563 Stop generating unnecessary _swigconstant helpers.
-
-2016-03-16: richardbeare
- [R] #636 Add extra std::vector numeric types
-
-2016-03-14: wsfulton
- [Java] Add std_array.i for C++11 std::array support.
-
-2016-03-12: wsfulton
- [Java, C#, D] Fix static const char member variables wrappers with %javaconst(1)
- %csconst(1) or %dmanifestconst.
- This fixes the case when an integer is used as the initializer, such as:
-
- struct W { static const char w = 100; };
-
- Fix generated code parsing enum values using char escape sequences
- when these values appear in the Java code (usually when using %javaconst(1))
- such as:
-
- enum X { x1 = '\n', x2 = '\1' };
-
- Similarly for static const member char variables such as:
-
- struct Y { static const char y = '\n'; }
-
- Likewise for D and %dmanifestconstant. For C# and %csconst(1), char
- values in C# are now hex escaped as C# doesn't support C octal escaping.
-
-2016-03-11: wsfulton
- [Java C#] Add support for treating C++ base classes as Java interfaces
- instead of Java proxy classes. This enable some sort of support for
- multiple inheritance. The implementation is in swiginterface.i and
- provides additional macros (see Java.html for full documentation):
-
- %interface(CTYPE)
- %interface_impl(CTYPE)
- %interface_custom("PROXY", "INTERFACE", CTYPE)
-
-2016-03-01: wsfulton
- Add rstrip encoder for use in %rename. This is like the strip encoder but
- strips the symbol's suffix instead of the prefix. The example below
- will rename SomeThingCls to SomeThing and AnotherThingCls to AnotherThing:
-
- %rename("%(rstrip:[Cls])s") "";
-
- class SomeThingCls {};
- struct AnotherThingCls {};
-
-2016-03-01: olly
- Fix isfinite() check to work with GCC6. Fixes
- issue #615 reported by jplesnik.
-
-2016-02-17: olly
- [Python] Add missing keywords 'as' and 'with' to pythonkw.swg.
-
-2016-02-07: kwwette
- [Octave] recognise various unary functions
- * Use __float__() for numeric conversions, e.g. when calling double()
- * Map various unary functions, e.g. abs() to __abs__(), see full list
- in section 32.3.10 of manual; only available in Octave 3.8.0 or later
-
-2016-02-07: kwwette
- [Octave] export function swig_octave_prereq() for testing Octave version
-
-2016-02-06: pjohangustavsson
- [C#] Fix duplicate symbol problems when linking the source generated
- from multiple SWIG modules into one shared library for the -namespace
- option. The namespace is now mangled into the global PInvoke function
- names.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2016-01-27: ahnolds
- [Python] Added support for differentiating between Python Bytes
- and Unicode objects using by defining SWIG_PYTHON_STRICT_BYTE_CHAR
- and SWIG_PYTHON_STRICT_UNICODE_WCHAR.
-
-2016-01-27: steeve
- [Go] Ensure structs are properly packed between gc and GCC/clang.
-
-2016-01-25: ahnolds
- [Python] Support the full Python test suite in -classic mode
- * Convert long/unsigned long/long long/unsigned long long to PyInt
- rather than PyLong when possible. Certain python functions like
- len() require a PyInt when operating on old-style classes.
- * Add support for static methods in classic mode, including support
- for pythonappend, pythonprepend, and docstrings.
- * Removing the use of __swig_getmethods__ for static member methods
- since they will always be found by the standard argument lookup
- * Fix a bug where the wrong type of exception was caught when
- checking for new-style class support
-
-2016-01-23: ahnolds
- [Go] Enable support for the Go test-suite on OSX:
- * The linker on OSX requires that all symbols (even weak symbols)
- are defined at link time. Because the function _cgo_topofstack is
- only defined starting in Go version 1.4, we explicitly mark it as
- undefined for older versions of Go on OSX.
- * Avoid writing empty swigargs structs, since empty structs are not
- allowed in extern "C" blocks.
-
-2016-01-12: olly
- [Javascript] Look for "nodejs" as well as "node", as it's packaged
- as the former on Debian.
-
-2016-01-12: olly
- [Javascript] For v8 >= 4.3.0, use V8_MAJOR_VERSION.
- Fixes issue 561.
-
-2016-01-10: ahnolds
- Improved size_t and ptrdiff_t typemaps to support large values
- on platforms where sizeof(size_t) > sizeof(unsigned long) and
- sizeof(ptrdiff_t) > sizeof(long).
-
-Version 3.0.8 (31 Dec 2015)
-===========================
-
-2015-12-30: wsfulton
- The pdf documentation is now generated by wkhtmltopdf and has colour
- for the code snippets just like the html documentation!
-
-2015-12-23: ahnolds
- [Python] Fixes for conversion of signed and unsigned integer types:
-
- No longer check for PyInt objects in Python3. Because PyInt_Check
- and friends are #defined to the corresponding PyLong methods, this
- had caused errors in Python3 where values greater than what could be
- stored in a long were incorrectly interpreted as the value -1 with
- the Python error indicator set to OverflowError. This applies to
- both the conversions PyLong->long and PyLong->double.
-
- Conversion from PyLong to long, unsigned long, long long, and
- unsigned long long now raise OverflowError instead of TypeError in
- both Python2 and Python3 for PyLong values outside the range
- expressible by the corresponding C type. This matches the existing
- behavior for other integral types (signed and unsigned ints, shorts,
- and chars), as well as the conversion for PyInt to all numeric
- types. This also indirectly applies to the size_t and ptrdiff_t
- types, which depend on the conversions for unsigned long and long.
-
-2015-12-19: wsfulton
- [Python] Python 2 Unicode UTF-8 strings can be used as inputs to char * or
- std::string types if the generated C/C++ code has SWIG_PYTHON_2_UNICODE defined.
-
-2015-12-17: wsfulton
- Issues #286, #128
- Remove ccache-swig.1 man page - please use the CCache.html docs instead.
- The yodl2man and yodl2html tools are no longer used and so SWIG no
- longer has a dependency on these packages which were required when
- building from git.
-
-2015-12-16: zturner/coleb
- [Python] Fix Python3.5 interpreter assertions when objects are being
- deleted due to an existing exception. Most notably in generators
- which terminate using a StopIteration exception. Fixes #559 #560 #573.
- If a further exception is raised during an object destruction,
- PyErr_WriteUnraisable is used on this second exception and the
- original exception bubbles through.
-
-2015-12-14: ahnolds/wsfulton
- [Python] Add in missing initializers for tp_finalize,
- nb_matrix_multiply, nb_inplace_matrix_multiply, ht_qualname
- ht_cached_keys and tp_prev.
-
-2015-12-12: wsfulton
- Fix STL wrappers to not generate <: digraphs.
- For example std::vector<::X::Y> was sometimes generated, now
- corrected to std::vector< ::X::Y >.
-
-2015-11-25: wsfulton
- [Ruby] STL ranges and slices fixes.
-
- Ruby STL container setting slices fixes:
-
- Setting an STL container wrapper slice better matches the way Ruby
- arrays work. The behaviour is now the same as Ruby arrays. The only
- exception is the default value used when expanding a container
- cannot be nil as this is not a valid type/value for C++ container
- elements.
-
- Obtaining a Ruby STL container ranges and slices fixes:
-
- Access via ranges and slices now behave identically to Ruby arrays.
- The fixes are mostly for out of range indices and lengths.
- - Zero length slice requests return an empty container instead of nil.
- - Slices which request a length greater than the size of the container
- no longer chop off the last element.
- - Ranges which used to return nil now return an empty array when the
- the start element is a valid index.
-
- Ruby STL container negative indexing support improved.
-
- Using negative indexes to set values works the same as Ruby arrays, eg
-
- %template(IntVector) std::vector<int>;
-
- iv = IntVector.new([1,2,3,4])
- iv[-4] = 9 # => [1,2,3,9]
- iv[-5] = 9 # => IndexError
-
-2015-11-21: wsfulton
- [Ruby, Python] Add std::array container wrappers.
-
- These work much like any of the other STL containers except Python/Ruby slicing
- is somewhat limited because the array is a fixed size. Only slices of
- the full size are supported.
-
-2015-10-10: wsfulton
- [Python] #539 - Support Python 3.5 and -builtin. PyAsyncMethods is a new
- member in PyHeapTypeObject.
-
-2015-10-06: ianlancetaylor
- [Go] Don't emit a constructor function for a director
- class with an abstract method, since the function will
- always panic.
-
-2015-10-01: wsfulton
- Fix %shared_ptr support for private and protected inheritance.
- - Remove unnecessary Warning 520: Derived class 'Derived' of 'Base'
- is not similarly marked as a smart pointer
- - Do not generate code that attempts to cast up the inheritance chain in the
- type system runtime in such cases as it doesn't compile and can't be used.
- Remove unnecessary warning 520 for %shared_ptr when the base class is ignored.
-
-2015-10-01: vkalinin
- Fix #508: Fix segfault parsing anonymous typedef nested classes.
-
-2015-09-26: wsfulton
- [Ruby] Add shared_ptr support
-
-2015-09-13: kkaempf
- [Ruby] Resolve tracking bug - issue #225.
- The bug is that the tracking code uses a ruby hash and thus may
- allocate objects (Bignum) while running the GC. This was tolerated in
- 1.8 but is invalid (raises an exception) in 1.9.
- The patch uses a C hash (also used by ruby) instead.
-
-2015-09-09: lyze
- [CFFI] Extend the "export" feature in the CFFI module to support
- exporting to a specified package.
-
-2015-09-04: olly
- [Python] Fix docstrings for %callback functions.
-
-2015-09-03: demi-rluddy
- [Go] Removed golang stringing for signed/unsigned char
-
- Changed default handling of signed char* and unsigned char* to be
- opaque pointers rather than strings, similarly to how other
- languages work.
-
- Any existing code relying on treating signed char* or unsigned
- char* as a string can restore the old behavior with typemaps.i by
- using %apply to copy the [unchanged] char* behavior.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2015-08-07: talby
- [Perl] tidy -Wtautological-constant-out-of-range-compare warnings when building generated code under clang
-
-2015-08-07: xantares
- [Python] pep257 & numpydoc conforming docstrings:
- - Mono-line module docsstring
- - Rewrite autodoc parameters section in numpydoc style:
- https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
- - One line summary should end with "."
- - Adds a blank line after class docstring
-
-2015-08-05: vadz
- [Java] Make (char* STRING, size_t LENGTH) typemaps usable for
- strings of other types, e.g. "unsigned char*".
-
-Version 3.0.7 (3 Aug 2015)
-==========================
-
-2015-08-02: wsfulton
- [Java] Fix potential security exploit in generated Java classes.
- The swigCPtr and swigCMemOwn member variables in the generated Java
- classes are now declared 'transient' by default. Further details of the exploit
- in Android is being published in an academic paper as part of USENIX WOOT '15:
- https://www.usenix.org/conference/woot15/workshop-program/presentation/peles.
-
- In the unlikely event that you are relying on these members being serializable,
- then you will need to override the default javabody and javabody_derived typemaps
- to generate the old generated code. The relevant typemaps are in the Lib directory
- in the java.swg, boost_shared_ptr.i and boost_intrusive_ptr.i files. Copy the
- relevant default typemaps into your interface file and remove the 'transient' keyword.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2015-08-01: vadz
- Make configure --without-alllang option more useful: it can now be overridden by the following
- --with-xxx options, allowing to easily enable just one or two languages.
-
-2015-07-30: wsfulton
- Fix #440 - Initialise all newly created arrays when using %array_functions and %array_class
- in the carrays.i library - bug is only relevant when using C++.
-
-2015-07-29: wsfulton
- [Python] Improve indentation warning and error messages for code in the following directives:
-
- %pythonprepend
- %pythonappend
- %pythoncode
- %pythonbegin
- %feature("shadow")
-
- Old error example:
- Error: Line indented less than expected (line 3 of pythoncode)
-
- New error example:
- Error: Line indented less than expected (line 3 of %pythoncode or %insert("python") block)
- as no line should be indented less than the indentation in line 1
-
- Old warning example:
- Warning 740: Whitespace prefix doesn't match (line 2 of %pythoncode or %insert("python") block)
-
- New warning example:
- Warning 740: Whitespace indentation is inconsistent compared to earlier lines (line 3 of
- %pythoncode or %insert("python") block)
-
-
-2015-07-28: wsfulton
- [Python] Fix #475. Improve docstring indentation handling.
-
- SWIG-3.0.5 and earlier sometimes truncated text provided in the docstring feature.
- This occurred when the indentation (whitespace) in the docstring was less in the
- second or later lines when compared to the first line.
- SWIG-3.0.6 gave a 'Line indented less than expected' error instead of truncating
- the docstring text.
- Now the indentation for the 'docstring' feature is smarter and is appropriately
- adjusted so that no truncation occurs.
-
-2015-07-22: wsfulton
- Support for special variable expansion in typemap attributes. Example usage expansion
- in the 'out' attribute (C# specific):
-
- %typemap(ctype, out="$*1_ltype") unsigned int& "$*1_ltype"
-
- is equivalent to the following as $*1_ltype expands to 'unsigned int':
-
- %typemap(ctype, out="unsigned int") unsigned int& "unsigned int"
-
- Special variables can be used within special variable macros too. Example usage expansion:
-
- %typemap(cstype) unsigned int "uint"
- %typemap(cstype, out="$typemap(cstype, $*1_ltype)") unsigned int& "$typemap(cstype, $*1_ltype)"
-
- Special variables are expanded first and hence the above is equivalent to:
-
- %typemap(cstype, out="$typemap(cstype, unsigned int)") unsigned int& "$typemap(cstype, unsigned int)"
-
- which then expands to:
-
- %typemap(cstype, out="uint") unsigned int& "uint"
-
-2015-07-22: lindleyf
- Apply patch #439 - support for $typemap() (aka embedded typemaps or special variable
- macros) in typemap attributes. A simple example where $typemap() is expanded in the
- 'out' attribute (C# specific):
-
- %typemap(cstype) unsigned int "uint"
- %typemap(cstype, out="$typemap(cstype, unsigned int)") unsigned int& "$typemap(cstype, unsigned int)"
-
- is equivalent to:
-
- %typemap(cstype, out="uint") unsigned int& "uint"
-
-2015-07-18: m7thon
- [Python] Docstrings provided via %feature("docstring") are now quoted and added to
- the tp_doc slot when using python builtin classes (-builtin). When no docstring is
- provided, the tp_doc slot is set to the fully qualified C/C++ class name.
- Github issues #445 and #461.
-
-2015-07-17: kwwette
- [octave] Support Octave version 4.0.0 (thanks to patches from Orion Poplawski).
-
-2015-07-07: wsfulton
- SWIG no longer generates a wrapper for a class' constructor if that class has
- any base class with a private destructor. This is because your compiler should
- not allow a class to be instantiated if a base has a private destructor. Some
- compilers do, so if you need the old behaviour, use the "notabstract" feature, eg:
-
- %feature("notabstract") Derived;
- class Base {
- ~Base() {}
- };
- struct Derived : Base {};
-
-Version 3.0.6 (5 Jul 2015)
-==========================
-
-2015-07-02: wsfulton
- Fix syntax error when the template keyword is used in types, eg:
-
- std::template vector<int> v;
-
-2015-07-02: ngladitz
- [Lua] Push characters as unformatted 1-character strings to avoid
- unprintable characters such as (char)127 being converted to
- "<\127>" with Lua 5.3 and later. (github PR #452)
-
-2015-06-29: olly
- [Python] Improve handling of whitespace in %pythoncode.
-
- Previously SWIG looked at the indentation of the first line and
- removed that many characters from each subsequent line, regardless
- of what those characters were. This was made worse because SWIG's
- preprocessor removes any whitespace before a '#'. Fixes github
- issue #379, reported by Joe Orton.
-
-2015-06-12: wsfulton
- [R] Fix #430 - call to SWIG_createNewRef in copyToC was incorrectly named.
-
-2015-06-11: sghirate
- [C#] Patch #427 adds in new command line option -outfile to combine all the
- generated C# code into a single file.
-
-2015-06-09: wsfulton
- Fix seg fault processing C++11 type aliasing. Issue #424.
-
-2015-05-28: wsfulton
- [Python] Add new feature "python:cdefaultargs" to control default argument
- code generation. By default, SWIG attempts to convert C/C++ default argument values
- into Python values and generates code into the Python layer with these values.
- Recent versions of SWIG are able to convert more of these values, however, the
- new behaviour can be circumvented if desired via this new feature, such that
- the default argument values are obtained from the C layer and not the Python layer.
- For example:
-
- struct CDA {
- int fff(int a = 1, bool b = false);
- };
-
- The default code generation in the Python layer is:
-
- class CDA(_object):
- ...
- def fff(self, a=1, b=False):
- return _default_args.CDA_fff(self, a, b)
-
- Adding the feature:
-
- %feature("python:cdefaultargs") CDA::fff;
-
- Results in:
-
- class CDA(_object):
- ...
- def fff(self, *args):
- return _default_args.CDA_fff(self, *args)
-
- Some code generation modes, eg -builtin and -fastproxy, are unaffected by this as
- the default values are always obtained from the C layer.
-
-2015-05-27: wsfulton
- [Python] Deal with an integer as the default value of a typedef to bool
- parameter in the C++ prototype. See #327. Regression from 3.0.0 onwards.
-
-2015-05-19: olly
- [Python] Fix warning when compiling generated code with MSVC.
- (Fixes https://sourceforge.net/p/swig/patches/351/ reported by
- Mateusz Szyma¿ski).
-
-2015-05-14: wsfulton
- Fix seg fault wrapping shared_ptr of classes with private constructors and destructors.
- This also fixes the "unref" feature when used on classes with private destructors.
-
-2015-05-10: wsfulton
- [Java] Fix multi-argument typemaps (char *STRING, size_t LENGTH)
- so that they can be applied to a wider range of types. Fixes #385.
-
-2015-05-07: olly
- [Python] Deal with an integer as the default value of a bool
- parameter in the C++ prototype. Fixes github #327, reported by
- Greg Allen.
-
-2015-05-07: LindleyF
- [Java] Allow feature("director") and feature("ref") to be used
- together. Github PR#403.
-
-2015-05-05: olly
- Suppress warning 325 "Nested class not currently supported (Foo
- ignored)" when Foo has already been explicitly ignored with "%ignore".
-
-2015-05-04: wsfulton
- Add support for friend templates, including operator overloading - fixes #196. Considering
- the example below, previously the operator gave a syntax error and friendfunc incorrectly
- warned with:
-
- "Warning 503: Can't wrap 'friendfunc<(Type)>' unless renamed to a valid identifier."
-
- template <class Type> class MyClass {
- friend int friendfunc <Type>(double is, MyClass <Type> & x);
- friend int operator<< <Type>(double un, const MyClass <Type> &x);
- };
-
- The following also previously incorrectly warned with:
-
- "Warning 302: Identifier 'template_friend' redefined (ignored),"
-
- template<typename T> T template_friend(T);
- struct MyTemplate {
- template<typename T> friend T template_friend(T);
- };
-
-2015-05-01: wsfulton
- Fix handling of conversion operators where the operator is split over multiple
- lines or has comments within the operator type. Fixes #401.
-
- Also fix similar problem with normal operators which gave a syntax error if split over
- multiple lines or had a comment within the operator declaration.
-
-2015-04-30: olly
- Ignore unknown preprocessor directives which are inside an inactive
- conditional (github issue #394, reported by Dan Wilcox).
- Regression introduced in 3.0.3.
-
-2015-04-27: vadz
- [Python] Fix "default" typemap used after an argument with "numinputs=0" (#377).
-
-2015-04-24: wsfulton
- [Python] Fix #256. Code generated with '-builtin -modernargs' segfaults for any
- method taking zero arguments.
-
- Also fixes: "SystemError: error return without exception set" during error checking
- when using just -builtin and the incorrect number of arguments is passed to a class
- method expecting zero arguments.
-
-2015-04-23: wsfulton
- [Java] Bug #386 - Memory leak fix in (char *STRING, size_t LENGTH) typemaps.
-
-2015-04-23: vadz
- [Python] Make "default" typemap work again (#330, #377).
-
-2015-04-23: vadz
- [Python] Fix the use of default values for the pointer types (#365, #376).
-
-2015-04-23: wsfulton
- Fix 'make check-ccache' which is part of 'make check' when one of the CCACHE_
- environment variables, for example CCACHE_DISABLE, is set.
-
-2015-04-14: wsfulton
- Clearer warning message for badly constructed typecheck typemaps. For example, was:
-
- example.i:3: Warning 467: Overloaded foo(int) not supported (no type checking
- rule for 'int').
-
- Now:
-
- example.i:3: Warning 467: Overloaded foo(int) not supported (incomplete type checking
- rule - no precedence level in typecheck typemap for 'int').
-
-2015-04-11: wsfulton
- [Java] Fix #353 - Linker multiple definition of 'ExceptionMatches' when
- using directors and multiple modules.
-
-2015-04-11: wsfulton
- Merge #320 - Make __dict__ accessible for Python builtin classes.
-
-2015-04-07: wsfulton
- Fix #375 - parsing of extern "C" and typedef for example:
- extern "C" typedef void (*Hook2_t)(int, const char *);
- extern "C" typedef int Integer;
-
-2015-03-12: olly
- -DSWIG_DIRECTOR_STATIC is now supported for all languages with
- director support, not only Python and PHP.
-
-2015-03-02: ianlancetaylor
- [Go] Add -cgo option, required for Go versions 1.5 and
- later.
-
-2015-02-26: olly
- Fix segmentation fault when top==NULL, introduced by nested class
- handling (reported in issue#346 by Pawe¿ Tomulik).
-
-2015-02-09: wsfulton
- [Guile] Fix generated code for static const char member variables when
- defined and declared inline.
-
-2015-02-09: mishas
- [Go] Fix %import of files in sub directories.
-
-2015-02-05: ianlancetaylor
- [Go] Ignore Go specific type maps (goin, goout, etc.) if they are empty.
-
-2015-02-05: ianlancetaylor
- [Go] Generated Go code no longer calls _swig_goallocate or
- _swig_makegostring, as they will no longer work as of Go 1.5.
-
-Version 3.0.5 (31 Jan 2015)
-===========================
-
-2015-01-30: wsfulton
- [Python] Fix Python -classic and property setting. Setting properties on classic classes
- was broken in swig-3.0.3 by attempting to use __setattr__. This regression is fixed now
- by using __dict__ again when using -classic.
- Fixes patch #232.
-
-2015-01-27: smarchetto
- [Scilab] Support for the Scilab language has been added
-
-2015-01-23: olly
- [PHP] When wrapping a returned resource as an object, check if all
- cases wrap it in the same class, and if so eliminate the pointless
- switch statement wrapper we previously generated.
-
-2015-01-22: wsfulton
- [Octave] Merge patch #297 for SF bug #1277 - Octave shared_ptr support
-
-2015-01-15: wsfulton
- [Python] Merge patch #250 - Fixes for using %constant and objects (non-primitive types)
-
-2015-01-15: wsfulton
- [C# Go] Merge patch #308 and fix #307 - C++11 strongly typed enum support
- in directors
-
-2015-01-15: wsfulton
- [Python] Second fix for #294 #296 - Regression introduced in SWIG-3.0.3 when
- wrapping functions with default arguments, this time when using kwargs.
-
-Version 3.0.4 (14 Jan 2015)
-===========================
-
-2015-01-12: olly
- [PHP] Fix segfault in director upcall check when using PHP built with
- ZTS enabled. Fixes #155, reported by Pierre Labastie.
-
-2015-01-12: vadz
- [Python] Fix #294 #296 - Regression introduced in SWIG-3.0.3 when
- wrapping functions with default arguments. Invalid or missing default
- arguments were sometimes being generated into the python layer.
-
-2015-01-08: olly
- Allow C++11 "explicit constexpr". Fixes github issue #284 reported
- by Pawel Tomulik. Also handle "constexpr explicit" and "constexpr
- static".
-
-2015-01-08: olly
- When reporting an error for a construct which hasn't been
- terminated when the end of the file is reached, report it at the
- start line rather than "EOF" as then tools like editors and IDEs
- will take you to a generally more useful place for fixing the
- problem.
-
-2015-01-08: olly
- Improve error messages for a few cases which previously gave the
- one of the cryptic catch-all errors "Syntax error in input".
-
-2015-01-08: olly
- Provide -cppext as a general command line option for setting the
- extension used for generated C++ files (previously it was specific
- to the PHP backend). Deprecate the equivalent -suffix option
- provided by the Ocaml backend, but continue to support that for
- now.
-
-Version 3.0.3 (30 Dec 2014)
-===========================
-
-2014-12-27: wsfulton
- Fix #280 - abort using all default template parameters within other template
- parameters.
-
-2014-12-27: talby
- [Perl] Issue #282 perl5 archlib vs archlibexp
- [Perl] tidy "warning: duplicate 'extern' declaration specifier" when building generated code
- under clang
-
-2014-12-18: wsfulton
- Add support for %constant and structs/classes - issue #272
-
-2014-12-09: wsfulton
- Fix #245 - regression (since swig-3.0.0) in templated constructors.
- Templated constructors could not be instantiated - they were incorrectly ignored with a warning 504:
- "Function: xyz must have a return type. Ignored."
-
-2014-12-07: wsfulton
- Add support for C++11 strongly typed enumerations.
-
-2014-11-21: wsfulton
- [Java C#] Fix multiply defined error when using %rename of enum items when using the "simple enum"
- wrappers.
-
-2014-10-28: vadz
- [Python] Patch #201 The generated .py file no longer uses *args for all Python parameters.
- Instead, the parameters are named using the C++ parameter names.
-
- "compactdefaultargs" feature can be enabled to restore the old behaviour.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2014-10-24: timotheecour
- [D] Patch #204 Use core.atomic.atomicOp to mutate shared variables
-
-2014-10-21: wsfulton
- Fix issue #242 - Use of the "kwargs" feature no longer automatically turns on the
- "compactdefaultargs" feature if the target language does not support kwargs.
- This change affects all languages except Python and Ruby.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2014-10-10: diorcety
- [Python] Patch #232 Fix property access using directors
-
-2014-10-06: wsfulton
- [Python] Fixes when using -builtin and std::vector/std::list wrappers to allow deletion
- of single elements, such as 'del vec[0]'.
-
-2014-09-30: oliverb
- [Javascript] Merge patch #216 by Richie765 - Added support for many versions of v8 javascript.
-
-2014-09-30: oliverb
- [Javascript] Merge patch #195 by zittix - Fixed JSClassRef declaration not using the static one.
-
-2014-09-30: ianlancetaylor
- [Go] In configure script, require Go 1.1 or later.
-
-2014-09-30: wsfulton
- [Python] Patch #207 - Fix No module error with -relativeimport when using single
- header file import.
-
-2014-09-27: wsfulton
- Patch #208 - Initialise newly created array when using array_functions in the
- carrays.i library (C++ usage).
-
-2014-09-27: wsfulton
- [Ruby] Patch #187 - Fix crash on shutdown of the Ruby interpreter if more than one
- module was loaded at a time when data is being shared between modules.
-
-2014-09-27: wsfulton
- [Java] Patch #168 - Fix leak in Java director string handling after the Java
- upcall when called from a native thread.
-
-2014-09-25: ianlancetaylor
- [Go] Adjust generated code to work with upcoming Go 1.4
- release.
-
-2014-09-23: wsfulton
- [Python] Add patch from Thomas Maslach to fix crash in wrappers when using -threads in
- the STL iterators (SwigPyIterator destructor).
-
-2014-09-17: wsfulton
- [C#] Merge patch #229 from contre - Add bool array types to arrays_csharp.i
-
-2014-09-12: olly
- [PHP] Add support for specifying any PHP interfaces a wrapped class
- implements, e.g.: %typemap("phpinterfaces") MyIterator "Iterator"
-
-2014-09-11: olly
- [PHP] Fix throwing a PHP exception through C++ from a subclassed
- director method - PHP NULL gets returned by the subclassed method
- in this case, so the directorout typemap needs to allow that (at
- least if an exception is active).
-
-2014-09-09: ianlancetaylor
- [Go] Add goargout typemap.
-
-2014-09-09: olly
- [PHP] Fix segmentation faults with directors in PHP >= 5.4, and
- reenable runme tests for director_basic testcase. Fix from
- pavel-charvat in issue#164.
-
-2014-09-05: ianlancetaylor
- [Go] Add imtype, goin, goout, godirectorin, and
- godirectorout typemaps, to support writing Go code to
- convert between types.
-
-2014-09-02: olly
- [Python] Fix regression in indentation of python code produced with
- -modern, introduced by changes in #188. Reported by fabiencastan
- in #218.
-
-2014-09-01: olly
- Issue an error for unknown SWIG preprocessor directives, rather
- than quietly ignoring them. Reported by jrhelsey in issue#217.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2014-08-15: talby
- [Perl] Include guard fix for nested modules from Anthony Heading (SF Patch #350).
-
-2014-08-04: wsfulton
- [C#] Merge patch #200 from gpetrou - Changed CSharp license header to include auto-generated
- tag so that StyleCop ignores the files.
-
-2014-08-04: wsfulton
- [Java] Merge patch #198 from Yuval Kashtan - Support for java.nio.ByteBuffer mapping to
- unsigned char * in various.i in NIOBUFFER typemaps.
-
-2014-07-14: ianlancetaylor
- [Go] Change struct definition to use void *, not uint8, so
- that the type is recorded as possibly containing
- pointers. This ensures that the 1.3 garbage collector
- does not collect pointers passed to C++ code.
-
-2014-07-01: wsfulton
- Fix SF Bug #1375 - Expansion of the $parentclassname special variable incorrectly contains
- brackets in the expanded name.
-
-Version 3.0.2 (4 Jun 2014)
-==========================
-
-2014-06-02: v-for-vandal
- [Lua] Pull request #176:
- If class has no __eq implemented, then default __eq is generated.
- Default __eq compares actual pointers stored inside Lua userdata.
-
-2014-06-02: vkalinin
- Fix #183 - %extend and unnamed nested structs
-
-2014-05-28: kwwette
- Fix install failure when using an 'out of source' build using the shipped
- tarball - regression introduced in swig-3.0.1.
-
-2014-05-24: kwwette
- [Octave] Remove deprecated -global/-noglobal command-line arguments
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-Version 3.0.1 (27 May 2014)
-===========================
-
-2014-05-25: hfalcic
- [Python] Python 3 byte string output: use errors="surrogateescape"
- if available on the version of Python that's in use. This allows
- obtaining the original byte string (and potentially trying a fallback
- encoding) if the bytes can't be decoded as UTF-8.
-
- Previously, a UnicodeDecodeError would be raised with no way to treat
- the data as bytes or try another codec.
-
-2014-05-18: vkalinin
- Bug #175 - Restore %extend to work for unnamed nested structures by using a C
- symbol comprising the outer structure name and unnamed variable instance name.
-
-2014-05-15: kwwette
- Add #166 - 'make check' now works out of source. This required the examples to build
- out of source. The main languages have been tested - C#, Go, Guile, Java, Javascript,
- Lua, Octave, Perl, PHP, Python, Ruby and Tcl.
-
-2014-05-01: Oliver Buchtala
- Javascript support added, see Javascript chapter in the documentation.
-
-2014-05-01: olly
- [PHP] The generated __isset() method now returns true for read-only properties.
-
-2014-04-24: kwwette
- [Go] Fix go ./configure parsing of gccgo --version, and
- goruntime.swg typo in __GNUC_PATCHLEVEL__ (SF Bug #1298)
-
-2014-04-24: kwwette
- Fix {python|perl5|ruby|tcl}/java examples
-
- In Lib/gcj/cni.i, for compatibility with newer gcj versions:
-
- - remove JvAllocObject() which gcj no longer defines, from gcj Changelog:
- 2004-04-16 Bryce McKinlay <mckinlay@redhat.com>
- * gcj/cni.h (JvAllocObject): Remove these obsolete,
- undocumented CNI calls.
-
- - change JvCreateJavaVM() argument from void* to JvVMInitArgs*, from gcj Changelog:
- 2005-02-23 Thomas Fitzsimmons <fitzsim@redhat.com>
- PR libgcj/16923
- ...
- (JvCreateJavaVM): Declare vm_args as JvVMInitArgs* rather than void*.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2014-04-08: wsfulton
- SF Bug #1366 - Remove duplicate declarations of strtoimax and strtoumax in inttypes.i
-
-2014-04-08: wsfulton
- [Java C#] Enums which have been ignored via %ignore and are subsequently
- used are handled slightly differently. Type wrapper classes are now generated
- which are effectively a wrapper of an empty enum. Previously in Java uncompilable
- code was generated and in C# an int was used.
-
-2014-04-04: wsfulton
- Fix regression in 3.0.0 where legal code following an operator<< definition might
- give a syntax error. SF Bug #1365.
-
-2014-04-03: olly
- [PHP] Fix wrapping director constructors with default parameters
- with a ZTS-enabled build of PHP.
-
-2014-04-02: olly
- [PHP] Pass the ZTS context we already have to avoid needing to
- call TSRMLS_FETCH, which is relatively expensive.
-
-2014-04-02: olly
- [PHP] Pass ZTS context through to t_output_helper() so it works
- with a ZTS-enabled build of PHP. Reported by Pierre Labastie in
- github PR#155.
-
-2014-03-28: wsfulton
- [Java C# D Go] Fixes for C enums used in an API and the definition of the enum
- has not been parsed. For D, this fixes a segfault in SWIG. The other languages
- now produce code that compiles, although the definition of the enum is needed
- in order to use the enum properly from the target language.
-
-2014-03-23: v-for-vandal
- [Lua] Fix for usage of snprintf in Lua runtime which Visual Studio does not have.
-
-Version 3.0.0 (16 Mar 2014)
-===========================
-
-2014-03-16: wsfulton
- C++11 support initially developed as C++0x support by Matevz Jekovec as a Google Summer of Code
- project has been further extended. The C++11 support is comprehensive, but by no means complete
- or without limitations. Full details for each new feature in C++11 is covered in the
- CPlusPlus11.html chapter in the documentation which is included in SWIG and also available
- online at https://www.swig.org/Doc3.0/CPlusPlus11.html.
-
-2014-03-14: v-for-vandal
- [Lua] Numerous Lua improvements:
- 1. %nspace support has been added. Namespaces are mapped to tables in the module, with the same
- name as the C++ namespace.
- 2. Inheritance is now handled differently. Each class metatable keeps a list of class bases instead
- of merging all members of all bases into the derived class.
- 3. The new metatables result in differences in accessing class members. For example:
-
- %module example
- struct Test {
- enum { TEST1 = 10, TEST2 = 20 };
- static const int ICONST = 12;
- };
-
- Now this can be used as follows:
- print(example.Test.TEST1)
- print(example.Test.ICONST)
- The old way was:
- print(example.Test_TEST1)
- print(example.Test_ICONST)
-
- 4. The special class metatable member ".constructor" was removed. Now SWIG generates the proxy
- function by itself and assigns it directly to the class table "__call" method.
- 5. eLua should also now support inheritance.
- 6. 'const' subtable in eLua is considered deprecated.
-
- Changes in behaviour:
- a. You can no longer assign to non-existing class members in classes without a __setitem__ method.
- It will cause a Lua error.
- b. You can no longer iterate over a module table and copy everything into the global namespace.
- Actually, this was never the case, but it is now explicitly prohibited.
- c. Now changing a base class will immediately affect all derived classes.
- d. There might be some issues with inheritance. Although the bases iteration scheme is the same
- as was used for merging base classes into derived one, some unknown issues may arise.
-
- The old metatable behaviour can be restored by using the -no-old-metatable-bindings option.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2014-03-06: wsfulton
- [Python] Change in default behaviour wrapping C++ bool. Only a Python True or False
- will now work for C++ bool parameters. This fixes overloading bool with other types.
- Python 2.3 minimum is now required for wrapping bool.
-
- When wrapping:
-
- const char* overloaded(bool value) { return "bool"; }
- const char* overloaded(int value) { return "int"; }
-
- Previous behaviour:
- >>> overloaded(False)
- 'int'
- >>> overloaded(True)
- 'int'
- >>> overloaded(0)
- 'int'
-
- Now we get the expected behaviour:
- >>> overloaded(False)
- 'bool'
- >>> overloaded(0)
- 'int'
-
- The consequence is when wrapping bool in non-overloaded functions:
-
- const char* boolfunction(bool value) { return value ? "true" : "false"; }
-
- The previous behaviour was very Pythonic:
- >>> boolfunction("")
- 'false'
- >>> boolfunction("hi")
- 'true'
- >>> boolfunction(12.34)
- 'true'
- >>> boolfunction(0)
- 'false'
- >>> boolfunction(1)
- 'true'
-
- Now the new behaviour more along the lines of C++ due to stricter type checking. The
- above calls result in an exception and need to be explicitly converted into a bool as
- follows:
- >>> boolfunction(0)
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- TypeError: in method 'boolfunction', argument 1 of type 'bool'
- >>> boolfunction(bool(0))
- 'false'
-
- The old behaviour can be resurrected by passing the -DSWIG_PYTHON_LEGACY_BOOL command line
- parameter when executing SWIG. Typemaps can of course be written to customise the behaviour
- for specific parameters.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2014-03-06: wsfulton
- Fix SF Bug #1363 - Problem with method overloading when some methods are added by %extend
- and others are real methods and using template default parameters with smart pointers.
- This is noticeable as a regression since 2.0.12 when using the default smart pointer
- handling for some languages when the smart pointer wraps std::map and other STL containers.
-
-2014-03-02: wsfulton
- [Python] SF Patch #346 from Jens Krueger. Correct exception thrown attempting to
- access a non-existent C/C++ global variable on the 'cvar' object. The exception thrown
- used to be a NameError. However, as this access is via a primary, an AttributeError
- is more correct and so the exception thrown now is an AttributeError. Reference:
- http://docs.python.org/2/reference/expressions.html#attribute-references
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2014-03-01: wsfulton
- [Python] Patch #143 Fix type shown when using type() to include the module and package
- name when using -builtin.
-
-2014-03-01: wsfulton
- [Python] SF patch #347 Fix missing argument count checking with -modern.
- Fixes regression introduced when builtin changes were introduced in SWIG-2.0.3.
-
-2014-02-21: wsfulton
- [PHP] Fix warning suppression using %warnfilter for PHP reserved class names.
-
-2014-02-19: olly
- [Lua] Add keyword warnings for Lua keywords and Basic Functions.
-
-2014-02-19: olly
- -Wallkw now includes keywords for all languages with keyword
- warnings (previously Go and R were missing).
-
-2014-02-19: olly
- [PHP] Update the lists of PHP keywords with new ones from PHP 5.4
- and newer (and some missing ones from 5.3). Reserved PHP constants
- names are now checked against enum values and constants, instead
- of against function and method names. Built-in PHP function names
- no longer match methods added by %extend. Functions and methods
- named '__sleep', '__wakeup', 'not', 'parent', or 'virtual' are no
- longer needlessly renamed.
-
-2014-02-15: wsfulton
- Fix the %$ismember %rename predicates to also apply to members added via %extend.
-
- Add %$isextendmember for %rename of members added via %extend. This can be used to
- distinguish between normal class/struct members and %extend members. For example
- '%$ismember, %$not %$isextendmember' will now identify just class/struct members.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2014-02-16: hfalcic
- [Python] Patch #137 - fix crashes/exceptions in exception handling in Python 3.3
-
-2014-02-15: wsfulton
- [Java] Add support for the cdata library.
-
-2014-02-08: vkalinin
- Nested class support added. This primarily allows SWIG to properly parse nested
- classes and keep the nested class information in the parse tree. Java and C#
- have utilised this information wrapping the C++ nested classes as Java/C#
- nested classes. The remaining target languages ignore nested classes as in
- previous versions. Help is needed by users of these remaining languages to
- design how C++ nested classes can be best wrapped. Please talk to us on the
- swig-devel mailing list if you think you can help.
-
- Previously, there was limited nested class support. Nested classes were treated
- as opaque pointers. However, the "nestedworkaround" feature provided a way to
- wrap a nested class as if it was a global class. This feature no longer exists
- and is replaced by the new "flatnested" feature. This effectively does the same
- thing with less manual code to be written. Please see the 'Nested classes'
- section in the documentation in SWIGPlus.html if you were previously using this
- feature.
-
- SWIG now parses the contents of nested classes where previously it did not. You
- may find that you will need to make adjustments to your interface file as
- effectively extra code is being wrapped.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2014-02-06: gjanssens
- [Guile] Patch #133. Make scm to string conversion work with non-ascii strings.
- Guile 2 has a completely rewritten string implementation. SWIG made some assumptions
- that are no longer valid as to the internals of guile's string representation.
-
-2014-01-30: wsfulton
- [C#] Add new swigtype_inout.i library containing SWIGTYPE *& OUTPUT typemaps.
-
- Example usage wrapping:
-
- void f(XXX *& x) { x = new XXX(111); }
-
- would be:
-
- XXX x = null;
- f(out x);
- // use x
- x.Dispose(); // manually clear memory or otherwise leave out and leave it to the garbage collector
-
-2014-01-21: ianlancetaylor
- [Go] Add %go_import directive.
-
-2014-01-21: ianlancetaylor
- [Go] Add support for Go 1.3, not yet released.
-
-2014-01-20: wsfulton
- Director exceptions (Swig::DirectorException) now derive from std::exception
- and hence provide the what() method. In Python and Ruby, this replaces the now
- deprecated DirectorException::getMessage() method.
-
-2014-01-14: diorcety
- Patch #112 - Fix symbol resolution involving scopes that have multiple levels
- of typedefs - fixes some template resolutions as well as some typemap searches.
-
-2014-01-11: wsfulton
- Fix and document the naturalvar feature override behaviour - the naturalvar
- feature attached to a variable name has precedence over the naturalvar
- feature attached to the variable's type. The overriding was not working
- when turning the feature off on the variable's name.
-
- Fix so that any use of the naturalvar feature will override the global
- setting. Previously when set globally by -naturalvar or %module(naturalvar=1),
- use of the naturalvar feature was not always honoured.
-
-2014-01-06: ianlancetaylor
- [Go] Fix bug that broke using directors from a thread not
- created by Go.
-
-2013-12-24: ptomulik
- [Python] SF Bug #1297
-
- Resolve several issues related to python imports.
- For example, it's now possible to import modules having the same module
- names, but belonging in different packages.
-
- From the user's viewpoint, this patch gives a little bit more control on
- import statements generated by SWIG. The user may choose to use relative
- or absolute imports.
-
- Some details:
- - we (still) generate import statements in the form 'import a.b.c' which
- corresponds to absolute imports in python3 and (the only available)
- ambiguous one in python2.
- - added -relativeimport option to use explicit relative import syntax
- (python3),
-
- The "Python Packages" section in the documentation discusses how to work
- with importing packages including the new -relativeimport command line option.
-
-2013-12-23: vadz
- [Octave, Perl, Python, R, Ruby, Tcl] Change the length of strings created from fixed-size char
- buffers in C code.
-
- This is a potential backwards compatibility break: a "char buf[5]" containing "ho\0la" was
- returned as a string of length 5 before, but is returned as a string of length 2 now. Also,
- it was possible to assign a (non-NUL-terminated) string "hello" to such a buffer before but
- now this fails and only "helo" can fit.
-
- Apply "char FIXSIZE[ANY]" typemaps to explicitly choose the old behaviour.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2013-12-23: talby
- [Perl] Add support for directors.
-
-2013-12-18: ianlancetaylor
- [Go] Don't require that Go environment variables be set
- when running examples or testsuite when using Go 1 or
- later.
-
-2013-12-17: ianlancetaylor
- [Go] Remove -longsize option (for backward compatibility,
- ignore it if seen).
-
-2013-12-17: ianlancetaylor
- [Go] Add -go-pkgpath option.
-
-2013-12-16: ianlancetaylor
- [Go] Update for Go 1.2 release. Add support for linking
- SWIG code directly into executable, rather than using a
- shared library.
-
-2013-12-13: ianlancetaylor
- [Go] Add SWIG source file name as comments in generated
- files. This can be used by Go documentation tools.
-
-2013-12-12: jleveque
- [Lua] Fix typo (wchar instead of wchar_t) which made wchar.i
- for Lua useless.
-
-2013-12-12: vmiklos
- [PHP] PHP's peculiar call-time pass-by-reference feature was
- deprecated in PHP 5.3 and removed in PHP 5.4, so update the REF
- typemaps in phppointers.i to specify pass-by-reference in the
- function definition. Examples/php/pointer has been updated
- accordingly.
-
-2013-12-12: olly
- [PHP] The usage of $input in PHP directorout typemaps has been
- changed to be consistent with other languages. The typemaps
- provided by SWIG have been updated accordingly, but if you
- have written your own directorout typemaps, you'll need to
- update $input to &$input (or make equivalent changes).
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2013-11-27: vadz
- [C#, Java, Python] Add std_auto_ptr.i defining typemaps for returning std::auto_ptr<>.
-
-2013-11-09: wsfulton
- [C#] Apply patch #79 from Brant Kyser
- - Remove using directives from the generated C# code and fully qualify the use of all .NET
- framework types in order to minimize potential name collisions from input files defining
- types, namespace, etc with the same name as .NET framework members.
- - Globally qualify the use of .NET framework types in the System namespace
- - Remove .NET 1.1 support, .NET 2 is the minimum for the C# module
-
- This is a potential backwards compatibility break if code has been added relying on these using
- statements that used to be generated:
-
- using System;
- using System.Runtime.InteropServices;
-
- The quick fix to add these back in is to add the -DSWIG2_CSHARP command line option when
- executing SWIG. See CSharp.html documentation for more info.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2013-11-05: wsfulton
- [Java] Fix some corner cases for the $packagepath/$javaclassname special variable substitution.
-
-2013-11-05: wsfulton
- [Java] Apply patch #91 from Marvin Greenberg - Add director:except feature for improved
- exception handling in director methods for Java.
-
-2013-10-15: vadz
- Allow using \l, \L, \u, \U and \E in the substitution part of %(regex:/pattern/subst/)
- inside %rename to change the case of the text being replaced.
-
-2013-10-12: wsfulton
- [CFFI] Apply #96 - superclass not lispify
-
-2013-10-12: wsfulton
- Merge in C++11 support from the gsoc2009-matevz branch where Matevz Jekovec first
- started the C++0x additions. Documentation of the C++11 features supported is in a
- new Chapter of the documentation, "SWIG and C++11" in Doc/Manual/CPlusPlus11.html.
-
-2013-10-04: wsfulton
- Fix %naturalvar not having any affect on templated classes instantiated with an
- enum as the template parameter type. Problem reported by Vadim Zeitlin.
-
-2013-09-20: wsfulton
- [Java] Fix a memory leak for the java char **STRING_ARRAY typemaps.
-
-Version 2.0.12 (9 Feb 2014)
-===========================
-
-2014-01-16: wsfulton
- [PHP] Fix compilation error in ZTS mode (64 bit windows) due to incorrect placement
- of TSRMLS_FETCH() in SWIG_Php_GetModule() as reported by Mark Dawson-Butterworth.
-
-2014-01-13: kwwette
- [Octave] update support to Octave version 3.8.0
-
- - Octave 3.8.0 no longer defines OCTAVE_API_VERSION_NUMBER, but 3.8.1
- will define OCTAVE_{MAJOR,MINOR,PATCH}_VERSION instead: see
- http://hg.savannah.gnu.org/hgweb/octave/rev/b6b6e0dc700e
- So we now use a new macro SWIG_OCTAVE_PREREQ(major,minor,patch) to
- enable features requiring Octave version major.minor.patch or later.
-
- For Octave versions prior to 3.8.1, we reconstruct values for
- OCTAVE_{MAJOR,MINOR,PATCH}_VERSION based on OCTAVE_API_VERSION_NUMBER,
- extracted from Octave's ChangeLogs. An additional hack is needed to
- distinguish between Octave <= 3.2.x and 3.8.0, neither of which define
- OCTAVE_API_VERSION_NUMBER.
-
- - Octave 3.8.0 deprecates symbol_table::varref(), so remove its use
- for this and future versions of Octave.
-
- - Octave 3.8.0 removes octave_value::is_real_nd_array(), used in
- octave_swig_type::dims(). Its use is not required here, so remove it.
-
- - Retested against Octave versions 3.0.5, 3.2.4, 3.4.3, 3.6.4, and 3.8.0.
-
- - Updated Octave documentation with tested Octave versions, and added a
- warning against using versions <= 3.x.x, which are no longer tested.
-
-2013-12-22: wsfulton
- C++11 support for new versions of erase and insert in the STL containers.
-
- The erase and insert methods in the containers use const_iterator instead
- of iterator in C++11. There are times when the methods wrapped must match
- the parameters exactly. Specifically when full type information for
- template types is missing or SWIG fails to look up the type correctly,
- for example:
-
- %include <std_vector.i>
- typedef float Real;
- %template(RealVector) std::vector<Real>;
-
- SWIG does not find std::vector<Real>::iterator because %template using
- typedefs does not always work and so SWIG doesn't know if the type is
- copyable and so uses SwigValueWrapper<iterator> which does
- not support conversion to another type (const_iterator). This resulted
- in compilation errors when using the C++11 version of the containers.
-
- Closes #73
-
-2013-10-17: wsfulton
- [R] Fix SF #1340 - Visual Studio compile error in C++ wrappers due to #include <exception>
- within extern "C" block.
-
-2013-10-17: wsfulton
- [Python] Fix SF #1345 - Missing #include <stddef.h> for offsetof when using -builtin.
-
-2013-10-12: wsfulton
- [Lua] Apply #92 - missing return statements for SWIG_Lua_add_namespace_details()
- and SWIG_Lua_namespace_register().
-
-Version 2.0.11 (15 Sep 2013)
-============================
-
-2013-09-15: wsfulton
- [R] Fix attempt to free a non-heap object in OUTPUT typemaps for:
- unsigned short *OUTPUT
- unsigned long *OUTPUT
- signed long long *OUTPUT
- char *OUTPUT
- signed char*OUTPUT
- unsigned char*OUTPUT
-
-2013-09-12: wsfulton
- [Lua] Pull Git patch #62.
- 1) Static members and static functions inside class can be accessed as
- ModuleName.ClassName.FunctionName (MemberName respectively). Old way such as
- ModuleName.ClassName_FunctionName still works.
- 2) Same goes for enums inside classes: ModuleName.ClassName.EnumValue1 etc.
-
-2013-09-12: wsfulton
- [UTL] Infinity is now by default an acceptable value for type 'float'. This fix makes
- the handling of type 'float' and 'double' the same. The implementation requires the
- C99 isfinite() macro, or otherwise some platform dependent equivalents, to be available.
-
- Users requiring the old behaviour of not accepting infinity, can define a 'check' typemap
- wherever a float is used, such as:
-
- %typemap(check,fragment="<float.h>") float, const float & %{
- if ($1 < -FLT_MAX || $1 > FLT_MAX) {
- SWIG_exception_fail(SWIG_TypeError, "Overflow in type float");
- }
- %}
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2013-08-30: wsfulton
- [Lua] Pull Git patch #81: Include Lua error locus in SWIG error messages.
- This is standard information in Lua error messages, and makes it much
- easier to find bugs.
-
-2013-08-29: wsfulton
- Pull Git patch #75: Handle UTF-8 files with BOM at beginning of file. Was giving an
- 'Illegal token' syntax error.
-
-2013-08-29: wsfulton
- [C#] Pull Git patch #77: Allow exporting std::map using non-default comparison function.
-
-2013-08-28: wsfulton
- [Python] %implicitconv is improved for overloaded functions. Like in C++, the methods
- with the actual types are considered before trying implicit conversions. Example:
-
- %implicitconv A;
- struct A {
- A(int i);
- };
- class CCC {
- public:
- int xx(int i) { return 11; }
- int xx(const A& i) { return 22; }
- };
-
- The following python code:
-
- CCC().xx(-1)
-
- will now return 11 instead of 22 - the implicit conversion is not done.
-
-2013-08-23: olly
- [Python] Fix clang++ warning in generated wrapper code.
-
-2013-08-16: wsfulton
- [Python] %implicitconv will now accept None where the implicit conversion takes a C/C++ pointer.
- Problem highlighted by Bo Peng. Closes SF patch #230.
-
-2013-08-07: wsfulton
- [Python] SF Patch #326 from Kris Thielemans - Remove SwigPyObject_print and SwigPyObject_str and
- make the generated wrapper use the default python implementations, which will fall back to repr
- (for -builtin option).
-
- Advantages:
- - it avoids the swig user having to jump through hoops to get print to work as expected when
- redefining repr/str slots.
- - typing the name of a variable on the python prompt now prints the result of a (possibly redefined)
- repr, without the swig user having to do any extra work.
- - when redefining repr, the swig user doesn't necessarily have to redefine str as it will call the
- redefined repr
- - the behaviour is exactly the same as without the -builtin option while requiring no extra work
- by the user (aside from adding the %feature("python:slot...) statements of course)
-
- Disadvantage:
- - default str() will give different (but clearer?) output on swigged classes
-
-2013-07-30: wsfulton
- [Python, Ruby] Fix #64 #65: Missing code in std::multimap wrappers. Previously an instantiation
- of a std::map was erroneously required in addition to an instantiation of std::multimap with the
- same template parameters to prevent compilation errors for the wrappers of a std::multimap.
-
-2013-07-14: joequant
- [R] Change types file to allow for SEXP return values
-
-2013-07-05: wsfulton
- [Python] Add %pythonbegin directive which works like %pythoncode, except the specified code is
- added at the beginning of the generated .py file. This is primarily needed for importing from
- __future__ statements required to be at the very beginning of the file. Example:
-
- %pythonbegin %{
- from __future__ import print_function
- print("Loading", "Whizz", "Bang", sep=' ... ')
- %}
-
-2013-07-01: wsfulton
- [Python] Apply SF patch #340 - Uninitialized variable fix in SWIG_Python_NonDynamicSetAttr
- when using -builtin.
-
-2013-07-01: wsfulton
- [Python, Ruby, Ocaml] Apply SF patch #341 - fix a const_cast in generated code that was generating
- a <:: digraph when using the unary scope operator (::) (global scope) in a template type.
-
-2013-07-01: wsfulton
- [Python] Add SF patch #342 from Christian Delbaere to fix some director classes crashing on
- object deletion when using -builtin. Fixes SF bug #1301.
-
-2013-06-11: wsfulton
- [Python] Add SWIG_PYTHON_INTERPRETER_NO_DEBUG macro which can be defined to use the Release version
- of the Python interpreter in Debug builds of the wrappers. The Visual Studio .dsp example
- files have been modified to use this so that Debug builds will now work without having
- to install or build a Debug build of the interpreter.
-
-2013-06-07: wsfulton
- [Ruby] Git issue #52. Fix regression with missing rb_complex_new function for Ruby
- versions prior to 1.9 using std::complex wrappers if just using std::complex as an output type.
- Also fix the Complex helper functions external visibility (to static by default).
-
-2013-06-04: olly
- [PHP] Fix SWIG_ZTS_ConvertResourcePtr() not to dereference NULL
- if the type lookup fails.
-
-Version 2.0.10 (27 May 2013)
-============================
-
-2013-05-25: wsfulton
- [Python] Fix Python 3 inconsistency when negative numbers are passed
- where a parameter expects an unsigned C type. An OverFlow error is
- now consistently thrown instead of a TypeError.
-
-2013-05-25: Artem Serebriyskiy
- SVN Patch ticket #338 - fixes to %attribute macros for template usage
- with %arg.
-
-2013-05-19: wsfulton
- Fix ccache-swig internal error bug due to premature file cleanup.
-
- Fixes SF bug 1319 which shows up as a failure in the ccache tests on
- Debian 64 bit Wheezy, possibly because ENABLE_ZLIB is defined.
-
- This is a corner case which will be hit when the maximum number of files
- in the cache is set to be quite low (-F option), resulting in a cache miss.
-
-2013-05-09: kwwette
- [Octave] Fix bugs in Octave module loading:
- - fix a memory leak in setting of global variables
- - install functions only once, to speed up module loads
-
-2013-04-28: gjanssens
- [Guile] Updates in guile module:
- - Add support for guile 2.0
- - Drop support for guile 1.6
- - Drop support for generating wrappers using guile's gh interface.
- All generated wrappers will use the scm interface from now on.
- - Deprecate -gh and -scm options. They are no longer needed.
- A warning will be issued when these options are still used.
- - Fix all tests and examples to have a successful travis test
-
-2013-04-18: wsfulton
- Apply Patch #36 from Jesus Lopez to add support for $descriptor() special variable macro expansion
- in fragments. For example:
-
- %fragment("nameDescriptor", "header")
- %{
- static const char *nameDescriptor = "$descriptor(Name)";
- %}
-
- which will generate into the wrapper if the fragment is used:
-
- static const char *nameDescriptor = "SWIGTYPE_Name";
-
-2013-04-18: wsfulton
- Fix SF Bug #428 - Syntax error when preprocessor macros are defined inside of enum lists, such as:
-
- typedef enum {
- eZero = 0
- #define ONE 1
- } EFoo;
-
- The macros are silently ignored.
-
-2013-04-17: wsfulton
- [C#] Pull patch #34 from BrantKyser to fix smart pointers in conjunction with directors.
-
-2013-04-15: kwwette
- [Octave] Fix bugs in output of cleanup code.
- - Cleanup code is now written also after the "fail:" label, so it will be called if
- a SWIG_exception is raised by the wrapping function, consistent with other modules.
- - Octave module now also recognises the "$cleanup" special variable, if needed.
-
-2013-04-08: kwwette
- Add -MP option to SWIG for generating phony targets for all dependencies.
- - Prevents make from complaining if header files have been deleted before
- the dependency file has been updated.
- - Modelled on similar option in GCC.
-
-2013-04-09: olly
- [PHP] Add missing directorin typemap for char* and char[] which
- fixes director_string testcase failure.
-
-2013-04-05: wsfulton
- [Ruby] SF Bug #1292 - Runtime fixes for Proc changes in ruby-1.9 when using STL
- wrappers that override the default predicate, such as:
-
- %template(Map) std::map<swig::LANGUAGE_OBJ, swig::LANGUAGE_OBJ, swig::BinaryPredicate<> >;
-
-2013-04-05: wsfulton
- [Ruby] SF Bug #1159 - Correctly check rb_respond_to call return values to fix some
- further 1.9 problems with functors and use of Complex wrappers.
-
-2013-04-02: wsfulton
- [Ruby] Runtime fixes for std::complex wrappers for ruby-1.9 - new native Ruby complex numbers are used.
-
-2013-03-30: wsfulton
- [Ruby] Fix seg fault when using STL containers of generic Ruby types, GC_VALUE or LANGUAGE_OBJECT,
- on exit of the Ruby interpreter. More frequently observed in ruby-1.9.
-
-2013-03-29: wsfulton
- [Ruby] Fix delete_if (reject!) for the STL container wrappers which previously would
- sometimes seg fault or not work.
-
-2013-03-25: wsfulton
- [Python] Fix some undefined behaviour deleting slices in the STL containers.
-
-2013-03-19: wsfulton
- [C#, Java, D] Fix seg fault in SWIG using directors when class and virtual method names are
- the same except being in different namespaces when the %nspace feature is not being used.
-
-2013-02-19: kwwette
- Fix bug in SWIG's handling of qualified (e.g. const) variables of array type. Given the typedef
- a(7).q(volatile).double myarray // typedef volatile double[7] myarray;
- the type
- q(const).myarray // const myarray
- becomes
- a(7).q(const volatile).double // const volatile double[7]
- Previously, SwigType_typedef_resolve() produces the type
- q(const).a(7).q(volatile).double // non-sensical type
- which would never match %typemap declarations, whose types were parsed correctly.
- Add typemap_array_qualifiers.i to the test suite which checks for the correct behaviour.
-
-2013-02-18: wsfulton
- Deprecate typedef names used as constructor and destructor names in %extend. The real
- class/struct name should be used.
-
- typedef struct tagEStruct {
- int ivar;
- } EStruct;
-
- %extend tagEStruct {
- EStruct() // illegal name, should be tagEStruct()
- {
- EStruct *s = new EStruct();
- s->ivar = ivar0;
- return s;
- }
- ~EStruct() // illegal name, should be ~tagEStruct()
- {
- delete $self;
- }
- }
-
- For now these trigger a warning:
-
- extend_constructor_destructor.i:107: Warning 522: Use of an illegal constructor name 'EStruct' in
- %extend is deprecated, the constructor name should be 'tagEStruct'.
- extend_constructor_destructor.i:111: Warning 523: Use of an illegal destructor name 'EStruct' in
- %extend is deprecated, the destructor name should be 'tagEStruct'.
-
- These %extend destructor and constructor names were valid up to swig-2.0.4, however swig-2.0.5 ignored
- them altogether for C code as reported in SF bug #1306. The old behaviour of using them has been
- restored for now, but is officially deprecated. This does not apply to anonymously defined typedef
- classes/structs such as:
-
- typedef struct {...} X;
-
-2013-02-17: kwwette
- When generating functions provided by %extend, use "(void)" for no-argument functions
- instead of "()". This prevents warnings when compiling with "gcc -Wstrict-prototypes".
-
-2013-02-17: kwwette
- [Octave] Minor fix to autodoc generation: get the right type for functions returning structs.
-
-2013-02-15: wsfulton
- Deprecate typedef names used in %extend that are not the real class/struct name. For example:
-
- typedef struct StructBName {
- int myint;
- } StructB;
-
- %extend StructB {
- void method() {}
- }
-
- will now trigger a warning:
-
- swig_extend.i:19: Warning 326: Deprecated %extend name used - the struct name StructBName
- should be used instead of the typedef name StructB.
-
- This is only partially working anyway (the %extend only worked if placed after the class
- definition).
-
-2013-02-09: wsfulton
- [CFFI] Apply patch #22 - Fix missing package before &body
-
-2013-01-29: wsfulton
- [Java] Ensure 'javapackage' typemap is used as it stopped working from version 2.0.5.
-
-2013-01-28: wsfulton
- [Python] Apply patch SF #334 - Fix default value conversions "TRUE"->True, "FALSE"->False.
-
-2013-01-28: wsfulton
- [Java] Apply patch SF #335 - Truly ignore constructors in directors with %ignore.
-
-2013-01-18: Brant Kyser
- [Java] Patch #15 - Allow the use of the nspace feature without the -package commandline option.
- This works as long and the new jniclasspackage pragma is used to place the JNI intermediate class
- into a package and the nspace feature is used to place all exposed types into a package.
-
-2013-01-15: wsfulton
- Fix Visual Studio examples to work when SWIG is unzipped into a directory containing spaces.
-
-2013-01-15: wsfulton
- [C#] Fix cstype typemap lookup for member variables so that a fully qualified variable name
- matches. For example:
- %typemap(cstype) bool MVar::mvar "MyBool"
- struct MVar {
- bool mvar;
- };
-
-2013-01-11: Brant Kyser
- [Java, C#, D] SF Bug #1299 - Fix generated names for when %nspace is used on
- classes with the same name in two different namespaces.
-
-2013-01-11: Vladimir Kalinin
- [C#] Add support for csdirectorin 'pre', 'post' and 'terminator' attributes.
-
-2013-01-08: olly
- [PHP] Fix to work with a ZTS build of PHP (broken in 2.0.7).
-
-2013-01-07: olly
- Fix bashism in configure, introduced in 2.0.9.
-
-2013-01-06: wsfulton
- Pull patch #4 from ptomulik to fix SF Bug #1296 - Fix incorrect warning for virtual destructors
- in templates, such as:
- Warning 521: Illegal destructor name B< A >::~B(). Ignored.
-
-2013-01-05: wsfulton
- [Python] Pull patch #3 from ptomulik to fix SF Bug #1295 - standard exceptions as
- classes using the SWIG_STD_EXCEPTIONS_AS_CLASSES macro.
-
-2013-01-04: wsfulton
- [Java] Pull patch #2 from BrantKyser to fix SF Bug #1283 - fix smart pointers in conjuction
- with directors.
-
-2013-01-03: wsfulton
- [Java] Pull patch #1 from BrantKyser to fix SF Bug #1278 - fix directors and nspace feature when
- multilevel namespaces are used.
-
-Version 2.0.9 (16 December 2012)
-================================
-
-2012-12-16: wsfulton
- Fix garbage line number / empty file name reporting for some missing
- '}' or ')' error messages.
-
-2012-12-15: kkaempf
- [Ruby] Apply patch 3530444, Class#methods and Class#constants returns array of
- symbols in Ruby 1.9+
-
-2012-12-14: kkaempf
- [Ruby] Apply patch 3530439 and finally replace all occurrences of the STR2CSTR() macro
- with StringValuePtr(). STR2CSTR was deprecated since years and got removed in Ruby 1.9
-
-2012-12-14: kkaempf
- [Ruby] Applied patches #3530442 and 3530443 to adapt compile and runtime include
- paths to match Ruby 1.9+
-
-2012-12-14: wsfulton
- [CFFI] Fix #3161614 - Some string constants are incorrect
-
-2012-12-13: wsfulton
- [CFFI] Fix #3529690 - Fix incorrect constant names.
-
-2012-12-12: drjoe
- [R] add fix to finalizer that was missed earlier
-
-2012-12-11: wsfulton
- [Python] Apply patch #3590522 - fully qualified package paths for Python 3 even if a module is in the
- same package.
-
-2012-12-08: wsfulton
- [Python] Bug #3563647 - PyInt_FromSize_t unavailable prior to Python 2.5 for unsigned int types.
-
-2012-12-08: wsfulton
- [Perl] Fix bug #3571361 - C++ comment in C wrappers.
-
-2012-12-07: wsfulton
- [C#] Apply patch #3571029 which adds missing director support for const unsigned long long &.
-
-2012-11-28: kwwette
- [Octave] Simplified module loading: now just the syntax
- $ example;
- is accepted, which loads functions globally but constants and variables relative to the current scope.
- This make module loading behaviour reliably consistent, and reduces problems when loading modules which
- depend on other modules which may not have been previously loaded.
-
-2012-11-27: wsfulton
- [cffi] Fix junk output when wrapping single character literal constants.
-
-2012-11-17: wsfulton
- [Tcl, Modula3] Add missing support for -outdir.
-
-2012-11-17: wsfulton
- Fix segfaults when using filename paths greater than 1024 characters in length.
-
-2012-11-14: wsfulton
- [ccache-swig] Apply patch #3586392 from Frederik Deweerdt to fix some error cases - incorrectly using
- memory after it has been deleted.
-
-2012-11-09: vzeitlin
- [Python] Fix overflow when passing values greater than LONG_MAX from Python 3 for parameters with unsigned long C type.
-
-2012-11-09: wsfulton
- Fix some feature matching issues for implicit destructors and implicit constructors and implicit
- copy constructors added with %copyctor. Previously a feature for these had to be fully qualified
- in order to match. Now the following will also match:
-
- %feature("xyz") ~XXX();
- struct XXX {};
-
-2012-11-09: wsfulton
- Further consistency in named output typemap lookups for implicit constructors and destructors and
- implicit copy constructors added with %copyctor. Previously only the fully qualified name was being
- used, now the unqualified name will also be used. For example, previously:
-
- example.i:38: Searching for a suitable 'out' typemap for: void Space::More::~More
- Looking for: void Space::More::~More
- Looking for: void
-
- Now the unqualified name is also used:
-
- example.i:38: Searching for a suitable 'out' typemap for: void Space::More::~More
- Looking for: void Space::More::~More
- Looking for: void ~More
- Looking for: void
-
-2012-11-02: wsfulton
- Fix some subtle named output typemap lookup misses, the fully qualified name was not always being
- used for variables, for example:
-
- struct Glob {
- int MyVar;
- };
-
- Previously the search rules (as shown by -debug-tmsearch) for the getter wrapper were:
-
- example.i:44: Searching for a suitable 'out' typemap for: int MyVar
- Looking for: int MyVar
- Looking for: int
-
- Now the scope is named correctly:
-
- example.i:44: Searching for a suitable 'out' typemap for: int Glob::MyVar
- Looking for: int Glob::MyVar
- Looking for: int MyVar
- Looking for: int
-
-2012-10-26: wsfulton
- Fix director typemap searching so that a typemap specified with a name will be correctly matched. Previously
- the name was ignored during the typemap search. Applies to the following list of typemaps:
- directorout, csdirectorout, cstype, imtype, ctype, ddirectorout, dtype, gotype, jtype, jni, javadirectorout.
-
-2012-10-11: wsfulton
- Most of the special variables available for use in %exception are now also available for expansion in
- %extend blocks. These are: $name $symname $overname $decl $fulldecl $parentclassname $parentclasssymname, see docs
- on "Class extension" in SWIGPlus.html. Patch based on submission from Kris Thielemans.
-
-2012-10-10: wsfulton
- Additional new special variables in %exception are expanded as follows:
- $parentclassname - The parent class name (if any) for a method.
- $parentclasssymname - The target language parent class name (if any) for a method.
-
-2012-10-08: iant
- [Go] Generating Go code now requires using the -intgosize option to
- indicate the size of the 'int' type in Go. This is because the
- size of the type is changing from Go 1.0 to Go 1.1 for x86_64.
-
-2012-09-14: wsfulton
- Add new warning if the empty template instantiation is used as a base class, for example:
-
- template <typename T> class Base {};
- %template() Base<int>;
- class Derived : public Base<int> {};
-
- gives the following warning instead of silently ignoring the base:
-
- cpp_inherit.i:52: Warning 401: Base class 'Base< int >' has no name as it is an empty template instantiated with '%template()'. Ignored.
- cpp_inherit.i:51: Warning 401: The %template directive must be written before 'Base< int >' is used as a base class and be declared with a name.
-
-
-2012-09-11: wsfulton
- [Java] Fix #3535304 - Direct use of a weak global reference in directors
- sometimes causing seg faults especially on Android.
-
-2012-09-06: wsfulton
- [Java] Fix (char *STRING, size_t LENGTH) typemaps to accept NULL string.
-
-2012-08-26: drjoe
- [R] make ExternalReference slot ref to contain reference
-
-2012-08-26: drjoe
- [R] fix Examples/Makefile to use C in $(CC) rather than $(CXX)
-
-Version 2.0.8 (20 August 2012)
-==============================
-
-2012-08-15: wsfulton
- [Perl] Add size_type, value_type, const_reference to the STL containers.
-
-2012-08-15: wsfulton
- [Python] Add discard and add methods to std::set wrappers so that pyabc.i can be used ensuring
- MutableSet is a valid abstract base class for std::set. As reported by Alexey Sokolov.
- Similarly for std::multiset.
-
-2012-08-15: wsfulton
- [Python] Fix #3541744 - Missing PyInt_FromSize_t calls for Python 3.
-
-2012-08-13: wsfulton
- [Java] Patch from David Baum to add the assumeoverride feature for Java directors to
- improve performance when all overridden methods can be assumed to be overridden.
-
-2012-08-05: wsfulton
- [Python] #3530021 Fix unused variable warning.
-
-2012-08-05: wsfulton
- [C#] Fix #3536360 - Invalid code sometimes being generated for director methods
- with many arguments.
-
-2012-08-05: wsfulton
- [Perl] #3545877 - Don't undefine bool if defined by C99 stdbool.h - problem using
- Perl 5.16 and later.
-
-2012-08-04: wsfulton
- Remove incorrect warning (314) about target language keywords which were triggered
- by using declarations and using directives. For example 'string' is a keyword in C#:
- namespace std { class string; }
- using std::string;
-
-2012-07-21: wsfulton
- Fix display of pointers in various places on 64 bit systems - only 32 bits were being shown.
-
-2012-07-21: wsfulton
- Fix gdb debugger functions 'swigprint' and 'locswigprint' to display to the gdb output window
- rather than stdout. This fixes display problems in gdbtui and the ensures the output
- appears where expected in other gdb based debuggers such as Eclipse CDT.
-
-2012-07-20: kwwette
- [Octave] segfault-on-exit prevention hack now preserves exit status, and uses C99 _Exit().
-
-2012-07-02: wsfulton
- Fix Debian bug http://bugs.debian.org/672035, typemap copy failure - regression introduced
- in swig-2.0.5:
- %include<stl.i>
- using std::pair;
- %template(StrPair) pair<std::string, std::string>;
-
-2012-07-02: wsfulton
- Fix using declarations combined with using directives with forward class declarations so that
- types are correctly found in scope for templates. Example:
-
- namespace Outer2 {
- namespace Space2 {
- template<typename T> class Thing2;
- }
- }
- using namespace Outer2;
- using Space2::Thing2;
- template<typename T> class Thing2 {};
- // STILL BROKEN void useit2(Thing2<int> t) {}
- void useit2a(Outer2::Space2::Thing2<int> t) {}
- void useit2b(::Outer2::Space2::Thing2<int> t) {}
- void useit2c(Space2::Thing2<int> t) {}
- namespace Outer2 {
- void useit2d(Space2::Thing2<int> t) {}
- }
-
- %template(Thing2Int) Thing2<int>;
-
-
-2012-06-30: wsfulton
- Fix template namespace problems for symbols declared with a forward class declarations, such as:
-
- namespace Space1 {
- namespace Space2 {
- template<typename T> struct YYY;
- }
- template<typename T> struct Space2::YYY {
- T yyy(T h) {
- return h;
- }
- };
- void testYYY1(Space1::Space2::YYY<int> yy) {}
- void testYYY2(Space2::YYY<int> yy) {}
- void testYYY3(::Space1::Space2::YYY<int> yy) {}
- }
-
- %template(YYYInt) Space1::Space2::YYY<int>;
-
-2012-06-30: wsfulton
- Fix namespace problems for symbols declared with a forward class declarations, such as:
-
- namespace Space1 {
- namespace Space2 {
- struct XXX;
- struct YYY;
- }
-
- struct Space2::YYY {};
- struct Space1::Space2::XXX {};
-
- void testXXX2(Space2::XXX xx) {}
- void testYYY2(Space2::YYY yy) {}
- }
-
- where xx and yy were not recognised as the proxy classes XXX and YYY.
-
-2012-06-30: wsfulton
- Fix using declarations combined with using directives with forward class declarations so that
- types are correctly found in scope.
-
- namespace Outer2 {
- namespace Space2 {
- class Thing2;
- }
- }
- using namespace Outer2;
- using Space2::Thing2;
- class Thing2 {};
- // None of the methods below correctly used the Thing2 proxy class
- void useit2(Thing2 t) {}
- void useit2a(Outer2::Space2::Thing2 t) {}
- void useit2b(::Outer2::Space2::Thing2 t) {}
- void useit2c(Space2::Thing2 t) {}
- namespace Outer2 {
- void useit2d(Space2::Thing2 t) {}
- }
-
-2012-06-25: wsfulton
- Fix using declarations combined with using directives so that types are correctly found in scope.
- Example:
-
- namespace Outer2 {
- namespace Space2 {
- class Thing2 {};
- }
- }
- using namespace Outer2; // using directive
- using Space2::Thing2; // using declaration
- void useit2(Thing2 t) {}
-
- Similarly for templated classes.
-
-2012-05-29: wsfulton
- Fix #3529601 - seg fault when a protected method has the "director"
- feature but the parent class does not. Also fix similar problems with
- the allprotected feature.
-
-2012-05-28: wsfulton
- Fix seg fault when attempting to warn about an illegal destructor - #3530055, 3530078 and #3530118.
-
-Version 2.0.7 (26 May 2012)
-===========================
-2012-05-26: wsfulton
- std::string typemap modifications so they can be used with %apply for other string
- classes.
-
-2012-05-25: wsfulton
- [Lua] Fixes for -external-runtime to work again.
-
-2012-05-22: szager
- [python] Disambiguate SWIG_From_unsigned_SS_int and SWIG_From_unsigned_SS_long.
-
-2012-05-18: olly
- [PHP] Fix getters for template members. (SF#3428833, SF#3528035)
-
-2012-05-14: wsfulton
- Fix some language's std::map wrappers to recognise difference_type, size_type, key_type
- and mapped_type.
-
-2012-05-14: kwwette (signed off by xavier98)
- [Octave] Prevent Octave from seg-faulting at exit when SWIG
- modules are loaded, due to bugs in Octave's cleanup code:
- * Wrapping functions now declared with Octave DEFUN_DLD macro,
- and loaded through Octave's dynamic module loader
- * Global variables of swigref type are now assigned a new()
- copy of the swigref class, to prevent double-free errors
- * SWIG module at-exit cleanup function now created in Octave
- through eval(), so not dependent on loaded .oct library
- * For Octave versions 3.1.* to 3.3.*, register C-level at-exit
- function which terminates Octave immediately (with correct
- status code) without performing memory cleanup. This function
- can be controlled with macros in Lib/octave/octruntime.swg
-
- [Octave] New syntax for determing whether SWIG module should be
- loaded globally or non-globally. To load module "example" globally,
- type the module name
- $ example;
- as before; to load module non-globally, assign it to a variable:
- $ example = example;
- or
- $ ex = example;
- for a shorter (local) module name. -global/-noglobal command-line
- options and module command line are deprecated. Added usage info
- to module, so typing
- $ help example
- or incorrect usage should display proper usage, with examples.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2012-05-12: olly
- [PHP] Fix memory leak in code generated for a callback. Patch from
- SF bug #3510806.
-
-2012-05-12: olly
- [PHP] Avoid using zend_error_noreturn() as it doesn't work with all
- builds of PHP (SF bug #3166423). Instead we now wrap it in a
- SWIG_FAIL() function which we annotate as "noreturn" for GCC to
- avoids warnings. This also reduces the size of the compiled
- wrapper (e.g. the stripped size is reduced by 6% for Xapian's PHP
- bindings).
-
-2012-05-11: wsfulton
- [Java] SF patch #3522855 Fix unintended uninitialised memory access in OUTPUT typemaps.
-
-2012-05-11: wsfulton
- [Java] SF patch #3522674 Fix possible uninitialised memory access in char **STRING_OUT
- typemap.
-
-2012-05-11: wsfulton
- [Java] SF patch #3522611 Fix uninitialised size regression in char **STRING_ARRAY
- introduced in swig-2.0.6.
-
-2012-05-11: wsfulton
- SF bug #3525050 - Fix regression introduced in swig-2.0.5 whereby defining one typemap
- method such as an 'out' typemap may hide another typemap method such as an 'in' typemap -
- only occurs when the type is a template type where the template parameters are the same
- via a typedef.
-
-2012-05-10: olly
- [PHP] Fix the constant typemaps for SWIGTYPE, etc - previously
- these used the wrong name for renamed constants. Add
- autodoc_runme.php to the testsuite as a regression test for this.
-
-2012-05-02: ianlancetaylor
- [Go] Remove compatibility support for gccgo 4.6. Using
- SWIG with gccgo will now require gccgo 4.7. Using SWIG
- with the more commonly used gc compiler is unaffected.
-
-2012-05-01: wsfulton
- Fix generated code for C forward enum declarations in some languages.
-
-Version 2.0.6 (30 April 2012)
-=============================
-
-2012-04-25: wsfulton
- [Lua] Fix uninitialised variable in SWIGTYPE **OUTPUT typemaps as reported by Jim Anderson.
-
-2012-04-28: wsfulton
- [Python] Fix compilation errors when wrapping STL containers on Mac OS X and possibly other systems.
-
-2012-04-28: wsfulton
- [Java] Patch 3521811 from Leo Davis - char **STRING_ARRAY typemaps fixed to handle
- null pointers.
-
-Version 2.0.5 (19 April 2012)
-=============================
-
-2012-04-14: wsfulton
- [Lua] Apply patch #3517435 from Miles Bader - prefer to use Lua_pushglobaltable
-
-2012-04-14: wsfulton
- [Ruby] Apply patch #3517769 from Robin Stocker to fix compile error on MacRuby using RSTRING_PTR.
-
-2012-04-13: wsfulton
- Apply patch #3511009 from Leif Middelschulte for slightly optimised char * variable wrappers.
-
-2012-04-13: wsfulton
- [Lua] Apply #3219676 from Shane Liesegang which adds:
- - support for %factory
- - a __tostring method
- - a __disown method
-
-2012-04-13: wsfulton
- [Xml] Apply #3513569 which adds a catchlist to the xml output.
-
-2012-04-05: olly
- [Lua] Add support for Lua 5.2 (patch SF#3514593 from Miles Bader)
-
-2012-03-26: xavier98
- [octave] Apply patch #3425993 from jgillis: add extra logic to the octave_swig_type::dims(void) method: it checks if the user has defined a __dims__ method and uses this in stead of returning (1,1)
- [octave] Apply patch #3424833 from jgillis: make is_object return true for swig types
-
-2012-03-24: wsfulton
- [D] Apply #3502431 to fix duplicate symbols in multiple modules.
-
-2012-03-21: wsfulton
- Fix #3494791 - %$isglobal for %rename matching.
-
-2012-03-20: wsfulton
- Fix #3487706 and #3391906 - missing stddef.h include for ptrdiff_t when using %import
- for STL containers and compiling with g++-4.6. An include of stddef.h is now only
- generated when SWIG generates STL helper templates which require ptrdiff_t. If you
- were previously relying on "#include <stddef.h>" always being generated when using a
- %include of an STL header, you may now need to add this in manually.
-
-2012-03-16: wsfulton
- Apply patch #3392264 from Sebastien Bine to parse (unsigned) long long types in enum value assignment.
-
-2012-03-16: wsfulton
- Apply patch #3505530 from Karl Wette to allow custom allocators in STL string classes for the UTL languages.
-
-2012-03-13: wsfulton
- Apply patch #3468362 from Karl Wette to fix %include inside %define.
-
-2012-03-13: wsfulton
- [Python, Ruby, Octave, R] Fix #3475492 - iterating through std::vector wrappers of enumerations.
-
-2012-02-27: xavier98 (patches from Karl Wette)
- [Octave] Use -globals . to load global variables in module namespace
- [Octave] Comment declaration of unimplemented function swig_register_director
- [Octave] Fix OCTAVE_PATH in octave Makefiles
- [Octave] Add support for std::list - fix li_std_containers_int test
- [Octave] Fix imports test
-
-2012-02-16: wsfulton
- [Java] Make generated support functions in arrays_java.i static so that generated code
- from multiple instances of SWIG can be compiled and linked together - problem reported by
- Evan Krause.
-
-2012-01-24: wsfulton
- Fix crash with bad regex - bug #3474250.
-
-2012-01-24: wsfulton
- [Python] Add Python stepped slicing support to the STL wrappers (std::vector, std::list).
- Assigning to a slice, reading a slice and deleting a slice with steps now work.
- For example:
-
- %template(vector_i) std::vector<int>
-
- vi = vector_i(range(10))
- print list(vi)
- vi[1:4:2] = [111, 333]
- print list(vi)
- del vi[3:10:3]
- print list(vi)
- print list(vi[::-1])
-
- gives (same behaviour as native Python sequences such as list):
-
- [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- [0, 111, 2, 333, 4, 5, 6, 7, 8, 9]
- [0, 111, 2, 4, 5, 7, 8]
- [8, 7, 5, 4, 2, 111, 0]
-
-2012-01-23: klickverbot
- [D] Correctly annotate function pointers with C linkage.
- [D] Exception and Error have become blessed names; removed d_exception_name test case.
-
-2012-01-20: wsfulton
- [Python] Fix some indexing bugs in Python STL wrappers when the index is negative, eg:
-
- %template(vector_i) std::vector<int>
-
- iv=vector_i([0,1,2,3,4,5])
- iv[-7:]
-
- now returns [0, 1, 2, 3, 4, 5] instead of [5].
-
- vv[7:9] = [22,33]
-
- now returns [0, 1, 2, 3, 4, 5, 22, 33] instead of "index out range" error.
-
- Also fix some segfaults when replacing ranges, eg when il is a std::list wrapper:
-
- il[0:2] = [11]
-
-2012-01-17: wsfulton
- [Go] Fix forward class declaration within a class when used as a base.
-
-2012-01-07: wsfulton
- [C#] Add support for %nspace when using directors.
-
-2012-01-06: wsfulton
- [Java] Patch #3452560 from Brant Kyser - add support for %nspace when using directors.
-
-2011-12-21: wsfulton
- The 'directorin' typemap now accepts $1, $2 etc expansions instead of having to use workarounds -
- $1_name, $2_name etc.
-
-2011-12-20: wsfulton
- [Java] Add (char *STRING, size_t LENGTH) director typemaps.
-
-2011-12-20: wsfulton
- [C#, Go, Java, D] Add support for the 'directorargout' typemap.
-
-2011-12-20: wsfulton
- [Ocaml, Octave, PHP, Python, Ruby] Correct special variables in 'directorargout' typemap.
- This change will break any 'directorargout' typemaps you may have written. Please change:
- $result to $1
- $input to $result
-
- Also fix the named 'directorargout' DIRECTOROUT typemaps for these languages which didn't
- previously compile and add in $1, $2 etc expansion.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2011-12-10: talby
- [perl5] SWIG_error() now gets decorated with perl source file/line number.
- [perl5] error handling now conforms to public XS api (fixes perl v5.14 issue).
-
-2011-12-10: wsfulton
- [Android/Java] Fix directors to compile on Android.
-
- Added documentation and examples for Android.
-
-2011-12-08: vadz
- Bug fix: Handle methods renamed or ignored in the base class correctly in the derived classes
- (they could be sometimes mysteriously not renamed or ignored there before).
-
-2011-12-03: klickverbot
- [D] Fix exception glue code for newer DMD 2 versions.
- [D] Do not default to 32 bit glue code for DMD anymore.
- [D] Use stdc.config.c_long/c_ulong to represent C long types.
-
-2011-12-01: szager
- [python] Fixed bug 3447426: memory leak in vector.__getitem__.
-
-2011-11-30: wsfulton
- [R] Remove C++ comments from generated C code.
-
-2011-11-27: olly
- [Python] Fix some warnings when compiling generated wrappers with
- certain GCC warning options (Debian bug #650246).
-
-2011-11-28: wsfulton
- Fix #3433541 %typemap(in, numinputs=0) with 10+ arguments.
-
-2011-11-28: olly
- [Perl] Fix warnings when compiling generated wrappers with certain
- GCC warning options (Debian bug #436711).
-
-2011-11-28: olly
- [PHP] Update keyword list to include keywords added in PHP releases up to 5.3.
-
-2011-11-25: wsfulton
- [C#] Provide an easy way to override the default visibility for the proxy class pointer
- constructors and getCPtr() method. The visibility is 'internal' by default and if multiple
- SWIG modules are being used and compiled into different assemblies, then they need to be
- 'public' in order to use the constructor or getCPtr() method from a different assembly.
- Use the following macros to change the visibilities in the proxy and type wrapper class:
-
- SWIG_CSBODY_PROXY(public, public, SWIGTYPE)
- SWIG_CSBODY_TYPEWRAPPER(public, public, public, SWIGTYPE)
-
- [Java] Provide an easy way to override the default visibility for the proxy class pointer
- constructors and getCPtr() method. The visibility is 'protected' by default and if multiple
- SWIG modules are being used and compiled into different packages, then they need to be
- 'public' in order to use the constructor or getCPtr() method from a different package.
- Use the following macros to change the visibilities in the proxy and type wrapper class:
-
- SWIG_JAVABODY_PROXY(public, public, SWIGTYPE)
- SWIG_JAVABODY_TYPEWRAPPER(public, public, public, SWIGTYPE)
-
- The default for Java has changed from public to protected for the proxy classes. Use the
- SWIG_JAVABODY_PROXY macro above to restore to the previous visibilities.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2011-11-22: szager
- [python] Bug 3440044: #ifdef out SWIG_Python_NonDynamicSetAttr if -builtin
- isn't being used, to avoid unnecessary binary incompatibilities between
- python installations.
-
-2011-11-17: wsfulton
- Bug fix: Remove root directory from directory search list in Windows.
-
-2011-11-13: wsfulton
- [Ruby] Apply patch #3421876 from Robin Stocker to fix #3416818 - same class name in
- different namespaces confusion when using multiple modules.
-
-2011-11-11: wsfulton
- Fix pcre-build.sh to work with non-compressed tarballs - problem reported by Adrian Blakely.
-
-2011-11-03: wsfulton
- Expand special variables in typemap warnings, eg:
-
- %typemap(in, warning="1000:Test warning for 'in' typemap for $1_type $1_name") int "..."
-
-2011-11-01: wsfulton
- Fix named output typemaps not being used when the symbol uses a qualifier and contains
- a number, eg:
-
- %typemap(out) double ABC::m1 "..."
-
-2011-10-24: talby
- [perl5] SF bug #3423119 - overload dispatch stack corruption fix. Better, but more research
- is needed on a stable path for tail calls in XS.
-
- Also, fix for large long longs in 32 bit perl.
-
-2011-10-13: xavier98
- [octave] Allow Octave modules to be re-loaded after a "clear all".
-
-2011-09-19: wsfulton
- Fix regression introduced in swig-2.0.1 reported by Teemu Ikonone leading to uncompilable code
- when using typedef and function pointer references, for example:
-
- typedef int FN(const int &a, int b);
- void *typedef_call1(FN *& precallback, FN * postcallback);
-
-2011-09-14: wsfulton
- [Lua] Patch #3408012 from Raman Gopalan - add support for embedded Lua (eLua)
- including options for targeting Lua Tiny RAM (LTR).
-
-2011-09-14: wsfulton
- [C#] Add boost_intrusive_ptr.i library contribution from patch #3401571.
-
-2011-09-13: wsfulton
- Add warnings for badly named destructors, eg:
-
- struct KStruct {
- ~NOT_KStruct() {}
- };
-
- cpp_extend_destructors.i:92: Warning 521: Illegal destructor name ~NOT_KStruct. Ignored.
-
-2011-09-13: wsfulton
- Fix %extend and destructors for templates. The destructor in %extend was not always wrapped,
- for example:
-
- %extend FooT {
- ~FooT() { delete $self; } // was not wrapped as expected
- };
- template<class T> class FooT {};
- %template(FooTi) FooT<int>;
-
-2011-09-13: wsfulton
- Fix special variables such as "$decl" and "$fulldecl" in destructors to include the ~ character.
-
-2011-09-10: talby
- [perl5] SF bug #1481958 - Improve range checking for integer types.
- Enhance li_typemaps_runme.pl
-
-2011-09-08: wsfulton
- Fix %extend on typedef classes in a namespace using the typedef name, for example:
- namespace Space {
- %extend CStruct {
- ...
- }
- typedef struct tagCStruct { ... } CStruct;
- }
-
-2011-08-31: xavier98
- [octave] patches from Karl Wette: improvements to module loading behavior;
- added example of friend operator to operator example; fixed octave panic/crash in 3.0.5;
- documentation improvements
-
-2011-08-30: szager
- [python] Bug 3400486, fix error signalling for built-in constructors.
-
-2011-08-26: wsfulton
- [Go] Fix file/line number display for "gotype" when using typemap debugging options
- -tmsearch and -tmused.
-
-2011-08-26: wsfulton
- [C#, D] Fix %callback which was generating uncompilable code.
-
-2011-08-25: wsfulton
- Fix constructors in named typedef class declarations as reported by Gregory Bronner:
-
- typedef struct A {
- A(){} // Constructor which was not accepted by SWIG
- B(){} // NOT a constructor --illegal, but was accepted by SWIG
- } B;
-
- For C code, the fix now results in the use of 'struct A *' instead of just 'B *' in
- the generated code when wrapping members in A, but ultimately this does not matter, as
- they are the same thing.
-
-2011-08-23: wsfulton
- Fix %newobject when used in conjunction with %feature("ref") as reported by Jan Becker. The
- code from the "ref" feature was not always being generated for the function specified by %newobject.
- Documentation for "ref" and "unref" moved from Python to the C++ chapter.
-
-2011-08-22: szager
- [python] Fixed memory leak with --builtin option (bug 3385089).
-
-2011-08-22: wsfulton
- [Lua] SF patch #3394339 from Torsten Landschoff - new option -nomoduleglobal to disable installing
- the module table into the global namespace. Require call also returns the module table instead
- of a string.
-
-2011-08-09: xavier98
- Fix bug 3387394; Octave patches for 3.4.0 compatibility, etc. (from Karl Wette)
-
-2011-08-04: wsfulton
- Add in $symname expansion for director methods.
-
-2011-07-29: olly
- [PHP] Don't generate "return $r;" in cases where $r hasn't been set.
- This was basically harmless, except it generated a PHP E_NOTICE if
- the calling code had enabled them.
-
-2011-07-26: wsfulton
- Fix scoping of forward class declarations nested within a class (for C++). Previously the symbol
- was incorrectly put into the outer namespace, eg
-
- namespace std {
- template<class Key, class T> struct map {
- class iterator;
- };
- }
-
- iterator was scoped as std::iterator, but now it is correctly std::map<Key, T>::iterator;
-
- Also fixed is %template and template parameters that are a typedef when the template contains
- default template parameters, eg:
-
- namespace Std {
- template<class Key, class T, class C = int> struct Map {
- typedef Key key_type;
- typedef T mapped_type;
- };
- }
- typedef double DOUBLE;
- %template(MM) Std::Map<int, DOUBLE>;
-
- All symbols within Map will be resolved correctly, eg key_type and mapped_type no matter if the
- wrapped code uses Std::Map<int, double> or std::Map<int, DOUBLE> or Std::Map<int, double, int>
-
- Also fixes bug #3378145 - regression introduced in 2.0.4 - %template using traits.
-
-2011-07-20 szager
- [python] Fix closure for tp_call slot.
-
-2011-07-16: wsfulton
- [python] Fix director typemap using PyObject *.
-
-2011-07-13: szager
- [python] SF patch #3365908 - Add all template parameters to map support code in std_map.i
-
-2011-07-13: szager
- [python] Fix for bug 3324753: %rename member variables with -builtin.
-
-2011-07-01: wsfulton
- Fix some scope and symbol lookup problems when template default parameters are being
- used with typedef. For example:
-
- template<typename XX, typename TT = SomeType> struct Foo {
- typedef XX X;
- typedef TT T;
- };
- template<typename TT> struct UsesFoo {
- void x(typename Foo<TT>::T, typename Foo<TT>::X);
- };
-
- Also fixes use of std::vector<int>::size_type for Python as reported by Aubrey Barnard.
-
-2011-06-23: olly
- [PHP] Fix director code to work when PHP is built with ZTS enabled,
- which is the standard configuration on Microsoft Windows.
-
-2011-06-21: mutandiz
- [allegrocl]
- - various small tweaks and bug fixes.
- - Avoid name conflicts between smart pointer wrappers and the wrappers for
- the actual class.
- - Fix default typemaps for C bindings, which were incorrectly attempting to
- call non-existent destructors on user-defined types.
- - New feature, feature:aclmixins, for adding superclass to the foreign class
- wrappers.
- - Improve longlong typemaps.
-
-2011-06-19: wsfulton
- Fix incorrect typemaps being used for a symbol within a templated type, eg:
- A<int>::value_type would incorrectly use a typemap for type A.
-
-2011-06-18: olly
- [Tcl] Fix variable declarations in middle of blocks which isn't
- permitted in C90 (issue probably introduced in 2.0.3 by patch #3224663).
- Reported by Paul Obermeier in SF#3288586.
-
-2011-06-17: wsfulton
- [Java] SF #3312505 - slightly easier to wrap char[] or char[ANY] with a Java byte[]
- using arrays_java.i.
-
-2011-06-13: wsfulton
- [Ruby, Octave] SF #3310528 Autodoc fixes similar to those described below for Python.
-
-2011-06-10: wsfulton
- [Python] Few subtle bugfixes in autodoc documentation generation,
- - Unnamed argument names fix for autodoc levels > 0.
- - Display of template types fixed for autodoc levels > 1.
- - Fix SF #3310528 - display of typedef structs for autodoc levels > 1.
- - Add missing type for self for autodoc levels 1 and 3.
- - autodoc levels 2 and 3 documented.
- - Minor tweaks to autodoc style to conform with PEP8.
-
-2011-05-30: olly
- [PHP] Fix handling of directors when -prefix is used.
-
-2011-05-24: olly
- [PHP] Fix handling of methods of classes with a virtual base class (SF#3124665).
-
-Version 2.0.4 (21 May 2011)
-===========================
-
-2011-05-19: wsfulton
- [Guile] Patch #3191625 fixing overloading of integer types.
-
-2011-05-19: wsfulton
- [Perl] Patch #3260265 fixing overloading of non-primitive types and integers in
- Perl 5.12 and later.
-
-2011-05-19: wsfulton
- [Ruby] Fix %import where one of the imported files %include one of the STL include
- files such as std_vector.i.
-
-2011-05-17: wsfulton
- [Java] Apply #3289851 from Alan Harder to fix memory leak in directors when checking
- for pending exceptions.
-
-2011-05-17: wsfulton
- [Tcl] Apply #3300072 from Christian Delbaere to fix multiple module loading not
- always sharing variables across modules.
-
-2011-05-16: xavier98
- [octave] Fix an incompatibility with never versions of Octave. Case on Octave
- API >= 40 to handle rename of Octave_map to octave_map.
- [octave] Add support for y.__rop__(x) operators when x.__op__(y) doesn't exist.
- [octave] Allow global operators to be defined by SWIG-wrapped functions.
- [octave] Fix several bugs around module namespaces; add -global, -noglobal,
- -globals <name> command line options to the module.
-
-2011-05-14: wsfulton
- %varargs when used with a numeric argument used to create an additional argument
- which was intended to provide a guaranteed sentinel value. This never worked and now
- the additional argument is not generated.
-
-2011-05-13: wsfulton
- [python] Additional fixes for python3.2 support.
-
-2011-05-07: szager
- [python] Fixed PyGetSetDescr for python3.2.
-
-2011-05-05: wsfulton
- [Lua, Python, Tcl] C/C++ prototypes shown in error message when calling an overloaded
- method with incorrect arguments improved to show always show fully qualified name
- and if a const method.
-
- Also fixed other Lua error messages in generated code which weren't consistently
- using the fully qualified C++ name - requested by Gedalia Pasternak.
-
-2011-04-29: szager
- Bug 2635919: Convenience method to convert std::map to a python dict.
-
-2011-04-29: szager
- [Python] Fixed bug 2811549: return non-const iterators from STL
- methods begin(), end(), rbegin(), rend().
-
-2011-04-25: szager
- [Python] Fixed bug 1498929: Access to member fields in map elements
-
-2011-04-23: klickverbot
- [D] nspace: Correctly generate identifiers for base classes when
- not in split proxy mode.
-
-2011-04-13: szager
- Fixed bug 3286333: infinite recursion with mutual 'using namespace' clauses.
-
-2011-04-12: szager
- Fixed bug 1163440: vararg typemaps.
-
-2011-04-12: szager
- Fixed bug #3285386: parse error from 'operator T*&()'. Added operator_pointer_ref
- test case to demonstrate.
-
-2011-04-11: szager
- [Python] Fixed PyVarObject_HEAD_INIT to eliminate VC++ compiler errors about
- static initialization of struct members with pointers.
-
-2011-04-11: wsfulton
- [Tcl] Apply patch #3284326 from Colin McDonald to fix some compiler warnings.
-
-2011-04-11: szager
- [Python] Fixed PyVarObject_HEAD_INIT to eliminate VC++ compiler errors about
- static initialization of struct members with pointers.
-
-2011-04-10: klickverbot
- [D] Fixed wrapping of enums that are type char, for example:
- enum { X = 'X'; } (this was already in 2.0.3 for C# and Java)
-
-2011-04-10: klickverbot
- [D] nspace: Fixed referencing types in the root namespace when
- not in split proxy mode.
-
-2011-04-09: szager
- [Python] Applied patch #1932484: migrate PyCObject to PyCapsule.
-
-2011-04-09: szager
- [Python] Added preprocessor guards for python functions PyUnicode_AsWideChar and
- PySlice_GetIndices, which changed signatures in python3.2.
-
-2011-04-07: wsfulton
- Fix wrapping of const array typedefs which were generating uncompilable code as
- reported by Karl Wette.
-
-2011-04-03: szager
- [Python] Fixed the behavior of %pythonnondynamic to conform to the spec in Lib/pyuserdir.swg.
-
-2011-04-03: szager
- [Python] Merged in the szager-python-builtin branch, adding the -builtin feature
- for python. The -builtin option may provide a significant performance gain
- in python wrappers. For full details and limitations, refer to Doc/Manual/Python.html.
- A small test suite designed to demonstrate the performance gain is in
- Examples/python/performance.
-
-2011-04-01: wsfulton
- Add in missing wrappers for friend functions for some target languages, mostly
- the non-scripting languages like Java and C#.
-
-Version 2.0.3 (29 March 2011)
-=============================
-
-2011-03-29: wsfulton
- [R] Apply patch #3239076 from Marie White fixing strings for R >= 2.7.0
-
-2011-03-29: wsfulton
- [Tcl] Apply patch #3248280 from Christian Delbaere which adds better error messages when
- the incorrect number or type of arguments are passed to overloaded methods.
-
-2011-03-29: wsfulton
- [Tcl] Apply patch #3224663 from Christian Delbaere.
- 1. Fix when function returns a NULL value, a "NULL" command will be created in the Tcl interpreter
- and calling this command will cause a segmentation fault.
-
- 2. Previous implementation searches for class methods using a linear search causing performance issues
- in wrappers for classes with many member functions. The patch adds a method hash table to classes and
- changes method name lookup to use the hash table instead of doing a linear search.
-
-2011-03-26: wsfulton
- [C#, Java] SF bug #3195112 - fix wrapping of enums that are type char, for example:
- enum { X = 'X'; }
-
-2011-03-21: vadz
- Allow setting PCRE_CFLAGS and PCRE_LIBS during configuration to override the values returned by
- pcre-config, e.g. to allow using a static version of PCRE library.
-
-2011-03-17: wsfulton
- [UTL] Add missing headers in generated STL wrappers to fix compilation with gcc-4.6.
-
-2011-03-17: wsfulton
- Fix regression introduced in swig-2.0.2 where filenames with spaces were not found
- when used with %include and %import. Reported by Shane Liesegang.
-
-2011-03-15: wsfulton
- [UTL] Fix overloading when using const char[], problem reported by David Maxwell.
- Similarly for char[ANY] and const char[ANY].
-
-2011-03-15: wsfulton
- [C#] Apply patch #3212624 fixing std::map Keys property.
-
-2011-03-14: olly
- [PHP] Fix handling of overloaded methods/functions where some
- return void and others don't - whether this worked or not depended
- on the order they were encountered in (SF#3208299).
-
-2011-03-13: klickverbot
- [D] Extended support for C++ namespaces (nspace feature).
-
-2011-03-12: olly
- [PHP] Fix sharing of type information between multiple SWIG-wrapped
- modules (SF#3202463).
-
-2011-03-09: wsfulton
- [Python] Fix SF #3194294 - corner case bug when 'NULL' is used as the default value
- for a primitive type parameter in a method declaration.
-
-2011-03-07: olly
- [PHP] Don't use zend_error_noreturn() for cases where the function
- returns void - now this issue can only matter if you have a function
- or method which is directed and returns non-void.
-
-2011-03-06: olly
- [PHP] Add casts to the typemaps for long long and unsigned long
- long to avoid issues when they are used with shorter types via
- %apply.
-
-2011-03-02: wsfulton
- Templated smart pointers overloaded with both const and non const operator-> generated uncompilable
- code when the pointee was a class with either public member variables or static methods.
- Regression in 2.0.x reported as working in 1.3.40 by xantares on swig-user mailing list.
-
-Version 2.0.2 (20 February 2011)
-================================
-
-2011-02-19: wsfulton
- [PHP] Add missing INPUT, OUTPUT and INOUT typemaps in the typemaps.i library
- for primitive reference types as well as signed char * and bool *.
-
-2011-02-19: olly
- [PHP] Address bug in PHP on some platforms/architectures which
- results in zend_error_noreturn() not being available using
- SWIG_ZEND_ERROR_NORETURN which defaults to zend_error_noreturn but
- can be overridden when building the module by passing
- -DSWIG_ZEND_ERROR_NORETURN=zend_error to the compiler. This may
- result in compiler warnings, but should at least allow a module
- to be built on those platforms/architectures (SF#3166423).
-
-2011-02-18: wsfulton
- Fix #3184549 - vararg functions and function overloading when using the -fastdispatch option.
-
-2011-02-18: olly
- [PHP] An overloaded method which can return an object or a
- primitive type no longer causes SWIG to segfault. Reported by Paul
- Colby in SF#3168531.
-
-2011-02-18: olly
- [PHP] Fix invalid erase during iteration of std::map in generated
- director code. Reported by Cory Bennett in SF#3175820.
-
-2011-02-17: wsfulton
- Preprocessing now warns if extra tokens appear after #else and #end.
-
-2011-02-16: wsfulton
- Fix #1653092 Preprocessor does not error out when #elif is missing an expression.
- This and other cases of missing preprocessor expressions now result in an error.
-
-2011-02-14: wsfulton
- [Ocaml] Apply patch #3151788 from Joel Reymont. Brings Ocaml support up to date
- (ver 3.11 and 3.12), including std::string.
-
-2011-02-13: wsfulton
- [Ruby] Apply patch #3176274 from James Masters - typecheck typemap for time_t.
-
-2011-02-13: wsfulton
- Apply patch #3171793 from szager - protected director methods failing when -fvirtual is used.
-
-2011-02-13: wsfulton
- Fix #1927852 - #include directives don't preprocess the file passed to it. The fix is for
- #include with -importall or -includeall, %include and %import, for example:
- #define FILENAME "abc.h"
- %include FILENAME
-
-2011-02-12: wsfulton
- Fix #1940536, overactive preprocessor which was expanding defined(...) outside of #if and #elif
- preprocessor directives.
-
-2011-02-05: wsfulton
- [MzScheme] SF #2942899 Add user supplied documentation to help getting started with MzScheme.
- Update chapter name to MzScheme/Racket accounting for the rename of MzScheme to Racket.
-
-2011-02-05: wsfulton
- [C#] SF #3085906 - Possible fix running test-suite on Mac OS X.
-
-2011-02-05: wsfulton
- SF #3173367 Better information during configure about Boost prerequisite for running
- the test-suite.
-
-2011-02-05: wsfulton
- SF #3127633 Fix infinite loop in recursive typedef resolution.
-
-2011-02-04: wsfulton
- [R] SF #3168676 Fix %rename not working for member variables and methods.
-
-2011-02-04: wsfulton
- [clisp] SF #3148200 Fix segfault parsing nested unions.
-
-2011-02-01: wsfulton
- [C#] Directors - a call to a method being defined in the base class, not
- overridden in a subclass, but again overridden in a class derived from
- the first subclass was not being dispatched correctly to the most derived class.
- See director_alternating.i for an example.
-
-2011-02-01: wsfulton
- [C#, Java] Any 'using' statements in the protected section of a class were previously
- ignored with director protected (dirprot) mode.
-
-2011-01-30: wsfulton
- Fix overloading with const pointer reference (SWIGTYPE *const&) parameters for a
- number of scripting languages.
-
-2011-01-17: wsfulton
- New warning for smart pointers if only some of the classes in the inheritance
- chain are marked as smart pointer, eg, %shared_ptr should be used for all classes
- in an inheritance hierarchy, so this new warning highlights code where this is
- not the case.
-
- example.i:12: Warning 520: Base class 'A' of 'B' is not similarly marked as a smart pointer.
- example.i:16: Warning 520: Derived class 'C' of 'B' is not similarly marked as a smart pointer.
-
-2011-01-14: wsfulton
- Added some missing multi-argument typemaps: (char *STRING, size_t LENGTH) and
- (char *STRING, int LENGTH). Documentation for this updated. Java patch from
- Volker Grabsch.
-
-2011-01-11: iant
- Require Go version 7077 or later.
-
-2010-12-30: klickverbot
- [C#, D, Java] Check for collision of parameter names with target
- language keywords when generating the director glue code.
-
- The situation in which the generated could would previously be
- invalid is illustrated in the new 'director_keywords' test case.
-
-2010-12-23: wsfulton
- [C#] Fix $csinput special variable not being expanded for csvarin typemaps
- when used for global variables. Reported by Vadim Zeitlin.
-
-2010-12-14: wsfulton
- Fix $basemangle expansion in array typemaps. For example if type is int *[3],
- $basemangle expands to _p_int.
-
-2010-12-07: iant
- Check that we are using a sufficiently new version of the
- 6g or 8g Go compiler during configure time. If not, disable Go.
- Minimum version is now 6707.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2010-12-06: wsfulton
- Fix #3127394 - use of network paths on Windows/MSys.
-
-2010-11-18: klickverbot
- [D] Added the D language module.
-
-2010-11-12: vadz
- Fix handling of multiple regex-using %renames attached to the same
- declaration. For example, now
-
- %rename("%(regex:/^Set(.*)/put\\1/)s") "";
- %rename("%(regex:/^Get(.*)/get\\1/)s") "";
-
- works as expected whereas before only the last anonymous rename was
- taken into account.
-
-2010-10-17: drjoe
- [R] Fix failure in overloaded functions which was breaking
- QuantLib-SWIG
-
-2010-10-14: olly
- [PHP] Allow compilation on non-conforming Microsoft C++ compilers
- which don't accept: return function_returning_void();
- Reported by Frank Vanden Berghen on the SWIG mailing list.
-
-2010-10-12: wsfulton
- Fix unary scope operator (::) (global scope) regression introduced in 2.0.0, reported by
- Ben Walker. The mangled symbol names were incorrect, sometimes resulting in types being
- incorrectly treated as opaque types.
-
- Also fixes #2958781 and some other type problems due to better typedef resolution, eg
- std::vector<T *>::value_type didn't resolve to T * when it should have. The mangled type
- was incorrectly SWIGTYPE_std__vectorT_Test_p_std__allocatorT_Test_p_t_t__value_type and now
- it is correctly SWIGTYPE_p_Test.
-
-Version 2.0.1 (4 October 2010)
-==============================
-
-2010-10-03: wsfulton
- Apply patch #3066958 from Mikael Johansson to fix default smart pointer
- handling when the smart pointer contains both a const and non-const operator->.
-
-2010-10-01: wsfulton
- Add -pcreversion option to display PCRE version information.
-
-2010-10-01: olly
- [Ruby] Avoid segfault when a method node has no parentNode
- (SF#3034054).
-
-2010-10-01: olly
- [Python] Allow reinitialisation to work with an embedded Python
- interpreter (patch from Jim Carroll in SF#3075178).
-
-2010-09-28: wsfulton
- [C#] Apply patch from Tomas Dirvanauskas for std::map wrappers to avoid
- throwing exceptions with normal usage of iterators.
-
-2010-09-27: olly
- [Python] Improve error message given when a parameter of the wrong
- type is passed to an overloaded method (SF#3027355).
-
-2010-09-25: wsfulton
- Apply SF patch #3075150 - Java directors using static variables in
- named namespace.
-
-2010-09-24: wsfulton
- More file and line error/warning reporting fixes where SWIG macros
- are used within {} braces (where the preprocessor expands macros),
- for example macros within %inline {...} and %fragment(...) {...}
- and nested structs.
-
-2010-09-18: wsfulton
- More file and line error/warning reporting fixes for various inherited
- class problems.
-
-2010-09-15: wsfulton
- A much improved debugging of SWIG source experience is now available and
- documented in the "Debugging SWIG" section in the Doc/Devel/internals.html
- file, including a swig.dbg support file for the gdb debugger.
-
-2010-09-11: wsfulton
- Fix incorrect line number reporting in errors/warnings when a macro
- definition ends with '/' and it is not the end of a C comment.
-
-2010-09-11: wsfulton
- Fix incorrect line number reporting in errors/warnings after parsing
- macro invocations with parameters given over more than one line.
-
-2010-09-10: wsfulton
- Remove extraneous extra line in preprocessed output after including files
- which would sometimes lead to error/warning messages two lines after the
- end of the file.
-
-2010-09-10: wsfulton
- Fix #2149523 - Incorrect line number reporting in errors after parsing macros
- containing C++ comments.
-
-2010-09-08: olly
- [PHP] Fix handling of OUTPUT typemaps (Patch from Ryan in SF#3058394).
-
-2010-09-03: wsfulton
- Fix erroneous line numbers in error messages for macro expansions, for example,
- the error message now points to instantiation of the macro, ie the last line here:
-
- #define MACRO2(a, b)
-
- #define MACRO1(NAME) MACRO2(NAME,2,3)
-
- MACRO1(abc)
-
-2010-09-02: wsfulton
- Fix line numbers in error and warning messages for preprocessor messages within
- %inline, for example:
-
- %inline %{
- #define FOOBAR 1
- #define FOOBAR "hi"
- %}
-
-2010-09-02: wsfulton
- Fix line numbers in error and warning messages which were cumulatively one
- less than they should have been after parsing each %include/%import - bug
- introduced in swig-1.3.32. Also fix line numbers in error and warning messages
- when new line characters appear between the %include / %import statement and
- the filename.
-
-2010-08-30: wsfulton
- Fix line number and file name reporting for some macro preprocessor warnings.
- The line number of the macro argument has been corrected and the line number
- of the start of the macro instead of one past the end of the macro is used.
- Some examples:
- file.h:11: Error: Illegal macro argument name '..'
- file.h:19: Error: Macro 'DUPLICATE' redefined,
- file.h:15: Error: previous definition of 'DUPLICATE'.
- file.h:25: Error: Variable-length macro argument must be last parameter
- file.h:32: Error: Illegal character in macro argument name
- file.i:37: Error: Macro 'SIT' expects 2 arguments
-
-2010-08-26: wsfulton
- Fix __LINE__ and __FILE__ expansion reported by Camille Gillot. Mostly this
- did not work at all. Also fixes SF #2822822.
-
-2010-08-17: wsfulton
- [Perl] Fix corner case marshalling of doubles - errno was not being correctly
- set before calling strtod - patch from Justin Vallon - SF Bug #3038936.
-
-2010-08-17: wsfulton
- Fix make distclean when some of the more obscure languages are detected by
- configure - fixes from Torsten Landschoff.
-
-2010-07-28: wsfulton
- Restore configuring out of source for the test-suite since it broke in 1.3.37.
- As previously, if running 'make check-test-suite' out of source, it needs to be
- done by invoking configure with a relative path. Invoking configure with an
- absolute path will not work. Running the full 'make check' still needs to be
- done in the source tree.
-
-2010-07-16: wsfulton
- Fix wrapping of function pointers and member function pointers when the function
- returns by reference.
-
-2010-07-13: vadz
- Removed support for the old experimental "rxspencer" encoder and
- "[not]rxsmatch" in %rename (see the 01/16/2006 entry). The new and
- officially supported "regex" encoder and "[not]regexmatch" checks
- should be used instead (see the two previous entries). Please
- replace "%(rxspencer:[pat][subst])s" with "%(regex:/pat/subst/)s"
- when upgrading. Notice that you will also need to replace the back-
- references of form "@1" with the more standard "\\1" and may need to
- adjust your regular expressions syntax as the new regex encoder uses
- Perl-compatible syntax and not (extended) POSIX syntax as the old one.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2010-07-13: vadz
- Add "regexmatch", "regextarget" and "notregexmatch" which can be
- used to apply %rename directives to the declarations matching the
- specified regular expression only. The first two can be used
- interchangeably, both of the %renames below do the same thing:
-
- %rename("$ignore", regexmatch$name="Old$") "";
- %rename("$ignore", regextarget=1) "Old$";
-
- (namely ignore the declarations having "Old" suffix).
-
- "notregexmatch" restricts the match to only the declarations which
- do not match the regular expression, e.g. here is how to rename to
- lower case versions all declarations except those consisting from
- capital letters only:
-
- %rename("$(lowercase)s", notregexmatch$name="^[A-Z]+$") "";
-
-2010-07-13: vadz
- Add the new "regex" encoder that can be used in %rename, e.g.
-
- %rename("regex:/(\\w+)_(.*)/\\2/") "";
-
- to remove any alphabetical prefix from all identifiers. The syntax
- of the regular expressions is Perl-like and PCRE library
- (http://www.pcre.org/) is used to implement this feature but notice
- that backslashes need to be escaped as usual inside C strings.
-
- Original patch from Torsten Landschoff.
-
-2010-07-08: wsfulton
- Fix #3024875 - shared_ptr of classes with non-public destructors. This also fixes
- the "unref" feature when used on classes with non-public destructors.
-
-2010-06-17: ianlancetaylor
- [Go] Add the Go language module.
-
-2010-06-10: wsfulton
- [Lua] Fix SWIG_lua_isnilstring multiply defined when using multiple
- modules and wrapping strings. Patch from 'Number Cruncher'.
-
-2010-06-10: olly
- [PHP] Fix directors to correctly call a method with has a
- different name in PHP to C++ (we were always using the C++ name
- in this case).
-
-2010-06-03: wsfulton
- Fix uncompilable code when %rename results in two enum items
- with the same name. Reported by Vadim Zeitlin.
-
-Version 2.0.0 (2 June 2010)
-===========================
-
-2010-06-02: wsfulton
- [C#] Fix SWIG_STD_VECTOR_ENHANCED macro used in std::vector to work with
- types containing commas, for example:
-
- SWIG_STD_VECTOR_ENHANCED(std::pair< double, std::string >)
-
-2010-06-01: wsfulton
- Add in std_shared_ptr.i for wrapping std::shared_ptr. Requires the %shared_ptr
- macro like in the boost_shared_ptr.i library. std::tr1::shared_ptr can also be
- wrapped if the following macro is defined:
-
- #define SWIG_SHARED_PTR_SUBNAMESPACE tr1
- %include <std_shared_ptr.i>
-
- shared_ptr is also documented in Library.html now.
-
-2010-05-27: wsfulton
- Add the ability for $typemap special variable macros to call other $typemap
- special variable macros, for example:
-
- %typemap(cstype) CC "CC"
- %typemap(cstype) BB "$typemap(cstype, CC)"
- %typemap(cstype) AA "$typemap(cstype, BB)"
- void hah(AA aa);
-
- This also fixes C# std::vector containers of shared_ptr and %shared_ptr.
-
- Also added diagnostics for $typemap with -debug-tmsearch, for example, the
- above displays additional diagnostic lines starting "Containing: ":
-
- example.i:34: Searching for a suitable 'cstype' typemap for: AA aa
- Looking for: AA aa
- Looking for: AA
- Using: %typemap(cstype) AA
- Containing: $typemap(cstype, BB)
- example.i:31: Searching for a suitable 'cstype' typemap for: BB
- Looking for: BB
- Using: %typemap(cstype) BB
- Containing: $typemap(cstype, CC)
- example.i:29: Searching for a suitable 'cstype' typemap for: CC
- Looking for: CC
- Using: %typemap(cstype) CC
-
-2010-05-26: olly
- Fix %attribute2ref not to produce a syntax error if the last
- argument (AccessorMethod) is omitted. Patch from David Piepgras
- in SF#2235756.
-
-2010-05-26: olly
- [PHP] When using %throws or %catches, SWIG-generated PHP5 wrappers
- now throw PHP Exception objects instead of giving a PHP error of
- type E_ERROR.
-
- This change shouldn't cause incompatibility issues, since you can't
- set an error handler for E_ERROR, so previously PHP would just exit
- which also happens for unhandled exceptions. The benefit is you can
- now catch them if you want to.
-
- Fixes SF#2545578 and SF#2955522.
-
-2010-05-25: olly
- [PHP] Add missing directorin typemap for const std::string &.
- Fixes SF#3006404 reported by t-Legiaw.
-
-2010-05-23: wsfulton
- [C#] Fix #2957375 - SWIGStringHelper and SWIGExceptionHelper not always being
- initialized before use in .NET 4 as the classes were not marked beforefieldinit.
- A static constructor has been added to the intermediary class like this:
-
- %pragma(csharp) imclasscode=%{
- static $imclassname() {
- }
- %}
-
- If you had added your own custom static constructor to the intermediary class in
- the same way as above, you will have to modify your approach to use static variable
- initialization or define SWIG_CSHARP_NO_IMCLASS_STATIC_CONSTRUCTOR - See csharphead.swg.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2010-05-23: wsfulton
- Fix #2408232. Improve shared_ptr and intrusive_ptr wrappers for classes in an
- inheritance hierarchy. No special treatment is needed for derived classes.
- The proxy class also no longer needs to be specified, it is automatically
- deduced. The following macros are deprecated:
- SWIG_SHARED_PTR(PROXYCLASS, TYPE)
- SWIG_SHARED_PTR_DERIVED(PROXYCLASS, BASECLASSTYPE, TYPE)
- and have been replaced by
- %shared_ptr(TYPE)
- Similarly for intrusive_ptr wrappers, the following macro is deprecated:
- SWIG_INTRUSIVE_PTR(PROXYCLASS, TYPE)
- SWIG_INTRUSIVE_PTR_DERIVED(PROXYCLASS, BASECLASSTYPE, TYPE)
- and have been replaced by
- %intrusive_ptr(TYPE)
-
-2010-05-21: olly
- [PHP] Stop generating a bogus line of code in certain constructors.
- This was mostly harmless, but caused a PHP notice to be issued, if
- enabled (SF#2985684).
-
-2010-05-18: wsfulton
- [Java] Fix member pointers on 64 bit platforms.
-
-2010-05-14: wsfulton
- Fix wrapping of C++ enum boolean values reported by Torsten Landschoff:
- typedef enum { PLAY = true, STOP = false } play_state;
-
-2010-05-14: olly
- [PHP] Fix wrapping of global variables which was producing
- uncompilable code in some cases.
-
-2010-05-12: drjoe
- [R] Add two more changes from Wil Nolan. Get garbage
- collection to work. Implement newfree
-
-2010-05-09: drjoe
- Fix bug reported by Wil Nolan change creation of string so
- that R 2.7.0+ can use char hashes
-
-2010-05-07: wsfulton
- Apply patch #2955146 from Sergey Satskiy to fix expressions containing divide by
- operator in constructor initialization lists.
-
-2010-05-05: wsfulton
- [R] Memory leak fix handling const std::string & inputs, reported by Will Nolan.
-
-2010-05-01: wsfulton
- Typemap matching enhancement for non-default typemaps. Previously all
- qualifiers were stripped in one step, now they are stripped one at a time
- starting with the left most qualifier. For example, int const*const
- is first stripped to int *const then int *.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2010-04-25: bhy
- [Python] Fix #2985655 - broken constructor renaming.
-
-2010-04-14: wsfulton
- Typemap fragments are now official and documented in Typemaps.html.
-
-2010-04-09: wsfulton
- [Ruby] Fix #2048064 and #2408020.
- Apply Ubuntu patch to fix Ruby and std::vector wrappers with -minherit.
- https://bugs.launchpad.net/ubuntu/+source/swig1.3/+bug/522874
-
-2010-04-09: wsfulton
- [Mzscheme] Apply Ubuntu patch to fix std::map wrappers:
- https://bugs.launchpad.net/ubuntu/+source/swig1.3/+bug/203876
-
-2010-04-09: wsfulton
- [Python] Apply patch #2952374 - fix directors and the -nortti option.
-
-2010-04-09: wsfulton
- [Lua] Fix #2887254 and #2946032 - SWIG_Lua_typename using wrong stack index.
-
-2010-04-03: wsfulton
- [Python] Fix exceptions being thrown with the -threads option based on patch from Arto Vuori.
- Fixes bug #2818499.
-
-2010-04-03: wsfulton
- Fix Makefile targets: distclean and maintainer-clean
-
-2010-04-02: wsfulton
- [Lua] Fix char pointers, wchar_t pointers and char arrays so that nil can be passed as a
- valid value. Bug reported by Gedalia Pasternak.
-
-2010-04-01: wsfulton
- Numerous subtle typemap matching rule fixes when using the default type. The typemap
- matching rules are to take a type and find the best default typemap (SWIGTYPE, SWIGTYPE* etc),
- then look for the next best match by reducing the chosen default type. The type deduction
- now follows C++ class template partial specialization matching rules.
-
- Below are the set of changes made showing the default type deduction
- along with the old reduced type and the new version of the reduced type:
-
- SWIGTYPE const &[ANY]
- new: SWIGTYPE const &[]
- old: SWIGTYPE (&)[ANY]
-
- SWIGTYPE *const [ANY]
- new: SWIGTYPE const [ANY]
- old: SWIGTYPE *[ANY]
-
- SWIGTYPE const *const [ANY]
- new: SWIGTYPE *const [ANY]
- old: SWIGTYPE const *[ANY]
-
- SWIGTYPE const *const &
- new: SWIGTYPE *const &
- old: SWIGTYPE const *&
-
- SWIGTYPE *const *
- new: SWIGTYPE const *
- old: SWIGTYPE **
-
- SWIGTYPE *const &
- new: SWIGTYPE const &
- old: SWIGTYPE *&
-
- Additionally, a const SWIGTYPE lookup is used now for any constant type. Some examples, where
- T is some reduced type, eg int, struct Foo:
-
- T const
- new: SWIGTYPE const
- old: SWIGTYPE
-
- T *const
- new: SWIGTYPE *const
- old: SWIGTYPE *
-
- T const[]
- new: SWIGTYPE const[]
- old: SWIGTYPE[]
-
- enum T const
- new: enum SWIGTYPE const
- old: enum SWIGTYPE
-
- T (*const )[]
- new: SWIGTYPE (*const )[]
- old: SWIGTYPE (*)[]
-
- Reminder: the typemap matching rules can now be seen for any types being wrapped by using
- either the -debug-tmsearch or -debug-tmused options.
-
- In practice this leads to some subtle matching rule changes and the majority of users
- won't notice any changes, except in the prime area of motivation for this change: Improve
- STL containers of const pointers and passing const pointers by reference. This is fixed
- because many of the STL containers use a type 'T const&' as parameters and when T is
- a const pointer, for example, 'K const*', then the full type is 'K const*const&'. This
- means that the 'SWIGTYPE *const&' typemaps now match when T is either a non-const or
- const pointer. Furthermore, some target languages incorrectly had 'SWIGTYPE *&' typemaps
- when these should have been 'SWIGTYPE *const&'. These have been corrected (Java, C#, Lua, PHP).
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2010-03-13: wsfulton
- [Java] Some very old deprecated pragma warnings are now errors.
-
-2010-03-13: wsfulton
- Improve handling of file names and directories containing double/multiple path separators.
-
-2010-03-10: mutandiz (Mikel Bancroft)
- [allegrocl] Use fully qualified symbol name of cl::identity in emit_defun().
-
-2010-03-06: wsfulton
- [Java] The intermediary JNI class modifiers are now public by default meaning these
- intermediary low level functions are now accessible by default from outside any package
- used. The proxy class pointer constructor and getCPtr() methods are also now public.
- These are needed in order for the nspace option to work without any other mods.
- The previous default of protected access can be restored using:
-
- SWIG_JAVABODY_METHODS(protected, protected, SWIGTYPE)
- %pragma(java) jniclassclassmodifiers = "class"
-
-2010-03-06: wsfulton
- [C#] Added the nspace feature for C#. Documentation for the nspace feature is now available.
-
-2010-03-04: wsfulton
- Added the nspace feature. This adds some improved namespace support. Currently only Java
- is supported for target languages, where C++ namespaces are automatically translated into
- Java packages. The feature only applies to classes,struct,unions and enums declared within
- a namespace. Methods and variables declared in namespaces still effectively have their
- namespaces flattened. Example usage:
-
- %feature(nspace) Outer::Inner1::Color;
- %feature(nspace) Outer::Inner2::Color;
-
- namespace Outer {
- namespace Inner1 {
- struct Color {
- ...
- };
- }
- namespace Inner2 {
- struct Color {
- ...
- };
- }
- }
-
- For Java, the -package option is also required when using the nspace feature. Say
- we use -package com.myco, the two classes can then be accessed as follows from Java:
-
- com.myco.Outer.Inner1.Color and com.myco.Outer.Inner2.Color.
-
-2010-02-27: wsfulton
- [Python] Remove -dirvtable from the optimizations included by -O as it this option
- currently leads to memory leaks as reported by Johan Blake.
-
-2010-02-27: wsfulton
- License code changes: SWIG Source is GPL-v3 and library code license is now clearer
- and is provided under a very permissive license. See https://www.swig.org/legal.html.
-
-2010-02-13: wsfulton
- [Ruby] A few fixes for compiling under ruby-1.9.x including patch from 'Nibble'.
-
-2010-02-13: wsfulton
- [Ruby] Apply patch from Patrick Bennett to fix RARRAY_LEN and RARRAY_PTR usage for Ruby 1.9.x
- used in various STL wrappers.
-
-2010-02-13: wsfulton
- [C#, Java] Fix incorrect multiply defined symbol name error when an enum item
- and class name have the same name, as reported by Nathan Krieger. Example:
-
- class Vector {};
- namespace Text {
- enum Preference { Vector };
- }
-
- This also fixes other incorrect corner case target language symbol name clashes.
-
-2010-02-11: wsfulton
- Add the -debug-lsymbols option for displaying the target language layer symbols.
-
-2010-02-09: wsfulton
- Fix -MM and -MMD options on Windows. They were not omitting files in the SWIG library as
- they should be.
-
-2010-02-08: wsfulton
- Fix #1807329 - When Makefile dependencies are being generated using the -M family of options
- on Windows, the file paths have been corrected to use single backslashes rather than double
- backslashes as path separators.
-
-2010-02-06: wsfulton
- Fix #2918902 - language specific files not being generated in correct directory on
- Windows when using forward slashes for -o, for example:
- swig -python -c++ -o subdirectory/theinterface_wrap.cpp subdirectory/theinterface.i
-
-2010-02-05: wsfulton
- Fix #2894405 - assertion when using -xmlout.
-
-2010-01-28: wsfulton
- Fix typemap matching bug when a templated type has a typemap both specialized and not
- specialized. For example:
-
- template<typename T> struct XX { ... };
- %typemap(in) const XX & "..."
- %typemap(in) const XX< int > & "..."
-
- resulted in the 2nd typemap being applied for all T in XX< T >.
-
-2010-01-22: wsfulton
- Fix #2933129 - typemaps not being found when the unary scope operator (::) is used to denote
- global scope, the typemap is now used in situations like this:
-
- struct X {};
- %typemap(in) const X & "..."
- void m(const ::X &);
-
- and this:
-
- struct X {};
- %typemap(in) const ::X & "..."
- void m(const X &);
-
-2010-01-20: wsfulton
- Fix some unary scope operator (::) denoting global scope problems in the types generated
- into the C++ layer. Previously the unary scope operator was dropped in the generated code
- if the type had any sort of qualifier, for example when using pointers, references, like
- ::foo*, ::foo&, bar< ::foo* >.
-
-2010-01-13: olly
- [PHP] Add datetime to the list of PHP predefined classes (patch
- from David Fletcher in SF#2931042).
-
-2010-01-11: wsfulton
- Slight change to warning, error and diagnostic reporting. The warning number is no
- longer shown within brackets. This is to help default parsing of warning messages by
- other tools, vim on Unix in particular.
-
- Example original display using -Fstandard:
- example.i:20: Warning(401): Nothing known about base class 'B'. Ignored.
- New display:
- example.i:20: Warning 401: Nothing known about base class 'B'. Ignored.
-
- Also subtle fix to -Fmicrosoft format adding in missing space. Example original display:
- example.i(20): Warning(401): Nothing known about base class 'Base'. Ignored.
- New display:
- example.i(20) : Warning 401: Nothing known about base class 'Base'. Ignored.
-
-2010-01-10: wsfulton
- Fix a few inconsistencies in reporting of file/line numberings including modifying
- the overload warnings 509, 512, 516, 474, 475 to now be two line warnings.
-
-2010-01-10: wsfulton
- Modify -debug-tags output to use standard file name/line reporting so that editors
- can easily navigate to the appropriate lines.
- Was typically:
- . top . include . include (/usr/share/swig/temp/trunk/Lib/swig.swg:312)
- . top . include . include . include (/usr/share/swig/temp/trunk/Lib/swigwarnings.swg:39)
- now:
- /usr/share/swig/temp/trunk/Lib/swig.swg:312: . top . include . include
- /usr/share/swig/temp/trunk/Lib/swigwarnings.swg:39: . top . include . include . include
-
-2010-01-03: wsfulton
- Fix missing file/line numbers for typemap warnings and in output from the
- -debug-tmsearch/-debug-tmused options.
-
-2010-01-03: wsfulton
- Add typemaps used debugging option (-debug-tmused). When used each line displays
- the typemap used for each type for which code is being generated including the file
- and line number related to the type. This is effectively a condensed form of the
- -debug-tmsearch option. Documented in Typemaps.html.
-
-2009-12-23: wsfulton
- Fix for %javaexception and directors so that all the appropriate throws clauses
- are generated. Problem reported by Peter Greenwood.
-
-2009-12-20: wsfulton
- Add -debug-tmsearch option for debugging the typemap pattern matching rules.
- Documented in Typemaps.html.
-
-2009-12-12: wsfulton
- [Octave] Remove the -api option and use the new OCTAVE_API_VERSION_NUMBER
- macro provided in the octave headers for determining the api version instead.
-
-2009-12-04: olly
- [Ruby] Improve support for Ruby 1.9 under GCC. Addresses part of
- SF#2859614.
-
-2009-12-04: olly
- Fix handling of modulo operator (%) in constant expressions
- (SF#2818562).
-
-2009-12-04: olly
- [PHP] "empty" is a reserved word in PHP, so rename empty() method
- on STL classes to "is_empty()" (previously this was automatically
- renamed to "c_empty()").
- *** POTENTIAL INCOMPATIBILITY ***
-
-2009-12-03: olly
- [PHP] Add typemaps for long long and unsigned long long, and for
- pointer to method.
-
-2009-12-02: olly
- [PHP] Fix warning and rename of reserved class name to be case
- insensitive.
-
-2009-12-01: wsfulton
- Revert support for %extend and memberin typemaps added in swig-1.3.39. The
- memberin typemaps are ignored again for member variables within a %extend block.
- Documentation inconsistency reported by Torsten Landschoff.
-
-2009-11-29: wsfulton
- [Java, C#] Fix generated quoting when using %javaconst(1)/%csconst(1) for
- static const char member variables.
-
- %javaconst(1) A;
- %csconst(1) A;
- struct X {
- static const char A = 'A';
- };
-
-2009-11-26: wsfulton
- [Java, C#] Fix %javaconst(1)/%csconst(1) for static const member variables to
- use the actual constant value if it is specified, rather than the C++ code to
- access the member.
-
- %javaconst(1) EN;
- %csconst(1) EN;
- struct X {
- static const int EN = 2;
- };
-
-2009-11-23: wsfulton
- C++ nested typedef classes can now be handled too, for example:
- struct Outer {
- typedef Foo { } FooTypedef1, FooTypedef2;
- };
-
-2009-11-18: wsfulton
- The wrappers for C nested structs are now generated in the same order as declared
- in the parsed code.
-
-2009-11-18: wsfulton
- Fix #491476 - multiple declarations of nested structs, for example:
- struct Outer {
- struct {
- int val;
- } inner1, inner2, *inner3, inner4[1];
- } outer;
-
-2009-11-17: wsfulton
- Fix parsing of enum declaration and initialization, for example:
-
- enum ABC {
- a,
- b,
- c
- } A = a, *pC = &C, array[3] = {a, b, c};
-
-2009-11-17: wsfulton
- Fix parsing of struct declaration and initialization, for example:
-
- struct S {
- int x;
- } instance = { 10 };
-
-2009-11-15: wsfulton
- Fix #1960977 - Syntax error parsing derived nested class declaration and member
- variable instance.
-
-2009-11-14: wsfulton
- Fix #2310483 - function pointer typedef within extern "C" block.
-
-2009-11-13: wsfulton
- Fix usage of nested template classes within templated classes so that compilable code
- is generated.
-
-2009-11-13: olly
- [php] Fix place where class prefix (as specified with -prefix)
- wasn't being used. Patch from gverbruggen in SF#2892647.
-
-2009-11-12: wsfulton
- Fix usage of nested template classes so that compilable code is generated - the nested
- template class is now treated like a normal nested classes, that is, as an opaque type
- unless the nestedworkaround feature is used.
-
-2009-11-12: wsfulton
- Replace SWIGWARN_PARSE_NESTED_CLASS with SWIGWARN_PARSE_NAMED_NESTED_CLASS and
- SWIGWARN_PARSE_UNNAMED_NESTED_CLASS for named and unnamed nested classes respectively.
-
- Named nested class ignored warnings can now be suppressed by name using %warnfilter, eg:
-
- %warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::Inner;
-
- but clearly unnamed nested classes cannot and the global suppression is still required, eg:
-
- #pragma SWIG nowarn=SWIGWARN_PARSE_UNNAMED_NESTED_CLASS
-
-2009-11-11: wsfulton
- Added the nestedworkaround feature as a way to use the full functionality of a nested class
- (C++ mode only). It removes the nested class from SWIG's type information so it is as if SWIG
- had never parsed the nested class. The documented nested class workarounds using a global
- fake class stopped working when SWIG treated the nested class as an opaque pointer, and
- this feature reverts this behaviour. The documentation has been updated with details of how
- to use and implement it, see the "Nested classes" section in SWIGPlus.html.
-
-2009-11-11: wsfulton
- There were a number of C++ cases where nested classes/structs/unions were being handled
- as if C code was being parsed which would oftentimes lead to uncompilable code as an
- attempt was made to wrap the nested structs like it is documented for C code. Now all
- nested structs/classes/unions are ignored in C++ mode, as was always documented. However,
- there is an improvement as usage of nested structs/classes/unions is now always treated
- as an opaque type by default, resulting in generated code that should always compile.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2009-11-09: drjoe
- Fix R for -fcompact and add std_map.i
-
-2009-11-08: wsfulton
- Fix inconsistency for nested structs/unions/classes. Uncompilable code was being
- generated when inner struct and union declarations were used as types within the
- inner struct. The inner struct/union is now treated as a forward declaration making the
- behaviour the same as an inner class. (C++ code), eg:
-
- struct Outer {
- struct InnerStruct { int x; };
- InnerStruct* getInnerStruct();
- };
-
-2009-11-08: wsfulton
- Ignored nested class/struct warnings now display the name of the ignored class/struct.
-
-2009-11-07: wsfulton
- Bug #1514681 - Fix nested template classes within a namespace generated uncompilable
- code and introduced strange side effects to other wrapper code especially code
- after the nested template class. Note that nested template classes are still ignored.
-
-2009-11-07: wsfulton
- Add new debug options:
- -debug-symtabs - Display symbol tables information
- -debug-symbols - Display target language symbols in the symbol tables
- -debug-csymbols - Display C symbols in the symbol tables
-
-2009-11-03: wsfulton
- Fix some usage of unary scope operator (::) denoting global scope, for example:
-
- namespace AA { /* ... */ }
- using namespace ::AA;
-
- and bug #1816802 - SwigValueWrapper should be used:
-
- struct CC {
- CC(int); // no default constructor
- };
- ::CC x();
-
- and in template parameter specializations:
-
- struct S {};
- template <typename T> struct X { void a() {} };
- template <> struct X<S> { void b() {} };
- %template(MyTConcrete) X< ::S >;
-
- plus probably some other corner case usage of ::.
-
-2009-11-02: olly
- [Python] Fix potential memory leak in initialisation code for the
- generated module.
-
-2009-10-23: wsfulton
- Fix seg fault when using a named nested template instantiation using %template(name)
- within a class. A warning that these are not supported is now issued plus processing
- continues as if no name was given.
-
-2009-10-20: wsfulton
- [Python] Fix std::vector<const T*>. This would previously compile, but not run correctly.
-
-2009-10-20: wsfulton
- Fixed previously fairly poor template partial specialization and explicit
- specialization support. Numerous bugs in this area have been fixed including:
-
- - Template argument deduction implemented for template type arguments, eg this now
- works:
- template<typename T> class X {};
- template<typename T> class X<T *> {};
- %template(X1) X<const int *>; // Chooses T * specialization
-
- and more complex cases with multiple parameters and a mix of template argument
- deduction and explicitly specialised parameters, eg:
- template <typename T1, typename T2> struct TwoParm { void a() {} };
- template <typename T1> struct TwoParm<T1 *, int *> { void e() {} };
- %template(E) TwoParm<int **, int *>;
-
- Note that the primary template must now be in scope, like in C++, when
- an explicit or partial specialization is instantiated with %template.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2009-09-14: wsfulton
- [C#] Add %csattributes for adding C# attributes to enum values, see docs for example.
-
-2009-09-11: wsfulton
- Fix memmove regression in cdata.i as reported by Adriaan Renting.
-
-2009-09-07: wsfulton
- Fix constant expressions containing <= or >=.
-
-2009-09-02: wsfulton
- The following operators in constant expressions now result in type bool for C++
- wrappers and remain as type int for C wrappers, as per each standard:
-
- && || == != < > <= >= (Actually the last 4 are still broken). For example:
-
- #define A 10
- #define B 10
- #define A_EQ_B A == B // now wrapped as type bool for C++
- #define A_AND_B A && B // now wrapped as type bool for C++
-
-2009-09-02: wsfulton
- Fix #2845746. true and false are now recognised keywords (only when wrapping C++).
- Constants such as the following are now wrapped (as type bool):
- #define FOO true
- #define BAR FOO && false
-
-Version 1.3.40 (18 August 2009)
-===============================
-
-2009-08-17: olly
- [Perl] Add "#undef do_exec" to our clean up of Perl global
- namespace pollution.
-
-2009-08-17: olly
- [PHP] Fix to wrap a resource returned by __get() in a PHP object (SF#2549217).
-
-2009-08-17: wsfulton
- Fix #2797485 After doing a 'make clean', install fails if yodl2man or yodl2html
- is not available.
-
-2009-08-16: wsfulton
- [Octave] Caught exceptions display the type of the C++ exception instead of the
- generic "c++-side threw an exception" message.
-
-2009-08-16: wsfulton
- [Java] When %catches is used, fix so that any classes specified in the "throws"
- attribute of the "throws" typemap are generated into the Java method's throws clause.
-
-2009-08-16: wsfulton
- [C#] Fix exception handling when %catches is used, reported by Juan Manuel Alvarez.
-
-2009-08-15: wsfulton
- Fix %template seg fault on some cases of overloading the templated method.
- Bug reported by Jan Kupec.
-
-2009-08-15: wsfulton
- [Ruby] Add numerous missing wrapped methods for std::vector<bool> specialization
- as reported by Youssef Jones.
-
-2009-08-14: wsfulton
- [Perl] Add SWIG_ConvertPtrAndOwn() method into the runtime for smart pointer
- memory ownership control. shared_ptr support still to be added. Patch from
- David Fletcher.
-
-2009-08-14: olly
- [PHP] PHP5 now wraps static member variables as documented.
-
-2009-08-14: olly
- [PHP] Update the PHP "class" example to work with PHP5 and use
- modern wrapping features.
-
-2009-08-13: wsfulton
- [PHP] std::vector wrappers overhaul. They no longer require the
- specialize_std_vector() macro. Added wrappers for capacity() and reserve().
-
-2009-08-13: wsfulton
- [PHP] Add const reference typemaps. const reference primitive types are
- now passed by value rather than pointer like the other target languages.
- Fixes SF#2524029.
-
-2009-08-08: wsfulton
- [Python] More user friendly AttributeError is raised when there are
- no constructors generated for the proxy class in the event that the
- class is abstract - the error message is now
- "No constructor defined - class is abstract" whereas if there are no
- public constructors for any other reason and the class is not abstract,
- the message remains
- "No constructor defined".
- [tcl] Similarly for tcl when using -itcl.
-
-2009-08-04: olly
- [PHP] Fix generated code to work with PHP 5.3.
-
-2009-08-04: vmiklos
- [PHP] Various mathematical functions (which would conflict
- with the built-in PHP ones) are now automatically handled by
- adding a 'c_' prefix.
-
-2009-08-03: wsfulton
- [C#] The std::vector<T> implementation is improved and now uses $typemap such
- that the proxy class for T no longer has to be specified in some macros
- for correct C# compilation; the following macros are deprecated, where
- CSTYPE was the C# type for the C++ class CTYPE:
-
- SWIG_STD_VECTOR_SPECIALIZE_MINIMUM(CSTYPE, CTYPE)
- usage should be removed altogether
-
- SWIG_STD_VECTOR_SPECIALIZE(CSTYPE, CTYPE)
- should be replaced with:
- SWIG_STD_VECTOR_ENHANCED(CTYPE)
-
- Some more details in csharp/std_vector.i
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2009-07-31: olly
- [Python] Fix indentation so that we give a useful error if the
- module can't be loaded. Patch from Gaetan Lehmann in SF#2829853.
-
-2009-07-29: wsfulton
- Add $typemap(method, typelist) special variable macro. This allows
- the contents of a typemap to be inserted within another typemap.
- Fully documented in Typemaps.html.
-
-2009-07-29: vmiklos
- [PHP] Static member variables are now prefixed with the
- class name. This allows static member variables with the
- same name in different classes.
-
-2009-07-29: olly
- [Python] Add missing locks to std::map wrappers. Patch from
- Paul Hampson in SF#2813836.
-
-2009-07-29: olly
- [PHP] Fix memory leak in PHP OUTPUT typemaps. Reported by Hitoshi
- Amano in SF#2826322.
-
-2009-07-29: olly
- [PHP] Fix memory leak in PHP resource destructor for classes
- without a destructor and non-class types. Patch from Hitoshi Amano
- in SF#2825303.
-
-2009-07-28: olly
- [PHP] Update warnings about clashes between identifiers and PHP
- keywords and automatic renaming to work with the PHP5 class
- wrappers. Fixes SF#1613679.
-
-2009-07-28: vmiklos
- [PHP] If a member function is not public but it has a base
- which is public, then now a warning is issued and the member
- function will be public, as PHP requires this.
-
-2009-07-21: vmiklos
- [PHP] Director support added.
-
-2009-07-15: olly
- [Perl] Don't specify Perl prototype "()" for a constructor with a
- different name to the class, as such constructors can still take
- parameters.
-
-2009-07-12: xavier98
- [Octave] Add support for Octave 3.2 API
-
-2009-07-05: olly
- [PHP] Update the list of PHP keywords - "cfunction" is no longer a
- keyword in PHP5 and PHP 5.3 added "goto", "namespace", "__DIR__",
- and "__NAMESPACE__".
-
-2009-07-03: olly
- [Tcl] To complement USE_TCL_STUBS, add support for USE_TK_STUBS
- and SWIG_TCL_STUBS_VERSION. Document all three in the Tcl chapter
- of the manual. Based on patch from SF#2810380 by Christian
- Gollwitzer.
-
-2009-07-02: vmiklos
- [PHP] Added factory.i for PHP, see the li_factory testcase
- for more info on how to use it.
-
-2009-07-02: wsfulton
- Fix -Wallkw option as reported by Solomon Gibbs.
-
-2009-07-02: wsfulton
- Fix syntax error when a nested struct contains a comment containing a * followed
- eventually by a /. Regression from 1.3.37, reported by Solomon Gibbs.
-
-2009-07-01: vmiklos
- [PHP] Unknown properties are no longer ignored in proxy
- classes.
-
-2009-07-01: vmiklos
- [PHP] Fixed %newobject behaviour, previously any method
- marked with %newobject was handled as a constructor.
-
-2009-06-30: olly
- [Ruby] Undefine close and connect macros defined by Ruby API
- headers as we don't need them and they can clash with C++ methods
- being wrapped. Patch from Vit Ondruch in SF#2814430.
-
-2009-06-26: olly
- [Ruby] Fix to handle FIXNUM values greater than MAXINT passed for a
- double parameter.
-
-2009-06-24: wsfulton
- Fix wrapping methods with default arguments and the compactdefaultargs feature
- where a class is passed by value and is assigned a default value. The SwigValueWrapper
- template workaround for a missing default constructor is no longer used as the code
- generated does not call the default constructor.
-
-2009-06-16: wsfulton
- [Java,C#] Fix enum marshalling when %ignore is used on one of the enum items.
- Incorrect enum values were being passed to the C++ layer or compilation errors resulted.
-
-2009-06-02: talby
- [Perl] Resolved reference.i overload support problem
- identified by John Potowsky.
-
-2009-05-26: wsfulton
- [C#] Improved std::map wrappers based on patch from Yuval Baror. The C# proxy
- now implements System.Collections.Generic.IDictionary<>.
-
- These std:map wrappers have a non-backwards compatible overhaul to make them
- like a .NET IDictionary. Some method names have changed as following:
- set -> setitem (use this[] property now)
- get -> getitem (use this[] property now)
- has_key -> ContainsKey
- del -> Remove
- clear -> Clear
-
- The following macros used for std::map wrappers are deprecated and will no longer work:
- specialize_std_map_on_key
- specialize_std_map_on_value
- specialize_std_map_on_both
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2009-05-20: vmiklos
- [PHP] Add the 'thisown' member to classes. The usage of it
- is the same as the Python thisown one: it's 1 by default and
- you can set it to 0 if you want to prevent freeing it. (For
- example to prevent a double free.)
-
-2009-05-14: bhy
- [Python] Fix the wrong pointer value returned by SwigPyObject_repr().
-
-2009-05-13: mutandiz (Mikel Bancroft)
- [allegrocl] Minor tweak when wrapping in -nocwrap mode.
-
-2009-05-11: wsfulton
- [C#] Improved std::vector wrappers on the C# proxy side from Yuval Baror. These
- implement IList<> instead of IEnumerable<> where possible.
-
-2009-04-29: wsfulton
- [Java, C#] Add the 'notderived' attribute to the javabase and csbase typemaps.
- When this attribute is set, the typemap will not apply to classes that are derived
- from a C++ base class, eg
- %typemap(csbase, notderived="1") SWIGTYPE "CommonBase"
-
-2009-04-29: olly
- [Python] Don't attempt to acquire the GIL in situations where we
- know that it will already be locked. This avoids some dead-locks
- with mod_python (due to mod_python bugs which are apparently
- unlikely to ever be fixed), and results in smaller wrappers which
- run a little faster (in tests with Xapian on x86-64 Ubuntu 9.04,
- the stripped wrapper library was 11% smaller and ran 2.7% faster).
-
-2009-04-21: wsfulton
- [C#] Fix #2753469 - bool &OUTPUT and bool *OUTPUT typemaps initialisation.
-
-2009-04-09: wsfulton
- Fix #2746858 - C macro expression using floating point numbers
-
-2009-03-30: olly
- [PHP] The default out typemap for char[ANY] now returns the string up to a
- zero byte, or the end of the array if there is no zero byte. This
- is the same as Python does, and seems more generally useful than
- the previous behaviour of returning the whole contents of the array
- including any zero bytes. If you want the old behaviour, you can provide
- your own typemap to do this:
-
- %typemap(out) char [ANY]
- %{
- RETVAL_STRINGL($1, $1_dim0, 1);
- %}
-
-Version 1.3.39 (21 March 2009)
-==============================
-
-2009-03-19: bhy
- [Python] Fix the memory leak related to Python 3 unicode and C char* conversion,
- which can be shown in the following example before this fix:
-
- from li_cstring import *
- i=0
- while True:
- i += 1
- n = str(i)*10
- test3(n)
-
- This fix affected SWIG_AsCharPtrAndSize() so you cannot call this function with
- a null alloc and non-null cptr argument in Python 3, otherwise a runtime error
- will be raised.
-
-2009-03-18: wsfulton
- [C#] std::vector<T> wrapper improvements for .NET 2 and also providing the
- necessary machinery to use the std::vector<T> wrappers with more advanced features such
- as LINQ - the C# proxy class now derives from IEnumerable<>. The default is now to
- generate code requiring .NET 2 as a minimum, although the C# code can be compiled
- for .NET 1 by defining the SWIG_DOTNET_1 C# preprocessor constant. See the
- std_vector.i file for more details.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2009-03-12: wsfulton
- [Ruby] Fix #2676738 SWIG generated symbol name clashes.
-
-2009-03-01: bhy
- [Python] Some fixes for Python 3.0.1 and higher support. In 3.0.1, the C API function
- PyObject_Compare is removed, so PyObject_RichCompareBool is used for replacement.
- Struct initilization of SwigPyObject and SwigPyObject_as_number changed to reflect
- the drop of tp_compare and nb_long.
-
-2009-03-01: bhy
- [Python] Fix SF#2583160. Now the importer in Python shadow wrapper take care of the
- case that module already imported at other place.
-
-2009-02-28: bhy
- [Python] Fix SF#2637352. Move struct declaration of SWIG_module in pyinit.swg before
- the method calls, since some C compiler don't allow declaration in middle of function
- body.
-
-2009-02-21: wsfulton
- [Allegrocl] Fix seg fault wrapping some constant variable (%constant) types.
-
-2009-02-20: wsfulton
- [CFFI] Fix seg faults when for %extend and using statements.
-
-2009-02-20: wsfulton
- Fix SF #2605955: -co option which broke in 1.3.37.
-
-2009-02-20: wsfulton
- New %insert("begin") section added. Also can be used as %begin. This is a new
- code section reserved entirely for users and the code within the section is generated
- at the top of the C/C++ wrapper file and so provides a means to put custom code
- into the wrapper file before anything else that SWIG generates.
-
-2009-02-17: wsfulton
- 'make clean-test-suite' will now run clean on ALL languages. Previously it only
- ran the correctly configured languages. This way it is now possible to clean up
- properly after running 'make partialcheck-test-suite'.
-
-2009-02-14: wsfulton
- Extend attribute library support for structs/classes and the accessor functions use
- pass/return by value semantics. Two new macros are available and usage is identical
- to %attribute. These are %attributeval for structs/classes and %attributestring for
- string classes, like std::string. See attribute.swg for more details.
-
-2009-02-13: wsfulton
- Add support for %extend and memberin typemaps. Previously the memberin typemaps were
- ignored for member variables within a %extend block.
-
-2009-02-12: wsfulton
- Remove unnecessary temporary variable when wrapping return values that are references.
- Example of generated code for wrapping:
-
- struct XYZ {
- std::string& refReturn();
- };
-
- used to be:
-
- std::string *result = 0 ;
- ...
- {
- std::string &_result_ref = (arg1)->refReturn();
- result = (std::string *) &_result_ref;
- }
-
- Now it is:
-
- std::string *result = 0 ;
- ...
- result = (std::string *) &(arg1)->refReturn();
-
-2009-02-08: bhy
- Change the SIZE mapped by %pybuffer_mutable_binary and %pybuffer_binary in pybuffer.i from
- the length of the buffer to the number of items in the buffer.
-
-2009-02-08: wsfulton
- Fix %feature not working for conversion operators, reported by Matt Sprague, for example:
- %feature("cs:methodmodifiers") operator bool "protected";
-
-2009-02-07: wsfulton
- [MzScheme] Apply #2081967 configure changes for examples to build with recent PLT versions.
- Also fixes Makefile errors building SWIG executable when mzscheme package is installed
- (version 3.72 approx and later).
-
-2009-02-04: talby
- [Perl] Fix SF#2564192 reported by David Kolovratnk.
- SWIG_AsCharPtrAndSize() now handles "get" magic.
-
-Version 1.3.38 (31 January 2009)
-================================
-
-2009-01-31: bhy
- [Python] Fix SF#2552488 reported by Gaetan Lehmann. Now %pythonprepend
- and %pythonappend have correct indentation.
-
-2009-01-31: bhy
- [Python] Fix SF#2552048 reported by Gaetan Lehmann. The parameter list
- of static member function in generated proxy code should not have the
- 'self' parameter.
-
-2009-01-29: wsfulton
- Fix regression introduced in 1.3.37 where the default output directory
- for target language specific files (in the absence of -outdir) was no
- longer the same directory as the generated c/c++ file.
-
-2009-01-28: wsfulton
- [Java, C#] Fix proxy class not being used when the global scope operator
- was used for parameters passed by value. Reported by David Piepgrass.
-
-2009-01-15: wsfulton
- [Perl] Fix seg fault when running with -v option, reported by John Ky.
-
-Version 1.3.37 (13 January 2009)
-================================
-
-2009-01-13: mgossage
- [Lua] Added contract support for requiring that unsigned numbers are >=0
- Rewrote much of Examples/Lua/embed3.
- Added a lot to the Lua documentation.
-
-2009-01-13: wsfulton
- Fix compilation error when using directors on protected virtual overloaded
- methods reported by Sam Hendley.
-
-2009-01-12: drjoe
- [R] Fixed handling of integer arrays
-
-2009-01-10: drjoe
- [R] Fix integer handling in r to deal correctly with signed
- and unsigned issues
-
-2009-01-10: wsfulton
- Patch #1992756 from Colin McDonald - %contract not working for classes
- in namespace
-
-2009-01-05: olly
- Mark SWIGPERL5, SWIGPHP5, and SWIGTCL8 as deprecated in the source
- code and remove documentation of them.
-
-2008-12-30: wsfulton
- Bug #2430756. All the languages now define a macro in the generated C/C++
- wrapper file indicating which language is being wrapped. The macro name is the
- same as those defined when SWIG is run, eg SWIGJAVA, SWIGOCTAVE, SWIGCSHARP etc
- and are listed in the "Conditional Compilation" section in the documentation.
-
-2008-12-23: wsfulton
- [Java] Fix #2153773 - %nojavaexception was clearing the exception feature
- instead of disabling it. Clearing checked Java exceptions also didn't work.
- The new %clearjavaexception can be used for clearing the exception feature.
-
-2008-12-22: wsfulton
- Fix #2432801 - Make SwigValueWrapper exception safe for when copy constructors
- throw exceptions.
-
-2008-12-21: wsfulton
- Apply patch #2440046 which fixes possible seg faults for member and global
- variable char arrays when the strings are larger than the string array size.
-
-2008-12-20: wsfulton
- The ccache compiler cache has been adapted to work with SWIG and
- named ccache-swig. It now works with C/C++ compilers as well as SWIG
- and can result in impressive speedups when used to recompile unchanged
- code with either a C/C++ compiler or SWIG. Documentation is in CCache.html
- or the installed ccache-swig man page.
-
-2008-12-12: wsfulton
- Apply patch from Kalyanov Dmitry which fixes parsing of nested structs
- containing comments.
-
-2008-12-12: wsfulton
- Fix error message in some nested struct and %inline parsing error situations
- such as unterminated strings and comments.
-
-2008-12-07: olly
- [PHP] Fix warnings when compiling generated wrapper with GCC 4.3.
-
-2008-12-06: wsfulton
- [PHP] Deprecate %pragma(php4). Please use %pragma(php) instead.
- The following two warnings have been renamed:
- WARN_PHP4_MULTIPLE_INHERITANCE -> WARN_PHP_MULTIPLE_INHERITANCE
- WARN_PHP4_UNKNOWN_PRAGMA -> WARN_PHP_UNKNOWN_PRAGMA
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2008-12-04: bhy
- [Python] Applied patch SF#2158938: all the SWIG symbol names started with Py
- are changed, since they are inappropriate and discouraged in Python
- documentation (from http://www.python.org/doc/2.5.2/api/includes.html):
-
- "All user visible names defined by Python.h (except those defined by
- the included standard headers) have one of the prefixes "Py" or "_Py".
- Names beginning with "_Py" are for internal use by the Python implementation
- and should not be used by extension writers. Structure member names do
- not have a reserved prefix.
-
- Important: user code should never define names that begin with "Py" or "_Py".
- This confuses the reader, and jeopardizes the portability of the user
- code to future Python versions, which may define additional names beginning
- with one of these prefixes."
-
- Here is a brief list of what changed:
-
- PySwig* -> SwigPy*
- PyObject_ptr -> SwigPtr_PyObject
- PyObject_var -> SwigVar_PyObject
- PySequence_Base, PySequence_Cont, PySequence_Ref ->
- SwigPySequence_Base, SwigPySequence_Cont, SwigPySequence_Ref
- PyMap* -> SwigPyMap*
-
- We provided a pyname_compat.i for backward compatibility. Users whose code having
- these symbols and do not want to change it could simply include this file
- at front of your code. A better solution is to run the converting tool on
- your code, which has been put in SWIG's SVN trunk (Tools/pyname_patch.py) and
- you can download it here:
- https://swig.svn.sourceforge.net/svnroot/swig/trunk/Tools/pyname_patch.py
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-2008-12-02: wsfulton
- [Python] Apply patch #2143727 from Serge Monkewitz to fix importing base classes
- when the package option is specified in %module and that module is %import'ed.
-
-2008-11-28: wsfulton
- [UTL] Fix #2080497. Some incorrect acceptance of types in the STL, eg a double * element
- passed into a vector<int *> constructor would be accepted, but the ensuing behaviour
- was undefined. Now the type conversion correctly raises an exception.
-
-2008-11-24: wsfulton
- Add -outcurrentdir option. This sets the default output directory to the current
- directory instead of the path specified by the input file. This option enables
- behaviour similar to c/c++ compilers. Note that this controls the output directory,
- but only in the absence of the -o and/or -outdir options.
-
-2008-11-23: wsfulton
- [ruby] Apply patch #2263850 to fix ruby/file.i ... rubyio.h filename change in
- ruby 1.9.
-
-2008-11-23: wsfulton
- Apply patch #2319790 from Johan Hake to fix shared_ptr usage in std::tr1 namespace.
-
-2008-11-21: wsfulton
- The use of the include path to find the input file is now deprecated.
- This makes the behaviour of SWIG the same as C/C++ compilers in preparation
- for use with ccache.
-
-2008-11-16: wsfulton
- Fix -nopreprocess option to:
- - correctly report file names in warning and error messages.
- - use the original input filename that created the preprocessed output when
- determining the C++ wrapper file name (in the absence of -o). Previously
- the name of the input file containing the preprocessed output was used.
-
-2008-11-11: wsfulton
- [Java] Add patch #2152691 from MATSUURA Takanori which fixes compiles using the
- Intel compiler
-
-2008-11-01: wsfulton
- Add patch #2128249 from Anatoly Techtonik which corrects the C/C++ proxy
- class being reported for Python docstrings when %rename is used.
-
-2008-11-01: wsfulton
- Add the strip encoder patch from Anatoly Techtonik #2130016. This enables an
- easy way to rename symbols by stripping a commonly used prefix in all the
- function/struct names. It works in the same way as the other encoders, such as
- title, lower, command etc outlined in CHANGES file dated 12/30/2005. Example
- below will rename wxAnotherWidget to AnotherWidget and wxDoSomething to
- DoSomething:
-
- %rename("%(strip:[wx])s") "";
-
- struct wxAnotherWidget {
- void wxDoSomething();
- };
-
-2008-09-26: mutandiz
- [allegrocl]
- Lots of test-suite work.
- - Fix ordering of wrapper output and %{ %} header output.
- - Fix declarations of local vars in C wrappers.
- - Fix declaration of defined constants in C wrappers.
- - Fix declaration of EnumValues in C wrappers.
- - add some const typemaps to allegrocl.swg
- - add rename for operator bool() overloads.
-
-2008-09-25: olly
- [PHP5] Fill in typemaps for SWIGTYPE and void * (SF#2095186).
-
-2008-09-22: mutandiz (Mikel Bancroft)
- [allegrocl]
- - Support wrapping of types whose definitions are not seen by
- SWIG. They are treated as forward-referenced classes and if a
- definition is not seen are treated as (* :void).
- - Don't wrap the contents of unnamed namespaces.
- - More code cleanup. Removed some extraneous warnings.
- - start work on having the allegrocl mod pass the cpp test-suite.
-
-2008-09-19: olly
- [PHP5] Add typemaps for long long and unsigned long long.
-
-2008-09-18: wsfulton
- [C#] Added C# array typemaps provided by Antti Karanta.
- The arrays provide a way to use MarshalAs(UnmanagedType.LPArray)
- and pinning the array using 'fixed'. See arrays_csharp.i library file
- for details.
-
-2008-09-18: wsfulton
- Document the optional module attribute in the %import directive,
- see Modules.html. Add a warning for Python wrappers when the
- module name for an imported base class is missing, requiring the
- module attribute to be added to %import, eg
-
- %import(module="FooModule") foo.h
-
-2008-09-18: olly
- [PHP5] Change the default input typemap for char * to turn PHP
- Null into C NULL (previously it was converted to an empty string).
- The new behaviour is consistent with how the corresponding output
- typemap works (SF#2025719).
-
- If you want to keep the old behaviour, add the following typemap
- to your interface file (PHP's convert_to_string_ex() function does
- the converting from PHP Null to an empty string):
-
- %typemap(in) char * {
- convert_to_string_ex($input);
- $1 = Z_STRVAL_PP($input);
- }
-
-2008-09-18: olly
- [PHP5] Fix extra code added to proxy class constructors in the case
- where the only constructor takes no arguments.
-
-2008-09-18: olly
- [PHP5] Fix wrapping of a renamed enumerated value of an enum class
- member (SF#2095273).
-
-2008-09-17: mutandiz (Mikel Bancroft)
- [allegrocl]
- - Fix how forward reference typedefs are handled, so as not to conflict
- with other legit typedefs.
- - Don't (for now) perform an ffitype typemap lookup when trying to
- when calling compose_foreign_type(). This is actually a useful thing
- to do in certain cases, the test cases for which I can't currently
- locate :/. It's breaking some wrapping behavior that is more commonly
- seen, however. I'll readd in a more appropriate way when I can
- recreate the needed test case, or a user complains (which means
- they probably have a test case).
- - document the -isolate command-line arg in the 'swig -help' output.
- It was in the html docs, but not there.
- - small amount of code cleanup, removed some unused code.
- - some minor aesthetic changes.
-
-2008-09-12: bhy
- [Python] Python 3.0 support branch merged into SWIG trunk. Thanks to
- Google Summer of Code 2008 for supporting this project! By default
- SWIG will generate interface files compatible with both Python 2.x
- and 3.0. And there's also some Python 3 new features that can be
- enabled by passing a "-py3" command line option to SWIG. These
- features are:
-
- - Function annotation support
- Also, the parameter list of proxy function will be generated,
- even without the "-py3" option. However, the parameter list
- will fallback to *args if the function (or method) is overloaded.
- - Buffer interface support
- - Abstract base class support
-
- For details of Python 3 support and these features, please see the
- "Python 3 Support" section in the "SWIG and Python" chapter of the SWIG
- documentation.
-
- The "-apply" command line option and support of generating codes
- using apply() is removed. Since this is only required by very old
- Python.
-
- This merge also patched SWIG's parser to solve a bug. By this patch,
- SWIG features able to be correctly applied on C++ conversion operator,
- such like this:
-
- %feature("shadow") *::operator bool %{ ... %}
-
-2008-09-02: richardb
- [Python] Commit patch #2089149: Director exception handling mangles
- returned exception. Exceptions raised by Python code in directors
- are now passed through to the caller without change. Also, remove
- the ": " prefix which used to be added to other director exceptions
- (eg, those due to incorrect return types).
-
-2008-09-02: wsfulton
- [Python] Commit patch #1988296 GCItem multiple module linking issue when using
- directors.
-
-2008-09-02: wsfulton
- [C#] Support for 'using' and 'fixed' blocks in the 'csin' typemap is now
- possible through the use of the pre attribute and the new terminator attribute, eg
-
- %typemap(csin,
- pre=" using (CDate temp$csinput = new CDate($csinput)) {",
- terminator=" } // terminate temp$csinput using block",
- ) const CDate &
- "$csclassname.getCPtr(temp$csinput)"
-
- See CSharp.html for more info.
-
-2008-09-01: wsfulton
- [CFFI] Commit patch #2079381 submitted by Boris Smilga - constant exprs put into
- no-eval context in DEFCENUM
-
-2008-08-02: wuzzeb
- [Chicken,Allegro] Commit Patch 2019314
- Fixes a build error in chicken, and several build errors and other errors
- in Allegro CL
-
-2008-07-19: wsfulton
- Fix building of Tcl examples/test-suite on Mac OS X reported by Gideon Simpson.
-
-2008-07-17: wsfulton
- Fix SF #2019156 Configuring with --without-octave or --without-alllang
- did not disable octave.
-
-2008-07-14: wsfulton
- [Java, C#] Fix director typemaps for pointers so that NULL pointers are correctly
- marshalled to C#/Java null in director methods.
-
-2008-07-04: olly
- [PHP] For std_vector.i and std_map.i, rename empty() to is_empty()
- since "empty" is a PHP reserved word. Based on patch from Mark Klein
- in SF#1943417.
-
-2008-07-04: olly
- [PHP] The deprecated command line option "-make" has been removed.
- Searches on Google codesearch suggest that nobody is using it now
- anyway.
-
-2008-07-04: olly
- [PHP] The SWIG cdata.i library module is now supported.
-
-2008-07-03: olly
- [PHP] The deprecated command line option "-phpfull" has been
- removed. We recommend building your extension as a dynamically
- loadable module.
-
-2008-07-02: olly
- [PHP4] Support for PHP4 has been removed. The PHP developers are
- no longer making new PHP4 releases, and won't even be providing
- patches for critical security issues after 2008-08-08.
-
-2008-07-02: olly
- [Python] Import the C extension differently for Python 2.6 and
- later so that an implicit relative import doesn't produce a
- deprecation warning for 2.6 and a failure for 2.7 and later.
- Patch from Richard Boulton in SF#2008229, plus follow-up patches
- from Richard and Haoyu Bai.
-
-Version 1.3.36 (24 June 2008)
-=============================
-
-06/24/2008: wsfulton
- Remove deprecated -c commandline option (runtime library generation).
-
-06/24/2008: olly
- [PHP] Fix assertion failure when handling %typemap(in,numinputs=0)
- (testcase ignore_parameter).
-
-06/24/2008: olly
- [PHP] Fix segfault when wrapping a non-class function marked with
- %newobject (testcase char_strings).
-
-06/22/2008: wsfulton
- [Java] Add a way to use AttachCurrentThreadAsDaemon instead of AttachCurrentThread
- in director code. Define the SWIG_JAVA_ATTACH_CURRENT_THREAD_AS_DAEMON macro, see
- Lib/java/director.swg.
-
-06/21/2008: wsfulton
- [Ruby] Fix crashing in the STL wrappers (reject! and delete_if methods)
-
-06/19/2008: wsfulton
- [Java, C#] C# and Java keywords will be renamed instead of just issuing a warning
- and then generating uncompilable code. Warning 314 gives the new name when a
- keyword is found.
-
-06/19/2008: wsfulton
- [R] Keyword handling added. R Keywords will be renamed as necessary.
- Warning 314 gives the new name when a keyword is found.
-
-06/17/2008: mgossage
- [Lua] Added missing support for bool& and bool*. Added runtest for li_typemaps testcase.
- (Bug #1938142)
-
-06/07/2008: bhy
- Added test case keyword_rename, then made the keyword renaming works properly
- by fixing Swig_name_make() for a incomplete condition checking.
-
-06/02/2008: wsfulton
- [Java, C#] Fix enum wrappers when using -noproxy.
-
-05/30/2008: bhy
- Added std::wstring into Lib/typemaps/primtypes.swg, since it is also a primitive
- type in SWIG - fixed SF #1976978.
-
-05/29/2008: wsfulton
- [Java, C#] Fix variable wrappers when using -noproxy.
-
-05/29/2008: bhy
- [Python] Fixed a typo of %#ifdef in Lib/python/pycontainer.swg, which is related
- to -extranative SWIG option - SF #1971977.
-
-05/20/2008: wsfulton
- New partialcheck makefile targets for partial testing of the test-suite. These
- just invoke SWIG, ie no compilation and no runtime testing. It can be faster
- when developing by just doing a directory diff of the files SWIG generates
- against those from a previous run. Example usage from the top level directory:
-
- make partialcheck-test-suite
- make partialcheck-java-test-suite
-
- This change also encompasses more flexibility in running the test-suite, eg
- it is possible to prefix the command line which runs any target language test
- with a tool. See the RUNTOOL, COMPILETOOL and SWIGTOOL targets in the common.mk
- file and makefiles in the test-suite directory. For example it is possible to
- run the runtime tests through valgrind using:
-
- make check RUNTOOL="valgrind --leak-check=full"
-
- or invoke SWIG under valgrind using:
-
- make check SWIGTOOL="valgrind --tool=memcheck"
-
-05/19/2008: drjoe
- [R] Fixed define that was breaking pre-2.7. Checked in
- patch from Soren Sonnenburg that creates strings in
- version independent way
-
-05/15/2008: wsfulton
- [Java] Fix variable name clash in directors - SF #1963316 reported by Tristan.
-
-05/14/2008: wsfulton
- Add an optimisation for functions that return objects by value, reducing
- the number of copies of the object that are made. Implemented using an
- optional attribute in the "out" typemap called "optimal". Details in
- Typemaps.html.
-
-05/11/2008: olly
- [PHP] Check for %feature("notabstract") when generating PHP5 class
- wrapper.
-
-05/11/2008: wsfulton
- Fix SF #1943608 - $self substitution in %contract, patch submitted by
- Toon Verstraelen.
-
-05/09/2008: olly
- [PHP] Fix char * typemaps to work when applied to signed char * and
- unsigned char * (uncovered by testcase apply_strings).
-
-05/09/2008: wsfulton
- Fix wrapping of char * member variables when using allprotected mode.
- Bug reported by Warren Wang.
-
-05/09/2008: olly
- [PHP] Fix bad PHP code generated when wrapping an enum in a
- namespace (uncovered by testcase arrays_scope).
-
-05/09/2008: olly
- [PHP] SWIG now runs the PHP testsuite using PHP5, not PHP4. PHP4
- is essentially obsolete now, so we care much more about solid PHP5
- support.
-
-05/07/2008: wsfulton
- STL fixes when using %import rather than %include and the Solaris Workshop
- compiler and the Roguewave STL.
-
-05/07/2008: wsfulton
- Fix wrapping of overloaded protected methods when using allprotected mode.
- Bug reported by Warren Wang.
-
-05/03/2008: wsfulton
- Commit patch #1956607 to add -MT support from Richard Boulton.
- This patch mirrors the gcc -MT option which allows one to change the default
- Makefile target being generated when generating makefiles with the -M family
- of options. For example:
-
- $ swig -java -MM -MT overriddenname -c++ example.i
- overriddenname: \
- example.i \
- example.h
-
-04/30/2008: mgossage
- [Lua] Removed generation of _wrap_delete_XXXXX (wrappered destructor)
- which was unused and causing warning with g++ -Wall.
- Removed other unused warning in typemaps.i and other places.
- Added Examples/lua/embed3, and run tests a few test cases.
-
-04/24/2008: olly
- [Python] Fix generated code for IBM's C++ compiler on AIX (patch
- from Goeran Uddeborg in SF#1928048).
-
-04/24/2008: olly
- Rename BSIZE in Examples/test-suite/arrays_scope.i to BBSIZE to
- avoid a clash with BSIZE defined by headers on AIX with Perl
- (reported in SF#1928048).
-
-04/20/2008: wsfulton
- Add the ability to wrap all protected members when using directors.
- Previously only the virtual methods were available to the target language.
- Now all protected members, (static and non-static variables, non-virtual methods
- and static methods) are wrapped when using the allprotected mode. The allprotected
- mode is turned on in the module declaration:
-
- %module(directors="1", allprotected="1") modulename
-
-Version 1.3.35 (7 April 2008)
-=============================
-
-04/07/2008: wsfulton
- [Lua] Add missing pointer reference typemaps
-
-04/06/2008: wsfulton
- Fix stack overflow when using typemap warning suppression, eg
- %warnfilter(SWIGWARN_TYPEMAP_CHARLEAK_MSG)
-
-04/05/2008: wsfulton
- [Python] Fix shared_ptr typemaps so that %pythonnondynamic can be used. Also corrects
- display of the proxy class type. Reported by Robert Lupton.
-
-04/04/2008: olly
- [Python] Add %newobject reference to python memory management subsection of manual
- (patch from mdbeachy in SF#1894610).
-
-03/27/2008: wsfulton
- [Python] Fix shared_ptr typemaps where the pointer type is a templated type with
- with more than one parameter. Reported by Robert Lupton.
-
-03/27/2008: mgossage
- [Lua] Added a typemap DISOWN for SWIGTYPE* and SWIGTYPE[], and support for %delobject feature.
- Added Examples/lua/owner which demonstrates the use of the memory management.
-
-03/26/2008: wsfulton
- [Java] Apply patch #1844301 from Monty Taylor to suppress enum constructor
- unused warnings.
-
-03/26/2008: wsfulton
- [Python] Apply patch #1924524 from Casey Raymondson which ensures the
- "No constructor defined" message is displayed when attempting to call a
- constructor on a class that doesn't have a constructor wrapper, eg if
- the C++ class is abstract.
-
-03/26/2008: wsfulton
- [Python] Apply patch #1925702 from Casey Raymondson which removes warning 512
- for std::vector wrappers.
-
-03/26/2008: olly
- [Python] Apply GCC 4.3 warnings patch from Philipp Thomas
- (SF#1925122).
-
-03/21/2008: wsfulton
- [Python] Thread safety patch for STL iterators from Abhinandan Jain.
-
-03/17/2008: mgossage
- [Lua] Added %luacode feature to add source code into wrappers.
- Updated documentation to document this.
- Added Examples/lua/arrays to show its use (and typemaps)
-
-03/17/2008: olly
- Fix nonportable sed usage which failed on Mac OS X (and probably
- other platforms). Fixes SF#1903612.
-
-03/17/2008: olly
- Fix memory leak in SWIG's parser (based on patch from Russell
- Bryant in SF#1914023).
-
-03/12/2008: wsfulton
- Fix bug #1878285 - unnecessary cast for C struct creation wrappers.
-
-03/12/2008: wsfulton
- [Python] Remove debugging info when using shared_ptr support
-
-03/06/2008: mgossage
- [Lua] Updated documentation for Lua exceptions.
- Added Examples/lua/exception and Examples/lua/embed2.
- Small updates to the typemaps.
-
-03/04/2008: wsfulton
- [Java, C#] Add char *& typemaps.
-
-03/04/2008: wsfulton
- Fix occasional seg fault when attempting to report overloaded methods as being ignored.
-
-02/29/2008: wsfulton
- [Perl] Fix #1904537 Swig causes a Perl warning "x used only once" in Perl 5.10
- reported by Ari Jolma
-
-02/29/2008: wsfulton
- [Python] Add shared_ptr varin/varout typemaps for wrapping global variables.
-
-02/25/2008: wsfulton
- Fix $wrapname to work in %exception (fixes some wrap:name assertions)
-
-Version 1.3.34 (27 February 2008)
-=================================
-
-02/13/2008: wsfulton
- [R] Fix wrapping of global function pointer variables.
-
-02/13/2008: wsfulton
- Add new special variables for use within %exception:
- $wrapname - language specific wrapper name
- $overname - if a method is overloaded this contains the extra mangling used on
- the overloaded method
- $decl - the fully qualified C/C++ declaration of the method being wrapped
- without the return type
- $fulldecl - the fully qualified C/C++ declaration of the method being wrapped
- including the return type
-
-02/12/2008: drjoe
- [R] Now setting S4 flag in SWIG created objects. This
- fixes R-SWIG for 2.6 and warning for 2.6 failure has been removed.
-
-02/11/2008: mgossage
- [Lua] Added a patch by Torsten Landschoff to fix the unary minus issue
- Ran 'astyle --style=kr -2' across lua.cxx to neaten it up
-
-02/10/2008: wsfulton
- Bump SWIG_RUNTIME_VERSION to 4. This is because of the recently introduced API
- change in the conversion functions, ie change in definition of swig_converter_func.
- Anyone calling SWIG_TypeCast must pass in a valid value for the new additional
- (third) parameter and then handle the newly created memory if the returned value
- is set to SWIG_CAST_NEW_MEMORY else a memory leak will ensue.
-
-02/09/2008: wsfulton
- [Python] Experimental shared_ptr typemaps added. Usage is the same as the recently
- added Java and C# shared_ptr typemaps. Two macros are available, although these
- may well change in a future version:
-
- For base classes or classes not in an inheritance chain:
- SWIG_SHARED_PTR(PROXYCLASS, TYPE)
- For derived classes:
- SWIG_SHARED_PTR_DERIVED(PROXYCLASS, BASECLASSTYPE, TYPE)
-
- The PROXYCLASS is the name of the proxy class, but is only required for Java/C#.
- Example usage:
-
- %include "boost_shared_ptr.i"
-
- SWIG_SHARED_PTR(Klass, Space::Klass)
- SWIG_SHARED_PTR_DERIVED(KlassDerived, Space::Klass, Space::KlassDerived)
-
- namespace Space {
- struct Klass { ... };
- struct KlassDerived : Klass { ... };
- }
-
- Further details to follow in future documentation, but the following features
- should be noted:
-
- - Not restricted to boost::shared_ptr, eg std::tr1::shared_ptr can also be used.
- - Available typemap groups:
- (a) Typemaps for shared_ptr passed by value, reference, pointer and pointer
- reference.
- - (b) Typemaps for passing by raw value, raw pointer, raw reference, raw pointer
- reference.
- - The code being wrapped does not even have to use shared_ptr, SWIG can use
- shared_ptr as the underlying storage mechanism instead of a raw pointer due to
- the typemaps in group (b) above.
- - No array support as shared_ptr does not support arrays.
- - This works quite differently to the usual SWIG smart pointer support when
- operator-> is parsed by SWIG:
- - An additional smart pointer class is not generated reducing code bloat in
- the wrappers.
- - Using smart pointers and raw pointers can be mixed seamlessly.
- - Missing constructors for the smart pointers is no longer a problem and so
- separate factory type functions do not have to be written and wrapped.
- - The implicit C++ shared_ptr< derived class > to shared_ptr< base class >
- cast also works in the target language. This negates the necessity to write
- an explicit helper cast function providing the upcast which would need
- calling prior to passing a derived class to a method taking a shared_ptr to
- a base class.
-
-02/09/2008: wsfulton
- [Python] Add support for overriding the class registration function via a new
- "smartptr" feature. This is a very low level of customisation most users
- would never need to know. The feature will typically be used for intrusive
- smart pointers along with additional typemaps. Example usage of the feature:
-
- %feature("smartptr", noblock=1) Foo { boost::shared_ptr< Foo > }
- class Foo {};
-
- The generated Foo_swigregister function will then register boost::shared < Foo >
- (SWIGTYPE_p_boost__shared_ptrTFoo_t instead of SWIGTYPE_p_Foo) as the underlying
- type for instantiations of Foo.
-
-02/09/2008: wsfulton
- Features now supports the optional 'noblock' attribute for all usage of %feature.
- When specified, the { } braces are removed from the feature code. This is identical
- in behaviour to usage of 'noblock' in typemaps and is used when the preprocessor
- is required to operate on the code in the feature and the enclosing { } braces
- are not required. Example:
-
- #define FOO foo
- %feature("smartptr", noblock="1") { FOO::bar }
-
- The preprocessor then reduces this as if this had been used instead:
-
- %feature("smartptr") "foo::bar"
-
-02/01/2008: olly
- [Python] Fix format string bug (SF#1882220).
-
-01/31/2008: wsfulton
- Additions to the %types directive. Now the conversion / casting code can be
- overridden to some custom code in the %types directive, like so:
-
- %types(fromtype = totype) %{
- ... code to convert fromtype to totype and return ...
- %}
-
- The special variable $from will be replaced by the name of the parameter of the
- type being converted from. The code must return the totype cast to void *. Example:
-
- class Time;
- class Date;
- Date &Time::dateFromTime();
-
- %types(Time = Date) %{
- Time *t = (Time *)$from;
- Date &d = t->dateFromTime();
- return (void *) &d;
- %}
-
- resulting in the conversion / casting code looking something like:
-
- static void *_p_TimeTo_p_Date(void *x) {
- Time *t = (Time *)x;
- Date &d = t->dateFromTime();
- return (void *) &d;
- }
-
- This is advanced usage, please use only if you understand the runtime type system.
-
-01/30/2008: mgossage
- Small update to documentation in Typemaps.html, to warn about use of local
- variables in typemaps for multiple types.
-
-01/25/2008: wsfulton
- [Java] Fix bug reported by Kevin Mills in ARRAYSOFCLASSES typemaps where any
- changes made to an array element passed from Java to C are not reflected back
- into Java.
-
-01/24/2008: mgossage
- More updates to the configure script for detecting lua.
- Also looks in /usr/include/lua*
- Also changed typemaps.i not to check for NULL before freeing a pointer
-
-01/21/2008: wsfulton
- [Python] For STL containers, SWIG no longer attempts to convert from one
- STL container to another, eg from std::vector<int> to std::vector<double>
- or std::list<int> to std::vector<int> or even std::vector<Foo> to
- std::vector<Bar> as it previously did. In fact SWIG no longer attempts to
- convert any SWIG wrapped C++ proxy class that is also a Python sequence,
- whereas previously it would. Any non-SWIG Python sequence will still be
- accepted wherever an STL container is accepted. Overloaded methods using
- containers should be faster.
-
-01/18/2008: wsfulton
- [C#] Add 'directorinattributes' and 'directoroutattributes' typemap attributes
- for the imtype typemap. These should contain C# attributes which will
- be generated into the C# director delegate methods.
-
-01/18/2008: olly
- Fix handling of byte value 255 in input files on platforms where
- char is signed (it was getting mapped to EOF). Fixes SF#1518219.
-
-01/16/2008: wsfulton
- Fix template member variables wrapped by a smart pointer. Bug reported
- by Robert Lupton.
-
-01/14/2008: mgossage
- Substantial changes to configure script for detecting lua.
- Code can now link to liblua.a, liblua50.a or liblua51.a
- It's also a lot neater now.
-
-12/16/2007: wsfulton
- [Perl] Backed out #1798728 - numbers can be passed to functions taking char *
-
-12/16/2007: wsfulton
- Fix #1832613 - Templates and some typedefs involving pointers or function pointers
-
-12/12/2007: wsfulton
- [Java] Fix #1632625 - Compilation errors on Visual C++ 6 when using directors.
-
-12/12/2007: wsfulton
- [Perl] Fix #1798728 - numbers can be passed to functions taking char *.
-
-12/12/2007: wsfulton
- Fix #1819847 %template with just one default template parameter
-
- template<typename T = int> class Foo {...};
- %template(FooDefault) Foo<>;
-
-12/12/2007: mgossage
- [Lua] Small correction on Lua.html
-
-12/09/2007: wsfulton
- Apply patch #1838248 from Monty Taylor for vpath builds of SWIG.
-
-12/08/2007: wsfulton
- [Lua] Fixes to remove gcc-4.2 warnings
-
-12/06/2007: wsfulton
- Fix #1734415 - template template parameters with default arguments such as:
-
- template<typename t_item, template<typename> class t_alloc = pfc::alloc_fast >
- class list_t : public list_impl_t<t_item,pfc::array_t<t_item,t_alloc> > { ... };
-
-12/04/2007: mgossage
- [lua] Fix a bug in the class hierachy code, where the methods were not propagated,
- if the name ordering was in a certain order.
- Added new example programs (dual, embed) and runtime tests for test-suite.
-
-11/30/2007: wsfulton
- Fix using statements using a base class method where the methods were overloaded.
- Depending on the order of the using statements and method declarations, these
- were previously generating uncompilable wrappers, eg:
-
- struct Derived : Base {
- virtual void funk();
- using Base::funk;
- };
-
-Version 1.3.33 (November 23, 2007)
-==================================
-
-11/21/2007: mikel
- [allegrocl] omit private slot type info in the classes/types
- defined on the lisp side. Fix bug in mapping of C/++ types
- to lisp types. Fix typo in modules generated defpackage form.
- Have std::string *'s automatically marshalled between foreign
- and lisp strings.
-
-11/20/2007: olly
- [Python] Fill in Python Dictionary functions list (patch from
- Jelmer Vernooij posted to swig-devel).
-
-11/20/2007: beazley
- Fixed a bug in the C scanner related to backslash characters.
-
-11/19/2007: wsfulton
- [Perl] Fix broken compilation of C++ wrappers on some compilers.
-
-11/16/2007: olly
- [Python] Don't pass Py_ssize_t for a %d printf-like format as
- that's undefined behaviour when sizeof(Py_ssize_t) != sizeof(int).
-
-Version 1.3.32 (November 15, 2007)
-==================================
-
-11/14/2007: wsfulton
- [R] Package name and dll name is now the same as the SWIG module
- name. It used to be the module name with _wrap as a suffix. The package
- and dll names can be modified using the -package and -dll commandline
- options.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-11/11/2007: wsfulton
- [R] Add support for Windows (Visual C++ 8 tested)
-
-11/10/2007: olly
- [php] Fix makefile generated by -make (SF#1633679). Update
- documentation to mark "-make" as deprecated (none of the other
- SWIG backends seem to offer such a feature, it can't realistically
- generate a fully portable makefile, and the commands to build an
- extension are easy enough to write for the user's preferred build
- tool). Also recommend against the use of "-phpfull" (it's only
- really useful when static linking, and a dynamically loadable
- module is virtually always the better approach).
-
-11/09/2007: olly
- Fix --help output to note that `export SWIG_FEATURES' is required.
-
-10/29/2007: wsfulton
- [R] Fix seg fault on Windows
- [R] Examples R scripts are now platform independent
-
-10/30/2007: mgossage
- [lua] fixed bug in template classes which cases template_default2
- and template_specialization_defarg to fail.
- Added several warning filters into the overload's test cases.
- Added runtime tests for several codes.
- You can now make check-lua-test-suite with no errors and only a few warnings.
-
-10/30/2007: olly
- [guile] Fix the configure test to put GUILELINK in LIBS not LDFLAGS
- (SF#1822430).
-
-10/30/2007: olly
- [guile] Fix the guile examples on 64-bit platforms.
-
-10/29/2007: wsfulton
- [C#] Fix member pointers on 64 bit platforms.
-
-10/28/2007: olly
- [lua] Fix swig_lua_class instances to be static to allow multiple
- SWIG wrappers to be compiled into the same executable statically.
- Patch from Andreas Fredriksson (posted to the swig mailing list).
-
-10/28/2007: olly
- [lua] Fix Examples/lua to pass SRCS for C tests rather than CXXSRCS.
- The code as it was happened to work on x86, but broke on x86_64 (and
- probably any other platforms which require -fPIC).
-
-10/28/2007: wsfulton
- [Java, C#] New approach for fixing uninitialised variable usage on error in director
- methods using the new templated initialisation function SwigValueInit().
-
-10/28/2007: wsfulton
- [Perl] Use more efficient SvPV_nolen(x) instead of SvPV(x,PL_na) if SvPV_nolen is
- supported.
-
-10/26/2007: wuzzeb
- [Chicken] Fix global variables of class member function pointers.
- Other minor fixes, so all tests in the chicken test suite now pass
-
-10/25/2007: olly
- Fix UTL typecheck macro for a function taking char[] or const
- char[] (SF#1820132).
-
-10/22/2007: mkoeppe
- [Guile] Filter out -ansi -pedantic from CFLAGS while compiling test programs for Guile
- in configure. This enables running the test suite for Guile if it is installed and
- usable.
-
-10/22/2007: mkoeppe
- [Guile -scm] Fix testcases apply_signed_char and apply_strings
- by adding explicit casts to the appropriate $ltype.
-
-10/22/2007: wsfulton
- [Java, C#] Fix uninitialised variable usage on error in director methods.
-
-10/19/2007: wsfulton
- [Java, C#] Bug #1794247 - fix generated code for derived classes when csbase or javabase
- typemaps are used with the replace="1" attribute.
-
-10/19/2007: wsfulton
- [Python] Docs updated to suggest using distutils. Patch #1796681 from Christopher Barker.
-
-10/19/2007: olly
- [perl5] Clear errno before calls to strtol(), strtoul(), strtoll()
- and strtoull() which we check errno after to avoid seeing a junk
- value of errno if there isn't an error in the call.
-
-10/16/2007: wsfulton
- Deprecate %attribute_ref and replace with %attributeref. There is just an argument
- order change in order to maintain consistency with %attribute, from:
-
- %attribute_ref(Class, AttributeType, AccessorMethod, AttributeName)
- to
- %attributeref(Class, AttributeType, AttributeName, AccessorMethod)
-
-10/16/2007: olly
- [Tcl] Fix several occurrences of "warning: deprecated conversion
- from string constant to 'char*'" from GCC 4.2 in generated C/C++
- code.
-
-10/16/2007: olly
- [PHP] Fix many occurrences of "warning: deprecated conversion from
- string constant to 'char*'" from GCC 4.2 in generated C/C++ code
- when compiling with a new enough version of PHP 5 (tested with
- PHP 5.2.3, but PHP 5.2.1 is probably the minimum requirement).
-
-10/15/2007: wsfulton
- Patch #1797133 from David Piepgrass fixes %attribute when the getter has the same name
- as the attribute name and no longer generate non-functional setter for read-only attributes.
-
-10/15/2007: olly
- [Tcl] Prevent SWIG_Tcl_ConvertPtr from calling the unknown proc.
- Add Examples/tcl/std_vector/ which this change fixes. Patch
- is from "Cliff C" in SF#1809819.
-
-10/12/2007: wsfulton
- [Java] Add DetachCurrentThread back in for directors. See entry dated 08/11/2006 and
- search for DetachCurrentThread on the mailing lists for details. The crashes on Solaris
- seem to be only present in jdk-1.4.2 and lower (jdk-1.5.0 and jdk-1.6.0 are okay), so
- anyone using directors should use a recent jdk on Solaris, or define (see director.swg)
- SWIG_JAVA_NO_DETACH_CURRENT_THREAD to the C++ compiler to get old behaviour.
-
-10/12/2007: wsfulton
- [Java] Ensure the premature garbage collection prevention parameter (pgcpp) is generated
- when there are C comments in the jtype and jstype typemaps.
-
-10/12/2007: wuzzeb
- Added a testsuite entry for Bug #1735931
-
-10/09/2007: olly
- Automatically rerun autogen.sh if configure.in is modified.
-
-10/09/2007: olly
- Enhance check-%-test-suite rule and friends to give a more helpful
- error message if you try them for a language which doesn't exist
- (e.g. "make check-php-test-suite" rather than the correct
- "make check-php4-test-suite").
-
-10/09/2007: olly
- Add make rule to regenerate Makefile from Makefile.in if it has
- changed.
-
-10/09/2007: olly
- [php] Fix long-standing memory leak in wrapped constructors and
- wrapped functions/methods which return an object.
-
-10/08/2007: olly
- Fix Makefile.in to read check.list files correctly in a VPATH
- build.
-
-10/07/2007: wsfulton
- [C#, Java] Experimental shared_ptr typemaps added
-
-09/27/2007: mgossage
- [lua] added more verbose error messages for incorrect typechecks.
- Added a routine which checks the exact number of parameters passed to a function
- (breaks operator_overloading for unary minus operator, currently disabled).
- Reorganised the luatypemaps.swg to tidy it up.
- Added a lot of %ignores on the operators not supported by lua.
- Added support for constant member function pointers & runtest for member_pointer.i
- Added first version of wchar.i
-
-09/25/2007: wsfulton
- [C#, Java] throws typemaps for std::wstring using C# patch #1799064 from David Piepgrass
-
-09/24/2007: wsfulton
- [Tcl] Apply #1771313 to fix bug #1650229 - fixes long long and unsigned long long
- handling.
-
-09/20/2007: olly
- [Java] Eliminate some unnecessary uses of a temporary buffer
- allocated using new[]. SF#1796609.
-
-09/19/2007: wsfulton
- [C#] The $csinput special variable can be used in the csvarin typemap where it is always
- expanded to 'value'.
-
-09/19/2007: wsfulton
- [C#] Fix bug reported by Glenn A Watson and #1795260 where the cstype typemap used the 'ref'
- keyword in the typemap body, it produced uncompilable C# properties (variable wrappers).
- The type for the property now correctly comes from the 'out' attribute in the cstype typemap.
-
-09/19/2007: wsfulton
- [Java] Fix const std::wstring& typemaps
-
-09/19/2007: wsfulton
- [Java] Ensure the premature garbage collection prevention parameter (pgcpp) is generated
- where a parameter is passed by pointer reference, eg in the std::vector wrappers. The pgcpp
- is also generated now when user's custom typemaps use a proxy class in the jstype typemap
- and a 'long' in the jtype typemap.
-
-09/18/2007: olly
- [php] Add typemaps for handling parameters of type std::string &
- which are modified by the wrapped function.
-
-09/17/2007: olly
- [python] Split potentially long string literals to avoid hitting
- MSVC's low fixed limit on string literal length - patch from
- SF#1723770, also reported as SF#1630855.
-
-09/17/2007: olly
- [ocaml] Fix renaming of overloaded methods in the method_table -
- my patch from SF#940399.
-
-09/17/2007: olly
- [python] Simpler code for SWIG_AsVal_bool() which fixes a "strict
- aliasing" warning from GCC - patch from SF#1724581 by Andrew
- Baumann.
-
-09/17/2007: olly
- [perl5] Use sv_setpvn() to set a scalar from a pointer and length
- - patch from SF#174460 by "matsubaray".
-
-09/17/2007: olly
- When wrapping C++ code, generate code which uses
- std::string::assign(PTR, LEN) rather than assigning
- std::string(PTR, LEN). Using assign generates more efficient code
- (tested with GCC 4.1.2).
-
-09/07/2007: wsfulton
- Fix %ignore on constructors which are not explicitly declared [SF #1777712]
-
-09/05/2007: wuzzeb (John Lenz)
- - Change r_ltype in typesys.c to store a hashtable instead of a single value.
- several very subtle bugs were being caused by multiple ltypes being mapped
- to a single mangled type, mostly when using typedefed template parameters.
- Now, r_ltype stores a hashtable of possible ltypes, and when generating the
- type table, all the ltypes are added into the swig_type_info structure.
-
-08/31/2007: wsfulton
- SF #1754967 from James Bigler.
- - Fix bug in turning on warnings that were turned off by default. Eg 'swig -w+309' will now
- turn on the normally suppressed warning 309.
-
- - New -Wextra commandline option which enables the extra warning numbers:
- 202,309,403,512,321,322 (this is the list of warnings that have always been suppressed by
- default). By specifying -Wextra, all warnings will be turned on, but unlike -Wall,
- warnings can still be selectively turned on/off using %warnfilter,
- #pragma SWIG nowarn or further -w commandline options, eg:
- swig -Wextra -w309
- will turn on all warnings except 309.
-
-08/28/2007: wsfulton
- - New debugging options, -debug-module <n> and -debug-top <n> to display the parse tree at
- various stages, where <n> is a comma separated list of stages 1-4.For example, to
- display top of parse tree at stages 1 and 3:
- swig -debug-top 1,3
-
- - Deprecate the following options which have equivalents below:
- -dump_parse_module => -debug-module 1
- -dump_module => -debug-module 4
- -dump_parse_top => -debug-top 1
- -dump_top => -debug-top 4
-
- - Renamed some commandline options for naming consistency across all options:
- -debug_template => -debug-template
- -debug_typemap => -debug-typemap
- -dump_classes => -debug-classes
- -dump_tags => -debug-tags
- -dump_typedef => -debug-typedef
- -dump_memory => -debug-memory
-
-08/25/2007: olly
- [PHP5] Fix handling of double or float parameters with an integer
- default value.
-
-08/25/2007: olly
- [PHP5] Generate __isset() methods for setters for PHP 5.1 and later.
-
-08/20/2007: wsfulton
- [Java C#] Fix director bug #1776651 reported by Stephane Routelous which occurred when
- the director class name is the same as the start of some other symbols used within
- the director class.
-
-08/17/2007: wsfulton
- Correct behaviour for templated methods used with %rename or %ignore and the empty
- template declaration - %template(). A warning is issued if the method has not been
- renamed.
-
-08/16/2007: mutandiz (Mikel Bancroft)
- [allegrocl] Name generated cl file based on input file rather than by
- module name. It was possible to end up with a mypackage.cl and a test_wrap.c
- when parsing a test.i input file. Confusing. Also, include external-format
- templates for :fat and :fat-le automatically to avoid these being compiled
- at runtime.
-
-08/15/2007: efuzzyone
- [cffi] Apply patch #1766076 from Leigh Smith adding support for newly introduced
- in cffi :long-long and :unsigned-long-long.
-
-08/10/2007: wsfulton
- [Java] Add documentation patch #1743573 from Jeffrey Sorensen. It contains a neat
- idea with respect to better memory management by the JVM of C++ allocated memory.
-
-08/10/2007: wsfulton
- [Perl] Apply patch #1771410 from Wade Brainerd to fix typedef XS(SwigPerlWrapper) in
- perlrun.swg for ActiveState Perl build 822 and Perl 5.8.9 and 5.10 branches.
-
-08/10/2007: wsfulton
- [Lua] const enum reference typemaps fixed.
-
-08/09/2007: wsfulton
- [C#] Added missing support for C++ class member pointers.
-
-08/09/2007: wsfulton
- [C#, Java] Add support for $owner in the "out" typemaps like in the scripting
- language modules. Note that $owner has always been supported in the "javaout" / "csout"
- typemaps.
-
-08/01/2007: wsfulton
- Fix smart pointer handling for classes that have templated methods within the smart
- pointer type. Problem reported by craigdo at ee.washington.edu.
-
-07/31/2007: efuzzyone
- [cffi] fixed memory access after being freed bug. thanks to Martin Percossi.
- package name clos changed to cl. thanks to Ralf Mattes
-
-07/24/2007: wsfulton
- Parallel make support added for the examples and test-suite for developers who have
- more than one CPU. Now parallel make can be used for checking in addition to building
- the SWIG executable. Some typical checking examples:
-
- make -j8 -k check
- make -j4 check-java-test-suite
- make -j2 check-java-examples
-
-07/19/2007: mgossage
- Fixed bug that stopped configure working on mingw (applied dos2unix to configure.in)
-
-07/10/2007: mgossage
- [lua] Extra compatibility with Lua 5.1 (updated SWIG_init, docs, examples, test suite)
- Removed name clash for static link of multiple modules
-
-07/05/2007: mgossage
- [lua] Fix a bug in SWIG_ALLOC_ARRAY()
- improved the error messages for incorrect arguments.
- Changed the output of swig_type() to use the human readable form of the type,
- rather than the raw swig type.
-
-07/03/2007: wsfulton
- [C#] Fix directors for some overloaded methods where the imtype resulted in identical
- methods being generated in the C# director class, eg void foo(int *) and void foo(double *)
- used to generated two of these:
-
- private void SwigDirectorfoo(IntPtr p) { ... }
-
-06/25/2007: wsfulton
- [Java, C#] Some parameter name changes in std_vector.i allowing better targeting
- of typemaps for method parameters (for memory management of containers of pointers).
-
-06/07/2007: mutandiz (Mikel Bancroft)
- [allegrocl]
- fix foreign-type constructor to properly look for ffitype typemap
- bindings. fix inout_typemaps.i for strings.
-
-06/06/2007: olly
- [Ruby]
- Use whichever of "long" or "long long" is the same size as "void*"
- to hold pointers as integers, rather than whichever matches off_t.
- Fixes compilation on OS X and GCC warnings on platforms where
- sizeof(void*) < sizeof(off_t) (SF patch #1731979).
-
-06/06/2007: olly
- [PHP5]
- Fix handling of a particular case involving overloaded functions
- with default parameters.
-
-06/05/2007: mutandiz (Mikel Bancroft)
- [allegrocl]
- Fix case where we'd pass fully qualified identifiers
- (i.e. NS1::NS2::FOO) to swig-insert-id. All namespaces
- should be stripped.
-
- Fix bug in TypedefHandler introduced by last fix.
-
-06/05/2007: olly
- Fix reporting of filenames in errors after %include (patch from
- Leigh Smith in #1731040; also reported as #1699940).
-
-05/31/2007: olly
- [Python]
- Fix "missing initialiser" warning when compiling generated C/C++
- wrapper code with Python 2.5 with warnings enabled (patch from
- bug#1727668 from Luke Moore).
-
-05/29/2007: olly
- [Python]
- Split docstrings into separate string literals at each newline when
- generating C/C++ wrapper code (the C/C++ compiler will just combine
- them back into a single string literal). This avoids MSVC
- complaining that the strings are too long (problem reported by
- Bo Peng on the mailing list).
-
-05/28/2007: olly
- [Python]
- Escape backslashes in docstrings.
-
-05/26/2007: olly
- [Python]
- Fix autodoc generation of enums to be more consistent with how the
- enums are wrapped - patch #1697226 from Josh Cherry.
-
-05/26/2007: olly
- [PHP5]
- Fix wrapping of methods and functions which return a pointer to a
- class (bug#1700788) and those which have overloaded forms returning
- both classes and non-classes (bug#1712717, thanks to Simon
- Berthiaume for the patch).
-
-05/25/2007: wsfulton
- Fixed %rename inconsistency in conversion operators as reported by Zhong Ren. The matching
- is now done on the operator name in the same way as it is done for parameters. For example:
-
- %rename(opABC) Space::ABC::operator ABC() const;
- %rename(methodABC) Space::ABC::method(ABC a) const;
- namespace Space {
- class ABC {
- public:
- void method(ABC a) const {}
- operator ABC() const { ABC a; return a; }
- };
- }
-
- Note that qualifying the conversion operator previously may or may not have matched.
- Now it definitely won't, so this will not match:
-
- %rename(opABC) Space::ABC::operator Space::ABC() const;
-
- in the same way that this does not match:
-
- %rename(methodABC) Space::ABC::method(Space::ABC a) const;
-
- The documentation has been improved with respect to %rename, namespaces and templates.
- Conversion operators documentation too.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-05/16/2007: mutandiz
- [allegrocl]
- Fix bad generation of local var ltype's in functionWrapper().
- Try to work better with the backward order in which swig
- unrolls nested class definitions.
- cleaned up a little unnecessary code/debug printf's.
- Remove warning when replacing $ldestructor for ff:foreign-pointer
-
-05/12/2007: olly
- [Python]
- swig -python -threads now generates C/C++ code which uses Python's
- own threading abstraction (from pythread.h) rather than OS specific
- code. The old code failed to compile on MS Windows. (See SF patch
- tracker #1710341).
-
-05/04/2007: gga
- [Ruby]
- Changed STL renames to be global renames. This fixes
- STL functions not being renamed when autorename is on.
- This is a not a totally perfect work-around, but better.
- Someone really needs to fix the template renaming code.
- (See bug #1545634)
-
-05/04/2007 gga
- [All]
- Changed %rename("%(undercase)s") a little so that single
- numbers at the end of a function are not undercased. That is:
- getSomething -> get_something
- get2D -> get_2d
- get234 -> get_234
- BUT:
- asFloat2 -> as_float2
- (Bug #1699714)
-
-05/03/2007: gga
- [Ruby]
- Made __swigtype__ => @__swigtype__ so it can be accessed
- from the scripting language (and follows Ruby's official
- documentation, just in case).
- Made tracking => @__trackings__ for same reason.
- Currently storing ivars without the @ seems valid, but
- the PickAxe says this is not correct, so just in case...
-
-05/03/2007: gga
- [Ruby]
- Applied patch for -minherit bug and exception classes.
- This issue should be revisited more closely, as Multiple
- Inheritance in Ruby is still problematic.
- (patch/bug #1604878)
-
-05/03/2007: gga
- [Ruby]
- Overloaded functions in ruby will now report to the user
- the possible prototypes when the user mistypes the number or
- type of a parameter.
-
-05/03/2007: gga
- [Ruby]
- Forgot to document the bug fixing of an old bug regarding
- exceptions.
- (bug #1458247)
-
-05/03/2007: gga
- [Ruby]
- Fixed Ruby documentation to use the proper css styles for
- each section. Added autodoc section to Ruby's docs to
- document the features supported by Ruby in documenting its modules.
- Made rdoc documentation spit out the full name of the class +
- method name. Albeit this will make the current rdoc not recognize
- the method, this is still needed to disambiguate between different
- classes with similar methods (rdoc was created to document the
- ruby source which only contains one class per c file, unlike swig)
- I have patched rdoc to make it more friendly to swig. This
- patch needs to be merged in the ruby std library now.
-
-05/03/2007: gga
- [Ruby]
- Changed flag -feature to be -init_name to better reflect its
- purpose and avoid confusion with -features.
-
-05/03/2007: gga
- [Ruby]
- Improved autodoc generation.
- Added autodoc .swg files to Ruby library for easily adding
- documentation to common Ruby methods and STL methods.
- Fixed autodoc documenting of getters and setters and module.
- Made test suite always generate autodocs.
-
-05/03/2007: gga
- [Ruby]
- Removed some warnings from STL and test suite.
-
-05/02/2007: mgossage
- [Lua] Fixed issues with C++ classes and hierachies across multiple
- source files. Fixed imports test case & added run test.
- Added Examples/imports.
- Added typename for raw lua_State*
- Added documentation on native functions.
-
-05/02/2007: gga
- [Ruby]
- Docstrings are now supported.
- %feature("autodoc") and %feature("docstring") are now
- properly supported in Ruby. These features will generate
- a _wrap.cxx file with rdoc comments in them.
-
-05/02/2007: gga
- [Ruby]
- STL files have been upgraded to follow the new swig/python
- Lib/std conventions.
- This means std::vector, std::set, std::map, set::multimap,
- std::multiset, std::deque and std::string are now properly
- supported, including their iterators, support for containing
- ruby objects (swig::GC_VALUE) and several other ruby
- enhancements.
- std::complex, std::ios, std::iostream, std::iostreambuf and
- std::sstream are now also supported.
- std::wstring, std::wios, std::wiostream, std::wiostreambuf
- and std::wsstream are supported verbatim with no unicode
- conversion.
-
- std_vector.i now mimics the behavior of Ruby Arrays much more
- closely, supporting slicing, shifting, unshifting,
- multiple indexing and proper return values on assignment.
-
- COMPATABILITY NOTE: this changes the older api a little bit in
- that improper indexing would previously (incorrectly) raise
- exceptions. Now, nil is returned instead, following ruby's
- standard Array behavior.
-
-05/02/2007: gga
- [Ruby]
- Changed the value of SWIG_TYPECHECK_BOOL to be 10000 (ie. higher
- than that of all integers).
- This is because Ruby allows typecasting
- integers down to booleans which can make overloaded functions on
- bools and integers to fail.
- (bug# 1488142)
-
-05/02/2007: gga
- [Ruby]
- Fixed a subtle bug in multiple argouts that could get triggered if
- the user returned two or more arguments and the first one was an
- array.
-
-05/01/2007: gga
- [Ruby]
- Improved the documentation to document the new features
- added, add directorin/out/argout typemaps, etc.
-
-05/01/2007: gga
- [Ruby]
- Added %initstack and %ignorestack directives for director
- functions. These allow you to control whether a director
- function should re-init the Ruby stack.
- This is sometimes needed for an embedded Ruby where the
- director method is used as a C++ callback and not called
- by the user from ruby code.
- Explanation:
- Ruby's GC needs to be aware of the running OS stack in order to
- mark any VALUE (Ruby objects) it finds there to avoid collection
- of them. This allows the ruby API to be very simple and allows
- you to write code like "VALUE a = sth" anywhere without needing
- to do things like refcounting like python.
- By default, the start of the stack is set when ruby_init() is
- called. If ruby is inited within main(), as it usually is the
- case with the main ruby executable, ruby will be able to calculate
- its stack properly. However, when this is not possible, as when
- ruby is embedded as a plugin to an application where main is not
- available, ruby_init() will be called in the wrong place, and
- ruby will be incorrectly tracking the stack from the function
- that called ruby_init() forwards only, which can lead to
- all sorts of weird crashes or to ruby thinking it has run out of
- stack space incorrectly.
- To avoid this, director (callback) functions can now be tagged
- to try to reset the ruby stack, which will solve the issues.
- NOTE: ruby1.8.6 still contains a bug in it in that its function
- to reset the stack will not always do so. This bug is triggered
- very rarely, when ruby is called from two very distinct places
- in memory, like a branch of main() and another dso. This bug
- has now been reported to ruby-core and is pending further
- investigation.
- (bug #1700535 and patch #1702907)
-
-04/30/2007: wsfulton
- Fix #1707582 - Restore building from read-only source directories.
-
-04/30/2007: gga
- [Ruby]
- Ruby will now report the parameter index properly on type
- errors as well as the class and value of the incorrect
- argument passed.
- (feature request #1699670)
-
-04/30/2007: gga
- [Ruby]
- Ruby no longer creates the free_Class function if the class
- contains its own user defined free function (%freefunc).
- (bug #1702882)
-
-04/30/2007: gga
- [Ruby]
- Made directors raise a ruby exception for incorrect argout
- returned values if RUBY_EMBEDDED is set, instead of throwing
- an actual SwigDirector exception.
- This will prevent crashes when ruby is embedded and unaware
- of the SwigDirector exception.
-
-04/30/2007: gga
- [Ruby]
- Removed the need for -DSWIGEXTERN.
- Changed swig_ruby_trackings to be a static variable, but also
- be kept within a hidden instance variable in the SWIG module.
- This allows properly dealing with trackings across multiple
- DSOs, which was previously broken.
- (bug #1700535 and improvement to patch #1702907)
-
-04/29/2007: gga
- [Ruby] Fixed GC memory issues with trackings that could lead
- to segfaults when dealing, mainly, with static variables.
- (bug #1700535 and patch #1702907)
-
-04/29/2007: gga
- [Ruby]
- Fixed String conversion using old ruby1.6 macros. Now
- StringValuePtr() is used if available. This removes warnings
- when converting strings with \0 in them.
- (bug #1700535 and patch #1702907)
-
-04/29/2007: gga
- [Ruby]
- Fixed the argout count in directors for Ruby. Previously,
- ignored or "numinputs=0" typemaps would incorrectly not get
- counted towards the argout count.
- (bug/patch #1545585)
-
-04/29/2007: gga
- [Ruby]
- Upgraded Ruby converter to recognize "numinputs=0". Previously,
- only the old "ignore" flag was checked (which would currently
- still work properly, but is deprecated).
-
-04/29/2007: gga
- [Ruby - but should be made generic]
-
- %feature("numoutputs","0") added.
-
- This feature allows you to ignore the output of a function so
- that it is not added to a list of output values
- ( ie. argouts ).
- This should also become a feature of %typemap(directorout)
- as "numoutputs"=0, just like "numinputs"=0 exists.
-
- %feature("directors"=1)
-
- %include <typemaps.i>
-
- %feature("numoutputs","0") { Class::member_function1 };
- %typemap(out) MStatus { // some code, like check mstatus
- // and raise exception if wrong };
-
- %inline %{
- typedef int MStatus;
- class Class {
-
- // one argument returned, but director out code added
- // MStatus is discarded as a return (out) parameter.
- virtual MStatus member_function1( int& OUTPUT );
-
- // two arguments returned, director out code added
- // MStatus is not discarded
- virtual MStatus member_function2( int& OUTPUT );
- };
- %}
-
-
-04/21/2007: olly
- Fix parsing of float constants with an exponent (e.g. 1e-02f)
- (bug #1699646).
-
-04/20/2007: olly
- [Python] Fix lack of generation of docstrings when -O is used.
- Also, fix generation of docstrings containing a double quote
- character. Patch from Richard Boulton in bug#1700146.
-
-04/17/2007: wsfulton
- [Java, C#] Support for adding in Java/C# code before and after the intermediary call,
- specifically related to the marshalling of the proxy type to the intermediary type.
- The javain/csin typemap now supports the 'pre' and 'post' attributes to achieve this.
- The javain typemap also supports an optional 'pgcppname' attribute for premature garbage
- collection prevention parameter naming and the csin typemap supports an optional 'cshin'
- attribute for the parameter type used in a constructor helper generated when the type is used
- in a constructor. Details in the Java.html and CSharp.html documentation.
-
-04/16/2007: olly
- Don't treat `restrict' as a reserved identifier in C++ mode
- (bug#1685534).
-
-04/16/2007: olly
- [PHP5] Fix how zend_throw_exception() is called (bug #1700785).
-
-04/10/2007: olly
- Define SWIGTEMPLATEDISAMBIGUATOR to template for aCC (reported on
- swig-user that this is needed).
-
-04/04/2007: olly
- [PHP5] If ZTS is enabled, release <module>_globals_id in MSHUTDOWN
- to avoid PHP interpreter crash on shutdown. This solution was
- suggested here: http://bugs.php.net/bug.php?id=40985
-
-04/03/2007: olly
- [PHP4] Add missing ZTS annotations to generated C++ wrapper code
- to fix compilation failures when using ZTS enabled SWIG (Linux
- distributions tend to disable ZTS, but notably the Windows build
- uses it by default).
-
-04/01/2007: efuzzyone
- [CFFI] Patch #1684261: fixes handling of unsigned int literals, thanks Leigh Smith.
- Also, improved documentation.
-
-03/30/2007: olly
- Avoid generating '<:' token when using SwigValueWrapper<> on a type
- which starts with '::' (patch #1690948).
-
-03/25/2007: wuzzeb (John Lenz)
- [perl5] Add SWIG_fail to the SWIG_exception macro. Fixes a few problems reported
- on the mailing list.
-
-03/23/2007: wsfulton
- String copying patch from Josh Cherry reducing memory consumption by about 25%.
-
-03/21/2007: wsfulton
- [Java] Apply patch #1631987 from Ulrik Peterson - bool INOUT typemaps
- fail on big endian machines.
-
-03/16/2007: wsfulton
- Fix seg fault given dodgy C++ code: namespace abc::def { }
-
-03/16/2007: wsfulton
- [Java] Fixes so that ARRAYSOFCLASSES and ARRAYSOFENUMS in arrays_java.i can be applied
- to pointer types.
-
-03/03/2007: olly
- [PHP5] When we know the literal numeric value for a constant, use
- that to initialise the const member in the PHP wrapper class.
-
-03/02/2007: olly
- [PHP5] Fix PHP wrapper code generated for certain cases of
- overloaded forms with default arguments.
-
-02/26/2007: efuzzyone
- [CFFI] Patch #1656395: fixed hex and octal values bug, thanks to Arthur Smyles.
-
-02/22/2007: mgossage
- [Lua] Fixed bug in typemaps which caused derived_byvalue and rname test cases to fail.
- Updated derived_byvalue.i to explain how to find and fix the problem
-
-01/25/2007: wsfulton
- Fix #1538522 and #1338527, forward templated class declarations without a
- name for the templated class parameters, such as:
-
- template <typename, class> class X;
-
-01/23/2007: mgossage
- [Lua] Patch #1640862: <malloc.h> replaced by <stdlib.h>
- Patch #1598063 Typo in typemaps.i
-
-01/22/2007: mgossage
- [Lua] Added a lua specific carrays.i which adds the operator[] support.
- modified the main code to make it not emit all the class member functions & accessors
- Note: C structs are created using new_XXX() while C++ classes use XXX() (should be standardised)
- Updated test case: li_carrays
- Updated the documentation.
-
-01/12/2007: wsfulton
- [Php] Add support for newfree typemaps (sometimes used by %newobject)
-
-01/12/2007: beazley
- New command line option -macroerrors. When supplied, this will force
- the C scanner/parser to report proper location information for code contained
- inside SWIG macros (defined with %define). By default, SWIG merely reports
- errors on the line at which a macro is used. With this option, you
- can expand the error back to its source---something which may simplify
- debugging.
-
-01/12/2007: beazley
- [Internals] Major overhaul of C/C++ scanning implementation. For quite
- some time, SWIG contained two completely independent C/C++ tokenizers--
- the legacy scanner in CParse/cscanner.c and a general purpose scanner
- in Swig/scanner.c. SWIG still has two scanning modules, but the C parser
- scanner (CParse/cscanner.c) now relies upon the general purpose
- scanner found in Swig/scanner.c. As a result, it is much smaller and
- less complicated. This change also makes it possible to maintain all
- of the low-level C tokenizing in one central location instead of two
- places as before.
-
- ***POTENTIAL FLAKINESS***
- This change may cause problems with accurate line number reporting
- as well as error reporting more generally. I have tried to resolve this
- as much as possible, but there might be some corner cases.
-
-01/12/2007: mgossage
- [Lua] Added typemap throws for std::string*, typemap for SWIGTYPE DYNAMIC,
- changed the existing throws typemap to throw a string instead of making a copy of
- the object (updating a few test cases to deal with the change).
- fixed test case: dynamic_casts, exception_partial_info, li_std_string, size_t
-
-01/03/2007: beazley
- [Internals]. Use of swigkeys.c/.h variables is revoked. Please use
- simple strings for attribute names.
-
-12/30/2006: beazley
- Internal API functions HashGetAttr() and HashCheckAttr() have been revoked.
- Please use Getattr() to retrieve attributes. The function Checkattr() can
- be used to check attributes. Note: These functions have been revoked
- because they only added a marginal performance improvement at the expense
- code clarity.
-
-12/26/2006: mgossage
- [Lua] Added more STL (more exceptions, map, size_t),
- fixed test case: conversion_ns_template.
-
-12/21/2006: mgossage
- [Lua] Update to throw errors when setting immutables,
- and allowing user addition of module variables.
-
-12/20/2006: wsfulton
- Fix typedef'd variable wrappers that use %naturalvar, eg, std::string.
-
-12/14/2006: wsfulton
- [C#] Add std::wstring and wchar_t typemaps
-
-12/14/2006: olly
- [php] Fix bug #1613673 (bad PHP5 code generated for getters and
- setters).
-
-12/02/2006: wsfulton, John Lenz, Dave Beazley
- Move from cvs to Subversion for source control
-
-11/30/2006: beazley
- Cleaned up swigwarnings.swg file not to use nested macro
- definitions.
-
-11/12/2006: wsfulton
- [Java, C#] Fix for %extend to work for static member variables.
-
-Version 1.3.31 (November 20, 2006)
-==================================
-
-11/12/2006: Luigi Ballabio
- [Python] Alternate fix for Python exceptions bug #1578346 (the previous one broke Python
- properties in modern classes)
-
-11/12/2006: wsfulton
- -fakeversion commandline option now generates the fake version into the generated wrappers
- as well as displaying it when the -version commandline option is used.
-
-14/11/2006: mgossage
- [lua] update to typemap for object by value, to make it c89 compliant
-
-Version 1.3.30 (November 13, 2006)
-==================================
-
-11/12/2006: wsfulton
- [java] Remove DetachCurrentThread patch from 08/11/2006 - it causes segfaults
- on some systems.
-
-11/12/2006: wsfulton
- [python] Fix #1578346 - Python exceptions with -modern
-
-11/10/2006: wsfulton
- Fix #1593291 - Smart pointers and inheriting from templates
-
-11/09/2006: wsfulton
- Fix director operator pointer/reference casts - #1592173.
-
-11/07/2006: wsfulton
- Add $self special variable for %extend methods. Please use this instead of just 'self'
- as the C++ 'this' pointer.
-
-11/07/2006: mutandiz
- [allegrocl]
- allegrocl.swg: swig-defvar updated to allow specifying of
- non-default foreign type (via :ftype keyword arg).
- allegrocl.cxx: Specify proper access type for enum values.
-
-11/03/2006: wsfulton
- [Java/C#] Fix const std::string& return types for directors as reported by
- Mark Donselzmann
-
-10/29/2006: wsfulton
- [Java] Remove DeleteLocalRef from end of director methods for now as it is causing a
- seg fault when run on Solaris 8.
-
-10/29/2006: wuzzeb (John Lenz)
- [Guile] Patch from Chris Shoemaker to clean up some warnings in the generated code.
-
-10/29/2006: wsfulton
- [Java] Important fix to prevent early garbage collection of the Java proxy class
- while it is being used in a native method. The finalizer could destroy the underlying
- C++ object while it was being used. The problem occurs when the proxy class is no
- longer strongly reachable after a native call. The problem seems to occur in
- memory stress situations on some JVMs. It does not seem to occur on the
- Sun client JVM up to jdk 1.5. However the 1.6 client jdk has a more aggressive garbage
- collector and so the problem does occur. It does occur on the Sun server
- JVMs (certainly 1.4 onwards). The fix entails passing the proxy class into the native
- method in addition to the C++ pointer in the long parameter, as Java classes are not
- collected when they are passed into JNI methods. The extra parameter can be suppressed
- by setting the nopgcpp attribute in the jtype typemap to "1" or using the new -nopgcpp
- commandline option.
-
- See Java.html#java_pgcpp for further details on this topic.
-
-10/24/2006: wsfulton
- [C#] Fix smart pointer wrappers. The virtual/override/new keyword is not generated
- for each method as the smart pointer class does not mirror the underlying pointer
- class inheritance hierarchy. SF #1496535
-
-10/24/2006: mgossage
- [lua] added support for native methods & member function pointers.
- fixed test cases arrays_dimensionless & cpp_basic. Added new example (functor).
- tidied up a little of the code (around classHandler).
-
-10/17/2006: wsfulton
- [C#, Java] directorout typemap changes to fall in line with the other director
- languages. $result is now used where $1 used to be used. Please change your typemaps
- if you have a custom directorout typemap.
-
-10/18/2006: wsfulton
- Some fixes for applying the char array typemaps to unsigned char arrays.
-
-10/17/2006: wsfulton
- [C#, Java] Add in const size_t& and const std::size_t& typemaps.
-
-10/15/2006: efuzzyone
- [CFFI] Suppress generating defctype for enums, thanks to Arthur Smyles. Patch 1560983.
-
-10/14/2006: wuzzeb (John Lenz)
- [Chicken] Minor fix to make SWIG work with the (as yet unreleased) chicken 2.5
-
- [Guile,Chicken] Fix SF Bug 1573892. Added an ext_test to the test suite to test
- this bug, but this test can not really be made generic because the external code must
- plug into the target language interpreter directly.
- See Examples/test-suite/chicken/ext_test.i and ext_test_external.cxx
-
- Added a %.externaltest to common.mk, and any interested language modules can
- copy and slightly modify either the chicken or the guile ext_test.i
-
-10/14/2006: mgossage
- [Lua] added OUTPUT& for all number types, added a long long type
- fixed several test cases.
- update: changed typemaps to use SWIG_ConvertPtr rather than SWIG_MustGetPointer
- started spliting lua.swg into smaller parts to make it neater
-
-10/13/2006: wsfulton
- [C#, Java] Marginally better support for multiple inheritance only in that you can
- control what the base class is. This is done using the new 'replace' attribute in the
- javabase/csbase typemap, eg in the following, 'Me' will be the base class,
- no matter what Foo is really derived from in the C++ layer.
-
- %typemap(javabase, replace="1") Foo "Me"
- %typemap(csbase, replace="1") Foo "Me"
-
- Previously it was not possible for the javabase/csbase typemaps to override the C++ base.
-
-10/12/2006: wsfulton
- [Java] Remove potential race condition on the proxy class' delete() method
- (it is now a synchronized method, but is now customisable by changing the
- methodmodifiers attribute in the javadestruct or javadestruct_derived typemap)
-
- [C#] Remove potential race condition on the proxy class' Dispose() method,
- similar to Java's delete() above.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-10/12/2006: wsfulton
- [Ruby, Python] Remove redundant director code in %extend methods (%extend
- methods cannot be director methods)
-
-10/12/2006: wsfulton
- [Ruby, Python] Fix #1505594 - director objects not returned as director objects
- in %extend methods.
-
-10/11/2006: wsfulton
- [Java] Fix #1238798 - Directors using unsigned long long or any other type
- marshalled across the JNI boundary using a Java class (where the jni typemap
- contains jobject).
-
-10/06/2006: wsfulton
- Fix #1162194 - #include/%include within a structure
-
-10/06/2006: wsfulton
- Fix #1450661, string truncation in String_seek truncating Java/C# enums.
-
-10/06/2006: mgossage
- [Lua] Fix #1569587. The name is now correct.
-
-10/04/2006: wsfulton
- Director fixes for virtual conversion operators
-
-10/04/2006: olly
- [php] Fix #1569587 for PHP. Don't use sizeof() except with string
- literals. Change some "//" comments to "/* */" for portability.
-
-10/04/2006: mgossage
- [Lua] Partial Fix #1569587. The type is now correct, but the name is still not correct.
-
-10/03/2006: wsfulton
- [Ruby] Fix #1527885 - Overloaded director virtual methods sometimes produced
- uncompilable code when used with the director:except feature.
-
-10/03/2006: wsfulton
- Directors: Directors are output in the order in which they are declared in
- the C++ class rather than in some pseudo-random order.
-
-10/03/2006: mmatus
- Fix #1486281 and #1471039.
-
-10/03/2006: olly
- [Perl] Fix for handling strings with zero bytes from Stephen Hutsal.
-
-09/30/2006: efuzzyone
- [CFFI] Bitfield support and vararg support due to Arthur Smyles.
- C expression to Lisp conversion, thanks to Arthur Smyles for the initial
- idea, it now supports conversion for a whole range of C expressions.
-
-09/28/2006: wsfulton
- Fix #1508327 - Overloaded methods are hidden when using -fvirtual optimisation.
- Overloaded methods are no longer candidates for elimination - this mimics
- C++ behaviour where all overloaded methods must be defined and implemented
- in a derived class in order for them to be available.
-
-09/25/2006: wsfulton
- [Ruby, Python, Ocaml] Fix #1505591 Throwing exceptions in extended directors
-
-09/25/2006: wsfulton
- Fix #1056100 - virtual operators.
-
-09/24/2006: olly
- Don't accidentally create a "<:" token (which is the same as "[" in C++).
- Fixes bug # 1521788.
-
-09/23/2006: olly
- [Ruby] Support building with recent versions of the Ruby 1.9
- development branch. Fixes bug #1560092.
-
-09/23/2006: olly
- Templates can now be instantiated using negative numbers and
- constant expressions, e.g.:
-
- template<int q> class x {};
- %template(x_minus1) x<-1>;
- %template(x_1plus2) x<1+2>;
-
- Also, constant expressions can now include comparisons (>, <, >=,
- <=, !=, ==), modulus (%), and ternary conditionals (a ? b : c).
-
- Fixes bugs #646275, #925555, #956282, #994301.
-
-09/22/2006: wsfulton
- Fix %ignore on director methods - Bugs #1546254, #1543533
-
-09/20/2006: wsfulton
- Fix %ignore on director constructors
-
-09/20/2006: wsfulton
- Fix seg faults and asserts when director methods are ignored (#1543533)
-
-09/20/2006: wsfulton
- Fix out of source builds - bug #1544718
-
-09/20/2006: olly
- Treat a nested class definition as a forward declaration rather
- than ignoring it completely, so that we generate correct code for
- passing opaque pointers to the nested class (fixes SF bug #909387).
-
-09/20/2006: olly
- *** POTENTIAL INCOMPATIBILITY ***
- [php] Overload resolution now works. However to allow this, SWIG
- generated wrappers no longer coerce PHP types (which reverts a change
- made in 1.3.26). So for example, if a method takes a string, you
- can no longer pass a number without explicitly converting it to a
- string in PHP using: (string)x
-
-09/18/2006: mgossage
- [ALL] fix on swiginit.swg, has been reported to crash on several test cases
- found and fixed problem in imports under python (mingw)
-
-09/16/2006: wsfulton
- [Python] Patch from Michal Marek for Python 2.5 to fix 64 bit array indexes on
- 64 bit machines.
-
-09/13/2006: wsfulton
- The explicitcall feature has been scrapped. This feature was introduced primarily
- to solve recursive director method calls. Director upcall improvements made instead:
-
- [Python, Ruby, Ocaml] The swig_up flag is no longer used. The required mutexes
- wrapping this flag are also no longer needed. The recursive calls going from C++
- to the target language and back again etc are now avoided by a subtlely different
- approach. Instead of using the swig_up flag in each director method to indicate
- whether the explicit C++ call to the appropriate base class method or a normal
- polymorphic C++ call should be made, the new approach makes one of these calls
- directly from the wrapper method.
-
- [Java, C#] The recursive call problem when calling a C++ base class method from
- Java/C# is now fixed. The implementation is slightly different to the other languages
- as the detection as to whether the explicit call or a normal polymorphic call is made
- in the Java/C# layer rather than in the C++ layer.
-
-09/11/2006: mgossage
- [ALL] updated swiginit.swg to allow multiple interpreters to use multiple
- swig modules at once. This has been tested in Lua (mingw & linux),
- perl5 & python (linux) only.
-
-09/11/2006: mgossage
- [lua] added support for passing function pointers as well as native lua object
- into wrappered function.
- Added example funcptr3 to demonstrate this feature
-
-09/05/2006: olly
- [php] Rename ErrorCode and ErrorMsg #define-s to SWIG_ErrorCode
- and SWIG_ErrorMsg to avoid clashes with code the user might be
- wrapping (patch from Darren Warner in SF bug #1466086). Any
- user typemaps which use ErrorCode and/or ErrorMsg directly will
- need adjusting - you can easily fix them to work with both old
- and new SWIG by changing to use SWIG_ErrorMsg and adding:
-
- #ifndef SWIG_ErrorMsg
- #define SWIG_ErrorMsg() ErrorMsg()
- #endif
-
-08/29/2006: olly
- [php] Move constant initialisation from RINIT to MINIT to fix a
- warning when using Apache and mod_php. We only need to create
- PHP constants once when we're first initialised, not for every HTTP
- request.
-
-08/21/2006: mgossage
- [Lua]
- Bugfix #1542466 added code to allow mapping Lua nil's <-> C/C++ NULL's
- updated various typemaps to work correctly with the changes
- added voidtest_runme.lua to show the features working
-
-08/19/2006: wuzzeb (John Lenz)
- [Guile] Add feature:constasvar to export constants as variables instead of functions
- that return the constant value.
-
-08/11/2006: wsfulton
- [Java] DetachCurrentThread calls have been added so that natively created threads
- no longer prevent the JVM from exiting. Bug reported by Thomas Dudziak and
- Paul Noll.
-
-08/10/2006: wsfulton
- [C#] Fix director protected methods so they work
-
-07/25/2006: mutandiz
- [allegrocl]
- more additions to std::string, some tweaks and small bug fixes
- -nocwrap mode.
-
-07/21/2006: mgossage
- [Lua]
- Bugfix #1526022 pdated std::string to support strings with '\0' inside them
- updated typemaps.i to add support for pointer to pointers
-
-07/19/2006: mutandiz
- [allegrocl]
- - Add std_string.i support.
- - Add newobject patch submitted by mkoeppe (thanks!)
- - Fix type name mismatch issue for nested type definitions.
- specifically typedefs in templated class defns.
-
-07/18/2006: mgossage
- Bugfix #1522858
- updated lua.cxx to support -external-runtime command
-
-07/14/2006: wuzzeb (John Lenz)
- Increment the SWIG_RUNTIME_VERSION to 3, because of the
- addition of the owndata member in swig_type_info.
- Reported by: Prabhu Ramachandran
-
-07/05/2006: wsfulton
- Search path fixes:
- - Fix search path for library files to behave as documented in Library.html.
- - Fix mingw/msys builds which did not find the SWIG library when installed.
- - Windows builds also output the mingw/msys install location when running
- swig -swiglib.
- - The non-existent and undocumented config directory in the search path has
- been removed.
-
-07/05/2006: wsfulton
- Fix $symname special variable expansion.
-
-07/04/2006: wuzzeb (John Lenz)
- [Chicken]
- Add %feature("constasvar"), which instead of exporting a constant as a
- scheme function, exports the constant as a scheme variable. Update the
- documentation as well.
-
-07/04/2006: wsfulton
- [See entry of 09/13/2006 - explicitcall feature and documentation to it removed]
- New explicitcall feature which generates additional wrappers for virtual methods
- that call the method explicitly, not relying on polymorphism to make the method
- call. The feature is a feature flag and is enabled like any other feature flag.
- It also recognises an attribute, "suffix" for mangling the feature name, see
- SWIGPlus.html#SWIGPlus_explicitcall documentation for more details.
-
- [Java, C#]
- The explicitcall feature is also a workaround for solving the recursive calls
- problem when a director method makes a call to a base class method. See
- Java.html#java_directors_explicitcall for updated documentation.
-
-06/28/2006: joe (Joseph Wang)
- [r] Initial support for R
-
-06/20/2006: wuzzeb (John Lenz)
- [Chicken]
- Minor fixes to get apply_strings.i testsuite to pass
- Remove integers_runme.scm from the testsuite, because SWIG and Chicken does
- handle overflows.
-
-06/19/2005: olly
- [php] Add support for generating PHP5 class wrappers for C++
- classes (use "swig -php5").
-
-06/17/2006: olly
- [php] Added some missing keywords to the PHP4 keyword list, and
- fixed __LINE__ and __FILE__ which were in the wrong category.
- Also added all the keywords new in PHP5, and added comments
- noting the PHP4 keywords which aren't keywords in PHP5.
-
-06/17/2006: olly
- [php] Don't segfault if PHP Null is passed as this pointer (e.g.
- Class_method(Null)) - give a PHP Error instead.
-
-06/15/2006: mutandiz
- [allegrocl]
- Add initial support for std::list container class.
- Fix a few bugs in helper functions.
-
-05/13/2006: wsfulton
- [Java] Replace JNIEXPORT with SWIGEXPORT, thereby enabling the possibility
- of using gcc -fvisibility=hidden for potentially smaller faster loading wrappers.
-
-05/13/2006: wsfulton
- Fix for Makefiles for autoconf-2.60 beta
-
-05/13/2006: wsfulton
- Vladimir Menshakov patch for compiling wrappers with python-2.5 alpha.
-
-05/12/2006: wsfulton
- Fix buffer overflow error when using large %feature(docstring) reported
- by Joseph Winston.
-
-05/12/2006: wsfulton
- [Perl] Operator overload fix from Daniel Moore.
-
-05/25/2006: mutandiz
- [allegrocl]
- Fix bug in generation of CLOS type declarations for unions
- and equivalent types.
-
-05/24/2006: mutandiz
- [allegrocl]
- Don't require a full class definition to generate a CLOS wrapper.
-
-05/20/2006: olly
- [php] GCC Visibility support now works with PHP.
-
-05/19/2006: olly
- [php] Removed support for -dlname (use -module instead). Fixed
- naming of PHP extension module to be consistent with PHP
- conventions (no "php_" prefix on Unix; on PHP >= 4.3.0, handle Unix
- platforms which use something other than ".so" as the extension.)
-
-05/13/2006: wsfulton
- [C#] Director support added
-
-05/07/2006: olly
- [php] Don't segfault if PHP Null is passed where a C++ reference
- is wanted.
-
-05/05/2006: olly
- [php] Fix wrappers generated for global 'char' variables to not
- include a terminating zero byte in the PHP string.
-
-05/03/2006: wsfulton
- Modify typemaps so that char * can be applied to unsigned char * or signed char *
- types and visa versa.
-
-05/03/2006: efuzzyone
- [cffi]Thanks to Luke J Crook for this idea.
- - a struct/enum/union is replaced with :pointer only if
- that slot is actually a pointer to that type. So,:
- struct a_struct { int x; } and
- struct b_struct { a_struct struct_1; };
- will be converted as:
- (cffi:defcstruct b_struct
- (struct_1 a_struct))
- - Other minor fixes in lispifying names.
-
-05/02/2006: wsfulton
- Fix possible redefinition of _CRT_SECURE_NO_DEPRECATE for VC++.
-
-04/14/2006: efuzzyone
- [cffi]
- Thanks to Thomas Weidner for the patch.
- - when feature export is set (export 'foo) is
- generated for every symbol
- - when feature inline is set (declaim (inline foo)) is
- generated before every function definition
- - when feature intern_function is set
- #.(value-of-intern-function "name" "nodeType" package)
- is emitted instead of the plain symbol. A sample swig-lispify
- is provided.
- - every symbol is prefixed by it's package.
-
-04/13/2006: efuzzyone
- [cffi]
- Fixed the generation of wrappers for global variables.
- Added the option [no]swig-lisp which turns on/off generation
- of code for swig helper lisp macro, functions, etc.
-
-Version 1.3.29 (March 21, 2006)
-===============================
-
-04/05/2006: mutandiz
- [allegrocl]
- Fix output typemap of char so it produces a character instead
- of an integer. Also adds input/output typemaps for 'char *'.
-
- add command-line argument -isolate to generate an interface
- file that won't interfere with other SWIG generated files that
- may be used in the same application.
-
-03/20/2005: mutandiz
- [allegrocl]
- More tweaks to INPUT/OUTPUT typemaps for bool.
-
- Fix constantWrapper for char and string literals.
-
- find-definition keybindings should work in ELI/SLIME.
- Output (in-package <module-name>) to lisp wrapper
- instead of (in-package #.*swig-module-name*).
-
- slight rework of multiple return values.
-
- doc updates.
-
-03/17/2005: mutandiz
- [allegrocl]
- mangle names of constants generated via constantWrapper.
-
- When using OUTPUT typemaps and the function has a non-void
- return value, it should be first in the values-list, followed
- by the OUTPUT mapped values.
-
- Fix bug with boolean parameters, which needed to be
- passed in as int values, rather than T or NIL.
-
-03/15/2006: mutandiz
- [allegrocl]
- Generate wrappers for constants when in C++ or -cwrap mode.
- Make -cwrap the default, since it is most correct. Users
- can use the -nocwrap option to avoid the creation of a .cxx
- file when interfacing to C code.
-
- When in -nocwrap mode, improve the handling of converting
- infix literals to prefix notation for lisp. This is very
- basic and not likely to be improved upon since this only
- applies to the -nocwrap case. Literals we can't figure out
- will result in a warning and be included in the generated
- code.
-
- validIdentifier now more closely approximates what may be
- a legal common lisp symbol.
-
- Fix typemap error in allegrocl.swg
-
-03/12/2006: mutandiz
- [allegrocl]
- fix up INPUT/OUTPUT typemaps for bool.
- Generate c++ style wrapper functions for struct/union members
- when -cwrap option specified.
-
-03/10/2006: mutandiz
- [allegrocl]
- Fix bug in C wrapper generation introduced by last allegrocl
- commit.
-
-03/10/2006: wsfulton
- [Java]
- Commit #1447337 - Delete LocalRefs at the end of director methods to fix potential leak
-
-03/10/2006: wsfulton
- Fix #1444949 - configure does not honor --program-prefix.
- Removed non-standard configure option --with-release-suffix. Fix the autoconf standard
- options --program-prefix and --program-suffix which were being shown in the help,
- but were being ignored. Use --program-suffix instead of --with-release-suffix now.
-
-03/10/2006: wsfulton
- [Java]
- Fix #1446319 with patch from andreasth - more than one wstring parameter in director methods
-
-03/07/2006: mkoeppe
- [Guile]
- Fix for module names containing a "-" in non-"shadow" mode.
- Patch from Aaron VanDevender (#1441474).
-
-03/04/2006: mmatus
- - Add -O to the main program, which now enables -fastdispatch
-
- [Python]
-
- - Add the -fastinit option to enable faster __init__
- methods. Setting 'this' as 'self.this.append(this)' in the python
- code confuses PyLucene. Now the initialization is done in the
- the C++ side, as reported by Andi and Robin.
-
- - Add the -fastquery option to enable faster SWIG_TypeQuery via a
- python dict cache, as proposed by Andi Vajda
-
- - Avoid to call PyObject_GetAttr inside SWIG_Python_GetSwigThis,
- since this confuses PyLucene, as reported by Andi Vajda.
-
-03/02/2006: wsfulton
- [Java]
- Removed extra (void *) cast when casting pointers to and from jlong as this
- was suppressing gcc's "dereferencing type-punned pointer will break strict-aliasing rules"
- warning. This warning could be ignored in versions of gcc prior to 4.0, but now the
- warning is useful as gcc -O2 and higher optimisation levels includes -fstrict-aliasing which
- generates code that doesn't work with these casts. The assignment is simply never made.
- Please use -fno-strict-aliasing to both suppress the warning and fix the bad assembly
- code generated. Note that the warning is only generated by the C compiler, but not
- the C++ compiler, yet the C++ compiler will also generate broken code. Alternatively use
- -Wno-strict-aliasing to suppress the warning for gcc-3.x. The typemaps affected
- are the "in" and "out" typemaps in java.swg and arrays_java.swg. Users ought to fix
- their own typemaps to do the same. Note that removal of the void * cast simply prevents
- suppression of the warning for the C compiler and nothing else. Typical change:
-
- From:
- %typemap(in) SWIGTYPE * %{ $1 = *($&1_ltype)(void *)&$input; %}
- To:
- %typemap(in) SWIGTYPE * %{ $1 = *($&1_ltype)&$input; %}
-
- From:
- %typemap(out) SWIGTYPE * %{ *($&1_ltype)(void *)&$result = $1; %}
- To:
- %typemap(out) SWIGTYPE * %{ *($&1_ltype)&$result = $1; %}
-
-03/02/2006: mkoeppe
- [Guile -scm]
- Add typemaps for "long long"; whether the generated code compiles, however, depends
- on the version and configuration of Guile.
-
-03/02/2006: wsfulton
- [C#]
- Add support for inner exceptions. If any of the delegates are called which construct
- a pending exception and there is already a pending exception, it will create the new
- exception with the pending exception as an inner exception.
-
-03/02/2006: wsfulton
- [Php]
- Added support for Php5 exceptions if compiling against Php5 (patch from Olly Betts).
-
-03/01/2006: mmatus
- Use the GCC visibility attribute in SWIGEXPORT.
-
- Now you can compile (with gcc 3.4 or later) using
- CFLAGS="-fvisibility=hidden".
-
- Check the difference for the 'std_containers.i' python
- test case:
-
- Sizes:
-
- 3305432 _std_containers.so
- 2383992 _std_containers.so.hidden
-
- Exported symbols (nm -D <file>.so | wc -l):
-
- 6146 _std_containers.so
- 174 _std_containers.so.hidden
-
- Execution times:
-
- real 0m0.050s user 0m0.039s sys 0m0.005s _std_containers.so
- real 0m0.039s user 0m0.026s sys 0m0.007s _std_containers.so.hidden
-
- Read http://gcc.gnu.org/wiki/Visibility for more details.
-
-
-02/27/2006: mutandiz
- [allegrocl]
- Add support for INPUT, OUTPUT, and INOUT typemaps.
- For OUTPUT variables, the lisp wrapper returns multiple
- values.
-
-02/26/2006: mmatus
-
- [Ruby] add argcargv.i library file.
-
- Use it as follow:
-
- %include argcargv.i
-
- %apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
-
- %inline {
- int mainApp(size_t argc, const char **argv)
- {
- return argc;
- }
- }
-
- then in the ruby side:
-
- args = ["asdf", "asdf2"]
- n = mainApp(args);
-
-
- This is the similar to the python version Lib/python/argcargv.i
-
-02/24/2006: mgossage
-
- Small update Lua documents on troubleshooting problems
-
-02/22/2006: mmatus
-
- Fix all the errors reported for 1.3.28.
- - fix bug #1158178
- - fix bug #1060789
- - fix bug #1263457
- - fix 'const char*&' typemap in the UTL, reported by Geoff Hutchison
- - fixes for python 2.1 and the runtime library
- - fix copyctor + template bug #1432125
- - fix [ 1432152 ] %rename friend operators in namespace
- - fix gcc warning reported by R. Bernstein
- - avoid assert when finding a recursive scope inheritance,
- emit a warning in the worst case, reported by Nitro
- - fix premature object deletion reported by Paul in tcl3d
- - fix warning reported by Nitro in VC7
- - more fixes for old Solaris compiler
- - fix for python 2.3 and gc_refs issue reported by Luigi
- - fix fastproxy for methods using kwargs
- - fix overload + protected member issue reported by Colin McDonald
- - fix seterrormsg as reported by Colin McDonald
- - fix directors, now the test-suite runs again using -directors
- - fix for friend operator and Visual studio and bug 1432152
- - fix bug #1435090
- - fix using + %extend as reported by William
- - fix bug #1094964
- - fix for Py_NotImplemented as reported by Olly and Amaury
- - fix nested namespace issue reported by Charlie
-
- and also:
-
- - allow director protected members by default
- - delete extra new lines in swigmacros[UTL]
- - cosmetic for generated python code
- - add the factory.i library for UTL
- - add swigregister proxy method and move __repr__ to a
- single global module [python]
-
-02/22/2006: mmatus
-
- When using directors, now swig will emit all the virtual
- protected methods by default.
-
- In previous releases, you needed to use the 'dirprot'
- option to achieve the same.
-
- If you want, you can disable the new default behaviour,
- use the 'nodirprot' option:
-
- swig -nodirprot ...
-
- and/or the %nodirector feature for specific methods, i.e.:
-
- %nodirector Foo::bar;
-
- struct Foo {
- virtual ~Foo();
-
- protected:
- virtual void bar();
- };
-
-
- As before, pure abstract protected members are allways
- emitted, independent of the 'dirprot/nodirprot' options.
-
-
-02/22/2006: mmatus
- Add the factory.i library for languages using the UTL (python,tcl,ruby,perl).
-
- factory.i implements a more natural wrap for factory methods.
-
- For example, if you have:
-
- ---- geometry.h --------
- struct Geometry {
- enum GeomType{
- POINT,
- CIRCLE
- };
-
- virtual ~Geometry() {}
- virtual int draw() = 0;
-
- //
- // Factory method for all the Geometry objects
- //
- static Geometry *create(GeomType i);
- };
-
- struct Point : Geometry {
- int draw() { return 1; }
- double width() { return 1.0; }
- };
-
- struct Circle : Geometry {
- int draw() { return 2; }
- double radius() { return 1.5; }
- };
-
- //
- // Factory method for all the Geometry objects
- //
- Geometry *Geometry::create(GeomType type) {
- switch (type) {
- case POINT: return new Point();
- case CIRCLE: return new Circle();
- default: return 0;
- }
- }
- ---- geometry.h --------
-
-
- You can use the %factory with the Geometry::create method as follows:
-
- %newobject Geometry::create;
- %factory(Geometry *Geometry::create, Point, Circle);
- %include "geometry.h"
-
- and Geometry::create will return a 'Point' or 'Circle' instance
- instead of the plain 'Geometry' type. For example, in python:
-
- circle = Geometry.create(Geometry.CIRCLE)
- r = circle.radius()
-
- where 'circle' now is a Circle proxy instance.
-
-
-02/17/2006: mkoeppe
- [MzScheme] Typemaps for all integral types now accept the full range of integral
- values, and they signal an error when a value outside the valid range is passed.
- [Guile] Typemaps for all integral types now signal an error when a value outside
- the valid range is passed.
-
-02/13/2006: mgossage
- [Documents] updated the extending documents to give a skeleton swigging code
- with a few typemaps.
- [Lua] added an extra typemap for void* [in], so a function which requires a void*
- can take any kind of pointer
-
-Version 1.3.28 (February 12, 2006)
-==================================
-
-02/11/2006: mmatus
- Fix many issues with line counting and error reports.
-
-02/11/2006: mmatus
- [Python] Better static data member support, if you have
-
- struct Foo {
- static int bar;
- };
-
- then now is valid to access the static data member, ie:
-
- f = Foo()
- f.bar = 3
-
- just as in C++.
-
-
-02/11/2006: wsfulton
- [Perl]
- Fixed code generation to work again with old versions of Perl
- (5.004 and later tested)
-
-02/04/2006: mmatus
- [Python] Add the %extend_smart_pointer() directive to extend
- SWIG smart pointer support in python.
-
- For example, if you have a smart pointer as:
-
- template <class Type> class RCPtr {
- public:
- ...
- RCPtr(Type *p);
- Type * operator->() const;
- ...
- };
-
- you use the %extend_smart_pointer directive as:
-
- %extend_smart_pointer(RCPtr<A>);
- %template(RCPtr_A) RCPtr<A>;
-
- then, if you have something like:
-
- RCPtr<A> make_ptr();
- int foo(A *);
-
- you can do the following:
-
- a = make_ptr();
- b = foo(a);
-
- ie, swig will accept a RCPtr<A> object where a 'A *' is
- expected.
-
- Also, when using vectors
-
- %extend_smart_pointer(RCPtr<A>);
- %template(RCPtr_A) RCPtr<A>;
- %template(vector_A) std::vector<RCPtr<A> >;
-
- you can type
-
- a = A();
- v = vector_A(2)
- v[0] = a
-
- ie, an 'A *' object is accepted, via implicit conversion,
- where a RCPtr<A> object is expected. Additionally
-
- x = v[0]
-
- returns (and sets 'x' as) a copy of v[0], making reference
- counting possible and consistent.
-
- %extend_smart_pointer is just a collections of new/old
- tricks, including %typemaps and the new %implicitconv
- directive.
-
-02/02/2006: mgossage
- bugfix #1356577, changed double=>lua_number in a few places.
- added the std::pair wrapping
-
-01/30/2006: wsfulton
- std::string and std::wstring member variables and global variables now use
- %naturalvar by default, meaning they will now be wrapped as expected in all languages.
- Previously these were wrapped as a pointer rather than a target language string.
- It is no longer necessary to add the following workaround to wrap these as strings:
-
- %apply const std::string & { std::string *}
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-01/28/2006: mkoeppe
- [Guile -scm]
- Add typemaps for handling of member function pointers.
-
-01/24/2006: mmatus
- - Better support for the %naturalvar directive, now it
- works with the scripting languages as well as
- Java/C#.
-
- Now, it can also be applied to class types:
-
- %naturalvar std::string;
- %include <std_string.i>
-
- that will tell swig to use the 'natural' wrapping
- mechanism to all std::string global and member
- variables.
-
- - Add support for the %allowexcept feature along the
- scripting languages, which allows the %exception feature
- to be applied to the variable access methods. Also, add
- the %exceptionvar directive to specify a distintic
- exception mechanism only for variables.
-
-
- - Add more docs for the %delobject directive to mark a method as a
- destructor, 'disowning' the first argument. For example:
-
- %newobject create_foo;
- %delobject destroy_foo;
-
- Foo *create_foo() { return new Foo(); }
- void destroy_foo(Foo *foo) { delete foo; }
-
- or in a member method as:
-
- %delobject Foo::destroy;
-
- class Foo {
- public:
- void destroy() { delete this;}
-
- private:
- ~Foo();
- };
-
-
-01/24/2006: mgossage
- [Lua]
- - Removed the type swig_lua_command_info & replace with luaL_reg
- (which then broke the code), fixed this
- - added an additional cast in the typemaps for enum's
- due to the issue that VC.Net will not allow casting of
- a double to an enum directly. Therefore cast to int then to enum
- (thanks to Jason Rego for this observation)
-
-01/16/2006: mmatus (Change disabled... will be back in CVS soon)
- Add initial support for regexp via the external library
- RxSpencer. SWIG doesn't require this library to compile
- and/or run. But if you specify --with-rxspencer, and the
- library is found during installation, then swig will use
- it in three places:
-
- - In %renames rules, via the new rxsmatch rules, for example:
-
- %rename("%(lowercase)",rxsmatch$name="GSL_.*") "";
- %rename("%(lowercase)",rxsmatch$nodeType="enum GSL_.*") "";
-
- rxsmatch is similar to the match rule, it just uses
- the RxSpencer regexp library to decide if there is a
- match with the provided regexp. As with the match
- rule, you can also use the negate rule notrxsmatch.
-
- - In the %rename target name via the rxstarget option, for example:
-
- %rename("%(lowercase)",rxstarget=1) "GSL_.*";
-
- where the target name "GSL.*" is now understood as a
- regexp to be matched.
-
- - In the new encoder "rxspencer", which looks like:
-
- %(rxspencer:[regexp][replace])s
-
- where "regexp" is the regular expression and "replace"
- is a string used as a replacement, where the @0,@1,...,@9
- pseudo arguments are used to represent the
- corresponding matching items in the reg expression.
-
- For example:
-
- %(rxspencer:[GSL.*][@0])s <- Hello ->
- %(rxspencer:[GSL.*][@0])s <- GSLHello -> GSLHello
- %(rxspencer:[GSL(.*)][@1])s <- GSLHello -> Hello
- %(rxspencer:[GSL(.*)][gsl@1])s <- GSLHello -> gslHello
-
- Another example could be:
-
- %rename("%(lowercase)s",sourcefmt="%(rxspencer:[GSL_(.*)][@1])s",%$isfunction) "";
-
- which take out the prefix "GSL_" and returns all the
- function names in lower cases, as following:
-
- void GSL_Hello(); -> hello();
- void GSL_Hi(); -> hi();
- const int GSL_MAX; -> GSL_MAX; // no change, is not a function
-
- We use the RxSpencer as an initial test bed to
- implemention while we decide which library will be
- finally added to swig.
-
- You can obtain the RxSpencer library from
-
- http://arglist.com/regex (Unix)
-
- or
-
- http://gnuwin32.sourceforge.net/packages.html (Windows)
-
- Once installed, use "man rxspencer" to get more info
- about the regexp format, or just google rxspencer.
-
- Since now you can enable the rxsmatch rules (see above),
- the simple or '|' support for the match rules
- (01/12/2006: mmatus) is disabled. Still, if you have
- problems with the rxspencer library, you can re-enable
- the simple 'match or' support using
- -DSWIG_USE_SIMPLE_MATCHOR.
-
-
-01/16/2006: mmatus
- Change the %rename predicates to use the prefix '%$', as in:
-
- %rename("%(utitle)s",%$isfunction,%$ismember) "";
-
- to avoid clashes with other swig macros/directives.
-
-01/14/2006: cfisavage
- [Ruby]
- Added support for Ruby bang! methods via a new %bang feature.
- Bang methods end in exclamation points and indicate that the
- object being processed will be modified in-place as
- opposed to being copied.
-
-01/12/2006: cfisavage
- [Ruby]
- Updated the Ruby module to automatically convert
- method names to lower_case_with_underscores using the
- new %rename functionality.
-
-01/12/2006: mmatus
- - Add aliases for 'case' encoders used with %rename/%namewarn
-
- %(uppercase)s hello_world -> HELLO_WORLD
- %(lowercase)s HelloWorld -> helloworld
- %(camelcase)s hello_world -> HelloWorld
- %(undercase)s HelloWorld -> hello_world
-
-
-01/12/2006: mmatus
- - Add the -dump_parse_module and -dump_parse_top options,
- which are similar to -dump_module and -dump_top, but they
- dump the node trees just after parsing, showing only the
- attributes visible at the parsing stage, and not the added
- later in typemap.cxx, allocate.cxx, lang.cxx or elsewhere.
-
- Besides debugging porpuses, these options are very useful
- if you plan to use %rename in an "advance way", since it
- shows only and all the node's attributes you can use
- inside the match rules.
-
-
-01/12/2006: mmatus
- - Add predicates to %rename, so, you don't need to
- remember, for example, how to match a member function.
-
- Now it is easy, for example to use the 'utitle' encoder
- in all the member methods, you type:
-
- %rename("%(utitle)s",%isfunction,%ismember) "";
-
- or to ignore all the enumitems in a given class:
-
- %rename("$ignore", %isenumitem, %classname="MyClass") "";
-
- Available predicates are (see swig.swg):
-
- %isenum
- %isenumitem
- %isaccess
- %isclass
- %isextend
- %isextend
- %isconstructor
- %isdestructor
- %isnamespace
- %istemplate
- %isconstant
-
- %isunion
- %isfunction
- %isvariable
- %isimmutable
-
- %isstatic
- %isfriend
- %istypedef
- %isvirtual
- %isexplicit
- %isextern
-
- %ismember
- %isglobal
- %innamespace
-
- %ispublic
- %isprotected
- %isprivate
-
- %classname
-
- These predicates correspond to specific 'match'
- declarations, which sometimes are not as evident as the
- predicates names.
-
-
- - Add the or '|' operation in %rename match, for
- example to capitalize all the constants (%constant or
- const cdecl):
-
- %rename("%(upper)s",match="cdecl|constant",%isimmutable) "";
-
-
-
-01/12/2006: mgossage
- - Partial fixed of errors under C89, bug #1356574
- (converted C++ style comments to C style)
- - Added patches from neomantra@users.sf.net #1379988 and #1388343
- missing a 'return' statement for error conditions
- also updated the %init block bug #1356586
-
-01/10/2006: mmatus
- - Add the 'utitle' encoder, as an example of how to add
- your own encoder. I added the encoder method in misc.c
- but developers can add others, the same way, inside any
- target language.
-
- Well, 'utitle' is the reverse of 'ctitle', ie:
-
- %rename("%(ctitle)s") camel_case; -> CamelCase;
- %rename("%(utitle)s") CamelCase; -> camel_case;
-
-
-01/10/2006: cfisavage
- [Ruby]
- Updated Ruby Exception handling. Classes that are specified in throws clauses,
- or are marked as %exceptionclass, are now inherited from rb_eRuntimeError.
- This allows instances of these classes to be returned to Ruby as exceptions.
- Thus if a C++ method throws an instance of MyException, the calling Ruby
- method will get back a MyException object. To see an example,
- look at ruby/examples/exception_class.
-
-01/10/2006: mmatus
-
- - Add the %catches directive, which complements the %exception
- directive in a more automatic way. For example, if you have
-
- int foo() throw(E1);
-
- swig generates the proper try/catch code to dispatch E1.
-
- But if you have:
-
-
- int barfoo(int i) {
- if (i == 1) {
- throw E1();
- } else {
- throw E2();
- }
- return 0;
- }
-
- ie, where there is no explicit exception specification in the decl, you
- end up doing:
-
- %exception barfoo {
- try {
- $action
- } catch(E1) { ... }
- } catch(E2) { ... }
- }
-
- which is very tedious. Well, the %catches directive defines
- the list of exceptions to catch, and from swig:
-
- %catches(E1,E2) barfoo(int i);
- int barfoo(int i);
-
- is equivalent to
-
- int barfoo(int i) throw(E1,E2);
-
- Note, however, that the %catches list doesn't have to
- correspond to the C++ exception specification. For example, if you
- have:
-
- struct E {};
- struct E1 : E {};
- struct E2 : E {};
-
- int barfoo(int i) throw(E1,E2);
-
- you can define
-
- %catches(E) barfoo(int i);
-
- and swig will generate an action code equivalent to
-
- try {
- $action
- } catch(E &_e) {
- <raise _e>;
- }
-
- Of course, you still have to satisfy the C++ restrictions,
- and the catches list must be compatible (not the same)
- as the original list of types in the exception specification.
-
- Also, you can now specify that you want to catch the
- unknown exception '...', for example:
-
- %catches(E1,E2,...) barfoo(int);
-
- In any case, the %catches directive will emit the
- code to convert into the target language error/exception
- using the 'throws' typemap.
-
- For the '...' case to work, you need to
- write the proper typemap in your target language. In the
- UTL, this looks like:
-
- %typemap(throws) (...) {
- SWIG_exception(SWIG_RuntimeError,"unknown exception");
- }
-
-01/09/2006: mutandiz
- [Allegrocl]
-
- Fixes a number of SEGVs primarily in the handling of
- various anonymous types. Found in a pass through the
- swig test-suite. Still more to do here, but this is a
- good checkpoint.
-
- Adds -cwrap and -nocwrap as an allegrocl specific
- command-line argument. Controls generating of a C
- wrapper file when wrapping C code. By default only a
- lisp file is created for C code wrapping.
-
- Doc updates for the command-line arguments and fixes as
- pointed out on swig-devel
-
-01/05/2006: wsfulton
- [Java] Fix unsigned long long and const unsigned long long & typemaps
- - Bug #1398394 with patch from Dries Decock
-
-01/06/2006: mmatus
- Add 'named' warning codes, now in addition to:
-
- %warnfilter(813);
-
- you can use
-
- %warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE);
-
- just use the same code name found in Source/Include/swigwarn.h
- plus the 'SWIG' prefix.
-
- If a developer adds a new warning code, the Lib/swigwarn.swg file
- will be generated when running the top level make.
-
-01/05/2006: cfisavage
- [Ruby]
- Reimplemented object tracking for Ruby. The new implementation works
- by expanding the swig_class structure for Ruby by adding a trackObjects
- field. This field can be set/unset via %trackobjects as explained
- in the Ruby documentation. The new implementation is more robust
- and takes less code to implement.
-
-01/05/2006: wsfulton
- Fix for %extend and static const integral types, eg:
-
- class Foo {
- public:
- %extend {
- static const int bar = 42;
- }
- };
-
-12/30/2005: mmatus
-
- - Add info for old and new debug options:
-
- -dump_top - Print information of the entire node tree, including system nodes
- -dump_module - Print information of the module node tree, avoiding system nodes
- -dump_classes - Print information about the classes found in the interface
- -dump_typedef - Print information about the types and typedefs found in the interface
- -dump_tags - Print information about the tags found in the interface
- -debug_typemap - Print information for debugging typemaps
- -debug_template - Print information for debugging templates
-
- - Add the fakeversion. If you have a project that uses
- configure/setup.py, or another automatic building system
- and requires a specific swig version, let say 1.3.22
- you can use:
-
- SWIG_FEATURES="-fakeversion 1.3.22"
-
- or
-
- swig -fakeversion 1.3.22
-
- and then swig -version will report 1.3.22 instead of the
- current version.
-
- Typical use would be
-
- SWIG_FEATURES="-fakeversion 1.3.22" ./configure
-
-12/30/2005: mmatus
-
- - Add option/format support to %rename and %namewarn.
- Now %namewarn can force renaming, for example:
-
- %namewarn("314: import is a keyword",rename="_%s") "import";
-
- and rename can also support format forms:
-
- %rename("swig_%s") import;
-
- Now, since the format is processed via swig Printf, you
- can use encoders as follows:
-
- %rename("%(title)s") import; -> Import
- %rename("%(upper)s") import; -> IMPORT
- %rename("%(lower)s") Import; -> import
- %rename("%(ctitle)s") camel_case; -> CamelCase
-
- This will allow us to add more encoders, as the
- expected one for regular expressions.
-
- - Add the above 'ctitle' encoder, which does the camel case:
-
- camel_case -> CamelCase
-
- - Also, while we get the regexp support, add the 'command' encoder,
- you can use it as follows
-
- %rename("%(command:sed -e 's/\([a-z]\)/\U\\1/' <<< )s") import;
-
- then swig will popen the command
-
- "sed -e 's/\([a-z]\)/\U\\1/' <<< import"
-
- see below for anonymous renames for better examples.
-
- - The rename directive now also allows:
-
- - simple match: only apply the rename if a type match
- happen, for example
-
- %rename(%(title)s,match="enumitem") hello;
-
- enum Hello {
- hi, hello -> hi, Hello
- };
- int hello() -> hello;
-
- - extended match: only apply the rename if the 'extended attribute' match
- occurred, for example:
-
- // same as simple match
- %rename(%(title)s,match$nodeType="enumitem") hello;
-
- enum Hello {
- hi, hello -> hi, Hello
- };
-
- Note that the symbol '$' is used to define the attribute name in
- a 'recursive' way, for example:
-
- // match only hello in 'enum Hello'
- %rename(%(title)s,match$parentNode$type="enum Hello") hello;
-
- enum Hello {
- hi, hello -> hi, Hello // match
- };
-
- enum Hi {
- hi, hello -> hi, hello // no match
- };
-
- here, for Hello::hi, the "parentNode" is "Hello", and its "type"
- is "enum Hello".
-
-
- - Anonymous renames: you can use 'anonymous' rename directives, for example:
-
- // rename all the enum items in Hello
- %rename(%(title)s,match$parentNode$type="enum Hello") "";
-
- enum Hello {
- hi, hello -> Hi, Hello // match both
- };
-
- enum Hi {
- hi, hello -> hi, hello // no match
- };
-
- // rename all the enum items
- %rename(%(title)s,match$nodeType="enumitem") "";
-
- // rename all the items in given command (sloooow, but...)
- %rename(%(command:<my external cmd>)s) "";
-
-
- Anonymous renames with commands can be very powerful, since you
- can 'outsource' all the renaming mechanism (or part of it) to an
- external program:
-
- // Uppercase all (and only) the names that start with 'i'
- %rename("%(command:awk '/^i/{print toupper($1)}' <<<)s") "";
-
- int imported() -> IMPORTED;
- int hello() -> hello
-
- Note that if the 'command' encoder returns an empty string, swig
- understands that no rename is necessary.
-
- Also note that %rename 'passes' the matched name. For example, in
- this case
-
- namespace ns1 {
- int foo();
- }
-
- namespace ns2 {
- int bar();
- }
-
- the external program only receives "foo" and "bar". If needed,
- however, you can request the 'fullname'
-
- %rename("%(command:awk 'awk '/ns1::/{l=split($1,a,"::"); print toupper(a[l])}'' <<<)s",fullname=1) "";
-
- ns1::foo -> FOO
- ns2::bar -> bar
-
- - Mixing encoders and matching: of course, you can do mix commands
- and match fields, for example:
-
- %rename("%(<my encoder for fncs>)",match="cdecl") "";
- %rename("%(<my encoder for enums>)",match="enumitem") "";
- %rename("%(<my encoder for enums inside a class>)",match="enumitem",
- match$parentNode$parentNode$nodeType="class") "";
-
- Use "swig -dump_parse_module" to see the attribute names you can use to
- match a specific case.
-
- - 'sourcefmt' and 'targetfmt': sometimes you need to
- process the 'source' name before comparing, for example
-
- %namewarn("314: empty is a keyword",sourcefmt="%(lower)s") "empty";
-
- then if you have
-
- int Empty(); // "Empty" is the source
-
- you will get the keyword warning since 'Empty' will be
- lower cased, via the sourcefmt="%(lower)s" option,
- before been compared to the 'target' "empty".
-
- There is an additional 'targetfmt' option to process the
- 'target' before comparing.
-
- - complementing 'match': you can use 'notmatch', for example
-
- %namewarn("314: empty is a keyword",sourcefmt="%(lower)s",notmatch="namespace") "empty";
-
- here, the name warning will be applied to all the symbols except namespaces.
-
-
-12/30/2005: mmatus
-
- - Add initial support for gcj and Java -> <target language> mechanism.
-
- See examples in:
-
- Examples/python/java
- Examples/ruby/java
- Examples/tcl/java
-
- to see how to use gcj+swig to export java classes into
- python/ruby/tcl.
-
- The idea is to put all the common code for gcj inside
-
- Lib/gcj
-
- and localize specific types such as jstring, as can be found
- in
-
- Lib/python/jstring.i
- Lib/ruby/jstring.i
- Lib/tcl/jstring.i
-
- Using the UTL, this is very easy, and the perl version for
- jstring.i will be next.
-
-
-12/29/2005: mmatus
- - Add the copyctor feature/directive/option to enable the automatic
- generation of copy constructors. Use as in:
-
- %copyctor A;
-
- struct A {
-
- };
-
- then this will work
-
- a1 = A();
- a2 = A(a1);
-
- Also, since it is a feature, if you just type
-
- %copyctor;
-
- that will enable the automatic generation for all the
- classes. It is also equivalent to
-
- swig -copyctor -c++ ...
-
- Notes:
-
- 1.- The feature only works in C++ mode.
-
- 2.- The automatic creation of the copy constructor will
- usually produce overloading. Hence, if the target
- language doesn't support overloading, a special name
- will be used (A_copy).
-
- 3.- For the overloading reasons above, it is probably not
- a good idea to use the flag when, for example, you are
- using keywords in Python.
-
- 4.- The copyctor automatic mechanism follows more or less
- the same rules as the default constructor mechanism,
- i.e., a copy constructor will not be added if the
- class is abstract or if there is a pertinent non-public
- copy ctor in the class or its hierarchy.
-
- Hence, it might be necessary for you to complete the
- class declaration with the proper non-public copy ctor
- to avoid a wrong constructor addition.
-
- - Fix features/rename for templates ctor/dtor and other
- things around while adding the copyctor mechanism.
-
-
-12/27/2005: mmatus
- - Add the 'match' option to typemaps. Assume you have:
-
- %typemap(in) SWIGTYPE * (int res) {..}
- %typemap(freearg) SWIGTYPE * { if (res$argnum) ...}
-
- then if you do
-
- %typemap(in) A * {...}
-
- swig will 'overload the 'in' typemap, but the 'freearg'
- typemap will be also applied, even when this is wrong. The old
- solutions is to write:
-
- %typemap(in) A * {...}
- %typemap(freeag) A * ""
-
- overload 'freearg' with an empty definition.
-
- The problem is, however, there is no way to know you need
- to do that until you start getting broken C++ code, or
- worse, broken runtime code.
-
- The same applies to the infamous 'typecheck' typemap,
- which always confuses people, since the first thing you do
- is to just write the 'in' typemap.
-
- The 'match' option solves the problem, and if instead you write:
-
- %typemap(in) SWIGTYPE * (int res) {..}
- %typemap(freearg,match="in") SWIGTYPE * { if (res$argnum) ...}
- %typemap(typecheck,match="in",precedence...) SWIGTYPE * {...}
-
- it will tell swig to apply the 'freearg/typecheck'
- typemaps only if they 'match' the type of the 'in'
- typemap. The same can be done with other typemaps as:
-
- %typemap(directorout) SWIGTYPE * {...}
- %typemap(directorfree,match="directorout") SWIGTYPE * {...}
-
-
-12/27/2005: mmatus
- - Add the 'naturalvar' option/mode/feature to treat member
- variables in a more natural way, ie, similar to the global
- variable behavior.
-
- You can use it in a global way via the command line
-
- swig -naturalvar ...
-
- or the module mode option
-
- %module(naturalvar=1)
-
- both forms make swig treat all the member variables in the
- same way it treats global variables.
-
- Also, you can use it in a case by case approach for
- specific member variables using the directive form:
-
- %naturalvar Bar::s;
-
- Then, in the following case for example:
-
- std::string s;
- struct Bar {
- std::string s;
- };
-
- you can do:
-
- b = Bar()
- b.s ="hello"
- cvar.s = "hello"
-
- if (b.s != cvar.s):
- raise RuntimeError
-
-
- This is valid for all the languages, and the
- implementation is based on forcing the use of the
- const SWIGTYPE& (C++)/SWIGTYPE (C) typemaps for the
- get/set methods instead of the SWIGTYPE * typemaps.
- Hence, for 'naturalvar' to work, each target language
- must implement 'typemap(in/out) const Type&' properly.
-
- The 'naturalvar' option replaces or makes workarounds such as:
-
- %apply const std::string & { std::string *}
-
- unnecessary.
-
- Note1: If your interface has other kinds of workarounds to
- deal with the old 'unnatural' way to deal with member
- variables (returning/expecting pointers), the
- 'naturalvar' option could break them.
-
- Note2: the option has no effect on unnamed types, such
- as unnamed nested unions.
-
-
-12/27/2005: mmatus
- - Add more 'expressive' result states for the typemap
- libraries.
-
- In the past, for scripting languages, you would do checking something like:
-
- if (ConvertPtr(obj,&vptr,ty,flags) != -1) {
- // success
- } else {
- // error
- }
-
- Now the result state can carry more information,
- including:
-
- - Error state: like the old -1/0, but with error codes from swigerrors.swg.
-
- int res = ConvertPtr(obj,&vptr,ty,flags);
- if (SWIG_IsOK(res)) {
- // success code
- } else {
- SWIG_Error(res); // res carries the error code
- }
-
- - Cast rank: when returning a simple successful
- conversion, you just return SWIG_OK, but if you need
- to do a 'cast', you can add the casting rank, ie:
-
- if (PyFloat_Check(obj)) {
- value = PyFloat_AsDouble(obj);
- return SWIG_OK;
- } else if (PyInt_Check(obj)) {
- value = (double) PyInt_AsLong(obj);
- return SWIG_AddCast(SWIG_OK);
- }
-
- later, the casting rank is used to properly dispatch
- the overloaded function, for example. This of course
- requires your language to support and use the new
- dispatch cast/rank mechanism (Now mainly supported in
- perl and python, and easily expandable to ruby and tcl).
-
- - [UTL] Add support for the new 'expressive' result states.
-
-12/27/2005: mmatus
- - Add support for the C++ implicit conversion mechanism, which
- required some modifications in parser.y (to recognize
- 'explicit') and overload.cxx (to replace $implicitconv as
- needed).
-
- Still, real support in each target language requires each
- target language to be modified. Python provides an example,
- see below.
-
-
- - Add support for native C++ implicit conversions, ie, if you
- have
-
- %implicitconv A;
-
- struct A {
- int ii;
- A() {ii = 1;}
- A(int) {ii = 2;}
- A(double) {ii = 3;}
- explicit A(char *s) {ii = 4;}
- };
-
- int get(const A& a) {return a.ii;}
-
- you can call:
-
- a = A()
- ai = A(1)
- ad = A(1.0)
- as = A("hello")
-
- # old forms
- get(a) -> 1
- get(ai) -> 2
- get(ad) -> 3
- get(as) -> 4
-
- #implicit conversions
- get(1) -> 2
- get(1.0) -> 3
- get("hello") -> Error, explicit constructor
-
- Also, as in C++, now implicit conversions are supported in
- variable assigments, and if you have:
-
- A ga;
- struct Bar {
- A a;
- };
-
- you can do:
-
- cvar.ga = A(1)
- cvar.ga = 1
- cvar.ga = 1.0
- cvar.ga = A("hello")
- cvar.ga = "hello" -> error, explicit constructor
-
- b = Bar()
- b.a = A("hello")
- b.a = 1
- b.a = 1.0
- b.a = "hello" -> error, explicit constructor
-
- Note that the last case, assigning a member var directly,
- also requires the 'naturalvar' option.
-
- This support now makes the old '%implicit' macro, which
- was found in 'implicit.i' and it was fragile in many ways,
- obsolete, and you should use the new '%implicitconv'
- directive instead.
-
- Note that we follow the C++ conventions, ie, in the
- following the implicit conversion is allowed:
-
- int get(A a) {return a.ii;}
- int get(const A& a) {return a.ii;}
-
- but not in these cases:
-
- int get(A *a) {return a->ii;}
- int get(A& a) {return a.ii;}
-
- Also, it works for director methods that return a by value
- result, ie, the following will work:
-
- virtual A get_a() = 0;
-
- def get_a(self):
- return 1
-
- but not in this case:
-
- virtual const A& get_a() = 0;
- virtual A& get_a() = 0;
- virtual A* get_a() = 0;
-
- Notes:
-
- - the implicitconv mechanism is implemented by directly
- calling/dispatching the python constructor, triggering a
- call to the __init__method. Hence, if you expanded the
- __init__ method, like in:
-
- class A:
- def __init__(self,args):
- <swig code>
- <my code here>
-
- then 'my code' will also be executed.
-
- - Since the %implicitconv directive is a SWIG feature, if you type:
-
- %implicitconv;
-
- that will enable implicit conversion for all the classes in
- your module.
-
- But if you are worried about performance, maybe that will be
- too much, especially if you have overloaded methods, since
- to resolve the dispatching problem, python will efectively
- try to call all the implicit constructors as needed.
-
- - For the same reason, it is highly recommended that you use
- the new 'castmode' when mixing implicit conversion and
- overloading.
-
- - [python] The %implicit directive is declared obsolete, and
- you should use %implicitconv instead. If you include
- the implicit.i file, a warning will remind you of this.
-
- Note: Since %implicit is fragile, just replacing it by
- %implicitconv could lead to different behavior. Hence, we
- don't automatically switch from to the other, and the user
- must migrate to the new %implicitconv directive manually.
-
-
-12/26/2005: wsfulton
- [C#]
- Modify std::vector wrappers to use std::vector::value_type as this is
- closer to the real STL declarations for some methods, eg for push_back().
- Fixes some compilation errors for some compilers eg when the templated
- type is a pointer.
-
- [Java]
- std::vector improvements - a few more methods are wrapped and specializations are
- no longer required. The specialize_std_vector macro is no longer needed (a
- warning is issued if an attempt is made to use it).
-
-12/26/2005: wsfulton
- [Java, C#]
- Add in pointer reference typemaps. This also enables one to easily wrap
- std::vector<T> where T is a pointer.
-
-12/24/2005: efuzzyone
- [CFFI] The cffi module for SWIG:
- - Fully supports C, but provides limited supports for C++, in
- particular C++ support for templates and overloading needs to
- be worked upon.
-
-12/23/2005: mmatus
- [python] Add the castmode that allows the python
- type casting to occur.
-
- For example, if you have 'int foo(int)', now
-
- class Ai():
- def __init__(self,x):
- self.x = x
- def __int__(self):
- return self.x
-
- foo(1) // Ok
- foo(1.0) // Ok
- foo(1.3) // Error
- a = Ai(4)
- foo(ai) // Ok
-
- The castmode, which can be enabled either with the
- '-castmode' option or the %module("castmode") option, uses
- the new cast/rank dispatch mechanism. Hence, now if you
- have 'int foo(int); int foo(double);', the following works
- as expected:
-
- foo(1) -> foo(int)
- foo(1.0) -> foo(double)
- ai = Ai(4)
- foo(ai) -> foo(int)
-
- Note1: the 'castmode' could disrupt some specialized
- typemaps. In particular, the "implicit.i" library seems to
- have problem with the castmode. But besides that one, the
- entire test-suite compiles fine with and without the
- castmode.
-
- Note2: the cast mode can't be combined with the fast
- dispatch mode, ie, the -fastdispatch option has no effect
- when the cast mode is selected. The penalties, however,
- are minimum since the cast dispatch code is already based
- on the same fast dispatch mechanism.
-
- See the file overload_dispatch_cast_runme.py file for
- new cases and examples.
-
-12/22/2005: mmatus
- Add the cast and rank mechanism to dispatch overloading
- functions. The UTF supports it now, but for each language
- it must be decided how to implement and/or when to use it.
-
- [perl] Now perl uses the new cast and rank dispatch
- mechanism, which solves all the past problems known
- in perl, such as the old '+ 1' problem:
-
- int foo(int);
-
- $n = 1
- $n = $n + 1
- $r = foo(n)
-
- also works:
-
- foo(1);
- foo("1");
- foo(1.0);
- foo("1.0");
-
- but fails
-
- foo("l");
-
- and when overloading foo(int) and foo(double);
-
- foo(1) -> foo(int)
- foo(1.0) -> foo(double)
- foo("1") -> foo(int)
- foo("1.0") -> foo(double)
- foo("l") -> error
- foo($n) -> foo(int) for good perl versions
- foo($n) -> foo(double) for old bad perl versions
-
- when overloading foo(int), foo(char*) and foo(double):
-
- foo(1) -> foo(int)
- foo(1.0) -> foo(double)
- foo("1") -> foo(char*)
- foo("1.0") -> foo(char*)
- foo("l") -> foo(char*)
-
- Note: In perl the old dispatch mechanism was broken,
- so, we don't provide an option to enable the old one
- since, again, it was really really broken.
-
- See 'overload_simple_runme.pl' for more cases and tests.
-
- PS: all the old known issues are declared resolved, any
- new "problem" that could be discovered is declared,
- a priori, as "features" of the new dispatch mechanism
- (until we find another solution at least).
-
-
- *** POTENTIAL INCOMPATIBILITY ***
-
- As with the introduction of the UTF, some things could
- now start to work as expected, and people used to deal or
- workaround previous bugs related to the dispatch
- mechanism, could see now a difference in perl behavior.
-
-12/21/2005: mmatus
- - The '-nodefault' flag (pragma and feature) now generates
- a warning, and recommends to use the explicit
- -nodefaultctor and -nodefaultdtor options.
-
- The reason to split the 'nodefault' behavior is that, in
- general, ignoring the default destructor generates memory
- leaks in the target language. Hence, is too risky just to
- disable both the default constructor and destructor
- at the same time.
-
- If you need to disable the default destructor, it is
- also recommended you use the directive form:
-
- %nodefaultdtor MyVerySpecialClass;
-
- for specific classes, and always avoid using the global
- -nodefault and -nodefaultdtor options.
-
-12/21/2005: wsfulton
- [Java, C#]
- Fix incorrect code generation when the intermediary classname is changed
- in the module directive from its default. For example:
-
- %module(jniclassname="myimclassnewname") "mymodule" // Java
- %module(imclassname="myimclassnewname") "mymodule" // C#
-
- Add in new special variable $imclassname. See docs.
-
-12/17/2005: mmatus
- [Python]
- - Add the -aliasobj0/-noaliasobj0 options to use with
- -fastunpack and/or -O and old typemaps that use 'obj0'
- directly.
-
- So, if you compile your code using -O and get errors about
- the undeclared 'obj0' variable, run again using
-
- swig -O -aliasobj0 -python ....
-
- For new typemaps, never use 'obj0' directly, if needed,
- use the '$self' name that will be properly expanded to
- 'obj0' (nofastunpack) or 'swig_obj[0]' (fastunpack).
-
- If you have no idea what I am talking about, better, that
- means you have no typemap with this problem.
-
-
-12/14/2005: mmatus
- [Python]
- - Add the -fastunpack/-nofastunpack options to enable/disable
- the use of the internal UnpackTuple method, instead of
- calling the one from the python C API.
-
- The option -O now also implies -fastunpack.
-
-
-12/11/2005: mmatus
- [Python]
- - Add the -proxydel/-noproxydel options to enable/disable
- the generation of proxy/shadow __del__ methods, even
- when now they are redundant, since they are empty.
- However, old interfaces could rely on calling them.
-
- The default behavior is to generate the __del__ methods
- as in 1.3.27 or older swig versions.
-
- The option -O now also implies -noproxydel.
-
-12/10/2005: mmatus
- [UTF]
- - Fix unnecessary calls to SWIG_TypeQuery for 'char *'
- and 'wchar_t *', problem found by Clay Culver while
- profiling the PyOgre project.
-
-
- [Python]
- - Add the -dirvtable/-nodirvtable to enable/disable
- a pseudo virtual table used for directors, avoiding
- the need to resolve the python method at each call.
-
- - Add the -safecstrings/-nosafecstrings options to
- enable/disable the use of safe conversions from PyString
- to char *. Python requires you to never change the internal
- buffer directly, and hence 'safectrings' warranties that
- but returning a copy of the internal python string buffer.
-
- The default, as in previous releases, is to return a
- pointer to the buffer (nosafecstrings), so, it is the user's
- responsibility to avoid its modification.
-
- - Add the -O option to enable all the optimization options
- at once, initially equivalent to
-
- -modern -fastdispatch -dirvtable -nosafecstrings -fvirtual
-
-12/08/2005: mmatus
-
- - Add the -fastdispatch option (fastdispatch feature). This
- enables the "fast dispatch" mechanism for overloaded
- methods provided by Salvador Fandi~no Garc'ia (#930586).
-
- The resulting code is smaller and faster since less type
- checking is performed. However, the error messages you
- get when the overloading is not resolved could be
- different from what the traditional method returns.
-
- With the old method you always get an error such as
-
- "No matching function for overloaded ..."
-
- with the new method you can also get errors such as
-
- "Type error in argument 1 of type ..."
-
- See bug report #930586 for more details.
-
- So, this optimization must be explicitly enabled by users.
-
- The new mechanism can be used as:
-
- swig -fastdispatch
-
- or using the feature form
-
- %feature("fastdispatch") method;
- or
- %fastdispatch method;
-
-
-12/06/2005: mmatus
-
- - Several memory and speed improvements, specially for
- templates. Now swig is up to 20 faster than before for
- large template interfaces, such as the std_containers.i
- and template_matrix.i files in the python test-suite.
-
- Memory footprint is also reduced in consideration of small
- pcs/architectures.
-
- - add commandline options -cpperraswarn and -nocpperraswarn" to force
- the swig preprocessor to treat the #error directive as a #warning.
-
- the pragmas
-
- #pragma SWIG cpperraswarn=1
- #pragma SWIG cpperraswarn=0
-
- are equivalent to the command line options, respectively.
-
-
-12/06/2005: mmatus
- [Python] The generated code is now more portable, especially
- for Windows. Following
-
- http://www.python.org/doc/faq/windows.html
-
- Py_None is never accessed as a structure, plus other
- tricks mentioned there.
-
-12/06/2005: mmatus
- [Python] Added initial support for threads based in the
- proposal by Joseph Winston.
-
- The user interface is as follows:
-
- 1.- the module thread support is enable via the "threads" module
- option, i.e.
-
- %module("threads"=1)
-
- 2.- Equivalent to that, is the new '-threads' swig option
-
- swig -threads -python ...
-
- 3.- You can partially disable thread support for a given
- method using:
-
- %feature("nothread") method;
- or
- %nothread method;
-
- also, you can disable sections of the thread support,
- for example
-
- %feature("nothreadblock") method;
- or
- %nothreadblock method;
-
- %feature("nothreadallow") method;
- or
- %nothreadallow method;
-
- the first disables the C++/python thread protection, and the
- second disables the python/C++ thread protection.
-
- 4.- The current thread support is based in the PyGIL
- extension present in python version 2.3 or later, but
- you can provide the thread code for older versions by
- defining the macros in pythreads.swg.
-
- If you get a working implementation for older versions,
- please send us a patch.
-
- For the curious about performance, here are some numbers
- for the profiletest.i test, which is used to check the speed
- of the wrapped code:
-
- nothread 9.6s (no thread code)
- nothreadblock 12.2s (only 'allow' code)
- nothreadallow 13.6s (only 'block' code)
- full thread 15.5s ('allow' + 'block' code)
-
- i.e., full thread code decreases the wrapping performance by
- around 60%. If that is important to your application, you
- can tune each method using the different 'nothread',
- 'nothreadblock' or 'nothreadallow' features as
- needed. Note that for some methods deactivating the
- 'thread block' or 'thread allow' code is not an option,
- so, be careful.
-
-
-11/26/2005: wsfulton
- SWIG library files use system angle brackets everywhere for %include, eg
- %include "std_common.i"
- becomes
- %include <std_common.i>
-
-11/26/2005: wsfulton
- [Java, C#]
- Typesafe enums and proper enums have an extra constructor so that enum item values that
- are initialised by another enum item value can be wrapped without having to use %javaconstvalue/
- %csconstvalue for when using %javaconst(1)/%csconst(1). Suggestion by
- Bob Marinier/Douglas Pearson.
- For example:
-
- typedef enum
- {
- xyz,
- last = xyz
- } repeat;
-
-11/21/2005: mmatus
- [ruby + python]
-
- Fixes for directors + pointers. This is an ugly problem without an easy
- solution. Before we identified this case as problematic:
-
- virtual const MyClass& my_method();
-
- but it turns out that all the cases where a pointer, array or
- reference is returned, are problematic, even for
- primitive types (as int, double, char*, etc).
-
- To try to fix the issue, a new typemap was added,
- 'directorfree', which is used to 'free' the resources
- allocated during the 'directorout' phase. At the same
- time, a primitive garbage collector engine was added to
- deal with orphaned addresses, when needed.
-
- The situation is much better now, but still it is possible to have
- memory exhaustation if recursion is used.
-
- So, still you need to avoid returning pointers, arrays or
- references when using director methods.
-
- - Added stdint.i - typemaps for latest C99 integral types found in stdint.h.
-
-11/14/2005: wsfulton
- More types added to windows.i, eg UINT8, WORD, BYTE etc.
- Including windows.i will also enable SWIG to parse the __declspec Microsoft
- extension, eg __declspec(dllimport). Also other Windows calling conventions
- such as __stdcall.
-
-11/10/2005: wsfulton
- New library file for Windows - windows.i. This file will contain useful type
- information for users who include windows.h. Initial support is for the
- non ISO integral types: __int8, __int16, __int32, __int64 and unsigned versions.
- The unsigned versions previously could not be parsed by SWIG. SF #872013.
-
-11/09/2005: wsfulton
- [Java, C#] Portability warning for files which will overwrite each other on case
- insensitive file systems such as FAT32/NTFS. This will occur, for example, when two
- class names are the same barring case. The warning is issued on all platforms and
- can be suppressed with the usual warning suppression techniques. SF bug #1084507.
-
-11/09/2005: wsfulton
- ./configure --with-python --with-ruby --with-perl5 etc enable these languages,
- ie the --with-xxxx options, where no path is specified, work the same as if
- the option was not specified at all. Based on patches #1335042 #1329048 #1329047.
-
-11/09/2005: dancy
-
- [Allegrocl]
- Add C++ support to the Allegrocl module. Further
- enhances the C support as well. Some of the
- features:
-
- - MUCH better generation of foreign types based on
- the C/C++ types for use in defining the FFI on
- the lisp side. We don't pass everything as a (* :void)
- any longer.
-
- - Uses typemaps for better control of type conversions
- and code generation in the generated lisp and c++ wrapper
- code.
-
- - CLOS wrapping of pointers returned from foreign space
- makes it easier to differentiate pointers in user code.
- The wrapping objects can be passed directly to FF calls.
-
- - Defun wrapping of FF calls, allowing for more lispy
- interface. Conversion, GCing, of lisp objects to
- foreign objects can be done in the wrapping defun via
- the use of typemaps.
-
- - overload dispatching implemented on the lisp side
- using generic functions.
-
- - Templates and synonymous types supported.
-
-11/07/2005: mmatus
-
- [Python] Adding proper support for multi-inheritance in
- the python side, ie, if you have two C++ wrapped class, Foo
- and Bar, now:
-
- class MyPythonClass(Foo,Bar):
- ....
-
- will properly work, even with directors, and the
- deallocation of Foo.this and Bar.this will follow
- correctly. Before, a class could only have one 'this'
- instance (unlike C++), only the last base class was
- properly deleted, or detected with directors.
-
- Now 'self.this' can be a list, which will contain the C++
- instance pointers for all the base classes.
-
- Also, swig.this is responsible for deallocating the C++
- instance(s), and the __del__ method is not emitted unless
- the user preppend/append some code to it.
-
- - Swig can now detect memory leaks, ie, if you still
- don't use proxy/shadow classes, and type something like
-
- import _example
- f = _example.new_Foo()
-
- and forget to call _example.delete_Foo(f), then swig will
- tell you that there is a memory leak.
-
- Otherwise, if you always use the proxy classes, you probably
- you will never ever see this warning unless there is
- something wrong inside the swig wrapping code.
-
-
- *** POTENTIAL INCOMPATIBILITY ***
-
- If you overloaded the __del__ method, and call the base
- one without a try block, as in
-
- class MyClass(SwigClass):
-
- def __del__(self):
- <your code here>
- SwigClass.__del__(self)
-
- python could complain that the method SwigClass.__del__ is
- undefined. Try to use instead:
-
- def __del__(self):
- <your code here>
- try: SwigClass.__del__(self)
- except: pass
-
- or simply
-
- def __del__(self):
- <your code here>
-
-11/02/2005: mmatus
-
- [Python] Adding more fun to STL/STD containers, now you
- can do
-
- %template(pyset) std::set<PyObject *>;
- %template(pyvector) std::vector<PyObject *>;
- %template() std::pair<PyObject *,PyObject *>;
- %template(pyvector) std::map<PyObject *,PyObject *>;
- ....
-
- The same applies to std::list, std::deque, std::multiset, etc.
-
- Then, at the python side you can do now:
-
- # C++ std::vector as native python sequence
- v = pyvector([1,"hello",(1,2)])
- print v[1]
- >> 'hello'
- print v[2]
- >> (1,2)
-
- # C++ std::set as native python sequence
- s = pyset()
- s.insert((1,2))
- s.insert(1)
- s.insert("hello")
- sum=()
- for i in s:
- sum +=(i,)
- print sum
- >>> (1, 'hello', (1, 2))
-
- # C++ std::map as native python sequence
- m = pymap()
- m["foo"] = "hello"
- m[1] = (1,2)
- pm = {}
- for k in m:
- pm[k] = m[k]
- print pm
- >>> {1: (1, 2), 'foo': 'hello'}
-
- ie, the STD/STL containers work as real native python
- container, with arbitrary item types and so.
-
- But since normal C++ containers do not properly ref/unref
- their items, you should use the safer versions:
-
- %template(pyset) std::set<swig::PyObject_ptr>;
- %template(pyvector) std::vector<swig::PyObject_ptr>;
- %template() std::pair<swig::PyObject_ptr, swig::PyObject_ptr>;
- %template(pyvector) std::map<swig::PyObject_ptr,swig::PyObject_ptr>;
- ....
-
- where swig::PyObject_ptr is a PyObject * envelope class provided
- to safely incref/decref the python object.
-
- So, now you can use all the STL/STD containers as native
- Python containers.
-
- Note 1: std::map, std::set and the other 'ordered'
- containers will properly use PyObject_Compare for sorting,
- when needed.
-
- Note 2: all the STL/STD containers have a limit size of
- SIZE_MAX, ie, you can have manage containers larger than
- INT_MAX, the python limit.
-
-
-11/02/2005: mmatus
-
- [Python]
- - add 'iterator()' method for all sequences and additionally
- 'key_iterator()' for maps.
-
- 'iterator()' will always return the native C++ iterator.
- Additionally, in maps, 'key_iterator()' will return a python
- iterator using only the map keys.
-
- In general the sequence method __iter__ will call
- 'iterator()', returning the native C++ iterator, but in
- maps it will call 'key_iterator()', maintaining
- backward compatibility.
-
- Hence, for std::maps, you can play then with the native
- C++ iterator, which value is a (key, value) pair, by
- calling map.iterator(), as with map.begin(), map.end(), etc.
-
- The difference is that map.iterator() returns a safe
- 'closed' iterator, while map.begin() and map.end() are
- 'open' iterators.
-
- A 'closed' iterator knows the begin and the end of the
- sequence, and it never can seg. fault. An 'open'
- iterator, as in C++, can seg. fault at the C++ side.
-
- # a closed iterator is safe in the following example.
- # the next() method will throw a StopIteration
- # exception as needed
-
- i = seq.iterator()
- try:
- while True:
- sum += i.next()
- except: pass
-
- # an open iterator always need to be checked,
- # or it will crash at the C++ side
-
- current = seq.begin()
- end = seq.end()
- while (current != end):
- sum += current.next()
-
-
- [Python]
- - Finally, when we call
-
- f = Foo()
-
- the construction is 'one-way'. Before construction was done
- something like
-
- Foo() (python) -> _new_Foo() (C++)
- new_Foo() (C++) -> FooPtr() (python)
- FooPtr() (python) -> Foo() (python)
-
- and returning a pointer was done like
-
- NewPointerObj() (C++) -> FooPtr() (python)
- FooPtr(python) -> Foo() (python)
-
-
- ie, we when going back and forward between the C++ and
- python side.
-
- Now since there is no FooPtr the construction process is
-
- Foo() (python) -> _new_Foo() (C++)
- _new_Foo() (C++) -> NewPointerObj() (C++) (no shadow class)
-
- and returning a pointer is done
-
- NewPointerObj() (C++) (with shadow class) -> NewInstaceObj() (C++)
-
- where NewInstanceObj creates a new instance without
- calling __init__ and it doesn't go 'back' to python, is
- 'pure' C API.
-
- - With this change, and the other ones in the
- PySwigObject type, which now carries the thisown and
- swig_type_info pointer, the generated code should be as
- fast as boost::Python and/or the other python wrappers
- based in pure Python/C API calls.
-
- As a reference, the profiletest_runme.py example, which
- does a simple call function many times, such as this code:
-
- import profiletest
-
- a = profiletest.A()
- b = profiletest.B()
- for i in range(0,1000000)
- a = b.fn(a)
-
-
- where fn is defined as 'A* B::fn(A *a) {return a;}',
- produces the following times
-
- nomodern modern
- swig-1.3.26 19.70s 5.98s
- swig-CVS 0.99s 0.98s
-
-
- Clearly, there is a large improvement for the python
- 'nomodern' mode. Still, the 'modern' mode is around
- 6 times faster than before. For the same test, but
- using the non-shadow version of the module, we get
-
- _profiletest (non-shadow)
- swig-1.3.26 0.80s
- swig-CVS 0.60s
-
- Hence, now for practical purposes, the proxy overhead
- is insignificant.
-
- Note that the performance numbers we are showing is for
- a simple module (two types) and a simple function (one
- argument). For real situations, for modules with many
- more types and/or functions with many more parameters,
- you will see even better results.
-
-
-10/31/2005: mmatus
- [Python]
-
- - Finally, no more ClassPtr proxy classes. You will see
- only a clean Class proxy class in the .py file.
-
- - No more 'real' thisown attribute either, the PySwigObject now
- carries the ownership info.
-
- You can also do something like
-
- print self.this.own()
- >>> True
-
- self.this.disown()
- self.this.own(0)
- print self.this.own()
- >>> False
-
- self.this.acquire()
- self.this.own(1)
- print self.this.own()
- >>> True
-
- Still the old way,
-
- print self.thisown
- >>> True
-
- self.thisown = 0
- print self.thisown
- >>> False
-
- self.thisown = 1
- print self.thisown
- >>> True
-
- is supported, and python dispatches the proper method
- calls as needed.
-
-
- - Support for iterators in STL/STD containers, for example, if you have
-
- %template<set_string> std::set<std::string>;
-
- you can use the C++ iterators as:
-
- s = set_string()
-
- s.append("c")
- s.append("a")
- s.append("b")
-
- b = s.begin()
- e = s.end()
- sum = ""
- while (b != e):
- sum += b.next()
- print sum
-
- >>> "abc"
-
- advance the iterator as in C++
-
- current = s.begin()
- current += 1
- print current.value()
- >>> "b"
-
- now using the reverse operators
-
- b = s.rbegin()
- e = s.rend()
- sum = ""
- while (b != e):
- sum += b.next()
- print sum
-
- >>> "cba"
-
- or the 'previous' method
-
- b = s.begin()
- e = s.end()
- sum = ""
- while (b != e):
- sum += e.previous()
- print sum
-
- >>> "cba"
-
- or just as in a python fashion
-
- for i in s:
- sum += i
-
- Note 1: Iterators in C++ are very powerful, but
- dangerous too. And in python you can shoot yourself in the foot
- just like in C++, so, be careful.
-
- Note 2: the iterators are 'light', ie, they do not
- convert sequence elements until you request to do so, via
- next(), value() or previous(). If you just increment/decrement one
- no conversion is performed, for example:
-
-
- b = s.begin()
- b += 1
- b.incr()
- b.incr(2)
- b.decr(2)
- b.decr()
- b -= 1
-
- only the iterator is modified, and not value wrapper
- is generated. Other typical C++ operations are also
- available, such as:
-
- print s.end() - s.begin()
- >>> 3
- f = s.begin() + 1
- print f.value()
- >>> "b"
- l = s.end() - 1
- print l.value()
- >>> "c"
-
- etc. Of course, the 'find', 'insert', 'erase', and
- so on methods also supports iterators now, ie:
-
- i = s.begin()
- i += 1
- s.erase(i)
- for i in s:
- sum += i
- print sum
- >>> "ac"
-
- *** POTENTIAL INCOMPATIBILITY ***
-
- There is no more 'thisown' attribute. If you use it, python
- will translate the following code as follows:
-
- if (self.thisown): ==> if (self.this.own()):
- self.thisown = 1 ==> self.this.own(1)
- self.thisown = 0 ==> self.this.own(0)
-
- Still, maybe in some unusual cases the translation will not be
- 100% correct, so if you have a problem, please report it
- and/or use the new 'self.this.own()' accessor.
-
-
- *** POTENTIAL INCOMPATIBILITY ***
-
- There is no more ClassPtr classes in the python code. Hence,
- if in the past you needed to resort to some kind of trickery
- with them, or overcome their presence, it is no longer
- required, but the extra code you added could now break
- things.
-
- If needed, you can use the option -classptr, i.e.,
-
- swig -classptr -python ...
-
- to generate the old ClassPtr classes.
-
-
-10/30/2005: mkoeppe
- [Guile] Make declared and defined linkage of SWIG_init consistent.
- Reported by Steven G. Johnson (SF patch 1315498).
-
-10/26/2005: mmatus
-
- - Added the attribute.i file to the global library director.
- Now it can be used from other languages that do not use
- the unified typemap library as well.
-
- So, if you have something like:
-
- %include attribute.i
-
- %attribute(A, int, a, get_a, set_a);
-
- struct A
- {
- int get_a() const;
- void set_a(int aa);
- };
-
- %attribute_ref(B, int, c);
-
- struct B
- {
- int& c();
- };
-
- then in the target language the 'A.a' and 'B.c' attributes will
- be visible, ie, you can access them as plain variables:
-
- f = A()
- f.a = 3
- g = B()
- g.c = 3
-
- h = f.a + g.c
-
- and the proper get/set methods will be dispatched. See
- attribute.i for more info.
-
- - More cleanups around and adding more test-cases. The
- DISOWN typemap now is tested and working in all the
- languages that use the unified typemap library, ie, tcl,
- ruby, perl and python.
-
-
-10/25/2005: mmatus
-
- - Perl, complete the DISOWN typemap.
-
- - added the attribute.i file to the unified typemap
- library (before was only usable from python).
-
- - unify the names for the setter and getter methods in
- perl,tcl,ruby and python, so, the attribute.i library
- can work across them.
-
- - see the li_attribute.i test-case or the library file
-
- Lib/typemaps/attribute.swg
-
- for more info about how to use it.
-
-
-
-
-10/24/2005: mmatus
-
- - Perl now uses the unified typemap library.
-
- - Changes in ruby to use the $track option in typemaps.
-
- - Changes in the unified typemap library to follow the
- convention that all macros that are not used in the
- C/C++ side starts with %, such as
-
- %delete
- %new_array
-
- etc.
-
- - Documenting fragments, see fragments.swg.
-
- - Cleaner way to use the unified typemap library, include
- just <typemaps/swigtypes.swg>.
-
- Check some of the supported languages: perl, tcl, ruby,
- python.
-
- Always start with the head file, such as
-
- python/python.swg
- tcl/tcl8.swg
- ruby/ruby.swg
- perl5/perl5.swg
-
- and the principal file that invokes the unified library, such as
-
- python/pytypemaps.swg
- tcl/tcltypemaps.swg
- ruby/rubytypemaps.swg
- perl/perltypemaps.swg
-
- The file that provide the specialization for each
- language are the one that provides the basic types:
-
- python/pyprimtypes.swg
- ruby/rubyprimtypes.swg
- tcl/tclprimtypes.swg
- perl5/perlprimtypes.swg
-
- and the string manipulation:
-
- python/pystrings.swg
- ruby/rubystrings.swg
- tcl/tclstrings.swg
- perl5/perlstrings.swg
-
-
- The rest of the files, such as carray.i, are mostly one
- line files that include the proper typemap library
- version.
-
- *** POTENTIAL INCOMPATIBILITY in Perl ***
-
- Some missing/wrong typemaps could start working properly,
- and change the old expected behavior in Perl.
-
-10/23/2005: wuzzeb
- Chicken:
- + pointers to member functions finally work properly
- + add test of member function pointers to cpp_basic.i
-
-10/20/2005: dancy
- [allegrocl] Added C++ support. Large update, many changes. See
- newly added Allegro Common Lisp section in lisp.html
-
-10/20/2005: mmatus
- Ruby, Tcl, Python:
-
- - Uniform way to fail (label fail:), now finally
- SWIG_exception works across the three languages and all
- the typemaps.
-
- - Add proper cleanup code to ruby
-
- - More valgrind fixes
-
- - Simplify the inline use, it seems a small interface of
- 20,000 lines (plus many many templates) can break
- gcc -O3 easily.
-
- - Finalize the typemaps library. All the old *.i files
- (carray.i, cpointer.i, exception.i) had been implemented
- in the new typemaps library.
-
-
-10/19/2005: wuzzeb
- Update the Runtime Typemap documentation in Typemaps.html
-
-10/18/2005: wuzzeb
- Chicken:
- - Correctly handle %ignored classes
- - Correctly convert long, long long, unsigned long, etc
- to chicken primitives. (Thanks to Felix Winkelmann)
- - Using argout parameters when the return value was a
- wrapped pointer caused a memory corruption. The chicken
- garbage collector moved a pointer out from under us.
- This is now fixed by running all the proxy creation
- functions as continuations after the wrapper function
- returns. As part of this, we no longer need the
- chickenfastproxy flag on output typemaps.
- - using -proxy and -nocollection together works now
- Before, it was not exporting the destructor in the proxy
- wrapper.
-
-10/18/2005: mmatus
-
- Added the Unified Typemap Library (UTL). It unifies the typemaps for
-
- python, ruby, tcl
-
- and in the process, fixes several problems in each of the three
- languages to work in a "canonical" way now established in
- the typemap library
-
- SWIG/Lib/typempas
-
- The current status of the unification is that everything
- compiles and runs inside the test-suite and examples
- directories. And for the first time we have three
- languages than pass the primitive_types.i case.
-
- Also, we have a uniform way to treat the errors, for example
- if you do something like
-
- >>> from primitive_types import *
- >>> print val_uchar(10)
- 10
- >>> print val_uchar(1000)
- Traceback (most recent call last):
- File "<stdin>", line 1, in ?
- OverflowError: in argument 1 of type 'unsigned char'
-
- you get the same exception in all the three languages.
-
- And well, many more good things will come from this
- unification, for example, proper support of the STL/STD classes
- for all the languages, and hopefully, we can keep
- adding other languages.
-
- The hardest part, writing a common typemap library
- that suites the three different languages, is done,
- and adding another language should now be easy.
-
- Still the global unification is not complete, the STL/STD
- part is next, and probably as well as adding one or two more
- languages.
-
- If you are curious, look at the python, ruby and/or tcl
- directories to see what is needed to support the new
- common typemaps library. Still, the final way to
- integrate a new language could change as we move to
- integrate the STD/STL.
-
- *** POTENTIAL INCOMPATIBILITY in Ruby/Tcl ***
-
- Some missing/wrong typemaps could start working properly,
- and change the old behavior, specially in ruby and tcl.
-
-Version 1.3.27 (October 15, 2005)
-=================================
-
-10/15/2005: wsfulton
- [Java] Fix for typesafe enum wrapping so that it is possible to
- overload a method with 2 different enum types.
-
-10/15/2005: wsfulton
- Fix for %feature("immutable","0") attempting to generate setters
- for constants.
-
- Restored %immutable and %makedefault to clear the feature as it
- behaved in SWIG-1.3.25 and earlier.
-
-10/14/2005: mmatus
- Fix bug in anonymous typedef structures which was leading to
- strange behaviour.
-
-10/13/2005: mmatus
- Several minor changes:
-
- - Improve the wchar_t type support
- - Add a warning for when you define the 'in' typemap but
- you don't define the 'typecheck' one. Very common mistake.
- - Add proper default rule for function pointers, now you
- can define a typemap such as:
-
- %typemap(in) SWIGTYPE ((*)(ANY)) {...}
-
- That will apply to all the pointer to functions. The
- rule in C++ also apply to the function 'reference', ie,
- in both cases
-
- typedef int (*fptr)(int a);
- typedef int (func)(int a);
-
- This was needed since it seems to be 'illegal' in C++ to
- do something like:
-
- void *ptr = static_cast<void *>(fptr);
-
- and probably, as for member functions, it is not
- warrantied that the pointer sizes will match.
-
- - Add the #error/#warning directives to swig's cpp.
-
- - Add the noblock option for typemaps, which is used as
- follows: supposed you a typemap, like this
-
-
- %typemap(in,noblock=1) Hello {
- ....
- }
-
- then the typemap will be inserted without the block
- imposed by the brackets, similar to
-
- %typemap(in) Hello "..."
-
- So, why you don't just use the quote style?, because:
-
- 1.- The quote style doesn't get preprocessed, for example
-
- %typemap(in) Hello "$1= SWIG_macro($1);"
-
- here, SWIG_macro doesn't get expanded
-
- 2.- Inside a quote typemap, you have to use
- quotes carefully
-
- %typemap(in) Hello "$1 = \"hello\" "
-
- 3.- You can't make emacs and/or other editors
- to indent inside a string!.
-
-
- So, why do you want to remove the block?, because an extra
- block when not needed (no local variables in it):
-
- 1.- makes the code harder to read
- 2.- makes the code larger
- 3.- or in short, for the same reason we have the quote style.
-
-Version 1.3.26 (October 9, 2005)
-================================
-
-10/08/2005: wsfulton
- [Php] Added 'throws' typemaps.
-
-10/08/2005: wsfulton
- Fixes for languages that don't support multiple inheritance. The
- first non-ignored class in the public base class list is used for inheritance.
- by the proxy class. Previously, if the first class in the list was ignored, then
- the proxy class wouldn't have any base classes.
-
-10/07/2005: mmatus
- Update more features to follow new convention, including:
-
- callback
- ref/unref
- except
-
- All of them use not only the feature as a flag, but also
- as code value. To deal with those features, we use now
- GetFlagAttr, which is similar to GetFlag, but instead or
- returning 1 or 0, it returns the attr value, if happens
- to be different of "0" of course.
-
- Now there are also more uniform directive names for the
- ones based in features, for example, for the old
- %newobject directive now we have tree directives defined:
-
-
- #define %newobject %feature("new")
- #define %nonewobject %feature("new","0")
- #define %clearnewobject %feature("new","")
-
- and so on for all the other feature directives.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-09/30/2005: wsfulton
- Subtle change to some features. Previously it was not possible to disable many
- features once they had been enabled. This was for most features that behave as
- flags. These features now work as follows:
-
- %feature("name") // enables the feature
- %feature("name", "1") // enables the feature
- %feature("name", "0") // disables the feature
- %feature("name", "") // clears the feature
-
- In fact any non-empty value other than "0" will enable the feature (like C boolean logic).
- Previously "1", "0" or any other non-empty value would enable the feature and it would
- only be possible to disable the feature by clearing it (assuming there was no global enable).
-
- The following features are affected:
-
- allowexcept
- compactdefaultargs
- classic (Python)
- cs:const (C#)
- director
- exceptionclass (Python)
- ignore
- immutable
- java:const (Java)
- java:downcast (Java)
- kwargs
- modern (Python)
- new
- noautodoc (Python)
- nodefault
- nodirector
- noref
- notabstract
- nounref
- novaluewrapper
- python:maybecall (Python)
- python:nondynamic (Python)
- modula3:multiretval (Modula3)
- predicate (Ruby)
- trackobjects (Ruby)
- valuewrapper
-
- It is now possible, for example to ignore all methods/classes in a header file, except for a
- few targetted methods, for example:
-
- %feature("ignore"); // ignore all methods/classes
- %feature("ignore","0") some_function(int, double); // do not ignore this function
- %feature("ignore","0") SomeClass; // do not ignore this Class
- %feature("ignore","0") SomeClass::method; // do not ignore this method
- %include "bigheader.h"
-
- Removed %pythondynamic - it never worked properly. Use %pythonnondynamic instead.
- Removed %feature("nokwargs") - it wasn't fully implemented - use %feature("kwargs","0") instead.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-09/25/2005: mkoeppe
- [Guile] Add "throws" typemaps.
-
-09/24/2005: cfisavage
- [Ruby] Adds new %trackobjects functionality that maps C++ objects to
- Ruby objects. This functionality makes it much easier to implement
- mark functions for the garbage collector. For more information
- refer to the update documentation and examples.
-
-09/20/2005: wsfulton
- [Perl] Patch 1116431 from Josh Cherry. Fixes non member functions inadvertently
- being called instead of member functions.
-
-09/20/2005: wsfulton
- [Lua] Patch from Mark Gossage to add support for Lua-5.1, std::string,
- std::vector, std::exception and documentation.
-
-09/14/2005: mmatus
- [Python] Add -nocppcast. Now the default behavior is to
- always use the cppcast operators. Before that was the case
- only when you used the -cppcast option.
-
- If this seems to break your code... your welcome!, it
- means it was broken before, and you never notice.
-
- If you thing the error is due to one of the SWIG typemaps,
- send us an example.
-
- Use -nocppcast only with very old C++ compilers that
- do not support the cppcast operations.
-
- So, here applies:
-
- This change doesn't break compatibility, it was broken before.
-
-09/13/2005: wsfulton
- [Java] Fix for director methods when a class is passed by value as a
- parameter.
-
-09/11/2005: mmatus
- Adding the module option to the %import directive. Now you
- can use it as
-
- %import(module="BigModule") foo.i
-
- where subfile could (or not) define the module name via
- the %module directive. The module option take precedence
- and it has the same effects than having the directive
-
- %module BigModule
-
- inside the imported file foo.i.
-
- You can use the option in mainly two cases:
-
- 1.- You used the -module option when you generated the
- module to be imported, and hence the module name in
- the imported %module directive is not really useful.
-
- 2.- The module you want to import is very large, and it
- has several .i/.h files. Then, if you just one to
- import a class or so from the module, says 'foo', and
- not the entire module via importing the main
- BigModule.i file, then you just do:
-
- %import(module="BigModule") foo.h
-
- or
-
- %import(module="BigModule") foo.i
-
- where foo.i contains the 'foo' declaration and maybe a
- couple of extra %include directives, as needed.
-
-
-09/11/2005: mmatus
- Fix bug #1282637, about the -module option not having effect
- in places where it was needed.
-
-09/11/2005: wsfulton
- When wrapping variables, ensure that none of the typemaps used for the
- set wrappers are used when generating the get wrappers. I doubt this was a
- problem for any languages except for the recently introduced null attribute
- in the out typemap (C# only).
-
-09/08/2005: wsfulton
- More descriptive error messages when files fail to open.
-
-09/06/2005: mmatus
-
- Allow a %define a macro inside another %define macro, for example
-
- %define hello(name, Type)
- %define name ## a(Type)
- %typemap(in) Type "hello;"
- %enddef
- %enddef
-
- To learn how to use this new features in your own typemaps library, see
- python/cstring.i, python/cwstring.i and python/cwstrbase.i.
-
- [Python] Normalize the cstring.i implementation to use fragments, and add
- cwstring.i, which implements the same typemaps but for wchar_t strings.
-
- [Python] Bug fixed: 1247477, 1245591, 1249878 and others.
-
-08/18/2005: wsfulton
- [Ruby] Implement support for SWIGTYPE* DISOWN typemap (like in Python) for
- better control of memory management, eg when adding an object created in Ruby
- to a C++ container. Patch #1261692 from Charlie Savage.
-
-08/18/2005: wsfulton
- [Tcl] 64 bit platform fixes for the varargs handling in SWIG_GetArgs. This is an
- improved fix for bug #1011604 as suggested by Jeremy Lin.
-
-08/18/2005: wsfulton
- [Tcl] Bug #1240469 - %newobject support for Tcl. Patch from Bob Marinier.
-
-08/16/2005: wsfulton
- [Perl] Bug #1254494 - Fix for global namespace pollution by perl header files
- (bool define) prevented STL headers from being used on some systems, eg
- Windows with Visual Studio.
-
-08/16/2005: wsfulton
- [Java] Bug #1240937 - Redefinition of __int64 typedef for Intel compilers.
-
-08/15/2005: wsfulton
- [Xml] Bug #1251832 - C++ template may generate invalid XML file
-
-08/15/2005: wsfulton
- [Lua] Support added for Lua. Patch #1242772 from Mark Gossage.
- It supports most C/C++ features (functions, struct, classes, arrays, pointers,
- exceptions), as well as lots of documentation and a few test cases & examples.
-
-08/14/2005: wsfulton
- [Xml] Fix incorrect xml escaping in base class name when base class is a template.
-
-08/13/2005: efuzzyone
- [CLISP] Added support for handling enums. Does not adds the return type declaration
- to the function definition, if a function returns void.
-
-08/09/2005: mkoeppe
- New language module, Common Lisp with UFFI, from Utz-Uwe Haus.
-
-08/09/2005: mkoeppe
- Fix the Lisp s-expression output module; it no longer complains about "unknown targets".
-
-07/27/2005: wsfulton
- Modifications to STL wrappers so that it is possible for a user's %exception directive
- to be applied to the STL wrapper methods. Previously the following global %exception
- directive would not be used on the wrapper methods:
-
- %exception {
- try {
- $action
- } catch (...) {
- // handle uncaught exceptions
- }
- }
-
- This has been implemented by replacing %exception directives for specific STL wrapper
- methods with an exception specification declared on the wrapper methods. throws typemaps
- are now supplied for handling the STL exception specification. These can also be easily
- overridden, for example the std::out_of_range exception, which is used a lot in the STL
- wrappers, can be customised easily:
-
- %include "std_vector.i"
- %typemap(throws) std::out_of_range {
- // custom exception handler
- }
- %template(VectInt) std::vector<int>;
-
-07/22/2005: efuzzyone
- [CLISP] The clisp module for SWIG:
- - It can only handle C, clisp currently does not supports ffi bindings to C++.
- - It has two options, (a) -extern-all this will generate wrappers for all functions
- and variablestions, (b) -generate-typedef this will generate wrappers "def-c-type"
- wrappers for typedefs
- - Can handle pointers to functions, complex types such as n-dimensional arrays of
- pointers of depth d
- - Generates wrappers for constants as well as variables
- - Correctly distinguishes between the declaration of variables in structures and functions
- - Creates a defpackage "declaration" with the module name as the package name, the created
- package exports both functions and variables
- - tries to guess when should a pointer variable be declared as c-ptr or c-pointer
-
-07/22/2005: wsfulton
- [C#] Changes to support C# structs returned by value. The changes required are:
- - Using an optional 'null' attribute in the out typemap. If this attribute is specified,
- then it is used for the $null special variable substitution.
- - The ctype used in the C/C++ wrappers is no longer initialised to 0 on declaration.
- Both of these changes fix the situations where an attempt was made to assign 0 to the
- returned struct. Marshalling structs as value types still requires user defined typemaps.
- See documentation for an example.
-
-07/22/2005: wsfulton
- [C#, Java] Fix SWIG_exception usage to work with compilers that don't support empty macro
- arguments. Unfortunately this fix will stop usage of SWIG_exception being used within typemaps
- that use "" or %{ %} delimiters, but continues to work with typemaps using {} delimiters.
- Please use the SWIG_CSharpSetPendingExceptionArgument or SWIG_JavaThrowException methods instead
- as SWIG_exception is really intended as a platform independent macro for the SWIG library writers.
-
-07/16/2005: mkoeppe
- [Allegro CL] Use specific foreign types rather than (* :void).
- Use *swig-identifier-converter*.
-
-06/27/2005: wsfulton
- Functions declared as 'extern' no longer have an additional function declaration added to the
- wrapper files. There are some cases where SWIG does not get this right, eg bug #1205859 (extern
- functions with default arguments declared in a namespace). Also SWIG cannot get non-standard
- calling conventions correct, eg Windows calling conventions are usually handled like this:
-
- %{
- #define DLLIMPORT __declspec(dllimport)
- #define STDCALL __stdcall
- %}
- #define DLLIMPORT
- #define STDCALL
- %inline %{
- DLLIMPORT extern STDCALL void function(int);
- %}
-
- SWIG incorrectly generates:
-
- extern void function(int);
-
- To which there is no solution as SWIG doesn't handle non-standard calling conventions. The extra
- 'extern' function that SWIG generates is superfluous unless a user has forgotten to add the function
- declaration into the wrappers.
-
- The -noextern commandline argument is now redundant and a new commandline argument -addextern can
- be used to obtain the original behaviour. This shouldn't be necessary unless the header file
- containing the function declaration was inadvertently not added to the wrappers. To fix this
- add the function declaration into your wrappers, For example, replace:
-
- extern void foo(int);
-
- with:
-
- %inline %{
- extern void foo(int);
- %}
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-06/22/2005: wsfulton
- [C#, Java, Modula3, Ocaml]
- The intermediary function names have been changed when wrapping variables to
- match the other language modules so that %extend for a member variable works
- uniformly across all language modules, eg:
-
- %extend ExtendMe {
- Var;
- };
-
- %{
- void ExtendMe_Var_set(ExtendMe *, double) {...}
- double ExtendMe_Var_get(ExtendMe *) {...}
- %}
-
- The methods implementing the get/set used to be:
-
- %{
- void set_ExtendMe_Var(ExtendMe *, double) {...}
- double get_ExtendMe_Var(ExtendMe *) {...}
- %}
-
- This also changes the name of variable wrapper functions when using -noproxy.
- The original names can be generated with the -oldvarnames commandline option.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-Version 1.3.25 (June 11, 2005)
-==============================
-
-06/11/2006: mkoeppe
- [Guile] Fix handling of anonymous-enum variables.
-
-06/10/2005: mkoeppe
- [Guile] Fix for function arguments that are passed by
- copy-of-value. Fix for global "const char *" variables.
- Fix testcases arrays_dimensionless, arrays_global.
-
-06/08/2005: wsfulton
- Fix for when a base class defines a symbol as a member variable and a derived class defines
- the same symbol as a member method.
-
-06/08/2005: wsfulton
- [C#] More fixes for virtual/new/override modifiers - when a method has protected access
- in base and public access in derived class.
-
-06/02/2005: wsfulton
- Fix #1066363 - Follow convention of release tarball name matching directory name.
-
-06/02/2005: wsfulton
- [C#, Java] Fix #1211353 - typesafe enums (and Java proper enums) wrappers when enum value
- is negative.
-
-05/27/2005: wsfulton
- Modernised and tidied up Windows macros --> SWIGEXPORT, SWIGSTDCALL. They can be overridden
- by users via -D compiler directives if need be.
-
-05/26/2005: wsfulton
- %csmethodmodifiers can be applied to variables as well as methods now.
-
- In addition to the default 'public' modifier that SWIG generates, %csmethodmodifiers will also
- replace the virtual/new/override modifiers that SWIG thinks is appropriate. This feature is
- useful for some obscure cases where SWIG might get the modifiers incorrect, for example
- with multiple inheritance and overriding a method in the base class.
-
- *** POTENTIAL INCOMPATIBILITY FOR C# MODULE ***
-
-05/25/2005: wsfulton
- Added missing constructors to std::pair wrappers (std_pair.i) for all languages.
-
-05/25/2005: wsfulton
- [C#] Added std::pair wrappers in std_pair.i
-
-05/25/2005: wsfulton
- [C#] The C# 'new' and 'override' modifiers will be generated when a C++ class inherits methods
- via a C++ 'using' declaration.
-
-05/25/2005: wsfulton
- Fix for exception specifications previously being ignored in classes that inherited methods
- from 'using' declarations, eg calls to Derived::bar below will convert C++ exceptions into
- a target language exception/error, like it always has done for Base::Bar.
-
- class Base {
- virtual bar() throw (std::string);
- };
- class Derived : public Base {
- using Base::bar;
- };
-
-05/23/2005: wsfulton
- Fixes for detecting virtual methods in %extend for the -fvirtual option and C# override and new
- method modifiers.
-
-05/23/2005: wsfulton
- [C#] The 'new' modifier is now generated on the proxy method when a method in a derived
- class is not polymorphic and the same method exists in the derived class (ie it hides
- the base class' non-virtual method).
-
-05/23/2005: wsfulton
- [Java, C#] Fixes to detection of covariant return types - when the class hierarchy is more
- than 2 classes deep.
-
-05/21/2005: wsfulton
- [Java] std::wstring typemaps moved from std_string.i to std_wstring.i
-
-05/21/2005: wsfulton
- Fix for crash in DohStrstr, bug #1190921
-
-05/21/2005: wsfulton
- [TCL] Fix for methods with similar names when showing list of names on error - bug #1191828.
- Patch from Jeroen Dobbelaere.
-
-05/21/2005: wsfulton
- [TCL] long long overloading fix - bug #1191835, patch from Jeroen Dobbelaere.
-
-05/21/2005: wsfulton
- Fix bug #1196755 to remove debug from swigtcl8.swg.
-
-05/19/2005: wsfulton
- [C# and -fvirtual option] Fix for the override key not being generated in the derived class when a
- virtual method's return type was a typedef in either the base or derived class. Also ensures the
- method is eliminated when using the -fvirtual option. For example, Derived.method now has the C#
- override keyword generated:
-
- typedef int* IntegerPtr;
-
- struct Base {
- virtual IntegerPtr method();
- };
-
- struct Derived : Base {
- int * method() const;
- };
-
- [C#] Fix for the override key being incorrectly generated for virtual methods when a base class
- is ignored with %ignore.
-
-05/13/2005: wsfulton
- [Java] Fixes to remove "dereferencing type-punned pointer will break strict-aliasing rules"
- warnings in C wrappers when compiling C code with 'gcc -Wall -fstrict-aliasing'. Patch from
- Michael Cahill. This modifies many of the casts slightly, for example
- arg1 = *(DB_ENV **)&jarg1;
- to
- arg1 = *(DB_ENV **)(void *)&jarg1;
-
-05/12/2005: wsfulton
- [C#] Support for C# attributes. C# attributes can be generated:
- 1) On a C/C++ type basis by specifying an inattributes and/or outattributes typemap attribute
- in the imtype or cstype typemaps (for C# return type or C# parameter type attributes).
- 2) On a wrapped method or variable by specifying a csattributes feature (%feature).
- 3) On a wrapped proxy class or enum by specifying a csattributes typemap.
-
- Examples are in the C# documentation (CSharp.html).
-
-04/29/2005: wsfulton
- New configure option to turn off the default maximum compiler warning as
- they couldn't be removed even when overriding CFLAGS and CXXFLAGS with configure
- (./configure CFLAGS= CXXFLAGS=). To turn the maximum warnings off, run:
-
- ./configure --without-maximum-compile-warnings
-
-04/28/2005: wsfulton
- Patch from Scott Michel which reworks the Java constructor and finalize/destructor typemaps,
- for directors to reduce the number of overall Java typemaps. Added the director_take and
- director_release typemaps to emulate other modules' __disown__ functionality.
-
- *** POTENTIAL INCOMPATIBILITY FOR JAVA DIRECTORS ***
-
-04/28/2005: wsfulton
- [C#] Fixed problems due to the over eager garbage collector. Occasionally the
- garbage collector would collect a C# proxy class instance while it was being used
- in unmanaged code if the object was passed as a parameter to a wrapped function.
- Needless to say this caused havoc as the C# proxy class calls the C++ destructor
- when it is collected. Proxy classes and type wrapper classes now use a HandleRef,
- which holds an IntPtr, instead of a plain IntPtr to marshal the C++ pointer to unmanaged
- code. There doesn't appear to be any performance degradation as a result of this
- modification.
-
- The changes are in the proxy and type wrapper classes. The swigCPtr is now of type HandleRef
- instead of IntPtr and consequently the getCPtr method return type has also changed. The net
- effect is that any custom written typemaps might have to be modified to suite. Affected users
- should note that the implementation uses the new 'out' attribute in the imtype typemap as the
- input type is now a HandleRef and the output type is still an IntPtr.
-
- *** POTENTIAL INCOMPATIBILITY FOR C# MODULE ***
-
-04/28/2005: wsfulton
- [C#] Support for asymmetric type marshalling added. Sometimes the output type needs to be
- different to the input type. Support for this comes in the form of a new optional 'out'
- attribute for the ctype, imtype and cstype typemaps. If this typemap attribute is not
- specified, then the type used for both input and output is the type specified in the
- typemap, as has always previously been the case. If this typemap attribute is specified,
- then the type specified in the attribute is used for output types and the type specified
- in the typemap itself is used for the input type. An output type is a return value from
- a wrapped method or wrapped constant and an input type is a parameter in a wrapped method.
-
- An example shows that char * could be marshalled in different ways,
-
- %typemap(imtype, out="IntPtr") char * "string"
- char * function(char *);
-
- The output type is thus IntPtr and the input type is string. The resulting intermediary C# code is:
-
- public static extern IntPtr function(string jarg1);
-
-04/22/2005: mkoeppe (Matthias Koeppe)
- [Guile] Fix generation of "define-method" for methods of
- classes with a constructor. Reported by Luigi Ballabio.
-
-04/15/2005: wuzzeb (John Lenz)
- [Chicken]
- For wrapped functions that return multiple values (using argout),
- SWIG CHICKEN now returns them as multiple values instead of as
- a list. They can then be accessed using (call-with-values).
-
-04/14/2005: wuzzeb (John Lenz)
- [Chicken]
- + Added a whole bunch of new _runme scripts into the chicken test
- suite. Also fix some bugs these new scripts turned up.
-
- + Added optimization when returning a wrapped proxy class. Before,
- a minor garbage collection was invoked every time a function returned.
-
- + All the chicken Examples should now run correctly
-
-04/14/2005: wsfulton
- [C#] More fixes for typemap matching when wrapping variables, in particular
- std::string, so that std::string variables can be easily marshalled with
- a C# string property using:
-
- %include "std_string.i"
- %apply const std::string & { std::string *variable_name };
- std::string variable_name;
-
- (Recall that all class variables are wrapped using pointers)
-
-04/05/2005: wuzzeb (John Lenz)
- [Chicken]
- + Added Examples/chicken/egg, an example on how to build a chicken
- extension library in the form of an egg. Also updated the
- documentation on the different linking options.
-
- + chicken test-suite now has support to check SWIG with the -proxy
- argument if there exists a _proxy_runme.ss file.
-
- + More fixes for overloaded functions and -proxy
-
-03/31/2005: wsfulton
- Turned on extra template features for all languages which were
- previously only available to Python.
-
- This enables typemaps defined within a templated class to be used as
- expected. Requires %template on the templated class, %template() will
- also pick up the typemaps. Example:
-
- template <typename T> struct Foo {
- ...
- %typemap(in) Foo "in typemap for Foo<T> "
- or
- %typemap(in) Foo<T> "in typemap for Foo<T> "
- };
-
- %template(Foo_i) Foo<int>;
- %template() Foo<double>;
-
- will generate the proper 'in' typemaps wherever Foo<int> and Foo<double>
- are used.
-
-03/30/2005: mkoeppe (Matthias Koeppe)
- [MzScheme] Patch from Hans Oesterholt for supporting MzScheme 30x.
-
-03/29/2005: wuzzeb (John Lenz)
- [Chicken]
- + Reallow older versions of chicken (1.40 to 1.89) by passing -nocollection
- argument to SWIG
- + %import now works correctly with tinyclos. (declare (uses ...)) will be
- exported correctly.
- + TinyCLOS proxy classes now work correctly with overloaded functions
- and constructors.
-
-03/29/2005: wsfulton
- [Java] Patch from Scott Michel for directorout typemaps. Java directors
- require the directorout typemaps like the other languages now. The new
- typemaps provide fixes for methods where the return type is returned
- by reference (this cannot automatically be made thread safe though).
-
-03/22/2005: wsfulton
- Enum casting fixes. Visual C++ didn't like the C type casting SWIG produced
- when wrapping C++ enum references, as reported by Admire Kandawasvika.
-
-03/21/2005: wsfulton
- [Perl] SF #1124490. Fix Perl macro clashes when using Visual Studio's STL string,
- so now projects can #include <string>.
-
-03/21/2005: wsfulton
- Fixed %varargs which got broken with the recent default argument changes.
- Also works for Java and C# for the first time now.
-
-03/17/2005: wuzzeb (John Lenz)
- [Chicken]
- + Fix a whole bunch of bugs in the chicken module. The entire
- test suite now compiles, with the exception of the tests that require
- std_vector.i, std_deque.i, and so on, which chicken does not have yet.
-
- + Add support for %exception and %typemap(exceptions). Exceptions are
- thrown with a call to (abort) and can be handled by (handle-exceptions)
-
-03/15/2005: wsfulton
- [Java] Patch from Scott Michel for directors. Modifications to the typemaps
- giving users fine control over memory ownership and lifetime of director classes.
- Director classes no longer live forever by default as they are now collectable
- by the GC.
-
-03/15/2005: wuzzeb (John Lenz)
- [Chicken] Add support for adding finalizers garbage collected objects.
- Functions that return new objects should be marked with %newobject and
- input arguments which consume (or take ownership) of a pointer should
- be marked with the DISOWN typemap.
-
- Also add support for correctly checking the number of arguments passed
- to a function, and raising an error if the wrong number are passed.
-
-03/14/2005: wuzzeb (John Lenz)
- Add --without-alllang option to configure.in, which is the same as
- passing all the --without-python --without-perl5 etc... that Matthias added.
-
-03/09/2005: wsfulton
- [Php] Memory leak fix for functions returning classes/structs by value.
-
-03/08/2005: wsfulton
- [Perl] Fix for Perl incorrectly taking memory ownership for return types that
- are typedefs to a struct/class pointer. Reported by Josh Cherry.
-
-03/07/2005: wsfulton
- [C#] Various exception changes for the std::vector wrappers. These now more
- accurately mirror the same exceptions that System.Collections.ArrayList throw.
-
-03/07/2005: wsfulton
- [C#] Fix undefined behaviour after any of the std::vector methods
- throw an exception.
-
-03/07/2005: wsfulton
- [C#] When null is passed for a C++ reference or value parameter, the
- exception thrown has been corrected to an ArgumentNullException instead
- of NullReferenceException as recommended in the .NET Framework documentation.
-
- The default throws typemaps turn a C++ exception into an ApplicationException,
- not a SystemException now.
-
-03/07/2005: wsfulton
- [C#] Numerous changes in C# exception handling have been made over the past
- few weeks. A summary follows:
-
- The way in which C++ exceptions are mapped to C# exceptions is quite different.
- The change is to fix C# exceptions so that the C++ exception stack is correctly
- unwound as previously C++ exceptions were being thrown across the C PInvoke layer
- into the managed world.
-
- New typemap attributes (canthrow and excode) have been introduced to control the
- mapping of C++ to C# exceptions. Essentially a callback into the unmanaged world
- is made to set a pending exception. The exception to throw is stored in thread local
- storage (so the approach is thread-safe). The typemaps are expected to return
- from unmanaged code as soon as the pending exception is set. Any pending exceptions
- are checked for and thrown once managed code starts executing. There should
- be minimal impact on execution speed during normal behaviour. Full details will be
- documented in CSharp.html.
-
- The SWIG_CSharpThrowException() function has been removed and replaced with the
- SWIG_CSharpSetPendingExceptionArgument() and SWIG_CSharpSetPendingException()
- functions. The original name has been deliberately changed to break old code as
- the old approach was somewhat flawed. Any user defined exceptions that follow the
- same pattern as the old approach should also be fixed.
-
- Numerous new .NET framework exceptions are now available for easy throwing from
- unmanaged code. The complete list is:
-
- ApplicationException, ArithmeticException, DivideByZeroException,
- IndexOutOfRangeException, InvalidOperationException, IOException,
- NullReferenceException, OutOfMemoryException, OverflowException,
- SystemException, ArgumentException, ArgumentNullException and
- ArgumentOutOfRangeException.
-
- *** POTENTIAL INCOMPATIBILITY FOR C# MODULE ***
-
-05/05/2005: mmatus
-
- Fix several memory leaks around. Even when we survive knowning
- swig is a memory leak factory, it was a little out of
- control. To run std_containers.i in the python test-suite,
- swig was using ~260MB, now it uses 'only' ~40MB, which is
- the same ammount that g++ uses, so, is not that bad.
- In the process, I found a couple of extra Deletes, which
- in some cases could trigger seg. faults and/or
- DOH/asserts.
-
- [python] Better support for directors + exception. More
- verbose errors and added an unexpected exception handler.
-
- [python] Fix memory leak for the
-
- std::vector<std::vector<int> >
-
- case,reported by Bo Peng.
-
- [python] Fix SwigPyObject compare problem reporte by
- Cameron Patrick.
-
- [python] Fix several warnings in the generated code
- for gnu-gcc, Intel and VC7.1 compilers.
-
-
-02/25/2005: wuzzeb (John Lenz)
- Update documentation to use CSS and <div> instead of <blockquote>
- I used a script to convert the docs, and it set all the box classes
- to be "code". There are actually 4 different classes,
- "shell", "code", "targetlang", and "diagram". We need to go through
- and convert the divs depending on what they contain.
-
-02/23/2005: mmatus
-
- [Python] Added option -nortti to disable the use of native
- C++ RTTI with directors (dynamic_cast<> is not used).
-
- Add more code for directors to detect and report errors in
- the python side.
-
- Extend the use of SWIGINTERN whenever is possible.
-
- Remove template warnings reported by VC7.1.
-
- Remove warnings reported by gcc/g++. Finally you can
- compile using
-
- g++ -W -Wall -c mymodule_wrap.cxx
-
- and no spurious errors will be generated in the wrapper
- code.
-
-02/23/2005: wuzzeb (John Lenz)
- Added -external-runtime argument. This argument is used to dump
- out all the code needed for external access to the runtime system,
- and it replaces including the files directly. This change adds
- two new virtual functions to the Language class, which are used
- to find the language specific runtime code. I also updated
- all languages that use the runtime to implement these two functions.
-
-02/22/2005: mmatus
- Fix %template + private error SF#1099976.
-
-02/21/2005: mmatus
-
- Fix swigrun.swg warnings reported when using "gcc -W -Wall"
- (static/inline not used in front of a function
- declaration), and add SWIGUNUSED attribute to avoid
- unused warnings elsewhere.
-
- Fix unused variable warnings.
-
- [Python] Use new SWIGUNUSED attribute to avoid warnings in
- SWIGINTERN methods.
-
- [Python] Fix PyOS_snprintf for python versions < 2.2 (SF #1104919).
-
- [Python] Fix map/multimap to allow empty maps (reported by
- Philippe Hetroy).
-
- [Docs] Add some documentation to Python.html and
- SWIGPlus.html, including for example the fact that
- 'friends' are now supported.
-
-02/21/2005: wsfulton
- [PHP] Patch from Olly Betts, so that wrappers compile with Zend thread safety enabled.
-
-02/17/2005: wsfulton
- Memory leak fix in some of the scripting language modules when using default
- arguments in constructors. The scripting language was not taking ownership of the
- C++ object memory when any of the constructors that use default arguments was called.
-
-02/16/2005: wsfulton
- SF #1115055: Failed make install. Patch from Rob Stone.
-
-02/16/2005: wsfulton
- [Java] SF #1123416 from Paul Moore. Correct memory allocation for STRINGARRAY
- typemaps in various.i.
-
-02/15/2005: wsfulton
- Disabled typemap search changes for now (see entry 19/12/2004). It breaks
- old typemaps, lengthens the execution time by about 25% and introduces
- inconsistencies.
-
-02/15/2005: wsfulton
- swig -help follows other software by printing to stdout instead of stderr now.
- swig -version also displays to stdout instead of stderr now.
- Behaviour reported by Torsten Landschoff.
-
-02/15/2005: wsfulton
- [Ruby] Fix for the less commonly used ordering of %include and #include, so
- that the generated code compiles. Bug reported by reported by Max Bowsher.
- %include foo.h
- %{
- #include foo.h
- %}
-
-02/15/2005: wsfulton
- [C#, Java] SWIG_exception macro will now return from unmanaged code / native code
- as soon as it is called. Fixes possible JVM crashes and other code unexpectedly
- being executed. Note SWIG_exception is only occasionally used by SWIG library
- writers, and is best avoided by SWIG users.
-
-02/15/2005: wsfulton
- [C#, Java] Typemaps can now be targeted at global variable names
- and static member variable names. Previously the typemaps for
- the setters were ignored, for example:
-
- %typemap(in) int globalint "..."
- int globalint;
-
-02/13/2005: mkoeppe (Matthias Koeppe)
- [Guile] Add %typecheck for SWIGTYPE, add %typecheck for ptrdiff_t, fix
- typemaps for size_t.
-
- [Pike] Merge patch from Torsten Landschoff for improved Pike configuration.
-
-02/12/2005: mkoeppe (Matthias Koeppe)
- New configure switches --without-tcl, --without-python etc. allow to
- disable the search for installed languages.
-
-01/31/2005: wuzzeb (John Lenz)
- - Add DohSortList to DOH
-
- - Improve the runtime type system:
- + Speed. Type loading is now O(n log n) instead of O(N^2), which
- for large modules is a huge improvement.
- + A whole bunch of functions in swigrun.swg no longer need the
- swig_type_list_handle passed to them. The only one left is
- TypeQuery. This also makes runtime.swg a lot smaller.
- + Split up swig_type_info structure into two structures
- (swig_type_info and swig_cast_info)
- + Store a pointer to a swig_type_info rather than just the type
- name string in the linked list of casts. First off, this makes
- the guile module a little faster, and second, the
- SWIG_TypeClientData() function is faster too.
- + Add the idea of a module into the type system. Before, all the
- types were stored in one huge linked list. Now, another level is
- added, and the type system stores a linked list of modules, each
- of which stores an array of types associated with it.
- + For more information of how the runtime type system now works,
- please see Doc/Manual/typemaps.html and Doc/Devel/runtime.txt
-
- - Update all language modules to use the new type system. The changes
- to each language module are minor. All languages are now able to
- use runtime.swg for external access to the type system. Before
- only python and perl did.
-
- - [guile, mzscheme, ocaml, and php4] These languages opened up the
- init function inside the .cxx code, and any code in the .swg files
- in the init section was inside this function. This was a problem
- for swiginit.swg, which needs to be inserted before the SWIG_init
- function is opened. Thus I changed these languages to be like
- python or perl, where the init function is declared in the .swg
- file.
-
- - [Ruby] Instead of moving the init function to the .swg file, I
- added a new section initbeforefunc, and then added
- %insert(initbeforefunc) "swiginit.swg"
-
- - [MzScheme] Fix enums and fix Examples/Makefile.in so that if
- multiple -I arguments are specified in the INCLUDES variable, each
- gets a ++ccf.
-
- - [Guile GH] Update Guile GH to use the new type system. See
- Doc/Manual/Guile.html for how smobs are now used.
-
-01/11/2005: wsfulton
- [C#] New typemap called 'csconstruct'. The code in this typemaps was previously hard
- coded and could not be customised by a user. This typemap contains the code that is
- generated into a proxy class's constructor.
-
- [Java] New typemap called 'javaconstruct'. The code in this typemaps was previously hard
- coded and could not be customised by a user. This typemap contains the code that is
- generated into a proxy class's constructor. Another typemap named 'javaconstruct_director'
- is used instead when the proxy class is a director class.
-
- [C#, Java] If a C++ class did not have a default constructor, a protected default constructor
- was automatically generated by SWIG. This seems is unnecessary and has been removed
- and thereby giving the user almost complete control over the generated code along with the
- new typemaps above.
-
-19/12/2004: mmatus
- [Disabled, see entry 02/15/2004]
- - Fix typemap search, now the "out" typemap search is done as follows
-
- int *Foo::foo(int bar) -> int *Foo::foo(int bar)
- -> int *Foo::foo
- -> int *foo(int bar)
- -> int *foo
- -> int *
-
- then, now you can be more specific, and define
-
- /* apply only for 'Foo::foo' method */
- %typemap(out) int * Foo::foo(int *bar) ...;
-
- /* apply for all 'foo' functions/methods */
- %typemap(out) int * foo(int *bar) ...;
-
- %inline {
- struct Foo {
- int *foo(int *bar);
- };
- }
-
-
-15/12/2004: mmatus
- - More fixes for templates and template default args.
- See template_default.i for scary cases that now are
- supported, besides the already ugly STL/std cases.
-
- - Cosmetics and more use of 'const' where it was implicit.
- - Other fixes for OSS, which is now working again with 1.3.25.
-
-Version 1.3.24 (December 14, 2004)
-==================================
-
-12/12/2004: wuzzeb (John Lenz)
- [Chicken] Fix a bunch of bugs relating to -proxy support
- + non-class variables now export properly using -proxy
- + static member functions now export properly using -proxy
- + member class variables now export properly using -proxy
- + added a -nounit argument, which does not export the (declare (unit ...))
- + correctly install swigclosprefix.scm
- + constants (enums, defines) now correcly export when using -proxy
-
-12/11/2004: wsfulton
- configure fix for when more than one version of jni_md.h is found
- in the Java include directory (was generating lots of sed error
- messages).
-
-12/08/2004: wsfulton
- [Java] Fixes to arrays_java.i so that one can apply the array
- typemaps to functions taking pointers as input, eg
-
- %include "arrays_java.i"
- %apply int[] {int*};
- void foo(int *a);
-
-12/05/2004: wsfulton
- [Java] Director mods contributed by Scott Michel. New typemaps
- directordisconnect and directordisconnect_derived for the
- swigDirectorDisconnect() method. Also fix to get the javapackage
- typemap working again.
-
-12/05/2004: mmatus
- - Finishing the fixes for templates + default template
- args + specializations.
-
- - [Python] Now we use the new templates + default template
- args in the std/STL library. That means the internal
- swig files are getting uglier since we now support the
- original declarations:
-
- template<class _Tp, class _Alloc = std::allocator< _Tp > >
- class vector {
- ....
- };
-
- template<class _Key, class _Tp, class _Compare = std::less<_Key >,
- class _Alloc = std::allocator<std::pair<const _Key, _Tp > > >
- class map {
- ....
- };
-
- and the user can use the %template directive as
-
- %template() std::vector<int>;
- %template() std::vector<int, std::allocator<int> >;
- %template() std::vector<int, MyAllocator<int> >;
-
- Now we are closer to the cleaning/rewriting of the
- python std/STL support, such that we recover support for
- MSVC++ 6.0, and we can add support for other languages
- too.
-
-
-12/02/2004: wsfulton
- [Java] Fix for directors when wrapping methods using a member enum
- and typesafe/proper enums enabled.
-
-12/01/2004: mmatus
- - Fix typemaps to work with templates and default template
- args, ie
-
- template <class A, class B = int>
- struct Foo {
- };
-
- %typemap(in) Foo<int> *{...}
- %typemap(out) Foo<int,int> *{...}
-
- Foo<int> * foo( Foo<int> *f1, Foo<int,int> *f2);
-
- now 'f1', 'f2' and the return value resolve the provided
- typemaps properly.
-
- This is highly needed for proper STL support, see new
- std_basic_string.i, std_sstream.i, etc.
-
- - Added std_sstream.i, and fix std_basic_string.i to use
- the new typemaps + template def. arg mechanism. Also,
- added the needed std_alloc.i. Now, all the containers
- can be modified to support std::allocator, like in:
-
- template<class T, class A = std::allocator<T > >
- class vector {
- public:
- ....
- };
-
- This change is only completed by now for basic_string.
-
- - Fix for smart pointers + members + extensions:
-
- %extend Foo {
- int extension(int i, int j) { return i; }
- int extension() { return 1; }
- }
-
- %inline %{
-
- class Foo {
- public:
- int y;
- static const int z;
- };
-
- class Bar {
- Foo *f;
- public:
- Bar(Foo *f) : f(f) { }
- Foo *operator->() {
- return f;
- }
- };
-
- now you can
-
- f = Foo()
- f.y = 3
- a = f.z
- f->extension()
-
- b = Bar(f)
- b.y = 3
- a = b.z
- b->extension()
-
- - Other small errors fixes, mostly python.
-
-11/25/2004: wsfulton
- [Java] Numerous director bug fixes so that the correct java types
- and canonicalized types in the JNI code are emitted. Use of the
- $javaclassname special variables in the director typemaps now
- consistent with the non-director typemaps. The types used for
- typemap lookups are also corrected in a few places. If you
- previously had your own director typemaps, ensure they are using the
- correct C++ type.
-
- *** POTENTIAL INCOMPATIBILITY FOR JAVA DIRECTORS ***
-
-11/25/2004: wsfulton
- const enum SWIGTYPE & typemaps added. These wrap const enum references
- as if they were passed by value. Const enum references thus work the
- same as const reference primitive types such as const double &,
- const int & etc. Typemaps added for Java, C#, Ruby, Tcl, Perl and Pike.
-
-11/25/2004: wsfulton
- [Java, C#] New special variable: $*javaclassname, similar to $javaclassname
- and $&javaclassname. The new one removes a pointer from the C type before
- obtaining the Java class name. One or more of $javaclassname,
- $&javaclassname or $*javaclassname may now appear in a typemap. Likewise for
- C# using csclassname instead of javaclassname.
-
-11/25/2004: wsfulton
- The last vestiges of enums being handled as integers removed from the
- internals. The wrapper methods use the enum type rather than an int
- now. The net result is added type safety for enums when handled as
- pointers, references etc. Previously in situations such as a method
- taking a pointer to an enum, a pointer to an int or a pointer to an
- enum of some other type could inadvertantly be passed to the method.
- This is now fixed as the descriptor for an enum is no longer based on
- an int, but the enum type instead. Anonymous enums are still handled
- as integers.
-
- The consequence for scripting language users in correct usage of enums
- should not be noticeable. There is no change for any of the languages
- where enums are passed by value - most of the scripting languages will
- still accept an integer for an enum value and the strongly typed
- languages still use either typesafe enums, integers or proper enums
- depending on what the user configures. For Java and C# users a change
- in the typewrapper class name has occurred (for enum pointers,
- references etc). For example:
-
- enum Numbers { one=1, two };
- enum Numbers* number();
-
- In Java and C# this must now be coded as
-
- SWIGTYPE_p_Numbers n = modulename.number();
-
- rather than
-
- SWIGTYPE_p_int n = modulename.number();
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-11/21/2004: wsfulton/mmatus
- Added missing deprecated warning for %name and remove remaining %name
- usage in the SWIG libraries.
-
-11/21/04: mmatus
- - [Python] Adding the PySwigObject to be used for carrying
- the instance C/C++ pointers. This is used instead of
- string and PyCObjects.
-
- The new PySwigObject is even safer than PyCObject, and
- more friendly than plain strings:
-
- now you can do
-
- print a.this
- <Swig Object at _00691608_p_A>
-
- print str(a.this)
- _00691608_p_A
-
- print long(a.this)
- 135686400
-
- print "%s 0x%x" % (a.this, a.this)
- _00691608_p_A 0x8166900
-
- the last one is very useful when debugging the C/C++
- side, since is the pointer value you will usually get
- from the debugger.
-
- Also, if you have some old code that uses the string
- representation "_00691608_p_A", you can use it now again
- using 'str(ptr)', or by calling 'str = PyObject_Str(obj)'
- in the C/C++ side.
-
- This change is mainly for nostalgic swig users that miss
- the string representation, but also allows to say again
-
- if a.this == b.this:
- return "a is b"
-
- and well, since the change were really simple, maybe in
- the future we will be able to do
-
- next = a.this + 1
-
- or add native python iteration over native C/C++ arrays,
- ie, no need to create/copy new tuples when returning and
- array or vector.
-
- Also, a PySwigPacked object was adding to carry a member
- method pointer, but this is probably a temporal solution
- until a more general object for methods is added.
-
- Be aware that to simplify maintaining and compatibility
- with other tools, the old string and PyCObjects
- representation could disappear very soon, and the
- SWIG_COBJECTS_TYPES or SWIG_NO_OBJECT_TYPES macros will
- have no effect at compilation time. Still, the three
- mechanisms are present in the code just for testing,
- debugging and comparison purposes.
-
-11/21/04: mmatus
-
- - [Python] Adding back support for using the swig runtime code
- inside the user code. We just allow the user to include
- the minimal code needed to implement the runtime
- mechanism statically, just as in done in the swig
- modules.
-
- To use the swig runtime code, for example with python,
- the user needs include the following:
-
- #include <Python.h> // or using your favorite language
- #include <swigrun.swg>
- #include <python/pyrun.swg> // or using your favorite language
- #include <runtime.swg>
-
- the files swigrun.swg, pyrun.swg and runtime.swg can
- be checked out by using swig -co, or they can simply
- be found by adding the swig lib directory to the
- compiler include directory list, for example
-
- SWIGLIB=`swig -swiglib`
- c++ -I${SWIGLIB} ..
-
- of better, using the CPPFLAGS, but that depends on your
- environment.
-
- This change can be ported to the other languages too,
- you just need to isolate the needed runtime code in
- a single file like 'pyrun.swg', and provide the
- SWIG_Runtime_GetTypeList() method. Look at the
- Lib/python/pyrun.swg file and the Examples/python/swigrun
- example.
-
-11/15/04: mmatus
- - Fix mixed_types.i + gcc-3.4, ie, arrays + references +
- typedefs
-
- - Fix multidim arrays + typedefs,ie
-
- typedef char character[1];
- typedef character word[64];
-
- - Process protected/private bases in the same way before
- we process protected/private members, ie, we check
- for constructors, operator new, virtual members, etc.
-
- - Fix Ruby/Java to work (or ignore) multi-inheritance +
- directors. Allow other languages to define if it is
- supported or not.
-
- - Now you can run
-
- SWIG_FEATURES="-directors -dirprot"
- make check-ruby-test-suite
- make check-python-test-suite
- make check-java-test-suite
- make check-ocaml-test-suite
-
- and you will get only 'real' errors. ruby and python
- compile with no errors, java shows some problems.
-
-Version 1.3.23 (November 11, 2004)
-==================================
-
-11/05/2004: wsfulton
- Patch #982753 from Fabrice Salvaire: Adds dependencies generation for
- constructing makefiles. New command line options -MF -MD -MMD to work
- with the current options -M and -MM. These options are named the same
- and work the same as in gcc.
-
-11/05/2004: wsfulton
- %ignore/%rename changes for methods with default arguments to mirror
- %feature behaviour. See previous entry.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-11/04/2004: wsfulton
- %feature improvements for fine tuning when wrapping methods with
- default arguments. Any %feature targeting a method with default arguments
- will apply to all the extra overloaded methods that SWIG generates if the
- default arguments are specified in the feature. If the default arguments are
- not specified in the feature, then the feature will match that exact
- wrapper method only and not the extra overloaded methods that SWIG generates.
- For example:
-
- %feature("except") hello(int i=0, double d=0.0);
- void hello(int i=0, double d=0.0);
-
- will apply the feature to all three wrapper methods, that is:
-
- void hello(int i, double d);
- void hello(int i);
- void hello();
-
- If the default arguments are not specified in the feature:
-
- %feature("except") hello(int i, double d);
- void hello(int i=0, double d=0.0);
-
- then the feature will only apply to this wrapper method:
-
- void hello(int i, double d);
-
- and not these wrapper methods:
-
- void hello(int i);
- void hello();
-
- This has been introduced to make %feature more powerful to ease the migration
- to new default arguments wrapping approach.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
- If you previously had a %feature and didn't specify the default arguments,
- you will have to add them in now or you can obtain the original behaviour
- by using %feature("compactdefaultargs").
-
-11/04/2004: wsfulton
- [C#] Typemaps for std::vector added into std_vector.i. The proxy classes
- generated are modelled on the .NET ArrayList class. This isn't quite
- ready for general consumption yet, but will work with vectors of primitive
- types and some classes.
-
-10/3/2004: wuzzeb (John Lenz)
- [GUILE] The -scm interface is now the default. The old GH interface can
- still be enabled by passing -gh to SWIG.
-
-10/2/2004: mmatus
-
- - More fixes for namespace + class declarations.
- As an extra bonus, we get %template support for static/members class
- methods, ie, now you can say:
-
- namespace space {
- struct A
- {
- template <class Y>
- static void fooT(Y y) { }
- };
- }
-
- struct B
- {
- template <class Y>
- void barT(Y y) {}
- };
-
- %template(foo) space::A::fooT<double>;
- %template(foo) space::A::fooT<int>;
- %template(foo) space::A::fooT<char>;
-
- %template(bar) B::barT<double>;
- %template(bar) B::barT<int>;
- %template(bar) B::barT<char>;
-
- and call
-
- A.foo(1)
- b = B()
- b.bar(1)
-
- note the methods are emitted inside the classes,
- and hence, the %template name refers to the 'member'
- method name, not a global namespace name.
-
-10/31/2004: mmatus
- - Solve namespace + class declarations, as in
-
- namespace foo {
- struct Bar;
- struct Foo {
- };
- }
-
- struct foo::Bar : Foo {
- };
-
- see namespace_class.i for more examples.
-
- - Fix %template directive to properly use namespaces,
- including the case:
-
- namespace one
- {
- template <typename T>
- struct Ptr {};
- }
-
- namespace one
- {
- struct Obj1 {};
- typedef Ptr<Obj1> Obj1_ptr;
- %template(Obj1_ptr) Ptr<Obj1>;
- }
-
- namespace two
- {
- struct Obj2 {};
- typedef one::Ptr<Obj2> Obj2_ptr;
- %template(Obj2_ptr) one::Ptr<Obj2>;
- }
-
- this is done by using the namespace name 'one' to create
- a namespace node to emit the template instantiation,
- just as before, but the template parameters are resolved
- and qualified in the current namespace ('one' or 'two').
- This is same way that typedef works.
-
- This resolve the smart_pointer_namespace2.i case, and at
- the same time, several other ones where before swig was
- generating the
-
- "Can't instantiate template 'xx' inside namespace 'yy'"
-
- error message. In fact, that error doesn't exist
- anymore. You can only get an error if you use a bad
- namespace name or so.
-
-10/30/2004: mmatus
- - [ruby] Directors fixes:
- - enums and std::strings are working now (several
- reports in bug track system)
- - added patch 1025861 for director + exceptions
-
- *** Attention ***: ruby with directors + protected
- members work with version 1.7+. Older versions seems to
- have a broken signature for'rb_protect'.
-
- If you need to use an old version, look at
-
- http://excruby.sourceforge.net/docs/html/ruby__hacks_8hpp-source.html
- for workarounds.
-
- - [ruby] Fix memory allocation problem in typemap (bug 1037259)
-
- - [tcl] Fix (enums|constants) + namespace option
- (reported by jason.m.surprise@intel.com).
-
- - [perl] Add patch 962168 for multiple inheretance
-
- - Fix 'defined' as variable name.
-
-10/29/2004: wsfulton
- Seg fault fix for global scope operator used for friend methods:
-
- class B {
- friend void ::globalscope();
- ...
- };
-
-10/28/2004:mmatus
- - Added module and swig option "templatereduce" to force swig
- to reduce any type needed with templates, ie, in these cases
-
- %module("templatereduce") test
-
- template <class T> struct A { };
-
- typedef int Int;
- %template(A_Int) A<Int> ==> %template(A_Int) A<int>
-
- typedef B* Bp;
- %template(A_Bp) A<Bp> ==> %template(A_Bp) A<B*>
-
- swig reduces the types Int and Bp to their primitives
- int and B*. This is closer to the usual compiler
- resolution mechanism, and it is really needed sometimes
- when you mix templates + typedefs + specializations.
-
- Don't use it if you don't have any problem already,
- since the type reduction can interfere with some
- user typemaps, specially if you defined something like
-
- typedef int Int;
- %typemap(in) Int ...;
-
- in this case, when you use the "templatereduce" option,
- swig will ignore the user typemap, since the "typedef int Int"
- will take precedence, and the usual "int" typemap will be
- applied.
-
- Note that the previous case is not common, and should be
- avoided, ie, is not recommended to use a typedef and a
- typemap at the same time, specially if you are going to
- use templates + specializations.
-
- - Directors:
-
- virtual destructor is always emitted now, this doesn't
- cause any harm, and could solve some nasty and
- mysterious errors, like the one mentioned by Scott.
-
- also the destructor is not in-lined, so, that can solve
- some other mysterious errors when mixing directors +
- imports + embedded applications + some specific compilers.
-
-10/27/2004: wsfulton
- [C#] typemaps.i library file with INPUT, OUTPUT and INOUT typemaps added.
-
-10/27/2004: wsfulton
- [Java] std::wstring typemap fixes in std_string.i from Russell Keith-Magee.
-
-10/25/2004: mmatus
-
- - Using + namespace is working now (using_namespace.i).
-
- - Derived + nested classes is working now
- (deriver_nested.i), but of course, we are still waiting
- for the nested class support.
-
- - Directors:
- - unnamed parameters support,
-
- - protected constructor support (automatic and with
- dirprot mode),
-
- - detection of really needed protected declarations
- (members and constructors) now is done automatically.
- Even if you don't use the 'dirprot' mode, swig will
- wrap what is minimally needed (and protected) for the
- code to compile.
-
- what is public, as usual, is always wrapped, and if
- you use the 'dirport'
-
-
- - Final fixes for the OSS to compile with SWIG 1.3.23 (my
- very very ugly C++ + templates + everything mounters wrap).
-
-10/25/2004: wsfulton
- [C#] New commandline option -dllimport. This enables one to specify
- the name of the DLL for the DllImport attribute. Normally this name
- comes from the module name, so now it is possible to override this:
-
- swig -csharp -dllimport xyz example.i
-
- will generate for all the wrapped PInvoke methods:
-
- [DllImport("xyz", EntryPoint="...")]
- public static extern ...
-
- The wrappers from many different SWIG invocations can thus be compiled
- into one DLL.
-
- A new special variable $dllimport can also be used in typemaps, pragmas,
- features etc. This will get translated into the value specified by -dllimport
- if specified, otherwise the module name.
-
-10/22/2004: wsfulton
- [Java] Patch #1049496 from Scott Michel fixes directors methods with
- enums when wrapped with typesafe or proper Java enums.
-
-10/21/2004: wsfulton
- Fixes for default arguments in director constructors (Python, Ruby, Ocaml).
-
-10/21/2004: mmatus
- - [Python] Add the '-cpluscast' option to enable the 'new'
- C++ casting operators, such as 'static_cast', inside the
- typemaps. By default swig use the old C cast style, even
- when parsing C++.
-
- - [Python] Add the '-new_vwm' option to enable the new
- SwigValueWrapper mode. Now this is mainly for testing
- that the typemaps are really safe for any future
- solution, but you can use it if you have a very strange
- error with default cosntructors missing + %apply +
- %typemap, and if everything else fails (see
- valuwrapper_opaque.i for alternative and current
- solutions). If you are a user that don't know what is
- SwigValueWrapper, don't even try it.
-
- - [Python] Add the '-noh' option to be used with directors
- and when you prefer to disable the generation of the
- director header file. If not used, swig will work as
- usual generating both the wrap.cxx and wrap.h files. If
- you use it, swig will only generate wrap.cxx.
-
-10/21/2004: wuzzeb (John Lenz)
- - If you define SWIG_TYPE_TABLE when compiling a wrapper file,
- the runtime types will be stored in the given type table name.
- Using this, you can seperate different modules to share their
- own type systems. -DSWIG_TYPE_TABLE=Mytable
-
- - [Python] If you define SWIG_STATIC_RUNTIME then the type information
- will be static to this wrapper. Nothing will be shared with any
- other modules
-
- - [Python] If you define SWIG_LINK_RUNTIME, then instead of using
- the new way of sharing type information, the wrapper will expect
- to be linked against the Lib/linkruntime.c file. Any modules compiled
- with SWIG_LINK_RUNTIME and linked against linkruntime.c will all
- share type information.
-
-10/20/2004: mmatus
- - [Python] Initial fix for python/import example. Please
- update the Makefile (autoconf, configure, etc, expert),
- since now probably is only working with g++, icc and a
- few other compilers that have the -shared option.
-
- We need to create additional shared libraries for the
- virtual destructors. Old and usually forgotten C++
- requirement.
-
- Same fix need to be used in perl, I think.
-
- - [Python] Fix generation of header file for directors,
- now directors.swg is also included, so, it can be really
- used from C++, and it solves some problem with compiler
- that require that, even with the simple swig inclusion.
-
- - [Python] Reordering the methods and moving some bodies
- outside the class declaration. This is needed due to
- some gcc-2.96 internal compiler errors. It seems the
- PYTHON class is getting too large to been declared and
- defined at the same time.
-
- - Add the -oh option to change the output header file name
- if needed:
-
- swig -c++ -python test.i -o test.CC -oh test.HH
-
- this is mainly needed when using directors, and if the
- current default header file name is not good for you,
- which is generated as follow:
-
- swig -c++ -python test.i => test_wrap.h
- swig -c++ -python test.i -o test.CC => test.h
-
-
-10/20/2004: wsfulton
- 1) Compact default arguments feature added. This feature allows one
- to use the default argument code generation that was used in
- SWIG-1.3.22 and earlier versions. It produces more compact wrappers
- as only one wrapper method is generated for any method with default
- arguments. So the advantage is it generates less code but has the
- original limitations, like it it does not work with all default arguments
- and default arguments cannot be taken advantage of in the strongly typed
- languages (C# and Java). It is implemented via the usual %feature mechanism:
-
- %feature("compactdefaultargs");
-
- 2) Keyword arguments (kwargs) are working again for default arguments
- in the languages that support it, ie, Python and Ruby. The new default
- argument wrapping approach using overloaded methods cannot support kwargs
- so the compact default argument feature is automatically turned on when
- kwargs are specified, by %feature("kwargs").
-
- 3) Compact default arguments are also automatically turned on when wrapping
- C (not C++) code. This is to support the bizarre notion of default arguments
- for C code.
-
-10/20/2004: wsfulton
- Overloaded templated functions in namespaces also working now.
- Templated functions with default arguments in namespaces too.
-
-10/19/2004: mmatus
-
- - Allow to disable the new SwigValueWrapper mechanism,
- if you add the following line in your language main.
-
- /* Turn on safe value wrapper use mode */
- Swig_value_wrapper_mode(1);
-
-
- Now is only active in python. All the other languages
- are using the old resolution, but they can also use the
- "valuewrapper"/"novaluewrapper" features to fix some
- of the old broken cases. Note, however, that not all
- the broken cases can be solved in that way.
-
- The new mechanism seems to be working fine in perl, ruby
- and tcl, but failing in some typemaps in java.
-
- Hence, is upto the language maintainer to test it, and
- decide to enable it or not.
-
- Look at the valuewrapper_opaque.i for examples.
-
- - Fix more SwigValueWrapper cases when the new mechanism
- is active. Now it also check for local typemap
- variables, see valuewrapper_opaque.i for an example when
- this is needed. But again, this extra checking will only
- be activated when using the new value wrapper mode.
-
- - [Python] Fix variable wrapping of classes with private
- assign operators. It should be easy to fix in all the
- other modules, instead of checking
-
- if (!Getattr(n,"immutable")) ...
-
- you need to verify
-
- if (is_assignable(n)) ...
-
- Look at the private_assign.i for an example.
-
-10/18/2004: mmatus
- - %features "director"/"nodirector" now work as expected.
- - General fixes in %feature to resolve function decl
- properly,
-
- %feature("hello") foo();
- char foo() -> f() // was working
- char *foo() -> f().p // it wasn't
-
-
- - Template + specialization + default template args now is
- working, (don't confuse with template + default arg
- values, that was solved before), now this ugly case is
- working:
-
- template <class T, class A = Alloc<T> >
- struct Vector
- {
- Vector(T a){}
- };
-
- template <>
- struct Vector<double>
- {
- Vector(){}
- int foo() { return 0; }
- };
-
- %template(V_c) Vector<char, Alloc<char> >;
- %template(V_i) Vector<int>; // picks Vector<int,Alloc<int> >
- %template(V_d) Vector<double>; // picks the specialization
-
- this is needed for automatic STL support (later will
- be).
-
- - Fix the template + typedef errors in test-suite, which
- probably will fix another group of strange template +
- namespaces + typedefs errors.
-
- - %warnfilter is working better now, parser.y tries to use
- them when needed.
-
- - **** New default type resolution method (stype.c) *****
-
- It preserves the original mixed types, then it goes
- 'backward' first deleting the qualifier, then the inner
- types, for example:
-
- typedef A *Aptr;
- const Aptr&;
- r.q(const).Aptr -> r.q(const).p.SWIGTYPE
- r.q(const).p.SWIGTYPE -> r.p.SWIGTYPE
- r.p.SWIGTYPE -> r.SWIGTYPE
- r.SWIGTYPE -> SWIGTYPE
-
- enum Hello {};
- const Hello& hi;
- r.q(const).Hello -> r.q(const).enum SWIGTYPE
- r.q(const).enum SWIGTYPE -> r.enum SWIGTYPE
- r.enum SWIGTYPE -> r.SWIGTYPE
- r.SWIGTYPE -> SWIGTYPE
-
- int a[2][4];
- a(2).a(4).int -> a(ANY).a(ANY).SWIGTYPE
- a(ANY).a(ANY).SWIGTYPE -> a(ANY).a().SWIGTYPE
- a(ANY).a().SWIGTYPE -> a(ANY).p.SWIGTYPE
- a(ANY).p.SWIGTYPE -> a(ANY).SWIGTYPE
- a(ANY).SWIGTYPE -> a().SWIGTYPE
- a().SWIGTYPE -> p.SWIGTYPE
- p.SWIGTYPE -> SWIGTYPE
-
- before it always stops after finding ref/pointer/enum/array/etc.
-
- Now, then, you can define (use and apply) 'higher' typemaps such as:
-
- %typemap(in) SWIGTYPE* const&
- %typemap(out) char FIXSIZE[ANY]
- %typemap(in) SWIGTYPE* const&
- %typemap(in) const enum SWIGTYPE&
- %typemap(in) SWIGTYPE[ANY][ANY]
- %typemap(in) const char (&)[ANY]
-
- It is possible with this change that previous typemaps
- that were defined (but ignored), now will start to work.
-
- Also, it is necessary check for the '%typemap(varin) SWIGTYPE[]',
- before it was usually not defined (but char[] was),
- and that can produce some inconsistencies.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
- This change was needed for STL, since std::vector<enum Hello>
- std::vector<A*>, etc, will always generate methods that
- mix const references with the vector type.
-
- Now that is working, all the std::container<T*>
- specialization will not be needed anymore, well, in
- theory.
-
- In the practice, everythin is working as before until
- the proper mixed types are defined and the libraries
- simplified to use them.
-
- - Change the behavior of extern "java"/"fortran"/"etc",
- now swig produces a warning, and use extern "C" instead.
- The warning can also be disable with the "-w 313" flag.
- (WARN_PARSE_UNDEFINED_EXTERN).
-
- - SwigValueWrapper is now more selective (lang.cxx).
-
- [Perl/Tcl]
- - Fix some typemaps (perl/tcl) to work properly with
- SwigValueWrapper. This was not a problem with
- SwigValueWrapper, but with the typemaps that now are
- safe to use with %apply.
-
- [Python]
-
- - Fix %callback/%pythoncallback work now as before after
- the def args changes. Also, %callback now is an alias
- for %pythoncallback, so, they do the same.
-
- [Python/Ruby]
- - %callback is more usable and uniform:
-
- %callback("%s_cb") foo(); // for both, python/ruby
- %callback("%s_cb"); // for both, python/ruby
- %callback(1) foo(); // only in python.
-
-10/17/2004: arty
- [OCAML]
- - Tweak to enum typing for soundness in the presence of multiple
- modules.
- - global functions are now unambiguous in multiple loaded modules.
- - Fixed test case code to build multimodule test cases correctly.
- - There is no way to share overload resolution across modules
- because of soundness issues. If the user wants to call some
- function foo from an arbitrary module bar, they will have to
- use Bar._foo to call it correctly. Later I will fix the
- camlp4 module to do something clever in this case.
- - Promided performance overhaul of class mechanism.
- - Removed symbol hack for ocaml-3.07 and below which is not needed
- for ocaml-3.08 and above.
-
-10/16/2004: wuzzeb (John Lenz)
- [CHICKEN]
- - Completly change how chicken.cxx handles CLOS and generic code.
- chicken no longer exports -clos.scm and -generic.scm. The clos
- code is exported directly into the module.scm file if -proxy is passed.
- - The code now always exports a unit. Running the test-suite is now
- majorly broken, and needs to be fixed.
- - CLOS now generates virtual slots for member variables similar to how
- GOOPS support works in the guile module.
- - chicken no longer prefixes symbols by the module name, and no longer
- forces all names to lower case. It now has -useclassprefix and -closprefix
- similar to how guile handles GOOPS names.
-
-10/16/2004: wsfulton
- Templated functions with default arguments working with new default argument
- wrapping approach. The new approach no longer fails with the following default
- argument pattern (previously failed with some primitive types, like
- unsigned primitive types):
-
- template<typename T> int foo(const T& u = T());
- %template(foo) foo<unsigned int>;
-
- This relies on the templated function overloading support just added, so all
- the combinations of overloading by template parameters and normal parameters
- as well as overloading with default parameters works.
-
-10/16/2004: wsfulton
- Added support for the large range of templated function overloading that C++
- supports.
-
- - Overloaded templated functions, eg
-
- template<typename T> int overload(T t);
- template<typename T> int overload(T t, const T &r);
-
- - Fixes where the templated type is not used in the parameter list, eg
-
- template<typename T> void xyz();
- template<> void xyz<double>();
-
- - Fixes for overloading of plain functions by a templated function:
-
- void abc(double d);
- template<typename T> void abc(T t);
-
- - Overloading by templated parameters fixed:
-
- template<typename T> void foo(T t) {}
- template<typename T, typename U> void foo(T t, U u) {}
-
- %template(foo) foo<double, double>;
-
- - All combinations of the above also working including specializations, eg:
-
- void abc(double d);
- template<typename T> void abc(T t);
- template<> void abc<double>(double t);
- template<> void abc(int t);
-
-10/16/2004: wuzzeb (John Lenz)
- - Remove the ability to share type information by using c linking.
- All type sharing happens through a global variable in the target language.
- + Remove SWIG_NOIMPORT, SWIG_RUNTIME, and related defines.
- + Deprecate -runtime, -noruntime command line options
- + Update test-suite common.mk to correctly build multicpptest
- + Remove reference to precommon.swg
- + Update the guile_gh interface to share data by a global var instead
- of c linkage.
-
- - Remove Advanced.html, since everything in it is now obsolete
-
-10/09/2004: mmatus
- - Split the python std/STL C++ library files, now
- all the language independent definitions are under
- the directory
-
- Lib/std
-
- and hence, can be used from other languages.
-
- - Add more documentation to the Python STL, and
- clean unnecessary code.
-
- - Add initial C99 complex support, and some fixes
- for long double.
-
-10/08/2004: mmatus
- - Fix the SwigValueWrapper for opaque types, now it is
- applied for opaque templates and classes, for which we
- don't know if there is or not a default constructor, ie
-
- struct A {
- A(int);
- };
-
- Still, if you know that you class has a default
- constructor, and for some very very particular reason
- you want to avoid the SwigValueWrapper, and you don't
- want or can't expose the class to swig, now you can
- say
-
- %feature("novaluewrapper") A;
- class A;
-
- or the other way around, if the class has a default
- constructor, but you want to use the value wrapper, you
- can say
-
- %feature("valuewrapper") A;
- struct A {
- A();
- ....
- };
-
- - Fix for char > 128, ie
-
- const char tilde_a = '\341';
-
- - Add patch 1041858 for $lextype, which carries the
- literal type of a symbol. See lextype.i in the
- test-suite for more details.
-
-
-
-
-10/07/2004: wsfulton
- {Ruby, Java] Fix director + 'empty' throws
-
- struct A {
- A() throw();
- virtual ~A() throw();
- int foo() throw();
- };
-
-
-10/06/2004: wuzzeb (John Lenz)
- [TCL]
- - Fix bug reported by William A. Hoffman propagating clientdata
- between modules. Added clientdata_prop.multicpptest to check for
- this bug. The fix involved the following changes:
- + SwigType_clientdata_collect does not need to check
- types in r_resolved because we only want to propagate clientdata
- to typedefed classes, and r_mangled already takes care of typedefs.
-
- + SWIG_TypeRegister now copies the clientdata field correctly
-
- + Move SWIG_Guile_PropagateClientData function from guile module
- into common.swg, because we need to call it from both guile and tcl.
-
- + Add base_names to swig_class to delay the lookup of bases. SWIG
- now exports the base names and only when the base swig_class is
- needed is SWIG_TypeQuery(name)->clientdata looked up.
-
- - conversion_ns_template testsuite test was failing because
- the name of the wrapped constructor function was not calculated
- correctly for structs. Fixed.
-
-10/06/2004: wsfulton
- Fixes for default arguments used in directors - in virtual
- methods and director constructors.
-
-10/06/2004: mmatus
- Fix the __cplusplus macro, and bug 1041170.
- Now it is working as supposed, ie, you can safely use
-
- #ifdef __cplusplus
- ...
-
- all over swig, including inside %defines and %{ %} bodies.
-
-
- *** POTENTIAL INCOMPATIBILITY ***
-
- The old trick of using
-
- #if __cplusplus
-
- doesn't work any more. So, if you have your own typemaps
- using that syntax, you will need to migrate them to use
- "#ifdef __cplusplus".
-
-10/05/2004: wuzzeb (John Lenz)
- - Reorganize how runtime type information is stored and shared
- between modules. For chicken and mzscheme, I removed
- the ability to use runtime libraries, while perl, tcl, python, and
- ruby default to using the new method but can go back to the old
- method by declaring SWIG_ALLOW_RUNTIME.
-
- - line 582 in mzscheme.cxx was generating a segfault on
- imports.multicpptest, so I fixed it.
-
-10/05/2004: wsfulton
- Fixes for %extend and overloaded static methods with default
- arguments.
-
-10/05/2004: mmatus
- - [python] Fix director + method with 'empty' throw, ie
-
- struct A {
- virtual int foo() throw();
- };
-
- other languages should also easy to fix, look for
- Getattr(n,"throw") in python.cxx.
-
- - Fix director + destructor with 'empty' throw
-
- struct A {
- virtual ~A() throw();
- };
-
- - Now SWIG_FEATURES parse all and the same options you
- can pass to swig in the command line.
-
- - New command line flag: -features <list>, as in
-
- swig -features autodoc=3,director
-
- ie, any global feature can be initialized from the
- command line. This is mainly for testing, but users
- can also take advantage of it.
-
-10/04/2004: mmatus
- - Properly qualify type in syntax as 'long(2)' or 'Foo()',
- this solve old problem with default args, and probably
- other problems around. However, the default arg problem
- was also already solved by William (see below).
-
- - Fix feature_set and feature_get methods. Before
- they look from particular to general and keep the first
- feature found. This didn't work well with templates.
- Now the methods look from general to particular, and
- override any found feature.
-
- - Previously a feature could not be applied to constructors
- or destructors that weren't explicitly declared in the class.
- This is now fixed, for example:
-
- %feature("featurename") Foo() "..."
- %feature("featurename") ~Foo() "..."
- class Foo {
- // implicit Foo() and ~Foo()
- };
-
- - Fix missing features for default const/dest, by really
- 'creating' the methods and applying the features.
-
- - Fix return_const_value.i case by adding SwigValueWrapper<const T>
- specialization.
-
- - Fix %extend + overload, including overloading actual
- class methods.
-
- - Adding more cases in related files in the test-suite.
-
-10/04/2004: wsfulton
- Changes to the way default arguments are wrapped. Previously a single
- method was generated for each method that had default arguments. If
- a method had 5 arguments, say, of which 1 had a default argument
- then the call to the wrapped method would pass 5 arguments. The default
- value was copied into the wrapper method and used if the scripting
- language passed just 4 arguments. However, this was flawed as the
- default argument sometimes does not have global access, for example
- SWIG would generate code that couldn't compile when wrapping:
-
- class Tricky {
- public:
- void foo(int val = privatevalue);
- void bar(int val = Tricky::getDefault());
- private:
- static int getDefault();
- enum { privatevalue = 200 };
- };
-
- Also bugs in resolving symbols generated code that wouldn't compile, for example
- (probably fixable though):
-
- namespace Space {
- class Klass {
- };
- Klass constructorcall(const Klass& k = Klass());
- }
-
- The approach also does not work for statically typed languages (C# and Java)
- as these languages do not allow methods to have variable number of arguments.
- Although C# has a mechanism to pass a variable number of arguments they
- must be of the same type and are more like varargs.
-
- The new approach solves the above problems and wraps methods with default
- arguments as if the method was overloaded. So SWIG will now treat
-
- void foo(int val=0);
-
- as if it had parsed:
-
- void foo(int);
- void foo();
-
- The code generated is then exactly the same as if SWIG had parsed the two
- overloaded methods. The scripting languages count the arguments passed and call
- the appropriate method, just like overloaded methods. C# and Java are now able
- to properly wrap methods with default arguments by generating extra methods,
- again as if the method was overloaded, so for:
-
- void bar(string s="hello", double d=10.0, int i=0);
-
- the following proxy methods are generated:
-
- void bar(string s, double d, int i);
- void bar(string s, double d);
- void bar(string s);
- void bar();
-
- The new approach comes with a couple of minor knock on effects.
-
- 1) SWIG support for default arguments for C (not C++) code no longer works.
- Previously you could have this interface:
-
- %{
- void foo(int val);
- %}
- void foo(int val=0);
-
- and call the wrapped method from a scripting language and pass no arguments
- whereupon the default of 0 was used. You can get the same behaviour for C
- code by using the "default" typemap:
-
- %typemap(default) int val "$1 = 0;"
- %{
- void foo(int val);
- %}
- void foo(int val);
-
- or you could of course compile your code as C++ if you want C++ features :) :
-
- %{
- void foo(int val=0);
- %}
- void foo(int val=0);
-
- A couple of SWIG's libraries used this C extension and these have been modified
- to use the "default" typemap. The "default" typemap is thus unchanged (and still
- is not and is not fully supported by C# and Java, and is likely to remain so).
-
-
- 2) All features (%feature, %rename, %ignore etc) no longer work as if the method
- with default arguments is just one method. For example, previously
-
- %ignore foo(int);
-
- would have ignored the method completely. Now it will only ignore foo(int) but
- not the extra foo() method. Instead use:
-
- %ignore foo;
-
- to ignore them all. or
-
- %ignore foo(int);
- %ignore foo();
-
- This of course allows one to fine tune the wrapping, for example one could use:
-
- %rename(fooint) foo(int);
- %rename(foodefaults) foo();
- void foo(int val=0);
-
- and call them from any language like so:
-
- fooint(200)
- foodefaults()
-
- or for example ignore the extra overloaded method, so the defaults cannot be used:
-
- %ignore foo();
- void foo(int val=0);
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-10/2/2004: mmatus
- [Python]
- - More cleaning up and uniformation on the Python Lib
-
- - Added Robin's docstring patch, plus some fixes, plus
- some extensions, see autodoc.i example in the test-suite,
- and try using %feature("autodoc","extended").
-
- This patch is not a complete solution for the
- documentation problem, just enough to inform python about
- the parameter list.
-
- The expected swig documentation support is far far away yet.
-
-
-10/1/2004: mmatus
- - Fix the %callback feature (only used in ruby and python examples,
- by now, but it should be generic), now member callbacks
- are working again
-
- - Fix wrapping of functions pointers like
-
- std::ostream& std::endl(std::ostream&);
-
- ie, the ones that return references or enums.
-
- [Python] Add the %pythoncallback directive, which is
- an improved version of %callback, ie,
-
- %pythoncallback(1) foo;
- %pythoncallback(1) A::bar;
- %pythoncallback(1) A::barm;
-
- int foo(int a) {
- return a;
- }
-
- struct A
- {
- static int bar(int a);
- int barm(int a);
-
- };
-
- int foobar(int a, int (*pf)(int a));
-
- in python you can use
-
- foo(2)
- foobar(2,foo)
- A.bar(2)
- foobar(2,A.bar)
-
- ie, no additional pointer elements are created, and
- the original 'foo' and 'A.bar' can be used as parameters.
-
- In the case of member function however, still you need
- to use the special variable Class::<fnc_name>_cb_ptr, ie:
-
- foobarm(3, a, A.barm_cb_ptr)
-
- we will try to fix this situation also, but later.
-
- [Python] Add more elements from the STL library, now
- you can use
-
- import std
- std.cout << "hello " << 123 << std.endl
-
- [Python] Fix in/out return mechanism, now swig will behave
- as 1.3.21 but using a python list when needed. The problem
- is that the types std::pair,std::vector,etc, use tuples,
- and they interfer with the previous inout tuple type.
-
- By using lists we solve the conflicts, swig acts as before,
- but returns a list when more than one parameter are using
- the OUT typemap. See the new inout.i example in the
- test-suite.
-
- *** POTENTIAL INCOMPATIBILITY FOR PYTHON MODULE ***
-
- [Python] Much better error messages for bad arguments, now
- you always get the argument number where the error occurred.
-
-09/27/2004: wsfulton
- Patch from Bill Clarke -
- 1) Warning emitted when -importall and -includeall is used together,
- with -includeall taking precedence.
- 2) Ensure SWIGIMPORTED is always defined when a file is being
- imported with %import. Note that this is not the same as SWIGIMPORT,
- which gets defined in all generated wrapper files.
-
-09/26/2004: mmatus
-
- - add %feature("exceptionclass") to identify a class used
- as exception. Before swig identified and marked a class
- using the "cplus:exceptionclass" attribute. However, the
- class needed to appear on an throw() statement. Now
- swig keeps trying to identify the exception classes, as
- before, but it also allows the user to mark a class by
- using the %feature explicitly. (mostly relevant for
- python and chicken)
-
- [Python]
-
- - fix -modern option + exceptions, which mix old class
- style with the new one. So, we always need to emit
- the "nonmodern" python code.
-
- - add the "python:nondynamic" feature and its handler
-
- now if you have
-
- %pythonnondynamic A;
-
- struct A {
- int a;
- int b;
- };
-
- then, in the python side
-
- aa = A()
-
- aa.a = 1 # ok
- aa.b = 2 # ok
- aa.c = 3 # error, the class can not be extended dynamically.
-
-
- Since this is a feature, you can use
-
- %pythonnondynamic;
-
- or
-
- %pythondynamic; [ Note: %pythondynamic since deprecated ]
-
- to force all the wrapped classes to be "nondynamic" ones.
-
- The default, as in regular python, is that all the wrapped
- classes are dynamics. So, careful with your spelling.
-
-09/14/2004: mmatus
- - Support the -I- option.
-
- - Differentiate between %include <file> and %include "file".
- This fix several corner cases.
-
-
- [Python] Several patches:
-
- - Normalize the Lib file names:
- *.swg internal files,
- *.i user files.
-
- - Fix Char[ANY] typemaps, so they also delete any extra '\0' chars,
- now they behave as before (1.3.21). Still, you can use
- the SWIG_PRESERVE_CARRAY_SIZE macro if you need to
- preserve the original size (see pystrbase.swg).
-
- - Add the Char FIXSIZE[ANY] typemaps, to preserve the
- original C array sizes (see above). Though, you can't
- use them yet since %apply and arrays are not working
- together.
-
- - Add pyfragments.swg, now the user can add fragments
- to override the default ones.
-
-09/10/2004: wsfulton
- Patch from Bill Clarke which fixes spurious preprocessor bug which
- shows on Solaris and gcc, eg:
- Warning(202): Could not evaluate '!defined(SWIGJAVA) &&
- !(defined(SWIGCSHARP)'
- Also fixes a bug where '#if "a" == "b" == 1' wouldn't have worked
-
-09/10/2004: wsfulton
- Restored multiple build directories for the test-suite. Patch from
- Bill Clarke.
-
-09/06/2004: wsfulton
- Added the missing runtime.dsp Visual Studio project files for the
- import examples to work.
-
-
-Version 1.3.22 (September 4, 2004)
-==================================
-
-09/03/2004: wsfulton
- The swig.m4 macro for use with the Autoconf/Automake/Libtool has
- been removed and is no longer installed. Please use the new and better
- maintained version derived from swig.m4 in the Autoconf macro archive.
- See http://www.gnu.org/software/ac-archive/htmldoc/ac_pkg_swig.html and
- http://www.gnu.org/software/ac-archive/htmldoc/ac_python_devel.html.
-
-09/01/2004: wsfulton
- [Perl] Applied patch #1019669 from Christoph Flamm. Adds support
- for %feature("shadow") in the same way as it works in Python. This
- enables one to override the generated shadow/proxy methods, including
- constructors and destructors. For example:
-
- /* Let's make the constructor of the class Square more verbose */
-
- %feature("shadow") Square(double w)
- %{
- sub new {
- my $pkg = shift;
- my $self = examplec::new_Square(@_);
- print STDERR "Constructed an @{[ref($self)]}\n";
- bless $self, $pkg if defined($self);
- }
- %}
-
- class Square {
- public:
- Square(double w);
- ...
- };
-
-08/31/2004: mmatus
- [Python] Incompatibility reported by Bill Clarke (llib@computer.org):
-
- If you are using Sun Studio 8 (and possibly earlier
- versions) to compile the output produced by swig
- 1.3.22rc1, and you are using C++ and STL templates then
- you need to use either "-runtime" or "-noruntime". If you
- use neither of these options then you will probably get
- compiler errors when trying to compile the wrapper file;
- the error message will be like this: The name
- SWIG_Python_ConvertPtr[...] is unusable in static
- swigpy::traits_asptr[...] If you get this error message,
- you need to regenerate your wrapper file using 'swig
- -runtime' or 'swig -noruntime'.
-
- You shouldn't get this problem with Sun Studio 9.
-
- *** POTENTIAL INCOMPATIBILITY FOR PYTHON MODULE ***
-
-08/26/2004: wsfulton
- [Perl] Applied #932333 from Ikegami Tsutomu. Fixes long long *OUTPUT
- and unsigned long long *OUTPUT typemaps in typemaps.i.
-
-08/26/2004: wsfulton
- Applied patch #857344 from Art Yerkes. Workaround for autoconf bug when
- running 'make install'.
-
-08/26/2004: wsfulton
- [Perl] Part of patch #982753 applied. This implements a %perlcode directive.
- It allows one to add Perl code to the generated .pm file. Works the same
- as %pythoncode.
-
-08/26/2004: wsfulton
- [Java] Fix for directors when wrapping virtual methods with exception
- specifications that were not simple types. Previously code was generated that
- didn't compile, for example when the exception specification was a pointer.
-
-08/25/2004: wsfulton
- [C#] Typemap fix for methods that return char *. The CLR would incorrectly
- delete the memory pointed to by char *. Also applied the same correction to
- the char array typemaps.
-
-08/24/2004: wsfulton
- Fixes for -fmicrosoft error/warning message display:
- - End of file (EOF) warning messages not displaying in correct format
- - Some messages containing a file path were displaying a double backslash
- instead of a single backslash
-
-08/23/2004: wsfulton
- Applied patch #1011604 submitted by Charles Schwieters. Fix for 64 bit tcl
- interpreters.
-
-08/23/2004: wsfulton
- Fix for bug #875583 - enum forward declarations previously gave a syntax error.
-
-08/23/2004: mkoeppe
- [Allegro CL] Use typemaps "ffitype" and "lisptype" to determine the FFI type
- specifiers from the C type. This makes it possible, for instance, to control
- whether a C "char" argument takes a Lisp character or a Lisp integer value.
- The default (taking Lisp characters) is done by these built-in typemaps:
- %typemap(ffitype) char ":char"
- %typemap(lisptype) char "character"
- If char means an integer instead, use these typemaps:
- %typemap(ffitype) char ":char"
- %typemap(lisptype) char "integer"
-
-08/22/2004: wsfulton
- As discussed in bug #772453, the SWIG library directory is now installed
- into a different default directory. The library used to be installed to
- /usr/local/lib/swig1.3. It is now in the more usual architecture independent
- directory and I have additionally used a version specific subdirectory as
- the library will rarely work with older versions of SWIG. This release
- will thus use /usr/local/share/swig/1.3.22 by default, which can be
- tailored as before using './configure --swiglibdir'.
-
-08/17/2004: mkoeppe
- [MzScheme] Add support to create native MzScheme structures from C structures.
- To convert a C structure to an MzScheme structure, use the new runtime macro
- SWIG_NewStructFromPtr in a typemap. Patch from Dmitriy Zavin.
-
-08/12/2004: wsfulton
- Patch #837715 from Ben Reser to correctly detect Python lib directory
- on 64 bit systems.
-
-08/12/2004: wsfulton
- [C# and Java] Prevent memory leaks in the case of early return
- from wrapper methods using const std::string & parameters. Modified
- Mark Traudt patch #951565.
-
-08/12/2004: wsfulton
- Bug #943783 with patch fixes php char * out typemap NULL values.
-
-08/03/2004: Ahmon Dancy <dancy@dancy>
-
- [allegrocl] Additional case mode fixes. Also, make sure
- foreign types are exported.
-
-07/24/2004: mkoeppe
- [Guile] In -scm mode, SWIG modules now exchange their pointer type
- information via the Guile interpreter. It is no longer necessary to build a
- runtime library or to use -noruntime and -runtime etc.
-
- The module (Swig swigrun) which was introduced in the change of 05/17/2004 is
- no longer automatically built. If you need it, run SWIG on the interface file
- swigrun.i.
-
-07/23/2004: wsfulton
- [C#] Bug #917601 Mapping C++ bool fix from Mark Traudt
-
-07/23/2004: wsfulton
- RPM fixes for latest CVS version including removal of runtime
- library.
-
-07/23/2004: wsfulton
- Patch #908955 from Robert H De Vries.
- RPM file generation fix for Fedore Core 1 and Redhat AS2.1.
-
-07/12/2004: wsfulton
- Patch #864689 from Robin Dunn:
-
- This patch corrects two problems in the XML output of SWIG:
-
- 1. There were often extra '/>\n' in the output.
-
- 2. value attributes were output with '\n' in them but
- since that is not technically legal most (all?) XML
- parsers will strip them out. Replacing the '\n' with
- the '&#10;' entity reference solves this as that is
- legal and XML parsers will convert it to a '\n' when
- reading the values back in.
-
- This patch also adds a new global command line option
- that will allow the parse tree to be written out in XML
- *after* some other language module has been run, in
- order to be able to get extra info that the language
- module puts in the tree. In this way the XML is a
- post-processed version of the tree rather than a
- pre-processed version.
-
- Command line option is -dump_xml or -xmlout <file>
-
-07/12/2004: wsfulton
- [Java] Patch from Scott Michel to fix typesafe enums and proper enums
- with directors.
-
-07/12/2004: wsfulton
- HTML documentation (makechap.py) file generator missing end of line
- patch #908951 from Robert de Vries.
-
-07/08/2004: wsfulton
- The deprecated runtime library build has been removed. This also removes
- the dependency on Libtool. Libtool is no longer required to build SWIG.
- The associated -ldflags SWIG commandline option has also been removed.
-
- The examples and test-suite testcases that used the runtime library have
- been updated to use the replacement approach to using SWIG across
- multiple modules, that is they use the -noruntime and -runtime commandline
- options, see Modules.html. Effectively they build their own runtime
- libraries using -runtime. The examples are import and import_template.
- The test cases are in the imports and template_typedef_import directories.
-
- Anyone who wants the original runtime libraries can either run the test-suite
- or build the examples and use the appropriate shared object/DLL that is
- generated with the -runtime commandline option. For example libimports_runtime.so
- (Python calls it lib_imports_runtime.so) is generated after running the
- 'make imports.multicpptest' testcase in the Examples/test-suite/<lang>
- directory. Or use libruntime.so / runtime.dll after building the import
- examples in Examples/<lang>/import.
-
-07/07/2004: mkoeppe
- [Allegro CL] Convert character and string literals in constants to
- CL syntax. Fix FF:DEF-FOREIGN-CALL for mixed-case C functions.
-
-06/27/2004: wsfulton
- [Java] New feature for Java exceptions with format %javaexception(exceptionclasses).
- This feature is a slight enhancement to %exception and the only difference is the
- addition of the exception classes which are generated into a throws clause.
- The 'exceptionclasses' is a comma separated list of classes which will be
- added to the associated proxy method's throws clause. The 'exceptionclasses'
- are specified like the exception classes in the 'throws' attribute in the
- typemaps. This feature should be used for correctly handling checked exceptions
- thrown from JNI code. For example:
-
- %javaexception("java.lang.Exception") throwException %{
- ... convert a std::logic_error into a java.lang.Exception using JNI code ...
- %}
-
- #include <stdexcept>
- void throwException() {
- throw std::logic_error("Logic error!");
- }
-
- will generate a method with a throws clause in the module class:
-
- public static void throwException() throws java.lang.Exception { ... }
-
-06/27/2004: wsfulton
- [C#] New %csconstvalue(value) feature directive for use with constants and
- enums. This works the same way as %javaconstvalue. For C#, this directive
- is the only way that one can fix wrapping of C/C++ enums with proper C#
- enums if the enum item's initialiser cannot compile as C# code. This is
- because Java enums can use a call into C code to initialise the enum item,
- whereas in C#, the enum value must be a compile time constant. That is,
- using %csconst(0) cannot be used in C# to initialise the C# enum item via
- a PINVOKE call.
-
-06/27/2004: wsfulton
- [Java] New %javaconstvalue(value) feature directive for use with constants and
- enums. Sometimes the use of %javaconst(1) will produce code that won't compile
- under Java. If a compile time constant is required, %javaconst(0) is not an
- option. The %javaconstvalue directive achieves this goal and the value specified
- is generated as Java code to initialise the constant. For example:
-
- %javaconst(1);
- %javaconstvalue(1000) BIG;
- %javaconstvalue("new java.math.BigInteger(\"2000\")") LARGE;
- %javaconstvalue(10) bar;
- %{
- const int bar = 10;
- %}
- %inline %{
- #define BIG 1000LL
- #define LARGE 2000ULL
- enum Foo { BAR = ::bar };
- %}
-
- Generates:
-
- public interface exampleConstants {
- public final static long BIG = 1000;
- public final static java.math.BigInteger LARGE = new java.math.BigInteger("2000");
- }
- public final class Foo {
- public final static Foo BAR = new Foo("BAR", 10);
- ...
- }
-
- Previously, none of BIG, LARGE or BAR would have produced compilable code
- when using %javaconst(1).
-
-06/27/2004: wsfulton
- %feature enhancements. Features can now take an unlimited number of attributes
- in addition to the feature name and feature value. The attributes are optional
- and are much the same as the typemap attributes. For example, the following
- specifies two optional attributes, attrib1 and attrib2:
-
- %feature(featurename, attrib1="attribval1", attrib2="attribval2") name "val";
- %feature(featurename, val, attrib1="attribval1", attrib2="attribval2") name;
-
-06/27/2004: wsfulton
- %feature improvements for the syntax that takes the feature value within the
- %feature() brackets. The value specified is no longer restricted to being just
- a string. It can be a string or a number. For example, this is now acceptable
- syntax:
- %feature("featurename",20.0);
- whereas previously it would have to have been:
- %feature("featurename","20.0");
- Useful for features that are implemented as a macro, for example:
- #define %somefeature(value) %feature("somefeature",value)
- These will now work accepting either a string or a number:
- %somefeature("Fred");
- %somefeature(4);
-
-06/06/2004: wuzzeb (John Lenz)
- [Chicken, Guile]
- - Created the Examples/test-suite/schemerunme directory, which holds all the
- runme scripts for guile and chicken (and possibly mzscheme...). The guile
- and chicken _runme files then (load "../schemerunme/foo.scm").
- - In chicken module, fix a few bugs invlolving dynamic casts.
-
-06/03/2004: wsfulton
- Patch to fix wrapping of templated methods. ISO compliant compilers, like
- Comeau and GCC-3.4.0, don't like the template specifier that SWIG was generating
- when calling the method. This fix may break some non standard compliant compilers,
- for example, Sun workshop compilers prior to version 6.2.p2. Patch submitted
- by Bill Clarke.
-
-06/03/2004: wsfulton
- [Java, C#] Undocumented special variable $imclassname removed.
- New special variable $module is replaced by the module name, as specified
- by %module or -module commandline option. $imclassname can be created from $module.
-
-06/03/2004: wsfulton
- [C#] Same as for Java below. The new typemaps are named differently, namely,
- csbody and csbody_derived. The deprecated typemaps are csgetcptr and
- csptrconstructormodifiers.
-
- *** POTENTIAL INCOMPATIBILITY FOR C# MODULE ***
-
-06/03/2004: wsfulton
- [Java] Typemap changes for the Java proxy / typewrapper and enum classes. A new
- typemap called javabody contains the essential support code for generation into the body
- of these classes. There is also a new javabody_derived typemap which is used instead for
- wrapped classes that have a wrapped base class. The code is basically, the getCPtr()
- method and swigCPtr and swigCMemOwn member variables. These used to be hard coded
- with no way to modify the code. The introduction of this typemap makes it possible for
- the user to tailor nearly every aspect of the code generation.
- The exception now is the code for director classes.
-
- The javagetcptr and javaptrconstructormodifiers typemaps are deprecated and are
- no longer used as the code that these generated can be put in the more flexible
- javabody and javabody_derived typemaps.
-
- *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
-
- The following macros contributed by Scott Michel may help you upgrade if you have used
- the javagetcptr typemap:
-
- /* Utility macro for manipulating the Java body code method attributes */
- %define SWIGJAVA_ATTRIBS(TYPENAME, CTOR_ATTRIB, GETCPTR_ATTRIB)
- %typemap(javabody) TYPENAME %{
- private long swigCPtr;
- protected boolean swigCMemOwn;
-
- CTOR_ATTRIB $javaclassname(long cPtr, boolean cMemoryOwn) {
- swigCMemOwn = cMemoryOwn;
- swigCPtr = cPtr;
- }
-
- GETCPTR_ATTRIB static long getCPtr($javaclassname obj) {
- return (obj == null) ? 0 : obj.swigCPtr;
- }
- %}
-
- %typemap(javabody_derived) TYPENAME %{
- private long swigCPtr;
-
- CTOR_ATTRIB $javaclassname(long cPtr, boolean cMemoryOwn) {
- super($moduleJNI.SWIG$javaclassnameUpcast(cPtr), cMemoryOwn);
- swigCPtr = cPtr;
- }
-
- GETCPTR_ATTRIB static long getCPtr($javaclassname obj) {
- return (obj == null) ? 0 : obj.swigCPtr;
- }
- %}
- %enddef
-
- /* The default is protected getCPtr, protected constructor */
- SWIGJAVA_ATTRIBS(SWIGTYPE, protected, protected)
-
- /* Public getCPtr method, protected constructor */
- %define PUBLIC_GETCPTR(TYPENAME)
- SWIGJAVA_ATTRIBS(TYPENAME, protected, public)
- %enddef
-
- /* Public getCPtr method, public constructor */
- %define PUBLIC_BODYMETHODS(TYPENAME)
- SWIGJAVA_ATTRIBS(TYPENAME, public, public)
- %enddef
-
-06/03/2004: wsfulton
- [Java, C#] The contents of the class modifier typemaps and pragmas have changed.
- They must now include the class type. Previously 'class' was hard coded.
- This change enables flexibility into what type of class is generated,
- for example the proxy class could be an interface instead of a class.
-
- For Java this affects the javaclassmodifiers typemap and the jniclassclassmodifiers
- and moduleclassmodifiers pragmas.
-
- For C# this affects the csclassmodifiers typemap and the imclassclassmodifiers
- and moduleclassmodifiers pragmas.
-
- Unless you have overridden the default versions of these typemaps or pragmas, you
- shouldn't be affected. However, if you have, upgrading is easy, for example
-
- class Foo {};
- %typemap(javaclassmodifiers) Foo "public final"
-
- must now be:
-
- class Foo {};
- %typemap(javaclassmodifiers) Foo "public final class"
-
-
- *** POTENTIAL INCOMPATIBILITY FOR C# MODULE ***
- *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
-
-05/31/2004: wsfulton
- Fix for C++ exception specifications that are references. Problem reported by
- Oren Miller. Also improves the generated exception declarations in the
- catch handler for pointers - a pointer is used instead of a reference to
- a pointer. Added default throws typemaps for SWIGTYPE &, SWIGTYPE * and
- SWIGTYPE[ANY] (Java and C#).
-
-05/31/2004: wsfulton
- [Java, C#] Some minor typesafe enum improvements, including storing the name of
- the enum item. The toSring() / ToString() methods are overridden to return this name.
-
-05/30/2004: wuzzeb (John Lenz)
- [Chicken]
- - Update how examples and the test suite are built.
- - Symbol names are no longer converted to lower case
- - Added union_runme.ss, which was copied and modified from the guile module
-
-05/26/2004: lballabio (Luigi Ballabio)
- Committed on behalf of Marcelo (who still has problems with
- the SourceForge CVS.)
-
- Added Python typemaps for FILE* with (Python-only) test.
-
-5/24/2004: dancy
-
- * Allegro CL module: Now using some macros (defined in
- Lib/allegrocl/allegrocl.swg), swig-defconstant and swig-defun, for
- defining constants and foreign functions. This makes the
- generated file a bit neater.
-
- Now strips a layer of parenthesis from constants.
-
- Uses (* :void) instead of :foreign-address now.
-
-05/20/2004: wsfulton
- Unnamed enum global variables are now supported in addition
- to the recently added support for unnamed enum member variables.
- For example:
-
- struct Foo {
- enum { enum1, enum2 } MemberInstance;
- };
- enum { enum3, enum4 } GlobalInstance;
-
- The int typemaps are used for wrapping the get/set accessor methods.
- If the sizeof an enum is not the same size as an int then setting the
- variable will silently do nothing as the casts cannot be easily and portably
- generated. If you need to solve this highly obscure situation, write
- the assignment using the %exception feature.
-
-05/20/2004: wsfulton
- [C#] C# enum wrapping mods. Similar to the Java module, enums can be wrapped using
- one of 3 approaches:
-
- 1) Proper C# enums - use %include "enums.swg"
- 2) Typesafe enums - use %include "enumtypesafe.swg"
- 3) Simple constant integers (original approach) - use %include "enumsimple.swg"
-
- See each of these files for further details. Each of these files use typemaps
- and a new feature to control the generated code. The feature is:
-
- %csenum(wrapapproach);
-
- where wrapapproach should be one of: "proper", "typesafe", "typeunsafe" or "simple".
- [No implementation deemed necessary for type unsafe enums].
-
- The default approach is proper C# enums. Anonymous enums are always wrapped by
- constant integers.
-
- *** POTENTIAL INCOMPATIBILITY FOR C# MODULE ***
-
-05/20/2004: wsfulton
- [Java] Java enum support added. There are now 4 ways in which enums can be wrapped:
-
- 1) Proper Java enums - use %include "enums.swg"
- 2) Typesafe enums - use %include "enumtypesafe.swg"
- 3) Type unsafe enums (constant integers) - use %include "enumtypeunsafe.swg"
- 4) Simple constant integers (original approach) - use %include "enumsimple.swg"
-
- See each of these files for further details. Each of these files use typemaps
- and a new feature to control the generated code. The feature is:
-
- %javaenum(wrapapproach);
-
- where wrapapproach should be one of: "proper", "typesafe", "typeunsafe" or "simple".
- The default typemaps will handle enums that may or may not have specified initial
- values, for example ten is specified:
-
- enum Numbers { zero, ten(10) };
-
- However, the amount of generated Java code can be cut down, by modifying these typemaps
- if none of the enums have initial values (proper Java enums and typesafe enums approach).
-
- The default approach is typesafe enums. Anonymous enums are always wrapped by
- constant integers.
-
- *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
-
-05/11/2004: wsfulton
- [Java, C#] Fix bug using %rename on enum items and when using
- %javaconst(1) / %csconst(1)
- For example, the following used to generate code that wouldn't compile:
-
- %rename(Obj) Object;
- enum Grammar { Subject, Object };
-
-04/28/2004: wsfulton
- [Java, C#] Minor fixes when using combinations of the
- javainterfaces, javabase, csinterfaces and csbase typemaps.
-
-05/18/2004: wsfulton
- [Java] JVM link failure on some systems fixed when using std_vector.i.
- Also adds default vector constructor for use from Java.
-
-05/17/2004: mkoeppe (Matthias Koeppe)
-
- [Guile] New runtime functions SWIG_PointerAddress,
- SWIG_PointerType, SWIG_IsPointerOfType, SWIG_IsPointer.
-
- [Guile] In -scm mode, wrap several SWIG runtime functions
- and export them into the module (Swig swigrun). The
- runtime module is now built with "module" linkage.
-
- [Guile] GOOPS proxy objects now also print the pointer
- address of the C object.
-
-05/14/2004: lyle
- Added Kou's patch for the Ruby %import directive so that modules
- with "nested" names are handled properly. Consider an interface
- file foo.i that has this %module declaration at its top:
-
- %module "misc::text::foo"
-
- Now consider another interface file spam.i that imports foo.i:
-
- %import foo.i
-
- Before this patch, this would result in the following code being
- generated for spam_wrap.c:
-
- rb_require("misc::text::foo");
-
- With this patch, however, you'll get the correct path name
- for the call to rb_require(), e.g.
-
- rb_require("misc/text/foo");
-
- See SourceForge Bug #928299.
-
-05/12/2004: wsfulton
- Patch for emitting directors when %feature("director") specified
- for a class with no virtual methods, but does have a virtual destructor.
- Submitted by Kevin Smith.
-
-05/06/2004: mkoeppe (Matthias Koeppe)
- New SWIG runtime function SWIG_TypePrettyName, which
- returns an unmangled type name for a swig_type_info
- object.
-
- [Guile]: Use it for printing pointer objects.
-
-05/03/2004: dancy (Ahmon Dancy)
-
- * Lib/allegrocl/allegrocl.swg: Updated comments about identifer
- conversion.
-
- * Sources/Modules/allegrocl.cxx: Register /dev/null for "header"
- target. Also, disregard "const" qualifiers during type
- conversion.
-
-
-05/02/2004: wuzzeb (John Lenz)
- [Chicken] Fix bug 782468.
- To fix this bug, the runtime code has been rewritten, and
- pointers are now represented as a C_SWIG_POINTER_TYPE.
-
- Chicken version > 1.40 is now required!
-
- * Typemap incompatibility: typemaps no longer use chicken_words.
- If a typemap needs some space, it should just call C_alloc
-
- * argout typemaps no longer use the /* if ONE */ construct to
- build an output list. A SWIG_APPEND_VALUE macro, exactly like
- guile and mzscheme is now used.
-
-04/25/2004: mkoeppe (Matthias Koeppe)
- [Guile] In the generated GOOPS code, don't create methods
- that would not specialize any arguments; simply re-export
- the primitive functions. (This is a performance
- optimization which reduces load time and execution time.)
-
- [Guile] In -gh mode, fix the "too many initializers" error
- which was caused by an incompatible swig_type_info layout.
-
- [Guile] The typemap for FILE * in ports.i now also accepts
- a regular FILE * pointer object. Also a bug with Scheme
- file ports that are open for input and output has been
- fixed.
-
-04/25/2004: wsfulton
- Change entry 03/21/2004 revoked. The change introduced another
- inconsistency (reference typemaps beings used instead of
- pointer typemaps for member variables as well as static
- member variables and global variables for some languages,
- but only for C++ and not C). This would break user's current
- typemaps and introduce further inconsistencies. Alternative
- solution required and being discussed.
-
-04/10/2004: mmatus (Marcelo Matus)
-
- Added the -directors flag. This enables the director
- mode for the interface and all the classes that
- don't set the "feature:nodirector" explicitly.
-
- You can use this in your module if you want to use the
- director feature in all your classes, but it is most
- intended for testing purposes, like:
-
- make check-python-test-suite SWIG="../../../swig -directors"
- make check-ruby-test-suite SWIG="../../../swig -directors"
- make check-java-test-suite SWIG="../../../../swig -directors"
-
- These commands will run the entire test-suite using
- directors, and not only the specific 'directors_*'
- cases. This should be done from time to time.
-
-04/10/2004: mmatus (Marcelo Matus)
-
- [python] Added support for std::wstring and wchar_t,
- for compiler and python versions that support them.
-
- When needed, use
-
- %inlcude std_string.i // 'char' strings
- %inlcude std_wstring.i // 'wchar_t' strings
-
-
-04/10/2004: mmatus (Marcelo Matus)
-
- [python] Fix the default behaviour (seg. fault) when an
- inplace operator (+=,-=,...) was wrapped, as reported by
- Lucriz (lucriz@sitilandia.it), when the most common
- form was used:
-
- A& A::operator+=(int i) { ...; return *this; }
- ^^^^ ^^^^^^
-
-
- ie, an object is returned and its contains the same 'this'
- value than the input object, which is deleted after the
- operation "a += b", leaving the result with no real
- object, but a seg. fault.
-
- To fix it, we needed to introduce a new feature and use an
- old one:
-
- %feature("self:disown") A::operator+=;
- %feature("new") A::operator+=;
-
- here, "self:disown" disable the ownership of the 'self'
- or input object, and the "new" feature transfers the
- ownership to the result object.
-
- The feature/solution could also be used in other languages
- that use gc and implement the inplace operators, or other
- operators, in a similar way.
-
- *** POTENTIAL INCOMPATIBILITY FOR Python MODULE ***
-
- If you already are using the inplace operators in python,
- and you implemented some kind of workaround to the problem
- fixed here, it is possible you could end with 'free'
- objects that never get deleted. If that is the case, and
- you want to disable the current fix, use:
-
- %feature("self:disown","") A::operator+=;
- %feature("new","") A::operator+=;
-
-
-04/07/2004: cheetah (William Fulton)
- [C#] C++ enums are no longer wrapped by integers, they are now wrapped by
- C# enums. For Example, given C++:
-
- enum AnEnum { foo, bar };
- typedef AnEnum AnEnumeration;
- void something(AnEnum e, AnEnumeration f);
-
- The following is generated:
-
- public enum AnEnum {
- foo,
- bar
- }
- public static void something(AnEnum e, AnEnum f) {...}
-
- Note that a global enum like AnEnum above is generated into its own
- file called AnEnum.cs. Enums defined within a C++ class are defined
- within the C# proxy class. Some of the typemaps for modifying C# proxy
- classes also work for enums. For example global enums can use
-
- %typemap(csimports) to add in extra using statements.
-
- Global enums and class enums can use
-
- %typemap(csclassmodifiers) to make the enum private, public etc.
- %typemap(csbase) to change the underlying enum type (enum base)
-
- If we add this for the above example:
-
- %typemap(csclassmodifiers) AnEnum "protected"
- %typemap(csbase) AnEnum "long"
-
- the following is generated:
-
- protected enum AnEnum : long {
- foo,
- bar
- }
-
- *** POTENTIAL INCOMPATIBILITY FOR C# MODULE ***
-
-04/07/2004: cheetah (William Fulton)
- Seg fault fix for empty enums, like
- enum Foo {};
-
-03/21/2004: mmatus
- [Note: this change revoked on 04/25/2004]
- [Python] Makes the following 'var' cases more uniform:
-
- std::string ga;
-
- struct A {
- static std::string sa;
- std::string ma;
- };
-
-
- now the three variables (ga, sa, ma) can be assigned as:
-
-
- cvar.ga = "hello";
- A.sa = "hello";
- a.ma = "hello";
-
- ie, now 'ma' will also use a std::string typemap 'in' if
- defined, before it was only accepting a 'p_std_string'
- pointer. Note, however, that 'ma' will not use the
- 'varin/varout' typemaps (that probably could be more
- natural), but it will pick up the 'in' typemap for const
- std::string& (which is easier).
-
- The changes in cwrap.c and lang.cxx will probably fix the
- behaviour in other languages that do not overload the
- membervarHandler method "too much".
-
-
-03/21/2004: mmatus
- [Python] Disabling the default instantiations like:
-
- %template() std::pair<int,int>;
-
- for all the primitive types and STL containers/classes.
- They are expensive, specially for pair and map, and the
- previous behaviour also requires the user to perform
- manual instantiations. Still, if the speed difference is
- not important, it can be re-enabled by defining the macro
- SWIG_STD_DEFAULT_INSTANTIATION (see std_common.i).
-
- Also, normalizing the INPUT/OUTPUT/INOUT typemaps. Now
- they use the same conversors than the rest of the
- typemaps, and you can use them for std::pair, std::string
- and all the other STL types, like in:
-
- void p_inoutd(std::pair<double, double> *INOUT);
-
- Added the attribute.i and implicit.i files with macros to
- transform functions pairs like 'set_x'/'get_x'
- (or 'T& x()'/'const T& x() const') into an attribute,
- and allowing the use of implicit constructors in typemaps
- (see the files for more details).
-
-03/21/2004: mkoeppe
- [Guile] Fix the documentation strings of functions with
- anonymous arguments.
-
-03/18/2004: mmatus
- [Python] More general std_string.i interface.
- Now you can wrap it using
-
- %template(string) std::basic_string<char>;
-
- and use the std::string as a base class:
-
- struct A : std::string {
- };
-
- But more important, swig will recognize
- both std::basic_string<char> and std::string as
- the same type.
-
-03/16/2004: mmatus
- Previously added, but not mentioned before:
-
- - friend declaration support, swig now emits a global
- function in the same class scope.
-
- - ref/unref features: to mix ref counting C++ classes
- and native script ref counting mechanisms (like in python).
-
- Use it like:
-
- %feature("ref") RCObj "$this->ref();"
- %feature("unref") RCObj "$this->unref();"
-
- And the class RCObj, and all the derived ones, will
- perform the right ref/unref calls when a new pointer
- is returned to the target language, or when the target
- language attempts to delete the object.
-
- See the refcount.i file in the test-suite for more
- details.
-
-
-03/16/2004: mmatus
- [Python] Using the new %fragment support, major rewrote
- of the python swig library, including:
-
- - Almost automatic template/typemap instantiation for
- the STL components. For example, now you can write:
-
- %template(vector_i) std::vector<int>;
-
- and a specialized vector_i class is emitted with all
- the needed typemaps. No need to use the old
- 'specialize_vector' macros.
-
- Note you can also define
-
- %template(matrix_i) std::vector<std::vector<int> >;
- %template(vector_pii) std::vector<std::pair<int,int> >;
-
- - The empty template instantiation
-
- %template() std::vector<int>;
-
- defines the vector typemaps, but no proxy class. For all the
- fundamental types, the empty template instantiation are
- defined, so, you can say
-
- %include std_vector
-
- int func(const std::vector<int>& a);
-
- where the proper typemap is applied to 'a', but no
- std::vector<int> proxy is generated.
-
-
- - All the STL containers present a more uniform behavior and
- more complete interface declaration. The following are
- now supported:
-
- std::vector<T>
- std::list<T>
- std::deque<T>
- std::set<T>
- std::multiset<T>
- std::map<T>
- std::multimap<T>
-
- not a container, but also supported:
-
- std::pair<T,U>
-
- also, more typemaps are defined for all of them,
- including varin, varout, typecheck, etc.
-
- - Initial attempt to implement the STL containers
- considering allocators, ie:
-
- std::vector<T,A>
-
- it is partially working, but it is just a workaround
- while swig improves its template type support.
-
-
- Please test with your particular setup. It seems to be
- working with g++ 3.2.2, g++ 2.96, Intel icc and SGI CC
- compilers, plus python 1.5.2, 2.0 and 2.3, but since
- we are using templates, there is a chance you can find
- some problems when using with an old C++ compiler.
-
-03/16/2004: mmatus
-
- - Allowing the empty %template directive, such as
-
- %template() std::vector<int>;
-
- to process the class "typedef"s and "typemap"s. Before
- only the internal "typedef"s were processed.
-
- This makes possible to emit the default in/out
- typemaps without the need of wrapping an specialized
- vector instance.
-
- - Adding the preprocessor extension #@ which mangles the
- following macro argument, like in:
-
- #define macro(X) #@X
- macro(int) -> int
- macro(std::string) -> std_s_s_string
-
- - Fragments can now be "type specialized", as the typemaps. The
- syntax is as follows
-
- %fragment("name","header")
- { /* a type independent fragment (old syntax) */ }
- %fragment("name" {Type}, "header")
- { /* the fragment is type dependent */}
-
- Now fragments can also be used inside templates:
-
- template <class T>
- struct A {
- %fragment("incode"{A<T>},"header") {
- /* 'incode' specialized fragment */
- }
-
- %typemap(in,fragment="incode"{A<T>}) {
- /*
- here we use the 'type specialized'
- fragment "incode"{A<T>}
- */
- }
- };
-
-
-03/11/2004: cheetah (William Fulton)
- [Java] Director bug which meant that some virtual functions overridden in
- Java were not being called on some operating systems. Bug reported and fixed
- by Robert de Vries and Scott Michel.
-
-03/02/2004: mkoeppe (Matthias Koeppe)
- [Guile] In -scm mode, don't forget to check the type of string arguments.
-
-02/24/2004: cheetah (William Fulton)
- [C#] New commandline option -namespace <name>. This allows one to specify
- a C# namespace into which all C# classes are generated.
-
-02/23/2004: mkoeppe (Matthias Koeppe)
- [MzScheme] Use FUNC_NAME rather than a bogus typemap variable for signalling
- errors. Call scheme_wrong_type with a zero-based argument number.
- Reported by Ondrej Pacovsky, SF #902621.
-
- [Guile] Define FUNC_NAME also in the dispatch wrapper for overloaded
- functions. Patch by John Lenz, SF #896255.
-
-02/22/2004: mkoeppe (Matthias Koeppe)
- [Guile] In -scm mode, don't try to invoke a null destructor function.
-
-02/20/2004: cheetah (William Fulton)
- Fixes so that the SWIG source will compile using the Digital Mars Compiler
- (formerly Symantic compiler) on Windows. Submitted by Scott Michel.
-
-02/13/2004: mkoeppe (Matthias Koeppe)
- [MzScheme] New command-line argument -noinit. Use it for building
- the runtime library, where we don't want to define the functions
- scheme_initialize etc. Reported by Tim Brown, SF #891754.
-
- [MzScheme] Don't produce invalid C code when invoked with the
- -declaremodule option. Reported by Tim Brown, SF #891108.
-
- [Guile] Build the runtime library with passive linkage, to rename
- the SWIG_init function uniquely.
-
-02/12/2004: cheetah (William Fulton)
- [Java, C#] Patch submitted by Bill Hoffman which prevents SWIG from crashing
- when a file for the typewrapper class cannot be opened.
-
-02/11/2004: cheetah (William Fulton)
- [Java, C#] Overloading changes:
- - Methods which are overloaded in const only no longer generate Java
- code that won't compile - the first method parsed is used and a
- warning is displayed. Note that this behaviour is slightly different
- to the scripting languages which always uses the non-const method.
- - Warning messages 509 and 512 replaced by new warning number 516, which
- is more relevant to these statically typed languages as the overloaded
- methods aren't 'shadowed', they are ignored.
-
-01/23/2004: mkoeppe (Matthias Koeppe)
- [Guile] Replace the "known_classes" hash table by a node
- attribute. Methods of classes in C++ namespaces now get
- the proper specializer in the GOOPS declaration.
- Reported by rm@mh-freiburg.de.
-
-01/23/2004: mkoeppe (Matthias Koeppe)
- [Guile] Uniquify the argument names in GOOPS shadow method
- declarations. Reported by rm@mh-freiburg.de.
-
-01/21/2004: sunshine (Eric Sunshine)
- Revived the NextStep port of SWIG.
-
- Fixed fatal problem in DohStrstr() caused by difference in strstr()
- implementation which made %apply become entirely dysfunctional. On
- NextStep, strstr("foo","") evaluates to NULL; whereas, on modern
- platforms, it evaluates to "foo". %apply relies extensively upon
- strstr("foo","") evaluating to non-NULL, therefore it failed
- catastrophically when faced with NextStep's strstr().
-
- Added `bool' check to configure.in since NextStep's C++ compiler
- does not supply this type. swig.h now fakes up `bool' if needed.
-
- Worked around NextStep C++ compiler bug in which C++ code is
- disallowed inside extern "C" functions. This problem affected all
- language modules, since they publish hook functions of the form:
- extern "C" Language *swig_foo(void) { return new FOO(); }
- Fixed by creating a C++ wrapper:
- static Language *new_swig_foo() { return new FOO(); }
- extern "C" Language *swig_foo(void) { return new_swig_foo(); }
-
- Ensured that Swig_copy_string() is used in place of strdup() since
- NextStep does not supply strdup().
-
- Fixed detection of Ruby library name and location in configure.in.
- Problem 1: Assumed that library always resided in Ruby's "archdir",
- which was correct for Ruby 1.6.x, but which is incorrect for Ruby
- 1.8.x, in which case the library normally resides in Ruby's
- "libdir". Problem 2: Assumed that the library could always be
- linked via "-l"+RUBY_INSTALL_NAME (where RUBY_INSTALL_NAME
- typically is "ruby"), however this failed for platforms, such as
- NextStep, which do not support shared libraries. In this case, the
- static library name in 1.8.x is libruby-static.a, thus
- -lruby-static is required. The new logic works correctly for
- static and shared libraries for 1.6.x and 1.8.x.
-
- Fixed detection of Perl CFLAGS in configure.in for NextStep.
- Detection code extracted CFLAGS from Perl's %Config hash but
- neglected to add a newline to the value before passing it through
- `sed'. NextStep's ancient `sed' discards input which is not
- terminated with a newline, thus Perl CFLAGS always evaluated to the
- empty string.
-
-01/16/2004: cheetah (William Fulton)
- Tidy up in the exception handling code that is generated when
- C++ exception specifications are wrapped with the throws typemap.
- This redundant code is no longer generated:
-
- catch(...) {
- throw;
- }
-
-01/12/2004: wsfulton on behalf of mmatus (marcelo matus)
- if a method uses %exception and the method requires the use
- of the throws typemap, the code in a throws typemap will be
- generated inside the try body. For example:
-
- %exception method {
- try {
- // method action
- $action
- } catch (int i) {
- // method int catch handler
- } catch (...) {
- // method generic catch handler
- }
- }
- %typemap(throws) Except %{
- // throws typemap Except catch handler
- %}
-
- %inline %{
- class Except {};
- void method(int i) throw (Except);
-
- Will generate:
-
- {
- try {
- // method action
- try {
- method(arg1);
- }
- catch(Except &_e) {
- // throws typemap Except catch handler
-
- }
-
- } catch (int i) {
- // method int catch handler
- } catch (...) {
- // method generic catch handler
- }
- }
-
-
- As can be seen, the inner try catch block is for the throws typemaps.
- Previously, this was reversed so that the inner try catch block
- was the %exception code. In the example above, it would have been
- impossible to catch Except as the catch all (...) would catch the
- exception instead.
-
-Version 1.3.21 (January 11, 2004)
-=================================
-
-01/10/2004: cheetah (William Fulton)
- The output format for both warnings and errors can be selected for
- integration with your favourite IDE/editor. Editors and IDEs can usually
- parse error messages and if in the appropriate format will easily take you
- directly to the source of the error. The standard format is used by
- default except on Windows where the Microsoft format is used by default.
- These can be overridden using command line options, for example:
-
- $ swig -python -Fstandard example.i
- example.i:4: Syntax error in input.
- $ swig -python -Fmicrosoft example.i
- example.i(4): Syntax error in input.
-
-01/09/2004: beazley
- Fixed [ 871909 ] simple namespace problem.
- This was a problem using anonymous structures in a namespace.
- For example:
-
- namespace ns {
- typedef struct {
- int n;
- } S;
- };
-
- Reported by Josh Cherry.
-
-01/09/2004: beazley
- Fixed some broken Perl examples.
-
-12/28/2003: cheetah (William Fulton)
- [Java and C#] Fixes for wrapping covariant (polymorphic) return types.
- For example:
-
- struct Base {
- virtual ~Base();
- virtual Base* copy() const = 0;
- };
- struct Derived : Base {
- virtual Derived* copy() const;
- };
-
- The Derived::copy proxy method returns Base not Derived. A warning is issued
- about this. Previously the pointer used by the proxy class was incorrectly
- treated as a Base* instead of a Derived*.
-
-12/18/2003: cheetah (William Fulton)
- Fix so that Windows paths are displayed correctly when reporting errors.
- An error previously would have been shown something like:
-
- .?xample.i:14: Syntax error in input.
-
- instead of:
-
- .\example.i:14: Syntax error in input.
-
-
-Version 1.3.20 (December 17, 2003)
-==================================
-
-12/17/2003: beazley
- Last minute modifications. Perl5 module now generates shadow classes
- by default like all of the other modules. PHP4 wrappers no longer
- include "config.h".
-
-12/14/2003: beazley
- Weakened warning message related to constructor names so that an
- unusual nested-class wrapping technique would work again (apparently
- it worked in some older SWIG releases). For example:
-
- class Scope {
- class ClassA;
- class ClassB;
- };
- class Scope::ClassA {
- ...
- };
- class Scope::ClassB {
- ...
- }
-
- Note: There is still some odd interaction with the SWIG symbol
- table/type system that will need to be looked at in a future release.
- Reported by Gustavo Niemeyer.
-
-
-12/11/2003: cheetah (William Fulton)
- [Java] Protected class methods are wrapped as protected Java methods
- when using the dirprot director feature. This can be changed using
- %javamethodmodifiers to something else should the need arise, for
- example, private or package access.
-
-12/11/2003: cheetah (William Fulton)
- [Java, C#]
- %javamethodmodifiers (Java) and %csmethodmodifiers (C#) operate slightly
- differently. Previously this feature had to be present to set the method
- modifiers. Now it is only used if it exists for the method being wrapped.
- The default is "public" as previous however, when wrapping protected
- director methods it is "protected". This change will not affect existing
- use of the %javamethodmodifiers or %csmethodmodifiers.
-
-12/11/2003: mmatus (Marcelo Matus)
-
- This fix some recurring reports about keywords not been
- properly identified and warned, and it solves the problem
- of how to add a test file to the test-suite such that it
- doesn't use any keyword of all the supported languages
- (and doing it without compiling the test for all the
- supported languages, thing that is not always possible,
- and without requiring you to know all the supported
- language keywords, thing that is always impossible).
-
- So these are the changes globally speaking:
-
- - Uniform the definition of the keyword warnings through
- the supported languages: all the languages has now a
- separate file that defines the keywords or bad names:
-
- python/pythonkw.swg
- chicken/chickenkw.swg
- ....
-
- - Added keyword list for most of the languages that didn't
- have one (using the new separated file).
-
- - Added the "All keywords" warning support: -Wallkw option.
-
- This option allows you to include all the known keywords
- for all the supported languages, and can be used as:
-
- swig -Wallkw ....
-
- This will help to the process of adding a test-suite
- file that can be compiled in all the swig supported
- languages, and it will be also helpful for users who
- want to create multi-language libraries.
-
- And these are the detailed changes (mostly file addition):
-
- - For the languages that already have some sort of keyword
- warning list, move it to an external languagekw.swg
- file, ie:
-
- move keywords from python.swg -> pythonkw.swg
- move keywords from chicken.swg -> chickenkw.swg
- move keywords from tcl8.swg -> tclkw.swg
-
- and re-include languagekw.swg from language.swg.
-
- - For the language that didn't have a keyword list, and
- for the ones that I could find a list, add the
- languagekw.swg file, ie:
-
- csharp/csharpkw.swg
- java/javakw.swg
- php4/phpkw.swg
- pike/pikekw.swg
- ruby/rubykw.swg
-
-
- also add a line in language.swg to include
- languagekw.swg, but now it is commented!!!, like in
- java.swg:
-
- /* java keywords */
- /* please test and activate */
- //%include "javakw.swg"
-
- ie, there will be no change in how swig runs normally
- until the language maintainer test and uncomment that
- line.
-
- So, please check each languagekw.swg file (I left the
- link to the keyword list source for checking), and after
- testing, uncomment the %include line.
-
- - Added the file allkw.swg, which includes all the
- languagekw.swg files.
-
- For the languages that has no languagekw.swg file right
- now, and if they need one, add the file into the
- language directory, and add the corresponding include
- line into the allkw.swg file.
-
- - Added the -Wallkw that includes the allkw.swg file.
- Note that the old -lallkw.swg option couldn't be used
- since it include the file after it would be needed.
-
-
- Hopefully, the -Wallkw option will be added to the default
- rules in the related test-suite Makefiles, so, when
- creating a new test, or adding a new swig library file
- (like _std_deque.i), swig will warn you if you are using a
- bad name, considering all the language where it needs to
- run.
-
- Right now you can test it by using:
-
- make check-python-test-suite SWIG="swig -Wallkw"
-
- or using your favorite target language, it doesn't matter.
-
- And yes, there are several examples that are using
- reserved keywords, specially from csharp.
-
- *** Remember ****: the new keyword warning lists are not
- included by default in any of language that before didn't
- have one. To enable the keyword warnings as the default
- behavior, the inclusion of the languagekw.swg file has to
- be uncommented at each language.swg file.
-
- So, all the language maintainers, please check the
- keywords list.
-
- Also, you can add buit-in names, and not only keywords, like
- 'True/False' in python. Remember that you can be more
- specific and refer only to member names, like *::configure
- or *::cget (see an example in the tcl8/tcl8kw.swg file),
- or only global names, like ::range (see an example in the
- python/pythonkw.swg file.
-
- Just to be consistent, use the following codes:
-
- - Use code 314 for keyword and/or fatal bad names.
- - Use code 321 for buit-in and/or not fatal bad names.
-
- so, they can't be disabled/enabled independently (see
- python/pyhtonkw.swg for examples).
-
- **** And don't add any new test file without checking it
- with the -Wallkw option!! (that includes me) *****.
-
-
-12/11/2003: cheetah (William Fulton)
- SF bug #854634
- Added support for accepting the Unix directory separator '/' on
- Windows and the Mac in addition to the native one ( '\' on
- Windows). This can be used in %import, %include and commandline
- options taking a path, for example -I. On Cygwin, both the Windows
- and Unix directory separator can now be used (was '/' only).
-
-12/10/2003: mmatus (Marcelo Matus)
-
- [python] Implementing the runtime "reprotected" director
- members, if you have:
-
- %feature("director") B;
-
- class Bar {
- public:
- virtual ~Bar();
- virtual int hello() { return do_hello();)
-
- protected:
- virtual int do_hi() {return 0;}
- virtual int do_hello() {return 0;}
- };
-
- then, at the python side
-
- import my_module
-
- class Foo(my_module.Bar):
- def do_hello(self):
- return 1
- pass
-
- b = Bar() # Pure C++ Director class
- f = Foo() # C++ Director + python methods
-
- b.hello() # Ok, and it calls C++ Bar::do_hello()
- f.hello() # Ok, and it calls Python Foo::do_hello()
-
- b.do_hi() # RuntimeError, do_hi() is protected!!
- f.do_hi() # RuntimeError, do_hi() is protected!!
-
- b.do_hello() # RuntimeError, do_hello() is protected!!
- f.do_hello() # Ok, since it its redefined in python.
-
- Here Bar.do_hello is always protected, but Foo.do_hello
- is "public", because it is redefined in python. Before,
- all the 'do_hello' methods were public.
-
- This seems to be a good compromise between C++ and python
- philosophies, ie, all the director protected methods keep
- protected at the user side (C++ way) until they are
- redefined (python way, were all defined methods are always
- public). And this is not only a good compromise, it also
- seems to be the only way to do it :).
-
- Now ruby has native director protected members, and python
- pure runtime support. I guess these are the two possible
- extreme cases. And hopefully, they could be used as
- templates to modify the other languages that support
- directors, so they can "reprotect" the protected director
- members at the target language side.
-
- This finished the director protected support for the
- python language. Ocalm will need to add the
- "reprotection" later.
-
-12/10/2003: mmatus (Marcelo Matus)
-
- The following case (reported by Lyle Johnson) was fixed:
-
- %rename(x) Foo::y();
-
- class Foo {
- public:
- void y();
-
- protected:
- int x;
- };
-
- swig warned that the symbol 'x' was already defined, and
- the renaming fails. 'x' was not emitted, since it is
- protected, but it was kept in the symbol table with too
- much information.
-
- Now swig works for all the cases (plain, director and
- dirprot) again. This was fixed by allowing the parser.y to
- decide much closer what to do with 'x'. Before all the
- discarding or generation was resolved at the lang.cxx
- stage. Also the changes in parser.y to implement the
- director protected mode are now much more encapsulated, and
- they get disabled if the mode is not enabled. Before the
- deactivation was done at the generation stage (lang.cxx).
-
- By the other hand, if the director mode is enabled, and
- %rename is done, reusing a protected member name, there is
- a pathological case:
-
- %rename(x) Foo::y();
-
- class Foo : public A {
- public:
- void y();
-
- protected:
- int x; /* works */
- static int x; /* works */
- static void x(); /* works */
- typedef void x(); /* works */
-
- virtual void x(); /* always fails, as it should, since
- Foo::x() will be emitted in the
- director */
-
- void x(); /* always fails, but sometimes it shouldn't,
- since the Foo::x() will not be emitted if
- it is not virtual */
-
- };
-
- The last case is not always right because at the parser.py
- stage it is not possible to decide if the protected member
- Foo::x() could or not conflict with the renamed Foo::y(),
- since Foo::x() could be virtual by inheritance.
-
- I guess this just an intrinsic limitation, and no much can
- be done about it without resorting into larger changes to
- postpone, under certain conditions, the multiply symbol
- detection (lang.cxx stage).
-
- So, by now, it is just considered a well known "feature" in
- the director protected mode. The good news is that it seems
- to be a rare case, and it can be avoided by the user by
- hiding 'x' before renaming 'y':
-
- %rename(_x) Foo::x();
- %rename(x) Foo::y();
-
-
-12/08/2003: mmatus (Marcelo Matus)
- The virtual method detections now properly
- treats the following cases:
-
- namespace foo { typedef int Int; }
- struct A {};
- typedef A B;
-
- struct Foo {
- virtual ~Foo() {}
-
- virtual Foo* cloner() = 0;
- virtual int get_value() = 0;
- virtual A* get_class() = 0;
- virtual void just_do_it() = 0;
- };
-
- struct Bar : Foo
- {
- Bar* cloner();
- foo::Int get_value();
- B* get_class();
- void just_do_it();
- };
-
- All the Foo and Bar methods are virtual. A new attribute
- "virtual:type" record the base polymorphic type. In the
- previous cases we have:
-
- type : Bar virtual:type : Foo
- type : foo::Int virtual:type : int
- type : B virtual:type : A
- type : void virtual:type : void
-
- This attribute is useful in languages (java+directors)
- that could have problems redefining Bar* Bar::cloner().
-
- If you never had code like the above, you will see no
- effects. But if you have some code like that, you
- will see some effects since some methods that
- before were not properly treated as virtual,
- will start to act like that. This could enlarge
- your director classes.
-
-
-12/08/2003: mmatus (Marcelo Matus)
- The director protected member support (dirprot)
- is disabled by default.
-
- It can be enable by using '-dirprot' or by adding
- the option to the module declaration, like:
-
- %module(directors="1",dirprot="1") my_module
-
- This module option was added to properly compile the
- director_protected.i and director_nested.i examples.
-
- The feature has been tested with python[2.2,2.3]
- and ruby[1.6.7], both at compilation and runtime, and
- java[j2sdk1.4.1_01], but only at compilation (my java
- installation doesn't run any of the director examples,
- olds nor news).
-
- Please test for ocaml and java.
-
- The errors reported by William and Scott were fixed,
- except for a warning about SWIG_JavaThrowExecption()
- multiply defined. I can't reproduce this error with my
- examples. We will wait for Scott to send us a minimal
- case.
-
-
-12/07/2003: mmatus (Marcelo Matus)
- The director protected member support has been
- completly moved out from python.cxx, and now
- resides in the common lang.cxx, emit.cxx and
- allocate.cxx files.
-
- This means it should work for all the other languages
- that currently support directors, ie, python, java, ocalm
- and ruby.
-
- The change has been tested with python (compilation+runtime)
- and java (just compilation).
-
- Please add runtime tests for the missing languages
- and test it.
-
- The '-nodirprot' option was moved to the principal main,
- and can be used from all the languages.
-
-12/07/2003: cheetah (William Fulton)
- [Java] Fixed and improved error checking of STRING_OUT typemaps in
- various.i.
-
-12/04/2003: mmatus (Marcelo Matus)
-
- - Now the virtual members with no explicit declarator
- are properly identified:
-
- struct A {
- virtual int f() = 0;
- };
-
- struct B : A {
- int f();
- };
-
- Here, B::f() is virtual, and the director and the
- virtual elimination mechanism now recognize that.
-
- - [C#] This fix also fixes the problem where 'override' was not being
- used on any overridden virtual method, so for struct B above,
- this C# code is generated:
-
- public class B : A {
- ...
- public override int f() {
- ...
- }
- ...
- }
-
- - Initial support for protected virtual methods. They are now
- properly emitted when using with director (python only by
- now).
-
- %feature("director") A;
- struct A {
- protected:
- virtual int f1() = 0;
- };
-
- %feature("director") B;
- struct B : A{
- protected:
- int f1();
- virtual f2();
- };
-
- This can be dissabled by using the '-nodirprot' option.
-
- - The feature 'nodirector' is working now at the top level,
- so, it must work for all the languages:
-
- %feature("director") A;
- %feature("nodirector") A::f2;
-
- struct A {
- virtual int f1();
- virtual int f2();
- };
-
- in this case, only 'f1' is exported to the director class.
-
- - Added director support for const TYPE& arguments (python).
-
-12/02/2003: cheetah (William Fulton)
- [Java] Fix for INOUT and OUTPUT typemaps in typemaps.i for when the JNI type
- is bigger than the C type. For example, unsigned long (32bits on most systems)
- is mapped to jlong (64bits). Returned value was incorrect. Bug reported by
- Brian Hawley.
-
-12/02/2003: cheetah (William Fulton)
- [C# and Java] Better fix for entry dated 05/11/2003. Fixes the following
- typemaps:
-
- Java: javabase, javainterfaces, javaimports, javaclassmodifiers,
- javaptrconstructormodifiers, javafinalize, javagetcptr & javacode.
- C#: csbase, csinterfaces, csimports, csclassmodifiers,
- csptrconstructormodifiers, csfinalize, csgetcptr & cscode.
-
- It also fixes bug in using arrays of C structs with arrays_java.i
- as reported Scott Michel.
-
-12/02/2003: beazley
- [Perl] Fixed [ 852119 ] recursive inheritance in output .pm, perl5.
- Reported by William Dowling.
-
-12/02/2003: beazley
- [Tcl] Fixed [ 755382 ] calling func(const vector<T>& p) evaluates p[0] in interp.
- The Tcl type checker was improperly handling the interpreter result when
- type violations were supposed to be ignored.
- Reported by Flaviu Popp-Nowak.
-
-11/30/2003: cheetah (William Fulton)
- Fixed [ 545058 ] configure's --with-tclincl has no effect
-
-11/30/2003: cheetah (William Fulton)
- [Java] Fixed [ 766409 ] missing symbol SWIG_JavaThrowException during module load
- SWIG's internal functions are all static as there is no need for different SWIG
- generated modules to share any code at runtime.
-
-11/30/2003: beazley
- [Tcl] Added support for C++ pointers to members.
-
-11/28/2003: cheetah (William Fulton)
- Fixed [ 848335 ] Directors: #include wrapper .h file - was incorrectly
- adding a directory to the generated #include "foo_wrap.h" statement
- in some situations.
-
-11/28/2003: cheetah (William Fulton)
- [Java] Fixed [ 849064 ] JAVA : Access modifier for derived class wrong.
- The delete() method is always public now. It used to be protected whenever a
- destructor was non public. An UnsupportedOperationException runtime
- exception is thrown instead of making delete() protected now.
-
-11/28/2003: beazley
- [Perl5] Added support for C++ pointers to members.
-
-11/28/2003: beazley
- Fixed [ 850151 ] PYVERSION with python2.3 in configure of SWIG 1.3.19 (Maybe).
-
-11/28/2003: beazley
- Fixed [ 850666 ] #include extra line added.
- This should fix some problems with getting correct line numbers on
- error messages.
-
-11/26/2003: beazley
- Fixed another one of Marcelo's evil template bugs (infinite
- recursion). [ 849504 ] template and typedef -> inf. recursion.
-
-11/26/2003: beazley
- Fixed parsing problem with declarations like this:
-
- int *x = &somearray[0];
-
-11/25/2003: beazley
- Fixed [ 756552 ] missing default argument class scope with "|".
- This is really only a band-aid fix for use of class-enums in
- expressions. For example:
-
- class A {
- public:
- enum Flag { flag1 = 0x1, flag2 = 0x2 };
- void foo(int x = flag1 | flag2);
- };
-
- Note: there are still some (more subtle) cases that are broken,
- but hard to fix due to an issue with template expansion. Will
- address later.
- Reported by Dmitry Mironov.
-
-11/25/2003: beazley
- Incorporated [ 840878 ] support for %inline { ... } (PATCH).
- This adds support for the following:
-
- %inline {
- ... some code ...
- }
-
- The difference between this and %inline %{ ... %} is that the
- enclosed text is processed by the SWIG preprocessor. This
- allows special macros and other processing to be used in
- conjunction with %inline.
- Contributed by Salvador Fandino Garcia.
-
-11/25/2003: beazley
- Fixed [ 836903 ] C++ inconsistency (with void arguments).
- SWIG was having difficulty with f() vs f(void) in C++ programs.
- For instance:
-
- class A {
- public:
- virtual void f(void) = 0;
- };
-
- class B {
- public:
- virtual void f(); // Not matched to f(void) correctly
- };
-
- The parser now normalizes all declarations of the form f(void)
- in C++ classes to f(). This should fix a variety of subtle
- problems with inheritance, optimizations, overloading, etc.
- Problem reported by Partho Bhowmick.
-
-11/25/2003: beazley
- [Perl5] Incorporated [ 841074 ] better croaking (PATCH). This fixes some problems
- with strings and provides some new error functions.
- Contributed by Salvador Fandino Garcia.
-
-11/25/2003: beazley
- Fixed [ 791835 ] Default argument with cast: txt = (char *)"txt" syntax Error.
- The parser should now accept things like this:
-
- void foo(char *s = (char *) "Hello");
-
- Problem reported by Claudius Schnorr.
-
-11/24/2003: beazley
- [Tcl] Fixed problem with cross module linking. Previously modules referred
- to base classes through a global variable. Now, the module looks up base
- classes through the type system itself---avoiding the need to link to a global
- like before. Caveat: modules with base classes must be loaded before
- modules with derived classes.
-
-11/24/2003: mkoeppe (Matthias Koeppe)
- [Guile] In -scm mode, use () to represent null pointers,
- as it is done in -gh mode.
-
-11/23/2003: mkoeppe (Matthias Koeppe)
- Add a generated script "preinst-swig", which can be used
- to invoke SWIG before it has been installed. It arranges
- that the runtime libraries from the source directory are
- used.
-
-11/23/2003: mkoeppe (Matthias Koeppe)
- [Guile] In -gh mode, don't forget to call SWIG_Guile_Init.
- Add a SWIG_contract_assert macro.
-
-11/23/2003: mkoeppe (Matthias Koeppe)
- [MzScheme] Update the configure check for the dynext object to work
- with MzScheme 205.
-
-11/20/2003: mmatus
- Fixed the include/import error reported by Kerim Borchaev,
- where two files with names like
-
- 'dir1/hello.i'
- 'dir2/hello.i'
-
- can not be include at the same time. Swig was including
- just the first one, assuming the second one was not a
- different one, since it was checking/keeping just the
- basename 'hello.i'.
-
-11/19/2003: beazley
- Changes to the SWIG runtime library support.
- - The -c command line option has been renamed to -noruntime
- - New command line option: -runtime. When supplied, this
- inserts the symbol SWIG_GLOBAL into the wrapper code. This,
- in turn, makes all of the runtime support functions globally
- visible.
- - New library file: swigrun.i. Used to create modules
- for runtime library (if needed).
-
-11/18/2003: cheetah (William Fulton)
- 'make srcrpm' rpmbuild fix - patch from Joe Cooper
-
-11/18/2003: mkoeppe (Matthias Koeppe)
- [Guile] Change meaning of configure option --with-guile to
- the name of the Guile executable. The new option --with-guile-prefix
- can be used to specify the tree where Guile is
- installed. (However, usually it suffices to use the
- single option --with-guile-config.)
- When running the run tests test-suite, make sure to use the
- version of Guile that SWIG was configured for.
-
-11/17/2003: mkoeppe (Matthias Koeppe)
- [Guile] Improvements to object-ownership management in
- "-scm" mode. (They do not apply to the default "-gh" mode.)
- * Renamed the smob type that indicates that the object can
- be garbage collected from "collected swig" to "collectable
- swig", which is more precise.
- * Export the destructor functions again. It is now
- allowed to explicitly call destructors, even for
- garbage-collected pointer objects. A pointer object
- that has been passed to a destructor is marked in a
- special way using a new smob type, "destroyed swig".
- (This helps avoid nasty memory bugs, where references to
- dead C objects are still held in Scheme. Moreover, the
- garbage collector will not try to free a destroyed
- object once more.)
- * Destructor-like functions can also mark their arguments
- as destroyed by applying the typemap SWIGTYPE *DESTROYED.
- (It calls the function SWIG_Guile_MarkPointerDestroyed.)
- * Functions that "consume" their objects (or that "own"
- them after the call) can mark their arguments as
- not garbage collectable. This can be done by applying
- the typemap SWIGTYPE *CONSUMED. (It calls the function
- SWIG_Guile_MarkPointerNoncollectable.)
- * The macro TYPEMAP_POINTER_INPUT_OUTPUT from library
- pointer-in-out.i creates additional typemaps
- PTRTYPE *INPUT_CONSUMED, PTRTYPE *INPUT_DESTROYED.
- They mark the passed pointer object likewise.
- The typemap PTRTYPE *OUTPUT creates a garbage-collectable
- pointer object, like %newobject does for a returned
- pointer. Use the new typemap PTRTYPE *OUTPUT_NONCOLLECTABLE
- to create a pointer object that will not be garbage collected.
-
-11/17/2003: mkoeppe (Matthias Koeppe)
- [Guile] Handle $input in "freearg" typemaps.
- Never qualify GOOPS slot names with the class name.
- Handle optional arguments properly in the GOOPS methods.
-
-11/16/2003: cheetah (William Fulton)
- Fixes for installation to work with the upcoming Automake-1.8.
- mkinstalldirs was being used by a non-Automake makefile.
- mkinstalldirs is being phased out and so was not being
- created by Automake. install-sh used instead.
-
-11/16/2003: cheetah (William Fulton)
- [Java] Numerous director improvements, tweaks and bug fixes since
- the initial implementation have been contributed by Scott Michel.
-
-11/12/2003: beazley
- [Python] When %feature("shadow") is used to add code to shadow
- classes, the special variable $action expands to the name of the
- underlying wrapper function that would have been called normally.
-
-11/12/2003: beazley
- [Python] When generating proxy class code, SWIG emits a few
- default methods for __repr__() and other Python special
- methods. Some of these methods are emitted after all of the
- contents of a class. However, this makes it hard to override
- the methods using %pythoncode and some other directives that
- allow code to be inserted into a class. These special methods
- are now emitted into the code *before* all of the other methods.
- Suggested by Eric Jones.
-
-11/11/2003: beazley
- Preprocessor enhancement. For include statements like this:
-
- %include "foo/bar.i"
-
- the directory "foo" is now added to the search path while
- processing the contents of bar.i. Thus, if bar.i includes other
- files in the same directory, they will be found. Previously,
- you would have to add additional directories using -I to make this
- work correctly. Note: the C preprocessor seems to behave in
- an identical manner on many (most? all?) systems.
- Suggested by Kerim Borchaev.
-
-11/11/2003: beazley
- Configuration changes to make SWIG work on Mac OS X 10.3.x (Panther).
- Tested with Python, Tcl, Perl, and Ruby---all of which seem to work.
-
-11/08/2003: cheetah (William Fulton)
- [Java] Fixed the typemaps in various.i which were mostly broken.
- char **STRING_IN and char **STRING_RET typemaps replaced with
- STRING_ARRAY. float *FLOAT_ARRAY_RETURN typemap removed.
-
-11/08/2003: beazley
- [Tcl] Tcl module now emits a safe module initialization function by
- default. It can be removed by running 'swig -nosafe'.
-
-11/04/2003: mkoeppe (Matthias Koeppe)
- [Guile] Only use the SCM_ API when the function
- `scm_slot_exists_p' exists (needed for GOOPS support).
- This function was renamed during the Guile 1.5 series
- from `scm_slots_exists_p'.
- Report the right runtime library when invoked with
- -scm -ldflags.
-
-11/03/2003: mkoeppe (Matthias Koeppe)
- [Chicken] Fix #782052. The --with-chickencfg configure
- option (and others) were not accepted.
-
-11/02/2003: mkoeppe (Matthias Koeppe)
- [Guile] Merge new set of GOOPS changes by John Lenz.
- GOOPS objects are now manipulated directly by the C code.
- Some fixes to typemap-GOOPS interaction.
-
-11/02/2003: mkoeppe (Matthias Koeppe)
- [Guile] Remove the file argument to -scmstub and -goops.
- The Scheme files are now always called MODULE.scm or
- MODULE-primitive.scm, where MODULE is the module name and
- "primitive" can be changed by the -primsuffix option.
- The Scheme files are now placed in the directory given by
- the -outdir option, or the current directory.
- (Patch by John Lenz, slightly modified.)
-
- *** INCOMPATIBILITY [Guile] ***
-
-11/02/2003: mkoeppe (Matthias Koeppe)
- Unify the pointer-conversion runtime API. The standard
- functions are:
- * SWIG_NewPointerObj (POINTER, TYPE, FLAGS)
- -- Create an scripting object that represents a typed
- pointer. FLAGS are language specific.
- * SWIG_ConvertPtr (INPUT, RESULT, TYPE, FLAGS)
- -- Get a pointer from the scripting object INPUT and
- store it in the place RESULT. When a type mismatch
- occurs, return nonzero.
- * SWIG_MustGetPtr (INPUT, TYPE, ARGNUM, FLAGS)
- -- Get a pointer from the scripting object INPUT and
- return it. When a type mismatch occurs, throw an
- exception. If ARGNUM > 0, report it as the
- argument number that has the type mismatch.
- [Guile]: No changes.
- [MzScheme]: No changes.
- [Perl]: Add the function SWIG_NewPointerObj.
- The function SWIG_MakePtr is kept.
- The function SWIG_MustGetPtr is currently not
- supported.
- [Python]: Add the function SWIG_MustGetPtr.
- [Ruby]: Add the function SWIG_MustGetPtr.
- [Tcl]: Remove the "interp" argument of
- SWIG_NewInstanceObj, SWIG_ConvertPtr,
- SWIG_ConvertPacked, and SWIG_ConvertPtrFromString.
- The function SWIG_MustGetPtr is currently
- not supported.
- No changes to Pike because its pointer conversion code did
- not look complete. No changes to PHP4, because I did not
- understand its runtime code. No changes to Chicken
- because major changes are expected soon anyway. No
- changes to Java, OCaml, C# because they do not seem to
- have a pointer-conversion runtime API.
-
- *** INCOMPATIBILITY [Tcl] ***
-
-11/02/2003: mkoeppe (Matthias Koeppe)
- [Perl5, PHP4, Pike, Python, Ruby, Tcl]: Use the
- preprocessor to rename external functions of the SWIG
- runtime API to follow the naming convention
- SWIG_<language>_<function>. This should allow linking
- more than one interpreter into a program.
-
-10/31/2003: cheetah (William Fulton)
- [C#] Fix since introducing the exception and std::string delegates.
- The fix overcomes linker errors when using more than one SWIG module.
- Problem reported by Andreas Schörk.
-
-10/31/2003: beazley
- Incorporated patch: [ 823302 ] Incr Tcl support.
- Contributed by Alexey Dyachenko.
- Note: needs documentation.
-
-10/31/2003: beazley
- Incorporated patch: [ 829325 ] new Python Module options and features.
- Robin Dunn writes:
-
- This patch makes a number of changes to the SWIG python module.
-
- 1. Add -apply option, and change the default code
- output to use the foo(*args, **kw) calling syntax
- instead of using apply(). If the -apply option is
- given then code is generated as before. This is very
- similar to Patch #737281 but the new -modern option
- makes the second half of that patch unnecessary so it
- is not included here.
-
- 2. Add -new_repr option. This is the same as my Patch
- #797002 which I will mark as closed since it is no
- longer needed. When this new option is used then the
- __repr__ methods that are generated for proxy classes
- will be more informative and give details about the
- python class and the C++ class.
-
- 3. Add %feature("addtofunc"). It allows you to insert
- one or more lines of code inside the shadow method or
- function that is already generated, instead of
- replacing the whole thing like %feature("shadow") does.
- For __init__ it goes at the end, for __del__ it goes
- at the begining and for all others the code generated
- is expanded out to be like
-
- def Bar(*args, **kwargs):
- val = _module.Foo_Bar(*args, **kwargs)
- return val
-
- and the "addtofunc" code is inserted just before the
- return statement. If the feature is not used for a
- particular method or function then the shorter code is
- generated just like before.
-
- 4. A little bit of refactoring to make implementing
- addtofunc a little easier.
-
- 5. Added a -modern command-line flag that will cause
- SWIG to omit the cruft in the proxy modules that allows
- it to work with versions of Python prior to 2.2. The
- result is a simpler, cleaner and faster python proxy
- module, but one that requires Python 2.2 or greater.
-
-10/31/2003: beazley
- Incorporated patch: [ 829319 ] XML module tweaks.
- This adds a new command line option -xmllite that
- greatly reduces the amount of emitted XML code by
- eliminating some fields mostly used in SWIG's
- internal processing. Contributed by Robin Dunn.
-
-10/31/2003: beazley
- Incorporated patch: [ 829317 ] Adds DohSplitLines function.
- Contributed by Robin Dunn.
-
-10/29/2003: beazley
- Fixed [ 827907 ] argout objects not being wrapped properly (PATH).
- Patch contributed by Salvador Fandiño García.
-
-10/29/2003: beazley
- Fixed [ 826996 ] perl type checking ignores perl subclasses.
- This enhancement makes it so wrapped classes and structs can
- be subclassed in Perl and used normally.
- Patch contributed by Salvador Fandiño García.
-
-10/16/2003: cheetah (William Fulton)
- [C#] IntPtr marshalled with a void* instead of int in C function
- declarations. The casts thus look more conventional, for example:
-
- // old
- DllExport double SWIGSTDCALL CSharp_get_Shape_x(int jarg1) {
- ...
- Shape *arg1 = (Shape *) 0 ;
- arg1 = *(Shape **)&jarg1;
- ...
- }
- // new
- DllExport double SWIGSTDCALL CSharp_get_Shape_x(void * jarg1) {
- ...
- Shape *arg1 = (Shape *) 0 ;
- arg1 = (Shape *)jarg1;
- ...
- }
-
-
-10/14/2003: beazley
- Fixed a subtle problem with overloaded methods and smart pointers.
- If a class has overloaded methods like this:
-
- class Foo {
- public:
- int bar(int x);
- static int bar(int x, int y);
- };
-
- and the class is used as a smart pointer:
-
- class FooPtr {
- public:
- Foo *operator->();
- };
-
- The SWIG would try to expose the static member Foo::bar
- through FooPtr---resulting bogus wrapper code and a compiler
- error.
-
- Due to the way in which overloading is handled, it is
- extremely difficult to eliminate the static method in
- this case. Therefore, it is still exposed. However,
- the generated code now compiles and works.
-
-10/05/2003: mkoeppe (Matthias Koeppe)
- [Guile, MzScheme, Chicken]: Remove symbol clashes between
- the runtime libraries by renaming all extern common.swg
- functions with the preprocessor.
-
-10/05/2003: mkoeppe (Matthias Koeppe)
- [Guile] Added basic GOOPS support, contributed by John Lenz.
- See the documentation for details.
-
- *** NEW FEATURE ***
-
-10/04/2003: mkoeppe (Matthias Koeppe)
- [Guile] New option, -only-setters, which disables
- traditional getter and setter procedures for structure slots.
-
-10/03/2003: mkoeppe (Matthias Koeppe)
- [Guile] Added run test for reference_global_vars by John Lenz.
-
-09/30/2003: beazley
- Partial solution to [ 792180 ] C++ smart-pointer/namespace mixup revisited.
- The problem is not easy to fix (at least it doesn't seem so), but is
- related to the instantiation of qualified templates inside of other
- namespaces. SWIG now generates an error message in this case rather
- than generating broken wrappers.
-
-09/30/2003: beazley
- Fixed [ 800012 ] ENTER macro from CORE/scope.h clashes with libc search.h.
- Reported by Britton Leo Kerin.
-
-09/30/2003: beazley
- Fixed [ 811518 ] Casting ints to doubles (w/ solution?)
- Addresses a problem with overloading in the Perl module.
- Reported by Gerald Dalley.
-
-09/28/2003: mkoeppe
- [Guile with -scm option] Fix typo in generated code for
- procedures-with-setters. Reported by John Lenz.
-
-09/26/2003: beazley
- Fixed [ 812528 ] externs not correct when throw is in signature.
- Reported by Joseph Winston.
-
-09/23/2003: cheetah (William Fulton)
- SWIG was generating a number of symbols that didn't comply with
- the ISO C/C++ standard, in particular ISO/IEC 14882:1998(E) 17.4.3.1.2
- where double underscores are forbidden as well as symbols starting with
- an underscore followed by an upper case letter. Most of these have
- been rooted out. See new section added to internals.html development
- manual 'Symbol Naming Guidelines for Generated C/C++ Code'.
-
-09/23/2003: cheetah (William Fulton)
- Director typemap name changes:
- inv => directorin
- outv => directorout
- argoutv => directorargout
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-09/19/2003: mrose (Mark Rose)
- [Python] Director constructors now default to __disown = 0,
- which is the intended behavior and fixes the director_finalizer
- test case under python.
-
-09/12/2003: cheetah (William Fulton)
- [C#] - Typemaps added for std::string and const std::string &.
- - New delegate for creating a C# string given a char *. It
- can be used by calling SWIG_csharp_string_callback as shown
- in the std::string 'out' typemap. Useful if the return type is
- mapped to a C# string and the calling function is responsible
- for cleaning up memory as the C# garbage collector doesn't
- free the memory created in C/C++ and then returned as a C# string.
- - The exception delegates have moved into an inner class in the
- intermediate class, thereby freeing up the static constructor.
-
-09/11/2003: beazley
- (Internals)
- Major refactoring of iteration over lists and hashes. The
- DOH library now uses iterators. They work like this:
-
- List *l = (some list);
-
- Iterator i;
- for (i = First(l); i.item; i = Next(i)) {
- // i.item contains the actual list item.
- // i.item is NULL at end of list
- ...
- }
-
- Hash *h = (some hash);
- Iterator j;
- for (j = First(h); j.item; j = Next(j)) {
- // j.item contains hash table item
- // j.key contains hash table key
- // Both j.item and j.key are NULL at end
- ...
- }
-
- The old iteration functions Firstitem(), Nextitem(), Firstkey(),
- and Nextkey() are gone.
-
- The new iterators are simpler, result in better memory use,
- and may be faster. Also, there are no longer any problems
- iterating over the same list/hash in multiple places at
- the same time. For example, this is fine:
-
- Iterator i,j;
- for (i = First(l); i.item; i = Next(i)) {
- for (j = First(l); j.item; j = Next(j)) {
- ...
- }
- }
-
- (This never worked in previous versions).
- *** POTENTIAL INCOMPATIBILITY ***. This will probably break
- third party extensions to SWIG (or give them further encouragement
- to join the SWIG CVS-tree :-).
-
-09/10/2003: mkoeppe (Matthias Koeppe)
- [Guile] Fix memory leaks in the "list-vector.i" typemaps.
-
-09/09/2003: mkoeppe (Matthias Koeppe)
- [Chicken] Use C_mk_bool rather than C_mkbool. This fixes
- the wrapping of boolean values for Chicken 1.10 and newer.
- Reported by Dave <hundo@yahoo.com> / Felix Winkelmann
- <felix@proxima-mt.de>.
-
-09/05/2003: cheetah (William Fulton)
- [Java] Directors implemented for Java. In summary this is a big new feature
- which supports upcalls from C++ to Java. Code is generated to support C++
- callbacks to call into Java and true polymorphic behaviour for Java classes
- derived from C++ classes. See java.html for details. Contributed by
- Scott Michel.
-
-09/05/2003: Tiger
- Created contract example directory at /SWIG/Examples/contract
- Added simple contract examples (simple_c & simple_cxx)
- Modified contract module's output format
-
- *** NEW FEATURE ***
-
-09/01/2003: cheetah (William Fulton)
- Test-suite build improvements:
- - Multiple build directories working for the test suite, so it is now
- possible to run configure in multiple subdirectories and run the test
- suite in each of these sub directories.
- - 'make distclean' fixed so it doesn't bomb out on the Examples directory
- when using multiple subdiretory builds. Required the following directories
- to be moved:
- Examples/GIFPlot/Perl -> Examples/GIFPlot/Perl5
- Examples/GIFPlot/Php -> Examples/GIFPlot/Php4
- These new directories used to be symbolic links to the old directory.
- Also the Examples/test-suite/Perl symbolic link has been removed.
- - Running the test-suite, other than from the root directory, say
- in Examples/test-suite/python will now display all the code being
- executed.
- - The following 3 C# compilers are detected during configure and work with
- the test-suite: Mono, Portable.NET and Microsoft.
-
-09/01/2003: Tiger
- Added inheritance support for design by contract feature.
-
-09/01/2003: beazley
- Fixed [ 794914 ] Wrong types in template specialization.
- SWIG was not handling arguments correctly in template
- partial specialization. For example,
-
- template<class T> class Foo<T *> {
- public:
- T *blah();
- };
-
- %template(FooInt) Foo<int *>;
-
- in this class, the return type of blah was set to
- 'int **', but it should really be 'int *'. This has been
- fixed, but it will affect all prior uses of partial
- specialization.
-
-09/01/2003: beazley
- Fixed [ 786394 ] Patch for generated perl code does not compile under RedHat9.
- Reported by Scott Finneran.
-
-09/01/2003: beazley
- Fixed [ 791579 ] (unsigned) long long handled incorrectly (Tcl).
- This was an error in the Tcl typemaps.i file.
- Reported by Kjell Wooding.
-
-09/01/2003: beazley
- Fixed [ 797573 ] no way to rename classes coming from C structures.
- This problem relates to renaming of anonymous structures with a
- typedef. For example:
-
- %rename(Bar) Foo;
- typedef struct {
- ...
- } Foo;
-
- Reported by Britton Leo Kerin.
-
-09/01/2003: beazley
- Fixed [ 797576 ] -help seems to imply that only tcl-specific options exist.
- Added a comment to alert user to other options.
- Reported by Britton Leo Kerin.
-
-09/01/2003: beazley
- Fixed [ 798205 ] Segfault in SWIG_ConvertPtr.
- Reported by Prabhu Ramachandran.
-
-08/30/2003: mrose (Mark Rose)
- Modified the director typemaps in python/std_complex.i to use the
- new-style macro and conversion functions, which eliminated some
- redundant code. Fixed a few bugs in these typemaps as well, although
- more testing is needed.
-
-08/29/2003: mrose (Mark Rose)
- Completed initial support for wrapping abstract classes with directors.
- Constructor wrappers will be generated for abstract classes that have
- directors, and instances of the director classes will be created regardless
- of whether the proxy class has been subclassed in the target language.
- No checks are made during construction to ensure that all pure virtual
- methods are implemented in the target language. Instead, calls to
- unimplemented methods will throw SWIG_DIRECTOR_PURE_VIRTUAL_EXCEPTION
- exceptions in C++.
-
- Integrated Prabhu Ramachandran's typemap patches, which provide director
- typemap support for enums and std::size_t, and fix a couple bugs in the
- director std::vector<> typemaps.
-
-08/29/2003: cheetah (William Fulton)
- [C#] Implemented exception handling for throwing C# exceptions from C/C++ code.
- A few delegate functions are available for calling which then throw the C#
- exception. Use the SWIG_CSharpThrowException function from C/C++ typemaps.
- See the generated wrapper code or csharphead.swg for all available exceptions.
- Example:
-
- SWIG_CSharpThrowException(SWIG_CSharpException, "exception description");
-
- The 'throws' typemaps are also now implemented, so code is automatically
- generated to convert any C++ exception into a C# System.Exception when the C++
- method declares an exception specification such as:
-
- int foo() throw(Bar);
-
- Also any parameters that are references to a C++ class or a class passed by value
- and are passed as a C# null will now throw a C# NullReferenceException.
-
-08/29/2003: cheetah (William Fulton)
- [C#] Fix to match the calling convention of all pinvoke methods so that they
- match the calling convention used by default in the C# 'static extern' declarations
- (__stdcall is used on Windows).
-
-08/19/2003: cheetah (William Fulton)
- [Java] Reworked std::string typemaps. Fixes a number of string in std namespace
- problems. For example %template vector<string>. The templated class' get method
- wasn't returning a Java String, but a SWIGTYPE_p_string. Reported
- by Zach Baum.
-
-08/15/2003: beazley
- Fixed [ 763522 ] 1.3.19 segfault in SwigType_add_pointer/DohInsertitem.
- Related to problem with unnamed class handling in Perl module.
-
-08/15/2003: beazley
- Fixed [ 763563 ] Missing indication of optional arguments.
- Tcl module. Reported by Krzysztof Kozminski.
-
-08/15/2003: beazley
- Fixed [ 787432 ] long param handled as int. Tcl module
- now uses Tcl_GetLongFromObj to convert integer values.
-
-08/11/2003: beazley
- Fixed [ 775989 ] numeric template parameters. There were
- some errors in template expansion related to the use of
- arrays where the array dimension was a template parameter.
- It should work now. Reported by Bryan Green.
-
-08/10/2003: mrose (Mark Rose)
- Added a director typemap (outv) for return by value and cleaned up up a few
- of the commented director typemaps.
-
-08/10/2003: mrose (Mark Rose)
- Fixed constructor generation for director classes to ignore private
- constructors. Protected constructors are also ignored for now, pending
- a solution to the problem of wrapping classes that only define protected
- constructors.
-
-08/07/2003: cheetah (William Fulton)
- New commandline option -outdir <dir> to specify where the language specific
- files are to be generated. This is useful for target languages like Python,
- Java etc which generate proxy files in the appropriate language.
- This option does not apply to the C/C++ wrapper file.
-
-08/07/2003: cheetah (William Fulton)
- On Windows the generated files (other than the _wrap.c or _wrap.cxx files)
- were sometimes incorrectly being generated into the current directory unless
- the input file used the Unix path separator. The Windows path separator
- should now be used. Bug reported by Robert Davies.
-
-08/07/2003: beazley
- Added array variable set typemap to Perl module.
-
-08/07/2003: beazley
- Fixed [ 775677 ] Array init causes codegen bug..
-
-08/07/2003: beazley
- Fixed [ 779062 ] Class"\n"::foo not supported. SWIG
- should now correctly handle whitespace in between
- namespace qualifiers. For example "A :: Foo :: Bar".
-
-07/31/2003: cheetah (William Fulton)
- Fixes for parameters which are classes that are passed by value and have
- a default value. A copy constructor for SwigValueWrapper is required
- (SF #780056). Also fixed memory leak in these circumstances. These mods
- also fix SF #780054.
-
-07/28/2003: beazley
- Improved run-time error message for pointers in Python module.
- Contributed by Zooko.
-
-07/10/2003: ballabio (Luigi Ballabio)
- [Almost all languages] Wrappers for std::pair added.
- Typemaps for Python, Ruby, Guile and MzScheme.
-
-07/01/2003: mkoeppe (Matthias Koeppe)
- [Chicken] Handle the case of more than one argout typemap
- per function.
-
-06/29/2003: cheetah (William Fulton)
- [Java, C#] SF #670949 request. The destructor wrapper function name is now
- configurable. A new attribute called methodname in the
- javadestruct/javadestruct_derived (Java) or csdestruct/csdestruct_derived (C#)
- typemaps specifies the method name. For example in Java the destructor is
- wrapped by default with the delete method:
-
- %typemap(javadestruct, methodname="delete") SWIGTYPE {...}
-
-06/27/2003: cheetah (William Fulton)
- [Java, C#] The throws attribute for adding exception classes to the throws
- clause also now works with the following typemaps:
- newfree
- javain, javaout (Java)
- csin, csout (C#)
-
- For example, the 'AnException' will be added to the throws clause in the
- proxy function:
-
- %typemap(javaout, throws="AnException") int {
- int returnValue=$jnicall;
- if (returnValue==0) throw new AnException("Value must not be zero");
- return returnValue;
- }
-
-06/25/2003: mrose (Mark Rose)
- [Python] Director typemap marshalling checks for null pointers when
- walking the parameter list instead of relying soley on the parameter
- count. Cures a segfault that occurred for multiple argument inv typemaps.
- Someone with more Swig experience should probably review this code.
-
-06/24/2003: mkoeppe (Matthias Koeppe)
- [Chicken] Don't emit calls to "C_check_for_interrupt",
- which may result in an endless loop. Patch by felix@proxima-mt.de.
-
-06/20/2003: cheetah (William Fulton)
- [C#] Finalizers now use destructor syntax as the override which was used in
- the Finalize method is not in the ECMA standards, spotted by the MS compiler.
-
-06/10/2003: cheetah (William Fulton)
- [C#] A number of changes have been made to remove the Java naming
- that was used in the C# module.
-
- Typemap name changes:
- jni -> ctype
- jtype -> imtype
- jstype -> cstype
- javain -> csin
- javaout -> csout
- javainterfaces -> csinterfaces
- javabase -> csbase
- javaclassmodifiers -> csclassmodifiers
- javacode -> cscode
- javaimports -> csimports
- javaptrconstructormodifiers -> csptrconstructormodifiers
- javagetcptr -> csgetcptr
- javafinalize -> csfinalize
-
- Feature name changes:
- javaconst -> csconst
- javamethodmodifiers -> csmethodmodifiers
-
- Pragma changes:
- pragma(java) -> pragma(csharp)
- jniclassbase -> imclassbase
- jniclassclassmodifiers -> imclassclassmodifiers
- jniclasscode -> imclasscode
- jniclassimports -> imclassimports
- jniclassinterfaces -> imclassinterfaces
-
- Special variable name changes:
- $javaclassname -> $csclassname
- $javainput -> $csinput
- $jnicall -> $imcall
-
- This will break SWIG interface files that use these typemaps, features
- and pragmas. Please update your code or use macros for backwards
- compatibility.
-
- *** POTENTIAL INCOMPATIBILITY FOR C# MODULE ***
-
-06/10/2003: mkoeppe (Matthias Koeppe)
- [MzScheme] Applied MzScheme module updates contributed by
- John Lenz <jelenz@students.wisc.edu>.
-
- - Updated mzscheme to use SWIG's common runtime type
- system from common.swg.
-
- - The Lib/mzscheme directory has been reorganized to
- standardize names across the language modules:
- mzscheme.i was moved to mzscheme.swg, mzscheme.swg and
- mzschemedec.swg have been removed, mzrun.swg (which
- contains the runtime code) has been added.
-
- - The swig_proxy structure was renamed to swig_mz_proxy.
- swig_mz_proxy now contains a pointer to a swig_type_info
- structure.
-
- - Added varin and varout typemaps for SWIGTYPE [] and
- SWIGTYPE &.
-
- - Garbage collection by calling scheme_add_finalizer() has
- been added.
-
- *** NEW FEATURE [MzScheme] ***
-
-06/10/2003: cheetah (William Fulton)
- [Java] New typemaps: javadestruct and javadestruct_derived
- for the C++ destructor wrapper. The javadestruct version gets used by
- classes at the top of an inheritance chain and the javadestruct_derived
- version gets used by other classes.
-
- [C#] cildispose and cildisposeoverride typemaps replaced by
- csdestruct and csdestruct_derived typemaps. The delete()
- method has been removed and its functionality put into these
- typemaps designed for the Dispose() method.
-
- - New typemaps csinterfaces and csinterfaces_derived replace
- the javainterfaces typemap. Also fixes the peculiarity of all classes
- in an inheritance chain individually deriving from the IDisposable
- interface.
-
- - New typemap csfinalize for finalizers. C++ destructors are now called
- by garbage collector during finalization. Problem reported by
- Andreas Schörk.
-
-06/10/2003: Tiger
- Modified contract code for error message output.
- Contract code can now print out simple error message.
- Modified contract code to prepare for inheritance
-
-06/03/2003: mkoeppe
- [Guile] Applied Guile module updates contributed by
- John Lenz <jelenz@students.wisc.edu>.
-
- - SWIG currently uses Guile's gh_ API, which is marked as
- deprecated in Guile 1.6 and will be removed in Guile
- 1.9. This change introduces a command-line flag "-scm"
- which causes SWIG to generate wrappers that use Guile's
- SCM API instead; this requires Guile >= 1.6.
-
- - The Lib/guile directory has been reorganized to
- standardize names across language modules: guiledec.swg
- and guile.swg have been moved into guile_gh_run.swg,
- guile.i has been moved to guile_gh.swg, guile_scm.swg
- and guile_scm_run.swg which contain the SCM API stuff
- have been added
-
- - ghinterface.i, which contains the defines from the gh_
- functions to the scm_functions has been added
-
- - The API for dealing with pointer objects is now
- SWIG_ConvertPtr, SWIG_MustGetPtr, SWIG_NewPointerObj.
-
- - Added varin and varout typemaps for SWIGTYPE [] and SWIGTYPE &
-
- - Garbage collection has been added.
-
- *** NEW FEATURE [Guile] ***
-
-06/01/2003: cheetah (William Fulton)
- Dimensionless arrays such as
-
- int foo[] = {1, 2};
- extern int bar[];
-
- produce a warning that the variable is read-only. Depending on the target
- language, this used to cause compile errors or generate a setter that
- generated a runtime error. A setter cannot be automatically generated
- because the array size cannot be determined by SWIG. A varin, globalin
- or memberin typemap (depending on the target language) must be written
- by the user.
-
-05/29/2003: beazley
- Refinement to default typemap matching and arrays. When an
- array is declared like this:
-
- int foo[4];
-
- The default typemap now resolves to
-
- SWIGTYPE [ANY]
-
- If no match is found for that, it then resolves to
-
- SWIGTYPE []
-
- If no array dimension is specified in the original declaration,
- the SWIGTYPE [] is used right away.
-
- Note: This change has been made to resolve problems related to
- arrays with and without dimensions. For example, sometimes SWIG
- was generating setter functions for array variables with no dimensions
- (an error). Likewise, SWIG sometimes made arrays with dimensions
- read-only (also an error). This fixes the arrays_global test
- problem.
-
-05/28/2003: beazley
- Fixed subtle type handling bug with references and pointers.
- If you had functions like this:
-
- typedef Foo Bar;
-
- Foo *func1();
- void func2(Bar &x);
-
- Then func2() wouldn't accept objects returned by func1()
- because of a type error. It should work now.
- Reported by Brian Yang.
-
-05/21/2003: cheetah (William Fulton)
- Fixes to some of the Visual C++ example project files which would not
- work with spaces in the paths held in the environment variables used to
- point to the target language's library / include directory.
- SF bug #740769
-
-05/21/2003: songyanf (Tiger)
- Added -contracts option.
- First try of the idea of "Wrap by Contract":
- build up realiable cross-language module by wrapping with SWIG.
- Implemented basic assertion
- (preassertion & postassertion & invariant)
- for simple C/C++ functions.
-
- Current format of contracts are:
- %contract class_name :: func_name (paras...) {
- require:
- boolean exprs;
- exprs;
- ensure:
- boolean expr;
- exprs;
- invariant:
- boolean expr;
- exprs;
- }
-
- *** NEW FEATURE ***
-
-05/19/2003: cheetah (William Fulton)
- Build tweaks. There were a few preprocessor definitions which were
- specified in the Makefile for passing on the commandline when compiling.
- These are now all defined in swigconfig.h. Autoconf doesn't normally
- allow installation directories to be defined in this config header file,
- but an autoconf archive macro enables this. This macro along with future
- autoconf macros are going to be put in the Tools/config directory.
-
- 'swig -version' now reports the target build platform.
-
-05/11/2003: cheetah (William Fulton)
- [C# and Java] Fix to the following typemaps:
-
- javabase, javainterfaces, javaimports, javaclassmodifiers,
- javaptrconstructormodifiers, javafinalize, javagetcptr & javacode.
-
- These are the typemaps for modifying/generating proxy classes.
- Previously the typemaps would use the proxy class name and not the
- C++ type, which was inconsistent with all other typemaps.
-
- In most circumstances the proxy class name and the C++ class name/type
- is the same except for classes in namespace, templated classes etc. so
- this shouldn't affect most cases.
-
- *** POTENTIAL INCOMPATIBILITY FOR JAVA and C# MODULES ***
-
-05/09/2003: cheetah (William Fulton)
- Visual C++ Project files have been added so that the runtime libraries
- can be built on Windows (for Tcl, Perl, Python and Ruby).
-
-05/01/2003: beazley
- Fixed problem with return by value, const, and private constructors.
- For example:
-
- class B {
- private:
- B();
- public:
- B(const B&);
- };
-
- class A {
- ...
- const B returnB() const;
- ...
- };
-
- Problem and patch suggestion reported by Bill Hoffman.
-
-04/29/2003: cheetah (William Fulton)
- Build changes:
- - Single autoconf invocation - autoconf in the Tools directory has gone.
-
- - Libtool bootstrapped when running autogen.sh. This requires anyone
- using the cvs version of SWIG to have libtool installed on their
- machine. Suggest version 1.4.2 or higher, preferably the latest - 1.5.
-
- - Automake is now used to build the runtime libraries in conjunction
- with libtool.
-
- - Runtime libraries are now successfully built as DLLs on Cygwin.
-
- - Skipping languages is no longer just determined in the top level
- makefile but in configure.in. This info is used for building
- the runtime libraries and for running the examples and test-suite.
-
- - These changes have fixed multiple build directory builds, that is
- building from directories other than the top level directory.
- Installation from multiple build directories also working. An initial
- configure in the top level directory is no longer needed as described
- in 04/02/2003 entry. A 'make distclean' will be needed before building
- in a directory other than the top level directory if the autotools
- have been run from this top level directory at some point, but
- autoconf will tell you this. Note that 'make check' only works from
- the top level directory at the moment.
-
-04/28/2003: beazley
- Fixed [ 723471 ] Wrapper_print() fails with preprocessor directives.
-
-04/28/2003: beazley
- Minor refinement of const static member variable handling
- described in CHANGES 08/11/2002. Previously, SWIG merely
- checked to see if there was an initializer in the declaration.
- Now, SWIG additionally checks to make sure the static member
- is const.
-
-04/25/2003: ljohnson (Lyle Johnson)
- [Ruby] Added a kind of limited support for multiple inheritance,
- activated using the -minherit command-line option. I've also updated
- the "C++ Inheritance" section of the Ruby documentation to discuss
- how this works, and its limitations. Also also modified the minherit.i
- test case to run against this.
-
-04/25/2003: ljohnson (Lyle Johnson)
- [Ruby] Added the -globalmodule command-line option for the Ruby
- module, for wrapping stuff into the global module (Kernel) instead
- of a nested module. Updated documentation accordingly.
-
-04/23/2003: mrose (Mark Rose)
- Fixed symname error in director calls to Python methods
- that extend C++ operators.
-
- Stopped director destructor wrappers from calling __set_up,
- which was leaving the director flag in an inconsistent state.
-
-04/23/2003: beazley
- Fixed problem with namespace resolution and nested namespaces.
- Reported by Alfred Lorber (and Marcelo Matus).
-
-04/16/2003: cheetah (William Fulton)
- Patch for Java examples and test-suite to run on Mac OS X.
-
-04/15/2003: ljohnson (Lyle Johnson)
- [Ruby] Incorporated Nobu Nakada's patches for supporting the Ruby
- 1.8 allocation framework.
-
-04/15/2003: ljohnson (Lyle Johnson)
- [Ruby] Replaced all uses of the deprecated STR2CSTR() macro with the
- safer StringValuePtr() macro. For more information, see ruby-talk:67059
- and follow-ups to that post.
-
-04/11/2003: beazley
- Fixed problem with preprocessor macro expansion. For example:
-
- #define min(x,y) ((x) < (y)) ? (x) : (y)
- int f(int min);
-
- Reported by Sebastien Recio.
-
-04/10/2003: cheetah (William Fulton)
- [Java] Added a runtime check to typemaps in arrays_java.i library to check
- that the Java array passed in is the same size as the C array and throw an
- exception if not.
-
- Also fix to use delete instead of free for arrays created using new.
-
-04/07/2003: cheetah (William Fulton)
- Remove GCC3 warning when compiling the examples and test-suite:
-
- cc1plus: warning: changing search order for system directory "/usr/include"
- cc1plus: warning: as it has already been specified as a non-system directory
-
- See SF patch #715531 submitted by Gerald Williams
-
-04/03/2003: cheetah (William Fulton)
- [C#] Improved wrapping of enums and constants. These were previously
- wrapped as C# variables rather than constants. Either these are wrapped
- as readonly (runtime) constants or compile time constants, depending on
- the %javaconst directive (The directive is likely to change name soon).
- For example wrapping:
- %javaconst(0);
- #define ABC 22
- %javaconst(1) XYZ;
- #define XYZ 33
- is now:
- public static readonly int ABC = examplePINVOKE.get_ABC();
- public const int XYZ = 33;
-
-04/03/2003: cheetah (William Fulton)
- [Java] Global constants and enums are put in their own interface called
- xxxConstants, where xxx is the module name. This is an improvement as
- it is possible to derive (implement) a Java class from the xxxConstants
- interface to improve the syntax; namely when wrapping:
- enum {ONE=1, TWO, THREE};
- accessing these from a Java class implementing xxxConstants is neater:
- int number = ONE;
- than the previous:
- int number = xxx.ONE;
-
- Patch submitted by Dave Dribin.
-
-04/02/2003: cheetah (William Fulton)
- Build improvements for multiple builds. This allows one to build
- the SWIG executable and runtime libraries for different platforms/compilers
- etc by running configure in different directories. This isn't 100% just
- yet and won't be until libtool is better configured... a 'configure' and
- 'make distclean' needs to be run in the root directory before it all works.
- For example:
- $ ./configure
- $ make distclean
- $ mkdir config1; cd config1; ../configure CC=gcc CXX=g++; make; cd ..
- $ mkdir config2; cd config2; ../configure CC=cc CXX=c++; make; cd ..
-
- To be improved. A 'make check' does not work yet either.
-
-04/01/2003: beazley
- Fixed template partial specialization argument expansion bug.
- This showed up when trying to use std_vector.i with vectors
- of pointers.
-
-03/31/2003: cheetah (William Fulton)
- Fix for parallel make builds of SWIG, for example
- make -j 4
- Build failure reported by Bill Clarke.
-
-03/28/2003: beazley
- Released 1.3.19.
-
-
-
-Version 1.3.19 (March 28, 2003)
-===============================
-
-03/28/2003: beazley
- Variety of minor bug fixes to the 1.3.18 release including:
-
- - Segmentation fault with %extend directive.
- - Typemap variable substitution bug.
- - Expression evaluation bug.
- - Large memory leak with template expansion.
-
-Version 1.3.18 (March 23, 2003)
-===============================
-
-03/21/2003: beazley
- Fixed two problems with the %extend directive, overloading, and
- template expansion. See the 'template_extend_overload' and
- 'template_extend_overload_2' tests in Examples/test-suite for
- details.
-
-03/20/2003: cheetah (William Fulton)
- [C#] Added some typemaps as suggested by Andreas Schoerk for handling
- parameters that are passed as pointers or by reference. These have
- been put in typemaps.i.
-
-03/20/2003: beazley
- Fixed a C++ scoping bug related to code like this:
-
- class Foo {
- public:
- int Foo::bar();
- };
-
- Previously, SWIG just tossed out the Foo::bar() declaration. Now,
- the declaration is wrapped provided that the prefix is exactly the
- same as the current scope (including any enclosing namespaces).
- Reported by Bruce Lowery.
-
-03/20/2003: beazley
- Incorporated [ 696516 ] Enabling exception processing for data member access.
- In some compilers, attribute access can generate exceptions. However,
- SWIG ordinarily assumes that no exceptions will be raised. To disable this,
- use the %feature("allowexcept"). For example:
-
- %feature("allowexcept") Foo::x;
- ...
- class Foo {
- public:
- int x; /* Exception handling enabled */
- ...
- };
-
- Patch contributed by Yakov Markovitch.
-
-03/20/2003: beazley
- Incorporated Patch. [ 701860 ] Improve Performance (python proxies).
- Gives a performance boost to proxy class code and the management of the
- .this and .thisown attributes. Contributed by Mike Romberg.
-
-03/19/2003: cheetah (William Fulton)
- [C# and Java] Added missing vararg support.
-
-03/18/2003: mrose (Mark Rose)
- Removed code related to tagging individual methods for directors.
- The concept of having directors for some but not all virtual methods
- of a class is deeply flawed. The %feature("nodirector") tag is also
- gone.
-
- Directors are off by default. To enable them for a class, issue
- %feature("director") classname; which will create director methods
- for every virtual method in the hierarchy of the class.
-
-03/17/2003: beazley
- Fixed a subtle problem with passing arguments of type function. For
- example:
-
- int foo(int x(int, int));
-
- or
-
- typedef int binop_t(int, int);
- int foo(binop_t x);
-
- In old versions, this would produce code that wouldn't compile. Now,
- SWIG merely adds an extra pointer, making these declarations the same
- as:
-
- int foo(int (*x)(int, int));
-
- typedef int binop_t(int, int);
- int foo(binop_t *x);
-
- Reported by Garth Bushell.
-
-03/17/2003: mrose (Mark Rose)
- Fixed the return statement for director base class calls that have no
- return value.
-
-03/15/2003: beazley
- Fixed a problem with const smart-pointer wrapping. For example:
-
- class Foo {
- public:
- int x;
- void bar() const;
- void spam();
- };
-
- class Blah {
- ...
- const Foo *operator->();
- ...
- };
-
- In this case, only "x" and "bar" are visible from Blah (since application
- of spam violates constness). Moreover, access to "x" is read-only.
-
-03/15/2003: mrose (Mark Rose)
- Cleaned up two signed versus unsigned comparisons in python/std_vector.i.
-
-03/15/2003: cheetah (William Fulton)
- [C#] Global variables are wrapped using properties instead of get and set methods.
- Member variable wrapping bug fixes, for example wrapping pointers work now.
- Typemaps are used for all variable wrapping to generate the property code.
-
-03/13/2003: mrose (Mark Rose)
- Fixed a bug in the virtual method unrolling for directors.
- The order of unrolling is now from base to derived, to ensure
- that the most derived implementation of a director method is
- found.
-
- Director methods for pure virtual methods now throw
- DIRECTOR_PURE_VIRTUAL_EXCEPTION if _up is set.
-
-03/12/2003: cheetah (William Fulton)
- [C#] Polymorphism fix: virtual functions now use the appropriate
- keyword in the C# proxy class, virtual or override.
- Some 'using System;' statement fixes needed by the Mono compiler.
-
-03/11/2003: beazley
- Fixed subtle bug in the application of SwigValueWrapper<> to
- template classes with default constructors. Reported by
- Bruce Lowery.
-
-03/11/2003: beazley
- The $descriptor(type) variable is now expanded in code supplied to
- %extend. This is useful for certain kinds of advanced wrapping
- (especially container classes).
-
-03/11/2003: luigi
- Support for std::map.
- (a) Integration with scripting language (a la std::vector) for
- Python, Ruby, MzScheme, and Guile;
- (b) Simple wrapper for other languages
-
-03/10/2003: beazley
- Fixed problem with escape sequences in string and character constants. SWIG
- wasn't parsing certain octal codes correctly.
-
-03/07/2003: beazley
- Fixed a variety of subtle preprocessor problems reported by
- Sebastien Recio.
-
- (a) Empty preprocessor values no longer generate "bad constant
- value" errors. For example:
-
- #define FOO
- #define FOO BAR
-
- (b) Macro names can now span multiple lines (technically valid,
- although questionable practice). For example:
-
- #define A_LONG_MACRO_\
- NAME 42
-
- (c) Whitespace is no longer required before certain macro values.
- For example:
-
- #define FOO"Hello"
- #define BAR\
- "Hello"
-
-03/07/2003: ljohnson (Lyle Johnson)
- [Ruby] Added missing long long and unsigned long long typemaps
- in the Lib/ruby/typemaps.i library file.
-
-03/07/2003: mrose (Mark Rose)
- Added Examples/python/callback to demostrate how directors can
- be used to implement callbacks in Python
- Added Examples/python/extend to demonstrate virtual method
- calls from C++ to Python (really the same as the callback
- example, just a different context).
- Added four tests for very basic director functionality. These
- have runtime tests under python.
- The Python module now emits #define SWIG_DIRECTORS near the
- top of the output file if directors are enabled. This is useful
- for disabling parts of tests in target languages that don't
- support directors.
-
-03/06/2003: mrose (Mark Rose)
- Added a section to Doc/Manual/Python.html on cross language
- polymorphism (directors).
-
-03/06/2003: mrose (Mark Rose)
- The short-lived "-fdirectors" command line option has been
- removed. To enable directors, instead use the extended %module
- directive as follows:
-
- %module(directors="1") modulename
-
-03/06/2003: cheetah (William Fulton)
- The long long typemaps have been rewritten so that they can be more
- easily used with non ISO compilers, like Visual C++. For example
- if you are wrapping the Windows 64 bit type __int64 the long long
- typemaps can be used with %apply:
-
- %apply long long { __int64 };
- __int64 value1(__int64 x);
-
- __int64 will now appear in the generated code instead of long long.
-
-03/06/2003: beazley
- *** DEVELOPER CHANGE ***
- Swig module mutation has been changed slightly. When a language
- class method wants to save node attributes, it now uses one of the
- following functions:
-
- Swig_require()
- Swig_save()
-
- The first argument to these functions is a namespace in which
- saved attributes are placed. For example,this code
-
- Node *n;
- Swig_save("cDeclaration",n,"type","parms","name",NIL);
-
- saves the attributes as "cDeclaration:type", "cDeclaration:parms",
- and so forth. If necessary, a language module can refer to
- old values by using this special namespace qualifier.
-
- In addition to this, a special attribute "view" contains the name
- of the last namespace used to save attributes. In the above
- example, "view" would have the value "cDeclaration". The value
- of "cDeclaration:view" would have the previous view and so forth.
-
- Swig_restore(n) restores a node to the state before the last
- Swig_require() or Swig_save() call.
-
- Note: This change makes it easier for language modules to refer
- to old values of attributes.
-
-
-03/06/2003: mrose (Mark Rose)
- Merged the cross-language polymorphism patch. When enabled, C++
- "proxy" classes (called directors) are generated for each specified
- C++ class. Directors pass method calls from C++ to Python, similar
- to the way the usual proxy (shadow) classes pass method calls from
- Python to C++. Together, these two types of proxies allow C++
- classes that are extended in Python to behave just like ordinary
- C++ classes and be used in C++ like native objects.
-
- This feature is still very experimental and is disabled by default.
- To enable director support, specify '-fdirectors' on the SWIG command
- line or in the SWIG_FEATURES environment variable. In the interface
- file, add %feature("director") to generate directors for all classes
- that have virtual methods.
-
- See http://stm.lbl.gov/~tm2/swig/ProxyDoc.html for more details.
-
-
-03/03/2003: beazley
- Fixed a small glitch in typemap local variable replacement. If you had
- a typemap like this:
-
- %typemap(in) type ($1_type temp) {
- ...
- temp = ...;
- ...
- }
-
- and no occurrence of "$1_type" appeared in the body, then the local
- variable type wouldn't be substituted.
-
-03/03/2003: cheetah (William Fulton)
- [C#] New version of the CSharp module which is typemap based.
- It also uses ECMA C# and no longer uses Microsoft Visual C++.NET
- glue. This means that it will work on non-Windows platforms.
- Contributed by Neil Cawse.
-
-02/27/2003: beazley
- Fixed [ 653548 ] error parsing casting operator definition.
- SWIG now ignores casting operators declared outside of a class.
- For example:
-
- inline A::operator char *() { ... }
-
- Bug reported by Martin Casado.
-
-02/27/2003: beazley
- Added support for anonymous bit-fields. For example:
-
- struct Foo {
- int x : 4;
- int : 4;
- int y : 8;
- };
-
- Anonymous bit-fields are ignored by SWIG. Problem
- reported by Franz Höpfinger.
-
-02/26/2003: cheetah (William Fulton)
- [Java] Better typemaps in the Examples/java/typemap example and also
- fixes subtle bug when using the StringBuffer typemaps more than once.
-
-02/26/2003: beazley
- Fixed [ 642112 ] Constants char bug.
-
-02/26/2003: beazley
- Fixed [ 675337 ] Partial template specialization not entirely working.
- There was a subtle problem related to the naming and ordering of
- template partial specialization arguments. Matching worked okay,
- the resulting templates weren't expanded correctly.
-
-02/25/2003: beazley
- Fixed problem with parsing (and generating code) for
- references to arrays. For example:
-
- int foo(int (&x)[10]);
-
-02/25/2003: beazley
- Fixed [ 635347 ] Compilation warning from libpy.c.
- Reported by Daniel L. Rall.
-
-02/25/2003: beazley
- Fixed a subtle problem with virtual method implementation
- checking and typedef.
-
- typedef int *intptr;
-
- struct A {
- virtual int *foo() = 0;
- };
- struct B : public A {
- virtual intptr foo() { };
- };
-
- SWIG was treating these declarations as different even though
- they are the same (via typedef).
-
-02/25/2003: ljohnson (Lyle Johnson)
- [Ruby] Added range checking for the NUM2USHRT macro, per [ 675353 ].
-
-02/24/2003: beazley
- Fixed a subtle problem with the code that determined if a class is abstract
- and can be instantiated. If you had classes like this:
-
- struct A {
- virtual int foo(int) = 0;
- };
- struct B : virtual A {
- virtual int foo(int);
- };
-
- struct C : virtual A {
- };
-
- /* Note order of base classes */
- struct D : B, C { }; /* Ok */
- struct E : C, B { }; /* Broken */
-
- then SWIG determined that it could instantiate D(), but not E().
- This inconsistency arose from the depth-first search of the
- inheritance hierarchy to locate the implementations of virtual
- methods. This problem should now be fixed---SWIG will attempt
- to locate any valid implementation of a virtual method by
- traversing over the entire hierarchy.
-
-02/22/2003: cheetah (William Fulton)
- [Java] Fix for using enum typemaps. The Java final static variable type
- can be set using the jstype typemap, enabling enums to be mapped to
- something other than int. Bug reported by Heiner Petith.
-
-02/21/2003: songyanf (Tiger)
- Added CSharp (C#) module prototype
- i.e. csharp.cxx & csharp.h at Source/Modules/.
- They are for test usage only now and need improvement.
- The interface also need to be modified.
-
- *** NEW FEATURE ***
-
-02/20/2003: songyanf (Tiger)
- Fixed problem with typedef with -fvirtual.
- Similar as beazley's modification today.
-
-02/20/2003: beazley
- Added support for gcc-style variadic preprocessor macros.
- Patch [ 623258 ] GCC-style vararg macro support.
- Contributed by Joe Mason.
-
-02/20/2003: beazley
- Fixed [ 605162 ] Typemap local variables.
- Reported by Lyle Johnson.
-
-02/20/2003: beazley
- Fixed problem with abstract classes and typedef. For example:
-
- class Foo {
- public:
- virtual void foo(int x) = 0;
- };
-
- typedef int Integer;
- class Bar : public Foo {
- public:
- virtual void foo(Integer x);
- };
-
- SWIG was getting confused about the latter method---making Bar
- abstract. Reported by Marcelo Matus.
-
-02/19/2003: cheetah (William Fulton)
- [Java] %javaconst(flag) can also be used on enums as well as constants.
- This feature enables true Java compiler constants so that they can be
- used in Java switch statements. Thanks to Heiner Petith for patches.
-
-02/19/2003: songyanf (Tiger)
- Modified -fcompact feature to deal with PP lines
-
-02/18/2003: beazley
- Fixed [ 689040 ] Missing return value in std_vector.i.
- Reported by Robert H. de Vries.
-
-02/18/2003: beazley
- Fixed a few evil scoping problems with templates, namespaces, and the
- %extend directive. Problem reported by Luigi Ballabio.
-
-
-02/18/2003: cheetah (William Fulton)
- [Ruby] Improved support for Visual C++ and other native Windows compilers.
- It is no longer necessary to specify "/EXPORT:Init_<module>", where <module> is the
- swig module name when linking using these native Windows compilers.
-
-02/15/2003: songyanf (Tiger)
- Added -fvirtual option.
- Reduce the lines and size of the wrapper file
- by omitting redifined virtual function in children classes.
-
- Modified -compact option to -fcompact option
-
- Added -small option.
- -small = -fvirtual -fcompact
- And it can be extended by future feature options,
- which are used to reduce wrapper file szie.
-
- Added SWIG_FEATURES environment variable check.
- To dynamically set the feature options such as -fcompact & -fvirtual
- *** NEW FEATURE ***
-
-02/13/2003: lenz
- Updated Doc/Manual/Perl5.html to talk about C++ compile problems
- configure.in now checks for PERL5_CCFLAGS
- Runtime/Makefile.in and Example/Makefile.in now use PERL5_CCFLAGS
- Added Lib/perl5/noembed.h which contains all the known macro conflicts
-
-02/12/2003: beazley
- Fixed [ 685410 ] C++ Explicit template instantiation causes SWIG to exit.
- Fixes a syntax error with declarations similar to this:
-
- template class std::vector<int>;
-
- SWIG now ignores the instantiation and generates a warning message.
- We might do more later. Reported by Thomas Williamson.
-
-02/11/2003: cheetah (William Fulton)
- Rewrote bool typemaps to remove performance warning for compiling generated code
- under Visual C++.
-
-02/11/2003: cheetah (William Fulton)
- Fix for wrapping reference variables (const non-primitive and all non-const types)
- for example:
- int& i;
- Class& c;
- const Class& c;
-
-02/11/2003: beazley
- Fixed more very subtle preprocessor corner cases related to recursive
- macro expansion. For example:
-
- #define cat(x,y) x ## y
-
- cat(cat(1,2),3) // Produces: cat(1,2)3
-
- #define xcat(x,y) cat(x,y)
-
- xcat(xcat(1,2),3) // Produces 123
-
- See K&R, 2nd Ed. p. 231.
-
-02/10/2003: cheetah (William Fulton)
- Fixed [ 683882 ] - patch submitted by F. Postma for SWIG to compile on HP-UX.
-
-02/10/2003: beazley
- Fixed subtle preprocessor argument expansion bug. Reported by Marcelo Matus.
-
-02/10/2003: songyanf
- Added -compact option.
- Reduce the lines and size of the wrapper file
- by omitting comments and combining short lines.
- *** NEW FEATURE ***
-
-02/07/2003: beazley
- Fixed [ 651355 ] Syntax error with cstring.i
- Reported by Omri Barel.
-
-02/07/2003: beazley
- Fixed [ 663632 ] incompatibility with standard cpp.
- This is a refinement that fixes this problem:
-
- // Some macro with an argument
- #define FOO(x) x
-
- int FOO; /* Not a macro---no arguments */
-
-02/05/2003: beazley
- Fixed [ 675491 ] parse error with global namespace qualification.
- Submitted by Jeremy Yallop.
-
-02/04/2003: beazley
- Fixed bug in varargs processing introduced by the numinputs typemap parameter.
-
-01/08/2003: ttn
- [xml] Fix string-replacement ordering buglet.
- Thanks to Gary Herron.
-
-12/23/2002: cheetah (William Fulton)
- Further build changes:
- - The SWIG executable is now built using a single Makefile.
- - This makefile is generated by Automake (Source/Makefile.am).
- - Dependency tracking and tags support are in this makefile.
- - Automake 1.7.2 and Autoconf 2.54 minimum versions are needed to build SWIG from CVS.
- - Running ./autogen.sh now installs Autoconf/Automake support files into
- Tools/config and these files are no longer stored in CVS.
- - Bug fixes in 'make install' for systems using .exe executable extension and
- ./configure --with-release-suffix=whatever
-
-12/16/2002: cheetah (William Fulton)
- More build changes:
- - Autoconf's AC_CANONICAL_HOST replaces proprietary approach for detecting build host.
- - Autoconf support files moved to Tools/config.
-
-12/16/2002: cheetah (William Fulton)
- Modifications to run on MacOS, submitted by Bernard Desgraupes.
- Mainly ensuring generated files are output in the appropriate directory for
- some modules.
-
-12/11/2002: cheetah (William Fulton)
- Various build modifications and bug fixes:
- - Simplification of version string. Use autoconf's PACKAGE_VERSION instead.
- - Build time removed from SWIG version.
- - Using standard autoconf config header generation.
- - Updated old autoconf macros as reported by autoupdate.
- - Removed $prefix in autoconf from search paths as autoconf won't expand them.
- - Subtle bug fix where 'make prefix=/somewhere; make clean; make prefix=/somwhere/else'
- produced an executable using the incorrect library directories.
- - Added -ldflags commandline option for MzScheme, Ocaml, Pike and PHP.
- - Fixed reporting of compiler used when using -version commandline option.
- - SWIG web address added to -version commandline option.
-
-12/11/2002: beazley
- Minor fix to Tcl dynamic cast typemaps. Reported by
- Kristopher Blom.
-
-12/10/2002: beazley
- Fixed subtle template argument replace bug. Reported by
- Chris Flatley.
-
-12/10/2002: beazley
- Reverted CHANGES 09/03/2002, preprocessor argument evaluation. Arguments
- are not evaluated during collection, K&R, p. 230.
-
-12/06/2002: beazley
- Fixed [ 649022 ] Compilation problems with KAI/KCC
-
-12/02/2002: beazley
- SWIG 'rel-1-3' CVS branch merged back into the main branch.
-
-
-Version 1.3.17 (November 22, 2002)
-==================================
-
-11/19/2002: beazley
- Fixed [ 613922 ] preprocessor errors with HAVE_LONG_LONG.
-
-11/19/2002: beazley
- Fixed [ 615480 ] mzscheme SWIG_MustGetPtr_.
-
-11/19/2002: beazley
- Fixed [ 635119 ] SWIG_croak causes compiler warning.
-
-11/16/2002: cheetah (William Fulton)
- [Java] Added typemaps for pointers to class members.
-
-11/15/2002: cheetah (William Fulton)
- [Java] Bug fix: Overloaded C++ functions which cannot be overloaded in Java
- once again issue a warning.
-
-11/14/2002: cheetah (William Fulton)
- [Java] Handling of NULL pointers is improved. A java null object will now
- be translated to and from a NULL C/C++ pointer by default. Previously when
- wrapping:
-
- class SomeClass {...};
- void foo(SomeClass *s);
-
- and it was called from Java with null:
-
- modulename.foo(null)
-
- a Java NullPointerException was thrown. Extra typemaps had to be written in
- order to obtain a NULL pointer to pass to functions like this one. Now the
- default wrapping will detect 'null' and translate it into a NULL pointer.
- Also if a function returns a NULL pointer, eg:
-
- SomeClass *bar() { return NULL; }
-
- Then this used to be wrapped with a SomeClass proxy class holding a NULL
- pointer. Now null is returned instead. These changes are subtle but useful.
- The original behaviour can be obtained by using the original typemaps:
-
- %typemap(javaout) SWIGTYPE {
- return new $&javaclassname($jnicall, true);
- }
- %typemap(javaout) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] {
- return new $javaclassname($jnicall, $owner);
- }
- %typemap(javagetcptr) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] %{
- protected static long getCPtr($javaclassname obj) {
- return obj.swigCPtr;
- }
- %}
-
- *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
-
-
-11/12/2002: beazley
- Fixed problem with abstract methods and signatures. For example:
-
- class abstract_foo {
- public:
- virtual int meth(int meth_param) = 0;
- };
-
-
- class abstract_bar : public abstract_foo {
- public:
- int meth(int meth_param_1, int meth_param_2) { return 0; }
- };
-
- In this case, abstract_bar is still abstract.
-
- Fixes [ 628438 ] Derived abstract class not abstract.
- Reported and patched by Scott Michel.
-
-11/11/2002: beazley
- Fixed a matching problem with typemaps and array dimensions. For example, if you
- had this:
-
- typedef char blah[20];
-
- and a typemap:
-
- %typemap() char [ANY] {
- ... $1_dim0 ...
- }
-
- then $1_dim* variables weren't be expanded properly. It should work now.
- Problem reported by Pankaj Kumar Goel.
-
-11/07/2002: mkoeppe
- Added an experimental new module that dumps SWIG's parse
- tree as (Common) Lisp s-expressions. The module is
- invoked with SWIG's -sexp command-line switch. The output
- can be read into Common Lisp. There is (prototype)
- example Lisp code that generates Foreign Function Interface
- definitions for use with Kevin Rosenberg's UFFI.
-
- *** EXPERIMENTAL NEW FEATURE ***
-
-11/07/2002: mkoeppe
- Removed duplicate declaration of "cpp_template_decl" in
- parser.y; bison 1.75 complained.
-
-11/06/2002: cheetah (William Fulton)
- [Java] Default primitive array handling has changed like arrays of classes.
- C primitive arrays are no longer wrapped by a Java array but with a pointer
- (type wrapper class). Again the changes have been made for efficiency reasons.
- The original typemaps have been moved into arrays_java.i, so the original
- behaviour can be obtained merely including this file:
-
- %include "arrays_java.i"
-
- The array support functions are no longer generated by default. They are only
- generated when including this file, thus this often unused code is only
- generated when specifically requiring this type of array support.
-
- *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
-
-11/05/2002: ljohnson (Lyle Johnson)
- [Ruby] Added support for nested module declarations (as was
- previously added for the Perl module). So a %module directive
- of the form:
-
- %module "Outer::Inner::Foo"
-
- will nest everything as (in Ruby code):
-
- module Outer
- module Inner
- module Foo
- # stuff goes here
- end
- end
- end
-
-11/05/2002: mkoeppe
- [MzScheme] Add an argument (-declaremodule) that generates
- code to correctly declare a primitive module extension.
- Patch submitted by Bruce Butterfield.
-
-11/02/2002: cheetah (William Fulton)
- [Java] Added patch submitted by Michael Cahill to remove unused parameter
- warnings for the jenv and cls parameters. This patch also also allows one
- to use "void" in the jni typemap for any type without code being generated
- attempting to return a value.
-
-10/29/2002: cheetah (William Fulton)
- [Java] Array handling is different. Arrays of classes are no longer wrapped
- with proxy arrays, eg wrapping
-
- class X {...};
- X foo[10];
-
- used to be wrapped with these Java getters and setters:
-
- public static void setFoo(X[] value) {...}
- public static X[] getFoo() {...}
-
- This approach is very inefficient as the entire array is copied numerous
- times on each invocation of the getter or setter. These arrays are now
- wrapped with a pointer so it is only possible to access the first array element
- using a proxy class:
-
- public static void setFoo(X value) {...}
- public static X getFoo() {...}
-
- Arrays of enums have also been similarly changed. This behaviour is now like the
- other SWIG language's implementation and the array library should be used to
- access the other elements. The original behaviour can be achieved using the
- macros and typemaps in arrays_java.i, for example:
-
- %include "arrays_java.i"
- JAVA_ARRAYSOFCLASSES(X)
- class X {...};
- X foo[10];
-
- *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
-
-10/29/2002: cheetah (William Fulton)
- [Java] Two new typemaps javain and javaout for generating the proxy class
- and type wrapper class method calls to the JNI class. The new typemaps are
- really used for transforming the jstype (used in proxy class and type wrapper
- classes) to the jtype (used in the JNI class) and visa versa. A javain typemap
- is required whenever an in typemap is written and similarly javaout for an out
- typemap. An example is probably best to show them working:
-
- %typemap(javain) Class "Class.getCPtr($javainput)"
- %typemap(javain) unsigned short "$javainput"
- %typemap(javaout) Class * {
- return new Class($jnicall, $owner);
- }
-
- %inline %{
- class Class {};
- Class * bar(Class cls, unsigned short ush) { return new Class(); };
- %}
-
- The generated proxy code is then:
-
- public static Class bar(Class cls, int ush) {
- return new Class(exampleJNI.bar(Class.getCPtr(cls), ush), false);
- }
-
-
- Some new special variables have been introduced in order to use these typemaps.
- Here $javainput has been replaced by 'cls' and 'ush'. $jnicall has been replaced by
- the native method call, 'exampleJNI.bar(...)' and $owner has been replaced by 'false'.
- $javainput is analogous to the $input special variable. It is replaced by the parameter name.
- $jnicall is analogous to $action in %exception. It is replaced by the call to the native
- method in the JNI class.
- $owner is replaced by either true if %newobject has been used otherwise false.
-
- The java.swg file contains default javain and javout typemaps which will produce the same code
- as previously. This change is only of concern to those who have written their own typemaps as
- you will then most likely have to write your own javain and javaout typemaps.
-
- The javaout typemap also makes it possible to use a Java downcast to be used on abstract
- proxy base classes. See the Java documentation on dynamic_cast.
-
- *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
-
-10/24/2002: ttn
- [Methodology] Upgaded to libtool 1.4.3, presumably w/ better
- support for newish platforms (like MacOS X).
-
-10/21/2002: ttn
- Fixed Runtime/Makefile.in bug -- thanks to Richard Calmbach.
-
-10/18/2002: ttn
- Fixed typo in doh.h -- thanks to Max Horn.
-
-Version 1.3.16 (October 14, 2002)
-=================================
-
-10/13/2002: beazley
- Fixed bug with %extend directive and %feature reported
- by William Fulton.
-
-10/13/2002: beazley
- Added OpenVMS build directory (vms). Contributed by
- Jean-François Pieronne.
-
-10/09/2002: cheetah (William Fulton)
- [Java] Added throws clause to the native functions in the JNI class.
- The throws clause is the same as the one generated for proxy functions
- and module class functions.
-
-09/27/2002: beazley
- Fixed some problems with the %import directive and classes that
- were defined but not wrapped. Problem reported by Leslie Brooks,
- Gerry Woods, and others.
-
-09/23/2002: cheetah (William Fulton)
- [Java] Some error checking added:
- 1) OutOfMemoryException check in the char * typemaps.
- 2) As SWIG treats pointers, references and passing by value all the
- same, it is possible to pass a NULL pointer to a function that expects
- an object passed by value or by reference. A NullPointerException is
- now thrown under this scenario.
-
-09/20/2002: ttn
- [Methodology] Reworked "make clean" and "make install"
- to be more table driven.
- [Docs] Explain how to extend "make install" w/ extra-install.list.
-
-09/15/2002: beazley
- Deprecation of the "ignore" typemap. The "ignore" typemap has
- been deprecated in favor of a generalization of the "in" typemap.
- To ignore an argument, use something like this instead:
-
- %typemap(in,numinputs=0) int *output (int temp) {
- $1 = &temp;
- }
-
- This change fixes a number of subtle bugs related to the interaction
- of the "in" and "ignore" typemaps (which were supposed to be
- mutually exclusive).
-
- The use of the numinputs argument is reserved for future expansion.
- Currently, values >1 will generate an error. However, future
- releases of SWIG may utilize that to support multi-input typemaps.
-
- %typemap(ignore) still works, but generates a warning message and is
- translated to %typemap(in,numinputs=0).
-
- *** POTENTIAL INCOMPATIBILITY ***
- *** NEW FEATURE ***
-
-09/15/2002: beazley
- Fixed segmentation fault for unnamed structures. For example:
-
- typedef struct {
- } *blah;
-
-
- Reported by Roger Gibson.
- Note: we might be able to generate wrappers in special cases.
-
-09/13/2002: beazley
- Minor modification to generated wrapper functions. Pointer arguments are now
- always set to an initial value of 0. Simplifies typemap writing and cleanup
- code (since you can rely on zero-value initialization). This also greatly
- reduces the need to ever write an "arginit" typemap.
-
-09/12/2002: beazley
- Minor enhancement to smart-pointer support. If operator->()
- is part of an ignored base class like this,
-
- %ignore Bar;
-
- class Foo {
- public:
- int blah();
- };
-
- class Bar { /* Ignored */
- public:
- ...
- Foo *operator->();
- ...
- };
-
- class Spam : public Bar { };
-
- then methods from Foo are still available. For example,
-
- >>> s = Spam()
- >>> s.blah()
- 0
- >>>
-
- The only catch is that the operator->() itself is not available
- (since it wasn't wrapped). Therefore, there won't be any
- __deref__() operation unless it is explicitly added to Spam
- (either using %extend or just placing operator->() in the
- definition of Spam).
-
-09/11/2002: ttn
- [Methodology] Reworked "make check" to be more table driven.
- [Docs] Docuemented methodology in Manual/Extending.html.
-
-09/11/2002: ttn
- [Docs] Prefixed Manual/*.html with "<!DOCTYPE html ...>" to
- pander dotingly to (over-)sensitive editors.
-
-09/10/2002: ttn
- [Guile] Converted Examples/guile/simple "make check"
- behavior to actually check execution results. Reduced
- iteration counts so that the test doesn't take too long.
-
-09/10/2002: beazley
- SWIG-1.3.15 released.
-
-
-Version 1.3.15 (September 9, 2002)
-==================================
-
-09/09/2002: beazley
- Fixed nasty runtime type checking bug with subtypes and inheritance
- and templates.
-
-09/09/2002: cheetah (William Fulton)
- [Java] Java exception classes for a method's throws clause can be generated by
- specifying them in a comma separated list in the throws attribute in any one
- of the following typemaps: in, out, check, freearg, argout and throws. A classic
- example would be to convert C++ exceptions into a standard Java exception:
-
- %typemap(throws, throws="java.io.IOException") file_exception {
- jclass excep = jenv->FindClass("java/io/IOException");
- if (excep)
- jenv->ThrowNew(excep, $1.what());
- return $null; // or use SWIG_fail
- }
-
- class file_exception {...};
- void open(const char *filename) throw(file_exception);
-
- The Java method will then be declared with a throws clause:
-
- public static void open(String filename) throws java.io.IOException {...}
-
-09/08/2002: mkoeppe
- * [Guile] Improved the documentation system. The arglist no
- longer gets cluttered with type specification, making it
- more readable. (Also the ILISP function C-u M-x
- `arglist-lisp' RET works better this way.) The types of
- arguments are explained in an extra sentence after the
- arglist.
-
- There are now two documentation-related typemap arguments:
-
- %typemap(in, doc="$NAME is a vector of integers",
- arglist="$name") int *VECTOR { ... }
-
- The "arglist" texts of all arguments of a function make up
- its arglist in the documentation. The "doc" texts of all
- arguments are collected to make a sentence that describes
- the types of the arguments. Reasonable defaults are
- provided.
-
- As usual, $name is substituted by the name of the
- argument. The new typemap variable $NAME is like $name,
- but marked-up as a variable. This means that it is
- upper-cased; in TeXinfo mode ("-procdocformat texinfo") it
- comes out as @var{name}.
-
- The directives %values_as_list, %values_as_vector,
- %multiple_values now also have an effect on the
- documentation. (This is achieved via the new pragmas
- return_nothing_doc, return_one_doc, return_multi_doc.)
-
- Documentation has also improved for variables that are
- wrapped as procedures-with-setters (command-line switch
- "-emit-setters").
-
- * [Guile] Emit constants as _immutable_ variables. (This
- was broken recently.)
-
-09/07/2002: mkoeppe
- [Guile] Updated the typemaps in list-vector.i.
-
-09/07/2002: mkoeppe
- Short-circuit the typechecks for overloaded functions.
- (The changes in code generation are visible in the new
- testcase "overload_complicated".)
-
-09/06/2002: cheetah (William Fulton)
- [Java] Solution for [ 596413 ]
- New typemap so that the Java proxy classes and type wrapper classes
- wrapper constructor modifier can be tailored by users. The default value is
- protected. Normally SWIG generates a constructor like this which can only
- be accessed within one package:
-
- protected Bar(long cPtr, boolean cMemoryOwn) {
- ...
- }
-
- If you are using SWIG across multiple packages or want to use this constructor
- anyway, it can now be accessed outside the package. To modify use for example:
-
- %typemap(javaptrconstructormodifiers) SWIGTYPE "public"
-
- to change to public for all proxy classes and similarly for all type wrapper classes:
-
- %typemap(javaptrconstructormodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "public"
-
-09/06/2002: cheetah (William Fulton)
- [Java] Added throws typemaps for the Java module. C++ exceptions get converted into
- java.lang.RuntimeException Java exceptions.
-
- Warning: This may change from java.lang.Runtime exception in the future.
-
-09/05/2002: cheetah (William Fulton)
- [Java] Fix for variables declared as references.
-
-09/05/2002: beazley
- Fixed [ 605162 ] Typemap local variables. Reported by Lyle Johnson.
-
-09/05/2002: ljohnson (Lyle Johnson)
- [Ruby] More updates to the Ruby module documentation, including
- a new typemap example that demonstrates how to collect key-value
- pairs from an argument list into a Hash.
-
-09/05/2002: beazley
- Fixed bug with template expansion and constructors.
-
- template<class T> class Foo {
- public:
- Foo<T>() { }
- };
-
- The extra <T> in the constructor was carried through in the
- name--causing runtime problems in generated modules.
- Reported by Jordi Arnabat Benedicto.
-
-09/05/2002: mkoeppe
- [Guile] Support overloading.
-
-09/04/2002: ljohnson (Lyle Johnson)
- [Ruby] Updated typemaps for long long and unsigned long long types
- to use Ruby 1.7 support for these types when available.
-
-09/04/2002: ljohnson (Lyle Johnson)
- [Ruby] Added output typemaps for const reference to primitive
- types.
-
-09/04/2002: mkoeppe
- [Guile] Fix pass-by-value typemaps. Reported by Arno
- Peters via Debian bugtracking (#156902), patch by Torsten
- Landschoff <torsten@debian.org>.
-
-09/03/2002: samjam (Sam Liddicott)
- Better reference support.
- Functions that want a void** can take a NULL by reference and
- the void* will be made for you and then passed-by-reference
-
- Also all integer-class native types can be passed by reference
- where an int* or int& etc is needed
-
-09/03/2002: beazley
- Changed the evaluation order of preprocessor macro arguments.
- Arguments are now expanded by the preprocessor *before* they
- are passed to macro expansion. This fixes a subtle expansion
- bug reported by Anthony Heading.
-
-09/03/2002: beazley
- Fixed the file include order (again, apparently). See 2/27/99.
-
-09/02/2002: beazley
- [Perl] Better exception handling support. Since Perl error handling
- relies on setjmp/longjmp, wrapper functions have been modified slightly
- to provide an extra block scope:
-
- XS(foo) {
- char _swigmsg[SWIG_MAX_ERRMSG] = "";
- const char *_swigerr = _swigmsg;
- {
- /* Normal wrapper function here */
- ...
- SWIG_croak("An error occurred\n");
- ...
- XSRETURN(argvi); /* Successful return */
- fail:
- /* cleanup code */
- }
- croak(_swig_err);
- }
-
- The macro SWIG_croak(x) sets the value of _swigerr to x and
- executes a "goto fail". The whole wrapper function is enclosed
- block scope to provide proper cleanup of C++ objects. Since
- croak executes a longjmp(), there is no way to properly reclaim
- resources if this executes in the same scope as the wrapper
- function.
-
- The _swigmsg[] variable is normally unused, but can be used
- to store small error messages using sprintf or snprintf. It
- has a capacity of at least 256 bytes (SWIG_MAX_ERRMSG).
-
-09/02/2002: beazley
- [Tcl] Added better support for exceptions. Instead of returning TCL_ERROR,
- use the macro SWIG_fail to return with an error. This ensures that
- arguments are properly cleaned up. Exception specifiers are now
- handled by default.
-
-09/02/2002: ljohnson (Lyle Johnson)
- [Ruby] The type-checking system for the Ruby module has had a flaw
- in that some types which should be considered equivalent
- weren't. This bug was best demonstrated by the inherit_missing.i
- test suite case, which defines a base class "Foo" that is
- subclassed by "Bar". The "Foo" class isn't actually wrapped (i.e.
- it's not directly accessible from Ruby) but we'd still like to be
- able to pass "Bar" instances to functions expecting Foos and have
- that work; it wasn't. The revised implementation (similar to that
- used for some other language modules) adds a new instance variable
- (__swigtype__) to each object that indicates its SWIG type;
- that is, each "Bar" instance will now have a string instance
- variable called "__swigtype__" whose value is "_p_Bar".
-
- Unless developers were taking advantage of this low-level
- implementation detail, they shouldn't notice any compatibility
- problems; nevertheless, I'm marking it as a "potential
- incompatibility".
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-09/01/2002: ljohnson (Lyle Johnson)
- [Ruby] Fixed SF Bug #603199.
-
-08/08/2002: cheetah (William Fulton)
- [Java] Added OUTPUT, INPUT and INOUT typemaps in typemaps.i for C++
- references.
-
-08/27/2002: mkoeppe
- [Guile] Fixed error in "lib_std_vector" testcase and
- compiler warning in "lib_cdata" testcase.
-
-08/27/2002: ljohnson (Lyle Johnson)
- [Ruby] Added the "%mixin" directive, which allows the user to
- specify a comma-separated list of module names to mix-in to a
- class. So, for example, if you'd like to specify that Ruby's
- Enumerable module should be mixed-in to your class Foo, you'd
- write:
-
- %mixin Foo "Enumerable";
-
- or to specify that the modules Fee, Fie and Fo should be mixed
- in to Foo:
-
- %mixin Foo "Fee,Fie,Fo";
-
- *** NEW FEATURE ***
-
-08/27/2002: ljohnson (Lyle Johnson)
- [Ruby] Modified the %alias directive so that multiple aliases
- can be specified for an instance method by using a comma-separated
- list of aliases.
-
-08/27/2002: ljohnson (Lyle Johnson)
- [Ruby] Added "throw" typemaps for the Ruby module.
-
-08/26/2002: beazley
- Two new command line options for printing dependencies.
- 'swig -M' lists all file dependencies. 'swig -MM' lists
- dependencies, but excludes files in the SWIG library.
- Example:
-
- % swig -M -python example.i
- example_wrap.cxx: \
- /u0/beazley/Projects/lib/swig1.3/swig.swg \
- /u0/beazley/Projects/lib/swig1.3/python/python.swg \
- example.i \
- example.h
-
- % swig -MM -python example.i
- example_wrap.cxx: \
- example.i \
- example.h
-
- *** NEW FEATURE ***
-
-08/26/2002: beazley
- Fixed [ 597599 ] union in class: incorrect scope.
- Reported by Art Yerkes.
-
-08/26/2002: beazley
- Fixed [ 600132 ] Default argument with namespace.
- Reported by Shibukawa Yoshiki.
-
-08/24/2002: beazley
- Automatic C++ exception handling enabled for all language modules. This is
- pretty simple. If you have a class like this:
-
- class Foo {
- };
- class Bar {
- public:
- void blah() throw(Foo);
- }
-
- then the generated wrapper code looks like this:
-
- wrap_Bar_blah() {
- ...
- try {
- arg1->blah();
- }
- catch (Foo &_e) {
- /* "throw" typemap code inserted. $1 = _e */
- }
- catch (...) {
- throw;
- }
- }
- The "throw" typemap can be used to raise an error in the target
- language. It can do anything. Here is a very simple example:
-
- %typemap("throw") Foo {
- PyErr_SetString(PyExc_RuntimeError, "Foo exception");
- return NULL;
- }
-
- To make this work in each language module, simply define a few default
- "throw" typemaps for SWIGTYPE, SWIGTYPE *, int, const char *, and a
- few common exception types. That's all there is to it.
-
- Automatic exception handling can be disabled using -noexcept or
- setting the NoExcept global variable to 1.
- *** NEW FEATURE ***
-
-08/23/2002: beazley
- [ Python ]
- Automatic translation of C++ exception specifications into error handling code.
- For example:
-
- class Foo {
- };
- class Bar {
- public:
- void blah() throw(Foo);
- }
-
- In this case, Foo is wrapped as a classic-style class (compatible
- with exception handling). Furthermore, you can write Python code
- like this:
-
- b = Bar()
- try:
- b.blah();
- except Foo,e: # Note use of exception class here!
- # Handle Foo error
- ...
-
- The object "e" in the exception handler is just a wrapped Foo
- object. Access it like a normal object.
-
- If an exception is not wrapped as a class, a RuntimeError
- exception is raised. The argument to this exception is
- the exception object. For example:
-
- class Bar {
- public:
- void blah() throw(int);
- }
-
- b = Bar()
- try:
- b.blah();
- except RuntimeError,e:
- print e.args[0] # Integer exception value
-
- Comments:
-
- - If a class is used as an exception, it *must* be wrapped
- as a Python classic-style class (new classes don't work).
-
- - Automatic exception handling is compatible with %exception.
-
- - Use -noexcept to turn off this feature.
-
- - The newly introduced "throw" typemap is used to raise
- Python errors (naturally).
-
- *** EXPERIMENTAL NEW FEATURE ***
-
-08/23/2002: beazley
- Information from throw() specifiers is now stored in the parse
- tree. For example:
-
- class Foo {
- public:
- int blah() throw(spam,bar);
- }
-
- The stored information is fully corrected for namespaces and works
- with templates. Uses will follow.
-
-08/22/2002: beazley
- Exception handling code is no longer applied to member access
- function. For example, in this code
-
- %exception {
- try {
- $action
- } catch(whatever) {
- ...
- }
- }
-
- class Foo {
- public:
- int x;
- ...
- }
-
- The exception handling code is not applied to accessor functions
- for Foo::x. This should reduce the amount of extra code
- generated.
-
- Caveat: Exception handling code *is* used when attributes are
- accessed through a smart-pointer or a synthesized attributed
- added with %extend is used.
-
-08/22/2002: beazley
- Made more patches to hopefully eliminate problems when compiling SWIG
- as a 64-bit executable.
-
-08/22/2002: beazley
- Fixed a bug with const reference members, variables, and static members.
- For example:
-
- class Foo {
- public:
- static const int &ref;
- };
-
- SWIG was trying to generate "set" functions which wouldn't compile.
-
-08/21/2002: beazley
- Made the warning message for "Class X might abstract" off by default.
- Enable with -Wall.
-
-08/21/2002: beazley
- Refined handling of const and non-const overloaded methods. If
- a class defines a method like this:
-
- class Foo {
- public:
- int bar(int);
- int bar(int) const;
- }
-
- Then the non-const method is *always* selected in overloading and
- the const method silently discarded. If running with -Wall, a warning
- message will be generated.
-
-08/19/2002: beazley
- Better support for using declarations and inheritance. Consider this:
-
- class Foo {
- public:
- int blah(int x);
- };
-
- class Bar {
- public:
- double blah(double x);
- };
-
- class FooBar : public Foo, public Bar {
- public:
- char *blah(char *x);
- using Foo::blah;
- using Bar::blah;
- };
-
- Now SWIG wraps FooBar::blah as an overloaded method that uses all
- accessible versions of blah(). See section 15.2.2 in Stroustrup, 3rd Ed.
-
- SWIG also supports access change through using declarations. For example:
-
- class Foo {
- protected:
- int x;
- int blah(int x);
- };
-
- class Bar : public Foo {
- public:
- using Foo::x;
- using Foo::blah;
- };
-
-
- Caveat: SWIG does not actually check to see if declarations imported
- via 'using' are in the inheritance hierarchy. If this occurs, the
- wrapper code won't compile anyways---not sure it's worth worrying about.
-
-08/18/2002: beazley
- Modified overloading dispatch to not include nodes with an "error" attribute.
- A language module can set this if a node couldn't be wrapped and you don't want
- it included in the dispatch function.
-
-08/18/2002: beazley
- Enhancement to overloaded function dispatch. The dispatcher is now aware of
- inheritance relationships. For example:
-
- class Foo { };
- class Bar : public Foo { };
-
- void spam(Foo *f);
- void spam(Bar *b);
-
- In this case, the dispatcher re-orders the functions so that spam(Bar *b) is
- checked first---it is more specific than spam(Foo *f).
-
-08/17/2002: beazley
- Added -Werror command line option. If supplied, warning messages are treated
- as errors and SWIG will return a non-zero exit code.
-
-08/17/2002: beazley
- Fixed [ 596135 ] Typedef of reference can't compile. For example:
-
- typedef int &IntRef;
- void foo(IntRef i);
-
- SWIG-1.3.14 generated code that wouldn't compile.
-
-Version 1.3.14 (August 12, 2002)
-================================
-
-08/11/2002: mmatus
- Static const members initialized during declaration, and
- only them, ie:
-
- struct A
- {
- static const int a = 1 ; // this one
- static const int b; // not this one
- };
-
- are emitted like constants (equivalent to enums or
- explicit %constant).
-
- This is because they cannot be added directly to 'cvar'
- since they lack the needed reference (well, you can force
- them to have a real reference, but in an ugly way which
- goes completely again the original purpose of initialize
- them during declaration, you also have to deal with extra
- linking matters, and it take a while to figure out what is
- the problem and how to solve it).
-
- Please test it with your preferred target language, and
- not only the code generation, but really run the example
- in the test-suite (static-const-member-2.i) because the
- problem and the solution cannot be "fully" appreciated
- until you try to load the module and run it.
-
- In some target languages (python specially), this can
- produces a difference in the way that the static constant
- members 'a' and 'b' are internally wrapped. Hopefully,
- they still can be accessed in the same way.
-
-
-08/11/2002: mmatus
- [python] Now static const members can be accessed in a more
- natural way, ie, if you have
-
- struct A
- {
- typedef unsigned int viewflags;
- static const viewflags forward_field = 0;
- static const viewflags backward_field;
- };
-
- now you can do:
-
- print A.backward_field
-
- and also
-
- a = A()
- print a.forward_field
-
- Note that if the static const members don't have an
- initializer (like backward_field), still you can access
- them in the same way in the python side, but the
- implementation is a quite different: backward_field will
- still appear in the cvar entity, and also, you are
- responsible to initialize it in some code unit, and link it
- properly. forward_field, by the other hand, will not
- appear in the cvar entity but only as a A member, similar
- to what happen with enum or %constant members.
-
-08/11/2002: mmatus
- [python] Common code in the __setattr__/__getattr__ now
- goes to two "free" methods at the beginning of the proxy
- file, from where each class use it. This change reduces
- the size of the proxy file, specially if you wrap a lot of
- small classes in one module (up to 33% in some cases),
- making it faster to load too.
-
-08/09/2002: beazley
- [Perl5] If a function that returns char * returns NULL,
- undef is returned to the Perl interpreter.
-
-08/09/2002: beazley
- Fix to conversion operators and namespaces. For example:
-
- namespace ns {
- struct Foo { };
- struct Bar {
- operator Foo*();
- };
- }
-
- In the wrapper code, SWIG was using ->operator Foo*()
- when it should have been using ->operator ns::Foo*().
-
- Note: if using %rename with a conversion operator, you
- might have to do this:
-
- %rename(toFooPtr) ns::operator ns::Foo*();
- // ^^^^ note extra qualifier
- namespace ns {
- ...
-
-
-08/09/2002: beazley
- [Python] Minor enhancement to 'const' variable declarations.
- Normally const declarations are wrapped as read-only variables
- accessible only through the cvar attribute (see SWIG.html for
- a discussion of why). However, in many programs, "const"
- declarations may just be constants---making the cvar. access
- awkward. To fix this, "const" declarations are now available
- both through cvar. and as a simple name. For example:
-
- const int FOO = 42;
-
- In Python:
-
- >>> print example.cvar.FOO
- 42
- >>> print example.FOO
- 42
-
- Note: There are cases where the value of a "const" variable
- might change. For example:
-
- char *const BAR = "Hello World";
-
- In this case, the pointer itself can not change, but the
- data being pointed to could be modified. In these situations,
- cvar.BAR should be accessed to obtained the current value.
-
-08/08/2002: beazley
- [Python] Fixed generation of the proxy code (.py files) to more
- closely follow the order of declarations as they appear in
- the .i file. In the past, all of the class wrappers appeared
- first, followed by function stubs, inserted Python code, and
- other details.
-
-08/08/2002: cheetah (William Fulton)
- [Java] Proxy method _delete() changed to delete(). There shouldn't ever
- be a wrapped function called delete() as it is a C++ keyword and there
- is no such thing as a member function in C.
-
- *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
-
- Backwards compatibility can be achieved by adding the function back in
- for all proxy classes:
- %typemap(javacode) SWIGTYPE %{
- public void _delete() {
- delete();
- }
- %}
-
- Java backwards compatibility summary
- ------------------------------------
-
- There are a number of changes that have been made in improving the Java module
- for ver 1.3.14. If at all possible change your code to take advantages of the
- improvements. If you were using proxy classes you may not notice any backwards
- compatibility issues. Here is an example which will help with most backwards
- compatibility problems where it is not possible to modify the code that uses
- the generated output:
-
- Replace:
- %module modulename
-
- With:
- %module (jniclassname="modulename") modulename;
- %typemap(javacode) SWIGTYPE %{
- public long getCPtr$javaclassname() {
- return swigCPtr;
- }
- public void _delete() {
- delete();
- }
- %}
- %pragma(java) jniclassclassmodifiers="public";
-
- The proxy constructors that took parameters (long cPtr, boolean cMemoryOwn)
- were public and are now protected. If you were making use of these then you'll
- have to modify your code and the best solution would be to use the new type
- wrapper classes.
-
- The other main areas are the pragmas and global variable wrapping. Replace
- the pragmas with one of the new directives or typemaps mentioned below and use
- %rename on the variables.
-
- If you were not using proxy classes, you will have to define a jstype typemap
- as well as a jtype typemap.
-
-08/08/2002: cheetah (William Fulton)
- [Java] Fix for wrapping two dimension array variables.
-
-08/07/2002: beazley
- [Python,Tcl]
- Object management now has a much better sense of ownership.
- Ownership bits is changed whenever an object is stored in a
- global variable or structure member. For example:
-
- struct Foo {
- int val;
- Foo *next;
- };
-
- Now in Python
-
- >>> f = Foo()
- >>> f.thisown
- 1
- >>> g = Foo()
- >>> g.next = f # Assign a pointer
- >>> f.thisown # Notice ownership change
- 0
- >>>
-
- This scheme is mostly a conservative heuristic designed to
- provide segmentation faults. It could cause a memory leak
- if ownership is changed unnecessarily. In this case, you can
- either write a typemap (that doesn't change ownership), or
- manually set the thisown attribute back to 1.
-
-08/07/2002: beazley
- [Tcl] Major usability improvements to the object interface.
- Suppose you had code like this:
-
- struct Foo {
- int x;
- int spam();
- };
-
- void blah(Foo *f);
-
- In past versions of SWIG, you could create objects and use
- them like this:
-
- % Foo f
- % f configure -x 3
- % f spam
- 37
-
- The only problem is that if you tried to call blah(), it didn't
- work:
-
- % blah f
- Type Error. Expected _p_Foo
- %
-
- Instead, you had to do this:
-
- % blah [f cget -this]
-
- SWIG now automatically extracts the -this pointer, avoiding this
- problem. This means that saying "blah f" is perfectly legal and
- everything will still work normally.
-
- Caveat: Since pointer strings start with a leading underscore (_),
- don't use this in object names. For example:
-
- % Foo _f
- % blah _f # Potential crash
-
- Objects now have a -thisown attribute that shows the ownership.
- This builds upon the CHANGES 11/24/2001 entry.
-
-08/07/2002: samjam, Sam Liddicott
- Properly implemented pointer system using php resources.
- Still need to work out whether or not to let script-users call
- destructors directly
-
-08/06/2002: beazley
- Upgraded mzscheme module to support version 201 and added
- overloading support.
-
-08/05/2002: beazley
- Added parsing support for extra grouping (in very limited cases).
- For example:
-
- typedef int (FuncPtr)(int, double);
-
- *** EXPERIMENTAL ***
-
-08/03/2002: ljohnson (Lyle Johnson)
- [Ruby] Updates to typemaps.i as those done previously for Perl,
- Python and Tcl modules. Now supports reference types with INPUT,
- OUTPUT and INOUT typemaps.
-
-08/02/2002: beazley
- New library file cstring.i added. Provides macros for
- manipulating char * data.
-
-08/02/2002: beazley
- Deprecated the %new directive. Use %newobject instead. For
- example:
-
- %newobject foo;
- ...
- char *foo();
-
- %newobject follows the same rules as %rename, %ignore, %feature,
- etc.
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-08/01/2002: cheetah (William Fulton)
- [Java] New attribute 'jniclassname' for the module directive allows a way of
- changing the JNI class name from the default which uses the modulename with JNI
- appended after it.
-
- %module (jniclassname="name") modulename
-
- If 'name' is the same as 'modulename' then the module class name gets changed
- from 'modulename' to modulenameModule.
-
-08/01/2002: beazley
- Fixed problem with file include order. Language specific
- directories should take precedence over generic directories.
- For example: "swig_lib/python/foo.i" should be loaded before
- "swig_lib/foo.i". I thought this was the case already, but
- apparently it has been broken for quite some time.
-
-08/01/2002: beazley
- Added std_deque.i library file. Work in progress.
-
-08/01/2002: beazley
- [Python,Tcl,Perl]
- Improvements to typemaps.i. INPUT/INOUT typemaps perform better
- error checking. Typemaps are now supplied for references like
- int &OUTPUT, double &INOUT, etc.
-
-08/01/2002: beazley
- [Python] Deprecated the T_* and L_* typemaps in typemaps.i.
- Multiple return values are always placed in a tuple. Deprecated
- the BOTH typemaps. This is now INOUT (e.g., int *INOUT).
-
- *** POTENTIAL INCOMPATIBILITY FOR PYTHON MODULE ***
-
-08/01/2002: beazley
- Deprecated the array.i, carray.i, and timer.i library files.
-
-08/01/2002: beazley
- Deprecated the pointer.i library file. Use cpointer.i instead.
- *** POTENTIAL INCOMPATIBILITY ***
-
-08/01/2002: cheetah (William Fulton)
- [Java] For consistency the global variable getters and setters use the JavaBean
- property design pattern like member variables always have. This means if you are
- wrapping a variable called foo, the getter is called getFoo() and the setter is
- called setFoo(). Before the recent changes to the Java module the getters and
- setters were called get_foo() and set_foo(). If you really want the original
- function names use the %rename directive like this: %rename(_foo) Foo;
-
-07/31/2002: beazley
- Fixed casting problem with multiple inheritance. If you had this,
-
- class foo {};
- class bar : public foo {};
- class baz : public foo {};
- class spam : public bar, public baz {};
-
- then the wrappers wouldn't compile due to an ambiguous cast.
- Reported by Art Yerkes.
-
-07/30/2002: cheetah (William Fulton)
- [Java] Due to new static typechecking all pointers held in a Java long are part of
- the internal workings and this pointer value in the Java long has become abstracted
- data. The type wrapper constructor and getCPtr() methods are as such protected.
- If you need to mess around with pointers from Java or for example create a proxy
- class or type wrapper class around a null pointer, add a function/constructor
- to do so with the %javacode typemap. You can also make getCPtr() public again with
- the %javagetcptr typemap.
-
-07/30/2002: cheetah (William Fulton)
- [Java] Fixes for %typemap(ignore). In particular when ignoring the last parameter
- in a function. Also for all parameters in constructors. These mods have also fixed
- multi-argument typemaps for proxy classes - SF 581791.
-
-07/30/2002: cheetah (William Fulton)
- [Java] %newobject (replacement for %new) now implemented for Java.
-
-07/29/2002: beazley
- Fixed problem with typemap copies, %apply, and %clear inside
- C++ namespaces.
-
-07/28/2002: cheetah (William Fulton)
- [Java] The JNI class now has package access as the class modifier
- has been changed from "public" to nothing. This has been done
- as this class is now more for the internal workings of SWIG since the module
- class has static type checking for all types.
-
- *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
-
- Backwards compatibility can be achieved by using the %jniclassclassmodifier
- pragma to change it back to "public".
-
-07/28/2002: cheetah (William Fulton)
- [Java] Proxy/Shadow classes are generated by default. The -proxy and
- -shadow command line options are deprecated. If you want to use the
- low-level functional interface then use the new -noproxy commandline option.
-
- *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
-
-07/28/2002: cheetah (William Fulton)
- [Java] Remaining pragmas shakeup. These were the remaining pragmas and their
- new names where changed:
-
- modulebase
- modulecode
- moduleclassmodifiers
- moduleimport => moduleimports
- moduleinterface => moduleinterfaces
-
- The moduleimports works slightly differently to how the moduleimport pragma worked.
- Now it actually takes code which gets placed before the class definition so the
- whole import statement has to be given, for example:
-
- %pragma(java) moduleimports=%{
- import java.io.*;
- import java.math.*;
- %}
-
- The moduleinterfaces is slightly different to the old moduleinterface in that if
- more than one interface is required they must be comma separated in one use of
- the pragma, for example:
-
- %pragma(java) moduleinterfaces="Serializable, MyInterface"
-
- These last two pragmas are consistent with the javainterfaces and javaimports
- typemap.
-
- A similar set of pragmas has been introduced, namely:
-
- jniclassbase
- jniclasscode
- jniclassclassmodifiers
- jniclassimport
- jniclassinterface
-
- These work in the same way as their module counterparts. Note that previously
- the moduleXXX pragmas worked on the old module class which is now called the
- JNI class (the class with the native functions). The jniclassXXX pragmas now
- work on the new module class (the class that has all the global functions and
- global variable getters and setters when using proxy classes, plus all other
- remaining functions when using the low-level procedural interface).
-
- In summary the contents of the pragmas make up a class like this:
-
- <jniclassimports>
- <jniclassmodifiers> class modulename extends <jniclassbase> implements <jniclassinterfaces> {
- <jniclasscode>
- ... SWIG generated functions ...
- }
-}
- *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
-
-07/28/2002: cheetah (William Fulton)
- [Java] Deprecated modulemethodmodifiers pragma and replaced with
- a better %feature based directive called %javamethodmodifiers.
- A useful example would be for synchronisation in multi-threaded apps:
-
- %javamethodmodifiers foo(int a) "public synchronized";
-
- Changes this function from the default ("public") to "public synchronized".
-
- *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
-
-07/26/2002: beazley
- Several directives now allow optional configuration parameters.
- These include:
-
- %module(name="value", name="value", ...) modulename
- %import(name="value", ...) "filename.i"
- %extend(name="value", ...) classname {
- ...
- }
-
- These currently have no effect and are reserved for
- future expansion.
-
-07/26/2002: beazley
- Enhancements to smart-pointer handling. SWIG only provides
- extra support for a smart-pointer if operator->() returns
- a proper pointer. For example:
-
- Foo *operator->();
-
- If operator->() returns an object by value or reference,
- then SWIG examines the returned object to see if it also
- implements operator->(). If so, SWIG chases operator->()
- until it can find one that returns a pointer. This allows
- cases like this to work:
-
- class Foo {
- public:
- void blah();
- };
-
- class Bar {
- ...
- Foo *operator->();
- ...
- };
-
- class Spam {
- ...
- Bar operator->();
- ...
- };
-
- For example:
-
- >>> s = Spam()
- >>> s.blah() # Invokes Foo::blah()
-
- The s.blah() call actually invokes:
-
- ((s.operator->()).operator->())->blah();
-
-07/26/2002: beazley
- Fixed a bug with typedef and references. For example:
-
- typedef Foo & FooRef;
- FooRef blah();
-
- Previous versions of SWIG generated code that wouldn't
- compile.
-
-07/25/2002: beazley
- Wrapping of static methods has been improved in proxy classes. In older
- versions of SWIG, if you had this:
-
- class Foo {
- public:
- static void bar();
- };
-
- The static method was only available as a function Foo_bar(). For example:
-
- >>> Foo_bar()
-
- Now, the static method can also be invoked through an instance like this:
-
- >>> f = Foo()
- >>> f.bar() # Invokes static method
-
- This works with all versions of Python. Additionally, for Python-2.2,
- the static method can be invoked as:
-
- >>> Foo.bar()
-
- The old-style function is still support for backwards compatibility. If
- you care about making your code across different versions of Python,
- either use Foo_bar() or access the method through an instance.
-
-07/25/2002: beazley
- Changes to the Python module. Proxy classes now utilize new Python-2.2
- features including properties and static methods. However, these features
- are supported in a way that provides backwards compatibility with older
- Python versions. In other words, proxy classes work with all versions
- of Python and only use new features when running on Python-2.2.
-
-
-07/25/2002: beazley
- Modified %extend so that overloaded methods can be added. For example:
-
- %extend Foo {
- void bar(int x) { };
- void bar(char *s) { };
- ...
- }
-
- This works with both C++ *and* C.
-
-07/24/2002: cheetah (William Fulton)
- [Java] More new typemaps so that the Java proxy classes and type wrapper classes
- can be further tailored by users. These are the default code for generating the
- finalize() methods (proxy classes only) and the getCPtr() methods for proxy
- classes and type wrapper classes:
-
- %typemap(javafinalize) SWIGTYPE %{
- protected void finalize() {
- _delete();
- }
- %}
-
- %typemap(javagetcptr) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] %{
- public static long getCPtr($javaclassname obj) {
- return obj.swigCPtr;
- }
- %}
-
- The javagetcptr typemap will enable users to handle Java null by overriding
- this typemap - a requested feature.
-
- The -nofinalize commandline option has been deprecated. The javafinalize
- typemap is more powerful as it will allow the removal of the finalize methods
- for all or any one or more particular proxy class.
-
-07/23/2002: cheetah (William Fulton)
- [Java] The getCPtrXXX() function has been changed to a static function and
- is now of the form:
-
- protected static long getCPtr(XXX obj) {...}
-
- This is a requested change which will allow Java null pointers to be used as null
- can be passed in for obj. However, to achieve this the appropriate code must be
- written using the new javagetcptr typemap directive.
-
- *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
-
- Backwards compatibility can be achieved by adding this function back in using the
- new javacode typemap:
-
- %typemap(javacode) SWIGTYPE %{
-
- // SWIG-1.3.12 and SWIG-1.3.13
- public long getCPtr$javaclassname() {
- return swigCPtr;
- }
- // SWIG-1.3.11 and earlier
- public long getCPtr() {
- return swigCPtr;
- }
-
- %}
-
-
-07/23/2002: cheetah (William Fulton)
- [Java] New directive to control constant code generation - %javaconst.
- The default handling for handling constants is to get the value through
- a JNI call, eg
-
- #define YELLOW 5
- #define BIG 1234LL
-
- results in:
-
- public final static int YELLOW = modulename.get_YELLOW();
- public final static long BIG = modulename.get_BIG();
-
- Earlier versions of the Java module initialised the value using the C value:
-
- public final static int YELLOW = 5;
- public final static long BIG = 1234LL;
-
- This works in most cases, but the value for BIG won't compile as 1234LL is not
- valid Java code and this is one of the reasons why the default is now to get the
- values through a JNI call. The side effect is that these 'constants' cannot be used
- in switch statements. The %javaconst directive allows one to specify the
- way the constant value is initialised and works like other %feature
- directives, eg
-
- %javaconst(0); // all constants from this point on are initialised using the C value
- %javaconst(1) BIG; // just BIG initialised using JNI call (must be parsed before BIG is defined)
-
-07/23/2002: beazley
- *** IMPORTANT CHANGES TO THE PYTHON MODULE ***
-
- (1) The Python module now enables shadow/proxy classes by default.
- This means that two files are always created by SWIG. For
- instance, if you have this:
-
- // file: foo.i
- %module foo
- ...
-
- Then swig generates two files "foo_wrap.c" and "foo.py".
-
- (2) The name of the low-level C extension module has been changed
- to start with a leading underscore. This means that you have
- to compile the module as follows:
-
- $ cc -c -I/usr/local/include/python2.2 foo_wrap.c
- $ cc -shared foo_wrap.o $(OBJS) -o _foo.so
- ^^^^
- note extra underscore
-
- This naming scheme is consistent with other Python modules that
- utilize extension code. For instance, the socket module consists
- of "_socket.so" and "socket.py". In previous versions of SWIG,
- the shared object file was named "foocmodule.so".
-
- (3) A new directive can be used to insert Python code into
- the corresponding .py file. For example:
-
- %pythoncode %{
- def foo():
- print "Hello World"
- %}
-
- This directive allows you to create modules as a mix of C and Python.
- Python code is seamlessly added to the module.
-
- (4) The -shadow command line option is deprecated. This is turned on
- by default.
-
- (5) To disable the generation of the extra python file, use the "-noproxy"
- command line option.
-
- *** POTENTIAL INCOMPATIBILITY ***
- This change will likely break the build environment of projects that
- utilize shadow classes. To fix this, you probably only need to
- change the name of the target .so file. For example, if you have
- Makefile information like this:
-
- TARGET = examplecmodule.so
-
- Just change it to:
-
- TARGET = _example.so
-
- *** DOCUMENTATION UPDATE ***
- The file Doc/Manual/Python.html has been updated to describe these changes.
-
-
-07/23/2002: beazley
- Added -noextern option. If supplied, SWIG will not generate
- extra extern declarations. This is sometimes an issue on
- non-unix platforms.
-
-07/23/2002: beazley
- Added a warning for ignored friend functions.
-
-07/23/2002: beazley
- Fixed [ 574498 ] -proxy and %include "pointer.i" clash.
- Reported by David Creasy.
-
-07/23/2002: beazley
- Fixed [ 576103 ] global destruction warning with shadow.
- Perl extensions should no longer report the warning
-
- "Use of uninitialized value during global destruction."
-
- when running with "perl -w". Reported by
- Brett Williams.
-
-07/23/2002: beazley
- In C++ mode, SWIG now always defines namespace std. By default,
- it's empty. However, this will silence errors from programs
- that include statements such as "using namespace std;".
- This fixes Bug [ 584017 ] using namespace std generates error.
- Reported by Joseph Winston.
-
-07/22/2002: beazley
- Added a new warning message for %apply. If you use %apply but no typemaps
- are defined, you will get a warning message. This should help with
- problems like this:
-
- %apply char *OUTPUT { ... };
-
- In old versions of SWIG, this silently did nothing. Now you get an error like this:
-
- file:line. Warning. Can't apply (char *OUTPUT). No typemaps are defined.
-
-07/22/2002: cheetah (William Fulton)
- [Java] Started Java pragma deprecation. Replacements use %typemap based
- directives and enable proxy classes and the new type wrapper classes to be
- tailored in various ways. These are the new typemaps:
-
- %typemap(javabase) - base (extends) for Java class
- %typemap(javaclassmodifiers) - class modifiers for the Java class: default is "public"
- %typemap(javacode) - java code is copied verbatim to the Java class
- %typemap(javaimports) - import statements for Java class
- %typemap(javainterfaces) - interfaces (extends) for Java class
-
- And these are the %pragma directives being deprecated:
- allshadowbase
- allshadowclassmodifiers
- allshadowcode
- allshadowimport
- allshadowinterface
- shadowbase
- shadowclassmodifiers
- shadowcode
- shadowimport
- shadowinterface
-
- Note that it is possible to target a particular proxy class:
- %typemap(javaimports) Foo "import java.util.*"
- or a particular type wrapper class:
- %typemap(javaimports) double* "import java.math.*"
- Note that $javaclassname in these typemaps are substituted with either the proxy
- classname when using proxy classes or the SWIGTYPE class name.
-
-07/18/2002: cheetah (William Fulton)
- [Java] Java module overhaul to implement static type checking of all
- types.
-
- 1) Changes when using Java Proxy classes
- ----------------------------------------
-
- Previously when wrapping global functions:
-
- class SomeClass{};
- void foo(SomeClass* s);
- SomeClass* bar();
-
- The native method prototypes used a long for pointers and looked like this:
-
- public class modulename {
- ...
- public final static native void foo(long jarg1);
- public final static native long bar();
- }
-
- and unlike member functions of a C++ class there was no wrapper around the native calls
- to make the use of them more user friendly. They would be used from Java like this:
-
- SomeClass s = new SomeClass(modulename.bar(), false);
- modulename.foo(s.getCPtrSomeClass());
-
- Note that the following will have the same effect, but then it would not have
- been possible to call any proxy member functions in SomeClass:
-
- long s = modulename.bar();
- modulename.foo(s);
-
- Now wrapper functions are generated:
-
- public class modulename {
- public static void foo(SomeClass s) {
- // calls the native function
- }
-
- public static SomeClass bar() {
- // calls the native function
- }
- }
-
- Which means these functions can now be used more naturally with proxy classes:
-
- SomeClass s = modulename.bar();
- modulename.foo(s);
-
- 2) Changes when not using Java Proxy classes
- --------------------------------------------
-
- The so called low-level interface was rather low-level indeed. The
- new static type checking implementation makes it less so but it remains a
- functional interface to the C/C++ world. Proxy classes are the obvious way to use
- SWIG generated code, but for those who want a functional interface all non-primitive
- types now have a simple Java class wrapper around the C/C++ type. Pointers and
- references to primitive types are also wrapped by type wrapper classes. The type
- wrapper classnames are based on the SWIG descriptors used by the other language
- modules. For example:
-
- C/C++ type Java type wrapper class name
- ---------- ----------------------------
- int* SWIGTYPE_p_int
- double** SWIGTYPE_p_p_double
- SomeClass* SWIGTYPE_p_SomeClass
- SomeClass& SWIGTYPE_p_SomeClass
- SomeClass SWIGTYPE_p_SomeClass
-
- Note that everything wrapped by SWIG is accessed via a pointer even when wrapping
- functions that pass by value or reference. So the previous example would now be
- used like this:
-
- SWIGTYPE_p_SomeClass s = example.bar();
- example.foo(s);
-
- Note that typedefs that SWIG knows about are resolved, so that if one has
-
- class Foo{};
- typedef Foo Bar;
-
- then any use of Bar will require one to use SWIGTYPE_p_Foo;
-
- Some considerations:
- Make sure you make a firm decision to use either proxy classes or the functional
- interface early on as the classnames are different.
-
- 3) Pointers and non-parsed types
- --------------------------------
- Sometimes SWIG cannot generate a proxy class. This occurs when the definition of
- a type is not parsed by SWIG, but is then used as a variable or a parameter.
- For example,
-
- void foo(Snazzy sds);
-
- If SWIG has not parsed Snazzy it handles it simply as a pointer to a Snazzy.
- The Java module gives it a type wrapper class around the pointer and calls it
- SWIGTYPE_p_Snazzy. In other words it handles it in the same manner as types are
- handled in the low-level functional interface. This approach is used for all
- non-proxy classes, eg all pointer to pointers and pointers to primitive types.
-
- 4) Backwards compatibility
- -----------------------
- Backwards compatibility is not an issue if you have been using proxy classes and
- no global variables/functions. Otherwise some changes will have to be made.
- The native methods still exist but they are now in a JNI class, which is called
- modulenameJNI. As this class is really part of the internal workings,
- it should not be required so the class has become protected. Some pragmas/directives
- will hopefully be added to help with backwards compatibility.
-
- *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
-
-07/18/2002: beazley
- Modified wrapping of uninstantiated templates returned by
- value. Just to be safe, they are now wrapped by SwigValueWrapper<>
- just in case they don't define a default constructor. This
- would be used if you had code like this
-
- Foo<int> blah();
- void moreblah(Foo<int> x);
-
- but you didn't instantiate Foo<int> using %template.
- We should probably add a warning for this.
-
-07/17/2002: beazley
- Added an error check to detect shadowed template paramaters.
- For example:
-
- template<class T> class Foo {
- public:
- int T;
- };
-
- This results in an error, not a warning. This warning is
- also needed to fix some rather insidious problems like
- this:
-
- struct T {
- int blah;
- };
-
- template<class T> class Foo {
- public:
- typedef T Traits; // Which T is this????
- };
-
- In this case, the template parameter T shadows the outer
- structure (which is what you want).
-
-07/16/2002: beazley
- Improved support for templates with integer arguments. SWIG is
- much more aware of situations such as this:
-
- const int Size = 100;
-
- %template(Foo100) Foo<100>;
- void bar(Foo<Size> *x); // Knows that Foo<Size> is the same as Foo<100>;
-
-07/15/2002: beazley
- Fixed bug with %feature/%ignore/%rename and namespaces.
- For example:
-
- %ignore Foo::Bar
- namespace Foo {
- class Bar {
- ...
- };
- }
-
- Reported by Marcelo Matus.
-
-07/09/2002: beazley
- Added parsing support for constructors that try to catch
- exceptions in initializers. For example:
-
- class Foo {
- Bar b;
- public:
- Foo(int x) try
- : b(x) { ... }
- catch(int) {
- ...
- }
- }
-
- This has no effect on the generated wrappers. However, the try and catch
- parts of the declaration are ignored. See Stroustrup, 3rd Ed, section
- 14.4.6.1 for details.
-
-07/06/2002: beazley
- Fixed bug in template symbol table management. This fixes
- two bugs. First, mixing abstract methods, templates, and
- inheritance no longer generates a failed assertion.
-
- template <class T>
- class A {
- public:
- virtual void foo() = 0;
- };
-
- template <class T>
- class B : public A<T>
- {
- };
- %template(A_int) A<int>;
- %template(B_int) B<int>;
-
- This fix also fixes a subtle problem with default values and
- templates. For example:
-
- template <class C>
- struct B {
- typedef unsigned int size_type;
- static const size_type nindex = static_cast<size_type>(-1);
- void foo(size_type index = nindex);
- };
-
- Bugs reported by Marcelo Matus.
-
-
-07/05/2002: ljohnson (Lyle Johnson)
- [Ruby] Changed the definition of the SWIG_ConvertPtr() function
- for the SWIG/Ruby runtime support so that it looks like the
- Python version. If the last argument (flags) is non-zero,
- SWIG_ConvertPtr() will raise an exception for type mismatches
- as before. If flags is zero, this function will return -1 for
- type mismatches without raising an exception.
-
- *** POTENTIAL INCOMPATIBILITY FOR RUBY MODULE ***
-
-07/04/2002: beazley
- Overloaded functions/methods/constructors now work in many language
- modules. The support is completely transparent--just call the
- function normally and SWIG will dispatch to the correct implementation.
- There are a variety of issues associated with this. Please refer
- to the overloading section of Doc/Manual/SWIGPlus.html for details.
- *** NEW FEATURE ***
-
-07/04/2002: beazley
- Fixed a bug with namespaces, enums, and templates. For example:
-
- namespace hello {
- enum Hello { Hi, Hola };
-
- template <Hello H>
- struct traits
- {
- typedef double value_type;
- };
-
- traits<Hi>::value_type say_hi()
- {
- return traits<Hi>::value_type(1);
- }
- }
- SWIG wasn't generating wrappers that properly qualified
- traits<Hi>. Reported by Marcelo Matus.
-
-06/30/2002: beazley
- Supplied array variable typemaps for Tcl module. If you have a
- variable like this:
-
- int foo[10];
-
- then a set function like this is generated:
-
- void foo_set(int *x) {
- memmove(foo,x,10*sizeof(int));
- }
-
-06/30/2002: beazley
- New %fragment directive. When writing typemaps, it can be easy to
- get carried away and write a lot of code. However, doing so causes
- tremendous code bloat. A common way to solve this is to write
- helper functions. For example:
-
- %{
- void some_helper_function() {
- ...
- }
- %}
-
- %typemap(in) type {
- some_helper_function(...);
- }
-
- The only problem with this is that the wrapper file gets polluted
- with helper functions even if they aren't used. To fix this,
- a new fragment directive is available. For example:
-
- (corrected typo in line below - 06/26/2008)
- %fragment("type_header","header") %{
- void some_helper_function() {
- ...
- }
- %}
-
- %typemap(in, fragment="type_header") type {
- some_helper_function(...);
- }
-
- In this case, the code fragment is only emitted if the typemap is
- actually used. A similar capability is provided for declaration
- annotation and the %feature directive. For example:
-
- %feature("fragment","type_header") SomeDeclaration;
-
- The first argument to %fragment is the fragment name. The second argument
- is the file section where the fragment should be emitted.
-
- The primary use of this directive is for writers of language modules
- and advanced users wanting to streamline typemap code.
-
- *** EXPERIMENTAL NEW FEATURE ***
-
-06/30/2002: beazley
- Supplied memberin typemaps for all arrays in an attempt to eliminate
- confusion about their use.
-
-06/29/2002: beazley
- Experimental support for smart-pointers. When a class defines
- operator->() like this
-
- class Foo {
- ...
- Bar *operator->();
- ...
- };
-
- SWIG locates class Bar and tries to wrap its member variables and
- methods as part of Foo. For example, if Bar was defined like this:
-
- class Bar {
- public:
- int x;
- int spam();
- };
-
- You could do this (in the target language):
-
- f = Foo()
- f.x = 4 # Accesses Bar::x
- f.spam() # Accesses Bar::spam
-
- The primary use of this feature is to emulate the behavior of C++
- smart-pointers---which allow attributes to accessed transparently
- through operator->.
-
- This feature is supported automatically in SWIG---no special directives
- are needed. To disable this behavior. Use %ignore to ignore
- operator->.
- *** NEW FEATURE ***
-
-06/26/2002: beazley
- Deprecated the %except directive. %exception should be used instead.
-
-06/25/2002: beazley
- Major cleanup of the modules directory. Eliminated most
- header files, consolidated module code into single files.
-
-06/24/2002: beazley
- Reworked the instantiation of language modules. All language
- modules must now define a factory function similar to this:
-
- extern "C" Language *
- swig_python(void) {
- return new PYTHON();
- }
-
- This function is then placed in a table and associated with
- a command line option in swigmain.cxx.
-
- This approach has a number of benefits. It decouples the
- SWIG main program from having to know about the class
- definitions for each module. Also, by using a factory
- function, it will be easier to implement dynamic loading
- of modules (simply load the file and invoke the factory
- function).
-
-06/24/2002: beazley
- Fixed syntax error for reference conversions. For example:
-
- operator Foo &();
-
-06/24/2002: beazley
- Fixed syntax error for operator new[] and operator delete[].
-
-06/24/2002: beazley
- Fixed code generation problem for constants and default arguments
- involving templates.
-
-06/19/2002: ljohnson (Lyle Johnson)
- [Ruby] Fixed a bug for the '-feature' command line argument;
- that setting was effectively being ignored and so the feature
- name was always set equal to the module name.
-
-06/17/2002: beazley
- Fixed problems with static members and enums in templates.
-
-Version 1.3.13 (June 17, 2002)
-==============================
-
-06/16/2002: beazley
- Fixed a bug with __FILE__ expansion in the preprocessor. On Windows,
- the backslash (\) is now converted to (\\) in the string literal
- used for __FILE__. Reported by Steve Glaser.
-
-06/14/2002: beazley
- Fixed warning message about 'name private in this context'. The
- warning is only generated for public methods. Reported by
- Scott Michel.
-
-06/14/2002: beazley
- Fixed some problems related to template instantiation
- and namespaces. When SWIG expands a template, it does
- so with fully resolved types. For example, if you have this:
-
- template<class T> class foo { };
- typedef double Double;
- %template(foo_d) foo<Double>;
-
- then, it is handled as foo<double> in the typesystem.
- This fixes a number of subtle problems with inheritance
- and templates.
-
-06/14/2002: ljohnson (Lyle Johnson)
- [Ruby] Added missing bool typemaps for INPUT, OUTPUT and
- INOUT in Lib/ruby/typemaps.i.
-
-05/29/2002: cheetah (William Fulton)
- [Java] Fix for a couple of broken pragmas.
-
-05/29/2002: cheetah (William Fulton)
- Fix for unnecessary cast when wrapping global variable where
- the type is not parsed by SWIG - Java variables example
- failure as reported by Larry Virden.
-
-06/10/2002: beazley
- Modified %template to allow for empty instantiations.
-
- %template() foo<int,int>;
-
- This registers foo<int,int> with the type system, but
- doesn't wrap it (same as %ignore). This may only be a
- temporary measure. SWIG might be able to automatically
- instantiate templates in certain cases.
-
-06/10/2002: beazley
- Fixed function prototype problems with Tcl 8.4
-
-06/09/2002: beazley
- Fixed problem with templates and location of base classes.
- This one is a little mind-bending, but here is an example
- that illustrates:
-
- template <class ArgType, class ResType>
- struct traits
- {
- typedef ArgType arg_type;
- typedef ResType res_type;
- };
-
- template <class ArgType, class ResType>
- struct Function
- {
- };
-
- template <class AF, class AG>
- struct Class : Function<typename traits<AF, AG>::arg_type,
- typename traits<AF, AG>::res_type>
- {
- };
-
- %template(traits_dd) traits <double, double>;
- %template(Function_dd) Function <double, double>;
- %template(Class_dd) Class <double, double>;
-
-
- In this example, the base class of 'Class' is determined from
- the Function template, but the types are obtained through typedefs.
- Because of this, SWIG could not locate the wrapped base class
- (Function<double,double>). Should be fixed in 1.3.13 even
- though I can think of a million other things that might
- also be broken.
-
-06/07/2002: beazley
- Fixed a problem with conversion operators. If you had an
- operator like this,
-
- operator double() const;
-
- SWIG was ommitting the "const" qualifier. This affected
- %rename and other directives. Reported by Zhong Ren.
-
-06/07/2002: beazley
- Lessened the strictness of abstract class checking. If
- you have code like this:
-
- class Foo {
- public:
- virtual int method() = 0;
- };
-
- class Bar : public Foo {
- public:
- Bar();
- ~Bar();
- };
-
- SWIG will go ahead and generate constructor/destructors
- for Bar. However, it will also generate a warning message
- that "Bar" might be abstract (since method() isn't defined).
- In SWIG-1.3.12, SWIG refused to generate a constructor at all.
-
-06/07/2002: beazley
- Change to %template directive. If you specify something like this:
-
- %template(vi) std::vector<int>;
-
- It is *exactly* the same as this:
-
- namespace std {
- %template(vi) vector<int>;
- }
-
- SWIG-1.3.12 tried to instantiate the template outside of the namespace
- using some trick. However, this was extremely problematic and full
- holes. This version is safer.
-
-06/07/2002: beazley
- Fixed bug with scope qualification and templates. For example:
-
- A<B::C>::DD
-
- Before, this was separated as scopes A<B, C>, and DD. Fixed now.
-
-06/06/2002: beazley
- Allow the following syntax:
-
- class A { };
- struct B : A { ... };
-
- A base class without a specifier is assumed to be public for a struct.
-
-06/06/2002: beazley
- Fixed syntax error with template constructor initializers.
- Reported by Marcelo Matus.
-
-06/06/2002: beazley
- Fixed bug with default template arguments.
- Reported by Marcelo Matus.
-
-06/05/2002: beazley
- Fixed subtle problems with %rename directive and template
- expansion.
-
- Code like this should now work:
-
- %rename(blah) foo<double>::method;
- ...
- template<class T> class foo {
- public:
- void method();
- };
-
- %template(whatever) foo<double>;
-
-06/05/2002: beazley
- Resolved some tricky issues of multi-pass compilation and
- and inheritance. The following situation now generates
- an error:
-
- class Foo : public Bar {
- ...
- };
-
- class Bar {
- ...
- };
-
- The following code generates a warning about incomplete classes.
-
- class Bar;
- class Foo : public Bar { };
-
- The following code generates a warning about an undefined class.
-
- class Foo : public Bar { }; // Bar undefined
-
- This fixes a failed assertion bug reported by Jason Stewart.
-
-06/05/2002: ljohnson
- [Ruby] Added a warning message for the Ruby module about the lack
- of support for multiple inheritance. Only the first base class
- listed is used and the others are ignored. (Reported by Craig
- Files).
-
-06/03/2002: beazley
- Fixed a bug with struct declarations and typedef. For example:
-
- typedef struct Foo Foo;
- struct Foo {
- ...
- };
-
- A few other subtle struct related typing problems were
- also resolved.
-
-Version 1.3.12 (June 2, 2002)
-=============================
-
-05/30/2002: beazley
- Fixed problem related to forward template class declarations and
- namespaces. Bug reported by Marcelo Matus.
-
-05/30/2002: beazley
- Added 'make uninstall' target. Contributed by Joel Reed.
-
-05/29/2002: beazley
- Fixed rather insidious bug with %rename, %feature and template specialization.
- For example:
-
- %exception vector::__getitem__ {
- ... some exception ...
- }
-
- template<class T> class vector {
- ...
- T __getitem__(int index); // Fine
- ...
- };
-
- template<> class vector<int> {
- ...
- T __getitem__(int index); // Oops.
- ...
- };
-
- Now, the %exception directive (and other features) should correctly apply to
- both vector and specializations.
-
-05/29/2002: beazley
- Subtle changes to %template() directive. Template arguments are now
- reduced to primitive types in template matching. For example:
-
- template<class T> class vector<T *> {
- ... partial specialization ...
- }
-
- typedef int *IntPtr; // Gross typedef
-
- // Gets the above partial specialization
- %template(vectorIntPtr) vector<IntPtr>;
-
- This change is extremely subtle, but it fixes a number of potential
- holes in Luigi's STL library modules. For example:
-
- typedef int Integer;
- %template(vectori) vector<int>;
-
-05/29/2002: beazley
- Fixed rather insidious typemap bug related to const. const
- was being discarded through typedefs.
-
-05/29/2002: ljohnson (Lyle Johnson)
- [Ruby] Added input typemaps for const references to primitive
- types (in Lib/ruby/ruby.swg).
-
-05/29/2002: cheetah (William Fulton)
- [Java] The java arrray support functions are enclosed by
- a SWIG_NOARRAYS #define. Useful if not using arrays and
- it is desirable to minimise the amount of compiled code.
-
-05/29/2002: cheetah (William Fulton)
- [Java] Enums were not renamed when using %name or %rename
- fix.
-
-05/28/2002: ljohnson
- [Ruby] Modified the name of the wrapper functions for the
- "new" singleton method and "initialize" instance method for
- consistency with the other language modules. The wrapper name
- for the function that implements "new" is alloc_classname and
- the wrapper name for the function that implements "initialize"
- is new_classname.
-
-
-05/27/2002: beazley
- Changes to runtime. Pointer conversion/creation functions
- now almost always have an extra "flags" argument. For
- example:
-
- SWIG_ConvertPtr(obj, void **, swig_type_info *ty, int flags);
- ^^^^^^^^^^
- This extra parameter is reserved for future expansion and will
- be used for more control over pointers in future versions.
-
-05/27/2002: beazley
- Fix for C++ classes with private assignment operators. It
- is now possible to safely return objects like this by value.
- Caveat: the class must provide a copy constructor.
-
-05/26/2002: beazley
- -proxy option added to many language modules. This is the
- same as -shadow. We are merely changing terminology.
-
-05/26/2002: beazley
- [perl] Fixed some inconsistencies in the -package option.
- -package merely sets the package name to be used on the
- wrappers. It does not change the name of the shared library
- file or the name of the generated .pm file. This was
- broken at some point, but works again now.
-
-05/25/2002: beazley
- [perl] Fixed [ 475452 ] memory leak in return-by-value.
- Problem related to static member variables returning newly
- allocated objects. Reported by Roy Lecates.
-
-05/25/2002: beazley
- [perl] Fixed [ 513134 ] %BLESSEDMEMBERS isn't always right.
- Reported by Fleur Diana Dragan.
-
-05/25/2002: beazley
- Fixed [ 540735 ] -importall and the -I option.
-
-05/25/2002: beazley
- [guile] Fixed [ 532723 ] Default arg for char* can SegV.
- Error in guile module. Reported by Brett Williams.
-
-05/25/2002: beazley
- Subtle change to typemap application code. The "freearg"
- typemap must exactly match up with the "in" or "ignore"
- typemap. For example:
-
- %typemap(in) (char *data, int len) { ... }
- %typemap(freearg) char *data { ... }
-
- void foo(char *data, int len);
-
- In this case, the "in" typemap is applied, but the
- freearg typemap is not. This is because the freearg
- typemap doesn't match up with the input argument sequence.
-
-05/25/2002: beazley
- Fixed [ 548272 ] Default argument code missing braces.
- Reported by Brett Williams.
-
-05/25/2002: beazley
- Fixed [ 547730 ] SwigValueWrapper needed for constructors.
- Reported by William Fulton.
-
-05/25/2002: beazley
- Undefined identifiers now evaluate to 0 when evaluating
- preprocessor expressions. For example:
-
- #if !FOO
- ...
- #endif
-
- where FOO is undefined or set to some non-numeric value.
-
- Fixes [ 540868 ] #if defined whatever - not parsed.
- Reported by Adam Hupp.
-
-
-05/24/2002: beazley
- SWIG now ignores the C++ 'export' keyword.
-
-05/23/2002: beazley
- Some refinement of type-name mangling to account for pointers, arrays,
- references, and other embedded type constructs.
-
-05/23/2002: beazley
- Initial attempt at supporting template partial specialization. At
- the very least, it is parsed and the classes are stored. Matching
- of instantiations to specialized version is more limited and based on
- the SWIG default typemap rules:
-
- SWIGTYPE *
- SWIGTYPE []
- SWIGTYPE &
-
- Now, why in the world would you want to use this feature? Other
- than allowing for slightly modified class APIs, this capability is
- primarily used to provide advanced wrapping support for STL-like
- objects. It can also be mixed with typemaps. Here is an example:
-
-
- /* Generic version */
- template<class T> class vector {
- %typemap(in) vector<T> * {
- // A container of objects
- }
- };
- /* Partial specialization (pointers) */
- template<class T> class vector<T *> {
- %typemap(in) vector<T> * {
- // A container of pointers to objects.
- }
- };
- /* Specialization (integers). */
- template<> class vector<int> {
- %typemap(in) vector<int> * {
- // A container of integers.
- }
- };
-
- *** EXPERIMENTAL FEATURE ***
-
-05/23/2002: beazley
- Enhancement to typemaps. Normally, typemap variables are
- renamed to avoid conflicts. For example:
-
- %typemap(in) int * (int temp) {
- $1 = &temp;
- }
-
- This results in code that creates and uses variables "temp1","temp2",
- "temp3" and so forth depending on how many times the typemap is used.
- Sometimes you want a single variable instead. To do that, using
- the following naming scheme:
-
- %typemap(in) int *(int _global_temp) {
- }
-
- Is this case, a single variable _global_temp is emitted in the
- wrapper functions. It is shared across all typemaps. Repeated
- typemaps do not replicate the variable---they use the first one
- emitted.
- *** NEW FEATURE ***
-
-05/23/2002: beazley
- Minor enhancement to typemaps. If you have this code,
-
- %typemap(in) Foo (int somevar = 3) {
- ...
- }
-
- the default value for somevar is now emitted into the wrapper code.
-
-05/22/2002: beazley
- Fixed %extend to be better behaved in namespaces. If you have code
- like this:
-
- namespace foo {
- struct bar {
- %extend {
- void blah();
- };
- };
- }
-
- SWIG matches the blah() method to a C function named
- void foo_bar_blah(foo::bar *self).
-
- This is consistent with the non-namespace version.
- Bug reported by Marcelo Matus.
-
-05/22/2002: beazley
- New library files: cpointer.i, carrays.i, cmalloc.i. These
- provide access to C pointers and memory allocation functions.
- See Doc/Manual/Library.html for details.
-
-05/22/2002: cheetah (William Fulton)
- [Java] C type char no longer maps to Java type byte, but to Java type char.
- It is now treated as a character rather than a signed number. This fits in
- with the other language modules and is a more natural mapping as char* is
- mapped as a string of characters. Note that the C signed char type is still
- mapped to a Java byte.
-
- *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
-
-05/22/2002: cheetah (William Fulton)
- [Java] Improved constants wrapping. Constants (#define and %constant) values
- are now obtained through a JNI call. Previously the value was compiled as
- Java code, but this didn't work for all cases, eg #define 123ULL.
-
-05/22/2002: beazley
- Fixed bogus error message with %extend directive and C++
- access specifiers. Reported by Marcelo Matus.
-
-05/22/2002: beazley
- Namespaces and enums now work correctly. For example:
-
- namespace Foo {
- enum Bar { A, B };
- }
-
- Bug reported by Marcelo Matus.
-
-05/21/2002: beazley
- The %types directive can now be used to specify inheritance relationships
- in the runtime type system. For example,
-
- %types(Foo = Bar);
-
- specifies that Foo isa Bar. Using this is potentially quite dangerous.
- However, this is useful in certain cases (and in the SWIG library).
-
-05/20/2002: beazley
- %nodefault and %makedefault directives now require a trailing semicolon.
- For example:
-
- %nodefault;
- ...
- %makedefault;
-
- In addition both directives can take a class name. For example:
-
- %nodefault Foo;
-
- class Foo { /* No default constructor/destructor */
- };
-
- class Bar { /* Default constructor/destructor generated */
- };
-
- *** POTENTIAL INCOMPATIBILITY ***
- If you don't use the trailing semicolon, things will mysteriously break.
-
-05/20/2002: beazley
- More improvements to type system handling. SWIG now correctly handles
- template names and parameters in a namespace. For example:
-
- namespace foo {
- template<class T> class bar { };
- typedef int Integer;
-
- void blah(bar<Integer> *x);
- };
-
- In the generated code, all of the typenames are properly qualified.
-
-05/17/2002: cheetah (William Fulton)
- [Java] deprecated broken -jnic and -jnicpp commandline options. The C or C++
- JNI calling convention is now determined from the -c++ commandline option.
-
-05/16/2002: cheetah (William Fulton)
- [Java] The JCALL macros which exist so that the same typemaps can be used
- for generating both the C and C++ JNI calling conventions no longer appear
- in the generated code. This is because the output is now passed through the
- SWIG preprocessor which does the macro expansion for either C or C++ (depending
- on whether -c++ is passed on the SWIG commandline).
-
- The generation of the functions used in the array typemaps have been adjusted
- to take account of this. The side effect is that any typemaps which contained
- JCALL macros within %{ %} brackets will have to be moved within {} brackets
- so that the SWIG preprocessor can expand the macros.
-
- *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
-
-05/13/2002: beazley
- Class templates may now be used as template parameters. For example:
-
- template<class T, template<class> class C> class Foo {
- ...
- };
- template<class T> class Bar {
- ...
- };
-
- %template(Fooi) Foo<int, Bar>;
-
- SWIG doesn't really do anything special with this---it's just
- another way of specifying a template parameter.
-
-05/13/2002: beazley
- Minor refinement of template support. Template parameter names are no longer
- required for types. For example:
-
- template<bool> class Foo {
- };
-
- Obviously, names are required for template<class T>;
-
-05/12/2002: beazley
- New macro expansion in typemaps. The sequence:
-
- $descriptor(type)
-
- Will expand into the SWIG type descriptor structor for
- the given type. Type may be any abstract datatype.
- For example:
-
- $descriptor(int *)
- $descriptor(int (*)(int,double))
- $descriptor(vector<int> *)
-
- Caveat: It is *NOT* currently legal to use other typemap
- substitution variables in the macro. For example
- $descriptor($1_type).
-
- The primary purpose of this modification is to better
- support typemaps for container objects or to allow typemaps
- that might be performing type conversions.
- *** NEW FEATURE ***
-
-05/11/2002: beazley
- The wrapping of references to primitive types has been
- changed as follows:
-
- Arguments of type 'const primitive &' are now passed
- by value as opposed to pointers. Return values of
- type 'const primitive &' are returned as values instead of
- pointers.
-
- 'primitive' is any one of int, short, long, long long,
- char, float, double, bool (as well as unsigned variants).
-
- This change is being made to better support C++ wrapping--especially
- code that makes use of templates and the STL.
-
-05/11/2002: beazley
- The %template directive can now be used to access templates
- in a namespace. For example:
-
- namespace std {
- template<class T> class complex {
- T re, im;
- public:
- complex(T _r = T(), T _i = T()) : re(_r), im(_i) { }
- T real() { return re; }
- T imag() { return im; }
- };
- }
-
- %template(complex) std::complex<double>;
-
- Note: There are some very subtle namespace/symbol table
- management issues involved in the implementation of this.
- It may not work in certain cases.
-
-05/10/2002: beazley
- Member template constructor support added. For example:
-
- template<typename _T1, typename _T2>
- struct pair {
- _T1 first;
- _T2 second;
- pair() : first(_T1()), second(_T2()) { }
- template<class _U1, class _U2> pair(const pair<_U1,_U2> &x);
- };
-
- To instantiate the template, use %template and %extend.
- For example, this expands the constructor into a default
- copy constructor:
-
- %extend pair {
- %template(pair) pair<_T1,_T2>;
- }
-
- Highly experimental. Other uses may be broken.
-
-05/10/2002: beazley
- The %extend (%addmethods) directive no longer works unless
- it appears in the public section of a class. An error
- message is now generated (as opposed to a segmentation fault).
-
-05/09/2002: beazley
- New %warnfilter() directive. This directive attaches a warning
- filter to specific declarations and has the same semantics as
- %rename, %ignore, %feature, and so forth. For example:
-
- %warnfilter(501) foo; // Suppress overloaded warning
- int foo(int);
- int foo(double);
-
- or
-
- %warnfilter(501) Object::foo(double);
- class Object {
- public:
- int foo(int);
- int foo(double);
- };
-
- This feature only suppresses warnings in later stages of code
- generation. It does not suppress warnings related to preprocessing
- or parsing.
- *** NEW FEATURE ***
-
-05/09/2002: beazley
- SWIG now supports C99 variadic preprocessor macros. For example:
-
- #define debugf(fmt,...) fprintf(stderr,fmt,__VA_ARGS__)
-
- The argument "..." is used to indicate variable arguments which
- are all placed into the special argument name __VA_ARGS__ in
- the macro expansion.
-
- SWIG also implements the GNU (##) extension for swallowing the
- preceding comma when __VA_ARGS__ is empty. For example:
-
- #define debugf(fmt,...) fprintf(stderr,fmt, ##__VA_ARGS__)
-
- Here is how this is expanded:
-
- debugf("%d", 3) --> fprintf(stderr,"%d",3)
- debugf("Hello") --> fprintf(stderr,"Hello" )
-
- (notice the deleted comma).
- *** NEW FEATURE ***
-
-05/08/2002: samjam (Sam Liddicott)
- Many changes to php module. Shadow classes are now implemented
- entirely in native C and no need for php-code shadow wrappers
- Populated template config.m4 and Makefile.in as needed by
- phpize are generated.
-
-05/08/2002: ljohnson (Lyle Johnson)
- [Ruby] A copy constructor is now turned into a "clone"
- instance method (see Dave's change for copy constructors
- dated 4/7/2002). This seems like the appropriate thing
- to do for Ruby code.
-
-05/08/2002: ljohnson (Lyle Johnson)
- [Ruby] Fixed [ 553864 ] Inline destructor code not written.
-
-05/08/2002: beazley
- %ignore behaves better with constructors, destructors, and the
- type system in general. For constructors and destructors,
- %ignore now suppresses the creation of a default constructor
- or destructor. For example:
-
- %ignore ~Foo;
- class Foo {
- public:
- Foo();
- ~Foo();
- ...
- };
-
- In SWIG-1.3.11, ~Foo() simply "disappeared" and the code generator
- created a wrapper for a default destructor (as if it was never
- declared in the interface). In SWIG-1.3.12, %ignore suppresses
- the creation of a destructor if one is actually defined.
-
- Similarly, even though a declaration is ignored, information
- may still be needed to properly handle types. For example, here
- is a very subtle error that is fixed by this change:
-
- %ignore std::string; // Prevent class wrapping
- namespace std {
- class string {
- ...
- };
- %typemap(in) string * {
- ...
- }
- }
-
- void foo(std::string *s); // Broken.
-
- Before this fix, %ignore would cause the class definition to disappear.
- This, in turn, would cause the typemap to be misapplied.
-
-05/08/2002: beazley
- Minor changes to %rename, %ignore, %feature, and related directives
- for better support of destructors. Destructors can now be precisely
- tagged. For example:
-
- %ignore Foo::~Foo;
- %feature("action") ~Bar {
- ...
- }
-
- *Developer warning*
- Operations such as renaming and feature attachment for classes used to
- be applied to destructors as well. For instance, if you did this:
-
- %rename(Bar) Foo;
-
- The operation applied to the class itself, the constructor, and
- the destructor. This is no longer the case. Now such operations
- will only apply to the class and the constructor. Note: if you
- were relying on this for class renaming, be aware that renamed
- classes should really only be handled at the level of the class itself
- and not the level of individual declarations in the class (although
- they can be renamed individually if needed). As far as I know,
- the Language class is already taking care of this case correctly.
-
-05/07/2002: beazley
- New set of tests. The Examples/test-suite/errors directory contains
- tests that try to exercise all of SWIG's error and warning messages.
-
-05/07/2002: beazley
- Start of a warning framework. Warning messages are now assigned numeric values
- that are shown in warning messages. These can be suppressed using the
- -w option. For example:
-
- swig -w302 example.i
- swig -w302,305 example.i
-
- Alternatively, the #pragma preprocessor directive can be used to disable this:
-
- #pragma SWIG nowarn=302
- #pragma SWIG nowarn=302,305
-
- Note: Since SWIG is a multi-pass compiler, this pragma should
- only be used to change global settings of the warning filter. It should
- not be used to selectively enable/disable warnings in an interface file.
- The handling of #pragma occurs in the C++ preprocoessor and affects all
- subsequent stages of compilation.
-
- The -Wall option turns on all warnings and overrides any filters that
- might have been set.
-
- Warnings can be issued from an interface using %warn. For example:
-
- %warn "110:%section is deprecated"
-
- The first part of a warning message is an optional warning number.
- A complete set of warning numbers is found in Source/Include/swigwarn.h.
- *** NEW FEATURE ***
-
-05/07/2002: beazley
- Internal parsing change. Directives to include files now use brackets [ ... ]
- instead of { ... }.
-
- %includefile "foo.i" [
- ...
- ]
-
- The use of { ... } was a bad choice because they were included implicitly by
- the preprocessor and made it impossible to properly detect legitimate missing '}'
- errors.
-
-04/16/2002-
-05/02/2002: beazley
- SWIG European Tour: Paris-Amsterdam-Bath.
-
-04/23/2002: beazley
- The %addmethods directive has been renamed to %extend.
- For example:
-
- class Foo {
- ...
- };
-
- %extend Foo {
- int blah() { ... };
- int bar() { ... };
- ...
- };
-
- Motivation: the %addmethods directive can be used for many
- other tasks including adding synthesized attributes, constructors,
- and typemaps. Because of this, "addmethods" is somewhat misleading.
- %extend more precisely describes this operation---extension of a
- class or structure.
-
- *** POTENTIAL INCOMPATIBILITY ***
- %addmethods still works via a macro definition. However,
- a warning message may be generated. Errors involving %addmethods
- will actually refer to the %extend directive.
-
-04/23/2002: beazley
- Further refinement of the type system. Typedef now
- propagates through functions, pointers to functions,
- and pointers to member functions.
- For example:
-
- typedef int Integer;
- void foo(int (*x)(int), Integer (*y)(Integer));
-
- In this case, arguments 'x' and 'y' have exactly
- the same type (and would obviously accept objects
- of either type).
-
- Similarly, consider this:
-
- class Foo {
- };
-
- typedef Foo Bar;
- void bar(int (Foo::*x)(int), int (Bar::*y)(int));
-
- In this case, arguments x and y are the same
- type (via typedef).
-
-04/22/2002: beazley
- SWIG now generates a warning message if any part of
- an expression involves values from a private part of a class.
- For example:
-
- class Foo {
- private:
- static int X;
- public:
- void blah(int a, int b = X); // Warning
- };
-
- In this case, the default argument is ignored. There
- are workarounds, but they are rather clumsy. For instance,
- you might do this:
-
- %feature("action") blah(int,int) {
- if ($nargs == 1) {
- result = blah(arg1);
- } else {
- result = blah(arg1,arg2);
- }
- }
- void blah(int a, int b = 0);
-
-
-04/21/2002: beazley
- Use of the %inline directive inside a namespace is
- forbidden and now generates an error message. This is
- not allowed since the inlined code that is emitted is
- not placed inside a namespace. This confuses other
- stages of parsing.
-
-04/21/2002: beazley
- Some bug fixes to casting operations and expression
- parsing. Due to some parsing issues, it is not
- currently possible to use casts for all possible
- datatypes. However, the common cases work.
-
-04/20/2002: beazley (Amsterdam)
- Member templates now work. Simply use the %template
- directive inside a class or %addmethods to create
- instantiations (see Doc/Manual/SWIGPlus.html). Supporting
- this was easy---earlier changes to templates made it
- possible using only a two-line modification to the parser
- and a few minor modifications elsewhere. Hmmm, come to
- think of it, the smoke was rather thick in that Internet "cafe".
- *** NEW FEATURE ***
-
-04/19/2002: beazley (TGV)
- Improved handling of non-type template parameters. For example:
-
- vector<int,100>;
-
- Simple numbers and strings can be used with the %template
- directive as well. For example:
-
- %template(vecint100) vector<int,100>;
-
- Note: Arithmetic expressions are not currently allowed.
-
- Default template arguments now work and do not have to
- be given to %template.
-
-04/18/2002: beazley (Paris)
- Change in internal template handling. Template
- parameters are now fully integrated into the type
- system and are aware of typedefs, etc. This builds
- upon the change below.
-
- *** DEVELOPER WARNING ***
- Word of caution to language module writers. The "name"
- parameter of certain parse tree nodes (classes, functions, etc.)
- may be parameterized with types. This parameterization is
- done using SWIG type-strings and not the underlying C version.
- For example,
-
- int max<int *>(int *,int *)
-
- has a name of "max<(p.int)>". If you use the name directly,
- you may get syntax errors in the generated code. To fix this,
- use SwigType_namestr(name) to convert a parameterized name
- to a C name with valid syntax. The internal version is
- used to reduce template types to a common representation
- and to handle issues of typedef.
-
-04/16/2002: beazley (somewhere over the Atlantic)
- Enhancement of typedef resolution. The type system is now
- aware of template arguments and typedef. For example:
-
- typedef int Integer;
-
- foo(vector<int> *x, vector<Integer> *y);
-
- In this case, vector<int> and vector<Integer> are
- the same type. There is some interaction between this
- mechanism and the implementation of typemaps. For example,
- a typemap defined for vector<int> * would apply to either type.
- However, a typemap for vector<Integer> * would only apply to
- that type.
-
- Typedefs and typemaps and matched by left-most expansion.
- For example:
-
- vector<Integer,Integer> -->
- vector<int, Integer> -->
- vector<int, int>
-
-
-04/24/2002: cheetah (William Fulton)
- [Java] Changes to Java shadow classes.
- Overcomes a bug where the module assumed that a pointer to a derived
- class could be used in place of a pointer to a base class. Thanks
- to Stephen McCaul for analysing the bug and submitting patches.
-
- A consequence is that the getCPtr() method in each shadow class has
- disappeared and has been replaced with a getCPtrXXX(), where XXX is the
- shadow class name. If you have code that previously used getCPtr(),
- and the associated class is wrapping a C struct or a C++ class that
- is not involved in an inheritance chain, just use the new method. If
- however, the class is involved in an inheritance chain, you'll have
- to choose which pointer you really want. Backwards compatibility
- has been broken as not using the correct pointer can lead to weird bugs
- through ill-defined behaviour. If you are sure you want the old methods,
- you could add them back into all shadow classes by adding this at the
- beginning of your interface file:
-
- %pragma(java) allshadowcode=%{
- public long getCPtr(){
- return swigCPtr;
- }
- %}
-
- Please see entry dated 07/23/2002 to see how to do this after the deprecation
- of the allshadowcode pragma.
-
- *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
-
-04/13/2002: beazley
- Fixed problem with default arguments and references. Declarations such
- as this should now work:
-
- void foo(const string &x = "Hello");
-
-04/12/2002: beazley
- Added typemap $* substitutions for typemaps involving arrays.
- Requested by William Fulton.
-
-04/11/2002: beazley
- Template specialization is now supported. For example:
-
- template<> class vector<int> {
- ...
- };
-
- When the %template directive is used, it will use a specialization
- if one is defined. There are still some limitations. Partial
- specialization is not supported. A template of type <void *> does
- not match all pointers.
- *** NEW FEATURE ***
-
-04/11/2002: beazley
- Major change to template wrapping internals. Template declarations are
- no longer processed as macros but now result in real parse-tree
- nodes. The %template directive expands these nodes into a
- specific instantiation. This change enables a number of
- new and interesting capabilities:
-
- Directives such as %rename, %feature, and %addmethods can
- now be applied to uninstantiated templates. For example:
-
- %rename(barsize) vector::bar(char *buf, int len);
- ...
- template<typename T> class vector {
- public:
- ...
- void bar(char *buf);
- void bar(char *buf, int len); // Renamed
- ...
- };
-
- %template(intvector) vector<int>; // Renaming carries through
-
-
- By parsing templates into an internal data structure, it will
- be possible to support specialization (and maybe partial
- specialization).
-
- This is highly experimental and a work in progress.
-
- *** POTENTIAL INCOMPATIBILITY ***
- In SWIG-1.3.11, template declarations were simply processed
- as weird macros. No other information was retained. This
- made it impossible to support more advanced features and
- complicated many other parts of the implementation.
-
-04/09/2002: beazley
- Change to template class wrapping. There were a variety of
- "issues" with the old approach related to parsing, the type
- system, and namespaces. These changes are meant to rectify
- some of these problems:
-
- A specific instantiation of a template can now be specified
- by including the class inline like this:
-
- class vector<int> {
- public:
- vector();
- ~vector();
- ... whatever ...
- };
-
- This is template specialization, but partial specialization is
- not yet implemented.
-
- The %template directive has been modified to expand roughly as
- follows:
-
- %template(vecint) vector<int>;
-
- becomes
-
- %rename(vecint> vector<int>;
- class vector<int> {
- public:
- vector();
- ...
- };
-
- Note that this simply builds upon the code above (templates
- included inline).
-
- This modified approach to wrapping fixes some subtle type
- issues. For instance, you can now define typemaps and typedefs
- like this:
-
- %typemap(in) vector<int> * {
- ...
- }
- typedef vector<int> intvector;
- ...
- void blah(intvector *v); // Gets the above typemap
-
- This did not work in SWIG-1.3.11 due to a peculiarity of
- the template implementation.
-
- %template(name) no longer installs the template as a class
- with name "name". This might break %addmethods as described
- in the manual. For example:
-
- %template(vecint) vector<int>;
- %addmethods vecint { // Fails. vecint not a class
- ...
- };
-
- To fix this, just use the template name instead:
-
- %addmethods vector<int> {
- ...
- }
-
- Note: This technique might be a way to implement some bizarre
- template specialization techniques. For example:
-
- %addmethods vector<int> {
- // Only applied if vector<int> instantiated later
- %typemap(in) vector<int> * {
- ...
- }
- ...
- };
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-04/08/2002: beazley
- Fixed [ 540868 ] #if defined whatever - not parsed. SWIG should
- now correctly handle preprocessor directives like this:
-
- #if defined __cplusplus
- ...
- #endif
-
- Note: was implemented previously, but there was a minor bug.
- Reported by Adam Hupp.
-
-04/07/2002: beazley
- %readonly and %readwrite are deprecated due to a change in the
- implementation. Instead of being pragmas, mutability is now
- controlled as a "feature" using the following two directives:
-
- %immutable;
- int x; // read-only variable
- int y; // read-only variable
- %mutable;
- int z; // Modifiable
-
- %immutable and %mutable are much more powerful than their older
- counterparts. They can now pinpoint a specific declaration like
- this:
-
- %immutable x; /* Any x */
- %immutable Foo::x; /* x in class Foo */
-
- In fact, the matching algorithm is the same as for %rename,
- %ignore, and other directives. This means that the declaration
-
- %immutable Foo::x;
-
- would not only apply to class Foo but to all derived classes
- as well.
-
- *** POTENTIAL INCOMPATIBILITY ***
- %immutable and %mutable must be terminated by a semi-colon. This
- differs slightly from the older %readonly and %readwrite directives.
- Since %immutable and %mutable can be applied to declarations the
- semicolon is needed to distinguish between a global feature and
- one targeted to a single declaration. Note: this incompatibility is the
- primary reason for changing the name of the directive.
-
-04/07/2002: beazley
- New handling of copy constructors. If a class defines
- constructors like this:
-
- class Foo {
- public:
- Foo();
- Foo(const Foo &); // Copy constructor
- ...
- };
-
- SWIG now generates a function copy_Foo() for the copy
- constructor.
-
- In previous verions, this generated a name-clash and an
- error message. To preserve backwards compatibility, SWIG
- does not change the behavior if %rename is used to resolve
- the name conflict. However, if no name resolution is made,
- this new approach is used.
-
- Copy constructors may be handled as a special case in the
- target language. However, this is up to the language module
- itself.
-
-04/07/2002: beazley
- The %template directive is now namespace aware. This allows
- code like this:
-
- namespace foo {
- template<typename T> max(T a, T b) { return a > b ? a : b; }
- }
-
- using namespace foo;
- %template(maxint) max<int>; // Ok
-
- namespace bar {
- using foo::max;
- %template(maxdouble) max<double>; // Ok
- }
-
- Caveat: the template name supplied to %template must be defined in the
- same scope in which the %template directive appears. This code is
- illegal:
-
- %template(maxint) foo::max<int>;
-
-04/07/2002: beazley
- Minor enhancement to preprocessor. The preprocessor can now perform
- string comparison. For example:
-
- #define A "hello"
- ...
- #if A == "hello"
- ...
- #endif
-
- The primary use of this is in SWIG macros. For example:
-
- %define FOO(x)
- #if #x == "int"
- /* Special handling for int */
- ...
- #endif
- %enddef
-
- Normal users can probably safely ignore this feature. However, it may
- be used in parts of the SWIG library.
-
-04/07/2002: beazley
- Further refinement of default constructor/destructor wrapper generation.
- SWIG is now much more aware of pure virtual methods. For instance:
-
- class A { /* Abstract */
- public:
- virtual void method1() = 0;
- virtual void method2() = 0;
- };
- class B : public A { /* Abstract */
- public:
- virtual void method1() { };
- };
-
- class C : public B { /* Ok */
- public:
- virtual void method2() { };
- };
-
- In this case, SWIG will only generate default constructors for C.
- Even though B looks fine, it's missing a required method and is abstract.
-
-04/04/2002: beazley
- Subtle change to structure data member access. If you
- have a structure like this:
-
- struct Foo {
- Bar b;
- };
-
- The accessor functions for b are generated as follows:
-
- (1) If b is *not* defined as a structure or class:
-
- Bar Foo_b_get(Foo *self) {
- return self->b;
- }
- void Foo_b_set(Foo *self, Bar value) {
- self->b = value;
- }
-
- (2) If b *is* defined as a structure or class:
-
- Bar *Foo_b_get(Foo *self) {
- return &self->b;
- }
- void Foo_b_set(Foo *self, Bar *value) {
- self->b = *value;
- }
- See the "Structure data members" section of Doc/Manual/SWIG.html
- for further details.
-
- *** POTENTIAL INCOMPATIBILITY ***
- This may break interfaces that relied on a lot of a undeclared
- structure and class names. To get the old behavior, simply
- use a forward declaration such as "struct Bar;"
-
-04/04/2002: beazley
- C++ namespace support added. SWIG supports all aspects of
- namespaces including namespace, using, and namespace alias
- declarations. The default behavior of SWIG is to flatten
- namespaces in the target language. However, namespaces are
- fully supported at the C++ level and in the type system.
- See Doc/Manual/SWIGPlus.html for details on the implementation.
-
-04/02/2002: cheetah (William Fulton)
- [Java] Sun has modified javac in jdk1.4 to no longer compile
- an import of an unnamed namespace. To fix this SWIG no longer
- generates the import for packageless classes.
- http://developer.java.sun.com/developer/bugParade/bugs/4361575.html
- As reported SF #538415.
-
-03/27/2002: ljohnson (Lyle Johnson)
- [Ruby] Added support for pointer-to-member, similar to that
- for the Python module. Remarkably similar. Also added a new
- example for this (Examples/ruby/mpointer), which is remarkably
- similar to the Python example of the same name.
-
-03/26/2002: ljohnson (Lyle Johnson)
- [Ruby] Made a few minor edits to the "Advanced Topics"
- chapter of the SWIG manual and added a new major section
- about how to create multi-module Ruby packages with SWIG.
-
-03/26/2002: ljohnson (Lyle Johnson)
- [Ruby] Removed all of the old Ruby pragmas. If any of this
- functionality is truly missed we can resurrect it, preferably
- with some kind of feature-based directive.
-
-03/25/2002: ljohnson (Lyle Johnson)
- [Ruby] Fixed SWIG exception library support for Ruby, which
- has apparently been broken for some time. Luckily, no one seems
- to have noticed.
-
-03/23/2002: beazley
- C++-namespace support in SWIG directives.
-
- %addmethods:
-
- The %addmethods directive now accepts a fully qualified classname
- and can be used inside C++ namespace declarations. For example:
-
- // Attaches to the class Foo::Bar below
- %addmethods Foo::Bar {
- int somemethod() { ... }
- };
-
- namespace Foo {
- class Bar {
- public:
- ...
- };
-
- // Attaches to the class Bar above
- %addmethods Bar {
- int othermethod() { ... };
- }
- }
-
- %feature, %rename, %ignore, %exception, and related directives:
-
- Namespaces are fully integrated into the renaming and declaration
- matcher. For example:
-
- %rename(display) Foo::print; // Rename in namespace Foo
- %ignore Foo::Bar::blah; // Ignore a declaration
-
- %rename directives can be placed inside namespace blocks as well. For
- example:
-
- namespace Foo {
- %rename(display) print; // Applies to print below
-
- void print();
- };
-
- Most other SWIG directives should work properly inside namespaces.
- No other changes are needed.
-
-03/22/2002: beazley
- Some changes to internal symbol table handling. SWIG no longer
- manages structures and unions in a separate namespace than normal
- declarations like ANSI C. This means you can't have a structure
- with the same name as a function. For example:
-
- struct Foo {
- ...
- }
-
- int Foo() { ... }
-
- This approach is more like C++. It's not clear that SWIG ever
- really supported the ANSI C anyways---using the same name would
- almost certainly generate a name-clash in the target language.
-
-03/22/2002: ljohnson (Lyle Johnson)
- [Ruby] Fixed [ 517302 ] for handling of renamed overloaded
- constructors. Now, renamed overloaded constructors are converted
- into class singleton methods (basically acting as "factory"
- methods).
-
-03/21/2002: beazley
- Fixed [ 532957 ] %ignore parse error and casting operator.
- Reported by William Fulton.
-
-03/18/2002: beazley (** ADVANCED USERS ONLY **)
- Added support for dynamic casting in return values. A somewhat
- common problem in certain C++ programs is functions that hide
- the identity of underlying objects when they are returned
- from methods and functions. For example, a program might include
- some generic method like this:
-
- Node *getNode();
-
- However, Node * may just be base class to a whole hierarchy
- of different objects. Instead of returning this generic Node *,
- it might be nice to automatically downcast the object into the
- appropriate type using some kind dynamic cast.
-
- Assuming you understand the peril involved, a downcast can now
- be performed using the following function in the run-time type
- checker:
-
- swig_type_info *SWIG_TypeDynamicCast(swig_type_info *, void **ptr);
-
- This function checks to see if the type can be converted to another
- type. If so, a different type descriptor (for the converted type)
- is returned. This type descriptor would then be used to create
- a pointer in the target language.
-
- To use this, you would write a typemap similar to this:
-
- %typemap(out) Node * {
- swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor, (void **) &$1);
- $result = SWIG_NewPointerObj($1, ty);
- }
-
- Alternatively,
-
- %typemap(out) Node * = SWIGTYPE *DYNAMIC;
-
- To make the typemap have any effect, you have to write a supporting
- function that knows how to perform downcasting. For example:
-
- %{
- static swig_type_info *
- Node_dynamic_cast(void **ptr) {
- Node **nptr = (Node **) ptr;
- Element *e = dynamic_cast<Element *>(*nptr);
- if (e) {
- *ptr = (void *) e;
- return SWIGTYPE_p_Element;
- }
- Data *d = dynamic_cast<Data *>(*nptr);
- if (d) {
- *ptr = (void *) d;
- return SWIGTYPE_p_Data;
- }
- return 0;
- }
- %}
-
- There is no restriction on how types are determined. dynamic_cast<>
- uses C++ RTTI. However, if you had some other mechanism for determining
- the type, you could use that here. Note: it is important to save
- the new pointer value back into the argument as shown. When downcasting,
- the value of the pointer could change.
-
- Finally, to make the casting function available, you have to register
- it with the run-time type checker. Put this macro in your interface file.
-
- DYNAMIC_CAST(SWIGTYPE_p_Node, Node_dynamic_cast);
-
- Note: this feature does not introduce a performance penalty on
- normal SWIG operation. The feature is only enabled by writing
- a new typemap that explicitly calls SWIG_TypeDynamicCast() to
- make a conversion.
-
- Examples/test-suite/dynamic_cast.i contains a simple example.
- This feature is not supported in the Java module due to differences
- in the type-checking implementation.
-
- *** EXPERIMENTAL FEATURE ***
-
-03/17/2002: beazley
- Small change to type-name handling of unnamed structures and
- typedef. If a structure of this form appears:
-
- typedef struct {
- ...
- } Foo;
-
- Then 'Foo' is used as the proper typename for the structure.
- Furthermore, Foo can now be used as a name in C++ inheritance.
- SWIG was already kind of doing this, but this modification refines
- the implementation to more closely follow the C++ ARM, section
- 7.1.3, p. 106. This fixes a couple of obscure corner cases.
-
-03/16/2002: beazley
- Modified C++ inheritance with a few enhancements. First, type information
- needed for casting and type-equivalence is generated even when base-classes
- aren't defined in the interface. For example:
-
- class Foo : public Bar { /* Bar unspecified */
- public:
- ...
- };
-
- void blah(Bar *b);
-
- In this case, the blah() function still accepts Foo * even though nothing
- is really known about Bar. Previous SWIG versions would just generate
- a type error.
-
- Inheritance has also been modified to work through typedef. For example:
-
- class Bar {
- };
-
- typedef Bar OtherBar;
- class Foo: public OtherBar {
- }
-
- In this case, the base class of OtherBar is correctly resolved back to
- Bar. The use of the name OtherBar is lost in this resolution (the wrappers
- will simply use Bar instead of the typedef name OtherBar).
-
-03/13/2002: beazley
- %typemap, %apply, and related directives can now appear inside
- class definitions.
-
-03/13/2002: beazley
- Fixed a variety of problems related to compiling SWIG on 64-bit
- platforms.
-
-03/12/2002: beazley
- Fixed problem with "ignore" and "in" typemaps. Local variables
- associated with "in" were being added to the wrapper function even
- though they were never used. Mostly harmless, but it would lead
- to a variety of compilation warnings.
-
-03/12/2002: beazley
- Some changes to the internal type system and handling of nested C++
- types. In previous versions of SWIG, if you had the following:
-
- class Foo {
- public:
- typedef int Blah;
- };
- class Bar : public Foo {
- public:
- void somemethod(Blah x);
- };
-
- The argument type in somemethod() would implicitly be set to Bar::Blah.
- Although this is technically allowed, it breaks typemaps. For example:
-
- %typemap(in) Foo::Blah { ... }
-
- doesn't match like you expect. This has been changed in SWIG-1.3.12.
- Now, types are expanded using the class in which they were defined.
- So, the argument type in somemethod() will be Foo::Blah---since the
- type Blah was defined in Foo.
-
-03/10/2002: beazley
- Fixed some subtle type scoping problems with typedef and C++ classes.
- For example:
-
- typedef int Blah;
- class Bar {
- public:
- typedef double Blah;
- void foo(Blah x, ::Blah y);
- ...
- }
-
-03/10/2002: beazley
- Highly experimental change to handle variable length arguments.
- First, there is no portable or reliable way to wrap
- a varargs function in full generality. However, you *can* change
- the function signature using %varargs.
-
- %varargs(char *) fprintf;
- ...
- void fprintf(FILE *f, char *fmt, ...);
-
- In this case, the variable length parameter "..." is
- simply replaced by the parameters given in %varargs. This
- results in a function like this:
-
- void fprintf(FILE *f, char *fmt, char *s);
-
- More than one argument can be used and default values
- can be defined. For example, this code specifies a
- maximum of four arguments.
-
- %varargs(char *x1 = 0, char *x2 = 0, char *x3 = 0, char *x4 = 0) fprintf;
-
- *** EXPERIMENTAL NEW FEATURE ***
-
-03/10/2002: beazley
- Change to handling of variable length arguments. varargs
- is now handled as a proper parameter and is passed to the
- code generator. However, it still can't be handled correctly
- (and will generate a typemap warning). This change has been
- made to better incorporate variable length arguments with other
- directives such as %ignore, %rename, %feature, and so forth.
-
-03/10/2002: beazley
- Fixed [ 522555 ] Syntax error parsing "define" construct. SWIG
- is a little more restrictive in determining #define statements
- that will be wrapped as constants. Also added a better parser
- error rule for handling bad constants.
-
-03/08/2002: cheetah (William Fulton)
- [Java] Bug fix: Classes renamed with %rename that are derived from
- another class generate more appropriate shadow class code.
-
-03/08/2002: cheetah (William Fulton)
- [Java] Fixed SF [ #523632 ] and [ #513335 ] both reported by Israel
- Tanner. Support for types that are used which are in a typedef. The
- appropriate shadow class name is generated. Also generated correct
- shadow classname when a templated class is used within another
- templated class. See the cpp_typedef.i testcase.
-
-03/08/2002: cheetah (William Fulton)
- [Java] Bug fix: No type was generated in shadow classes for types
- that weren't wrapped by SWIG. The type is treated as a raw
- pointer, ie no shadow class.
-
-02/22/2002: beazley
- Refined the matching algorithm used by %rename, %ignore, and
- %feature. If a type signature is supplied, it must exactly
- match that used in the declaration---including any use of
- const. For example:
-
- %rename(foo1) foo(int);
- %rename(bar1) bar(int) const;
-
- class Blah {
- public:
- void foo(int); // Matched --> foo1
- void foo(int) const; // Not matched
- void bar(int); // Not matched
- void bar(int) const; // Matched --> bar1
- }
-
- In previous versions, a non-const specification would match
- both the non-const and const declarations. However, the whole
- point of %rename and related directives is that they be able
- to precisely pinpoint exact declarations in an interface. This
- fixes the problem.
-
-02/21/2002: beazley
- Reworked the handling of default constructor and destructors.
- SWIG now makes a preliminary pass over the parse tree to discover
- which classes support default allocation. This fixes a number
- of very subtle issues in code generation and call/return by value.
-
-02/18/2002: cheetah (William Fulton)
- Improved support on Cygwin: Perl, Python, Tcl, Ruby and Java should
- work out of the box, barring the runtime library. Removed dllwrap
- and replaced with newly working gcc -shared instead for Cygwin.
- All this will require the new improved binutils 20010802 and later,
- but the latest Cygwin is usually the best recommendation.
-
-02/15/2002: beazley
- Fixed some problems related to wrapping of global variables
- and Perl shadow classes. Reported by Chia-liang Kao.
-
-02/15/2002: ljohnson (Lyle Johnson)
- [Ruby] Made a fix to the code generation for C++ class
- constructors so that we get both a "new" singleton method
- and an "initialize" instance method for each class. This
- change enables developers to derive new Ruby classes from
- SWIG-wrapped C++ classes and then override their initialize
- methods to provide subclass-specific instance initialization.
-
-02/15/2002: ljohnson (Lyle Johnson)
- [Ruby] Massive documentation update for the Ruby module,
- contributed by Craig Files.
-
-02/14/2002: ljohnson (Lyle Johnson)
- [Ruby] Bug fix: An error in the SWIG runtime support for Ruby
- was causing several of the examples to fail. Reported by
- William Fulton.
-
-02/14/2002: ljohnson (Lyle Johnson)
- [Ruby] Bug fix: Enumerations defined within a class (such
- as those seen in the Examples/ruby/enum example) were not
- being exported with the correct names. Reported by William
- Fulton.
-
-02/13/2002: ljohnson (Lyle Johnson)
- [Ruby] Added a warning message when we run across overloaded
- class constructors for C++ code, that this is currently not
- supported (even if the overloads have been %renamed). For an
- example of where this doesn't work, see Examples/ruby/operator.
-
-02/13/2002: ljohnson (Lyle Johnson)
- [Ruby] Added an "ignored" warning message when the parser runs
- across an operator!=() declaration for C++ code.
-
-02/11/2002: ljohnson (Lyle Johnson)
- [Ruby] Added the "import", "import_template", "operator" and
- "template" examples.
-
-02/11/2002: ljohnson (Lyle Johnson)
- [Ruby] Added multi-module support.
-
-02/09/2002: ljohnson (Lyle Johnson)
- [Ruby] Added the missing "#define SWIG_NOINCLUDE" at the top of
- the wrapper code when the '-c' option is used.
-
-02/09/2002: ljohnson (Lyle Johnson)
- Corrected a minor off-by-one error for the size of the
- swig_types[] array that's generated in the wrapper code.
-
-02/08/2002: beazley
- Fixed SF [ #515058 ] Wrong code for C++ templates.
- Reported by Israel Taller.
-
-Version 1.3.11 (January 31, 2002)
-=================================
-
-01/30/2002: beazley
- Fix to pass/return by value for C++ objects that define
- no default constructor. Changes to the typemap system
- made it impossible to wrap C++ objects with no default
- constructor. This has been fixed, but the solution
- involves some clever template magic contributed by
- William Fulton. Please see the comments in the file
- Lib/swig.swg for further details. This solution is
- experimental and may be refined in a future release.
-
-01/30/2002: beazley
- Global variables and member data of type "const char *"
- can be set, but the old value is silently discarded without
- any garbage collection. This may generate a memory leak.
- This change is needed to more safely handle variables
- like this:
-
- const char *foo = "Hello World\n";
-
- In this case, it's not safe to free the old value. However,
- SWIG can dynamically allocate a new value and make foo point
- to it. To fix this memory leak, you can probably do this:
-
- %clear const char *foo;
- %apply char * {const char *foo};
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-01/30/2002: beazley
- Two minor typemap enhancements have been added. First,
- typemaps can issue a warning message by including a special
- warning attribute. For example:
-
- %typemap(in,warning="I'm going to do something dangerous") ...
-
- The warning message will show up whenever the typemap is
- applied.
-
- Second, a typemap can force a no-match by defining
-
- %typemap(in) sometype "pass"
-
- If this is used, the typemap system will *not* record a
- typemap match for "sometype". This can be used to block
- selected typemaps. For example, if you wanted to disable
- a typemap feature for some type, you could do this.
-
- // Do not allow global variables of type 'const char *' to be set.
- %typemap(varin) const char * "pass"
-
- It might also be possible to use this to do subtle and
- strange things with typemaps. For example, if you wanted to
- make 'blah *' an output value and 'const blah *' an input
- parameter, you might do this:
-
- %typemap(ignore) blah *(blah temp) {
- $1 = &temp;
- }
- %typemap(argout) blah * {
- ... return a value ...
- }
- /* Block unqualified typemaps defined above */
- %typemap(ignore) const blah * "pass"
- %typemap(argout) const blah * "pass"
- %typemap(in) const blah * {
- ... get input value ...
- }
-
- (This potential applications of typemaps suggested by Greg Stein).
- *** NEW FEATURE ***
-
-01/29/2002: cheetah (william fulton)
- [Java] Bug fix: No enumerations were wrapped when the -shadow
- commandline option was not specified. Reported by Israel Taller.
-
-01/28/2002: cheetah (william fulton)
- [Java] Global arrays are successfully wrapped. In fact they started
- mostly working in SWIG-1.3.10.
-
-01/28/2002:richardp
- Added first attempt at C++ and -shadow support for PHP4 module,
- please test and mail me if any problems/ideas on improving it.
-
- There is a known problem with uninitialized member variables,
- please see Examples/php4/sync/README for details.
-
- Also more PHP documentation added to Doc/Manual/Php.html
-
-01/27/2002:beazley
- The ANSI C size_t type is now recognized as an integer by default.
-
-01/26/2002:beazley
- long long and unsigned long long support added to many language modules.
- This is not a portable feature and will require compiler support
- for the long long type. In target languages that do not support
- long long (e.g., Tcl and Perl), numbers are converted to a string
- of digits. This prevents their use in arithmetic calculations, but
- still allows values to be set from a string.
-
- long long support requires the use of the strtoll() and strtoull()
- functions as well as the 'lld' and 'llu' format specifiers
- of sprintf().
-
-01/26/2002:beazley
- Fixed [ #501827 ] Delete method is not called. The Tcl
- module wasn't correctly calling destructors when they
- were defined using %addmethods. This has been fixed.
- Reported by Reinhard Fobbe.
-
-01/26/2002: beazley
- Better support for long long and unsigned long long. Typemaps
- have been included in a number of modules for handling these types.
- In addition, the parser has been modified to accept long long
- literals such as 1234LL and 1234ULL.
-
-01/27/2002: cheetah (william fulton)
- [Java] A C char[] is mapped to a Java String which is the default
- SWIG handling of char[] and char*. It used to be mapped to byte[].
- Note that a C signed char[] array is mapped to byte[].
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-01/25/2002: beazley
- Fixed a problem with return-by-value, C++, and
- objects that define no default constructor.
- Reported by Joel Reed.
-
-01/25/2002: cheetah (william fulton)
- [Java] Overhaul of the Java module. The C code generation is now
- done from typemaps.
-
-01/24/2002: cheetah (william fulton)
- [Java] Support for arrays of enum pointers
-
-01/20/2002: cheetah (william fulton)
- [Java] Error checking for null Java objects being passed to native
- functions. Exception thrown now whereas before the JVM crashed.
-
-01/18/2002: cheetah (william fulton)
- [Java] Corrected behaviour for functions that take arrays. For
- example, when this c function:
-
- void arrayfn(int array[]);
-
- is wrapped the corresponding native function
-
- public final static native void arrayfn(int[] array);
-
- is produced. Previously if the C function made any changes to the
- array elements, these were not reflected back into the Java array.
- This has now been corrected so that the changes are propogated back
- to Java and the calling function will see these changes. This is
- how pure Java functions work, ie arrays are passed by reference.
-
-01/15/2002:mkoeppe
- [Guile] New file cplusplus.i with C++ typemaps contributed
- by Marcio Luis Teixeira <marciot@holly.colostate.edu>.
-
-01/11/2002: cheetah (william fulton)
- [Java] Changed mapping of C long to Java type. Was mapped to Java
- long, now mapped to Java int. If you want the previous mapping to
- Java long use this approach in your interface file:
-
- %clear long;
- %typemap(jni) long "jlong"
- %typemap(jtype) long "long"
- %typemap(jstype) long "long"
-
- %clear long[ANY];
- %typemap(jni) long[ANY] "jlongArray"
- %typemap(jtype) long[ANY] "long[]"
- %typemap(jstype) long[ANY] "long[]"
- %typemap(in) long[ANY] {write me for array support}
- %typemap(out) long[ANY] {write me for array support}
- %typemap(argout) long[ANY] {write me for array support}
- %typemap(freearg) long[ANY] {write me for array support}
-
- *** POTENTIAL INCOMPATIBILITY ***
-
- This new mapping is more appropriate when interfacing to 32 bit
- applications which are used in the current 32-bit JVMs. For future
- 64-bit JVMs you may have to change these mappings - eg on Unix LP64
- systems, but not on Microsoft 64bit Windows which will be using a
- P64 IL32 model. This may be automated in a future version of SWIG.
-
-01/10/2002:beazley
- Fixed [ 501677 ] %init block in wrong place. Reported
- by Luigi Ballabio.
-
-01/09/2002: cheetah (william fulton)
- [Java] Default support for the long long type. signed long long is
- mapped to a Java long. unsigned long long is mapped to BigInteger.
-
-01/09/2002:beazley
- Experimental change to parser to better support mixing of
- int, long, short, unsigned, float, and double. The parser
- should now support types like this:
-
- short unsigned int
- int unsigned short
- unsigned short int
- unsigned int short
-
- This change also enables a type of 'long double' (previously
- unsupported) to be used.
- *** NEW FEATURE ***
-
-01/05/2002: cheetah (william fulton)
- [Java] Casting fix for when function return type is a pointer as
- reported by Gary Pennington 2002-01-05. The upper 32bits of the
- 64 bit jlong will have contained junk for 32bit pointers.
-
-01/05/2002: cheetah (william fulton)
- [Java] Better pointer handling in Java is possible as the
- INPUT, OUTPUT and INOUT typemaps have been added into typemaps.i.
-
-01/05/2002: cheetah (william fulton)
- [Java] $null can be used in input typemaps to return early from JNI
- functions that have either void or a non-void return type. Example:
-
- %typemap(check) int * %{
- if (error) {
- SWIG_exception(SWIG_IndexError, "Array element error");
- return $null;
- }
- %}
-
- If the typemap gets put into a function with void as return, $null
- will expand to nothing:
-
- void jni_fn(...) {
- if (error) {
- SWIG_exception(SWIG_IndexError, "Array element error");
- return ;
- }
- ...
- }
-
- otherwise $null expands to zero, where javareturntype is either a
- pointer or a primitive type:
-
- javareturntype jni_fn(...) {
- if (error) {
- SWIG_exception(SWIG_IndexError, "Array element error");
- return 0;
- }
- ...
- }
-
-01/02/2002: cheetah (william fulton)
- [Java] The Java module incorrectly used argout typemaps for
- strings. This is now corrected and the code now resides
- in the freearg typemap. The argout array typemaps have been split into
- argout and freearg typemaps. This correction may require some user
- written typemaps to be modified.
- *** POTENTIAL INCOMPATIBILITY ***
-
-12/28/2001: cheetah (william fulton)
- [Java] Multi typemaps now working for Java see multimap example.
- [Java] Fix for recently introduced bug - freearg typemap code was appearing
- before the function call.
-
-12/28/2001: cheetah (william fulton)
- [Java] JCALL macro for JNI calls that work in both C and C++ typemaps
- have been replaced with JCALL0, JCALL1, JCALL2, JCALL3 and JCALL4
- macros.
- *** POTENTIAL INCOMPATIBILITY ***
-
-12/22/2001:beazley
- Resolved some inconsistent behavior with %rename and class renaming.
- If you specify the following:
-
- %rename(Foo) Bar;
-
- class Bar {
- public:
- Bar();
- ~Bar();
- }
-
- Then the %rename directive applies to the class itself, the constructor,
- and the destructor (all will be renamed to Foo).
-
- If a class defines more than one constructor, the overloaded variants
- can still be renamed by specifying parameters to %rename. For example:
-
- %rename(Bar_copy) Bar(Bar &);
- class Bar {
- public:
- Bar();
- Bar(Bar &);
- ~Bar();
- };
-
- There are still some odd corner cases. If you specify
-
- %rename(Foo) ::Bar;
-
- then only the name of the class is changed and the constructor/destructor
- names are left unmodified. If you specify
-
- %rename(Foo) *::Bar;
-
- then the names of the constructor/destructor functions are modified but
- the name of the class is not.
-
-12/21/2001: cheetah (william fulton)
- [Java] jni, jtype and jstype typemaps no longer hardcoded but real
- typemaps. New variable substitution, $javaclassname, can be used in
- the jstype typemaps. It is replaced with the Java shadow class name
- where applicable.
- [Java] Fix for recently introduced bug to do with inheritance when
- using %import.
- [Java] A few more bug fixes, todo with %rename and using the kind
- with the type, eg
- void fn(union uni myuni, struct str mystr, class cl mycl);
-
-12/20/2001:beazley
- Fixed [ #494524 ] Preprocessor bug - apostrophe and #subst.
-
-12/20/2001:beazley
- Added SWIG_VERSION preprocessor symbol. This is a hexadecimal
- integer such as 0x010311 (corresponding to SWIG-1.3.11). This can
- be used in the interface as follows:
-
- #if SWIG_VERSION >= 0x010311
- /* Use some fancy new feature */
- #endif
-
- Note: The version symbol is not defined in the generated SWIG
- wrapper file.
-
- *** NEW FEATURE ***
-
-12/20/2001:mkoeppe
- [MzScheme]: Renamed mzswig_make_boolean to
- swig_make_boolean, as the latter is used in the typemaps.
- Reported by Luigi Ballabio.
-
-12/17/2001:mkoeppe
- [Guile]: Rewrote list-vector.i using multi-dispatch
- typemaps. Updated pointer-in-out.i. Make the
- deprecated typemap-substitution of "$source" in "argout"
- work as before.
-
-12/16/2001:mkoeppe
- [Guile]: Fixed macros %values_as_list, %values_as_vector,
- %multiple_values to use the proper %pragma syntax. New
- Guile example/test "multivalue"; new Guile run-test for
- test-suite item "list-vector" (currently broken).
-
-12/14/2001:mkoeppe
- [Guile]: Fixed typemap-substition bug for "varin". Relaxed
- valid-identifier check to allow all R5RS identifiers.
-
-
-Version 1.3.10 (December 10, 2001)
-==================================
-
-12/08/2001:beazley
- Modified %typemap so that %{ ... %} can also be used as a
- code block (mostly for completeness). For example:
-
- %typemap(in) blah %{
- ...
- %}
-
- This form does not introduce a new block scope. Also, the
- code enclosed in %{ ... %} is not processed by the preprocessor.
-
-12/08/2001:beazley
- Fixed [ #459614 ] SWIG with multiple TCL interpreters.
-
-12/08/2001:beazley
- Fixed [ #417141 ] rubydec.swg is wrong
- Reported by Paul Brannan.
-
-12/08/2001:beazley
- Fixed [ #410557 ] Problem with %addmethods on NT.
- Reported by Magnus Ljung.
-
-12/08/2001:beazley
- Fixed [ #445233 ] Enhancement: handle access change.
- SWIG now parses (but ignores) C++ access changes for the
- the following:
-
- class A {
- protected:
- void something() { }
- public:
- A() {}
- };
-
- class B : private A {
- public:
- B() : A() { }
- protected:
- A::something; <---- Parsed, but ignored
- };
-
- Suggested by Krzysztof Kozminski.
-
-12/08/2001: cheetah (william fulton)
- Fix for Ruby to work using Visual C++.
-
-12/06/2001:beazley
- Fixed [ #465687 ] unsigned short parameters fail.
- Reported by Gerald Williams.
-
-12/06/2001:beazley
- Fixed SF [ #489594 ] PyString_FromString can't take NULL arg.
- Reported by John Merritt. SWIG now converts string values
- to Python using code like this:
-
- resultobj = result ? PyString_FromString(result) : Py_BuildValue("");
-
-12/06/2001:beazley
- Fixed SF [ #463561 ] Type conversions not generated.
- Reported by Gerald Williams.
-
-12/04/2001:beazley
- Fixed SF [ #470217 ] Tcl default argument handling.
- Reported by Shaun Lowry.
-
-12/04/2001:beazley
- Fixed SF [ #472088 ] defined(MACRO) expanded everywhere.
- Embedded preprocessor directives such as
-
- %#if defined(FOO)
-
- are not expanded by the SWIG preprocessor.
- Reported by Gerald Williams.
-
-12/04/2001:beazley
- Fixed SF [ #476467 ] Problems with #define & commas.
-
-12/04/2001:beazley
- Fixed SF [ #477547 ] wrong declaration of pointer functions.
- Bad prototypes in Lib/tcl/ptrlang.i.
-
-12/04/2001:beazley
- Fixed SF [ #483182 ] Constants can take args by mistake.
- When swig -perl5 -const is used, constants are declared
- with a void prototype. For example:
-
- sub ICONST () { $examplec::ICONST }
-
- Patch submitted by Rich Wales.
-
-12/03/2001:beazley
- New %exception directive. This is intended to replace %except.
- It works in exactly the same manner except it does not accept a
- language specifier. For example:
-
- %exception {
- try {
- $action
- }
- catch(SomeError) {
- error
- }
- }
-
- %exception is also name aware---allowing it to be applied to
- specific declarations in an interface. For example:
-
- %exception foo {
- ...
- exception for any function/method foo
- ...
- }
-
- %exception Foo::bar {
- ...
- exception for method bar in class Foo
- ...
- }
-
- %exception Foo::bar(double) {
- ...
- exception for method bar(double) in class Foo
- ...
- }
-
- The semantics of this name matching is exactly the same as for %rename.
- *** NEW FEATURE ***
-
-12/03/2001:beazley
- Substantial cleanup of the Python shadow class code. Shadow classes
- used to be created in this rather complicated manner involving about
- a half-dozen strings created in bits and pieces. Shadow classes
- are now generated in a more straightforward manner--in the same
- order that appears in the interface file.
-
- *** POTENTIAL INCOMPATIBILITY ***
- The order in which declarations appear in the shadow file may differ.
-
-12/03/2001:beazley
- The %insert directive (%{ ... %}, %runtime, %header, %wrapper, etc.)
- can now be used inside of a class definition. This has potential
- uses when generating shadow class code. For example:
-
- class Foo {
- ...
- %insert("shadow") %{
- # Some python code
- def blah(self):
- print "I'm blah!"
- %}
- ...
- };
-
- The support for class code insertion depends on the language module.
- However, the intent of this feature is to simplify the task of extending
- shadow class code. In the Python module, this inserts code with the
- proper level of indendation (regardless of what was used in the SWIG
- interface).
- *** NEW FEATURE ***
-
-11/29/2001: cheetah (william fulton)
- Modifications for Java and Python modules to work on cygwin.
- Unfortunately a lot of the python module has started to produces code
- which cannot be auto-imported using cygwin libtools so most of it is
- still broken.
-
-11/28/2001:beazley
- The %rename and %feature directive can now be used inside
- of a class definition. For example:
-
- class Foo {
- %rename(foo_i) foo(int);
- %rename(foo_d) foo(double);
- public:
- ...
- void foo(int);
- void foo(double);
- ...
- };
-
- When used in this manner, the %rename directive only applies
- to members of the class in which it appears as well as all
- derived classes. In fact, this is really just the same
- as saying:
-
- %rename(foo_i) Foo::foo(int);
- %rename(foo_d) Foo::foo(double);
- class Foo {
- ...
- };
-
- *** NEW FEATURE ***
-
-11/26/2001:beazley
- Added the experimental %feature directive. %feature can be
- used to attach arbitrary string attributes to parse tree nodes.
- For example:
-
- %feature("except") blah {
- try {
- $function
- } catch (Error) {
- whatever;
- }
- }
-
- or
-
- %feature("set") *::x_set "x";
-
- or
-
- %feature("blah") Foo::bar(int,double) const "spam";
-
- The syntax is borrowed from the %rename directive. In fact, the
- exact same semantics apply (inheritance, matching, etc.).
-
- %feature is a very powerful low-level primitive that can be used to
- customize individual language modules and to provide hints to
- any stage of code generation. Features are attached to
- parse tree nodes as attributes with names like "feature:*" where *
- is replaced by the feature name (e.g., "feature:except", "feature:set",
- etc.). Language modules can then look for the features using
- a simple attribute lookup.
-
- %feature is intended to be a replacement for a number of
- older SWIG directives including %except and specialized
- pragmas. It is more powerful (due to its parameterized
- name matching) and it provides very precise control over
- how customization features are attached to individual
- declarations. There are future expansion plans that will
- build upon this capability as well.
-
- It's not certain that %feature will ever be used directly
- by SWIG users. Instead, it may be a low-level primitive
- that is used in high-level macro definitions. For instance,
- to support properties, you might define a macro like this:
-
- %define %property(name, setf, getf)
- %feature("set") setf #name;
- %feature("get") getf #name;
- %enddef
-
- Which allows a user to specify things like this:
-
- %property(p, get_p, set_p);
-
- class Blah {
- public:
- int get_p();
- void set_p(int);
- };
-
- *** EXPERIMENTAL NEW FEATURE ***
-
-11/24/2001:beazley
- The Tcl module has been expanded with some new features for
- managing object ownership. For example:
-
- set c [Circle -args 20]
- $c area # Invoke a method
- $c -disown # Releases ownership of the object
- $c -acquire # Acquires ownership of the object
-
- If Tcl owns the object, its destructor is invoked when the
- corresponding object command is deleted in Tcl.
-
- To simplify the destruction of objects, the following syntax
- can be used:
-
- $c -delete # Delete an object
-
- This is an alternative for the more obscure variant of
-
- rename $c {}
-
- These features also add functionality at the C API level.
- The following functions manage ownership from C and
- can be used in typemaps.
-
- SWIG_Acquire(void *ptr);
- SWIG_Disown(void *ptr);
-
- A new function for constructing instances is also available:
-
- Tcl_Obj *
- SWIG_NewInstanceObj(Tcl_Interp *interp, void *ptr,
- swig_type_info *type, int own);
-
- When used in a typemap, this creates a pointer object and
- an interpreter command that can be used to issue methods and
- access attributes as shown above.
- *** NEW FEATURE ***
-
-11/23/2001:beazley
- All Python-related %pragma operations have been eliminated.
- Most of these were written for older SWIG versions in order to
- compensate for limitations in earlier releases. In an effort
- to reduce the amount of code-clutter and potential for errors,
- it is easier to simply eliminate the pragmas and to start over
- (if needed). To be honest, I'm not even sure the pragmas
- worked in 1.3.9 and recent releases.
-
- Note: If you need to insert code into the shadow class file
- created by SWIG, simply use the %shadow directive like this:
-
- %shadow %{
- def some_python_code():
- print "blah!"
- %}
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-11/22/2001:beazley
- Sweeping changes to the way in which the Python module handles
- shadow classes. In early implementations, shadow classes were
- merely Python wrappers around typed pointer objects. However,
- some users actually wanted to receive the shadow class object in C.
- To accommodate this, the dereferencing of the "this" pointer in
- a shadow class was moved to C as described in CHANGES [8/8/99].
- However, the process of returning pointers to Python was still
- somewhat problematic. Specifically, shadow classes never worked
- in situations such as these:
-
- - Use of any kind of output typemap ('out' or 'argout')
- - Global variables (broken as far as I can tell).
-
- In the past, some users have dealt with this by manually trying
- to create shadow class objects themselves from C/C++. However,
- this was difficult because the C wrappers don't really know how
- to get access to the corresponding Python class.
-
- The Python module has now been modified to automatically attach
- shadow class objects to pointers when they are returned to
- Python. This process occurs in the function SWIG_NewPointerObj()
- so the process is completely transparent to users. As a result,
- shadow classes are now more seamlessly integrated with typemaps
- and other features of SWIG.
-
- This change may introduce a number of incompatibilities. The
- SWIG_NewPointerObj() now takes an extra parameter "own" to
- indicate object ownership. This can be used to return a pointer
- to Python that Python should destroy. In addition, older code
- that tries to manually construct shadow class objects or which
- expects bare pointers may break---such pointers may already be
- encapsulated by a shadow class.
- *** POTENTIAL INCOMPATIBILITY ***
-
-11/20/2001:beazley
- Modified the %insert directive to accept single braces { ... }.
- For example:
-
- %insert("header") {
- ... some code ...
- }
-
- This works exactly like %{ ... %} except that the code in the
- braces is processed using the preprocessor. This can be useful
- in certain contexts such as low-level code generation in
- language modules.
- *** NEW FEATURE ***
-
-11/20/2001:beazley
- Command line options are now translated into preprocessor
- symbols. For example:
-
- ./swig -python -shadow -module blah interface.i
-
- Creates the symbols:
-
- SWIGOPT_PYTHON 1
- SWIGOPT_SHADOW 1
- SWIGOPT_MODULE blah
-
- Modules can look for these symbols to alter their code generation
- if needed.
- *** NEW FEATURE ***
-
-11/20/2001:beazley
- Massive overhaul of the Perl5 module. A lot of code generation is
- now driven by tables and typemaps. The generated wrapper code
- also makes use of tables to install constants, variables, and
- functions instead of inlining a bunch of procedure calls. The
- separate variable initialization function is gone. Most
- code generation is controlled via the perl5.swg file in the
- library.
- *** POTENTIAL INCOMPATIBILITY ***
-
-11/13/2001:beazley
- Added parsing support for the C++ typename keyword. Primarily this
- is added to better support templates. For example:
-
- template<typename T> void blah(C& v) {
- typename C::iterator i = v.begin();
- }
-
- Note: typename is supported in the parser in the same way as 'struct'
- or 'class'. You probably shouldn't use it anywhere except in templates.
- *** NEW FEATURE ***
-
-11/11/2001:beazley
- Massive overhaul of the language module API. Most functions now
- use a common, very simple, API. There are also a number of
- interesting semantic side-effects of how code is actually generated.
- Details will be forthcoming in Doc/Manual/Extending.html.
-
- *** POTENTIAL INCOMPATIBILITY *** Language modules written for
- previous versions of SWIG will no longer work,
-
-11/10/2001:beazley
- Fixed a very subtle bug due to unnamed class wrapping. For example, if
- you did this
-
- typedef struct {
- int x,y;
- } gdPoint, *gdPointPtr;
-
- void foo(gdPointPtr x);
-
- Then the foo function would get a type-error. The problem has
- to do with internal typedef handling and the fact that the typedef
- declarations after the struct appear later in the parse tree.
- It should work now. Problem reported by Vin Jovanovic.
-
-11/09/2001:beazley
- Subtle change to "out" typemaps (and related variations). The name
- that is attached to the typemap is now the raw C identifier that
- appears on a declaration. This changes the behavior of
- member functions. For example:
-
- %typemap(out) int foo {
- ...
- }
-
- class Blah {
- public:
- int foo(); // typemap gets applied
- }
-
- Previous versions never really specified how this was supposed to
- work. In SWIG1.1, you could probably write a typemap for the
- wrapper name like this:
-
- %typemap(out) int Blah_foo { ... }
-
- However, this old behavior is now withdrawn and not supported.
- Just use the member name without any sort of special prefix.
- *** POTENTIAL INCOMPATIBILITY ***
-
-11/06/2001:beazley
- Changes to Tcl module initialization:
-
- (1) SWIG now automatically includes the code needed to work with
- Tcl stubs. Simply compile with -DUSE_TCL_STUBS.
-
- (2) SWIG now automatically calls Tcl_PkgProvide to register
- a package name. The package name is the same as the name
- specified with the %module directive. The version number is
- set to "0.0" by default. To change the version number, use
- swig -pkgversion 1.2 interface.i.
-
- *** POTENTIAL INCOMPATIBILITY ***
- Modules that provided stubs and Tcl_PkgProvide on their own might
- break. Simply remove that code.
-
-11/05/2001:beazley
- Changed code generation of constants in the Tcl module. Constants
- are now stored in a large table that get installed at module startup.
- There are also no longer any static variables so it should generate
- somewhat less code.
-
-11/04/2001:beazley
- The "const" typemap has been renamed to "constant" in many language
- modules. "const" is a C keyword which made the handling of the typemap
- directive somewhat awkward in the parser.
- *** POTENTIAL INCOMPATIBILITY ***
-
-11/04/2001:beazley
- %typemap directive can now accept nearly arbitrary keyword parameters.
- For example:
-
- %typemap(in,parse="i",doc="integer") int "..."
-
- The purpose of the keyword parameters is to supply code generation
- hints to the target language module. The intepretation of the
- parameters is language specific.
- *** NEW FEATURE ***
-
-11/04/2001:beazley
- Slight semantic change to internal call/return by value handling.
- In previous versions of SWIG, call-by-value was translated
- into pointers. For example:
-
- double dot_product(Vector a, Vector b);
-
- turned into this:
-
- double wrap_dot_product(Vector *a, Vector *b) {
- return dot_product(*a,*b);
- }
-
- This translation was normally performed by the SWIG core, outside
- of the control of language modules. However, a side effect
- of this was a lot of bizarre typemap behavior. For example,
- if you did something like this:
-
- %typemap(in) int32 {
- ...
- }
-
- You would find that int32 was transformed into a pointer everywhere!
- (needless to say, such behavior is unexpected and quite awkward to
- deal with). To make matters worse, if a typedef was also used,
- the pointer behavior suddenly disappeared.
-
- To fix this, the pointer transformation is now pushed to the
- language modules. This produces wrappers that look roughly
- like this:
-
- double wrap_dot_product(Vector *a, Vector *b) {
- Vector arg1 = *a;
- Vector arg2 = *b;
- return dot_product(arg1,arg2);
- }
-
- This change also makes it easy to define typemaps for
- arbitrary undefined types. For example, you can do this (and it
- will work regardless what int32 is):
-
- %typemap(in) int32 {
- $1 = (int32) PyInt_AsLong($input);
- }
-
- *** POTENTIAL IMCOMPATIBILITY ***
- This change may break call/return by value code generation in
- some language modules.
-
-11/03/2001:beazley
- Changed the name of the default typemaps to the following:
-
- %typemap() SWIGTYPE {
- ... an object ...
- }
- %typemap() SWIGTYPE * {
- ... a pointer ...
- }
- %typemap() SWIGTYPE & {
- ... a reference ...
- }
- %typemap() SWIGTYPE [] {
- ... an array ...
- }
- %typemap() enum SWIGTYPE {
- ... an enum value ...
- }
- %typemap() SWIGTYPE (CLASS::*) {
- ... pointer to member ...
- }
-
-
- These types are used as the default for all types that don't match
- anything else. See CHANGES log entry for 8/27/2000 for the
- old behavior. The role of these types is also described in
- Doc/Manual/Typemaps.html
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-10/25/2001:beazley
- Modified Guile and Mzscheme modules to support
- multi-argument typemaps.
-
-10/25/2001: cheetah (william fulton)
- [Java] Fix to handle pointers to arrays.
-
-10/24/2001:beazley
- Defining a typemap rule for enum SWIGENUM can now be used
- to define default behavior for enum variables.
-
-10/22/2001:beazley
- Ruby module modified to support multi-argument typemaps.
-
-10/22/2001:beazley
- The Ruby module can now handle functions with an arbitrary
- number of arguments. Previous versions were limited to
- to functions with only 9 or 16 arguments depending on
- the use of default arguments. Note: from some inspection
- of the Ruby interpreter source, the new approach might be
- a little faster as well.
-
-10/18/2001:beazley
- Fixed a bug with forward class declarations and
- templates.
-
- class Foo <S,T>;
-
- Bug reported by Irina Kotlova.
-
-10/16/2001:beazley
- Support for multivalued typemaps added. The typemaps
- are specified using the syntax below. Within each
- typemap, variable substitution is handled as follows:
-
- %typemap(in) (int argc, char *argv[]) {
- $arg; // The input object in the target language
- $1; // C local variable for first argument
- $2; // C local variable for second argument
-
- // These variables refer to either argument
- $1_type, $1_ltype, $1_basetype, etc... (argc)
- $2_type, $2_ltype, $2_basetype, etc... (argv[])
-
- // Array dimension of argv
- $2_dim0
- }
-
- Basically any variable that was available in normal typemaps
- is available for either argument by prefacing the variable
- name by '$n_' where n is the argument position.
-
- Notes:
- (1) Multi-valued typemaps can only be applied to a single
- object in the target scripting language. For example,
- you can split a string into a (char *, int) pair or
- split a list into a (int, char []) pair. It is not
- possible to map multiple objects to multiple arguments.
-
- (2) To maintain compatibility with older SWIG versions, the
- variables such as $target and $type are preserved and
- are mapped onto the first argument only.
-
- (3) This should not affect compatibility with older code.
- Multi-valued typemaps are an extension to typemap handling.
- Single valued typemaps can be specified in the usual
- way.
-
- The old $source and $target variables are officially
- deprecated. Input variables are referenced through
- $arg$ and output values are reference through $result$.
-
- *** NEW FEATURE ***
-
-10/16/2001:beazley
- Added parsing support for multivalued typemaps. The syntax
- is a little funky, but here goes:
-
- // Define a multivalued typemap
- %typemap(in) (int argc, char *argv[]) {
- ... typemap code ...
- }
-
- // Multivalued typemap with locals
- %typemap(in) (int argc, char *argv[])(int temp) {
- ... typemap code ...
- }
-
- // Copy a multivalued typemap
- %typemap(in) (int argcount, char **argv) = (int argc, char *argv[]);
-
- // Apply a multivalued typemap
- %apply (int argc, char *argv[]) { (int argcount, char **argv) };
-
- Note: this extra parsing support is added for future extension.
- No language modules currently support multi-valued typemaps.
-
-10/11/2001:beazley
- Modified the typemap matching code to discard qualifiers when
- checking for a match. For example, if you have a declaration
- like this:
-
- void blah(const char *x);
-
- The typemap checker checks for a match in the following order:
-
- const char *x
- const char *
- char *x
- char *
-
- If typedef's are involved, qualifier stripping occurs before
- typedef resolution. So if you had this,
-
- typedef char *string;
- void blah(const string x);
-
- typemap checking would be as follows:
-
- const string x
- const string
- string x
- string
- const char *x
- const char *
- char *x
- char *
-
- The primary reason for this change is to simplify the implementation
- of language modules. Without qualifier stripping, one has to write
- seperate typemaps for all variations of const and volatile (which
- is a pain).
-
- *** POTENTIAL INCOMPATIBILITY *** Typemaps might be applied in
- places where they weren't before.
-
-
-10/9/2001: beazley
- SWIG now generates wrappers that properly disambiguate
- overloaded methods that only vary in constness. For
- example:
-
- class Foo {
- ...
- void blah();
- void blah() const;
- ...
- };
-
- To handle this, the %rename directive can be used normally.
-
- %rename(blah_const) blah() const;
-
- In the resulting wrapper code, method calls like this
- are now generated:
-
- (obj)->blah() // Non-const version
- ((Foo const *)obj)->blah() // const version
-
- This should force the right method to be invoked.
- Admittedly, this is probably obscure, but we might
- as well get it right.
-
-10/8/2001: beazley
- The preprocessor now ignores '\r' in the input.
- This should fix the following bug:
- [ #468416 ] SWIG thinks macro defs are declarations?
-
-10/8/2001: beazley
- Added support for ||, &&, and ! in constants. This
- fixes SF [ #468988 ] Logical ops break preprocessor.
- However, at this time, constants using these operators
- are not supported (the parser will issue a warning).
-
-10/4/2001: beazley
- Added -show_templates command line option. This makes
- SWIG display the code it actually parses to generate
- template wrappers. Mostly useful for debugging.
- *** NEW FEATURE ***
-
-10/4/2001: beazley
- Change to semantics of %template directive. When
- using %template, the template arguments are handled
- as types by default. For example:
-
- %template(vecint) vector<int>;
- %template(vecdouble) vector<double>;
-
- To specify a template argument that is *not* a type, you
- need to use default-value syntax. For example:
-
- %template(vecint) vector<int,int=50>;
- %template(vecdouble) vector<int,size=100>;
-
- In this case, the type name doesn't really matter--only
- the default value (e.g., 50, 100) is used during
- expansion. This differs from normal C++, but I couldn't
- figure out a better way to do it in the parser. Might
- implement an alternative later.
- *** POTENTIAL INCOMPATIBILITY ***
-
-10/4/2001: beazley
- Major changes to template handling in order to provide
- better integration with the C++ type-system. The main
- problem is as follows:
-
- Suppose you have a template like this:
-
- template<class T> void blah(const T x) { stuff };
-
- Now suppose, that you instantiate the template on a
- type like this in SWIG:
-
- %template(blahint) blah<int *>;
-
- In C++, this is *supposed* to generate code like this:
-
- void blah(int *const x) { stuff };
-
- However, in SWIG-1.3.9, the template substitution gets it wrong
- and produces
-
- void blah(const int *x) { stuff };
-
- (notice the bad placement of the 'const' qualifier).
-
- To fix this, the SWIG parser now generates implicit typedefs
- for template type arguments that produces code roughly
- equivalent to doing this:
-
- typedef int *__swigtmpl1;
- %template(blahint) blah<__swigtmpl1>;
-
- which generates code like this:
-
- void blah(const __swigtmpl1 x) { stuff };
-
- Since this is correct in both C++ and SWIG, it provides the right
- semantics and allows everything to compile properly. However,
- to clean up the generated code a little bit, the parser keeps
- track of the template types and performs back-substitution to
- the original type when building the parse tree. Thus, even
- though the implicit typedef is used in the input and may appear
- in the generated wrapper file (for proper compilation), the parse
- tree will hide a lot of these details. For example:
-
- void blah(const __swigtmpl1 x) { stuff };
-
- will look like it was declared as follows (which is what
- you want):
-
- void blah(int *const x) { stuff }
-
- The only place you are likely to notice the typedef hack
- is in bodies of template functions. For example, if you
- did this,
-
- template<class T> class blah {
- ...
- %addmethods {
- void spam() {
- T tempvalue;
- ...
- }
- }
- }
-
- you will find that 'T tempvalue' got expanded into some
- strange typedef type. This *still* compiles correctly
- so it's not a big deal (other than looking kind of ugly
- in the wrapper file).
-
-10/4/2001: beazley
- Fixed some inheritance problems in Tcl Object interface.
-
-10/1/2001: beazley
- Tcl module has changed to use byte-backed pointer strings. This
- implementation should be safe on 64-bit platforms. However,
- the order in which digits appear in pointer values no longer
- directly corresponds to the actual numerical value of a
- pointer (on little-endian machines, pairs of digits appear
- in reverse order).
-
-10/1/2001: beazley
- Perl5 module is now driven by a configuration file 'perl5.swg'
- in the SWIG library.
-
-10/1/2001: beazley
- The perl5 module no longer tries to apply the "out" typemap
- in code generated for magic variables. I'm surprised that
- this ever worked at all (since all of the code that was there
- was wrong anyways). Use the "varout" typemap to handle
- global variables.
-
-10/1/2001: beazley
- Fixed a bug related to character array members of structures.
- For example:
-
- struct Foo {
- char name[32];
- };
-
- SWIG is normally supposed to return a string, but this was
- broken in 1.3.9. The reason it was broken was actually
- due to a subtle new feature of typemaps. When a data member
- is set to an array like this, the return type of the related
- accessor function is actually set to an array. This means
- that you can now write typemaps like this:
-
- %typemap(python,out) char [ANY] {
- $target = PyString_FromStringAndSize($source,$dim0);
- }
-
- This functionality can be used to replace the defunct
- memberout typemap in a more elegant manner.
-
-9/29/2001: beazley
- Some further refinement of qualified C++ member functions.
- For example:
-
- class Foo {
- ...
- void foo() const;
- ...
- };
-
- (i) The SWIG parser was extended slightly to allow 'volatile'
- and combinations of 'const' and 'volatile' to be used. This
- is probably rare, but technically legal. Only added for
- completeness.
-
- (ii) For the purposes of overloading, qualified and non-qualified
- functions are different. Thus, when a class has methods like this:
-
- void foo();
- void foo() const;
-
- Two distinct methods are declared. To deal with this, %rename
- and similar directives have been extended to recognize const.
- Thus, one can disambiguate the two functions like this:
-
- %rename(fooconst) Foo::foo() const;
-
- or simply ignore the const variant like this:
-
- %ignore Foo::foo() const;
-
- Note: SWIG currently has no way to actually invoke the const
- member since the 'const' is discarded when generating wrappers
- for objects.
-
-9/27/2001: beazley
- New directive. %namewarn can be used to issue warning
- messages for certain declaration names. The name
- matching is the same as for the %rename directive.
- The intent of this directive is to issue warnings for
- possible namespace conflicts. For example:
-
- %namewarn("print is a python keyword") print;
-
- The name matching algorithm is performed after a name
- has been resolved using %rename. Therefore, a
- declaration like this will not generate a warning:
-
- %rename("Print") print;
- ...
- void print(); /* No warning generated */
-
- Since the warning mechanism follows %rename semantics, it is
- also to issue warnings for specific classes or just for
- certain member function names.
-
- (Dave - I've been thinking about adding something like this
- for quite some time. Just never got around to it)
- *** NEW FEATURE ***
-
-
-9/27/2001: beazley
- Enhanced the %ignore directive so that warning messages
- can be issued to users. This is done using %ignorewarn
- like this:
-
- %ignorewarn("operator new ignored") operator new;
-
- The names and semantics of %ignorewarn is exactly the
- same as %ignore. The primary purpose of this directive
- is for module writers who want to ignore certain types
- of declarations, but who also want to alert users about it.
- A user might also use this for debugging (since messages
- will appear whenever an ignored declaration appears).
- *** NEW FEATURE ***
-
-9/26/2001: beazley
- Super-experimental support for overloaded operators.
- This implementation consists of a few different parts.
-
- (i) Operator names such as 'operator+' are now allowed
- as valid declarator names. Thus the 'operator' syntax
- can appear *anyplace* a normal declarator name was used
- before. On the surface, this means that operators can
- be parsed just like normal functions and methods.
- However, it also means that operator names can be used
- in many other SWIG directives like %rename. For example:
-
- %rename(__add__) Complex::operator+(const Complex &);
-
- (ii) Operators are wrapped *exactly* like normal functions
- and methods. Internally, the operator name is used
- directly meaning that the wrapper code might contain
- statements like this:
-
- arg0->operator*((Complex const &)*arg1);
-
- This all seems to parse and compile correctly (at least
- on my machine).
-
- (iii) SWIG will no longer wrap a declaration if its symbol
- table name contains illegal identifier characters. If
- illegal characters are detected, you will see an error
- like this:
-
- Warning. Can't wrap operator* unless renamed to a valid identifier.
-
- The only way to fix this is to use %rename or %name to bind
- the operator to a nice name like "add" or something. Note:
- the legal identifier characters are determined by the target
- language.
-
- There are certain issues with friend functions and operators.
- Sometimes, friends are used to define mixed operators such
- as adding a Complex and a double together. Currently, SWIG
- ignores all friend declarations in a class. A global operator
- declaration can probably be made to work, but you'll have to
- rename it and it probably won't work very cleanly in the
- target language since it's not a class member.
-
- SWIG doesn't know how to handle operator specifications
- sometimes used for automatic type conversion. For example:
-
- class String {
- ...
- operator const char*();
- ...
- };
-
- (this doesn't parse correctly and generates a syntax error).
-
- Also: operators no longer show up as separate parse-tree
- nodes (instead they are normal 'cdecl' nodes). I may
- separate them as a special case later.
-
- See Examples/python/operator for an example.
-
- *** SUPER-EXPERIMENTAL NEW FEATURE ***
-
-Version 1.3.9 (September 25, 2001)
-==================================
-
-9/25/2001: beazley
- Fixed parsing problem with type declarations like
- 'char ** const'. SWIG parsed this correctly, but the
- internal type was represented incorrectly (the pointers
- and qualifiers were in the wrong order).
-
-9/25/2001: beazley
- Withdrew experimental feature (noted below) that was
- causing serious parsing problems.
-
-Version 1.3.8 (September 23, 2001)
-==================================
-
-9/23/2001: beazley
- Included improved distutils setup.py file in the Tools
- directory (look for the setup.py.tmpl file). Contributed by
- Tony Seward.
-
-9/23/2001: beazley
- Included two new RPM spec files in the Tools directory. Contributed
- by Tony Seward and Uwe Steinmann.
-
-9/21/2001: beazley
- Fixed SF Bug [ #463635 ] Perl5.swg does not compile in Visual C++
-
-9/21/2001: beazley
- Two new directives control the creation of default
- constructors and destructors:
-
- %nodefault
- %makedefault
-
- These replace %pragma nodefault and %pragma makedefault.
- (old code will still work, but documentation will only
- describe the new directives).
-
-9/21/2001: beazley
- Fixed SF Bug [ #462354 ] %import broken in 1.3.7.
-
-9/20/2001: beazley
-
- Parser modified to ignore out-of-class constructor
- and destructor declarations. For example:
-
- inline Foo::Foo() :
- Bar("foo")
- {
- }
-
- inline Foo::~Foo() {
- }
-
- Suggested by Jason Stewart.
- *** EXPERIMENTAL FEATURE ***
-
-9/20/2001: beazley
- Modified the parser to ignore forward template class
- declarations. For example:
-
- template <class V, long S> class MapIter;
-
- Suggested by an email example from Irina Kotlova.
-
-9/20/2001: beazley
- Fixed problem with undeclared tcl_result variable in
- the "out" typemap for Tcl. Reported by Shaun Lowry.
-
-9/20/2001: beazley
- Incorporated changes to make SWIG work with ActivePerl.
- Contributed by Joel Reed.
-
-9/20/2001: beazley
- Slight change to the parsing of C++ constructor initializers.
- For example:
-
- class Foo : public Bar {
- public:
- Foo() : Bar(...) {...}
- };
-
- SWIG now discards the contents of the (...) regardless of
- what might enclosed (even if syntactically wrong). SWIG
- doesn't need this information and there is no reason to
- needless add syntax rules to handle all of the possibilities
- here.
-
-9/20/2001: beazley
- Change to typemaps for structure members. If you have a
- structure like this:
-
- struct Vector {
- int *bar;
- };
-
- The member name 'bar' is now used in any accessor functions.
- This allows the "in" typemap to be used when setting the value.
- For example, this typemap
-
- %typemap(python,in) int *bar {
- ...
- }
-
- now matches Vector::bar. It should be noted that this will also
- match any function with an argument of "int *bar" (so you should
- be careful).
- *** NEW FEATURE. POTENTIAL INCOMPATIBILITY ***
-
-9/20/2001: beazley
- Fixed SF bug #462642 setting string values in structures
-
-9/20/2001: beazley
- Fixed SF bug #462398 problem with nested templates.
-
-9/20/2001: beazley
- Fixed SF bug #461626 problem with formatting and C++ comments.
-
-9/20/2001: beazley
- Fixed SF bug #462845 Wrong ownership of returned objects.
-
-9/19/2001: beazley
- Fixed SF bug #459367. Default constructors for classes
- with pure virtual methods.
-
-9/19/2001: beazley
- Fixed problem with default arguments and class scope. For
- example:
-
- class Foo {
- public:
- enum bar { FOO, BAR };
- void blah(bar b = FOO);
- ...
- }
-
- SWIG now correctly generates a default value of "Foo::FOO" for
- the blah() method above. This used to work in 1.1, but was
- broken in 1.3.7. Bug reported by Mike Romberg.
-
-Version 1.3.7 (September 3, 2001)
-==================================
-
-9/02/2001: beazley
- Added special %ignore directive to ignore declarations. This
- feature works exactly like %rename. For example:
-
- %ignore foo; // Ignore all declarations foo
- %ignore ::foo; // Only ignore foo in global scope
- %ignore Spam::foo; // Only ignore in class Spam
- %ignore *::foo; // Ignore in all classes
-
- %ignore can also be parameterized. For example:
-
- %ignore foo(int);
- %ignore ::foo(int);
- %ignore Spam::foo(int);
- %ignore *::foo(int);
-
- *** NEW FEATURE ***
-
-
-9/02/2001: cheetah (william fulton)
- [Java] shadowcode pragma modified so that the code that is output
- in the shadow file is placed relative to where it is placed in the
- c/c++ code. This allows support for JavaDoc function comments.
-
-9/01/2001: beazley
- Fixed SF Patch [ #447791 ] Fix for python -interface option.
- Submitted by Tarn Weisner Burton.
-
-9/01/2001: beazley
- SWIG no longer generates default constructors/destructors
- for a class if it only defines a private/protected constructor
- or destructor or if any one of its base classes only has
- private constructors/destructors. This was reported in
- SF Patch [ #444281 ] nonpublic/default/inhereted ctor/dtor
- by Marcelo Matus.
-
-9/01/2001: beazley
- Added patch to Perl5 module that allows constants to be
- wrapped as constants that don't require the leading $.
- This feature is enabled using the -const option.
- Patch contributed by Rich Wales.
- *** NEW FEATURE ***
-
-8/31/2001: beazley
- Added parsing support for the 'volatile' type qualifier.
- volatile doesn't mean anything to SWIG, but it is
- needed to properly generate prototypes for declarations
- that use it. It's also been added to make the SWIG type
- system more complete.
- *** NEW FEATURE ***
-
-8/30/2001: beazley
- Added support for parameterized %rename directive. *** This
- new feature can be used to greatly simplify the task of
- resolving overloaded methods and functions. ***
-
- In prior versions of SWIG, the %rename directive was
- used to consistently apply an identifier renaming. For
- example, if you said this:
-
- %rename foo bar;
-
- Every occurrence of 'foo' would be renamed to 'bar'.
- Although this works fine for resolving a conflict with a
- target language reserved word, it is useless for
- for dealing with overloaded methods. This is because
- all methods are simply renamed to the same thing
- (generating the same conflict as before).
-
- Therefore, the only way to deal with overloaded methods
- was to go through and individually rename them all using
- %name. For example:
-
- class Foo {
- public:
- virtual void bar(void);
- %name(bar_i) virtual void bar(int);
- ...
- };
-
- To make matters worse, you had to do this for all
- derived classes too.
-
- class Spam : public Foo {
- public:
- virtual void bar(void);
- %name(bar_i) virtual void bar(int);
- ...
- };
-
- Needless to say, this makes it extremely hard to resolve
- overloading without a lot of work and makes it almost
- impossible to use SWIG on raw C++ .h files.
-
- To fix this, %rename now accepts parameter declarators.
- The syntax has also been changed slightly. For example,
- the following declaration renames all occurrences of 'bar(int)'
- to 'bar_i', leaving any other occurrence of 'bar' alone.
-
- %rename(bar_i) bar(int);
-
- Using this feature, you can now selectively rename
- certain declarations in advance. For example:
-
- %rename(bar_i) bar(int);
- %rename(bar_d) bar(double);
-
- // Include raw C++ header
- %include "header.h"
-
- When %rename is used in this manner, all occurrence of bar(int)
- are renamed wherever they might occur. More control is obtained
- through explicit qualification. For example,
-
- %rename(bar_i) ::bar(int);
-
- only applies the renaming if bar(int) is defined in the global scope.
- The declaration,
-
- %rename(bar_i) Foo::bar(int);
-
- applies the renaming if bar(int) is defined in a class Foo.
- This latter form also supports inheritance. Therefore, if you
- had a class like this:
-
- class Spam : public Foo {
- public:
- void bar(int);
- }
-
- The Spam::bar(int) method would also be renamed (since Spam
- is a subclass of Foo). This latter feature makes it easy
- for SWIG to apply a consistent renaming across an entire
- class hierarchy simply by specifying renaming rules for
- the base class.
-
- A class wildcard of * can be used if you want to renaming
- all matching members of all classes. For example:
-
- %rename(bar_i) *::bar(int);
-
- will rename all members bar(int) that are defined in classes.
- It will not renamed definitions of bar(int) in the global
- scope.
-
- The old use of %rename is still supported, but is somewhat
- enhanced.
-
- %rename(foo) bar; // Renames all occurrences of 'bar'.
- %rename(foo) ::bar; // Rename all 'bar' in global scope only.
- %rename(foo) *::bar; // Rename all 'bar' in classes only.
- %rename(foo) Foo::bar; // Rename all 'bar' defined in class Foo.
-
- *** NEW FEATURE ***
-
-8/30/2001: beazley
- Added support for data-member to member-function
- transformation. For example, suppose you had a
- structure like this:
-
- struct Vector {
- double x,y;
- };
-
- Now suppose that you wanted to access x and y
- through a member function interface instead
- of the usual SWIG behavior. For example:
-
- f.set_x(3.4) # instead of f.x = 3.4
- x = f.get_x() # instead of x = f.x
-
- To do this, simply use the new %attributefunc
- directive. For example:
-
- %attributefunc(get_%s,set_%s)
- struct Vector {
- double x,y;
- };
- %noattributefunc
-
- The arguments to %attributefunc are C-style printf
- format strings that determine the naming convention
- to use. %s is replaced with the actual name of the
- data member. SWIG provides a number of printf
- extensions that might help. For example, if you
- wanted to title case all of the attributes, you
- could do this:
-
- %attributefunc(get%(title)s,set%(title)s);
-
- This will turn an attribute 'bar' to 'getBar()' and 'setBar()'.
-
- (someone requested this long ago, but I finally figured
- how to implement it in a straightforward manner).
- *** EXPERIMENTAL NEW FEATURE ***
-
-8/30/2001: beazley
- SWIG now automatically generates default constructors
- and destructors if none are defined. This used to be
- enabled with a command line switch -make_default, but
- most people want these functions anyways. To turn
- off this behavior use the -no_default option or include
- the following pragma in the interface file:
-
- %pragma no_default;
-
- This may break certain interfaces that defined their
- own constructors/destructors using the same naming
- convention as SWIG. If so, you will get duplicate
- symbols when compiling the SWIG wrapper file.
- *** POTENTIAL INCOMPATIBILITY ***
-
-8/29/2001: beazley
- Changes to Perl5 shadow class code generation. Iterators
- are no longer supported (FIRSTKEY, NEXTKEY). Also, attribute
- access has been changed to rely on inheritance in order
- to provide better behavior across modules.
-
-8/28/2001: beazley
- Various obscure improvements to the type system and classes.
- Strange declarations like this are now wrapped correctly
- (i.e., the generated wrapper code doesn't cause the C++
- compiler to die with a type error).
-
- class Foo {
- public:
- typedef double Real;
- Real foo(Real (*op)(Real,Real), Real x, Real y);
- };
-
- Inheritance of types is also handled correctly.
-
-8/28/2001: beazley
- Changes to class wrappers. When SWIG sees two classes like this,
-
- class X {
- public:
- void foo();
- ...
- }
-
- class Y : public X {
- public:
- void bar();
- ...
- }
-
- it now only generates two wrapper functions:
-
- X_foo(X *x) { x->foo(); }
- Y_bar(Y *y) { y->bar(); }
-
- Unlike SWIG1.15, the foo() method does *not* propagate to a wrapper
- function Y_foo(). Instead, the base class method X_foo() must be
- used.
-
- This change should not affect modules that use shadow classes, but
- it might break modules that directly use the low-level C wrappers.
- This change is being made for a number of reasons:
-
- - It greatly simplifies the implementation of SWIG--especially
- with anticipated future changes such as overloaded methods.
-
- - It results in substantially less wrapper code--especially
- for big C++ class hierarchies (inherited declarations
- are no longer copied into every single derived class).
-
- - It allows for better code generation across multiple
- SWIG generated modules (code isn't replicated in
- every single module).
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-8/22/2001: cheetah (william fulton)
- Provided some Windows documentation in the Win directory and some
- Visual C++ project files for running examples on Windows.
-
-8/28/2001: mkoeppe
- [Guile] Handle renamed overloaded functions properly;
- thanks to Marc Zonzon <Marc.Zonzon@univ-rennes1.fr> for the
- patch. See the new test case name_cxx.
-
-8/27/2001: mkoeppe
- [Tcl] Removed lots of warnings issued by the Sun Forte
- compilers, which were caused by mixing function pointers
- of different linkages (C++/C).
-
-8/23/2001: mkoeppe
- Improved the MzScheme module by porting Guile's pointer
- type checking system and making type dispatch
- typemap-driven.
-
-8/22/2001: beazley
- Entirely new symbol table processing. SWIG should be able to
- report much better error messages for multiple declarations.
- Also, the new symbol table allows for overloaded functions
- (although overloading isn't quite supported in the language
- modules yet).
-
-8/22/2001: cheetah (william fulton)
- * [Java] %new support added.
- * [Java] Package JNI name refixed!
-
-8/19/2001: beazley
- Python module modified to support pointers to C++ members. This
- is an experimental feature.
- *** NEW FEATURE ***
-
-8/19/2001: beazley
- Added limited parsing and full type-system support for pointers to
- members. None of SWIG's language modules really know how to deal with
- this so this is really only provided for completeness and future
- expansion. Note: SWIG does not support pointers to members which
- are themselves pointers to members, references to pointers to members,
- or other complicated declarations like this.
- *** NEW FEATURE ***
-
-8/19/2001: beazley
- SWIG is much better at parsing certain C++ declarations. Operators and
- friends generally don't cause anymore syntax errors. However, neither
- are really supported.
-
-8/18/2001: beazley
- Added *highly* experimental support for wrapping of C++
- template declarations. Since C++ templates are essentially
- glorified macros and SWIG has a fully operational C
- preprocessor with macro support, the parser now converts
- template declarations to macros. For example, a function
- template like this
-
- template<class T> T max(T a, T b);
-
- is internally converted into a macro like this:
-
- %define %_template_max(__name,T)
- %name(__name) T max(T a, T b);
- %enddef
-
- To instantiate a version of the template, a special %template declaration
- is used like this:
-
- %template(maxint) max<int>;
- %template(maxdouble) max<double>;
-
- The parameter to the %template directive must be proper C identifier that's
- used to uniquely name the resulting instantiation. When used, the
- the expanded macro looks like this:
-
- %name(maxint) int max(int a, int b);
- %name(maxdouble) double max(double a, double b);
-
- A similar technique is used for template classes. For instance:
-
- template<class T> class vector {
- T *data;
- int sz;
- public:
- vector(int nitems);
- T *get(int n);
- ...
- };
-
- Gets converted into a macro like this:
-
- %define %_template_vector(__name, T)
- %{
- typedef vector<T> __name;
- %}
- class __name {
- T *data;
- int sz;
- public:
- __name(int nitems);
- T *get(int n);
- ...
- };
- typedef __name vector<T>;
- %enddef
-
- A specific instantiation is created in exactly the same way:
-
- %template(intvec) vector<int>;
-
- The resulting code parsed by SWIG is then:
-
- %{
- typedef vector<int> intvec;
- %}
- class intvec {
- int *data;
- int sz;
- public:
- intvec(int nitems);
- int *get(int n);
- ...
- };
- typedef intvec vector<int>;
-
- Note: the last typedef is non-standard C and is used by SWIG to provide
- an association between the name "intvec" and the template type
- "vector<int>".
-
- CAUTION: This is an experimental feature and the first time SWIG has
- supported C++ templates. Error reporting is essential non-existent.
- It will probably break in certain cases.
- *** EXPERIMENTAL NEW FEATURE ****
-
-8/15/2001: beazley
- Change to wrapping of multi-dimensional arrays. Arrays
- are now properly mapped to a pointer to an array of
- one less dimension. For example:
-
- int [10]; --> int *
- int [10][20]; --> int (*)[20];
- int [10][20][30]; --> int (*)[20][30];
-
- This change may break certain SWIG extensions because
- older versions simply mapped all arrays into a single
- pointer such as "int *". Although possibly unusual,
- the new version is correct in terms of the C type system.
- *** POTENTIAL INCOMPATIBILITY ***
-
-8/06/2001: cheetah (william fulton)
- * [Java] Array setters generated for struct/class array members.
-
-8/13/2001: beazley
- Many improvements to Tcl/Perl/Python modules to better
- work with multiple interface files and the %import directive.
-
-8/13/2001: beazley
- Fixed up the behavior of %import in the Python module.
- SWIG no longer pollutes the module namespace by using
- 'from module import *' to refer to the other module.
- Instead, it does a proper 'import module'. Also, SWIG
- may work a lot better when importing modules that include
- references to other imported modules.
-
-8/13/2001: mkoeppe
- Added new typemap substitutions, generalizing those of the
- Guile-specific 5/27/2001 changes:
- * $descriptor is the same as SWIGTYPE$mangle, but also
- ensures that the type descriptor of this name gets
- defined.
- * $*type, $*ltype, $*mangle, $*descriptor are the same as
- the variants without star, but they REMOVE one level of
- pointers from the type. (This is only valid for pointer
- types.)
- * $&type, $&ltype, $&mangle, $&descriptor are the same as
- the variants without ampersand, but they ADD one level of
- pointers to the type.
- The Guile-specific substitution $basedescriptor was removed
- because it was useless.
-
-8/12/2001: beazley
- The %extern directive is now deprecated and withdrawn. The
- purpose of this directive was to import selected definitions
- from other interface files and headers. However, the same
- functionality is better handled through %import. This
- leaves SWIG with two file inclusion directives:
-
- %include filename - Inserts into current interface
- %import filename - Import types and classes from
- another module
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-8/09/2001: beazley
- Added new support for wrapping C/C++ callback functions.
- A common problem with some C libraries is that many
- functions take a function pointer as an argument. For example:
-
- int do_op(..., int (*op)(int,int), ...);
-
- Unfortunately, the only way to call such a function is to
- pass it a function pointer of some compatible type. In
- previous versions of SWIG, you had to solve this problem
- with some really gross hacks. For example, if you wanted to
- use the following function as a callback,
-
- int foo(int, int);
-
- you had to install a pointer to it as a constant. For example:
-
- %constant int (*FOO)(int,int) = foo;
-
- or
-
- const int (*FOO)(int,int) = foo;
-
- or if you had a really old SWIG version:
-
- typedef int (*OP_FUNC)(int,int);
- int do_op(..., OP_FUNC, ...);
- const OP_FUNC FOO = foo;
-
-
- Now, you can do one of two things:
-
- %constant int foo(int,int);
-
- This creates a constant 'foo' of type int (*)(int,int).
- Alternatively, you can do this:
-
- %callback("%s");
- int foo(int,int);
- int bar(int,int);
- %nocallback;
-
- In this case, the functions are installed as constants where
- the name is defined by the format string given to %callback().
- If the names generated by the format string differ from the
- actual function name, both a function wrapper and a callback
- constant are created. For example:
-
- %callback("%(upper)s");
- int foo(int,int);
- int bar(int,int);
- %nocallback;
-
- Creates two wrapper functions 'foo', 'bar' and additionally
- creates two callback constants 'FOO', 'BAR'.
-
- Note: SWIG still does not provide automatic support for
- writing callback functions in the target language.
- *** NEW FEATURE ***
-
-8/06/2001: cheetah (william fulton)
- * struct nesting fixes as per SF bug #447488.
-
-8/03/2001: beazley
- The %name directive now applies to constants created with
- #define and %constant. However, most language modules
- were never written to support this and will have to be
- modified to make it work. Tcl, Python, and Perl modules
- are working now.
- *** NEW FEATURE ***
-
-8/03/2001: beazley
- Massive changes and simplification of C declaration parsing.
- Although SWIG is still not a full C parser, its ability
- to handle complex datatypes including pointers to functions
- and pointers to arrays has been vastly improved.
-
-8/03/2001: cheetah (william fulton)
- * Distribution fixes: autoconf no longer needed to install SWIG.
-
-8/02/2001: beazley
- Removed two undocumented parsing features. SWIG no longer
- supports out-of-class static function or variable
- declarations. For example:
-
- static int Foo::bar;
-
- This feature may return if there is sufficient demand.
- However, since SWIG is most often used with header files,
- it is more likely for these definitions to be included
- in the class definition.
- *** POTENTIAL INCOMPATIBILITY ***
-
-8/02/2001: cheetah (william fulton)
- * Cleanup of the GIFPlot examples. Upgraded Java GIFPlot example.
-
-8/01/2001: cheetah (william fulton)
- * [Java] Efficiency changes: _cPtr used where possible rather than
- getCPtr(). Bug fixes for inheritance - derived class sometimes
- didn't delete the c memory when _delete() was called.
- * [Java] Abstract c++ classes are wrapped with a java abstract shadow
- class. Also a pure virtual function is mapped with an abstract method.
- * The default output file has always been <module>_wrap.c. It is now
- <module>_wrap.cxx if the -c++ commandline option is passed to swig.
- This has been done as otherwise c++ code would appear in a c file.
- *** POTENTIAL INCOMPATIBILITY ***
-
-7/31/2001: beazley
- Modified the %constant directive to be more C-like in syntax.
- The syntax is now:
-
- %constant NAME = VALUE;
- %constant TYPE NAME = VALUE;
-
- For example:
-
- %constant Foo *Bar = &Spam;
-
- A more subtle case is as follows:
-
- %constant int (*FOO)(int,int) = blah;
-
- *** POTENTIAL INCOMPATIBILITY *** Modules that were using
- the %constant directive directly will need to be modified.
-
-7/30/2001: beazley
- Removed obscure and undocumented form of the %inline directive:
-
- %inline int blah(int a, int b) {
- ...
- }
-
- *** POTENTIAL INCOMPATIBILITY ***
- (note: this feature was never documented and is withdrawn)
-
-7/30/2001: beazley
- Removed support for functions with no explicitly declared
- return type. For example:
-
- foo(int);
-
- In C, such functions were implicitly assumed to return an 'int'.
- In C++, this is illegal. Either way, it's considered bad
- style. Removing support for this in SWIG will simplify
- certain issues in parsing.
- *** POTENTIAL INCOMPATIBILITY ***
-
-7/30/2001: mkoeppe
- * Partial merge from the CVS trunk. The Source/DOH directory
- and most of the Source/Swig directory is up-to-date now.
- * [Guile] %scheme is now a macro for %insert("scheme").
- New syntax: %scheme "FILENAME";
- New syntax: %scheme %{ SCHEME-CODE %}
- New macros %multiple_values, %values_as_list,
- %values_as_vector.
-
-7/29/2001: beazley
- %readonly and %readwrite have been turned into SWIG pragmas.
- %pragma(swig) readonly and %pragma(swig) readwrite. Macros
- are used to provide backwards compatibility.
-
-7/29/2001: beazley
- Minor changes to %pragma directive. %pragma must always
- be directed to a specific language. For example:
-
- %pragma(swig) make_default;
- %pragma(perl5) include = "blah.i";
-
- Also extended the pragma directive to allow code blocks
-
- %pragma(foo) code = %{
- ... some code ...
- %}
-
- *** POTENTIAL INCOMPATIBILITY ***
-
-7/29/2001: beazley
- Change to the way 'const' variables are wrapped. In
- previous versions of SWIG, a 'const' variable was
- wrapped as a constant. Now, 'const' variables are
- wrapped as read-only variables. There are several
- reasons for making this change, mostly pertaining to
- subtle details of how 'const' actually works.
-
- This will probably break old interfaces that used 'const'
- to create constants. As a replacement, consider using this:
-
- const int a = 4; ===> %constant int a = 4;
- *** POTENTIAL INCOMPATIBILITY ***
-
-7/29/2001: beazley
- Reorganization and simplification of type parsing.
- Types with 'const' should work correctly now.
-
-7/29/2001: beazley
- Most swig directives related to the documentation system
- are now deprecated.
-
-7/29/2001: beazley
- Removed support for Objective-C in order to simplify
- parser reconstruction. Will return if there is sufficient
- demand.
- *** POTENTIAL INCOMPATIBILITY ***
-
-7/29/2001: beazley
- Code inclusion has been modified in the parser. A common
- directive %insert is now used for everything. This
- inserts a file into the output:
-
- %insert(header) "foo.swg"
-
- This inserts some inline code into the output
-
- %insert(header) %{
- ... some code ...
- %}
-
- There are five predefined targets for the insert directive:
-
- "header" - Header section of wrapper file
- "runtime" - Runtime section of wrapper file
- "wrapper" - Wrapper section
- "init" - Initialization function
- "null" - Nothing. Discard.
-
- The following directives are still supported, but are
- now defined in terms of macros:
-
- %{ ... %} -> %insert(header) %{ ... %}
- %init %{ ... %} -> %insert(init) %{ ... %}
- %wrapper %{ ... %} -> %insert(wrapper) %{ ... %}
- %runtime %{ ... %} -> %insert(runtime) %{ ... %}
-
- Language modules can define new named targets by using the
- C API function Swig_register_filebyname() (see main.cxx).
- For example, if you wanted to expose a shadow class file,
- you could do this:
-
- Swig_register_filebyname("shadow", f_shadow);
-
- Then in the interface file:
-
- %insert(shadow) %{ ... %}
-
- Note: this change should not affect any old interfaces, but
- does open up new possibilities for enhancements.
-
-7/29/2001: beazley
- SWIG now always includes a standard library file 'swig.swg'.
- This file defines a large number of macro definitions
- that define the behavior of various SWIG directives.
- Previously, all SWIG directives were handled as special
- cases in the parser. This made the parser a large
- bloated mess. Now, the parser is stripped down to a few
- simple directives and macros are used to handle everything else.
-
-7/26/2001: cheetah (william fulton)
- * Fixes for Sourceforge bug #444748 - new testcase cpp_static:
- [TCL] Class with just static member variable/function fix
- [Java] Fixed static variables support
- [Ruby] Static variables workaround removed
-
-7/27/2001: mkoeppe
- * stype.c (SwigType_default): Strip qualifiers first. The
- default type of "int * const" is now "SWIGPOINTER *".
- * main.cxx: Define "__cplusplus" in SWIG's preprocessor if
- in C++ mode.
- * [Guile]: Added some support for arrays and C++
- references, fixing the "constant_pointers" test case.
- * Moved most tests from the old Guile-specific test-suite
- to the new test-suite. Also moved perl5/pointer-cxx
- example there.
-
-7/26/2001: cheetah (william fulton)
- * Test-suite added.
- * Initial testcases: constant_pointers cpp_enum defines
- sizeof_pointers unions virtual_destructor
- * Make clean improvements.
-
-7/24/2001: cheetah (william fulton)
- * [Java] Underscores in the package name and/or module name
- no longer give linking problems.
-
-7/17/2001: cheetah (william fulton)
- * More parser bug fixes for constant pointers
-
-7/19/2001: mkoeppe
- * [Guile] Aesthetic improvement in variable wrappers.
-
-7/18/2001: beazley
- * Fixed core-dump problem in pointer library when
- freeing character arrays.
- SF Bug [ #415837 ] pointer lib core dump
-
-7/18/2001: beazley
- * Fixed problem with default destructors and shadow
- classes. SF bug #221128.
-
-7/18/2001: beazley
- * To provide better line-number tracking in interfaces
- with lots of macros, special locator comments are
- now generated by the SWIG preprocessor. For example:
-
- /*@foo.i,42,BLAH@*/expanded macro/*@@*/
-
- The first /*@...@*/ sequence sets the context
- to point to the macro code. The /*@@*/ comment
- terminates the context. The SWIG parser should
- ignore all of the locator comments as should
- the C compiler (should such comments end up
- in generated wrapper code).
-
-7/18/2001: mkoeppe
- * The parser now handles severely constified types in
- typemaps. This introduced a new shift/reduce conflict, but
- only with a heuristic function-pointer catch-all rule.
- * [Guile]: Added typemaps for severely constified types.
- * Fixed the "template-whitespace" problem by canonicalizing
- whitespace, especially around angle brackets and commas.
-
-7/17/2001: mkoeppe
- * [Guile]: A Scheme file is emitted if the -scmstub FILE.SCM
- command-line option is used. The %scheme directive
- (implemented as a macro for a pragma) allows to insert
- arbitrary code here. In "simple" and "passive" linkage,
- the file gets filled with define-module and export
- declarations.
-
-7/17/2001: cheetah (william fulton)
- * Parser bug fix to support constant pointers, eg int* const ptr.
- Fixed everywhere - variables, parameters, return types etc. Note that
- when wrapping a constant pointer variable only the getter is generated.
-
-7/17/2001: mkoeppe
- * Fixed SF bug #441470 (#define X "//" would not be parsed,
- see test-suite entry "preproc-1"), reported by T. W. Burton
- <twburton@users.sf.net>.
- * Changed the type of character constants to "char", rather
- than "char *". Changed the individual language modules
- to keep the old behaviour, except for the Guile module,
- where it is desired to make them Scheme characters. This
- fixes SF bug #231409, test-suite entry "char-constant".
- * Applied patch for DOH/Doh/memory.c by Les Schaffer
- <schaffer@optonline.net> (avoid required side effects in
- assert).
-
-7/17/2001: cheetah (william fulton)
- * Bug fix in parser for virtual destructor with void as parameter
- * Bug fix in parser #defines embedded within classes/structs/unions
- Consequently %constant can now also be placed within a struct/class/union.
- * Bug fix in parser to allow sizeof(*I_am_a_pointer) within a #define
-
-7/16/2001: mkoeppe
- * Added changes for the Macintosh contributed by Luigi
- Ballabio <ballabio@mac.com>.
- * Some "const" fixes in the code.
- * [Guile]: Made the constant-wrapper functions much shorter.
-
-7/13/2001: mkoeppe
- * [Guile]: Some "const" fixes for Guile version 1.3.4.
- * Handle anonymous arguments with default values and static
- array members of classes. Both bugs reported by Annalisa Terracina
- <annalisa.terracina@datamat.it>; see the files
- Examples/guile/test-suite/static-array-member.i and
- anonymous-arg.i.
-
-Version 1.3.6 (July 9, 2001)
-=============================
-
-7/09/2001: cheetah (william fulton)
- * GIFPlot examples: FOREGROUND and BACKGROUND definition missing
- after TRANSPARENT #define fix in GIFPlot
-
-7/03/2001: beazley
- Fixed up the version numbers so that the release is known
- as 1.3.6. All future releases should have a similar
- version format.
-
-7/02/2001: mkoeppe
- * [Python]: Prevent the problem of self.thisown not being
- defined if the C++ class constructor raised an exception.
- Thanks to Luigi Ballabio <ballabio@mac.com>.
-
-6/29/2001: mkoeppe
- * More portability fixes; fixed "gcc -Wall" warnings.
-
-6/29/2001: cheetah (william fulton)
- * GIFPlot examples: TRANSPARENT #define multiple times on Solaris
- (clashes with stream.h).
- * Multiple definition bug fix for shadow classes. The perl and python
- modules had workarounds which have been replaced with fixes in
- the core. Many of the Language::cpp_xxxx functions now set a
- flag which the derived classes can access through
- is_multiple_definition() to see whether or not code should be
- generated. The code below would have produced varying degrees
- of incorrect shadow class code for the various modules:
- class TestClass
- {
- public:
- TestClass() {}
- TestClass(int a) {}
- ~TestClass() {}
- unsigned long xyz(short k) {}
- unsigned long xyz(int n) {}
- static void static_func() {}
- static void static_func(int a) {}
- };
- void delete_TestClass(int a);
-
-6/27/2001: mkoeppe
- * [Perl] Another const-related portability fix.
-
-6/26/2001: cheetah (william fulton)
- * [Java] Added in cpp_pragma() support with a host of new pragmas - see
- jswig.html. These are designed for better mixing of Java and c++. It
- enables the user to specify pure Java classes as bases and/or interfaces
- for the wrapped c/c++.
- * [Java] Old pragmas renamed. Warning given for the moment if used.
- *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
-
-6/25/2001: mkoeppe
- * Incorporated more build changes contributed by Wyss Clemens
- <WYS@helbling.ch> for swig/ruby on cygwin.
-
-6/20/2001: cheetah (william fulton)
- * Makefile mods so that 'make check' uses the swig options in the makefiles
- * [Java] Removed Generating wrappers message
- * [Java] NULL pointer bug fix
- * [Java] Bug fix for Kaffe JVM
-
-6/20/2001: mkoeppe
- * SWIG_TypeQuery from common.swg now returns a
- swig_type_info* rather than a void*. This fixes a problem
- when using pointer.i and C++, as illustrated by the new
- test-suite example perl5/pointer-cxx.
- * Portability fixes (const char *).
- * Incorporated build changes contributed by Wyss Clemens
- <WYS@helbling.ch>, which make swig runnable on cygwin.
-
-6/19/2001: cheetah (william fulton)
- * [Java] Bug fix for SF bug #211144. This fix is a workaround
- until fixed in the core.
-
-6/19/2001: mkoeppe
- * [Guile]: Portability fixes for use with the Sun Forte
- compilers.
- * [Tcl]: Portability fix (const char *).
- * [Tcl]: Configure now first tries to find a tclConfig.sh
- file in order to find the Tcl include directory, library
- location and library name.
- * [Python]: Added a few possible library locations.
-
-6/18/2001: mkoeppe
- * [Guile]: Don't call scm_c_export if nothing is to be
- exported. Don't warn on %module if module has been set
- already (this frequently occurs when %import is used).
-
-6/16/2001: mkoeppe
- * [Guile]: New "passive" linkage, which is appropriate for
- multi-module extensions without Guile module magic.
-
-6/15/2001: mkoeppe
- * [Guile]: Fixed printing of smobs (space and angle were
- missing).
- * Properly generate type information for base classes
- imported with the %import directive. Thanks to Marcelo
- Matus <mmatus@acms.arizona.edu> for the report and the
- patch; this closes SF bug #231619; see also
- Examples/guile/test-suite/import*.
- * [Guile]: Fix casting between class and base class; the
- runtime type system had it the wrong way around; see
- Examples/guile/test-suite/casts.i
- * Make typemaps for SWIGPOINTER * with arg name take
- precedence over those without arg name, to match normal
- typemap precedence rules.
- * Fixed the random-line-numbers problem reported as SF bug
- #217310; thanks to Michael Scharf <scharf@users.sf.net>.
- * [Guile]: Handle the %name and %rename directives.
- * New syntax: %name and %rename now optionally take double
- quotes around the scripting name. This is to allow scripting
- names that aren't valid C identifiers.
-
-6/14/2001: beazley
- Made a minor change to the way files are loaded in
- order to get file/line number reporting correct in
- the preprocessor.
-
-6/14/2001: mkoeppe
- * The parser now understands the (non-standard) "long long"
- types. It is up to the individual language modules to
- provide typemaps if needed. Reported by Sam Steingold, SF
- bug #429176.
- * The parser now understands arguments like "const int *
- const i". This fixes SF bug #215649.
- * Fixed the Guile test-suite.
-
-6/13/2001: mkoeppe
- Partial merge from the CVS trunk at tag
- "mkoeppe-merge-1". This covers the following changes:
-
-| 01/16/01: ttn
-| Wrote table of contents for Doc/engineering.html. Added section
-| on CVS tagging conventions. Added copyright to other docs.
-| 9/25/00 : beazley
-| Modified the preprocessor so that macro names can start with a '%'.
-| This may allow new SWIG "directives" to be defined as macros instead
-| of having to be hard-coded into the parser.
-|
-| *** Also a yet-to-be-documented quoting mechanism with backquotes
-| *** has been implemented?
-
-6/13/2001: mkoeppe
- * When configure does not find a language, don't use default
- paths like /usr/local/include; this only causes build
- problems.
- * New directory: Examples/Guile/test-suite, where a few
- bugs in 1.3a5 are demonstrated.
- * Handle C++ methods that have both a "const" and a "throw"
- directive (see Examples/Guile/test-suite/cplusplus-throw.i);
- thanks to Scott B. Drummonds for the report and the fix.
- * Handle C++ pointer-reference arguments (like "int *& arg")
- (see Examples/Guile/test-suite/pointer-reference.i,
- reported as SF bug #432224).
- * [Ruby] Fixed typo in rubydec.swg; thanks to Lyle Johnson!
- * Don't stop testing when one test fails.
- * [Guile, MzScheme] Don't print "Generating wrappers...".
-
-6/12/2001: mkoeppe
- [Guile] VECTORLENINPUT and LISTLENINPUT now have separate
- list length variables. TYPEMAP_POINTER_INPUT_OUTPUT
- attaches argument documentation involving SCM_TYPE to the
- standard pointer typemaps. INOUT is now an alias for BOTH.
-
-6/12/2001: cheetah (william fulton)
- Some Java documentation added.
- [Java] Fixed bugs in import pragma and shadow pragma.
-
-6/12/2001: mkoeppe
- Fix declarations of SWIG_define_class
- (Lib/ruby/rubydec.swg) and SWIG_TypeQuery
- (Lib/common.swg). Thanks to Lyle Johnson
- <ljohnson@resgen.com> for the patches.
-
-6/11/2001: mkoeppe
- [Guile] Use long instead of scm_bits_t; this makes the
- generated wrapper code compatible with Guile 1.3.4
- again. Thanks to Masaki Fukushima for pointing this out.
-
-6/11/2001: cheetah (william fulton)
- The generic INSTALL file from autoconf added. Few changes to README file.
-
-6/11/2001: mkoeppe
- Fixed typo in Makefile.in; thanks to Greg Troxel
- <gdt@ir.bbn.com>.
-
-6/08/2001: cheetah (william fulton)
- make check works again. Examples/GIFPlot configure generated by
- top level autoconf now.
-
-6/08/2001: mkoeppe
- Another build change: The new script autogen.sh runs
- autoconf in the appropriate directories. The top-level
- configure also configures in Examples/GIFPlot.
-
-6/07/2001: mkoeppe
- Made the Makefile work with non-GNU make again.
-
-6/07/2001: cheetah (william fulton)
- [Java] Class/struct members that are arrays of pointers to classes/structs -
- Shadow class's get/set accessors now use Java classes instead of longs (pointers).
- [Java] Shadow classes will now clean up memory if function return type
- is a class/struct.
- [Java] New example called reference based on the same example from other modules.
-
-6/06/2001: mkoeppe
- New configure option --with-release-suffix allows for
- attaching a suffix to the swig binary and the swig runtime
- libraries. Minor changes to the build system. "swig
- -swiglib" works again. If invoked with the new option
- "-ldflags", SWIG prints a line of linker flags needed to
- link with the runtime library of the selected language
- module.
-
-6/06/2001: mkoeppe
- [Guile] gswig_list_p is an int, not a SCM. This typo
- caused warnings when compiling with a Guile configured with
- strict C type checking. In INPUT and BOTH typemaps
- generated by the SIMPLE_MAP macro, use the SCM_TO_C
- function to convert from Guile to C (rather than C_TO_SCM).
- Use scm_intprint to print pointers (rather than
- sprintf). Allow using "-linkage" instead of "-Linkage".
-
-6/05/2001: cheetah (william fulton)
- [Java] Mods for using inherited c++ classes from Java
- [Java] New example called class based on the same example from other modules
-
-6/05/2001: cheetah (william fulton)
- [Java] destructor (_delete()) was not aware of %name renaming
- [Java] extends baseclass did not know about %name renaming
- [Java] extends baseclass did extend even when the baseclass was not known to swig
- [Java] sometimes enum-declarations occurred before the Java class declaration
- [Java] unrelated enum initialisations no longer appear in Java class
- [Java] if module ends in '_' correct JNI names are now produced
-
-6/04/2001: cheetah (william fulton)
- [Java] Shadow class mods - Modified constructor replaces
- newInstance(). _delete() now thread safe. getCPtr() replaces
- _self. _selfClass() removed as now redundant.
- *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
-
- [Java] Not all output java files had SWIG banner. New banner.
-
- [Java] Shadow class finalizers are output by default: Command
- line option -finalize deprecated and replaced with -nofinalize.
- *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE ***
-
-6/ 1/2001: mkoeppe
- [Guile] Cast SCM_CAR() to scm_bits_t before shifting it.
- This is required for compiling with a Guile configured with
- strict C type checking.
-
-6/ 1/2001: mkoeppe
- Added configure option "--with-swiglibdir".
-
-5/31/2001: mkoeppe
- [Guile] Support multiple parallel lists or vectors in
- the typemaps provided by list-vector.i. New typemaps file,
- pointer-in-out.i.
-
-5/25/2001: cheetah (william fulton)
- [Java] HTML update for examples.
-
-5/28/2001: mkoeppe
- Minor changes to the build system. Added subdirectory for
- Debian package control files.
-
-5/28/2001: mkoeppe
- [Guile] Build a runtime library, libswigguile.
-
-5/28/2001: mkoeppe
- [Guile] New typemap substitution $*descriptor. Use the {}
- syntax, rather than the "" syntax for the standard
- typemaps, in order to work around strange macro-expansion
- behavior of the SWIG preprocessor. This introduces some
- extra braces.
-
-5/27/2001: mkoeppe
- [Guile] Handle pointer types with typemaps, rather than
- hard-coded. New typemap substitutions $descriptor,
- $basedescriptor; see documentation. Some clean-up in the
- variable/constants wrapper generator code. New convenience
- macro SWIG_Guile_MustGetPtr, which allows getting pointers
- from smobs in a functional style. New typemap file
- "list-vector.i", providing macros that define typemaps for
- converting between C arrays and Scheme lists and vectors.
-
-5/25/2001: cheetah (william fulton)
- [Java] STL string moved into its own typemap as it is c++ code and
- it break any c code using the typemaps.i file.
- - Fixes for wrappers around global variables - applies to primitive
- types and user types (class/struct) and pointers to these.
- - Structure member variables and class public member variables getters
- and setters pass a pointer to the member as was in 1.3a3 and 1.1
- (1.3a5 was passing by value)
- - Parameters that were arrays and return types were incorrectly
- being passed to create_function() as pointers.
- - Fix for arrays of enums.
- [Java] Updated java examples and added two more.
- [Java] Java module updated from SWIG1.3a3 including code cleanup etc.
- [Java] enum support added.
- [Java] Array support implemented
- [Java] Shadow classes improved - Java objects used rather than
- longs holding the c pointer to the wrapped structure/c++class
-
-5/22/2001: mkoeppe
- [Guile] Fixed extern "C" declarations in C++ mode. Thanks
- to Greg Troxel <gdt@ir.bbn.com>.
-
-5/21/2001: mkoeppe
- [Guile] New linkage "module" for creating Guile modules for
- Guile versions >= 1.5.0.
-
-4/18/2001: mkoeppe
- [MzScheme] Added typemaps for passing through Scheme_Object
- pointers.
-
-4/9/2001 : mkoeppe
- [MzScheme] Added typemaps for `bool'. Inclusion of headers
- and support routines is now data-driven via mzscheme.i.
- Headers come from the new file mzschemdec.swg. Don't abort
- immediately when a type-handling error is reported. When
- searching for typemaps for enums, fall back to using int,
- like the Guile backend does. Support char constants. Emit
- correct wrapper code for variables.
-
-3/12/2001: mkoeppe
- [Guile] Fixed typemaps for char **OUTPUT, char **BOTH.
-
-3/2/2001 : mkoeppe
- [Guile] Every wrapper function now gets a boolean variable
- gswig_list_p which indicates whether multiple values are
- present. The macros GUILE_APPEND_RESULT, GUILE_MAYBE_VALUES
- and GUILE_MAYBE_VECTOR use this variable, rather than
- checking whether the current return value is a list. This
- allows for typemaps returning a list as a single value (a
- list was erroneously converted into a vector or a
- multiple-value object in this case).
-
-3/1/2001 : mkoeppe
- [Guile] Added support for returning multiple values as
- vectors, or passing them to a muliple-value
- continuation. By default, multiple values still get
- returned as a list.
-
-3/1/2001 : mkoeppe
- [Guile] Added a "beforereturn" pragma. The value of this
- pragma is inserted just before every return statement.
-
-3/1/2001 : mkoeppe
- [Guile] Added support for Guile 1.4.1 procedure
- documentation formats, see internals.html.
-
-2/26/2001: mkoeppe
- [Guile] Made the wrapper code compile with C++ if the
- "-c++" command-line switch is given. Thanks to
- <monkeyiq@dingoblue.net.au>.
-
-2/26/2001: mkoeppe
- [Guile] Now two type tables, swig_types and
- swig_types_initial, are used, as all other SWIG language
- modules do. This removes the need for the tricky
- construction used before that the broken Redhat 7.0 gcc
- doesn't parse. Reported by <monkeyiq@dingoblue.net.au>.
-
-2/26/2001: mkoeppe
- [Guile] Fixed typemaps for char *OUTPUT, char *BOTH; a bad
- free() would be emitted. Added typemap for SCM.
-
-
-Version 1.3 Alpha 5
-===================
-
-9/19/00 : beazley
- [Python] Python module generates more efficient code for
- creating the return value of a wrapper function. Modification
- suggested by Jon Travis.
-
-9/19/00 : beazley
- Library files specified with the -l option are now included at the
- end of the interface file (reverting to the old behavior).
-
-9/19/00 : beazley
- Fixed some problems with enum handling. enums are now manipulated as
- 'int', but cast into the enum type when values are passed to the
- corresponding C function.
-
-9/19/00 : mkoeppe
- [Guile] Removed "-with-smobs" command-line option, as this is the
- default now. Added "-emit-setters" command-line option,
- which turns on generating procedures-with-setters; see
- internals.html.
-
-9/18/00 : mkoeppe
- Incorporated patch #101430, fixing bugs in the Guile module:
- 1. Some arguments were erroneously taken as *optional* arguments when
- ignored arguments were present.
- 2. Guile 1.3.4 was not supported since functions introduced in Guile
- 1.4 were used.
- 3. Added handling of `const char *'.
-
-9/17/00 : beazley
- Fixed problem with failed assertion and large files.
-
-9/17/00 : beazley
- Fixed problem with the '%' character appearing in added methods
- and function bodies. Preprocessor bug.
-
-Version 1.3 Alpha 4 (September 4, 2000)
-=======================================
-
-9/3/00 : ttn
- Added instructions for maintainers in Examples/README on how
- to make examples also be useful in the testing framework.
- Also, "make check" now uses ./Lib by via env var `SWIG_LIB'.
- This is overridable like so:
- make chk-swiglib=/my/experimental/swig/Lib check
-
-9/3/00 : beazley
- Added $typemap variable to typemaps. This gets replaced with
- a string indicating the typemap that is applied. Feature
- request from rsalz.
-
-9/3/00 : beazley
- Experimental optimization to code generation for virtual
- member functions. If you have two classes like this:
-
- class A() {
- virtual void foo();
- }
-
- class B() : public A {
- virtual void foo();
- }
-
- Swig now will generate a single wrapper function for this
-
- A_foo(A *a) {
- a->foo();
- }
-
- and use it as the implementation of both A_foo() and B_foo().
- This optimization only takes place if both methods are declared
- as virtual and both take identical parameters.
- *** EXPERIMENTAL FEATURE ***
-
-9/3/00 : beazley
- Restored the "memberin" typemap for setting structure members.
- Unlike the old version, the new version is expanded inline in the
- wrapper function allowing access to scripting language
- internals (a sometimes requested feature). The "memberout" typemap
- is gone. Use the "out" typemaps instead.
- *** POTENTIAL INCOMPATIBILITY ***
-
-9/3/00 : beazley
- Attribute set methods no longer return the value of a member.
- For example:
-
- struct Foo {
- int x;
- ...
- }
-
- now gets set as follows:
-
- void Foo_x_set(Foo *f, int x) {
- f->x = x;
- }
-
- In SWIG1.1 it used to be this:
-
- int Foo_x_set(Foo *f, int x) {
- return (f->x = x);
- }
-
- This has been changed due to the complexity created by trying
- to do this with more exotic datatypes such as arrays. It also
- complicates inlining and handling of the "memberin" typemap.
- *** POTENTIAL INCOMPATIBILITY ***
-
-9/2/00 : beazley
- Removed the ptrcast() and ptrmap() functions from the
- pointer.i library file. Old implementation is incompatible
- with new type system.
- *** POTENTIAL INCOMPATIBILITY ***
-
-9/2/00 : beazley
- New runtime function SWIG_TypeQuery(const char *name) added.
- This function can be used to extract the type info structure
- that is used for type-checking. It works with either the
- nice C name or mangled version of a datatype. For example:
-
- swig_type_info *ty = Swig_TypeQuery("int *");
- swig_type_info *ty = Swig_TypeQuery("_p_int");
-
- This is an advanced feature that has been added to support some
- exotic extension modules that need to directly manipulate
- scripting language objects.
- *** NEW FEATURE ***
-
-9/2/00 : beazley
- New directive %types() added. This is used to
- explicitly list datatypes that should be included in
- the runtime type-checking code. Normally it is never
- necessary to use this but sometimes advanced extensions
- (such as the pointer.i library) may need to manually
- add types to the type-checker.
- *** NEW FEATURE ***
-
-8/31/00 : beazley
- Improved handling of string array variables. For example,
- a global variable of the form "char name[64]" is automatically
- managed as a 64 character string. Previously this didn't
- work at all or required the use of a special typemap.
- *** NEW FEATURE (Tcl, Perl, Python) ***
-
-8/31/00 : ttn
- Added Makefile target `check-c++-examples', which uses new
- files under Examples/C++ contributed by Tal Shalif. Now "make
- check" also does "make check-c++-examples". Also, expanded
- actions in `check-gifplot-example' and `check-aliveness'.
-
-8/30/00 : mkoeppe
- Major clean-up in the Guile module. Added typemap-driven
- documentation system. Changed to handle more than 10
- args. Updated and extended examples.
- *** NEW FEATURE ***
-
-8/29/00 : beazley
- Added new %insert directive that inserts the contents of a file
- into a portion of the output wrapper file. This is only intended
- for use by writers of language modules. Works as follows:
-
- %insert(headers) "file.swg";
- %insert(runtime) "file.swg";
- %insert(wrappers) "file.swg";
- %insert(init) "file.swg";
-
- *** NEW FEATURE ***
-
-8/29/00 : beazley
- Added new %runtime directive which includes code into the runtime
- portion of the wrapper code. For example:
-
- %runtime %{
- ... some internal runtime code ...
- %}
-
- There is no practical reason for ordinary users to use this
- feature (almost everything can be done using %{ ... %}
- instead). However, writers of language modules may want to
- use this in language configuration files.
- *** NEW FEATURE ***
-
-8/28/00 : beazley
- Typemaps can now be specified using string literals like
- this:
-
- %typemap(in) int "$target = SvIV($source);"
-
- When code is specified like this, it is *NOT* enclosed
- inside a local scope (as with older typemap declarations).
- Note: character escape sequences are interpreted in the
- code string so if you want to include a quote or some
- other special character, make sure you use a (\).
- *** NEW FEATURE ***
-
-8/27/00 : beazley
- Typemaps have been modified to follow typedef declarations.
- For example, if you have this:
-
- typedef int Number;
-
- %typemap(in) int {
- ... get an integer ...
- }
-
- void foo(Number a);
-
- The typemap for 'int' will be applied to the argument 'Number a'.
- Of course, if you specify a typemap for 'Number' it will take
- precedence (nor will it ever be applied to an 'int').
- *** POTENTIAL INCOMPATIBILITY ***
-
-8/27/00 : beazley
- Default typemap specification has changed. In older
- versions of swig, you could do this:
-
- %typemap(in) int SWIG_DEFAULT_TYPE {
- ...
- }
-
- To specify the default handling of a datatype. Now that
- SWIG follows typedef declarations, this is unnecessary.
- Simply specifying a typemap for 'int' will work for all
- variations of integers that are typedef'd to 'int'.
-
- Caveat, specifying the default behavior for pointers,
- references, arrays, and user defined types is a little
- different. This must be done as follows:
-
- %typemap() SWIGPOINTER * {
- ... a pointer ...
- }
- %typemap() SWIGREFERENCE & {
- ... a reference ...
- }
- %typemap() SWIGARRAY [] {
- ... an array ...
- }
- %typemap() SWIGTYPE {
- ... a user-defined type (by value) ...
- }
- *** POTENTIAL INCOMPATIBILITY ***
-
-8/15/00 : dustin
- The file swig-1.3a1-1.spec has been added to the Tools directory.
- It can be used to build a redhat package for SWIG, although it
- will need to be updated for the next public release.
-
-8/15/00 : beazley
- Typemaps have been completely rewritten. Eventually they may be
- replaced with something better, but for now they stay. However,
- there are a number of a significant changes that may trip some
- people up:
-
- 1. Typemap scoping is currently broken. Because of this, the
- following code won't work.
-
- %typemap(in) blah * {
- ...
- }
- class Foo {
- ...
- int bar(blah *x);
- }
- %typemap(in) blah *; /* Clear typemap */
-
- (this breaks because the code for the class Foo is actually
- generated after the entire interface file has been processed).
- This is only a temporary bug.
-
- 2. In SWIG1.1, the %apply directive worked by performing a
- very complex type-aliasing procedure. From this point on,
- %apply is simply a generalized typemap copy operation.
- For example,
-
- %apply double *OUTPUT { double *x, double *y };
-
- Copies *ALL* currently defined typemaps for 'double *OUTPUT' and
- copies them to 'double *x' and 'double *y'.
-
- Most people probably won't even notice this change in
- %apply. However, where it will break things is in code like
- this:
-
- %apply double *OUTPUT { double *x };
- %typemap(in) double *OUTPUT {
- ... whatever ...
- }
-
- void foo(double *x);
-
- In SWIG1.1, you will find that 'foo' uses the 'double *OUTPUT' rule
- even though it was defined after the %apply directive (this is
- the weird aliasing scheme at work). In SWIG1.3 and later,
- the 'double *OUTPUT' rule is ignored because it is defined
- after the %apply directive.
-
- 3. The %clear directive has been modified to erase all currently
- defined typemaps for a particular type. This differs from
- SWIG1.1 where %clear only removed rules that were added using
- the %apply directive.
-
- 4. Typemap matching is now performed using *exact* types.
- This means that things like this
-
- %typemap(in) char * { }
- %typemap(in) const char * { }
-
- are different typemaps. A similar rule applies for pointers,
- arrays, and references. For example:
-
- %typemap(in) double * { }
-
- used to apply to 'double &', 'double []', Now, it only applies
- to 'double *'. If you want a 'double &', you'll need to handle
- that separately.
-
- 5. Array matching has been simplfied. In SWIG1.1, array matching
- was performed by trying various combinations of dimensions.
- For example, 'double a[10][20]' was matched as follows:
-
- double [10][20]
- double [ANY][20]
- double [10][ANY]
- double [ANY][ANY]
-
- In SWIG1.3, only the following matches are attempted:
-
- double [10][20]
- double [ANY][ANY]
-
- On the positive side, typemap matching is now *significantly* faster
- than before.
- *** POTENTIAL INCOMPATIBILITY ***
-
-8/15/00 : beazley
- Secret developer feature. Since datatypes are now represented as
- strings internally, you can bypass limitations of the parser and
- create a wild datatype by simply enclosing the raw string encoding
- in backticks (``) and sticking it in the interface file anywhere a
- type is expected. For example, `a(20).a(10).p.f(int,int)`. This
- feature is only intended for testing (i.e., you want to see what
- happens to your language module if it gets a reference to a pointer
- to an array of pointers to functions or something).
- *** SICK HACK ***
-
-8/14/00 : beazley
- Completely new type-system added to the implementation.
- More details later.
-
-8/11/00 : beazley
- Cleaned up some of the I/O handling. SWIG no longer generates
- any temporary files such as _wrap.wrap, _wrap.ii, _wrap.init.
- Instead, these "files" are kept around in memory as strings
- (although this is transparent to language modules).
-
-8/4/00 : ttn
- Added Makefile target "check" and variants.
- This can be used like "make check" or, to explicitly skip a
- language LANG: "make skip-LANG=true check". LANG is skipped
- automatically if ./configure determines that LANG support is
- insufficient.
-
- Currently, the check is limited to doing the equivalent of
- "make all" in some of the Examples directories. This should
- be expanded both horizontally (different types of tests) and
- vertically (after "make all" in an Examples subdir succeeds,
- do some additional tests with the resulting interpreter, etc).
-
-8/4/00 : ttn
- Added Makefile target "distclean", which deletes all the
- files ./configure creates, including config.status and friends.
-
-8/3/00 : harcoh
- java changes??? [todo: document changes]
-
-7/23/00 : beazley
- Typemaps have been modified to key off of the real datatypes
- used in the interface file. This means that typemaps for
- "const char *" and "char *" will be difference as will typemaps
- for "Vector" and "Vector *."
- *** POTENTIAL INCOMPATIBILITY ***
- This is likely to break interfaces that rely on the odd type
- handling behavior of typemaps in SWIG1.1--especially with
- respect to interfaces involving pass-by-value.
-
-7/23/00 : beazley
- New %constant directive. This directive can be used to
- create true constants in the target scripting language.
- It's most simple form is something like this:
-
- %constant FOO 42;
-
- In this case, the type is inferred from the syntax of the
- value (in reality, all #define macros are translated into
- directives of this form).
-
- An expanded version is as follows:
-
- %constant(Foo *) FOO = &FooObj;
-
- In this case, an explicit type can be specified. This
- latter form may be useful for creating constants that
- used to be specified as
-
- const Foo *FOO = &FooObj;
-
- (which are now treated as variables).
- *** EXPERIMENTAL FEATURE *** The syntax may change in
- the final release.
-
-7/23/00 : beazley
- Modified the parser so that variable declarations of the form
- "const type *a" are handled as variables, not constants.
- Note: SWIG1.1 handled this case erroneously because
- const char *a is a pointer variable that can be reassigned.
- *** POTENTIAL INCOMPATIBILITY ***
- Note: just because this is the "right" way to do things,
- doesn't mean it's the most appropriate interpretation.
- I suspect that many C programmers might use 'const char *'
- with the intent of creating a constant, without realizing
- that they've created a reassignable global variable.
-
-7/23/00 : beazley
- The C/C++ wrapping layer has been completely redesigned and
- reimplemented. This change should iron out a few rough
- spots with the handling of datatypes. In addition, the
- wrapper code is somewhat cleaner.
- *** POTENTIAL INCOMPATIBILITY ***
- This change may break interfaces that involve
- subtle corner-cases with typemaps and the %addmethods
- directive since some of these features had somewhat
- type handling behavior in SWIG1.1.
-
-7/23/00 : beazley
- The "memberin" and "memberout" typemaps are gone for the
- moment, but they might return as soon as I figure out
- how to integrate them with some of the streamlined C wrapper
- functions.
- *** POTENTIAL INCOMPATIBILITY ***
-
-7/22/00 : beazley
- A variety of old type handling functions such as print_type(),
- print_full(), print_mangle(), etc... are gone and have been
- replaced with a smaller set of functions. See the file
- Doc/internals.html for details. This will break all third
- party language modules.
- *** POTENTIAL INCOMPATIBILITY ***
-
-7/20/00 : beazley
- Deprecated the %val and %out directives. These directives
- shouldn't really be necessary since typemaps can be used
- to achieve similar results. This also cleans up the
- handling of types and parameters quite a bit.
- *** POTENTIAL INCOMPATIBILITY ***
-
-7/20/00 : ttn
- Fixed unspecified-module bug in Guile support and removed
- more non-"with-smobs" functionality using patches submitted
- by Matthias Koeppe.
-
- Re-enable recognition of "-with-smobs" (with no effect since
- we use smobs by default now) for the time being. After the
- 1.3a4 release, this option will signal an error.
-
-7/17/00 : ttn
- Fixed NULL-input bug in parameter list handling.
- Reported by Matthias Koeppe.
-
-7/12/00 : beazley
- Fixed memory leak in Python type-checking code. Reported by
- Keith Davidson. Bug #109379.
-
-7/10/00 : beazley
- Changed internal data structures related to function parameters.
-
-7/10/00 : beazley
- Fixed some bugs related to the handling of the %name() directive
- and classes in the Tcl module. Problem reported by James Bailey.
-
-7/10/00 : beazley
- Fixed parsing and enum handling problems with character constants.
- Reported by Greg Kochanski.
-
-7/10/00 : beazley
- Removed WrapperFunction class from the core and updated the language
- module. This will break third party modules.
- *** POTENTIAL INCOMPATIBILITY ***
-
-7/9/00 : beazley
- Implementation of SWIG no longer makes use of C++ operator overloading.
- This will almost certainly break *all* third party language modules
- that are not part of the main SWIG CVS tree. Sorry.
- *** POTENTIAL INCOMPATIBILITY ***
-
-7/8/00 : beazley
- Removed the experimental and undocumented "build" typemap that
- was intended to work with multiple arguments. Simply too weird
- to keep around. Besides, a better replacement is in the works.
-
-7/6/00 : ttn
- Removed non-"with-smobs" functionality (Guile support), i.e.,
- "-with-smobs" is now the default and no longer needs to be
- specified on the command-line.
-
-7/5/00 : ttn
- Incorporated Ruby support contributed by Masaki Fukushima.
-
-6/28/00 : ttn
- Applied more-than-10-args bugfix patch contributed
- by Matthias Koeppe.
-
-6/27/00 : beazley
- Rewrote some of the string handling and eliminated the C++
- implementation (which is now just a wrapper).
-
-6/27/00 : ttn
- Added Doc/index.html and Doc/internals.html. The target
- audience for the latter is new SWIG developers.
-
-
-Version 1.3 Alpha 3 (June 18, 2000)
-===================================
-
-6/18/00 : beazley
- Removed the naming.cxx, hash.cxx, and symbol.cxx files from
- the SWIG1.1 directory. Continued to migrate things away
- from the C++ base (although there's still a lot of work to do).
-
-6/17/00 : beazley
- Added a few more examples to the Examples directory. Still
- need to do a lot of work on this.
-
-6/16/00 : beazley
- Added -includeall to follow all #include statements in the
- preprocessor.
-
-6/15/00 : beazley
- Tried to fix as many C++ warnings as possible when compiling
- with the Sun Workshop C++ compiler. Unfortunately, this means
- that there are a lot of statements that contain string literals
- of the form (char*)"Blah".
-
-6/15/00: beazley
- A variety of cleanup and performance optimization in the
- low-level DOH library. This seems to result in a speedup
- of 50-100% for preprocessing and other related tasks.
-
-5/10/00 : ttn
- Applied variable-wrapping bugfix patch contributed
- by Matthias Koeppe.
-
-4/17/00 : ttn
- Updated MzScheme support contributed by Oleg Tolmatcev.
- We now use a `Scheme_Type'-based structure to wrap pointers.
-
-4/11/00 : ttn
- Incorporated further Guile-support patch by Matthias Koeppe.
- Typemaps previously deleted have been re-added. There is now
- exception handling (see Doc/engineering.html). `SWIG_init' is now
- declared extern only for simple linkage. Some bugs were fixed.
-
-4/06/00 : ttn
- Incorporated MzScheme support contributed by Oleg Tolmatcev.
- This includes new directories Lib/mzscheme and Examples/mzscheme.
-
-4/03/00 : ttn
- Added Examples/guile and children. This is an adaptation of
- the same-named directory from the SWIG-1.1p5 distribution.
- Added Guile-specific section to Doc/engineering.html.
-
-4/02/00 : ttn
- Incorporated new guilemain.i by Martin Froehlich.
- Incorporated Guile-support rewrite patch by Matthias Koeppe.
- The command line option "-with-smobs" enables implementation of
- pointer type handling using smobs, the canonical mechanism for
- defining new types in Guile. Previous implementation (using
- strings) is at the moment still supported but deprecated. At
- some point, "-with-smobs" will be the default and no longer
- required.
-
-3/13/00 : beazley
- Added purify patches submitted by Ram Bhamidipaty.
-
-3/02/00 : ttn
- Added support for different Guile "linkage" schemes.
- Currently, "-Linkage hobbit" works.
-
-
-Version 1.3 Alpha 2 (March 1, 2000)
-===================================
-
-2/29/00 : beazley
- Made SWIG ignore the 'mutable' keyword.
-
-2/29/00 : beazley
- Incorporated some patches to the Perl5 module related to
- the -hide option and the destruction of objects.
- Patch submitted by Karl Forner.
-
-2/27/00 : ttn
- Incorporated Guile support contributed by Matthias Koeppe.
- This includes a cpp macro in Lib/guile/guile.swg and the
- entire file Lib/guile/typemaps.i.
-
-2/25/00 : ttn
- Modified configure.in and Makefile.in files to support
- non-local build (useful in multi-arch environments).
-
-2/24/00 : ttn
- Incorporated Guile support contributed by Clark McGrew.
- This works with Guile 1.3, but since it depends heavily
- on the gh_ interface, it should work for all later versions.
- It has not been tested with versions before 1.3.
- WARNING: Code is unstable due to experimentation by ttn.
-
-2/16/00 : beazley
- A variety of performance improvements to the Python shadow
- class code generation. Many of these result in substantial
- runtime performance gains. However, these have come at
- a cost of requiring the use of Python 1.5.2. For older
- versions, use 'swig -noopt -python' to turn off these
- optimization features.
-
-Version 1.3 Alpha 1 (February 11, 2000)
-=======================================
-
-2/11/00 : Added 'void' to prototype of Python module initializer.
- Reported by Mark Howson (1/20/00).
-
-2/11/00 : beazley
- Modified the Python shadow class code to discard ownership of an
- object whenever it is assigned to a member of another object.
- This problem has been around for awhile, but was most recently
- reported by Burkhard Kloss (12/30/99).
-
-2/11/00 : beazley
- Added braces around macros in the exception.i library. Reported
- by Buck Hodges (12/19/99)
-
-2/11/00 : beazley
- Fixed bug in the constraints.i library. Reported by Buck
- Hodges (12/14/99)
-
-2/11/00 : beazley
- The %native directive now generates Tcl8 object-style command calls.
- A full solution for Tcl7 and Tcl8 is still needed. Patch suggested
- by Mike Weiblen (11/29/99)
-
-2/11/00 : beazley
- Modified the typemap code to include the $ndim variable for arrays.
- Patch provided by Michel Sanner (11/12/99).
-
-2/11/00 : beazley
- Modified the Python module to raise a Runtime error if an attempt
- is made to set a read-only member of a shadow class. Reported by
- Michel Sanner (11/5/99).
-
-2/10/00 : The documentation system has been removed. However, it is likely
- to return at some point in the future.
-
-2/1/00 : Added a number of performance enhancements to the Python shadow
- classing and type-checking code. Contributed by Vadim Chugunov.
-
- 1. Remove _kwargs argument from the shadow wrappers when -keyword
- option is not specified. This saves us a construction of keyword
- dictionary on each method call.
-
- def method1(self, *_args, **_kwargs):
- val = apply(test2c.PyClass1_method1, (self,) + _args, _kwargs)
- return val
-
- becomes
-
- def method1(self, *_args):
- val = apply(test2c.PyClass1_method1, (self,) + _args)
- return val
-
- 2. Incorporate self into the _args tuple. This saves at least one tuple
- allocation per method call.
-
- def method1(self, *_args):
- val = apply(test2c.PyClass1_method1, (self,) + _args)
- return val
-
- becomes
-
- def method1(*_args):
- val = apply(test2c.PyClass1_method1, _args)
- return val
-
- 3. Remove *Ptr classes.
- Assume that we are SWIGging a c++ class CppClass.
- Currently SWIG will generate both CppClassPtr class
- that hosts all methods and also CppClass that is derived
- from the former and contains just the constructor.
- When CppClass method is called, the interpreter will try
- to find it in the CppClass's dictionary first, and only then
- check the base class.
-
- CppClassPtr functionality may be emulated with:
-
- import new
- _new_instance = new.instance
- def CppClassPtr(this):
- return _new_instance(CppClass, {"this":this,"thisown":0})
-
- This saves us one dictionary lookup per call.
-
- <DB>The new module was first added in Python-1.5.2 so it
- won't work with older versions. I've implemented an
- alternative that achieves the same thing</DB>
-
- 4. Use CObjects instead of strings for pointers.
-
- Dave: This enhancements result in speedups of up to 50% in some
- of the preliminary tests I ran.
-
-2/1/00 : Upgraded the Python module to use a new type-checking scheme that
- is more memory efficient, provides better performance, and
- is less error prone. Unfortunately, it will break all code that
- depends on the SWIG_GetPtr() function call in typemaps.
- These functions should be changed as follows:
-
- if (SWIG_GetPtr(string,&ptr,"_Foo_p")) {
- return NULL;
- }
-
- becomes
-
- if (SWIG_ConvertPtr(pyobj, &ptr, SWIG_TYPE_Foo_p) == -1) {
- return NULL;
- }
-
- Note: In the new implementation SWIG_TYPE_Foo_p is no longer
- a type-signature string, but rather an index into a type
- encoding table that contains type information.
- *** POTENTIAL INCOMPATIBILITY ***
-
-1/30/00 : loic
- Conditionally compile experimental code with --enable-experiment
- configure flag.
- Fix .cvsignore to ignore configure & yacc generated files
-
-1/28/00 : loic
- Apply automake everywhere
- Keep configure scripts so that people are not *forced* to autoconf
- Keep sources generated by yacc so that compilation without yacc
- is possible.
- Source/LParse/cscanner.c: change lyacc.h into parser.h to please
- default yacc generation rules.
- Use AC_CONFIG_SUBDIRS in configure.in instead of hand made script.
- Update all relevant .cvsignore to include .deps
- Fixed missing ; line 136 Source/Swig/swig.h
-
-1/13/00 : beazley
- Fixed a number of minor end-of-file parsing problems in the
- preprocessor.
-
-1/13/00 : beazley
- Added -freeze option that forces SWIG to freeze upon exit.
- This is only used as a debugging tool so that I can more
- easily examine SWIG's memory footprint.
-
-1/13/00 : beazley
- Added patch to guile module for supporting optional arguments
- Patch contributed by Dieter Baron.
-
-1/13/00 : loic
- Added .cvsignore, Examples/.cvsignore, Source/DOH/Doh/.cvsignore
- Source/SWIG1.1/main.cxx: Fixed -I handling bug
- Source/Modules1.1/java.cxx: fixed char* -> const char* warnings that are
- errors when compiling with gcc-2.95.2
- Source/SWIG1.1/main.cxx: cast const char* to char* for String_replace
- token and rep should really be const.
-
-1/12/00 : beazley
- Added Harco's Java modules.
-
-1/12/00 : beazley
- Revoked the %ifdef, %ifndef, %endif, %if, %elif, and %else
- directives. These are no longer needed as SWIG now has a real
- preprocessor.
- *** POTENTIAL INCOMPATIBILITY ***
-
-1/12/00 : beazley
- Moved the documentation modules from the SWIG directory
- to the Modules directory (where they really should have been
- to begin with).
-
-1/12/00 : beazley
- Removed the -stat option for printing statistics. The
- statistics reporting was inadequate and mostly broken
- anyway.
- *** POTENTIAL INCOMPATIBILITY ***
-
-1/12/00 : beazley
- Removed the -t option for reading a typemap file. More
- trouble than it's worth. Just include typemaps at the top
- of the interface file.
- *** POTENTIAL INCOMPATIBILITY ***
-
-1/12/00 : beazley
- Removed the %checkout directive.
- *** POTENTIAL INCOMPATIBILITY ***
-
-1/12/00 : beazley
- Removed the -ci option for file checkin. Too problematic
- to implement. Probably better to just put your SWIG library
- under CVS instead.
- *** POTENTIAL INCOMPATIBILITY ***.
-
-1/11/00 : beazley
- Deleted the LATEX module. Sorry... Didn't know anyone
- who was using it. Besides, I'm looking to simplify
- the documentation system.
- *** POTENTIAL INCOMPATIBILITY ***
-
-1/11/00 : beazley
- Modified the ASCII documentation module to use a .txt
- suffix for its output file instead of .doc.
-
-1/11/00 : beazley
- Added the long-lost SWIG preprocessor back to the system.
- It should be enabled by default. Raw preprocessed output
- can be viewed using swig -E file.i.
- *** NEW FEATURE ***
-
-1/11/00 : beazley and djmitche
- Completely reorganized the SWIG directory structure. The
- basic organization is now:
-
- Source/ SWIG source code
- Lib/ SWIG library files (swig_lib)
- Doc/ Documentation
- Examples/ Examples
-
- More directories will be added as needed.
-
-12/08/99: Loic Dachary (loic@senga.org)
- Enhanced package handling for perl5 and c++.
-
- With new option -hide Foo::Bar, every perl5 object (Frob) is
- qualified by Foo::Bar::Frob. The package name is solely used
- to encapsulate C/C++ wrappers output in <module>_wrap.c and the
- corresponding perl package in <module>.pm. Note that a package
- name may contain :: (Frob::Nitz) and will be relative to the
- package name provided by -hide (Foo::Bar::Frob::Nitz).
-
- In *_wrap.c, SWIG_init macro is used. Was previously defined
- but not used and simplifies code.
-
- Added typemap(perl5,perl5in) and typemap(perl5,perl5out) that
- do the equivalent of typemap(perl5,in) and typemap(perl5,out)
- but contain perl code and applies to wrappers generated by
- -shadow.
-
- Lacking proper regression tests I used
- Examples/perl5/{c++,constraint,defarg,except,
- graph/graph[1234],multinherit,nested,shadow,simple,tree,
- typemaps/{argv,argv2,arraymember,database,file,ignore,integer,
- output,passref,reference,return}}/. I ran swig with and without
- the patches, diff the generatedsources, run the .pl files
- and checked that the results are identical. In all those examples
- I had no error.
-
-11/21/99: Modified the Tcl module to provide full variable linking capabilities
- to all datatypes. In previous versions, a pair of accessor functions
- were created for datatypes incompatible with the Tcl_LinkVar() function.
- Now, we simply use variable traces to support everything. This may
- break scripts that rely upon the older behavior.
- *** POTENTIAL INCOMPATIBILITY ***
-
-11/21/99: Added slight tweak to wrapper generator to collect local variables
- of similar type. Produces somewhat more compact wrapper code.
-
-11/20/99: Modified the Tcl module to use SWIG_GetArgs() to parse
- arguments. This is a technique borrowed from Python in which
- arguments are converted using a format string convention similiar
- to fprintf(). This results in a *substantial* reduction in the
- size of the resulting wrapper code with only a modest runtime overhead
- in going through the extra conversion function.
-
-11/13/99: Completely rewrote the class/structure generation code for the
- Tcl module. Now, a small set of runtime functions are used
- to implement the functionality for all classes (instead of a
- massive amount of runtime code being generated for each class).
- Class specific information is simply encoded in a series of
- static tables. This results in a *HUGE* reduction in wrapper
- code size--especially for C++.
-
-11/13/99: Removed the -tcl (Tcl 7.x) module. Tcl 8.0 is now several
- years old and the defacto standard--no real reason to keep
- supporting the old version at this point.
-
-11/13/99: Cleaned up -c option for Python module. The pyexp.swg file
- is now gone.
-
-11/13/99: Fixed external declarations to work better with static linking
- on Windows. Static linking should now be possible by defining
- the -DSTATIC_LINK option on the command line. Patch contributed
- by Alberto Fonseca.
-
-11/5/99 : Fixed an obscure code generation bug related to the generation
- of default constructors. Bug reported by Brad Clements.
-
-11/5/99 : Fixed a few memory problems found by purify.
-
-11/5/99 : Officially deprecated the -htcl, -htk, and -plugin options
- from the Tcl and Tcl8 modules.
-
-10/26/99: Removed unused variable from python/typemaps.i. Patch
- contributed by Keith Davidson.
-
-8/16/99 : Added _WIN32 symbol to libraries to better support Windows.
-
-8/16/99 : Deprecated the Perl4 module. It is no longer included in the
- distribution and no longer supported. In the entire 3 years SWIG
- has been around I never received a single comment about it so I'm
- assuming no one will miss it...
-
-8/16/99 : Modified the type-checking code to register type mappings using a
- table instead of repeated calls to SWIG_RegisterMapping(). This
- reduces the size of the module initialization function somewhat.
-
-8/15/99 : Cleaned up the pointer type-checking code in the Tcl module.
-
-8/15/99 : Many changes to the libraries to support runtime libraries.
-
-8/13/99 : Eliminated C++ compiler warning messages about extern "C" linkage.
-
-8/13/99 : Some cleanup of Python .swg files to better support runtime libraries
- on Windows.
-
-8/13/99 : Modified the %pragma directive to attach pragmas declared inside
- a class definition to the class itself. For example:
-
- class foo {
- ...
- %pragma(python) addtomethod = "insert:print `hello world'"
- ...
- }
-
- Most people don't need to worry about how this works. For people
- writing backend modules, class-based pragmas work like this:
-
- lang->cpp_open_class() // Open a class
- lang->cpp_pragma() // Supply pragmas
- ... // Emit members
-
- lang->cpp_close_class() // Close the class
-
- All of the pragmas are passed first since they might be used to
- affect the code generation of other members. Please see
- the Python module for an example. Patches contributed
- by Robin Dunn.
-
-8/13/99 : Patch to Python shadow classes to eliminate ignored
- exception errors in destructors. Patch contributed
- by Robin Dunn.
-
-8/11/99 : Minor patch to swig_lib/python/swigptr.swg (added SWIGSTATIC
- declaration). Patch contributed by Lyle Johnson.
-
-8/11/99 : Added FIRSTKEY/NEXTKEY methods to Perl5 shadow classes
- Patch contributed by Dennis Marsa.
-
-8/11/99 : Modified Python module so that NULL pointers are returned
- and passed as 'None.' Patch contributed by Tal Shalif.
-
-8/10/99 : Fixed missing 'int' specifiers in various places.
-
-8/10/99 : Added Windows makefile for Runtime libraries. Contributed
- by Bob Techentin.
-
-8/10/99 : Fixed minor problem in Python runtime makefile introduced
- by keyword arguments.
-
-8/8/99 : Changed $target of perl5(out) typemap from ST(0) to
- ST(argvi). Patch contributed by Geoffrey Hort.
-
-8/8/99 : Fixed bug in typemap checking related to the ANY keyword
- in arrays and ignored arguments. Error reported by
- Geoffrey Hort.
-
-8/8/99 : %enabledoc and %disabledoc directives can now be used
- inside class/structure definitions. However, no check
- is made to see if they are balanced (i.e., a %disabledoc
- directive inside a class does not have to have a matching
- %enabledoc in the same class).
-
-8/8/99 : Keyword argument handling is now supported in the Python
- module. For example:
-
- int foo(char *bar, int spam, double x);
-
- Can be called from Python as
-
- foo(x = 3.4, bar="hello", spam=42)
-
- To enable this feature, run SWIG with the '-keyword' command
- line option. Mixing keyword and default arguments
- should work as well. Unnamed arguments are assigned names
- such as "arg1", "arg2", etc...
-
- *** POTENTIAL INCOMPATIBILITY ***
- Functions with duplicate argument names such as
- bar(int *OUTPUT, int *OUTPUT) will likely cause problematic
- wrapper code to be generated. To fix this, use different
- names or use %apply to map typemaps to alternate names.
-
-8/8/99 : Handling of the 'this' pointer has been changed in Python shadow
- classes. Previously, dereferencing of '.this' occurred in the
- Python shadow class itself. Now, this step occurs in the C
- wrappers using the following function:
-
- SWIG_GetPtrObj(PyObject *, void **ptr, char *type)
-
- This function can accept either a string containing a pointer
- or a shadow class instance with a '.this' attribute of
- appropriate type. This change allows the following:
-
- 1. The real shadow class instance for an object is
- passed to the C wrappers where it can be examined/modified
- by typemaps.
-
- 2. Handling of default/keyword arguments is now greatly
- simplified.
-
- 3. The Python wrapper code is much more simple.
-
- Plus, it eliminated more than 300 lines of C++ code in the
- Python module.
-
- *** CAVEAT : This requires the abstract object interface.
- It should work with Python 1.4, but probably nothing older
- than that.
-
-
-8/8/99 : Fixed handling of "const" and pointers in classes. In particular,
- declarations such as
-
- class foo {
- ...
- const char *msg;
- const int *iptr;
- }
-
- are handled as assignable variables as opposed to constant
- values (this is the correct behavior in C/C++). Note:
- declarations such as "char *const msg" are still unsupported.
- Constants declared at the global level using const are also
- broken (because I have a number of interfaces that rely upon
- this behavior).
-
- *** POTENTIAL INCOMPATIBILITY *** This may break interfaces that
- mistakenly treat 'const char *' types as constant values.
-
-8/8/99 : Modified the parser to support bit-fields. For example:
-
- typedef struct {
- unsigned int is_keyword : 1;
- unsigned int is_extern : 1;
- unsigned int is_static : 1;
- } flags;
-
- Bit-fields can only be applied to integer types and their
- are other restrictions. SWIG performs no such type-checking
- (although the C compiler will catch problems when it tries to
- compile the wrapper code).
-
-8/8/99 : Removed trailing space of $basetype substitution in typemaps.
- This is to allow things like this:
-
- %typemap(python, argout) spam** OUTPUT{
- ...
- char* a = "$basetype_p";
- ...
- }
-
- (Patch suggested by Nathan Dunfield).
-
-6/22/99 : Made a very slight tweak to the Perl5 shadow class
- code that allows typemaps to alter the return type
- of objects (to support polymorphic types). Patch
- contributed by Drake Diedrich.
-
-4/8/99 : Fixed null pointer handling bug in Perl module.
- Patch contributed by Junio Hamano.
-
-3/17/99 : Fixed bug in perl5ptr.swg for ActiveState Perl.
- Patch contributed by Greg Anderson.
-
-2/27/99 : Eliminated segmentation fault when Swig runs on
- empty files.
-
-2/27/99 : Added patch to Guile module to eliminate unused
- variables. Contributed by Mike Simons.
-
-2/27/99 : Fixed problem with %addmethods returning references.
-
-2/27/99 : Fixed Runtime/Makefile. Patch contributed by
- Mike Romberg.
-
-2/27/99 : Incorporated patches to the type-checker.
-
-2/27/99 : Fixed problem with -exportall switch and shadow classes
- in Perl5 module. Patch contributed by Dennis Marsa.
-
-2/27/99 : Modified Perl5 module to recognize 'undef' as a NULL char *.
- Patch contributed by Junio Hamano.
-
-2/27/99 : Fixed the Perl5 module to support the newer versions of
- ActiveState Perl for Win32.
-
-2/27/99 : Fixed the include order of files specified with the
- -I option.
-
-2/5/98- : Dave finishes his dissertation, goes job hunting, moves to
-2/5/99 Chicago and generally thrashes about.
-
-Version 1.1 Patch 5 (February 5, 1998)
-======================================
-
-2/4/98 : Fixed a bug in the configure script when different package
- locations are specified (--with-tclincl, etc...).
-
-2/2/98 : Fixed name-clash bug related to the switch to C macros for accessor
- functions. The new scheme did not work correctly for objects
- with members such as 'obj', 'val', etc... Fixed the bug by
- appending the word 'swig' to macro argument names. Patch
- contributed by Rudy Albachten.
-
-2/2/98 : Slight fix to the Perl5 module to eliminate warning messages
- about 'varname used only once : possible typo'. Fix
- contributed by Rudy Albachten.
-
-1/9/98 : Fixed a bug in the Perl 5 module related to the creation of
- constants and shadow classes.
-
-1/9/98 : Fixed linking bug with Python 1.5 embed.i library file.
-
-Version 1.1 Patch 4 (January 4, 1998)
-=====================================
-
-1/4/98 : Changed structured of the Examples directory to be more friendly
- to Borland C++.
-
-1/4/98 : Added the function Makefile.win.bc for compiling the examples
- under Borland 5.2.
-
-1/4/98 : Slight change to the perl5 module and C++ compilation. The
- <math.h> library is now included before any Perl headers
- because Perl the extern "C" linkage of math.h screws alot
- of things up (especially on Windows).
-
-1/2/98 : Change to the Python module that reduces the number of constants
- created by C++ classes, inheritance, and shadow classes. This
- modification may introduce a few slight incompatibilities if
- you attempt to use the non-shadow class interface with shadow
- classes enabled. Patch contributed by Mike Romberg.
-
-1/2/98 : Support for Tcl 8.0 namespaces has been added. This *replaces*
- the original SWIG mechanism that assumed [incr Tcl] namespaces.
- To use namespaces, simply run SWIG with the following options
-
- swig -tcl -namespace foo.i
-
- This places everything in a namespace that matches
- the module name
-
- swig -tcl -namespace -prefix bar foo.i
-
- This places everything in the namespace 'bar'
-
- The use of namespaces is new in Tcl 8.0. However, the wrapper code
- generated by SWIG will still work with all versions of Tcl newer
- than and including Tcl 7.3/Tk3.6 even if the -namespace option is
- used.
-
- *** POTENTIAL INCOMPATIBILITY ***
- This change may break existing applications that relied on the
- -prefix and -namespace options.
-
-1/2/98 : Added the following constants to the Tcl wrapper code
-
- SWIG_name - Name of the SWIG module
- SWIG_prefix - Prefix/namespace appended to command names
- SWIG_namespace - Name of the namespace
-
- SWIG library writers can use these to their advantages.
-
-1/2/98 : Fixed a bug in the Tcl8 module related to the creation of
- pointer constants (the function SWIG_MakePtr was missing from
- the wrapper code).
-
-1/2/98 : Added the consthash.i library file to the Tcl and Tcl8 modules.
-
-1/1/98 : Changed and cleaned up the Python typemaps.i file. The following
- significant changes were made :
-
- 1. The OUTPUT typemap now returns Python tuples instead of
- lists. Lists can be returned as before by using the
- L_OUTPUT type. If compatibility with older versions
- is needed, run SWIG with the -DOUTPUT_LIST option.
-
- 2. The BOTH typemap has been renamed to INOUT. For backwards
- compatibility, the "BOTH" method still exists however.
-
- 3. Output typemaps now generate less code than before.
-
- Changes to typemaps.i may break existing Python scripts that assume
- output in the form of a list.
- *** POTENTIAL INCOMPATIBILITY ***
-
-12/31/97: Fixed long overdue problems with the testing scripts and certain
- makefiles that required the use of the bash shell. Everything should
- work properly with the standard Bourne shell (sh) now.
-
-12/31/97: Modified typemaps to allow $basetype as a valid local variable.
- This allows for all sorts of bizarre hackish typemaps that
- do cool things. Patch contributed by Dominique Dumont.
-
-12/31/97: Switched accessor functions generated for member data to
- C preprocessor macros (except in cases involving typemaps
- or char *).
-
-12/31/97: Fixed a bug related to C++ member data involving references.
-
-12/31/97: Changed accessor functions for C++ member functions to
- preprocessor macros. This cleans up the wrapper code
- and results in fewer function definitions.
-
-12/31/97: Changed the default C constructor to use calloc() instead
- of malloc()
-
-12/30/97: Changed the creation of constants in the Perl5 module.
- For all practical purposes, they should work in exactly the
- same way as before except that they now require much less
- wrapper code. Modules containing large numbers of
- constants may see greater than a 50% reduction in wrapper
- code size.
-
-12/30/97: Modified the Python module to be more intelligent about the
- creation of constants. SWIG no longer generates redundant
- global variables and the size of the module initialization
- function should be reduced. (Many thanks to Jim Fulton).
-
-12/29/97: Fixed a bug in C++ code generation related to member functions,
- default arguments, and references.
-
-12/29/97: Fixed configure script and a few makefiles to support Python 1.5
-
-12/29/97: Added 'embed15.i' library file. This file should be used to
- statically link versions of Python 1.5. To make it the default,
- simply copy 'swig_lib/python/embed15.i' to 'swig_lib/python/embed.i'
-
-Version 1.1 Patch 3 (November 24, 1997)
-========================================
-
-11/23/97: Fixed a bug in the Perl5 module with shadow classes and
- static class functions that return class instances.
- Note : The fix for this bug requires a slight restructuring of
- of the .pm files created by SWIG.
-
-11/23/97: Fixed a bug in the Tcl/Tcl8 modules related to variable linking
- of character arrays. If you declared a global variable 'char foo[10]',
- the generated wrapper code would either cause a segmentation fault
- immediately upon loading or weird memory corruption elsewhere.
- This should now be fixed although character arrays can only be
- read-only.
-
-11/23/97: Fixed a bug with the %import directive that caused it to
- fail if files were imported from directories other than
- the current working directory.
-
-11/23/97: Fixed incorrect diagnostic message in the ASCII documentation
- module.
-
-11/23/97: Changed the behavior of the -o option when used with shadow
- classes. If -o was used to specify both the pathname and filename
- of SWIG's output such as
-
- swig -o /home/swig/wrapper.c -shadow -perl5 foo.i
-
- The wrapper code would be placed the file specified with -o,
- but the .pm file and documentation would be placed in the
- directory where SWIG was run. Now, these files are placed
- in the same directory as the file specified with the -o option.
- This change is also needed for proper operation on the
- Macintosh.
-
-11/23/97: Added a 'this()' method to Perl5 shadow classes. This can
- be used to return the normal pointer value from a shadow
- class that is represented as a tied hash. To use just
- invoke as a method like this :
-
- $l = new List; # Create an object
- $ptr = $l->this(); # Get the normal pointer value
-
- *** NEW FEATURE ***
-
-11/23/97: Fixed the Tcl 8 pointer.i library file (which was completely
- broken in 1.1p2).
-
-11/23/97: Modified the Perl5 type-checker to fix a few problems
- with global variables of pointer types and to allow
- tied hashes to be used interchangably with normal
- pointer values.
-
-11/23/97: Modified the typemap mechanism to allow output
- typemaps of type 'void'. These were ignored previously,
- but now if you specify,
-
- %typemap(lang,out) void {
- ... return a void ...
- }
-
- You can change or assign a return value to the function.
-
-11/23/97: Fixed processing of 'bool' datatypes in the Python module.
-
-11/23/97: Fixed minor parsing error with C++ initializers. For example,
-
- class B : public A {
- public:
- B() : A() { ... };
- ...
- }
-
-11/23/97: Fixed the Tcl8 module so that C functions that call back into
- Tcl don't corrupt the return result object (SWIG was gathering
- the result object too early which leads to problems if subsequent
- Tcl calls are made).
-
-11/23/97: Fixed a code generation bug in the Python module when two or
- more output parameters were used as the first arguments of a
- function. For example :
-
- %include typemaps.i
- void foo(double *OUTPUT, double *OUTPUT, double a);
-
- Previously, doing this resulted in the creation of an
- extraneous comma in the output, resulting in a C syntax error.
-
-11/22/97: Fixed a bug when template handling that was stripping whitespace
- around nested templates. For example :
-
- Foo<Bar<double> >
-
- was getting munged into Foo<Bar>> which is a syntax error in
- in the C++ compiler.
-
-11/22/97: Fixed bugs in the Borland C++ makefiles.
-
-11/22/97: Fixed memory corruption bug when processing integer
- arguments in Tcl8 module.
-
-11/21/97: Fixed a bug in the Runtime/Makefile related to Tcl 8.
-
-11/21/97: Fixed a bug with the %new directive and Perl5 shadow classes.
- No longer generates a perl syntax error.
-
-11/9/97 : Changed a strncpy() to strcpy() in the pointer type-checker.
- This results in a substantial performance improvement in
- type-checking.
-
-10/29/97: Fixed a bug in the code generation of default arguments and
- user-defined types. For example :
-
- void foo(Vector a, Vector b = d);
-
- should now work properly.
-
-Version 1.1 Patch 2 (September 4, 1997)
-=======================================
-
-9/4/97 : Fixed problem with handling of virtual functions that
- was introduced by some changes in the C++ module.
-
-Version 1.1 Patch 1 (August 27, 1997)
-=====================================
-
-8/26/97 : Fixed compilation and run-time bugs with Tcl 8.0 final.
-
-8/21/97 : Fixed code generation bug with arrays appearing as arguments
- to C++ member functions. For example :
-
- class Foo {
- public:
- void Bar(int a[20][20]);
- };
-
- There is still a bug using arrays with added methods
- however.
-
-8/20/97 : Fixed a bug with generating the code for added methods
- involving pass-by-value.
-
-8/19/97 : Modified the typemapper to substitute the '$arg' value
- when declaring local variables. For example :
-
- %typemap(in) double * (double temp_$arg) {
- ... do something ...
- }
-
- When applied to a real function such as the following :
-
- void foo(double *a, double *b, double *result);
-
- three local variables will be created as follows :
-
- double temp_a;
- double temp_b;
- double temp_result;
-
- This can be used when writing multiple typemaps that need
- to access the same local variables.
-
-
-7/27/97 : Fixed a variety of problems with the %apply directive and arrays.
- The following types of declarations should now work :
-
- %apply double [ANY] { Real [ANY] };
- %apply double [4] { double [10] };
-
- A generic version of apply like this :
-
- %apply double { Real };
-
- should now work--even if arrays involving doubles and Reals are
- used later.
-
-7/27/97 : Changed warning message about "Array X has been converted to Y" to
- only appear if running SWIG in verbose mode.
-
-7/27/97 : Added the variables $parmname and $basemangle to the typemap
- generator. $parmname is the name of the parameter used
- when the typemap was matched. It may be "" if no parameter
- was used. $basemangle is a mangled version of the base
- datatype. Sometimes used for array handling.
-
-7/27/97 : Changed the behavior of output arguments with Python shadow classes.
- Originally, if a function returned an object 'Foo', the shadow class
- mechanism would create code like this :
-
- def return_foo():
- val = FooPtr(shadowc.return_foo())
- val.this = 1
- return val
-
- The problem with this is that typemaps allow a user to redefine
- the output behavior of a function--as a result, we can no longer
- make any assumptions about the return type being a pointer or
- even being a single value for that matter (it could be a list,
- tuple, etc...). If SWIG detects the use of output typemaps
- (either "out" or "argout") it returns the result unmodified like
- this :
-
- def return_foo():
- val = shadowc.return_foo()
- return val
-
- In this case, it is up to the user to figure out what to do
- with the return value (including the possibility of converting it
- into a Python class).
-
-7/26/97 : Fixed a parsing problem with types like 'unsigned long int',
- 'unsigned short int', etc...
-
-7/24/97 : Minor bug fix to Tcl 8 module to parse enums properly. Also
- fixed a memory corruption problem in the type-checker.
- (patch contributed by Henry Rowley.
-
-7/24/97 : Added Python-tuple typemaps contributed by Robin Dunn.
-
-7/24/97 : Incorporated some changes to the Python module in support of
- Mark Hammond's COM support. I'm not entirely sure they
- work yet however. Needs documentation and testing.
-
-7/24/97 : Fixed code generation bugs when structures had array members
- and typemaps were used. For example :
-
- %typemap(memberin) double [20][20] {
- ... get a double [20][20] ...
- }
- struct Foo {
- double a[20][20];
- }
-
- Originally, this would generate a compiler-type error when
- the wrapper code was compiled. Now, a helper function like
- this is generated :
-
- double *Foo_a_set(Foo *a, double val[20][20]) {
- ... memberin typemap here ...
- return (double *) val;
- }
-
- When writing typemaps, one can assume that the source variable
- is an array of the *same* type as the structure member. This
- may break some codes that managed to work around the array bug.
- *** POTENTIAL INCOMPATIBILITY ***
-
-7/13/97 : Fixed bug in Perl5 module when using C global variables that
- are pointers. When used in function calls and other operations,
- the value of the pointer would be invalid---causing core
- dumps and other problems. SWIG implements global variables
- using Perl magic variables. As it turns out, the error
- was caused by the fact that the pointer-extraction code
- was somehow bypassing the procedure used to resolve magical
- variables (hence, leaving the value undefined). To fix
- the problem, SWIG now explicitly resolves magic before
- extracting pointer values.
-
-7/12/97 : Eliminated the last remnants of free() and malloc() from
- the SWIG compiler.
-
-7/12/97 : Fixed parsing problems with typemaps involving arrays and
- temporary variables of arrays. Also made it possible for
- SWIG to handle typemaps like this :
-
- %typemap(in) double [ANY] (double temp[$dim0]) {
- ... store data in temp[$dim0] ...
- }
-
- Not only does this typemap match any double [] array, it
- creates a local variable with precisely the right dimensions.
- (ie. $dim0 gets filled in with the real number of dimensions).
- Of course, off the record, this will be a way to add more
- functionality to the typemaps.i libraries.
-
-7/9/97 : Fixed some problems with Perl5, static linking, and shadow
- classes. When statically linking multiple modules together, write
- a top-level interface file like this when shadow classes are not
- used :
-
- %module swig, foo, bar, glob;
- %include perlmain.i
-
- When shadow classes are used, the module names have an extra 'c'
- appended so it should read as :
-
- %module swig, fooc, barc, globc;
- %include perlmain.i
-
- When linking multiple modules, consider using the SWIG runtime
- library.
-
-7/8/97 : Incorporated fixed versions of the Borland C++ Makefiles.
-
-7/8/97 : First cut at trying to eliminate excessive compiler warnings.
- As it turns out, alot of warnings go away if you just make
- declarations like this
-
- clientData = clientData;
-
- in the resulting wrapper code. Most compilers should just
- ignore this code (at least would can hope).
-
-7/8/97 : Fixed bizarre code generation bug with typemaps and C++ classes.
- In some cases, typemaps containing printf formatting strings such as
-
- %typemap(memberout) int * {
- printf("%d",42);
- }
-
- Would generate completely bogus code with garbage replacing
- the '%d'. Caused by one faulty use of printf (wasn't able to find
- any other occurrences).
-
-7/7/97 : Fixed bug in Python shadow class generation with non-member
- functions that are returning more than one value.
-
-7/7/97 : Incorporated modifications to make SWIG work with Guile 1.2.
- Still need to test it out, but it is rumored to work.
-
-7/2/97 : Fixed some bugs related to output arguments and Python shadow
- classes. If an output argument is detected, SWIG assumes
- that the result is a list and handles it appropriately.
- If the normal return type of an function is an object,
- it will be converted into a shadow class as before, but
- with the assumption that it is the first element of a
- list. *** NOTE : This behavior has been subsequently changed ***
-
-6/29/97 : Changed EXPORT to SWIGEXPORT in all of the language modules.
- Should provide better compatibility with Windows.
-
-6/29/97 : Modified Python shadow classes so that output arguments
- work correctly (when typemaps are used).
-
-Version 1.1 (June 24, 1997)
-===========================
-
-6/24/97 : Fixed Objective-C constructor bug when working with Perl5
- shadow classes.
-
-6/23/97 : Fixed some parsing problems with Objective-C. Declarations
- such as the following should work now :
-
- - foo : (int) a with: (int) b;
-
-6/22/97 : Added SWIG Runtime library. This library contains
- the SWIG pointer type-checker and support functions
- that are normally included in every module. By using
- the library, it is easier to work with multiple SWIG
- generated modules.
-
-6/22/97 : Fixed minor bug in Perl5 module related to static linking
- of multiple modules.
-
-6/22/97 : Fixed some bugs with the %import directive. When used with
- Perl5 shadow classes, this generates a 'require' statement
- to load in external modules.
-
-6/22/97 : Added -swiglib option. This prints out the location of the
- SWIG library and exits. This option is only really useful to
- configuration tools that are looking for SWIG and its library
- location (e.g. autoconf, configure, etc...).
-
-6/21/97 : Fixed export bug with Perl5.004 on Windows-NT.
-
-6/20/97 : Minor change to code generation of class/structure members in
- order to work better with typemaps. Should have no noticable
- impact on existing SWIG modules.
-
-6/19/97 : Added -t option. This allows SWIG to load a typemap file before
- processing any declarations. For example :
-
- swig -t typemaps.i -python example.i
-
- At most, only one typemap file can be specified in this manner.
- *** NEW FEATURE ***
-
-6/18/97 : Need a Makefile fast? Type
-
- swig [-tcl, -perl5, -python] -co Makefile
-
- and you will get a Makefile specific to that target language.
- You just need to modify it for your application and you're
- ready to run.
-
-6/18/97 : Completed the -ci option. This option checks a file into the
- SWIG library. It should be used in conjunction with a
- language option. For example :
-
- swig -tcl -ci foobar.i
-
- Checks the file foobar.i into the Tcl part of the library.
- In order to check a file into the general library (accessible
- to all languages modules), do the following
-
- swig -ci -o ../foobar.i foobar.i
-
- (Admittedly this looks a little strange but is unavoidable).
- The check-in option is primarily designed for SWIG maintenance
- and library development. The command will fail if the user does
- not have write permission to the SWIG library. Third party library
- extensions can easily install themselves by simply providing
- a shell script that uses 'swig -ci' to install the appropriate
- library files. It is not necessary to know where the SWIG library
- is located if you use this mechanism.
- *** NEW FEATURE ***
-
-6/16/97 : Fixed a bug in shadow class generation when %name() was applied
- to a class definition. Unfortunately, fixing the bug required
- a change in the Language C API by adding an extra argument to
- the Language::cpp_class_decl() function. This may break
- SWIG C++ extensions.
- *** POTENTIAL INCOMPATIBILITY ***
-
-6/15/97 : Added a warning message if no module name is specified with the
- %module directive or -module option.
-
-6/15/97 : Fixed line number bug when reporting errors for undefined
- base classes.
-
-6/15/97 : Added new %rename directive. This allows the forward declaration
- of a renaming. For example :
-
- %rename OldName NewName;
-
- .... later ...
- int OldName(int);
-
- Unlike %name, %rename will rename any occurrence of the old name.
- This applies to functions, variables, class members and so forth.
- There is no way to disable %rename once set, but you can change the
- name by redeclaring it to something else.
- *** NEW FEATURE ***
-
-6/15/97 : Improved the implementation of the %name directive so that it
- could be used with conditional compilation :
-
- #ifdef SWIG
- %name(NewName)
- #endif
- int OldName(int);
-
-6/15/97 : Added support for functions with no return datatype. In this case,
- SWIG assumes a return type of 'int'.
-
-6/11/97 : Improved error reporting in the parser. It should be a little
- less sensitive to errors that occur inside class definitions
- now. Also reports errors for function pointers.
-
-6/11/97 : Made '$' a legal symbol in identifiers. This is to support
- some Objective-C libraries. Some compilers (such as gcc) may also
- allow identifiers to contain a $ in C/C++ code as well (this is
- an obscure feature of C). When '$' appears in identifier, SWIG
- remaps it to the string '_S_' when creating the scripting language
- function. Thus a function 'foo$bar' would be called 'foo_S_bar'.
-
-6/11/97 : Fixed bug in Python shadow classes with __repr__ method. If
- supplied by the user, it was ignored, but now it should work.
-
-6/9/97 : Fixed the Tcl 8.0 module to work with Tcl 8.0b1. SWIG is no
- longer compatible with *any* alpha release of Tcl 8.0.
- *** POTENTIAL INCOMPATIBILITY ***
-
-6/7/97 : Put a maximal error count in (currently set to 20). SWIG will bail out
- if it generates more errors than this (useful for preventing SWIG
- from printing 4000 syntax errors when it gets confused).
-
-6/7/97 : Fixed segmentation fault when parsing variable length arguments.
-
-6/7/97 : Minor change to Perl5 module. C++ static functions are now
- put in the same package as their class when using shadow classes.
-
-6/7/97 : Centralized the naming of functions, members, wrappers etc... By
- centralizing the naming scheme, it should be possible to make
- some multi-file optimizations. Also, it should be possible to
- change SWIG's naming scheme (perhaps a new feature to be added
- later).
-
-6/2/97 : Added 'arginit' typemap. This can be used to assign initial values
- to function arguments. Doing so makes it somewhat easier to detect
- improper argument passing when working with other typemaps.
-
-6/2/97 : Fixed code generation bug when read-only variables were inherited
- into other classes. Under inheritance, the variables would
- become writable, but this has now been corrected.
-
-5/30/97 : An empty %name() directive is no longer allowed or supported.
- This directive was originally used to strip the prefix
- off of a class or structure. Unfortunately, this never really
- seemed to work right and it complicated the C++ code generator
- significantly. As far as I can tell no one uses it, so it
- is now history. *** POTENTIAL INCOMPATIBILITY ***
-
-5/28/97 : Fixed a parsing bug with #define and C++ comments. Declarations
- such as the following now work properly :
-
- #define CONST 4 // A Comment
-
-5/28/97 : Made some performance improvements to the SWIG String class.
- (only affects the SWIG compiler itself).
-
-5/28/97 : Modified the parser to skip template definitions and issue a
- warning message.
-
-5/28/97 : Preliminary support for parameterized types added (ie. templates).
- Types such as the following should pass through the SWIG compiler
-
- void foo(vector<complex> *a, vector<double> *b);
-
- When used, the entire name 'vector<complex>' becomes the name
- of the datatype. Due to space limitations in datatype
- representations, the name should not exceed 96 characters.
-
- Note : This is only part of what is needed for template support.
- Template class definitions are not yet supported by SWIG.
-
- The template notation above may also be used when specifying
- Objective-C protocol lists.
- *** NEW FEATURE ***
-
-5/24/97 : First cut at Objective-C support added. As it turns out, almost
- everything can be handled with only a few minor modifications to
- the C++ module.
- *** NEW FEATURE ***
-
-5/23/97 : Fixed repeated definition bug in multiple inheritance handling
- when multiple base classes share a common base class (ie.
- the evil diamond).
-
-5/21/97 : Fixed rather embarrassing typo that worked its way into the
- Tests/Build directory.
-
-5/19/97 : Fixed code generation bug when using native methods and
- shadow classes with Python and Perl5 modules.
-
-5/19/97 : Modified the %apply directive slightly so that it would work
- with pointers a little better. For example :
-
- %apply unsigned long { DWORD };
-
- Applies *all* typemaps associated with "unsigned long" to
- "DWORD". This now includes pointers to the two datatypes.
- For example, a typemap applied to "unsigned long **" would
- also be applied to any occurrence of "DWORD **" as well.
-
-5/19/97 : Fixed an ownership assignment bug in the Perl5 module when
- class members were returning new objects belonging to
- different classes.
-
-5/17/97 : Added a few more typemap variables.
-
- $name - Name of function/variable/member
- $basetype - Base datatype (type without pointers)
- $argnum - Argument number
-
-5/16/97 : Fixed embarrassing underscore error in local variable
- allocator.
-
-5/16/97 : Fixed namespace clash bug in parameterized typemaps
- when creating arrays as new local variables.
-
-5/15/97 : Fixed some bugs with inheritance of added methods across
- multiple files. SWIG now uses names of base classes
- when generating such functions.
-
-5/14/97 : Finished support for default typemaps. Primarily used
- internally, they can be used to match the basic
- built-in datatypes used inside of SWIG. You can
- specify them in interface files as well like this :
-
- %typemap(tcl,in) int SWIG_DEFAULT_TYPE {
- $target = atoi($target);
- }
-
- Unlike normal typemaps, this default map will get applied
- to *all* integer datatypes encountered, including those
- renamed with typedef, etc...
-
-5/13/97 : Fixed substring bug in type checker.
-
-5/12/97 : Fixed bug in parameterized typemaps when declaring local
- variables of structures.
-
-Version 1.1 Beta6 (May 9, 1997)
-===============================
-
-5/9/97 : Fixed bizarre NULL pointer handling bug in Perl5 module.
-
-5/8/97 : Fixed mysterious segmentation fault when running SWIG on an
- empty file.
-
-5/7/97 : The code generator will now replace the special symbol "$cleanup"
- with the cleanup code specified with the "freearg" typemap.
- This change needed to properly manage memory and exceptions.
-
-5/5/97 : Added the 'typemaps.i' library file. This contains a
- variety of common typemaps for input values, pointers,
- and so on.
-
-5/5/97 : Changed behavior of "argout" typemap in Python module.
- Old versions automatically turned the result into a
- Python list. The new version does nothing, leaving the
- implementation up to the user. This provides more flexibility
- but may break older codes that rely on typemaps.
- *** POTENTIAL INCOMPATIBILITY ***
-
-5/5/97 : Fixed bug in Python module related to the interaction of
- "argout" and "ignore" typemaps.
-
-5/5/97 : Fixed bug in Python module that would generate incorrect code
- if all function arguments are "ignored".
-
-5/4/97 : Added %apply and %clear directives. These form a higher level
- interface to the typemap mechanism. In a nutshell, they
- can be used to change the processing of various datatypes without
- ever having to write a typemap. See the SWIG documentation
- for more details. ** NEW FEATURE **
-
-5/4/97 : Added a local variable extension to the typemap handler.
- For example :
-
- %typemap(tcl,in) double *(double temp) {
- temp = atof($source);
- $target = &temp;
- }
-
- In this case, 'temp' is a local variable that exists
- in the entire wrapper function (not just the typemap
- code). This mechanism provides better support for
- certain types of argument handling and also makes it
- possible to write thread-safe typemaps. Any number
- local variables can be declared by supplying a comma
- separated list. Local variables are guaranteed to be
- unique, even if the same typemap is applied many times
- in a given function.
- ** Not currently supported in Perl4 or Guile modules.
-
-5/2/97 : Fixed processing of %ifdef, %endif, %if, etc... (These are
- SWIG equivalents of the C preprocessor directives that
- can pass through the C preprocessor without modification).
-
-5/2/97 : Fixed major (but subtle) bug in the run-time type checker
- related to searching and type-checking for C++ inheritance.
- To make a long story short, if you had two classes named
- "Foo" and "FooObject" the type checker would sometimes
- get confused and be unable to locate "Foo" in an internal
- table.
-
-5/2/97 : Fixed some bugs in the -co option.
-
-4/24/97 : Pointer library added to the SWIG library.
-
-4/19/97 : Added the %new directive. This is a "hint" that can be used
- to tell SWIG that a function is returning a new object. For
- example :
-
- %new Foo *create_foo();
-
- This tells SWIG that create_foo() is creating a new object
- and returning a pointer to it. Many language modules may
- choose to ignore the hint, but when working with shadow classes,
- the %new is used to handle proper ownership of objects.
-
- %new can also be used with dynamically allocated strings.
- For example :
-
- %new char *create_string();
-
- When used, all of the language modules will automatically cleanup
- the returned string--eliminating memory leaks.
- ** NEW FEATURE **
-
-4/19/97 : Added a new typemap "newfree". This is used in conjunction with
- the %new directive and can be used to change the method by which
- a new object returned by a function is deleted.
-
-4/19/97 : The symbol "__cplusplus" is now defined in the SWIG interpreter
- when running with the -c++ option.
-
-4/17/97 : Added support for static member functions when used inside the
- %addmethods directive.
-
-4/15/97 : Added a special typemap symbol PREVIOUS that can be used to
- restore a previous typemap. For example :
-
- %typemap(tcl,in) int * = PREVIOUS;
-
- This is primarily used in library files.
-
-4/13/97 : Added %pragma directive for Perl5 module. Two new pragmas are
- available :
-
- %pragma(perl5) code = "string"
- %pragma(perl5) include = "file.pl"
-
- Both insert code into the .pm file created by SWIG. This can
- be used to automatically customize the .pm file created by SWIG.
-
-4/13/97 : Scanner modified to only recognize C++ keywords when the -c++
- option has been specified. This provides support for C programs
- that make use of these keywords for identifiers.
- SWIG may need to be explicitly run with the -c++ option when
- compiling C++ code (this was allowed, but not recommended in
- previous versions). **POTENTIAL INCOMPATIBILITY**
-
-4/11/97 : Fixed a rather nasty bug in the Perl5 module related to using
- variable linking with complex datatypes and pointers. On Unix,
- code would work (somehow), but would cause an access violation
- under Windows-NT. The fix should correct the problem,
- but there may still be a problem using global variables of
- complex datatypes in conjunction with shadow classes. Fortunately,
- this sort of thing seems to be relatively rare (considering
- that the bug has been around for more than a year - yikes!).
-
-4/11/97 : Fixed bizarre constant evaluation bug in Perl5 code generation
- when running under Windows-NT.
-
-4/8/97 : Bug when using default arguments and C++ references fixed.
-
-4/8/97 : Fixed code generation bugs in Python and Perl5 modules related to
- using class renaming (applying the %name directive to a class
- definition) and shadow classes.
-
-4/7/97 : Fixed minor bugs in swigptr.swg, tcl8ptr.swg, and perl5ptr.swg to
- prevent infinite loops when weird datatypes are passed.
-
-3/29/97 : 'Makefile.win' added. This is used to build most of the examples
- in the Examples directory under Windows NT/95.
-
-3/27/97 : Fixes to SWIG's error return codes. SWIG now returns non-zero
- exit codes for certain kinds of errors (which makes it more
- friendly to makefiles). An overhaul of the error handling
- is on the to-do list and will probably show up in a later release.
-
-3/25/97 : Bug fix. "freearg" and "argout" typemaps have been fixed in
- the Perl5 module. In previous versions, function input parameters
- and function output parameters shared the same memory space--causing
- all sorts of nasty problems when trying to pass perl values by
- reference. SWIG now internally makes a "copy" (which is really
- just a pointer) of affected parameters and uses that. This
- is done transparently so there is no noticable impact on any
- SWIG generated modules. This change is probably only noticable
- to expert users.
-
-3/25/97 : Added type-check to verbose and stat mode. SWIG will now generate a list
- of all datatypes that were used but undefined (useful for tracking
- down weird bugs). This is enabled with the -v option (which
- is now officially known as "overly verbose" mode) or the -stat option.
-
-3/25/97 : Slight change to the parser to make include guards work correctly.
- For example :
-
- #ifndef INTERFACE_I
- #define INTERFACE_I
- %module foobar.i
- ... declarations ...
- #endif
-
-3/24/97 : %checkout directive added. This allows an interface file to
- extract files from the SWIG library and place them in the
- current directory. This can be used to extract scripts and
- other helper code that might be associated with library files.
- For example :
-
- %checkout array.tcl
-
- Will look for a file "array.tcl" in the library and copy it
- to the current directory. If the file already exists in the
- directory, this directive does nothing (it will not overwrite an
- existing file). This only an experimental feature for now.
-
-3/24/97 : SWIG will now look in the SWIG Library for a file if it can't
- find it in the current directory. As a result, it is easy to
- make modules from SWIG library files. For example, if you
- want to make a Python module from the SWIG timers library, just
- type this in any directory :
-
- swig -python timers.i
-
- You will get the files timers_wrap.c and timers_wrap.doc in
- the current directory that you can now compile. The file
- remains in the SWIG library (although you can check it out
- using the -co option). *** New Feature ***
-
-3/24/97 : -co option added to SWIG to allow easy access to the SWIG library.
- When used, this instructs SWIG to check out a library file and
- place it in the current directory. For example :
-
- unix > swig -co array.i
- array.i checked out from the SWIG library
- unix >
-
- Once in your directory you can customize the file to suit your
- particular purposes. The checkout option makes it easy to
- grab library files without knowing anything about the SWIG
- installation, but it also makes it possible to start
- including scripts, C code, and other miscellaneous files
- in the library. For example, you could put a cool script
- in the library and check it out whenever you wanted to use it.
- *** New Feature ***
-
-3/24/97 : #pragma export directives added to Tcl output for compiling
- shared libraries on the Mac.
-
-3/24/97 : Minor changes to wish.i and tclsh.i library files to provide
- support for the Macintosh.
-
-3/19/97 : SWIG's policy towards NULL pointers has been relaxed. The
- policy of requiring a special compiler directive -DALLOW_NULL
- to use NULL pointers is no longer supported. While this may
- seem "unsafe", it turns out that you can use a "check"
- typemap to achieve some safety. For example :
-
- %typemap(perl5,check) Node * {
- if (!$target)
- croak("NULL Pointers not allowed.");
- }
-
- This prevents any NULL value of a "Node *" pointer to be
- passed to a function. (I think this is much cleaner
- than the old -DALLOW_NULL hack anyways).
-
-3/19/97 : Fixed pointer handling errors in Perl5 module. Modules no
- longer core dump when a Perl reference is inadvertently
- passed in as a C pointer.
-
-3/18/97 : Added a "check" typemap. This can be used to check the
- validity of function input values. For example :
-
- %typemap(perl5,check) int posint {
- if ($target < 0)
- croak("Argument is not a positive integer");
- }
-
-3/18/97 : Added an $arg variable to Tcl typemaps. This makes it easier
- to return argument values by "reference".
-
-3/18/97 : Fixed a code generation bug when using C++ references and
- the %addmethods directive.
-
-3/18/97 : Fixed a few glitches in the typemap module with respect to
- chaining. For example :
-
- %typemap(tcl,in) int {
- $in // Inserts prexisting typemap
- printf("Received a %d\n", $target);
- }
-
- This has been allowed for quite some time, but didn't work
- if no existing typemap was defined. Now, it still doesn't
- work if no existing typemap is defined, but it issues a
- warning message. There is some support using default typemaps,
- but none of the language modules take advantage of it. This
- should be considered experimental at this time.
-
-Version 1.1b5 Patch 1 (March 16, 1997)
-======================================
-
-3/16/97 : Fixed references bug with C++ code generation.
-
-3/16/97 : Fixed initialization bug in the documentation system that
- was causing weird problems.
-
-3/16/97 : Fixed fatal bug with -c option in the Python module.
-
-3/13/97 : Fixed bug in the documentation system involving the %text directive
- and sorting. In the old system, %text entries would float to the
- top of a section because they were "nameless". Now they are
- attached to the previous declaration and will stay in the proper
- location relative to the previous entry.
-
-Version 1.1b5 (March 12, 1997)
-==============================
-
-3/11/97 : Fixed compilation problems introduced by Tcl/Tk 8.0a2.
- *** INCOMPATIBILITY *** SWIG no longer works with Tcl/Tk 8.0a1.
-
-3/10/97 : Fixed bug with ignored arguments and C++ member functions in
- the Python module.
-
-3/9/97 : Parsing bugs with nested class definitions and privately
- declared nested class definitions fixed.
-
-3/9/97 : Fixed a few minor code generation bugs with C++ classes and
- constructors. In some cases, the resulting wrapper code
- would not compile properly. SWIG now attempts to use
- the default copy constructor instead.
-
-3/8/97 : Added a -l option to SWIG that allows additional SWIG library files
- to be grabbed without having them specified in the interface file.
- This makes it easier to keep the interface file clean and move certain
- options into a Makefile. For example :
-
- swig -tcl example.i # Build a normal Tcl extension
- swig -tcl -lwish.i example.i # Build it as a wish extension
- # by including the 'wish.i' file.
-
- swig -python example.i # Build a dynamically loaded extension
- swig -python -lembed.i example.i # Build a static extension
-
- These kinds of options could previously be accomplished with
- conditional compilation such as :
-
- %module example
- ...
- #ifdef STATIC
- %include embed.i
- #endif
-
-3/8/97 : Incorporated changes to Guile module to use the new gh interface
- in FSF Guile 1.0. The older gscm interface used in Cygnus
- Guile releases is no longer supported by SWIG.
-
-3/8/97 : Cleaned up the Tcl Netscape plugin example. It should work with
- version 1.1 of the plugin now.
-
-3/8/97 : Added better array support to the typemap module. The keyword
- ANY can now be used to match any array dimension. For example :
-
- %typemap(tcl,in) double [ANY] {
- ... get an array ...
- }
-
- This will match any single-dimensional double array. The array
- dimension is passed in the variables $dim0, $dim1, ... $dim9. For
- example :
-
- %typemap(tcl,in) double [ANY][ANY][ANY] {
- printf("Received a double[%d][%d][%d]\n",$dim0,$dim1,$dim2);
- }
-
- Any typemap involving a specific array dimension will override any
- specified with the ANY tag. Thus, a %typemap(tcl,in) double [5][4][ANY] {}
- would override a double [ANY][ANY][ANY]. However, overuse of the ANY
- tag in arrays of high-dimensions may not work as you expect due to
- the pattern matching rule used. For example, which of the following
- typemaps has precedence?
-
- %typemap(in) double [ANY][5] {} // Avoid this!
- %typemap(in) double [5][ANY] {}
-
-3/7/97 : Fixed a number of bugs related to multi-dimensional array handling.
- Typedefs involving multi-dimensional arrays now works correctly.
- For example :
-
- typedef double MATRIX[4][4];
-
- ...
- extern double foo(MATRIX a);
-
- Typecasting of pointers into multi-dimensional arrays is now
- implemented properly when making C/C++ function calls.
-
-3/6/97 : Fixed potentially dangerous bug in the Tcl Object-oriented
- interface. Well, actually, didn't fix it but issued a
- Tcl error instead. The bug would manifest itself as follows:
-
- % set l [List] # Create an object
- ...
- % set m [List -this $l] # Make $m into an object assuming $l
- # contains a pointer.
- # Since $m == $l, $l gets destroyed
- # (since its the same command name)
- % $m insert Foo
- Segmentation fault # Note : the list no longer exists!
-
- Now, an error will be generated instead of redefining the command.
- As in :
-
- % set l [List]
- ...
- % set m [List -this $l]
- Object name already exists!
-
- Use catch{} to ignore the error.
-
-3/3/97 : Better support for enums added. Datatypes of 'enum MyEnum'
- and typedefs such as 'typedef enum MyEnum Foo;' now work.
-
-3/3/97 : Parser modified to ignore constructor initializers such as :
-
- class Foo : public Bar {
- int a,b;
- public:
- Foo(int i) : a(0), b(i), Bar(i,0) { };
- };
-
-3/3/97 : Modified parser to ignore C++ exception specifications such as :
-
- int foo(double) throw(X,Y);
-
-3/3/97 : Added %import directive. This works exactly like %extern
- except it tells the language module that the declarations are
- coming from a separate module. This is usually only
- needed when working with shadow classes.
-
-3/2/97 : Changed pointer type-checker to be significantly more
- efficient when working with derived datatypes. This
- has been accomplished by storing type-mappings in sorted
- order, using binary search schemes, and caching recently
- used datatypes. For SWIG generated C++ modules that
- make a large number of C function calls with derived types,
- this could result in speedups of between 100 and 50000 percent.
- However, due to the required sorting operation, module
- loading time may increased slightly when there are lots of
- datatypes.
-
-3/2/97 : Fixed some C++ compilation problems with Python
- embed.i library files.
-
-2/27/97 : Slight change to C++ code generation to use copy constructors
- when returning complex data type by value.
-
-2/26/97 : Fixed bug in Python module with -c option.
-
-2/26/97 : Slight tweak of parser to allow trailing comma in enumerations
- such as
-
- enum Value (ALE, STOUT, LAGER, };
-
-2/25/97 : Fixed code generation bug in Tcl module when using the
- %name() directive on a classname.
-
-2/25/97 : Finished code-size optimization of C++ code generation with
- inheritance of attributes. Inherited attributes now
- only generate one set of wrapper functions that are re-used
- in any derived classes. This could provide big code
- size improvements in some scripting language interfaces.
-
-2/25/97 : Perl5 module modified to support both the Unix and Windows
- versions. The windows version has been tested with the
- Activeware port of Perl 5.003 running under Windows 95.
- The C source generated by SWIG should compile without
- modification under both versions of Perl, but is now
- even more hideous than before.
-
-2/25/97 : Modified parser to allow scope resolution operation to
- appear in expressions and default arguments as in :
-
- void foo(int a = Bar::defvalue);
-
-2/25/97 : Fixed bug when resolving symbols inside C++ classes.
- For example :
-
- class Foo {
- public:
- enum Value {ALE, STOUT, LAGER};
- ...
- void defarg(Value v = STOUT);
-
- };
-
-2/24/97 : Fixed bug with member functions returning void *.
-
-2/23/97 : Modified Python module to be better behaved under Windows
-
- - Module initialization function is now properly exported.
- It should not be necessary to explicitly export this function
- yourself.
-
- - Bizarre compilation problems when compiling the SWIG wrapper
- code as ANSI C under Visual C++ 4.x fixed.
-
- - Tested with both the stock Python-1.4 distribution and Pythonwin
- running under Win95.
-
-2/19/97 : Fixed typedef handling bug in Perl5 shadow classes.
-
-2/19/97 : Added exception support. To use it, do the following :
-
- %except(lang) {
- ... try part of the exception ...
- $function
- ... catch part of exception ...
- }
-
- $function is a SWIG variable that will be replaced by the
- actual C/C++ function call in a wrapper function. Thus,
- a real exception specification might look like this :
-
- %except(perl5) {
- try {
- $function
- } catch (char *& sz) {
- ... process an exception ...
- } catch(...) {
- croak("Unknown exception. Bailing out...");
- }
- }
-
-2/19/97 : Added support for managing generic code fragments (needed
- for exceptions).
-
-2/19/97 : Fixed some really obscure typemap scoping bugs in the C++
- handler.
-
-2/18/97 : Cleaned up perlmain.i file by removing some problematic,
- but seemingly unnecessary declarations.
-
-2/18/97 : Optimized handling of member functions under inheritance.
- SWIG can now use wrapper functions generated for a
- base class instead of regenerating wrappers for
- the same functions in a derived class. This could
- make a drastic reduction in wrapper code size for C++
- applications with deep inheritance hierarchies and
- lots of functions.
-
-2/18/97 : Additional methods specified with %addmethods can now
- be inherited along with normal C++ member functions.
-
-2/18/97 : Minor internal fixes to make SWIG's string handling a little
- safer.
-
-2/16/97 : Moved some code generation of Tcl shadow classes to
- library files.
-
-2/16/97 : Fixed documentation error of '-configure' method in
- Tcl modules.
-
-2/16/97 : Modified Perl5 module slightly to allow typemaps
- to use Perl references.
-
-2/12/97 : Fixed argument checking bug that was introduced by
- default arguments (function calls with too many
- arguments would still be executed). Functions now
- must have the same number of arguments as C version
- (with possibility of default/optional arguments
- still supported).
-
-2/12/97 : Fixed default argument bug in Perl5 module when
- generating wrapper functions involving default
- arguments of complex datatypes.
-
-2/12/97 : Fixed typemap scoping problems. For example :
-
- %typemap(tcl,in) double {
- .. get a double ..
- }
-
- class Foo {
- public:
- double bar(double);
- }
-
- %typemap(tcl,in) double {
- .. new get double ..
- }
-
- Would apply the second typemap to all functions in Foo
- due to delayed generation of C++ wrapper code (clearly this
- is not the desired effect). Problem has been fixed by
- assigning unique numerical identifiers to every datatype in
- an interface file and recording the "range of effect" of each
- typemap.
-
-2/11/97 : Added support for "ignore" and "default" typemaps. Only use
- if you absolutely know what you're doing.
-
-2/9/97 : Added automatic creation of constructors and destructors for
- C structs and C++ classes that do not specify any sort of
- constructor or destructor. This feature can be enabled by
- running SWIG with the '-make_default' option or by inserting
- the following pragma into an interface file :
-
- %pragma make_default
-
- The following pragma disables automatic constructor generation
-
- %pragma no_default
-
-2/9/97 : Added -make_default option for producing default constructors
- and destructors for classes without them.
-
-2/9/97 : Changed the syntax of the SWIG %pragma directive to
- %pragma option=value or %pragma(lang) option=value.
- This change makes the syntax a little more consistent
- between general pragmas and language-specific pragmas.
- The old syntax still works, but will probably be phased
- out (a warning message is currently printed).
-
-2/9/97 : Improved Tcl support of global variables that are of
- structures, classes, and unions.
-
-2/9/97 : Fixed C++ compilation problem in Python 'embed.i' library file.
-
-2/9/97 : Fixed missing return value in perlmain.i library file.
-
-2/9/97 : Fixed Python shadow classes to return an AttributeError when
- undefined attributes are accessed (older versions returned
- a NameError).
-
-2/9/97 : Fixed bug when %addmethods is used after a class definition whose
- last section is protected or private.
-
-2/8/97 : Made slight changes in include file processing to support
- the Macintosh.
-
-2/8/97 : Extended swigmain.cxx to provide a rudimentary Macintosh interface.
- It's a really bad interface, but works until something better
- is written.
-
-1/29/97 : Fixed type-casting bug introduced by 1.1b4 when setting/getting the
- value of global variables involving complex data types.
-
-1/29/97 : Removed erroneous white space before an #endif in the code generated
- by the Python module (was causing errors on DEC Alpha compilers).
-
-1/26/97 : Fixed errors when using default/optional arguments in Python shadow
- shadow classes.
-
-1/23/97 : Fixed bug with nested %extern declarations.
-
-1/21/97 : Fixed problem with typedef involving const datatypes.
-
-1/21/97 : Somewhat obscure, but serious bug with having multiple levels
- of typedefs fixed. For example :
-
- typedef char *String;
- typedef String Name;
-
-Version 1.1 Beta4 (January 16, 1997)
-====================================
-
-Note : SWIG 1.1b3 crashed and burned shortly after take off due
-to a few major run-time problems that surfaced after release.
-This release should fix most, if not all, of those problems.
-
-1/16/97 : Fixed major memory management bug on Linux
-
-1/14/97 : Fixed bug in functions returning constant C++ references.
-
-1/14/97 : Modified C++ module to handle datatypes better.
-
-1/14/97 : Modified parser to allow a *single* scope resolution
- operator in datatypes. Ie : Foo::bar. SWIG doesn't
- yet handle nested classes, so this should be
- sufficient for now.
-
-1/14/97 : Modified parser to allow typedef inside a C++ class.
-
-1/14/97 : Fixed some problems related to datatypes defined inside
- a C++ class. SWIG was not generating correct code,
- but a new scoping mechanism and method for handling
- datatypes inside a C++ class have been added.
-
-1/14/97 : Changed enumerations to use the value name instead
- of any values that might have appeared in the interface
- file. This makes the code a little more friendly to
- C++ compilers.
-
-1/14/97 : Removed typedef bug that made all enumerations
- equivalent to each other in the type checker (since
- it generated alot of unnecessary code).
-
-Version 1.1 Beta3 (January 9, 1997)
-===================================
-
-Note : A *huge* number of changes related to ongoing modifications.
-
-1. Support for C++ multiple inheritance added.
-
-2. Typemaps added.
-
-3. Some support for nested structure definitions added.
-
-4. Default argument handling added.
-
-5. -c option added for building bare wrapper code modules.
-
-6. Rewrote Pointer type-checking to support multiple inheritance
- correctly.
-
-7. Tcl 8.0 module added.
-
-8. Perl4 and Guile modules resurrected from the dead (well, they
- at least work again).
-
-9. New Object Oriented Tcl interface added.
-
-10. Bug fixes to Perl5 shadow classes.
-
-11. Cleaned up many of the internal modules of the parser.
-
-12. Tons of examples and testing modules added.
-
-13. Fixed bugs related to use of "const" return values.
-
-14. Fixed bug with C++ member functions returning void *.
-
-15. Changed SWIG configuration script.
-
-Version 1.1 Beta2 (December 3, 1996)
-====================================
-
-1. Completely rewrote the SWIG documentation system. The changes
- involved are too numerous to mention. Basically, take everything
- you knew about the old system, throw them out, and read the
- file Doc/doc.ps.
-
-2. Limited support for #if defined() added.
-
-3. Type casts are now allowed in constant expressions. ie
-
- #define A (int) 3
-
-4. Added support for typedef lists. For example :
-
- typedef struct {
- double x,y,z;
- } Vector, *VectorPtr;
-
-5. New SWIG directives (related to documentation system)
-
- %style
- %localstyle
- %subsection
- %subsubsection
-
-6. Reorganized the C++ handling and made it a little easier to
- work with internally.
-
-7. Fixed problem with inheriting data members in Python
- shadow classes.
-
-8. Fixed symbol table problems with shadow classes in both
- Python and Perl.
-
-9. Fixed annoying segmentation fault bug in wrapper code
- generated for Perl5.
-
-10. Fixed bug with %addmethods directive. Now it can be placed
- anywhere in a class.
-
-11. More test cases added to the SWIG self-test. Documentation
- tests are now performed along with other things.
-
-12. Reorganized the SWIG library a little bit and set it up to
- self-document itself using SWIG.
-
-13. Lots and lots of minor bug fixes (mostly obscure, but bugs
- nonetheless).
-
-
-Version 1.1 Beta1 (October 30, 1996)
-====================================
-
-1. Added new %extern directive for handling multiple files
-
-2. Perl5 shadow classes added
-
-3. Rewrote conditional compilation to work better
-
-4. Added 'bool' datatype
-
-5. %{,%} block is now optional.
-
-6. Fixed some bugs in the Python shadow class module
-
-7. Rewrote all of the SWIG tests to be more informative
- (and less scary).
-
-8. Rewrote parameter list handling to be more memory
- efficient and flexible.
-
-9. Changed parser to ignore 'static' declarations.
-
-10. Initializers are now ignored. For example :
-
- struct FooBar a = {3,4,5};
-
-11. Somewhat better parsing of arrays (although it's
- usually just a better error message now).
-
-12. Lot's of minor bug fixes.
-
-
-Version 1.0 Final (August 31, 1996)
-===================================
-
-1. Fixed minor bug in C++ module
-
-2. Fixed minor bug in pointer type-checker when using
- -DALLOW_NULL.
-
-3. Fixed configure script to work with Python 1.4beta3
-
-4. Changed configure script to allow compilation without
- yacc or bison.
-
-Version 1.0 Final (August 28, 1996)
-===================================
-
-1. Changed parser to support more C/C++ datatypes (well,
- more variants). Types like "unsigned", "short int",
- "long int", etc... now work.
-
-2. "unions" added to parser.
-
-3. Use of "typedef" as in :
-
- typedef struct {
- double x,y,z;
- } Vector;
-
- Now works correctly. The name of the typedef is used as
- the structure name.
-
-4. Conditional compilation with #ifdef, #else, #endif, etc...
- added.
-
-5. New %disabledoc, %enabledoc directives allow documentation
- to selectively be disabled for certain parts of a wrapper
- file.
-
-6. New Python module supports better variable linking, constants,
- and shadow classes.
-
-7. Perl5 module improved with better compatibility with XS
- and xsubpp. SWIG pointers and now created so that they
- are compatible with xsubpp pointers.
-
-8. Support for [incr Tcl] namespaces added to Tcl module.
-
-9. %pragma directive added.
-
-10. %addmethods directive added.
-
-11. %native directive added to allow pre-existing wrapper functions
- to be used.
-
-12. Wrote configure script for SWIG installation.
-
-13. Function pointers now allowed with typedef statements.
-
-14. %typedef modified to insert a corresponding C typedef into
- the output file.
-
-15. Fixed some problems related to C++ references.
-
-16. New String and WrapperFunction classes add to make generating
- wrapper code easier.
-
-17. Fixed command line option processing to eliminate core dumps
- and to allow help messages.
-
-18. Lot's of minor bug fixes to almost all code modules
-
-
-Version 1.0 Beta 3 (Patch 1) July 17, 1996
-==========================================
-
-1.0 Final is not quite ready yet, but this release fixes a
-number of immediate problems :
-
-1. Compiler errors when using -strict 1 type checking have been fixed.
-
-2. Pointer type checker now recognizes pointers of the form
- _0_Type correctly.
-
-3. A few minor fixes were made in the Makefile
-
-Version 1.0 Beta 3 (June 14, 1996)
-==================================
-
-
-There are lots of changes in this release :
-
-1. SWIG is now invoked using the "swig" command instead of "wrap".
- Hey, swig sounds cooler.
-
-2. The SWIG_LIB environment variable can be set to change the
- location where SWIG looks for library files.
-
-3. C++ support has been added. You should use the -c++ option
- to enable it.
-
-4. The %init directive has been replaced by the %module directive.
- %module constructs a valid name for the initialization function
- for whatever target language you're using (actually this makes
- SWIG files a little cleaner). The old %init directive still works.
-
-5. The syntax of the %name directive has been changed. Use of the
- old one should generate a warning message, but may still work.
-
-6. To support Tcl/Tk on non-unix platforms, SWIG imports a file called
- swigtcl.cfg from the $(SWIG_LIB)/tcl directory. I don't have access
- to an NT machine, but this file is supposedly allows SWIG to
- produce wrapper code that compiles on both UNIX and non UNIX machines.
- If this doesn't work, you'll have to edit the file swigtcl.cfg. Please
- let me know if this doesn't work so I can update the file as
- necessary.
-
-7. The SWIG run-time typechecker has been improved. You can also
- now redefine how it works by supplying a file called "swigptr.cfg"
- in the same directory as your SWIG interface files. By default,
- SWIG reads this file from $(SWIG_LIB)/config.
-
-8. The documentation system has been changed to support the following :
-
- - Documentation order is printed in interface file order by
- default. This can be overridden by putting an %alpha
- directive in the beginning of the interface file.
-
- - You can supply additional documentation text using
-
- %text %{ put your text here %}
-
- - A few minor bugs were fixed.
-
-9. A few improvements have been made to the handling of command line
- options (but it's still not finished).
-
-10. Lots of minor bug fixes in most of the language modules have been
- made.
-
-11. Filenames have been changed to 8.3 for compatibility with a SWIG
- port to non-unix platforms (work in progress).
-
-12. C++ file suffix is now .cxx (for same reason).
-
-13. The documentation has been upgraded significantly and is now
- around 100 pages. I added new examples and a section on
- C++. The documentation now includes a Table of Contents.
-
-14. The SWIG Examples directory is still woefully sparse, but is
- getting better.
-
-Special notice about C++
-------------------------
-This is the first version of SWIG to support C++ parsing. Currently
-the C++ is far from complete, but seems to work for simple cases.
-No work has been done to add special C++ processing to any of
-the target languages. See the user manual for details about how
-C++ is handled. If you find problems with the C++ implementation,
-please let me know. Expect major improvements in this area.
-
-Note : I have only successfully used SWIG and C++ with Tcl and
-Python.
-
-Notice about Version 1.0Final
------------------------------
-
-Version 1.0B3 is the last Beta release before version 1.0 Final is
-released. I have frozen the list of features supported in version 1.0
-and will only fix bugs as they show up. Work on SWIG version 2.0 is
-already in progress, but is going to result in rather significant
-changes to SWIG's internal structure (hopefully for the better). No
-anticipated date for version 2.0 is set, but if you've got an idea,
-let me know.
-
-Version 1.0 Beta 2 (April 26, 1996)
-===================================
-
-This release is identical to Beta1 except a few minor bugs are
-fixed and the SWIG library has been updated to work with Tcl 7.5/Tk 4.1.
-A tcl7.5 examples directory is now included.
-
-- Fixed a bug in the Makefile that didn't install the libraries
- correctly.
-
-- SWIG Library files are now updated to work with Tcl 7.5 and Tk 4.1.
-
-- Minor bug fixes in other modules.
-
-
-Version 1.0 Beta 1 (April 10, 1996).
-=====================================
-
-This is the first "semi-official" release of SWIG. It has a
-number of substantial improvements over the Alpha release. These
-notes are in no particular order--hope I remembered everything....
-
-1. Tcl/Tk
-
-SWIG is known to work with Tcl7.3, Tk3.6 and later versions.
-I've also tested SWIG with expect-5.19.
-
-Normally SWIG expects to use the header files "tcl.h" and "tk.h".
-Newer versions of Tcl/Tk use version numbers. You can specify these
-in SWIG as follows :
-
- % wrap -htcl tcl7.4.h -htk tk4.0.h example.i
-
-Of course, I prefer to simply set up symbolic links between "tcl.h" and
-the most recent stable version on the machine.
-
-2. Perl4
-
-This implementation has been based on Perl-4.035. SWIG's interface to
-Perl4 is based on the documentation provided in the "Programming Perl"
-book by Larry Wall, and files located in the "usub" directory of the
-Perl4 distribution.
-
-In order to compile with Perl4, you'll need to link with the uperl.o
-file found in the Perl4 source directory. You may want to move this
-file to a more convenient location.
-
-3. Perl5
-
-This is a somewhat experimental implementation, but is alot less
-buggy than the alpha release. SWIG operates independently of
-the XS language and xsubpp supplied with Perl5. Currently SWIG
-produces the necessary C code and .pm file needed to dynamically
-load a module into Perl5.
-
-To support Perl5's notion of modules and packages (as with xsubpp),
-you can use the following command line options :
-
- % wrap -perl5 -module MyModule -package MyPackage example.i
-
-Note : In order for dynamic loading to be effective, you need to be
-careful about naming. For a module named "MyModule", you'll need to
-create a shared object file called "MyModule.so" using something like
-
- % ld -shared my_obj.o -o MyModule.so
-
-The use of the %init directive must match the module name since Perl5
-calls a function "boot_ModuleName" in order to initialize things.
-See the Examples directory for some examples of how to get things
-to work.
-
-4. Python1.3
-
-This is the first release supporting Python. The Python port is
-experimental and may be rewritten. Variable linkage is done through
-functions which is sort of a kludge. I also think it would be nice
-to import SWIG pointers into Python as a new object (instead of strings).
-Of course, this needs a little more work.
-
-5. Guile3
-
-If you really want to live on the edge, pick up a copy of Guile-iii and
-play around with this. This is highly experimental---especially since
-I'm not sure what the official state of Guile is these days. This
-implementation may change at any time should I suddenly figure out better
-ways to do things.
-
-6. Extending SWIG
-
-SWIG is written in C++ although I tend to think of the code as mostly
-being ANSI C with a little inheritance thrown in. Each target language
-is implemented as a C++ class that can be plugged into the system.
-If you want to add your own modifications, see Appendix C of the user
-manual. Then take a look at the "user" directory which contains some
-code for building your own extenions.
-
-7. The SWIG library
-
-The SWIG library is still incomplete. Some of the files mentioned in
-the user manual are unavailable. These files will be made available
-when they are ready. Subscribe to the SWIG mailing list for announcements
-and updates.
-
-8. SWIG Documentation
-
-I have sometimes experienced problems viewing the SWIG documentation in
-some postscript viewers. However, the documentation seems to print
-normally. I'm working on making much of the documentation online,
-but this takes time.
-
-Version 0.1 Alpha (February 9, 1996)
-====================================
-
-1. Run-time type-checking of SWIG pointers. Pointers are now represented
- as strings with both numeric and encoded type information. This makes
- it a little harder to shoot yourself in the foot (and it eliminates
- some segmentation faults and other oddities).
-
-2. Python 1.3 now supported.
-
-3. #define and enum can be used to install constants.
-
-4. Completely rewrote the %include directive and made it alot more powerful.
-
-5. Restructured the SWIG library to make it work better.
-
-6. Various bug fixes to Tcl, Perl4, Perl5, and Guile implementations.
-
-7. Better implementation of %typedef directive.
-
-8. Made some changes to SWIG's class structure to make it easier to expand.
- SWIG is now built into a library file that you can use to make your
- own extenions.
-
-9. Made extensive changes to the documentation.
-
-10. Minor changes to the SWIG parser to make it use less memory.
- Also took out some extraneous rules that were undocumented and
- didn't work in the first place.
-
-11. The SWIG library files "tclsh", "wish", "expect", etc... in the first
- release have been restructured and renamed to "tclsh.i", "wish.i",
- and so on.
diff --git a/contrib/tools/swig/CHANGES.current b/contrib/tools/swig/CHANGES.current
deleted file mode 100644
index d4883e5d6a..0000000000
--- a/contrib/tools/swig/CHANGES.current
+++ /dev/null
@@ -1,79 +0,0 @@
-Below are the changes for the current release.
-See the CHANGES file for changes in older releases.
-See the RELEASENOTES file for a summary of changes in each release.
-Issue # numbers mentioned below can be found on Github. For more details, add
-the issue number to the end of the URL: https://github.com/swig/swig/issues/
-
-Version 4.1.1 (30 Nov 2022)
-===========================
-
-2022-11-29: bero
- Fix mismatch between #pragma GCC diagnostic push and pop statements
-
-2022-11-26: wsfulton
- #2449 Fix undefined behaviour in ccache-swig calculating md4 hashes and possibly
- also handling errors when CCACHE_CPP2 is set.
-
-2022-11-25: wsfulton
- #961 Fix syntax error parsing unnamed template parameters with a default value.
-
-2022-11-25: olly
- #2447 Fix undefined behaviour in swig's parser when handling
- default parameter expressions containing method calls.
-
-2022-11-13: olly
- [PHP] #2419 Update the documentation to reflect that SWIG 4.1.0
- dropped support for -noproxy when generating PHP wrappers.
-
-2022-11-05: wsfulton
- #2417 Fix -swiglib for Windows when building with CMake.
-
-2022-11-02: wsfulton
- #2418 Fix infinite loop handling non-type template parameters.
-
- Fixes infinite loop due to () brackets in a non-type template
- parameter containing an expression.
-
-2022-10-28: wsfulton
- [R] R rtypecheck typemaps
-
- Further switch to use rtypecheck typemaps instead of hard coded logic.
- The full switch to typemaps is deferred until swig-4.2 as it can't be fully
- backwards compatible. For now a warning is provided to help the
- transition. It provides the full typemap that should be placed into
- a user's interface file, for example:
-
- %typemap("rtype") int32_t * "integer"
- void testmethod(int32_t * i);
- void testmethod();
-
- If there is no rtypecheck typemap for int32_t *, the warning shown is:
-
- example.i:7: Warning 750: Optional rtypecheck code is deprecated. Add the
- following typemap to fix as the next version of SWIG will not work without it:
- %typemap("rtypecheck") int32_t * %{ (is.integer($arg) || is.numeric($arg)) %}
-
- The warning is shown for any code that previously used "numeric", "integer" or
- "character" for the rtype typemap. Copying the rtypecheck typemap as
- shown into the user interface file will provide the appropriate fix and
- the warning will disappear. This is important to do as swig-4.2 will
- not be able to provide this helpful warning.
-
-2022-10-27: wsfulton
- [R] Allow NULL to be used in overloaded functions taking shared_ptr.
- Also fixes special variable $argtype expansion in rtypecheck typemaps.
-
-2022-10-26: wsfulton
- [R] Improve R wrapper error message when calling overloaded methods
- when incorrect types passed are passed to the overloaded methods.
-
- Old unhelpful error message:
- Error in f(...) : could not find function "f"
-
- Example of new improved error message:
- Error in use_count(k) :
- cannot find overloaded function for use_count with argtypes (NULL)
-
-2022-10-26: wsfulton
- [R] #2386 Fix memory leak in R shared_ptr wrappers.
- Fix leak when a cast up a class inheritance chain is required.
diff --git a/contrib/tools/swig/COPYRIGHT b/contrib/tools/swig/COPYRIGHT
deleted file mode 100644
index e6df73ff82..0000000000
--- a/contrib/tools/swig/COPYRIGHT
+++ /dev/null
@@ -1,113 +0,0 @@
-SWIG Copyright and Authors
---------------------------
-
-Copyright (c) 1995-2011 The SWIG Developers
-Copyright (c) 2005-2006 Arizona Board of Regents (University of Arizona).
-Copyright (c) 1998-2005 University of Chicago.
-Copyright (c) 1995-1998 The University of Utah and the Regents of the University of California
-
-Portions also copyrighted by:
- Network Applied Communication Laboratory, Inc
- Information-technology Promotion Agency, Japan
-
-Active SWIG Developers:
- William Fulton (wsf@fultondesigns.co.uk) (SWIG core, Java, C#, Windows, Cygwin)
- Olly Betts (olly@survex.com) (PHP)
- Joseph Wang (joequant@gmail.com) (R)
- Xavier Delacour (xavier.delacour@gmail.com) (Octave)
- David Nadlinger (code@klickverbot.at) (D)
- Oliver Buchtala (oliver.buchtala@gmail.com) (Javascript)
- Neha Narang (narangneha03@gmail.com) (Javascript)
- Simon Marchetto (simon.marchetto@scilab-enterprises.com) (Scilab)
- Zackery Spytz (zspytz@gmail.com) (OCaml, SWIG core)
-
-Past SWIG developers and major contributors include:
- Dave Beazley (dave-swig@dabeaz.com) (SWIG core, Python, Tcl, Perl)
- Henning Thielemann (swig@henning-thielemann.de) (Modula3)
- Matthias Köppe (mkoeppe@mail.math.uni-magdeburg.de) (Guile, MzScheme)
- Luigi Ballabio (luigi.ballabio@fastwebnet.it) (STL wrapping)
- Mikel Bancroft (mikel@franz.com) (Allegro CL)
- Surendra Singhi (efuzzyone@netscape.net) (CLISP, CFFI)
- Marcelo Matus (mmatus@acms.arizona.edu) (SWIG core, Python, UTL[python,perl,tcl,ruby])
- Art Yerkes (ayerkes@speakeasy.net) (OCaml)
- Lyle Johnson (lyle@users.sourceforge.net) (Ruby)
- Charlie Savage (cfis@interserv.com) (Ruby)
- Thien-Thi Nguyen (ttn@glug.org) (build/test/misc)
- Richard Palmer (richard@magicality.org) (PHP)
- Sam Liddicott - Ananova Ltd (saml@liddicott.com) (PHP)
- Tim Hockin - Sun Microsystems (thockin@sun.com) (PHP)
- Kevin Ruland (PHP)
- Shibukawa Yoshiki (Japanese Translation)
- Jason Stewart (jason@openinformatics.com) (Perl5)
- Loic Dachary (Perl5)
- David Fletcher (Perl5)
- Gary Holt (Perl5)
- Masaki Fukushima (Ruby)
- Scott Michel (scottm@cs.ucla.edu) (Java directors)
- Tiger Feng (songyanf@cs.uchicago.edu) (SWIG core)
- Mark Rose (mrose@stm.lbl.gov) (Directors)
- Jonah Beckford (beckford@usermail.com) (CHICKEN)
- Ahmon Dancy (dancy@franz.com) (Allegro CL)
- Dirk Gerrits (Allegro CL)
- Neil Cawse (C#)
- Harco de Hilster (Java)
- Alexey Dyachenko (dyachenko@fromru.com) (Tcl)
- Bob Techentin (Tcl)
- Martin Froehlich <MartinFroehlich@ACM.org> (Guile)
- Marcio Luis Teixeira <marciot@holly.colostate.edu> (Guile)
- Duncan Temple Lang (R)
- Miklos Vajna <vmiklos@frugalware.org> (PHP directors)
- Mark Gossage (mark@gossage.cjb.net) (Lua)
- Raman Gopalan (ramangopalan@gmail.com) (eLua)
- Gonzalo Garramuno (ggarra@advancedsl.com.ar) (Ruby, Ruby's UTL)
- John Lenz (Guile, MzScheme updates, Chicken module, runtime system)
- Baozeng Ding <sploving1@163.com> (Scilab)
- Ian Lance Taylor (Go)
- Dmitry Kabak (userdima@gmail.com) (Doxygen)
- Vadim Zeitlin (PCRE, Python, Doxygen)
- Stefan Zager (szager@gmail.com) (Python)
- Vincent Couvert (Scilab)
- Sylvestre Ledru (Scilab)
- Wolfgang Frisch (Scilab)
-
-Past contributors include:
- James Michael DuPont, Clark McGrew, Dustin Mitchell, Ian Cooke, Catalin Dumitrescu, Baran
- Kovuk, Oleg Tolmatcev, Tal Shalif, Lluis Padro, Chris Seatory, Igor Bely, Robin Dunn,
- Edward Zimmermann, David Ascher, Dominique Dumont, Pier Giorgio Esposito, Hasan Baran Kovuk,
- Klaus Wiederänders, Richard Beare, Hans Oesterholt.
- (See CHANGES and CHANGES.current and the bug tracker for a more complete list).
-
-Past students:
- Songyan Feng (Chicago).
- Xinghua Shi (Chicago).
- Jing Cao (Chicago).
- Aquinas Hobor (Chicago).
-
-Historically, the following people contributed to early versions of SWIG.
-Peter Lomdahl, Brad Holian, Shujia Zhou, Niels Jensen, and Tim Germann
-at Los Alamos National Laboratory were the first users. Patrick
-Tullmann at the University of Utah suggested the idea of automatic
-documentation generation. John Schmidt and Kurtis Bleeker at the
-University of Utah tested out the early versions. Chris Johnson
-supported SWIG's developed at the University of Utah. John Buckman,
-Larry Virden, and Tom Schwaller provided valuable input on the first
-releases and improving the portability of SWIG. David Fletcher and
-Gary Holt have provided a great deal of input on improving SWIG's
-Perl5 implementation. Kevin Butler contributed the first Windows NT
-port.
-
-Early bug reports and patches:
-Adam Hupp, Arthur Smyles, Brad Clements, Brett Williams, Buck Hodges,
-Burkhard Kloss, Chia-Liang Kao, Craig Files, Dennis Marsa, Dieter Baron,
-Drake Diedrich, Fleur Diana Dragan, Gary Pennington, Geoffrey Hort, Gerald Williams,
-Greg Anderson, Greg Kochanski, Greg Troxel, Henry Rowley, Irina Kotlova,
-Israel Taller, James Bailey, Jim Fulton, Joel Reed, Jon Travis,
-Junio Hamano, Justin Heyes-Jones, Karl Forner, Keith Davidson,
-Krzysztof Kozminski, Larry Virden, Luke J Crook, Magnus Ljung, Marc Zonzon,
-Mark Howson, Micahel Scharf, Michel Sanner, Mike Romberg, Mike Simons,
-Mike Weiblen, Paul Brannan, Ram Bhamidipaty, Reinhard Fobbe, Rich Wales,
-Richard Salz, Roy Lecates, Rudy Albachten, Scott Drummonds
-Scott Michel, Shaun Lowry, Steve Galser, Tarn Weisner Burton,
-Thomas Weidner, Tony Seward, Uwe Steinmann, Vadim Chugunov, Wyss Clemens,
-Zhong Ren.
-
diff --git a/contrib/tools/swig/INSTALL b/contrib/tools/swig/INSTALL
deleted file mode 100644
index 666ffd9f8a..0000000000
--- a/contrib/tools/swig/INSTALL
+++ /dev/null
@@ -1,226 +0,0 @@
-Basic Installation
-==================
-
- These are generic installation instructions.
-
- The `configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation. It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions. Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, and a
-file `config.log' containing compiler output (useful mainly for
-debugging `configure').
-
- It can also use an optional file (typically called `config.cache'
-and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring. (Caching is
-disabled by default to prevent problems with accidental use of stale
-cache files.)
-
- If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
-be considered for the next release. If you are using the cache, and at
-some point `config.cache' contains results you don't want to keep, you
-may remove or edit it.
-
- The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'. You only need
-`configure.ac' if you want to change it or regenerate `configure' using
-a newer version of `autoconf'.
-
-The simplest way to compile this package is:
-
- 1. `cd' to the directory containing the package's source code and type
- `./configure' to configure the package for your system. If you're
- using `csh' on an old version of System V, you might need to type
- `sh ./configure' instead to prevent `csh' from trying to execute
- `configure' itself.
-
- Running `configure' takes awhile. While running, it prints some
- messages telling which features it is checking for.
-
- 2. Type `make' to compile the package.
-
- 3. Optionally, type `make check' to run any self-tests that come with
- the package.
-
- 4. Type `make install' to install the programs and any data files and
- documentation.
-
- 5. You can remove the program binaries and object files from the
- source code directory by typing `make clean'. To also remove the
- files that `configure' created (so you can compile the package for
- a different kind of computer), type `make distclean'. There is
- also a `make maintainer-clean' target, but that is intended mainly
- for the package's developers. If you use it, you may have to get
- all sorts of other programs in order to regenerate files that came
- with the distribution.
-
-Compilers and Options
-=====================
-
- Some systems require unusual options for compilation or linking that
-the `configure' script does not know about. Run `./configure --help'
-for details on some of the pertinent environment variables.
-
- You can give `configure' initial values for variables by setting
-them in the environment. You can do that on the command line like this:
-
- ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
-
- *Note Environment Variables::, for more details.
-
-Compiling For Multiple Architectures
-====================================
-
- You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory. To do this, you must use a version of `make' that
-supports the `VPATH' variable, such as GNU `make'. `cd' to the
-directory where you want the object files and executables to go and run
-the `configure' script. `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'.
-
- If you have to use a `make' that does not support the `VPATH'
-variable, you have to compile the package for one architecture at a time
-in the source code directory. After you have installed the package for
-one architecture, use `make distclean' before reconfiguring for another
-architecture.
-
-Installation Names
-==================
-
- By default, `make install' will install the package's files in
-`/usr/local/bin', `/usr/local/man', etc. You can specify an
-installation prefix other than `/usr/local' by giving `configure' the
-option `--prefix=PATH'.
-
- You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files. If you
-give `configure' the option `--exec-prefix=PATH', the package will use
-PATH as the prefix for installing programs and libraries.
-Documentation and other data files will still use the regular prefix.
-
- In addition, if you use an unusual directory layout you can give
-options like `--bindir=PATH' to specify different values for particular
-kinds of files. Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them.
-
- If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
-Optional Features
-=================
-
- Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System). The
-`README' should mention any `--enable-' and `--with-' options that the
-package recognizes.
-
- For packages that use the X Window System, `configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
-
-Specifying the System Type
-==========================
-
- There may be some features `configure' cannot figure out
-automatically, but needs to determine by the type of host the package
-will run on. Usually `configure' can figure that out, but if it prints
-a message saying it cannot guess the host type, give it the
-`--build=TYPE' option. TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name which has the form:
-
- CPU-COMPANY-SYSTEM
-
-where SYSTEM can have one of these forms:
-
- OS
- KERNEL-OS
-
- See the file `config.sub' for the possible values of each field. If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the host type.
-
- If you are _building_ compiler tools for cross-compiling, you should
-use the `--target=TYPE' option to select the type of system they will
-produce code for.
-
- If you want to _use_ a cross compiler, that generates code for a
-platform different from the build platform, you should specify the host
-platform (i.e., that on which the generated programs will eventually be
-run) with `--host=TYPE'. In this case, you should also specify the
-build platform with `--build=TYPE', because, in this case, it may not
-be possible to guess the build platform (it sometimes involves
-compiling and running simple test programs, and this can't be done if
-the compiler is a cross compiler).
-
-Sharing Defaults
-================
-
- If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists. Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
-
-Environment Variables
-=====================
-
- Variables not defined in a site shell script can be set in the
-environment passed to configure. However, some packages may run
-configure again during the build, and the customized values of these
-variables may be lost. In order to avoid this problem, you should set
-them in the `configure' command line, using `VAR=value'. For example:
-
- ./configure CC=/usr/local2/bin/gcc
-
-will cause the specified gcc to be used as the C compiler (unless it is
-overridden in the site shell script).
-
-`configure' Invocation
-======================
-
- `configure' recognizes the following options to control how it
-operates.
-
-`--help'
-`-h'
- Print a summary of the options to `configure', and exit.
-
-`--version'
-`-V'
- Print the version of Autoconf used to generate the `configure'
- script, and exit.
-
-`--cache-file=FILE'
- Enable the cache: use and save the results of the tests in FILE,
- traditionally `config.cache'. FILE defaults to `/dev/null' to
- disable caching.
-
-`--config-cache'
-`-C'
- Alias for `--cache-file=config.cache'.
-
-`--quiet'
-`--silent'
-`-q'
- Do not print messages saying which checks are being made. To
- suppress all normal output, redirect it to `/dev/null' (any error
- messages will still be shown).
-
-`--srcdir=DIR'
- Look for the package's source code in directory DIR. Usually
- `configure' can determine that directory automatically.
-
-`configure' also accepts some other, not widely useful, options. Run
-`configure --help' for more details.
-
diff --git a/contrib/tools/swig/LICENSE b/contrib/tools/swig/LICENSE
deleted file mode 100644
index d7a422fda1..0000000000
--- a/contrib/tools/swig/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-SWIG is free software: you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version. See the LICENSE-GPL file for
-the full terms of the GNU General Public license version 3.
-
-Portions of SWIG are also licensed under the terms of the licenses
-in the file LICENSE-UNIVERSITIES. You must observe the terms of
-these licenses, as well as the terms of the GNU General Public License,
-when you distribute SWIG.
-
-The SWIG library and examples, under the Lib and Examples top level
-directories, are distributed under the following terms:
-
- You may copy, modify, distribute, and make derivative works based on
- this software, in source code or object code form, without
- restriction. If you distribute the software to others, you may do
- so according to the terms of your choice. This software is offered as
- is, without warranty of any kind.
-
-See the COPYRIGHT file for a list of contributors to SWIG and their
-copyright notices.
diff --git a/contrib/tools/swig/LICENSE-GPL b/contrib/tools/swig/LICENSE-GPL
deleted file mode 100644
index 94a9ed024d..0000000000
--- a/contrib/tools/swig/LICENSE-GPL
+++ /dev/null
@@ -1,674 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users. We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors. You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights. Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received. You must make sure that they, too, receive
-or can get the source code. And you must show them these terms so they
-know their rights.
-
- Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
- For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software. For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
- Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so. This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software. The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable. Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products. If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
- Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary. To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Use with the GNU Affero General Public License.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
- If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
- <program> Copyright (C) <year> <name of author>
- This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
- The GNU General Public License does not permit incorporating your program
-into proprietary programs. If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License. But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/contrib/tools/swig/LICENSE-UNIVERSITIES b/contrib/tools/swig/LICENSE-UNIVERSITIES
deleted file mode 100644
index 44fcaa13f6..0000000000
--- a/contrib/tools/swig/LICENSE-UNIVERSITIES
+++ /dev/null
@@ -1,95 +0,0 @@
-SWIG is distributed under the following terms:
-
-I.
-
-Copyright (c) 1995-1998
-The University of Utah and the Regents of the University of California
-All Rights Reserved
-
-Permission is hereby granted, without written agreement and without
-license or royalty fees, to use, copy, modify, and distribute this
-software and its documentation for any purpose, provided that
-(1) The above copyright notice and the following two paragraphs
-appear in all copies of the source code and (2) redistributions
-including binaries reproduces these notices in the supporting
-documentation. Substantial modifications to this software may be
-copyrighted by their authors and need not follow the licensing terms
-described here, provided that the new terms are clearly indicated in
-all files where they apply.
-
-IN NO EVENT SHALL THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, THE
-UNIVERSITY OF UTAH OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY
-PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
-DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
-EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
-THE POSSIBILITY OF SUCH DAMAGE.
-
-THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, AND THE UNIVERSITY OF UTAH
-SPECIFICALLY DISCLAIM ANY WARRANTIES,INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND
-THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE,
-SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
-
-
-II.
-
-This software includes contributions that are Copyright (c) 1998-2005
-University of Chicago.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-Redistributions of source code must retain the above copyright notice,
-this list of conditions and the following disclaimer. Redistributions
-in binary form must reproduce the above copyright notice, this list of
-conditions and the following disclaimer in the documentation and/or
-other materials provided with the distribution. Neither the name of
-the University of Chicago nor the names of its contributors may be
-used to endorse or promote products derived from this software without
-specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF CHICAGO 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 UNIVERSITY OF
-CHICAGO 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.
-
-
-III.
-
-This software includes contributions that are Copyright (c) 2005-2006
-Arizona Board of Regents (University of Arizona).
-All Rights Reserved
-
-Permission is hereby granted, without written agreement and without
-license or royalty fees, to use, copy, modify, and distribute this
-software and its documentation for any purpose, provided that
-(1) The above copyright notice and the following paragraph
-appear in all copies of the source code and (2) redistributions
-including binaries reproduces these notices in the supporting
-documentation. Substantial modifications to this software may be
-copyrighted by their authors and need not follow the licensing terms
-described here, provided that the new terms are clearly indicated in
-all files where they apply.
-
-THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF ARIZONA 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 UNIVERSITY OF
-ARIZONA 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.
-
diff --git a/contrib/tools/swig/Lib/go/go.swg b/contrib/tools/swig/Lib/go/go.swg
deleted file mode 100644
index 348ae5f0d9..0000000000
--- a/contrib/tools/swig/Lib/go/go.swg
+++ /dev/null
@@ -1,744 +0,0 @@
-/* ------------------------------------------------------------
- * go.swg
- *
- * Go configuration module.
- * ------------------------------------------------------------ */
-
-%include <gostring.swg>
-
-/* Code insertion directives */
-#define %go_import(...) %insert(go_imports) %{__VA_ARGS__%}
-
-/* Basic types */
-
-%typemap(gotype) bool, const bool & "bool"
-%typemap(gotype) char, const char & "byte"
-%typemap(gotype) signed char, const signed char & "int8"
-%typemap(gotype) unsigned char, const unsigned char & "byte"
-%typemap(gotype) short, const short & "int16"
-%typemap(gotype) unsigned short, const unsigned short & "uint16"
-%typemap(gotype) int, const int & "int"
-%typemap(gotype) unsigned int, const unsigned int & "uint"
-%typemap(gotype) long, const long & "int64"
-%typemap(gotype) unsigned long, const unsigned long & "uint64"
-%typemap(gotype) long long, const long long & "int64"
-%typemap(gotype) unsigned long long, const unsigned long long & "uint64"
-%typemap(gotype) float, const float & "float32"
-%typemap(gotype) double, const double & "float64"
-
-%typemap(in) bool,
- char,
- signed char,
- unsigned char,
- short,
- unsigned short,
- int,
- unsigned int,
- long,
- unsigned long,
- long long,
- unsigned long long,
- float,
- double
-%{ $1 = ($1_ltype)$input; %}
-
-%typemap(in) const bool &,
- const char &,
- const signed char &,
- const unsigned char &,
- const short &,
- const unsigned short &,
- const int &,
- const unsigned int &,
- const long long &,
- const unsigned long long &,
- const float &,
- const double &
-%{ $1 = ($1_ltype)&$input; %}
-
-%typemap(in) const long & ($*1_ltype temp),
- const unsigned long & ($*1_ltype temp)
-%{ temp = ($*1_ltype)$input;
- $1 = ($1_ltype)&temp; %}
-
-%typemap(out) bool,
- char,
- signed char,
- unsigned char,
- short,
- unsigned short,
- int,
- unsigned int,
- long,
- unsigned long,
- long long,
- unsigned long long,
- float,
- double
-%{ $result = $1; %}
-
-%typemap(goout) bool,
- char,
- signed char,
- unsigned char,
- short,
- unsigned short,
- int,
- unsigned int,
- long,
- unsigned long,
- long long,
- unsigned long long,
- float,
- double
-""
-
-%typemap(out) const bool &,
- const char &,
- const signed char &,
- const unsigned char &,
- const short &,
- const unsigned short &,
- const int &,
- const unsigned int &,
- const long &,
- const unsigned long &,
- const long long &,
- const unsigned long long &,
- const float &,
- const double &
-%{ $result = ($*1_ltype)*$1; %}
-
-%typemap(goout) const bool &,
- const char &,
- const signed char &,
- const unsigned char &,
- const short &,
- const unsigned short &,
- const int &,
- const unsigned int &,
- const long &,
- const unsigned long &,
- const long long &,
- const unsigned long long &,
- const float &,
- const double &
-""
-
-%typemap(out) void ""
-
-%typemap(goout) void ""
-
-%typemap(directorin) bool,
- char,
- signed char,
- unsigned char,
- short,
- unsigned short,
- int,
- unsigned int,
- long,
- unsigned long,
- long long,
- unsigned long long,
- float,
- double
-%{ $input = ($1_ltype)$1; %}
-
-%typemap(godirectorin) bool,
- char,
- signed char,
- unsigned char,
- short,
- unsigned short,
- int,
- unsigned int,
- long,
- unsigned long,
- long long,
- unsigned long long,
- float,
- double
-""
-
-%typemap(directorin) const bool &,
- const char &,
- const signed char &,
- const unsigned char &,
- const short &,
- const unsigned short &,
- const int &,
- const unsigned int &,
- const long &,
- const unsigned long &,
- const long long &,
- const unsigned long long &,
- const float &,
- const double &
-%{ $input = ($*1_ltype)$1; %}
-
-%typemap(godirectorin) const bool &,
- const char &,
- const signed char &,
- const unsigned char &,
- const short &,
- const unsigned short &,
- const int &,
- const unsigned int &,
- const long &,
- const unsigned long &,
- const long long &,
- const unsigned long long &,
- const float &,
- const double &
-""
-
-%typemap(directorout) bool,
- char,
- signed char,
- unsigned char,
- short,
- unsigned short,
- int,
- unsigned int,
- long,
- unsigned long,
- long long,
- unsigned long long,
- float,
- double
-%{ $result = ($1_ltype)$input; %}
-
-%typemap(directorout,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) const bool &,
- const char &,
- const signed char &,
- const unsigned char &,
- const short &,
- const unsigned short &,
- const int &,
- const unsigned int &,
- const long &,
- const unsigned long &,
- const long long &,
- const unsigned long long &,
- const float &,
- const double &
-%{
- $result = new $*1_ltype($input);
- swig_acquire_pointer(&swig_mem, $result);
-%}
-
-/* The size_t type. */
-
-%typemap(gotype) size_t, const size_t & %{int64%}
-
-%typemap(in) size_t
-%{ $1 = (size_t)$input; %}
-
-%typemap(in) const size_t &
-%{ $1 = ($1_ltype)&$input; %}
-
-%typemap(out) size_t
-%{ $result = $1; %}
-
-%typemap(goout) size_t ""
-
-%typemap(out) const size_t &
-%{ $result = ($*1_ltype)*$1; %}
-
-%typemap(goout) const size_t & ""
-
-%typemap(directorin) size_t
-%{ $input = (size_t)$1; %}
-
-%typemap(godirectorin) size_t ""
-
-%typemap(directorin) const size_t &
-%{ $input = ($*1_ltype)$1; %}
-
-%typemap(godirectorin) const size_t & ""
-
-%typemap(directorout) size_t
-%{ $result = ($1_ltype)$input; %}
-
-%typemap(directorout,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) const size_t &
-%{
- $result = new $*1_ltype($input);
- swig_acquire_pointer(&swig_mem, $result);
-%}
-
-/* Member pointers. */
-
-%typemap(gotype) SWIGTYPE (CLASS::*)
-%{$gotypename%}
-
-%typemap(in) SWIGTYPE (CLASS::*)
-%{ $1 = *($&1_ltype)$input; %}
-
-%typemap(out) SWIGTYPE (CLASS::*)
-%{
- struct swig_out_type { intgo size; void* val; } *swig_out;
- swig_out = (struct swig_out_type*)malloc(sizeof(*swig_out));
- if (swig_out) {
- swig_out->size = sizeof($1_ltype);
- swig_out->val = malloc(swig_out->size);
- if (swig_out->val) {
- *($&1_ltype)(swig_out->val) = $1;
- }
- }
- $result = swig_out;
-%}
-
-%typemap(goout) SWIGTYPE (CLASS::*)
-%{
- {
- type swig_out_type struct { size int; val uintptr }
- p := (*swig_out_type)(unsafe.Pointer($1))
- if p == nil || p.val == 0 {
- $result = nil
- } else {
- m := make([]byte, p.size)
- a := (*[1024]byte)(unsafe.Pointer(p.val))[:p.size]
- copy(m, a)
- Swig_free(p.val)
- Swig_free(uintptr(unsafe.Pointer(p)))
- $result = &m[0]
- }
- }
-%}
-
-%typemap(directorin) SWIGTYPE (CLASS::*)
-%{ $input = *($&1_ltype)$1; %}
-
-%typemap(godirectorin) SWIGTYPE (CLASS::*) ""
-
-%typemap(directorout) SWIGTYPE (CLASS::*)
-%{
- $result = new $1_ltype($input);
- swig_acquire_pointer(&swig_mem, $result);
-%}
-
-/* Pointers. */
-
-/* We can't translate pointers using a typemap, so that is handled in
- the C++ code. */
-%typemap(gotype) SWIGTYPE *
-%{$gotypename%}
-
-%typemap(in) SWIGTYPE *
-%{ $1 = *($&1_ltype)&$input; %}
-
-%typemap(out) SWIGTYPE *
-%{ *($&1_ltype)&$result = ($1_ltype)$1; %}
-
-%typemap(goout) SWIGTYPE * ""
-
-%typemap(directorin) SWIGTYPE *
-%{ *($&1_ltype)&$input = ($1_ltype)$1; %}
-
-%typemap(godirectorin) SWIGTYPE * ""
-
-%typemap(directorout) SWIGTYPE *
-%{ $result = *($&1_ltype)&$input; %}
-
-/* Pointer references. */
-
-%typemap(gotype) SWIGTYPE *const&
-%{$gotypename%}
-
-%typemap(in) SWIGTYPE *const& ($*1_ltype temp = 0)
-%{
- temp = *($1_ltype)&$input;
- $1 = ($1_ltype)&temp;
-%}
-
-%typemap(out) SWIGTYPE *const&
-%{ *($1_ltype)&$result = *$1; %}
-
-%typemap(goout) SWIGTYPE *const& ""
-
-/* References. */
-
-/* Converting a C++ reference to Go has to be handled in the C++
- code. */
-%typemap(gotype) SWIGTYPE &
-%{$gotypename%}
-
-%typemap(in) SWIGTYPE &
-%{ $1 = *($&1_ltype)&$input; %}
-
-%typemap(out) SWIGTYPE &
-%{ *($&1_ltype)&$result = $1; %}
-
-%typemap(goout) SWIGTYPE & ""
-
-%typemap(directorin) SWIGTYPE &
-%{ $input = ($1_ltype)&$1; %}
-
-%typemap(godirectorin) SWIGTYPE & ""
-
-%typemap(directorout) SWIGTYPE &
-%{ *($&1_ltype)&$result = $input; %}
-
-%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE *const&
-%{ static $*1_ltype swig_temp;
- swig_temp = *($1_ltype)&$input;
- $result = &swig_temp; %}
-
-%typemap(gotype) SWIGTYPE &&
-%{$gotypename%}
-
-%typemap(in, fragment="<memory>") SWIGTYPE && (std::unique_ptr<$*1_ltype> rvrdeleter)
-%{ $1 = *($&1_ltype)&$input;
-rvrdeleter.reset($1); %}
-
-%typemap(out) SWIGTYPE &&
-%{ *($&1_ltype)&$result = $1; %}
-
-%typemap(goout) SWIGTYPE && ""
-
-%typemap(directorin) SWIGTYPE &&
-%{ $input = ($1_ltype)&$1_name; %}
-
-%typemap(godirectorin) SWIGTYPE && ""
-
-%typemap(directorout) SWIGTYPE &&
-%{ *($&1_ltype)&$result = $input; %}
-
-/* C arrays turn into Go pointers. If we know the length we can use a
- slice. */
-
-%typemap(gotype) SWIGTYPE []
-%{$gotypename%}
-
-%typemap(in) SWIGTYPE []
-%{ $1 = *($&1_ltype)&$input; %}
-
-%typemap(out) SWIGTYPE []
-%{ *($&1_ltype)&$result = $1; %}
-
-%typemap(goout) SWIGTYPE [] ""
-
-%typemap(directorin) SWIGTYPE []
-%{ $input = *($1_ltype)&$1; %}
-
-%typemap(godirectorin) SWIGTYPE [] ""
-
-%typemap(directorout) SWIGTYPE []
-%{ *($&1_ltype)&$result = $input; %}
-
-/* Strings. */
-
-%typemap(gotype)
- char *, char *&, char[ANY], char[] "string"
-
-/* Needed to avoid confusion with the way the go module handles
- references. */
-%typemap(gotype) char&, unsigned char& "*byte"
-%typemap(gotype) signed char& "*int8"
-
-%typemap(in)
- char *, char[ANY], char[]
-%{
- $1 = ($1_ltype)malloc($input.n + 1);
- memcpy($1, $input.p, $input.n);
- $1[$input.n] = '\0';
-%}
-
-%typemap(in) char *& (char *temp)
-%{
- temp = (char *)malloc($input.n + 1);
- memcpy(temp, $input.p, $input.n);
- temp[$input.n] = '\0';
- $1 = ($1_ltype)&temp;
-%}
-
-%typemap(freearg)
- char *, char[ANY], char[]
-%{ free($1); %}
-
-%typemap(freearg) char *&
-%{ free(temp$argnum); %}
-
-%typemap(out,fragment="AllocateString")
- char *, char *&, char[ANY], char[]
-%{ $result = Swig_AllocateString((char*)$1, $1 ? strlen((char*)$1) : 0); %}
-
-%typemap(goout,fragment="CopyString")
- char *, char *&, char[ANY], char[]
-%{ $result = swigCopyString($1) %}
-
-%typemap(directorin,fragment="AllocateString")
- char *, char *&, char[ANY], char[]
-%{
- $input = Swig_AllocateString((char*)$1, $1 ? strlen((char*)$1) : 0);
-%}
-
-%typemap(godirectorin,fragment="CopyString")
- char *, char *&, char[ANY], char[]
-%{
- $result = swigCopyString($input)
-%}
-
-%typemap(godirectorout)
- char *, char *&, char[ANY], char[]
-%{
- {
- p := Swig_malloc(len($input) + 1)
- s := (*[1<<30]byte)(unsafe.Pointer(p))[:len($input) + 1]
- copy(s, $input)
- s[len($input)] = 0
- $result = *(*string)(unsafe.Pointer(&s))
- }
-%}
-
-%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG)
- char *, char *&, char[ANY], char[]
-%{ $result = ($1_ltype)$input.p; %}
-
-/* String & length */
-
-%typemap(gotype) (char *STRING, size_t LENGTH) "string"
-
-%typemap(in) (char *STRING, size_t LENGTH)
-%{
- $1 = ($1_ltype)$input.p;
- $2 = ($2_ltype)$input.n;
-%}
-
-%typemap(out,fragment="AllocateString") (char *STRING, size_t LENGTH)
-%{ $result = Swig_AllocateString((char*)$1, (size_t)$2); %}
-
-%typemap(goout,fragment="CopyString") (char *STRING, size_t LENGTH)
-%{ $result = swigCopyString($1) %}
-
-%typemap(directorin,fragment="AllocateString") (char *STRING, size_t LENGTH)
-%{ $input = Swig_AllocateString((char*)$1, $2); %}
-
-%typemap(godirectorin,fragment="CopyString") (char *STRING, size_t LENGTH)
-%{ $result = swigCopyString($input) %}
-
-%typemap(directorout) (char *STRING, size_t LENGTH)
-%{
- $1 = ($1_ltype)$input.p;
- $2 = ($2_ltype)$input.n;
-%}
-
-/* The int & type needs to convert to intgo. */
-
-%typemap(gotype) int & "*int"
-
-%typemap(in) int & (int e)
-%{
- e = (int)*$input;
- $1 = &e;
-%}
-
-%typemap(out) int &
-%{ $result = new intgo(*$1); %}
-
-%typemap(argout) int &
-%{ *$input = (intgo)e$argnum; %}
-
-%typemap(goout) int & ""
-
-%typemap(directorin) int & (intgo e)
-%{
- e = (intgo)$1;
- $input = &e;
-%}
-
-%typemap(godirectorin) int & ""
-
-%typemap(directorout) int &
-%{
- $*1_ltype f = ($*1_ltype)*$input;
- $result = ($1_ltype)&f;
-%}
-
-%typemap(directorargout) int &
-%{ $1 = (int)*$input; %}
-
-%typemap(argout) const int & ""
-%typemap(directorargout) const int & ""
-
-/* Enums. We can't do the right thing for enums in typemap(gotype) so
- we deliberately don't define them. The right thing would be to
- capitalize the name. This is instead done in go.cxx. */
-
-%typemap(gotype) enum SWIGTYPE
-%{$gotypename%}
-
-%typemap(in) enum SWIGTYPE
-%{ $1 = ($1_ltype)$input; %}
-
-%typemap(out) enum SWIGTYPE
-%{ $result = (intgo)$1; %}
-
-%typemap(goout) enum SWIGTYPE ""
-
-%typemap(directorin) enum SWIGTYPE
-%{ $input = (intgo)$1; %}
-
-%typemap(godirectorin) enum SWIGTYPE ""
-
-%typemap(directorout) enum SWIGTYPE
-%{ $result = ($1_ltype)$input; %}
-
-%typemap(directorin) enum SWIGTYPE & (intgo e)
-%{
- e = (intgo)$1;
- $input = ($1_ltype)&e;
-%}
-
-%typemap(godirectorin) enum SWIGTYPE & ""
-
-%typemap(directorout) enum SWIGTYPE &
-%{ $result = $input; %}
-
-/* Arbitrary type. This is a type passed by value in the C/C++ code.
- We convert it to a pointer for the Go code. Note that all basic
- types are explicitly handled above. */
-
-%typemap(gotype) SWIGTYPE
-%{$gotypename%}
-
-%typemap(in) SWIGTYPE ($&1_type argp)
-%{
- argp = ($&1_ltype)$input;
- if (argp == NULL) {
- _swig_gopanic("Attempt to dereference null $1_type");
- }
- $1 = ($1_ltype)*argp;
-%}
-
-%typemap(out) SWIGTYPE
-#ifdef __cplusplus
-%{ *($&1_ltype*)&$result = new $1_ltype($1); %}
-#else
-{
- $&1_ltype $1ptr = ($&1_ltype)malloc(sizeof($1_ltype));
- memmove($1ptr, &$1, sizeof($1_type));
- *($&1_ltype*)&$result = $1ptr;
-}
-#endif
-
-%typemap(goout) SWIGTYPE ""
-
-%typemap(directorin) SWIGTYPE
-%{ $input = new $1_ltype(SWIG_STD_MOVE($1)); %}
-
-%typemap(godirectorin) SWIGTYPE ""
-
-%typemap(directorout) SWIGTYPE
-%{ $result = *($&1_ltype)$input; %}
-
-/* Exception handling */
-
-%typemap(throws) char *
-%{ _swig_gopanic($1); %}
-
-%typemap(throws) SWIGTYPE, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE *, SWIGTYPE [], SWIGTYPE [ANY]
-%{
- (void)$1;
- _swig_gopanic("C++ $1_type exception thrown");
-%}
-
-/* Typecheck typemaps. The purpose of these is merely to issue a
- warning for overloaded C++ functions that cannot be overloaded in
- Go as more than one C++ type maps to a single Go type. */
-
-%typecheck(SWIG_TYPECHECK_BOOL) /* Go bool */
- bool,
- const bool &
- ""
-
-%typecheck(SWIG_TYPECHECK_CHAR) /* Go byte */
- char,
- const char &,
- unsigned char,
- const unsigned char &
- ""
-
-%typecheck(SWIG_TYPECHECK_INT8) /* Go int8 */
- signed char,
- const signed char &
- ""
-
-%typecheck(SWIG_TYPECHECK_INT16) /* Go int16 */
- short,
- const short &
- ""
-
-%typecheck(SWIG_TYPECHECK_INT16) /* Go uint16 */
- unsigned short,
- const unsigned short &
- ""
-
-%typecheck(SWIG_TYPECHECK_INT32) /* Go int */
- int,
- const int &
- ""
-
-%typecheck(SWIG_TYPECHECK_INT32) /* Go uint */
- unsigned int,
- const unsigned int &
- ""
-
-%typecheck(SWIG_TYPECHECK_INT64) /* Go int64 */
- long,
- const long &,
- long long,
- const long long &
- ""
-
-%typecheck(SWIG_TYPECHECK_INT64) /* Go uint64 */
- unsigned long,
- const unsigned long &,
- unsigned long long,
- const unsigned long long &
- ""
-
-%typecheck(SWIG_TYPECHECK_FLOAT) /* Go float32 */
- float,
- const float &
- ""
-
-%typecheck(SWIG_TYPECHECK_DOUBLE) /* Go float64 */
- double,
- const double &
- ""
-
-%typecheck(SWIG_TYPECHECK_STRING) /* Go string */
- char *,
- char *&,
- char[ANY],
- char [],
- signed char *,
- signed char *&,
- signed char[ANY],
- signed char [],
- unsigned char *,
- unsigned char *&,
- unsigned char[ANY],
- unsigned char []
- ""
-
-%typecheck(SWIG_TYPECHECK_POINTER)
- SWIGTYPE,
- SWIGTYPE *,
- SWIGTYPE &,
- SWIGTYPE &&,
- SWIGTYPE *const&,
- SWIGTYPE [],
- SWIGTYPE (CLASS::*)
- ""
-
-%apply SWIGTYPE * { SWIGTYPE *const }
-%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) }
-%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) }
-
-/* Go keywords. */
-%include <gokw.swg>
-
-%include <goruntime.swg>
diff --git a/contrib/tools/swig/Lib/go/gokw.swg b/contrib/tools/swig/Lib/go/gokw.swg
deleted file mode 100644
index 3542830024..0000000000
--- a/contrib/tools/swig/Lib/go/gokw.swg
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Rename keywords. */
-
-#define GOKW(x) %keywordwarn("'" `x` "' is a Go keyword",rename="X%s") `x`
-#define GOBN(x) %builtinwarn("'" `x` "' conflicts with a built-in name in Go") "::"`x`
-
-GOKW(break);
-GOKW(case);
-GOKW(chan);
-GOKW(const);
-GOKW(continue);
-GOKW(default);
-GOKW(defer);
-GOKW(else);
-GOKW(fallthrough);
-GOKW(for);
-GOKW(func);
-GOKW(go);
-GOKW(goto);
-GOKW(if);
-GOKW(import);
-GOKW(interface);
-GOKW(package);
-GOKW(range);
-GOKW(return);
-GOKW(select);
-GOKW(struct);
-GOKW(switch);
-GOKW(type);
-GOKW(var);
-
-GOBN(map);
-
-#undef GOKW
diff --git a/contrib/tools/swig/Lib/go/goruntime.swg b/contrib/tools/swig/Lib/go/goruntime.swg
deleted file mode 100644
index 7bf083bd3d..0000000000
--- a/contrib/tools/swig/Lib/go/goruntime.swg
+++ /dev/null
@@ -1,217 +0,0 @@
-/* ------------------------------------------------------------
- * goruntime.swg
- *
- * Go runtime code for the various generated files.
- * ------------------------------------------------------------ */
-
-%inline %{
-static void Swig_free(void* p) {
- free(p);
-}
-
-static void* Swig_malloc(int c) {
- return malloc(c);
-}
-%}
-
-%insert(runtime) %{
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
-%}
-
-%insert(cgo_comment_typedefs) %{
-#include <stddef.h>
-#include <stdint.h>
-%}
-
-#if SWIGGO_INTGO_SIZE == 32
-%insert(runtime) %{
-typedef int intgo;
-typedef unsigned int uintgo;
-%}
-%insert(cgo_comment_typedefs) %{
-typedef int intgo;
-typedef unsigned int uintgo;
-%}
-#elif SWIGGO_INTGO_SIZE == 64
-%insert(runtime) %{
-typedef long long intgo;
-typedef unsigned long long uintgo;
-%}
-%insert(cgo_comment_typedefs) %{
-typedef long long intgo;
-typedef unsigned long long uintgo;
-%}
-#else
-%insert(runtime) %{
-typedef ptrdiff_t intgo;
-typedef size_t uintgo;
-%}
-%insert(cgo_comment_typedefs) %{
-typedef ptrdiff_t intgo;
-typedef size_t uintgo;
-%}
-#endif
-
-#ifndef SWIGGO_GCCGO
-// Set the host compiler struct attribute that will be
-// used to match gc's struct layout. For example, on 386 Windows,
-// gcc wants to 8-align int64s, but gc does not.
-// Use __gcc_struct__ to work around http://gcc.gnu.org/PR52991 on x86,
-// and https://golang.org/issue/5603.
-// See: https://github.com/golang/go/blob/fcbf04f9b93b4cd8addd05c2ed784118eb50a46c/src/cmd/cgo/out.go#L663
-%insert(runtime) %{
-# if !defined(__clang__) && (defined(__i386__) || defined(__x86_64__))
-# define SWIGSTRUCTPACKED __attribute__((__packed__, __gcc_struct__))
-# else
-# define SWIGSTRUCTPACKED __attribute__((__packed__))
-# endif
-%}
-#else
-# define SWIGSTRUCTPACKED
-#endif
-
-%insert(runtime) %{
-
-typedef struct { char *p; intgo n; } _gostring_;
-typedef struct { void* array; intgo len; intgo cap; } _goslice_;
-
-%}
-
-%insert(cgo_comment_typedefs) %{
-
-typedef struct { char *p; intgo n; } _gostring_;
-typedef struct { void* array; intgo len; intgo cap; } _goslice_;
-
-%}
-
-#ifdef SWIGGO_GCCGO
-
-/* Boilerplate for C/C++ code when using gccgo. */
-%insert(runtime) %{
-#define SWIGGO_GCCGO
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-extern void *_cgo_allocate(size_t);
-extern void _cgo_panic(const char *);
-#ifdef __cplusplus
-}
-#endif
-
-#define _swig_goallocate _cgo_allocate
-#define _swig_gopanic _cgo_panic
-%}
-
-#endif
-
-#ifndef SWIGGO_GCCGO
-
-%go_import("unsafe", _ "runtime/cgo")
-
-#else
-
-%go_import("syscall", "unsafe")
-
-%insert(go_header) %{
-
-type _ syscall.Sockaddr
-
-%}
-
-#endif
-
-%insert(go_header) %{
-
-type _ unsafe.Pointer
-
-%}
-
-/* Swig_always_false is used to conditionally assign parameters to
- Swig_escape_val so that the compiler thinks that they escape. We
- only assign them if Swig_always_false is true, which it never is.
- We export the variable so that the compiler doesn't realize that it
- is never set. */
-%insert(go_header) %{
-var Swig_escape_always_false bool
-var Swig_escape_val interface{}
-%}
-
-/* Function pointers are translated by the code in go.cxx into
- _swig_fnptr. Member pointers are translated to _swig_memberptr. */
-
-%insert(go_header) %{
-type _swig_fnptr *byte
-type _swig_memberptr *byte
-%}
-
-/* Convert a Go interface value into a C++ pointer. */
-
-%insert(go_header) %{
-func getSwigcptr(v interface { Swigcptr() uintptr }) uintptr {
- if v == nil {
- return 0
- }
- return v.Swigcptr()
-}
-%}
-
-/* For directors we need C++ to track a Go pointer. Since we can't
- pass a Go pointer into C++, we use a map to track the pointers on
- the Go side. */
-
-%go_import("sync")
-
-%insert(go_header) %{
-type _ sync.Mutex
-%}
-
-%insert(go_director) %{
-
-var swigDirectorTrack struct {
- sync.Mutex
- m map[int]interface{}
- c int
-}
-
-func swigDirectorAdd(v interface{}) int {
- swigDirectorTrack.Lock()
- defer swigDirectorTrack.Unlock()
- if swigDirectorTrack.m == nil {
- swigDirectorTrack.m = make(map[int]interface{})
- }
- swigDirectorTrack.c++
- ret := swigDirectorTrack.c
- swigDirectorTrack.m[ret] = v
- return ret
-}
-
-func swigDirectorLookup(c int) interface{} {
- swigDirectorTrack.Lock()
- defer swigDirectorTrack.Unlock()
- ret := swigDirectorTrack.m[c]
- if ret == nil {
- panic("C++ director pointer not found (possible use-after-free)")
- }
- return ret
-}
-
-func swigDirectorDelete(c int) {
- swigDirectorTrack.Lock()
- defer swigDirectorTrack.Unlock()
- if swigDirectorTrack.m[c] == nil {
- if c > swigDirectorTrack.c {
- panic("C++ director pointer invalid (possible memory corruption")
- } else {
- panic("C++ director pointer not found (possible use-after-free)")
- }
- }
- delete(swigDirectorTrack.m, c)
-}
-
-%}
diff --git a/contrib/tools/swig/Lib/go/gostring.swg b/contrib/tools/swig/Lib/go/gostring.swg
deleted file mode 100644
index d9c47d2858..0000000000
--- a/contrib/tools/swig/Lib/go/gostring.swg
+++ /dev/null
@@ -1,29 +0,0 @@
-/* ------------------------------------------------------------
- * gostring.swg
- *
- * Support for returning strings from C to Go.
- * ------------------------------------------------------------ */
-
-// C/C++ code to convert a memory buffer into a Go string allocated in
-// C/C++ memory.
-%fragment("AllocateString", "runtime") %{
-static _gostring_ Swig_AllocateString(const char *p, size_t l) {
- _gostring_ ret;
- ret.p = (char*)malloc(l);
- memcpy(ret.p, p, l);
- ret.n = l;
- return ret;
-}
-%}
-
-// Go code to convert a string allocated in C++ memory to one
-// allocated in Go memory.
-%fragment("CopyString", "go_runtime") %{
-type swig_gostring struct { p unsafe.Pointer; n int }
-func swigCopyString(s string) string {
- p := *(*swig_gostring)(unsafe.Pointer(&s))
- r := string((*[0x7fffffff]byte)(p.p)[:p.n])
- Swig_free(uintptr(p.p))
- return r
-}
-%}
diff --git a/contrib/tools/swig/Lib/go/typemaps.i b/contrib/tools/swig/Lib/go/typemaps.i
deleted file mode 100644
index d2e60d37c8..0000000000
--- a/contrib/tools/swig/Lib/go/typemaps.i
+++ /dev/null
@@ -1,298 +0,0 @@
-/* -----------------------------------------------------------------------------
- * typemaps.i
- *
- * Pointer and reference handling typemap library
- *
- * These mappings provide support for input/output arguments and common
- * uses for C/C++ pointers and C++ references.
- * ----------------------------------------------------------------------------- */
-
-/*
-INPUT typemaps
---------------
-
-These typemaps remap a C pointer or C++ reference to be an "INPUT" value which is
-passed by value instead of reference.
-
-The following typemaps can be applied to turn a pointer or reference into a simple
-input value. That is, instead of passing a pointer or reference to an object,
-you would use a real value instead.
-
- bool *INPUT, bool &INPUT
- signed char *INPUT, signed char &INPUT
- unsigned char *INPUT, unsigned char &INPUT
- short *INPUT, short &INPUT
- unsigned short *INPUT, unsigned short &INPUT
- int *INPUT, int &INPUT
- unsigned int *INPUT, unsigned int &INPUT
- long *INPUT, long &INPUT
- unsigned long *INPUT, unsigned long &INPUT
- long long *INPUT, long long &INPUT
- unsigned long long *INPUT, unsigned long long &INPUT
- float *INPUT, float &INPUT
- double *INPUT, double &INPUT
-
-To use these, suppose you had a C function like this :
-
- double fadd(double *a, double *b) {
- return *a+*b;
- }
-
-You could wrap it with SWIG as follows :
-
- %include <typemaps.i>
- double fadd(double *INPUT, double *INPUT);
-
-or you can use the %apply directive :
-
- %include <typemaps.i>
- %apply double *INPUT { double *a, double *b };
- double fadd(double *a, double *b);
-
-In Go you could then use it like this:
- answer := modulename.Fadd(10.0, 20.0)
-
-There are no char *INPUT typemaps, however you can apply the signed
-char * typemaps instead:
- %include <typemaps.i>
- %apply signed char *INPUT {char *input};
- void f(char *input);
-*/
-
-%define INPUT_TYPEMAP(TYPE, GOTYPE)
-%typemap(gotype) TYPE *INPUT, TYPE &INPUT "GOTYPE"
-
- %typemap(in) TYPE *INPUT, TYPE &INPUT
-%{ $1 = ($1_ltype)&$input; %}
-
-%typemap(out) TYPE *INPUT, TYPE &INPUT ""
-
-%typemap(goout) TYPE *INPUT, TYPE &INPUT ""
-
-%typemap(freearg) TYPE *INPUT, TYPE &INPUT ""
-
-%typemap(argout) TYPE *INPUT, TYPE &INPUT ""
-
-// %typemap(typecheck) TYPE *INPUT = TYPE;
-// %typemap(typecheck) TYPE &INPUT = TYPE;
-%enddef
-
-INPUT_TYPEMAP(bool, bool);
-INPUT_TYPEMAP(signed char, int8);
-INPUT_TYPEMAP(char, byte);
-INPUT_TYPEMAP(unsigned char, byte);
-INPUT_TYPEMAP(short, int16);
-INPUT_TYPEMAP(unsigned short, uint16);
-INPUT_TYPEMAP(int, int);
-INPUT_TYPEMAP(unsigned int, uint);
-INPUT_TYPEMAP(long, int64);
-INPUT_TYPEMAP(unsigned long, uint64);
-INPUT_TYPEMAP(long long, int64);
-INPUT_TYPEMAP(unsigned long long, uint64);
-INPUT_TYPEMAP(float, float32);
-INPUT_TYPEMAP(double, float64);
-
-#undef INPUT_TYPEMAP
-
-// OUTPUT typemaps. These typemaps are used for parameters that
-// are output only. An array replaces the c pointer or reference parameter.
-// The output value is returned in this array passed in.
-
-/*
-OUTPUT typemaps
----------------
-
-The following typemaps can be applied to turn a pointer or reference
-into an "output" value. When calling a function, no input value would
-be given for a parameter, but an output value would be returned. This
-works by a Go slice being passed as a parameter where a c pointer or
-reference is required. As with any Go function, the array is passed
-by reference so that any modifications to the array will be picked up
-in the calling function. Note that the array passed in MUST have at
-least one element, but as the c function does not require any input,
-the value can be set to anything.
-
- bool *OUTPUT, bool &OUTPUT
- signed char *OUTPUT, signed char &OUTPUT
- unsigned char *OUTPUT, unsigned char &OUTPUT
- short *OUTPUT, short &OUTPUT
- unsigned short *OUTPUT, unsigned short &OUTPUT
- int *OUTPUT, int &OUTPUT
- unsigned int *OUTPUT, unsigned int &OUTPUT
- long *OUTPUT, long &OUTPUT
- unsigned long *OUTPUT, unsigned long &OUTPUT
- long long *OUTPUT, long long &OUTPUT
- unsigned long long *OUTPUT, unsigned long long &OUTPUT
- float *OUTPUT, float &OUTPUT
- double *OUTPUT, double &OUTPUT
-
-For example, suppose you were trying to wrap the modf() function in the
-C math library which splits x into integral and fractional parts (and
-returns the integer part in one of its parameters):
-
- double modf(double x, double *ip);
-
-You could wrap it with SWIG as follows :
-
- %include <typemaps.i>
- double modf(double x, double *OUTPUT);
-
-or you can use the %apply directive :
-
- %include <typemaps.i>
- %apply double *OUTPUT { double *ip };
- double modf(double x, double *ip);
-
-The Go output of the function would be the function return value and the
-value in the single element array. In Go you would use it like this:
-
- ptr := []float64{0.0}
- fraction := modulename.Modf(5.0,ptr)
-
-There are no char *OUTPUT typemaps, however you can apply the signed
-char * typemaps instead:
- %include <typemaps.i>
- %apply signed char *OUTPUT {char *output};
- void f(char *output);
-*/
-
-%define OUTPUT_TYPEMAP(TYPE, GOTYPE)
-%typemap(gotype) TYPE *OUTPUT, TYPE &OUTPUT %{[]GOTYPE%}
-
-%typemap(in) TYPE *OUTPUT($*1_ltype temp), TYPE &OUTPUT($*1_ltype temp)
-{
- if ($input.len == 0) {
- _swig_gopanic("array must contain at least 1 element");
- }
- $1 = &temp;
-}
-
-%typemap(out) TYPE *OUTPUT, TYPE &OUTPUT ""
-
-%typemap(goout) TYPE *INPUT, TYPE &INPUT ""
-
-%typemap(freearg) TYPE *OUTPUT, TYPE &OUTPUT ""
-
-%typemap(argout) TYPE *OUTPUT, TYPE &OUTPUT
-{
- TYPE* a = (TYPE *) $input.array;
- a[0] = temp$argnum;
-}
-
-%enddef
-
-OUTPUT_TYPEMAP(bool, bool);
-OUTPUT_TYPEMAP(signed char, int8);
-OUTPUT_TYPEMAP(char, byte);
-OUTPUT_TYPEMAP(unsigned char, byte);
-OUTPUT_TYPEMAP(short, int16);
-OUTPUT_TYPEMAP(unsigned short, uint16);
-OUTPUT_TYPEMAP(int, int);
-OUTPUT_TYPEMAP(unsigned int, uint);
-OUTPUT_TYPEMAP(long, int64);
-OUTPUT_TYPEMAP(unsigned long, uint64);
-OUTPUT_TYPEMAP(long long, int64);
-OUTPUT_TYPEMAP(unsigned long long, uint64);
-OUTPUT_TYPEMAP(float, float32);
-OUTPUT_TYPEMAP(double, float64);
-
-#undef OUTPUT_TYPEMAP
-
-/*
-INOUT typemaps
---------------
-
-Mappings for a parameter that is both an input and an output parameter
-
-The following typemaps can be applied to make a function parameter both
-an input and output value. This combines the behavior of both the
-"INPUT" and "OUTPUT" typemaps described earlier. Output values are
-returned as an element in a Go slice.
-
- bool *INOUT, bool &INOUT
- signed char *INOUT, signed char &INOUT
- unsigned char *INOUT, unsigned char &INOUT
- short *INOUT, short &INOUT
- unsigned short *INOUT, unsigned short &INOUT
- int *INOUT, int &INOUT
- unsigned int *INOUT, unsigned int &INOUT
- long *INOUT, long &INOUT
- unsigned long *INOUT, unsigned long &INOUT
- long long *INOUT, long long &INOUT
- unsigned long long *INOUT, unsigned long long &INOUT
- float *INOUT, float &INOUT
- double *INOUT, double &INOUT
-
-For example, suppose you were trying to wrap the following function :
-
- void neg(double *x) {
- *x = -(*x);
- }
-
-You could wrap it with SWIG as follows :
-
- %include <typemaps.i>
- void neg(double *INOUT);
-
-or you can use the %apply directive :
-
- %include <typemaps.i>
- %apply double *INOUT { double *x };
- void neg(double *x);
-
-This works similarly to C in that the mapping directly modifies the
-input value - the input must be an array with a minimum of one element.
-The element in the array is the input and the output is the element in
-the array.
-
- x := []float64{5.0}
- Neg(x);
-
-The implementation of the OUTPUT and INOUT typemaps is different to
-other languages in that other languages will return the output value
-as part of the function return value. This difference is due to Go
-being a typed language.
-
-There are no char *INOUT typemaps, however you can apply the signed
-char * typemaps instead:
- %include <typemaps.i>
- %apply signed char *INOUT {char *inout};
- void f(char *inout);
-*/
-
-%define INOUT_TYPEMAP(TYPE, GOTYPE)
-%typemap(gotype) TYPE *INOUT, TYPE &INOUT %{[]GOTYPE%}
-
-%typemap(in) TYPE *INOUT, TYPE &INOUT {
- if ($input.len == 0) {
- _swig_gopanic("array must contain at least 1 element");
- }
- $1 = ($1_ltype) $input.array;
-}
-
-%typemap(out) TYPE *INOUT, TYPE &INOUT ""
-
-%typemap(goout) TYPE *INOUT, TYPE &INOUT ""
-
-%typemap(freearg) TYPE *INOUT, TYPE &INOUT ""
-
-%typemap(argout) TYPE *INOUT, TYPE &INOUT ""
-
-%enddef
-
-INOUT_TYPEMAP(bool, bool);
-INOUT_TYPEMAP(signed char, int8);
-INOUT_TYPEMAP(char, byte);
-INOUT_TYPEMAP(unsigned char, byte);
-INOUT_TYPEMAP(short, int16);
-INOUT_TYPEMAP(unsigned short, uint16);
-INOUT_TYPEMAP(int, int);
-INOUT_TYPEMAP(unsigned int, uint);
-INOUT_TYPEMAP(long, int64);
-INOUT_TYPEMAP(unsigned long, uint64);
-INOUT_TYPEMAP(long long, int64);
-INOUT_TYPEMAP(unsigned long long, uint64);
-INOUT_TYPEMAP(float, float32);
-INOUT_TYPEMAP(double, float64);
-
-#undef INOUT_TYPEMAP
diff --git a/contrib/tools/swig/Lib/java/enumtypesafe.swg b/contrib/tools/swig/Lib/java/enumtypesafe.swg
deleted file mode 100644
index c2012f568b..0000000000
--- a/contrib/tools/swig/Lib/java/enumtypesafe.swg
+++ /dev/null
@@ -1,117 +0,0 @@
-/* -----------------------------------------------------------------------------
- * enumtypesafe.swg
- *
- * Include this file in order for C/C++ enums to be wrapped by the so called
- * typesafe enum pattern. Each enum has an equivalent Java class named after the
- * enum and each enum item is a static instance of this class.
- * ----------------------------------------------------------------------------- */
-
-// const enum SWIGTYPE & typemaps
-%typemap(jni) const enum SWIGTYPE & "jint"
-%typemap(jtype) const enum SWIGTYPE & "int"
-%typemap(jstype) const enum SWIGTYPE & "$*javaclassname"
-
-%typemap(in) const enum SWIGTYPE & ($*1_ltype temp)
-%{ temp = ($*1_ltype)$input;
- $1 = &temp; %}
-%typemap(out) const enum SWIGTYPE & %{ $result = (jint)*$1; %}
-
-%typemap(directorout,warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) const enum SWIGTYPE &
-%{ static $*1_ltype temp = ($*1_ltype)$input;
- $result = &temp; %}
-%typemap(directorin, descriptor="L$packagepath/$*javaclassname;") const enum SWIGTYPE & "$input = (jint)$1;"
-%typemap(javadirectorin) const enum SWIGTYPE & "$*javaclassname.swigToEnum($jniinput)"
-%typemap(javadirectorout) const enum SWIGTYPE & "($javacall).swigValue()"
-
-%typecheck(SWIG_TYPECHECK_POINTER) const enum SWIGTYPE & ""
-
-%typemap(throws) const enum SWIGTYPE &
-%{ (void)$1;
- SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, "C++ $1_type exception thrown"); %}
-
-%typemap(javain) const enum SWIGTYPE & "$javainput.swigValue()"
-%typemap(javaout) const enum SWIGTYPE & {
- return $*javaclassname.swigToEnum($jnicall);
- }
-
-// enum SWIGTYPE typemaps
-%typemap(jni) enum SWIGTYPE "jint"
-%typemap(jtype) enum SWIGTYPE "int"
-%typemap(jstype) enum SWIGTYPE "$javaclassname"
-
-%typemap(in) enum SWIGTYPE %{ $1 = ($1_ltype)$input; %}
-%typemap(out) enum SWIGTYPE %{ $result = (jint)$1; %}
-
-%typemap(directorout) enum SWIGTYPE %{ $result = ($1_ltype)$input; %}
-%typemap(directorin, descriptor="L$packagepath/$javaclassname;") enum SWIGTYPE "$input = (jint) $1;"
-%typemap(javadirectorin) enum SWIGTYPE "$javaclassname.swigToEnum($jniinput)"
-%typemap(javadirectorout) enum SWIGTYPE "($javacall).swigValue()"
-
-%typecheck(SWIG_TYPECHECK_POINTER) enum SWIGTYPE ""
-
-%typemap(throws) enum SWIGTYPE
-%{ (void)$1;
- SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, "C++ $1_type exception thrown"); %}
-
-%typemap(javain) enum SWIGTYPE "$javainput.swigValue()"
-%typemap(javaout) enum SWIGTYPE {
- return $javaclassname.swigToEnum($jnicall);
- }
-
-// '$static' will be replaced with either 'static' or nothing depending on whether the enum is an inner Java class or not
-%typemap(javaclassmodifiers) enum SWIGTYPE "public final $static class"
-%typemap(javabase) enum SWIGTYPE ""
-%typemap(javacode) enum SWIGTYPE ""
-%typemap(javaimports) enum SWIGTYPE ""
-%typemap(javainterfaces) enum SWIGTYPE ""
-
-/*
- * The swigToEnum method is used to find the Java enum from a C++ enum integer value. The default one here takes
- * advantage of the fact that most enums do not have initial values specified, so the lookup is fast. If initial
- * values are specified then a lengthy linear search through all possible enums might occur. Specific typemaps could be
- * written to possibly optimise this lookup by taking advantage of characteristics peculiar to the targeted enum.
- * The special variable, $enumvalues, is replaced with a comma separated list of all the enum values.
- */
-%typemap(javabody) enum SWIGTYPE %{
- public final int swigValue() {
- return swigValue;
- }
-
- public String toString() {
- return swigName;
- }
-
- public static $javaclassname swigToEnum(int swigValue) {
- if (swigValue < swigValues.length && swigValue >= 0 && swigValues[swigValue].swigValue == swigValue)
- return swigValues[swigValue];
- for (int i = 0; i < swigValues.length; i++)
- if (swigValues[i].swigValue == swigValue)
- return swigValues[i];
- throw new IllegalArgumentException("No enum " + $javaclassname.class + " with value " + swigValue);
- }
-
- private $javaclassname(String swigName) {
- this.swigName = swigName;
- this.swigValue = swigNext++;
- }
-
- private $javaclassname(String swigName, int swigValue) {
- this.swigName = swigName;
- this.swigValue = swigValue;
- swigNext = swigValue+1;
- }
-
- private $javaclassname(String swigName, $javaclassname swigEnum) {
- this.swigName = swigName;
- this.swigValue = swigEnum.swigValue;
- swigNext = this.swigValue+1;
- }
-
- private static $javaclassname[] swigValues = { $enumvalues };
- private static int swigNext = 0;
- private final int swigValue;
- private final String swigName;
-%}
-
-%javaenum(typesafe);
-
diff --git a/contrib/tools/swig/Lib/java/java.swg b/contrib/tools/swig/Lib/java/java.swg
deleted file mode 100644
index 8719818bb8..0000000000
--- a/contrib/tools/swig/Lib/java/java.swg
+++ /dev/null
@@ -1,1458 +0,0 @@
-/* -----------------------------------------------------------------------------
- * java.swg
- *
- * Java typemaps
- * ----------------------------------------------------------------------------- */
-
-%include <javahead.swg>
-
-/* The jni, jtype and jstype typemaps work together and so there should be one of each.
- * The jni typemap contains the JNI type used in the JNI (C/C++) code.
- * The jtype typemap contains the Java type used in the JNI intermediary class.
- * The jstype typemap contains the Java type used in the Java proxy classes, type wrapper classes and module class. */
-
-/* Fragments */
-%fragment("SWIG_PackData", "header") {
-/* Pack binary data into a string */
-SWIGINTERN char * SWIG_PackData(char *c, void *ptr, size_t sz) {
- static const char hex[17] = "0123456789abcdef";
- const unsigned char *u = (unsigned char *) ptr;
- const unsigned char *eu = u + sz;
- for (; u != eu; ++u) {
- unsigned char uu = *u;
- *(c++) = hex[(uu & 0xf0) >> 4];
- *(c++) = hex[uu & 0xf];
- }
- return c;
-}
-}
-
-%fragment("SWIG_UnPackData", "header") {
-/* Unpack binary data from a string */
-SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
- unsigned char *u = (unsigned char *) ptr;
- const unsigned char *eu = u + sz;
- for (; u != eu; ++u) {
- char d = *(c++);
- unsigned char uu;
- if ((d >= '0') && (d <= '9'))
- uu = ((d - '0') << 4);
- else if ((d >= 'a') && (d <= 'f'))
- uu = ((d - ('a'-10)) << 4);
- else
- return (char *) 0;
- d = *(c++);
- if ((d >= '0') && (d <= '9'))
- uu |= (d - '0');
- else if ((d >= 'a') && (d <= 'f'))
- uu |= (d - ('a'-10));
- else
- return (char *) 0;
- *u = uu;
- }
- return c;
-}
-}
-
-%fragment("SWIG_JavaIntFromSize_t", "header") {
-/* Check for overflow converting to Java int (always signed 32-bit) from (unsigned variable-bit) size_t */
-SWIGINTERN jint SWIG_JavaIntFromSize_t(size_t size) {
- static const jint JINT_MAX = 0x7FFFFFFF;
- return (size > (size_t)JINT_MAX) ? -1 : (jint)size;
-}
-}
-
-/* Primitive types */
-%typemap(jni) bool, const bool & "jboolean"
-%typemap(jni) char, const char & "jchar"
-%typemap(jni) signed char, const signed char & "jbyte"
-%typemap(jni) unsigned char, const unsigned char & "jshort"
-%typemap(jni) short, const short & "jshort"
-%typemap(jni) unsigned short, const unsigned short & "jint"
-%typemap(jni) int, const int & "jint"
-%typemap(jni) unsigned int, const unsigned int & "jlong"
-%typemap(jni) long, const long & "jint"
-%typemap(jni) unsigned long, const unsigned long & "jlong"
-%typemap(jni) long long, const long long & "jlong"
-%typemap(jni) unsigned long long, const unsigned long long & "jobject"
-%typemap(jni) float, const float & "jfloat"
-%typemap(jni) double, const double & "jdouble"
-%typemap(jni) void "void"
-
-%typemap(jtype) bool, const bool & "boolean"
-%typemap(jtype) char, const char & "char"
-%typemap(jtype) signed char, const signed char & "byte"
-%typemap(jtype) unsigned char, const unsigned char & "short"
-%typemap(jtype) short, const short & "short"
-%typemap(jtype) unsigned short, const unsigned short & "int"
-%typemap(jtype) int, const int & "int"
-%typemap(jtype) unsigned int, const unsigned int & "long"
-%typemap(jtype) long, const long & "int"
-%typemap(jtype) unsigned long, const unsigned long & "long"
-%typemap(jtype) long long, const long long & "long"
-%typemap(jtype) unsigned long long, const unsigned long long & "java.math.BigInteger"
-%typemap(jtype) float, const float & "float"
-%typemap(jtype) double, const double & "double"
-%typemap(jtype) void "void"
-
-%typemap(jstype) bool, const bool & "boolean"
-%typemap(jstype) char, const char & "char"
-%typemap(jstype) signed char, const signed char & "byte"
-%typemap(jstype) unsigned char, const unsigned char & "short"
-%typemap(jstype) short, const short & "short"
-%typemap(jstype) unsigned short, const unsigned short & "int"
-%typemap(jstype) int, const int & "int"
-%typemap(jstype) unsigned int, const unsigned int & "long"
-%typemap(jstype) long, const long & "int"
-%typemap(jstype) unsigned long, const unsigned long & "long"
-%typemap(jstype) long long, const long long & "long"
-%typemap(jstype) unsigned long long, const unsigned long long & "java.math.BigInteger"
-%typemap(jstype) float, const float & "float"
-%typemap(jstype) double, const double & "double"
-%typemap(jstype) void "void"
-
-%typemap(jboxtype) bool, const bool & "Boolean"
-%typemap(jboxtype) char, const char & "Character"
-%typemap(jboxtype) signed char, const signed char & "Byte"
-%typemap(jboxtype) unsigned char, const unsigned char & "Short"
-%typemap(jboxtype) short, const short & "Short"
-%typemap(jboxtype) unsigned short, const unsigned short & "Integer"
-%typemap(jboxtype) int, const int & "Integer"
-%typemap(jboxtype) unsigned int, const unsigned int & "Long"
-%typemap(jboxtype) long, const long & "Integer"
-%typemap(jboxtype) unsigned long, const unsigned long & "Long"
-%typemap(jboxtype) long long, const long long & "Long"
-%typemap(jboxtype) unsigned long long, const unsigned long long & "java.math.BigInteger"
-%typemap(jboxtype) float, const float & "Float"
-%typemap(jboxtype) double, const double & "Double"
-
-%typemap(jni) char *, char *&, char[ANY], char[] "jstring"
-%typemap(jtype) char *, char *&, char[ANY], char[] "String"
-%typemap(jstype) char *, char *&, char[ANY], char[] "String"
-
-/* JNI types */
-%typemap(jni) jboolean "jboolean"
-%typemap(jni) jchar "jchar"
-%typemap(jni) jbyte "jbyte"
-%typemap(jni) jshort "jshort"
-%typemap(jni) jint "jint"
-%typemap(jni) jlong "jlong"
-%typemap(jni) jfloat "jfloat"
-%typemap(jni) jdouble "jdouble"
-%typemap(jni) jstring "jstring"
-%typemap(jni) jobject "jobject"
-%typemap(jni) jbooleanArray "jbooleanArray"
-%typemap(jni) jcharArray "jcharArray"
-%typemap(jni) jbyteArray "jbyteArray"
-%typemap(jni) jshortArray "jshortArray"
-%typemap(jni) jintArray "jintArray"
-%typemap(jni) jlongArray "jlongArray"
-%typemap(jni) jfloatArray "jfloatArray"
-%typemap(jni) jdoubleArray "jdoubleArray"
-%typemap(jni) jobjectArray "jobjectArray"
-
-%typemap(jtype) jboolean "boolean"
-%typemap(jtype) jchar "char"
-%typemap(jtype) jbyte "byte"
-%typemap(jtype) jshort "short"
-%typemap(jtype) jint "int"
-%typemap(jtype) jlong "long"
-%typemap(jtype) jfloat "float"
-%typemap(jtype) jdouble "double"
-%typemap(jtype) jstring "String"
-%typemap(jtype) jobject "java.lang.Object"
-%typemap(jtype) jbooleanArray "boolean[]"
-%typemap(jtype) jcharArray "char[]"
-%typemap(jtype) jbyteArray "byte[]"
-%typemap(jtype) jshortArray "short[]"
-%typemap(jtype) jintArray "int[]"
-%typemap(jtype) jlongArray "long[]"
-%typemap(jtype) jfloatArray "float[]"
-%typemap(jtype) jdoubleArray "double[]"
-%typemap(jtype) jobjectArray "java.lang.Object[]"
-
-%typemap(jstype) jboolean "boolean"
-%typemap(jstype) jchar "char"
-%typemap(jstype) jbyte "byte"
-%typemap(jstype) jshort "short"
-%typemap(jstype) jint "int"
-%typemap(jstype) jlong "long"
-%typemap(jstype) jfloat "float"
-%typemap(jstype) jdouble "double"
-%typemap(jstype) jstring "String"
-%typemap(jstype) jobject "java.lang.Object"
-%typemap(jstype) jbooleanArray "boolean[]"
-%typemap(jstype) jcharArray "char[]"
-%typemap(jstype) jbyteArray "byte[]"
-%typemap(jstype) jshortArray "short[]"
-%typemap(jstype) jintArray "int[]"
-%typemap(jstype) jlongArray "long[]"
-%typemap(jstype) jfloatArray "float[]"
-%typemap(jstype) jdoubleArray "double[]"
-%typemap(jstype) jobjectArray "java.lang.Object[]"
-
-/* Non primitive types */
-%typemap(jni) SWIGTYPE "jlong"
-%typemap(jtype) SWIGTYPE "long"
-%typemap(jstype) SWIGTYPE "$&javaclassname"
-%typemap(jboxtype) SWIGTYPE "$typemap(jstype, $1_type)"
-
-%typemap(jni) SWIGTYPE [] "jlong"
-%typemap(jtype) SWIGTYPE [] "long"
-%typemap(jstype) SWIGTYPE [] "$javaclassname"
-
-%typemap(jni) SWIGTYPE * "jlong"
-%typemap(jtype) SWIGTYPE * "long"
-%typemap(jstype) SWIGTYPE * "$javaclassname"
-
-%typemap(jni) SWIGTYPE & "jlong"
-%typemap(jtype) SWIGTYPE & "long"
-%typemap(jstype) SWIGTYPE & "$javaclassname"
-
-%typemap(jni) SWIGTYPE && "jlong"
-%typemap(jtype) SWIGTYPE && "long"
-%typemap(jstype) SWIGTYPE && "$javaclassname"
-
-/* pointer to a class member */
-%typemap(jni) SWIGTYPE (CLASS::*) "jstring"
-%typemap(jtype) SWIGTYPE (CLASS::*) "String"
-%typemap(jstype) SWIGTYPE (CLASS::*) "$javaclassname"
-
-/* The following are the in, out, freearg, argout typemaps. These are the JNI code generating typemaps for converting from Java to C and visa versa. */
-
-/* primitive types */
-%typemap(in) bool
-%{ $1 = $input ? true : false; %}
-
-%typemap(directorout) bool
-%{ $result = $input ? true : false; %}
-
-%typemap(javadirectorin) bool "$jniinput"
-%typemap(javadirectorout) bool "$javacall"
-
-%typemap(in) char,
- signed char,
- unsigned char,
- short,
- unsigned short,
- int,
- unsigned int,
- long,
- unsigned long,
- long long,
- float,
- double
-%{ $1 = ($1_ltype)$input; %}
-
-%typemap(directorout) char,
- signed char,
- unsigned char,
- short,
- unsigned short,
- int,
- unsigned int,
- long,
- unsigned long,
- long long,
- float,
- double
-%{ $result = ($1_ltype)$input; %}
-
-%typemap(directorin, descriptor="Z") bool "$input = (jboolean) $1;"
-%typemap(directorin, descriptor="C") char "$input = (jint) $1;"
-%typemap(directorin, descriptor="B") signed char "$input = (jbyte) $1;"
-%typemap(directorin, descriptor="S") unsigned char "$input = (jshort) $1;"
-%typemap(directorin, descriptor="S") short "$input = (jshort) $1;"
-%typemap(directorin, descriptor="I") unsigned short "$input = (jint) $1;"
-%typemap(directorin, descriptor="I") int "$input = (jint) $1;"
-%typemap(directorin, descriptor="J") unsigned int "$input = (jlong) $1;"
-%typemap(directorin, descriptor="I") long "$input = (jint) $1;"
-%typemap(directorin, descriptor="J") unsigned long "$input = (jlong) $1;"
-%typemap(directorin, descriptor="J") long long "$input = (jlong) $1;"
-%typemap(directorin, descriptor="F") float "$input = (jfloat) $1;"
-%typemap(directorin, descriptor="D") double "$input = (jdouble) $1;"
-
-%typemap(javadirectorin) char,
- signed char,
- unsigned char,
- short,
- unsigned short,
- int,
- unsigned int,
- long,
- unsigned long,
- long long,
- float,
- double
- "$jniinput"
-
-%typemap(javadirectorout) char,
- signed char,
- unsigned char,
- short,
- unsigned short,
- int,
- unsigned int,
- long,
- unsigned long,
- long long,
- float,
- double
- "$javacall"
-
-%typemap(out) bool %{ $result = (jboolean)$1; %}
-%typemap(out) char %{ $result = (jchar)$1; %}
-%typemap(out) signed char %{ $result = (jbyte)$1; %}
-%typemap(out) unsigned char %{ $result = (jshort)$1; %}
-%typemap(out) short %{ $result = (jshort)$1; %}
-%typemap(out) unsigned short %{ $result = (jint)$1; %}
-%typemap(out) int %{ $result = (jint)$1; %}
-%typemap(out) unsigned int %{ $result = (jlong)$1; %}
-%typemap(out) long %{ $result = (jint)$1; %}
-%typemap(out) unsigned long %{ $result = (jlong)$1; %}
-%typemap(out) long long %{ $result = (jlong)$1; %}
-%typemap(out) float %{ $result = (jfloat)$1; %}
-%typemap(out) double %{ $result = (jdouble)$1; %}
-
-/* unsigned long long */
-/* Convert from BigInteger using the toByteArray member function */
-%typemap(in) unsigned long long {
- jclass clazz;
- jmethodID mid;
- jbyteArray ba;
- jbyte* bae;
- jsize sz;
- int i;
-
- if (!$input) {
- SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null");
- return $null;
- }
- clazz = JCALL1(GetObjectClass, jenv, $input);
- mid = JCALL3(GetMethodID, jenv, clazz, "toByteArray", "()[B");
- ba = (jbyteArray)JCALL2(CallObjectMethod, jenv, $input, mid);
- bae = JCALL2(GetByteArrayElements, jenv, ba, 0);
- sz = JCALL1(GetArrayLength, jenv, ba);
- $1 = 0;
- if (sz > 0) {
- $1 = ($1_type)(signed char)bae[0];
- for(i=1; i<sz; i++) {
- $1 = ($1 << 8) | ($1_type)(unsigned char)bae[i];
- }
- }
- JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
-}
-
-%typemap(directorout) unsigned long long {
- jclass clazz;
- jmethodID mid;
- jbyteArray ba;
- jbyte* bae;
- jsize sz;
- int i;
-
- if (!$input) {
- SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null");
- return $null;
- }
- clazz = JCALL1(GetObjectClass, jenv, $input);
- mid = JCALL3(GetMethodID, jenv, clazz, "toByteArray", "()[B");
- ba = (jbyteArray)JCALL2(CallObjectMethod, jenv, $input, mid);
- bae = JCALL2(GetByteArrayElements, jenv, ba, 0);
- sz = JCALL1(GetArrayLength, jenv, ba);
- $result = 0;
- if (sz > 0) {
- $result = ($1_type)(signed char)bae[0];
- for(i=1; i<sz; i++) {
- $result = ($result << 8) | ($1_type)(unsigned char)bae[i];
- }
- }
- JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
-}
-
-
-/* Convert to BigInteger - byte array holds number in 2's complement big endian format */
-%typemap(out) unsigned long long {
- jbyteArray ba = JCALL1(NewByteArray, jenv, 9);
- jbyte* bae = JCALL2(GetByteArrayElements, jenv, ba, 0);
- jclass clazz = JCALL1(FindClass, jenv, "java/math/BigInteger");
- jmethodID mid = JCALL3(GetMethodID, jenv, clazz, "<init>", "([B)V");
- jobject bigint;
- int i;
-
- bae[0] = 0;
- for(i=1; i<9; i++ ) {
- bae[i] = (jbyte)($1>>8*(8-i));
- }
-
- JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
- bigint = JCALL3(NewObject, jenv, clazz, mid, ba);
- JCALL1(DeleteLocalRef, jenv, ba);
- $result = bigint;
-}
-
-/* Convert to BigInteger (see out typemap) */
-%typemap(directorin, descriptor="Ljava/math/BigInteger;", noblock=1) unsigned long long, const unsigned long long & {
-{
- jbyteArray ba = JCALL1(NewByteArray, jenv, 9);
- jbyte* bae = JCALL2(GetByteArrayElements, jenv, ba, 0);
- jclass clazz = JCALL1(FindClass, jenv, "java/math/BigInteger");
- jmethodID mid = JCALL3(GetMethodID, jenv, clazz, "<init>", "([B)V");
- jobject bigint;
- int swig_i;
-
- bae[0] = 0;
- for(swig_i=1; swig_i<9; swig_i++ ) {
- bae[swig_i] = (jbyte)($1>>8*(8-swig_i));
- }
-
- JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
- bigint = JCALL3(NewObject, jenv, clazz, mid, ba);
- JCALL1(DeleteLocalRef, jenv, ba);
- $input = bigint;
-}
-Swig::LocalRefGuard $1_refguard(jenv, $input); }
-
-%typemap(javadirectorin) unsigned long long "$jniinput"
-%typemap(javadirectorout) unsigned long long "$javacall"
-
-/* char * - treat as String */
-%typemap(in, noblock=1) char * {
- $1 = 0;
- if ($input) {
- $1 = ($1_ltype)JCALL2(GetStringUTFChars, jenv, $input, 0);
- if (!$1) return $null;
- }
-}
-
-%typemap(directorout, noblock=1, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) char * {
- $1 = 0;
- if ($input) {
- $result = ($1_ltype)JCALL2(GetStringUTFChars, jenv, $input, 0);
- if (!$result) return $null;
- }
-}
-
-%typemap(directorin, descriptor="Ljava/lang/String;", noblock=1) char * {
- $input = 0;
- if ($1) {
- $input = JCALL1(NewStringUTF, jenv, (const char *)$1);
- if (!$input) return $null;
- }
- Swig::LocalRefGuard $1_refguard(jenv, $input);
-}
-
-%typemap(freearg, noblock=1) char * { if ($1) JCALL2(ReleaseStringUTFChars, jenv, $input, (const char *)$1); }
-%typemap(out, noblock=1) char * { if ($1) $result = JCALL1(NewStringUTF, jenv, (const char *)$1); }
-%typemap(javadirectorin) char * "$jniinput"
-%typemap(javadirectorout) char * "$javacall"
-
-/* char *& - treat as String */
-%typemap(in, noblock=1) char *& ($*1_ltype temp = 0) {
- $1 = 0;
- if ($input) {
- temp = ($*1_ltype)JCALL2(GetStringUTFChars, jenv, $input, 0);
- if (!temp) return $null;
- }
- $1 = &temp;
-}
-%typemap(freearg, noblock=1) char *& { if ($1 && *$1) JCALL2(ReleaseStringUTFChars, jenv, $input, (const char *)*$1); }
-%typemap(out, noblock=1) char *& { if (*$1) $result = JCALL1(NewStringUTF, jenv, (const char *)*$1); }
-
-%typemap(out) void ""
-%typemap(javadirectorin) void "$jniinput"
-%typemap(javadirectorout) void "$javacall"
-%typemap(directorin, descriptor="V") void ""
-
-/* primitive types by reference */
-%typemap(in) const bool & ($*1_ltype temp)
-%{ temp = $input ? true : false;
- $1 = &temp; %}
-
-%typemap(directorout,warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) const bool &
-%{ static $*1_ltype temp;
- temp = $input ? true : false;
- $result = &temp; %}
-
-%typemap(javadirectorin) const bool & "$jniinput"
-%typemap(javadirectorout) const bool & "$javacall"
-
-%typemap(in) const char & ($*1_ltype temp),
- const signed char & ($*1_ltype temp),
- const unsigned char & ($*1_ltype temp),
- const short & ($*1_ltype temp),
- const unsigned short & ($*1_ltype temp),
- const int & ($*1_ltype temp),
- const unsigned int & ($*1_ltype temp),
- const long & ($*1_ltype temp),
- const unsigned long & ($*1_ltype temp),
- const long long & ($*1_ltype temp),
- const float & ($*1_ltype temp),
- const double & ($*1_ltype temp)
-%{ temp = ($*1_ltype)$input;
- $1 = &temp; %}
-
-%typemap(directorout,warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) const char &,
- const signed char &,
- const unsigned char &,
- const short &,
- const unsigned short &,
- const int &,
- const unsigned int &,
- const long &,
- const unsigned long &,
- const long long &,
- const float &,
- const double &
-%{ static $*1_ltype temp;
- temp = ($*1_ltype)$input;
- $result = &temp; %}
-
-%typemap(directorin, descriptor="Z") const bool & "$input = (jboolean)$1;"
-%typemap(directorin, descriptor="C") const char & "$input = (jchar)$1;"
-%typemap(directorin, descriptor="B") const signed char & "$input = (jbyte)$1;"
-%typemap(directorin, descriptor="S") const unsigned char & "$input = (jshort)$1;"
-%typemap(directorin, descriptor="S") const short & "$input = (jshort)$1;"
-%typemap(directorin, descriptor="I") const unsigned short & "$input = (jint)$1;"
-%typemap(directorin, descriptor="I") const int & "$input = (jint)$1;"
-%typemap(directorin, descriptor="J") const unsigned int & "$input = (jlong)$1;"
-%typemap(directorin, descriptor="I") const long & "$input = (jint)$1;"
-%typemap(directorin, descriptor="J") const unsigned long & "$input = (jlong)$1;"
-%typemap(directorin, descriptor="J") const long long & "$input = (jlong)$1;"
-%typemap(directorin, descriptor="F") const float & "$input = (jfloat)$1;"
-%typemap(directorin, descriptor="D") const double & "$input = (jdouble)$1;"
-
-%typemap(javadirectorin) const char & ($*1_ltype temp),
- const signed char & ($*1_ltype temp),
- const unsigned char & ($*1_ltype temp),
- const short & ($*1_ltype temp),
- const unsigned short & ($*1_ltype temp),
- const int & ($*1_ltype temp),
- const unsigned int & ($*1_ltype temp),
- const long & ($*1_ltype temp),
- const unsigned long & ($*1_ltype temp),
- const long long & ($*1_ltype temp),
- const float & ($*1_ltype temp),
- const double & ($*1_ltype temp)
- "$jniinput"
-
-%typemap(javadirectorout) const char & ($*1_ltype temp),
- const signed char & ($*1_ltype temp),
- const unsigned char & ($*1_ltype temp),
- const short & ($*1_ltype temp),
- const unsigned short & ($*1_ltype temp),
- const int & ($*1_ltype temp),
- const unsigned int & ($*1_ltype temp),
- const long & ($*1_ltype temp),
- const unsigned long & ($*1_ltype temp),
- const long long & ($*1_ltype temp),
- const float & ($*1_ltype temp),
- const double & ($*1_ltype temp)
- "$javacall"
-
-
-%typemap(out) const bool & %{ $result = (jboolean)*$1; %}
-%typemap(out) const char & %{ $result = (jchar)*$1; %}
-%typemap(out) const signed char & %{ $result = (jbyte)*$1; %}
-%typemap(out) const unsigned char & %{ $result = (jshort)*$1; %}
-%typemap(out) const short & %{ $result = (jshort)*$1; %}
-%typemap(out) const unsigned short & %{ $result = (jint)*$1; %}
-%typemap(out) const int & %{ $result = (jint)*$1; %}
-%typemap(out) const unsigned int & %{ $result = (jlong)*$1; %}
-%typemap(out) const long & %{ $result = (jint)*$1; %}
-%typemap(out) const unsigned long & %{ $result = (jlong)*$1; %}
-%typemap(out) const long long & %{ $result = (jlong)*$1; %}
-%typemap(out) const float & %{ $result = (jfloat)*$1; %}
-%typemap(out) const double & %{ $result = (jdouble)*$1; %}
-
-/* const unsigned long long & */
-/* Similar to unsigned long long */
-%typemap(in) const unsigned long long & ($*1_ltype temp) {
- jclass clazz;
- jmethodID mid;
- jbyteArray ba;
- jbyte* bae;
- jsize sz;
- int i;
-
- if (!$input) {
- SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null");
- return $null;
- }
- clazz = JCALL1(GetObjectClass, jenv, $input);
- mid = JCALL3(GetMethodID, jenv, clazz, "toByteArray", "()[B");
- ba = (jbyteArray)JCALL2(CallObjectMethod, jenv, $input, mid);
- bae = JCALL2(GetByteArrayElements, jenv, ba, 0);
- sz = JCALL1(GetArrayLength, jenv, ba);
- $1 = &temp;
- temp = 0;
- if (sz > 0) {
- temp = ($*1_ltype)(signed char)bae[0];
- for(i=1; i<sz; i++) {
- temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i];
- }
- }
- JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
-}
-
-%typemap(directorout,warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) const unsigned long long & {
- static $*1_ltype temp;
- jclass clazz;
- jmethodID mid;
- jbyteArray ba;
- jbyte* bae;
- jsize sz;
- int i;
-
- if (!$input) {
- SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null");
- return $null;
- }
- clazz = JCALL1(GetObjectClass, jenv, $input);
- mid = JCALL3(GetMethodID, jenv, clazz, "toByteArray", "()[B");
- ba = (jbyteArray)JCALL2(CallObjectMethod, jenv, $input, mid);
- bae = JCALL2(GetByteArrayElements, jenv, ba, 0);
- sz = JCALL1(GetArrayLength, jenv, ba);
- $result = &temp;
- temp = 0;
- if (sz > 0) {
- temp = ($*1_ltype)(signed char)bae[0];
- for(i=1; i<sz; i++) {
- temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i];
- }
- }
- JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
-}
-
-%typemap(out) const unsigned long long & {
- jbyteArray ba = JCALL1(NewByteArray, jenv, 9);
- jbyte* bae = JCALL2(GetByteArrayElements, jenv, ba, 0);
- jclass clazz = JCALL1(FindClass, jenv, "java/math/BigInteger");
- jmethodID mid = JCALL3(GetMethodID, jenv, clazz, "<init>", "([B)V");
- jobject bigint;
- int i;
-
- bae[0] = 0;
- for(i=1; i<9; i++ ) {
- bae[i] = (jbyte)(*$1>>8*(8-i));
- }
-
- JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
- bigint = JCALL3(NewObject, jenv, clazz, mid, ba);
- JCALL1(DeleteLocalRef, jenv, ba);
- $result = bigint;
-}
-
-%typemap(javadirectorin) const unsigned long long & "$jniinput"
-%typemap(javadirectorout) const unsigned long long & "$javacall"
-
-/* Default handling. Object passed by value. Convert to a pointer */
-%typemap(in) SWIGTYPE ($&1_type argp)
-%{ argp = *($&1_ltype*)&$input;
- if (!argp) {
- SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null $1_type");
- return $null;
- }
- $1 = *argp; %}
-
-%typemap(directorout) SWIGTYPE ($&1_type argp)
-%{ argp = *($&1_ltype*)&$input;
- if (!argp) {
- SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Unexpected null return for type $1_type");
- return $null;
- }
- $result = *argp; %}
-
-%typemap(out) SWIGTYPE
-#ifdef __cplusplus
-%{ *($&1_ltype*)&$result = new $1_ltype($1); %}
-#else
-{
- $&1_ltype $1ptr = ($&1_ltype) malloc(sizeof($1_ltype));
- memmove($1ptr, &$1, sizeof($1_type));
- *($&1_ltype*)&$result = $1ptr;
-}
-#endif
-
-%typemap(directorin,descriptor="L$packagepath/$&javaclassname;") SWIGTYPE
-%{ $input = 0;
- *(($&1_ltype*)&$input) = new $1_ltype(SWIG_STD_MOVE($1)); %}
-%typemap(javadirectorin) SWIGTYPE "new $&javaclassname($jniinput, true)"
-%typemap(javadirectorout) SWIGTYPE "$&javaclassname.getCPtr($javacall)"
-
-/* Generic pointers and references */
-%typemap(in) SWIGTYPE * %{ $1 = *($&1_ltype)&$input; %}
-%typemap(in, fragment="SWIG_UnPackData") SWIGTYPE (CLASS::*) {
- const char *temp = 0;
- if ($input) {
- temp = JCALL2(GetStringUTFChars, jenv, $input, 0);
- if (!temp) return $null;
- }
- SWIG_UnpackData(temp, (void *)&$1, sizeof($1));
-}
-%typemap(in) SWIGTYPE & %{ $1 = *($&1_ltype)&$input;
- if (!$1) {
- SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type is null");
- return $null;
- } %}
-%typemap(in, fragment="<memory>") SWIGTYPE && (std::unique_ptr<$*1_ltype> rvrdeleter) %{ $1 = *($&1_ltype)&$input;
- if (!$1) {
- SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type is null");
- return $null;
- }
- rvrdeleter.reset($1); %}
-%typemap(out) SWIGTYPE *
-%{ *($&1_ltype)&$result = $1; %}
-%typemap(out, fragment="SWIG_PackData", noblock=1) SWIGTYPE (CLASS::*) {
- char buf[128];
- char *data = SWIG_PackData(buf, (void *)&$1, sizeof($1));
- *data = '\0';
- $result = JCALL1(NewStringUTF, jenv, buf);
-}
-%typemap(out) SWIGTYPE &
-%{ *($&1_ltype)&$result = $1; %}
-%typemap(out) SWIGTYPE &&
-%{ *($&1_ltype)&$result = $1; %}
-
-%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE *
-%{ $result = *($&1_ltype)&$input; %}
-%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE (CLASS::*)
-%{ $result = *($&1_ltype)&$input; %}
-
-%typemap(directorin,descriptor="L$packagepath/$javaclassname;") SWIGTYPE *
-%{ *(($&1_ltype)&$input) = ($1_ltype) $1; %}
-%typemap(directorin,descriptor="L$packagepath/$javaclassname;") SWIGTYPE (CLASS::*)
-%{ *(($&1_ltype)&$input) = ($1_ltype) $1; %}
-
-%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE &
-%{ if (!$input) {
- SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Unexpected null return for type $1_type");
- return $null;
- }
- $result = *($&1_ltype)&$input; %}
-%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE &&
-%{ if (!$input) {
- SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Unexpected null return for type $1_type");
- return $null;
- }
- $result = *($&1_ltype)&$input; %}
-%typemap(directorin,descriptor="L$packagepath/$javaclassname;") SWIGTYPE &
-%{ *($&1_ltype)&$input = ($1_ltype) &$1; %}
-%typemap(directorin,descriptor="L$packagepath/$javaclassname;") SWIGTYPE &&
-%{ *($&1_ltype)&$input = ($1_ltype) &$1; %}
-
-%typemap(javadirectorin) SWIGTYPE *, SWIGTYPE (CLASS::*) "($jniinput == 0) ? null : new $javaclassname($jniinput, false)"
-%typemap(javadirectorin) SWIGTYPE & "new $javaclassname($jniinput, false)"
-%typemap(javadirectorin) SWIGTYPE && "new $javaclassname($jniinput, false)"
-%typemap(javadirectorout) SWIGTYPE *, SWIGTYPE (CLASS::*), SWIGTYPE &, SWIGTYPE && "$javaclassname.getCPtr($javacall)"
-
-/* Default array handling */
-%typemap(in) SWIGTYPE [] %{ $1 = *($&1_ltype)&$input; %}
-%typemap(out) SWIGTYPE [] %{ *($&1_ltype)&$result = $1; %}
-%typemap(freearg) SWIGTYPE [ANY], SWIGTYPE [] ""
-
-/* char arrays - treat as String */
-%typemap(in, noblock=1) char[ANY], char[] {
- $1 = 0;
- if ($input) {
- $1 = ($1_ltype)JCALL2(GetStringUTFChars, jenv, $input, 0);
- if (!$1) return $null;
- }
-}
-
-%typemap(directorout, noblock=1) char[ANY], char[] {
- $1 = 0;
- if ($input) {
- $result = ($1_ltype)JCALL2(GetStringUTFChars, jenv, $input, 0);
- if (!$result) return $null;
- }
-}
-
-%typemap(directorin, descriptor="Ljava/lang/String;", noblock=1) char[ANY], char[] {
- $input = 0;
- if ($1) {
- $input = JCALL1(NewStringUTF, jenv, (const char *)$1);
- if (!$input) return $null;
- }
- Swig::LocalRefGuard $1_refguard(jenv, $input);
-}
-
-%typemap(argout) char[ANY], char[] ""
-%typemap(freearg, noblock=1) char[ANY], char[] { if ($1) JCALL2(ReleaseStringUTFChars, jenv, $input, (const char *)$1); }
-%typemap(out, noblock=1) char[ANY], char[] { if ($1) $result = JCALL1(NewStringUTF, jenv, (const char *)$1); }
-%typemap(javadirectorin) char[ANY], char[] "$jniinput"
-%typemap(javadirectorout) char[ANY], char[] "$javacall"
-
-/* JNI types */
-%typemap(in) jboolean,
- jchar,
- jbyte,
- jshort,
- jint,
- jlong,
- jfloat,
- jdouble,
- jstring,
- jobject,
- jbooleanArray,
- jcharArray,
- jbyteArray,
- jshortArray,
- jintArray,
- jlongArray,
- jfloatArray,
- jdoubleArray,
- jobjectArray
-%{ $1 = $input; %}
-
-%typemap(directorout) jboolean,
- jchar,
- jbyte,
- jshort,
- jint,
- jlong,
- jfloat,
- jdouble,
- jstring,
- jobject,
- jbooleanArray,
- jcharArray,
- jbyteArray,
- jshortArray,
- jintArray,
- jlongArray,
- jfloatArray,
- jdoubleArray,
- jobjectArray
-%{ $result = $input; %}
-
-%typemap(out) jboolean,
- jchar,
- jbyte,
- jshort,
- jint,
- jlong,
- jfloat,
- jdouble,
- jstring,
- jobject,
- jbooleanArray,
- jcharArray,
- jbyteArray,
- jshortArray,
- jintArray,
- jlongArray,
- jfloatArray,
- jdoubleArray,
- jobjectArray
-%{ $result = $1; %}
-
-%typemap(directorin,descriptor="Z") jboolean "$input = $1;"
-%typemap(directorin,descriptor="C") jchar "$input = $1;"
-%typemap(directorin,descriptor="B") jbyte "$input = $1;"
-%typemap(directorin,descriptor="S") jshort "$input = $1;"
-%typemap(directorin,descriptor="I") jint "$input = $1;"
-%typemap(directorin,descriptor="J") jlong "$input = $1;"
-%typemap(directorin,descriptor="F") jfloat "$input = $1;"
-%typemap(directorin,descriptor="D") jdouble "$input = $1;"
-%typemap(directorin,descriptor="Ljava/lang/String;") jstring "$input = $1;"
-%typemap(directorin,descriptor="Ljava/lang/Object;",nouse="1") jobject "$input = $1;"
-%typemap(directorin,descriptor="[Z") jbooleanArray "$input = $1;"
-%typemap(directorin,descriptor="[C") jcharArray "$input = $1;"
-%typemap(directorin,descriptor="[B") jbyteArray "$input = $1;"
-%typemap(directorin,descriptor="[S") jshortArray "$input = $1;"
-%typemap(directorin,descriptor="[I") jintArray "$input = $1;"
-%typemap(directorin,descriptor="[J") jlongArray "$input = $1;"
-%typemap(directorin,descriptor="[F") jfloatArray "$input = $1;"
-%typemap(directorin,descriptor="[D") jdoubleArray "$input = $1;"
-%typemap(directorin,descriptor="[Ljava/lang/Object;",nouse="1") jobjectArray "$input = $1;"
-
-%typemap(javadirectorin) jboolean,
- jchar,
- jbyte,
- jshort,
- jint,
- jlong,
- jfloat,
- jdouble,
- jstring,
- jobject,
- jbooleanArray,
- jcharArray,
- jbyteArray,
- jshortArray,
- jintArray,
- jlongArray,
- jfloatArray,
- jdoubleArray,
- jobjectArray
- "$jniinput"
-
-%typemap(javadirectorout) jboolean,
- jchar,
- jbyte,
- jshort,
- jint,
- jlong,
- jfloat,
- jdouble,
- jstring,
- jobject,
- jbooleanArray,
- jcharArray,
- jbyteArray,
- jshortArray,
- jintArray,
- jlongArray,
- jfloatArray,
- jdoubleArray,
- jobjectArray
- "$javacall"
-
-/* Typecheck typemaps - The purpose of these is merely to issue a warning for overloaded C++ functions
- * that cannot be overloaded in Java as more than one C++ type maps to a single Java type */
-
-%typecheck(SWIG_TYPECHECK_BOOL) /* Java boolean */
- jboolean,
- bool,
- const bool &
- ""
-
-%typecheck(SWIG_TYPECHECK_CHAR) /* Java char */
- jchar,
- char,
- const char &
- ""
-
-%typecheck(SWIG_TYPECHECK_INT8) /* Java byte */
- jbyte,
- signed char,
- const signed char &
- ""
-
-%typecheck(SWIG_TYPECHECK_INT16) /* Java short */
- jshort,
- unsigned char,
- short,
- const unsigned char &,
- const short &
- ""
-
-%typecheck(SWIG_TYPECHECK_INT32) /* Java int */
- jint,
- unsigned short,
- int,
- long,
- const unsigned short &,
- const int &,
- const long &
- ""
-
-%typecheck(SWIG_TYPECHECK_INT64) /* Java long */
- jlong,
- unsigned int,
- unsigned long,
- long long,
- const unsigned int &,
- const unsigned long &,
- const long long &
- ""
-
-%typecheck(SWIG_TYPECHECK_INT128) /* Java BigInteger */
- unsigned long long,
- const unsigned long long &
- ""
-
-%typecheck(SWIG_TYPECHECK_FLOAT) /* Java float */
- jfloat,
- float,
- const float &
- ""
-
-%typecheck(SWIG_TYPECHECK_DOUBLE) /* Java double */
- jdouble,
- double,
- const double &
- ""
-
-%typecheck(SWIG_TYPECHECK_STRING) /* Java String */
- jstring,
- char *,
- char *&,
- char[ANY],
- char []
- ""
-
-%typecheck(SWIG_TYPECHECK_BOOL_ARRAY) /* Java boolean[] */
- jbooleanArray
- ""
-
-%typecheck(SWIG_TYPECHECK_CHAR_ARRAY) /* Java char[] */
- jcharArray
- ""
-
-%typecheck(SWIG_TYPECHECK_INT8_ARRAY) /* Java byte[] */
- jbyteArray
- ""
-
-%typecheck(SWIG_TYPECHECK_INT16_ARRAY) /* Java short[] */
- jshortArray
- ""
-
-%typecheck(SWIG_TYPECHECK_INT32_ARRAY) /* Java int[] */
- jintArray
- ""
-
-%typecheck(SWIG_TYPECHECK_INT64_ARRAY) /* Java long[] */
- jlongArray
- ""
-
-%typecheck(SWIG_TYPECHECK_FLOAT_ARRAY) /* Java float[] */
- jfloatArray
- ""
-
-%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY) /* Java double[] */
- jdoubleArray
- ""
-
-%typecheck(SWIG_TYPECHECK_OBJECT_ARRAY) /* Java jobject[] */
- jobjectArray
- ""
-
-%typecheck(SWIG_TYPECHECK_POINTER) /* Default */
- SWIGTYPE,
- SWIGTYPE *,
- SWIGTYPE &,
- SWIGTYPE &&,
- SWIGTYPE *const&,
- SWIGTYPE [],
- SWIGTYPE (CLASS::*)
- ""
-
-
-/* Exception handling */
-
-%typemap(throws) int,
- long,
- short,
- unsigned int,
- unsigned long,
- unsigned short
-%{ char error_msg[256];
- sprintf(error_msg, "C++ $1_type exception thrown, value: %d", $1);
- SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, error_msg);
- return $null; %}
-
-%typemap(throws) SWIGTYPE, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE *, SWIGTYPE [], SWIGTYPE [ANY]
-%{ (void)$1;
- SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, "C++ $1_type exception thrown");
- return $null; %}
-
-%typemap(throws) char *
-%{ SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, $1);
- return $null; %}
-
-/* For methods to raise/throw the original Java exception thrown in a director method */
-%typemap(throws) Swig::DirectorException
-%{ $1.throwException(jenv);
- return $null; %}
-
-/* Java to C++ DirectorException should already be handled. Suppress warning and do nothing in the
- event a user specifies a global: %catches(Swig::DirectorException); */
-%typemap(directorthrows) Swig::DirectorException ""
-
-/* Typemaps for code generation in proxy classes and Java type wrapper classes */
-
-/* The javain typemap is used for converting function parameter types from the type
- * used in the proxy, module or type wrapper class to the type used in the JNI class. */
-%typemap(javain) bool, const bool &,
- char, const char &,
- signed char, const signed char &,
- unsigned char, const unsigned char &,
- short, const short &,
- unsigned short, const unsigned short &,
- int, const int &,
- unsigned int, const unsigned int &,
- long, const long &,
- unsigned long, const unsigned long &,
- long long, const long long &,
- unsigned long long, const unsigned long long &,
- float, const float &,
- double, const double &
- "$javainput"
-%typemap(javain) char *, char *&, char[ANY], char[] "$javainput"
-%typemap(javain) jboolean,
- jchar,
- jbyte,
- jshort,
- jint,
- jlong,
- jfloat,
- jdouble,
- jstring,
- jobject,
- jbooleanArray,
- jcharArray,
- jbyteArray,
- jshortArray,
- jintArray,
- jlongArray,
- jfloatArray,
- jdoubleArray,
- jobjectArray
- "$javainput"
-%typemap(javain) SWIGTYPE "$&javaclassname.getCPtr($javainput)"
-%typemap(javain) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "$javaclassname.getCPtr($javainput)"
-%typemap(javain) SWIGTYPE && "$javaclassname.swigRelease($javainput)"
-%typemap(javain) SWIGTYPE (CLASS::*) "$javaclassname.getCMemberPtr($javainput)"
-
-/* The javaout typemap is used for converting function return types from the return type
- * used in the JNI class to the type returned by the proxy, module or type wrapper class. */
-%typemap(javaout) bool, const bool &,
- char, const char &,
- signed char, const signed char &,
- unsigned char, const unsigned char &,
- short, const short &,
- unsigned short, const unsigned short &,
- int, const int &,
- unsigned int, const unsigned int &,
- long, const long &,
- unsigned long, const unsigned long &,
- long long, const long long &,
- unsigned long long, const unsigned long long &,
- float, const float &,
- double, const double & {
- return $jnicall;
- }
-%typemap(javaout) char *, char *&, char[ANY], char[] {
- return $jnicall;
- }
-%typemap(javaout) jboolean,
- jchar,
- jbyte,
- jshort,
- jint,
- jlong,
- jfloat,
- jdouble,
- jstring,
- jobject,
- jbooleanArray,
- jcharArray,
- jbyteArray,
- jshortArray,
- jintArray,
- jlongArray,
- jfloatArray,
- jdoubleArray,
- jobjectArray {
- return $jnicall;
- }
-%typemap(javaout) void {
- $jnicall;
- }
-%typemap(javaout) SWIGTYPE {
- return new $&javaclassname($jnicall, true);
- }
-%typemap(javaout) SWIGTYPE & {
- return new $javaclassname($jnicall, $owner);
- }
-%typemap(javaout) SWIGTYPE && {
- return new $javaclassname($jnicall, $owner);
- }
-%typemap(javaout) SWIGTYPE *, SWIGTYPE [] {
- long cPtr = $jnicall;
- return (cPtr == 0) ? null : new $javaclassname(cPtr, $owner);
- }
-%typemap(javaout) SWIGTYPE (CLASS::*) {
- String cMemberPtr = $jnicall;
- return (cMemberPtr == null) ? null : new $javaclassname(cMemberPtr, $owner);
- }
-
-/* Pointer reference typemaps */
-%typemap(jni) SWIGTYPE *const& "jlong"
-%typemap(jtype) SWIGTYPE *const& "long"
-%typemap(jstype) SWIGTYPE *const& "$*javaclassname"
-%typemap(javain) SWIGTYPE *const& "$*javaclassname.getCPtr($javainput)"
-%typemap(javaout) SWIGTYPE *const& {
- long cPtr = $jnicall;
- return (cPtr == 0) ? null : new $*javaclassname(cPtr, $owner);
- }
-%typemap(in) SWIGTYPE *const& ($*1_ltype temp = 0)
-%{ temp = *($1_ltype)&$input;
- $1 = ($1_ltype)&temp; %}
-%typemap(out) SWIGTYPE *const&
-%{ *($1_ltype)&$result = *$1; %}
-%typemap(directorin,descriptor="L$packagepath/$*javaclassname;") SWIGTYPE *const&
-%{ *(($1_ltype)&$input) = ($*1_ltype) $1; %}
-%typemap(directorout, warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) SWIGTYPE *const&
-%{ static $*1_ltype swig_temp;
- swig_temp = *($1_ltype)&$input;
- $result = &swig_temp; %}
-%typemap(javadirectorin) SWIGTYPE *const& "($jniinput == 0) ? null : new $*javaclassname($jniinput, false)"
-%typemap(javadirectorout) SWIGTYPE *const& "$*javaclassname.getCPtr($javacall)"
-
-/* Typemaps used for the generation of proxy and type wrapper class code */
-%typemap(javabase) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
-%typemap(javaclassmodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) "public class"
-%typemap(javacode) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
-%typemap(javaimports) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
-%typemap(javainterfaces) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
-%typemap(javainterfacemodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) "public interface"
-
-/* javabody typemaps */
-
-%define SWIG_JAVABODY_METHODS(PTRCTOR_VISIBILITY, CPTR_VISIBILITY, TYPE...) SWIG_JAVABODY_PROXY(PTRCTOR_VISIBILITY, CPTR_VISIBILITY, TYPE) %enddef // legacy name
-
-%define SWIG_JAVABODY_PROXY(PTRCTOR_VISIBILITY, CPTR_VISIBILITY, TYPE...)
-// Base proxy classes
-%typemap(javabody) TYPE %{
- private transient long swigCPtr;
- protected transient boolean swigCMemOwn;
-
- PTRCTOR_VISIBILITY $javaclassname(long cPtr, boolean cMemoryOwn) {
- swigCMemOwn = cMemoryOwn;
- swigCPtr = cPtr;
- }
-
- CPTR_VISIBILITY static long getCPtr($javaclassname obj) {
- return (obj == null) ? 0 : obj.swigCPtr;
- }
-
- CPTR_VISIBILITY static long swigRelease($javaclassname obj) {
- long ptr = 0;
- if (obj != null) {
- if (!obj.swigCMemOwn)
- throw new RuntimeException("Cannot release ownership as memory is not owned");
- ptr = obj.swigCPtr;
- obj.swigCMemOwn = false;
- obj.delete();
- }
- return ptr;
- }
-%}
-
-// Derived proxy classes
-%typemap(javabody_derived) TYPE %{
- private transient long swigCPtr;
-
- PTRCTOR_VISIBILITY $javaclassname(long cPtr, boolean cMemoryOwn) {
- super($imclassname.$javaclazznameSWIGUpcast(cPtr), cMemoryOwn);
- swigCPtr = cPtr;
- }
-
- CPTR_VISIBILITY static long getCPtr($javaclassname obj) {
- return (obj == null) ? 0 : obj.swigCPtr;
- }
-
- CPTR_VISIBILITY static long swigRelease($javaclassname obj) {
- long ptr = 0;
- if (obj != null) {
- if (!obj.swigCMemOwn)
- throw new RuntimeException("Cannot release ownership as memory is not owned");
- ptr = obj.swigCPtr;
- obj.swigCMemOwn = false;
- obj.delete();
- }
- return ptr;
- }
-%}
-%enddef
-
-%define SWIG_JAVABODY_TYPEWRAPPER(PTRCTOR_VISIBILITY, DEFAULTCTOR_VISIBILITY, CPTR_VISIBILITY, TYPE...)
-// Typewrapper classes
-%typemap(javabody) TYPE *, TYPE &, TYPE &&, TYPE [] %{
- private transient long swigCPtr;
-
- PTRCTOR_VISIBILITY $javaclassname(long cPtr, @SuppressWarnings("unused") boolean futureUse) {
- swigCPtr = cPtr;
- }
-
- DEFAULTCTOR_VISIBILITY $javaclassname() {
- swigCPtr = 0;
- }
-
- CPTR_VISIBILITY static long getCPtr($javaclassname obj) {
- return (obj == null) ? 0 : obj.swigCPtr;
- }
-
- CPTR_VISIBILITY static long swigRelease($javaclassname obj) {
- return (obj == null) ? 0 : obj.swigCPtr;
- }
-%}
-
-%typemap(javabody) TYPE (CLASS::*) %{
- private transient String swigCMemberPtr;
-
- PTRCTOR_VISIBILITY $javaclassname(String cMemberPtr, @SuppressWarnings("unused") boolean futureUse) {
- swigCMemberPtr = cMemberPtr;
- }
-
- DEFAULTCTOR_VISIBILITY $javaclassname() {
- swigCMemberPtr = null;
- }
-
- CPTR_VISIBILITY static String getCMemberPtr($javaclassname obj) {
- return obj.swigCMemberPtr;
- }
-%}
-%enddef
-
-/* Set the default javabody typemaps to use protected visibility.
- Use the macros to change to public if using multiple modules. */
-SWIG_JAVABODY_PROXY(protected, protected, SWIGTYPE)
-SWIG_JAVABODY_TYPEWRAPPER(protected, protected, protected, SWIGTYPE)
-
-%typemap(javafinalize) SWIGTYPE %{
- @SuppressWarnings("deprecation")
- protected void finalize() {
- delete();
- }
-%}
-
-/*
- * Java constructor typemaps:
- *
- * The javaconstruct typemap is inserted when a proxy class's constructor is generated.
- * This typemap allows control over what code is executed in the constructor as
- * well as specifying who owns the underlying C/C++ object. Normally, Java has
- * ownership and the underlying C/C++ object is deallocated when the Java object
- * is finalized (swigCMemOwn is true.) If swigCMemOwn is false, C/C++ is
- * ultimately responsible for deallocating the underlying object's memory.
- *
- * The SWIG_PROXY_CONSTRUCTOR macro defines the javaconstruct typemap for a proxy
- * class for a particular TYPENAME. OWNERSHIP is passed as the value of
- * swigCMemOwn to the pointer constructor method. WEAKREF determines which kind
- * of Java object reference will be used by the C++ director class (WeakGlobalRef
- * vs. GlobalRef.)
- *
- * The SWIG_DIRECTOR_OWNED macro sets the ownership of director-based proxy
- * classes and the weak reference flag to false, meaning that the underlying C++
- * object will be reclaimed by C++.
- */
-
-%define SWIG_PROXY_CONSTRUCTOR(OWNERSHIP, WEAKREF, TYPENAME...)
-%typemap(javaconstruct,directorconnect="\n $imclassname.$javaclazznamedirector_connect(this, swigCPtr, OWNERSHIP, WEAKREF);") TYPENAME {
- this($imcall, OWNERSHIP);$directorconnect
- }
-%enddef
-
-%define SWIG_DIRECTOR_OWNED(TYPENAME...)
-SWIG_PROXY_CONSTRUCTOR(true, false, TYPENAME)
-%enddef
-
-// Set the default for SWIGTYPE: Java owns the C/C++ object.
-SWIG_PROXY_CONSTRUCTOR(true, true, SWIGTYPE)
-
-%typemap(javadestruct, methodname="delete", methodmodifiers="public synchronized", parameters="") SWIGTYPE {
- if (swigCPtr != 0) {
- if (swigCMemOwn) {
- swigCMemOwn = false;
- $jnicall;
- }
- swigCPtr = 0;
- }
- }
-
-%typemap(javadestruct_derived, methodname="delete", methodmodifiers="public synchronized", parameters="") SWIGTYPE {
- if (swigCPtr != 0) {
- if (swigCMemOwn) {
- swigCMemOwn = false;
- $jnicall;
- }
- swigCPtr = 0;
- }
- super.delete();
- }
-
-%typemap(directordisconnect, methodname="swigDirectorDisconnect") SWIGTYPE %{
- protected void $methodname() {
- swigCMemOwn = false;
- $jnicall;
- }
-%}
-
-%typemap(directorowner_release, methodname="swigReleaseOwnership") SWIGTYPE %{
- public void $methodname() {
- swigCMemOwn = false;
- $jnicall;
- }
-%}
-
-%typemap(directorowner_take, methodname="swigTakeOwnership") SWIGTYPE %{
- public void $methodname() {
- swigCMemOwn = true;
- $jnicall;
- }
-%}
-
-/* Java specific directives */
-#define %javaconst(flag) %feature("java:const","flag")
-#define %javaconstvalue(value) %feature("java:constvalue",value)
-#define %javaenum(wrapapproach) %feature("java:enum","wrapapproach")
-#define %javamethodmodifiers %feature("java:methodmodifiers")
-#define %javaexception(exceptionclasses) %feature("except",throws=exceptionclasses)
-#define %nojavaexception %feature("except","0",throws="")
-#define %clearjavaexception %feature("except","",throws="")
-#define %proxycode %insert("proxycode")
-
-%pragma(java) jniclassclassmodifiers="public class"
-%pragma(java) moduleclassmodifiers="public class"
-
-/* Some ANSI C typemaps */
-
-%apply unsigned long { size_t };
-%apply const unsigned long & { const size_t & };
-
-/* Array reference typemaps */
-%apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) }
-%apply SWIGTYPE && { SWIGTYPE ((&&)[ANY]) }
-
-/* const pointers */
-%apply SWIGTYPE * { SWIGTYPE *const }
-%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) }
-%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) }
-
-/* String & length */
-%typemap(jni) (const char *STRING, size_t LENGTH) "jbyteArray"
-%typemap(jtype) (const char *STRING, size_t LENGTH) "byte[]"
-%typemap(jstype) (const char *STRING, size_t LENGTH) "byte[]"
-%typemap(javain) (const char *STRING, size_t LENGTH) "$javainput"
-%typemap(freearg) (const char *STRING, size_t LENGTH) ""
-%typemap(in) (const char *STRING, size_t LENGTH) {
- if ($input) {
- $1 = ($1_ltype) JCALL2(GetByteArrayElements, jenv, $input, 0);
- $2 = ($2_type) JCALL1(GetArrayLength, jenv, $input);
- } else {
- $1 = 0;
- $2 = 0;
- }
-}
-%typemap(argout) (const char *STRING, size_t LENGTH) {
- if ($input) JCALL3(ReleaseByteArrayElements, jenv, $input, (jbyte *)$1, JNI_ABORT);
-}
-%typemap(directorin, descriptor="[B", noblock=1) (const char *STRING, size_t LENGTH) {
- $input = 0;
- if ($1) {
- $input = JCALL1(NewByteArray, jenv, (jsize)$2);
- if (!$input) return $null;
- JCALL4(SetByteArrayRegion, jenv, $input, 0, (jsize)$2, (jbyte *)$1);
- }
- Swig::LocalRefGuard $1_refguard(jenv, $input);
-}
-%typemap(javadirectorin, descriptor="[B") (const char *STRING, size_t LENGTH) "$jniinput"
-%apply (const char *STRING, size_t LENGTH) { (char *STRING, size_t LENGTH) }
-/* Enable write-back for non-const version */
-%typemap(argout) (char *STRING, size_t LENGTH) {
- if ($input) JCALL3(ReleaseByteArrayElements, jenv, $input, (jbyte *)$1, 0);
-}
-%typemap(directorargout, noblock=1) (char *STRING, size_t LENGTH)
-{ if ($input && $1) JCALL4(GetByteArrayRegion, jenv, $input, 0, (jsize)$2, (jbyte *)$1); }
-%apply (char *STRING, size_t LENGTH) { (char *STRING, int LENGTH) }
-
-/* java keywords */
-%include <javakw.swg>
-
-// Default enum handling
-%include <enumtypesafe.swg>
-
diff --git a/contrib/tools/swig/Lib/java/javahead.swg b/contrib/tools/swig/Lib/java/javahead.swg
deleted file mode 100644
index 758a037d17..0000000000
--- a/contrib/tools/swig/Lib/java/javahead.swg
+++ /dev/null
@@ -1,91 +0,0 @@
-/* -----------------------------------------------------------------------------
- * javahead.swg
- *
- * Java support code
- * ----------------------------------------------------------------------------- */
-
-
-/* JNI function calls require different calling conventions for C and C++. These JCALL macros are used so
- * that the same typemaps can be used for generating code for both C and C++. The SWIG preprocessor can expand
- * the macros thereby generating the correct calling convention. It is thus essential that all typemaps that
- * use the macros are not within %{ %} brackets as they won't be run through the SWIG preprocessor. */
-#ifdef __cplusplus
-# define JCALL0(func, jenv) jenv->func()
-# define JCALL1(func, jenv, ar1) jenv->func(ar1)
-# define JCALL2(func, jenv, ar1, ar2) jenv->func(ar1, ar2)
-# define JCALL3(func, jenv, ar1, ar2, ar3) jenv->func(ar1, ar2, ar3)
-# define JCALL4(func, jenv, ar1, ar2, ar3, ar4) jenv->func(ar1, ar2, ar3, ar4)
-# define JCALL5(func, jenv, ar1, ar2, ar3, ar4, ar5) jenv->func(ar1, ar2, ar3, ar4, ar5)
-# define JCALL6(func, jenv, ar1, ar2, ar3, ar4, ar5, ar6) jenv->func(ar1, ar2, ar3, ar4, ar5, ar6)
-# define JCALL7(func, jenv, ar1, ar2, ar3, ar4, ar5, ar6, ar7) jenv->func(ar1, ar2, ar3, ar4, ar5, ar6, ar7)
-#else
-# define JCALL0(func, jenv) (*jenv)->func(jenv)
-# define JCALL1(func, jenv, ar1) (*jenv)->func(jenv, ar1)
-# define JCALL2(func, jenv, ar1, ar2) (*jenv)->func(jenv, ar1, ar2)
-# define JCALL3(func, jenv, ar1, ar2, ar3) (*jenv)->func(jenv, ar1, ar2, ar3)
-# define JCALL4(func, jenv, ar1, ar2, ar3, ar4) (*jenv)->func(jenv, ar1, ar2, ar3, ar4)
-# define JCALL5(func, jenv, ar1, ar2, ar3, ar4, ar5) (*jenv)->func(jenv, ar1, ar2, ar3, ar4, ar5)
-# define JCALL6(func, jenv, ar1, ar2, ar3, ar4, ar5, ar6) (*jenv)->func(jenv, ar1, ar2, ar3, ar4, ar5, ar6)
-# define JCALL7(func, jenv, ar1, ar2, ar3, ar4, ar5, ar6, ar7) (*jenv)->func(jenv, ar1, ar2, ar3, ar4, ar5, ar6, ar7)
-#endif
-
-%insert(runtime) %{
-#include <jni.h>
-#include <stdlib.h>
-#include <string.h>
-%}
-
-%insert(runtime) %{
-/* Support for throwing Java exceptions */
-typedef enum {
- SWIG_JavaOutOfMemoryError = 1,
- SWIG_JavaIOException,
- SWIG_JavaRuntimeException,
- SWIG_JavaIndexOutOfBoundsException,
- SWIG_JavaArithmeticException,
- SWIG_JavaIllegalArgumentException,
- SWIG_JavaNullPointerException,
- SWIG_JavaDirectorPureVirtual,
- SWIG_JavaUnknownError,
- SWIG_JavaIllegalStateException,
-} SWIG_JavaExceptionCodes;
-
-typedef struct {
- SWIG_JavaExceptionCodes code;
- const char *java_exception;
-} SWIG_JavaExceptions_t;
-%}
-
-%insert(runtime) {
-static void SWIGUNUSED SWIG_JavaThrowException(JNIEnv *jenv, SWIG_JavaExceptionCodes code, const char *msg) {
- jclass excep;
- static const SWIG_JavaExceptions_t java_exceptions[] = {
- { SWIG_JavaOutOfMemoryError, "java/lang/OutOfMemoryError" },
- { SWIG_JavaIOException, "java/io/IOException" },
- { SWIG_JavaRuntimeException, "java/lang/RuntimeException" },
- { SWIG_JavaIndexOutOfBoundsException, "java/lang/IndexOutOfBoundsException" },
- { SWIG_JavaArithmeticException, "java/lang/ArithmeticException" },
- { SWIG_JavaIllegalArgumentException, "java/lang/IllegalArgumentException" },
- { SWIG_JavaNullPointerException, "java/lang/NullPointerException" },
- { SWIG_JavaDirectorPureVirtual, "java/lang/RuntimeException" },
- { SWIG_JavaUnknownError, "java/lang/UnknownError" },
- { SWIG_JavaIllegalStateException, "java/lang/IllegalStateException" },
- { (SWIG_JavaExceptionCodes)0, "java/lang/UnknownError" }
- };
- const SWIG_JavaExceptions_t *except_ptr = java_exceptions;
-
- while (except_ptr->code != code && except_ptr->code)
- except_ptr++;
-
- JCALL0(ExceptionClear, jenv);
- excep = JCALL1(FindClass, jenv, except_ptr->java_exception);
- if (excep)
- JCALL2(ThrowNew, jenv, excep, msg);
-}
-}
-
-%insert(runtime) %{
-/* Contract support */
-
-#define SWIG_contract_assert(nullreturn, expr, msg) do { if (!(expr)) {SWIG_JavaThrowException(jenv, SWIG_JavaIllegalArgumentException, msg); return nullreturn; } } while (0)
-%}
diff --git a/contrib/tools/swig/Lib/java/javakw.swg b/contrib/tools/swig/Lib/java/javakw.swg
deleted file mode 100644
index 8a5b76eef2..0000000000
--- a/contrib/tools/swig/Lib/java/javakw.swg
+++ /dev/null
@@ -1,70 +0,0 @@
-#ifndef JAVA_JAVAKW_SWG_
-#define JAVA_JAVAKW_SWG_
-
-/* Warnings for Java keywords */
-#define JAVAKW(x) %keywordwarn("'" `x` "' is a java keyword",rename="_%s") `x`
-
-/*
- from
- http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html
-*/
-
-JAVAKW(abstract);
-JAVAKW(double);
-JAVAKW(int);
-JAVAKW(strictfp);
-JAVAKW(boolean);
-JAVAKW(else);
-JAVAKW(interface);
-JAVAKW(super);
-JAVAKW(break);
-JAVAKW(extends);
-JAVAKW(long);
-JAVAKW(switch);
-JAVAKW(byte);
-JAVAKW(final);
-JAVAKW(native);
-JAVAKW(synchronized);
-JAVAKW(case);
-JAVAKW(finally);
-JAVAKW(new);
-JAVAKW(this);
-JAVAKW(catch);
-JAVAKW(float);
-JAVAKW(package);
-JAVAKW(throw);
-JAVAKW(char);
-JAVAKW(for);
-JAVAKW(private);
-JAVAKW(throws);
-JAVAKW(class);
-JAVAKW(goto);
-JAVAKW(protected);
-JAVAKW(transient);
-JAVAKW(const);
-JAVAKW(if);
-JAVAKW(public);
-JAVAKW(try);
-JAVAKW(continue);
-JAVAKW(implements);
-JAVAKW(return);
-JAVAKW(void);
-JAVAKW(default);
-JAVAKW(import);
-JAVAKW(short);
-JAVAKW(volatile);
-JAVAKW(do);
-JAVAKW(instanceof);
-JAVAKW(static);
-JAVAKW(while);
-
-
-/* others bad names */
-
-/* Note here that only *::clone() is bad, and *::clone(int) is ok */
-%namewarn("321:clone() is a java bad method name") *::clone();
-
-
-#undef JAVAKW
-
-#endif //JAVA_JAVAKW_SWG_
diff --git a/contrib/tools/swig/Lib/java/typemaps.i b/contrib/tools/swig/Lib/java/typemaps.i
deleted file mode 100644
index e130c1930b..0000000000
--- a/contrib/tools/swig/Lib/java/typemaps.i
+++ /dev/null
@@ -1,529 +0,0 @@
-/* -----------------------------------------------------------------------------
- * typemaps.i
- *
- * Pointer and reference handling typemap library
- *
- * These mappings provide support for input/output arguments and common
- * uses for C/C++ pointers and C++ references.
- * ----------------------------------------------------------------------------- */
-
-/*
-INPUT typemaps
---------------
-
-These typemaps remap a C pointer or C++ reference to be an "INPUT" value which is
-passed by value instead of reference.
-
-The following typemaps can be applied to turn a pointer or reference into a simple
-input value. That is, instead of passing a pointer or reference to an object,
-you would use a real value instead.
-
- bool *INPUT, bool &INPUT
- signed char *INPUT, signed char &INPUT
- unsigned char *INPUT, unsigned char &INPUT
- short *INPUT, short &INPUT
- unsigned short *INPUT, unsigned short &INPUT
- int *INPUT, int &INPUT
- unsigned int *INPUT, unsigned int &INPUT
- long *INPUT, long &INPUT
- unsigned long *INPUT, unsigned long &INPUT
- long long *INPUT, long long &INPUT
- unsigned long long *INPUT, unsigned long long &INPUT
- float *INPUT, float &INPUT
- double *INPUT, double &INPUT
-
-To use these, suppose you had a C function like this :
-
- double fadd(double *a, double *b) {
- return *a+*b;
- }
-
-You could wrap it with SWIG as follows :
-
- %include <typemaps.i>
- double fadd(double *INPUT, double *INPUT);
-
-or you can use the %apply directive :
-
- %include <typemaps.i>
- %apply double *INPUT { double *a, double *b };
- double fadd(double *a, double *b);
-
-In Java you could then use it like this:
- double answer = modulename.fadd(10.0, 20.0);
-
-There are no char *INPUT typemaps, however you can apply the signed char * typemaps instead:
- %include <typemaps.i>
- %apply signed char *INPUT {char *input};
- void f(char *input);
-*/
-
-%define INPUT_TYPEMAP(TYPE, JNITYPE, JTYPE, JNIDESC)
-%typemap(jni) TYPE *INPUT, TYPE &INPUT "JNITYPE"
-%typemap(jtype) TYPE *INPUT, TYPE &INPUT "JTYPE"
-%typemap(jstype) TYPE *INPUT, TYPE &INPUT "JTYPE"
-%typemap(javain) TYPE *INPUT, TYPE &INPUT "$javainput"
-
-%typemap(in) TYPE *INPUT, TYPE &INPUT
-%{ $1 = ($1_ltype)&$input; %}
-
-%typemap(freearg) TYPE *INPUT, TYPE &INPUT ""
-
-%typemap(typecheck) TYPE *INPUT = TYPE;
-%typemap(typecheck) TYPE &INPUT = TYPE;
-%enddef
-
-INPUT_TYPEMAP(bool, jboolean, boolean, "Z");
-INPUT_TYPEMAP(signed char, jbyte, byte, "B");
-INPUT_TYPEMAP(unsigned char, jshort, short, "S");
-INPUT_TYPEMAP(short, jshort, short, "S");
-INPUT_TYPEMAP(unsigned short, jint, int, "I");
-INPUT_TYPEMAP(int, jint, int, "I");
-INPUT_TYPEMAP(unsigned int, jlong, long, "J");
-INPUT_TYPEMAP(long, jint, int, "I");
-INPUT_TYPEMAP(unsigned long, jlong, long, "J");
-INPUT_TYPEMAP(long long, jlong, long, "J");
-INPUT_TYPEMAP(unsigned long long, jobject, java.math.BigInteger, "Ljava/math/BigInteger;");
-INPUT_TYPEMAP(float, jfloat, float, "F");
-INPUT_TYPEMAP(double, jdouble, double, "D");
-
-#undef INPUT_TYPEMAP
-
-/* Convert from BigInteger using the toByteArray member function */
-/* Overrides the typemap in the INPUT_TYPEMAP macro */
-%typemap(in) unsigned long long *INPUT($*1_ltype temp), unsigned long long &INPUT($*1_ltype temp) {
- jclass clazz;
- jmethodID mid;
- jbyteArray ba;
- jbyte* bae;
- jsize sz;
- int i;
-
- if (!$input) {
- SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null");
- return $null;
- }
- clazz = JCALL1(GetObjectClass, jenv, $input);
- mid = JCALL3(GetMethodID, jenv, clazz, "toByteArray", "()[B");
- ba = (jbyteArray)JCALL2(CallObjectMethod, jenv, $input, mid);
- bae = JCALL2(GetByteArrayElements, jenv, ba, 0);
- sz = JCALL1(GetArrayLength, jenv, ba);
- temp = 0;
- if (sz > 0) {
- temp = ($*1_ltype)(signed char)bae[0];
- for(i=1; i<sz; i++) {
- temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i];
- }
- }
- JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
- $1 = &temp;
-}
-
-// OUTPUT typemaps. These typemaps are used for parameters that
-// are output only. An array replaces the c pointer or reference parameter.
-// The output value is returned in this array passed in.
-
-/*
-OUTPUT typemaps
----------------
-
-The following typemaps can be applied to turn a pointer or reference into an "output"
-value. When calling a function, no input value would be given for
-a parameter, but an output value would be returned. This works by a
-Java array being passed as a parameter where a c pointer or reference is required.
-As with any Java function, the array is passed by reference so that
-any modifications to the array will be picked up in the calling function.
-Note that the array passed in MUST have at least one element, but as the
-c function does not require any input, the value can be set to anything.
-
- bool *OUTPUT, bool &OUTPUT
- signed char *OUTPUT, signed char &OUTPUT
- unsigned char *OUTPUT, unsigned char &OUTPUT
- short *OUTPUT, short &OUTPUT
- unsigned short *OUTPUT, unsigned short &OUTPUT
- int *OUTPUT, int &OUTPUT
- unsigned int *OUTPUT, unsigned int &OUTPUT
- long *OUTPUT, long &OUTPUT
- unsigned long *OUTPUT, unsigned long &OUTPUT
- long long *OUTPUT, long long &OUTPUT
- unsigned long long *OUTPUT, unsigned long long &OUTPUT
- float *OUTPUT, float &OUTPUT
- double *OUTPUT, double &OUTPUT
-
-For example, suppose you were trying to wrap the modf() function in the
-C math library which splits x into integral and fractional parts (and
-returns the integer part in one of its parameters):
-
- double modf(double x, double *ip);
-
-You could wrap it with SWIG as follows :
-
- %include <typemaps.i>
- double modf(double x, double *OUTPUT);
-
-or you can use the %apply directive :
-
- %include <typemaps.i>
- %apply double *OUTPUT { double *ip };
- double modf(double x, double *ip);
-
-The Java output of the function would be the function return value and the
-value in the single element array. In Java you would use it like this:
-
- double[] ptr = {0.0};
- double fraction = modulename.modf(5.0,ptr);
-
-There are no char *OUTPUT typemaps, however you can apply the signed char * typemaps instead:
- %include <typemaps.i>
- %apply signed char *OUTPUT {char *output};
- void f(char *output);
-*/
-
-/* Java BigInteger[] */
-%typecheck(SWIG_TYPECHECK_INT128_ARRAY) SWIGBIGINTEGERARRAY ""
-
-%define OUTPUT_TYPEMAP(TYPE, JNITYPE, JTYPE, JAVATYPE, JNIDESC, TYPECHECKTYPE)
-%typemap(jni) TYPE *OUTPUT, TYPE &OUTPUT %{JNITYPE##Array%}
-%typemap(jtype) TYPE *OUTPUT, TYPE &OUTPUT "JTYPE[]"
-%typemap(jstype) TYPE *OUTPUT, TYPE &OUTPUT "JTYPE[]"
-%typemap(javain) TYPE *OUTPUT, TYPE &OUTPUT "$javainput"
-%typemap(javadirectorin) TYPE *OUTPUT, TYPE &OUTPUT "$jniinput"
-%typemap(javadirectorout) TYPE *OUTPUT, TYPE &OUTPUT "$javacall"
-
-%typemap(in) TYPE *OUTPUT($*1_ltype temp), TYPE &OUTPUT($*1_ltype temp)
-{
- if (!$input) {
- SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null");
- return $null;
- }
- if (JCALL1(GetArrayLength, jenv, $input) == 0) {
- SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element");
- return $null;
- }
- temp = ($*1_ltype)0;
- $1 = &temp;
-}
-
-%typemap(freearg) TYPE *OUTPUT, TYPE &OUTPUT ""
-
-%typemap(argout) TYPE *OUTPUT, TYPE &OUTPUT
-{
- JNITYPE jvalue = (JNITYPE)temp$argnum;
- JCALL4(Set##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &jvalue);
-}
-
-%typemap(directorin,descriptor=JNIDESC) TYPE &OUTPUT %{
- $input = JCALL1(New##JAVATYPE##Array, jenv, 1);
- if (!$input) return $null;
- Swig::LocalRefGuard $1_refguard(jenv, $input); %}
-
-%typemap(directorin,descriptor=JNIDESC) TYPE *OUTPUT %{
- if ($1) {
- $input = JCALL1(New##JAVATYPE##Array, jenv, 1);
- if (!$input) return $null;
- }
- Swig::LocalRefGuard $1_refguard(jenv, $input); %}
-
-%typemap(directorargout, noblock=1) TYPE &OUTPUT
-{
- JNITYPE $1_jvalue;
- JCALL4(Get##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
- $result = ($*1_ltype)$1_jvalue;
-}
-
-%typemap(directorargout, noblock=1) TYPE *OUTPUT
-{
- if ($result) {
- JNITYPE $1_jvalue;
- JCALL4(Get##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
- *$result = ($*1_ltype)$1_jvalue;
- }
-}
-
-%typemap(typecheck) TYPE *OUTPUT = TYPECHECKTYPE;
-%typemap(typecheck) TYPE &OUTPUT = TYPECHECKTYPE;
-%enddef
-
-OUTPUT_TYPEMAP(bool, jboolean, boolean, Boolean, "[Z", jbooleanArray);
-OUTPUT_TYPEMAP(signed char, jbyte, byte, Byte, "[B", jbyteArray);
-OUTPUT_TYPEMAP(unsigned char, jshort, short, Short, "[S", jshortArray);
-OUTPUT_TYPEMAP(short, jshort, short, Short, "[S", jshortArray);
-OUTPUT_TYPEMAP(unsigned short, jint, int, Int, "[I", jintArray);
-OUTPUT_TYPEMAP(int, jint, int, Int, "[I", jintArray);
-OUTPUT_TYPEMAP(unsigned int, jlong, long, Long, "[J", jlongArray);
-OUTPUT_TYPEMAP(long, jint, int, Int, "[I", jintArray);
-OUTPUT_TYPEMAP(unsigned long, jlong, long, Long, "[J", jlongArray);
-OUTPUT_TYPEMAP(long long, jlong, long, Long, "[J", jlongArray);
-OUTPUT_TYPEMAP(unsigned long long, jobject, java.math.BigInteger, Object, "[Ljava/math/BigInteger;", jobjectArray);
-OUTPUT_TYPEMAP(float, jfloat, float, Float, "[F", jfloatArray);
-OUTPUT_TYPEMAP(double, jdouble, double, Double, "[D", jdoubleArray);
-
-#undef OUTPUT_TYPEMAP
-
-%typemap(in) bool *OUTPUT($*1_ltype temp), bool &OUTPUT($*1_ltype temp)
-{
- if (!$input) {
- SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null");
- return $null;
- }
- if (JCALL1(GetArrayLength, jenv, $input) == 0) {
- SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element");
- return $null;
- }
- temp = false;
- $1 = &temp;
-}
-
-%typemap(directorargout, noblock=1) bool &OUTPUT
-{
- jboolean $1_jvalue;
- JCALL4(GetBooleanArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
- $result = $1_jvalue ? true : false;
-}
-
-%typemap(directorargout, noblock=1) bool *OUTPUT
-{
- if ($result) {
- jboolean $1_jvalue;
- JCALL4(GetBooleanArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
- *$result = $1_jvalue ? true : false;
- }
-}
-
-
-/* Convert to BigInteger - byte array holds number in 2's complement big endian format */
-/* Use first element in BigInteger array for output */
-/* Overrides the typemap in the OUTPUT_TYPEMAP macro */
-%typemap(argout) unsigned long long *OUTPUT, unsigned long long &OUTPUT {
- jbyteArray ba = JCALL1(NewByteArray, jenv, 9);
- jbyte* bae = JCALL2(GetByteArrayElements, jenv, ba, 0);
- jclass clazz = JCALL1(FindClass, jenv, "java/math/BigInteger");
- jmethodID mid = JCALL3(GetMethodID, jenv, clazz, "<init>", "([B)V");
- jobject bigint;
- int i;
-
- bae[0] = 0;
- for(i=1; i<9; i++ ) {
- bae[i] = (jbyte)(temp$argnum>>8*(8-i));
- }
-
- JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
- bigint = JCALL3(NewObject, jenv, clazz, mid, ba);
- JCALL1(DeleteLocalRef, jenv, ba);
- JCALL3(SetObjectArrayElement, jenv, $input, 0, bigint);
-}
-
-/*
-INOUT typemaps
---------------
-
-Mappings for a parameter that is both an input and an output parameter
-
-The following typemaps can be applied to make a function parameter both
-an input and output value. This combines the behavior of both the
-"INPUT" and "OUTPUT" typemaps described earlier. Output values are
-returned as an element in a Java array.
-
- bool *INOUT, bool &INOUT
- signed char *INOUT, signed char &INOUT
- unsigned char *INOUT, unsigned char &INOUT
- short *INOUT, short &INOUT
- unsigned short *INOUT, unsigned short &INOUT
- int *INOUT, int &INOUT
- unsigned int *INOUT, unsigned int &INOUT
- long *INOUT, long &INOUT
- unsigned long *INOUT, unsigned long &INOUT
- long long *INOUT, long long &INOUT
- unsigned long long *INOUT, unsigned long long &INOUT
- float *INOUT, float &INOUT
- double *INOUT, double &INOUT
-
-For example, suppose you were trying to wrap the following function :
-
- void neg(double *x) {
- *x = -(*x);
- }
-
-You could wrap it with SWIG as follows :
-
- %include <typemaps.i>
- void neg(double *INOUT);
-
-or you can use the %apply directive :
-
- %include <typemaps.i>
- %apply double *INOUT { double *x };
- void neg(double *x);
-
-This works similarly to C in that the mapping directly modifies the
-input value - the input must be an array with a minimum of one element.
-The element in the array is the input and the output is the element in
-the array.
-
- double x[] = {5.0};
- neg(x);
-
-The implementation of the OUTPUT and INOUT typemaps is different to other
-languages in that other languages will return the output value as part
-of the function return value. This difference is due to Java being a typed language.
-
-There are no char *INOUT typemaps, however you can apply the signed char * typemaps instead:
- %include <typemaps.i>
- %apply signed char *INOUT {char *inout};
- void f(char *inout);
-*/
-
-%define INOUT_TYPEMAP(TYPE, JNITYPE, JTYPE, JAVATYPE, JNIDESC, TYPECHECKTYPE)
-%typemap(jni) TYPE *INOUT, TYPE &INOUT %{JNITYPE##Array%}
-%typemap(jtype) TYPE *INOUT, TYPE &INOUT "JTYPE[]"
-%typemap(jstype) TYPE *INOUT, TYPE &INOUT "JTYPE[]"
-%typemap(javain) TYPE *INOUT, TYPE &INOUT "$javainput"
-%typemap(javadirectorin) TYPE *INOUT, TYPE &INOUT "$jniinput"
-%typemap(javadirectorout) TYPE *INOUT, TYPE &INOUT "$javacall"
-
-%typemap(in) TYPE *INOUT, TYPE &INOUT {
- if (!$input) {
- SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null");
- return $null;
- }
- if (JCALL1(GetArrayLength, jenv, $input) == 0) {
- SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element");
- return $null;
- }
- $1 = ($1_ltype) JCALL2(Get##JAVATYPE##ArrayElements, jenv, $input, 0);
-}
-
-%typemap(freearg) TYPE *INOUT, TYPE &INOUT ""
-
-%typemap(argout) TYPE *INOUT, TYPE &INOUT
-{ JCALL3(Release##JAVATYPE##ArrayElements, jenv, $input, (JNITYPE *)$1, 0); }
-
-%typemap(directorin,descriptor=JNIDESC) TYPE &INOUT %{
- $input = JCALL1(New##JAVATYPE##Array, jenv, 1);
- if (!$input) return $null;
- JNITYPE $1_jvalue = (JNITYPE)$1;
- JCALL4(Set##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
- Swig::LocalRefGuard $1_refguard(jenv, $input); %}
-
-%typemap(directorin,descriptor=JNIDESC) TYPE *INOUT %{
- if ($1) {
- $input = JCALL1(New##JAVATYPE##Array, jenv, 1);
- if (!$input) return $null;
- JNITYPE $1_jvalue = (JNITYPE)*$1;
- JCALL4(Set##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
- }
- Swig::LocalRefGuard $1_refguard(jenv, $input); %}
-
-%typemap(directorargout, noblock=1) TYPE &INOUT
-{
- JCALL4(Get##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
- $result = ($*1_ltype)$1_jvalue;
-}
-
-%typemap(directorargout, noblock=1) TYPE *INOUT
-{
- if ($result) {
- JNITYPE $1_jvalue;
- JCALL4(Get##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
- *$result = ($*1_ltype)$1_jvalue;
- }
-}
-
-%typemap(typecheck) TYPE *INOUT = TYPECHECKTYPE;
-%typemap(typecheck) TYPE &INOUT = TYPECHECKTYPE;
-%enddef
-
-INOUT_TYPEMAP(bool, jboolean, boolean, Boolean, "[Z", jbooleanArray);
-INOUT_TYPEMAP(signed char, jbyte, byte, Byte, "[B", jbyteArray);
-INOUT_TYPEMAP(unsigned char, jshort, short, Short, "[S", jshortArray);
-INOUT_TYPEMAP(short, jshort, short, Short, "[S", jshortArray);
-INOUT_TYPEMAP(unsigned short, jint, int, Int, "[I", jintArray);
-INOUT_TYPEMAP(int, jint, int, Int, "[I", jintArray);
-INOUT_TYPEMAP(unsigned int, jlong, long, Long, "[J", jlongArray);
-INOUT_TYPEMAP(long, jint, int, Int, "[I", jintArray);
-INOUT_TYPEMAP(unsigned long, jlong, long, Long, "[J", jlongArray);
-INOUT_TYPEMAP(long long, jlong, long, Long, "[J", jlongArray);
-INOUT_TYPEMAP(unsigned long long, jobject, java.math.BigInteger, Object, "[java/math/BigInteger;", jobjectArray);
-INOUT_TYPEMAP(float, jfloat, float, Float, "[F", jfloatArray);
-INOUT_TYPEMAP(double, jdouble, double, Double, "[D", jdoubleArray);
-
-#undef INOUT_TYPEMAP
-
-/* Override typemaps in the INOUT_TYPEMAP macro for booleans to fix casts
- as a jboolean isn't always the same size as a bool */
-%typemap(in) bool *INOUT (bool btemp, jboolean *jbtemp), bool &INOUT (bool btemp, jboolean *jbtemp) {
- if (!$input) {
- SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null");
- return $null;
- }
- if (JCALL1(GetArrayLength, jenv, $input) == 0) {
- SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element");
- return $null;
- }
- jbtemp = JCALL2(GetBooleanArrayElements, jenv, $input, 0);
- btemp = (*jbtemp) ? true : false;
- $1 = &btemp;
-}
-
-%typemap(argout) bool *INOUT, bool &INOUT {
- *jbtemp$argnum = btemp$argnum ? (jboolean)1 : (jboolean)0;
- JCALL3(ReleaseBooleanArrayElements, jenv, $input , (jboolean *)jbtemp$argnum, 0);
-}
-
-%typemap(directorargout, noblock=1) bool &INOUT
-{
- JCALL4(GetBooleanArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
- $result = $1_jvalue ? true : false;
-}
-
-%typemap(directorargout, noblock=1) bool *INOUT
-{
- if ($result) {
- jboolean $1_jvalue;
- JCALL4(GetBooleanArrayRegion, jenv, $input, 0, 1, &$1_jvalue);
- *$result = $1_jvalue ? true : false;
- }
-}
-
-
-/* Override the typemap in the INOUT_TYPEMAP macro for unsigned long long */
-%typemap(in) unsigned long long *INOUT ($*1_ltype temp), unsigned long long &INOUT ($*1_ltype temp) {
- jobject bigint;
- jclass clazz;
- jmethodID mid;
- jbyteArray ba;
- jbyte* bae;
- jsize sz;
- int i;
-
- if (!$input) {
- SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null");
- return $null;
- }
- if (JCALL1(GetArrayLength, jenv, $input) == 0) {
- SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element");
- return $null;
- }
- bigint = JCALL2(GetObjectArrayElement, jenv, $input, 0);
- if (!bigint) {
- SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array element null");
- return $null;
- }
- clazz = JCALL1(GetObjectClass, jenv, bigint);
- mid = JCALL3(GetMethodID, jenv, clazz, "toByteArray", "()[B");
- ba = (jbyteArray)JCALL2(CallObjectMethod, jenv, bigint, mid);
- bae = JCALL2(GetByteArrayElements, jenv, ba, 0);
- sz = JCALL1(GetArrayLength, jenv, ba);
- temp = 0;
- if (sz > 0) {
- temp = ($*1_ltype)(signed char)bae[0];
- for(i=1; i<sz; i++) {
- temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i];
- }
- }
- JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
- $1 = &temp;
-}
-
-%typemap(argout) unsigned long long *INOUT = unsigned long long *OUTPUT;
-%typemap(argout) unsigned long long &INOUT = unsigned long long &OUTPUT;
diff --git a/contrib/tools/swig/Lib/perl5/extra-install.list b/contrib/tools/swig/Lib/perl5/extra-install.list
deleted file mode 100644
index db93830aab..0000000000
--- a/contrib/tools/swig/Lib/perl5/extra-install.list
+++ /dev/null
@@ -1,2 +0,0 @@
-# see top-level Makefile.in
-Makefile.pl noembed.h
diff --git a/contrib/tools/swig/Lib/perl5/perl5.swg b/contrib/tools/swig/Lib/perl5/perl5.swg
deleted file mode 100644
index 693c2b9457..0000000000
--- a/contrib/tools/swig/Lib/perl5/perl5.swg
+++ /dev/null
@@ -1,42 +0,0 @@
-/* ------------------------------------------------------------
- * perl.swg
- *
- * Perl configuration module.
- * ------------------------------------------------------------ */
-
-/* ------------------------------------------------------------
- * Inner macros
- * ------------------------------------------------------------ */
-%include <perlmacros.swg>
-
-/* ------------------------------------------------------------
- * The runtime part
- * ------------------------------------------------------------ */
-%include <perlruntime.swg>
-
-/* ------------------------------------------------------------
- * Special user directives
- * ------------------------------------------------------------ */
-%include <perluserdir.swg>
-
-/* ------------------------------------------------------------
- * Typemap specializations
- * ------------------------------------------------------------ */
-%include <perltypemaps.swg>
-
-/* ------------------------------------------------------------
- * Overloaded operator support
- * ------------------------------------------------------------ */
-%include <perlopers.swg>
-
-/* ------------------------------------------------------------
- * Warnings for Perl keywords
- * ------------------------------------------------------------ */
-%include <perlkw.swg>
-
-/* ------------------------------------------------------------
- * The Perl initialization function
- * ------------------------------------------------------------ */
-%include <perlinit.swg>
-
-
diff --git a/contrib/tools/swig/Lib/perl5/perlfragments.swg b/contrib/tools/swig/Lib/perl5/perlfragments.swg
deleted file mode 100644
index 45d25d1f6c..0000000000
--- a/contrib/tools/swig/Lib/perl5/perlfragments.swg
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-
- Create a file with this name, 'perlfragments.swg', in your working
- directory and add all the %fragments you want to take precedence
- over the ones defined by default by swig.
-
- For example, if you add:
-
- %fragment(SWIG_AsVal_frag(int),"header") {
- SWIGINTERNINLINE int
- SWIG_AsVal(int)(PyObject *obj, int *val)
- {
- <your code here>;
- }
- }
-
- this will replace the code used to retrieve an integer value for all
- the typemaps that need it, including:
-
- int, std::vector<int>, std::list<std::pair<int,int> >, etc.
-
-
-*/
diff --git a/contrib/tools/swig/Lib/perl5/perlinit.swg b/contrib/tools/swig/Lib/perl5/perlinit.swg
deleted file mode 100644
index c26b93fadb..0000000000
--- a/contrib/tools/swig/Lib/perl5/perlinit.swg
+++ /dev/null
@@ -1,78 +0,0 @@
-
-/* Export the SWIG initialization function */
-%header %{
-#ifdef __cplusplus
-extern "C"
-#endif
-#ifndef MULTIPLICITY
-SWIGEXPORT void SWIG_init (CV* cv);
-#else
-SWIGEXPORT void SWIG_init (pTHXo_ CV* cv);
-#endif
-%}
-
-/* Module initialization function */
-
-%insert(init) "swiginit.swg"
-
-%init %{
-
-#if defined(__cplusplus) && ! defined(XSPROTO)
-extern "C"
-#endif
-
-XS(SWIG_init) {
- dXSARGS;
- int i;
- (void)items;
-
- SWIG_InitializeModule(0);
-
- /* Install commands */
- for (i = 0; swig_commands[i].name; i++) {
- /* Casts only needed for Perl < 5.10. */
-#ifdef __cplusplus
- newXS(const_cast<char*>(swig_commands[i].name), swig_commands[i].wrapper, const_cast<char*>(__FILE__));
-#else
- newXS((char*)swig_commands[i].name, swig_commands[i].wrapper, (char*)__FILE__);
-#endif
- }
-
- /* Install variables */
- for (i = 0; swig_variables[i].name; i++) {
- SV *sv;
- sv = get_sv(swig_variables[i].name, TRUE | 0x2 | GV_ADDMULTI);
- if (swig_variables[i].type) {
- SWIG_MakePtr(sv,(void *)1, *swig_variables[i].type,0);
- } else {
- sv_setiv(sv,(IV) 0);
- }
- swig_create_magic(sv, swig_variables[i].name, swig_variables[i].set, swig_variables[i].get);
- }
-
- /* Install constant */
- for (i = 0; swig_constants[i].type; i++) {
- SV *sv;
- sv = get_sv(swig_constants[i].name, TRUE | 0x2 | GV_ADDMULTI);
- switch(swig_constants[i].type) {
- case SWIG_INT:
- sv_setiv(sv, (IV) swig_constants[i].lvalue);
- break;
- case SWIG_FLOAT:
- sv_setnv(sv, (double) swig_constants[i].dvalue);
- break;
- case SWIG_STRING:
- sv_setpv(sv, (const char *) swig_constants[i].pvalue);
- break;
- case SWIG_POINTER:
- SWIG_MakePtr(sv, swig_constants[i].pvalue, *(swig_constants[i].ptype),0);
- break;
- case SWIG_BINARY:
- SWIG_MakePackedObj(sv, swig_constants[i].pvalue, swig_constants[i].lvalue, *(swig_constants[i].ptype));
- break;
- default:
- break;
- }
- SvREADONLY_on(sv);
- }
-%}
diff --git a/contrib/tools/swig/Lib/perl5/perlkw.swg b/contrib/tools/swig/Lib/perl5/perlkw.swg
deleted file mode 100644
index 00648e0bf3..0000000000
--- a/contrib/tools/swig/Lib/perl5/perlkw.swg
+++ /dev/null
@@ -1,251 +0,0 @@
-/* Warnings for Perl keywords */
-#define PERLKW(x) %keywordwarn("'" `x` "' is a perl keyword") `x`
-#define PERLBN(x) %builtinwarn("'" `x` "' conflicts with a built-in name in perl") "::" `x`
-
-
-/*
-
- From http://www.rocketaware.com/perl/perlfunc/
-
-*/
-
-/* Functions for SCALARs or strings*/
-PERLBN(chomp);
-PERLBN(chop);
-PERLBN(chr);
-PERLBN(crypt);
-PERLBN(hex);
-PERLBN(index);
-PERLBN(lc);
-PERLBN(lcfirst);
-PERLBN(length);
-PERLBN(oct);
-PERLBN(ord);
-PERLBN(pack);
-PERLBN(reverse);
-PERLBN(rindex);
-PERLBN(sprintf);
-PERLBN(substr);
-PERLBN(uc);
-PERLBN(ucfirst);
-
-/* Regular expressions and pattern matching */
-PERLBN(m);
-PERLBN(pos);
-PERLBN(quotemeta);
-PERLBN(split);
-PERLBN(study);
-
-/* Numeric functions */
-PERLBN(abs);
-PERLBN(atan2);
-PERLBN(cos);
-PERLBN(exp);
-PERLBN(hex);
-PERLBN(int);
-PERLBN(log);
-PERLBN(oct);
-PERLBN(rand);
-PERLBN(sin);
-PERLBN(sqrt);
-PERLBN(srand);
-
-
-/* Functions for real @ARRAYs*/
-PERLBN(pop);
-PERLBN(push);
-PERLBN(shift);
-PERLBN(splice);
-PERLBN(unshift);
-
-/* Functions for list data*/
-PERLBN(grep);
-PERLBN(join);
-PERLBN(map);
-PERLBN(qw);
-PERLBN(reverse);
-PERLBN(sort);
-PERLBN(unpack);
-
-
-/* Functions for real %HASHes*/
-PERLBN(delete);
-PERLBN(each);
-PERLBN(exists);
-PERLBN(keys);
-PERLBN(values);
-
-
-/* Input and output functions*/
-
-PERLBN(binmode);
-PERLBN(close);
-PERLBN(closedir);
-PERLBN(dbmclose);
-PERLBN(dbmopen);
-PERLBN(die);
-PERLBN(eof);
-PERLBN(fileno);
-PERLBN(flock);
-PERLBN(format);
-PERLBN(getc);
-PERLBN(print);
-PERLBN(printf);
-PERLBN(read);
-PERLBN(readdir);
-PERLBN(rewinddir);
-PERLBN(seek);
-PERLBN(seekdir);
-PERLBN(select);
-PERLBN(syscall);
-PERLBN(sysread);
-PERLBN(sysseek);
-PERLBN(syswrite);
-PERLBN(tell);
-PERLBN(telldir);
-PERLBN(truncate);
-PERLBN(warn);
-PERLBN(write);
-
-
-/* Functions for fixed length data or records*/
-PERLBN(pack);
-PERLBN(read);
-PERLBN(syscall);
-PERLBN(sysread);
-PERLBN(syswrite);
-PERLBN(unpack);
-PERLBN(vec);
-
-
-/* Functions for filehandles, files, or directories */
-PERLBN(chdir);
-PERLBN(chmod);
-PERLBN(chown);
-PERLBN(chroot);
-PERLBN(fcntl);
-PERLBN(glob);
-PERLBN(ioctl);
-PERLBN(link);
-PERLBN(lstat);
-PERLBN(mkdir);
-PERLBN(open);
-PERLBN(opendir);
-PERLBN(readlink);
-PERLBN(rename);
-PERLBN(rmdir);
-PERLBN(stat);
-PERLBN(symlink);
-PERLBN(umask);
-PERLBN(unlink);
-PERLBN(utime);
-
-
-/* Keywords related to the control flow of your perl program */
-PERLKW(caller);
-PERLKW(continue);
-PERLKW(die);
-PERLKW(do);
-PERLKW(dump);
-PERLKW(eval);
-PERLKW(exit);
-PERLKW(goto);
-PERLKW(last);
-PERLKW(next);
-PERLKW(redo);
-PERLKW(return);
-PERLKW(sub);
-PERLKW(wantarray);
-
-
-/* Keywords related to scoping */
-PERLKW(caller);
-PERLKW(import);
-PERLKW(local);
-PERLKW(my);
-PERLKW(package);
-PERLKW(use);
-
-
-/* Miscellaneous functions */
-PERLBN("defined");
-PERLBN(dump);
-PERLBN(eval);
-PERLBN(formline);
-PERLBN(local);
-PERLBN(my);
-PERLBN(reset);
-PERLBN(scalar);
-PERLBN(undef);
-PERLBN(wantarray);
-
-
-/* Functions for processes and process groups */
-PERLBN(alarm);
-PERLBN(exec);
-PERLBN(fork);
-PERLBN(getpgrp);
-PERLBN(getppid);
-PERLBN(getpriority);
-PERLBN(kill);
-PERLBN(pipe);
-PERLBN(setpgrp);
-PERLBN(setpriority);
-PERLBN(sleep);
-PERLBN(system);
-PERLBN(times);
-PERLBN(wait);
-PERLBN(waitpid);
-
-
-/* Keywords related to perl modules */
-PERLKW(do);
-PERLKW(import);
-PERLKW(no);
-PERLKW(package);
-PERLKW(require);
-PERLKW(use);
-
-
-/* Keywords related to classes and object-orientedness */
-PERLKW(bless);
-PERLKW(dbmclose);
-PERLKW(dbmopen);
-PERLKW(package);
-PERLKW(ref);
-PERLKW(tie);
-PERLKW(tied);
-PERLKW(untie);
-PERLKW(use);
-
-/* Functions new in perl5 */
-PERLBN(abs);
-PERLBN(bless);
-PERLBN(chomp);
-PERLBN(chr);
-PERLBN(exists);
-PERLBN(formline);
-PERLBN(glob);
-PERLBN(import);
-PERLBN(lc);
-PERLBN(lcfirst);
-PERLBN(map);
-PERLBN(my);
-PERLBN(no);
-PERLBN(prototype);
-PERLBN(qx);
-PERLBN(qw);
-PERLBN(readline);
-PERLBN(readpipe);
-PERLBN(ref);
-PERLBN(sub);
-PERLBN(sysopen);
-PERLBN(tie);
-PERLBN(tied);
-PERLBN(uc);
-PERLBN(ucfirst);
-PERLBN(untie);
-PERLBN(use);
-
-#undef PERLKW
-#undef PERLBN
diff --git a/contrib/tools/swig/Lib/perl5/perlmacros.swg b/contrib/tools/swig/Lib/perl5/perlmacros.swg
deleted file mode 100644
index 4917f6efc5..0000000000
--- a/contrib/tools/swig/Lib/perl5/perlmacros.swg
+++ /dev/null
@@ -1,2 +0,0 @@
-%include <typemaps/swigmacros.swg>
-
diff --git a/contrib/tools/swig/Lib/perl5/perlopers.swg b/contrib/tools/swig/Lib/perl5/perlopers.swg
deleted file mode 100644
index e7d13b678a..0000000000
--- a/contrib/tools/swig/Lib/perl5/perlopers.swg
+++ /dev/null
@@ -1,54 +0,0 @@
-/* ------------------------------------------------------------
- * Overloaded operator support
- * ------------------------------------------------------------ */
-
-#ifdef __cplusplus
-
-// These are auto-supported by the Perl-module
-%rename(__plusplus__) *::operator++;
-%rename(__minmin__) *::operator--;
-%rename(__add__) *::operator+;
-%rename(__sub__) *::operator-;
-%rename(__neg__) *::operator-();
-%rename(__neg__) *::operator-() const;
-%rename(__mul__) *::operator*;
-%rename(__div__) *::operator/;
-%rename(__eq__) *::operator==;
-%rename(__ne__) *::operator!=;
-%rename(__mod__) *::operator%;
-%rename(__gt__) *::operator>;
-%rename(__lt__) *::operator<;
-%rename(__not__) *::operator!;
-%rename(__le__) *::operator<=;
-%rename(__ge__) *::operator>=;
-%rename(__and__) *::operator&;
-%rename(__or__) *::operator|;
-%rename(__iadd__) *::operator+=;
-%rename(__isub__) *::operator-=;
-
-// These are renamed, but no test exists in operator_overload_runme.pl
-%ignoreoperator(EQ) operator=;
-
-// These are renamed, but no 'use overload...' is added
-%rename(__lshift__) *::operator<<;
-%rename(__rshift__) *::operator>>;
-%rename(__xor__) *::operator^;
-%rename(__invert__) *::operator~;
-%rename(__call__) *::operator();
-
-/* Ignored operators */
-%ignoreoperator(LAND) operator&&;
-%ignoreoperator(LOR) operator||;
-%ignoreoperator(MULEQ) operator*=;
-%ignoreoperator(DIVEQ) operator/=;
-%ignoreoperator(MODEQ) operator%=;
-%ignoreoperator(LSHIFTEQ) operator<<=;
-%ignoreoperator(RSHIFTEQ) operator>>=;
-%ignoreoperator(ANDEQ) operator&=;
-%ignoreoperator(OREQ) operator|=;
-%ignoreoperator(XOREQ) operator^=;
-%ignoreoperator(ARROWSTAR) operator->*;
-%ignoreoperator(INDEX) operator[];
-
-
-#endif /* __cplusplus */
diff --git a/contrib/tools/swig/Lib/perl5/perlprimtypes.swg b/contrib/tools/swig/Lib/perl5/perlprimtypes.swg
deleted file mode 100644
index 4cb675671c..0000000000
--- a/contrib/tools/swig/Lib/perl5/perlprimtypes.swg
+++ /dev/null
@@ -1,364 +0,0 @@
-/* ------------------------------------------------------------
- * Primitive Types
- * ------------------------------------------------------------ */
-
-/* bool */
-
-%fragment(SWIG_From_frag(bool),"header") {
-SWIGINTERNINLINE SV *
-SWIG_From_dec(bool)(bool value)
-{
- return boolSV(value);
-}
-}
-
-%fragment(SWIG_AsVal_frag(bool),"header") {
-SWIGINTERN int
-SWIG_AsVal_dec(bool)(SV *obj, bool* val)
-{
- if (obj == &PL_sv_yes) {
- if (val) *val = true;
- return SWIG_OK;
- } else if (obj == &PL_sv_no) {
- if (val) *val = false;
- return SWIG_OK;
- } else {
- if (val) *val = SvTRUE(obj) ? true : false;
- return SWIG_AddCast(SWIG_OK);
- }
-}
-}
-
-
-/* long */
-
-%fragment(SWIG_From_frag(long),"header") {
-SWIGINTERNINLINE SV *
-SWIG_From_dec(long)(long value)
-{
- SV *sv;
- if (IVSIZE >= sizeof(value) || (value >= IV_MIN && value <= IV_MAX))
- sv = newSViv(value);
- else
- sv = newSVpvf("%ld", value);
- return sv_2mortal(sv);
-}
-}
-
-%fragment(SWIG_AsVal_frag(long),"header",
- fragment="<limits.h>",
- fragment="<stdlib.h>",
- fragment="SWIG_CanCastAsInteger") {
-SWIGINTERN int
-SWIG_AsVal_dec(long)(SV *obj, long* val)
-{
- if (SvUOK(obj)) {
- UV v = SvUV(obj);
- if (UVSIZE < sizeof(*val) || v <= LONG_MAX) {
- if (val) *val = v;
- return SWIG_OK;
- }
- return SWIG_OverflowError;
- } else if (SvIOK(obj)) {
- IV v = SvIV(obj);
- if (IVSIZE <= sizeof(*val) || (v >= LONG_MIN && v <= LONG_MAX)) {
- if(val) *val = v;
- return SWIG_OK;
- }
- return SWIG_OverflowError;
- } else {
- int dispatch = 0;
- const char *nptr = SvPV_nolen(obj);
- if (nptr) {
- char *endptr;
- long v;
- errno = 0;
- v = strtol(nptr, &endptr,0);
- if (errno == ERANGE) {
- errno = 0;
- return SWIG_OverflowError;
- } else {
- if (*endptr == '\0') {
- if (val) *val = v;
- return SWIG_Str2NumCast(SWIG_OK);
- }
- }
- }
- if (!dispatch) {
- double d;
- int res = SWIG_AddCast(SWIG_AsVal(double)(obj,&d));
- if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) {
- if (val) *val = (long)(d);
- return res;
- }
- }
- }
- return SWIG_TypeError;
-}
-}
-
-/* unsigned long */
-
-%fragment(SWIG_From_frag(unsigned long),"header") {
-SWIGINTERNINLINE SV *
-SWIG_From_dec(unsigned long)(unsigned long value)
-{
- SV *sv;
- if (UVSIZE >= sizeof(value) || value <= UV_MAX)
- sv = newSVuv(value);
- else
- sv = newSVpvf("%lu", value);
- return sv_2mortal(sv);
-}
-}
-
-%fragment(SWIG_AsVal_frag(unsigned long),"header",
- fragment="<limits.h>",
- fragment="<stdlib.h>",
- fragment="SWIG_CanCastAsInteger") {
-SWIGINTERN int
-SWIG_AsVal_dec(unsigned long)(SV *obj, unsigned long *val)
-{
- if (SvUOK(obj)) {
- UV v = SvUV(obj);
- if (UVSIZE <= sizeof(*val) || v <= ULONG_MAX) {
- if (val) *val = v;
- return SWIG_OK;
- }
- return SWIG_OverflowError;
- } else if (SvIOK(obj)) {
- IV v = SvIV(obj);
- if (v >= 0 && (IVSIZE <= sizeof(*val) || v <= ULONG_MAX)) {
- if (val) *val = v;
- return SWIG_OK;
- }
- return SWIG_OverflowError;
- } else {
- int dispatch = 0;
- const char *nptr = SvPV_nolen(obj);
- if (nptr) {
- char *endptr;
- unsigned long v;
- errno = 0;
- v = strtoul(nptr, &endptr,0);
- if (errno == ERANGE) {
- errno = 0;
- return SWIG_OverflowError;
- } else {
- if (*endptr == '\0') {
- if (val) *val = v;
- return SWIG_Str2NumCast(SWIG_OK);
- }
- }
- }
- if (!dispatch) {
- double d;
- int res = SWIG_AddCast(SWIG_AsVal(double)(obj,&d));
- if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ULONG_MAX)) {
- if (val) *val = (unsigned long)(d);
- return res;
- }
- }
- }
- return SWIG_TypeError;
-}
-}
-
-/* long long */
-
-%fragment(SWIG_From_frag(long long),"header",
- fragment="SWIG_LongLongAvailable",
- fragment="<stdio.h>") {
-%#ifdef SWIG_LONG_LONG_AVAILABLE
-SWIGINTERNINLINE SV *
-SWIG_From_dec(long long)(long long value)
-{
- SV *sv;
- if (IVSIZE >= sizeof(value) || (value >= IV_MIN && value <= IV_MAX))
- sv = newSViv((IV)(value));
- else {
- //sv = newSVpvf("%lld", value); doesn't work in non 64bit Perl
- char temp[256];
- sprintf(temp, "%lld", value);
- sv = newSVpv(temp, 0);
- }
- return sv_2mortal(sv);
-}
-%#endif
-}
-
-%fragment(SWIG_AsVal_frag(long long),"header",
- fragment="SWIG_LongLongAvailable",
- fragment="<stdlib.h>",
- fragment="SWIG_CanCastAsInteger") {
-%#ifdef SWIG_LONG_LONG_AVAILABLE
-SWIGINTERN int
-SWIG_AsVal_dec(long long)(SV *obj, long long *val)
-{
- if (SvUOK(obj)) {
- UV v = SvUV(obj);
- /* pretty sure this could allow v == LLONG MAX */
- if (UVSIZE < sizeof(*val) || v < LLONG_MAX) {
- if (val) *val = v;
- return SWIG_OK;
- }
- return SWIG_OverflowError;
- } else if (SvIOK(obj)) {
- IV v = SvIV(obj);
- if (IVSIZE <= sizeof(*val) || (v >= LLONG_MIN && v <= LLONG_MAX)) {
- if (val) *val = v;
- return SWIG_OK;
- }
- return SWIG_OverflowError;
- } else {
- int dispatch = 0;
- const char *nptr = SvPV_nolen(obj);
- if (nptr) {
- char *endptr;
- long long v;
- errno = 0;
- v = strtoll(nptr, &endptr,0);
- if (errno == ERANGE) {
- errno = 0;
- return SWIG_OverflowError;
- } else {
- if (*endptr == '\0') {
- if (val) *val = v;
- return SWIG_Str2NumCast(SWIG_OK);
- }
- }
- }
- if (!dispatch) {
- const double mant_max = 1LL << DBL_MANT_DIG;
- const double mant_min = -mant_max;
- double d;
- int res = SWIG_AddCast(SWIG_AsVal(double)(obj,&d));
- if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, mant_min, mant_max)) {
- if (val) *val = (long long)(d);
- return res;
- }
- }
- }
- return SWIG_TypeError;
-}
-%#endif
-}
-
-/* unsigned long long */
-
-%fragment(SWIG_From_frag(unsigned long long),"header",
- fragment="SWIG_LongLongAvailable",
- fragment="<stdio.h>") {
-%#ifdef SWIG_LONG_LONG_AVAILABLE
-SWIGINTERNINLINE SV *
-SWIG_From_dec(unsigned long long)(unsigned long long value)
-{
- SV *sv;
- if (UVSIZE >= sizeof(value) || value <= UV_MAX)
- sv = newSVuv((UV)(value));
- else {
- //sv = newSVpvf("%llu", value); doesn't work in non 64bit Perl
- char temp[256];
- sprintf(temp, "%llu", value);
- sv = newSVpv(temp, 0);
- }
- return sv_2mortal(sv);
-}
-%#endif
-}
-
-%fragment(SWIG_AsVal_frag(unsigned long long),"header",
- fragment="SWIG_LongLongAvailable",
- fragment="<stdlib.h>",
- fragment="SWIG_CanCastAsInteger") {
-%#ifdef SWIG_LONG_LONG_AVAILABLE
-SWIGINTERN int
-SWIG_AsVal_dec(unsigned long long)(SV *obj, unsigned long long *val)
-{
- if (SvUOK(obj)) {
- /* pretty sure this should be conditional on
- * (UVSIZE <= sizeof(*val) || v <= ULLONG_MAX) */
- if (val) *val = SvUV(obj);
- return SWIG_OK;
- } else if (SvIOK(obj)) {
- IV v = SvIV(obj);
- if (v >= 0 && (IVSIZE <= sizeof(*val) || v <= ULLONG_MAX)) {
- if (val) *val = v;
- return SWIG_OK;
- } else {
- return SWIG_OverflowError;
- }
- } else {
- int dispatch = 0;
- const char *nptr = SvPV_nolen(obj);
- if (nptr) {
- char *endptr;
- unsigned long long v;
- errno = 0;
- v = strtoull(nptr, &endptr,0);
- if (errno == ERANGE) {
- errno = 0;
- return SWIG_OverflowError;
- } else {
- if (*endptr == '\0') {
- if (val) *val = v;
- return SWIG_Str2NumCast(SWIG_OK);
- }
- }
- }
- if (!dispatch) {
- const double mant_max = 1LL << DBL_MANT_DIG;
- double d;
- int res = SWIG_AddCast(SWIG_AsVal(double)(obj,&d));
- if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, mant_max)) {
- if (val) *val = (unsigned long long)(d);
- return res;
- }
- }
- }
- return SWIG_TypeError;
-}
-%#endif
-}
-
-/* double */
-
-%fragment(SWIG_From_frag(double),"header") {
-SWIGINTERNINLINE SV *
-SWIG_From_dec(double)(double value)
-{
- return sv_2mortal(newSVnv(value));
-}
-}
-
-%fragment(SWIG_AsVal_frag(double),"header") {
-SWIGINTERN int
-SWIG_AsVal_dec(double)(SV *obj, double *val)
-{
- if (SvNIOK(obj)) {
- if (val) *val = SvNV(obj);
- return SWIG_OK;
- } else if (SvIOK(obj)) {
- if (val) *val = (double) SvIV(obj);
- return SWIG_AddCast(SWIG_OK);
- } else {
- const char *nptr = SvPV_nolen(obj);
- if (nptr) {
- char *endptr;
- double v;
- errno = 0;
- v = strtod(nptr, &endptr);
- if (errno == ERANGE) {
- errno = 0;
- return SWIG_OverflowError;
- } else {
- if (*endptr == '\0') {
- if (val) *val = v;
- return SWIG_Str2NumCast(SWIG_OK);
- }
- }
- }
- }
- return SWIG_TypeError;
-}
-}
diff --git a/contrib/tools/swig/Lib/perl5/perlruntime.swg b/contrib/tools/swig/Lib/perl5/perlruntime.swg
deleted file mode 100644
index f948023de7..0000000000
--- a/contrib/tools/swig/Lib/perl5/perlruntime.swg
+++ /dev/null
@@ -1,8 +0,0 @@
-
-%runtime "swigrun.swg" // Common C API type-checking code
-%runtime "swigerrors.swg" // SWIG errors
-%runtime "perlhead.swg" // Perl includes and fixes
-%runtime "perlerrors.swg" // Perl errors
-%runtime "perlrun.swg" // Perl runtime functions
-%runtime "noembed.h" // undefine Perl5 macros
-
diff --git a/contrib/tools/swig/Lib/perl5/perlstrings.swg b/contrib/tools/swig/Lib/perl5/perlstrings.swg
deleted file mode 100644
index 242a9c9673..0000000000
--- a/contrib/tools/swig/Lib/perl5/perlstrings.swg
+++ /dev/null
@@ -1,59 +0,0 @@
-/* ------------------------------------------------------------
- * utility methods for char strings
- * ------------------------------------------------------------ */
-
-%fragment("SWIG_AsCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") {
-SWIGINTERN int
-SWIG_AsCharPtrAndSize(SV *obj, char** cptr, size_t* psize, int *alloc)
-{
- if (SvMAGICAL(obj)) {
- SV *tmp = sv_newmortal();
- SvSetSV(tmp, obj);
- obj = tmp;
- }
- if (SvPOK(obj)) {
- STRLEN len = 0;
- char *cstr = SvPV(obj, len);
- size_t size = len + 1;
- if (cptr) {
- if (alloc) {
- if (*alloc == SWIG_NEWOBJ) {
- *cptr = %new_copy_array(cstr, size, char);
- } else {
- *cptr = cstr;
- *alloc = SWIG_OLDOBJ;
- }
- }
- }
- if (psize) *psize = size;
- return SWIG_OK;
- } else {
- swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
- if (pchar_descriptor) {
- char* vptr = 0;
- if (SWIG_ConvertPtr(obj, (void**)&vptr, pchar_descriptor, 0) == SWIG_OK) {
- if (cptr) *cptr = vptr;
- if (psize) *psize = vptr ? (strlen(vptr) + 1) : 0;
- if (alloc) *alloc = SWIG_OLDOBJ;
- return SWIG_OK;
- }
- }
- }
- return SWIG_TypeError;
-}
-}
-
-%fragment("SWIG_FromCharPtrAndSize","header") {
-SWIGINTERNINLINE SV *
-SWIG_FromCharPtrAndSize(const char* carray, size_t size)
-{
- SV *obj = sv_newmortal();
- if (carray) {
- sv_setpvn(obj, carray, size);
- } else {
- sv_setsv(obj, &PL_sv_undef);
- }
- return obj;
-}
-}
-
diff --git a/contrib/tools/swig/Lib/perl5/perltypemaps.swg b/contrib/tools/swig/Lib/perl5/perltypemaps.swg
deleted file mode 100644
index 42f8887bef..0000000000
--- a/contrib/tools/swig/Lib/perl5/perltypemaps.swg
+++ /dev/null
@@ -1,104 +0,0 @@
-/* ------------------------------------------------------------
- * Typemap specializations for Perl
- * ------------------------------------------------------------ */
-
-/* ------------------------------------------------------------
- * Fragment section
- * ------------------------------------------------------------ */
-
-/*
- in Perl we need to pass the CPerlObj value, sometimes, so, we define
- the decl/call macros as needed.
-*/
-
-#define SWIG_AS_DECL_ARGS SWIG_PERL_DECL_ARGS_2
-#define SWIG_AS_CALL_ARGS SWIG_PERL_CALL_ARGS_2
-
-#define SWIG_FROM_DECL_ARGS SWIG_PERL_DECL_ARGS_1
-#define SWIG_FROM_CALL_ARGS SWIG_PERL_CALL_ARGS_1
-
-
-/* Include fundamental fragment definitions */
-%include <typemaps/fragments.swg>
-
-/* Look for user fragments file. */
-%include <perlfragments.swg>
-
-/* Perl fragments for primitive types */
-%include <perlprimtypes.swg>
-
-/* Perl fragments for char* strings */
-%include <perlstrings.swg>
-
-
-/* ------------------------------------------------------------
- * Unified typemap section
- * ------------------------------------------------------------ */
-
-/* director support in Perl is experimental */
-#ifndef SWIG_DIRECTOR_TYPEMAPS
-#define SWIG_DIRECTOR_TYPEMAPS
-#endif
-
-
-/* Perl types */
-#define SWIG_Object SV *
-#define VOID_Object &PL_sv_undef
-
-/* Perl $shadow flag */
-#define %newpointer_flags $shadow
-#define %newinstance_flags $shadow
-
-
-/* Complete overload of the output/constant/exception macros */
-
-/* output */
-%define %set_output(obj) $result = obj; argvi++ %enddef
-
-/* append output */
-%define %append_output(obj)
-if (argvi >= items) EXTEND(sp, argvi+1);
-%set_output(obj) %enddef
-
-/* variable output */
-%define %set_varoutput(obj) sv_setsv($result,obj) %enddef
-
-/* constant */
-%define %set_constant(name, obj) %begin_block
- SV *sv = get_sv((char*) SWIG_prefix name, TRUE | 0x2 | GV_ADDMULTI);
- sv_setsv(sv, obj);
- SvREADONLY_on(sv);
-%end_block %enddef
-
-/* raise exception */
-%define %raise(obj, type, desc) sv_setsv(get_sv("@", GV_ADD), obj); SWIG_fail %enddef
-
-/* For directors to raise/throw the original exception */
-%typemap(throws) Swig::DirectorException
-%{ sv_setsv(ERRSV, $1.getNative()); SWIG_fail; %}
-
-/* Include the unified typemap library */
-%include <typemaps/swigtypemaps.swg>
-
-/* ------------------------------------------------------------
- * Perl extra typemaps / typemap overrides
- * ------------------------------------------------------------ */
-
-%typemap(varout,type="$1_descriptor") SWIGTYPE *, SWIGTYPE []
- "sv_setiv(SvRV($result),PTR2IV($1));";
-
-%typemap(varout,type="$1_descriptor") SWIGTYPE &
- "sv_setiv(SvRV($result),PTR2IV(&$1));";
-
-%typemap(varout,type="$1_descriptor") SWIGTYPE &&
- "sv_setiv(SvRV($result),PTR2IV(&$1));";
-
-%typemap(varout,type="$&1_descriptor") SWIGTYPE
- "sv_setiv(SvRV($result), PTR2IV(&$1));";
-
-%typemap(varout,type="$1_descriptor") SWIGTYPE (CLASS::*) {
- SWIG_MakePackedObj($result, (void *) &$1, sizeof($1), $1_descriptor);
-}
-
-%typemap(varout) SWIGTYPE *const = SWIGTYPE *;
-
diff --git a/contrib/tools/swig/Lib/perl5/perluserdir.swg b/contrib/tools/swig/Lib/perl5/perluserdir.swg
deleted file mode 100644
index 718440e837..0000000000
--- a/contrib/tools/swig/Lib/perl5/perluserdir.swg
+++ /dev/null
@@ -1,2 +0,0 @@
-#define %perlcode %insert("perl")
-
diff --git a/contrib/tools/swig/Lib/perl5/reference.i b/contrib/tools/swig/Lib/perl5/reference.i
deleted file mode 100644
index b424c533b1..0000000000
--- a/contrib/tools/swig/Lib/perl5/reference.i
+++ /dev/null
@@ -1,261 +0,0 @@
-/* -----------------------------------------------------------------------------
- * reference.i
- *
- * Accept Perl references as pointers
- * ----------------------------------------------------------------------------- */
-
-/*
-The following methods make Perl references work like simple C
-pointers. References can only be used for simple input/output
-values, not C arrays however. It should also be noted that
-REFERENCES are specific to Perl and not supported in other
-scripting languages at this time.
-
- int *REFERENCE
- short *REFERENCE
- long *REFERENCE
- unsigned int *REFERENCE
- unsigned short *REFERENCE
- unsigned long *REFERENCE
- unsigned char *REFERENCE
- float *REFERENCE
- double *REFERENCE
-
-For example, suppose you were trying to wrap the following function :
-
- void neg(double *x) {
- *x = -(*x);
- }
-
-You could wrap it with SWIG as follows :
-
- %include reference.i
- void neg(double *REFERENCE);
-
-or you can use the %apply directive :
-
- %include reference.i
- %apply double *REFERENCE { double *x };
- void neg(double *x);
-
-Unlike the INOUT mapping described in typemaps.i, this approach directly
-modifies the value of a Perl reference. Thus, you could use it
-as follows :
-
- $x = 3;
- neg(\$x);
- print "$x\n"; # Should print out -3.
-
-*/
-
-%typemap(in) double *REFERENCE (double dvalue), double &REFERENCE(double dvalue)
-{
- SV *tempsv;
- if (!SvROK($input)) {
- SWIG_croak("expected a reference");
- }
- tempsv = SvRV($input);
- if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) {
- printf("Received %d\n", SvTYPE(tempsv));
- SWIG_croak("Expected a double reference.");
- }
- dvalue = SvNV(tempsv);
- $1 = &dvalue;
-}
-
-%typemap(in) float *REFERENCE (float dvalue), float &REFERENCE(float dvalue)
-{
- SV *tempsv;
- if (!SvROK($input)) {
- SWIG_croak("expected a reference");
- }
- tempsv = SvRV($input);
- if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) {
- SWIG_croak("expected a double reference");
- }
- dvalue = (float) SvNV(tempsv);
- $1 = &dvalue;
-}
-
-%typemap(in) int *REFERENCE (int dvalue), int &REFERENCE (int dvalue)
-{
- SV *tempsv;
- if (!SvROK($input)) {
- SWIG_croak("expected a reference");
- }
- tempsv = SvRV($input);
- if (!SvIOK(tempsv)) {
- SWIG_croak("expected an integer reference");
- }
- dvalue = SvIV(tempsv);
- $1 = &dvalue;
-}
-
-%typemap(in) short *REFERENCE (short dvalue), short &REFERENCE(short dvalue)
-{
- SV *tempsv;
- if (!SvROK($input)) {
- SWIG_croak("expected a reference");
- }
- tempsv = SvRV($input);
- if (!SvIOK(tempsv)) {
- SWIG_croak("expected an integer reference");
- }
- dvalue = (short) SvIV(tempsv);
- $1 = &dvalue;
-}
-%typemap(in) long *REFERENCE (long dvalue), long &REFERENCE(long dvalue)
-{
- SV *tempsv;
- if (!SvROK($input)) {
- SWIG_croak("expected a reference");
- }
- tempsv = SvRV($input);
- if (!SvIOK(tempsv)) {
- SWIG_croak("expected an integer reference");
- }
- dvalue = (long) SvIV(tempsv);
- $1 = &dvalue;
-}
-%typemap(in) unsigned int *REFERENCE (unsigned int dvalue), unsigned int &REFERENCE(unsigned int dvalue)
-{
- SV *tempsv;
- if (!SvROK($input)) {
- SWIG_croak("expected a reference");
- }
- tempsv = SvRV($input);
- if (!SvIOK(tempsv)) {
- SWIG_croak("expected an integer reference");
- }
- dvalue = (unsigned int) SvUV(tempsv);
- $1 = &dvalue;
-}
-%typemap(in) unsigned short *REFERENCE (unsigned short dvalue), unsigned short &REFERENCE(unsigned short dvalue)
-{
- SV *tempsv;
- if (!SvROK($input)) {
- SWIG_croak("expected a reference");
- }
- tempsv = SvRV($input);
- if (!SvIOK(tempsv)) {
- SWIG_croak("expected an integer reference");
- }
- dvalue = (unsigned short) SvUV(tempsv);
- $1 = &dvalue;
-}
-%typemap(in) unsigned long *REFERENCE (unsigned long dvalue), unsigned long &REFERENCE(unsigned long dvalue)
-{
- SV *tempsv;
- if (!SvROK($input)) {
- SWIG_croak("expected a reference");
- }
- tempsv = SvRV($input);
- if (!SvIOK(tempsv)) {
- SWIG_croak("expected an integer reference");
- }
- dvalue = (unsigned long) SvUV(tempsv);
- $1 = &dvalue;
-}
-
-%typemap(in) unsigned char *REFERENCE (unsigned char dvalue), unsigned char &REFERENCE(unsigned char dvalue)
-{
- SV *tempsv;
- if (!SvROK($input)) {
- SWIG_croak("expected a reference");
- }
- tempsv = SvRV($input);
- if (!SvIOK(tempsv)) {
- SWIG_croak("expected an integer reference");
- }
- dvalue = (unsigned char) SvUV(tempsv);
- $1 = &dvalue;
-}
-
-%typemap(in) signed char *REFERENCE (signed char dvalue), signed char &REFERENCE(signed char dvalue)
-{
- SV *tempsv;
- if (!SvROK($input)) {
- SWIG_croak("expected a reference");
- }
- tempsv = SvRV($input);
- if (!SvIOK(tempsv)) {
- SWIG_croak("expected an integer reference");
- }
- dvalue = (signed char) SvIV(tempsv);
- $1 = &dvalue;
-}
-
-%typemap(in) bool *REFERENCE (bool dvalue), bool &REFERENCE(bool dvalue)
-{
- SV *tempsv;
- if (!SvROK($input)) {
- SWIG_croak("expected a reference");
- }
- tempsv = SvRV($input);
- if (!SvIOK(tempsv)) {
- SWIG_croak("expected an integer reference");
- }
- dvalue = SvIV(tempsv) ? true : false;
- $1 = &dvalue;
-}
-
-%typemap(typecheck) int *REFERENCE, int &REFERENCE,
- short *REFERENCE, short &REFERENCE,
- long *REFERENCE, long &REFERENCE,
- signed char *REFERENCE, signed char &REFERENCE,
- bool *REFERENCE, bool &REFERENCE
-{
- $1 = SvROK($input) && SvIOK(SvRV($input));
-}
-%typemap(typecheck) double *REFERENCE, double &REFERENCE,
- float *REFERENCE, float &REFERENCE
-{
- $1 = SvROK($input);
- if($1) {
- SV *tmpsv = SvRV($input);
- $1 = SvNOK(tmpsv) || SvIOK(tmpsv);
- }
-}
-%typemap(typecheck) unsigned int *REFERENCE, unsigned int &REFERENCE,
- unsigned short *REFERENCE, unsigned short &REFERENCE,
- unsigned long *REFERENCE, unsigned long &REFERENCE,
- unsigned char *REFERENCE, unsigned char &REFERENCE
-{
- $1 = SvROK($input);
- if($1) {
- SV *tmpsv = SvRV($input);
- $1 = SvUOK(tmpsv) || SvIOK(tmpsv);
- }
-}
-
-%typemap(argout) double *REFERENCE, double &REFERENCE,
- float *REFERENCE, float &REFERENCE
-{
- SV *tempsv;
- tempsv = SvRV($arg);
- if (!$1) SWIG_croak("expected a reference");
- sv_setnv(tempsv, (double) *$1);
-}
-
-%typemap(argout) int *REFERENCE, int &REFERENCE,
- short *REFERENCE, short &REFERENCE,
- long *REFERENCE, long &REFERENCE,
- signed char *REFERENCE, signed char &REFERENCE,
- bool *REFERENCE, bool &REFERENCE
-{
- SV *tempsv;
- tempsv = SvRV($input);
- if (!$1) SWIG_croak("expected a reference");
- sv_setiv(tempsv, (IV) *$1);
-}
-
-%typemap(argout) unsigned int *REFERENCE, unsigned int &REFERENCE,
- unsigned short *REFERENCE, unsigned short &REFERENCE,
- unsigned long *REFERENCE, unsigned long &REFERENCE,
- unsigned char *REFERENCE, unsigned char &REFERENCE
-{
- SV *tempsv;
- tempsv = SvRV($input);
- if (!$1) SWIG_croak("expected a reference");
- sv_setuv(tempsv, (UV) *$1);
-}
diff --git a/contrib/tools/swig/Lib/perl5/typemaps.i b/contrib/tools/swig/Lib/perl5/typemaps.i
deleted file mode 100644
index 3e1f60d904..0000000000
--- a/contrib/tools/swig/Lib/perl5/typemaps.i
+++ /dev/null
@@ -1,371 +0,0 @@
-/* -----------------------------------------------------------------------------
- * typemaps.i
- *
- * The SWIG typemap library provides a language independent mechanism for
- * supporting output arguments, input values, and other C function
- * calling mechanisms. The primary use of the library is to provide a
- * better interface to certain C function--especially those involving
- * pointers.
- * ----------------------------------------------------------------------------- */
-
-#if !defined(SWIG_USE_OLD_TYPEMAPS)
-%include <typemaps/typemaps.swg>
-#else
-
-
-// INPUT typemaps.
-// These remap a C pointer to be an "INPUT" value which is passed by value
-// instead of reference.
-
-
-/*
-The following methods can be applied to turn a pointer into a simple
-"input" value. That is, instead of passing a pointer to an object,
-you would use a real value instead.
-
- int *INPUT
- short *INPUT
- long *INPUT
- long long *INPUT
- unsigned int *INPUT
- unsigned short *INPUT
- unsigned long *INPUT
- unsigned long long *INPUT
- unsigned char *INPUT
- bool *INPUT
- float *INPUT
- double *INPUT
-
-To use these, suppose you had a C function like this :
-
- double fadd(double *a, double *b) {
- return *a+*b;
- }
-
-You could wrap it with SWIG as follows :
-
- %include typemaps.i
- double fadd(double *INPUT, double *INPUT);
-
-or you can use the %apply directive :
-
- %include typemaps.i
- %apply double *INPUT { double *a, double *b };
- double fadd(double *a, double *b);
-
-*/
-
-%define INPUT_TYPEMAP(type, converter)
-%typemap(in) type *INPUT(type temp), type &INPUT(type temp) {
- temp = (type) converter($input);
- $1 = &temp;
-}
-%typemap(typecheck) type *INPUT = type;
-%typemap(typecheck) type &INPUT = type;
-%enddef
-
-INPUT_TYPEMAP(float, SvNV);
-INPUT_TYPEMAP(double, SvNV);
-INPUT_TYPEMAP(int, SvIV);
-INPUT_TYPEMAP(long, SvIV);
-INPUT_TYPEMAP(short, SvIV);
-INPUT_TYPEMAP(signed char, SvIV);
-INPUT_TYPEMAP(unsigned int, SvUV);
-INPUT_TYPEMAP(unsigned long, SvUV);
-INPUT_TYPEMAP(unsigned short, SvUV);
-INPUT_TYPEMAP(unsigned char, SvUV);
-
-%typemap(in) bool *INPUT(bool temp), bool &INPUT(bool temp) {
- temp = SvIV($input) ? true : false;
- $1 = &temp;
-}
-%typemap(typecheck) bool *INPUT = bool;
-%typemap(typecheck) bool &INPUT = bool;
-
-%typemap(in) long long *INPUT($*1_ltype temp), long long &INPUT($*1_ltype temp) {
- temp = strtoll(SvPV_nolen($input), 0, 0);
- $1 = &temp;
-}
-%typemap(typecheck) long long *INPUT = long long;
-%typemap(typecheck) long long &INPUT = long long;
-
-%typemap(in) unsigned long long *INPUT($*1_ltype temp), unsigned long long &INPUT($*1_ltype temp) {
- temp = strtoull(SvPV_nolen($input), 0, 0);
- $1 = &temp;
-}
-%typemap(typecheck) unsigned long long *INPUT = unsigned long long;
-%typemap(typecheck) unsigned long long &INPUT = unsigned long long;
-
-
-#undef INPUT_TYPEMAP
-
-// OUTPUT typemaps. These typemaps are used for parameters that
-// are output only. The output value is appended to the result as
-// a list element.
-
-/*
-The following methods can be applied to turn a pointer into an "output"
-value. When calling a function, no input value would be given for
-a parameter, but an output value would be returned. In the case of
-multiple output values, functions will return a Perl array.
-
- int *OUTPUT
- short *OUTPUT
- long *OUTPUT
- long long *OUTPUT
- unsigned int *OUTPUT
- unsigned short *OUTPUT
- unsigned long *OUTPUT
- unsigned long long *OUTPUT
- unsigned char *OUTPUT
- bool *OUTPUT
- float *OUTPUT
- double *OUTPUT
-
-For example, suppose you were trying to wrap the modf() function in the
-C math library which splits x into integral and fractional parts (and
-returns the integer part in one of its parameters).:
-
- double modf(double x, double *ip);
-
-You could wrap it with SWIG as follows :
-
- %include typemaps.i
- double modf(double x, double *OUTPUT);
-
-or you can use the %apply directive :
-
- %include typemaps.i
- %apply double *OUTPUT { double *ip };
- double modf(double x, double *ip);
-
-The Perl output of the function would be an array containing both
-output values.
-
-*/
-
-// Force the argument to be ignored.
-
-%typemap(in,numinputs=0) int *OUTPUT(int temp), int &OUTPUT(int temp),
- short *OUTPUT(short temp), short &OUTPUT(short temp),
- long *OUTPUT(long temp), long &OUTPUT(long temp),
- unsigned int *OUTPUT(unsigned int temp), unsigned int &OUTPUT(unsigned int temp),
- unsigned short *OUTPUT(unsigned short temp), unsigned short &OUTPUT(unsigned short temp),
- unsigned long *OUTPUT(unsigned long temp), unsigned long &OUTPUT(unsigned long temp),
- unsigned char *OUTPUT(unsigned char temp), unsigned char &OUTPUT(unsigned char temp),
- signed char *OUTPUT(signed char temp), signed char &OUTPUT(signed char temp),
- bool *OUTPUT(bool temp), bool &OUTPUT(bool temp),
- float *OUTPUT(float temp), float &OUTPUT(float temp),
- double *OUTPUT(double temp), double &OUTPUT(double temp),
- long long *OUTPUT($*1_ltype temp), long long &OUTPUT($*1_ltype temp),
- unsigned long long *OUTPUT($*1_ltype temp), unsigned long long &OUTPUT($*1_ltype temp)
-"$1 = &temp;";
-
-%typemap(argout) int *OUTPUT, int &OUTPUT,
- short *OUTPUT, short &OUTPUT,
- long *OUTPUT, long &OUTPUT,
- signed char *OUTPUT, signed char &OUTPUT,
- bool *OUTPUT, bool &OUTPUT
-{
- if (argvi >= items) {
- EXTEND(sp, argvi+1);
- }
- $result = sv_newmortal();
- sv_setiv($result,(IV) *($1));
- argvi++;
-}
-
-%typemap(argout) unsigned int *OUTPUT, unsigned int &OUTPUT,
- unsigned short *OUTPUT, unsigned short &OUTPUT,
- unsigned long *OUTPUT, unsigned long &OUTPUT,
- unsigned char *OUTPUT, unsigned char &OUTPUT
-{
- if (argvi >= items) {
- EXTEND(sp, argvi+1);
- }
- $result = sv_newmortal();
- sv_setuv($result,(UV) *($1));
- argvi++;
-}
-
-
-
-%typemap(argout) float *OUTPUT, float &OUTPUT,
- double *OUTPUT, double &OUTPUT
-{
- if (argvi >= items) {
- EXTEND(sp, argvi+1);
- }
- $result = sv_newmortal();
- sv_setnv($result,(double) *($1));
- argvi++;
-}
-
-%typemap(argout) long long *OUTPUT, long long &OUTPUT {
- char temp[256];
- if (argvi >= items) {
- EXTEND(sp, argvi+1);
- }
- sprintf(temp,"%lld", (long long)*($1));
- $result = sv_newmortal();
- sv_setpv($result,temp);
- argvi++;
-}
-
-%typemap(argout) unsigned long long *OUTPUT, unsigned long long &OUTPUT {
- char temp[256];
- if (argvi >= items) {
- EXTEND(sp, argvi+1);
- }
- sprintf(temp,"%llu", (unsigned long long)*($1));
- $result = sv_newmortal();
- sv_setpv($result,temp);
- argvi++;
-}
-
-// INOUT
-// Mappings for an argument that is both an input and output
-// parameter
-
-/*
-The following methods can be applied to make a function parameter both
-an input and output value. This combines the behavior of both the
-"INPUT" and "OUTPUT" methods described earlier. Output values are
-returned in the form of a Perl array.
-
- int *INOUT
- short *INOUT
- long *INOUT
- long long *INOUT
- unsigned int *INOUT
- unsigned short *INOUT
- unsigned long *INOUT
- unsigned long long *INOUT
- unsigned char *INOUT
- bool *INOUT
- float *INOUT
- double *INOUT
-
-For example, suppose you were trying to wrap the following function :
-
- void neg(double *x) {
- *x = -(*x);
- }
-
-You could wrap it with SWIG as follows :
-
- %include typemaps.i
- void neg(double *INOUT);
-
-or you can use the %apply directive :
-
- %include typemaps.i
- %apply double *INOUT { double *x };
- void neg(double *x);
-
-Unlike C, this mapping does not directly modify the input value.
-Rather, the modified input value shows up as the return value of the
-function. Thus, to apply this function to a Perl variable you might
-do this :
-
- $x = neg($x);
-
-*/
-
-%typemap(in) int *INOUT = int *INPUT;
-%typemap(in) short *INOUT = short *INPUT;
-%typemap(in) long *INOUT = long *INPUT;
-%typemap(in) unsigned *INOUT = unsigned *INPUT;
-%typemap(in) unsigned short *INOUT = unsigned short *INPUT;
-%typemap(in) unsigned long *INOUT = unsigned long *INPUT;
-%typemap(in) unsigned char *INOUT = unsigned char *INPUT;
-%typemap(in) signed char *INOUT = signed char *INPUT;
-%typemap(in) bool *INOUT = bool *INPUT;
-%typemap(in) float *INOUT = float *INPUT;
-%typemap(in) double *INOUT = double *INPUT;
-%typemap(in) long long *INOUT = long long *INPUT;
-%typemap(in) unsigned long long *INOUT = unsigned long long *INPUT;
-
-%typemap(in) int &INOUT = int &INPUT;
-%typemap(in) short &INOUT = short &INPUT;
-%typemap(in) long &INOUT = long &INPUT;
-%typemap(in) unsigned &INOUT = unsigned &INPUT;
-%typemap(in) unsigned short &INOUT = unsigned short &INPUT;
-%typemap(in) unsigned long &INOUT = unsigned long &INPUT;
-%typemap(in) unsigned char &INOUT = unsigned char &INPUT;
-%typemap(in) signed char &INOUT = signed char &INPUT;
-%typemap(in) bool &INOUT = bool &INPUT;
-%typemap(in) float &INOUT = float &INPUT;
-%typemap(in) double &INOUT = double &INPUT;
-%typemap(in) long long &INOUT = long long &INPUT;
-%typemap(in) unsigned long long &INOUT = unsigned long long &INPUT;
-
-
-%typemap(argout) int *INOUT = int *OUTPUT;
-%typemap(argout) short *INOUT = short *OUTPUT;
-%typemap(argout) long *INOUT = long *OUTPUT;
-%typemap(argout) unsigned *INOUT = unsigned *OUTPUT;
-%typemap(argout) unsigned short *INOUT = unsigned short *OUTPUT;
-%typemap(argout) unsigned long *INOUT = unsigned long *OUTPUT;
-%typemap(argout) unsigned char *INOUT = unsigned char *OUTPUT;
-%typemap(argout) signed char *INOUT = signed char *OUTPUT;
-%typemap(argout) bool *INOUT = bool *OUTPUT;
-%typemap(argout) float *INOUT = float *OUTPUT;
-%typemap(argout) double *INOUT = double *OUTPUT;
-%typemap(argout) long long *INOUT = long long *OUTPUT;
-%typemap(argout) unsigned long long *INOUT = unsigned long long *OUTPUT;
-
-
-%typemap(argout) int &INOUT = int &OUTPUT;
-%typemap(argout) short &INOUT = short &OUTPUT;
-%typemap(argout) long &INOUT = long &OUTPUT;
-%typemap(argout) unsigned &INOUT = unsigned &OUTPUT;
-%typemap(argout) unsigned short &INOUT = unsigned short &OUTPUT;
-%typemap(argout) unsigned long &INOUT = unsigned long &OUTPUT;
-%typemap(argout) unsigned char &INOUT = unsigned char &OUTPUT;
-%typemap(argout) signed char &INOUT = signed char &OUTPUT;
-%typemap(argout) bool &INOUT = bool &OUTPUT;
-%typemap(argout) float &INOUT = float &OUTPUT;
-%typemap(argout) double &INOUT = double &OUTPUT;
-%typemap(argout) long long &INOUT = long long &OUTPUT;
-%typemap(argout) unsigned long long &INOUT = unsigned long long &OUTPUT;
-
-
-/* Overloading information */
-
-%typemap(typecheck) double *INOUT = double;
-%typemap(typecheck) bool *INOUT = bool;
-%typemap(typecheck) signed char *INOUT = signed char;
-%typemap(typecheck) unsigned char *INOUT = unsigned char;
-%typemap(typecheck) unsigned long *INOUT = unsigned long;
-%typemap(typecheck) unsigned short *INOUT = unsigned short;
-%typemap(typecheck) unsigned int *INOUT = unsigned int;
-%typemap(typecheck) long *INOUT = long;
-%typemap(typecheck) short *INOUT = short;
-%typemap(typecheck) int *INOUT = int;
-%typemap(typecheck) float *INOUT = float;
-%typemap(typecheck) long long *INOUT = long long;
-%typemap(typecheck) unsigned long long *INOUT = unsigned long long;
-
-%typemap(typecheck) double &INOUT = double;
-%typemap(typecheck) bool &INOUT = bool;
-%typemap(typecheck) signed char &INOUT = signed char;
-%typemap(typecheck) unsigned char &INOUT = unsigned char;
-%typemap(typecheck) unsigned long &INOUT = unsigned long;
-%typemap(typecheck) unsigned short &INOUT = unsigned short;
-%typemap(typecheck) unsigned int &INOUT = unsigned int;
-%typemap(typecheck) long &INOUT = long;
-%typemap(typecheck) short &INOUT = short;
-%typemap(typecheck) int &INOUT = int;
-%typemap(typecheck) float &INOUT = float;
-%typemap(typecheck) long long &INOUT = long long;
-%typemap(typecheck) unsigned long long &INOUT = unsigned long long;
-
-#endif
-
-// --------------------------------------------------------------------
-// Special types
-// --------------------------------------------------------------------
-
-
-%include <reference.i>
diff --git a/contrib/tools/swig/Lib/python/README b/contrib/tools/swig/Lib/python/README
deleted file mode 100644
index 70968e7dd5..0000000000
--- a/contrib/tools/swig/Lib/python/README
+++ /dev/null
@@ -1,103 +0,0 @@
-/* -----------------------------------------------------------------------------
- *
- * User interfaces: include these ones as needed
- *
- * ----------------------------------------------------------------------------- */
-
-/* -----------------------------------------------------------------------------
- * Special types and user helpers
- * ----------------------------------------------------------------------------- */
-
-argcargv.i Handler for (int argc, char **argv)
-attribute.i Convert a pair of set/get methods into a "native" python attribute
-ccomplex.i C99 complex type
-complex.i C99 or C++ complex type
-cstring.i Various forms of C character string handling
-cwstring.i Various forms of C wchar_t string handling
-embed.i embedding the Python interpreter in something else
-file.i FILE C type
-implicit.i Allow the use of implicit C++ constructors
-wchar.i wchar_t C type
-
-/* -----------------------------------------------------------------------------
- * C++ STD + STL
- * ----------------------------------------------------------------------------- */
-
-std_alloc.i allocator
-std_basic_string.i basic string
-std_char_traits.i char traits
-std_complex.i complex
-std_deque.i deque
-std_except.i exceptions
-std_ios.i ios
-std_iostream.i istream/ostream
-std_list.i list
-std_map.i map
-std_multimap.i multimap
-std_multiset.i multiset
-std_pair.i pair
-std_set.i set
-std_sstream.i string stream
-std_streambuf.i streambuf
-std_string.i string
-std_vector.i vector
-std_wios.i wios
-std_wiostream.i wistream/wostream
-std_wsstream.i wstring stream
-std_wstreambuf.i wstreambuf
-std_wstring.i wstring
-
-
-
-/* -----------------------------------------------------------------------------
-/*
- * Implementation files: don't look at them unless you are really drunk
- *
- * ----------------------------------------------------------------------------- */
-
-/* -----------------------------------------------------------------------------
- * Basic files
- * ----------------------------------------------------------------------------- */
-
-python.swg Main language file, it just includes what is needed.
-pyuserdir.swg User visible directives (%pythonnondynamic, etc)
-pymacros.swg Internal macros used for typemaps
-pyfragments.swg Allow the user to overload the default fragments
-pyopers.swg Python operations (+=, *=, etc)
-pythonkw.swg Python keywords and special names
-pyinit.swg Python Init method
-
-/* -----------------------------------------------------------------------------
- * The runtime part
- * ----------------------------------------------------------------------------- */
-
-pyruntime.swg Main runtime file definition
-pyapi.swg SWIG/Python API declarations
-pyrun.swg Python run-time code
-
-/* -----------------------------------------------------------------------------
- * Internal typemap specializations
- * ----------------------------------------------------------------------------- */
-
-pyswigtype.swg SWIGTYPE
-pystrings.swg Char strings (char *)
-pywstrings.swg Wchar Strings (wchar_t *)
-pyprimtypes.swg Primitive types (shot,int,double,etc)
-pycomplex.swg PyComplex and helper for C/C++ complex types
-pydocs.swg Typemaps documentation
-
-/* -----------------------------------------------------------------------------
- * C++ STD + STL
- * ----------------------------------------------------------------------------- */
-
-pycontainer.swg python container iterators
-std_common.i general common code for the STD/STL implementation
-std_container.i general common code for the STD/STL containers
-
-
-/*-----------------------------------------------------------------------------
- * Backward compatibility and deprecated
- * ----------------------------------------------------------------------------- */
-
-std_vectora.i vector + allocator (allocators are now supported in STD/STL)
-typemaps.i old in/out typemaps (doesn't need to be included)
diff --git a/contrib/tools/swig/Lib/python/builtin.swg b/contrib/tools/swig/Lib/python/builtin.swg
deleted file mode 100644
index 5cff6835f8..0000000000
--- a/contrib/tools/swig/Lib/python/builtin.swg
+++ /dev/null
@@ -1,764 +0,0 @@
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-SWIGINTERN Py_hash_t
-SwigPyObject_hash(PyObject *obj) {
- SwigPyObject *sobj = (SwigPyObject *)obj;
- void *ptr = sobj->ptr;
-#if PY_VERSION_HEX < 0x03020000
- return (Py_hash_t)(Py_ssize_t)ptr;
-#else
- return (Py_hash_t)ptr;
-#endif
-}
-
-SWIGINTERN Py_hash_t
-SWIG_PyNumber_AsPyHash(PyObject *obj) {
- Py_hash_t result = -1;
-#if PY_VERSION_HEX < 0x03020000
- if (PyInt_Check(obj))
- result = PyInt_AsLong(obj);
- else if (PyLong_Check(obj))
- result = PyLong_AsLong(obj);
-#else
- if (PyNumber_Check(obj))
- result = PyNumber_AsSsize_t(obj, NULL);
-#endif
- else
- PyErr_Format(PyExc_TypeError, "Wrong type for hash function");
- return PyErr_Occurred() ? -1 : result;
-}
-
-SWIGINTERN int
-SwigPyBuiltin_BadInit(PyObject *self, PyObject *SWIGUNUSEDPARM(args), PyObject *SWIGUNUSEDPARM(kwds)) {
- PyErr_Format(PyExc_TypeError, "Cannot create new instances of type '%.300s'", self->ob_type->tp_name);
- return -1;
-}
-
-SWIGINTERN void
-SwigPyBuiltin_BadDealloc(PyObject *obj) {
- SwigPyObject *sobj = (SwigPyObject *)obj;
- if (sobj->own) {
- PyErr_Format(PyExc_TypeError, "Swig detected a memory leak in type '%.300s': no callable destructor found.", obj->ob_type->tp_name);
- }
-}
-
-typedef struct {
- PyCFunction get;
- PyCFunction set;
-} SwigPyGetSet;
-
-SWIGINTERN PyObject *
-SwigPyBuiltin_GetterClosure (PyObject *obj, void *closure) {
- SwigPyGetSet *getset;
- PyObject *tuple, *result;
- if (!closure)
- return SWIG_Py_Void();
- getset = (SwigPyGetSet *)closure;
- if (!getset->get)
- return SWIG_Py_Void();
- tuple = PyTuple_New(0);
- assert(tuple);
- result = (*getset->get)(obj, tuple);
- Py_DECREF(tuple);
- return result;
-}
-
-SWIGINTERN PyObject *
-SwigPyBuiltin_FunpackGetterClosure (PyObject *obj, void *closure) {
- SwigPyGetSet *getset;
- PyObject *result;
- if (!closure)
- return SWIG_Py_Void();
- getset = (SwigPyGetSet *)closure;
- if (!getset->get)
- return SWIG_Py_Void();
- result = (*getset->get)(obj, NULL);
- return result;
-}
-
-SWIGINTERN int
-SwigPyBuiltin_SetterClosure (PyObject *obj, PyObject *val, void *closure) {
- SwigPyGetSet *getset;
- PyObject *tuple, *result;
- if (!closure) {
- PyErr_Format(PyExc_TypeError, "Missing getset closure");
- return -1;
- }
- getset = (SwigPyGetSet *)closure;
- if (!getset->set) {
- PyErr_Format(PyExc_TypeError, "Illegal member variable assignment in type '%.300s'", obj->ob_type->tp_name);
- return -1;
- }
- tuple = PyTuple_New(1);
- assert(tuple);
- Py_INCREF(val);
- PyTuple_SET_ITEM(tuple, 0, val);
- result = (*getset->set)(obj, tuple);
- Py_DECREF(tuple);
- Py_XDECREF(result);
- return result ? 0 : -1;
-}
-
-SWIGINTERN int
-SwigPyBuiltin_FunpackSetterClosure (PyObject *obj, PyObject *val, void *closure) {
- SwigPyGetSet *getset;
- PyObject *result;
- if (!closure) {
- PyErr_Format(PyExc_TypeError, "Missing getset closure");
- return -1;
- }
- getset = (SwigPyGetSet *)closure;
- if (!getset->set) {
- PyErr_Format(PyExc_TypeError, "Illegal member variable assignment in type '%.300s'", obj->ob_type->tp_name);
- return -1;
- }
- result = (*getset->set)(obj, val);
- Py_XDECREF(result);
- return result ? 0 : -1;
-}
-
-SWIGINTERN void
-SwigPyStaticVar_dealloc(PyDescrObject *descr) {
- PyObject_GC_UnTrack(descr);
- Py_XDECREF(PyDescr_TYPE(descr));
- Py_XDECREF(PyDescr_NAME(descr));
- PyObject_GC_Del(descr);
-}
-
-SWIGINTERN PyObject *
-SwigPyStaticVar_repr(PyGetSetDescrObject *descr) {
-#if PY_VERSION_HEX >= 0x03000000
-
- return PyUnicode_FromFormat("<class attribute '%S' of type '%s'>", PyDescr_NAME(descr), PyDescr_TYPE(descr)->tp_name);
-#else
- return PyString_FromFormat("<class attribute '%s' of type '%s'>", PyString_AsString(PyDescr_NAME(descr)), PyDescr_TYPE(descr)->tp_name);
-#endif
-}
-
-SWIGINTERN int
-SwigPyStaticVar_traverse(PyObject *self, visitproc visit, void *arg) {
- PyDescrObject *descr;
- descr = (PyDescrObject *)self;
- Py_VISIT((PyObject*) PyDescr_TYPE(descr));
- return 0;
-}
-
-SWIGINTERN PyObject *
-SwigPyStaticVar_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *SWIGUNUSEDPARM(type)) {
- if (descr->d_getset->get != NULL)
- return descr->d_getset->get(obj, descr->d_getset->closure);
-#if PY_VERSION_HEX >= 0x03000000
- PyErr_Format(PyExc_AttributeError, "attribute '%.300S' of '%.100s' objects is not readable", PyDescr_NAME(descr), PyDescr_TYPE(descr)->tp_name);
-#else
- PyErr_Format(PyExc_AttributeError, "attribute '%.300s' of '%.100s' objects is not readable", PyString_AsString(PyDescr_NAME(descr)), PyDescr_TYPE(descr)->tp_name);
-#endif
- return NULL;
-}
-
-SWIGINTERN int
-SwigPyStaticVar_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) {
- if (descr->d_getset->set != NULL)
- return descr->d_getset->set(obj, value, descr->d_getset->closure);
-#if PY_VERSION_HEX >= 0x03000000
- PyErr_Format(PyExc_AttributeError, "attribute '%.300S' of '%.100s' objects is not writable", PyDescr_NAME(descr), PyDescr_TYPE(descr)->tp_name);
-#else
- PyErr_Format(PyExc_AttributeError, "attribute '%.300s' of '%.100s' objects is not writable", PyString_AsString(PyDescr_NAME(descr)), PyDescr_TYPE(descr)->tp_name);
-#endif
- return -1;
-}
-
-SWIGINTERN int
-SwigPyObjectType_setattro(PyObject *typeobject, PyObject *name, PyObject *value) {
- PyObject *attribute;
- PyTypeObject *type;
- descrsetfunc local_set;
-
- assert(PyType_Check(typeobject));
- type = (PyTypeObject *)typeobject;
- attribute = _PyType_Lookup(type, name);
- if (attribute != NULL) {
- /* Implement descriptor functionality, if any */
- local_set = attribute->ob_type->tp_descr_set;
- if (local_set != NULL)
- return local_set(attribute, (PyObject *)type, value);
-#if PY_VERSION_HEX >= 0x03000000
- PyErr_Format(PyExc_AttributeError, "cannot modify read-only attribute '%.50s.%.400S'", type->tp_name, name);
-#else
- PyErr_Format(PyExc_AttributeError, "cannot modify read-only attribute '%.50s.%.400s'", type->tp_name, PyString_AS_STRING(name));
-#endif
- } else {
-#if PY_VERSION_HEX >= 0x03000000
- PyErr_Format(PyExc_AttributeError, "type '%.50s' has no attribute '%.400S'", type->tp_name, name);
-#else
- PyErr_Format(PyExc_AttributeError, "type '%.50s' has no attribute '%.400s'", type->tp_name, PyString_AS_STRING(name));
-#endif
- }
-
- return -1;
-}
-
-SWIGINTERN PyTypeObject*
-SwigPyStaticVar_Type(void) {
- static PyTypeObject staticvar_type;
- static int type_init = 0;
- if (!type_init) {
- const PyTypeObject tmp = {
-#if PY_VERSION_HEX >= 0x03000000
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
-#else
- PyObject_HEAD_INIT(&PyType_Type)
- 0, /* ob_size */
-#endif
- "swig_static_var_getset_descriptor", /* tp_name */
- sizeof(PyGetSetDescrObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)SwigPyStaticVar_dealloc, /* tp_dealloc */
-#if PY_VERSION_HEX < 0x030800b4
- (printfunc)0, /* tp_print */
-#else
- (Py_ssize_t)0, /* tp_vectorcall_offset */
-#endif
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- (reprfunc)SwigPyStaticVar_repr, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- PyObject_GenericGetAttr, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_CLASS, /* tp_flags */
- 0, /* tp_doc */
- SwigPyStaticVar_traverse, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- 0, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- (descrgetfunc)SwigPyStaticVar_get, /* tp_descr_get */
- (descrsetfunc)SwigPyStaticVar_set, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- 0, /* tp_new */
- 0, /* tp_free */
- 0, /* tp_is_gc */
- 0, /* tp_bases */
- 0, /* tp_mro */
- 0, /* tp_cache */
- 0, /* tp_subclasses */
- 0, /* tp_weaklist */
- 0, /* tp_del */
- 0, /* tp_version_tag */
-#if PY_VERSION_HEX >= 0x03040000
- 0, /* tp_finalize */
-#endif
-#if PY_VERSION_HEX >= 0x03080000
- 0, /* tp_vectorcall */
-#endif
-#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000)
- 0, /* tp_print */
-#endif
-#ifdef COUNT_ALLOCS
- 0, /* tp_allocs */
- 0, /* tp_frees */
- 0, /* tp_maxalloc */
- 0, /* tp_prev */
- 0 /* tp_next */
-#endif
- };
- staticvar_type = tmp;
- type_init = 1;
- if (PyType_Ready(&staticvar_type) < 0)
- return NULL;
- }
- return &staticvar_type;
-}
-
-SWIGINTERN PyTypeObject*
-SwigPyObjectType(void) {
- static char swigpyobjecttype_doc[] = "Metaclass for SWIG wrapped types";
- static PyTypeObject swigpyobjecttype_type;
- static int type_init = 0;
- if (!type_init) {
- const PyTypeObject tmp = {
-#if PY_VERSION_HEX >= 0x03000000
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
-#else
- PyObject_HEAD_INIT(&PyType_Type)
- 0, /* ob_size */
-#endif
- "SwigPyObjectType", /* tp_name */
- PyType_Type.tp_basicsize, /* tp_basicsize */
- 0, /* tp_itemsize */
- 0, /* tp_dealloc */
-#if PY_VERSION_HEX < 0x030800b4
- (printfunc)0, /* tp_print */
-#else
- (Py_ssize_t)0, /* tp_vectorcall_offset */
-#endif
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- SwigPyObjectType_setattro, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_CLASS, /* tp_flags */
- swigpyobjecttype_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- 0, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- 0, /* tp_new */
- 0, /* tp_free */
- 0, /* tp_is_gc */
- 0, /* tp_bases */
- 0, /* tp_mro */
- 0, /* tp_cache */
- 0, /* tp_subclasses */
- 0, /* tp_weaklist */
- 0, /* tp_del */
- 0, /* tp_version_tag */
-#if PY_VERSION_HEX >= 0x03040000
- 0, /* tp_finalize */
-#endif
-#if PY_VERSION_HEX >= 0x03080000
- 0, /* tp_vectorcall */
-#endif
-#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000)
- 0, /* tp_print */
-#endif
-#ifdef COUNT_ALLOCS
- 0, /* tp_allocs */
- 0, /* tp_frees */
- 0, /* tp_maxalloc */
- 0, /* tp_prev */
- 0 /* tp_next */
-#endif
- };
- swigpyobjecttype_type = tmp;
- type_init = 1;
- swigpyobjecttype_type.tp_base = &PyType_Type;
- if (PyType_Ready(&swigpyobjecttype_type) < 0)
- return NULL;
- }
- return &swigpyobjecttype_type;
-}
-
-SWIGINTERN PyGetSetDescrObject *
-SwigPyStaticVar_new_getset(PyTypeObject *type, PyGetSetDef *getset) {
-
- PyGetSetDescrObject *descr;
- descr = (PyGetSetDescrObject *)PyType_GenericAlloc(SwigPyStaticVar_Type(), 0);
- assert(descr);
- Py_XINCREF(type);
- PyDescr_TYPE(descr) = type;
- PyDescr_NAME(descr) = PyString_InternFromString(getset->name);
- descr->d_getset = getset;
- if (PyDescr_NAME(descr) == NULL) {
- Py_DECREF(descr);
- descr = NULL;
- }
- return descr;
-}
-
-SWIGINTERN void
-SwigPyBuiltin_InitBases (PyTypeObject *type, PyTypeObject **bases) {
- Py_ssize_t base_count = 0;
- PyTypeObject **b;
- PyObject *tuple;
- Py_ssize_t i;
-
- if (!bases[0]) {
- bases[0] = SwigPyObject_type();
- bases[1] = NULL;
- }
- type->tp_base = bases[0];
- Py_INCREF((PyObject *)bases[0]);
- for (b = bases; *b != NULL; ++b)
- ++base_count;
- tuple = PyTuple_New(base_count);
- for (i = 0; i < base_count; ++i) {
- Py_INCREF((PyObject *)bases[i]);
- PyTuple_SET_ITEM(tuple, i, (PyObject *)bases[i]);
- }
- type->tp_bases = tuple;
-}
-
-SWIGINTERN PyObject *
-SwigPyBuiltin_ThisClosure (PyObject *self, void *SWIGUNUSEDPARM(closure)) {
- PyObject *result;
- result = (PyObject *)SWIG_Python_GetSwigThis(self);
- Py_XINCREF(result);
- return result;
-}
-
-SWIGINTERN void
-SwigPyBuiltin_SetMetaType (PyTypeObject *type, PyTypeObject *metatype)
-{
-#if PY_VERSION_HEX >= 0x030900a4
- Py_SET_TYPE(type, metatype);
-#else
- Py_TYPE(type) = metatype;
-#endif
-}
-
-
-/* Start of callback function macros for use in PyTypeObject */
-
-typedef PyObject *(*SwigPyWrapperFunction)(PyObject *, PyObject *);
-
-#define SWIGPY_UNARYFUNC_CLOSURE(wrapper) \
-SWIGINTERN PyObject * \
-wrapper##_unaryfunc_closure(PyObject *a) { \
- return SwigPyBuiltin_unaryfunc_closure(wrapper, a); \
-}
-SWIGINTERN PyObject *
-SwigPyBuiltin_unaryfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a) {
- return wrapper(a, NULL);
-}
-
-#define SWIGPY_DESTRUCTOR_CLOSURE(wrapper) \
-SWIGINTERN void \
-wrapper##_destructor_closure(PyObject *a) { \
- SwigPyBuiltin_destructor_closure(wrapper, #wrapper, a); \
-}
-SWIGINTERN void
-SwigPyBuiltin_destructor_closure(SwigPyWrapperFunction wrapper, const char *wrappername, PyObject *a) {
- SwigPyObject *sobj;
- sobj = (SwigPyObject *)a;
- Py_XDECREF(sobj->dict);
- if (sobj->own) {
- PyObject *o;
- PyObject *type = 0, *value = 0, *traceback = 0;
- PyErr_Fetch(&type, &value, &traceback);
- o = wrapper(a, NULL);
- if (!o) {
- PyObject *deallocname = PyString_FromString(wrappername);
- PyErr_WriteUnraisable(deallocname);
- Py_DECREF(deallocname);
- }
- PyErr_Restore(type, value, traceback);
- Py_XDECREF(o);
- }
- if (PyType_IS_GC(a->ob_type)) {
- PyObject_GC_Del(a);
- } else {
- PyObject_Del(a);
- }
-}
-
-#define SWIGPY_INQUIRY_CLOSURE(wrapper) \
-SWIGINTERN int \
-wrapper##_inquiry_closure(PyObject *a) { \
- return SwigPyBuiltin_inquiry_closure(wrapper, a); \
-}
-SWIGINTERN int
-SwigPyBuiltin_inquiry_closure(SwigPyWrapperFunction wrapper, PyObject *a) {
- PyObject *pyresult;
- int result;
- pyresult = wrapper(a, NULL);
- result = pyresult && PyObject_IsTrue(pyresult) ? 1 : 0;
- Py_XDECREF(pyresult);
- return result;
-}
-
-#define SWIGPY_GETITERFUNC_CLOSURE(wrapper) \
-SWIGINTERN PyObject * \
-wrapper##_getiterfunc_closure(PyObject *a) { \
- return SwigPyBuiltin_getiterfunc_closure(wrapper, a); \
-}
-SWIGINTERN PyObject *
-SwigPyBuiltin_getiterfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a) {
- return wrapper(a, NULL);
-}
-
-#define SWIGPY_BINARYFUNC_CLOSURE(wrapper) \
-SWIGINTERN PyObject * \
-wrapper##_binaryfunc_closure(PyObject *a, PyObject *b) { \
- return SwigPyBuiltin_binaryfunc_closure(wrapper, a, b); \
-}
-SWIGINTERN PyObject *
-SwigPyBuiltin_binaryfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a, PyObject *b) {
- PyObject *tuple, *result;
- tuple = PyTuple_New(1);
- assert(tuple);
- Py_INCREF(b);
- PyTuple_SET_ITEM(tuple, 0, b);
- result = wrapper(a, tuple);
- Py_DECREF(tuple);
- return result;
-}
-
-typedef ternaryfunc ternarycallfunc;
-
-#define SWIGPY_TERNARYFUNC_CLOSURE(wrapper) \
-SWIGINTERN PyObject * \
-wrapper##_ternaryfunc_closure(PyObject *a, PyObject *b, PyObject *c) { \
- return SwigPyBuiltin_ternaryfunc_closure(wrapper, a, b, c); \
-}
-SWIGINTERN PyObject *
-SwigPyBuiltin_ternaryfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a, PyObject *b, PyObject *c) {
- PyObject *tuple, *result;
- tuple = PyTuple_New(2);
- assert(tuple);
- Py_INCREF(b);
- PyTuple_SET_ITEM(tuple, 0, b);
- Py_INCREF(c);
- PyTuple_SET_ITEM(tuple, 1, c);
- result = wrapper(a, tuple);
- Py_DECREF(tuple);
- return result;
-}
-
-#define SWIGPY_TERNARYCALLFUNC_CLOSURE(wrapper) \
-SWIGINTERN PyObject * \
-wrapper##_ternarycallfunc_closure(PyObject *a, PyObject *b, PyObject *c) { \
- return SwigPyBuiltin_ternarycallfunc_closure(wrapper, a, b, c); \
-}
-SWIGINTERN PyObject *
-SwigPyBuiltin_ternarycallfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a, PyObject *b, PyObject *c) {
- (void) c;
- return wrapper(a, b);
-}
-
-#define SWIGPY_LENFUNC_CLOSURE(wrapper) \
-SWIGINTERN Py_ssize_t \
-wrapper##_lenfunc_closure(PyObject *a) { \
- return SwigPyBuiltin_lenfunc_closure(wrapper, a); \
-}
-SWIGINTERN Py_ssize_t
-SwigPyBuiltin_lenfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a) {
- PyObject *resultobj;
- Py_ssize_t result;
- resultobj = wrapper(a, NULL);
- result = PyNumber_AsSsize_t(resultobj, NULL);
- Py_DECREF(resultobj);
- return result;
-}
-
-#define SWIGPY_SSIZESSIZEARGFUNC_CLOSURE(wrapper) \
-SWIGINTERN PyObject * \
-wrapper##_ssizessizeargfunc_closure(PyObject *a, Py_ssize_t b, Py_ssize_t c) { \
- return SwigPyBuiltin_ssizessizeargfunc_closure(wrapper, a, b, c); \
-}
-SWIGINTERN PyObject *
-SwigPyBuiltin_ssizessizeargfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a, Py_ssize_t b, Py_ssize_t c) {
- PyObject *tuple, *result;
- tuple = PyTuple_New(2);
- assert(tuple);
- PyTuple_SET_ITEM(tuple, 0, _PyLong_FromSsize_t(b));
- PyTuple_SET_ITEM(tuple, 1, _PyLong_FromSsize_t(c));
- result = wrapper(a, tuple);
- Py_DECREF(tuple);
- return result;
-}
-
-#define SWIGPY_SSIZESSIZEOBJARGPROC_CLOSURE(wrapper) \
-SWIGINTERN int \
-wrapper##_ssizessizeobjargproc_closure(PyObject *a, Py_ssize_t b, Py_ssize_t c, PyObject *d) { \
- return SwigPyBuiltin_ssizessizeobjargproc_closure(wrapper, a, b, c, d); \
-}
-SWIGINTERN int
-SwigPyBuiltin_ssizessizeobjargproc_closure(SwigPyWrapperFunction wrapper, PyObject *a, Py_ssize_t b, Py_ssize_t c, PyObject *d) {
- PyObject *tuple, *resultobj;
- int result;
- tuple = PyTuple_New(d ? 3 : 2);
- assert(tuple);
- PyTuple_SET_ITEM(tuple, 0, _PyLong_FromSsize_t(b));
- PyTuple_SET_ITEM(tuple, 1, _PyLong_FromSsize_t(c));
- if (d) {
- Py_INCREF(d);
- PyTuple_SET_ITEM(tuple, 2, d);
- }
- resultobj = wrapper(a, tuple);
- result = resultobj ? 0 : -1;
- Py_DECREF(tuple);
- Py_XDECREF(resultobj);
- return result;
-}
-
-#define SWIGPY_SSIZEARGFUNC_CLOSURE(wrapper) \
-SWIGINTERN PyObject * \
-wrapper##_ssizeargfunc_closure(PyObject *a, Py_ssize_t b) { \
- return SwigPyBuiltin_funpack_ssizeargfunc_closure(wrapper, a, b); \
-}
-SWIGINTERN PyObject *
-SwigPyBuiltin_funpack_ssizeargfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a, Py_ssize_t b) {
- PyObject *tuple, *result;
- tuple = PyTuple_New(1);
- assert(tuple);
- PyTuple_SET_ITEM(tuple, 0, _PyLong_FromSsize_t(b));
- result = wrapper(a, tuple);
- Py_DECREF(tuple);
- return result;
-}
-
-#define SWIGPY_FUNPACK_SSIZEARGFUNC_CLOSURE(wrapper) \
-SWIGINTERN PyObject * \
-wrapper##_ssizeargfunc_closure(PyObject *a, Py_ssize_t b) { \
- return SwigPyBuiltin_ssizeargfunc_closure(wrapper, a, b); \
-}
-SWIGINTERN PyObject *
-SwigPyBuiltin_ssizeargfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a, Py_ssize_t b) {
- PyObject *arg, *result;
- arg = _PyLong_FromSsize_t(b);
- result = wrapper(a, arg);
- Py_DECREF(arg);
- return result;
-}
-
-#define SWIGPY_SSIZEOBJARGPROC_CLOSURE(wrapper) \
-SWIGINTERN int \
-wrapper##_ssizeobjargproc_closure(PyObject *a, Py_ssize_t b, PyObject *c) { \
- return SwigPyBuiltin_ssizeobjargproc_closure(wrapper, a, b, c); \
-}
-SWIGINTERN int
-SwigPyBuiltin_ssizeobjargproc_closure(SwigPyWrapperFunction wrapper, PyObject *a, Py_ssize_t b, PyObject *c) {
- PyObject *tuple, *resultobj;
- int result;
- tuple = PyTuple_New(2);
- assert(tuple);
- PyTuple_SET_ITEM(tuple, 0, _PyLong_FromSsize_t(b));
- Py_INCREF(c);
- PyTuple_SET_ITEM(tuple, 1, c);
- resultobj = wrapper(a, tuple);
- result = resultobj ? 0 : -1;
- Py_XDECREF(resultobj);
- Py_DECREF(tuple);
- return result;
-}
-
-#define SWIGPY_OBJOBJPROC_CLOSURE(wrapper) \
-SWIGINTERN int \
-wrapper##_objobjproc_closure(PyObject *a, PyObject *b) { \
- return SwigPyBuiltin_objobjproc_closure(wrapper, a, b); \
-}
-SWIGINTERN int
-SwigPyBuiltin_objobjproc_closure(SwigPyWrapperFunction wrapper, PyObject *a, PyObject *b) {
- int result;
- PyObject *pyresult;
- PyObject *tuple;
- tuple = PyTuple_New(1);
- assert(tuple);
- Py_INCREF(b);
- PyTuple_SET_ITEM(tuple, 0, b);
- pyresult = wrapper(a, tuple);
- result = pyresult ? (PyObject_IsTrue(pyresult) ? 1 : 0) : -1;
- Py_XDECREF(pyresult);
- Py_DECREF(tuple);
- return result;
-}
-
-#define SWIGPY_FUNPACK_OBJOBJPROC_CLOSURE(wrapper) \
-SWIGINTERN int \
-wrapper##_objobjproc_closure(PyObject *a, PyObject *b) { \
- return SwigPyBuiltin_funpack_objobjproc_closure(wrapper, a, b); \
-}
-SWIGINTERN int
-SwigPyBuiltin_funpack_objobjproc_closure(SwigPyWrapperFunction wrapper, PyObject *a, PyObject *b) {
- int result;
- PyObject *pyresult;
- pyresult = wrapper(a, b);
- result = pyresult ? (PyObject_IsTrue(pyresult) ? 1 : 0) : -1;
- Py_XDECREF(pyresult);
- return result;
-}
-
-#define SWIGPY_OBJOBJARGPROC_CLOSURE(wrapper) \
-SWIGINTERN int \
-wrapper##_objobjargproc_closure(PyObject *a, PyObject *b, PyObject *c) { \
- return SwigPyBuiltin_objobjargproc_closure(wrapper, a, b, c); \
-}
-SWIGINTERN int
-SwigPyBuiltin_objobjargproc_closure(SwigPyWrapperFunction wrapper, PyObject *a, PyObject *b, PyObject *c) {
- PyObject *tuple, *resultobj;
- int result;
- tuple = PyTuple_New(c ? 2 : 1);
- assert(tuple);
- Py_INCREF(b);
- PyTuple_SET_ITEM(tuple, 0, b);
- if (c) {
- Py_INCREF(c);
- PyTuple_SET_ITEM(tuple, 1, c);
- }
- resultobj = wrapper(a, tuple);
- result = resultobj ? 0 : -1;
- Py_XDECREF(resultobj);
- Py_DECREF(tuple);
- return result;
-}
-
-#define SWIGPY_REPRFUNC_CLOSURE(wrapper) \
-SWIGINTERN PyObject * \
-wrapper##_reprfunc_closure(PyObject *a) { \
- return SwigPyBuiltin_reprfunc_closure(wrapper, a); \
-}
-SWIGINTERN PyObject *
-SwigPyBuiltin_reprfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a) {
- return wrapper(a, NULL);
-}
-
-#define SWIGPY_HASHFUNC_CLOSURE(wrapper) \
-SWIGINTERN Py_hash_t \
-wrapper##_hashfunc_closure(PyObject *a) { \
- return SwigPyBuiltin_hashfunc_closure(wrapper, a); \
-}
-SWIGINTERN Py_hash_t
-SwigPyBuiltin_hashfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a) {
- PyObject *pyresult;
- Py_hash_t result;
- pyresult = wrapper(a, NULL);
- if (!pyresult)
- return -1;
- result = SWIG_PyNumber_AsPyHash(pyresult);
- Py_DECREF(pyresult);
- return result;
-}
-
-#define SWIGPY_ITERNEXTFUNC_CLOSURE(wrapper) \
-SWIGINTERN PyObject * \
-wrapper##_iternextfunc_closure(PyObject *a) { \
- return SwigPyBuiltin_iternextfunc_closure(wrapper, a);\
-}
-SWIGINTERN PyObject *
-SwigPyBuiltin_iternextfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a) {
- return wrapper(a, NULL);
-}
-
-/* End of callback function macros for use in PyTypeObject */
-
-#ifdef __cplusplus
-}
-#endif
-
diff --git a/contrib/tools/swig/Lib/python/pyapi.swg b/contrib/tools/swig/Lib/python/pyapi.swg
deleted file mode 100644
index 19e6979b56..0000000000
--- a/contrib/tools/swig/Lib/python/pyapi.swg
+++ /dev/null
@@ -1,30 +0,0 @@
-/* -----------------------------------------------------------------------------
- * Python API portion that goes into the runtime
- * ----------------------------------------------------------------------------- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* -----------------------------------------------------------------------------
- * Constant declarations
- * ----------------------------------------------------------------------------- */
-
-/* Constant Types */
-#define SWIG_PY_POINTER 4
-#define SWIG_PY_BINARY 5
-
-/* Constant information structure */
-typedef struct swig_const_info {
- int type;
- const char *name;
- long lvalue;
- double dvalue;
- void *pvalue;
- swig_type_info **ptype;
-} swig_const_info;
-
-#ifdef __cplusplus
-}
-#endif
-
diff --git a/contrib/tools/swig/Lib/python/pybackward.swg b/contrib/tools/swig/Lib/python/pybackward.swg
deleted file mode 100644
index 8305fc78b7..0000000000
--- a/contrib/tools/swig/Lib/python/pybackward.swg
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- adding backward compatibility macros
-*/
-
-#define SWIG_arg(x...) %arg(x)
-#define SWIG_Mangle(x...) %mangle(x)
-
-#define SWIG_As_frag(Type...) %fragment_name(As, Type)
-#define SWIG_As_name(Type...) %symbol_name(As, Type)
-#define SWIG_As(Type...) SWIG_As_name(Type) SWIG_AS_CALL_ARGS
-
-#define SWIG_Check_frag(Type...) %fragment_name(Check, Type)
-#define SWIG_Check_name(Type...) %symbol_name(Check, Type)
-#define SWIG_Check(Type...) SWIG_Check_name(Type) SWIG_AS_CALL_ARGS
-
-%define %ascheck_methods(Code, Type...)
-%fragment(SWIG_As_frag(Type),"header", fragment=SWIG_AsVal_frag(Type)) {
-SWIGINTERNINLINE Type
-SWIG_As(Type)(PyObject* obj)
-{
- Type v;
- int res = SWIG_AsVal(Type)(obj, &v);
- if (!SWIG_IsOK(res)) {
- /*
- this is needed to make valgrind/purify happier.
- */
- memset((void*)&v, 0, sizeof(Type));
- SWIG_Error(res, "");
- }
- return v;
-}
-}
-
-%fragment(SWIG_Check_frag(Type),"header",fragment=SWIG_AsVal_frag(Type)) {
-SWIGINTERNINLINE int
-SWIG_Check(Type)(PyObject* obj)
-{
- int res = SWIG_AsVal(Type)(obj, (Type*)0);
- return SWIG_IsOK(res);
-}
-}
-%enddef
-
-%apply_checkctypes(%ascheck_methods)
-
diff --git a/contrib/tools/swig/Lib/python/pyclasses.swg b/contrib/tools/swig/Lib/python/pyclasses.swg
deleted file mode 100644
index 31ebdd2a15..0000000000
--- a/contrib/tools/swig/Lib/python/pyclasses.swg
+++ /dev/null
@@ -1,157 +0,0 @@
-#ifdef __cplusplus
-
-/*
- SwigPtr_PyObject is used as a replacement of PyObject *, where
- the INCREF/DECREF are applied as needed.
-
- You can use SwigPtr_PyObject in a container, such as
-
- std::vector<SwigPtr_PyObject>;
-
- or as a member variable:
-
- struct A {
- SwigPtr_PyObject obj;
- A(PyObject *o) : _obj(o) {
- }
- };
-
- or as a input/output value
-
- SwigPtr_PyObject func(SwigPtr_PyObject obj) {
- SwigPtr_PyObject out = PyString_FromFormat("hello %s", PyObject_AsString(obj));
- Py_DECREF(out);
- return out;
- }
-
- just remember to pair the object creation with the proper DECREF,
- the same as with plain PyObject *ptr, since SwigPtr_PyObject always add
- one reference at construction.
-
- SwigPtr_PyObject is 'visible' at the wrapped side, so you can do:
-
-
- %template(pyvector) std::vector<swig::SwigPtr_PyObject>;
-
- and all the proper typemaps will be used.
-
-*/
-
-namespace swig {
- %ignore SwigPtr_PyObject;
- struct SwigPtr_PyObject {};
- %apply PyObject * {SwigPtr_PyObject};
- %apply PyObject * const& {SwigPtr_PyObject const&};
-
- %typemap(typecheck,precedence=SWIG_TYPECHECK_SWIGOBJECT,noblock=1) SwigPtr_PyObject const& "$1 = ($input != 0);"
-
-
- /* For output */
- %typemap(out,noblock=1) SwigPtr_PyObject {
- $result = (PyObject *)$1;
- Py_INCREF($result);
- }
-
- %typemap(out,noblock=1) SwigPtr_PyObject const & {
- $result = (PyObject *)*$1;
- Py_INCREF($result);
- }
-
-}
-
-%{
-namespace swig {
- class SwigPtr_PyObject {
- protected:
- PyObject *_obj;
-
- public:
- SwigPtr_PyObject() :_obj(0)
- {
- }
-
- SwigPtr_PyObject(const SwigPtr_PyObject& item) : _obj(item._obj)
- {
- SWIG_PYTHON_THREAD_BEGIN_BLOCK;
- Py_XINCREF(_obj);
- SWIG_PYTHON_THREAD_END_BLOCK;
- }
-
- SwigPtr_PyObject(PyObject *obj, bool initial_ref = true) :_obj(obj)
- {
- if (initial_ref) {
- SWIG_PYTHON_THREAD_BEGIN_BLOCK;
- Py_XINCREF(_obj);
- SWIG_PYTHON_THREAD_END_BLOCK;
- }
- }
-
- SwigPtr_PyObject & operator=(const SwigPtr_PyObject& item)
- {
- SWIG_PYTHON_THREAD_BEGIN_BLOCK;
- Py_XINCREF(item._obj);
- Py_XDECREF(_obj);
- _obj = item._obj;
- SWIG_PYTHON_THREAD_END_BLOCK;
- return *this;
- }
-
- ~SwigPtr_PyObject()
- {
- SWIG_PYTHON_THREAD_BEGIN_BLOCK;
- Py_XDECREF(_obj);
- SWIG_PYTHON_THREAD_END_BLOCK;
- }
-
- operator PyObject *() const
- {
- return _obj;
- }
-
- PyObject *operator->() const
- {
- return _obj;
- }
- };
-}
-%}
-
-/*
- SwigVar_PyObject is used to manage 'in the scope' PyObject * variables,
- as in
-
- int func () {
- SwigVar_PyObject obj = PyString_FromString("hello");
- }
-
- ie, 'obj' is created and destructed in the same scope from
- a python object that carries at least one reference value.
-
- SwigVar_PyObject just take care of applying the proper Py_DECREF.
-
- Hence, this class is purely internal and not visible at the wrapped side.
- */
-namespace swig {
- %ignore SwigVar_PyObject;
- struct SwigVar_PyObject {};
- %apply PyObject * {SwigVar_PyObject};
- %apply PyObject * const& {SwigVar_PyObject const&};
-}
-
-%{
-namespace swig {
- struct SwigVar_PyObject : SwigPtr_PyObject {
- SwigVar_PyObject(PyObject* obj = 0) : SwigPtr_PyObject(obj, false) { }
-
- SwigVar_PyObject & operator = (PyObject* obj)
- {
- Py_XDECREF(_obj);
- _obj = obj;
- return *this;
- }
- };
-}
-%}
-
-
-#endif
diff --git a/contrib/tools/swig/Lib/python/pydocs.swg b/contrib/tools/swig/Lib/python/pydocs.swg
deleted file mode 100644
index 5a25423d4c..0000000000
--- a/contrib/tools/swig/Lib/python/pydocs.swg
+++ /dev/null
@@ -1,45 +0,0 @@
-
-// Documentation for use with the autodoc feature.
-
-#ifdef SWIG_DOC_DOXYGEN_STYLE
-%typemap(doc) SWIGTYPE "@param $1_name $1_type"
-%typemap(doc) SWIGTYPE * "@param $1_name $1_type"
-%typemap(doc) const SWIGTYPE & "@param $1_name $1_type"
-%typemap(doc) const SWIGTYPE && "@param $1_name $1_type"
-%typemap(doc) enum SWIGTYPE "@param $1_name enum $1_type"
-
-%typemap(doc) SWIGTYPE *INOUT, SWIGTYPE &INOUT "@param $1_name $1_type (input/output)"
-%typemap(doc) SWIGTYPE *INPUT, SWIGTYPE &INPUT "@param $1_name $1_type (input)"
-%typemap(doc) SWIGTYPE *OUTPUT, SWIGTYPE &OUTPUT "@param $1_name $1_type (output)"
-#else
-%typemap(doc) SWIGTYPE "$1_name: $1_type"
-%typemap(doc) SWIGTYPE * "$1_name: $1_type"
-%typemap(doc) const SWIGTYPE & "$1_name: $1_type"
-%typemap(doc) const SWIGTYPE && "$1_name: $1_type"
-%typemap(doc) enum SWIGTYPE "$1_name: enum $1_type"
-
-%typemap(doc) SWIGTYPE *INOUT, SWIGTYPE &INOUT "$1_name: $1_type (input/output)"
-%typemap(doc) SWIGTYPE *INPUT, SWIGTYPE &INPUT "$1_name: $1_type (input)"
-%typemap(doc) SWIGTYPE *OUTPUT, SWIGTYPE &OUTPUT "$1_name: $1_type (output)"
-#endif
-
-
-// Types to use in Python documentation for the parameters of the given C++ type.
-%typemap(doctype) bool "boolean"
-
-%define int_doctype_for_cppint_type(cppint_type)
- %typemap(doctype) cppint_type, unsigned cppint_type "int"
-%enddef
-%formacro(int_doctype_for_cppint_type, short, int, long, long long)
-
-%typemap(doctype) size_t "int"
-
-%typemap(doctype) enum SWIGTYPE "int"
-
-%typemap(doctype) float, double, long double "float"
-
-%typemap(doctype) char*, std::string "string"
-
-%typemap(doctype) SWIGTYPE "$1_basetype"
-%typemap(doctype) SWIGTYPE * "$typemap(doctype, $*1_ltype)"
-%typemap(doctype) SWIGTYPE & "$typemap(doctype, $*1_ltype)"
diff --git a/contrib/tools/swig/Lib/python/pyerrors.swg b/contrib/tools/swig/Lib/python/pyerrors.swg
deleted file mode 100644
index 10b694cde6..0000000000
--- a/contrib/tools/swig/Lib/python/pyerrors.swg
+++ /dev/null
@@ -1,107 +0,0 @@
-/* -----------------------------------------------------------------------------
- * error manipulation
- * ----------------------------------------------------------------------------- */
-
-SWIGRUNTIME PyObject*
-SWIG_Python_ErrorType(int code) {
- PyObject* type = 0;
- switch(code) {
- case SWIG_MemoryError:
- type = PyExc_MemoryError;
- break;
- case SWIG_IOError:
- type = PyExc_IOError;
- break;
- case SWIG_RuntimeError:
- type = PyExc_RuntimeError;
- break;
- case SWIG_IndexError:
- type = PyExc_IndexError;
- break;
- case SWIG_TypeError:
- type = PyExc_TypeError;
- break;
- case SWIG_DivisionByZero:
- type = PyExc_ZeroDivisionError;
- break;
- case SWIG_OverflowError:
- type = PyExc_OverflowError;
- break;
- case SWIG_SyntaxError:
- type = PyExc_SyntaxError;
- break;
- case SWIG_ValueError:
- type = PyExc_ValueError;
- break;
- case SWIG_SystemError:
- type = PyExc_SystemError;
- break;
- case SWIG_AttributeError:
- type = PyExc_AttributeError;
- break;
- default:
- type = PyExc_RuntimeError;
- }
- return type;
-}
-
-
-SWIGRUNTIME void
-SWIG_Python_AddErrorMsg(const char* mesg)
-{
- PyObject *type = 0;
- PyObject *value = 0;
- PyObject *traceback = 0;
-
- if (PyErr_Occurred())
- PyErr_Fetch(&type, &value, &traceback);
- if (value) {
- PyObject *old_str = PyObject_Str(value);
- const char *tmp = SWIG_Python_str_AsChar(old_str);
- PyErr_Clear();
- Py_XINCREF(type);
- if (tmp)
- PyErr_Format(type, "%s %s", tmp, mesg);
- else
- PyErr_Format(type, "%s", mesg);
- Py_DECREF(old_str);
- Py_DECREF(value);
- } else {
- PyErr_SetString(PyExc_RuntimeError, mesg);
- }
-}
-
-SWIGRUNTIME int
-SWIG_Python_TypeErrorOccurred(PyObject *obj)
-{
- PyObject *error;
- if (obj)
- return 0;
- error = PyErr_Occurred();
- return error && PyErr_GivenExceptionMatches(error, PyExc_TypeError);
-}
-
-SWIGRUNTIME void
-SWIG_Python_RaiseOrModifyTypeError(const char *message)
-{
- if (SWIG_Python_TypeErrorOccurred(NULL)) {
- /* Use existing TypeError to preserve stacktrace and enhance with given message */
- PyObject *newvalue;
- PyObject *type = NULL, *value = NULL, *traceback = NULL;
- PyErr_Fetch(&type, &value, &traceback);
-#if PY_VERSION_HEX >= 0x03000000
- newvalue = PyUnicode_FromFormat("%S\nAdditional information:\n%s", value, message);
-#else
- newvalue = PyString_FromFormat("%s\nAdditional information:\n%s", PyString_AsString(value), message);
-#endif
- if (newvalue) {
- Py_XDECREF(value);
- PyErr_Restore(type, newvalue, traceback);
- } else {
- PyErr_Restore(type, value, traceback);
- }
- } else {
- /* Raise TypeError using given message */
- PyErr_SetString(PyExc_TypeError, message);
- }
-}
diff --git a/contrib/tools/swig/Lib/python/pyfragments.swg b/contrib/tools/swig/Lib/python/pyfragments.swg
deleted file mode 100644
index 535a45bdf2..0000000000
--- a/contrib/tools/swig/Lib/python/pyfragments.swg
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-
- Create a file with this name, 'pyfragments.swg', in your working
- directory and add all the %fragments you want to take precedence
- over the default ones defined by swig.
-
- For example, if you add:
-
- %fragment(SWIG_AsVal_frag(int),"header") {
- SWIGINTERNINLINE int
- SWIG_AsVal(int)(PyObject *obj, int *val)
- {
- <your code here>;
- }
- }
-
- this will replace the code used to retrieve an integer value for all
- the typemaps that need it, including:
-
- int, std::vector<int>, std::list<std::pair<int,int> >, etc.
-
-
-*/
diff --git a/contrib/tools/swig/Lib/python/pyhead.swg b/contrib/tools/swig/Lib/python/pyhead.swg
deleted file mode 100644
index 6f37160bb2..0000000000
--- a/contrib/tools/swig/Lib/python/pyhead.swg
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Compatibility macros for Python 3 */
-#if PY_VERSION_HEX >= 0x03000000
-
-#define PyClass_Check(obj) PyObject_IsInstance(obj, (PyObject *)&PyType_Type)
-#define PyInt_Check(x) PyLong_Check(x)
-#define PyInt_AsLong(x) PyLong_AsLong(x)
-#define PyInt_FromLong(x) PyLong_FromLong(x)
-#define PyInt_FromSize_t(x) PyLong_FromSize_t(x)
-#define PyString_Check(name) PyBytes_Check(name)
-#define PyString_FromString(x) PyUnicode_FromString(x)
-#define PyString_Format(fmt, args) PyUnicode_Format(fmt, args)
-#define PyString_AsString(str) PyBytes_AsString(str)
-#define PyString_Size(str) PyBytes_Size(str)
-#define PyString_InternFromString(key) PyUnicode_InternFromString(key)
-#define Py_TPFLAGS_HAVE_CLASS Py_TPFLAGS_BASETYPE
-#define _PyLong_FromSsize_t(x) PyLong_FromSsize_t(x)
-
-#endif
-
-#ifndef Py_TYPE
-# define Py_TYPE(op) ((op)->ob_type)
-#endif
-
-/* SWIG APIs for compatibility of both Python 2 & 3 */
-
-#if PY_VERSION_HEX >= 0x03000000
-# define SWIG_Python_str_FromFormat PyUnicode_FromFormat
-#else
-# define SWIG_Python_str_FromFormat PyString_FromFormat
-#endif
-
-
-SWIGINTERN char*
-SWIG_Python_str_AsChar(PyObject *str)
-{
-#if PY_VERSION_HEX >= 0x03030000
- return (char *)PyUnicode_AsUTF8(str);
-#else
- return PyString_AsString(str);
-#endif
-}
-
-/* Was useful for Python 3.0.x-3.2.x - now provided only for compatibility
- * with any uses in user interface files. */
-#define SWIG_Python_str_DelForPy3(x)
-
-
-SWIGINTERN PyObject*
-SWIG_Python_str_FromChar(const char *c)
-{
-#if PY_VERSION_HEX >= 0x03000000
- return PyUnicode_FromString(c);
-#else
- return PyString_FromString(c);
-#endif
-}
-
-#ifndef PyObject_DEL
-# define PyObject_DEL PyObject_Del
-#endif
-
-/* SWIGPY_USE_CAPSULE is no longer used within SWIG itself, but some user interface files check for it. */
-# define SWIGPY_USE_CAPSULE
-#ifdef SWIGPYTHON_BUILTIN
-# define SWIGPY_CAPSULE_ATTR_NAME "type_pointer_capsule_builtin" SWIG_TYPE_TABLE_NAME
-#else
-# define SWIGPY_CAPSULE_ATTR_NAME "type_pointer_capsule" SWIG_TYPE_TABLE_NAME
-#endif
-# define SWIGPY_CAPSULE_NAME ("swig_runtime_data" SWIG_RUNTIME_VERSION "." SWIGPY_CAPSULE_ATTR_NAME)
-
-#if PY_VERSION_HEX < 0x03020000
-#define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type)
-#define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name)
-#define Py_hash_t long
-#endif
diff --git a/contrib/tools/swig/Lib/python/pyinit.swg b/contrib/tools/swig/Lib/python/pyinit.swg
deleted file mode 100644
index 6833b455aa..0000000000
--- a/contrib/tools/swig/Lib/python/pyinit.swg
+++ /dev/null
@@ -1,325 +0,0 @@
-/* ------------------------------------------------------------
- * The start of the Python initialization function
- * ------------------------------------------------------------ */
-
-%insert(init) "swiginit.swg"
-
-#if defined(SWIGPYTHON_BUILTIN)
-%fragment("<stddef.h>"); // For offsetof
-#endif
-
-#if defined SWIGPYTHON_FASTPROXY && !defined SWIGPYTHON_BUILTIN
-
-%insert(runtime) %{
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Method creation and docstring support functions */
-
-SWIGINTERN PyMethodDef *SWIG_PythonGetProxyDoc(const char *name);
-SWIGINTERN PyObject *SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func);
-SWIGINTERN PyObject *SWIG_PyStaticMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func);
-
-#ifdef __cplusplus
-}
-#endif
-%}
-
-#endif
-
-%init %{
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* -----------------------------------------------------------------------------
- * constants/methods manipulation
- * ----------------------------------------------------------------------------- */
-
-/* Install Constants */
-SWIGINTERN void
-SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) {
- PyObject *obj = 0;
- size_t i;
- for (i = 0; constants[i].type; ++i) {
- switch(constants[i].type) {
- case SWIG_PY_POINTER:
- obj = SWIG_InternalNewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0);
- break;
- case SWIG_PY_BINARY:
- obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype));
- break;
- default:
- obj = 0;
- break;
- }
- if (obj) {
- PyDict_SetItemString(d, constants[i].name, obj);
- Py_DECREF(obj);
- }
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Patch %callback methods' docstrings to hold the callback ptrs
- * -----------------------------------------------------------------------------*/
-
-SWIGINTERN void
-SWIG_Python_FixMethods(PyMethodDef *methods, const swig_const_info *const_table, swig_type_info **types, swig_type_info **types_initial) {
- size_t i;
- for (i = 0; methods[i].ml_name; ++i) {
- const char *c = methods[i].ml_doc;
- if (!c) continue;
- c = strstr(c, "swig_ptr: ");
- if (c) {
- int j;
- const swig_const_info *ci = 0;
- const char *name = c + 10;
- for (j = 0; const_table[j].type; ++j) {
- if (strncmp(const_table[j].name, name,
- strlen(const_table[j].name)) == 0) {
- ci = &(const_table[j]);
- break;
- }
- }
- if (ci) {
- void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0;
- if (ptr) {
- size_t shift = (ci->ptype) - types;
- swig_type_info *ty = types_initial[shift];
- size_t ldoc = (c - methods[i].ml_doc);
- size_t lptr = strlen(ty->name)+2*sizeof(void*)+2;
- char *ndoc = (char*)malloc(ldoc + lptr + 10);
- if (ndoc) {
- char *buff = ndoc;
- memcpy(buff, methods[i].ml_doc, ldoc);
- buff += ldoc;
- memcpy(buff, "swig_ptr: ", 10);
- buff += 10;
- SWIG_PackVoidPtr(buff, ptr, ty->name, lptr);
- methods[i].ml_doc = ndoc;
- }
- }
- }
- }
- }
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-%}
-
-#if defined SWIGPYTHON_FASTPROXY && !defined SWIGPYTHON_BUILTIN
-
-%init %{
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* -----------------------------------------------------------------------------
- * Method creation and docstring support functions
- * ----------------------------------------------------------------------------- */
-
-/* -----------------------------------------------------------------------------
- * Function to find the method definition with the correct docstring for the
- * proxy module as opposed to the low-level API
- * ----------------------------------------------------------------------------- */
-
-SWIGINTERN PyMethodDef *SWIG_PythonGetProxyDoc(const char *name) {
- /* Find the function in the modified method table */
- size_t offset = 0;
- int found = 0;
- while (SwigMethods_proxydocs[offset].ml_meth != NULL) {
- if (strcmp(SwigMethods_proxydocs[offset].ml_name, name) == 0) {
- found = 1;
- break;
- }
- offset++;
- }
- /* Use the copy with the modified docstring if available */
- return found ? &SwigMethods_proxydocs[offset] : NULL;
-}
-
-/* -----------------------------------------------------------------------------
- * Wrapper of PyInstanceMethod_New() used in Python 3
- * It is exported to the generated module, used for -fastproxy
- * ----------------------------------------------------------------------------- */
-
-SWIGINTERN PyObject *SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func) {
- if (PyCFunction_Check(func)) {
- PyCFunctionObject *funcobj = (PyCFunctionObject *)func;
- PyMethodDef *ml = SWIG_PythonGetProxyDoc(funcobj->m_ml->ml_name);
- if (ml)
- func = PyCFunction_NewEx(ml, funcobj->m_self, funcobj->m_module);
- }
-#if PY_VERSION_HEX >= 0x03000000
- return PyInstanceMethod_New(func);
-#else
- return PyMethod_New(func, NULL, NULL);
-#endif
-}
-
-/* -----------------------------------------------------------------------------
- * Wrapper of PyStaticMethod_New()
- * It is exported to the generated module, used for -fastproxy
- * ----------------------------------------------------------------------------- */
-
-SWIGINTERN PyObject *SWIG_PyStaticMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func) {
- if (PyCFunction_Check(func)) {
- PyCFunctionObject *funcobj = (PyCFunctionObject *)func;
- PyMethodDef *ml = SWIG_PythonGetProxyDoc(funcobj->m_ml->ml_name);
- if (ml)
- func = PyCFunction_NewEx(ml, funcobj->m_self, funcobj->m_module);
- }
- return PyStaticMethod_New(func);
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-%}
-
-#endif
-
-%init %{
-
-/* -----------------------------------------------------------------------------*
- * Partial Init method
- * -----------------------------------------------------------------------------*/
-
-#ifdef __cplusplus
-extern "C"
-#endif
-
-SWIGEXPORT
-#if PY_VERSION_HEX >= 0x03000000
- PyObject*
-#else
- void
-#endif
-SWIG_init(void) {
- PyObject *m, *d, *md, *globals;
-
-#if PY_VERSION_HEX >= 0x03000000
- static struct PyModuleDef SWIG_module = {
- PyModuleDef_HEAD_INIT,
- SWIG_name,
- NULL,
- -1,
- SwigMethods,
- NULL,
- NULL,
- NULL,
- NULL
- };
-#endif
-
-#if defined(SWIGPYTHON_BUILTIN)
- static SwigPyClientData SwigPyObject_clientdata = {0, 0, 0, 0, 0, 0, 0};
- static PyGetSetDef this_getset_def = {
- (char *)"this", &SwigPyBuiltin_ThisClosure, NULL, NULL, NULL
- };
- static SwigPyGetSet thisown_getset_closure = {
- SwigPyObject_own,
- SwigPyObject_own
- };
- static PyGetSetDef thisown_getset_def = {
- (char *)"thisown", SwigPyBuiltin_GetterClosure, SwigPyBuiltin_SetterClosure, NULL, &thisown_getset_closure
- };
- PyTypeObject *builtin_pytype;
- int builtin_base_count;
- swig_type_info *builtin_basetype;
- PyObject *tuple;
- PyGetSetDescrObject *static_getset;
- PyTypeObject *metatype;
- PyTypeObject *swigpyobject;
- SwigPyClientData *cd;
- PyObject *public_interface, *public_symbol;
- PyObject *this_descr;
- PyObject *thisown_descr;
- PyObject *self = 0;
- int i;
-
- (void)builtin_pytype;
- (void)builtin_base_count;
- (void)builtin_basetype;
- (void)tuple;
- (void)static_getset;
- (void)self;
-
- /* Metaclass is used to implement static member variables */
- metatype = SwigPyObjectType();
- assert(metatype);
-#endif
-
- (void)globals;
-
- /* Create singletons now to avoid potential deadlocks with multi-threaded usage after module initialization */
- SWIG_This();
- SWIG_Python_TypeCache();
- SwigPyPacked_type();
-#ifndef SWIGPYTHON_BUILTIN
- SwigPyObject_type();
-#endif
-
- /* Fix SwigMethods to carry the callback ptrs when needed */
- SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial);
-
-#if PY_VERSION_HEX >= 0x03000000
- m = PyModule_Create(&SWIG_module);
-#else
- m = Py_InitModule(SWIG_name, SwigMethods);
-#endif
-
- md = d = PyModule_GetDict(m);
- (void)md;
-
- SWIG_InitializeModule(0);
-
-#ifdef SWIGPYTHON_BUILTIN
- swigpyobject = SwigPyObject_TypeOnce();
-
- SwigPyObject_stype = SWIG_MangledTypeQuery("_p_SwigPyObject");
- assert(SwigPyObject_stype);
- cd = (SwigPyClientData*) SwigPyObject_stype->clientdata;
- if (!cd) {
- SwigPyObject_stype->clientdata = &SwigPyObject_clientdata;
- SwigPyObject_clientdata.pytype = swigpyobject;
- } else if (swigpyobject->tp_basicsize != cd->pytype->tp_basicsize) {
- PyErr_SetString(PyExc_RuntimeError, "Import error: attempted to load two incompatible swig-generated modules.");
-# if PY_VERSION_HEX >= 0x03000000
- return NULL;
-# else
- return;
-# endif
- }
-
- /* All objects have a 'this' attribute */
- this_descr = PyDescr_NewGetSet(SwigPyObject_type(), &this_getset_def);
- (void)this_descr;
-
- /* All objects have a 'thisown' attribute */
- thisown_descr = PyDescr_NewGetSet(SwigPyObject_type(), &thisown_getset_def);
- (void)thisown_descr;
-
- public_interface = PyList_New(0);
- public_symbol = 0;
- (void)public_symbol;
-
- PyDict_SetItemString(md, "__all__", public_interface);
- Py_DECREF(public_interface);
- for (i = 0; SwigMethods[i].ml_name != NULL; ++i)
- SwigPyBuiltin_AddPublicSymbol(public_interface, SwigMethods[i].ml_name);
- for (i = 0; swig_const_table[i].name != 0; ++i)
- SwigPyBuiltin_AddPublicSymbol(public_interface, swig_const_table[i].name);
-#endif
-
- SWIG_InstallConstants(d,swig_const_table);
-%}
-
diff --git a/contrib/tools/swig/Lib/python/pymacros.swg b/contrib/tools/swig/Lib/python/pymacros.swg
deleted file mode 100644
index ab7bace5ba..0000000000
--- a/contrib/tools/swig/Lib/python/pymacros.swg
+++ /dev/null
@@ -1,4 +0,0 @@
-%include <typemaps/swigmacros.swg>
-
-
-
diff --git a/contrib/tools/swig/Lib/python/pyopers.swg b/contrib/tools/swig/Lib/python/pyopers.swg
deleted file mode 100644
index fd2fcc5812..0000000000
--- a/contrib/tools/swig/Lib/python/pyopers.swg
+++ /dev/null
@@ -1,264 +0,0 @@
-/* ------------------------------------------------------------
- * Overloaded operator support
-
- The directives in this file apply whether or not you use the
- -builtin option to SWIG, but operator overloads are particularly
- attractive when using -builtin, because they are much faster
- than named methods.
-
- If you're using the -builtin option to SWIG, and you want to define
- python operator overloads beyond the defaults defined in this file,
- here's what you need to know:
-
- There are two ways to define a python slot function: dispatch to a
- statically defined function; or dispatch to a method defined on the
- operand.
-
- To dispatch to a statically defined function, use %feature("python:<slot>"),
- where <slot> is the name of a field in a PyTypeObject, PyNumberMethods,
- PyMappingMethods, PySequenceMethods, or PyBufferProcs. For example:
-
- %feature("python:tp_hash") MyClass "myHashFunc";
-
- class MyClass {
- public:
- ...
- };
-
- %{
- // Note: Py_hash_t was introduced in Python 3.2
- static Py_hash_t myHashFunc(PyObject *pyobj) {
- MyClass *cobj;
- // Convert pyobj to cobj
- return (cobj->field1 * (cobj->field2 << 7));
- }
- %}
-
- NOTE: It is the responsibility of the programmer (that's you) to ensure
- that a statically defined slot function has the correct signature.
-
- If, instead, you want to dispatch to an instance method, you can
- use %feature("python:slot"). For example:
-
- %feature("python:slot", "tp_hash", functype="hashfunc") MyClass::myHashFunc;
-
- class MyClass {
- public:
- Py_hash_t myHashFunc () const;
- ...
- };
-
- NOTE: Some python slots use a method signature which does not
- match the signature of SWIG-wrapped methods. For those slots,
- SWIG will automatically generate a "closure" function to re-marshall
- the arguments before dispatching to the wrapped method. Setting
- the "functype" attribute of the feature enables SWIG to generate
- a correct closure function.
-
- --------------------------------------------------------------
-
- The tp_richcompare slot is a special case: SWIG automatically generates
- a rich compare function for all wrapped types. If a type defines C++
- operator overloads for comparison (operator==, operator<, etc.), they
- will be called from the generated rich compare function. If you
- want to explicitly choose a method to handle a certain comparison
- operation, you may use a different feature, %feature("python:compare")
- like this:
-
- %feature("python:compare", "Py_LT") MyClass::lessThan;
-
- class MyClass {
- public:
- bool lessThan(const MyClass& other) const;
- ...
- };
-
- ... where "Py_LT" is one of the rich comparison opcodes defined in the
- python header file object.h.
-
- If there's no method defined to handle a particular comparison operation,
- the default behavior is to compare pointer values of the wrapped
- C++ objects.
-
- --------------------------------------------------------------
-
-
- For more information about python slots, including their names and
- signatures, you may refer to the python documentation :
-
- http://docs.python.org/c-api/typeobj.html
-
- * ------------------------------------------------------------ */
-
-
-#ifdef __cplusplus
-
-#if defined(SWIGPYTHON_BUILTIN)
-#define %pybinoperator(pyname,oper,functp,slt) %rename(pyname) oper; %pythonmaybecall oper; %feature("python:slot", #slt, functype=#functp) oper; %feature("python:slot", #slt, functype=#functp) pyname;
-#define %pycompare(pyname,oper,comptype) %rename(pyname) oper; %pythonmaybecall oper; %feature("python:compare", #comptype) oper; %feature("python:compare", #comptype) pyname;
-#else
-#define %pybinoperator(pyname,oper,functp,slt) %rename(pyname) oper; %pythonmaybecall oper
-#define %pycompare(pyname,oper,comptype) %pybinoperator(pyname,oper,,comptype)
-#endif
-
-%pybinoperator(__add__, *::operator+, binaryfunc, nb_add);
-%pybinoperator(__pos__, *::operator+(), unaryfunc, nb_positive);
-%pybinoperator(__pos__, *::operator+() const, unaryfunc, nb_positive);
-%pybinoperator(__sub__, *::operator-, binaryfunc, nb_subtract);
-%pybinoperator(__neg__, *::operator-(), unaryfunc, nb_negative);
-%pybinoperator(__neg__, *::operator-() const, unaryfunc, nb_negative);
-%pybinoperator(__mul__, *::operator*, binaryfunc, nb_multiply);
-%pybinoperator(__mod__, *::operator%, binaryfunc, nb_remainder);
-%pybinoperator(__lshift__, *::operator<<, binaryfunc, nb_lshift);
-%pybinoperator(__rshift__, *::operator>>, binaryfunc, nb_rshift);
-%pybinoperator(__and__, *::operator&, binaryfunc, nb_and);
-%pybinoperator(__or__, *::operator|, binaryfunc, nb_or);
-%pybinoperator(__xor__, *::operator^, binaryfunc, nb_xor);
-%pycompare(__lt__, *::operator<, Py_LT);
-%pycompare(__le__, *::operator<=, Py_LE);
-%pycompare(__gt__, *::operator>, Py_GT);
-%pycompare(__ge__, *::operator>=, Py_GE);
-%pycompare(__eq__, *::operator==, Py_EQ);
-%pycompare(__ne__, *::operator!=, Py_NE);
-
-/* Special cases */
-%rename(__invert__) *::operator~;
-%feature("python:slot", "nb_invert", functype="unaryfunc") *::operator~;
-%rename(__call__) *::operator();
-%feature("python:slot", "tp_call", functype="ternarycallfunc") *::operator();
-
-#if defined(SWIGPYTHON_BUILTIN)
-%pybinoperator(__nonzero__, *::operator bool, inquiry, nb_nonzero);
-%pybinoperator(__truediv__, *::operator/ , binaryfunc, nb_divide);
-#else
-%feature("shadow") *::operator bool %{
-def __nonzero__(self):
- return $action(self)
-__bool__ = __nonzero__
-%};
-%rename(__nonzero__) *::operator bool;
-%feature("shadow") *::operator/ %{
-def __truediv__(self, *args):
- return $action(self, *args)
-__div__ = __truediv__
-%};
-%rename(__truediv__) *::operator/;
-%pythonmaybecall *::operator/;
-#endif
-
-/* Ignored operators */
-%ignoreoperator(LNOT) operator!;
-%ignoreoperator(LAND) operator&&;
-%ignoreoperator(LOR) operator||;
-%ignoreoperator(EQ) *::operator=;
-%ignoreoperator(PLUSPLUS) *::operator++;
-%ignoreoperator(MINUSMINUS) *::operator--;
-%ignoreoperator(ARROWSTAR) *::operator->*;
-%ignoreoperator(INDEX) *::operator[];
-
-/*
- Inplace operator declarations.
-
- They translate the inplace C++ operators (+=, -=, ...) into the
- corresponding python equivalents(__iadd__,__isub__), etc,
- disabling the ownership of the input 'this' pointer, and assigning
- it to the returning object:
-
- %feature("del") *::Operator; // disables ownership by generating SWIG_POINTER_DISOWN
- %feature("new") *::Operator; // claims ownership by generating SWIG_POINTER_OWN
-
- This makes the most common case safe, ie:
-
- A& A::operator+=(int i) { ...; return *this; }
- ^^^^ ^^^^^^
-
- will work fine, even when the resulting python object shares the
- 'this' pointer with the input one. The input object is usually
- deleted after the operation, including the shared 'this' pointer,
- producing 'strange' seg faults, as reported by Lucriz
- (lucriz@sitilandia.it).
-
- If you have an interface that already takes care of that, ie, you
- already are using inplace operators and you are not getting
- seg. faults, with the new scheme you could end with 'free' elements
- that never get deleted (maybe, not sure, it depends). But if that is
- the case, you could recover the old behaviour using
-
- %feature("del","0") A::operator+=;
- %feature("new","0") A::operator+=;
-
- which recovers the old behaviour for the class 'A', or if you are
- 100% sure your entire system works fine in the old way, use:
-
- %feature("del","") *::operator+=;
- %feature("new","") *::operator+=;
-
- The default behaviour assumes that the 'this' pointer's memory is
- already owned by the SWIG object; it relinquishes ownership then
- takes it back. This may not be the case though as the SWIG object
- might be owned by memory managed elsewhere, eg after calling a
- function that returns a C++ reference. In such case you will need
- to use the features above to recover the old behaviour too.
-*/
-
-#if defined(SWIGPYTHON_BUILTIN)
-#define %pyinplaceoper(SwigPyOper, Oper, functp, slt) %delobject Oper; %newobject Oper; %feature("python:slot", #slt, functype=#functp) Oper; %rename(SwigPyOper) Oper
-#else
-#define %pyinplaceoper(SwigPyOper, Oper, functp, slt) %delobject Oper; %newobject Oper; %rename(SwigPyOper) Oper
-#endif
-
-%pyinplaceoper(__iadd__ , *::operator +=, binaryfunc, nb_inplace_add);
-%pyinplaceoper(__isub__ , *::operator -=, binaryfunc, nb_inplace_subtract);
-%pyinplaceoper(__imul__ , *::operator *=, binaryfunc, nb_inplace_multiply);
-%pyinplaceoper(__imod__ , *::operator %=, binaryfunc, nb_inplace_remainder);
-%pyinplaceoper(__iand__ , *::operator &=, binaryfunc, nb_inplace_and);
-%pyinplaceoper(__ior__ , *::operator |=, binaryfunc, nb_inplace_or);
-%pyinplaceoper(__ixor__ , *::operator ^=, binaryfunc, nb_inplace_xor);
-%pyinplaceoper(__ilshift__, *::operator <<=, binaryfunc, nb_inplace_lshift);
-%pyinplaceoper(__irshift__, *::operator >>=, binaryfunc, nb_inplace_rshift);
-
-/* Special cases */
-#if defined(SWIGPYTHON_BUILTIN)
-%pyinplaceoper(__itruediv__ , *::operator /=, binaryfunc, nb_inplace_divide);
-#else
-%delobject *::operator /=;
-%newobject *::operator /=;
-%feature("shadow") *::operator /= %{
-def __itruediv__(self, *args):
- return $action(self, *args)
-__idiv__ = __itruediv__
-%};
-%rename(__itruediv__) *::operator /=;
-#endif
-
-/* Finally, in python we need to mark the binary operations to fail as
- 'maybecall' methods */
-
-#define %pybinopermaybecall(oper) %pythonmaybecall __ ## oper ## __; %pythonmaybecall __r ## oper ## __
-
-%pybinopermaybecall(add);
-%pybinopermaybecall(pos);
-%pybinopermaybecall(pos);
-%pybinopermaybecall(sub);
-%pybinopermaybecall(neg);
-%pybinopermaybecall(neg);
-%pybinopermaybecall(mul);
-%pybinopermaybecall(div);
-%pybinopermaybecall(truediv);
-%pybinopermaybecall(mod);
-%pybinopermaybecall(lshift);
-%pybinopermaybecall(rshift);
-%pybinopermaybecall(and);
-%pybinopermaybecall(or);
-%pybinopermaybecall(xor);
-%pybinopermaybecall(lt);
-%pybinopermaybecall(le);
-%pybinopermaybecall(gt);
-%pybinopermaybecall(ge);
-%pybinopermaybecall(eq);
-%pybinopermaybecall(ne);
-
-#endif
-
-
-
diff --git a/contrib/tools/swig/Lib/python/pyprimtypes.swg b/contrib/tools/swig/Lib/python/pyprimtypes.swg
deleted file mode 100644
index 6a01af17cf..0000000000
--- a/contrib/tools/swig/Lib/python/pyprimtypes.swg
+++ /dev/null
@@ -1,353 +0,0 @@
-/* ------------------------------------------------------------
- * Primitive Types
- * ------------------------------------------------------------ */
-
-/* boolean */
-
-%fragment(SWIG_From_frag(bool),"header") {
-SWIGINTERNINLINE PyObject*
- SWIG_From_dec(bool)(bool value)
-{
- return PyBool_FromLong(value ? 1 : 0);
-}
-}
-
-#ifdef SWIG_PYTHON_LEGACY_BOOL
-// Default prior to SWIG 3.0.0
-%fragment(SWIG_AsVal_frag(bool),"header",
- fragment=SWIG_AsVal_frag(long)) {
-SWIGINTERN int
-SWIG_AsVal_dec(bool)(PyObject *obj, bool *val)
-{
- int r = PyObject_IsTrue(obj);
- if (r == -1)
- return SWIG_ERROR;
- if (val) *val = r ? true : false;
- return SWIG_OK;
-}
-}
-#else
-%fragment(SWIG_AsVal_frag(bool),"header",
- fragment=SWIG_AsVal_frag(long)) {
-SWIGINTERN int
-SWIG_AsVal_dec(bool)(PyObject *obj, bool *val)
-{
- int r;
- if (!PyBool_Check(obj))
- return SWIG_ERROR;
- r = PyObject_IsTrue(obj);
- if (r == -1)
- return SWIG_ERROR;
- if (val) *val = r ? true : false;
- return SWIG_OK;
-}
-}
-#endif
-
-/* int */
-
-%fragment(SWIG_From_frag(int),"header") {
-SWIGINTERNINLINE PyObject*
- SWIG_From_dec(int)(int value)
-{
- return PyInt_FromLong((long) value);
-}
-}
-
-/* unsigned int */
-
-%fragment(SWIG_From_frag(unsigned int),"header") {
-SWIGINTERNINLINE PyObject*
- SWIG_From_dec(unsigned int)(unsigned int value)
-{
- return PyInt_FromSize_t((size_t) value);
-}
-}
-
-/* long */
-
-%fragment(SWIG_From_frag(long),"header") {
- %define_as(SWIG_From_dec(long), PyInt_FromLong)
-}
-
-%fragment(SWIG_AsVal_frag(long),"header",
- fragment="SWIG_CanCastAsInteger") {
-SWIGINTERN int
-SWIG_AsVal_dec(long)(PyObject *obj, long* val)
-{
-%#if PY_VERSION_HEX < 0x03000000
- if (PyInt_Check(obj)) {
- if (val) *val = PyInt_AsLong(obj);
- return SWIG_OK;
- } else
-%#endif
- if (PyLong_Check(obj)) {
- long v = PyLong_AsLong(obj);
- if (!PyErr_Occurred()) {
- if (val) *val = v;
- return SWIG_OK;
- } else {
- PyErr_Clear();
- return SWIG_OverflowError;
- }
- }
-%#ifdef SWIG_PYTHON_CAST_MODE
- {
- int dispatch = 0;
- long v = PyInt_AsLong(obj);
- if (!PyErr_Occurred()) {
- if (val) *val = v;
- return SWIG_AddCast(SWIG_OK);
- } else {
- PyErr_Clear();
- }
- if (!dispatch) {
- double d;
- int res = SWIG_AddCast(SWIG_AsVal(double)(obj,&d));
- if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) {
- if (val) *val = (long)(d);
- return res;
- }
- }
- }
-%#endif
- return SWIG_TypeError;
-}
-}
-
-/* unsigned long */
-
-%fragment(SWIG_From_frag(unsigned long),"header",
- fragment=SWIG_From_frag(long)) {
-SWIGINTERNINLINE PyObject*
-SWIG_From_dec(unsigned long)(unsigned long value)
-{
- return (value > LONG_MAX) ?
- PyLong_FromUnsignedLong(value) : PyInt_FromLong(%numeric_cast(value,long));
-}
-}
-
-%fragment(SWIG_AsVal_frag(unsigned long),"header",
- fragment="SWIG_CanCastAsInteger") {
-SWIGINTERN int
-SWIG_AsVal_dec(unsigned long)(PyObject *obj, unsigned long *val)
-{
-%#if PY_VERSION_HEX < 0x03000000
- if (PyInt_Check(obj)) {
- long v = PyInt_AsLong(obj);
- if (v >= 0) {
- if (val) *val = v;
- return SWIG_OK;
- } else {
- return SWIG_OverflowError;
- }
- } else
-%#endif
- if (PyLong_Check(obj)) {
- unsigned long v = PyLong_AsUnsignedLong(obj);
- if (!PyErr_Occurred()) {
- if (val) *val = v;
- return SWIG_OK;
- } else {
- PyErr_Clear();
- return SWIG_OverflowError;
- }
- }
-%#ifdef SWIG_PYTHON_CAST_MODE
- {
- int dispatch = 0;
- unsigned long v = PyLong_AsUnsignedLong(obj);
- if (!PyErr_Occurred()) {
- if (val) *val = v;
- return SWIG_AddCast(SWIG_OK);
- } else {
- PyErr_Clear();
- }
- if (!dispatch) {
- double d;
- int res = SWIG_AddCast(SWIG_AsVal(double)(obj,&d));
- if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ULONG_MAX)) {
- if (val) *val = (unsigned long)(d);
- return res;
- }
- }
- }
-%#endif
- return SWIG_TypeError;
-}
-}
-
-/* long long */
-
-%fragment(SWIG_From_frag(long long),"header",
- fragment="SWIG_LongLongAvailable") {
-%#ifdef SWIG_LONG_LONG_AVAILABLE
-SWIGINTERNINLINE PyObject*
-SWIG_From_dec(long long)(long long value)
-{
- return ((value < LONG_MIN) || (value > LONG_MAX)) ?
- PyLong_FromLongLong(value) : PyInt_FromLong(%numeric_cast(value,long));
-}
-%#endif
-}
-
-%fragment(SWIG_AsVal_frag(long long),"header",
- fragment=SWIG_AsVal_frag(long),
- fragment="SWIG_CanCastAsInteger",
- fragment="SWIG_LongLongAvailable") {
-%#ifdef SWIG_LONG_LONG_AVAILABLE
-SWIGINTERN int
-SWIG_AsVal_dec(long long)(PyObject *obj, long long *val)
-{
- int res = SWIG_TypeError;
- if (PyLong_Check(obj)) {
- long long v = PyLong_AsLongLong(obj);
- if (!PyErr_Occurred()) {
- if (val) *val = v;
- return SWIG_OK;
- } else {
- PyErr_Clear();
- res = SWIG_OverflowError;
- }
- } else {
- long v;
- res = SWIG_AsVal(long)(obj,&v);
- if (SWIG_IsOK(res)) {
- if (val) *val = v;
- return res;
- }
- }
-%#ifdef SWIG_PYTHON_CAST_MODE
- {
- const double mant_max = 1LL << DBL_MANT_DIG;
- const double mant_min = -mant_max;
- double d;
- res = SWIG_AsVal(double)(obj,&d);
- if (SWIG_IsOK(res) && !SWIG_CanCastAsInteger(&d, mant_min, mant_max))
- return SWIG_OverflowError;
- if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, mant_min, mant_max)) {
- if (val) *val = (long long)(d);
- return SWIG_AddCast(res);
- }
- res = SWIG_TypeError;
- }
-%#endif
- return res;
-}
-%#endif
-}
-
-/* unsigned long long */
-
-%fragment(SWIG_From_frag(unsigned long long),"header",
- fragment="SWIG_LongLongAvailable") {
-%#ifdef SWIG_LONG_LONG_AVAILABLE
-SWIGINTERNINLINE PyObject*
-SWIG_From_dec(unsigned long long)(unsigned long long value)
-{
- return (value > LONG_MAX) ?
- PyLong_FromUnsignedLongLong(value) : PyInt_FromLong(%numeric_cast(value,long));
-}
-%#endif
-}
-
-%fragment(SWIG_AsVal_frag(unsigned long long),"header",
- fragment=SWIG_AsVal_frag(unsigned long),
- fragment="SWIG_CanCastAsInteger",
- fragment="SWIG_LongLongAvailable") {
-%#ifdef SWIG_LONG_LONG_AVAILABLE
-SWIGINTERN int
-SWIG_AsVal_dec(unsigned long long)(PyObject *obj, unsigned long long *val)
-{
- int res = SWIG_TypeError;
- if (PyLong_Check(obj)) {
- unsigned long long v = PyLong_AsUnsignedLongLong(obj);
- if (!PyErr_Occurred()) {
- if (val) *val = v;
- return SWIG_OK;
- } else {
- PyErr_Clear();
- res = SWIG_OverflowError;
- }
- } else {
- unsigned long v;
- res = SWIG_AsVal(unsigned long)(obj,&v);
- if (SWIG_IsOK(res)) {
- if (val) *val = v;
- return res;
- }
- }
-%#ifdef SWIG_PYTHON_CAST_MODE
- {
- const double mant_max = 1LL << DBL_MANT_DIG;
- double d;
- res = SWIG_AsVal(double)(obj,&d);
- if (SWIG_IsOK(res) && !SWIG_CanCastAsInteger(&d, 0, mant_max))
- return SWIG_OverflowError;
- if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, mant_max)) {
- if (val) *val = (unsigned long long)(d);
- return SWIG_AddCast(res);
- }
- res = SWIG_TypeError;
- }
-%#endif
- return res;
-}
-%#endif
-}
-
-/* double */
-
-%fragment(SWIG_From_frag(double),"header") {
- %define_as(SWIG_From_dec(double), PyFloat_FromDouble)
-}
-
-%fragment(SWIG_AsVal_frag(double),"header") {
-SWIGINTERN int
-SWIG_AsVal_dec(double)(PyObject *obj, double *val)
-{
- int res = SWIG_TypeError;
- if (PyFloat_Check(obj)) {
- if (val) *val = PyFloat_AsDouble(obj);
- return SWIG_OK;
-%#if PY_VERSION_HEX < 0x03000000
- } else if (PyInt_Check(obj)) {
- if (val) *val = (double) PyInt_AsLong(obj);
- return SWIG_OK;
-%#endif
- } else if (PyLong_Check(obj)) {
- double v = PyLong_AsDouble(obj);
- if (!PyErr_Occurred()) {
- if (val) *val = v;
- return SWIG_OK;
- } else {
- PyErr_Clear();
- }
- }
-%#ifdef SWIG_PYTHON_CAST_MODE
- {
- int dispatch = 0;
- double d = PyFloat_AsDouble(obj);
- if (!PyErr_Occurred()) {
- if (val) *val = d;
- return SWIG_AddCast(SWIG_OK);
- } else {
- PyErr_Clear();
- }
- if (!dispatch) {
- long v = PyLong_AsLong(obj);
- if (!PyErr_Occurred()) {
- if (val) *val = v;
- return SWIG_AddCast(SWIG_AddCast(SWIG_OK));
- } else {
- PyErr_Clear();
- }
- }
- }
-%#endif
- return res;
-}
-}
-
-
-
diff --git a/contrib/tools/swig/Lib/python/pyrun.swg b/contrib/tools/swig/Lib/python/pyrun.swg
deleted file mode 100644
index 6b119be1c4..0000000000
--- a/contrib/tools/swig/Lib/python/pyrun.swg
+++ /dev/null
@@ -1,1913 +0,0 @@
-/* -----------------------------------------------------------------------------
- * pyrun.swg
- *
- * This file contains the runtime support for Python modules
- * and includes code for managing global variables and pointer
- * type checking.
- *
- * ----------------------------------------------------------------------------- */
-
-#if PY_VERSION_HEX < 0x02070000 /* 2.7.0 */
-# error "This version of SWIG only supports Python >= 2.7"
-#endif
-
-#if PY_VERSION_HEX >= 0x03000000 && PY_VERSION_HEX < 0x03030000
-# error "This version of SWIG only supports Python 3 >= 3.3"
-#endif
-
-/* Common SWIG API */
-
-/* for raw pointers */
-#define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0)
-#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags)
-#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own)
-
-#ifdef SWIGPYTHON_BUILTIN
-#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(self, ptr, type, flags)
-#else
-#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(NULL, ptr, type, flags)
-#endif
-
-#define SWIG_InternalNewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(NULL, ptr, type, flags)
-
-#define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty)
-#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src)
-#define swig_owntype int
-
-/* for raw packed data */
-#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty)
-#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type)
-
-/* for class or struct pointers */
-#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags)
-#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags)
-
-/* for C or C++ function pointers */
-#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type)
-#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(NULL, ptr, type, 0)
-
-/* for C++ member pointers, ie, member methods */
-#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty)
-#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type)
-
-
-/* Runtime API */
-
-#define SWIG_GetModule(clientdata) SWIG_Python_GetModule(clientdata)
-#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer)
-#define SWIG_NewClientData(obj) SwigPyClientData_New(obj)
-
-#define SWIG_SetErrorObj SWIG_Python_SetErrorObj
-#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg
-#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code)
-#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg)
-#define SWIG_fail goto fail
-
-
-/* Runtime API implementation */
-
-/* Error manipulation */
-
-SWIGINTERN void
-SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) {
- SWIG_PYTHON_THREAD_BEGIN_BLOCK;
- PyErr_SetObject(errtype, obj);
- Py_DECREF(obj);
- SWIG_PYTHON_THREAD_END_BLOCK;
-}
-
-SWIGINTERN void
-SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) {
- SWIG_PYTHON_THREAD_BEGIN_BLOCK;
- PyErr_SetString(errtype, msg);
- SWIG_PYTHON_THREAD_END_BLOCK;
-}
-
-#define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj)
-
-/* Set a constant value */
-
-#if defined(SWIGPYTHON_BUILTIN)
-
-SWIGINTERN void
-SwigPyBuiltin_AddPublicSymbol(PyObject *seq, const char *key) {
- PyObject *s = PyString_InternFromString(key);
- PyList_Append(seq, s);
- Py_DECREF(s);
-}
-
-SWIGINTERN void
-SWIG_Python_SetConstant(PyObject *d, PyObject *public_interface, const char *name, PyObject *obj) {
- PyDict_SetItemString(d, name, obj);
- Py_DECREF(obj);
- if (public_interface)
- SwigPyBuiltin_AddPublicSymbol(public_interface, name);
-}
-
-#else
-
-SWIGINTERN void
-SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) {
- PyDict_SetItemString(d, name, obj);
- Py_DECREF(obj);
-}
-
-#endif
-
-/* Append a value to the result obj */
-
-SWIGINTERN PyObject*
-SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) {
- if (!result) {
- result = obj;
- } else if (result == Py_None) {
- Py_DECREF(result);
- result = obj;
- } else {
- if (!PyList_Check(result)) {
- PyObject *o2 = result;
- result = PyList_New(1);
- if (result) {
- PyList_SET_ITEM(result, 0, o2);
- } else {
- Py_DECREF(obj);
- return o2;
- }
- }
- PyList_Append(result,obj);
- Py_DECREF(obj);
- }
- return result;
-}
-
-/* Unpack the argument tuple */
-
-SWIGINTERN Py_ssize_t
-SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs)
-{
- if (!args) {
- if (!min && !max) {
- return 1;
- } else {
- PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none",
- name, (min == max ? "" : "at least "), (int)min);
- return 0;
- }
- }
- if (!PyTuple_Check(args)) {
- if (min <= 1 && max >= 1) {
- Py_ssize_t i;
- objs[0] = args;
- for (i = 1; i < max; ++i) {
- objs[i] = 0;
- }
- return 2;
- }
- PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple");
- return 0;
- } else {
- Py_ssize_t l = PyTuple_GET_SIZE(args);
- if (l < min) {
- PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d",
- name, (min == max ? "" : "at least "), (int)min, (int)l);
- return 0;
- } else if (l > max) {
- PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d",
- name, (min == max ? "" : "at most "), (int)max, (int)l);
- return 0;
- } else {
- Py_ssize_t i;
- for (i = 0; i < l; ++i) {
- objs[i] = PyTuple_GET_ITEM(args, i);
- }
- for (; l < max; ++l) {
- objs[l] = 0;
- }
- return i + 1;
- }
- }
-}
-
-SWIGINTERN int
-SWIG_Python_CheckNoKeywords(PyObject *kwargs, const char *name) {
- int no_kwargs = 1;
- if (kwargs) {
- assert(PyDict_Check(kwargs));
- if (PyDict_Size(kwargs) > 0) {
- PyErr_Format(PyExc_TypeError, "%s() does not take keyword arguments", name);
- no_kwargs = 0;
- }
- }
- return no_kwargs;
-}
-
-/* A functor is a function object with one single object argument */
-#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL);
-
-/*
- Helper for static pointer initialization for both C and C++ code, for example
- static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...);
-*/
-#ifdef __cplusplus
-#define SWIG_STATIC_POINTER(var) var
-#else
-#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Python-specific SWIG API */
-#define SWIG_newvarlink() SWIG_Python_newvarlink()
-#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr)
-#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants)
-
-/* -----------------------------------------------------------------------------
- * global variable support code.
- * ----------------------------------------------------------------------------- */
-
-typedef struct swig_globalvar {
- char *name; /* Name of global variable */
- PyObject *(*get_attr)(void); /* Return the current value */
- int (*set_attr)(PyObject *); /* Set the value */
- struct swig_globalvar *next;
-} swig_globalvar;
-
-typedef struct swig_varlinkobject {
- PyObject_HEAD
- swig_globalvar *vars;
-} swig_varlinkobject;
-
-SWIGINTERN PyObject *
-swig_varlink_repr(PyObject *SWIGUNUSEDPARM(v)) {
-#if PY_VERSION_HEX >= 0x03000000
- return PyUnicode_InternFromString("<Swig global variables>");
-#else
- return PyString_FromString("<Swig global variables>");
-#endif
-}
-
-SWIGINTERN PyObject *
-swig_varlink_str(PyObject *o) {
- swig_varlinkobject *v = (swig_varlinkobject *) o;
-#if PY_VERSION_HEX >= 0x03000000
- PyObject *str = PyUnicode_InternFromString("(");
- PyObject *tail;
- PyObject *joined;
- swig_globalvar *var;
- for (var = v->vars; var; var=var->next) {
- tail = PyUnicode_FromString(var->name);
- joined = PyUnicode_Concat(str, tail);
- Py_DecRef(str);
- Py_DecRef(tail);
- str = joined;
- if (var->next) {
- tail = PyUnicode_InternFromString(", ");
- joined = PyUnicode_Concat(str, tail);
- Py_DecRef(str);
- Py_DecRef(tail);
- str = joined;
- }
- }
- tail = PyUnicode_InternFromString(")");
- joined = PyUnicode_Concat(str, tail);
- Py_DecRef(str);
- Py_DecRef(tail);
- str = joined;
-#else
- PyObject *str = PyString_FromString("(");
- swig_globalvar *var;
- for (var = v->vars; var; var=var->next) {
- PyString_ConcatAndDel(&str,PyString_FromString(var->name));
- if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", "));
- }
- PyString_ConcatAndDel(&str,PyString_FromString(")"));
-#endif
- return str;
-}
-
-SWIGINTERN void
-swig_varlink_dealloc(PyObject *o) {
- swig_varlinkobject *v = (swig_varlinkobject *) o;
- swig_globalvar *var = v->vars;
- while (var) {
- swig_globalvar *n = var->next;
- free(var->name);
- free(var);
- var = n;
- }
-}
-
-SWIGINTERN PyObject *
-swig_varlink_getattr(PyObject *o, char *n) {
- swig_varlinkobject *v = (swig_varlinkobject *) o;
- PyObject *res = NULL;
- swig_globalvar *var = v->vars;
- while (var) {
- if (strcmp(var->name,n) == 0) {
- res = (*var->get_attr)();
- break;
- }
- var = var->next;
- }
- if (res == NULL && !PyErr_Occurred()) {
- PyErr_Format(PyExc_AttributeError, "Unknown C global variable '%s'", n);
- }
- return res;
-}
-
-SWIGINTERN int
-swig_varlink_setattr(PyObject *o, char *n, PyObject *p) {
- swig_varlinkobject *v = (swig_varlinkobject *) o;
- int res = 1;
- swig_globalvar *var = v->vars;
- while (var) {
- if (strcmp(var->name,n) == 0) {
- res = (*var->set_attr)(p);
- break;
- }
- var = var->next;
- }
- if (res == 1 && !PyErr_Occurred()) {
- PyErr_Format(PyExc_AttributeError, "Unknown C global variable '%s'", n);
- }
- return res;
-}
-
-SWIGINTERN PyTypeObject*
-swig_varlink_type(void) {
- static char varlink__doc__[] = "Swig var link object";
- static PyTypeObject varlink_type;
- static int type_init = 0;
- if (!type_init) {
- const PyTypeObject tmp = {
-#if PY_VERSION_HEX >= 0x03000000
- PyVarObject_HEAD_INIT(NULL, 0)
-#else
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
-#endif
- "swigvarlink", /* tp_name */
- sizeof(swig_varlinkobject), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor) swig_varlink_dealloc, /* tp_dealloc */
-#if PY_VERSION_HEX < 0x030800b4
- (printfunc)0, /*tp_print*/
-#else
- (Py_ssize_t)0, /*tp_vectorcall_offset*/
-#endif
- (getattrfunc) swig_varlink_getattr, /* tp_getattr */
- (setattrfunc) swig_varlink_setattr, /* tp_setattr */
- 0, /* tp_compare */
- (reprfunc) swig_varlink_repr, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- (reprfunc) swig_varlink_str, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- 0, /* tp_flags */
- varlink__doc__, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */
- 0, /* tp_del */
- 0, /* tp_version_tag */
-#if PY_VERSION_HEX >= 0x03040000
- 0, /* tp_finalize */
-#endif
-#if PY_VERSION_HEX >= 0x03080000
- 0, /* tp_vectorcall */
-#endif
-#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000)
- 0, /* tp_print */
-#endif
-#ifdef COUNT_ALLOCS
- 0, /* tp_allocs */
- 0, /* tp_frees */
- 0, /* tp_maxalloc */
- 0, /* tp_prev */
- 0 /* tp_next */
-#endif
- };
- varlink_type = tmp;
- type_init = 1;
- if (PyType_Ready(&varlink_type) < 0)
- return NULL;
- }
- return &varlink_type;
-}
-
-/* Create a variable linking object for use later */
-SWIGINTERN PyObject *
-SWIG_Python_newvarlink(void) {
- swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type());
- if (result) {
- result->vars = 0;
- }
- return ((PyObject*) result);
-}
-
-SWIGINTERN void
-SWIG_Python_addvarlink(PyObject *p, const char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) {
- swig_varlinkobject *v = (swig_varlinkobject *) p;
- swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar));
- if (gv) {
- size_t size = strlen(name)+1;
- gv->name = (char *)malloc(size);
- if (gv->name) {
- memcpy(gv->name, name, size);
- gv->get_attr = get_attr;
- gv->set_attr = set_attr;
- gv->next = v->vars;
- }
- }
- v->vars = gv;
-}
-
-
-static PyObject *Swig_Globals_global = NULL;
-
-SWIGINTERN PyObject *
-SWIG_globals(void) {
- if (Swig_Globals_global == NULL) {
- Swig_Globals_global = SWIG_newvarlink();
- }
- return Swig_Globals_global;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-/* -----------------------------------------------------------------------------
- * Pointer declarations
- * ----------------------------------------------------------------------------- */
-
-/* Flags for new pointer objects */
-#define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1)
-#define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN)
-
-#define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1)
-
-#define SWIG_BUILTIN_TP_INIT (SWIG_POINTER_OWN << 2)
-#define SWIG_BUILTIN_INIT (SWIG_BUILTIN_TP_INIT | SWIG_POINTER_OWN)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* The python void return value */
-
-SWIGRUNTIMEINLINE PyObject *
-SWIG_Py_Void(void)
-{
- PyObject *none = Py_None;
- Py_INCREF(none);
- return none;
-}
-
-/* SwigPyClientData */
-
-typedef struct {
- PyObject *klass;
- PyObject *newraw;
- PyObject *newargs;
- PyObject *destroy;
- int delargs;
- int implicitconv;
- PyTypeObject *pytype;
-} SwigPyClientData;
-
-SWIGRUNTIMEINLINE int
-SWIG_Python_CheckImplicit(swig_type_info *ty)
-{
- SwigPyClientData *data = (SwigPyClientData *)ty->clientdata;
- int fail = data ? data->implicitconv : 0;
- if (fail)
- PyErr_SetString(PyExc_TypeError, "Implicit conversion is prohibited for explicit constructors.");
- return fail;
-}
-
-SWIGRUNTIMEINLINE PyObject *
-SWIG_Python_ExceptionType(swig_type_info *desc) {
- SwigPyClientData *data = desc ? (SwigPyClientData *) desc->clientdata : 0;
- PyObject *klass = data ? data->klass : 0;
- return (klass ? klass : PyExc_RuntimeError);
-}
-
-
-SWIGRUNTIME SwigPyClientData *
-SwigPyClientData_New(PyObject* obj)
-{
- if (!obj) {
- return 0;
- } else {
- SwigPyClientData *data = (SwigPyClientData *)malloc(sizeof(SwigPyClientData));
- /* the klass element */
- data->klass = obj;
- Py_INCREF(data->klass);
- /* the newraw method and newargs arguments used to create a new raw instance */
- if (PyClass_Check(obj)) {
- data->newraw = 0;
- Py_INCREF(obj);
- data->newargs = obj;
- } else {
- data->newraw = PyObject_GetAttrString(data->klass, "__new__");
- if (data->newraw) {
- data->newargs = PyTuple_New(1);
- if (data->newargs) {
- Py_INCREF(obj);
- PyTuple_SET_ITEM(data->newargs, 0, obj);
- } else {
- Py_DECREF(data->newraw);
- Py_DECREF(data->klass);
- free(data);
- return 0;
- }
- } else {
- Py_INCREF(obj);
- data->newargs = obj;
- }
- }
- /* the destroy method, aka as the C++ delete method */
- data->destroy = PyObject_GetAttrString(data->klass, "__swig_destroy__");
- if (PyErr_Occurred()) {
- PyErr_Clear();
- data->destroy = 0;
- }
- if (data->destroy) {
- data->delargs = !(PyCFunction_GET_FLAGS(data->destroy) & METH_O);
- } else {
- data->delargs = 0;
- }
- data->implicitconv = 0;
- data->pytype = 0;
- return data;
- }
-}
-
-SWIGRUNTIME void
-SwigPyClientData_Del(SwigPyClientData *data)
-{
- Py_XDECREF(data->klass);
- Py_XDECREF(data->newraw);
- Py_XDECREF(data->newargs);
- Py_XDECREF(data->destroy);
- free(data);
-}
-
-/* =============== SwigPyObject =====================*/
-
-typedef struct {
- PyObject_HEAD
- void *ptr;
- swig_type_info *ty;
- int own;
- PyObject *next;
-#ifdef SWIGPYTHON_BUILTIN
- PyObject *dict;
-#endif
-} SwigPyObject;
-
-
-#ifdef SWIGPYTHON_BUILTIN
-
-SWIGRUNTIME PyObject *
-SwigPyObject_get___dict__(PyObject *v, PyObject *SWIGUNUSEDPARM(args))
-{
- SwigPyObject *sobj = (SwigPyObject *)v;
-
- if (!sobj->dict)
- sobj->dict = PyDict_New();
-
- Py_XINCREF(sobj->dict);
- return sobj->dict;
-}
-
-#endif
-
-SWIGRUNTIME PyObject *
-SwigPyObject_long(SwigPyObject *v)
-{
- return PyLong_FromVoidPtr(v->ptr);
-}
-
-SWIGRUNTIME PyObject *
-SwigPyObject_format(const char* fmt, SwigPyObject *v)
-{
- PyObject *res = NULL;
- PyObject *args = PyTuple_New(1);
- if (args) {
- PyObject *val = SwigPyObject_long(v);
- if (val) {
- PyObject *ofmt;
- PyTuple_SET_ITEM(args, 0, val);
- ofmt = SWIG_Python_str_FromChar(fmt);
- if (ofmt) {
-#if PY_VERSION_HEX >= 0x03000000
- res = PyUnicode_Format(ofmt,args);
-#else
- res = PyString_Format(ofmt,args);
-#endif
- Py_DECREF(ofmt);
- }
- }
- Py_DECREF(args);
- }
- return res;
-}
-
-SWIGRUNTIME PyObject *
-SwigPyObject_oct(SwigPyObject *v)
-{
- return SwigPyObject_format("%o",v);
-}
-
-SWIGRUNTIME PyObject *
-SwigPyObject_hex(SwigPyObject *v)
-{
- return SwigPyObject_format("%x",v);
-}
-
-SWIGRUNTIME PyObject *
-SwigPyObject_repr(SwigPyObject *v)
-{
- const char *name = SWIG_TypePrettyName(v->ty);
- PyObject *repr = SWIG_Python_str_FromFormat("<Swig Object of type '%s' at %p>", (name ? name : "unknown"), (void *)v);
- if (repr && v->next) {
- PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next);
- if (nrep) {
-# if PY_VERSION_HEX >= 0x03000000
- PyObject *joined = PyUnicode_Concat(repr, nrep);
- Py_DecRef(repr);
- Py_DecRef(nrep);
- repr = joined;
-# else
- PyString_ConcatAndDel(&repr,nrep);
-# endif
- } else {
- Py_DecRef(repr);
- repr = NULL;
- }
- }
- return repr;
-}
-
-/* We need a version taking two PyObject* parameters so it's a valid
- * PyCFunction to use in swigobject_methods[]. */
-SWIGRUNTIME PyObject *
-SwigPyObject_repr2(PyObject *v, PyObject *SWIGUNUSEDPARM(args))
-{
- return SwigPyObject_repr((SwigPyObject*)v);
-}
-
-SWIGRUNTIME int
-SwigPyObject_compare(SwigPyObject *v, SwigPyObject *w)
-{
- void *i = v->ptr;
- void *j = w->ptr;
- return (i < j) ? -1 : ((i > j) ? 1 : 0);
-}
-
-/* Added for Python 3.x, would it also be useful for Python 2.x? */
-SWIGRUNTIME PyObject*
-SwigPyObject_richcompare(SwigPyObject *v, SwigPyObject *w, int op)
-{
- PyObject* res;
- if( op != Py_EQ && op != Py_NE ) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
- res = PyBool_FromLong( (SwigPyObject_compare(v, w)==0) == (op == Py_EQ) ? 1 : 0);
- return res;
-}
-
-
-SWIGRUNTIME PyTypeObject* SwigPyObject_TypeOnce(void);
-
-#ifdef SWIGPYTHON_BUILTIN
-static swig_type_info *SwigPyObject_stype = 0;
-SWIGRUNTIME PyTypeObject*
-SwigPyObject_type(void) {
- SwigPyClientData *cd;
- assert(SwigPyObject_stype);
- cd = (SwigPyClientData*) SwigPyObject_stype->clientdata;
- assert(cd);
- assert(cd->pytype);
- return cd->pytype;
-}
-#else
-SWIGRUNTIME PyTypeObject*
-SwigPyObject_type(void) {
- static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyObject_TypeOnce();
- return type;
-}
-#endif
-
-SWIGRUNTIMEINLINE int
-SwigPyObject_Check(PyObject *op) {
-#ifdef SWIGPYTHON_BUILTIN
- PyTypeObject *target_tp = SwigPyObject_type();
- if (PyType_IsSubtype(op->ob_type, target_tp))
- return 1;
- return (strcmp(op->ob_type->tp_name, "SwigPyObject") == 0);
-#else
- return (Py_TYPE(op) == SwigPyObject_type())
- || (strcmp(Py_TYPE(op)->tp_name,"SwigPyObject") == 0);
-#endif
-}
-
-SWIGRUNTIME PyObject *
-SwigPyObject_New(void *ptr, swig_type_info *ty, int own);
-
-static PyObject* Swig_Capsule_global = NULL;
-
-SWIGRUNTIME void
-SwigPyObject_dealloc(PyObject *v)
-{
- SwigPyObject *sobj = (SwigPyObject *) v;
- PyObject *next = sobj->next;
- if (sobj->own == SWIG_POINTER_OWN) {
- swig_type_info *ty = sobj->ty;
- SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0;
- PyObject *destroy = data ? data->destroy : 0;
- if (destroy) {
- /* destroy is always a VARARGS method */
- PyObject *res;
-
- /* PyObject_CallFunction() has the potential to silently drop
- the active exception. In cases of unnamed temporary
- variable or where we just finished iterating over a generator
- StopIteration will be active right now, and this needs to
- remain true upon return from SwigPyObject_dealloc. So save
- and restore. */
-
- PyObject *type = NULL, *value = NULL, *traceback = NULL;
- PyErr_Fetch(&type, &value, &traceback);
-
- if (data->delargs) {
- /* we need to create a temporary object to carry the destroy operation */
- PyObject *tmp = SwigPyObject_New(sobj->ptr, ty, 0);
- if (tmp) {
- res = SWIG_Python_CallFunctor(destroy, tmp);
- } else {
- res = 0;
- }
- Py_XDECREF(tmp);
- } else {
- PyCFunction meth = PyCFunction_GET_FUNCTION(destroy);
- PyObject *mself = PyCFunction_GET_SELF(destroy);
- res = ((*meth)(mself, v));
- }
- if (!res)
- PyErr_WriteUnraisable(destroy);
-
- PyErr_Restore(type, value, traceback);
-
- Py_XDECREF(res);
- }
-#if !defined(SWIG_PYTHON_SILENT_MEMLEAK)
- else {
- const char *name = SWIG_TypePrettyName(ty);
- printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown"));
- }
-#endif
- Py_XDECREF(Swig_Capsule_global);
- }
- Py_XDECREF(next);
-#ifdef SWIGPYTHON_BUILTIN
- Py_XDECREF(sobj->dict);
-#endif
- PyObject_DEL(v);
-}
-
-SWIGRUNTIME PyObject*
-SwigPyObject_append(PyObject* v, PyObject* next)
-{
- SwigPyObject *sobj = (SwigPyObject *) v;
- if (!SwigPyObject_Check(next)) {
- PyErr_SetString(PyExc_TypeError, "Attempt to append a non SwigPyObject");
- return NULL;
- }
- ((SwigPyObject *)next)->next = sobj->next;
- sobj->next = next;
- Py_INCREF(next);
- return SWIG_Py_Void();
-}
-
-SWIGRUNTIME PyObject*
-SwigPyObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
-{
- SwigPyObject *sobj = (SwigPyObject *) v;
- if (sobj->next) {
- Py_INCREF(sobj->next);
- return sobj->next;
- } else {
- return SWIG_Py_Void();
- }
-}
-
-SWIGINTERN PyObject*
-SwigPyObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
-{
- SwigPyObject *sobj = (SwigPyObject *)v;
- sobj->own = 0;
- return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject*
-SwigPyObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
-{
- SwigPyObject *sobj = (SwigPyObject *)v;
- sobj->own = SWIG_POINTER_OWN;
- return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject*
-SwigPyObject_own(PyObject *v, PyObject *args)
-{
- PyObject *val = 0;
- if (!PyArg_UnpackTuple(args, "own", 0, 1, &val)) {
- return NULL;
- } else {
- SwigPyObject *sobj = (SwigPyObject *)v;
- PyObject *obj = PyBool_FromLong(sobj->own);
- if (val) {
- if (PyObject_IsTrue(val)) {
- Py_DECREF(SwigPyObject_acquire(v,args));
- } else {
- Py_DECREF(SwigPyObject_disown(v,args));
- }
- }
- return obj;
- }
-}
-
-static PyMethodDef
-swigobject_methods[] = {
- {"disown", SwigPyObject_disown, METH_NOARGS, "releases ownership of the pointer"},
- {"acquire", SwigPyObject_acquire, METH_NOARGS, "acquires ownership of the pointer"},
- {"own", SwigPyObject_own, METH_VARARGS, "returns/sets ownership of the pointer"},
- {"append", SwigPyObject_append, METH_O, "appends another 'this' object"},
- {"next", SwigPyObject_next, METH_NOARGS, "returns the next 'this' object"},
- {"__repr__",SwigPyObject_repr2, METH_NOARGS, "returns object representation"},
- {0, 0, 0, 0}
-};
-
-SWIGRUNTIME PyTypeObject*
-SwigPyObject_TypeOnce(void) {
- static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer";
-
- static PyNumberMethods SwigPyObject_as_number = {
- (binaryfunc)0, /*nb_add*/
- (binaryfunc)0, /*nb_subtract*/
- (binaryfunc)0, /*nb_multiply*/
- /* nb_divide removed in Python 3 */
-#if PY_VERSION_HEX < 0x03000000
- (binaryfunc)0, /*nb_divide*/
-#endif
- (binaryfunc)0, /*nb_remainder*/
- (binaryfunc)0, /*nb_divmod*/
- (ternaryfunc)0,/*nb_power*/
- (unaryfunc)0, /*nb_negative*/
- (unaryfunc)0, /*nb_positive*/
- (unaryfunc)0, /*nb_absolute*/
- (inquiry)0, /*nb_nonzero*/
- 0, /*nb_invert*/
- 0, /*nb_lshift*/
- 0, /*nb_rshift*/
- 0, /*nb_and*/
- 0, /*nb_xor*/
- 0, /*nb_or*/
-#if PY_VERSION_HEX < 0x03000000
- 0, /*nb_coerce*/
-#endif
- (unaryfunc)SwigPyObject_long, /*nb_int*/
-#if PY_VERSION_HEX < 0x03000000
- (unaryfunc)SwigPyObject_long, /*nb_long*/
-#else
- 0, /*nb_reserved*/
-#endif
- (unaryfunc)0, /*nb_float*/
-#if PY_VERSION_HEX < 0x03000000
- (unaryfunc)SwigPyObject_oct, /*nb_oct*/
- (unaryfunc)SwigPyObject_hex, /*nb_hex*/
-#endif
-#if PY_VERSION_HEX >= 0x03050000 /* 3.5 */
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_matrix_multiply */
-#elif PY_VERSION_HEX >= 0x03000000 /* 3.0 */
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index, nb_inplace_divide removed */
-#else
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */
-#endif
- };
-
- static PyTypeObject swigpyobject_type;
- static int type_init = 0;
- if (!type_init) {
- const PyTypeObject tmp = {
-#if PY_VERSION_HEX >= 0x03000000
- PyVarObject_HEAD_INIT(NULL, 0)
-#else
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
-#endif
- "SwigPyObject", /* tp_name */
- sizeof(SwigPyObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)SwigPyObject_dealloc, /* tp_dealloc */
-#if PY_VERSION_HEX < 0x030800b4
- (printfunc)0, /*tp_print*/
-#else
- (Py_ssize_t)0, /*tp_vectorcall_offset*/
-#endif
- (getattrfunc)0, /* tp_getattr */
- (setattrfunc)0, /* tp_setattr */
-#if PY_VERSION_HEX >= 0x03000000
- 0, /* tp_reserved in 3.0.1, tp_compare in 3.0.0 but not used */
-#else
- (cmpfunc)SwigPyObject_compare, /* tp_compare */
-#endif
- (reprfunc)SwigPyObject_repr, /* tp_repr */
- &SwigPyObject_as_number, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- (hashfunc)0, /* tp_hash */
- (ternaryfunc)0, /* tp_call */
- 0, /* tp_str */
- PyObject_GenericGetAttr, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- swigobject_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- (richcmpfunc)SwigPyObject_richcompare,/* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- swigobject_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- 0, /* tp_new */
- 0, /* tp_free */
- 0, /* tp_is_gc */
- 0, /* tp_bases */
- 0, /* tp_mro */
- 0, /* tp_cache */
- 0, /* tp_subclasses */
- 0, /* tp_weaklist */
- 0, /* tp_del */
- 0, /* tp_version_tag */
-#if PY_VERSION_HEX >= 0x03040000
- 0, /* tp_finalize */
-#endif
-#if PY_VERSION_HEX >= 0x03080000
- 0, /* tp_vectorcall */
-#endif
-#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000)
- 0, /* tp_print */
-#endif
-#ifdef COUNT_ALLOCS
- 0, /* tp_allocs */
- 0, /* tp_frees */
- 0, /* tp_maxalloc */
- 0, /* tp_prev */
- 0 /* tp_next */
-#endif
- };
- swigpyobject_type = tmp;
- type_init = 1;
- if (PyType_Ready(&swigpyobject_type) != 0)
- return NULL;
- }
- return &swigpyobject_type;
-}
-
-SWIGRUNTIME PyObject *
-SwigPyObject_New(void *ptr, swig_type_info *ty, int own)
-{
- SwigPyObject *sobj = PyObject_NEW(SwigPyObject, SwigPyObject_type());
- if (sobj) {
- sobj->ptr = ptr;
- sobj->ty = ty;
- sobj->own = own;
- sobj->next = 0;
-#ifdef SWIGPYTHON_BUILTIN
- sobj->dict = 0;
-#endif
- if (own == SWIG_POINTER_OWN) {
- /* Obtain a reference to the Python capsule wrapping the module information, so that the
- * module information is correctly destroyed after all SWIG python objects have been freed
- * by the GC (and corresponding destructors invoked) */
- Py_XINCREF(Swig_Capsule_global);
- }
- }
- return (PyObject *)sobj;
-}
-
-/* -----------------------------------------------------------------------------
- * Implements a simple Swig Packed type, and use it instead of string
- * ----------------------------------------------------------------------------- */
-
-typedef struct {
- PyObject_HEAD
- void *pack;
- swig_type_info *ty;
- size_t size;
-} SwigPyPacked;
-
-SWIGRUNTIME PyObject *
-SwigPyPacked_repr(SwigPyPacked *v)
-{
- char result[SWIG_BUFFER_SIZE];
- if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
- return SWIG_Python_str_FromFormat("<Swig Packed at %s%s>", result, v->ty->name);
- } else {
- return SWIG_Python_str_FromFormat("<Swig Packed %s>", v->ty->name);
- }
-}
-
-SWIGRUNTIME PyObject *
-SwigPyPacked_str(SwigPyPacked *v)
-{
- char result[SWIG_BUFFER_SIZE];
- if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){
- return SWIG_Python_str_FromFormat("%s%s", result, v->ty->name);
- } else {
- return SWIG_Python_str_FromChar(v->ty->name);
- }
-}
-
-SWIGRUNTIME int
-SwigPyPacked_compare(SwigPyPacked *v, SwigPyPacked *w)
-{
- size_t i = v->size;
- size_t j = w->size;
- int s = (i < j) ? -1 : ((i > j) ? 1 : 0);
- return s ? s : strncmp((const char *)v->pack, (const char *)w->pack, 2*v->size);
-}
-
-SWIGRUNTIME PyTypeObject* SwigPyPacked_TypeOnce(void);
-
-SWIGRUNTIME PyTypeObject*
-SwigPyPacked_type(void) {
- static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyPacked_TypeOnce();
- return type;
-}
-
-SWIGRUNTIMEINLINE int
-SwigPyPacked_Check(PyObject *op) {
- return ((op)->ob_type == SwigPyPacked_TypeOnce())
- || (strcmp((op)->ob_type->tp_name,"SwigPyPacked") == 0);
-}
-
-SWIGRUNTIME void
-SwigPyPacked_dealloc(PyObject *v)
-{
- if (SwigPyPacked_Check(v)) {
- SwigPyPacked *sobj = (SwigPyPacked *) v;
- free(sobj->pack);
- }
- PyObject_DEL(v);
-}
-
-SWIGRUNTIME PyTypeObject*
-SwigPyPacked_TypeOnce(void) {
- static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer";
- static PyTypeObject swigpypacked_type;
- static int type_init = 0;
- if (!type_init) {
- const PyTypeObject tmp = {
-#if PY_VERSION_HEX>=0x03000000
- PyVarObject_HEAD_INIT(NULL, 0)
-#else
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
-#endif
- "SwigPyPacked", /* tp_name */
- sizeof(SwigPyPacked), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)SwigPyPacked_dealloc, /* tp_dealloc */
-#if PY_VERSION_HEX < 0x030800b4
- (printfunc)0, /*tp_print*/
-#else
- (Py_ssize_t)0, /*tp_vectorcall_offset*/
-#endif
- (getattrfunc)0, /* tp_getattr */
- (setattrfunc)0, /* tp_setattr */
-#if PY_VERSION_HEX>=0x03000000
- 0, /* tp_reserved in 3.0.1 */
-#else
- (cmpfunc)SwigPyPacked_compare, /* tp_compare */
-#endif
- (reprfunc)SwigPyPacked_repr, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- (hashfunc)0, /* tp_hash */
- (ternaryfunc)0, /* tp_call */
- (reprfunc)SwigPyPacked_str, /* tp_str */
- PyObject_GenericGetAttr, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- swigpacked_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- 0, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- 0, /* tp_new */
- 0, /* tp_free */
- 0, /* tp_is_gc */
- 0, /* tp_bases */
- 0, /* tp_mro */
- 0, /* tp_cache */
- 0, /* tp_subclasses */
- 0, /* tp_weaklist */
- 0, /* tp_del */
- 0, /* tp_version_tag */
-#if PY_VERSION_HEX >= 0x03040000
- 0, /* tp_finalize */
-#endif
-#if PY_VERSION_HEX >= 0x03080000
- 0, /* tp_vectorcall */
-#endif
-#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000)
- 0, /* tp_print */
-#endif
-#ifdef COUNT_ALLOCS
- 0, /* tp_allocs */
- 0, /* tp_frees */
- 0, /* tp_maxalloc */
- 0, /* tp_prev */
- 0 /* tp_next */
-#endif
- };
- swigpypacked_type = tmp;
- type_init = 1;
- if (PyType_Ready(&swigpypacked_type) != 0)
- return NULL;
- }
- return &swigpypacked_type;
-}
-
-SWIGRUNTIME PyObject *
-SwigPyPacked_New(void *ptr, size_t size, swig_type_info *ty)
-{
- SwigPyPacked *sobj = PyObject_NEW(SwigPyPacked, SwigPyPacked_type());
- if (sobj) {
- void *pack = malloc(size);
- if (pack) {
- memcpy(pack, ptr, size);
- sobj->pack = pack;
- sobj->ty = ty;
- sobj->size = size;
- } else {
- PyObject_DEL((PyObject *) sobj);
- sobj = 0;
- }
- }
- return (PyObject *) sobj;
-}
-
-SWIGRUNTIME swig_type_info *
-SwigPyPacked_UnpackData(PyObject *obj, void *ptr, size_t size)
-{
- if (SwigPyPacked_Check(obj)) {
- SwigPyPacked *sobj = (SwigPyPacked *)obj;
- if (sobj->size != size) return 0;
- memcpy(ptr, sobj->pack, size);
- return sobj->ty;
- } else {
- return 0;
- }
-}
-
-/* -----------------------------------------------------------------------------
- * pointers/data manipulation
- * ----------------------------------------------------------------------------- */
-
-static PyObject *Swig_This_global = NULL;
-
-SWIGRUNTIME PyObject *
-SWIG_This(void)
-{
- if (Swig_This_global == NULL)
- Swig_This_global = SWIG_Python_str_FromChar("this");
- return Swig_This_global;
-}
-
-/* #define SWIG_PYTHON_SLOW_GETSET_THIS */
-
-/* TODO: I don't know how to implement the fast getset in Python 3 right now */
-#if PY_VERSION_HEX>=0x03000000
-#define SWIG_PYTHON_SLOW_GETSET_THIS
-#endif
-
-SWIGRUNTIME SwigPyObject *
-SWIG_Python_GetSwigThis(PyObject *pyobj)
-{
- PyObject *obj;
-
- if (SwigPyObject_Check(pyobj))
- return (SwigPyObject *) pyobj;
-
-#ifdef SWIGPYTHON_BUILTIN
- (void)obj;
-# ifdef PyWeakref_CheckProxy
- if (PyWeakref_CheckProxy(pyobj)) {
- pyobj = PyWeakref_GET_OBJECT(pyobj);
- if (pyobj && SwigPyObject_Check(pyobj))
- return (SwigPyObject*) pyobj;
- }
-# endif
- return NULL;
-#else
-
- obj = 0;
-
-#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
- if (PyInstance_Check(pyobj)) {
- obj = _PyInstance_Lookup(pyobj, SWIG_This());
- } else {
- PyObject **dictptr = _PyObject_GetDictPtr(pyobj);
- if (dictptr != NULL) {
- PyObject *dict = *dictptr;
- obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0;
- } else {
-#ifdef PyWeakref_CheckProxy
- if (PyWeakref_CheckProxy(pyobj)) {
- PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
- return wobj ? SWIG_Python_GetSwigThis(wobj) : 0;
- }
-#endif
- obj = PyObject_GetAttr(pyobj,SWIG_This());
- if (obj) {
- Py_DECREF(obj);
- } else {
- if (PyErr_Occurred()) PyErr_Clear();
- return 0;
- }
- }
- }
-#else
- obj = PyObject_GetAttr(pyobj,SWIG_This());
- if (obj) {
- Py_DECREF(obj);
- } else {
- if (PyErr_Occurred()) PyErr_Clear();
- return 0;
- }
-#endif
- if (obj && !SwigPyObject_Check(obj)) {
- /* a PyObject is called 'this', try to get the 'real this'
- SwigPyObject from it */
- return SWIG_Python_GetSwigThis(obj);
- }
- return (SwigPyObject *)obj;
-#endif
-}
-
-/* Acquire a pointer value */
-
-SWIGRUNTIME int
-SWIG_Python_AcquirePtr(PyObject *obj, int own) {
- if (own == SWIG_POINTER_OWN) {
- SwigPyObject *sobj = SWIG_Python_GetSwigThis(obj);
- if (sobj) {
- int oldown = sobj->own;
- sobj->own = own;
- return oldown;
- }
- }
- return 0;
-}
-
-/* Convert a pointer value */
-
-SWIGRUNTIME int
-SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) {
- int res;
- SwigPyObject *sobj;
- int implicit_conv = (flags & SWIG_POINTER_IMPLICIT_CONV) != 0;
-
- if (!obj)
- return SWIG_ERROR;
- if (obj == Py_None && !implicit_conv) {
- if (ptr)
- *ptr = 0;
- return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
- }
-
- res = SWIG_ERROR;
-
- sobj = SWIG_Python_GetSwigThis(obj);
- if (own)
- *own = 0;
- while (sobj) {
- void *vptr = sobj->ptr;
- if (ty) {
- swig_type_info *to = sobj->ty;
- if (to == ty) {
- /* no type cast needed */
- if (ptr) *ptr = vptr;
- break;
- } else {
- swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
- if (!tc) {
- sobj = (SwigPyObject *)sobj->next;
- } else {
- if (ptr) {
- int newmemory = 0;
- *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
- if (newmemory == SWIG_CAST_NEW_MEMORY) {
- assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */
- if (own)
- *own = *own | SWIG_CAST_NEW_MEMORY;
- }
- }
- break;
- }
- }
- } else {
- if (ptr) *ptr = vptr;
- break;
- }
- }
- if (sobj) {
- if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !sobj->own) {
- res = SWIG_ERROR_RELEASE_NOT_OWNED;
- } else {
- if (own)
- *own = *own | sobj->own;
- if (flags & SWIG_POINTER_DISOWN) {
- sobj->own = 0;
- }
- if (flags & SWIG_POINTER_CLEAR) {
- sobj->ptr = 0;
- }
- res = SWIG_OK;
- }
- } else {
- if (implicit_conv) {
- SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0;
- if (data && !data->implicitconv) {
- PyObject *klass = data->klass;
- if (klass) {
- PyObject *impconv;
- data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/
- impconv = SWIG_Python_CallFunctor(klass, obj);
- data->implicitconv = 0;
- if (PyErr_Occurred()) {
- PyErr_Clear();
- impconv = 0;
- }
- if (impconv) {
- SwigPyObject *iobj = SWIG_Python_GetSwigThis(impconv);
- if (iobj) {
- void *vptr;
- res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0);
- if (SWIG_IsOK(res)) {
- if (ptr) {
- *ptr = vptr;
- /* transfer the ownership to 'ptr' */
- iobj->own = 0;
- res = SWIG_AddCast(res);
- res = SWIG_AddNewMask(res);
- } else {
- res = SWIG_AddCast(res);
- }
- }
- }
- Py_DECREF(impconv);
- }
- }
- }
- if (!SWIG_IsOK(res) && obj == Py_None) {
- if (ptr)
- *ptr = 0;
- if (PyErr_Occurred())
- PyErr_Clear();
- res = SWIG_OK;
- }
- }
- }
- return res;
-}
-
-/* Convert a function ptr value */
-
-SWIGRUNTIME int
-SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) {
- if (!PyCFunction_Check(obj)) {
- return SWIG_ConvertPtr(obj, ptr, ty, 0);
- } else {
- void *vptr = 0;
- swig_cast_info *tc;
-
- /* here we get the method pointer for callbacks */
- const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc);
- const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0;
- if (desc)
- desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0;
- if (!desc)
- return SWIG_ERROR;
- tc = SWIG_TypeCheck(desc,ty);
- if (tc) {
- int newmemory = 0;
- *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
- assert(!newmemory); /* newmemory handling not yet implemented */
- } else {
- return SWIG_ERROR;
- }
- return SWIG_OK;
- }
-}
-
-/* Convert a packed pointer value */
-
-SWIGRUNTIME int
-SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) {
- swig_type_info *to = SwigPyPacked_UnpackData(obj, ptr, sz);
- if (!to) return SWIG_ERROR;
- if (ty) {
- if (to != ty) {
- /* check type cast? */
- swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
- if (!tc) return SWIG_ERROR;
- }
- }
- return SWIG_OK;
-}
-
-/* -----------------------------------------------------------------------------
- * Create a new pointer object
- * ----------------------------------------------------------------------------- */
-
-/*
- Create a new instance object, without calling __init__, and set the
- 'this' attribute.
-*/
-
-SWIGRUNTIME PyObject*
-SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this)
-{
- PyObject *inst = 0;
- PyObject *newraw = data->newraw;
- if (newraw) {
- inst = PyObject_Call(newraw, data->newargs, NULL);
- if (inst) {
-#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
- PyObject **dictptr = _PyObject_GetDictPtr(inst);
- if (dictptr != NULL) {
- PyObject *dict = *dictptr;
- if (dict == NULL) {
- dict = PyDict_New();
- *dictptr = dict;
- }
- if (dict) {
- PyDict_SetItem(dict, SWIG_This(), swig_this);
- } else{
- Py_DECREF(inst);
- inst = 0;
- }
- }
-#else
- if (PyObject_SetAttr(inst, SWIG_This(), swig_this) == -1) {
- Py_DECREF(inst);
- inst = 0;
- }
-#endif
- }
- } else {
-#if PY_VERSION_HEX >= 0x03000000
- PyObject *empty_args = PyTuple_New(0);
- if (empty_args) {
- PyObject *empty_kwargs = PyDict_New();
- if (empty_kwargs) {
- inst = ((PyTypeObject *)data->newargs)->tp_new((PyTypeObject *)data->newargs, empty_args, empty_kwargs);
- Py_DECREF(empty_kwargs);
- if (inst) {
- if (PyObject_SetAttr(inst, SWIG_This(), swig_this) == -1) {
- Py_DECREF(inst);
- inst = 0;
- } else {
- PyType_Modified(Py_TYPE(inst));
- }
- }
- }
- Py_DECREF(empty_args);
- }
-#else
- PyObject *dict = PyDict_New();
- if (dict) {
- PyDict_SetItem(dict, SWIG_This(), swig_this);
- inst = PyInstance_NewRaw(data->newargs, dict);
- Py_DECREF(dict);
- }
-#endif
- }
- return inst;
-}
-
-SWIGRUNTIME int
-SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this)
-{
-#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
- PyObject **dictptr = _PyObject_GetDictPtr(inst);
- if (dictptr != NULL) {
- PyObject *dict = *dictptr;
- if (dict == NULL) {
- dict = PyDict_New();
- *dictptr = dict;
- }
- if (dict) {
- return PyDict_SetItem(dict, SWIG_This(), swig_this);
- } else{
- return -1;
- }
- }
-#endif
- return PyObject_SetAttr(inst, SWIG_This(), swig_this);
-}
-
-
-SWIGINTERN PyObject *
-SWIG_Python_InitShadowInstance(PyObject *args) {
- PyObject *obj[2];
- if (!SWIG_Python_UnpackTuple(args, "swiginit", 2, 2, obj)) {
- return NULL;
- } else {
- SwigPyObject *sthis = SWIG_Python_GetSwigThis(obj[0]);
- if (sthis) {
- Py_DECREF(SwigPyObject_append((PyObject*) sthis, obj[1]));
- } else {
- if (SWIG_Python_SetSwigThis(obj[0], obj[1]) != 0)
- return NULL;
- }
- return SWIG_Py_Void();
- }
-}
-
-/* Create a new pointer object */
-
-SWIGRUNTIME PyObject *
-SWIG_Python_NewPointerObj(PyObject *self, void *ptr, swig_type_info *type, int flags) {
- SwigPyClientData *clientdata;
- PyObject * robj;
- int own;
-
- if (!ptr)
- return SWIG_Py_Void();
-
- clientdata = type ? (SwigPyClientData *)(type->clientdata) : 0;
- own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0;
- if (clientdata && clientdata->pytype) {
- SwigPyObject *newobj;
- if (flags & SWIG_BUILTIN_TP_INIT) {
- newobj = (SwigPyObject*) self;
- if (newobj->ptr) {
- PyObject *next_self = clientdata->pytype->tp_alloc(clientdata->pytype, 0);
- while (newobj->next)
- newobj = (SwigPyObject *) newobj->next;
- newobj->next = next_self;
- newobj = (SwigPyObject *)next_self;
-#ifdef SWIGPYTHON_BUILTIN
- newobj->dict = 0;
-#endif
- }
- } else {
- newobj = PyObject_New(SwigPyObject, clientdata->pytype);
-#ifdef SWIGPYTHON_BUILTIN
- if (newobj) {
- newobj->dict = 0;
- }
-#endif
- }
- if (newobj) {
- newobj->ptr = ptr;
- newobj->ty = type;
- newobj->own = own;
- newobj->next = 0;
- return (PyObject*) newobj;
- }
- return SWIG_Py_Void();
- }
-
- assert(!(flags & SWIG_BUILTIN_TP_INIT));
-
- robj = SwigPyObject_New(ptr, type, own);
- if (robj && clientdata && !(flags & SWIG_POINTER_NOSHADOW)) {
- PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj);
- Py_DECREF(robj);
- robj = inst;
- }
- return robj;
-}
-
-/* Create a new packed object */
-
-SWIGRUNTIMEINLINE PyObject *
-SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) {
- return ptr ? SwigPyPacked_New((void *) ptr, sz, type) : SWIG_Py_Void();
-}
-
-/* -----------------------------------------------------------------------------*
- * Get type list
- * -----------------------------------------------------------------------------*/
-
-#ifdef SWIG_LINK_RUNTIME
-void *SWIG_ReturnGlobalTypeList(void *);
-#endif
-
-static PyObject *Swig_TypeCache_global = NULL;
-
-/* The python cached type query */
-SWIGRUNTIME PyObject *
-SWIG_Python_TypeCache(void) {
- if (Swig_TypeCache_global == NULL) {
- Swig_TypeCache_global = PyDict_New();
- }
- return Swig_TypeCache_global;
-}
-
-SWIGRUNTIME swig_module_info *
-SWIG_Python_GetModule(void *SWIGUNUSEDPARM(clientdata)) {
-#ifdef SWIG_LINK_RUNTIME
- static void *type_pointer = (void *)0;
- /* first check if module already created */
- if (!type_pointer) {
- type_pointer = SWIG_ReturnGlobalTypeList((void *)0);
- }
-#else
- void *type_pointer = PyCapsule_Import(SWIGPY_CAPSULE_NAME, 0);
- if (PyErr_Occurred()) {
- PyErr_Clear();
- type_pointer = (void *)0;
- }
-#endif
- return (swig_module_info *) type_pointer;
-}
-
-
-static int interpreter_counter = 0; // how many (sub-)interpreters are using swig_module's types
-
-SWIGRUNTIME void
-SWIG_Python_DestroyModule(PyObject *obj)
-{
- swig_module_info *swig_module = (swig_module_info *) PyCapsule_GetPointer(obj, SWIGPY_CAPSULE_NAME);
- swig_type_info **types = swig_module->types;
- size_t i;
- if (--interpreter_counter != 0) // another sub-interpreter may still be using the swig_module's types
- return;
- for (i =0; i < swig_module->size; ++i) {
- swig_type_info *ty = types[i];
- if (ty->owndata) {
- SwigPyClientData *data = (SwigPyClientData *) ty->clientdata;
- ty->clientdata = 0;
- if (data) SwigPyClientData_Del(data);
- }
- }
- Py_DECREF(SWIG_This());
- Swig_This_global = NULL;
- Py_DECREF(SWIG_globals());
- Swig_Globals_global = NULL;
- Py_DECREF(SWIG_Python_TypeCache());
- Swig_TypeCache_global = NULL;
- Swig_Capsule_global = NULL;
-}
-
-SWIGRUNTIME void
-SWIG_Python_SetModule(swig_module_info *swig_module) {
-#if PY_VERSION_HEX >= 0x03000000
- /* Add a dummy module object into sys.modules */
- PyObject *module = PyImport_AddModule("swig_runtime_data" SWIG_RUNTIME_VERSION);
-#else
- static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} }; /* Sentinel */
- PyObject *module = Py_InitModule("swig_runtime_data" SWIG_RUNTIME_VERSION, swig_empty_runtime_method_table);
-#endif
- PyObject *pointer = PyCapsule_New((void *) swig_module, SWIGPY_CAPSULE_NAME, SWIG_Python_DestroyModule);
- if (pointer && module) {
- if (PyModule_AddObject(module, SWIGPY_CAPSULE_ATTR_NAME, pointer) == 0) {
- ++interpreter_counter;
- Swig_Capsule_global = pointer;
- } else {
- Py_DECREF(pointer);
- }
- } else {
- Py_XDECREF(pointer);
- }
-}
-
-SWIGRUNTIME swig_type_info *
-SWIG_Python_TypeQuery(const char *type)
-{
- PyObject *cache = SWIG_Python_TypeCache();
- PyObject *key = SWIG_Python_str_FromChar(type);
- PyObject *obj = PyDict_GetItem(cache, key);
- swig_type_info *descriptor;
- if (obj) {
- descriptor = (swig_type_info *) PyCapsule_GetPointer(obj, NULL);
- } else {
- swig_module_info *swig_module = SWIG_GetModule(0);
- descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type);
- if (descriptor) {
- obj = PyCapsule_New((void*) descriptor, NULL, NULL);
- if (obj) {
- PyDict_SetItem(cache, key, obj);
- Py_DECREF(obj);
- }
- }
- }
- Py_DECREF(key);
- return descriptor;
-}
-
-/*
- For backward compatibility only
-*/
-#define SWIG_POINTER_EXCEPTION 0
-#define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg)
-#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags)
-
-SWIGRUNTIME int
-SWIG_Python_AddErrMesg(const char* mesg, int infront)
-{
- if (PyErr_Occurred()) {
- PyObject *type = 0;
- PyObject *value = 0;
- PyObject *traceback = 0;
- PyErr_Fetch(&type, &value, &traceback);
- if (value) {
- PyObject *old_str = PyObject_Str(value);
- const char *tmp = SWIG_Python_str_AsChar(old_str);
- const char *errmesg = tmp ? tmp : "Invalid error message";
- Py_XINCREF(type);
- PyErr_Clear();
- if (infront) {
- PyErr_Format(type, "%s %s", mesg, errmesg);
- } else {
- PyErr_Format(type, "%s %s", errmesg, mesg);
- }
- Py_DECREF(old_str);
- }
- return 1;
- } else {
- return 0;
- }
-}
-
-SWIGRUNTIME int
-SWIG_Python_ArgFail(int argnum)
-{
- if (PyErr_Occurred()) {
- /* add information about failing argument */
- char mesg[256];
- PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum);
- return SWIG_Python_AddErrMesg(mesg, 1);
- } else {
- return 0;
- }
-}
-
-SWIGRUNTIMEINLINE const char *
-SwigPyObject_GetDesc(PyObject *self)
-{
- SwigPyObject *v = (SwigPyObject *)self;
- swig_type_info *ty = v ? v->ty : 0;
- return ty ? ty->str : "";
-}
-
-SWIGRUNTIME void
-SWIG_Python_TypeError(const char *type, PyObject *obj)
-{
- if (type) {
-#if defined(SWIG_COBJECT_TYPES)
- if (obj && SwigPyObject_Check(obj)) {
- const char *otype = (const char *) SwigPyObject_GetDesc(obj);
- if (otype) {
- PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'SwigPyObject(%s)' is received",
- type, otype);
- return;
- }
- } else
-#endif
- {
- const char *otype = (obj ? obj->ob_type->tp_name : 0);
- if (otype) {
- PyObject *str = PyObject_Str(obj);
- const char *cstr = str ? SWIG_Python_str_AsChar(str) : 0;
- if (cstr) {
- PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received",
- type, otype, cstr);
- } else {
- PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received",
- type, otype);
- }
- Py_XDECREF(str);
- return;
- }
- }
- PyErr_Format(PyExc_TypeError, "a '%s' is expected", type);
- } else {
- PyErr_Format(PyExc_TypeError, "unexpected type is received");
- }
-}
-
-
-/* Convert a pointer value, signal an exception on a type mismatch */
-SWIGRUNTIME void *
-SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int SWIGUNUSEDPARM(argnum), int flags) {
- void *result;
- if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) {
- PyErr_Clear();
- }
- return result;
-}
-
-#ifdef SWIGPYTHON_BUILTIN
-SWIGRUNTIME int
-SWIG_Python_NonDynamicSetAttr(PyObject *obj, PyObject *name, PyObject *value) {
- PyTypeObject *tp = obj->ob_type;
- PyObject *descr;
- PyObject *encoded_name;
- descrsetfunc f;
- int res = -1;
-
-# ifdef Py_USING_UNICODE
- if (PyString_Check(name)) {
- name = PyUnicode_Decode(PyString_AsString(name), PyString_Size(name), NULL, NULL);
- if (!name)
- return -1;
- } else if (!PyUnicode_Check(name))
-# else
- if (!PyString_Check(name))
-# endif
- {
- PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", name->ob_type->tp_name);
- return -1;
- } else {
- Py_INCREF(name);
- }
-
- if (!tp->tp_dict) {
- if (PyType_Ready(tp) != 0)
- goto done;
- }
-
- descr = _PyType_Lookup(tp, name);
- f = NULL;
- if (descr != NULL)
- f = descr->ob_type->tp_descr_set;
- if (!f) {
- if (PyString_Check(name)) {
- encoded_name = name;
- Py_INCREF(name);
- } else {
- encoded_name = PyUnicode_AsUTF8String(name);
- if (!encoded_name)
- goto done;
- }
- PyErr_Format(PyExc_AttributeError, "'%.100s' object has no attribute '%.200s'", tp->tp_name, PyString_AsString(encoded_name));
- Py_DECREF(encoded_name);
- } else {
- res = f(descr, obj, value);
- }
-
- done:
- Py_DECREF(name);
- return res;
-}
-#endif
-
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/contrib/tools/swig/Lib/python/pyruntime.swg b/contrib/tools/swig/Lib/python/pyruntime.swg
deleted file mode 100644
index 1d028adaf0..0000000000
--- a/contrib/tools/swig/Lib/python/pyruntime.swg
+++ /dev/null
@@ -1,49 +0,0 @@
-%insert(runtime) %{
-#if defined(__GNUC__) && defined(_WIN32) && !defined(SWIG_PYTHON_NO_HYPOT_WORKAROUND)
-/* Workaround for '::hypot' has not been declared', see https://bugs.python.org/issue11566 */
-# include <math.h>
-#endif
-
-#if !defined(PY_SSIZE_T_CLEAN) && !defined(SWIG_NO_PY_SSIZE_T_CLEAN)
-#define PY_SSIZE_T_CLEAN
-#endif
-
-#if __GNUC__ >= 7
-#pragma GCC diagnostic push
-#if defined(__cplusplus) && __cplusplus >=201703L
-#pragma GCC diagnostic ignored "-Wregister" /* For python-2.7 headers that use register */
-#endif
-#endif
-
-#if defined(_DEBUG) && defined(SWIG_PYTHON_INTERPRETER_NO_DEBUG)
-/* Use debug wrappers with the Python release dll */
-
-#if defined(_MSC_VER) && _MSC_VER >= 1929
-/* Workaround compilation errors when redefining _DEBUG in MSVC 2019 version 16.10 and later
- * See https://github.com/swig/swig/issues/2090 */
-# include <corecrt.h>
-#endif
-
-# undef _DEBUG
-# include <Python.h>
-# define _DEBUG 1
-#else
-# include <Python.h>
-#endif
-
-#if __GNUC__ >= 7
-#pragma GCC diagnostic pop
-#endif
-%}
-
-%insert(runtime) "swigrun.swg"; /* SWIG API */
-%insert(runtime) "swigerrors.swg"; /* SWIG errors */
-%insert(runtime) "pyhead.swg"; /* Python includes and fixes */
-%insert(runtime) "pyerrors.swg"; /* Python errors */
-%insert(runtime) "pythreads.swg"; /* Python thread code */
-%insert(runtime) "pyapi.swg"; /* Python API */
-%insert(runtime) "pyrun.swg"; /* Python run-time code */
-
-#if defined(SWIGPYTHON_BUILTIN)
-%insert(runtime) "builtin.swg"; /* Specialization for classes with single inheritance */
-#endif
diff --git a/contrib/tools/swig/Lib/python/pystrings.swg b/contrib/tools/swig/Lib/python/pystrings.swg
deleted file mode 100644
index 64ed685e8c..0000000000
--- a/contrib/tools/swig/Lib/python/pystrings.swg
+++ /dev/null
@@ -1,139 +0,0 @@
-/* ------------------------------------------------------------
- * utility methods for char strings
- * ------------------------------------------------------------ */
-%fragment("SWIG_AsCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") {
-SWIGINTERN int
-SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
-{
-%#if PY_VERSION_HEX>=0x03000000
-%#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
- if (PyBytes_Check(obj))
-%#else
- if (PyUnicode_Check(obj))
-%#endif
-%#else
- if (PyString_Check(obj))
-%#endif
- {
- char *cstr; Py_ssize_t len;
- int ret = SWIG_OK;
-%#if PY_VERSION_HEX>=0x03000000
-%#if !defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
- if (!alloc && cptr) {
- /* We can't allow converting without allocation, since the internal
- representation of string in Python 3 is UCS-2/UCS-4 but we require
- a UTF-8 representation.
- TODO(bhy) More detailed explanation */
- return SWIG_RuntimeError;
- }
- obj = PyUnicode_AsUTF8String(obj);
- if (!obj)
- return SWIG_TypeError;
- if (alloc)
- *alloc = SWIG_NEWOBJ;
-%#endif
- if (PyBytes_AsStringAndSize(obj, &cstr, &len) == -1)
- return SWIG_TypeError;
-%#else
- if (PyString_AsStringAndSize(obj, &cstr, &len) == -1)
- return SWIG_TypeError;
-%#endif
- if (cptr) {
- if (alloc) {
- if (*alloc == SWIG_NEWOBJ) {
- *cptr = %new_copy_array(cstr, len + 1, char);
- *alloc = SWIG_NEWOBJ;
- } else {
- *cptr = cstr;
- *alloc = SWIG_OLDOBJ;
- }
- } else {
-%#if PY_VERSION_HEX>=0x03000000
-%#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
- *cptr = PyBytes_AsString(obj);
-%#else
- assert(0); /* Should never reach here with Unicode strings in Python 3 */
-%#endif
-%#else
- *cptr = SWIG_Python_str_AsChar(obj);
- if (!*cptr)
- ret = SWIG_TypeError;
-%#endif
- }
- }
- if (psize) *psize = len + 1;
-%#if PY_VERSION_HEX>=0x03000000 && !defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
- Py_XDECREF(obj);
-%#endif
- return ret;
- } else {
-%#if defined(SWIG_PYTHON_2_UNICODE)
-%#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
-%#error "Cannot use both SWIG_PYTHON_2_UNICODE and SWIG_PYTHON_STRICT_BYTE_CHAR at once"
-%#endif
-%#if PY_VERSION_HEX<0x03000000
- if (PyUnicode_Check(obj)) {
- char *cstr; Py_ssize_t len;
- if (!alloc && cptr) {
- return SWIG_RuntimeError;
- }
- obj = PyUnicode_AsUTF8String(obj);
- if (!obj)
- return SWIG_TypeError;
- if (PyString_AsStringAndSize(obj, &cstr, &len) != -1) {
- if (cptr) {
- if (alloc) *alloc = SWIG_NEWOBJ;
- *cptr = %new_copy_array(cstr, len + 1, char);
- }
- if (psize) *psize = len + 1;
-
- Py_XDECREF(obj);
- return SWIG_OK;
- } else {
- Py_XDECREF(obj);
- }
- }
-%#endif
-%#endif
-
- swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
- if (pchar_descriptor) {
- void* vptr = 0;
- if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) {
- if (cptr) *cptr = (char *) vptr;
- if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0;
- if (alloc) *alloc = SWIG_OLDOBJ;
- return SWIG_OK;
- }
- }
- }
- return SWIG_TypeError;
-}
-}
-
-%fragment("SWIG_FromCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") {
-SWIGINTERNINLINE PyObject *
-SWIG_FromCharPtrAndSize(const char* carray, size_t size)
-{
- if (carray) {
- if (size > INT_MAX) {
- swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
- return pchar_descriptor ?
- SWIG_InternalNewPointerObj(%const_cast(carray,char *), pchar_descriptor, 0) : SWIG_Py_Void();
- } else {
-%#if PY_VERSION_HEX >= 0x03000000
-%#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
- return PyBytes_FromStringAndSize(carray, %numeric_cast(size, Py_ssize_t));
-%#else
- return PyUnicode_DecodeUTF8(carray, %numeric_cast(size, Py_ssize_t), "surrogateescape");
-%#endif
-%#else
- return PyString_FromStringAndSize(carray, %numeric_cast(size, Py_ssize_t));
-%#endif
- }
- } else {
- return SWIG_Py_Void();
- }
-}
-}
-
diff --git a/contrib/tools/swig/Lib/python/python.swg b/contrib/tools/swig/Lib/python/python.swg
deleted file mode 100644
index 769d9e104a..0000000000
--- a/contrib/tools/swig/Lib/python/python.swg
+++ /dev/null
@@ -1,59 +0,0 @@
-/* ------------------------------------------------------------
- * python.swg
- *
- * Python configuration module.
- * ------------------------------------------------------------ */
-
-/* ------------------------------------------------------------
- * Inner macros
- * ------------------------------------------------------------ */
-%include <pymacros.swg>
-
-
-/* ------------------------------------------------------------
- * The runtime part
- * ------------------------------------------------------------ */
-%include <pyruntime.swg>
-
-/* ------------------------------------------------------------
- * Special user directives
- * ------------------------------------------------------------ */
-%include <pyuserdir.swg>
-
-/* ------------------------------------------------------------
- * Typemap specializations
- * ------------------------------------------------------------ */
-%include <pytypemaps.swg>
-
-/* ------------------------------------------------------------
- * Overloaded operator support
- * ------------------------------------------------------------ */
-%include <pyopers.swg>
-
-/* ------------------------------------------------------------
- * Warnings for Python keywords
- * ------------------------------------------------------------ */
-%include <pythonkw.swg>
-
-/* ------------------------------------------------------------
- * The Python autodoc support
- * ------------------------------------------------------------ */
-%include <pydocs.swg>
-
-/* ------------------------------------------------------------
- * The Python classes, for C++
- * ------------------------------------------------------------ */
-%include <pyclasses.swg>
-
-/* ------------------------------------------------------------
- * The Python initialization function
- * ------------------------------------------------------------ */
-%include <pyinit.swg>
-
-
-/* ------------------------------------------------------------
- * For backward compatibility
- * ------------------------------------------------------------ */
-%include <pybackward.swg>
-
-
diff --git a/contrib/tools/swig/Lib/python/pythonkw.swg b/contrib/tools/swig/Lib/python/pythonkw.swg
deleted file mode 100644
index a21034524f..0000000000
--- a/contrib/tools/swig/Lib/python/pythonkw.swg
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- Warnings for Python keywords, built-in names and bad names.
-*/
-
-#define PYTHONKW(x) %keywordwarn("'" `x` "' is a python keyword", rename="_%s") `x`
-#define PYTHONBN(x) %builtinwarn("'" `x` "' conflicts with a built-in name in python") `x`
-
-
-/*
- Warnings for Python keywords
- https://docs.python.org/2/reference/lexical_analysis.html#keywords
-*/
-
-PYTHONKW(and);
-PYTHONKW(as);
-PYTHONKW(assert);
-PYTHONKW(async);
-PYTHONKW(await);
-PYTHONKW(break);
-PYTHONKW(class);
-PYTHONKW(continue);
-PYTHONKW(def);
-PYTHONKW(del);
-PYTHONKW(elif);
-PYTHONKW(else);
-PYTHONKW(except);
-PYTHONKW(exec);
-PYTHONKW(finally);
-PYTHONKW(for);
-PYTHONKW(from);
-PYTHONKW(global);
-PYTHONKW(if);
-PYTHONKW(import);
-PYTHONKW(in);
-PYTHONKW(is);
-PYTHONKW(lambda);
-PYTHONKW(not);
-PYTHONKW(or);
-PYTHONKW(pass);
-PYTHONKW(print);
-PYTHONKW(raise);
-PYTHONKW(return);
-PYTHONKW(try);
-PYTHONKW(while);
-PYTHONKW(with);
-PYTHONKW(yield);
-
-/*
- built-in functions
- https://docs.python.org/2/library/functions.html
- */
-
-PYTHONBN(abs);
-PYTHONBN(apply);
-PYTHONBN(bool);
-PYTHONBN(buffer);
-PYTHONBN(callable);
-PYTHONBN(chr);
-PYTHONBN(classmethod);
-PYTHONBN(cmp);
-PYTHONBN(coerce);
-PYTHONBN(compile);
-PYTHONBN(complex);
-PYTHONBN(delattr);
-PYTHONBN(dict);
-PYTHONBN(dir);
-PYTHONBN(divmod);
-PYTHONBN(enumerate);
-PYTHONBN(eval);
-PYTHONBN(execfile);
-PYTHONBN(file);
-PYTHONBN(filter);
-PYTHONBN(float);
-PYTHONBN(frozenset);
-PYTHONBN(getattr);
-PYTHONBN(globals);
-PYTHONBN(hasattr);
-PYTHONBN(hash);
-PYTHONBN(hex);
-PYTHONBN(id);
-PYTHONBN(input);
-PYTHONBN(int);
-PYTHONBN(intern);
-PYTHONBN(isinstance);
-PYTHONBN(issubclass);
-PYTHONBN(iter);
-PYTHONBN(len);
-PYTHONBN(list);
-PYTHONBN(locals);
-PYTHONBN(long);
-PYTHONBN(map);
-PYTHONBN(max);
-PYTHONBN(min);
-PYTHONBN(object);
-PYTHONBN(oct);
-PYTHONBN(open);
-PYTHONBN(ord);
-PYTHONBN(pow);
-PYTHONBN(property);
-PYTHONBN(range);
-PYTHONBN(raw_input);
-PYTHONBN(reduce);
-PYTHONBN(reload);
-PYTHONBN(repr);
-PYTHONBN(reversed);
-PYTHONBN(round);
-PYTHONBN(set);
-PYTHONBN(setattr);
-PYTHONBN(slice);
-PYTHONBN(sorted);
-PYTHONBN(staticmethod);
-PYTHONBN(str);
-PYTHONBN(sum);
-PYTHONBN(super);
-PYTHONBN(tuple);
-PYTHONBN(type);
-PYTHONBN(unichr);
-PYTHONBN(unicode);
-PYTHONBN(vars);
-PYTHONBN(xrange);
-PYTHONBN(zip);
-
-
-/*
- built-in names
- boolean type and None
-*/
-PYTHONBN(True);
-PYTHONBN(False);
-
-PYTHONKW(None);
-
-
-/*
- 'self' is also a bad Name
-*/
-PYTHONKW(self);
-
-#undef PYTHONBN
-#undef PYTHONKW
diff --git a/contrib/tools/swig/Lib/python/pythreads.swg b/contrib/tools/swig/Lib/python/pythreads.swg
deleted file mode 100644
index 8d6c5ab49e..0000000000
--- a/contrib/tools/swig/Lib/python/pythreads.swg
+++ /dev/null
@@ -1,68 +0,0 @@
-#if defined(SWIG_PYTHON_NO_THREADS)
-# if defined(SWIG_PYTHON_THREADS)
-# undef SWIG_PYTHON_THREADS
-# endif
-#endif
-#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */
-# if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL)
-# define SWIG_PYTHON_USE_GIL
-# endif
-# if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */
-# if !defined(SWIG_PYTHON_INITIALIZE_THREADS)
-# if PY_VERSION_HEX < 0x03070000
-# define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads()
-# else
-# define SWIG_PYTHON_INITIALIZE_THREADS
-# endif
-# endif
-# ifdef __cplusplus /* C++ code */
- class SWIG_Python_Thread_Block {
- bool status;
- PyGILState_STATE state;
- public:
- void end() { if (status) { PyGILState_Release(state); status = false;} }
- SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {}
- ~SWIG_Python_Thread_Block() { end(); }
- };
- class SWIG_Python_Thread_Allow {
- bool status;
- PyThreadState *save;
- public:
- void end() { if (status) { PyEval_RestoreThread(save); status = false; }}
- SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {}
- ~SWIG_Python_Thread_Allow() { end(); }
- };
-# define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block
-# define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end()
-# define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow
-# define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end()
-# else /* C code */
-# define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure()
-# define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block)
-# define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread()
-# define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow)
-# endif
-# else /* Old thread way, not implemented, user must provide it */
-# if !defined(SWIG_PYTHON_INITIALIZE_THREADS)
-# define SWIG_PYTHON_INITIALIZE_THREADS
-# endif
-# if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK)
-# define SWIG_PYTHON_THREAD_BEGIN_BLOCK
-# endif
-# if !defined(SWIG_PYTHON_THREAD_END_BLOCK)
-# define SWIG_PYTHON_THREAD_END_BLOCK
-# endif
-# if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW)
-# define SWIG_PYTHON_THREAD_BEGIN_ALLOW
-# endif
-# if !defined(SWIG_PYTHON_THREAD_END_ALLOW)
-# define SWIG_PYTHON_THREAD_END_ALLOW
-# endif
-# endif
-#else /* No thread support */
-# define SWIG_PYTHON_INITIALIZE_THREADS
-# define SWIG_PYTHON_THREAD_BEGIN_BLOCK
-# define SWIG_PYTHON_THREAD_END_BLOCK
-# define SWIG_PYTHON_THREAD_BEGIN_ALLOW
-# define SWIG_PYTHON_THREAD_END_ALLOW
-#endif
diff --git a/contrib/tools/swig/Lib/python/pytypemaps.swg b/contrib/tools/swig/Lib/python/pytypemaps.swg
deleted file mode 100644
index 0ae25a686e..0000000000
--- a/contrib/tools/swig/Lib/python/pytypemaps.swg
+++ /dev/null
@@ -1,105 +0,0 @@
-/* ------------------------------------------------------------
- * Typemap specializations for Python
- * ------------------------------------------------------------ */
-
-/* ------------------------------------------------------------
- * Fragment section
- * ------------------------------------------------------------ */
-#ifdef SWIG_PYTHON_LEGACY_BOOL
-// Default prior to SWIG 3.0.0
-#undef SWIG_TYPECHECK_BOOL
-%define SWIG_TYPECHECK_BOOL 10000 %enddef
-#endif
-
-/* Include fundamental fragment definitions */
-%include <typemaps/fragments.swg>
-
-/* Look for user fragments file. */
-%include <pyfragments.swg>
-
-/* Python fragments for fundamental types */
-%include <pyprimtypes.swg>
-
-/* Python fragments for char* strings */
-%include <pystrings.swg>
-
-/* Backward compatibility output helper */
-%fragment("t_output_helper","header") %{
-#define t_output_helper SWIG_Python_AppendOutput
-%}
-
-
-/* ------------------------------------------------------------
- * Unified typemap section
- * ------------------------------------------------------------ */
-
-/* directors are supported in Python */
-#ifndef SWIG_DIRECTOR_TYPEMAPS
-#define SWIG_DIRECTOR_TYPEMAPS
-#endif
-
-
-/* Python types */
-#define SWIG_Object PyObject *
-#define VOID_Object SWIG_Py_Void()
-
-/* Python allows implicit conversion */
-#define %implicitconv_flag $implicitconv
-
-
-/* Overload of the output/constant/exception/dirout handling */
-
-/* append output */
-#define SWIG_AppendOutput(result, obj) SWIG_Python_AppendOutput(result, obj)
-
-/* set constant */
-#if defined(SWIGPYTHON_BUILTIN)
-#define SWIG_SetConstant(name, obj) SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, name,obj)
-#else
-#define SWIG_SetConstant(name, obj) SWIG_Python_SetConstant(d, name,obj)
-#endif
-
-/* raise */
-#define SWIG_Raise(obj, type, desc) SWIG_Python_Raise(obj, type, desc)
-
-/* Include the unified typemap library */
-%include <typemaps/swigtypemaps.swg>
-
-
-/* ------------------------------------------------------------
- * Python extra typemaps / typemap overrides
- * ------------------------------------------------------------ */
-
-/* Get the address of the 'python self' object */
-
-%typemap(in,numinputs=0,noblock=1) PyObject **PYTHON_SELF {
- $1 = &$self;
-}
-
-
-/* Consttab, needed for callbacks, it should be removed later */
-
-%typemap(consttab) SWIGTYPE ((*)(ANY))
-{ SWIG_PY_POINTER, "$symname", 0, 0, (void *)($value), &$descriptor }
-%typemap(consttab) SWIGTYPE ((* const)(ANY)) = SWIGTYPE ((*)(ANY));
-
-%typemap(constcode) SWIGTYPE ((*)(ANY)) ""
-%typemap(constcode) SWIGTYPE ((* const)(ANY)) = SWIGTYPE ((*)(ANY));
-
-
-/* Smart Pointers */
-%typemap(out,noblock=1) const SWIGTYPE & SMARTPOINTER {
- $result = SWIG_NewPointerObj(%new_copy(*$1, $*ltype), $descriptor, SWIG_POINTER_OWN | %newpointer_flags);
-}
-
-%typemap(ret,noblock=1) const SWIGTYPE & SMARTPOINTER, SWIGTYPE SMARTPOINTER {
- if ($result) {
- PyObject *robj = PyObject_CallMethod($result, (char *)"__deref__", NULL);
- if (robj && !PyErr_Occurred()) {
- SwigPyObject_append((PyObject *) SWIG_Python_GetSwigThis($result),
- (PyObject *) SWIG_Python_GetSwigThis(robj));
- Py_DECREF(robj);
- }
- }
-}
-
diff --git a/contrib/tools/swig/Lib/python/pyuserdir.swg b/contrib/tools/swig/Lib/python/pyuserdir.swg
deleted file mode 100644
index 3110760793..0000000000
--- a/contrib/tools/swig/Lib/python/pyuserdir.swg
+++ /dev/null
@@ -1,242 +0,0 @@
-/* -------------------------------------------------------------------------
- * Special user directives
- * ------------------------------------------------------------------------- */
-
-/* ------------------------------------------------------------------------- */
-
-/* shadow code */
-#define %shadow %insert("shadow")
-#define %pythoncode %insert("python")
-#define %pythonbegin %insert("pythonbegin")
-
-
-/* ------------------------------------------------------------------------- */
-/*
-Use the "nondynamic" feature to make a wrapped class behave as a "nondynamic"
-one, ie, a python class that doesn't dynamically add new attributes.
-
-For example, for the class
-
-%pythonnondynamic A;
-struct A
-{
- int a;
- int b;
-};
-
-you will get:
-
- aa = A()
- aa.a = 1 # Ok
- aa.b = 1 # Ok
- aa.c = 3 # error
-
-Since nondynamic is a feature, if you use it like
-
- %pythonnondynamic;
-
-it will make all the wrapped classes nondynamic ones.
-
-The implementation is based on this recipe:
-
- http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252158
-
-*/
-
-#define %pythonnondynamic %feature("python:nondynamic", "1")
-#define %nopythonnondynamic %feature("python:nondynamic", "0")
-#define %clearpythonnondynamic %feature("python:nondynamic", "")
-#define %pythondynamic %nopythonnondynamic
-
-
-/* ------------------------------------------------------------------------- */
-/*
-
-Use %pythonmaybecall to flag a method like __add__ or __radd__. These
-don't produce an error when called, they just return NotImplemented.
-
-These methods "may be called" if needed.
-
-*/
-
-#define %pythonmaybecall %feature("python:maybecall", "1")
-#define %nopythonmaybecall %feature("python:maybecall", "0")
-#define %clearpythonmaybecall %feature("python:maybecall", "")
-
-/* ------------------------------------------------------------------------- */
-/*
- The %pythoncallback feature produce a more natural callback wrapper
- than the %callback mechanism, ie, it uses the original name for
- the callback and callable objects.
-
- Just use it as
-
- %pythoncallback(1) foo;
- int foo(int a);
-
- %pythoncallback(1) A::foo;
- struct A {
- static int foo(int a);
- };
-
- int bar(int, int (*pf)(int));
-
- then, you can use it as:
-
- a = foo(1)
- b = bar(2, foo)
-
- c = A.foo(3)
- d = bar(4, A.foo)
-
-
- If you use it with a member method
- %pythoncallback(1) A::foom;
- struct A {
- int foom(int a);
- };
-
- then you can use it as
-
- r = a.foom(3) # eval the method
- mptr = A.foom_cb_ptr # returns the callback pointer
-
- where the '_cb_ptr' suffix is added for the callback pointer.
-
-*/
-
-#define %pythoncallback %feature("python:callback")
-#define %nopythoncallback %feature("python:callback","0")
-#define %clearpythoncallback %feature("python:callback","")
-
-/* ------------------------------------------------------------------------- */
-/*
- Support for the old %callback directive name
-*/
-#ifdef %callback
-#undef %callback
-#endif
-
-#ifdef %nocallback
-#undef %nocallback
-#endif
-
-#ifdef %clearcallback
-#undef %clearcallback
-#endif
-
-#define %callback(x) %feature("python:callback",`x`)
-#define %nocallback %nopythoncallback
-#define %clearcallback %clearpythoncallback
-
-/* ------------------------------------------------------------------------- */
-/*
- Thread support - Advance control
-
-*/
-
-#define %nothread %feature("nothread")
-#define %thread %feature("nothread","0")
-#define %clearnothread %feature("nothread","")
-
-#define %nothreadblock %feature("nothreadblock")
-#define %threadblock %feature("nothreadblock","0")
-#define %clearnothreadblock %feature("nothreadblock","")
-
-#define %nothreadallow %feature("nothreadallow")
-#define %threadallow %feature("nothreadallow","0")
-#define %clearnothreadallow %feature("nothreadallow","")
-
-
-/* ------------------------------------------------------------------------- */
-/*
- Implicit Conversion using the C++ constructor mechanism
-*/
-
-#define %implicitconv %feature("implicitconv")
-#define %noimplicitconv %feature("implicitconv", "0")
-#define %clearimplicitconv %feature("implicitconv", "")
-
-
-/* ------------------------------------------------------------------------- */
-/*
- Enable keywords parameters
-*/
-
-#define %kwargs %feature("kwargs")
-#define %nokwargs %feature("kwargs", "0")
-#define %clearkwargs %feature("kwargs", "")
-
-/* ------------------------------------------------------------------------- */
-/*
- Add python code to the proxy/shadow code
-
- %pythonprepend - Add code before the C++ function is called
- %pythonappend - Add code after the C++ function is called
-*/
-
-#define %pythonprepend %feature("pythonprepend")
-#define %clearpythonprepend %feature("pythonprepend","")
-
-#define %pythonappend %feature("pythonappend")
-#define %clearpythonappend %feature("pythonappend","")
-
-
-/* ------------------------------------------------------------------------- */
-/*
- %extend_smart_pointer extend the smart pointer support.
-
- For example, if you have a smart pointer as:
-
- template <class Type> class RCPtr {
- public:
- ...
- RCPtr(Type *p);
- Type * operator->() const;
- ...
- };
-
- you use the %extend_smart_pointer directive as:
-
- %extend_smart_pointer(RCPtr<A>);
- %template(RCPtr_A) RCPtr<A>;
-
- then, if you have something like:
-
- RCPtr<A> make_ptr();
- int foo(A *);
-
- you can do the following:
-
- a = make_ptr();
- b = foo(a);
-
- ie, swig will accept a RCPtr<A> object where a 'A *' is
- expected.
-
- Also, when using vectors
-
- %extend_smart_pointer(RCPtr<A>);
- %template(RCPtr_A) RCPtr<A>;
- %template(vector_A) std::vector<RCPtr<A> >;
-
- you can type
-
- a = A();
- v = vector_A(2)
- v[0] = a
-
- ie, an 'A *' object is accepted, via implicit conversion,
- where a RCPtr<A> object is expected. Additionally
-
- x = v[0]
-
- returns (and sets 'x' as) a copy of v[0], making reference
- counting possible and consistent.
-*/
-
-%define %extend_smart_pointer(Type...)
-%implicitconv Type;
-%apply const SWIGTYPE& SMARTPOINTER { const Type& };
-%apply SWIGTYPE SMARTPOINTER { Type };
-%enddef
diff --git a/contrib/tools/swig/Lib/python/typemaps.i b/contrib/tools/swig/Lib/python/typemaps.i
deleted file mode 100644
index dba63dd59e..0000000000
--- a/contrib/tools/swig/Lib/python/typemaps.i
+++ /dev/null
@@ -1,148 +0,0 @@
-/* -----------------------------------------------------------------------------
- * typemaps.i
- *
- * Pointer handling
- * These mappings provide support for input/output arguments and common
- * uses for C/C++ pointers.
- * ----------------------------------------------------------------------------- */
-
-// INPUT typemaps.
-// These remap a C pointer to be an "INPUT" value which is passed by value
-// instead of reference.
-
-/*
-The following methods can be applied to turn a pointer into a simple
-"input" value. That is, instead of passing a pointer to an object,
-you would use a real value instead.
-
- int *INPUT
- short *INPUT
- long *INPUT
- long long *INPUT
- unsigned int *INPUT
- unsigned short *INPUT
- unsigned long *INPUT
- unsigned long long *INPUT
- unsigned char *INPUT
- bool *INPUT
- float *INPUT
- double *INPUT
-
-To use these, suppose you had a C function like this :
-
- double fadd(double *a, double *b) {
- return *a+*b;
- }
-
-You could wrap it with SWIG as follows :
-
- %include <typemaps.i>
- double fadd(double *INPUT, double *INPUT);
-
-or you can use the %apply directive :
-
- %include <typemaps.i>
- %apply double *INPUT { double *a, double *b };
- double fadd(double *a, double *b);
-
-*/
-
-// OUTPUT typemaps. These typemaps are used for parameters that
-// are output only. The output value is appended to the result as
-// a list element.
-
-/*
-The following methods can be applied to turn a pointer into an "output"
-value. When calling a function, no input value would be given for
-a parameter, but an output value would be returned. In the case of
-multiple output values, they are returned in the form of a Python tuple.
-
- int *OUTPUT
- short *OUTPUT
- long *OUTPUT
- long long *OUTPUT
- unsigned int *OUTPUT
- unsigned short *OUTPUT
- unsigned long *OUTPUT
- unsigned long long *OUTPUT
- unsigned char *OUTPUT
- bool *OUTPUT
- float *OUTPUT
- double *OUTPUT
-
-For example, suppose you were trying to wrap the modf() function in the
-C math library which splits x into integral and fractional parts (and
-returns the integer part in one of its parameters) :
-
- double modf(double x, double *ip);
-
-You could wrap it with SWIG as follows :
-
- %include <typemaps.i>
- double modf(double x, double *OUTPUT);
-
-or you can use the %apply directive :
-
- %include <typemaps.i>
- %apply double *OUTPUT { double *ip };
- double modf(double x, double *ip);
-
-The Python output of the function would be a tuple containing both
-output values.
-
-*/
-
-// INOUT
-// Mappings for an argument that is both an input and output
-// parameter
-
-/*
-The following methods can be applied to make a function parameter both
-an input and output value. This combines the behavior of both the
-"INPUT" and "OUTPUT" methods described earlier. Output values are
-returned in the form of a Python tuple.
-
- int *INOUT
- short *INOUT
- long *INOUT
- long long *INOUT
- unsigned int *INOUT
- unsigned short *INOUT
- unsigned long *INOUT
- unsigned long long *INOUT
- unsigned char *INOUT
- bool *INOUT
- float *INOUT
- double *INOUT
-
-For example, suppose you were trying to wrap the following function :
-
- void neg(double *x) {
- *x = -(*x);
- }
-
-You could wrap it with SWIG as follows :
-
- %include <typemaps.i>
- void neg(double *INOUT);
-
-or you can use the %apply directive :
-
- %include <typemaps.i>
- %apply double *INOUT { double *x };
- void neg(double *x);
-
-Unlike C, this mapping does not directly modify the input value (since
-this makes no sense in Python). Rather, the modified input value shows
-up as the return value of the function. Thus, to apply this function
-to a Python variable you might do this :
-
- x = neg(x)
-
-Note : previous versions of SWIG used the symbol 'BOTH' to mark
-input/output arguments. This is still supported, but will be slowly
-phased out in future releases.
-
-*/
-
-%include <typemaps/typemaps.swg>
diff --git a/contrib/tools/swig/Lib/python/ya.make b/contrib/tools/swig/Lib/python/ya.make
deleted file mode 100644
index e843bff498..0000000000
--- a/contrib/tools/swig/Lib/python/ya.make
+++ /dev/null
@@ -1,22 +0,0 @@
-# Generated by devtools/yamaker.
-
-LIBRARY()
-
-LICENSE(LicenseRef-scancode-swig)
-
-LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-
-VERSION(4.1.1)
-
-ORIGINAL_SOURCE(https://github.com/swig/swig/archive/v4.1.1.tar.gz)
-
-ADDINCL(
- GLOBAL FOR
- swig
- contrib/tools/swig/Lib/python
- GLOBAL FOR
- swig
- contrib/tools/swig/Lib
-)
-
-END()
diff --git a/contrib/tools/swig/Lib/std/README b/contrib/tools/swig/Lib/std/README
deleted file mode 100644
index 5cd759dda1..0000000000
--- a/contrib/tools/swig/Lib/std/README
+++ /dev/null
@@ -1,22 +0,0 @@
-/* -----------------------------------------------------------------------------
- * C++ STD + STL
- * ----------------------------------------------------------------------------- */
-
-std_common.i general common code
-std_container.i general container code
-std_basic_string.i basic string
-std_char_traits.i char traits
-std_complex.i complex
-std_deque.i deque
-std_except.i exceptions
-std_ios.i ios
-std_iostream.i istream/ostream
-std_list.i list
-std_map.i map
-std_multimap.i multimap
-std_multiset.i multiset
-std_pair.i pair
-std_set.i set
-std_streambuf.i streambuf
-std_vector.i vector
-std_vectora.i vector + allocator
diff --git a/contrib/tools/swig/Lib/swig.swg b/contrib/tools/swig/Lib/swig.swg
deleted file mode 100644
index 9f9d533498..0000000000
--- a/contrib/tools/swig/Lib/swig.swg
+++ /dev/null
@@ -1,729 +0,0 @@
-/* -----------------------------------------------------------------------------
- * swig.swg
- *
- * Common macro definitions for various SWIG directives. This file is always
- * included at the top of each input file.
- * ----------------------------------------------------------------------------- */
-
-/* -----------------------------------------------------------------------------
- * User Directives
- * ----------------------------------------------------------------------------- */
-
-/* Deprecated SWIG-1.1 directives */
-
-#define %disabledoc %warn "104:%disabledoc is deprecated"
-#define %enabledoc %warn "105:%enabledoc is deprecated"
-#define %doconly %warn "106:%doconly is deprecated"
-#define %style %warn "107:%style is deprecated" /##/
-#define %localstyle %warn "108:%localstyle is deprecated" /##/
-#define %title %warn "109:%title is deprecated" /##/
-#define %section %warn "110:%section is deprecated" /##/
-#define %subsection %warn "111:%subsection is deprecated" /##/
-#define %subsubsection %warn "112:%subsubsection is deprecated" /##/
-#define %new %warn "117:%new is deprecated. Use %newobject"
-#define %text %insert("null")
-
-/* Code insertion directives such as %wrapper %{ ... %} */
-
-#define %begin %insert("begin")
-#define %runtime %insert("runtime")
-#define %header %insert("header")
-#define %wrapper %insert("wrapper")
-#define %init %insert("init")
-
-/* Class extension */
-
-#define %addmethods %warn "113:%addmethods is now %extend" %extend
-
-/* %ignore directive */
-
-#define %ignore %rename($ignore)
-#define %ignorewarn(x) %rename("$ignore:" x)
-
-/* Access control directives */
-
-#define %readonly %warn "114:%readonly is deprecated. Use %immutable; " %feature("immutable");
-#define %readwrite %warn "115:%readwrite is deprecated. Use %mutable; " %feature("immutable","");
-
-#define %immutable %feature("immutable")
-#define %noimmutable %feature("immutable","0")
-#define %clearimmutable %feature("immutable","")
-#define %mutable %clearimmutable
-
-/* Generation of default constructors/destructors (old form, don't use) */
-#define %nodefault %feature("nodefault","1")
-#define %default %feature("nodefault","0")
-#define %clearnodefault %feature("nodefault","")
-#define %makedefault %clearnodefault
-
-/* Disable the generation of implicit default constructor */
-#define %nodefaultctor %feature("nodefaultctor","1")
-#define %defaultctor %feature("nodefaultctor","0")
-#define %clearnodefaultctor %feature("nodefaultctor","")
-
-/* Disable the generation of implicit default destructor (dangerous) */
-#define %nodefaultdtor %feature("nodefaultdtor","1")
-#define %defaultdtor %feature("nodefaultdtor","0")
-#define %clearnodefaultdtor %feature("nodefaultdtor","")
-
-/* Enable the generation of copy constructor */
-#define %copyctor %feature("copyctor","1")
-#define %nocopyctor %feature("copyctor","0")
-#define %clearcopyctor %feature("copyctor","")
-
-/* Force the old nodefault behavior, ie disable both constructor and destructor */
-#define %oldnodefault %feature("oldnodefault","1")
-#define %nooldnodefault %feature("oldnodefault","0")
-#define %clearoldnodefault %feature("oldnodefault","")
-
-/* the %exception directive */
-#if defined(SWIGCSHARP) || defined(SWIGD)
-#define %exception %feature("except", canthrow=1)
-#else
-#define %exception %feature("except")
-#endif
-#define %noexception %feature("except","0")
-#define %clearexception %feature("except","")
-
-/* the %allowexception directive allows the %exception feature to
- be applied to set/get variable methods */
-#define %allowexception %feature("allowexcept")
-#define %noallowexception %feature("allowexcept","0")
-#define %clearallowexception %feature("allowexcept","")
-
-/* the %exceptionvar directive, as %exception but it is only applied
- to set/get variable methods. You don't need to use the
- %allowexception directive when using %exceptionvar.
-*/
-#if defined(SWIGCSHARP) || defined(SWIGD)
-#define %exceptionvar %feature("exceptvar", canthrow=1)
-#else
-#define %exceptionvar %feature("exceptvar")
-#endif
-#define %noexceptionvar %feature("exceptvar","0")
-#define %clearexceptionvar %feature("exceptvar","")
-
-/* the %catches directive */
-#define %catches(tlist...) %feature("catches","("`tlist`")")
-#define %clearcatches %feature("catches","")
-
-/* the %exceptionclass directive */
-#define %exceptionclass %feature("exceptionclass")
-#define %noexceptionclass %feature("exceptionclass","0")
-#define %clearexceptionclass %feature("exceptionclass","")
-
-/* the %newobject directive */
-#define %newobject %feature("new")
-#define %nonewobject %feature("new","0")
-#define %clearnewobject %feature("new","")
-
-/* the %delobject directive */
-#define %delobject %feature("del")
-#define %nodelobject %feature("del","0")
-#define %cleardelobject %feature("del","")
-
-/* the %refobject/%unrefobject directives */
-#define %refobject %feature("ref")
-#define %norefobject %feature("ref","0")
-#define %clearrefobject %feature("ref","")
-
-#define %unrefobject %feature("unref")
-#define %nounrefobject %feature("unref","0")
-#define %clearunrefobject %feature("unref","")
-
-/* Directives for callback functions (experimental) */
-#define %callback(x) %feature("callback",`x`)
-#define %nocallback %feature("callback","0")
-#define %clearcallback %feature("callback","")
-
-/* the %nestedworkaround directive (deprecated) */
-#define %nestedworkaround %feature("nestedworkaround")
-#define %nonestedworkaround %feature("nestedworkaround","0")
-#define %clearnestedworkaround %feature("nestedworkaround","")
-
-/* the %flatnested directive */
-#define %flatnested %feature("flatnested")
-#define %noflatnested %feature("flatnested","0")
-#define %clearflatnested %feature("flatnested","")
-
-/* the %fastdispatch directive */
-#define %fastdispatch %feature("fastdispatch")
-#define %nofastdispatch %feature("fastdispatch","0")
-#define %clearfastdispatch %feature("fastdispatch","")
-
-/* directors directives */
-#define %director %feature("director")
-#define %nodirector %feature("director","0")
-#define %cleardirector %feature("director","")
-
-/* naturalvar directives */
-#define %naturalvar %feature("naturalvar")
-#define %nonaturalvar %feature("naturalvar","0")
-#define %clearnaturalvar %feature("naturalvar","")
-
-/* nspace directives */
-#define %nspace %feature("nspace")
-#define %nonspace %feature("nspace","0")
-#define %clearnspace %feature("nspace","")
-
-/* valuewrapper directives */
-#define %valuewrapper %feature("valuewrapper")
-#define %clearvaluewrapper %feature("valuewrapper","")
-#define %novaluewrapper %feature("novaluewrapper")
-#define %clearnovaluewrapper %feature("novaluewrapper","")
-
-/* Contract support - Experimental */
-#define %contract %feature("contract")
-#define %nocontract %feature("contract","0")
-#define %clearcontract %feature("contract","")
-
-/* Macro for setting a dynamic cast function */
-%define DYNAMIC_CAST(mangle,func)
-%init %{
- mangle->dcast = (swig_dycast_func) func;
-%}
-%enddef
-
-/* aggregation support */
-/*
- This macro performs constant aggregation. Basically the idea of
- constant aggregation is that you can group a collection of constants
- together. For example, suppose you have some code like this:
-
- #define UP 1
- #define DOWN 2
- #define LEFT 3
- #define RIGHT 4
-
- Now, suppose you had a function like this:
-
- int move(int direction)
-
- In this case, you might want to restrict the direction argument to
- one of the supplied constant names. To do this, you could write some
- typemap code by hand. Alternatively, you can use the
- %aggregate_check macro defined here to create a simple check
- function for you. Here is an example:
-
- %aggregate_check(int, check_direction, UP, DOWN, LEFT, RIGHT);
-
- Now, using a typemap
-
- %typemap(check) int direction {
- if (!check_direction($1)) SWIG_exception(SWIG_ValueError,"Bad direction.");
- }
-
- or a contract (better)
-
- %contract move(int x) {
- require:
- check_direction(x);
- }
-
-*/
-
-%define %aggregate_check(TYPE, NAME, FIRST, ...)
-%wrapper %{
-static int NAME(TYPE x) {
- static TYPE values[] = { FIRST, ##__VA_ARGS__ };
- static int size = sizeof(values);
- int i,j;
- for (i = 0, j = 0; i < size; i+=sizeof(TYPE),j++) {
- if (x == values[j]) return 1;
- }
- return 0;
-}
-%}
-%enddef
-
-
-/* -----------------------------------------------------------------------------
- * %rename predicates
- * ----------------------------------------------------------------------------- */
-/*
- Predicates to be used with %rename, for example:
-
- - to rename all the functions:
-
- %rename("%(utitle)s", %$isfunction) "";
-
- - to rename only the member methods:
-
- %rename("m_%(utitle)s", %$isfunction, %$ismember) "";
-
- - to rename only the global functions:
-
- %rename("m_%(utitle)s", %$isfunction, %$not %$ismember) "";
-
- or
-
- %rename("g_%(utitle)s", %$isfunction, %$isglobal) "";
-
- - to ignore the enumitems in a given class:
-
- %rename("$ignore", %$isenumitem, %$classname="MyClass") "";
-
- we use the prefix '%$' to avoid clashes with other swig
- macros/directives.
-
-*/
-
-/* Note that when %$not is used with another macro, say %enum as follows: %$not %$enum, the result is "notmatch=enum" */
-%define %$not "not" %enddef
-
-%define %$isenum "match"="enum" %enddef
-%define %$isenumitem "match"="enumitem" %enddef
-%define %$isaccess "match"="access" %enddef
-%define %$isclass "match"="class","notmatch$template$templatetype"="class" %enddef
-%define %$isextend "match"="extend" %enddef
-%define %$isconstructor "match"="constructor" %enddef
-%define %$isdestructor "match"="destructor" %enddef
-%define %$isnamespace "match"="namespace" %enddef
-%define %$istemplate "match"="template" %enddef
-%define %$isconstant "match"="constant" %enddef /* %constant definition */
-%define %$isusing "match"="using" %enddef
-
-%define %$isunion "match$kind"="union" %enddef
-%define %$isfunction "match$kind"="function" %enddef
-%define %$isvariable "match$kind"="variable" %enddef
-%define %$isimmutable "match$feature:immutable"="1" %enddef
-%define %$hasconsttype "match$hasconsttype"="1" %enddef
-%define %$hasvalue "match$hasvalue"="1" %enddef
-%define %$isextension "match$isextension"="1" %enddef
-
-%define %$isstatic "match$storage"="static" %enddef
-%define %$isfriend "match$storage"="friend" %enddef
-%define %$istypedef "match$storage"="typedef" %enddef
-%define %$isvirtual "match$storage"="virtual" %enddef
-%define %$isexplicit "match$storage"="explicit" %enddef
-%define %$isextern "match$storage"="extern" %enddef
-
-%define %$ismember "match$ismember"="1" %enddef
-%define %$isglobal %$not %$ismember %enddef
-%define %$isextendmember "match$isextendmember"="1" %enddef
-%define %$innamespace "match$parentNode$nodeType"="namespace" %enddef
-
-%define %$ispublic "match$access"="public" %enddef
-%define %$isprotected "match$access"="protected" %enddef
-%define %$isprivate "match$access"="private" %enddef
-
-%define %$ismemberget "match$memberget"="1" %enddef
-%define %$ismemberset "match$memberset"="1" %enddef
-
-%define %$classname %$ismember,"match$parentNode$name" %enddef
-%define %$isnested "match$nested"="1" %enddef
-
-/* -----------------------------------------------------------------------------
- * Common includes for warning labels, macros, fragments etc
- * ----------------------------------------------------------------------------- */
-
-%include <swigwarnings.swg>
-%include <swigfragments.swg>
-
-/* -----------------------------------------------------------------------------
- * Overloading support
- * ----------------------------------------------------------------------------- */
-
-/*
- * Function/method overloading support. This is done through typemaps,
- * but also involves a precedence level.
- */
-
-/* Macro for overload resolution */
-
-%define %typecheck(_x...) %typemap(typecheck, precedence=_x) %enddef
-
-/* Macros for precedence levels */
-
-%define SWIG_TYPECHECK_POINTER 0 %enddef
-%define SWIG_TYPECHECK_ITERATOR 5 %enddef
-%define SWIG_TYPECHECK_VOIDPTR 10 %enddef
-%define SWIG_TYPECHECK_BOOL 15 %enddef
-%define SWIG_TYPECHECK_UINT8 20 %enddef
-%define SWIG_TYPECHECK_INT8 25 %enddef
-%define SWIG_TYPECHECK_UINT16 30 %enddef
-%define SWIG_TYPECHECK_INT16 35 %enddef
-%define SWIG_TYPECHECK_UINT32 40 %enddef
-%define SWIG_TYPECHECK_INT32 45 %enddef
-%define SWIG_TYPECHECK_SIZE 47 %enddef
-%define SWIG_TYPECHECK_PTRDIFF 48 %enddef
-%define SWIG_TYPECHECK_UINT64 50 %enddef
-%define SWIG_TYPECHECK_INT64 55 %enddef
-%define SWIG_TYPECHECK_UINT128 60 %enddef
-%define SWIG_TYPECHECK_INT128 65 %enddef
-%define SWIG_TYPECHECK_INTEGER 70 %enddef
-%define SWIG_TYPECHECK_FLOAT 80 %enddef
-%define SWIG_TYPECHECK_DOUBLE 90 %enddef
-%define SWIG_TYPECHECK_CPLXFLT 95 %enddef
-%define SWIG_TYPECHECK_CPLXDBL 100 %enddef
-%define SWIG_TYPECHECK_COMPLEX 105 %enddef
-%define SWIG_TYPECHECK_UNICHAR 110 %enddef
-%define SWIG_TYPECHECK_STDUNISTRING 115 %enddef
-%define SWIG_TYPECHECK_UNISTRING 120 %enddef
-%define SWIG_TYPECHECK_CHAR 130 %enddef
-%define SWIG_TYPECHECK_STDSTRING 135 %enddef
-%define SWIG_TYPECHECK_STRING 140 %enddef
-%define SWIG_TYPECHECK_PAIR 150 %enddef
-%define SWIG_TYPECHECK_STDARRAY 155 %enddef
-%define SWIG_TYPECHECK_VECTOR 160 %enddef
-%define SWIG_TYPECHECK_DEQUE 170 %enddef
-%define SWIG_TYPECHECK_LIST 180 %enddef
-%define SWIG_TYPECHECK_SET 190 %enddef
-%define SWIG_TYPECHECK_MULTISET 200 %enddef
-%define SWIG_TYPECHECK_MAP 210 %enddef
-%define SWIG_TYPECHECK_MULTIMAP 220 %enddef
-%define SWIG_TYPECHECK_STACK 230 %enddef
-%define SWIG_TYPECHECK_QUEUE 240 %enddef
-
-%define SWIG_TYPECHECK_BOOL_ARRAY 1015 %enddef
-%define SWIG_TYPECHECK_INT8_ARRAY 1025 %enddef
-%define SWIG_TYPECHECK_INT16_ARRAY 1035 %enddef
-%define SWIG_TYPECHECK_INT32_ARRAY 1045 %enddef
-%define SWIG_TYPECHECK_INT64_ARRAY 1055 %enddef
-%define SWIG_TYPECHECK_INT128_ARRAY 1065 %enddef
-%define SWIG_TYPECHECK_FLOAT_ARRAY 1080 %enddef
-%define SWIG_TYPECHECK_DOUBLE_ARRAY 1090 %enddef
-%define SWIG_TYPECHECK_CHAR_ARRAY 1130 %enddef
-%define SWIG_TYPECHECK_STRING_ARRAY 1140 %enddef
-%define SWIG_TYPECHECK_OBJECT_ARRAY 1150 %enddef
-
-%define SWIG_TYPECHECK_BOOL_PTR 2015 %enddef
-%define SWIG_TYPECHECK_UINT8_PTR 2020 %enddef
-%define SWIG_TYPECHECK_INT8_PTR 2025 %enddef
-%define SWIG_TYPECHECK_UINT16_PTR 2030 %enddef
-%define SWIG_TYPECHECK_INT16_PTR 2035 %enddef
-%define SWIG_TYPECHECK_UINT32_PTR 2040 %enddef
-%define SWIG_TYPECHECK_INT32_PTR 2045 %enddef
-%define SWIG_TYPECHECK_UINT64_PTR 2050 %enddef
-%define SWIG_TYPECHECK_INT64_PTR 2055 %enddef
-%define SWIG_TYPECHECK_FLOAT_PTR 2080 %enddef
-%define SWIG_TYPECHECK_DOUBLE_PTR 2090 %enddef
-%define SWIG_TYPECHECK_CHAR_PTR 2130 %enddef
-
-%define SWIG_TYPECHECK_SWIGOBJECT 5000 %enddef
-
-
-/* -----------------------------------------------------------------------------
- * Default handling of certain overloaded operators
- * ----------------------------------------------------------------------------- */
-
-#ifdef __cplusplus
-%ignoreoperator(NEW) operator new;
-%ignoreoperator(DELETE) operator delete;
-%ignoreoperator(NEWARR) operator new[];
-%ignoreoperator(DELARR) operator delete[];
-
-/* add C++ operator aliases */
-%rename("operator &&") operator and; // `and' `&&'
-%rename("operator ||") operator or; // `or' `||'
-%rename("operator !") operator not; // `not' `!'
-%rename("operator &=") operator and_eq; // `and_eq' `&='
-%rename("operator &") operator bitand; // `bitand' `&'
-%rename("operator |") operator bitor; // `bitor' `|'
-%rename("operator ~") operator compl; // `compl' `~'
-%rename("operator !=") operator not_eq; // `not_eq' `!='
-%rename("operator |=") operator or_eq; // `or_eq' `|='
-%rename("operator ^") operator xor; // `xor' `^'
-%rename("operator ^=") operator xor_eq; // `xor_eq' `^='
-
-/* Smart pointer handling */
-
-%rename(__deref__) *::operator->;
-%rename(__ref__) *::operator*();
-%rename(__ref__) *::operator*() const;
-
-/* Define std namespace */
-namespace std {
- /* Warn about std::initializer_list usage. The constructor/method where used should probably be ignored. See docs. */
- template<typename T> class initializer_list {};
- %typemap(in, warning=SWIGWARN_TYPEMAP_INITIALIZER_LIST_MSG) initializer_list<T> ""
- %typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER) initializer_list<T> ""
-}
-#endif
-
-/* -----------------------------------------------------------------------------
- * Default char * and C array typemaps
- * ----------------------------------------------------------------------------- */
-
-/* Set up the typemap for handling new return strings */
-
-#ifdef __cplusplus
-%typemap(newfree) char * "delete [] $1;"
-#else
-%typemap(newfree) char * "free($1);"
-#endif
-
-/* Default typemap for handling char * members */
-
-#ifdef __cplusplus
-%typemap(memberin,fragment="<string.h>") char * {
- delete [] $1;
- if ($input) {
- $1 = ($1_type) (new char[strlen((const char *)$input)+1]);
- strcpy((char *)$1, (const char *)$input);
- } else {
- $1 = 0;
- }
-}
-%typemap(memberin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="<string.h>") const char * {
- if ($input) {
- $1 = ($1_type) (new char[strlen((const char *)$input)+1]);
- strcpy((char *)$1, (const char *)$input);
- } else {
- $1 = 0;
- }
-}
-%typemap(globalin,fragment="<string.h>") char * {
- delete [] $1;
- if ($input) {
- $1 = ($1_type) (new char[strlen((const char *)$input)+1]);
- strcpy((char *)$1, (const char *)$input);
- } else {
- $1 = 0;
- }
-}
-%typemap(globalin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="<string.h>") const char * {
- if ($input) {
- $1 = ($1_type) (new char[strlen((const char *)$input)+1]);
- strcpy((char *)$1, (const char *)$input);
- } else {
- $1 = 0;
- }
-}
-#else
-%typemap(memberin,fragment="<string.h>") char * {
- free($1);
- if ($input) {
- $1 = ($1_type) malloc(strlen((const char *)$input)+1);
- strcpy((char *)$1, (const char *)$input);
- } else {
- $1 = 0;
- }
-}
-%typemap(memberin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="<string.h>") const char * {
- if ($input) {
- $1 = ($1_type) malloc(strlen((const char *)$input)+1);
- strcpy((char *)$1, (const char *)$input);
- } else {
- $1 = 0;
- }
-}
-%typemap(globalin,fragment="<string.h>") char * {
- free($1);
- if ($input) {
- $1 = ($1_type) malloc(strlen((const char *)$input)+1);
- strcpy((char *)$1, (const char *)$input);
- } else {
- $1 = 0;
- }
-}
-%typemap(globalin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="<string.h>") const char * {
- if ($input) {
- $1 = ($1_type) malloc(strlen((const char *)$input)+1);
- strcpy((char *)$1, (const char *)$input);
- } else {
- $1 = 0;
- }
-}
-
-#endif
-
-/* Character array handling */
-
-%typemap(memberin,fragment="<string.h>") char [ANY] {
- if($input) {
- strncpy((char*)$1, (const char *)$input, $1_dim0-1);
- $1[$1_dim0-1] = 0;
- } else {
- $1[0] = 0;
- }
-}
-
-%typemap(globalin,fragment="<string.h>") char [ANY] {
- if($input) {
- strncpy((char*)$1, (const char *)$input, $1_dim0-1);
- $1[$1_dim0-1] = 0;
- } else {
- $1[0] = 0;
- }
-}
-
-%typemap(memberin,fragment="<string.h>") char [] {
- if ($input) strcpy((char *)$1, (const char *)$input);
- else $1[0] = 0;
-}
-
-%typemap(globalin,fragment="<string.h>") char [] {
- if ($input) strcpy((char *)$1, (const char *)$input);
- else $1[0] = 0;
-}
-
-/* memberin/globalin typemap for arrays. */
-
-%typemap(memberin,fragment="<string.h>") SWIGTYPE [ANY] {
- size_t ii;
- $1_basetype *b = ($1_basetype *) $1;
- for (ii = 0; ii < (size_t)$1_size; ii++) b[ii] = *(($1_basetype *) $input + ii);
-}
-
-%typemap(globalin,fragment="<string.h>") SWIGTYPE [ANY] {
- size_t ii;
- $1_basetype *b = ($1_basetype *) $1;
- for (ii = 0; ii < (size_t)$1_size; ii++) b[ii] = *(($1_basetype *) $input + ii);
-}
-
-/* memberin/globalin typemap for double arrays. */
-
-%typemap(memberin,fragment="<string.h>") SWIGTYPE [ANY][ANY] {
- $basetype (*inp)[$1_dim1] = ($basetype (*)[$1_dim1])($input);
- $basetype (*dest)[$1_dim1] = ($basetype (*)[$1_dim1])($1);
- size_t ii = 0;
- for (; ii < $1_dim0; ++ii) {
- $basetype *ip = inp[ii];
- $basetype *dp = dest[ii];
- size_t jj = 0;
- for (; jj < $1_dim1; ++jj) dp[jj] = ip[jj];
- }
-}
-
-%typemap(globalin,fragment="<string.h>") SWIGTYPE [ANY][ANY] {
- $basetype (*inp)[$1_dim1] = ($basetype (*)[$1_dim1])($input);
- $basetype (*dest)[$1_dim1] = ($basetype (*)[$1_dim1])($1);
- size_t ii = 0;
- for (; ii < $1_dim0; ++ii) {
- $basetype *ip = inp[ii];
- $basetype *dp = dest[ii];
- size_t jj = 0;
- for (; jj < $1_dim1; ++jj) dp[jj] = ip[jj];
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Runtime code
- * ----------------------------------------------------------------------------- */
-
-
-%insert("runtime") "swiglabels.swg"
-
-
-/* The SwigValueWrapper class */
-
-/*
- * This template wrapper is used to handle C++ objects that are passed or
- * returned by value. This is necessary to handle objects that define
- * no default-constructor (making it difficult for SWIG to properly declare
- * local variables).
- *
- * The wrapper is used as follows. First consider a function like this:
- *
- * Vector cross_product(Vector a, Vector b)
- *
- * Now, if Vector is defined as a C++ class with no default constructor,
- * code is generated as follows:
- *
- * Vector *wrap_cross_product(Vector *inarg1, Vector *inarg2) {
- * SwigValueWrapper<Vector> arg1;
- * SwigValueWrapper<Vector> arg2;
- * SwigValueWrapper<Vector> result;
- *
- * arg1 = *inarg1;
- * arg2 = *inarg2;
- * ...
- * result = cross_product(arg1,arg2);
- * ...
- * return new Vector(result);
- * }
- *
- * In the wrappers, the template SwigValueWrapper simply provides a thin
- * layer around a Vector *. However, it does this in a way that allows
- * the object to be bound after the variable declaration (which is not possible
- * with the bare object when it lacks a default constructor).
- *
- * An observant reader will notice that the code after the variable declarations
- * is *identical* to the code used for classes that do define default constructors.
- * Thus, this neat trick allows us to fix this special case without having to
- * make massive changes to typemaps and other parts of the SWIG code generator.
- *
- * Note: this code is not included when SWIG runs in C-mode, when classes
- * define default constructors, or when pointers and references are used.
- * SWIG tries to avoid doing this except in very special circumstances.
- *
- * Note: This solution suffers from making a large number of copies
- * of the underlying object. However, this is needed in the interest of
- * safety and in order to cover all of the possible ways in which a value
- * might be assigned. For example:
- *
- * arg1 = *inarg1; // Assignment from a pointer
- * arg1 = Vector(1,2,3); // Assignment from a value
- *
- * SwigValueWrapper is a drop in replacement to modify normal value semantics by
- * using the heap instead of the stack to copy/move the underlying object it is
- * managing. Smart pointers also manage an underlying object on the heap, so
- * SwigValueWrapper has characteristics of a smart pointer. The reset function
- * is specific smart pointer functionality, but cannot be a non-static member as
- * when SWIG modifies typemap code it assumes non-static member function calls
- * are routed to the underlying object, changing for example $1.f() to (&x)->f().
- * The reset function was added as an optimisation to avoid some copying/moving
- * and to take ownership of an object already created on the heap.
- *
- * The class offers a strong guarantee of exception safety.
- * With regards to the implementation, the private SwigSmartPointer nested class is
- * a simple smart pointer providing exception safety, much like std::auto_ptr.
- *
- * This wrapping technique was suggested by William Fulton and is henceforth
- * known as the "Fulton Transform" :-).
- */
-
-#ifdef __cplusplus
-// Placed in the header section to ensure the language specific header files are
-// the first included headers and not <utility>
-%insert("header") %{
-#ifdef __cplusplus
-#include <utility>
-/* SwigValueWrapper is described in swig.swg */
-template<typename T> class SwigValueWrapper {
- struct SwigSmartPointer {
- T *ptr;
- SwigSmartPointer(T *p) : ptr(p) { }
- ~SwigSmartPointer() { delete ptr; }
- SwigSmartPointer& operator=(SwigSmartPointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; }
- void reset(T *p) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = p; }
- } pointer;
- SwigValueWrapper& operator=(const SwigValueWrapper<T>& rhs);
- SwigValueWrapper(const SwigValueWrapper<T>& rhs);
-public:
- SwigValueWrapper() : pointer(0) { }
- SwigValueWrapper& operator=(const T& t) { SwigSmartPointer tmp(new T(t)); pointer = tmp; return *this; }
-#if __cplusplus >=201103L
- SwigValueWrapper& operator=(T&& t) { SwigSmartPointer tmp(new T(std::move(t))); pointer = tmp; return *this; }
- operator T&&() const { return std::move(*pointer.ptr); }
-#else
- operator T&() const { return *pointer.ptr; }
-#endif
- T *operator&() const { return pointer.ptr; }
- static void reset(SwigValueWrapper& t, T *p) { t.pointer.reset(p); }
-};
-
-/*
- * SwigValueInit() is a generic initialisation solution as the following approach:
- *
- * T c_result = T();
- *
- * doesn't compile for all types for example:
- *
- * unsigned int c_result = unsigned int();
- */
-template <typename T> T SwigValueInit() {
- return T();
-}
-
-#if __cplusplus >=201103L
-# define SWIG_STD_MOVE(OBJ) std::move(OBJ)
-#else
-# define SWIG_STD_MOVE(OBJ) OBJ
-#endif
-
-#endif
-%}
-#endif
-
diff --git a/contrib/tools/swig/Lib/swigerrors.swg b/contrib/tools/swig/Lib/swigerrors.swg
deleted file mode 100644
index 4d5a8e473d..0000000000
--- a/contrib/tools/swig/Lib/swigerrors.swg
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SWIG Errors applicable to all language modules, values are reserved from -1 to -99 */
-#define SWIG_UnknownError -1
-#define SWIG_IOError -2
-#define SWIG_RuntimeError -3
-#define SWIG_IndexError -4
-#define SWIG_TypeError -5
-#define SWIG_DivisionByZero -6
-#define SWIG_OverflowError -7
-#define SWIG_SyntaxError -8
-#define SWIG_ValueError -9
-#define SWIG_SystemError -10
-#define SWIG_AttributeError -11
-#define SWIG_MemoryError -12
-#define SWIG_NullReferenceError -13
-
diff --git a/contrib/tools/swig/Lib/swigfragments.swg b/contrib/tools/swig/Lib/swigfragments.swg
deleted file mode 100644
index 28aa1180f9..0000000000
--- a/contrib/tools/swig/Lib/swigfragments.swg
+++ /dev/null
@@ -1,90 +0,0 @@
-/* -----------------------------------------------------------------------------
- * swigfragments.swg
- *
- * Common fragments
- * ----------------------------------------------------------------------------- */
-
-/* -----------------------------------------------------------------------------
- * Fragments for C header files
- * ----------------------------------------------------------------------------- */
-
-%fragment("<float.h>", "header") %{
-#include <float.h>
-%}
-
-/* Default compiler options for gcc allow long_long but not LLONG_MAX.
- * Define SWIG_NO_LLONG_MAX if this added limits support is not wanted. */
-%fragment("<limits.h>", "header") %{
-#include <limits.h>
-#if !defined(SWIG_NO_LLONG_MAX)
-# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__)
-# define LLONG_MAX __LONG_LONG_MAX__
-# define LLONG_MIN (-LLONG_MAX - 1LL)
-# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
-# endif
-#endif
-%}
-
-%fragment("<math.h>", "header") %{
-#include <math.h>
-%}
-
-%fragment("<string.h>", "header") %{
-#include <string.h>
-%}
-
-%fragment("<stddef.h>", "header") %{
-#include <stddef.h>
-%}
-
-%fragment("<stdio.h>", "header") %{
-#include <stdio.h>
-#if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__BORLANDC__) || defined(_WATCOM)
-# ifndef snprintf
-# define snprintf _snprintf
-# endif
-#endif
-%}
-
-%fragment("<stdlib.h>", "header") %{
-#include <stdlib.h>
-#ifdef _MSC_VER
-# ifndef strtoull
-# define strtoull _strtoui64
-# endif
-# ifndef strtoll
-# define strtoll _strtoi64
-# endif
-#endif
-%}
-
-%fragment("<wchar.h>", "header") %{
-#include <wchar.h>
-#include <limits.h>
-#ifndef WCHAR_MIN
-# define WCHAR_MIN 0
-#endif
-#ifndef WCHAR_MAX
-# define WCHAR_MAX 65535
-#endif
-%}
-
-/* -----------------------------------------------------------------------------
- * Fragments for C++ header files
- * ----------------------------------------------------------------------------- */
-
-%fragment("<algorithm>", "header") %{
-#include <algorithm>
-%}
-
-%fragment("<stdexcept>", "header") %{
-#include <stdexcept>
-%}
-
-%fragment("<string>", "header") %{
-#include <string>
-%}
-
-%fragment("<memory>", "header") %{
-#include <memory>
-%}
diff --git a/contrib/tools/swig/Lib/swiginit.swg b/contrib/tools/swig/Lib/swiginit.swg
deleted file mode 100644
index e50b1b46dc..0000000000
--- a/contrib/tools/swig/Lib/swiginit.swg
+++ /dev/null
@@ -1,233 +0,0 @@
-/* -----------------------------------------------------------------------------
- * Type initialization:
- * This problem is tough by the requirement that no dynamic
- * memory is used. Also, since swig_type_info structures store pointers to
- * swig_cast_info structures and swig_cast_info structures store pointers back
- * to swig_type_info structures, we need some lookup code at initialization.
- * The idea is that swig generates all the structures that are needed.
- * The runtime then collects these partially filled structures.
- * The SWIG_InitializeModule function takes these initial arrays out of
- * swig_module, and does all the lookup, filling in the swig_module.types
- * array with the correct data and linking the correct swig_cast_info
- * structures together.
- *
- * The generated swig_type_info structures are assigned statically to an initial
- * array. We just loop through that array, and handle each type individually.
- * First we lookup if this type has been already loaded, and if so, use the
- * loaded structure instead of the generated one. Then we have to fill in the
- * cast linked list. The cast data is initially stored in something like a
- * two-dimensional array. Each row corresponds to a type (there are the same
- * number of rows as there are in the swig_type_initial array). Each entry in
- * a column is one of the swig_cast_info structures for that type.
- * The cast_initial array is actually an array of arrays, because each row has
- * a variable number of columns. So to actually build the cast linked list,
- * we find the array of casts associated with the type, and loop through it
- * adding the casts to the list. The one last trick we need to do is making
- * sure the type pointer in the swig_cast_info struct is correct.
- *
- * First off, we lookup the cast->type name to see if it is already loaded.
- * There are three cases to handle:
- * 1) If the cast->type has already been loaded AND the type we are adding
- * casting info to has not been loaded (it is in this module), THEN we
- * replace the cast->type pointer with the type pointer that has already
- * been loaded.
- * 2) If BOTH types (the one we are adding casting info to, and the
- * cast->type) are loaded, THEN the cast info has already been loaded by
- * the previous module so we just ignore it.
- * 3) Finally, if cast->type has not already been loaded, then we add that
- * swig_cast_info to the linked list (because the cast->type) pointer will
- * be correct.
- * ----------------------------------------------------------------------------- */
-
-#ifdef __cplusplus
-extern "C" {
-#if 0
-} /* c-mode */
-#endif
-#endif
-
-#if 0
-#define SWIGRUNTIME_DEBUG
-#endif
-
-#ifndef SWIG_INIT_CLIENT_DATA_TYPE
-#define SWIG_INIT_CLIENT_DATA_TYPE void *
-#endif
-
-SWIGRUNTIME void
-SWIG_InitializeModule(SWIG_INIT_CLIENT_DATA_TYPE clientdata) {
- size_t i;
- swig_module_info *module_head, *iter;
- int init;
-
- /* check to see if the circular list has been setup, if not, set it up */
- if (swig_module.next==0) {
- /* Initialize the swig_module */
- swig_module.type_initial = swig_type_initial;
- swig_module.cast_initial = swig_cast_initial;
- swig_module.next = &swig_module;
- init = 1;
- } else {
- init = 0;
- }
-
- /* Try and load any already created modules */
- module_head = SWIG_GetModule(clientdata);
- if (!module_head) {
- /* This is the first module loaded for this interpreter */
- /* so set the swig module into the interpreter */
- SWIG_SetModule(clientdata, &swig_module);
- } else {
- /* the interpreter has loaded a SWIG module, but has it loaded this one? */
- iter=module_head;
- do {
- if (iter==&swig_module) {
- /* Our module is already in the list, so there's nothing more to do. */
- return;
- }
- iter=iter->next;
- } while (iter!= module_head);
-
- /* otherwise we must add our module into the list */
- swig_module.next = module_head->next;
- module_head->next = &swig_module;
- }
-
- /* When multiple interpreters are used, a module could have already been initialized in
- a different interpreter, but not yet have a pointer in this interpreter.
- In this case, we do not want to continue adding types... everything should be
- set up already */
- if (init == 0) return;
-
- /* Now work on filling in swig_module.types */
-#ifdef SWIGRUNTIME_DEBUG
- printf("SWIG_InitializeModule: size %lu\n", (unsigned long)swig_module.size);
-#endif
- for (i = 0; i < swig_module.size; ++i) {
- swig_type_info *type = 0;
- swig_type_info *ret;
- swig_cast_info *cast;
-
-#ifdef SWIGRUNTIME_DEBUG
- printf("SWIG_InitializeModule: type %lu %s\n", (unsigned long)i, swig_module.type_initial[i]->name);
-#endif
-
- /* if there is another module already loaded */
- if (swig_module.next != &swig_module) {
- type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name);
- }
- if (type) {
- /* Overwrite clientdata field */
-#ifdef SWIGRUNTIME_DEBUG
- printf("SWIG_InitializeModule: found type %s\n", type->name);
-#endif
- if (swig_module.type_initial[i]->clientdata) {
- type->clientdata = swig_module.type_initial[i]->clientdata;
-#ifdef SWIGRUNTIME_DEBUG
- printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name);
-#endif
- }
- } else {
- type = swig_module.type_initial[i];
- }
-
- /* Insert casting types */
- cast = swig_module.cast_initial[i];
- while (cast->type) {
-
- /* Don't need to add information already in the list */
- ret = 0;
-#ifdef SWIGRUNTIME_DEBUG
- printf("SWIG_InitializeModule: look cast %s\n", cast->type->name);
-#endif
- if (swig_module.next != &swig_module) {
- ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name);
-#ifdef SWIGRUNTIME_DEBUG
- if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name);
-#endif
- }
- if (ret) {
- if (type == swig_module.type_initial[i]) {
-#ifdef SWIGRUNTIME_DEBUG
- printf("SWIG_InitializeModule: skip old type %s\n", ret->name);
-#endif
- cast->type = ret;
- ret = 0;
- } else {
- /* Check for casting already in the list */
- swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type);
-#ifdef SWIGRUNTIME_DEBUG
- if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name);
-#endif
- if (!ocast) ret = 0;
- }
- }
-
- if (!ret) {
-#ifdef SWIGRUNTIME_DEBUG
- printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name);
-#endif
- if (type->cast) {
- type->cast->prev = cast;
- cast->next = type->cast;
- }
- type->cast = cast;
- }
- cast++;
- }
- /* Set entry in modules->types array equal to the type */
- swig_module.types[i] = type;
- }
- swig_module.types[i] = 0;
-
-#ifdef SWIGRUNTIME_DEBUG
- printf("**** SWIG_InitializeModule: Cast List ******\n");
- for (i = 0; i < swig_module.size; ++i) {
- int j = 0;
- swig_cast_info *cast = swig_module.cast_initial[i];
- printf("SWIG_InitializeModule: type %lu %s\n", (unsigned long)i, swig_module.type_initial[i]->name);
- while (cast->type) {
- printf("SWIG_InitializeModule: cast type %s\n", cast->type->name);
- cast++;
- ++j;
- }
- printf("---- Total casts: %d\n",j);
- }
- printf("**** SWIG_InitializeModule: Cast List ******\n");
-#endif
-}
-
-/* This function will propagate the clientdata field of type to
-* any new swig_type_info structures that have been added into the list
-* of equivalent types. It is like calling
-* SWIG_TypeClientData(type, clientdata) a second time.
-*/
-SWIGRUNTIME void
-SWIG_PropagateClientData(void) {
- size_t i;
- swig_cast_info *equiv;
- static int init_run = 0;
-
- if (init_run) return;
- init_run = 1;
-
- for (i = 0; i < swig_module.size; i++) {
- if (swig_module.types[i]->clientdata) {
- equiv = swig_module.types[i]->cast;
- while (equiv) {
- if (!equiv->converter) {
- if (equiv->type && !equiv->type->clientdata)
- SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata);
- }
- equiv = equiv->next;
- }
- }
- }
-}
-
-#ifdef __cplusplus
-#if 0
-{ /* c-mode */
-#endif
-}
-#endif
diff --git a/contrib/tools/swig/Lib/swiglabels.swg b/contrib/tools/swig/Lib/swiglabels.swg
deleted file mode 100644
index b3855665e2..0000000000
--- a/contrib/tools/swig/Lib/swiglabels.swg
+++ /dev/null
@@ -1,123 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This section contains generic SWIG labels for method/variable
- * declarations/attributes, and other compiler dependent labels.
- * ----------------------------------------------------------------------------- */
-
-/* template workaround for compilers that cannot correctly implement the C++ standard */
-#ifndef SWIGTEMPLATEDISAMBIGUATOR
-# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560)
-# define SWIGTEMPLATEDISAMBIGUATOR template
-# elif defined(__HP_aCC)
-/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */
-/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */
-# define SWIGTEMPLATEDISAMBIGUATOR template
-# else
-# define SWIGTEMPLATEDISAMBIGUATOR
-# endif
-#endif
-
-/* inline attribute */
-#ifndef SWIGINLINE
-# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__))
-# define SWIGINLINE inline
-# else
-# define SWIGINLINE
-# endif
-#endif
-
-/* attribute recognised by some compilers to avoid 'unused' warnings */
-#ifndef SWIGUNUSED
-# if defined(__GNUC__)
-# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
-# define SWIGUNUSED __attribute__ ((__unused__))
-# else
-# define SWIGUNUSED
-# endif
-# elif defined(__ICC)
-# define SWIGUNUSED __attribute__ ((__unused__))
-# else
-# define SWIGUNUSED
-# endif
-#endif
-
-#ifndef SWIG_MSC_UNSUPPRESS_4505
-# if defined(_MSC_VER)
-# pragma warning(disable : 4505) /* unreferenced local function has been removed */
-# endif
-#endif
-
-#ifndef SWIGUNUSEDPARM
-# ifdef __cplusplus
-# define SWIGUNUSEDPARM(p)
-# else
-# define SWIGUNUSEDPARM(p) p SWIGUNUSED
-# endif
-#endif
-
-/* internal SWIG method */
-#ifndef SWIGINTERN
-# define SWIGINTERN static SWIGUNUSED
-#endif
-
-/* internal inline SWIG method */
-#ifndef SWIGINTERNINLINE
-# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE
-#endif
-
-/* exporting methods */
-#if defined(__GNUC__)
-# if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
-# ifndef GCC_HASCLASSVISIBILITY
-# define GCC_HASCLASSVISIBILITY
-# endif
-# endif
-#endif
-
-#ifndef SWIGEXPORT
-# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
-# if defined(STATIC_LINKED)
-# define SWIGEXPORT
-# else
-# define SWIGEXPORT __declspec(dllexport)
-# endif
-# else
-# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)
-# define SWIGEXPORT __attribute__ ((visibility("default")))
-# else
-# define SWIGEXPORT
-# endif
-# endif
-#endif
-
-/* calling conventions for Windows */
-#ifndef SWIGSTDCALL
-# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
-# define SWIGSTDCALL __stdcall
-# else
-# define SWIGSTDCALL
-# endif
-#endif
-
-/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
-#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
-# define _CRT_SECURE_NO_DEPRECATE
-#endif
-
-/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */
-#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE)
-# define _SCL_SECURE_NO_DEPRECATE
-#endif
-
-/* Deal with Apple's deprecated 'AssertMacros.h' from Carbon-framework */
-#if defined(__APPLE__) && !defined(__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES)
-# define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0
-#endif
-
-/* Intel's compiler complains if a variable which was never initialised is
- * cast to void, which is a common idiom which we use to indicate that we
- * are aware a variable isn't used. So we just silence that warning.
- * See: https://github.com/swig/swig/issues/192 for more discussion.
- */
-#ifdef __INTEL_COMPILER
-# pragma warning disable 592
-#endif
diff --git a/contrib/tools/swig/Lib/swigrun.swg b/contrib/tools/swig/Lib/swigrun.swg
deleted file mode 100644
index f632c4cb6d..0000000000
--- a/contrib/tools/swig/Lib/swigrun.swg
+++ /dev/null
@@ -1,581 +0,0 @@
-/* -----------------------------------------------------------------------------
- * swigrun.swg
- *
- * This file contains generic C API SWIG runtime support for pointer
- * type checking.
- * ----------------------------------------------------------------------------- */
-
-/* This should only be incremented when either the layout of swig_type_info changes,
- or for whatever reason, the runtime changes incompatibly */
-#define SWIG_RUNTIME_VERSION "4"
-
-/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */
-#ifdef SWIG_TYPE_TABLE
-# define SWIG_QUOTE_STRING(x) #x
-# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x)
-# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE)
-#else
-# define SWIG_TYPE_TABLE_NAME
-#endif
-
-/*
- You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for
- creating a static or dynamic library from the SWIG runtime code.
- In 99.9% of the cases, SWIG just needs to declare them as 'static'.
-
- But only do this if strictly necessary, ie, if you have problems
- with your compiler or suchlike.
-*/
-
-#ifndef SWIGRUNTIME
-# define SWIGRUNTIME SWIGINTERN
-#endif
-
-#ifndef SWIGRUNTIMEINLINE
-# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE
-#endif
-
-/* Generic buffer size */
-#ifndef SWIG_BUFFER_SIZE
-# define SWIG_BUFFER_SIZE 1024
-#endif
-
-/* Flags for pointer conversions */
-#define SWIG_POINTER_DISOWN 0x1
-#define SWIG_CAST_NEW_MEMORY 0x2
-#define SWIG_POINTER_NO_NULL 0x4
-#define SWIG_POINTER_CLEAR 0x8
-#define SWIG_POINTER_RELEASE (SWIG_POINTER_CLEAR | SWIG_POINTER_DISOWN)
-
-/* Flags for new pointer objects */
-#define SWIG_POINTER_OWN 0x1
-
-
-/*
- Flags/methods for returning states.
-
- The SWIG conversion methods, as ConvertPtr, return an integer
- that tells if the conversion was successful or not. And if not,
- an error code can be returned (see swigerrors.swg for the codes).
-
- Use the following macros/flags to set or process the returning
- states.
-
- In old versions of SWIG, code such as the following was usually written:
-
- if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) {
- // success code
- } else {
- //fail code
- }
-
- Now you can be more explicit:
-
- int res = SWIG_ConvertPtr(obj,vptr,ty.flags);
- if (SWIG_IsOK(res)) {
- // success code
- } else {
- // fail code
- }
-
- which is the same really, but now you can also do
-
- Type *ptr;
- int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags);
- if (SWIG_IsOK(res)) {
- // success code
- if (SWIG_IsNewObj(res) {
- ...
- delete *ptr;
- } else {
- ...
- }
- } else {
- // fail code
- }
-
- I.e., now SWIG_ConvertPtr can return new objects and you can
- identify the case and take care of the deallocation. Of course that
- also requires SWIG_ConvertPtr to return new result values, such as
-
- int SWIG_ConvertPtr(obj, ptr,...) {
- if (<obj is ok>) {
- if (<need new object>) {
- *ptr = <ptr to new allocated object>;
- return SWIG_NEWOBJ;
- } else {
- *ptr = <ptr to old object>;
- return SWIG_OLDOBJ;
- }
- } else {
- return SWIG_BADOBJ;
- }
- }
-
- Of course, returning the plain '0(success)/-1(fail)' still works, but you can be
- more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the
- SWIG errors code.
-
- Finally, if the SWIG_CASTRANK_MODE is enabled, the result code
- allows returning the 'cast rank', for example, if you have this
-
- int food(double)
- int fooi(int);
-
- and you call
-
- food(1) // cast rank '1' (1 -> 1.0)
- fooi(1) // cast rank '0'
-
- just use the SWIG_AddCast()/SWIG_CheckState()
-*/
-
-#define SWIG_OK (0)
-/* Runtime errors are < 0 */
-#define SWIG_ERROR (-1)
-/* Errors in range -1 to -99 are in swigerrors.swg (errors for all languages including those not using the runtime) */
-/* Errors in range -100 to -199 are language specific errors defined in *errors.swg */
-/* Errors < -200 are generic runtime specific errors */
-#define SWIG_ERROR_RELEASE_NOT_OWNED (-200)
-
-#define SWIG_IsOK(r) (r >= 0)
-#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError)
-
-/* The CastRankLimit says how many bits are used for the cast rank */
-#define SWIG_CASTRANKLIMIT (1 << 8)
-/* The NewMask denotes the object was created (using new/malloc) */
-#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1)
-/* The TmpMask is for in/out typemaps that use temporal objects */
-#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1)
-/* Simple returning values */
-#define SWIG_BADOBJ (SWIG_ERROR)
-#define SWIG_OLDOBJ (SWIG_OK)
-#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK)
-#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK)
-/* Check, add and del object mask methods */
-#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r)
-#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r)
-#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK))
-#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r)
-#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r)
-#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK))
-
-/* Cast-Rank Mode */
-#if defined(SWIG_CASTRANK_MODE)
-# ifndef SWIG_TypeRank
-# define SWIG_TypeRank unsigned long
-# endif
-# ifndef SWIG_MAXCASTRANK /* Default cast allowed */
-# define SWIG_MAXCASTRANK (2)
-# endif
-# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1)
-# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK)
-SWIGINTERNINLINE int SWIG_AddCast(int r) {
- return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r;
-}
-SWIGINTERNINLINE int SWIG_CheckState(int r) {
- return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0;
-}
-#else /* no cast-rank mode */
-# define SWIG_AddCast(r) (r)
-# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0)
-#endif
-
-
-#include <string.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef void *(*swig_converter_func)(void *, int *);
-typedef struct swig_type_info *(*swig_dycast_func)(void **);
-
-/* Structure to store information on one type */
-typedef struct swig_type_info {
- const char *name; /* mangled name of this type */
- const char *str; /* human readable name of this type */
- swig_dycast_func dcast; /* dynamic cast function down a hierarchy */
- struct swig_cast_info *cast; /* linked list of types that can cast into this type */
- void *clientdata; /* language specific type data */
- int owndata; /* flag if the structure owns the clientdata */
-} swig_type_info;
-
-/* Structure to store a type and conversion function used for casting */
-typedef struct swig_cast_info {
- swig_type_info *type; /* pointer to type that is equivalent to this type */
- swig_converter_func converter; /* function to cast the void pointers */
- struct swig_cast_info *next; /* pointer to next cast in linked list */
- struct swig_cast_info *prev; /* pointer to the previous cast */
-} swig_cast_info;
-
-/* Structure used to store module information
- * Each module generates one structure like this, and the runtime collects
- * all of these structures and stores them in a circularly linked list.*/
-typedef struct swig_module_info {
- swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */
- size_t size; /* Number of types in this module */
- struct swig_module_info *next; /* Pointer to next element in circularly linked list */
- swig_type_info **type_initial; /* Array of initially generated type structures */
- swig_cast_info **cast_initial; /* Array of initially generated casting structures */
- void *clientdata; /* Language specific module data */
-} swig_module_info;
-
-/*
- Compare two type names skipping the space characters, therefore
- "char*" == "char *" and "Class<int>" == "Class<int >", etc.
-
- Return 0 when the two name types are equivalent, as in
- strncmp, but skipping ' '.
-*/
-SWIGRUNTIME int
-SWIG_TypeNameComp(const char *f1, const char *l1,
- const char *f2, const char *l2) {
- for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) {
- while ((*f1 == ' ') && (f1 != l1)) ++f1;
- while ((*f2 == ' ') && (f2 != l2)) ++f2;
- if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1;
- }
- return (int)((l1 - f1) - (l2 - f2));
-}
-
-/*
- Check type equivalence in a name list like <name1>|<name2>|...
- Return 0 if equal, -1 if nb < tb, 1 if nb > tb
-*/
-SWIGRUNTIME int
-SWIG_TypeCmp(const char *nb, const char *tb) {
- int equiv = 1;
- const char* te = tb + strlen(tb);
- const char* ne = nb;
- while (equiv != 0 && *ne) {
- for (nb = ne; *ne; ++ne) {
- if (*ne == '|') break;
- }
- equiv = SWIG_TypeNameComp(nb, ne, tb, te);
- if (*ne) ++ne;
- }
- return equiv;
-}
-
-/*
- Check type equivalence in a name list like <name1>|<name2>|...
- Return 0 if not equal, 1 if equal
-*/
-SWIGRUNTIME int
-SWIG_TypeEquiv(const char *nb, const char *tb) {
- return SWIG_TypeCmp(nb, tb) == 0 ? 1 : 0;
-}
-
-/*
- Check the typename
-*/
-SWIGRUNTIME swig_cast_info *
-SWIG_TypeCheck(const char *c, swig_type_info *ty) {
- if (ty) {
- swig_cast_info *iter = ty->cast;
- while (iter) {
- if (strcmp(iter->type->name, c) == 0) {
- if (iter == ty->cast)
- return iter;
- /* Move iter to the top of the linked list */
- iter->prev->next = iter->next;
- if (iter->next)
- iter->next->prev = iter->prev;
- iter->next = ty->cast;
- iter->prev = 0;
- if (ty->cast) ty->cast->prev = iter;
- ty->cast = iter;
- return iter;
- }
- iter = iter->next;
- }
- }
- return 0;
-}
-
-/*
- Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison
-*/
-SWIGRUNTIME swig_cast_info *
-SWIG_TypeCheckStruct(const swig_type_info *from, swig_type_info *ty) {
- if (ty) {
- swig_cast_info *iter = ty->cast;
- while (iter) {
- if (iter->type == from) {
- if (iter == ty->cast)
- return iter;
- /* Move iter to the top of the linked list */
- iter->prev->next = iter->next;
- if (iter->next)
- iter->next->prev = iter->prev;
- iter->next = ty->cast;
- iter->prev = 0;
- if (ty->cast) ty->cast->prev = iter;
- ty->cast = iter;
- return iter;
- }
- iter = iter->next;
- }
- }
- return 0;
-}
-
-/*
- Cast a pointer up an inheritance hierarchy
-*/
-SWIGRUNTIMEINLINE void *
-SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) {
- return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory);
-}
-
-/*
- Dynamic pointer casting. Down an inheritance hierarchy
-*/
-SWIGRUNTIME swig_type_info *
-SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) {
- swig_type_info *lastty = ty;
- if (!ty || !ty->dcast) return ty;
- while (ty && (ty->dcast)) {
- ty = (*ty->dcast)(ptr);
- if (ty) lastty = ty;
- }
- return lastty;
-}
-
-/*
- Return the name associated with this type
-*/
-SWIGRUNTIMEINLINE const char *
-SWIG_TypeName(const swig_type_info *ty) {
- return ty->name;
-}
-
-/*
- Return the pretty name associated with this type,
- that is an unmangled type name in a form presentable to the user.
-*/
-SWIGRUNTIME const char *
-SWIG_TypePrettyName(const swig_type_info *type) {
- /* The "str" field contains the equivalent pretty names of the
- type, separated by vertical-bar characters. Choose the last
- name. It should be the most specific; a fully resolved name
- but not necessarily with default template parameters expanded. */
- if (!type) return NULL;
- if (type->str != NULL) {
- const char *last_name = type->str;
- const char *s;
- for (s = type->str; *s; s++)
- if (*s == '|') last_name = s+1;
- return last_name;
- }
- else
- return type->name;
-}
-
-/*
- Set the clientdata field for a type
-*/
-SWIGRUNTIME void
-SWIG_TypeClientData(swig_type_info *ti, void *clientdata) {
- swig_cast_info *cast = ti->cast;
- /* if (ti->clientdata == clientdata) return; */
- ti->clientdata = clientdata;
-
- while (cast) {
- if (!cast->converter) {
- swig_type_info *tc = cast->type;
- if (!tc->clientdata) {
- SWIG_TypeClientData(tc, clientdata);
- }
- }
- cast = cast->next;
- }
-}
-SWIGRUNTIME void
-SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) {
- SWIG_TypeClientData(ti, clientdata);
- ti->owndata = 1;
-}
-
-/*
- Search for a swig_type_info structure only by mangled name
- Search is a O(log #types)
-
- We start searching at module start, and finish searching when start == end.
- Note: if start == end at the beginning of the function, we go all the way around
- the circular list.
-*/
-SWIGRUNTIME swig_type_info *
-SWIG_MangledTypeQueryModule(swig_module_info *start,
- swig_module_info *end,
- const char *name) {
- swig_module_info *iter = start;
- do {
- if (iter->size) {
- size_t l = 0;
- size_t r = iter->size - 1;
- do {
- /* since l+r >= 0, we can (>> 1) instead (/ 2) */
- size_t i = (l + r) >> 1;
- const char *iname = iter->types[i]->name;
- if (iname) {
- int compare = strcmp(name, iname);
- if (compare == 0) {
- return iter->types[i];
- } else if (compare < 0) {
- if (i) {
- r = i - 1;
- } else {
- break;
- }
- } else if (compare > 0) {
- l = i + 1;
- }
- } else {
- break; /* should never happen */
- }
- } while (l <= r);
- }
- iter = iter->next;
- } while (iter != end);
- return 0;
-}
-
-/*
- Search for a swig_type_info structure for either a mangled name or a human readable name.
- It first searches the mangled names of the types, which is a O(log #types)
- If a type is not found it then searches the human readable names, which is O(#types).
-
- We start searching at module start, and finish searching when start == end.
- Note: if start == end at the beginning of the function, we go all the way around
- the circular list.
-*/
-SWIGRUNTIME swig_type_info *
-SWIG_TypeQueryModule(swig_module_info *start,
- swig_module_info *end,
- const char *name) {
- /* STEP 1: Search the name field using binary search */
- swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name);
- if (ret) {
- return ret;
- } else {
- /* STEP 2: If the type hasn't been found, do a complete search
- of the str field (the human readable name) */
- swig_module_info *iter = start;
- do {
- size_t i = 0;
- for (; i < iter->size; ++i) {
- if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name)))
- return iter->types[i];
- }
- iter = iter->next;
- } while (iter != end);
- }
-
- /* neither found a match */
- return 0;
-}
-
-/*
- Pack binary data into a string
-*/
-SWIGRUNTIME char *
-SWIG_PackData(char *c, void *ptr, size_t sz) {
- static const char hex[17] = "0123456789abcdef";
- const unsigned char *u = (unsigned char *) ptr;
- const unsigned char *eu = u + sz;
- for (; u != eu; ++u) {
- unsigned char uu = *u;
- *(c++) = hex[(uu & 0xf0) >> 4];
- *(c++) = hex[uu & 0xf];
- }
- return c;
-}
-
-/*
- Unpack binary data from a string
-*/
-SWIGRUNTIME const char *
-SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
- unsigned char *u = (unsigned char *) ptr;
- const unsigned char *eu = u + sz;
- for (; u != eu; ++u) {
- char d = *(c++);
- unsigned char uu;
- if ((d >= '0') && (d <= '9'))
- uu = (unsigned char)((d - '0') << 4);
- else if ((d >= 'a') && (d <= 'f'))
- uu = (unsigned char)((d - ('a'-10)) << 4);
- else
- return (char *) 0;
- d = *(c++);
- if ((d >= '0') && (d <= '9'))
- uu |= (unsigned char)(d - '0');
- else if ((d >= 'a') && (d <= 'f'))
- uu |= (unsigned char)(d - ('a'-10));
- else
- return (char *) 0;
- *u = uu;
- }
- return c;
-}
-
-/*
- Pack 'void *' into a string buffer.
-*/
-SWIGRUNTIME char *
-SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) {
- char *r = buff;
- if ((2*sizeof(void *) + 2) > bsz) return 0;
- *(r++) = '_';
- r = SWIG_PackData(r,&ptr,sizeof(void *));
- if (strlen(name) + 1 > (bsz - (r - buff))) return 0;
- strcpy(r,name);
- return buff;
-}
-
-SWIGRUNTIME const char *
-SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) {
- if (*c != '_') {
- if (strcmp(c,"NULL") == 0) {
- *ptr = (void *) 0;
- return name;
- } else {
- return 0;
- }
- }
- return SWIG_UnpackData(++c,ptr,sizeof(void *));
-}
-
-SWIGRUNTIME char *
-SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) {
- char *r = buff;
- size_t lname = (name ? strlen(name) : 0);
- if ((2*sz + 2 + lname) > bsz) return 0;
- *(r++) = '_';
- r = SWIG_PackData(r,ptr,sz);
- if (lname) {
- strncpy(r,name,lname+1);
- } else {
- *r = 0;
- }
- return buff;
-}
-
-SWIGRUNTIME const char *
-SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) {
- if (*c != '_') {
- if (strcmp(c,"NULL") == 0) {
- memset(ptr,0,sz);
- return name;
- } else {
- return 0;
- }
- }
- return SWIG_UnpackData(++c,ptr,sz);
-}
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/contrib/tools/swig/Lib/swigwarn.swg b/contrib/tools/swig/Lib/swigwarn.swg
deleted file mode 100644
index 6a069220ef..0000000000
--- a/contrib/tools/swig/Lib/swigwarn.swg
+++ /dev/null
@@ -1,300 +0,0 @@
-/* SWIG warning codes - generated from swigwarn.h - do not edit */
-
-
-%define SWIGWARN_NONE 0 %enddef
-
-/* -- Deprecated features -- */
-
-%define SWIGWARN_DEPRECATED_EXTERN 101 %enddef
-%define SWIGWARN_DEPRECATED_VAL 102 %enddef
-%define SWIGWARN_DEPRECATED_OUT 103 %enddef
-%define SWIGWARN_DEPRECATED_DISABLEDOC 104 %enddef
-%define SWIGWARN_DEPRECATED_ENABLEDOC 105 %enddef
-%define SWIGWARN_DEPRECATED_DOCONLY 106 %enddef
-%define SWIGWARN_DEPRECATED_STYLE 107 %enddef
-%define SWIGWARN_DEPRECATED_LOCALSTYLE 108 %enddef
-%define SWIGWARN_DEPRECATED_TITLE 109 %enddef
-%define SWIGWARN_DEPRECATED_SECTION 110 %enddef
-%define SWIGWARN_DEPRECATED_SUBSECTION 111 %enddef
-%define SWIGWARN_DEPRECATED_SUBSUBSECTION 112 %enddef
-%define SWIGWARN_DEPRECATED_ADDMETHODS 113 %enddef
-%define SWIGWARN_DEPRECATED_READONLY 114 %enddef
-%define SWIGWARN_DEPRECATED_READWRITE 115 %enddef
-%define SWIGWARN_DEPRECATED_EXCEPT 116 %enddef
-%define SWIGWARN_DEPRECATED_NEW 117 %enddef
-%define SWIGWARN_DEPRECATED_EXCEPT_TM 118 %enddef
-%define SWIGWARN_DEPRECATED_IGNORE_TM 119 %enddef
-%define SWIGWARN_DEPRECATED_OPTC 120 %enddef
-%define SWIGWARN_DEPRECATED_NAME 121 %enddef
-%define SWIGWARN_DEPRECATED_NOEXTERN 122 %enddef
-%define SWIGWARN_DEPRECATED_NODEFAULT 123 %enddef
-/* Unused since 4.1.0: #define WARN_DEPRECATED_TYPEMAP_LANG 124 */
-%define SWIGWARN_DEPRECATED_INPUT_FILE 125 %enddef
-%define SWIGWARN_DEPRECATED_NESTED_WORKAROUND 126 %enddef
-
-/* -- Preprocessor -- */
-
-%define SWIGWARN_PP_MISSING_FILE 201 %enddef
-%define SWIGWARN_PP_EVALUATION 202 %enddef
-%define SWIGWARN_PP_INCLUDEALL_IMPORTALL 203 %enddef
-%define SWIGWARN_PP_CPP_WARNING 204 %enddef
-%define SWIGWARN_PP_CPP_ERROR 205 %enddef
-%define SWIGWARN_PP_UNEXPECTED_TOKENS 206 %enddef
-
-/* -- C/C++ Parser -- */
-
-%define SWIGWARN_PARSE_CLASS_KEYWORD 301 %enddef
-%define SWIGWARN_PARSE_REDEFINED 302 %enddef
-%define SWIGWARN_PARSE_EXTEND_UNDEF 303 %enddef
-%define SWIGWARN_PARSE_UNSUPPORTED_VALUE 304 %enddef
-%define SWIGWARN_PARSE_BAD_VALUE 305 %enddef
-%define SWIGWARN_PARSE_PRIVATE 306 %enddef
-%define SWIGWARN_PARSE_BAD_DEFAULT 307 %enddef
-%define SWIGWARN_PARSE_NAMESPACE_ALIAS 308 %enddef
-%define SWIGWARN_PARSE_PRIVATE_INHERIT 309 %enddef
-%define SWIGWARN_PARSE_TEMPLATE_REPEAT 310 %enddef
-%define SWIGWARN_PARSE_TEMPLATE_PARTIAL 311 %enddef
-%define SWIGWARN_PARSE_UNNAMED_NESTED_CLASS 312 %enddef
-%define SWIGWARN_PARSE_UNDEFINED_EXTERN 313 %enddef
-%define SWIGWARN_PARSE_KEYWORD 314 %enddef
-%define SWIGWARN_PARSE_USING_UNDEF 315 %enddef
-%define SWIGWARN_PARSE_MODULE_REPEAT 316 %enddef
-%define SWIGWARN_PARSE_TEMPLATE_SP_UNDEF 317 %enddef
-%define SWIGWARN_PARSE_TEMPLATE_AMBIG 318 %enddef
-%define SWIGWARN_PARSE_NO_ACCESS 319 %enddef
-%define SWIGWARN_PARSE_EXPLICIT_TEMPLATE 320 %enddef
-%define SWIGWARN_PARSE_BUILTIN_NAME 321 %enddef
-%define SWIGWARN_PARSE_REDUNDANT 322 %enddef
-%define SWIGWARN_PARSE_REC_INHERITANCE 323 %enddef
-%define SWIGWARN_PARSE_NESTED_TEMPLATE 324 %enddef
-%define SWIGWARN_PARSE_NAMED_NESTED_CLASS 325 %enddef
-%define SWIGWARN_PARSE_EXTEND_NAME 326 %enddef
-%define SWIGWARN_PARSE_EXTERN_TEMPLATE 327 %enddef
-
-%define SWIGWARN_CPP11_LAMBDA 340 %enddef
-%define SWIGWARN_CPP11_ALIAS_DECLARATION 341 %enddef /* redundant now */
-%define SWIGWARN_CPP11_ALIAS_TEMPLATE 342 %enddef /* redundant now */
-%define SWIGWARN_CPP11_VARIADIC_TEMPLATE 343 %enddef
-
-%define SWIGWARN_IGNORE_OPERATOR_NEW 350 %enddef /* new */
-%define SWIGWARN_IGNORE_OPERATOR_DELETE 351 %enddef /* delete */
-%define SWIGWARN_IGNORE_OPERATOR_PLUS 352 %enddef /* + */
-%define SWIGWARN_IGNORE_OPERATOR_MINUS 353 %enddef /* - */
-%define SWIGWARN_IGNORE_OPERATOR_MUL 354 %enddef /* * */
-%define SWIGWARN_IGNORE_OPERATOR_DIV 355 %enddef /* / */
-%define SWIGWARN_IGNORE_OPERATOR_MOD 356 %enddef /* % */
-%define SWIGWARN_IGNORE_OPERATOR_XOR 357 %enddef /* ^ */
-%define SWIGWARN_IGNORE_OPERATOR_AND 358 %enddef /* & */
-%define SWIGWARN_IGNORE_OPERATOR_OR 359 %enddef /* | */
-%define SWIGWARN_IGNORE_OPERATOR_NOT 360 %enddef /* ~ */
-%define SWIGWARN_IGNORE_OPERATOR_LNOT 361 %enddef /* ! */
-%define SWIGWARN_IGNORE_OPERATOR_EQ 362 %enddef /* = */
-%define SWIGWARN_IGNORE_OPERATOR_LT 363 %enddef /* < */
-%define SWIGWARN_IGNORE_OPERATOR_GT 364 %enddef /* > */
-%define SWIGWARN_IGNORE_OPERATOR_PLUSEQ 365 %enddef /* += */
-%define SWIGWARN_IGNORE_OPERATOR_MINUSEQ 366 %enddef /* -= */
-%define SWIGWARN_IGNORE_OPERATOR_MULEQ 367 %enddef /* *= */
-%define SWIGWARN_IGNORE_OPERATOR_DIVEQ 368 %enddef /* /= */
-%define SWIGWARN_IGNORE_OPERATOR_MODEQ 369 %enddef /* %= */
-%define SWIGWARN_IGNORE_OPERATOR_XOREQ 370 %enddef /* ^= */
-%define SWIGWARN_IGNORE_OPERATOR_ANDEQ 371 %enddef /* &= */
-%define SWIGWARN_IGNORE_OPERATOR_OREQ 372 %enddef /* |= */
-%define SWIGWARN_IGNORE_OPERATOR_LSHIFT 373 %enddef /* << */
-%define SWIGWARN_IGNORE_OPERATOR_RSHIFT 374 %enddef /* >> */
-%define SWIGWARN_IGNORE_OPERATOR_LSHIFTEQ 375 %enddef /* <<= */
-%define SWIGWARN_IGNORE_OPERATOR_RSHIFTEQ 376 %enddef /* >>= */
-%define SWIGWARN_IGNORE_OPERATOR_EQUALTO 377 %enddef /* == */
-%define SWIGWARN_IGNORE_OPERATOR_NOTEQUAL 378 %enddef /* != */
-%define SWIGWARN_IGNORE_OPERATOR_LTEQUAL 379 %enddef /* <= */
-%define SWIGWARN_IGNORE_OPERATOR_GTEQUAL 380 %enddef /* >= */
-%define SWIGWARN_IGNORE_OPERATOR_LAND 381 %enddef /* && */
-%define SWIGWARN_IGNORE_OPERATOR_LOR 382 %enddef /* || */
-%define SWIGWARN_IGNORE_OPERATOR_PLUSPLUS 383 %enddef /* ++ */
-%define SWIGWARN_IGNORE_OPERATOR_MINUSMINUS 384 %enddef /* -- */
-%define SWIGWARN_IGNORE_OPERATOR_COMMA 385 %enddef /* , */
-%define SWIGWARN_IGNORE_OPERATOR_ARROWSTAR 386 %enddef /* ->* */
-%define SWIGWARN_IGNORE_OPERATOR_ARROW 387 %enddef /* -> */
-%define SWIGWARN_IGNORE_OPERATOR_CALL 388 %enddef /* () */
-%define SWIGWARN_IGNORE_OPERATOR_INDEX 389 %enddef /* [] */
-%define SWIGWARN_IGNORE_OPERATOR_UPLUS 390 %enddef /* + */
-%define SWIGWARN_IGNORE_OPERATOR_UMINUS 391 %enddef /* - */
-%define SWIGWARN_IGNORE_OPERATOR_UMUL 392 %enddef /* * */
-%define SWIGWARN_IGNORE_OPERATOR_UAND 393 %enddef /* & */
-%define SWIGWARN_IGNORE_OPERATOR_NEWARR 394 %enddef /* new [] */
-%define SWIGWARN_IGNORE_OPERATOR_DELARR 395 %enddef /* delete [] */
-%define SWIGWARN_IGNORE_OPERATOR_REF 396 %enddef /* operator *() */
-%define SWIGWARN_IGNORE_OPERATOR_LTEQUALGT 397 %enddef /* <=> */
-
-/* please leave 350-399 free for WARN_IGNORE_OPERATOR_* */
-
-/* -- Type system and typemaps -- */
-
-%define SWIGWARN_TYPE_UNDEFINED_CLASS 401 %enddef
-%define SWIGWARN_TYPE_INCOMPLETE 402 %enddef
-%define SWIGWARN_TYPE_ABSTRACT 403 %enddef
-%define SWIGWARN_TYPE_REDEFINED 404 %enddef
-%define SWIGWARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED 405 %enddef
-
-%define SWIGWARN_TYPEMAP_SOURCETARGET 450 %enddef /* No longer issued */
-%define SWIGWARN_TYPEMAP_CHARLEAK 451 %enddef
-%define SWIGWARN_TYPEMAP_SWIGTYPE 452 %enddef /* No longer issued */
-%define SWIGWARN_TYPEMAP_APPLY_UNDEF 453 %enddef
-%define SWIGWARN_TYPEMAP_SWIGTYPELEAK 454 %enddef
-%define SWIGWARN_TYPEMAP_WCHARLEAK 455 %enddef
-
-%define SWIGWARN_TYPEMAP_IN_UNDEF 460 %enddef
-%define SWIGWARN_TYPEMAP_OUT_UNDEF 461 %enddef
-%define SWIGWARN_TYPEMAP_VARIN_UNDEF 462 %enddef
-%define SWIGWARN_TYPEMAP_VAROUT_UNDEF 463 %enddef
-%define SWIGWARN_TYPEMAP_CONST_UNDEF 464 %enddef
-%define SWIGWARN_TYPEMAP_UNDEF 465 %enddef
-%define SWIGWARN_TYPEMAP_VAR_UNDEF 466 %enddef
-%define SWIGWARN_TYPEMAP_TYPECHECK 467 %enddef
-%define SWIGWARN_TYPEMAP_THROW 468 %enddef
-%define SWIGWARN_TYPEMAP_DIRECTORIN_UNDEF 469 %enddef
-%define SWIGWARN_TYPEMAP_THREAD_UNSAFE 470 %enddef /* mostly used in directorout typemaps */
-%define SWIGWARN_TYPEMAP_DIRECTOROUT_UNDEF 471 %enddef
-%define SWIGWARN_TYPEMAP_TYPECHECK_UNDEF 472 %enddef
-%define SWIGWARN_TYPEMAP_DIRECTOROUT_PTR 473 %enddef
-%define SWIGWARN_TYPEMAP_OUT_OPTIMAL_IGNORED 474 %enddef
-%define SWIGWARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE 475 %enddef
-%define SWIGWARN_TYPEMAP_INITIALIZER_LIST 476 %enddef
-%define SWIGWARN_TYPEMAP_DIRECTORTHROWS_UNDEF 477 %enddef
-
-/* -- Fragments -- */
-%define SWIGWARN_FRAGMENT_NOT_FOUND 490 %enddef
-
-/* -- General code generation -- */
-
-%define SWIGWARN_LANG_OVERLOAD_DECL 501 %enddef
-%define SWIGWARN_LANG_OVERLOAD_CONSTRUCT 502 %enddef
-%define SWIGWARN_LANG_IDENTIFIER 503 %enddef
-%define SWIGWARN_LANG_RETURN_TYPE 504 %enddef
-%define SWIGWARN_LANG_VARARGS 505 %enddef
-%define SWIGWARN_LANG_VARARGS_KEYWORD 506 %enddef
-%define SWIGWARN_LANG_NATIVE_UNIMPL 507 %enddef
-%define SWIGWARN_LANG_DEREF_SHADOW 508 %enddef
-%define SWIGWARN_LANG_OVERLOAD_SHADOW 509 %enddef
-%define SWIGWARN_LANG_FRIEND_IGNORE 510 %enddef
-%define SWIGWARN_LANG_OVERLOAD_KEYWORD 511 %enddef
-%define SWIGWARN_LANG_OVERLOAD_CONST 512 %enddef
-%define SWIGWARN_LANG_CLASS_UNNAMED 513 %enddef
-%define SWIGWARN_LANG_DIRECTOR_VDESTRUCT 514 %enddef
-%define SWIGWARN_LANG_DISCARD_CONST 515 %enddef
-%define SWIGWARN_LANG_OVERLOAD_IGNORED 516 %enddef
-%define SWIGWARN_LANG_DIRECTOR_ABSTRACT 517 %enddef
-%define SWIGWARN_LANG_PORTABILITY_FILENAME 518 %enddef
-%define SWIGWARN_LANG_TEMPLATE_METHOD_IGNORE 519 %enddef
-%define SWIGWARN_LANG_SMARTPTR_MISSING 520 %enddef
-%define SWIGWARN_LANG_ILLEGAL_DESTRUCTOR 521 %enddef
-%define SWIGWARN_LANG_EXTEND_CONSTRUCTOR 522 %enddef
-%define SWIGWARN_LANG_EXTEND_DESTRUCTOR 523 %enddef
-%define SWIGWARN_LANG_EXPERIMENTAL 524 %enddef
-%define SWIGWARN_LANG_DIRECTOR_FINAL 525 %enddef
-%define SWIGWARN_LANG_USING_NAME_DIFFERENT 526 %enddef
-
-/* -- Doxygen comments -- */
-
-%define SWIGWARN_DOXYGEN_UNKNOWN_COMMAND 560 %enddef
-%define SWIGWARN_DOXYGEN_UNEXPECTED_END_OF_COMMENT 561 %enddef
-%define SWIGWARN_DOXYGEN_COMMAND_EXPECTED 562 %enddef
-%define SWIGWARN_DOXYGEN_HTML_ERROR 563 %enddef
-%define SWIGWARN_DOXYGEN_COMMAND_ERROR 564 %enddef
-%define SWIGWARN_DOXYGEN_UNKNOWN_CHARACTER 565 %enddef
-%define SWIGWARN_DOXYGEN_UNEXPECTED_ITERATOR_VALUE 566 %enddef
-
-/* -- Reserved (600-699) -- */
-
-/* -- Language module specific warnings (700 - 899) -- */
-
-
-%define SWIGWARN_D_TYPEMAP_CTYPE_UNDEF 700 %enddef
-%define SWIGWARN_D_TYPEMAP_IMTYPE_UNDEF 701 %enddef
-%define SWIGWARN_D_TYPEMAP_DTYPE_UNDEF 702 %enddef
-%define SWIGWARN_D_MULTIPLE_INHERITANCE 703 %enddef
-%define SWIGWARN_D_TYPEMAP_CLASSMOD_UNDEF 704 %enddef
-%define SWIGWARN_D_TYPEMAP_DBODY_UNDEF 705 %enddef
-%define SWIGWARN_D_TYPEMAP_DOUT_UNDEF 706 %enddef
-%define SWIGWARN_D_TYPEMAP_DIN_UNDEF 707 %enddef
-%define SWIGWARN_D_TYPEMAP_DDIRECTORIN_UNDEF 708 %enddef
-%define SWIGWARN_D_TYPEMAP_DCONSTRUCTOR_UNDEF 709 %enddef
-%define SWIGWARN_D_EXCODE_MISSING 710 %enddef
-%define SWIGWARN_D_CANTHROW_MISSING 711 %enddef
-%define SWIGWARN_D_NO_DIRECTORCONNECT_ATTR 712 %enddef
-%define SWIGWARN_D_NAME_COLLISION 713 %enddef
-
-/* please leave 700-719 free for D */
-
-%define SWIGWARN_SCILAB_TRUNCATED_NAME 720 %enddef
-
-/* please leave 720-739 free for Scilab */
-
-%define SWIGWARN_PYTHON_INDENT_MISMATCH 740 %enddef
-
-/* please leave 740-749 free for Python */
-
-%define SWIGWARN_R_MISSING_RTYPECHECK_TYPEMAP 750 %enddef
-
-/* please leave 750-759 free for R */
-
-%define SWIGWARN_RUBY_WRONG_NAME 801 %enddef
-%define SWIGWARN_RUBY_MULTIPLE_INHERITANCE 802 %enddef
-
-/* please leave 800-809 free for Ruby */
-
-%define SWIGWARN_JAVA_TYPEMAP_JNI_UNDEF 810 %enddef
-%define SWIGWARN_JAVA_TYPEMAP_JTYPE_UNDEF 811 %enddef
-%define SWIGWARN_JAVA_TYPEMAP_JSTYPE_UNDEF 812 %enddef
-%define SWIGWARN_JAVA_MULTIPLE_INHERITANCE 813 %enddef
-%define SWIGWARN_JAVA_TYPEMAP_GETCPTR_UNDEF 814 %enddef
-%define SWIGWARN_JAVA_TYPEMAP_CLASSMOD_UNDEF 815 %enddef
-%define SWIGWARN_JAVA_TYPEMAP_JAVABODY_UNDEF 816 %enddef
-%define SWIGWARN_JAVA_TYPEMAP_JAVAOUT_UNDEF 817 %enddef
-%define SWIGWARN_JAVA_TYPEMAP_JAVAIN_UNDEF 818 %enddef
-%define SWIGWARN_JAVA_TYPEMAP_JAVADIRECTORIN_UNDEF 819 %enddef
-%define SWIGWARN_JAVA_TYPEMAP_JAVADIRECTOROUT_UNDEF 820 %enddef
-%define SWIGWARN_JAVA_TYPEMAP_INTERFACECODE_UNDEF 821 %enddef
-%define SWIGWARN_JAVA_COVARIANT_RET 822 %enddef
-%define SWIGWARN_JAVA_TYPEMAP_JAVACONSTRUCT_UNDEF 823 %enddef
-%define SWIGWARN_JAVA_TYPEMAP_DIRECTORIN_NODESC 824 %enddef
-%define SWIGWARN_JAVA_NO_DIRECTORCONNECT_ATTR 825 %enddef
-%define SWIGWARN_JAVA_NSPACE_WITHOUT_PACKAGE 826 %enddef
-%define SWIGWARN_JAVA_TYPEMAP_INTERFACEMODIFIERS_UNDEF 827 %enddef
-
-/* please leave 810-829 free for Java */
-
-%define SWIGWARN_CSHARP_TYPEMAP_CTYPE_UNDEF 830 %enddef
-%define SWIGWARN_CSHARP_TYPEMAP_CSTYPE_UNDEF 831 %enddef
-%define SWIGWARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF 832 %enddef
-%define SWIGWARN_CSHARP_MULTIPLE_INHERITANCE 833 %enddef
-%define SWIGWARN_CSHARP_TYPEMAP_GETCPTR_UNDEF 834 %enddef
-%define SWIGWARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF 835 %enddef
-%define SWIGWARN_CSHARP_TYPEMAP_CSBODY_UNDEF 836 %enddef
-%define SWIGWARN_CSHARP_TYPEMAP_CSOUT_UNDEF 837 %enddef
-%define SWIGWARN_CSHARP_TYPEMAP_CSIN_UNDEF 838 %enddef
-%define SWIGWARN_CSHARP_TYPEMAP_CSDIRECTORIN_UNDEF 839 %enddef
-%define SWIGWARN_CSHARP_TYPEMAP_CSDIRECTOROUT_UNDEF 840 %enddef
-%define SWIGWARN_CSHARP_TYPEMAP_INTERFACECODE_UNDEF 841 %enddef
-%define SWIGWARN_CSHARP_COVARIANT_RET 842 %enddef
-%define SWIGWARN_CSHARP_TYPEMAP_CSCONSTRUCT_UNDEF 843 %enddef
-%define SWIGWARN_CSHARP_EXCODE 844 %enddef
-%define SWIGWARN_CSHARP_CANTHROW 845 %enddef
-%define SWIGWARN_CSHARP_NO_DIRECTORCONNECT_ATTR 846 %enddef
-%define SWIGWARN_CSHARP_TYPEMAP_INTERFACEMODIFIERS_UNDEF 847 %enddef
-
-/* please leave 830-849 free for C# */
-
-/* 850-860 were used by Modula 3 (removed in SWIG 4.1.0) - avoid reusing for now */
-
-%define SWIGWARN_PHP_MULTIPLE_INHERITANCE 870 %enddef
-%define SWIGWARN_PHP_UNKNOWN_PRAGMA 871 %enddef
-%define SWIGWARN_PHP_PUBLIC_BASE 872 %enddef
-
-/* please leave 870-889 free for PHP */
-
-%define SWIGWARN_GO_NAME_CONFLICT 890 %enddef
-
-/* please leave 890-899 free for Go */
-
-/* -- User defined warnings (900 - 999) -- */
-
diff --git a/contrib/tools/swig/Lib/swigwarnings.swg b/contrib/tools/swig/Lib/swigwarnings.swg
deleted file mode 100644
index 63ae4c65a9..0000000000
--- a/contrib/tools/swig/Lib/swigwarnings.swg
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- Include the internal swig macro codes. These macros correspond to
- the one found in Source/Include/swigwarn.h plus the 'SWIG' prefix.
-
- For example, in the include file 'swigwarn.h' you will find
-
- #define WARN_TYPEMAP_CHARLEAK ...
-
- and in the 'swigwarn.swg' interface, you will see
-
- %define SWIGWARN_TYPEMAP_CHARLEAK ...
-
- This code can be used in warning filters as follows:
-
- %warnfilter(SWIGWARN_TYPEMAP_CHARLEAK);
-
- Warnings messages used in typemaps. Message names will be the same
- as those in Lib/swigwarn.swg but with the suffix _MSG.
-
- For example, for the code SWIGWARN_TYPEMAP_CHARLEAK, once you use
-
- %typemapmsg(CHARLEAK,<msg>);
-
- you use the message in your typemap as
-
- %typemap(varin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) char *
-
- while you suppress the warning using
-
- %warnfilter(SWIGWARN_TYPEMAP_CHARLEAK);
-
- as described above.
-*/
-
-/* -----------------------------------------------------------------------------
- * SWIG warning codes
- * ----------------------------------------------------------------------------- */
-
-%include <swigwarn.swg>
-
-/* -----------------------------------------------------------------------------
- * Auxiliary macros
- * ----------------------------------------------------------------------------- */
-
-/* Macro to define warning messages */
-#define %_warningmsg(Val, Msg...) `Val`":"Msg
-#define %warningmsg(Val, Msg...) %_warningmsg(Val, Msg)
-
-/* -----------------------------------------------------------------------------
- * Typemap related warning messages
- * ----------------------------------------------------------------------------- */
-
-%define SWIGWARN_TYPEMAP_CHARLEAK_MSG "451:Setting a const char * variable may leak memory." %enddef
-%define SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG "454:Setting a pointer/reference variable may leak memory." %enddef
-%define SWIGWARN_TYPEMAP_WCHARLEAK_MSG "455:Setting a const wchar_t * variable may leak memory." %enddef
-%define SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG "470:Thread/reentrant unsafe wrapping, consider returning by value instead." %enddef
-%define SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG "473:Returning a pointer or reference in a director method is not recommended." %enddef
-%define SWIGWARN_TYPEMAP_INITIALIZER_LIST_MSG "476:Initialization using std::initializer_list." %enddef
-
-/* -----------------------------------------------------------------------------
- * Operator related warning messages
- * ----------------------------------------------------------------------------- */
-
-%define SWIGWARN_IGNORE_OPERATOR_NEW_MSG "350:operator new ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_DELETE_MSG "351:operator delete ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_PLUS_MSG "352:operator+ ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_MINUS_MSG "353:operator- ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_MUL_MSG "354:operator* ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_DIV_MSG "355:operator/ ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_MOD_MSG "356:operator% ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_XOR_MSG "357:operator^ ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_AND_MSG "358:operator& ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_OR_MSG "359:operator| ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_NOT_MSG "360:operator~ ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_LNOT_MSG "361:operator! ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_EQ_MSG "362:operator= ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_LT_MSG "363:operator< ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_GT_MSG "364:operator> ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_PLUSEQ_MSG "365:operator+= ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_MINUSEQ_MSG "366:operator-= ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_MULEQ_MSG "367:operator*= ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_DIVEQ_MSG "368:operator/= ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_MODEQ_MSG "369:operator%= ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_XOREQ_MSG "370:operator^= ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_ANDEQ_MSG "371:operator&= ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_OREQ_MSG "372:operator|= ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_LSHIFT_MSG "373:operator<< ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_RSHIFT_MSG "374:operator>> ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_LSHIFTEQ_MSG "375:operator<<= ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_RSHIFTEQ_MSG "376:operator>>= ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_EQUALTO_MSG "377:operator== ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_NOTEQUAL_MSG "378:operator!= ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_LTEQUAL_MSG "379:operator<= ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_GTEQUAL_MSG "380:operator>= ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_LAND_MSG "381:operator&& ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_LOR_MSG "382:operator|| ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_PLUSPLUS_MSG "383:operator++ ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_MINUSMINUS_MSG "384:operator-- ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_COMMA_MSG "385:operator-- ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_ARROWSTAR_MSG "386:operator->* ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_ARROW_MSG "387:operator-> ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_CALL_MSG "388:operator() ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_INDEX_MSG "389:operator[] ignored (consider using %%extend)" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_UPLUS_MSG "390:operator+ ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_UMINUS_MSG "391:operator- ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_UMUL_MSG "392:operator* ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_UAND_MSG "393:operator& ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_NEWARR_MSG "394:operator new[] ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_DELARR_MSG "395:operator delete[] ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_REF_MSG "396:operator*() ignored" %enddef
-%define SWIGWARN_IGNORE_OPERATOR_LTEQUALGT_MSG "397:operator<=> ignored" %enddef
-
-#define %ignoreoperator(Oper) %ignorewarn(SWIGWARN_IGNORE_OPERATOR_##Oper##_MSG)
-
-/* -----------------------------------------------------------------------------
- * Macros for keyword and built-in names
- * ----------------------------------------------------------------------------- */
-
-#define %keywordwarn(msg...) %namewarn(%warningmsg(SWIGWARN_PARSE_KEYWORD, msg))
-#define %builtinwarn(msg...) %namewarn(%warningmsg(SWIGWARN_PARSE_BUILTIN_NAME, msg), %$isfunction)
-
-
-/* -----------------------------------------------------------------------------
- * Warning filter feature
- * ----------------------------------------------------------------------------- */
-
-#define %_warnfilter(filter...) %feature("warnfilter",`filter`)
-#define %warnfilter(filter...) %_warnfilter(filter)
-
-
-
diff --git a/contrib/tools/swig/Lib/typemaps/README b/contrib/tools/swig/Lib/typemaps/README
deleted file mode 100644
index 65134578d3..0000000000
--- a/contrib/tools/swig/Lib/typemaps/README
+++ /dev/null
@@ -1,54 +0,0 @@
-Still in development, but if you are interested into looking around,
-start with
-
-
- swigtypemaps.swg
-
-which is the head file. Also read the docs for %fragments in
-
- fragments.swg
-
-and follow the definitions in one of the supported languages:
-
- python, perl, ruby, tcl
-
-
-
-
-/* -----------------------------------------------------------------------------
- * Internal typemap specializations
- * ----------------------------------------------------------------------------- */
-
-
-carrays.swg Implement the carrays.i library
-cdata.swg Implement the cdata.i library
-cmalloc.swg Implement the cmalloc.i library
-cpointer.swg Implement the cpointer.i library
-cstring.swg Implement the cstring.i library typemaps for char *
-cwstring.swg Implement the cstring.i library typemaps for wchar_t *
-exception.swg Implement the exception.i library
-implicit.swg Allow the use of implicit C++ constructors
-
-string.swg Typemaps for char * string
-wstring.swg Typemaps for wchar_t * string
-std_string.swg Typemaps for std::string
-std_wstring.swg Typemaps for std::wstring
-swigtype.swg Typemaps for the SWIGTYPE type
-void.swg Typemaps for the 'void' type
-enumint.swg Typemaps for enums treated as 'int'
-swigobject.swg Typemaps for the SWIG_Object as in PyObject, Tcl_Obj, etc.
-misctypes.swg Typemaps for miscellaneos types (size_t, ptrdiff_t, etc)
-ptrtypes.swg Typemaps for types with a 'ptr' behavior
-valtypes.swg Typemaps for 'by value' types
-inoutlist.swg IN/OUTPUT/INOUT typemaps, where the OUTPUT values are returned in a list
-primtypes.swg Common macros to manage primitive types (short,int,double,etc)
-
-cstrings.swg Common macros to implemented the cstring/cwstring libraries
-std_strings.swg Common macros to implemented the std::string/std::wstring typemaps
-strings.swg Common macros and typemaps for string and wstring (char *, wchar_t *)
-
-swigmacros.swg Basic macros
-fragments.swg Macros for fragment manipulations
-
-
-typemaps.swg The old typemaps.i library, not needed anymore
diff --git a/contrib/tools/swig/Lib/typemaps/enumint.swg b/contrib/tools/swig/Lib/typemaps/enumint.swg
deleted file mode 100644
index d048bb6bf7..0000000000
--- a/contrib/tools/swig/Lib/typemaps/enumint.swg
+++ /dev/null
@@ -1,39 +0,0 @@
-/* ------------------------------------------------------------
- * Enums mapped as integer values
- * ------------------------------------------------------------ */
-
-%apply int { enum SWIGTYPE };
-%apply const int& { const enum SWIGTYPE & };
-%apply const int& { const enum SWIGTYPE && };
-
-%typemap(in,fragment=SWIG_AsVal_frag(int),noblock=1) const enum SWIGTYPE & (int val, int ecode, $basetype temp) {
- ecode = SWIG_AsVal(int)($input, &val);
- if (!SWIG_IsOK(ecode)) {
- %argument_fail(ecode, "$type", $symname, $argnum);
- } else {
- temp = %static_cast(val,$basetype);
- $1 = &temp;
- }
-}
-
-%typemap(in,fragment=SWIG_AsVal_frag(int),noblock=1) const enum SWIGTYPE && (int val, int ecode, $basetype temp) {
- ecode = SWIG_AsVal(int)($input, &val);
- if (!SWIG_IsOK(ecode)) {
- %argument_fail(ecode, "$type", $symname, $argnum);
- } else {
- temp = %static_cast(val,$basetype);
- $1 = &temp;
- }
-}
-
-%typemap(varin,fragment=SWIG_AsVal_frag(int),noblock=1) enum SWIGTYPE {
- if (sizeof(int) != sizeof($1)) {
- %variable_fail(SWIG_AttributeError,"$type", "arch, read-only $name");
- } else {
- int ecode = SWIG_AsVal(int)($input, %reinterpret_cast(&$1,int*));
- if (!SWIG_IsOK(ecode)) {
- %variable_fail(ecode, "$type", "$name");
- }
- }
-}
-
diff --git a/contrib/tools/swig/Lib/typemaps/exception.swg b/contrib/tools/swig/Lib/typemaps/exception.swg
deleted file mode 100644
index aece8326f5..0000000000
--- a/contrib/tools/swig/Lib/typemaps/exception.swg
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -----------------------------------------------------------------------------
- * exceptions.swg
- *
- * This SWIG library file provides language independent exception handling
- * ----------------------------------------------------------------------------- */
-
-%include <typemaps/swigmacros.swg>
-
-
-/* macros for error manipulation */
-#define %nullref_fmt() "invalid null reference "
-#define %varfail_fmt(_type,_name) "in variable '"`_name`"' of type '"`_type`"'"
-#ifndef %argfail_fmt
-#define %argfail_fmt(_type,_name,_argn) "in method '" `_name` "', argument " `_argn`" of type '" `_type`"'"
-#endif
-#define %outfail_fmt(_type) "in output value of type '"_type"'"
-#ifndef %argnullref_fmt
-#define %argnullref_fmt(_type,_name,_argn) %nullref_fmt() %argfail_fmt(_type, _name, _argn)
-#endif
-#define %varnullref_fmt(_type,_name) %nullref_fmt() %varfail_fmt(_type, _name)
-#define %outnullref_fmt(_type) %nullref_fmt() %outfail_fmt(_type)
-#define %releasenotownedfail_fmt(_type,_name,_argn) "in method '" `_name` "', cannot release ownership as memory is not owned for argument " `_argn`" of type '" `_type`"'"
-
-/* setting an error */
-#define %error(code,msg...) SWIG_Error(code, msg)
-#define %type_error(msg...) SWIG_Error(SWIG_TypeError, msg)
-
-
-
-%insert("runtime") {
-
-%define_as(SWIG_exception_fail(code, msg), %block(%error(code, msg); SWIG_fail))
-
-%define_as(SWIG_contract_assert(expr, msg), do { if (!(expr)) { %error(SWIG_RuntimeError, msg); SWIG_fail; } } while (0))
-
-}
-
-#ifdef __cplusplus
-/*
- You can use the SWIG_CATCH_STDEXCEPT macro with the %exception
- directive as follows:
-
- %exception {
- try {
- $action
- }
- catch (my_except& e) {
- ...
- }
- SWIG_CATCH_STDEXCEPT // catch std::exception
- catch (...) {
- SWIG_exception_fail(SWIG_UnknownError, "Unknown exception");
- }
- }
-*/
-
-%fragment("<stdexcept>");
-
-%define SWIG_CATCH_STDEXCEPT
- /* catching std::exception */
- catch (std::invalid_argument& e) {
- SWIG_exception_fail(SWIG_ValueError, e.what() );
- } catch (std::domain_error& e) {
- SWIG_exception_fail(SWIG_ValueError, e.what() );
- } catch (std::overflow_error& e) {
- SWIG_exception_fail(SWIG_OverflowError, e.what() );
- } catch (std::out_of_range& e) {
- SWIG_exception_fail(SWIG_IndexError, e.what() );
- } catch (std::length_error& e) {
- SWIG_exception_fail(SWIG_IndexError, e.what() );
- } catch (std::runtime_error& e) {
- SWIG_exception_fail(SWIG_RuntimeError, e.what() );
- } catch (std::exception& e) {
- SWIG_exception_fail(SWIG_SystemError, e.what() );
- }
-%enddef
-%define SWIG_CATCH_UNKNOWN
- catch (std::exception& e) {
- SWIG_exception_fail(SWIG_SystemError, e.what() );
- }
- catch (...) {
- SWIG_exception_fail(SWIG_UnknownError, "unknown exception");
- }
-%enddef
-
-
-#endif /* __cplusplus */
diff --git a/contrib/tools/swig/Lib/typemaps/fragments.swg b/contrib/tools/swig/Lib/typemaps/fragments.swg
deleted file mode 100644
index e76a694eea..0000000000
--- a/contrib/tools/swig/Lib/typemaps/fragments.swg
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- Fragments
- =========
- See the "Typemap fragments" section in the documentation for understanding
- fragments. Below is some info on how fragments and automatic type
- specialization is used.
-
- Macros that make the automatic generation of typemaps easier are provided.
-
- Consider the following code:
-
- %fragment(SWIG_From_frag(bool), "header") {
- static PyObject*
- SWIG_From_dec(bool)(bool value)
- {
- PyObject *obj = value ? Py_True : Py_False;
- Py_INCREF(obj);
- return obj;
- }
- }
-
- %typemap(out, fragment=SWIG_From_frag(bool)) bool {
- $result = SWIG_From(bool)($1));
- }
-
- Here the macros
-
- SWIG_From_frag => fragment
- SWIG_From_dec => declaration
- SWIG_From => call
-
- allow you to define/include a fragment, and declare and call the
- 'from-bool' method as needed. In the simpler case, these macros
- just return something like
-
- SWIG_From_frag(bool) => "SWIG_From_bool"
- SWIG_From_dec(bool) => SWIG_From_bool
- SWIG_From(bool) => SWIG_From_bool
-
- But they are specialized for the different languages requirements,
- such as perl or tcl that requires passing the interpreter pointer,
- and also they can manage C++ ugly types, for example:
-
- SWIG_From_frag(std::complex<double>) => "SWIG_From_std_complex_Sl_double_Sg_"
- SWIG_From_dec(std::complex<double>) => SWIG_From_std_complex_Sl_double_Sg_
- SWIG_From(std::complex<double>) => SWIG_From_std_complex_Sl_double_Sg_
-
-
- Hence, to declare methods to use with typemaps, always use the
- SWIG_From* macros. In the same way, the SWIG_AsVal* and SWIG_AsPtr*
- set of macros are provided.
-
-*/
-
-
-/* -----------------------------------------------------------------------------
- * Define the basic macros to 'normalize' the type fragments
- * ----------------------------------------------------------------------------- */
-
-#ifndef SWIG_AS_DECL_ARGS
-#define SWIG_AS_DECL_ARGS
-#endif
-
-#ifndef SWIG_FROM_DECL_ARGS
-#define SWIG_FROM_DECL_ARGS
-#endif
-
-#ifndef SWIG_AS_CALL_ARGS
-#define SWIG_AS_CALL_ARGS
-#endif
-
-#ifndef SWIG_FROM_CALL_ARGS
-#define SWIG_FROM_CALL_ARGS
-#endif
-
-#define %fragment_name(Name, Type...) %string_name(Name) "_" {Type}
-
-#define SWIG_Traits_frag(Type...) %fragment_name(Traits, Type)
-#define SWIG_AsPtr_frag(Type...) %fragment_name(AsPtr, Type)
-#define SWIG_AsVal_frag(Type...) %fragment_name(AsVal, Type)
-#define SWIG_From_frag(Type...) %fragment_name(From, Type)
-
-#define SWIG_AsVal_name(Type...) %symbol_name(AsVal, Type)
-#define SWIG_AsPtr_name(Type...) %symbol_name(AsPtr, Type)
-#define SWIG_From_name(Type...) %symbol_name(From, Type)
-
-#define SWIG_AsVal_dec(Type...) SWIG_AsVal_name(Type) SWIG_AS_DECL_ARGS
-#define SWIG_AsPtr_dec(Type...) SWIG_AsPtr_name(Type) SWIG_AS_DECL_ARGS
-#define SWIG_From_dec(Type...) SWIG_From_name(Type) SWIG_FROM_DECL_ARGS
-
-#define SWIG_AsVal(Type...) SWIG_AsVal_name(Type) SWIG_AS_CALL_ARGS
-#define SWIG_AsPtr(Type...) SWIG_AsPtr_name(Type) SWIG_AS_CALL_ARGS
-#define SWIG_From(Type...) SWIG_From_name(Type) SWIG_FROM_CALL_ARGS
-
-/* ------------------------------------------------------------
- * common fragments
- * ------------------------------------------------------------ */
-
-%fragment("SWIG_isfinite","header",fragment="<math.h>,<float.h>") %{
-/* Getting isfinite working pre C99 across multiple platforms is non-trivial. Users can provide SWIG_isfinite on older platforms. */
-#ifndef SWIG_isfinite
-/* isfinite() is a macro for C99 */
-# if defined(isfinite)
-# define SWIG_isfinite(X) (isfinite(X))
-# elif defined(__cplusplus) && __cplusplus >= 201103L
-/* Use a template so that this works whether isfinite() is std::isfinite() or
- * in the global namespace. The reality seems to vary between compiler
- * versions.
- *
- * Make sure namespace std exists to avoid compiler warnings.
- *
- * extern "C++" is required as this fragment can end up inside an extern "C" { } block
- */
-namespace std { }
-extern "C++" template<typename T>
-inline int SWIG_isfinite_func(T x) {
- using namespace std;
- return isfinite(x);
-}
-# define SWIG_isfinite(X) (SWIG_isfinite_func(X))
-# elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
-# define SWIG_isfinite(X) (__builtin_isfinite(X))
-# elif defined(_MSC_VER)
-# define SWIG_isfinite(X) (_finite(X))
-# elif defined(__sun) && defined(__SVR4)
-# include <ieeefp.h>
-# define SWIG_isfinite(X) (finite(X))
-# endif
-#endif
-%}
-
-%fragment("SWIG_Float_Overflow_Check","header",fragment="<float.h>,SWIG_isfinite") %{
-/* Accept infinite as a valid float value unless we are unable to check if a value is finite */
-#ifdef SWIG_isfinite
-# define SWIG_Float_Overflow_Check(X) ((X < -FLT_MAX || X > FLT_MAX) && SWIG_isfinite(X))
-#else
-# define SWIG_Float_Overflow_Check(X) ((X < -FLT_MAX || X > FLT_MAX))
-#endif
-%}
-
-/* -----------------------------------------------------------------------------
- * special macros for fragments
- * ----------------------------------------------------------------------------- */
-
-/* Macros to derive numeric types */
-
-%define %numeric_type_from(Type, Base)
-%fragment(SWIG_From_frag(Type),"header",
- fragment=SWIG_From_frag(Base)) {
-SWIGINTERNINLINE SWIG_Object
-SWIG_From_dec(Type)(Type value)
-{
- return SWIG_From(Base)(value);
-}
-}
-%enddef
-
-%define %numeric_type_asval(Type, Base, Frag, OverflowCond)
-%fragment(SWIG_AsVal_frag(Type),"header",
- fragment=Frag,
- fragment=SWIG_AsVal_frag(Base)) {
-SWIGINTERN int
-SWIG_AsVal_dec(Type)(SWIG_Object obj, Type *val)
-{
- Base v;
- int res = SWIG_AsVal(Base)(obj, &v);
- if (SWIG_IsOK(res)) {
- if (OverflowCond) {
- return SWIG_OverflowError;
- } else {
- if (val) *val = %numeric_cast(v, Type);
- }
- }
- return res;
-}
-}
-%enddef
-
-#define %numeric_signed_type_asval(Type, Base, Frag, Min, Max) \
-%numeric_type_asval(Type, Base, Frag, (v < Min || v > Max))
-
-#define %numeric_unsigned_type_asval(Type, Base, Frag, Max) \
-%numeric_type_asval(Type, Base, Frag, (v > Max))
-
-
-/* Macro for 'signed long' derived types */
-
-%define %numeric_slong(Type, Frag, Min, Max)
-%numeric_type_from(Type, long)
-%numeric_signed_type_asval(Type, long, Frag , Min, Max)
-%enddef
-
-/* Macro for 'unsigned long' derived types */
-
-%define %numeric_ulong(Type, Frag, Max)
-%numeric_type_from(Type, unsigned long)
-%numeric_unsigned_type_asval(Type, unsigned long, Frag, Max)
-%enddef
-
-
-/* Macro for floating point derived types (original macro) */
-
-%define %numeric_double(Type, Frag, Min, Max)
-%numeric_type_from(Type, double)
-%numeric_signed_type_asval(Type, double, Frag , Min, Max)
-%enddef
-
-/* Macro for floating point derived types */
-
-%define %numeric_float(Type, Frag, OverflowCond)
-%numeric_type_from(Type, double)
-%numeric_type_asval(Type, double, Frag, OverflowCond)
-%enddef
-
-
-/* Macros for missing fragments */
-
-%define %ensure_fragment(Fragment)
-%fragment(`Fragment`,"header") {
-%#error "SWIG language implementation must provide the Fragment fragment"
-}
-%enddef
-
-%define %ensure_type_fragments(Type)
-%fragment(SWIG_From_frag(Type),"header") {
-%#error "SWIG language implementation must provide a SWIG_From_frag(Type) fragment"
-}
-%fragment(SWIG_AsVal_frag(Type),"header") {
-%#error "SWIG language implementation must provide a SWIG_AsVal_frag(Type) fragment"
-}
-%enddef
diff --git a/contrib/tools/swig/Lib/typemaps/inoutlist.swg b/contrib/tools/swig/Lib/typemaps/inoutlist.swg
deleted file mode 100644
index 23fda85f3a..0000000000
--- a/contrib/tools/swig/Lib/typemaps/inoutlist.swg
+++ /dev/null
@@ -1,296 +0,0 @@
-/* ------------------------------------------------------------
- *
- * Define the IN/OUTPUT typemaps assuming the output parameters are
- * returned in a list, i.e., they are not directly modified.
- *
- * The user should provide the %append_output(result, obj) method,
- * via a macro, which append a particular object to the result.
- *
- *
- * In Tcl, for example, the file is used as:
- *
- * #define %append_output(obj) Tcl_ListObjAppendElement(interp,Tcl_GetObjResult(interp),obj);
- * %include <typemaps/inoutlist.swg>
- *
- * while in Python it is used as:
- *
- * #define %append_output(obj) $result = SWIG_Python_AppendResult($result, obj)
- * %include <typemaps/inoutlist.swg>
- *
- * where the method SWIG_Python_AppendResult is defined inside the
- * %append_output fragment.
- *
- * If you forget to define %append_output, this file will generate
- * an error.
- *
- * ------------------------------------------------------------ */
-
-
-//
-// Uncomment the following definition if you don't want the in/out
-// typemaps by default, ie, you prefer to use typemaps.i.
-//
-//#define SWIG_INOUT_NODEF
-
-//
-// Use the following definition to enable the INPUT parameters to
-// accept both 'by value' and 'pointer' objects.
-//
-#define SWIG_INPUT_ACCEPT_PTRS
-
-// ------------------------------------------------------------------------
-// Pointer handling
-//
-// These mappings provide support for input/output arguments and common
-// uses for C/C++ pointers.
-// ------------------------------------------------------------------------
-
-// INPUT typemaps.
-// These remap a C pointer to be an "INPUT" value which is passed by value
-// instead of reference.
-
-/*
-The following methods can be applied to turn a pointer into a simple
-"input" value. That is, instead of passing a pointer to an object,
-you would use a real value instead.
-
-To use these, suppose you had a C function like this :
-
- double fadd(double *a, double *b) {
- return *a+*b;
- }
-
-You could wrap it with SWIG as follows :
-
- double fadd(double *INPUT, double *INPUT);
-
-or you can use the %apply directive :
-
- %apply double *INPUT { double *a, double *b };
- double fadd(double *a, double *b);
-
-*/
-#if defined(SWIG_INPUT_ACCEPT_PTRS)
-#define %check_input_ptr(input,arg,desc,disown) (SWIG_IsOK((res = SWIG_ConvertPtr(input,%as_voidptrptr(arg),desc,disown))))
-#else
-#define %check_input_ptr(input,arg,desc,disown) (SWIG_IsOK((res = SWIG_ERROR)))
-#endif
-
-%define %_value_input_typemap(code, asval_meth, asval_frag, Type)
- %typemap(in,noblock=1,fragment=asval_frag) Type *INPUT ($*ltype temp, int res = 0) {
- if (!%check_input_ptr($input,&$1,$descriptor,$disown)) {
- Type val;
- int ecode = asval_meth($input, &val);
- if (!SWIG_IsOK(ecode)) {
- %argument_fail(ecode, "$*ltype",$symname, $argnum);
- }
- temp = %static_cast(val, $*ltype);
- $1 = &temp;
- res = SWIG_AddTmpMask(ecode);
- }
- }
- %typemap(in,noblock=1,fragment=asval_frag) Type &INPUT($*ltype temp, int res = 0) {
- if (!%check_input_ptr($input,&$1,$descriptor,$disown)) {
- Type val;
- int ecode = asval_meth($input, &val);
- if (!SWIG_IsOK(ecode)) {
- %argument_fail(ecode, "$*ltype",$symname, $argnum);
- }
- temp = %static_cast(val, $*ltype);
- $1 = &temp;
- res = SWIG_AddTmpMask(ecode);
- }
- }
- %typemap(freearg,noblock=1,match="in") Type *INPUT, Type &INPUT {
- if (SWIG_IsNewObj(res$argnum)) %delete($1);
- }
- %typemap(typecheck,noblock=1,precedence=code,fragment=asval_frag) Type *INPUT, Type &INPUT {
- void *ptr = 0;
- int res = asval_meth($input, 0);
- $1 = SWIG_CheckState(res);
- if (!$1) {
- $1 = %check_input_ptr($input,&ptr,$1_descriptor,0);
- }
- }
-%enddef
-
-%define %_ptr_input_typemap(code,asptr_meth,asptr_frag,Type)
- %typemap(in,noblock=1,fragment=asptr_frag) Type *INPUT(int res = 0) {
- res = asptr_meth($input, &$1);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res,"$type",$symname, $argnum);
- }
- res = SWIG_AddTmpMask(res);
- }
- %typemap(in,noblock=1,fragment=asptr_frag) Type &INPUT(int res = 0) {
- res = asptr_meth($input, &$1);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res,"$type",$symname, $argnum);
- }
- if (!$1) {
- %argument_nullref("$type",$symname, $argnum);
- }
- res = SWIG_AddTmpMask(res);
- }
- %typemap(freearg,noblock=1,match="in") Type *INPUT, Type &INPUT {
- if (SWIG_IsNewObj(res$argnum)) %delete($1);
- }
- %typemap(typecheck,noblock=1,precedence=code,fragment=asptr_frag) Type *INPUT, Type &INPUT {
- int res = asptr_meth($input, (Type**)0);
- $1 = SWIG_CheckState(res);
- }
-%enddef
-
-// OUTPUT typemaps. These typemaps are used for parameters that
-// are output only. The output value is appended to the result as
-// a list element.
-
-/*
-The following methods can be applied to turn a pointer into an "output"
-value. When calling a function, no input value would be given for
-a parameter, but an output value would be returned. In the case of
-multiple output values, they are returned in the form of a list.
-
-
-For example, suppose you were trying to wrap the modf() function in the
-C math library which splits x into integral and fractional parts (and
-returns the integer part in one of its parameters):
-
- double modf(double x, double *ip);
-
-You could wrap it with SWIG as follows :
-
- double modf(double x, double *OUTPUT);
-
-or you can use the %apply directive :
-
- %apply double *OUTPUT { double *ip };
- double modf(double x, double *ip);
-
-The output of the function would be a list containing both output
-values.
-
-*/
-
-%define %_value_output_typemap(from_meth, from_frag, Type)
- %typemap(in,numinputs=0,noblock=1)
- Type *OUTPUT ($*1_ltype temp, int res = SWIG_TMPOBJ),
- Type &OUTPUT ($*1_ltype temp, int res = SWIG_TMPOBJ) {
- $1 = &temp;
- }
- %typemap(argout,noblock=1,fragment=from_frag) Type *OUTPUT, Type &OUTPUT {
- if (SWIG_IsTmpObj(res$argnum)) {
- %append_output(from_meth((*$1)));
- } else {
- int new_flags = SWIG_IsNewObj(res$argnum) ? (SWIG_POINTER_OWN | %newpointer_flags) : %newpointer_flags;
- %append_output(SWIG_NewPointerObj((void*)($1), $1_descriptor, new_flags));
- }
- }
-%enddef
-
-
-// INOUT
-// Mappings for an argument that is both an input and output
-// parameter
-
-/*
-The following methods can be applied to make a function parameter both
-an input and output value. This combines the behavior of both the
-"INPUT" and "OUTPUT" methods described earlier. Output values are
-returned in the form of a list.
-
-For example, suppose you were trying to wrap the following function :
-
- void neg(double *x) {
- *x = -(*x);
- }
-
-You could wrap it with SWIG as follows :
-
- void neg(double *INOUT);
-
-or you can use the %apply directive :
-
- %apply double *INOUT { double *x };
- void neg(double *x);
-
-Unlike C, this mapping does not directly modify the input value.
-Rather, the modified input value shows up as the return value of the
-function. Thus, to apply this function to a variable you might do
-this :
-
- x = neg(x)
-
-Note : previous versions of SWIG used the symbol 'BOTH' to mark
-input/output arguments. This is still supported, but will be slowly
-phased out in future releases.
-
-*/
-
-%define %_value_inout_typemap(Type)
- %typemap(in) Type *INOUT = Type *INPUT;
- %typemap(in) Type &INOUT = Type &INPUT;
- %typemap(typecheck) Type *INOUT = Type *INPUT;
- %typemap(typecheck) Type &INOUT = Type &INPUT;
- %typemap(argout) Type *INOUT = Type *OUTPUT;
- %typemap(argout) Type &INOUT = Type &OUTPUT;
-%enddef
-
-
-%define %_ptr_inout_typemap(Type)
- %_value_inout_typemap(%arg(Type))
- %typemap(typecheck) Type *INOUT = Type *INPUT;
- %typemap(typecheck) Type &INOUT = Type &INPUT;
- %typemap(freearg) Type *INOUT = Type *INPUT;
- %typemap(freearg) Type &INOUT = Type &INPUT;
-%enddef
-
-#ifndef SWIG_INOUT_NODEF
-
-%define %value_input_typemap(code,asval_meth, asval_frag, Type...)
- %_value_input_typemap(%arg(code),%arg(asval_meth),%arg(asval_frag),%arg(Type))
-%enddef
-
-%define %ptr_input_typemap(code,asval_meth,asval_frag,Type...)
- %_ptr_input_typemap(%arg(code),%arg(asval_meth),%arg(asval_frag),%arg(Type))
-%enddef
-
-%define %value_output_typemap(from_meth,from_frag,Type...)
- %_value_output_typemap(%arg(from_meth),%arg(from_frag),%arg(Type))
-%enddef
-
-#define %value_inout_typemap(Type...) %_value_inout_typemap(%arg(Type))
-#define %ptr_inout_typemap(Type...) %_ptr_inout_typemap(%arg(Type))
-
-#else /* You need to include typemaps.i */
-
-
-#define %value_output_typemap(Type...)
-#define %value_input_typemap(Type...)
-#define %value_inout_typemap(Type...)
-#define %ptr_input_typemap(Type...)
-#define %ptr_inout_typemap(Type...)
-
-#endif /* SWIG_INOUT_DEFAULT */
-
-/*----------------------------------------------------------------------
- Front ends.
-
- use the following macros to define your own IN/OUTPUT/INOUT typemaps
-
- ------------------------------------------------------------------------*/
-%define %typemaps_inout(Code, AsValMeth, FromMeth, AsValFrag, FromFrag, Type...)
- %_value_input_typemap(%arg(Code), %arg(AsValMeth),
- %arg(AsValFrag), %arg(Type));
- %_value_output_typemap(%arg(FromMeth), %arg(FromFrag), %arg(Type));
- %_value_inout_typemap(%arg(Type));
-%enddef
-
-%define %typemaps_inoutn(Code,Type...)
- %typemaps_inout(%arg(Code),
- %arg(SWIG_AsVal(Type)),
- %arg(SWIG_From(Type)),
- %arg(SWIG_AsVal_frag(Type)),
- %arg(SWIG_From_frag(Type)),
- %arg(Type));
-%enddef
diff --git a/contrib/tools/swig/Lib/typemaps/misctypes.swg b/contrib/tools/swig/Lib/typemaps/misctypes.swg
deleted file mode 100644
index 09c81d7433..0000000000
--- a/contrib/tools/swig/Lib/typemaps/misctypes.swg
+++ /dev/null
@@ -1,21 +0,0 @@
-
-/* ------------------------------------------------------------
- * --- ANSI/Posix C/C++ types ---
- * ------------------------------------------------------------ */
-
-
-#ifdef __cplusplus
-
-%apply size_t { std::size_t };
-%apply const size_t& { const std::size_t& };
-
-%apply ptrdiff_t { std::ptrdiff_t };
-%apply const ptrdiff_t& { const std::ptrdiff_t& };
-
-#ifndef SWIG_INOUT_NODEF
-%apply size_t& { std::size_t& };
-%apply ptrdiff_t& { std::ptrdiff_t& };
-#endif
-
-#endif
-
diff --git a/contrib/tools/swig/Lib/typemaps/primtypes.swg b/contrib/tools/swig/Lib/typemaps/primtypes.swg
deleted file mode 100644
index dd80eb775e..0000000000
--- a/contrib/tools/swig/Lib/typemaps/primtypes.swg
+++ /dev/null
@@ -1,367 +0,0 @@
-/* ------------------------------------------------------------
- * Primitive type fragments and macros
- * ------------------------------------------------------------ */
-
-/*
- This file provide fragments and macros for the C/C++ primitive types.
-
- The file defines default fragments for the following types:
-
- bool
- signed char
- unsigned char
- signed wchar_t // in C++
- unsigned wchar_t // in C++
- short
- unsigned short
- int
- unsigned int
- float
- size_t
- ptrdiff_t
-
- which can always be redefined in the swig target language if needed.
-
- The fragments for the following types, however, always need to be
- defined in the target language:
-
- long
- unsigned long
- long long
- unsigned long long
- double
-
- If they are not provided, an #error directive will appear in the
- wrapped code.
-
- --------------------------------------------------------------------
-
- This file provides the macro
-
- %typemaps_primitive(CheckCode, Type)
-
- which generates the typemaps for a primitive type with a given
- checkcode. It is assumed that the primitive type is 'normalized' and
- the corresponding SWIG_AsVal(Type) and SWIG_From(Type) methods are
- provided via fragments.
-
-
- The following auxiliary macros (explained with bash pseudo code) are
- also defined:
-
- %apply_ctypes(Macro)
- for i in C Type
- do
- Macro($i)
- done
-
- %apply_cpptypes(Macro)
- for i in C++ Type
- do
- Macro($i)
- done
-
- %apply_ctypes_2(Macro2)
- for i in C Type
- do
- for j in C Type
- do
- Macro_2($i, $j)
- done
- done
-
- %apply_cpptypes_2(Macro2)
- for i in C++ Type
- do
- for j in C++ Type
- do
- Macro_2($i, $j)
- done
- done
-
- %apply_checkctypes(Macro2)
- for i in Check Type
- do
- Macro2(%checkcode($i), $i)
- done
-
-*/
-
-
-/* ------------------------------------------------------------
- * Primitive type fragments
- * ------------------------------------------------------------ */
-/* boolean */
-
-%fragment(SWIG_From_frag(bool),"header",fragment=SWIG_From_frag(long)) {
-SWIGINTERN SWIG_Object
-SWIG_From_dec(bool)(bool value)
-{
- return SWIG_From(long)(value ? 1 : 0);
-}
-}
-
-%fragment(SWIG_AsVal_frag(bool),"header",fragment=SWIG_AsVal_frag(long)) {
-SWIGINTERN int
-SWIG_AsVal_dec(bool)(SWIG_Object obj, bool *val)
-{
- long v;
- int res = SWIG_AsVal(long)(obj, val ? &v : 0);
- if (SWIG_IsOK(res)) {
- if (val) *val = v ? true : false;
- return res;
- }
- return SWIG_TypeError;
-}
-}
-
-/* signed/unsigned char */
-
-%numeric_slong(signed char, "<limits.h>", SCHAR_MIN, SCHAR_MAX)
-%numeric_ulong(unsigned char, "<limits.h>", UCHAR_MAX)
-
-/* short/unsigned short */
-
-%numeric_slong(short, "<limits.h>", SHRT_MIN, SHRT_MAX)
-%numeric_ulong(unsigned short, "<limits.h>", USHRT_MAX)
-
-/* int/unsigned int */
-
-%numeric_slong(int, "<limits.h>", INT_MIN, INT_MAX)
-%numeric_ulong(unsigned int, "<limits.h>", UINT_MAX)
-
-/* signed/unsigned wchar_t */
-
-#ifdef __cplusplus
-%numeric_slong(signed wchar_t, "<wchar.h>", WCHAR_MIN, WCHAR_MAX)
-%numeric_ulong(unsigned wchar_t, "<wchar.h>", UWCHAR_MAX)
-#endif
-
-/* float */
-
-%numeric_float(float, "SWIG_Float_Overflow_Check", SWIG_Float_Overflow_Check(v))
-
-/* long/unsigned long */
-
-%ensure_type_fragments(long)
-%ensure_type_fragments(unsigned long)
-
-/* long long/unsigned long long */
-
-%fragment("SWIG_LongLongAvailable","header", fragment="<limits.h>") %{
-#if defined(LLONG_MAX) && !defined(SWIG_LONG_LONG_AVAILABLE)
-# define SWIG_LONG_LONG_AVAILABLE
-#endif
-%}
-
-%ensure_type_fragments(long long)
-%ensure_type_fragments(unsigned long long)
-
-/* double */
-
-%ensure_type_fragments(double)
-
-/* size_t */
-
-%fragment(SWIG_From_frag(size_t),"header",fragment=SWIG_From_frag(unsigned long),fragment=SWIG_From_frag(unsigned long long)) {
-SWIGINTERNINLINE SWIG_Object
-SWIG_From_dec(size_t)(size_t value)
-{
-%#ifdef SWIG_LONG_LONG_AVAILABLE
- if (sizeof(size_t) <= sizeof(unsigned long)) {
-%#endif
- return SWIG_From(unsigned long)(%numeric_cast(value, unsigned long));
-%#ifdef SWIG_LONG_LONG_AVAILABLE
- } else {
- /* assume sizeof(size_t) <= sizeof(unsigned long long) */
- return SWIG_From(unsigned long long)(%numeric_cast(value, unsigned long long));
- }
-%#endif
-}
-}
-
-%fragment(SWIG_AsVal_frag(size_t),"header",fragment=SWIG_AsVal_frag(unsigned long),fragment=SWIG_AsVal_frag(unsigned long long)) {
-SWIGINTERNINLINE int
-SWIG_AsVal_dec(size_t)(SWIG_Object obj, size_t *val)
-{
- int res = SWIG_TypeError;
-%#ifdef SWIG_LONG_LONG_AVAILABLE
- if (sizeof(size_t) <= sizeof(unsigned long)) {
-%#endif
- unsigned long v;
- res = SWIG_AsVal(unsigned long)(obj, val ? &v : 0);
- if (SWIG_IsOK(res) && val) *val = %numeric_cast(v, size_t);
-%#ifdef SWIG_LONG_LONG_AVAILABLE
- } else if (sizeof(size_t) <= sizeof(unsigned long long)) {
- unsigned long long v;
- res = SWIG_AsVal(unsigned long long)(obj, val ? &v : 0);
- if (SWIG_IsOK(res) && val) *val = %numeric_cast(v, size_t);
- }
-%#endif
- return res;
-}
-}
-
-/* ptrdiff_t */
-
-%fragment(SWIG_From_frag(ptrdiff_t),"header",fragment=SWIG_From_frag(long),fragment=SWIG_From_frag(long long)) {
-SWIGINTERNINLINE SWIG_Object
-SWIG_From_dec(ptrdiff_t)(ptrdiff_t value)
-{
-%#ifdef SWIG_LONG_LONG_AVAILABLE
- if (sizeof(ptrdiff_t) <= sizeof(long)) {
-%#endif
- return SWIG_From(long)(%numeric_cast(value, long));
-%#ifdef SWIG_LONG_LONG_AVAILABLE
- } else {
- /* assume sizeof(ptrdiff_t) <= sizeof(long long) */
- return SWIG_From(long long)(%numeric_cast(value, long long));
- }
-%#endif
-}
-}
-
-%fragment(SWIG_AsVal_frag(ptrdiff_t),"header",fragment=SWIG_AsVal_frag(long),fragment=SWIG_AsVal_frag(long long)) {
-SWIGINTERNINLINE int
-SWIG_AsVal_dec(ptrdiff_t)(SWIG_Object obj, ptrdiff_t *val)
-{
- int res = SWIG_TypeError;
-%#ifdef SWIG_LONG_LONG_AVAILABLE
- if (sizeof(ptrdiff_t) <= sizeof(long)) {
-%#endif
- long v;
- res = SWIG_AsVal(long)(obj, val ? &v : 0);
- if (SWIG_IsOK(res) && val) *val = %numeric_cast(v, ptrdiff_t);
-%#ifdef SWIG_LONG_LONG_AVAILABLE
- } else if (sizeof(ptrdiff_t) <= sizeof(long long)) {
- long long v;
- res = SWIG_AsVal(long long)(obj, val ? &v : 0);
- if (SWIG_IsOK(res) && val) *val = %numeric_cast(v, ptrdiff_t);
- }
-%#endif
- return res;
-}
-}
-
-
-%fragment("SWIG_CanCastAsInteger","header",
- fragment=SWIG_AsVal_frag(double),
- fragment="<float.h>",
- fragment="<math.h>") {
-SWIGINTERNINLINE int
-SWIG_CanCastAsInteger(double *d, double min, double max) {
- double x = *d;
- if ((min <= x && x <= max)) {
- double fx = floor(x);
- double cx = ceil(x);
- double rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */
- if ((errno == EDOM) || (errno == ERANGE)) {
- errno = 0;
- } else {
- double summ, reps, diff;
- if (rd < x) {
- diff = x - rd;
- } else if (rd > x) {
- diff = rd - x;
- } else {
- return 1;
- }
- summ = rd + x;
- reps = diff/summ;
- if (reps < 8*DBL_EPSILON) {
- *d = rd;
- return 1;
- }
- }
- }
- return 0;
-}
-}
-
-/* ------------------------------------------------------------
- * Generate the typemaps for primitive type
- * ------------------------------------------------------------ */
-
-#define %typemaps_primitive(Code, Type) %typemaps_asvalfromn(%arg(Code), Type)
-
-/* ------------------------------------------------------------
- * Primitive Type Macros
- * ------------------------------------------------------------ */
-
-/* useful macros to derive typemap declarations from primitive types */
-
-%define _apply_macro(macro, arg2, arg1...)
-#if #arg1 != ""
-macro(%arg(arg1),arg2);
-#else
-macro(arg2);
-#endif
-%enddef
-
-/* Apply macro to the C-types */
-%define %apply_ctypes(Macro, Arg2...)
-_apply_macro(Macro, bool , Arg2);
-_apply_macro(Macro, signed char , Arg2);
-_apply_macro(Macro, unsigned char , Arg2);
-_apply_macro(Macro, short , Arg2);
-_apply_macro(Macro, unsigned short , Arg2);
-_apply_macro(Macro, int , Arg2);
-_apply_macro(Macro, unsigned int , Arg2);
-_apply_macro(Macro, long , Arg2);
-_apply_macro(Macro, unsigned long , Arg2);
-_apply_macro(Macro, long long , Arg2);
-_apply_macro(Macro, unsigned long long , Arg2);
-_apply_macro(Macro, float , Arg2);
-_apply_macro(Macro, double , Arg2);
-_apply_macro(Macro, char , Arg2);
-_apply_macro(Macro, wchar_t , Arg2);
-_apply_macro(Macro, size_t , Arg2);
-_apply_macro(Macro, ptrdiff_t , Arg2);
-%enddef
-
-/* apply the Macro2(Type1, Type2) to all C types */
-#define %apply_ctypes_2(Macro2) %apply_ctypes(%apply_ctypes, Macro2)
-
-
-/* apply the Macro(Type) to all C++ types */
-%define %apply_cpptypes(Macro, Arg2...)
-%apply_ctypes(Macro, Arg2)
-_apply_macro(Macro, std::size_t, Arg2);
-_apply_macro(Macro, std::ptrdiff_t, Arg2);
-_apply_macro(Macro, std::string, Arg2);
-_apply_macro(Macro, std::wstring, Arg2);
-_apply_macro(Macro, std::complex<float>, Arg2);
-_apply_macro(Macro, std::complex<double>, Arg2);
-%enddef
-
-/* apply the Macro2(Type1, Type2) to all C++ types */
-#define %apply_cpptypes_2(Macro2) %apply_cpptypes(%apply_cpptypes, Macro2)
-
-/* apply the Macro2(CheckCode,Type) to all Checked Types */
-%define %apply_checkctypes(Macro2)
-Macro2(%checkcode(BOOL), bool);
-Macro2(%checkcode(INT8), signed char);
-Macro2(%checkcode(UINT8), unsigned char);
-Macro2(%checkcode(INT16), short);
-Macro2(%checkcode(UINT16), unsigned short);
-Macro2(%checkcode(INT32), int);
-Macro2(%checkcode(UINT32), unsigned int);
-Macro2(%checkcode(INT64), long);
-Macro2(%checkcode(UINT64), unsigned long);
-Macro2(%checkcode(INT128), long long);
-Macro2(%checkcode(UINT128), unsigned long long);
-Macro2(%checkcode(FLOAT), float);
-Macro2(%checkcode(DOUBLE), double);
-Macro2(%checkcode(CHAR), char);
-Macro2(%checkcode(UNICHAR), wchar_t);
-Macro2(%checkcode(SIZE), size_t);
-Macro2(%checkcode(PTRDIFF), ptrdiff_t);
-%enddef
-
-
-/* ------------------------------------------------------------
- * Generate the typemaps for all the primitive types with checkcode
- * ------------------------------------------------------------ */
-
-%apply_checkctypes(%typemaps_primitive);
-
diff --git a/contrib/tools/swig/Lib/typemaps/ptrtypes.swg b/contrib/tools/swig/Lib/typemaps/ptrtypes.swg
deleted file mode 100644
index ca54fcdc26..0000000000
--- a/contrib/tools/swig/Lib/typemaps/ptrtypes.swg
+++ /dev/null
@@ -1,208 +0,0 @@
-/* -----------------------------------------------------------------------------
- * ptrtypes.swg
- *
- * Value typemaps (Type, const Type&) for "Ptr" types, such as swig
- * wrapped classes, that define the AsPtr/From methods
- *
- * To apply them, just use one of the following macros:
- *
- * %typemaps_asptr(CheckCode, AsPtrMeth, AsPtrFrag, Type)
- * %typemaps_asptrfrom(CheckCode, AsPtrMeth, FromMeth, AsPtrFrag, FromFrag, Type)
- *
- * or the simpler and normalize form:
- *
- * %typemaps_asptrfromn(CheckCode, Type)
- *
- * Also, you can use the individual typemap definitions:
- *
- * %ptr_in_typemap(asptr_meth,frag,Type)
- * %ptr_varin_typemap(asptr_meth,frag,Type)
- * %ptr_typecheck_typemap(check,asptr_meth,frag,Type)
- * %ptr_directorout_typemap(asptr_meth,frag,Type)
- * ----------------------------------------------------------------------------- */
-
-%include <typemaps/valtypes.swg>
-
-/* in */
-
-%define %ptr_in_typemap(asptr_meth,frag,Type...)
- %typemap(in,fragment=frag) Type {
- Type *ptr = (Type *)0;
- int res = asptr_meth($input, &ptr);
- if (!SWIG_IsOK(res) || !ptr) {
- %argument_fail((ptr ? res : SWIG_TypeError), "$type", $symname, $argnum);
- }
- $1 = *ptr;
- if (SWIG_IsNewObj(res)) %delete(ptr);
- }
- %typemap(freearg) Type ""
- %typemap(in,fragment=frag) const Type & (int res = SWIG_OLDOBJ) {
- Type *ptr = (Type *)0;
- res = asptr_meth($input, &ptr);
- if (!SWIG_IsOK(res)) { %argument_fail(res,"$type",$symname, $argnum); }
- if (!ptr) { %argument_nullref("$type",$symname, $argnum); }
- $1 = ptr;
- }
- %typemap(freearg,noblock=1) const Type & {
- if (SWIG_IsNewObj(res$argnum)) %delete($1);
- }
-%enddef
-
-/* varin */
-
-%define %ptr_varin_typemap(asptr_meth,frag,Type...)
- %typemap(varin,fragment=frag) Type {
- Type *ptr = (Type *)0;
- int res = asptr_meth($input, &ptr);
- if (!SWIG_IsOK(res) || !ptr) {
- %variable_fail((ptr ? res : SWIG_TypeError), "$type", "$name");
- }
- $1 = *ptr;
- if (SWIG_IsNewObj(res)) %delete(ptr);
- }
-%enddef
-
-#if defined(SWIG_DIRECTOR_TYPEMAPS)
-/* directorout */
-
-%define %ptr_directorout_typemap(asptr_meth,frag,Type...)
- %typemap(directorargout,noblock=1,fragment=frag) Type *DIRECTOROUT ($*ltype temp, int swig_ores) {
- Type *swig_optr = 0;
- swig_ores = $result ? asptr_meth($result, &swig_optr) : 0;
- if (!SWIG_IsOK(swig_ores) || !swig_optr) {
- %dirout_fail((swig_optr ? swig_ores : SWIG_TypeError),"$type");
- }
- temp = *swig_optr;
- $1 = &temp;
- if (SWIG_IsNewObj(swig_ores)) %delete(swig_optr);
- }
-
- %typemap(directorout,noblock=1,fragment=frag) Type {
- Type *swig_optr = 0;
- int swig_ores = asptr_meth($input, &swig_optr);
- if (!SWIG_IsOK(swig_ores) || !swig_optr) {
- %dirout_fail((swig_optr ? swig_ores : SWIG_TypeError),"$type");
- }
- $result = *swig_optr;
- if (SWIG_IsNewObj(swig_ores)) %delete(swig_optr);
- }
-
- %typemap(directorout,noblock=1,fragment=frag,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) Type* {
- Type *swig_optr = 0;
- int swig_ores = asptr_meth($input, &swig_optr);
- if (!SWIG_IsOK(swig_ores)) {
- %dirout_fail(swig_ores,"$type");
- }
- $result = swig_optr;
- if (SWIG_IsNewObj(swig_ores)) {
- swig_acquire_ownership(swig_optr);
- }
- }
- %typemap(directorfree,noblock=1) Type*
- {
- if (director) {
- director->swig_release_ownership(%as_voidptr($input));
- }
- }
-
- %typemap(directorout,noblock=1,fragment=frag,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) Type& {
- Type *swig_optr = 0;
- int swig_ores = asptr_meth($input, &swig_optr);
- if (!SWIG_IsOK(swig_ores)) {
- %dirout_fail(swig_ores,"$type");
- } else {
- if (!swig_optr) {
- %dirout_nullref("$type");
- }
- }
- $result = swig_optr;
- if (SWIG_IsNewObj(swig_ores)) {
- swig_acquire_ownership(swig_optr);
- }
- }
- %typemap(directorfree,noblock=1) Type&
- {
- if (director) {
- director->swig_release_ownership(%as_voidptr($input));
- }
- }
-
-
- %typemap(directorout,fragment=frag) Type &DIRECTOROUT = Type
-
-%enddef
-
-#else
-
-#define %ptr_directorout_typemap(asptr_meth,frag,Type...)
-
-#endif /* SWIG_DIRECTOR_TYPEMAPS */
-
-/* typecheck */
-
-%define %ptr_typecheck_typemap(check,asptr_meth,frag,Type...)
-%typemap(typecheck,noblock=1,precedence=check,fragment=frag) Type * {
- int res = asptr_meth($input, (Type**)(0));
- $1 = SWIG_CheckState(res);
-}
-
-%typemap(typecheck,noblock=1,precedence=check,fragment=frag) Type, const Type& {
- int res = asptr_meth($input, (Type**)(0));
- $1 = SWIG_CheckState(res);
-}
-%enddef
-
-
-/*---------------------------------------------------------------------
- * typemap definition for types with asptr method
- *---------------------------------------------------------------------*/
-
-%define %typemaps_asptr(CheckCode, AsPtrMeth, AsPtrFrag, Type...)
- %fragment(SWIG_AsVal_frag(Type),"header",fragment=SWIG_AsPtr_frag(Type)) {
- SWIGINTERNINLINE int
- SWIG_AsVal(Type)(SWIG_Object obj, Type *val)
- {
- Type *v = (Type *)0;
- int res = SWIG_AsPtr(Type)(obj, &v);
- if (!SWIG_IsOK(res)) return res;
- if (v) {
- if (val) *val = *v;
- if (SWIG_IsNewObj(res)) {
- %delete(v);
- res = SWIG_DelNewMask(res);
- }
- return res;
- }
- return SWIG_ERROR;
- }
- }
- %ptr_in_typemap(%arg(AsPtrMeth), %arg(AsPtrFrag), Type);
- %ptr_varin_typemap(%arg(AsPtrMeth), %arg(AsPtrFrag), Type);
- %ptr_directorout_typemap(%arg(AsPtrMeth), %arg(AsPtrFrag), Type);
- %ptr_typecheck_typemap(%arg(CheckCode), %arg(AsPtrMeth),%arg(AsPtrFrag), Type);
- %ptr_input_typemap(%arg(CheckCode),%arg(AsPtrMeth),%arg(AsPtrFrag),Type);
-%enddef
-
-/*---------------------------------------------------------------------
- * typemap definition for types with asptr/from methods
- *---------------------------------------------------------------------*/
-
-%define %typemaps_asptrfrom(CheckCode, AsPtrMeth, FromMeth, AsPtrFrag, FromFrag, Type...)
- %typemaps_asptr(%arg(CheckCode), %arg(AsPtrMeth), %arg(AsPtrFrag), Type)
- %typemaps_from(%arg(FromMeth), %arg(FromFrag), Type);
- %value_output_typemap(%arg(FromMeth), %arg(FromFrag), Type);
- %ptr_inout_typemap(Type);
-%enddef
-
-/*---------------------------------------------------------------------
- * typemap definition for types with for 'normalized' asptr/from methods
- *---------------------------------------------------------------------*/
-
-%define %typemaps_asptrfromn(CheckCode, Type...)
-%typemaps_asptrfrom(%arg(CheckCode),
- %arg(SWIG_AsPtr(Type)),
- %arg(SWIG_From(Type)),
- %arg(SWIG_AsPtr_frag(Type)),
- %arg(SWIG_From_frag(Type)),
- Type);
-%enddef
diff --git a/contrib/tools/swig/Lib/typemaps/string.swg b/contrib/tools/swig/Lib/typemaps/string.swg
deleted file mode 100644
index 72f4aa5b56..0000000000
--- a/contrib/tools/swig/Lib/typemaps/string.swg
+++ /dev/null
@@ -1,36 +0,0 @@
-%ensure_fragment(SWIG_AsCharPtrAndSize)
-%ensure_fragment(SWIG_FromCharPtrAndSize)
-
-%types(char *);
-
-%fragment("SWIG_pchar_descriptor","header") {
-SWIGINTERN swig_type_info*
-SWIG_pchar_descriptor(void)
-{
- static int init = 0;
- static swig_type_info* info = 0;
- if (!init) {
- info = SWIG_TypeQuery("_p_char");
- init = 1;
- }
- return info;
-}
-}
-
-%fragment("SWIG_strnlen","header",fragment="SWIG_FromCharPtrAndSize") {
-SWIGINTERN size_t
-SWIG_strnlen(const char* s, size_t maxlen)
-{
- const char *p;
- for (p = s; maxlen-- && *p; p++)
- ;
- return p - s;
-}
-}
-
-%include <typemaps/strings.swg>
-%typemaps_string(%checkcode(STRING), %checkcode(CHAR),
- SWIGWARN_TYPEMAP_CHARLEAK_MSG,
- char, Char, SWIG_AsCharPtrAndSize, SWIG_FromCharPtrAndSize,
- strlen, SWIG_strnlen,
- "<limits.h>", CHAR_MIN, CHAR_MAX)
diff --git a/contrib/tools/swig/Lib/typemaps/strings.swg b/contrib/tools/swig/Lib/typemaps/strings.swg
deleted file mode 100644
index 1237d98dfd..0000000000
--- a/contrib/tools/swig/Lib/typemaps/strings.swg
+++ /dev/null
@@ -1,658 +0,0 @@
-//
-// Use the macro SWIG_PRESERVE_CARRAY_SIZE if you prefer to preserve
-// the size of char arrays, ie
-// ------------------------------------------
-// C Side => Language Side
-// ------------------------------------------
-// char name[5] = "hola" => 'hola\0'
-//
-// the default behaviour is
-//
-// char name[5] = "hola" => 'hola'
-//
-//
-//#define SWIG_PRESERVE_CARRAY_SIZE
-
-/* ------------------------------------------------------------
- * String typemaps for type Char (char or wchar_t)
- * ------------------------------------------------------------ */
-
-%define %_typemap_string(StringCode,
- Char,
- WarningLeakMsg,
- SWIG_AsCharPtrAndSize,
- SWIG_FromCharPtrAndSize,
- SWIG_CharPtrLen,
- SWIG_CharBufLen,
- SWIG_AsCharPtr,
- SWIG_FromCharPtr,
- SWIG_AsCharArray,
- SWIG_NewCopyCharArray,
- SWIG_DeleteCharArray)
-
-/* in */
-
-%typemap(in,noblock=1,fragment=#SWIG_AsCharPtr)
- Char * (int res, Char *buf = 0, int alloc = 0),
- const Char * (int res, Char *buf = 0, int alloc = 0) {
- res = SWIG_AsCharPtr($input, &buf, &alloc);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res,"$type",$symname, $argnum);
- }
- $1 = %reinterpret_cast(buf, $1_ltype);
-}
-%typemap(freearg,noblock=1,match="in") Char *, const Char * {
- if (alloc$argnum == SWIG_NEWOBJ) SWIG_DeleteCharArray(buf$argnum);
-}
-
-%typemap(in,noblock=1,fragment=#SWIG_AsCharPtr) Char const*& (int res, Char *buf = 0, int alloc = 0) {
- res = SWIG_AsCharPtr($input, &buf, &alloc);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res,"$type",$symname, $argnum);
- }
- $1 = &buf;
-}
-%typemap(freearg, noblock=1,match="in") Char const*& {
- if (alloc$argnum == SWIG_NEWOBJ) SWIG_DeleteCharArray(buf$argnum);
-}
-
-/* out */
-
-%typemap(out,noblock=1,fragment=#SWIG_FromCharPtr) Char *, const Char * {
- %set_output(SWIG_FromCharPtr((const Char *)$1));
-}
-
-
-%typemap(out,noblock=1,fragment=#SWIG_FromCharPtr) Char const*& {
- %set_output(SWIG_FromCharPtr(*$1));
-}
-
-%typemap(newfree,noblock=1) Char * {
- SWIG_DeleteCharArray($1);
-}
-
-/* varin */
-
-%typemap(varin,fragment=#SWIG_AsCharPtrAndSize) Char * {
- Char *cptr = 0; size_t csize = 0; int alloc = SWIG_NEWOBJ;
- int res = SWIG_AsCharPtrAndSize($input, &cptr, &csize, &alloc);
- if (!SWIG_IsOK(res)) {
- %variable_fail(res,"$type","$name");
- }
- SWIG_DeleteCharArray($1);
- if (alloc == SWIG_NEWOBJ) {
- $1 = cptr;
- } else {
- $1 = csize ? ($1_type)SWIG_NewCopyCharArray(cptr, csize, Char) : 0;
- }
-}
-
-%typemap(varin,fragment=#SWIG_AsCharPtrAndSize,warning=WarningLeakMsg) const Char * {
- Char *cptr = 0; size_t csize = 0; int alloc = SWIG_NEWOBJ;
- int res = SWIG_AsCharPtrAndSize($input, &cptr, &csize, &alloc);
- if (!SWIG_IsOK(res)) {
- %variable_fail(res, "$type", "$name");
- }
- if (alloc == SWIG_NEWOBJ) {
- $1 = cptr;
- } else {
- $1 = csize ? ($1_type)SWIG_NewCopyCharArray(cptr, csize, Char) : 0;
- }
-}
-
-/* varout */
-
-%typemap(varout,noblock=1,fragment=#SWIG_FromCharPtr) Char *, const Char * {
- %set_varoutput(SWIG_FromCharPtr($1));
-}
-
-/* memberin */
-
-%typemap(memberin,noblock=1) Char * {
- SWIG_DeleteCharArray($1);
- if ($input) {
- size_t size = SWIG_CharPtrLen(%reinterpret_cast($input, const Char *)) + 1;
- $1 = ($1_type)SWIG_NewCopyCharArray(%reinterpret_cast($input, const Char *), size, Char);
- } else {
- $1 = 0;
- }
-}
-
-%typemap(memberin,noblock=1,warning=WarningLeakMsg) const Char * {
- if ($input) {
- size_t size = SWIG_CharPtrLen(%reinterpret_cast(%reinterpret_cast($input, const Char *), const Char *)) + 1;
- $1 = ($1_type)SWIG_NewCopyCharArray($input, size, Char);
- } else {
- $1 = 0;
- }
-}
-
-/* globalin */
-
-%typemap(globalin,noblock=1) Char * {
- SWIG_DeleteCharArray($1);
- if ($input) {
- size_t size = SWIG_CharPtrLen(%reinterpret_cast(%reinterpret_cast($input, const Char *), const Char *)) + 1;
- $1 = ($1_type)SWIG_NewCopyCharArray($input, size, Char);
- } else {
- $1 = 0;
- }
-}
-
-%typemap(globalin,noblock=1,warning=WarningLeakMsg) const Char * {
- if ($input) {
- size_t size = SWIG_CharPtrLen($input) + 1;
- $1 = ($1_type)SWIG_NewCopyCharArray($input, size, Char);
- } else {
- $1 = 0;
- }
-}
-
-/* constant */
-
-%typemap(constcode,noblock=1,fragment=#SWIG_FromCharPtr)
- Char *, Char const*, Char * const, Char const* const {
- %set_constant("$symname", SWIG_FromCharPtr($value));
-}
-
-
-#if defined(SWIG_DIRECTOR_TYPEMAPS)
-
-/* directorin */
-
-%typemap(directorin,noblock=1,fragment=#SWIG_FromCharPtr)
- Char *, Char const*, Char *const, Char const *const,
- Char const *&, Char *const &, Char const *const & {
- $input = SWIG_FromCharPtr((const Char *)$1);
-}
-
-
-/* directorout */
-
-%typemap(directorout,noblock=1,fragment=#SWIG_AsCharPtr,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) Char * (int res, Char *buf = 0, int alloc = SWIG_NEWOBJ) {
- res = SWIG_AsCharPtr($input, &buf, &alloc);
- if (!SWIG_IsOK(res)) {
- %dirout_fail(res, "$type");
- }
- if (alloc == SWIG_NEWOBJ) {
- swig_acquire_ownership_array(buf);
- }
- $result = %reinterpret_cast(buf, $1_ltype);
-}
-%typemap(directorfree,noblock=1) Char *
-{
- if (director) {
- director->swig_release_ownership(%as_voidptr($input));
- }
-}
-
-
-%typemap(directorout,noblock=1,fragment=#SWIG_AsCharPtr,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) Char *const& (int res, Char *buf = 0, int alloc = SWIG_NEWOBJ), Char const*const& (int res, Char *buf = 0, int alloc = SWIG_NEWOBJ) {
- res = SWIG_AsCharPtr($input, &buf, &alloc);
- if (!SWIG_IsOK(res)) {
- %dirout_fail(res, "$type");
- }
- static $*1_ltype tmp = buf;
- $result = &tmp;
- if (alloc == SWIG_NEWOBJ) {
- swig_acquire_ownership_array(buf);
- }
-}
-%typemap(directorfree,noblock=1)
- Char * const&, Char const* const& {
- if (director) {
- director->swig_release_ownership(%as_voidptr(*$input));
- }
-}
-
-#endif /* SWIG_DIRECTOR_TYPEMAPS */
-
-/* typecheck */
-
-%typemap(typecheck,noblock=1,precedence=StringCode,
- fragment=#SWIG_AsCharPtr) Char *, const Char *, Char const*& {
- int res = SWIG_AsCharPtr($input, 0, 0);
- $1 = SWIG_CheckState(res);
-}
-
-
-/* throws */
-
-%typemap(throws,noblock=1,fragment=#SWIG_FromCharPtr) Char * {
- %raise(SWIG_FromCharPtr($1), "$type", 0);
-}
-
-
-/* ------------------------------------------------------------
- * Unknown size const Character array Char[ANY] handling
- * ------------------------------------------------------------ */
-
-%apply Char * { Char [] };
-%apply const Char * { const Char [] };
-
-%typemap(varin,noblock=1,warning="462:Unable to set variable of type Char []") Char []
-{
- %variable_fail(SWIG_AttributeError, "$type", "read-only $name");
-}
-
-
-/* ------------------------------------------------------------
- * Fixed size Character array Char[ANY] handling
- * ------------------------------------------------------------ */
-
-/* memberin and globalin typemaps */
-
-%typemap(memberin,noblock=1) Char [ANY]
-{
- if ($input) memcpy($1,$input,$1_dim0*sizeof(Char));
- else memset($1,0,$1_dim0*sizeof(Char));
-}
-
-%typemap(globalin,noblock=1) Char [ANY]
-{
- if ($input) memcpy($1,$input,$1_dim0*sizeof(Char));
- else memset($1,0,$1_dim0*sizeof(Char));
-}
-
-/* in */
-
-%typemap(in,noblock=1,fragment=#SWIG_AsCharArray)
- Char [ANY] (Char temp[$1_dim0], int res),
- const Char [ANY](Char temp[$1_dim0], int res)
-{
- res = SWIG_AsCharArray($input, temp, $1_dim0);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res,"$type",$symname, $argnum);
- }
- $1 = %reinterpret_cast(temp, $1_ltype);
-}
-%typemap(freearg) Char [ANY], const Char [ANY] ""
-
-%typemap(in,noblock=1,fragment=#SWIG_AsCharArray) const Char (&)[ANY] (Char temp[$1_dim0], int res)
-{
- res = SWIG_AsCharArray($input, temp, $1_dim0);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res,"$type",$symname, $argnum);
- }
- $1 = &temp;
-}
-%typemap(freearg) const Char (&)[ANY] ""
-
-%typemap(out,fragment=#SWIG_FromCharPtrAndSize,fragment=#SWIG_CharBufLen)
- Char [ANY], const Char[ANY]
-{
-%#ifndef SWIG_PRESERVE_CARRAY_SIZE
- size_t size = SWIG_CharBufLen($1, $1_dim0);
-%#else
- size_t size = $1_dim0;
-%#endif
- %set_output(SWIG_FromCharPtrAndSize($1, size));
-}
-
-/* varin */
-
-%typemap(varin,fragment=#SWIG_AsCharArray) Char [ANY]
-{
- int res = SWIG_AsCharArray($input, $1, $1_dim0);
- if (!SWIG_IsOK(res)) {
- %variable_fail(res, "$type", "$name");
- }
-}
-
-/* varout */
-
-%typemap(varout,fragment=#SWIG_CharBufLen)
- Char [ANY], const Char [ANY] {
-%#ifndef SWIG_PRESERVE_CARRAY_SIZE
- size_t size = SWIG_CharBufLen($1, $1_dim0);
-%#else
- size_t size = $1_dim0;
-%#endif
- %set_varoutput(SWIG_FromCharPtrAndSize($1, size));
-}
-
-/* constant */
-
-%typemap(constcode,fragment=#SWIG_CharBufLen)
- Char [ANY], const Char [ANY]
-{
-%#ifndef SWIG_PRESERVE_CARRAY_SIZE
- size_t size = SWIG_CharBufLen($1, $1_dim0);
-%#else
- size_t size = $value_dim0;
-%#endif
- %set_constant("$symname", SWIG_FromCharPtrAndSize($value,size));
-}
-
-
-#if defined(SWIG_DIRECTOR_TYPEMAPS)
-
-/* directorin */
-%typemap(directorin,fragment=#SWIG_CharBufLen)
- Char [ANY], const Char [ANY]
-{
-%#ifndef SWIG_PRESERVE_CARRAY_SIZE
- size_t size = SWIG_CharBufLen($1, $1_dim0);
-%#else
- size_t size = $1_dim0;
-%#endif
- $input = SWIG_FromCharPtrAndSize($1, size);
-}
-
-/* directorout */
-
-%typemap(directorout,noblock=1,fragment=#SWIG_AsCharArray)
- Char [ANY] (Char temp[$result_dim0]),
- const Char [ANY] (Char temp[$result_dim0], int res)
-{
- res = SWIG_AsCharArray($input, temp, $result_dim0);
- if (!SWIG_IsOK(res)) {
- %dirout_fail(res, "$type");
- }
- $result = temp;
-}
-
-#endif /* SWIG_DIRECTOR_TYPEMAPS */
-
-/* typecheck */
-
-%typemap(typecheck,noblock=1,precedence=StringCode,
- fragment=#SWIG_AsCharArray)
- Char [ANY], const Char[ANY] {
- int res = SWIG_AsCharArray($input, (Char *)0, $1_dim0);
- $1 = SWIG_CheckState(res);
-}
-
-
-/* throws */
-
-%typemap(throws,fragment=#SWIG_CharBufLen)
- Char [ANY], const Char[ANY]
-{
-%#ifndef SWIG_PRESERVE_CARRAY_SIZE
- size_t size = SWIG_CharBufLen($1, $1_dim0);
-%#else
- size_t size = $1_dim0;
-%#endif
- %raise(SWIG_FromCharPtrAndSize($1, size), "$type", 0);
-}
-
-/* -------------------------------------------------------------------
- * --- Really fix size Char arrays, including '\0'chars at the end ---
- * ------------------------------------------------------------------- */
-
-%typemap(varout,noblock=1,fragment=#SWIG_FromCharPtrAndSize)
- Char FIXSIZE[ANY], const Char FIXSIZE[ANY]
-{
- %set_varoutput(SWIG_FromCharPtrAndSize($1, $1_dim0));
-}
-
-%typemap(out,noblock=1,fragment=#SWIG_FromCharPtrAndSize)
- Char FIXSIZE[ANY], const Char FIXSIZE[ANY]
-{
- %set_output(SWIG_FromCharPtrAndSize($1, $1_dim0));
-}
-
-#if defined(SWIG_DIRECTOR_TYPEMAPS)
-
-%typemap(directorin,noblock=1,fragment=#SWIG_FromCharPtrAndSize)
- Char FIXSIZE[ANY], const Char FIXSIZE[ANY]
-{
- $input = SWIG_FromCharPtrAndSize($1, $1_dim0);
-}
-
-#endif /* SWIG_DIRECTOR_TYPEMAPS */
-
-%typemap(throws,noblock=1,fragment=#SWIG_FromCharPtrAndSize)
- Char FIXSIZE[ANY], const Char FIXSIZE[ANY] {
- %raise(SWIG_FromCharPtrAndSize($1, $1_dim0), "$type", 0);
-}
-
-/* ------------------------------------------------------------
- * --- String & length ---
- * ------------------------------------------------------------ */
-
-/* Here len doesn't include the '0' terminator */
-%typemap(in,noblock=1,fragment=#SWIG_AsCharPtrAndSize)
- (Char *STRING, size_t LENGTH) (int res, Char *buf = 0, size_t size = 0, int alloc = 0),
- (const Char *STRING, size_t LENGTH) (int res, Char *buf = 0, size_t size = 0, int alloc = 0)
-{
- res = SWIG_AsCharPtrAndSize($input, &buf, &size, &alloc);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res,"$type",$symname, $argnum);
- }
- $1 = %reinterpret_cast(buf, $1_ltype);
- $2 = %numeric_cast(size - 1, $2_ltype);
-}
-%typemap(freearg,noblock=1,match="in") (Char *STRING, size_t LENGTH) {
- if (alloc$argnum == SWIG_NEWOBJ) SWIG_DeleteCharArray(buf$argnum);
-}
-/* old 'int' form */
-%typemap(in) (Char *STRING, int LENGTH) = (Char *STRING, size_t LENGTH);
-%typemap(freearg) (Char *STRING, int LENGTH) = (Char *STRING, size_t LENGTH);
-
-
-/* Here size includes the '0' terminator */
-%typemap(in,noblock=1,fragment=#SWIG_AsCharPtrAndSize)
- (Char *STRING, size_t SIZE) (int res, Char *buf = 0, size_t size = 0, int alloc = 0),
- (const Char *STRING, size_t SIZE) (int res, Char *buf = 0, size_t size = 0, int alloc = 0)
-{
- res = SWIG_AsCharPtrAndSize($input, &buf, &size, &alloc);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res,"$type",$symname, $argnum);
- }
- $1 = %reinterpret_cast(buf, $1_ltype);
- $2 = %numeric_cast(size, $2_ltype);
-}
-%typemap(freearg,noblock=1,match="in") (Char *STRING, size_t SIZE) {
- if (alloc$argnum == SWIG_NEWOBJ) SWIG_DeleteCharArray(buf$argnum);
-}
-/* old 'int' form */
-%typemap(in) (Char *STRING, int SIZE) = (Char *STRING, size_t SIZE);
-%typemap(freearg) (Char *STRING, int SIZE) = (Char *STRING, size_t SIZE);
-
-
-/* reverse order versions */
-
-/* Here len doesn't include the '0' terminator */
-%typemap(in,noblock=1,fragment=#SWIG_AsCharPtrAndSize)
- (size_t LENGTH, Char *STRING) (int res, Char *buf = 0, size_t size = 0, int alloc = 0),
- (size_t LENGTH, const Char *STRING) (int res, Char *buf = 0, size_t size = 0, int alloc = 0)
-{
- res = SWIG_AsCharPtrAndSize($input, &buf, &size, &alloc);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res,"$type",$symname, $argnum);
- }
- $2 = %reinterpret_cast(buf, $2_ltype) ;
- $1 = %numeric_cast(size - 1, $1_ltype) ;
-}
-%typemap(freearg, noblock=1, match="in") (size_t LENGTH, Char *STRING) {
- if (alloc$argnum == SWIG_NEWOBJ) SWIG_DeleteCharArray(buf$argnum);
-}
-/* old 'int' form */
-%typemap(in) (int LENGTH, Char *STRING) = (size_t LENGTH, Char *STRING);
-%typemap(freearg) (int LENGTH, Char *STRING) = (size_t LENGTH, Char *STRING);
-
-/* Here size includes the '0' terminator */
-%typemap(in,noblock=1,fragment=#SWIG_AsCharPtrAndSize)
- (size_t SIZE, Char *STRING) (int res, Char *buf = 0, size_t size = 0, int alloc = 0),
- (size_t SIZE, const Char *STRING) (int res, Char *buf = 0, size_t size = 0, int alloc = 0)
-{
- res = SWIG_AsCharPtrAndSize($input, &buf, &size, &alloc);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res, "$type",$symname, $argnum);
- }
- $2 = %reinterpret_cast(buf, $2_ltype) ;
- $1 = %numeric_cast(size, $1_ltype) ;
-}
-%typemap(freearg, noblock=1, match="in") (size_t SIZE, Char *STRING) {
- if (alloc$argnum == SWIG_NEWOBJ) SWIG_DeleteCharArray(buf$argnum);
-}
-/* old 'int' form */
-%typemap(in) (int SIZE, Char *STRING) = (size_t SIZE, Char *STRING);
-%typemap(freearg) (int SIZE, Char *STRING) = (size_t SIZE, Char *STRING);
-
-
-%enddef
-
-
-/* ------------------------------------------------------------
- * --- String fragment methods ---
- * ------------------------------------------------------------ */
-
-#ifndef %_typemap2_string
-%define %_typemap2_string(StringCode, CharCode,
- WarningLeakMsg,
- Char, CharName,
- SWIG_AsCharPtrAndSize,
- SWIG_FromCharPtrAndSize,
- SWIG_CharPtrLen,
- SWIG_CharBufLen,
- SWIG_NewCopyCharArray,
- SWIG_DeleteCharArray,
- FragLimits, CHAR_MIN, CHAR_MAX)
-
-%fragment("SWIG_From"#CharName"Ptr","header",fragment=#SWIG_FromCharPtrAndSize) {
-SWIGINTERNINLINE SWIG_Object
-SWIG_From##CharName##Ptr(const Char *cptr)
-{
- return SWIG_FromCharPtrAndSize(cptr, (cptr ? SWIG_CharPtrLen(cptr) : 0));
-}
-}
-
-%fragment("SWIG_From"#CharName"Array","header",fragment=#SWIG_FromCharPtrAndSize) {
-SWIGINTERNINLINE SWIG_Object
-SWIG_From##CharName##Array(const Char *cptr, size_t size)
-{
- return SWIG_FromCharPtrAndSize(cptr, size);
-}
-}
-
-%fragment("SWIG_As" #CharName "Ptr","header",fragment=#SWIG_AsCharPtrAndSize) {
-%define_as(SWIG_As##CharName##Ptr(obj, val, alloc), SWIG_AsCharPtrAndSize(obj, val, NULL, alloc))
-}
-
-%fragment("SWIG_As" #CharName "Array","header",fragment=#SWIG_AsCharPtrAndSize) {
-SWIGINTERN int
-SWIG_As##CharName##Array(SWIG_Object obj, Char *val, size_t size)
-{
- Char* cptr = 0; size_t csize = 0; int alloc = SWIG_OLDOBJ;
- int res = SWIG_AsCharPtrAndSize(obj, &cptr, &csize, &alloc);
- if (SWIG_IsOK(res)) {
- /* special case of single char conversion when we don't need space for NUL */
- if (size == 1 && csize == 2 && cptr && !cptr[1]) --csize;
- if (csize <= size) {
- if (val) {
- if (csize) memcpy(val, cptr, csize*sizeof(Char));
- if (csize < size) memset(val + csize, 0, (size - csize)*sizeof(Char));
- }
- if (alloc == SWIG_NEWOBJ) {
- SWIG_DeleteCharArray(cptr);
- res = SWIG_DelNewMask(res);
- }
- return res;
- }
- if (alloc == SWIG_NEWOBJ) SWIG_DeleteCharArray(cptr);
- }
- return SWIG_TypeError;
-}
-}
-
-/* Char */
-
-%fragment(SWIG_From_frag(Char),"header",fragment=#SWIG_FromCharPtrAndSize) {
-SWIGINTERNINLINE SWIG_Object
-SWIG_From_dec(Char)(Char c)
-{
- return SWIG_FromCharPtrAndSize(&c,1);
-}
-}
-
-%fragment(SWIG_AsVal_frag(Char),"header",
- fragment="SWIG_As"#CharName"Array",
- fragment=FragLimits,
- fragment=SWIG_AsVal_frag(long)) {
-SWIGINTERN int
-SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val)
-{
- int res = SWIG_As##CharName##Array(obj, val, 1);
- if (!SWIG_IsOK(res)) {
- long v;
- res = SWIG_AddCast(SWIG_AsVal(long)(obj, &v));
- if (SWIG_IsOK(res)) {
- if ((CHAR_MIN <= v) && (v <= CHAR_MAX)) {
- if (val) *val = %numeric_cast(v, Char);
- } else {
- res = SWIG_OverflowError;
- }
- }
- }
- return res;
-}
-}
-
-%_typemap_string(StringCode,
- Char,
- WarningLeakMsg,
- SWIG_AsCharPtrAndSize,
- SWIG_FromCharPtrAndSize,
- SWIG_CharPtrLen,
- SWIG_CharBufLen,
- SWIG_As##CharName##Ptr,
- SWIG_From##CharName##Ptr,
- SWIG_As##CharName##Array,
- SWIG_NewCopyCharArray,
- SWIG_DeleteCharArray)
-
-%enddef
-#endif
-
-/* ------------------------------------------------------------
- * String typemaps and fragments, with default allocators
- * ------------------------------------------------------------ */
-
-%define %typemaps_string(StringCode, CharCode,
- WarningLeakMsg,
- Char, CharName,
- SWIG_AsCharPtrAndSize,
- SWIG_FromCharPtrAndSize,
- SWIG_CharPtrLen,
- SWIG_CharBufLen,
- FragLimits, CHAR_MIN, CHAR_MAX)
-%_typemap2_string(StringCode, CharCode,
- WarningLeakMsg,
- Char, CharName,
- SWIG_AsCharPtrAndSize,
- SWIG_FromCharPtrAndSize,
- SWIG_CharPtrLen,
- SWIG_CharBufLen,
- %new_copy_array,
- %delete_array,
- FragLimits, CHAR_MIN, CHAR_MAX)
-%enddef
-
-/* ------------------------------------------------------------
- * String typemaps and fragments, with custom allocators
- * ------------------------------------------------------------ */
-
-%define %typemaps_string_alloc(StringCode, CharCode,
- WarningLeakMsg,
- Char, CharName,
- SWIG_AsCharPtrAndSize,
- SWIG_FromCharPtrAndSize,
- SWIG_CharPtrLen,
- SWIG_CharBufLen,
- SWIG_NewCopyCharArray,
- SWIG_DeleteCharArray,
- FragLimits, CHAR_MIN, CHAR_MAX)
-%_typemap2_string(StringCode, CharCode,
- WarningLeakMsg,
- Char, CharName,
- SWIG_AsCharPtrAndSize,
- SWIG_FromCharPtrAndSize,
- SWIG_CharPtrLen,
- SWIG_CharBufLen,
- SWIG_NewCopyCharArray,
- SWIG_DeleteCharArray,
- FragLimits, CHAR_MIN, CHAR_MAX)
-%enddef
diff --git a/contrib/tools/swig/Lib/typemaps/swigmacros.swg b/contrib/tools/swig/Lib/typemaps/swigmacros.swg
deleted file mode 100644
index b772eb04b3..0000000000
--- a/contrib/tools/swig/Lib/typemaps/swigmacros.swg
+++ /dev/null
@@ -1,228 +0,0 @@
-/* -----------------------------------------------------------------------------
- * SWIG API. Portion only visible from SWIG
- * ----------------------------------------------------------------------------- */
-/*
- This file implements the internal macros of the 'SWIG API', which
- are useful to implement all the SWIG target languages.
-
- Basic preprocessor macros:
- --------------------------
-
- %arg(Arg) Safe argument wrap
- %str(Arg) Stringify the argument
- %begin_block Begin an execution block
- %end_block End an execution block
- %block(Block) Execute Block as an execution block
- %define_as(Def, Val) Define 'Def' as 'Val', expanding Def and Val first
- %ifcplusplus(V1, V2) if C++ Mode; then V1; else V2; fi
-
-
- Casting Operations:
- -------------------
-
- SWIG provides the following casting macros, which implement the
- corresponding C++ casting operations:
-
- %const_cast(a, Type) const_cast<Type >(a)
- %static_cast(a, Type) static_cast<Type >(a)
- %reinterpret_cast(a, Type) reinterpret_cast<Type >(a)
- %numeric_cast(a, Type) static_cast<Type >(a)
- %as_voidptr(a) const_cast<void *>(static_cast<const void *>(a))
- %as_voidptrptr(a) reinterpret_cast<void **>(a)
-
- or their C unsafe versions. In C++ we use the safe version unless
- SWIG_NO_CPLUSPLUS_CAST is defined
-
-
- Memory allocation:
- ------------------
-
- These allocation/freeing macros are safe to use in C or C++ and
- dispatch the proper new/delete/delete[] or free/malloc calls as
- needed.
-
- %new_instance(Type) Allocate a new instance of given Type
- %new_copy(value,Type) Allocate and initialize a new instance with 'value'
- %new_array(size,Type) Allocate a new array with given size and Type and zero initialize
- %new_copy_array(cptr,size,Type) Allocate and initialize a new array from 'cptr'
- %delete(cptr) Delete an instance
- %delete_array(cptr) Delete an array
-
-
- Auxiliary loop macros:
- ----------------------
-
- %formacro(Macro, Args...) or %formacro_1(Macro, Args...)
- for i in Args
- do
- Macro($i)
- done
-
- %formacro_2(Macro2, Args...)
- for i,j in Args
- do
- Macro2($i, $j)
- done
-
-
- Flags and conditional macros:
- -----------------------------
-
- %mark_flag(flag)
- flag := True
-
- %evalif(flag,expr)
- if flag; then
- expr
- fi
-
- %evalif_2(flag1 flag2,expr)
- if flag1 and flag2; then
- expr
- fi
-
-
-*/
-/* -----------------------------------------------------------------------------
- * Basic preprocessor macros
- * ----------------------------------------------------------------------------- */
-
-#define %arg(Arg...) Arg
-#define %str(Arg) `Arg`
-#ifndef %begin_block
-# define %begin_block do {
-#endif
-#ifndef %end_block
-# define %end_block } while(0)
-#endif
-#define %block(Block...) %begin_block Block; %end_block
-
-/* define a new macro */
-%define %define_as(Def, Val...)%#define Def Val %enddef
-
-/* include C++ or else value */
-%define %ifcplusplus(cppval, nocppval)
-#ifdef __cplusplus
-cppval
-#else
-nocppval
-#endif
-%enddef
-
-/* -----------------------------------------------------------------------------
- * Casting operators
- * ----------------------------------------------------------------------------- */
-
-#if defined(__cplusplus) && !defined(SWIG_NO_CPLUSPLUS_CAST)
-# define %const_cast(a,Type...) const_cast< Type >(a)
-# define %static_cast(a,Type...) static_cast< Type >(a)
-# define %reinterpret_cast(a,Type...) reinterpret_cast< Type >(a)
-# define %numeric_cast(a,Type...) static_cast< Type >(a)
-#else /* C case */
-# define %const_cast(a,Type...) (Type)(a)
-# define %static_cast(a,Type...) (Type)(a)
-# define %reinterpret_cast(a,Type...) (Type)(a)
-# define %numeric_cast(a,Type...) (Type)(a)
-#endif /* __cplusplus */
-
-
-#define %as_voidptr(a) SWIG_as_voidptr(a)
-#define %as_voidptrptr(a) SWIG_as_voidptrptr(a)
-
-%insert("header") {
-%define_as(SWIG_as_voidptr(a), %const_cast(%static_cast(a,const void *), void *))
-%define_as(SWIG_as_voidptrptr(a), ((void)%as_voidptr(*a),%reinterpret_cast(a, void**)))
-}
-
-
-/* -----------------------------------------------------------------------------
- * Allocating/freeing elements
- * ----------------------------------------------------------------------------- */
-
-#if defined(__cplusplus)
-# define %new_instance(Type...) (new Type())
-# define %new_copy(val,Type...) (new Type(%static_cast(val, const Type&)))
-# define %new_array(size,Type...) (new Type[size]())
-# define %new_copy_array(ptr,size,Type...) %reinterpret_cast(memcpy(new Type[size], ptr, sizeof(Type)*(size)), Type*)
-# define %delete(cptr) delete cptr
-# define %delete_array(cptr) delete[] cptr
-#else /* C case */
-# define %new_instance(Type...) (Type *)calloc(1,sizeof(Type))
-# define %new_copy(val,Type...) (Type *)memcpy(%new_instance(Type),&val,sizeof(Type))
-# define %new_array(size,Type...) (Type *)calloc(size, sizeof(Type))
-# define %new_copy_array(ptr,size,Type...) (Type *)memcpy(malloc((size)*sizeof(Type)), ptr, sizeof(Type)*(size))
-# define %delete(cptr) free((char*)cptr)
-# define %delete_array(cptr) free((char*)cptr)
-#endif /* __cplusplus */
-
-/* -----------------------------------------------------------------------------
- * SWIG names and mangling
- * ----------------------------------------------------------------------------- */
-
-#define %mangle(Type...) #@Type
-#define %descriptor(Type...) SWIGTYPE_ ## #@Type
-#define %string_name(Name) "SWIG_" %str(Name)
-#define %symbol_name(Name, Type...) SWIG_ ## Name ## _ #@Type
-#define %checkcode(Code) SWIG_TYPECHECK_ ## Code
-
-
-/* -----------------------------------------------------------------------------
- * Auxiliary loop macros
- * ----------------------------------------------------------------------------- */
-
-
-/* for loop for macro with one argument */
-%define %_formacro_1(macro, arg1,...)macro(arg1)
-#if #__VA_ARGS__ != "__fordone__"
-%_formacro_1(macro, __VA_ARGS__)
-#endif
-%enddef
-
-/* for loop for macro with one argument */
-%define %formacro_1(macro,...)%_formacro_1(macro,__VA_ARGS__,__fordone__)%enddef
-%define %formacro(macro,...)%_formacro_1(macro,__VA_ARGS__,__fordone__)%enddef
-
-/* for loop for macro with two arguments */
-%define %_formacro_2(macro, arg1, arg2, ...)macro(arg1, arg2)
-#if #__VA_ARGS__ != "__fordone__"
-%_formacro_2(macro, __VA_ARGS__)
-#endif
-%enddef
-
-/* for loop for macro with two arguments */
-%define %formacro_2(macro,...)%_formacro_2(macro, __VA_ARGS__, __fordone__)%enddef
-
-/* -----------------------------------------------------------------------------
- * SWIG flags
- * ----------------------------------------------------------------------------- */
-
-/*
- mark a flag, ie, define a macro name but ignore it in
- the interface.
-
- the flag can be later used with %evalif
-*/
-
-%define %mark_flag(x) %define x 1 %enddef %enddef
-
-
-/*
- %evalif and %evalif_2 are use to evaluate or process
- an expression if the given predicate is 'true' (1).
-*/
-%define %_evalif(_x,_expr)
-#if _x == 1
-_expr
-#endif
-%enddef
-
-%define %_evalif_2(_x,_y,_expr)
-#if _x == 1 && _y == 1
-_expr
-#endif
-%enddef
-
-%define %evalif(_x,_expr...) %_evalif(%arg(_x),%arg(_expr)) %enddef
-
-%define %evalif_2(_x,_y,_expr...) %_evalif_2(%arg(_x),%arg(_y),%arg(_expr)) %enddef
-
diff --git a/contrib/tools/swig/Lib/typemaps/swigobject.swg b/contrib/tools/swig/Lib/typemaps/swigobject.swg
deleted file mode 100644
index 26c6ba8edf..0000000000
--- a/contrib/tools/swig/Lib/typemaps/swigobject.swg
+++ /dev/null
@@ -1,37 +0,0 @@
-/* ------------------------------------------------------------
- * Language Object * - Just pass straight through unmodified
- * ------------------------------------------------------------ */
-
-%typemap(in) SWIG_Object "$1 = $input;"
-
-%typemap(in,noblock=1) SWIG_Object const & ($*ltype temp)
-{
- temp = %static_cast($input, $*ltype);
- $1 = &temp;
-}
-
-%typemap(out,noblock=1) SWIG_Object {
- %set_output($1);
-}
-
-%typemap(out,noblock=1) SWIG_Object const & {
- %set_output(*$1);
-}
-
-%typecheck(SWIG_TYPECHECK_SWIGOBJECT) SWIG_Object "$1 = ($input != 0);";
-
-%typemap(throws,noblock=1) SWIG_Object {
- %raise($1, "$type", 0);
-}
-
-%typemap(constcode,noblock=1) SWIG_Object {
- %set_constant("$symname", $value);
-}
-
-#if defined(SWIG_DIRECTOR_TYPEMAPS)
-
-%typemap(directorin) SWIG_Object "$input = $1;"
-%typemap(directorout) SWIG_Object "$result = $input;"
-
-#endif /* SWIG_DIRECTOR_TYPEMAPS */
-
diff --git a/contrib/tools/swig/Lib/typemaps/swigtype.swg b/contrib/tools/swig/Lib/typemaps/swigtype.swg
deleted file mode 100644
index 69f83794d2..0000000000
--- a/contrib/tools/swig/Lib/typemaps/swigtype.swg
+++ /dev/null
@@ -1,710 +0,0 @@
-/* -----------------------------------------------------------------------------
- * --- Input arguments ---
- * ----------------------------------------------------------------------------- */
-/* Pointers and arrays */
-%typemap(in, noblock=1) SWIGTYPE *(void *argp = 0, int res = 0) {
- res = SWIG_ConvertPtr($input, &argp,$descriptor, $disown | %convertptr_flags);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res, "$type", $symname, $argnum);
- }
- $1 = %reinterpret_cast(argp, $ltype);
-}
-%typemap(freearg) SWIGTYPE * ""
-
-%typemap(in, noblock=1) SWIGTYPE [] (void *argp = 0, int res = 0) {
- res = SWIG_ConvertPtr($input, &argp,$descriptor, $disown | %convertptr_flags);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res, "$type", $symname, $argnum);
- }
- $1 = %reinterpret_cast(argp, $ltype);
-}
-%typemap(freearg) SWIGTYPE [] ""
-
-
-%typemap(in, noblock=1) SWIGTYPE *const& (void *argp = 0, int res = 0, $*1_ltype temp) {
- res = SWIG_ConvertPtr($input, &argp, $*descriptor, $disown | %convertptr_flags);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res, "$*ltype", $symname, $argnum);
- }
- temp = %reinterpret_cast(argp, $*ltype);
- $1 = %reinterpret_cast(&temp, $1_ltype);
-}
-%typemap(freearg) SWIGTYPE *const& ""
-
-
-/* Reference */
-%typemap(in, noblock=1) SWIGTYPE & (void *argp = 0, int res = 0) {
- res = SWIG_ConvertPtr($input, &argp, $descriptor, %convertptr_flags);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res, "$type", $symname, $argnum);
- }
- if (!argp) { %argument_nullref("$type", $symname, $argnum); }
- $1 = %reinterpret_cast(argp, $ltype);
-}
-%typemap(freearg) SWIGTYPE & ""
-
-#if defined(__cplusplus) && defined(%implicitconv_flag)
-%typemap(in,noblock=1,implicitconv=1) const SWIGTYPE & (void *argp = 0, int res = 0) {
- res = SWIG_ConvertPtr($input, &argp, $descriptor, %convertptr_flags | %implicitconv_flag);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res, "$type", $symname, $argnum);
- }
- if (!argp) { %argument_nullref("$type", $symname, $argnum); }
- $1 = %reinterpret_cast(argp, $ltype);
-}
-%typemap(freearg,noblock=1,match="in",implicitconv=1) const SWIGTYPE &
-{
- if (SWIG_IsNewObj(res$argnum)) %delete($1);
-}
-#endif
-
-/* Rvalue reference */
-%typemap(in, noblock=1, fragment="<memory>") SWIGTYPE && (void *argp = 0, int res = 0, std::unique_ptr<$*1_ltype> rvrdeleter) {
- res = SWIG_ConvertPtr($input, &argp, $descriptor, SWIG_POINTER_RELEASE | %convertptr_flags);
- if (!SWIG_IsOK(res)) {
- if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
- %releasenotowned_fail(res, "$type", $symname, $argnum);
- } else {
- %argument_fail(res, "$type", $symname, $argnum);
- }
- }
- if (!argp) { %argument_nullref("$type", $symname, $argnum); }
- $1 = %reinterpret_cast(argp, $ltype);
- rvrdeleter.reset($1);
-}
-%typemap(freearg) SWIGTYPE && ""
-
-/* By value */
-#if defined(__cplusplus) && defined(%implicitconv_flag)
-%typemap(in,implicitconv=1) SWIGTYPE (void *argp, int res = 0) {
- res = SWIG_ConvertPtr($input, &argp, $&descriptor, %convertptr_flags | %implicitconv_flag);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res, "$type", $symname, $argnum);
- }
- if (!argp) {
- %argument_nullref("$type", $symname, $argnum);
- } else {
- $&ltype temp = %reinterpret_cast(argp, $&ltype);
- $1 = *temp;
- if (SWIG_IsNewObj(res)) %delete(temp);
- }
-}
-#else
-%typemap(in) SWIGTYPE (void *argp, int res = 0) {
- res = SWIG_ConvertPtr($input, &argp, $&descriptor, %convertptr_flags);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res, "$type", $symname, $argnum);
- }
- if (!argp) {
- %argument_nullref("$type", $symname, $argnum);
- } else {
- $1 = *(%reinterpret_cast(argp, $&ltype));
- }
-}
-#endif
-
-
-/* -----------------------------------------------------------------------------
- * --- Output arguments ---
- * ----------------------------------------------------------------------------- */
-
-/* Pointers, references */
-%typemap(out,noblock=1) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE[] {
- %set_output(SWIG_NewPointerObj(%as_voidptr($1), $descriptor, $owner | %newpointer_flags));
-}
-
-%typemap(out, noblock=1) SWIGTYPE *const& {
- %set_output(SWIG_NewPointerObj(%as_voidptr(*$1), $*descriptor, $owner | %newpointer_flags));
-}
-
-/* Return by value */
-#ifdef __cplusplus
-%typemap(out, noblock=1) SWIGTYPE {
- %set_output(SWIG_NewPointerObj((new $1_ltype($1)), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags));
-}
-#else
-%typemap(out, noblock=1) SWIGTYPE {
- %set_output(SWIG_NewPointerObj(%new_copy($1, $1_ltype), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags));
-}
-#endif
-
-/* -----------------------------------------------------------------------------
- * --- Variable input ---
- * ----------------------------------------------------------------------------- */
-
-/* memberin/globalin/varin, for fix arrays. */
-
-%typemap(memberin) SWIGTYPE [ANY] {
- if ($input) {
- size_t ii = 0;
- for (; ii < (size_t)$1_dim0; ++ii) *($1_basetype *)&$1[ii] = *(($1_basetype *)$input + ii);
- } else {
- %variable_nullref("$type","$name");
- }
-}
-
-%typemap(globalin) SWIGTYPE [ANY] {
- if ($input) {
- size_t ii = 0;
- for (; ii < (size_t)$1_dim0; ++ii) *($1_basetype *)&$1[ii] = *(($1_basetype *)$input + ii);
- } else {
- %variable_nullref("$type","$name");
- }
-}
-
-%typemap(varin) SWIGTYPE [ANY] {
- $basetype *inp = 0;
- int res = SWIG_ConvertPtr($input, %as_voidptrptr(&inp), $descriptor, %convertptr_flags);
- if (!SWIG_IsOK(res)) {
- %variable_fail(res, "$type", "$name");
- } else if (inp) {
- size_t ii = 0;
- for (; ii < (size_t)$1_dim0; ++ii) *($1_basetype *)&$1[ii] = *(($1_basetype *)inp + ii);
- } else {
- %variable_nullref("$type", "$name");
- }
-}
-
-
-/* memberin/globalin/varin, for fix double arrays. */
-
-%typemap(memberin) SWIGTYPE [ANY][ANY] {
- if ($input) {
- size_t ii = 0;
- for (; ii < (size_t)$1_dim0; ++ii) {
- if ($input[ii]) {
- size_t jj = 0;
- for (; jj < (size_t)$1_dim1; ++jj) $1[ii][jj] = $input[ii][jj];
- } else {
- %variable_nullref("$type","$name");
- }
- }
- } else {
- %variable_nullref("$type","$name");
- }
-}
-
-%typemap(globalin) SWIGTYPE [ANY][ANY] {
- if ($input) {
- size_t ii = 0;
- for (; ii < (size_t)$1_dim0; ++ii) {
- if ($input[ii]) {
- size_t jj = 0;
- for (; jj < (size_t)$1_dim1; ++jj) $1[ii][jj] = $input[ii][jj];
- } else {
- %variable_nullref("$type","$name");
- }
- }
- } else {
- %variable_nullref("$type","$name");
- }
-}
-
-%typemap(varin) SWIGTYPE [ANY][ANY] {
- $basetype (*inp)[$1_dim1] = 0;
- int res = SWIG_ConvertPtr($input, %as_voidptrptr(&inp), $descriptor, %convertptr_flags);
- if (!SWIG_IsOK(res)) {
- %variable_fail(res, "$type", "$name");
- } else if (inp) {
- size_t ii = 0;
- for (; ii < (size_t)$1_dim0; ++ii) {
- if (inp[ii]) {
- size_t jj = 0;
- for (; jj < (size_t)$1_dim1; ++jj) $1[ii][jj] = inp[ii][jj];
- } else {
- %variable_nullref("$type", "$name");
- }
- }
- } else {
- %variable_nullref("$type", "$name");
- }
-}
-
-/* Pointers, references, and variable size arrays */
-
-%typemap(varin,warning=SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) SWIGTYPE * {
- void *argp = 0;
- int res = SWIG_ConvertPtr($input, &argp, $descriptor, %convertptr_flags);
- if (!SWIG_IsOK(res)) {
- %variable_fail(res, "$type", "$name");
- }
- $1 = %reinterpret_cast(argp, $ltype);
-}
-
-%typemap(varin,noblock=1,warning="462:Unable to set dimensionless array variable") SWIGTYPE []
-{
- %variable_fail(SWIG_AttributeError, "$type", "read-only $name");
-}
-
-%typemap(varin,warning=SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) SWIGTYPE & {
- void *argp = 0;
- int res = SWIG_ConvertPtr($input, &argp, $descriptor, %convertptr_flags);
- if (!SWIG_IsOK(res)) {
- %variable_fail(res, "$type", "$name");
- }
- if (!argp) {
- %variable_nullref("$type", "$name");
- }
- $1 = *(%reinterpret_cast(argp, $ltype));
-}
-
-%typemap(varin,warning=SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) SWIGTYPE && {
- void *argp = 0;
- int res = SWIG_ConvertPtr($input, &argp, $descriptor, %convertptr_flags);
- if (!SWIG_IsOK(res)) {
- %variable_fail(res, "$type", "$name");
- }
- if (!argp) {
- %variable_nullref("$type", "$name");
- }
- $1 = *(%reinterpret_cast(argp, $ltype));
-}
-
-#if defined(__cplusplus) && defined(%implicitconv_flag)
-%typemap(varin,implicitconv=1) SWIGTYPE {
- void *argp = 0;
- int res = SWIG_ConvertPtr($input, &argp, $&descriptor, %convertptr_flags | %implicitconv_flag);
- if (!SWIG_IsOK(res)) {
- %variable_fail(res, "$type", "$name");
- }
- if (!argp) {
- %variable_nullref("$type", "$name");
- } else {
- $&type temp;
- temp = %reinterpret_cast(argp, $&type);
- $1 = *temp;
- if (SWIG_IsNewObj(res)) %delete(temp);
- }
-}
-#else
-%typemap(varin) SWIGTYPE {
- void *argp = 0;
- int res = SWIG_ConvertPtr($input, &argp, $&descriptor, %convertptr_flags);
- if (!SWIG_IsOK(res)) {
- %variable_fail(res, "$type", "$name");
- }
- if (!argp) {
- %variable_nullref("$type", "$name");
- } else {
- $1 = *(%reinterpret_cast(argp, $&type));
- }
-}
-#endif
-
-/* -----------------------------------------------------------------------------
- * --- Variable output ---
- * ----------------------------------------------------------------------------- */
-
-/* Pointers and arrays */
-%typemap(varout, noblock=1) SWIGTYPE * {
- %set_varoutput(SWIG_NewPointerObj(%as_voidptr($1), $descriptor, %newpointer_flags));
-}
-
-%typemap(varout, noblock=1) SWIGTYPE [] {
- %set_varoutput(SWIG_NewPointerObj(%as_voidptr($1), $descriptor, %newpointer_flags));
-}
-
-/* References */
-%typemap(varout, noblock=1) SWIGTYPE & {
- %set_varoutput(SWIG_NewPointerObj(%as_voidptr(&$1), $descriptor, %newpointer_flags));
-}
-
-%typemap(varout, noblock=1) SWIGTYPE && {
- %set_varoutput(SWIG_NewPointerObj(%as_voidptr(&$1), $descriptor, %newpointer_flags));
-}
-
-/* Value */
-%typemap(varout, noblock=1) SWIGTYPE {
- %set_varoutput(SWIG_NewPointerObj(%as_voidptr(&$1), $&descriptor, %newpointer_flags));
-}
-
-/* ------------------------------------------------------------
- * --- Typechecking rules ---
- * ------------------------------------------------------------ */
-
-%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) SWIGTYPE * {
- void *vptr = 0;
- int res = SWIG_ConvertPtr($input, &vptr, $descriptor, 0);
- $1 = SWIG_CheckState(res);
-}
-
-%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) SWIGTYPE *const& {
- void *vptr = 0;
- int res = SWIG_ConvertPtr($input, &vptr, $*descriptor, 0);
- $1 = SWIG_CheckState(res);
-}
-
-%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) SWIGTYPE & {
- void *vptr = 0;
- int res = SWIG_ConvertPtr($input, &vptr, $descriptor, SWIG_POINTER_NO_NULL);
- $1 = SWIG_CheckState(res);
-}
-
-%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) SWIGTYPE && {
- void *vptr = 0;
- int res = SWIG_ConvertPtr($input, &vptr, $descriptor, SWIG_POINTER_NO_NULL);
- $1 = SWIG_CheckState(res);
-}
-
-#if defined(__cplusplus) && defined(%implicitconv_flag)
-%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1,implicitconv=1) const SWIGTYPE & {
- int res = SWIG_ConvertPtr($input, 0, $descriptor, SWIG_POINTER_NO_NULL | %implicitconv_flag);
- $1 = SWIG_CheckState(res);
-}
-
-%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1,implicitconv=1) const SWIGTYPE && {
- int res = SWIG_ConvertPtr($input, 0, $descriptor, SWIG_POINTER_NO_NULL | %implicitconv_flag);
- $1 = SWIG_CheckState(res);
-}
-
-%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1,implicitconv=1) SWIGTYPE {
- int res = SWIG_ConvertPtr($input, 0, $&descriptor, SWIG_POINTER_NO_NULL | %implicitconv_flag);
- $1 = SWIG_CheckState(res);
-}
-#else
-%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) const SWIGTYPE & {
- void *vptr = 0;
- int res = SWIG_ConvertPtr($input, &vptr, $descriptor, SWIG_POINTER_NO_NULL);
- $1 = SWIG_CheckState(res);
-}
-
-%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) const SWIGTYPE && {
- void *vptr = 0;
- int res = SWIG_ConvertPtr($input, &vptr, $descriptor, SWIG_POINTER_NO_NULL);
- $1 = SWIG_CheckState(res);
-}
-
-%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) SWIGTYPE {
- void *vptr = 0;
- int res = SWIG_ConvertPtr($input, &vptr, $&descriptor, SWIG_POINTER_NO_NULL);
- $1 = SWIG_CheckState(res);
-}
-#endif
-
-/* -----------------------------------------------------------------------------
- * --- Director typemaps --- *
- * ----------------------------------------------------------------------------- */
-
-#if defined(SWIG_DIRECTOR_TYPEMAPS)
-
-/* directorin */
-
-%typemap(directorin,noblock=1) SWIGTYPE {
- $input = SWIG_NewPointerObj((new $1_ltype(SWIG_STD_MOVE($1))), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags);
-}
-
-%typemap(directorin,noblock=1) SWIGTYPE * {
- $input = SWIG_NewPointerObj(%as_voidptr($1), $descriptor, %newpointer_flags);
-}
-
-%typemap(directorin,noblock=1) SWIGTYPE *const& {
- $input = SWIG_NewPointerObj(%as_voidptr($1), $*descriptor, %newpointer_flags);
-}
-
-%typemap(directorin,noblock=1) SWIGTYPE & {
- $input = SWIG_NewPointerObj(%as_voidptr(&$1), $descriptor, %newpointer_flags);
-}
-
-%typemap(directorin,noblock=1) SWIGTYPE && {
- $input = SWIG_NewPointerObj(%as_voidptr(&$1_name), $descriptor, %newpointer_flags);
-}
-
-/* directorout */
-
-#if defined(__cplusplus) && defined(%implicitconv_flag)
-%typemap(directorout,noblock=1,implicitconv=1) SWIGTYPE (void * swig_argp, int swig_res = 0) {
- swig_res = SWIG_ConvertPtr($input,&swig_argp,$&descriptor, %convertptr_flags | %implicitconv_flag);
- if (!SWIG_IsOK(swig_res)) {
- %dirout_fail(swig_res,"$type");
- }
- $result = *(%reinterpret_cast(swig_argp, $&ltype));
- if (SWIG_IsNewObj(swig_res)) %delete(%reinterpret_cast(swig_argp, $&ltype));
-}
-#else
-%typemap(directorout,noblock=1) SWIGTYPE (void * swig_argp, int swig_res = 0) {
- swig_res = SWIG_ConvertPtr($input,&swig_argp,$&descriptor, %convertptr_flags);
- if (!SWIG_IsOK(swig_res)) {
- %dirout_fail(swig_res,"$type");
- }
- $result = *(%reinterpret_cast(swig_argp, $&ltype));
-}
-#endif
-
-%typemap(directorout,noblock=1,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG)
- SWIGTYPE *(void *swig_argp, int swig_res, swig_owntype own) {
- swig_res = SWIG_ConvertPtrAndOwn($input, &swig_argp, $descriptor, %convertptr_flags | SWIG_POINTER_DISOWN, &own);
- if (!SWIG_IsOK(swig_res)) {
- %dirout_fail(swig_res,"$type");
- }
- $result = %reinterpret_cast(swig_argp, $ltype);
- swig_acquire_ownership_obj(%as_voidptr($result), own /* & TODO: SWIG_POINTER_OWN */);
-}
-%typemap(directorfree,noblock=1,match="directorout") SWIGTYPE * {
- if (director) {
- SWIG_AcquirePtr($result, director->swig_release_ownership(%as_voidptr($input)));
- }
-}
-
-%typemap(directorout,noblock=1,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG)
- SWIGTYPE *const&(void *swig_argp, int swig_res, swig_owntype own) {
- swig_res = SWIG_ConvertPtrAndOwn($input, &swig_argp, $*descriptor, %convertptr_flags | SWIG_POINTER_DISOWN, &own);
- if (!SWIG_IsOK(swig_res)) {
- %dirout_fail(swig_res,"$type");
- }
- $1_ltype swig_temp = new $*1_ltype(($*1_ltype)swig_argp);
- swig_acquire_ownership(swig_temp);
- $result = swig_temp;
-}
-%typemap(directorfree,noblock=1,match="directorout") SWIGTYPE *const& {
- if (director) {
- SWIG_AcquirePtr($result, director->swig_release_ownership(%as_voidptr(*$input)));
- }
-}
-
-%typemap(directorout,noblock=1,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG)
- SWIGTYPE &(void *swig_argp, int swig_res, swig_owntype own) {
- swig_res = SWIG_ConvertPtrAndOwn($input, &swig_argp, $descriptor, %convertptr_flags | SWIG_POINTER_DISOWN, &own);
- if (!SWIG_IsOK(swig_res)) {
- %dirout_fail(swig_res,"$type");
- }
- if (!swig_argp) { %dirout_nullref("$type"); }
- $result = %reinterpret_cast(swig_argp, $ltype);
- swig_acquire_ownership_obj(%as_voidptr($result), own /* & TODO: SWIG_POINTER_OWN */);
-}
-%typemap(directorfree,noblock=1,match="directorout") SWIGTYPE & {
- if (director) {
- SWIG_AcquirePtr($result, director->swig_release_ownership(%as_voidptr($input)));
- }
-}
-
-%typemap(directorout,noblock=1,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG)
- SWIGTYPE &&(void *swig_argp, int swig_res, swig_owntype own) {
- swig_res = SWIG_ConvertPtrAndOwn($input, &swig_argp, $descriptor, %convertptr_flags | SWIG_POINTER_DISOWN, &own);
- if (!SWIG_IsOK(swig_res)) {
- %dirout_fail(swig_res,"$type");
- }
- if (!swig_argp) { %dirout_nullref("$type"); }
- $result = %reinterpret_cast(swig_argp, $ltype);
- swig_acquire_ownership_obj(%as_voidptr($result), own /* & TODO: SWIG_POINTER_OWN */);
-}
-%typemap(directorfree,noblock=1,match="directorout") SWIGTYPE && {
- if (director) {
- SWIG_AcquirePtr($result, director->swig_release_ownership(%as_voidptr($input)));
- }
-}
-
-#endif /* SWIG_DIRECTOR_TYPEMAPS */
-
-
-/* ------------------------------------------------------------
- * --- Constants ---
- * ------------------------------------------------------------ */
-
-%typemap(constcode,noblock=1) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] {
- %set_constant("$symname", SWIG_NewPointerObj(%as_voidptr($value),$descriptor,%newpointer_flags));
-}
-
-%typemap(constcode,noblock=1) SWIGTYPE {
- %set_constant("$symname", SWIG_NewPointerObj(%as_voidptr(&$value),$&descriptor,%newpointer_flags));
-}
-
-/* ------------------------------------------------------------
- * --- Exception handling ---
- * ------------------------------------------------------------ */
-
-%typemap(throws,noblock=1) SWIGTYPE {
- %raise(SWIG_NewPointerObj(%new_copy($1, $1_ltype),$&descriptor,SWIG_POINTER_OWN), "$type", $&descriptor);
-}
-
-%typemap(throws,noblock=1) SWIGTYPE * {
- %raise(SWIG_NewPointerObj(%as_voidptr($1),$descriptor,0), "$type", $descriptor);
-}
-
-%typemap(throws,noblock=1) SWIGTYPE [ANY] {
- %raise(SWIG_NewPointerObj(%as_voidptr($1),$descriptor,0), "$type", $descriptor);
-}
-
-%typemap(throws,noblock=1) SWIGTYPE & {
- %raise(SWIG_NewPointerObj(%as_voidptr(&$1),$descriptor,0), "$type", $descriptor);
-}
-
-%typemap(throws,noblock=1) SWIGTYPE && {
- %raise(SWIG_NewPointerObj(%as_voidptr(&$1),$descriptor,0), "$type", $descriptor);
-}
-
-%typemap(throws,noblock=1) (...) {
- SWIG_exception_fail(SWIG_RuntimeError,"unknown exception");
-}
-
-/* ------------------------------------------------------------
- * --- CLASS::* typemaps ---
- * ------------------------------------------------------------ */
-
-%typemap(in) SWIGTYPE (CLASS::*) {
- int res = SWIG_ConvertMember($input, %as_voidptr(&$1), sizeof($1),$descriptor);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res,"$type",$symname, $argnum);
- }
-}
-
-%typemap(out,noblock=1) SWIGTYPE (CLASS::*) {
- %set_output(SWIG_NewMemberObj(%as_voidptr(&$1), sizeof($1), $descriptor));
-}
-
-%typemap(varin) SWIGTYPE (CLASS::*) {
- int res = SWIG_ConvertMember($input,%as_voidptr(&$1), sizeof($1), $descriptor);
- if (!SWIG_IsOK(res)) {
- %variable_fail(res, "$type", "$name");
- }
-}
-
-%typemap(varout,noblock=1) SWIGTYPE (CLASS::*) {
- %set_varoutput(SWIG_NewMemberObj(%as_voidptr(&$1), sizeof($1), $descriptor));
-}
-
-%typemap(constcode,noblock=1) SWIGTYPE (CLASS::*) {
- %set_constant("$symname", SWIG_NewMemberObj(%as_voidptr(&$value), sizeof($value), $descriptor));
-}
-
-#if defined(SWIG_DIRECTOR_TYPEMAPS)
-
-/* directorin */
-
-%typemap(directorin,noblock=1) SWIGTYPE (CLASS::*) {
- $input = SWIG_NewMemberObj(%as_voidptr(&$1), sizeof($1), $descriptor);
-}
-
-/* directorout */
-
-%typemap(directorout) SWIGTYPE (CLASS::*) {
- int swig_res = SWIG_ConvertMember($input,%as_voidptr(&$result), sizeof($result), $descriptor);
- if (!SWIG_IsOK(swig_res)) {
- %dirout_fail(swig_res,"$type");
- }
-}
-#endif
-
-%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) }
-%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) }
-
-/* ------------------------------------------------------------
- * --- function ptr typemaps ---
- * ------------------------------------------------------------ */
-
-/*
- ISO C++ doesn't allow direct casting of a function ptr to a object
- ptr. So, maybe the ptr sizes are not the same, and we need to take
- some providences.
- */
-%typemap(in) SWIGTYPE ((*)(ANY)) {
- int res = SWIG_ConvertFunctionPtr($input, (void**)(&$1), $descriptor);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res,"$type",$symname, $argnum);
- }
-}
-
-%typecheck(SWIG_TYPECHECK_POINTER,noblock=1) SWIGTYPE ((*)(ANY)) {
- void *ptr = 0;
- int res = SWIG_ConvertFunctionPtr($input, &ptr, $descriptor);
- $1 = SWIG_CheckState(res);
-}
-
-
-%typemap(out, noblock=1) SWIGTYPE ((*)(ANY)) {
- %set_output(SWIG_NewFunctionPtrObj((void *)($1), $descriptor));
-}
-
-%typemap(varin) SWIGTYPE ((*)(ANY)) {
- int res = SWIG_ConvertFunctionPtr($input, (void**)(&$1), $descriptor);
- if (!SWIG_IsOK(res)) {
- %variable_fail(res, "$type", "$name");
- }
-}
-
-%typemap(varout,noblock=1) SWIGTYPE ((*)(ANY)) {
- %set_varoutput(SWIG_NewFunctionPtrObj((void *)($1), $descriptor));
-}
-
-%typemap(constcode, noblock=1) SWIGTYPE ((*)(ANY)){
- %set_constant("$symname", SWIG_NewFunctionPtrObj((void *)$value, $descriptor));
-}
-%typemap(constcode) SWIGTYPE ((* const)(ANY)) = SWIGTYPE ((*)(ANY));
-
-#if defined(SWIG_DIRECTOR_TYPEMAPS)
-
-/* directorin */
-
-%typemap(directorin,noblock=1) SWIGTYPE ((*)(ANY)) {
- $input = SWIG_NewFunctionPtrObj((void*)($1), $descriptor);
-}
-
-/* directorout */
-
-%typemap(directorout) SWIGTYPE ((*)(ANY)) {
- int swig_res = SWIG_ConvertFunctionPtr($input,(void**)(&$result),$descriptor);
- if (!SWIG_IsOK(swig_res)) {
- %dirout_fail(swig_res,"$type");
- }
-}
-#endif
-
-%apply SWIGTYPE ((*)(ANY)) { SWIGTYPE ((* const)(ANY)) }
-
-%apply SWIGTYPE * { SWIGTYPE *const }
-
-/* ------------------------------------------------------------
- * --- Special typemaps ---
- * ------------------------------------------------------------ */
-
-/* DISOWN typemap */
-
-%typemap(in, noblock=1) SWIGTYPE *DISOWN (int res = 0) {
- res = SWIG_ConvertPtr($input, %as_voidptrptr(&$1), $descriptor, SWIG_POINTER_DISOWN | %convertptr_flags);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res,"$type", $symname, $argnum);
- }
-}
-
-%typemap(varin) SWIGTYPE *DISOWN {
- void *temp = 0;
- int res = SWIG_ConvertPtr($input, &temp, $descriptor, SWIG_POINTER_DISOWN | %convertptr_flags);
- if (!SWIG_IsOK(res)) {
- %variable_fail(res, "$type", "$name");
- }
- $1 = ($ltype) temp;
-}
-
-/* DYNAMIC typemap */
-
-%typemap(out,noblock=1) SWIGTYPE *DYNAMIC, SWIGTYPE &DYNAMIC {
- %set_output(SWIG_NewPointerObj(%as_voidptr($1), SWIG_TypeDynamicCast($descriptor, %as_voidptrptr(&$1)), $owner | %newpointer_flags));
-}
-
-/* INSTANCE typemap */
-
-#ifdef __cplusplus
-%typemap(out,noblock=1) SWIGTYPE INSTANCE {
- %set_output(SWIG_NewInstanceObj((new $1_ltype($1)), $&1_descriptor, SWIG_POINTER_OWN | %newinstance_flags));
-}
-#else
-%typemap(out,noblock=1) SWIGTYPE INSTANCE {
- %set_output(SWIG_NewInstanceObj(%new_copy($1, $1_ltype), $&1_descriptor, SWIG_POINTER_OWN | %newinstance_flags));
-}
-#endif
-
-%typemap(out,noblock=1) SWIGTYPE *INSTANCE, SWIGTYPE &INSTANCE, SWIGTYPE INSTANCE[] {
- %set_output(SWIG_NewInstanceObj(%as_voidptr($1), $1_descriptor, $owner | %newinstance_flags));
-}
-
-%typemap(varout,noblock=1) SWIGTYPE *INSTANCE, SWIGTYPE INSTANCE[] {
- %set_varoutput(SWIG_NewInstanceObj(%as_voidptr($1), $1_descriptor, %newinstance_flags));
-}
-
-%typemap(varout,noblock=1) SWIGTYPE &INSTANCE {
- %set_varoutput(SWIG_NewInstanceObj(%as_voidptr($1), $1_descriptor, %newinstance_flags));
-}
-
-%typemap(varout,noblock=1) SWIGTYPE INSTANCE {
- %set_varoutput(SWIG_NewInstanceObj(%as_voidptr(&$1), $&1_descriptor, %newinstance_flags));
-}
-
diff --git a/contrib/tools/swig/Lib/typemaps/swigtypemaps.swg b/contrib/tools/swig/Lib/typemaps/swigtypemaps.swg
deleted file mode 100644
index 733e5acd0f..0000000000
--- a/contrib/tools/swig/Lib/typemaps/swigtypemaps.swg
+++ /dev/null
@@ -1,168 +0,0 @@
-/* -----------------------------------------------------------------------------
- * swigtypemaps.swg
- *
- * Unified Typemap Library frontend
- * ----------------------------------------------------------------------------- */
-
-/*
- This file provides the frontend to the Unified Typemap Library.
-
- When using this library in a SWIG target language, you need to
- define a minimum set of fragments, specialize a couple of macros,
- and then include this file.
-
- Typically you will create a 'mytypemaps.swg' file in each target
- language, where you will have the following sections:
-
- === mytypemaps.swg ===
-
- // Fragment section
- %include <typemaps/fragments.swg>
- <include target language fragments>
-
- // Unified typemap section
- <specialized the typemap library macros>
- %include <typemaps/swigtypemaps.swg>
-
- // Local typemap section
- <add/replace extra target language typemaps>
-
- === mytypemaps.swg ===
-
- While we add more docs, please take a look at the following cases
- to see how you specialized the unified typemap library for a new
- target language:
-
- Lib/python/pytypemaps.swg
- Lib/tcl/tcltypemaps.swg
- Lib/ruby/rubytypemaps.swg
- Lib/perl5/perltypemaps.swg
-
-*/
-
-#define SWIGUTL SWIGUTL
-
-/* -----------------------------------------------------------------------------
- * Language specialization section.
- *
- * Tune these macros for each language as needed.
- * ----------------------------------------------------------------------------- */
-
-/*
- The SWIG target language object must be provided.
- For example in python you define:
-
- #define SWIG_Object PyObject *
-*/
-
-#if !defined(SWIG_Object)
-#error "SWIG_Object must be defined as the SWIG target language object"
-#endif
-
-/*==== flags for new/convert methods ====*/
-
-
-#ifndef %convertptr_flags
-%define %convertptr_flags 0 %enddef
-#endif
-
-#ifndef %newpointer_flags
-%define %newpointer_flags 0 %enddef
-#endif
-
-#ifndef %newinstance_flags
-%define %newinstance_flags 0 %enddef
-#endif
-
-/*==== set output ====*/
-
-#ifndef %set_output
-/* simple set output operation */
-#define %set_output(obj) $result = obj
-#endif
-
-/*==== set variable output ====*/
-
-#ifndef %set_varoutput
-/* simple set varoutput operation */
-#define %set_varoutput(obj) $result = obj
-#endif
-
-/*==== append output ====*/
-
-#ifndef %append_output
-#if defined(SWIG_AppendOutput)
-/* simple append operation */
-#define %append_output(obj) $result = SWIG_AppendOutput($result,obj)
-#else
-#error "Language must define SWIG_AppendOutput or %append_output"
-#endif
-#endif
-
-/*==== set constant ====*/
-
-#ifndef %set_constant
-#if defined(SWIG_SetConstant)
-/* simple set constant operation */
-#define %set_constant(name,value) SWIG_SetConstant(name,value)
-#else
-#error "Language must define SWIG_SetConstant or %set_constant"
-#endif
-#endif
-
-/*==== raise an exception ====*/
-
-#ifndef %raise
-#if defined(SWIG_Raise)
-/* simple raise operation */
-#define %raise(obj, type, desc) SWIG_Raise(obj, type, desc); SWIG_fail
-#else
-#error "Language must define SWIG_Raise or %raise"
-#endif
-#endif
-
-/*==== director output exception ====*/
-
-#if defined(SWIG_DIRECTOR_TYPEMAPS)
-#ifndef SWIG_DirOutFail
-#define SWIG_DirOutFail(code, msg) Swig::DirectorTypeMismatchException::raise(SWIG_ErrorType(code), msg)
-#endif
-#endif
-
-
-/* -----------------------------------------------------------------------------
- * Language independent definitions
- * ----------------------------------------------------------------------------- */
-
-#define %error_block(Block...) %block(Block)
-#define %default_code(code) SWIG_ArgError(code)
-#define %argument_fail(code, type, name, argn) SWIG_exception_fail(%default_code(code), %argfail_fmt(type, name, argn))
-#define %argument_nullref(type, name, argn) SWIG_exception_fail(SWIG_ValueError, %argnullref_fmt(type, name, argn))
-#define %variable_fail(code, type, name) SWIG_exception_fail(%default_code(code), %varfail_fmt(type, name))
-#define %variable_nullref(type, name) SWIG_exception_fail(SWIG_ValueError, %varnullref_fmt(type, name))
-#define %releasenotowned_fail(code, type, name, argn) SWIG_exception_fail(%default_code(code), %releasenotownedfail_fmt(type, name, argn))
-
-#if defined(SWIG_DIRECTOR_TYPEMAPS)
-#define %dirout_fail(code, type) SWIG_DirOutFail(%default_code(code), %outfail_fmt(type))
-#define %dirout_nullref(type) SWIG_DirOutFail(SWIG_ValueError, %outnullref_fmt(type))
-#endif
-
-/* -----------------------------------------------------------------------------
- * All the typemaps
- * ----------------------------------------------------------------------------- */
-
-
-%include <typemaps/fragments.swg>
-%include <typemaps/exception.swg>
-%include <typemaps/swigtype.swg>
-%include <typemaps/void.swg>
-%include <typemaps/swigobject.swg>
-%include <typemaps/valtypes.swg>
-%include <typemaps/ptrtypes.swg>
-%include <typemaps/inoutlist.swg>
-%include <typemaps/primtypes.swg>
-%include <typemaps/string.swg>
-%include <typemaps/misctypes.swg>
-%include <typemaps/enumint.swg>
-
-
diff --git a/contrib/tools/swig/Lib/typemaps/typemaps.swg b/contrib/tools/swig/Lib/typemaps/typemaps.swg
deleted file mode 100644
index 4629e8dfa0..0000000000
--- a/contrib/tools/swig/Lib/typemaps/typemaps.swg
+++ /dev/null
@@ -1,157 +0,0 @@
-/* -----------------------------------------------------------------------------
- * typemaps.swg
- *
- * Tcl Pointer handling
- *
- * These mappings provide support for input/output arguments and common
- * uses for C/C++ pointers.
- * ----------------------------------------------------------------------------- */
-
-// INPUT typemaps.
-// These remap a C pointer to be an "INPUT" value which is passed by value
-// instead of reference.
-
-/*
-The following methods can be applied to turn a pointer into a simple
-"input" value. That is, instead of passing a pointer to an object,
-you would use a real value instead.
-
- int *INPUT
- short *INPUT
- long *INPUT
- long long *INPUT
- unsigned int *INPUT
- unsigned short *INPUT
- unsigned long *INPUT
- unsigned long long *INPUT
- unsigned char *INPUT
- bool *INPUT
- float *INPUT
- double *INPUT
-
-To use these, suppose you had a C function like this :
-
- double fadd(double *a, double *b) {
- return *a+*b;
- }
-
-You could wrap it with SWIG as follows :
-
- %include <typemaps.i>
- double fadd(double *INPUT, double *INPUT);
-
-or you can use the %apply directive :
-
- %include <typemaps.i>
- %apply double *INPUT { double *a, double *b };
- double fadd(double *a, double *b);
-
-*/
-
-// OUTPUT typemaps. These typemaps are used for parameters that
-// are output only. The output value is appended to the result as
-// a list element.
-
-/*
-The following methods can be applied to turn a pointer into an "output"
-value. When calling a function, no input value would be given for
-a parameter, but an output value would be returned. In the case of
-multiple output values, they are returned in the form of a Tcl tuple.
-
- int *OUTPUT
- short *OUTPUT
- long *OUTPUT
- long long *OUTPUT
- unsigned int *OUTPUT
- unsigned short *OUTPUT
- unsigned long *OUTPUT
- unsigned long long *OUTPUT
- unsigned char *OUTPUT
- bool *OUTPUT
- float *OUTPUT
- double *OUTPUT
-
-For example, suppose you were trying to wrap the modf() function in the
-C math library which splits x into integral and fractional parts (and
-returns the integer part in one of its parameters).K:
-
- double modf(double x, double *ip);
-
-You could wrap it with SWIG as follows :
-
- %include <typemaps.i>
- double modf(double x, double *OUTPUT);
-
-or you can use the %apply directive :
-
- %include <typemaps.i>
- %apply double *OUTPUT { double *ip };
- double modf(double x, double *ip);
-
-The Tcl output of the function would be a tuple containing both
-output values.
-
-*/
-
-// INOUT
-// Mappings for an argument that is both an input and output
-// parameter
-
-/*
-The following methods can be applied to make a function parameter both
-an input and output value. This combines the behavior of both the
-"INPUT" and "OUTPUT" methods described earlier. Output values are
-returned in the form of a Tcl tuple.
-
- int *INOUT
- short *INOUT
- long *INOUT
- long long *INOUT
- unsigned int *INOUT
- unsigned short *INOUT
- unsigned long *INOUT
- unsigned long long *INOUT
- unsigned char *INOUT
- bool *INOUT
- float *INOUT
- double *INOUT
-
-For example, suppose you were trying to wrap the following function :
-
- void neg(double *x) {
- *x = -(*x);
- }
-
-You could wrap it with SWIG as follows :
-
- %include <typemaps.i>
- void neg(double *INOUT);
-
-or you can use the %apply directive :
-
- %include <typemaps.i>
- %apply double *INOUT { double *x };
- void neg(double *x);
-
-Unlike C, this mapping does not directly modify the input value (since
-this makes no sense in Tcl). Rather, the modified input value shows
-up as the return value of the function. Thus, to apply this function
-to a Tcl variable you might do this :
-
- x = neg(x)
-
-Note : previous versions of SWIG used the symbol 'BOTH' to mark
-input/output arguments. This is still supported, but will be slowly
-phased out in future releases.
-
-*/
-
-
-#if defined(SWIG_INOUT_NODEF)
-
-%apply_checkctypes(%typemaps_inoutn)
-
-%apply size_t& { std::size_t& };
-%apply ptrdiff_t& { std::ptrdiff_t& };
-
-#endif
diff --git a/contrib/tools/swig/Lib/typemaps/valtypes.swg b/contrib/tools/swig/Lib/typemaps/valtypes.swg
deleted file mode 100644
index f2f34acfca..0000000000
--- a/contrib/tools/swig/Lib/typemaps/valtypes.swg
+++ /dev/null
@@ -1,215 +0,0 @@
-/*---------------------------------------------------------------------
- * Value typemaps (Type, const Type&) for value types, such as
- * fundamental types (int, double), that define the AsVal/From
- * methods.
- *
- * To apply them, just use one of the following macros:
- *
- * %typemaps_from(FromMeth, FromFrag, Type)
- * %typemaps_asval(CheckCode, AsValMeth, AsValFrag, Type)
- * %typemaps_asvalfrom(CheckCode, AsValMeth, FromMeth, AsValFrag, FromFrag, Type)
- *
- * or the simpler and normalize form:
- *
- * %typemaps_asvalfromn(CheckCode, Type)
- *
- * Also, you can use the individual typemap definitions:
- *
- * %value_in_typemap(asval_meth,frag,Type)
- * %value_varin_typemap(asval_meth,frag,Type)
- * %value_typecheck_typemap(checkcode,asval_meth,frag,Type)
- * %value_directorout_typemap(asval_meth,frag,Type)
- *
- * %value_out_typemap(from_meth,frag,Type)
- * %value_varout_typemap(from_meth,frag,Type)
- * %value_constcode_typemap(from_meth,frag,Type)
- * %value_directorin_typemap(from_meth,frag,Type)
- * %value_throws_typemap(from_meth,frag,Type)
- *
- *---------------------------------------------------------------------*/
-
-/* in */
-
-%define %value_in_typemap(asval_meth,frag,Type...)
- %typemap(in,noblock=1,fragment=frag) Type (Type val, int ecode = 0) {
- ecode = asval_meth($input, &val);
- if (!SWIG_IsOK(ecode)) {
- %argument_fail(ecode, "$ltype", $symname, $argnum);
- }
- $1 = %static_cast(val,$ltype);
- }
- %typemap(freearg) Type ""
- %typemap(in,noblock=1,fragment=frag) const Type & ($*ltype temp, Type val, int ecode = 0) {
- ecode = asval_meth($input, &val);
- if (!SWIG_IsOK(ecode)) {
- %argument_fail(ecode, "$*ltype", $symname, $argnum);
- }
- temp = %static_cast(val, $*ltype);
- $1 = &temp;
- }
- %typemap(freearg) const Type& ""
-%enddef
-
-/* out */
-
-%define %value_out_typemap(from_meth,frag,Type...)
- %typemap(out,noblock=1,fragment=frag) Type, const Type {
- %set_output(from_meth(%static_cast($1,Type)));
- }
- %typemap(out,noblock=1,fragment=frag) const Type& {
- %set_output(from_meth(%static_cast(*$1,Type)));
- }
-%enddef
-
-/* varin */
-
-%define %value_varin_typemap(asval_meth,frag,Type...)
- %typemap(varin,fragment=frag) Type {
- Type val;
- int res = asval_meth($input, &val);
- if (!SWIG_IsOK(res)) {
- %variable_fail(res, "$type", "$name");
- }
- $1 = %static_cast(val,$ltype);
- }
-%enddef
-
-/* varout */
-
-%define %value_varout_typemap(from_meth,frag,Type...)
- %typemap(varout,noblock=1,fragment=frag) Type, const Type& {
- %set_varoutput(from_meth(%static_cast($1,Type)));
- }
-%enddef
-
-/* constant installation code */
-
-%define %value_constcode_typemap(from_meth,frag,Type...)
- %typemap(constcode,noblock=1,fragment=frag) Type {
- %set_constant("$symname", from_meth(%static_cast($value,Type)));
- }
-%enddef
-
-
-#if defined(SWIG_DIRECTOR_TYPEMAPS)
-
-/* directorin */
-
-%define %value_directorin_typemap(from_meth,frag,Type...)
- %typemap(directorin,noblock=1,fragment=frag) Type *DIRECTORIN {
- $input = from_meth(%static_cast(*$1,Type));
- }
- %typemap(directorin,noblock=1,fragment=frag) Type, const Type& {
- $input = from_meth(%static_cast($1,Type));
- }
-%enddef
-
-/* directorout */
-
-%define %value_directorout_typemap(asval_meth,frag,Type...)
- %typemap(directorargout,noblock=1,fragment=frag) Type *DIRECTOROUT(Type swig_val, int swig_res) {
- swig_res = asval_meth($result, &swig_val);
- if (!SWIG_IsOK(swig_res)) {
- %dirout_fail(swig_res, "$type");
- }
- *$1 = swig_val;
- }
- %typemap(directorout,noblock=1,fragment=frag) Type {
- Type swig_val;
- int swig_res = asval_meth($input, &swig_val);
- if (!SWIG_IsOK(swig_res)) {
- %dirout_fail(swig_res, "$type");
- }
- $result = %static_cast(swig_val,$type);
- }
- %typemap(directorout,noblock=1,fragment=frag,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) const Type& {
- Type swig_val;
- int swig_res = asval_meth($input, &swig_val);
- if (!SWIG_IsOK(swig_res)) {
- %dirout_fail(swig_res, "$type");
- }
- $basetype *temp = new $basetype(($basetype)swig_val);
- swig_acquire_ownership(temp);
- $result = temp;
- }
- %typemap(directorfree,noblock=1) const Type & {
- if (director) {
- director->swig_release_ownership(%as_voidptr($input));
- }
- }
- %typemap(directorout,fragment=frag) Type &DIRECTOROUT = Type
-%enddef
-
-#else
-
-#define %value_directorin_typemap(from_meth,frag,Type...)
-#define %value_directorout_typemap(asval_meth,frag,Type...)
-
-#endif /* SWIG_DIRECTOR_TYPEMAPS */
-
-
-/* throws */
-
-%define %value_throws_typemap(from_meth,frag,Type...)
- %typemap(throws,noblock=1,fragment=frag) Type {
- %raise(from_meth(%static_cast($1,Type)), "$type", 0);
- }
-%enddef
-
-/* typecheck */
-
-%define %value_typecheck_typemap(check,asval_meth,frag,Type...)
- %typemap(typecheck,precedence=check,fragment=frag) Type, const Type& {
- int res = asval_meth($input, NULL);
- $1 = SWIG_CheckState(res);
- }
-%enddef
-
-/*---------------------------------------------------------------------
- * typemap definition for types with AsVal methods
- *---------------------------------------------------------------------*/
-%define %typemaps_asval(CheckCode, AsValMeth, AsValFrag, Type...)
- %value_in_typemap(%arg(AsValMeth), %arg(AsValFrag), Type);
- %value_varin_typemap(%arg(AsValMeth), %arg(AsValFrag), Type);
- %value_directorout_typemap(%arg(AsValMeth), %arg(AsValFrag), Type);
- %value_typecheck_typemap(%arg(CheckCode), %arg(AsValMeth), %arg(AsValFrag), Type);
- %value_input_typemap(%arg(CheckCode), %arg(AsValMeth), %arg(AsValFrag), Type);
-%enddef
-
-
-/*---------------------------------------------------------------------
- * typemap definition for types with from method
- *---------------------------------------------------------------------*/
-%define %typemaps_from(FromMeth, FromFrag, Type...)
- %value_out_typemap(%arg(FromMeth), %arg(FromFrag), Type);
- %value_varout_typemap(%arg(FromMeth), %arg(FromFrag), Type);
- %value_constcode_typemap(%arg(FromMeth), %arg(FromFrag), Type);
- %value_directorin_typemap(%arg(FromMeth), %arg(FromFrag), Type);
- %value_throws_typemap(%arg(FromMeth), %arg(FromFrag), Type);
- %value_output_typemap(%arg(FromMeth), %arg(FromFrag), Type);
-%enddef
-
-
-/*---------------------------------------------------------------------
- * typemap definition for types with alval/from method
- *---------------------------------------------------------------------*/
-
-%define %typemaps_asvalfrom(CheckCode, AsValMeth, FromMeth,
- AsValFrag, FromFrag, Type...)
- %typemaps_asval(%arg(CheckCode), %arg(AsValMeth), %arg(AsValFrag), Type);
- %typemaps_from(%arg(FromMeth), %arg(FromFrag), Type);
- %value_inout_typemap(Type);
-%enddef
-
-
-/*---------------------------------------------------------------------
- * typemap definition for types with for 'normalized' asval/from methods
- *---------------------------------------------------------------------*/
-%define %typemaps_asvalfromn(CheckCode, Type...)
- %typemaps_asvalfrom(%arg(CheckCode),
- SWIG_AsVal(Type),
- SWIG_From(Type),
- %arg(SWIG_AsVal_frag(Type)),
- %arg(SWIG_From_frag(Type)),
- Type);
-%enddef
diff --git a/contrib/tools/swig/Lib/typemaps/void.swg b/contrib/tools/swig/Lib/typemaps/void.swg
deleted file mode 100644
index 795992bf48..0000000000
--- a/contrib/tools/swig/Lib/typemaps/void.swg
+++ /dev/null
@@ -1,84 +0,0 @@
-/* ------------------------------------------------------------
- * Void * - Accepts any kind of pointer
- * ------------------------------------------------------------ */
-
-/* in */
-
-%typemap(in,noblock=1) void * (int res) {
- res = SWIG_ConvertPtr($input,%as_voidptrptr(&$1), 0, $disown);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res, "$type", $symname, $argnum);
- }
-}
-%typemap(freearg) void * ""
-
-%typemap(in,noblock=1) void * const& ($*ltype temp = 0, int res) {
- res = SWIG_ConvertPtr($input, %as_voidptrptr(&temp), 0, $disown);
- if (!SWIG_IsOK(res)) {
- %argument_fail(res, "Stype", $symname, $argnum);
- }
- $1 = &temp;
-}
-%typemap(freearg) void * const& ""
-
-
-/* out */
-
-#if defined(VOID_Object)
-%typemap(out,noblock=1) void { $result = VOID_Object; }
-#else
-%typemap(out,noblock=1) void {}
-#endif
-
-/* varin */
-
-%typemap(varin) void * {
- void *temp = 0;
- int res = SWIG_ConvertPtr($input, &temp, 0, SWIG_POINTER_DISOWN);
- if (!SWIG_IsOK(res)) {
- %variable_fail(res, "$type", "$name");
- }
- $1 = ($1_ltype) temp;
-}
-
-/* typecheck */
-
-%typecheck(SWIG_TYPECHECK_VOIDPTR, noblock=1) void *
-{
- void *ptr = 0;
- int res = SWIG_ConvertPtr($input, &ptr, 0, 0);
- $1 = SWIG_CheckState(res);
-}
-
-#if defined(SWIG_DIRECTOR_TYPEMAPS)
-
-/* directorin */
-
-%typemap(directorin,noblock=1) void *, void const*, void *const, void const *const,
- void const *&, void *const &, void const *const & {
- $input = SWIG_NewPointerObj(%as_voidptr($1), $descriptor, %newpointer_flags);
-}
-
-/* directorout */
-
-%typemap(directorout,noblock=1) void * (void *argp, int res) {
- res = SWIG_ConvertPtr($input, &argp, 0, 0);
- if (!SWIG_IsOK(res)) {
- %dirout_fail(res,"$type");
- }
- $result = %reinterpret_cast(argp, $ltype);
-}
-
-%typemap(directorout,noblock=1,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) void * const& (void *argp, int res) {
- res = SWIG_ConvertPtr($input, &argp, 0, $disown);
- if (!SWIG_IsOK(res)) {
- %dirout_fail(res,"$type");
- }
- static $*ltype temp = %reinterpret_cast(argp, $*ltype);
- $result = &temp;
-}
-
-
-
-#endif /* SWIG_DIRECTOR_TYPEMAPS */
-
diff --git a/contrib/tools/swig/README b/contrib/tools/swig/README
deleted file mode 100644
index e499e7605e..0000000000
--- a/contrib/tools/swig/README
+++ /dev/null
@@ -1,139 +0,0 @@
-SWIG (Simplified Wrapper and Interface Generator)
-
-Tagline: SWIG is a compiler that integrates C and C++ with languages
- including Perl, Python, Tcl, Ruby, PHP, Java, C#, D, Go, Lua,
- Octave, R, Scheme (Guile, MzScheme/Racket), Scilab, Ocaml.
- SWIG can also export its parse tree into XML.
-
-SWIG reads annotated C/C++ header files and creates wrapper code (glue
-code) in order to make the corresponding C/C++ libraries available to
-the listed languages, or to extend C/C++ programs with a scripting
-language.
-
-Up-to-date SWIG related information can be found at
-
- https://www.swig.org
-
-A SWIG FAQ and other hints can be found on the SWIG Wiki:
-
- https://github.com/swig/swig/wiki
-
-License
-=======
-Please see the LICENSE file for details of the SWIG license. For
-further insight into the license including the license of SWIG's
-output code, please visit
-
- https://www.swig.org/legal.html
-
-Release Notes
-=============
-Please see the CHANGES.current file for a detailed list of bug fixes and
-new features for the current release. The CHANGES file contains bug fixes
-and new features for older versions. A summary of changes in each release
-can be found in the RELEASENOTES file.
-
-Documentation
-=============
-The Doc/Manual directory contains the most recent set of updated
-documentation for this release. The documentation is available in
-three different formats, each of which contains identical content.
-These format are, pdf (Doc/Manual/SWIGDocumentation.pdf), single
-page html (Doc/Manual/SWIGDocumentation.html) or multiple page html
-(other files in Doc/Manual). Please select your chosen format and
-copy/install to wherever takes your fancy.
-
-There is some technical developer documentation available in the
-Doc/Devel subdirectory. This is not necessarily up-to-date, but it
-has some information on SWIG internals.
-
-Documentation is also online at https://www.swig.org/doc.html.
-
-Backwards Compatibility
-=======================
-The developers strive their best to preserve backwards compatibility
-between releases, but this is not always possible as the overriding
-aim is to provide the best wrapping experience. Where backwards
-compatibility is known to be broken, it is clearly marked as an
-incompatibility in the CHANGES and CHANGES.current files.
-
-See the documentation for details of the SWIG_VERSION preprocessor
-symbol if you have backward compatibility issues and need to use more
-than one version of SWIG.
-
-Installation
-============
-Please read the Doc/Manual/Preface.html#Preface_installation for
-full installation instructions for Windows, Unix and Mac OS X
-using the release tarball/zip file. The INSTALL file has generic
-build and installation instructions for Unix users.
-Users wishing to build and install code from Github should
-visit https://swig.org/svn.html to obtain the more detailed
-instructions required for building code obtained from Github - extra
-steps are required compared to building from the release tarball.
-
-Testing
-=======
-The typical 'make -k check' can be performed on Unix operating systems.
-Please read Doc/Manual/Preface.html#Preface_testing for details.
-
-Examples
-========
-The Examples directory contains a variety of examples of using SWIG
-and it has some browsable documentation. Simply point your browser to
-the file "Example/index.html".
-
-The Examples directory also includes Visual C++ project 6 (.dsp) files for
-building some of the examples on Windows. Later versions of Visual Studio
-will convert these old style project files into a current solution file.
-
-Known Issues
-============
-There are minor known bugs, details of which are in the bug tracker, see
-https://www.swig.org/bugs.html.
-
-Troubleshooting
-===============
-In order to operate correctly, SWIG relies upon a set of library
-files. If after building SWIG, you get error messages like this,
-
- $ swig foo.i
- :1. Unable to find 'swig.swg'
- :3. Unable to find 'tcl8.swg'
-
-it means that SWIG has either been incorrectly configured or
-installed. To fix this:
-
- 1. Make sure you remembered to do a 'make install' and that
- the installation actually worked. Make sure you have
- write permission on the install directory.
-
- 2. If that doesn't work, type 'swig -swiglib' to find out
- where SWIG thinks its library is located.
-
- 3. If the location is not where you expect, perhaps
- you supplied a bad option to configure. Use
- ./configure --prefix=pathname to set the SWIG install
- location. Also, make sure you don't include a shell
- escape character such as ~ when you specify the path.
-
- 4. The SWIG library can be changed by setting the SWIG_LIB
- environment variable. However, you really shouldn't
- have to do this.
-
-If you are having other troubles, you might look at the SWIG Wiki at
-https://github.com/swig/swig/wiki.
-
-Participate!
-============
-Please report any errors and submit patches (if possible)! We only
-have access to a limited variety of hardware (Linux, Solaris, OS-X,
-and Windows). All contributions help.
-
-If you would like to join the SWIG development team or contribute a
-language module to the distribution, please contact the swig-devel
-mailing list, details at https://www.swig.org/mail.html.
-
-
- -- The SWIG Maintainers
-
diff --git a/contrib/tools/swig/RELEASENOTES b/contrib/tools/swig/RELEASENOTES
deleted file mode 100644
index 493f199549..0000000000
--- a/contrib/tools/swig/RELEASENOTES
+++ /dev/null
@@ -1,494 +0,0 @@
-This file contains a brief overview of the changes made in each release.
-A detailed description of changes are available in the CHANGES.current
-and CHANGES files.
-
-Release Notes
-=============
-Detailed release notes are available with the release and are also
-published on the SWIG web site at https://swig.org/release.html.
-
-SWIG-4.1.1 summary:
-- Couple of stability fixes.
-- Stability fix in ccache-swig when calculating hashes of inputs.
-- Some template handling improvements.
-- R - minor fixes plus deprecation for rtypecheck typemaps being optional.
-
-SWIG-4.1.0 summary:
-- Add Javascript Node v12-v18 support, remove support prior to v6.
-- Octave 6.0 to 6.4 support added.
-- Add PHP 8 support.
-- PHP wrapping is now done entirely via PHP's C API - no more .php wrapper.
-- Perl 5.8.0 is now the oldest version SWIG supports.
-- Python 3.3 is now the oldest Python 3 version SWIG supports.
-- Python 3.9-3.11 support added.
-- Various memory leak fixes in Python generated code.
-- Scilab 5.5-6.1 support improved.
-- Many improvements for each and every target language.
-- Various preprocessor expression handling improvements.
-- Improved C99, C++11, C++14, C++17 support. Start adding C++20 standard.
-- Make SWIG much more move semantics friendly.
-- Add C++ std::unique_ptr support.
-- Few minor C++ template handling improvements.
-- Various C++ using declaration fixes.
-- Few fixes for handling Doxygen comments.
-- GitHub Actions is now used instead of Travis CI for continuous integration.
-- Add building SWIG using CMake as a secondary build system.
-- Update optional SWIG build dependency for regex support from PCRE to PCRE2.
-
-SWIG-4.0.2 summary:
-- A few fixes around doxygen comment handling.
-- Ruby 2.7 support added.
-- Various minor improvements to C#, D, Java, OCaml, Octave, Python,
- R, Ruby.
-- Considerable performance improvement running SWIG on large
- interface files.
-
-SWIG-4.0.1 summary:
-- SWIG now cleans up on error by removing all generated files.
-- Add Python 3.8 support.
-- Python Sphinx compatibility added for Doxygen comments.
-- Some minor regressions introduced in 4.0.0 were fixed.
-- Fix some C++17 compatibility problems in Python and Ruby generated
- code.
-- Minor improvements/fixes for C#, Java, Javascript, Lua, MzScheme,
- Ocaml, Octave and Python.
-
-SWIG-4.0.0 summary:
-- Support for Doxygen documentation comments which are parsed and
- converted into JavaDoc or PyDoc comments.
-- STL wrappers improved for C#, Java and Ruby.
-- C++11 STL containers added for Java, Python and Ruby.
-- Improved support for parsing C++11 and C++14 code.
-- Various fixes for shared_ptr.
-- Various C preprocessor corner case fixes.
-- Corner case fixes for member function pointers.
-- Python module overhaul by simplifying the generated code and turning
- most optimizations on by default.
-- %template improvements wrt scoping to align with C++ explicit
- template instantiations.
-- Added support for a command-line options file (sometimes called a
- response file).
-- Numerous enhancements and fixes for all supported target languages.
-- SWIG now classifies the status of target languages into either
- 'Experimental' or 'Supported' to indicate the expected maturity
- level.
-- Support for CFFI, Allegrocl, Chicken, CLISP, S-EXP, UFFI, Pike,
- Modula3 has been removed.
-- Octave 4.4-5.1 support added.
-- PHP5 support removed, PHP7 is now the supported PHP version.
-- Minimum Python version required is now 2.7, 3.2-3.7 are the only
- other versions supported.
-- Added support for Javascript NodeJS versions 2-10.
-- OCaml support is much improved and updated, minimum OCaml version
- required is now 3.12.0.
-
-SWIG-3.0.12 summary:
-- Add support for Octave-4.2.
-- Enhance %extend to support template functions.
-- Language specific enhancements and fixes for C#, D, Guile, Java, PHP7.
-
-SWIG-3.0.11 summary:
-- PHP 7 support added.
-- C++11 alias templates and type aliasing support added.
-- Minor fixes and enhancements for C# Go Guile Java Javascript Octave
- PHP Python R Ruby Scilab XML.
-
-SWIG-3.0.10 summary:
-- Regression fixes for smart pointers and importing Python modules.
-
-SWIG-3.0.9 summary:
-- Add support for Python's implicit namespace packages.
-- Fixes to support Go 1.6.
-- C++11 std::array support added for Java.
-- Improved C++ multiple inheritance support for Java/C# wrappers.
-- Various other minor fixes and improvements for C#, D, Go, Java,
- Javascript, Lua, Python, R, Ruby, Scilab.
-
-SWIG-3.0.8 summary:
-- pdf documentation enhancements.
-- Various Python 3.5 issues fixed.
-- std::array support added for Ruby and Python.
-- shared_ptr support added for Ruby.
-- Minor improvements for CFFI, Go, Java, Perl, Python, Ruby.
-
-SWIG-3.0.7 summary:
-- Add support for Octave-4.0.0.
-- Remove potential Android security exploit in generated Java classes.
-- Minor new features and bug fixes.
-
-SWIG-3.0.6 summary:
-- Stability and regression fixes.
-- Fixed parsing of C++ corner cases.
-- Language improvements and bug fixes for C#, Go, Java, Lua, Python, R.
-
-SWIG-3.0.5 summary:
-- Added support for Scilab.
-- Important Python regression fix when wrapping C++ default arguments.
-- Minor improvements for C#, Go, Octave, PHP and Python.
-
-SWIG-3.0.4 summary:
-- Python regression fix when wrapping C++ default arguments.
-- Improved error messages.
-
-SWIG-3.0.3 summary:
-- Add support for C++11 strongly typed enumerations.
-- Numerous bug fixes and minor enhancements for C#, D, Go, Java,
- Javascript, PHP, Perl and Python wrappers.
-
-SWIG-3.0.2 summary:
-- Bug fix during install and a couple of other minor changes.
-
-SWIG-3.0.1 summary:
-- Javascript module added. This supports JavascriptCore (Safari/Webkit),
- v8 (Chromium) and node.js currently.
-- A few notable regressions introduced in 3.0.0 have been fixed - in
- Lua, nested classes and parsing of operator <<.
-- The usual round of bug fixes and minor improvements for:
- C#, GCJ, Go, Java, Lua, PHP and Python.
-
-SWIG-3.0.0 summary:
-- This is a major new release focusing primarily on C++ improvements.
-- C++11 support added. Please see documentation for details of supported
- features: https://www.swig.org/Doc3.0/CPlusPlus11.html
-- Nested class support added. This has been taken full advantage of in
- Java and C#. Other languages can use the nested classes, but require
- further work for a more natural integration into the target language.
- We urge folk knowledgeable in the other target languages to step
- forward and help with this effort.
-- Lua: improved metatables and support for %nspace.
-- Go 1.3 support added.
-- Python import improvements including relative imports.
-- Python 3.3 support completed.
-- Perl director support added.
-- C# .NET 2 support is now the minimum. Generated using statements are
- replaced by fully qualified names.
-- Bug fixes and improvements to the following languages:
- C#, Go, Guile, Java, Lua, Perl, PHP, Python, Octave, R, Ruby, Tcl
-- Various other bug fixes and improvements affecting all languages.
-- Note that this release contains some backwards incompatible changes
- in some languages.
-- Full detailed release notes are in the changes file.
-
-SWIG-2.0.12 summary:
-- This is a maintenance release backporting some fixes from the pending
- 3.0.0 release.
-- Octave 3.8 support added.
-- C++11 support for new versions of erase/insert in the STL containers.
-- Compilation fixes on some systems for the generated Lua, PHP, Python
- and R wrappers.
-
-SWIG-2.0.11 summary:
-- Minor bug fixes and enhancements mostly in Python, but also
- C#, Lua, Ocaml, Octave, Perl, PHP, Python, R, Ruby, Tcl.
-
-SWIG-2.0.10 summary:
-- Ruby 1.9 support is now complete.
-- Add support for Guile 2.0 and Guile 1.6 support (GH interface) has
- been dropped.
-- Various small language neutral improvements and fixes.
-- Various bug fixes and minor improvements specific to C#, CFFI, D,
- Java, Octave, PHP, Python,
-- Minor bug fix in ccache-swig.
-- Development has moved to Github with Travis continuous integration
- testing - patches using https://github.com/swig/swig are welcome.
-
-SWIG-2.0.9 summary:
-- Improved typemap matching.
-- Ruby 1.9 support is much improved.
-- Various bug fixes and minor improvements in C#, CFFI, Go, Java,
- Modula3, Octave, Perl, Python, R, Ruby, Tcl and in ccache-swig.
-
-SWIG-2.0.8 summary:
-- Fix a couple of regressions introduced in 2.0.5 and 2.0.7.
-- Improved using declarations and using directives support.
-- Minor fixes/enhancements for C#, Java, Octave, Perl and Python.
-
-SWIG-2.0.7 summary:
-- Important regression fixes since 2.0.5 for typemaps in general and
- in Python.
-- Fixes and enhancements for Go, Java, Octave and PHP.
-
-SWIG-2.0.6 summary:
-- Regression fix for Python STL wrappers on some systems.
-
-SWIG-2.0.5 summary:
-- Official Android support added including documentation and examples.
-- Improvements involving templates:
- 1) Various fixes with templates and typedef types.
- 2) Some template lookup problems fixed.
- 3) Templated type fixes to use correct typemaps.
-- Autodoc documentation generation improvements.
-- Python STL container wrappers improvements including addition of
- stepped slicing.
-- Approximately 70 fixes and minor enhancements for the following
- target languages: AllegroCL, C#, D, Go, Java, Lua, Ocaml, Octave,
- Perl, PHP, Python, R, Ruby, Tcl, Xml.
-
-SWIG-2.0.4 summary:
-- This is mainly a Python oriented release including support for Python
- built-in types for superior performance with the new -builtin option.
- The -builtin option is especially suitable for performance-critical
- libraries and applications that call wrapped methods repeatedly.
- See the python-specific chapter of the SWIG manual for more info.
-- Python 3.2 support has also been added and various Python bugs have
- been fixed.
-- Octave 3.4 support has also been added.
-- There are also the usual minor generic improvements, as well as bug
- fixes and enhancements for D, Guile, Lua, Octave, Perl and Tcl.
-
-SWIG-2.0.3 summary:
-- A bug fix release including a couple of fixes for regressions in the
- 2.0 series.
-
-SWIG-2.0.2 summary:
-- Support for the D language has been added.
-- Various bug fixes and minor enhancements.
-- Bug fixes particular to the Clisp, C#, Go, MzScheme, Ocaml, PHP, R,
- Ruby target languages.
-
-SWIG-2.0.1 summary:
-- Support for the Go language has been added.
-- New regular expression (regex) encoder for renaming symbols based on
- the Perl Compatible Regular Expressions (PCRE) library.
-- Numerous fixes in reporting file and line numbers in error and warning
- messages.
-- Various bug fixes and improvements in the C#, Lua, Perl, PHP, Ruby
- and Python language modules.
-
-SWIG-2.0.0 summary:
-- License changes, see LICENSE file and https://www.swig.org/legal.html.
-- Much better nested class/struct support.
-- Much improved template partial specialization and explicit
- specialization handling.
-- Namespace support improved with the 'nspace' feature where namespaces
- can be automatically translated into Java packages or C# namespaces.
-- Improved typemap and symbol table debugging.
-- Numerous subtle typemap matching rule changes when using the default
- (SWIGTYPE) type. These now work much like C++ class template partial
- specialization matching.
-- Other small enhancements for typemaps. Typemap fragments are also now
- official and documented.
-- Warning and error display refinements.
-- Wrapping of shared_ptr is improved and documented now.
-- Numerous C++ unary scope operator (::) fixes.
-- Better support for boolean expressions.
-- Various bug fixes and improvements in the Allegrocl, C#, Java, Lua,
- Octave, PHP, Python, R, Ruby and XML modules.
-
-SWIG-1.3.40 summary:
-- SWIG now supports directors for PHP.
-- PHP support improved in general.
-- Octave 3.2 support added.
-- Various bug fixes/enhancements for Allegrocl, C#, Java, Octave, Perl,
- Python, Ruby and Tcl.
-- Other generic fixes and minor new features.
-
-SWIG-1.3.39 summary:
-- Some new small feature enhancements.
-- Improved C# std::vector wrappers.
-- Bug fixes: mainly Python, but also Perl, MzScheme, CFFI, Allegrocl
- and Ruby
-
-SWIG-1.3.38 summary:
-- Output directory regression fix and other minor bug fixes
-
-SWIG-1.3.37 summary:
-- Python 3 support added
-- SWIG now ships with a version of ccache that can be used with SWIG.
- This enables the files generated by SWIG to be cached so that repeated
- use of SWIG on unchanged input files speeds up builds quite considerably.
-- PHP 4 support removed and PHP support improved in general
-- Improved C# array support
-- Numerous Allegro CL improvements
-- Bug fixes/enhancements for Python, PHP, Java, C#, Chicken, Allegro CL,
- CFFI, Ruby, Tcl, Perl, R, Lua.
-- Other minor generic bug fixes and enhancements
-
-SWIG-1.3.36 summary:
-- Enhancement to directors to wrap all protected members
-- Optimisation feature for objects returned by value
-- A few bugs fixes in the PHP, Java, Ruby, R, C#, Python, Lua and
- Perl modules
-- Other minor generic bug fixes
-
-SWIG-1.3.35 summary:
-- Octave language module added
-- Bug fixes in Python, Lua, Java, C#, Perl modules
-- A few other generic bugs and runtime assertions fixed
-
-SWIG-1.3.34 summary:
-- shared_ptr support for Python
-- Support for latest R - version 2.6
-- Various minor improvements/bug fixes for R, Lua, Python, Java, C#
-- A few other generic bug fixes, mainly for templates and using statements
-
-SWIG-1.3.33 summary:
-- Fix regression for Perl where C++ wrappers would not compile
-- Fix regression parsing macros
-
-SWIG-1.3.32 summary:
-- shared_ptr support for Java and C#
-- Enhanced STL support for Ruby
-- Windows support for R
-- Fixed long-standing memory leak in PHP Module
-- Numerous fixes and minor enhancements for Allegrocl, C#, cffi, Chicken, Guile,
- Java, Lua, Ocaml, Perl, PHP, Python, Ruby, Tcl.
-- Improved warning support
-
-SWIG-1.3.31 summary:
-- Python modern classes regression fix
-
-SWIG-1.3.30 summary:
-- Python-2.5 support
-- New language module: R
-- Director support added for C#
-- Numerous director fixes and improvements
-- Improved mingw/msys support
-- Better constants support in Guile and chicken modules
-- Support for generating PHP5 class wrappers
-- Important Java premature garbage collection fix
-- Minor improvements/fixes in cffi, php, allegrocl, perl, chicken, lua, ruby,
- ocaml, python, java, c# and guile language modules
-- Many many other bug fixes
-
-SWIG-1.3.29 summary:
-- Numerous important bug fixes
-- Few minor new features
-- Some performance improvements in generated code for Python
-
-SWIG-1.3.28 summary:
-- More powerful renaming (%rename) capability.
-- More user friendly warning handling.
-- Add finer control for default constructors and destructors. We discourage
- the use of the 'nodefault' option, which disables both constructors and
- destructors, leading to possible memory leaks. Use instead 'nodefaultctor'
- and/or 'nodefaultdtor'.
-- Automatic copy constructor wrapper generation via the 'copyctor' option/feature.
-- Better handling of Windows extensions and types.
-- Better runtime error reporting.
-- Add the %catches directive to catch and dispatch exceptions.
-- Add the %naturalvar directive for more 'natural' variable wrapping.
-- Better default handling of std::string variables using the %naturalvar directive.
-- Add the %allowexcept and %exceptionvar directives to handle exceptions when
- accessing a variable.
-- Add the %delobject directive to mark methods that act like destructors.
-- Add the -fastdispatch option to enable smaller and faster overload dispatch
- mechanism.
-- Template support for %rename, %feature and %typemap improved.
-- Add/doc more debug options, such as -dump_module, -debug_typemaps, etc.
-- Unified typemap library (UTL) potentially providing core typemaps for all
- scripting languages based on the recently evolving Python typemaps.
-- New language module: Common Lisp with CFFI.
-- Python, Ruby, Perl and Tcl use the new UTL, many old reported and hidden
- errors with typemaps are now fixed.
-- Initial Java support for languages using the UTL via GCJ, you can now use
- Java libraries in your favorite script language using gcj + swig.
-- Tcl support for std::wstring.
-- PHP4 module update, many error fixes and actively maintained again.
-- Allegrocl support for C++, also enhanced C support.
-- Ruby support for bang methods.
-- Ruby support for user classes as native exceptions.
-- Perl improved dispatching in overloaded functions via the new cast and rank
- mechanism.
-- Perl improved backward compatibility, 5.004 and later tested and working.
-- Python improved backward compatibility, 1.5.2 and later tested and working.
-- Python can use the same cast/rank mechanism via the -castmode option.
-- Python implicit conversion mechanism similar to C++, via the %implicitconv
- directive (replaces and improves the implicit.i library).
-- Python threading support added.
-- Python STL support improved, iterators are supported and STL containers can
- use now the native PyObject type.
-- Python many performance options and improvements, try the -O option to test
- all of them. Python runtime benchmarks show up to 20 times better performance
- compared to 1.3.27 and older versions.
-- Python support for 'multi-inheritance' on the python side.
-- Python simplified proxy classes, now swig doesn't need to generate the
- additional 'ClassPtr' classes.
-- Python extended support for smart pointers.
-- Python better support for static member variables.
-- Python backward compatibility improved, many projects that used to work
- only with swig-1.3.21 to swig-1.3.24 are working again with swig-1.3.28
-- Python test-suite is now 'valgrinded' before release, and swig also
- reports memory leaks due to missing destructors.
-- Minor bug fixes and improvements to the Lua, Ruby, Java, C#, Python, Guile,
- Chicken, Tcl and Perl modules.
-
-SWIG-1.3.27 summary:
-- Fix bug in anonymous typedef structures which was leading to strange behaviour
-
-SWIG-1.3.26 summary:
-- New language modules: Lua, CLISP and Common Lisp with UFFI.
-- Big overhaul to the PHP module.
-- Change to the way 'extern' is handled.
-- Minor bug fixes specific to C#, Java, Modula3, Ocaml, Allegro CL,
- XML, Lisp s-expressions, Tcl, Ruby and Python modules.
-- Other minor improvements and bug fixes.
-
-SWIG-1.3.25 summary:
-- Improved runtime type system. Speed of module loading improved in
- modules with lots of types. SWIG_RUNTIME_VERSION has been increased
- from 1 to 2, but the API is exactly the same; only internal changes
- were made.
-- The languages that use the runtime type system now support external
- access to the runtime type system.
-- Various improvements with typemaps and template handling.
-- Fewer warnings in generated code.
-- Improved colour documentation.
-- Many C# module improvements (exception handling, prevention of early
- garbage collection, C# attributes support added, more flexible type
- marshalling/asymmetric types.)
-- Minor improvements and bug fixes specific to the C#, Java, TCL, Guile,
- Chicken, MzScheme, Perl, Php, Python, Ruby and Ocaml modules).
-- Various other bug fixes and memory leak fixes.
-
-SWIG-1.3.24 summary:
-- Improved enum handling
-- More runtime library options
-- More bugs fixes for templates and template default arguments, directors
- and other areas.
-- Better smart pointer support, including data members, static members
- and %extend.
-
-SWIG-1.3.23 summary:
-- Improved support for callbacks
-- Python docstring support and better error handling
-- C++ default argument support for Java and C# added.
-- Improved c++ default argument support for the scripting languages plus
- option to use original (compact) default arguments.
-- %feature and %ignore/%rename bug fixes and mods - they might need default
- arguments specified to maintain compatible behaviour when using the new
- default arguments wrapping.
-- Runtime library changes: Runtime code can now exist in more than one module
- and so need not be compiled into just one module
-- Further improved support for templates and namespaces
-- Overloaded templated function support added
-- More powerful default typemaps (mixed default typemaps)
-- Some important %extend and director code bug fixes
-- Guile now defaults to using SCM API. The old interface can be obtained by
- the -gh option.
-- Various minor improvements and bug fixes for C#, Chicken, Guile, Java,
- MzScheme, Perl, Python and Ruby
-- Improved dependencies generation for constructing Makefiles.
-
-SWIG-1.3.22 summary:
-- Improved exception handling and translation of C errors or C++
- exceptions into target language exceptions.
-- Improved enum support, mapping to built-in Java 1.5 enums and C#
- enums or the typesafe enum pattern for these two languages.
-- Python - much better STL support and support for std::wstring,
- wchar_t and FILE *.
-- Initial support for Modula3 and Allegro CL.
-- 64 bit TCL support.
-- Java and C#'s proxy classes are now nearly 100% generated from
- typemaps and/or features for finer control on the generated code.
-- SWIG runtime library support deprecation.
-- Improved documentation. SWIG now additionally provides documentation
- in the form of a single HTML page as well as a pdf document.
-- Enhanced C++ friend declaration support.
-- Better support for reference counted classes.
-- Various %fragment improvements.
-- RPM fixes.
-- Various minor improvements and bug fixes for C#, Chicken, Guile, Java,
- MzScheme, Perl, Php, Python, Ruby and XML.
-
-
diff --git a/contrib/tools/swig/Source/CParse/cparse.h b/contrib/tools/swig/Source/CParse/cparse.h
deleted file mode 100644
index 2b63f034d0..0000000000
--- a/contrib/tools/swig/Source/CParse/cparse.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * cparse.h
- *
- * SWIG parser module.
- * ----------------------------------------------------------------------------- */
-
-#ifndef SWIG_CPARSE_H
-#define SWIG_CPARSE_H
-
-#include "swig.h"
-#include "swigwarn.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* cscanner.c */
- extern String *cparse_file;
- extern int cparse_line;
- extern int cparse_cplusplus;
- extern int cparse_cplusplusout;
- extern int cparse_start_line;
- extern String *cparse_unknown_directive;
- extern int scan_doxygen_comments;
-
- extern void Swig_cparse_cplusplus(int);
- extern void Swig_cparse_cplusplusout(int);
- extern void scanner_file(File *);
- extern void scanner_next_token(int);
- extern void skip_balanced(int startchar, int endchar);
- extern String *get_raw_text_balanced(int startchar, int endchar);
- extern void skip_decl(void);
- extern void scanner_check_typedef(void);
- extern void scanner_ignore_typedef(void);
- extern void scanner_last_id(int);
- extern void scanner_clear_rename(void);
- extern void scanner_set_location(String *file, int line);
- extern void scanner_set_main_input_file(String *file);
- extern String *scanner_get_main_input_file(void);
- extern void Swig_cparse_follow_locators(int);
- extern void start_inline(char *, int);
- extern String *scanner_ccode;
- extern int yylex(void);
-
-/* parser.y */
- extern SwigType *Swig_cparse_type(String *);
- extern Node *Swig_cparse(File *);
- extern Hash *Swig_cparse_features(void);
- extern void SWIG_cparse_set_compact_default_args(int defargs);
- extern int SWIG_cparse_template_reduce(int treduce);
-
-/* util.c */
- extern void Swig_cparse_replace_descriptor(String *s);
- extern SwigType *Swig_cparse_smartptr(Node *n);
- extern void cparse_normalize_void(Node *);
- extern Parm *Swig_cparse_parm(String *s);
- extern ParmList *Swig_cparse_parms(String *s, Node *file_line_node);
- extern Node *Swig_cparse_new_node(const_String_or_char_ptr tag);
-
-/* templ.c */
- extern int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *tscope);
- extern Node *Swig_cparse_template_locate(String *name, ParmList *tparms, Symtab *tscope);
- extern void Swig_cparse_debug_templates(int);
-
-#ifdef __cplusplus
-}
-#endif
-#define SWIG_WARN_NODE_BEGIN(Node) \
- { \
- String *wrnfilter = Node ? Getattr(Node,"feature:warnfilter") : 0; \
- if (wrnfilter) Swig_warnfilter(wrnfilter,1)
-#define SWIG_WARN_NODE_END(Node) \
- if (wrnfilter) Swig_warnfilter(wrnfilter,0); \
- }
-
-#define COMPOUND_EXPR_VAL(dtype) \
- ((dtype).type == T_CHAR || (dtype).type == T_WCHAR ? (dtype).rawval : (dtype).val)
-#endif
diff --git a/contrib/tools/swig/Source/CParse/cscanner.c b/contrib/tools/swig/Source/CParse/cscanner.c
deleted file mode 100644
index 2eb3f97749..0000000000
--- a/contrib/tools/swig/Source/CParse/cscanner.c
+++ /dev/null
@@ -1,1088 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * scanner.c
- *
- * SWIG tokenizer. This file is a wrapper around the generic C scanner
- * found in Swig/scanner.c. Extra logic is added both to accommodate the
- * bison-based grammar and certain peculiarities of C++ parsing (e.g.,
- * operator overloading, typedef resolution, etc.). This code also splits
- * C identifiers up into keywords and SWIG directives.
- * ----------------------------------------------------------------------------- */
-
-#include "cparse.h"
-#include "parser.h"
-#include <string.h>
-#include <ctype.h>
-
-/* Scanner object */
-static Scanner *scan = 0;
-
-/* Global string containing C code. Used by the parser to grab code blocks */
-String *scanner_ccode = 0;
-
-/* The main file being parsed */
-static String *main_input_file = 0;
-
-/* Error reporting/location information */
-int cparse_line = 1;
-String *cparse_file = 0;
-int cparse_start_line = 0;
-
-/* C++ mode */
-int cparse_cplusplus = 0;
-
-/* Generate C++ compatible code when wrapping C code */
-int cparse_cplusplusout = 0;
-
-/* To allow better error reporting */
-String *cparse_unknown_directive = 0;
-
-/* Private vars */
-static int scan_init = 0;
-static int num_brace = 0;
-static int last_brace = 0;
-static int last_id = 0;
-static int rename_active = 0;
-
-/* Doxygen comments scanning */
-int scan_doxygen_comments = 0;
-
-int isStructuralDoxygen(String *s) {
- static const char* const structuralTags[] = {
- "addtogroup",
- "callgraph",
- "callergraph",
- "category",
- "def",
- "defgroup",
- "dir",
- "example",
- "file",
- "headerfile",
- "internal",
- "mainpage",
- "name",
- "nosubgrouping",
- "overload",
- "package",
- "page",
- "protocol",
- "relates",
- "relatesalso",
- "showinitializer",
- "weakgroup",
- };
-
- unsigned n;
- char *slashPointer = Strchr(s, '\\');
- char *atPointer = Strchr(s,'@');
- if (slashPointer == NULL && atPointer == NULL)
- return 0;
- else if(slashPointer == NULL)
- slashPointer = atPointer;
-
- slashPointer++; /* skip backslash or at sign */
-
- for (n = 0; n < sizeof(structuralTags)/sizeof(structuralTags[0]); n++) {
- const size_t len = strlen(structuralTags[n]);
- if (strncmp(slashPointer, structuralTags[n], len) == 0) {
- /* Take care to avoid false positives with prefixes of other tags. */
- if (slashPointer[len] == '\0' || isspace((int)slashPointer[len]))
- return 1;
- }
- }
-
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_cparse_cplusplus()
- * ----------------------------------------------------------------------------- */
-
-void Swig_cparse_cplusplus(int v) {
- cparse_cplusplus = v;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_cparse_cplusplusout()
- * ----------------------------------------------------------------------------- */
-
-void Swig_cparse_cplusplusout(int v) {
- cparse_cplusplusout = v;
-}
-
-/* ----------------------------------------------------------------------------
- * scanner_init()
- *
- * Initialize buffers
- * ------------------------------------------------------------------------- */
-
-void scanner_init(void) {
- scan = NewScanner();
- Scanner_idstart(scan,"%");
- scan_init = 1;
- scanner_ccode = NewStringEmpty();
-}
-
-/* ----------------------------------------------------------------------------
- * scanner_file(DOHFile *f)
- *
- * Start reading from new file
- * ------------------------------------------------------------------------- */
-void scanner_file(DOHFile * f) {
- if (!scan_init) scanner_init();
- Scanner_clear(scan);
- Scanner_push(scan,f);
-}
-
-/* ----------------------------------------------------------------------------
- * start_inline(char *text, int line)
- *
- * Take a chunk of text and recursively feed it back into the scanner. Used
- * by the %inline directive.
- * ------------------------------------------------------------------------- */
-
-void start_inline(char *text, int line) {
- String *stext = NewString(text);
-
- Seek(stext,0,SEEK_SET);
- Setfile(stext,cparse_file);
- Setline(stext,line);
- Scanner_push(scan,stext);
- Delete(stext);
-}
-
-/* -----------------------------------------------------------------------------
- * skip_balanced()
- *
- * Skips a piece of code enclosed in begin/end symbols such as '{...}' or
- * (...). Ignores symbols inside comments or strings.
- * ----------------------------------------------------------------------------- */
-
-void skip_balanced(int startchar, int endchar) {
- int start_line = Scanner_line(scan);
- Clear(scanner_ccode);
-
- if (Scanner_skip_balanced(scan,startchar,endchar) < 0) {
- Swig_error(cparse_file, start_line, "Missing '%c'. Reached end of input.\n", endchar);
- return;
- }
-
- cparse_line = Scanner_line(scan);
- cparse_file = Scanner_file(scan);
-
- Append(scanner_ccode, Scanner_text(scan));
- if (endchar == '}')
- num_brace--;
- return;
-}
-
-/* -----------------------------------------------------------------------------
- * get_raw_text_balanced()
- *
- * Returns raw text between 2 braces
- * ----------------------------------------------------------------------------- */
-
-String *get_raw_text_balanced(int startchar, int endchar) {
- return Scanner_get_raw_text_balanced(scan, startchar, endchar);
-}
-
-/* ----------------------------------------------------------------------------
- * void skip_decl(void)
- *
- * This tries to skip over an entire declaration. For example
- *
- * friend ostream& operator<<(ostream&, const char *s);
- *
- * or
- * friend ostream& operator<<(ostream&, const char *s) { }
- *
- * ------------------------------------------------------------------------- */
-
-void skip_decl(void) {
- int tok;
- int done = 0;
- int start_line = Scanner_line(scan);
-
- while (!done) {
- tok = Scanner_token(scan);
- if (tok == 0) {
- if (!Swig_error_count()) {
- Swig_error(cparse_file, start_line, "Missing semicolon (';'). Reached end of input.\n");
- }
- return;
- }
- if (tok == SWIG_TOKEN_LBRACE) {
- if (Scanner_skip_balanced(scan,'{','}') < 0) {
- Swig_error(cparse_file, start_line, "Missing closing brace ('}'). Reached end of input.\n");
- }
- break;
- }
- if (tok == SWIG_TOKEN_SEMI) {
- done = 1;
- }
- }
- cparse_file = Scanner_file(scan);
- cparse_line = Scanner_line(scan);
-}
-
-/* ----------------------------------------------------------------------------
- * int yylook()
- *
- * Lexical scanner.
- * ------------------------------------------------------------------------- */
-
-static int yylook(void) {
-
- int tok = 0;
-
- while (1) {
- if ((tok = Scanner_token(scan)) == 0)
- return 0;
- if (tok == SWIG_TOKEN_ERROR)
- return 0;
- cparse_start_line = Scanner_start_line(scan);
- cparse_line = Scanner_line(scan);
- cparse_file = Scanner_file(scan);
-
- switch(tok) {
- case SWIG_TOKEN_ID:
- return ID;
- case SWIG_TOKEN_LPAREN:
- return LPAREN;
- case SWIG_TOKEN_RPAREN:
- return RPAREN;
- case SWIG_TOKEN_SEMI:
- return SEMI;
- case SWIG_TOKEN_COMMA:
- return COMMA;
- case SWIG_TOKEN_STAR:
- return STAR;
- case SWIG_TOKEN_RBRACE:
- num_brace--;
- if (num_brace < 0) {
- Swig_error(cparse_file, cparse_line, "Syntax error. Extraneous closing brace ('}')\n");
- num_brace = 0;
- } else {
- return RBRACE;
- }
- break;
- case SWIG_TOKEN_LBRACE:
- last_brace = num_brace;
- num_brace++;
- return LBRACE;
- case SWIG_TOKEN_EQUAL:
- return EQUAL;
- case SWIG_TOKEN_EQUALTO:
- return EQUALTO;
- case SWIG_TOKEN_PLUS:
- return PLUS;
- case SWIG_TOKEN_MINUS:
- return MINUS;
- case SWIG_TOKEN_SLASH:
- return SLASH;
- case SWIG_TOKEN_AND:
- return AND;
- case SWIG_TOKEN_LAND:
- return LAND;
- case SWIG_TOKEN_OR:
- return OR;
- case SWIG_TOKEN_LOR:
- return LOR;
- case SWIG_TOKEN_XOR:
- return XOR;
- case SWIG_TOKEN_NOT:
- return NOT;
- case SWIG_TOKEN_LNOT:
- return LNOT;
- case SWIG_TOKEN_NOTEQUAL:
- return NOTEQUALTO;
- case SWIG_TOKEN_LBRACKET:
- return LBRACKET;
- case SWIG_TOKEN_RBRACKET:
- return RBRACKET;
- case SWIG_TOKEN_QUESTION:
- return QUESTIONMARK;
- case SWIG_TOKEN_LESSTHAN:
- return LESSTHAN;
- case SWIG_TOKEN_LTEQUAL:
- return LESSTHANOREQUALTO;
- case SWIG_TOKEN_LSHIFT:
- return LSHIFT;
- case SWIG_TOKEN_GREATERTHAN:
- return GREATERTHAN;
- case SWIG_TOKEN_GTEQUAL:
- return GREATERTHANOREQUALTO;
- case SWIG_TOKEN_RSHIFT:
- return RSHIFT;
- case SWIG_TOKEN_ARROW:
- return ARROW;
- case SWIG_TOKEN_PERIOD:
- return PERIOD;
- case SWIG_TOKEN_MODULO:
- return MODULO;
- case SWIG_TOKEN_COLON:
- return COLON;
- case SWIG_TOKEN_DCOLONSTAR:
- return DSTAR;
- case SWIG_TOKEN_LTEQUALGT:
- return LESSEQUALGREATER;
-
- case SWIG_TOKEN_DCOLON:
- {
- int nexttok = Scanner_token(scan);
- if (nexttok == SWIG_TOKEN_STAR) {
- return DSTAR;
- } else if (nexttok == SWIG_TOKEN_NOT) {
- return DCNOT;
- } else {
- Scanner_pushtoken(scan,nexttok,Scanner_text(scan));
- if (!last_id) {
- scanner_next_token(DCOLON);
- return NONID;
- } else {
- return DCOLON;
- }
- }
- }
- break;
-
- case SWIG_TOKEN_ELLIPSIS:
- return ELLIPSIS;
-
- case SWIG_TOKEN_LLBRACKET:
- do {
- tok = Scanner_token(scan);
- } while ((tok != SWIG_TOKEN_RRBRACKET) && (tok > 0));
- if (tok <= 0) {
- Swig_error(cparse_file, cparse_line, "Unbalanced double brackets, missing closing (']]'). Reached end of input.\n");
- }
- break;
-
- case SWIG_TOKEN_RRBRACKET:
- /* Turn an unmatched ]] back into two ] - e.g. `a[a[0]]` */
- scanner_next_token(RBRACKET);
- return RBRACKET;
-
- /* Look for multi-character sequences */
-
- case SWIG_TOKEN_RSTRING:
- yylval.type = NewString(Scanner_text(scan));
- return TYPE_RAW;
-
- case SWIG_TOKEN_STRING:
- yylval.id = Swig_copy_string(Char(Scanner_text(scan)));
- return STRING;
-
- case SWIG_TOKEN_WSTRING:
- yylval.id = Swig_copy_string(Char(Scanner_text(scan)));
- return WSTRING;
-
- case SWIG_TOKEN_CHAR:
- yylval.str = NewString(Scanner_text(scan));
- if (Len(yylval.str) == 0) {
- Swig_error(cparse_file, cparse_line, "Empty character constant\n");
- }
- return CHARCONST;
-
- case SWIG_TOKEN_WCHAR:
- yylval.str = NewString(Scanner_text(scan));
- if (Len(yylval.str) == 0) {
- Swig_error(cparse_file, cparse_line, "Empty character constant\n");
- }
- return WCHARCONST;
-
- /* Numbers */
-
- case SWIG_TOKEN_INT:
- return NUM_INT;
-
- case SWIG_TOKEN_UINT:
- return NUM_UNSIGNED;
-
- case SWIG_TOKEN_LONG:
- return NUM_LONG;
-
- case SWIG_TOKEN_ULONG:
- return NUM_ULONG;
-
- case SWIG_TOKEN_LONGLONG:
- return NUM_LONGLONG;
-
- case SWIG_TOKEN_ULONGLONG:
- return NUM_ULONGLONG;
-
- case SWIG_TOKEN_DOUBLE:
- case SWIG_TOKEN_FLOAT:
- return NUM_FLOAT;
-
- case SWIG_TOKEN_BOOL:
- return NUM_BOOL;
-
- case SWIG_TOKEN_POUND:
- Scanner_skip_line(scan);
- yylval.id = Swig_copy_string(Char(Scanner_text(scan)));
- return POUND;
- break;
-
- case SWIG_TOKEN_CODEBLOCK:
- yylval.str = NewString(Scanner_text(scan));
- return HBLOCK;
-
- case SWIG_TOKEN_COMMENT:
- {
- typedef enum {
- DOX_COMMENT_PRE = -1,
- DOX_COMMENT_NONE,
- DOX_COMMENT_POST
- } comment_kind_t;
- comment_kind_t existing_comment = DOX_COMMENT_NONE;
-
- /* Concatenate or skip all consecutive comments at once. */
- do {
- String *cmt = Scanner_text(scan);
- String *cmt_modified = 0;
- char *loc = Char(cmt);
- if ((strncmp(loc, "/*@SWIG", 7) == 0) && (loc[Len(cmt)-3] == '@')) {
- Scanner_locator(scan, cmt);
- }
- if (scan_doxygen_comments) { /* else just skip this node, to avoid crashes in parser module*/
-
- int slashStyle = 0; /* Flag for "///" style doxygen comments */
- if (strncmp(loc, "///", 3) == 0) {
- slashStyle = 1;
- if (Len(cmt) == 3) {
- /* Modify to make length=4 to ensure that the empty comment does
- get processed to preserve the newlines in the original comments. */
- cmt_modified = NewStringf("%s ", cmt);
- cmt = cmt_modified;
- loc = Char(cmt);
- }
- }
-
- /* Check for all possible Doxygen comment start markers while ignoring
- comments starting with a row of asterisks or slashes just as
- Doxygen itself does. Also skip empty comment (slash-star-star-slash),
- which causes a crash due to begin > end. */
- if (Len(cmt) > 3 && loc[0] == '/' &&
- ((loc[1] == '/' && ((loc[2] == '/' && loc[3] != '/') || loc[2] == '!')) ||
- (loc[1] == '*' && ((loc[2] == '*' && loc[3] != '*' && loc[3] != '/') || loc[2] == '!')))) {
- comment_kind_t this_comment = loc[3] == '<' ? DOX_COMMENT_POST : DOX_COMMENT_PRE;
- if (existing_comment != DOX_COMMENT_NONE && this_comment != existing_comment) {
- /* We can't concatenate together Doxygen pre- and post-comments. */
- break;
- }
-
- if (this_comment == DOX_COMMENT_POST || !isStructuralDoxygen(loc)) {
- String *str;
-
- int begin = this_comment == DOX_COMMENT_POST ? 4 : 3;
- int end = Len(cmt);
- if (loc[end - 1] == '/' && loc[end - 2] == '*') {
- end -= 2;
- }
-
- str = NewStringWithSize(loc + begin, end - begin);
-
- if (existing_comment == DOX_COMMENT_NONE) {
- yylval.str = str;
- Setline(yylval.str, Scanner_start_line(scan));
- Setfile(yylval.str, Scanner_file(scan));
- } else {
- if (slashStyle) {
- /* Add a newline to the end of each doxygen "///" comment,
- since they are processed individually, unlike the
- slash-star style, which gets processed as a block with
- newlines included. */
- Append(yylval.str, "\n");
- }
- Append(yylval.str, str);
- }
-
- existing_comment = this_comment;
- }
- }
- }
- do {
- tok = Scanner_token(scan);
- } while (tok == SWIG_TOKEN_ENDLINE);
- Delete(cmt_modified);
- } while (tok == SWIG_TOKEN_COMMENT);
-
- Scanner_pushtoken(scan, tok, Scanner_text(scan));
-
- switch (existing_comment) {
- case DOX_COMMENT_PRE:
- return DOXYGENSTRING;
- case DOX_COMMENT_NONE:
- break;
- case DOX_COMMENT_POST:
- return DOXYGENPOSTSTRING;
- }
- }
- break;
- case SWIG_TOKEN_ENDLINE:
- break;
- case SWIG_TOKEN_BACKSLASH:
- break;
- default:
- Swig_error(cparse_file, cparse_line, "Illegal token '%s'.\n", Scanner_text(scan));
- return (ILLEGAL);
- }
- }
-}
-
-static int check_typedef = 0;
-
-void scanner_set_location(String *file, int line) {
- Scanner_set_location(scan,file,line-1);
-}
-
-void scanner_check_typedef(void) {
- check_typedef = 1;
-}
-
-void scanner_ignore_typedef(void) {
- check_typedef = 0;
-}
-
-void scanner_last_id(int x) {
- last_id = x;
-}
-
-void scanner_clear_rename(void) {
- rename_active = 0;
-}
-
-/* Used to push a fictitious token into the scanner */
-static int next_token = 0;
-void scanner_next_token(int tok) {
- next_token = tok;
-}
-
-void scanner_set_main_input_file(String *file) {
- main_input_file = file;
-}
-
-String *scanner_get_main_input_file(void) {
- return main_input_file;
-}
-
-/* ----------------------------------------------------------------------------
- * int yylex()
- *
- * Gets the lexene and returns tokens.
- * ------------------------------------------------------------------------- */
-
-int yylex(void) {
-
- int l;
- char *yytext;
-
- if (!scan_init) {
- scanner_init();
- }
-
- Delete(cparse_unknown_directive);
- cparse_unknown_directive = NULL;
-
- if (next_token) {
- l = next_token;
- next_token = 0;
- return l;
- }
-
- l = yylook();
-
- /* Swig_diagnostic(cparse_file, cparse_line, ":::%d: '%s'\n", l, Scanner_text(scan)); */
-
- if (l == NONID) {
- last_id = 1;
- } else {
- last_id = 0;
- }
-
- /* We got some sort of non-white space object. We set the start_line
- variable unless it has already been set */
-
- if (!cparse_start_line) {
- cparse_start_line = cparse_line;
- }
-
- /* Copy the lexene */
-
- switch (l) {
-
- case NUM_INT:
- case NUM_FLOAT:
- case NUM_ULONG:
- case NUM_LONG:
- case NUM_UNSIGNED:
- case NUM_LONGLONG:
- case NUM_ULONGLONG:
- case NUM_BOOL:
- if (l == NUM_INT)
- yylval.dtype.type = T_INT;
- if (l == NUM_FLOAT)
- yylval.dtype.type = T_DOUBLE;
- if (l == NUM_ULONG)
- yylval.dtype.type = T_ULONG;
- if (l == NUM_LONG)
- yylval.dtype.type = T_LONG;
- if (l == NUM_UNSIGNED)
- yylval.dtype.type = T_UINT;
- if (l == NUM_LONGLONG)
- yylval.dtype.type = T_LONGLONG;
- if (l == NUM_ULONGLONG)
- yylval.dtype.type = T_ULONGLONG;
- if (l == NUM_BOOL)
- yylval.dtype.type = T_BOOL;
- yylval.dtype.val = NewString(Scanner_text(scan));
- yylval.dtype.bitfield = 0;
- yylval.dtype.throws = 0;
- return (l);
-
- case ID:
- yytext = Char(Scanner_text(scan));
- if (yytext[0] != '%') {
- /* Look for keywords now */
-
- if (strcmp(yytext, "int") == 0) {
- yylval.type = NewSwigType(T_INT);
- return (TYPE_INT);
- }
- if (strcmp(yytext, "double") == 0) {
- yylval.type = NewSwigType(T_DOUBLE);
- return (TYPE_DOUBLE);
- }
- if (strcmp(yytext, "void") == 0) {
- yylval.type = NewSwigType(T_VOID);
- return (TYPE_VOID);
- }
- if (strcmp(yytext, "char") == 0) {
- yylval.type = NewSwigType(T_CHAR);
- return (TYPE_CHAR);
- }
- if (strcmp(yytext, "wchar_t") == 0) {
- yylval.type = NewSwigType(T_WCHAR);
- return (TYPE_WCHAR);
- }
- if (strcmp(yytext, "short") == 0) {
- yylval.type = NewSwigType(T_SHORT);
- return (TYPE_SHORT);
- }
- if (strcmp(yytext, "long") == 0) {
- yylval.type = NewSwigType(T_LONG);
- return (TYPE_LONG);
- }
- if (strcmp(yytext, "float") == 0) {
- yylval.type = NewSwigType(T_FLOAT);
- return (TYPE_FLOAT);
- }
- if (strcmp(yytext, "signed") == 0) {
- yylval.type = NewSwigType(T_INT);
- return (TYPE_SIGNED);
- }
- if (strcmp(yytext, "unsigned") == 0) {
- yylval.type = NewSwigType(T_UINT);
- return (TYPE_UNSIGNED);
- }
- if (strcmp(yytext, "bool") == 0) {
- yylval.type = NewSwigType(T_BOOL);
- return (TYPE_BOOL);
- }
-
- /* Non ISO (Windows) C extensions */
- if (strcmp(yytext, "__int8") == 0) {
- yylval.type = NewString(yytext);
- return (TYPE_NON_ISO_INT8);
- }
- if (strcmp(yytext, "__int16") == 0) {
- yylval.type = NewString(yytext);
- return (TYPE_NON_ISO_INT16);
- }
- if (strcmp(yytext, "__int32") == 0) {
- yylval.type = NewString(yytext);
- return (TYPE_NON_ISO_INT32);
- }
- if (strcmp(yytext, "__int64") == 0) {
- yylval.type = NewString(yytext);
- return (TYPE_NON_ISO_INT64);
- }
-
- /* C++ keywords */
- if (cparse_cplusplus) {
- if (strcmp(yytext, "and") == 0)
- return (LAND);
- if (strcmp(yytext, "or") == 0)
- return (LOR);
- if (strcmp(yytext, "not") == 0)
- return (LNOT);
- if (strcmp(yytext, "class") == 0)
- return (CLASS);
- if (strcmp(yytext, "private") == 0)
- return (PRIVATE);
- if (strcmp(yytext, "public") == 0)
- return (PUBLIC);
- if (strcmp(yytext, "protected") == 0)
- return (PROTECTED);
- if (strcmp(yytext, "friend") == 0)
- return (FRIEND);
- if (strcmp(yytext, "constexpr") == 0)
- return (CONSTEXPR);
- if (strcmp(yytext, "thread_local") == 0)
- return (THREAD_LOCAL);
- if (strcmp(yytext, "decltype") == 0)
- return (DECLTYPE);
- if (strcmp(yytext, "virtual") == 0)
- return (VIRTUAL);
- if (strcmp(yytext, "static_assert") == 0)
- return (STATIC_ASSERT);
- if (strcmp(yytext, "operator") == 0) {
- int nexttok;
- String *s = NewString("operator ");
-
- /* If we have an operator, we have to collect the operator symbol and attach it to
- the operator identifier. To do this, we need to scan ahead by several tokens.
- Cases include:
-
- (1) If the next token is an operator as determined by Scanner_isoperator(),
- it means that the operator applies to one of the standard C++ mathematical,
- assignment, or logical operator symbols (e.g., '+','<=','==','&', etc.)
- In this case, we merely append the symbol text to the operator string above.
-
- (2) If the next token is (, we look for ). This is operator ().
- (3) If the next token is [, we look for ]. This is operator [].
- (4) If the next token is an identifier. The operator is possibly a conversion operator.
- (a) Must check for special case new[] and delete[]
-
- Error handling is somewhat tricky here. We'll try to back out gracefully if we can.
-
- */
-
- do {
- nexttok = Scanner_token(scan);
- } while (nexttok == SWIG_TOKEN_ENDLINE || nexttok == SWIG_TOKEN_COMMENT);
-
- if (Scanner_isoperator(nexttok)) {
- /* One of the standard C/C++ symbolic operators */
- Append(s,Scanner_text(scan));
- yylval.str = s;
- return OPERATOR;
- } else if (nexttok == SWIG_TOKEN_LPAREN) {
- /* Function call operator. The next token MUST be a RPAREN */
- nexttok = Scanner_token(scan);
- if (nexttok != SWIG_TOKEN_RPAREN) {
- Swig_error(Scanner_file(scan),Scanner_line(scan),"Syntax error. Bad operator name.\n");
- } else {
- Append(s,"()");
- yylval.str = s;
- return OPERATOR;
- }
- } else if (nexttok == SWIG_TOKEN_LBRACKET) {
- /* Array access operator. The next token MUST be a RBRACKET */
- nexttok = Scanner_token(scan);
- if (nexttok != SWIG_TOKEN_RBRACKET) {
- Swig_error(Scanner_file(scan),Scanner_line(scan),"Syntax error. Bad operator name.\n");
- } else {
- Append(s,"[]");
- yylval.str = s;
- return OPERATOR;
- }
- } else if (nexttok == SWIG_TOKEN_STRING) {
- /* Operator "" or user-defined string literal ""_suffix */
- Append(s,"\"\"");
- yylval.str = s;
- return OPERATOR;
- } else if (nexttok == SWIG_TOKEN_ID) {
- /* We have an identifier. This could be any number of things. It could be a named version of
- an operator (e.g., 'and_eq') or it could be a conversion operator. To deal with this, we're
- going to read tokens until we encounter a ( or ;. Some care is needed for formatting. */
- int needspace = 1;
- int termtoken = 0;
- const char *termvalue = 0;
-
- Append(s,Scanner_text(scan));
- while (1) {
-
- nexttok = Scanner_token(scan);
- if (nexttok <= 0) {
- Swig_error(Scanner_file(scan),Scanner_line(scan),"Syntax error. Bad operator name.\n");
- }
- if (nexttok == SWIG_TOKEN_LPAREN) {
- termtoken = SWIG_TOKEN_LPAREN;
- termvalue = "(";
- break;
- } else if (nexttok == SWIG_TOKEN_CODEBLOCK) {
- termtoken = SWIG_TOKEN_CODEBLOCK;
- termvalue = Char(Scanner_text(scan));
- break;
- } else if (nexttok == SWIG_TOKEN_LBRACE) {
- termtoken = SWIG_TOKEN_LBRACE;
- termvalue = "{";
- break;
- } else if (nexttok == SWIG_TOKEN_SEMI) {
- termtoken = SWIG_TOKEN_SEMI;
- termvalue = ";";
- break;
- } else if (nexttok == SWIG_TOKEN_STRING) {
- termtoken = SWIG_TOKEN_STRING;
- termvalue = Swig_copy_string(Char(Scanner_text(scan)));
- break;
- } else if (nexttok == SWIG_TOKEN_ID) {
- if (needspace) {
- Append(s," ");
- }
- Append(s,Scanner_text(scan));
- } else if (nexttok == SWIG_TOKEN_ENDLINE) {
- } else if (nexttok == SWIG_TOKEN_COMMENT) {
- } else {
- Append(s,Scanner_text(scan));
- needspace = 0;
- }
- }
- yylval.str = s;
- if (!rename_active) {
- String *cs;
- char *t = Char(s) + 9;
- if (!((strcmp(t, "new") == 0)
- || (strcmp(t, "delete") == 0)
- || (strcmp(t, "new[]") == 0)
- || (strcmp(t, "delete[]") == 0)
- || (strcmp(t, "and") == 0)
- || (strcmp(t, "and_eq") == 0)
- || (strcmp(t, "bitand") == 0)
- || (strcmp(t, "bitor") == 0)
- || (strcmp(t, "compl") == 0)
- || (strcmp(t, "not") == 0)
- || (strcmp(t, "not_eq") == 0)
- || (strcmp(t, "or") == 0)
- || (strcmp(t, "or_eq") == 0)
- || (strcmp(t, "xor") == 0)
- || (strcmp(t, "xor_eq") == 0)
- )) {
- /* retract(strlen(t)); */
-
- /* The operator is a conversion operator. In order to deal with this, we need to feed the
- type information back into the parser. For now this is a hack. Needs to be cleaned up later. */
- cs = NewString(t);
- if (termtoken) Append(cs,termvalue);
- Seek(cs,0,SEEK_SET);
- Setline(cs,cparse_line);
- Setfile(cs,cparse_file);
- Scanner_push(scan,cs);
- Delete(cs);
- return CONVERSIONOPERATOR;
- }
- }
- if (termtoken)
- Scanner_pushtoken(scan, termtoken, termvalue);
- return (OPERATOR);
- }
- }
- if (strcmp(yytext, "throw") == 0)
- return (THROW);
- if (strcmp(yytext, "noexcept") == 0)
- return (NOEXCEPT);
- if (strcmp(yytext, "try") == 0)
- return (yylex());
- if (strcmp(yytext, "catch") == 0)
- return (CATCH);
- if (strcmp(yytext, "inline") == 0)
- return (yylex());
- if (strcmp(yytext, "mutable") == 0)
- return (yylex());
- if (strcmp(yytext, "explicit") == 0)
- return (EXPLICIT);
- if (strcmp(yytext, "auto") == 0)
- return (AUTO);
- if (strcmp(yytext, "export") == 0)
- return (yylex());
- if (strcmp(yytext, "typename") == 0)
- return (TYPENAME);
- if (strcmp(yytext, "template") == 0) {
- yylval.intvalue = cparse_line;
- return (TEMPLATE);
- }
- if (strcmp(yytext, "delete") == 0)
- return (DELETE_KW);
- if (strcmp(yytext, "default") == 0)
- return (DEFAULT);
- if (strcmp(yytext, "using") == 0)
- return (USING);
- if (strcmp(yytext, "namespace") == 0)
- return (NAMESPACE);
- if (strcmp(yytext, "override") == 0) {
- last_id = 1;
- return (OVERRIDE);
- }
- if (strcmp(yytext, "final") == 0) {
- last_id = 1;
- return (FINAL);
- }
- } else {
- if (strcmp(yytext, "class") == 0) {
- Swig_warning(WARN_PARSE_CLASS_KEYWORD, cparse_file, cparse_line, "class keyword used, but not in C++ mode.\n");
- }
- if (strcmp(yytext, "_Complex") == 0) {
- yylval.type = NewSwigType(T_COMPLEX);
- return (TYPE_COMPLEX);
- }
- if (strcmp(yytext, "restrict") == 0)
- return (yylex());
- }
-
- /* Misc keywords */
-
- if (strcmp(yytext, "extern") == 0)
- return (EXTERN);
- if (strcmp(yytext, "const") == 0)
- return (CONST_QUAL);
- if (strcmp(yytext, "static") == 0)
- return (STATIC);
- if (strcmp(yytext, "struct") == 0)
- return (STRUCT);
- if (strcmp(yytext, "union") == 0)
- return (UNION);
- if (strcmp(yytext, "enum") == 0)
- return (ENUM);
- if (strcmp(yytext, "sizeof") == 0)
- return (SIZEOF);
-
- if (strcmp(yytext, "typedef") == 0) {
- yylval.intvalue = 0;
- return (TYPEDEF);
- }
-
- /* Ignored keywords */
-
- if (strcmp(yytext, "volatile") == 0)
- return (VOLATILE);
- if (strcmp(yytext, "register") == 0)
- return (REGISTER);
- if (strcmp(yytext, "inline") == 0)
- return (yylex());
-
- } else {
- /* SWIG directives */
- String *stext = 0;
- if (strcmp(yytext, "%module") == 0)
- return (MODULE);
- if (strcmp(yytext, "%insert") == 0)
- return (INSERT);
- if (strcmp(yytext, "%name") == 0)
- return (NAME);
- if (strcmp(yytext, "%rename") == 0) {
- rename_active = 1;
- return (RENAME);
- }
- if (strcmp(yytext, "%namewarn") == 0) {
- rename_active = 1;
- return (NAMEWARN);
- }
- if (strcmp(yytext, "%includefile") == 0)
- return (INCLUDE);
- if (strcmp(yytext, "%beginfile") == 0)
- return (BEGINFILE);
- if (strcmp(yytext, "%endoffile") == 0)
- return (ENDOFFILE);
- if (strcmp(yytext, "%val") == 0) {
- Swig_warning(WARN_DEPRECATED_VAL, cparse_file, cparse_line, "%%val directive deprecated (ignored).\n");
- return (yylex());
- }
- if (strcmp(yytext, "%out") == 0) {
- Swig_warning(WARN_DEPRECATED_OUT, cparse_file, cparse_line, "%%out directive deprecated (ignored).\n");
- return (yylex());
- }
- if (strcmp(yytext, "%constant") == 0)
- return (CONSTANT);
- if (strcmp(yytext, "%typedef") == 0) {
- yylval.intvalue = 1;
- return (TYPEDEF);
- }
- if (strcmp(yytext, "%native") == 0)
- return (NATIVE);
- if (strcmp(yytext, "%pragma") == 0)
- return (PRAGMA);
- if (strcmp(yytext, "%extend") == 0)
- return (EXTEND);
- if (strcmp(yytext, "%fragment") == 0)
- return (FRAGMENT);
- if (strcmp(yytext, "%inline") == 0)
- return (INLINE);
- if (strcmp(yytext, "%typemap") == 0)
- return (TYPEMAP);
- if (strcmp(yytext, "%feature") == 0) {
- /* The rename_active indicates we don't need the information of the
- * following function's return type. This applied for %rename, so do
- * %feature.
- */
- rename_active = 1;
- return (FEATURE);
- }
- if (strcmp(yytext, "%except") == 0)
- return (EXCEPT);
- if (strcmp(yytext, "%importfile") == 0)
- return (IMPORT);
- if (strcmp(yytext, "%echo") == 0)
- return (ECHO);
- if (strcmp(yytext, "%apply") == 0)
- return (APPLY);
- if (strcmp(yytext, "%clear") == 0)
- return (CLEAR);
- if (strcmp(yytext, "%types") == 0)
- return (TYPES);
- if (strcmp(yytext, "%parms") == 0)
- return (PARMS);
- if (strcmp(yytext, "%varargs") == 0)
- return (VARARGS);
- if (strcmp(yytext, "%template") == 0) {
- return (SWIGTEMPLATE);
- }
- if (strcmp(yytext, "%warn") == 0)
- return (WARN);
-
- /* Note down the apparently unknown directive for error reporting - if
- * we end up reporting a generic syntax error we'll instead report an
- * error for his as an unknown directive. Then we treat it as MODULO
- * (`%`) followed by an identifier and if that parses OK then
- * `cparse_unknown_directive` doesn't get used.
- *
- * This allows `a%b` to be handled in expressions without a space after
- * the operator.
- */
- cparse_unknown_directive = NewString(yytext);
- stext = NewString(yytext + 1);
- Seek(stext,0,SEEK_SET);
- Setfile(stext,cparse_file);
- Setline(stext,cparse_line);
- Scanner_push(scan,stext);
- Delete(stext);
- return (MODULO);
- }
- /* Have an unknown identifier, as a last step, we'll do a typedef lookup on it. */
-
- /* Need to fix this */
- if (check_typedef) {
- if (SwigType_istypedef(yytext)) {
- yylval.type = NewString(yytext);
- return (TYPE_TYPEDEF);
- }
- }
- yylval.id = Swig_copy_string(yytext);
- last_id = 1;
- return (ID);
- case POUND:
- return yylex();
- case SWIG_TOKEN_COMMENT:
- return yylex();
- default:
- return (l);
- }
-}
diff --git a/contrib/tools/swig/Source/CParse/parser.y b/contrib/tools/swig/Source/CParse/parser.y
deleted file mode 100644
index 97b467b5c4..0000000000
--- a/contrib/tools/swig/Source/CParse/parser.y
+++ /dev/null
@@ -1,7499 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * parser.y
- *
- * YACC parser for SWIG. The grammar is a somewhat broken subset of C/C++.
- * This file is a bit of a mess and probably needs to be rewritten at
- * some point. Beware.
- * ----------------------------------------------------------------------------- */
-
-/* There are a small number of known shift-reduce conflicts in this file, fail
- compilation if any more are introduced.
-
- Please don't increase the number of the conflicts if at all possible. And if
- you really have no choice but to do it, make sure you clearly document each
- new conflict in this file.
- */
-%expect 7
-
-%{
-#define yylex yylex
-
-/* doh.h uses #pragma GCC poison with GCC to prevent direct calls to certain
- * standard C library functions being introduced, but those cause errors due
- * to checks like `#if defined YYMALLOC || defined malloc` in the bison
- * template code. We can't easily arrange to include headers after that
- * template code, so instead we disable the problematic poisoning for this
- * file.
- */
-#define DOH_NO_POISON_MALLOC_FREE
-
-#include "swig.h"
-#include "cparse.h"
-#include "preprocessor.h"
-#include <ctype.h>
-
-/* We do this for portability */
-#undef alloca
-#define alloca Malloc
-
-#define YYMALLOC Malloc
-#define YYFREE Free
-
-/* -----------------------------------------------------------------------------
- * Externals
- * ----------------------------------------------------------------------------- */
-
-int yyparse(void);
-
-/* NEW Variables */
-
-static Node *top = 0; /* Top of the generated parse tree */
-static int unnamed = 0; /* Unnamed datatype counter */
-static Hash *classes = 0; /* Hash table of classes */
-static Hash *classes_typedefs = 0; /* Hash table of typedef classes: typedef struct X {...} Y; */
-static Symtab *prev_symtab = 0;
-static Node *current_class = 0;
-String *ModuleName = 0;
-static Node *module_node = 0;
-static String *Classprefix = 0;
-static String *Namespaceprefix = 0;
-static int inclass = 0;
-static Node *currentOuterClass = 0; /* for nested classes */
-static const char *last_cpptype = 0;
-static int inherit_list = 0;
-static Parm *template_parameters = 0;
-static int parsing_template_declaration = 0;
-static int extendmode = 0;
-static int compact_default_args = 0;
-static int template_reduce = 0;
-static int cparse_externc = 0;
-int ignore_nested_classes = 0;
-int kwargs_supported = 0;
-/* -----------------------------------------------------------------------------
- * Doxygen Comment Globals
- * ----------------------------------------------------------------------------- */
-static String *currentDeclComment = NULL; /* Comment of C/C++ declaration. */
-static Node *previousNode = NULL; /* Pointer to the previous node (for post comments) */
-static Node *currentNode = NULL; /* Pointer to the current node (for post comments) */
-
-/* -----------------------------------------------------------------------------
- * Assist Functions
- * ----------------------------------------------------------------------------- */
-
-
-
-/* Called by the parser (yyparse) when an error is found.*/
-static void yyerror (const char *e) {
- (void)e;
-}
-
-static Node *new_node(const_String_or_char_ptr tag) {
- Node *n = Swig_cparse_new_node(tag);
- /* Remember the previous node in case it will need a post-comment */
- previousNode = currentNode;
- currentNode = n;
- return n;
-}
-
-/* Copies a node. Does not copy tree links or symbol table data (except for
- sym:name) */
-
-static Node *copy_node(Node *n) {
- Node *nn;
- Iterator k;
- nn = NewHash();
- Setfile(nn,Getfile(n));
- Setline(nn,Getline(n));
- for (k = First(n); k.key; k = Next(k)) {
- String *ci;
- String *key = k.key;
- char *ckey = Char(key);
- if ((strcmp(ckey,"nextSibling") == 0) ||
- (strcmp(ckey,"previousSibling") == 0) ||
- (strcmp(ckey,"parentNode") == 0) ||
- (strcmp(ckey,"lastChild") == 0)) {
- continue;
- }
- if (Strncmp(key,"csym:",5) == 0) continue;
- /* We do copy sym:name. For templates */
- if ((strcmp(ckey,"sym:name") == 0) ||
- (strcmp(ckey,"sym:weak") == 0) ||
- (strcmp(ckey,"sym:typename") == 0)) {
- String *ci = Copy(k.item);
- Setattr(nn,key, ci);
- Delete(ci);
- continue;
- }
- if (strcmp(ckey,"sym:symtab") == 0) {
- Setattr(nn,"sym:needs_symtab", "1");
- }
- /* We don't copy any other symbol table attributes */
- if (strncmp(ckey,"sym:",4) == 0) {
- continue;
- }
- /* If children. We copy them recursively using this function */
- if (strcmp(ckey,"firstChild") == 0) {
- /* Copy children */
- Node *cn = k.item;
- while (cn) {
- Node *copy = copy_node(cn);
- appendChild(nn,copy);
- Delete(copy);
- cn = nextSibling(cn);
- }
- continue;
- }
- /* We don't copy the symbol table. But we drop an attribute
- requires_symtab so that functions know it needs to be built */
-
- if (strcmp(ckey,"symtab") == 0) {
- /* Node defined a symbol table. */
- Setattr(nn,"requires_symtab","1");
- continue;
- }
- /* Can't copy nodes */
- if (strcmp(ckey,"node") == 0) {
- continue;
- }
- if ((strcmp(ckey,"parms") == 0) || (strcmp(ckey,"pattern") == 0) || (strcmp(ckey,"throws") == 0)
- || (strcmp(ckey,"kwargs") == 0)) {
- ParmList *pl = CopyParmList(k.item);
- Setattr(nn,key,pl);
- Delete(pl);
- continue;
- }
- if (strcmp(ckey,"nested:outer") == 0) { /* don't copy outer classes links, they will be updated later */
- Setattr(nn, key, k.item);
- continue;
- }
- /* defaultargs will be patched back in later in update_defaultargs() */
- if (strcmp(ckey,"defaultargs") == 0) {
- Setattr(nn, "needs_defaultargs", "1");
- continue;
- }
- /* same for abstracts, which contains pointers to the source node children, and so will need to be patch too */
- if (strcmp(ckey,"abstracts") == 0) {
- SetFlag(nn, "needs_abstracts");
- continue;
- }
- /* Looks okay. Just copy the data using Copy */
- ci = Copy(k.item);
- Setattr(nn, key, ci);
- Delete(ci);
- }
- return nn;
-}
-
-static void set_comment(Node *n, String *comment) {
- String *name;
- Parm *p;
- if (!n || !comment)
- return;
-
- if (Getattr(n, "doxygen"))
- Append(Getattr(n, "doxygen"), comment);
- else {
- Setattr(n, "doxygen", comment);
- /* This is the first comment, populate it with @params, if any */
- p = Getattr(n, "parms");
- while (p) {
- if (Getattr(p, "doxygen"))
- Printv(comment, "\n@param ", Getattr(p, "name"), Getattr(p, "doxygen"), NIL);
- p=nextSibling(p);
- }
- }
-
- /* Append same comment to every generated overload */
- name = Getattr(n, "name");
- if (!name)
- return;
- n = nextSibling(n);
- while (n && Getattr(n, "name") && Strcmp(Getattr(n, "name"), name) == 0) {
- Setattr(n, "doxygen", comment);
- n = nextSibling(n);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Variables
- * ----------------------------------------------------------------------------- */
-
-static char *typemap_lang = 0; /* Current language setting */
-
-static int cplus_mode = 0;
-
-/* C++ modes */
-
-#define CPLUS_PUBLIC 1
-#define CPLUS_PRIVATE 2
-#define CPLUS_PROTECTED 3
-
-/* include types */
-static int import_mode = 0;
-
-void SWIG_typemap_lang(const char *tm_lang) {
- typemap_lang = Swig_copy_string(tm_lang);
-}
-
-void SWIG_cparse_set_compact_default_args(int defargs) {
- compact_default_args = defargs;
-}
-
-int SWIG_cparse_template_reduce(int treduce) {
- template_reduce = treduce;
- return treduce;
-}
-
-/* -----------------------------------------------------------------------------
- * Assist functions
- * ----------------------------------------------------------------------------- */
-
-static int promote_type(int t) {
- if (t <= T_UCHAR || t == T_CHAR || t == T_WCHAR) return T_INT;
- return t;
-}
-
-/* Perform type-promotion for binary operators */
-static int promote(int t1, int t2) {
- t1 = promote_type(t1);
- t2 = promote_type(t2);
- return t1 > t2 ? t1 : t2;
-}
-
-static String *yyrename = 0;
-
-/* Forward renaming operator */
-
-static String *resolve_create_node_scope(String *cname, int is_class_definition);
-
-
-Hash *Swig_cparse_features(void) {
- static Hash *features_hash = 0;
- if (!features_hash) features_hash = NewHash();
- return features_hash;
-}
-
-/* Fully qualify any template parameters */
-static String *feature_identifier_fix(String *s) {
- String *tp = SwigType_istemplate_templateprefix(s);
- if (tp) {
- String *ts, *ta, *tq;
- ts = SwigType_templatesuffix(s);
- ta = SwigType_templateargs(s);
- tq = Swig_symbol_type_qualify(ta,0);
- Append(tp,tq);
- Append(tp,ts);
- Delete(ts);
- Delete(ta);
- Delete(tq);
- return tp;
- } else {
- return NewString(s);
- }
-}
-
-static void set_access_mode(Node *n) {
- if (cplus_mode == CPLUS_PUBLIC)
- Setattr(n, "access", "public");
- else if (cplus_mode == CPLUS_PROTECTED)
- Setattr(n, "access", "protected");
- else
- Setattr(n, "access", "private");
-}
-
-static void restore_access_mode(Node *n) {
- String *mode = Getattr(n, "access");
- if (Strcmp(mode, "private") == 0)
- cplus_mode = CPLUS_PRIVATE;
- else if (Strcmp(mode, "protected") == 0)
- cplus_mode = CPLUS_PROTECTED;
- else
- cplus_mode = CPLUS_PUBLIC;
-}
-
-/* Generate the symbol table name for an object */
-/* This is a bit of a mess. Need to clean up */
-static String *add_oldname = 0;
-
-
-
-static String *make_name(Node *n, String *name,SwigType *decl) {
- String *made_name = 0;
- int destructor = name && (*(Char(name)) == '~');
-
- if (yyrename) {
- String *s = NewString(yyrename);
- Delete(yyrename);
- yyrename = 0;
- if (destructor && (*(Char(s)) != '~')) {
- Insert(s,0,"~");
- }
- return s;
- }
-
- if (!name) return 0;
-
- if (parsing_template_declaration)
- SetFlag(n, "parsing_template_declaration");
- made_name = Swig_name_make(n, Namespaceprefix, name, decl, add_oldname);
- Delattr(n, "parsing_template_declaration");
-
- return made_name;
-}
-
-/* Generate an unnamed identifier */
-static String *make_unnamed(void) {
- unnamed++;
- return NewStringf("$unnamed%d$",unnamed);
-}
-
-/* Return if the node is a friend declaration */
-static int is_friend(Node *n) {
- return Cmp(Getattr(n,"storage"),"friend") == 0;
-}
-
-static int is_operator(String *name) {
- return Strncmp(name,"operator ", 9) == 0;
-}
-
-
-/* Add declaration list to symbol table */
-static int add_only_one = 0;
-
-static void add_symbols(Node *n) {
- String *decl;
- String *wrn = 0;
-
- if (inclass && n) {
- cparse_normalize_void(n);
- }
- while (n) {
- String *symname = 0;
- /* for friends, we need to pop the scope once */
- String *old_prefix = 0;
- Symtab *old_scope = 0;
- int isfriend = inclass && is_friend(n);
- int iscdecl = Cmp(nodeType(n),"cdecl") == 0;
- int only_csymbol = 0;
-
- if (inclass) {
- String *name = Getattr(n, "name");
- if (isfriend) {
- /* for friends, we need to add the scopename if needed */
- String *prefix = name ? Swig_scopename_prefix(name) : 0;
- old_prefix = Namespaceprefix;
- old_scope = Swig_symbol_popscope();
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- if (!prefix) {
- if (name && !is_operator(name) && Namespaceprefix) {
- String *nname = NewStringf("%s::%s", Namespaceprefix, name);
- Setattr(n,"name",nname);
- Delete(nname);
- }
- } else {
- Symtab *st = Swig_symbol_getscope(prefix);
- String *ns = st ? Getattr(st,"name") : prefix;
- String *base = Swig_scopename_last(name);
- String *nname = NewStringf("%s::%s", ns, base);
- Setattr(n,"name",nname);
- Delete(nname);
- Delete(base);
- Delete(prefix);
- }
- Namespaceprefix = 0;
- } else {
- /* for member functions, we need to remove the redundant
- class scope if provided, as in
-
- struct Foo {
- int Foo::method(int a);
- };
-
- */
- String *prefix = name ? Swig_scopename_prefix(name) : 0;
- if (prefix) {
- if (Classprefix && (Equal(prefix,Classprefix))) {
- String *base = Swig_scopename_last(name);
- Setattr(n,"name",base);
- Delete(base);
- }
- Delete(prefix);
- }
- }
- }
-
- if (!isfriend && (inclass || extendmode)) {
- Setattr(n,"ismember","1");
- }
-
- if (extendmode) {
- if (!Getattr(n, "template"))
- SetFlag(n,"isextendmember");
- }
-
- if (!isfriend && inclass) {
- if ((cplus_mode != CPLUS_PUBLIC)) {
- only_csymbol = 1;
- if (cplus_mode == CPLUS_PROTECTED) {
- Setattr(n,"access", "protected");
- only_csymbol = !Swig_need_protected(n);
- } else {
- Setattr(n,"access", "private");
- /* private are needed only when they are pure virtuals - why? */
- if ((Cmp(Getattr(n,"storage"),"virtual") == 0) && (Cmp(Getattr(n,"value"),"0") == 0)) {
- only_csymbol = 0;
- }
- if (Cmp(nodeType(n),"destructor") == 0) {
- /* Needed for "unref" feature */
- only_csymbol = 0;
- }
- }
- } else {
- Setattr(n,"access", "public");
- }
- }
- if (Getattr(n,"sym:name")) {
- n = nextSibling(n);
- continue;
- }
- decl = Getattr(n,"decl");
- if (!SwigType_isfunction(decl)) {
- String *name = Getattr(n,"name");
- String *makename = Getattr(n,"parser:makename");
- if (iscdecl) {
- String *storage = Getattr(n, "storage");
- if (Cmp(storage,"typedef") == 0) {
- Setattr(n,"kind","typedef");
- } else {
- SwigType *type = Getattr(n,"type");
- String *value = Getattr(n,"value");
- Setattr(n,"kind","variable");
- if (value && Len(value)) {
- Setattr(n,"hasvalue","1");
- }
- if (type) {
- SwigType *ty;
- SwigType *tmp = 0;
- if (decl) {
- ty = tmp = Copy(type);
- SwigType_push(ty,decl);
- } else {
- ty = type;
- }
- if (!SwigType_ismutable(ty) || (storage && Strstr(storage, "constexpr"))) {
- SetFlag(n,"hasconsttype");
- SetFlag(n,"feature:immutable");
- }
- if (tmp) Delete(tmp);
- }
- if (!type) {
- Printf(stderr,"notype name %s\n", name);
- }
- }
- }
- Swig_features_get(Swig_cparse_features(), Namespaceprefix, name, 0, n);
- if (makename) {
- symname = make_name(n, makename,0);
- Delattr(n,"parser:makename"); /* temporary information, don't leave it hanging around */
- } else {
- makename = name;
- symname = make_name(n, makename,0);
- }
-
- if (!symname) {
- symname = Copy(Getattr(n,"unnamed"));
- }
- if (symname) {
- if (parsing_template_declaration)
- SetFlag(n, "parsing_template_declaration");
- wrn = Swig_name_warning(n, Namespaceprefix, symname,0);
- Delattr(n, "parsing_template_declaration");
- }
- } else {
- String *name = Getattr(n,"name");
- SwigType *fdecl = Copy(decl);
- SwigType *fun = SwigType_pop_function(fdecl);
- if (iscdecl) {
- Setattr(n,"kind","function");
- }
-
- Swig_features_get(Swig_cparse_features(),Namespaceprefix,name,fun,n);
-
- symname = make_name(n, name,fun);
- if (parsing_template_declaration)
- SetFlag(n, "parsing_template_declaration");
- wrn = Swig_name_warning(n, Namespaceprefix,symname,fun);
- Delattr(n, "parsing_template_declaration");
-
- Delete(fdecl);
- Delete(fun);
-
- }
- if (!symname) {
- n = nextSibling(n);
- continue;
- }
- if (cparse_cplusplus) {
- String *value = Getattr(n, "value");
- if (value && Strcmp(value, "delete") == 0) {
- /* C++11 deleted definition / deleted function */
- SetFlag(n,"deleted");
- SetFlag(n,"feature:ignore");
- }
- if (SwigType_isrvalue_reference(Getattr(n, "refqualifier"))) {
- /* Ignore rvalue ref-qualifiers by default
- * Use Getattr instead of GetFlag to handle explicit ignore and explicit not ignore */
- if (!(Getattr(n, "feature:ignore") || Strncmp(symname, "$ignore", 7) == 0)) {
- SWIG_WARN_NODE_BEGIN(n);
- Swig_warning(WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED, Getfile(n), Getline(n),
- "Method with rvalue ref-qualifier %s ignored.\n", Swig_name_decl(n));
- SWIG_WARN_NODE_END(n);
- SetFlag(n, "feature:ignore");
- }
- }
- }
- if (only_csymbol || GetFlag(n, "feature:ignore") || Strncmp(symname, "$ignore", 7) == 0) {
- /* Only add to C symbol table and continue */
- Swig_symbol_add(0, n);
- if (!only_csymbol && !GetFlag(n, "feature:ignore")) {
- /* Print the warning attached to $ignore name, if any */
- char *c = Char(symname) + 7;
- if (strlen(c)) {
- SWIG_WARN_NODE_BEGIN(n);
- Swig_warning(0,Getfile(n), Getline(n), "%s\n",c+1);
- SWIG_WARN_NODE_END(n);
- }
- /* If the symbol was ignored via "rename" and is visible, set also feature:ignore*/
- SetFlag(n, "feature:ignore");
- }
- if (!GetFlag(n, "feature:ignore") && Strcmp(symname,"$ignore") == 0) {
- /* Add feature:ignore if the symbol was explicitly ignored, regardless of visibility */
- SetFlag(n, "feature:ignore");
- }
- } else {
- Node *c;
- if ((wrn) && (Len(wrn))) {
- String *metaname = symname;
- if (!Getmeta(metaname,"already_warned")) {
- SWIG_WARN_NODE_BEGIN(n);
- Swig_warning(0,Getfile(n),Getline(n), "%s\n", wrn);
- SWIG_WARN_NODE_END(n);
- Setmeta(metaname,"already_warned","1");
- }
- }
- c = Swig_symbol_add(symname,n);
-
- if (c != n) {
- /* symbol conflict attempting to add in the new symbol */
- if (Getattr(n,"sym:weak")) {
- Setattr(n,"sym:name",symname);
- } else {
- String *e = NewStringEmpty();
- String *en = NewStringEmpty();
- String *ec = NewStringEmpty();
- int redefined = Swig_need_redefined_warn(n,c,inclass);
- if (redefined) {
- Printf(en,"Identifier '%s' redefined (ignored)",symname);
- Printf(ec,"previous definition of '%s'",symname);
- } else {
- Printf(en,"Redundant redeclaration of '%s'",symname);
- Printf(ec,"previous declaration of '%s'",symname);
- }
- if (Cmp(symname,Getattr(n,"name"))) {
- Printf(en," (Renamed from '%s')", SwigType_namestr(Getattr(n,"name")));
- }
- Printf(en,",");
- if (Cmp(symname,Getattr(c,"name"))) {
- Printf(ec," (Renamed from '%s')", SwigType_namestr(Getattr(c,"name")));
- }
- Printf(ec,".");
- SWIG_WARN_NODE_BEGIN(n);
- if (redefined) {
- Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en);
- Swig_warning(WARN_PARSE_REDEFINED,Getfile(c),Getline(c),"%s\n",ec);
- } else if (!is_friend(n) && !is_friend(c)) {
- Swig_warning(WARN_PARSE_REDUNDANT,Getfile(n),Getline(n),"%s\n",en);
- Swig_warning(WARN_PARSE_REDUNDANT,Getfile(c),Getline(c),"%s\n",ec);
- }
- SWIG_WARN_NODE_END(n);
- Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(n),Getline(n),en,
- Getfile(c),Getline(c),ec);
- Setattr(n,"error",e);
- Delete(e);
- Delete(en);
- Delete(ec);
- }
- }
- }
- /* restore the class scope if needed */
- if (isfriend) {
- Swig_symbol_setscope(old_scope);
- if (old_prefix) {
- Delete(Namespaceprefix);
- Namespaceprefix = old_prefix;
- }
- }
- Delete(symname);
-
- if (add_only_one) return;
- n = nextSibling(n);
- }
-}
-
-
-/* add symbols a parse tree node copy */
-
-static void add_symbols_copy(Node *n) {
- String *name;
- int emode = 0;
- while (n) {
- char *cnodeType = Char(nodeType(n));
-
- if (strcmp(cnodeType,"access") == 0) {
- String *kind = Getattr(n,"kind");
- if (Strcmp(kind,"public") == 0) {
- cplus_mode = CPLUS_PUBLIC;
- } else if (Strcmp(kind,"private") == 0) {
- cplus_mode = CPLUS_PRIVATE;
- } else if (Strcmp(kind,"protected") == 0) {
- cplus_mode = CPLUS_PROTECTED;
- }
- n = nextSibling(n);
- continue;
- }
-
- add_oldname = Getattr(n,"sym:name");
- if ((add_oldname) || (Getattr(n,"sym:needs_symtab"))) {
- int old_inclass = -1;
- Node *old_current_class = 0;
- if (add_oldname) {
- DohIncref(add_oldname);
- /* Disable this, it prevents %rename to work with templates */
- /* If already renamed, we used that name */
- /*
- if (Strcmp(add_oldname, Getattr(n,"name")) != 0) {
- Delete(yyrename);
- yyrename = Copy(add_oldname);
- }
- */
- }
- Delattr(n,"sym:needs_symtab");
- Delattr(n,"sym:name");
-
- add_only_one = 1;
- add_symbols(n);
-
- if (Getattr(n,"partialargs")) {
- Swig_symbol_cadd(Getattr(n,"partialargs"),n);
- }
- add_only_one = 0;
- name = Getattr(n,"name");
- if (Getattr(n,"requires_symtab")) {
- Swig_symbol_newscope();
- Swig_symbol_setscopename(name);
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- }
- if (strcmp(cnodeType,"class") == 0) {
- old_inclass = inclass;
- inclass = 1;
- old_current_class = current_class;
- current_class = n;
- if (Strcmp(Getattr(n,"kind"),"class") == 0) {
- cplus_mode = CPLUS_PRIVATE;
- } else {
- cplus_mode = CPLUS_PUBLIC;
- }
- }
- if (strcmp(cnodeType,"extend") == 0) {
- emode = cplus_mode;
- cplus_mode = CPLUS_PUBLIC;
- }
- add_symbols_copy(firstChild(n));
- if (strcmp(cnodeType,"extend") == 0) {
- cplus_mode = emode;
- }
- if (Getattr(n,"requires_symtab")) {
- Setattr(n,"symtab", Swig_symbol_popscope());
- Delattr(n,"requires_symtab");
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- }
- if (add_oldname) {
- Delete(add_oldname);
- add_oldname = 0;
- }
- if (strcmp(cnodeType,"class") == 0) {
- inclass = old_inclass;
- current_class = old_current_class;
- }
- } else {
- if (strcmp(cnodeType,"extend") == 0) {
- emode = cplus_mode;
- cplus_mode = CPLUS_PUBLIC;
- }
- add_symbols_copy(firstChild(n));
- if (strcmp(cnodeType,"extend") == 0) {
- cplus_mode = emode;
- }
- }
- n = nextSibling(n);
- }
-}
-
-/* Add in the "defaultargs" attribute for functions in instantiated templates.
- * n should be any instantiated template (class or start of linked list of functions). */
-static void update_defaultargs(Node *n) {
- if (n) {
- Node *firstdefaultargs = n;
- update_defaultargs(firstChild(n));
- n = nextSibling(n);
- /* recursively loop through nodes of all types, but all we really need are the overloaded functions */
- while (n) {
- update_defaultargs(firstChild(n));
- if (!Getattr(n, "defaultargs")) {
- if (Getattr(n, "needs_defaultargs")) {
- Setattr(n, "defaultargs", firstdefaultargs);
- Delattr(n, "needs_defaultargs");
- } else {
- firstdefaultargs = n;
- }
- } else {
- /* Functions added in with %extend (for specialized template classes) will already have default args patched up */
- assert(Getattr(n, "defaultargs") == firstdefaultargs);
- }
- n = nextSibling(n);
- }
- }
-}
-
-/* Check a set of declarations to see if any are pure-abstract */
-
-static List *pure_abstracts(Node *n) {
- List *abstracts = 0;
- while (n) {
- if (Cmp(nodeType(n),"cdecl") == 0) {
- String *decl = Getattr(n,"decl");
- if (SwigType_isfunction(decl)) {
- String *init = Getattr(n,"value");
- if (Cmp(init,"0") == 0) {
- if (!abstracts) {
- abstracts = NewList();
- }
- Append(abstracts,n);
- SetFlag(n,"abstract");
- }
- }
- } else if (Cmp(nodeType(n),"destructor") == 0) {
- if (Cmp(Getattr(n,"value"),"0") == 0) {
- if (!abstracts) {
- abstracts = NewList();
- }
- Append(abstracts,n);
- SetFlag(n,"abstract");
- }
- }
- n = nextSibling(n);
- }
- return abstracts;
-}
-
-/* Recompute the "abstracts" attribute for the classes in instantiated templates, similarly to update_defaultargs() above. */
-static void update_abstracts(Node *n) {
- for (; n; n = nextSibling(n)) {
- Node* const child = firstChild(n);
- if (!child)
- continue;
-
- update_abstracts(child);
-
- if (Getattr(n, "needs_abstracts")) {
- Setattr(n, "abstracts", pure_abstracts(child));
- Delattr(n, "needs_abstracts");
- }
- }
-}
-
-/* Make a classname */
-
-static String *make_class_name(String *name) {
- String *nname = 0;
- String *prefix;
- if (Namespaceprefix) {
- nname= NewStringf("%s::%s", Namespaceprefix, name);
- } else {
- nname = NewString(name);
- }
- prefix = SwigType_istemplate_templateprefix(nname);
- if (prefix) {
- String *args, *qargs;
- args = SwigType_templateargs(nname);
- qargs = Swig_symbol_type_qualify(args,0);
- Append(prefix,qargs);
- Delete(nname);
- Delete(args);
- Delete(qargs);
- nname = prefix;
- }
- return nname;
-}
-
-/* Use typedef name as class name */
-
-static void add_typedef_name(Node *n, Node *declnode, String *oldName, Symtab *cscope, String *scpname) {
- String *class_rename = 0;
- SwigType *decl = Getattr(declnode, "decl");
- if (!decl || !Len(decl)) {
- String *cname;
- String *tdscopename;
- String *class_scope = Swig_symbol_qualifiedscopename(cscope);
- String *name = Getattr(declnode, "name");
- cname = Copy(name);
- Setattr(n, "tdname", cname);
- tdscopename = class_scope ? NewStringf("%s::%s", class_scope, name) : Copy(name);
- class_rename = Getattr(n, "class_rename");
- if (class_rename && (Strcmp(class_rename, oldName) == 0))
- Setattr(n, "class_rename", NewString(name));
- if (!classes_typedefs) classes_typedefs = NewHash();
- if (!Equal(scpname, tdscopename) && !Getattr(classes_typedefs, tdscopename)) {
- Setattr(classes_typedefs, tdscopename, n);
- }
- Setattr(n, "decl", decl);
- Delete(class_scope);
- Delete(cname);
- Delete(tdscopename);
- }
-}
-
-/* If the class name is qualified. We need to create or lookup namespace entries */
-
-static Symtab *set_scope_to_global(void) {
- Symtab *symtab = Swig_symbol_global_scope();
- Swig_symbol_setscope(symtab);
- return symtab;
-}
-
-/* Remove the block braces, { and }, if the 'noblock' attribute is set.
- * Node *kw can be either a Hash or Parmlist. */
-static String *remove_block(Node *kw, const String *inputcode) {
- String *modified_code = 0;
- while (kw) {
- String *name = Getattr(kw,"name");
- if (name && (Cmp(name,"noblock") == 0)) {
- char *cstr = Char(inputcode);
- int len = Len(inputcode);
- if (len && cstr[0] == '{') {
- --len; ++cstr;
- if (len && cstr[len - 1] == '}') { --len; }
- /* we now remove the extra spaces */
- while (len && isspace((int)cstr[0])) { --len; ++cstr; }
- while (len && isspace((int)cstr[len - 1])) { --len; }
- modified_code = NewStringWithSize(cstr, len);
- break;
- }
- }
- kw = nextSibling(kw);
- }
- return modified_code;
-}
-
-/*
-#define RESOLVE_DEBUG 1
-*/
-static Node *nscope = 0;
-static Node *nscope_inner = 0;
-
-/* Remove the scope prefix from cname and return the base name without the prefix.
- * The scopes required for the symbol name are resolved and/or created, if required.
- * For example AA::BB::CC as input returns CC and creates the namespace AA then inner
- * namespace BB in the current scope. */
-static String *resolve_create_node_scope(String *cname, int is_class_definition) {
- Symtab *gscope = 0;
- Node *cname_node = 0;
- String *last = Swig_scopename_last(cname);
- nscope = 0;
- nscope_inner = 0;
-
- if (Strncmp(cname,"::" ,2) != 0) {
- if (is_class_definition) {
- /* Only lookup symbols which are in scope via a using declaration but not via a using directive.
- For example find y via 'using x::y' but not y via a 'using namespace x'. */
- cname_node = Swig_symbol_clookup_no_inherit(cname, 0);
- if (!cname_node) {
- Node *full_lookup_node = Swig_symbol_clookup(cname, 0);
- if (full_lookup_node) {
- /* This finds a symbol brought into scope via both a using directive and a using declaration. */
- Node *last_node = Swig_symbol_clookup_no_inherit(last, 0);
- if (last_node == full_lookup_node)
- cname_node = last_node;
- }
- }
- } else {
- /* For %template, the template needs to be in scope via any means. */
- cname_node = Swig_symbol_clookup(cname, 0);
- }
- }
-#if RESOLVE_DEBUG
- if (!cname_node)
- Printf(stdout, "symbol does not yet exist (%d): [%s]\n", is_class_definition, cname);
- else
- Printf(stdout, "symbol does exist (%d): [%s]\n", is_class_definition, cname);
-#endif
-
- if (cname_node) {
- /* The symbol has been defined already or is in another scope.
- If it is a weak symbol, it needs replacing and if it was brought into the current scope,
- the scope needs adjusting appropriately for the new symbol.
- Similarly for defined templates. */
- Symtab *symtab = Getattr(cname_node, "sym:symtab");
- Node *sym_weak = Getattr(cname_node, "sym:weak");
- if ((symtab && sym_weak) || Equal(nodeType(cname_node), "template")) {
- /* Check if the scope is the current scope */
- String *current_scopename = Swig_symbol_qualifiedscopename(0);
- String *found_scopename = Swig_symbol_qualifiedscopename(symtab);
- if (!current_scopename)
- current_scopename = NewString("");
- if (!found_scopename)
- found_scopename = NewString("");
-
- {
- int fail = 1;
- List *current_scopes = Swig_scopename_tolist(current_scopename);
- List *found_scopes = Swig_scopename_tolist(found_scopename);
- Iterator cit = First(current_scopes);
- Iterator fit = First(found_scopes);
-#if RESOLVE_DEBUG
-Printf(stdout, "comparing current: [%s] found: [%s]\n", current_scopename, found_scopename);
-#endif
- for (; fit.item && cit.item; fit = Next(fit), cit = Next(cit)) {
- String *current = cit.item;
- String *found = fit.item;
-#if RESOLVE_DEBUG
- Printf(stdout, " looping %s %s\n", current, found);
-#endif
- if (Strcmp(current, found) != 0)
- break;
- }
-
- if (!cit.item) {
- String *subscope = NewString("");
- for (; fit.item; fit = Next(fit)) {
- if (Len(subscope) > 0)
- Append(subscope, "::");
- Append(subscope, fit.item);
- }
- if (Len(subscope) > 0)
- cname = NewStringf("%s::%s", subscope, last);
- else
- cname = Copy(last);
-#if RESOLVE_DEBUG
- Printf(stdout, "subscope to create: [%s] cname: [%s]\n", subscope, cname);
-#endif
- fail = 0;
- Delete(subscope);
- } else {
- if (is_class_definition) {
- if (!fit.item) {
- /* It is valid to define a new class with the same name as one forward declared in a parent scope */
- fail = 0;
- } else if (Swig_scopename_check(cname)) {
- /* Classes defined with scope qualifiers must have a matching forward declaration in matching scope */
- fail = 1;
- } else {
- /* This may let through some invalid cases */
- fail = 0;
- }
-#if RESOLVE_DEBUG
- Printf(stdout, "scope for class definition, fail: %d\n", fail);
-#endif
- } else {
-#if RESOLVE_DEBUG
- Printf(stdout, "no matching base scope for template\n");
-#endif
- fail = 1;
- }
- }
-
- Delete(found_scopes);
- Delete(current_scopes);
-
- if (fail) {
- String *cname_resolved = NewStringf("%s::%s", found_scopename, last);
- Swig_error(cparse_file, cparse_line, "'%s' resolves to '%s' and was incorrectly instantiated in scope '%s' instead of within scope '%s'.\n", cname, cname_resolved, current_scopename, found_scopename);
- cname = Copy(last);
- Delete(cname_resolved);
- }
- }
-
- Delete(current_scopename);
- Delete(found_scopename);
- }
- } else if (!is_class_definition) {
- /* A template instantiation requires a template to be found in scope... fail here too?
- Swig_error(cparse_file, cparse_line, "No template found to instantiate '%s' with %%template.\n", cname);
- */
- }
-
- if (Swig_scopename_check(cname)) {
- Node *ns;
- String *prefix = Swig_scopename_prefix(cname);
- if (prefix && (Strncmp(prefix,"::",2) == 0)) {
-/* I don't think we can use :: global scope to declare classes and hence neither %template. - consider reporting error instead - wsfulton. */
- /* Use the global scope */
- String *nprefix = NewString(Char(prefix)+2);
- Delete(prefix);
- prefix= nprefix;
- gscope = set_scope_to_global();
- }
- if (Len(prefix) == 0) {
- String *base = Copy(last);
- /* Use the global scope, but we need to add a 'global' namespace. */
- if (!gscope) gscope = set_scope_to_global();
- /* note that this namespace is not the "unnamed" one,
- and we don't use Setattr(nscope,"name", ""),
- because the unnamed namespace is private */
- nscope = new_node("namespace");
- Setattr(nscope,"symtab", gscope);;
- nscope_inner = nscope;
- Delete(last);
- return base;
- }
- /* Try to locate the scope */
- ns = Swig_symbol_clookup(prefix,0);
- if (!ns) {
- Swig_error(cparse_file,cparse_line,"Undefined scope '%s'\n", prefix);
- } else {
- Symtab *nstab = Getattr(ns,"symtab");
- if (!nstab) {
- Swig_error(cparse_file,cparse_line, "'%s' is not defined as a valid scope.\n", prefix);
- ns = 0;
- } else {
- /* Check if the node scope is the current scope */
- String *tname = Swig_symbol_qualifiedscopename(0);
- String *nname = Swig_symbol_qualifiedscopename(nstab);
- if (tname && (Strcmp(tname,nname) == 0)) {
- ns = 0;
- cname = Copy(last);
- }
- Delete(tname);
- Delete(nname);
- }
- if (ns) {
- /* we will try to create a new node using the namespaces we
- can find in the scope name */
- List *scopes = Swig_scopename_tolist(prefix);
- String *sname;
- Iterator si;
-
- for (si = First(scopes); si.item; si = Next(si)) {
- Node *ns1,*ns2;
- sname = si.item;
- ns1 = Swig_symbol_clookup(sname,0);
- assert(ns1);
- if (Strcmp(nodeType(ns1),"namespace") == 0) {
- if (Getattr(ns1,"alias")) {
- ns1 = Getattr(ns1,"namespace");
- }
- } else {
- /* now this last part is a class */
- si = Next(si);
- /* or a nested class tree, which is unrolled here */
- for (; si.item; si = Next(si)) {
- if (si.item) {
- Printf(sname,"::%s",si.item);
- }
- }
- /* we get the 'inner' class */
- nscope_inner = Swig_symbol_clookup(sname,0);
- /* set the scope to the inner class */
- Swig_symbol_setscope(Getattr(nscope_inner,"symtab"));
- /* save the last namespace prefix */
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- /* and return the node name, including the inner class prefix */
- break;
- }
- /* here we just populate the namespace tree as usual */
- ns2 = new_node("namespace");
- Setattr(ns2,"name",sname);
- Setattr(ns2,"symtab", Getattr(ns1,"symtab"));
- add_symbols(ns2);
- Swig_symbol_setscope(Getattr(ns1,"symtab"));
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- if (nscope_inner) {
- if (Getattr(nscope_inner,"symtab") != Getattr(ns2,"symtab")) {
- appendChild(nscope_inner,ns2);
- Delete(ns2);
- }
- }
- nscope_inner = ns2;
- if (!nscope) nscope = ns2;
- }
- cname = Copy(last);
- Delete(scopes);
- }
- }
- Delete(prefix);
- }
- Delete(last);
-
- return cname;
-}
-
-/* look for simple typedef name in typedef list */
-static String *try_to_find_a_name_for_unnamed_structure(const char *storage, Node *decls) {
- String *name = 0;
- Node *n = decls;
- if (storage && (strcmp(storage, "typedef") == 0)) {
- for (; n; n = nextSibling(n)) {
- if (!Len(Getattr(n, "decl"))) {
- name = Copy(Getattr(n, "name"));
- break;
- }
- }
- }
- return name;
-}
-
-/* traverse copied tree segment, and update outer class links*/
-static void update_nested_classes(Node *n)
-{
- Node *c = firstChild(n);
- while (c) {
- if (Getattr(c, "nested:outer"))
- Setattr(c, "nested:outer", n);
- update_nested_classes(c);
- c = nextSibling(c);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * nested_forward_declaration()
- *
- * Nested struct handling for C++ code if the nested classes are disabled.
- * Create the nested class/struct/union as a forward declaration.
- * ----------------------------------------------------------------------------- */
-
-static Node *nested_forward_declaration(const char *storage, const char *kind, String *sname, String *name, Node *cpp_opt_declarators) {
- Node *nn = 0;
-
- if (sname) {
- /* Add forward declaration of the nested type */
- Node *n = new_node("classforward");
- Setattr(n, "kind", kind);
- Setattr(n, "name", sname);
- Setattr(n, "storage", storage);
- Setattr(n, "sym:weak", "1");
- add_symbols(n);
- nn = n;
- }
-
- /* Add any variable instances. Also add in any further typedefs of the nested type.
- Note that anonymous typedefs (eg typedef struct {...} a, b;) are treated as class forward declarations */
- if (cpp_opt_declarators) {
- int storage_typedef = (storage && (strcmp(storage, "typedef") == 0));
- int variable_of_anonymous_type = !sname && !storage_typedef;
- if (!variable_of_anonymous_type) {
- int anonymous_typedef = !sname && (storage && (strcmp(storage, "typedef") == 0));
- Node *n = cpp_opt_declarators;
- SwigType *type = name;
- while (n) {
- Setattr(n, "type", type);
- Setattr(n, "storage", storage);
- if (anonymous_typedef) {
- Setattr(n, "nodeType", "classforward");
- Setattr(n, "sym:weak", "1");
- }
- n = nextSibling(n);
- }
- add_symbols(cpp_opt_declarators);
-
- if (nn) {
- set_nextSibling(nn, cpp_opt_declarators);
- } else {
- nn = cpp_opt_declarators;
- }
- }
- }
-
- if (!currentOuterClass || !GetFlag(currentOuterClass, "nested")) {
- if (nn && Equal(nodeType(nn), "classforward")) {
- Node *n = nn;
- if (!GetFlag(n, "feature:ignore")) {
- SWIG_WARN_NODE_BEGIN(n);
- Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", kind, sname ? sname : name);
- SWIG_WARN_NODE_END(n);
- }
- } else {
- Swig_warning(WARN_PARSE_UNNAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", kind);
- }
- }
-
- return nn;
-}
-
-
-Node *Swig_cparse(File *f) {
- scanner_file(f);
- top = 0;
- yyparse();
- return top;
-}
-
-static void single_new_feature(const char *featurename, String *val, Hash *featureattribs, char *declaratorid, SwigType *type, ParmList *declaratorparms, String *qualifier) {
- String *fname;
- String *name;
- String *fixname;
- SwigType *t = Copy(type);
-
- /* Printf(stdout, "single_new_feature: [%s] [%s] [%s] [%s] [%s] [%s]\n", featurename, val, declaratorid, t, ParmList_str_defaultargs(declaratorparms), qualifier); */
-
- /* Warn about deprecated features */
- if (strcmp(featurename, "nestedworkaround") == 0)
- Swig_warning(WARN_DEPRECATED_NESTED_WORKAROUND, cparse_file, cparse_line, "The 'nestedworkaround' feature is deprecated.\n");
-
- fname = NewStringf("feature:%s",featurename);
- if (declaratorid) {
- fixname = feature_identifier_fix(declaratorid);
- } else {
- fixname = NewStringEmpty();
- }
- if (Namespaceprefix) {
- name = NewStringf("%s::%s",Namespaceprefix, fixname);
- } else {
- name = fixname;
- }
-
- if (declaratorparms) Setmeta(val,"parms",declaratorparms);
- if (!Len(t)) t = 0;
- if (t) {
- if (qualifier) SwigType_push(t,qualifier);
- if (SwigType_isfunction(t)) {
- SwigType *decl = SwigType_pop_function(t);
- if (SwigType_ispointer(t)) {
- String *nname = NewStringf("*%s",name);
- Swig_feature_set(Swig_cparse_features(), nname, decl, fname, val, featureattribs);
- Delete(nname);
- } else {
- Swig_feature_set(Swig_cparse_features(), name, decl, fname, val, featureattribs);
- }
- Delete(decl);
- } else if (SwigType_ispointer(t)) {
- String *nname = NewStringf("*%s",name);
- Swig_feature_set(Swig_cparse_features(),nname,0,fname,val, featureattribs);
- Delete(nname);
- }
- } else {
- /* Global feature, that is, feature not associated with any particular symbol */
- Swig_feature_set(Swig_cparse_features(),name,0,fname,val, featureattribs);
- }
- Delete(fname);
- Delete(name);
-}
-
-/* Add a new feature to the Hash. Additional features are added if the feature has a parameter list (declaratorparms)
- * and one or more of the parameters have a default argument. An extra feature is added for each defaulted parameter,
- * simulating the equivalent overloaded method. */
-static void new_feature(const char *featurename, String *val, Hash *featureattribs, char *declaratorid, SwigType *type, ParmList *declaratorparms, String *qualifier) {
-
- ParmList *declparms = declaratorparms;
-
- /* remove the { and } braces if the noblock attribute is set */
- String *newval = remove_block(featureattribs, val);
- val = newval ? newval : val;
-
- /* Add the feature */
- single_new_feature(featurename, val, featureattribs, declaratorid, type, declaratorparms, qualifier);
-
- /* Add extra features if there are default parameters in the parameter list */
- if (type) {
- while (declparms) {
- if (ParmList_has_defaultargs(declparms)) {
-
- /* Create a parameter list for the new feature by copying all
- but the last (defaulted) parameter */
- ParmList* newparms = CopyParmListMax(declparms, ParmList_len(declparms)-1);
-
- /* Create new declaration - with the last parameter removed */
- SwigType *newtype = Copy(type);
- Delete(SwigType_pop_function(newtype)); /* remove the old parameter list from newtype */
- SwigType_add_function(newtype,newparms);
-
- single_new_feature(featurename, Copy(val), featureattribs, declaratorid, newtype, newparms, qualifier);
- declparms = newparms;
- } else {
- declparms = 0;
- }
- }
- }
-}
-
-/* check if a function declaration is a plain C object */
-static int is_cfunction(Node *n) {
- if (!cparse_cplusplus || cparse_externc)
- return 1;
- if (Swig_storage_isexternc(n)) {
- return 1;
- }
- return 0;
-}
-
-/* If the Node is a function with parameters, check to see if any of the parameters
- * have default arguments. If so create a new function for each defaulted argument.
- * The additional functions form a linked list of nodes with the head being the original Node n. */
-static void default_arguments(Node *n) {
- Node *function = n;
-
- if (function) {
- ParmList *varargs = Getattr(function,"feature:varargs");
- if (varargs) {
- /* Handles the %varargs directive by looking for "feature:varargs" and
- * substituting ... with an alternative set of arguments. */
- Parm *p = Getattr(function,"parms");
- Parm *pp = 0;
- while (p) {
- SwigType *t = Getattr(p,"type");
- if (Strcmp(t,"v(...)") == 0) {
- if (pp) {
- ParmList *cv = Copy(varargs);
- set_nextSibling(pp,cv);
- Delete(cv);
- } else {
- ParmList *cv = Copy(varargs);
- Setattr(function,"parms", cv);
- Delete(cv);
- }
- break;
- }
- pp = p;
- p = nextSibling(p);
- }
- }
-
- /* Do not add in functions if kwargs is being used or if user wants old default argument wrapping
- (one wrapped method per function irrespective of number of default arguments) */
- if (compact_default_args
- || is_cfunction(function)
- || GetFlag(function,"feature:compactdefaultargs")
- || (GetFlag(function,"feature:kwargs") && kwargs_supported)) {
- ParmList *p = Getattr(function,"parms");
- if (p)
- Setattr(p,"compactdefargs", "1"); /* mark parameters for special handling */
- function = 0; /* don't add in extra methods */
- }
- }
-
- while (function) {
- ParmList *parms = Getattr(function,"parms");
- if (ParmList_has_defaultargs(parms)) {
-
- /* Create a parameter list for the new function by copying all
- but the last (defaulted) parameter */
- ParmList* newparms = CopyParmListMax(parms,ParmList_len(parms)-1);
-
- /* Create new function and add to symbol table */
- {
- SwigType *ntype = Copy(nodeType(function));
- char *cntype = Char(ntype);
- Node *new_function = new_node(ntype);
- SwigType *decl = Copy(Getattr(function,"decl"));
- int constqualifier = SwigType_isconst(decl);
- String *ccode = Copy(Getattr(function,"code"));
- String *cstorage = Copy(Getattr(function,"storage"));
- String *cvalue = Copy(Getattr(function,"value"));
- SwigType *ctype = Copy(Getattr(function,"type"));
- String *cthrow = Copy(Getattr(function,"throw"));
-
- Delete(SwigType_pop_function(decl)); /* remove the old parameter list from decl */
- SwigType_add_function(decl,newparms);
- if (constqualifier)
- SwigType_add_qualifier(decl,"const");
-
- Setattr(new_function,"name", Getattr(function,"name"));
- Setattr(new_function,"code", ccode);
- Setattr(new_function,"decl", decl);
- Setattr(new_function,"parms", newparms);
- Setattr(new_function,"storage", cstorage);
- Setattr(new_function,"value", cvalue);
- Setattr(new_function,"type", ctype);
- Setattr(new_function,"throw", cthrow);
-
- Delete(ccode);
- Delete(cstorage);
- Delete(cvalue);
- Delete(ctype);
- Delete(cthrow);
- Delete(decl);
-
- {
- Node *throws = Getattr(function,"throws");
- ParmList *pl = CopyParmList(throws);
- if (throws) Setattr(new_function,"throws",pl);
- Delete(pl);
- }
-
- /* copy specific attributes for global (or in a namespace) template functions - these are not templated class methods */
- if (strcmp(cntype,"template") == 0) {
- Node *templatetype = Getattr(function,"templatetype");
- Node *symtypename = Getattr(function,"sym:typename");
- Parm *templateparms = Getattr(function,"templateparms");
- if (templatetype) {
- Node *tmp = Copy(templatetype);
- Setattr(new_function,"templatetype",tmp);
- Delete(tmp);
- }
- if (symtypename) {
- Node *tmp = Copy(symtypename);
- Setattr(new_function,"sym:typename",tmp);
- Delete(tmp);
- }
- if (templateparms) {
- Parm *tmp = CopyParmList(templateparms);
- Setattr(new_function,"templateparms",tmp);
- Delete(tmp);
- }
- } else if (strcmp(cntype,"constructor") == 0) {
- /* only copied for constructors as this is not a user defined feature - it is hard coded in the parser */
- if (GetFlag(function,"feature:new")) SetFlag(new_function,"feature:new");
- }
-
- add_symbols(new_function);
- /* mark added functions as ones with overloaded parameters and point to the parsed method */
- Setattr(new_function,"defaultargs", n);
-
- /* Point to the new function, extending the linked list */
- set_nextSibling(function, new_function);
- Delete(new_function);
- function = new_function;
-
- Delete(ntype);
- }
- } else {
- function = 0;
- }
- }
-}
-
-/* -----------------------------------------------------------------------------
- * mark_nodes_as_extend()
- *
- * Used by the %extend to mark subtypes with "feature:extend".
- * template instances declared within %extend are skipped
- * ----------------------------------------------------------------------------- */
-
-static void mark_nodes_as_extend(Node *n) {
- for (; n; n = nextSibling(n)) {
- if (Getattr(n, "template") && Strcmp(nodeType(n), "class") == 0)
- continue;
- /* Fix me: extend is not a feature. Replace with isextendmember? */
- Setattr(n, "feature:extend", "1");
- mark_nodes_as_extend(firstChild(n));
- }
-}
-
-/* -----------------------------------------------------------------------------
- * add_qualifier_to_declarator()
- *
- * Normally the qualifier is pushed on to the front of the type.
- * Adding a qualifier to a pointer to member function is a special case.
- * For example : typedef double (Cls::*pmf)(void) const;
- * The qualifier is : q(const).
- * The declarator is : m(Cls).f(void).
- * We need : m(Cls).q(const).f(void).
- * ----------------------------------------------------------------------------- */
-
-static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier) {
- int is_pointer_to_member_function = 0;
- String *decl = Copy(type);
- String *poppedtype = NewString("");
- assert(qualifier);
-
- while (decl) {
- if (SwigType_ismemberpointer(decl)) {
- String *memberptr = SwigType_pop(decl);
- if (SwigType_isfunction(decl)) {
- is_pointer_to_member_function = 1;
- SwigType_push(decl, qualifier);
- SwigType_push(decl, memberptr);
- Insert(decl, 0, poppedtype);
- Delete(memberptr);
- break;
- } else {
- Append(poppedtype, memberptr);
- }
- Delete(memberptr);
- } else {
- String *popped = SwigType_pop(decl);
- if (!popped)
- break;
- Append(poppedtype, popped);
- Delete(popped);
- }
- }
-
- if (!is_pointer_to_member_function) {
- Delete(decl);
- decl = Copy(type);
- SwigType_push(decl, qualifier);
- }
-
- Delete(poppedtype);
- return decl;
-}
-
-%}
-
-%union {
- const char *id;
- List *bases;
- struct Define {
- String *val;
- String *rawval;
- int type;
- String *qualifier;
- String *refqualifier;
- String *bitfield;
- Parm *throws;
- String *throwf;
- String *nexcept;
- String *final;
- } dtype;
- struct {
- const char *type;
- String *filename;
- int line;
- } loc;
- struct {
- char *id;
- SwigType *type;
- String *defarg;
- ParmList *parms;
- short have_parms;
- ParmList *throws;
- String *throwf;
- String *nexcept;
- String *final;
- } decl;
- Parm *tparms;
- struct {
- String *method;
- Hash *kwargs;
- } tmap;
- struct {
- String *type;
- String *us;
- } ptype;
- SwigType *type;
- String *str;
- Parm *p;
- ParmList *pl;
- int intvalue;
- Node *node;
-};
-
-// Define special token END for end of input.
-%token END 0
-
-%token <id> ID
-%token <str> HBLOCK
-%token <id> POUND
-%token <id> STRING WSTRING
-%token <loc> INCLUDE IMPORT INSERT
-%token <str> CHARCONST WCHARCONST
-%token <dtype> NUM_INT NUM_FLOAT NUM_UNSIGNED NUM_LONG NUM_ULONG NUM_LONGLONG NUM_ULONGLONG NUM_BOOL
-%token <intvalue> TYPEDEF
-%token <type> TYPE_INT TYPE_UNSIGNED TYPE_SHORT TYPE_LONG TYPE_FLOAT TYPE_DOUBLE TYPE_CHAR TYPE_WCHAR TYPE_VOID TYPE_SIGNED TYPE_BOOL TYPE_COMPLEX TYPE_TYPEDEF TYPE_RAW TYPE_NON_ISO_INT8 TYPE_NON_ISO_INT16 TYPE_NON_ISO_INT32 TYPE_NON_ISO_INT64
-%token LPAREN RPAREN COMMA SEMI EXTERN INIT LBRACE RBRACE PERIOD ELLIPSIS
-%token CONST_QUAL VOLATILE REGISTER STRUCT UNION EQUAL SIZEOF MODULE LBRACKET RBRACKET
-%token BEGINFILE ENDOFFILE
-%token ILLEGAL CONSTANT
-%token NAME RENAME NAMEWARN EXTEND PRAGMA FEATURE VARARGS
-%token ENUM
-%token CLASS TYPENAME PRIVATE PUBLIC PROTECTED COLON STATIC VIRTUAL FRIEND THROW CATCH EXPLICIT
-%token STATIC_ASSERT CONSTEXPR THREAD_LOCAL DECLTYPE AUTO NOEXCEPT /* C++11 keywords */
-%token OVERRIDE FINAL /* C++11 identifiers with special meaning */
-%token USING
-%token <node> NAMESPACE
-%token NATIVE INLINE
-%token TYPEMAP EXCEPT ECHO APPLY CLEAR SWIGTEMPLATE FRAGMENT
-%token WARN
-%token LESSTHAN GREATERTHAN DELETE_KW DEFAULT
-%token LESSTHANOREQUALTO GREATERTHANOREQUALTO EQUALTO NOTEQUALTO LESSEQUALGREATER
-%token ARROW
-%token QUESTIONMARK
-%token TYPES PARMS
-%token NONID DSTAR DCNOT
-%token <intvalue> TEMPLATE
-%token <str> OPERATOR
-%token <str> CONVERSIONOPERATOR
-%token PARSETYPE PARSEPARM PARSEPARMS
-
-%token <str> DOXYGENSTRING
-%token <str> DOXYGENPOSTSTRING
-
-%left CAST
-%left QUESTIONMARK
-%left LOR
-%left LAND
-%left OR
-%left XOR
-%left AND
-%left EQUALTO NOTEQUALTO
-%left GREATERTHAN LESSTHAN GREATERTHANOREQUALTO LESSTHANOREQUALTO
-%left LESSEQUALGREATER
-%left LSHIFT RSHIFT
-%left PLUS MINUS
-%left STAR SLASH MODULO
-%left UMINUS NOT LNOT
-%left DCOLON
-
-%type <node> program interface declaration swig_directive ;
-
-/* SWIG directives */
-%type <node> extend_directive apply_directive clear_directive constant_directive ;
-%type <node> echo_directive except_directive fragment_directive include_directive inline_directive ;
-%type <node> insert_directive module_directive name_directive native_directive ;
-%type <node> pragma_directive rename_directive feature_directive varargs_directive typemap_directive ;
-%type <node> types_directive template_directive warn_directive ;
-
-/* C declarations */
-%type <node> c_declaration c_decl c_decl_tail c_enum_key c_enum_inherit c_enum_decl c_enum_forward_decl c_constructor_decl;
-%type <node> enumlist enumlist_item edecl_with_dox edecl;
-
-/* C++ declarations */
-%type <node> cpp_declaration cpp_class_decl cpp_forward_class_decl cpp_template_decl cpp_alternate_rettype;
-%type <node> cpp_members cpp_member cpp_member_no_dox;
-%type <node> cpp_constructor_decl cpp_destructor_decl cpp_protection_decl cpp_conversion_operator cpp_static_assert;
-%type <node> cpp_swig_directive cpp_template_possible cpp_opt_declarators ;
-%type <node> cpp_using_decl cpp_namespace_decl cpp_catch_decl cpp_lambda_decl;
-%type <node> kwargs options;
-
-/* Misc */
-%type <id> identifier;
-%type <dtype> initializer cpp_const exception_specification cv_ref_qualifier qualifiers_exception_specification;
-%type <id> storage_class extern_string;
-%type <pl> parms ptail rawparms varargs_parms ;
-%type <pl> templateparameters templateparameterstail;
-%type <p> parm_no_dox parm valparm rawvalparms valparms valptail ;
-%type <p> typemap_parm tm_list tm_tail ;
-%type <p> templateparameter ;
-%type <id> templcpptype cpptype classkey classkeyopt access_specifier;
-%type <node> base_specifier;
-%type <str> variadic;
-%type <type> type rawtype type_right anon_bitfield_type decltype ;
-%type <bases> base_list inherit raw_inherit;
-%type <dtype> definetype def_args etype default_delete deleted_definition explicit_default;
-%type <dtype> expr exprnum exprsimple exprcompound valexpr exprmem callparms callptail;
-%type <id> ename ;
-%type <id> less_valparms_greater;
-%type <str> type_qualifier;
-%type <str> ref_qualifier;
-%type <id> type_qualifier_raw;
-%type <id> idstring idstringopt;
-%type <id> pragma_lang;
-%type <str> pragma_arg;
-%type <loc> includetype;
-%type <type> pointer primitive_type;
-%type <decl> declarator direct_declarator notso_direct_declarator parameter_declarator plain_declarator;
-%type <decl> abstract_declarator direct_abstract_declarator ctor_end;
-%type <tmap> typemap_type;
-%type <str> idcolon idcolontail idcolonnt idcolontailnt idtemplate idtemplatetemplate stringbrace stringbracesemi;
-%type <str> string stringnum wstring;
-%type <tparms> template_parms;
-%type <dtype> cpp_end cpp_vend;
-%type <intvalue> rename_namewarn;
-%type <ptype> type_specifier primitive_type_list ;
-%type <node> fname stringtype;
-%type <node> featattr;
-%type <node> lambda_introducer lambda_body lambda_template;
-%type <pl> lambda_tail;
-%type <str> virt_specifier_seq virt_specifier_seq_opt;
-%type <str> class_virt_specifier_opt;
-
-%%
-
-/* ======================================================================
- * High-level Interface file
- *
- * An interface is just a sequence of declarations which may be SWIG directives
- * or normal C declarations.
- * ====================================================================== */
-
-program : interface {
- if (!classes) classes = NewHash();
- Setattr($1,"classes",classes);
- Setattr($1,"name",ModuleName);
-
- if ((!module_node) && ModuleName) {
- module_node = new_node("module");
- Setattr(module_node,"name",ModuleName);
- }
- Setattr($1,"module",module_node);
- top = $1;
- }
- | PARSETYPE parm SEMI {
- top = Copy(Getattr($2,"type"));
- Delete($2);
- }
- | PARSETYPE error {
- top = 0;
- }
- | PARSEPARM parm SEMI {
- top = $2;
- }
- | PARSEPARM error {
- top = 0;
- }
- | PARSEPARMS LPAREN parms RPAREN SEMI {
- top = $3;
- }
- | PARSEPARMS error SEMI {
- top = 0;
- }
- ;
-
-interface : interface declaration {
- /* add declaration to end of linked list (the declaration isn't always a single declaration, sometimes it is a linked list itself) */
- if (currentDeclComment != NULL) {
- set_comment($2, currentDeclComment);
- currentDeclComment = NULL;
- }
- appendChild($1,$2);
- $$ = $1;
- }
- | interface DOXYGENSTRING {
- currentDeclComment = $2;
- $$ = $1;
- }
- | interface DOXYGENPOSTSTRING {
- Node *node = lastChild($1);
- if (node) {
- set_comment(node, $2);
- }
- $$ = $1;
- }
- | empty {
- $$ = new_node("top");
- }
- ;
-
-declaration : swig_directive { $$ = $1; }
- | c_declaration { $$ = $1; }
- | cpp_declaration { $$ = $1; }
- | SEMI { $$ = 0; }
- | error {
- $$ = 0;
- if (cparse_unknown_directive) {
- Swig_error(cparse_file, cparse_line, "Unknown directive '%s'.\n", cparse_unknown_directive);
- } else {
- Swig_error(cparse_file, cparse_line, "Syntax error in input(1).\n");
- }
- Exit(EXIT_FAILURE);
- }
-/* Out of class constructor/destructor declarations */
- | c_constructor_decl {
- if ($$) {
- add_symbols($$);
- }
- $$ = $1;
- }
-
-/* Out of class conversion operator. For example:
- inline A::operator char *() const { ... }.
-
- This is nearly impossible to parse normally. We just let the
- first part generate a syntax error and then resynchronize on the
- CONVERSIONOPERATOR token---discarding the rest of the definition. Ugh.
-
- */
-
- | error CONVERSIONOPERATOR {
- $$ = 0;
- skip_decl();
- }
- ;
-
-/* ======================================================================
- * SWIG DIRECTIVES
- * ====================================================================== */
-
-swig_directive : extend_directive { $$ = $1; }
- | apply_directive { $$ = $1; }
- | clear_directive { $$ = $1; }
- | constant_directive { $$ = $1; }
- | echo_directive { $$ = $1; }
- | except_directive { $$ = $1; }
- | fragment_directive { $$ = $1; }
- | include_directive { $$ = $1; }
- | inline_directive { $$ = $1; }
- | insert_directive { $$ = $1; }
- | module_directive { $$ = $1; }
- | name_directive { $$ = $1; }
- | native_directive { $$ = $1; }
- | pragma_directive { $$ = $1; }
- | rename_directive { $$ = $1; }
- | feature_directive { $$ = $1; }
- | varargs_directive { $$ = $1; }
- | typemap_directive { $$ = $1; }
- | types_directive { $$ = $1; }
- | template_directive { $$ = $1; }
- | warn_directive { $$ = $1; }
- ;
-
-/* ------------------------------------------------------------
- %extend classname { ... }
- ------------------------------------------------------------ */
-
-extend_directive : EXTEND options classkeyopt idcolon LBRACE {
- Node *cls;
- String *clsname;
- extendmode = 1;
- cplus_mode = CPLUS_PUBLIC;
- if (!classes) classes = NewHash();
- if (!classes_typedefs) classes_typedefs = NewHash();
- clsname = make_class_name($4);
- cls = Getattr(classes,clsname);
- if (!cls) {
- cls = Getattr(classes_typedefs, clsname);
- if (!cls) {
- /* No previous definition. Create a new scope */
- Node *am = Getattr(Swig_extend_hash(),clsname);
- if (!am) {
- Swig_symbol_newscope();
- Swig_symbol_setscopename($4);
- prev_symtab = 0;
- } else {
- prev_symtab = Swig_symbol_setscope(Getattr(am,"symtab"));
- }
- current_class = 0;
- } else {
- /* Previous typedef class definition. Use its symbol table.
- Deprecated, just the real name should be used.
- Note that %extend before the class typedef never worked, only %extend after the class typedef. */
- prev_symtab = Swig_symbol_setscope(Getattr(cls, "symtab"));
- current_class = cls;
- SWIG_WARN_NODE_BEGIN(cls);
- Swig_warning(WARN_PARSE_EXTEND_NAME, cparse_file, cparse_line, "Deprecated %%extend name used - the %s name '%s' should be used instead of the typedef name '%s'.\n", Getattr(cls, "kind"), SwigType_namestr(Getattr(cls, "name")), $4);
- SWIG_WARN_NODE_END(cls);
- }
- } else {
- /* Previous class definition. Use its symbol table */
- prev_symtab = Swig_symbol_setscope(Getattr(cls,"symtab"));
- current_class = cls;
- }
- Classprefix = NewString($4);
- Namespaceprefix= Swig_symbol_qualifiedscopename(0);
- Delete(clsname);
- } cpp_members RBRACE {
- String *clsname;
- extendmode = 0;
- $$ = new_node("extend");
- Setattr($$,"symtab",Swig_symbol_popscope());
- if (prev_symtab) {
- Swig_symbol_setscope(prev_symtab);
- }
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- clsname = make_class_name($4);
- Setattr($$,"name",clsname);
-
- mark_nodes_as_extend($7);
- if (current_class) {
- /* We add the extension to the previously defined class */
- appendChild($$, $7);
- appendChild(current_class,$$);
- } else {
- /* We store the extensions in the extensions hash */
- Node *am = Getattr(Swig_extend_hash(),clsname);
- if (am) {
- /* Append the members to the previous extend methods */
- appendChild(am, $7);
- } else {
- appendChild($$, $7);
- Setattr(Swig_extend_hash(),clsname,$$);
- }
- }
- current_class = 0;
- Delete(Classprefix);
- Delete(clsname);
- Classprefix = 0;
- prev_symtab = 0;
- $$ = 0;
-
- }
- ;
-
-/* ------------------------------------------------------------
- %apply
- ------------------------------------------------------------ */
-
-apply_directive : APPLY typemap_parm LBRACE tm_list RBRACE {
- $$ = new_node("apply");
- Setattr($$,"pattern",Getattr($2,"pattern"));
- appendChild($$,$4);
- };
-
-/* ------------------------------------------------------------
- %clear
- ------------------------------------------------------------ */
-
-clear_directive : CLEAR tm_list SEMI {
- $$ = new_node("clear");
- appendChild($$,$2);
- }
- ;
-
-/* ------------------------------------------------------------
- %constant name = value;
- %constant type name = value;
-
- Note: Source/Preprocessor/cpp.c injects `%constant X = Y;` for
- each `#define X Y` so that's handled here too.
- ------------------------------------------------------------ */
-
-constant_directive : CONSTANT identifier EQUAL definetype SEMI {
- if (($4.type != T_ERROR) && ($4.type != T_SYMBOL)) {
- SwigType *type = NewSwigType($4.type);
- $$ = new_node("constant");
- Setattr($$,"name",$2);
- Setattr($$,"type",type);
- Setattr($$,"value",$4.val);
- if ($4.rawval) Setattr($$,"rawval", $4.rawval);
- Setattr($$,"storage","%constant");
- SetFlag($$,"feature:immutable");
- add_symbols($$);
- Delete(type);
- } else {
- if ($4.type == T_ERROR) {
- Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line,"Unsupported constant value (ignored)\n");
- }
- $$ = 0;
- }
-
- }
- | CONSTANT type declarator def_args SEMI {
- if (($4.type != T_ERROR) && ($4.type != T_SYMBOL)) {
- SwigType_push($2,$3.type);
- /* Sneaky callback function trick */
- if (SwigType_isfunction($2)) {
- SwigType_add_pointer($2);
- }
- $$ = new_node("constant");
- Setattr($$,"name",$3.id);
- Setattr($$,"type",$2);
- Setattr($$,"value",$4.val);
- if ($4.rawval) Setattr($$,"rawval", $4.rawval);
- Setattr($$,"storage","%constant");
- SetFlag($$,"feature:immutable");
- add_symbols($$);
- } else {
- if ($4.type == T_ERROR) {
- Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line, "Unsupported constant value\n");
- }
- $$ = 0;
- }
- }
- /* Member function pointers with qualifiers. eg.
- %constant short (Funcs::*pmf)(bool) const = &Funcs::F; */
- | CONSTANT type direct_declarator LPAREN parms RPAREN cv_ref_qualifier def_args SEMI {
- if (($8.type != T_ERROR) && ($8.type != T_SYMBOL)) {
- SwigType_add_function($2, $5);
- SwigType_push($2, $7.qualifier);
- SwigType_push($2, $3.type);
- /* Sneaky callback function trick */
- if (SwigType_isfunction($2)) {
- SwigType_add_pointer($2);
- }
- $$ = new_node("constant");
- Setattr($$, "name", $3.id);
- Setattr($$, "type", $2);
- Setattr($$, "value", $8.val);
- if ($8.rawval) Setattr($$, "rawval", $8.rawval);
- Setattr($$, "storage", "%constant");
- SetFlag($$, "feature:immutable");
- add_symbols($$);
- } else {
- if ($8.type == T_ERROR) {
- Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line, "Unsupported constant value\n");
- }
- $$ = 0;
- }
- }
- | CONSTANT error SEMI {
- Swig_warning(WARN_PARSE_BAD_VALUE,cparse_file,cparse_line,"Bad constant value (ignored).\n");
- $$ = 0;
- }
- | CONSTANT error END {
- Swig_error(cparse_file,cparse_line,"Missing semicolon (';') after %%constant.\n");
- Exit(EXIT_FAILURE);
- }
- ;
-
-/* ------------------------------------------------------------
- %echo "text"
- %echo %{ ... %}
- ------------------------------------------------------------ */
-
-echo_directive : ECHO HBLOCK {
- char temp[64];
- Replace($2,"$file",cparse_file, DOH_REPLACE_ANY);
- sprintf(temp,"%d", cparse_line);
- Replace($2,"$line",temp,DOH_REPLACE_ANY);
- Printf(stderr,"%s\n", $2);
- Delete($2);
- $$ = 0;
- }
- | ECHO string {
- char temp[64];
- String *s = $2;
- Replace(s,"$file",cparse_file, DOH_REPLACE_ANY);
- sprintf(temp,"%d", cparse_line);
- Replace(s,"$line",temp,DOH_REPLACE_ANY);
- Printf(stderr,"%s\n", s);
- Delete(s);
- $$ = 0;
- }
- ;
-
-/* ------------------------------------------------------------
- %except(lang) { ... }
- %except { ... }
- %except(lang);
- %except;
- ------------------------------------------------------------ */
-
-except_directive : EXCEPT LPAREN identifier RPAREN LBRACE {
- skip_balanced('{','}');
- $$ = 0;
- Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n");
- }
-
- | EXCEPT LBRACE {
- skip_balanced('{','}');
- $$ = 0;
- Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n");
- }
-
- | EXCEPT LPAREN identifier RPAREN SEMI {
- $$ = 0;
- Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n");
- }
-
- | EXCEPT SEMI {
- $$ = 0;
- Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n");
- }
- ;
-
-/* fragment keyword arguments */
-stringtype : string LBRACE parm RBRACE {
- $$ = NewHash();
- Setattr($$,"value",$1);
- Setattr($$,"type",Getattr($3,"type"));
- }
- ;
-
-fname : string {
- $$ = NewHash();
- Setattr($$,"value",$1);
- }
- | stringtype {
- $$ = $1;
- }
- ;
-
-/* ------------------------------------------------------------
- %fragment(name, section) %{ ... %}
- %fragment("name" {type}, "section") %{ ... %}
- %fragment("name", "section", fragment="fragment1", fragment="fragment2") %{ ... %}
- Also as above but using { ... }
- %fragment("name");
- ------------------------------------------------------------ */
-
-fragment_directive: FRAGMENT LPAREN fname COMMA kwargs RPAREN HBLOCK {
- Hash *p = $5;
- $$ = new_node("fragment");
- Setattr($$,"value",Getattr($3,"value"));
- Setattr($$,"type",Getattr($3,"type"));
- Setattr($$,"section",Getattr(p,"name"));
- Setattr($$,"kwargs",nextSibling(p));
- Setattr($$,"code",$7);
- }
- | FRAGMENT LPAREN fname COMMA kwargs RPAREN LBRACE {
- Hash *p = $5;
- String *code;
- skip_balanced('{','}');
- $$ = new_node("fragment");
- Setattr($$,"value",Getattr($3,"value"));
- Setattr($$,"type",Getattr($3,"type"));
- Setattr($$,"section",Getattr(p,"name"));
- Setattr($$,"kwargs",nextSibling(p));
- Delitem(scanner_ccode,0);
- Delitem(scanner_ccode,DOH_END);
- code = Copy(scanner_ccode);
- Setattr($$,"code",code);
- Delete(code);
- }
- | FRAGMENT LPAREN fname RPAREN SEMI {
- $$ = new_node("fragment");
- Setattr($$,"value",Getattr($3,"value"));
- Setattr($$,"type",Getattr($3,"type"));
- Setattr($$,"emitonly","1");
- }
- ;
-
-/* ------------------------------------------------------------
- %includefile(option1="xyz", ...) "filename" [ declarations ]
- %importfile(option1="xyz", ...) "filename" [ declarations ]
- ------------------------------------------------------------ */
-
-include_directive: includetype options string BEGINFILE {
- $1.filename = Copy(cparse_file);
- $1.line = cparse_line;
- scanner_set_location($3,1);
- if ($2) {
- String *maininput = Getattr($2, "maininput");
- if (maininput)
- scanner_set_main_input_file(NewString(maininput));
- }
- } interface ENDOFFILE {
- String *mname = 0;
- $$ = $6;
- scanner_set_location($1.filename,$1.line+1);
- if (strcmp($1.type,"include") == 0) set_nodeType($$,"include");
- if (strcmp($1.type,"import") == 0) {
- mname = $2 ? Getattr($2,"module") : 0;
- set_nodeType($$,"import");
- if (import_mode) --import_mode;
- }
-
- Setattr($$,"name",$3);
- /* Search for the module (if any) */
- {
- Node *n = firstChild($$);
- while (n) {
- if (Strcmp(nodeType(n),"module") == 0) {
- if (mname) {
- Setattr(n,"name", mname);
- mname = 0;
- }
- Setattr($$,"module",Getattr(n,"name"));
- break;
- }
- n = nextSibling(n);
- }
- if (mname) {
- /* There is no module node in the import
- node, ie, you imported a .h file
- directly. We are forced then to create
- a new import node with a module node.
- */
- Node *nint = new_node("import");
- Node *mnode = new_node("module");
- Setattr(mnode,"name", mname);
- Setattr(mnode,"options",$2);
- appendChild(nint,mnode);
- Delete(mnode);
- appendChild(nint,firstChild($$));
- $$ = nint;
- Setattr($$,"module",mname);
- }
- }
- Setattr($$,"options",$2);
- }
- ;
-
-includetype : INCLUDE { $$.type = "include"; }
- | IMPORT { $$.type = "import"; ++import_mode;}
- ;
-
-/* ------------------------------------------------------------
- %inline %{ ... %}
- ------------------------------------------------------------ */
-
-inline_directive : INLINE HBLOCK {
- String *cpps;
- if (Namespaceprefix) {
- Swig_error(cparse_file, cparse_start_line, "%%inline directive inside a namespace is disallowed.\n");
- $$ = 0;
- } else {
- $$ = new_node("insert");
- Setattr($$,"code",$2);
- /* Need to run through the preprocessor */
- Seek($2,0,SEEK_SET);
- Setline($2,cparse_start_line);
- Setfile($2,cparse_file);
- cpps = Preprocessor_parse($2);
- start_inline(Char(cpps), cparse_start_line);
- Delete($2);
- Delete(cpps);
- }
-
- }
- | INLINE LBRACE {
- String *cpps;
- int start_line = cparse_line;
- skip_balanced('{','}');
- if (Namespaceprefix) {
- Swig_error(cparse_file, cparse_start_line, "%%inline directive inside a namespace is disallowed.\n");
-
- $$ = 0;
- } else {
- String *code;
- $$ = new_node("insert");
- Delitem(scanner_ccode,0);
- Delitem(scanner_ccode,DOH_END);
- code = Copy(scanner_ccode);
- Setattr($$,"code", code);
- Delete(code);
- cpps=Copy(scanner_ccode);
- start_inline(Char(cpps), start_line);
- Delete(cpps);
- }
- }
- ;
-
-/* ------------------------------------------------------------
- %{ ... %}
- %insert(section) "filename"
- %insert("section") "filename"
- %insert(section) %{ ... %}
- %insert("section") %{ ... %}
- ------------------------------------------------------------ */
-
-insert_directive : HBLOCK {
- $$ = new_node("insert");
- Setattr($$,"code",$1);
- }
- | INSERT LPAREN idstring RPAREN string {
- String *code = NewStringEmpty();
- $$ = new_node("insert");
- Setattr($$,"section",$3);
- Setattr($$,"code",code);
- if (Swig_insert_file($5,code) < 0) {
- Swig_error(cparse_file, cparse_line, "Couldn't find '%s'.\n", $5);
- $$ = 0;
- }
- }
- | INSERT LPAREN idstring RPAREN HBLOCK {
- $$ = new_node("insert");
- Setattr($$,"section",$3);
- Setattr($$,"code",$5);
- }
- | INSERT LPAREN idstring RPAREN LBRACE {
- String *code;
- skip_balanced('{','}');
- $$ = new_node("insert");
- Setattr($$,"section",$3);
- Delitem(scanner_ccode,0);
- Delitem(scanner_ccode,DOH_END);
- code = Copy(scanner_ccode);
- Setattr($$,"code", code);
- Delete(code);
- }
- ;
-
-/* ------------------------------------------------------------
- %module modname
- %module "modname"
- ------------------------------------------------------------ */
-
-module_directive: MODULE options idstring {
- $$ = new_node("module");
- if ($2) {
- Setattr($$,"options",$2);
- if (Getattr($2,"directors")) {
- Wrapper_director_mode_set(1);
- if (!cparse_cplusplus) {
- Swig_error(cparse_file, cparse_line, "Directors are not supported for C code and require the -c++ option\n");
- }
- }
- if (Getattr($2,"dirprot")) {
- Wrapper_director_protected_mode_set(1);
- }
- if (Getattr($2,"allprotected")) {
- Wrapper_all_protected_mode_set(1);
- }
- if (Getattr($2,"templatereduce")) {
- template_reduce = 1;
- }
- if (Getattr($2,"notemplatereduce")) {
- template_reduce = 0;
- }
- }
- if (!ModuleName) ModuleName = NewString($3);
- if (!import_mode) {
- /* first module included, we apply global
- ModuleName, which can be modify by -module */
- String *mname = Copy(ModuleName);
- Setattr($$,"name",mname);
- Delete(mname);
- } else {
- /* import mode, we just pass the idstring */
- Setattr($$,"name",$3);
- }
- if (!module_node) module_node = $$;
- }
- ;
-
-/* ------------------------------------------------------------
- %name(newname) declaration
- %name("newname") declaration
- ------------------------------------------------------------ */
-
-name_directive : NAME LPAREN idstring RPAREN {
- Swig_warning(WARN_DEPRECATED_NAME,cparse_file,cparse_line, "%%name is deprecated. Use %%rename instead.\n");
- Delete(yyrename);
- yyrename = NewString($3);
- $$ = 0;
- }
- | NAME LPAREN RPAREN {
- Swig_warning(WARN_DEPRECATED_NAME,cparse_file,cparse_line, "%%name is deprecated. Use %%rename instead.\n");
- $$ = 0;
- Swig_error(cparse_file,cparse_line,"Missing argument to %%name directive.\n");
- }
- ;
-
-
-/* ------------------------------------------------------------
- %native(scriptname) name;
- %native(scriptname) type name (parms);
- ------------------------------------------------------------ */
-
-native_directive : NATIVE LPAREN identifier RPAREN storage_class identifier SEMI {
- $$ = new_node("native");
- Setattr($$,"name",$3);
- Setattr($$,"wrap:name",$6);
- add_symbols($$);
- }
- | NATIVE LPAREN identifier RPAREN storage_class type declarator SEMI {
- if (!SwigType_isfunction($7.type)) {
- Swig_error(cparse_file,cparse_line,"%%native declaration '%s' is not a function.\n", $7.id);
- $$ = 0;
- } else {
- Delete(SwigType_pop_function($7.type));
- /* Need check for function here */
- SwigType_push($6,$7.type);
- $$ = new_node("native");
- Setattr($$,"name",$3);
- Setattr($$,"wrap:name",$7.id);
- Setattr($$,"type",$6);
- Setattr($$,"parms",$7.parms);
- Setattr($$,"decl",$7.type);
- }
- add_symbols($$);
- }
- ;
-
-/* ------------------------------------------------------------
- %pragma(lang) name=value
- %pragma(lang) name
- %pragma name = value
- %pragma name
- ------------------------------------------------------------ */
-
-pragma_directive : PRAGMA pragma_lang identifier EQUAL pragma_arg {
- $$ = new_node("pragma");
- Setattr($$,"lang",$2);
- Setattr($$,"name",$3);
- Setattr($$,"value",$5);
- }
- | PRAGMA pragma_lang identifier {
- $$ = new_node("pragma");
- Setattr($$,"lang",$2);
- Setattr($$,"name",$3);
- }
- ;
-
-pragma_arg : string { $$ = $1; }
- | HBLOCK { $$ = $1; }
- ;
-
-pragma_lang : LPAREN identifier RPAREN { $$ = $2; }
- | empty { $$ = (char *) "swig"; }
- ;
-
-/* ------------------------------------------------------------
- %rename(newname) identifier;
- ------------------------------------------------------------ */
-
-rename_directive : rename_namewarn declarator idstring SEMI {
- SwigType *t = $2.type;
- Hash *kws = NewHash();
- String *fixname;
- fixname = feature_identifier_fix($2.id);
- Setattr(kws,"name",$3);
- if (!Len(t)) t = 0;
- /* Special declarator check */
- if (t) {
- if (SwigType_isfunction(t)) {
- SwigType *decl = SwigType_pop_function(t);
- if (SwigType_ispointer(t)) {
- String *nname = NewStringf("*%s",fixname);
- if ($1) {
- Swig_name_rename_add(Namespaceprefix, nname,decl,kws,$2.parms);
- } else {
- Swig_name_namewarn_add(Namespaceprefix,nname,decl,kws);
- }
- Delete(nname);
- } else {
- if ($1) {
- Swig_name_rename_add(Namespaceprefix,(fixname),decl,kws,$2.parms);
- } else {
- Swig_name_namewarn_add(Namespaceprefix,(fixname),decl,kws);
- }
- }
- Delete(decl);
- } else if (SwigType_ispointer(t)) {
- String *nname = NewStringf("*%s",fixname);
- if ($1) {
- Swig_name_rename_add(Namespaceprefix,(nname),0,kws,$2.parms);
- } else {
- Swig_name_namewarn_add(Namespaceprefix,(nname),0,kws);
- }
- Delete(nname);
- }
- } else {
- if ($1) {
- Swig_name_rename_add(Namespaceprefix,(fixname),0,kws,$2.parms);
- } else {
- Swig_name_namewarn_add(Namespaceprefix,(fixname),0,kws);
- }
- }
- $$ = 0;
- scanner_clear_rename();
- }
- | rename_namewarn LPAREN kwargs RPAREN declarator cpp_const SEMI {
- String *fixname;
- Hash *kws = $3;
- SwigType *t = $5.type;
- fixname = feature_identifier_fix($5.id);
- if (!Len(t)) t = 0;
- /* Special declarator check */
- if (t) {
- if ($6.qualifier) SwigType_push(t,$6.qualifier);
- if (SwigType_isfunction(t)) {
- SwigType *decl = SwigType_pop_function(t);
- if (SwigType_ispointer(t)) {
- String *nname = NewStringf("*%s",fixname);
- if ($1) {
- Swig_name_rename_add(Namespaceprefix, nname,decl,kws,$5.parms);
- } else {
- Swig_name_namewarn_add(Namespaceprefix,nname,decl,kws);
- }
- Delete(nname);
- } else {
- if ($1) {
- Swig_name_rename_add(Namespaceprefix,(fixname),decl,kws,$5.parms);
- } else {
- Swig_name_namewarn_add(Namespaceprefix,(fixname),decl,kws);
- }
- }
- Delete(decl);
- } else if (SwigType_ispointer(t)) {
- String *nname = NewStringf("*%s",fixname);
- if ($1) {
- Swig_name_rename_add(Namespaceprefix,(nname),0,kws,$5.parms);
- } else {
- Swig_name_namewarn_add(Namespaceprefix,(nname),0,kws);
- }
- Delete(nname);
- }
- } else {
- if ($1) {
- Swig_name_rename_add(Namespaceprefix,(fixname),0,kws,$5.parms);
- } else {
- Swig_name_namewarn_add(Namespaceprefix,(fixname),0,kws);
- }
- }
- $$ = 0;
- scanner_clear_rename();
- }
- | rename_namewarn LPAREN kwargs RPAREN string SEMI {
- if ($1) {
- Swig_name_rename_add(Namespaceprefix,$5,0,$3,0);
- } else {
- Swig_name_namewarn_add(Namespaceprefix,$5,0,$3);
- }
- $$ = 0;
- scanner_clear_rename();
- }
- ;
-
-rename_namewarn : RENAME {
- $$ = 1;
- }
- | NAMEWARN {
- $$ = 0;
- };
-
-
-/* ------------------------------------------------------------
- Feature targeting a symbol name (non-global feature):
-
- %feature(featurename) name "val";
- %feature(featurename, val) name;
-
- where "val" could instead be the other bracket types, that is,
- { val } or %{ val %} or indeed omitted whereupon it defaults to "1".
- Or, the global feature which does not target a symbol name:
-
- %feature(featurename) "val";
- %feature(featurename, val);
-
- An empty val (empty string) clears the feature.
- Any number of feature attributes can optionally be added, for example
- a non-global feature with 2 attributes:
-
- %feature(featurename, attrib1="attribval1", attrib2="attribval2") name "val";
- %feature(featurename, val, attrib1="attribval1", attrib2="attribval2") name;
- ------------------------------------------------------------ */
-
- /* Non-global feature */
-feature_directive : FEATURE LPAREN idstring RPAREN declarator cpp_const stringbracesemi {
- String *val = $7 ? NewString($7) : NewString("1");
- new_feature($3, val, 0, $5.id, $5.type, $5.parms, $6.qualifier);
- $$ = 0;
- scanner_clear_rename();
- }
- | FEATURE LPAREN idstring COMMA stringnum RPAREN declarator cpp_const SEMI {
- String *val = Len($5) ? $5 : 0;
- new_feature($3, val, 0, $7.id, $7.type, $7.parms, $8.qualifier);
- $$ = 0;
- scanner_clear_rename();
- }
- | FEATURE LPAREN idstring featattr RPAREN declarator cpp_const stringbracesemi {
- String *val = $8 ? NewString($8) : NewString("1");
- new_feature($3, val, $4, $6.id, $6.type, $6.parms, $7.qualifier);
- $$ = 0;
- scanner_clear_rename();
- }
- | FEATURE LPAREN idstring COMMA stringnum featattr RPAREN declarator cpp_const SEMI {
- String *val = Len($5) ? $5 : 0;
- new_feature($3, val, $6, $8.id, $8.type, $8.parms, $9.qualifier);
- $$ = 0;
- scanner_clear_rename();
- }
-
- /* Global feature */
- | FEATURE LPAREN idstring RPAREN stringbracesemi {
- String *val = $5 ? NewString($5) : NewString("1");
- new_feature($3, val, 0, 0, 0, 0, 0);
- $$ = 0;
- scanner_clear_rename();
- }
- | FEATURE LPAREN idstring COMMA stringnum RPAREN SEMI {
- String *val = Len($5) ? $5 : 0;
- new_feature($3, val, 0, 0, 0, 0, 0);
- $$ = 0;
- scanner_clear_rename();
- }
- | FEATURE LPAREN idstring featattr RPAREN stringbracesemi {
- String *val = $6 ? NewString($6) : NewString("1");
- new_feature($3, val, $4, 0, 0, 0, 0);
- $$ = 0;
- scanner_clear_rename();
- }
- | FEATURE LPAREN idstring COMMA stringnum featattr RPAREN SEMI {
- String *val = Len($5) ? $5 : 0;
- new_feature($3, val, $6, 0, 0, 0, 0);
- $$ = 0;
- scanner_clear_rename();
- }
- ;
-
-stringbracesemi : stringbrace { $$ = $1; }
- | SEMI { $$ = 0; }
- | PARMS LPAREN parms RPAREN SEMI { $$ = $3; }
- ;
-
-featattr : COMMA idstring EQUAL stringnum {
- $$ = NewHash();
- Setattr($$,"name",$2);
- Setattr($$,"value",$4);
- }
- | COMMA idstring EQUAL stringnum featattr {
- $$ = NewHash();
- Setattr($$,"name",$2);
- Setattr($$,"value",$4);
- set_nextSibling($$,$5);
- }
- ;
-
-/* %varargs() directive. */
-
-varargs_directive : VARARGS LPAREN varargs_parms RPAREN declarator cpp_const SEMI {
- Parm *val;
- String *name;
- SwigType *t;
- if (Namespaceprefix) name = NewStringf("%s::%s", Namespaceprefix, $5.id);
- else name = NewString($5.id);
- val = $3;
- if ($5.parms) {
- Setmeta(val,"parms",$5.parms);
- }
- t = $5.type;
- if (!Len(t)) t = 0;
- if (t) {
- if ($6.qualifier) SwigType_push(t,$6.qualifier);
- if (SwigType_isfunction(t)) {
- SwigType *decl = SwigType_pop_function(t);
- if (SwigType_ispointer(t)) {
- String *nname = NewStringf("*%s",name);
- Swig_feature_set(Swig_cparse_features(), nname, decl, "feature:varargs", val, 0);
- Delete(nname);
- } else {
- Swig_feature_set(Swig_cparse_features(), name, decl, "feature:varargs", val, 0);
- }
- Delete(decl);
- } else if (SwigType_ispointer(t)) {
- String *nname = NewStringf("*%s",name);
- Swig_feature_set(Swig_cparse_features(),nname,0,"feature:varargs",val, 0);
- Delete(nname);
- }
- } else {
- Swig_feature_set(Swig_cparse_features(),name,0,"feature:varargs",val, 0);
- }
- Delete(name);
- $$ = 0;
- };
-
-varargs_parms : parms { $$ = $1; }
- | NUM_INT COMMA parm {
- int i;
- int n;
- Parm *p;
- n = atoi(Char($1.val));
- if (n <= 0) {
- Swig_error(cparse_file, cparse_line,"Argument count in %%varargs must be positive.\n");
- $$ = 0;
- } else {
- String *name = Getattr($3, "name");
- $$ = Copy($3);
- if (name)
- Setattr($$, "name", NewStringf("%s%d", name, n));
- for (i = 1; i < n; i++) {
- p = Copy($3);
- name = Getattr(p, "name");
- if (name)
- Setattr(p, "name", NewStringf("%s%d", name, n-i));
- set_nextSibling(p,$$);
- Delete($$);
- $$ = p;
- }
- }
- }
- ;
-
-
-/* ------------------------------------------------------------
- %typemap(method) type { ... }
- %typemap(method) type "..."
- %typemap(method) type; - typemap deletion
- %typemap(method) type1,type2,... = type; - typemap copy
- %typemap type1,type2,... = type; - typemap copy
- ------------------------------------------------------------ */
-
-typemap_directive : TYPEMAP LPAREN typemap_type RPAREN tm_list stringbrace {
- $$ = 0;
- if ($3.method) {
- String *code = 0;
- $$ = new_node("typemap");
- Setattr($$,"method",$3.method);
- if ($3.kwargs) {
- ParmList *kw = $3.kwargs;
- code = remove_block(kw, $6);
- Setattr($$,"kwargs", $3.kwargs);
- }
- code = code ? code : NewString($6);
- Setattr($$,"code", code);
- Delete(code);
- appendChild($$,$5);
- }
- }
- | TYPEMAP LPAREN typemap_type RPAREN tm_list SEMI {
- $$ = 0;
- if ($3.method) {
- $$ = new_node("typemap");
- Setattr($$,"method",$3.method);
- appendChild($$,$5);
- }
- }
- | TYPEMAP LPAREN typemap_type RPAREN tm_list EQUAL typemap_parm SEMI {
- $$ = 0;
- if ($3.method) {
- $$ = new_node("typemapcopy");
- Setattr($$,"method",$3.method);
- Setattr($$,"pattern", Getattr($7,"pattern"));
- appendChild($$,$5);
- }
- }
- ;
-
-/* typemap method type (lang,method) or (method) */
-
-typemap_type : kwargs {
- String *name = Getattr($1, "name");
- Hash *p = nextSibling($1);
- $$.method = name;
- $$.kwargs = p;
- if (Getattr($1, "value")) {
- Swig_error(cparse_file, cparse_line,
- "%%typemap method shouldn't have a value specified.\n");
- }
- while (p) {
- if (!Getattr(p, "value")) {
- Swig_error(cparse_file, cparse_line,
- "%%typemap attribute '%s' is missing its value. If this is specifying the target language, that's no longer supported: use #ifdef SWIG<LANG> instead.\n",
- Getattr(p, "name"));
- /* Set to empty value to avoid segfaults later. */
- Setattr(p, "value", NewStringEmpty());
- }
- p = nextSibling(p);
- }
- }
- ;
-
-tm_list : typemap_parm tm_tail {
- $$ = $1;
- set_nextSibling($$,$2);
- }
- ;
-
-tm_tail : COMMA typemap_parm tm_tail {
- $$ = $2;
- set_nextSibling($$,$3);
- }
- | empty { $$ = 0;}
- ;
-
-typemap_parm : type plain_declarator {
- Parm *parm;
- SwigType_push($1,$2.type);
- $$ = new_node("typemapitem");
- parm = NewParmWithoutFileLineInfo($1,$2.id);
- Setattr($$,"pattern",parm);
- Setattr($$,"parms", $2.parms);
- Delete(parm);
- /* $$ = NewParmWithoutFileLineInfo($1,$2.id);
- Setattr($$,"parms",$2.parms); */
- }
- | LPAREN parms RPAREN {
- $$ = new_node("typemapitem");
- Setattr($$,"pattern",$2);
- /* Setattr($$,"multitype",$2); */
- }
- | LPAREN parms RPAREN LPAREN parms RPAREN {
- $$ = new_node("typemapitem");
- Setattr($$,"pattern", $2);
- /* Setattr($$,"multitype",$2); */
- Setattr($$,"parms",$5);
- }
- ;
-
-/* ------------------------------------------------------------
- %types(parmlist);
- %types(parmlist) %{ ... %}
- ------------------------------------------------------------ */
-
-types_directive : TYPES LPAREN parms RPAREN stringbracesemi {
- $$ = new_node("types");
- Setattr($$,"parms",$3);
- if ($5)
- Setattr($$,"convcode",NewString($5));
- }
- ;
-
-/* ------------------------------------------------------------
- %template(name) tname<args>;
- ------------------------------------------------------------ */
-
-template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN valparms GREATERTHAN SEMI {
- Parm *p, *tp;
- Node *n;
- Node *outer_class = currentOuterClass;
- Symtab *tscope = 0;
- int specialized = 0;
- int variadic = 0;
-
- $$ = 0;
-
- tscope = Swig_symbol_current(); /* Get the current scope */
-
- /* If the class name is qualified, we need to create or lookup namespace entries */
- $5 = resolve_create_node_scope($5, 0);
-
- if (nscope_inner && Strcmp(nodeType(nscope_inner), "class") == 0) {
- outer_class = nscope_inner;
- }
-
- /*
- We use the new namespace entry 'nscope' only to
- emit the template node. The template parameters are
- resolved in the current 'tscope'.
-
- This is closer to the C++ (typedef) behavior.
- */
- n = Swig_cparse_template_locate($5,$7,tscope);
-
- /* Patch the argument types to respect namespaces */
- p = $7;
- while (p) {
- SwigType *value = Getattr(p,"value");
- if (!value) {
- SwigType *ty = Getattr(p,"type");
- if (ty) {
- SwigType *rty = 0;
- int reduce = template_reduce;
- if (reduce || !SwigType_ispointer(ty)) {
- rty = Swig_symbol_typedef_reduce(ty,tscope);
- if (!reduce) reduce = SwigType_ispointer(rty);
- }
- ty = reduce ? Swig_symbol_type_qualify(rty,tscope) : Swig_symbol_type_qualify(ty,tscope);
- Setattr(p,"type",ty);
- Delete(ty);
- Delete(rty);
- }
- } else {
- value = Swig_symbol_type_qualify(value,tscope);
- Setattr(p,"value",value);
- Delete(value);
- }
-
- p = nextSibling(p);
- }
-
- /* Look for the template */
- {
- Node *nn = n;
- Node *linklistend = 0;
- Node *linkliststart = 0;
- while (nn) {
- Node *templnode = 0;
- if (Strcmp(nodeType(nn),"template") == 0) {
- int nnisclass = (Strcmp(Getattr(nn,"templatetype"),"class") == 0); /* if not a templated class it is a templated function */
- Parm *tparms = Getattr(nn,"templateparms");
- if (!tparms) {
- specialized = 1;
- } else if (Getattr(tparms,"variadic") && strncmp(Char(Getattr(tparms,"variadic")), "1", 1)==0) {
- variadic = 1;
- }
- if (nnisclass && !variadic && !specialized && (ParmList_len($7) > ParmList_len(tparms))) {
- Swig_error(cparse_file, cparse_line, "Too many template parameters. Maximum of %d.\n", ParmList_len(tparms));
- } else if (nnisclass && !specialized && ((ParmList_len($7) < (ParmList_numrequired(tparms) - (variadic?1:0))))) { /* Variadic parameter is optional */
- Swig_error(cparse_file, cparse_line, "Not enough template parameters specified. %d required.\n", (ParmList_numrequired(tparms)-(variadic?1:0)) );
- } else if (!nnisclass && ((ParmList_len($7) != ParmList_len(tparms)))) {
- /* must be an overloaded templated method - ignore it as it is overloaded with a different number of template parameters */
- nn = Getattr(nn,"sym:nextSibling"); /* repeat for overloaded templated functions */
- continue;
- } else {
- String *tname = Copy($5);
- int def_supplied = 0;
- /* Expand the template */
- Node *templ = Swig_symbol_clookup($5,0);
- Parm *targs = templ ? Getattr(templ,"templateparms") : 0;
-
- ParmList *temparms;
- if (specialized) temparms = CopyParmList($7);
- else temparms = CopyParmList(tparms);
-
- /* Create typedef's and arguments */
- p = $7;
- tp = temparms;
- if (!p && ParmList_len(p) != ParmList_len(temparms)) {
- /* we have no template parameters supplied in %template for a template that has default args*/
- p = tp;
- def_supplied = 1;
- }
-
- while (p) {
- String *value = Getattr(p,"value");
- if (def_supplied) {
- Setattr(p,"default","1");
- }
- if (value) {
- Setattr(tp,"value",value);
- } else {
- SwigType *ty = Getattr(p,"type");
- if (ty) {
- Setattr(tp,"type",ty);
- }
- Delattr(tp,"value");
- }
- /* fix default arg values */
- if (targs) {
- Parm *pi = temparms;
- Parm *ti = targs;
- String *tv = Getattr(tp,"value");
- if (!tv) tv = Getattr(tp,"type");
- while(pi != tp && ti && pi) {
- String *name = Getattr(ti,"name");
- String *value = Getattr(pi,"value");
- if (!value) value = Getattr(pi,"type");
- Replaceid(tv, name, value);
- pi = nextSibling(pi);
- ti = nextSibling(ti);
- }
- }
- p = nextSibling(p);
- tp = nextSibling(tp);
- if (!p && tp) {
- p = tp;
- def_supplied = 1;
- } else if (p && !tp) { /* Variadic template - tp < p */
- SWIG_WARN_NODE_BEGIN(nn);
- Swig_warning(WARN_CPP11_VARIADIC_TEMPLATE,cparse_file, cparse_line,"Only the first variadic template argument is currently supported.\n");
- SWIG_WARN_NODE_END(nn);
- break;
- }
- }
-
- templnode = copy_node(nn);
- update_nested_classes(templnode); /* update classes nested within template */
- /* We need to set the node name based on name used to instantiate */
- Setattr(templnode,"name",tname);
- Delete(tname);
- if (!specialized) {
- Delattr(templnode,"sym:typename");
- } else {
- Setattr(templnode,"sym:typename","1");
- }
- /* for now, nested %template is allowed only in the same scope as the template declaration */
- if ($3 && !(nnisclass && ((outer_class && (outer_class != Getattr(nn, "nested:outer")))
- ||(extendmode && current_class && (current_class != Getattr(nn, "nested:outer")))))) {
- /*
- Comment this out for 1.3.28. We need to
- re-enable it later but first we need to
- move %ignore from using %rename to use
- %feature(ignore).
-
- String *symname = Swig_name_make(templnode,0,$3,0,0);
- */
- String *symname = NewString($3);
- Swig_cparse_template_expand(templnode,symname,temparms,tscope);
- Setattr(templnode,"sym:name",symname);
- } else {
- static int cnt = 0;
- String *nname = NewStringf("__dummy_%d__", cnt++);
- Swig_cparse_template_expand(templnode,nname,temparms,tscope);
- Setattr(templnode,"sym:name",nname);
- SetFlag(templnode,"hidden");
- Delete(nname);
- Setattr(templnode,"feature:onlychildren", "typemap,typemapitem,typemapcopy,typedef,types,fragment,apply");
- if ($3) {
- Swig_warning(WARN_PARSE_NESTED_TEMPLATE, cparse_file, cparse_line, "Named nested template instantiations not supported. Processing as if no name was given to %%template().\n");
- }
- }
- Delattr(templnode,"templatetype");
- Setattr(templnode,"template",nn);
- Setfile(templnode,cparse_file);
- Setline(templnode,cparse_line);
- Delete(temparms);
- if (outer_class && nnisclass) {
- SetFlag(templnode, "nested");
- Setattr(templnode, "nested:outer", outer_class);
- }
- add_symbols_copy(templnode);
-
- if (Strcmp(nodeType(templnode),"class") == 0) {
-
- /* Identify pure abstract methods */
- Setattr(templnode,"abstracts", pure_abstracts(firstChild(templnode)));
-
- /* Set up inheritance in symbol table */
- {
- Symtab *csyms;
- List *baselist = Getattr(templnode,"baselist");
- csyms = Swig_symbol_current();
- Swig_symbol_setscope(Getattr(templnode,"symtab"));
- if (baselist) {
- List *bases = Swig_make_inherit_list(Getattr(templnode,"name"),baselist, Namespaceprefix);
- if (bases) {
- Iterator s;
- for (s = First(bases); s.item; s = Next(s)) {
- Symtab *st = Getattr(s.item,"symtab");
- if (st) {
- Setfile(st,Getfile(s.item));
- Setline(st,Getline(s.item));
- Swig_symbol_inherit(st);
- }
- }
- Delete(bases);
- }
- }
- Swig_symbol_setscope(csyms);
- }
-
- /* Merge in %extend methods for this class.
- This only merges methods within %extend for a template specialized class such as
- template<typename T> class K {}; %extend K<int> { ... }
- The copy_node() call above has already added in the generic %extend methods such as
- template<typename T> class K {}; %extend K { ... } */
-
- /* !!! This may be broken. We may have to add the
- %extend methods at the beginning of the class */
- {
- String *stmp = 0;
- String *clsname;
- Node *am;
- if (Namespaceprefix) {
- clsname = stmp = NewStringf("%s::%s", Namespaceprefix, Getattr(templnode,"name"));
- } else {
- clsname = Getattr(templnode,"name");
- }
- am = Getattr(Swig_extend_hash(),clsname);
- if (am) {
- Symtab *st = Swig_symbol_current();
- Swig_symbol_setscope(Getattr(templnode,"symtab"));
- /* Printf(stdout,"%s: %s %p %p\n", Getattr(templnode,"name"), clsname, Swig_symbol_current(), Getattr(templnode,"symtab")); */
- Swig_extend_merge(templnode,am);
- Swig_symbol_setscope(st);
- Swig_extend_append_previous(templnode,am);
- Delattr(Swig_extend_hash(),clsname);
- }
- if (stmp) Delete(stmp);
- }
-
- /* Add to classes hash */
- if (!classes)
- classes = NewHash();
-
- if (Namespaceprefix) {
- String *temp = NewStringf("%s::%s", Namespaceprefix, Getattr(templnode,"name"));
- Setattr(classes,temp,templnode);
- Delete(temp);
- } else {
- String *qs = Swig_symbol_qualifiedscopename(templnode);
- Setattr(classes, qs,templnode);
- Delete(qs);
- }
- }
- }
-
- /* all the overloaded templated functions are added into a linked list */
- if (!linkliststart)
- linkliststart = templnode;
- if (nscope_inner) {
- /* non-global namespace */
- if (templnode) {
- appendChild(nscope_inner,templnode);
- Delete(templnode);
- if (nscope) $$ = nscope;
- }
- } else {
- /* global namespace */
- if (!linklistend) {
- $$ = templnode;
- } else {
- set_nextSibling(linklistend,templnode);
- Delete(templnode);
- }
- linklistend = templnode;
- }
- }
- nn = Getattr(nn,"sym:nextSibling"); /* repeat for overloaded templated functions. If a templated class there will never be a sibling. */
- }
- update_defaultargs(linkliststart);
- update_abstracts(linkliststart);
- }
- Swig_symbol_setscope(tscope);
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- }
- ;
-
-/* ------------------------------------------------------------
- %warn "text"
- %warn(no)
- ------------------------------------------------------------ */
-
-warn_directive : WARN string {
- Swig_warning(0,cparse_file, cparse_line,"%s\n", $2);
- $$ = 0;
- }
- ;
-
-/* ======================================================================
- * C Parsing
- * ====================================================================== */
-
-c_declaration : c_decl {
- $$ = $1;
- if ($$) {
- add_symbols($$);
- default_arguments($$);
- }
- }
- | c_enum_decl { $$ = $1; }
- | c_enum_forward_decl { $$ = $1; }
-
-/* An extern C type declaration, disable cparse_cplusplus if needed. */
-
- | EXTERN string LBRACE {
- if (Strcmp($2,"C") == 0) {
- cparse_externc = 1;
- }
- } interface RBRACE {
- cparse_externc = 0;
- if (Strcmp($2,"C") == 0) {
- Node *n = firstChild($5);
- $$ = new_node("extern");
- Setattr($$,"name",$2);
- appendChild($$,n);
- while (n) {
- String *s = Getattr(n, "storage");
- if (s) {
- if (Strstr(s, "thread_local")) {
- Insert(s,0,"externc ");
- } else if (!Equal(s, "typedef")) {
- Setattr(n,"storage","externc");
- }
- } else {
- Setattr(n,"storage","externc");
- }
- n = nextSibling(n);
- }
- } else {
- if (!Equal($2,"C++")) {
- Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", $2);
- }
- $$ = new_node("extern");
- Setattr($$,"name",$2);
- appendChild($$,firstChild($5));
- }
- }
- | cpp_lambda_decl {
- $$ = $1;
- SWIG_WARN_NODE_BEGIN($$);
- Swig_warning(WARN_CPP11_LAMBDA, cparse_file, cparse_line, "Lambda expressions and closures are not fully supported yet.\n");
- SWIG_WARN_NODE_END($$);
- }
- | USING idcolon EQUAL type plain_declarator SEMI {
- /* Convert using statement to a typedef statement */
- $$ = new_node("cdecl");
- Setattr($$,"type",$4);
- Setattr($$,"storage","typedef");
- Setattr($$,"name",$2);
- Setattr($$,"decl",$5.type);
- SetFlag($$,"typealias");
- add_symbols($$);
- }
- | TEMPLATE LESSTHAN template_parms GREATERTHAN USING idcolon EQUAL type plain_declarator SEMI {
- /* Convert alias template to a "template" typedef statement */
- $$ = new_node("template");
- Setattr($$,"type",$8);
- Setattr($$,"storage","typedef");
- Setattr($$,"name",$6);
- Setattr($$,"decl",$9.type);
- Setattr($$,"templateparms",$3);
- Setattr($$,"templatetype","cdecl");
- SetFlag($$,"aliastemplate");
- add_symbols($$);
- }
- | cpp_static_assert {
- $$ = $1;
- }
- ;
-
-/* ------------------------------------------------------------
- A C global declaration of some kind (may be variable, function, typedef, etc.)
- ------------------------------------------------------------ */
-
-c_decl : storage_class type declarator cpp_const initializer c_decl_tail {
- String *decl = $3.type;
- $$ = new_node("cdecl");
- if ($4.qualifier)
- decl = add_qualifier_to_declarator($3.type, $4.qualifier);
- Setattr($$,"refqualifier",$4.refqualifier);
- Setattr($$,"type",$2);
- Setattr($$,"storage",$1);
- Setattr($$,"name",$3.id);
- Setattr($$,"decl",decl);
- Setattr($$,"parms",$3.parms);
- Setattr($$,"value",$5.val);
- Setattr($$,"throws",$4.throws);
- Setattr($$,"throw",$4.throwf);
- Setattr($$,"noexcept",$4.nexcept);
- Setattr($$,"final",$4.final);
- if ($5.val && $5.type) {
- /* store initializer type as it might be different to the declared type */
- SwigType *valuetype = NewSwigType($5.type);
- if (Len(valuetype) > 0)
- Setattr($$,"valuetype",valuetype);
- else
- Delete(valuetype);
- }
- if (!$6) {
- if (Len(scanner_ccode)) {
- String *code = Copy(scanner_ccode);
- Setattr($$,"code",code);
- Delete(code);
- }
- } else {
- Node *n = $6;
- /* Inherit attributes */
- while (n) {
- String *type = Copy($2);
- Setattr(n,"type",type);
- Setattr(n,"storage",$1);
- n = nextSibling(n);
- Delete(type);
- }
- }
- if ($5.bitfield) {
- Setattr($$,"bitfield", $5.bitfield);
- }
-
- if ($3.id) {
- /* Look for "::" declarations (ignored) */
- if (Strstr($3.id, "::")) {
- /* This is a special case. If the scope name of the declaration exactly
- matches that of the declaration, then we will allow it. Otherwise, delete. */
- String *p = Swig_scopename_prefix($3.id);
- if (p) {
- if ((Namespaceprefix && Strcmp(p, Namespaceprefix) == 0) ||
- (Classprefix && Strcmp(p, Classprefix) == 0)) {
- String *lstr = Swig_scopename_last($3.id);
- Setattr($$, "name", lstr);
- Delete(lstr);
- set_nextSibling($$, $6);
- } else {
- Delete($$);
- $$ = $6;
- }
- Delete(p);
- } else {
- Delete($$);
- $$ = $6;
- }
- } else {
- set_nextSibling($$, $6);
- }
- } else {
- Swig_error(cparse_file, cparse_line, "Missing symbol name for global declaration\n");
- $$ = 0;
- }
-
- if ($4.qualifier && $1 && Strstr($1, "static"))
- Swig_error(cparse_file, cparse_line, "Static function %s cannot have a qualifier.\n", Swig_name_decl($$));
- }
- /* Alternate function syntax introduced in C++11:
- auto funcName(int x, int y) -> int; */
- | storage_class AUTO declarator cpp_const ARROW cpp_alternate_rettype virt_specifier_seq_opt initializer c_decl_tail {
- $$ = new_node("cdecl");
- if ($4.qualifier) SwigType_push($3.type, $4.qualifier);
- Setattr($$,"refqualifier",$4.refqualifier);
- Setattr($$,"type",$6);
- Setattr($$,"storage",$1);
- Setattr($$,"name",$3.id);
- Setattr($$,"decl",$3.type);
- Setattr($$,"parms",$3.parms);
- Setattr($$,"value",$4.val);
- Setattr($$,"throws",$4.throws);
- Setattr($$,"throw",$4.throwf);
- Setattr($$,"noexcept",$4.nexcept);
- Setattr($$,"final",$4.final);
- if (!$9) {
- if (Len(scanner_ccode)) {
- String *code = Copy(scanner_ccode);
- Setattr($$,"code",code);
- Delete(code);
- }
- } else {
- Node *n = $9;
- while (n) {
- String *type = Copy($6);
- Setattr(n,"type",type);
- Setattr(n,"storage",$1);
- n = nextSibling(n);
- Delete(type);
- }
- }
- if ($4.bitfield) {
- Setattr($$,"bitfield", $4.bitfield);
- }
-
- if (Strstr($3.id,"::")) {
- String *p = Swig_scopename_prefix($3.id);
- if (p) {
- if ((Namespaceprefix && Strcmp(p, Namespaceprefix) == 0) ||
- (Classprefix && Strcmp(p, Classprefix) == 0)) {
- String *lstr = Swig_scopename_last($3.id);
- Setattr($$,"name",lstr);
- Delete(lstr);
- set_nextSibling($$, $9);
- } else {
- Delete($$);
- $$ = $9;
- }
- Delete(p);
- } else {
- Delete($$);
- $$ = $9;
- }
- } else {
- set_nextSibling($$, $9);
- }
-
- if ($4.qualifier && $1 && Strstr($1, "static"))
- Swig_error(cparse_file, cparse_line, "Static function %s cannot have a qualifier.\n", Swig_name_decl($$));
- }
- ;
-
-/* Allow lists of variables and functions to be built up */
-
-c_decl_tail : SEMI {
- $$ = 0;
- Clear(scanner_ccode);
- }
- | COMMA declarator cpp_const initializer c_decl_tail {
- $$ = new_node("cdecl");
- if ($3.qualifier) SwigType_push($2.type,$3.qualifier);
- Setattr($$,"refqualifier",$3.refqualifier);
- Setattr($$,"name",$2.id);
- Setattr($$,"decl",$2.type);
- Setattr($$,"parms",$2.parms);
- Setattr($$,"value",$4.val);
- Setattr($$,"throws",$3.throws);
- Setattr($$,"throw",$3.throwf);
- Setattr($$,"noexcept",$3.nexcept);
- Setattr($$,"final",$3.final);
- if ($4.bitfield) {
- Setattr($$,"bitfield", $4.bitfield);
- }
- if (!$5) {
- if (Len(scanner_ccode)) {
- String *code = Copy(scanner_ccode);
- Setattr($$,"code",code);
- Delete(code);
- }
- } else {
- set_nextSibling($$, $5);
- }
- }
- | LBRACE {
- skip_balanced('{','}');
- $$ = 0;
- }
- | error {
- $$ = 0;
- if (yychar == RPAREN) {
- Swig_error(cparse_file, cparse_line, "Unexpected closing parenthesis (')').\n");
- } else {
- Swig_error(cparse_file, cparse_line, "Syntax error - possibly a missing semicolon (';').\n");
- }
- Exit(EXIT_FAILURE);
- }
- ;
-
-initializer : def_args {
- $$ = $1;
- }
- ;
-
-cpp_alternate_rettype : primitive_type { $$ = $1; }
- | TYPE_BOOL { $$ = $1; }
- | TYPE_VOID { $$ = $1; }
-/*
- | TYPE_TYPEDEF template_decl { $$ = NewStringf("%s%s",$1,$2); }
-*/
- | TYPE_RAW { $$ = $1; }
- | idcolon { $$ = $1; }
- | idcolon AND {
- $$ = $1;
- SwigType_add_reference($$);
- }
- | decltype { $$ = $1; }
- ;
-
-/* ------------------------------------------------------------
- Lambda functions and expressions, such as:
- auto myFunc = [] { return something; };
- auto myFunc = [](int x, int y) { return x+y; };
- auto myFunc = [](int x, int y) -> int { return x+y; };
- auto myFunc = [](int x, int y) throw() -> int { return x+y; };
- auto six = [](int x, int y) { return x+y; }(4, 2);
- ------------------------------------------------------------ */
-cpp_lambda_decl : storage_class AUTO idcolon EQUAL lambda_introducer lambda_template LPAREN parms RPAREN cpp_const lambda_body lambda_tail {
- $$ = new_node("lambda");
- Setattr($$,"name",$3);
- add_symbols($$);
- }
- | storage_class AUTO idcolon EQUAL lambda_introducer lambda_template LPAREN parms RPAREN cpp_const ARROW type lambda_body lambda_tail {
- $$ = new_node("lambda");
- Setattr($$,"name",$3);
- add_symbols($$);
- }
- | storage_class AUTO idcolon EQUAL lambda_introducer lambda_template lambda_body lambda_tail {
- $$ = new_node("lambda");
- Setattr($$,"name",$3);
- add_symbols($$);
- }
- ;
-
-lambda_introducer : LBRACKET {
- skip_balanced('[',']');
- $$ = 0;
- }
- ;
-
-lambda_template : LESSTHAN {
- skip_balanced('<','>');
- $$ = 0;
- }
- | empty { $$ = 0; }
- ;
-
-lambda_body : LBRACE {
- skip_balanced('{','}');
- $$ = 0;
- }
-
-lambda_tail : SEMI {
- $$ = 0;
- }
- | LPAREN {
- skip_balanced('(',')');
- } SEMI {
- $$ = 0;
- }
- ;
-
-/* ------------------------------------------------------------
- enum
- or
- enum class
- ------------------------------------------------------------ */
-
-c_enum_key : ENUM {
- $$ = (char *)"enum";
- }
- | ENUM CLASS {
- $$ = (char *)"enum class";
- }
- | ENUM STRUCT {
- $$ = (char *)"enum struct";
- }
- ;
-
-/* ------------------------------------------------------------
- base enum type (eg. unsigned short)
- ------------------------------------------------------------ */
-
-c_enum_inherit : COLON type_right {
- $$ = $2;
- }
- | empty { $$ = 0; }
- ;
-/* ------------------------------------------------------------
- enum [class] Name;
- enum [class] Name [: base_type];
- ------------------------------------------------------------ */
-
-c_enum_forward_decl : storage_class c_enum_key ename c_enum_inherit SEMI {
- SwigType *ty = 0;
- int scopedenum = $3 && !Equal($2, "enum");
- $$ = new_node("enumforward");
- ty = NewStringf("enum %s", $3);
- Setattr($$,"enumkey",$2);
- if (scopedenum)
- SetFlag($$, "scopedenum");
- Setattr($$,"name",$3);
- Setattr($$,"inherit",$4);
- Setattr($$,"type",ty);
- Setattr($$,"sym:weak", "1");
- add_symbols($$);
- }
- ;
-
-/* ------------------------------------------------------------
- enum [class] Name [: base_type] { ... };
- or
- enum [class] Name [: base_type] { ... } MyEnum [= ...];
- * ------------------------------------------------------------ */
-
-c_enum_decl : storage_class c_enum_key ename c_enum_inherit LBRACE enumlist RBRACE SEMI {
- SwigType *ty = 0;
- int scopedenum = $3 && !Equal($2, "enum");
- $$ = new_node("enum");
- ty = NewStringf("enum %s", $3);
- Setattr($$,"enumkey",$2);
- if (scopedenum)
- SetFlag($$, "scopedenum");
- Setattr($$,"name",$3);
- Setattr($$,"inherit",$4);
- Setattr($$,"type",ty);
- appendChild($$,$6);
- add_symbols($$); /* Add to tag space */
-
- if (scopedenum) {
- Swig_symbol_newscope();
- Swig_symbol_setscopename($3);
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- }
-
- add_symbols($6); /* Add enum values to appropriate enum or enum class scope */
-
- if (scopedenum) {
- Setattr($$,"symtab", Swig_symbol_popscope());
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- }
- }
- | storage_class c_enum_key ename c_enum_inherit LBRACE enumlist RBRACE declarator cpp_const initializer c_decl_tail {
- Node *n;
- SwigType *ty = 0;
- String *unnamed = 0;
- int unnamedinstance = 0;
- int scopedenum = $3 && !Equal($2, "enum");
-
- $$ = new_node("enum");
- Setattr($$,"enumkey",$2);
- if (scopedenum)
- SetFlag($$, "scopedenum");
- Setattr($$,"inherit",$4);
- if ($3) {
- Setattr($$,"name",$3);
- ty = NewStringf("enum %s", $3);
- } else if ($8.id) {
- unnamed = make_unnamed();
- ty = NewStringf("enum %s", unnamed);
- Setattr($$,"unnamed",unnamed);
- /* name is not set for unnamed enum instances, e.g. enum { foo } Instance; */
- if ($1 && Cmp($1,"typedef") == 0) {
- Setattr($$,"name",$8.id);
- } else {
- unnamedinstance = 1;
- }
- Setattr($$,"storage",$1);
- }
- if ($8.id && Cmp($1,"typedef") == 0) {
- Setattr($$,"tdname",$8.id);
- Setattr($$,"allows_typedef","1");
- }
- appendChild($$,$6);
- n = new_node("cdecl");
- Setattr(n,"type",ty);
- Setattr(n,"name",$8.id);
- Setattr(n,"storage",$1);
- Setattr(n,"decl",$8.type);
- Setattr(n,"parms",$8.parms);
- Setattr(n,"unnamed",unnamed);
-
- if (unnamedinstance) {
- SwigType *cty = NewString("enum ");
- Setattr($$,"type",cty);
- SetFlag($$,"unnamedinstance");
- SetFlag(n,"unnamedinstance");
- Delete(cty);
- }
- if ($11) {
- Node *p = $11;
- set_nextSibling(n,p);
- while (p) {
- SwigType *cty = Copy(ty);
- Setattr(p,"type",cty);
- Setattr(p,"unnamed",unnamed);
- Setattr(p,"storage",$1);
- Delete(cty);
- p = nextSibling(p);
- }
- } else {
- if (Len(scanner_ccode)) {
- String *code = Copy(scanner_ccode);
- Setattr(n,"code",code);
- Delete(code);
- }
- }
-
- /* Ensure that typedef enum ABC {foo} XYZ; uses XYZ for sym:name, like structs.
- * Note that class_rename/yyrename are bit of a mess so used this simple approach to change the name. */
- if ($8.id && $3 && Cmp($1,"typedef") == 0) {
- String *name = NewString($8.id);
- Setattr($$, "parser:makename", name);
- Delete(name);
- }
-
- add_symbols($$); /* Add enum to tag space */
- set_nextSibling($$,n);
- Delete(n);
-
- if (scopedenum) {
- Swig_symbol_newscope();
- Swig_symbol_setscopename($3);
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- }
-
- add_symbols($6); /* Add enum values to appropriate enum or enum class scope */
-
- if (scopedenum) {
- Setattr($$,"symtab", Swig_symbol_popscope());
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- }
-
- add_symbols(n);
- Delete(unnamed);
- }
- ;
-
-c_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end {
- /* This is a sick hack. If the ctor_end has parameters,
- and the parms parameter only has 1 parameter, this
- could be a declaration of the form:
-
- type (id)(parms)
-
- Otherwise it's an error. */
- int err = 0;
- $$ = 0;
-
- if ((ParmList_len($4) == 1) && (!Swig_scopename_check($2))) {
- SwigType *ty = Getattr($4,"type");
- String *name = Getattr($4,"name");
- err = 1;
- if (!name) {
- $$ = new_node("cdecl");
- Setattr($$,"type",$2);
- Setattr($$,"storage",$1);
- Setattr($$,"name",ty);
-
- if ($6.have_parms) {
- SwigType *decl = NewStringEmpty();
- SwigType_add_function(decl,$6.parms);
- Setattr($$,"decl",decl);
- Setattr($$,"parms",$6.parms);
- if (Len(scanner_ccode)) {
- String *code = Copy(scanner_ccode);
- Setattr($$,"code",code);
- Delete(code);
- }
- }
- if ($6.defarg) {
- Setattr($$,"value",$6.defarg);
- }
- Setattr($$,"throws",$6.throws);
- Setattr($$,"throw",$6.throwf);
- Setattr($$,"noexcept",$6.nexcept);
- Setattr($$,"final",$6.final);
- err = 0;
- }
- }
- if (err) {
- Swig_error(cparse_file,cparse_line,"Syntax error in input(2).\n");
- Exit(EXIT_FAILURE);
- }
- }
- ;
-
-/* ======================================================================
- * C++ Support
- * ====================================================================== */
-
-cpp_declaration : cpp_class_decl { $$ = $1; }
- | cpp_forward_class_decl { $$ = $1; }
- | cpp_template_decl { $$ = $1; }
- | cpp_using_decl { $$ = $1; }
- | cpp_namespace_decl { $$ = $1; }
- | cpp_catch_decl { $$ = 0; }
- ;
-
-
-/* A simple class/struct/union definition */
-
-/* Note that class_virt_specifier_opt for supporting final classes introduces one shift-reduce conflict
- with C style variable declarations, such as: struct X final; */
-
-cpp_class_decl: storage_class cpptype idcolon class_virt_specifier_opt inherit LBRACE {
- String *prefix;
- List *bases = 0;
- Node *scope = 0;
- String *code;
- $<node>$ = new_node("class");
- Setline($<node>$,cparse_start_line);
- Setattr($<node>$,"kind",$2);
- if ($5) {
- Setattr($<node>$,"baselist", Getattr($5,"public"));
- Setattr($<node>$,"protectedbaselist", Getattr($5,"protected"));
- Setattr($<node>$,"privatebaselist", Getattr($5,"private"));
- }
- Setattr($<node>$,"allows_typedef","1");
-
- /* preserve the current scope */
- Setattr($<node>$,"prev_symtab",Swig_symbol_current());
-
- /* If the class name is qualified. We need to create or lookup namespace/scope entries */
- scope = resolve_create_node_scope($3, 1);
- /* save nscope_inner to the class - it may be overwritten in nested classes*/
- Setattr($<node>$, "nested:innerscope", nscope_inner);
- Setattr($<node>$, "nested:nscope", nscope);
- Setfile(scope,cparse_file);
- Setline(scope,cparse_line);
- $3 = scope;
- Setattr($<node>$,"name",$3);
-
- if (currentOuterClass) {
- SetFlag($<node>$, "nested");
- Setattr($<node>$, "nested:outer", currentOuterClass);
- set_access_mode($<node>$);
- }
- Swig_features_get(Swig_cparse_features(), Namespaceprefix, Getattr($<node>$, "name"), 0, $<node>$);
- /* save yyrename to the class attribute, to be used later in add_symbols()*/
- Setattr($<node>$, "class_rename", make_name($<node>$, $3, 0));
- Setattr($<node>$, "Classprefix", $3);
- Classprefix = NewString($3);
- /* Deal with inheritance */
- if ($5)
- bases = Swig_make_inherit_list($3,Getattr($5,"public"),Namespaceprefix);
- prefix = SwigType_istemplate_templateprefix($3);
- if (prefix) {
- String *fbase, *tbase;
- if (Namespaceprefix) {
- fbase = NewStringf("%s::%s", Namespaceprefix,$3);
- tbase = NewStringf("%s::%s", Namespaceprefix, prefix);
- } else {
- fbase = Copy($3);
- tbase = Copy(prefix);
- }
- Swig_name_inherit(tbase,fbase);
- Delete(fbase);
- Delete(tbase);
- }
- if (strcmp($2,"class") == 0) {
- cplus_mode = CPLUS_PRIVATE;
- } else {
- cplus_mode = CPLUS_PUBLIC;
- }
- if (!cparse_cplusplus) {
- set_scope_to_global();
- }
- Swig_symbol_newscope();
- Swig_symbol_setscopename($3);
- Swig_inherit_base_symbols(bases);
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- cparse_start_line = cparse_line;
-
- /* If there are active template parameters, we need to make sure they are
- placed in the class symbol table so we can catch shadows */
-
- if (template_parameters) {
- Parm *tp = template_parameters;
- while(tp) {
- String *tpname = Copy(Getattr(tp,"name"));
- Node *tn = new_node("templateparm");
- Setattr(tn,"name",tpname);
- Swig_symbol_cadd(tpname,tn);
- tp = nextSibling(tp);
- Delete(tpname);
- }
- }
- Delete(prefix);
- inclass = 1;
- currentOuterClass = $<node>$;
- if (cparse_cplusplusout) {
- /* save the structure declaration to declare it in global scope for C++ to see */
- code = get_raw_text_balanced('{', '}');
- Setattr($<node>$, "code", code);
- Delete(code);
- }
- } cpp_members RBRACE cpp_opt_declarators {
- Node *p;
- SwigType *ty;
- Symtab *cscope;
- Node *am = 0;
- String *scpname = 0;
- (void) $<node>6;
- $$ = currentOuterClass;
- currentOuterClass = Getattr($$, "nested:outer");
- nscope_inner = Getattr($<node>$, "nested:innerscope");
- nscope = Getattr($<node>$, "nested:nscope");
- Delattr($<node>$, "nested:innerscope");
- Delattr($<node>$, "nested:nscope");
- if (nscope_inner && Strcmp(nodeType(nscope_inner), "class") == 0) { /* actual parent class for this class */
- Node* forward_declaration = Swig_symbol_clookup_no_inherit(Getattr($<node>$,"name"), Getattr(nscope_inner, "symtab"));
- if (forward_declaration) {
- Setattr($<node>$, "access", Getattr(forward_declaration, "access"));
- }
- Setattr($<node>$, "nested:outer", nscope_inner);
- SetFlag($<node>$, "nested");
- }
- if (!currentOuterClass)
- inclass = 0;
- cscope = Getattr($$, "prev_symtab");
- Delattr($$, "prev_symtab");
-
- /* Check for pure-abstract class */
- Setattr($$,"abstracts", pure_abstracts($8));
-
- /* This bit of code merges in a previously defined %extend directive (if any) */
- {
- String *clsname = Swig_symbol_qualifiedscopename(0);
- am = Getattr(Swig_extend_hash(), clsname);
- if (am) {
- Swig_extend_merge($$, am);
- Delattr(Swig_extend_hash(), clsname);
- }
- Delete(clsname);
- }
- if (!classes) classes = NewHash();
- scpname = Swig_symbol_qualifiedscopename(0);
- Setattr(classes, scpname, $$);
-
- appendChild($$, $8);
-
- if (am)
- Swig_extend_append_previous($$, am);
-
- p = $10;
- if (p && !nscope_inner) {
- if (!cparse_cplusplus && currentOuterClass)
- appendChild(currentOuterClass, p);
- else
- appendSibling($$, p);
- }
-
- if (nscope_inner) {
- ty = NewString(scpname); /* if the class is declared out of scope, let the declarator use fully qualified type*/
- } else if (cparse_cplusplus && !cparse_externc) {
- ty = NewString($3);
- } else {
- ty = NewStringf("%s %s", $2, $3);
- }
- while (p) {
- Setattr(p, "storage", $1);
- Setattr(p, "type" ,ty);
- if (!cparse_cplusplus && currentOuterClass && (!Getattr(currentOuterClass, "name"))) {
- SetFlag(p, "hasconsttype");
- SetFlag(p, "feature:immutable");
- }
- p = nextSibling(p);
- }
- if ($10 && Cmp($1,"typedef") == 0)
- add_typedef_name($$, $10, $3, cscope, scpname);
- Delete(scpname);
-
- if (cplus_mode != CPLUS_PUBLIC) {
- /* we 'open' the class at the end, to allow %template
- to add new members */
- Node *pa = new_node("access");
- Setattr(pa, "kind", "public");
- cplus_mode = CPLUS_PUBLIC;
- appendChild($$, pa);
- Delete(pa);
- }
- if (currentOuterClass)
- restore_access_mode($$);
- Setattr($$, "symtab", Swig_symbol_popscope());
- Classprefix = Getattr($<node>$, "Classprefix");
- Delattr($<node>$, "Classprefix");
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- if (cplus_mode == CPLUS_PRIVATE) {
- $$ = 0; /* skip private nested classes */
- } else if (cparse_cplusplus && currentOuterClass && ignore_nested_classes && !GetFlag($$, "feature:flatnested")) {
- $$ = nested_forward_declaration($1, $2, $3, Copy($3), $10);
- } else if (nscope_inner) {
- /* this is tricky */
- /* we add the declaration in the original namespace */
- if (Strcmp(nodeType(nscope_inner), "class") == 0 && cparse_cplusplus && ignore_nested_classes && !GetFlag($$, "feature:flatnested"))
- $$ = nested_forward_declaration($1, $2, $3, Copy($3), $10);
- appendChild(nscope_inner, $$);
- Swig_symbol_setscope(Getattr(nscope_inner, "symtab"));
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- yyrename = Copy(Getattr($<node>$, "class_rename"));
- add_symbols($$);
- Delattr($$, "class_rename");
- /* but the variable definition in the current scope */
- Swig_symbol_setscope(cscope);
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- add_symbols($10);
- if (nscope) {
- $$ = nscope; /* here we return recreated namespace tower instead of the class itself */
- if ($10) {
- appendSibling($$, $10);
- }
- } else if (!SwigType_istemplate(ty) && template_parameters == 0) { /* for template we need the class itself */
- $$ = $10;
- }
- } else {
- Delete(yyrename);
- yyrename = 0;
- if (!cparse_cplusplus && currentOuterClass) { /* nested C structs go into global scope*/
- Node *outer = currentOuterClass;
- while (Getattr(outer, "nested:outer"))
- outer = Getattr(outer, "nested:outer");
- appendSibling(outer, $$);
- Swig_symbol_setscope(cscope); /* declaration goes in the parent scope */
- add_symbols($10);
- set_scope_to_global();
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- yyrename = Copy(Getattr($<node>$, "class_rename"));
- add_symbols($$);
- if (!cparse_cplusplusout)
- Delattr($$, "nested:outer");
- Delattr($$, "class_rename");
- $$ = 0;
- } else {
- yyrename = Copy(Getattr($<node>$, "class_rename"));
- add_symbols($$);
- add_symbols($10);
- Delattr($$, "class_rename");
- }
- }
- Delete(ty);
- Swig_symbol_setscope(cscope);
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- Classprefix = currentOuterClass ? Getattr(currentOuterClass, "Classprefix") : 0;
- }
-
-/* An unnamed struct, possibly with a typedef */
-
- | storage_class cpptype inherit LBRACE {
- String *unnamed;
- String *code;
- unnamed = make_unnamed();
- $<node>$ = new_node("class");
- Setline($<node>$,cparse_start_line);
- Setattr($<node>$,"kind",$2);
- if ($3) {
- Setattr($<node>$,"baselist", Getattr($3,"public"));
- Setattr($<node>$,"protectedbaselist", Getattr($3,"protected"));
- Setattr($<node>$,"privatebaselist", Getattr($3,"private"));
- }
- Setattr($<node>$,"storage",$1);
- Setattr($<node>$,"unnamed",unnamed);
- Setattr($<node>$,"allows_typedef","1");
- if (currentOuterClass) {
- SetFlag($<node>$, "nested");
- Setattr($<node>$, "nested:outer", currentOuterClass);
- set_access_mode($<node>$);
- }
- Swig_features_get(Swig_cparse_features(), Namespaceprefix, 0, 0, $<node>$);
- /* save yyrename to the class attribute, to be used later in add_symbols()*/
- Setattr($<node>$, "class_rename", make_name($<node>$,0,0));
- if (strcmp($2,"class") == 0) {
- cplus_mode = CPLUS_PRIVATE;
- } else {
- cplus_mode = CPLUS_PUBLIC;
- }
- Swig_symbol_newscope();
- cparse_start_line = cparse_line;
- currentOuterClass = $<node>$;
- inclass = 1;
- Classprefix = 0;
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- /* save the structure declaration to make a typedef for it later*/
- code = get_raw_text_balanced('{', '}');
- Setattr($<node>$, "code", code);
- Delete(code);
- } cpp_members RBRACE cpp_opt_declarators {
- String *unnamed;
- List *bases = 0;
- String *name = 0;
- Node *n;
- Classprefix = 0;
- (void)$<node>5;
- $$ = currentOuterClass;
- currentOuterClass = Getattr($$, "nested:outer");
- if (!currentOuterClass)
- inclass = 0;
- else
- restore_access_mode($$);
- unnamed = Getattr($$,"unnamed");
- /* Check for pure-abstract class */
- Setattr($$,"abstracts", pure_abstracts($6));
- n = $8;
- if (cparse_cplusplus && currentOuterClass && ignore_nested_classes && !GetFlag($$, "feature:flatnested")) {
- String *name = n ? Copy(Getattr(n, "name")) : 0;
- $$ = nested_forward_declaration($1, $2, 0, name, n);
- Swig_symbol_popscope();
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- } else if (n) {
- appendSibling($$,n);
- /* If a proper typedef name was given, we'll use it to set the scope name */
- name = try_to_find_a_name_for_unnamed_structure($1, n);
- if (name) {
- String *scpname = 0;
- SwigType *ty;
- Setattr($$,"tdname",name);
- Setattr($$,"name",name);
- Swig_symbol_setscopename(name);
- if ($3)
- bases = Swig_make_inherit_list(name,Getattr($3,"public"),Namespaceprefix);
- Swig_inherit_base_symbols(bases);
-
- /* If a proper name was given, we use that as the typedef, not unnamed */
- Clear(unnamed);
- Append(unnamed, name);
- if (cparse_cplusplus && !cparse_externc) {
- ty = NewString(name);
- } else {
- ty = NewStringf("%s %s", $2,name);
- }
- while (n) {
- Setattr(n,"storage",$1);
- Setattr(n, "type", ty);
- if (!cparse_cplusplus && currentOuterClass && (!Getattr(currentOuterClass, "name"))) {
- SetFlag(n,"hasconsttype");
- SetFlag(n,"feature:immutable");
- }
- n = nextSibling(n);
- }
- n = $8;
-
- /* Check for previous extensions */
- {
- String *clsname = Swig_symbol_qualifiedscopename(0);
- Node *am = Getattr(Swig_extend_hash(),clsname);
- if (am) {
- /* Merge the extension into the symbol table */
- Swig_extend_merge($$,am);
- Swig_extend_append_previous($$,am);
- Delattr(Swig_extend_hash(),clsname);
- }
- Delete(clsname);
- }
- if (!classes) classes = NewHash();
- scpname = Swig_symbol_qualifiedscopename(0);
- Setattr(classes,scpname,$$);
- Delete(scpname);
- } else { /* no suitable name was found for a struct */
- Setattr($$, "nested:unnamed", Getattr(n, "name")); /* save the name of the first declarator for later use in name generation*/
- while (n) { /* attach unnamed struct to the declarators, so that they would receive proper type later*/
- Setattr(n, "nested:unnamedtype", $$);
- Setattr(n, "storage", $1);
- n = nextSibling(n);
- }
- n = $8;
- Swig_symbol_setscopename("<unnamed>");
- }
- appendChild($$,$6);
- /* Pop the scope */
- Setattr($$,"symtab",Swig_symbol_popscope());
- if (name) {
- Delete(yyrename);
- yyrename = Copy(Getattr($<node>$, "class_rename"));
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- add_symbols($$);
- add_symbols(n);
- Delattr($$, "class_rename");
- }else if (cparse_cplusplus)
- $$ = 0; /* ignore unnamed structs for C++ */
- Delete(unnamed);
- } else { /* unnamed struct w/o declarator*/
- Swig_symbol_popscope();
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- add_symbols($6);
- Delete($$);
- $$ = $6; /* pass member list to outer class/namespace (instead of self)*/
- }
- Classprefix = currentOuterClass ? Getattr(currentOuterClass, "Classprefix") : 0;
- }
- ;
-
-cpp_opt_declarators : SEMI { $$ = 0; }
- | declarator cpp_const initializer c_decl_tail {
- $$ = new_node("cdecl");
- Setattr($$,"name",$1.id);
- Setattr($$,"decl",$1.type);
- Setattr($$,"parms",$1.parms);
- set_nextSibling($$, $4);
- }
- ;
-/* ------------------------------------------------------------
- class Name;
- ------------------------------------------------------------ */
-
-cpp_forward_class_decl : storage_class cpptype idcolon SEMI {
- if ($1 && (Strcmp($1,"friend") == 0)) {
- /* Ignore */
- $$ = 0;
- } else {
- $$ = new_node("classforward");
- Setattr($$,"kind",$2);
- Setattr($$,"name",$3);
- Setattr($$,"sym:weak", "1");
- add_symbols($$);
- }
- }
- ;
-
-/* ------------------------------------------------------------
- template<...> decl
- ------------------------------------------------------------ */
-
-cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN {
- if (currentOuterClass)
- Setattr(currentOuterClass, "template_parameters", template_parameters);
- template_parameters = $3;
- parsing_template_declaration = 1;
- } cpp_template_possible {
- String *tname = 0;
- int error = 0;
-
- /* check if we get a namespace node with a class declaration, and retrieve the class */
- Symtab *cscope = Swig_symbol_current();
- Symtab *sti = 0;
- Node *ntop = $6;
- Node *ni = ntop;
- SwigType *ntype = ni ? nodeType(ni) : 0;
- while (ni && Strcmp(ntype,"namespace") == 0) {
- sti = Getattr(ni,"symtab");
- ni = firstChild(ni);
- ntype = nodeType(ni);
- }
- if (sti) {
- Swig_symbol_setscope(sti);
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- $6 = ni;
- }
-
- $$ = $6;
- if ($$) tname = Getattr($$,"name");
-
- /* Check if the class is a template specialization */
- if (($$) && (Strchr(tname,'<')) && (!is_operator(tname))) {
- /* If a specialization. Check if defined. */
- Node *tempn = 0;
- {
- String *tbase = SwigType_templateprefix(tname);
- tempn = Swig_symbol_clookup_local(tbase,0);
- if (!tempn || (Strcmp(nodeType(tempn),"template") != 0)) {
- SWIG_WARN_NODE_BEGIN(tempn);
- Swig_warning(WARN_PARSE_TEMPLATE_SP_UNDEF, Getfile($$),Getline($$),"Specialization of non-template '%s'.\n", tbase);
- SWIG_WARN_NODE_END(tempn);
- tempn = 0;
- error = 1;
- }
- Delete(tbase);
- }
- Setattr($$,"specialization","1");
- Setattr($$,"templatetype",nodeType($$));
- set_nodeType($$,"template");
- /* Template partial specialization */
- if (tempn && ($3) && ($6)) {
- List *tlist;
- String *targs = SwigType_templateargs(tname);
- tlist = SwigType_parmlist(targs);
- /* Printf(stdout,"targs = '%s' %s\n", targs, tlist); */
- if (!Getattr($$,"sym:weak")) {
- Setattr($$,"sym:typename","1");
- }
-
- if (Len(tlist) != ParmList_len(Getattr(tempn,"templateparms"))) {
- Swig_error(Getfile($$),Getline($$),"Inconsistent argument count in template partial specialization. %d %d\n", Len(tlist), ParmList_len(Getattr(tempn,"templateparms")));
-
- } else {
-
- /* This code builds the argument list for the partial template
- specialization. This is a little hairy, but the idea is as
- follows:
-
- $3 contains a list of arguments supplied for the template.
- For example template<class T>.
-
- tlist is a list of the specialization arguments--which may be
- different. For example class<int,T>.
-
- tp is a copy of the arguments in the original template definition.
-
- The patching algorithm walks through the list of supplied
- arguments ($3), finds the position in the specialization arguments
- (tlist), and then patches the name in the argument list of the
- original template.
- */
-
- {
- String *pn;
- Parm *p, *p1;
- int i, nargs;
- Parm *tp = CopyParmList(Getattr(tempn,"templateparms"));
- nargs = Len(tlist);
- p = $3;
- while (p) {
- for (i = 0; i < nargs; i++){
- pn = Getattr(p,"name");
- if (Strcmp(pn,SwigType_base(Getitem(tlist,i))) == 0) {
- int j;
- Parm *p1 = tp;
- for (j = 0; j < i; j++) {
- p1 = nextSibling(p1);
- }
- Setattr(p1,"name",pn);
- Setattr(p1,"partialarg","1");
- }
- }
- p = nextSibling(p);
- }
- p1 = tp;
- i = 0;
- while (p1) {
- if (!Getattr(p1,"partialarg")) {
- Delattr(p1,"name");
- Setattr(p1,"type", Getitem(tlist,i));
- }
- i++;
- p1 = nextSibling(p1);
- }
- Setattr($$,"templateparms",tp);
- Delete(tp);
- }
- #if 0
- /* Patch the parameter list */
- if (tempn) {
- Parm *p,*p1;
- ParmList *tp = CopyParmList(Getattr(tempn,"templateparms"));
- p = $3;
- p1 = tp;
- while (p && p1) {
- String *pn = Getattr(p,"name");
- Printf(stdout,"pn = '%s'\n", pn);
- if (pn) Setattr(p1,"name",pn);
- else Delattr(p1,"name");
- pn = Getattr(p,"type");
- if (pn) Setattr(p1,"type",pn);
- p = nextSibling(p);
- p1 = nextSibling(p1);
- }
- Setattr($$,"templateparms",tp);
- Delete(tp);
- } else {
- Setattr($$,"templateparms",$3);
- }
- #endif
- Delattr($$,"specialization");
- Setattr($$,"partialspecialization","1");
- /* Create a specialized name for matching */
- {
- Parm *p = $3;
- String *fname = NewString(Getattr($$,"name"));
- String *ffname = 0;
- ParmList *partialparms = 0;
-
- char tmp[32];
- int i, ilen;
- while (p) {
- String *n = Getattr(p,"name");
- if (!n) {
- p = nextSibling(p);
- continue;
- }
- ilen = Len(tlist);
- for (i = 0; i < ilen; i++) {
- if (Strstr(Getitem(tlist,i),n)) {
- sprintf(tmp,"$%d",i+1);
- Replaceid(fname,n,tmp);
- }
- }
- p = nextSibling(p);
- }
- /* Patch argument names with typedef */
- {
- Iterator tt;
- Parm *parm_current = 0;
- List *tparms = SwigType_parmlist(fname);
- ffname = SwigType_templateprefix(fname);
- Append(ffname,"<(");
- for (tt = First(tparms); tt.item; ) {
- SwigType *rtt = Swig_symbol_typedef_reduce(tt.item,0);
- SwigType *ttr = Swig_symbol_type_qualify(rtt,0);
-
- Parm *newp = NewParmWithoutFileLineInfo(ttr, 0);
- if (partialparms)
- set_nextSibling(parm_current, newp);
- else
- partialparms = newp;
- parm_current = newp;
-
- Append(ffname,ttr);
- tt = Next(tt);
- if (tt.item) Putc(',',ffname);
- Delete(rtt);
- Delete(ttr);
- }
- Delete(tparms);
- Append(ffname,")>");
- }
- {
- Node *new_partial = NewHash();
- String *partials = Getattr(tempn,"partials");
- if (!partials) {
- partials = NewList();
- Setattr(tempn,"partials",partials);
- Delete(partials);
- }
- /* Printf(stdout,"partial: fname = '%s', '%s'\n", fname, Swig_symbol_typedef_reduce(fname,0)); */
- Setattr(new_partial, "partialparms", partialparms);
- Setattr(new_partial, "templcsymname", ffname);
- Append(partials, new_partial);
- }
- Setattr($$,"partialargs",ffname);
- Swig_symbol_cadd(ffname,$$);
- }
- }
- Delete(tlist);
- Delete(targs);
- } else {
- /* An explicit template specialization */
- /* add default args from primary (unspecialized) template */
- String *ty = Swig_symbol_template_deftype(tname,0);
- String *fname = Swig_symbol_type_qualify(ty,0);
- Swig_symbol_cadd(fname,$$);
- Delete(ty);
- Delete(fname);
- }
- } else if ($$) {
- Setattr($$,"templatetype",nodeType($6));
- set_nodeType($$,"template");
- Setattr($$,"templateparms", $3);
- if (!Getattr($$,"sym:weak")) {
- Setattr($$,"sym:typename","1");
- }
- add_symbols($$);
- default_arguments($$);
- /* We also place a fully parameterized version in the symbol table */
- {
- Parm *p;
- String *fname = NewStringf("%s<(", Getattr($$,"name"));
- p = $3;
- while (p) {
- String *n = Getattr(p,"name");
- if (!n) n = Getattr(p,"type");
- Append(fname,n);
- p = nextSibling(p);
- if (p) Putc(',',fname);
- }
- Append(fname,")>");
- Swig_symbol_cadd(fname,$$);
- }
- }
- $$ = ntop;
- Swig_symbol_setscope(cscope);
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- if (error || (nscope_inner && Strcmp(nodeType(nscope_inner), "class") == 0)) {
- $$ = 0;
- }
- if (currentOuterClass)
- template_parameters = Getattr(currentOuterClass, "template_parameters");
- else
- template_parameters = 0;
- parsing_template_declaration = 0;
- }
-
- /* Class template explicit instantiation definition */
- | TEMPLATE cpptype idcolon {
- Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n");
- $$ = 0;
- }
-
- /* Function template explicit instantiation definition */
- | TEMPLATE cpp_alternate_rettype idcolon LPAREN parms RPAREN {
- Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n");
- $$ = 0;
- }
-
- /* Class template explicit instantiation declaration (extern template) */
- | EXTERN TEMPLATE cpptype idcolon {
- Swig_warning(WARN_PARSE_EXTERN_TEMPLATE, cparse_file, cparse_line, "Extern template ignored.\n");
- $$ = 0;
- }
-
- /* Function template explicit instantiation declaration (extern template) */
- | EXTERN TEMPLATE cpp_alternate_rettype idcolon LPAREN parms RPAREN {
- Swig_warning(WARN_PARSE_EXTERN_TEMPLATE, cparse_file, cparse_line, "Extern template ignored.\n");
- $$ = 0;
- }
- ;
-
-cpp_template_possible: c_decl {
- $$ = $1;
- }
- | cpp_class_decl {
- $$ = $1;
- }
- | cpp_constructor_decl {
- $$ = $1;
- }
- | cpp_template_decl {
- $$ = 0;
- }
- | cpp_forward_class_decl {
- $$ = $1;
- }
- | cpp_conversion_operator {
- $$ = $1;
- }
- ;
-
-template_parms : templateparameters {
- /* Rip out the parameter names */
- Parm *p = $1;
- $$ = $1;
-
- while (p) {
- String *name = Getattr(p,"name");
- if (!name) {
- /* Hmmm. Maybe it's a 'class T' parameter */
- char *type = Char(Getattr(p,"type"));
- /* Template template parameter */
- if (strncmp(type,"template<class> ",16) == 0) {
- type += 16;
- }
- if ((strncmp(type,"class ",6) == 0) || (strncmp(type,"typename ", 9) == 0)) {
- char *t = strchr(type,' ');
- Setattr(p,"name", t+1);
- } else
- /* Variadic template args */
- if ((strncmp(type,"class... ",9) == 0) || (strncmp(type,"typename... ", 12) == 0)) {
- char *t = strchr(type,' ');
- Setattr(p,"name", t+1);
- Setattr(p,"variadic", "1");
- } else {
- /*
- Swig_error(cparse_file, cparse_line, "Missing template parameter name\n");
- $$.rparms = 0;
- $$.parms = 0;
- break; */
- }
- }
- p = nextSibling(p);
- }
- }
- ;
-
-templateparameters : templateparameter templateparameterstail {
- set_nextSibling($1,$2);
- $$ = $1;
- }
- | empty { $$ = 0; }
- ;
-
-templateparameter : templcpptype def_args {
- $$ = NewParmWithoutFileLineInfo(NewString($1), 0);
- Setattr($$, "value", $2.rawval ? $2.rawval : $2.val);
- }
- | parm {
- $$ = $1;
- }
- ;
-
-templateparameterstail : COMMA templateparameter templateparameterstail {
- set_nextSibling($2,$3);
- $$ = $2;
- }
- | empty { $$ = 0; }
- ;
-
-/* Namespace support */
-
-cpp_using_decl : USING idcolon SEMI {
- String *uname = Swig_symbol_type_qualify($2,0);
- String *name = Swig_scopename_last($2);
- $$ = new_node("using");
- Setattr($$,"uname",uname);
- Setattr($$,"name", name);
- Delete(uname);
- Delete(name);
- add_symbols($$);
- }
- | USING NAMESPACE idcolon SEMI {
- Node *n = Swig_symbol_clookup($3,0);
- if (!n) {
- Swig_error(cparse_file, cparse_line, "Nothing known about namespace '%s'\n", $3);
- $$ = 0;
- } else {
-
- while (Strcmp(nodeType(n),"using") == 0) {
- n = Getattr(n,"node");
- }
- if (n) {
- if (Strcmp(nodeType(n),"namespace") == 0) {
- Symtab *current = Swig_symbol_current();
- Symtab *symtab = Getattr(n,"symtab");
- $$ = new_node("using");
- Setattr($$,"node",n);
- Setattr($$,"namespace", $3);
- if (current != symtab) {
- Swig_symbol_inherit(symtab);
- }
- } else {
- Swig_error(cparse_file, cparse_line, "'%s' is not a namespace.\n", $3);
- $$ = 0;
- }
- } else {
- $$ = 0;
- }
- }
- }
- ;
-
-cpp_namespace_decl : NAMESPACE idcolon LBRACE {
- Hash *h;
- Node *parent_ns = 0;
- List *scopes = Swig_scopename_tolist($2);
- int ilen = Len(scopes);
- int i;
-
-/*
-Printf(stdout, "==== Namespace %s creation...\n", $2);
-*/
- $<node>$ = 0;
- for (i = 0; i < ilen; i++) {
- Node *ns = new_node("namespace");
- Symtab *current_symtab = Swig_symbol_current();
- String *scopename = Getitem(scopes, i);
- Setattr(ns, "name", scopename);
- $<node>$ = ns;
- if (parent_ns)
- appendChild(parent_ns, ns);
- parent_ns = ns;
- h = Swig_symbol_clookup(scopename, 0);
- if (h && (current_symtab == Getattr(h, "sym:symtab")) && (Strcmp(nodeType(h), "namespace") == 0)) {
-/*
-Printf(stdout, " Scope %s [found C++17 style]\n", scopename);
-*/
- if (Getattr(h, "alias")) {
- h = Getattr(h, "namespace");
- Swig_warning(WARN_PARSE_NAMESPACE_ALIAS, cparse_file, cparse_line, "Namespace alias '%s' not allowed here. Assuming '%s'\n",
- scopename, Getattr(h, "name"));
- scopename = Getattr(h, "name");
- }
- Swig_symbol_setscope(Getattr(h, "symtab"));
- } else {
-/*
-Printf(stdout, " Scope %s [creating single scope C++17 style]\n", scopename);
-*/
- h = Swig_symbol_newscope();
- Swig_symbol_setscopename(scopename);
- }
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- }
- Delete(scopes);
- } interface RBRACE {
- Node *n = $<node>4;
- Node *top_ns = 0;
- do {
- Setattr(n, "symtab", Swig_symbol_popscope());
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- add_symbols(n);
- top_ns = n;
- n = parentNode(n);
- } while(n);
- appendChild($<node>4, firstChild($5));
- Delete($5);
- $$ = top_ns;
- }
- | NAMESPACE LBRACE {
- Hash *h;
- $1 = Swig_symbol_current();
- h = Swig_symbol_clookup(" ",0);
- if (h && (Strcmp(nodeType(h),"namespace") == 0)) {
- Swig_symbol_setscope(Getattr(h,"symtab"));
- } else {
- Swig_symbol_newscope();
- /* we don't use "__unnamed__", but a long 'empty' name */
- Swig_symbol_setscopename(" ");
- }
- Namespaceprefix = 0;
- } interface RBRACE {
- $$ = $4;
- set_nodeType($$,"namespace");
- Setattr($$,"unnamed","1");
- Setattr($$,"symtab", Swig_symbol_popscope());
- Swig_symbol_setscope($1);
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- add_symbols($$);
- }
- | NAMESPACE identifier EQUAL idcolon SEMI {
- /* Namespace alias */
- Node *n;
- $$ = new_node("namespace");
- Setattr($$,"name",$2);
- Setattr($$,"alias",$4);
- n = Swig_symbol_clookup($4,0);
- if (!n) {
- Swig_error(cparse_file, cparse_line, "Unknown namespace '%s'\n", $4);
- $$ = 0;
- } else {
- if (Strcmp(nodeType(n),"namespace") != 0) {
- Swig_error(cparse_file, cparse_line, "'%s' is not a namespace\n",$4);
- $$ = 0;
- } else {
- while (Getattr(n,"alias")) {
- n = Getattr(n,"namespace");
- }
- Setattr($$,"namespace",n);
- add_symbols($$);
- /* Set up a scope alias */
- Swig_symbol_alias($2,Getattr(n,"symtab"));
- }
- }
- }
- ;
-
-cpp_members : cpp_member cpp_members {
- $$ = $1;
- /* Insert cpp_member (including any siblings) to the front of the cpp_members linked list */
- if ($$) {
- Node *p = $$;
- Node *pp =0;
- while (p) {
- pp = p;
- p = nextSibling(p);
- }
- set_nextSibling(pp,$2);
- if ($2)
- set_previousSibling($2, pp);
- } else {
- $$ = $2;
- }
- }
- | EXTEND LBRACE {
- extendmode = 1;
- if (cplus_mode != CPLUS_PUBLIC) {
- Swig_error(cparse_file,cparse_line,"%%extend can only be used in a public section\n");
- }
- } cpp_members RBRACE {
- extendmode = 0;
- } cpp_members {
- $$ = new_node("extend");
- mark_nodes_as_extend($4);
- appendChild($$,$4);
- set_nextSibling($$,$7);
- }
- | include_directive { $$ = $1; }
- | empty { $$ = 0;}
- | error {
- Swig_error(cparse_file,cparse_line,"Syntax error in input(3).\n");
- Exit(EXIT_FAILURE);
- } cpp_members {
- $$ = $3;
- }
- ;
-
-/* ======================================================================
- * C++ Class members
- * ====================================================================== */
-
-/* A class member. May be data or a function. Static or virtual as well */
-
-cpp_member_no_dox : c_declaration { $$ = $1; }
- | cpp_constructor_decl {
- $$ = $1;
- if (extendmode && current_class) {
- String *symname;
- symname= make_name($$,Getattr($$,"name"), Getattr($$,"decl"));
- if (Strcmp(symname,Getattr($$,"name")) == 0) {
- /* No renaming operation. Set name to class name */
- Delete(yyrename);
- yyrename = NewString(Getattr(current_class,"sym:name"));
- } else {
- Delete(yyrename);
- yyrename = symname;
- }
- }
- add_symbols($$);
- default_arguments($$);
- }
- | cpp_destructor_decl { $$ = $1; }
- | cpp_protection_decl { $$ = $1; }
- | cpp_swig_directive { $$ = $1; }
- | cpp_conversion_operator { $$ = $1; }
- | cpp_forward_class_decl { $$ = $1; }
- | cpp_class_decl { $$ = $1; }
- | storage_class idcolon SEMI { $$ = 0; }
- | cpp_using_decl { $$ = $1; }
- | cpp_template_decl { $$ = $1; }
- | cpp_catch_decl { $$ = 0; }
- | template_directive { $$ = $1; }
- | warn_directive { $$ = $1; }
- | anonymous_bitfield { $$ = 0; }
- | fragment_directive {$$ = $1; }
- | types_directive {$$ = $1; }
- | SEMI { $$ = 0; }
-
-cpp_member : cpp_member_no_dox {
- $$ = $1;
- }
- | DOXYGENSTRING cpp_member_no_dox {
- $$ = $2;
- set_comment($2, $1);
- }
- | cpp_member_no_dox DOXYGENPOSTSTRING {
- $$ = $1;
- set_comment($1, $2);
- }
- ;
-
-/* Possibly a constructor */
-/* Note: the use of 'type' is here to resolve a shift-reduce conflict. For example:
- typedef Foo ();
- typedef Foo (*ptr)();
-*/
-
-cpp_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end {
- if (inclass || extendmode) {
- SwigType *decl = NewStringEmpty();
- $$ = new_node("constructor");
- Setattr($$,"storage",$1);
- Setattr($$,"name",$2);
- Setattr($$,"parms",$4);
- SwigType_add_function(decl,$4);
- Setattr($$,"decl",decl);
- Setattr($$,"throws",$6.throws);
- Setattr($$,"throw",$6.throwf);
- Setattr($$,"noexcept",$6.nexcept);
- Setattr($$,"final",$6.final);
- if (Len(scanner_ccode)) {
- String *code = Copy(scanner_ccode);
- Setattr($$,"code",code);
- Delete(code);
- }
- SetFlag($$,"feature:new");
- if ($6.defarg)
- Setattr($$,"value",$6.defarg);
- } else {
- $$ = 0;
- }
- }
- ;
-
-/* A destructor (hopefully) */
-
-cpp_destructor_decl : NOT idtemplate LPAREN parms RPAREN cpp_end {
- String *name = NewStringf("%s",$2);
- if (*(Char(name)) != '~') Insert(name,0,"~");
- $$ = new_node("destructor");
- Setattr($$,"name",name);
- Delete(name);
- if (Len(scanner_ccode)) {
- String *code = Copy(scanner_ccode);
- Setattr($$,"code",code);
- Delete(code);
- }
- {
- String *decl = NewStringEmpty();
- SwigType_add_function(decl,$4);
- Setattr($$,"decl",decl);
- Delete(decl);
- }
- Setattr($$,"throws",$6.throws);
- Setattr($$,"throw",$6.throwf);
- Setattr($$,"noexcept",$6.nexcept);
- Setattr($$,"final",$6.final);
- if ($6.val)
- Setattr($$,"value",$6.val);
- if ($6.qualifier)
- Swig_error(cparse_file, cparse_line, "Destructor %s %s cannot have a qualifier.\n", Swig_name_decl($$), SwigType_str($6.qualifier, 0));
- add_symbols($$);
- }
-
-/* A virtual destructor */
-
- | VIRTUAL NOT idtemplate LPAREN parms RPAREN cpp_vend {
- String *name;
- $$ = new_node("destructor");
- Setattr($$,"storage","virtual");
- name = NewStringf("%s",$3);
- if (*(Char(name)) != '~') Insert(name,0,"~");
- Setattr($$,"name",name);
- Delete(name);
- Setattr($$,"throws",$7.throws);
- Setattr($$,"throw",$7.throwf);
- Setattr($$,"noexcept",$7.nexcept);
- Setattr($$,"final",$7.final);
- if ($7.val)
- Setattr($$,"value",$7.val);
- if (Len(scanner_ccode)) {
- String *code = Copy(scanner_ccode);
- Setattr($$,"code",code);
- Delete(code);
- }
- {
- String *decl = NewStringEmpty();
- SwigType_add_function(decl,$5);
- Setattr($$,"decl",decl);
- Delete(decl);
- }
- if ($7.qualifier)
- Swig_error(cparse_file, cparse_line, "Destructor %s %s cannot have a qualifier.\n", Swig_name_decl($$), SwigType_str($7.qualifier, 0));
- add_symbols($$);
- }
- ;
-
-
-/* C++ type conversion operator */
-cpp_conversion_operator : storage_class CONVERSIONOPERATOR type pointer LPAREN parms RPAREN cpp_vend {
- $$ = new_node("cdecl");
- Setattr($$,"type",$3);
- Setattr($$,"name",$2);
- Setattr($$,"storage",$1);
-
- SwigType_add_function($4,$6);
- if ($8.qualifier) {
- SwigType_push($4,$8.qualifier);
- }
- if ($8.val) {
- Setattr($$,"value",$8.val);
- }
- Setattr($$,"refqualifier",$8.refqualifier);
- Setattr($$,"decl",$4);
- Setattr($$,"parms",$6);
- Setattr($$,"conversion_operator","1");
- add_symbols($$);
- }
- | storage_class CONVERSIONOPERATOR type AND LPAREN parms RPAREN cpp_vend {
- SwigType *decl;
- $$ = new_node("cdecl");
- Setattr($$,"type",$3);
- Setattr($$,"name",$2);
- Setattr($$,"storage",$1);
- decl = NewStringEmpty();
- SwigType_add_reference(decl);
- SwigType_add_function(decl,$6);
- if ($8.qualifier) {
- SwigType_push(decl,$8.qualifier);
- }
- if ($8.val) {
- Setattr($$,"value",$8.val);
- }
- Setattr($$,"refqualifier",$8.refqualifier);
- Setattr($$,"decl",decl);
- Setattr($$,"parms",$6);
- Setattr($$,"conversion_operator","1");
- add_symbols($$);
- }
- | storage_class CONVERSIONOPERATOR type LAND LPAREN parms RPAREN cpp_vend {
- SwigType *decl;
- $$ = new_node("cdecl");
- Setattr($$,"type",$3);
- Setattr($$,"name",$2);
- Setattr($$,"storage",$1);
- decl = NewStringEmpty();
- SwigType_add_rvalue_reference(decl);
- SwigType_add_function(decl,$6);
- if ($8.qualifier) {
- SwigType_push(decl,$8.qualifier);
- }
- if ($8.val) {
- Setattr($$,"value",$8.val);
- }
- Setattr($$,"refqualifier",$8.refqualifier);
- Setattr($$,"decl",decl);
- Setattr($$,"parms",$6);
- Setattr($$,"conversion_operator","1");
- add_symbols($$);
- }
-
- | storage_class CONVERSIONOPERATOR type pointer AND LPAREN parms RPAREN cpp_vend {
- SwigType *decl;
- $$ = new_node("cdecl");
- Setattr($$,"type",$3);
- Setattr($$,"name",$2);
- Setattr($$,"storage",$1);
- decl = NewStringEmpty();
- SwigType_add_pointer(decl);
- SwigType_add_reference(decl);
- SwigType_add_function(decl,$7);
- if ($9.qualifier) {
- SwigType_push(decl,$9.qualifier);
- }
- if ($9.val) {
- Setattr($$,"value",$9.val);
- }
- Setattr($$,"refqualifier",$9.refqualifier);
- Setattr($$,"decl",decl);
- Setattr($$,"parms",$7);
- Setattr($$,"conversion_operator","1");
- add_symbols($$);
- }
-
- | storage_class CONVERSIONOPERATOR type LPAREN parms RPAREN cpp_vend {
- String *t = NewStringEmpty();
- $$ = new_node("cdecl");
- Setattr($$,"type",$3);
- Setattr($$,"name",$2);
- Setattr($$,"storage",$1);
- SwigType_add_function(t,$5);
- if ($7.qualifier) {
- SwigType_push(t,$7.qualifier);
- }
- if ($7.val) {
- Setattr($$,"value",$7.val);
- }
- Setattr($$,"refqualifier",$7.refqualifier);
- Setattr($$,"decl",t);
- Setattr($$,"parms",$5);
- Setattr($$,"conversion_operator","1");
- add_symbols($$);
- }
- ;
-
-/* isolated catch clause. */
-
-cpp_catch_decl : CATCH LPAREN parms RPAREN LBRACE {
- skip_balanced('{','}');
- $$ = 0;
- }
- ;
-
-/* static_assert(bool, const char*); (C++11)
- * static_assert(bool); (C++17) */
-cpp_static_assert : STATIC_ASSERT LPAREN {
- skip_balanced('(',')');
- $$ = 0;
- }
- ;
-
-/* public: */
-cpp_protection_decl : PUBLIC COLON {
- $$ = new_node("access");
- Setattr($$,"kind","public");
- cplus_mode = CPLUS_PUBLIC;
- }
-
-/* private: */
- | PRIVATE COLON {
- $$ = new_node("access");
- Setattr($$,"kind","private");
- cplus_mode = CPLUS_PRIVATE;
- }
-
-/* protected: */
-
- | PROTECTED COLON {
- $$ = new_node("access");
- Setattr($$,"kind","protected");
- cplus_mode = CPLUS_PROTECTED;
- }
- ;
-/* These directives can be included inside a class definition */
-
-cpp_swig_directive: pragma_directive { $$ = $1; }
-
-/* A constant (includes #defines) inside a class */
- | constant_directive { $$ = $1; }
-
-/* This is the new style rename */
-
- | name_directive { $$ = $1; }
-
-/* rename directive */
- | rename_directive { $$ = $1; }
- | feature_directive { $$ = $1; }
- | varargs_directive { $$ = $1; }
- | insert_directive { $$ = $1; }
- | typemap_directive { $$ = $1; }
- | apply_directive { $$ = $1; }
- | clear_directive { $$ = $1; }
- | echo_directive { $$ = $1; }
- ;
-
-cpp_end : cpp_const SEMI {
- Clear(scanner_ccode);
- $$.val = 0;
- $$.qualifier = $1.qualifier;
- $$.refqualifier = $1.refqualifier;
- $$.bitfield = 0;
- $$.throws = $1.throws;
- $$.throwf = $1.throwf;
- $$.nexcept = $1.nexcept;
- $$.final = $1.final;
- }
- | cpp_const EQUAL default_delete SEMI {
- Clear(scanner_ccode);
- $$.val = $3.val;
- $$.qualifier = $1.qualifier;
- $$.refqualifier = $1.refqualifier;
- $$.bitfield = 0;
- $$.throws = $1.throws;
- $$.throwf = $1.throwf;
- $$.nexcept = $1.nexcept;
- $$.final = $1.final;
- }
- | cpp_const LBRACE {
- skip_balanced('{','}');
- $$.val = 0;
- $$.qualifier = $1.qualifier;
- $$.refqualifier = $1.refqualifier;
- $$.bitfield = 0;
- $$.throws = $1.throws;
- $$.throwf = $1.throwf;
- $$.nexcept = $1.nexcept;
- $$.final = $1.final;
- }
- ;
-
-cpp_vend : cpp_const SEMI {
- Clear(scanner_ccode);
- $$.val = 0;
- $$.qualifier = $1.qualifier;
- $$.refqualifier = $1.refqualifier;
- $$.bitfield = 0;
- $$.throws = $1.throws;
- $$.throwf = $1.throwf;
- $$.nexcept = $1.nexcept;
- $$.final = $1.final;
- }
- | cpp_const EQUAL definetype SEMI {
- Clear(scanner_ccode);
- $$.val = $3.val;
- $$.qualifier = $1.qualifier;
- $$.refqualifier = $1.refqualifier;
- $$.bitfield = 0;
- $$.throws = $1.throws;
- $$.throwf = $1.throwf;
- $$.nexcept = $1.nexcept;
- $$.final = $1.final;
- }
- | cpp_const LBRACE {
- skip_balanced('{','}');
- $$.val = 0;
- $$.qualifier = $1.qualifier;
- $$.refqualifier = $1.refqualifier;
- $$.bitfield = 0;
- $$.throws = $1.throws;
- $$.throwf = $1.throwf;
- $$.nexcept = $1.nexcept;
- $$.final = $1.final;
- }
- ;
-
-
-anonymous_bitfield : storage_class anon_bitfield_type COLON expr SEMI { };
-
-/* Equals type_right without the ENUM keyword and cpptype (templates etc.): */
-anon_bitfield_type : primitive_type { $$ = $1;
- /* Printf(stdout,"primitive = '%s'\n", $$);*/
- }
- | TYPE_BOOL { $$ = $1; }
- | TYPE_VOID { $$ = $1; }
-/*
- | TYPE_TYPEDEF template_decl { $$ = NewStringf("%s%s",$1,$2); }
-*/
- | TYPE_RAW { $$ = $1; }
-
- | idcolon {
- $$ = $1;
- }
- ;
-
-/* ======================================================================
- * PRIMITIVES
- * ====================================================================== */
-extern_string : EXTERN string {
- if (Strcmp($2,"C") == 0) {
- $$ = "externc";
- } else if (Strcmp($2,"C++") == 0) {
- $$ = "extern";
- } else {
- Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", $2);
- $$ = 0;
- }
- }
- ;
-
-storage_class : EXTERN { $$ = "extern"; }
- | extern_string { $$ = $1; }
- | extern_string THREAD_LOCAL {
- if (Equal($1, "extern")) {
- $$ = "extern thread_local";
- } else {
- $$ = "externc thread_local";
- }
- }
- | extern_string TYPEDEF { $$ = "typedef"; }
- | STATIC { $$ = "static"; }
- | TYPEDEF { $$ = "typedef"; }
- | VIRTUAL { $$ = "virtual"; }
- | FRIEND { $$ = "friend"; }
- | EXPLICIT { $$ = "explicit"; }
- | CONSTEXPR { $$ = "constexpr"; }
- | EXPLICIT CONSTEXPR { $$ = "explicit constexpr"; }
- | CONSTEXPR EXPLICIT { $$ = "explicit constexpr"; }
- | STATIC CONSTEXPR { $$ = "static constexpr"; }
- | CONSTEXPR STATIC { $$ = "static constexpr"; }
- | THREAD_LOCAL { $$ = "thread_local"; }
- | THREAD_LOCAL STATIC { $$ = "static thread_local"; }
- | STATIC THREAD_LOCAL { $$ = "static thread_local"; }
- | EXTERN THREAD_LOCAL { $$ = "extern thread_local"; }
- | THREAD_LOCAL EXTERN { $$ = "extern thread_local"; }
- | empty { $$ = 0; }
- ;
-
-/* ------------------------------------------------------------------------------
- Function parameter lists
- ------------------------------------------------------------------------------ */
-
-parms : rawparms {
- Parm *p;
- $$ = $1;
- p = $1;
- while (p) {
- Replace(Getattr(p,"type"),"typename ", "", DOH_REPLACE_ANY);
- p = nextSibling(p);
- }
- }
- ;
-
-rawparms : parm ptail {
- set_nextSibling($1,$2);
- $$ = $1;
- }
- | empty {
- $$ = 0;
- previousNode = currentNode;
- currentNode=0;
- }
- ;
-
-ptail : COMMA parm ptail {
- set_nextSibling($2,$3);
- $$ = $2;
- }
- | COMMA DOXYGENPOSTSTRING parm ptail {
- set_comment(previousNode, $2);
- set_nextSibling($3, $4);
- $$ = $3;
- }
- | empty { $$ = 0; }
- ;
-
-
-parm_no_dox : rawtype parameter_declarator {
- SwigType_push($1,$2.type);
- $$ = NewParmWithoutFileLineInfo($1,$2.id);
- previousNode = currentNode;
- currentNode = $$;
- Setfile($$,cparse_file);
- Setline($$,cparse_line);
- if ($2.defarg) {
- Setattr($$,"value",$2.defarg);
- }
- }
-
- | TEMPLATE LESSTHAN cpptype GREATERTHAN cpptype idcolon def_args {
- $$ = NewParmWithoutFileLineInfo(NewStringf("template<class> %s %s", $5,$6), 0);
- previousNode = currentNode;
- currentNode = $$;
- Setfile($$,cparse_file);
- Setline($$,cparse_line);
- if ($7.val) {
- Setattr($$,"value",$7.val);
- }
- }
- | ELLIPSIS {
- SwigType *t = NewString("v(...)");
- $$ = NewParmWithoutFileLineInfo(t, 0);
- previousNode = currentNode;
- currentNode = $$;
- Setfile($$,cparse_file);
- Setline($$,cparse_line);
- }
- ;
-
-parm : parm_no_dox {
- $$ = $1;
- }
- | DOXYGENSTRING parm_no_dox {
- $$ = $2;
- set_comment($2, $1);
- }
- | parm_no_dox DOXYGENPOSTSTRING {
- $$ = $1;
- set_comment($1, $2);
- }
- ;
-
-valparms : rawvalparms {
- Parm *p;
- $$ = $1;
- p = $1;
- while (p) {
- if (Getattr(p,"type")) {
- Replace(Getattr(p,"type"),"typename ", "", DOH_REPLACE_ANY);
- }
- p = nextSibling(p);
- }
- }
- ;
-
-rawvalparms : valparm valptail {
- set_nextSibling($1,$2);
- $$ = $1;
- }
- | empty { $$ = 0; }
- ;
-
-valptail : COMMA valparm valptail {
- set_nextSibling($2,$3);
- $$ = $2;
- }
- | empty { $$ = 0; }
- ;
-
-
-valparm : parm {
- $$ = $1;
- {
- /* We need to make a possible adjustment for integer parameters. */
- SwigType *type;
- Node *n = 0;
-
- while (!n) {
- type = Getattr($1,"type");
- n = Swig_symbol_clookup(type,0); /* See if we can find a node that matches the typename */
- if ((n) && (Strcmp(nodeType(n),"cdecl") == 0)) {
- SwigType *decl = Getattr(n,"decl");
- if (!SwigType_isfunction(decl)) {
- String *value = Getattr(n,"value");
- if (value) {
- String *v = Copy(value);
- Setattr($1,"type",v);
- Delete(v);
- n = 0;
- }
- }
- } else {
- break;
- }
- }
- }
-
- }
- | valexpr {
- $$ = NewParmWithoutFileLineInfo(0,0);
- Setfile($$,cparse_file);
- Setline($$,cparse_line);
- Setattr($$,"value",$1.val);
- }
- ;
-
-callparms : valexpr callptail {
- $$ = $1;
- Printf($$.val, "%s", $2.val);
- }
- | empty { $$.val = NewStringEmpty(); }
- ;
-
-callptail : COMMA valexpr callptail {
- $$.val = NewStringf(",%s%s", $2.val, $3.val);
- $$.type = 0;
- }
- | empty { $$.val = NewStringEmpty(); }
- ;
-
-def_args : EQUAL definetype {
- $$ = $2;
- if ($2.type == T_ERROR) {
- Swig_warning(WARN_PARSE_BAD_DEFAULT,cparse_file, cparse_line, "Can't set default argument (ignored)\n");
- $$.val = 0;
- $$.rawval = 0;
- $$.bitfield = 0;
- $$.throws = 0;
- $$.throwf = 0;
- $$.nexcept = 0;
- $$.final = 0;
- }
- }
- | EQUAL definetype LBRACKET expr RBRACKET {
- $$ = $2;
- if ($2.type == T_ERROR) {
- Swig_warning(WARN_PARSE_BAD_DEFAULT,cparse_file, cparse_line, "Can't set default argument (ignored)\n");
- $$ = $2;
- $$.val = 0;
- $$.rawval = 0;
- $$.bitfield = 0;
- $$.throws = 0;
- $$.throwf = 0;
- $$.nexcept = 0;
- $$.final = 0;
- } else {
- $$.val = NewStringf("%s[%s]",$2.val,$4.val);
- }
- }
- | EQUAL LBRACE {
- skip_balanced('{','}');
- $$.val = NewString(scanner_ccode);
- $$.rawval = 0;
- $$.type = T_INT;
- $$.bitfield = 0;
- $$.throws = 0;
- $$.throwf = 0;
- $$.nexcept = 0;
- $$.final = 0;
- }
- | COLON expr {
- $$.val = 0;
- $$.rawval = 0;
- $$.type = 0;
- $$.bitfield = $2.val;
- $$.throws = 0;
- $$.throwf = 0;
- $$.nexcept = 0;
- $$.final = 0;
- }
- | empty {
- $$.val = 0;
- $$.rawval = 0;
- $$.type = T_INT;
- $$.bitfield = 0;
- $$.throws = 0;
- $$.throwf = 0;
- $$.nexcept = 0;
- $$.final = 0;
- }
- ;
-
-parameter_declarator : declarator def_args {
- $$ = $1;
- $$.defarg = $2.rawval ? $2.rawval : $2.val;
- }
- | abstract_declarator def_args {
- $$ = $1;
- $$.defarg = $2.rawval ? $2.rawval : $2.val;
- }
- | def_args {
- $$.type = 0;
- $$.id = 0;
- $$.defarg = $1.rawval ? $1.rawval : $1.val;
- }
- /* Member function pointers with qualifiers. eg.
- int f(short (Funcs::*parm)(bool) const); */
- | direct_declarator LPAREN parms RPAREN cv_ref_qualifier {
- SwigType *t;
- $$ = $1;
- t = NewStringEmpty();
- SwigType_add_function(t,$3);
- if ($5.qualifier)
- SwigType_push(t, $5.qualifier);
- if (!$$.have_parms) {
- $$.parms = $3;
- $$.have_parms = 1;
- }
- if (!$$.type) {
- $$.type = t;
- } else {
- SwigType_push(t, $$.type);
- Delete($$.type);
- $$.type = t;
- }
- $$.defarg = 0;
- }
- ;
-
-plain_declarator : declarator {
- $$ = $1;
- if (SwigType_isfunction($1.type)) {
- Delete(SwigType_pop_function($1.type));
- } else if (SwigType_isarray($1.type)) {
- SwigType *ta = SwigType_pop_arrays($1.type);
- if (SwigType_isfunction($1.type)) {
- Delete(SwigType_pop_function($1.type));
- } else {
- $$.parms = 0;
- }
- SwigType_push($1.type,ta);
- Delete(ta);
- } else {
- $$.parms = 0;
- }
- }
- | abstract_declarator {
- $$ = $1;
- if (SwigType_isfunction($1.type)) {
- Delete(SwigType_pop_function($1.type));
- } else if (SwigType_isarray($1.type)) {
- SwigType *ta = SwigType_pop_arrays($1.type);
- if (SwigType_isfunction($1.type)) {
- Delete(SwigType_pop_function($1.type));
- } else {
- $$.parms = 0;
- }
- SwigType_push($1.type,ta);
- Delete(ta);
- } else {
- $$.parms = 0;
- }
- }
- /* Member function pointers with qualifiers. eg.
- int f(short (Funcs::*parm)(bool) const) */
- | direct_declarator LPAREN parms RPAREN cv_ref_qualifier {
- SwigType *t;
- $$ = $1;
- t = NewStringEmpty();
- SwigType_add_function(t, $3);
- if ($5.qualifier)
- SwigType_push(t, $5.qualifier);
- if (!$$.have_parms) {
- $$.parms = $3;
- $$.have_parms = 1;
- }
- if (!$$.type) {
- $$.type = t;
- } else {
- SwigType_push(t, $$.type);
- Delete($$.type);
- $$.type = t;
- }
- }
- | empty {
- $$.type = 0;
- $$.id = 0;
- $$.parms = 0;
- }
- ;
-
-declarator : pointer notso_direct_declarator {
- $$ = $2;
- if ($$.type) {
- SwigType_push($1,$$.type);
- Delete($$.type);
- }
- $$.type = $1;
- }
- | pointer AND notso_direct_declarator {
- $$ = $3;
- SwigType_add_reference($1);
- if ($$.type) {
- SwigType_push($1,$$.type);
- Delete($$.type);
- }
- $$.type = $1;
- }
- | pointer LAND notso_direct_declarator {
- $$ = $3;
- SwigType_add_rvalue_reference($1);
- if ($$.type) {
- SwigType_push($1,$$.type);
- Delete($$.type);
- }
- $$.type = $1;
- }
- | direct_declarator {
- $$ = $1;
- if (!$$.type) $$.type = NewStringEmpty();
- }
- | AND notso_direct_declarator {
- $$ = $2;
- $$.type = NewStringEmpty();
- SwigType_add_reference($$.type);
- if ($2.type) {
- SwigType_push($$.type,$2.type);
- Delete($2.type);
- }
- }
- | LAND notso_direct_declarator {
- /* Introduced in C++11, move operator && */
- /* Adds one S/R conflict */
- $$ = $2;
- $$.type = NewStringEmpty();
- SwigType_add_rvalue_reference($$.type);
- if ($2.type) {
- SwigType_push($$.type,$2.type);
- Delete($2.type);
- }
- }
- | idcolon DSTAR notso_direct_declarator {
- SwigType *t = NewStringEmpty();
-
- $$ = $3;
- SwigType_add_memberpointer(t,$1);
- if ($$.type) {
- SwigType_push(t,$$.type);
- Delete($$.type);
- }
- $$.type = t;
- }
- | pointer idcolon DSTAR notso_direct_declarator {
- SwigType *t = NewStringEmpty();
- $$ = $4;
- SwigType_add_memberpointer(t,$2);
- SwigType_push($1,t);
- if ($$.type) {
- SwigType_push($1,$$.type);
- Delete($$.type);
- }
- $$.type = $1;
- Delete(t);
- }
- | pointer idcolon DSTAR AND notso_direct_declarator {
- $$ = $5;
- SwigType_add_memberpointer($1,$2);
- SwigType_add_reference($1);
- if ($$.type) {
- SwigType_push($1,$$.type);
- Delete($$.type);
- }
- $$.type = $1;
- }
- | idcolon DSTAR AND notso_direct_declarator {
- SwigType *t = NewStringEmpty();
- $$ = $4;
- SwigType_add_memberpointer(t,$1);
- SwigType_add_reference(t);
- if ($$.type) {
- SwigType_push(t,$$.type);
- Delete($$.type);
- }
- $$.type = t;
- }
-
- /* Variadic versions eg. MyClasses&... myIds */
-
- | pointer ELLIPSIS notso_direct_declarator {
- $$ = $3;
- if ($$.type) {
- SwigType_push($1,$$.type);
- Delete($$.type);
- }
- $$.type = $1;
- }
- | pointer AND ELLIPSIS notso_direct_declarator {
- $$ = $4;
- SwigType_add_reference($1);
- if ($$.type) {
- SwigType_push($1,$$.type);
- Delete($$.type);
- }
- $$.type = $1;
- }
- | pointer LAND ELLIPSIS notso_direct_declarator {
- $$ = $4;
- SwigType_add_rvalue_reference($1);
- if ($$.type) {
- SwigType_push($1,$$.type);
- Delete($$.type);
- }
- $$.type = $1;
- }
- | ELLIPSIS direct_declarator {
- $$ = $2;
- if (!$$.type) $$.type = NewStringEmpty();
- }
- | AND ELLIPSIS notso_direct_declarator {
- $$ = $3;
- $$.type = NewStringEmpty();
- SwigType_add_reference($$.type);
- if ($3.type) {
- SwigType_push($$.type,$3.type);
- Delete($3.type);
- }
- }
- | LAND ELLIPSIS notso_direct_declarator {
- /* Introduced in C++11, move operator && */
- /* Adds one S/R conflict */
- $$ = $3;
- $$.type = NewStringEmpty();
- SwigType_add_rvalue_reference($$.type);
- if ($3.type) {
- SwigType_push($$.type,$3.type);
- Delete($3.type);
- }
- }
- | idcolon DSTAR ELLIPSIS notso_direct_declarator {
- SwigType *t = NewStringEmpty();
-
- $$ = $4;
- SwigType_add_memberpointer(t,$1);
- if ($$.type) {
- SwigType_push(t,$$.type);
- Delete($$.type);
- }
- $$.type = t;
- }
- | pointer idcolon DSTAR ELLIPSIS notso_direct_declarator {
- SwigType *t = NewStringEmpty();
- $$ = $5;
- SwigType_add_memberpointer(t,$2);
- SwigType_push($1,t);
- if ($$.type) {
- SwigType_push($1,$$.type);
- Delete($$.type);
- }
- $$.type = $1;
- Delete(t);
- }
- | pointer idcolon DSTAR AND ELLIPSIS notso_direct_declarator {
- $$ = $6;
- SwigType_add_memberpointer($1,$2);
- SwigType_add_reference($1);
- if ($$.type) {
- SwigType_push($1,$$.type);
- Delete($$.type);
- }
- $$.type = $1;
- }
- | pointer idcolon DSTAR LAND ELLIPSIS notso_direct_declarator {
- $$ = $6;
- SwigType_add_memberpointer($1,$2);
- SwigType_add_rvalue_reference($1);
- if ($$.type) {
- SwigType_push($1,$$.type);
- Delete($$.type);
- }
- $$.type = $1;
- }
- | idcolon DSTAR AND ELLIPSIS notso_direct_declarator {
- SwigType *t = NewStringEmpty();
- $$ = $5;
- SwigType_add_memberpointer(t,$1);
- SwigType_add_reference(t);
- if ($$.type) {
- SwigType_push(t,$$.type);
- Delete($$.type);
- }
- $$.type = t;
- }
- | idcolon DSTAR LAND ELLIPSIS notso_direct_declarator {
- SwigType *t = NewStringEmpty();
- $$ = $5;
- SwigType_add_memberpointer(t,$1);
- SwigType_add_rvalue_reference(t);
- if ($$.type) {
- SwigType_push(t,$$.type);
- Delete($$.type);
- }
- $$.type = t;
- }
- ;
-
-notso_direct_declarator : idcolon {
- /* Note: This is non-standard C. Template declarator is allowed to follow an identifier */
- $$.id = Char($1);
- $$.type = 0;
- $$.parms = 0;
- $$.have_parms = 0;
- }
- | NOT idcolon {
- $$.id = Char(NewStringf("~%s",$2));
- $$.type = 0;
- $$.parms = 0;
- $$.have_parms = 0;
- }
-
-/* This generates a shift-reduce conflict with constructors */
- | LPAREN idcolon RPAREN {
- $$.id = Char($2);
- $$.type = 0;
- $$.parms = 0;
- $$.have_parms = 0;
- }
-
-/*
- | LPAREN AND idcolon RPAREN {
- $$.id = Char($3);
- $$.type = 0;
- $$.parms = 0;
- $$.have_parms = 0;
- }
-*/
-/* Technically, this should be LPAREN declarator RPAREN, but we get reduce/reduce conflicts */
- | LPAREN pointer notso_direct_declarator RPAREN {
- $$ = $3;
- if ($$.type) {
- SwigType_push($2,$$.type);
- Delete($$.type);
- }
- $$.type = $2;
- }
- | LPAREN idcolon DSTAR notso_direct_declarator RPAREN {
- SwigType *t;
- $$ = $4;
- t = NewStringEmpty();
- SwigType_add_memberpointer(t,$2);
- if ($$.type) {
- SwigType_push(t,$$.type);
- Delete($$.type);
- }
- $$.type = t;
- }
- | notso_direct_declarator LBRACKET RBRACKET {
- SwigType *t;
- $$ = $1;
- t = NewStringEmpty();
- SwigType_add_array(t,"");
- if ($$.type) {
- SwigType_push(t,$$.type);
- Delete($$.type);
- }
- $$.type = t;
- }
- | notso_direct_declarator LBRACKET expr RBRACKET {
- SwigType *t;
- $$ = $1;
- t = NewStringEmpty();
- SwigType_add_array(t,$3.val);
- if ($$.type) {
- SwigType_push(t,$$.type);
- Delete($$.type);
- }
- $$.type = t;
- }
- | notso_direct_declarator LPAREN parms RPAREN {
- SwigType *t;
- $$ = $1;
- t = NewStringEmpty();
- SwigType_add_function(t,$3);
- if (!$$.have_parms) {
- $$.parms = $3;
- $$.have_parms = 1;
- }
- if (!$$.type) {
- $$.type = t;
- } else {
- SwigType_push(t, $$.type);
- Delete($$.type);
- $$.type = t;
- }
- }
- ;
-
-direct_declarator : idcolon {
- /* Note: This is non-standard C. Template declarator is allowed to follow an identifier */
- $$.id = Char($1);
- $$.type = 0;
- $$.parms = 0;
- $$.have_parms = 0;
- }
-
- | NOT idcolon {
- $$.id = Char(NewStringf("~%s",$2));
- $$.type = 0;
- $$.parms = 0;
- $$.have_parms = 0;
- }
-
-/* This generate a shift-reduce conflict with constructors */
-/*
- | LPAREN idcolon RPAREN {
- $$.id = Char($2);
- $$.type = 0;
- $$.parms = 0;
- $$.have_parms = 0;
- }
-*/
-/* Technically, this should be LPAREN declarator RPAREN, but we get reduce/reduce conflicts */
- | LPAREN pointer direct_declarator RPAREN {
- $$ = $3;
- if ($$.type) {
- SwigType_push($2,$$.type);
- Delete($$.type);
- }
- $$.type = $2;
- }
- | LPAREN AND direct_declarator RPAREN {
- $$ = $3;
- if (!$$.type) {
- $$.type = NewStringEmpty();
- }
- SwigType_add_reference($$.type);
- }
- | LPAREN LAND direct_declarator RPAREN {
- $$ = $3;
- if (!$$.type) {
- $$.type = NewStringEmpty();
- }
- SwigType_add_rvalue_reference($$.type);
- }
- | LPAREN idcolon DSTAR declarator RPAREN {
- SwigType *t;
- $$ = $4;
- t = NewStringEmpty();
- SwigType_add_memberpointer(t,$2);
- if ($$.type) {
- SwigType_push(t,$$.type);
- Delete($$.type);
- }
- $$.type = t;
- }
- | LPAREN idcolon DSTAR type_qualifier declarator RPAREN {
- SwigType *t;
- $$ = $5;
- t = NewStringEmpty();
- SwigType_add_memberpointer(t, $2);
- SwigType_push(t, $4);
- if ($$.type) {
- SwigType_push(t, $$.type);
- Delete($$.type);
- }
- $$.type = t;
- }
- | LPAREN idcolon DSTAR abstract_declarator RPAREN {
- SwigType *t;
- $$ = $4;
- t = NewStringEmpty();
- SwigType_add_memberpointer(t, $2);
- if ($$.type) {
- SwigType_push(t, $$.type);
- Delete($$.type);
- }
- $$.type = t;
- }
- | LPAREN idcolon DSTAR type_qualifier abstract_declarator RPAREN {
- SwigType *t;
- $$ = $5;
- t = NewStringEmpty();
- SwigType_add_memberpointer(t, $2);
- SwigType_push(t, $4);
- if ($$.type) {
- SwigType_push(t, $$.type);
- Delete($$.type);
- }
- $$.type = t;
- }
- | direct_declarator LBRACKET RBRACKET {
- SwigType *t;
- $$ = $1;
- t = NewStringEmpty();
- SwigType_add_array(t,"");
- if ($$.type) {
- SwigType_push(t,$$.type);
- Delete($$.type);
- }
- $$.type = t;
- }
- | direct_declarator LBRACKET expr RBRACKET {
- SwigType *t;
- $$ = $1;
- t = NewStringEmpty();
- SwigType_add_array(t,$3.val);
- if ($$.type) {
- SwigType_push(t,$$.type);
- Delete($$.type);
- }
- $$.type = t;
- }
- | direct_declarator LPAREN parms RPAREN {
- SwigType *t;
- $$ = $1;
- t = NewStringEmpty();
- SwigType_add_function(t,$3);
- if (!$$.have_parms) {
- $$.parms = $3;
- $$.have_parms = 1;
- }
- if (!$$.type) {
- $$.type = t;
- } else {
- SwigType_push(t, $$.type);
- Delete($$.type);
- $$.type = t;
- }
- }
- /* User-defined string literals. eg.
- int operator"" _mySuffix(const char* val, int length) {...} */
- /* This produces one S/R conflict. */
- | OPERATOR ID LPAREN parms RPAREN {
- SwigType *t;
- Append($1, " "); /* intervening space is mandatory */
- Append($1, Char($2));
- $$.id = Char($1);
- t = NewStringEmpty();
- SwigType_add_function(t,$4);
- if (!$$.have_parms) {
- $$.parms = $4;
- $$.have_parms = 1;
- }
- if (!$$.type) {
- $$.type = t;
- } else {
- SwigType_push(t, $$.type);
- Delete($$.type);
- $$.type = t;
- }
- }
- ;
-
-abstract_declarator : pointer {
- $$.type = $1;
- $$.id = 0;
- $$.parms = 0;
- $$.have_parms = 0;
- }
- | pointer direct_abstract_declarator {
- $$ = $2;
- SwigType_push($1,$2.type);
- $$.type = $1;
- Delete($2.type);
- }
- | pointer AND {
- $$.type = $1;
- SwigType_add_reference($$.type);
- $$.id = 0;
- $$.parms = 0;
- $$.have_parms = 0;
- }
- | pointer LAND {
- $$.type = $1;
- SwigType_add_rvalue_reference($$.type);
- $$.id = 0;
- $$.parms = 0;
- $$.have_parms = 0;
- }
- | pointer AND direct_abstract_declarator {
- $$ = $3;
- SwigType_add_reference($1);
- if ($$.type) {
- SwigType_push($1,$$.type);
- Delete($$.type);
- }
- $$.type = $1;
- }
- | pointer LAND direct_abstract_declarator {
- $$ = $3;
- SwigType_add_rvalue_reference($1);
- if ($$.type) {
- SwigType_push($1,$$.type);
- Delete($$.type);
- }
- $$.type = $1;
- }
- | direct_abstract_declarator {
- $$ = $1;
- }
- | AND direct_abstract_declarator {
- $$ = $2;
- $$.type = NewStringEmpty();
- SwigType_add_reference($$.type);
- if ($2.type) {
- SwigType_push($$.type,$2.type);
- Delete($2.type);
- }
- }
- | LAND direct_abstract_declarator {
- $$ = $2;
- $$.type = NewStringEmpty();
- SwigType_add_rvalue_reference($$.type);
- if ($2.type) {
- SwigType_push($$.type,$2.type);
- Delete($2.type);
- }
- }
- | AND {
- $$.id = 0;
- $$.parms = 0;
- $$.have_parms = 0;
- $$.type = NewStringEmpty();
- SwigType_add_reference($$.type);
- }
- | LAND {
- $$.id = 0;
- $$.parms = 0;
- $$.have_parms = 0;
- $$.type = NewStringEmpty();
- SwigType_add_rvalue_reference($$.type);
- }
- | idcolon DSTAR {
- $$.type = NewStringEmpty();
- SwigType_add_memberpointer($$.type,$1);
- $$.id = 0;
- $$.parms = 0;
- $$.have_parms = 0;
- }
- | idcolon DSTAR type_qualifier {
- $$.type = NewStringEmpty();
- SwigType_add_memberpointer($$.type, $1);
- SwigType_push($$.type, $3);
- $$.id = 0;
- $$.parms = 0;
- $$.have_parms = 0;
- }
- | pointer idcolon DSTAR {
- SwigType *t = NewStringEmpty();
- $$.type = $1;
- $$.id = 0;
- $$.parms = 0;
- $$.have_parms = 0;
- SwigType_add_memberpointer(t,$2);
- SwigType_push($$.type,t);
- Delete(t);
- }
- | pointer idcolon DSTAR direct_abstract_declarator {
- $$ = $4;
- SwigType_add_memberpointer($1,$2);
- if ($$.type) {
- SwigType_push($1,$$.type);
- Delete($$.type);
- }
- $$.type = $1;
- }
- ;
-
-direct_abstract_declarator : direct_abstract_declarator LBRACKET RBRACKET {
- SwigType *t;
- $$ = $1;
- t = NewStringEmpty();
- SwigType_add_array(t,"");
- if ($$.type) {
- SwigType_push(t,$$.type);
- Delete($$.type);
- }
- $$.type = t;
- }
- | direct_abstract_declarator LBRACKET expr RBRACKET {
- SwigType *t;
- $$ = $1;
- t = NewStringEmpty();
- SwigType_add_array(t,$3.val);
- if ($$.type) {
- SwigType_push(t,$$.type);
- Delete($$.type);
- }
- $$.type = t;
- }
- | LBRACKET RBRACKET {
- $$.type = NewStringEmpty();
- $$.id = 0;
- $$.parms = 0;
- $$.have_parms = 0;
- SwigType_add_array($$.type,"");
- }
- | LBRACKET expr RBRACKET {
- $$.type = NewStringEmpty();
- $$.id = 0;
- $$.parms = 0;
- $$.have_parms = 0;
- SwigType_add_array($$.type,$2.val);
- }
- | LPAREN abstract_declarator RPAREN {
- $$ = $2;
- }
- | direct_abstract_declarator LPAREN parms RPAREN {
- SwigType *t;
- $$ = $1;
- t = NewStringEmpty();
- SwigType_add_function(t,$3);
- if (!$$.type) {
- $$.type = t;
- } else {
- SwigType_push(t,$$.type);
- Delete($$.type);
- $$.type = t;
- }
- if (!$$.have_parms) {
- $$.parms = $3;
- $$.have_parms = 1;
- }
- }
- | direct_abstract_declarator LPAREN parms RPAREN cv_ref_qualifier {
- SwigType *t;
- $$ = $1;
- t = NewStringEmpty();
- SwigType_add_function(t,$3);
- SwigType_push(t, $5.qualifier);
- if (!$$.type) {
- $$.type = t;
- } else {
- SwigType_push(t,$$.type);
- Delete($$.type);
- $$.type = t;
- }
- if (!$$.have_parms) {
- $$.parms = $3;
- $$.have_parms = 1;
- }
- }
- | LPAREN parms RPAREN {
- $$.type = NewStringEmpty();
- SwigType_add_function($$.type,$2);
- $$.parms = $2;
- $$.have_parms = 1;
- $$.id = 0;
- }
- ;
-
-
-pointer : STAR type_qualifier pointer {
- $$ = NewStringEmpty();
- SwigType_add_pointer($$);
- SwigType_push($$,$2);
- SwigType_push($$,$3);
- Delete($3);
- }
- | STAR pointer {
- $$ = NewStringEmpty();
- SwigType_add_pointer($$);
- SwigType_push($$,$2);
- Delete($2);
- }
- | STAR type_qualifier {
- $$ = NewStringEmpty();
- SwigType_add_pointer($$);
- SwigType_push($$,$2);
- }
- | STAR {
- $$ = NewStringEmpty();
- SwigType_add_pointer($$);
- }
- ;
-
-/* cv-qualifier plus C++11 ref-qualifier for non-static member functions */
-cv_ref_qualifier : type_qualifier {
- $$.qualifier = $1;
- $$.refqualifier = 0;
- }
- | type_qualifier ref_qualifier {
- $$.qualifier = $1;
- $$.refqualifier = $2;
- SwigType_push($$.qualifier, $2);
- }
- | ref_qualifier {
- $$.qualifier = NewStringEmpty();
- $$.refqualifier = $1;
- SwigType_push($$.qualifier, $1);
- }
- ;
-
-ref_qualifier : AND {
- $$ = NewStringEmpty();
- SwigType_add_reference($$);
- }
- | LAND {
- $$ = NewStringEmpty();
- SwigType_add_rvalue_reference($$);
- }
- ;
-
-type_qualifier : type_qualifier_raw {
- $$ = NewStringEmpty();
- if ($1) SwigType_add_qualifier($$,$1);
- }
- | type_qualifier_raw type_qualifier {
- $$ = $2;
- if ($1) SwigType_add_qualifier($$,$1);
- }
- ;
-
-type_qualifier_raw : CONST_QUAL { $$ = "const"; }
- | VOLATILE { $$ = "volatile"; }
- | REGISTER { $$ = 0; }
- ;
-
-/* Data type must be a built in type or an identifier for user-defined types
- This type can be preceded by a modifier. */
-
-type : rawtype {
- $$ = $1;
- Replace($$,"typename ","", DOH_REPLACE_ANY);
- }
- ;
-
-rawtype : type_qualifier type_right {
- $$ = $2;
- SwigType_push($$,$1);
- }
- | type_right { $$ = $1; }
- | type_right type_qualifier {
- $$ = $1;
- SwigType_push($$,$2);
- }
- | type_qualifier type_right type_qualifier {
- $$ = $2;
- SwigType_push($$,$3);
- SwigType_push($$,$1);
- }
- ;
-
-type_right : primitive_type { $$ = $1;
- /* Printf(stdout,"primitive = '%s'\n", $$);*/
- }
- | TYPE_BOOL { $$ = $1; }
- | TYPE_VOID { $$ = $1; }
-/*
- | TYPE_TYPEDEF template_decl { $$ = NewStringf("%s%s",$1,$2); }
-*/
- | c_enum_key idcolon { $$ = NewStringf("enum %s", $2); }
- | TYPE_RAW { $$ = $1; }
-
- | idcolon {
- $$ = $1;
- }
- | cpptype idcolon {
- $$ = NewStringf("%s %s", $1, $2);
- }
- | decltype {
- $$ = $1;
- }
- ;
-
-decltype : DECLTYPE LPAREN idcolon RPAREN {
- Node *n = Swig_symbol_clookup($3,0);
- if (!n) {
- Swig_error(cparse_file, cparse_line, "Identifier %s not defined.\n", $3);
- $$ = $3;
- } else {
- $$ = Getattr(n, "type");
- }
- }
- ;
-
-primitive_type : primitive_type_list {
- if (!$1.type) $1.type = NewString("int");
- if ($1.us) {
- $$ = NewStringf("%s %s", $1.us, $1.type);
- Delete($1.us);
- Delete($1.type);
- } else {
- $$ = $1.type;
- }
- if (Cmp($$,"signed int") == 0) {
- Delete($$);
- $$ = NewString("int");
- } else if (Cmp($$,"signed long") == 0) {
- Delete($$);
- $$ = NewString("long");
- } else if (Cmp($$,"signed short") == 0) {
- Delete($$);
- $$ = NewString("short");
- } else if (Cmp($$,"signed long long") == 0) {
- Delete($$);
- $$ = NewString("long long");
- }
- }
- ;
-
-primitive_type_list : type_specifier {
- $$ = $1;
- }
- | type_specifier primitive_type_list {
- if ($1.us && $2.us) {
- Swig_error(cparse_file, cparse_line, "Extra %s specifier.\n", $2.us);
- }
- $$ = $2;
- if ($1.us) $$.us = $1.us;
- if ($1.type) {
- if (!$2.type) $$.type = $1.type;
- else {
- int err = 0;
- if ((Cmp($1.type,"long") == 0)) {
- if ((Cmp($2.type,"long") == 0) || (Strncmp($2.type,"double",6) == 0)) {
- $$.type = NewStringf("long %s", $2.type);
- } else if (Cmp($2.type,"int") == 0) {
- $$.type = $1.type;
- } else {
- err = 1;
- }
- } else if ((Cmp($1.type,"short")) == 0) {
- if (Cmp($2.type,"int") == 0) {
- $$.type = $1.type;
- } else {
- err = 1;
- }
- } else if (Cmp($1.type,"int") == 0) {
- $$.type = $2.type;
- } else if (Cmp($1.type,"double") == 0) {
- if (Cmp($2.type,"long") == 0) {
- $$.type = NewString("long double");
- } else if (Cmp($2.type,"_Complex") == 0) {
- $$.type = NewString("double _Complex");
- } else {
- err = 1;
- }
- } else if (Cmp($1.type,"float") == 0) {
- if (Cmp($2.type,"_Complex") == 0) {
- $$.type = NewString("float _Complex");
- } else {
- err = 1;
- }
- } else if (Cmp($1.type,"_Complex") == 0) {
- $$.type = NewStringf("%s _Complex", $2.type);
- } else {
- err = 1;
- }
- if (err) {
- Swig_error(cparse_file, cparse_line, "Extra %s specifier.\n", $1.type);
- }
- }
- }
- }
- ;
-
-
-type_specifier : TYPE_INT {
- $$.type = NewString("int");
- $$.us = 0;
- }
- | TYPE_SHORT {
- $$.type = NewString("short");
- $$.us = 0;
- }
- | TYPE_LONG {
- $$.type = NewString("long");
- $$.us = 0;
- }
- | TYPE_CHAR {
- $$.type = NewString("char");
- $$.us = 0;
- }
- | TYPE_WCHAR {
- $$.type = NewString("wchar_t");
- $$.us = 0;
- }
- | TYPE_FLOAT {
- $$.type = NewString("float");
- $$.us = 0;
- }
- | TYPE_DOUBLE {
- $$.type = NewString("double");
- $$.us = 0;
- }
- | TYPE_SIGNED {
- $$.us = NewString("signed");
- $$.type = 0;
- }
- | TYPE_UNSIGNED {
- $$.us = NewString("unsigned");
- $$.type = 0;
- }
- | TYPE_COMPLEX {
- $$.type = NewString("_Complex");
- $$.us = 0;
- }
- | TYPE_NON_ISO_INT8 {
- $$.type = NewString("__int8");
- $$.us = 0;
- }
- | TYPE_NON_ISO_INT16 {
- $$.type = NewString("__int16");
- $$.us = 0;
- }
- | TYPE_NON_ISO_INT32 {
- $$.type = NewString("__int32");
- $$.us = 0;
- }
- | TYPE_NON_ISO_INT64 {
- $$.type = NewString("__int64");
- $$.us = 0;
- }
- ;
-
-definetype : { /* scanner_check_typedef(); */ } expr {
- $$ = $2;
- if ($$.type == T_STRING) {
- $$.rawval = NewStringf("\"%(escape)s\"",$$.val);
- } else if ($$.type != T_CHAR && $$.type != T_WSTRING && $$.type != T_WCHAR) {
- $$.rawval = NewStringf("%s", $$.val);
- }
- $$.qualifier = 0;
- $$.refqualifier = 0;
- $$.bitfield = 0;
- $$.throws = 0;
- $$.throwf = 0;
- $$.nexcept = 0;
- $$.final = 0;
- scanner_ignore_typedef();
- }
- | default_delete {
- $$ = $1;
- }
- ;
-
-default_delete : deleted_definition {
- $$ = $1;
- }
- | explicit_default {
- $$ = $1;
- }
- ;
-
-/* For C++ deleted definition '= delete' */
-deleted_definition : DELETE_KW {
- $$.val = NewString("delete");
- $$.rawval = 0;
- $$.type = T_STRING;
- $$.qualifier = 0;
- $$.refqualifier = 0;
- $$.bitfield = 0;
- $$.throws = 0;
- $$.throwf = 0;
- $$.nexcept = 0;
- $$.final = 0;
- }
- ;
-
-/* For C++ explicitly defaulted functions '= default' */
-explicit_default : DEFAULT {
- $$.val = NewString("default");
- $$.rawval = 0;
- $$.type = T_STRING;
- $$.qualifier = 0;
- $$.refqualifier = 0;
- $$.bitfield = 0;
- $$.throws = 0;
- $$.throwf = 0;
- $$.nexcept = 0;
- $$.final = 0;
- }
- ;
-
-/* Some stuff for handling enums */
-
-ename : identifier { $$ = $1; }
- | empty { $$ = (char *) 0;}
- ;
-
-constant_directives : constant_directive
- | constant_directive constant_directives
- ;
-
-optional_ignored_defines
- : constant_directives
- | empty
- ;
-
-/* Enum lists - any #define macros (constant directives) within the enum list are ignored. Trailing commas accepted. */
-
-/*
- Note that "_last" attribute is not supposed to be set on the last enum element, as might be expected from its name, but on the _first_ one, and _only_ on it,
- so we propagate it back to the first item while parsing and reset it on all the subsequent ones.
- */
-
-enumlist : enumlist_item {
- Setattr($1,"_last",$1);
- $$ = $1;
- }
- | enumlist_item DOXYGENPOSTSTRING {
- Setattr($1,"_last",$1);
- set_comment($1, $2);
- $$ = $1;
- }
- | enumlist_item COMMA enumlist {
- if ($3) {
- set_nextSibling($1, $3);
- Setattr($1,"_last",Getattr($3,"_last"));
- Setattr($3,"_last",NULL);
- } else {
- Setattr($1,"_last",$1);
- }
- $$ = $1;
- }
- | enumlist_item COMMA DOXYGENPOSTSTRING enumlist {
- if ($4) {
- set_nextSibling($1, $4);
- Setattr($1,"_last",Getattr($4,"_last"));
- Setattr($4,"_last",NULL);
- } else {
- Setattr($1,"_last",$1);
- }
- set_comment($1, $3);
- $$ = $1;
- }
- | optional_ignored_defines {
- $$ = 0;
- }
- ;
-
-enumlist_item : optional_ignored_defines edecl_with_dox optional_ignored_defines {
- $$ = $2;
- }
- ;
-
-edecl_with_dox : edecl {
- $$ = $1;
- }
- | DOXYGENSTRING edecl {
- $$ = $2;
- set_comment($2, $1);
- }
- ;
-
-edecl : identifier {
- SwigType *type = NewSwigType(T_INT);
- $$ = new_node("enumitem");
- Setattr($$,"name",$1);
- Setattr($$,"type",type);
- SetFlag($$,"feature:immutable");
- Delete(type);
- }
- | identifier EQUAL etype {
- SwigType *type = NewSwigType($3.type == T_BOOL ? T_BOOL : ($3.type == T_CHAR ? T_CHAR : T_INT));
- $$ = new_node("enumitem");
- Setattr($$,"name",$1);
- Setattr($$,"type",type);
- SetFlag($$,"feature:immutable");
- Setattr($$,"enumvalue", $3.val);
- Setattr($$,"value",$1);
- Delete(type);
- }
- ;
-
-etype : expr {
- $$ = $1;
- if (($$.type != T_INT) && ($$.type != T_UINT) &&
- ($$.type != T_LONG) && ($$.type != T_ULONG) &&
- ($$.type != T_LONGLONG) && ($$.type != T_ULONGLONG) &&
- ($$.type != T_SHORT) && ($$.type != T_USHORT) &&
- ($$.type != T_SCHAR) && ($$.type != T_UCHAR) &&
- ($$.type != T_CHAR) && ($$.type != T_BOOL)) {
- Swig_error(cparse_file,cparse_line,"Type error. Expecting an integral type\n");
- }
- }
- ;
-
-/* Arithmetic expressions. Used for constants, C++ templates, and other cool stuff. */
-
-expr : valexpr { $$ = $1; }
- | type {
- Node *n;
- $$.val = $1;
- $$.type = T_INT;
- /* Check if value is in scope */
- n = Swig_symbol_clookup($1,0);
- if (n) {
- /* A band-aid for enum values used in expressions. */
- if (Strcmp(nodeType(n),"enumitem") == 0) {
- String *q = Swig_symbol_qualified(n);
- if (q) {
- $$.val = NewStringf("%s::%s", q, Getattr(n,"name"));
- Delete(q);
- }
- }
- }
- }
- ;
-
-/* simple member access expressions */
-exprmem : ID ARROW ID {
- $$.val = NewStringf("%s->%s", $1, $3);
- $$.type = 0;
- }
- | ID ARROW ID LPAREN callparms RPAREN {
- $$.val = NewStringf("%s->%s(%s)", $1, $3, $5.val);
- $$.type = 0;
- }
- | exprmem ARROW ID {
- $$ = $1;
- Printf($$.val, "->%s", $3);
- }
- | exprmem ARROW ID LPAREN callparms RPAREN {
- $$ = $1;
- Printf($$.val, "->%s(%s)", $3, $5.val);
- }
- | ID PERIOD ID {
- $$.val = NewStringf("%s.%s", $1, $3);
- $$.type = 0;
- }
- | ID PERIOD ID LPAREN callparms RPAREN {
- $$.val = NewStringf("%s.%s(%s)", $1, $3, $5.val);
- $$.type = 0;
- }
- | exprmem PERIOD ID {
- $$ = $1;
- Printf($$.val, ".%s", $3);
- }
- | exprmem PERIOD ID LPAREN callparms RPAREN {
- $$ = $1;
- Printf($$.val, ".%s(%s)", $3, $5.val);
- }
- ;
-
-/* Non-compound expression */
-exprsimple : exprnum {
- $$ = $1;
- }
- | exprmem {
- $$ = $1;
- }
- | string {
- $$.val = $1;
- $$.type = T_STRING;
- }
- | SIZEOF LPAREN type parameter_declarator RPAREN {
- SwigType_push($3,$4.type);
- $$.val = NewStringf("sizeof(%s)",SwigType_str($3,0));
- $$.type = T_ULONG;
- }
- | SIZEOF ELLIPSIS LPAREN type parameter_declarator RPAREN {
- SwigType_push($4,$5.type);
- $$.val = NewStringf("sizeof...(%s)",SwigType_str($4,0));
- $$.type = T_ULONG;
- }
- /* We don't support all valid expressions here currently - e.g.
- * sizeof(<unaryop> x) doesn't work - but those are unlikely to
- * be seen in real code.
- *
- * Note: sizeof(x) is not handled here, but instead by the rule
- * for sizeof(<type>) because it matches that syntactically.
- */
- | SIZEOF LPAREN exprsimple RPAREN {
- $$.val = NewStringf("sizeof(%s)", $3.val);
- $$.type = T_ULONG;
- }
- /* `sizeof expr` without parentheses is valid for an expression,
- * but not for a type. This doesn't support `sizeof x` in
- * addition to the case not supported above.
- */
- | SIZEOF exprsimple {
- $$.val = NewStringf("sizeof(%s)", $2.val);
- $$.type = T_ULONG;
- }
- | wstring {
- $$.val = $1;
- $$.rawval = NewStringf("L\"%s\"", $$.val);
- $$.type = T_WSTRING;
- }
- | CHARCONST {
- $$.val = NewString($1);
- if (Len($$.val)) {
- $$.rawval = NewStringf("'%(escape)s'", $$.val);
- } else {
- $$.rawval = NewString("'\\0'");
- }
- $$.type = T_CHAR;
- $$.bitfield = 0;
- $$.throws = 0;
- $$.throwf = 0;
- $$.nexcept = 0;
- $$.final = 0;
- }
- | WCHARCONST {
- $$.val = NewString($1);
- if (Len($$.val)) {
- $$.rawval = NewStringf("L\'%s\'", $$.val);
- } else {
- $$.rawval = NewString("L'\\0'");
- }
- $$.type = T_WCHAR;
- $$.bitfield = 0;
- $$.throws = 0;
- $$.throwf = 0;
- $$.nexcept = 0;
- $$.final = 0;
- }
-
- ;
-
-valexpr : exprsimple { $$ = $1; }
- | exprcompound { $$ = $1; }
-
-/* grouping */
- | LPAREN expr RPAREN %prec CAST {
- $$.val = NewStringf("(%s)",$2.val);
- if ($2.rawval) {
- $$.rawval = NewStringf("(%s)",$2.rawval);
- }
- $$.type = $2.type;
- }
-
-/* A few common casting operations */
-
- | LPAREN expr RPAREN expr %prec CAST {
- $$ = $4;
- if ($4.type != T_STRING) {
- switch ($2.type) {
- case T_FLOAT:
- case T_DOUBLE:
- case T_LONGDOUBLE:
- case T_FLTCPLX:
- case T_DBLCPLX:
- $$.val = NewStringf("(%s)%s", $2.val, $4.val); /* SwigType_str and decimal points don't mix! */
- break;
- default:
- $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $4.val);
- break;
- }
- }
- $$.type = promote($2.type, $4.type);
- }
- | LPAREN expr pointer RPAREN expr %prec CAST {
- $$ = $5;
- if ($5.type != T_STRING) {
- SwigType_push($2.val,$3);
- $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val);
- }
- }
- | LPAREN expr AND RPAREN expr %prec CAST {
- $$ = $5;
- if ($5.type != T_STRING) {
- SwigType_add_reference($2.val);
- $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val);
- }
- }
- | LPAREN expr LAND RPAREN expr %prec CAST {
- $$ = $5;
- if ($5.type != T_STRING) {
- SwigType_add_rvalue_reference($2.val);
- $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val);
- }
- }
- | LPAREN expr pointer AND RPAREN expr %prec CAST {
- $$ = $6;
- if ($6.type != T_STRING) {
- SwigType_push($2.val,$3);
- SwigType_add_reference($2.val);
- $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $6.val);
- }
- }
- | LPAREN expr pointer LAND RPAREN expr %prec CAST {
- $$ = $6;
- if ($6.type != T_STRING) {
- SwigType_push($2.val,$3);
- SwigType_add_rvalue_reference($2.val);
- $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $6.val);
- }
- }
- | AND expr {
- $$ = $2;
- $$.val = NewStringf("&%s",$2.val);
- }
- | STAR expr {
- $$ = $2;
- $$.val = NewStringf("*%s",$2.val);
- }
- ;
-
-exprnum : NUM_INT { $$ = $1; }
- | NUM_FLOAT { $$ = $1; }
- | NUM_UNSIGNED { $$ = $1; }
- | NUM_LONG { $$ = $1; }
- | NUM_ULONG { $$ = $1; }
- | NUM_LONGLONG { $$ = $1; }
- | NUM_ULONGLONG { $$ = $1; }
- | NUM_BOOL { $$ = $1; }
- ;
-
-exprcompound : expr PLUS expr {
- $$.val = NewStringf("%s+%s", COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
- $$.type = promote($1.type,$3.type);
- }
- | expr MINUS expr {
- $$.val = NewStringf("%s-%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
- $$.type = promote($1.type,$3.type);
- }
- | expr STAR expr {
- $$.val = NewStringf("%s*%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
- $$.type = promote($1.type,$3.type);
- }
- | expr SLASH expr {
- $$.val = NewStringf("%s/%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
- $$.type = promote($1.type,$3.type);
- }
- | expr MODULO expr {
- $$.val = NewStringf("%s%%%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
- $$.type = promote($1.type,$3.type);
- }
- | expr AND expr {
- $$.val = NewStringf("%s&%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
- $$.type = promote($1.type,$3.type);
- }
- | expr OR expr {
- $$.val = NewStringf("%s|%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
- $$.type = promote($1.type,$3.type);
- }
- | expr XOR expr {
- $$.val = NewStringf("%s^%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
- $$.type = promote($1.type,$3.type);
- }
- | expr LSHIFT expr {
- $$.val = NewStringf("%s << %s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
- $$.type = promote_type($1.type);
- }
- | expr RSHIFT expr {
- $$.val = NewStringf("%s >> %s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
- $$.type = promote_type($1.type);
- }
- | expr LAND expr {
- $$.val = NewStringf("%s&&%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
- $$.type = cparse_cplusplus ? T_BOOL : T_INT;
- }
- | expr LOR expr {
- $$.val = NewStringf("%s||%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
- $$.type = cparse_cplusplus ? T_BOOL : T_INT;
- }
- | expr EQUALTO expr {
- $$.val = NewStringf("%s==%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
- $$.type = cparse_cplusplus ? T_BOOL : T_INT;
- }
- | expr NOTEQUALTO expr {
- $$.val = NewStringf("%s!=%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
- $$.type = cparse_cplusplus ? T_BOOL : T_INT;
- }
- /* Trying to parse `>` in the general case results in conflicts
- * in the parser, but all user-reported cases are actually inside
- * parentheses and we can handle that case.
- */
- | LPAREN expr GREATERTHAN expr RPAREN {
- $$.val = NewStringf("%s > %s", COMPOUND_EXPR_VAL($2), COMPOUND_EXPR_VAL($4));
- $$.type = cparse_cplusplus ? T_BOOL : T_INT;
- }
-
- /* Similarly for `<` except trying to handle exprcompound on the
- * left side gives a shift/reduce conflict, so also restrict
- * handling to non-compound subexpressions there. Again this
- * covers all user-reported cases.
- */
- | LPAREN exprsimple LESSTHAN expr RPAREN {
- $$.val = NewStringf("%s < %s", COMPOUND_EXPR_VAL($2), COMPOUND_EXPR_VAL($4));
- $$.type = cparse_cplusplus ? T_BOOL : T_INT;
- }
- | expr GREATERTHANOREQUALTO expr {
- $$.val = NewStringf("%s >= %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
- $$.type = cparse_cplusplus ? T_BOOL : T_INT;
- }
- | expr LESSTHANOREQUALTO expr {
- $$.val = NewStringf("%s <= %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
- $$.type = cparse_cplusplus ? T_BOOL : T_INT;
- }
- | expr LESSEQUALGREATER expr {
- $$.val = NewStringf("%s <=> %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
- /* Really `<=>` returns one of `std::strong_ordering`,
- * `std::partial_ordering` or `std::weak_ordering`, but we
- * fake it by treating the return value as `int`. The main
- * thing to do with the return value in this context is to
- * compare it with 0, for which `int` does the job. */
- $$.type = T_INT;
- }
- | expr QUESTIONMARK expr COLON expr %prec QUESTIONMARK {
- $$.val = NewStringf("%s?%s:%s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3), COMPOUND_EXPR_VAL($5));
- /* This may not be exactly right, but is probably good enough
- * for the purposes of parsing constant expressions. */
- $$.type = promote($3.type, $5.type);
- }
- | MINUS expr %prec UMINUS {
- $$.val = NewStringf("-%s",$2.val);
- $$.type = $2.type;
- }
- | PLUS expr %prec UMINUS {
- $$.val = NewStringf("+%s",$2.val);
- $$.type = $2.type;
- }
- | NOT expr {
- $$.val = NewStringf("~%s",$2.val);
- $$.type = $2.type;
- }
- | LNOT expr {
- $$.val = NewStringf("!%s",COMPOUND_EXPR_VAL($2));
- $$.type = T_INT;
- }
- | type LPAREN {
- String *qty;
- skip_balanced('(',')');
- qty = Swig_symbol_type_qualify($1,0);
- if (SwigType_istemplate(qty)) {
- String *nstr = SwigType_namestr(qty);
- Delete(qty);
- qty = nstr;
- }
- $$.val = NewStringf("%s%s",qty,scanner_ccode);
- Clear(scanner_ccode);
- $$.type = T_INT;
- Delete(qty);
- }
- ;
-
-variadic : ELLIPSIS {
- $$ = NewString("...");
- }
- | empty {
- $$ = 0;
- }
- ;
-
-inherit : raw_inherit {
- $$ = $1;
- }
- ;
-
-raw_inherit : COLON { inherit_list = 1; } base_list { $$ = $3; inherit_list = 0; }
- | empty { $$ = 0; }
- ;
-
-base_list : base_specifier {
- Hash *list = NewHash();
- Node *base = $1;
- Node *name = Getattr(base,"name");
- List *lpublic = NewList();
- List *lprotected = NewList();
- List *lprivate = NewList();
- Setattr(list,"public",lpublic);
- Setattr(list,"protected",lprotected);
- Setattr(list,"private",lprivate);
- Delete(lpublic);
- Delete(lprotected);
- Delete(lprivate);
- Append(Getattr(list,Getattr(base,"access")),name);
- $$ = list;
- }
-
- | base_list COMMA base_specifier {
- Hash *list = $1;
- Node *base = $3;
- Node *name = Getattr(base,"name");
- Append(Getattr(list,Getattr(base,"access")),name);
- $$ = list;
- }
- ;
-
-base_specifier : opt_virtual {
- $<intvalue>$ = cparse_line;
- } idcolon variadic {
- $$ = NewHash();
- Setfile($$,cparse_file);
- Setline($$,$<intvalue>2);
- Setattr($$,"name",$3);
- Setfile($3,cparse_file);
- Setline($3,$<intvalue>2);
- if (last_cpptype && (Strcmp(last_cpptype,"struct") != 0)) {
- Setattr($$,"access","private");
- Swig_warning(WARN_PARSE_NO_ACCESS, Getfile($$), Getline($$), "No access specifier given for base class '%s' (ignored).\n", SwigType_namestr($3));
- } else {
- Setattr($$,"access","public");
- }
- if ($4)
- SetFlag($$, "variadic");
- }
- | opt_virtual access_specifier {
- $<intvalue>$ = cparse_line;
- } opt_virtual idcolon variadic {
- $$ = NewHash();
- Setfile($$,cparse_file);
- Setline($$,$<intvalue>3);
- Setattr($$,"name",$5);
- Setfile($5,cparse_file);
- Setline($5,$<intvalue>3);
- Setattr($$,"access",$2);
- if (Strcmp($2,"public") != 0) {
- Swig_warning(WARN_PARSE_PRIVATE_INHERIT, Getfile($$), Getline($$), "%s inheritance from base '%s' (ignored).\n", $2, SwigType_namestr($5));
- }
- if ($6)
- SetFlag($$, "variadic");
- }
- ;
-
-access_specifier : PUBLIC { $$ = (char*)"public"; }
- | PRIVATE { $$ = (char*)"private"; }
- | PROTECTED { $$ = (char*)"protected"; }
- ;
-
-templcpptype : CLASS {
- $$ = (char*)"class";
- if (!inherit_list) last_cpptype = $$;
- }
- | TYPENAME {
- $$ = (char *)"typename";
- if (!inherit_list) last_cpptype = $$;
- }
- | CLASS ELLIPSIS {
- $$ = (char *)"class...";
- if (!inherit_list) last_cpptype = $$;
- }
- | TYPENAME ELLIPSIS {
- $$ = (char *)"typename...";
- if (!inherit_list) last_cpptype = $$;
- }
- ;
-
-cpptype : templcpptype {
- $$ = $1;
- }
- | STRUCT {
- $$ = (char*)"struct";
- if (!inherit_list) last_cpptype = $$;
- }
- | UNION {
- $$ = (char*)"union";
- if (!inherit_list) last_cpptype = $$;
- }
- ;
-
-classkey : CLASS {
- $$ = (char*)"class";
- if (!inherit_list) last_cpptype = $$;
- }
- | STRUCT {
- $$ = (char*)"struct";
- if (!inherit_list) last_cpptype = $$;
- }
- | UNION {
- $$ = (char*)"union";
- if (!inherit_list) last_cpptype = $$;
- }
- ;
-
-classkeyopt : classkey {
- $$ = $1;
- }
- | empty {
- $$ = 0;
- }
- ;
-
-opt_virtual : VIRTUAL
- | empty
- ;
-
-virt_specifier_seq : OVERRIDE {
- $$ = 0;
- }
- | FINAL {
- $$ = NewString("1");
- }
- | FINAL OVERRIDE {
- $$ = NewString("1");
- }
- | OVERRIDE FINAL {
- $$ = NewString("1");
- }
- ;
-
-virt_specifier_seq_opt : virt_specifier_seq {
- $$ = $1;
- }
- | empty {
- $$ = 0;
- }
- ;
-
-class_virt_specifier_opt : FINAL {
- $$ = NewString("1");
- }
- | empty {
- $$ = 0;
- }
- ;
-
-exception_specification : THROW LPAREN parms RPAREN {
- $$.throws = $3;
- $$.throwf = NewString("1");
- $$.nexcept = 0;
- $$.final = 0;
- }
- | NOEXCEPT {
- $$.throws = 0;
- $$.throwf = 0;
- $$.nexcept = NewString("true");
- $$.final = 0;
- }
- | virt_specifier_seq {
- $$.throws = 0;
- $$.throwf = 0;
- $$.nexcept = 0;
- $$.final = $1;
- }
- | THROW LPAREN parms RPAREN virt_specifier_seq {
- $$.throws = $3;
- $$.throwf = NewString("1");
- $$.nexcept = 0;
- $$.final = $5;
- }
- | NOEXCEPT virt_specifier_seq {
- $$.throws = 0;
- $$.throwf = 0;
- $$.nexcept = NewString("true");
- $$.final = $2;
- }
- | NOEXCEPT LPAREN expr RPAREN {
- $$.throws = 0;
- $$.throwf = 0;
- $$.nexcept = $3.val;
- $$.final = 0;
- }
- ;
-
-qualifiers_exception_specification : cv_ref_qualifier {
- $$.throws = 0;
- $$.throwf = 0;
- $$.nexcept = 0;
- $$.final = 0;
- $$.qualifier = $1.qualifier;
- $$.refqualifier = $1.refqualifier;
- }
- | exception_specification {
- $$ = $1;
- $$.qualifier = 0;
- $$.refqualifier = 0;
- }
- | cv_ref_qualifier exception_specification {
- $$ = $2;
- $$.qualifier = $1.qualifier;
- $$.refqualifier = $1.refqualifier;
- }
- ;
-
-cpp_const : qualifiers_exception_specification {
- $$ = $1;
- }
- | empty {
- $$.throws = 0;
- $$.throwf = 0;
- $$.nexcept = 0;
- $$.final = 0;
- $$.qualifier = 0;
- $$.refqualifier = 0;
- }
- ;
-
-ctor_end : cpp_const ctor_initializer SEMI {
- Clear(scanner_ccode);
- $$.have_parms = 0;
- $$.defarg = 0;
- $$.throws = $1.throws;
- $$.throwf = $1.throwf;
- $$.nexcept = $1.nexcept;
- $$.final = $1.final;
- if ($1.qualifier)
- Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n");
- }
- | cpp_const ctor_initializer LBRACE {
- skip_balanced('{','}');
- $$.have_parms = 0;
- $$.defarg = 0;
- $$.throws = $1.throws;
- $$.throwf = $1.throwf;
- $$.nexcept = $1.nexcept;
- $$.final = $1.final;
- if ($1.qualifier)
- Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n");
- }
- | LPAREN parms RPAREN SEMI {
- Clear(scanner_ccode);
- $$.parms = $2;
- $$.have_parms = 1;
- $$.defarg = 0;
- $$.throws = 0;
- $$.throwf = 0;
- $$.nexcept = 0;
- $$.final = 0;
- }
- | LPAREN parms RPAREN LBRACE {
- skip_balanced('{','}');
- $$.parms = $2;
- $$.have_parms = 1;
- $$.defarg = 0;
- $$.throws = 0;
- $$.throwf = 0;
- $$.nexcept = 0;
- $$.final = 0;
- }
- | EQUAL definetype SEMI {
- $$.have_parms = 0;
- $$.defarg = $2.val;
- $$.throws = 0;
- $$.throwf = 0;
- $$.nexcept = 0;
- $$.final = 0;
- }
- | exception_specification EQUAL default_delete SEMI {
- $$.have_parms = 0;
- $$.defarg = $3.val;
- $$.throws = $1.throws;
- $$.throwf = $1.throwf;
- $$.nexcept = $1.nexcept;
- $$.final = $1.final;
- if ($1.qualifier)
- Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n");
- }
- ;
-
-ctor_initializer : COLON mem_initializer_list
- | empty
- ;
-
-mem_initializer_list : mem_initializer
- | mem_initializer_list COMMA mem_initializer
- | mem_initializer ELLIPSIS
- | mem_initializer_list COMMA mem_initializer ELLIPSIS
- ;
-
-mem_initializer : idcolon LPAREN {
- skip_balanced('(',')');
- Clear(scanner_ccode);
- }
- /* Uniform initialization in C++11.
- Example:
- struct MyStruct {
- MyStruct(int x, double y) : x_{x}, y_{y} {}
- int x_;
- double y_;
- };
- */
- | idcolon LBRACE {
- skip_balanced('{','}');
- Clear(scanner_ccode);
- }
- ;
-
-less_valparms_greater : LESSTHAN valparms GREATERTHAN {
- String *s = NewStringEmpty();
- SwigType_add_template(s,$2);
- $$ = Char(s);
- scanner_last_id(1);
- }
- ;
-
-/* Identifiers including the C++11 identifiers with special meaning */
-identifier : ID { $$ = $1; }
- | OVERRIDE { $$ = Swig_copy_string("override"); }
- | FINAL { $$ = Swig_copy_string("final"); }
- ;
-
-idstring : identifier { $$ = $1; }
- | default_delete { $$ = Char($1.val); }
- | string { $$ = Char($1); }
- ;
-
-idstringopt : idstring { $$ = $1; }
- | empty { $$ = 0; }
- ;
-
-idcolon : idtemplate idcolontail {
- $$ = 0;
- if (!$$) $$ = NewStringf("%s%s", $1,$2);
- Delete($2);
- }
- | NONID DCOLON idtemplatetemplate idcolontail {
- $$ = NewStringf("::%s%s",$3,$4);
- Delete($4);
- }
- | idtemplate {
- $$ = NewString($1);
- }
- | NONID DCOLON idtemplatetemplate {
- $$ = NewStringf("::%s",$3);
- }
- | OPERATOR {
- $$ = NewStringf("%s", $1);
- }
- | OPERATOR less_valparms_greater {
- $$ = NewStringf("%s%s", $1, $2);
- }
- | NONID DCOLON OPERATOR {
- $$ = NewStringf("::%s",$3);
- }
- ;
-
-idcolontail : DCOLON idtemplatetemplate idcolontail {
- $$ = NewStringf("::%s%s",$2,$3);
- Delete($3);
- }
- | DCOLON idtemplatetemplate {
- $$ = NewStringf("::%s",$2);
- }
- | DCOLON OPERATOR {
- $$ = NewStringf("::%s",$2);
- }
-/* | DCOLON CONVERSIONOPERATOR {
- $$ = NewString($2);
- } */
-
- | DCNOT idtemplate {
- $$ = NewStringf("::~%s",$2);
- }
- ;
-
-
-idtemplate : identifier {
- $$ = NewStringf("%s", $1);
- }
- | identifier less_valparms_greater {
- $$ = NewStringf("%s%s", $1, $2);
- }
- ;
-
-idtemplatetemplate : idtemplate {
- $$ = $1;
- }
- | TEMPLATE identifier less_valparms_greater {
- $$ = NewStringf("%s%s", $2, $3);
- }
- ;
-
-/* Identifier, but no templates */
-idcolonnt : identifier idcolontailnt {
- $$ = 0;
- if (!$$) $$ = NewStringf("%s%s", $1,$2);
- Delete($2);
- }
- | NONID DCOLON identifier idcolontailnt {
- $$ = NewStringf("::%s%s",$3,$4);
- Delete($4);
- }
- | identifier {
- $$ = NewString($1);
- }
- | NONID DCOLON identifier {
- $$ = NewStringf("::%s",$3);
- }
- | OPERATOR {
- $$ = NewString($1);
- }
- | NONID DCOLON OPERATOR {
- $$ = NewStringf("::%s",$3);
- }
- ;
-
-idcolontailnt : DCOLON identifier idcolontailnt {
- $$ = NewStringf("::%s%s",$2,$3);
- Delete($3);
- }
- | DCOLON identifier {
- $$ = NewStringf("::%s",$2);
- }
- | DCOLON OPERATOR {
- $$ = NewStringf("::%s",$2);
- }
- | DCNOT identifier {
- $$ = NewStringf("::~%s",$2);
- }
- ;
-
-/* Concatenated strings */
-string : string STRING {
- $$ = NewStringf("%s%s", $1, $2);
- }
- | STRING { $$ = NewString($1);}
- ;
-/* Concatenated wide strings: L"str1" L"str2" */
-wstring : wstring WSTRING {
- $$ = NewStringf("%s%s", $1, $2);
- }
-/* Concatenated wide string and normal string literal: L"str1" "str2" */
-/*not all the compilers support this concatenation mode, so perhaps better to postpone it*/
- /*| wstring STRING { here $2 comes unescaped, we have to escape it back first via NewStringf("%(escape)s)"
- $$ = NewStringf("%s%s", $1, $2);
- }*/
- | WSTRING { $$ = NewString($1);}
- ;
-
-stringbrace : string {
- $$ = $1;
- }
- | LBRACE {
- skip_balanced('{','}');
- $$ = NewString(scanner_ccode);
- }
- | HBLOCK {
- $$ = $1;
- }
- ;
-
-options : LPAREN kwargs RPAREN {
- Hash *n;
- $$ = NewHash();
- n = $2;
- while(n) {
- String *name, *value;
- name = Getattr(n,"name");
- value = Getattr(n,"value");
- if (!value) value = (String *) "1";
- Setattr($$,name, value);
- n = nextSibling(n);
- }
- }
- | empty { $$ = 0; };
-
-
-/* Keyword arguments */
-kwargs : idstring EQUAL stringnum {
- $$ = NewHash();
- Setattr($$,"name",$1);
- Setattr($$,"value",$3);
- }
- | idstring EQUAL stringnum COMMA kwargs {
- $$ = NewHash();
- Setattr($$,"name",$1);
- Setattr($$,"value",$3);
- set_nextSibling($$,$5);
- }
- | idstring {
- $$ = NewHash();
- Setattr($$,"name",$1);
- }
- | idstring COMMA kwargs {
- $$ = NewHash();
- Setattr($$,"name",$1);
- set_nextSibling($$,$3);
- }
- | idstring EQUAL stringtype {
- $$ = $3;
- Setattr($$,"name",$1);
- }
- | idstring EQUAL stringtype COMMA kwargs {
- $$ = $3;
- Setattr($$,"name",$1);
- set_nextSibling($$,$5);
- }
- ;
-
-stringnum : string {
- $$ = $1;
- }
- | exprnum {
- $$ = Char($1.val);
- }
- ;
-
-empty : ;
-
-%%
-
-SwigType *Swig_cparse_type(String *s) {
- String *ns;
- ns = NewStringf("%s;",s);
- Seek(ns,0,SEEK_SET);
- scanner_file(ns);
- top = 0;
- scanner_next_token(PARSETYPE);
- yyparse();
- /* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */
- return top;
-}
-
-
-Parm *Swig_cparse_parm(String *s) {
- String *ns;
- ns = NewStringf("%s;",s);
- Seek(ns,0,SEEK_SET);
- scanner_file(ns);
- top = 0;
- scanner_next_token(PARSEPARM);
- yyparse();
- /* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */
- Delete(ns);
- return top;
-}
-
-
-ParmList *Swig_cparse_parms(String *s, Node *file_line_node) {
- String *ns;
- char *cs = Char(s);
- if (cs && cs[0] != '(') {
- ns = NewStringf("(%s);",s);
- } else {
- ns = NewStringf("%s;",s);
- }
- Setfile(ns, Getfile(file_line_node));
- Setline(ns, Getline(file_line_node));
- Seek(ns,0,SEEK_SET);
- scanner_file(ns);
- top = 0;
- scanner_next_token(PARSEPARMS);
- yyparse();
- /* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */
- return top;
-}
-
diff --git a/contrib/tools/swig/Source/CParse/templ.c b/contrib/tools/swig/Source/CParse/templ.c
deleted file mode 100644
index 0dec215869..0000000000
--- a/contrib/tools/swig/Source/CParse/templ.c
+++ /dev/null
@@ -1,976 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * templ.c
- *
- * Expands a template into a specialized version.
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-#include "cparse.h"
-
-static int template_debug = 0;
-
-
-const char *baselists[3];
-
-void SwigType_template_init(void) {
- baselists[0] = "baselist";
- baselists[1] = "protectedbaselist";
- baselists[2] = "privatebaselist";
-}
-
-
-static void add_parms(ParmList *p, List *patchlist, List *typelist, int is_pattern) {
- while (p) {
- SwigType *ty = Getattr(p, "type");
- SwigType *val = Getattr(p, "value");
- Append(typelist, ty);
- Append(typelist, val);
- if (is_pattern) {
- /* Typemap patterns are not simple parameter lists.
- * Output style ("out", "ret" etc) typemap names can be
- * qualified names and so may need template expansion */
- SwigType *name = Getattr(p, "name");
- Append(typelist, name);
- }
- Append(patchlist, val);
- p = nextSibling(p);
- }
-}
-
-void Swig_cparse_debug_templates(int x) {
- template_debug = x;
-}
-
-/* -----------------------------------------------------------------------------
- * cparse_template_expand()
- *
- * Expands a template node into a specialized version. This is done by
- * patching typenames and other aspects of the node according to a list of
- * template parameters
- * ----------------------------------------------------------------------------- */
-
-static void cparse_template_expand(Node *templnode, Node *n, String *tname, String *rname, String *templateargs, List *patchlist, List *typelist, List *cpatchlist) {
- static int expanded = 0;
- String *nodeType;
- if (!n)
- return;
- nodeType = nodeType(n);
- if (Getattr(n, "error"))
- return;
-
- if (Equal(nodeType, "template")) {
- /* Change the node type back to normal */
- if (!expanded) {
- expanded = 1;
- set_nodeType(n, Getattr(n, "templatetype"));
- cparse_template_expand(templnode, n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
- expanded = 0;
- return;
- } else {
- /* Called when template appears inside another template */
- /* Member templates */
-
- set_nodeType(n, Getattr(n, "templatetype"));
- cparse_template_expand(templnode, n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
- set_nodeType(n, "template");
- return;
- }
- } else if (Equal(nodeType, "cdecl")) {
- /* A simple C declaration */
- SwigType *t, *v, *d;
- String *code;
- t = Getattr(n, "type");
- v = Getattr(n, "value");
- d = Getattr(n, "decl");
-
- code = Getattr(n, "code");
-
- Append(typelist, t);
- Append(typelist, d);
- Append(patchlist, v);
- Append(cpatchlist, code);
-
- if (Getattr(n, "conversion_operator")) {
- Append(cpatchlist, Getattr(n, "name"));
- if (Getattr(n, "sym:name")) {
- Append(cpatchlist, Getattr(n, "sym:name"));
- }
- }
- if (checkAttribute(n, "storage", "friend")) {
- String *symname = Getattr(n, "sym:name");
- if (symname) {
- String *stripped_name = SwigType_templateprefix(symname);
- Setattr(n, "sym:name", stripped_name);
- Delete(stripped_name);
- }
- Append(typelist, Getattr(n, "name"));
- }
-
- add_parms(Getattr(n, "parms"), cpatchlist, typelist, 0);
- add_parms(Getattr(n, "throws"), cpatchlist, typelist, 0);
-
- } else if (Equal(nodeType, "class")) {
- /* Patch base classes */
- {
- int b = 0;
- for (b = 0; b < 3; ++b) {
- List *bases = Getattr(n, baselists[b]);
- if (bases) {
- int i;
- int ilen = Len(bases);
- for (i = 0; i < ilen; i++) {
- String *name = Copy(Getitem(bases, i));
- Setitem(bases, i, name);
- Append(typelist, name);
- }
- }
- }
- }
- /* Patch children */
- {
- Node *cn = firstChild(n);
- while (cn) {
- cparse_template_expand(templnode, cn, tname, rname, templateargs, patchlist, typelist, cpatchlist);
- cn = nextSibling(cn);
- }
- }
- } else if (Equal(nodeType, "constructor")) {
- String *name = Getattr(n, "name");
- if (!(Getattr(n, "templatetype"))) {
- String *symname;
- String *stripped_name = SwigType_templateprefix(name);
- if (Strstr(tname, stripped_name)) {
- Replaceid(name, stripped_name, tname);
- }
- Delete(stripped_name);
- symname = Getattr(n, "sym:name");
- if (symname) {
- stripped_name = SwigType_templateprefix(symname);
- if (Strstr(tname, stripped_name)) {
- Replaceid(symname, stripped_name, tname);
- }
- Delete(stripped_name);
- }
- if (strchr(Char(name), '<')) {
- Append(patchlist, Getattr(n, "name"));
- } else {
- Append(name, templateargs);
- }
- name = Getattr(n, "sym:name");
- if (name) {
- if (strchr(Char(name), '<')) {
- Clear(name);
- Append(name, rname);
- } else {
- String *tmp = Copy(name);
- Replace(tmp, tname, rname, DOH_REPLACE_ANY);
- Clear(name);
- Append(name, tmp);
- Delete(tmp);
- }
- }
- /* Setattr(n,"sym:name",name); */
- }
- Append(cpatchlist, Getattr(n, "code"));
- Append(typelist, Getattr(n, "decl"));
- add_parms(Getattr(n, "parms"), cpatchlist, typelist, 0);
- add_parms(Getattr(n, "throws"), cpatchlist, typelist, 0);
- } else if (Equal(nodeType, "destructor")) {
- /* We only need to patch the dtor of the template itself, not the destructors of any nested classes, so check that the parent of this node is the root
- * template node, with the special exception for %extend which adds its methods under an intermediate node. */
- Node* parent = parentNode(n);
- if (parent == templnode || (parentNode(parent) == templnode && Equal(nodeType(parent), "extend"))) {
- String *name = Getattr(n, "name");
- if (name) {
- if (strchr(Char(name), '<'))
- Append(patchlist, Getattr(n, "name"));
- else
- Append(name, templateargs);
- }
- name = Getattr(n, "sym:name");
- if (name) {
- if (strchr(Char(name), '<')) {
- String *sn = Copy(tname);
- Setattr(n, "sym:name", sn);
- Delete(sn);
- } else {
- Replace(name, tname, rname, DOH_REPLACE_ANY);
- }
- }
- /* Setattr(n,"sym:name",name); */
- Append(cpatchlist, Getattr(n, "code"));
- }
- } else if (Equal(nodeType, "using")) {
- String *uname = Getattr(n, "uname");
- if (uname && strchr(Char(uname), '<')) {
- Append(patchlist, uname);
- }
- if (Getattr(n, "namespace")) {
- /* Namespace link. This is nasty. Is other namespace defined? */
-
- }
- } else {
- /* Look for obvious parameters */
- Node *cn;
- Append(cpatchlist, Getattr(n, "code"));
- Append(typelist, Getattr(n, "type"));
- Append(typelist, Getattr(n, "decl"));
- add_parms(Getattr(n, "parms"), cpatchlist, typelist, 0);
- add_parms(Getattr(n, "kwargs"), cpatchlist, typelist, 0);
- add_parms(Getattr(n, "pattern"), cpatchlist, typelist, 1);
- add_parms(Getattr(n, "throws"), cpatchlist, typelist, 0);
- cn = firstChild(n);
- while (cn) {
- cparse_template_expand(templnode, cn, tname, rname, templateargs, patchlist, typelist, cpatchlist);
- cn = nextSibling(cn);
- }
- }
-}
-
-/* -----------------------------------------------------------------------------
- * cparse_fix_function_decl()
- *
- * Move the prefix of the "type" attribute (excluding any trailing qualifier)
- * to the end of the "decl" attribute.
- * Examples:
- * decl="f().", type="p.q(const).char" => decl="f().p.", type="q(const).char"
- * decl="f().p.", type="p.SomeClass" => decl="f().p.p.", type="SomeClass"
- * decl="f().", type="r.q(const).p.int" => decl="f().r.q(const).p.", type="int"
- * ----------------------------------------------------------------------------- */
-
-static void cparse_fix_function_decl(String *name, SwigType *decl, SwigType *type) {
- String *prefix;
- int prefixLen;
- SwigType *last;
-
- /* The type's prefix is what potentially has to be moved to the end of 'decl' */
- prefix = SwigType_prefix(type);
-
- /* First some parts (qualifier and array) have to be removed from prefix
- in order to remain in the 'type' attribute. */
- last = SwigType_last(prefix);
- while (last) {
- if (SwigType_isqualifier(last) || SwigType_isarray(last)) {
- /* Keep this part in the 'type' */
- Delslice(prefix, Len(prefix) - Len(last), DOH_END);
- Delete(last);
- last = SwigType_last(prefix);
- } else {
- /* Done with processing prefix */
- Delete(last);
- last = 0;
- }
- }
-
- /* Transfer prefix from the 'type' to the 'decl' attribute */
- prefixLen = Len(prefix);
- if (prefixLen > 0) {
- Append(decl, prefix);
- Delslice(type, 0, prefixLen);
- if (template_debug) {
- Printf(stdout, " change function '%s' to type='%s', decl='%s'\n", name, type, decl);
- }
- }
-
- Delete(prefix);
-}
-
-/* -----------------------------------------------------------------------------
- * cparse_postprocess_expanded_template()
- *
- * This function postprocesses the given node after template expansion.
- * Currently the only task to perform is fixing function decl and type attributes.
- * ----------------------------------------------------------------------------- */
-
-static void cparse_postprocess_expanded_template(Node *n) {
- String *nodeType;
- if (!n)
- return;
- nodeType = nodeType(n);
- if (Getattr(n, "error"))
- return;
-
- if (Equal(nodeType, "cdecl")) {
- /* A simple C declaration */
- SwigType *d = Getattr(n, "decl");
- if (d && SwigType_isfunction(d)) {
- /* A function node */
- SwigType *t = Getattr(n, "type");
- if (t) {
- String *name = Getattr(n, "name");
- cparse_fix_function_decl(name, d, t);
- }
- }
- } else {
- /* Look for any children */
- Node *cn = firstChild(n);
- while (cn) {
- cparse_postprocess_expanded_template(cn);
- cn = nextSibling(cn);
- }
- }
-}
-
-/* -----------------------------------------------------------------------------
- * partial_arg()
- * ----------------------------------------------------------------------------- */
-
-static
-String *partial_arg(String *s, String *p) {
- char *c;
- char *cp = Char(p);
- String *prefix;
- String *newarg;
-
- /* Find the prefix on the partial argument */
-
- c = strchr(cp, '$');
- if (!c) {
- return Copy(s);
- }
- prefix = NewStringWithSize(cp, (int)(c - cp));
- newarg = Copy(s);
- Replace(newarg, prefix, "", DOH_REPLACE_FIRST);
- Delete(prefix);
- return newarg;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_cparse_template_expand()
- * ----------------------------------------------------------------------------- */
-
-int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *tscope) {
- List *patchlist, *cpatchlist, *typelist;
- String *templateargs;
- String *tname;
- String *iname;
- String *tbase;
- patchlist = NewList();
- cpatchlist = NewList();
- typelist = NewList();
-
- {
- String *tmp = NewStringEmpty();
- if (tparms) {
- SwigType_add_template(tmp, tparms);
- }
- templateargs = Copy(tmp);
- Delete(tmp);
- }
-
- tname = Copy(Getattr(n, "name"));
- tbase = Swig_scopename_last(tname);
-
- /* Look for partial specialization matching */
- if (Getattr(n, "partialargs")) {
- Parm *p, *tp;
- ParmList *ptargs = SwigType_function_parms(Getattr(n, "partialargs"), n);
- p = ptargs;
- tp = tparms;
- while (p && tp) {
- SwigType *ptype;
- SwigType *tptype;
- SwigType *partial_type;
- ptype = Getattr(p, "type");
- tptype = Getattr(tp, "type");
- if (ptype && tptype) {
- partial_type = partial_arg(tptype, ptype);
- /* Printf(stdout,"partial '%s' '%s' ---> '%s'\n", tptype, ptype, partial_type); */
- Setattr(tp, "type", partial_type);
- Delete(partial_type);
- }
- p = nextSibling(p);
- tp = nextSibling(tp);
- }
- assert(ParmList_len(ptargs) == ParmList_len(tparms));
- Delete(ptargs);
- }
-
- /*
- Parm *p = tparms;
- while (p) {
- Printf(stdout, "tparm: '%s' '%s' '%s'\n", Getattr(p, "name"), Getattr(p, "type"), Getattr(p, "value"));
- p = nextSibling(p);
- }
- */
-
- /* Printf(stdout,"targs = '%s'\n", templateargs);
- Printf(stdout,"rname = '%s'\n", rname);
- Printf(stdout,"tname = '%s'\n", tname); */
- cparse_template_expand(n, n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
-
- /* Set the name */
- {
- String *name = Getattr(n, "name");
- if (name) {
- Append(name, templateargs);
- }
- iname = name;
- }
-
- /* Patch all of the types */
- {
- Parm *tp = Getattr(n, "templateparms");
- Parm *p = tparms;
- /* Printf(stdout,"%s\n", ParmList_str_defaultargs(tp)); */
-
- if (tp) {
- Symtab *tsdecl = Getattr(n, "sym:symtab");
- String *tsname = Getattr(n, "sym:name");
- while (p && tp) {
- String *name, *value, *valuestr, *tmp, *tmpr;
- int sz, i;
- String *dvalue = 0;
- String *qvalue = 0;
-
- name = Getattr(tp, "name");
- value = Getattr(p, "value");
-
- if (name) {
- if (!value)
- value = Getattr(p, "type");
- qvalue = Swig_symbol_typedef_reduce(value, tsdecl);
- dvalue = Swig_symbol_type_qualify(qvalue, tsdecl);
- if (SwigType_istemplate(dvalue)) {
- String *ty = Swig_symbol_template_deftype(dvalue, tscope);
- Delete(dvalue);
- dvalue = ty;
- }
-
- assert(dvalue);
- valuestr = SwigType_str(dvalue, 0);
- /* Need to patch default arguments */
- {
- Parm *rp = nextSibling(p);
- while (rp) {
- String *rvalue = Getattr(rp, "value");
- if (rvalue) {
- Replace(rvalue, name, dvalue, DOH_REPLACE_ID);
- }
- rp = nextSibling(rp);
- }
- }
- sz = Len(patchlist);
- for (i = 0; i < sz; i++) {
- String *s = Getitem(patchlist, i);
- Replace(s, name, dvalue, DOH_REPLACE_ID);
- }
- sz = Len(typelist);
- for (i = 0; i < sz; i++) {
- String *s = Getitem(typelist, i);
- /*
- The approach of 'trivially' replacing template arguments is kind of fragile.
- In particular if types with similar name in different namespaces appear.
- We will not replace template args if a type/class exists with the same
- name which is not a template.
- */
- Node * tynode = Swig_symbol_clookup(s, 0);
- String *tyname = tynode ? Getattr(tynode, "sym:name") : 0;
- if (!tyname || !tsname || !Equal(tyname, tsname) || Getattr(tynode, "templatetype")) {
- SwigType_typename_replace(s, name, dvalue);
- SwigType_typename_replace(s, tbase, iname);
- }
- }
-
- tmp = NewStringf("#%s", name);
- tmpr = NewStringf("\"%s\"", valuestr);
-
- sz = Len(cpatchlist);
- for (i = 0; i < sz; i++) {
- String *s = Getitem(cpatchlist, i);
- Replace(s, tmp, tmpr, DOH_REPLACE_ID);
- Replace(s, name, valuestr, DOH_REPLACE_ID);
- }
- Delete(tmp);
- Delete(tmpr);
- Delete(valuestr);
- Delete(dvalue);
- Delete(qvalue);
- }
- p = nextSibling(p);
- tp = nextSibling(tp);
- if (!p)
- p = tp;
- }
- } else {
- /* No template parameters at all. This could be a specialization */
- int i, sz;
- sz = Len(typelist);
- for (i = 0; i < sz; i++) {
- String *s = Getitem(typelist, i);
- SwigType_typename_replace(s, tbase, iname);
- }
- }
- }
- cparse_postprocess_expanded_template(n);
-
- /* Patch bases */
- {
- List *bases = Getattr(n, "baselist");
- if (bases) {
- Iterator b;
- for (b = First(bases); b.item; b = Next(b)) {
- String *qn = Swig_symbol_type_qualify(b.item, tscope);
- Clear(b.item);
- Append(b.item, qn);
- Delete(qn);
- }
- }
- }
- Delete(patchlist);
- Delete(cpatchlist);
- Delete(typelist);
- Delete(tbase);
- Delete(tname);
- Delete(templateargs);
-
- /* set_nodeType(n,"template"); */
- return 0;
-}
-
-typedef enum { ExactNoMatch = -2, PartiallySpecializedNoMatch = -1, PartiallySpecializedMatch = 1, ExactMatch = 2 } EMatch;
-
-/* -----------------------------------------------------------------------------
- * does_parm_match()
- *
- * Template argument deduction - check if a template type matches a partially specialized
- * template parameter type. Typedef reduce 'partial_parm_type' to see if it matches 'type'.
- *
- * type - template parameter type to match against
- * partial_parm_type - partially specialized template type - a possible match
- * partial_parm_type_base - base type of partial_parm_type
- * tscope - template scope
- * specialization_priority - (output) contains a value indicating how good the match is
- * (higher is better) only set if return is set to PartiallySpecializedMatch or ExactMatch.
- * ----------------------------------------------------------------------------- */
-
-static EMatch does_parm_match(SwigType *type, SwigType *partial_parm_type, const char *partial_parm_type_base, Symtab *tscope, int *specialization_priority) {
- static const int EXACT_MATCH_PRIORITY = 99999; /* a number bigger than the length of any conceivable type */
- int matches;
- int substitutions;
- EMatch match;
- SwigType *ty = Swig_symbol_typedef_reduce(type, tscope);
- String *base = SwigType_base(ty);
- SwigType *t = Copy(partial_parm_type);
- substitutions = Replaceid(t, partial_parm_type_base, base); /* eg: Replaceid("p.$1", "$1", "int") returns t="p.int" */
- matches = Equal(ty, t);
- *specialization_priority = -1;
- if (substitutions == 1) {
- /* we have a non-explicit specialized parameter (in partial_parm_type) because a substitution for $1, $2... etc has taken place */
- SwigType *tt = Copy(partial_parm_type);
- int len;
- /*
- check for match to partial specialization type, for example, all of the following could match the type in the %template:
- template <typename T> struct XX {};
- template <typename T> struct XX<T &> {}; // r.$1
- template <typename T> struct XX<T const&> {}; // r.q(const).$1
- template <typename T> struct XX<T *const&> {}; // r.q(const).p.$1
- %template(XXX) XX<int *const&>; // r.q(const).p.int
-
- where type="r.q(const).p.int" will match either of tt="r.", tt="r.q(const)" tt="r.q(const).p"
- */
- Replaceid(tt, partial_parm_type_base, ""); /* remove the $1, $2 etc, eg tt="p.$1" => "p." */
- len = Len(tt);
- if (Strncmp(tt, ty, len) == 0) {
- match = PartiallySpecializedMatch;
- *specialization_priority = len;
- } else {
- match = PartiallySpecializedNoMatch;
- }
- Delete(tt);
- } else {
- match = matches ? ExactMatch : ExactNoMatch;
- if (matches)
- *specialization_priority = EXACT_MATCH_PRIORITY; /* exact matches always take precedence */
- }
- /*
- Printf(stdout, " does_parm_match %2d %5d [%s] [%s]\n", match, *specialization_priority, type, partial_parm_type);
- */
- Delete(t);
- Delete(base);
- Delete(ty);
- return match;
-}
-
-/* -----------------------------------------------------------------------------
- * template_locate()
- *
- * Search for a template that matches name with given parameters.
- * ----------------------------------------------------------------------------- */
-
-static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) {
- Node *n = 0;
- String *tname = 0;
- Node *templ;
- Symtab *primary_scope = 0;
- List *possiblepartials = 0;
- Parm *p;
- Parm *parms = 0;
- Parm *targs;
- ParmList *expandedparms;
- int *priorities_matrix = 0;
- int max_possible_partials = 0;
- int posslen = 0;
-
- /* Search for primary (unspecialized) template */
- templ = Swig_symbol_clookup(name, 0);
-
- if (template_debug) {
- tname = Copy(name);
- SwigType_add_template(tname, tparms);
- Printf(stdout, "\n");
- Swig_diagnostic(cparse_file, cparse_line, "template_debug: Searching for match to: '%s'\n", tname);
- Delete(tname);
- tname = 0;
- }
-
- if (templ) {
- tname = Copy(name);
- parms = CopyParmList(tparms);
-
- /* All template specializations must be in the primary template's scope, store the symbol table for this scope for specialization lookups */
- primary_scope = Getattr(templ, "sym:symtab");
-
- /* Add default values from primary template */
- targs = Getattr(templ, "templateparms");
- expandedparms = Swig_symbol_template_defargs(parms, targs, tscope, primary_scope);
-
- /* reduce the typedef */
- p = expandedparms;
- while (p) {
- SwigType *ty = Getattr(p, "type");
- if (ty) {
- SwigType *nt = Swig_symbol_type_qualify(ty, tscope);
- Setattr(p, "type", nt);
- Delete(nt);
- }
- p = nextSibling(p);
- }
- SwigType_add_template(tname, expandedparms);
-
- /* Search for an explicit (exact) specialization. Example: template<> class name<int> { ... } */
- {
- if (template_debug) {
- Printf(stdout, " searching for : '%s' (explicit specialization)\n", tname);
- }
- n = Swig_symbol_clookup_local(tname, primary_scope);
- if (!n) {
- SwigType *rname = Swig_symbol_typedef_reduce(tname, tscope);
- if (!Equal(rname, tname)) {
- if (template_debug) {
- Printf(stdout, " searching for : '%s' (explicit specialization with typedef reduction)\n", rname);
- }
- n = Swig_symbol_clookup_local(rname, primary_scope);
- }
- Delete(rname);
- }
- if (n) {
- Node *tn;
- String *nodeType = nodeType(n);
- if (Equal(nodeType, "template")) {
- if (template_debug) {
- Printf(stdout, " explicit specialization found: '%s'\n", Getattr(n, "name"));
- }
- goto success;
- }
- tn = Getattr(n, "template");
- if (tn) {
- if (template_debug) {
- Printf(stdout, " previous instantiation found: '%s'\n", Getattr(n, "name"));
- }
- n = tn;
- goto success; /* Previously wrapped by a template instantiation */
- }
- Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType(n));
- Delete(tname);
- Delete(parms);
- return 0; /* Found a match, but it's not a template of any kind. */
- }
- }
-
- /* Search for partial specializations.
- * Example: template<typename T> class name<T *> { ... }
-
- * There are 3 types of template arguments:
- * (1) Template type arguments
- * (2) Template non type arguments
- * (3) Template template arguments
- * only (1) is really supported for partial specializations
- */
-
- /* Rank each template parameter against the desired template parameters then build a matrix of best matches */
- possiblepartials = NewList();
- {
- char tmp[32];
- List *partials;
-
- partials = Getattr(templ, "partials"); /* note that these partial specializations do not include explicit specializations */
- if (partials) {
- Iterator pi;
- int parms_len = ParmList_len(parms);
- int *priorities_row;
- max_possible_partials = Len(partials);
- priorities_matrix = (int *)Malloc(sizeof(int) * max_possible_partials * parms_len); /* slightly wasteful allocation for max possible matches */
- priorities_row = priorities_matrix;
- for (pi = First(partials); pi.item; pi = Next(pi)) {
- Parm *p = parms;
- int all_parameters_match = 1;
- int i = 1;
- Parm *partialparms = Getattr(pi.item, "partialparms");
- Parm *pp = partialparms;
- String *templcsymname = Getattr(pi.item, "templcsymname");
- if (template_debug) {
- Printf(stdout, " checking match: '%s' (partial specialization)\n", templcsymname);
- }
- if (ParmList_len(partialparms) == parms_len) {
- while (p && pp) {
- SwigType *t;
- sprintf(tmp, "$%d", i);
- t = Getattr(p, "type");
- if (!t)
- t = Getattr(p, "value");
- if (t) {
- EMatch match = does_parm_match(t, Getattr(pp, "type"), tmp, tscope, priorities_row + i - 1);
- if (match < (int)PartiallySpecializedMatch) {
- all_parameters_match = 0;
- break;
- }
- }
- i++;
- p = nextSibling(p);
- pp = nextSibling(pp);
- }
- if (all_parameters_match) {
- Append(possiblepartials, pi.item);
- priorities_row += parms_len;
- }
- }
- }
- }
- }
-
- posslen = Len(possiblepartials);
- if (template_debug) {
- int i;
- if (posslen == 0)
- Printf(stdout, " matched partials: NONE\n");
- else if (posslen == 1)
- Printf(stdout, " chosen partial: '%s'\n", Getattr(Getitem(possiblepartials, 0), "templcsymname"));
- else {
- Printf(stdout, " possibly matched partials:\n");
- for (i = 0; i < posslen; i++) {
- Printf(stdout, " '%s'\n", Getattr(Getitem(possiblepartials, i), "templcsymname"));
- }
- }
- }
-
- if (posslen > 1) {
- /* Now go through all the possibly matched partial specialization templates and look for a non-ambiguous match.
- * Exact matches rank the highest and deduced parameters are ranked by how specialized they are, eg looking for
- * a match to const int *, the following rank (highest to lowest):
- * const int * (exact match)
- * const T *
- * T *
- * T
- *
- * An ambiguous example when attempting to match as either specialization could match: %template() X<int *, double *>;
- * template<typename T1, typename T2> X class {}; // primary template
- * template<typename T1> X<T1, double *> class {}; // specialization (1)
- * template<typename T2> X<int *, T2> class {}; // specialization (2)
- */
- if (template_debug) {
- int row, col;
- int parms_len = ParmList_len(parms);
- Printf(stdout, " parameter priorities matrix (%d parms):\n", parms_len);
- for (row = 0; row < posslen; row++) {
- int *priorities_row = priorities_matrix + row*parms_len;
- Printf(stdout, " ");
- for (col = 0; col < parms_len; col++) {
- Printf(stdout, "%5d ", priorities_row[col]);
- }
- Printf(stdout, "\n");
- }
- }
- {
- int row, col;
- int parms_len = ParmList_len(parms);
- /* Printf(stdout, " parameter priorities inverse matrix (%d parms):\n", parms_len); */
- for (col = 0; col < parms_len; col++) {
- int *priorities_col = priorities_matrix + col;
- int maxpriority = -1;
- /*
- Printf(stdout, "max_possible_partials: %d col:%d\n", max_possible_partials, col);
- Printf(stdout, " ");
- */
- /* determine the highest rank for this nth parameter */
- for (row = 0; row < posslen; row++) {
- int *element_ptr = priorities_col + row*parms_len;
- int priority = *element_ptr;
- if (priority > maxpriority)
- maxpriority = priority;
- /* Printf(stdout, "%5d ", priority); */
- }
- /* Printf(stdout, "\n"); */
- /* flag all the parameters which equal the highest rank */
- for (row = 0; row < posslen; row++) {
- int *element_ptr = priorities_col + row*parms_len;
- int priority = *element_ptr;
- *element_ptr = (priority >= maxpriority) ? 1 : 0;
- }
- }
- }
- {
- int row, col;
- int parms_len = ParmList_len(parms);
- Iterator pi = First(possiblepartials);
- Node *chosenpartials = NewList();
- if (template_debug)
- Printf(stdout, " priority flags matrix:\n");
- for (row = 0; row < posslen; row++) {
- int *priorities_row = priorities_matrix + row*parms_len;
- int highest_count = 0; /* count of highest priority parameters */
- for (col = 0; col < parms_len; col++) {
- highest_count += priorities_row[col];
- }
- if (template_debug) {
- Printf(stdout, " ");
- for (col = 0; col < parms_len; col++) {
- Printf(stdout, "%5d ", priorities_row[col]);
- }
- Printf(stdout, "\n");
- }
- if (highest_count == parms_len) {
- Append(chosenpartials, pi.item);
- }
- pi = Next(pi);
- }
- if (Len(chosenpartials) > 0) {
- /* one or more best match found */
- Delete(possiblepartials);
- possiblepartials = chosenpartials;
- posslen = Len(possiblepartials);
- } else {
- /* no best match found */
- Delete(chosenpartials);
- }
- }
- }
-
- if (posslen > 0) {
- String *s = Getattr(Getitem(possiblepartials, 0), "templcsymname");
- n = Swig_symbol_clookup_local(s, primary_scope);
- if (posslen > 1) {
- int i;
- if (n) {
- Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, cparse_file, cparse_line, "Instantiation of template '%s' is ambiguous,\n", SwigType_namestr(tname));
- Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, Getfile(n), Getline(n), " instantiation '%s' used,\n", SwigType_namestr(Getattr(n, "name")));
- }
- for (i = 1; i < posslen; i++) {
- String *templcsymname = Getattr(Getitem(possiblepartials, i), "templcsymname");
- Node *ignored_node = Swig_symbol_clookup_local(templcsymname, primary_scope);
- assert(ignored_node);
- Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, Getfile(ignored_node), Getline(ignored_node), " instantiation '%s' ignored.\n", SwigType_namestr(Getattr(ignored_node, "name")));
- }
- }
- }
-
- if (!n) {
- if (template_debug) {
- Printf(stdout, " chosen primary template: '%s'\n", Getattr(templ, "name"));
- }
- n = templ;
- }
- } else {
- if (template_debug) {
- Printf(stdout, " primary template not found\n");
- }
- /* Give up if primary (unspecialized) template not found as specializations will only exist if there is a primary template */
- n = 0;
- }
-
- if (!n) {
- Swig_error(cparse_file, cparse_line, "Template '%s' undefined.\n", name);
- } else if (n) {
- String *nodeType = nodeType(n);
- if (!Equal(nodeType, "template")) {
- Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType);
- n = 0;
- }
- }
-success:
- Delete(tname);
- Delete(possiblepartials);
- if ((template_debug) && (n)) {
- /*
- Printf(stdout, "Node: %p\n", n);
- Swig_print_node(n);
- */
- Printf(stdout, " chosen template:'%s'\n", Getattr(n, "name"));
- }
- Delete(parms);
- Free(priorities_matrix);
- return n;
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_cparse_template_locate()
- *
- * Search for a template that matches name with given parameters.
- * For templated classes finds the specialized template should there be one.
- * For templated functions finds the unspecialized template even if a specialized
- * template exists.
- * ----------------------------------------------------------------------------- */
-
-Node *Swig_cparse_template_locate(String *name, Parm *tparms, Symtab *tscope) {
- Node *n = template_locate(name, tparms, tscope); /* this function does what we want for templated classes */
-
- if (n) {
- String *nodeType = nodeType(n);
- int isclass = 0;
- assert(Equal(nodeType, "template"));
- (void)nodeType;
- isclass = (Equal(Getattr(n, "templatetype"), "class"));
- if (!isclass) {
- /* If not a templated class we must have a templated function.
- The template found is not necessarily the one we want when dealing with templated
- functions. We don't want any specialized templated functions as they won't have
- the default parameters. Let's look for the unspecialized template. Also make sure
- the number of template parameters is correct as it is possible to overload a
- templated function with different numbers of template parameters. */
-
- if (template_debug) {
- Printf(stdout, " Not a templated class, seeking most appropriate templated function\n");
- }
-
- n = Swig_symbol_clookup_local(name, 0);
- while (n) {
- Parm *tparmsfound = Getattr(n, "templateparms");
- if (ParmList_len(tparms) == ParmList_len(tparmsfound)) {
- /* successful match */
- break;
- }
- /* repeat until we find a match with correct number of templated parameters */
- n = Getattr(n, "sym:nextSibling");
- }
-
- if (!n) {
- Swig_error(cparse_file, cparse_line, "Template '%s' undefined.\n", name);
- }
-
- if ((template_debug) && (n)) {
- Printf(stdout, "Templated function found: %p\n", n);
- Swig_print_node(n);
- }
- }
- }
-
- return n;
-}
diff --git a/contrib/tools/swig/Source/CParse/util.c b/contrib/tools/swig/Source/CParse/util.c
deleted file mode 100644
index 00863c0357..0000000000
--- a/contrib/tools/swig/Source/CParse/util.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * util.c
- *
- * Parsing utilities.
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-#include "cparse.h"
-
-/* -----------------------------------------------------------------------------
- * Swig_cparse_replace_descriptor()
- *
- * Replaces type descriptor string $descriptor() with the SWIG type descriptor
- * string.
- * ----------------------------------------------------------------------------- */
-
-void Swig_cparse_replace_descriptor(String *s) {
- char tmp[512];
- String *arg = 0;
- SwigType *t;
- char *c = 0;
-
- while ((c = strstr(Char(s), "$descriptor("))) {
- char *d = tmp;
- int level = 0;
- while (*c) {
- if (*c == '(')
- level++;
- if (*c == ')') {
- level--;
- if (level == 0) {
- break;
- }
- }
- *d = *c;
- d++;
- c++;
- }
- *d = 0;
- arg = NewString(tmp + 12);
- t = Swig_cparse_type(arg);
- Delete(arg);
- arg = 0;
-
- if (t) {
- String *mangle;
- String *descriptor;
-
- mangle = SwigType_manglestr(t);
- descriptor = NewStringf("SWIGTYPE%s", mangle);
- SwigType_remember(t);
- *d = ')';
- d++;
- *d = 0;
- Replace(s, tmp, descriptor, DOH_REPLACE_ANY);
- Delete(mangle);
- Delete(descriptor);
- Delete(t);
- } else {
- Swig_error(Getfile(s), Getline(s), "Bad $descriptor() macro.\n");
- break;
- }
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_cparse_smartptr()
- *
- * Parse the type in smartptr feature and convert into a SwigType.
- * Error out if the parsing fails as this is like a parser syntax error.
- * ----------------------------------------------------------------------------- */
-
-SwigType *Swig_cparse_smartptr(Node *n) {
- SwigType *smart = 0;
- String *smartptr = Getattr(n, "feature:smartptr");
- if (smartptr) {
- SwigType *cpt = Swig_cparse_type(smartptr);
- if (cpt) {
- smart = SwigType_typedef_resolve_all(cpt);
- Delete(cpt);
- } else {
- Swig_error(Getfile(n), Getline(n), "Invalid type (%s) in 'smartptr' feature for class %s.\n", smartptr, SwigType_namestr(Getattr(n, "name")));
- }
- }
- return smart;
-}
-
-/* -----------------------------------------------------------------------------
- * cparse_normalize_void()
- *
- * This function is used to replace arguments of the form (void) with empty
- * arguments in C++
- * ----------------------------------------------------------------------------- */
-
-void cparse_normalize_void(Node *n) {
- String *decl = Getattr(n, "decl");
- Parm *parms = Getattr(n, "parms");
-
- if (SwigType_isfunction(decl)) {
- if ((ParmList_len(parms) == 1) && (SwigType_type(Getattr(parms, "type")) == T_VOID)) {
- Replaceall(decl, "f(void).", "f().");
- Delattr(n, "parms");
- }
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_cparse_new_node()
- *
- * Create an empty parse node, setting file and line number information
- * ----------------------------------------------------------------------------- */
-
-Node *Swig_cparse_new_node(const_String_or_char_ptr tag) {
- Node *n = NewHash();
- set_nodeType(n,tag);
- Setfile(n,cparse_file);
- Setline(n,cparse_line);
- return n;
-}
diff --git a/contrib/tools/swig/Source/DOH/README b/contrib/tools/swig/Source/DOH/README
deleted file mode 100644
index be90f25b46..0000000000
--- a/contrib/tools/swig/Source/DOH/README
+++ /dev/null
@@ -1,124 +0,0 @@
-DOH (Dave's Object Hack)
-
-Overview:
----------
-DOH is a small C library that provides a number of simple yet powerful
-data structures. The data structures are built around a dynamic typing
-model in which any given object is allowed to support one or more
-classes of operations. Furthermore, a simple garbage collection
-scheme and a variety of interesting library methods are available.
-All and all, the operation of DOH makes massive abuse of the C type
-system and would probably make the language purists scream and
-performance addicts run away in horror. However, I really don't
-care--so there! However, for the rest of us, DOH is actually kind of
-fun to use. This is only a short description of the methods and is no
-way meant to be exhaustive.
-
-Common Operations (for all types)
----------------------------------
-Delete(obj) Decrease the reference count and destroy if zero
-Copy(obj) Make a copy of an object.
-Clear(obj) Clear an object.
-Setscope(obj) Set scope of an object (guru's only)
-Str(obj) Create a string representation of obj.
-Data(obj) Return pointer to raw data in an object
-Char(obj) Convert to a char *
-Len(obj) Length of an object
-Hash(obj) Hash value (used for mapping)
-Cmp(obj1,obj2) Compare two objects.
-Name(obj) Return the object name
-First(obj) Return first object (iterator)
-Next(obj) Return next object
-Dump(obj,out) Serialize on out
-Load(in) Unserialize from in
-First(obj) Iterator
-Next(iter) Next iterator
-
-Mapping Operations (for hash table behavior)
---------------------------------------------
-Getattr(hash,key) Get an attribute
-Setattr(hash,key,value) Set an attribute
-Delattr(hash,key) Delete an attribute
-First(hash) Get first object (iterator)
-Next(hash) Get next object
-GetInt(hash,key) Get attribute as an 'int'
-SetInt(hash,key,ivalue) Set attribute as an 'int'
-GetDouble(hash,key) Get attribute as a 'double'
-SetDouble(hash,key,dvalue) Set Attribute as a 'double'
-GetChar(hash,key) Get attribute as a 'char *'
-
-Sequence Operations
--------------------
-Getitem(list,index) Get an item
-Setitem(list,index,val) Set an item
-Delitem(list,index) Delete an item
-Insert(list,index,val) Insert an item
-Append(list,val) Append to end
-Push(list,val) Insert at beginning
-
-File Operations
----------------
-Read(obj,buffer,len) Read data
-Write(obj,buffer,len) Write data
-Getc(obj) Get a character
-Putc(ch,obj) Put a character
-Ungetc(ch,obj) Put character back on input stream
-Seek(obj,offset,whence) Seek
-Tell(obj) Return file pointer
-Delete(obj) Decrease the reference count, close file if zero
-
-String Operations
------------------
-Replace(obj, orig, rep, flags) Replace occurrences of orig with rep.
-Chop(obj) Remove trailing whitespace
-
-flags is one of the following:
- DOH_REPLACE_ID
- DOH_REPLACE_ID_BEGIN
- DOH_REPLACE_ID_END
- DOH_REPLACE_NUMBER_END
-
-and can be combined with one or more of the following:
- DOH_REPLACE_ANY
- DOH_REPLACE_NOQUOTE
- DOH_REPLACE_NOCOMMENT
- DOH_REPLACE_FIRST
-
-Callable Operations
--------------------
-Call(obj, args) Perform a function call with arguments args.
-
-Miscellaneous library functions
--------------------------------
-NewScope() Create a new scope
-DelScope(s) Delete scope s
-Readline(in) Read a line of input from in
-Printf(out,fmt,...) Formatted output
-DohEncoding(name, fn) Register a format encoding for Printf
-
-Currently Available datatypes
-------------------------------
-NewString(char *initial) Strings
-NewHash() Hash
-NewList() List
-NewVoid(void *ptr, void (*del)(void *)) Void
-NewFile(char *filename, char *mode, List *newfiles) File
-NewCallable(DOH *(*func)(DOH *, DOH *)) Callable object
-
-
-Odds and ends:
-
- 1. All objects are of type 'DOH *'
- 2. When in doubt, see rule (1)
- 3. In certain cases, DOH performs implicit conversions
- of 'char *' to an appropriate DOH string representation.
- For operations involving files, DOH works with many
- kinds of objects including FILE *, DOH File objects,
- and DOH strings. Don't even ask how this works.
-
- 4. More complete documentation is forthcoming.
-
-
-
-
-
diff --git a/contrib/tools/swig/Source/DOH/base.c b/contrib/tools/swig/Source/DOH/base.c
deleted file mode 100644
index 8731a5f118..0000000000
--- a/contrib/tools/swig/Source/DOH/base.c
+++ /dev/null
@@ -1,937 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * base.c
- *
- * This file contains the function entry points for dispatching methods on
- * DOH objects. A number of small utility functions are also included.
- * ----------------------------------------------------------------------------- */
-
-#include "dohint.h"
-
-/* -----------------------------------------------------------------------------
- * DohDelete()
- * ----------------------------------------------------------------------------- */
-
-void DohDelete(DOH *obj) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo;
-
- if (!obj)
- return;
- if (!DohCheck(b)) {
- fputs("Fatal internal error: Attempt to delete a non-DOH object.\n", stderr);
- Exit(EXIT_FAILURE);
- }
- if (b->flag_intern)
- return;
- assert(b->refcount > 0);
- b->refcount--;
- if (b->refcount <= 0) {
- objinfo = b->type;
- if (objinfo->doh_del) {
- (objinfo->doh_del) (b);
- } else {
- if (b->data)
- DohFree(b->data);
- }
- DohObjFree(b);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * DohCopy()
- * ----------------------------------------------------------------------------- */
-
-DOH *DohCopy(const DOH *obj) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo;
-
- if (!obj)
- return 0;
- if (!DohCheck(b)) {
- fputs("Fatal internal error: Attempt to copy a non-DOH object.\n", stderr);
- Exit(EXIT_FAILURE);
- }
- objinfo = b->type;
- if (objinfo->doh_copy) {
- DohBase *bc = (DohBase *) (objinfo->doh_copy) (b);
- if ((bc) && b->meta) {
- bc->meta = Copy(b->meta);
- }
- return (DOH *) bc;
- }
- return 0;
-}
-
-void DohIncref(DOH *obj) {
- Incref(obj);
-}
-
-/* -----------------------------------------------------------------------------
- * DohClear()
- * ----------------------------------------------------------------------------- */
-
-void DohClear(DOH *obj) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = b->type;
- if (objinfo->doh_clear)
- (objinfo->doh_clear) (b);
-}
-
-/* -----------------------------------------------------------------------------
- * DohStr()
- * ----------------------------------------------------------------------------- */
-
-DOH *DohStr(const DOH *obj) {
- char buffer[512];
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo;
- if (DohCheck(b)) {
- objinfo = b->type;
- if (objinfo->doh_str) {
- return (objinfo->doh_str) (b);
- }
- sprintf(buffer, "<Object '%s' at %p>", objinfo->objname, (void *) b);
- return NewString(buffer);
- } else {
- return NewString(obj);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * DohDump()
- * ----------------------------------------------------------------------------- */
-
-int DohDump(const DOH *obj, DOH *out) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = b->type;
- if (objinfo->doh_dump) {
- return (objinfo->doh_dump) (b, out);
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * DohLen() - Defaults to strlen() if not a DOH object
- * ----------------------------------------------------------------------------- */
-int DohLen(const DOH *obj) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo;
- if (!b)
- return 0;
- if (DohCheck(b)) {
- objinfo = b->type;
- if (objinfo->doh_len) {
- return (objinfo->doh_len) (b);
- }
- return 0;
- } else {
- return (int)strlen((char *) obj);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * DohHashVal()
- * ----------------------------------------------------------------------------- */
-
-int DohHashval(const DOH *obj) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo;
- /* obj is already checked and/or converted into DohBase* */
- /* if (DohCheck(b)) */
- {
- objinfo = b->type;
- if (objinfo->doh_hashval) {
- return (objinfo->doh_hashval) (b);
- }
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * DohData()
- * ----------------------------------------------------------------------------- */
-
-void *DohData(const DOH *obj) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo;
- if (DohCheck(obj)) {
- objinfo = b->type;
- if (objinfo->doh_data) {
- return (objinfo->doh_data) (b);
- }
- return 0;
- }
- return (void *) obj;
-}
-
-/* -----------------------------------------------------------------------------
- * RawData()
- * ----------------------------------------------------------------------------- */
-
-static void *RawData(DohBase *b) {
- DohObjInfo *objinfo = b->type;
- return (objinfo->doh_data) ? (objinfo->doh_data) (b) : 0;
-}
-
-
-/* -----------------------------------------------------------------------------
- * DohCmp()
- * ----------------------------------------------------------------------------- */
-
-int DohCmp(const DOH *obj1, const DOH *obj2) {
- DohBase *b1, *b2;
- DohObjInfo *b1info, *b2info;
- int c1, c2;
- b1 = (DohBase *) obj1;
- b2 = (DohBase *) obj2;
- c1 = DohCheck(b1);
- c2 = DohCheck(b2);
- /* most of the times, obj2 is a plain c string */
- if (!c1 || !c2) {
- if ((b1 == 0) && (b2 == 0))
- return 0;
- if (b1 && !b2)
- return 1;
- if (!b1 && b2)
- return -1;
- return strcmp((char *) (c1 ? RawData(b1) : (void *) obj1), (char *) (c2 ? RawData(b2) : (void *) obj2));
- }
- b1info = b1->type;
- b2info = b2->type;
- if ((b1info == b2info) && (b1info->doh_cmp))
- return (b1info->doh_cmp) (b1, b2);
- return 1;
-}
-
-/* -----------------------------------------------------------------------------
- * DohEqual()
- * ----------------------------------------------------------------------------- */
-
-int DohEqual(const DOH *obj1, const DOH *obj2) {
- DohBase *b1 = (DohBase *) obj1;
- DohBase *b2 = (DohBase *) obj2;
- if (!b1) {
- return !b2;
- } else if (!b2) {
- return 0;
- } else {
- DohObjInfo *b1info = 0;
- DohObjInfo *b2info = 0;
- if (DohCheck(b1)) {
- b1info = b1->type;
- if (DohCheck(b2)) {
- b2info = b2->type;
- } else {
- int len = (b1info->doh_len) (b1);
- char *cobj = (char *) obj2;
- return len == (int) strlen(cobj) ? (memcmp(RawData(b1), cobj, len) == 0) : 0;
- }
- } else if (DohCheck(b2)) {
- int len = (b2->type->doh_len) (b2);
- char *cobj = (char *) obj1;
- return len == (int) strlen(cobj) ? (memcmp(RawData(b2), cobj, len) == 0) : 0;
- } else {
- return strcmp((char *) obj1, (char *) obj2) == 0;
- }
-
- if (!b1info) {
- return obj1 == obj2;
- } else if (b1info == b2info) {
- return b1info->doh_equal ? (b1info->doh_equal) (b1, b2) : (b1info->doh_cmp ? (b1info->doh_cmp) (b1, b2) == 0 : (b1 == b2));
- } else {
- return 0;
- }
- }
-}
-
-/* -----------------------------------------------------------------------------
- * DohFirst()
- * ----------------------------------------------------------------------------- */
-
-DohIterator DohFirst(DOH *obj) {
- DohIterator iter;
- DohBase *b;
- DohObjInfo *binfo;
-
- b = (DohBase *) obj;
- if (DohCheck(b)) {
- binfo = b->type;
- if (binfo->doh_first) {
- return (binfo->doh_first) (b);
- }
- }
- iter.object = 0;
- iter.item = 0;
- iter.key = 0;
- iter._current = 0;
- iter._index = 0;
- return iter;
-}
-
-/* -----------------------------------------------------------------------------
- * DohNext()
- * ----------------------------------------------------------------------------- */
-
-DohIterator DohNext(DohIterator iter) {
- DohIterator niter;
-
- if (iter.object) {
- DohBase *b;
- DohObjInfo *binfo;
-
- b = (DohBase *) iter.object;
- binfo = b->type;
- if (binfo->doh_next) {
- return (binfo->doh_next) (iter);
- }
- }
- niter = iter;
- return niter;
-}
-
-/* -----------------------------------------------------------------------------
- * DohIsMapping()
- * ----------------------------------------------------------------------------- */
-int DohIsMapping(const DOH *obj) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo;
- if (!DohCheck(b))
- return 0;
- objinfo = b->type;
- if (objinfo->doh_hash)
- return 1;
- else
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * DohGetattr()
- * ----------------------------------------------------------------------------- */
-
-DOH *DohGetattr(DOH *obj, const DOH *name) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = b->type;
- if (objinfo->doh_hash && objinfo->doh_hash->doh_getattr) {
- DOH *r = (objinfo->doh_hash->doh_getattr) (b, (DOH *) name);
- return (r == DohNone) ? 0 : r;
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * DohSetattr()
- * ----------------------------------------------------------------------------- */
-
-int DohSetattr(DOH *obj, const DOH *name, const DOH *value) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = b->type;
- if (objinfo->doh_hash && objinfo->doh_hash->doh_setattr) {
- return (objinfo->doh_hash->doh_setattr) (b, (DOH *) name, (DOH *) value);
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * DohDelattr()
- * ----------------------------------------------------------------------------- */
-
-int DohDelattr(DOH *obj, const DOH *name) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = b->type;
- if (objinfo->doh_hash && objinfo->doh_hash->doh_delattr) {
- return (objinfo->doh_hash->doh_delattr) (b, (DOH *) name);
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * DohCheckattr()
- * ----------------------------------------------------------------------------- */
-
-int DohCheckattr(DOH *obj, const DOH *name, const DOH *value) {
- DOH *attr = Getattr(obj,name);
- if (!attr) return 0;
- return DohEqual(attr,value);
-}
-
-/* -----------------------------------------------------------------------------
- * DohKeys()
- * ----------------------------------------------------------------------------- */
-
-DOH *DohKeys(DOH *obj) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = b->type;
- if (objinfo && objinfo->doh_hash->doh_keys) {
- return (objinfo->doh_hash->doh_keys) (b);
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * DohSortedKeys()
- * ----------------------------------------------------------------------------- */
-
-DOH *DohSortedKeys(DOH *obj, int (*cmp) (const DOH *, const DOH *)) {
- DOHList *keys = DohKeys(obj);
- if (keys) {
- DohSortList(keys, cmp);
- }
- return keys;
-}
-
-/* -----------------------------------------------------------------------------
- * DohGetInt()
- * ----------------------------------------------------------------------------- */
-
-int DohGetInt(DOH *obj, const DOH *name) {
- DOH *val;
- val = Getattr(obj, (DOH *) name);
- if (!val)
- return 0;
- if (DohIsString(val)) {
- return atoi((char *) Data(val));
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * DohGetDouble()
- * ----------------------------------------------------------------------------- */
-
-double DohGetDouble(DOH *obj, const DOH *name) {
- DOH *val;
- val = Getattr(obj, (DOH *) name);
- if (!val)
- return 0;
- if (DohIsString(val)) {
- return atof((char *) Data(val));
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * DohGetChar()
- * ----------------------------------------------------------------------------- */
-
-char *DohGetChar(DOH *obj, const DOH *name) {
- DOH *val;
- val = Getattr(obj, (DOH *) name);
- if (!val)
- return 0;
- if (DohIsString(val)) {
- return (char *) Data(val);
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * DohGetFlagAttr() / DohGetFlag()
- * A flag is unset if the attribute (name) does not exist on the node (obj),
- * or it is set to "0". If the attribute is set to any other value,
- * the flag is set.
- *
- * DohGetFlag() returns if the flag is set or not
- * DohGetFlagAttr() returns the flag value if is set, NULL otherwise
- * ----------------------------------------------------------------------------- */
-
-
-DOH *DohGetFlagAttr(DOH *obj, const DOH *name) {
- DOH *val = Getattr(obj, (DOH *) name);
- if (!val) {
- return NULL;
- } else {
- const char *cval = Char(val);
- if (!cval)
- return val;
- return (strcmp(cval, "0") != 0) ? val : NULL;
- }
-}
-
-int DohGetFlag(DOH *obj, const DOH *name) {
- return DohGetFlagAttr(obj, name) ? 1 : 0;
-}
-
-
-/* -----------------------------------------------------------------------------
- * DohGetVoid()
- * ----------------------------------------------------------------------------- */
-
-void *DohGetVoid(DOH *obj, const DOH *name) {
- DOH *val;
- val = Getattr(obj, (DOH *) name);
- if (!val)
- return 0;
- return (void *) Data(val);
-}
-
-/* -----------------------------------------------------------------------------
- * DohSetInt()
- * ----------------------------------------------------------------------------- */
-
-void DohSetInt(DOH *obj, const DOH *name, int value) {
- DOH *temp;
- temp = NewStringEmpty();
- Printf(temp, "%d", value);
- Setattr(obj, (DOH *) name, temp);
-}
-
-/* -----------------------------------------------------------------------------
- * DohSetDouble()
- * ----------------------------------------------------------------------------- */
-
-void DohSetDouble(DOH *obj, const DOH *name, double value) {
- DOH *temp;
- temp = NewStringEmpty();
- Printf(temp, "%0.17f", value);
- Setattr(obj, (DOH *) name, temp);
-}
-
-/* -----------------------------------------------------------------------------
- * DohSetChar()
- * ----------------------------------------------------------------------------- */
-
-void DohSetChar(DOH *obj, const DOH *name, char *value) {
- Setattr(obj, (DOH *) name, NewString(value));
-}
-
-/* -----------------------------------------------------------------------------
- * DohSetFlag()
- * ----------------------------------------------------------------------------- */
-
-void DohSetFlagAttr(DOH *obj, const DOH *name, const DOH *attr) {
- Setattr(obj, (DOH *) name, attr ? attr : NewString("0"));
-}
-
-void DohSetFlag(DOH *obj, const DOH *name) {
- Setattr(obj, (DOH *) name, NewString("1"));
-}
-
-/* -----------------------------------------------------------------------------
- * DohSetVoid()
- * ----------------------------------------------------------------------------- */
-
-void DohSetVoid(DOH *obj, const DOH *name, void *value) {
- Setattr(obj, (DOH *) name, NewVoid(value, 0));
-}
-
-/* -----------------------------------------------------------------------------
- * DohIsSequence()
- * ----------------------------------------------------------------------------- */
-
-int DohIsSequence(const DOH *obj) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo;
- if (!DohCheck(b))
- return 0;
- objinfo = b->type;
- if (objinfo->doh_list)
- return 1;
- else
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * DohGetitem()
- * ----------------------------------------------------------------------------- */
-
-DOH *DohGetitem(DOH *obj, int index) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = b->type;
- if (objinfo->doh_list && objinfo->doh_list->doh_getitem) {
- return (objinfo->doh_list->doh_getitem) (b, index);
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * DohSetitem()
- * ----------------------------------------------------------------------------- */
-
-int DohSetitem(DOH *obj, int index, const DOH *value) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = b->type;
- if (objinfo->doh_list && objinfo->doh_list->doh_setitem) {
- return (objinfo->doh_list->doh_setitem) (b, index, (DOH *) value);
- }
- return -1;
-}
-
-/* -----------------------------------------------------------------------------
- * DohDelitem()
- * ----------------------------------------------------------------------------- */
-
-int DohDelitem(DOH *obj, int index) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = b->type;
- if (objinfo->doh_list && objinfo->doh_list->doh_delitem) {
- return (objinfo->doh_list->doh_delitem) (b, index);
- }
- return -1;
-}
-
-/* -----------------------------------------------------------------------------
- * DohInsertitem()
- * ----------------------------------------------------------------------------- */
-
-int DohInsertitem(DOH *obj, int index, const DOH *value) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = b->type;
- if (objinfo->doh_list && objinfo->doh_list->doh_insitem) {
- return (objinfo->doh_list->doh_insitem) (b, index, (DOH *) value);
- }
- return -1;
-}
-
-
-/* -----------------------------------------------------------------------------
- * DohDelslice()
- * ----------------------------------------------------------------------------- */
-
-int DohDelslice(DOH *obj, int sindex, int eindex) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = b->type;
- if (objinfo->doh_list && objinfo->doh_list->doh_delslice) {
- return (objinfo->doh_list->doh_delslice) (b, sindex, eindex);
- }
- return -1;
-}
-
-/* -----------------------------------------------------------------------------
- * DohIsFile()
- * ----------------------------------------------------------------------------- */
-
-int DohIsFile(const DOH *obj) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo;
- if (!DohCheck(b))
- return 0;
- objinfo = b->type;
- if (objinfo->doh_file)
- return 1;
- else
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * DohRead()
- * ----------------------------------------------------------------------------- */
-
-int DohRead(DOH *obj, void *buffer, int length) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo;
- if (DohCheck(obj)) {
- objinfo = b->type;
- if ((objinfo->doh_file) && (objinfo->doh_file->doh_read)) {
- return (objinfo->doh_file->doh_read) (b, buffer, length);
- }
- return -1;
- }
- /* Hmmm. Not a file. Maybe it's a real FILE */
- return (int)fread(buffer, 1, length, (FILE *) b);
-}
-
-/* -----------------------------------------------------------------------------
- * DohWrite()
- * ----------------------------------------------------------------------------- */
-
-int DohWrite(DOH *obj, const void *buffer, int length) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo;
- if (DohCheck(obj)) {
- objinfo = b->type;
- if ((objinfo->doh_file) && (objinfo->doh_file->doh_write)) {
- return (objinfo->doh_file->doh_write) (b, buffer, length);
- }
- return -1;
- }
- /* Hmmm. Not a file. Maybe it's a real FILE */
- return (int)fwrite(buffer, 1, length, (FILE *) b);
-}
-
-/* -----------------------------------------------------------------------------
- * DohSeek()
- * ----------------------------------------------------------------------------- */
-
-int DohSeek(DOH *obj, long offset, int whence) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo;
- if (DohCheck(obj)) {
- objinfo = b->type;
- if ((objinfo->doh_file) && (objinfo->doh_file->doh_seek)) {
- return (objinfo->doh_file->doh_seek) (b, offset, whence);
- }
- return -1;
- }
- return fseek((FILE *) b, offset, whence);
-}
-
-/* -----------------------------------------------------------------------------
- * DohTell()
- * ----------------------------------------------------------------------------- */
-
-long DohTell(DOH *obj) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo;
- if (DohCheck(obj)) {
- objinfo = b->type;
- if ((objinfo->doh_file) && (objinfo->doh_file->doh_tell)) {
- return (objinfo->doh_file->doh_tell) (b);
- }
- return -1;
- }
- return ftell((FILE *) b);
-}
-
-/* -----------------------------------------------------------------------------
- * DohGetc()
- * ----------------------------------------------------------------------------- */
-
-int DohGetc(DOH *obj) {
- static DOH *lastdoh = 0;
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo;
- if (obj == lastdoh) {
- objinfo = b->type;
- return (objinfo->doh_file->doh_getc) (b);
- }
- if (DohCheck(obj)) {
- objinfo = b->type;
- if (objinfo->doh_file->doh_getc) {
- lastdoh = obj;
- return (objinfo->doh_file->doh_getc) (b);
- }
- return EOF;
- }
- return fgetc((FILE *) b);
-}
-
-/* -----------------------------------------------------------------------------
- * DohPutc()
- * ----------------------------------------------------------------------------- */
-
-int DohPutc(int ch, DOH *obj) {
- static DOH *lastdoh = 0;
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo;
-
- if (obj == lastdoh) {
- objinfo = b->type;
- return (objinfo->doh_file->doh_putc) (b, ch);
- }
- if (DohCheck(obj)) {
- objinfo = b->type;
- if (objinfo->doh_file->doh_putc) {
- lastdoh = obj;
- return (objinfo->doh_file->doh_putc) (b, ch);
- }
- return EOF;
- }
- return fputc(ch, (FILE *) b);
-}
-
-/* -----------------------------------------------------------------------------
- * DohUngetc()
- * ----------------------------------------------------------------------------- */
-
-int DohUngetc(int ch, DOH *obj) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo;
- if (DohCheck(obj)) {
- objinfo = b->type;
- if (objinfo->doh_file->doh_ungetc) {
- return (objinfo->doh_file->doh_ungetc) (b, ch);
- }
- return EOF;
- }
- return ungetc(ch, (FILE *) b);
-}
-
-/* -----------------------------------------------------------------------------
- * DohIsString()
- * ----------------------------------------------------------------------------- */
-
-int DohIsString(const DOH *obj) {
- DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo;
- if (!DohCheck(b))
- return 0;
- objinfo = b->type;
- if (objinfo->doh_string)
- return 1;
- else
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * DohReplace()
- * ----------------------------------------------------------------------------- */
-
-int DohReplace(DOH *src, const DOH *token, const DOH *rep, int flags) {
- DohBase *b = (DohBase *) src;
- DohObjInfo *objinfo;
- if (!token)
- return 0;
- if (!rep)
- rep = "";
- if (DohIsString(src)) {
- objinfo = b->type;
- if (objinfo->doh_string->doh_replace) {
- return (objinfo->doh_string->doh_replace) (b, (DOH *) token, (DOH *) rep, flags);
- }
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * DohChop()
- * ----------------------------------------------------------------------------- */
-
-void DohChop(DOH *src) {
- DohBase *b = (DohBase *) src;
- DohObjInfo *objinfo;
- if (DohIsString(src)) {
- objinfo = b->type;
- if (objinfo->doh_string->doh_chop) {
- (objinfo->doh_string->doh_chop) (b);
- }
- }
-}
-
-/* -----------------------------------------------------------------------------
- * DohSetFile()
- * ----------------------------------------------------------------------------- */
-void DohSetfile(DOH *ho, DOH *file) {
- DohBase *h = (DohBase *) ho;
- DohObjInfo *objinfo;
- if (!h)
- return;
- objinfo = h->type;
- if (objinfo->doh_setfile)
- (objinfo->doh_setfile) (h, file);
-}
-
-/* -----------------------------------------------------------------------------
- * DohGetFile()
- * ----------------------------------------------------------------------------- */
-DOH *DohGetfile(const DOH *ho) {
- DohBase *h = (DohBase *) ho;
- DohObjInfo *objinfo;
- if (!h)
- return 0;
- objinfo = h->type;
- if (objinfo->doh_getfile)
- return (objinfo->doh_getfile) (h);
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * DohSetLine()
- * ----------------------------------------------------------------------------- */
-void DohSetline(DOH *ho, int l) {
- DohBase *h = (DohBase *) ho;
- DohObjInfo *objinfo;
- if (!h)
- return;
- objinfo = h->type;
- if (objinfo->doh_setline)
- (objinfo->doh_setline) (h, l);
-}
-
-/* -----------------------------------------------------------------------------
- * DohGetLine()
- * ----------------------------------------------------------------------------- */
-int DohGetline(const DOH *ho) {
- DohBase *h = (DohBase *) ho;
- DohObjInfo *objinfo;
- if (!h)
- return 0;
- objinfo = h->type;
- if (objinfo->doh_getline)
- return (objinfo->doh_getline) (h);
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * DohGetmeta()
- * ----------------------------------------------------------------------------- */
-
-DOH *DohGetmeta(DOH *ho, const DOH *name) {
- DohBase *h = (DohBase *) ho;
- if (!DohCheck(ho))
- return 0;
- if (!h->meta)
- return 0;
- return DohGetattr(h->meta, name);
-}
-
-/* -----------------------------------------------------------------------------
- * DohGetmeta()
- * ----------------------------------------------------------------------------- */
-
-int DohSetmeta(DOH *ho, const DOH *name, const DOH *value) {
- DohBase *h = (DohBase *) ho;
- if (!DohCheck(ho))
- return 0;
- if (!h->meta)
- h->meta = NewHash();
- return DohSetattr(h->meta, name, value);
-}
-
-/* -----------------------------------------------------------------------------
- * DohDelmeta()
- * ----------------------------------------------------------------------------- */
-
-int DohDelmeta(DOH *ho, const DOH *name) {
- DohBase *h = (DohBase *) ho;
- if (!DohCheck(ho))
- return 0;
- if (!h->meta)
- return 0;
- return DohDelattr(h->meta, name);
-}
-
-/* -----------------------------------------------------------------------------
- * DohSetmark()
- * ----------------------------------------------------------------------------- */
-
-void DohSetmark(DOH *ho, int x) {
- DohBase *h = (DohBase *) ho;
- h->flag_usermark = x;
-}
-
-int DohGetmark(DOH *ho) {
- DohBase *h = (DohBase *) ho;
- return h->flag_usermark;
-}
-
-/* -----------------------------------------------------------------------------
- * DohCall()
- *
- * Invokes a function via DOH. A Function is represented by a hash table with
- * the following attributes:
- *
- * "builtin" - Pointer to built-in function (if any)
- *
- * (Additional attributes may be added later)
- *
- * Returns a DOH object with result on success. Returns NULL on error
- * ----------------------------------------------------------------------------- */
-
-DOH *DohCall(DOH *func, DOH *args) {
- DOH *result;
- DohFuncPtr_t builtin;
-
- builtin.p = GetVoid(func, "builtin");
-
- if (!builtin.p)
- return 0;
- result = (*builtin.func) (args);
- return result;
-}
diff --git a/contrib/tools/swig/Source/DOH/doh.h b/contrib/tools/swig/Source/DOH/doh.h
deleted file mode 100644
index 45a1f7fc89..0000000000
--- a/contrib/tools/swig/Source/DOH/doh.h
+++ /dev/null
@@ -1,507 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * doh.h
- *
- * This file describes of the externally visible functions in DOH.
- * ----------------------------------------------------------------------------- */
-
-#ifndef SWIG_DOH_H
-#define SWIG_DOH_H
-
-#include "swigconfig.h"
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/* Set the namespace prefix for DOH API functions. This can be used to control
- visibility of the functions in libraries */
-
-/* Set this macro if you want to change DOH linkage. You would do this if you
- wanted to hide DOH in a library using a different set of names. Note: simply
- change "Doh" to a new name. */
-
-/*
-#define DOH_NAMESPACE(x) Doh ## x
-*/
-
-#ifdef DOH_NAMESPACE
-
-/* Namespace control. These macros define all of the public API names in DOH */
-
-#define DohCheck DOH_NAMESPACE(Check)
-#define DohIntern DOH_NAMESPACE(Intern)
-#define DohDelete DOH_NAMESPACE(Delete)
-#define DohCopy DOH_NAMESPACE(Copy)
-#define DohClear DOH_NAMESPACE(Clear)
-#define DohStr DOH_NAMESPACE(Str)
-#define DohData DOH_NAMESPACE(Data)
-#define DohDump DOH_NAMESPACE(Dump)
-#define DohLen DOH_NAMESPACE(Len)
-#define DohHashval DOH_NAMESPACE(Hashval)
-#define DohCmp DOH_NAMESPACE(Cmp)
-#define DohEqual DOH_NAMESPACE(Equal)
-#define DohIncref DOH_NAMESPACE(Incref)
-#define DohCheckattr DOH_NAMESPACE(Checkattr)
-#define DohSetattr DOH_NAMESPACE(Setattr)
-#define DohDelattr DOH_NAMESPACE(Delattr)
-#define DohKeys DOH_NAMESPACE(Keys)
-#define DohSortedKeys DOH_NAMESPACE(SortedKeys)
-#define DohGetInt DOH_NAMESPACE(GetInt)
-#define DohGetDouble DOH_NAMESPACE(GetDouble)
-#define DohGetChar DOH_NAMESPACE(GetChar)
-#define DohSetChar DOH_NAMESPACE(SetChar)
-#define DohSetInt DOH_NAMESPACE(SetInt)
-#define DohSetDouble DOH_NAMESPACE(SetDouble)
-#define DohSetVoid DOH_NAMESPACE(SetVoid)
-#define DohGetVoid DOH_NAMESPACE(GetVoid)
-#define DohGetitem DOH_NAMESPACE(Getitem)
-#define DohSetitem DOH_NAMESPACE(Setitem)
-#define DohDelitem DOH_NAMESPACE(Delitem)
-#define DohInsertitem DOH_NAMESPACE(Insertitem)
-#define DohDelslice DOH_NAMESPACE(Delslice)
-#define DohWrite DOH_NAMESPACE(Write)
-#define DohRead DOH_NAMESPACE(Read)
-#define DohSeek DOH_NAMESPACE(Seek)
-#define DohTell DOH_NAMESPACE(Tell)
-#define DohGetc DOH_NAMESPACE(Getc)
-#define DohPutc DOH_NAMESPACE(Putc)
-#define DohUngetc DOH_NAMESPACE(Ungetc)
-#define DohGetline DOH_NAMESPACE(Getline)
-#define DohSetline DOH_NAMESPACE(Setline)
-#define DohGetfile DOH_NAMESPACE(Getfile)
-#define DohSetfile DOH_NAMESPACE(Setfile)
-#define DohReplace DOH_NAMESPACE(Replace)
-#define DohChop DOH_NAMESPACE(Chop)
-#define DohGetmeta DOH_NAMESPACE(Getmeta)
-#define DohSetmeta DOH_NAMESPACE(Setmeta)
-#define DohDelmeta DOH_NAMESPACE(Delmeta)
-#define DohEncoding DOH_NAMESPACE(Encoding)
-#define DohPrintf DOH_NAMESPACE(Printf)
-#define DohvPrintf DOH_NAMESPACE(vPrintf)
-#define DohPrintv DOH_NAMESPACE(Printv)
-#define DohReadline DOH_NAMESPACE(Readline)
-#define DohIsMapping DOH_NAMESPACE(IsMapping)
-#define DohIsSequence DOH_NAMESPACE(IsSequence)
-#define DohIsString DOH_NAMESPACE(IsString)
-#define DohIsFile DOH_NAMESPACE(IsFile)
-#define DohNewString DOH_NAMESPACE(NewString)
-#define DohNewStringEmpty DOH_NAMESPACE(NewStringEmpty)
-#define DohNewStringWithSize DOH_NAMESPACE(NewStringWithSize)
-#define DohNewStringf DOH_NAMESPACE(NewStringf)
-#define DohStrcmp DOH_NAMESPACE(Strcmp)
-#define DohStrncmp DOH_NAMESPACE(Strncmp)
-#define DohStrstr DOH_NAMESPACE(Strstr)
-#define DohStrchr DOH_NAMESPACE(Strchr)
-#define DohNewFile DOH_NAMESPACE(NewFile)
-#define DohNewFileFromFile DOH_NAMESPACE(NewFileFromFile)
-#define DohNewFileFromFd DOH_NAMESPACE(NewFileFromFd)
-#define DohFileErrorDisplay DOH_NAMESPACE(FileErrorDisplay)
-#define DohCopyto DOH_NAMESPACE(Copyto)
-#define DohNewList DOH_NAMESPACE(NewList)
-#define DohNewHash DOH_NAMESPACE(NewHash)
-#define DohNewVoid DOH_NAMESPACE(NewVoid)
-#define DohSplit DOH_NAMESPACE(Split)
-#define DohSplitLines DOH_NAMESPACE(SplitLines)
-#define DohNone DOH_NAMESPACE(None)
-#define DohCall DOH_NAMESPACE(Call)
-#define DohObjMalloc DOH_NAMESPACE(ObjMalloc)
-#define DohObjFree DOH_NAMESPACE(ObjFree)
-#define DohMemoryDebug DOH_NAMESPACE(MemoryDebug)
-#define DohStringType DOH_NAMESPACE(StringType)
-#define DohListType DOH_NAMESPACE(ListType)
-#define DohHashType DOH_NAMESPACE(HashType)
-#define DohFileType DOH_NAMESPACE(FileType)
-#define DohVoidType DOH_NAMESPACE(VoidType)
-#define DohIterator DOH_NAMESPACE(Iterator)
-#define DohFirst DOH_NAMESPACE(First)
-#define DohNext DOH_NAMESPACE(Next)
-#define DohMalloc DOH_NAMESPACE(Malloc)
-#define DohRealloc DOH_NAMESPACE(Realloc)
-#define DohCalloc DOH_NAMESPACE(Calloc)
-#define DohFree DOH_NAMESPACE(Free)
-#define DohSetExitHandler DOH_NAMESPACE(SetExitHandler)
-#define DohExit DOH_NAMESPACE(Exit)
-#endif
-
-#define DOH_MAJOR_VERSION 0
-#define DOH_MINOR_VERSION 1
-
-typedef void DOH;
-
-/*
- * With dynamic typing, all DOH objects are technically of type 'void *'.
- * However, to clarify the reading of source code, the following symbolic
- * names are used.
- */
-
-#define DOHString DOH
-#define DOHList DOH
-#define DOHHash DOH
-#define DOHFile DOH
-#define DOHVoid DOH
-#define DOHString_or_char DOH
-#define DOHObj_or_char DOH
-
-typedef const DOHString_or_char * const_String_or_char_ptr;
-typedef const DOHString_or_char * DOHconst_String_or_char_ptr;
-
-#define DOH_BEGIN -1
-#define DOH_END -2
-#define DOH_CUR -3
-#define DOH_CURRENT -3
-
-/* Iterator objects */
-
-typedef struct {
- void *key; /* Current key (if any) */
- void *item; /* Current item */
- void *object; /* Object being iterated over */
- void *_current; /* Internal use */
- int _index; /* Internal use */
-} DohIterator;
-
-/* Memory management */
-
-/* Wrappers around malloc(), realloc() and calloc() which never return NULL. */
-extern void *DohMalloc(size_t size);
-extern void *DohRealloc(void *ptr, size_t size);
-extern void *DohCalloc(size_t n, size_t size);
-
-#ifndef DohFree
-#define DohFree free
-#endif
-
-extern int DohCheck(const DOH *ptr); /* Check if a DOH object */
-extern void DohIntern(DOH *); /* Intern an object */
-
-/* Basic object methods. Common to most objects */
-
-extern void DohDelete(DOH *obj); /* Delete an object */
-extern DOH *DohCopy(const DOH *obj);
-extern void DohClear(DOH *obj);
-extern DOHString *DohStr(const DOH *obj);
-extern void *DohData(const DOH *obj);
-extern int DohDump(const DOH *obj, DOHFile * out);
-extern int DohLen(const DOH *obj);
-extern int DohHashval(const DOH *obj);
-extern int DohCmp(const DOH *obj1, const DOH *obj2);
-extern int DohEqual(const DOH *obj1, const DOH *obj2);
-extern void DohIncref(DOH *obj);
-
-/* Mapping methods */
-
-extern DOH *DohGetattr(DOH *obj, const DOHString_or_char *name);
-extern int DohSetattr(DOH *obj, const DOHString_or_char *name, const DOHObj_or_char * value);
-extern int DohDelattr(DOH *obj, const DOHString_or_char *name);
-extern int DohCheckattr(DOH *obj, const DOHString_or_char *name, const DOHString_or_char *value);
-extern DOH *DohKeys(DOH *obj);
-extern DOH *DohSortedKeys(DOH *obj, int (*cmp) (const DOH *, const DOH *));
-extern int DohGetInt(DOH *obj, const DOHString_or_char *name);
-extern void DohSetInt(DOH *obj, const DOHString_or_char *name, int);
-extern double DohGetDouble(DOH *obj, const DOHString_or_char *name);
-extern void DohSetDouble(DOH *obj, const DOHString_or_char *name, double);
-extern char *DohGetChar(DOH *obj, const DOHString_or_char *name);
-extern void DohSetChar(DOH *obj, const DOH *name, char *value);
-extern void *DohGetFlagAttr(DOH *obj, const DOHString_or_char *name);
-extern int DohGetFlag(DOH *obj, const DOHString_or_char *name);
-extern void DohSetFlagAttr(DOH *obj, const DOHString_or_char *name, const DOHString_or_char *attr);
-extern void DohSetFlag(DOH *obj, const DOHString_or_char *name);
-extern void *DohGetVoid(DOH *obj, const DOHString_or_char *name);
-extern void DohSetVoid(DOH *obj, const DOHString_or_char *name, void *value);
-
-/* Sequence methods */
-
-extern DOH *DohGetitem(DOH *obj, int index);
-extern int DohSetitem(DOH *obj, int index, const DOHObj_or_char * value);
-extern int DohDelitem(DOH *obj, int index);
-extern int DohInsertitem(DOH *obj, int index, const DOHObj_or_char * value);
-extern int DohDelslice(DOH *obj, int sindex, int eindex);
-
-/* File methods */
-
-extern int DohWrite(DOHFile * obj, const void *buffer, int length);
-extern int DohRead(DOHFile * obj, void *buffer, int length);
-extern int DohSeek(DOHFile * obj, long offset, int whence);
-extern long DohTell(DOHFile * obj);
-extern int DohGetc(DOHFile * obj);
-extern int DohPutc(int ch, DOHFile * obj);
-extern int DohUngetc(int ch, DOHFile * obj);
-
-
-
-/* Iterators */
-extern DohIterator DohFirst(DOH *obj);
-extern DohIterator DohNext(DohIterator x);
-
-/* Positional */
-
-extern int DohGetline(const DOH *obj);
-extern void DohSetline(DOH *obj, int line);
-extern DOH *DohGetfile(const DOH *obj);
-extern void DohSetfile(DOH *obj, DOH *file);
-
- /* String Methods */
-
-extern int DohReplace(DOHString * src, const DOHString_or_char *token, const DOHString_or_char *rep, int flags);
-extern void DohChop(DOHString * src);
-
-/* Meta-variables */
-extern DOH *DohGetmeta(DOH *, const DOH *);
-extern int DohSetmeta(DOH *, const DOH *, const DOH *value);
-extern int DohDelmeta(DOH *, const DOH *);
-
- /* Utility functions */
-
-extern void DohEncoding(const char *name, DOH *(*fn) (DOH *s));
-extern int DohPrintf(DOHFile * obj, const char *format, ...);
-extern int DohvPrintf(DOHFile * obj, const char *format, va_list ap);
-extern int DohPrintv(DOHFile * obj, ...);
-extern DOH *DohReadline(DOHFile * in);
-
- /* Miscellaneous */
-
-extern int DohIsMapping(const DOH *obj);
-extern int DohIsSequence(const DOH *obj);
-extern int DohIsString(const DOH *obj);
-extern int DohIsFile(const DOH *obj);
-
-extern void DohSetMaxHashExpand(int count);
-extern int DohGetMaxHashExpand(void);
-extern void DohSetmark(DOH *obj, int x);
-extern int DohGetmark(DOH *obj);
-
-/* Set the function for DohExit() to call instead of exit().
- *
- * The registered function can perform clean up, etc. It should simply
- * return when done and then exit() will get called. Bear in mind that
- * the handler function can be called after malloc() has failed, so it's
- * a good idea for it to avoid allocating additional memory.
- *
- * The registered handler function is unregistered by DohExit() before calling
- * it to avoid the potential for infinite loops.
- *
- * Note: This is sort of like C's atexit(), only for DohExit(). However
- * only one function can be registered (setting a new function overrides the
- * previous one) and the registered function is passed the exit status so can
- * vary its actions based on that.
- */
-extern void DohSetExitHandler(void (*new_handler)(int));
-extern void DohExit(int status);
-
-/* -----------------------------------------------------------------------------
- * Strings.
- * ----------------------------------------------------------------------------- */
-
-extern DOHString *DohNewStringEmpty(void);
-extern DOHString *DohNewString(const DOHString_or_char *c);
-extern DOHString *DohNewStringWithSize(const DOHString_or_char *c, int len);
-extern DOHString *DohNewStringf(const DOHString_or_char *fmt, ...);
-
-extern int DohStrcmp(const DOHString_or_char *s1, const DOHString_or_char *s2);
-extern int DohStrncmp(const DOHString_or_char *s1, const DOHString_or_char *s2, int n);
-extern char *DohStrstr(const DOHString_or_char *s1, const DOHString_or_char *s2);
-extern char *DohStrchr(const DOHString_or_char *s1, int ch);
-
-/* String replacement flags */
-
-#define DOH_REPLACE_ANY 0x01
-#define DOH_REPLACE_NOQUOTE 0x02
-#define DOH_REPLACE_NOCOMMENT 0x04
-#define DOH_REPLACE_ID 0x08
-#define DOH_REPLACE_FIRST 0x10
-#define DOH_REPLACE_ID_BEGIN 0x20
-#define DOH_REPLACE_ID_END 0x40
-#define DOH_REPLACE_NUMBER_END 0x80
-
-#define Replaceall(s,t,r) DohReplace(s,t,r,DOH_REPLACE_ANY)
-#define Replaceid(s,t,r) DohReplace(s,t,r,DOH_REPLACE_ID)
-
-/* -----------------------------------------------------------------------------
- * Files
- * ----------------------------------------------------------------------------- */
-
-extern DOHFile *DohNewFile(DOHString *filename, const char *mode, DOHList *outfiles);
-extern DOHFile *DohNewFileFromFile(FILE *f);
-extern DOHFile *DohNewFileFromFd(int fd);
-extern void DohFileErrorDisplay(DOHString * filename);
-extern int DohCopyto(DOHFile * input, DOHFile * output);
-extern void DohCloseAllOpenFiles(void);
-
-
-/* -----------------------------------------------------------------------------
- * List
- * ----------------------------------------------------------------------------- */
-
-extern DOHList *DohNewList(void);
-extern void DohSortList(DOH *lo, int (*cmp) (const DOH *, const DOH *));
-
-/* -----------------------------------------------------------------------------
- * Hash
- * ----------------------------------------------------------------------------- */
-
-extern DOHHash *DohNewHash(void);
-
-/* -----------------------------------------------------------------------------
- * Void
- * ----------------------------------------------------------------------------- */
-
-extern DOHVoid *DohNewVoid(void *ptr, void (*del) (void *));
-extern DOHList *DohSplit(DOHFile * input, char ch, int nsplits);
-extern DOHList *DohSplitLines(DOHFile * input);
-extern DOH *DohNone;
-
-/* Helper union for converting between function and object pointers. */
-typedef union DohFuncPtr {
- void* p;
- DOH *(*func)(DOH *);
-} DohFuncPtr_t;
-
-extern void DohMemoryDebug(void);
-
-#ifndef DOH_LONG_NAMES
-/* Macros to invoke the above functions. Includes the location of
- the caller to simplify debugging if something goes wrong */
-
-#define Delete DohDelete
-#define Copy DohCopy
-#define Clear DohClear
-#define Str DohStr
-#define Dump DohDump
-#define Getattr DohGetattr
-#define Setattr DohSetattr
-#define Delattr DohDelattr
-#define Checkattr DohCheckattr
-#define Hashval DohHashval
-#define Getitem DohGetitem
-#define Setitem DohSetitem
-#define Delitem DohDelitem
-#define Insert DohInsertitem
-#define Delslice DohDelslice
-#define Append(s,x) DohInsertitem(s,DOH_END,x)
-#define Push(s,x) DohInsertitem(s,DOH_BEGIN,x)
-#define Len DohLen
-#define Data DohData
-#define Char(X) ((char *) Data(X))
-#define Cmp DohCmp
-#define Equal DohEqual
-#define Setline DohSetline
-#define Getline DohGetline
-#define Setfile DohSetfile
-#define Getfile DohGetfile
-#define Write DohWrite
-#define Read DohRead
-#define Seek DohSeek
-#define Tell DohTell
-#define Printf DohPrintf
-#define Printv DohPrintv
-#define Getc DohGetc
-#define Putc DohPutc
-#define Ungetc DohUngetc
-
-/* #define StringPutc DohStringPutc */
-/* #define StringGetc DohStringGetc */
-/* #define StringUngetc DohStringUngetc */
-/* #define StringAppend Append */
-/* #define StringLen DohStringLen */
-/* #define StringChar DohStringChar */
-/* #define StringEqual DohStringEqual */
-
-#define vPrintf DohvPrintf
-#define GetInt DohGetInt
-#define GetDouble DohGetDouble
-#define GetChar DohGetChar
-#define GetVoid DohGetVoid
-#define GetFlagAttr DohGetFlagAttr
-#define GetFlag DohGetFlag
-#define SetInt DohSetInt
-#define SetDouble DohSetDouble
-#define SetChar DohSetattr
-#define SetVoid DohSetVoid
-#define SetFlagAttr DohSetFlagAttr
-#define SetFlag DohSetFlag
-#define UnsetFlag(o,n) DohSetFlagAttr(o,n,NULL)
-#define ClearFlag(o,n) DohSetFlagAttr(o,n,"")
-#define Readline DohReadline
-#define Replace DohReplace
-#define Chop DohChop
-#define Getmeta DohGetmeta
-#define Setmeta DohSetmeta
-#define Delmeta DohDelmeta
-#define NewString DohNewString
-#define NewStringEmpty DohNewStringEmpty
-#define NewStringWithSize DohNewStringWithSize
-#define NewStringf DohNewStringf
-#define NewHash DohNewHash
-#define NewList DohNewList
-#define NewFile DohNewFile
-#define NewFileFromFile DohNewFileFromFile
-#define NewFileFromFd DohNewFileFromFd
-#define FileErrorDisplay DohFileErrorDisplay
-#define NewVoid DohNewVoid
-#define Keys DohKeys
-#define SortedKeys DohSortedKeys
-#define Strcmp DohStrcmp
-#define Strncmp DohStrncmp
-#define Strstr DohStrstr
-#define Strchr DohStrchr
-#define Copyto DohCopyto
-#define CloseAllOpenFiles DohCloseAllOpenFiles
-#define Split DohSplit
-#define SplitLines DohSplitLines
-#define Setmark DohSetmark
-#define Getmark DohGetmark
-#define SetMaxHashExpand DohSetMaxHashExpand
-#define GetMaxHashExpand DohGetMaxHashExpand
-#define None DohNone
-#define Call DohCall
-#define First DohFirst
-#define Next DohNext
-#define Iterator DohIterator
-#define SortList DohSortList
-#define Malloc DohMalloc
-#define Realloc DohRealloc
-#define Calloc DohCalloc
-#define Free DohFree
-#define SetExitHandler DohSetExitHandler
-#define Exit DohExit
-#endif
-
-#ifdef NIL
-#undef NIL
-#endif
-
-#define NIL (char *) NULL
-
-/* Defines to allow use of poisoned identifiers.
- *
- * For DOH-internal use only!
- */
-#define doh_internal_calloc calloc
-#define doh_internal_exit exit
-/* doh_internal_free not needed as Free() is a macro defined above. */
-#define doh_internal_malloc malloc
-#define doh_internal_realloc realloc
-
-#if defined __GNUC__ && defined DOH_POISON
-/* Use Malloc(), Realloc(), Calloc(), and Free() instead (which will exit with
- * an error rather than return NULL).
- */
-# ifndef DOH_NO_POISON_MALLOC_FREE
-/* This works around bison's template checking if malloc and free are defined,
- * which triggers GCC's poison checks.
- */
-# pragma GCC poison malloc free
-# endif
-# pragma GCC poison realloc calloc
-/* Use Exit() instead (which will remove output files on error). */
-# pragma GCC poison abort exit
-#endif
-
-#endif /* SWIG_DOH_H */
diff --git a/contrib/tools/swig/Source/DOH/dohint.h b/contrib/tools/swig/Source/DOH/dohint.h
deleted file mode 100644
index b637debd26..0000000000
--- a/contrib/tools/swig/Source/DOH/dohint.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * dohint.h
- *
- * This file describes internally managed objects.
- * ----------------------------------------------------------------------------- */
-
-#ifndef SWIG_DOHINT_H
-#define SWIG_DOHINT_H
-
-#include "doh.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <ctype.h>
-#include <stdarg.h>
-
-/* Hash objects */
-typedef struct {
- DOH *(*doh_getattr) (DOH *obj, DOH *name); /* Get attribute */
- int (*doh_setattr) (DOH *obj, DOH *name, DOH *value); /* Set attribute */
- int (*doh_delattr) (DOH *obj, DOH *name); /* Del attribute */
- DOH *(*doh_keys) (DOH *obj); /* All keys as a list */
-} DohHashMethods;
-
-/* List objects */
-typedef struct {
- DOH *(*doh_getitem) (DOH *obj, int index); /* Get item */
- int (*doh_setitem) (DOH *obj, int index, DOH *value); /* Set item */
- int (*doh_delitem) (DOH *obj, int index); /* Delete item */
- int (*doh_insitem) (DOH *obj, int index, DOH *value); /* Insert item */
- int (*doh_delslice) (DOH *obj, int sindex, int eindex); /* Delete slice */
-} DohListMethods;
-
-/* File methods */
-typedef struct {
- int (*doh_read) (DOH *obj, void *buffer, int nbytes); /* Read bytes */
- int (*doh_write) (DOH *obj, const void *buffer, int nbytes); /* Write bytes */
- int (*doh_putc) (DOH *obj, int ch); /* Put character */
- int (*doh_getc) (DOH *obj); /* Get character */
- int (*doh_ungetc) (DOH *obj, int ch); /* Unget character */
- int (*doh_seek) (DOH *obj, long offset, int whence); /* Seek */
- long (*doh_tell) (DOH *obj); /* Tell */
-} DohFileMethods;
-
-/* String methods */
-typedef struct {
- int (*doh_replace) (DOH *obj, const DOHString_or_char *old, const DOHString_or_char *rep, int flags);
- void (*doh_chop) (DOH *obj);
-} DohStringMethods;
-
-/* -----------------------------------------------------------------------------
- * DohObjInfo
- * ----------------------------------------------------------------------------- */
-
-typedef struct DohObjInfo {
- const char *objname; /* Object name */
-
- /* Basic object methods */
- void (*doh_del) (DOH *obj); /* Delete object */
- DOH *(*doh_copy) (DOH *obj); /* Copy and object */
- void (*doh_clear) (DOH *obj); /* Clear an object */
-
- /* I/O methods */
- DOH *(*doh_str) (DOH *obj); /* Make a full string */
- void *(*doh_data) (DOH *obj); /* Return raw data */
- int (*doh_dump) (DOH *obj, DOH *out); /* Serialize on out */
-
- /* Length and hash values */
- int (*doh_len) (DOH *obj);
- int (*doh_hashval) (DOH *obj);
-
- /* Compare */
- int (*doh_cmp) (DOH *obj1, DOH *obj2);
-
- /* Equal */
- int (*doh_equal) (DOH *obj1, DOH *obj2);
-
- /* Iterators */
- DohIterator (*doh_first) (DOH *obj);
- DohIterator (*doh_next) (DohIterator);
-
- /* Positional */
- void (*doh_setfile) (DOH *obj, DOHString_or_char *file);
- DOH *(*doh_getfile) (DOH *obj);
- void (*doh_setline) (DOH *obj, int line);
- int (*doh_getline) (DOH *obj);
-
- DohHashMethods *doh_hash; /* Hash methods */
- DohListMethods *doh_list; /* List methods */
- DohFileMethods *doh_file; /* File methods */
- DohStringMethods *doh_string; /* String methods */
- void *doh_reserved; /* Reserved */
- void *clientdata; /* User data */
-} DohObjInfo;
-
-typedef struct {
- void *data; /* Data pointer */
- DohObjInfo *type;
- void *meta; /* Meta data */
- unsigned int flag_intern:1; /* Interned object */
- unsigned int flag_marked:1; /* Mark flag. Used to avoid recursive loops in places */
- unsigned int flag_user:1; /* User flag */
- unsigned int flag_usermark:1; /* User marked */
- unsigned int refcount:28; /* Reference count (max 16 million) */
-} DohBase;
-
-/* Macros for decrefing and increfing (safe for null objects). */
-
-#define Decref(a) if (a) ((DohBase *) a)->refcount--
-#define Incref(a) if (a) ((DohBase *) a)->refcount++
-#define Refcount(a) ((DohBase *) a)->refcount
-
-/* Macros for manipulating objects in a safe manner */
-#define ObjData(a) ((DohBase *)a)->data
-#define ObjSetMark(a,x) ((DohBase *)a)->flag_marked = x
-#define ObjGetMark(a) ((DohBase *)a)->flag_marked
-#define ObjType(a) ((DohBase *)a)->type
-
-extern DOH *DohObjMalloc(DohObjInfo *type, void *data); /* Allocate a DOH object */
-extern void DohObjFree(DOH *ptr); /* Free a DOH object */
-
-#endif /* SWIG_DOHINT_H */
diff --git a/contrib/tools/swig/Source/DOH/file.c b/contrib/tools/swig/Source/DOH/file.c
deleted file mode 100644
index 4bcf5d5e1d..0000000000
--- a/contrib/tools/swig/Source/DOH/file.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * file.c
- *
- * This file implements a file-like object that can be built around an
- * ordinary FILE * or integer file descriptor.
- * ----------------------------------------------------------------------------- */
-
-#include "dohint.h"
-
-#ifdef DOH_INTFILE
-#include <unistd.h>
-#endif
-#include <errno.h>
-
-typedef struct {
- FILE *filep;
- int fd;
- int closeondel;
-} DohFile;
-
-/* -----------------------------------------------------------------------------
- * open_files_list_instance
- * open_files_list_add
- * open_files_list_remove
- *
- * Singleton list containing all the files that have been opened by DohNewFile.
- * Open file pointers are held in the list as strings so as to not affect the
- * reference count of the underlying DOH objects.
- * ----------------------------------------------------------------------------- */
-
-static DOHList *open_files_list_instance(void) {
- static DOHList *all_open_files = 0;
- if (!all_open_files)
- all_open_files = DohNewList();
- return all_open_files;
-}
-
-static void open_files_list_add(DohFile *f) {
- DOHList *all_open_files = open_files_list_instance();
- DOHString *sf = NewStringf("%p", f);
- Append(all_open_files, sf);
- Delete(sf);
-}
-
-static void open_files_list_remove(DohFile *f) {
- int i;
- int removed = 0;
- DOHList *all_open_files = open_files_list_instance();
- DOHString *sf = NewStringf("%p", f);
- for (i = 0; i < DohLen(all_open_files); i++) {
- DOHString *sf_i = Getitem(all_open_files, i);
- if (Strcmp(sf, sf_i) == 0) {
- DohDelitem(all_open_files, i);
- removed = 1;
- break;
- }
- }
- Delete(sf);
- assert(removed);
- (void)removed;
-}
-
-/* -----------------------------------------------------------------------------
- * DohCloseAllOpenFiles()
- *
- * Close all opened files, to be called on program termination
- * ----------------------------------------------------------------------------- */
-
-void DohCloseAllOpenFiles(void) {
- int i;
- DOHList *all_open_files = open_files_list_instance();
- for (i = 0; i < DohLen(all_open_files); i++) {
- DohFile *f = 0;
- DOHString *sf = Getitem(all_open_files, i);
- int check = sscanf(Char(sf), "%p", (void **)&f);
- assert(check == 1);
- (void)check;
- if (f->closeondel) {
- if (f->filep) {
- check = fclose(f->filep);
- assert(check == 0);
- }
- f->closeondel = 0;
- f->filep = 0;
- }
- }
- DohClear(all_open_files);
-}
-
-/* -----------------------------------------------------------------------------
- * DelFile()
- * ----------------------------------------------------------------------------- */
-
-static void DelFile(DOH *fo) {
- DohFile *f = (DohFile *) ObjData(fo);
- if (f->closeondel) {
- if (f->filep) {
- fclose(f->filep);
- }
-#ifdef DOH_INTFILE
- if (f->fd) {
- close(f->fd);
- }
-#endif
- open_files_list_remove(f);
- }
- DohFree(f);
-}
-
-/* -----------------------------------------------------------------------------
- * File_read()
- * ----------------------------------------------------------------------------- */
-
-static int File_read(DOH *fo, void *buffer, int len) {
- DohFile *f = (DohFile *) ObjData(fo);
-
- if (f->filep) {
- return (int)fread(buffer, 1, len, f->filep);
- } else if (f->fd) {
-#ifdef DOH_INTFILE
- return read(f->fd, buffer, len);
-#endif
- }
- return -1;
-}
-
-/* -----------------------------------------------------------------------------
- * File_write()
- * ----------------------------------------------------------------------------- */
-
-static int File_write(DOH *fo, const void *buffer, int len) {
- DohFile *f = (DohFile *) ObjData(fo);
- if (f->filep) {
- int ret = (int) fwrite(buffer, 1, len, f->filep);
- int err = (ret != len) ? ferror(f->filep) : 0;
- return err ? -1 : ret;
- } else if (f->fd) {
-#ifdef DOH_INTFILE
- return write(f->fd, buffer, len);
-#endif
- }
- return -1;
-}
-
-/* -----------------------------------------------------------------------------
- * File_seek()
- * ----------------------------------------------------------------------------- */
-
-static int File_seek(DOH *fo, long offset, int whence) {
- DohFile *f = (DohFile *) ObjData(fo);
- if (f->filep) {
- return fseek(f->filep, offset, whence);
- } else if (f->fd) {
-#ifdef DOH_INTFILE
- return lseek(f->fd, offset, whence);
-#endif
- }
- return -1;
-}
-
-/* -----------------------------------------------------------------------------
- * File_tell()
- * ----------------------------------------------------------------------------- */
-
-static long File_tell(DOH *fo) {
- DohFile *f = (DohFile *) ObjData(fo);
- if (f->filep) {
- return ftell(f->filep);
- } else if (f->fd) {
-#ifdef DOH_INTFILE
- return lseek(f->fd, 0, SEEK_CUR);
-#endif
- }
- return -1;
-}
-
-/* -----------------------------------------------------------------------------
- * File_putc()
- * ----------------------------------------------------------------------------- */
-
-static int File_putc(DOH *fo, int ch) {
- DohFile *f = (DohFile *) ObjData(fo);
- if (f->filep) {
- return fputc(ch, f->filep);
- } else if (f->fd) {
-#ifdef DOH_INTFILE
- char c;
- c = (char) ch;
- return write(f->fd, &c, 1);
-#endif
- }
- return -1;
-}
-
-/* -----------------------------------------------------------------------------
- * File_getc()
- * ----------------------------------------------------------------------------- */
-
-static int File_getc(DOH *fo) {
- DohFile *f = (DohFile *) ObjData(fo);
- if (f->filep) {
- return fgetc(f->filep);
- } else if (f->fd) {
-#ifdef DOH_INTFILE
- unsigned char c;
- if (read(f->fd, &c, 1) < 0)
- return EOF;
- return c;
-#endif
- }
- return EOF;
-}
-
-/* -----------------------------------------------------------------------------
- * File_ungetc()
- *
- * Put a character back onto the input
- * ----------------------------------------------------------------------------- */
-
-static int File_ungetc(DOH *fo, int ch) {
- DohFile *f = (DohFile *) ObjData(fo);
- if (f->filep) {
- return ungetc(ch, f->filep);
- } else if (f->fd) {
-#ifdef DOH_INTFILE
- /* Not implemented yet */
-#endif
- }
- return -1;
-}
-
-static DohFileMethods FileFileMethods = {
- File_read,
- File_write,
- File_putc,
- File_getc,
- File_ungetc,
- File_seek,
- File_tell,
-};
-
-static DohObjInfo DohFileType = {
- "DohFile", /* objname */
- DelFile, /* doh_del */
- 0, /* doh_copy */
- 0, /* doh_clear */
- 0, /* doh_str */
- 0, /* doh_data */
- 0, /* doh_dump */
- 0, /* doh_len */
- 0, /* doh_hash */
- 0, /* doh_cmp */
- 0, /* doh_equal */
- 0, /* doh_first */
- 0, /* doh_next */
- 0, /* doh_setfile */
- 0, /* doh_getfile */
- 0, /* doh_setline */
- 0, /* doh_getline */
- 0, /* doh_mapping */
- 0, /* doh_sequence */
- &FileFileMethods, /* doh_file */
- 0, /* doh_string */
- 0, /* doh_callable */
- 0, /* doh_position */
-};
-
-/* -----------------------------------------------------------------------------
- * NewFile()
- *
- * Create a new file from a given filename and mode.
- * If newfiles is non-zero, the filename is added to the list of new files.
- * ----------------------------------------------------------------------------- */
-
-DOH *DohNewFile(DOHString *filename, const char *mode, DOHList *newfiles) {
- DohFile *f;
- DOH *obj;
- FILE *file;
- char *filen;
-
- filen = Char(filename);
- file = fopen(filen, mode);
- if (!file)
- return 0;
-
- f = (DohFile *) DohMalloc(sizeof(DohFile));
- if (newfiles)
- Append(newfiles, filename);
- f->filep = file;
- f->fd = 0;
- f->closeondel = 1;
- obj = DohObjMalloc(&DohFileType, f);
- open_files_list_add(f);
- return obj;
-}
-
-/* -----------------------------------------------------------------------------
- * NewFileFromFile()
- *
- * Create a file object from an already open FILE *.
- * ----------------------------------------------------------------------------- */
-
-DOH *DohNewFileFromFile(FILE *file) {
- DohFile *f;
- f = (DohFile *) DohMalloc(sizeof(DohFile));
- f->filep = file;
- f->fd = 0;
- f->closeondel = 0;
- return DohObjMalloc(&DohFileType, f);
-}
-
-/* -----------------------------------------------------------------------------
- * NewFileFromFd()
- *
- * Create a file object from an already open FILE *.
- * ----------------------------------------------------------------------------- */
-
-DOH *DohNewFileFromFd(int fd) {
- DohFile *f;
- f = (DohFile *) DohMalloc(sizeof(DohFile));
- f->filep = 0;
- f->fd = fd;
- f->closeondel = 0;
- return DohObjMalloc(&DohFileType, f);
-}
-
-/* -----------------------------------------------------------------------------
- * FileErrorDisplay()
- *
- * Display cause of one of the NewFile functions failing.
- * ----------------------------------------------------------------------------- */
-
-void DohFileErrorDisplay(DOHString * filename) {
- Printf(stderr, "Unable to open file %s: %s\n", filename, strerror(errno));
-}
diff --git a/contrib/tools/swig/Source/DOH/fio.c b/contrib/tools/swig/Source/DOH/fio.c
deleted file mode 100644
index 972fb23df9..0000000000
--- a/contrib/tools/swig/Source/DOH/fio.c
+++ /dev/null
@@ -1,599 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * fio.c
- *
- * This file implements a number of standard I/O operations included
- * formatted output, readline, and splitting.
- * ----------------------------------------------------------------------------- */
-
-#include "dohint.h"
-
-#define OBUFLEN 512
-
-static DOH *encodings = 0; /* Encoding hash */
-
-/* -----------------------------------------------------------------------------
- * Writen()
- *
- * Writes N characters of output and retries until all characters are
- * written. This is useful should a write operation encounter a spurious signal.
- * ----------------------------------------------------------------------------- */
-
-static int Writen(DOH *out, void *buffer, int len) {
- int nw = len, ret;
- char *cb = (char *) buffer;
- while (nw) {
- ret = Write(out, cb, nw);
- if (ret < 0)
- return -1;
- nw = nw - ret;
- cb += ret;
- }
- return len;
-}
-
-/* -----------------------------------------------------------------------------
- * DohEncoding()
- *
- * Registers a new printf encoding method. An encoder function should accept
- * two file-like objects and operate as a filter.
- * ----------------------------------------------------------------------------- */
-
-void DohEncoding(const char *name, DOH *(*fn) (DOH *s)) {
- DohFuncPtr_t fp;
-
- if (!encodings)
- encodings = NewHash();
-
- fp.func = fn;
- Setattr(encodings, (void *) name, NewVoid(fp.p, 0));
-}
-
-/* internal function for processing an encoding */
-static DOH *encode(char *name, DOH *s) {
- DOH *handle, *ns;
- DohFuncPtr_t fp;
- long pos;
- char *cfmt = strchr(name, ':');
- DOH *tmp = 0;
- if (cfmt) {
- tmp = NewString(cfmt + 1);
- Append(tmp, s);
- Setfile(tmp, Getfile((DOH *) s));
- Setline(tmp, Getline((DOH *) s));
- *cfmt = '\0';
- }
- if (!encodings || !(handle = Getattr(encodings, name))) {
- return Copy(s);
- }
- if (tmp)
- s = tmp;
- pos = Tell(s);
- Seek(s, 0, SEEK_SET);
-
- fp.p = Data(handle);
- ns = (*fp.func) (s);
- assert(pos != -1);
- (void)Seek(s, pos, SEEK_SET);
- if (tmp)
- Delete(tmp);
- return ns;
-}
-
-/* -----------------------------------------------------------------------------
- * DohvPrintf()
- *
- * DOH implementation of printf. Output can be directed to any file-like object
- * including bare FILE * objects. The same formatting codes as printf are
- * recognized with two extensions:
- *
- * %s - Prints a "char *" or the string representation of any
- * DOH object. This will implicitly result in a call to
- * Str(obj).
- *
- * %(encoder)* - Filters the output through an encoding function registered
- * with DohEncoder().
- *
- * Note: This function is not particularly memory efficient with large strings.
- * It's better to use Dump() or some other method instead.
- * ----------------------------------------------------------------------------- */
-
-int DohvPrintf(DOH *so, const char *format, va_list ap) {
- static const char *fmt_codes = "dioxXucsSfeEgGpn";
- int state = 0;
- const char *p = format;
- char newformat[256];
- char obuffer[OBUFLEN];
- char *fmt = 0;
- char temp[64];
- int widthval = 0;
- int precval = 0;
- int maxwidth;
- char *w = 0;
- int ivalue;
- double dvalue;
- void *pvalue;
- char *stemp;
- int nbytes = 0;
- char encoder[128], *ec = 0;
- int plevel = 0;
-
- memset(newformat, 0, sizeof(newformat));
-
- while (*p) {
- switch (state) {
- case 0: /* Ordinary text */
- if (*p != '%') {
- Putc(*p, so);
- nbytes++;
- } else {
- fmt = newformat;
- widthval = 0;
- precval = 0;
- *(fmt++) = *p;
- encoder[0] = 0;
- state = 10;
- }
- break;
- case 10: /* Look for a width and precision */
- if (isdigit((int) *p) && (*p != '0')) {
- w = temp;
- *(w++) = *p;
- *(fmt++) = *p;
- state = 20;
- } else if (strchr(fmt_codes, *p)) {
- /* Got one of the formatting codes */
- p--;
- state = 100;
- } else if (*p == '*') {
- /* Width field is specified in the format list */
- widthval = va_arg(ap, int);
- sprintf(temp, "%d", widthval);
- for (w = temp; *w; w++) {
- *(fmt++) = *w;
- }
- state = 30;
- } else if (*p == '%') {
- Putc(*p, so);
- fmt = newformat;
- nbytes++;
- state = 0;
- } else if (*p == '(') {
- ++plevel;
- ec = encoder;
- state = 60;
- } else {
- *(fmt++) = *p;
- }
- break;
-
- case 20: /* Hmmm. At the start of a width field */
- if (isdigit((int) *p)) {
- *(w++) = *p;
- *(fmt++) = *p;
- } else if (strchr(fmt_codes, *p)) {
- /* Got one of the formatting codes */
- /* Figure out width */
- *w = 0;
- widthval = atoi(temp);
- p--;
- state = 100;
- } else if (*p == '.') {
- *w = 0;
- widthval = atoi(temp);
- w = temp;
- *(fmt++) = *p;
- state = 40;
- } else {
- /* ??? */
- *w = 0;
- widthval = atoi(temp);
- state = 50;
- }
- break;
-
- case 30: /* Parsed a width from an argument. Look for a . */
- if (*p == '.') {
- w = temp;
- *(fmt++) = *p;
- state = 40;
- } else if (strchr(fmt_codes, *p)) {
- /* Got one of the formatting codes */
- /* Figure out width */
- p--;
- state = 100;
- } else {
- /* hmmm. Something else. */
- state = 50;
- }
- break;
-
- case 40:
- /* Start of precision expected */
- if (isdigit((int) *p) && (*p != '0')) {
- *(fmt++) = *p;
- *(w++) = *p;
- state = 41;
- } else if (*p == '*') {
- /* Precision field is specified in the format list */
- precval = va_arg(ap, int);
- sprintf(temp, "%d", precval);
- for (w = temp; *w; w++) {
- *(fmt++) = *w;
- }
- state = 50;
- } else if (strchr(fmt_codes, *p)) {
- p--;
- state = 100;
- } else {
- *(fmt++) = *p;
- state = 50;
- }
- break;
- case 41:
- if (isdigit((int) *p)) {
- *(fmt++) = *p;
- *(w++) = *p;
- } else if (strchr(fmt_codes, *p)) {
- /* Got one of the formatting codes */
- /* Figure out width */
- *w = 0;
- precval = atoi(temp);
- p--;
- state = 100;
- } else {
- *w = 0;
- precval = atoi(temp);
- *(fmt++) = *p;
- state = 50;
- }
- break;
- /* Hang out, wait for format specifier */
- case 50:
- if (strchr(fmt_codes, *p)) {
- p--;
- state = 100;
- } else {
- *(fmt++) = *p;
- }
- break;
-
- /* Got an encoding header */
- case 60:
- if (*p == '(') {
- ++plevel;
- *ec = *p;
- ec++;
- } else if (*p == ')') {
- --plevel;
- if (plevel <= 0) {
- *ec = 0;
- state = 10;
- } else {
- *ec = *p;
- ec++;
- }
- } else {
- *ec = *p;
- ec++;
- }
- break;
- case 100:
- /* Got a formatting code */
- if (widthval < precval)
- maxwidth = precval;
- else
- maxwidth = widthval;
- if ((*p == 's') || (*p == 'S')) { /* Null-Terminated string */
- DOH *doh;
- DOH *Sval;
- DOH *enc = 0;
- doh = va_arg(ap, DOH *);
- if (DohCheck(doh)) {
- /* Is a DOH object. */
- if (DohIsString(doh)) {
- Sval = doh;
- } else {
- Sval = Str(doh);
- }
- if (strlen(encoder)) {
- enc = encode(encoder, Sval);
- maxwidth = maxwidth + (int)strlen(newformat) + Len(enc);
- } else {
- maxwidth = maxwidth + (int)strlen(newformat) + Len(Sval);
- }
- *(fmt++) = 's';
- *fmt = 0;
- if ((maxwidth + 1) < OBUFLEN) {
- stemp = obuffer;
- } else {
- stemp = (char *) DohMalloc(maxwidth + 1);
- }
- if (enc) {
- nbytes += sprintf(stemp, newformat, Data(enc));
- } else {
- nbytes += sprintf(stemp, newformat, Data(Sval));
- }
- if (Writen(so, stemp, (int)strlen(stemp)) < 0)
- return -1;
- if ((DOH *) Sval != doh) {
- Delete(Sval);
- }
- if (enc)
- Delete(enc);
- if (*p == 'S') {
- Delete(doh);
- }
- if (stemp != obuffer) {
- DohFree(stemp);
- }
- } else {
- if (!doh)
- doh = (char *) "";
-
- if (strlen(encoder)) {
- DOH *s = NewString(doh);
- Seek(s, 0, SEEK_SET);
- enc = encode(encoder, s);
- Delete(s);
- doh = Char(enc);
- } else {
- enc = 0;
- }
- maxwidth = maxwidth + (int)strlen(newformat) + (int)strlen((char *) doh);
- *(fmt++) = 's';
- *fmt = 0;
- if ((maxwidth + 1) < OBUFLEN) {
- stemp = obuffer;
- } else {
- stemp = (char *) DohMalloc(maxwidth + 1);
- }
- nbytes += sprintf(stemp, newformat, doh);
- if (Writen(so, stemp, (int)strlen(stemp)) < 0)
- return -1;
- if (stemp != obuffer) {
- DohFree(stemp);
- }
- if (enc)
- Delete(enc);
- }
- } else {
- *(fmt++) = *p;
- *fmt = 0;
- maxwidth = maxwidth + (int)strlen(newformat) + 64;
-
- /* Only allocate a buffer if it is too big to fit. Shouldn't have to do
- this very often */
-
- if (maxwidth < OBUFLEN)
- stemp = obuffer;
- else
- stemp = (char *) DohMalloc(maxwidth + 1);
- switch (*p) {
- case 'd':
- case 'i':
- case 'o':
- case 'u':
- case 'x':
- case 'X':
- case 'c':
- ivalue = va_arg(ap, int);
- nbytes += sprintf(stemp, newformat, ivalue);
- break;
- case 'f':
- case 'g':
- case 'e':
- case 'E':
- case 'G':
- dvalue = va_arg(ap, double);
- nbytes += sprintf(stemp, newformat, dvalue);
- break;
- case 'p':
- pvalue = va_arg(ap, void *);
- nbytes += sprintf(stemp, newformat, pvalue);
- break;
- default:
- break;
- }
- if (Writen(so, stemp, (int)strlen(stemp)) < 0)
- return -1;
- if (stemp != obuffer)
- DohFree(stemp);
- }
- state = 0;
- break;
- }
- p++;
- }
- if (state) {
- int r;
- *fmt = 0;
- r = Writen(so, fmt, (int)strlen(fmt));
- if (r < 0)
- return -1;
- nbytes += r;
- }
- return nbytes;
-}
-
-/* -----------------------------------------------------------------------------
- * DohPrintf()
- *
- * Variable length argument entry point to Printf
- * ----------------------------------------------------------------------------- */
-
-int DohPrintf(DOH *obj, const char *format, ...) {
- va_list ap;
- int ret;
- va_start(ap, format);
- ret = DohvPrintf(obj, format, ap);
- va_end(ap);
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
- * DohPrintv()
- *
- * Print a null-terminated variable length list of DOH objects
- * ----------------------------------------------------------------------------- */
-
-int DohPrintv(DOHFile * f, ...) {
- va_list ap;
- int ret = 0;
- DOH *obj;
- va_start(ap, f);
- while (1) {
- obj = va_arg(ap, void *);
- if ((!obj) || (obj == DohNone))
- break;
- if (DohCheck(obj)) {
- ret += DohDump(obj, f);
- } else {
- ret += DohWrite(f, obj, (int)strlen((char *) obj));
- }
- }
- va_end(ap);
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
- * DohCopyto()
- *
- * Copies all of the input from an input stream to an output stream. Returns the
- * number of bytes copied.
- * ----------------------------------------------------------------------------- */
-
-int DohCopyto(DOH *in, DOH *out) {
- int nbytes = 0, ret;
- int nwrite = 0, wret;
- char *cw;
- char buffer[16384];
-
- if ((!in) || (!out))
- return 0;
- while (1) {
- ret = Read(in, buffer, 16384);
- if (ret > 0) {
- nwrite = ret;
- cw = buffer;
- while (nwrite) {
- wret = Write(out, cw, nwrite);
- if (wret < 0) {
- nbytes = -1;
- break;
- }
- nwrite = nwrite - wret;
- cw += wret;
- }
- nbytes += ret;
- } else {
- break;
- }
- }
- return nbytes;
-}
-
-
-/* -----------------------------------------------------------------------------
- * DohSplit()
- *
- * Split an input stream into a list of strings delimited by the specified
- * character. Optionally accepts a maximum number of splits to perform.
- * ----------------------------------------------------------------------------- */
-
-DOH *DohSplit(DOH *in, char ch, int nsplits) {
- DOH *list;
- DOH *str;
- int c;
-
- list = NewList();
-
- if (DohIsString(in)) {
- Seek(in, 0, SEEK_SET);
- }
-
- while (1) {
- str = NewStringEmpty();
- do {
- c = Getc(in);
- } while ((c != EOF) && (c == ch));
- if (c != EOF) {
- Putc(c, str);
- while (1) {
- c = Getc(in);
- if ((c == EOF) || ((c == ch) && (nsplits != 0)))
- break;
- Putc(c, str);
- }
- nsplits--;
- }
- Append(list, str);
- Delete(str);
- if (c == EOF)
- break;
- }
- return list;
-}
-
-/* -----------------------------------------------------------------------------
- * DohSplitLines()
- *
- * Split an input stream into a list of strings delimited by newline characters.
- * ----------------------------------------------------------------------------- */
-
-DOH *DohSplitLines(DOH *in) {
- DOH *list;
- DOH *str;
- int c = 0;
-
- list = NewList();
-
- if (DohIsString(in)) {
- Seek(in, 0, SEEK_SET);
- }
-
- while (c != EOF) {
- str = NewStringEmpty();
- while ((c = Getc(in)) != '\n' && c != EOF) {
- Putc(c, str);
- }
- Append(list, str);
- Delete(str);
- }
- return list;
-}
-
-
-/* -----------------------------------------------------------------------------
- * DohReadline()
- *
- * Read a single input line and return it as a string.
- * ----------------------------------------------------------------------------- */
-
-DOH *DohReadline(DOH *in) {
- char c;
- int n = 0;
- DOH *s = NewStringEmpty();
- while (1) {
- if (Read(in, &c, 1) < 0) {
- if (n == 0) {
- Delete(s);
- s = 0;
- }
- break;
- }
- if (c == '\n')
- break;
- if (c == '\r')
- continue;
- Putc(c, s);
- n++;
- }
- return s;
-}
diff --git a/contrib/tools/swig/Source/DOH/hash.c b/contrib/tools/swig/Source/DOH/hash.c
deleted file mode 100644
index b9d501e3c4..0000000000
--- a/contrib/tools/swig/Source/DOH/hash.c
+++ /dev/null
@@ -1,583 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * hash.c
- *
- * Implements a simple hash table object.
- * ----------------------------------------------------------------------------- */
-
-#include "dohint.h"
-
-extern DohObjInfo DohHashType;
-
-/* Hash node */
-typedef struct HashNode {
- DOH *key;
- DOH *object;
- struct HashNode *next;
-} HashNode;
-
-/* Hash object */
-typedef struct Hash {
- DOH *file;
- int line;
- HashNode **hashtable;
- int hashsize;
- int nitems;
-} Hash;
-
-/* Key interning structure */
-typedef struct KeyValue {
- char *cstr;
- DOH *sstr;
- struct KeyValue *left;
- struct KeyValue *right;
-} KeyValue;
-
-static KeyValue *root = 0;
-static int max_expand = 1;
-
-/* Find or create a key in the interned key table */
-static DOH *find_key(DOH *doh_c) {
- char *c = (char *) doh_c;
- KeyValue *r, *s;
- int d = 0;
- /* OK, sure, we use a binary tree for maintaining interned
- symbols. Then we use their hash values for accessing secondary
- hash tables. */
- r = root;
- s = 0;
- while (r) {
- s = r;
- d = strcmp(r->cstr, c);
- if (d == 0)
- return r->sstr;
- if (d < 0)
- r = r->left;
- else
- r = r->right;
- }
- /* fprintf(stderr,"Interning '%s'\n", c); */
- r = (KeyValue *) DohMalloc(sizeof(KeyValue));
- r->cstr = (char *) DohMalloc(strlen(c) + 1);
- strcpy(r->cstr, c);
- r->sstr = NewString(c);
- DohIntern(r->sstr);
- r->left = 0;
- r->right = 0;
- if (!s) {
- root = r;
- } else {
- if (d < 0)
- s->left = r;
- else
- s->right = r;
- }
- return r->sstr;
-}
-
-#define HASH_INIT_SIZE 7
-
-/* Create a new hash node */
-static HashNode *NewNode(DOH *k, void *obj) {
- HashNode *hn = (HashNode *) DohMalloc(sizeof(HashNode));
- hn->key = k;
- Incref(hn->key);
- hn->object = obj;
- Incref(obj);
- hn->next = 0;
- return hn;
-}
-
-/* Delete a hash node */
-static void DelNode(HashNode *hn) {
- Delete(hn->key);
- Delete(hn->object);
- DohFree(hn);
-}
-
-/* -----------------------------------------------------------------------------
- * DelHash()
- *
- * Delete a hash table.
- * ----------------------------------------------------------------------------- */
-
-static void DelHash(DOH *ho) {
- Hash *h = (Hash *) ObjData(ho);
- HashNode *n, *next;
- int i;
-
- for (i = 0; i < h->hashsize; i++) {
- n = h->hashtable[i];
- while (n) {
- next = n->next;
- DelNode(n);
- n = next;
- }
- }
- DohFree(h->hashtable);
- h->hashtable = 0;
- h->hashsize = 0;
- DohFree(h);
-}
-
-/* -----------------------------------------------------------------------------
- * Hash_clear()
- *
- * Clear all of the entries in the hash table.
- * ----------------------------------------------------------------------------- */
-
-static void Hash_clear(DOH *ho) {
- Hash *h = (Hash *) ObjData(ho);
- HashNode *n, *next;
- int i;
-
- for (i = 0; i < h->hashsize; i++) {
- n = h->hashtable[i];
- while (n) {
- next = n->next;
- DelNode(n);
- n = next;
- }
- h->hashtable[i] = 0;
- }
- h->nitems = 0;
-}
-
-/* resize the hash table */
-static void resize(Hash *h) {
- HashNode *n, *next, **table;
- int oldsize, newsize;
- int i, p, hv;
-
- if (h->nitems < 2 * h->hashsize)
- return;
-
- /* Too big. We have to rescale everything now */
- oldsize = h->hashsize;
-
- /* Calculate a new size */
- newsize = 2 * oldsize + 1;
- p = 3;
- while (p < (newsize >> 1)) {
- if (((newsize / p) * p) == newsize) {
- newsize += 2;
- p = 3;
- continue;
- }
- p = p + 2;
- }
-
- table = (HashNode **) DohCalloc(newsize, sizeof(HashNode *));
-
- /* Walk down the old set of nodes and re-place */
- h->hashsize = newsize;
- for (i = 0; i < oldsize; i++) {
- n = h->hashtable[i];
- while (n) {
- hv = Hashval(n->key) % newsize;
- next = n->next;
- n->next = table[hv];
- table[hv] = n;
- n = next;
- }
- }
- DohFree(h->hashtable);
- h->hashtable = table;
-}
-
-/* -----------------------------------------------------------------------------
- * Hash_setattr()
- *
- * Set an attribute in the hash table. Deletes the existing entry if it already
- * exists.
- * ----------------------------------------------------------------------------- */
-
-static int Hash_setattr(DOH *ho, DOH *k, DOH *obj) {
- int hv;
- HashNode *n, *prev;
- Hash *h = (Hash *) ObjData(ho);
-
- if (!obj) {
- return DohDelattr(ho, k);
- }
- if (!DohCheck(k))
- k = find_key(k);
- if (!DohCheck(obj)) {
- obj = NewString((char *) obj);
- Decref(obj);
- }
- hv = (Hashval(k)) % h->hashsize;
- n = h->hashtable[hv];
- prev = 0;
- while (n) {
- if (Cmp(n->key, k) == 0) {
- /* Node already exists. Just replace its contents */
- if (n->object == obj) {
- /* Whoa. Same object. Do nothing */
- return 1;
- }
- Delete(n->object);
- n->object = obj;
- Incref(obj);
- return 1; /* Return 1 to indicate a replacement */
- } else {
- prev = n;
- n = n->next;
- }
- }
- /* Add this to the table */
- n = NewNode(k, obj);
- if (prev)
- prev->next = n;
- else
- h->hashtable[hv] = n;
- h->nitems++;
- resize(h);
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Hash_getattr()
- *
- * Get an attribute from the hash table. Returns 0 if it doesn't exist.
- * ----------------------------------------------------------------------------- */
-typedef int (*binop) (DOH *obj1, DOH *obj2);
-
-
-static DOH *Hash_getattr(DOH *h, DOH *k) {
- DOH *obj = 0;
- Hash *ho = (Hash *) ObjData(h);
- DOH *ko = DohCheck(k) ? k : find_key(k);
- int hv = Hashval(ko) % ho->hashsize;
- DohObjInfo *k_type = ((DohBase*)ko)->type;
- HashNode *n = ho->hashtable[hv];
- if (k_type->doh_equal) {
- binop equal = k_type->doh_equal;
- while (n) {
- DohBase *nk = (DohBase *)n->key;
- if ((k_type == nk->type) && equal(ko, nk)) obj = n->object;
- n = n->next;
- }
- } else {
- binop cmp = k_type->doh_cmp;
- while (n) {
- DohBase *nk = (DohBase *)n->key;
- if ((k_type == nk->type) && (cmp(ko, nk) == 0)) obj = n->object;
- n = n->next;
- }
- }
- return obj;
-}
-
-/* -----------------------------------------------------------------------------
- * Hash_delattr()
- *
- * Delete an object from the hash table.
- * ----------------------------------------------------------------------------- */
-
-static int Hash_delattr(DOH *ho, DOH *k) {
- HashNode *n, *prev;
- int hv;
- Hash *h = (Hash *) ObjData(ho);
-
- if (!DohCheck(k))
- k = find_key(k);
- hv = Hashval(k) % h->hashsize;
- n = h->hashtable[hv];
- prev = 0;
- while (n) {
- if (Cmp(n->key, k) == 0) {
- /* Found it, kill it */
-
- if (prev) {
- prev->next = n->next;
- } else {
- h->hashtable[hv] = n->next;
- }
- DelNode(n);
- h->nitems--;
- return 1;
- }
- prev = n;
- n = n->next;
- }
- return 0;
-}
-
-static DohIterator Hash_firstiter(DOH *ho) {
- DohIterator iter;
- Hash *h = (Hash *) ObjData(ho);
- iter.object = ho;
- iter._current = 0;
- iter.item = 0;
- iter.key = 0;
- iter._index = 0; /* Index in hash table */
- while ((iter._index < h->hashsize) && !h->hashtable[iter._index])
- iter._index++;
-
- if (iter._index >= h->hashsize) {
- return iter;
- }
- iter._current = h->hashtable[iter._index];
- iter.item = ((HashNode *) iter._current)->object;
- iter.key = ((HashNode *) iter._current)->key;
-
- /* Actually save the next slot in the hash. This makes it possible to
- delete the item being iterated over without trashing the universe */
- iter._current = ((HashNode *) iter._current)->next;
- return iter;
-}
-
-static DohIterator Hash_nextiter(DohIterator iter) {
- Hash *h = (Hash *) ObjData(iter.object);
- if (!iter._current) {
- iter._index++;
- while ((iter._index < h->hashsize) && !h->hashtable[iter._index]) {
- iter._index++;
- }
- if (iter._index >= h->hashsize) {
- iter.item = 0;
- iter.key = 0;
- iter._current = 0;
- return iter;
- }
- iter._current = h->hashtable[iter._index];
- }
- iter.key = ((HashNode *) iter._current)->key;
- iter.item = ((HashNode *) iter._current)->object;
-
- /* Store the next node to iterator on */
- iter._current = ((HashNode *) iter._current)->next;
- return iter;
-}
-
-/* -----------------------------------------------------------------------------
- * Hash_keys()
- *
- * Return a list of keys
- * ----------------------------------------------------------------------------- */
-
-static DOH *Hash_keys(DOH *so) {
- DOH *keys;
- Iterator i;
-
- keys = NewList();
- for (i = First(so); i.key; i = Next(i)) {
- Append(keys, i.key);
- }
- return keys;
-}
-
-/* -----------------------------------------------------------------------------
- * DohSetMaxHashExpand()
- *
- * Controls how many Hash objects are displayed in full in Hash_str
- * ----------------------------------------------------------------------------- */
-
-void DohSetMaxHashExpand(int count) {
- max_expand = count;
-}
-
-/* -----------------------------------------------------------------------------
- * DohGetMaxHashExpand()
- *
- * Returns how many Hash objects are displayed in full in Hash_str
- * ----------------------------------------------------------------------------- */
-
-int DohGetMaxHashExpand(void) {
- return max_expand;
-}
-
-/* -----------------------------------------------------------------------------
- * Hash_str()
- *
- * Create a string representation of a hash table (mainly for debugging).
- * ----------------------------------------------------------------------------- */
-
-static DOH *Hash_str(DOH *ho) {
- int i, j;
- HashNode *n;
- DOH *s;
- static int expanded = 0;
- static const char *tab = " ";
- Hash *h = (Hash *) ObjData(ho);
-
- s = NewStringEmpty();
- if (ObjGetMark(ho)) {
- Printf(s, "Hash(%p)", ho);
- return s;
- }
- if (expanded >= max_expand) {
- /* replace each hash attribute with a '.' */
- Printf(s, "Hash(%p) {", ho);
- for (i = 0; i < h->hashsize; i++) {
- n = h->hashtable[i];
- while (n) {
- Putc('.', s);
- n = n->next;
- }
- }
- Putc('}', s);
- return s;
- }
- ObjSetMark(ho, 1);
- Printf(s, "Hash(%p) {\n", ho);
- for (i = 0; i < h->hashsize; i++) {
- n = h->hashtable[i];
- while (n) {
- for (j = 0; j < expanded + 1; j++)
- Printf(s, tab);
- expanded += 1;
- Printf(s, "'%s' : %s, \n", n->key, n->object);
- expanded -= 1;
- n = n->next;
- }
- }
- for (j = 0; j < expanded; j++)
- Printf(s, tab);
- Printf(s, "}");
- ObjSetMark(ho, 0);
- return s;
-}
-
-/* -----------------------------------------------------------------------------
- * Hash_len()
- *
- * Return number of entries in the hash table.
- * ----------------------------------------------------------------------------- */
-
-static int Hash_len(DOH *ho) {
- Hash *h = (Hash *) ObjData(ho);
- return h->nitems;
-}
-
-/* -----------------------------------------------------------------------------
- * CopyHash()
- *
- * Make a copy of a hash table. Note: this is a shallow copy.
- * ----------------------------------------------------------------------------- */
-
-static DOH *CopyHash(DOH *ho) {
- Hash *h, *nh;
- HashNode *n;
- DOH *nho;
-
- int i;
- h = (Hash *) ObjData(ho);
- nh = (Hash *) DohMalloc(sizeof(Hash));
- nh->hashsize = h->hashsize;
- nh->hashtable = (HashNode **) DohMalloc(nh->hashsize * sizeof(HashNode *));
- for (i = 0; i < nh->hashsize; i++) {
- nh->hashtable[i] = 0;
- }
- nh->nitems = 0;
- nh->line = h->line;
- nh->file = h->file;
- if (nh->file)
- Incref(nh->file);
-
- nho = DohObjMalloc(&DohHashType, nh);
- for (i = 0; i < h->hashsize; i++) {
- n = h->hashtable[i];
- while (n) {
- Hash_setattr(nho, n->key, n->object);
- n = n->next;
- }
- }
- return nho;
-}
-
-
-
-static void Hash_setfile(DOH *ho, DOH *file) {
- DOH *fo;
- Hash *h = (Hash *) ObjData(ho);
-
- if (!DohCheck(file)) {
- fo = NewString(file);
- Decref(fo);
- } else
- fo = file;
- Incref(fo);
- Delete(h->file);
- h->file = fo;
-}
-
-static DOH *Hash_getfile(DOH *ho) {
- Hash *h = (Hash *) ObjData(ho);
- return h->file;
-}
-
-static void Hash_setline(DOH *ho, int line) {
- Hash *h = (Hash *) ObjData(ho);
- h->line = line;
-}
-
-static int Hash_getline(DOH *ho) {
- Hash *h = (Hash *) ObjData(ho);
- return h->line;
-}
-
-/* -----------------------------------------------------------------------------
- * type information
- * ----------------------------------------------------------------------------- */
-
-static DohHashMethods HashHashMethods = {
- Hash_getattr,
- Hash_setattr,
- Hash_delattr,
- Hash_keys,
-};
-
-DohObjInfo DohHashType = {
- "Hash", /* objname */
- DelHash, /* doh_del */
- CopyHash, /* doh_copy */
- Hash_clear, /* doh_clear */
- Hash_str, /* doh_str */
- 0, /* doh_data */
- 0, /* doh_dump */
- Hash_len, /* doh_len */
- 0, /* doh_hash */
- 0, /* doh_cmp */
- 0, /* doh_equal */
- Hash_firstiter, /* doh_first */
- Hash_nextiter, /* doh_next */
- Hash_setfile, /* doh_setfile */
- Hash_getfile, /* doh_getfile */
- Hash_setline, /* doh_setline */
- Hash_getline, /* doh_getline */
- &HashHashMethods, /* doh_mapping */
- 0, /* doh_sequence */
- 0, /* doh_file */
- 0, /* doh_string */
- 0, /* doh_positional */
- 0,
-};
-
-/* -----------------------------------------------------------------------------
- * NewHash()
- *
- * Create a new hash table.
- * ----------------------------------------------------------------------------- */
-
-DOH *DohNewHash(void) {
- Hash *h;
- int i;
- h = (Hash *) DohMalloc(sizeof(Hash));
- h->hashsize = HASH_INIT_SIZE;
- h->hashtable = (HashNode **) DohMalloc(h->hashsize * sizeof(HashNode *));
- for (i = 0; i < h->hashsize; i++) {
- h->hashtable[i] = 0;
- }
- h->nitems = 0;
- h->file = 0;
- h->line = 0;
- return DohObjMalloc(&DohHashType, h);
-}
diff --git a/contrib/tools/swig/Source/DOH/list.c b/contrib/tools/swig/Source/DOH/list.c
deleted file mode 100644
index cc619022d8..0000000000
--- a/contrib/tools/swig/Source/DOH/list.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * list.c
- *
- * Implements a simple list object.
- * ----------------------------------------------------------------------------- */
-
-#include "dohint.h"
-
-typedef struct List {
- int maxitems; /* Max size */
- int nitems; /* Num items */
- DOH *file;
- int line;
- DOH **items;
-} List;
-
-extern DohObjInfo DohListType;
-
-/* Doubles amount of memory in a list */
-static
-void more(List *l) {
- l->items = (void **) DohRealloc(l->items, l->maxitems * 2 * sizeof(void *));
- l->maxitems *= 2;
-}
-
-/* -----------------------------------------------------------------------------
- * CopyList()
- *
- * Make a shallow copy of a list.
- * ----------------------------------------------------------------------------- */
-static DOH *CopyList(DOH *lo) {
- List *l, *nl;
- int i;
- l = (List *) ObjData(lo);
- nl = (List *) DohMalloc(sizeof(List));
- nl->nitems = l->nitems;
- nl->maxitems = l->maxitems;
- nl->items = (void **) DohMalloc(l->maxitems * sizeof(void *));
- for (i = 0; i < l->nitems; i++) {
- nl->items[i] = l->items[i];
- Incref(nl->items[i]);
- }
- nl->file = l->file;
- if (nl->file)
- Incref(nl->file);
- nl->line = l->line;
- return DohObjMalloc(&DohListType, nl);
-}
-
-/* -----------------------------------------------------------------------------
- * DelList()
- *
- * Delete a list.
- * ----------------------------------------------------------------------------- */
-
-static void DelList(DOH *lo) {
- List *l = (List *) ObjData(lo);
- int i;
- for (i = 0; i < l->nitems; i++)
- Delete(l->items[i]);
- DohFree(l->items);
- DohFree(l);
-}
-
-/* -----------------------------------------------------------------------------
- * List_clear()
- *
- * Remove all of the list entries, but keep the list object intact.
- * ----------------------------------------------------------------------------- */
-
-static void List_clear(DOH *lo) {
- List *l = (List *) ObjData(lo);
- int i;
- for (i = 0; i < l->nitems; i++) {
- Delete(l->items[i]);
- }
- l->nitems = 0;
-}
-
-/* -----------------------------------------------------------------------------
- * List_insert()
- *
- * Insert an item into the list. If the item is not a DOH object, it is assumed
- * to be a 'char *' and is used to construct an equivalent string object.
- * ----------------------------------------------------------------------------- */
-
-static int List_insert(DOH *lo, int pos, DOH *item) {
- List *l = (List *) ObjData(lo);
- int i;
-
- if (!item)
- return -1;
- if (!DohCheck(item)) {
- item = NewString(item);
- Decref(item);
- }
- if (pos == DOH_END)
- pos = l->nitems;
- if (pos < 0)
- pos = 0;
- if (pos > l->nitems)
- pos = l->nitems;
- if (l->nitems == l->maxitems)
- more(l);
- for (i = l->nitems; i > pos; i--) {
- l->items[i] = l->items[i - 1];
- }
- l->items[pos] = item;
- Incref(item);
- l->nitems++;
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * List_remove()
- *
- * Remove an item from a list.
- * ----------------------------------------------------------------------------- */
-
-static int List_remove(DOH *lo, int pos) {
- List *l = (List *) ObjData(lo);
- int i;
- if (pos == DOH_END)
- pos = l->nitems - 1;
- if (pos == DOH_BEGIN)
- pos = 0;
- assert(!((pos < 0) || (pos >= l->nitems)));
- Delete(l->items[pos]);
- for (i = pos; i < l->nitems - 1; i++) {
- l->items[i] = l->items[i + 1];
- }
- l->nitems--;
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * List_len()
- *
- * Return the number of elements in the list
- * ----------------------------------------------------------------------------- */
-
-static int List_len(DOH *lo) {
- List *l = (List *) ObjData(lo);
- return l->nitems;
-}
-
-/* -----------------------------------------------------------------------------
- * List_get()
- *
- * Get the nth item from the list.
- * ----------------------------------------------------------------------------- */
-
-static DOH *List_get(DOH *lo, int n) {
- List *l = (List *) ObjData(lo);
- if (n == DOH_END)
- n = l->nitems - 1;
- if (n == DOH_BEGIN)
- n = 0;
- assert(!((n < 0) || (n >= l->nitems)));
- return l->items[n];
-}
-
-/* -----------------------------------------------------------------------------
- * List_set()
- *
- * Set the nth item in the list replacing any previous item.
- * ----------------------------------------------------------------------------- */
-
-static int List_set(DOH *lo, int n, DOH *val) {
- List *l = (List *) ObjData(lo);
- if (!val)
- return -1;
- assert(!((n < 0) || (n >= l->nitems)));
- if (!DohCheck(val)) {
- val = NewString(val);
- Decref(val);
- }
- Delete(l->items[n]);
- l->items[n] = val;
- Incref(val);
- Delete(val);
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * List_first()
- *
- * Return the first item in the list.
- * ----------------------------------------------------------------------------- */
-
-static DohIterator List_first(DOH *lo) {
- DohIterator iter;
- List *l = (List *) ObjData(lo);
- iter.object = lo;
- iter._index = 0;
- iter._current = 0;
- iter.key = 0;
- if (l->nitems > 0) {
- iter.item = l->items[0];
- } else {
- iter.item = 0;
- }
- return iter;
-}
-
-/* -----------------------------------------------------------------------------
- * List_next()
- *
- * Return the next item in the list.
- * ----------------------------------------------------------------------------- */
-
-static DohIterator List_next(DohIterator iter) {
- List *l = (List *) ObjData(iter.object);
- iter._index = iter._index + 1;
- if (iter._index >= l->nitems) {
- iter.item = 0;
- iter.key = 0;
- } else {
- iter.item = l->items[iter._index];
- }
- return iter;
-}
-
-/* -----------------------------------------------------------------------------
- * List_str()
- *
- * Create a string representation of the list.
- * ----------------------------------------------------------------------------- */
-static DOH *List_str(DOH *lo) {
- DOH *s;
- int i;
- List *l = (List *) ObjData(lo);
- s = NewStringEmpty();
- if (ObjGetMark(lo)) {
- Printf(s, "List(%p)", lo);
- return s;
- }
- ObjSetMark(lo, 1);
- Printf(s, "List[ ");
- for (i = 0; i < l->nitems; i++) {
- Printf(s, "%s", l->items[i]);
- if ((i + 1) < l->nitems)
- Printf(s, ", ");
- }
- Printf(s, " ]");
- ObjSetMark(lo, 0);
- return s;
-}
-
-/* -----------------------------------------------------------------------------
- * List_dump()
- *
- * Dump the items to an output stream.
- * ----------------------------------------------------------------------------- */
-
-static int List_dump(DOH *lo, DOH *out) {
- int nsent = 0;
- int i, ret;
- List *l = (List *) ObjData(lo);
- for (i = 0; i < l->nitems; i++) {
- ret = Dump(l->items[i], out);
- if (ret < 0)
- return -1;
- nsent += ret;
- }
- return nsent;
-}
-
-static void List_setfile(DOH *lo, DOH *file) {
- DOH *fo;
- List *l = (List *) ObjData(lo);
-
- if (!DohCheck(file)) {
- fo = NewString(file);
- Decref(fo);
- } else
- fo = file;
- Incref(fo);
- Delete(l->file);
- l->file = fo;
-}
-
-static DOH *List_getfile(DOH *lo) {
- List *l = (List *) ObjData(lo);
- return l->file;
-}
-
-static void List_setline(DOH *lo, int line) {
- List *l = (List *) ObjData(lo);
- l->line = line;
-}
-
-static int List_getline(DOH *lo) {
- List *l = (List *) ObjData(lo);
- return l->line;
-}
-
-static DohListMethods ListListMethods = {
- List_get,
- List_set,
- List_remove,
- List_insert,
- 0, /* delslice */
-};
-
-DohObjInfo DohListType = {
- "List", /* objname */
- DelList, /* doh_del */
- CopyList, /* doh_copy */
- List_clear, /* doh_clear */
- List_str, /* doh_str */
- 0, /* doh_data */
- List_dump, /* doh_dump */
- List_len, /* doh_len */
- 0, /* doh_hash */
- 0, /* doh_cmp */
- 0, /* doh_equal */
- List_first, /* doh_first */
- List_next, /* doh_next */
- List_setfile, /* doh_setfile */
- List_getfile, /* doh_getfile */
- List_setline, /* doh_setline */
- List_getline, /* doh_getline */
- 0, /* doh_mapping */
- &ListListMethods, /* doh_sequence */
- 0, /* doh_file */
- 0, /* doh_string */
- 0, /* doh_callable */
- 0, /* doh_position */
-};
-
-/* -----------------------------------------------------------------------------
- * NewList()
- *
- * Create a new list.
- * ----------------------------------------------------------------------------- */
-
-#define MAXLISTITEMS 8
-
-DOH *DohNewList(void) {
- List *l = (List *) DohMalloc(sizeof(List));
- l->nitems = 0;
- l->maxitems = MAXLISTITEMS;
- l->items = (void **) DohCalloc(l->maxitems, sizeof(void *));
- l->file = 0;
- l->line = 0;
- return DohObjMalloc(&DohListType, l);
-}
-
-static int (*List_sort_compare_func) (const DOH *, const DOH *);
-static int List_qsort_compare(const void *a, const void *b) {
- return List_sort_compare_func(*((DOH **) a), *((DOH **) b));
-}
-
-/* Sort a list */
-void DohSortList(DOH *lo, int (*cmp) (const DOH *, const DOH *)) {
- List *l = (List *) ObjData(lo);
- if (cmp) {
- List_sort_compare_func = cmp;
- } else {
- List_sort_compare_func = DohCmp;
- }
- qsort(l->items, l->nitems, sizeof(DOH *), List_qsort_compare);
-}
diff --git a/contrib/tools/swig/Source/DOH/memory.c b/contrib/tools/swig/Source/DOH/memory.c
deleted file mode 100644
index f8081d3aee..0000000000
--- a/contrib/tools/swig/Source/DOH/memory.c
+++ /dev/null
@@ -1,292 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * memory.c
- *
- * This file implements all of DOH's memory management including allocation
- * of objects and checking of objects.
- * ----------------------------------------------------------------------------- */
-
-#include "dohint.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#ifndef DOH_POOL_SIZE
-#define DOH_POOL_SIZE 4194304
-#endif
-
-/* Checks stale DOH object use - will use a lot more memory as pool memory is not re-used. */
-/*
-#define DOH_DEBUG_MEMORY_POOLS
-*/
-
-static int PoolSize = DOH_POOL_SIZE;
-
-DOH *DohNone = 0; /* The DOH None object */
-
-typedef struct pool {
- DohBase *ptr; /* Start of pool */
- int len; /* Length of pool */
- int blen; /* Byte length of pool */
- int current; /* Current position for next allocation */
- char *pbeg; /* Beg of pool */
- char *pend; /* End of pool */
- struct pool *next; /* Next pool */
-} Pool;
-
-static DohBase *FreeList = 0; /* List of free objects */
-static Pool *Pools = 0;
-static int pools_initialized = 0;
-
-/* ----------------------------------------------------------------------
- * CreatePool() - Create a new memory pool
- * ---------------------------------------------------------------------- */
-
-static void CreatePool(void) {
- Pool *p = 0;
- p = (Pool *) DohMalloc(sizeof(Pool));
- p->ptr = (DohBase *) DohCalloc(PoolSize, sizeof(DohBase));
- p->len = PoolSize;
- p->blen = PoolSize * sizeof(DohBase);
- p->current = 0;
- p->pbeg = ((char *) p->ptr);
- p->pend = p->pbeg + p->blen;
- p->next = Pools;
- Pools = p;
-}
-
-/* ----------------------------------------------------------------------
- * InitPools() - Initialize the memory allocator
- * ---------------------------------------------------------------------- */
-
-static void InitPools(void) {
- if (pools_initialized)
- return;
- CreatePool(); /* Create initial pool */
- pools_initialized = 1;
- DohNone = NewVoid(0, 0); /* Create the None object */
- DohIntern(DohNone);
-}
-
-/* ----------------------------------------------------------------------
- * DohCheck()
- *
- * Returns 1 if an arbitrary pointer is a DOH object.
- * ---------------------------------------------------------------------- */
-
-int DohCheck(const DOH *ptr) {
- Pool *p = Pools;
- char *cptr = (char *) ptr;
- while (p) {
- if ((cptr >= p->pbeg) && (cptr < p->pend)) {
-#ifdef DOH_DEBUG_MEMORY_POOLS
- DohBase *b = (DohBase *) ptr;
- int DOH_object_already_deleted = b->type == 0;
- assert(!DOH_object_already_deleted);
-#endif
- return 1;
- }
- /*
- pptr = (char *) p->ptr;
- if ((cptr >= pptr) && (cptr < (pptr+(p->current*sizeof(DohBase))))) return 1; */
- p = p->next;
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * DohIntern()
- * ----------------------------------------------------------------------------- */
-
-void DohIntern(DOH *obj) {
- DohBase *b = (DohBase *) obj;
- b->flag_intern = 1;
-}
-
-/* ----------------------------------------------------------------------
- * DohObjMalloc()
- *
- * Allocate memory for a new object.
- * ---------------------------------------------------------------------- */
-
-DOH *DohObjMalloc(DohObjInfo *type, void *data) {
- DohBase *obj;
- if (!pools_initialized)
- InitPools();
-#ifndef DOH_DEBUG_MEMORY_POOLS
- if (FreeList) {
- obj = FreeList;
- FreeList = (DohBase *) obj->data;
- } else {
-#endif
- while (Pools->current == Pools->len) {
- CreatePool();
- }
- obj = Pools->ptr + Pools->current;
- ++Pools->current;
-#ifndef DOH_DEBUG_MEMORY_POOLS
- }
-#endif
- obj->type = type;
- obj->data = data;
- obj->meta = 0;
- obj->refcount = 1;
- obj->flag_intern = 0;
- obj->flag_marked = 0;
- obj->flag_user = 0;
- obj->flag_usermark = 0;
- return (DOH *) obj;
-}
-
-/* ----------------------------------------------------------------------
- * DohObjFree() - Free a DOH object
- * ---------------------------------------------------------------------- */
-
-void DohObjFree(DOH *ptr) {
- DohBase *b, *meta;
- b = (DohBase *) ptr;
- if (b->flag_intern)
- return;
- meta = (DohBase *) b->meta;
- b->data = (void *) FreeList;
- b->meta = 0;
- b->type = 0;
- b->refcount = 0;
- FreeList = b;
- if (meta) {
- Delete(meta);
- }
-}
-
-/* ----------------------------------------------------------------------
- * DohMemoryDebug()
- *
- * Display memory usage statistics
- * ---------------------------------------------------------------------- */
-
-void DohMemoryDebug(void) {
- extern DohObjInfo DohStringType;
- extern DohObjInfo DohListType;
- extern DohObjInfo DohHashType;
-
- Pool *p;
- int totsize = 0;
- int totused = 0;
- int totfree = 0;
-
- int numstring = 0;
- int numlist = 0;
- int numhash = 0;
-
- printf("Memory statistics:\n\n");
- printf("Pools:\n");
-
- p = Pools;
- while (p) {
- /* Calculate number of used, free items */
- int i;
- int nused = 0, nfree = 0;
- for (i = 0; i < p->len; i++) {
- if (p->ptr[i].refcount <= 0)
- nfree++;
- else {
- nused++;
- if (p->ptr[i].type == &DohStringType)
- numstring++;
- else if (p->ptr[i].type == &DohListType)
- numlist++;
- else if (p->ptr[i].type == &DohHashType)
- numhash++;
- }
- }
- printf(" Pool %8p: size = %10d. used = %10d. free = %10d\n", (void *) p, p->len, nused, nfree);
- totsize += p->len;
- totused += nused;
- totfree += nfree;
- p = p->next;
- }
- printf("\n Total: size = %10d, used = %10d, free = %10d\n", totsize, totused, totfree);
-
- printf("\nObject types\n");
- printf(" Strings : %d\n", numstring);
- printf(" Lists : %d\n", numlist);
- printf(" Hashes : %d\n", numhash);
-
-#if 0
- p = Pools;
- while (p) {
- int i;
- for (i = 0; i < p->len; i++) {
- if (p->ptr[i].refcount > 0) {
- if (p->ptr[i].type == &DohStringType) {
- Printf(stdout, "%s\n", p->ptr + i);
- }
- }
- }
- p = p->next;
- }
-#endif
-
-}
-
-/* Function to call instead of exit(). */
-static void (*doh_exit_handler)(int) = NULL;
-
-void DohSetExitHandler(void (*new_handler)(int)) {
- doh_exit_handler = new_handler;
-}
-
-void DohExit(int status) {
- if (doh_exit_handler) {
- void (*handler)(int) = doh_exit_handler;
- /* Unset the handler to avoid infinite loops if it tries to do something
- * which calls DohExit() (e.g. calling Malloc() and that failing).
- */
- doh_exit_handler = NULL;
- handler(status);
- }
- doh_internal_exit(status);
-}
-
-static void allocation_failed(size_t n, size_t size) {
- /* Report and exit as directly as possible to try to avoid further issues due
- * to lack of memory. */
- if (n == 1) {
-#if defined __STDC_VERSION__ && __STDC_VERSION__-0 >= 19901L
- fprintf(stderr, "Failed to allocate %zu bytes\n", size);
-#else
- fprintf(stderr, "Failed to allocate %lu bytes\n", (unsigned long)size);
-#endif
- } else {
-#if defined __STDC_VERSION__ && __STDC_VERSION__-0 >= 19901L
- fprintf(stderr, "Failed to allocate %zu*%zu bytes\n", n, size);
-#else
- fprintf(stderr, "Failed to allocate %lu*%lu bytes\n", (unsigned long)n, (unsigned long)size);
-#endif
- }
- DohExit(EXIT_FAILURE);
-}
-
-void *DohMalloc(size_t size) {
- void *p = doh_internal_malloc(size);
- if (!p) allocation_failed(1, size);
- return p;
-}
-
-void *DohRealloc(void *ptr, size_t size) {
- void *p = doh_internal_realloc(ptr, size);
- if (!p) allocation_failed(1, size);
- return p;
-}
-
-void *DohCalloc(size_t n, size_t size) {
- void *p = doh_internal_calloc(n, size);
- if (!p) allocation_failed(n, size);
- return p;
-}
diff --git a/contrib/tools/swig/Source/DOH/string.c b/contrib/tools/swig/Source/DOH/string.c
deleted file mode 100644
index c86cab0be5..0000000000
--- a/contrib/tools/swig/Source/DOH/string.c
+++ /dev/null
@@ -1,1286 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * string.c
- *
- * Implements a string object that supports both sequence operations and
- * file semantics.
- * ----------------------------------------------------------------------------- */
-
-#include "dohint.h"
-
-extern DohObjInfo DohStringType;
-
-typedef struct String {
- DOH *file;
- int line;
- int maxsize; /* Max size allocated */
- int len; /* Current length */
- int hashkey; /* Hash key value */
- int sp; /* Current position */
- char *str; /* String data */
-} String;
-
-/* -----------------------------------------------------------------------------
- * String_data() - Return as a 'void *'
- * ----------------------------------------------------------------------------- */
-
-static void *String_data(DOH *so) {
- String *s = (String *) ObjData(so);
- s->str[s->len] = 0;
- return (void *) s->str;
-}
-
-/* static char *String_char(DOH *so) {
- return (char *) String_data(so);
-}
-*/
-
-/* -----------------------------------------------------------------------------
- * String_dump() - Serialize a string onto out
- * ----------------------------------------------------------------------------- */
-
-static int String_dump(DOH *so, DOH *out) {
- int nsent;
- int ret;
- String *s = (String *) ObjData(so);
- nsent = 0;
- while (nsent < s->len) {
- ret = Write(out, s->str + nsent, (s->len - nsent));
- if (ret < 0)
- return ret;
- nsent += ret;
- }
- return nsent;
-}
-
-/* -----------------------------------------------------------------------------
- * CopyString() - Copy a string
- * ----------------------------------------------------------------------------- */
-
-static DOH *CopyString(DOH *so) {
- String *str;
- String *s = (String *) ObjData(so);
- str = (String *) DohMalloc(sizeof(String));
- str->hashkey = s->hashkey;
- str->sp = s->sp;
- str->line = s->line;
- str->file = s->file;
- if (str->file)
- Incref(str->file);
- str->str = (char *) DohMalloc(s->len + 1);
- memcpy(str->str, s->str, s->len);
- str->maxsize = s->len;
- str->len = s->len;
- str->str[str->len] = 0;
-
- return DohObjMalloc(&DohStringType, str);
-}
-
-/* -----------------------------------------------------------------------------
- * DelString() - Delete a string
- * ----------------------------------------------------------------------------- */
-
-static void DelString(DOH *so) {
- String *s = (String *) ObjData(so);
- DohFree(s->str);
- DohFree(s);
-}
-
-/* -----------------------------------------------------------------------------
- * DohString_len() - Length of a string
- * ----------------------------------------------------------------------------- */
-
-static int String_len(DOH *so) {
- String *s = (String *) ObjData(so);
- return s->len;
-}
-
-
-/* -----------------------------------------------------------------------------
- * String_cmp() - Compare two strings
- * ----------------------------------------------------------------------------- */
-
-static int String_cmp(DOH *so1, DOH *so2) {
- String *s1, *s2;
- char *c1, *c2;
- int maxlen, i;
- s1 = (String *) ObjData(so1);
- s2 = (String *) ObjData(so2);
- maxlen = s1->len;
- if (s2->len < maxlen)
- maxlen = s2->len;
- c1 = s1->str;
- c2 = s2->str;
- for (i = maxlen; i; --i, c1++, c2++) {
- if (*c1 != *c2)
- break;
- }
- if (i != 0) {
- if (*c1 < *c2)
- return -1;
- else
- return 1;
- }
- if (s1->len == s2->len)
- return 0;
- if (s1->len > s2->len)
- return 1;
- return -1;
-}
-
-/* -----------------------------------------------------------------------------
- * String_equal() - Say if two string are equal
- * ----------------------------------------------------------------------------- */
-
-static int String_equal(DOH *so1, DOH *so2) {
- String *s1 = (String *) ObjData(so1);
- String *s2 = (String *) ObjData(so2);
- int len = s1->len;
- if (len != s2->len) {
- return 0;
- } else {
- char *c1 = s1->str;
- char *c2 = s2->str;
-#if 0
- int mlen = len >> 2;
- int i = mlen;
- for (; i; --i) {
- if (*(c1++) != *(c2++))
- return 0;
- if (*(c1++) != *(c2++))
- return 0;
- if (*(c1++) != *(c2++))
- return 0;
- if (*(c1++) != *(c2++))
- return 0;
- }
- for (i = len - (mlen << 2); i; --i) {
- if (*(c1++) != *(c2++))
- return 0;
- }
- return 1;
-#else
- return memcmp(c1, c2, len) == 0;
-#endif
- }
-}
-
-/* -----------------------------------------------------------------------------
- * String_hash() - Compute string hash value
- * ----------------------------------------------------------------------------- */
-
-static int String_hash(DOH *so) {
- String *s = (String *) ObjData(so);
- if (s->hashkey >= 0) {
- return s->hashkey;
- } else {
- /* We use the djb2 hash function: https://theartincode.stanis.me/008-djb2/
- *
- * One difference is we use initial seed 0. It seems the usual seed value
- * is intended to help spread out hash values, which is beneficial if
- * linear probing is used but DOH Hash uses a chain of buckets instead, and
- * grouped hash values are probably more cache friendly. In tests using
- * 0 seems slightly faster anyway.
- */
- const char *c = s->str;
- unsigned int len = s->len > 50 ? 50 : s->len;
- unsigned int h = 0;
- unsigned int mlen = len >> 2;
- unsigned int i = mlen;
- for (; i; --i) {
- h = h + (h << 5) + *(c++);
- h = h + (h << 5) + *(c++);
- h = h + (h << 5) + *(c++);
- h = h + (h << 5) + *(c++);
- }
- for (i = len - (mlen << 2); i; --i) {
- h = h + (h << 5) + *(c++);
- }
- h &= 0x7fffffff;
- s->hashkey = (int)h;
- return h;
- }
-}
-
-/* -----------------------------------------------------------------------------
- * DohString_append() - Append to s
- * ----------------------------------------------------------------------------- */
-
-static void DohString_append(DOH *so, const DOHString_or_char *str) {
- int oldlen, newlen, newmaxsize, l, sp;
- char *tc;
- String *s = (String *) ObjData(so);
- char *newstr = 0;
-
- if (DohCheck(str)) {
- String *ss = (String *) ObjData(str);
- newstr = (char *) String_data((DOH *) str);
- l = ss->len;
- } else {
- newstr = (char *) (str);
- l = (int) strlen(newstr);
- }
- if (!newstr)
- return;
- s->hashkey = -1;
-
- oldlen = s->len;
- newlen = oldlen + l + 1;
- if (newlen >= s->maxsize - 1) {
- newmaxsize = 2 * s->maxsize;
- if (newlen >= newmaxsize - 1)
- newmaxsize = newlen + 1;
- s->str = (char *) DohRealloc(s->str, newmaxsize);
- s->maxsize = newmaxsize;
- }
- tc = s->str;
- memcpy(tc + oldlen, newstr, l + 1);
- sp = s->sp;
- if (sp >= oldlen) {
- int i = oldlen + l - sp;
- tc += sp;
- for (; i; --i) {
- if (*(tc++) == '\n')
- s->line++;
- }
- s->sp = oldlen + l;
- }
- s->len += l;
-}
-
-
-/* -----------------------------------------------------------------------------
- * String_clear() - Clear a string
- * ----------------------------------------------------------------------------- */
-
-static void String_clear(DOH *so) {
- String *s = (String *) ObjData(so);
- s->hashkey = -1;
- s->len = 0;
- *(s->str) = 0;
- s->sp = 0;
- s->line = 1;
-}
-
-/* -----------------------------------------------------------------------------
- * String_insert() - Insert a string
- * ----------------------------------------------------------------------------- */
-
-static int String_insert(DOH *so, int pos, DOH *str) {
- String *s;
- int len;
- char *data;
-
- if (pos == DOH_END) {
- DohString_append(so, str);
- return 0;
- }
-
-
- s = (String *) ObjData(so);
- s->hashkey = -1;
- if (DohCheck(str)) {
- String *ss = (String *) ObjData(str);
- data = (char *) String_data(str);
- len = ss->len;
- } else {
- data = (char *) (str);
- len = (int) strlen(data);
- }
-
- if (pos < 0)
- pos = 0;
- else if (pos > s->len)
- pos = s->len;
-
- /* See if there is room to insert the new data */
- while (s->maxsize <= s->len + len) {
- int newsize = 2 * s->maxsize;
- s->str = (char *) DohRealloc(s->str, newsize);
- s->maxsize = newsize;
- }
- memmove(s->str + pos + len, s->str + pos, (s->len - pos));
- memcpy(s->str + pos, data, len);
- if (s->sp >= pos) {
- int i;
-
- for (i = 0; i < len; i++) {
- if (data[i] == '\n')
- s->line++;
- }
- s->sp += len;
- }
- s->len += len;
- s->str[s->len] = 0;
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * String_delitem() - Delete a character
- * ----------------------------------------------------------------------------- */
-
-static int String_delitem(DOH *so, int pos) {
- String *s = (String *) ObjData(so);
- s->hashkey = -1;
- if (pos == DOH_END)
- pos = s->len - 1;
- if (pos == DOH_BEGIN)
- pos = 0;
- if (s->len == 0)
- return 0;
-
- if (s->sp > pos) {
- s->sp--;
- assert(s->sp >= 0);
- if (s->str[pos] == '\n')
- s->line--;
- }
- memmove(s->str + pos, s->str + pos + 1, ((s->len - 1) - pos));
- s->len--;
- s->str[s->len] = 0;
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * String_delslice() - Delete a range
- * ----------------------------------------------------------------------------- */
-
-static int String_delslice(DOH *so, int sindex, int eindex) {
- String *s = (String *) ObjData(so);
- int size;
- if (s->len == 0)
- return 0;
- s->hashkey = -1;
- if (eindex == DOH_END)
- eindex = s->len;
- if (sindex == DOH_BEGIN)
- sindex = 0;
-
- size = eindex - sindex;
- if (s->sp > sindex) {
- /* Adjust the file pointer and line count */
- int i, end;
- if (s->sp > eindex) {
- end = eindex;
- s->sp -= size;
- } else {
- end = s->sp;
- s->sp = sindex;
- }
- for (i = sindex; i < end; i++) {
- if (s->str[i] == '\n')
- s->line--;
- }
- assert(s->sp >= 0);
- }
- memmove(s->str + sindex, s->str + eindex, s->len - eindex);
- s->len -= size;
- s->str[s->len] = 0;
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * String_str() - Returns a string (used by printing commands)
- * ----------------------------------------------------------------------------- */
-
-static DOH *String_str(DOH *so) {
- String *s = (String *) ObjData(so);
- s->str[s->len] = 0;
- return NewString(s->str);
-}
-
-/* -----------------------------------------------------------------------------
- * String_read() - Read data from a string
- * ----------------------------------------------------------------------------- */
-
-static int String_read(DOH *so, void *buffer, int len) {
- int reallen, retlen;
- char *cb;
- String *s = (String *) ObjData(so);
- if ((s->sp + len) > s->len)
- reallen = (s->len - s->sp);
- else
- reallen = len;
-
- cb = (char *) buffer;
- retlen = reallen;
-
- if (reallen > 0) {
- memmove(cb, s->str + s->sp, reallen);
- s->sp += reallen;
- }
- return retlen;
-}
-
-/* -----------------------------------------------------------------------------
- * String_write() - Write data to a string
- * ----------------------------------------------------------------------------- */
-static int String_write(DOH *so, const void *buffer, int len) {
- int newlen;
- String *s = (String *) ObjData(so);
- s->hashkey = -1;
- if (s->sp > s->len)
- s->sp = s->len;
- newlen = s->sp + len + 1;
- if (newlen > s->maxsize) {
- s->str = (char *) DohRealloc(s->str, newlen);
- s->maxsize = newlen;
- s->len = s->sp + len;
- }
- if ((s->sp + len) > s->len)
- s->len = s->sp + len;
- memmove(s->str + s->sp, buffer, len);
- s->sp += len;
- s->str[s->len] = 0;
- return len;
-}
-
-/* -----------------------------------------------------------------------------
- * String_seek() - Seek to a new position
- * ----------------------------------------------------------------------------- */
-
-static int String_seek(DOH *so, long offset, int whence) {
- int pos, nsp, inc;
- String *s = (String *) ObjData(so);
- if (whence == SEEK_SET)
- pos = 0;
- else if (whence == SEEK_CUR)
- pos = s->sp;
- else if (whence == SEEK_END) {
- pos = s->len;
- offset = -offset;
- } else
- pos = s->sp;
-
- nsp = pos + offset;
- if (nsp < 0)
- nsp = 0;
- if (s->len > 0 && nsp > s->len)
- nsp = s->len;
-
- inc = (nsp > s->sp) ? 1 : -1;
-
- {
-#if 0
- int sp = s->sp;
- char *tc = s->str;
- int len = s->len;
- while (sp != nsp) {
- int prev = sp + inc;
- if (prev >= 0 && prev <= len && tc[prev] == '\n')
- s->line += inc;
- sp += inc;
- }
-#else
- int sp = s->sp;
- char *tc = s->str;
- if (inc > 0) {
- while (sp != nsp) {
- if (tc[++sp] == '\n')
- ++s->line;
- }
- } else {
- while (sp != nsp) {
- if (tc[--sp] == '\n')
- --s->line;
- }
- }
-#endif
- s->sp = sp;
- }
- assert(s->sp >= 0);
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * String_tell() - Return current position
- * ----------------------------------------------------------------------------- */
-
-static long String_tell(DOH *so) {
- String *s = (String *) ObjData(so);
- return (long) (s->sp);
-}
-
-/* -----------------------------------------------------------------------------
- * String_putc()
- * ----------------------------------------------------------------------------- */
-
-static int String_putc(DOH *so, int ch) {
- String *s = (String *) ObjData(so);
- int len = s->len;
- int sp = s->sp;
- s->hashkey = -1;
- if (sp >= len) {
- int maxsize = s->maxsize;
- char *tc = s->str;
- if (len > (maxsize - 2)) {
- maxsize *= 2;
- tc = (char *) DohRealloc(tc, maxsize);
- s->maxsize = (int) maxsize;
- s->str = tc;
- }
- tc += sp;
- *tc = (char) ch;
- *(++tc) = 0;
- s->len = s->sp = sp + 1;
- } else {
- s->str[s->sp++] = (char) ch;
- }
- if (ch == '\n')
- s->line++;
- return ch;
-}
-
-/* -----------------------------------------------------------------------------
- * String_getc()
- * ----------------------------------------------------------------------------- */
-
-static int String_getc(DOH *so) {
- int c;
- String *s = (String *) ObjData(so);
- if (s->sp >= s->len)
- c = EOF;
- else
- c = (int)(unsigned char) s->str[s->sp++];
- if (c == '\n')
- s->line++;
- return c;
-}
-
-/* -----------------------------------------------------------------------------
- * String_ungetc()
- * ----------------------------------------------------------------------------- */
-
-static int String_ungetc(DOH *so, int ch) {
- String *s = (String *) ObjData(so);
- if (ch == EOF)
- return ch;
- if (s->sp <= 0)
- return EOF;
- s->sp--;
- if (ch == '\n')
- s->line--;
- return ch;
-}
-
-static char *end_quote(char *s) {
- char *qs;
- char qc;
- char *q;
- char *nl;
- qc = *s;
- qs = s;
- while (1) {
- q = strpbrk(s + 1, "\"\'");
- nl = strchr(s + 1, '\n');
- if (nl && (nl < q)) {
- /* A new line appears before the end of the string */
- if (*(nl - 1) == '\\') {
- s = nl + 1;
- continue;
- }
- /* String was terminated by a newline. Wing it */
- return qs;
- }
- if (!q && nl) {
- return qs;
- }
- if (!q)
- return 0;
- if ((*q == qc) && (*(q - 1) != '\\'))
- return q;
- s = q;
- }
-}
-
-static char *end_comment(char *s) {
- char *substring = strstr(s, "*/");
- if (substring)
- ++substring;
- return substring;
-}
-
-static char *match_simple(char *base, char *s, char *token, int tokenlen) {
- (void) base;
- (void) tokenlen;
- return strstr(s, token);
-}
-
-static char *match_identifier(char *base, char *s, char *token, int tokenlen) {
- while (s) {
- s = strstr(s, token);
- if (!s)
- return 0;
- if ((s > base) && (isalnum((int) *(s - 1)) || (*(s - 1) == '_'))) {
- /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */
- ++s;
- continue;
- }
- if (isalnum((int) *(s + tokenlen)) || (*(s + tokenlen) == '_')) {
- /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */
- ++s;
- continue;
- }
- return s;
- }
- return 0;
-}
-
-
-static char *match_identifier_begin(char *base, char *s, char *token, int tokenlen) {
- (void)tokenlen;
- while (s) {
- s = strstr(s, token);
- if (!s)
- return 0;
- if ((s > base) && (isalnum((int) *(s - 1)) || (*(s - 1) == '_'))) {
- /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */
- ++s;
- continue;
- }
- return s;
- }
- return 0;
-}
-
-static char *match_identifier_end(char *base, char *s, char *token, int tokenlen) {
- (void) base;
- while (s) {
- s = strstr(s, token);
- if (!s)
- return 0;
- if (isalnum((int) *(s + tokenlen)) || (*(s + tokenlen) == '_')) {
- /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */
- ++s;
- continue;
- }
- return s;
- }
- return 0;
-}
-
-static char *match_number_end(char *base, char *s, char *token, int tokenlen) {
- (void) base;
- while (s) {
- s = strstr(s, token);
- if (!s)
- return 0;
- if (isdigit((int) *(s + tokenlen))) {
- /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */
- ++s;
- continue;
- }
- return s;
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * replace_simple()
- *
- * Replaces count non-overlapping occurrences of token with rep in a string.
- * ----------------------------------------------------------------------------- */
-
-static int replace_simple(String *str, char *token, char *rep, int flags, int count, char *(*match) (char *, char *, char *, int)) {
- int tokenlen; /* Length of the token */
- int replen; /* Length of the replacement */
- int delta, expand = 0;
- int ic;
- int rcount = 0;
- int noquote = 0;
- int nocomment = 0;
- char *c, *s, *t, *first;
- char *q, *q2;
- char *base;
- int i;
-
- /* Figure out if anything gets replaced */
- if (!strlen(token))
- return 0;
-
- base = str->str;
- tokenlen = (int)strlen(token);
- s = (*match) (base, base, token, tokenlen);
-
- if (!s)
- return 0; /* No matches. Who cares */
-
- str->hashkey = -1;
-
- if (flags & DOH_REPLACE_NOQUOTE)
- noquote = 1;
-
- if (flags & DOH_REPLACE_NOCOMMENT)
- nocomment = 1;
-
- assert(!(noquote && nocomment)); /* quote and comment combination not implemented */
-
- /* If we are not replacing inside quotes, we need to do a little extra work */
- if (noquote) {
- q = strpbrk(base, "\"\'");
- if (!q) {
- noquote = 0; /* Well, no quotes to worry about. Oh well */
- } else {
- while (q && (q < s)) {
- /* First match was found inside a quote. Try to find another match */
- q2 = end_quote(q);
- if (!q2) {
- return 0;
- }
- if (q2 > s) {
- /* Find next match */
- s = (*match) (base, q2 + 1, token, tokenlen);
- }
- if (!s)
- return 0; /* Oh well, no matches */
- q = strpbrk(q2 + 1, "\"\'");
- if (!q)
- noquote = 0; /* No more quotes */
- }
- }
- }
-
- /* If we are not replacing inside comments, we need to do a little extra work */
- if (nocomment) {
- q = strstr(base, "/*");
- if (!q) {
- nocomment = 0; /* Well, no comments to worry about. Oh well */
- } else {
- while (q && (q < s)) {
- /* First match was found inside a comment. Try to find another match */
- q2 = end_comment(q);
- if (!q2) {
- return 0;
- }
- if (q2 > s) {
- /* Find next match */
- s = (*match) (base, q2 + 1, token, tokenlen);
- }
- if (!s)
- return 0; /* Oh well, no matches */
- q = strstr(q2 + 1, "/*");
- if (!q)
- nocomment = 0; /* No more comments */
- }
- }
- }
-
- first = s;
- replen = (int)strlen(rep);
-
- delta = (replen - tokenlen);
-
- if (delta <= 0) {
- /* String is either shrinking or staying the same size */
- /* In this case, we do the replacement in place without memory reallocation */
- ic = count;
- t = s; /* Target of memory copies */
- while (ic && s) {
- if (replen) {
- memcpy(t, rep, replen);
- t += replen;
- }
- rcount++;
- expand += delta;
- /* Find the next location */
- s += tokenlen;
- if (ic == 1)
- break;
- c = (*match) (base, s, token, tokenlen);
-
- if (noquote) {
- q = strpbrk(s, "\"\'");
- if (!q) {
- noquote = 0;
- } else {
- while (q && (q < c)) {
- /* First match was found inside a quote. Try to find another match */
- q2 = end_quote(q);
- if (!q2) {
- c = 0;
- break;
- }
- if (q2 > c)
- c = (*match) (base, q2 + 1, token, tokenlen);
- if (!c)
- break;
- q = strpbrk(q2 + 1, "\"\'");
- if (!q)
- noquote = 0; /* No more quotes */
- }
- }
- }
- if (nocomment) {
- q = strstr(s, "/*");
- if (!q) {
- nocomment = 0;
- } else {
- while (q && (q < c)) {
- /* First match was found inside a comment. Try to find another match */
- q2 = end_comment(q);
- if (!q2) {
- c = 0;
- break;
- }
- if (q2 > c)
- c = (*match) (base, q2 + 1, token, tokenlen);
- if (!c)
- break;
- q = strstr(q2 + 1, "/*");
- if (!q)
- nocomment = 0; /* No more comments */
- }
- }
- }
- if (delta) {
- if (c) {
- memmove(t, s, c - s);
- t += (c - s);
- } else {
- memmove(t, s, (str->str + str->len) - s + 1);
- }
- } else {
- if (c) {
- t += (c - s);
- }
- }
- s = c;
- ic--;
- }
- if (s && delta) {
- memmove(t, s, (str->str + str->len) - s + 1);
- }
- str->len += expand;
- str->str[str->len] = 0;
- if (str->sp >= str->len)
- str->sp += expand; /* Fix the end of file pointer */
- return rcount;
- }
- /* The string is expanding as a result of the replacement */
- /* Figure out how much expansion is going to occur and allocate a new string */
- {
- char *ns;
- int newsize;
-
- rcount++;
- ic = count - 1;
- s += tokenlen;
- while (ic && (c = (*match) (base, s, token, tokenlen))) {
- if (noquote) {
- q = strpbrk(s, "\"\'");
- if (!q) {
- break;
- } else {
- while (q && (q < c)) {
- /* First match was found inside a quote. Try to find another match */
- q2 = end_quote(q);
- if (!q2) {
- c = 0;
- break;
- }
- if (q2 > c) {
- c = (*match) (base, q2 + 1, token, tokenlen);
- if (!c)
- break;
- }
- q = strpbrk(q2 + 1, "\"\'");
- if (!q)
- noquote = 0;
- }
- }
- }
- if (nocomment) {
- q = strstr(s, "/*");
- if (!q) {
- break;
- } else {
- while (q && (q < c)) {
- /* First match was found inside a comment. Try to find another match */
- q2 = end_comment(q);
- if (!q2) {
- c = 0;
- break;
- }
- if (q2 > c) {
- c = (*match) (base, q2 + 1, token, tokenlen);
- if (!c)
- break;
- }
- q = strstr(q2 + 1, "/*");
- if (!q)
- nocomment = 0;
- }
- }
- }
- if (c) {
- rcount++;
- ic--;
- s = c + tokenlen;
- } else {
- break;
- }
- }
-
- expand = delta * rcount; /* Total amount of expansion for the replacement */
- newsize = str->maxsize;
- while ((str->len + expand) >= newsize)
- newsize *= 2;
-
- ns = (char *) DohMalloc(newsize);
- t = ns;
- s = first;
-
- /* Copy the first part of the string */
- if (first > str->str) {
- memcpy(t, str->str, (first - str->str));
- t += (first - str->str);
- }
- for (i = 0; i < rcount; i++) {
- memcpy(t, rep, replen);
- t += replen;
- s += tokenlen;
- c = (*match) (base, s, token, tokenlen);
- if (noquote) {
- q = strpbrk(s, "\"\'");
- if (!q) {
- noquote = 0;
- } else {
- while (q && (q < c)) {
- /* First match was found inside a quote. Try to find another match */
- q2 = end_quote(q);
- if (!q2) {
- c = 0;
- break;
- }
- if (q2 > c) {
- c = (*match) (base, q2 + 1, token, tokenlen);
- if (!c)
- break;
- }
- q = strpbrk(q2 + 1, "\"\'");
- if (!q)
- noquote = 0; /* No more quotes */
- }
- }
- }
- if (nocomment) {
- q = strstr(s, "/*");
- if (!q) {
- nocomment = 0;
- } else {
- while (q && (q < c)) {
- /* First match was found inside a comment. Try to find another match */
- q2 = end_comment(q);
- if (!q2) {
- c = 0;
- break;
- }
- if (q2 > c) {
- c = (*match) (base, q2 + 1, token, tokenlen);
- if (!c)
- break;
- }
- q = strstr(q2 + 1, "/*");
- if (!q)
- nocomment = 0; /* No more comments */
- }
- }
- }
- if (i < (rcount - 1)) {
- memcpy(t, s, c - s);
- t += (c - s);
- } else {
- memcpy(t, s, (str->str + str->len) - s + 1);
- }
- s = c;
- }
- c = str->str;
- str->str = ns;
- if (str->sp >= str->len)
- str->sp += expand;
- str->len += expand;
- str->str[str->len] = 0;
- str->maxsize = newsize;
- DohFree(c);
- return rcount;
- }
-}
-
-/* -----------------------------------------------------------------------------
- * String_replace()
- * ----------------------------------------------------------------------------- */
-
-static int String_replace(DOH *stro, const DOHString_or_char *token, const DOHString_or_char *rep, int flags) {
- int count = -1;
- String *str = (String *) ObjData(stro);
-
- if (flags & DOH_REPLACE_FIRST)
- count = 1;
-
- if (flags & DOH_REPLACE_ID_END) {
- return replace_simple(str, Char(token), Char(rep), flags, count, match_identifier_end);
- } else if (flags & DOH_REPLACE_ID_BEGIN) {
- return replace_simple(str, Char(token), Char(rep), flags, count, match_identifier_begin);
- } else if (flags & DOH_REPLACE_ID) {
- return replace_simple(str, Char(token), Char(rep), flags, count, match_identifier);
- } else if (flags & DOH_REPLACE_NUMBER_END) {
- return replace_simple(str, Char(token), Char(rep), flags, count, match_number_end);
- } else {
- return replace_simple(str, Char(token), Char(rep), flags, count, match_simple);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * String_chop()
- * ----------------------------------------------------------------------------- */
-
-static void String_chop(DOH *so) {
- char *c;
- String *str = (String *) ObjData(so);
- /* Replace trailing whitespace */
- c = str->str + str->len - 1;
- while ((str->len > 0) && (isspace((int) *c))) {
- if (str->sp >= str->len) {
- str->sp--;
- if (*c == '\n')
- str->line--;
- }
- str->len--;
- c--;
- }
- str->str[str->len] = 0;
- assert(str->sp >= 0);
- str->hashkey = -1;
-}
-
-static void String_setfile(DOH *so, DOH *file) {
- DOH *fo;
- String *str = (String *) ObjData(so);
-
- if (!DohCheck(file)) {
- fo = NewString(file);
- Decref(fo);
- } else
- fo = file;
- Incref(fo);
- Delete(str->file);
- str->file = fo;
-}
-
-static DOH *String_getfile(DOH *so) {
- String *str = (String *) ObjData(so);
- return str->file;
-}
-
-static void String_setline(DOH *so, int line) {
- String *str = (String *) ObjData(so);
- str->line = line;
-}
-
-static int String_getline(DOH *so) {
- String *str = (String *) ObjData(so);
- return str->line;
-}
-
-static DohListMethods StringListMethods = {
- 0, /* doh_getitem */
- 0, /* doh_setitem */
- String_delitem, /* doh_delitem */
- String_insert, /* doh_insitem */
- String_delslice, /* doh_delslice */
-};
-
-static DohFileMethods StringFileMethods = {
- String_read,
- String_write,
- String_putc,
- String_getc,
- String_ungetc,
- String_seek,
- String_tell,
-};
-
-static DohStringMethods StringStringMethods = {
- String_replace,
- String_chop,
-};
-
-DohObjInfo DohStringType = {
- "String", /* objname */
- DelString, /* doh_del */
- CopyString, /* doh_copy */
- String_clear, /* doh_clear */
- String_str, /* doh_str */
- String_data, /* doh_data */
- String_dump, /* doh_dump */
- String_len, /* doh_len */
- String_hash, /* doh_hash */
- String_cmp, /* doh_cmp */
- String_equal, /* doh_equal */
- 0, /* doh_first */
- 0, /* doh_next */
- String_setfile, /* doh_setfile */
- String_getfile, /* doh_getfile */
- String_setline, /* doh_setline */
- String_getline, /* doh_getline */
- 0, /* doh_mapping */
- &StringListMethods, /* doh_sequence */
- &StringFileMethods, /* doh_file */
- &StringStringMethods, /* doh_string */
- 0, /* doh_position */
- 0
-};
-
-
-#define INIT_MAXSIZE 16
-
-/* -----------------------------------------------------------------------------
- * NewString() - Create a new string
- * ----------------------------------------------------------------------------- */
-
-DOHString *DohNewString(const DOHString_or_char *so) {
- int l = 0, max;
- String *str;
- char *s;
- int hashkey = -1;
- if (DohCheck(so)) {
- str = (String *) ObjData(so);
- s = (char *) String_data((String *) so);
- l = s ? str->len : 0;
- hashkey = str->hashkey;
- } else {
- s = (char *) so;
- l = s ? (int) strlen(s) : 0;
- }
-
- str = (String *) DohMalloc(sizeof(String));
- str->hashkey = hashkey;
- str->sp = 0;
- str->line = 1;
- str->file = 0;
- max = INIT_MAXSIZE;
- if (s) {
- if ((l + 1) > max)
- max = l + 1;
- }
- str->str = (char *) DohMalloc(max);
- str->maxsize = max;
- if (s) {
- strcpy(str->str, s);
- str->len = l;
- str->sp = l;
- } else {
- str->str[0] = 0;
- str->len = 0;
- }
- return DohObjMalloc(&DohStringType, str);
-}
-
-
-/* -----------------------------------------------------------------------------
- * NewStringEmpty() - Create a new string
- * ----------------------------------------------------------------------------- */
-
-DOHString *DohNewStringEmpty(void) {
- int max = INIT_MAXSIZE;
- String *str = (String *) DohMalloc(sizeof(String));
- str->hashkey = 0;
- str->sp = 0;
- str->line = 1;
- str->file = 0;
- str->str = (char *) DohMalloc(max);
- str->maxsize = max;
- str->str[0] = 0;
- str->len = 0;
- return DohObjMalloc(&DohStringType, str);
-}
-
-/* -----------------------------------------------------------------------------
- * NewStringWithSize() - Create a new string
- * ----------------------------------------------------------------------------- */
-
-DOHString *DohNewStringWithSize(const DOHString_or_char *so, int len) {
- int l = 0, max;
- String *str;
- char *s;
- if (DohCheck(so)) {
- s = (char *) String_data((String *) so);
- } else {
- s = (char *) so;
- }
-
- str = (String *) DohMalloc(sizeof(String));
- str->hashkey = -1;
- str->sp = 0;
- str->line = 1;
- str->file = 0;
- max = INIT_MAXSIZE;
- if (s) {
- l = (int) len;
- if ((l + 1) > max)
- max = l + 1;
- }
- str->str = (char *) DohMalloc(max);
- str->maxsize = max;
- if (s) {
- strncpy(str->str, s, len);
- str->str[l] = 0;
- str->len = l;
- str->sp = l;
- } else {
- str->str[0] = 0;
- str->len = 0;
- }
- return DohObjMalloc(&DohStringType, str);
-}
-
-/* -----------------------------------------------------------------------------
- * NewStringf()
- *
- * Create a new string from a list of objects.
- * ----------------------------------------------------------------------------- */
-
-DOHString *DohNewStringf(const DOHString_or_char *fmt, ...) {
- va_list ap;
- DOH *r;
- va_start(ap, fmt);
- r = NewStringEmpty();
- DohvPrintf(r, Char(fmt), ap);
- va_end(ap);
- return (DOHString *) r;
-}
-
-/* -----------------------------------------------------------------------------
- * Strcmp()
- * Strncmp()
- * Strstr()
- * Strchr()
- *
- * Some utility functions.
- * ----------------------------------------------------------------------------- */
-
-int DohStrcmp(const DOHString_or_char *s1, const DOHString_or_char *s2) {
- const char *c1 = Char(s1);
- const char *c2 = Char(s2);
- return strcmp(c1, c2);
-}
-
-int DohStrncmp(const DOHString_or_char *s1, const DOHString_or_char *s2, int n) {
- return strncmp(Char(s1), Char(s2), n);
-}
-
-char *DohStrstr(const DOHString_or_char *s1, const DOHString_or_char *s2) {
- char *p1 = Char(s1);
- char *p2 = Char(s2);
- return p1 == 0 || p2 == 0 || *p2 == '\0' ? p1 : strstr(p1, p2);
-}
-
-char *DohStrchr(const DOHString_or_char *s1, int ch) {
- return strchr(Char(s1), ch);
-}
diff --git a/contrib/tools/swig/Source/DOH/void.c b/contrib/tools/swig/Source/DOH/void.c
deleted file mode 100644
index bbecca21b4..0000000000
--- a/contrib/tools/swig/Source/DOH/void.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * void.c
- *
- * Implements a "void" object that is really just a DOH container around
- * an arbitrary C object represented as a void *.
- * ----------------------------------------------------------------------------- */
-
-#include "dohint.h"
-
-typedef struct {
- void *ptr;
- void (*del) (void *);
-} VoidObj;
-
-/* -----------------------------------------------------------------------------
- * Void_delete()
- *
- * Delete a void object. Invokes the destructor supplied at the time of creation.
- * ----------------------------------------------------------------------------- */
-
-static void Void_delete(DOH *vo) {
- VoidObj *v = (VoidObj *) ObjData(vo);
- if (v->del)
- (*v->del) (v->ptr);
- DohFree(v);
-}
-
-/* -----------------------------------------------------------------------------
- * Void_copy()
- *
- * Copies a void object. This is only a shallow copy. The object destruction
- * function is not copied in order to avoid potential double-free problems.
- * ----------------------------------------------------------------------------- */
-
-static DOH *Void_copy(DOH *vo) {
- VoidObj *v = (VoidObj *) ObjData(vo);
- return NewVoid(v->ptr, 0);
-}
-
-/* -----------------------------------------------------------------------------
- * Void_data()
- *
- * Returns the void * stored in the object.
- * ----------------------------------------------------------------------------- */
-
-static void *Void_data(DOH *vo) {
- VoidObj *v = (VoidObj *) ObjData(vo);
- return v->ptr;
-}
-
-static DohObjInfo DohVoidType = {
- "VoidObj", /* objname */
- Void_delete, /* doh_del */
- Void_copy, /* doh_copy */
- 0, /* doh_clear */
- 0, /* doh_str */
- Void_data, /* doh_data */
- 0, /* doh_dump */
- 0, /* doh_len */
- 0, /* doh_hash */
- 0, /* doh_cmp */
- 0, /* doh_equal */
- 0, /* doh_first */
- 0, /* doh_next */
- 0, /* doh_setfile */
- 0, /* doh_getfile */
- 0, /* doh_setline */
- 0, /* doh_getline */
- 0, /* doh_mapping */
- 0, /* doh_sequence */
- 0, /* doh_file */
- 0, /* doh_string */
- 0, /* doh_reserved */
- 0, /* clientdata */
-};
-
-/* -----------------------------------------------------------------------------
- * NewVoid()
- *
- * Creates a new Void object given a void * and an optional destructor function.
- * ----------------------------------------------------------------------------- */
-
-DOH *DohNewVoid(void *obj, void (*del) (void *)) {
- VoidObj *v;
- v = (VoidObj *) DohMalloc(sizeof(VoidObj));
- v->ptr = obj;
- v->del = del;
- return DohObjMalloc(&DohVoidType, v);
-}
diff --git a/contrib/tools/swig/Source/Doxygen/doxycommands.h b/contrib/tools/swig/Source/Doxygen/doxycommands.h
deleted file mode 100644
index 782b6ab944..0000000000
--- a/contrib/tools/swig/Source/Doxygen/doxycommands.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * doxycommands.h
- *
- * Part of the Doxygen comment translation module of SWIG.
- * ----------------------------------------------------------------------------- */
-
-#ifndef DOXYGENCOMMANDS_H
-#define DOXYGENCOMMANDS_H
-
-// doxy commands are not processed inside this block
-const char *CMD_HTML_ONLY = "htmlonly";
-// doxy commands are not processed inside this block
-const char *CMD_VERBATIM = "verbatim";
-const char *CMD_CODE = "code";
-const char *CMD_LATEX_1 = "f$";
-const char *CMD_LATEX_2 = "f{";
-const char *CMD_LATEX_3 = "f[";
-const char *CMD_END_HTML_ONLY = "endhtmlonly";
-const char *CMD_END_VERBATIM = "endverbatim";
-const char *CMD_END_CODE = "endcode";
-const char *CMD_END_LATEX_1 = "f$";
-const char *CMD_END_LATEX_2 = "f}";
-const char *CMD_END_LATEX_3 = "f]";
-
-const char *sectionIndicators[] = {
- "attention", "author", "authors", "brief", "bug", "cond", "date",
- "deprecated", "details", "else", "elseif", "endcond", "endif",
- "exception", "if", "ifnot", "invariant", "note", "par", "param",
- "tparam", "post", "pre", "remarks", "remark", "result", "return",
- "returns", "retval", "sa", "see", "since", "test", "throw", "throws",
- "todo", "version", "warning", "xrefitem"
-};
-
-const int sectionIndicatorsSize = sizeof(sectionIndicators) / sizeof(*sectionIndicators);
-
-/* All of the doxygen commands divided up by how they are parsed */
-const char *simpleCommands[] = {
- // the first line are escaped chars, except \~, which is a language ID command.
- "n", "$", "@", "\\", "&", "~", "<", ">", "#", "%", "\"", ".", "::",
- // Member groups, which we currently ignore.
- "{", "}",
- "endcond",
- "callgraph", "callergraph", "showinitializer", "hideinitializer", "internal",
- "nosubgrouping", "public", "publicsection", "private", "privatesection",
- "protected", "protectedsection", "tableofcontents"
-};
-
-const int simpleCommandsSize = sizeof(simpleCommands) / sizeof(*simpleCommands);
-
-const char *commandWords[] = {
- "a", "b", "c", "e", "em", "p", "def", "enum", "package", "relates",
- "namespace", "relatesalso", "anchor", "dontinclude", "include",
- "includelineno", "copydoc", "copybrief", "copydetails", "verbinclude",
- "htmlinclude", "extends", "implements", "memberof", "related", "relatedalso",
- "cite"
-};
-
-const int commandWordsSize = sizeof(commandWords) / sizeof(*commandWords);
-
-const char *commandLines[] = {
- "addindex", "fn", "name", "line", "var", "skipline", "typedef", "skip",
- "until", "property"
-};
-
-const int commandLinesSize = sizeof(commandLines) / sizeof(*commandLines);
-
-const char *commandParagraph[] = {
- "partofdescription", "result", "return", "returns", "remarks", "remark",
- "since", "test", "sa", "see", "pre", "post", "details", "invariant",
- "deprecated", "date", "note", "warning", "version", "todo", "bug",
- "attention", "brief", "author", "authors", "copyright", "short"
-};
-
-const int commandParagraphSize = sizeof(commandParagraph) / sizeof(*commandParagraph);
-
-const char *commandEndCommands[] = {
- CMD_HTML_ONLY, "latexonly", "manonly", "xmlonly", "link", "rtfonly"
-};
-
-const int commandEndCommandsSize = sizeof(commandEndCommands) / sizeof(*commandEndCommands);
-
-const char *commandWordParagraphs[] = {
- "param", "tparam", "throw", "throws", "retval", "exception", "example"
-};
-
-const int commandWordParagraphsSize = sizeof(commandWordParagraphs) / sizeof(*commandWordParagraphs);
-
-const char *commandWordLines[] = {
- "page", "subsection", "subsubsection", "section", "paragraph", "defgroup",
- "snippet", "mainpage"
-};
-
-const int commandWordLinesSize = sizeof(commandWordLines) / sizeof(*commandWordLines);
-
-const char *commandWordOWordOWords[] = {
- "category", "class", "protocol", "interface", "struct", "union"
-};
-
-const int commandWordOWordOWordsSize = sizeof(commandWordOWordOWords) / sizeof(*commandWordOWordOWords);
-
-const char *commandOWords[] = {
- "dir", "file", "cond"
-};
-
-const int commandOWordsSize = sizeof(commandOWords) / sizeof(*commandOWords);
-
-const char *commandErrorThrowings[] = {
- "annotatedclassstd::list", "classhierarchy", "define", "functionindex", "header",
- "headerfilestd::list", "inherit", "l", "postheader", "endcode", "enddot", "endmsc", "endhtmlonly",
- "endlatexonly", "endmanonly", "endlink", "endverbatim", "endxmlonly", "f]", "f}", "endif", "else",
- "endrtfonly"
-};
-
-const int commandErrorThrowingsSize = sizeof(commandErrorThrowings) / sizeof(*commandErrorThrowings);
-
-const char *commandUniques[] = {
- "xrefitem", "arg", "ingroup", "par", "headerfile", "overload", "weakgroup", "ref", "subpage", "dotfile", "image", "addtogroup", "li",
- "if", "ifnot", "elseif", "else", "mscfile", "code", CMD_VERBATIM, "f{", "f[", "f$", "dot", "msc"
-};
-
-const int commandUniquesSize = sizeof(commandUniques) / sizeof(*commandUniques);
-
-// These HTML commands are transformed when producing output in other formats.
-// Other commands are left intact, but '<' and '> are replaced with entities in HTML
-// output. So <varName> appears as &lt;varName&gt; in HTML output. The same
-// behavior must be repeated by SWIG. See Doxygen doc for the list of commands.
-// '<' is prepended to distinguish HTML tags from Doxygen commands.
-const char *commandHtml[] = {
- "<a", "<b", "<blockquote", "<body", "<br", "<center", "<caption", "<code", "<dd", "<dfn",
- "<div", "<dl", "<dt", "<em", "<form", "<hr", "<h1", "<h2", "<h3", "<i", "<input", "<img",
- "<li", "<meta", "<multicol", "<ol", "<p", "<pre", "<small", "<span", "<strong",
- "<sub", "<sup", "<table", "<td", "<th", "<tr", "<tt", "<kbd", "<ul", "<var"
-};
-
-const int commandHtmlSize = sizeof(commandHtml) / sizeof(*commandHtml);
-
-// Only entities which are translatable to plain text are used here. Others
-// are copied unchanged to output.
-const char *commandHtmlEntities[] = {
- "&copy", // (C)
- "&trade", // (TM)
- "&reg", // (R)
- "&lt", // less-than symbol
- "&gt", // greater-than symbol
- "&amp", // ampersand
- "&apos", // single quotation mark (straight)
- "&quot", // double quotation mark (straight)
- "&lsquo", // left single quotation mark
- "&rsquo", // right single quotation mark
- "&ldquo", // left double quotation mark
- "&rdquo", // right double quotation mark
- "&ndash", // n-dash (for numeric ranges, e.g. 2–8)
- "&mdash", // --
- "&nbsp", //
- "&times", // x
- "&minus", // -
- "&sdot", // .
- "&sim", // ~
- "&le", // <=
- "&ge", // >=
- "&larr", // <--
- "&rarr" // -->
-};
-
-const int commandHtmlEntitiesSize = sizeof(commandHtmlEntities) / sizeof(*commandHtmlEntities);
-
-#endif
diff --git a/contrib/tools/swig/Source/Doxygen/doxyentity.cxx b/contrib/tools/swig/Source/Doxygen/doxyentity.cxx
deleted file mode 100644
index 6fe97dd362..0000000000
--- a/contrib/tools/swig/Source/Doxygen/doxyentity.cxx
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * doxyentity.cxx
- *
- * Part of the Doxygen comment translation module of SWIG.
- * ----------------------------------------------------------------------------- */
-
-#include "doxyentity.h"
-#include <iostream>
-
-using std::cout;
-
-DoxygenEntity::DoxygenEntity(const std::string &typeEnt):typeOfEntity(typeEnt), isLeaf(true) {
-}
-
-
-/* Basic node for commands that have
- * only 1 item after them
- * example: \b word
- * OR holding a std::string
- */
-DoxygenEntity::DoxygenEntity(const std::string &typeEnt, const std::string &param1) : typeOfEntity(typeEnt), data(param1), isLeaf(true) {
-}
-
-
-/* Nonterminal node
- * contains
- */
-DoxygenEntity::DoxygenEntity(const std::string &typeEnt, const DoxygenEntityList &entList) : typeOfEntity(typeEnt), isLeaf(false), entityList(entList) {
-}
-
-
-void DoxygenEntity::printEntity(int level) const {
-
- int thisLevel = level;
-
- if (isLeaf) {
- for (int i = 0; i < thisLevel; i++) {
- cout << "\t";
- }
-
- cout << "Node Leaf Command: '" << typeOfEntity << "', ";
-
- if (!data.empty()) {
- cout << "Node Data: '" << data << "'";
- }
- cout << std::endl;
-
- } else {
-
- for (int i = 0; i < thisLevel; i++) {
- cout << "\t";
- }
-
- cout << "Node Command: '" << typeOfEntity << "'" << std::endl;
-
- thisLevel++;
-
- for (DoxygenEntityListCIt p = entityList.begin(); p != entityList.end(); p++) {
- p->printEntity(thisLevel);
- }
- }
-}
diff --git a/contrib/tools/swig/Source/Doxygen/doxyentity.h b/contrib/tools/swig/Source/Doxygen/doxyentity.h
deleted file mode 100644
index e475141a3a..0000000000
--- a/contrib/tools/swig/Source/Doxygen/doxyentity.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * doxyentity.h
- *
- * Part of the Doxygen comment translation module of SWIG.
- * ----------------------------------------------------------------------------- */
-
-#ifndef SWIG_DOXYENTITY_H
-#define SWIG_DOXYENTITY_H
-
-#include <string>
-#include <list>
-
-
-class DoxygenEntity;
-
-typedef std::list<DoxygenEntity> DoxygenEntityList;
-typedef DoxygenEntityList::iterator DoxygenEntityListIt;
-typedef DoxygenEntityList::const_iterator DoxygenEntityListCIt;
-
-
-/*
- * Structure to represent a doxygen comment entry
- */
-class DoxygenEntity {
-public:
- std::string typeOfEntity;
- std::string data;
- bool isLeaf;
- DoxygenEntityList entityList;
-
- DoxygenEntity(const std::string &typeEnt);
- DoxygenEntity(const std::string &typeEnt, const std::string &param1);
- DoxygenEntity(const std::string &typeEnt, const DoxygenEntityList &entList);
-
- void printEntity(int level) const;
-};
-
-#endif
diff --git a/contrib/tools/swig/Source/Doxygen/doxyparser.cxx b/contrib/tools/swig/Source/Doxygen/doxyparser.cxx
deleted file mode 100644
index 0c445f1a04..0000000000
--- a/contrib/tools/swig/Source/Doxygen/doxyparser.cxx
+++ /dev/null
@@ -1,1494 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * doxyparser.cxx
- * ----------------------------------------------------------------------------- */
-
-#include "doxyparser.h"
-#include "doxycommands.h"
-#include "swig.h"
-#include "swigwarn.h"
-
-#include <iostream>
-#include <algorithm>
-#include <vector>
-
-using std::string;
-using std::cout;
-using std::endl;
-
-// This constant defines the (only) characters valid inside a Doxygen "word".
-// It includes some unusual ones because of the commands such as \f[, \f{, \f],
-// \f} and \f$.
-static const char *DOXYGEN_WORD_CHARS = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789" "$[]{}";
-
-// Define static class members
-DoxygenParser::DoxyCommandsMap DoxygenParser::doxygenCommands;
-std::set<std::string> DoxygenParser::doxygenSectionIndicators;
-
-const int TOKENSPERLINE = 8; //change this to change the printing behaviour of the token list
-const std::string END_HTML_TAG_MARK("/");
-
-std::string getBaseCommand(const std::string &cmd) {
- if (cmd.substr(0,5) == "param")
- return "param";
- else if (cmd.substr(0,4) == "code")
- return "code";
- else
- return cmd;
-}
-
-// Find the first position beyond the word command. Extra logic is
-// used to avoid putting the characters "," and "." in
-// DOXYGEN_WORD_CHARS.
-static size_t getEndOfWordCommand(const std::string &line, size_t pos) {
- size_t endOfWordPos = line.find_first_not_of(DOXYGEN_WORD_CHARS, pos);
- if (line.substr(pos, 6) == "param[")
- // include ",", which can appear in param[in,out]
- endOfWordPos = line.find_first_not_of(string(DOXYGEN_WORD_CHARS)+ ",", pos);
- else if (line.substr(pos, 5) == "code{")
- // include ".", which can appear in e.g. code{.py}
- endOfWordPos = line.find_first_not_of(string(DOXYGEN_WORD_CHARS)+ ".", pos);
- return endOfWordPos;
-}
-
-
-DoxygenParser::DoxygenParser(bool noisy) : noisy(noisy) {
- fillTables();
-}
-
-DoxygenParser::~DoxygenParser() {
-}
-
-void DoxygenParser::fillTables() {
- // run it only once
- if (doxygenCommands.size())
- return;
-
- // fill in tables with data from doxycommands.h
- for (int i = 0; i < simpleCommandsSize; i++)
- doxygenCommands[simpleCommands[i]] = SIMPLECOMMAND;
-
- for (int i = 0; i < commandWordsSize; i++)
- doxygenCommands[commandWords[i]] = COMMANDWORD;
-
- for (int i = 0; i < commandLinesSize; i++)
- doxygenCommands[commandLines[i]] = COMMANDLINE;
-
- for (int i = 0; i < commandParagraphSize; i++)
- doxygenCommands[commandParagraph[i]] = COMMANDPARAGRAPH;
-
- for (int i = 0; i < commandEndCommandsSize; i++)
- doxygenCommands[commandEndCommands[i]] = COMMANDENDCOMMAND;
-
- for (int i = 0; i < commandWordParagraphsSize; i++)
- doxygenCommands[commandWordParagraphs[i]] = COMMANDWORDPARAGRAPH;
-
- for (int i = 0; i < commandWordLinesSize; i++)
- doxygenCommands[commandWordLines[i]] = COMMANDWORDLINE;
-
- for (int i = 0; i < commandWordOWordOWordsSize; i++)
- doxygenCommands[commandWordOWordOWords[i]] = COMMANDWORDOWORDWORD;
-
- for (int i = 0; i < commandOWordsSize; i++)
- doxygenCommands[commandOWords[i]] = COMMANDOWORD;
-
- for (int i = 0; i < commandErrorThrowingsSize; i++)
- doxygenCommands[commandErrorThrowings[i]] = COMMANDERRORTHROW;
-
- for (int i = 0; i < commandUniquesSize; i++)
- doxygenCommands[commandUniques[i]] = COMMANDUNIQUE;
-
- for (int i = 0; i < commandHtmlSize; i++)
- doxygenCommands[commandHtml[i]] = COMMAND_HTML;
-
- for (int i = 0; i < commandHtmlEntitiesSize; i++)
- doxygenCommands[commandHtmlEntities[i]] = COMMAND_HTML_ENTITY;
-
- // fill section indicators command set
- for (int i = 0; i < sectionIndicatorsSize; i++)
- doxygenSectionIndicators.insert(sectionIndicators[i]);
-}
-
-std::string DoxygenParser::stringToLower(const std::string &stringToConvert) {
-
- string result(stringToConvert.size(), ' ');
-
- for (size_t i = 0; i < result.size(); i++) {
- result[i] = tolower(stringToConvert[i]);
- }
-
- return result;
-}
-
-bool DoxygenParser::isSectionIndicator(const std::string &smallString) {
-
- std::set<std::string>::iterator it = doxygenSectionIndicators.find(stringToLower(smallString));
-
- return it != doxygenSectionIndicators.end();
-}
-
-void DoxygenParser::printTree(const DoxygenEntityList &rootList) {
- DoxygenEntityList::const_iterator p = rootList.begin();
- while (p != rootList.end()) {
- (*p).printEntity(0);
- p++;
- }
-}
-
-DoxygenParser::DoxyCommandEnum DoxygenParser::commandBelongs(const std::string &theCommand) {
- DoxyCommandsMapIt it = doxygenCommands.find(stringToLower(getBaseCommand(theCommand)));
-
- if (it != doxygenCommands.end()) {
- return it->second;
- }
- // Check if this command is defined as an alias.
- if (Getattr(m_node, ("feature:doxygen:alias:" + theCommand).c_str())) {
- return COMMAND_ALIAS;
- }
- // Check if this command should be ignored.
- if (String *const ignore = getIgnoreFeature(theCommand)) {
- // Check that no value is specified for this feature ("1" is the implicit
- // one given to it by SWIG itself), we may use the value in the future, but
- // for now we only use the attributes.
- if (Strcmp(ignore, "1") != 0) {
- Swig_warning(WARN_PP_UNEXPECTED_TOKENS, m_fileName.c_str(), m_fileLineNo,
- "Feature \"doxygen:ignore\" value ignored for Doxygen command \"%s\".\n", theCommand.c_str());
- }
- // Also ensure that the matching end command, if any, will be recognized.
- const string endCommand = getIgnoreFeatureEndCommand(theCommand);
- if (!endCommand.empty()) {
- Setattr(m_node, ("feature:doxygen:ignore:" + endCommand).c_str(), NewString("1"));
- }
-
- return COMMAND_IGNORE;
- }
-
- return NONE;
-}
-
-std::string DoxygenParser::trim(const std::string &text) {
- size_t start = text.find_first_not_of(" \t");
- size_t end = text.find_last_not_of(" \t");
-
- if (start == string::npos || start > end) {
- return "";
- }
- return text.substr(start, end - start + 1);
-}
-
-bool DoxygenParser::isEndOfLine() {
- if (m_tokenListIt == m_tokenList.end()) {
- return false;
- }
- Token nextToken = *m_tokenListIt;
- return nextToken.m_tokenType == END_LINE;
-}
-
-void DoxygenParser::skipWhitespaceTokens() {
- if (m_tokenListIt == m_tokenList.end()) {
- return;
- }
-
- while (m_tokenListIt != m_tokenList.end()
- && (m_tokenListIt->m_tokenType == END_LINE || trim(m_tokenListIt->m_tokenString).empty())) {
-
- m_tokenListIt++;
- }
-}
-
-std::string DoxygenParser::getNextToken() {
-
- if (m_tokenListIt == m_tokenList.end()) {
- return "";
- }
-
- if (m_tokenListIt->m_tokenType == PLAINSTRING) {
- return (m_tokenListIt++)->m_tokenString;
- }
-
- return "";
-}
-
-std::string DoxygenParser::getNextWord() {
-
- /* if (m_tokenListIt == m_tokenList.end()) {
- return "";
- }
- */
- while (m_tokenListIt != m_tokenList.end()
- && (m_tokenListIt->m_tokenType == PLAINSTRING)) {
- // handle quoted strings as words
- string token = m_tokenListIt->m_tokenString;
- if (token == "\"") {
-
- string word = m_tokenListIt->m_tokenString;
- m_tokenListIt++;
- while (true) {
- string nextWord = getNextToken();
- if (nextWord.empty()) { // maybe report unterminated string error
- return word;
- }
- word += nextWord;
- if (nextWord == "\"") {
- return word;
- }
- }
- }
-
- string tokenStr = trim(m_tokenListIt->m_tokenString);
- m_tokenListIt++;
- if (!tokenStr.empty()) {
- return tokenStr;
- }
- }
-
- return "";
-}
-
-DoxygenParser::TokenListCIt DoxygenParser::getOneLine(const TokenList &tokList) {
-
- TokenListCIt endOfLineIt = m_tokenListIt;
-
- while (endOfLineIt != tokList.end()) {
- if (endOfLineIt->m_tokenType == END_LINE) {
- return endOfLineIt;
- }
- endOfLineIt++;
- }
-
- return tokList.end();
-}
-
-std::string DoxygenParser::getStringTilCommand(const TokenList &tokList) {
-
- if (m_tokenListIt == tokList.end()) {
- return "";
- }
-
- string description;
-
- while (m_tokenListIt->m_tokenType == PLAINSTRING) {
- const Token &currentToken = *m_tokenListIt++;
- if (currentToken.m_tokenType == PLAINSTRING) {
- description = description + currentToken.m_tokenString; // + " ";
- }
- }
- return description;
-}
-
-std::string DoxygenParser::getStringTilEndCommand(const std::string &theCommand, const TokenList &tokList) {
-
- if (m_tokenListIt == tokList.end()) {
- return "";
- }
-
- string description;
- while (m_tokenListIt != tokList.end()) {
-
- if (m_tokenListIt->m_tokenType == PLAINSTRING) {
- description += m_tokenListIt->m_tokenString;
- } else if (m_tokenListIt->m_tokenType == END_LINE) {
- description += "\n";
- } else if (m_tokenListIt->m_tokenString == theCommand) {
- m_tokenListIt++;
- return description;
- }
-
- m_tokenListIt++;
- }
-
- printListError(WARN_DOXYGEN_COMMAND_EXPECTED, "Expected Doxygen command: " + theCommand + ".");
-
- return description;
-}
-
-DoxygenParser::TokenListCIt DoxygenParser::getEndOfParagraph(const TokenList &tokList) {
-
- TokenListCIt endOfParagraph = m_tokenListIt;
-
- while (endOfParagraph != tokList.end()) {
- // If \code or \verbatim is encountered within a paragraph, then
- // go all the way to the end of that command, since the content
- // could contain empty lines that would appear to be paragraph
- // ends:
- if (endOfParagraph->m_tokenType == COMMAND &&
- (endOfParagraph->m_tokenString == "code" ||
- endOfParagraph->m_tokenString == "verbatim")) {
- const string theCommand = endOfParagraph->m_tokenString;
- endOfParagraph = getEndCommand("end" + theCommand, tokList);
- endOfParagraph++; // Move after the end command
- return endOfParagraph;
- }
- if (endOfParagraph->m_tokenType == END_LINE) {
- endOfParagraph++;
- if (endOfParagraph != tokList.end()
- && endOfParagraph->m_tokenType == END_LINE) {
- endOfParagraph++;
- //cout << "ENCOUNTERED END OF PARA" << endl;
- return endOfParagraph;
- }
-
- } else if (endOfParagraph->m_tokenType == COMMAND) {
-
- if (isSectionIndicator(getBaseCommand(endOfParagraph->m_tokenString))) {
- return endOfParagraph;
- } else {
- endOfParagraph++;
- }
-
- } else if (endOfParagraph->m_tokenType == PLAINSTRING) {
- endOfParagraph++;
- } else {
- return tokList.end();
- }
- }
-
- return tokList.end();
-}
-
-DoxygenParser::TokenListCIt DoxygenParser::getEndOfSection(const std::string &theCommand, const TokenList &tokList) {
-
- TokenListCIt endOfParagraph = m_tokenListIt;
-
- while (endOfParagraph != tokList.end()) {
- if (endOfParagraph->m_tokenType == COMMAND) {
- if (theCommand == endOfParagraph->m_tokenString)
- return endOfParagraph;
- else
- endOfParagraph++;
- } else if (endOfParagraph->m_tokenType == PLAINSTRING) {
- endOfParagraph++;
- } else if (endOfParagraph->m_tokenType == END_LINE) {
- endOfParagraph++;
- if (endOfParagraph->m_tokenType == END_LINE) {
- endOfParagraph++;
- return endOfParagraph;
- }
- }
- }
- return tokList.end();
-}
-
-DoxygenParser::TokenListCIt DoxygenParser::getEndCommand(const std::string &theCommand, const TokenList &tokList) {
-
- TokenListCIt endOfCommand = m_tokenListIt;
-
- while (endOfCommand != tokList.end()) {
- endOfCommand++;
- if ((*endOfCommand).m_tokenType == COMMAND) {
- if (theCommand == (*endOfCommand).m_tokenString) {
- return endOfCommand;
- }
- }
- }
- //End command not found
- return tokList.end();
-}
-
-void DoxygenParser::skipEndOfLine() {
- if (m_tokenListIt != m_tokenList.end()
- && m_tokenListIt->m_tokenType == END_LINE) {
- m_tokenListIt++;
- }
-}
-
-void DoxygenParser::addSimpleCommand(const std::string &theCommand, DoxygenEntityList &doxyList) {
- if (noisy)
- cout << "Parsing " << theCommand << endl;
-
- doxyList.push_back(DoxygenEntity(theCommand));
-}
-
-void DoxygenParser::addCommandWord(const std::string &theCommand, const TokenList &, DoxygenEntityList &doxyList) {
- if (noisy)
- cout << "Parsing " << theCommand << endl;
-
- if (isEndOfLine()) {
- // handles cases when command is at the end of line (for example "\c\nreally"
- skipWhitespaceTokens();
- doxyList.push_back(DoxygenEntity("plainstd::endl"));
- }
- std::string name = getNextWord();
- if (!name.empty()) {
- DoxygenEntityList aNewList;
- aNewList.push_back(DoxygenEntity("plainstd::string", name));
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
- } else {
- printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No word followed the command. Command ignored.");
- }
-}
-
-void DoxygenParser::addCommandLine(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList) {
- if (noisy)
- cout << "Parsing " << theCommand << endl;
- TokenListCIt endOfLine = getOneLine(tokList);
- DoxygenEntityList aNewList = parse(endOfLine, tokList);
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
- skipEndOfLine();
-}
-
-void DoxygenParser::addCommandParagraph(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList) {
- if (noisy)
- cout << "Parsing " << theCommand << endl;
-
- TokenListCIt endOfParagraph = getEndOfParagraph(tokList);
- DoxygenEntityList aNewList;
- aNewList = parse(endOfParagraph, tokList);
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
-}
-
-void DoxygenParser::addCommandEndCommand(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList) {
- if (noisy)
- cout << "Parsing " << theCommand << endl;
- TokenListCIt endCommand = getEndCommand("end" + theCommand, tokList);
- if (endCommand == tokList.end()) {
- printListError(WARN_DOXYGEN_COMMAND_EXPECTED, "Expected Doxygen command: end" + theCommand + ".");
- return;
- }
- DoxygenEntityList aNewList;
- aNewList = parse(endCommand, tokList);
- m_tokenListIt++;
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
-}
-
-void DoxygenParser::addCommandWordParagraph(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList) {
- if (noisy)
- cout << "Parsing " << theCommand << endl;
-
- std::string name = getNextWord();
-
- if (name.empty()) {
- printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No word followed the command. Command ignored.");
- return;
- }
- TokenListCIt endOfParagraph = getEndOfParagraph(tokList);
- DoxygenEntityList aNewList;
- aNewList = parse(endOfParagraph, tokList);
- aNewList.push_front(DoxygenEntity("plainstd::string", name));
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
-}
-
-void DoxygenParser::addCommandWordLine(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList) {
- if (noisy)
- cout << "Parsing " << theCommand << endl;
- std::string name = getNextWord();
- if (name.empty()) {
- printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No word followed the command. Command ignored.");
- return;
- }
-
- TokenListCIt endOfLine = getOneLine(tokList);
- DoxygenEntityList aNewList;
- aNewList = parse(endOfLine, tokList);
- aNewList.push_front(DoxygenEntity("plainstd::string", name));
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
- //else cout << "No line followed " << theCommand << " command. Not added" << endl;
-}
-
-void DoxygenParser::addCommandWordOWordOWord(const std::string &theCommand, const TokenList &, DoxygenEntityList &doxyList) {
- if (noisy)
- cout << "Parsing " << theCommand << endl;
-
- std::string name = getNextWord();
- if (name.empty()) {
- printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No word followed the command. Command ignored.");
- return;
- }
- std::string headerfile = getNextWord();
- std::string headername = getNextWord();
- DoxygenEntityList aNewList;
- aNewList.push_back(DoxygenEntity("plainstd::string", name));
- if (!headerfile.empty())
- aNewList.push_back(DoxygenEntity("plainstd::string", headerfile));
- if (!headername.empty())
- aNewList.push_back(DoxygenEntity("plainstd::string", headername));
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
-}
-
-void DoxygenParser::addCommandOWord(const std::string &theCommand, const TokenList &, DoxygenEntityList &doxyList) {
- if (noisy)
- cout << "Parsing " << theCommand << endl;
-
- std::string name = getNextWord();
- DoxygenEntityList aNewList;
- aNewList.push_back(DoxygenEntity("plainstd::string", name));
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
-}
-
-void DoxygenParser::addCommandErrorThrow(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &) {
-
- printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": Unexpectedly encountered this command.");
- m_tokenListIt = getOneLine(tokList);
-}
-
-void DoxygenParser::addCommandHtml(const std::string &theCommand, const TokenList &, DoxygenEntityList &doxyList) {
- if (noisy)
- cout << "Parsing " << theCommand << endl;
-
- std::string htmlTagArgs = getNextToken();
- doxyList.push_back(DoxygenEntity(theCommand, htmlTagArgs));
-}
-
-void DoxygenParser::addCommandHtmlEntity(const std::string &theCommand, const TokenList &, DoxygenEntityList &doxyList) {
- if (noisy)
- cout << "Parsing " << theCommand << endl;
-
- DoxygenEntityList aNewList;
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
-}
-
-void DoxygenParser::addCommandUnique(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList) {
-
- static std::map<std::string, std::string> endCommands;
- DoxygenEntityList aNewList;
- if (theCommand == "arg" || theCommand == "li") {
- TokenListCIt endOfSection = getEndOfSection(theCommand, tokList);
- DoxygenEntityList aNewList;
- aNewList = parse(endOfSection, tokList);
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
- }
- // \xrefitem <key> "(heading)" "(std::list title)" {text}
- else if (theCommand == "xrefitem") {
- if (noisy)
- cout << "Parsing " << theCommand << endl;
- std::string key = getNextWord();
- if (key.empty()) {
- printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No key followed the command. Command ignored.");
- return;
- }
- std::string heading = getNextWord();
- if (key.empty()) {
- printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No heading followed the command. Command ignored.");
- return;
- }
- std::string title = getNextWord();
- if (title.empty()) {
- printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No title followed the command. Command ignored.");
- return;
- }
- TokenListCIt endOfParagraph = getEndOfParagraph(tokList);
- aNewList = parse(endOfParagraph, tokList);
- aNewList.push_front(DoxygenEntity("plainstd::string", title));
- aNewList.push_front(DoxygenEntity("plainstd::string", heading));
- aNewList.push_front(DoxygenEntity("plainstd::string", key));
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
- }
- // \ingroup (<groupname> [<groupname> <groupname>])
- else if (theCommand == "ingroup") {
- std::string name = getNextWord();
- aNewList.push_back(DoxygenEntity("plainstd::string", name));
- name = getNextWord();
- if (!name.empty())
- aNewList.push_back(DoxygenEntity("plainstd::string", name));
- name = getNextWord();
- if (!name.empty())
- aNewList.push_back(DoxygenEntity("plainstd::string", name));
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
- }
- // \par [(paragraph title)] { paragraph }
- else if (theCommand == "par") {
- TokenListCIt endOfLine = getOneLine(tokList);
- aNewList = parse(endOfLine, tokList);
- DoxygenEntityList aNewList2;
- TokenListCIt endOfParagraph = getEndOfParagraph(tokList);
- aNewList2 = parse(endOfParagraph, tokList);
- aNewList.splice(aNewList.end(), aNewList2);
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
- }
- // \headerfile <header-file> [<header-name>]
- else if (theCommand == "headerfile") {
- DoxygenEntityList aNewList;
- std::string name = getNextWord();
- aNewList.push_back(DoxygenEntity("plainstd::string", name));
- name = getNextWord();
- if (!name.empty())
- aNewList.push_back(DoxygenEntity("plainstd::string", name));
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
- }
- // \overload [(function declaration)]
- else if (theCommand == "overload") {
- TokenListCIt endOfLine = getOneLine(tokList);
- if (endOfLine != m_tokenListIt) {
- DoxygenEntityList aNewList;
- aNewList = parse(endOfLine, tokList);
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
- } else
- doxyList.push_back(DoxygenEntity(theCommand));
- }
- // \weakgroup <name> [(title)]
- else if (theCommand == "weakgroup") {
- if (noisy)
- cout << "Parsing " << theCommand << endl;
- std::string name = getNextWord();
- if (name.empty()) {
- printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No word followed the command. Command ignored.");
- return;
- }
- DoxygenEntityList aNewList;
- TokenListCIt endOfLine = getOneLine(tokList);
- if (endOfLine != m_tokenListIt) {
- aNewList = parse(endOfLine, tokList);
- }
- aNewList.push_front(DoxygenEntity("plainstd::string", name));
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
- }
- // \ref <name> ["(text)"]
- else if (theCommand == "ref") {
- if (noisy)
- cout << "Parsing " << theCommand << endl;
- std::string name = getNextWord();
- if (name.empty()) {
- printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No key followed the command. Command ignored.");
- return;
- }
- DoxygenEntityList aNewList;
- aNewList.push_front(DoxygenEntity("plainstd::string", name));
- // TokenListCIt endOfLine = getOneLine(tokList);
- // if (endOfLine != m_tokenListIt) {
- // aNewList = parse(endOfLine, tokList);
- //}
- TokenListCIt tmpIt = m_tokenListIt;
- std::string refTitle = getNextWord();
- // If title is following the ref tag, it must be quoted. Otherwise
- // doxy puts link on ref id.
- if (refTitle.size() > 1 && refTitle[0] == '"') {
- // remove quotes
- refTitle = refTitle.substr(1, refTitle.size() - 2);
- aNewList.push_back(DoxygenEntity("plainstd::string", refTitle));
- } else {
- // no quoted string is following, so we have to restore iterator
- m_tokenListIt = tmpIt;
- }
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
- }
- // \subpage <name> ["(text)"]
- else if (theCommand == "subpage") {
- if (noisy)
- cout << "Parsing " << theCommand << endl;
- std::string name = getNextWord();
- if (name.empty()) {
- printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No name followed the command. Command ignored.");
- return;
- }
- std::string text = getNextWord();
- aNewList.push_back(DoxygenEntity("plainstd::string", name));
- if (!text.empty())
- aNewList.push_back(DoxygenEntity("plainstd::string", text));
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
- }
- // \code ... \endcode
- // \verbatim ... \endverbatim
- // \dot dotcode \enddot
- // \msc msccode \endmsc
- // \f[ ... \f]
- // \f{ ... \f}
- // \f{env}{ ... \f}
- // \f$ ... \f$
- else if (getBaseCommand(theCommand) == "code" || theCommand == "verbatim"
- || theCommand == "dot" || theCommand == "msc" || theCommand == "f[" || theCommand == "f{" || theCommand == "f$") {
- if (!endCommands.size()) {
- // fill in static table of end commands
- endCommands["f["] = "f]";
- endCommands["f{"] = "f}";
- endCommands["f$"] = "f$";
- }
- if (noisy)
- cout << "Parsing " << theCommand << endl;
-
- std::string endCommand;
- std::map<std::string, std::string>::iterator it;
- it = endCommands.find(theCommand);
- if (it != endCommands.end())
- endCommand = it->second;
- else
- endCommand = "end" + getBaseCommand(theCommand);
-
- std::string content = getStringTilEndCommand(endCommand, tokList);
- aNewList.push_back(DoxygenEntity("plainstd::string", content));
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
- }
- // \dotfile <file> ["caption"]
- // \mscfile <file> ["caption"]
- else if (theCommand == "dotfile" || theCommand == "mscfile") {
- if (noisy)
- cout << "Parsing " << theCommand << endl;
- std::string file = getNextWord();
- if (file.empty()) {
- printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No file followed the command. Command ignored.");
- return;
- }
- std::string caption = getNextWord();
- aNewList.push_back(DoxygenEntity("plainstd::string", file));
- if (!caption.empty())
- aNewList.push_back(DoxygenEntity("plainstd::string", caption));
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
- }
- // \image <format> <file> ["caption"] [<sizeindication>=<size>]
- else if (theCommand == "image") {
- if (noisy)
- cout << "Parsing " << theCommand << endl;
- std::string format = getNextWord();
- if (format.empty()) {
- printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No format followed the command. Command ignored.");
- return;
- }
- std::string file = getNextWord();
- if (file.empty()) {
- printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No name followed the command. Command ignored.");
- return;
- }
- std::string caption = getNextWord();
- std::string size = getNextWord();
-
- DoxygenEntityList aNewList;
- aNewList.push_back(DoxygenEntity("plainstd::string", format));
- aNewList.push_back(DoxygenEntity("plainstd::string", file));
- if (!caption.empty())
- aNewList.push_back(DoxygenEntity("plainstd::string", caption));
- if (!size.empty())
- aNewList.push_back(DoxygenEntity("plainstd::string", size));
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
- }
- // \addtogroup <name> [(title)]
- else if (theCommand == "addtogroup") {
- if (noisy)
- cout << "Parsing " << theCommand << endl;
- std::string name = getNextWord();
- if (name.empty()) {
- printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": There should be at least one word following the command. Command ignored.");
- return;
- }
- DoxygenEntityList aNewList;
- TokenListCIt endOfLine = getOneLine(tokList);
- if (endOfLine != m_tokenListIt) {
- aNewList = parse(endOfLine, tokList);
- }
- aNewList.push_front(DoxygenEntity("plainstd::string", name));
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
- skipEndOfLine();
- }
- // \if <cond> [\else ...] [\elseif <cond> ...] \endif
- else if (theCommand == "if" || theCommand == "ifnot" || theCommand == "else" || theCommand == "elseif") {
- if (noisy)
- cout << "Parsing " << theCommand << endl;
-
- std::string cond;
- bool skipEndif = false; // if true then we skip endif after parsing block of code
- bool needsCond = (theCommand == "if" || theCommand == "ifnot" || theCommand == "elseif");
- if (needsCond) {
- cond = getNextWord();
- if (cond.empty()) {
- printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No word followed the command. Command ignored.");
- return;
- }
- }
-
- int nestedCounter = 1;
- TokenListCIt endCommand = tokList.end();
-
- // go through the commands and find closing endif or else or elseif
- for (TokenListCIt it = m_tokenListIt; it != tokList.end(); it++) {
- if (it->m_tokenType == COMMAND) {
- if (it->m_tokenString == "if" || it->m_tokenString == "ifnot")
- nestedCounter++;
- else if (it->m_tokenString == "endif")
- nestedCounter--;
- if (nestedCounter == 1 && (it->m_tokenString == "else" || it->m_tokenString == "elseif")) { // else found
- endCommand = it;
- break;
- }
- if (nestedCounter == 0) { // endif found
- endCommand = it;
- skipEndif = true;
- break;
- }
- }
- }
-
- if (endCommand == tokList.end()) {
- printListError(WARN_DOXYGEN_COMMAND_EXPECTED, "Expected Doxygen command: endif.");
- return;
- }
-
- DoxygenEntityList aNewList;
- aNewList = parse(endCommand, tokList);
- if (skipEndif)
- m_tokenListIt++;
- if (needsCond)
- aNewList.push_front(DoxygenEntity("plainstd::string", cond));
- doxyList.push_back(DoxygenEntity(theCommand, aNewList));
- }
-}
-
-void DoxygenParser::aliasCommand(const std::string &theCommand, const TokenList &/* tokList */ , DoxygenEntityList &doxyList) {
- String *const alias = Getattr(m_node, ("feature:doxygen:alias:" + theCommand).c_str());
- if (!alias)
- return;
-
- doxyList.push_back(DoxygenEntity("plainstd::string", Char(alias)));
-}
-
-String *DoxygenParser::getIgnoreFeature(const std::string &theCommand, const char *argument) const {
- string feature_name = "feature:doxygen:ignore:" + theCommand;
- if (argument) {
- feature_name += ':';
- feature_name += argument;
- }
-
- return Getattr(m_node, feature_name.c_str());
-}
-
-string DoxygenParser::getIgnoreFeatureEndCommand(const std::string &theCommand) const {
- // We may be dealing either with a simple command or with the starting command
- // of a block, as indicated by the value of "range" starting with "end".
- string endCommand;
- if (String *const range = getIgnoreFeature(theCommand, "range")) {
- const char *const p = Char(range);
- if (strncmp(p, "end", 3) == 0) {
- if (p[3] == ':') {
- // Normally the end command name follows after the colon.
- endCommand = p + 4;
- } else if (p[3] == '\0') {
- // But it may be omitted in which case the default Doxygen convention of
- // using "something"/"endsomething" is used.
- endCommand = "end" + theCommand;
- }
- }
- }
-
- return endCommand;
-}
-
-void DoxygenParser::ignoreCommand(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList) {
- const string endCommand = getIgnoreFeatureEndCommand(theCommand);
- if (!endCommand.empty()) {
- TokenListCIt itEnd = getEndCommand(endCommand, tokList);
- if (itEnd == tokList.end()) {
- printListError(WARN_DOXYGEN_COMMAND_EXPECTED, "Expected Doxygen command: " + endCommand + ".");
- return;
- }
- // If we ignore the command, also ignore any whitespace preceding it as we
- // want to avoid having lines consisting of whitespace only or trailing
- // whitespace in general (at least Python, with its pep8 tool, really
- // doesn't like it).
- if (!doxyList.empty()) {
- DoxygenEntityList::iterator i = doxyList.end();
- --i;
- if (i->typeOfEntity == "plainstd::string" && i->data.find_first_not_of(" \t") == std::string::npos) {
- doxyList.erase(i);
- }
- }
- // Determine what to do with the part of the comment between the start and
- // end commands: by default, we simply throw it away, but "contents"
- // attribute may be used to change this.
- if (String *const contents = getIgnoreFeature(theCommand, "contents")) {
- // Currently only "parse" is supported but we may need to add "copy" to
- // handle custom tags which contain text that is supposed to be copied
- // verbatim in the future.
- if (Strcmp(contents, "parse") == 0) {
- DoxygenEntityList aNewList = parse(itEnd, tokList);
- doxyList.splice(doxyList.end(), aNewList);
- } else {
- Swig_error(m_fileName.c_str(), m_fileLineNo, "Invalid \"doxygen:ignore\" feature \"contents\" attribute \"%s\".\n", Char(contents));
- return;
- }
- }
-
- m_tokenListIt = itEnd;
- m_tokenListIt++;
- } else if (String *const range = getIgnoreFeature(theCommand, "range")) {
- // Currently we only support "line" but, in principle, we should also
- // support "word" and "paragraph" for consistency with the built-in Doxygen
- // commands which can have either of these three ranges (which are indicated
- // using <word-arg>, (line-arg) and {para-arg} respectively in Doxygen
- // documentation).
- if (Strcmp(range, "line") == 0) {
- // Consume everything until the end of line.
- m_tokenListIt = getOneLine(tokList);
- skipEndOfLine();
- } else {
- Swig_error(m_fileName.c_str(), m_fileLineNo, "Invalid \"doxygen:ignore\" feature \"range\" attribute \"%s\".\n", Char(range));
- return;
- }
- }
-}
-
-void DoxygenParser::addCommand(const std::string &commandString, const TokenList &tokList, DoxygenEntityList &doxyList) {
-
- string theCommand = stringToLower(commandString);
-
- if (theCommand == "plainstd::string") {
- string nextPhrase = getStringTilCommand(tokList);
- if (noisy)
- cout << "Parsing plain std::string :" << nextPhrase << endl;
- doxyList.push_back(DoxygenEntity("plainstd::string", nextPhrase));
- return;
- }
-
- switch (commandBelongs(commandString)) {
- case SIMPLECOMMAND:
- addSimpleCommand(theCommand, doxyList);
- break;
- case COMMANDWORD:
- addCommandWord(theCommand, tokList, doxyList);
- break;
- case COMMANDLINE:
- addCommandLine(theCommand, tokList, doxyList);
- break;
- case COMMANDPARAGRAPH:
- addCommandParagraph(theCommand, tokList, doxyList);
- break;
- case COMMANDENDCOMMAND:
- addCommandEndCommand(theCommand, tokList, doxyList);
- break;
- case COMMANDWORDPARAGRAPH:
- addCommandWordParagraph(theCommand, tokList, doxyList);
- break;
- case COMMANDWORDLINE:
- addCommandWordLine(theCommand, tokList, doxyList);
- break;
- case COMMANDWORDOWORDWORD:
- addCommandWordOWordOWord(theCommand, tokList, doxyList);
- break;
- case COMMANDOWORD:
- addCommandOWord(theCommand, tokList, doxyList);
- break;
- case COMMANDERRORTHROW:
- addCommandErrorThrow(theCommand, tokList, doxyList);
- break;
- case COMMANDUNIQUE:
- addCommandUnique(theCommand, tokList, doxyList);
- break;
- case COMMAND_HTML:
- addCommandHtml(theCommand, tokList, doxyList);
- break;
- case COMMAND_HTML_ENTITY:
- addCommandHtmlEntity(theCommand, tokList, doxyList);
- break;
- case COMMAND_ALIAS:
- aliasCommand(commandString, tokList, doxyList);
- break;
- case COMMAND_IGNORE:
- ignoreCommand(commandString, tokList, doxyList);
- break;
- case NONE:
- case END_LINE:
- case PARAGRAPH_END:
- case PLAINSTRING:
- case COMMAND:
- // TODO: Ensure that these values either are correctly ignored here or can't happen.
- break;
- }
-}
-
-/**
- * This method converts TokenList to DoxygenEntryList.
- */
-DoxygenEntityList DoxygenParser::parse(TokenListCIt endParsingIndex, const TokenList &tokList, bool root) {
- // if we are root, than any strings should be added as 'partofdescription', else as 'plainstd::string'
- std::string currPlainstringCommandType = root ? "partofdescription" : "plainstd::string";
- DoxygenEntityList aNewList;
-
- // Less than check (instead of not equal) is a safeguard in case the
- // iterator is incremented past the end
- while (m_tokenListIt < endParsingIndex) {
-
- Token currToken = *m_tokenListIt;
-
- if (noisy)
- cout << "Parsing for phrase starting in:" << currToken.toString() << endl;
-
- if (currToken.m_tokenType == END_LINE) {
- aNewList.push_back(DoxygenEntity("plainstd::endl"));
- m_tokenListIt++;
- } else if (currToken.m_tokenType == COMMAND) {
- m_tokenListIt++;
- addCommand(currToken.m_tokenString, tokList, aNewList);
- } else if (currToken.m_tokenType == PLAINSTRING) {
- addCommand(currPlainstringCommandType, tokList, aNewList);
- }
-
- // If addCommand above misbehaves, it can move the iterator past endParsingIndex
- if (m_tokenListIt > endParsingIndex)
- printListError(WARN_DOXYGEN_UNEXPECTED_ITERATOR_VALUE, "Unexpected iterator value in DoxygenParser::parse");
-
- if (endParsingIndex != tokList.end() && m_tokenListIt == tokList.end()) {
- // this could happen if we can't reach the original endParsingIndex
- printListError(WARN_DOXYGEN_UNEXPECTED_END_OF_COMMENT, "Unexpected end of Doxygen comment encountered.");
- break;
- }
- }
- return aNewList;
-}
-
-DoxygenEntityList DoxygenParser::createTree(Node *node, String *documentation) {
- m_node = node;
-
- tokenizeDoxygenComment(Char(documentation), Char(Getfile(documentation)), Getline(documentation));
-
- if (noisy) {
- cout << "---TOKEN LIST---" << endl;
- printList();
- }
-
- DoxygenEntityList rootList = parse(m_tokenList.end(), m_tokenList, true);
-
- if (noisy) {
- cout << "PARSED LIST" << endl;
- printTree(rootList);
- }
- return rootList;
-}
-
-/*
- * Splits 'text' on 'separator' chars. Separator chars are not part of the
- * strings.
- */
-DoxygenParser::StringVector DoxygenParser::split(const std::string &text, char separator) {
- StringVector lines;
- size_t prevPos = 0, pos = 0;
-
- while (pos < string::npos) {
- pos = text.find(separator, prevPos);
- lines.push_back(text.substr(prevPos, pos - prevPos));
- prevPos = pos + 1;
- }
-
- return lines;
-}
-
-/*
- * Returns true, if 'c' is one of doxygen comment block start
- * characters: *, /, or !
- */
-bool DoxygenParser::isStartOfDoxyCommentChar(char c) {
- return (strchr("*/!", c) != NULL);
-}
-
-/*
- * Adds token with Doxygen command to token list, but only if command is one of
- * Doxygen commands. In that case true is returned. If the command is not
- * recognized as a doxygen command, it is ignored and false is returned.
- */
-bool DoxygenParser::addDoxyCommand(DoxygenParser::TokenList &tokList, const std::string &cmd) {
- if (commandBelongs(cmd) != NONE) {
- tokList.push_back(Token(COMMAND, cmd));
- return true;
- } else {
- if (cmd.empty()) {
- // This actually indicates a bug in the code in this file, as this
- // function shouldn't be called at all in this case.
- printListError(WARN_DOXYGEN_UNKNOWN_COMMAND, "Unexpected empty Doxygen command.");
- return false;
- }
-
- // This function is called for the special Doxygen commands, but also for
- // HTML commands (or anything that looks like them, actually) and entities.
- // We don't recognize all of those, so just ignore them and pass them
- // through, but warn about unknown Doxygen commands as ignoring them will
- // often result in wrong output being generated.
- const char ch = *cmd.begin();
- if (ch != '<' && ch != '&') {
- // Before calling printListError() we must ensure that m_tokenListIt used
- // by it is valid.
- const TokenListCIt itSave = m_tokenListIt;
- m_tokenListIt = m_tokenList.end();
-
- printListError(WARN_DOXYGEN_UNKNOWN_COMMAND, "Unknown Doxygen command: " + cmd + ".");
-
- m_tokenListIt = itSave;
- }
- }
-
- return false;
-}
-
-/*
- * This method copies comment text to output as it is - no processing is
- * done, Doxygen commands are ignored. It is used for commands \verbatim,
- * \htmlonly, \f$, \f[, and \f{.
- */
-size_t DoxygenParser::processVerbatimText(size_t pos, const std::string &line) {
- if (line[pos] == '\\' || line[pos] == '@') { // check for end commands
-
- pos++;
- size_t endOfWordPos = line.find_first_not_of(DOXYGEN_WORD_CHARS, pos);
- string cmd = line.substr(pos, endOfWordPos - pos);
-
- if (cmd == CMD_END_HTML_ONLY || cmd == CMD_END_VERBATIM || cmd == CMD_END_LATEX_1 || cmd == CMD_END_LATEX_2 || cmd == CMD_END_LATEX_3 || cmd == CMD_END_CODE) {
-
- m_isVerbatimText = false;
- addDoxyCommand(m_tokenList, cmd);
-
- } else {
-
- m_tokenList.push_back(Token(PLAINSTRING,
- // include '\' or '@'
- line.substr(pos - 1, endOfWordPos - pos + 1)));
- }
-
- pos = endOfWordPos;
-
- } else {
-
- // whitespaces are stored as plain strings
- size_t startOfPossibleEndCmd = line.find_first_of("\\@", pos);
- m_tokenList.push_back(Token(PLAINSTRING, line.substr(pos, startOfPossibleEndCmd - pos)));
- pos = startOfPossibleEndCmd;
- }
-
- return pos;
-}
-
-/*
- * Processes doxy commands for escaped characters: \$ \@ \\ \& \~ \< \> \# \% \" \. \::
- * Handling this separately supports documentation text like \@someText.
- */
-bool DoxygenParser::processEscapedChars(size_t &pos, const std::string &line) {
- if ((pos + 1) < line.size()) {
-
- // \ and @ with trailing whitespace or quoted get to output as plain string
- string whitespaces = " '\t\n";
- if (whitespaces.find(line[pos + 1]) != string::npos) {
- m_tokenList.push_back(Token(PLAINSTRING, line.substr(pos, 1)));
- pos++;
- return true;
- }
- // these chars can be escaped for doxygen
- string escapedChars = "$@\\&~<>#%\".";
- if (escapedChars.find(line[pos + 1]) != string::npos) {
-
- addDoxyCommand(m_tokenList, line.substr(pos + 1, 1));
- pos += 2;
- return true;
-
- } else if ((pos + 2) < line.size() && line[pos + 1] == ':' && line[pos + 2] == ':') {
-
- // add command \:: - handling this separately supports documentation
- // text like \::someText
- addDoxyCommand(m_tokenList, line.substr(pos + 1, 2));
- pos += 3;
- return true;
- }
- }
- return false;
-}
-
-/*
- * Processes word doxygen commands, like \arg, \c, \b, \return, ...
- */
-void DoxygenParser::processWordCommands(size_t &pos, const std::string &line) {
- pos++;
- size_t endOfWordPos = getEndOfWordCommand(line, pos);
-
- string cmd = line.substr(pos, endOfWordPos - pos);
- if (cmd.empty()) {
- // This was a bare backslash, just ignore it.
- return;
- }
-
- addDoxyCommand(m_tokenList, cmd);
-
- // A flag for whether we want to skip leading spaces after the command
- bool skipLeadingSpace = true;
-
- if (cmd == CMD_HTML_ONLY || cmd == CMD_VERBATIM || cmd == CMD_LATEX_1 || cmd == CMD_LATEX_2 || cmd == CMD_LATEX_3 || getBaseCommand(cmd) == CMD_CODE) {
-
- m_isVerbatimText = true;
-
- // Skipping leading space is necessary with inline \code command,
- // and it won't hurt anything for block \code (TODO: are the other
- // commands also compatible with skip leading space? If so, just
- // do it every time.)
- if (getBaseCommand(cmd) == CMD_CODE) skipLeadingSpace = true;
- else skipLeadingSpace = false;
- } else if (cmd.substr(0,3) == "end") {
- // If processing an "end" command such as "endlink", don't skip
- // the space before the next string
- skipLeadingSpace = false;
- }
-
- if (skipLeadingSpace) {
- // skip any possible spaces after command, because some commands have parameters,
- // and spaces between command and parameter must be ignored.
- if (endOfWordPos != string::npos) {
- endOfWordPos = line.find_first_not_of(" \t", endOfWordPos);
- }
- }
-
- pos = endOfWordPos;
-}
-
-void DoxygenParser::processHtmlTags(size_t &pos, const std::string &line) {
- bool isEndHtmlTag = false;
- pos++;
- if (line.size() > pos && line[pos] == '/') {
- isEndHtmlTag = true;
- pos++;
- }
-
- size_t endHtmlPos = line.find_first_of("\t >", pos);
-
- string cmd = line.substr(pos, endHtmlPos - pos);
- pos = endHtmlPos;
-
- // prepend '<' to distinguish HTML tags from doxygen commands
- if (!cmd.empty() && addDoxyCommand(m_tokenList, '<' + cmd)) {
- // it is a valid HTML command
- if (pos == string::npos) {
- pos = line.size();
- }
- if (line[pos] != '>') {
- // it should be HTML tag with args,
- // for example <A ...>, <IMG ...>, ...
- if (isEndHtmlTag) {
- m_tokenListIt = m_tokenList.end();
- printListError(WARN_DOXYGEN_HTML_ERROR, "Doxygen HTML error for tag " + cmd + ": Illegal end HTML tag without greater-than ('>') found.");
- }
-
- endHtmlPos = line.find(">", pos);
- if (endHtmlPos == string::npos) {
- m_tokenListIt = m_tokenList.end();
- printListError(WARN_DOXYGEN_HTML_ERROR, "Doxygen HTML error for tag " + cmd + ": HTML tag without greater-than ('>') found.");
- }
- // add args of HTML command, like link URL, image URL, ...
- m_tokenList.push_back(Token(PLAINSTRING, line.substr(pos, endHtmlPos - pos)));
- pos = endHtmlPos;
- } else {
- if (isEndHtmlTag) {
- m_tokenList.push_back(Token(PLAINSTRING, END_HTML_TAG_MARK));
- } else {
- // it is a simple tag, so push empty string
- m_tokenList.push_back(Token(PLAINSTRING, ""));
- }
- }
-
- if (pos < line.size()) {
- pos++; // skip '>'
- }
- } else {
- // the command is not HTML supported by Doxygen, < and > will be
- // replaced by HTML entities &lt; and &gt; respectively,
- addDoxyCommand(m_tokenList, "&lt");
- m_tokenList.push_back(Token(PLAINSTRING, cmd));
- }
-}
-
-void DoxygenParser::processHtmlEntities(size_t &pos, const std::string &line) {
- size_t endOfWordPos = line.find_first_not_of("abcdefghijklmnopqrstuvwxyz", pos + 1);
-
- if (endOfWordPos != string::npos) {
-
- if (line[endOfWordPos] == ';' && (endOfWordPos - pos) > 1) {
- // if entity is not recognized by Doxygen (not in the list of
- // commands) nothing is added (here and in Doxygen).
- addDoxyCommand(m_tokenList, line.substr(pos, endOfWordPos - pos));
- endOfWordPos++; // skip ';'
- } else {
- // it is not an entity - add entity for ampersand and the rest of string
- addDoxyCommand(m_tokenList, "&amp");
- m_tokenList.push_back(Token(PLAINSTRING, line.substr(pos + 1, endOfWordPos - pos - 1)));
- }
- }
- pos = endOfWordPos;
-}
-
-/*
- * This method processes normal comment, which has to be tokenized.
- */
-size_t DoxygenParser::processNormalComment(size_t pos, const std::string &line) {
- switch (line[pos]) {
- case '\\':
- case '@':
- if (processEscapedChars(pos, line)) {
- break;
- }
- // handle word commands \arg, \c, \return, ... and \f[, \f$, ... commands
- processWordCommands(pos, line);
- break;
-
- case ' ': // whitespace
- case '\t':
- {
- // whitespaces are stored as plain strings
- size_t startOfNextWordPos = line.find_first_not_of(" \t", pos + 1);
- m_tokenList.push_back(Token(PLAINSTRING, line.substr(pos, startOfNextWordPos - pos)));
- pos = startOfNextWordPos;
- }
- break;
-
- case '<':
- processHtmlTags(pos, line);
- break;
- case '>': // this char is detected here only when it is not part of HTML tag
- addDoxyCommand(m_tokenList, "&gt");
- pos++;
- break;
- case '&':
- processHtmlEntities(pos, line);
- break;
- case '"':
- m_isInQuotedString = true;
- m_tokenList.push_back(Token(PLAINSTRING, "\""));
- pos++;
- break;
- default:
- m_tokenListIt = m_tokenList.end();
- printListError(WARN_DOXYGEN_UNKNOWN_CHARACTER, std::string("Unknown special character in Doxygen comment: ") + line[pos] + ".");
- }
-
- return pos;
-}
-
-/*
- * This is the main method, which tokenizes Doxygen comment to words and
- * doxygen commands.
- */
-void DoxygenParser::tokenizeDoxygenComment(const std::string &doxygenComment, const std::string &fileName, int fileLine) {
- m_isVerbatimText = false;
- m_isInQuotedString = false;
- m_tokenList.clear();
- m_fileLineNo = fileLine;
- m_fileName = fileName;
-
- StringVector lines = split(doxygenComment, '\n');
-
- // remove trailing spaces, because they cause additional new line at the end
- // comment, which is wrong, because these spaces are space preceding
- // end of comment : ' */'
- if (!doxygenComment.empty() && doxygenComment[doxygenComment.size() - 1] == ' ') {
-
- string lastLine = lines[lines.size() - 1];
-
- if (trim(lastLine).empty()) {
- lines.pop_back(); // remove trailing empty line
- }
- }
-
- for (StringVectorCIt it = lines.begin(); it != lines.end(); it++) {
- const string &line = *it;
- size_t pos = line.find_first_not_of(" \t");
-
- if (pos == string::npos) {
- m_tokenList.push_back(Token(END_LINE, "\n"));
- continue;
- }
- // skip sequences of '*', '/', and '!' of any length
- bool isStartOfCommentLineCharFound = false;
- while (pos < line.size() && isStartOfDoxyCommentChar(line[pos])) {
- pos++;
- isStartOfCommentLineCharFound = true;
- }
-
- if (pos == line.size()) {
- m_tokenList.push_back(Token(END_LINE, "\n"));
- continue;
- }
- // if 'isStartOfCommentLineCharFound' then preserve leading spaces, so
- // ' * comment' gets translated to ' * comment', not ' * comment'
- // This is important to keep formatting for comments translated to Python.
- if (isStartOfCommentLineCharFound && line[pos] == ' ') {
- pos++; // points to char after ' * '
- if (pos == line.size()) {
- m_tokenList.push_back(Token(END_LINE, "\n"));
- continue;
- }
- }
- // line[pos] may be ' \t' or start of word, it there was no '*', '/' or '!'
- // at beginning of the line. Make sure it points to start of the first word
- // in the line.
- if (isStartOfCommentLineCharFound) {
- size_t firstWordPos = line.find_first_not_of(" \t", pos);
- if (firstWordPos == string::npos) {
- m_tokenList.push_back(Token(END_LINE, "\n"));
- continue;
- }
-
- if (firstWordPos > pos) {
- m_tokenList.push_back(Token(PLAINSTRING, line.substr(pos, firstWordPos - pos)));
- pos = firstWordPos;
- }
- } else {
- m_tokenList.push_back(Token(PLAINSTRING, line.substr(0, pos)));
- }
-
- while (pos != string::npos) {
- // find the end of the word
- size_t doxyCmdOrHtmlTagPos = line.find_first_of("\\@<>&\" \t", pos);
- if (doxyCmdOrHtmlTagPos != pos) {
- // plain text found
- // if the last char is punctuation, make it a separate word, otherwise
- // it may be included with word also when not appropriate, for example:
- // colors are \b red, green, and blue --> colors are <b>red,</b> green, and blue
- // instead of (comma not bold):
- // colors are \b red, green, and blue --> colors are <b>red</b>, green, and blue
- // In Python it looks even worse:
- // colors are \b red, green, and blue --> colors are 'red,' green, and blue
- string text = line.substr(pos, doxyCmdOrHtmlTagPos - pos);
- string punctuations(".,:");
- size_t textSize = text.size();
-
- if (!text.empty()
- && punctuations.find(text[text.size() - 1]) != string::npos &&
- // but do not break ellipsis (...)
- !(textSize > 1 && text[textSize - 2] == '.')) {
- m_tokenList.push_back(Token(PLAINSTRING, text.substr(0, text.size() - 1)));
- m_tokenList.push_back(Token(PLAINSTRING, text.substr(text.size() - 1)));
- } else {
- m_tokenList.push_back(Token(PLAINSTRING, text));
- }
- }
-
- pos = doxyCmdOrHtmlTagPos;
- if (pos != string::npos) {
- if (m_isVerbatimText) {
- pos = processVerbatimText(pos, line);
-
- } else if (m_isInQuotedString) {
-
- if (line[pos] == '"') {
- m_isInQuotedString = false;
- }
- m_tokenList.push_back(Token(PLAINSTRING, line.substr(pos, 1)));
- pos++;
-
- } else {
- pos = processNormalComment(pos, line);
- }
- }
- }
- m_tokenList.push_back(Token(END_LINE, "\n")); // add when pos == npos - end of line
- }
-
- m_tokenListIt = m_tokenList.begin();
-}
-
-void DoxygenParser::printList() {
-
- int tokNo = 0;
- for (TokenListCIt it = m_tokenList.begin(); it != m_tokenList.end(); it++, tokNo++) {
-
- cout << it->toString() << " ";
-
- if ((tokNo % TOKENSPERLINE) == 0) {
- cout << endl;
- }
- }
-}
-
-void DoxygenParser::printListError(int warningType, const std::string &message) {
- int curLine = m_fileLineNo;
- for (TokenListCIt it = m_tokenList.begin(); it != m_tokenListIt; it++) {
- if (it->m_tokenType == END_LINE) {
- curLine++;
- }
- }
-
- Swig_warning(warningType, m_fileName.c_str(), curLine, "%s\n", message.c_str());
-}
diff --git a/contrib/tools/swig/Source/Doxygen/doxyparser.h b/contrib/tools/swig/Source/Doxygen/doxyparser.h
deleted file mode 100644
index a60446517b..0000000000
--- a/contrib/tools/swig/Source/Doxygen/doxyparser.h
+++ /dev/null
@@ -1,377 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * doxyparser.h
- * ----------------------------------------------------------------------------- */
-
-#ifndef SWIG_DOXYPARSER_H
-#define SWIG_DOXYPARSER_H
-#include <string>
-#include <list>
-#include <map>
-#include <vector>
-#include <set>
-
-#include "swig.h"
-
-#include "doxyentity.h"
-
-// Utility function to return the base part of a command that may
-// include options, e.g. param[in] -> param
-std::string getBaseCommand(const std::string &cmd);
-
-
-class DoxygenParser {
-private:
-
- enum DoxyCommandEnum {
- NONE = -1,
- SIMPLECOMMAND,
- COMMANDWORD,
- COMMANDLINE,
- COMMANDPARAGRAPH,
- COMMANDENDCOMMAND,
- COMMANDWORDPARAGRAPH,
- COMMANDWORDLINE,
- COMMANDWORDOWORDWORD,
- COMMANDOWORD,
- COMMANDERRORTHROW,
- COMMANDUNIQUE,
- COMMAND_HTML,
- COMMAND_HTML_ENTITY,
- COMMAND_ALIAS,
- COMMAND_IGNORE,
- END_LINE,
- PARAGRAPH_END,
- PLAINSTRING,
- COMMAND
- };
-
-
- /** This class contains parts of Doxygen comment as a token. */
- class Token {
- public:
- DoxyCommandEnum m_tokenType;
- std::string m_tokenString; /* the data , such as param for @param */
-
- Token(DoxyCommandEnum tType, std::string tString) : m_tokenType(tType), m_tokenString(tString) {
- }
-
- std::string toString() const {
- switch (m_tokenType) {
- case END_LINE:
- return "{END OF LINE}";
- case PARAGRAPH_END:
- return "{END OF PARAGRAPH}";
- case PLAINSTRING:
- return "{PLAINSTRING :" + m_tokenString + "}";
- case COMMAND:
- return "{COMMAND : " + m_tokenString + "}";
- default:
- return "";
- }
- }
- };
-
-
- typedef std::vector<Token> TokenList;
- typedef TokenList::const_iterator TokenListCIt;
- typedef TokenList::iterator TokenListIt;
-
- TokenList m_tokenList;
- TokenListCIt m_tokenListIt;
-
- typedef std::map<std::string, DoxyCommandEnum> DoxyCommandsMap;
- typedef DoxyCommandsMap::iterator DoxyCommandsMapIt;
-
- /*
- * Map of Doxygen commands to determine if a string is a
- * command and how it needs to be parsed
- */
- static DoxyCommandsMap doxygenCommands;
- static std::set<std::string> doxygenSectionIndicators;
-
- bool m_isVerbatimText; // used to handle \htmlonly and \verbatim commands
- bool m_isInQuotedString;
-
- Node *m_node;
- std::string m_fileName;
- int m_fileLineNo;
-
- /*
- * Return the end command for a command appearing in "ignore" feature or empty
- * string if this is a simple command and not a block one.
- */
- std::string getIgnoreFeatureEndCommand(const std::string &theCommand) const;
-
- /*
- * Helper for getting the value of doxygen:ignore feature or its argument.
- */
- String *getIgnoreFeature(const std::string &theCommand, const char *argument = NULL) const;
-
- /*
- * Whether to print lots of debug info during parsing
- */
- bool noisy;
-
- /*
- *Changes a std::string to all lower case
- */
- std::string stringToLower(const std::string &stringToConvert);
-
- /*
- * isSectionIndicator returns a boolean if the command is a section indicator
- * This is a helper method for finding the end of a paragraph
- * by Doxygen's terms
- */
- bool isSectionIndicator(const std::string &smallString);
- /*
- * Determines how a command should be handled (what group it belongs to
- * for parsing rules
- */
- DoxyCommandEnum commandBelongs(const std::string &theCommand);
-
- /*
- *prints the parse tree
- */
- void printTree(const std::list<DoxygenEntity> &rootList);
-
- /**
- * Returns true if the next token is end of line token. This is important
- * when single word commands like \c are at the end of line.
- */
- bool isEndOfLine();
-
- /**
- * Skips spaces, tabs, and end of line tokens.
- */
- void skipWhitespaceTokens();
-
- /**
- * Removes all spaces and tabs from beginning end end of string.
- */
- std::string trim(const std::string &text);
-
- /*
- * Returns string of the next token if the next token is PLAINSTRING. Returns
- * empty string otherwise.
- */
- std::string getNextToken();
-
- /*
- * Returns the next word ON THE CURRENT LINE ONLY
- * if a new line is encountered, returns a blank std::string.
- * Updates the iterator if successful.
- */
- std::string getNextWord();
-
- /*
- * Returns the next word, which is not necessarily on the same line.
- * Updates the iterator if successful.
- */
- std::string getNextWordInComment();
-
- /*
- * Returns the location of the end of the line as
- * an iterator.
- */
- TokenListCIt getOneLine(const TokenList &tokList);
-
- /*
- * Returns a properly formatted std::string
- * up til ANY command or end of line is encountered.
- */
- std::string getStringTilCommand(const TokenList &tokList);
-
- /*
- * Returns a properly formatted std::string
- * up til the command specified is encountered
- */
- //TODO check that this behaves properly for formulas
- std::string getStringTilEndCommand(const std::string &theCommand, const TokenList &tokList);
-
- /*
- * Returns the end of a Paragraph as an iterator-
- * Paragraph is defined in Doxygen to be a paragraph of text
- * separated by either a structural command or a blank line
- */
- TokenListCIt getEndOfParagraph(const TokenList &tokList);
-
- /*
- * Returns the end of a section, defined as the first blank line OR first
- * encounter of the same command. Example of this behaviour is \arg.
- * If no end is encountered, returns the last token of the std::list.
- */
- TokenListCIt getEndOfSection(const std::string &theCommand, const TokenList &tokList);
-
- /*
- * This method is for returning the end of a specific form of doxygen command
- * that begins with a \command and ends in \endcommand
- * such as \code and \endcode. The proper usage is
- * progressTilEndCommand("endcode", tokenList);
- * If the end is never encountered, it returns the end of the std::list.
- */
- TokenListCIt getEndCommand(const std::string &theCommand, const TokenList &tokList);
- /*
- * A special method for commands such as \arg that end at the end of a
- * paragraph OR when another \arg is encountered
- //TODO getTilAnyCommand
- TokenListCIt getTilAnyCommand(const std::string &theCommand, const TokenList &tokList);
- */
-
- /**
- * This methods skips end of line token, if it is the next token to be
- * processed. It is called with comment commands which have args till the
- * end of line, such as 'addtogroup' or 'addindex'.
- * It is up to translator to specific language to decide whether
- * to insert eol or not. For example, if a command is ignored in target
- * language, new lines may make formatting ugly (Python).
- */
- void skipEndOfLine();
-
- /*
- * Method for Adding a Simple Command
- * Format: @command
- * Plain commands, such as newline etc, they contain no other data
- * \n \\ \@ \& \$ \# \< \> \% \{ \}
- */
- void addSimpleCommand(const std::string &theCommand, DoxygenEntityList &doxyList);
- /*
- * CommandWord
- * Format: @command <word>
- * Commands with a single WORD after then such as @b
- * "a", "b", "c", "e", "em", "p", "def", "enum", "example", "package",
- * "relates", "namespace", "relatesalso","anchor", "dontinclude", "include",
- * "includelineno"
- */
- void addCommandWord(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
- /*
- * CommandLine
- * Format: @command (line)
- * Commands with a single LINE after then such as @var
- * "addindex", "fn", "name", "line", "var", "skipline", "typedef", "skip",
- * "until", "property"
- */
- void addCommandLine(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
- /*
- * CommandParagraph
- * Format: @command {paragraph}
- * Commands with a single paragraph after then such as @return
- * "return", "remarks", "since", "test", "sa", "see", "pre", "post",
- * "details", "invariant", "deprecated", "date", "note", "warning",
- * "version", "todo", "bug", "attention", "brief", "arg", "author"
- */
- void addCommandParagraph(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
- /*
- * Command EndCommand
- * Format: @command and ends at @endcommand
- * Commands that take in a block of text such as @code:
- * "code", "dot", "msc", "f$", "f[", "f{environment}{", "htmlonly",
- * "latexonly", "manonly", "verbatim", "xmlonly", "cond", "if", "ifnot",
- * "link"
- * Returns 1 if success, 0 if the endcommand is never encountered.
- */
- void addCommandEndCommand(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
- /*
- * CommandWordParagraph
- * Format: @command <word> {paragraph}
- * Commands such as param
- * "param", "tparam", "throw", "throws", "retval", "exception"
- */
- void addCommandWordParagraph(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
- /*
- * CommandWordLine
- * Format: @command <word> (line)
- * Commands such as param
- * "page", "subsection", "subsubsection", "section", "paragraph", "defgroup"
- */
- void addCommandWordLine(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
- /*
- * Command Word Optional Word Optional Word
- * Format: @command <word> [<header-file>] [<header-name>]
- * Commands such as class
- * "category", "class", "protocol", "interface", "struct", "union"
- */
- void addCommandWordOWordOWord(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
- /*
- * Command Optional Word
- * Format: @command [<word>]
- * Commands such as dir
- * "dir", "file", "cond"
- */
- void addCommandOWord(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
-
- /*
- * Commands that should not be encountered (such as PHP only)
- * goes til the end of line then returns
- */
- void addCommandErrorThrow(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
-
- void addCommandHtml(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
-
- void addCommandHtmlEntity(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
-
- /*
- *Adds the unique commands- different process for each unique command
- */
- void addCommandUnique(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
-
- /*
- * Replace the given command with its predefined alias expansion.
- */
- void aliasCommand(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
-
- /*
- * Simply ignore the given command, possibly with the word following it or
- * until the matching end command.
- */
- void ignoreCommand(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
-
- /*
- * The actual "meat" of the doxygen parser. Calls the correct addCommand...()
- * function.
- */
- void addCommand(const std::string &commandString, const TokenList &tokList, DoxygenEntityList &doxyList);
-
- DoxygenEntityList parse(TokenListCIt endParsingIndex, const TokenList &tokList, bool root = false);
-
- /*
- * Fill static doxygenCommands and sectionIndicators containers
- */
- void fillTables();
-
- /** Processes comment when \htmlonly and \verbatim commands are encountered. */
- size_t processVerbatimText(size_t pos, const std::string &line);
-
- bool processEscapedChars(size_t &pos, const std::string &line);
- void processWordCommands(size_t &pos, const std::string &line);
- void processHtmlTags(size_t &pos, const std::string &line);
- void processHtmlEntities(size_t &pos, const std::string &line);
-
-
- /** Processes comment outside \htmlonly and \verbatim commands. */
- size_t processNormalComment(size_t pos, const std::string &line);
-
- void tokenizeDoxygenComment(const std::string &doxygenComment, const std::string &fileName, int fileLine);
- void printList();
- void printListError(int warningType, const std::string &message);
-
- typedef std::vector<std::string> StringVector;
- typedef StringVector::const_iterator StringVectorCIt;
-
- StringVector split(const std::string &text, char separator);
- bool isStartOfDoxyCommentChar(char c);
- bool addDoxyCommand(DoxygenParser::TokenList &tokList, const std::string &cmd);
-
-public:
- DoxygenParser(bool noisy = false);
- virtual ~DoxygenParser();
- DoxygenEntityList createTree(Node *node, String *documentation);
-};
-
-#endif
diff --git a/contrib/tools/swig/Source/Doxygen/doxytranslator.cxx b/contrib/tools/swig/Source/Doxygen/doxytranslator.cxx
deleted file mode 100644
index a638717eca..0000000000
--- a/contrib/tools/swig/Source/Doxygen/doxytranslator.cxx
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * doxytranslator.cxx
- *
- * Module to return documentation for nodes formatted for various documentation
- * systems.
- * ----------------------------------------------------------------------------- */
-
-#include "doxytranslator.h"
-
-DoxygenTranslator::DoxygenTranslator(int flags) : m_flags(flags), parser((flags &debug_parser) != 0) {
-}
-
-
-DoxygenTranslator::~DoxygenTranslator() {
-}
-
-
-bool DoxygenTranslator::hasDocumentation(Node *node) {
- return getDoxygenComment(node) != NULL;
-}
-
-
-String *DoxygenTranslator::getDoxygenComment(Node *node) {
- return Getattr(node, "doxygen");
-}
-
-/**
- * Indent all lines in the comment by given indentation string
- */
-void DoxygenTranslator::extraIndentation(String *comment, const_String_or_char_ptr indentationString) {
- if (indentationString || Len(indentationString) > 0) {
- int len = Len(comment);
- bool trailing_newline = len > 0 && *(Char(comment) + len - 1) == '\n';
- Insert(comment, 0, indentationString);
- String *replace = NewStringf("\n%s", indentationString);
- Replaceall(comment, "\n", replace);
- if (trailing_newline) {
- len = Len(comment);
- Delslice(comment, len - 2, len); // Remove added trailing spaces on last line
- }
- Delete(replace);
- }
-}
-
-String *DoxygenTranslator::getDocumentation(Node *node, const_String_or_char_ptr indentationString) {
-
- if (!hasDocumentation(node)) {
- return NewString("");
- }
-
- String *documentation = makeDocumentation(node);
- extraIndentation(documentation, indentationString);
- return documentation;
-}
-
-
-void DoxygenTranslator::printTree(const DoxygenEntityList &entityList) {
-
- for (DoxygenEntityListCIt p = entityList.begin(); p != entityList.end(); p++) {
- p->printEntity(0);
- }
-}
diff --git a/contrib/tools/swig/Source/Doxygen/doxytranslator.h b/contrib/tools/swig/Source/Doxygen/doxytranslator.h
deleted file mode 100644
index f0d3b1b060..0000000000
--- a/contrib/tools/swig/Source/Doxygen/doxytranslator.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * doxytranslator.h
- *
- * Module to return documentation for nodes formatted for various documentation
- * systems.
- * ----------------------------------------------------------------------------- */
-
-#ifndef SWIG_DOXYTRANSLATOR_H
-#define SWIG_DOXYTRANSLATOR_H
-
-#include "swig.h"
-#include "doxyentity.h"
-#include "doxyparser.h"
-#include <list>
-#include <string>
-
-
-/*
- * This is a base class for translator classes. It defines the basic interface
- * for translators, which convert Doxygen comments into alternative formats for
- * target languages.
- */
-class DoxygenTranslator {
-public:
- /*
- * Bit flags for the translator ctor.
- *
- * Derived classes may define additional flags.
- */
- enum {
- // Use DoxygenParser in "noisy" mode.
- debug_parser = 1,
-
- // Output results of translating Doxygen comments.
- debug_translator = 2
- };
-
- /*
- * Constructor
- */
- DoxygenTranslator(int flags = 0);
-
- /*
- * Virtual destructor.
- */
- virtual ~DoxygenTranslator();
-
- /*
- * Return the documentation for a given node formatted for the correct
- * documentation system.
- */
- String *getDocumentation(Node *node, const_String_or_char_ptr indentationString);
-
- /*
- * Returns true if the specified node has comment attached.
- */
- bool hasDocumentation(Node *node);
-
- /*
- * Get original comment string in Doxygen-format.
- */
- String *getDoxygenComment(Node *node);
-
-protected:
- // The flags passed to the ctor.
- const int m_flags;
-
- DoxygenParser parser;
-
- /*
- * Returns the documentation formatted for a target language.
- */
- virtual String *makeDocumentation(Node *node) = 0;
-
- /*
- * Prints the details of a parsed entity list to stdout (for debugging).
- */
- void printTree(const DoxygenEntityList &entityList);
-
- void extraIndentation(String *comment, const_String_or_char_ptr indentationString);
-};
-
-#endif
diff --git a/contrib/tools/swig/Source/Doxygen/javadoc.cxx b/contrib/tools/swig/Source/Doxygen/javadoc.cxx
deleted file mode 100644
index a1406b2303..0000000000
--- a/contrib/tools/swig/Source/Doxygen/javadoc.cxx
+++ /dev/null
@@ -1,849 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * javadoc.cxx
- * ----------------------------------------------------------------------------- */
-
-#include "javadoc.h"
-#include "doxyparser.h"
-#include <iostream>
-#include <vector>
-#include <list>
-#include "swigmod.h"
-#define APPROX_LINE_LENGTH 64 // characters per line allowed
-#define TAB_SIZE 8 // current tab size in spaces
-//TODO {@link} {@linkplain} {@docRoot}, and other useful doxy commands that are not a javadoc tag
-
-// define static tables, they are filled in JavaDocConverter's constructor
-std::map<std::string, std::pair<JavaDocConverter::tagHandler, std::string> > JavaDocConverter::tagHandlers;
-
-using std::string;
-using std::list;
-using std::vector;
-
-void JavaDocConverter::fillStaticTables() {
- if (tagHandlers.size()) // fill only once
- return;
-
- /*
- * Some translation rules:
- *
- * @ and \ must be escaped for both Java and Python to appear on output: \@, \\,
- * while Doxygen produces output in both cases.
- * Rule: @ and \ with space on the right should get to output.
- *
- * :: remains intact, even in class::method(). But you can use class#method also
- * in C++ comment and it is properly translated to C++ output (changed by doxygen to ::)
- * and Java output (remains #).
- * Rule: SWIG type system can't be used to convert C::m to C#m, because in Java it is C.m
- * Use string replacement :: --> # in tag see and links.
- *
- * HTML tags must be translated - remain in Java, to markdown in Python
- *
- * Unknown HTML tags, for example <x> is translated to &lt;x&gt; by doxygen, while
- * Java src is <x> and therefore invisible on output - browser ignores unknown command.
- * This is handy in syntax descriptions, for example: more <fileName>.
- *
- * Standalone < and > need not be translated, they are rendered properly in
- * all three outputs.
- *
- * ., %, and " need not to be translated
- *
- * entities must be translated - remain in Java, something meaningful in Python (&lt, ...)
- *
- * - Python
- * - add comments also to auto-generated methods like equals(), delete() in Java,
- * and methods for std::vector(), ...
- * Commenting methods of std types is simple - add comment to std_*.i file.
- */
-
- // these commands insert HTML tags
- tagHandlers["a"] = make_pair(&JavaDocConverter::handleTagHtml, "i");
- tagHandlers["arg"] = make_pair(&JavaDocConverter::handleTagHtml, "li");
- tagHandlers["b"] = make_pair(&JavaDocConverter::handleTagHtml, "b");
- tagHandlers["c"] = make_pair(&JavaDocConverter::handleTagHtml, "code");
- tagHandlers["cite"] = make_pair(&JavaDocConverter::handleTagHtml, "i");
- tagHandlers["e"] = make_pair(&JavaDocConverter::handleTagHtml, "i");
- tagHandlers["em"] = make_pair(&JavaDocConverter::handleTagHtml, "i");
- tagHandlers["li"] = make_pair(&JavaDocConverter::handleTagHtml, "li");
- tagHandlers["p"] = make_pair(&JavaDocConverter::handleTagHtml, "code");
- // these commands insert just a single char, some of them need to be escaped
- tagHandlers["$"] = make_pair(&JavaDocConverter::handleTagChar, "");
- tagHandlers["@"] = make_pair(&JavaDocConverter::handleTagChar, "");
- tagHandlers["\\"] = make_pair(&JavaDocConverter::handleTagChar, "");
- tagHandlers["<"] = make_pair(&JavaDocConverter::handleTagChar, "&lt;");
- tagHandlers[">"] = make_pair(&JavaDocConverter::handleTagChar, "&gt;");
- tagHandlers["&"] = make_pair(&JavaDocConverter::handleTagChar, "&amp;");
- tagHandlers["#"] = make_pair(&JavaDocConverter::handleTagChar, "");
- tagHandlers["%"] = make_pair(&JavaDocConverter::handleTagChar, "");
- tagHandlers["~"] = make_pair(&JavaDocConverter::handleTagChar, "");
- tagHandlers["\""] = make_pair(&JavaDocConverter::handleTagChar, "&quot;");
- tagHandlers["."] = make_pair(&JavaDocConverter::handleTagChar, "");
- tagHandlers["::"] = make_pair(&JavaDocConverter::handleTagChar, "");
- // these commands are stripped out
- tagHandlers["attention"] = make_pair(&JavaDocConverter::handleParagraph, "");
- tagHandlers["anchor"] = make_pair(&JavaDocConverter::handleTagAnchor, "");
- tagHandlers["brief"] = make_pair(&JavaDocConverter::handleParagraph, "");
- tagHandlers["bug"] = make_pair(&JavaDocConverter::handleParagraph, "");
- tagHandlers["date"] = make_pair(&JavaDocConverter::handleParagraph, "");
- tagHandlers["details"] = make_pair(&JavaDocConverter::handleParagraph, "");
- // this command is inserts text accumulated after cmd htmlonly -
- // see DoxygenParser - CMD_HTML_ONLY.
- tagHandlers["htmlonly"] = make_pair(&JavaDocConverter::handleParagraph, "");
- tagHandlers["invariant"] = make_pair(&JavaDocConverter::handleParagraph, "");
- tagHandlers["latexonly"] = make_pair(&JavaDocConverter::handleParagraph, "");
- tagHandlers["manonly"] = make_pair(&JavaDocConverter::handleParagraph, "");
- tagHandlers["partofdescription"] = make_pair(&JavaDocConverter::handleParagraph, "");
- tagHandlers["rtfonly"] = make_pair(&JavaDocConverter::handleParagraph, "");
- tagHandlers["short"] = make_pair(&JavaDocConverter::handleParagraph, "");
- tagHandlers["xmlonly"] = make_pair(&JavaDocConverter::handleParagraph, "");
- // these commands are kept as-is, they are supported by JavaDoc
- tagHandlers["author"] = make_pair(&JavaDocConverter::handleTagSame, "");
- tagHandlers["authors"] = make_pair(&JavaDocConverter::handleTagSame, "author");
- tagHandlers["deprecated"] = make_pair(&JavaDocConverter::handleTagSame, "");
- tagHandlers["exception"] = make_pair(&JavaDocConverter::handleTagSame, "");
- tagHandlers["package"] = make_pair(&JavaDocConverter::handleTagSame, "");
- tagHandlers["param"] = make_pair(&JavaDocConverter::handleTagParam, "");
- tagHandlers["tparam"] = make_pair(&JavaDocConverter::handleTagParam, "");
- tagHandlers["ref"] = make_pair(&JavaDocConverter::handleTagRef, "");
- tagHandlers["result"] = make_pair(&JavaDocConverter::handleTagSame, "return");
- tagHandlers["return"] = make_pair(&JavaDocConverter::handleTagSame, "");
- tagHandlers["returns"] = make_pair(&JavaDocConverter::handleTagSame, "return");
- //tagHandlers["see"] = make_pair(&JavaDocConverter::handleTagSame, "");
- //tagHandlers["sa"] = make_pair(&JavaDocConverter::handleTagSame, "see");
- tagHandlers["since"] = make_pair(&JavaDocConverter::handleTagSame, "");
- tagHandlers["throws"] = make_pair(&JavaDocConverter::handleTagSame, "");
- tagHandlers["throw"] = make_pair(&JavaDocConverter::handleTagSame, "throws");
- tagHandlers["version"] = make_pair(&JavaDocConverter::handleTagSame, "");
- // these commands have special handlers
- tagHandlers["code"] = make_pair(&JavaDocConverter::handleTagExtended, "code");
- tagHandlers["cond"] = make_pair(&JavaDocConverter::handleTagMessage, "Conditional comment: ");
- tagHandlers["copyright"] = make_pair(&JavaDocConverter::handleTagMessage, "Copyright: ");
- tagHandlers["else"] = make_pair(&JavaDocConverter::handleTagIf, "Else: ");
- tagHandlers["elseif"] = make_pair(&JavaDocConverter::handleTagIf, "Else if: ");
- tagHandlers["endcond"] = make_pair(&JavaDocConverter::handleTagMessage, "End of conditional comment.");
- // space in second arg prevents Javadoc to treat '@ example' as command. File name of
- // example is still informative to user.
- tagHandlers["example"] = make_pair(&JavaDocConverter::handleTagSame, " example");
- tagHandlers["if"] = make_pair(&JavaDocConverter::handleTagIf, "If: ");
- tagHandlers["ifnot"] = make_pair(&JavaDocConverter::handleTagIf, "If not: ");
- tagHandlers["image"] = make_pair(&JavaDocConverter::handleTagImage, "");
- tagHandlers["link"] = make_pair(&JavaDocConverter::handleTagLink, "");
- tagHandlers["see"] = make_pair(&JavaDocConverter::handleTagSee, "");
- tagHandlers["sa"] = make_pair(&JavaDocConverter::handleTagSee, "");
- tagHandlers["note"] = make_pair(&JavaDocConverter::handleTagMessage, "Note: ");
- tagHandlers["overload"] = make_pair(&JavaDocConverter::handleTagMessage,
- "This is an overloaded member function, provided for"
- " convenience. It differs from the above function only in what" " argument(s) it accepts.");
- tagHandlers["par"] = make_pair(&JavaDocConverter::handleTagPar, "");
- tagHandlers["remark"] = make_pair(&JavaDocConverter::handleTagMessage, "Remarks: ");
- tagHandlers["remarks"] = make_pair(&JavaDocConverter::handleTagMessage, "Remarks: ");
- tagHandlers["todo"] = make_pair(&JavaDocConverter::handleTagMessage, "TODO: ");
- tagHandlers["verbatim"] = make_pair(&JavaDocConverter::handleTagExtended, "literal");
-
- // \f commands output literal Latex formula, which is still better than nothing.
- tagHandlers["f$"] = make_pair(&JavaDocConverter::handleTagVerbatim, "");
- tagHandlers["f["] = make_pair(&JavaDocConverter::handleTagVerbatim, "");
- tagHandlers["f{"] = make_pair(&JavaDocConverter::handleTagVerbatim, "");
-
- tagHandlers["warning"] = make_pair(&JavaDocConverter::handleTagMessage, "Warning: ");
- // this command just prints its contents
- // (it is internal command of swig's parser, contains plain text)
- tagHandlers["plainstd::string"] = make_pair(&JavaDocConverter::handlePlainString, "");
- tagHandlers["plainstd::endl"] = make_pair(&JavaDocConverter::handleNewLine, "");
- tagHandlers["n"] = make_pair(&JavaDocConverter::handleNewLine, "");
-
- // HTML tags
- tagHandlers["<a"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<a");
- tagHandlers["<b"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<b");
- tagHandlers["<blockquote"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<blockquote");
- tagHandlers["<body"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<body");
- tagHandlers["<br"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<br");
- tagHandlers["<center"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<center");
- tagHandlers["<caption"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<caption");
- tagHandlers["<code"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<code");
- tagHandlers["<dd"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<dd");
- tagHandlers["<dfn"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<dfn");
- tagHandlers["<div"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<div");
- tagHandlers["<dl"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<dl");
- tagHandlers["<dt"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<dt");
- tagHandlers["<em"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<em");
- tagHandlers["<form"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<form");
- tagHandlers["<hr"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<hr");
- tagHandlers["<h1"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<h1");
- tagHandlers["<h2"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<h2");
- tagHandlers["<h3"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<h3");
- tagHandlers["<i"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<i");
- tagHandlers["<input"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<input");
- tagHandlers["<img"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<img");
- tagHandlers["<li"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<li");
- tagHandlers["<meta"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<meta");
- tagHandlers["<multicol"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<multicol");
- tagHandlers["<ol"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<ol");
- tagHandlers["<p"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<p");
- tagHandlers["<pre"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<pre");
- tagHandlers["<small"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<small");
- tagHandlers["<span"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<span");
- tagHandlers["<strong"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<strong");
- tagHandlers["<sub"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<sub");
- tagHandlers["<sup"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<sup");
- tagHandlers["<table"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<table");
- tagHandlers["<td"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<td");
- tagHandlers["<th"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<th");
- tagHandlers["<tr"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<tr");
- tagHandlers["<tt"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<tt");
- tagHandlers["<kbd"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<kbd");
- tagHandlers["<ul"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<ul");
- tagHandlers["<var"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<var");
-
- // HTML entities
- tagHandlers["&copy"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&copy");
- tagHandlers["&trade"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&trade");
- tagHandlers["&reg"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&reg");
- tagHandlers["&lt"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&lt");
- tagHandlers["&gt"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&gt");
- tagHandlers["&amp"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&amp");
- tagHandlers["&apos"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&apos");
- tagHandlers["&quot"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&quot");
- tagHandlers["&lsquo"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&lsquo");
- tagHandlers["&rsquo"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&rsquo");
- tagHandlers["&ldquo"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&ldquo");
- tagHandlers["&rdquo"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&rdquo");
- tagHandlers["&ndash"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&ndash");
- tagHandlers["&mdash"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&mdash");
- tagHandlers["&nbsp"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&nbsp");
- tagHandlers["&times"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&times");
- tagHandlers["&minus"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&minus");
- tagHandlers["&sdot"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&sdot");
- tagHandlers["&sim"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&sim");
- tagHandlers["&le"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&le");
- tagHandlers["&ge"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&ge");
- tagHandlers["&larr"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&larr");
- tagHandlers["&rarr"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&rarr");
-}
-
-JavaDocConverter::JavaDocConverter(int flags) :
- DoxygenTranslator(flags) {
- fillStaticTables();
-}
-
-/**
- * Formats comment lines by inserting '\n *' at to long lines and tabs for
- * indent. Currently it is disabled, which means original comment format is
- * preserved. Experience shows, that this is usually better than breaking
- * lines automatically, especially because original line endings are not removed,
- * which results in short lines. To be useful, this function should have much
- * better algorithm.
- */
-std::string JavaDocConverter::formatCommand(std::string unformattedLine, int indent) {
- std::string formattedLines;
- return unformattedLine; // currently disabled
- std::string::size_type lastPosition = 0;
- std::string::size_type i = 0;
- int isFirstLine = 1;
- while (i != std::string::npos && i < unformattedLine.length()) {
- lastPosition = i;
- if (isFirstLine) {
- i += APPROX_LINE_LENGTH;
- } else {
- i += APPROX_LINE_LENGTH - indent * TAB_SIZE;
- }
-
- i = unformattedLine.find(" ", i);
-
- if (i > 0 && i + 1 < unformattedLine.length()) {
- if (!isFirstLine)
- for (int j = 0; j < indent; j++) {
- formattedLines.append("\t");
- } else {
- isFirstLine = 0;
- }
- formattedLines.append(unformattedLine.substr(lastPosition, i - lastPosition + 1));
- formattedLines.append("\n *");
-
- }
- }
- if (lastPosition < unformattedLine.length()) {
- if (!isFirstLine) {
- for (int j = 0; j < indent; j++) {
- formattedLines.append("\t");
- }
- }
- formattedLines.append(unformattedLine.substr(lastPosition, unformattedLine.length() - lastPosition));
- }
-
- return formattedLines;
-}
-
-/**
- * Returns true, if the given parameter exists in the current node
- * (for example param is a name of function parameter). If feature
- * 'doxygen:nostripparams' is set, then this method always returns
- * true - parameters are copied to output regardless of presence in
- * function params list.
- */
-bool JavaDocConverter::paramExists(std::string param) {
-
- if (GetFlag(currentNode, "feature:doxygen:nostripparams")) {
- return true;
- }
-
- ParmList *plist = CopyParmList(Getattr(currentNode, "parms"));
-
- for (Parm *p = plist; p;) {
-
- if (Getattr(p, "name") && Char(Getattr(p, "name")) == param) {
- return true;
- }
- /* doesn't seem to work always: in some cases (especially for 'self' parameters)
- * tmap:in is present, but tmap:in:next is not and so this code skips all the parameters
- */
- //p = Getattr(p, "tmap:in") ? Getattr(p, "tmap:in:next") : nextSibling(p);
- p = nextSibling(p);
- }
-
- Delete(plist);
-
- return false;
-}
-
-std::string JavaDocConverter::translateSubtree(DoxygenEntity &doxygenEntity) {
- std::string translatedComment;
-
- if (doxygenEntity.isLeaf) {
- return translatedComment;
- }
-
- for (DoxygenEntityListIt p = doxygenEntity.entityList.begin(); p != doxygenEntity.entityList.end(); p++) {
-
- translateEntity(*p, translatedComment);
- translateSubtree(*p);
- }
-
- return translatedComment;
-}
-
-/**
- * Checks if a handler for the given tag exists, and calls it.
- */
-void JavaDocConverter::translateEntity(DoxygenEntity &tag, std::string &translatedComment) {
-
- std::map<std::string, std::pair<tagHandler, std::string> >::iterator it;
- it = tagHandlers.find(getBaseCommand(tag.typeOfEntity));
-
- if (it != tagHandlers.end()) {
- (this->*(it->second.first))(tag, translatedComment, it->second.second);
- } else {
- // do NOT print warning, since there are many tags, which are not
- // translatable - many warnings hide important ones
- // addError(WARN_DOXYGEN_COMMAND_ERROR, "Unknown doxygen or HTML tag: " + tag.typeOfEntity);
- }
-}
-
-
-void JavaDocConverter::handleTagAnchor(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
- translatedComment += "<a id=\"" + translateSubtree(tag) + "\"></a>";
-}
-
-
-void JavaDocConverter::handleTagHtml(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
- if (tag.entityList.size()) { // do not include empty tags
- std::string tagData = translateSubtree(tag);
- // wrap the thing, ignoring whitespace
- size_t wsPos = tagData.find_last_not_of("\n\t ");
- if (wsPos != std::string::npos)
- translatedComment += "<" + arg + ">" + tagData.substr(0, wsPos + 1) + "</" + arg + ">" + tagData.substr(wsPos + 1);
- else
- translatedComment += "<" + arg + ">" + translateSubtree(tag) + "</" + arg + "> ";
- }
-}
-
-void JavaDocConverter::handleDoxyHtmlTag(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
- std::string htmlTagArgs = tag.data;
- if (htmlTagArgs == "/") {
- // end html tag, for example "</ul>
- translatedComment += "</" + arg.substr(1) + ">";
- } else {
- translatedComment += arg + htmlTagArgs + ">";
- }
-}
-
-void JavaDocConverter::handleHtmlEntity(DoxygenEntity &, std::string &translatedComment, std::string &arg) {
- // html entities can be preserved for Java
- translatedComment += arg + ';';
-}
-
-void JavaDocConverter::handleNewLine(DoxygenEntity &, std::string &translatedComment, std::string &) {
- // <br> tag is added, because otherwise to much text is joined
- // into same paragraph by javadoc. For example, doxy list:
- // - item one
- // - item two
- // becomes one paragraph with surrounding text without newlines.
- // This way we get to many empty lines in javadoc output, but this
- // is still better than joined lines. Possibility for improvements
- // exists.
- translatedComment += "<br>\n * ";
-}
-
-void JavaDocConverter::handleTagChar(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
- // escape it if we need to, else just print
- if (arg.size())
- translatedComment += arg;
- else
- translatedComment += tag.typeOfEntity;
-}
-
-// handles tags which are the same in Doxygen and Javadoc.
-void JavaDocConverter::handleTagSame(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
- if (arg.size())
- tag.typeOfEntity = arg;
- translatedComment += formatCommand(std::string("@" + tag.typeOfEntity + " " + translateSubtree(tag)), 2);
-}
-
-void JavaDocConverter::handleParagraph(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
- translatedComment += formatCommand(translateSubtree(tag), 0);
-}
-
-void JavaDocConverter::handlePlainString(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
- translatedComment += tag.data;
- // if (tag.data.size() && tag.data[tag.data.size()-1] != ' ')
- // translatedComment += " ";
-}
-
-void JavaDocConverter::handleTagVerbatim(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
- translatedComment += arg + " ";
- for (DoxygenEntityListCIt it = tag.entityList.begin(); it != tag.entityList.end(); it++) {
- translatedComment += it->data;
- }
-}
-
-void JavaDocConverter::handleTagExtended(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
- std::string dummy;
- translatedComment += "{@" + arg + " ";
- handleParagraph(tag, translatedComment, dummy);
- translatedComment += "}";
-}
-
-void JavaDocConverter::handleTagIf(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
- std::string dummy;
- translatedComment += arg;
- if (tag.entityList.size()) {
- translatedComment += tag.entityList.begin()->data;
- tag.entityList.pop_front();
- translatedComment += " {" + translateSubtree(tag) + "}";
- }
-}
-
-void JavaDocConverter::handleTagMessage(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
- std::string dummy;
- translatedComment += formatCommand(arg, 0);
- handleParagraph(tag, translatedComment, dummy);
-}
-
-void JavaDocConverter::handleTagImage(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
- if (tag.entityList.size() < 2)
- return;
-
- std::string file;
- std::string title;
-
- std::list<DoxygenEntity>::iterator it = tag.entityList.begin();
- if (it->data != "html")
- return;
-
- it++;
- file = it->data;
-
- it++;
- if (it != tag.entityList.end())
- title = it->data;
-
- translatedComment += "<img src=";
- if (file.size() >= 2 && file[0] == '"' && file[file.size() - 1] == '"')
- translatedComment += file;
- else
- translatedComment += "\"" + file + "\"";
- if (title.size())
- translatedComment += " alt=" + title;
-
- // the size indication is supported for Latex only in Doxygen, see manual
-
- translatedComment += "/>";
-}
-
-void JavaDocConverter::handleTagPar(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
- std::string dummy;
- translatedComment += "<p";
- if (tag.entityList.size()) {
- translatedComment += " alt=\"" + tag.entityList.begin()->data + "\"";
- translatedComment += ">";
- tag.entityList.pop_front();
- handleParagraph(tag, translatedComment, dummy);
- }
- translatedComment += "</p>";
-}
-
-
-void JavaDocConverter::handleTagParam(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
- std::string dummy;
-
- if (!tag.entityList.size())
- return;
- if (!paramExists(tag.entityList.begin()->data))
- return;
-
- translatedComment += "@param ";
- translatedComment += tag.entityList.begin()->data;
- tag.entityList.pop_front();
- handleParagraph(tag, translatedComment, dummy);
-}
-
-
-void JavaDocConverter::handleTagRef(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
- std::string dummy;
- if (!tag.entityList.size())
- return;
-
- // we translate to link, although \page is not supported in Java, but
- // reader at least knows what to look at. Also for \anchor tag on the same
- // page this link works.
- string anchor = tag.entityList.begin()->data;
- tag.entityList.pop_front();
- string anchorText = anchor;
- if (!tag.entityList.empty()) {
- anchorText = tag.entityList.begin()->data;
- }
- translatedComment += "<a href=\"#" + anchor + "\">" + anchorText + "</a>";
-}
-
-
-string JavaDocConverter::convertLink(string linkObject) {
- if (GetFlag(currentNode, "feature:doxygen:nolinktranslate"))
- return linkObject;
- // find the params in function in linkObject (if any)
- size_t lbracePos = linkObject.find('(', 0);
- size_t rbracePos = linkObject.find(')', 0);
- if (lbracePos == string::npos || rbracePos == string::npos || lbracePos >= rbracePos)
- return "";
-
- string paramsStr = linkObject.substr(lbracePos + 1,
- rbracePos - lbracePos - 1);
- // strip the params, to fill them later
- string additionalObject = linkObject.substr(rbracePos + 1, string::npos);
- linkObject = linkObject.substr(0, lbracePos);
-
- // find all the params
- vector<string> params;
- size_t lastPos = 0, commaPos = 0;
- while (true) {
- commaPos = paramsStr.find(',', lastPos);
- if (commaPos == string::npos)
- commaPos = paramsStr.size();
- string param = paramsStr.substr(lastPos, commaPos - lastPos);
- // if any param type is empty, we are failed
- if (!param.size())
- return "";
- params.push_back(param);
- lastPos = commaPos + 1;
- if (lastPos >= paramsStr.size())
- break;
- }
-
- linkObject += "(";
- for (size_t i = 0; i < params.size(); i++) {
- // translate c/c++ type string to swig's type
- // i e 'int **arr[100][10]' -> 'a(100).a(10).p.p.int'
- // also converting arrays to pointers
- string paramStr = params[i];
- String *swigType = NewString("");
-
- // handle const qualifier
- if (paramStr.find("const") != string::npos)
- SwigType_add_qualifier(swigType, "const");
-
- // handle pointers, references and arrays
- for (int j = (int)params[i].size() - 1; j >= 0; j--) {
- // skip all the [...] blocks, write 'p.' for every of it
- if (paramStr[j] == ']') {
- while (j >= 0 && paramStr[j] != '[')
- j--;
- // no closing brace
- if (j < 0)
- return "";
- SwigType_add_pointer(swigType);
- continue;
- } else if (paramStr[j] == '*')
- SwigType_add_pointer(swigType);
- else if (paramStr[j] == '&')
- SwigType_add_reference(swigType);
- else if (isalnum(paramStr[j])) {
- size_t typeNameStart = paramStr.find_last_of(' ', j + 1);
- if (typeNameStart == string::npos)
- typeNameStart = 0;
- else
- typeNameStart++;
- Append(swigType, paramStr.substr(typeNameStart, j - typeNameStart + 1).c_str());
- break;
- }
- }
-
- // make dummy param list, to lookup typemaps for it
- Parm *dummyParam = NewParm(swigType, "", 0);
- Swig_typemap_attach_parms("jstype", dummyParam, NULL);
- Language::instance()->replaceSpecialVariables(0, Getattr(dummyParam, "tmap:jstype"), dummyParam);
-
- //Swig_print(dummyParam, 1);
- linkObject += Char(Getattr(dummyParam, "tmap:jstype"));
- if (i != params.size() - 1)
- linkObject += ",";
-
- Delete(dummyParam);
- Delete(swigType);
- }
- linkObject += ")";
-
- return linkObject + additionalObject;
-}
-
-void JavaDocConverter::handleTagLink(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
- std::string dummy;
- if (!tag.entityList.size())
- return;
-
- string linkObject = convertLink(tag.entityList.begin()->data);
- if (!linkObject.size())
- linkObject = tag.entityList.begin()->data;
- tag.entityList.pop_front();
-
- translatedComment += "{@link ";
- translatedComment += linkObject + " ";
- handleParagraph(tag, translatedComment, dummy);
- translatedComment += "}";
-}
-
-void JavaDocConverter::handleTagSee(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
- std::string dummy;
- if (!tag.entityList.size())
- return;
-
- // tag.entity list contains contents of the @see paragraph. It should contain
- // one link (references) to method with or without parameters. Doxygen supports
- // arbitrary text and types mixed, but this feature is not supported here.
- // :: or # may be used as a separator between class name and method name.
- list<DoxygenEntity>::iterator it;
- string methodRef;
- for (it = tag.entityList.begin(); it != tag.entityList.end(); it++) {
- if (it->typeOfEntity == "plainstd::endl") {
- // handleNewLine(*it, translatedComment, dummy);
- continue;
- }
- // restore entities which may be used in C++ type declaration
- if (it->typeOfEntity == "&amp") {
- methodRef += '&';
- } else if (it->typeOfEntity == "&lt") {
- methodRef += '<';
- } else if (it->typeOfEntity == "&gt") {
- methodRef += '>';
- } else {
- methodRef += it->data;
- }
- }
-
- // replace :: with #, but only if it appears before left brace
- size_t lbrace = methodRef.find('(');
- size_t dblColon = methodRef.find("::");
- if (dblColon < lbrace) {
- methodRef = methodRef.substr(0, dblColon) + '#' + methodRef.substr(dblColon + 2);
- }
-
- translatedComment += "@see ";
- string linkObject = convertLink(methodRef);
- if (!linkObject.size()) {
- linkObject = methodRef;
- }
- translatedComment += linkObject;
-}
-
-/* This function moves all line endings at the end of child entities
- * out of the child entities to the parent.
- * For example, entity tree:
-
- -root
- |-param
- |-paramText
- |-endline
-
- should be turned to
-
- -root
- |-param
- |-paramText
- |-endline
- *
- */
-int JavaDocConverter::shiftEndlinesUpTree(DoxygenEntity &root, int level) {
- DoxygenEntityListIt it = root.entityList.begin();
- while (it != root.entityList.end()) {
- // remove line endings
- int ret = shiftEndlinesUpTree(*it, level + 1);
- // insert them after this element
- it++;
- for (int i = 0; i < ret; i++) {
- root.entityList.insert(it, DoxygenEntity("plainstd::endl"));
- }
- }
-
- // continue only if we are not root
- if (!level) {
- return 0;
- }
-
- int removedCount = 0;
- while (!root.entityList.empty()
- && root.entityList.rbegin()->typeOfEntity == "plainstd::endl") {
- root.entityList.pop_back();
- removedCount++;
- }
- return removedCount;
-}
-
-/**
- * This makes sure that all comment lines contain '*'. It is not mandatory in doxygen,
- * but highly recommended for Javadoc. '*' in empty lines are indented according
- * to indentation of the first line. Indentation of non-empty lines is not
- * changed - garbage in garbage out.
- */
-std::string JavaDocConverter::indentAndInsertAsterisks(const string &doc) {
-
- size_t idx = doc.find('\n');
- size_t indent = 0;
- bool singleLineComment = idx == string::npos;
- // Detect indentation.
- // The first line in comment is the one after '/**', which may be
- // spaces and '\n' or the text. In any case it is not suitable to detect
- // indentation, so we have to skip the first '\n'.
- // However, if there is just one line, then use that line to detect indentation.
- if (idx != string::npos) {
- size_t nonspaceIdx = doc.find_first_not_of(" \t", idx + 1);
- if (nonspaceIdx != string::npos) {
- indent = nonspaceIdx - idx;
- }
- }
-
- if (indent == 0) {
- // we can't indent the first line less than 0
- indent = 1;
- }
- // Create the first line of Javadoc comment.
- string indentStr(indent - 1, ' ');
- string translatedStr = indentStr + "/**";
- if (indent > 1) {
- // remove the first space, so that '*' will be aligned
- translatedStr = translatedStr.substr(1);
- }
-
- translatedStr += doc;
-
- // insert '*' before each comment line, if it does not have it
- idx = translatedStr.find('\n');
-
- while (idx != string::npos) {
-
- size_t nonspaceIdx = translatedStr.find_first_not_of(" \t", idx + 1);
- if (nonspaceIdx != string::npos && translatedStr[nonspaceIdx] != '*') {
- // line without '*' found - is it empty?
- if (translatedStr[nonspaceIdx] != '\n') {
- // add '* ' to each line without it
- translatedStr = translatedStr.substr(0, nonspaceIdx) + "* " + translatedStr.substr(nonspaceIdx);
- //printf(translatedStr.c_str());
- } else {
- // we found empty line, replace it with indented '*'
- translatedStr = translatedStr.substr(0, idx + 1) + indentStr + "* " + translatedStr.substr(nonspaceIdx);
- }
- }
- idx = translatedStr.find('\n', nonspaceIdx);
- }
-
- // Add the last comment line properly indented
- size_t nonspaceEndIdx = translatedStr.find_last_not_of(" \t");
- if (nonspaceEndIdx != string::npos) {
- if (translatedStr[nonspaceEndIdx] != '\n') {
- if (!singleLineComment)
- translatedStr += '\n';
- } else {
- // remove trailing spaces
- translatedStr = translatedStr.substr(0, nonspaceEndIdx + 1);
- }
- }
- translatedStr += indentStr + "*/\n";
-
- return translatedStr;
-}
-
-String *JavaDocConverter::makeDocumentation(Node *node) {
-
- String *documentation = getDoxygenComment(node);
-
- if (documentation == NULL) {
- return NewString("");
- }
-
- if (GetFlag(node, "feature:doxygen:notranslate")) {
-
- string doc = Char(documentation);
-
- string translatedStr = indentAndInsertAsterisks(doc);
-
- return NewString(translatedStr.c_str());
- }
-
- DoxygenEntityList entityList = parser.createTree(node, documentation);
-
- // entityList.sort(CompareDoxygenEntities()); sorting currently not used,
-
- if (m_flags & debug_translator) {
- std::cout << "---RESORTED LIST---" << std::endl;
- printTree(entityList);
- }
- // store the current node
- // (currently just to handle params)
- currentNode = node;
-
- std::string javaDocString = "/**\n * ";
-
- DoxygenEntity root("root", entityList);
-
- shiftEndlinesUpTree(root);
-
- // strip line endings at the beginning
- while (!root.entityList.empty()
- && root.entityList.begin()->typeOfEntity == "plainstd::endl") {
- root.entityList.pop_front();
- }
-
- // and at the end
- while (!root.entityList.empty()
- && root.entityList.rbegin()->typeOfEntity == "plainstd::endl") {
- root.entityList.pop_back();
- }
-
- javaDocString += translateSubtree(root);
-
- javaDocString += "\n */\n";
-
- if (m_flags & debug_translator) {
- std::cout << "\n---RESULT IN JAVADOC---" << std::endl;
- std::cout << javaDocString;
- }
-
- return NewString(javaDocString.c_str());
-}
-
-void JavaDocConverter::addError(int warningType, const std::string &message) {
- Swig_warning(warningType, "", 0, "Doxygen parser warning: %s. \n", message.c_str());
-}
diff --git a/contrib/tools/swig/Source/Doxygen/javadoc.h b/contrib/tools/swig/Source/Doxygen/javadoc.h
deleted file mode 100644
index d2c956c9db..0000000000
--- a/contrib/tools/swig/Source/Doxygen/javadoc.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * javadoc.h
- *
- * Module to return documentation for nodes formatted for JavaDoc
- * ----------------------------------------------------------------------------- */
-
-#ifndef SWIG_JAVADOC_H
-#define SWIG_JAVADOC_H
-
-#include "doxytranslator.h"
-#include <map>
-
-/*
- * A class to translate doxygen comments into JavaDoc style comments.
- */
-class JavaDocConverter : public DoxygenTranslator {
-public:
- JavaDocConverter(int flags = 0);
- String *makeDocumentation(Node *node);
-
-protected:
- /*
- * Used to properly format JavaDoc-style command
- */
- std::string formatCommand(std::string unformattedLine, int indent);
-
- /*
- * Translate every entity in a tree.
- */
- std::string translateSubtree(DoxygenEntity &doxygenEntity);
-
- /*
- * Translate one entity with the appropriate handler, according
- * to the tagHandlers
- */
- void translateEntity(DoxygenEntity &tag, std::string &translatedComment);
-
- /*
- * Fix all endlines location, etc
- */
- int shiftEndlinesUpTree(DoxygenEntity &root, int level = 0);
-
- /*
- * Convert params in link-objects and references
- */
- std::string convertLink(std::string linkObject);
-
- /*
- * Typedef for the function that handles one tag
- * arg - some string argument to easily pass it through lookup table
- */
- typedef void (JavaDocConverter::*tagHandler) (DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
-
- /**
- * Copies verbatim args of the tag to output, used for commands like \f$, ...
- */
- void handleTagVerbatim(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
-
- /** Creates anchor link. */
- void handleTagAnchor(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
-
- /*
- * Wrap the command data with the html tag
- * arg - html tag, with no braces
- */
- void handleTagHtml(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
-
- /* Handles HTML tags recognized by Doxygen, like <A ...>, <ul>, <table>, ... */
- void handleDoxyHtmlTag(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
-
- /* Handles HTML entities recognized by Doxygen, like &lt;, &copy;, ... */
- void handleHtmlEntity(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
-
- /*
- * Just prints new line
- */
- void handleNewLine(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
-
- /*
- * Print the name of tag to the output, used for escape-commands
- * arg - html-escaped variant, if not provided the command data is used
- */
- void handleTagChar(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
-
- /*
- * Do not translate and print as-is
- * arg - the new tag name, if it needs to be renamed
- */
- void handleTagSame(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
-
- /*
- * Print only the content and strip original tag
- */
- void handleParagraph(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
-
- /*
- * Print only data part of code
- */
- void handlePlainString(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
-
- /*
- * Print extended Javadoc command, like {@code ...} or {@literal ...}
- * arg - command name
- */
- void handleTagExtended(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
-
- /*
- * Print the if-elseif-else-endif section
- */
- void handleTagIf(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
-
- /*
- * Prints the specified message, than the contents of the tag
- * arg - message
- */
- void handleTagMessage(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
-
- /*
- * Insert <img src=... /> tag if the 'format' field is specified as 'html'
- */
- void handleTagImage(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
-
- /*
- * Insert <p alt='title'>...</p>
- */
- void handleTagPar(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
-
- /*
- * Insert \@param command, if it is really a function param
- */
- void handleTagParam(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
-
- /*
- * Writes link for \ref tag.
- */
- void handleTagRef(DoxygenEntity &tag, std::string &translatedComment, std::string &);
-
- /*
- * Insert {@link...} command, and handle all the <link-object>s correctly
- * (like converting types of params, etc)
- */
- void handleTagLink(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
-
- /*
- * Insert @see command, and handle all the <link-object>s correctly
- * (like converting types of params, etc)
- */
- void handleTagSee(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
-
-private:
- Node *currentNode;
- // this contains the handler pointer and one string argument
- static std::map<std::string, std::pair<tagHandler, std::string> > tagHandlers;
- void fillStaticTables();
-
- bool paramExists(std::string param);
- std::string indentAndInsertAsterisks(const std::string &doc);
-
- void addError(int warningType, const std::string &message);
-};
-
-#endif
diff --git a/contrib/tools/swig/Source/Doxygen/pydoc.cxx b/contrib/tools/swig/Source/Doxygen/pydoc.cxx
deleted file mode 100644
index 28f6051a72..0000000000
--- a/contrib/tools/swig/Source/Doxygen/pydoc.cxx
+++ /dev/null
@@ -1,993 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * pydoc.cxx
- *
- * Module to return documentation for nodes formatted for PyDoc
- * ----------------------------------------------------------------------------- */
-
-#include "pydoc.h"
-#include "doxyparser.h"
-#include <sstream>
-#include <string>
-#include <vector>
-#include <iostream>
-
-#include "swigmod.h"
-
-// define static tables, they are filled in PyDocConverter's constructor
-PyDocConverter::TagHandlersMap PyDocConverter::tagHandlers;
-std::map<std::string, std::string> PyDocConverter::sectionTitles;
-
-using std::string;
-
-// Helper class increasing the provided indent string in its ctor and decreasing
-// it in its dtor.
-class IndentGuard {
-public:
- // One indent level.
- static const char *Level() {
- return " ";
- }
- // Default ctor doesn't do anything and prevents the dtor from doing anything// too and should only be used when the guard needs to be initialized// conditionally as Init() can then be called after checking some condition.// Otherwise, prefer to use the non default ctor below.
- IndentGuard() {
- m_initialized = false;
- }
-
- // Ctor takes the output to determine the current indent and to remove the
- // extra indent added to it in the dtor and the variable containing the indent
- // to use, which must be used after every new line by the code actually
- // updating the output.
- IndentGuard(string &output, string &indent) {
- Init(output, indent);
- }
-
- // Really initializes the object created using the default ctor.
- void Init(string &output, string &indent) {
- m_output = &output;
- m_indent = &indent;
-
- const string::size_type lastNonSpace = m_output->find_last_not_of(' ');
- if (lastNonSpace == string::npos) {
- m_firstLineIndent = m_output->length();
- } else if ((*m_output)[lastNonSpace] == '\n') {
- m_firstLineIndent = m_output->length() - (lastNonSpace + 1);
- } else {
- m_firstLineIndent = 0;
- }
-
- // Notice that the indent doesn't include the first line indent because it's
- // implicit, i.e. it is present in the input and so is copied into the
- // output anyhow.
- *m_indent = Level();
-
- m_initialized = true;
- }
-
- // Get the indent for the first line of the paragraph, which is smaller than
- // the indent for the subsequent lines.
- string getFirstLineIndent() const {
- return string(m_firstLineIndent, ' ');
- }
-
- ~IndentGuard() {
- if (!m_initialized)
- return;
-
- m_indent->clear();
-
- // Get rid of possible remaining extra indent, e.g. if there were any trailing
- // new lines: we shouldn't add the extra indent level to whatever follows
- // this paragraph.
- static const size_t lenIndentLevel = strlen(Level());
- if (m_output->length() > lenIndentLevel) {
- const size_t start = m_output->length() - lenIndentLevel;
- if (m_output->compare(start, string::npos, Level()) == 0)
- m_output->erase(start);
- }
- }
-
-private:
- string *m_output;
- string *m_indent;
- string::size_type m_firstLineIndent;
- bool m_initialized;
-
- IndentGuard(const IndentGuard &);
- IndentGuard &operator=(const IndentGuard &);
-};
-
-// Return the indent of the given multiline string, i.e. the maximal number of
-// spaces present in the beginning of all its non-empty lines.
-static size_t determineIndent(const string &s) {
- size_t minIndent = static_cast<size_t>(-1);
-
- for (size_t lineStart = 0; lineStart < s.length();) {
- const size_t lineEnd = s.find('\n', lineStart);
- const size_t firstNonSpace = s.find_first_not_of(' ', lineStart);
-
- // If inequality doesn't hold, it means that this line contains only spaces
- // (notice that this works whether lineEnd is valid or string::npos), in
- // which case it doesn't matter when determining the indent.
- if (firstNonSpace < lineEnd) {
- // Here we can be sure firstNonSpace != string::npos.
- const size_t lineIndent = firstNonSpace - lineStart;
- if (lineIndent < minIndent)
- minIndent = lineIndent;
- }
-
- if (lineEnd == string::npos)
- break;
-
- lineStart = lineEnd + 1;
- }
-
- return minIndent;
-}
-
-static void trimWhitespace(string &s) {
- const string::size_type lastNonSpace = s.find_last_not_of(' ');
- if (lastNonSpace == string::npos)
- s.clear();
- else
- s.erase(lastNonSpace + 1);
-}
-
-// Erase the first character in the string if it is a newline
-static void eraseLeadingNewLine(string &s) {
- if (!s.empty() && s[0] == '\n')
- s.erase(s.begin());
-}
-
-// Erase the last character in the string if it is a newline
-static void eraseTrailingNewLine(string &s) {
- if (!s.empty() && s[s.size() - 1] == '\n')
- s.erase(s.size() - 1);
-}
-
-// Check the generated docstring line by line and make sure that any
-// code and verbatim blocks have an empty line preceding them, which
-// is necessary for Sphinx. Additionally, this strips any empty lines
-// appearing at the beginning of the docstring.
-static string padCodeAndVerbatimBlocks(const string &docString) {
- std::string result;
-
- std::istringstream iss(docString);
-
- // Initialize to false because there is no previous line yet
- bool lastLineWasNonBlank = false;
-
- for (string line; std::getline(iss, line); result += line) {
- if (!result.empty()) {
- // Terminate the previous line
- result += '\n';
- }
-
- const size_t pos = line.find_first_not_of(" \t");
- if (pos == string::npos) {
- lastLineWasNonBlank = false;
- } else {
- if (lastLineWasNonBlank &&
- (line.compare(pos, 13, ".. code-block") == 0 ||
- line.compare(pos, 7, ".. math") == 0 ||
- line.compare(pos, 3, ">>>") == 0)) {
- // Must separate code or math blocks from the previous line
- result += '\n';
- }
- lastLineWasNonBlank = true;
- }
- }
- return result;
-}
-
-// Helper function to extract the option value from a command,
-// e.g. param[in] -> in
-static std::string getCommandOption(const std::string &command, char openChar, char closeChar) {
- string option;
-
- size_t opt_begin, opt_end;
- opt_begin = command.find(openChar);
- opt_end = command.find(closeChar);
- if (opt_begin != string::npos && opt_end != string::npos)
- option = command.substr(opt_begin+1, opt_end-opt_begin-1);
-
- return option;
-}
-
-
-/* static */
-PyDocConverter::TagHandlersMap::mapped_type PyDocConverter::make_handler(tagHandler handler) {
- return make_pair(handler, std::string());
-}
-
-/* static */
-PyDocConverter::TagHandlersMap::mapped_type PyDocConverter::make_handler(tagHandler handler, const char *arg) {
- return make_pair(handler, arg);
-}
-
-void PyDocConverter::fillStaticTables() {
- if (tagHandlers.size()) // fill only once
- return;
-
- // table of section titles, they are printed only once
- // for each group of specified doxygen commands
- sectionTitles["author"] = "Author: ";
- sectionTitles["authors"] = "Authors: ";
- sectionTitles["copyright"] = "Copyright: ";
- sectionTitles["deprecated"] = "Deprecated: ";
- sectionTitles["example"] = "Example: ";
- sectionTitles["note"] = "Notes: ";
- sectionTitles["remark"] = "Remarks: ";
- sectionTitles["remarks"] = "Remarks: ";
- sectionTitles["warning"] = "Warning: ";
-// sectionTitles["sa"] = "See also: ";
-// sectionTitles["see"] = "See also: ";
- sectionTitles["since"] = "Since: ";
- sectionTitles["todo"] = "TODO: ";
- sectionTitles["version"] = "Version: ";
-
- tagHandlers["a"] = make_handler(&PyDocConverter::handleTagWrap, "*");
- tagHandlers["b"] = make_handler(&PyDocConverter::handleTagWrap, "**");
- // \c command is translated as single quotes around next word
- tagHandlers["c"] = make_handler(&PyDocConverter::handleTagWrap, "``");
- tagHandlers["cite"] = make_handler(&PyDocConverter::handleTagWrap, "'");
- tagHandlers["e"] = make_handler(&PyDocConverter::handleTagWrap, "*");
- // these commands insert just a single char, some of them need to be escaped
- tagHandlers["$"] = make_handler(&PyDocConverter::handleTagChar);
- tagHandlers["@"] = make_handler(&PyDocConverter::handleTagChar);
- tagHandlers["\\"] = make_handler(&PyDocConverter::handleTagChar);
- tagHandlers["<"] = make_handler(&PyDocConverter::handleTagChar);
- tagHandlers[">"] = make_handler(&PyDocConverter::handleTagChar);
- tagHandlers["&"] = make_handler(&PyDocConverter::handleTagChar);
- tagHandlers["#"] = make_handler(&PyDocConverter::handleTagChar);
- tagHandlers["%"] = make_handler(&PyDocConverter::handleTagChar);
- tagHandlers["~"] = make_handler(&PyDocConverter::handleTagChar);
- tagHandlers["\""] = make_handler(&PyDocConverter::handleTagChar);
- tagHandlers["."] = make_handler(&PyDocConverter::handleTagChar);
- tagHandlers["::"] = make_handler(&PyDocConverter::handleTagChar);
- // these commands are stripped out, and only their content is printed
- tagHandlers["attention"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["author"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["authors"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["brief"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["bug"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["code"] = make_handler(&PyDocConverter::handleCode);
- tagHandlers["copyright"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["date"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["deprecated"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["details"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["em"] = make_handler(&PyDocConverter::handleTagWrap, "*");
- tagHandlers["example"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["exception"] = tagHandlers["throw"] = tagHandlers["throws"] = make_handler(&PyDocConverter::handleTagException);
- tagHandlers["htmlonly"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["invariant"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["latexonly"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["link"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["manonly"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["note"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["p"] = make_handler(&PyDocConverter::handleTagWrap, "``");
- tagHandlers["partofdescription"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["rtfonly"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["remark"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["remarks"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["sa"] = make_handler(&PyDocConverter::handleTagMessage, "See also: ");
- tagHandlers["see"] = make_handler(&PyDocConverter::handleTagMessage, "See also: ");
- tagHandlers["since"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["short"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["todo"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["version"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["verbatim"] = make_handler(&PyDocConverter::handleVerbatimBlock);
- tagHandlers["warning"] = make_handler(&PyDocConverter::handleParagraph);
- tagHandlers["xmlonly"] = make_handler(&PyDocConverter::handleParagraph);
- // these commands have special handlers
- tagHandlers["arg"] = make_handler(&PyDocConverter::handleTagMessage, "* ");
- tagHandlers["cond"] = make_handler(&PyDocConverter::handleTagMessage, "Conditional comment: ");
- tagHandlers["else"] = make_handler(&PyDocConverter::handleTagIf, "Else: ");
- tagHandlers["elseif"] = make_handler(&PyDocConverter::handleTagIf, "Else if: ");
- tagHandlers["endcond"] = make_handler(&PyDocConverter::handleTagMessage, "End of conditional comment.");
- tagHandlers["if"] = make_handler(&PyDocConverter::handleTagIf, "If: ");
- tagHandlers["ifnot"] = make_handler(&PyDocConverter::handleTagIf, "If not: ");
- tagHandlers["image"] = make_handler(&PyDocConverter::handleTagImage);
- tagHandlers["li"] = make_handler(&PyDocConverter::handleTagMessage, "* ");
- tagHandlers["overload"] = make_handler(&PyDocConverter::handleTagMessage,
- "This is an overloaded member function, provided for"
- " convenience.\nIt differs from the above function only in what" " argument(s) it accepts.");
- tagHandlers["par"] = make_handler(&PyDocConverter::handleTagPar);
- tagHandlers["param"] = tagHandlers["tparam"] = make_handler(&PyDocConverter::handleTagParam);
- tagHandlers["ref"] = make_handler(&PyDocConverter::handleTagRef);
- tagHandlers["result"] = tagHandlers["return"] = tagHandlers["returns"] = make_handler(&PyDocConverter::handleTagReturn);
-
- // this command just prints its contents
- // (it is internal command of swig's parser, contains plain text)
- tagHandlers["plainstd::string"] = make_handler(&PyDocConverter::handlePlainString);
- tagHandlers["plainstd::endl"] = make_handler(&PyDocConverter::handleNewLine);
- tagHandlers["n"] = make_handler(&PyDocConverter::handleNewLine);
-
- // \f commands output literal Latex formula, which is still better than nothing.
- tagHandlers["f$"] = tagHandlers["f["] = tagHandlers["f{"] = make_handler(&PyDocConverter::handleMath);
-
- // HTML tags
- tagHandlers["<a"] = make_handler(&PyDocConverter::handleDoxyHtmlTag_A);
- tagHandlers["<b"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "**");
- tagHandlers["<blockquote"] = make_handler(&PyDocConverter::handleDoxyHtmlTag_A, "Quote: ");
- tagHandlers["<body"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
- tagHandlers["<br"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "\n");
-
- // there is no formatting for this tag as it was deprecated in HTML 4.01 and
- // not used in HTML 5
- tagHandlers["<center"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
- tagHandlers["<caption"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
- tagHandlers["<code"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "``");
-
- tagHandlers["<dl"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
- tagHandlers["<dd"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, " ");
- tagHandlers["<dt"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
-
- tagHandlers["<dfn"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
- tagHandlers["<div"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
- tagHandlers["<em"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "**");
- tagHandlers["<form"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
- tagHandlers["<hr"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "--------------------------------------------------------------------\n");
- tagHandlers["<h1"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "# ");
- tagHandlers["<h2"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "## ");
- tagHandlers["<h3"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "### ");
- tagHandlers["<i"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "*");
- tagHandlers["<input"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
- tagHandlers["<img"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "Image:");
- tagHandlers["<li"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "* ");
- tagHandlers["<meta"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
- tagHandlers["<multicol"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
- tagHandlers["<ol"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
- tagHandlers["<p"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "\n");
- tagHandlers["<pre"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
- tagHandlers["<small"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
- tagHandlers["<span"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "'");
- tagHandlers["<strong"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "**");
-
- // make a space between text and super/sub script.
- tagHandlers["<sub"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, " ");
- tagHandlers["<sup"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, " ");
-
- tagHandlers["<table"] = make_handler(&PyDocConverter::handleDoxyHtmlTagNoParam);
- tagHandlers["<td"] = make_handler(&PyDocConverter::handleDoxyHtmlTag_td);
- tagHandlers["<th"] = make_handler(&PyDocConverter::handleDoxyHtmlTag_th);
- tagHandlers["<tr"] = make_handler(&PyDocConverter::handleDoxyHtmlTag_tr);
- tagHandlers["<tt"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
- tagHandlers["<kbd"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
- tagHandlers["<ul"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
- tagHandlers["<var"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "*");
-
- // HTML entities
- tagHandlers["&copy"] = make_handler(&PyDocConverter::handleHtmlEntity, "(C)");
- tagHandlers["&trade"] = make_handler(&PyDocConverter::handleHtmlEntity, " TM");
- tagHandlers["&reg"] = make_handler(&PyDocConverter::handleHtmlEntity, "(R)");
- tagHandlers["&lt"] = make_handler(&PyDocConverter::handleHtmlEntity, "<");
- tagHandlers["&gt"] = make_handler(&PyDocConverter::handleHtmlEntity, ">");
- tagHandlers["&amp"] = make_handler(&PyDocConverter::handleHtmlEntity, "&");
- tagHandlers["&apos"] = make_handler(&PyDocConverter::handleHtmlEntity, "'");
- tagHandlers["&quot"] = make_handler(&PyDocConverter::handleHtmlEntity, "\"");
- tagHandlers["&lsquo"] = make_handler(&PyDocConverter::handleHtmlEntity, "`");
- tagHandlers["&rsquo"] = make_handler(&PyDocConverter::handleHtmlEntity, "'");
- tagHandlers["&ldquo"] = make_handler(&PyDocConverter::handleHtmlEntity, "\"");
- tagHandlers["&rdquo"] = make_handler(&PyDocConverter::handleHtmlEntity, "\"");
- tagHandlers["&ndash"] = make_handler(&PyDocConverter::handleHtmlEntity, "-");
- tagHandlers["&mdash"] = make_handler(&PyDocConverter::handleHtmlEntity, "--");
- tagHandlers["&nbsp"] = make_handler(&PyDocConverter::handleHtmlEntity, " ");
- tagHandlers["&times"] = make_handler(&PyDocConverter::handleHtmlEntity, "x");
- tagHandlers["&minus"] = make_handler(&PyDocConverter::handleHtmlEntity, "-");
- tagHandlers["&sdot"] = make_handler(&PyDocConverter::handleHtmlEntity, ".");
- tagHandlers["&sim"] = make_handler(&PyDocConverter::handleHtmlEntity, "~");
- tagHandlers["&le"] = make_handler(&PyDocConverter::handleHtmlEntity, "<=");
- tagHandlers["&ge"] = make_handler(&PyDocConverter::handleHtmlEntity, ">=");
- tagHandlers["&larr"] = make_handler(&PyDocConverter::handleHtmlEntity, "<--");
- tagHandlers["&rarr"] = make_handler(&PyDocConverter::handleHtmlEntity, "-->");
-}
-
-PyDocConverter::PyDocConverter(int flags):
-DoxygenTranslator(flags), m_tableLineLen(0), m_prevRowIsTH(false) {
- fillStaticTables();
-}
-
-// Return the type as it should appear in the output documentation.
-static std::string getPyDocType(Node *n, const_String_or_char_ptr lname = "") {
- std::string type;
-
- String *s = Swig_typemap_lookup("doctype", n, lname, 0);
- if (!s) {
- if (String *t = Getattr(n, "type"))
- s = SwigType_str(t, "");
- }
-
- if (!s)
- return type;
-
- if (Language::classLookup(s)) {
- // In Python C++ namespaces are flattened, so remove all but last component
- // of the name.
- String *const last = Swig_scopename_last(s);
-
- // We are not actually sure whether it's a documented class or not, but
- // there doesn't seem to be any harm in making it a reference if it isn't,
- // while there is a lot of benefit in having a hyperlink if it is.
- type = ":py:class:`";
- type += Char(last);
- type += "`";
-
- Delete(last);
- } else {
- type = Char(s);
- }
-
- Delete(s);
-
- return type;
-}
-
-std::string PyDocConverter::getParamType(std::string param) {
- std::string type;
-
- ParmList *plist = CopyParmList(Getattr(currentNode, "parms"));
- for (Parm *p = plist; p; p = nextSibling(p)) {
- String *pname = Getattr(p, "name");
- if (pname && Char(pname) == param) {
- type = getPyDocType(p, pname);
- break;
- }
- }
- Delete(plist);
- return type;
-}
-
-std::string PyDocConverter::getParamValue(std::string param) {
- std::string value;
-
- ParmList *plist = CopyParmList(Getattr(currentNode, "parms"));
- for (Parm *p = plist; p; p = nextSibling(p)) {
- String *pname = Getattr(p, "name");
- if (pname && Char(pname) == param) {
- String *pval = Getattr(p, "value");
- if (pval)
- value = Char(pval);
- break;
- }
- }
- Delete(plist);
- return value;
-}
-
-std::string PyDocConverter::translateSubtree(DoxygenEntity &doxygenEntity) {
- std::string translatedComment;
-
- if (doxygenEntity.isLeaf)
- return translatedComment;
-
- std::string currentSection;
- std::list<DoxygenEntity>::iterator p = doxygenEntity.entityList.begin();
- while (p != doxygenEntity.entityList.end()) {
- std::map<std::string, std::string>::iterator it;
- it = sectionTitles.find(p->typeOfEntity);
- if (it != sectionTitles.end()) {
- if (it->second != currentSection) {
- currentSection = it->second;
- translatedComment += currentSection;
- }
- }
- translateEntity(*p, translatedComment);
- translateSubtree(*p);
- p++;
- }
-
- return translatedComment;
-}
-
-void PyDocConverter::translateEntity(DoxygenEntity &doxyEntity, std::string &translatedComment) {
- // check if we have needed handler and call it
- std::map<std::string, std::pair<tagHandler, std::string> >::iterator it;
- it = tagHandlers.find(getBaseCommand(doxyEntity.typeOfEntity));
- if (it != tagHandlers.end())
- (this->*(it->second.first)) (doxyEntity, translatedComment, it->second.second);
-}
-
-void PyDocConverter::handleParagraph(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
- translatedComment += translateSubtree(tag);
-}
-
-void PyDocConverter::handleVerbatimBlock(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
- string verb = translateSubtree(tag);
-
- eraseLeadingNewLine(verb);
-
- // Remove the last newline to prevent doubling the newline already present after \endverbatim
- trimWhitespace(verb); // Needed to catch trailing newline below
- eraseTrailingNewLine(verb);
- translatedComment += verb;
-}
-
-void PyDocConverter::handleMath(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
- IndentGuard indent;
-
- // Only \f$ is translated to inline formulae, \f[ and \f{ are for the block ones.
- const bool inlineFormula = tag.typeOfEntity == "f$";
-
- string formulaNL;
-
- if (inlineFormula) {
- translatedComment += ":math:`";
- } else {
- indent.Init(translatedComment, m_indent);
-
- trimWhitespace(translatedComment);
-
- const string formulaIndent = indent.getFirstLineIndent();
- translatedComment += formulaIndent;
- translatedComment += ".. math::\n";
-
- formulaNL = '\n';
- formulaNL += formulaIndent;
- formulaNL += m_indent;
- translatedComment += formulaNL;
- }
-
- std::string formula;
- handleTagVerbatim(tag, formula, arg);
-
- // It is important to ensure that we have no spaces around the inline math
- // contents, so strip them.
- const size_t start = formula.find_first_not_of(" \t\n");
- const size_t end = formula.find_last_not_of(" \t\n");
- if (start != std::string::npos) {
- for (size_t n = start; n <= end; n++) {
- if (formula[n] == '\n') {
- // New lines must be suppressed in inline maths and indented in the block ones.
- if (!inlineFormula)
- translatedComment += formulaNL;
- } else {
- // Just copy everything else.
- translatedComment += formula[n];
- }
- }
- }
-
- if (inlineFormula) {
- translatedComment += "`";
- }
-}
-
-void PyDocConverter::handleCode(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
- IndentGuard indent(translatedComment, m_indent);
-
- trimWhitespace(translatedComment);
-
- // Check for an option given to the code command (e.g. code{.py}),
- // and try to set the code-block language accordingly.
- string option = getCommandOption(tag.typeOfEntity, '{', '}');
- // Set up the language option to the code-block command, which can
- // be any language supported by pygments:
- string codeLanguage;
- if (option == ".py")
- // Other possibilities here are "default" or "python3". In Sphinx
- // 2.1.2, basic syntax doesn't render quite the same in these as
- // with "python", which for basic keywords seems to provide
- // slightly richer formatting. Another option would be to leave
- // the language empty, but testing with Sphinx 1.8.5 has produced
- // an error "1 argument required".
- codeLanguage = "python";
- else if (option == ".java")
- codeLanguage = "java";
- else if (option == ".c")
- codeLanguage = "c";
- else
- // If there is not a match, or if no option was given, go out on a
- // limb and assume that the examples in the C or C++ sources use
- // C++.
- codeLanguage = "c++";
-
- std::string code;
- handleTagVerbatim(tag, code, arg);
-
- // Try and remove leading newline, which is present for block \code
- // command:
- eraseLeadingNewLine(code);
-
- // Check for python doctest blocks, and treat them specially:
- bool isDocTestBlock = false;
- size_t startPos;
- // ">>>" would normally appear at the beginning, but doxygen comment
- // style may have space in front, so skip leading whitespace
- if ((startPos=code.find_first_not_of(" \t")) != string::npos && code.substr(startPos,3) == ">>>")
- isDocTestBlock = true;
-
- string codeIndent;
- if (! isDocTestBlock) {
- // Use the current indent for the code-block line itself.
- translatedComment += indent.getFirstLineIndent();
- translatedComment += ".. code-block:: " + codeLanguage + "\n\n";
-
- // Specify the level of extra indentation that will be used for
- // subsequent lines within the code block. Note that the correct
- // "starting indentation" is already present in the input, so we
- // only need to add the desired code block indentation.
- codeIndent = m_indent;
- }
-
- translatedComment += codeIndent;
- for (size_t n = 0; n < code.length(); n++) {
- if (code[n] == '\n') {
- // Don't leave trailing white space, this results in PEP8 validation
- // errors in Python code (which are performed by our own unit tests).
- trimWhitespace(translatedComment);
- translatedComment += '\n';
-
- // Ensure that we indent all the lines by the code indent.
- translatedComment += codeIndent;
- } else {
- // Just copy everything else.
- translatedComment += code[n];
- }
- }
-
- trimWhitespace(translatedComment);
-
- // For block commands, the translator adds the newline after
- // \endcode, so try and compensate by removing the last newline from
- // the code text:
- eraseTrailingNewLine(translatedComment);
-}
-
-void PyDocConverter::handlePlainString(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
- translatedComment += tag.data;
-}
-
-void PyDocConverter::handleTagVerbatim(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
- translatedComment += arg;
- for (DoxygenEntityListCIt it = tag.entityList.begin(); it != tag.entityList.end(); it++) {
- translatedComment += it->data;
- }
-}
-
-void PyDocConverter::handleTagMessage(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
- translatedComment += arg;
- handleParagraph(tag, translatedComment);
-}
-
-void PyDocConverter::handleTagChar(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
- translatedComment += tag.typeOfEntity;
-}
-
-void PyDocConverter::handleTagIf(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
- translatedComment += arg;
- if (tag.entityList.size()) {
- translatedComment += tag.entityList.begin()->data;
- tag.entityList.pop_front();
- translatedComment += " {" + translateSubtree(tag) + "}";
- }
-}
-
-void PyDocConverter::handleTagPar(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
- translatedComment += "Title: ";
- if (tag.entityList.size())
- translatedComment += tag.entityList.begin()->data;
- tag.entityList.pop_front();
- handleParagraph(tag, translatedComment);
-}
-
-void PyDocConverter::handleTagImage(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
- if (tag.entityList.size() < 2)
- return;
- tag.entityList.pop_front();
- translatedComment += "Image: ";
- translatedComment += tag.entityList.begin()->data;
- tag.entityList.pop_front();
- if (tag.entityList.size())
- translatedComment += "(" + tag.entityList.begin()->data + ")";
-}
-
-void PyDocConverter::handleTagParam(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
- if (tag.entityList.size() < 2)
- return;
-
- IndentGuard indent(translatedComment, m_indent);
-
- DoxygenEntity paramNameEntity = *tag.entityList.begin();
- tag.entityList.pop_front();
-
- const std::string &paramName = paramNameEntity.data;
-
- const std::string paramType = getParamType(paramName);
- const std::string paramValue = getParamValue(paramName);
-
- // Get command option, e.g. "in", "out", or "in,out"
- string commandOpt = getCommandOption(tag.typeOfEntity, '[', ']');
- if (commandOpt == "in,out") commandOpt = "in/out";
-
- // If provided, append the parameter direction to the type
- // information via a suffix:
- std::string suffix;
- if (commandOpt.size() > 0)
- suffix = ", " + commandOpt;
-
- // If the parameter has a default value, flag it as optional in the
- // generated type definition. Particularly helpful when the python
- // call is generated with *args, **kwargs.
- if (paramValue.size() > 0)
- suffix += ", optional";
-
- if (!paramType.empty()) {
- translatedComment += ":type " + paramName + ": " + paramType + suffix + "\n";
- translatedComment += indent.getFirstLineIndent();
- }
-
- translatedComment += ":param " + paramName + ":";
-
- handleParagraph(tag, translatedComment);
-}
-
-
-void PyDocConverter::handleTagReturn(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
- IndentGuard indent(translatedComment, m_indent);
-
- const std::string pytype = getPyDocType(currentNode);
- if (!pytype.empty()) {
- translatedComment += ":rtype: ";
- translatedComment += pytype;
- translatedComment += "\n";
- translatedComment += indent.getFirstLineIndent();
- }
-
- translatedComment += ":return: ";
- handleParagraph(tag, translatedComment);
-}
-
-
-void PyDocConverter::handleTagException(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
- IndentGuard indent(translatedComment, m_indent);
-
- translatedComment += ":raises: ";
- handleParagraph(tag, translatedComment);
-}
-
-
-void PyDocConverter::handleTagRef(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
- if (!tag.entityList.size())
- return;
-
- string anchor = tag.entityList.begin()->data;
- tag.entityList.pop_front();
- string anchorText = anchor;
- if (!tag.entityList.empty()) {
- anchorText = tag.entityList.begin()->data;
- }
- translatedComment += "'" + anchorText + "'";
-}
-
-
-void PyDocConverter::handleTagWrap(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
- if (tag.entityList.size()) { // do not include empty tags
- std::string tagData = translateSubtree(tag);
- // wrap the thing, ignoring whitespace
- size_t wsPos = tagData.find_last_not_of("\n\t ");
- if (wsPos != std::string::npos && wsPos != tagData.size() - 1)
- translatedComment += arg + tagData.substr(0, wsPos + 1) + arg + tagData.substr(wsPos + 1);
- else
- translatedComment += arg + tagData + arg;
- }
-}
-
-void PyDocConverter::handleDoxyHtmlTag(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
- std::string htmlTagArgs = tag.data;
- if (htmlTagArgs == "/") {
- // end html tag, for example "</ul>
- // translatedComment += "</" + arg.substr(1) + ">";
- } else {
- translatedComment += arg + htmlTagArgs;
- }
-}
-
-void PyDocConverter::handleDoxyHtmlTagNoParam(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
- std::string htmlTagArgs = tag.data;
- if (htmlTagArgs == "/") {
- // end html tag, for example "</ul>
- } else {
- translatedComment += arg;
- }
-}
-
-void PyDocConverter::handleDoxyHtmlTag_A(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
- std::string htmlTagArgs = tag.data;
- if (htmlTagArgs == "/") {
- // end html tag, "</a>
- translatedComment += " (" + m_url + ')';
- m_url.clear();
- } else {
- m_url.clear();
- size_t pos = htmlTagArgs.find('=');
- if (pos != string::npos) {
- m_url = htmlTagArgs.substr(pos + 1);
- }
- translatedComment += arg;
- }
-}
-
-void PyDocConverter::handleDoxyHtmlTag2(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
- std::string htmlTagArgs = tag.data;
- if (htmlTagArgs == "/") {
- // end html tag, for example "</em>
- translatedComment += arg;
- } else {
- translatedComment += arg;
- }
-}
-
-void PyDocConverter::handleDoxyHtmlTag_tr(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
- std::string htmlTagArgs = tag.data;
- size_t nlPos = translatedComment.rfind('\n');
- if (htmlTagArgs == "/") {
- // end tag, </tr> appends vertical table line '|'
- translatedComment += '|';
- if (nlPos != string::npos) {
- size_t startOfTableLinePos = translatedComment.find_first_not_of(" \t", nlPos + 1);
- if (startOfTableLinePos != string::npos) {
- m_tableLineLen = translatedComment.size() - startOfTableLinePos;
- }
- }
- } else {
- if (m_prevRowIsTH) {
- // if previous row contained <th> tag, add horizontal separator
- // but first get leading spaces, because they'll be needed for the next row
- size_t numLeadingSpaces = translatedComment.size() - nlPos - 1;
-
- translatedComment += string(m_tableLineLen, '-') + '\n';
-
- if (nlPos != string::npos) {
- translatedComment += string(numLeadingSpaces, ' ');
- }
- m_prevRowIsTH = false;
- }
- }
-}
-
-void PyDocConverter::handleDoxyHtmlTag_th(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
- std::string htmlTagArgs = tag.data;
- if (htmlTagArgs == "/") {
- // end tag, </th> is ignored
- } else {
- translatedComment += '|';
- m_prevRowIsTH = true;
- }
-}
-
-void PyDocConverter::handleDoxyHtmlTag_td(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
- std::string htmlTagArgs = tag.data;
- if (htmlTagArgs == "/") {
- // end tag, </td> is ignored
- } else {
- translatedComment += '|';
- }
-}
-
-void PyDocConverter::handleHtmlEntity(DoxygenEntity &, std::string &translatedComment, const std::string &arg) {
- // html entities
- translatedComment += arg;
-}
-
-void PyDocConverter::handleNewLine(DoxygenEntity &, std::string &translatedComment, const std::string &) {
- trimWhitespace(translatedComment);
-
- translatedComment += "\n";
- if (!m_indent.empty())
- translatedComment += m_indent;
-}
-
-String *PyDocConverter::makeDocumentation(Node *n) {
- String *documentation;
- std::string pyDocString;
-
- // store the node, we may need it later
- currentNode = n;
-
- // for overloaded functions we must concat documentation for underlying overloads
- if (Getattr(n, "sym:overloaded")) {
- // rewind to the first overload
- while (Getattr(n, "sym:previousSibling"))
- n = Getattr(n, "sym:previousSibling");
-
- std::vector<std::string> allDocumentation;
-
- // minimal indent of any documentation comments, not initialized yet
- size_t minIndent = static_cast<size_t>(-1);
-
- // for each real method (not a generated overload) append the documentation
- string oneDoc;
- while (n) {
- documentation = getDoxygenComment(n);
- if (!Swig_is_generated_overload(n) && documentation) {
- currentNode = n;
- if (GetFlag(n, "feature:doxygen:notranslate")) {
- String *comment = NewString("");
- Append(comment, documentation);
- Replaceall(comment, "\n *", "\n");
- oneDoc = Char(comment);
- Delete(comment);
- } else {
- std::list<DoxygenEntity> entityList = parser.createTree(n, documentation);
- DoxygenEntity root("root", entityList);
-
- oneDoc = translateSubtree(root);
- }
-
- // find the minimal indent of this documentation comment, we need to
- // ensure that the entire comment is indented by it to avoid the leading
- // parts of the other lines being simply discarded later
- const size_t oneIndent = determineIndent(oneDoc);
- if (oneIndent < minIndent)
- minIndent = oneIndent;
-
- allDocumentation.push_back(oneDoc);
- }
- n = Getattr(n, "sym:nextSibling");
- }
-
- // construct final documentation string
- if (allDocumentation.size() > 1) {
- string indentStr;
- if (minIndent != static_cast<size_t>(-1))
- indentStr.assign(minIndent, ' ');
-
- std::ostringstream concatDocString;
- for (size_t realOverloadCount = 0; realOverloadCount < allDocumentation.size(); realOverloadCount++) {
- if (realOverloadCount != 0) {
- // separate it from the preceding one.
- concatDocString << "\n" << indentStr << "|\n\n";
- }
-
- oneDoc = allDocumentation[realOverloadCount];
- trimWhitespace(oneDoc);
- concatDocString << indentStr << "*Overload " << (realOverloadCount + 1) << ":*\n" << oneDoc;
- }
- pyDocString = concatDocString.str();
- } else if (allDocumentation.size() == 1) {
- pyDocString = *(allDocumentation.begin());
- }
- }
- // for other nodes just process as normal
- else {
- documentation = getDoxygenComment(n);
- if (documentation != NULL) {
- if (GetFlag(n, "feature:doxygen:notranslate")) {
- String *comment = NewString("");
- Append(comment, documentation);
- Replaceall(comment, "\n *", "\n");
- pyDocString = Char(comment);
- Delete(comment);
- } else {
- std::list<DoxygenEntity> entityList = parser.createTree(n, documentation);
- DoxygenEntity root("root", entityList);
- pyDocString = translateSubtree(root);
- }
- }
- }
-
- // if we got something log the result
- if (!pyDocString.empty()) {
-
- // remove the last '\n' since additional one is added during writing to file
- eraseTrailingNewLine(pyDocString);
-
- // ensure that a blank line occurs before code or math blocks
- pyDocString = padCodeAndVerbatimBlocks(pyDocString);
-
- if (m_flags & debug_translator) {
- std::cout << "\n---RESULT IN PYDOC---" << std::endl;
- std::cout << pyDocString;
- std::cout << std::endl;
- }
- }
-
- return NewString(pyDocString.c_str());
-}
-
diff --git a/contrib/tools/swig/Source/Doxygen/pydoc.h b/contrib/tools/swig/Source/Doxygen/pydoc.h
deleted file mode 100644
index 880ee3069c..0000000000
--- a/contrib/tools/swig/Source/Doxygen/pydoc.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * pydoc.h
- *
- * Module to return documentation for nodes formatted for PyDoc
- * ----------------------------------------------------------------------------- */
-
-#ifndef SWIG_PYDOC_H
-#define SWIG_PYDOC_H
-
-#include <list>
-#include <string>
-#include "swig.h"
-#include "doxyentity.h"
-#include "doxytranslator.h"
-
-#define DOC_STRING_LENGTH 64 // characters per line allowed
-#define DOC_PARAM_STRING_LENGTH 30 // characters reserved for param name / type
-
-class PyDocConverter : public DoxygenTranslator {
-public:
- PyDocConverter(int flags = 0);
- String *makeDocumentation(Node *node);
-
-protected:
-
- size_t m_tableLineLen;
- bool m_prevRowIsTH;
- std::string m_url;
-
- /*
- * Translate every entity in a tree, also manages sections
- * display. Prints title for every group of tags that have
- * a section title associated with them
- */
- std::string translateSubtree(DoxygenEntity &doxygenEntity);
-
- /*
- * Translate one entity with the appropriate handler, according
- * to the tagHandlers
- */
- void translateEntity(DoxygenEntity &doxyEntity, std::string &translatedComment);
-
- /*
- * Typedef for the function that handles one tag
- * arg - some string argument to easily pass it through lookup table
- */
- typedef void (PyDocConverter::*tagHandler) (DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /*
- * Wrap the command data with the some string
- * arg - string to wrap with, like '_' or '*'
- */
- void handleTagWrap(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /*
- * Just prints new line
- */
- void handleNewLine(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /*
- * Print the name of tag to the output, used for escape-commands
- */
- void handleTagChar(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /*
- * Format the contents of the \exception tag or its synonyms.
- */
- void handleTagException(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /*
- * Print only the content and strip original tag
- */
- void handleParagraph(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg = std::string());
-
- /*
- * Handle Doxygen verbatim tag
- */
- void handleVerbatimBlock(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg = std::string());
-
- /*
- * Handle one of the Doxygen formula-related tags.
- */
- void handleMath(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /*
- * Handle a code snippet.
- */
- void handleCode(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /*
- * Print only data part of code
- */
- void handlePlainString(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /**
- * Copies verbatim args of the tag to output, used for commands like \f$, ...
- */
- void handleTagVerbatim(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /*
- * Print the if-elseif-else-endif section
- */
- void handleTagIf(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /*
- * Prints the specified message, than the contents of the tag
- * arg - message
- */
- void handleTagMessage(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /*
- * Insert 'Title: ...'
- */
- void handleTagPar(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /*
- * Insert 'Image: ...'
- */
- void handleTagImage(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /*
- * Format nice param description with type information
- */
- void handleTagParam(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /*
- * Format the contents of the \return tag or its synonyms.
- */
- void handleTagReturn(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /*
- * Writes text for \ref tag.
- */
- void handleTagRef(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /* Handles HTML tags recognized by Doxygen, like <A ...>, <ul>, <table>, ... */
-
- void handleDoxyHtmlTag(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /** Does not output params of HTML tag, for example in <table border='1'>
- * 'border=1' is not written to output.
- */
- void handleDoxyHtmlTagNoParam(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /** Translates tag <a href = "url">text</a> to: text ("url"). */
- void handleDoxyHtmlTag_A(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /*
- * Handles HTML tags, which are translated to markdown-like syntax, for example
- * <i>text</i> --> _text_. Appends arg for start HTML tag and end HTML tag.
- */
- void handleDoxyHtmlTag2(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /* Handles HTML table, tag <tr> */
- void handleDoxyHtmlTag_tr(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /* Handles HTML table, tag <th> */
- void handleDoxyHtmlTag_th(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /* Handles HTML table, tag <td> */
- void handleDoxyHtmlTag_td(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
-
- /* Handles HTML entities recognized by Doxygen, like &lt;, &copy;, ... */
- void handleHtmlEntity(DoxygenEntity &, std::string &translatedComment, const std::string &arg);
-
-
- /*
- * Simple helper function that calculates correct parameter type
- * of the node stored in 'currentNode'
- * If param with specified name is not found, empty string is returned
- */
- std::string getParamType(std::string name);
-
- /*
- * Simple helper function to retrieve the parameter value
- */
- std::string getParamValue(std::string name);
-
-private:
- // temporary thing, should be refactored somehow
- Node *currentNode;
-
- // Extra indent for the current paragraph, must be output after each new line.
- std::string m_indent;
-
-
- // this contains the handler pointer and one string argument
- typedef std::map<std::string, std::pair<tagHandler, std::string> >TagHandlersMap;
- static TagHandlersMap tagHandlers;
-
- // this contains the sections titles, like 'Arguments:' or 'Notes:', that are printed only once
- static std::map<std::string, std::string> sectionTitles;
-
- // Helper functions for fillStaticTables(): make a new tag handler object.
- TagHandlersMap::mapped_type make_handler(tagHandler handler);
- TagHandlersMap::mapped_type make_handler(tagHandler handler, const char *arg);
-
- void fillStaticTables();
-};
-
-#endif
diff --git a/contrib/tools/swig/Source/Include/swigconfig.h b/contrib/tools/swig/Source/Include/swigconfig.h
deleted file mode 100644
index b6287a10b8..0000000000
--- a/contrib/tools/swig/Source/Include/swigconfig.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* Source/Include/swigconfig.h. Generated from swigconfig.h.in by configure. */
-/* Source/Include/swigconfig.h.in. Generated from configure.ac by autoheader. */
-
-/* define if the Boost library is available */
-#define HAVE_BOOST /**/
-
-/* define if the compiler supports basic C++11 syntax */
-/* #undef HAVE_CXX11 */
-
-/* define if the compiler supports basic C++14 syntax */
-/* #undef HAVE_CXX14 */
-
-/* define if the compiler supports basic C++17 syntax */
-/* #undef HAVE_CXX17 */
-
-/* define if the compiler supports basic C++20 syntax */
-#define HAVE_CXX20 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-/* #undef HAVE_INTTYPES_H */
-
-/* Define to 1 if you have the `dl' library (-ldl). */
-#define HAVE_LIBDL 1
-
-/* Define to 1 if you have the `dld' library (-ldld). */
-/* #undef HAVE_LIBDLD */
-
-/* Define if you have PCRE2 library */
-#define HAVE_PCRE 1
-
-/* Define if popen is available */
-#define HAVE_POPEN 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-/* #undef HAVE_STDINT_H */
-
-/* Define to 1 if you have the <stdio.h> header file. */
-/* #undef HAVE_STDIO_H */
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-/* #undef HAVE_STDLIB_H */
-
-/* Define to 1 if you have the <strings.h> header file. */
-/* #undef HAVE_STRINGS_H */
-
-/* Define to 1 if you have the <string.h> header file. */
-/* #undef HAVE_STRING_H */
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-/* #undef HAVE_SYS_STAT_H */
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-/* #undef HAVE_SYS_TYPES_H */
-
-/* Define to 1 if you have the <unistd.h> header file. */
-/* #undef HAVE_UNISTD_H */
-
-/* Name of package */
-#define PACKAGE "swig"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "https://www.swig.org"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "swig"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "swig 4.1.1"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "swig"
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "4.1.1"
-
-/* Define to 1 if all of the C90 standard headers exist (not just the ones
- required in a freestanding environment). This macro is provided for
- backward compatibility; new code need not use it. */
-/* #undef STDC_HEADERS */
-
-/* Compiler that built SWIG */
-#define SWIG_CXX "g++"
-
-/* Directory for SWIG system-independent libraries */
-#define SWIG_LIB "/var/empty/swig-4.1.1/share/swig/4.1.1"
-
-/* Directory for SWIG system-independent libraries (Unix install on native
- Windows) */
-#define SWIG_LIB_WIN_UNIX ""
-
-/* Platform that SWIG is built for */
-#define SWIG_PLATFORM "x86_64-pc-linux-gnu"
-
-/* Version number of package */
-#define VERSION "4.1.1"
-
-
-/* Deal with attempt by Microsoft to deprecate C standard runtime functions */
-#if defined(_MSC_VER)
-# define _CRT_SECURE_NO_DEPRECATE
-#endif
-
diff --git a/contrib/tools/swig/Source/Include/swigwarn.h b/contrib/tools/swig/Source/Include/swigwarn.h
deleted file mode 100644
index f38607f925..0000000000
--- a/contrib/tools/swig/Source/Include/swigwarn.h
+++ /dev/null
@@ -1,327 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * swigwarn.h
- *
- * SWIG warning message numbers
- * This file serves as the main registry of warning message numbers. Some of these
- * numbers are used internally in the C/C++ source code of SWIG. However, some
- * of the numbers are used in SWIG configuration files (swig.swg and others).
- *
- * The numbers are roughly organized into a few different classes by functionality.
- *
- * Even though symbolic constants are used in the SWIG source, this is
- * not always the case in SWIG interface files. Do not change the
- * numbers in this file.
- *
- * This file is used as the input for generating Lib/swigwarn.swg.
- * ----------------------------------------------------------------------------- */
-
-#ifndef SWIG_SWIGWARN_H
-#define SWIG_SWIGWARN_H
-
-#define WARN_NONE 0
-
-/* -- Deprecated features -- */
-
-#define WARN_DEPRECATED_EXTERN 101
-#define WARN_DEPRECATED_VAL 102
-#define WARN_DEPRECATED_OUT 103
-#define WARN_DEPRECATED_DISABLEDOC 104
-#define WARN_DEPRECATED_ENABLEDOC 105
-#define WARN_DEPRECATED_DOCONLY 106
-#define WARN_DEPRECATED_STYLE 107
-#define WARN_DEPRECATED_LOCALSTYLE 108
-#define WARN_DEPRECATED_TITLE 109
-#define WARN_DEPRECATED_SECTION 110
-#define WARN_DEPRECATED_SUBSECTION 111
-#define WARN_DEPRECATED_SUBSUBSECTION 112
-#define WARN_DEPRECATED_ADDMETHODS 113
-#define WARN_DEPRECATED_READONLY 114
-#define WARN_DEPRECATED_READWRITE 115
-#define WARN_DEPRECATED_EXCEPT 116
-#define WARN_DEPRECATED_NEW 117
-#define WARN_DEPRECATED_EXCEPT_TM 118
-#define WARN_DEPRECATED_IGNORE_TM 119
-#define WARN_DEPRECATED_OPTC 120
-#define WARN_DEPRECATED_NAME 121
-#define WARN_DEPRECATED_NOEXTERN 122
-#define WARN_DEPRECATED_NODEFAULT 123
-/* Unused since 4.1.0: #define WARN_DEPRECATED_TYPEMAP_LANG 124 */
-#define WARN_DEPRECATED_INPUT_FILE 125
-#define WARN_DEPRECATED_NESTED_WORKAROUND 126
-
-/* -- Preprocessor -- */
-
-#define WARN_PP_MISSING_FILE 201
-#define WARN_PP_EVALUATION 202
-#define WARN_PP_INCLUDEALL_IMPORTALL 203
-#define WARN_PP_CPP_WARNING 204
-#define WARN_PP_CPP_ERROR 205
-#define WARN_PP_UNEXPECTED_TOKENS 206
-
-/* -- C/C++ Parser -- */
-
-#define WARN_PARSE_CLASS_KEYWORD 301
-#define WARN_PARSE_REDEFINED 302
-#define WARN_PARSE_EXTEND_UNDEF 303
-#define WARN_PARSE_UNSUPPORTED_VALUE 304
-#define WARN_PARSE_BAD_VALUE 305
-#define WARN_PARSE_PRIVATE 306
-#define WARN_PARSE_BAD_DEFAULT 307
-#define WARN_PARSE_NAMESPACE_ALIAS 308
-#define WARN_PARSE_PRIVATE_INHERIT 309
-#define WARN_PARSE_TEMPLATE_REPEAT 310
-#define WARN_PARSE_TEMPLATE_PARTIAL 311
-#define WARN_PARSE_UNNAMED_NESTED_CLASS 312
-#define WARN_PARSE_UNDEFINED_EXTERN 313
-#define WARN_PARSE_KEYWORD 314
-#define WARN_PARSE_USING_UNDEF 315
-#define WARN_PARSE_MODULE_REPEAT 316
-#define WARN_PARSE_TEMPLATE_SP_UNDEF 317
-#define WARN_PARSE_TEMPLATE_AMBIG 318
-#define WARN_PARSE_NO_ACCESS 319
-#define WARN_PARSE_EXPLICIT_TEMPLATE 320
-#define WARN_PARSE_BUILTIN_NAME 321
-#define WARN_PARSE_REDUNDANT 322
-#define WARN_PARSE_REC_INHERITANCE 323
-#define WARN_PARSE_NESTED_TEMPLATE 324
-#define WARN_PARSE_NAMED_NESTED_CLASS 325
-#define WARN_PARSE_EXTEND_NAME 326
-#define WARN_PARSE_EXTERN_TEMPLATE 327
-
-#define WARN_CPP11_LAMBDA 340
-#define WARN_CPP11_ALIAS_DECLARATION 341 /* redundant now */
-#define WARN_CPP11_ALIAS_TEMPLATE 342 /* redundant now */
-#define WARN_CPP11_VARIADIC_TEMPLATE 343
-
-#define WARN_IGNORE_OPERATOR_NEW 350 /* new */
-#define WARN_IGNORE_OPERATOR_DELETE 351 /* delete */
-#define WARN_IGNORE_OPERATOR_PLUS 352 /* + */
-#define WARN_IGNORE_OPERATOR_MINUS 353 /* - */
-#define WARN_IGNORE_OPERATOR_MUL 354 /* * */
-#define WARN_IGNORE_OPERATOR_DIV 355 /* / */
-#define WARN_IGNORE_OPERATOR_MOD 356 /* % */
-#define WARN_IGNORE_OPERATOR_XOR 357 /* ^ */
-#define WARN_IGNORE_OPERATOR_AND 358 /* & */
-#define WARN_IGNORE_OPERATOR_OR 359 /* | */
-#define WARN_IGNORE_OPERATOR_NOT 360 /* ~ */
-#define WARN_IGNORE_OPERATOR_LNOT 361 /* ! */
-#define WARN_IGNORE_OPERATOR_EQ 362 /* = */
-#define WARN_IGNORE_OPERATOR_LT 363 /* < */
-#define WARN_IGNORE_OPERATOR_GT 364 /* > */
-#define WARN_IGNORE_OPERATOR_PLUSEQ 365 /* += */
-#define WARN_IGNORE_OPERATOR_MINUSEQ 366 /* -= */
-#define WARN_IGNORE_OPERATOR_MULEQ 367 /* *= */
-#define WARN_IGNORE_OPERATOR_DIVEQ 368 /* /= */
-#define WARN_IGNORE_OPERATOR_MODEQ 369 /* %= */
-#define WARN_IGNORE_OPERATOR_XOREQ 370 /* ^= */
-#define WARN_IGNORE_OPERATOR_ANDEQ 371 /* &= */
-#define WARN_IGNORE_OPERATOR_OREQ 372 /* |= */
-#define WARN_IGNORE_OPERATOR_LSHIFT 373 /* << */
-#define WARN_IGNORE_OPERATOR_RSHIFT 374 /* >> */
-#define WARN_IGNORE_OPERATOR_LSHIFTEQ 375 /* <<= */
-#define WARN_IGNORE_OPERATOR_RSHIFTEQ 376 /* >>= */
-#define WARN_IGNORE_OPERATOR_EQUALTO 377 /* == */
-#define WARN_IGNORE_OPERATOR_NOTEQUAL 378 /* != */
-#define WARN_IGNORE_OPERATOR_LTEQUAL 379 /* <= */
-#define WARN_IGNORE_OPERATOR_GTEQUAL 380 /* >= */
-#define WARN_IGNORE_OPERATOR_LAND 381 /* && */
-#define WARN_IGNORE_OPERATOR_LOR 382 /* || */
-#define WARN_IGNORE_OPERATOR_PLUSPLUS 383 /* ++ */
-#define WARN_IGNORE_OPERATOR_MINUSMINUS 384 /* -- */
-#define WARN_IGNORE_OPERATOR_COMMA 385 /* , */
-#define WARN_IGNORE_OPERATOR_ARROWSTAR 386 /* ->* */
-#define WARN_IGNORE_OPERATOR_ARROW 387 /* -> */
-#define WARN_IGNORE_OPERATOR_CALL 388 /* () */
-#define WARN_IGNORE_OPERATOR_INDEX 389 /* [] */
-#define WARN_IGNORE_OPERATOR_UPLUS 390 /* + */
-#define WARN_IGNORE_OPERATOR_UMINUS 391 /* - */
-#define WARN_IGNORE_OPERATOR_UMUL 392 /* * */
-#define WARN_IGNORE_OPERATOR_UAND 393 /* & */
-#define WARN_IGNORE_OPERATOR_NEWARR 394 /* new [] */
-#define WARN_IGNORE_OPERATOR_DELARR 395 /* delete [] */
-#define WARN_IGNORE_OPERATOR_REF 396 /* operator *() */
-#define WARN_IGNORE_OPERATOR_LTEQUALGT 397 /* <=> */
-
-/* please leave 350-399 free for WARN_IGNORE_OPERATOR_* */
-
-/* -- Type system and typemaps -- */
-
-#define WARN_TYPE_UNDEFINED_CLASS 401
-#define WARN_TYPE_INCOMPLETE 402
-#define WARN_TYPE_ABSTRACT 403
-#define WARN_TYPE_REDEFINED 404
-#define WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED 405
-
-#define WARN_TYPEMAP_SOURCETARGET 450 /* No longer issued */
-#define WARN_TYPEMAP_CHARLEAK 451
-#define WARN_TYPEMAP_SWIGTYPE 452 /* No longer issued */
-#define WARN_TYPEMAP_APPLY_UNDEF 453
-#define WARN_TYPEMAP_SWIGTYPELEAK 454
-#define WARN_TYPEMAP_WCHARLEAK 455
-
-#define WARN_TYPEMAP_IN_UNDEF 460
-#define WARN_TYPEMAP_OUT_UNDEF 461
-#define WARN_TYPEMAP_VARIN_UNDEF 462
-#define WARN_TYPEMAP_VAROUT_UNDEF 463
-#define WARN_TYPEMAP_CONST_UNDEF 464
-#define WARN_TYPEMAP_UNDEF 465
-#define WARN_TYPEMAP_VAR_UNDEF 466
-#define WARN_TYPEMAP_TYPECHECK 467
-#define WARN_TYPEMAP_THROW 468
-#define WARN_TYPEMAP_DIRECTORIN_UNDEF 469
-#define WARN_TYPEMAP_THREAD_UNSAFE 470 /* mostly used in directorout typemaps */
-#define WARN_TYPEMAP_DIRECTOROUT_UNDEF 471
-#define WARN_TYPEMAP_TYPECHECK_UNDEF 472
-#define WARN_TYPEMAP_DIRECTOROUT_PTR 473
-#define WARN_TYPEMAP_OUT_OPTIMAL_IGNORED 474
-#define WARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE 475
-#define WARN_TYPEMAP_INITIALIZER_LIST 476
-#define WARN_TYPEMAP_DIRECTORTHROWS_UNDEF 477
-
-/* -- Fragments -- */
-#define WARN_FRAGMENT_NOT_FOUND 490
-
-/* -- General code generation -- */
-
-#define WARN_LANG_OVERLOAD_DECL 501
-#define WARN_LANG_OVERLOAD_CONSTRUCT 502
-#define WARN_LANG_IDENTIFIER 503
-#define WARN_LANG_RETURN_TYPE 504
-#define WARN_LANG_VARARGS 505
-#define WARN_LANG_VARARGS_KEYWORD 506
-#define WARN_LANG_NATIVE_UNIMPL 507
-#define WARN_LANG_DEREF_SHADOW 508
-#define WARN_LANG_OVERLOAD_SHADOW 509
-#define WARN_LANG_FRIEND_IGNORE 510
-#define WARN_LANG_OVERLOAD_KEYWORD 511
-#define WARN_LANG_OVERLOAD_CONST 512
-#define WARN_LANG_CLASS_UNNAMED 513
-#define WARN_LANG_DIRECTOR_VDESTRUCT 514
-#define WARN_LANG_DISCARD_CONST 515
-#define WARN_LANG_OVERLOAD_IGNORED 516
-#define WARN_LANG_DIRECTOR_ABSTRACT 517
-#define WARN_LANG_PORTABILITY_FILENAME 518
-#define WARN_LANG_TEMPLATE_METHOD_IGNORE 519
-#define WARN_LANG_SMARTPTR_MISSING 520
-#define WARN_LANG_ILLEGAL_DESTRUCTOR 521
-#define WARN_LANG_EXTEND_CONSTRUCTOR 522
-#define WARN_LANG_EXTEND_DESTRUCTOR 523
-#define WARN_LANG_EXPERIMENTAL 524
-#define WARN_LANG_DIRECTOR_FINAL 525
-#define WARN_LANG_USING_NAME_DIFFERENT 526
-
-/* -- Doxygen comments -- */
-
-#define WARN_DOXYGEN_UNKNOWN_COMMAND 560
-#define WARN_DOXYGEN_UNEXPECTED_END_OF_COMMENT 561
-#define WARN_DOXYGEN_COMMAND_EXPECTED 562
-#define WARN_DOXYGEN_HTML_ERROR 563
-#define WARN_DOXYGEN_COMMAND_ERROR 564
-#define WARN_DOXYGEN_UNKNOWN_CHARACTER 565
-#define WARN_DOXYGEN_UNEXPECTED_ITERATOR_VALUE 566
-
-/* -- Reserved (600-699) -- */
-
-/* -- Language module specific warnings (700 - 899) -- */
-
-/* Feel free to claim any number in this space that's not currently being used. Just make sure you
- add an entry here */
-
-#define WARN_D_TYPEMAP_CTYPE_UNDEF 700
-#define WARN_D_TYPEMAP_IMTYPE_UNDEF 701
-#define WARN_D_TYPEMAP_DTYPE_UNDEF 702
-#define WARN_D_MULTIPLE_INHERITANCE 703
-#define WARN_D_TYPEMAP_CLASSMOD_UNDEF 704
-#define WARN_D_TYPEMAP_DBODY_UNDEF 705
-#define WARN_D_TYPEMAP_DOUT_UNDEF 706
-#define WARN_D_TYPEMAP_DIN_UNDEF 707
-#define WARN_D_TYPEMAP_DDIRECTORIN_UNDEF 708
-#define WARN_D_TYPEMAP_DCONSTRUCTOR_UNDEF 709
-#define WARN_D_EXCODE_MISSING 710
-#define WARN_D_CANTHROW_MISSING 711
-#define WARN_D_NO_DIRECTORCONNECT_ATTR 712
-#define WARN_D_NAME_COLLISION 713
-
-/* please leave 700-719 free for D */
-
-#define WARN_SCILAB_TRUNCATED_NAME 720
-
-/* please leave 720-739 free for Scilab */
-
-#define WARN_PYTHON_INDENT_MISMATCH 740
-
-/* please leave 740-749 free for Python */
-
-#define WARN_R_MISSING_RTYPECHECK_TYPEMAP 750
-
-/* please leave 750-759 free for R */
-
-#define WARN_RUBY_WRONG_NAME 801
-#define WARN_RUBY_MULTIPLE_INHERITANCE 802
-
-/* please leave 800-809 free for Ruby */
-
-#define WARN_JAVA_TYPEMAP_JNI_UNDEF 810
-#define WARN_JAVA_TYPEMAP_JTYPE_UNDEF 811
-#define WARN_JAVA_TYPEMAP_JSTYPE_UNDEF 812
-#define WARN_JAVA_MULTIPLE_INHERITANCE 813
-#define WARN_JAVA_TYPEMAP_GETCPTR_UNDEF 814
-#define WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF 815
-#define WARN_JAVA_TYPEMAP_JAVABODY_UNDEF 816
-#define WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF 817
-#define WARN_JAVA_TYPEMAP_JAVAIN_UNDEF 818
-#define WARN_JAVA_TYPEMAP_JAVADIRECTORIN_UNDEF 819
-#define WARN_JAVA_TYPEMAP_JAVADIRECTOROUT_UNDEF 820
-#define WARN_JAVA_TYPEMAP_INTERFACECODE_UNDEF 821
-#define WARN_JAVA_COVARIANT_RET 822
-#define WARN_JAVA_TYPEMAP_JAVACONSTRUCT_UNDEF 823
-#define WARN_JAVA_TYPEMAP_DIRECTORIN_NODESC 824
-#define WARN_JAVA_NO_DIRECTORCONNECT_ATTR 825
-#define WARN_JAVA_NSPACE_WITHOUT_PACKAGE 826
-#define WARN_JAVA_TYPEMAP_INTERFACEMODIFIERS_UNDEF 827
-
-/* please leave 810-829 free for Java */
-
-#define WARN_CSHARP_TYPEMAP_CTYPE_UNDEF 830
-#define WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF 831
-#define WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF 832
-#define WARN_CSHARP_MULTIPLE_INHERITANCE 833
-#define WARN_CSHARP_TYPEMAP_GETCPTR_UNDEF 834
-#define WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF 835
-#define WARN_CSHARP_TYPEMAP_CSBODY_UNDEF 836
-#define WARN_CSHARP_TYPEMAP_CSOUT_UNDEF 837
-#define WARN_CSHARP_TYPEMAP_CSIN_UNDEF 838
-#define WARN_CSHARP_TYPEMAP_CSDIRECTORIN_UNDEF 839
-#define WARN_CSHARP_TYPEMAP_CSDIRECTOROUT_UNDEF 840
-#define WARN_CSHARP_TYPEMAP_INTERFACECODE_UNDEF 841
-#define WARN_CSHARP_COVARIANT_RET 842
-#define WARN_CSHARP_TYPEMAP_CSCONSTRUCT_UNDEF 843
-#define WARN_CSHARP_EXCODE 844
-#define WARN_CSHARP_CANTHROW 845
-#define WARN_CSHARP_NO_DIRECTORCONNECT_ATTR 846
-#define WARN_CSHARP_TYPEMAP_INTERFACEMODIFIERS_UNDEF 847
-
-/* please leave 830-849 free for C# */
-
-/* 850-860 were used by Modula 3 (removed in SWIG 4.1.0) - avoid reusing for now */
-
-#define WARN_PHP_MULTIPLE_INHERITANCE 870
-#define WARN_PHP_UNKNOWN_PRAGMA 871
-#define WARN_PHP_PUBLIC_BASE 872
-
-/* please leave 870-889 free for PHP */
-
-#define WARN_GO_NAME_CONFLICT 890
-
-/* please leave 890-899 free for Go */
-
-/* -- User defined warnings (900 - 999) -- */
-
-#endif
diff --git a/contrib/tools/swig/Source/Modules/README b/contrib/tools/swig/Source/Modules/README
deleted file mode 100644
index 058779d227..0000000000
--- a/contrib/tools/swig/Source/Modules/README
+++ /dev/null
@@ -1,9 +0,0 @@
-06/25/2002
-
-This directory contains all of the SWIG language modules. Many of these
-modules contain code that dates back to SWIG1.0. The module API has changed
-a lot in the development releases so this is fairly messy. We're working on
-cleaning it up, but you'll have to bear with us until it's done.
-
--- Dave
-
diff --git a/contrib/tools/swig/Source/Modules/allocate.cxx b/contrib/tools/swig/Source/Modules/allocate.cxx
deleted file mode 100644
index 0e1262f839..0000000000
--- a/contrib/tools/swig/Source/Modules/allocate.cxx
+++ /dev/null
@@ -1,971 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * allocate.cxx
- *
- * This module tries to figure out which classes and structures support
- * default constructors and destructors in C++. There are several rules that
- * define this behavior including pure abstract methods, private sections,
- * and non-default constructors in base classes. See the ARM or
- * Doc/Manual/SWIGPlus.html for details.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include "cparse.h"
-
-static int virtual_elimination_mode = 0; /* set to 0 on default */
-
-/* Set virtual_elimination_mode */
-void Wrapper_virtual_elimination_mode_set(int flag) {
- virtual_elimination_mode = flag;
-}
-
-/* Helper function to assist with abstract class checking.
- This is a major hack. Sorry. */
-
-extern "C" {
- static String *search_decl = 0; /* Declarator being searched */
- static int check_implemented(Node *n) {
- String *decl;
- if (!n)
- return 0;
- while (n) {
- if (Strcmp(nodeType(n), "cdecl") == 0) {
- decl = Getattr(n, "decl");
- if (SwigType_isfunction(decl)) {
- SwigType *decl1 = SwigType_typedef_resolve_all(decl);
- SwigType *decl2 = SwigType_pop_function(decl1);
- if (Strcmp(decl2, search_decl) == 0) {
- if (!GetFlag(n, "abstract")) {
- Delete(decl1);
- Delete(decl2);
- return 1;
- }
- }
- Delete(decl1);
- Delete(decl2);
- }
- }
- n = Getattr(n, "csym:nextSibling");
- }
- return 0;
- }
-}
-
-class Allocate:public Dispatcher {
- Node *inclass;
- int extendmode;
-
- /* Checks if a function, n, is the same as any in the base class, ie if the method is polymorphic.
- * Also checks for methods which will be hidden (ie a base has an identical non-virtual method).
- * Both methods must have public access for a match to occur. */
- int function_is_defined_in_bases(Node *n, Node *bases) {
-
- if (!bases)
- return 0;
-
- String *this_decl = Getattr(n, "decl");
- if (!this_decl)
- return 0;
-
- String *name = Getattr(n, "name");
- String *this_type = Getattr(n, "type");
- String *resolved_decl = SwigType_typedef_resolve_all(this_decl);
-
- // Search all base classes for methods with same signature
- for (int i = 0; i < Len(bases); i++) {
- Node *b = Getitem(bases, i);
- Node *base = firstChild(b);
- while (base) {
- if (Strcmp(nodeType(base), "extend") == 0) {
- // Loop through all the %extend methods
- Node *extend = firstChild(base);
- while (extend) {
- if (function_is_defined_in_bases_seek(n, b, extend, this_decl, name, this_type, resolved_decl)) {
- Delete(resolved_decl);
- return 1;
- }
- extend = nextSibling(extend);
- }
- } else if (Strcmp(nodeType(base), "using") == 0) {
- // Loop through all the using declaration methods
- Node *usingdecl = firstChild(base);
- while (usingdecl) {
- if (function_is_defined_in_bases_seek(n, b, usingdecl, this_decl, name, this_type, resolved_decl)) {
- Delete(resolved_decl);
- return 1;
- }
- usingdecl = nextSibling(usingdecl);
- }
- } else {
- // normal methods
- if (function_is_defined_in_bases_seek(n, b, base, this_decl, name, this_type, resolved_decl)) {
- Delete(resolved_decl);
- return 1;
- }
- }
- base = nextSibling(base);
- }
- }
- Delete(resolved_decl);
- resolved_decl = 0;
- for (int j = 0; j < Len(bases); j++) {
- Node *b = Getitem(bases, j);
- if (function_is_defined_in_bases(n, Getattr(b, "allbases")))
- return 1;
- }
- return 0;
- }
-
- /* Helper function for function_is_defined_in_bases */
- int function_is_defined_in_bases_seek(Node *n, Node *b, Node *base, String *this_decl, String *name, String *this_type, String *resolved_decl) {
-
- String *base_decl = Getattr(base, "decl");
- SwigType *base_type = Getattr(base, "type");
- if (base_decl && base_type) {
- if (checkAttribute(base, "name", name) && !GetFlag(b, "feature:ignore") /* whole class is ignored */ ) {
- if (SwigType_isfunction(resolved_decl) && SwigType_isfunction(base_decl)) {
- // We have found a method that has the same name as one in a base class
- bool covariant_returntype = false;
- bool returntype_match = Strcmp(base_type, this_type) == 0 ? true : false;
- bool decl_match = Strcmp(base_decl, this_decl) == 0 ? true : false;
- if (returntype_match && decl_match) {
- // Exact match - we have found a method with identical signature
- // No typedef resolution was done, but skipping it speeds things up slightly
- } else {
- // Either we have:
- // 1) matching methods but are one of them uses a different typedef (return type or parameter) to the one in base class' method
- // 2) matching polymorphic methods with covariant return type
- // 3) a non-matching method (ie an overloaded method of some sort)
- // 4) a matching method which is not polymorphic, ie it hides the base class' method
-
- // Check if fully resolved return types match (including
- // covariant return types)
- if (!returntype_match) {
- String *this_returntype = function_return_type(n);
- String *base_returntype = function_return_type(base);
- returntype_match = Strcmp(this_returntype, base_returntype) == 0 ? true : false;
- if (!returntype_match) {
- covariant_returntype = SwigType_issubtype(this_returntype, base_returntype) ? true : false;
- returntype_match = covariant_returntype;
- }
- Delete(this_returntype);
- Delete(base_returntype);
- }
- // The return types must match at this point, for the whole method to match
- if (returntype_match && !decl_match) {
- // Now need to check the parameter list
- // First do an inexpensive parameter count
- ParmList *this_parms = Getattr(n, "parms");
- ParmList *base_parms = Getattr(base, "parms");
- if (ParmList_len(this_parms) == ParmList_len(base_parms)) {
- // Number of parameters are the same, now check that all the parameters match
- SwigType *base_fn = NewString("");
- SwigType *this_fn = NewString("");
- SwigType_add_function(base_fn, base_parms);
- SwigType_add_function(this_fn, this_parms);
- base_fn = SwigType_typedef_resolve_all(base_fn);
- this_fn = SwigType_typedef_resolve_all(this_fn);
- if (Strcmp(base_fn, this_fn) == 0) {
- // Finally check that the qualifiers match
- int base_qualifier = SwigType_isqualifier(resolved_decl);
- int this_qualifier = SwigType_isqualifier(base_decl);
- if (base_qualifier == this_qualifier) {
- decl_match = true;
- }
- }
- Delete(base_fn);
- Delete(this_fn);
- }
- }
- }
- //Printf(stderr,"look %s %s %d %d\n",base_decl, this_decl, returntype_match, decl_match);
-
- if (decl_match && returntype_match) {
- // Found an identical method in the base class
- bool this_wrapping_protected_members = is_member_director(n) ? true : false; // This should really check for dirprot rather than just being a director method
- bool base_wrapping_protected_members = is_member_director(base) ? true : false; // This should really check for dirprot rather than just being a director method
- bool both_have_public_access = is_public(n) && is_public(base);
- bool both_have_protected_access = (is_protected(n) && this_wrapping_protected_members) && (is_protected(base) && base_wrapping_protected_members);
- bool both_have_private_access = is_private(n) && is_private(base);
- if (checkAttribute(base, "storage", "virtual")) {
- // Found a polymorphic method.
- // Mark the polymorphic method, in case the virtual keyword was not used.
- Setattr(n, "storage", "virtual");
- if (!GetFlag(b, "feature:interface")) { // interface implementation neither hides nor overrides
- if (both_have_public_access || both_have_protected_access) {
- if (!is_non_public_base(inclass, b))
- Setattr(n, "override", base); // Note C# definition of override, ie access must be the same
- }
- else if (!both_have_private_access) {
- // Different access
- if (this_wrapping_protected_members || base_wrapping_protected_members)
- if (!is_non_public_base(inclass, b))
- Setattr(n, "hides", base); // Note C# definition of hiding, ie hidden if access is different
- }
- }
- // Try and find the most base's covariant return type
- SwigType *most_base_covariant_type = Getattr(base, "covariant");
- if (!most_base_covariant_type && covariant_returntype)
- most_base_covariant_type = function_return_type(base, false);
-
- if (!most_base_covariant_type) {
- // Eliminate the derived virtual method.
- if (virtual_elimination_mode && !is_member_director(n))
- if (both_have_public_access)
- if (!is_non_public_base(inclass, b))
- if (!Swig_symbol_isoverloaded(n)) {
- // Don't eliminate if an overloaded method as this hides the method
- // in the scripting languages: the dispatch function will hide the base method if ignored.
- SetFlag(n, "feature:ignore");
- }
- } else {
- // Some languages need to know about covariant return types
- Setattr(n, "covariant", most_base_covariant_type);
- }
-
- } else {
- // Found an identical method in the base class, but it is not polymorphic.
- if (both_have_public_access || both_have_protected_access)
- if (!is_non_public_base(inclass, b))
- Setattr(n, "hides", base);
- }
- if (both_have_public_access || both_have_protected_access)
- return 1;
- }
- }
- }
- }
- return 0;
- }
-
- /* Determines whether the base class, b, is in the list of private
- * or protected base classes for class n. */
- bool is_non_public_base(Node *n, Node *b) {
- bool non_public_base = false;
- Node *bases = Getattr(n, "privatebases");
- if (bases) {
- for (int i = 0; i < Len(bases); i++) {
- Node *base = Getitem(bases, i);
- if (base == b)
- non_public_base = true;
- }
- }
- bases = Getattr(n, "protectedbases");
- if (bases) {
- for (int i = 0; i < Len(bases); i++) {
- Node *base = Getitem(bases, i);
- if (base == b)
- non_public_base = true;
- }
- }
- return non_public_base;
- }
-
- /* Returns the return type for a function. The node n should be a function.
- If resolve is true the fully returned type is fully resolved.
- Caller is responsible for deleting returned string. */
- String *function_return_type(Node *n, bool resolve = true) {
- String *decl = Getattr(n, "decl");
- SwigType *type = Getattr(n, "type");
- String *ty = NewString(type);
- SwigType_push(ty, decl);
- if (SwigType_isqualifier(ty))
- Delete(SwigType_pop(ty));
- Delete(SwigType_pop_function(ty));
- if (resolve) {
- String *unresolved = ty;
- ty = SwigType_typedef_resolve_all(unresolved);
- Delete(unresolved);
- }
- return ty;
- }
-
- /* Checks if a class member is the same as inherited from the class bases */
- int class_member_is_defined_in_bases(Node *member, Node *classnode) {
- Node *bases; /* bases is the closest ancestors of classnode */
- int defined = 0;
-
- bases = Getattr(classnode, "allbases");
- if (!bases)
- return 0;
-
- {
- int old_mode = virtual_elimination_mode;
- if (is_member_director(classnode, member))
- virtual_elimination_mode = 0;
-
- if (function_is_defined_in_bases(member, bases)) {
- defined = 1;
- }
-
- virtual_elimination_mode = old_mode;
- }
-
- if (defined)
- return 1;
- else
- return 0;
- }
-
- /* Checks to see if a class is abstract through inheritance,
- and saves the first node that seems to be abstract.
- */
- int is_abstract_inherit(Node *n, Node *base = 0, int first = 0) {
- if (!first && (base == n))
- return 0;
- if (!base) {
- /* Root node */
- Symtab *stab = Getattr(n, "symtab"); /* Get symbol table for node */
- Symtab *oldtab = Swig_symbol_setscope(stab);
- int ret = is_abstract_inherit(n, n, 1);
- Swig_symbol_setscope(oldtab);
- return ret;
- }
- List *abstracts = Getattr(base, "abstracts");
- if (abstracts) {
- int dabstract = 0;
- int len = Len(abstracts);
- for (int i = 0; i < len; i++) {
- Node *nn = Getitem(abstracts, i);
- String *name = Getattr(nn, "name");
- if (!name)
- continue;
- if (Strchr(name, '~'))
- continue; /* Don't care about destructors */
- String *base_decl = Getattr(nn, "decl");
- if (base_decl)
- base_decl = SwigType_typedef_resolve_all(base_decl);
- if (SwigType_isfunction(base_decl))
- search_decl = SwigType_pop_function(base_decl);
- Node *dn = Swig_symbol_clookup_local_check(name, 0, check_implemented);
- Delete(search_decl);
- Delete(base_decl);
-
- if (!dn) {
- List *nabstracts = Getattr(n, "abstracts");
- if (!nabstracts) {
- nabstracts = NewList();
- Setattr(n, "abstracts", nabstracts);
- Delete(nabstracts);
- }
- Append(nabstracts, nn);
- if (!Getattr(n, "abstracts:firstnode")) {
- Setattr(n, "abstracts:firstnode", nn);
- }
- dabstract = base != n;
- }
- }
- if (dabstract)
- return 1;
- }
- List *bases = Getattr(base, "allbases");
- if (!bases)
- return 0;
- for (int i = 0; i < Len(bases); i++) {
- if (is_abstract_inherit(n, Getitem(bases, i))) {
- return 1;
- }
- }
- return 0;
- }
-
-
- /* Grab methods used by smart pointers */
-
- List *smart_pointer_methods(Node *cls, List *methods, int isconst, String *classname = 0) {
- if (!methods) {
- methods = NewList();
- }
-
- Node *c = firstChild(cls);
-
- while (c) {
- if (Getattr(c, "error") || GetFlag(c, "feature:ignore")) {
- c = nextSibling(c);
- continue;
- }
- if (!isconst && (Strcmp(nodeType(c), "extend") == 0)) {
- methods = smart_pointer_methods(c, methods, isconst, Getattr(cls, "name"));
- } else if (Strcmp(nodeType(c), "cdecl") == 0) {
- if (!GetFlag(c, "feature:ignore")) {
- String *storage = Getattr(c, "storage");
- if (!((Cmp(storage, "typedef") == 0))
- && !((Cmp(storage, "friend") == 0))) {
- String *name = Getattr(c, "name");
- String *symname = Getattr(c, "sym:name");
- Node *e = Swig_symbol_clookup_local(name, 0);
- if (e && is_public(e) && !GetFlag(e, "feature:ignore") && (Cmp(symname, Getattr(e, "sym:name")) == 0)) {
- Swig_warning(WARN_LANG_DEREF_SHADOW, Getfile(e), Getline(e), "Declaration of '%s' shadows declaration accessible via operator->(),\n", name);
- Swig_warning(WARN_LANG_DEREF_SHADOW, Getfile(c), Getline(c), "previous declaration of '%s'.\n", name);
- } else {
- /* Make sure node with same name doesn't already exist */
- int k;
- int match = 0;
- for (k = 0; k < Len(methods); k++) {
- e = Getitem(methods, k);
- if (Cmp(symname, Getattr(e, "sym:name")) == 0) {
- match = 1;
- break;
- }
- if (!Getattr(e, "sym:name") && (Cmp(name, Getattr(e, "name")) == 0)) {
- match = 1;
- break;
- }
- }
- if (!match) {
- Node *cc = c;
- while (cc) {
- Node *cp = cc;
- if (classname) {
- Setattr(cp, "extendsmartclassname", classname);
- }
- Setattr(cp, "allocate:smartpointeraccess", "1");
- /* If constant, we have to be careful */
- if (isconst) {
- SwigType *decl = Getattr(cp, "decl");
- if (decl) {
- if (SwigType_isfunction(decl)) { /* If method, we only add if it's a const method */
- if (SwigType_isconst(decl)) {
- Append(methods, cp);
- }
- } else {
- Append(methods, cp);
- }
- } else {
- Append(methods, cp);
- }
- } else {
- Append(methods, cp);
- }
- cc = Getattr(cc, "sym:nextSibling");
- }
- }
- }
- }
- }
- }
-
- c = nextSibling(c);
- }
- /* Look for methods in base classes */
- {
- Node *bases = Getattr(cls, "bases");
- int k;
- for (k = 0; k < Len(bases); k++) {
- smart_pointer_methods(Getitem(bases, k), methods, isconst);
- }
- }
- /* Remove protected/private members */
- {
- for (int i = 0; i < Len(methods);) {
- Node *n = Getitem(methods, i);
- if (!is_public(n)) {
- Delitem(methods, i);
- continue;
- }
- i++;
- }
- }
- return methods;
- }
-
- void mark_exception_classes(ParmList *p) {
- while (p) {
- SwigType *ty = Getattr(p, "type");
- SwigType *t = SwigType_typedef_resolve_all(ty);
- if (SwigType_isreference(t) || SwigType_ispointer(t) || SwigType_isarray(t)) {
- Delete(SwigType_pop(t));
- }
- Node *c = Swig_symbol_clookup(t, 0);
- if (c) {
- if (!GetFlag(c, "feature:exceptionclass")) {
- SetFlag(c, "feature:exceptionclass");
- }
- }
- p = nextSibling(p);
- Delete(t);
- }
- }
-
-
- void process_exceptions(Node *n) {
- ParmList *catchlist = 0;
- /*
- the "catchlist" attribute is used to emit the block
-
- try {$action;}
- catch <list of catches>;
-
- in emit.cxx
-
- and is either constructed from the "feature:catches" feature
- or copied from the node "throws" list.
- */
- String *scatchlist = Getattr(n, "feature:catches");
- if (scatchlist) {
- catchlist = Swig_cparse_parms(scatchlist, n);
- if (catchlist) {
- Setattr(n, "catchlist", catchlist);
- mark_exception_classes(catchlist);
- Delete(catchlist);
- }
- }
- ParmList *throws = Getattr(n, "throws");
- if (throws) {
- /* if there is no explicit catchlist, we catch everything in the throws list */
- if (!catchlist) {
- Setattr(n, "catchlist", throws);
- }
- mark_exception_classes(throws);
- }
- }
-
-public:
-Allocate():
- inclass(NULL), extendmode(0) {
- }
-
- virtual int top(Node *n) {
- cplus_mode = PUBLIC;
- inclass = 0;
- extendmode = 0;
- emit_children(n);
- return SWIG_OK;
- }
-
- virtual int importDirective(Node *n) {
- return emit_children(n);
- }
- virtual int includeDirective(Node *n) {
- return emit_children(n);
- }
- virtual int externDeclaration(Node *n) {
- return emit_children(n);
- }
- virtual int namespaceDeclaration(Node *n) {
- return emit_children(n);
- }
- virtual int extendDirective(Node *n) {
- extendmode = 1;
- emit_children(n);
- extendmode = 0;
- return SWIG_OK;
- }
-
- virtual int classDeclaration(Node *n) {
- Symtab *symtab = Swig_symbol_current();
- Swig_symbol_setscope(Getattr(n, "symtab"));
- save_value<Node*> oldInclass(inclass);
- save_value<AccessMode> oldAcessMode(cplus_mode);
- save_value<int> oldExtendMode(extendmode);
- if (Getattr(n, "template"))
- extendmode = 0;
- if (!CPlusPlus) {
- /* Always have default constructors/destructors in C */
- Setattr(n, "allocate:default_constructor", "1");
- Setattr(n, "allocate:default_destructor", "1");
- }
-
- if (Getattr(n, "allocate:visit"))
- return SWIG_OK;
- Setattr(n, "allocate:visit", "1");
-
- /* Always visit base classes first */
- {
- List *bases = Getattr(n, "bases");
- if (bases) {
- for (int i = 0; i < Len(bases); i++) {
- Node *b = Getitem(bases, i);
- classDeclaration(b);
- }
- }
- }
- inclass = n;
- String *kind = Getattr(n, "kind");
- if (Strcmp(kind, "class") == 0) {
- cplus_mode = PRIVATE;
- } else {
- cplus_mode = PUBLIC;
- }
-
- emit_children(n);
-
- /* Check if the class is abstract via inheritance. This might occur if a class didn't have
- any pure virtual methods of its own, but it didn't implement all of the pure methods in
- a base class */
- if (!Getattr(n, "abstracts") && is_abstract_inherit(n)) {
- if (((Getattr(n, "allocate:public_constructor") || (!GetFlag(n, "feature:nodefault") && !Getattr(n, "allocate:has_constructor"))))) {
- if (!GetFlag(n, "feature:notabstract")) {
- Node *na = Getattr(n, "abstracts:firstnode");
- if (na) {
- Swig_warning(WARN_TYPE_ABSTRACT, Getfile(n), Getline(n),
- "Class '%s' might be abstract, " "no constructors generated,\n", SwigType_namestr(Getattr(n, "name")));
- Swig_warning(WARN_TYPE_ABSTRACT, Getfile(na), Getline(na), "Method %s might not be implemented.\n", Swig_name_decl(na));
- if (!Getattr(n, "abstracts")) {
- List *abstracts = NewList();
- Append(abstracts, na);
- Setattr(n, "abstracts", abstracts);
- Delete(abstracts);
- }
- }
- }
- }
- }
-
- if (!Getattr(n, "allocate:has_constructor")) {
- /* No constructor is defined. We need to check a few things */
- /* If class is abstract. No default constructor. Sorry */
- if (Getattr(n, "abstracts")) {
- Delattr(n, "allocate:default_constructor");
- }
- if (!Getattr(n, "allocate:default_constructor")) {
- /* Check base classes */
- List *bases = Getattr(n, "allbases");
- int allows_default = 1;
-
- for (int i = 0; i < Len(bases); i++) {
- Node *n = Getitem(bases, i);
- /* If base class does not allow default constructor, we don't allow it either */
- if (!Getattr(n, "allocate:default_constructor") && (!Getattr(n, "allocate:default_base_constructor"))) {
- allows_default = 0;
- }
- }
- if (allows_default) {
- Setattr(n, "allocate:default_constructor", "1");
- }
- }
- }
- if (!Getattr(n, "allocate:has_copy_constructor")) {
- if (Getattr(n, "abstracts")) {
- Delattr(n, "allocate:copy_constructor");
- }
- if (!Getattr(n, "allocate:copy_constructor")) {
- /* Check base classes */
- List *bases = Getattr(n, "allbases");
- int allows_copy = 1;
-
- for (int i = 0; i < Len(bases); i++) {
- Node *n = Getitem(bases, i);
- /* If base class does not allow copy constructor, we don't allow it either */
- if (!Getattr(n, "allocate:copy_constructor") && (!Getattr(n, "allocate:copy_base_constructor"))) {
- allows_copy = 0;
- }
- }
- if (allows_copy) {
- Setattr(n, "allocate:copy_constructor", "1");
- }
- }
- }
-
- if (!Getattr(n, "allocate:has_destructor")) {
- /* No destructor was defined */
- List *bases = Getattr(n, "allbases");
- int allows_destruct = 1;
-
- for (int i = 0; i < Len(bases); i++) {
- Node *n = Getitem(bases, i);
- /* If base class does not allow default destructor, we don't allow it either */
- if (!Getattr(n, "allocate:default_destructor") && (!Getattr(n, "allocate:default_base_destructor"))) {
- allows_destruct = 0;
- }
- }
- if (allows_destruct) {
- Setattr(n, "allocate:default_destructor", "1");
- }
- }
-
- if (!Getattr(n, "allocate:has_assign")) {
- /* No assignment operator was defined */
- List *bases = Getattr(n, "allbases");
- int allows_assign = 1;
-
- for (int i = 0; i < Len(bases); i++) {
- Node *n = Getitem(bases, i);
- /* If base class does not allow assignment, we don't allow it either */
- if (Getattr(n, "allocate:has_assign")) {
- allows_assign = !Getattr(n, "allocate:noassign");
- }
- }
- if (!allows_assign) {
- Setattr(n, "allocate:noassign", "1");
- }
- }
-
- if (!Getattr(n, "allocate:has_new")) {
- /* No new operator was defined */
- List *bases = Getattr(n, "allbases");
- int allows_new = 1;
-
- for (int i = 0; i < Len(bases); i++) {
- Node *n = Getitem(bases, i);
- /* If base class does not allow new operator, we don't allow it either */
- if (Getattr(n, "allocate:has_new")) {
- allows_new = !Getattr(n, "allocate:nonew");
- }
- }
- if (!allows_new) {
- Setattr(n, "allocate:nonew", "1");
- }
- }
-
- /* Check if base classes allow smart pointers, but might be hidden */
- if (!Getattr(n, "allocate:smartpointer")) {
- Node *sp = Swig_symbol_clookup("operator ->", 0);
- if (sp) {
- /* Look for parent */
- Node *p = parentNode(sp);
- if (Strcmp(nodeType(p), "extend") == 0) {
- p = parentNode(p);
- }
- if (Strcmp(nodeType(p), "class") == 0) {
- if (GetFlag(p, "feature:ignore")) {
- Setattr(n, "allocate:smartpointer", Getattr(p, "allocate:smartpointer"));
- }
- }
- }
- }
-
- Swig_interface_propagate_methods(n);
-
- /* Only care about default behavior. Remove temporary values */
- Setattr(n, "allocate:visit", "1");
- Swig_symbol_setscope(symtab);
- return SWIG_OK;
- }
-
- virtual int accessDeclaration(Node *n) {
- String *kind = Getattr(n, "kind");
- if (Cmp(kind, "public") == 0) {
- cplus_mode = PUBLIC;
- } else if (Cmp(kind, "private") == 0) {
- cplus_mode = PRIVATE;
- } else if (Cmp(kind, "protected") == 0) {
- cplus_mode = PROTECTED;
- }
- return SWIG_OK;
- }
-
- virtual int usingDeclaration(Node *n) {
-
- Node *c = 0;
- for (c = firstChild(n); c; c = nextSibling(c)) {
- if (Strcmp(nodeType(c), "cdecl") == 0) {
- process_exceptions(c);
-
- if (inclass)
- class_member_is_defined_in_bases(c, inclass);
- }
- }
-
- return SWIG_OK;
- }
-
- virtual int cDeclaration(Node *n) {
-
- process_exceptions(n);
-
- if (inclass) {
- /* check whether the member node n is defined in class node in class's bases */
- class_member_is_defined_in_bases(n, inclass);
-
- /* Check to see if this is a static member or not. If so, we add an attribute
- cplus:staticbase that saves the current class */
-
- if (Swig_storage_isstatic(n)) {
- Setattr(n, "cplus:staticbase", inclass);
- } else if (Cmp(Getattr(n, "kind"), "variable") == 0) {
- /* Check member variable to determine whether assignment is valid */
- if (SwigType_isreference(Getattr(n, "type"))) {
- /* Can't assign a class with reference member data */
- Setattr(inclass, "allocate:noassign", "1");
- }
- }
-
- String *name = Getattr(n, "name");
- if (cplus_mode != PUBLIC) {
- if (Strcmp(name, "operator =") == 0) {
- /* Look for a private assignment operator */
- if (!GetFlag(n, "deleted"))
- Setattr(inclass, "allocate:has_assign", "1");
- Setattr(inclass, "allocate:noassign", "1");
- } else if (Strcmp(name, "operator new") == 0) {
- /* Look for a private new operator */
- if (!GetFlag(n, "deleted"))
- Setattr(inclass, "allocate:has_new", "1");
- Setattr(inclass, "allocate:nonew", "1");
- }
- } else {
- if (Strcmp(name, "operator =") == 0) {
- if (!GetFlag(n, "deleted"))
- Setattr(inclass, "allocate:has_assign", "1");
- else
- Setattr(inclass, "allocate:noassign", "1");
- } else if (Strcmp(name, "operator new") == 0) {
- if (!GetFlag(n, "deleted"))
- Setattr(inclass, "allocate:has_new", "1");
- else
- Setattr(inclass, "allocate:nonew", "1");
- }
- /* Look for smart pointer operator */
- if ((Strcmp(name, "operator ->") == 0) && (!GetFlag(n, "feature:ignore"))) {
- /* Look for version with no parameters */
- Node *sn = n;
- while (sn) {
- if (!Getattr(sn, "parms")) {
- SwigType *type = SwigType_typedef_resolve_all(Getattr(sn, "type"));
- SwigType_push(type, Getattr(sn, "decl"));
- Delete(SwigType_pop_function(type));
- SwigType *base = SwigType_base(type);
- Node *sc = Swig_symbol_clookup(base, 0);
- if ((sc) && (Strcmp(nodeType(sc), "class") == 0)) {
- if (SwigType_check_decl(type, "p.")) {
- /* Need to check if type is a const pointer */
- int isconst = 0;
- Delete(SwigType_pop(type));
- if (SwigType_isconst(type)) {
- isconst = !Getattr(inclass, "allocate:smartpointermutable");
- Setattr(inclass, "allocate:smartpointerconst", "1");
- }
- else {
- Setattr(inclass, "allocate:smartpointermutable", "1");
- }
- List *methods = smart_pointer_methods(sc, 0, isconst);
- Setattr(inclass, "allocate:smartpointer", methods);
- Setattr(inclass, "allocate:smartpointerpointeeclassname", Getattr(sc, "name"));
- } else {
- /* Hmmm. The return value is not a pointer. If the type is a value
- or reference. We're going to chase it to see if another operator->()
- can be found */
- if ((SwigType_check_decl(type, "")) || (SwigType_check_decl(type, "r."))) {
- Node *nn = Swig_symbol_clookup("operator ->", Getattr(sc, "symtab"));
- if (nn) {
- Delete(base);
- Delete(type);
- sn = nn;
- continue;
- }
- }
- }
- }
- Delete(base);
- Delete(type);
- break;
- }
- }
- }
- }
- }
- return SWIG_OK;
- }
-
- virtual int constructorDeclaration(Node *n) {
- if (!inclass)
- return SWIG_OK;
- Parm *parms = Getattr(n, "parms");
-
- process_exceptions(n);
- if (!extendmode) {
- if (!ParmList_numrequired(parms)) {
- /* Class does define a default constructor */
- /* However, we had better see where it is defined */
- if (cplus_mode == PUBLIC) {
- Setattr(inclass, "allocate:default_constructor", "1");
- } else if (cplus_mode == PROTECTED) {
- Setattr(inclass, "allocate:default_base_constructor", "1");
- }
- }
- /* Class defines some kind of constructor. May or may not be public */
- Setattr(inclass, "allocate:has_constructor", "1");
- if (cplus_mode == PUBLIC) {
- Setattr(inclass, "allocate:public_constructor", "1");
- }
- } else {
- Setattr(inclass, "allocate:has_constructor", "1");
- Setattr(inclass, "allocate:public_constructor", "1");
- }
-
-
- /* See if this is a copy constructor */
- if (parms && (ParmList_numrequired(parms) == 1)) {
- /* Look for a few cases. X(const X &), X(X &), X(X *) */
- int copy_constructor = 0;
- SwigType *type = Getattr(inclass, "name");
- String *tn = NewStringf("r.q(const).%s", type);
- String *cc = SwigType_typedef_resolve_all(tn);
- SwigType *rt = SwigType_typedef_resolve_all(Getattr(parms, "type"));
- if (SwigType_istemplate(type)) {
- String *tmp = Swig_symbol_template_deftype(cc, 0);
- Delete(cc);
- cc = tmp;
- tmp = Swig_symbol_template_deftype(rt, 0);
- Delete(rt);
- rt = tmp;
- }
- if (Strcmp(cc, rt) == 0) {
- copy_constructor = 1;
- } else {
- Delete(cc);
- cc = NewStringf("r.%s", Getattr(inclass, "name"));
- if (Strcmp(cc, Getattr(parms, "type")) == 0) {
- copy_constructor = 1;
- } else {
- Delete(cc);
- cc = NewStringf("p.%s", Getattr(inclass, "name"));
- String *ty = SwigType_strip_qualifiers(Getattr(parms, "type"));
- if (Strcmp(cc, ty) == 0) {
- copy_constructor = 1;
- }
- Delete(ty);
- }
- }
- Delete(cc);
- Delete(rt);
- Delete(tn);
-
- if (copy_constructor) {
- Setattr(n, "copy_constructor", "1");
- Setattr(inclass, "allocate:has_copy_constructor", "1");
- if (cplus_mode == PUBLIC) {
- Setattr(inclass, "allocate:copy_constructor", "1");
- } else if (cplus_mode == PROTECTED) {
- Setattr(inclass, "allocate:copy_base_constructor", "1");
- }
- }
- }
- return SWIG_OK;
- }
-
- virtual int destructorDeclaration(Node *n) {
- (void) n;
- if (!inclass)
- return SWIG_OK;
- if (!extendmode) {
- Setattr(inclass, "allocate:has_destructor", "1");
- if (cplus_mode == PUBLIC) {
- Setattr(inclass, "allocate:default_destructor", "1");
- } else if (cplus_mode == PROTECTED) {
- Setattr(inclass, "allocate:default_base_destructor", "1");
- } else if (cplus_mode == PRIVATE) {
- Setattr(inclass, "allocate:private_destructor", "1");
- }
- } else {
- Setattr(inclass, "allocate:has_destructor", "1");
- Setattr(inclass, "allocate:default_destructor", "1");
- }
- return SWIG_OK;
- }
-};
-
-void Swig_default_allocators(Node *n) {
- if (!n)
- return;
- Allocate *a = new Allocate;
- a->top(n);
- delete a;
-}
diff --git a/contrib/tools/swig/Source/Modules/contract.cxx b/contrib/tools/swig/Source/Modules/contract.cxx
deleted file mode 100644
index dfc85ebe76..0000000000
--- a/contrib/tools/swig/Source/Modules/contract.cxx
+++ /dev/null
@@ -1,358 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * contract.cxx
- *
- * Support for Wrap by Contract in SWIG.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-
-/* Contract structure. This holds rules about the different kinds of contract sections
- and their combination rules */
-
-struct contract {
- const char *section;
- const char *combiner;
-};
-/* Contract rules. This table defines what contract sections are recognized as well as
- how contracts are to combined via inheritance */
-
-static contract Rules[] = {
- {"require:", "&&"},
- {"ensure:", "||"},
- {NULL, NULL}
-};
-
-/* ----------------------------------------------------------------------------
- * class Contracts:
- *
- * This class defines the functions that need to be used in
- * "wrap by contract" module.
- * ------------------------------------------------------------------------- */
-
-class Contracts:public Dispatcher {
- String *make_expression(String *s, Node *n);
- void substitute_parms(String *s, ParmList *p, int method);
-public:
- Hash *ContractSplit(Node *n);
- int emit_contract(Node *n, int method);
- int cDeclaration(Node *n);
- int constructorDeclaration(Node *n);
- int externDeclaration(Node *n);
- int extendDirective(Node *n);
- int importDirective(Node *n);
- int includeDirective(Node *n);
- int namespaceDeclaration(Node *n);
- int classDeclaration(Node *n);
- virtual int top(Node *n);
-};
-
-static int Contract_Mode = 0; /* contract option */
-static int InClass = 0; /* Parsing C++ or not */
-static int InConstructor = 0;
-static Node *CurrentClass = 0;
-
-/* Set the contract mode, default is 0 (not open) */
-/* Normally set in main.cxx, when get the "-contracts" option */
-void Swig_contract_mode_set(int flag) {
- Contract_Mode = flag;
-}
-
-/* Get the contract mode */
-int Swig_contract_mode_get() {
- return Contract_Mode;
-}
-
-/* Apply contracts */
-void Swig_contracts(Node *n) {
-
- Contracts *a = new Contracts;
- a->top(n);
- delete a;
-}
-
-/* Split the whole contract into preassertion, postassertion and others */
-Hash *Contracts::ContractSplit(Node *n) {
-
- String *contract = Getattr(n, "feature:contract");
- Hash *result;
- if (!contract)
- return NULL;
-
- result = NewHash();
- String *current_section = NewString("");
- const char *current_section_name = Rules[0].section;
- List *l = SplitLines(contract);
-
- Iterator i;
- for (i = First(l); i.item; i = Next(i)) {
- int found = 0;
- if (Strchr(i.item, '{'))
- continue;
- if (Strchr(i.item, '}'))
- continue;
- for (int j = 0; Rules[j].section; j++) {
- if (Strstr(i.item, Rules[j].section)) {
- if (Len(current_section)) {
- Setattr(result, current_section_name, current_section);
- current_section = Getattr(result, Rules[j].section);
- if (!current_section)
- current_section = NewString("");
- }
- current_section_name = Rules[j].section;
- found = 1;
- break;
- }
- }
- if (!found)
- Append(current_section, i.item);
- }
- if (Len(current_section))
- Setattr(result, current_section_name, current_section);
- return result;
-}
-
-/* This function looks in base classes and collects contracts found */
-void inherit_contracts(Node *c, Node *n, Hash *contracts, Hash *messages) {
-
- Node *b, *temp;
- String *name, *type, *local_decl, *base_decl;
- List *bases;
- int found = 0;
-
- bases = Getattr(c, "bases");
- if (!bases)
- return;
-
- name = Getattr(n, "name");
- type = Getattr(n, "type");
- local_decl = Getattr(n, "decl");
- if (local_decl) {
- local_decl = SwigType_typedef_resolve_all(local_decl);
- } else {
- return;
- }
- /* Width first search */
- for (int i = 0; i < Len(bases); i++) {
- b = Getitem(bases, i);
- temp = firstChild(b);
- while (temp) {
- base_decl = Getattr(temp, "decl");
- if (base_decl) {
- base_decl = SwigType_typedef_resolve_all(base_decl);
- if ((checkAttribute(temp, "storage", "virtual")) &&
- (checkAttribute(temp, "name", name)) && (checkAttribute(temp, "type", type)) && (!Strcmp(local_decl, base_decl))) {
- /* Yes, match found. */
- Hash *icontracts = Getattr(temp, "contract:rules");
- Hash *imessages = Getattr(temp, "contract:messages");
- found = 1;
- if (icontracts && imessages) {
- /* Add inherited contracts and messages to the contract rules above */
- int j = 0;
- for (j = 0; Rules[j].section; j++) {
- String *t = Getattr(contracts, Rules[j].section);
- String *s = Getattr(icontracts, Rules[j].section);
- if (s) {
- if (t) {
- Insert(t, 0, "(");
- Printf(t, ") %s (%s)", Rules[j].combiner, s);
- String *m = Getattr(messages, Rules[j].section);
- Printf(m, " %s [%s from %s]", Rules[j].combiner, Getattr(imessages, Rules[j].section), Getattr(b, "name"));
- } else {
- Setattr(contracts, Rules[j].section, NewString(s));
- Setattr(messages, Rules[j].section, NewStringf("[%s from %s]", Getattr(imessages, Rules[j].section), Getattr(b, "name")));
- }
- }
- }
- }
- }
- Delete(base_decl);
- }
- temp = nextSibling(temp);
- }
- }
- Delete(local_decl);
- if (!found) {
- for (int j = 0; j < Len(bases); j++) {
- b = Getitem(bases, j);
- inherit_contracts(b, n, contracts, messages);
- }
- }
-}
-
-/* This function cleans up the assertion string by removing some extraneous characters.
- Splitting the assertion into pieces */
-
-String *Contracts::make_expression(String *s, Node *n) {
- String *str_assert, *expr = 0;
- List *list_assert;
-
- str_assert = NewString(s);
- /* Omit all useless characters and split by ; */
- Replaceall(str_assert, "\n", "");
- Replaceall(str_assert, "{", "");
- Replaceall(str_assert, "}", "");
- Replace(str_assert, " ", "", DOH_REPLACE_ANY | DOH_REPLACE_NOQUOTE);
- Replace(str_assert, "\t", "", DOH_REPLACE_ANY | DOH_REPLACE_NOQUOTE);
-
- list_assert = Split(str_assert, ';', -1);
- Delete(str_assert);
-
- /* build up new assertion */
- str_assert = NewString("");
- Iterator ei;
-
- for (ei = First(list_assert); ei.item; ei = Next(ei)) {
- expr = ei.item;
- if (Len(expr)) {
- Replaceid(expr, Getattr(n, "name"), Swig_cresult_name());
- if (Len(str_assert))
- Append(str_assert, "&&");
- Printf(str_assert, "(%s)", expr);
- }
- }
- Delete(list_assert);
- return str_assert;
-}
-
-/* This function substitutes parameter names for argument names in the
- contract specification. Note: it is assumed that the wrapper code
- uses arg1 for self and arg2..argn for arguments. */
-
-void Contracts::substitute_parms(String *s, ParmList *p, int method) {
- int argnum = 1;
- char argname[32];
-
- if (method) {
- Replaceid(s, "$self", "arg1");
- argnum++;
- }
- while (p) {
- sprintf(argname, "arg%d", argnum);
- String *name = Getattr(p, "name");
- if (name) {
- Replaceid(s, name, argname);
- }
- argnum++;
- p = nextSibling(p);
- }
-}
-
-int Contracts::emit_contract(Node *n, int method) {
- Hash *contracts;
- Hash *messages;
- String *c;
-
- ParmList *cparms;
-
- if (!Getattr(n, "feature:contract"))
- return SWIG_ERROR;
-
- /* Get contract parameters */
- cparms = Getmeta(Getattr(n, "feature:contract"), "parms");
-
- /* Split contract into preassert & postassert */
- contracts = ContractSplit(n);
- if (!contracts)
- return SWIG_ERROR;
-
- /* This messages hash is used to hold the error messages that will be displayed on
- failed contract. */
-
- messages = NewHash();
-
- /* Take the different contract expressions and clean them up a bit */
- Iterator i;
- for (i = First(contracts); i.item; i = Next(i)) {
- String *e = make_expression(i.item, n);
- substitute_parms(e, cparms, method);
- Setattr(contracts, i.key, e);
-
- /* Make a string containing error messages */
- Setattr(messages, i.key, NewString(e));
- }
-
- /* If we're in a class. We need to inherit other assertions. */
- if (InClass) {
- inherit_contracts(CurrentClass, n, contracts, messages);
- }
-
- /* Save information */
- Setattr(n, "contract:rules", contracts);
- Setattr(n, "contract:messages", messages);
-
- /* Okay. Generate the contract runtime code. */
-
- if ((c = Getattr(contracts, "require:"))) {
- Setattr(n, "contract:preassert", NewStringf("SWIG_contract_assert(%s, \"Contract violation: require: %s\");\n", c, Getattr(messages, "require:")));
- }
- if ((c = Getattr(contracts, "ensure:"))) {
- Setattr(n, "contract:postassert", NewStringf("SWIG_contract_assert(%s, \"Contract violation: ensure: %s\");\n", c, Getattr(messages, "ensure:")));
- }
- return SWIG_OK;
-}
-
-int Contracts::cDeclaration(Node *n) {
- int ret = SWIG_OK;
- String *decl = Getattr(n, "decl");
-
- /* Not a function. Don't even bother with it (for now) */
- if (!SwigType_isfunction(decl))
- return SWIG_OK;
-
- if (Getattr(n, "feature:contract"))
- ret = emit_contract(n, InClass && !Swig_storage_isstatic(n));
- return ret;
-}
-
-int Contracts::constructorDeclaration(Node *n) {
- int ret = SWIG_OK;
- InConstructor = 1;
- if (Getattr(n, "feature:contract"))
- ret = emit_contract(n, 0);
- InConstructor = 0;
- return ret;
-}
-
-int Contracts::externDeclaration(Node *n) {
- return emit_children(n);
-}
-
-int Contracts::extendDirective(Node *n) {
- return emit_children(n);
-}
-
-int Contracts::importDirective(Node *n) {
- return emit_children(n);
-}
-
-int Contracts::includeDirective(Node *n) {
- return emit_children(n);
-}
-
-int Contracts::namespaceDeclaration(Node *n) {
- return emit_children(n);
-}
-
-int Contracts::classDeclaration(Node *n) {
- int ret = SWIG_OK;
- int oldInClass = InClass;
- Node *oldClass = CurrentClass;
- InClass = 1;
- CurrentClass = n;
- emit_children(n);
- InClass = oldInClass;
- CurrentClass = oldClass;
- return ret;
-}
-
-int Contracts::top(Node *n) {
- emit_children(n);
- return SWIG_OK;
-}
diff --git a/contrib/tools/swig/Source/Modules/csharp.cxx b/contrib/tools/swig/Source/Modules/csharp.cxx
deleted file mode 100644
index 240a002b40..0000000000
--- a/contrib/tools/swig/Source/Modules/csharp.cxx
+++ /dev/null
@@ -1,4616 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * csharp.cxx
- *
- * C# language module for SWIG.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include "cparse.h"
-#include <limits.h> // for INT_MAX
-#include <ctype.h>
-
-/* Hash type used for upcalls from C/C++ */
-typedef DOH UpcallData;
-
-class CSHARP:public Language {
- static const char *usage;
- const String *empty_string;
- const String *public_string;
- const String *protected_string;
-
- Hash *swig_types_hash;
- File *f_begin;
- File *f_runtime;
- File *f_runtime_h;
- File *f_header;
- File *f_wrappers;
- File *f_init;
- File *f_directors;
- File *f_directors_h;
- File *f_single_out;
- List *filenames_list;
-
- bool proxy_flag; // Flag for generating proxy classes
- bool native_function_flag; // Flag for when wrapping a native function
- bool enum_constant_flag; // Flag for when wrapping an enum or constant
- bool static_flag; // Flag for when wrapping a static functions or member variables
- bool variable_wrapper_flag; // Flag for when wrapping a nonstatic member variable
- bool wrapping_member_flag; // Flag for when wrapping a member variable/enum/const
- bool global_variable_flag; // Flag for when wrapping a global variable
- bool old_variable_names; // Flag for old style variable names in the intermediary class
- bool generate_property_declaration_flag; // Flag for generating properties
-
- String *imclass_name; // intermediary class name
- String *module_class_name; // module class name
- String *imclass_class_code; // intermediary class code
- String *proxy_class_def;
- String *proxy_class_code;
- String *interface_class_code; // if %feature("interface") was declared for a class, here goes the interface declaration
- String *module_class_code;
- String *proxy_class_name; // proxy class name
- String *full_imclass_name; // fully qualified intermediary class name when using nspace feature, otherwise same as imclass_name
- String *variable_name; //Name of a variable being wrapped
- String *proxy_class_constants_code;
- String *module_class_constants_code;
- String *enum_code;
- String *dllimport; // DllImport attribute name
- String *namespce; // Optional namespace name
- String *imclass_imports; //intermediary class imports from %pragma
- String *module_imports; //module imports from %pragma
- String *imclass_baseclass; //inheritance for intermediary class class from %pragma
- String *module_baseclass; //inheritance for module class from %pragma
- String *imclass_interfaces; //interfaces for intermediary class class from %pragma
- String *module_interfaces; //interfaces for module class from %pragma
- String *imclass_class_modifiers; //class modifiers for intermediary class overridden by %pragma
- String *module_class_modifiers; //class modifiers for module class overridden by %pragma
- String *upcasts_code; //C++ casts for inheritance hierarchies C++ code
- String *imclass_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code
- String *director_callback_typedefs; // Director function pointer typedefs for callbacks
- String *director_callbacks; // Director callback function pointer member variables
- String *director_delegate_callback; // Director callback method that delegates are set to call
- String *director_delegate_definitions; // Director delegates definitions in proxy class
- String *director_delegate_instances; // Director delegates member variables in proxy class
- String *director_method_types; // Director method types
- String *director_connect_parms; // Director delegates parameter list for director connect call
- String *destructor_call; //C++ destructor call if any
- String *output_file; // File name for single file mode. If set all generated code will be written to this file
-
- // Director method stuff:
- List *dmethods_seq;
- Hash *dmethods_table;
- int n_dmethods;
- int n_directors;
- int first_class_dmethod;
- int curr_class_dmethod;
- int nesting_depth;
-
- enum EnumFeature { SimpleEnum, TypeunsafeEnum, TypesafeEnum, ProperEnum };
-
-public:
-
- /* -----------------------------------------------------------------------------
- * CSHARP()
- * ----------------------------------------------------------------------------- */
-
- CSHARP():empty_string(NewString("")),
- public_string(NewString("public")),
- protected_string(NewString("protected")),
- swig_types_hash(NULL),
- f_begin(NULL),
- f_runtime(NULL),
- f_runtime_h(NULL),
- f_header(NULL),
- f_wrappers(NULL),
- f_init(NULL),
- f_directors(NULL),
- f_directors_h(NULL),
- f_single_out(NULL),
- filenames_list(NULL),
- proxy_flag(true),
- native_function_flag(false),
- enum_constant_flag(false),
- static_flag(false),
- variable_wrapper_flag(false),
- wrapping_member_flag(false),
- global_variable_flag(false),
- old_variable_names(false),
- generate_property_declaration_flag(false),
- imclass_name(NULL),
- module_class_name(NULL),
- imclass_class_code(NULL),
- proxy_class_def(NULL),
- proxy_class_code(NULL),
- interface_class_code(NULL),
- module_class_code(NULL),
- proxy_class_name(NULL),
- full_imclass_name(NULL),
- variable_name(NULL),
- proxy_class_constants_code(NULL),
- module_class_constants_code(NULL),
- enum_code(NULL),
- dllimport(NULL),
- namespce(NULL),
- imclass_imports(NULL),
- module_imports(NULL),
- imclass_baseclass(NULL),
- module_baseclass(NULL),
- imclass_interfaces(NULL),
- module_interfaces(NULL),
- imclass_class_modifiers(NULL),
- module_class_modifiers(NULL),
- upcasts_code(NULL),
- imclass_cppcasts_code(NULL),
- director_callback_typedefs(NULL),
- director_callbacks(NULL),
- director_delegate_callback(NULL),
- director_delegate_definitions(NULL),
- director_delegate_instances(NULL),
- director_method_types(NULL),
- director_connect_parms(NULL),
- destructor_call(NULL),
- output_file(NULL),
- dmethods_seq(NULL),
- dmethods_table(NULL),
- n_dmethods(0),
- n_directors(0),
- first_class_dmethod(0),
- curr_class_dmethod(0),
- nesting_depth(0){
- /* for now, multiple inheritance in directors is disabled, this
- should be easy to implement though */
- director_multiple_inheritance = 0;
- director_language = 1;
- }
-
- /* -----------------------------------------------------------------------------
- * getProxyName()
- *
- * Test to see if a type corresponds to something wrapped with a proxy class.
- * Return NULL if not otherwise the proxy class name, fully qualified with
- * a namespace if the nspace feature is used.
- * ----------------------------------------------------------------------------- */
-
- String *getProxyName(SwigType *t) {
- String *proxyname = NULL;
- if (proxy_flag) {
- Node *n = classLookup(t);
- if (n) {
- proxyname = Getattr(n, "proxyname");
- if (!proxyname) {
- String *nspace = Getattr(n, "sym:nspace");
- String *symname = Copy(Getattr(n, "sym:name"));
- if (symname && !GetFlag(n, "feature:flatnested")) {
- for (Node *outer_class = Getattr(n, "nested:outer"); outer_class; outer_class = Getattr(outer_class, "nested:outer")) {
- if (String* name = Getattr(outer_class, "sym:name")) {
- Push(symname, ".");
- Push(symname, name);
- }
- else
- return NULL;
- }
- }
- if (nspace) {
- if (namespce)
- proxyname = NewStringf("%s.%s.%s", namespce, nspace, symname);
- else
- proxyname = NewStringf("%s.%s", nspace, symname);
- } else {
- proxyname = Copy(symname);
- }
- Setattr(n, "proxyname", proxyname);
- Delete(proxyname);
- Delete(symname);
- }
- }
- }
- return proxyname;
- }
-
- /* ------------------------------------------------------------
- * main()
- * ------------------------------------------------------------ */
-
- virtual void main(int argc, char *argv[]) {
-
- SWIG_library_directory("csharp");
-
- // Look for certain command line options
- for (int i = 1; i < argc; i++) {
- if (argv[i]) {
- if (strcmp(argv[i], "-dllimport") == 0) {
- if (argv[i + 1]) {
- dllimport = NewString("");
- Printf(dllimport, argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-namespace") == 0) {
- if (argv[i + 1]) {
- namespce = NewString("");
- Printf(namespce, argv[i + 1]);
- if (Len(namespce) == 0) {
- Delete(namespce);
- namespce = 0;
- }
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if ((strcmp(argv[i], "-noproxy") == 0)) {
- Swig_mark_arg(i);
- proxy_flag = false;
- } else if (strcmp(argv[i], "-oldvarnames") == 0) {
- Swig_mark_arg(i);
- old_variable_names = true;
- } else if (strcmp(argv[i], "-outfile") == 0) {
- if (argv[i + 1]) {
- output_file = NewString("");
- Printf(output_file, argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-help") == 0) {
- Printf(stdout, "%s\n", usage);
- }
- }
- }
-
- // Add a symbol to the parser for conditional compilation
- Preprocessor_define("SWIGCSHARP 1", 0);
-
- // Add typemap definitions
- SWIG_typemap_lang("csharp");
- SWIG_config_file("csharp.swg");
-
- allow_overloading();
- Swig_interface_feature_enable();
- }
-
- /* ---------------------------------------------------------------------
- * top()
- * --------------------------------------------------------------------- */
-
- virtual int top(Node *n) {
-
- // Get any options set in the module directive
- Node *optionsnode = Getattr(Getattr(n, "module"), "options");
-
- if (optionsnode) {
- if (Getattr(optionsnode, "imclassname"))
- imclass_name = Copy(Getattr(optionsnode, "imclassname"));
- /* check if directors are enabled for this module. note: this
- * is a "master" switch, without which no director code will be
- * emitted. %feature("director") statements are also required
- * to enable directors for individual classes or methods.
- *
- * use %module(directors="1") modulename at the start of the
- * interface file to enable director generation.
- */
- if (Getattr(optionsnode, "directors")) {
- allow_directors();
- }
- if (Getattr(optionsnode, "dirprot")) {
- allow_dirprot();
- }
- allow_allprotected(GetFlag(optionsnode, "allprotected"));
- }
-
- /* Initialize all of the output files */
- String *outfile = Getattr(n, "outfile");
- String *outfile_h = Getattr(n, "outfile_h");
-
- if (!outfile) {
- Printf(stderr, "Unable to determine outfile\n");
- Exit(EXIT_FAILURE);
- }
-
- f_begin = NewFile(outfile, "w", SWIG_output_files());
- if (!f_begin) {
- FileErrorDisplay(outfile);
- Exit(EXIT_FAILURE);
- }
-
- if (directorsEnabled()) {
- if (!outfile_h) {
- Printf(stderr, "Unable to determine outfile_h\n");
- Exit(EXIT_FAILURE);
- }
- f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
- if (!f_runtime_h) {
- FileErrorDisplay(outfile_h);
- Exit(EXIT_FAILURE);
- }
- }
-
- f_runtime = NewString("");
- f_init = NewString("");
- f_header = NewString("");
- f_wrappers = NewString("");
- f_directors_h = NewString("");
- f_directors = NewString("");
-
- /* Register file targets with the SWIG file handler */
- Swig_register_filebyname("header", f_header);
- Swig_register_filebyname("wrapper", f_wrappers);
- Swig_register_filebyname("begin", f_begin);
- Swig_register_filebyname("runtime", f_runtime);
- Swig_register_filebyname("init", f_init);
- Swig_register_filebyname("director", f_directors);
- Swig_register_filebyname("director_h", f_directors_h);
-
- swig_types_hash = NewHash();
- filenames_list = NewList();
-
- // Make the intermediary class and module class names. The intermediary class name can be set in the module directive.
- if (!imclass_name) {
- imclass_name = NewStringf("%sPINVOKE", Getattr(n, "name"));
- module_class_name = Copy(Getattr(n, "name"));
- } else {
- // Rename the module name if it is the same as intermediary class name - a backwards compatibility solution
- if (Cmp(imclass_name, Getattr(n, "name")) == 0)
- module_class_name = NewStringf("%sModule", Getattr(n, "name"));
- else
- module_class_name = Copy(Getattr(n, "name"));
- }
-
- // module class and intermediary classes are always created
- if (!addSymbol(imclass_name, n))
- return SWIG_ERROR;
- if (!addSymbol(module_class_name, n))
- return SWIG_ERROR;
-
- imclass_class_code = NewString("");
- proxy_class_def = NewString("");
- proxy_class_code = NewString("");
- module_class_constants_code = NewString("");
- imclass_baseclass = NewString("");
- imclass_interfaces = NewString("");
- imclass_class_modifiers = NewString("");
- module_class_code = NewString("");
- module_baseclass = NewString("");
- module_interfaces = NewString("");
- module_imports = NewString("");
- module_class_modifiers = NewString("");
- imclass_imports = NewString("");
- imclass_cppcasts_code = NewString("");
- director_connect_parms = NewString("");
- upcasts_code = NewString("");
- dmethods_seq = NewList();
- dmethods_table = NewHash();
- n_dmethods = 0;
- n_directors = 0;
- if (!dllimport)
- dllimport = Copy(module_class_name);
-
- Swig_banner(f_begin);
-
- Swig_obligatory_macros(f_runtime, "CSHARP");
-
- if (directorsEnabled()) {
- Printf(f_runtime, "#define SWIG_DIRECTORS\n");
-
- /* Emit initial director header and director code: */
- Swig_banner(f_directors_h);
- Printf(f_directors_h, "\n");
- Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module_class_name);
- Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module_class_name);
-
- Printf(f_directors, "\n\n");
- Printf(f_directors, "/* ---------------------------------------------------\n");
- Printf(f_directors, " * C++ director class methods\n");
- Printf(f_directors, " * --------------------------------------------------- */\n\n");
- if (outfile_h) {
- String *filename = Swig_file_filename(outfile_h);
- Printf(f_directors, "#include \"%s\"\n\n", filename);
- Delete(filename);
- }
- }
-
- Printf(f_runtime, "\n");
- if (namespce) {
- String *wrapper_name = NewStringf("");
- Printf(wrapper_name, "CSharp_%s_%%f", namespce);
- Swig_name_register("wrapper", wrapper_name);
- Delete(wrapper_name);
- }
- else {
- Swig_name_register("wrapper", "CSharp_%f");
- }
-
- if (old_variable_names) {
- Swig_name_register("set", "set_%n%v");
- Swig_name_register("get", "get_%n%v");
- }
-
- Printf(f_wrappers, "\n#ifdef __cplusplus\n");
- Printf(f_wrappers, "extern \"C\" {\n");
- Printf(f_wrappers, "#endif\n\n");
-
- /* Emit code */
- Language::top(n);
-
- if (directorsEnabled()) {
- // Insert director runtime into the f_runtime file (make it occur before %header section)
- Swig_insert_file("director_common.swg", f_runtime);
- Swig_insert_file("director.swg", f_runtime);
- }
- // Generate the intermediary class
- {
- File *f_im = getOutputFile(SWIG_output_directory(), imclass_name);
-
- addOpenNamespace(0, f_im);
-
- if (imclass_imports)
- Printf(f_im, "%s\n", imclass_imports);
-
- if (Len(imclass_class_modifiers) > 0)
- Printf(f_im, "%s ", imclass_class_modifiers);
- Printf(f_im, "%s ", imclass_name);
-
- if (imclass_baseclass && *Char(imclass_baseclass))
- Printf(f_im, ": %s ", imclass_baseclass);
- if (Len(imclass_interfaces) > 0)
- Printv(f_im, "implements ", imclass_interfaces, " ", NIL);
- Printf(f_im, "{\n");
-
- // Add the intermediary class methods
- Replaceall(imclass_class_code, "$module", module_class_name);
- Replaceall(imclass_class_code, "$imclassname", imclass_name);
- Replaceall(imclass_class_code, "$dllimport", dllimport);
- Printv(f_im, imclass_class_code, NIL);
- Printv(f_im, imclass_cppcasts_code, NIL);
-
- // Finish off the class
- Printf(f_im, "}\n");
- addCloseNamespace(0, f_im);
-
- if (f_im != f_single_out)
- Delete(f_im);
- f_im = NULL;
- }
-
- // Generate the C# module class
- {
- File *f_module = getOutputFile(SWIG_output_directory(), module_class_name);
-
- addOpenNamespace(0, f_module);
-
- if (module_imports)
- Printf(f_module, "%s\n", module_imports);
-
- if (Len(module_class_modifiers) > 0)
- Printf(f_module, "%s ", module_class_modifiers);
- Printf(f_module, "%s ", module_class_name);
-
- if (module_baseclass && *Char(module_baseclass))
- Printf(f_module, ": %s ", module_baseclass);
- if (Len(module_interfaces) > 0)
- Printv(f_module, "implements ", module_interfaces, " ", NIL);
- Printf(f_module, "{\n");
-
- Replaceall(module_class_code, "$module", module_class_name);
- Replaceall(module_class_constants_code, "$module", module_class_name);
-
- Replaceall(module_class_code, "$imclassname", imclass_name);
- Replaceall(module_class_constants_code, "$imclassname", imclass_name);
-
- Replaceall(module_class_code, "$dllimport", dllimport);
- Replaceall(module_class_constants_code, "$dllimport", dllimport);
-
- // Add the wrapper methods
- Printv(f_module, module_class_code, NIL);
-
- // Write out all the global constants
- Printv(f_module, module_class_constants_code, NIL);
-
- // Finish off the class
- Printf(f_module, "}\n");
- addCloseNamespace(0, f_module);
-
- if (f_module != f_single_out)
- Delete(f_module);
- f_module = NULL;
- }
-
- if (upcasts_code)
- Printv(f_wrappers, upcasts_code, NIL);
-
- Printf(f_wrappers, "#ifdef __cplusplus\n");
- Printf(f_wrappers, "}\n");
- Printf(f_wrappers, "#endif\n");
-
- // Output a C# type wrapper class for each SWIG type
- for (Iterator swig_type = First(swig_types_hash); swig_type.key; swig_type = Next(swig_type)) {
- emitTypeWrapperClass(swig_type.key, swig_type.item);
- }
-
- // Check for overwriting file problems on filesystems that are case insensitive
- Iterator it1;
- Iterator it2;
- for (it1 = First(filenames_list); it1.item; it1 = Next(it1)) {
- String *item1_lower = Swig_string_lower(it1.item);
- for (it2 = Next(it1); it2.item; it2 = Next(it2)) {
- String *item2_lower = Swig_string_lower(it2.item);
- if (it1.item && it2.item) {
- if (Strcmp(item1_lower, item2_lower) == 0) {
- Swig_warning(WARN_LANG_PORTABILITY_FILENAME, input_file, line_number,
- "Portability warning: File %s will be overwritten by %s on case insensitive filesystems such as "
- "Windows' FAT32 and NTFS unless the class/module name is renamed\n", it1.item, it2.item);
- }
- }
- Delete(item2_lower);
- }
- Delete(item1_lower);
- }
-
- Delete(swig_types_hash);
- swig_types_hash = NULL;
- Delete(filenames_list);
- filenames_list = NULL;
- Delete(imclass_name);
- imclass_name = NULL;
- Delete(imclass_class_code);
- imclass_class_code = NULL;
- Delete(proxy_class_def);
- proxy_class_def = NULL;
- Delete(proxy_class_code);
- proxy_class_code = NULL;
- Delete(module_class_constants_code);
- module_class_constants_code = NULL;
- Delete(imclass_baseclass);
- imclass_baseclass = NULL;
- Delete(imclass_interfaces);
- imclass_interfaces = NULL;
- Delete(imclass_class_modifiers);
- imclass_class_modifiers = NULL;
- Delete(module_class_name);
- module_class_name = NULL;
- Delete(module_class_code);
- module_class_code = NULL;
- Delete(module_baseclass);
- module_baseclass = NULL;
- Delete(module_interfaces);
- module_interfaces = NULL;
- Delete(module_imports);
- module_imports = NULL;
- Delete(module_class_modifiers);
- module_class_modifiers = NULL;
- Delete(imclass_imports);
- imclass_imports = NULL;
- Delete(imclass_cppcasts_code);
- imclass_cppcasts_code = NULL;
- Delete(upcasts_code);
- upcasts_code = NULL;
- Delete(dmethods_seq);
- dmethods_seq = NULL;
- Delete(dmethods_table);
- dmethods_table = NULL;
- Delete(namespce);
- namespce = NULL;
- n_dmethods = 0;
-
- /* Close all of the files */
- Dump(f_runtime, f_begin);
- Dump(f_header, f_begin);
-
- if (directorsEnabled()) {
- Dump(f_directors, f_begin);
- Dump(f_directors_h, f_runtime_h);
-
- Printf(f_runtime_h, "\n");
- Printf(f_runtime_h, "#endif\n");
-
- Delete(f_runtime_h);
- f_runtime_h = NULL;
- Delete(f_directors);
- f_directors = NULL;
- Delete(f_directors_h);
- f_directors_h = NULL;
- }
-
- if (f_single_out) {
- Dump(f_single_out, f_begin);
- Delete(f_single_out);
- f_single_out = NULL;
- }
-
- Dump(f_wrappers, f_begin);
- Wrapper_pretty_print(f_init, f_begin);
- Delete(f_header);
- Delete(f_wrappers);
- Delete(f_init);
- Delete(f_runtime);
- Delete(f_begin);
- return SWIG_OK;
- }
-
- /* -----------------------------------------------------------------------------
- * emitBanner()
- * ----------------------------------------------------------------------------- */
-
- void emitBanner(File *f) {
- Printf(f, "//------------------------------------------------------------------------------\n");
- Printf(f, "// <auto-generated />\n");
- Printf(f, "//\n");
- Swig_banner_target_lang(f, "//");
- Printf(f, "//------------------------------------------------------------------------------\n\n");
- }
-
- /* -----------------------------------------------------------------------------
- * getOutputFile()
- *
- * Prepares a File object by creating the file in the file system and
- * writing the banner for auto-generated files to it (emitBanner).
- * If '-outfile' is provided (single file mode) the supplied parameters will
- * be ignored and the returned file will always be:
- * <outdir>/<outfile>
- * Otherwise the file will be:
- * <dir>/<name>.cs
- * ----------------------------------------------------------------------------- */
-
- File *getOutputFile(const String *dir, const String *name) {
- if (output_file) {
- if (!f_single_out) {
- String *filen = NewStringf("%s%s", SWIG_output_directory(), output_file);
- f_single_out = NewFile(filen, "w", SWIG_output_files());
- if (!f_single_out) {
- FileErrorDisplay(filen);
- Exit(EXIT_FAILURE);
- }
- Append(filenames_list, Copy(filen));
- Delete(filen);
- filen = NULL;
-
- emitBanner(f_single_out);
- }
- return f_single_out;
- } else {
- String *filen = NewStringf("%s%s.cs", dir, name);
- File *f = NewFile(filen, "w", SWIG_output_files());
- if (!f) {
- FileErrorDisplay(filen);
- Exit(EXIT_FAILURE);
- }
- Append(filenames_list, Copy(filen));
- Delete(filen);
- filen = NULL;
-
- emitBanner(f);
- return f;
- }
- }
-
- /*-----------------------------------------------------------------------
- * Add new director upcall signature
- *----------------------------------------------------------------------*/
-
- UpcallData *addUpcallMethod(String *imclass_method, String *class_method, String *decl, String *overloaded_name) {
- String *key = NewStringf("%s|%s", imclass_method, decl);
-
- ++curr_class_dmethod;
-
- String *class_methodidx = NewStringf("%d", n_dmethods - first_class_dmethod);
- n_dmethods++;
-
- Hash *new_udata = NewHash();
- Append(dmethods_seq, new_udata);
- Setattr(dmethods_table, key, new_udata);
-
- Setattr(new_udata, "method", Copy(class_method));
- Setattr(new_udata, "class_methodidx", class_methodidx);
- Setattr(new_udata, "decl", Copy(decl));
- Setattr(new_udata, "overname", Copy(overloaded_name));
-
- Delete(key);
- return new_udata;
- }
-
- /*-----------------------------------------------------------------------
- * Get director upcall signature
- *----------------------------------------------------------------------*/
-
- /*
- UpcallData * getUpcallMethodData(String *director_class, String *decl) {
- String *key = NewStringf("%s|%s", director_class, decl);
- UpcallData *udata = Getattr(dmethods_table, key);
-
- Delete(key);
- return udata;
- }
- */
-
- /* ----------------------------------------------------------------------
- * nativeWrapper()
- * ---------------------------------------------------------------------- */
-
- virtual int nativeWrapper(Node *n) {
- String *wrapname = Getattr(n, "wrap:name");
-
- if (!addSymbol(wrapname, n, imclass_name))
- return SWIG_ERROR;
-
- if (Getattr(n, "type")) {
- Swig_save("nativeWrapper", n, "name", NIL);
- Setattr(n, "name", wrapname);
- native_function_flag = true;
- functionWrapper(n);
- Swig_restore(n);
- native_function_flag = false;
- } else {
- Swig_error(input_file, line_number, "No return type for %%native method %s.\n", Getattr(n, "wrap:name"));
- }
-
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * functionWrapper()
- * ---------------------------------------------------------------------- */
-
- virtual int functionWrapper(Node *n) {
- String *symname = Getattr(n, "sym:name");
- SwigType *t = Getattr(n, "type");
- ParmList *l = Getattr(n, "parms");
- String *tm;
- Parm *p;
- int i;
- String *c_return_type = NewString("");
- String *im_return_type = NewString("");
- String *cleanup = NewString("");
- String *outarg = NewString("");
- String *body = NewString("");
- String *im_outattributes = 0;
- int num_arguments = 0;
- bool is_void_return;
- String *overloaded_name = getOverloadedName(n);
-
- if (!Getattr(n, "sym:overloaded")) {
- if (!addSymbol(symname, n, imclass_name))
- return SWIG_ERROR;
- }
-
- /*
- The rest of this function deals with generating the intermediary class wrapper function (that wraps
- a c/c++ function) and generating the PInvoke c code. Each C# wrapper function has a
- matching PInvoke c function call.
- */
-
- // A new wrapper function object
- Wrapper *f = NewWrapper();
-
- // Make a wrapper name for this function
- String *wname = Swig_name_wrapper(overloaded_name);
-
- /* Attach the non-standard typemaps to the parameter list. */
- Swig_typemap_attach_parms("ctype", l, f);
- Swig_typemap_attach_parms("imtype", l, f);
-
- /* Get return types */
- if ((tm = Swig_typemap_lookup("ctype", n, "", 0))) {
- String *ctypeout = Getattr(n, "tmap:ctype:out"); // the type in the ctype typemap's out attribute overrides the type in the typemap
- if (ctypeout)
- tm = ctypeout;
- Printf(c_return_type, "%s", tm);
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s\n", SwigType_str(t, 0));
- }
-
- if ((tm = Swig_typemap_lookup("imtype", n, "", 0))) {
- String *imtypeout = Getattr(n, "tmap:imtype:out"); // the type in the imtype typemap's out attribute overrides the type in the typemap
- if (imtypeout)
- tm = imtypeout;
- Printf(im_return_type, "%s", tm);
- im_outattributes = Getattr(n, "tmap:imtype:outattributes");
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(t, 0));
- }
-
- is_void_return = (Cmp(c_return_type, "void") == 0);
- if (!is_void_return)
- Wrapper_add_localv(f, "jresult", c_return_type, "jresult", NIL);
-
- Printv(f->def, " SWIGEXPORT ", c_return_type, " SWIGSTDCALL ", wname, "(", NIL);
-
- // Emit all of the local variables for holding arguments.
- emit_parameter_variables(l, f);
-
- /* Attach the standard typemaps */
- emit_attach_parmmaps(l, f);
-
- // Parameter overloading
- Setattr(n, "wrap:parms", l);
- Setattr(n, "wrap:name", wname);
-
- // Wrappers not wanted for some methods where the parameters cannot be overloaded in C#
- if (Getattr(n, "sym:overloaded")) {
- // Emit warnings for the few cases that can't be overloaded in C# and give up on generating wrapper
- Swig_overload_check(n);
- if (Getattr(n, "overload:ignore")) {
- DelWrapper(f);
- return SWIG_OK;
- }
- }
-
- Printv(imclass_class_code, "\n [global::System.Runtime.InteropServices.DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL);
-
- if (im_outattributes)
- Printf(imclass_class_code, " %s\n", im_outattributes);
-
- Printf(imclass_class_code, " public static extern %s %s(", im_return_type, overloaded_name);
-
-
- /* Get number of required and total arguments */
- num_arguments = emit_num_arguments(l);
- int gencomma = 0;
-
- // Now walk the function parameter list and generate code to get arguments
- for (i = 0, p = l; i < num_arguments; i++) {
-
- while (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- }
-
- SwigType *pt = Getattr(p, "type");
- String *ln = Getattr(p, "lname");
- String *im_param_type = NewString("");
- String *c_param_type = NewString("");
- String *arg = NewString("");
-
- Printf(arg, "j%s", ln);
-
- /* Get the ctype types of the parameter */
- if ((tm = Getattr(p, "tmap:ctype"))) {
- Printv(c_param_type, tm, NIL);
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- /* Get the intermediary class parameter types of the parameter */
- if ((tm = Getattr(p, "tmap:imtype"))) {
- const String *inattributes = Getattr(p, "tmap:imtype:inattributes");
- Printf(im_param_type, "%s%s", inattributes ? inattributes : empty_string, tm);
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- /* Add parameter to intermediary class method */
- if (gencomma)
- Printf(imclass_class_code, ", ");
- Printf(imclass_class_code, "%s %s", im_param_type, arg);
-
- // Add parameter to C function
- Printv(f->def, gencomma ? ", " : "", c_param_type, " ", arg, NIL);
-
- gencomma = 1;
-
- // Get typemap for this argument
- if ((tm = Getattr(p, "tmap:in"))) {
- canThrow(n, "in", p);
- Replaceall(tm, "$arg", arg); /* deprecated? */
- Replaceall(tm, "$input", arg);
- Setattr(p, "emit:input", arg);
- Printf(f->code, "%s\n", tm);
- p = Getattr(p, "tmap:in:next");
- } else {
- Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
- p = nextSibling(p);
- }
- Delete(im_param_type);
- Delete(c_param_type);
- Delete(arg);
- }
-
- /* Insert constraint checking code */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:check"))) {
- canThrow(n, "check", p);
- Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(f->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:check:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* Insert cleanup code */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:freearg"))) {
- canThrow(n, "freearg", p);
- Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(cleanup, tm, "\n", NIL);
- p = Getattr(p, "tmap:freearg:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* Insert argument output code */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:argout"))) {
- canThrow(n, "argout", p);
- Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */
- Replaceall(tm, "$result", "jresult");
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(outarg, tm, "\n", NIL);
- p = Getattr(p, "tmap:argout:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- // Look for usage of throws typemap and the canthrow flag
- ParmList *throw_parm_list = NULL;
- if ((throw_parm_list = Getattr(n, "catchlist"))) {
- Swig_typemap_attach_parms("throws", throw_parm_list, f);
- for (p = throw_parm_list; p; p = nextSibling(p)) {
- if (Getattr(p, "tmap:throws")) {
- canThrow(n, "throws", p);
- }
- }
- }
-
- String *null_attribute = 0;
- // Now write code to make the function call
- if (!native_function_flag) {
-
- Swig_director_emit_dynamic_cast(n, f);
- String *actioncode = emit_action(n);
-
- /* Return value if necessary */
- if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
- canThrow(n, "out", n);
- Replaceall(tm, "$result", "jresult");
-
- if (GetFlag(n, "feature:new"))
- Replaceall(tm, "$owner", "1");
- else
- Replaceall(tm, "$owner", "0");
-
- Printf(f->code, "%s", tm);
- null_attribute = Getattr(n, "tmap:out:null");
- if (Len(tm))
- Printf(f->code, "\n");
- } else {
- Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(t, 0), Getattr(n, "name"));
- }
- emit_return_variable(n, t, f);
- }
-
- /* Output argument output code */
- Printv(f->code, outarg, NIL);
-
- /* Output cleanup code */
- Printv(f->code, cleanup, NIL);
-
- /* Look to see if there is any newfree cleanup code */
- if (GetFlag(n, "feature:new")) {
- if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
- canThrow(n, "newfree", n);
- Printf(f->code, "%s\n", tm);
- }
- }
-
- /* See if there is any return cleanup code */
- if (!native_function_flag) {
- if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
- canThrow(n, "ret", n);
- Printf(f->code, "%s\n", tm);
- }
- }
-
- /* Finish C function and intermediary class function definitions */
- Printf(imclass_class_code, ")");
- Printf(imclass_class_code, ";\n");
-
- Printf(f->def, ") {");
-
- if (!is_void_return)
- Printv(f->code, " return jresult;\n", NIL);
- Printf(f->code, "}\n");
-
- /* Substitute the cleanup code */
- Replaceall(f->code, "$cleanup", cleanup);
-
- /* Substitute the function name */
- Replaceall(f->code, "$symname", symname);
-
- /* Contract macro modification */
- if (Replaceall(f->code, "SWIG_contract_assert(", "SWIG_contract_assert($null, ") > 0) {
- Setattr(n, "csharp:canthrow", "1");
- }
-
- if (!null_attribute)
- Replaceall(f->code, "$null", "0");
- else
- Replaceall(f->code, "$null", null_attribute);
-
- /* Dump the function out */
- if (!native_function_flag) {
- Wrapper_print(f, f_wrappers);
-
- // Handle %csexception which sets the canthrow attribute
- if (Getattr(n, "feature:except:canthrow"))
- Setattr(n, "csharp:canthrow", "1");
-
- // A very simple check (it is not foolproof) to help typemap/feature writers for
- // throwing C# exceptions from unmanaged code. It checks for the common methods which
- // set a pending C# exception... the 'canthrow' typemap/feature attribute must be set
- // so that code which checks for pending exceptions is added in the C# proxy method.
- if (!Getattr(n, "csharp:canthrow")) {
- if (Strstr(f->code, "SWIG_exception")) {
- Swig_warning(WARN_CSHARP_CANTHROW, input_file, line_number,
- "Unmanaged code contains a call to SWIG_exception and C# code does not handle pending exceptions via the canthrow attribute.\n");
- } else if (Strstr(f->code, "SWIG_CSharpSetPendingException")) {
- Swig_warning(WARN_CSHARP_CANTHROW, input_file, line_number,
- "Unmanaged code contains a call to a SWIG_CSharpSetPendingException method and C# code does not handle pending exceptions via the canthrow attribute.\n");
- }
- }
- }
-
- if (!(proxy_flag && is_wrapping_class()) && !enum_constant_flag) {
- moduleClassFunctionHandler(n);
- }
-
- /*
- * Generate the proxy class properties for public member variables.
- * Not for enums and constants.
- */
- if (proxy_flag && wrapping_member_flag && !enum_constant_flag) {
- // Capitalize the first letter in the variable in the getter/setter function name
- bool getter_flag = Cmp(symname, Swig_name_set(getNSpace(), Swig_name_member(0, getClassPrefix(), variable_name))) != 0;
-
- String *getter_setter_name = NewString("");
- if (!getter_flag)
- Printf(getter_setter_name, "set");
- else
- Printf(getter_setter_name, "get");
- Putc(toupper((int) *Char(variable_name)), getter_setter_name);
- Printf(getter_setter_name, "%s", Char(variable_name) + 1);
-
- Setattr(n, "proxyfuncname", getter_setter_name);
- Setattr(n, "imfuncname", symname);
-
- proxyClassFunctionHandler(n);
- Delete(getter_setter_name);
- }
-
- Delete(c_return_type);
- Delete(im_return_type);
- Delete(cleanup);
- Delete(outarg);
- Delete(body);
- Delete(overloaded_name);
- DelWrapper(f);
- return SWIG_OK;
- }
-
- /* -----------------------------------------------------------------------
- * variableWrapper()
- * ----------------------------------------------------------------------- */
-
- virtual int variableWrapper(Node *n) {
- Language::variableWrapper(n);
- return SWIG_OK;
- }
-
- /* -----------------------------------------------------------------------
- * globalvariableHandler()
- * ------------------------------------------------------------------------ */
-
- virtual int globalvariableHandler(Node *n) {
-
- generate_property_declaration_flag = true;
- variable_name = Getattr(n, "sym:name");
- global_variable_flag = true;
- int ret = Language::globalvariableHandler(n);
- global_variable_flag = false;
- generate_property_declaration_flag = false;
-
- if (proxy_flag) {
- Printf(module_class_code, "\n }\n\n");
- }
-
- return ret;
- }
-
- String *getCurrentScopeName(String *nspace) {
- String *scope = 0;
- if (nspace || getCurrentClass()) {
- scope = NewString("");
- if (nspace)
- Printf(scope, "%s", nspace);
- if (Node *cls = getCurrentClass()) {
- if (Node *outer = Getattr(cls, "nested:outer")) {
- String *outerClassesPrefix = Copy(Getattr(outer, "sym:name"));
- for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) {
- Push(outerClassesPrefix, ".");
- Push(outerClassesPrefix, Getattr(outer, "sym:name"));
- }
- Printv(scope, nspace ? "." : "", outerClassesPrefix, ".", proxy_class_name, NIL);
- Delete(outerClassesPrefix);
- } else
- Printv(scope, nspace ? "." : "", proxy_class_name, NIL);
- }
- }
- return scope;
- }
-
- /* ----------------------------------------------------------------------
- * enumDeclaration()
- *
- * C/C++ enums can be mapped in one of 4 ways, depending on the cs:enum feature specified:
- * 1) Simple enums - simple constant within the proxy class or module class
- * 2) Typeunsafe enums - simple constant in a C# class (class named after the c++ enum name)
- * 3) Typesafe enum - typesafe enum pattern (class named after the c++ enum name)
- * 4) Proper enums - proper C# enum
- * Anonymous enums always default to 1)
- * ---------------------------------------------------------------------- */
-
- virtual int enumDeclaration(Node *n) {
-
- if (!ImportMode) {
- if (getCurrentClass() && (cplus_mode != PUBLIC))
- return SWIG_NOWRAP;
-
- String *nspace = Getattr(n, "sym:nspace"); // NSpace/getNSpace() only works during Language::enumDeclaration call
- if (proxy_flag && !is_wrapping_class()) {
- // Global enums / enums in a namespace
- assert(!full_imclass_name);
-
- if (!nspace) {
- full_imclass_name = NewStringf("%s", imclass_name);
- } else {
- if (namespce) {
- full_imclass_name = NewStringf("%s.%s", namespce, imclass_name);
- } else {
- full_imclass_name = NewStringf("%s", imclass_name);
- }
- }
- }
-
- enum_code = NewString("");
- String *symname = Getattr(n, "sym:name");
- String *constants_code = (proxy_flag && is_wrapping_class())? proxy_class_constants_code : module_class_constants_code;
- EnumFeature enum_feature = decodeEnumFeature(n);
- String *typemap_lookup_type = Getattr(n, "name");
-
- if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
- // Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper C# enum
-
- String *scope = getCurrentScopeName(nspace);
- if (!addSymbol(symname, n, scope))
- return SWIG_ERROR;
-
- // Pure C# baseclass and interfaces
- const String *pure_baseclass = typemapLookup(n, "csbase", typemap_lookup_type, WARN_NONE);
- const String *pure_interfaces = typemapLookup(n, "csinterfaces", typemap_lookup_type, WARN_NONE);
-
- // Class attributes
- const String *csattributes = typemapLookup(n, "csattributes", typemap_lookup_type, WARN_NONE);
- if (csattributes && *Char(csattributes))
- Printf(enum_code, "%s\n", csattributes);
-
- // Emit the enum
- Printv(enum_code, typemapLookup(n, "csclassmodifiers", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers (enum modifiers really)
- " ", symname, (*Char(pure_baseclass) || *Char(pure_interfaces)) ? " : " : "", pure_baseclass, ((*Char(pure_baseclass)) && *Char(pure_interfaces)) ? // Interfaces
- ", " : "", pure_interfaces, " {\n", NIL);
- Delete(scope);
- } else {
- // Wrap C++ enum with integers - just indicate start of enum with a comment, no comment for anonymous enums of any sort
- if (symname && !Getattr(n, "unnamedinstance"))
- Printf(constants_code, " // %s \n", symname);
- }
-
- // Emit each enum item
- Language::enumDeclaration(n);
-
- if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
- // Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper C# enum
- // Finish the enum declaration
- // Typemaps are used to generate the enum definition in a similar manner to proxy classes.
- Printv(enum_code, (enum_feature == ProperEnum) ? "\n" : typemapLookup(n, "csbody", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF), // main body of class
- typemapLookup(n, "cscode", typemap_lookup_type, WARN_NONE), // extra C# code
- "}", NIL);
-
- Replaceall(enum_code, "$csclassname", symname);
-
- // Substitute $enumvalues - intended usage is for typesafe enums
- if (Getattr(n, "enumvalues"))
- Replaceall(enum_code, "$enumvalues", Getattr(n, "enumvalues"));
- else
- Replaceall(enum_code, "$enumvalues", "");
-
- if (proxy_flag && is_wrapping_class()) {
- // Enums defined within the C++ class are defined within the proxy class
-
- // Add extra indentation
- Replaceall(enum_code, "\n", "\n ");
- Replaceall(enum_code, " \n", "\n");
-
- Printv(proxy_class_constants_code, " ", enum_code, "\n\n", NIL);
- } else {
- // Global enums are defined in their own file
- String *output_directory = outputDirectory(nspace);
- File *f_enum = getOutputFile(output_directory, symname);
-
- addOpenNamespace(nspace, f_enum);
-
- Printv(f_enum, typemapLookup(n, "csimports", typemap_lookup_type, WARN_NONE), // Import statements
- "\n", enum_code, "\n", NIL);
-
- addCloseNamespace(nspace, f_enum);
- if (f_enum != f_single_out)
- Delete(f_enum);
- f_enum = NULL;
- Delete(output_directory);
- }
- } else {
- // Wrap C++ enum with simple constant
- Printf(enum_code, "\n");
- if (proxy_flag && is_wrapping_class())
- Printv(proxy_class_constants_code, enum_code, NIL);
- else
- Printv(module_class_constants_code, enum_code, NIL);
- }
-
- Delete(enum_code);
- enum_code = NULL;
-
- if (proxy_flag && !is_wrapping_class()) {
- Delete(full_imclass_name);
- full_imclass_name = 0;
- }
- }
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * enumvalueDeclaration()
- * ---------------------------------------------------------------------- */
-
- virtual int enumvalueDeclaration(Node *n) {
- if (getCurrentClass() && (cplus_mode != PUBLIC))
- return SWIG_NOWRAP;
-
- Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL);
- String *symname = Getattr(n, "sym:name");
- String *value = Getattr(n, "value");
- String *name = Getattr(n, "name");
- Node *parent = parentNode(n);
- int unnamedinstance = GetFlag(parent, "unnamedinstance");
- String *parent_name = Getattr(parent, "name");
- String *nspace = getNSpace();
- String *newsymname = 0;
- String *tmpValue;
-
- // Strange hack from parent method
- if (value)
- tmpValue = NewString(value);
- else
- tmpValue = NewString(name);
- // Note that this is used in enumValue() amongst other places
- Setattr(n, "value", tmpValue);
-
- // Deal with enum values that are not int
- int swigtype = SwigType_type(Getattr(n, "type"));
- if (swigtype == T_BOOL) {
- const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0";
- Setattr(n, "enumvalue", val);
- } else if (swigtype == T_CHAR) {
- String *val = NewStringf("'%(hexescape)s'", Getattr(n, "enumvalue"));
- Setattr(n, "enumvalue", val);
- Delete(val);
- }
-
- {
- EnumFeature enum_feature = decodeEnumFeature(parent);
-
- if ((enum_feature == SimpleEnum) && GetFlag(parent, "scopedenum")) {
- newsymname = Swig_name_member(0, Getattr(parent, "sym:name"), symname);
- symname = newsymname;
- }
-
- // Add to language symbol table
- String *scope = 0;
- if (unnamedinstance || !parent_name || enum_feature == SimpleEnum) {
- String *enumClassPrefix = getEnumClassPrefix();
- if (enumClassPrefix) {
- scope = NewString("");
- if (nspace)
- Printf(scope, "%s.", nspace);
- Printf(scope, "%s", enumClassPrefix);
- } else {
- scope = Copy(module_class_name);
- }
- } else {
- scope = getCurrentScopeName(nspace);
- if (!scope)
- scope = Copy(Getattr(parent, "sym:name"));
- else
- Printf(scope, ".%s", Getattr(parent, "sym:name"));
- }
- if (!addSymbol(symname, n, scope))
- return SWIG_ERROR;
-
- const String *csattributes = Getattr(n, "feature:cs:attributes");
-
- if ((enum_feature == ProperEnum) && parent_name && !unnamedinstance) {
- // Wrap (non-anonymous) C/C++ enum with a proper C# enum
- // Emit the enum item.
- if (!GetFlag(n, "firstenumitem"))
- Printf(enum_code, ",\n");
-
- if (csattributes)
- Printf(enum_code, " %s\n", csattributes);
-
- Printf(enum_code, " %s", symname);
-
- // Check for the %csconstvalue feature
- String *value = Getattr(n, "feature:cs:constvalue");
-
- // Note that the enum value must be a true constant and cannot be set from a PINVOKE call, thus no support for %csconst(0)
- value = value ? value : Getattr(n, "enumvalue");
- if (value) {
- Printf(enum_code, " = %s", value);
- }
- } else {
- // Wrap C/C++ enums with constant integers or use the typesafe enum pattern
- SwigType *typemap_lookup_type = parent_name ? parent_name : NewString("enum ");
- Setattr(n, "type", typemap_lookup_type);
- const String *tm = typemapLookup(n, "cstype", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF);
-
- String *return_type = Copy(tm);
- substituteClassname(typemap_lookup_type, return_type);
- const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
- methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
-
- if (csattributes)
- Printf(enum_code, " %s\n", csattributes);
-
- if ((enum_feature == TypesafeEnum) && parent_name && !unnamedinstance) {
- // Wrap (non-anonymous) enum using the typesafe enum pattern
- if (Getattr(n, "enumvalue")) {
- String *value = enumValue(n);
- Printf(enum_code, " %s static readonly %s %s = new %s(\"%s\", %s);\n", methodmods, return_type, symname, return_type, symname, value);
- Delete(value);
- } else {
- Printf(enum_code, " %s static readonly %s %s = new %s(\"%s\");\n", methodmods, return_type, symname, return_type, symname);
- }
- } else {
- // Simple integer constants
- // Note these are always generated for anonymous enums, no matter what enum_feature is specified
- // Code generated is the same for SimpleEnum and TypeunsafeEnum -> the class it is generated into is determined later
-
- // The %csconst feature determines how the constant value is obtained
- int const_feature_flag = GetFlag(n, "feature:cs:const");
-
- const char *const_readonly = const_feature_flag ? "const" : "static readonly";
- String *value = enumValue(n);
- Printf(enum_code, " %s %s %s %s = %s;\n", methodmods, const_readonly, return_type, symname, value);
- Delete(value);
- }
- Delete(return_type);
- }
-
- // Add the enum value to the comma separated list being constructed in the enum declaration.
- String *enumvalues = Getattr(parent, "enumvalues");
- if (!enumvalues)
- Setattr(parent, "enumvalues", Copy(symname));
- else
- Printv(enumvalues, ", ", symname, NIL);
- Delete(scope);
- }
-
- Delete(newsymname);
- Delete(tmpValue);
- Swig_restore(n);
- return SWIG_OK;
- }
-
- /* -----------------------------------------------------------------------
- * constantWrapper()
- * Used for wrapping constants - #define or %constant.
- * Also for inline initialised const static primitive type member variables (short, int, double, enums etc).
- * C# static const variables are generated for these.
- * If the %csconst(1) feature is used then the C constant value is used to initialise the C# const variable.
- * If not, a PINVOKE method is generated to get the C constant value for initialisation of the C# const variable.
- * However, if the %csconstvalue feature is used, it overrides all other ways to generate the initialisation.
- * Also note that this method might be called for wrapping enum items (when the enum is using %csconst(0)).
- * ------------------------------------------------------------------------ */
-
- virtual int constantWrapper(Node *n) {
- String *symname = Getattr(n, "sym:name");
- SwigType *t = Getattr(n, "type");
- SwigType *valuetype = Getattr(n, "valuetype");
- ParmList *l = Getattr(n, "parms");
- String *tm;
- String *return_type = NewString("");
- String *constants_code = NewString("");
- Swig_save("constantWrapper", n, "value", NIL);
- Swig_save("constantWrapper", n, "tmap:ctype:out", "tmap:imtype:out", "tmap:cstype:out", "tmap:out:null", "tmap:imtype:outattributes", "tmap:cstype:outattributes", NIL);
-
- bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0);
-
- const String *itemname = (proxy_flag && wrapping_member_flag) ? variable_name : symname;
- if (!is_enum_item) {
- String *scope = 0;
- if (proxy_class_name) {
- String *nspace = getNSpace();
- scope = NewString("");
- if (nspace)
- Printf(scope, "%s.", nspace);
- Printf(scope, "%s", proxy_class_name);
- } else {
- scope = Copy(module_class_name);
- }
- if (!addSymbol(itemname, n, scope))
- return SWIG_ERROR;
- Delete(scope);
- }
-
- // The %csconst feature determines how the constant value is obtained
- int const_feature_flag = GetFlag(n, "feature:cs:const");
-
- /* Adjust the enum type for the Swig_typemap_lookup.
- * We want the same jstype typemap for all the enum items so we use the enum type (parent node). */
- if (is_enum_item) {
- t = Getattr(parentNode(n), "enumtype");
- Setattr(n, "type", t);
- }
-
- /* Attach the non-standard typemaps to the parameter list. */
- Swig_typemap_attach_parms("cstype", l, NULL);
-
- /* Get C# return types */
- bool classname_substituted_flag = false;
-
- if ((tm = Swig_typemap_lookup("cstype", n, "", 0))) {
- String *cstypeout = Getattr(n, "tmap:cstype:out"); // the type in the cstype typemap's out attribute overrides the type in the typemap
- if (cstypeout)
- tm = cstypeout;
- classname_substituted_flag = substituteClassname(t, tm);
- Printf(return_type, "%s", tm);
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(t, 0));
- }
-
- // Default (octal) escaping is no good - change to hex escaped value
- String *hexescaped_value = Getattr(n, "rawvalue") ? NewStringf("%(hexescape)s", Getattr(n, "rawvalue")) : 0;
- // Add the stripped quotes back in
- String *new_value = NewString("");
- if (SwigType_type(t) == T_STRING) {
- Printf(new_value, "\"%s\"", hexescaped_value ? hexescaped_value : Copy(Getattr(n, "value")));
- Setattr(n, "value", new_value);
- } else if (SwigType_type(t) == T_CHAR) {
- Printf(new_value, "\'%s\'", hexescaped_value ? hexescaped_value : Copy(Getattr(n, "value")));
- Setattr(n, "value", new_value);
- }
-
- const String *outattributes = Getattr(n, "tmap:cstype:outattributes");
- if (outattributes)
- Printf(constants_code, " %s\n", outattributes);
-
- const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
- methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
-
- Printf(constants_code, " %s %s %s %s = ", methodmods, (const_feature_flag ? "const" : "static readonly"), return_type, itemname);
-
- // Check for the %csconstvalue feature
- String *value = Getattr(n, "feature:cs:constvalue");
-
- if (value) {
- Printf(constants_code, "%s;\n", value);
- } else if (!const_feature_flag) {
- // Default enum and constant handling will work with any type of C constant and initialises the C# variable from C through a PINVOKE call.
-
- if (classname_substituted_flag) {
- if (SwigType_isenum(t)) {
- // This handles wrapping of inline initialised const enum static member variables (not when wrapping enum items - ignored later on)
- Printf(constants_code, "(%s)%s.%s();\n", return_type, full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname));
- } else {
- // This handles function pointers using the %constant directive
- Printf(constants_code, "new %s(%s.%s(), false);\n", return_type, full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname));
- }
- } else {
- Printf(constants_code, "%s.%s();\n", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname));
- }
-
- // Each constant and enum value is wrapped with a separate PInvoke function call
- SetFlag(n, "feature:immutable");
- enum_constant_flag = true;
- variableWrapper(n);
- enum_constant_flag = false;
- } else {
- // Alternative constant handling will use the C syntax to make a true C# constant and hope that it compiles as C# code
- if (Getattr(n, "wrappedasconstant")) {
- if (SwigType_type(t) == T_CHAR) {
- if (SwigType_type(valuetype) == T_CHAR)
- Printf(constants_code, "\'%(hexescape)s\';\n", Getattr(n, "staticmembervariableHandler:value"));
- else
- Printf(constants_code, "(char)%s;\n", Getattr(n, "staticmembervariableHandler:value"));
- } else {
- Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value"));
- }
- } else {
- Printf(constants_code, "%s;\n", Getattr(n, "value"));
- }
- }
-
- // Emit the generated code to appropriate place
- // Enums only emit the intermediate and PINVOKE methods, so no proxy or module class wrapper methods needed
- if (!is_enum_item) {
- if (proxy_flag && wrapping_member_flag)
- Printv(proxy_class_constants_code, constants_code, NIL);
- else
- Printv(module_class_constants_code, constants_code, NIL);
- }
- // Cleanup
- Swig_restore(n);
- Delete(new_value);
- Delete(return_type);
- Delete(constants_code);
- return SWIG_OK;
- }
-
- /* -----------------------------------------------------------------------------
- * insertDirective()
- * ----------------------------------------------------------------------------- */
-
- virtual int insertDirective(Node *n) {
- int ret = SWIG_OK;
- String *code = Getattr(n, "code");
- String *section = Getattr(n, "section");
- Replaceall(code, "$module", module_class_name);
- Replaceall(code, "$imclassname", imclass_name);
- Replaceall(code, "$dllimport", dllimport);
-
- if (!ImportMode && (Cmp(section, "proxycode") == 0)) {
- if (proxy_class_code) {
- Swig_typemap_replace_embedded_typemap(code, n);
- int offset = Len(code) > 0 && *Char(code) == '\n' ? 1 : 0;
- Printv(proxy_class_code, Char(code) + offset, "\n", NIL);
- }
- } else {
- ret = Language::insertDirective(n);
- }
- return ret;
- }
-
- /* -----------------------------------------------------------------------------
- * pragmaDirective()
- *
- * Valid Pragmas:
- * imclassbase - base (extends) for the intermediary class
- * imclassclassmodifiers - class modifiers for the intermediary class
- * imclasscode - text (C# code) is copied verbatim to the intermediary class
- * imclassimports - import statements for the intermediary class
- * imclassinterfaces - interface (implements) for the intermediary class
- *
- * modulebase - base (extends) for the module class
- * moduleclassmodifiers - class modifiers for the module class
- * modulecode - text (C# code) is copied verbatim to the module class
- * moduleimports - import statements for the module class
- * moduleinterfaces - interface (implements) for the module class
- *
- * ----------------------------------------------------------------------------- */
-
- virtual int pragmaDirective(Node *n) {
- if (!ImportMode) {
- String *lang = Getattr(n, "lang");
- String *code = Getattr(n, "name");
- String *value = Getattr(n, "value");
-
- if (Strcmp(lang, "csharp") == 0) {
-
- String *strvalue = NewString(value);
- Replaceall(strvalue, "\\\"", "\"");
-
- if (Strcmp(code, "imclassbase") == 0) {
- Delete(imclass_baseclass);
- imclass_baseclass = Copy(strvalue);
- } else if (Strcmp(code, "imclassclassmodifiers") == 0) {
- Delete(imclass_class_modifiers);
- imclass_class_modifiers = Copy(strvalue);
- } else if (Strcmp(code, "imclasscode") == 0) {
- Printf(imclass_class_code, "%s\n", strvalue);
- } else if (Strcmp(code, "imclassimports") == 0) {
- Delete(imclass_imports);
- imclass_imports = Copy(strvalue);
- } else if (Strcmp(code, "imclassinterfaces") == 0) {
- Delete(imclass_interfaces);
- imclass_interfaces = Copy(strvalue);
- } else if (Strcmp(code, "modulebase") == 0) {
- Delete(module_baseclass);
- module_baseclass = Copy(strvalue);
- } else if (Strcmp(code, "moduleclassmodifiers") == 0) {
- Delete(module_class_modifiers);
- module_class_modifiers = Copy(strvalue);
- } else if (Strcmp(code, "modulecode") == 0) {
- Printf(module_class_code, "%s\n", strvalue);
- } else if (Strcmp(code, "moduleimports") == 0) {
- Delete(module_imports);
- module_imports = Copy(strvalue);
- } else if (Strcmp(code, "moduleinterfaces") == 0) {
- Delete(module_interfaces);
- module_interfaces = Copy(strvalue);
- } else {
- Swig_error(input_file, line_number, "Unrecognized pragma.\n");
- }
- Delete(strvalue);
- }
- }
- return Language::pragmaDirective(n);
- }
-
- /* -----------------------------------------------------------------------------
- * getQualifiedInterfaceName()
- * ----------------------------------------------------------------------------- */
-
- String *getQualifiedInterfaceName(Node *n) {
- String *ret = Getattr(n, "interface:qname");
- if (!ret) {
- String *nspace = Getattr(n, "sym:nspace");
- String *interface_name = Getattr(n, "interface:name");
- if (nspace) {
- if (namespce)
- ret = NewStringf("%s.%s.%s", namespce, nspace, interface_name);
- else
- ret = NewStringf("%s.%s", nspace, interface_name);
- } else {
- ret = Copy(interface_name);
- }
- Setattr(n, "interface:qname", ret);
- }
- return ret;
- }
-
- /* -----------------------------------------------------------------------------
- * getInterfaceName()
- * ----------------------------------------------------------------------------- */
-
- String *getInterfaceName(SwigType *t, bool qualified) {
- String *interface_name = NULL;
- if (proxy_flag) {
- Node *n = classLookup(t);
- if (n && Getattr(n, "interface:name"))
- interface_name = qualified ? getQualifiedInterfaceName(n) : Getattr(n, "interface:name");
- }
- return interface_name;
- }
-
- /* -----------------------------------------------------------------------------
- * addInterfaceNameAndUpcasts()
- * ----------------------------------------------------------------------------- */
-
- void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, List *base_list, SwigType *c_classname) {
- for (Iterator it = First(base_list); it.item; it = Next(it)) {
- Node *base = it.item;
- SwigType *c_baseclassname = Getattr(base, "name");
- String *interface_name = Getattr(base, "interface:name");
- if (Len(interface_list))
- Append(interface_list, ", ");
- Append(interface_list, interface_name);
-
- Node *attributes = NewHash();
- String *interface_code = Copy(typemapLookup(base, "csinterfacecode", Getattr(base, "classtypeobj"), WARN_CSHARP_TYPEMAP_INTERFACECODE_UNDEF, attributes));
- String *cptr_method_name = 0;
- if (interface_code) {
- Replaceall(interface_code, "$interfacename", interface_name);
- Printv(interface_upcasts, interface_code, NIL);
- cptr_method_name = Copy(Getattr(attributes, "tmap:csinterfacecode:cptrmethod"));
- }
- if (!cptr_method_name)
- cptr_method_name = NewStringf("%s_GetInterfaceCPtr", interface_name);
- Replaceall(cptr_method_name, ".", "_");
- Replaceall(cptr_method_name, "$interfacename", interface_name);
-
- String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), cptr_method_name);
- upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname);
-
- Delete(upcast_method_name);
- Delete(cptr_method_name);
- Delete(interface_code);
- }
- }
-
- /* -----------------------------------------------------------------------------
- * upcastsCode()
- *
- * Add code for C++ casting to base class
- * ----------------------------------------------------------------------------- */
-
- void upcastsCode(SwigType *smart, String *upcast_method_name, SwigType *c_classname, SwigType *c_baseclassname) {
- String *wname = Swig_name_wrapper(upcast_method_name);
-
- Printv(imclass_cppcasts_code, "\n [global::System.Runtime.InteropServices.DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL);
- Printf(imclass_cppcasts_code, " public static extern global::System.IntPtr %s(global::System.IntPtr jarg1);\n", upcast_method_name);
-
- Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name);
-
- String *classname = SwigType_namestr(c_classname);
- String *baseclassname = SwigType_namestr(c_baseclassname);
- if (smart) {
- String *smartnamestr = SwigType_namestr(smart);
- String *bsmartnamestr = SwigType_namestr(smart);
-
- // TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
- SwigType *rclassname = SwigType_typedef_resolve_all(classname);
- SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname);
- Replaceall(bsmartnamestr, rclassname, rbaseclassname);
-
- Printv(upcasts_code,
- "SWIGEXPORT ", bsmartnamestr, " * SWIGSTDCALL ", wname, "(", smartnamestr, " *jarg1) {\n",
- " return jarg1 ? new ", bsmartnamestr, "(*jarg1) : 0;\n"
- "}\n", "\n", NIL);
-
- Delete(rbaseclassname);
- Delete(rclassname);
- Delete(bsmartnamestr);
- Delete(smartnamestr);
- } else {
- Printv(upcasts_code,
- "SWIGEXPORT ", baseclassname, " * SWIGSTDCALL ", wname, "(", classname, " *jarg1) {\n",
- " return (", baseclassname, " *)jarg1;\n"
- "}\n", "\n", NIL);
- }
-
- Delete(baseclassname);
- Delete(classname);
- Delete(wname);
- }
-
- /* -----------------------------------------------------------------------------
- * emitProxyClassDefAndCPPCasts()
- * ----------------------------------------------------------------------------- */
-
- void emitProxyClassDefAndCPPCasts(Node *n) {
- SwigType *c_classname = Getattr(n, "name");
- SwigType *c_baseclassname = NULL;
- String *baseclass = NULL;
- String *interface_list = NewStringEmpty();
- String *interface_upcasts = NewStringEmpty();
- SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
- bool feature_director = Swig_directorclass(n) ? true : false;
- bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested");
- SwigType *smart = Swig_cparse_smartptr(n);
-
- // Inheritance from pure C# classes
- Node *attributes = NewHash();
- const String *pure_baseclass = typemapLookup(n, "csbase", typemap_lookup_type, WARN_NONE, attributes);
- bool purebase_replace = GetFlag(attributes, "tmap:csbase:replace") ? true : false;
- bool purebase_notderived = GetFlag(attributes, "tmap:csbase:notderived") ? true : false;
- Delete(attributes);
-
- // C++ inheritance
- if (!purebase_replace) {
- List *baselist = Getattr(n, "bases");
- if (baselist) {
- Iterator base = First(baselist);
- while (base.item) {
- if (!(GetFlag(base.item, "feature:ignore") || GetFlag(base.item, "feature:interface"))) {
- SwigType *baseclassname = Getattr(base.item, "name");
- if (!c_baseclassname) {
- String *name = getProxyName(baseclassname);
- if (name) {
- c_baseclassname = baseclassname;
- baseclass = name;
- }
- } else {
- /* Warn about multiple inheritance for additional base class(es) */
- String *proxyclassname = Getattr(n, "classtypeobj");
- Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
- "Warning for %s, base %s ignored. Multiple inheritance is not supported in C#.\n", SwigType_namestr(proxyclassname), SwigType_namestr(baseclassname));
- }
- }
- base = Next(base);
- }
- }
- }
- List *interface_bases = Getattr(n, "interface:bases");
- if (interface_bases)
- addInterfaceNameAndUpcasts(smart, interface_list, interface_upcasts, interface_bases, c_classname);
-
- bool derived = baseclass != 0;
- if (derived && purebase_notderived)
- pure_baseclass = empty_string;
- const String *wanted_base = baseclass ? baseclass : pure_baseclass;
-
- if (purebase_replace) {
- wanted_base = pure_baseclass;
- derived = false;
- baseclass = NULL;
- if (purebase_notderived)
- Swig_error(Getfile(n), Getline(n), "The csbase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", typemap_lookup_type);
- } else if (Len(pure_baseclass) > 0 && Len(baseclass) > 0) {
- Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
- "Warning for %s, base %s ignored. Multiple inheritance is not supported in C#. "
- "Perhaps you need one of the 'replace' or 'notderived' attributes in the csbase typemap?\n", typemap_lookup_type, pure_baseclass);
- }
-
- // Pure C# interfaces
- const String *pure_interfaces = typemapLookup(n, derived ? "csinterfaces_derived" : "csinterfaces", typemap_lookup_type, WARN_NONE);
- if (*Char(interface_list) && *Char(pure_interfaces))
- Append(interface_list, ", ");
- Append(interface_list, pure_interfaces);
- // Start writing the proxy class
- if (!has_outerclass)
- Printv(proxy_class_def, typemapLookup(n, "csimports", typemap_lookup_type, WARN_NONE), // Import statements
- "\n", NIL);
-
- // Class attributes
- const String *csattributes = typemapLookup(n, "csattributes", typemap_lookup_type, WARN_NONE);
- if (csattributes && *Char(csattributes))
- Printf(proxy_class_def, "%s\n", csattributes);
-
- Printv(proxy_class_def, typemapLookup(n, "csclassmodifiers", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
- " $csclassname", // Class name and base class
- (*Char(wanted_base) || *Char(interface_list)) ? " : " : "", wanted_base, (*Char(wanted_base) && *Char(interface_list)) ? // Interfaces
- ", " : "", interface_list, " {", derived ? typemapLookup(n, "csbody_derived", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF) : // main body of class
- typemapLookup(n, "csbody", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF), // main body of class
- NIL);
-
- // C++ destructor is wrapped by the Finalize and Dispose methods
-
- const char *tmap_method = derived ? "csdestruct_derived" : "csdestruct";
- const String *tm = typemapExists(n, tmap_method, typemap_lookup_type);
- if (tm) {
- Swig_error(Getfile(tm), Getline(tm),
- "A deprecated %s typemap was found for %s, please remove it and replace all csdestruct, csdestruct_derived and csfinalize typemaps by the csdispose, csdispose_derived, csdisposing and csdisposing_derived typemaps.\n",
- tmap_method, proxy_class_name);
- }
- tmap_method = "csfinalize";
- tm = typemapExists(n, tmap_method, typemap_lookup_type);
- if (tm) {
- Swig_error(Getfile(tm), Getline(tm),
- "A deprecated %s typemap was found for %s, please remove it and replace all csdestruct, csdestruct_derived and csfinalize typemaps by the csdispose, csdispose_derived, csdisposing and csdisposing_derived typemaps.\n",
- tmap_method, proxy_class_name);
- }
-
- tmap_method = derived ? "csdisposing_derived" : "csdisposing";
- String *destruct = NewString("");
- attributes = NewHash();
- const String *destruct_methodname = NULL;
- const String *destruct_methodmodifiers = NULL;
- const String *destruct_parameters = NULL;
- if (derived) {
- tm = typemapLookup(n, "csdisposing_derived", typemap_lookup_type, WARN_NONE, attributes);
- destruct_methodname = Getattr(attributes, "tmap:csdisposing_derived:methodname");
- destruct_methodmodifiers = Getattr(attributes, "tmap:csdisposing_derived:methodmodifiers");
- destruct_parameters = Getattr(attributes, "tmap:csdisposing_derived:parameters");
- } else {
- tm = typemapLookup(n, "csdisposing", typemap_lookup_type, WARN_NONE, attributes);
- destruct_methodname = Getattr(attributes, "tmap:csdisposing:methodname");
- destruct_methodmodifiers = Getattr(attributes, "tmap:csdisposing:methodmodifiers");
- destruct_parameters = Getattr(attributes, "tmap:csdisposing:parameters");
- }
- if (tm && *Char(tm)) {
- if (!destruct_methodname) {
- Swig_error(Getfile(n), Getline(n), "No methodname attribute defined in %s typemap for %s\n", tmap_method, proxy_class_name);
- }
- if (!destruct_methodmodifiers) {
- Swig_error(Getfile(n), Getline(n),
- "No methodmodifiers attribute defined in %s typemap for %s.\n", tmap_method, proxy_class_name);
- }
- if (!destruct_parameters)
- destruct_parameters = empty_string;
- }
- // Emit the Finalize and Dispose methods
- if (tm) {
- // Finalize and Dispose methods
- Printv(proxy_class_def, typemapLookup(n, derived ? "csdispose_derived" : "csdispose", typemap_lookup_type, WARN_NONE), NIL);
- // Dispose(bool disposing) method
- Printv(destruct, tm, NIL);
- if (*Char(destructor_call))
- Replaceall(destruct, "$imcall", destructor_call);
- else
- Replaceall(destruct, "$imcall", "throw new global::System.MethodAccessException(\"C++ destructor does not have public access\")");
- if (*Char(destruct)) {
- Printv(proxy_class_def, "\n ", NIL);
- const String *methodmods = Getattr(n, "destructmethodmodifiers");
- if (methodmods)
- Printv(proxy_class_def, methodmods, NIL);
- else
- Printv(proxy_class_def, destruct_methodmodifiers, " ", derived ? "override" : "virtual", NIL);
- Printv(proxy_class_def, " void ", destruct_methodname, "(", destruct_parameters, ") ", destruct, "\n", NIL);
- }
- }
- if (*Char(interface_upcasts))
- Printv(proxy_class_def, interface_upcasts, NIL);
-
- if (feature_director) {
- // Generate director connect method
- // put this in classDirectorEnd ???
- Printf(proxy_class_code, " private void SwigDirectorConnect() {\n");
-
- int i;
- for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
- UpcallData *udata = Getitem(dmethods_seq, i);
- String *method = Getattr(udata, "method");
- String *methid = Getattr(udata, "class_methodidx");
- String *overname = Getattr(udata, "overname");
- Printf(proxy_class_code, " if (SwigDerivedClassHasMethod(\"%s\", swigMethodTypes%s))\n", method, methid);
- Printf(proxy_class_code, " swigDelegate%s = new SwigDelegate%s_%s(SwigDirectorMethod%s);\n", methid, proxy_class_name, methid, overname);
- }
- String *director_connect_method_name = Swig_name_member(getNSpace(), getClassPrefix(), "director_connect");
- Printf(proxy_class_code, " %s.%s(swigCPtr", imclass_name, director_connect_method_name);
- for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
- UpcallData *udata = Getitem(dmethods_seq, i);
- String *methid = Getattr(udata, "class_methodidx");
- Printf(proxy_class_code, ", swigDelegate%s", methid);
- }
- Printf(proxy_class_code, ");\n");
- Printf(proxy_class_code, " }\n");
-
- if (first_class_dmethod < curr_class_dmethod) {
- // Only emit if there is at least one director method
- Printf(proxy_class_code, "\n");
- Printf(proxy_class_code, " private bool SwigDerivedClassHasMethod(string methodName, global::System.Type[] methodTypes) {\n");
- Printf(proxy_class_code, " global::System.Reflection.MethodInfo[] methodInfos = this.GetType().GetMethods(\n");
- Printf(proxy_class_code, " global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance);\n");
- Printf(proxy_class_code, " foreach (global::System.Reflection.MethodInfo methodInfo in methodInfos) {\n");
- Printf(proxy_class_code, " if (methodInfo.DeclaringType == null)\n");
- Printf(proxy_class_code, " continue;\n\n");
- Printf(proxy_class_code, " if (methodInfo.Name != methodName)\n");
- Printf(proxy_class_code, " continue;\n\n");
- Printf(proxy_class_code, " var parameters = methodInfo.GetParameters();\n");
- Printf(proxy_class_code, " if (parameters.Length != methodTypes.Length)\n");
- Printf(proxy_class_code, " continue;\n\n");
- Printf(proxy_class_code, " bool parametersMatch = true;\n");
- Printf(proxy_class_code, " for (var i = 0; i < parameters.Length; i++) {\n");
- Printf(proxy_class_code, " if (parameters[i].ParameterType != methodTypes[i]) {\n");
- Printf(proxy_class_code, " parametersMatch = false;\n");
- Printf(proxy_class_code, " break;\n");
- Printf(proxy_class_code, " }\n");
- Printf(proxy_class_code, " }\n\n");
- Printf(proxy_class_code, " if (!parametersMatch)\n");
- Printf(proxy_class_code, " continue;\n\n");
- Printf(proxy_class_code, " if (methodInfo.IsVirtual && (methodInfo.DeclaringType.IsSubclassOf(typeof(%s))) &&\n", proxy_class_name);
- Printf(proxy_class_code, " methodInfo.DeclaringType != methodInfo.GetBaseDefinition().DeclaringType) {\n");
- Printf(proxy_class_code, " return true;\n");
- Printf(proxy_class_code, " }\n");
- Printf(proxy_class_code, " }\n\n");
- Printf(proxy_class_code, " return false;\n");
-
- /* Could add this code to cover corner case where the GetMethod() returns a method which allows type
- * promotion, eg it will return foo(double), if looking for foo(int).
- if (hasDerivedMethod) {
- hasDerivedMethod = false;
- if (methodInfo != null)
- {
- hasDerivedMethod = true;
- ParameterInfo[] parameterArray1 = methodInfo.GetParameters();
- for (int i=0; i<methodTypes.Length; i++)
- {
- if (parameterArray1[0].ParameterType != methodTypes[0])
- {
- hasDerivedMethod = false;
- break;
- }
- }
- }
- }
- */
- //Printf(proxy_class_code, " return hasDerivedMethod;\n");
- Printf(proxy_class_code, " }\n");
- }
-
- if (Len(director_delegate_callback) > 0)
- Printv(proxy_class_code, director_delegate_callback, NIL);
- if (Len(director_delegate_definitions) > 0)
- Printv(proxy_class_code, "\n", director_delegate_definitions, NIL);
- if (Len(director_delegate_instances) > 0)
- Printv(proxy_class_code, "\n", director_delegate_instances, NIL);
- if (Len(director_method_types) > 0)
- Printv(proxy_class_code, "\n", director_method_types, NIL);
-
- Delete(director_callback_typedefs);
- director_callback_typedefs = NULL;
- Delete(director_callbacks);
- director_callbacks = NULL;
- Delete(director_delegate_callback);
- director_delegate_callback = NULL;
- Delete(director_delegate_definitions);
- director_delegate_definitions = NULL;
- Delete(director_delegate_instances);
- director_delegate_instances = NULL;
- Delete(director_method_types);
- director_method_types = NULL;
- Delete(director_connect_parms);
- director_connect_parms = NULL;
- Delete(director_connect_method_name);
- }
-
- Delete(interface_upcasts);
- Delete(interface_list);
- Delete(attributes);
- Delete(destruct);
-
- // Emit extra user code
- Printv(proxy_class_def, typemapLookup(n, "cscode", typemap_lookup_type, WARN_NONE), // extra C# code
- "\n", NIL);
-
- if (derived) {
- String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), smart != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast");
- upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname);
- Delete(upcast_method_name);
- }
-
- Delete(smart);
- }
-
- /* ----------------------------------------------------------------------
- * emitInterfaceDeclaration()
- * ---------------------------------------------------------------------- */
-
- void emitInterfaceDeclaration(Node *n, String *interface_name, File *f_interface) {
- Printv(f_interface, typemapLookup(n, "csimports", Getattr(n, "classtypeobj"), WARN_NONE), "\n", NIL);
- Printv(f_interface, typemapLookup(n, "csinterfacemodifiers", Getattr(n, "classtypeobj"), WARN_CSHARP_TYPEMAP_INTERFACEMODIFIERS_UNDEF), NIL);
- Printf(f_interface, " %s", interface_name);
- if (List *baselist = Getattr(n, "bases")) {
- String *bases = 0;
- for (Iterator base = First(baselist); base.item; base = Next(base)) {
- if (GetFlag(base.item, "feature:ignore") || !GetFlag(base.item, "feature:interface"))
- continue; // TODO: warn about skipped non-interface bases
- String *base_iname = Getattr(base.item, "interface:name");
- if (!bases)
- bases = NewStringf(" : %s", base_iname);
- else {
- Append(bases, ", ");
- Append(bases, base_iname);
- }
- }
- if (bases) {
- Printv(f_interface, bases, NIL);
- Delete(bases);
- }
- }
- Printf(f_interface, " {\n");
-
- Node *attributes = NewHash();
- String *interface_code = Copy(typemapLookup(n, "csinterfacecode", Getattr(n, "classtypeobj"), WARN_CSHARP_TYPEMAP_INTERFACECODE_UNDEF, attributes));
- if (interface_code) {
- String *interface_declaration = Copy(Getattr(attributes, "tmap:csinterfacecode:declaration"));
- if (interface_declaration) {
- Replaceall(interface_declaration, "$interfacename", interface_name);
- Printv(f_interface, interface_declaration, NIL);
- Delete(interface_declaration);
- }
- Delete(interface_code);
- }
- }
-
- /* ----------------------------------------------------------------------
- * classHandler()
- * ---------------------------------------------------------------------- */
-
- virtual int classHandler(Node *n) {
- String *nspace = getNSpace();
- File *f_proxy = NULL;
- File *f_interface = NULL;
- // save class local variables
- String *old_proxy_class_name = proxy_class_name;
- String *old_full_imclass_name = full_imclass_name;
- String *old_destructor_call = destructor_call;
- String *old_proxy_class_constants_code = proxy_class_constants_code;
- String *old_proxy_class_def = proxy_class_def;
- String *old_proxy_class_code = proxy_class_code;
- bool has_outerclass = Getattr(n, "nested:outer") && !GetFlag(n, "feature:flatnested");
- String *old_interface_class_code = interface_class_code;
- interface_class_code = 0;
-
- if (proxy_flag) {
- proxy_class_name = NewString(Getattr(n, "sym:name"));
- String *interface_name = GetFlag(n, "feature:interface") ? Getattr(n, "interface:name") : 0;
- if (Node *outer = Getattr(n, "nested:outer")) {
- String *outerClassesPrefix = Copy(Getattr(outer, "sym:name"));
- for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) {
- Push(outerClassesPrefix, ".");
- Push(outerClassesPrefix, Getattr(outer, "sym:name"));
- }
- String *fnspace = nspace ? NewStringf("%s.%s", nspace, outerClassesPrefix) : outerClassesPrefix;
- if (!addSymbol(proxy_class_name, n, fnspace))
- return SWIG_ERROR;
- if (interface_name && !addInterfaceSymbol(interface_name, n, fnspace))
- return SWIG_ERROR;
- if (nspace)
- Delete(fnspace);
- Delete(outerClassesPrefix);
- } else {
- if (!addSymbol(proxy_class_name, n, nspace))
- return SWIG_ERROR;
- if (interface_name && !addInterfaceSymbol(interface_name, n, nspace))
- return SWIG_ERROR;
- }
-
- if (!nspace) {
- full_imclass_name = NewStringf("%s", imclass_name);
- if (Cmp(proxy_class_name, imclass_name) == 0) {
- Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name);
- Exit(EXIT_FAILURE);
- }
-
- if (Cmp(proxy_class_name, module_class_name) == 0) {
- Printf(stderr, "Class name cannot be equal to module class name: %s\n", proxy_class_name);
- Exit(EXIT_FAILURE);
- }
- } else {
- if (namespce) {
- full_imclass_name = NewStringf("%s.%s", namespce, imclass_name);
- } else {
- full_imclass_name = NewStringf("%s", imclass_name);
- }
- }
-
- if (!has_outerclass) {
- String *output_directory = outputDirectory(nspace);
- f_proxy = getOutputFile(output_directory, proxy_class_name);
-
- addOpenNamespace(nspace, f_proxy);
- Delete(output_directory);
- }
- else
- ++nesting_depth;
-
- proxy_class_def = NewString("");
- proxy_class_code = NewString("");
- destructor_call = NewString("");
- proxy_class_constants_code = NewString("");
-
- if (GetFlag(n, "feature:interface")) {
- interface_class_code = NewString("");
- String *output_directory = outputDirectory(nspace);
- f_interface = getOutputFile(output_directory, interface_name);
- addOpenNamespace(nspace, f_interface);
- emitInterfaceDeclaration(n, interface_name, interface_class_code);
- Delete(output_directory);
- }
- }
-
- Language::classHandler(n);
-
- if (proxy_flag) {
-
- emitProxyClassDefAndCPPCasts(n);
-
- String *csclazzname = Swig_name_member(getNSpace(), getClassPrefix(), ""); // mangled full proxy class name
-
- Replaceall(proxy_class_def, "$csclassname", proxy_class_name);
- Replaceall(proxy_class_code, "$csclassname", proxy_class_name);
- Replaceall(proxy_class_constants_code, "$csclassname", proxy_class_name);
- Replaceall(interface_class_code, "$csclassname", proxy_class_name);
-
- Replaceall(proxy_class_def, "$csclazzname", csclazzname);
- Replaceall(proxy_class_code, "$csclazzname", csclazzname);
- Replaceall(proxy_class_constants_code, "$csclazzname", csclazzname);
- Replaceall(interface_class_code, "$csclazzname", csclazzname);
-
- Replaceall(proxy_class_def, "$module", module_class_name);
- Replaceall(proxy_class_code, "$module", module_class_name);
- Replaceall(proxy_class_constants_code, "$module", module_class_name);
- Replaceall(interface_class_code, "$module", module_class_name);
-
- Replaceall(proxy_class_def, "$imclassname", full_imclass_name);
- Replaceall(proxy_class_code, "$imclassname", full_imclass_name);
- Replaceall(proxy_class_constants_code, "$imclassname", full_imclass_name);
- Replaceall(interface_class_code, "$imclassname", full_imclass_name);
-
- Replaceall(proxy_class_def, "$dllimport", dllimport);
- Replaceall(proxy_class_code, "$dllimport", dllimport);
- Replaceall(proxy_class_constants_code, "$dllimport", dllimport);
- Replaceall(interface_class_code, "$dllimport", dllimport);
-
- if (!has_outerclass)
- Printv(f_proxy, proxy_class_def, proxy_class_code, NIL);
- else {
- Swig_offset_string(proxy_class_def, nesting_depth);
- Append(old_proxy_class_code, proxy_class_def);
- Swig_offset_string(proxy_class_code, nesting_depth);
- Append(old_proxy_class_code, proxy_class_code);
- }
-
- // Write out all the constants
- if (Len(proxy_class_constants_code) != 0) {
- if (!has_outerclass)
- Printv(f_proxy, proxy_class_constants_code, NIL);
- else {
- Swig_offset_string(proxy_class_constants_code, nesting_depth);
- Append(old_proxy_class_code, proxy_class_constants_code);
- }
- }
- if (!has_outerclass) {
- Printf(f_proxy, "}\n");
- addCloseNamespace(nspace, f_proxy);
- if (f_proxy != f_single_out)
- Delete(f_proxy);
- f_proxy = NULL;
- } else {
- for (int i = 0; i < nesting_depth; ++i)
- Append(old_proxy_class_code, " ");
- Append(old_proxy_class_code, "}\n\n");
- --nesting_depth;
- }
-
- if (f_interface) {
- Printv(f_interface, interface_class_code, "}\n", NIL);
- addCloseNamespace(nspace, f_interface);
- if (f_interface != f_single_out)
- Delete(f_interface);
- f_interface = 0;
- }
-
- emitDirectorExtraMethods(n);
-
- Delete(interface_class_code);
- interface_class_code = old_interface_class_code;
- Delete(csclazzname);
- Delete(proxy_class_name);
- proxy_class_name = old_proxy_class_name;
- Delete(full_imclass_name);
- full_imclass_name = old_full_imclass_name;
- Delete(destructor_call);
- destructor_call = old_destructor_call;
- Delete(proxy_class_constants_code);
- proxy_class_constants_code = old_proxy_class_constants_code;
- Delete(proxy_class_def);
- proxy_class_def = old_proxy_class_def;
- Delete(proxy_class_code);
- proxy_class_code = old_proxy_class_code;
- }
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * memberfunctionHandler()
- * ---------------------------------------------------------------------- */
-
- virtual int memberfunctionHandler(Node *n) {
- Language::memberfunctionHandler(n);
-
- if (proxy_flag) {
- String *overloaded_name = getOverloadedName(n);
- String *intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name);
- Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
- Setattr(n, "imfuncname", intermediary_function_name);
- proxyClassFunctionHandler(n);
- Delete(overloaded_name);
- }
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * staticmemberfunctionHandler()
- * ---------------------------------------------------------------------- */
-
- virtual int staticmemberfunctionHandler(Node *n) {
-
- static_flag = true;
- Language::staticmemberfunctionHandler(n);
-
- if (proxy_flag) {
- String *overloaded_name = getOverloadedName(n);
- String *intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name);
- Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
- Setattr(n, "imfuncname", intermediary_function_name);
- proxyClassFunctionHandler(n);
- Delete(overloaded_name);
- }
- static_flag = false;
-
- return SWIG_OK;
- }
-
-
- /* -----------------------------------------------------------------------------
- * proxyClassFunctionHandler()
- *
- * Function called for creating a C# wrapper function around a c++ function in the
- * proxy class. Used for both static and non-static C++ class functions.
- * C++ class static functions map to C# static functions.
- * Two extra attributes in the Node must be available. These are "proxyfuncname" -
- * the name of the C# class proxy function, which in turn will call "imfuncname" -
- * the intermediary (PInvoke) function name in the intermediary class.
- * ----------------------------------------------------------------------------- */
-
- void proxyClassFunctionHandler(Node *n) {
- SwigType *t = Getattr(n, "type");
- ParmList *l = Getattr(n, "parms");
- String *intermediary_function_name = Getattr(n, "imfuncname");
- String *proxy_function_name = Getattr(n, "proxyfuncname");
- String *tm;
- Parm *p;
- Parm *last_parm = 0;
- int i;
- String *imcall = NewString("");
- String *return_type = NewString("");
- String *function_code = NewString("");
- bool setter_flag = false;
- String *pre_code = NewString("");
- String *post_code = NewString("");
- String *terminator_code = NewString("");
- bool is_interface = GetFlag(parentNode(n), "feature:interface") && !checkAttribute(n, "kind", "variable")
- && !static_flag && Getattr(n, "interface:owner") == 0;
-
- if (!proxy_flag)
- return;
-
- // Wrappers not wanted for some methods where the parameters cannot be overloaded in C#
- if (Getattr(n, "overload:ignore"))
- return;
-
- // Don't generate proxy method for additional explicitcall method used in directors
- if (GetFlag(n, "explicitcall"))
- return;
-
- if (l) {
- if (SwigType_type(Getattr(l, "type")) == T_VOID) {
- l = nextSibling(l);
- }
- }
-
- /* Attach the non-standard typemaps to the parameter list */
- Swig_typemap_attach_parms("in", l, NULL);
- Swig_typemap_attach_parms("cstype", l, NULL);
- Swig_typemap_attach_parms("csin", l, NULL);
-
- /* Get return types */
- if ((tm = Swig_typemap_lookup("cstype", n, "", 0))) {
- // Note that in the case of polymorphic (covariant) return types, the method's return type is changed to be the base of the C++ return type
- SwigType *covariant = Getattr(n, "covariant");
- String *cstypeout = Getattr(n, "tmap:cstype:out"); // the type in the cstype typemap's out attribute overrides the type in the typemap
- if (cstypeout)
- tm = cstypeout;
- substituteClassname(covariant ? covariant : t, tm);
- Printf(return_type, "%s", tm);
- if (covariant)
- Swig_warning(WARN_CSHARP_COVARIANT_RET, input_file, line_number,
- "Covariant return types not supported in C#. Proxy method will return %s.\n", SwigType_str(covariant, 0));
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(t, 0));
- }
-
- if (wrapping_member_flag && !enum_constant_flag) {
- // Properties
- setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), Swig_name_member(0, getClassPrefix(), variable_name))) == 0);
- if (setter_flag)
- Swig_typemap_attach_parms("csvarin", l, NULL);
- }
-
- /* Start generating the proxy function */
- const String *outattributes = Getattr(n, "tmap:cstype:outattributes");
- if (outattributes)
- Printf(function_code, " %s\n", outattributes);
- const String *csattributes = Getattr(n, "feature:cs:attributes");
- if (csattributes)
- Printf(function_code, " %s\n", csattributes);
- const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
- if (methodmods) {
- if (is_smart_pointer()) {
- // Smart pointer classes do not mirror the inheritance hierarchy of the underlying pointer type, so no virtual/override/new required.
- String *mmods = Copy(methodmods);
- Replaceall(mmods, "override", "");
- Replaceall(mmods, "virtual", "");
- Replaceall(mmods, "new", "");
- Chop(mmods); // remove trailing whitespace
- Printf(function_code, " %s ", mmods);
- Delete(mmods);
- } else {
- Printf(function_code, " %s ", methodmods);
- }
- } else {
- methodmods = (is_public(n) ? public_string : protected_string);
- Printf(function_code, " %s ", methodmods);
- if (!is_smart_pointer()) {
- // Smart pointer classes do not mirror the inheritance hierarchy of the underlying pointer type, so no virtual/override/new required.
- if (Getattr(n, "override"))
- Printf(function_code, "override ");
- else if (checkAttribute(n, "storage", "virtual"))
- Printf(function_code, "virtual ");
- if (Getattr(n, "hides"))
- Printf(function_code, "new ");
- }
- }
- if (static_flag)
- Printf(function_code, "static ");
- Printf(function_code, "%s %s(", return_type, proxy_function_name);
- if (is_interface)
- Printf(interface_class_code, " %s %s(", return_type, proxy_function_name);
-
-
- Printv(imcall, full_imclass_name, ".$imfuncname(", NIL);
- if (!static_flag)
- Printf(imcall, "swigCPtr");
-
- emit_mark_varargs(l);
-
- int gencomma = !static_flag;
-
- /* Output each parameter */
- for (i = 0, p = l; p; i++) {
-
- /* Ignored varargs */
- if (checkAttribute(p, "varargs:ignore", "1")) {
- p = nextSibling(p);
- continue;
- }
-
- /* Ignored parameters */
- if (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- continue;
- }
-
- /* Ignore the 'this' argument for variable wrappers */
- if (!(variable_wrapper_flag && i == 0)) {
- SwigType *pt = Getattr(p, "type");
- String *param_type = NewString("");
- if (setter_flag)
- last_parm = p;
-
- /* Get the C# parameter type */
- if ((tm = Getattr(p, "tmap:cstype"))) {
- substituteClassname(pt, tm);
- const String *inattributes = Getattr(p, "tmap:cstype:inattributes");
- Printf(param_type, "%s%s", inattributes ? inattributes : empty_string, tm);
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- if (gencomma)
- Printf(imcall, ", ");
-
- String *arg = makeParameterName(n, p, i, setter_flag);
-
- // Use typemaps to transform type used in C# wrapper function (in proxy class) to type used in PInvoke function (in intermediary class)
- if ((tm = Getattr(p, "tmap:csin"))) {
- substituteClassname(pt, tm);
- Replaceall(tm, "$csinput", arg);
- String *pre = Getattr(p, "tmap:csin:pre");
- if (pre) {
- substituteClassname(pt, pre);
- Replaceall(pre, "$csinput", arg);
- if (Len(pre_code) > 0)
- Printf(pre_code, "\n");
- Printv(pre_code, pre, NIL);
- }
- String *post = Getattr(p, "tmap:csin:post");
- if (post) {
- substituteClassname(pt, post);
- Replaceall(post, "$csinput", arg);
- if (Len(post_code) > 0)
- Printf(post_code, "\n");
- Printv(post_code, post, NIL);
- }
- String *terminator = Getattr(p, "tmap:csin:terminator");
- if (terminator) {
- substituteClassname(pt, terminator);
- Replaceall(terminator, "$csinput", arg);
- if (Len(terminator_code) > 0)
- Insert(terminator_code, 0, "\n");
- Insert(terminator_code, 0, terminator);
- }
- Printv(imcall, tm, NIL);
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number, "No csin typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- /* Add parameter to proxy function */
- if (gencomma >= 2) {
- Printf(function_code, ", ");
- if (is_interface)
- Printf(interface_class_code, ", ");
- }
- gencomma = 2;
- Printf(function_code, "%s %s", param_type, arg);
- if (is_interface)
- Printf(interface_class_code, "%s %s", param_type, arg);
-
- Delete(arg);
- Delete(param_type);
- }
- p = Getattr(p, "tmap:in:next");
- }
-
- Printf(imcall, ")");
- Printf(function_code, ")");
- if (is_interface)
- Printf(interface_class_code, ");\n");
-
- // Transform return type used in PInvoke function (in intermediary class) to type used in C# wrapper function (in proxy class)
- if ((tm = Swig_typemap_lookup("csout", n, "", 0))) {
- excodeSubstitute(n, tm, "csout", n);
- bool is_pre_code = Len(pre_code) > 0;
- bool is_post_code = Len(post_code) > 0;
- bool is_terminator_code = Len(terminator_code) > 0;
- if (is_pre_code || is_post_code || is_terminator_code) {
- Replaceall(tm, "\n ", "\n "); // add extra indentation to code in typemap
- if (is_post_code) {
- Insert(tm, 0, "\n try ");
- Printv(tm, " finally {\n", post_code, "\n }", NIL);
- } else {
- Insert(tm, 0, "\n ");
- }
- if (is_pre_code) {
- Insert(tm, 0, pre_code);
- Insert(tm, 0, "\n");
- }
- if (is_terminator_code) {
- Printv(tm, "\n", terminator_code, NIL);
- }
- Insert(tm, 0, "{");
- Printf(tm, "\n }");
- }
- if (GetFlag(n, "feature:new"))
- Replaceall(tm, "$owner", "true");
- else
- Replaceall(tm, "$owner", "false");
- substituteClassname(t, tm);
-
- // For director methods: generate code to selectively make a normal polymorphic call or
- // an explicit method call - needed to prevent infinite recursion calls in director methods.
- Node *explicit_n = Getattr(n, "explicitcallnode");
- if (explicit_n) {
- String *ex_overloaded_name = getOverloadedName(explicit_n);
- String *ex_intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), ex_overloaded_name);
-
- String *ex_imcall = Copy(imcall);
- Replaceall(ex_imcall, "$imfuncname", ex_intermediary_function_name);
- Replaceall(imcall, "$imfuncname", intermediary_function_name);
- String *excode = NewString("");
- Node *directorNode = Getattr(n, "directorNode");
- UpcallData *udata = directorNode ? Getattr(directorNode, "upcalldata") : 0;
- if (udata) {
- String *methid = Getattr(udata, "class_methodidx");
-
- if (!Cmp(return_type, "void"))
- Printf(excode, "if (SwigDerivedClassHasMethod(\"%s\", swigMethodTypes%s)) %s; else %s", proxy_function_name, methid, ex_imcall, imcall);
- else
- Printf(excode, "(SwigDerivedClassHasMethod(\"%s\", swigMethodTypes%s) ? %s : %s)", proxy_function_name, methid, ex_imcall, imcall);
-
- Clear(imcall);
- Printv(imcall, excode, NIL);
- } else {
- // probably an ignored method or nodirector
- }
- Delete(excode);
- Delete(ex_overloaded_name);
- } else {
- Replaceall(imcall, "$imfuncname", intermediary_function_name);
- }
- Replaceall(tm, "$imfuncname", intermediary_function_name);
- Replaceall(tm, "$imcall", imcall);
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t, 0));
- }
-
- if (wrapping_member_flag && !enum_constant_flag) {
- // Properties
- if (generate_property_declaration_flag) { // Ensure the declaration is generated just once should the property contain both a set and get
- // Get the C# variable type - obtained differently depending on whether a setter is required.
- String *variable_type = return_type;
- if (setter_flag) {
- assert(last_parm); // (last parameter is the only parameter for properties)
- /* Get variable type - ensure the variable name is fully resolved during typemap lookup via the symbol table set in NewParmNode */
- SwigType *cvariable_type = Getattr(last_parm, "type");
- Parm *variable_parm = NewParmNode(cvariable_type, n);
- if ((tm = Swig_typemap_lookup("cstype", variable_parm, "", 0))) {
- String *cstypeout = Getattr(variable_parm, "tmap:cstype:out"); // the type in the cstype typemap's out attribute overrides the type in the typemap
- if (cstypeout)
- tm = cstypeout;
- substituteClassname(cvariable_type, tm);
- variable_type = tm;
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(cvariable_type, 0));
- }
- }
- const String *csattributes = Getattr(n, "feature:cs:attributes");
- if (csattributes)
- Printf(proxy_class_code, " %s\n", csattributes);
- const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
- if (!methodmods)
- methodmods = (is_public(n) ? public_string : protected_string);
- Printf(proxy_class_code, " %s %s%s %s {", methodmods, static_flag ? "static " : "", variable_type, variable_name);
- }
- generate_property_declaration_flag = false;
-
- if (setter_flag) {
- // Setter method
- assert(last_parm); // (last parameter is the only parameter for properties)
- SwigType *cvariable_type = Getattr(last_parm, "type");
- Parm *variable_parm = NewParmNode(cvariable_type, n);
- if ((tm = Swig_typemap_lookup("csvarin", variable_parm, "", 0))) {
- substituteClassname(cvariable_type, tm);
- Replaceall(tm, "$csinput", "value");
- Replaceall(tm, "$imfuncname", intermediary_function_name);
- Replaceall(tm, "$imcall", imcall);
- excodeSubstitute(n, tm, "csvarin", variable_parm);
- Printf(proxy_class_code, "%s", tm);
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csvarin typemap defined for %s\n", SwigType_str(cvariable_type, 0));
- }
- } else {
- // Getter method
- if ((tm = Swig_typemap_lookup("csvarout", n, "", 0))) {
- if (GetFlag(n, "feature:new"))
- Replaceall(tm, "$owner", "true");
- else
- Replaceall(tm, "$owner", "false");
- substituteClassname(t, tm);
- Replaceall(tm, "$imfuncname", intermediary_function_name);
- Replaceall(tm, "$imcall", imcall);
- excodeSubstitute(n, tm, "csvarout", n);
- Printf(proxy_class_code, "%s", tm);
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csvarout typemap defined for %s\n", SwigType_str(t, 0));
- }
- }
- } else {
- // Normal function call
- Printf(function_code, " %s\n\n", tm ? (const String *) tm : empty_string);
- Printv(proxy_class_code, function_code, NIL);
- }
-
- Delete(pre_code);
- Delete(post_code);
- Delete(terminator_code);
- Delete(function_code);
- Delete(return_type);
- Delete(imcall);
- }
-
- /* ----------------------------------------------------------------------
- * constructorHandler()
- * ---------------------------------------------------------------------- */
-
- virtual int constructorHandler(Node *n) {
-
- ParmList *l = Getattr(n, "parms");
- String *tm;
- Parm *p;
- int i;
- String *function_code = NewString("");
- String *helper_code = NewString(""); // Holds code for the constructor helper method generated only when the csin typemap has code in the pre or post attributes
- String *helper_args = NewString("");
- String *pre_code = NewString("");
- String *post_code = NewString("");
- String *terminator_code = NewString("");
- String *im_return_type = NewString("");
- bool feature_director = (parentNode(n) && Swig_directorclass(n));
-
- Language::constructorHandler(n);
-
- // Wrappers not wanted for some methods where the parameters cannot be overloaded in C#
- if (Getattr(n, "overload:ignore"))
- return SWIG_OK;
-
- if (proxy_flag) {
- String *overloaded_name = getOverloadedName(n);
- String *mangled_overname = Swig_name_construct(getNSpace(), overloaded_name);
- String *imcall = NewString("");
-
- const String *csattributes = Getattr(n, "feature:cs:attributes");
- if (csattributes) {
- Printf(function_code, " %s\n", csattributes);
- Printf(helper_code, " %s\n", csattributes);
- }
- const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
- methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
-
- tm = Getattr(n, "tmap:imtype"); // typemaps were attached earlier to the node
- String *imtypeout = Getattr(n, "tmap:imtype:out"); // the type in the imtype typemap's out attribute overrides the type in the typemap
- if (imtypeout)
- tm = imtypeout;
- Printf(im_return_type, "%s", tm);
-
- Printf(function_code, " %s %s(", methodmods, proxy_class_name);
- Printf(helper_code, " static private %s SwigConstruct%s(", im_return_type, proxy_class_name);
-
- Printv(imcall, full_imclass_name, ".", mangled_overname, "(", NIL);
-
- /* Attach the non-standard typemaps to the parameter list */
- Swig_typemap_attach_parms("in", l, NULL);
- Swig_typemap_attach_parms("cstype", l, NULL);
- Swig_typemap_attach_parms("csin", l, NULL);
-
- emit_mark_varargs(l);
-
- int gencomma = 0;
-
- /* Output each parameter */
- for (i = 0, p = l; p; i++) {
-
- /* Ignored varargs */
- if (checkAttribute(p, "varargs:ignore", "1")) {
- p = nextSibling(p);
- continue;
- }
-
- /* Ignored parameters */
- if (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- continue;
- }
-
- SwigType *pt = Getattr(p, "type");
- String *param_type = NewString("");
-
- /* Get the C# parameter type */
- if ((tm = Getattr(p, "tmap:cstype"))) {
- substituteClassname(pt, tm);
- const String *inattributes = Getattr(p, "tmap:cstype:inattributes");
- Printf(param_type, "%s%s", inattributes ? inattributes : empty_string, tm);
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- if (gencomma)
- Printf(imcall, ", ");
-
- String *arg = makeParameterName(n, p, i, false);
- String *cshin = 0;
-
- // Use typemaps to transform type used in C# wrapper function (in proxy class) to type used in PInvoke function (in intermediary class)
- if ((tm = Getattr(p, "tmap:csin"))) {
- substituteClassname(pt, tm);
- Replaceall(tm, "$csinput", arg);
- String *pre = Getattr(p, "tmap:csin:pre");
- if (pre) {
- substituteClassname(pt, pre);
- Replaceall(pre, "$csinput", arg);
- if (Len(pre_code) > 0)
- Printf(pre_code, "\n");
- Printv(pre_code, pre, NIL);
- }
- String *post = Getattr(p, "tmap:csin:post");
- if (post) {
- substituteClassname(pt, post);
- Replaceall(post, "$csinput", arg);
- if (Len(post_code) > 0)
- Printf(post_code, "\n");
- Printv(post_code, post, NIL);
- }
- String *terminator = Getattr(p, "tmap:csin:terminator");
- if (terminator) {
- substituteClassname(pt, terminator);
- Replaceall(terminator, "$csinput", arg);
- if (Len(terminator_code) > 0)
- Insert(terminator_code, 0, "\n");
- Insert(terminator_code, 0, terminator);
- }
- cshin = Getattr(p, "tmap:csin:cshin");
- if (cshin)
- Replaceall(cshin, "$csinput", arg);
- Printv(imcall, tm, NIL);
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number, "No csin typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- /* Add parameter to proxy function */
- if (gencomma) {
- Printf(function_code, ", ");
- Printf(helper_code, ", ");
- Printf(helper_args, ", ");
- }
- Printf(function_code, "%s %s", param_type, arg);
- Printf(helper_code, "%s %s", param_type, arg);
- Printf(helper_args, "%s", cshin ? cshin : arg);
- ++gencomma;
-
- Delete(cshin);
- Delete(arg);
- Delete(param_type);
- p = Getattr(p, "tmap:in:next");
- }
-
- Printf(imcall, ")");
-
- Printf(function_code, ")");
- Printf(helper_code, ")");
-
- /* Insert the csconstruct typemap, doing the replacement for $directorconnect, as needed */
- Hash *attributes = NewHash();
- String *typemap_lookup_type = Getattr(getCurrentClass(), "classtypeobj");
- String *construct_tm = Copy(typemapLookup(n, "csconstruct", typemap_lookup_type,
- WARN_CSHARP_TYPEMAP_CSCONSTRUCT_UNDEF, attributes));
- if (construct_tm) {
- if (!feature_director) {
- Replaceall(construct_tm, "$directorconnect", "");
- } else {
- String *connect_attr = Getattr(attributes, "tmap:csconstruct:directorconnect");
-
- if (connect_attr) {
- Replaceall(construct_tm, "$directorconnect", connect_attr);
- } else {
- Swig_warning(WARN_CSHARP_NO_DIRECTORCONNECT_ATTR, input_file, line_number, "\"directorconnect\" attribute missing in %s \"csconstruct\" typemap.\n",
- Getattr(n, "name"));
- Replaceall(construct_tm, "$directorconnect", "");
- }
- }
-
- Printv(function_code, " ", construct_tm, NIL);
- }
-
- excodeSubstitute(n, function_code, "csconstruct", attributes);
-
- bool is_pre_code = Len(pre_code) > 0;
- bool is_post_code = Len(post_code) > 0;
- bool is_terminator_code = Len(terminator_code) > 0;
- if (is_pre_code || is_post_code || is_terminator_code) {
- Printf(helper_code, " {\n");
- if (is_pre_code) {
- Printv(helper_code, pre_code, "\n", NIL);
- }
- if (is_post_code) {
- Printf(helper_code, " try {\n");
- Printv(helper_code, " return ", imcall, ";\n", NIL);
- Printv(helper_code, " } finally {\n", post_code, "\n }", NIL);
- } else {
- Printv(helper_code, " return ", imcall, ";", NIL);
- }
- if (is_terminator_code) {
- Printv(helper_code, "\n", terminator_code, NIL);
- }
- Printf(helper_code, "\n }\n");
- String *helper_name = NewStringf("%s.SwigConstruct%s(%s)", proxy_class_name, proxy_class_name, helper_args);
- String *im_outattributes = Getattr(n, "tmap:imtype:outattributes");
- if (im_outattributes)
- Printf(proxy_class_code, " %s\n", im_outattributes);
- Printv(proxy_class_code, helper_code, "\n", NIL);
- Replaceall(function_code, "$imcall", helper_name);
- Delete(helper_name);
- } else {
- Replaceall(function_code, "$imcall", imcall);
- }
-
- Printv(proxy_class_code, function_code, "\n", NIL);
-
- Delete(helper_args);
- Delete(im_return_type);
- Delete(pre_code);
- Delete(post_code);
- Delete(terminator_code);
- Delete(construct_tm);
- Delete(attributes);
- Delete(overloaded_name);
- Delete(imcall);
- }
-
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * destructorHandler()
- * ---------------------------------------------------------------------- */
-
- virtual int destructorHandler(Node *n) {
- Language::destructorHandler(n);
- String *symname = Getattr(n, "sym:name");
-
- if (proxy_flag) {
- Printv(destructor_call, full_imclass_name, ".", Swig_name_destroy(getNSpace(), symname), "(swigCPtr)", NIL);
- const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
- if (methodmods)
- Setattr(getCurrentClass(), "destructmethodmodifiers", methodmods);
- }
-
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * membervariableHandler()
- * ---------------------------------------------------------------------- */
-
- virtual int membervariableHandler(Node *n) {
-
- generate_property_declaration_flag = true;
- variable_name = Getattr(n, "sym:name");
- wrapping_member_flag = true;
- variable_wrapper_flag = true;
- Language::membervariableHandler(n);
- wrapping_member_flag = false;
- variable_wrapper_flag = false;
- generate_property_declaration_flag = false;
-
- Printf(proxy_class_code, "\n }\n\n");
-
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * staticmembervariableHandler()
- * ---------------------------------------------------------------------- */
-
- virtual int staticmembervariableHandler(Node *n) {
-
- bool static_const_member_flag = (Getattr(n, "value") == 0);
-
- generate_property_declaration_flag = true;
- variable_name = Getattr(n, "sym:name");
- wrapping_member_flag = true;
- static_flag = true;
- Language::staticmembervariableHandler(n);
- wrapping_member_flag = false;
- static_flag = false;
- generate_property_declaration_flag = false;
-
- if (static_const_member_flag)
- Printf(proxy_class_code, "\n }\n\n");
-
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * memberconstantHandler()
- * ---------------------------------------------------------------------- */
-
- virtual int memberconstantHandler(Node *n) {
- variable_name = Getattr(n, "sym:name");
- wrapping_member_flag = true;
- Language::memberconstantHandler(n);
- wrapping_member_flag = false;
- return SWIG_OK;
- }
-
- /* -----------------------------------------------------------------------------
- * getOverloadedName()
- * ----------------------------------------------------------------------------- */
-
- String *getOverloadedName(Node *n) {
-
- /* A C# HandleRef is used for all classes in the SWIG intermediary class.
- * The intermediary class methods are thus mangled when overloaded to give
- * a unique name. */
- String *overloaded_name = NewStringf("%s", Getattr(n, "sym:name"));
-
- if (Getattr(n, "sym:overloaded")) {
- Printv(overloaded_name, Getattr(n, "sym:overname"), NIL);
- }
-
- return overloaded_name;
- }
-
- /* -----------------------------------------------------------------------------
- * moduleClassFunctionHandler()
- * ----------------------------------------------------------------------------- */
-
- void moduleClassFunctionHandler(Node *n) {
- SwigType *t = Getattr(n, "type");
- ParmList *l = Getattr(n, "parms");
- String *tm;
- Parm *p;
- Parm *last_parm = 0;
- int i;
- String *imcall = NewString("");
- String *return_type = NewString("");
- String *function_code = NewString("");
- int num_arguments = 0;
- String *overloaded_name = getOverloadedName(n);
- String *func_name = NULL;
- bool setter_flag = false;
- String *pre_code = NewString("");
- String *post_code = NewString("");
- String *terminator_code = NewString("");
-
- if (l) {
- if (SwigType_type(Getattr(l, "type")) == T_VOID) {
- l = nextSibling(l);
- }
- }
-
- /* Attach the non-standard typemaps to the parameter list */
- Swig_typemap_attach_parms("cstype", l, NULL);
- Swig_typemap_attach_parms("csin", l, NULL);
-
- /* Get return types */
- if ((tm = Swig_typemap_lookup("cstype", n, "", 0))) {
- String *cstypeout = Getattr(n, "tmap:cstype:out"); // the type in the cstype typemap's out attribute overrides the type in the typemap
- if (cstypeout)
- tm = cstypeout;
- substituteClassname(t, tm);
- Printf(return_type, "%s", tm);
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(t, 0));
- }
-
- /* Change function name for global variables */
- if (proxy_flag && global_variable_flag) {
- // Capitalize the first letter in the variable to create the getter/setter function name
- func_name = NewString("");
- setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), variable_name)) == 0);
- if (setter_flag)
- Printf(func_name, "set");
- else
- Printf(func_name, "get");
- Putc(toupper((int) *Char(variable_name)), func_name);
- Printf(func_name, "%s", Char(variable_name) + 1);
- if (setter_flag)
- Swig_typemap_attach_parms("csvarin", l, NULL);
- } else {
- func_name = Copy(Getattr(n, "sym:name"));
- }
-
- /* Start generating the function */
- const String *outattributes = Getattr(n, "tmap:cstype:outattributes");
- if (outattributes)
- Printf(function_code, " %s\n", outattributes);
- const String *csattributes = Getattr(n, "feature:cs:attributes");
- if (csattributes)
- Printf(function_code, " %s\n", csattributes);
- const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
- methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
- Printf(function_code, " %s static %s %s(", methodmods, return_type, func_name);
- Printv(imcall, imclass_name, ".", overloaded_name, "(", NIL);
-
- /* Get number of required and total arguments */
- num_arguments = emit_num_arguments(l);
-
- bool global_or_member_variable = global_variable_flag || (wrapping_member_flag && !enum_constant_flag);
- int gencomma = 0;
-
- /* Output each parameter */
- for (i = 0, p = l; i < num_arguments; i++) {
-
- /* Ignored parameters */
- while (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- }
-
- SwigType *pt = Getattr(p, "type");
- String *param_type = NewString("");
- last_parm = p;
-
- /* Get the C# parameter type */
- if ((tm = Getattr(p, "tmap:cstype"))) {
- substituteClassname(pt, tm);
- const String *inattributes = Getattr(p, "tmap:cstype:inattributes");
- Printf(param_type, "%s%s", inattributes ? inattributes : empty_string, tm);
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- if (gencomma)
- Printf(imcall, ", ");
-
- String *arg = makeParameterName(n, p, i, global_or_member_variable);
-
- // Use typemaps to transform type used in C# wrapper function (in proxy class) to type used in PInvoke function (in intermediary class)
- if ((tm = Getattr(p, "tmap:csin"))) {
- substituteClassname(pt, tm);
- Replaceall(tm, "$csinput", arg);
- String *pre = Getattr(p, "tmap:csin:pre");
- if (pre) {
- substituteClassname(pt, pre);
- Replaceall(pre, "$csinput", arg);
- if (Len(pre_code) > 0)
- Printf(pre_code, "\n");
- Printv(pre_code, pre, NIL);
- }
- String *post = Getattr(p, "tmap:csin:post");
- if (post) {
- substituteClassname(pt, post);
- Replaceall(post, "$csinput", arg);
- if (Len(post_code) > 0)
- Printf(post_code, "\n");
- Printv(post_code, post, NIL);
- }
- String *terminator = Getattr(p, "tmap:csin:terminator");
- if (terminator) {
- substituteClassname(pt, terminator);
- Replaceall(terminator, "$csinput", arg);
- if (Len(terminator_code) > 0)
- Insert(terminator_code, 0, "\n");
- Insert(terminator_code, 0, terminator);
- }
- Printv(imcall, tm, NIL);
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number, "No csin typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- /* Add parameter to module class function */
- if (gencomma >= 2)
- Printf(function_code, ", ");
- gencomma = 2;
- Printf(function_code, "%s %s", param_type, arg);
-
- p = Getattr(p, "tmap:in:next");
- Delete(arg);
- Delete(param_type);
- }
-
- Printf(imcall, ")");
- Printf(function_code, ")");
-
- // Transform return type used in PInvoke function (in intermediary class) to type used in C# wrapper function (in module class)
- if ((tm = Swig_typemap_lookup("csout", n, "", 0))) {
- excodeSubstitute(n, tm, "csout", n);
- bool is_pre_code = Len(pre_code) > 0;
- bool is_post_code = Len(post_code) > 0;
- bool is_terminator_code = Len(terminator_code) > 0;
- if (is_pre_code || is_post_code || is_terminator_code) {
- Replaceall(tm, "\n ", "\n "); // add extra indentation to code in typemap
- if (is_post_code) {
- Insert(tm, 0, "\n try ");
- Printv(tm, " finally {\n", post_code, "\n }", NIL);
- } else {
- Insert(tm, 0, "\n ");
- }
- if (is_pre_code) {
- Insert(tm, 0, pre_code);
- Insert(tm, 0, "\n");
- }
- if (is_terminator_code) {
- Printv(tm, "\n", terminator_code, NIL);
- }
- Insert(tm, 0, "{");
- Printf(tm, "\n }");
- }
- if (GetFlag(n, "feature:new"))
- Replaceall(tm, "$owner", "true");
- else
- Replaceall(tm, "$owner", "false");
- substituteClassname(t, tm);
- Replaceall(tm, "$imfuncname", overloaded_name);
- Replaceall(tm, "$imcall", imcall);
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t, 0));
- }
-
- if (proxy_flag && global_variable_flag) {
- // Properties
- if (generate_property_declaration_flag) { // Ensure the declaration is generated just once should the property contain both a set and get
- // Get the C# variable type - obtained differently depending on whether a setter is required.
- String *variable_type = return_type;
- if (setter_flag) {
- p = last_parm; // (last parameter is the only parameter for properties)
- SwigType *pt = Getattr(p, "type");
- if ((tm = Getattr(p, "tmap:cstype"))) {
- substituteClassname(pt, tm);
- String *cstypeout = Getattr(p, "tmap:cstype:out"); // the type in the cstype typemap's out attribute overrides the type in the typemap
- variable_type = cstypeout ? cstypeout : tm;
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csvarin typemap defined for %s\n", SwigType_str(pt, 0));
- }
- }
- const String *csattributes = Getattr(n, "feature:cs:attributes");
- if (csattributes)
- Printf(module_class_code, " %s\n", csattributes);
- const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
- if (!methodmods)
- methodmods = (is_public(n) ? public_string : protected_string);
- Printf(module_class_code, " %s static %s %s {", methodmods, variable_type, variable_name);
- }
- generate_property_declaration_flag = false;
-
- if (setter_flag) {
- // Setter method
- p = last_parm; // (last parameter is the only parameter for properties)
- SwigType *pt = Getattr(p, "type");
- if ((tm = Getattr(p, "tmap:csvarin"))) {
- substituteClassname(pt, tm);
- Replaceall(tm, "$csinput", "value");
- Replaceall(tm, "$imfuncname", overloaded_name);
- Replaceall(tm, "$imcall", imcall);
- excodeSubstitute(n, tm, "csvarin", p);
- Printf(module_class_code, "%s", tm);
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csvarin typemap defined for %s\n", SwigType_str(pt, 0));
- }
- } else {
- // Getter method
- if ((tm = Swig_typemap_lookup("csvarout", n, "", 0))) {
- if (GetFlag(n, "feature:new"))
- Replaceall(tm, "$owner", "true");
- else
- Replaceall(tm, "$owner", "false");
- substituteClassname(t, tm);
- Replaceall(tm, "$imfuncname", overloaded_name);
- Replaceall(tm, "$imcall", imcall);
- excodeSubstitute(n, tm, "csvarout", n);
- Printf(module_class_code, "%s", tm);
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csvarout typemap defined for %s\n", SwigType_str(t, 0));
- }
- }
- } else {
- // Normal function call
- Printf(function_code, " %s\n\n", tm ? (const String *) tm : empty_string);
- Printv(module_class_code, function_code, NIL);
- }
-
- Delete(pre_code);
- Delete(post_code);
- Delete(terminator_code);
- Delete(function_code);
- Delete(return_type);
- Delete(imcall);
- Delete(func_name);
- }
-
- /*----------------------------------------------------------------------
- * replaceSpecialVariables()
- *--------------------------------------------------------------------*/
-
- virtual void replaceSpecialVariables(String *method, String *tm, Parm *parm) {
- (void)method;
- SwigType *type = Getattr(parm, "type");
- substituteClassname(type, tm);
- }
-
- /*----------------------------------------------------------------------
- * decodeEnumFeature()
- * Decode the possible enum features, which are one of:
- * %csenum(simple)
- * %csenum(typeunsafe) - default
- * %csenum(typesafe)
- * %csenum(proper)
- *--------------------------------------------------------------------*/
-
- EnumFeature decodeEnumFeature(Node *n) {
- EnumFeature enum_feature = TypeunsafeEnum;
- String *feature = Getattr(n, "feature:cs:enum");
- if (feature) {
- if (Cmp(feature, "simple") == 0)
- enum_feature = SimpleEnum;
- else if (Cmp(feature, "typesafe") == 0)
- enum_feature = TypesafeEnum;
- else if (Cmp(feature, "proper") == 0)
- enum_feature = ProperEnum;
- }
- return enum_feature;
- }
-
- /* -----------------------------------------------------------------------
- * enumValue()
- * This method will return a string with an enum value to use in C# generated
- * code. If the %csconst feature is not used, the string will contain the intermediary
- * class call to obtain the enum value. The intermediary class and PINVOKE methods to obtain
- * the enum value will be generated. Otherwise the C/C++ enum value will be used if there
- * is one and hopefully it will compile as C# code - e.g. 20 as in: enum E{e=20};
- * The %csconstvalue feature overrides all other ways to generate the constant value.
- * The caller must delete memory allocated for the returned string.
- * ------------------------------------------------------------------------ */
-
- String *enumValue(Node *n) {
- String *symname = Getattr(n, "sym:name");
-
- // Check for the %csconstvalue feature
- String *value = Getattr(n, "feature:cs:constvalue");
-
- if (!value) {
- // The %csconst feature determines how the constant value is obtained
- int const_feature_flag = GetFlag(n, "feature:cs:const");
-
- if (const_feature_flag) {
- // Use the C syntax to make a true C# constant and hope that it compiles as C# code
- value = Getattr(n, "enumvalue") ? Copy(Getattr(n, "enumvalue")) : Copy(Getattr(n, "enumvalueex"));
- } else {
- String *newsymname = 0;
- if (!getCurrentClass() || !proxy_flag) {
- String *enumClassPrefix = getEnumClassPrefix();
- if (enumClassPrefix) {
- // A global scoped enum
- newsymname = Swig_name_member(0, enumClassPrefix, symname);
- symname = newsymname;
- }
- }
-
- // Get the enumvalue from a PINVOKE call
- if (!getCurrentClass() || !cparse_cplusplus || !proxy_flag) {
- // Strange hack to change the name
- Setattr(n, "name", Getattr(n, "value")); /* for wrapping of enums in a namespace when emit_action is used */
- constantWrapper(n);
- value = NewStringf("%s.%s()", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname));
- } else {
- memberconstantHandler(n);
- value = NewStringf("%s.%s()", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), Swig_name_member(0, getEnumClassPrefix(), symname)));
- }
- }
- }
- return value;
- }
-
- /* -----------------------------------------------------------------------------
- * getEnumName()
- * ----------------------------------------------------------------------------- */
-
- String *getEnumName(SwigType *t) {
- Node *enumname = NULL;
- Node *n = enumLookup(t);
- if (n) {
- enumname = Getattr(n, "enumname");
- if (!enumname) {
- String *symname = Getattr(n, "sym:name");
- if (symname) {
- // Add in class scope when referencing enum if not a global enum
- String *scopename_prefix = Swig_scopename_prefix(Getattr(n, "name"));
- String *proxyname = 0;
- if (scopename_prefix) {
- proxyname = getProxyName(scopename_prefix);
- }
- if (proxyname) {
- enumname = NewStringf("%s.%s", proxyname, symname);
- } else {
- // global enum or enum in a namespace
- String *nspace = Getattr(n, "sym:nspace");
- if (nspace) {
- if (namespce)
- enumname = NewStringf("%s.%s.%s", namespce, nspace, symname);
- else
- enumname = NewStringf("%s.%s", nspace, symname);
- } else {
- enumname = Copy(symname);
- }
- }
- Setattr(n, "enumname", enumname);
- Delete(enumname);
- Delete(scopename_prefix);
- }
- }
- }
-
- return enumname;
- }
-
- /* -----------------------------------------------------------------------------
- * substituteClassname()
- *
- * Substitute the special variable $csclassname with the proxy class name for classes/structs/unions
- * that SWIG knows about. Also substitutes enums with enum name.
- * Otherwise use the $descriptor name for the C# class name. Note that the $&csclassname substitution
- * is the same as a $&descriptor substitution, ie one pointer added to descriptor name.
- * Inputs:
- * pt - parameter type
- * tm - typemap contents that might contain the special variable to be replaced
- * Outputs:
- * tm - typemap contents complete with the special variable substitution
- * Return:
- * substitution_performed - flag indicating if a substitution was performed
- * ----------------------------------------------------------------------------- */
-
- bool substituteClassname(SwigType *pt, String *tm) {
- bool substitution_performed = false;
- SwigType *type = Copy(SwigType_typedef_resolve_all(pt));
- SwigType *strippedtype = SwigType_strip_qualifiers(type);
-
- if (Strstr(tm, "$csclassname")) {
- SwigType *classnametype = Copy(strippedtype);
- substituteClassnameSpecialVariable(classnametype, tm, "$csclassname");
- substitution_performed = true;
- Delete(classnametype);
- }
- if (Strstr(tm, "$*csclassname")) {
- SwigType *classnametype = Copy(strippedtype);
- Delete(SwigType_pop(classnametype));
- if (Len(classnametype) > 0) {
- substituteClassnameSpecialVariable(classnametype, tm, "$*csclassname");
- substitution_performed = true;
- }
- Delete(classnametype);
- }
- if (Strstr(tm, "$&csclassname")) {
- SwigType *classnametype = Copy(strippedtype);
- SwigType_add_pointer(classnametype);
- substituteClassnameSpecialVariable(classnametype, tm, "$&csclassname");
- substitution_performed = true;
- Delete(classnametype);
- }
- if (Strstr(tm, "$csinterfacename")) {
- SwigType *interfacenametype = Copy(strippedtype);
- substituteInterfacenameSpecialVariable(interfacenametype, tm, "$csinterfacename", true);
- substitution_performed = true;
- Delete(interfacenametype);
- }
- if (Strstr(tm, "$*csinterfacename")) {
- SwigType *interfacenametype = Copy(strippedtype);
- Delete(SwigType_pop(interfacenametype));
- if (Len(interfacenametype) > 0) {
- substituteInterfacenameSpecialVariable(interfacenametype, tm, "$*csinterfacename", true);
- substitution_performed = true;
- }
- Delete(interfacenametype);
- }
- if (Strstr(tm, "$&csinterfacename")) {
- SwigType *interfacenametype = Copy(strippedtype);
- SwigType_add_pointer(interfacenametype);
- substituteInterfacenameSpecialVariable(interfacenametype, tm, "$&csinterfacename", true);
- substitution_performed = true;
- Delete(interfacenametype);
- }
- if (Strstr(tm, "$interfacename")) {
- SwigType *interfacenametype = Copy(strippedtype);
- substituteInterfacenameSpecialVariable(interfacenametype, tm, "$interfacename", false);
- substitution_performed = true;
- Delete(interfacenametype);
- }
- if (Strstr(tm, "$*interfacename")) {
- SwigType *interfacenametype = Copy(strippedtype);
- Delete(SwigType_pop(interfacenametype));
- if (Len(interfacenametype) > 0) {
- substituteInterfacenameSpecialVariable(interfacenametype, tm, "$*interfacename", false);
- substitution_performed = true;
- }
- Delete(interfacenametype);
- }
- if (Strstr(tm, "$&interfacename")) {
- SwigType *interfacenametype = Copy(strippedtype);
- SwigType_add_pointer(interfacenametype);
- substituteInterfacenameSpecialVariable(interfacenametype, tm, "$&interfacename", false);
- substitution_performed = true;
- Delete(interfacenametype);
- }
-
- Delete(strippedtype);
- Delete(type);
-
- return substitution_performed;
- }
-
- /* -----------------------------------------------------------------------------
- * substituteClassnameSpecialVariable()
- * ----------------------------------------------------------------------------- */
-
- void substituteClassnameSpecialVariable(SwigType *classnametype, String *tm, const char *classnamespecialvariable) {
- String *replacementname;
- if (SwigType_isenum(classnametype)) {
- String *enumname = getEnumName(classnametype);
- if (enumname) {
- replacementname = Copy(enumname);
- } else {
- bool anonymous_enum = (Cmp(classnametype, "enum ") == 0);
- if (anonymous_enum) {
- replacementname = NewString("int");
- } else {
- // An unknown enum - one that has not been parsed (neither a C enum forward reference nor a definition) or an ignored enum
- replacementname = NewStringf("SWIGTYPE%s", SwigType_manglestr(classnametype));
- Replace(replacementname, "enum ", "", DOH_REPLACE_ANY);
- Setattr(swig_types_hash, replacementname, classnametype);
- }
- }
- } else {
- String *classname = getProxyName(classnametype); // getProxyName() works for pointers to classes too
- if (classname) {
- replacementname = Copy(classname);
- } else {
- // use $descriptor if SWIG does not know anything about this type. Note that any typedefs are resolved.
- replacementname = NewStringf("SWIGTYPE%s", SwigType_manglestr(classnametype));
-
- // Add to hash table so that the type wrapper classes can be created later
- Setattr(swig_types_hash, replacementname, classnametype);
- }
- }
- Replaceall(tm, classnamespecialvariable, replacementname);
-
- Delete(replacementname);
- }
-
- /* -----------------------------------------------------------------------------
- * substituteInterfacenameSpecialVariable()
- * ----------------------------------------------------------------------------- */
-
- void substituteInterfacenameSpecialVariable(SwigType *interfacenametype, String *tm, const char *interfacenamespecialvariable, bool qualified) {
-
- String *interfacename = getInterfaceName(interfacenametype, qualified);
- if (interfacename) {
- String *replacementname = Copy(interfacename);
- Replaceall(tm, interfacenamespecialvariable, replacementname);
- Delete(replacementname);
- }
- }
-
- /* -----------------------------------------------------------------------------
- * emitTypeWrapperClass()
- * ----------------------------------------------------------------------------- */
-
- void emitTypeWrapperClass(String *classname, SwigType *type) {
- Node *n = NewHash();
- Setfile(n, input_file);
- Setline(n, line_number);
-
- String *swigtype = NewString("");
- File *f_swigtype = getOutputFile(SWIG_output_directory(), classname);
-
- addOpenNamespace(0, f_swigtype);
-
- // Pure C# baseclass and interfaces
- const String *pure_baseclass = typemapLookup(n, "csbase", type, WARN_NONE);
- const String *pure_interfaces = typemapLookup(n, "csinterfaces", type, WARN_NONE);
-
- // Emit the class
- Printv(swigtype, typemapLookup(n, "csimports", type, WARN_NONE), // Import statements
- "\n", NIL);
-
- // Class attributes
- const String *csattributes = typemapLookup(n, "csattributes", type, WARN_NONE);
- if (csattributes && *Char(csattributes))
- Printf(swigtype, "%s\n", csattributes);
-
- Printv(swigtype, typemapLookup(n, "csclassmodifiers", type, WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
- " $csclassname", // Class name and base class
- (*Char(pure_baseclass) || *Char(pure_interfaces)) ? " : " : "", pure_baseclass, ((*Char(pure_baseclass)) && *Char(pure_interfaces)) ? // Interfaces
- ", " : "", pure_interfaces, " {", typemapLookup(n, "csbody", type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF), // main body of class
- typemapLookup(n, "cscode", type, WARN_NONE), // extra C# code
- "}\n", NIL);
-
- Replaceall(swigtype, "$csclassname", classname);
- Replaceall(swigtype, "$module", module_class_name);
- Replaceall(swigtype, "$imclassname", imclass_name);
- Replaceall(swigtype, "$dllimport", dllimport);
-
- // For unknown enums
- Replaceall(swigtype, "$enumvalues", "");
-
- Printv(f_swigtype, swigtype, NIL);
-
- addCloseNamespace(0, f_swigtype);
- if (f_swigtype != f_single_out)
- Delete(f_swigtype);
- f_swigtype = NULL;
- Delete(swigtype);
- Delete(n);
- }
-
- /* -----------------------------------------------------------------------------
- * typemapLookup()
- * n - for input only and must contain info for Getfile(n) and Getline(n) to work
- * tmap_method - typemap method name
- * type - typemap type to lookup
- * warning - warning number to issue if no typemaps found
- * typemap_attributes - the typemap attributes are attached to this node and will
- * also be used for temporary storage if non null
- * return is never NULL, unlike Swig_typemap_lookup()
- * ----------------------------------------------------------------------------- */
-
- const String *typemapLookup(Node *n, const_String_or_char_ptr tmap_method, SwigType *type, int warning, Node *typemap_attributes = 0) {
- Node *node = !typemap_attributes ? NewHash() : typemap_attributes;
- Setattr(node, "type", type);
- Setfile(node, Getfile(n));
- Setline(node, Getline(n));
- const String *tm = Swig_typemap_lookup(tmap_method, node, "", 0);
- if (!tm) {
- tm = empty_string;
- if (warning != WARN_NONE)
- Swig_warning(warning, Getfile(n), Getline(n), "No %s typemap defined for %s\n", tmap_method, SwigType_str(type, 0));
- }
- if (!typemap_attributes)
- Delete(node);
- return tm;
- }
-
- /* -----------------------------------------------------------------------------
- * typemapExists()
- * n - for input only and must contain info for Getfile(n) and Getline(n) to work
- * tmap_method - typemap method name
- * type - typemap type to lookup
- * returns found typemap or NULL if not found
- * ----------------------------------------------------------------------------- */
-
- const String *typemapExists(Node *n, const_String_or_char_ptr tmap_method, SwigType *type) {
- Node *node = NewHash();
- Setattr(node, "type", type);
- Setfile(node, Getfile(n));
- Setline(node, Getline(n));
- const String *tm = Swig_typemap_lookup(tmap_method, node, "", 0);
- Delete(node);
- return tm;
- }
-
- /* -----------------------------------------------------------------------------
- * canThrow()
- * Determine whether the code in the typemap can throw a C# exception.
- * If so, note it for later when excodeSubstitute() is called.
- * ----------------------------------------------------------------------------- */
-
- void canThrow(Node *n, const String *typemap, Node *parameter) {
- String *canthrow_attribute = NewStringf("tmap:%s:canthrow", typemap);
- String *canthrow = Getattr(parameter, canthrow_attribute);
- if (canthrow)
- Setattr(n, "csharp:canthrow", "1");
- Delete(canthrow_attribute);
- }
-
- /* -----------------------------------------------------------------------------
- * excodeSubstitute()
- * If a method can throw a C# exception, additional exception code is added to
- * check for the pending exception so that it can then throw the exception. The
- * $excode special variable is replaced by the exception code in the excode
- * typemap attribute.
- * ----------------------------------------------------------------------------- */
-
- void excodeSubstitute(Node *n, String *code, const String *typemap, Node *parameter) {
- String *excode_attribute = NewStringf("tmap:%s:excode", typemap);
- String *excode = Getattr(parameter, excode_attribute);
- if (Getattr(n, "csharp:canthrow")) {
- int count = Replaceall(code, "$excode", excode);
- if (count < 1 || !excode) {
- Swig_warning(WARN_CSHARP_EXCODE, input_file, line_number,
- "C# exception may not be thrown - no $excode or excode attribute in '%s' typemap.\n", typemap);
- }
- } else {
- Replaceall(code, "$excode", empty_string);
- }
- Delete(excode_attribute);
- }
-
- /* -----------------------------------------------------------------------------
- * addOpenNamespace()
- * ----------------------------------------------------------------------------- */
-
- void addOpenNamespace(const String *nspace, File *file) {
- if (namespce || nspace) {
- Printf(file, "namespace ");
- if (namespce)
- Printv(file, namespce, nspace ? "." : "", NIL);
- if (nspace)
- Printv(file, nspace, NIL);
- Printf(file, " {\n");
- }
- }
-
- /* -----------------------------------------------------------------------------
- * addCloseNamespace()
- * ----------------------------------------------------------------------------- */
-
- void addCloseNamespace(const String *nspace, File *file) {
- if (namespce || nspace)
- Printf(file, "\n}\n");
- }
-
- /* -----------------------------------------------------------------------------
- * outputDirectory()
- *
- * Return the directory to use for generating C# classes/enums and create the
- * subdirectory (does not create if language specific outdir does not exist).
- * ----------------------------------------------------------------------------- */
-
- String *outputDirectory(String *nspace) {
- String *output_directory = Copy(SWIG_output_directory());
- if (nspace) {
- String *nspace_subdirectory = Copy(nspace);
- Replaceall(nspace_subdirectory, ".", SWIG_FILE_DELIMITER);
- String *newdir_error = Swig_new_subdirectory(output_directory, nspace_subdirectory);
- if (newdir_error) {
- Printf(stderr, "%s\n", newdir_error);
- Delete(newdir_error);
- Exit(EXIT_FAILURE);
- }
- Printv(output_directory, nspace_subdirectory, SWIG_FILE_DELIMITER, 0);
- Delete(nspace_subdirectory);
- }
- return output_directory;
- }
-
- /*----------------------------------------------------------------------
- * Start of director methods
- *--------------------------------------------------------------------*/
-
-#if 0
- /*----------------------------------------------------------------------
- * emitDirectorUpcalls()
- *--------------------------------------------------------------------*/
-
- void emitDirectorUpcalls() {
- if (n_dmethods) {
- Wrapper *w = NewWrapper();
- String *dmethod_data = NewString("");
- int n_methods = 0;
- Iterator udata_iter;
-
- udata_iter = First(dmethods_seq);
- while (udata_iter.item) {
- UpcallData *udata = udata_iter.item;
- Printf(dmethod_data, " { \"%s\", \"%s\" }", Getattr(udata, "imclass_method"), Getattr(udata, "imclass_fdesc"));
- ++n_methods;
-
- udata_iter = Next(udata_iter);
-
- if (udata_iter.item)
- Putc(',', dmethod_data);
- Putc('\n', dmethod_data);
- }
-
-
- Wrapper_print(w, f_wrappers);
- Delete(dmethod_data);
- Delete(swig_module_init);
- DelWrapper(w);
- }
- }
-#endif
-
- /*----------------------------------------------------------------------
- * emitDirectorExtraMethods()
- *
- * This is where the director connect method is generated.
- *--------------------------------------------------------------------*/
- void emitDirectorExtraMethods(Node *n) {
- if (!Swig_directorclass(n))
- return;
-
- // Output the director connect method:
- String *norm_name = SwigType_namestr(Getattr(n, "name"));
- String *dirclassname = directorClassName(n);
- String *swig_director_connect = Swig_name_member(getNSpace(), getClassPrefix(), "director_connect");
- String *wname = Swig_name_wrapper(swig_director_connect);
- String *sym_name = Getattr(n, "sym:name");
- String *qualified_classname = Copy(sym_name);
- String *nspace = getNSpace();
- String *dirClassName = directorClassName(n);
- String *smartptr = Getattr(n, "feature:smartptr");
- if (!GetFlag(n, "feature:flatnested")) {
- for (Node *outer_class = Getattr(n, "nested:outer"); outer_class; outer_class = Getattr(outer_class, "nested:outer")) {
-
- Push(qualified_classname, ".");
- Push(qualified_classname, Getattr(outer_class, "sym:name"));
- }
- }
- if (nspace)
- Insert(qualified_classname, 0, NewStringf("%s.", nspace));
-
- Printv(imclass_class_code, "\n [global::System.Runtime.InteropServices.DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL);
- Printf(imclass_class_code, " public static extern void %s(global::System.Runtime.InteropServices.HandleRef jarg1", swig_director_connect);
-
- Wrapper *code_wrap = NewWrapper();
- Printf(code_wrap->def, "SWIGEXPORT void SWIGSTDCALL %s(void *objarg", wname);
-
- if (smartptr) {
- Printf(code_wrap->code, " %s *obj = (%s *)objarg;\n", smartptr, smartptr);
- Printf(code_wrap->code, " // Keep a local instance of the smart pointer around while we are using the raw pointer\n");
- Printf(code_wrap->code, " // Avoids using smart pointer specific API.\n");
- Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj->operator->());\n", dirClassName, dirClassName);
- } else {
- Printf(code_wrap->code, " %s *obj = (%s *)objarg;\n", norm_name, norm_name);
- Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj);\n", dirClassName, dirClassName);
- }
-
- Printf(code_wrap->code, " director->swig_connect_director(");
-
- for (int i = first_class_dmethod; i < curr_class_dmethod; ++i) {
- UpcallData *udata = Getitem(dmethods_seq, i);
- String *methid = Getattr(udata, "class_methodidx");
-
- Printf(code_wrap->def, ", ");
- if (i != first_class_dmethod)
- Printf(code_wrap->code, ", ");
- Printf(code_wrap->def, "%s::SWIG_Callback%s_t callback%s", dirclassname, methid, methid);
- Printf(code_wrap->code, "callback%s", methid);
- Printf(imclass_class_code, ", %s.SwigDelegate%s_%s delegate%s", qualified_classname, sym_name, methid, methid);
- }
-
- Printf(code_wrap->def, ") {\n");
- Printf(code_wrap->code, ");\n");
- Printf(imclass_class_code, ");\n");
- Printf(code_wrap->code, "}\n");
-
- Wrapper_print(code_wrap, f_wrappers);
- DelWrapper(code_wrap);
-
- Delete(wname);
- Delete(swig_director_connect);
- Delete(qualified_classname);
- Delete(dirclassname);
- }
-
- /* ---------------------------------------------------------------
- * classDirectorMethod()
- *
- * Emit a virtual director method to pass a method call on to the
- * underlying C# object.
- *
- * --------------------------------------------------------------- */
-
- int classDirectorMethod(Node *n, Node *parent, String *super) {
- String *classname = Getattr(parent, "sym:name");
- String *c_classname = Getattr(parent, "name");
- String *name = Getattr(n, "name");
- String *symname = Getattr(n, "sym:name");
- SwigType *returntype = Getattr(n, "type");
- String *overloaded_name = getOverloadedName(n);
- String *storage = Getattr(n, "storage");
- String *value = Getattr(n, "value");
- String *decl = Getattr(n, "decl");
- String *declaration = NewString("");
- String *pre_code = NewString("");
- String *post_code = NewString("");
- String *terminator_code = NewString("");
- String *tm;
- Parm *p;
- int i;
- Wrapper *w = NewWrapper();
- ParmList *l = Getattr(n, "parms");
- bool is_void = !(Cmp(returntype, "void"));
- String *qualified_return = 0;
- bool pure_virtual = (!(Cmp(storage, "virtual")) && !(Cmp(value, "0")));
- int status = SWIG_OK;
- bool output_director = true;
- String *dirclassname = directorClassName(parent);
- String *qualified_name = NewStringf("%s::%s", dirclassname, name);
- SwigType *c_ret_type = NULL;
- String *jupcall_args = NewString("");
- String *imclass_dmethod;
- String *callback_typedef_parms = NewString("");
- String *delegate_parms = NewString("");
- String *proxy_method_types = NewString("");
- String *callback_def = NewString("");
- String *callback_code = NewString("");
- String *imcall_args = NewString("");
- bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
-
- // Kludge Alert: functionWrapper sets sym:overload properly, but it
- // isn't at this point, so we have to manufacture it ourselves. At least
- // we're consistent with the sym:overload name in functionWrapper. (?? when
- // does the overloaded method name get set?)
-
- imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name));
-
- qualified_return = SwigType_rcaststr(returntype, "c_result");
-
- if (!is_void && (!ignored_method || pure_virtual)) {
- if (!SwigType_isclass(returntype)) {
- if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
- String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
- Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL);
- Delete(construct_result);
- } else {
- String *base_typename = SwigType_base(returntype);
- String *resolved_typename = SwigType_typedef_resolve_all(base_typename);
- Symtab *symtab = Getattr(n, "sym:symtab");
- Node *typenode = Swig_symbol_clookup(resolved_typename, symtab);
-
- if (SwigType_ispointer(returntype) || (typenode && Getattr(typenode, "abstracts"))) {
- /* initialize pointers to something sane. Same for abstract
- classes when a reference is returned. */
- Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL);
- } else {
- /* If returning a reference, initialize the pointer to a sane
- default - if a C# exception occurs, then the pointer returns
- something other than a NULL-initialized reference. */
- SwigType *noref_type = SwigType_del_reference(Copy(returntype));
- String *noref_ltype = SwigType_lstr(noref_type, 0);
- String *return_ltype = SwigType_lstr(returntype, 0);
-
- Wrapper_add_localv(w, "result_default", "static", noref_ltype, "result_default", NIL);
- Wrapper_add_localv(w, "c_result", return_ltype, "c_result", NIL);
- Printf(w->code, "result_default = SwigValueInit< %s >();\n", noref_ltype);
- Printf(w->code, "c_result = &result_default;\n");
- Delete(return_ltype);
- Delete(noref_ltype);
- Delete(noref_type);
- }
-
- Delete(base_typename);
- Delete(resolved_typename);
- }
- } else {
- SwigType *vt;
-
- vt = cplus_value_type(returntype);
- if (!vt) {
- Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), NIL);
- } else {
- Wrapper_add_localv(w, "c_result", SwigType_lstr(vt, "c_result"), NIL);
- Delete(vt);
- }
- }
- }
-
- /* Create the intermediate class wrapper */
- tm = Swig_typemap_lookup("imtype", n, "", 0);
- if (tm) {
- String *imtypeout = Getattr(n, "tmap:imtype:out"); // the type in the imtype typemap's out attribute overrides the type in the typemap
- if (imtypeout)
- tm = imtypeout;
- const String *im_directoroutattributes = Getattr(n, "tmap:imtype:directoroutattributes");
- if (im_directoroutattributes) {
- Printf(callback_def, " %s\n", im_directoroutattributes);
- if (!ignored_method)
- Printf(director_delegate_definitions, " %s\n", im_directoroutattributes);
- }
-
- Printf(callback_def, " private %s SwigDirectorMethod%s(", tm, overloaded_name);
- if (!ignored_method) {
- const String *csdirectordelegatemodifiers = Getattr(n, "feature:csdirectordelegatemodifiers");
- String *modifiers = (csdirectordelegatemodifiers ? NewStringf("%s%s", csdirectordelegatemodifiers, Len(csdirectordelegatemodifiers) > 0 ? " " : "") : NewStringf("public "));
- Printf(director_delegate_definitions, " %sdelegate %s", modifiers, tm);
- Delete(modifiers);
- }
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(returntype, 0));
- }
-
- if ((c_ret_type = Swig_typemap_lookup("ctype", n, "", 0))) {
- if (!is_void && !ignored_method) {
- String *jretval_decl = NewStringf("%s jresult", c_ret_type);
- Wrapper_add_localv(w, "jresult", jretval_decl, "= 0", NIL);
- Delete(jretval_decl);
- }
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s for use in %s::%s (skipping director method)\n",
- SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- output_director = false;
- }
-
- Swig_director_parms_fixup(l);
-
- /* Attach the standard typemaps */
- Swig_typemap_attach_parms("out", l, 0);
- Swig_typemap_attach_parms("ctype", l, 0);
- Swig_typemap_attach_parms("imtype", l, 0);
- Swig_typemap_attach_parms("cstype", l, 0);
- Swig_typemap_attach_parms("directorin", l, w);
- Swig_typemap_attach_parms("csdirectorin", l, 0);
- Swig_typemap_attach_parms("directorargout", l, w);
-
- /* Preamble code */
- if (!ignored_method)
- Printf(w->code, "if (!swig_callback%s) {\n", overloaded_name);
-
- if (!pure_virtual) {
- String *super_call = Swig_method_call(super, l);
- if (is_void) {
- Printf(w->code, "%s;\n", super_call);
- if (!ignored_method)
- Printf(w->code, "return;\n");
- } else {
- Printf(w->code, "return %s;\n", super_call);
- }
- Delete(super_call);
- } else {
- Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"%s::%s\");\n", SwigType_namestr(c_classname), SwigType_namestr(name));
- if (!is_void)
- Printf(w->code, "return %s;", qualified_return);
- else if (!ignored_method)
- Printf(w->code, "return;\n");
- }
-
- if (!ignored_method)
- Printf(w->code, "} else {\n");
-
- /* Go through argument list, convert from native to C# */
- for (i = 0, p = l; p; ++i) {
- /* Is this superfluous? */
- while (checkAttribute(p, "tmap:directorin:numinputs", "0")) {
- p = Getattr(p, "tmap:directorin:next");
- }
-
- SwigType *pt = Getattr(p, "type");
- String *ln = makeParameterName(n, p, i, false);
- String *c_param_type = NULL;
- String *c_decl = NewString("");
- String *arg = NewString("");
-
- Printf(arg, "j%s", ln);
-
- /* And add to the upcall args */
- if (i > 0)
- Printf(jupcall_args, ", ");
- Printf(jupcall_args, "%s", arg);
-
- /* Get parameter's intermediary C type */
- if ((c_param_type = Getattr(p, "tmap:ctype"))) {
- String *ctypeout = Getattr(p, "tmap:ctype:out"); // the type in the ctype typemap's out attribute overrides the type in the typemap
- if (ctypeout)
- c_param_type = ctypeout;
-
- /* Add to local variables */
- Printf(c_decl, "%s %s", c_param_type, arg);
- if (!ignored_method)
- Wrapper_add_localv(w, arg, c_decl, (!(SwigType_ispointer(pt) || SwigType_isreference(pt)) ? "" : "= 0"), NIL);
-
- /* Add input marshalling code */
- if ((tm = Getattr(p, "tmap:directorin"))) {
-
- Setattr(p, "emit:directorinput", arg);
- Replaceall(tm, "$input", arg);
- Replaceall(tm, "$owner", "0");
-
- if (Len(tm))
- if (!ignored_method)
- Printf(w->code, "%s\n", tm);
-
- /* Add C type to callback typedef */
- if (i > 0)
- Printf(callback_typedef_parms, ", ");
- Printf(callback_typedef_parms, "%s", c_param_type);
-
- /* Add parameter to the intermediate class code if generating the
- * intermediate's upcall code */
- if ((tm = Getattr(p, "tmap:imtype"))) {
-
- String *imtypeout = Getattr(p, "tmap:imtype:out"); // the type in the imtype typemap's out attribute overrides the type in the typemap
- if (imtypeout)
- tm = imtypeout;
- const String *im_directorinattributes = Getattr(p, "tmap:imtype:directorinattributes");
-
- String *din = Copy(Getattr(p, "tmap:csdirectorin"));
-
- if (din) {
- Replaceall(din, "$module", module_class_name);
- Replaceall(din, "$imclassname", imclass_name);
- substituteClassname(pt, din);
- Replaceall(din, "$iminput", ln);
-
- // pre and post attribute support
- String *pre = Getattr(p, "tmap:csdirectorin:pre");
- if (pre) {
- substituteClassname(pt, pre);
- Replaceall(pre, "$iminput", ln);
- if (Len(pre_code) > 0)
- Printf(pre_code, "\n");
- Printv(pre_code, pre, NIL);
- }
- String *post = Getattr(p, "tmap:csdirectorin:post");
- if (post) {
- substituteClassname(pt, post);
- Replaceall(post, "$iminput", ln);
- if (Len(post_code) > 0)
- Printf(post_code, "\n");
- Printv(post_code, post, NIL);
- }
- String *terminator = Getattr(p, "tmap:csdirectorin:terminator");
- if (terminator) {
- substituteClassname(pt, terminator);
- Replaceall(terminator, "$iminput", ln);
- if (Len(terminator_code) > 0)
- Insert(terminator_code, 0, "\n");
- Insert(terminator_code, 0, terminator);
- }
-
- if (i > 0) {
- Printf(delegate_parms, ", ");
- Printf(proxy_method_types, ", ");
- Printf(imcall_args, ", ");
- }
- Printf(delegate_parms, "%s%s %s", im_directorinattributes ? im_directorinattributes : empty_string, tm, ln);
-
- if (Cmp(din, ln)) {
- Printv(imcall_args, din, NIL);
- } else
- Printv(imcall_args, ln, NIL);
-
- /* Get the C# parameter type */
- if ((tm = Getattr(p, "tmap:cstype"))) {
- substituteClassname(pt, tm);
- int flags = DOH_REPLACE_FIRST | DOH_REPLACE_ID_BEGIN | DOH_REPLACE_NOCOMMENT;
- if (Replace(tm, "ref ", "", flags) || Replace(tm, "ref\t", "", flags)) {
- Printf(proxy_method_types, "typeof(%s).MakeByRefType()", tm);
- } else if (Replace(tm, "out ", "", flags) || Replace(tm, "out\t", "", flags)) {
- Printf(proxy_method_types, "typeof(%s).MakeByRefType()", tm);
- } else {
- Printf(proxy_method_types, "typeof(%s)", tm);
- }
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(pt, 0));
- }
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSDIRECTORIN_UNDEF, input_file, line_number, "No csdirectorin typemap defined for %s for use in %s::%s (skipping director method)\n",
- SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- output_director = false;
- }
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s for use in %s::%s (skipping director method)\n",
- SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- output_director = false;
- }
-
- p = Getattr(p, "tmap:directorin:next");
-
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSDIRECTORIN_UNDEF, input_file, line_number,
- "No or improper directorin typemap defined for argument %s for use in %s::%s (skipping director method)\n",
- SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- p = nextSibling(p);
- output_director = false;
- }
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s for use in %s::%s (skipping director method)\n",
- SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- output_director = false;
- p = nextSibling(p);
- }
-
- Delete(ln);
- Delete(arg);
- Delete(c_decl);
- }
-
- /* header declaration, start wrapper definition */
- String *target;
- SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
- target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
- Printf(w->def, "%s", target);
- Delete(qualified_name);
- Delete(target);
- target = Swig_method_decl(rtype, decl, name, l, 1);
- Printf(declaration, " virtual %s", target);
- Delete(target);
-
- // Add any exception specifications to the methods in the director class
- if (Getattr(n, "noexcept")) {
- Append(w->def, " noexcept");
- Append(declaration, " noexcept");
- }
- ParmList *throw_parm_list = NULL;
- if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
- int gencomma = 0;
-
- Append(w->def, " throw(");
- Append(declaration, " throw(");
-
- if (throw_parm_list)
- Swig_typemap_attach_parms("throws", throw_parm_list, 0);
- for (p = throw_parm_list; p; p = nextSibling(p)) {
- if (Getattr(p, "tmap:throws")) {
- if (gencomma++) {
- Append(w->def, ", ");
- Append(declaration, ", ");
- }
- Printf(w->def, "%s", SwigType_str(Getattr(p, "type"), 0));
- Printf(declaration, "%s", SwigType_str(Getattr(p, "type"), 0));
- }
- }
-
- Append(w->def, ")");
- Append(declaration, ")");
- }
-
- Append(w->def, " {");
- Append(declaration, ";\n");
-
- /* Finish off the inherited upcall's definition */
-
- Printf(callback_def, "%s)", delegate_parms);
- Printf(callback_def, " {\n");
-
- /* Emit the intermediate class's upcall to the actual class */
-
- String *upcall = NewStringf("%s(%s)", symname, imcall_args);
-
- if ((tm = Swig_typemap_lookup("csdirectorout", n, "", 0))) {
- substituteClassname(returntype, tm);
- Replaceall(tm, "$cscall", upcall);
- if (!is_void)
- Insert(tm, 0, "return ");
- Replaceall(tm, "\n ", "\n "); // add extra indentation to code in typemap
-
- // pre and post attribute support
- bool is_pre_code = Len(pre_code) > 0;
- bool is_post_code = Len(post_code) > 0;
- bool is_terminator_code = Len(terminator_code) > 0;
- if (is_pre_code && is_post_code)
- Printf(callback_code, "%s\n try {\n %s;\n } finally {\n%s\n }\n", pre_code, tm, post_code);
- else if (is_pre_code)
- Printf(callback_code, "%s\n %s;\n", pre_code, tm);
- else if (is_post_code)
- Printf(callback_code, " try {\n %s;\n } finally {\n%s\n }\n", tm, post_code);
- else
- Printf(callback_code, " %s;\n", tm);
- if (is_terminator_code)
- Printv(callback_code, "\n", terminator_code, NIL);
- }
-
- Printf(callback_code, " }\n");
- Delete(upcall);
-
- if (!ignored_method) {
- if (!is_void)
- Printf(w->code, "jresult = (%s) ", c_ret_type);
-
- Printf(w->code, "swig_callback%s(%s);\n", overloaded_name, jupcall_args);
-
- if (!is_void) {
- String *jresult_str = NewString("jresult");
- String *result_str = NewString("c_result");
-
- /* Copy jresult into c_result... */
- if ((tm = Swig_typemap_lookup("directorout", n, result_str, w))) {
- Replaceall(tm, "$input", jresult_str);
- Replaceall(tm, "$result", result_str);
- Printf(w->code, "%s\n", tm);
- } else {
- Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
- "Unable to use return type %s used in %s::%s (skipping director method)\n",
- SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- output_director = false;
- }
-
- Delete(jresult_str);
- Delete(result_str);
- }
-
- /* Marshal outputs */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:directorargout"))) {
- canThrow(n, "directorargout", p);
- Replaceall(tm, "$result", "jresult");
- Replaceall(tm, "$input", Getattr(p, "emit:directorinput"));
- Printv(w->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:directorargout:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* Terminate wrapper code */
- Printf(w->code, "}\n");
- if (!is_void)
- Printf(w->code, "return %s;", qualified_return);
- }
-
- Printf(w->code, "}");
-
- // We expose virtual protected methods via an extra public inline method which makes a straight call to the wrapped class' method
- String *inline_extra_method = NewString("");
- if (dirprot_mode() && !is_public(n) && !pure_virtual) {
- Printv(inline_extra_method, declaration, NIL);
- String *extra_method_name = NewStringf("%sSwigPublic", name);
- Replaceall(inline_extra_method, name, extra_method_name);
- Replaceall(inline_extra_method, ";\n", " {\n ");
- if (!is_void)
- Printf(inline_extra_method, "return ");
- String *methodcall = Swig_method_call(super, l);
- Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
- Delete(methodcall);
- Delete(extra_method_name);
- }
-
- /* emit the director method */
- if (status == SWIG_OK && output_director) {
- if (!is_void) {
- Replaceall(w->code, "$null", qualified_return);
- } else {
- Replaceall(w->code, "$null", "");
- }
- if (!ignored_method)
- Printv(director_delegate_callback, "\n", callback_def, callback_code, NIL);
- if (!Getattr(n, "defaultargs")) {
- Replaceall(w->code, "$symname", symname);
- Wrapper_print(w, f_directors);
- Printv(f_directors_h, declaration, NIL);
- Printv(f_directors_h, inline_extra_method, NIL);
- }
- }
-
- if (!ignored_method) {
- /* Emit the actual upcall through */
- UpcallData *udata = addUpcallMethod(imclass_dmethod, symname, decl, overloaded_name);
- String *methid = Getattr(udata, "class_methodidx");
- Setattr(n, "upcalldata", udata);
- /*
- Printf(stdout, "setting upcalldata, nodeType: %s %s::%s %p\n", nodeType(n), classname, Getattr(n, "name"), n);
- */
-
- Printf(director_callback_typedefs, " typedef %s (SWIGSTDCALL* SWIG_Callback%s_t)(", c_ret_type, methid);
- Printf(director_callback_typedefs, "%s);\n", callback_typedef_parms);
- Printf(director_callbacks, " SWIG_Callback%s_t swig_callback%s;\n", methid, overloaded_name);
-
- Printf(director_delegate_definitions, " SwigDelegate%s_%s(%s);\n", classname, methid, delegate_parms);
- Printf(director_delegate_instances, " private SwigDelegate%s_%s swigDelegate%s;\n", classname, methid, methid);
- Printf(director_method_types, " private static global::System.Type[] swigMethodTypes%s = new global::System.Type[] { %s };\n", methid, proxy_method_types);
- Printf(director_connect_parms, "SwigDirector%s%s delegate%s", classname, methid, methid);
- }
-
- Delete(pre_code);
- Delete(post_code);
- Delete(terminator_code);
- Delete(qualified_return);
- Delete(declaration);
- Delete(callback_typedef_parms);
- Delete(delegate_parms);
- Delete(proxy_method_types);
- Delete(callback_def);
- Delete(callback_code);
- Delete(dirclassname);
- DelWrapper(w);
-
- return status;
- }
-
- /* ------------------------------------------------------------
- * classDirectorConstructor()
- * ------------------------------------------------------------ */
-
- int classDirectorConstructor(Node *n) {
- Node *parent = parentNode(n);
- String *decl = Getattr(n, "decl");
- String *supername = Swig_class_name(parent);
- String *dirclassname = directorClassName(parent);
- String *sub = NewString("");
- Parm *p;
- ParmList *superparms = Getattr(n, "parms");
- ParmList *parms;
- int argidx = 0;
-
- /* Assign arguments to superclass's parameters, if not already done */
- for (p = superparms; p; p = nextSibling(p)) {
- String *pname = Getattr(p, "name");
-
- if (!pname) {
- pname = NewStringf("arg%d", argidx++);
- Setattr(p, "name", pname);
- }
- }
-
- // TODO: Is this copy needed?
- parms = CopyParmList(superparms);
-
- if (!Getattr(n, "defaultargs")) {
- /* constructor */
- {
- String *basetype = Getattr(parent, "classtype");
- String *target = Swig_method_decl(0, decl, dirclassname, parms, 0);
- String *call = Swig_csuperclass_call(0, basetype, superparms);
-
- Printf(f_directors, "%s::%s : %s, %s {\n", dirclassname, target, call, Getattr(parent, "director:ctor"));
- Printf(f_directors, " swig_init_callbacks();\n");
- Printf(f_directors, "}\n\n");
-
- Delete(target);
- Delete(call);
- }
-
- /* constructor header */
- {
- String *target = Swig_method_decl(0, decl, dirclassname, parms, 1);
- Printf(f_directors_h, " %s;\n", target);
- Delete(target);
- }
- }
-
- Delete(sub);
- Delete(supername);
- Delete(parms);
- Delete(dirclassname);
- return Language::classDirectorConstructor(n);
- }
-
- /* ------------------------------------------------------------
- * classDirectorDefaultConstructor()
- * ------------------------------------------------------------ */
-
- int classDirectorDefaultConstructor(Node *n) {
- String *dirclassname = directorClassName(n);
- String *classtype = SwigType_namestr(Getattr(n, "name"));
- Wrapper *w = NewWrapper();
-
- Printf(w->def, "%s::%s() : %s {", dirclassname, dirclassname, Getattr(n, "director:ctor"));
- Printf(w->code, "}\n");
- Wrapper_print(w, f_directors);
-
- Printf(f_directors_h, " %s();\n", dirclassname);
- DelWrapper(w);
- Delete(classtype);
- Delete(dirclassname);
- return Language::classDirectorDefaultConstructor(n);
- }
-
-
- /* ------------------------------------------------------------
- * classDirectorInit()
- * ------------------------------------------------------------ */
-
- int classDirectorInit(Node *n) {
- Delete(none_comparison);
- none_comparison = NewString(""); // not used
-
- Delete(director_ctor_code);
- director_ctor_code = NewString("$director_new");
-
- directorDeclaration(n);
-
- Printf(f_directors_h, "%s {\n", Getattr(n, "director:decl"));
- Printf(f_directors_h, "\npublic:\n");
-
- /* Keep track of the director methods for this class */
- first_class_dmethod = curr_class_dmethod = n_dmethods;
-
- director_callback_typedefs = NewString("");
- director_callbacks = NewString("");
- director_delegate_callback = NewString("");
- director_delegate_definitions = NewString("");
- director_delegate_instances = NewString("");
- director_method_types = NewString("");
- director_connect_parms = NewString("");
-
- return Language::classDirectorInit(n);
- }
-
- int classDeclaration(Node *n) {
- String *old_director_callback_typedefs = director_callback_typedefs;
- String *old_director_callbacks = director_callbacks;
- String *old_director_delegate_callback = director_delegate_callback;
- String *old_director_delegate_definitions = director_delegate_definitions;
- String *old_director_delegate_instances = director_delegate_instances;
- String *old_director_method_types = director_method_types;
- String *old_director_connect_parms = director_connect_parms;
-
- int ret = Language::classDeclaration(n);
-
- // these variables are deleted in emitProxyClassDefAndCPPCasts, hence no Delete here
- director_callback_typedefs = old_director_callback_typedefs;
- director_callbacks = old_director_callbacks;
- director_delegate_callback = old_director_delegate_callback;
- director_delegate_definitions = old_director_delegate_definitions;
- director_delegate_instances = old_director_delegate_instances;
- director_method_types = old_director_method_types;
- director_connect_parms = old_director_connect_parms;
-
- return ret;
- }
-
- /* ----------------------------------------------------------------------
- * classDirectorDestructor()
- * ---------------------------------------------------------------------- */
-
- int classDirectorDestructor(Node *n) {
- Node *current_class = getCurrentClass();
- String *dirclassname = directorClassName(current_class);
- Wrapper *w = NewWrapper();
-
- if (Getattr(n, "noexcept")) {
- Printf(f_directors_h, " virtual ~%s() noexcept;\n", dirclassname);
- Printf(w->def, "%s::~%s() noexcept {\n", dirclassname, dirclassname);
- } else if (Getattr(n, "throw")) {
- Printf(f_directors_h, " virtual ~%s() throw();\n", dirclassname);
- Printf(w->def, "%s::~%s() throw() {\n", dirclassname, dirclassname);
- } else {
- Printf(f_directors_h, " virtual ~%s();\n", dirclassname);
- Printf(w->def, "%s::~%s() {\n", dirclassname, dirclassname);
- }
-
- Printv(w->code, "}\n", NIL);
-
- Wrapper_print(w, f_directors);
-
- DelWrapper(w);
- Delete(dirclassname);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * classDirectorEnd()
- * ------------------------------------------------------------ */
-
- int classDirectorEnd(Node *n) {
- int i;
- String *dirclassname = directorClassName(n);
-
- Wrapper *w = NewWrapper();
-
- if (Len(director_callback_typedefs) > 0) {
- Printf(f_directors_h, "\n%s", director_callback_typedefs);
- }
-
- Printf(f_directors_h, " void swig_connect_director(");
-
- Printf(w->def, "void %s::swig_connect_director(", dirclassname);
-
- for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
- UpcallData *udata = Getitem(dmethods_seq, i);
- String *methid = Getattr(udata, "class_methodidx");
- String *overname = Getattr(udata, "overname");
-
- Printf(f_directors_h, "SWIG_Callback%s_t callback%s", methid, overname);
- Printf(w->def, "SWIG_Callback%s_t callback%s", methid, overname);
- Printf(w->code, "swig_callback%s = callback%s;\n", overname, overname);
- if (i != curr_class_dmethod - 1) {
- Printf(f_directors_h, ", ");
- Printf(w->def, ", ");
- }
- }
-
- Printf(f_directors_h, ");\n");
- Printf(w->def, ") {");
-
-
- if (Len(director_callbacks) > 0) {
- Printf(f_directors_h, "\nprivate:\n%s", director_callbacks);
- }
- Printf(f_directors_h, " void swig_init_callbacks();\n");
- Printf(f_directors_h, "};\n\n");
- Printf(w->code, "}\n\n");
-
- Printf(w->code, "void %s::swig_init_callbacks() {\n", dirclassname);
- for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
- UpcallData *udata = Getitem(dmethods_seq, i);
- String *overname = Getattr(udata, "overname");
- Printf(w->code, "swig_callback%s = 0;\n", overname);
- }
- Printf(w->code, "}");
-
- Wrapper_print(w, f_directors);
-
- DelWrapper(w);
- Delete(dirclassname);
-
- return Language::classDirectorEnd(n);
- }
-
- /* --------------------------------------------------------------------
- * classDirectorDisown()
- * ------------------------------------------------------------------*/
- virtual int classDirectorDisown(Node *n) {
- (void) n;
- return SWIG_OK;
- }
-
- /*----------------------------------------------------------------------
- * extraDirectorProtectedCPPMethodsRequired()
- *--------------------------------------------------------------------*/
-
- bool extraDirectorProtectedCPPMethodsRequired() const {
- return false;
- }
-
- /*----------------------------------------------------------------------
- * directorDeclaration()
- *
- * Generate the director class's declaration
- * e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {"
- *--------------------------------------------------------------------*/
-
- void directorDeclaration(Node *n) {
-
- String *base = Getattr(n, "classtype");
- String *class_ctor = NewString("Swig::Director()");
-
- String *dirclassname = directorClassName(n);
- String *declaration = Swig_class_declaration(n, dirclassname);
-
- Printf(declaration, " : public %s, public Swig::Director", base);
-
- // Stash stuff for later.
- Setattr(n, "director:decl", declaration);
- Setattr(n, "director:ctor", class_ctor);
-
- Delete(dirclassname);
- }
-
- /*----------------------------------------------------------------------
- * nestedClassesSupport()
- *--------------------------------------------------------------------*/
-
- NestedClassSupport nestedClassesSupport() const {
- return NCS_Full;
- }
-}; /* class CSHARP */
-
-/* -----------------------------------------------------------------------------
- * swig_csharp() - Instantiate module
- * ----------------------------------------------------------------------------- */
-
-static Language *new_swig_csharp() {
- return new CSHARP();
-}
-extern "C" Language *swig_csharp(void) {
- return new_swig_csharp();
-}
-
-/* -----------------------------------------------------------------------------
- * Static member variables
- * ----------------------------------------------------------------------------- */
-
-const char *CSHARP::usage = "\
-C# Options (available with -csharp)\n\
- -dllimport <dl> - Override DllImport attribute name to <dl>\n\
- -namespace <nm> - Generate wrappers into C# namespace <nm>\n\
- -noproxy - Generate the low-level functional interface instead\n\
- of proxy classes\n\
- -oldvarnames - Old intermediary method names for variable wrappers\n\
- -outfile <file> - Write all C# into a single <file> located in the output directory\n\
-\n";
diff --git a/contrib/tools/swig/Source/Modules/d.cxx b/contrib/tools/swig/Source/Modules/d.cxx
deleted file mode 100644
index 31f300f2ea..0000000000
--- a/contrib/tools/swig/Source/Modules/d.cxx
+++ /dev/null
@@ -1,4649 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * d.cxx
- *
- * D language module for SWIG.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include "cparse.h"
-#include <ctype.h>
-
-// Hash type used for storing information about director callbacks for a class.
-typedef DOH UpcallData;
-
-class D : public Language {
- static const char *usage;
- const String *empty_string;
- const String *public_string;
- const String *protected_string;
-
- /*
- * Files and file sections containing C/C++ code.
- */
- File *f_begin;
- File *f_runtime;
- File *f_runtime_h;
- File *f_header;
- File *f_wrappers;
- File *f_init;
- File *f_directors;
- File *f_directors_h;
- List *filenames_list;
-
- /*
- * Command line-set modes of operation.
- */
- // Whether a single proxy D module is generated or classes and enums are
- // written to their own files.
- bool split_proxy_dmodule;
-
- // The major D version targeted (currently 1 or 2).
- unsigned short d_version;
-
- /*
- * State variables which indicate what is being wrapped at the moment.
- * This is probably not the most elegant way of handling state, but it has
- * proven to work in the C# and Java modules.
- */
- // Indicates if wrapping a native function.
- bool native_function_flag;
-
- // Indicates if wrapping a static functions or member variables
- bool static_flag;
-
- // Indicates if wrapping a nonstatic member variable
- bool variable_wrapper_flag;
-
- // Indicates if wrapping a member variable/enum/const.
- bool wrapping_member_flag;
-
- // Indicates if wrapping a global variable.
- bool global_variable_flag;
-
- // Name of a variable being wrapped.
- String *variable_name;
-
- /*
- * Variables temporarily holding the generated C++ code.
- */
- // C++ code for the generated wrapper functions for casts up the C++
- // for inheritance hierarchies.
- String *upcasts_code;
-
- // Function pointer typedefs for handling director callbacks on the C++ side.
- String *director_callback_typedefs;
-
- // Variables for storing the function pointers to the director callbacks on
- // the C++ side.
- String *director_callback_pointers;
-
- /*
- * Names of generated D entities.
- */
- // The name of the D module containing the interface to the C wrapper.
- String *im_dmodule_name;
-
- // The fully qualified name of the wrap D module (package name included).
- String *im_dmodule_fq_name;
-
- // The name of the proxy module which exposes the (SWIG) module contents as a
- // D module.
- String *proxy_dmodule_name;
-
- // The fully qualified name of the proxy D module.
- String *proxy_dmodule_fq_name;
-
- // Optional: Package the D modules are placed in (set via the -package
- // command line option).
- String *package;
-
- // The directory the generated D module files are written to. Is constructed
- // from the package path if a target package is set, points to the general
- // output directory otherwise.
- String *dmodule_directory;
-
- // The name of the library which contains the C wrapper (used when generating
- // the dynamic library loader). Can be overridden via the -wrapperlibrary
- // command line flag.
- String *wrap_library_name;
-
- /*
- * Variables temporarily holding the generated D code.
- */
- // Import statements written to the intermediary D module header set via
- // %pragma(d) imdmoduleimports.
- String *im_dmodule_imports;
-
- // The code for the intermediary D module body.
- String *im_dmodule_code;
-
- // Import statements for all proxy modules (the main proxy module and, if in
- // split proxy module mode, the proxy class modules) from
- // %pragma(d) globalproxyimports.
- String *global_proxy_imports;
-
- // The D code for the main proxy modules. nspace_proxy_dmodules is a hash from
- // the namespace name as key to an {"imports", "code"}. If the nspace feature
- // is not active, only proxy_dmodule_imports and proxy_dmodule_code are used,
- // which contain the code for the root proxy module.
- //
- // These variables should not be accessed directly but rather via the
- // proxy{Imports, Code}Buffer)() helper functions which return the right
- // buffer for a given namespace. If not in split proxy mode, they contain the
- // whole proxy code.
- String *proxy_dmodule_imports;
- String *proxy_dmodule_code;
- Hash *nspace_proxy_dmodules;
-
- // The D code generated for the currently processed enum.
- String *proxy_enum_code;
-
- /*
- * D data for the current proxy class.
- *
- * These strings are mainly used to temporarily accumulate code from the
- * various member handling functions while a single class is processed and are
- * no longer relevant once that class has been finished, i.e. after
- * classHandler() has returned.
- */
- // The unqualified name of the current proxy class.
- String *proxy_class_name;
-
- // The name of the current proxy class, qualified with the name of the
- // namespace it is in, if any.
- String *proxy_class_qname;
-
- // The import directives for the current proxy class. They are written to the
- // same D module the proxy class is written to.
- String *proxy_class_imports;
-
- // Code for enumerations nested in the current proxy class. Is emitted earlier
- // than the rest of the body to work around forward referencing-issues.
- String *proxy_class_enums_code;
-
- // The generated D code making up the body of the current proxy class.
- String *proxy_class_body_code;
-
- // D code which is emitted right after the proxy class.
- String *proxy_class_epilogue_code;
-
- // The full code for the current proxy class, including the epilogue.
- String* proxy_class_code;
-
- // Contains a D call to the function wrapping C++ the destructor of the
- // current class (if there is a public C++ destructor).
- String *destructor_call;
-
- // D code for the director callbacks generated for the current class.
- String *director_dcallbacks_code;
-
- /*
- * Code for dynamically loading the wrapper library on the D side.
- */
- // D code which is inserted into the im D module if dynamic linking is used.
- String *wrapper_loader_code;
-
- // The D code to bind a function pointer to a library symbol.
- String *wrapper_loader_bind_command;
-
- // The cumulated binding commands binding all the functions declared in the
- // intermediary D module to the C/C++ library symbols.
- String *wrapper_loader_bind_code;
-
- /*
- * Director data.
- */
- List *dmethods_seq;
- Hash *dmethods_table;
- int n_dmethods;
- int first_class_dmethod;
- int curr_class_dmethod;
-
- /*
- * SWIG types data.
- */
- // Collects information about encountered types SWIG does not know about (e.g.
- // incomplete types). This is used later to generate type wrapper proxy
- // classes for the unknown types.
- Hash *unknown_types;
-
-
-public:
- /* ---------------------------------------------------------------------------
- * D::D()
- * --------------------------------------------------------------------------- */
- D():empty_string(NewString("")),
- public_string(NewString("public")),
- protected_string(NewString("protected")),
- f_begin(NULL),
- f_runtime(NULL),
- f_runtime_h(NULL),
- f_header(NULL),
- f_wrappers(NULL),
- f_init(NULL),
- f_directors(NULL),
- f_directors_h(NULL),
- filenames_list(NULL),
- split_proxy_dmodule(false),
- d_version(1),
- native_function_flag(false),
- static_flag(false),
- variable_wrapper_flag(false),
- wrapping_member_flag(false),
- global_variable_flag(false),
- variable_name(NULL),
- upcasts_code(NULL),
- director_callback_typedefs(NULL),
- director_callback_pointers(NULL),
- im_dmodule_name(NULL),
- im_dmodule_fq_name(NULL),
- proxy_dmodule_name(NULL),
- proxy_dmodule_fq_name(NULL),
- package(NULL),
- dmodule_directory(NULL),
- wrap_library_name(NULL),
- im_dmodule_imports(NULL),
- im_dmodule_code(NULL),
- global_proxy_imports(NULL),
- proxy_dmodule_imports(NULL),
- proxy_dmodule_code(NULL),
- nspace_proxy_dmodules(NULL),
- proxy_enum_code(NULL),
- proxy_class_name(NULL),
- proxy_class_qname(NULL),
- proxy_class_imports(NULL),
- proxy_class_enums_code(NULL),
- proxy_class_body_code(NULL),
- proxy_class_epilogue_code(NULL),
- proxy_class_code(NULL),
- destructor_call(NULL),
- director_dcallbacks_code(NULL),
- wrapper_loader_code(NULL),
- wrapper_loader_bind_command(NULL),
- wrapper_loader_bind_code(NULL),
- dmethods_seq(NULL),
- dmethods_table(NULL),
- n_dmethods(0),
- first_class_dmethod(0),
- curr_class_dmethod(0),
- unknown_types(NULL) {
-
- // For now, multiple inheritance with directors is not possible. It should be
- // easy to implement though.
- director_multiple_inheritance = 0;
- director_language = 1;
-
- // Not used:
- Delete(none_comparison);
- none_comparison = NewString("");
- }
-
- /* ---------------------------------------------------------------------------
- * D::main()
- * --------------------------------------------------------------------------- */
- virtual void main(int argc, char *argv[]) {
- SWIG_library_directory("d");
-
- // Look for certain command line options
- for (int i = 1; i < argc; i++) {
- if (argv[i]) {
- if ((strcmp(argv[i], "-d2") == 0)) {
- Swig_mark_arg(i);
- d_version = 2;
- } else if (strcmp(argv[i], "-wrapperlibrary") == 0) {
- if (argv[i + 1]) {
- wrap_library_name = NewString("");
- Printf(wrap_library_name, argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-package") == 0) {
- if (argv[i + 1]) {
- package = NewString("");
- Printf(package, argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if ((strcmp(argv[i], "-splitproxy") == 0)) {
- Swig_mark_arg(i);
- split_proxy_dmodule = true;
- } else if (strcmp(argv[i], "-help") == 0) {
- Printf(stdout, "%s\n", usage);
- }
- }
- }
-
- // Add a symbol to the parser for conditional compilation
- Preprocessor_define("SWIGD 1", 0);
-
- // Also make the target D version available as preprocessor symbol for
- // use in our library files.
- String *version_define = NewStringf("SWIG_D_VERSION %u", d_version);
- Preprocessor_define(version_define, 0);
- Delete(version_define);
-
- // Add typemap definitions
- SWIG_typemap_lang("d");
- SWIG_config_file("d.swg");
-
- allow_overloading();
- }
-
- /* ---------------------------------------------------------------------------
- * D::top()
- * --------------------------------------------------------------------------- */
- virtual int top(Node *n) {
- // Get any options set in the module directive
- Node *optionsnode = Getattr(Getattr(n, "module"), "options");
-
- if (optionsnode) {
- if (Getattr(optionsnode, "imdmodulename")) {
- im_dmodule_name = Copy(Getattr(optionsnode, "imdmodulename"));
- }
-
- if (Getattr(optionsnode, "directors")) {
- // Check if directors are enabled for this module. Note: This is a
- // "master switch", if it is not set, not director code will be emitted
- // at all. %feature("director") statements are also required to enable
- // directors for individual classes or methods.
- //
- // Use the »directors« attributte of the %module directive to enable
- // director generation (e.g. »%module(directors="1") modulename«).
- allow_directors();
- }
-
- if (Getattr(optionsnode, "dirprot")) {
- allow_dirprot();
- }
-
- allow_allprotected(GetFlag(optionsnode, "allprotected"));
- }
-
- /* Initialize all of the output files */
- String *outfile = Getattr(n, "outfile");
- String *outfile_h = Getattr(n, "outfile_h");
-
- if (!outfile) {
- Printf(stderr, "Unable to determine outfile\n");
- Exit(EXIT_FAILURE);
- }
-
- f_begin = NewFile(outfile, "w", SWIG_output_files());
- if (!f_begin) {
- FileErrorDisplay(outfile);
- Exit(EXIT_FAILURE);
- }
-
- if (directorsEnabled()) {
- if (!outfile_h) {
- Printf(stderr, "Unable to determine outfile_h\n");
- Exit(EXIT_FAILURE);
- }
- f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
- if (!f_runtime_h) {
- FileErrorDisplay(outfile_h);
- Exit(EXIT_FAILURE);
- }
- }
-
- f_runtime = NewString("");
- f_init = NewString("");
- f_header = NewString("");
- f_wrappers = NewString("");
- f_directors_h = NewString("");
- f_directors = NewString("");
-
- /* Register file targets with the SWIG file handler */
- Swig_register_filebyname("header", f_header);
- Swig_register_filebyname("wrapper", f_wrappers);
- Swig_register_filebyname("begin", f_begin);
- Swig_register_filebyname("runtime", f_runtime);
- Swig_register_filebyname("init", f_init);
- Swig_register_filebyname("director", f_directors);
- Swig_register_filebyname("director_h", f_directors_h);
-
- unknown_types = NewHash();
- filenames_list = NewList();
-
- // Make the package name and the resulting module output path.
- if (package) {
- // Append a dot so we can prepend the package variable directly to the
- // module names in the rest of the code.
- Printv(package, ".", NIL);
- } else {
- // Write the generated D modules to the »root« package by default.
- package = NewString("");
- }
-
- dmodule_directory = Copy(SWIG_output_directory());
- if (Len(package) > 0) {
- String *package_directory = Copy(package);
- Replaceall(package_directory, ".", SWIG_FILE_DELIMITER);
- Printv(dmodule_directory, package_directory, NIL);
- Delete(package_directory);
- }
-
- // Make the wrap and proxy D module names.
- // The wrap module name can be set in the module directive.
- if (!im_dmodule_name) {
- im_dmodule_name = NewStringf("%s_im", Getattr(n, "name"));
- }
- im_dmodule_fq_name = NewStringf("%s%s", package, im_dmodule_name);
- proxy_dmodule_name = Copy(Getattr(n, "name"));
- proxy_dmodule_fq_name = NewStringf("%s%s", package, proxy_dmodule_name);
-
- im_dmodule_code = NewString("");
- proxy_class_imports = NewString("");
- proxy_class_enums_code = NewString("");
- proxy_class_body_code = NewString("");
- proxy_class_epilogue_code = NewString("");
- proxy_class_code = NewString("");
- destructor_call = NewString("");
- proxy_dmodule_code = NewString("");
- proxy_dmodule_imports = NewString("");
- nspace_proxy_dmodules = NewHash();
- im_dmodule_imports = NewString("");
- upcasts_code = NewString("");
- global_proxy_imports = NewString("");
- wrapper_loader_code = NewString("");
- wrapper_loader_bind_command = NewString("");
- wrapper_loader_bind_code = NewString("");
- dmethods_seq = NewList();
- dmethods_table = NewHash();
- n_dmethods = 0;
-
- // By default, expect the dynamically loaded wrapper library to be named
- // [lib]<module>_wrap[.so/.dll].
- if (!wrap_library_name)
- wrap_library_name = NewStringf("%s_wrap", Getattr(n, "name"));
-
- Swig_banner(f_begin);
-
- Swig_obligatory_macros(f_runtime, "D");
-
- if (directorsEnabled()) {
- Printf(f_runtime, "#define SWIG_DIRECTORS\n");
-
- /* Emit initial director header and director code: */
- Swig_banner(f_directors_h);
- Printf(f_directors_h, "\n");
- Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", proxy_dmodule_name);
- Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", proxy_dmodule_name);
-
- Printf(f_directors, "\n\n");
- Printf(f_directors, "/* ---------------------------------------------------\n");
- Printf(f_directors, " * C++ director class methods\n");
- Printf(f_directors, " * --------------------------------------------------- */\n\n");
- if (outfile_h) {
- String *filename = Swig_file_filename(outfile_h);
- Printf(f_directors, "#include \"%s\"\n\n", filename);
- Delete(filename);
- }
- }
-
- Printf(f_runtime, "\n");
-
- Swig_name_register("wrapper", "D_%f");
-
- Printf(f_wrappers, "\n#ifdef __cplusplus\n");
- Printf(f_wrappers, "extern \"C\" {\n");
- Printf(f_wrappers, "#endif\n\n");
-
- // Emit all the wrapper code.
- Language::top(n);
-
- if (directorsEnabled()) {
- // Insert director runtime into the f_runtime file (before %header section).
- Swig_insert_file("director_common.swg", f_runtime);
- Swig_insert_file("director.swg", f_runtime);
- }
-
- // Generate the wrap D module.
- // TODO: Add support for »static« linking.
- {
- String *filen = NewStringf("%s%s.d", dmodule_directory, im_dmodule_name);
- File *im_d_file = NewFile(filen, "w", SWIG_output_files());
- if (!im_d_file) {
- FileErrorDisplay(filen);
- Exit(EXIT_FAILURE);
- }
- Append(filenames_list, Copy(filen));
- Delete(filen);
- filen = NULL;
-
- // Start writing out the intermediary class file.
- emitBanner(im_d_file);
-
- Printf(im_d_file, "module %s;\n", im_dmodule_fq_name);
-
- Printv(im_d_file, im_dmodule_imports, "\n", NIL);
-
- Replaceall(wrapper_loader_code, "$wraplibrary", wrap_library_name);
- Replaceall(wrapper_loader_code, "$wrapperloaderbindcode", wrapper_loader_bind_code);
- Replaceall(wrapper_loader_code, "$module", proxy_dmodule_name);
- Printf(im_d_file, "%s\n", wrapper_loader_code);
-
- // Add the wrapper function declarations.
- replaceModuleVariables(im_dmodule_code);
- Printv(im_d_file, im_dmodule_code, NIL);
-
- Delete(im_d_file);
- }
-
- // Generate the main D proxy module.
- {
- String *filen = NewStringf("%s%s.d", dmodule_directory, proxy_dmodule_name);
- File *proxy_d_file = NewFile(filen, "w", SWIG_output_files());
- if (!proxy_d_file) {
- FileErrorDisplay(filen);
- Exit(EXIT_FAILURE);
- }
- Append(filenames_list, Copy(filen));
- Delete(filen);
- filen = NULL;
-
- emitBanner(proxy_d_file);
-
- Printf(proxy_d_file, "module %s;\n", proxy_dmodule_fq_name);
- Printf(proxy_d_file, "\nstatic import %s;\n", im_dmodule_fq_name);
- Printv(proxy_d_file, global_proxy_imports, NIL);
- Printv(proxy_d_file, proxy_dmodule_imports, NIL);
- Printv(proxy_d_file, "\n", NIL);
-
- // Write a D type wrapper class for each SWIG type to the proxy module code.
- for (Iterator swig_type = First(unknown_types); swig_type.key; swig_type = Next(swig_type)) {
- writeTypeWrapperClass(swig_type.key, swig_type.item);
- }
-
- // Add the proxy functions (and classes, if they are not written to a separate file).
- replaceModuleVariables(proxy_dmodule_code);
- Printv(proxy_d_file, proxy_dmodule_code, NIL);
-
- Delete(proxy_d_file);
- }
-
- // Generate the additional proxy modules for nspace support.
- for (Iterator it = First(nspace_proxy_dmodules); it.key; it = Next(it)) {
- String *module_name = createLastNamespaceName(it.key);
-
- String *filename = NewStringf("%s%s.d", outputDirectory(it.key), module_name);
- File *file = NewFile(filename, "w", SWIG_output_files());
- if (!file) {
- FileErrorDisplay(filename);
- Exit(EXIT_FAILURE);
- }
- Delete(filename);
-
- emitBanner(file);
-
- Printf(file, "module %s%s.%s;\n", package, it.key, module_name);
- Printf(file, "\nstatic import %s;\n", im_dmodule_fq_name);
- Printv(file, global_proxy_imports, NIL);
- Printv(file, Getattr(it.item, "imports"), NIL);
- Printv(file, "\n", NIL);
-
- String *code = Getattr(it.item, "code");
- replaceModuleVariables(code);
- Printv(file, code, NIL);
-
- Delete(file);
- Delete(module_name);
- }
-
- if (upcasts_code)
- Printv(f_wrappers, upcasts_code, NIL);
-
- Printf(f_wrappers, "#ifdef __cplusplus\n");
- Printf(f_wrappers, "}\n");
- Printf(f_wrappers, "#endif\n");
-
- // Check for overwriting file problems on filesystems that are case insensitive
- Iterator it1;
- Iterator it2;
- for (it1 = First(filenames_list); it1.item; it1 = Next(it1)) {
- String *item1_lower = Swig_string_lower(it1.item);
- for (it2 = Next(it1); it2.item; it2 = Next(it2)) {
- String *item2_lower = Swig_string_lower(it2.item);
- if (it1.item && it2.item) {
- if (Strcmp(item1_lower, item2_lower) == 0) {
- Swig_warning(WARN_LANG_PORTABILITY_FILENAME, input_file, line_number,
- "Portability warning: File %s will be overwritten by %s on case insensitive filesystems such as "
- "Windows' FAT32 and NTFS unless the class/module name is renamed\n", it1.item, it2.item);
- }
- }
- Delete(item2_lower);
- }
- Delete(item1_lower);
- }
-
- Delete(unknown_types);
- unknown_types = NULL;
- Delete(filenames_list);
- filenames_list = NULL;
- Delete(im_dmodule_name);
- im_dmodule_name = NULL;
- Delete(im_dmodule_fq_name);
- im_dmodule_fq_name = NULL;
- Delete(im_dmodule_code);
- im_dmodule_code = NULL;
- Delete(proxy_class_imports);
- proxy_class_imports = NULL;
- Delete(proxy_class_enums_code);
- proxy_class_enums_code = NULL;
- Delete(proxy_class_body_code);
- proxy_class_body_code = NULL;
- Delete(proxy_class_epilogue_code);
- proxy_class_epilogue_code = NULL;
- Delete(proxy_class_code);
- proxy_class_code = NULL;
- Delete(destructor_call);
- destructor_call = NULL;
- Delete(proxy_dmodule_name);
- proxy_dmodule_name = NULL;
- Delete(proxy_dmodule_fq_name);
- proxy_dmodule_fq_name = NULL;
- Delete(proxy_dmodule_code);
- proxy_dmodule_code = NULL;
- Delete(proxy_dmodule_imports);
- proxy_dmodule_imports = NULL;
- Delete(nspace_proxy_dmodules);
- nspace_proxy_dmodules = NULL;
- Delete(im_dmodule_imports);
- im_dmodule_imports = NULL;
- Delete(upcasts_code);
- upcasts_code = NULL;
- Delete(global_proxy_imports);
- global_proxy_imports = NULL;
- Delete(wrapper_loader_code);
- wrapper_loader_code = NULL;
- Delete(wrapper_loader_bind_code);
- wrapper_loader_bind_code = NULL;
- Delete(wrapper_loader_bind_command);
- wrapper_loader_bind_command = NULL;
- Delete(dmethods_seq);
- dmethods_seq = NULL;
- Delete(dmethods_table);
- dmethods_table = NULL;
- Delete(package);
- package = NULL;
- Delete(dmodule_directory);
- dmodule_directory = NULL;
- n_dmethods = 0;
-
- // Merge all the generated C/C++ code and close the output files.
- Dump(f_runtime, f_begin);
- Dump(f_header, f_begin);
-
- if (directorsEnabled()) {
- Dump(f_directors, f_begin);
- Dump(f_directors_h, f_runtime_h);
-
- Printf(f_runtime_h, "\n");
- Printf(f_runtime_h, "#endif\n");
-
- Delete(f_runtime_h);
- f_runtime_h = NULL;
- Delete(f_directors);
- f_directors = NULL;
- Delete(f_directors_h);
- f_directors_h = NULL;
- }
-
- Dump(f_wrappers, f_begin);
- Wrapper_pretty_print(f_init, f_begin);
- Delete(f_header);
- Delete(f_wrappers);
- Delete(f_init);
- Delete(f_runtime);
- Delete(f_begin);
-
- return SWIG_OK;
- }
-
- /* ---------------------------------------------------------------------------
- * D::insertDirective()
- * --------------------------------------------------------------------------- */
- virtual int insertDirective(Node *n) {
- int ret = SWIG_OK;
- String *code = Getattr(n, "code");
- String *section = Getattr(n, "section");
- replaceModuleVariables(code);
-
- if (!ImportMode && (Cmp(section, "proxycode") == 0)) {
- if (proxy_class_body_code) {
- Swig_typemap_replace_embedded_typemap(code, n);
- Printv(proxy_class_body_code, code, NIL);
- }
- } else {
- ret = Language::insertDirective(n);
- }
- return ret;
- }
-
- /* ---------------------------------------------------------------------------
- * D::pragmaDirective()
- *
- * Valid Pragmas:
- * imdmodulecode - text (D code) is copied verbatim to the wrap module
- * imdmoduleimports - import statements for the im D module
- *
- * proxydmodulecode - text (D code) is copied verbatim to the proxy module
- * (the main proxy module if in split proxy mode).
- * globalproxyimports - import statements inserted into _all_ proxy modules.
- *
- * wrapperloadercode - D code for loading the wrapper library (is copied to
- * the im D module).
- * wrapperloaderbindcommand - D code for binding a symbol from the wrapper
- * library to the declaration in the im D module.
- * --------------------------------------------------------------------------- */
- virtual int pragmaDirective(Node *n) {
- if (!ImportMode) {
- String *lang = Getattr(n, "lang");
- String *code = Getattr(n, "name");
- String *value = Getattr(n, "value");
-
- if (Strcmp(lang, "d") == 0) {
- String *strvalue = NewString(value);
- Replaceall(strvalue, "\\\"", "\"");
-
- if (Strcmp(code, "imdmodulecode") == 0) {
- Printf(im_dmodule_code, "%s\n", strvalue);
- } else if (Strcmp(code, "imdmoduleimports") == 0) {
- replaceImportTypeMacros(strvalue);
- Chop(strvalue);
- Printf(im_dmodule_imports, "%s\n", strvalue);
- } else if (Strcmp(code, "proxydmodulecode") == 0) {
- Printf(proxyCodeBuffer(0), "%s\n", strvalue);
- } else if (Strcmp(code, "globalproxyimports") == 0) {
- replaceImportTypeMacros(strvalue);
- Chop(strvalue);
- Printf(global_proxy_imports, "%s\n", strvalue);
- } else if (Strcmp(code, "wrapperloadercode") == 0) {
- Delete(wrapper_loader_code);
- wrapper_loader_code = Copy(strvalue);
- } else if (Strcmp(code, "wrapperloaderbindcommand") == 0) {
- Delete(wrapper_loader_bind_command);
- wrapper_loader_bind_command = Copy(strvalue);
- } else {
- Swig_error(input_file, line_number, "Unrecognized pragma.\n");
- }
- Delete(strvalue);
- }
- }
- return Language::pragmaDirective(n);
- }
-
- /* ---------------------------------------------------------------------------
- * D::enumDeclaration()
- *
- * Wraps C/C++ enums as D enums.
- * --------------------------------------------------------------------------- */
- virtual int enumDeclaration(Node *n) {
- if (ImportMode)
- return SWIG_OK;
-
- if (getCurrentClass() && (cplus_mode != PUBLIC))
- return SWIG_NOWRAP;
-
- proxy_enum_code = NewString("");
- String *symname = Getattr(n, "sym:name");
- String *typemap_lookup_type = Getattr(n, "name");
-
- // Emit the enum declaration.
- if (typemap_lookup_type) {
- const String *enummodifiers = lookupCodeTypemap(n, "dclassmodifiers", typemap_lookup_type, WARN_D_TYPEMAP_CLASSMOD_UNDEF);
- Printv(proxy_enum_code, "\n", enummodifiers, " ", symname, " {\n", NIL);
- } else {
- // Handle anonymous enums.
- Printv(proxy_enum_code, "\nenum {\n", NIL);
- }
-
- // Emit each enum item.
- Language::enumDeclaration(n);
-
- if (GetFlag(n, "nonempty")) {
- // Finish the enum.
- if (typemap_lookup_type) {
- Printv(proxy_enum_code,
- lookupCodeTypemap(n, "dcode", typemap_lookup_type, WARN_NONE), // Extra D code
- "\n}\n", NIL);
- } else {
- // Handle anonymous enums.
- Printv(proxy_enum_code, "\n}\n", NIL);
- }
- Replaceall(proxy_enum_code, "$dclassname", symname);
- } else {
- // D enum declarations must have at least one member to be legal, so emit
- // an alias to int instead (their ctype/imtype is always int).
- Delete(proxy_enum_code);
- proxy_enum_code = NewStringf("\nalias int %s;\n", symname);
- }
-
- const String* imports =
- lookupCodeTypemap(n, "dimports", typemap_lookup_type, WARN_NONE);
- String* imports_trimmed;
- if (Len(imports) > 0) {
- imports_trimmed = Copy(imports);
- Chop(imports_trimmed);
- replaceImportTypeMacros(imports_trimmed);
- Printv(imports_trimmed, "\n", NIL);
- } else {
- imports_trimmed = NewString("");
- }
-
- if (is_wrapping_class()) {
- // Enums defined within the C++ class are written into the proxy
- // class.
- Printv(proxy_class_imports, imports_trimmed, NIL);
- Printv(proxy_class_enums_code, proxy_enum_code, NIL);
- } else {
- // Write non-anonymous enums to their own file if in split proxy module
- // mode.
- if (split_proxy_dmodule && typemap_lookup_type) {
- assertClassNameValidity(proxy_class_name);
-
- String *nspace = Getattr(n, "sym:nspace");
- String *output_directory = outputDirectory(nspace);
- String *filename = NewStringf("%s%s.d", output_directory, symname);
- Delete(output_directory);
-
- File *class_file = NewFile(filename, "w", SWIG_output_files());
- if (!class_file) {
- FileErrorDisplay(filename);
- Exit(EXIT_FAILURE);
- }
- Append(filenames_list, Copy(filename));
- Delete(filename);
-
- emitBanner(class_file);
- if (nspace) {
- Printf(class_file, "module %s%s.%s;\n", package, nspace, symname);
- } else {
- Printf(class_file, "module %s%s;\n", package, symname);
- }
- Printv(class_file, imports_trimmed, NIL);
-
- Printv(class_file, proxy_enum_code, NIL);
-
- Delete(class_file);
- } else {
- String *nspace = Getattr(n, "sym:nspace");
- Printv(proxyImportsBuffer(nspace), imports, NIL);
- Printv(proxyCodeBuffer(nspace), proxy_enum_code, NIL);
- }
- }
-
- Delete(imports_trimmed);
-
- Delete(proxy_enum_code);
- proxy_enum_code = NULL;
- return SWIG_OK;
- }
-
- /* ---------------------------------------------------------------------------
- * D::enumvalueDeclaration()
- * --------------------------------------------------------------------------- */
- virtual int enumvalueDeclaration(Node *n) {
- if (getCurrentClass() && (cplus_mode != PUBLIC))
- return SWIG_NOWRAP;
-
- Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL);
- String *value = Getattr(n, "value");
- String *name = Getattr(n, "name");
- Node *parent = parentNode(n);
- String *tmpValue;
-
- // Strange hack from parent method.
- // RESEARCH: What is this doing?
- if (value)
- tmpValue = NewString(value);
- else
- tmpValue = NewString(name);
- // Note that this is used in enumValue() amongst other places
- Setattr(n, "value", tmpValue);
-
- // Deal with enum values that are not int
- int swigtype = SwigType_type(Getattr(n, "type"));
- if (swigtype == T_BOOL) {
- const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0";
- Setattr(n, "enumvalue", val);
- } else if (swigtype == T_CHAR) {
- String *val = NewStringf("'%(escape)s'", Getattr(n, "enumvalue"));
- Setattr(n, "enumvalue", val);
- Delete(val);
- }
-
- // Emit the enum item.
- {
- if (!GetFlag(n, "firstenumitem"))
- Printf(proxy_enum_code, ",\n");
-
- Printf(proxy_enum_code, " %s", Getattr(n, "sym:name"));
-
- // Check for the %dconstvalue feature
- String *value = Getattr(n, "feature:d:constvalue");
-
- // Note that in D, enum values must be compile-time constants. Thus,
- // %dmanifestconst(0) (getting the enum values at runtime) is not supported.
- value = value ? value : Getattr(n, "enumvalue");
- if (value) {
- Printf(proxy_enum_code, " = %s", value);
- }
-
- // Keep track that the currently processed enum has at least one value.
- SetFlag(parent, "nonempty");
- }
-
- Delete(tmpValue);
- Swig_restore(n);
- return SWIG_OK;
- }
-
- /* ---------------------------------------------------------------------------
- * D::memberfunctionHandler()
- * --------------------------------------------------------------------------- */
- virtual int memberfunctionHandler(Node *n) {
- Language::memberfunctionHandler(n);
-
- String *overloaded_name = getOverloadedName(n);
- String *intermediary_function_name =
- Swig_name_member(getNSpace(), proxy_class_name, overloaded_name);
- Setattr(n, "imfuncname", intermediary_function_name);
-
- String *proxy_func_name = Getattr(n, "sym:name");
- Setattr(n, "proxyfuncname", proxy_func_name);
- if (split_proxy_dmodule &&
- Len(Getattr(n, "parms")) == 0 &&
- Strncmp(proxy_func_name, package, Len(proxy_func_name)) == 0) {
- // If we are in split proxy mode and the function is named like the
- // target package, the D compiler is unable to resolve the ambiguity
- // between the package name and an argument-less function call.
- // TODO: This might occur with nspace as well, augment the check.
- Swig_warning(WARN_D_NAME_COLLISION, input_file, line_number,
- "%s::%s might collide with the package name, consider using %%rename to resolve the ambiguity.\n",
- proxy_class_name, proxy_func_name);
- }
-
- writeProxyClassFunction(n);
-
- Delete(overloaded_name);
-
- // For each function, look if we have to alias in the parent class function
- // for the overload resolution process to work as expected from C++
- // (http://www.digitalmars.com/d/2.0/function.html#function-inheritance).
- // For multiple overloads, only emit the alias directive once (for the
- // last method, »sym:nextSibling« is null then).
- // Smart pointer classes do not mirror the inheritance hierarchy of the
- // underlying types, so aliasing the base class methods in is not required
- // for them.
- // DMD BUG: We have to emit the alias after the last function because
- // taking a delegate in the overload checking code fails otherwise
- // (http://d.puremagic.com/issues/show_bug.cgi?id=4860).
- if (!Getattr(n, "sym:nextSibling") && !is_smart_pointer() &&
- !areAllOverloadsOverridden(n)) {
- String *name = Getattr(n, "sym:name");
- Printf(proxy_class_body_code, "\nalias $dbaseclass.%s %s;\n", name, name);
- }
- return SWIG_OK;
- }
-
- /* ---------------------------------------------------------------------------
- * D::staticmemberfunctionHandler()
- * --------------------------------------------------------------------------- */
- virtual int staticmemberfunctionHandler(Node *n) {
- static_flag = true;
-
- Language::staticmemberfunctionHandler(n);
-
- String *overloaded_name = getOverloadedName(n);
- String *intermediary_function_name =
- Swig_name_member(getNSpace(), proxy_class_name, overloaded_name);
- Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
- Setattr(n, "imfuncname", intermediary_function_name);
- writeProxyClassFunction(n);
- Delete(overloaded_name);
-
- static_flag = false;
- return SWIG_OK;
- }
-
- /* ---------------------------------------------------------------------------
- * D::globalvariableHandler()
- * --------------------------------------------------------------------------- */
- virtual int globalvariableHandler(Node *n) {
- variable_name = Getattr(n, "sym:name");
- global_variable_flag = true;
- int ret = Language::globalvariableHandler(n);
- global_variable_flag = false;
-
- return ret;
- }
-
- /* ---------------------------------------------------------------------------
- * D::membervariableHandler()
- * --------------------------------------------------------------------------- */
- virtual int membervariableHandler(Node *n) {
- variable_name = Getattr(n, "sym:name");
- wrapping_member_flag = true;
- variable_wrapper_flag = true;
- Language::membervariableHandler(n);
- wrapping_member_flag = false;
- variable_wrapper_flag = false;
-
- return SWIG_OK;
- }
-
- /* ---------------------------------------------------------------------------
- * D::staticmembervariableHandler()
- * --------------------------------------------------------------------------- */
- virtual int staticmembervariableHandler(Node *n) {
- if (GetFlag(n, "feature:d:manifestconst") != 1) {
- Delattr(n, "value");
- }
-
- variable_name = Getattr(n, "sym:name");
- wrapping_member_flag = true;
- static_flag = true;
- Language::staticmembervariableHandler(n);
- wrapping_member_flag = false;
- static_flag = false;
-
- return SWIG_OK;
- }
-
- /* ---------------------------------------------------------------------------
- * D::memberconstantHandler()
- * --------------------------------------------------------------------------- */
- virtual int memberconstantHandler(Node *n) {
- variable_name = Getattr(n, "sym:name");
- wrapping_member_flag = true;
- Language::memberconstantHandler(n);
- wrapping_member_flag = false;
- return SWIG_OK;
- }
-
- /* ---------------------------------------------------------------------------
- * D::constructorHandler()
- * --------------------------------------------------------------------------- */
- virtual int constructorHandler(Node *n) {
- Language::constructorHandler(n);
-
- // Wrappers not wanted for some methods where the parameters cannot be overloadedprocess in D.
- if (Getattr(n, "overload:ignore")) {
- return SWIG_OK;
- }
-
- ParmList *l = Getattr(n, "parms");
- String *tm;
- String *proxy_constructor_code = NewString("");
- int i;
-
- // Holds code for the constructor helper method generated only when the din
- // typemap has code in the pre or post attributes.
- String *helper_code = NewString("");
- String *helper_args = NewString("");
- String *pre_code = NewString("");
- String *post_code = NewString("");
- String *terminator_code = NewString("");
- NewString("");
-
- String *overloaded_name = getOverloadedName(n);
- String *mangled_overname = Swig_name_construct(getNSpace(), overloaded_name);
- String *imcall = NewString("");
-
- const String *methodmods = Getattr(n, "feature:d:methodmodifiers");
- methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
-
- // Typemaps were attached earlier to the node, get the return type of the
- // call to the C++ constructor wrapper.
- const String *wrapper_return_type = lookupDTypemap(n, "imtype", true);
-
- String *imtypeout = Getattr(n, "tmap:imtype:out");
- if (imtypeout) {
- // The type in the imtype typemap's out attribute overrides the type in
- // the typemap itself.
- wrapper_return_type = imtypeout;
- }
-
- Printf(proxy_constructor_code, "\n%s this(", methodmods);
- Printf(helper_code, "static private %s SwigConstruct%s(",
- wrapper_return_type, proxy_class_name);
-
- Printv(imcall, im_dmodule_fq_name, ".", mangled_overname, "(", NIL);
-
- /* Attach the non-standard typemaps to the parameter list */
- Swig_typemap_attach_parms("in", l, NULL);
- Swig_typemap_attach_parms("dtype", l, NULL);
- Swig_typemap_attach_parms("din", l, NULL);
-
- emit_mark_varargs(l);
-
- int gencomma = 0;
-
- /* Output each parameter */
- Parm *p = l;
- for (i = 0; p; i++) {
- if (checkAttribute(p, "varargs:ignore", "1")) {
- // Skip ignored varargs.
- p = nextSibling(p);
- continue;
- }
-
- if (checkAttribute(p, "tmap:in:numinputs", "0")) {
- // Skip ignored parameters.
- p = Getattr(p, "tmap:in:next");
- continue;
- }
-
- SwigType *pt = Getattr(p, "type");
- String *param_type = NewString("");
-
- // Get the D parameter type.
- if ((tm = lookupDTypemap(p, "dtype", true))) {
- const String *inattributes = Getattr(p, "tmap:dtype:inattributes");
- Printf(param_type, "%s%s", inattributes ? inattributes : empty_string, tm);
- } else {
- Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number,
- "No dtype typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- if (gencomma)
- Printf(imcall, ", ");
-
- String *arg = makeParameterName(n, p, i, false);
- String *parmtype = 0;
-
- // Get the D code to convert the parameter value to the type used in the
- // intermediary D module.
- if ((tm = lookupDTypemap(p, "din"))) {
- Replaceall(tm, "$dinput", arg);
- String *pre = Getattr(p, "tmap:din:pre");
- if (pre) {
- replaceClassname(pre, pt);
- Replaceall(pre, "$dinput", arg);
- if (Len(pre_code) > 0)
- Printf(pre_code, "\n");
- Printv(pre_code, pre, NIL);
- }
- String *post = Getattr(p, "tmap:din:post");
- if (post) {
- replaceClassname(post, pt);
- Replaceall(post, "$dinput", arg);
- if (Len(post_code) > 0)
- Printf(post_code, "\n");
- Printv(post_code, post, NIL);
- }
- String *terminator = Getattr(p, "tmap:din:terminator");
- if (terminator) {
- replaceClassname(terminator, pt);
- Replaceall(terminator, "$dinput", arg);
- if (Len(terminator_code) > 0)
- Insert(terminator_code, 0, "\n");
- Insert(terminator_code, 0, terminator);
- }
- parmtype = Getattr(p, "tmap:din:parmtype");
- if (parmtype)
- Replaceall(parmtype, "$dinput", arg);
- Printv(imcall, tm, NIL);
- } else {
- Swig_warning(WARN_D_TYPEMAP_DIN_UNDEF, input_file, line_number,
- "No din typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- /* Add parameter to proxy function */
- if (gencomma) {
- Printf(proxy_constructor_code, ", ");
- Printf(helper_code, ", ");
- Printf(helper_args, ", ");
- }
- Printf(proxy_constructor_code, "%s %s", param_type, arg);
- Printf(helper_code, "%s %s", param_type, arg);
- Printf(helper_args, "%s", parmtype ? parmtype : arg);
- ++gencomma;
-
- Delete(parmtype);
- Delete(arg);
- Delete(param_type);
- p = Getattr(p, "tmap:in:next");
- }
-
- Printf(imcall, ")");
-
- Printf(proxy_constructor_code, ")");
- Printf(helper_code, ")");
-
- // Insert the dconstructor typemap (replacing $directorconnect as needed).
- Hash *attributes = NewHash();
- String *typemap_lookup_type = Getattr(getCurrentClass(), "classtypeobj");
- String *construct_tm = Copy(lookupCodeTypemap(n, "dconstructor",
- typemap_lookup_type, WARN_D_TYPEMAP_DCONSTRUCTOR_UNDEF, attributes));
- if (construct_tm) {
- const bool use_director = (parentNode(n) && Swig_directorclass(n));
- if (!use_director) {
- Replaceall(construct_tm, "$directorconnect", "");
- } else {
- String *connect_attr = Getattr(attributes, "tmap:dconstructor:directorconnect");
-
- if (connect_attr) {
- Replaceall(construct_tm, "$directorconnect", connect_attr);
- } else {
- Swig_warning(WARN_D_NO_DIRECTORCONNECT_ATTR, input_file, line_number,
- "\"directorconnect\" attribute missing in %s \"dconstructor\" typemap.\n",
- Getattr(n, "name"));
- Replaceall(construct_tm, "$directorconnect", "");
- }
- }
-
- Printv(proxy_constructor_code, " ", construct_tm, NIL);
- }
-
- replaceExcode(n, proxy_constructor_code, "dconstructor", attributes);
-
- bool is_pre_code = Len(pre_code) > 0;
- bool is_post_code = Len(post_code) > 0;
- bool is_terminator_code = Len(terminator_code) > 0;
- if (is_pre_code || is_post_code || is_terminator_code) {
- Printf(helper_code, " {\n");
- if (is_pre_code) {
- Printv(helper_code, pre_code, "\n", NIL);
- }
- if (is_post_code) {
- Printf(helper_code, " try {\n");
- Printv(helper_code, " return ", imcall, ";\n", NIL);
- Printv(helper_code, " } finally {\n", post_code, "\n }", NIL);
- } else {
- Printv(helper_code, " return ", imcall, ";", NIL);
- }
- if (is_terminator_code) {
- Printv(helper_code, "\n", terminator_code, NIL);
- }
- Printf(helper_code, "\n}\n");
- String *helper_name = NewStringf("%s.SwigConstruct%s(%s)",
- proxy_class_name, proxy_class_name, helper_args);
- Replaceall(proxy_constructor_code, "$imcall", helper_name);
- Delete(helper_name);
- } else {
- Replaceall(proxy_constructor_code, "$imcall", imcall);
- }
-
- Printv(proxy_class_body_code, proxy_constructor_code, "\n", NIL);
-
- Delete(helper_args);
- Delete(pre_code);
- Delete(post_code);
- Delete(terminator_code);
- Delete(construct_tm);
- Delete(attributes);
- Delete(overloaded_name);
- Delete(imcall);
-
- return SWIG_OK;
- }
-
- /* ---------------------------------------------------------------------------
- * D::destructorHandler()
- * --------------------------------------------------------------------------- */
- virtual int destructorHandler(Node *n) {
- Language::destructorHandler(n);
- String *symname = Getattr(n, "sym:name");
-
- Printv(destructor_call, im_dmodule_fq_name, ".", Swig_name_destroy(getNSpace(),symname), "(cast(void*)swigCPtr)", NIL);
- const String *methodmods = Getattr(n, "feature:d:methodmodifiers");
- if (methodmods)
- Setattr(getCurrentClass(), "destructmethodmodifiers", methodmods);
-
- return SWIG_OK;
- }
-
- /* ---------------------------------------------------------------------------
- * D::classHandler()
- * --------------------------------------------------------------------------- */
- virtual int classHandler(Node *n) {
- String *nspace = getNSpace();
- File *class_file = NULL;
-
- proxy_class_name = Copy(Getattr(n, "sym:name"));
- if (nspace) {
- proxy_class_qname = NewStringf("%s.%s", nspace, proxy_class_name);
- } else {
- proxy_class_qname = Copy(proxy_class_name);
- }
-
- if (!addSymbol(proxy_class_name, n, nspace)) {
- return SWIG_ERROR;
- }
-
- assertClassNameValidity(proxy_class_name);
-
- if (split_proxy_dmodule) {
- String *output_directory = outputDirectory(nspace);
- String *filename = NewStringf("%s%s.d", output_directory, proxy_class_name);
- class_file = NewFile(filename, "w", SWIG_output_files());
- Delete(output_directory);
- if (!class_file) {
- FileErrorDisplay(filename);
- Exit(EXIT_FAILURE);
- }
- Append(filenames_list, Copy(filename));
- Delete(filename);
-
- emitBanner(class_file);
- if (nspace) {
- Printf(class_file, "module %s%s.%s;\n", package, nspace, proxy_class_name);
- } else {
- Printf(class_file, "module %s%s;\n", package, proxy_class_name);
- }
- Printf(class_file, "\nstatic import %s;\n", im_dmodule_fq_name);
- }
-
- Clear(proxy_class_imports);
- Clear(proxy_class_enums_code);
- Clear(proxy_class_body_code);
- Clear(proxy_class_epilogue_code);
- Clear(proxy_class_code);
- Clear(destructor_call);
-
-
- // Traverse the tree for this class, using the *Handler()s to generate code
- // to the proxy_class_* variables.
- Language::classHandler(n);
-
-
- writeProxyClassAndUpcasts(n);
- writeDirectorConnectWrapper(n);
-
- Replaceall(proxy_class_code, "$dclassname", proxy_class_name);
-
- String *dclazzname = Swig_name_member(getNSpace(), proxy_class_name, "");
- Replaceall(proxy_class_code, "$dclazzname", dclazzname);
- Delete(dclazzname);
-
- if (split_proxy_dmodule) {
- Printv(class_file, global_proxy_imports, NIL);
- Printv(class_file, proxy_class_imports, NIL);
-
- replaceModuleVariables(proxy_class_code);
- Printv(class_file, proxy_class_code, NIL);
-
- Delete(class_file);
- } else {
- Printv(proxyImportsBuffer(getNSpace()), proxy_class_imports, NIL);
- Printv(proxyCodeBuffer(getNSpace()), proxy_class_code, NIL);
- }
-
- Delete(proxy_class_qname);
- proxy_class_qname = NULL;
- Delete(proxy_class_name);
- proxy_class_name = NULL;
-
- return SWIG_OK;
- }
-
- /* ---------------------------------------------------------------------------
- * D::constantWrapper()
- *
- * Used for wrapping constants declared by #define or %constant and also for
- * (primitive) static member constants initialised inline.
- *
- * If the %dmanifestconst feature is used, the C/C++ constant value is used to
- * initialize a D »const«. If not, a »getter« method is generated which
- * retrieves the value via a call to the C wrapper. However, if there is a
- * %dconstvalue specified, it overrides all other settings.
- * --------------------------------------------------------------------------- */
- virtual int constantWrapper(Node *n) {
- String *symname = Getattr(n, "sym:name");
- if (!addSymbol(symname, n))
- return SWIG_ERROR;
-
- // The %dmanifestconst feature determines if a D manifest constant
- // (const/enum) or a getter function is created.
- if (GetFlag(n, "feature:d:manifestconst") != 1) {
- // Default constant handling will work with any type of C constant. It
- // generates a getter function (which is the same as a read only property
- // in D) which retrieves the value via by calling the C wrapper.
- // Note that this is only called for global constants, static member
- // constants are already handled in staticmemberfunctionHandler().
-
- Swig_save("constantWrapper", n, "value", NIL);
- Swig_save("constantWrapper", n, "tmap:ctype:out", "tmap:imtype:out", "tmap:dtype:out", "tmap:out:null", "tmap:imtype:outattributes", "tmap:dtype:outattributes", NIL);
-
- // Add the stripped quotes back in.
- String *old_value = Getattr(n, "value");
- SwigType *t = Getattr(n, "type");
- if (SwigType_type(t) == T_STRING) {
- Setattr(n, "value", NewStringf("\"%s\"", old_value));
- Delete(old_value);
- } else if (SwigType_type(t) == T_CHAR) {
- Setattr(n, "value", NewStringf("\'%s\'", old_value));
- Delete(old_value);
- }
-
- SetFlag(n, "feature:immutable");
- int result = globalvariableHandler(n);
-
- Swig_restore(n);
- return result;
- }
-
- String *constants_code = NewString("");
- SwigType *t = Getattr(n, "type");
- SwigType *valuetype = Getattr(n, "valuetype");
- ParmList *l = Getattr(n, "parms");
-
- // Attach the non-standard typemaps to the parameter list.
- Swig_typemap_attach_parms("dtype", l, NULL);
-
- // Get D return type.
- String *return_type = NewString("");
- String *tm;
- if ((tm = lookupDTypemap(n, "dtype"))) {
- String *dtypeout = Getattr(n, "tmap:dtype:out");
- if (dtypeout) {
- // The type in the out attribute of the typemap overrides the type
- // in the dtype typemap.
- tm = dtypeout;
- replaceClassname(tm, t);
- }
- Printf(return_type, "%s", tm);
- } else {
- Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number,
- "No dtype typemap defined for %s\n", SwigType_str(t, 0));
- }
-
- const String *itemname = wrapping_member_flag ? variable_name : symname;
-
- String *attributes = Getattr(n, "feature:d:methodmodifiers");
- if (attributes) {
- attributes = Copy(attributes);
- } else {
- attributes = Copy(is_public(n) ? public_string : protected_string);
- }
-
- if (d_version == 1) {
- if (static_flag) {
- Printv(attributes, " static", NIL);
- }
- Printf(constants_code, "\n%s const %s %s = ", attributes, return_type, itemname);
- } else {
- Printf(constants_code, "\n%s enum %s %s = ", attributes, return_type, itemname);
- }
- Delete(attributes);
-
- // Retrieve the override value set via %dconstvalue, if any.
- String *override_value = Getattr(n, "feature:d:constvalue");
- if (override_value) {
- Printf(constants_code, "%s;\n", override_value);
- } else {
- // Just take the value from the C definition and hope it compiles in D.
- if (Getattr(n, "wrappedasconstant")) {
- if (SwigType_type(valuetype) == T_CHAR)
- Printf(constants_code, "\'%(escape)s\';\n", Getattr(n, "staticmembervariableHandler:value"));
- else
- Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value"));
- } else {
- // Add the stripped quotes back in.
- String* value = Getattr(n, "value");
- if (SwigType_type(t) == T_STRING) {
- Printf(constants_code, "\"%s\";\n", value);
- } else if (SwigType_type(t) == T_CHAR) {
- Printf(constants_code, "\'%s\';\n", value);
- } else {
- Printf(constants_code, "%s;\n", value);
- }
- }
- }
-
- // Emit the generated code to appropriate place.
- if (wrapping_member_flag) {
- Printv(proxy_class_body_code, constants_code, NIL);
- } else {
- Printv(proxyCodeBuffer(getNSpace()), constants_code, NIL);
- }
-
- // Cleanup.
- Delete(return_type);
- Delete(constants_code);
-
- return SWIG_OK;
- }
-
- /* ---------------------------------------------------------------------------
- * D::functionWrapper()
- *
- * Generates the C wrapper code for a function and the corresponding
- * declaration in the wrap D module.
- * --------------------------------------------------------------------------- */
- virtual int functionWrapper(Node *n) {
- String *symname = Getattr(n, "sym:name");
- SwigType *t = Getattr(n, "type");
- ParmList *l = Getattr(n, "parms");
- String *tm;
- Parm *p;
- int i;
- String *c_return_type = NewString("");
- String *im_return_type = NewString("");
- String *cleanup = NewString("");
- String *outarg = NewString("");
- String *body = NewString("");
- int num_arguments = 0;
- bool is_void_return;
- String *overloaded_name = getOverloadedName(n);
-
- if (!Getattr(n, "sym:overloaded")) {
- if (!addSymbol(Getattr(n, "sym:name"), n))
- return SWIG_ERROR;
- }
-
- // A new wrapper function object
- Wrapper *f = NewWrapper();
-
- // Make a wrapper name for this function
- String *wname = Swig_name_wrapper(overloaded_name);
-
- /* Attach the non-standard typemaps to the parameter list. */
- Swig_typemap_attach_parms("ctype", l, f);
- Swig_typemap_attach_parms("imtype", l, f);
-
- /* Get return types */
- if ((tm = lookupDTypemap(n, "ctype"))) {
- String *ctypeout = Getattr(n, "tmap:ctype:out");
- if (ctypeout) {
- // The type in the ctype typemap's out attribute overrides the type in
- // the typemap itself.
- tm = ctypeout;
- }
- Printf(c_return_type, "%s", tm);
- } else {
- Swig_warning(WARN_D_TYPEMAP_CTYPE_UNDEF, input_file, line_number,
- "No ctype typemap defined for %s\n", SwigType_str(t, 0));
- }
-
- if ((tm = lookupDTypemap(n, "imtype"))) {
- String *imtypeout = Getattr(n, "tmap:imtype:out");
- if (imtypeout) {
- // The type in the imtype typemap's out attribute overrides the type in
- // the typemap itself.
- tm = imtypeout;
- }
- Printf(im_return_type, "%s", tm);
- } else {
- Swig_warning(WARN_D_TYPEMAP_IMTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(t, 0));
- }
-
- is_void_return = (Cmp(c_return_type, "void") == 0);
- if (!is_void_return)
- Wrapper_add_localv(f, "jresult", c_return_type, "jresult", NIL);
-
- Printv(f->def, " SWIGEXPORT ", c_return_type, " ", wname, "(", NIL);
-
- // Emit all of the local variables for holding arguments.
- emit_parameter_variables(l, f);
-
- /* Attach the standard typemaps */
- emit_attach_parmmaps(l, f);
-
- // Parameter overloading
- Setattr(n, "wrap:parms", l);
- Setattr(n, "wrap:name", wname);
-
- // Wrappers not wanted for some methods where the parameters cannot be overloaded in D
- if (Getattr(n, "sym:overloaded")) {
- // Emit warnings for the few cases that can't be overloaded in D and give up on generating wrapper
- Swig_overload_check(n);
- if (Getattr(n, "overload:ignore")) {
- DelWrapper(f);
- return SWIG_OK;
- }
- }
-
- // Collect the parameter list for the intermediary D module declaration of
- // the generated wrapper function.
- String *im_dmodule_parameters = NewString("(");
-
- /* Get number of required and total arguments */
- num_arguments = emit_num_arguments(l);
- int gencomma = 0;
-
- // Now walk the function parameter list and generate code to get arguments
- for (i = 0, p = l; i < num_arguments; i++) {
-
- while (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- }
-
- SwigType *pt = Getattr(p, "type");
- String *ln = Getattr(p, "lname");
- String *im_param_type = NewString("");
- String *c_param_type = NewString("");
- String *arg = NewString("");
-
- Printf(arg, "j%s", ln);
-
- /* Get the ctype types of the parameter */
- if ((tm = lookupDTypemap(p, "ctype", true))) {
- Printv(c_param_type, tm, NIL);
- } else {
- Swig_warning(WARN_D_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- /* Get the intermediary class parameter types of the parameter */
- if ((tm = lookupDTypemap(p, "imtype", true))) {
- const String *inattributes = Getattr(p, "tmap:imtype:inattributes");
- Printf(im_param_type, "%s%s", inattributes ? inattributes : empty_string, tm);
- } else {
- Swig_warning(WARN_D_TYPEMAP_IMTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- /* Add parameter to intermediary class method */
- if (gencomma)
- Printf(im_dmodule_parameters, ", ");
- Printf(im_dmodule_parameters, "%s %s", im_param_type, arg);
-
- // Add parameter to C function
- Printv(f->def, gencomma ? ", " : "", c_param_type, " ", arg, NIL);
-
- gencomma = 1;
-
- // Get typemap for this argument
- if ((tm = Getattr(p, "tmap:in"))) {
- canThrow(n, "in", p);
- Replaceall(tm, "$input", arg);
- Setattr(p, "emit:input", arg);
- Printf(f->code, "%s\n", tm);
- p = Getattr(p, "tmap:in:next");
- } else {
- Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
- p = nextSibling(p);
- }
- Delete(im_param_type);
- Delete(c_param_type);
- Delete(arg);
- }
-
- /* Insert constraint checking code */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:check"))) {
- canThrow(n, "check", p);
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(f->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:check:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* Insert cleanup code */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:freearg"))) {
- canThrow(n, "freearg", p);
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(cleanup, tm, "\n", NIL);
- p = Getattr(p, "tmap:freearg:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* Insert argument output code */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:argout"))) {
- canThrow(n, "argout", p);
- Replaceall(tm, "$result", "jresult");
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(outarg, tm, "\n", NIL);
- p = Getattr(p, "tmap:argout:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- // Look for usage of throws typemap and the canthrow flag
- ParmList *throw_parm_list = NULL;
- if ((throw_parm_list = Getattr(n, "catchlist"))) {
- Swig_typemap_attach_parms("throws", throw_parm_list, f);
- for (p = throw_parm_list; p; p = nextSibling(p)) {
- if (Getattr(p, "tmap:throws")) {
- canThrow(n, "throws", p);
- }
- }
- }
-
- String *null_attribute = 0;
- // Now write code to make the function call
- if (!native_function_flag) {
-
- Swig_director_emit_dynamic_cast(n, f);
- String *actioncode = emit_action(n);
-
- /* Return value if necessary */
- if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
- canThrow(n, "out", n);
- Replaceall(tm, "$result", "jresult");
-
- if (GetFlag(n, "feature:new"))
- Replaceall(tm, "$owner", "1");
- else
- Replaceall(tm, "$owner", "0");
-
- Printf(f->code, "%s", tm);
- null_attribute = Getattr(n, "tmap:out:null");
- if (Len(tm))
- Printf(f->code, "\n");
- } else {
- Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(t, 0), Getattr(n, "name"));
- }
- emit_return_variable(n, t, f);
- }
-
- /* Output argument output code */
- Printv(f->code, outarg, NIL);
-
- /* Output cleanup code */
- Printv(f->code, cleanup, NIL);
-
- /* Look to see if there is any newfree cleanup code */
- if (GetFlag(n, "feature:new")) {
- if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
- canThrow(n, "newfree", n);
- Printf(f->code, "%s\n", tm);
- }
- }
-
- /* See if there is any return cleanup code */
- if (!native_function_flag) {
- if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
- canThrow(n, "ret", n);
- Printf(f->code, "%s\n", tm);
- }
- }
-
- // Complete D im parameter list and emit the declaration/binding code.
- Printv(im_dmodule_parameters, ")", NIL);
- writeImDModuleFunction(overloaded_name, im_return_type,
- im_dmodule_parameters, wname);
- Delete(im_dmodule_parameters);
-
- // Finish C function header.
- Printf(f->def, ") {");
-
- if (!is_void_return)
- Printv(f->code, " return jresult;\n", NIL);
- Printf(f->code, "}\n");
-
- /* Substitute the cleanup code */
- Replaceall(f->code, "$cleanup", cleanup);
-
- /* Substitute the function name */
- Replaceall(f->code, "$symname", symname);
-
- /* Contract macro modification */
- if (Replaceall(f->code, "SWIG_contract_assert(", "SWIG_contract_assert($null, ") > 0) {
- Setattr(n, "d:canthrow", "1");
- }
-
- if (!null_attribute)
- Replaceall(f->code, "$null", "0");
- else
- Replaceall(f->code, "$null", null_attribute);
-
- /* Dump the function out */
- if (!native_function_flag) {
- Wrapper_print(f, f_wrappers);
-
- // Handle %exception which sets the canthrow attribute.
- if (Getattr(n, "feature:except:canthrow")) {
- Setattr(n, "d:canthrow", "1");
- }
-
- // A very simple check (it is not foolproof) to assist typemap writers
- // with setting the correct features when the want to throw D exceptions
- // from C++ code. It checks for the common methods which set
- // a pending D exception and issues a warning if one of them has been found
- // in the typemap, but the »canthrow« attribute/feature is not set.
- if (!Getattr(n, "d:canthrow")) {
- if (Strstr(f->code, "SWIG_exception")) {
- Swig_warning(WARN_D_CANTHROW_MISSING, input_file, line_number,
- "C code contains a call to SWIG_exception and D code does not handle pending exceptions via the canthrow attribute.\n");
- } else if (Strstr(f->code, "SWIG_DSetPendingException")) {
- Swig_warning(WARN_D_CANTHROW_MISSING, input_file, line_number,
- "C code contains a call to a SWIG_DSetPendingException method and D code does not handle pending exceptions via the canthrow attribute.\n");
- }
- }
- }
-
- // If we are not processing an enum or constant, and we were not generating
- // a wrapper function which will be accessed via a proxy class, write a
- // function to the proxy D module.
- if (!is_wrapping_class()) {
- writeProxyDModuleFunction(n);
- }
-
- // If we are processing a public member variable, write the property-style
- // member function to the proxy class.
- if (wrapping_member_flag) {
- Setattr(n, "proxyfuncname", variable_name);
- Setattr(n, "imfuncname", symname);
-
- writeProxyClassFunction(n);
- }
-
- Delete(c_return_type);
- Delete(im_return_type);
- Delete(cleanup);
- Delete(outarg);
- Delete(body);
- Delete(overloaded_name);
- DelWrapper(f);
- return SWIG_OK;
- }
-
- /* ---------------------------------------------------------------------------
- * D::nativeWrapper()
- * --------------------------------------------------------------------------- */
- virtual int nativeWrapper(Node *n) {
- String *wrapname = Getattr(n, "wrap:name");
-
- if (!addSymbol(wrapname, n))
- return SWIG_ERROR;
-
- if (Getattr(n, "type")) {
- Swig_save("nativeWrapper", n, "name", NIL);
- Setattr(n, "name", wrapname);
- native_function_flag = true;
- functionWrapper(n);
- Swig_restore(n);
- native_function_flag = false;
- } else {
- Swig_error(input_file, line_number, "No return type for %%native method %s.\n", Getattr(n, "wrap:name"));
- }
-
- return SWIG_OK;
- }
-
- /* ---------------------------------------------------------------------------
- * D::classDirector()
- * --------------------------------------------------------------------------- */
- virtual int classDirector(Node *n) {
- String *nspace = Getattr(n, "sym:nspace");
- proxy_class_name = NewString(Getattr(n, "sym:name"));
- if (nspace) {
- proxy_class_qname = NewStringf("%s.%s", nspace, proxy_class_name);
- } else {
- proxy_class_qname = Copy(proxy_class_name);
- }
-
- int success = Language::classDirector(n);
-
- Delete(proxy_class_qname);
- proxy_class_qname = NULL;
- Delete(proxy_class_name);
- proxy_class_name = NULL;
-
- return success;
- }
-
-
- /* ---------------------------------------------------------------------------
- * D::classDirectorInit()
- * --------------------------------------------------------------------------- */
- virtual int classDirectorInit(Node *n) {
- Delete(director_ctor_code);
- director_ctor_code = NewString("$director_new");
-
- // Write C++ director class declaration, for example:
- // class SwigDirector_myclass : public myclass, public Swig::Director {
- String *classname = Swig_class_name(n);
- String *directorname = directorClassName(n);
- String *declaration = Swig_class_declaration(n, directorname);
- const String *base = Getattr(n, "classtype");
-
- Printf(f_directors_h,
- "%s : public %s, public Swig::Director {\n", declaration, base);
- Printf(f_directors_h, "\npublic:\n");
-
- Delete(declaration);
- Delete(directorname);
- Delete(classname);
-
- // Stash for later.
- Setattr(n, "director:ctor", NewString("Swig::Director()"));
-
- // Keep track of the director methods for this class.
- first_class_dmethod = curr_class_dmethod = n_dmethods;
-
- director_callback_typedefs = NewString("");
- director_callback_pointers = NewString("");
- director_dcallbacks_code = NewString("");
-
- return Language::classDirectorInit(n);
- }
-
- /* ---------------------------------------------------------------------------
- * D::classDirectorMethod()
- *
- * Emit a virtual director method to pass a method call on to the
- * underlying D object.
- * --------------------------------------------------------------------------- */
- virtual int classDirectorMethod(Node *n, Node *parent, String *super) {
- String *classname = Getattr(parent, "sym:name");
- String *c_classname = Getattr(parent, "name");
- String *name = Getattr(n, "name");
- String *symname = Getattr(n, "sym:name");
- SwigType *returntype = Getattr(n, "type");
- String *overloaded_name = getOverloadedName(n);
- String *storage = Getattr(n, "storage");
- String *value = Getattr(n, "value");
- String *decl = Getattr(n, "decl");
- String *declaration = NewString("");
- String *tm;
- Parm *p;
- int i;
- Wrapper *w = NewWrapper();
- ParmList *l = Getattr(n, "parms");
- bool is_void = !(Cmp(returntype, "void"));
- String *qualified_return = 0;
- bool pure_virtual = (!(Cmp(storage, "virtual")) && !(Cmp(value, "0")));
- int status = SWIG_OK;
- bool output_director = true;
- String *dirclassname = directorClassName(parent);
- String *qualified_name = NewStringf("%s::%s", dirclassname, name);
- SwigType *c_ret_type = NULL;
- String *dcallback_call_args = NewString("");
- String *imclass_dmethod;
- String *callback_typedef_parms = NewString("");
- String *delegate_parms = NewString("");
- String *proxy_method_param_list = NewString("");
- String *proxy_callback_return_type = NewString("");
- String *callback_def = NewString("");
- String *callback_code = NewString("");
- String *imcall_args = NewString("");
- bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
-
- // Kludge Alert: functionWrapper sets sym:overload properly, but it
- // isn't at this point, so we have to manufacture it ourselves. At least
- // we're consistent with the sym:overload name in functionWrapper. (?? when
- // does the overloaded method name get set?)
-
- imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(getNSpace(), classname, overloaded_name));
-
- qualified_return = SwigType_rcaststr(returntype, "c_result");
-
- if (!is_void && (!ignored_method || pure_virtual)) {
- if (!SwigType_isclass(returntype)) {
- if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
- String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
- Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL);
- Delete(construct_result);
- } else {
- String *base_typename = SwigType_base(returntype);
- String *resolved_typename = SwigType_typedef_resolve_all(base_typename);
- Symtab *symtab = Getattr(n, "sym:symtab");
- Node *typenode = Swig_symbol_clookup(resolved_typename, symtab);
-
- if (SwigType_ispointer(returntype) || (typenode && Getattr(typenode, "abstracts"))) {
- /* initialize pointers to something sane. Same for abstract
- classes when a reference is returned. */
- Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL);
- } else {
- /* If returning a reference, initialize the pointer to a sane
- default - if a D exception occurs, then the pointer returns
- something other than a NULL-initialized reference. */
- SwigType *noref_type = SwigType_del_reference(Copy(returntype));
- String *noref_ltype = SwigType_lstr(noref_type, 0);
- String *return_ltype = SwigType_lstr(returntype, 0);
-
- Wrapper_add_localv(w, "result_default", "static", noref_ltype, "result_default", NIL);
- Wrapper_add_localv(w, "c_result", return_ltype, "c_result", NIL);
- Printf(w->code, "result_default = SwigValueInit< %s >();\n", noref_ltype);
- Printf(w->code, "c_result = &result_default;\n");
- Delete(return_ltype);
- Delete(noref_ltype);
- Delete(noref_type);
- }
-
- Delete(base_typename);
- Delete(resolved_typename);
- }
- } else {
- SwigType *vt;
-
- vt = cplus_value_type(returntype);
- if (!vt) {
- Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), NIL);
- } else {
- Wrapper_add_localv(w, "c_result", SwigType_lstr(vt, "c_result"), NIL);
- Delete(vt);
- }
- }
- }
-
- /* Create the intermediate class wrapper */
- tm = lookupDTypemap(n, "imtype");
- if (tm) {
- String *imtypeout = Getattr(n, "tmap:imtype:out");
- if (imtypeout) {
- // The type in the imtype typemap's out attribute overrides the type
- // in the typemap.
- tm = imtypeout;
- }
- Printf(callback_def, "\nprivate extern(C) %s swigDirectorCallback_%s_%s(void* dObject", tm, classname, overloaded_name);
- Printv(proxy_callback_return_type, tm, NIL);
- } else {
- Swig_warning(WARN_D_TYPEMAP_IMTYPE_UNDEF, input_file, line_number,
- "No imtype typemap defined for %s\n", SwigType_str(returntype, 0));
- }
-
- if ((c_ret_type = Swig_typemap_lookup("ctype", n, "", 0))) {
- if (!is_void && !ignored_method) {
- String *jretval_decl = NewStringf("%s jresult", c_ret_type);
- Wrapper_add_localv(w, "jresult", jretval_decl, "= 0", NIL);
- Delete(jretval_decl);
- }
- } else {
- Swig_warning(WARN_D_TYPEMAP_CTYPE_UNDEF, input_file, line_number,
- "No ctype typemap defined for %s for use in %s::%s (skipping director method)\n",
- SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- output_director = false;
- }
-
- Swig_director_parms_fixup(l);
-
- // Attach the standard typemaps.
- Swig_typemap_attach_parms("out", l, 0);
- Swig_typemap_attach_parms("ctype", l, 0);
- Swig_typemap_attach_parms("imtype", l, 0);
- Swig_typemap_attach_parms("dtype", l, 0);
- Swig_typemap_attach_parms("directorin", l, w);
- Swig_typemap_attach_parms("ddirectorin", l, 0);
- Swig_typemap_attach_parms("directorargout", l, w);
-
- // Preamble code.
- if (!ignored_method)
- Printf(w->code, "if (!swig_callback_%s) {\n", overloaded_name);
-
- if (!pure_virtual) {
- String *super_call = Swig_method_call(super, l);
- if (is_void) {
- Printf(w->code, "%s;\n", super_call);
- if (!ignored_method)
- Printf(w->code, "return;\n");
- } else {
- Printf(w->code, "return %s;\n", super_call);
- }
- Delete(super_call);
- } else {
- Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"%s::%s\");\n", SwigType_namestr(c_classname), SwigType_namestr(name));
- if (!is_void)
- Printf(w->code, "return %s;", qualified_return);
- else if (!ignored_method)
- Printf(w->code, "return;\n");
- }
-
- if (!ignored_method)
- Printf(w->code, "} else {\n");
-
- // Go through argument list.
- for (i = 0, p = l; p; ++i) {
- /* Is this superfluous? */
- while (checkAttribute(p, "tmap:directorin:numinputs", "0")) {
- p = Getattr(p, "tmap:directorin:next");
- }
-
- SwigType *pt = Getattr(p, "type");
- String *ln = makeParameterName(n, p, i, false);
- String *c_param_type = NULL;
- String *c_decl = NewString("");
- String *arg = NewString("");
-
- Printf(arg, "j%s", ln);
-
- // Add each parameter to the D callback invocation arguments.
- Printf(dcallback_call_args, ", %s", arg);
-
- /* Get parameter's intermediary C type */
- if ((c_param_type = lookupDTypemap(p, "ctype", true))) {
- String *ctypeout = Getattr(p, "tmap:ctype:out");
- if (ctypeout) {
- // The type in the ctype typemap's out attribute overrides the type
- // in the typemap itself.
- c_param_type = ctypeout;
- }
-
- /* Add to local variables */
- Printf(c_decl, "%s %s", c_param_type, arg);
- if (!ignored_method)
- Wrapper_add_localv(w, arg, c_decl, (!(SwigType_ispointer(pt) || SwigType_isreference(pt)) ? "" : "= 0"), NIL);
-
- /* Add input marshalling code */
- if ((tm = Getattr(p, "tmap:directorin"))) {
-
- Setattr(p, "emit:directorinput", arg);
- Replaceall(tm, "$input", arg);
- Replaceall(tm, "$owner", "0");
-
- if (Len(tm))
- if (!ignored_method)
- Printf(w->code, "%s\n", tm);
-
- // Add parameter type to the C typedef for the D callback function.
- Printf(callback_typedef_parms, ", %s", c_param_type);
-
- /* Add parameter to the intermediate class code if generating the
- * intermediate's upcall code */
- if ((tm = lookupDTypemap(p, "imtype", true))) {
- String *imtypeout = Getattr(p, "tmap:imtype:out");
- if (imtypeout) {
- // The type in the imtype typemap's out attribute overrides the
- // type in the typemap itself.
- tm = imtypeout;
- }
- const String *im_directorinattributes = Getattr(p, "tmap:imtype:directorinattributes");
-
- // TODO: Is this copy really needed?
- String *din = Copy(lookupDTypemap(p, "ddirectorin", true));
-
- if (din) {
- Replaceall(din, "$winput", ln);
-
- Printf(delegate_parms, ", ");
- if (i > 0) {
- Printf(proxy_method_param_list, ", ");
- Printf(imcall_args, ", ");
- }
- Printf(delegate_parms, "%s%s %s", im_directorinattributes ? im_directorinattributes : empty_string, tm, ln);
-
- if (Cmp(din, ln)) {
- Printv(imcall_args, din, NIL);
- } else {
- Printv(imcall_args, ln, NIL);
- }
-
- Delete(din);
-
- // Get the parameter type in the proxy D class (used later when
- // generating the overload checking code for the directorConnect
- // function).
- if ((tm = lookupDTypemap(p, "dtype", true))) {
- Printf(proxy_method_param_list, "%s", tm);
- } else {
- Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number,
- "No dtype typemap defined for %s\n", SwigType_str(pt, 0));
- }
- } else {
- Swig_warning(WARN_D_TYPEMAP_DDIRECTORIN_UNDEF, input_file, line_number,
- "No ddirectorin typemap defined for %s for use in %s::%s (skipping director method)\n",
- SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- output_director = false;
- }
- } else {
- Swig_warning(WARN_D_TYPEMAP_IMTYPE_UNDEF, input_file, line_number,
- "No imtype typemap defined for %s for use in %s::%s (skipping director method)\n",
- SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- output_director = false;
- }
-
- p = Getattr(p, "tmap:directorin:next");
- } else {
- Swig_warning(WARN_D_TYPEMAP_DDIRECTORIN_UNDEF, input_file, line_number,
- "No or improper directorin typemap defined for argument %s for use in %s::%s (skipping director method)\n",
- SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- p = nextSibling(p);
- output_director = false;
- }
- } else {
- Swig_warning(WARN_D_TYPEMAP_CTYPE_UNDEF, input_file, line_number,
- "No ctype typemap defined for %s for use in %s::%s (skipping director method)\n",
- SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- output_director = false;
- p = nextSibling(p);
- }
-
- Delete(arg);
- Delete(c_decl);
- Delete(c_param_type);
- Delete(ln);
- }
-
- /* header declaration, start wrapper definition */
- String *target;
- SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
- target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
- Printf(w->def, "%s", target);
- Delete(qualified_name);
- Delete(target);
- target = Swig_method_decl(rtype, decl, name, l, 1);
- Printf(declaration, " virtual %s", target);
- Delete(target);
-
- // Add any exception specifications to the methods in the director class
- if (Getattr(n, "noexcept")) {
- Append(w->def, " noexcept");
- Append(declaration, " noexcept");
- }
- ParmList *throw_parm_list = NULL;
- if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
- int gencomma = 0;
-
- Append(w->def, " throw(");
- Append(declaration, " throw(");
-
- if (throw_parm_list)
- Swig_typemap_attach_parms("throws", throw_parm_list, 0);
- for (p = throw_parm_list; p; p = nextSibling(p)) {
- if (Getattr(p, "tmap:throws")) {
- if (gencomma++) {
- Append(w->def, ", ");
- Append(declaration, ", ");
- }
- Printf(w->def, "%s", SwigType_str(Getattr(p, "type"), 0));
- Printf(declaration, "%s", SwigType_str(Getattr(p, "type"), 0));
- }
- }
-
- Append(w->def, ")");
- Append(declaration, ")");
- }
-
- Append(w->def, " {");
- Append(declaration, ";\n");
-
- // Finish the callback function declaraction.
- Printf(callback_def, "%s)", delegate_parms);
- Printf(callback_def, " {\n");
-
- /* Emit the intermediate class's upcall to the actual class */
-
- String *upcall = NewStringf("(cast(%s)dObject).%s(%s)", classname, symname, imcall_args);
-
- if (!is_void) {
- if ((tm = lookupDTypemap(n, "ddirectorout"))) {
- Replaceall(tm, "$dcall", upcall);
- Printf(callback_code, " return %s;\n", tm);
- }
- } else {
- Printf(callback_code, " %s;\n", upcall);
- }
-
- Printf(callback_code, "}\n");
- Delete(upcall);
-
- if (!ignored_method) {
- if (!is_void)
- Printf(w->code, "jresult = (%s) ", c_ret_type);
-
- Printf(w->code, "swig_callback_%s(d_object%s);\n", overloaded_name, dcallback_call_args);
-
- if (!is_void) {
- String *jresult_str = NewString("jresult");
- String *result_str = NewString("c_result");
-
- /* Copy jresult into c_result... */
- if ((tm = Swig_typemap_lookup("directorout", n, result_str, w))) {
- Replaceall(tm, "$input", jresult_str);
- Replaceall(tm, "$result", result_str);
- Printf(w->code, "%s\n", tm);
- } else {
- Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
- "Unable to use return type %s used in %s::%s (skipping director method)\n",
- SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- output_director = false;
- }
-
- Delete(jresult_str);
- Delete(result_str);
- }
-
- /* Marshal outputs */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:directorargout"))) {
- canThrow(n, "directorargout", p);
- Replaceall(tm, "$result", "jresult");
- Replaceall(tm, "$input", Getattr(p, "emit:directorinput"));
- Printv(w->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:directorargout:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* Terminate wrapper code */
- Printf(w->code, "}\n");
- if (!is_void)
- Printf(w->code, "return %s;", qualified_return);
- }
-
- Printf(w->code, "}");
-
- // We expose virtual protected methods via an extra public inline method which makes a straight call to the wrapped class' method
- String *inline_extra_method = NewString("");
- if (dirprot_mode() && !is_public(n) && !pure_virtual) {
- Printv(inline_extra_method, declaration, NIL);
- String *extra_method_name = NewStringf("%sSwigPublic", name);
- Replaceall(inline_extra_method, name, extra_method_name);
- Replaceall(inline_extra_method, ";\n", " {\n ");
- if (!is_void)
- Printf(inline_extra_method, "return ");
- String *methodcall = Swig_method_call(super, l);
- Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
- Delete(methodcall);
- Delete(extra_method_name);
- }
-
- /* emit the director method */
- if (status == SWIG_OK && output_director) {
- if (!is_void) {
- Replaceall(w->code, "$null", qualified_return);
- } else {
- Replaceall(w->code, "$null", "");
- }
- if (!ignored_method)
- Printv(director_dcallbacks_code, callback_def, callback_code, NIL);
- if (!Getattr(n, "defaultargs")) {
- Replaceall(w->code, "$symname", symname);
- Wrapper_print(w, f_directors);
- Printv(f_directors_h, declaration, NIL);
- Printv(f_directors_h, inline_extra_method, NIL);
- }
- }
-
- if (!ignored_method) {
- // Register the upcall method so that the callback registering code can
- // be written later.
-
- // We cannot directly use n here because its »type« attribute does not
- // the full return type any longer after Language::functionHandler has
- // returned.
- String *dp_return_type = lookupDTypemap(n, "dtype");
- if (dp_return_type) {
- String *dtypeout = Getattr(n, "tmap:dtype:out");
- if (dtypeout) {
- // The type in the dtype typemap's out attribute overrides the type
- // in the typemap itself.
- dp_return_type = dtypeout;
- replaceClassname(dp_return_type, returntype);
- }
- } else {
- Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number,
- "No dtype typemap defined for %s\n", SwigType_str(returntype, 0));
- dp_return_type = NewString("");
- }
-
- UpcallData *udata = addUpcallMethod(imclass_dmethod, symname, decl, overloaded_name, dp_return_type, proxy_method_param_list);
- Delete(dp_return_type);
-
- // Write the global callback function pointer on the C code.
- String *methid = Getattr(udata, "class_methodidx");
-
- Printf(director_callback_typedefs, " typedef %s (* SWIG_Callback%s_t)", c_ret_type, methid);
- Printf(director_callback_typedefs, "(void *dobj%s);\n", callback_typedef_parms);
- Printf(director_callback_pointers, " SWIG_Callback%s_t swig_callback_%s;\n", methid, overloaded_name);
-
- // Write the type alias for the callback to the intermediary D module.
- String *proxy_callback_type = NewString("");
- String *dirClassName = directorClassName(parent);
- Printf(proxy_callback_type, "%s_Callback%s", dirClassName, methid);
- Printf(im_dmodule_code, "alias extern(C) %s function(void*%s) %s;\n", proxy_callback_return_type, delegate_parms, proxy_callback_type);
- Delete(proxy_callback_type);
- Delete(dirClassName);
- }
-
- Delete(qualified_return);
- Delete(c_ret_type);
- Delete(declaration);
- Delete(callback_typedef_parms);
- Delete(delegate_parms);
- Delete(proxy_method_param_list);
- Delete(callback_def);
- Delete(callback_code);
- DelWrapper(w);
-
- return status;
- }
-
- /* ---------------------------------------------------------------------------
- * D::classDirectorConstructor()
- * --------------------------------------------------------------------------- */
- virtual int classDirectorConstructor(Node *n) {
- Node *parent = parentNode(n);
- String *decl = Getattr(n, "decl");;
- String *supername = Swig_class_name(parent);
- String *dirclassname = directorClassName(parent);
- String *sub = NewString("");
- Parm *p;
- ParmList *superparms = Getattr(n, "parms");
- ParmList *parms;
- int argidx = 0;
-
- /* Assign arguments to superclass's parameters, if not already done */
- for (p = superparms; p; p = nextSibling(p)) {
- String *pname = Getattr(p, "name");
-
- if (!pname) {
- pname = NewStringf("arg%d", argidx++);
- Setattr(p, "name", pname);
- }
- }
-
- // TODO: Is this copy needed?
- parms = CopyParmList(superparms);
-
- if (!Getattr(n, "defaultargs")) {
- /* constructor */
- {
- String *basetype = Getattr(parent, "classtype");
- String *target = Swig_method_decl(0, decl, dirclassname, parms, 0);
- String *call = Swig_csuperclass_call(0, basetype, superparms);
- String *classtype = SwigType_namestr(Getattr(n, "name"));
-
- Printf(f_directors, "%s::%s : %s, %s {\n", dirclassname, target, call, Getattr(parent, "director:ctor"));
- Printf(f_directors, " swig_init_callbacks();\n");
- Printf(f_directors, "}\n\n");
-
- Delete(classtype);
- Delete(target);
- Delete(call);
- }
-
- /* constructor header */
- {
- String *target = Swig_method_decl(0, decl, dirclassname, parms, 1);
- Printf(f_directors_h, " %s;\n", target);
- Delete(target);
- }
- }
-
- Delete(sub);
- Delete(supername);
- Delete(parms);
- Delete(dirclassname);
- return Language::classDirectorConstructor(n);
- }
-
- /* ---------------------------------------------------------------------------
- * D::classDirectorDefaultConstructor()
- * --------------------------------------------------------------------------- */
- virtual int classDirectorDefaultConstructor(Node *n) {
- String *dirclassname = directorClassName(n);
- String *classtype = SwigType_namestr(Getattr(n, "name"));
- Wrapper *w = NewWrapper();
-
- Printf(w->def, "%s::%s() : %s {", dirclassname, dirclassname, Getattr(n, "director:ctor"));
- Printf(w->code, "}\n");
- Wrapper_print(w, f_directors);
-
- Printf(f_directors_h, " %s();\n", dirclassname);
- DelWrapper(w);
- Delete(classtype);
- Delete(dirclassname);
- return Language::classDirectorDefaultConstructor(n);
- }
-
- /* ---------------------------------------------------------------------------
- * D::classDirectorDestructor()
- * --------------------------------------------------------------------------- */
- virtual int classDirectorDestructor(Node *n) {
- Node *current_class = getCurrentClass();
- String *dirclassname = directorClassName(current_class);
- Wrapper *w = NewWrapper();
-
- if (Getattr(n, "noexcept")) {
- Printf(f_directors_h, " virtual ~%s() noexcept;\n", dirclassname);
- Printf(w->def, "%s::~%s() noexcept {\n", dirclassname, dirclassname);
- } else if (Getattr(n, "throw")) {
- Printf(f_directors_h, " virtual ~%s() throw();\n", dirclassname);
- Printf(w->def, "%s::~%s() throw() {\n", dirclassname, dirclassname);
- } else {
- Printf(f_directors_h, " virtual ~%s();\n", dirclassname);
- Printf(w->def, "%s::~%s() {\n", dirclassname, dirclassname);
- }
-
- Printv(w->code, "}\n", NIL);
-
- Wrapper_print(w, f_directors);
-
- DelWrapper(w);
- Delete(dirclassname);
- return SWIG_OK;
- }
-
- /* ---------------------------------------------------------------------------
- * D::classDirectorEnd()
- * --------------------------------------------------------------------------- */
- virtual int classDirectorEnd(Node *n) {
- int i;
- String *director_classname = directorClassName(n);
-
- Wrapper *w = NewWrapper();
-
- if (Len(director_callback_typedefs) > 0) {
- Printf(f_directors_h, "\n%s", director_callback_typedefs);
- }
-
- Printf(f_directors_h, " void swig_connect_director(void* dobj");
-
- Printf(w->def, "void %s::swig_connect_director(void* dobj", director_classname);
- Printf(w->code, "d_object = dobj;");
-
- for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
- UpcallData *udata = Getitem(dmethods_seq, i);
- String *methid = Getattr(udata, "class_methodidx");
- String *overname = Getattr(udata, "overname");
-
- Printf(f_directors_h, ", SWIG_Callback%s_t callback%s", methid, overname);
- Printf(w->def, ", SWIG_Callback%s_t callback_%s", methid, overname);
- Printf(w->code, "swig_callback_%s = callback_%s;\n", overname, overname);
- }
-
- Printf(f_directors_h, ");\n");
- Printf(w->def, ") {");
-
- Printf(f_directors_h, "\nprivate:\n");
- Printf(f_directors_h, " void swig_init_callbacks();\n");
- Printf(f_directors_h, " void *d_object;\n");
- if (Len(director_callback_pointers) > 0) {
- Printf(f_directors_h, "%s", director_callback_pointers);
- }
- Printf(f_directors_h, "};\n\n");
- Printf(w->code, "}\n\n");
-
- Printf(w->code, "void %s::swig_init_callbacks() {\n", director_classname);
- for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
- UpcallData *udata = Getitem(dmethods_seq, i);
- String *overname = Getattr(udata, "overname");
- Printf(w->code, "swig_callback_%s = 0;\n", overname);
- }
- Printf(w->code, "}");
-
- Wrapper_print(w, f_directors);
-
- DelWrapper(w);
-
- return Language::classDirectorEnd(n);
- }
-
- /* ---------------------------------------------------------------------------
- * D::classDirectorDisown()
- * --------------------------------------------------------------------------- */
- virtual int classDirectorDisown(Node *n) {
- (void) n;
- return SWIG_OK;
- }
-
- /* ---------------------------------------------------------------------------
- * D::replaceSpecialVariables()
- * --------------------------------------------------------------------------- */
- virtual void replaceSpecialVariables(String *method, String *tm, Parm *parm) {
- (void)method;
- SwigType *type = Getattr(parm, "type");
-
- // Just assume that this goes to the proxy class, we cannot know.
- replaceClassname(tm, type);
- }
-
-protected:
- /* ---------------------------------------------------------------------------
- * D::extraDirectorProtectedCPPMethodsRequired()
- * --------------------------------------------------------------------------- */
- virtual bool extraDirectorProtectedCPPMethodsRequired() const {
- return false;
- }
-
-private:
- /* ---------------------------------------------------------------------------
- * D::writeImDModuleFunction()
- *
- * Writes a function declaration for the given (C) wrapper function to the
- * intermediary D module.
- *
- * d_name - The name the function in the intermediary D module will get.
- * return type - The return type of the function in the C wrapper.
- * parameters - The parameter list of the C wrapper function.
- * wrapper_function_name - The name of the exported function in the C wrapper
- * (usually d_name prefixed by »D_«).
- * --------------------------------------------------------------------------- */
- void writeImDModuleFunction(const_String_or_char_ptr d_name,
- const_String_or_char_ptr return_type, const_String_or_char_ptr parameters,
- const_String_or_char_ptr wrapper_function_name) {
-
- // TODO: Add support for static linking here.
- Printf(im_dmodule_code, "SwigExternC!(%s function%s) %s;\n", return_type,
- parameters, d_name);
- Printv(wrapper_loader_bind_code, wrapper_loader_bind_command, NIL);
- Replaceall(wrapper_loader_bind_code, "$function", d_name);
- Replaceall(wrapper_loader_bind_code, "$symbol", wrapper_function_name);
- }
-
- /* ---------------------------------------------------------------------------
- * D::writeProxyClassFunction()
- *
- * Creates a D proxy function for a C++ function in the wrapped class. Used
- * for both static and non-static C++ class functions.
- *
- * The Node must contain two extra attributes.
- * - "proxyfuncname": The name of the D proxy function.
- * - "imfuncname": The corresponding function in the intermediary D module.
- * --------------------------------------------------------------------------- */
- void writeProxyClassFunction(Node *n) {
- SwigType *t = Getattr(n, "type");
- ParmList *l = Getattr(n, "parms");
- String *intermediary_function_name = Getattr(n, "imfuncname");
- String *proxy_function_name = Getattr(n, "proxyfuncname");
- String *tm;
- Parm *p;
- int i;
- String *imcall = NewString("");
- String *return_type = NewString("");
- String *function_code = NewString("");
- bool setter_flag = false;
- String *pre_code = NewString("");
- String *post_code = NewString("");
- String *terminator_code = NewString("");
-
- // Wrappers not wanted for some methods where the parameters cannot be
- // overloaded in D.
- if (Getattr(n, "overload:ignore"))
- return;
-
- // Don't generate proxy method for additional explicitcall method used in
- // directors.
- if (GetFlag(n, "explicitcall"))
- return;
-
- // RESEARCH: What is this good for?
- if (l) {
- if (SwigType_type(Getattr(l, "type")) == T_VOID) {
- l = nextSibling(l);
- }
- }
-
- /* Attach the non-standard typemaps to the parameter list */
- Swig_typemap_attach_parms("in", l, NULL);
- Swig_typemap_attach_parms("dtype", l, NULL);
- Swig_typemap_attach_parms("din", l, NULL);
-
- // Get return types.
- if ((tm = lookupDTypemap(n, "dtype"))) {
- String *dtypeout = Getattr(n, "tmap:dtype:out");
- if (dtypeout) {
- // The type in the dtype typemap's out attribute overrides the type in
- // the typemap.
- tm = dtypeout;
- replaceClassname(tm, t);
- }
- Printf(return_type, "%s", tm);
- } else {
- Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number,
- "No dtype typemap defined for %s\n", SwigType_str(t, 0));
- }
-
- if (wrapping_member_flag) {
- // Check if this is a setter method for a public member.
- const String *setter_name = Swig_name_set(getNSpace(),
- Swig_name_member(0, proxy_class_name, variable_name));
-
- if (Cmp(Getattr(n, "sym:name"), setter_name) == 0) {
- setter_flag = true;
- }
- }
-
- // Write function modifiers.
- {
- String *modifiers;
-
- const String *mods_override = Getattr(n, "feature:d:methodmodifiers");
- if (mods_override) {
- modifiers = Copy(mods_override);
- } else {
- modifiers = Copy(is_public(n) ? public_string : protected_string);
-
- if (Getattr(n, "override")) {
- Printf(modifiers, " override");
- }
- }
-
- if (is_smart_pointer()) {
- // Smart pointer classes do not mirror the inheritance hierarchy of the
- // underlying pointer type, so no override required.
- Replaceall(modifiers, "override", "");
- }
-
- Chop(modifiers);
-
- if (static_flag) {
- Printf(modifiers, " static");
- }
-
- Printf(function_code, "%s ", modifiers);
- Delete(modifiers);
- }
-
- // Complete the function declaration up to the parameter list.
- Printf(function_code, "%s %s(", return_type, proxy_function_name);
-
- // Write the wrapper function call up to the parameter list.
- Printv(imcall, im_dmodule_fq_name, ".$imfuncname(", NIL);
- if (!static_flag) {
- Printf(imcall, "cast(void*)swigCPtr");
- }
-
- String *proxy_param_types = NewString("");
-
- // Write the parameter list for the proxy function declaration and the
- // wrapper function call.
- emit_mark_varargs(l);
- int gencomma = !static_flag;
- for (i = 0, p = l; p; i++) {
- // Ignored varargs.
- if (checkAttribute(p, "varargs:ignore", "1")) {
- p = nextSibling(p);
- continue;
- }
-
- // Ignored parameters.
- if (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- continue;
- }
-
- // Ignore the 'this' argument for variable wrappers.
- if (!(variable_wrapper_flag && i == 0)) {
- String *param_name = makeParameterName(n, p, i, setter_flag);
- SwigType *pt = Getattr(p, "type");
-
- // Write the wrapper function call argument.
- {
- if (gencomma) {
- Printf(imcall, ", ");
- }
-
- if ((tm = lookupDTypemap(p, "din", true))) {
- Replaceall(tm, "$dinput", param_name);
- String *pre = Getattr(p, "tmap:din:pre");
- if (pre) {
- replaceClassname(pre, pt);
- Replaceall(pre, "$dinput", param_name);
- if (Len(pre_code) > 0)
- Printf(pre_code, "\n");
- Printv(pre_code, pre, NIL);
- }
- String *post = Getattr(p, "tmap:din:post");
- if (post) {
- replaceClassname(post, pt);
- Replaceall(post, "$dinput", param_name);
- if (Len(post_code) > 0)
- Printf(post_code, "\n");
- Printv(post_code, post, NIL);
- }
- String *terminator = Getattr(p, "tmap:din:terminator");
- if (terminator) {
- replaceClassname(terminator, pt);
- Replaceall(terminator, "$dinput", param_name);
- if (Len(terminator_code) > 0)
- Insert(terminator_code, 0, "\n");
- Insert(terminator_code, 0, terminator);
- }
- Printv(imcall, tm, NIL);
- } else {
- Swig_warning(WARN_D_TYPEMAP_DIN_UNDEF, input_file, line_number,
- "No din typemap defined for %s\n", SwigType_str(pt, 0));
- }
- }
-
- // Write the D proxy function parameter.
- {
- String *proxy_type = NewString("");
-
- if ((tm = lookupDTypemap(p, "dtype"))) {
- const String *inattributes = Getattr(p, "tmap:dtype:inattributes");
- Printf(proxy_type, "%s%s", inattributes ? inattributes : empty_string, tm);
- } else {
- Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number,
- "No dtype typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- if (gencomma >= 2) {
- Printf(function_code, ", ");
- Printf(proxy_param_types, ", ");
- }
- gencomma = 2;
- Printf(function_code, "%s %s", proxy_type, param_name);
- Append(proxy_param_types, proxy_type);
-
- Delete(proxy_type);
- }
-
- Delete(param_name);
- }
- p = Getattr(p, "tmap:in:next");
- }
-
- Printf(imcall, ")");
- Printf(function_code, ") ");
-
- if (d_version > 1 && wrapping_member_flag) {
- Printf(function_code, "@property ");
- }
-
- if (wrapMemberFunctionAsDConst(n)) {
- Printf(function_code, "const ");
- }
-
- // Lookup the code used to convert the wrapper return value to the proxy
- // function return type.
- if ((tm = lookupDTypemap(n, "dout"))) {
- replaceExcode(n, tm, "dout", n);
- bool is_pre_code = Len(pre_code) > 0;
- bool is_post_code = Len(post_code) > 0;
- bool is_terminator_code = Len(terminator_code) > 0;
- if (is_pre_code || is_post_code || is_terminator_code) {
- if (is_post_code) {
- Insert(tm, 0, "\n try ");
- Printv(tm, " finally {\n", post_code, "\n }", NIL);
- } else {
- Insert(tm, 0, "\n ");
- }
- if (is_pre_code) {
- Insert(tm, 0, pre_code);
- Insert(tm, 0, "\n");
- }
- if (is_terminator_code) {
- Printv(tm, "\n", terminator_code, NIL);
- }
- Insert(tm, 0, "{");
- Printv(tm, "}", NIL);
- }
- if (GetFlag(n, "feature:new"))
- Replaceall(tm, "$owner", "true");
- else
- Replaceall(tm, "$owner", "false");
- replaceClassname(tm, t);
-
- // For director methods: generate code to selectively make a normal
- // polymorphic call or an explicit method call. Needed to prevent infinite
- // recursion when calling director methods.
- Node *explicit_n = Getattr(n, "explicitcallnode");
- if (explicit_n && Swig_directorclass(getCurrentClass())) {
- String *ex_overloaded_name = getOverloadedName(explicit_n);
- String *ex_intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, ex_overloaded_name);
-
- String *ex_imcall = Copy(imcall);
- Replaceall(ex_imcall, "$imfuncname", ex_intermediary_function_name);
- Replaceall(imcall, "$imfuncname", intermediary_function_name);
-
- String *excode = NewString("");
- if (!Cmp(return_type, "void"))
- Printf(excode, "if (swigIsMethodOverridden!(%s delegate(%s), %s function(%s), %s)()) %s; else %s",
- return_type, proxy_param_types, return_type, proxy_param_types, proxy_function_name, ex_imcall, imcall);
- else
- Printf(excode, "((swigIsMethodOverridden!(%s delegate(%s), %s function(%s), %s)()) ? %s : %s)",
- return_type, proxy_param_types, return_type, proxy_param_types, proxy_function_name, ex_imcall, imcall);
-
- Clear(imcall);
- Printv(imcall, excode, NIL);
- Delete(ex_overloaded_name);
- Delete(excode);
- } else {
- Replaceall(imcall, "$imfuncname", intermediary_function_name);
- }
- Replaceall(tm, "$imfuncname", intermediary_function_name);
- Replaceall(tm, "$imcall", imcall);
- } else {
- Swig_warning(WARN_D_TYPEMAP_DOUT_UNDEF, input_file, line_number,
- "No dout typemap defined for %s\n", SwigType_str(t, 0));
- }
-
- Delete(proxy_param_types);
-
- // The whole function body is now in stored tm (if there was a matching type
- // map, of course), so simply append it to the code buffer. The braces are
- // included in the typemap.
- Printv(function_code, tm, NIL);
-
- // Write function code buffer to the class code.
- Printv(proxy_class_body_code, "\n", function_code, "\n", NIL);
-
- Delete(pre_code);
- Delete(post_code);
- Delete(terminator_code);
- Delete(function_code);
- Delete(return_type);
- Delete(imcall);
- }
-
- /* ---------------------------------------------------------------------------
- * D::writeProxyDModuleFunction()
- * --------------------------------------------------------------------------- */
- void writeProxyDModuleFunction(Node *n) {
- SwigType *t = Getattr(n, "type");
- ParmList *l = Getattr(n, "parms");
- String *tm;
- Parm *p;
- int i;
- String *imcall = NewString("");
- String *return_type = NewString("");
- String *function_code = NewString("");
- int num_arguments = 0;
- String *overloaded_name = getOverloadedName(n);
- String *func_name = NULL;
- String *pre_code = NewString("");
- String *post_code = NewString("");
- String *terminator_code = NewString("");
-
- // RESEARCH: What is this good for?
- if (l) {
- if (SwigType_type(Getattr(l, "type")) == T_VOID) {
- l = nextSibling(l);
- }
- }
-
- /* Attach the non-standard typemaps to the parameter list */
- Swig_typemap_attach_parms("dtype", l, NULL);
- Swig_typemap_attach_parms("din", l, NULL);
-
- /* Get return types */
- if ((tm = lookupDTypemap(n, "dtype"))) {
- String *dtypeout = Getattr(n, "tmap:dtype:out");
- if (dtypeout) {
- // The type in the dtype typemap's out attribute overrides the type in
- // the typemap.
- tm = dtypeout;
- replaceClassname(tm, t);
- }
- Printf(return_type, "%s", tm);
- } else {
- Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number,
- "No dtype typemap defined for %s\n", SwigType_str(t, 0));
- }
-
- /* Change function name for global variables */
- if (global_variable_flag) {
- // RESEARCH: Is the Copy() needed here?
- func_name = Copy(variable_name);
- } else {
- func_name = Copy(Getattr(n, "sym:name"));
- }
-
- /* Start generating the function */
- const String *outattributes = Getattr(n, "tmap:dtype:outattributes");
- if (outattributes)
- Printf(function_code, " %s\n", outattributes);
-
- const String *methodmods = Getattr(n, "feature:d:methodmodifiers");
- // TODO: Check if is_public(n) could possibly make any sense here
- // (private global functions would be useless anyway?).
- methodmods = methodmods ? methodmods : empty_string;
-
- Printf(function_code, "\n%s%s %s(", methodmods, return_type, func_name);
- Printv(imcall, im_dmodule_fq_name, ".", overloaded_name, "(", NIL);
-
- /* Get number of required and total arguments */
- num_arguments = emit_num_arguments(l);
-
- int gencomma = 0;
-
- /* Output each parameter */
- for (i = 0, p = l; i < num_arguments; i++) {
-
- /* Ignored parameters */
- while (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- }
-
- SwigType *pt = Getattr(p, "type");
- String *param_type = NewString("");
-
- // Get the D parameter type.
- if ((tm = lookupDTypemap(p, "dtype", true))) {
- const String *inattributes = Getattr(p, "tmap:dtype:inattributes");
- Printf(param_type, "%s%s", inattributes ? inattributes : empty_string, tm);
- } else {
- Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number,
- "No dtype typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- if (gencomma)
- Printf(imcall, ", ");
-
- const bool generating_setter = global_variable_flag || wrapping_member_flag;
- String *arg = makeParameterName(n, p, i, generating_setter);
-
- // Get the D code to convert the parameter value to the type used in the
- // wrapper D module.
- if ((tm = lookupDTypemap(p, "din", true))) {
- Replaceall(tm, "$dinput", arg);
- String *pre = Getattr(p, "tmap:din:pre");
- if (pre) {
- replaceClassname(pre, pt);
- Replaceall(pre, "$dinput", arg);
- if (Len(pre_code) > 0)
- Printf(pre_code, "\n");
- Printv(pre_code, pre, NIL);
- }
- String *post = Getattr(p, "tmap:din:post");
- if (post) {
- replaceClassname(post, pt);
- Replaceall(post, "$dinput", arg);
- if (Len(post_code) > 0)
- Printf(post_code, "\n");
- Printv(post_code, post, NIL);
- }
- String *terminator = Getattr(p, "tmap:din:terminator");
- if (terminator) {
- replaceClassname(terminator, pt);
- Replaceall(terminator, "$dinput", arg);
- if (Len(terminator_code) > 0)
- Insert(terminator_code, 0, "\n");
- Insert(terminator_code, 0, terminator);
- }
- Printv(imcall, tm, NIL);
- } else {
- Swig_warning(WARN_D_TYPEMAP_DIN_UNDEF, input_file, line_number,
- "No din typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- /* Add parameter to module class function */
- if (gencomma >= 2)
- Printf(function_code, ", ");
- gencomma = 2;
- Printf(function_code, "%s %s", param_type, arg);
-
- p = Getattr(p, "tmap:in:next");
- Delete(arg);
- Delete(param_type);
- }
-
- Printf(imcall, ")");
- Printf(function_code, ") ");
-
- if (global_variable_flag && (d_version > 1)) {
- Printf(function_code, "@property ");
- }
-
- // Lookup the code used to convert the wrapper return value to the proxy
- // function return type.
- if ((tm = lookupDTypemap(n, "dout"))) {
- replaceExcode(n, tm, "dout", n);
- bool is_pre_code = Len(pre_code) > 0;
- bool is_post_code = Len(post_code) > 0;
- bool is_terminator_code = Len(terminator_code) > 0;
- if (is_pre_code || is_post_code || is_terminator_code) {
- if (is_post_code) {
- Insert(tm, 0, "\n try ");
- Printv(tm, " finally {\n", post_code, "\n }", NIL);
- } else {
- Insert(tm, 0, "\n ");
- }
- if (is_pre_code) {
- Insert(tm, 0, pre_code);
- Insert(tm, 0, "\n");
- }
- if (is_terminator_code) {
- Printv(tm, "\n", terminator_code, NIL);
- }
- Insert(tm, 0, " {");
- Printf(tm, "\n}");
- }
- if (GetFlag(n, "feature:new"))
- Replaceall(tm, "$owner", "true");
- else
- Replaceall(tm, "$owner", "false");
- replaceClassname(tm, t);
- Replaceall(tm, "$imfuncname", overloaded_name);
- Replaceall(tm, "$imcall", imcall);
- } else {
- Swig_warning(WARN_D_TYPEMAP_DOUT_UNDEF, input_file, line_number,
- "No dout typemap defined for %s\n", SwigType_str(t, 0));
- }
-
- // The whole function code is now stored in tm (if there was a matching
- // type map, of course), so simply append it to the code buffer.
- Printf(function_code, "%s\n", tm ? (const String *) tm : empty_string);
- Printv(proxyCodeBuffer(getNSpace()), function_code, NIL);
-
- Delete(pre_code);
- Delete(post_code);
- Delete(terminator_code);
- Delete(function_code);
- Delete(return_type);
- Delete(imcall);
- Delete(func_name);
- }
-
- /* ---------------------------------------------------------------------------
- * D::writeProxyClassAndUpcasts()
- *
- * Collects all the code fragments generated by the handler function while
- * traversing the tree from the proxy_class_* variables and writes the
- * class definition (including any epilogue code) to proxy_class_code.
- *
- * Also writes the upcast function to the wrapper layer when processing a
- * derived class.
- *
- * Inputs:
- * n – The class node currently processed.
- * --------------------------------------------------------------------------- */
- void writeProxyClassAndUpcasts(Node *n) {
- SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
-
- /*
- * Handle inheriting from D and C++ classes.
- */
-
- String *c_classname = Getattr(n, "name");
- String *c_baseclassname = NULL;
- Node *basenode = NULL;
- String *baseclass = NULL;
-
- // Inheritance from pure D classes.
- Node *attributes = NewHash();
- const String *pure_baseclass =
- lookupCodeTypemap(n, "dbase", typemap_lookup_type, WARN_NONE, attributes);
- bool purebase_replace = GetFlag(attributes, "tmap:dbase:replace") ? true : false;
- bool purebase_notderived = GetFlag(attributes, "tmap:dbase:notderived") ? true : false;
- Delete(attributes);
-
- // C++ inheritance.
- if (!purebase_replace) {
- List *baselist = Getattr(n, "bases");
- if (baselist) {
- Iterator base = First(baselist);
- while (base.item) {
- if (!GetFlag(base.item, "feature:ignore")) {
- SwigType *baseclassname = Getattr(base.item, "name");
- if (!c_baseclassname) {
- basenode = base.item;
- String *name = createProxyName(baseclassname);
- if (name) {
- c_baseclassname = baseclassname;
- baseclass = name;
- }
- } else {
- /* Warn about multiple inheritance for additional base class(es) */
- String *proxyclassname = Getattr(n, "classtypeobj");
- Swig_warning(WARN_D_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
- "Base %s of class %s ignored: multiple inheritance is not supported in D.\n", SwigType_namestr(baseclassname), SwigType_namestr(proxyclassname));
- }
- }
- base = Next(base);
- }
- }
- }
-
- bool derived = baseclass != NULL;
-
- if (derived && purebase_notderived) {
- pure_baseclass = empty_string;
- }
- const String *wanted_base = baseclass ? baseclass : pure_baseclass;
-
- if (purebase_replace) {
- wanted_base = pure_baseclass;
- derived = false;
- basenode = NULL;
- baseclass = NULL;
- if (purebase_notderived) {
- Swig_error(Getfile(n), Getline(n),
- "The dbase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n",
- typemap_lookup_type);
- }
- } else if (baseclass && Len(pure_baseclass) > 0) {
- Swig_warning(WARN_D_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
- "Warning for %s, base class %s ignored. Multiple inheritance is not supported in D. "
- "Perhaps you need one of the 'replace' or 'notderived' attributes in the dbase typemap?\n", typemap_lookup_type, pure_baseclass);
- }
-
- // Add code to do C++ casting to base class (only for classes in an inheritance hierarchy)
- if (derived) {
- writeClassUpcast(n, proxy_class_name, c_classname, c_baseclassname);
- }
-
- /*
- * Write needed imports.
- */
- // If this class is derived from a C++ class, we need to have the D class
- // generated for it in scope.
- if (derived) {
- requireDType(Getattr(basenode, "sym:nspace"), Getattr(basenode, "sym:name"));
- }
-
- // Write any custom import statements to the proxy module header.
- const String *imports = lookupCodeTypemap(n, "dimports", typemap_lookup_type, WARN_NONE);
- if (Len(imports) > 0) {
- String* imports_trimmed = Copy(imports);
- Chop(imports_trimmed);
- replaceImportTypeMacros(imports_trimmed);
- Printv(proxy_class_imports, imports_trimmed, "\n", NIL);
- Delete(imports_trimmed);
- }
-
- /*
- * Write the proxy class header.
- */
- // Class modifiers.
- const String *modifiers =
- lookupCodeTypemap(n, "dclassmodifiers", typemap_lookup_type, WARN_D_TYPEMAP_CLASSMOD_UNDEF);
-
- // User-defined interfaces.
- const String *interfaces =
- lookupCodeTypemap(n, derived ? "dinterfaces_derived" : "dinterfaces", typemap_lookup_type, WARN_NONE);
-
- Printv(proxy_class_code,
- "\n",
- modifiers,
- " $dclassname",
- (*Char(wanted_base) || *Char(interfaces)) ? " : " : "", wanted_base,
- (*Char(wanted_base) && *Char(interfaces)) ? ", " : "", interfaces, " {",
- NIL);
-
- /*
- * Write the proxy class body.
- */
- String* body = NewString("");
-
- // Default class body.
- const String *dbody;
- if (derived) {
- dbody = lookupCodeTypemap(n, "dbody_derived", typemap_lookup_type, WARN_D_TYPEMAP_DBODY_UNDEF);
- } else {
- dbody = lookupCodeTypemap(n, "dbody", typemap_lookup_type, WARN_D_TYPEMAP_DBODY_UNDEF);
- }
-
- Printv(body, dbody, NIL);
-
- // Destructor and dispose().
- // If the C++ destructor is accessible (public), it is wrapped by the
- // dispose() method which is also called by the emitted D constructor. If it
- // is not accessible, no D destructor is written and the generated dispose()
- // method throws an exception.
- // This enables C++ classes with protected or private destructors to be used
- // in D as it would be used in C++ (GC finalization is a no-op then because
- // of the empty D destructor) while preventing usage in »scope« variables.
- // The method name for the dispose() method is specified in a typemap
- // attribute called »methodname«.
- const String *tm = NULL;
-
- const String *dispose_methodname;
- const String *dispose_methodmodifiers;
- const String *dispose_parameters;
- attributes = NewHash();
- if (derived) {
- tm = lookupCodeTypemap(n, "ddispose_derived", typemap_lookup_type, WARN_NONE, attributes);
- dispose_methodname = Getattr(attributes, "tmap:ddispose_derived:methodname");
- dispose_methodmodifiers = Getattr(attributes, "tmap:ddispose_derived:methodmodifiers");
- dispose_parameters = Getattr(attributes, "tmap:ddispose_derived:parameters");
- } else {
- tm = lookupCodeTypemap(n, "ddispose", typemap_lookup_type, WARN_NONE, attributes);
- dispose_methodname = Getattr(attributes, "tmap:ddispose:methodname");
- dispose_methodmodifiers = Getattr(attributes, "tmap:ddispose:methodmodifiers");
- dispose_parameters = Getattr(attributes, "tmap:ddispose:parameters");
- }
-
- if (tm && *Char(tm)) {
- if (!dispose_methodname) {
- Swig_error(Getfile(n), Getline(n),
- "No methodname attribute defined in the ddispose%s typemap for %s\n",
- (derived ? "_derived" : ""), proxy_class_name);
- }
- if (!dispose_methodmodifiers) {
- Swig_error(Getfile(n), Getline(n),
- "No methodmodifiers attribute defined in ddispose%s typemap for %s.\n",
- (derived ? "_derived" : ""), proxy_class_name);
- }
- if (!dispose_parameters)
- dispose_parameters = empty_string;
- }
-
- if (tm) {
- // Write the destructor if the C++ one is accessible.
- if (*Char(destructor_call)) {
- Printv(body,
- lookupCodeTypemap(n, "ddestructor", typemap_lookup_type, WARN_NONE), NIL);
- }
-
- // Write the dispose() method.
- String *dispose_code = NewString("");
- Printv(dispose_code, tm, NIL);
-
- if (*Char(destructor_call)) {
- Replaceall(dispose_code, "$imcall", destructor_call);
- } else {
- Replaceall(dispose_code, "$imcall", "throw new object.Exception(\"C++ destructor does not have public access\")");
- }
-
- if (*Char(dispose_code)) {
- Printv(body, "\n", NIL);
- const String *methodmods = Getattr(n, "destructmethodmodifiers");
- if (methodmods)
- Printv(body, methodmods, NIL);
- else
- Printv(body, dispose_methodmodifiers, (derived ? " override" : ""), NIL);
- Printv(body, " void ", dispose_methodname, "(", dispose_parameters, ") ", dispose_code, "\n", NIL);
- }
- }
-
- if (Swig_directorclass(n)) {
- // If directors are enabled for the current class, generate the
- // director connect helper function which is called from the constructor
- // and write it to the class body.
- writeDirectorConnectProxy(n);
- }
-
- // Write all constants and enumerations first to prevent forward reference
- // errors.
- Printv(body, proxy_class_enums_code, NIL);
-
- // Write the code generated in other methods to the class body.
- Printv(body, proxy_class_body_code, NIL);
-
- // Append extra user D code to the class body.
- Printv(body,
- lookupCodeTypemap(n, "dcode", typemap_lookup_type, WARN_NONE), "\n", NIL);
-
- // Write the class body and the curly bracket closing the class definition
- // to the proxy module.
- indentCode(body);
- Replaceall(body, "$dbaseclass", baseclass);
-
- Printv(proxy_class_code, body, "\n}\n", NIL);
- Delete(body);
-
- // Write the epilogue code if there is any.
- Printv(proxy_class_code, proxy_class_epilogue_code, NIL);
- }
-
-
- /* ---------------------------------------------------------------------------
- * D::writeClassUpcast()
- * --------------------------------------------------------------------------- */
- void writeClassUpcast(Node *n, const String* d_class_name, SwigType* c_classname, SwigType* c_baseclassname) {
-
- SwigType *smart = Swig_cparse_smartptr(n);
- String *upcast_name = Swig_name_member(getNSpace(), d_class_name, (smart != 0 ? "SmartPtrUpcast" : "Upcast"));
- String *upcast_wrapper_name = Swig_name_wrapper(upcast_name);
-
- writeImDModuleFunction(upcast_name, "void*", "(void* objectRef)",
- upcast_wrapper_name);
-
- String *classname = SwigType_namestr(c_classname);
- String *baseclassname = SwigType_namestr(c_baseclassname);
- if (smart) {
- String *smartnamestr = SwigType_namestr(smart);
- String *bsmartnamestr = SwigType_namestr(smart);
-
- // TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
- SwigType *rclassname = SwigType_typedef_resolve_all(classname);
- SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname);
- Replaceall(bsmartnamestr, rclassname, rbaseclassname);
-
- Printv(upcasts_code,
- "SWIGEXPORT ", bsmartnamestr, " * ", upcast_wrapper_name,
- "(", smartnamestr, " *objectRef) {\n",
- " return objectRef ? new ", bsmartnamestr, "(*objectRef) : 0;\n"
- "}\n",
- "\n", NIL);
-
- Delete(rbaseclassname);
- Delete(rclassname);
- Delete(bsmartnamestr);
- Delete(smartnamestr);
- } else {
- Printv(upcasts_code,
- "SWIGEXPORT ", baseclassname, " * ", upcast_wrapper_name,
- "(", classname, " *objectRef) {\n",
- " return (", baseclassname, " *)objectRef;\n"
- "}\n",
- "\n", NIL);
- }
-
- Replaceall(upcasts_code, "$cclass", classname);
- Replaceall(upcasts_code, "$cbaseclass", baseclassname);
-
- Delete(baseclassname);
- Delete(classname);
- Delete(upcast_name);
- Delete(upcast_wrapper_name);
- Delete(smart);
- }
-
- /* ---------------------------------------------------------------------------
- * D::writeTypeWrapperClass()
- * --------------------------------------------------------------------------- */
- void writeTypeWrapperClass(String *classname, SwigType *type) {
- Node *n = NewHash();
- Setfile(n, input_file);
- Setline(n, line_number);
-
- assertClassNameValidity(classname);
-
- String* imports_target;
- String* code_target;
- File *class_file = NULL;
- if (split_proxy_dmodule) {
- String *filename = NewStringf("%s%s.d", dmodule_directory, classname);
- class_file = NewFile(filename, "w", SWIG_output_files());
- if (!class_file) {
- FileErrorDisplay(filename);
- Exit(EXIT_FAILURE);
- }
- Append(filenames_list, Copy(filename));
- Delete(filename);
-
- emitBanner(class_file);
- Printf(class_file, "module %s%s;\n", package, classname);
- Printf(class_file, "\nstatic import %s;\n", im_dmodule_fq_name);
-
- imports_target = NewString("");
- code_target = NewString("");
- } else {
- imports_target = proxyImportsBuffer(0);
- code_target = proxyCodeBuffer(0);
- }
-
- // Import statements.
- const String *imports = lookupCodeTypemap(n, "dimports", type, WARN_NONE);
- if (Len(imports) > 0) {
- String *imports_trimmed = Copy(imports);
- Chop(imports_trimmed);
- replaceImportTypeMacros(imports_trimmed);
- Printv(imports_target, imports_trimmed, "\n", NIL);
- Delete(imports_trimmed);
- }
-
- // Pure D baseclass and interfaces (no C++ inheritance possible.
- const String *pure_baseclass = lookupCodeTypemap(n, "dbase", type, WARN_NONE);
- const String *pure_interfaces = lookupCodeTypemap(n, "dinterfaces", type, WARN_NONE);
-
- // Emit the class.
- Printv(code_target,
- "\n",
- lookupCodeTypemap(n, "dclassmodifiers", type, WARN_D_TYPEMAP_CLASSMOD_UNDEF),
- " $dclassname",
- (*Char(pure_baseclass) || *Char(pure_interfaces)) ? " : " : "", pure_baseclass,
- ((*Char(pure_baseclass)) && *Char(pure_interfaces)) ? ", " : "", pure_interfaces,
- " {", NIL);
-
- String* body = NewString("");
- Printv(body, lookupCodeTypemap(n, "dbody", type, WARN_D_TYPEMAP_DBODY_UNDEF),
- lookupCodeTypemap(n, "dcode", type, WARN_NONE), NIL);
- indentCode(body);
- Printv(code_target, body, "\n}\n", NIL);
- Delete(body);
-
- Replaceall(code_target, "$dclassname", classname);
-
- if (split_proxy_dmodule) {
- Printv(class_file, imports_target, NIL);
- Delete(imports_target);
-
- replaceModuleVariables(code_target);
- Printv(class_file, code_target, NIL);
- Delete(code_target);
-
- Delete(class_file);
- }
-
- Delete(n);
- }
-
- /* ---------------------------------------------------------------------------
- * D::writeDirectorConnectProxy(Node *classNode)
- *
- * Writes the helper method which registers the director callbacks by calling
- * the director connect function from the D side to the proxy class.
- * --------------------------------------------------------------------------- */
- void writeDirectorConnectProxy(Node* classNode) {
- String *dirClassName = directorClassName(classNode);
- String *connect_name = Swig_name_member(getNSpace(),
- proxy_class_name, "director_connect");
- Printf(proxy_class_body_code, "\nprivate void swigDirectorConnect() {\n");
-
- int i;
- for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
- UpcallData *udata = Getitem(dmethods_seq, i);
- String *method = Getattr(udata, "method");
- String *overloaded_name = Getattr(udata, "overname");
- String *return_type = Getattr(udata, "return_type");
- String *param_list = Getattr(udata, "param_list");
- String *methid = Getattr(udata, "class_methodidx");
- Printf(proxy_class_body_code, " %s.%s_Callback%s callback%s;\n", im_dmodule_fq_name, dirClassName, methid, methid);
- Printf(proxy_class_body_code, " if (swigIsMethodOverridden!(%s delegate(%s), %s function(%s), %s)()) {\n", return_type, param_list, return_type, param_list, method);
- Printf(proxy_class_body_code, " callback%s = &swigDirectorCallback_%s_%s;\n", methid, proxy_class_name, overloaded_name);
- Printf(proxy_class_body_code, " }\n\n");
- }
- Printf(proxy_class_body_code, " %s.%s(cast(void*)swigCPtr, cast(void*)this", im_dmodule_fq_name, connect_name);
- for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
- UpcallData *udata = Getitem(dmethods_seq, i);
- String *methid = Getattr(udata, "class_methodidx");
- Printf(proxy_class_body_code, ", callback%s", methid);
- }
- Printf(proxy_class_body_code, ");\n");
- Printf(proxy_class_body_code, "}\n");
-
- // Helper function to determine if a method has been overridden in a
- // subclass of the wrapped class. If not, we just pass null to the
- // director_connect_function since the method from the C++ class should
- // be called as usual (see above).
- // Only emit it if the proxy class has at least one method.
- if (first_class_dmethod < curr_class_dmethod) {
- Printf(proxy_class_body_code, "\n");
- Printf(proxy_class_body_code, "private bool swigIsMethodOverridden(DelegateType, FunctionType, alias fn)() %s{\n", (d_version > 1) ? "const " : "");
- Printf(proxy_class_body_code, " DelegateType dg = &fn;\n");
- Printf(proxy_class_body_code, " return dg.funcptr != SwigNonVirtualAddressOf!(FunctionType, fn);\n");
- Printf(proxy_class_body_code, "}\n");
- Printf(proxy_class_body_code, "\n");
- Printf(proxy_class_body_code, "private static Function SwigNonVirtualAddressOf(Function, alias fn)() {\n");
- Printf(proxy_class_body_code, " return cast(Function) &fn;\n");
- Printf(proxy_class_body_code, "}\n");
- }
-
- if (Len(director_dcallbacks_code) > 0) {
- Printv(proxy_class_epilogue_code, director_dcallbacks_code, NIL);
- }
-
- Delete(director_callback_typedefs);
- director_callback_typedefs = NULL;
- Delete(director_callback_pointers);
- director_callback_pointers = NULL;
- Delete(director_dcallbacks_code);
- director_dcallbacks_code = NULL;
- Delete(dirClassName);
- Delete(connect_name);
- }
-
- /* ---------------------------------------------------------------------------
- * D::writeDirectorConnectWrapper()
- *
- * Writes the director connect function and the corresponding declaration to
- * the C++ wrapper respectively the D wrapper.
- * --------------------------------------------------------------------------- */
- void writeDirectorConnectWrapper(Node *n) {
- if (!Swig_directorclass(n))
- return;
-
- // Output the director connect method.
- String *norm_name = SwigType_namestr(Getattr(n, "name"));
- String *connect_name = Swig_name_member(getNSpace(),
- proxy_class_name, "director_connect");
- String *dirClassName = directorClassName(n);
- Wrapper *code_wrap;
-
- Printv(wrapper_loader_bind_code, wrapper_loader_bind_command, NIL);
- Replaceall(wrapper_loader_bind_code, "$function", connect_name);
- Replaceall(wrapper_loader_bind_code, "$symbol", Swig_name_wrapper(connect_name));
-
- Printf(im_dmodule_code, "extern(C) void function(void* cObject, void* dObject");
-
- code_wrap = NewWrapper();
- Printf(code_wrap->def, "SWIGEXPORT void D_%s(void *objarg, void *dobj", connect_name);
-
- Printf(code_wrap->code, " %s *obj = (%s *)objarg;\n", norm_name, norm_name);
- Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj);\n", dirClassName, dirClassName);
-
- Printf(code_wrap->code, " director->swig_connect_director(dobj");
-
- for (int i = first_class_dmethod; i < curr_class_dmethod; ++i) {
- UpcallData *udata = Getitem(dmethods_seq, i);
- String *methid = Getattr(udata, "class_methodidx");
-
- Printf(code_wrap->def, ", %s::SWIG_Callback%s_t callback%s", dirClassName, methid, methid);
- Printf(code_wrap->code, ", callback%s", methid);
- Printf(im_dmodule_code, ", %s_Callback%s callback%s", dirClassName, methid, methid);
- }
-
- Printf(code_wrap->def, ") {\n");
- Printf(code_wrap->code, ");\n");
- Printf(im_dmodule_code, ") %s;\n", connect_name);
- Printf(code_wrap->code, "}\n");
-
- Wrapper_print(code_wrap, f_wrappers);
- DelWrapper(code_wrap);
-
- Delete(connect_name);
- Delete(dirClassName);
- }
-
- /* ---------------------------------------------------------------------------
- * D::requireDType()
- *
- * If the given type is not already in scope in the current module, adds an
- * import statement for it. The name is considered relative to the global root
- * package if one is set.
- *
- * This is only used for dependencies created in generated code, user-
- * (i.e. typemap-) specified import statements are handled separately.
- * --------------------------------------------------------------------------- */
- void requireDType(const String *nspace, const String *symname) {
- String *dmodule = createModuleName(nspace, symname);
-
- if (!inProxyModule(dmodule)) {
- String *import = createImportStatement(dmodule);
- Append(import, "\n");
- if (is_wrapping_class()) {
- addImportStatement(proxy_class_imports, import);
- } else {
- addImportStatement(proxyImportsBuffer(getNSpace()), import);
- }
- Delete(import);
- }
- Delete(dmodule);
- }
-
- /* ---------------------------------------------------------------------------
- * D::addImportStatement()
- *
- * Adds the given import statement to the given list of import statements if
- * there is no statement importing that module present yet.
- * --------------------------------------------------------------------------- */
- void addImportStatement(String *target, const String *import) const {
- char *position = Strstr(target, import);
- if (position) {
- // If the import statement has been found in the target string, we have to
- // check if the previous import was static, which would lead to problems
- // if this import is not.
- // Thus, we check if the seven characters in front of the occurrence are
- // »static «. If the import string passed is also static, the checks fail
- // even if the found statement is also static because the last seven
- // characters would be part of the previous import statement then.
-
- if (position - Char(target) < 7) {
- return;
- }
- if (strncmp(position - 7, "static ", 7)) {
- return;
- }
- }
-
- Printv(target, import, NIL);
- }
-
- /* ---------------------------------------------------------------------------
- * D::createImportStatement()
- *
- * Creates a string containing an import statement for the given module.
- * --------------------------------------------------------------------------- */
- String *createImportStatement(const String *dmodule_name,
- bool static_import = true) const {
-
- if (static_import) {
- return NewStringf("static import %s%s;", package, dmodule_name);
- } else {
- return NewStringf("import %s%s;", package, dmodule_name);
- }
- }
-
- /* ---------------------------------------------------------------------------
- * D::inProxyModule()
- *
- * Determines if the specified proxy type is declared in the currently
- * processed proxy D module.
- *
- * This function is used to determine if fully qualified type names have to
- * be used (package, module and type name). If the split proxy mode is not
- * used, this solely depends on whether the type is in the current namespace.
- * --------------------------------------------------------------------------- */
- bool inProxyModule(const String *type_name) const {
- if (!split_proxy_dmodule) {
- String *nspace = createOuterNamespaceNames(type_name);
-
- // Check if strings are either both null (no namespace) or are both
- // non-null and have the same contents. Cannot use Strcmp for this
- // directly because of its strange way of handling the case where only
- // one argument is 0 ("<").
- bool result = !nspace && !getNSpace();
- if (nspace && getNSpace())
- result = (Strcmp(nspace, getNSpace()) == 0);
-
- Delete(nspace);
- return result;
- }
-
- if (!is_wrapping_class()) {
- return false;
- }
-
- return (Strcmp(proxy_class_qname, type_name) == 0);
- }
-
- /* ---------------------------------------------------------------------------
- * D::addUpcallMethod()
- *
- * Adds new director upcall signature.
- * --------------------------------------------------------------------------- */
- UpcallData *addUpcallMethod(String *imclass_method, String *class_method,
- String *decl, String *overloaded_name, String *return_type, String *param_list) {
-
- String *key = NewStringf("%s|%s", imclass_method, decl);
-
- ++curr_class_dmethod;
-
- String *class_methodidx = NewStringf("%d", n_dmethods - first_class_dmethod);
- n_dmethods++;
-
- Hash *new_udata = NewHash();
- Append(dmethods_seq, new_udata);
- Setattr(dmethods_table, key, new_udata);
-
- Setattr(new_udata, "method", Copy(class_method));
- Setattr(new_udata, "class_methodidx", class_methodidx);
- Setattr(new_udata, "decl", Copy(decl));
- Setattr(new_udata, "overname", Copy(overloaded_name));
- Setattr(new_udata, "return_type", Copy(return_type));
- Setattr(new_udata, "param_list", Copy(param_list));
-
- Delete(key);
- return new_udata;
- }
-
- /* ---------------------------------------------------------------------------
- * D::assertClassNameValidity()
- * --------------------------------------------------------------------------- */
- void assertClassNameValidity(const String* class_name) const {
- // TODO: With nspace support, there could arise problems also when not in
- // split proxy mode, warnings for these should be added.
- if (split_proxy_dmodule) {
- if (Cmp(class_name, im_dmodule_name) == 0) {
- Swig_error(input_file, line_number,
- "Class name cannot be equal to intermediary D module name: %s\n",
- class_name);
- Exit(EXIT_FAILURE);
- }
-
- String *nspace = getNSpace();
- if (nspace) {
- // Check the root package/outermost namespace (a class A in module
- // A.B leads to problems if another module A.C is also imported)
- if (Len(package) > 0) {
- String *dotless_package = NewStringWithSize(package, Len(package) - 1);
- if (Cmp(class_name, dotless_package) == 0) {
- Swig_error(input_file, line_number,
- "Class name cannot be the same as the root package it is in: %s\n",
- class_name);
- Exit(EXIT_FAILURE);
- }
- Delete(dotless_package);
- } else {
- String *outer = createFirstNamespaceName(nspace);
- if (Cmp(class_name, outer) == 0) {
- Swig_error(input_file, line_number,
- "Class name cannot be the same as the outermost namespace it is in: %s\n",
- class_name);
- Exit(EXIT_FAILURE);
- }
- Delete(outer);
- }
-
- // … and the innermost one (because of the conflict with the main proxy
- // module named like the namespace).
- String *inner = createLastNamespaceName(nspace);
- if (Cmp(class_name, inner) == 0) {
- Swig_error(input_file, line_number,
- "Class name cannot be the same as the innermost namespace it is in: %s\n",
- class_name);
- Exit(EXIT_FAILURE);
- }
- Delete(inner);
- } else {
- if (Cmp(class_name, proxy_dmodule_name) == 0) {
- Swig_error(input_file, line_number,
- "Class name cannot be equal to proxy D module name: %s\n",
- class_name);
- Exit(EXIT_FAILURE);
- }
- }
- }
- }
-
- /* ---------------------------------------------------------------------------
- * D::getPrimitiveDptype()
- *
- * Returns the D proxy type for the passed type if it is a primitive type in
- * both C and D.
- * --------------------------------------------------------------------------- */
- String *getPrimitiveDptype(Node *node, SwigType *type) {
- SwigType *stripped_type = SwigType_typedef_resolve_all(type);
-
- // A reference can only be the »outermost element« of a type.
- bool mutable_ref = false;
- if (SwigType_isreference(stripped_type)) {
- SwigType_del_reference(stripped_type);
-
- if (SwigType_isconst(stripped_type)) {
- SwigType_del_qualifier(stripped_type);
- } else {
- mutable_ref = true;
- }
- }
-
- // Strip all the pointers from the type.
- int indirection_count = 0;
- while (SwigType_ispointer(stripped_type)) {
- ++indirection_count;
- SwigType_del_pointer(stripped_type);
- }
-
- // Now that we got rid of the pointers, see if we are dealing with a
- // primitive type.
- String *dtype = 0;
- if (SwigType_isfunction(stripped_type) && indirection_count > 0) {
- // type was a function pointer, split it up.
- SwigType_add_pointer(stripped_type);
- --indirection_count;
-
- SwigType *return_type = Copy(stripped_type);
- SwigType *params_type = SwigType_functionpointer_decompose(return_type);
- String *return_dtype = getPrimitiveDptype(node, return_type);
- Delete(return_type);
- if (!return_dtype) {
- return 0;
- }
-
- List *parms = SwigType_parmlist(params_type);
- List *param_dtypes = NewList();
- for (Iterator it = First(parms); it.item; it = Next(it)) {
- String *current_dtype = getPrimitiveDptype(node, it.item);
- if (Cmp(current_dtype, "void") == 0) {
- // void somefunc(void) is legal syntax in C, but not in D, so simply
- // skip the void parameter.
- Delete(current_dtype);
- continue;
- }
- if (!current_dtype) {
- Delete(return_dtype);
- Delete(param_dtypes);
- return 0;
- }
- Append(param_dtypes, current_dtype);
- }
-
- String *param_list = NewString("");
- {
- bool gen_comma = false;
- for (Iterator it = First(param_dtypes); it.item; it = Next(it)) {
- if (gen_comma) {
- Append(param_list, ", ");
- }
- Append(param_list, it.item);
- Delete(it.item);
- gen_comma = true;
- }
- }
-
- dtype = NewStringf("%s.SwigExternC!(%s function(%s))", im_dmodule_fq_name,
- return_dtype, param_list);
- Delete(param_list);
- Delete(param_dtypes);
- Delete(return_dtype);
- } else {
- Hash *attributes = NewHash();
- const String *tm =
- lookupCodeTypemap(node, "dtype", stripped_type, WARN_NONE, attributes);
- if(!GetFlag(attributes, "tmap:dtype:cprimitive")) {
- dtype = 0;
- } else {
- dtype = Copy(tm);
-
- // We need to call replaceClassname here with the stripped type to avoid
- // $dclassname in the enum typemaps being replaced later with the full
- // type.
- replaceClassname(dtype, stripped_type);
- }
- Delete(attributes);
- }
- Delete(stripped_type);
-
- if (!dtype) {
- // The type passed is no primitive type.
- return 0;
- }
-
- // The type is ultimately a primitive type, now append the right number of
- // indirection levels (pointers).
- for (int i = 0; i < indirection_count; ++i) {
- Append(dtype, "*");
- }
-
- // Add a level of indirection for a mutable reference since it is wrapped
- // as a pointer.
- if (mutable_ref) {
- Append(dtype, "*");
- }
-
- return dtype;
- }
-
- /* ---------------------------------------------------------------------------
- * D::lookupCodeTypemap()
- *
- * Looks up a D code fragment for generating the wrapper class for the given
- * type.
- *
- * n - for input only and must contain info for Getfile(n) and Getline(n) to work
- * tmap_method - typemap method name
- * type - typemap type to lookup
- * warning - warning number to issue if no typemaps found
- * typemap_attributes - the typemap attributes are attached to this node and will
- * also be used for temporary storage if non null
- * return is never NULL, unlike Swig_typemap_lookup()
- * --------------------------------------------------------------------------- */
- const String *lookupCodeTypemap(Node *n, const_String_or_char_ptr tmap_method,
- SwigType *type, int warning, Node *typemap_attributes = 0) const {
-
- Node *node = !typemap_attributes ? NewHash() : typemap_attributes;
- Setattr(node, "type", type);
- Setfile(node, Getfile(n));
- Setline(node, Getline(n));
- const String *tm = Swig_typemap_lookup(tmap_method, node, "", 0);
- if (!tm) {
- tm = empty_string;
- if (warning != WARN_NONE) {
- Swig_warning(warning, Getfile(n), Getline(n),
- "No %s typemap defined for %s\n", tmap_method, SwigType_str(type, 0));
- }
- }
- if (!typemap_attributes) {
- Delete(node);
- }
-
- return tm;
- }
-
- /* ---------------------------------------------------------------------------
- * D::lookupDTypemap()
- *
- * Looks up a D typemap for the given node, replacing D-specific special
- * variables as needed.
- *
- * The method parameter specifies the typemap method to use. If attached is
- * true, the value is just fetched from the tmap:<method> node attribute,
- * Swig_typemap_lookup is used otherwise.
- * --------------------------------------------------------------------------- */
- String *lookupDTypemap(Node *n, const_String_or_char_ptr method, bool attached = false) {
- String *result = 0;
-
- if (attached) {
- String *attr_name = NewStringf("tmap:%s", method);
- result = Copy(Getattr(n, attr_name));
- Delete(attr_name);
- } else {
- // FIXME: As a workaround for a bug so far only surfacing in the
- // smart_pointer_const_overload test case, remove the nativepointer
- // typemap attribute since it seems to be already there from a dout
- // typemap of a different type in that test.
- String *np_key = NewStringf("tmap:%s:nativepointer", method);
- Delattr(n, np_key);
- Delete(np_key);
-
- result = Swig_typemap_lookup(method, n, "", 0);
- }
-
- if (!result) {
- return 0;
- }
-
- // Check if the passed node actually has type information attached. This
- // is not the case e.g. in constructorWrapper.
- SwigType *type = Getattr(n, "type");
- if (type) {
- String *np_key = NewStringf("tmap:%s:nativepointer", method);
- String *np_value = Getattr(n, np_key);
- Delete(np_key);
- String *dtype;
- if (np_value && (dtype = getPrimitiveDptype(n, type))) {
- // If the typemap in question has a »nativepointer« attribute and we
- // are dealing with a primitive type, use it instead.
- result = Copy(np_value);
- Replaceall(result, "$dtype", dtype);
- }
-
- replaceClassname(result, type);
- }
-
- return result;
- }
-
- /* ---------------------------------------------------------------------------
- * D::replaceClassname()
- *
- * Replaces the special variable $dclassname with the proxy class name for
- * classes/structs/unions SWIG knows about. Also substitutes the enumeration
- * name for non-anonymous enums. Otherwise, $classname is replaced with a
- * $descriptor(type)-like name.
- *
- * $*dclassname and $&classname work like with descriptors (see manual section
- * 10.4.3), they remove a prointer from respectively add a pointer to the type.
- *
- * Inputs:
- * tm - String to perform the substitution at (will usually come from a
- * typemap.
- * pt - The type to substitute for the variables.
- * Outputs:
- * tm - String with the variables substituted.
- * Return:
- * substitution_performed - flag indicating if a substitution was performed
- * --------------------------------------------------------------------------- */
- bool replaceClassname(String *tm, SwigType *pt) {
- bool substitution_performed = false;
- SwigType *type = Copy(SwigType_typedef_resolve_all(pt));
- SwigType *strippedtype = SwigType_strip_qualifiers(type);
-
- if (Strstr(tm, "$dclassname")) {
- SwigType *classnametype = Copy(strippedtype);
- replaceClassnameVariable(tm, "$dclassname", classnametype);
- substitution_performed = true;
- Delete(classnametype);
- }
- if (Strstr(tm, "$*dclassname")) {
- SwigType *classnametype = Copy(strippedtype);
- Delete(SwigType_pop(classnametype));
- replaceClassnameVariable(tm, "$*dclassname", classnametype);
- substitution_performed = true;
- Delete(classnametype);
- }
- if (Strstr(tm, "$&dclassname")) {
- SwigType *classnametype = Copy(strippedtype);
- SwigType_add_pointer(classnametype);
- replaceClassnameVariable(tm, "$&dclassname", classnametype);
- substitution_performed = true;
- Delete(classnametype);
- }
-
- Delete(strippedtype);
- Delete(type);
-
- return substitution_performed;
- }
-
- /* ---------------------------------------------------------------------------
- * D::replaceClassnameVariable()
- *
- * See D::replaceClassname().
- * --------------------------------------------------------------------------- */
- void replaceClassnameVariable(String *target, const char *variable, SwigType *type) {
- // TODO: Fix const-correctness of methods called in here and make type const.
-
- // We make use of the fact that this function is called at least once for
- // every type encountered which is written to a separate file, which allows
- // us to handle imports here.
- // When working in split proxy module mode, each generated proxy class/enum
- // is written to a separate module. This requires us to add a corresponding
- // import when a type is used in another generated module. If we are not
- // working in split proxy module mode, this is not relevant and the
- // generated module name is discarded.
- String *type_name;
-
- if (SwigType_isenum(type)) {
- // RESEARCH: Make sure that we really cannot get here for anonymous enums.
- Node *n = enumLookup(type);
- if (n) {
- String *enum_name = Getattr(n, "sym:name");
-
- Node *p = parentNode(n);
- if (p && !Strcmp(nodeType(p), "class")) {
- // This is a nested enum.
- String *parent_name = Getattr(p, "sym:name");
- String *nspace = Getattr(p, "sym:nspace");
-
- // An enum nested in a class is not written to a separate module (this
- // would not even be possible in D), so just import the parent.
- requireDType(nspace, parent_name);
-
- String *module = createModuleName(nspace, parent_name);
- if (inProxyModule(module)) {
- type_name = NewStringf("%s.%s", parent_name, enum_name);
- } else {
- type_name = NewStringf("%s%s.%s.%s", package, module, parent_name, enum_name);
- }
- } else {
- // A non-nested enum is written to a separate module, import it.
- String *nspace = Getattr(n, "sym:nspace");
- requireDType(nspace, enum_name);
-
- String *module = createModuleName(nspace, enum_name);
- if (inProxyModule(module)) {
- type_name = Copy(enum_name);
- } else {
- type_name = NewStringf("%s%s.%s", package, module, enum_name);
- }
- }
- } else {
- type_name = NewStringf("int");
- }
- } else {
- Node *n = classLookup(type);
- if (n) {
- String *class_name = Getattr(n, "sym:name");
- String *nspace = Getattr(n, "sym:nspace");
- requireDType(nspace, class_name);
-
- String *module = createModuleName(nspace, class_name);
- if (inProxyModule(module)) {
- type_name = Copy(class_name);
- } else {
- type_name = NewStringf("%s%s.%s", package, module, class_name);
- }
- Delete(module);
- } else {
- // SWIG does not know anything about the type (after resolving typedefs).
- // Just mangle the type name string like $descriptor(type) would do.
- String *descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(type));
- requireDType(NULL, descriptor);
-
- String *module = createModuleName(NULL, descriptor);
- if (inProxyModule(module)) {
- type_name = Copy(descriptor);
- } else {
- type_name = NewStringf("%s%s.%s", package, module, descriptor);
- }
- Delete(module);
-
- // Add to hash table so that a type wrapper class can be created later.
- Setattr(unknown_types, descriptor, type);
-
- Delete(descriptor);
- }
- }
-
- Replaceall(target, variable, type_name);
- Delete(type_name);
- }
-
- /* ---------------------------------------------------------------------------
- * D::createModuleName()
- *
- * Returns a string holding the name of the module to import to bring the
- * given type in scope.
- * --------------------------------------------------------------------------- */
- String *createModuleName(const String *nspace, const String *type_name) const {
- String *module;
- if (nspace) {
- module = NewStringf("%s.", nspace);
- if (split_proxy_dmodule) {
- Printv(module, type_name, NIL);
- } else {
- String *inner = createLastNamespaceName(nspace);
- Printv(module, inner, NIL);
- Delete(inner);
- }
- } else {
- if (split_proxy_dmodule) {
- module = Copy(type_name);
- } else {
- module = Copy(proxy_dmodule_name);
- }
- }
- return module;
- }
-
- /* ---------------------------------------------------------------------------
- * D::replaceModuleVariables()
- *
- * Replaces the $imdmodule and $module variables with their values in the
- * target string.
- * --------------------------------------------------------------------------- */
- void replaceModuleVariables(String *target) const {
- Replaceall(target, "$imdmodule", im_dmodule_fq_name);
- Replaceall(target, "$module", proxy_dmodule_name);
- }
-
- /* ---------------------------------------------------------------------------
- * D::replaceExcode()
- *
- * If a C++ method can throw a exception, additional code is added to the
- * proxy method to check if an exception is pending so that it can be
- * rethrown on the D side.
- *
- * This method replaces the $excode variable with the exception handling code
- * in the excode typemap attribute if it »canthrow« an exception.
- * --------------------------------------------------------------------------- */
- void replaceExcode(Node *n, String *code, const String *typemap, Node *parameter) const {
- String *excode_attribute = NewStringf("tmap:%s:excode", typemap);
- String *excode = Getattr(parameter, excode_attribute);
- if (Getattr(n, "d:canthrow")) {
- int count = Replaceall(code, "$excode", excode);
- if (count < 1 || !excode) {
- Swig_warning(WARN_D_EXCODE_MISSING, input_file, line_number,
- "D exception may not be thrown – no $excode or excode attribute in '%s' typemap.\n",
- typemap);
- }
- } else {
- Replaceall(code, "$excode", "");
- }
- Delete(excode_attribute);
- }
-
- /* ---------------------------------------------------------------------------
- * D::replaceImportTypeMacros()
- *
- * Replaces the $importtype(SomeDClass) macro with an import statement if it
- * is required to get SomeDClass in scope for the currently generated proxy
- * D module.
- * --------------------------------------------------------------------------- */
- void replaceImportTypeMacros(String *target) const {
- // Code from replace_embedded_typemap.
- char *start = 0;
- while ((start = Strstr(target, "$importtype("))) {
- char *end = 0;
- char *param_start = 0;
- char *param_end = 0;
- int level = 0;
- char *c = start;
- while (*c) {
- if (*c == '(') {
- if (level == 0) {
- param_start = c + 1;
- }
- level++;
- }
- if (*c == ')') {
- level--;
- if (level == 0) {
- param_end = c;
- end = c + 1;
- break;
- }
- }
- c++;
- }
-
- if (end) {
- String *current_macro = NewStringWithSize(start, (int)(end - start));
- String *current_param = NewStringWithSize(param_start, (int)(param_end - param_start));
-
-
- if (inProxyModule(current_param)) {
- Replace(target, current_macro, "", DOH_REPLACE_ANY);
- } else {
- String *import = createImportStatement(current_param, false);
- Replace(target, current_macro, import, DOH_REPLACE_ANY);
- Delete(import);
- }
-
- Delete(current_param);
- Delete(current_macro);
- } else {
- String *current_macro = NewStringWithSize(start, (int)(c - start));
- Swig_error(Getfile(target), Getline(target), "Syntax error in: %s\n", current_macro);
- Replace(target, current_macro, "<error in $importtype macro>", DOH_REPLACE_ANY);
- Delete(current_macro);
- }
- }
- }
-
- /* ---------------------------------------------------------------------------
- * D::getOverloadedName()
- * --------------------------------------------------------------------------- */
- String *getOverloadedName(Node *n) const {
- // A void* parameter is used for all wrapped classes in the wrapper code.
- // Thus, the wrapper function names for overloaded functions are postfixed
- // with a counter string to make them unique.
- String *overloaded_name = Copy(Getattr(n, "sym:name"));
-
- if (Getattr(n, "sym:overloaded")) {
- Append(overloaded_name, Getattr(n, "sym:overname"));
- }
-
- return overloaded_name;
- }
-
- /* ---------------------------------------------------------------------------
- * D::createProxyName()
- *
- * Returns the D class name if a type corresponds to something wrapped with a
- * proxy class, NULL otherwise.
- * --------------------------------------------------------------------------- */
- String *createProxyName(SwigType *t) {
- String *proxyname = NULL;
- Node *n = classLookup(t);
- if (n) {
- String *nspace = Getattr(n, "sym:nspace");
- String *symname = Getattr(n, "sym:name");
-
- String *module = createModuleName(nspace, symname);
- if (inProxyModule(module)) {
- proxyname = Copy(symname);
- } else {
- proxyname = NewStringf("%s%s.%s", package, module, symname);
- }
- }
- return proxyname;
- }
-
- String *makeParameterName(Node *n, Parm *p, int arg_num, bool setter) const {
- String *arg = Language::makeParameterName(n, p, arg_num, setter);
-
- if (split_proxy_dmodule && Strncmp(arg, package, Len(arg)) == 0) {
- // If we are in split proxy mode and the argument is named like the target
- // package, we append an underscore to its name to avoid clashes.
- Append(arg, "_");
- }
-
- return arg;
- }
-
- /* ---------------------------------------------------------------------------
- * D::canThrow()
- *
- * Determines whether the code in the typemap can throw a D exception.
- * If so, note it for later when excodeSubstitute() is called.
- * --------------------------------------------------------------------------- */
- void canThrow(Node *n, const String *typemap, Node *parameter) const {
- String *canthrow_attribute = NewStringf("tmap:%s:canthrow", typemap);
- String *canthrow = Getattr(parameter, canthrow_attribute);
- if (canthrow)
- Setattr(n, "d:canthrow", "1");
- Delete(canthrow_attribute);
- }
-
- /* ---------------------------------------------------------------------------
- * D::wrapMemberFunctionAsDConst()
- *
- * Determines whether the member function represented by the passed node is
- * wrapped as D »const« or not.
- * --------------------------------------------------------------------------- */
- bool wrapMemberFunctionAsDConst(Node *n) const {
- if (d_version == 1) return false;
- if (static_flag) return false; // Never emit »const« for static member functions.
- return GetFlag(n, "memberget") || SwigType_isconst(Getattr(n, "decl"));
- }
-
- /* ---------------------------------------------------------------------------
- * D::areAllOverloadsOverridden()
- *
- * Determines whether the class the passed function node belongs to overrides
- * all the overlaods for the passed function node defined somewhere up the
- * inheritance hierarchy.
- * --------------------------------------------------------------------------- */
- bool areAllOverloadsOverridden(Node *n) const {
- List *base_list = Getattr(parentNode(n), "bases");
- if (!base_list) {
- // If the class which contains n is not derived from any other class,
- // there cannot be any not-overridden overloads.
- return true;
- }
-
- // In case of multiple base classes, skip to the one which has not been
- // ignored.
- // RESEARCH: Also emit a warning in case of multiple inheritance here?
- Iterator it = First(base_list);
- while (it.item && GetFlag(it.item, "feature:ignore")) {
- it = Next(it);
- }
- Node *base_class = it.item;
-
- if (!base_class) {
- // If all base classes have been ignored, there cannot be one either.
- return true;
- }
-
- // We try to find at least a single overload which exists in the base class
- // so we can progress up the inheritance hierarchy even if there have been
- // new overloads introduced after the topmost class.
- Node *base_function = NULL;
- String *symname = Getattr(n, "sym:name");
- if (symname) {
- for (Node *tmp = firstChild(base_class); tmp; tmp = nextSibling(tmp)) {
- String *child_symname = Getattr(tmp, "sym:name");
- if (child_symname && (Strcmp(child_symname, symname) == 0)) {
- base_function = tmp;
- break;
- }
- }
- }
-
- if (!base_function) {
- // If there is no overload which also exists in the super class, there
- // cannot be any base class overloads not overridden.
- return true;
- }
-
- size_t base_overload_count = 0;
- for (Node *tmp = firstSibling(base_function); tmp; tmp = Getattr(tmp, "sym:nextSibling")) {
- if (is_protected(base_function) &&
- !(Swig_director_mode() && Swig_director_protected_mode() && Swig_all_protected_mode())) {
- // If the base class function is »protected« and were are not in
- // director mode, it is not emitted to the base class and thus we do
- // not count it. Otherwise, we would run into issues if the visibility
- // of some functions was changed from protected to public in a child
- // class with the using directive.
- continue;
- }
- ++base_overload_count;
- }
-
- return ((base_overload_count <= overridingOverloadCount(n)) &&
- areAllOverloadsOverridden(base_function));
- }
-
- /* ---------------------------------------------------------------------------
- * D::overridingOverloadCount()
- *
- * Given a member function node, this function counts how many of the
- * overloads of the function (including itself) override a function in the
- * base class.
- * --------------------------------------------------------------------------- */
- size_t overridingOverloadCount(Node *n) const {
- size_t result = 0;
-
- Node *tmp = firstSibling(n);
- do {
- // KLUDGE: We also have to count the function if the access attribute is
- // not present, since this means that it has been promoted into another
- // protection level in the base class with the C++ »using« directive, and
- // is thus taken into account when counting the base class overloads, even
- // if it is not marked as »override« by the SWIG parser.
- if (Getattr(n, "override") || !Getattr(n, "access")) {
- ++result;
- }
- } while((tmp = Getattr(tmp, "sym:nextSibling")));
-
- return result;
- }
-
- /* ---------------------------------------------------------------------------
- * D::firstSibling()
- *
- * Returns the first sibling of the passed node.
- * --------------------------------------------------------------------------- */
- Node *firstSibling(Node *n) const {
- Node *result = n;
- while (Node *tmp = Getattr(result, "sym:previousSibling")) {
- result = tmp;
- }
- return result;
- }
-
- /* ---------------------------------------------------------------------------
- * D::indentCode()
- *
- * Helper function to indent a code (string) by one level.
- * --------------------------------------------------------------------------- */
- void indentCode(String* code) const {
- Replaceall(code, "\n", "\n ");
- Replaceall(code, " \n", "\n");
- Chop(code);
- }
-
- /* ---------------------------------------------------------------------------
- * D::emitBanner()
- * --------------------------------------------------------------------------- */
- void emitBanner(File *f) const {
- Printf(f, "/* ----------------------------------------------------------------------------\n");
- Swig_banner_target_lang(f, " *");
- Printf(f, " * ----------------------------------------------------------------------------- */\n\n");
- }
-
- /* ---------------------------------------------------------------------------
- * D::outputDirectory()
- *
- * Returns the directory to write the D modules for the given namespace to and
- * and creates the subdirectory if it doesn't exist.
- * --------------------------------------------------------------------------- */
- String *outputDirectory(String *nspace) {
- String *output_directory = Copy(dmodule_directory);
- if (nspace) {
- String *nspace_subdirectory = Copy(nspace);
- Replaceall(nspace_subdirectory, ".", SWIG_FILE_DELIMITER);
- String *newdir_error = Swig_new_subdirectory(output_directory, nspace_subdirectory);
- if (newdir_error) {
- Printf(stderr, "%s\n", newdir_error);
- Delete(newdir_error);
- Exit(EXIT_FAILURE);
- }
- Printv(output_directory, nspace_subdirectory, SWIG_FILE_DELIMITER, 0);
- Delete(nspace_subdirectory);
- }
- return output_directory;
- }
-
- /* ---------------------------------------------------------------------------
- * D::proxyCodeBuffer()
- *
- * Returns the buffer to write proxy code for the given namespace to.
- * --------------------------------------------------------------------------- */
- String *proxyCodeBuffer(String *nspace) {
- if (!nspace) {
- return proxy_dmodule_code;
- }
-
- Hash *hash = Getattr(nspace_proxy_dmodules, nspace);
- if (!hash) {
- hash = NewHash();
- Setattr(hash, "code", NewString(""));
- Setattr(hash, "imports", NewString(""));
- Setattr(nspace_proxy_dmodules, nspace, hash);
- }
- return Getattr(hash, "code");
- }
-
- /* ---------------------------------------------------------------------------
- * D::proxyCodeBuffer()
- *
- * Returns the buffer to write imports for the proxy code for the given
- * namespace to.
- * --------------------------------------------------------------------------- */
- String *proxyImportsBuffer(String *nspace) {
- if (!nspace) {
- return proxy_dmodule_imports;
- }
-
- Hash *hash = Getattr(nspace_proxy_dmodules, nspace);
- if (!hash) {
- hash = NewHash();
- Setattr(hash, "code", NewString(""));
- Setattr(hash, "imports", NewString(""));
- Setattr(nspace_proxy_dmodules, nspace, hash);
- }
- return Getattr(hash, "imports");
- }
-
- /* ---------------------------------------------------------------------------
- * D::createFirstNamespaceName()
- *
- * Returns a new string containing the name of the outermost namespace, e.g.
- * »A« for the argument »A.B.C«.
- * --------------------------------------------------------------------------- */
- String *createFirstNamespaceName(const String *nspace) const {
- char *tmp = Char(nspace);
- char *c = tmp;
- char *co = 0;
- if (!strstr(c, "."))
- return 0;
-
- co = c + Len(nspace);
-
- while (*c && (c != co)) {
- if (*c == '.') {
- break;
- }
- c++;
- }
- if (!*c || (c == tmp)) {
- return NULL;
- }
- return NewStringWithSize(tmp, (int)(c - tmp));
- }
-
- /* ---------------------------------------------------------------------------
- * D::createLastNamespaceName()
- *
- * Returns a new string containing the name of the innermost namespace, e.g.
- * »C« for the argument »A.B.C«.
- * --------------------------------------------------------------------------- */
- String *createLastNamespaceName(const String *nspace) const {
- if (!nspace) return NULL;
- char *c = Char(nspace);
- char *cc = c;
- if (!strstr(c, "."))
- return NewString(nspace);
-
- while (*c) {
- if (*c == '.') {
- cc = c;
- }
- ++c;
- }
- return NewString(cc + 1);
- }
-
- /* ---------------------------------------------------------------------------
- * D::createOuterNamespaceNames()
- *
- * Returns a new string containing the name of the outer namespace, e.g.
- * »A.B« for the argument »A.B.C«.
- * --------------------------------------------------------------------------- */
- String *createOuterNamespaceNames(const String *nspace) const {
- if (!nspace) return NULL;
- char *tmp = Char(nspace);
- char *c = tmp;
- char *cc = c;
- if (!strstr(c, "."))
- return NULL;
-
- while (*c) {
- if (*c == '.') {
- cc = c;
- }
- ++c;
- }
- if (cc == tmp) {
- return NULL;
- }
- return NewStringWithSize(tmp, (int)(cc - tmp));
- }
-};
-
-static Language *new_swig_d() {
- return new D();
-}
-
-/* -----------------------------------------------------------------------------
- * swig_d() - Instantiate module
- * ----------------------------------------------------------------------------- */
-extern "C" Language *swig_d(void) {
- return new_swig_d();
-}
-
-/* -----------------------------------------------------------------------------
- * Usage information displayed at the command line.
- * ----------------------------------------------------------------------------- */
-const char *D::usage = "\
-D Options (available with -d)\n\
- -d2 - Generate code for D2/Phobos (default: D1/Tango)\n\
- -package <pkg> - Write generated D modules into package <pkg>\n\
- -splitproxy - Write each D type to a dedicated file instead of\n\
- generating a single proxy D module.\n\
- -wrapperlibrary <wl> - Set the name of the wrapper library to <wl>\n\
-\n";
diff --git a/contrib/tools/swig/Source/Modules/directors.cxx b/contrib/tools/swig/Source/Modules/directors.cxx
deleted file mode 100644
index 14e2e84661..0000000000
--- a/contrib/tools/swig/Source/Modules/directors.cxx
+++ /dev/null
@@ -1,270 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * directors.cxx
- *
- * Director support functions.
- * Not all of these may be necessary, and some may duplicate existing functionality
- * in SWIG. --MR
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-
-/* -----------------------------------------------------------------------------
- * Swig_csuperclass_call()
- *
- * Generates a fully qualified method call, including the full parameter list.
- * e.g. "base::method(i, j)"
- * ----------------------------------------------------------------------------- */
-
-String *Swig_csuperclass_call(String *base, String *method, ParmList *l) {
- String *call = NewString("");
- int arg_idx = 0;
- Parm *p;
- if (base) {
- Printf(call, "%s::", base);
- }
- Printf(call, "%s(", method);
- for (p = l; p; p = nextSibling(p)) {
- String *pname = Getattr(p, "name");
- if (!pname && Cmp(Getattr(p, "type"), "void")) {
- pname = NewString("");
- Printf(pname, "arg%d", arg_idx++);
- }
- if (p != l)
- Printf(call, ", ");
- Printv(call, pname, NIL);
- }
- Printf(call, ")");
- return call;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_class_declaration()
- *
- * Generate the start of a class/struct declaration.
- * e.g. "class myclass"
- * ----------------------------------------------------------------------------- */
-
-String *Swig_class_declaration(Node *n, String *name) {
- if (!name) {
- name = Getattr(n, "sym:name");
- }
- String *result = NewString("");
- String *kind = Getattr(n, "kind");
- Printf(result, "%s %s", kind, name);
- return result;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_class_name()
- * ----------------------------------------------------------------------------- */
-
-String *Swig_class_name(Node *n) {
- String *name;
- name = Copy(Getattr(n, "sym:name"));
- return name;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_director_declaration()
- *
- * Generate the full director class declaration, complete with base classes.
- * e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {"
- * ----------------------------------------------------------------------------- */
-
-String *Swig_director_declaration(Node *n) {
- String *classname = Swig_class_name(n);
- String *directorname = Language::instance()->directorClassName(n);
- String *base = Getattr(n, "classtype");
- String *declaration = Swig_class_declaration(n, directorname);
-
- Printf(declaration, " : public %s, public Swig::Director {\n", base);
- Delete(classname);
- Delete(directorname);
- return declaration;
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_method_call()
- * ----------------------------------------------------------------------------- */
-
-String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms) {
- String *func;
- int comma = 0;
- Parm *p = parms;
- SwigType *pt;
- String *nname;
-
- func = NewString("");
- nname = SwigType_namestr(name);
- Printf(func, "%s(", nname);
- while (p) {
- String *pname;
- pt = Getattr(p, "type");
- if ((SwigType_type(pt) != T_VOID)) {
- if (comma)
- Printf(func, ",");
- pname = Getattr(p, "name");
- Printf(func, "%s", pname);
- comma = 1;
- }
- p = nextSibling(p);
- }
- Printf(func, ")");
- return func;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_method_decl()
- *
- * Return a stringified version of a C/C++ declaration.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_method_decl(SwigType *return_base_type, SwigType *decl, const_String_or_char_ptr id, List *args, int default_args) {
- String *result = NewString("");
- bool conversion_operator = Strstr(id, "operator ") != 0 && !return_base_type;
-
- Parm *parm = args;
- int arg_idx = 0;
- while (parm) {
- String *type = Getattr(parm, "type");
- String *name = Getattr(parm, "name");
- if (!name && Cmp(type, "void")) {
- name = NewString("");
- Printf(name, "arg%d", arg_idx++);
- Setattr(parm, "name", name);
- }
- parm = nextSibling(parm);
- }
-
- String *rettype = Copy(decl);
- String *quals = SwigType_pop_function_qualifiers(rettype);
- String *qualifiers = 0;
- if (quals)
- qualifiers = SwigType_str(quals, 0);
-
- String *popped_decl = SwigType_pop_function(rettype);
- if (return_base_type)
- Append(rettype, return_base_type);
-
- if (!conversion_operator) {
- SwigType *rettype_stripped = SwigType_strip_qualifiers(rettype);
- String *rtype = SwigType_str(rettype, 0);
- Append(result, rtype);
- if ((SwigType_issimple(rettype_stripped) && return_base_type) || SwigType_isqualifier(rettype))
- Append(result, " ");
- Delete(rtype);
- Delete(rettype_stripped);
- }
-
- if (id)
- Append(result, id);
-
- String *args_string = default_args ? ParmList_str_defaultargs(args) : ParmList_str(args);
- Printv(result, "(", args_string, ")", NIL);
-
- if (qualifiers)
- Printv(result, " ", qualifiers, NIL);
-
- Delete(args_string);
- Delete(popped_decl);
- Delete(qualifiers);
- Delete(quals);
- Delete(rettype);
- return result;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_director_emit_dynamic_cast()
- *
- * In order to call protected virtual director methods from the target language, we need
- * to add an extra dynamic_cast to call the public C++ wrapper in the director class.
- * Also for non-static protected members when the allprotected option is on.
- * ----------------------------------------------------------------------------- */
-
-void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f) {
- // TODO: why is the storage element removed in staticmemberfunctionHandler ??
- if ((!is_public(n) && (is_member_director(n) || GetFlag(n, "explicitcall"))) ||
- (is_non_virtual_protected_access(n) && !(Swig_storage_isstatic_custom(n, "staticmemberfunctionHandler:storage") ||
- Swig_storage_isstatic(n))
- && !Equal(nodeType(n), "constructor"))) {
- Node *parent = Getattr(n, "parentNode");
- String *dirname;
- String *dirdecl;
- dirname = Language::instance()->directorClassName(parent);
- dirdecl = NewStringf("%s *darg = 0", dirname);
- Wrapper_add_local(f, "darg", dirdecl);
- Printf(f->code, "darg = dynamic_cast<%s *>(arg1);\n", dirname);
- Delete(dirname);
- Delete(dirdecl);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_director_parms_fixup()
- *
- * For each parameter in the C++ member function, copy the parameter name
- * to its "lname"; this ensures that Swig_typemap_attach_parms() will do
- * the right thing when it sees strings like "$1" in "directorin" typemaps.
- * ----------------------------------------------------------------------------- */
-
-void Swig_director_parms_fixup(ParmList *parms) {
- Parm *p;
- int i;
- for (i = 0, p = parms; p; p = nextSibling(p), ++i) {
- String *arg = Getattr(p, "name");
- String *lname = 0;
-
- if (!arg && !Equal(Getattr(p, "type"), "void")) {
- lname = NewStringf("arg%d", i);
- Setattr(p, "name", lname);
- } else
- lname = Copy(arg);
-
- Setattr(p, "lname", lname);
- Delete(lname);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_director_can_unwrap()
- *
- * Determine whether a function's return type can be returned as an existing
- * target language object instead of creating a new target language object.
- * Must be a director class and only for return by pointer or reference only
- * (not by value or by pointer to pointer etc).
- * ----------------------------------------------------------------------------- */
-
-bool Swig_director_can_unwrap(Node *n) {
-
- // FIXME: this will not try to unwrap directors returned as non-director
- // base class pointers!
-
- bool unwrap = false;
-
- String *type = Getattr(n, "type");
- SwigType *t = SwigType_typedef_resolve_all(type);
- SwigType *t1 = SwigType_strip_qualifiers(t);
- SwigType *prefix = SwigType_prefix(t1);
-
- if (Strcmp(prefix, "p.") == 0 || Strcmp(prefix, "r.") == 0) {
- Node *parent = Swig_methodclass(n);
- Node *module = Getattr(parent, "module");
- Node *target = Swig_directormap(module, t1);
- if (target)
- unwrap = true;
- }
-
- Delete(prefix);
- Delete(t1);
- Delete(t);
-
- return unwrap;
-}
diff --git a/contrib/tools/swig/Source/Modules/emit.cxx b/contrib/tools/swig/Source/Modules/emit.cxx
deleted file mode 100644
index 74adc54009..0000000000
--- a/contrib/tools/swig/Source/Modules/emit.cxx
+++ /dev/null
@@ -1,556 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * emit.cxx
- *
- * Useful functions for emitting various pieces of code.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include "cparse.h"
-
-/* -----------------------------------------------------------------------------
- * emit_return_variable()
- *
- * Emits a variable declaration for a function return value.
- * The variable name is always called result.
- * n => Node of the method being wrapped
- * rt => the return type
- * f => the wrapper to generate code into
- * ----------------------------------------------------------------------------- */
-
-void emit_return_variable(Node *n, SwigType *rt, Wrapper *f) {
-
- if (!GetFlag(n, "tmap:out:optimal")) {
- if (rt && (SwigType_type(rt) != T_VOID)) {
- SwigType *vt = cplus_value_type(rt);
- SwigType *tt = vt ? vt : rt;
- SwigType *lt = SwigType_ltype(tt);
- String *lstr = SwigType_str(lt, Swig_cresult_name());
- if (SwigType_ispointer(lt)) {
- Wrapper_add_localv(f, Swig_cresult_name(), lstr, "= 0", NULL);
- } else {
- Wrapper_add_local(f, Swig_cresult_name(), lstr);
- }
- if (vt) {
- Delete(vt);
- }
- Delete(lt);
- Delete(lstr);
- }
- }
-}
-
-/* -----------------------------------------------------------------------------
- * emit_parameter_variables()
- *
- * Emits a list of variable declarations for function parameters.
- * The variable names are always called arg1, arg2, etc...
- * l => the parameter list
- * f => the wrapper to generate code into
- * ----------------------------------------------------------------------------- */
-
-void emit_parameter_variables(ParmList *l, Wrapper *f) {
-
- Parm *p;
- String *tm;
-
- /* Emit function arguments */
- Swig_cargs(f, l);
-
- /* Attach typemaps to parameters */
- /* Swig_typemap_attach_parms("ignore",l,f); */
-
- Swig_typemap_attach_parms("default", l, f);
- Swig_typemap_attach_parms("arginit", l, f);
-
- /* Apply the arginit and default */
- p = l;
- while (p) {
- tm = Getattr(p, "tmap:arginit");
- if (tm) {
- Printv(f->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:arginit:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* Apply the default typemap */
- p = l;
- while (p) {
- tm = Getattr(p, "tmap:default");
- if (tm) {
- Printv(f->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:default:next");
- } else {
- p = nextSibling(p);
- }
- }
-}
-
-/* -----------------------------------------------------------------------------
- * emit_attach_parmmaps()
- *
- * Attach the standard parameter related typemaps.
- * ----------------------------------------------------------------------------- */
-
-void emit_attach_parmmaps(ParmList *l, Wrapper *f) {
- Swig_typemap_attach_parms("in", l, f);
- Swig_typemap_attach_parms("typecheck", l, 0);
- Swig_typemap_attach_parms("argout", l, f);
- Swig_typemap_attach_parms("check", l, f);
- Swig_typemap_attach_parms("freearg", l, f);
-
- {
- /* This is compatibility code to deal with the deprecated "ignore" typemap */
- Parm *p = l;
- Parm *np;
- while (p) {
- String *tm = Getattr(p, "tmap:in");
- if (tm && checkAttribute(p, "tmap:in:numinputs", "0")) {
- Printv(f->code, tm, "\n", NIL);
- np = Getattr(p, "tmap:in:next");
- while (p && (p != np)) {
- /* Setattr(p,"ignore","1"); Deprecate */
- p = nextSibling(p);
- }
- } else if (tm) {
- p = Getattr(p, "tmap:in:next");
- } else {
- p = nextSibling(p);
- }
- }
- }
-
- /* Perform a sanity check on "in" and "freearg" typemaps. These
- must exactly match to avoid chaos. If a mismatch occurs, we
- nuke the freearg typemap */
- {
- Parm *p = l;
- Parm *npin, *npfreearg;
- while (p) {
- npin = Getattr(p, "tmap:in:next");
-
- /*
- if (Getattr(p,"tmap:ignore")) {
- npin = Getattr(p,"tmap:ignore:next");
- } else if (Getattr(p,"tmap:in")) {
- npin = Getattr(p,"tmap:in:next");
- }
- */
-
- if (Getattr(p, "tmap:freearg")) {
- npfreearg = Getattr(p, "tmap:freearg:next");
- if (npin != npfreearg) {
- while (p != npin) {
- Delattr(p, "tmap:freearg");
- Delattr(p, "tmap:freearg:next");
- p = nextSibling(p);
- }
- }
- }
- p = npin;
- }
- }
-
- /* Check for variable length arguments with no input typemap.
- If no input is defined, we set this to ignore and print a
- message.
- */
- {
- Parm *p = l;
- Parm *lp = 0;
- while (p) {
- if (!checkAttribute(p, "tmap:in:numinputs", "0")) {
- lp = p;
- p = Getattr(p, "tmap:in:next");
- continue;
- }
- if (SwigType_isvarargs(Getattr(p, "type"))) {
- Swig_warning(WARN_LANG_VARARGS, input_file, line_number, "Variable length arguments discarded.\n");
- Setattr(p, "tmap:in", "");
- }
- lp = 0;
- p = nextSibling(p);
- }
-
- /* Check if last input argument is variable length argument */
- if (lp) {
- p = lp;
- while (p) {
- if (SwigType_isvarargs(Getattr(p, "type"))) {
- // Mark the head of the ParmList that it has varargs
- Setattr(l, "emit:varargs", lp);
-//Printf(stdout, "setting emit:varargs %s ... %s +++ %s\n", Getattr(l, "emit:varargs"), Getattr(l, "type"), Getattr(p, "type"));
- break;
- }
- p = nextSibling(p);
- }
- }
- }
-
- /*
- * An equivalent type can be used in the typecheck typemap for SWIG to detect the overloading of equivalent
- * target language types. This is primarily for the smartptr feature, where a pointer and a smart pointer
- * are seen as equivalent types in the target language.
- */
- {
- Parm *p = l;
- while (p) {
- String *tm = Getattr(p, "tmap:typecheck");
- if (tm) {
- String *equivalent = Getattr(p, "tmap:typecheck:equivalent");
- if (equivalent) {
- String *precedence = Getattr(p, "tmap:typecheck:precedence");
- if (precedence && Strcmp(precedence, "0") != 0)
- Swig_error(Getfile(tm), Getline(tm), "The 'typecheck' typemap for %s contains an 'equivalent' attribute for a 'precedence' that is not set to SWIG_TYPECHECK_POINTER or 0.\n", SwigType_str(Getattr(p, "type"), 0));
- SwigType *cpt = Swig_cparse_type(equivalent);
- if (cpt) {
- Setattr(p, "equivtype", cpt);
- Delete(cpt);
- } else {
- Swig_error(Getfile(tm), Getline(tm), "Invalid type (%s) in 'equivalent' attribute in 'typecheck' typemap for type %s.\n", equivalent, SwigType_str(Getattr(p, "type"), 0));
- }
- }
- p = Getattr(p, "tmap:typecheck:next");
- } else {
- p = nextSibling(p);
- }
- }
- }
-}
-
-/* -----------------------------------------------------------------------------
- * emit_num_arguments()
- *
- * Calculate the total number of arguments. This function is safe for use
- * with multi-argument typemaps which may change the number of arguments in
- * strange ways.
- * ----------------------------------------------------------------------------- */
-
-int emit_num_arguments(ParmList *parms) {
- Parm *p = parms;
- int nargs = 0;
-
- while (p) {
- if (Getattr(p, "tmap:in")) {
- nargs += GetInt(p, "tmap:in:numinputs");
- p = Getattr(p, "tmap:in:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* DB 04/02/2003: Not sure this is necessary with tmap:in:numinputs */
- /*
- if (parms && (p = Getattr(parms,"emit:varargs"))) {
- if (!nextSibling(p)) {
- nargs--;
- }
- }
- */
- return nargs;
-}
-
-/* -----------------------------------------------------------------------------
- * emit_num_required()
- *
- * Computes the number of required arguments. This function is safe for
- * use with multi-argument typemaps and knows how to skip over everything
- * properly. Note that parameters with default values are counted unless
- * the compact default args option is on.
- * ----------------------------------------------------------------------------- */
-
-int emit_num_required(ParmList *parms) {
- Parm *p = parms;
- int nargs = 0;
- Parm *first_default_arg = 0;
- int compactdefargs = ParmList_is_compactdefargs(p);
-
- while (p) {
- if (Getattr(p, "tmap:in") && checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- } else {
- if (Getattr(p, "tmap:default"))
- break;
- if (Getattr(p, "value")) {
- if (!first_default_arg)
- first_default_arg = p;
- if (compactdefargs)
- break;
- }
- nargs += GetInt(p, "tmap:in:numinputs");
- if (Getattr(p, "tmap:in")) {
- p = Getattr(p, "tmap:in:next");
- } else {
- p = nextSibling(p);
- }
- }
- }
-
- /* Print error message for non-default arguments following default arguments */
- /* The error message is printed more than once with most language modules, this ought to be fixed */
- if (first_default_arg) {
- p = first_default_arg;
- while (p) {
- if (Getattr(p, "tmap:in") && checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- } else {
- if (!Getattr(p, "value") && (!Getattr(p, "tmap:default"))) {
- Swig_error(Getfile(p), Getline(p), "Non-optional argument '%s' follows an optional argument.\n", Getattr(p, "name"));
- }
- if (Getattr(p, "tmap:in")) {
- p = Getattr(p, "tmap:in:next");
- } else {
- p = nextSibling(p);
- }
- }
- }
- }
-
- /* DB 04/02/2003: Not sure this is necessary with tmap:in:numinputs */
- /*
- if (parms && (p = Getattr(parms,"emit:varargs"))) {
- if (!nextSibling(p)) {
- nargs--;
- }
- }
- */
- return nargs;
-}
-
-/* -----------------------------------------------------------------------------
- * emit_isvarargs()
- *
- * Checks if a ParmList is a parameter list containing varargs.
- * This function requires emit_attach_parmmaps to have been called beforehand.
- * ----------------------------------------------------------------------------- */
-
-int emit_isvarargs(ParmList *p) {
- if (!p)
- return 0;
- if (Getattr(p, "emit:varargs"))
- return 1;
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * emit_isvarargs_function()
- *
- * Checks for varargs in a function/constructor (can be overloaded)
- * ----------------------------------------------------------------------------- */
-
-bool emit_isvarargs_function(Node *n) {
- bool has_varargs = false;
- Node *over = Getattr(n, "sym:overloaded");
- if (over) {
- for (Node *sibling = over; sibling; sibling = Getattr(sibling, "sym:nextSibling")) {
- if (ParmList_has_varargs(Getattr(sibling, "parms"))) {
- has_varargs = true;
- break;
- }
- }
- } else {
- has_varargs = ParmList_has_varargs(Getattr(n, "parms")) ? true : false;
- }
- return has_varargs;
-}
-
-/* -----------------------------------------------------------------------------
- * void emit_mark_vararg_parms()
- *
- * Marks the vararg parameters which are to be ignored.
- * Vararg parameters are marked as ignored if there is no 'in' varargs (...)
- * typemap.
- * ----------------------------------------------------------------------------- */
-
-void emit_mark_varargs(ParmList *l) {
- Parm *p = l;
- while (p) {
- if (SwigType_isvarargs(Getattr(p, "type")))
- if (!Getattr(p, "tmap:in"))
- Setattr(p, "varargs:ignore", "1");
- p = nextSibling(p);
- }
-}
-
-#if 0
-/* replace_contract_args. This function replaces argument names in contract
- specifications. Used in conjunction with the %contract directive. */
-
-static void replace_contract_args(Parm *cp, Parm *rp, String *s) {
- while (cp && rp) {
- String *n = Getattr(cp, "name");
- if (n) {
- Replace(s, n, Getattr(rp, "lname"), DOH_REPLACE_ID);
- }
- cp = nextSibling(cp);
- rp = nextSibling(rp);
- }
-}
-#endif
-
-/* -----------------------------------------------------------------------------
- * int emit_action_code()
- *
- * Emits action code for a wrapper. Adds in exception handling code (%exception).
- * eaction -> the action code to emit
- * wrappercode -> the emitted code (output)
- * ----------------------------------------------------------------------------- */
-int emit_action_code(Node *n, String *wrappercode, String *eaction) {
- assert(Getattr(n, "wrap:name"));
-
- /* Look for except feature (%exception) */
- String *tm = GetFlagAttr(n, "feature:except");
- if (tm)
- tm = Copy(tm);
- if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
- if (Strstr(tm, "$")) {
- Swig_replace_special_variables(n, parentNode(n), tm);
- Replaceall(tm, "$function", eaction); // deprecated
- Replaceall(tm, "$action", eaction);
- }
- Printv(wrappercode, tm, "\n", NIL);
- Delete(tm);
- return 1;
- } else {
- Printv(wrappercode, eaction, "\n", NIL);
- return 0;
- }
-}
-
-/* -----------------------------------------------------------------------------
- * int emit_action()
- *
- * Emits the call to the wrapped function.
- * Adds in exception specification exception handling and %exception code.
- * ----------------------------------------------------------------------------- */
-String *emit_action(Node *n) {
- String *actioncode = NewStringEmpty();
- String *tm;
- String *action;
- String *wrap;
- ParmList *catchlist = Getattr(n, "catchlist");
-
- /* Look for fragments */
- {
- String *fragment = Getattr(n, "feature:fragment");
- if (fragment) {
- char *c, *tok;
- String *t = Copy(fragment);
- c = Char(t);
- tok = strtok(c, ",");
- while (tok) {
- String *fname = NewString(tok);
- Setfile(fname, Getfile(n));
- Setline(fname, Getline(n));
- Swig_fragment_emit(fname);
- Delete(fname);
- tok = strtok(NULL, ",");
- }
- Delete(t);
- }
- }
-
- /* Emit wrapper code (if any) */
- wrap = Getattr(n, "wrap:code");
- if (wrap && Swig_filebyname("header") != Getattr(n, "wrap:code:done")) {
- File *f_code = Swig_filebyname("header");
- if (f_code) {
- Printv(f_code, wrap, NIL);
- }
- Setattr(n, "wrap:code:done", f_code);
- }
-
- action = Getattr(n, "feature:action");
- if (!action)
- action = Getattr(n, "wrap:action");
- assert(action != 0);
-
- /* Emit contract code (if any) */
- if (Swig_contract_mode_get()) {
- /* Preassertion */
- tm = Getattr(n, "contract:preassert");
- if (Len(tm)) {
- Printv(actioncode, tm, "\n", NIL);
- }
- }
- /* Exception handling code */
-
- /* saves action -> eaction for postcatching exception */
- String *eaction = NewString("");
-
- /* If we are in C++ mode and there is an exception specification. We're going to
- enclose the block in a try block */
- if (catchlist) {
- Printf(eaction, "try {\n");
- }
-
- String *preaction = Getattr(n, "wrap:preaction");
- if (preaction)
- Printv(eaction, preaction, NIL);
-
- Printv(eaction, action, NIL);
-
- String *postaction = Getattr(n, "wrap:postaction");
- if (postaction)
- Printv(eaction, postaction, NIL);
-
- if (catchlist) {
- int unknown_catch = 0;
- int has_varargs = 0;
- Printf(eaction, "}");
- for (Parm *ep = catchlist; ep; ep = nextSibling(ep)) {
- String *em = Swig_typemap_lookup("throws", ep, "_e", 0);
- if (em) {
- SwigType *et = Getattr(ep, "type");
- SwigType *etr = SwigType_typedef_resolve_all(et);
- if (SwigType_isreference(etr) || SwigType_ispointer(etr) || SwigType_isarray(etr)) {
- Printf(eaction, " catch(%s) {", SwigType_str(et, "_e"));
- } else if (SwigType_isvarargs(etr)) {
- Printf(eaction, " catch(...) {");
- has_varargs = 1;
- } else {
- Printf(eaction, " catch(%s) {", SwigType_str(et, "&_e"));
- }
- Printv(eaction, em, "\n", NIL);
- Printf(eaction, "}");
- } else {
- Swig_warning(WARN_TYPEMAP_THROW, Getfile(n), Getline(n), "No 'throws' typemap defined for exception type '%s'\n", SwigType_str(Getattr(ep, "type"), 0));
- unknown_catch = 1;
- }
- }
- if (unknown_catch && !has_varargs) {
- Printf(eaction, " catch(...) {\nthrow;\n}");
- }
- }
-
- /* Look for except typemap (Deprecated) */
- tm = Swig_typemap_lookup("except", n, Swig_cresult_name(), 0);
- if (tm) {
- Setattr(n, "feature:except", tm);
- tm = 0;
- }
-
- /* emit the except feature code */
- emit_action_code(n, actioncode, eaction);
-
- Delete(eaction);
-
- /* Emit contract code (if any) */
- if (Swig_contract_mode_get()) {
- /* Postassertion */
- tm = Getattr(n, "contract:postassert");
- if (Len(tm)) {
- Printv(actioncode, tm, "\n", NIL);
- }
- }
-
- return actioncode;
-}
diff --git a/contrib/tools/swig/Source/Modules/go.cxx b/contrib/tools/swig/Source/Modules/go.cxx
deleted file mode 100644
index bf63bec639..0000000000
--- a/contrib/tools/swig/Source/Modules/go.cxx
+++ /dev/null
@@ -1,5708 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * go.cxx
- *
- * Go language module for SWIG.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include "cparse.h"
-#include <ctype.h>
-
-/* ----------------------------------------------------------------------
- * siphash()
- *
- * 64-bit SipHash-2-4 to generate unique id for each module
- * ---------------------------------------------------------------------- */
-
-// An unsigned 64-bit integer that works on a 32-bit host.
-typedef struct {
- // Assume unsigned long is at least 32 bits.
- unsigned long hi;
- unsigned long lo;
-} swig_uint64;
-
-// Rotate v left by bits, which must be <= 32.
-static inline void _rotl(swig_uint64 *v, int bits) {
- assert(bits <= 32);
- unsigned long tmp = v->hi;
- if (bits == 32) {
- v->hi = v->lo;
- v->lo = tmp;
- } else {
- v->hi = (tmp << bits) | ((0xfffffffful & v->lo) >> (32 - bits));
- v->lo = (v->lo << bits) | ((0xfffffffful & tmp) >> (32 - bits));
- }
-}
-
-// dst ^= src
-static inline void _xor(swig_uint64 *dst, swig_uint64 *src) {
- dst->lo ^= src->lo;
- dst->hi ^= src->hi;
-}
-
-// dst += src
-static inline void _add(swig_uint64 *dst, swig_uint64 *src) {
- dst->lo += src->lo;
- dst->hi += src->hi + ((dst->lo & 0xfffffffful) < (src->lo&0xfffffffful) ? 1 : 0);
-}
-#define SIPROUND \
- do { \
- _add(&v0, &v1); _rotl(&v1, 13); _xor(&v1, &v0); _rotl(&v0, 32); \
- _add(&v2, &v3); _rotl(&v3, 16); _xor(&v3, &v2); \
- _add(&v0, &v3); _rotl(&v3, 21); _xor(&v3, &v0); \
- _add(&v2, &v1); _rotl(&v1, 17); _xor(&v1, &v2); _rotl(&v2, 32); \
- } while(0)
-
-// Set out to the hash of inc/inlen.
-static void siphash(swig_uint64 *out, const char *inc, unsigned long inlen) {
- /* "somepseudorandomlygeneratedbytes" */
- swig_uint64 v0 = {0x736f6d65UL, 0x70736575UL};
- swig_uint64 v1 = {0x646f7261UL, 0x6e646f6dUL};
- swig_uint64 v2 = {0x6c796765UL, 0x6e657261UL};
- swig_uint64 v3 = {0x74656462UL, 0x79746573UL};
- swig_uint64 b;
- /* hard-coded k. */
- swig_uint64 k0 = {0x07060504UL, 0x03020100UL};
- swig_uint64 k1 = {0x0F0E0D0CUL, 0x0B0A0908UL};
- int i;
- const int cROUNDS = 2, dROUNDS = 4;
- const unsigned char *in = (const unsigned char *)inc;
- const unsigned char *end = in + inlen - (inlen % 8);
- int left = inlen & 7;
- _xor(&v3, &k1); _xor(&v2, &k0); _xor(&v1, &k1); _xor(&v0, &k0);
- for (; in != end; in += 8) {
- b.hi = 0; b.lo = 0;
- for (i = 0; i < 4; i++) {
- b.lo |= ((unsigned long)in[i]) << (8*i);
- }
- for (i = 0; i < 4; i++) {
- b.hi |= ((unsigned long)in[i+4]) << (8*i);
- }
- _xor(&v3, &b);
- for (i = 0; i < cROUNDS; i++) {
- SIPROUND;
- }
- _xor(&v0, &b);
- }
- b.hi = (inlen & 0xff)<<24; b.lo = 0;
- for (; left; left--) {
- if (left > 4) {
- b.hi |= ((unsigned long)in[left-1]) << (8*left-8-32);
- } else {
- b.lo |= ((unsigned long)in[left-1]) << (8*left-8);
- }
- }
- _xor(&v3, &b);
- for(i=0; i<cROUNDS; i++) {
- SIPROUND;
- }
- _xor(&v0, &b); v2.lo ^= 0xff;
- for(i=0; i<dROUNDS; i++) {
- SIPROUND;
- }
- out->lo = 0; out->hi = 0;
- _xor(out, &v0); _xor(out, &v1); _xor(out, &v2); _xor(out, &v3);
-}
-#undef SIPROUND
-
-class GO:public Language {
- static const char *const usage;
-
- // Go package name.
- String *package;
- // SWIG module name.
- String *module;
- // Flag for generating gccgo output.
- bool gccgo_flag;
- // Prefix to use with gccgo.
- String *go_prefix;
- // -fgo-prefix option.
- String *prefix_option;
- // -fgo-pkgpath option.
- String *pkgpath_option;
- // Prefix for translating %import directive to import statements.
- String *import_prefix;
- // Whether to use a shared library.
- bool use_shlib;
- // Name of shared library to import.
- String *soname;
- // Size in bits of the Go type "int". 0 if not specified.
- int intgo_type_size;
-
- /* Output files */
- File *f_c_begin;
- File *f_go_begin;
-
- /* Output fragments */
- File *f_c_runtime;
- File *f_c_header;
- File *f_c_wrappers;
- File *f_c_init;
- File *f_c_directors;
- File *f_c_directors_h;
- File *f_go_imports;
- File *f_go_runtime;
- File *f_go_header;
- File *f_go_wrappers;
- File *f_go_directors;
- File *f_cgo_comment;
- File *f_cgo_comment_typedefs;
-
- // True if we imported a module.
- bool saw_import;
- // If not NULL, name of import package being processed.
- String *imported_package;
- // Build interface methods while handling a class. This is only
- // non-NULL when we are handling methods.
- String *interfaces;
- // The class node while handling a class. This is only non-NULL
- // when we are handling methods.
- Node *class_node;
- // The class name while handling a class. This is only non-NULL
- // when we are handling methods. This is the name of the class as
- // SWIG sees it.
- String *class_name;
- // The receiver name while handling a class. This is only non-NULL
- // when we are handling methods. This is the name of the class
- // as run through goCPointerType.
- String *class_receiver;
- // A hash table of method names that we have seen when processing a
- // class. This lets us detect base class methods that we don't want
- // to use.
- Hash *class_methods;
- // True when we are generating the wrapper functions for a variable.
- bool making_variable_wrappers;
- // True when working with a static member function.
- bool is_static_member_function;
- // A hash table of enum types that we have seen but which may not have
- // been defined. The index is a SwigType.
- Hash *undefined_enum_types;
- // A hash table of types that we have seen but which may not have
- // been defined. The index is a SwigType.
- Hash *undefined_types;
- // A hash table of classes which were defined. The index is a Go
- // type name.
- Hash *defined_types;
- // A hash table of all the go_imports already imported. The index is a full
- // import name e.g. '"runtime"' or '_ "runtime/cgo"' or 'sc "syscall"'.
- Hash *go_imports;
- // A unique ID used to make public symbols unique.
- String *unique_id;
-
-public:
- GO():package(NULL),
- module(NULL),
- gccgo_flag(false),
- go_prefix(NULL),
- prefix_option(NULL),
- pkgpath_option(NULL),
- import_prefix(NULL),
- use_shlib(false),
- soname(NULL),
- intgo_type_size(0),
- f_c_begin(NULL),
- f_go_begin(NULL),
- f_c_runtime(NULL),
- f_c_header(NULL),
- f_c_wrappers(NULL),
- f_c_init(NULL),
- f_c_directors(NULL),
- f_c_directors_h(NULL),
- f_go_imports(NULL),
- f_go_runtime(NULL),
- f_go_header(NULL),
- f_go_wrappers(NULL),
- f_go_directors(NULL),
- f_cgo_comment(NULL),
- f_cgo_comment_typedefs(NULL),
- saw_import(false),
- imported_package(NULL),
- interfaces(NULL),
- class_node(NULL),
- class_name(NULL),
- class_receiver(NULL),
- class_methods(NULL),
- making_variable_wrappers(false),
- is_static_member_function(false),
- undefined_enum_types(NULL),
- undefined_types(NULL),
- defined_types(NULL),
- go_imports(NULL),
- unique_id(NULL) {
- director_multiple_inheritance = 1;
- director_language = 1;
- director_prot_ctor_code = NewString("_swig_gopanic(\"accessing abstract class or protected constructor\");");
- }
-
-private:
- /* ------------------------------------------------------------
- * main()
- * ------------------------------------------------------------ */
- virtual void main(int argc, char *argv[]) {
-
- SWIG_library_directory("go");
- bool saw_nocgo_flag = false;
-
- // Process command line options.
- for (int i = 1; i < argc; i++) {
- if (argv[i]) {
- if (strcmp(argv[i], "-package") == 0) {
- if (argv[i + 1]) {
- package = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-cgo") == 0) {
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-no-cgo") == 0) {
- Swig_mark_arg(i);
- saw_nocgo_flag = true;
- } else if (strcmp(argv[i], "-gccgo") == 0) {
- Swig_mark_arg(i);
- gccgo_flag = true;
- } else if (strcmp(argv[i], "-go-prefix") == 0) {
- if (argv[i + 1]) {
- prefix_option = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-go-pkgpath") == 0) {
- if (argv[i + 1]) {
- pkgpath_option = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-import-prefix") == 0) {
- if (argv[i + 1]) {
- import_prefix = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-use-shlib") == 0) {
- Swig_mark_arg(i);
- use_shlib = true;
- } else if (strcmp(argv[i], "-soname") == 0) {
- if (argv[i + 1]) {
- soname = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-longsize") == 0) {
- // Ignore for backward compatibility.
- if (argv[i + 1]) {
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- ++i;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-intgosize") == 0) {
- if (argv[i + 1]) {
- intgo_type_size = atoi(argv[i + 1]);
- if (intgo_type_size != 32 && intgo_type_size != 64) {
- Printf(stderr, "-intgosize not 32 or 64\n");
- Swig_arg_error();
- }
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- ++i;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-help") == 0) {
- Printf(stdout, "%s\n", usage);
- }
- }
- }
-
- if (saw_nocgo_flag) {
- Printf(stderr, "SWIG -go: -no-cgo option is no longer supported\n");
- Exit(EXIT_FAILURE);
- }
-
- if (gccgo_flag && !pkgpath_option && !prefix_option) {
- prefix_option = NewString("go");
- }
-
- // Add preprocessor symbol to parser.
- Preprocessor_define("SWIGGO 1", 0);
-
- if (gccgo_flag) {
- Preprocessor_define("SWIGGO_GCCGO 1", 0);
- }
-
- if (intgo_type_size == 32) {
- Preprocessor_define("SWIGGO_INTGO_SIZE 32", 0);
- } else if (intgo_type_size == 64) {
- Preprocessor_define("SWIGGO_INTGO_SIZE 64", 0);
- } else {
- Preprocessor_define("SWIGGO_INTGO_SIZE 0", 0);
- }
-
- // Add typemap definitions.
- SWIG_typemap_lang("go");
- SWIG_config_file("go.swg");
-
- allow_overloading();
- }
-
- /* ---------------------------------------------------------------------
- * top()
- *
- * For gc, we are going to create the following files:
- *
- * 1) A .c or .cxx file compiled with gcc. This file will contain
- * function wrappers. Each wrapper will take a pointer to a
- * struct holding the arguments, unpack them, and call the real
- * function.
- *
- * 2) A .go file which defines the Go form of all types, and which
- * defines Go function wrappers. Each wrapper will call the C
- * function wrapper in the second file.
- *
- * 3) A .c file compiled with 6c/8c. This file will define
- * Go-callable C function wrappers. Each wrapper will use
- * cgocall to call the function wrappers in the first file.
- *
- * When generating code for gccgo, we don't need the third file, and
- * the function wrappers in the first file have a different form.
- *
- * --------------------------------------------------------------------- */
-
- virtual int top(Node *n) {
- Node *optionsnode = Getattr(Getattr(n, "module"), "options");
- if (optionsnode) {
- if (Getattr(optionsnode, "directors")) {
- allow_directors();
- }
- if (Getattr(optionsnode, "dirprot")) {
- allow_dirprot();
- }
- allow_allprotected(GetFlag(optionsnode, "allprotected"));
- }
-
- module = Getattr(n, "name");
- if (!package) {
- package = Copy(module);
- }
- if (!soname && use_shlib) {
- soname = Copy(package);
- Append(soname, ".so");
- }
-
- if (gccgo_flag) {
- String *pref;
- if (pkgpath_option) {
- pref = pkgpath_option;
- } else {
- pref = prefix_option;
- }
- go_prefix = NewString("");
- for (char *p = Char(pref); *p != '\0'; p++) {
- if ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || (*p >= '0' && *p <= '9') || *p == '.' || *p == '$') {
- Putc(*p, go_prefix);
- } else {
- Putc('_', go_prefix);
- }
- }
- if (!pkgpath_option) {
- Append(go_prefix, ".");
- Append(go_prefix, getModuleName(package));
- }
- }
-
- // Get filenames.
-
- String *swig_filename = Getattr(n, "infile");
- String *c_filename = Getattr(n, "outfile");
- String *c_filename_h = Getattr(n, "outfile_h");
-
- String *go_filename = NewString("");
- Printf(go_filename, "%s%s.go", SWIG_output_directory(), module);
-
- // Generate a unique ID based on a hash of the SWIG input.
- swig_uint64 hash = {0, 0};
- FILE *swig_input = Swig_open(swig_filename);
- if (swig_input == NULL) {
- FileErrorDisplay(swig_filename);
- Exit(EXIT_FAILURE);
- }
- String *swig_input_content = Swig_read_file(swig_input);
- siphash(&hash, Char(swig_input_content), Len(swig_input_content));
- Delete(swig_input_content);
- fclose(swig_input);
- unique_id = NewString("");
- Printf(unique_id, "_%s_%08x%08x", getModuleName(package), hash.hi, hash.lo);
-
- // Open files.
-
- f_c_begin = NewFile(c_filename, "w", SWIG_output_files());
- if (!f_c_begin) {
- FileErrorDisplay(c_filename);
- Exit(EXIT_FAILURE);
- }
-
- if (directorsEnabled()) {
- if (!c_filename_h) {
- Printf(stderr, "Unable to determine outfile_h\n");
- Exit(EXIT_FAILURE);
- }
- f_c_directors_h = NewFile(c_filename_h, "w", SWIG_output_files());
- if (!f_c_directors_h) {
- FileErrorDisplay(c_filename_h);
- Exit(EXIT_FAILURE);
- }
- }
-
- f_go_begin = NewFile(go_filename, "w", SWIG_output_files());
- if (!f_go_begin) {
- FileErrorDisplay(go_filename);
- Exit(EXIT_FAILURE);
- }
-
- f_c_runtime = NewString("");
- f_c_header = NewString("");
- f_c_wrappers = NewString("");
- f_c_init = NewString("");
- f_c_directors = NewString("");
- f_go_imports = NewString("");
- f_go_runtime = NewString("");
- f_go_header = NewString("");
- f_go_wrappers = NewString("");
- f_go_directors = NewString("");
- f_cgo_comment = NewString("");
- f_cgo_comment_typedefs = NewString("");
-
- Swig_register_filebyname("begin", f_c_begin);
- Swig_register_filebyname("runtime", f_c_runtime);
- Swig_register_filebyname("header", f_c_header);
- Swig_register_filebyname("wrapper", f_c_wrappers);
- Swig_register_filebyname("init", f_c_init);
- Swig_register_filebyname("director", f_c_directors);
- Swig_register_filebyname("director_h", f_c_directors_h);
- Swig_register_filebyname("go_begin", f_go_begin);
- Swig_register_filebyname("go_imports", f_go_imports);
- Swig_register_filebyname("go_runtime", f_go_runtime);
- Swig_register_filebyname("go_header", f_go_header);
- Swig_register_filebyname("go_wrapper", f_go_wrappers);
- Swig_register_filebyname("go_director", f_go_directors);
- Swig_register_filebyname("cgo_comment", f_cgo_comment);
- Swig_register_filebyname("cgo_comment_typedefs", f_cgo_comment_typedefs);
-
- Swig_banner(f_c_begin);
-
- Swig_obligatory_macros(f_c_runtime, "GO");
-
- if (CPlusPlus) {
- Printf(f_c_begin, "\n// source: %s\n\n", swig_filename);
- } else {
- Printf(f_c_begin, "\n/* source: %s */\n\n", swig_filename);
- }
-
- Printf(f_c_runtime, "#define SWIGMODULE %s\n", module);
-
- if (gccgo_flag) {
- Printf(f_c_runtime, "#define SWIGGO_PREFIX %s\n", go_prefix);
- }
-
- if (directorsEnabled()) {
- Printf(f_c_runtime, "#define SWIG_DIRECTORS\n");
-
- Swig_banner(f_c_directors_h);
- Printf(f_c_directors_h, "\n// source: %s\n\n", swig_filename);
-
- Printf(f_c_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module);
- Printf(f_c_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module);
- Printf(f_c_directors_h, "class Swig_memory;\n\n");
-
- Printf(f_c_directors, "\n// C++ director class methods.\n");
- String *filename = Swig_file_filename(c_filename_h);
- Printf(f_c_directors, "#include \"%s\"\n\n", filename);
- Delete(filename);
- }
-
- Swig_banner(f_go_begin);
- Printf(f_go_begin, "\n// source: %s\n", swig_filename);
-
- Printv(f_cgo_comment_typedefs, "/*\n", NULL);
-
- // The cgo program defines the intgo type after our function
- // definitions, but we want those definitions to be able to use
- // intgo also.
- Printv(f_cgo_comment_typedefs, "#define intgo swig_intgo\n", NULL);
- Printv(f_cgo_comment_typedefs, "typedef void *swig_voidp;\n", NULL);
-
- // Output module initialization code.
-
- Printf(f_go_begin, "\npackage %s\n\n", getModuleName(package));
-
- // All the C++ wrappers should be extern "C".
-
- Printv(f_c_wrappers, "#ifdef __cplusplus\n", "extern \"C\" {\n", "#endif\n\n", NULL);
-
- // Set up the hash table for types not defined by SWIG.
-
- undefined_enum_types = NewHash();
- undefined_types = NewHash();
- defined_types = NewHash();
- go_imports = NewHash();
-
- // Emit code.
-
- Language::top(n);
-
- if (directorsEnabled()) {
- // Insert director runtime into the f_runtime file (make it occur before %header section)
- Swig_insert_file("director_common.swg", f_c_runtime);
- Swig_insert_file("director.swg", f_c_runtime);
- }
-
- Delete(go_imports);
-
- // Write out definitions for the types not defined by SWIG.
-
- if (Len(undefined_enum_types) > 0)
- Printv(f_go_wrappers, "\n", NULL);
- for (Iterator p = First(undefined_enum_types); p.key; p = Next(p)) {
- String *name = p.item;
- Printv(f_go_wrappers, "type ", name, " int\n", NULL);
- }
-
- Printv(f_go_wrappers, "\n", NULL);
- for (Iterator p = First(undefined_types); p.key; p = Next(p)) {
- String *ty = goType(NULL, p.key);
- if (!Getattr(defined_types, ty)) {
- String *cp = goCPointerType(p.key, false);
- if (!Getattr(defined_types, cp)) {
- Printv(f_go_wrappers, "type ", cp, " uintptr\n", NULL);
- Printv(f_go_wrappers, "type ", ty, " interface {\n", NULL);
- Printv(f_go_wrappers, "\tSwigcptr() uintptr;\n", NULL);
- Printv(f_go_wrappers, "}\n", NULL);
- Printv(f_go_wrappers, "func (p ", cp, ") Swigcptr() uintptr {\n", NULL);
- Printv(f_go_wrappers, "\treturn uintptr(p)\n", NULL);
- Printv(f_go_wrappers, "}\n\n", NULL);
- }
- Delete(cp);
- }
- Delete(ty);
- }
- Delete(undefined_enum_types);
- Delete(undefined_types);
- Delete(defined_types);
-
- /* Write and cleanup */
-
- Dump(f_c_header, f_c_runtime);
-
- if (directorsEnabled()) {
- Printf(f_c_directors_h, "#endif\n");
- Delete(f_c_directors_h);
- f_c_directors_h = NULL;
-
- Dump(f_c_directors, f_c_runtime);
- Delete(f_c_directors);
- f_c_directors = NULL;
- }
-
- // End the extern "C".
- Printv(f_c_wrappers, "#ifdef __cplusplus\n", "}\n", "#endif\n\n", NULL);
-
- // End the cgo comment.
- Printv(f_cgo_comment, "#undef intgo\n", NULL);
- Printv(f_cgo_comment, "*/\n", NULL);
- Printv(f_cgo_comment, "import \"C\"\n", NULL);
- Printv(f_cgo_comment, "\n", NULL);
-
- bool need_panic = false;
- if (Strstr(f_c_runtime, "SWIG_contract_assert(") != 0 || Strstr(f_c_wrappers, "SWIG_contract_assert(") != 0) {
- Printv(f_c_begin, "\n#define SWIG_contract_assert(expr, msg) if (!(expr)) { _swig_gopanic(msg); } else\n\n", NULL);
- need_panic = true;
- }
-
- if (!gccgo_flag && (need_panic || Strstr(f_c_runtime, "_swig_gopanic") != 0 || Strstr(f_c_wrappers, "_swig_gopanic") != 0)) {
- Printv(f_go_header, "//export cgo_panic_", unique_id, "\n", NULL);
- Printv(f_go_header, "func cgo_panic_", unique_id, "(p *byte) {\n", NULL);
- Printv(f_go_header, "\ts := (*[1024]byte)(unsafe.Pointer(p))[:]\n", NULL);
- Printv(f_go_header, "\tfor i, b := range s {\n", NULL);
- Printv(f_go_header, "\t\tif b == 0 {\n", NULL);
- Printv(f_go_header, "\t\t\tpanic(string(s[:i]))\n", NULL);
- Printv(f_go_header, "\t\t}\n", NULL);
- Printv(f_go_header, "\t}\n", NULL);
- Printv(f_go_header, "\tpanic(string(s))\n", NULL);
- Printv(f_go_header, "}\n\n", NULL);
-
- Printv(f_c_begin, "\nextern\n", NULL);
- Printv(f_c_begin, "#ifdef __cplusplus\n", NULL);
- Printv(f_c_begin, " \"C\"\n", NULL);
- Printv(f_c_begin, "#endif\n", NULL);
- Printv(f_c_begin, " void cgo_panic_", unique_id, "(const char*);\n", NULL);
- Printv(f_c_begin, "static void _swig_gopanic(const char *p) {\n", NULL);
- Printv(f_c_begin, " cgo_panic_", unique_id, "(p);\n", NULL);
- Printv(f_c_begin, "}\n\n", NULL);
- }
-
- Dump(f_c_runtime, f_c_begin);
- Dump(f_c_wrappers, f_c_begin);
- Dump(f_c_init, f_c_begin);
- Dump(f_cgo_comment_typedefs, f_go_begin);
- Dump(f_cgo_comment, f_go_begin);
- Dump(f_go_imports, f_go_begin);
- Dump(f_go_header, f_go_begin);
- Dump(f_go_runtime, f_go_begin);
- Dump(f_go_wrappers, f_go_begin);
- if (directorsEnabled()) {
- Dump(f_go_directors, f_go_begin);
- }
- Delete(f_c_runtime);
- Delete(f_c_header);
- Delete(f_c_wrappers);
- Delete(f_c_init);
- Delete(f_go_imports);
- Delete(f_go_runtime);
- Delete(f_go_header);
- Delete(f_go_wrappers);
- Delete(f_go_directors);
- Delete(f_cgo_comment);
- Delete(f_cgo_comment_typedefs);
- Delete(f_c_begin);
- Delete(f_go_begin);
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * importDirective()
- *
- * Handle a SWIG import statement by generating a Go import
- * statement.
- * ------------------------------------------------------------ */
-
- virtual int importDirective(Node *n) {
- String *hold_import = imported_package;
- String *modname = Getattr(n, "module");
- if (modname) {
- if (!Getattr(go_imports, modname)) {
- Setattr(go_imports, modname, modname);
- Printv(f_go_imports, "import \"", NULL);
- if (import_prefix) {
- Printv(f_go_imports, import_prefix, "/", NULL);
- }
- Printv(f_go_imports, modname, "\"\n", NULL);
- }
- imported_package = modname;
- saw_import = true;
- }
- int r = Language::importDirective(n);
- imported_package = hold_import;
- return r;
- }
-
- /* ----------------------------------------------------------------------
- * Language::insertDirective()
- *
- * If the section is go_imports, store them for later.
- * ---------------------------------------------------------------------- */
- virtual int insertDirective(Node *n) {
- char *section = Char(Getattr(n, "section"));
- if ((ImportMode && !Getattr(n, "generated")) ||
- !section || (strcmp(section, "go_imports") != 0)) {
- return Language::insertDirective(n);
- }
-
- char *code = Char(Getattr(n, "code"));
- char *pch = strtok(code, ",");
- while (pch != NULL) {
- // Do not import same thing more than once.
- if (!Getattr(go_imports, pch)) {
- Setattr(go_imports, pch, pch);
- Printv(f_go_imports, "import ", pch, "\n", NULL);
- }
- pch = strtok(NULL, ",");
- }
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * functionWrapper()
- *
- * Implement a function.
- * ---------------------------------------------------------------------- */
-
- virtual int functionWrapper(Node *n) {
- if (GetFlag(n, "feature:ignore")) {
- return SWIG_OK;
- }
-
- // We don't need explicit calls.
- if (GetFlag(n, "explicitcall")) {
- return SWIG_OK;
- }
-
- // Don't emit constructors for abstract director classes. They
- // will never succeed anyhow.
- if (Swig_methodclass(n) && Swig_directorclass(n)
- && Strcmp(Char(Getattr(n, "wrap:action")), director_prot_ctor_code) == 0) {
- return SWIG_OK;
- }
-
- String *name = Getattr(n, "sym:name");
- String *nodetype = Getattr(n, "nodeType");
- bool is_static = is_static_member_function || isStatic(n);
- bool is_friend = isFriend(n);
- bool is_ctor_dtor = false;
-
- SwigType *result = Getattr(n, "type");
-
- // For some reason SWIG changs the "type" value during the call to
- // functionWrapper. We need to remember the type for possible
- // overload processing.
- Setattr(n, "go:type", Copy(result));
-
- String *go_name;
-
- String *r1 = NULL;
- if (making_variable_wrappers) {
- // Change the name of the variable setter and getter functions
- // to be more Go like.
-
- bool is_set = Strcmp(Char(name) + Len(name) - 4, "_set") == 0;
- assert(is_set || Strcmp(Char(name) + Len(name) - 4, "_get") == 0);
-
- // Start with Set or Get.
- go_name = NewString(is_set ? "Set" : "Get");
-
- // If this is a static variable, put in the class name,
- // capitalized.
- if (is_static && class_name) {
- String *ccn = exportedName(class_name);
- Append(go_name, ccn);
- Delete(ccn);
- }
-
- // Add the rest of the name, capitalized, dropping the _set or
- // _get.
- String *c1 = removeClassname(name);
- String *c2 = exportedName(c1);
- char *p = Char(c2);
- int len = Len(p);
- for (int i = 0; i < len - 4; ++i) {
- Putc(p[i], go_name);
- }
- Delete(c2);
- Delete(c1);
-
- if (!checkIgnoredParameters(n, go_name)) {
- Delete(go_name);
- return SWIG_NOWRAP;
- }
- } else if (Cmp(nodetype, "constructor") == 0) {
- is_ctor_dtor = true;
-
- // Change the name of a constructor to be more Go like. Change
- // new_ to New, and capitalize the class name.
- assert(Strncmp(name, "new_", 4) == 0);
- String *c1 = NewString(Char(name) + 4);
- String *c2 = exportedName(c1);
- go_name = NewString("New");
- Append(go_name, c2);
- Delete(c2);
- Delete(c1);
-
- if (Swig_methodclass(n) && Swig_directorclass(n)) {
- // The core SWIG code skips the first parameter when
- // generating the $nondirector_new string. Recreate the
- // action in this case. But don't it if we are using the
- // special code for an abstract class.
- String *call = Swig_cppconstructor_call(getClassType(),
- Getattr(n, "parms"));
- SwigType *type = Copy(getClassType());
- SwigType_add_pointer(type);
- String *cres = Swig_cresult(type, Swig_cresult_name(), call);
- Setattr(n, "wrap:action", cres);
- }
- } else if (Cmp(nodetype, "destructor") == 0) {
- // No need to emit protected destructors.
- if (!is_public(n)) {
- return SWIG_OK;
- }
-
- is_ctor_dtor = true;
-
- // Change the name of a destructor to be more Go like. Change
- // delete_ to Delete and capitalize the class name.
- assert(Strncmp(name, "delete_", 7) == 0);
- String *c1 = NewString(Char(name) + 7);
- String *c2 = exportedName(c1);
- go_name = NewString("Delete");
- Append(go_name, c2);
- Delete(c2);
- Delete(c1);
-
- result = NewString("void");
- r1 = result;
- } else {
- if (!checkFunctionVisibility(n, NULL)) {
- return SWIG_OK;
- }
-
- go_name = buildGoName(name, is_static, is_friend);
-
- if (!checkIgnoredParameters(n, go_name)) {
- Delete(go_name);
- return SWIG_NOWRAP;
- }
- }
-
- String *overname = NULL;
- if (Getattr(n, "sym:overloaded")) {
- overname = Getattr(n, "sym:overname");
- } else {
- String *scope;
- if (!class_name || is_static || is_ctor_dtor) {
- scope = NULL;
- } else {
- scope = NewString("swiggoscope.");
- Append(scope, class_name);
- }
- if (!checkNameConflict(go_name, n, scope)) {
- Delete(go_name);
- return SWIG_NOWRAP;
- }
- }
-
- String *wname = Swig_name_wrapper(name);
- if (overname) {
- Append(wname, overname);
- }
- Append(wname, unique_id);
- Setattr(n, "wrap:name", wname);
-
- ParmList *parms = Getattr(n, "parms");
- Setattr(n, "wrap:parms", parms);
-
- int r = makeWrappers(n, go_name, overname, wname, NULL, parms, result, is_static);
- if (r != SWIG_OK) {
- return r;
- }
-
- if (Getattr(n, "sym:overloaded") && !Getattr(n, "sym:nextSibling")) {
- String *scope ;
- if (!class_name || is_static || is_ctor_dtor) {
- scope = NULL;
- } else {
- scope = NewString("swiggoscope.");
- Append(scope, class_name);
- }
- if (!checkNameConflict(go_name, n, scope)) {
- Delete(go_name);
- return SWIG_NOWRAP;
- }
-
- String *receiver = class_receiver;
- if (is_static || is_ctor_dtor) {
- receiver = NULL;
- }
- r = makeDispatchFunction(n, go_name, receiver, is_static, NULL, false);
- if (r != SWIG_OK) {
- return r;
- }
- }
-
- Delete(wname);
- Delete(go_name);
- Delete(r1);
-
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * staticmemberfunctionHandler()
- *
- * For some reason the language code removes the "storage" attribute
- * for a static function before calling functionWrapper, which means
- * that we have no way of knowing whether a function is static or
- * not. That makes no sense in the Go context. Here we note that a
- * function is static.
- * ---------------------------------------------------------------------- */
-
- int staticmemberfunctionHandler(Node *n) {
- assert(!is_static_member_function);
- is_static_member_function = true;
- int r = Language::staticmemberfunctionHandler(n);
- is_static_member_function = false;
- return r;
- }
-
- /* ----------------------------------------------------------------------
- * makeWrappers()
- *
- * Write out the various function wrappers.
- * n: The function we are emitting.
- * go_name: The name of the function in Go.
- * overname: The overload string for overloaded function.
- * wname: The SWIG wrapped name--the name of the C function.
- * base: A list of the names of base classes, in the case where this
- * is a virtual method not defined in the current class.
- * parms: The parameters.
- * result: The result type.
- * is_static: Whether this is a static method or member.
- * ---------------------------------------------------------------------- */
-
- int makeWrappers(Node *n, String *go_name, String *overname, String *wname, List *base, ParmList *parms, SwigType *result, bool is_static) {
-
- assert(result);
-
- int ret = SWIG_OK;
-
- int r = makeCgoWrappers(n, go_name, overname, wname, base, parms, result, is_static);
- if (r != SWIG_OK) {
- ret = r;
- }
-
- if (class_methods) {
- Setattr(class_methods, Getattr(n, "name"), NewString(""));
- }
-
- return ret;
- }
-
- /* ----------------------------------------------------------------------
- * struct cgoWrapperInfo
- *
- * Information needed by the CGO wrapper functions.
- * ---------------------------------------------------------------------- */
-
- struct cgoWrapperInfo {
- // The function we are generating code for.
- Node *n;
- // The name of the Go function.
- String *go_name;
- // The overload string for an overloaded function.
- String *overname;
- // The name of the C wrapper function.
- String *wname;
- // The base classes.
- List *base;
- // The parameters.
- ParmList *parms;
- // The result type.
- SwigType *result;
- // Whether this is a static function, not a class method.
- bool is_static;
- // The Go receiver type.
- String *receiver;
- // Whether this is a class constructor.
- bool is_constructor;
- // Whether this is a class destructor.
- bool is_destructor;
- };
-
- /* ----------------------------------------------------------------------
- * makeCgoWrappers()
- *
- * Write out the wrappers for a function when producing cgo input
- * files.
- * ---------------------------------------------------------------------- */
-
- int makeCgoWrappers(Node *n, String *go_name, String *overname, String *wname, List *base, ParmList *parms, SwigType *result, bool is_static) {
- Swig_save("makeCgoWrappers", n, "emit:cgotype", "emit:cgotypestruct", NULL);
-
- cgoWrapperInfo info;
-
- info.n = n;
- info.go_name = go_name;
- info.overname = overname;
- info.wname = wname;
- info.base = base;
- info.parms = parms;
- info.result = result;
- info.is_static = is_static;
-
- info.receiver = class_receiver;
- if (is_static) {
- info.receiver = NULL;
- }
-
- String *nodetype = Getattr(n, "nodeType");
- info.is_constructor = Cmp(nodetype, "constructor") == 0;
- info.is_destructor = Cmp(nodetype, "destructor") == 0;
- if (info.is_constructor || info.is_destructor) {
- assert(class_receiver);
- assert(!base);
- info.receiver = NULL;
- }
-
- int ret = SWIG_OK;
-
- int r = cgoGoWrapper(&info);
- if (r != SWIG_OK) {
- ret = r;
- }
-
- r = cgoCommentWrapper(&info);
- if (r != SWIG_OK) {
- ret = r;
- }
-
- r = cgoGccWrapper(&info);
- if (r != SWIG_OK) {
- ret = r;
- }
-
- Swig_restore(n);
-
- return ret;
- }
-
- /* ----------------------------------------------------------------------
- * cgoGoWrapper()
- *
- * Write out Go code to call a cgo function. This code will go into
- * the generated Go output file.
- * ---------------------------------------------------------------------- */
- int cgoGoWrapper(const cgoWrapperInfo *info) {
-
- Wrapper *dummy = initGoTypemaps(info->parms);
-
- bool add_to_interface = interfaces && !info->is_constructor && !info->is_destructor && !info->is_static && !info->overname && checkFunctionVisibility(info->n, NULL);
-
- Printv(f_go_wrappers, "func ", NULL);
-
- Parm *p = info->parms;
- int pi = 0;
-
- // Add the receiver first if this is a method.
- if (info->receiver) {
- Printv(f_go_wrappers, "(", NULL);
- if (info->base && info->receiver) {
- Printv(f_go_wrappers, "_swig_base", NULL);
- } else {
- Printv(f_go_wrappers, Getattr(p, "lname"), NULL);
- p = nextParm(p);
- ++pi;
- }
- Printv(f_go_wrappers, " ", info->receiver, ") ", NULL);
- }
-
- Printv(f_go_wrappers, info->go_name, NULL);
- if (info->overname) {
- Printv(f_go_wrappers, info->overname, NULL);
- }
- Printv(f_go_wrappers, "(", NULL);
-
- // If we are doing methods, add this method to the interface.
- if (add_to_interface) {
- Printv(interfaces, "\t", info->go_name, "(", NULL);
- }
-
- // Write out the parameters to both the function definition and
- // the interface.
-
- String *parm_print = NewString("");
-
- int parm_count = emit_num_arguments(info->parms);
- int required_count = emit_num_required(info->parms);
- int args = 0;
-
- for (; pi < parm_count; ++pi) {
- p = getParm(p);
- if (pi == 0 && info->is_destructor) {
- String *cl = exportedName(class_name);
- Printv(parm_print, Getattr(p, "lname"), " ", cl, NULL);
- Delete(cl);
- ++args;
- } else {
- if (args > 0) {
- Printv(parm_print, ", ", NULL);
- }
- ++args;
- if (pi >= required_count) {
- Printv(parm_print, "_swig_args ...interface{}", NULL);
- break;
- }
- Printv(parm_print, Getattr(p, "lname"), " ", NULL);
- String *tm = goType(p, Getattr(p, "type"));
- Printv(parm_print, tm, NULL);
- Delete(tm);
- }
- p = nextParm(p);
- }
-
- Printv(parm_print, ")", NULL);
-
- // Write out the result type.
- if (info->is_constructor) {
- String *cl = exportedName(class_name);
- Printv(parm_print, " (_swig_ret ", cl, ")", NULL);
- Delete(cl);
- } else {
- if (SwigType_type(info->result) != T_VOID) {
- String *tm = goType(info->n, info->result);
- Printv(parm_print, " (_swig_ret ", tm, ")", NULL);
- Delete(tm);
- }
- }
-
- Printv(f_go_wrappers, parm_print, NULL);
- if (add_to_interface) {
- Printv(interfaces, parm_print, "\n", NULL);
- }
-
- // Write out the function body.
-
- Printv(f_go_wrappers, " {\n", NULL);
-
- if (parm_count > required_count) {
- Parm *p = info->parms;
- int i;
- for (i = 0; i < required_count; ++i) {
- p = getParm(p);
- p = nextParm(p);
- }
- for (; i < parm_count; ++i) {
- p = getParm(p);
- String *tm = goType(p, Getattr(p, "type"));
- Printv(f_go_wrappers, "\tvar ", Getattr(p, "lname"), " ", tm, "\n", NULL);
- Printf(f_go_wrappers, "\tif len(_swig_args) > %d {\n", i - required_count);
- Printf(f_go_wrappers, "\t\t%s = _swig_args[%d].(%s)\n", Getattr(p, "lname"), i - required_count, tm);
- Printv(f_go_wrappers, "\t}\n", NULL);
- Delete(tm);
- p = nextParm(p);
- }
- }
-
- String *call = NewString("\t");
-
- String *ret_type = NULL;
- bool memcpy_ret = false;
- String *wt = NULL;
- if (SwigType_type(info->result) != T_VOID) {
- if (info->is_constructor) {
- ret_type = exportedName(class_name);
- } else {
- ret_type = goImType(info->n, info->result);
- }
- Printv(f_go_wrappers, "\tvar swig_r ", ret_type, "\n", NULL);
-
- bool c_struct_type;
- Delete(cgoTypeForGoValue(info->n, info->result, &c_struct_type));
- if (c_struct_type) {
- memcpy_ret = true;
- }
-
- if (memcpy_ret) {
- Printv(call, "swig_r_p := ", NULL);
- } else {
- Printv(call, "swig_r = (", ret_type, ")(", NULL);
- }
-
- if (info->is_constructor || goTypeIsInterface(info->n, info->result)) {
- if (info->is_constructor) {
- wt = Copy(class_receiver);
- } else {
- wt = goWrapperType(info->n, info->result, true);
- }
- Printv(call, wt, "(", NULL);
- }
- }
-
- Printv(call, "C.", info->wname, "(", NULL);
-
- args = 0;
-
- if (parm_count > required_count) {
- Printv(call, "C.swig_intgo(len(_swig_args))", NULL);
- ++args;
- }
-
- if (info->base && info->receiver) {
- if (args > 0) {
- Printv(call, ", ", NULL);
- }
- ++args;
- Printv(call, "C.uintptr_t(_swig_base)", NULL);
- }
-
- p = info->parms;
- for (int i = 0; i < parm_count; ++i) {
- p = getParm(p);
- if (args > 0) {
- Printv(call, ", ", NULL);
- }
- ++args;
-
- SwigType *pt = Getattr(p, "type");
- String *ln = Getattr(p, "lname");
-
- String *ivar = NewStringf("_swig_i_%d", i);
-
- String *goin = goGetattr(p, "tmap:goin");
- if (goin == NULL) {
- Printv(f_go_wrappers, "\t", ivar, " := ", NULL);
- bool need_close = false;
- if ((i == 0 && info->is_destructor) || ((i > 0 || !info->receiver || info->base || info->is_constructor) && goTypeIsInterface(p, pt))) {
- Printv(f_go_wrappers, "getSwigcptr(", NULL);
- need_close = true;
- }
- Printv(f_go_wrappers, ln, NULL);
- if (need_close) {
- Printv(f_go_wrappers, ")", NULL);
- }
- Printv(f_go_wrappers, "\n", NULL);
- Setattr(p, "emit:goinput", ln);
- } else {
- String *itm = goImType(p, pt);
- Printv(f_go_wrappers, "\tvar ", ivar, " ", itm, "\n", NULL);
- goin = Copy(goin);
- Replaceall(goin, "$input", ln);
- Replaceall(goin, "$result", ivar);
- Printv(f_go_wrappers, goin, "\n", NULL);
- Delete(goin);
- Setattr(p, "emit:goinput", ivar);
- }
-
- bool c_struct_type;
- String *ct = cgoTypeForGoValue(p, pt, &c_struct_type);
- if (c_struct_type) {
- Printv(call, "*(*C.", ct, ")(unsafe.Pointer(&", ivar, "))", NULL);
- } else {
- Printv(call, "C.", ct, "(", ivar, ")", NULL);
- }
- Delete(ct);
-
- p = nextParm(p);
- }
-
- Printv(f_go_wrappers, call, ")", NULL);
- Delete(call);
-
- if (wt) {
- // Close the type conversion to the wrapper type.
- Printv(f_go_wrappers, ")", NULL);
- }
- if (SwigType_type(info->result) != T_VOID && !memcpy_ret) {
- // Close the type conversion of the return value.
- Printv(f_go_wrappers, ")", NULL);
- }
-
- Printv(f_go_wrappers, "\n", NULL);
-
- if (memcpy_ret) {
- Printv(f_go_wrappers, "\tswig_r = *(*", ret_type, ")(unsafe.Pointer(&swig_r_p))\n", NULL);
- }
- if (ret_type) {
- Delete(ret_type);
- }
-
- goargout(info->parms);
-
- if (SwigType_type(info->result) != T_VOID) {
-
- Swig_save("cgoGoWrapper", info->n, "type", "tmap:goout", NULL);
- Setattr(info->n, "type", info->result);
-
- String *goout = goTypemapLookup("goout", info->n, "swig_r");
- if (goout == NULL) {
- Printv(f_go_wrappers, "\treturn swig_r\n", NULL);
- } else {
- String *tm = goType(info->n, info->result);
- Printv(f_go_wrappers, "\tvar swig_r_1 ", tm, "\n", NULL);
- goout = Copy(goout);
- Replaceall(goout, "$input", "swig_r");
- Replaceall(goout, "$result", "swig_r_1");
- Printv(f_go_wrappers, goout, "\n", NULL);
- Printv(f_go_wrappers, "\treturn swig_r_1\n", NULL);
- }
-
- Swig_restore(info->n);
- }
-
- Printv(f_go_wrappers, "}\n\n", NULL);
-
- DelWrapper(dummy);
-
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * cgoCommentWrapper()
- *
- * Write out a cgo function to call a C/C++ function. This code
- * will go into the cgo comment in the generated Go output file.
- * ---------------------------------------------------------------------- */
- int cgoCommentWrapper(const cgoWrapperInfo *info) {
- String *ret_type;
- if (SwigType_type(info->result) == T_VOID) {
- ret_type = NewString("void");
- } else {
- bool c_struct_type;
- ret_type = cgoTypeForGoValue(info->n, info->result, &c_struct_type);
- }
-
- Printv(f_cgo_comment, "extern ", ret_type, " ", info->wname, "(", NULL);
-
- Delete(ret_type);
-
- int parm_count = emit_num_arguments(info->parms);
- int required_count = emit_num_required(info->parms);
- int args = 0;
-
- if (parm_count > required_count) {
- Printv(f_cgo_comment, "intgo _swig_args", NULL);
- ++args;
- }
-
- if (info->base && info->receiver) {
- if (args > 0) {
- Printv(f_cgo_comment, ", ", NULL);
- }
- ++args;
- Printv(f_cgo_comment, "uintptr_t _swig_base", NULL);
- }
-
- Parm *p = info->parms;
- for (int i = 0; i < parm_count; ++i) {
- p = getParm(p);
- if (args > 0) {
- Printv(f_cgo_comment, ", ", NULL);
- }
- ++args;
-
- SwigType *pt = Getattr(p, "type");
- String *ln = Getattr(p, "lname");
-
- bool c_struct_type;
- String *ct = cgoTypeForGoValue(p, pt, &c_struct_type);
- Printv(f_cgo_comment, ct, " ", ln, NULL);
- Delete(ct);
-
- p = nextParm(p);
- }
-
- if (args == 0) {
- Printv(f_cgo_comment, "void", NULL);
- }
-
- Printv(f_cgo_comment, ");\n", NULL);
-
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * cgoGccWrapper()
- *
- * Write out code to the C/C++ wrapper file. This code will be
- * called by the code generated by cgoCommentWrapper.
- * ---------------------------------------------------------------------- */
- int cgoGccWrapper(const cgoWrapperInfo *info) {
- Wrapper *f = NewWrapper();
-
- Swig_save("cgoGccWrapper", info->n, "parms", NULL);
-
- ParmList *parms = info->parms;
-
- Parm *base_parm = NULL;
- if (info->base && !isStatic(info->n)) {
- SwigType *base_type = Copy(getClassType());
- SwigType_add_pointer(base_type);
- base_parm = NewParm(base_type, NewString("arg1"), info->n);
- set_nextSibling(base_parm, parms);
- parms = base_parm;
- }
-
- emit_parameter_variables(parms, f);
- emit_attach_parmmaps(parms, f);
- int parm_count = emit_num_arguments(parms);
- int required_count = emit_num_required(parms);
-
- emit_return_variable(info->n, info->result, f);
-
- // Start the function definition.
-
- String *fnname = NewString("");
- Printv(fnname, info->wname, "(", NULL);
-
- int args = 0;
-
- if (parm_count > required_count) {
- Printv(fnname, "intgo _swig_optargc", NULL);
- ++args;
- }
-
- Parm *p = parms;
- for (int i = 0; i < parm_count; ++i) {
- if (args > 0) {
- Printv(fnname, ", ", NULL);
- }
- ++args;
-
- p = getParm(p);
-
- SwigType *pt = Copy(Getattr(p, "type"));
- if (SwigType_isarray(pt) && Getattr(p, "tmap:gotype") == NULL) {
- SwigType_del_array(pt);
- SwigType_add_pointer(pt);
- }
- String *pn = NewStringf("_swig_go_%d", i);
- String *ct = gcCTypeForGoValue(p, pt, pn);
- Printv(fnname, ct, NULL);
- Delete(ct);
- Delete(pn);
- Delete(pt);
-
- p = nextParm(p);
- }
-
- Printv(fnname, ")", NULL);
-
- if (SwigType_type(info->result) == T_VOID) {
- Printv(f->def, "void ", fnname, NULL);
- } else {
- String *ct = gcCTypeForGoValue(info->n, info->result, fnname);
- Printv(f->def, ct, NULL);
- Delete(ct);
-
- String *ln = NewString("_swig_go_result");
- ct = gcCTypeForGoValue(info->n, info->result, ln);
- Wrapper_add_local(f, "_swig_go_result", ct);
- Delete(ct);
- Delete(ln);
- }
-
- Delete(fnname);
-
- Printv(f->def, " {\n", NULL);
-
- // Apply the in typemaps.
-
- p = parms;
- for (int i = 0; i < parm_count; ++i) {
- p = getParm(p);
- String *tm = Getattr(p, "tmap:in");
- if (!tm) {
- Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "unable to use type %s as a function argument\n", SwigType_str(Getattr(p, "type"), 0));
- } else {
- tm = Copy(tm);
- String *pn = NewStringf("_swig_go_%d", i);
- Replaceall(tm, "$input", pn);
- if (i < required_count) {
- Printv(f->code, "\t", tm, "\n", NULL);
- } else {
- Printf(f->code, "\tif (_swig_optargc > %d) {\n", i - required_count);
- Printv(f->code, "\t\t", tm, "\n", NULL);
- Printv(f->code, "\t}\n", NULL);
- }
- Delete(tm);
- Setattr(p, "emit:input", pn);
- }
- p = nextParm(p);
- }
-
- Printv(f->code, "\n", NULL);
-
- // Do the real work of the function.
-
- checkConstraints(parms, f);
-
- emitGoAction(info->n, info->base, parms, info->result, f);
-
- argout(parms, f);
-
- cleanupFunction(info->n, f, parms);
-
- if (SwigType_type(info->result) != T_VOID) {
- Printv(f->code, "\treturn _swig_go_result;\n", NULL);
- }
-
- Printv(f->code, "}\n", NULL);
-
- Wrapper_print(f, f_c_wrappers);
-
- Swig_restore(info->n);
-
- DelWrapper(f);
- if (base_parm) {
- Delete(base_parm);
- }
-
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * initGoTypemaps()
- *
- * Initialize the typenames for a Go wrapper, returning a dummy
- * Wrapper*. Also set consistent names for the parameters.
- * ---------------------------------------------------------------------- */
-
- Wrapper* initGoTypemaps(ParmList *parms) {
- Wrapper *dummy = NewWrapper();
- emit_attach_parmmaps(parms, dummy);
-
- Parm *p = parms;
- int parm_count = emit_num_arguments(parms);
- for (int i = 0; i < parm_count; ++i) {
- p = getParm(p);
- Swig_cparm_name(p, i);
- p = nextParm(p);
- }
-
- Swig_typemap_attach_parms("default", parms, dummy);
- Swig_typemap_attach_parms("gotype", parms, dummy);
- Swig_typemap_attach_parms("goin", parms, dummy);
- Swig_typemap_attach_parms("goargout", parms, dummy);
- Swig_typemap_attach_parms("imtype", parms, dummy);
-
- return dummy;
- }
-
- /* -----------------------------------------------------------------------
- * checkConstraints()
- *
- * Check parameter constraints if any. This is used for the C/C++
- * function. This assumes that each parameter has an "emit:input"
- * property with the name to use to refer to that parameter.
- * ----------------------------------------------------------------------- */
-
- void checkConstraints(ParmList *parms, Wrapper *f) {
- Parm *p = parms;
- while (p) {
- String *tm = Getattr(p, "tmap:check");
- if (!tm) {
- p = nextSibling(p);
- } else {
- tm = Copy(tm);
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(f->code, tm, "\n\n", NULL);
- Delete(tm);
- p = Getattr(p, "tmap:check:next");
- }
- }
- }
-
- /* -----------------------------------------------------------------------
- * emitGoAction()
- *
- * Emit the action of the function. This is used for the C/C++ function.
- * ----------------------------------------------------------------------- */
-
- void emitGoAction(Node *n, List *base, ParmList *parms, SwigType *result, Wrapper *f) {
- String *actioncode;
- if (!base || isStatic(n)) {
- Swig_director_emit_dynamic_cast(n, f);
- actioncode = emit_action(n);
- } else {
- // Call the base class method.
- actioncode = NewString("");
-
- String *current = NewString("");
- Printv(current, Getattr(parms, "lname"), NULL);
-
- int vc = 0;
- for (Iterator bi = First(base); bi.item; bi = Next(bi)) {
- Printf(actioncode, " %s *swig_b%d = (%s *)%s;\n", bi.item, vc, bi.item, current);
- Delete(current);
- current = NewString("");
- Printf(current, "swig_b%d", vc);
- ++vc;
- }
-
- String *code = Copy(Getattr(n, "wrap:action"));
- Replace(code, Getattr(parms, "lname"), current, DOH_REPLACE_ANY | DOH_REPLACE_ID);
- Delete(current);
- Printv(actioncode, code, "\n", NULL);
- }
-
- Swig_save("emitGoAction", n, "type", "tmap:out", NULL);
-
- Setattr(n, "type", result);
-
- String *tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode);
- if (!tm) {
- Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s\n", SwigType_str(result, 0));
- } else {
- Replaceall(tm, "$result", "_swig_go_result");
- if (GetFlag(n, "feature:new")) {
- Replaceall(tm, "$owner", "1");
- } else {
- Replaceall(tm, "$owner", "0");
- }
- Printv(f->code, tm, "\n", NULL);
- Delete(tm);
- }
-
- Swig_restore(n);
- }
-
- /* -----------------------------------------------------------------------
- * argout()
- *
- * Handle argument output code if any. This is used for the C/C++
- * function. This assumes that each parameter has an "emit:input"
- * property with the name to use to refer to that parameter.
- * ----------------------------------------------------------------------- */
-
- void argout(ParmList *parms, Wrapper *f) {
- Parm *p = parms;
- while (p) {
- String *tm = Getattr(p, "tmap:argout");
- if (!tm) {
- p = nextSibling(p);
- } else {
- tm = Copy(tm);
- Replaceall(tm, "$result", Swig_cresult_name());
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(f->code, tm, "\n", NULL);
- Delete(tm);
- p = Getattr(p, "tmap:argout:next");
- }
- }
- }
-
- /* -----------------------------------------------------------------------
- * goargout()
- *
- * Handle Go argument output code if any. This is used for the Go
- * function. This assumes that each parameter has an "emit:goinput"
- * property with the name to use to refer to that parameter.
- * ----------------------------------------------------------------------- */
-
- void goargout(ParmList *parms) {
- Parm *p = parms;
- while (p) {
- String *tm = Getattr(p, "tmap:goargout");
- if (!tm) {
- p = nextSibling(p);
- } else {
- tm = Copy(tm);
- Replaceall(tm, "$result", "swig_r");
- Replaceall(tm, "$input", Getattr(p, "emit:goinput"));
- Printv(f_go_wrappers, tm, "\n", NULL);
- Delete(tm);
- p = Getattr(p, "tmap:goargout:next");
- }
- }
-
- // If we need to memcpy a parameter to pass it to the C code, the
- // compiler may think that the parameter is not live during the
- // function call. If the garbage collector runs while the C/C++
- // function is running, the parameter may be freed. Force the
- // compiler to see the parameter as live across the C/C++ function.
- int parm_count = emit_num_arguments(parms);
- p = parms;
- for (int i = 0; i < parm_count; ++i) {
- p = getParm(p);
- bool c_struct_type;
- Delete(cgoTypeForGoValue(p, Getattr(p, "type"), &c_struct_type));
- if (c_struct_type) {
- Printv(f_go_wrappers, "\tif Swig_escape_always_false {\n", NULL);
- Printv(f_go_wrappers, "\t\tSwig_escape_val = ", Getattr(p, "emit:goinput"), "\n", NULL);
- Printv(f_go_wrappers, "\t}\n", NULL);
- }
- p = nextParm(p);
- }
- }
-
- /* -----------------------------------------------------------------------
- * freearg()
- *
- * Handle argument cleanup code if any. This is used for the C/C++
- * function. This assumes that each parameter has an "emit:input"
- * property with the name to use to refer to that parameter.
- * ----------------------------------------------------------------------- */
-
- String *freearg(ParmList *parms) {
- String *ret = NewString("");
- Parm *p = parms;
- while (p) {
- String *tm = Getattr(p, "tmap:freearg");
- if (!tm) {
- p = nextSibling(p);
- } else {
- tm = Copy(tm);
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(ret, tm, "\n", NULL);
- Delete(tm);
- p = Getattr(p, "tmap:freearg:next");
- }
- }
- return ret;
- }
-
- /* -----------------------------------------------------------------------
- * cleanupFunction()
- *
- * Final function cleanup code.
- * ----------------------------------------------------------------------- */
-
- void cleanupFunction(Node *n, Wrapper *f, ParmList *parms) {
- String *cleanup = freearg(parms);
- Printv(f->code, cleanup, NULL);
-
- if (GetFlag(n, "feature:new")) {
- String *tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0);
- if (tm) {
- Printv(f->code, tm, "\n", NULL);
- Delete(tm);
- }
- }
-
- Replaceall(f->code, "$cleanup", cleanup);
- Delete(cleanup);
-
- /* See if there is any return cleanup code */
- String *tm;
- if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
- Printf(f->code, "%s\n", tm);
- Delete(tm);
- }
-
- Replaceall(f->code, "$symname", Getattr(n, "sym:name"));
- }
-
- /* -----------------------------------------------------------------------
- * variableHandler()
- *
- * This exists just to set the making_variable_wrappers flag.
- * ----------------------------------------------------------------------- */
-
- virtual int variableHandler(Node *n) {
- assert(!making_variable_wrappers);
- making_variable_wrappers = true;
- int r = Language::variableHandler(n);
- making_variable_wrappers = false;
- return r;
- }
-
- /* -----------------------------------------------------------------------
- * constantWrapper()
- *
- * Product a const declaration.
- * ------------------------------------------------------------------------ */
-
- virtual int constantWrapper(Node *n) {
- SwigType *type = Getattr(n, "type");
-
- if (!SwigType_issimple(type) && SwigType_type(type) != T_STRING) {
- return goComplexConstant(n, type);
- }
-
- if (Swig_storage_isstatic(n)) {
- return goComplexConstant(n, type);
- }
-
- String *go_name = buildGoName(Getattr(n, "sym:name"), false, false);
-
- String *tm = goType(n, type);
- String *value = Getattr(n, "value");
-
- String *copy = NULL;
- if (SwigType_type(type) == T_BOOL) {
- if (Cmp(value, "true") != 0 && Cmp(value, "false") != 0) {
- return goComplexConstant(n, type);
- }
- } else if (SwigType_type(type) == T_STRING || SwigType_type(type) == T_CHAR) {
- // Backslash sequences are somewhat different in Go and C/C++.
- if (Strchr(value, '\\') != 0) {
- return goComplexConstant(n, type);
- }
- } else {
- // Accept a 0x prefix, and strip combinations of u and l
- // suffixes. Otherwise accept digits, decimal point, and
- // exponentiation. Treat anything else as too complicated to
- // handle as a Go constant.
- char *p = Char(value);
- int len = (int)strlen(p);
- bool need_copy = false;
- while (len > 0) {
- char c = p[len - 1];
- if (c != 'l' && c != 'L' && c != 'u' && c != 'U') {
- break;
- }
- --len;
- need_copy = true;
- }
- bool is_hex = false;
- int i = 0;
- if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
- i = 2;
- is_hex = true;
- }
- for (; i < len; ++i) {
- switch (p[i]) {
- case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
- break;
- case 'a': case 'b': case 'c': case 'd': case 'f': case 'A': case 'B': case 'C': case 'D': case 'F':
- if (!is_hex) {
- return goComplexConstant(n, type);
- }
- break;
- case '.': case 'e': case 'E': case '+': case '-':
- break;
- default:
- return goComplexConstant(n, type);
- }
- }
- if (need_copy) {
- copy = Copy(value);
- Replaceall(copy, p + len, "");
- value = copy;
- }
- }
-
- if (!checkNameConflict(go_name, n, NULL)) {
- Delete(tm);
- Delete(go_name);
- Delete(copy);
- return SWIG_NOWRAP;
- }
-
- Printv(f_go_wrappers, "const ", go_name, " ", tm, " = ", NULL);
- if (SwigType_type(type) == T_STRING) {
- Printv(f_go_wrappers, "\"", value, "\"", NULL);
- } else if (SwigType_type(type) == T_CHAR) {
- Printv(f_go_wrappers, "'", value, "'", NULL);
- } else {
- Printv(f_go_wrappers, value, NULL);
- }
-
- Printv(f_go_wrappers, "\n", NULL);
-
- Delete(tm);
- Delete(go_name);
- Delete(copy);
-
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * enumDeclaration()
- *
- * A C++ enum type turns into a Named go int type.
- * ---------------------------------------------------------------------- */
-
- virtual int enumDeclaration(Node *n) {
- if (getCurrentClass() && (cplus_mode != PUBLIC))
- return SWIG_NOWRAP;
-
- String *name = goEnumName(n);
- if (Strcmp(name, "int") != 0) {
- if (!ImportMode || !imported_package) {
- if (!checkNameConflict(name, n, NULL)) {
- Delete(name);
- return SWIG_NOWRAP;
- }
- Printv(f_go_wrappers, "type ", name, " int\n", NULL);
- } else {
- String *nw = NewString("");
- Printv(nw, getModuleName(imported_package), ".", name, NULL);
- Setattr(n, "go:enumname", nw);
- }
- }
- Delete(name);
-
- return Language::enumDeclaration(n);
- }
-
- /* -----------------------------------------------------------------------
- * enumvalueDeclaration()
- *
- * Declare a single value of an enum type. We fetch the value by
- * calling a C/C++ function.
- * ------------------------------------------------------------------------ */
-
- virtual int enumvalueDeclaration(Node *n) {
- if (!is_public(n)) {
- return SWIG_OK;
- }
-
- Swig_require("enumvalueDeclaration", n, "*sym:name", NIL);
- Node *parent = parentNode(n);
-
- if (Getattr(parent, "unnamed")) {
- Setattr(n, "type", NewString("int"));
- } else {
- Setattr(n, "type", Getattr(parent, "enumtype"));
- }
-
- if (GetFlag(parent, "scopedenum")) {
- String *symname = Getattr(n, "sym:name");
- symname = Swig_name_member(0, Getattr(parent, "sym:name"), symname);
- Setattr(n, "sym:name", symname);
- Delete(symname);
- }
-
- int ret = goComplexConstant(n, Getattr(n, "type"));
- Swig_restore(n);
- return ret;
- }
-
- /* -----------------------------------------------------------------------
- * goComplexConstant()
- *
- * Handle a const declaration for something which is not a Go constant.
- * ------------------------------------------------------------------------ */
-
- int goComplexConstant(Node *n, SwigType *type) {
- String *symname = Getattr(n, "sym:name");
- if (!symname) {
- symname = Getattr(n, "name");
- }
-
- String *varname = buildGoName(symname, true, false);
-
- if (!checkNameConflict(varname, n, NULL)) {
- Delete(varname);
- return SWIG_NOWRAP;
- }
-
- String *rawval = Getattr(n, "rawval");
- if (rawval && Len(rawval)) {
- // Based on Swig_VargetToFunction
- String *nname = NewStringf("(%s)", rawval);
- String *call;
- if (SwigType_isclass(type)) {
- call = NewStringf("%s", nname);
- } else {
- call = SwigType_lcaststr(type, nname);
- }
- String *cres = Swig_cresult(type, Swig_cresult_name(), call);
- Setattr(n, "wrap:action", cres);
- Delete(nname);
- Delete(call);
- Delete(cres);
- } else {
- String *get = NewString("");
- Printv(get, Swig_cresult_name(), " = ", NULL);
-
- char quote;
- if (Getattr(n, "wrappedasconstant")) {
- quote = '\0';
- } else if (SwigType_type(type) == T_CHAR) {
- quote = '\'';
- } else if (SwigType_type(type) == T_STRING) {
- Printv(get, "(char *)", NULL);
- quote = '"';
- } else {
- quote = '\0';
- }
-
- if (quote != '\0') {
- Printf(get, "%c", quote);
- }
-
- Printv(get, Getattr(n, "value"), NULL);
-
- if (quote != '\0') {
- Printf(get, "%c", quote);
- }
-
- Printv(get, ";\n", NULL);
-
- Setattr(n, "wrap:action", get);
- Delete(get);
- }
-
- String *sname = Copy(symname);
- if (class_name) {
- Append(sname, "_");
- Append(sname, class_name);
- }
-
- String *go_name = NewString("_swig_get");
- if (class_name) {
- Append(go_name, class_name);
- Append(go_name, "_");
- }
- Append(go_name, sname);
-
- String *wname = Swig_name_wrapper(sname);
- Append(wname, unique_id);
- Setattr(n, "wrap:name", wname);
-
- int r = makeWrappers(n, go_name, NULL, wname, NULL, NULL, type, true);
-
- if (r != SWIG_OK) {
- return r;
- }
-
- String *t = goType(n, type);
- Printv(f_go_wrappers, "var ", varname, " ", t, " = ", go_name, "()\n", NULL);
-
- Delete(varname);
- Delete(t);
- Delete(go_name);
- Delete(sname);
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * classHandler()
- *
- * For a C++ class, in Go we generate both a struct and an
- * interface. The interface will declare all the class public
- * methods. We will define all the methods on the struct, so that
- * the struct meets the interface. We then expect users of the
- * class to use the interface.
- * ------------------------------------------------------------ */
-
- virtual int classHandler(Node *n) {
- class_node = n;
-
- List *baselist = Getattr(n, "bases");
- bool has_base_classes = baselist && Len(baselist) > 0;
-
- String *name = Getattr(n, "sym:name");
-
- String *go_name = exportedName(name);
-
- if (!checkNameConflict(go_name, n, NULL)) {
- Delete(go_name);
- SetFlag(n, "go:conflict");
- return SWIG_NOWRAP;
- }
-
- String *go_type_name = goCPointerType(Getattr(n, "classtypeobj"), true);
-
- class_name = name;
- class_receiver = go_type_name;
- class_methods = NewHash();
-
- int isdir = GetFlag(n, "feature:director");
- int isnodir = GetFlag(n, "feature:nodirector");
- bool is_director = isdir && !isnodir;
-
- Printv(f_go_wrappers, "type ", go_type_name, " uintptr\n\n", NULL);
-
- // A method to return the pointer to the C++ class. This is used
- // by generated code to convert between the interface and the C++
- // value.
- Printv(f_go_wrappers, "func (p ", go_type_name, ") Swigcptr() uintptr {\n", NULL);
- Printv(f_go_wrappers, "\treturn (uintptr)(p)\n", NULL);
- Printv(f_go_wrappers, "}\n\n", NULL);
-
- // A method used as a marker for the class, to avoid invalid
- // interface conversions when using multiple inheritance.
- Printv(f_go_wrappers, "func (p ", go_type_name, ") SwigIs", go_name, "() {\n", NULL);
- Printv(f_go_wrappers, "}\n\n", NULL);
-
- if (is_director) {
- // Return the interface passed to the NewDirector function.
- Printv(f_go_wrappers, "func (p ", go_type_name, ") DirectorInterface() interface{} {\n", NULL);
- Printv(f_go_wrappers, "\treturn nil\n", NULL);
- Printv(f_go_wrappers, "}\n\n", NULL);
- }
-
- // We have seen a definition for this type.
- Setattr(defined_types, go_name, go_name);
- Setattr(defined_types, go_type_name, go_type_name);
-
- interfaces = NewString("");
-
- int r = Language::classHandler(n);
- if (r != SWIG_OK) {
- return r;
- }
-
- if (has_base_classes) {
- // For each method defined in a base class but not defined in
- // this class, we need to define the method in this class. We
- // can't use anonymous field inheritance because it works
- // differently in Go and in C++.
-
- Hash *local = NewHash();
- for (Node *ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
-
- if (!is_public(ni)) {
- continue;
- }
-
- String *type = Getattr(ni, "nodeType");
- if (Cmp(type, "constructor") == 0 || Cmp(type, "destructor") == 0) {
- continue;
- }
-
- String *cname = Getattr(ni, "sym:name");
- if (!cname) {
- cname = Getattr(ni, "name");
- }
- if (cname) {
- Setattr(local, cname, NewString(""));
- }
- }
-
- for (Iterator b = First(baselist); b.item; b = Next(b)) {
- List *bases = NewList();
- Append(bases, Getattr(b.item, "classtype"));
- int r = addBase(n, b.item, bases, local);
- if (r != SWIG_OK) {
- return r;
- }
- Delete(bases);
- }
-
- Delete(local);
-
- Hash *parents = NewHash();
- addFirstBaseInterface(n, parents, baselist);
- int r = addExtraBaseInterfaces(n, parents, baselist);
- Delete(parents);
- if (r != SWIG_OK) {
- return r;
- }
- }
-
- Printv(f_go_wrappers, "type ", go_name, " interface {\n", NULL);
- Printv(f_go_wrappers, "\tSwigcptr() uintptr\n", NULL);
- Printv(f_go_wrappers, "\tSwigIs", go_name, "()\n", NULL);
-
- if (is_director) {
- Printv(f_go_wrappers, "\tDirectorInterface() interface{}\n", NULL);
- }
-
- Append(f_go_wrappers, interfaces);
- Printv(f_go_wrappers, "}\n\n", NULL);
- Delete(interfaces);
-
- interfaces = NULL;
- class_name = NULL;
- class_receiver = NULL;
- class_node = NULL;
- Delete(class_methods);
- class_methods = NULL;
-
- Delete(go_type_name);
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * addBase()
- *
- * Implement methods and members defined in a parent class for a
- * child class.
- * ------------------------------------------------------------ */
-
- int addBase(Node *n, Node *base, List *bases, Hash *local) {
- if (GetFlag(base, "feature:ignore")) {
- return SWIG_OK;
- }
-
- for (Node *ni = Getattr(base, "firstChild"); ni; ni = nextSibling(ni)) {
- int r = goBaseEntry(n, bases, local, ni);
- if (r != SWIG_OK) {
- return r;
- }
- }
-
- List *baselist = Getattr(base, "bases");
- if (baselist && Len(baselist) > 0) {
- for (Iterator b = First(baselist); b.item; b = Next(b)) {
- List *nb = Copy(bases);
- Append(nb, Getattr(b.item, "classtype"));
- int r = addBase(n, b.item, nb, local);
- Delete(nb);
- if (r != SWIG_OK) {
- return r;
- }
- }
- }
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * goBaseEntry()
- *
- * Implement one entry defined in a parent class for a child class.
- * n is the child class.
- * ------------------------------------------------------------ */
-
- int goBaseEntry(Node* n, List* bases, Hash *local, Node* entry) {
- if (GetFlag(entry, "feature:ignore")) {
- return SWIG_OK;
- }
-
- if (!is_public(entry)) {
- return SWIG_OK;
- }
-
- String *type = Getattr(entry, "nodeType");
- if (Strcmp(type, "constructor") == 0 || Strcmp(type, "destructor") == 0 || Strcmp(type, "enum") == 0 || Strcmp(type, "using") == 0 || Strcmp(type, "classforward") == 0 || Strcmp(type, "template") == 0) {
- return SWIG_OK;
- }
-
- if (Strcmp(type, "extend") == 0) {
- for (Node* extend = firstChild(entry); extend; extend = nextSibling(extend)) {
- if (isStatic(extend)) {
- // If we don't do this, the extend_default test case fails.
- continue;
- }
-
- int r = goBaseEntry(n, bases, local, extend);
- if (r != SWIG_OK) {
- return r;
- }
- }
- return SWIG_OK;
- }
-
- String *storage = Getattr(entry, "storage");
- if (storage && (Strcmp(storage, "typedef") == 0 || Strcmp(storage, "friend") == 0)) {
- return SWIG_OK;
- }
-
- String *mname = Getattr(entry, "sym:name");
- if (!mname) {
- return SWIG_OK;
- }
-
- String *lname = Getattr(entry, "name");
- if (Getattr(class_methods, lname)) {
- return SWIG_OK;
- }
- if (Getattr(local, lname)) {
- return SWIG_OK;
- }
- Setattr(local, lname, NewString(""));
-
- String *ty = NewString(Getattr(entry, "type"));
- SwigType_push(ty, Getattr(entry, "decl"));
- String *fullty = SwigType_typedef_resolve_all(ty);
- bool is_function = SwigType_isfunction(fullty) ? true : false;
- Delete(ty);
- Delete(fullty);
-
- if (is_function) {
- int r = goBaseMethod(n, bases, entry);
- if (r != SWIG_OK) {
- return r;
- }
-
- if (Getattr(entry, "sym:overloaded")) {
- for (Node *on = Getattr(entry, "sym:nextSibling"); on; on = Getattr(on, "sym:nextSibling")) {
- r = goBaseMethod(n, bases, on);
- if (r != SWIG_OK) {
- return r;
- }
- }
-
- String *receiver = class_receiver;
- bool is_static = isStatic(entry);
- if (is_static) {
- receiver = NULL;
- }
- String *go_name = buildGoName(Getattr(entry, "sym:name"), is_static, false);
- r = makeDispatchFunction(entry, go_name, receiver, is_static, NULL, false);
- Delete(go_name);
- if (r != SWIG_OK) {
- return r;
- }
- }
- } else {
- int r = goBaseVariable(n, bases, entry);
- if (r != SWIG_OK) {
- return r;
- }
- }
-
- return SWIG_OK;
- }
-
-
- /* ------------------------------------------------------------
- * goBaseMethod()
- *
- * Implement a method defined in a parent class for a child class.
- * ------------------------------------------------------------ */
-
- int goBaseMethod(Node *method_class, List *bases, Node *method) {
- String *symname = Getattr(method, "sym:name");
- if (!validIdentifier(symname)) {
- return SWIG_OK;
- }
-
- String *name = NewString("");
- Printv(name, Getattr(method_class, "sym:name"), "_", symname, NULL);
-
- bool is_static = isStatic(method);
-
- String *go_name = buildGoName(name, is_static, false);
-
- String *overname = NULL;
- if (Getattr(method, "sym:overloaded")) {
- overname = Getattr(method, "sym:overname");
- }
- String *wname = Swig_name_wrapper(name);
- if (overname) {
- Append(wname, overname);
- }
- Append(wname, unique_id);
-
- String *result = NewString(Getattr(method, "type"));
- SwigType_push(result, Getattr(method, "decl"));
- if (SwigType_isqualifier(result)) {
- Delete(SwigType_pop(result));
- }
- Delete(SwigType_pop_function(result));
-
- // If the base method is imported, wrap:action may not be set.
- Swig_save("goBaseMethod", method, "wrap:name", "wrap:action", "parms", NULL);
- Setattr(method, "wrap:name", wname);
- if (!Getattr(method, "wrap:action")) {
- if (!is_static) {
- Swig_MethodToFunction(method, getNSpace(), getClassType(), (Getattr(method, "template") ? SmartPointer : Extend | SmartPointer), NULL, false);
- // Remove any self parameter that was just added.
- ParmList *parms = Getattr(method, "parms");
- if (parms && Getattr(parms, "self")) {
- parms = CopyParmList(nextSibling(parms));
- Setattr(method, "parms", parms);
- }
- } else {
- String *call = Swig_cfunction_call(Getattr(method, "name"), Getattr(method, "parms"));
- Setattr(method, "wrap:action", Swig_cresult(Getattr(method, "type"), Swig_cresult_name(), call));
- }
- }
-
- // A method added by %extend in a base class may have void parms.
- ParmList* parms = Getattr(method, "parms");
- if (parms != NULL && SwigType_type(Getattr(parms, "type")) == T_VOID) {
- parms = NULL;
- }
-
- int r = makeWrappers(method, go_name, overname, wname, bases, parms, result, is_static);
-
- Swig_restore(method);
-
- Delete(result);
- Delete(go_name);
- Delete(name);
-
- return r;
- }
-
- /* ------------------------------------------------------------
- * goBaseVariable()
- *
- * Add accessors for a member variable defined in a parent class for
- * a child class.
- * ------------------------------------------------------------ */
-
- int goBaseVariable(Node *var_class, List *bases, Node *var) {
- if (isStatic(var)) {
- return SWIG_OK;
- }
-
- String *var_name = buildGoName(Getattr(var, "sym:name"), false, false);
-
- Swig_save("goBaseVariable", var, "type", "wrap:action", NULL);
-
- // For a pointer type we apparently have to wrap in the decl.
- SwigType *var_type = NewString(Getattr(var, "type"));
- SwigType_push(var_type, Getattr(var, "decl"));
- Setattr(var, "type", var_type);
-
- SwigType *vt = Copy(var_type);
-
- int flags = Extend | SmartPointer | use_naturalvar_mode(var);
- if (isNonVirtualProtectedAccess(var)) {
- flags |= CWRAP_ALL_PROTECTED_ACCESS;
- }
-
- // Copied from Swig_wrapped_member_var_type.
- if (SwigType_isclass(vt)) {
- if (flags & CWRAP_NATURAL_VAR) {
- if (CPlusPlus) {
- if (!SwigType_isconst(vt)) {
- SwigType_add_qualifier(vt, "const");
- }
- SwigType_add_reference(vt);
- }
- } else {
- SwigType_add_pointer(vt);
- }
- }
-
- String *mname = Swig_name_member(getNSpace(), Getattr(var_class, "sym:name"), var_name);
-
- if (is_assignable(var)) {
- for (Iterator ki = First(var); ki.key; ki = Next(ki)) {
- if (Strncmp(ki.key, "tmap:", 5) == 0) {
- Delattr(var, ki.key);
- }
- }
- Swig_save("goBaseVariableSet", var, "name", "sym:name", "type", NULL);
-
- String *mname_set = NewString("Set");
- Append(mname_set, mname);
-
- String *go_name = NewString("Set");
- Append(go_name, var_name);
-
- Swig_MembersetToFunction(var, class_name, flags);
-
- String *wname = Swig_name_wrapper(mname_set);
- Append(wname, unique_id);
- ParmList *parms = NewParm(vt, var_name, var);
- String *result = NewString("void");
- int r = makeWrappers(var, go_name, NULL, wname, bases, parms, result, false);
- if (r != SWIG_OK) {
- return r;
- }
- Delete(wname);
- Delete(parms);
- Delete(result);
- Delete(go_name);
- Delete(mname_set);
-
- Swig_restore(var);
- for (Iterator ki = First(var); ki.key; ki = Next(ki)) {
- if (Strncmp(ki.key, "tmap:", 5) == 0) {
- Delattr(var, ki.key);
- }
- }
- }
-
- Swig_MembergetToFunction(var, class_name, flags);
-
- String *mname_get = NewString("Get");
- Append(mname_get, mname);
-
- String *go_name = NewString("Get");
- Append(go_name, var_name);
-
- String *wname = Swig_name_wrapper(mname_get);
- Append(wname, unique_id);
-
- int r = makeWrappers(var, go_name, NULL, wname, bases, NULL, vt, false);
- if (r != SWIG_OK) {
- return r;
- }
-
- Delete(wname);
- Delete(mname_get);
- Delete(go_name);
- Delete(mname);
- Delete(var_name);
- Delete(var_type);
- Delete(vt);
-
- Swig_restore(var);
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * addFirstBaseInterface()
- *
- * When a C++ class uses multiple inheritance, we can use the C++
- * pointer for the first base class but not for any subsequent base
- * classes. However, the Go interface will match the interface for
- * all the base classes. To avoid accidentally treating a class as
- * a pointer to a base class other than the first one, we use an
- * isClassname method. This function adds those methods as
- * required.
- *
- * For convenience when using multiple inheritance, we also add
- * functions to retrieve the base class pointers.
- * ------------------------------------------------------------ */
-
- void addFirstBaseInterface(Node *n, Hash *parents, List *bases) {
- if (!bases || Len(bases) == 0) {
- return;
- }
- Iterator b = First(bases);
- if (!GetFlag(b.item, "feature:ignore")) {
- String *go_name = buildGoName(Getattr(n, "sym:name"), false, false);
- String *go_type_name = goCPointerType(Getattr(n, "classtypeobj"), true);
- String *go_base_name = exportedName(Getattr(b.item, "sym:name"));
- String *go_base_type = goType(n, Getattr(b.item, "classtypeobj"));
- String *go_base_type_name = goCPointerType(Getattr(b.item, "classtypeobj"), true);
-
- Printv(f_go_wrappers, "func (p ", go_type_name, ") SwigIs", go_base_name, "() {\n", NULL);
- Printv(f_go_wrappers, "}\n\n", NULL);
-
- Printv(interfaces, "\tSwigIs", go_base_name, "()\n", NULL);
-
- Printv(f_go_wrappers, "func (p ", go_type_name, ") SwigGet", go_base_name, "() ", go_base_type, " {\n", NULL);
- Printv(f_go_wrappers, "\treturn ", go_base_type_name, "(getSwigcptr(p))\n", NULL);
- Printv(f_go_wrappers, "}\n\n", NULL);
-
- Printv(interfaces, "\tSwigGet", go_base_name, "() ", go_base_type, "\n", NULL);
-
- Setattr(parents, go_base_name, NewString(""));
-
- Delete(go_name);
- Delete(go_type_name);
- Delete(go_base_type);
- Delete(go_base_type_name);
- }
-
- addFirstBaseInterface(n, parents, Getattr(b.item, "bases"));
- }
-
- /* ------------------------------------------------------------
- * addExtraBaseInterfaces()
- *
- * Add functions to retrieve the base class pointers for all base
- * classes other than the first.
- * ------------------------------------------------------------ */
-
- int addExtraBaseInterfaces(Node *n, Hash *parents, List *bases) {
- Iterator b = First(bases);
-
- Node *fb = b.item;
-
- for (b = Next(b); b.item; b = Next(b)) {
- if (GetFlag(b.item, "feature:ignore")) {
- continue;
- }
-
- String *go_base_name = exportedName(Getattr(b.item, "sym:name"));
-
- Swig_save("addExtraBaseInterface", n, "wrap:action", "wrap:name", "wrap:parms", NULL);
-
- SwigType *type = Copy(Getattr(n, "classtypeobj"));
- SwigType_add_pointer(type);
- Parm *parm = NewParm(type, "self", n);
- Setattr(n, "wrap:parms", parm);
-
- String *pn = Swig_cparm_name(parm, 0);
- String *action = NewString("");
- Printv(action, Swig_cresult_name(), " = (", Getattr(b.item, "classtype"), "*)", pn, ";", NULL);
- Delete(pn);
-
- Setattr(n, "wrap:action", action);
-
- String *name = Copy(class_name);
- Append(name, "_SwigGet");
- Append(name, go_base_name);
-
- String *go_name = NewString("SwigGet");
- String *c1 = exportedName(go_base_name);
- Append(go_name, c1);
- Delete(c1);
-
- String *wname = Swig_name_wrapper(name);
- Append(wname, unique_id);
- Setattr(n, "wrap:name", wname);
-
- SwigType *result = Copy(Getattr(b.item, "classtypeobj"));
- SwigType_add_pointer(result);
-
- int r = makeWrappers(n, go_name, NULL, wname, NULL, parm, result, false);
- if (r != SWIG_OK) {
- return r;
- }
-
- Swig_restore(n);
-
- Setattr(parents, go_base_name, NewString(""));
-
- Delete(go_name);
- Delete(type);
- Delete(parm);
- Delete(action);
- Delete(result);
-
- String *ns = NewString("");
- addParentExtraBaseInterfaces(n, parents, b.item, false, ns);
- Delete(ns);
- }
-
- if (!GetFlag(fb, "feature:ignore")) {
- String *ns = NewString("");
- addParentExtraBaseInterfaces(n, parents, fb, true, ns);
- Delete(ns);
- }
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * addParentExtraBaseInterfaces()
- *
- * Add functions to retrieve the base class pointers for all base
- * classes of parents other than the first base class at each level.
- * ------------------------------------------------------------ */
-
- void addParentExtraBaseInterfaces(Node *n, Hash *parents, Node *base, bool is_base_first, String *sofar) {
- List *baselist = Getattr(base, "bases");
- if (!baselist || Len(baselist) == 0) {
- return;
- }
-
- String *go_this_base_name = exportedName(Getattr(base, "sym:name"));
-
- String *sf = NewString("");
- Printv(sf, sofar, ".SwigGet", go_this_base_name, "()", NULL);
-
- Iterator b = First(baselist);
-
- if (is_base_first) {
- if (!b.item) {
- return;
- }
- if (!GetFlag(b.item, "feature:ignore")) {
- addParentExtraBaseInterfaces(n, parents, b.item, true, sf);
- }
-
- b = Next(b);
- }
-
- String *go_name = buildGoName(Getattr(n, "sym:name"), false, false);
- String *go_type_name = goCPointerType(Getattr(n, "classtypeobj"), true);
-
- for (; b.item; b = Next(b)) {
- if (GetFlag(b.item, "feature:ignore")) {
- continue;
- }
-
- String *go_base_name = exportedName(Getattr(b.item, "sym:name"));
-
- if (!Getattr(parents, go_base_name)) {
- Printv(f_go_wrappers, "func (p ", go_type_name, ") SwigGet", go_base_name, "() ", go_base_name, " {\n", NULL);
- Printv(f_go_wrappers, "\treturn p", sf, ".SwigGet", go_base_name, "()\n", NULL);
- Printv(f_go_wrappers, "}\n\n", NULL);
-
- Printv(interfaces, "\tSwigGet", go_base_name, "() ", go_base_name, "\n", NULL);
-
- addParentExtraBaseInterfaces(n, parents, b.item, false, sf);
-
- Setattr(parents, go_base_name, NewString(""));
- }
- }
-
- Delete(go_name);
- Delete(go_type_name);
- Delete(go_this_base_name);
- Delete(sf);
- }
-
- /* ------------------------------------------------------------
- * classDirectorInit
- *
- * Add support for a director class.
- *
- * Virtual inheritance is different in Go and C++. We implement
- * director classes by defining a new function in Go,
- * NewDirectorClassname, which takes a empty interface value and
- * creates an instance of a new child class. The new child class
- * refers all methods back to Go. The Go code checks whether the
- * value passed to NewDirectorClassname implements that method; if
- * it does, it calls it, otherwise it calls back into C++.
- * ------------------------------------------------------------ */
-
- int classDirectorInit(Node *n) {
- // Because we use a different function to handle inheritance in
- // Go, ordinary creations of the object should not create a
- // director object.
- Delete(director_ctor_code);
- director_ctor_code = NewString("$nondirector_new");
-
- class_node = n;
-
- String *name = Getattr(n, "sym:name");
-
- assert(!class_name);
- class_name = name;
-
- String *go_name = exportedName(name);
-
- String *go_type_name = goCPointerType(Getattr(n, "classtypeobj"), true);
-
- assert(!class_receiver);
- class_receiver = go_type_name;
-
- String *director_struct_name = NewString("_swig_Director");
- Append(director_struct_name, go_name);
-
- String *cxx_director_name = NewString("SwigDirector_");
- Append(cxx_director_name, name);
-
- // The Go type of the director class.
- Printv(f_go_wrappers, "type ", director_struct_name, " struct {\n", NULL);
- Printv(f_go_wrappers, "\t", go_type_name, "\n", NULL);
- Printv(f_go_wrappers, "\tv interface{}\n", NULL);
- Printv(f_go_wrappers, "}\n\n", NULL);
-
- Printv(f_go_wrappers, "func (p *", director_struct_name, ") Swigcptr() uintptr {\n", NULL);
- Printv(f_go_wrappers, "\treturn getSwigcptr(p.", go_type_name, ")\n", NULL);
- Printv(f_go_wrappers, "}\n\n", NULL);
-
- Printv(f_go_wrappers, "func (p *", director_struct_name, ") SwigIs", go_name, "() {\n", NULL);
- Printv(f_go_wrappers, "}\n\n", NULL);
-
- Printv(f_go_wrappers, "func (p *", director_struct_name, ") DirectorInterface() interface{} {\n", NULL);
- Printv(f_go_wrappers, "\treturn p.v\n", NULL);
- Printv(f_go_wrappers, "}\n\n", NULL);
-
- // Start defining the director class.
- Printv(f_c_directors_h, "class ", cxx_director_name, " : public ", Getattr(n, "classtype"), "\n", NULL);
- Printv(f_c_directors_h, "{\n", NULL);
- Printv(f_c_directors_h, " public:\n", NULL);
-
- Delete(director_struct_name);
- Delete(cxx_director_name);
-
- class_methods = NewHash();
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * classDirectorConstructor
- *
- * Emit a constructor for a director class.
- * ------------------------------------------------------------ */
-
- int classDirectorConstructor(Node *n) {
- bool is_ignored = GetFlag(n, "feature:ignore") ? true : false;
-
- String *name = Getattr(n, "sym:name");
- if (!name) {
- assert(is_ignored);
- name = Getattr(n, "name");
- }
-
- String *overname = NULL;
- if (Getattr(n, "sym:overloaded")) {
- overname = Getattr(n, "sym:overname");
- }
-
- String *go_name = exportedName(name);
-
- ParmList *parms = Getattr(n, "parms");
- Setattr(n, "wrap:parms", parms);
-
- String *cn = exportedName(Getattr(parentNode(n), "sym:name"));
-
- String *go_type_name = goCPointerType(Getattr(parentNode(n), "classtypeobj"), true);
-
- String *director_struct_name = NewString("_swig_Director");
- Append(director_struct_name, cn);
-
- String *fn_name = NewString("_swig_NewDirector");
- Append(fn_name, cn);
- Append(fn_name, go_name);
-
- if (!overname && !is_ignored) {
- if (!checkNameConflict(fn_name, n, NULL)) {
- return SWIG_NOWRAP;
- }
- }
-
- String *fn_with_over_name = Copy(fn_name);
- if (overname) {
- Append(fn_with_over_name, overname);
- }
-
- String *wname = Swig_name_wrapper(fn_name);
-
- if (overname) {
- Append(wname, overname);
- }
- Append(wname, unique_id);
- Setattr(n, "wrap:name", wname);
-
- bool is_static = isStatic(n);
-
- Wrapper *dummy = NewWrapper();
- emit_attach_parmmaps(parms, dummy);
- DelWrapper(dummy);
-
- Swig_typemap_attach_parms("gotype", parms, NULL);
- Swig_typemap_attach_parms("goin", parms, NULL);
- Swig_typemap_attach_parms("goargout", parms, NULL);
- Swig_typemap_attach_parms("imtype", parms, NULL);
- int parm_count = emit_num_arguments(parms);
-
- String *func_name = NewString("NewDirector");
- Append(func_name, go_name);
-
- String *func_with_over_name = Copy(func_name);
- if (overname) {
- Append(func_with_over_name, overname);
- }
-
- SwigType *first_type = NewString("int");
- Parm *first_parm = NewParm(first_type, "swig_p", n);
- set_nextSibling(first_parm, parms);
- Setattr(first_parm, "lname", "p");
-
- Parm *p = parms;
- for (int i = 0; i < parm_count; ++i) {
- p = getParm(p);
- Swig_cparm_name(p, i);
- p = nextParm(p);
- }
-
- if (!is_ignored) {
- Printv(f_cgo_comment, "extern uintptr_t ", wname, "(int", NULL);
-
- p = parms;
- for (int i = 0; i < parm_count; ++i) {
- p = getParm(p);
- bool c_struct_type;
- String *ct = cgoTypeForGoValue(p, Getattr(p, "type"), &c_struct_type);
- Printv(f_cgo_comment, ", ", ct, " ", Getattr(p, "lname"), NULL);
- p = nextParm(p);
- }
- Printv(f_cgo_comment, ");\n", NULL);
-
- // Write out the Go function that calls the wrapper.
-
- Printv(f_go_wrappers, "func ", func_with_over_name, "(v interface{}", NULL);
-
- p = parms;
- for (int i = 0; i < parm_count; ++i) {
- p = getParm(p);
- Printv(f_go_wrappers, ", ", Getattr(p, "lname"), " ", NULL);
- String *tm = goType(p, Getattr(p, "type"));
- Printv(f_go_wrappers, tm, NULL);
- Delete(tm);
- p = nextParm(p);
- }
-
- Printv(f_go_wrappers, ") ", cn, " {\n", NULL);
-
- Printv(f_go_wrappers, "\tp := &", director_struct_name, "{0, v}\n", NULL);
-
- String *call = NewString("");
-
- Printv(call, "\tp.", class_receiver, " = ", NULL);
- Printv(call, go_type_name, "(C.", wname, "(C.int(swigDirectorAdd(p))", NULL);
-
- p = parms;
- for (int i = 0; i < parm_count; ++i) {
- Printv(call, ", ", NULL);
-
- p = getParm(p);
- String *pt = Getattr(p, "type");
- String *ln = Getattr(p, "lname");
-
- String *ivar = NewStringf("_swig_i_%d", i);
-
- String *goin = goGetattr(p, "tmap:goin");
- if (goin == NULL) {
- Printv(f_go_wrappers, "\t", ivar, " := ", NULL);
- bool need_close = false;
- if (goTypeIsInterface(p, pt)) {
- Printv(f_go_wrappers, "getSwigcptr(", NULL);
- need_close = true;
- }
- Printv(f_go_wrappers, ln, NULL);
- if (need_close) {
- Printv(f_go_wrappers, ")", NULL);
- }
- Printv(f_go_wrappers, "\n", NULL);
- } else {
- String *itm = goImType(p, pt);
- Printv(f_go_wrappers, "\tvar ", ivar, " ", itm, "\n", NULL);
- goin = Copy(goin);
- Replaceall(goin, "$input", ln);
- Replaceall(goin, "$result", ivar);
- Printv(f_go_wrappers, goin, "\n", NULL);
- Delete(goin);
- }
-
- Setattr(p, "emit:goinput", ivar);
-
- bool c_struct_type;
- String *ct = cgoTypeForGoValue(p, pt, &c_struct_type);
- if (c_struct_type) {
- Printv(call, "*(*C.", ct, ")(unsafe.Pointer(&", ivar, "))", NULL);
- } else {
- Printv(call, "C.", ct, "(", ivar, ")", NULL);
- }
- Delete(ct);
-
- p = nextParm(p);
- }
-
- Printv(call, "))", NULL);
-
- Printv(f_go_wrappers, call, "\n", NULL);
-
- goargout(parms);
-
- Printv(f_go_wrappers, "\treturn p\n", NULL);
- Printv(f_go_wrappers, "}\n\n", NULL);
-
- SwigType *result = Copy(Getattr(parentNode(n), "classtypeobj"));
- SwigType_add_pointer(result);
-
- Swig_save("classDirectorConstructor", n, "wrap:name", "wrap:action", NULL);
-
- String *dwname = Swig_name_wrapper(name);
- Append(dwname, unique_id);
- Setattr(n, "wrap:name", dwname);
-
- String *action = NewString("");
- Printv(action, Swig_cresult_name(), " = new SwigDirector_", class_name, "(", NULL);
- String *pname = Swig_cparm_name(NULL, 0);
- Printv(action, pname, NULL);
- Delete(pname);
- p = parms;
- for (int i = 0; i < parm_count; ++i) {
- p = getParm(p);
- String *pname = Swig_cparm_name(NULL, i + 1);
- Printv(action, ", ", NULL);
- if (SwigType_isreference(Getattr(p, "type"))) {
- Printv(action, "*", NULL);
- }
- Printv(action, pname, NULL);
- Delete(pname);
- p = nextParm(p);
- }
- Printv(action, ");", NULL);
- Setattr(n, "wrap:action", action);
-
- cgoWrapperInfo info;
-
- info.n = n;
- info.go_name = func_name;
- info.overname = overname;
- info.wname = wname;
- info.base = NULL;
- info.parms = first_parm;
- info.result = result;
- info.is_static = false;
- info.receiver = NULL;
- info.is_constructor = true;
- info.is_destructor = false;
-
- int r = cgoGccWrapper(&info);
- if (r != SWIG_OK) {
- return r;
- }
-
- Swig_restore(n);
-
- Delete(result);
- }
-
- String *cxx_director_name = NewString("SwigDirector_");
- Append(cxx_director_name, class_name);
-
- String *decl = Swig_method_decl(NULL, Getattr(n, "decl"), cxx_director_name, first_parm, 0);
- Printv(f_c_directors_h, " ", decl, ";\n", NULL);
- Delete(decl);
-
- decl = Swig_method_decl(NULL, Getattr(n, "decl"), cxx_director_name, first_parm, 0);
- Printv(f_c_directors, cxx_director_name, "::", decl, "\n", NULL);
- Delete(decl);
-
- Printv(f_c_directors, " : ", Getattr(parentNode(n), "classtype"), "(", NULL);
-
- p = parms;
- for (int i = 0; i < parm_count; ++i) {
- p = getParm(p);
- if (i > 0) {
- Printv(f_c_directors, ", ", NULL);
- }
- String *pn = Getattr(p, "name");
- assert(pn);
- Printv(f_c_directors, pn, NULL);
- p = nextParm(p);
- }
- Printv(f_c_directors, "),\n", NULL);
- Printv(f_c_directors, " go_val(swig_p), swig_mem(0)\n", NULL);
- Printv(f_c_directors, "{ }\n\n", NULL);
-
- if (Getattr(n, "sym:overloaded") && !Getattr(n, "sym:nextSibling")) {
- int r = makeDispatchFunction(n, func_name, cn, is_static, Getattr(parentNode(n), "classtypeobj"), false);
- if (r != SWIG_OK) {
- return r;
- }
- }
-
- Delete(cxx_director_name);
- Delete(go_name);
- Delete(cn);
- Delete(go_type_name);
- Delete(director_struct_name);
- Delete(fn_name);
- Delete(fn_with_over_name);
- Delete(func_name);
- Delete(func_with_over_name);
- Delete(wname);
- Delete(first_type);
- Delete(first_parm);
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * classDirectorDestructor
- *
- * Emit a destructor for a director class.
- * ------------------------------------------------------------ */
-
- int classDirectorDestructor(Node *n) {
- if (!is_public(n)) {
- return SWIG_OK;
- }
-
- bool is_ignored = GetFlag(n, "feature:ignore") ? true : false;
-
- if (!is_ignored) {
- String *fnname = NewString("DeleteDirector");
- String *c1 = exportedName(class_name);
- Append(fnname, c1);
- Delete(c1);
-
- String *wname = Swig_name_wrapper(fnname);
- Append(wname, unique_id);
-
- Setattr(n, "wrap:name", fnname);
-
- Swig_DestructorToFunction(n, getNSpace(), getClassType(), CPlusPlus, Extend);
-
- ParmList *parms = Getattr(n, "parms");
- Setattr(n, "wrap:parms", parms);
-
- String *result = NewString("void");
- int r = makeWrappers(n, fnname, NULL, wname, NULL, parms, result, isStatic(n));
- if (r != SWIG_OK) {
- return r;
- }
-
- Delete(result);
- Delete(fnname);
- Delete(wname);
- }
-
- // Generate the destructor for the C++ director class. Since the
- // Go code is keeping a pointer to the C++ object, we need to call
- // back to the Go code to let it know that the C++ object is gone.
-
- String *go_name = NewString("Swiggo_DeleteDirector_");
- Append(go_name, class_name);
-
- String *cn = exportedName(class_name);
-
- String *director_struct_name = NewString("_swig_Director");
- Append(director_struct_name, cn);
-
- Printv(f_c_directors_h, " virtual ~SwigDirector_", class_name, "()", NULL);
-
- String *throws = buildThrow(n);
- if (throws) {
- Printv(f_c_directors_h, " ", throws, NULL);
- }
-
- Printv(f_c_directors_h, ";\n", NULL);
-
- String *director_sig = NewString("");
-
- Printv(director_sig, "SwigDirector_", class_name, "::~SwigDirector_", class_name, "()", NULL);
-
- if (throws) {
- Printv(director_sig, " ", throws, NULL);
- Delete(throws);
- }
-
- Printv(director_sig, "\n", NULL);
- Printv(director_sig, "{\n", NULL);
-
- if (is_ignored) {
- Printv(f_c_directors, director_sig, NULL);
- } else {
- makeDirectorDestructorWrapper(go_name, director_struct_name, director_sig);
- }
-
- Printv(f_c_directors, " delete swig_mem;\n", NULL);
-
- Printv(f_c_directors, "}\n\n", NULL);
-
- Delete(director_sig);
- Delete(go_name);
- Delete(cn);
- Delete(director_struct_name);
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * makeDirectorDestructorWrapper
- *
- * Emit the function wrapper for the destructor of a director class.
- * ------------------------------------------------------------ */
-
- void makeDirectorDestructorWrapper(String *go_name, String *director_struct_name, String *director_sig) {
- String *wname = Copy(go_name);
- Append(wname, unique_id);
-
- Printv(f_go_wrappers, "//export ", wname, "\n", NULL);
- Printv(f_go_wrappers, "func ", wname, "(c int) {\n", NULL);
- Printv(f_go_wrappers, "\tswigDirectorLookup(c).(*", director_struct_name, ").", class_receiver, " = 0\n", NULL);
- Printv(f_go_wrappers, "\tswigDirectorDelete(c)\n", NULL);
- Printv(f_go_wrappers, "}\n\n", NULL);
-
- Printv(f_c_directors, "extern \"C\" void ", wname, "(intgo);\n", NULL);
- Printv(f_c_directors, director_sig, NULL);
- Printv(f_c_directors, " ", wname, "(go_val);\n", NULL);
- }
-
- /* ------------------------------------------------------------
- * classDirectorMethod
- *
- * Emit a method for a director class, plus its overloads.
- * ------------------------------------------------------------ */
-
- int classDirectorMethod(Node *n, Node *parent, String *super) {
- bool is_ignored = GetFlag(n, "feature:ignore") ? true : false;
-
- // We don't need explicit calls.
- if (GetFlag(n, "explicitcall")) {
- return SWIG_OK;
- }
-
- String *name = Getattr(n, "sym:name");
- if (!name) {
- assert(is_ignored);
- (void)is_ignored;
- name = Getattr(n, "name");
- }
-
- bool overloaded = Getattr(n, "sym:overloaded") && !Getattr(n, "explicitcallnode");
- if (!overloaded) {
- int r = oneClassDirectorMethod(n, parent, super);
- if (r != SWIG_OK) {
- return r;
- }
- } else {
- // Handle overloaded methods here, because otherwise we will
- // reject them in the class_methods hash table. We need to use
- // class_methods so that we correctly handle cases where a
- // function in one class hides a function of the same name in a
- // parent class.
- if (!Getattr(class_methods, name)) {
- for (Node *on = Getattr(n, "sym:overloaded"); on; on = Getattr(on, "sym:nextSibling")) {
- // Swig_overload_rank expects wrap:name and wrap:parms to be
- // set.
- String *wn = Swig_name_wrapper(Getattr(on, "sym:name"));
- Append(wn, Getattr(on, "sym:overname"));
- Append(wn, unique_id);
- Setattr(on, "wrap:name", wn);
- Delete(wn);
- Setattr(on, "wrap:parms", Getattr(on, "parms"));
- }
- }
-
- int r = oneClassDirectorMethod(n, parent, super);
- if (r != SWIG_OK) {
- return r;
- }
-
- if (!Getattr(n, "sym:nextSibling"))
- {
- // Last overloaded function
- Node *on = Getattr(n, "sym:overloaded");
- bool is_static = isStatic(on);
-
- String *cn = exportedName(Getattr(parent, "sym:name"));
- String *go_name = buildGoName(name, is_static, false);
-
- String *director_struct_name = NewString("_swig_Director");
- Append(director_struct_name, cn);
-
- int r = makeDispatchFunction(on, go_name, director_struct_name, is_static, director_struct_name, false);
- if (r != SWIG_OK) {
- return r;
- }
-
- if (!GetFlag(n, "abstract")) {
- String *go_upcall = NewString("Director");
- Append(go_upcall, cn);
- Append(go_upcall, go_name);
- r = makeDispatchFunction(on, go_upcall, director_struct_name, is_static, director_struct_name, true);
- if (r != SWIG_OK) {
- return r;
- }
- Delete(go_upcall);
- }
-
- Delete(director_struct_name);
- Delete(go_name);
- Delete(cn);
- }
- }
- Setattr(class_methods, name, NewString(""));
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * oneClassDirectorMethod
- *
- * Emit a method for a director class.
- * ------------------------------------------------------------ */
-
- int oneClassDirectorMethod(Node *n, Node *parent, String *super) {
- String *symname = Getattr(n, "sym:name");
- if (!checkFunctionVisibility(n, parent)) {
- return SWIG_OK;
- }
-
- bool is_ignored = GetFlag(n, "feature:ignore") ? true : false;
- bool is_pure_virtual = (Cmp(Getattr(n, "storage"), "virtual") == 0 && Cmp(Getattr(n, "value"), "0") == 0);
-
- String *name = Getattr(n, "sym:name");
- if (!name) {
- assert(is_ignored);
- name = Getattr(n, "name");
- }
-
- String *overname = NULL;
- if (Getattr(n, "sym:overloaded")) {
- overname = Getattr(n, "sym:overname");
- }
-
- String *cn = exportedName(Getattr(parent, "sym:name"));
-
- String *go_type_name = goCPointerType(Getattr(parent, "classtypeobj"), true);
-
- String *director_struct_name = NewString("_swig_Director");
- Append(director_struct_name, cn);
-
- bool is_static = isStatic(n);
-
- String *go_name = buildGoName(name, is_static, false);
-
- ParmList *parms = Getattr(n, "parms");
- Setattr(n, "wrap:parms", parms);
-
- Wrapper *dummy = NewWrapper();
- emit_attach_parmmaps(parms, dummy);
-
- Swig_typemap_attach_parms("gotype", parms, NULL);
- Swig_typemap_attach_parms("imtype", parms, NULL);
- int parm_count = emit_num_arguments(parms);
-
- SwigType *result = Getattr(n, "type");
-
- // Save the type for overload processing.
- Setattr(n, "go:type", result);
-
- String *interface_name = NewString("_swig_DirectorInterface");
- Append(interface_name, cn);
- Append(interface_name, go_name);
- if (overname) {
- Append(interface_name, overname);
- }
-
- String *callback_name = Copy(director_struct_name);
- Append(callback_name, "_callback_");
- Append(callback_name, name);
- Replace(callback_name, "_swig", "Swig", DOH_REPLACE_FIRST);
- if (overname) {
- Append(callback_name, overname);
- }
- Append(callback_name, unique_id);
-
- String *upcall_name = Copy(director_struct_name);
- Append(upcall_name, "_upcall_");
- Append(upcall_name, go_name);
-
- String *upcall_wname = Swig_name_wrapper(upcall_name);
- if (overname) {
- Append(upcall_wname, overname);
- }
- Append(upcall_wname, unique_id);
-
- String *upcall_gc_name = buildGoWrapperName(upcall_name, overname);
-
- String *go_with_over_name = Copy(go_name);
- if (overname) {
- Append(go_with_over_name, overname);
- }
-
- Parm *p = 0;
- Wrapper *w = NewWrapper();
-
- Swig_director_parms_fixup(parms);
-
- Swig_typemap_attach_parms("directorin", parms, w);
- Swig_typemap_attach_parms("directorargout", parms, w);
- Swig_typemap_attach_parms("godirectorin", parms, w);
- Swig_typemap_attach_parms("goin", parms, dummy);
- Swig_typemap_attach_parms("goargout", parms, dummy);
-
- DelWrapper(dummy);
-
- if (!is_ignored) {
- // We use an interface to see if this method is defined in Go.
- Printv(f_go_wrappers, "type ", interface_name, " interface {\n", NULL);
- Printv(f_go_wrappers, "\t", go_with_over_name, "(", NULL);
-
- p = parms;
- for (int i = 0; i < parm_count; ++i) {
- p = getParm(p);
- if (i > 0) {
- Printv(f_go_wrappers, ", ", NULL);
- }
- String *tm = goType(p, Getattr(p, "type"));
- Printv(f_go_wrappers, tm, NULL);
- Delete(tm);
- p = nextParm(p);
- }
-
- Printv(f_go_wrappers, ")", NULL);
-
- if (SwigType_type(result) != T_VOID) {
- String *tm = goType(n, result);
- Printv(f_go_wrappers, " ", tm, NULL);
- Delete(tm);
- }
-
- Printv(f_go_wrappers, "\n", NULL);
- Printv(f_go_wrappers, "}\n\n", NULL);
-
- if (!GetFlag(n, "abstract")) {
- Printv(f_cgo_comment, "extern ", NULL);
-
- if (SwigType_type(result) == T_VOID) {
- Printv(f_cgo_comment, "void", NULL);
- } else {
- bool c_struct_type;
- String *ret_type = cgoTypeForGoValue(n, result, &c_struct_type);
- Printv(f_cgo_comment, ret_type, NULL);
- Delete(ret_type);
- }
-
- Printv(f_cgo_comment, " ", upcall_wname, "(uintptr_t", NULL);
-
- p = parms;
- for (int i = 0; i < parm_count; ++i) {
- p = getParm(p);
- bool c_struct_type;
- String *ct = cgoTypeForGoValue(p, Getattr(p, "type"), &c_struct_type);
- Printv(f_cgo_comment, ", ", ct, " ", Getattr(p, "lname"), NULL);
- p = nextParm(p);
- }
- Printv(f_cgo_comment, ");\n", NULL);
- }
-
- // Define the method on the director class in Go.
-
- Printv(f_go_wrappers, "func (swig_p *", director_struct_name, ") ", go_with_over_name, "(", NULL);
-
- p = parms;
- for (int i = 0; i < parm_count; ++i) {
- p = getParm(p);
- if (i > 0) {
- Printv(f_go_wrappers, ", ", NULL);
- }
- Printv(f_go_wrappers, Getattr(p, "lname"), " ", NULL);
- String *tm = goType(p, Getattr(p, "type"));
- Printv(f_go_wrappers, tm, NULL);
- Delete(tm);
- p = nextParm(p);
- }
-
- Printv(f_go_wrappers, ")", NULL);
-
- if (SwigType_type(result) != T_VOID) {
- String *tm = goType(n, result);
- Printv(f_go_wrappers, " ", tm, NULL);
- Delete(tm);
- }
-
- Printv(f_go_wrappers, " {\n", NULL);
-
- Printv(f_go_wrappers, "\tif swig_g, swig_ok := swig_p.v.(", interface_name, "); swig_ok {\n", NULL);
- Printv(f_go_wrappers, "\t\t", NULL);
- if (SwigType_type(result) != T_VOID) {
- Printv(f_go_wrappers, "return ", NULL);
- }
- Printv(f_go_wrappers, "swig_g.", go_with_over_name, "(", NULL);
-
- p = parms;
- for (int i = 0; i < parm_count; ++i) {
- p = getParm(p);
- if (i > 0) {
- Printv(f_go_wrappers, ", ", NULL);
- }
- Printv(f_go_wrappers, Getattr(p, "lname"), NULL);
- p = nextParm(p);
- }
-
- Printv(f_go_wrappers, ")\n", NULL);
- if (SwigType_type(result) == T_VOID) {
- Printv(f_go_wrappers, "\t\treturn\n", NULL);
- }
- Printv(f_go_wrappers, "\t}\n", NULL);
-
- if (GetFlag(n, "abstract")) {
- Printv(f_go_wrappers, "\tpanic(\"call to pure virtual method\")\n", NULL);
- } else {
- String *ret_type = NULL;
- bool memcpy_ret = false;
- String *wt = NULL;
- String *goout = NULL;
- if (SwigType_type(result) != T_VOID) {
- ret_type = goImType(n, result);
- Printv(f_go_wrappers, "\tvar swig_r ", ret_type, "\n", NULL);
- goout = goTypemapLookup("goout", n, "swig_r");
-
- bool c_struct_type;
- Delete(cgoTypeForGoValue(n, result, &c_struct_type));
- if (c_struct_type) {
- memcpy_ret = true;
- }
- }
-
- String *call = NewString("");
-
- Printv(call, "\t", NULL);
- if (SwigType_type(result) != T_VOID) {
- if (memcpy_ret) {
- Printv(call, "swig_r_p := ", NULL);
- } else {
- Printv(call, "swig_r = (", ret_type, ")(", NULL);
- }
- if (goTypeIsInterface(n, result)) {
- wt = goWrapperType(n, result, true);
- Printv(call, "(", wt, ")(", NULL);
- }
- }
-
- Printv(call, "C.", upcall_wname, "(C.uintptr_t(swig_p.",
- go_type_name, ")", NULL);
-
- p = parms;
- for (int i = 0; i < parm_count; ++i) {
- Printv(call, ", ", NULL);
- p = getParm(p);
- SwigType *pt = Getattr(p, "type");
-
- String *ln = Getattr(p, "lname");
-
- String *ivar = NewStringf("_swig_i_%d", i);
-
- // This is an ordinary call from Go to C++, so adjust using
- // the goin typemap.
- String *goin = goGetattr(p, "tmap:goin");
- if (goin == NULL) {
- Printv(f_go_wrappers, "\t", ivar, " := ", NULL);
- bool need_close = false;
- if (goTypeIsInterface(p, pt)) {
- Printv(f_go_wrappers, "getSwigcptr(", NULL);
- need_close = true;
- }
- Printv(f_go_wrappers, ln, NULL);
- if (need_close) {
- Printv(f_go_wrappers, ")", NULL);
- }
- Printv(f_go_wrappers, "\n", NULL);
- } else {
- String *itm = goImType(p, pt);
- Printv(f_go_wrappers, "\tvar ", ivar, " ", itm, "\n", NULL);
- goin = Copy(goin);
- Replaceall(goin, "$input", ln);
- Replaceall(goin, "$result", ivar);
- Printv(f_go_wrappers, goin, "\n", NULL);
- Delete(goin);
- }
-
- Setattr(p, "emit:goinput", ivar);
-
- bool c_struct_type;
- String *ct = cgoTypeForGoValue(p, pt, &c_struct_type);
- if (c_struct_type) {
- Printv(call, "*(*C.", ct, ")(unsafe.Pointer(&", ivar, "))", NULL);
- } else {
- Printv(call, "C.", ct, "(", ivar, ")", NULL);
- }
-
- p = nextParm(p);
- }
-
- Printv(call, ")", NULL);
-
- if (wt) {
- // Close the type conversion to the wrapper type.
- Printv(call, ")", NULL);
- }
- if (SwigType_type(result) != T_VOID && !memcpy_ret) {
- // Close the type conversion of the return value.
- Printv(call, ")", NULL);
- }
-
- Printv(call, "\n", NULL);
-
- Printv(f_go_wrappers, call, NULL);
- Delete(call);
-
- if (memcpy_ret) {
- Printv(f_go_wrappers, "\tswig_r = *(*", ret_type, ")(unsafe.Pointer(&swig_r_p))\n", NULL);
- }
-
- goargout(parms);
-
- if (SwigType_type(result) != T_VOID) {
- if (goout == NULL) {
- Printv(f_go_wrappers, "\treturn swig_r\n", NULL);
- } else {
- String *tm = goType(n, result);
- Printv(f_go_wrappers, "\tvar swig_r_1 ", tm, "\n", NULL);
- Replaceall(goout, "$input", "swig_r");
- Replaceall(goout, "$result", "swig_r_1");
- Printv(f_go_wrappers, goout, "\n", NULL);
- Printv(f_go_wrappers, "\treturn swig_r_1\n", NULL);
- }
- }
-
- if (ret_type) {
- Delete(ret_type);
- }
- if (wt) {
- Delete(wt);
- }
- }
-
- Printv(f_go_wrappers, "}\n\n", NULL);
-
- if (!GetFlag(n, "abstract")) {
- // Define a function that uses the Go director type that other
- // methods in the Go type can call to get parent methods.
-
- Printv(f_go_wrappers, "func Director", cn, go_with_over_name, "(swig_p ", cn, NULL);
-
- p = parms;
- for (int i = 0; i < parm_count; ++i) {
- p = getParm(p);
- Printv(f_go_wrappers, ", ", Getattr(p, "lname"), " ", NULL);
- String *tm = goType(p, Getattr(p, "type"));
- Printv(f_go_wrappers, tm, NULL);
- Delete(tm);
- p = nextParm(p);
- }
-
- Printv(f_go_wrappers, ")", NULL);
-
- if (SwigType_type(result) != T_VOID) {
- String *tm = goType(n, result);
- Printv(f_go_wrappers, " ", tm, NULL);
- Delete(tm);
- }
-
- Printv(f_go_wrappers, " {\n", NULL);
-
- String *ret_type = NULL;
- bool memcpy_ret = false;
- String *wt = NULL;
- String *goout = NULL;
- if (SwigType_type(result) != T_VOID) {
- ret_type = goImType(n, result);
- Printv(f_go_wrappers, "\tvar swig_r ", ret_type, "\n", NULL);
- goout = goTypemapLookup("goout", n, "swig_r");
-
- bool c_struct_type;
- Delete(cgoTypeForGoValue(n, result, &c_struct_type));
- if (c_struct_type) {
- memcpy_ret = true;
- }
- }
-
- String *call = NewString("");
-
- Printv(call, "\t", NULL);
- if (SwigType_type(result) != T_VOID) {
- if (memcpy_ret) {
- Printv(call, "swig_r_p := ", NULL);
- } else {
- Printv(call, "swig_r = (", ret_type, ")(", NULL);
- }
- if (goTypeIsInterface(n, result)) {
- wt = goWrapperType(n, result, true);
- Printv(call, "(", wt, ")(", NULL);
- }
- }
-
- Printv(call, "C.", upcall_wname, "(C.uintptr_t(swig_p.(*",
- director_struct_name, ").", go_type_name, ")", NULL);
-
- p = parms;
- for (int i = 0; i < parm_count; ++i) {
- Printv(call, ", ", NULL);
- p = getParm(p);
- SwigType *pt = Getattr(p, "type");
-
- String *ivar = NewStringf("_swig_i_%d", i);
-
- String *ln = Copy(Getattr(p, "lname"));
-
- String *goin = goGetattr(p, "tmap:goin");
- if (goin == NULL) {
- Printv(f_go_wrappers, "\t", ivar, " := ", NULL);
- bool need_close = false;
- if (goTypeIsInterface(p, pt)) {
- Printv(f_go_wrappers, "getSwigcptr(", NULL);
- need_close = true;
- }
- Printv(f_go_wrappers, ln, NULL);
- if (need_close) {
- Printv(f_go_wrappers, ")", NULL);
- }
- Printv(f_go_wrappers, "\n", NULL);
- } else {
- String *itm = goImType(p, pt);
- Printv(f_go_wrappers, "\tvar ", ivar, " ", itm, "\n", NULL);
- goin = Copy(goin);
- Replaceall(goin, "$input", ln);
- Replaceall(goin, "$result", ivar);
- Printv(f_go_wrappers, goin, "\n", NULL);
- Delete(goin);
- }
-
- Setattr(p, "emit:goinput", ivar);
-
- bool c_struct_type;
- String *ct = cgoTypeForGoValue(p, pt, &c_struct_type);
- if (c_struct_type) {
- Printv(call, "*(*C.", ct, ")(unsafe.Pointer(&", ivar, "))", NULL);
- } else {
- Printv(call, "C.", ct, "(", ivar, ")", NULL);
- }
-
- Delete(ln);
-
- p = nextParm(p);
- }
-
- Printv(call, ")", NULL);
-
- if (wt) {
- // Close the type conversion to the wrapper type.
- Printv(call, ")", NULL);
- }
- if (SwigType_type(result) != T_VOID && !memcpy_ret) {
- // Close the type conversion of the return value.
- Printv(call, ")", NULL);
- }
-
- Printv(call, "\n", NULL);
-
- Printv(f_go_wrappers, call, NULL);
- Delete(call);
-
- if (memcpy_ret) {
- Printv(f_go_wrappers, "\tswig_r = *(*", ret_type, ")(unsafe.Pointer(&swig_r_p))\n", NULL);
- }
-
- goargout(parms);
-
- if (SwigType_type(result) != T_VOID) {
- if (goout == NULL) {
- Printv(f_go_wrappers, "\treturn swig_r\n", NULL);
- } else {
- String *tm = goType(n, result);
- Printv(f_go_wrappers, "\tvar swig_r_1 ", tm, "\n", NULL);
- Replaceall(goout, "$input", "swig_r");
- Replaceall(goout, "$result", "swig_r_1");
- Printv(f_go_wrappers, goout, "\n", NULL);
- Printv(f_go_wrappers, "\treturn swig_r_1\n", NULL);
- }
- }
-
- Printv(f_go_wrappers, "}\n\n", NULL);
-
- if (ret_type) {
- Delete(ret_type);
- }
- if (wt) {
- Delete(wt);
- }
-
- // Define a method in the C++ director class that the C++
- // upcall function can call. This permits an upcall to a
- // protected method.
-
- String *upcall_method_name = NewString("_swig_upcall_");
- Append(upcall_method_name, name);
- if (overname) {
- Append(upcall_method_name, overname);
- }
- SwigType *rtype = Getattr(n, "classDirectorMethods:type");
- String *upcall_decl = Swig_method_decl(rtype, Getattr(n, "decl"), upcall_method_name, parms, 0);
- Printv(f_c_directors_h, " ", upcall_decl, " {\n", NULL);
- Delete(upcall_decl);
-
- Printv(f_c_directors_h, " ", NULL);
- if (SwigType_type(result) != T_VOID) {
- Printv(f_c_directors_h, "return ", NULL);
- }
-
- String *super_call = Swig_method_call(super, parms);
- Printv(f_c_directors_h, super_call, ";\n", NULL);
- Delete(super_call);
-
- Printv(f_c_directors_h, " }\n", NULL);
-
- // Define the C++ function that the Go function calls.
-
- SwigType *first_type = NULL;
- Parm *first_parm = parms;
- if (!is_static) {
- first_type = NewString("SwigDirector_");
- Append(first_type, class_name);
- SwigType_add_pointer(first_type);
- first_parm = NewParm(first_type, "p", n);
- set_nextSibling(first_parm, parms);
- }
-
- Swig_save("classDirectorMethod", n, "wrap:name", "wrap:action", NULL);
-
- Setattr(n, "wrap:name", upcall_wname);
-
- String *action = NewString("");
- if (SwigType_type(result) != T_VOID) {
- Printv(action, Swig_cresult_name(), " = (", SwigType_lstr(result, 0), ")", NULL);
- if (SwigType_isreference(result)) {
- Printv(action, "&", NULL);
- }
- }
- Printv(action, Swig_cparm_name(NULL, 0), "->", upcall_method_name, "(", NULL);
-
- p = parms;
- int i = 0;
- while (p != NULL) {
- if (SwigType_type(Getattr(p, "type")) != T_VOID) {
- String *pname = Swig_cparm_name(NULL, i + 1);
- if (i > 0) {
- Printv(action, ", ", NULL);
- }
-
- // A parameter whose type is a reference is converted into a
- // pointer type by gcCTypeForGoValue. We are calling a
- // function which expects a reference so we need to convert
- // back.
- if (SwigType_isreference(Getattr(p, "type"))) {
- Printv(action, "*", NULL);
- }
-
- Printv(action, pname, NULL);
- Delete(pname);
- i++;
- }
- p = nextSibling(p);
- }
- Printv(action, ");", NULL);
- Setattr(n, "wrap:action", action);
-
- cgoWrapperInfo info;
-
- info.n = n;
- info.go_name = go_name;
- info.overname = overname;
- info.wname = upcall_wname;
- info.base = NULL;
- info.parms = first_parm;
- info.result = result;
- info.is_static = is_static;
- info.receiver = NULL;
- info.is_constructor = false;
- info.is_destructor = false;
-
- int r = cgoGccWrapper(&info);
- if (r != SWIG_OK) {
- return r;
- }
-
- Delete(first_type);
- if (first_parm != parms) {
- Delete(first_parm);
- }
-
- Swig_restore(n);
- Delete(upcall_method_name);
- }
-
- // The Go function which invokes the method. This is called by
- // the C++ method on the director class.
-
- Printv(f_go_wrappers, "//export ", callback_name, "\n",
- "func ", callback_name, "(swig_c int", NULL);
-
- p = parms;
- for (int i = 0; i < parm_count; ++i) {
- p = getParm(p);
- String *tm = goWrapperType(p, Getattr(p, "type"), false);
- Printv(f_go_wrappers, ", ", Getattr(p, "lname"), " ", tm, NULL);
- Delete(tm);
- p = nextParm(p);
- }
-
- Printv(f_go_wrappers, ") ", NULL);
- String *result_wrapper = NULL;
- if (SwigType_type(result) != T_VOID) {
- result_wrapper = goWrapperType(n, result, true);
- Printv(f_go_wrappers, "(swig_result ", result_wrapper, ") ", NULL);
- }
- Printv(f_go_wrappers, "{\n", NULL);
-
- if (is_ignored) {
- Printv(f_go_wrappers, "\treturn\n", NULL);
- } else {
- bool result_is_interface = false;
- String *goout = NULL;
- if (SwigType_type(result) != T_VOID) {
- result_is_interface = goTypeIsInterface(NULL, result);
- Printv(f_go_wrappers, "\tvar swig_r ", NULL);
- if (!result_is_interface) {
- Printv(f_go_wrappers, goType(n, result), NULL);
- } else {
- Printv(f_go_wrappers, result_wrapper, NULL);
- }
- Printv(f_go_wrappers, "\n", NULL);
- goout = goTypemapLookup("godirectorout", n, "swig_r");
- }
-
- String *call = NewString("");
- Printv(call, "\t", NULL);
-
- if (SwigType_type(result) != T_VOID) {
- Printv(call, "swig_r = ", NULL);
- if (result_is_interface) {
- Printv(call, result_wrapper, "(getSwigcptr(", NULL);
- }
- }
- Printv(call, "swig_p.", go_with_over_name, "(", NULL);
-
- String *goincode = NewString("");
-
- p = parms;
- for (int i = 0; i < parm_count; ++i) {
- p = getParm(p);
- if (i > 0) {
- Printv(call, ", ", NULL);
- }
- SwigType *pt = Getattr(p, "type");
-
- String *ln = NewString("");
-
- // If the Go representation is an interface type class, then
- // we are receiving a uintptr, and must convert to the
- // interface.
- bool is_interface = goTypeIsInterface(p, pt);
- if (is_interface) {
- // Passing is_result as true to goWrapperType gives us the
- // name of the Go type we need to convert to an interface.
- String *wt = goWrapperType(p, pt, true);
- Printv(ln, wt, "(", NULL);
- Delete(wt);
- }
-
- Printv(ln, Getattr(p, "lname"), NULL);
-
- if (is_interface) {
- Printv(ln, ")", NULL);
- }
-
- String *goin = goGetattr(p, "tmap:godirectorin");
- if (goin == NULL) {
- Printv(call, ln, NULL);
- } else {
- String *ivar = NewString("");
- Printf(ivar, "_swig_i_%d", i);
- String *itm = goType(p, pt);
- Printv(f_go_wrappers, "\tvar ", ivar, " ", itm, "\n", NULL);
- goin = Copy(goin);
- Replaceall(goin, "$input", ln);
- Replaceall(goin, "$result", ivar);
- Printv(goincode, goin, "\n", NULL);
- Delete(goin);
- Printv(call, ivar, NULL);
- Delete(ivar);
- }
-
- Delete(ln);
-
- p = nextParm(p);
- }
-
- Printv(call, ")", NULL);
-
- if (result_is_interface) {
- Printv(call, "))", NULL);
- }
- Printv(call, "\n", NULL);
-
- Printv(f_go_wrappers, "\tswig_p := swigDirectorLookup(swig_c).(*", director_struct_name, ")\n", NULL);
- Printv(f_go_wrappers, goincode, NULL);
- Printv(f_go_wrappers, call, NULL);
- Delete(call);
-
- if (SwigType_type(result) != T_VOID) {
- if (goout == NULL) {
- Printv(f_go_wrappers, "\treturn swig_r\n", NULL);
- } else {
- String *tm = goImType(n, result);
- Printv(f_go_wrappers, "\tvar swig_r_1 ", tm, "\n", NULL);
- Replaceall(goout, "$input", "swig_r");
- Replaceall(goout, "$result", "swig_r_1");
- Printv(f_go_wrappers, goout, "\n", NULL);
- Printv(f_go_wrappers, "\treturn swig_r_1\n", NULL);
- }
- }
- }
-
- Printv(f_go_wrappers, "}\n\n", NULL);
-
- Delete(result_wrapper);
-
- Delete(upcall_wname);
- Delete(upcall_gc_name);
- Delete(go_with_over_name);
- }
-
- if (!is_ignored || is_pure_virtual) {
- // Declare the method for the director class.
-
- SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
- String *decl = Swig_method_decl(rtype, Getattr(n, "decl"), Getattr(n, "name"), parms, 0);
- Printv(f_c_directors_h, " virtual ", decl, NULL);
- Delete(decl);
-
- String *qname = NewString("");
- Printv(qname, "SwigDirector_", class_name, "::", Getattr(n, "name"), NULL);
- decl = Swig_method_decl(rtype, Getattr(n, "decl"), qname, parms, 0);
- Printv(w->def, decl, NULL);
- Delete(decl);
- Delete(qname);
-
- String *throws = buildThrow(n);
- if (throws) {
- Printv(f_c_directors_h, " ", throws, NULL);
- Printv(w->def, " ", throws, NULL);
- Delete(throws);
- }
-
- Printv(f_c_directors_h, ";\n", NULL);
-
- Printv(w->def, " {\n", NULL);
-
- if (SwigType_type(result) != T_VOID) {
- if (!SwigType_isclass(result)) {
- if (!(SwigType_ispointer(result) || SwigType_isreference(result))) {
- String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(result, 0));
- Wrapper_add_localv(w, "c_result", SwigType_lstr(result, "c_result"), construct_result, NIL);
- Delete(construct_result);
- } else {
- Wrapper_add_localv(w, "c_result", SwigType_lstr(result, "c_result"), "= 0", NIL);
- }
- } else {
- String *cres = SwigType_lstr(result, "c_result");
- Printf(w->code, "%s;\n", cres);
- Delete(cres);
- }
- }
-
- if (!is_ignored) {
- makeDirectorMethodWrapper(n, w, callback_name);
- } else {
- assert(is_pure_virtual);
- Printv(w->code, " _swig_gopanic(\"call to pure virtual function ", Getattr(parent, "sym:name"), name, "\");\n", NULL);
- if (SwigType_type(result) != T_VOID) {
- String *retstr = SwigType_rcaststr(result, "c_result");
- Printv(w->code, " return ", retstr, ";\n", NULL);
- Delete(retstr);
- }
- }
-
- Printv(w->code, "}", NULL);
-
- Replaceall(w->code, "$symname", symname);
- Wrapper_print(w, f_c_directors);
- }
-
- Delete(cn);
- Delete(go_type_name);
- Delete(director_struct_name);
- Delete(interface_name);
- Delete(callback_name);
- Delete(upcall_name);
- Delete(go_name);
- DelWrapper(w);
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * makeDirectorMethodWrapper
- *
- * Emit the function wrapper for a director method.
- * ------------------------------------------------------------ */
- void makeDirectorMethodWrapper(Node *n, Wrapper *w, String *callback_name) {
- ParmList *parms = Getattr(n, "wrap:parms");
- SwigType *result = Getattr(n, "type");
-
- Printv(f_c_directors, "extern \"C\" ", NULL);
-
- String *fnname = Copy(callback_name);
- Append(fnname, "(int");
-
- Parm *p = parms;
- while (p) {
- while (checkAttribute(p, "tmap:directorin:numinputs", "0")) {
- p = Getattr(p, "tmap:directorin:next");
- }
- String *cg = gcCTypeForGoValue(p, Getattr(p, "type"), Getattr(p, "lname"));
- Printv(fnname, ", ", cg, NULL);
- Delete(cg);
- p = Getattr(p, "tmap:directorin:next");
- }
-
- Printv(fnname, ")", NULL);
-
- if (SwigType_type(result) == T_VOID) {
- Printv(f_c_directors, "void ", fnname, NULL);
- } else {
- String *tm = gcCTypeForGoValue(n, result, fnname);
- Printv(f_c_directors, tm, NULL);
- Delete(tm);
- }
-
- Delete(fnname);
-
- Printv(f_c_directors, ";\n", NULL);
-
- if (SwigType_type(result) != T_VOID) {
- String *r = NewString(Swig_cresult_name());
- String *tm = gcCTypeForGoValue(n, result, r);
- Wrapper_add_local(w, r, tm);
- Delete(tm);
- Delete(r);
- }
-
- String *args = NewString("");
-
- p = parms;
- while (p) {
- while (checkAttribute(p, "tmap:directorin:numinputs", "0")) {
- p = Getattr(p, "tmap:directorin:next");
- }
-
- String *pn = NewString("swig_");
- Append(pn, Getattr(p, "lname"));
- Setattr(p, "emit:directorinput", pn);
-
- String *tm = gcCTypeForGoValue(p, Getattr(p, "type"), pn);
- Wrapper_add_local(w, pn, tm);
- Delete(tm);
-
- tm = Getattr(p, "tmap:directorin");
- if (!tm) {
- Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file,
- line_number, "Unable to use type %s as director method argument\n", SwigType_str(Getattr(p, "type"), 0));
- } else {
- tm = Copy(tm);
- Replaceall(tm, "$input", pn);
- Replaceall(tm, "$owner", 0);
- Printv(w->code, " ", tm, "\n", NULL);
- Delete(tm);
-
- Printv(args, ", ", pn, NULL);
- }
-
- p = Getattr(p, "tmap:directorin:next");
- }
-
- Printv(w->code, " ", NULL);
- if (SwigType_type(result) != T_VOID) {
- Printv(w->code, Swig_cresult_name(), " = ", NULL);
- }
- Printv(w->code, callback_name, "(go_val", args, ");\n", NULL);
-
- /* Marshal outputs */
- for (p = parms; p; ) {
- String *tm;
- if ((tm = Getattr(p, "tmap:directorargout"))) {
- tm = Copy(tm);
- Replaceall(tm, "$result", "jresult");
- Replaceall(tm, "$input", Getattr(p, "emit:directorinput"));
- Printv(w->code, tm, "\n", NULL);
- Delete(tm);
- p = Getattr(p, "tmap:directorargout:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- if (SwigType_type(result) != T_VOID) {
- String *result_str = NewString("c_result");
- String *tm = Swig_typemap_lookup("directorout", n, result_str, NULL);
- if (!tm) {
- Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
- "Unable to use type %s as director method result\n", SwigType_str(result, 0));
- } else {
- tm = Copy(tm);
- Replaceall(tm, "$input", Swig_cresult_name());
- Replaceall(tm, "$result", "c_result");
- Printv(w->code, " ", tm, "\n", NULL);
- String *retstr = SwigType_rcaststr(result, "c_result");
- Printv(w->code, " return ", retstr, ";\n", NULL);
- Delete(retstr);
- Delete(tm);
- }
- Delete(result_str);
- }
- }
-
-
- /* ------------------------------------------------------------
- * classDirectorEnd
- *
- * Complete support for a director class.
- * ------------------------------------------------------------ */
-
- int classDirectorEnd(Node *n) {
- (void) n;
-
- Printv(f_c_directors_h, " private:\n", NULL);
- Printv(f_c_directors_h, " intgo go_val;\n", NULL);
- Printv(f_c_directors_h, " Swig_memory *swig_mem;\n", NULL);
- Printv(f_c_directors_h, "};\n\n", NULL);
-
- class_name = NULL;
- class_node = NULL;
-
- Delete(class_receiver);
- class_receiver = NULL;
-
- Delete(class_methods);
- class_methods = NULL;
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * classDirectorDisown
- *
- * I think Go does not require a disown method.
- * ------------------------------------------------------------ */
-
- int classDirectorDisown(Node *n) {
- (void) n;
- return SWIG_OK;
- }
-
- /*----------------------------------------------------------------------
- * buildThrow()
- *
- * Build and return a throw clause if needed.
- *--------------------------------------------------------------------*/
-
- String *buildThrow(Node *n) {
- if (Getattr(n, "noexcept"))
- return NewString("noexcept");
- ParmList *throw_parm_list = Getattr(n, "throws");
- if (!throw_parm_list && !Getattr(n, "throw"))
- return NULL;
- String *ret = NewString("throw(");
- if (throw_parm_list) {
- Swig_typemap_attach_parms("throws", throw_parm_list, NULL);
- }
- bool first = true;
- for (Parm *p = throw_parm_list; p; p = nextSibling(p)) {
- if (Getattr(p, "tmap:throws")) {
- if (first) {
- first = false;
- } else {
- Printv(ret, ", ", NULL);
- }
- String *s = SwigType_str(Getattr(p, "type"), 0);
- Printv(ret, s, NULL);
- Delete(s);
- }
- }
- Printv(ret, ")", NULL);
- return ret;
- }
-
- /*----------------------------------------------------------------------
- * extraDirectorProtectedCPPMethodsRequired()
- *
- * We don't need to check upcall when calling methods.
- *--------------------------------------------------------------------*/
-
- bool extraDirectorProtectedCPPMethodsRequired() const {
- return false;
- }
-
- /*----------------------------------------------------------------------
- * makeDispatchFunction
- *
- * Make a dispatch function for an overloaded C++ function. The
- * receiver parameter is the receiver for a method, unless is_upcall
- * is true. If is_upcall is true, then the receiver parameter is
- * the type of the first argument to the function.
- *--------------------------------------------------------------------*/
-
- int makeDispatchFunction(Node *n, String *go_name, String *receiver, bool is_static, SwigType *director_struct, bool is_upcall) {
- bool is_director = director_struct ? true : false;
-
- String *nodetype = Getattr(n, "nodeType");
- bool is_constructor = Cmp(nodetype, "constructor") == 0;
- bool is_destructor = Cmp(nodetype, "destructor") == 0;
-
- bool can_use_receiver = (!is_constructor && !is_destructor && !is_upcall);
-
- bool use_receiver = (!is_static && can_use_receiver);
-
- bool add_to_interface = (interfaces && !is_constructor && !is_destructor && !is_static && !is_upcall);
-
- List *dispatch = Swig_overload_rank(n, false);
- int nfunc = Len(dispatch);
-
- SwigType *all_result;
- bool mismatch;
- if (is_constructor) {
- assert(!is_upcall);
- if (!is_director) {
- all_result = Copy(Getattr(class_node, "classtypeobj"));
- } else {
- all_result = Copy(director_struct);
- }
- mismatch = false;
- } else {
- all_result = NULL;
- mismatch = false;
- bool any_void = false;
- for (int i = 0; i < nfunc; ++i) {
- Node *nn = Getitem(dispatch, i);
- Node *ni = Getattr(nn, "directorNode") ? Getattr(nn, "directorNode") : nn;
- SwigType *result = Getattr(ni, "go:type");
- assert(result);
-
- if (SwigType_type(result) == T_VOID) {
- if (all_result) {
- mismatch = true;
- }
- any_void = true;
- } else {
- if (any_void) {
- mismatch = true;
- } else if (!all_result) {
- all_result = Copy(result);
- } else if (Cmp(result, all_result) != 0) {
- mismatch = true;
- }
- }
- }
- if (mismatch) {
- Delete(all_result);
- all_result = NULL;
- } else if (all_result) {
- ;
- } else {
- all_result = NewString("void");
- }
- }
-
- Printv(f_go_wrappers, "func ", NULL);
-
- if (receiver && use_receiver) {
- Printv(f_go_wrappers, "(p ", receiver, ") ", NULL);
- }
-
- Printv(f_go_wrappers, go_name, "(", NULL);
- if (is_director && is_constructor) {
- Printv(f_go_wrappers, "abi interface{}, ", NULL);
- assert(!add_to_interface);
- }
- if (is_upcall) {
- Printv(f_go_wrappers, "p *", receiver, ", ", NULL);
- assert(!add_to_interface);
- }
- Printv(f_go_wrappers, "a ...interface{})", NULL);
-
- if (add_to_interface) {
- Printv(interfaces, "\t", go_name, "(a ...interface{})", NULL);
- }
-
- if (mismatch) {
- Printv(f_go_wrappers, " interface{}", NULL);
- if (add_to_interface) {
- Printv(interfaces, " interface{}", NULL);
- }
- } else if (all_result && SwigType_type(all_result) != T_VOID) {
- if (is_director && is_constructor) {
- Printv(f_go_wrappers, " ", receiver, NULL);
- if (add_to_interface) {
- Printv(interfaces, " ", receiver, NULL);
- }
- } else {
- String *tm = goType(n, all_result);
- Printv(f_go_wrappers, " ", tm, NULL);
- if (add_to_interface) {
- Printv(interfaces, " ", tm, NULL);
- }
- Delete(tm);
- }
- }
- Printv(f_go_wrappers, " {\n", NULL);
- if (add_to_interface) {
- Printv(interfaces, "\n", NULL);
- }
-
- Printv(f_go_wrappers, "\targc := len(a)\n", NULL);
-
- for (int i = 0; i < nfunc; ++i) {
- int fn = 0;
- Node *nn = Getitem(dispatch, i);
- Node *ni = Getattr(nn, "directorNode") ? Getattr(nn, "directorNode") : nn;
- Parm *pi = Getattr(ni, "wrap:parms");
-
- // If we are using a receiver, we want to ignore a leading self
- // parameter. Because of the way this is called, there may or
- // may not be a self parameter at this point.
- if (use_receiver && pi && Getattr(pi, "self")) {
- pi = getParm(pi);
- if (pi) {
- pi = nextParm(pi);
- }
- }
-
- int num_required = emit_num_required(pi);
- int num_arguments = emit_num_arguments(pi);
- bool varargs = emit_isvarargs(pi) ? true : false;
-
- if (varargs) {
- Printf(f_go_wrappers, "\tif argc >= %d {\n", num_required);
- } else {
- if (num_required == num_arguments) {
- Printf(f_go_wrappers, "\tif argc == %d {\n", num_required);
- } else {
- Printf(f_go_wrappers, "\tif argc >= %d && argc <= %d {\n", num_required, num_arguments);
- }
- }
-
- // Build list of collisions with the same number of arguments.
- List *coll = NewList();
- for (int k = i + 1; k < nfunc; ++k) {
- Node *nnk = Getitem(dispatch, k);
- Node *nk = Getattr(nnk, "directorNode") ? Getattr(nnk, "directorNode") : nnk;
- Parm *pk = Getattr(nk, "wrap:parms");
- if (use_receiver && pk && Getattr(pk, "self")) {
- pk = getParm(pk);
- if (pk) {
- pk = nextParm(pk);
- }
- }
- int nrk = emit_num_required(pk);
- int nak = emit_num_arguments(pk);
- if ((nrk >= num_required && nrk <= num_arguments)
- || (nak >= num_required && nak <= num_arguments)
- || (nrk <= num_required && nak >= num_arguments)
- || (varargs && nrk >= num_required)) {
- Append(coll, nk);
- }
- }
-
- int num_braces = 0;
- if (Len(coll) > 0 && num_arguments > 0) {
- int j = 0;
- Parm *pj = pi;
- while (pj) {
- pj = getParm(pj);
- if (!pj) {
- break;
- }
-
- // If all the overloads have the same type in this position,
- // we can omit the check.
- SwigType *tm = goOverloadType(pj, Getattr(pj, "type"));
- bool emitcheck = false;
- for (int k = 0; k < Len(coll) && !emitcheck; ++k) {
- Node *nk = Getitem(coll, k);
- Parm *pk = Getattr(nk, "wrap:parms");
- if (use_receiver && pk && Getattr(pk, "self")) {
- pk = getParm(pk);
- if (pk) {
- pk = nextParm(pk);
- }
- }
- int nak = emit_num_arguments(pk);
- if (nak <= j)
- continue;
- int l = 0;
- Parm *pl = pk;
- while (pl && l <= j) {
- pl = getParm(pl);
- if (!pl) {
- break;
- }
- if (l == j) {
- SwigType *tml = goOverloadType(pl, Getattr(pl, "type"));
- if (Cmp(tm, tml) != 0) {
- emitcheck = true;
- }
- Delete(tml);
- }
- pl = nextParm(pl);
- ++l;
- }
- }
-
- if (emitcheck) {
- if (j >= num_required) {
- Printf(f_go_wrappers, "\t\tif argc > %d {\n", j);
- ++num_braces;
- }
-
- fn = i + 1;
- Printf(f_go_wrappers, "\t\tif _, ok := a[%d].(%s); !ok {\n", j, tm);
- Printf(f_go_wrappers, "\t\t\tgoto check_%d\n", fn);
- Printv(f_go_wrappers, "\t\t}\n", NULL);
- }
-
- Delete(tm);
-
- pj = nextParm(pj);
-
- ++j;
- }
- }
-
- for (; num_braces > 0; --num_braces) {
- Printv(f_go_wrappers, "\t\t}\n", NULL);
- }
-
- // We may need to generate multiple calls if there are variable
- // argument lists involved. Build the start of the call.
-
- String *start = NewString("");
-
- SwigType *result = Getattr(ni, "go:type");
-
- if (is_constructor) {
- result = all_result;
- } else if (is_destructor) {
- result = NULL;
- }
-
- if (result && SwigType_type(result) != T_VOID && (!all_result || SwigType_type(all_result) != T_VOID)) {
- Printv(start, "return ", NULL);
- }
-
- bool advance_parm = false;
-
- if (receiver && use_receiver) {
- Printv(start, "p.", go_name, NULL);
- } else if (can_use_receiver && !isStatic(ni) && pi && Getattr(pi, "self")) {
- // This is an overload of a static function and a non-static
- // function.
- assert(num_required > 0);
- SwigType *tm = goWrapperType(pi, Getattr(pi, "type"), true);
- String *nm = buildGoName(Getattr(ni, "sym:name"), false, isFriend(ni));
- Printv(start, "a[0].(", tm, ").", nm, NULL);
- Delete(nm);
- Delete(tm);
- advance_parm = true;
- } else {
- Printv(start, go_name, NULL);
- }
-
- Printv(start, Getattr(ni, "sym:overname"), "(", NULL);
-
- bool need_comma = false;
-
- if (is_director && is_constructor) {
- Printv(start, "abi", NULL);
- need_comma = true;
- }
- if (is_upcall) {
- Printv(start, "p", NULL);
- need_comma = true;
- }
- Parm *p = pi;
- int pn = 0;
- if (advance_parm) {
- p = getParm(p);
- if (p) {
- p = nextParm(p);
- }
- ++pn;
- }
- while (pn < num_required) {
- p = getParm(p);
-
- if (need_comma) {
- Printv(start, ", ", NULL);
- }
-
- SwigType *tm = goType(p, Getattr(p, "type"));
- Printf(start, "a[%d].(%s)", pn, tm);
- Delete(tm);
-
- need_comma = true;
- ++pn;
- p = nextParm(p);
- }
-
- String *end = NULL;
- if (!result || SwigType_type(result) == T_VOID || (all_result && SwigType_type(all_result) == T_VOID)) {
- end = NewString("");
- Printv(end, "return", NULL);
- if (!all_result || SwigType_type(all_result) != T_VOID) {
- Printv(end, " 0", NULL);
- }
- }
-
- if (num_required == num_arguments) {
- Printv(f_go_wrappers, "\t\t", start, ")\n", NULL);
- if (end) {
- Printv(f_go_wrappers, "\t\t", end, "\n", NULL);
- }
- } else {
- Printv(f_go_wrappers, "\t\tswitch argc {\n", NULL);
- for (int j = num_required; j <= num_arguments; ++j) {
- Printf(f_go_wrappers, "\t\tcase %d:\n", j);
- Printv(f_go_wrappers, "\t\t\t", start, NULL);
- bool nc = need_comma;
- for (int k = num_required; k < j; ++k) {
- if (nc) {
- Printv(f_go_wrappers, ", ", NULL);
- }
- Printf(f_go_wrappers, "a[%d]", k);
- nc = true;
- }
- Printv(f_go_wrappers, ")\n", NULL);
- if (end) {
- Printv(f_go_wrappers, "\t\t\t", end, "\n", NULL);
- }
- }
- Printv(f_go_wrappers, "\t\t}\n", NULL);
- }
-
- Printv(f_go_wrappers, "\t}\n", NULL);
-
- if (fn != 0) {
- Printf(f_go_wrappers, "check_%d:\n", fn);
- }
-
- Delete(coll);
- }
-
- Printv(f_go_wrappers, "\tpanic(\"No match for overloaded function call\")\n", NULL);
- Printv(f_go_wrappers, "}\n\n", NULL);
-
- Delete(all_result);
- Delete(dispatch);
-
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * checkFunctionVisibility()
- *
- * Return true if we should write out a function based on its
- * visibility, false otherwise.
- * ---------------------------------------------------------------------- */
-
- bool checkFunctionVisibility(Node *n, Node *parent) {
- // Write out a public function.
- if (is_public(n))
- return true;
- // Don't write out a private function.
- if (is_private(n))
- return false;
- // Write a protected function for a director class in
- // dirprot_mode.
- if (parent == NULL) {
- return false;
- }
- if (dirprot_mode() && Swig_directorclass(parent))
- return true;
- // Otherwise don't write out a protected function.
- return false;
- }
-
-
- /* ----------------------------------------------------------------------
- * exportedName()
- *
- * Given a C/C++ name, return a name in Go which will be exported.
- * If the first character is an upper case letter, this returns a
- * copy of its argument. If the first character is a lower case
- * letter, this forces it to upper case. Otherwise, this prepends
- * 'X'.
- * ---------------------------------------------------------------------- */
-
- String *exportedName(String *name) {
- String *copy = Copy(name);
- char c = *Char(copy);
- if (islower(c)) {
- char l[2];
- char u[2];
- l[0] = c;
- l[1] = '\0';
- u[0] = toupper(c);
- u[1] = '\0';
- Replace(copy, l, u, DOH_REPLACE_FIRST);
- } else if (!isalpha(c)) {
- char l[2];
- char u[3];
- l[0] = c;
- l[1] = '\0';
- u[0] = 'X';
- u[1] = c;
- u[2] = '\0';
- Replace(copy, l, u, DOH_REPLACE_FIRST);
- }
- String *ret = Swig_name_mangle(copy);
- Delete(copy);
- return ret;
- }
-
- /* ----------------------------------------------------------------------
- * removeClassname()
- *
- * If the name starts with the current class name, followed by an
- * underscore, remove it. If there is no current class name, this
- * simply returns a copy of the name. This undoes Swig's way of
- * recording the class name in a member name.
- * ---------------------------------------------------------------------- */
-
- String *removeClassname(String *name) {
- String *copy = Copy(name);
- if (class_name) {
- char *p = Char(name);
- if (Strncmp(name, class_name, Len(class_name)) == 0 && p[Len(class_name)] == '_') {
- Replace(copy, class_name, "", DOH_REPLACE_FIRST);
- Replace(copy, "_", "", DOH_REPLACE_FIRST);
- }
- }
- return copy;
- }
-
- /* ----------------------------------------------------------------------
- * buildGoName()
- *
- * Build the name to use for an ordinary function, variable, or
- * whatever in Go. The name argument is something like the sym:name
- * attribute of the node. If is_static is false, this could be a
- * method, and the returned name will be the name of the
- * method--i.e., it will not include the class name.
- * ---------------------------------------------------------------------- */
-
- String *buildGoName(String *name, bool is_static, bool is_friend) {
- String *nw = NewString("");
- if (is_static && !is_friend && class_name) {
- String *c1 = exportedName(class_name);
- Append(nw, c1);
- Delete(c1);
- }
- String *c2 = removeClassname(name);
- String *c3 = exportedName(c2);
- Append(nw, c3);
- Delete(c2);
- Delete(c3);
- String *ret = Swig_name_mangle(nw);
- Delete(nw);
- return ret;
- }
-
- /* ----------------------------------------------------------------------
- * buildGoWrapperName()
- *
- * Build the name to use for a Go wrapper function. This is a
- * function called by the real Go function in order to convert C++
- * classes from interfaces to pointers, and other such conversions
- * between the Go type and the C++ type.
- * ---------------------------------------------------------------------- */
-
- String *buildGoWrapperName(String *name, String *overname) {
- String *s1 = NewString("_swig_wrap_");
- Append(s1, name);
- String *s2 = Swig_name_mangle(s1);
- Delete(s1);
- if (overname) {
- Append(s2, overname);
- }
- return s2;
- }
-
- /* ----------------------------------------------------------------------
- * checkNameConflict()
- *
- * Check for a name conflict on the name we are going to use in Go.
- * These conflicts are likely because of the enforced
- * capitalization. When we find one, issue a warning and return
- * false. If the name is OK, return true.
- * ---------------------------------------------------------------------- */
-
- bool checkNameConflict(String* name, Node* n, const_String_or_char_ptr scope) {
- Node *lk = symbolLookup(name, scope);
- if (lk) {
- String *n1 = Getattr(n, "sym:name");
- if (!n1) {
- n1 = Getattr(n, "name");
- }
- String *n2 = Getattr(lk, "sym:name");
- if (!n2) {
- n2 = Getattr(lk, "name");
- }
- Swig_warning(WARN_GO_NAME_CONFLICT, input_file, line_number,
- "Ignoring '%s' due to Go name ('%s') conflict with '%s'\n",
- n1, name, n2);
- return false;
- }
- bool r = addSymbol(name, n, scope) ? true : false;
- assert(r);
- (void)r;
- return true;
- }
-
- /* ----------------------------------------------------------------------
- * checkIgnoredParameters()
- *
- * If any of the parameters of this function, or the return type,
- * are ignored due to a name conflict, give a warning and return
- * false.
- * ---------------------------------------------------------------------- */
-
- bool checkIgnoredParameters(Node *n, String *go_name) {
- ParmList *parms = Getattr(n, "parms");
- if (parms) {
- Wrapper *dummy = NewWrapper();
- emit_attach_parmmaps(parms, dummy);
- int parm_count = emit_num_arguments(parms);
- Parm *p = parms;
-
- for (int i = 0; i < parm_count; ++i) {
- p = getParm(p);
- if (!checkIgnoredType(n, go_name, Getattr(p, "type"))) {
- DelWrapper(dummy);
- return false;
- }
- p = nextParm(p);
- }
-
- DelWrapper(dummy);
- }
-
- if (!checkIgnoredType(n, go_name, Getattr(n, "type"))) {
- return false;
- }
-
- return true;
- }
-
- /* ----------------------------------------------------------------------
- * checkIgnoredType()
- *
- * If this type is being ignored due to a name conflict, give a
- * warning and return false.
- * ---------------------------------------------------------------------- */
-
- bool checkIgnoredType(Node *n, String *go_name, SwigType *type) {
- if (hasGoTypemap(n, type)) {
- return true;
- }
-
- SwigType *t = SwigType_typedef_resolve_all(type);
-
- bool ret = true;
- bool is_conflict = false;
- Node *e = Language::enumLookup(t);
- if (e) {
- if (GetFlag(e, "go:conflict")) {
- is_conflict = true;
- }
- } else if (SwigType_issimple(t)) {
- Node *cn = classLookup(t);
- if (cn) {
- if (GetFlag(cn, "go:conflict")) {
- is_conflict = true;
- }
- }
- } else if (SwigType_ispointer(t) || SwigType_isarray(t) || SwigType_isqualifier(t) || SwigType_isreference(t)) {
- SwigType *r = Copy(t);
- if (SwigType_ispointer(r)) {
- SwigType_del_pointer(r);
- } else if (SwigType_isarray(r)) {
- SwigType_del_array(r);
- } else if (SwigType_isqualifier(r)) {
- SwigType_del_qualifier(r);
- } else {
- SwigType_del_reference(r);
- }
-
- if (!checkIgnoredType(n, go_name, r)) {
- ret = false;
- }
-
- Delete(r);
- }
-
- if (is_conflict) {
- String *s = SwigType_str(t, NULL);
- Swig_warning(WARN_GO_NAME_CONFLICT, input_file, line_number,
- "Ignoring '%s' (Go name '%s') due to Go name conflict for parameter or result type '%s'\n",
- Getattr(n, "name"), go_name, s);
- Delete(s);
- ret = false;
- }
-
- Delete(t);
-
- return ret;
- }
-
- /* ----------------------------------------------------------------------
- * goType()
- *
- * Given a SWIG type, return a string for the type in Go.
- * ---------------------------------------------------------------------- */
-
- String *goType(Node *n, SwigType *type) {
- return goTypeWithInfo(n, type, false, NULL);
- }
-
- /* ----------------------------------------------------------------------
- * goImType()
- *
- * Given a SWIG type, return a string for the intermediate Go type
- * to pass to C/C++. This is like goType except that it looks for
- * an imtype typemap entry first.
- * ---------------------------------------------------------------------- */
-
- String *goImType(Node *n, SwigType *type) {
- return goTypeWithInfo(n, type, true, NULL);
- }
-
- /* ----------------------------------------------------------------------
- * goTypeWithInfo()
- *
- * Like goType, but return some more information.
- *
- * If use_imtype is true, this look for a imtype typemap entry.
- *
- * If the p_is_interface parameter is not NULL, this sets
- * *p_is_interface to indicate whether this type is going to be
- * represented by a Go interface type. These are cases where the Go
- * code needs to make some adjustments when passing values back and
- * forth with C/C++.
- * ---------------------------------------------------------------------- */
-
- String *goTypeWithInfo(Node *n, SwigType *type, bool use_imtype, bool *p_is_interface) {
- if (p_is_interface) {
- *p_is_interface = false;
- }
-
- String *ret = NULL;
- if (use_imtype) {
- if (n && Cmp(type, Getattr(n, "type")) == 0) {
- if (Strcmp(Getattr(n, "nodeType"), "parm") == 0) {
- ret = Getattr(n, "tmap:imtype");
- }
- if (!ret) {
- ret = Swig_typemap_lookup("imtype", n, "", NULL);
- }
- } else {
- Parm *p = NewParm(type, "goImType", n);
- ret = Swig_typemap_lookup("imtype", p, "", NULL);
- Delete(p);
- }
- }
- if (!ret) {
- if (n && Cmp(type, Getattr(n, "type")) == 0) {
- if (Strcmp(Getattr(n, "nodeType"), "parm") == 0) {
- ret = Getattr(n, "tmap:gotype");
- }
- if (!ret) {
- ret = Swig_typemap_lookup("gotype", n, "", NULL);
- }
- } else {
- Parm *p = NewParm(type, "goType", n);
- ret = Swig_typemap_lookup("gotype", p, "", NULL);
- Delete(p);
- }
- }
-
- if (ret && Strstr(ret, "$gotypename") != 0) {
- ret = NULL;
- }
-
- if (ret) {
- return Copy(ret);
- }
-
- SwigType *t = SwigType_typedef_resolve_all(type);
-
- if (SwigType_isenum(t)) {
- Node *e = Language::enumLookup(t);
- if (e) {
- ret = goEnumName(e);
- } else if (Strcmp(t, "enum ") == 0) {
- ret = NewString("int");
- } else {
- // An unknown enum - one that has not been parsed (neither a C enum forward reference nor a definition) or an ignored enum
- String *tt = Copy(t);
- Replace(tt, "enum ", "", DOH_REPLACE_ANY);
- ret = exportedName(tt);
- Setattr(undefined_enum_types, t, ret);
- Delete(tt);
- }
- } else if (SwigType_isfunctionpointer(t) || SwigType_isfunction(t)) {
- ret = NewString("_swig_fnptr");
- } else if (SwigType_ismemberpointer(t)) {
- ret = NewString("_swig_memberptr");
- } else if (SwigType_issimple(t)) {
- Node *cn = classLookup(t);
- if (cn) {
- ret = Getattr(cn, "sym:name");
- if (!ret) {
- ret = Getattr(cn, "name");
- }
- ret = exportedName(ret);
-
- Node *cnmod = Getattr(cn, "module");
- if (!cnmod || Strcmp(Getattr(cnmod, "name"), module) == 0) {
- Setattr(undefined_types, t, t);
- } else {
- String *nw = NewString("");
- Printv(nw, getModuleName(Getattr(cnmod, "name")), ".", ret, NULL);
- Delete(ret);
- ret = nw;
- }
- } else {
- // SWIG does not know about this type.
- ret = exportedName(t);
- Setattr(undefined_types, t, t);
- }
- if (p_is_interface) {
- *p_is_interface = true;
- }
- } else if (SwigType_ispointer(t) || SwigType_isarray(t)) {
- SwigType *r = Copy(t);
- if (SwigType_ispointer(r)) {
- SwigType_del_pointer(r);
- } else {
- SwigType_del_array(r);
- }
-
- if (SwigType_type(r) == T_VOID) {
- ret = NewString("uintptr");
- } else {
- bool is_interface;
- String *base = goTypeWithInfo(n, r, false, &is_interface);
-
- // At the Go level, an unknown or class type is handled as an
- // interface wrapping a pointer. This means that if a
- // function returns the C type X, we will be wrapping the C
- // type X*. In Go we will call that type X. That means that
- // if a C function expects X*, we can pass the Go type X. And
- // that means that when we see the C type X*, we should use
- // the Go type X.
-
- // The is_interface variable tells us this. However, it will
- // be true both for the case of X and for the case of X*. If
- // r is a pointer here, then we are looking at X**. There is
- // really no good way for us to handle that.
- bool is_pointer_to_pointer = false;
- if (is_interface) {
- SwigType *c = Copy(r);
- if (SwigType_isqualifier(c)) {
- SwigType_del_qualifier(c);
- if (SwigType_ispointer(c) || SwigType_isarray(c)) {
- is_pointer_to_pointer = true;
- }
- }
- Delete(c);
- }
-
- if (is_interface) {
- if (!is_pointer_to_pointer) {
- ret = base;
- if (p_is_interface) {
- *p_is_interface = true;
- }
- } else {
- ret = NewString("uintptr");
- }
- } else {
- ret = NewString("*");
- Append(ret, base);
- Delete(base);
- }
- }
-
- Delete(r);
- } else if (SwigType_isreference(t)) {
- SwigType *r = Copy(t);
- SwigType_del_reference(r);
-
- // If this is a const reference, and we are looking at a pointer
- // to it, then we just use the pointer we already have.
- bool add_pointer = true;
- if (SwigType_isqualifier(r)) {
- String *q = SwigType_parm(r);
- if (Strcmp(q, "const") == 0) {
- SwigType *c = Copy(r);
- SwigType_del_qualifier(c);
- if (SwigType_ispointer(c)) {
- add_pointer = false;
- }
- Delete(c);
- }
- }
- if (add_pointer) {
- SwigType_add_pointer(r);
- }
- ret = goTypeWithInfo(n, r, false, p_is_interface);
- Delete(r);
- } else if (SwigType_isqualifier(t)) {
- SwigType *r = Copy(t);
- SwigType_del_qualifier(r);
- ret = goTypeWithInfo(n, r, false, p_is_interface);
- Delete(r);
- } else if (SwigType_isvarargs(t)) {
- ret = NewString("[]interface{}");
- }
-
- Delete(t);
-
- if (!ret) {
- Swig_warning(WARN_LANG_NATIVE_UNIMPL, input_file, line_number, "No Go typemap defined for %s\n", SwigType_str(type, 0));
- ret = NewString("uintptr");
- }
-
- return ret;
- }
-
- /* ----------------------------------------------------------------------
- * cgoTypeForGoValue()
- *
- * Given a SWIG type, return a string for the C type to use for the
- * cgo wrapper code. This always returns a simple identifier, since
- * it is used in Go code as C.name.
- *
- * This sets *c_struct_type if the C type uses a struct where the Go
- * type uses a simple type. This is true for strings and slices.
- * When this is true the Go code has to jump through unsafe hoops to
- * pass the type checker.
- * ---------------------------------------------------------------------- */
-
- String *cgoTypeForGoValue(Node *n, SwigType *type, bool *c_struct_type) {
- *c_struct_type = false;
-
- bool is_interface;
- String *go_type = goTypeWithInfo(n, type, true, &is_interface);
- if (is_interface) {
- Delete(go_type);
- return NewString("uintptr_t");
- }
- if (Strcmp(go_type, "uintptr") == 0) {
- Delete(go_type);
- return NewString("uintptr_t");
- }
- if (((char*)Char(go_type))[0] == '*') {
- // Treat all pointers as void*. There is no meaningful type
- // checking going on here anyhow, and that lets us avoid
- // worrying about defining the base type of the pointer.
- Delete(go_type);
- return NewString("swig_voidp");
- }
-
- // Check for some Go types that are really pointers under the covers.
- bool is_hidden_pointer = Strncmp(go_type, "func(", 5) == 0 || Strncmp(go_type, "map[", 4) == 0 || Strncmp(go_type, "chan ", 5) == 0;
-
- Delete(go_type);
-
- String *ct = Getattr(n, "emit:cgotype");
- if (ct) {
- *c_struct_type = Getattr(n, "emit:cgotypestruct") ? true : false;
- return Copy(ct);
- }
-
- String *t = Copy(type);
- if (SwigType_isarray(t) && Getattr(n, "tmap:gotype") == NULL) {
- SwigType_del_array(t);
- SwigType_add_pointer(t);
- }
-
- bool add_typedef = true;
-
- static int count;
- ++count;
- ct = NewStringf("swig_type_%d", count);
-
- String *gct = gcCTypeForGoValue(n, t, ct);
- Delete(t);
-
- if (Strncmp(gct, "_gostring_", 10) == 0 || Strncmp(gct, "_goslice_", 9) == 0) {
- *c_struct_type = true;
- Setattr(n, "emit:cgotypestruct", type);
- } else {
- char *p = Strstr(gct, ct);
- if (p != NULL && p > (char*)Char(gct) && p[-1] == '*' && p[Len(ct)] == '\0') {
- // Treat all pointers as void*. See above.
- Delete(ct);
- --count;
- ct = NewString("swig_voidp");
- add_typedef = false;
- if (is_hidden_pointer) {
- // A Go type that is really a pointer, like func, map, chan,
- // is being represented in C by a pointer. This is fine,
- // but we have to memcpy the type rather than simply
- // converting it.
- *c_struct_type = true;
- Setattr(n, "emit:cgotypestruct", type);
- }
- }
-
- if (Strncmp(gct, "bool ", 5) == 0) {
- // Change the C++ type bool to the C type _Bool.
- Replace(gct, "bool", "_Bool", DOH_REPLACE_FIRST);
- }
- if (Strncmp(gct, "intgo ", 6) == 0) {
- // We #define intgo to swig_intgo for the cgo comment.
- Replace(gct, "intgo", "swig_intgo", DOH_REPLACE_FIRST);
- }
- p = Strstr(gct, ct);
- if (p != NULL && p > (char*)Char(gct) && p[-1] == ' ' && p[Len(ct)] == '\0') {
- String *q = NewStringWithSize(gct, Len(gct) - Len(ct) - 1);
- if (validIdentifier(q)) {
- // This is a simple type name, and we can use it directly.
- Delete(ct);
- --count;
- ct = q;
- add_typedef = false;
- }
- }
- }
- if (add_typedef) {
- Printv(f_cgo_comment_typedefs, "typedef ", gct, ";\n", NULL);
- }
-
- Setattr(n, "emit:cgotype", ct);
-
- Delete(gct);
-
- return Copy(ct);
- }
-
- /* ----------------------------------------------------------------------
- * goWrapperType()
- *
- * Given a type, return a string for the type to use for the wrapped
- * Go function. This function exists because for a C++ class we
- * need to convert interface and reference types.
- * ---------------------------------------------------------------------- */
-
- String *goWrapperType(Node *n, SwigType *type, bool is_result) {
- bool is_interface;
- String *ret = goTypeWithInfo(n, type, true, &is_interface);
-
- // If this is an interface, we want to pass the real type.
- if (is_interface) {
- Delete(ret);
- if (!is_result) {
- ret = NewString("uintptr");
- } else {
- SwigType *ty = SwigType_typedef_resolve_all(type);
- while (true) {
- if (SwigType_ispointer(ty)) {
- SwigType_del_pointer(ty);
- } else if (SwigType_isarray(ty)) {
- SwigType_del_array(ty);
- } else if (SwigType_isreference(ty)) {
- SwigType_del_reference(ty);
- } else if (SwigType_isqualifier(ty)) {
- SwigType_del_qualifier(ty);
- } else {
- break;
- }
- }
- assert(SwigType_issimple(ty));
- String *p = goCPointerType(ty, true);
- Delete(ty);
- ret = p;
- }
- }
-
- return ret;
- }
-
- /* ----------------------------------------------------------------------
- * goOverloadType()
- *
- * Given a type, return the Go type to use when dispatching of
- * overloaded functions. This is normally just the usual Go type.
- * However, for a C++ class, the usual Go type is an interface type.
- * And if that interface type represents a C++ type that SWIG does
- * not know about, then the interface type generated for any C++
- * class will match that interface. So for that case, we match on
- * the underlying integer type.
- *
- * It has to work this way so that we can handle a derived type of a
- * %ignore'd type. It's unlikely that anybody will have a value of
- * an undefined type, but we support it because it worked in the
- * past.
- * ---------------------------------------------------------------------- */
-
- String *goOverloadType(Node *n, SwigType *type) {
- SwigType *ty = SwigType_typedef_resolve_all(type);
- while (true) {
- if (SwigType_ispointer(ty)) {
- SwigType_del_pointer(ty);
- } else if (SwigType_isarray(ty)) {
- SwigType_del_array(ty);
- } else if (SwigType_isreference(ty)) {
- SwigType_del_reference(ty);
- } else if (SwigType_isqualifier(ty)) {
- SwigType_del_qualifier(ty);
- } else {
- break;
- }
- }
-
- String* go_type = goType(n, ty);
-
- if (Getattr(undefined_types, ty) && !Getattr(defined_types, go_type)) {
- Delete(go_type);
- return goWrapperType(n, type, true);
- }
-
- Delete(go_type);
- return goType(n, type);
- }
-
- /* ----------------------------------------------------------------------
- * goCPointerType()
- *
- * Return the name of the Go type to use for the C pointer value.
- * The regular C type is the name of an interface type which wraps a
- * pointer whose name is returned by this function.
- * ---------------------------------------------------------------------- */
-
- String *goCPointerType(SwigType *type, bool add_to_hash) {
- SwigType *ty = SwigType_typedef_resolve_all(type);
- Node *cn = classLookup(ty);
- String *ex;
- String *ret;
- if (!cn) {
- if (add_to_hash) {
- Setattr(undefined_types, ty, ty);
- }
- ret = NewString("Swigcptr");
- ex = exportedName(ty);
- Append(ret, ex);
- } else {
- String *cname = Getattr(cn, "sym:name");
- if (!cname) {
- cname = Getattr(cn, "name");
- }
- ex = exportedName(cname);
- Node *cnmod = Getattr(cn, "module");
- if (!cnmod || Strcmp(Getattr(cnmod, "name"), module) == 0) {
- if (add_to_hash) {
- Setattr(undefined_types, ty, ty);
- }
- ret = NewString("Swigcptr");
- Append(ret, ex);
- } else {
- ret = NewString("");
- Printv(ret, getModuleName(Getattr(cnmod, "name")), ".Swigcptr", ex, NULL);
- }
- }
- Delete(ty);
- Delete(ex);
- return ret;
- }
-
- /* ----------------------------------------------------------------------
- * gcCTypeForGoValue()
- *
- * Given a type, return the C/C++ type which will be used to catch
- * the value in Go. This is the gc version.
- * ---------------------------------------------------------------------- */
-
- String *gcCTypeForGoValue(Node *n, SwigType *type, String *name) {
- bool is_interface;
- String *gt = goTypeWithInfo(n, type, true, &is_interface);
-
- String *tail = NewString("");
- SwigType *t = SwigType_typedef_resolve_all(type);
- bool is_const_ref = false;
- if (SwigType_isreference(t)) {
- SwigType* tt = Copy(t);
- SwigType_del_reference(tt);
- if (SwigType_isqualifier(tt)) {
- String* q = SwigType_parm(tt);
- if (Strcmp(q, "const") == 0) {
- is_const_ref = true;
- }
- }
- Delete(tt);
- }
- if (!is_const_ref) {
- while (Strncmp(gt, "*", 1) == 0) {
- Replace(gt, "*", "", DOH_REPLACE_FIRST);
- Printv(tail, "*", NULL);
- }
- }
- Delete(t);
-
- bool is_string = Strcmp(gt, "string") == 0;
- bool is_slice = Strncmp(gt, "[]", 2) == 0;
- bool is_function = Strcmp(gt, "_swig_fnptr") == 0;
- bool is_member = Strcmp(gt, "_swig_memberptr") == 0;
- bool is_complex64 = Strcmp(gt, "complex64") == 0;
- bool is_complex128 = Strcmp(gt, "complex128") == 0;
- bool is_bool = false;
- bool is_int8 = false;
- bool is_int16 = false;
- bool is_int = Strcmp(gt, "int") == 0 || Strcmp(gt, "uint") == 0;
- bool is_int32 = false;
- bool is_int64 = false;
- bool is_float32 = false;
- bool is_float64 = false;
-
- bool has_typemap = (n != NULL && Getattr(n, "tmap:gotype") != NULL) || hasGoTypemap(n, type);
- if (has_typemap) {
- is_bool = Strcmp(gt, "bool") == 0;
- is_int8 = Strcmp(gt, "int8") == 0 || Strcmp(gt, "uint8") == 0 || Strcmp(gt, "byte") == 0;
- is_int16 = Strcmp(gt, "int16") == 0 || Strcmp(gt, "uint16") == 0;
- is_int32 = Strcmp(gt, "int32") == 0 || Strcmp(gt, "uint32") == 0;
- is_int64 = Strcmp(gt, "int64") == 0 || Strcmp(gt, "uint64") == 0;
- is_float32 = Strcmp(gt, "float32") == 0;
- is_float64 = Strcmp(gt, "float64") == 0;
- }
- Delete(gt);
-
- String *ret;
- if (is_string) {
- // Note that we don't turn a reference to a string into a
- // pointer to a string. Strings are immutable anyhow.
- ret = NewString("");
- Printv(ret, "_gostring_", tail, " ", name, NULL);
- Delete(tail);
- return ret;
- } else if (is_slice) {
- // Slices are always passed as a _goslice_, whether or not references
- // are involved.
- ret = NewString("");
- Printv(ret, "_goslice_", tail, " ", name, NULL);
- Delete(tail);
- return ret;
- } else if (is_function || is_member) {
- ret = NewString("");
- Printv(ret, "void*", tail, " ", name, NULL);
- Delete(tail);
- return ret;
- } else if (is_complex64) {
- ret = NewString("_Complex float ");
- } else if (is_complex128) {
- ret = NewString("_Complex double ");
- } else if (is_interface) {
- SwigType *t = SwigType_typedef_resolve_all(type);
- if (SwigType_ispointer(t)) {
- SwigType_del_pointer(t);
- }
- if (SwigType_isreference(t)) {
- SwigType_del_reference(t);
- }
- SwigType_add_pointer(t);
- ret = SwigType_lstr(t, name);
- Delete(t);
- Delete(tail);
- return ret;
- } else {
- SwigType *t = SwigType_typedef_resolve_all(type);
- if (!has_typemap && SwigType_isreference(t)) {
- // A const reference to a known type, or to a pointer, is not
- // mapped to a pointer.
- SwigType_del_reference(t);
- if (SwigType_isqualifier(t)) {
- String *q = SwigType_parm(t);
- if (Strcmp(q, "const") == 0) {
- SwigType_del_qualifier(t);
- if (hasGoTypemap(n, t) || SwigType_ispointer(t)) {
- if (is_int) {
- ret = NewString("intgo ");
- Append(ret, name);
- } else if (is_int64) {
- ret = NewString("long long ");
- Append(ret, name);
- } else {
- ret = SwigType_lstr(t, name);
- }
- Delete(q);
- Delete(t);
- Delete(tail);
- return ret;
- }
- }
- Delete(q);
- }
- }
-
- if (Language::enumLookup(t) != NULL) {
- is_int = true;
- } else {
- SwigType *tstripped = SwigType_strip_qualifiers(t);
- if (SwigType_isenum(tstripped))
- is_int = true;
- Delete(tstripped);
- }
-
- Delete(t);
- if (is_bool) {
- ret = NewString("bool ");
- } else if (is_int8) {
- ret = NewString("char ");
- } else if (is_int16) {
- ret = NewString("short ");
- } else if (is_int) {
- ret = NewString("intgo ");
- } else if (is_int32) {
- ret = NewString("int ");
- } else if (is_int64) {
- ret = NewString("long long ");
- } else if (is_float32) {
- ret = NewString("float ");
- } else if (is_float64) {
- ret = NewString("double ");
- } else {
- Delete(tail);
- return SwigType_lstr(type, name);
- }
- }
-
- Append(ret, tail);
- if (!has_typemap && SwigType_isreference(type)) {
- Append(ret, "* ");
- }
- Append(ret, name);
- Delete(tail);
- return ret;
- }
-
- /* ----------------------------------------------------------------------
- * goTypeIsInterface
- *
- * Return whether this C++ type is represented as an interface type
- * in Go. These types require adjustments in the Go code when
- * passing them back and forth between Go and C++.
- * ---------------------------------------------------------------------- */
-
- bool goTypeIsInterface(Node *n, SwigType *type) {
- bool is_interface;
- Delete(goTypeWithInfo(n, type, false, &is_interface));
- return is_interface;
- }
-
- /* ----------------------------------------------------------------------
- * hasGoTypemap
- *
- * Return whether a type has a "gotype" typemap entry.
- * ---------------------------------------------------------------------- */
-
- bool hasGoTypemap(Node *n, SwigType *type) {
- Parm *p = NewParm(type, "test", n);
- SwigType *tm = Swig_typemap_lookup("gotype", p, "", NULL);
- Delete(p);
- if (tm && Strstr(tm, "$gotypename") == 0) {
- Delete(tm);
- return true;
- }
- Delete(tm);
- return false;
- }
-
- /* ----------------------------------------------------------------------
- * goEnumName()
- *
- * Given an enum node, return a string to use for the enum type in Go.
- * ---------------------------------------------------------------------- */
-
- String *goEnumName(Node *n) {
- String *ret = Getattr(n, "go:enumname");
- if (ret) {
- return Copy(ret);
- }
-
- if (Equal(Getattr(n, "type"), "enum ")) {
- return NewString("int");
- }
-
- String *type = Getattr(n, "enumtype");
- assert(type);
- char *p = Char(type);
- int len = Len(type);
- String *s = NewString("");
- bool capitalize = true;
- for (int i = 0; i < len; ++i, ++p) {
- if (*p == ':') {
- ++i;
- ++p;
- assert(*p == ':');
- capitalize = true;
- } else if (capitalize) {
- Putc(toupper(*p), s);
- capitalize = false;
- } else {
- Putc(*p, s);
- }
- }
-
- ret = Swig_name_mangle(s);
- Delete(s);
- return ret;
- }
-
-
- /* ----------------------------------------------------------------------
- * getParm()
- *
- * Get the real parameter to use.
- * ---------------------------------------------------------------------- */
-
- Parm *getParm(Parm *p) {
- while (p && checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- }
- return p;
- }
-
- /* ----------------------------------------------------------------------
- * nextParm()
- *
- * Return the next parameter.
- * ---------------------------------------------------------------------- */
-
- Parm *nextParm(Parm *p) {
- if (!p) {
- return NULL;
- } else if (Getattr(p, "tmap:in")) {
- return Getattr(p, "tmap:in:next");
- } else {
- return nextSibling(p);
- }
- }
-
- /* ----------------------------------------------------------------------
- * isStatic
- *
- * Return whether a node should be considered as static rather than
- * as a member.
- * ---------------------------------------------------------------------- */
-
- bool isStatic(Node *n) {
- String *storage = Getattr(n, "storage");
- return (storage && (Swig_storage_isstatic(n) || Strcmp(storage, "friend") == 0) && (!SmartPointer || !Getattr(n, "allocate:smartpointeraccess")));
- }
-
- /* ----------------------------------------------------------------------
- * isFriend
- *
- * Return whether a node is a friend.
- * ---------------------------------------------------------------------- */
-
- bool isFriend(Node *n) {
- String *storage = Getattr(n, "storage");
- return storage && Strcmp(storage, "friend") == 0;
- }
-
- /* ----------------------------------------------------------------------
- * goGetattr
- *
- * Fetch an attribute from a node but return NULL if it is the empty string.
- * ---------------------------------------------------------------------- */
- Node *goGetattr(Node *n, const char *name) {
- Node *ret = Getattr(n, name);
- if (ret != NULL && Len(ret) == 0) {
- ret = NULL;
- }
- return ret;
- }
-
- /* ----------------------------------------------------------------------
- * goTypemapLookup
- *
- * Look up a typemap but return NULL if it is the empty string.
- * ---------------------------------------------------------------------- */
- String *goTypemapLookup(const char *name, Node *node, const char *lname) {
- String *ret = Swig_typemap_lookup(name, node, lname, NULL);
- if (ret != NULL && Len(ret) == 0) {
- ret = NULL;
- }
- return ret;
- }
-
- /* ----------------------------------------------------------------------
- * getModuleName
- *
- * Return the name of a module. This is different from module path:
- * "some/path/to/module" -> "module".
- * ---------------------------------------------------------------------- */
-
- String *getModuleName(String *module_path) {
- char *suffix = strrchr(Char(module_path), '/');
- if (suffix == NULL) {
- return module_path;
- }
- return Str(suffix + 1);
- }
-
-}; /* class GO */
-
-/* -----------------------------------------------------------------------------
- * swig_go() - Instantiate module
- * ----------------------------------------------------------------------------- */
-
-static Language *new_swig_go() {
- return new GO();
-}
-extern "C" Language *swig_go(void) {
- return new_swig_go();
-}
-
-/* -----------------------------------------------------------------------------
- * Static member variables
- * ----------------------------------------------------------------------------- */
-
-// Usage message.
-const char * const GO::usage = "\
-Go Options (available with -go)\n\
- -cgo - Generate cgo input files\n\
- -no-cgo - Do not generate cgo input files\n\
- -gccgo - Generate code for gccgo rather than gc\n\
- -go-pkgpath <p> - Like gccgo -fgo-pkgpath option\n\
- -go-prefix <p> - Like gccgo -fgo-prefix option\n\
- -import-prefix <p> - Prefix to add to %import directives\n\
- -intgosize <s> - Set size of Go int type--32 or 64 bits\n\
- -package <name> - Set name of the Go package to <name>\n\
- -use-shlib - Force use of a shared library\n\
- -soname <name> - Set shared library holding C/C++ code to <name>\n\
-\n";
diff --git a/contrib/tools/swig/Source/Modules/guile.cxx b/contrib/tools/swig/Source/Modules/guile.cxx
deleted file mode 100644
index 605e031975..0000000000
--- a/contrib/tools/swig/Source/Modules/guile.cxx
+++ /dev/null
@@ -1,1662 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * guile.cxx
- *
- * Guile language module for SWIG.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include <ctype.h>
-
-// Note string broken in half for compilers that can't handle long strings
-static const char *usage = "\
-Guile Options (available with -guile)\n\
- -emitsetters - Emit procedures-with-setters for variables\n\
- and structure slots.\n\
- -emitslotaccessors - Emit accessor methods for all GOOPS slots\n" "\
- -exportprimitive - Add the (export ...) code from scmstub into the\n\
- GOOPS file.\n\
- -goopsprefix <prefix> - Prepend <prefix> to all goops identifiers\n\
- -Linkage <lstyle> - Use linkage protocol <lstyle> (default `simple')\n\
- Use `module' for native Guile module linking\n\
- (requires Guile >= 1.5.0). Use `passive' for\n\
- passive linking (no C-level module-handling code),\n\
- `ltdlmod' for Guile's old dynamic module\n\
- convention (Guile <= 1.4), or `hobbit' for hobbit\n\
- modules.\n\
- -onlysetters - Don't emit traditional getter and setter\n\
- procedures for structure slots,\n\
- only emit procedures-with-setters.\n\
- -package <name> - Set the path of the module to <name>\n\
- (default NULL)\n\
- -prefix <name> - Use <name> as prefix [default \"gswig_\"]\n\
- -procdoc <file> - Output procedure documentation to <file>\n\
- -procdocformat <format> - Output procedure documentation in <format>;\n\
- one of `guile-1.4', `plain', `texinfo'\n\
- -proxy - Export GOOPS class definitions\n\
- -primsuffix <suffix> - Name appended to primitive module when exporting\n\
- GOOPS classes. (default = \"primitive\")\n\
- -scmstub - Output Scheme file with module declaration and\n\
- exports; only with `passive' and `simple' linkage\n\
- -useclassprefix - Prepend the class name to all goops identifiers\n\
-\n";
-
-static File *f_begin = 0;
-static File *f_runtime = 0;
-static File *f_header = 0;
-static File *f_wrappers = 0;
-static File *f_init = 0;
-
-
-static String *prefix = NewString("gswig_");
-static char *module = 0;
-static String *package = 0;
-static enum {
- GUILE_LSTYLE_SIMPLE, // call `SWIG_init()'
- GUILE_LSTYLE_PASSIVE, // passive linking (no module code)
- GUILE_LSTYLE_MODULE, // native guile module linking (Guile >= 1.4.1)
- GUILE_LSTYLE_LTDLMOD_1_4, // old (Guile <= 1.4) dynamic module convention
- GUILE_LSTYLE_HOBBIT // use (hobbit4d link)
-} linkage = GUILE_LSTYLE_SIMPLE;
-
-static File *procdoc = 0;
-static bool scmstub = false;
-static String *scmtext;
-static bool goops = false;
-static String *goopstext;
-static String *goopscode;
-static String *goopsexport;
-
-static enum {
- GUILE_1_4,
- PLAIN,
- TEXINFO
-} docformat = GUILE_1_4;
-
-static int emit_setters = 0;
-static int only_setters = 0;
-static int emit_slot_accessors = 0;
-static int struct_member = 0;
-
-static String *beforereturn = 0;
-static String *return_nothing_doc = 0;
-static String *return_one_doc = 0;
-static String *return_multi_doc = 0;
-
-static String *exported_symbols = 0;
-
-static int exporting_destructor = 0;
-static String *swigtype_ptr = 0;
-
-/* GOOPS stuff */
-static String *primsuffix = 0;
-static String *class_name = 0;
-static String *short_class_name = 0;
-static String *goops_class_methods;
-static int in_class = 0;
-static int have_constructor = 0;
-static int useclassprefix = 0; // -useclassprefix argument
-static String *goopsprefix = 0; // -goopsprefix argument
-static int primRenamer = 0; // if (use-modules ((...) :renamer ...) is exported to GOOPS file
-static int exportprimitive = 0; // -exportprimitive argument
-static String *memberfunction_name = 0;
-
-extern "C" {
- static int has_classname(Node *class_node) {
- return Getattr(class_node, "guile:goopsclassname") ? 1 : 0;
- }
-}
-
-class GUILE:public Language {
-public:
-
- /* ------------------------------------------------------------
- * main()
- * ------------------------------------------------------------ */
-
- virtual void main(int argc, char *argv[]) {
- int i;
-
- SWIG_library_directory("guile");
- SWIG_typemap_lang("guile");
-
- // Look for certain command line options
- for (i = 1; i < argc; i++) {
- if (argv[i]) {
- if (strcmp(argv[i], "-help") == 0) {
- fputs(usage, stdout);
- Exit(EXIT_SUCCESS);
- } else if (strcmp(argv[i], "-prefix") == 0) {
- if (argv[i + 1]) {
- prefix = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-package") == 0) {
- if (argv[i + 1]) {
- package = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-Linkage") == 0 || strcmp(argv[i], "-linkage") == 0) {
- if (argv[i + 1]) {
- if (0 == strcmp(argv[i + 1], "ltdlmod"))
- linkage = GUILE_LSTYLE_LTDLMOD_1_4;
- else if (0 == strcmp(argv[i + 1], "hobbit"))
- linkage = GUILE_LSTYLE_HOBBIT;
- else if (0 == strcmp(argv[i + 1], "simple"))
- linkage = GUILE_LSTYLE_SIMPLE;
- else if (0 == strcmp(argv[i + 1], "passive"))
- linkage = GUILE_LSTYLE_PASSIVE;
- else if (0 == strcmp(argv[i + 1], "module"))
- linkage = GUILE_LSTYLE_MODULE;
- else
- Swig_arg_error();
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-procdoc") == 0) {
- if (argv[i + 1]) {
- procdoc = NewFile(argv[i + 1], "w", SWIG_output_files());
- if (!procdoc) {
- FileErrorDisplay(argv[i + 1]);
- Exit(EXIT_FAILURE);
- }
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-procdocformat") == 0) {
- if (strcmp(argv[i + 1], "guile-1.4") == 0)
- docformat = GUILE_1_4;
- else if (strcmp(argv[i + 1], "plain") == 0)
- docformat = PLAIN;
- else if (strcmp(argv[i + 1], "texinfo") == 0)
- docformat = TEXINFO;
- else
- Swig_arg_error();
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else if (strcmp(argv[i], "-emit-setters") == 0 || strcmp(argv[i], "-emitsetters") == 0) {
- emit_setters = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-only-setters") == 0 || strcmp(argv[i], "-onlysetters") == 0) {
- emit_setters = 1;
- only_setters = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-emit-slot-accessors") == 0 || strcmp(argv[i], "-emitslotaccessors") == 0) {
- emit_slot_accessors = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-scmstub") == 0) {
- scmstub = true;
- Swig_mark_arg(i);
- } else if ((strcmp(argv[i], "-shadow") == 0) || ((strcmp(argv[i], "-proxy") == 0))) {
- goops = true;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-gh") == 0) {
- Printf(stderr, "Deprecated command line option: -gh. Wrappers are always generated for the SCM interface. See documentation for more information regarding the deprecated GH interface.\n");
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-scm") == 0) {
- Printf(stderr, "Deprecated command line option: -scm. Wrappers are always generated for the SCM interface. See documentation for more information regarding the deprecated GH interface.\n");
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-primsuffix") == 0) {
- if (argv[i + 1]) {
- primsuffix = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-goopsprefix") == 0) {
- if (argv[i + 1]) {
- goopsprefix = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-useclassprefix") == 0) {
- useclassprefix = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-exportprimitive") == 0) {
- exportprimitive = 1;
- // should use Swig_warning() here?
- Swig_mark_arg(i);
- }
- }
- }
-
- // set default value for primsuffix
- if (!primsuffix)
- primsuffix = NewString("primitive");
-
- //goops support can only be enabled if passive or module linkage is used
- if (goops) {
- if (linkage != GUILE_LSTYLE_PASSIVE && linkage != GUILE_LSTYLE_MODULE) {
- Printf(stderr, "guile: GOOPS support requires passive or module linkage\n");
- Exit(EXIT_FAILURE);
- }
- }
-
- if (goops) {
- // -proxy implies -emit-setters
- emit_setters = 1;
- }
-
- if ((linkage == GUILE_LSTYLE_PASSIVE && scmstub) || linkage == GUILE_LSTYLE_MODULE)
- primRenamer = 1;
-
- if (exportprimitive && primRenamer) {
- // should use Swig_warning() ?
- Printf(stderr, "guile: Warning: -exportprimitive only makes sense with passive linkage without a scmstub.\n");
- }
-
- // Make sure `prefix' ends in an underscore
- if (prefix) {
- const char *px = Char(prefix);
- if (px[Len(prefix) - 1] != '_')
- Printf(prefix, "_");
- }
-
- /* Add a symbol for this module */
- Preprocessor_define("SWIGGUILE 1", 0);
- /* Read in default typemaps */
- SWIG_config_file("guile_scm.swg");
- allow_overloading();
-
- }
-
- /* ------------------------------------------------------------
- * top()
- * ------------------------------------------------------------ */
-
- virtual int top(Node *n) {
- /* Initialize all of the output files */
- String *outfile = Getattr(n, "outfile");
-
- f_begin = NewFile(outfile, "w", SWIG_output_files());
- if (!f_begin) {
- FileErrorDisplay(outfile);
- Exit(EXIT_FAILURE);
- }
- f_runtime = NewString("");
- f_init = NewString("");
- f_header = NewString("");
- f_wrappers = NewString("");
-
- /* Register file targets with the SWIG file handler */
- Swig_register_filebyname("header", f_header);
- Swig_register_filebyname("wrapper", f_wrappers);
- Swig_register_filebyname("begin", f_begin);
- Swig_register_filebyname("runtime", f_runtime);
- Swig_register_filebyname("init", f_init);
-
- scmtext = NewString("");
- Swig_register_filebyname("scheme", scmtext);
- exported_symbols = NewString("");
- goopstext = NewString("");
- Swig_register_filebyname("goops", goopstext);
- goopscode = NewString("");
- goopsexport = NewString("");
-
- Swig_banner(f_begin);
-
- Swig_obligatory_macros(f_runtime, "GUILE");
-
- /* Write out directives and declarations */
-
- module = Swig_copy_string(Char(Getattr(n, "name")));
-
- switch (linkage) {
- case GUILE_LSTYLE_SIMPLE:
- /* Simple linkage; we have to export the SWIG_init function. The user can
- rename the function by a #define. */
- Printf(f_runtime, "#define SWIG_GUILE_INIT_STATIC extern\n");
- break;
- default:
- /* Other linkage; we make the SWIG_init function static */
- Printf(f_runtime, "#define SWIG_GUILE_INIT_STATIC static\n");
- break;
- }
-
- if (CPlusPlus) {
- Printf(f_runtime, "extern \"C\" {\n\n");
- }
- Printf(f_runtime, "SWIG_GUILE_INIT_STATIC void\nSWIG_init (void);\n");
- if (CPlusPlus) {
- Printf(f_runtime, "\n}\n");
- }
-
- Printf(f_runtime, "\n");
-
- Language::top(n);
-
- /* Close module */
-
- Printf(f_wrappers, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
-
- SwigType_emit_type_table(f_runtime, f_wrappers);
-
- Printf(f_init, "}\n\n");
- Printf(f_init, "#ifdef __cplusplus\n}\n#endif\n");
-
- String *module_name = NewString("");
-
- if (!module)
- Printv(module_name, "swig", NIL);
- else {
- if (package)
- Printf(module_name, "%s/%s", package, module);
- else
- Printv(module_name, module, NIL);
- }
- emit_linkage(module_name);
-
- Delete(module_name);
-
- if (procdoc) {
- Delete(procdoc);
- procdoc = NULL;
- }
- Delete(goopscode);
- Delete(goopsexport);
- Delete(goopstext);
-
- /* Close all of the files */
- Dump(f_runtime, f_begin);
- Dump(f_header, f_begin);
- Dump(f_wrappers, f_begin);
- Wrapper_pretty_print(f_init, f_begin);
- Delete(f_header);
- Delete(f_wrappers);
- Delete(f_init);
- Delete(f_runtime);
- Delete(f_begin);
- return SWIG_OK;
- }
-
- void emit_linkage(String *module_name) {
- String *module_func = NewString("");
-
- if (CPlusPlus) {
- Printf(f_init, "extern \"C\" {\n\n");
- }
-
- Printv(module_func, module_name, NIL);
- Replaceall(module_func, "-", "_");
-
- switch (linkage) {
- case GUILE_LSTYLE_SIMPLE:
- Printf(f_init, "\n/* Linkage: simple */\n");
- break;
- case GUILE_LSTYLE_PASSIVE:
- Printf(f_init, "\n/* Linkage: passive */\n");
- Replaceall(module_func, "/", "_");
- Insert(module_func, 0, "scm_init_");
- Append(module_func, "_module");
-
- Printf(f_init, "SCM\n%s (void)\n{\n", module_func);
- Printf(f_init, " SWIG_init();\n");
- Printf(f_init, " return SCM_UNSPECIFIED;\n");
- Printf(f_init, "}\n");
- break;
- case GUILE_LSTYLE_LTDLMOD_1_4:
- Printf(f_init, "\n/* Linkage: ltdlmod */\n");
- Replaceall(module_func, "/", "_");
- Insert(module_func, 0, "scm_init_");
- Append(module_func, "_module");
- Printf(f_init, "SCM\n%s (void)\n{\n", module_func);
- {
- String *mod = NewString(module_name);
- Replaceall(mod, "/", " ");
- Printf(f_init, " scm_register_module_xxx (\"%s\", (void *) SWIG_init);\n", mod);
- Printf(f_init, " return SCM_UNSPECIFIED;\n");
- Delete(mod);
- }
- Printf(f_init, "}\n");
- break;
- case GUILE_LSTYLE_MODULE:
- Printf(f_init, "\n/* Linkage: module */\n");
- Replaceall(module_func, "/", "_");
- Insert(module_func, 0, "scm_init_");
- Append(module_func, "_module");
-
- Printf(f_init, "static void SWIG_init_helper(void *data)\n");
- Printf(f_init, "{\n SWIG_init();\n");
- if (Len(exported_symbols) > 0)
- Printf(f_init, " scm_c_export(%sNULL);", exported_symbols);
- Printf(f_init, "\n}\n\n");
-
- Printf(f_init, "SCM\n%s (void)\n{\n", module_func);
- {
- String *mod = NewString(module_name);
- if (goops)
- Printv(mod, "-", primsuffix, NIL);
- Replaceall(mod, "/", " ");
- Printf(f_init, " scm_c_define_module(\"%s\",\n", mod);
- Printf(f_init, " SWIG_init_helper, NULL);\n");
- Printf(f_init, " return SCM_UNSPECIFIED;\n");
- Delete(mod);
- }
- Printf(f_init, "}\n");
- break;
- case GUILE_LSTYLE_HOBBIT:
- Printf(f_init, "\n/* Linkage: hobbit */\n");
- Replaceall(module_func, "/", "_slash_");
- Insert(module_func, 0, "scm_init_");
- Printf(f_init, "SCM\n%s (void)\n{\n", module_func);
- {
- String *mod = NewString(module_name);
- Replaceall(mod, "/", " ");
- Printf(f_init, " scm_register_module_xxx (\"%s\", (void *) SWIG_init);\n", mod);
- Printf(f_init, " return SCM_UNSPECIFIED;\n");
- Delete(mod);
- }
- Printf(f_init, "}\n");
- break;
- default:
- fputs("Fatal internal error: Invalid Guile linkage setting.\n", stderr);
- Exit(EXIT_FAILURE);
- }
-
- if (scmstub) {
- /* Emit Scheme stub if requested */
- String *primitive_name = NewString(module_name);
- if (goops)
- Printv(primitive_name, "-", primsuffix, NIL);
-
- String *mod = NewString(primitive_name);
- Replaceall(mod, "/", " ");
-
- String *fname = NewStringf("%s%s.scm",
- SWIG_output_directory(),
- primitive_name);
- Delete(primitive_name);
- File *scmstubfile = NewFile(fname, "w", SWIG_output_files());
- if (!scmstubfile) {
- FileErrorDisplay(fname);
- Exit(EXIT_FAILURE);
- }
- Delete(fname);
-
- Swig_banner_target_lang(scmstubfile, ";;;");
- Printf(scmstubfile, "\n");
- if (linkage == GUILE_LSTYLE_SIMPLE || linkage == GUILE_LSTYLE_PASSIVE)
- Printf(scmstubfile, "(define-module (%s))\n\n", mod);
- Delete(mod);
- Printf(scmstubfile, "%s", scmtext);
- if ((linkage == GUILE_LSTYLE_SIMPLE || linkage == GUILE_LSTYLE_PASSIVE)
- && Len(exported_symbols) > 0) {
- String *ex = NewString(exported_symbols);
- Replaceall(ex, ", ", "\n ");
- Replaceall(ex, "\"", "");
- Chop(ex);
- Printf(scmstubfile, "\n(export %s)\n", ex);
- Delete(ex);
- }
- Delete(scmstubfile);
- }
-
- if (goops) {
- String *mod = NewString(module_name);
- Replaceall(mod, "/", " ");
-
- String *fname = NewStringf("%s%s.scm", SWIG_output_directory(),
- module_name);
- File *goopsfile = NewFile(fname, "w", SWIG_output_files());
- if (!goopsfile) {
- FileErrorDisplay(fname);
- Exit(EXIT_FAILURE);
- }
- Delete(fname);
- Swig_banner_target_lang(goopsfile, ";;;");
- Printf(goopsfile, "\n");
- Printf(goopsfile, "(define-module (%s))\n", mod);
- Printf(goopsfile, "%s\n", goopstext);
- Printf(goopsfile, "(use-modules (oop goops) (Swig common))\n");
- if (primRenamer) {
- Printf(goopsfile, "(use-modules ((%s-%s) :renamer (symbol-prefix-proc 'primitive:)))\n", mod, primsuffix);
- }
- Printf(goopsfile, "%s\n(export %s)", goopscode, goopsexport);
- if (exportprimitive) {
- String *ex = NewString(exported_symbols);
- Replaceall(ex, ", ", "\n ");
- Replaceall(ex, "\"", "");
- Chop(ex);
- Printf(goopsfile, "\n(export %s)", ex);
- Delete(ex);
- }
- Delete(mod);
- Delete(goopsfile);
- }
-
- Delete(module_func);
- if (CPlusPlus) {
- Printf(f_init, "\n}\n");
- }
- }
-
- /* Return true iff T is a pointer type */
-
- int is_a_pointer(SwigType *t) {
- return SwigType_ispointer(SwigType_typedef_resolve_all(t));
- }
-
- /* Report an error handling the given type. */
-
- void throw_unhandled_guile_type_error(SwigType *d) {
- Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, "Unable to handle type %s.\n", SwigType_str(d, 0));
- }
-
- /* Write out procedure documentation */
-
- void write_doc(const String *proc_name, const String *signature, const String *doc, const String *signature2 = NULL) {
- switch (docformat) {
- case GUILE_1_4:
- Printv(procdoc, "\f\n", NIL);
- Printv(procdoc, "(", signature, ")\n", NIL);
- if (signature2)
- Printv(procdoc, "(", signature2, ")\n", NIL);
- Printv(procdoc, doc, "\n", NIL);
- break;
- case PLAIN:
- Printv(procdoc, "\f", proc_name, "\n\n", NIL);
- Printv(procdoc, "(", signature, ")\n", NIL);
- if (signature2)
- Printv(procdoc, "(", signature2, ")\n", NIL);
- Printv(procdoc, doc, "\n\n", NIL);
- break;
- case TEXINFO:
- Printv(procdoc, "\f", proc_name, "\n", NIL);
- Printv(procdoc, "@deffn primitive ", signature, "\n", NIL);
- if (signature2)
- Printv(procdoc, "@deffnx primitive ", signature2, "\n", NIL);
- Printv(procdoc, doc, "\n", NIL);
- Printv(procdoc, "@end deffn\n\n", NIL);
- break;
- }
- }
-
- /* returns false if the typemap is an empty string */
- bool handle_documentation_typemap(String *output,
- const String *maybe_delimiter, Parm *p, const String *typemap, const String *default_doc, const String *name = NULL) {
- String *tmp = NewString("");
- String *tm;
- if (!(tm = Getattr(p, typemap))) {
- Printf(tmp, "%s", default_doc);
- tm = tmp;
- }
- bool result = (Len(tm) > 0);
- if (maybe_delimiter && Len(output) > 0 && Len(tm) > 0) {
- Printv(output, maybe_delimiter, NIL);
- }
- const String *pn = !name ? (const String *) Getattr(p, "name") : name;
- String *pt = Getattr(p, "type");
- Replaceall(tm, "$name", pn); // legacy for $parmname
- Replaceall(tm, "$type", SwigType_str(pt, 0));
- /* $NAME is like $name, but marked-up as a variable. */
- String *ARGNAME = NewString("");
- if (docformat == TEXINFO)
- Printf(ARGNAME, "@var{%s}", pn);
- else
- Printf(ARGNAME, "%(upper)s", pn);
- Replaceall(tm, "$NAME", ARGNAME);
- Replaceall(tm, "$PARMNAME", ARGNAME);
- Printv(output, tm, NIL);
- Delete(tmp);
- return result;
- }
-
- /* ------------------------------------------------------------
- * functionWrapper()
- * Create a function declaration and register it with the interpreter.
- * ------------------------------------------------------------ */
-
- virtual int functionWrapper(Node *n) {
- String *iname = Getattr(n, "sym:name");
- SwigType *d = Getattr(n, "type");
- ParmList *l = Getattr(n, "parms");
- Parm *p;
- String *proc_name = 0;
- char source[256];
- Wrapper *f = NewWrapper();
- String *cleanup = NewString("");
- String *outarg = NewString("");
- String *signature = NewString("");
- String *doc_body = NewString("");
- String *returns = NewString("");
- String *method_signature = NewString("");
- String *primitive_args = NewString("");
- Hash *scheme_arg_names = NewHash();
- int num_results = 1;
- String *tmp = NewString("");
- String *tm;
- int i;
- int numargs = 0;
- int numreq = 0;
- String *overname = 0;
- int args_passed_as_array = 0;
- int scheme_argnum = 0;
- bool any_specialized_arg = false;
-
- // Make a wrapper name for this
- String *wname = Swig_name_wrapper(iname);
- if (Getattr(n, "sym:overloaded")) {
- overname = Getattr(n, "sym:overname");
- args_passed_as_array = 1;
- } else {
- if (!addSymbol(iname, n)) {
- DelWrapper(f);
- return SWIG_ERROR;
- }
- }
- if (overname) {
- Append(wname, overname);
- }
- Setattr(n, "wrap:name", wname);
-
- // Build the name for scheme.
- proc_name = NewString(iname);
- Replaceall(proc_name, "_", "-");
-
- /* Emit locals etc. into f->code; figure out which args to ignore */
- emit_parameter_variables(l, f);
-
- /* Attach the standard typemaps */
- emit_attach_parmmaps(l, f);
- Setattr(n, "wrap:parms", l);
-
- /* Get number of required and total arguments */
- numargs = emit_num_arguments(l);
- numreq = emit_num_required(l);
-
- /* Declare return variable */
-
- Wrapper_add_local(f, "gswig_result", "SCM gswig_result");
- Wrapper_add_local(f, "gswig_list_p", "SWIGUNUSED int gswig_list_p = 0");
-
- /* Open prototype and signature */
-
- Printv(f->def, "static SCM\n", wname, " (", NIL);
- if (args_passed_as_array) {
- Printv(f->def, "int argc, SCM *argv", NIL);
- }
- Printv(signature, proc_name, NIL);
-
- /* Now write code to extract the parameters */
-
- for (i = 0, p = l; i < numargs; i++) {
-
- while (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- }
-
- SwigType *pt = Getattr(p, "type");
- int opt_p = (i >= numreq);
-
- // Produce names of source and target
- if (args_passed_as_array)
- sprintf(source, "argv[%d]", i);
- else
- sprintf(source, "s_%d", i);
-
- if (!args_passed_as_array) {
- if (i != 0)
- Printf(f->def, ", ");
- Printf(f->def, "SCM s_%d", i);
- }
- if (opt_p) {
- Printf(f->code, " if (%s != SCM_UNDEFINED) {\n", source);
- }
- if ((tm = Getattr(p, "tmap:in"))) {
- Replaceall(tm, "$input", source);
- Setattr(p, "emit:input", source);
- Printv(f->code, tm, "\n", NIL);
-
- SwigType *pb = SwigType_typedef_resolve_all(SwigType_base(pt));
- SwigType *pn = Getattr(p, "name");
- String *argname;
- scheme_argnum++;
- if (pn && !Getattr(scheme_arg_names, pn))
- argname = pn;
- else {
- /* Anonymous arg or re-used argument name -- choose a name that cannot clash */
- argname = NewStringf("%%arg%d", scheme_argnum);
- }
-
- if (procdoc) {
- if (i == numreq) {
- /* First optional argument */
- Printf(signature, " #:optional");
- }
- /* Add to signature (arglist) */
- handle_documentation_typemap(signature, " ", p, "tmap:in:arglist", "$name", argname);
- /* Document the type of the arg in the documentation body */
- handle_documentation_typemap(doc_body, ", ", p, "tmap:in:doc", "$NAME is of type <$type>", argname);
- }
-
- if (goops) {
- if (i < numreq) {
- if (strcmp("void", Char(pt)) != 0) {
- Node *class_node = Swig_symbol_clookup_check(pb, Getattr(n, "sym:symtab"),
- has_classname);
- String *goopsclassname = !class_node ? NULL : Getattr(class_node, "guile:goopsclassname");
- /* do input conversion */
- if (goopsclassname) {
- Printv(method_signature, " (", argname, " ", goopsclassname, ")", NIL);
- any_specialized_arg = true;
- } else {
- Printv(method_signature, " ", argname, NIL);
- }
- Printv(primitive_args, " ", argname, NIL);
- Setattr(scheme_arg_names, argname, p);
- }
- }
- }
-
- if (!pn) {
- Delete(argname);
- }
- p = Getattr(p, "tmap:in:next");
- } else {
- throw_unhandled_guile_type_error(pt);
- p = nextSibling(p);
- }
- if (opt_p)
- Printf(f->code, " }\n");
- }
- if (Len(doc_body) > 0)
- Printf(doc_body, ".\n");
-
- /* Insert constraint checking code */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:check"))) {
- Printv(f->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:check:next");
- } else {
- p = nextSibling(p);
- }
- }
- /* Pass output arguments back to the caller. */
-
- /* Insert argument output code */
- String *returns_argout = NewString("");
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:argout"))) {
- Replaceall(tm, "$arg", Getattr(p, "emit:input"));
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(outarg, tm, "\n", NIL);
- if (procdoc) {
- if (handle_documentation_typemap(returns_argout, ", ", p, "tmap:argout:doc", "$NAME (of type $type)")) {
- /* A documentation typemap that is not the empty string
- indicates that a value is returned to Scheme. */
- num_results++;
- }
- }
- p = Getattr(p, "tmap:argout:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* Insert cleanup code */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:freearg"))) {
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(cleanup, tm, "\n", NIL);
- p = Getattr(p, "tmap:freearg:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- if (exporting_destructor) {
- /* Mark the destructor's argument as destroyed. */
- String *tm = NewString("SWIG_Guile_MarkPointerDestroyed($input);");
- Replaceall(tm, "$input", Getattr(l, "emit:input"));
- Printv(cleanup, tm, "\n", NIL);
- Delete(tm);
- }
-
- /* Close prototype */
-
- Printf(f->def, ")\n{\n");
-
- /* Define the scheme name in C. This define is used by several Guile
- macros. */
- Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
-
- // Now write code to make the function call
- String *actioncode = emit_action(n);
-
- // Now have return value, figure out what to do with it.
- if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
- Replaceall(tm, "$result", "gswig_result");
- if (GetFlag(n, "feature:new"))
- Replaceall(tm, "$owner", "1");
- else
- Replaceall(tm, "$owner", "0");
- Printv(f->code, tm, "\n", NIL);
- } else {
- throw_unhandled_guile_type_error(d);
- }
- emit_return_variable(n, d, f);
-
- // Documentation
- if ((tm = Getattr(n, "tmap:out:doc"))) {
- Printv(returns, tm, NIL);
- if (Len(tm) > 0)
- num_results = 1;
- else
- num_results = 0;
- } else {
- String *s = SwigType_str(d, 0);
- Chop(s);
- Printf(returns, "<%s>", s);
- Delete(s);
- num_results = 1;
- }
- Append(returns, returns_argout);
-
-
- // Dump the argument output code
- Printv(f->code, outarg, NIL);
-
- // Dump the argument cleanup code
- Printv(f->code, cleanup, NIL);
-
- // Look for any remaining cleanup
-
- if (GetFlag(n, "feature:new")) {
- if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
- Printv(f->code, tm, "\n", NIL);
- }
- }
- // Free any memory allocated by the function being wrapped..
- if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
- Printv(f->code, tm, "\n", NIL);
- }
- // Wrap things up (in a manner of speaking)
-
- if (beforereturn)
- Printv(f->code, beforereturn, "\n", NIL);
- Printv(f->code, "return gswig_result;\n", NIL);
-
- /* Substitute the function name */
- Replaceall(f->code, "$symname", iname);
- // Undefine the scheme name
-
- Printf(f->code, "#undef FUNC_NAME\n");
- Printf(f->code, "}\n");
-
- Wrapper_print(f, f_wrappers);
-
- if (!Getattr(n, "sym:overloaded")) {
- if (numargs > 10) {
- int i;
- /* gh_new_procedure would complain: too many args */
- /* Build a wrapper wrapper */
- Printv(f_wrappers, "static SCM\n", wname, "_rest (SCM rest)\n", NIL);
- Printv(f_wrappers, "{\n", NIL);
- Printf(f_wrappers, "SCM arg[%d];\n", numargs);
- Printf(f_wrappers, "SWIG_Guile_GetArgs (arg, rest, %d, %d, \"%s\");\n", numreq, numargs - numreq, proc_name);
- Printv(f_wrappers, "return ", wname, "(", NIL);
- Printv(f_wrappers, "arg[0]", NIL);
- for (i = 1; i < numargs; i++)
- Printf(f_wrappers, ", arg[%d]", i);
- Printv(f_wrappers, ");\n", NIL);
- Printv(f_wrappers, "}\n", NIL);
- /* Register it */
- Printf(f_init, "scm_c_define_gsubr(\"%s\", 0, 0, 1, (swig_guile_proc) %s_rest);\n", proc_name, wname);
- } else if (emit_setters && struct_member && strlen(Char(proc_name)) > 3) {
- int len = Len(proc_name);
- const char *pc = Char(proc_name);
- /* MEMBER-set and MEMBER-get functions. */
- int is_setter = (pc[len - 3] == 's');
- if (is_setter) {
- Printf(f_init, "SCM setter = ");
- struct_member = 2; /* have a setter */
- } else
- Printf(f_init, "SCM getter = ");
- /* GOOPS support uses the MEMBER-set and MEMBER-get functions,
- so ignore only_setters in this case. */
- if (only_setters && !goops)
- Printf(f_init, "scm_c_make_gsubr(\"%s\", %d, %d, 0, (swig_guile_proc) %s);\n", proc_name, numreq, numargs - numreq, wname);
- else
- Printf(f_init, "scm_c_define_gsubr(\"%s\", %d, %d, 0, (swig_guile_proc) %s);\n", proc_name, numreq, numargs - numreq, wname);
-
- if (!is_setter) {
- /* Strip off "-get" */
- if (struct_member == 2) {
- /* There was a setter, so create a procedure with setter */
- Printf(f_init, "scm_c_define");
- Printf(f_init, "(\"%.*s\", " "scm_make_procedure_with_setter(getter, setter));\n", pc, len - 4);
- } else {
- /* There was no setter, so make an alias to the getter */
- Printf(f_init, "scm_c_define");
- Printf(f_init, "(\"%.*s\", getter);\n", pc, len - 4);
- }
- Printf(exported_symbols, "\"%.*s\", ", pc, len - 4);
- }
- } else {
- /* Register the function */
- if (exporting_destructor) {
- Printf(f_init, "((swig_guile_clientdata *)(SWIGTYPE%s->clientdata))->destroy = (guile_destructor) %s;\n", swigtype_ptr, wname);
- //Printf(f_init, "SWIG_TypeClientData(SWIGTYPE%s, (void *) %s);\n", swigtype_ptr, wname);
- }
- Printf(f_init, "scm_c_define_gsubr(\"%s\", %d, %d, 0, (swig_guile_proc) %s);\n", proc_name, numreq, numargs - numreq, wname);
- }
- } else { /* overloaded function; don't export the single methods */
- if (!Getattr(n, "sym:nextSibling")) {
- /* Emit overloading dispatch function */
-
- int maxargs;
- String *dispatch = Swig_overload_dispatch(n, "return %s(argc,argv);", &maxargs);
-
- /* Generate a dispatch wrapper for all overloaded functions */
-
- Wrapper *df = NewWrapper();
- String *dname = Swig_name_wrapper(iname);
-
- Printv(df->def, "static SCM\n", dname, "(SCM rest)\n{\n", NIL);
- Printf(df->code, "#define FUNC_NAME \"%s\"\n", proc_name);
- Printf(df->code, "SCM argv[%d];\n", maxargs);
- Printf(df->code, "int argc = SWIG_Guile_GetArgs (argv, rest, %d, %d, \"%s\");\n", 0, maxargs, proc_name);
- Printv(df->code, dispatch, "\n", NIL);
- Printf(df->code, "scm_misc_error(\"%s\", \"No matching method for generic function `%s'\", SCM_EOL);\n", proc_name, iname);
- Printf(df->code, "#undef FUNC_NAME\n");
- Printv(df->code, "}\n", NIL);
- Wrapper_print(df, f_wrappers);
- Printf(f_init, "scm_c_define_gsubr(\"%s\", 0, 0, 1, (swig_guile_proc) %s);\n", proc_name, dname);
- DelWrapper(df);
- Delete(dispatch);
- Delete(dname);
- }
- }
- Printf(exported_symbols, "\"%s\", ", proc_name);
-
- if (!in_class || memberfunction_name) {
- // export wrapper into goops file
- String *method_def = NewString("");
- String *goops_name;
- if (in_class)
- goops_name = NewString(memberfunction_name);
- else
- goops_name = goopsNameMapping(proc_name, "");
- String *primitive_name = NewString("");
- if (primRenamer)
- Printv(primitive_name, "primitive:", proc_name, NIL);
- else
- Printv(primitive_name, proc_name, NIL);
- Replaceall(method_signature, "_", "-");
- Replaceall(primitive_args, "_", "-");
- if (!any_specialized_arg) {
- /* If there would not be any specialized argument in
- the method declaration, we simply re-export the
- function. This is a performance optimization. */
- Printv(method_def, "(define ", goops_name, " ", primitive_name, ")\n", NIL);
- } else if (numreq == numargs) {
- Printv(method_def, "(define-method (", goops_name, method_signature, ")\n", NIL);
- Printv(method_def, " (", primitive_name, primitive_args, "))\n", NIL);
- } else {
- /* Handle optional args. For the rest argument, use a name
- that cannot clash. */
- Printv(method_def, "(define-method (", goops_name, method_signature, " . %args)\n", NIL);
- Printv(method_def, " (apply ", primitive_name, primitive_args, " %args))\n", NIL);
- }
- if (in_class) {
- /* Defer method definition till end of class definition. */
- Printv(goops_class_methods, method_def, NIL);
- } else {
- Printv(goopscode, method_def, NIL);
- }
- Printf(goopsexport, "%s ", goops_name);
- Delete(primitive_name);
- Delete(goops_name);
- Delete(method_def);
- }
-
- if (procdoc) {
- String *returns_text = NewString("");
- if (num_results == 0)
- Printv(returns_text, return_nothing_doc, NIL);
- else if (num_results == 1)
- Printv(returns_text, return_one_doc, NIL);
- else
- Printv(returns_text, return_multi_doc, NIL);
- /* Substitute documentation variables */
- static const char *numbers[] = { "zero", "one", "two", "three",
- "four", "five", "six", "seven",
- "eight", "nine", "ten", "eleven",
- "twelve"
- };
- if (num_results <= 12)
- Replaceall(returns_text, "$num_values", numbers[num_results]);
- else {
- String *num_results_str = NewStringf("%d", num_results);
- Replaceall(returns_text, "$num_values", num_results_str);
- Delete(num_results_str);
- }
- Replaceall(returns_text, "$values", returns);
- Printf(doc_body, "\n%s", returns_text);
- write_doc(proc_name, signature, doc_body);
- Delete(returns_text);
- }
-
- Delete(proc_name);
- Delete(outarg);
- Delete(cleanup);
- Delete(signature);
- Delete(method_signature);
- Delete(primitive_args);
- Delete(doc_body);
- Delete(returns_argout);
- Delete(returns);
- Delete(tmp);
- Delete(scheme_arg_names);
- DelWrapper(f);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * variableWrapper()
- *
- * Create a link to a C variable.
- * This creates a single function PREFIX_var_VARNAME().
- * This function takes a single optional argument. If supplied, it means
- * we are setting this variable to some value. If omitted, it means we are
- * simply evaluating this variable. Either way, we return the variables
- * value.
- * ------------------------------------------------------------ */
-
- virtual int variableWrapper(Node *n) {
-
- char *name = GetChar(n, "name");
- char *iname = GetChar(n, "sym:name");
- SwigType *t = Getattr(n, "type");
-
- String *proc_name;
- Wrapper *f;
- String *tm;
-
- if (!addSymbol(iname, n))
- return SWIG_ERROR;
-
- f = NewWrapper();
- // evaluation function names
-
- String *var_name = Swig_name_wrapper(iname);
-
- // Build the name for scheme.
- proc_name = NewString(iname);
- Replaceall(proc_name, "_", "-");
- Setattr(n, "wrap:name", proc_name);
-
- if (1 || (SwigType_type(t) != T_USER) || (is_a_pointer(t))) {
-
- Printf(f->def, "static SCM\n%s(SCM s_0)\n{\n", var_name);
-
- /* Define the scheme name in C. This define is used by several Guile
- macros. */
- Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
-
- Wrapper_add_local(f, "gswig_result", "SCM gswig_result");
-
- if (!GetFlag(n, "feature:immutable")) {
- /* Check for a setting of the variable value */
- Printf(f->code, "if (s_0 != SCM_UNDEFINED) {\n");
- if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
- Replaceall(tm, "$input", "s_0");
- /* Printv(f->code,tm,"\n",NIL); */
- emit_action_code(n, f->code, tm);
- } else {
- throw_unhandled_guile_type_error(t);
- }
- Printf(f->code, "}\n");
- }
- // Now return the value of the variable (regardless
- // of evaluating or setting)
-
- if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
- Replaceall(tm, "$result", "gswig_result");
- /* Printv(f->code,tm,"\n",NIL); */
- emit_action_code(n, f->code, tm);
- } else {
- throw_unhandled_guile_type_error(t);
- }
- Printf(f->code, "\nreturn gswig_result;\n");
- Printf(f->code, "#undef FUNC_NAME\n");
- Printf(f->code, "}\n");
-
- Wrapper_print(f, f_wrappers);
-
- // Now add symbol to the Guile interpreter
-
- if (!emit_setters || GetFlag(n, "feature:immutable")) {
- /* Read-only variables become a simple procedure returning the
- value; read-write variables become a simple procedure with
- an optional argument. */
-
- if (!goops && GetFlag(n, "feature:constasvar")) {
- /* need to export this function as a variable instead of a procedure */
- if (scmstub) {
- /* export the function in the wrapper, and (set!) it in scmstub */
- Printf(f_init, "scm_c_define_gsubr(\"%s\", 0, %d, 0, (swig_guile_proc) %s);\n", proc_name, !GetFlag(n, "feature:immutable"), var_name);
- Printf(scmtext, "(set! %s (%s))\n", proc_name, proc_name);
- } else {
- /* export the variable directly */
- Printf(f_init, "scm_c_define(\"%s\", %s(SCM_UNDEFINED));\n", proc_name, var_name);
- }
-
- } else {
- /* Export the function as normal */
- Printf(f_init, "scm_c_define_gsubr(\"%s\", 0, %d, 0, (swig_guile_proc) %s);\n", proc_name, !GetFlag(n, "feature:immutable"), var_name);
- }
-
- } else {
- /* Read/write variables become a procedure with setter. */
- Printf(f_init, "{ SCM p = scm_c_define_gsubr(\"%s\", 0, 1, 0, (swig_guile_proc) %s);\n", proc_name, var_name);
- Printf(f_init, "scm_c_define");
- Printf(f_init, "(\"%s\", " "scm_make_procedure_with_setter(p, p)); }\n", proc_name);
- }
- Printf(exported_symbols, "\"%s\", ", proc_name);
-
- // export wrapper into goops file
- if (!in_class) { // only if the variable is not part of a class
- String *class_name = SwigType_typedef_resolve_all(SwigType_base(t));
- String *goops_name = goopsNameMapping(proc_name, "");
- String *primitive_name = NewString("");
- if (primRenamer)
- Printv(primitive_name, "primitive:", NIL);
- Printv(primitive_name, proc_name, NIL);
- /* Simply re-export the procedure */
- if ((!emit_setters || GetFlag(n, "feature:immutable"))
- && GetFlag(n, "feature:constasvar")) {
- Printv(goopscode, "(define ", goops_name, " (", primitive_name, "))\n", NIL);
- } else {
- Printv(goopscode, "(define ", goops_name, " ", primitive_name, ")\n", NIL);
- }
- Printf(goopsexport, "%s ", goops_name);
- Delete(primitive_name);
- Delete(class_name);
- Delete(goops_name);
- }
-
- if (procdoc) {
- /* Compute documentation */
- String *signature = NewString("");
- String *signature2 = NULL;
- String *doc = NewString("");
-
- if (GetFlag(n, "feature:immutable")) {
- Printv(signature, proc_name, NIL);
- if (GetFlag(n, "feature:constasvar")) {
- Printv(doc, "Is constant ", NIL);
- } else {
- Printv(doc, "Returns constant ", NIL);
- }
- if ((tm = Getattr(n, "tmap:varout:doc"))) {
- Printv(doc, tm, NIL);
- } else {
- String *s = SwigType_str(t, 0);
- Chop(s);
- Printf(doc, "<%s>", s);
- Delete(s);
- }
- } else if (emit_setters) {
- Printv(signature, proc_name, NIL);
- signature2 = NewString("");
- Printv(signature2, "set! (", proc_name, ") ", NIL);
- handle_documentation_typemap(signature2, NIL, n, "tmap:varin:arglist", "new-value");
- Printv(doc, "Get or set the value of the C variable, \n", NIL);
- Printv(doc, "which is of type ", NIL);
- handle_documentation_typemap(doc, NIL, n, "tmap:varout:doc", "$1_type");
- Printv(doc, ".");
- } else {
- Printv(signature, proc_name, " #:optional ", NIL);
- if ((tm = Getattr(n, "tmap:varin:doc"))) {
- Printv(signature, tm, NIL);
- } else {
- String *s = SwigType_str(t, 0);
- Chop(s);
- Printf(signature, "new-value <%s>", s);
- Delete(s);
- }
-
- Printv(doc, "If NEW-VALUE is provided, " "set C variable to this value.\n", NIL);
- Printv(doc, "Returns variable value ", NIL);
- if ((tm = Getattr(n, "tmap:varout:doc"))) {
- Printv(doc, tm, NIL);
- } else {
- String *s = SwigType_str(t, 0);
- Chop(s);
- Printf(doc, "<%s>", s);
- Delete(s);
- }
- }
- write_doc(proc_name, signature, doc, signature2);
- Delete(signature);
- if (signature2)
- Delete(signature2);
- Delete(doc);
- }
-
- } else {
- Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number, "Unsupported variable type %s (ignored).\n", SwigType_str(t, 0));
- }
- Delete(var_name);
- Delete(proc_name);
- DelWrapper(f);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * constantWrapper()
- *
- * We create a read-only variable.
- * ------------------------------------------------------------ */
-
- virtual int constantWrapper(Node *n) {
- char *name = GetChar(n, "name");
- char *iname = GetChar(n, "sym:name");
- SwigType *type = Getattr(n, "type");
- String *rawval = Getattr(n, "rawval");
- String *value = rawval ? rawval : Getattr(n, "value");
- int constasvar = GetFlag(n, "feature:constasvar");
-
-
- String *proc_name;
- String *var_name;
- Wrapper *f;
- SwigType *nctype;
- String *tm;
-
- f = NewWrapper();
-
- // Make a static variable;
- var_name = NewStringf("%sconst_%s", prefix, iname);
-
- // Strip const qualifier from type if present
-
- nctype = NewString(type);
- if (SwigType_isconst(nctype)) {
- Delete(SwigType_pop(nctype));
- }
- // Build the name for scheme.
- proc_name = NewString(iname);
- Replaceall(proc_name, "_", "-");
-
- if ((SwigType_type(nctype) == T_USER) && (!is_a_pointer(nctype))) {
- Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n");
- Delete(var_name);
- DelWrapper(f);
- return SWIG_NOWRAP;
- }
- // See if there's a typemap
-
- if ((tm = Swig_typemap_lookup("constant", n, name, 0))) {
- Replaceall(tm, "$value", value);
- Printv(f_header, tm, "\n", NIL);
- } else {
- // Create variable and assign it a value
- Printf(f_header, "static %s = (%s)(%s);\n", SwigType_str(type, var_name), SwigType_str(type, 0), value);
- }
- {
- /* Hack alert: will cleanup later -- Dave */
- Node *nn = NewHash();
- Setfile(nn, Getfile(n));
- Setline(nn, Getline(n));
- Setattr(nn, "name", var_name);
- Setattr(nn, "sym:name", iname);
- Setattr(nn, "type", nctype);
- SetFlag(nn, "feature:immutable");
- if (constasvar) {
- SetFlag(nn, "feature:constasvar");
- }
- variableWrapper(nn);
- Delete(nn);
- }
- Delete(var_name);
- Delete(nctype);
- Delete(proc_name);
- DelWrapper(f);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * classDeclaration()
- * ------------------------------------------------------------ */
- virtual int classDeclaration(Node *n) {
- String *class_name = NewStringf("<%s>", Getattr(n, "sym:name"));
- Setattr(n, "guile:goopsclassname", class_name);
- return Language::classDeclaration(n);
- }
-
- /* ------------------------------------------------------------
- * classHandler()
- * ------------------------------------------------------------ */
- virtual int classHandler(Node *n) {
- /* Create new strings for building up a wrapper function */
- have_constructor = 0;
-
- class_name = NewString("");
- short_class_name = NewString("");
- Printv(class_name, "<", Getattr(n, "sym:name"), ">", NIL);
- Printv(short_class_name, Getattr(n, "sym:name"), NIL);
- Replaceall(class_name, "_", "-");
- Replaceall(short_class_name, "_", "-");
-
- if (!addSymbol(class_name, n))
- return SWIG_ERROR;
-
- /* Handle inheritance */
- String *base_class = NewString("<");
- List *baselist = Getattr(n, "bases");
- if (baselist && Len(baselist)) {
- Iterator i = First(baselist);
- while (i.item) {
- Printv(base_class, Getattr(i.item, "sym:name"), NIL);
- i = Next(i);
- if (i.item) {
- Printf(base_class, "> <");
- }
- }
- }
- Printf(base_class, ">");
- Replaceall(base_class, "_", "-");
-
- Printv(goopscode, "(define-class ", class_name, " ", NIL);
- Printf(goopsexport, "%s ", class_name);
-
- if (Len(base_class) > 2) {
- Printv(goopscode, "(", base_class, ")\n", NIL);
- } else {
- Printv(goopscode, "(<swig>)\n", NIL);
- }
- SwigType *ct = NewStringf("p.%s", Getattr(n, "name"));
- swigtype_ptr = SwigType_manglestr(ct);
-
- String *mangled_classname = Swig_name_mangle(Getattr(n, "sym:name"));
- /* Export clientdata structure */
- Printf(f_runtime, "static swig_guile_clientdata _swig_guile_clientdata%s = { NULL, SCM_EOL };\n", mangled_classname);
-
- Printv(f_init, "SWIG_TypeClientData(SWIGTYPE", swigtype_ptr, ", (void *) &_swig_guile_clientdata", mangled_classname, ");\n", NIL);
- SwigType_remember(ct);
- Delete(ct);
-
- /* Emit all of the members */
- goops_class_methods = NewString("");
-
- in_class = 1;
- Language::classHandler(n);
- in_class = 0;
-
- Printv(goopscode, " #:metaclass <swig-metaclass>\n", NIL);
-
- if (have_constructor)
- Printv(goopscode, " #:new-function ", primRenamer ? "primitive:" : "", "new-", short_class_name, "\n", NIL);
-
- Printf(goopscode, ")\n%s\n", goops_class_methods);
- Delete(goops_class_methods);
- goops_class_methods = 0;
-
-
- /* export class initialization function */
- if (goops) {
- /* export the wrapper function */
- String *funcName = NewString(mangled_classname);
- Printf(funcName, "_swig_guile_setgoopsclass");
- String *guileFuncName = NewString(funcName);
- Replaceall(guileFuncName, "_", "-");
-
- Printv(f_wrappers, "static SCM ", funcName, "(SCM cl) \n", NIL);
- Printf(f_wrappers, "#define FUNC_NAME %s\n{\n", guileFuncName);
- Printv(f_wrappers, " ((swig_guile_clientdata *)(SWIGTYPE", swigtype_ptr, "->clientdata))->goops_class = cl;\n", NIL);
- Printf(f_wrappers, " return SCM_UNSPECIFIED;\n");
- Printf(f_wrappers, "}\n#undef FUNC_NAME\n\n");
-
- Printf(f_init, "scm_c_define_gsubr(\"%s\", 1, 0, 0, (swig_guile_proc) %s);\n", guileFuncName, funcName);
- Printf(exported_symbols, "\"%s\", ", guileFuncName);
-
- /* export the call to the wrapper function */
- Printf(goopscode, "(%s%s %s)\n\n", primRenamer ? "primitive:" : "", guileFuncName, class_name);
-
- Delete(guileFuncName);
- Delete(funcName);
- }
-
- Delete(mangled_classname);
-
- Delete(swigtype_ptr);
- swigtype_ptr = 0;
-
- Delete(class_name);
- Delete(short_class_name);
- class_name = 0;
- short_class_name = 0;
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * memberfunctionHandler()
- * ------------------------------------------------------------ */
- int memberfunctionHandler(Node *n) {
- String *iname = Getattr(n, "sym:name");
- String *proc = NewString(iname);
- Replaceall(proc, "_", "-");
-
- memberfunction_name = goopsNameMapping(proc, short_class_name);
- Language::memberfunctionHandler(n);
- Delete(memberfunction_name);
- memberfunction_name = NULL;
- Delete(proc);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * membervariableHandler()
- * ------------------------------------------------------------ */
- int membervariableHandler(Node *n) {
- String *iname = Getattr(n, "sym:name");
-
- if (emit_setters) {
- struct_member = 1;
- Printf(f_init, "{\n");
- }
-
- Language::membervariableHandler(n);
-
- if (emit_setters) {
- Printf(f_init, "}\n");
- struct_member = 0;
- }
-
- String *proc = NewString(iname);
- Replaceall(proc, "_", "-");
- String *goops_name = goopsNameMapping(proc, short_class_name);
-
- /* The slot name is never qualified with the class,
- even if useclassprefix is true. */
- Printv(goopscode, " (", proc, " #:allocation #:virtual", NIL);
- /* GOOPS (at least in Guile 1.6.3) only accepts closures, not
- primitive procedures for slot-ref and slot-set. */
- Printv(goopscode, "\n #:slot-ref (lambda (obj) (", primRenamer ? "primitive:" : "", short_class_name, "-", proc, "-get", " obj))", NIL);
- if (!GetFlag(n, "feature:immutable")) {
- Printv(goopscode, "\n #:slot-set! (lambda (obj value) (", primRenamer ? "primitive:" : "", short_class_name, "-", proc, "-set", " obj value))", NIL);
- } else {
- Printf(goopscode, "\n #:slot-set! (lambda (obj value) (error \"Immutable slot\"))");
- }
- if (emit_slot_accessors) {
- if (GetFlag(n, "feature:immutable")) {
- Printv(goopscode, "\n #:getter ", goops_name, NIL);
- } else {
- Printv(goopscode, "\n #:accessor ", goops_name, NIL);
- }
- Printf(goopsexport, "%s ", goops_name);
- }
- Printv(goopscode, ")\n", NIL);
- Delete(proc);
- Delete(goops_name);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * constructorHandler()
- * ------------------------------------------------------------ */
- int constructorHandler(Node *n) {
- Language::constructorHandler(n);
- have_constructor = 1;
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * destructorHandler()
- * ------------------------------------------------------------ */
- virtual int destructorHandler(Node *n) {
- exporting_destructor = true;
- Language::destructorHandler(n);
- exporting_destructor = false;
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * pragmaDirective()
- * ------------------------------------------------------------ */
-
- virtual int pragmaDirective(Node *n) {
- if (!ImportMode) {
- String *lang = Getattr(n, "lang");
- String *cmd = Getattr(n, "name");
- String *value = Getattr(n, "value");
-
-# define store_pragma(PRAGMANAME) \
- if (Strcmp(cmd, #PRAGMANAME) == 0) { \
- if (PRAGMANAME) Delete(PRAGMANAME); \
- PRAGMANAME = value ? NewString(value) : NULL; \
- }
-
- if (Strcmp(lang, "guile") == 0) {
- store_pragma(beforereturn)
- store_pragma(return_nothing_doc)
- store_pragma(return_one_doc)
- store_pragma(return_multi_doc);
-# undef store_pragma
- }
- }
- return Language::pragmaDirective(n);
- }
-
-
- /* ------------------------------------------------------------
- * goopsNameMapping()
- * Maps the identifier from C++ to the GOOPS based * on command
- * line parameters and such.
- * If class_name = "" that means the mapping is for a function or
- * variable not attached to any class.
- * ------------------------------------------------------------ */
- String *goopsNameMapping(String *name, const_String_or_char_ptr class_name) {
- String *n = NewString("");
-
- if (Strcmp(class_name, "") == 0) {
- // not part of a class, so no class name to prefix
- if (goopsprefix) {
- Printf(n, "%s%s", goopsprefix, name);
- } else {
- Printf(n, "%s", name);
- }
- } else {
- if (useclassprefix) {
- Printf(n, "%s-%s", class_name, name);
- } else {
- if (goopsprefix) {
- Printf(n, "%s%s", goopsprefix, name);
- } else {
- Printf(n, "%s", name);
- }
- }
- }
- return n;
- }
-
-
- /* ------------------------------------------------------------
- * validIdentifier()
- * ------------------------------------------------------------ */
-
- virtual int validIdentifier(String *s) {
- char *c = Char(s);
- /* Check whether we have an R5RS identifier. Guile supports a
- superset of R5RS identifiers, but it's probably a bad idea to use
- those. */
- /* <identifier> --> <initial> <subsequent>* | <peculiar identifier> */
- /* <initial> --> <letter> | <special initial> */
- if (!(isalpha(*c) || (*c == '!') || (*c == '$') || (*c == '%')
- || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
- || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
- || (*c == '^') || (*c == '_') || (*c == '~'))) {
- /* <peculiar identifier> --> + | - | ... */
- if ((strcmp(c, "+") == 0)
- || strcmp(c, "-") == 0 || strcmp(c, "...") == 0)
- return 1;
- else
- return 0;
- }
- /* <subsequent> --> <initial> | <digit> | <special subsequent> */
- while (*c) {
- if (!(isalnum(*c) || (*c == '!') || (*c == '$') || (*c == '%')
- || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
- || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
- || (*c == '^') || (*c == '_') || (*c == '~') || (*c == '+')
- || (*c == '-') || (*c == '.') || (*c == '@')))
- return 0;
- c++;
- }
- return 1;
- }
-
- String *runtimeCode() {
- String *s;
- s = Swig_include_sys("guile_scm_run.swg");
- if (!s) {
- Printf(stderr, "*** Unable to open 'guile_scm_run.swg");
- s = NewString("");
- }
- return s;
- }
-
- String *defaultExternalRuntimeFilename() {
- return NewString("swigguilerun.h");
- }
-};
-
-/* -----------------------------------------------------------------------------
- * swig_guile() - Instantiate module
- * ----------------------------------------------------------------------------- */
-
-static Language *new_swig_guile() {
- return new GUILE();
-}
-extern "C" Language *swig_guile(void) {
- return new_swig_guile();
-}
diff --git a/contrib/tools/swig/Source/Modules/interface.cxx b/contrib/tools/swig/Source/Modules/interface.cxx
deleted file mode 100644
index 83a5e5f8a1..0000000000
--- a/contrib/tools/swig/Source/Modules/interface.cxx
+++ /dev/null
@@ -1,210 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * interface.cxx
- *
- * This module contains support for the interface feature.
- * This feature is used in language modules where the target language does not
- * naturally support C++ style multiple inheritance, but does support inheritance
- * from multiple interfaces.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include "cparse.h"
-
-static bool interface_feature_enabled = false;
-
-/* -----------------------------------------------------------------------------
- * collect_interface_methods()
- *
- * Create a list of all the methods from the base classes of class n that are
- * marked as an interface. The resulting list is thus the list of methods that
- * need to be implemented in order for n to be non-abstract.
- * ----------------------------------------------------------------------------- */
-
-static List *collect_interface_methods(Node *n) {
- List *methods = NewList();
- if (List *bases = Getattr(n, "interface:bases")) {
- for (Iterator base = First(bases); base.item; base = Next(base)) {
- Node *cls = base.item;
- if (cls == n)
- continue;
- for (Node *child = firstChild(cls); child; child = nextSibling(child)) {
- if (Cmp(nodeType(child), "cdecl") == 0) {
- if (GetFlag(child, "feature:ignore") || Getattr(child, "interface:owner"))
- continue; // skip methods propagated to bases
- if (!checkAttribute(child, "kind", "function"))
- continue;
- if (checkAttribute(child, "storage", "static"))
- continue; // accept virtual methods, non-virtual methods too... mmm??. Warn that the interface class has something that is not a virtual method?
- Node *nn = copyNode(child);
- Setattr(nn, "interface:owner", cls);
- ParmList *parms = CopyParmList(Getattr(child, "parms"));
- Setattr(nn, "parms", parms);
- Delete(parms);
- ParmList *throw_parm_list = Getattr(child, "throws");
- if (throw_parm_list)
- Setattr(nn, "throws", CopyParmList(throw_parm_list));
- Append(methods, nn);
- }
- }
- }
- }
- return methods;
-}
-
-/* -----------------------------------------------------------------------------
- * collect_interface_bases
- * ----------------------------------------------------------------------------- */
-
-static void collect_interface_bases(List *bases, Node *n) {
- if (GetFlag(n, "feature:interface")) {
- String *name = Getattr(n, "interface:name");
- if (!Getattr(bases, name))
- Append(bases, n);
- }
-
- if (List *baselist = Getattr(n, "bases")) {
- for (Iterator base = First(baselist); base.item; base = Next(base)) {
- if (!GetFlag(base.item, "feature:ignore")) {
- if (GetFlag(base.item, "feature:interface"))
- collect_interface_bases(bases, base.item);
- }
- }
- }
-}
-
-/* -----------------------------------------------------------------------------
- * collect_interface_base_classes()
- *
- * Create a hash containing all the classes up the inheritance hierarchy
- * marked with feature:interface (including this class n).
- * Stops going up the inheritance chain as soon as a class is found without
- * feature:interface.
- * The idea is to find all the base interfaces that a class must implement.
- * ----------------------------------------------------------------------------- */
-
-static void collect_interface_base_classes(Node *n) {
- if (GetFlag(n, "feature:interface")) {
- // check all bases are also interfaces
- if (List *baselist = Getattr(n, "bases")) {
- for (Iterator base = First(baselist); base.item; base = Next(base)) {
- if (!GetFlag(base.item, "feature:ignore")) {
- if (!GetFlag(base.item, "feature:interface")) {
- Swig_error(Getfile(n), Getline(n), "Base class '%s' of '%s' is not similarly marked as an interface.\n", SwigType_namestr(Getattr(base.item, "name")), SwigType_namestr(Getattr(n, "name")));
- Exit(EXIT_FAILURE);
- }
- }
- }
- }
- }
-
- List *interface_bases = NewList();
- collect_interface_bases(interface_bases, n);
- if (Len(interface_bases) == 0)
- Delete(interface_bases);
- else
- Setattr(n, "interface:bases", interface_bases);
-}
-
-/* -----------------------------------------------------------------------------
- * process_interface_name()
- * ----------------------------------------------------------------------------- */
-
-static void process_interface_name(Node *n) {
- if (GetFlag(n, "feature:interface")) {
- String *interface_name = Getattr(n, "feature:interface:name");
- if (!Len(interface_name)) {
- Swig_error(Getfile(n), Getline(n), "The interface feature for '%s' is missing the name attribute.\n", SwigType_namestr(Getattr(n, "name")));
- Exit(EXIT_FAILURE);
- }
- if (Strchr(interface_name, '%')) {
- String *name = NewStringf(interface_name, Getattr(n, "sym:name"));
- Setattr(n, "interface:name", name);
- } else {
- Setattr(n, "interface:name", interface_name);
- }
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_interface_propagate_methods()
- *
- * Find all the base classes marked as an interface (with feature:interface) for
- * class node n. For each of these, add all of its methods as methods of n so that
- * n is not abstract. If class n is also marked as an interface, it will remain
- * abstract and not have any methods added.
- * ----------------------------------------------------------------------------- */
-
-void Swig_interface_propagate_methods(Node *n) {
- if (interface_feature_enabled) {
- process_interface_name(n);
- collect_interface_base_classes(n);
- List *methods = collect_interface_methods(n);
- bool is_interface = GetFlag(n, "feature:interface") ? true : false;
- for (Iterator mi = First(methods); mi.item; mi = Next(mi)) {
- if (!is_interface && GetFlag(mi.item, "abstract"))
- continue;
- String *this_decl = Getattr(mi.item, "decl");
- String *this_decl_resolved = SwigType_typedef_resolve_all(this_decl);
- bool identically_overloaded_method = false; // true when a base class' method is implemented in n
- if (SwigType_isfunction(this_decl_resolved)) {
- String *name = Getattr(mi.item, "name");
- for (Node *child = firstChild(n); child; child = nextSibling(child)) {
- if (Getattr(child, "interface:owner"))
- break; // at the end of the list are newly appended methods
- if (Cmp(nodeType(child), "cdecl") == 0) {
- if (checkAttribute(child, "name", name)) {
- String *decl = SwigType_typedef_resolve_all(Getattr(child, "decl"));
- identically_overloaded_method = Strcmp(decl, this_decl_resolved) == 0;
- Delete(decl);
- if (identically_overloaded_method)
- break;
- }
- }
- }
- }
- Delete(this_decl_resolved);
- if (!identically_overloaded_method) {
- // Add method copied from base class to this derived class
- Node *cn = mi.item;
- Delattr(cn, "sym:overname");
- String *prefix = Getattr(n, "name");
- String *name = Getattr(cn, "name");
- String *decl = Getattr(cn, "decl");
- String *oldname = Getattr(cn, "sym:name");
-
- String *symname = Swig_name_make(cn, prefix, name, decl, oldname);
- if (Strcmp(symname, "$ignore") != 0) {
- Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
- Node *on = Swig_symbol_add(symname, cn);
- (void)on;
- assert(on == cn);
-
- // Features from the copied base class method are already present, now add in features specific to the added method in the derived class
- Swig_features_get(Swig_cparse_features(), Swig_symbol_qualifiedscopename(0), name, decl, cn);
- Swig_symbol_setscope(oldscope);
- appendChild(n, cn);
- }
- } else {
- Delete(mi.item);
- }
- }
- Delete(methods);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_interface_feature_enable()
- *
- * Turn on interface feature support
- * ----------------------------------------------------------------------------- */
-
-void Swig_interface_feature_enable() {
- interface_feature_enabled = true;
-}
diff --git a/contrib/tools/swig/Source/Modules/java.cxx b/contrib/tools/swig/Source/Modules/java.cxx
deleted file mode 100644
index 773945af20..0000000000
--- a/contrib/tools/swig/Source/Modules/java.cxx
+++ /dev/null
@@ -1,4979 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * java.cxx
- *
- * Java language module for SWIG.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include "cparse.h"
-#include <limits.h> // for INT_MAX
-#include <ctype.h>
-#include "javadoc.h"
-
-/* Hash type used for upcalls from C/C++ */
-typedef DOH UpcallData;
-
-class JAVA:public Language {
- static const char *usage;
- const String *empty_string;
- const String *public_string;
- const String *protected_string;
-
- Hash *swig_types_hash;
- File *f_begin;
- File *f_runtime;
- File *f_runtime_h;
- File *f_header;
- File *f_wrappers;
- File *f_init;
- File *f_directors;
- File *f_directors_h;
- List *filenames_list;
-
- bool proxy_flag; // Flag for generating proxy classes
- bool nopgcpp_flag; // Flag for suppressing the premature garbage collection prevention parameter
- bool native_function_flag; // Flag for when wrapping a native function
- bool enum_constant_flag; // Flag for when wrapping an enum or constant
- bool static_flag; // Flag for when wrapping a static functions or member variables
- bool variable_wrapper_flag; // Flag for when wrapping a nonstatic member variable
- bool wrapping_member_flag; // Flag for when wrapping a member variable/enum/const
- bool global_variable_flag; // Flag for when wrapping a global variable
- bool old_variable_names; // Flag for old style variable names in the intermediary class
- bool member_func_flag; // flag set when wrapping a member function
- bool doxygen; //flag for converting found doxygen to javadoc
- bool comment_creation_chatter; //flag for getting information about where comments were created in java.cxx
-
- String *imclass_name; // intermediary class name
- String *module_class_name; // module class name
- String *constants_interface_name; // constants interface name
- String *imclass_class_code; // intermediary class code
- String *proxy_class_def;
- String *proxy_class_code;
- String *interface_class_code; // if %feature("interface") was declared for a class, here goes the interface declaration
- String *module_class_code;
- String *proxy_class_name; // proxy class name
- String *full_proxy_class_name;// fully qualified proxy class name when using nspace feature, otherwise same as proxy_class_name
- String *full_imclass_name; // fully qualified intermediary class name when using nspace feature, otherwise same as imclass_name
- String *variable_name; //Name of a variable being wrapped
- String *proxy_class_constants_code;
- String *module_class_constants_code;
- String *enum_code;
- String *package; // Optional package name
- String *jnipackage; // Package name used in the JNI code
- String *package_path; // Package name used internally by JNI (slashes)
- String *imclass_imports; //intermediary class imports from %pragma
- String *module_imports; //module imports from %pragma
- String *imclass_baseclass; //inheritance for intermediary class class from %pragma
- String *imclass_package; //package in which to generate the intermediary class
- String *module_baseclass; //inheritance for module class from %pragma
- String *imclass_interfaces; //interfaces for intermediary class class from %pragma
- String *module_interfaces; //interfaces for module class from %pragma
- String *imclass_class_modifiers; //class modifiers for intermediary class overridden by %pragma
- String *module_class_modifiers; //class modifiers for module class overridden by %pragma
- String *upcasts_code; //C++ casts for inheritance hierarchies C++ code
- String *imclass_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code
- String *imclass_directors; // Intermediate class director code
- String *destructor_call; //C++ destructor call if any
- String *destructor_throws_clause; //C++ destructor throws clause if any
-
- // Director method stuff:
- List *dmethods_seq;
- Hash *dmethods_table;
- int n_dmethods;
- int n_directors;
- int first_class_dmethod;
- int curr_class_dmethod;
- int nesting_depth;
-
- enum EnumFeature { SimpleEnum, TypeunsafeEnum, TypesafeEnum, ProperEnum };
-
-public:
-
- /* -----------------------------------------------------------------------------
- * JAVA()
- * ----------------------------------------------------------------------------- */
-
- JAVA():empty_string(NewString("")),
- public_string(NewString("public")),
- protected_string(NewString("protected")),
- swig_types_hash(NULL),
- f_begin(NULL),
- f_runtime(NULL),
- f_runtime_h(NULL),
- f_header(NULL),
- f_wrappers(NULL),
- f_init(NULL),
- f_directors(NULL),
- f_directors_h(NULL),
- filenames_list(NULL),
- proxy_flag(true),
- nopgcpp_flag(false),
- native_function_flag(false),
- enum_constant_flag(false),
- static_flag(false),
- variable_wrapper_flag(false),
- wrapping_member_flag(false),
- global_variable_flag(false),
- old_variable_names(false),
- member_func_flag(false),
- doxygen(false),
- comment_creation_chatter(false),
- imclass_name(NULL),
- module_class_name(NULL),
- constants_interface_name(NULL),
- imclass_class_code(NULL),
- proxy_class_def(NULL),
- proxy_class_code(NULL),
- interface_class_code(NULL),
- module_class_code(NULL),
- proxy_class_name(NULL),
- full_proxy_class_name(NULL),
- full_imclass_name(NULL),
- variable_name(NULL),
- proxy_class_constants_code(NULL),
- module_class_constants_code(NULL),
- enum_code(NULL),
- package(NULL),
- jnipackage(NULL),
- package_path(NULL),
- imclass_imports(NULL),
- module_imports(NULL),
- imclass_baseclass(NULL),
- imclass_package(NULL),
- module_baseclass(NULL),
- imclass_interfaces(NULL),
- module_interfaces(NULL),
- imclass_class_modifiers(NULL),
- module_class_modifiers(NULL),
- upcasts_code(NULL),
- imclass_cppcasts_code(NULL),
- imclass_directors(NULL),
- destructor_call(NULL),
- destructor_throws_clause(NULL),
- dmethods_seq(NULL),
- dmethods_table(NULL),
- n_dmethods(0),
- n_directors(0),
- first_class_dmethod(0),
- curr_class_dmethod(0),
- nesting_depth(0){
- /* for now, multiple inheritance in directors is disabled, this
- should be easy to implement though */
- director_multiple_inheritance = 0;
- director_language = 1;
- }
-
- ~JAVA() {
- delete doxygenTranslator;
- }
-
- /* -----------------------------------------------------------------------------
- * constructIntermediateClassName()
- *
- * Construct the fully qualified name of the intermediate class and set
- * the full_imclass_name attribute accordingly.
- * ----------------------------------------------------------------------------- */
- void constructIntermediateClassName(Node *n) {
- String *nspace = Getattr(n, "sym:nspace");
-
- if (imclass_package && package)
- full_imclass_name = NewStringf("%s.%s.%s", package, imclass_package, imclass_name);
- else if (package && nspace)
- full_imclass_name = NewStringf("%s.%s", package, imclass_name);
- else if (imclass_package)
- full_imclass_name = NewStringf("%s.%s", imclass_package, imclass_name);
- else
- full_imclass_name = NewStringf("%s", imclass_name);
-
- if (nspace && !package) {
- String *name = Getattr(n, "name") ? Getattr(n, "name") : NewString("<unnamed>");
- Swig_warning(WARN_JAVA_NSPACE_WITHOUT_PACKAGE, Getfile(n), Getline(n),
- "The nspace feature is used on '%s' without -package. "
- "The generated code may not compile as Java does not support types declared in a named package accessing types declared in an unnamed package.\n", SwigType_namestr(name));
- }
- }
-
- /* -----------------------------------------------------------------------------
- * getProxyName()
- *
- * Test to see if a type corresponds to something wrapped with a proxy class.
- * Return NULL if not otherwise the proxy class name, fully qualified with
- * package name if the nspace feature is used, unless jnidescriptor is true as
- * the package name is handled differently (unfortunately for legacy reasons).
- * ----------------------------------------------------------------------------- */
-
- String *getProxyName(SwigType *t, bool jnidescriptor = false) {
- String *proxyname = NULL;
- if (proxy_flag) {
- Node *n = classLookup(t);
- if (n) {
- proxyname = Getattr(n, "proxyname");
- if (!proxyname || jnidescriptor) {
- String *nspace = Getattr(n, "sym:nspace");
- String *symname = Copy(Getattr(n, "sym:name"));
- if (symname && !GetFlag(n, "feature:flatnested")) {
- for (Node *outer_class = Getattr(n, "nested:outer"); outer_class; outer_class = Getattr(outer_class, "nested:outer")) {
- if (String* name = Getattr(outer_class, "sym:name")) {
- Push(symname, jnidescriptor ? "$" : ".");
- Push(symname, name);
- }
- else
- return NULL;
- }
- }
- if (nspace) {
- if (package && !jnidescriptor)
- proxyname = NewStringf("%s.%s.%s", package, nspace, symname);
- else
- proxyname = NewStringf("%s.%s", nspace, symname);
- } else {
- proxyname = Copy(symname);
- }
- if (!jnidescriptor) {
- Setattr(n, "proxyname", proxyname); // Cache it
- Delete(proxyname);
- }
- Delete(symname);
- }
- }
- }
- return proxyname;
- }
-
- /* -----------------------------------------------------------------------------
- * makeValidJniName()
- * ----------------------------------------------------------------------------- */
-
- String *makeValidJniName(const String *name) {
- String *valid_jni_name = NewString(name);
- Replaceall(valid_jni_name, "_", "_1");
- return valid_jni_name;
- }
-
- /* ------------------------------------------------------------
- * main()
- * ------------------------------------------------------------ */
-
- virtual void main(int argc, char *argv[]) {
-
- SWIG_library_directory("java");
-
- int doxygen_translator_flags = 0;
-
- // Look for certain command line options
- for (int i = 1; i < argc; i++) {
- if (argv[i]) {
- if (strcmp(argv[i], "-package") == 0) {
- if (argv[i + 1]) {
- package = NewString("");
- Printf(package, argv[i + 1]);
- if (Len(package) == 0) {
- Delete(package);
- package = 0;
- }
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if ((strcmp(argv[i], "-shadow") == 0) || ((strcmp(argv[i], "-proxy") == 0))) {
- Printf(stderr, "Deprecated command line option: %s. Proxy classes are now generated by default.\n", argv[i]);
- Swig_mark_arg(i);
- proxy_flag = true;
- } else if ((strcmp(argv[i], "-doxygen") == 0)) {
- Swig_mark_arg(i);
- doxygen = true;
- scan_doxygen_comments = true;
- } else if ((strcmp(argv[i], "-debug-doxygen-translator") == 0)) {
- Swig_mark_arg(i);
- doxygen_translator_flags |= DoxygenTranslator::debug_translator;
- } else if ((strcmp(argv[i], "-debug-doxygen-parser") == 0)) {
- Swig_mark_arg(i);
- doxygen_translator_flags |= DoxygenTranslator::debug_parser;
- } else if ((strcmp(argv[i], "-noproxy") == 0)) {
- Swig_mark_arg(i);
- proxy_flag = false;
- } else if (strcmp(argv[i], "-nopgcpp") == 0) {
- Swig_mark_arg(i);
- nopgcpp_flag = true;
- } else if (strcmp(argv[i], "-oldvarnames") == 0) {
- Swig_mark_arg(i);
- old_variable_names = true;
- } else if (strcmp(argv[i], "-jnic") == 0) {
- Swig_mark_arg(i);
- Printf(stderr, "Deprecated command line option: -jnic. C JNI calling convention now used when -c++ not specified.\n");
- } else if (strcmp(argv[i], "-nofinalize") == 0) {
- Swig_mark_arg(i);
- Printf(stderr, "Deprecated command line option: -nofinalize. Use the new javafinalize typemap instead.\n");
- } else if (strcmp(argv[i], "-jnicpp") == 0) {
- Swig_mark_arg(i);
- Printf(stderr, "Deprecated command line option: -jnicpp. C++ JNI calling convention now used when -c++ specified.\n");
- } else if (strcmp(argv[i], "-help") == 0) {
- Printf(stdout, "%s\n", usage);
- }
- }
- }
-
- if (doxygen)
- doxygenTranslator = new JavaDocConverter(doxygen_translator_flags);
-
- // Add a symbol to the parser for conditional compilation
- Preprocessor_define("SWIGJAVA 1", 0);
-
- // Add typemap definitions
- SWIG_typemap_lang("java");
- SWIG_config_file("java.swg");
-
- allow_overloading();
- Swig_interface_feature_enable();
- }
-
- /* ---------------------------------------------------------------------
- * top()
- * --------------------------------------------------------------------- */
-
- virtual int top(Node *n) {
-
- // Get any options set in the module directive
- Node *optionsnode = Getattr(Getattr(n, "module"), "options");
-
- if (optionsnode) {
- if (Getattr(optionsnode, "jniclassname"))
- imclass_name = Copy(Getattr(optionsnode, "jniclassname"));
- /* check if directors are enabled for this module. note: this
- * is a "master" switch, without which no director code will be
- * emitted. %feature("director") statements are also required
- * to enable directors for individual classes or methods.
- *
- * use %module(directors="1") modulename at the start of the
- * interface file to enable director generation.
- */
- if (Getattr(optionsnode, "directors")) {
- allow_directors();
- }
- if (Getattr(optionsnode, "dirprot")) {
- allow_dirprot();
- }
- allow_allprotected(GetFlag(optionsnode, "allprotected"));
- }
-
- /* Initialize all of the output files */
- String *outfile = Getattr(n, "outfile");
- String *outfile_h = Getattr(n, "outfile_h");
-
- if (!outfile) {
- Printf(stderr, "Unable to determine outfile\n");
- Exit(EXIT_FAILURE);
- }
-
- f_begin = NewFile(outfile, "w", SWIG_output_files());
- if (!f_begin) {
- FileErrorDisplay(outfile);
- Exit(EXIT_FAILURE);
- }
-
- if (directorsEnabled()) {
- if (!outfile_h) {
- Printf(stderr, "Unable to determine outfile_h\n");
- Exit(EXIT_FAILURE);
- }
- f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
- if (!f_runtime_h) {
- FileErrorDisplay(outfile_h);
- Exit(EXIT_FAILURE);
- }
- }
-
- f_runtime = NewString("");
- f_init = NewString("");
- f_header = NewString("");
- f_wrappers = NewString("");
- f_directors_h = NewString("");
- f_directors = NewString("");
-
- /* Register file targets with the SWIG file handler */
- Swig_register_filebyname("begin", f_begin);
- Swig_register_filebyname("header", f_header);
- Swig_register_filebyname("wrapper", f_wrappers);
- Swig_register_filebyname("runtime", f_runtime);
- Swig_register_filebyname("init", f_init);
- Swig_register_filebyname("director", f_directors);
- Swig_register_filebyname("director_h", f_directors_h);
-
- swig_types_hash = NewHash();
- filenames_list = NewList();
-
- // Make the intermediary class and module class names. The intermediary class name can be set in the module directive.
- if (!imclass_name) {
- imclass_name = NewStringf("%sJNI", Getattr(n, "name"));
- module_class_name = Copy(Getattr(n, "name"));
- } else {
- // Rename the module name if it is the same as intermediary class name - a backwards compatibility solution
- if (Cmp(imclass_name, Getattr(n, "name")) == 0)
- module_class_name = NewStringf("%sModule", Getattr(n, "name"));
- else
- module_class_name = Copy(Getattr(n, "name"));
- }
- constants_interface_name = NewStringf("%sConstants", module_class_name);
-
- // module class and intermediary classes are always created
- if (!addSymbol(imclass_name, n))
- return SWIG_ERROR;
- if (!addSymbol(module_class_name, n))
- return SWIG_ERROR;
-
- imclass_class_code = NewString("");
- proxy_class_def = NewString("");
- proxy_class_code = NewString("");
- module_class_constants_code = NewString("");
- imclass_baseclass = NewString("");
- imclass_package = NULL;
- imclass_interfaces = NewString("");
- imclass_class_modifiers = NewString("");
- module_class_code = NewString("");
- module_baseclass = NewString("");
- module_interfaces = NewString("");
- module_imports = NewString("");
- module_class_modifiers = NewString("");
- imclass_imports = NewString("");
- imclass_cppcasts_code = NewString("");
- imclass_directors = NewString("");
- upcasts_code = NewString("");
- dmethods_seq = NewList();
- dmethods_table = NewHash();
- n_dmethods = 0;
- n_directors = 0;
- jnipackage = NewString("");
- package_path = NewString("");
-
- Swig_banner(f_begin);
-
- Swig_obligatory_macros(f_runtime, "JAVA");
-
- if (directorsEnabled()) {
- Printf(f_runtime, "#define SWIG_DIRECTORS\n");
-
- /* Emit initial director header and director code: */
- Swig_banner(f_directors_h);
- Printf(f_directors_h, "\n");
- Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module_class_name);
- Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module_class_name);
-
- Printf(f_directors, "\n\n");
- Printf(f_directors, "/* ---------------------------------------------------\n");
- Printf(f_directors, " * C++ director class methods\n");
- Printf(f_directors, " * --------------------------------------------------- */\n\n");
- if (outfile_h) {
- String *filename = Swig_file_filename(outfile_h);
- Printf(f_directors, "#include \"%s\"\n\n", filename);
- Delete(filename);
- }
- }
-
- Printf(f_runtime, "\n");
-
- String *wrapper_name = NewString("");
-
- if (package) {
- String *jniname = makeValidJniName(package);
- Printv(jnipackage, jniname, NIL);
- Delete(jniname);
- Replaceall(jnipackage, ".", "_");
- Append(jnipackage, "_");
- Printv(package_path, package, NIL);
- Replaceall(package_path, ".", "/");
- }
- String *jniname = makeValidJniName(imclass_name);
- Printf(wrapper_name, "Java_%s%s_%%f", jnipackage, jniname);
- Delete(jniname);
-
- Swig_name_register("wrapper", Char(wrapper_name));
- if (old_variable_names) {
- Swig_name_register("set", "set_%n%v");
- Swig_name_register("get", "get_%n%v");
- }
-
- Delete(wrapper_name);
-
- Printf(f_wrappers, "\n#ifdef __cplusplus\n");
- Printf(f_wrappers, "extern \"C\" {\n");
- Printf(f_wrappers, "#endif\n\n");
-
- /* Emit code */
- Language::top(n);
-
- if (directorsEnabled()) {
- // Insert director runtime into the f_runtime file (make it occur before %header section)
- Swig_insert_file("director_common.swg", f_runtime);
- Swig_insert_file("director.swg", f_runtime);
- }
- // Generate the intermediary class
- {
- String *filen = NewStringf("%s%s.java", outputDirectory(imclass_package), imclass_name);
- File *f_im = NewFile(filen, "w", SWIG_output_files());
- if (!f_im) {
- FileErrorDisplay(filen);
- Exit(EXIT_FAILURE);
- }
- Append(filenames_list, Copy(filen));
- Delete(filen);
- filen = NULL;
-
- // Start writing out the intermediary class file
- emitBanner(f_im);
-
- if (imclass_package && package)
- Printf(f_im, "package %s.%s;", package, imclass_package);
- else if (imclass_package)
- Printf(f_im, "package %s;", imclass_package);
- else if (package)
- Printf(f_im, "package %s;\n", package);
-
- if (imclass_imports)
- Printf(f_im, "%s\n", imclass_imports);
-
- if (Len(imclass_class_modifiers) > 0)
- Printf(f_im, "%s ", imclass_class_modifiers);
- Printf(f_im, "%s ", imclass_name);
-
- if (imclass_baseclass && *Char(imclass_baseclass))
- Printf(f_im, "extends %s ", imclass_baseclass);
- if (Len(imclass_interfaces) > 0)
- Printv(f_im, "implements ", imclass_interfaces, " ", NIL);
- Printf(f_im, "{\n");
-
- // Add the intermediary class methods
- Replaceall(imclass_class_code, "$module", module_class_name);
- Replaceall(imclass_class_code, "$imclassname", imclass_name);
- Printv(f_im, imclass_class_code, NIL);
- Printv(f_im, imclass_cppcasts_code, NIL);
- if (Len(imclass_directors) > 0)
- Printv(f_im, "\n", imclass_directors, NIL);
-
- if (n_dmethods > 0) {
- Putc('\n', f_im);
- Printf(f_im, " private final static native void swig_module_init();\n");
- Printf(f_im, " static {\n");
- Printf(f_im, " swig_module_init();\n");
- Printf(f_im, " }\n");
- }
- // Finish off the class
- Printf(f_im, "}\n");
- Delete(f_im);
- }
-
- // Generate the Java module class
- {
- String *filen = NewStringf("%s%s.java", SWIG_output_directory(), module_class_name);
- File *f_module = NewFile(filen, "w", SWIG_output_files());
- if (!f_module) {
- FileErrorDisplay(filen);
- Exit(EXIT_FAILURE);
- }
- Append(filenames_list, Copy(filen));
- Delete(filen);
- filen = NULL;
-
- // Start writing out the module class file
- emitBanner(f_module);
-
- if (package)
- Printf(f_module, "package %s;\n", package);
-
- if (module_imports)
- Printf(f_module, "%s\n", module_imports);
-
- if (doxygen && doxygenTranslator->hasDocumentation(n)) {
- String *doxygen_comments = doxygenTranslator->getDocumentation(n, 0);
- if (comment_creation_chatter)
- Printf(f_module, "/* This was generated from top() */\n");
- Printv(f_module, Char(doxygen_comments), NIL);
- Delete(doxygen_comments);
- }
- if (Len(module_class_modifiers) > 0)
- Printf(f_module, "%s ", module_class_modifiers);
- Printf(f_module, "%s ", module_class_name);
-
- if (module_baseclass && *Char(module_baseclass))
- Printf(f_module, "extends %s ", module_baseclass);
- if (Len(module_interfaces) > 0) {
- if (Len(module_class_constants_code) != 0)
- Printv(f_module, "implements ", constants_interface_name, ", ", module_interfaces, " ", NIL);
- else
- Printv(f_module, "implements ", module_interfaces, " ", NIL);
- } else {
- if (Len(module_class_constants_code) != 0)
- Printv(f_module, "implements ", constants_interface_name, " ", NIL);
- }
- Printf(f_module, "{\n");
-
- Replaceall(module_class_code, "$module", module_class_name);
- Replaceall(module_class_constants_code, "$module", module_class_name);
-
- Replaceall(module_class_code, "$imclassname", imclass_name);
- Replaceall(module_class_constants_code, "$imclassname", imclass_name);
-
- // Add the wrapper methods
- Printv(f_module, module_class_code, NIL);
-
- // Finish off the class
- Printf(f_module, "}\n");
- Delete(f_module);
- }
-
- // Generate the Java constants interface
- if (Len(module_class_constants_code) != 0) {
- String *filen = NewStringf("%s%s.java", SWIG_output_directory(), constants_interface_name);
- File *f_module = NewFile(filen, "w", SWIG_output_files());
- if (!f_module) {
- FileErrorDisplay(filen);
- Exit(EXIT_FAILURE);
- }
- Append(filenames_list, Copy(filen));
- Delete(filen);
- filen = NULL;
-
- // Start writing out the Java constants interface file
- emitBanner(f_module);
-
- if (package)
- Printf(f_module, "package %s;\n", package);
-
- if (module_imports)
- Printf(f_module, "%s\n", module_imports);
-
- Printf(f_module, "public interface %s {\n", constants_interface_name);
-
- // Write out all the global constants
- Printv(f_module, module_class_constants_code, NIL);
-
- // Finish off the Java interface
- Printf(f_module, "}\n");
- Delete(f_module);
- }
-
- if (upcasts_code)
- Printv(f_wrappers, upcasts_code, NIL);
-
- emitDirectorUpcalls();
-
- Printf(f_wrappers, "#ifdef __cplusplus\n");
- Printf(f_wrappers, "}\n");
- Printf(f_wrappers, "#endif\n");
-
- // Output a Java type wrapper class for each SWIG type
- for (Iterator swig_type = First(swig_types_hash); swig_type.key; swig_type = Next(swig_type)) {
- emitTypeWrapperClass(swig_type.key, swig_type.item);
- }
-
- // Check for overwriting file problems on filesystems that are case insensitive
- Iterator it1;
- Iterator it2;
- for (it1 = First(filenames_list); it1.item; it1 = Next(it1)) {
- String *item1_lower = Swig_string_lower(it1.item);
- for (it2 = Next(it1); it2.item; it2 = Next(it2)) {
- String *item2_lower = Swig_string_lower(it2.item);
- if (it1.item && it2.item) {
- if (Strcmp(item1_lower, item2_lower) == 0) {
- Swig_warning(WARN_LANG_PORTABILITY_FILENAME, input_file, line_number,
- "Portability warning: File %s will be overwritten by %s on case insensitive filesystems such as "
- "Windows' FAT32 and NTFS unless the class/module name is renamed\n", it1.item, it2.item);
- }
- }
- Delete(item2_lower);
- }
- Delete(item1_lower);
- }
-
- Delete(swig_types_hash);
- swig_types_hash = NULL;
- Delete(filenames_list);
- filenames_list = NULL;
- Delete(imclass_name);
- imclass_name = NULL;
- Delete(imclass_class_code);
- imclass_class_code = NULL;
- Delete(proxy_class_def);
- proxy_class_def = NULL;
- Delete(proxy_class_code);
- proxy_class_code = NULL;
- Delete(module_class_constants_code);
- module_class_constants_code = NULL;
- Delete(imclass_baseclass);
- imclass_baseclass = NULL;
- Delete(imclass_package);
- imclass_package = NULL;
- Delete(imclass_interfaces);
- imclass_interfaces = NULL;
- Delete(imclass_class_modifiers);
- imclass_class_modifiers = NULL;
- Delete(module_class_name);
- module_class_name = NULL;
- Delete(constants_interface_name);
- constants_interface_name = NULL;
- Delete(module_class_code);
- module_class_code = NULL;
- Delete(module_baseclass);
- module_baseclass = NULL;
- Delete(module_interfaces);
- module_interfaces = NULL;
- Delete(module_imports);
- module_imports = NULL;
- Delete(module_class_modifiers);
- module_class_modifiers = NULL;
- Delete(imclass_imports);
- imclass_imports = NULL;
- Delete(imclass_cppcasts_code);
- imclass_cppcasts_code = NULL;
- Delete(imclass_directors);
- imclass_directors = NULL;
- Delete(upcasts_code);
- upcasts_code = NULL;
- Delete(package);
- package = NULL;
- Delete(jnipackage);
- jnipackage = NULL;
- Delete(package_path);
- package_path = NULL;
- Delete(dmethods_seq);
- dmethods_seq = NULL;
- Delete(dmethods_table);
- dmethods_table = NULL;
- n_dmethods = 0;
-
- /* Close all of the files */
- Dump(f_header, f_runtime);
-
- if (directorsEnabled()) {
- Dump(f_directors, f_runtime);
- Dump(f_directors_h, f_runtime_h);
-
- Printf(f_runtime_h, "\n");
- Printf(f_runtime_h, "#endif\n");
-
- Delete(f_runtime_h);
- f_runtime_h = NULL;
- Delete(f_directors);
- f_directors = NULL;
- Delete(f_directors_h);
- f_directors_h = NULL;
- }
-
- Dump(f_wrappers, f_runtime);
- Wrapper_pretty_print(f_init, f_runtime);
- Delete(f_header);
- Delete(f_wrappers);
- Delete(f_init);
- Dump(f_runtime, f_begin);
- Delete(f_runtime);
- Delete(f_begin);
- return SWIG_OK;
- }
-
- /* -----------------------------------------------------------------------------
- * emitBanner()
- * ----------------------------------------------------------------------------- */
-
- void emitBanner(File *f) {
- Printf(f, "/* ----------------------------------------------------------------------------\n");
- Swig_banner_target_lang(f, " *");
- Printf(f, " * ----------------------------------------------------------------------------- */\n\n");
- }
-
- /*-----------------------------------------------------------------------
- * Add new director upcall signature
- *----------------------------------------------------------------------*/
-
- UpcallData *addUpcallMethod(String *imclass_method, String *class_method, String *imclass_desc, String *class_desc, String *decl) {
- String *key = NewStringf("%s|%s", imclass_method, decl);
-
- ++curr_class_dmethod;
-
- String *imclass_methodidx = NewStringf("%d", n_dmethods);
- String *class_methodidx = NewStringf("%d", n_dmethods - first_class_dmethod);
- n_dmethods++;
-
- Hash *new_udata = NewHash();
- Append(dmethods_seq, new_udata);
- Setattr(dmethods_table, key, new_udata);
-
- Setattr(new_udata, "method", Copy(class_method));
- Setattr(new_udata, "fdesc", Copy(class_desc));
- Setattr(new_udata, "imclass_method", Copy(imclass_method));
- Setattr(new_udata, "imclass_fdesc", Copy(imclass_desc));
- Setattr(new_udata, "imclass_methodidx", imclass_methodidx);
- Setattr(new_udata, "class_methodidx", class_methodidx);
- Setattr(new_udata, "decl", Copy(decl));
-
- Delete(key);
- return new_udata;
- }
-
- /*-----------------------------------------------------------------------
- * Get director upcall signature
- *----------------------------------------------------------------------*/
-
- UpcallData *getUpcallMethodData(String *director_class, String *decl) {
- String *key = NewStringf("%s|%s", director_class, decl);
- UpcallData *udata = Getattr(dmethods_table, key);
-
- Delete(key);
- return udata;
- }
-
- /* ----------------------------------------------------------------------
- * nativeWrapper()
- * ---------------------------------------------------------------------- */
-
- virtual int nativeWrapper(Node *n) {
- String *wrapname = Getattr(n, "wrap:name");
-
- if (!addSymbol(wrapname, n, imclass_name))
- return SWIG_ERROR;
-
- if (Getattr(n, "type")) {
- Swig_save("nativeWrapper", n, "name", NIL);
- Setattr(n, "name", wrapname);
- native_function_flag = true;
- functionWrapper(n);
- Swig_restore(n);
- native_function_flag = false;
- } else {
- Swig_error(input_file, line_number, "No return type for %%native method %s.\n", Getattr(n, "wrap:name"));
- }
-
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * functionWrapper()
- * ---------------------------------------------------------------------- */
-
- virtual int functionWrapper(Node *n) {
- String *symname = Getattr(n, "sym:name");
- SwigType *t = Getattr(n, "type");
- ParmList *l = Getattr(n, "parms");
- String *tm;
- Parm *p;
- int i;
- String *c_return_type = NewString("");
- String *im_return_type = NewString("");
- String *cleanup = NewString("");
- String *outarg = NewString("");
- String *body = NewString("");
- int num_arguments = 0;
- int gencomma = 0;
- bool is_void_return;
- String *overloaded_name = getOverloadedName(n);
- String *nondir_args = NewString("");
- bool is_destructor = (Cmp(Getattr(n, "nodeType"), "destructor") == 0);
-
- if (!Getattr(n, "sym:overloaded")) {
- if (!addSymbol(symname, n, imclass_name))
- return SWIG_ERROR;
- }
-
- /*
- The rest of this function deals with generating the intermediary class wrapper function (that wraps
- a c/c++ function) and generating the JNI c code. Each Java wrapper function has a
- matching JNI c function call.
- */
-
- // A new wrapper function object
- Wrapper *f = NewWrapper();
-
- // Make a wrapper name for this function
- String *jniname = makeValidJniName(overloaded_name);
- String *wname = Swig_name_wrapper(jniname);
-
- Delete(jniname);
-
- /* Attach the non-standard typemaps to the parameter list. */
- Swig_typemap_attach_parms("jni", l, f);
- Swig_typemap_attach_parms("jtype", l, f);
- Swig_typemap_attach_parms("jstype", l, f);
-
- /* Get return types */
- if ((tm = Swig_typemap_lookup("jni", n, "", 0))) {
- Printf(c_return_type, "%s", tm);
- } else {
- Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number, "No jni typemap defined for %s\n", SwigType_str(t, 0));
- }
-
- if ((tm = Swig_typemap_lookup("jtype", n, "", 0))) {
- Printf(im_return_type, "%s", tm);
- } else {
- Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s\n", SwigType_str(t, 0));
- }
-
- is_void_return = (Cmp(c_return_type, "void") == 0);
- if (!is_void_return)
- Wrapper_add_localv(f, "jresult", c_return_type, "jresult = 0", NIL);
-
- Printv(f->def, "SWIGEXPORT ", c_return_type, " JNICALL ", wname, "(JNIEnv *jenv, jclass jcls", NIL);
-
- // Usually these function parameters are unused - The code below ensures
- // that compilers do not issue such a warning if configured to do so.
-
- Printv(f->code, " (void)jenv;\n", NIL);
- Printv(f->code, " (void)jcls;\n", NIL);
-
- // Emit all of the local variables for holding arguments.
- emit_parameter_variables(l, f);
-
- /* Attach the standard typemaps */
- emit_attach_parmmaps(l, f);
-
- // Parameter overloading
- Setattr(n, "wrap:parms", l);
- Setattr(n, "wrap:name", wname);
-
- // Wrappers not wanted for some methods where the parameters cannot be overloaded in Java
- if (Getattr(n, "sym:overloaded")) {
- // Emit warnings for the few cases that can't be overloaded in Java and give up on generating wrapper
- Swig_overload_check(n);
- if (Getattr(n, "overload:ignore")) {
- DelWrapper(f);
- return SWIG_OK;
- }
- }
-
- Printf(imclass_class_code, " public final static native %s %s(", im_return_type, overloaded_name);
-
- num_arguments = emit_num_arguments(l);
-
- // Now walk the function parameter list and generate code to get arguments
- for (i = 0, p = l; i < num_arguments; i++) {
-
- while (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- }
-
- SwigType *pt = Getattr(p, "type");
- String *ln = Getattr(p, "lname");
- String *im_param_type = NewString("");
- String *c_param_type = NewString("");
- String *arg = NewString("");
-
- Printf(arg, "j%s", ln);
-
- /* Get the JNI C types of the parameter */
- if ((tm = Getattr(p, "tmap:jni"))) {
- Printv(c_param_type, tm, NIL);
- } else {
- Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number, "No jni typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- /* Get the intermediary class parameter types of the parameter */
- if ((tm = Getattr(p, "tmap:jtype"))) {
- Printv(im_param_type, tm, NIL);
- } else {
- Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- /* Add parameter to intermediary class method */
- if (gencomma)
- Printf(imclass_class_code, ", ");
- Printf(imclass_class_code, "%s %s", im_param_type, arg);
-
- // Add parameter to C function
- Printv(f->def, ", ", c_param_type, " ", arg, NIL);
-
- ++gencomma;
-
- // Premature garbage collection prevention parameter
- if (!is_destructor) {
- String *pgc_parameter = prematureGarbageCollectionPreventionParameter(pt, p);
- if (pgc_parameter) {
- Printf(imclass_class_code, ", %s %s_", pgc_parameter, arg);
- Printf(f->def, ", jobject %s_", arg);
- Printf(f->code, " (void)%s_;\n", arg);
- }
- }
- // Get typemap for this argument
- if ((tm = Getattr(p, "tmap:in"))) {
- addThrows(n, "tmap:in", p);
- Replaceall(tm, "$arg", arg); /* deprecated? */
- Replaceall(tm, "$input", arg);
- Setattr(p, "emit:input", arg);
-
- Printf(nondir_args, "%s\n", tm);
-
- p = Getattr(p, "tmap:in:next");
- } else {
- Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
- p = nextSibling(p);
- }
-
- Delete(im_param_type);
- Delete(c_param_type);
- Delete(arg);
- }
-
- Printv(f->code, nondir_args, NIL);
- Delete(nondir_args);
-
- /* Insert constraint checking code */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:check"))) {
- addThrows(n, "tmap:check", p);
- Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(f->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:check:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* Insert cleanup code */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:freearg"))) {
- addThrows(n, "tmap:freearg", p);
- Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(cleanup, tm, "\n", NIL);
- p = Getattr(p, "tmap:freearg:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* Insert argument output code */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:argout"))) {
- addThrows(n, "tmap:argout", p);
- Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */
- Replaceall(tm, "$result", "jresult");
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(outarg, tm, "\n", NIL);
- p = Getattr(p, "tmap:argout:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- // Get any Java exception classes in the throws typemap
- ParmList *throw_parm_list = NULL;
- if ((throw_parm_list = Getattr(n, "catchlist"))) {
- Swig_typemap_attach_parms("throws", throw_parm_list, f);
- for (p = throw_parm_list; p; p = nextSibling(p)) {
- if (Getattr(p, "tmap:throws")) {
- addThrows(n, "tmap:throws", p);
- }
- }
- }
-
- // Now write code to make the function call
- if (!native_function_flag) {
-
- Swig_director_emit_dynamic_cast(n, f);
- String *actioncode = emit_action(n);
-
- // Handle exception classes specified in the "except" feature's "throws" attribute
- addThrows(n, "feature:except", n);
-
- /* Return value if necessary */
- if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
- addThrows(n, "tmap:out", n);
- Replaceall(tm, "$result", "jresult");
-
- if (GetFlag(n, "feature:new"))
- Replaceall(tm, "$owner", "1");
- else
- Replaceall(tm, "$owner", "0");
-
- Printf(f->code, "%s", tm);
- if (Len(tm))
- Printf(f->code, "\n");
- } else {
- Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(t, 0), Getattr(n, "name"));
- }
- emit_return_variable(n, t, f);
- }
-
- /* Output argument output code */
- Printv(f->code, outarg, NIL);
-
- /* Output cleanup code */
- Printv(f->code, cleanup, NIL);
-
- /* Look to see if there is any newfree cleanup code */
- if (GetFlag(n, "feature:new")) {
- if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
- addThrows(n, "tmap:newfree", n);
- Printf(f->code, "%s\n", tm);
- }
- }
-
- /* See if there is any return cleanup code */
- if (!native_function_flag) {
- if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
- addThrows(n, "tmap:ret", n);
- Printf(f->code, "%s\n", tm);
- }
- }
-
- /* Finish C function and intermediary class function definitions */
- Printf(imclass_class_code, ")");
- generateThrowsClause(n, imclass_class_code);
- Printf(imclass_class_code, ";\n");
-
- Printf(f->def, ") {");
-
- if (!is_void_return)
- Printv(f->code, " return jresult;\n", NIL);
- Printf(f->code, "}\n");
-
- /* Substitute the cleanup code */
- Replaceall(f->code, "$cleanup", cleanup);
-
- /* Substitute the function name */
- Replaceall(f->code, "$symname", symname);
-
- /* Contract macro modification */
- Replaceall(f->code, "SWIG_contract_assert(", "SWIG_contract_assert($null, ");
-
- if (!is_void_return)
- Replaceall(f->code, "$null", "0");
- else
- Replaceall(f->code, "$null", "");
-
- /* Dump the function out */
- if (!native_function_flag)
- Wrapper_print(f, f_wrappers);
-
- if (!(proxy_flag && is_wrapping_class()) && !enum_constant_flag) {
- moduleClassFunctionHandler(n);
- }
-
- /*
- * Generate the proxy class getters/setters for public member variables.
- * Not for enums and constants.
- */
- if (proxy_flag && wrapping_member_flag && !enum_constant_flag) {
- // Capitalize the first letter in the variable to create a JavaBean type getter/setter function name
- bool getter_flag = Cmp(symname, Swig_name_set(getNSpace(), Swig_name_member(0, getClassPrefix(), variable_name))) != 0;
-
- String *getter_setter_name = NewString("");
- if (!getter_flag)
- Printf(getter_setter_name, "set");
- else
- Printf(getter_setter_name, "get");
- Putc(toupper((int) *Char(variable_name)), getter_setter_name);
- Printf(getter_setter_name, "%s", Char(variable_name) + 1);
-
- Setattr(n, "proxyfuncname", getter_setter_name);
- Setattr(n, "imfuncname", symname);
-
- proxyClassFunctionHandler(n);
- Delete(getter_setter_name);
- }
-
- Delete(c_return_type);
- Delete(im_return_type);
- Delete(cleanup);
- Delete(outarg);
- Delete(body);
- Delete(overloaded_name);
- DelWrapper(f);
- return SWIG_OK;
- }
-
- /* -----------------------------------------------------------------------
- * variableWrapper()
- * ----------------------------------------------------------------------- */
-
- virtual int variableWrapper(Node *n) {
- variable_wrapper_flag = true;
- Language::variableWrapper(n); /* Default to functions */
- variable_wrapper_flag = false;
- return SWIG_OK;
- }
-
- /* -----------------------------------------------------------------------
- * globalvariableHandler()
- * ------------------------------------------------------------------------ */
-
- virtual int globalvariableHandler(Node *n) {
-
- variable_name = Getattr(n, "sym:name");
- global_variable_flag = true;
- int ret = Language::globalvariableHandler(n);
- global_variable_flag = false;
- return ret;
- }
-
- String *getCurrentScopeName(String *nspace) {
- String *scope = 0;
- if (nspace || getCurrentClass()) {
- scope = NewString("");
- if (nspace)
- Printf(scope, "%s", nspace);
- if (Node* cls = getCurrentClass()) {
- if (Node *outer = Getattr(cls, "nested:outer")) {
- String *outerClassesPrefix = Copy(Getattr(outer, "sym:name"));
- for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) {
- Push(outerClassesPrefix, ".");
- Push(outerClassesPrefix, Getattr(outer, "sym:name"));
- }
- Printv(scope, nspace ? "." : "", outerClassesPrefix, ".", proxy_class_name, NIL);
- Delete(outerClassesPrefix);
- } else
- Printv(scope, nspace ? "." : "", proxy_class_name, NIL);
- }
- }
- return scope;
- }
-
- /* ----------------------------------------------------------------------
- * enumDeclaration()
- *
- * C/C++ enums can be mapped in one of 4 ways, depending on the java:enum feature specified:
- * 1) Simple enums - simple constant within the proxy class or module class
- * 2) Typeunsafe enums - simple constant in a Java class (class named after the c++ enum name)
- * 3) Typesafe enum - typesafe enum pattern (class named after the c++ enum name)
- * 4) Proper enums - proper Java enum
- * Anonymous enums always default to 1)
- * ---------------------------------------------------------------------- */
-
- virtual int enumDeclaration(Node *n) {
-
- if (!ImportMode) {
- if (getCurrentClass() && (cplus_mode != PUBLIC))
- return SWIG_NOWRAP;
-
- String *nspace = Getattr(n, "sym:nspace"); // NSpace/getNSpace() only works during Language::enumDeclaration call
- if (proxy_flag && !is_wrapping_class()) {
- // Global enums / enums in a namespace
- assert(!full_imclass_name);
- constructIntermediateClassName(n);
- }
-
- enum_code = NewString("");
- String *symname = Getattr(n, "sym:name");
- String *constants_code = (proxy_flag && is_wrapping_class())? proxy_class_constants_code : module_class_constants_code;
- EnumFeature enum_feature = decodeEnumFeature(n);
- String *typemap_lookup_type = Getattr(n, "name");
-
- if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
- // Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper Java enum
-
- if (doxygen && doxygenTranslator->hasDocumentation(n)) {
- String *doxygen_comments = doxygenTranslator->getDocumentation(n, 0);
- if (comment_creation_chatter)
- Printf(enum_code, "/* This was generated from enumDeclaration() */\n");
- Printv(enum_code, Char(doxygen_comments), NIL);
- Delete(doxygen_comments);
- }
-
- String *scope = getCurrentScopeName(nspace);
- if (!addSymbol(symname, n, scope))
- return SWIG_ERROR;
-
- // Pure Java baseclass and interfaces
- const String *pure_baseclass = typemapLookup(n, "javabase", typemap_lookup_type, WARN_NONE);
- const String *pure_interfaces = typemapLookup(n, "javainterfaces", typemap_lookup_type, WARN_NONE);
-
- // Emit the enum
- Printv(enum_code, typemapLookup(n, "javaclassmodifiers", typemap_lookup_type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers (enum modifiers really)
- " ", symname, *Char(pure_baseclass) ? // Bases
- " extends " : "", pure_baseclass, *Char(pure_interfaces) ? // Interfaces
- " implements " : "", pure_interfaces, " {\n", NIL);
- if (proxy_flag && is_wrapping_class())
- Replaceall(enum_code, "$static ", "static ");
- else
- Replaceall(enum_code, "$static ", "");
- Delete(scope);
- } else {
- if (symname && !Getattr(n, "unnamedinstance"))
- Printf(constants_code, " // %s \n", symname);
- // Translate and write javadoc comment for the enum itself if flagged
- if (doxygen && doxygenTranslator->hasDocumentation(n)) {
- String *doxygen_comments = doxygenTranslator->getDocumentation(n, " ");
- if (comment_creation_chatter)
- Printf(constants_code, "/* This was generated from enumDeclaration() */\n");
- Printf(constants_code, Char(doxygen_comments));
- Printf(constants_code, "\n");
- Delete(doxygen_comments);
- }
- }
-
- // Emit each enum item
- Language::enumDeclaration(n);
-
- if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
- // Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper Java enum
- // Finish the enum declaration
- // Typemaps are used to generate the enum definition in a similar manner to proxy classes.
- Printv(enum_code, (enum_feature == ProperEnum) ? ";\n" : "", typemapLookup(n, "javabody", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF), // main body of class
- typemapLookup(n, "javacode", typemap_lookup_type, WARN_NONE), // extra Java code
- "}", NIL);
-
- Replaceall(enum_code, "$javaclassname", symname);
-
- // Substitute $enumvalues - intended usage is for typesafe enums
- if (Getattr(n, "enumvalues"))
- Replaceall(enum_code, "$enumvalues", Getattr(n, "enumvalues"));
- else
- Replaceall(enum_code, "$enumvalues", "");
-
- if (proxy_flag && is_wrapping_class()) {
- // Enums defined within the C++ class are defined within the proxy class
-
- // Add extra indentation
- Replaceall(enum_code, "\n", "\n ");
- Replaceall(enum_code, " \n", "\n");
- Printv(proxy_class_constants_code, " ", enum_code, "\n\n", NIL);
- } else {
- // Global enums are defined in their own file
- String *output_directory = outputDirectory(nspace);
- String *filen = NewStringf("%s%s.java", output_directory, symname);
- File *f_enum = NewFile(filen, "w", SWIG_output_files());
- if (!f_enum) {
- FileErrorDisplay(filen);
- Exit(EXIT_FAILURE);
- }
- Append(filenames_list, Copy(filen));
- Delete(filen);
- filen = NULL;
-
- // Start writing out the enum file
- emitBanner(f_enum);
-
- if (package || nspace) {
- Printf(f_enum, "package ");
- if (package)
- Printv(f_enum, package, nspace ? "." : "", NIL);
- if (nspace)
- Printv(f_enum, nspace, NIL);
- Printf(f_enum, ";\n");
- }
-
- Printv(f_enum, typemapLookup(n, "javaimports", typemap_lookup_type, WARN_NONE), // Import statements
- "\n", enum_code, "\n", NIL);
-
- Printf(f_enum, "\n");
- Delete(f_enum);
- Delete(output_directory);
- }
- } else {
- // Wrap C++ enum with simple constant
- Printf(enum_code, "\n");
- if (proxy_flag && is_wrapping_class())
- Printv(proxy_class_constants_code, enum_code, NIL);
- else
- Printv(module_class_constants_code, enum_code, NIL);
- }
-
- Delete(enum_code);
- enum_code = NULL;
-
- if (proxy_flag && !is_wrapping_class()) {
- Delete(full_imclass_name);
- full_imclass_name = 0;
- }
- }
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * enumvalueDeclaration()
- * ---------------------------------------------------------------------- */
-
- virtual int enumvalueDeclaration(Node *n) {
- if (getCurrentClass() && (cplus_mode != PUBLIC))
- return SWIG_NOWRAP;
-
- Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL);
- String *symname = Getattr(n, "sym:name");
- String *value = Getattr(n, "value");
- String *name = Getattr(n, "name");
- Node *parent = parentNode(n);
- int unnamedinstance = GetFlag(parent, "unnamedinstance");
- String *parent_name = Getattr(parent, "name");
- String *nspace = getNSpace();
- String *newsymname = 0;
- String *tmpValue;
-
- // Strange hack from parent method
- if (value)
- tmpValue = NewString(value);
- else
- tmpValue = NewString(name);
- // Note that this is used in enumValue() amongst other places
- Setattr(n, "value", tmpValue);
-
- // Deal with enum values that are not int
- int swigtype = SwigType_type(Getattr(n, "type"));
- if (swigtype == T_BOOL) {
- const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0";
- Setattr(n, "enumvalue", val);
- } else if (swigtype == T_CHAR) {
- String *val = NewStringf("'%(escape)s'", Getattr(n, "enumvalue"));
- Setattr(n, "enumvalue", val);
- Delete(val);
- }
-
- {
- EnumFeature enum_feature = decodeEnumFeature(parent);
-
- if ((enum_feature == SimpleEnum) && GetFlag(parent, "scopedenum")) {
- newsymname = Swig_name_member(0, Getattr(parent, "sym:name"), symname);
- symname = newsymname;
- }
-
- // Add to language symbol table
- String *scope = 0;
- if (unnamedinstance || !parent_name || enum_feature == SimpleEnum) {
- String *enumClassPrefix = getEnumClassPrefix();
- if (enumClassPrefix) {
- scope = NewString("");
- if (nspace)
- Printf(scope, "%s.", nspace);
- Printf(scope, "%s", enumClassPrefix);
- } else {
- scope = Copy(constants_interface_name);
- }
- } else {
- scope = getCurrentScopeName(nspace);
- if (!scope)
- scope = Copy(Getattr(parent, "sym:name"));
- else
- Printf(scope, ".%s", Getattr(parent, "sym:name"));
- }
- if (!addSymbol(symname, n, scope))
- return SWIG_ERROR;
-
- if ((enum_feature == ProperEnum) && parent_name && !unnamedinstance) {
- if (!GetFlag(n, "firstenumitem"))
- Printf(enum_code, ",\n");
- }
-
- // Translate and write javadoc comment if flagged
- if (doxygen && doxygenTranslator->hasDocumentation(n)) {
- String *doxygen_comments = doxygenTranslator->getDocumentation(n, " ");
- if (comment_creation_chatter)
- Printf(enum_code, "/* This was generated from enumvalueDeclaration() */\n");
- Printv(enum_code, Char(doxygen_comments), NIL);
- Delete(doxygen_comments);
- }
-
- if ((enum_feature == ProperEnum) && parent_name && !unnamedinstance) {
- // Wrap (non-anonymous) C/C++ enum with a proper Java enum
- // Emit the enum item.
- Printf(enum_code, " %s", symname);
- if (Getattr(n, "enumvalue")) {
- String *value = enumValue(n);
- Printf(enum_code, "(%s)", value);
- Delete(value);
- }
- } else {
- // Wrap C/C++ enums with constant integers or use the typesafe enum pattern
- SwigType *typemap_lookup_type = parent_name ? parent_name : NewString("enum ");
- Setattr(n, "type", typemap_lookup_type);
- const String *tm = typemapLookup(n, "jstype", typemap_lookup_type, WARN_JAVA_TYPEMAP_JSTYPE_UNDEF);
-
- String *return_type = Copy(tm);
- substituteClassname(typemap_lookup_type, return_type);
- const String *methodmods = Getattr(n, "feature:java:methodmodifiers");
- methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
-
- if ((enum_feature == TypesafeEnum) && parent_name && !unnamedinstance) {
- // Wrap (non-anonymous) enum using the typesafe enum pattern
- if (Getattr(n, "enumvalue")) {
- String *value = enumValue(n);
- Printf(enum_code, " %s final static %s %s = new %s(\"%s\", %s);\n", methodmods, return_type, symname, return_type, symname, value);
- Delete(value);
- } else {
- Printf(enum_code, " %s final static %s %s = new %s(\"%s\");\n", methodmods, return_type, symname, return_type, symname);
- }
- } else {
- // Simple integer constants
- // Note these are always generated for anonymous enums, no matter what enum_feature is specified
- // Code generated is the same for SimpleEnum and TypeunsafeEnum -> the class it is generated into is determined later
- String *value = enumValue(n);
- Printf(enum_code, " %s final static %s %s = %s;\n", methodmods, return_type, symname, value);
- Delete(value);
- }
- Delete(return_type);
- }
-
- // Add the enum value to the comma separated list being constructed in the enum declaration.
- String *enumvalues = Getattr(parent, "enumvalues");
- if (!enumvalues)
- Setattr(parent, "enumvalues", Copy(symname));
- else
- Printv(enumvalues, ", ", symname, NIL);
- Delete(scope);
- }
-
- Delete(newsymname);
- Delete(tmpValue);
- Swig_restore(n);
- return SWIG_OK;
- }
-
- /* -----------------------------------------------------------------------
- * constantWrapper()
- * Used for wrapping constants - #define or %constant.
- * Also for inline initialised const static primitive type member variables (short, int, double, enums etc).
- * Java static final variables are generated for these.
- * If the %javaconst(1) feature is used then the C constant value is used to initialise the Java final variable.
- * If not, a JNI method is generated to get the C constant value for initialisation of the Java final variable.
- * However, if the %javaconstvalue feature is used, it overrides all other ways to generate the initialisation.
- * Also note that this method might be called for wrapping enum items (when the enum is using %javaconst(0)).
- * ------------------------------------------------------------------------ */
-
- virtual int constantWrapper(Node *n) {
- String *symname = Getattr(n, "sym:name");
- SwigType *t = Getattr(n, "type");
- SwigType *valuetype = Getattr(n, "valuetype");
- ParmList *l = Getattr(n, "parms");
- String *tm;
- String *return_type = NewString("");
- String *constants_code = NewString("");
- Swig_save("constantWrapper", n, "value", NIL);
-
- // Translate and write javadoc comment if flagged
- if (doxygen && doxygenTranslator->hasDocumentation(n)) {
- String *doxygen_comments = doxygenTranslator->getDocumentation(n, " ");
- if (comment_creation_chatter)
- Printf(constants_code, "/* This was generated from constantWrapper() */\n");
- Printv(constants_code, Char(doxygen_comments), NIL);
- Delete(doxygen_comments);
- }
-
- bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0);
-
- const String *itemname = (proxy_flag && wrapping_member_flag) ? variable_name : symname;
- if (!is_enum_item) {
- String *scope = 0;
- if (proxy_class_name) {
- String *nspace = getNSpace();
- scope = NewString("");
- if (nspace)
- Printf(scope, "%s.", nspace);
- Printf(scope, "%s", proxy_class_name);
- } else {
- scope = Copy(constants_interface_name);
- }
- if (!addSymbol(itemname, n, scope))
- return SWIG_ERROR;
- Delete(scope);
- }
-
- // The %javaconst feature determines how the constant value is obtained
- int const_feature_flag = GetFlag(n, "feature:java:const");
-
- /* Adjust the enum type for the Swig_typemap_lookup.
- * We want the same jstype typemap for all the enum items so we use the enum type (parent node). */
- if (is_enum_item) {
- t = Getattr(parentNode(n), "enumtype");
- Setattr(n, "type", t);
- }
-
- /* Attach the non-standard typemaps to the parameter list. */
- Swig_typemap_attach_parms("jstype", l, NULL);
-
- /* Get Java return types */
- bool classname_substituted_flag = false;
-
- if ((tm = Swig_typemap_lookup("jstype", n, "", 0))) {
- classname_substituted_flag = substituteClassname(t, tm);
- Printf(return_type, "%s", tm);
- } else {
- Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(t, 0));
- }
-
- // Add the stripped quotes back in
- String *new_value = NewString("");
- if (SwigType_type(t) == T_STRING) {
- Printf(new_value, "\"%s\"", Copy(Getattr(n, "value")));
- Setattr(n, "value", new_value);
- } else if (SwigType_type(t) == T_CHAR) {
- Printf(new_value, "\'%s\'", Copy(Getattr(n, "value")));
- Setattr(n, "value", new_value);
- }
-
- const String *methodmods = Getattr(n, "feature:java:methodmodifiers");
- methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
-
- Printf(constants_code, " %s final static %s %s = ", methodmods, return_type, itemname);
-
- // Check for the %javaconstvalue feature
- String *value = Getattr(n, "feature:java:constvalue");
-
- if (value) {
- Printf(constants_code, "%s;\n", value);
- } else if (!const_feature_flag) {
- // Default enum and constant handling will work with any type of C constant and initialises the Java variable from C through a JNI call.
-
- if (classname_substituted_flag) {
- if (SwigType_isenum(t)) {
- // This handles wrapping of inline initialised const enum static member variables (not when wrapping enum items - ignored later on)
- Printf(constants_code, "%s.swigToEnum(%s.%s());\n", return_type, full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname));
- } else {
- // This handles function pointers using the %constant directive
- Printf(constants_code, "new %s(%s.%s(), false);\n", return_type, full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname));
- }
- } else {
- Printf(constants_code, "%s.%s();\n", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname));
- }
-
- // Each constant and enum value is wrapped with a separate JNI function call
- SetFlag(n, "feature:immutable");
- enum_constant_flag = true;
- variableWrapper(n);
- enum_constant_flag = false;
- } else {
- // Alternative constant handling will use the C syntax to make a true Java constant and hope that it compiles as Java code
- if (Getattr(n, "wrappedasconstant")) {
- if (SwigType_type(valuetype) == T_CHAR)
- Printf(constants_code, "\'%(escape)s\';\n", Getattr(n, "staticmembervariableHandler:value"));
- else
- Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value"));
- } else {
- Printf(constants_code, "%s;\n", Getattr(n, "value"));
- }
- }
-
- // Emit the generated code to appropriate place
- // Enums only emit the intermediate and JNI methods, so no proxy or module class wrapper methods needed
- if (!is_enum_item) {
- if (proxy_flag && wrapping_member_flag)
- Printv(proxy_class_constants_code, constants_code, NIL);
- else
- Printv(module_class_constants_code, constants_code, NIL);
- }
- // Cleanup
- Swig_restore(n);
- Delete(new_value);
- Delete(return_type);
- Delete(constants_code);
- return SWIG_OK;
- }
-
- /* -----------------------------------------------------------------------------
- * insertDirective()
- * ----------------------------------------------------------------------------- */
-
- virtual int insertDirective(Node *n) {
- int ret = SWIG_OK;
- String *code = Getattr(n, "code");
- String *section = Getattr(n, "section");
- Replaceall(code, "$module", module_class_name);
- Replaceall(code, "$imclassname", imclass_name);
-
- if (!ImportMode && (Cmp(section, "proxycode") == 0)) {
- if (proxy_class_code) {
- Swig_typemap_replace_embedded_typemap(code, n);
- int offset = Len(code) > 0 && *Char(code) == '\n' ? 1 : 0;
- Printv(proxy_class_code, Char(code) + offset, "\n", NIL);
- }
- } else {
- ret = Language::insertDirective(n);
- }
- return ret;
- }
-
- /* -----------------------------------------------------------------------------
- * pragmaDirective()
- *
- * Valid Pragmas:
- * jniclassbase - base (extends) for the intermediary class
- * jniclasspackage - package in which to generate the intermediary class
- * jniclassclassmodifiers - class modifiers for the intermediary class
- * jniclasscode - text (java code) is copied verbatim to the intermediary class
- * jniclassimports - import statements for the intermediary class
- * jniclassinterfaces - interface (implements) for the intermediary class
- *
- * modulebase - base (extends) for the module class
- * moduleclassmodifiers - class modifiers for the module class
- * modulecode - text (java code) is copied verbatim to the module class
- * moduleimports - import statements for the module class
- * moduleinterfaces - interface (implements) for the module class
- *
- * ----------------------------------------------------------------------------- */
-
- virtual int pragmaDirective(Node *n) {
- if (!ImportMode) {
- String *lang = Getattr(n, "lang");
- String *code = Getattr(n, "name");
- String *value = Getattr(n, "value");
-
- if (Strcmp(lang, "java") == 0) {
-
- String *strvalue = NewString(value);
- Replaceall(strvalue, "\\\"", "\"");
-
- if (Strcmp(code, "jniclassbase") == 0) {
- Delete(imclass_baseclass);
- imclass_baseclass = Copy(strvalue);
- } else if (Strcmp(code, "jniclasspackage") == 0) {
- Delete(imclass_package);
- imclass_package = Copy(strvalue);
- String *imclass_class_package_jniname = makeValidJniName(imclass_package);
- Printv(jnipackage, imclass_class_package_jniname, NIL);
- Delete(imclass_class_package_jniname);
- Replaceall(jnipackage, NSPACE_SEPARATOR, "_");
- Append(jnipackage, "_");
-
- String *wrapper_name = NewString("");
- String *imclass_class_jniname = makeValidJniName(imclass_name);
- Printf(wrapper_name, "Java_%s%s_%%f", jnipackage, imclass_class_jniname);
- Delete(imclass_class_jniname);
-
- Swig_name_unregister("wrapper");
- Swig_name_register("wrapper", Char(wrapper_name));
-
- Delete(wrapper_name);
- } else if (Strcmp(code, "jniclassclassmodifiers") == 0) {
- Delete(imclass_class_modifiers);
- imclass_class_modifiers = Copy(strvalue);
- } else if (Strcmp(code, "jniclasscode") == 0) {
- Printf(imclass_class_code, "%s\n", strvalue);
- } else if (Strcmp(code, "jniclassimports") == 0) {
- Delete(imclass_imports);
- imclass_imports = Copy(strvalue);
- } else if (Strcmp(code, "jniclassinterfaces") == 0) {
- Delete(imclass_interfaces);
- imclass_interfaces = Copy(strvalue);
- } else if (Strcmp(code, "modulebase") == 0) {
- Delete(module_baseclass);
- module_baseclass = Copy(strvalue);
- } else if (Strcmp(code, "moduleclassmodifiers") == 0) {
- Delete(module_class_modifiers);
- module_class_modifiers = Copy(strvalue);
- } else if (Strcmp(code, "modulecode") == 0) {
- Printf(module_class_code, "%s\n", strvalue);
- } else if (Strcmp(code, "moduleimports") == 0) {
- Delete(module_imports);
- module_imports = Copy(strvalue);
- } else if (Strcmp(code, "moduleinterfaces") == 0) {
- Delete(module_interfaces);
- module_interfaces = Copy(strvalue);
- } else if (Strcmp(code, "moduleimport") == 0) {
- Swig_error(input_file, line_number, "Deprecated pragma. Please use the moduleimports pragma.\n");
- } else if (Strcmp(code, "moduleinterface") == 0) {
- Swig_error(input_file, line_number, "Deprecated pragma. Please use the moduleinterfaces pragma.\n");
- } else if (Strcmp(code, "modulemethodmodifiers") == 0) {
- Swig_error(input_file, line_number, "Deprecated pragma. Please use %%javamethodmodifiers.\n");
- } else if (Strcmp(code, "allshadowimport") == 0) {
- Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javaimports).\n");
- } else if (Strcmp(code, "allshadowcode") == 0) {
- Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javacode).\n");
- } else if (Strcmp(code, "allshadowbase") == 0) {
- Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javabase).\n");
- } else if (Strcmp(code, "allshadowinterface") == 0) {
- Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javainterfaces).\n");
- } else if (Strcmp(code, "allshadowclassmodifiers") == 0) {
- Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javaclassmodifiers).\n");
- } else if (proxy_flag) {
- if (Strcmp(code, "shadowcode") == 0) {
- Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javacode).\n");
- } else if (Strcmp(code, "shadowimport") == 0) {
- Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javaimports).\n");
- } else if (Strcmp(code, "shadowbase") == 0) {
- Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javabase).\n");
- } else if (Strcmp(code, "shadowinterface") == 0) {
- Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javainterfaces).\n");
- } else if (Strcmp(code, "shadowclassmodifiers") == 0) {
- Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javaclassmodifiers).\n");
- } else {
- Swig_error(input_file, line_number, "Unrecognized pragma.\n");
- }
- } else {
- Swig_error(input_file, line_number, "Unrecognized pragma.\n");
- }
- Delete(strvalue);
- }
- }
- return Language::pragmaDirective(n);
- }
-
- /* -----------------------------------------------------------------------------
- * getQualifiedInterfaceName()
- * ----------------------------------------------------------------------------- */
-
- String *getQualifiedInterfaceName(Node *n) {
- String *ret = Getattr(n, "interface:qname");
- if (!ret) {
- String *nspace = Getattr(n, "sym:nspace");
- String *symname = Getattr(n, "interface:name");
- if (nspace) {
- if (package)
- ret = NewStringf("%s.%s.%s", package, nspace, symname);
- else
- ret = NewStringf("%s.%s", nspace, symname);
- } else {
- ret = Copy(symname);
- }
- Setattr(n, "interface:qname", ret);
- }
- return ret;
- }
-
- /* -----------------------------------------------------------------------------
- * getInterfaceName()
- * ----------------------------------------------------------------------------- */
-
- String *getInterfaceName(SwigType *t, bool qualified) {
- String *interface_name = NULL;
- if (proxy_flag) {
- Node *n = classLookup(t);
- if (n && Getattr(n, "interface:name"))
- interface_name = qualified ? getQualifiedInterfaceName(n) : Getattr(n, "interface:name");
- }
- return interface_name;
- }
-
- /* -----------------------------------------------------------------------------
- * addInterfaceNameAndUpcasts()
- * ----------------------------------------------------------------------------- */
-
- void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, List *base_list, SwigType *c_classname) {
- for (Iterator it = First(base_list); it.item; it = Next(it)) {
- Node *base = it.item;
- SwigType *c_baseclassname = Getattr(base, "name");
- String *interface_name = Getattr(base, "interface:name");
- if (Len(interface_list))
- Append(interface_list, ", ");
- Append(interface_list, interface_name);
-
- Node *attributes = NewHash();
- String *interface_code = Copy(typemapLookup(base, "javainterfacecode", Getattr(base, "classtypeobj"), WARN_JAVA_TYPEMAP_INTERFACECODE_UNDEF, attributes));
- String *cptr_method_name = 0;
- if (interface_code) {
- Replaceall(interface_code, "$interfacename", interface_name);
- Printv(interface_upcasts, interface_code, NIL);
- cptr_method_name = Copy(Getattr(attributes, "tmap:javainterfacecode:cptrmethod"));
- }
- if (!cptr_method_name)
- cptr_method_name = NewStringf("%s_GetInterfaceCPtr", interface_name);
- Replaceall(cptr_method_name, ".", "_");
- Replaceall(cptr_method_name, "$interfacename", interface_name);
-
- String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), cptr_method_name);
- upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname);
-
- Delete(upcast_method_name);
- Delete(cptr_method_name);
- Delete(interface_code);
- }
- }
-
- /* -----------------------------------------------------------------------------
- * upcastsCode()
- *
- * Add code for C++ casting to base class
- * ----------------------------------------------------------------------------- */
-
- void upcastsCode(SwigType *smart, String *upcast_method_name, SwigType *c_classname, SwigType *c_baseclassname) {
- String *jniname = makeValidJniName(upcast_method_name);
- String *wname = Swig_name_wrapper(jniname);
-
- Printf(imclass_cppcasts_code, " public final static native long %s(long jarg1);\n", upcast_method_name);
-
- String *classname = SwigType_namestr(c_classname);
- String *baseclassname = SwigType_namestr(c_baseclassname);
- if (smart) {
- String *smartnamestr = SwigType_namestr(smart);
- String *bsmartnamestr = SwigType_namestr(smart);
-
- // TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
- SwigType *rclassname = SwigType_typedef_resolve_all(classname);
- SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname);
- Replaceall(bsmartnamestr, rclassname, rbaseclassname);
-
- Printv(upcasts_code,
- "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n",
- " jlong baseptr = 0;\n"
- " ", smartnamestr, " *argp1;\n"
- " (void)jenv;\n"
- " (void)jcls;\n"
- " argp1 = *(", smartnamestr, " **)&jarg1;\n"
- " *(", bsmartnamestr, " **)&baseptr = argp1 ? new ", bsmartnamestr, "(*argp1) : 0;\n"
- " return baseptr;\n"
- "}\n", "\n", NIL);
-
- Delete(rbaseclassname);
- Delete(rclassname);
- Delete(bsmartnamestr);
- Delete(smartnamestr);
- } else {
- Printv(upcasts_code,
- "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n",
- " jlong baseptr = 0;\n"
- " (void)jenv;\n"
- " (void)jcls;\n"
- " *(", baseclassname, " **)&baseptr = *(", classname, " **)&jarg1;\n"
- " return baseptr;\n"
- "}\n", "\n", NIL);
- }
-
- Delete(baseclassname);
- Delete(classname);
- Delete(wname);
- Delete(jniname);
- }
-
- /* -----------------------------------------------------------------------------
- * emitProxyClassDefAndCPPCasts()
- * ----------------------------------------------------------------------------- */
-
- void emitProxyClassDefAndCPPCasts(Node *n) {
- SwigType *c_classname = Getattr(n, "name");
- SwigType *c_baseclassname = NULL;
- String *baseclass = NULL;
- String *interface_list = NewStringEmpty();
- String *interface_upcasts = NewStringEmpty();
- SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
- bool feature_director = Swig_directorclass(n) ? true : false;
- bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested");
- SwigType *smart = Swig_cparse_smartptr(n);
-
- // Inheritance from pure Java classes
- Node *attributes = NewHash();
- const String *pure_baseclass = typemapLookup(n, "javabase", typemap_lookup_type, WARN_NONE, attributes);
- bool purebase_replace = GetFlag(attributes, "tmap:javabase:replace") ? true : false;
- bool purebase_notderived = GetFlag(attributes, "tmap:javabase:notderived") ? true : false;
- Delete(attributes);
-
- // C++ inheritance
- if (!purebase_replace) {
- List *baselist = Getattr(n, "bases");
- if (baselist) {
- Iterator base = First(baselist);
- while (base.item) {
- if (!(GetFlag(base.item, "feature:ignore") || GetFlag(base.item, "feature:interface"))) {
- SwigType *baseclassname = Getattr(base.item, "name");
- if (!c_baseclassname) {
- String *name = getProxyName(baseclassname);
- if (name) {
- c_baseclassname = baseclassname;
- baseclass = name;
- }
- } else {
- /* Warn about multiple inheritance for additional base class(es) */
- String *proxyclassname = Getattr(n, "classtypeobj");
- Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
- "Warning for %s, base %s ignored. Multiple inheritance is not supported in Java.\n", SwigType_namestr(proxyclassname), SwigType_namestr(baseclassname));
- }
- }
- base = Next(base);
- }
- }
- }
-
- List *interface_bases = Getattr(n, "interface:bases");
- if (interface_bases)
- addInterfaceNameAndUpcasts(smart, interface_list, interface_upcasts, interface_bases, c_classname);
-
- bool derived = baseclass != 0;
- if (derived && purebase_notderived)
- pure_baseclass = empty_string;
- const String *wanted_base = baseclass ? baseclass : pure_baseclass;
-
- if (purebase_replace) {
- wanted_base = pure_baseclass;
- derived = false;
- baseclass = NULL;
- if (purebase_notderived)
- Swig_error(Getfile(n), Getline(n), "The javabase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", typemap_lookup_type);
- } else if (Len(pure_baseclass) > 0 && Len(baseclass) > 0) {
- Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
- "Warning for %s, base %s ignored. Multiple inheritance is not supported in Java. "
- "Perhaps you need one of the 'replace' or 'notderived' attributes in the javabase typemap?\n", typemap_lookup_type, pure_baseclass);
- }
-
- // Pure Java interfaces
- const String *pure_interfaces = typemapLookup(n, "javainterfaces", typemap_lookup_type, WARN_NONE);
-
- if (*Char(interface_list) && *Char(pure_interfaces))
- Append(interface_list, ", ");
- Append(interface_list, pure_interfaces);
- // Start writing the proxy class
- if (!has_outerclass) // Import statements
- Printv(proxy_class_def, typemapLookup(n, "javaimports", typemap_lookup_type, WARN_NONE),"\n", NIL);
-
- // Translate and write javadoc comment if flagged
- if (doxygen && doxygenTranslator->hasDocumentation(n)) {
- String *doxygen_comments = doxygenTranslator->getDocumentation(n, 0);
- if (comment_creation_chatter)
- Printf(proxy_class_def, "/* This was generated from emitProxyClassDefAndCPPCasts() */\n");
- Printv(proxy_class_def, Char(doxygen_comments), NIL);
- Delete(doxygen_comments);
- }
-
- if (has_outerclass)
- Printv(proxy_class_def, "static ", NIL); // C++ nested classes correspond to static java classes
- Printv(proxy_class_def, typemapLookup(n, "javaclassmodifiers", typemap_lookup_type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
- " $javaclassname", // Class name and bases
- (*Char(wanted_base)) ? " extends " : "", wanted_base, *Char(interface_list) ? // Pure Java interfaces
- " implements " : "", interface_list, " {", derived ? typemapLookup(n, "javabody_derived", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF) : // main body of class
- typemapLookup(n, "javabody", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF), // main body of class
- NIL);
-
- // C++ destructor is wrapped by the delete method
- // Note that the method name is specified in a typemap attribute called methodname
- String *destruct = NewString("");
- const String *tm = NULL;
- attributes = NewHash();
- const String *destruct_methodname = NULL;
- const String *destruct_methodmodifiers = NULL;
- const String *destruct_parameters = NULL;
- if (derived) {
- tm = typemapLookup(n, "javadestruct_derived", typemap_lookup_type, WARN_NONE, attributes);
- destruct_methodname = Getattr(attributes, "tmap:javadestruct_derived:methodname");
- destruct_methodmodifiers = Getattr(attributes, "tmap:javadestruct_derived:methodmodifiers");
- destruct_parameters = Getattr(attributes, "tmap:javadestruct_derived:parameters");
- } else {
- tm = typemapLookup(n, "javadestruct", typemap_lookup_type, WARN_NONE, attributes);
- destruct_methodname = Getattr(attributes, "tmap:javadestruct:methodname");
- destruct_methodmodifiers = Getattr(attributes, "tmap:javadestruct:methodmodifiers");
- destruct_parameters = Getattr(attributes, "tmap:javadestruct:parameters");
- }
- if (tm && *Char(tm)) {
- if (!destruct_methodname) {
- Swig_error(Getfile(n), Getline(n), "No methodname attribute defined in javadestruct%s typemap for %s\n", (derived ? "_derived" : ""), proxy_class_name);
- }
- if (!destruct_methodmodifiers) {
- Swig_error(Getfile(n), Getline(n), "No methodmodifiers attribute defined in javadestruct%s typemap for %s.\n", (derived ? "_derived" : ""), proxy_class_name);
- }
- if (!destruct_parameters)
- destruct_parameters = empty_string;
- }
- // Emit the finalize and delete methods
- if (tm) {
- // Finalize method
- if (*Char(destructor_call)) {
- Printv(proxy_class_def, typemapLookup(n, "javafinalize", typemap_lookup_type, WARN_NONE), NIL);
- }
- // delete method
- Printv(destruct, tm, NIL);
- if (*Char(destructor_call))
- Replaceall(destruct, "$jnicall", destructor_call);
- else
- Replaceall(destruct, "$jnicall", "throw new UnsupportedOperationException(\"C++ destructor does not have public access\")");
- if (*Char(destruct)) {
- Printv(proxy_class_def, "\n ", NIL);
- const String *methodmods = Getattr(n, "destructmethodmodifiers");
- if (methodmods)
- Printv(proxy_class_def, methodmods, NIL);
- else
- Printv(proxy_class_def, destruct_methodmodifiers, NIL);
- Printv(proxy_class_def, " void ", destruct_methodname, "(", destruct_parameters, ")", destructor_throws_clause, " ", destruct, "\n", NIL);
- }
- }
- if (*Char(interface_upcasts))
- Printv(proxy_class_def, interface_upcasts, NIL);
-
- /* Insert directordisconnect typemap, if this class has directors enabled */
- /* Also insert the swigTakeOwnership and swigReleaseOwnership methods */
- if (feature_director) {
- String *destruct_jnicall, *release_jnicall, *take_jnicall;
- String *changeown_method_name = Swig_name_member(getNSpace(), getClassPrefix(), "change_ownership");
-
- destruct_jnicall = NewStringf("%s()", destruct_methodname);
- release_jnicall = NewStringf("%s.%s(this, swigCPtr, false)", full_imclass_name, changeown_method_name);
- take_jnicall = NewStringf("%s.%s(this, swigCPtr, true)", full_imclass_name, changeown_method_name);
-
- emitCodeTypemap(n, false, typemap_lookup_type, "directordisconnect", "methodname", destruct_jnicall);
- emitCodeTypemap(n, false, typemap_lookup_type, "directorowner_release", "methodname", release_jnicall);
- emitCodeTypemap(n, false, typemap_lookup_type, "directorowner_take", "methodname", take_jnicall);
-
- Delete(destruct_jnicall);
- Delete(changeown_method_name);
- Delete(release_jnicall);
- Delete(take_jnicall);
- }
-
- Delete(interface_upcasts);
- Delete(interface_list);
- Delete(attributes);
- Delete(destruct);
-
- // Emit extra user code
- Printv(proxy_class_def, typemapLookup(n, "javacode", typemap_lookup_type, WARN_NONE), // extra Java code
- "\n", NIL);
-
- if (derived) {
- String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), smart != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast");
- upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname);
- Delete(upcast_method_name);
- }
-
- Delete(smart);
- }
-
- /* ----------------------------------------------------------------------
- * emitInterfaceDeclaration()
- * ---------------------------------------------------------------------- */
-
- void emitInterfaceDeclaration(Node *n, String *interface_name, File *f_interface, String *nspace) {
- if (package || nspace) {
- Printf(f_interface, "package ");
- if (package)
- Printv(f_interface, package, nspace ? "." : "", NIL);
- if (nspace)
- Printv(f_interface, nspace, NIL);
- Printf(f_interface, ";\n");
- }
-
- Printv(f_interface, typemapLookup(n, "javaimports", Getattr(n, "classtypeobj"), WARN_NONE), "\n", NIL);
- Printv(f_interface, typemapLookup(n, "javainterfacemodifiers", Getattr(n, "classtypeobj"), WARN_JAVA_TYPEMAP_INTERFACEMODIFIERS_UNDEF), NIL);
- Printf(f_interface, " %s", interface_name);
- if (List *baselist = Getattr(n, "bases")) {
- String *bases = 0;
- for (Iterator base = First(baselist); base.item; base = Next(base)) {
- if (GetFlag(base.item, "feature:ignore") || !GetFlag(base.item, "feature:interface"))
- continue; // TODO: warn about skipped non-interface bases
- String *base_iname = Getattr(base.item, "interface:name");
- if (!bases)
- bases = Copy(base_iname);
- else {
- Append(bases, ", ");
- Append(bases, base_iname);
- }
- }
- if (bases) {
- Printv(f_interface, " extends ", bases, NIL);
- Delete(bases);
- }
- }
- Printf(f_interface, " {\n");
-
- Node *attributes = NewHash();
- String *interface_code = Copy(typemapLookup(n, "javainterfacecode", Getattr(n, "classtypeobj"), WARN_JAVA_TYPEMAP_INTERFACECODE_UNDEF, attributes));
- if (interface_code) {
- String *interface_declaration = Copy(Getattr(attributes, "tmap:javainterfacecode:declaration"));
- if (interface_declaration) {
- Replaceall(interface_declaration, "$interfacename", interface_name);
- Printv(f_interface, interface_declaration, NIL);
- Delete(interface_declaration);
- }
- Delete(interface_code);
- }
- }
-
- /* ----------------------------------------------------------------------
- * classDeclaration()
- * ---------------------------------------------------------------------- */
-
- int classDeclaration(Node *n) {
- return Language::classDeclaration(n);
- }
-
- /* ----------------------------------------------------------------------
- * classHandler()
- * ---------------------------------------------------------------------- */
-
- virtual int classHandler(Node *n) {
- File *f_proxy = NULL;
- File *f_interface = NULL;
- String *old_proxy_class_name = proxy_class_name;
- String *old_full_proxy_class_name = full_proxy_class_name;
- String *old_full_imclass_name = full_imclass_name;
- String *old_destructor_call = destructor_call;
- String *old_destructor_throws_clause = destructor_throws_clause;
- String *old_proxy_class_constants_code = proxy_class_constants_code;
- String *old_proxy_class_def = proxy_class_def;
- String *old_proxy_class_code = proxy_class_code;
- bool has_outerclass = Getattr(n, "nested:outer") && !GetFlag(n, "feature:flatnested");
- String *old_interface_class_code = interface_class_code;
- interface_class_code = 0;
-
- if (proxy_flag) {
- proxy_class_name = NewString(Getattr(n, "sym:name"));
- String *nspace = getNSpace();
- constructIntermediateClassName(n);
-
- String *outerClassesPrefix = 0;
- if (Node *outer = Getattr(n, "nested:outer")) {
- outerClassesPrefix = Copy(Getattr(outer, "sym:name"));
- for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) {
- Push(outerClassesPrefix, ".");
- Push(outerClassesPrefix, Getattr(outer, "sym:name"));
- }
- }
- if (!nspace) {
- full_proxy_class_name = outerClassesPrefix ? NewStringf("%s.%s", outerClassesPrefix, proxy_class_name) : NewStringf("%s", proxy_class_name);
-
- if (Cmp(proxy_class_name, imclass_name) == 0) {
- Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name);
- Exit(EXIT_FAILURE);
- }
-
- if (Cmp(proxy_class_name, module_class_name) == 0) {
- Printf(stderr, "Class name cannot be equal to module class name: %s\n", proxy_class_name);
- Exit(EXIT_FAILURE);
- }
- } else {
- if (outerClassesPrefix) {
- if (package)
- full_proxy_class_name = NewStringf("%s.%s.%s.%s", package, nspace, outerClassesPrefix, proxy_class_name);
- else
- full_proxy_class_name = NewStringf("%s.%s.%s", nspace, outerClassesPrefix, proxy_class_name);
- } else {
- if (package)
- full_proxy_class_name = NewStringf("%s.%s.%s", package, nspace, proxy_class_name);
- else
- full_proxy_class_name = NewStringf("%s.%s", nspace, proxy_class_name);
- }
- }
-
- String *interface_name = GetFlag(n, "feature:interface") ? Getattr(n, "interface:name") : 0;
- if (outerClassesPrefix) {
- String *fnspace = nspace ? NewStringf("%s.%s", nspace, outerClassesPrefix) : outerClassesPrefix;
- if (!addSymbol(proxy_class_name, n, fnspace))
- return SWIG_ERROR;
- if (interface_name && !addInterfaceSymbol(interface_name, n, fnspace))
- return SWIG_ERROR;
- if (nspace)
- Delete(fnspace);
- Delete(outerClassesPrefix);
- } else {
- if (!addSymbol(proxy_class_name, n, nspace))
- return SWIG_ERROR;
- if (interface_name && !addInterfaceSymbol(interface_name, n, nspace))
- return SWIG_ERROR;
- }
-
- // Each outer proxy class goes into a separate file
- if (!has_outerclass) {
- String *output_directory = outputDirectory(nspace);
- String *filen = NewStringf("%s%s.java", output_directory, proxy_class_name);
- f_proxy = NewFile(filen, "w", SWIG_output_files());
- if (!f_proxy) {
- FileErrorDisplay(filen);
- Exit(EXIT_FAILURE);
- }
- Append(filenames_list, Copy(filen));
- Delete(filen);
- Delete(output_directory);
-
- // Start writing out the proxy class file
- emitBanner(f_proxy);
-
- if (package || nspace) {
- Printf(f_proxy, "package ");
- if (package)
- Printv(f_proxy, package, nspace ? "." : "", NIL);
- if (nspace)
- Printv(f_proxy, nspace, NIL);
- Printf(f_proxy, ";\n");
- }
- }
- else
- ++nesting_depth;
-
- proxy_class_def = NewString("");
- proxy_class_code = NewString("");
- destructor_call = NewString("");
- destructor_throws_clause = NewString("");
- proxy_class_constants_code = NewString("");
-
- if (GetFlag(n, "feature:interface")) {
- interface_class_code = NewString("");
- String *output_directory = outputDirectory(nspace);
- String *filen = NewStringf("%s%s.java", output_directory, interface_name);
- f_interface = NewFile(filen, "w", SWIG_output_files());
- if (!f_interface) {
- FileErrorDisplay(filen);
- Exit(EXIT_FAILURE);
- }
- Append(filenames_list, filen); // file name ownership goes to the list
- emitBanner(f_interface);
- emitInterfaceDeclaration(n, interface_name, interface_class_code, nspace);
- Delete(filen);
- Delete(output_directory);
- }
- }
-
- Language::classHandler(n);
-
- if (proxy_flag) {
- emitProxyClassDefAndCPPCasts(n);
-
- String *javaclazzname = Swig_name_member(getNSpace(), getClassPrefix(), ""); // mangled full proxy class name
-
- Replaceall(proxy_class_def, "$javaclassname", proxy_class_name);
- Replaceall(proxy_class_code, "$javaclassname", proxy_class_name);
- Replaceall(proxy_class_constants_code, "$javaclassname", proxy_class_name);
- Replaceall(interface_class_code, "$javaclassname", proxy_class_name);
-
- Replaceall(proxy_class_def, "$javaclazzname", javaclazzname);
- Replaceall(proxy_class_code, "$javaclazzname", javaclazzname);
- Replaceall(proxy_class_constants_code, "$javaclazzname", javaclazzname);
- Replaceall(interface_class_code, "$javaclazzname", javaclazzname);
-
- Replaceall(proxy_class_def, "$module", module_class_name);
- Replaceall(proxy_class_code, "$module", module_class_name);
- Replaceall(proxy_class_constants_code, "$module", module_class_name);
- Replaceall(interface_class_code, "$module", module_class_name);
-
- Replaceall(proxy_class_def, "$imclassname", full_imclass_name);
- Replaceall(proxy_class_code, "$imclassname", full_imclass_name);
- Replaceall(proxy_class_constants_code, "$imclassname", full_imclass_name);
- Replaceall(interface_class_code, "$imclassname", full_imclass_name);
-
- if (!has_outerclass)
- Printv(f_proxy, proxy_class_def, proxy_class_code, NIL);
- else {
- Swig_offset_string(proxy_class_def, nesting_depth);
- Append(old_proxy_class_code, proxy_class_def);
- Swig_offset_string(proxy_class_code, nesting_depth);
- Append(old_proxy_class_code, proxy_class_code);
- }
-
- // Write out all the constants
- if (Len(proxy_class_constants_code) != 0) {
- if (!has_outerclass)
- Printv(f_proxy, proxy_class_constants_code, NIL);
- else {
- Swig_offset_string(proxy_class_constants_code, nesting_depth);
- Append(old_proxy_class_code, proxy_class_constants_code);
- }
- }
-
- if (!has_outerclass) {
- Printf(f_proxy, "}\n");
- Delete(f_proxy);
- f_proxy = NULL;
- } else {
- for (int i = 0; i < nesting_depth; ++i)
- Append(old_proxy_class_code, " ");
- Append(old_proxy_class_code, "}\n\n");
- --nesting_depth;
- }
-
- if (f_interface) {
- Printv(f_interface, interface_class_code, "}\n", NIL);
- Delete(f_interface);
- f_interface = 0;
- }
-
- emitDirectorExtraMethods(n);
-
- Delete(interface_class_code);
- interface_class_code = old_interface_class_code;
- Delete(javaclazzname);
- Delete(proxy_class_name);
- proxy_class_name = old_proxy_class_name;
- Delete(full_proxy_class_name);
- full_proxy_class_name = old_full_proxy_class_name;
- Delete(full_imclass_name);
- full_imclass_name = old_full_imclass_name;
- Delete(destructor_call);
- destructor_call = old_destructor_call;
- Delete(destructor_throws_clause);
- destructor_throws_clause = old_destructor_throws_clause;
- Delete(proxy_class_constants_code);
- proxy_class_constants_code = old_proxy_class_constants_code;
- Delete(proxy_class_def);
- proxy_class_def = old_proxy_class_def;
- Delete(proxy_class_code);
- proxy_class_code = old_proxy_class_code;
- }
-
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * memberfunctionHandler()
- * ---------------------------------------------------------------------- */
-
- virtual int memberfunctionHandler(Node *n) {
- member_func_flag = true;
- Language::memberfunctionHandler(n);
-
- if (proxy_flag) {
- String *overloaded_name = getOverloadedName(n);
- String *intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name);
- Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
- Setattr(n, "imfuncname", intermediary_function_name);
- proxyClassFunctionHandler(n);
- Delete(overloaded_name);
- }
- member_func_flag = false;
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * staticmemberfunctionHandler()
- * ---------------------------------------------------------------------- */
-
- virtual int staticmemberfunctionHandler(Node *n) {
-
- static_flag = true;
- member_func_flag = true;
- Language::staticmemberfunctionHandler(n);
-
- if (proxy_flag) {
- String *overloaded_name = getOverloadedName(n);
- String *intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name);
- Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
- Setattr(n, "imfuncname", intermediary_function_name);
- proxyClassFunctionHandler(n);
- Delete(overloaded_name);
- }
- static_flag = false;
- member_func_flag = false;
-
- return SWIG_OK;
- }
-
- /* -----------------------------------------------------------------------------
- * proxyClassFunctionHandler()
- *
- * Function called for creating a Java wrapper function around a c++ function in the
- * proxy class. Used for both static and non-static C++ class functions.
- * C++ class static functions map to Java static functions.
- * Two extra attributes in the Node must be available. These are "proxyfuncname" -
- * the name of the Java class proxy function, which in turn will call "imfuncname" -
- * the intermediary (JNI) function name in the intermediary class.
- * ----------------------------------------------------------------------------- */
-
- void proxyClassFunctionHandler(Node *n) {
- SwigType *t = Getattr(n, "type");
- ParmList *l = Getattr(n, "parms");
- String *intermediary_function_name = Getattr(n, "imfuncname");
- String *proxy_function_name = Getattr(n, "proxyfuncname");
- String *tm;
- Parm *p;
- int i;
- String *imcall = NewString("");
- String *return_type = NewString("");
- String *function_code = NewString("");
- bool setter_flag = false;
- String *pre_code = NewString("");
- String *post_code = NewString("");
- bool is_interface = GetFlag(parentNode(n), "feature:interface") && !checkAttribute(n, "kind", "variable")
- && !static_flag && Getattr(n, "interface:owner") == 0;
-
- if (!proxy_flag)
- return;
-
- // Wrappers not wanted for some methods where the parameters cannot be overloaded in Java
- if (Getattr(n, "overload:ignore"))
- return;
-
- // Don't generate proxy method for additional explicitcall method used in directors
- if (GetFlag(n, "explicitcall"))
- return;
-
- if (l) {
- if (SwigType_type(Getattr(l, "type")) == T_VOID) {
- l = nextSibling(l);
- }
- }
-
- /* Attach the non-standard typemaps to the parameter list */
- Swig_typemap_attach_parms("in", l, NULL);
- Swig_typemap_attach_parms("jtype", l, NULL);
- Swig_typemap_attach_parms("jstype", l, NULL);
- Swig_typemap_attach_parms("javain", l, NULL);
-
- /* Get return types */
- if ((tm = Swig_typemap_lookup("jstype", n, "", 0))) {
- // Note that in the case of polymorphic (covariant) return types, the method's return type is changed to be the base of the C++ return type
- SwigType *covariant = Getattr(n, "covariant");
- substituteClassname(covariant ? covariant : t, tm);
- Printf(return_type, "%s", tm);
- if (covariant)
- Swig_warning(WARN_JAVA_COVARIANT_RET, input_file, line_number,
- "Covariant return types not supported in Java. Proxy method will return %s.\n", SwigType_str(covariant, 0));
- } else {
- Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(t, 0));
- }
-
- if (wrapping_member_flag && !enum_constant_flag) {
- // For wrapping member variables (Javabean setter)
- setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), Swig_name_member(0, getClassPrefix(), variable_name))) == 0);
- }
-
- // Translate and write javadoc comment if flagged
- if (doxygen && doxygenTranslator->hasDocumentation(n)) {
- String *doxygen_comments = doxygenTranslator->getDocumentation(n, " ");
- if (comment_creation_chatter)
- Printf(function_code, "/* This was generated from proxyclassfunctionhandler() */\n");
- Printv(function_code, Char(doxygen_comments), NIL);
- Delete(doxygen_comments);
- }
-
- /* Start generating the proxy function */
- const String *methodmods = Getattr(n, "feature:java:methodmodifiers");
- methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
- Printf(function_code, " %s ", methodmods);
- if (static_flag)
- Printf(function_code, "static ");
- Printf(function_code, "%s %s(", return_type, proxy_function_name);
-
- if (is_interface)
- Printf(interface_class_code, " %s %s(", return_type, proxy_function_name);
-
- Printv(imcall, full_imclass_name, ".$imfuncname(", NIL);
- if (!static_flag) {
- Printf(imcall, "swigCPtr");
-
- String *this_type = Copy(getClassType());
- String *name = NewString("jself");
- String *qualifier = Getattr(n, "qualifier");
- if (qualifier)
- SwigType_push(this_type, qualifier);
- SwigType_add_pointer(this_type);
- Parm *this_parm = NewParm(this_type, name, n);
- Swig_typemap_attach_parms("jtype", this_parm, NULL);
- Swig_typemap_attach_parms("jstype", this_parm, NULL);
-
- if (prematureGarbageCollectionPreventionParameter(this_type, this_parm))
- Printf(imcall, ", this");
-
- Delete(this_parm);
- Delete(name);
- Delete(this_type);
- }
-
- emit_mark_varargs(l);
-
- int gencomma = !static_flag;
-
- /* Output each parameter */
- for (i = 0, p = l; p; i++) {
-
- /* Ignored varargs */
- if (checkAttribute(p, "varargs:ignore", "1")) {
- p = nextSibling(p);
- continue;
- }
-
- /* Ignored parameters */
- if (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- continue;
- }
-
- /* Ignore the 'this' argument for variable wrappers */
- if (!(variable_wrapper_flag && i == 0) || static_flag) {
- SwigType *pt = Getattr(p, "type");
- String *param_type = NewString("");
-
- /* Get the Java parameter type */
- if ((tm = Getattr(p, "tmap:jstype"))) {
- substituteClassname(pt, tm);
- Printf(param_type, "%s", tm);
- } else {
- Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- if (gencomma)
- Printf(imcall, ", ");
-
- String *arg = makeParameterName(n, p, i, setter_flag);
-
- // Use typemaps to transform type used in Java proxy wrapper (in proxy class) to type used in JNI function (in intermediary class)
- if ((tm = Getattr(p, "tmap:javain"))) {
- addThrows(n, "tmap:javain", p);
- substituteClassname(pt, tm);
- Replaceall(tm, "$javainput", arg);
- String *pre = Getattr(p, "tmap:javain:pre");
- if (pre) {
- substituteClassname(pt, pre);
- Replaceall(pre, "$javainput", arg);
- if (Len(pre_code) > 0)
- Printf(pre_code, "\n");
- Printv(pre_code, pre, NIL);
- }
- String *post = Getattr(p, "tmap:javain:post");
- if (post) {
- substituteClassname(pt, post);
- Replaceall(post, "$javainput", arg);
- if (Len(post_code) > 0)
- Printf(post_code, "\n");
- Printv(post_code, post, NIL);
- }
- Printv(imcall, tm, NIL);
- } else {
- Swig_warning(WARN_JAVA_TYPEMAP_JAVAIN_UNDEF, input_file, line_number, "No javain typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- /* Add parameter to proxy function */
- if (gencomma >= 2) {
- Printf(function_code, ", ");
- if (is_interface)
- Printf(interface_class_code, ", ");
- }
- gencomma = 2;
- Printf(function_code, "%s %s", param_type, arg);
- if (is_interface)
- Printf(interface_class_code, "%s %s", param_type, arg);
-
- if (prematureGarbageCollectionPreventionParameter(pt, p)) {
- String *pgcppname = Getattr(p, "tmap:javain:pgcppname");
- if (pgcppname) {
- String *argname = Copy(pgcppname);
- Replaceall(argname, "$javainput", arg);
- Printf(imcall, ", %s", argname);
- Delete(argname);
- } else {
- Printf(imcall, ", %s", arg);
- }
- }
-
- Delete(arg);
- Delete(param_type);
- }
- p = Getattr(p, "tmap:in:next");
- }
-
- Printf(imcall, ")");
- Printf(function_code, ")");
-
- // Transform return type used in JNI function (in intermediary class) to type used in Java wrapper function (in proxy class)
- if ((tm = Swig_typemap_lookup("javaout", n, "", 0))) {
- addThrows(n, "tmap:javaout", n);
- bool is_pre_code = Len(pre_code) > 0;
- bool is_post_code = Len(post_code) > 0;
- if (is_pre_code || is_post_code) {
- Replaceall(tm, "\n ", "\n "); // add extra indentation to code in typemap
- if (is_post_code) {
- Insert(tm, 0, "\n try ");
- Printv(tm, " finally {\n", post_code, "\n }", NIL);
- } else {
- Insert(tm, 0, "\n ");
- }
- if (is_pre_code) {
- Insert(tm, 0, pre_code);
- Insert(tm, 0, "\n");
- }
- Insert(tm, 0, "{");
- Printf(tm, "\n }");
- }
- if (GetFlag(n, "feature:new"))
- Replaceall(tm, "$owner", "true");
- else
- Replaceall(tm, "$owner", "false");
- substituteClassname(t, tm);
-
- // For director methods: generate code to selectively make a normal polymorphic call or
- // an explicit method call - needed to prevent infinite recursion calls in director methods.
- Node *explicit_n = Getattr(n, "explicitcallnode");
- if (explicit_n) {
- String *ex_overloaded_name = getOverloadedName(explicit_n);
- String *ex_intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), ex_overloaded_name);
-
- String *ex_imcall = Copy(imcall);
- Replaceall(ex_imcall, "$imfuncname", ex_intermediary_function_name);
- Replaceall(imcall, "$imfuncname", intermediary_function_name);
-
- String *excode = NewString("");
- if (!Cmp(return_type, "void"))
- Printf(excode, "if (getClass() == %s.class) %s; else %s", proxy_class_name, imcall, ex_imcall);
- else
- Printf(excode, "(getClass() == %s.class) ? %s : %s", proxy_class_name, imcall, ex_imcall);
-
- Clear(imcall);
- Printv(imcall, excode, NIL);
- Delete(ex_overloaded_name);
- Delete(excode);
- } else {
- Replaceall(imcall, "$imfuncname", intermediary_function_name);
- }
-
- Replaceall(tm, "$imfuncname", intermediary_function_name);
- Replaceall(tm, "$jnicall", imcall);
- } else {
- Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number, "No javaout typemap defined for %s\n", SwigType_str(t, 0));
- }
-
- if (is_interface) {
- Printf(interface_class_code, ")");
- generateThrowsClause(n, interface_class_code);
- Printf(interface_class_code, ";\n");
- }
- generateThrowsClause(n, function_code);
- Printf(function_code, " %s\n\n", tm ? tm : empty_string);
- Printv(proxy_class_code, function_code, NIL);
-
- Delete(pre_code);
- Delete(post_code);
- Delete(function_code);
- Delete(return_type);
- Delete(imcall);
- }
-
- /* ----------------------------------------------------------------------
- * constructorHandler()
- * ---------------------------------------------------------------------- */
-
- virtual int constructorHandler(Node *n) {
-
- ParmList *l = Getattr(n, "parms");
- String *tm;
- Parm *p;
- int i;
- String *function_code = NewString("");
- String *helper_code = NewString(""); // Holds code for the constructor helper method generated only when the javain typemap has code in the pre or post attributes
- String *helper_args = NewString("");
- String *pre_code = NewString("");
- String *post_code = NewString("");
- String *im_return_type = NewString("");
- bool feature_director = (parentNode(n) && Swig_directorclass(n));
-
- Language::constructorHandler(n);
-
- // Wrappers not wanted for some methods where the parameters cannot be overloaded in Java
- if (Getattr(n, "overload:ignore"))
- return SWIG_OK;
-
- if (proxy_flag) {
- String *overloaded_name = getOverloadedName(n);
- String *mangled_overname = Swig_name_construct(getNSpace(), overloaded_name);
- String *imcall = NewString("");
-
- const String *methodmods = Getattr(n, "feature:java:methodmodifiers");
- methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
-
- tm = Getattr(n, "tmap:jtype"); // typemaps were attached earlier to the node
- Printf(im_return_type, "%s", tm);
-
- // Translate and write javadoc comment if flagged
- if (doxygen && doxygenTranslator->hasDocumentation(n)) {
- String *doxygen_comments = doxygenTranslator->getDocumentation(n, " ");
- if (comment_creation_chatter)
- Printf(function_code, "/* This was generated from constructionhandler() */\n");
- Printv(function_code, Char(doxygen_comments), NIL);
- Delete(doxygen_comments);
- }
-
- Printf(function_code, " %s %s(", methodmods, proxy_class_name);
- Printf(helper_code, " static private %s SwigConstruct%s(", im_return_type, proxy_class_name);
-
- Printv(imcall, full_imclass_name, ".", mangled_overname, "(", NIL);
-
- /* Attach the non-standard typemaps to the parameter list */
- Swig_typemap_attach_parms("in", l, NULL);
- Swig_typemap_attach_parms("jtype", l, NULL);
- Swig_typemap_attach_parms("jstype", l, NULL);
- Swig_typemap_attach_parms("javain", l, NULL);
-
- emit_mark_varargs(l);
-
- int gencomma = 0;
-
- /* Output each parameter */
- for (i = 0, p = l; p; i++) {
-
- /* Ignored varargs */
- if (checkAttribute(p, "varargs:ignore", "1")) {
- p = nextSibling(p);
- continue;
- }
-
- /* Ignored parameters */
- if (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- continue;
- }
-
- SwigType *pt = Getattr(p, "type");
- String *param_type = NewString("");
-
- /* Get the Java parameter type */
- if ((tm = Getattr(p, "tmap:jstype"))) {
- substituteClassname(pt, tm);
- Printf(param_type, "%s", tm);
- } else {
- Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- if (gencomma)
- Printf(imcall, ", ");
-
- String *arg = makeParameterName(n, p, i, false);
-
- // Use typemaps to transform type used in Java wrapper function (in proxy class) to type used in JNI function (in intermediary class)
- if ((tm = Getattr(p, "tmap:javain"))) {
- addThrows(n, "tmap:javain", p);
- substituteClassname(pt, tm);
- Replaceall(tm, "$javainput", arg);
- String *pre = Getattr(p, "tmap:javain:pre");
- if (pre) {
- substituteClassname(pt, pre);
- Replaceall(pre, "$javainput", arg);
- if (Len(pre_code) > 0)
- Printf(pre_code, "\n");
- Printv(pre_code, pre, NIL);
- }
- String *post = Getattr(p, "tmap:javain:post");
- if (post) {
- substituteClassname(pt, post);
- Replaceall(post, "$javainput", arg);
- if (Len(post_code) > 0)
- Printf(post_code, "\n");
- Printv(post_code, post, NIL);
- }
- Printv(imcall, tm, NIL);
- } else {
- Swig_warning(WARN_JAVA_TYPEMAP_JAVAIN_UNDEF, input_file, line_number, "No javain typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- /* Add parameter to proxy function */
- if (gencomma) {
- Printf(function_code, ", ");
- Printf(helper_code, ", ");
- Printf(helper_args, ", ");
- }
- Printf(function_code, "%s %s", param_type, arg);
- Printf(helper_code, "%s %s", param_type, arg);
- Printf(helper_args, "%s", arg);
- ++gencomma;
-
- if (prematureGarbageCollectionPreventionParameter(pt, p)) {
- String *pgcppname = Getattr(p, "tmap:javain:pgcppname");
- if (pgcppname) {
- String *argname = Copy(pgcppname);
- Replaceall(argname, "$javainput", arg);
- Printf(imcall, ", %s", argname);
- Delete(argname);
- } else {
- Printf(imcall, ", %s", arg);
- }
- }
-
- Delete(arg);
- Delete(param_type);
- p = Getattr(p, "tmap:in:next");
- }
-
- Printf(imcall, ")");
-
- Printf(function_code, ")");
- Printf(helper_code, ")");
- generateThrowsClause(n, function_code);
-
- /* Insert the javaconstruct typemap, doing the replacement for $directorconnect, as needed */
- Hash *attributes = NewHash();
- String *typemap_lookup_type = Getattr(getCurrentClass(), "classtypeobj");
- String *construct_tm = Copy(typemapLookup(n, "javaconstruct", typemap_lookup_type,
- WARN_JAVA_TYPEMAP_JAVACONSTRUCT_UNDEF, attributes));
- if (construct_tm) {
- if (!feature_director) {
- Replaceall(construct_tm, "$directorconnect", "");
- } else {
- String *connect_attr = Getattr(attributes, "tmap:javaconstruct:directorconnect");
-
- if (connect_attr) {
- Replaceall(construct_tm, "$directorconnect", connect_attr);
- } else {
- Swig_warning(WARN_JAVA_NO_DIRECTORCONNECT_ATTR, input_file, line_number, "\"directorconnect\" attribute missing in %s \"javaconstruct\" typemap.\n",
- Getattr(n, "name"));
- Replaceall(construct_tm, "$directorconnect", "");
- }
- }
-
- Printv(function_code, " ", construct_tm, "\n", NIL);
- }
-
- bool is_pre_code = Len(pre_code) > 0;
- bool is_post_code = Len(post_code) > 0;
- if (is_pre_code || is_post_code) {
- generateThrowsClause(n, helper_code);
- Printf(helper_code, " {\n");
- if (is_pre_code) {
- Printv(helper_code, pre_code, "\n", NIL);
- }
- if (is_post_code) {
- Printf(helper_code, " try {\n");
- Printv(helper_code, " return ", imcall, ";\n", NIL);
- Printv(helper_code, " } finally {\n", post_code, "\n }", NIL);
- } else {
- Printv(helper_code, " return ", imcall, ";", NIL);
- }
- Printf(helper_code, "\n }\n");
- String *helper_name = NewStringf("%s.SwigConstruct%s(%s)", proxy_class_name, proxy_class_name, helper_args);
- Printv(proxy_class_code, helper_code, "\n", NIL);
- Replaceall(function_code, "$imcall", helper_name);
- Delete(helper_name);
- } else {
- Replaceall(function_code, "$imcall", imcall);
- }
-
- Printv(proxy_class_code, function_code, "\n", NIL);
-
- Delete(helper_args);
- Delete(im_return_type);
- Delete(pre_code);
- Delete(post_code);
- Delete(construct_tm);
- Delete(attributes);
- Delete(overloaded_name);
- Delete(imcall);
- }
-
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * destructorHandler()
- * ---------------------------------------------------------------------- */
-
- virtual int destructorHandler(Node *n) {
- Language::destructorHandler(n);
- String *symname = Getattr(n, "sym:name");
-
- if (proxy_flag) {
- Printv(destructor_call, full_imclass_name, ".", Swig_name_destroy(getNSpace(), symname), "(swigCPtr)", NIL);
- generateThrowsClause(n, destructor_throws_clause);
- const String *methodmods = Getattr(n, "feature:java:methodmodifiers");
- if (methodmods)
- Setattr(getCurrentClass(), "destructmethodmodifiers", methodmods);
- }
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * membervariableHandler()
- * ---------------------------------------------------------------------- */
-
- virtual int membervariableHandler(Node *n) {
- variable_name = Getattr(n, "sym:name");
- wrapping_member_flag = true;
- variable_wrapper_flag = true;
- Language::membervariableHandler(n);
- wrapping_member_flag = false;
- variable_wrapper_flag = false;
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * staticmembervariableHandler()
- * ---------------------------------------------------------------------- */
-
- virtual int staticmembervariableHandler(Node *n) {
- variable_name = Getattr(n, "sym:name");
- wrapping_member_flag = true;
- static_flag = true;
- Language::staticmembervariableHandler(n);
- wrapping_member_flag = false;
- static_flag = false;
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * memberconstantHandler()
- * ---------------------------------------------------------------------- */
-
- virtual int memberconstantHandler(Node *n) {
- variable_name = Getattr(n, "sym:name");
- wrapping_member_flag = true;
- Language::memberconstantHandler(n);
- wrapping_member_flag = false;
- return SWIG_OK;
- }
-
- /* -----------------------------------------------------------------------------
- * getOverloadedName()
- * ----------------------------------------------------------------------------- */
-
- String *getOverloadedName(Node *n) {
-
- /* Although JNI functions are designed to handle overloaded Java functions,
- * a Java long is used for all classes in the SWIG intermediary class.
- * The intermediary class methods are thus mangled when overloaded to give
- * a unique name. */
- String *overloaded_name = NewStringf("%s", Getattr(n, "sym:name"));
-
- if (Getattr(n, "sym:overloaded")) {
- Printv(overloaded_name, Getattr(n, "sym:overname"), NIL);
- }
-
- return overloaded_name;
- }
-
- /* -----------------------------------------------------------------------------
- * moduleClassFunctionHandler()
- * ----------------------------------------------------------------------------- */
-
- void moduleClassFunctionHandler(Node *n) {
- SwigType *t = Getattr(n, "type");
- ParmList *l = Getattr(n, "parms");
- String *tm;
- Parm *p;
- int i;
- String *imcall = NewString("");
- String *return_type = NewString("");
- String *function_code = NewString("");
- int num_arguments = 0;
- String *overloaded_name = getOverloadedName(n);
- String *func_name = NULL;
- bool setter_flag = false;
- String *pre_code = NewString("");
- String *post_code = NewString("");
-
- // Translate and write javadoc comment if flagged
- if (doxygen && doxygenTranslator->hasDocumentation(n)) {
- String *doxygen_comments = doxygenTranslator->getDocumentation(n, " ");
- if (comment_creation_chatter)
- Printf(function_code, "/* This was generated from moduleClassFunctionHandler() */\n");
- Printv(function_code, doxygen_comments, NIL);
- Delete(doxygen_comments);
- }
-
- if (l) {
- if (SwigType_type(Getattr(l, "type")) == T_VOID) {
- l = nextSibling(l);
- }
- }
-
- /* Attach the non-standard typemaps to the parameter list */
- Swig_typemap_attach_parms("jstype", l, NULL);
- Swig_typemap_attach_parms("javain", l, NULL);
-
- /* Get return types */
- if ((tm = Swig_typemap_lookup("jstype", n, "", 0))) {
- substituteClassname(t, tm);
- Printf(return_type, "%s", tm);
- } else {
- Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(t, 0));
- }
-
- /* Change function name for global variables */
- if (proxy_flag && global_variable_flag) {
- // Capitalize the first letter in the variable to create a JavaBean type getter/setter function name
- func_name = NewString("");
- setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), variable_name)) == 0);
- if (setter_flag)
- Printf(func_name, "set");
- else
- Printf(func_name, "get");
- Putc(toupper((int) *Char(variable_name)), func_name);
- Printf(func_name, "%s", Char(variable_name) + 1);
- } else {
- func_name = Copy(Getattr(n, "sym:name"));
- }
-
- /* Start generating the function */
- const String *methodmods = Getattr(n, "feature:java:methodmodifiers");
- methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
- Printf(function_code, " %s static %s %s(", methodmods, return_type, func_name);
- Printv(imcall, imclass_name, ".", overloaded_name, "(", NIL);
-
- /* Get number of required and total arguments */
- num_arguments = emit_num_arguments(l);
-
- bool global_or_member_variable = global_variable_flag || (wrapping_member_flag && !enum_constant_flag);
- int gencomma = 0;
-
- /* Output each parameter */
- for (i = 0, p = l; i < num_arguments; i++) {
-
- /* Ignored parameters */
- while (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- }
-
- SwigType *pt = Getattr(p, "type");
- String *param_type = NewString("");
-
- /* Get the Java parameter type */
- if ((tm = Getattr(p, "tmap:jstype"))) {
- substituteClassname(pt, tm);
- Printf(param_type, "%s", tm);
- } else {
- Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- if (gencomma)
- Printf(imcall, ", ");
-
- String *arg = makeParameterName(n, p, i, global_or_member_variable);
-
- // Use typemaps to transform type used in Java wrapper function (in proxy class) to type used in JNI function (in intermediary class)
- if ((tm = Getattr(p, "tmap:javain"))) {
- addThrows(n, "tmap:javain", p);
- substituteClassname(pt, tm);
- Replaceall(tm, "$javainput", arg);
- String *pre = Getattr(p, "tmap:javain:pre");
- if (pre) {
- substituteClassname(pt, pre);
- Replaceall(pre, "$javainput", arg);
- if (Len(pre_code) > 0)
- Printf(pre_code, "\n");
- Printv(pre_code, pre, NIL);
- }
- String *post = Getattr(p, "tmap:javain:post");
- if (post) {
- substituteClassname(pt, post);
- Replaceall(post, "$javainput", arg);
- if (Len(post_code) > 0)
- Printf(post_code, "\n");
- Printv(post_code, post, NIL);
- }
- Printv(imcall, tm, NIL);
- } else {
- Swig_warning(WARN_JAVA_TYPEMAP_JAVAIN_UNDEF, input_file, line_number, "No javain typemap defined for %s\n", SwigType_str(pt, 0));
- }
-
- /* Add parameter to module class function */
- if (gencomma >= 2)
- Printf(function_code, ", ");
- gencomma = 2;
- Printf(function_code, "%s %s", param_type, arg);
-
- if (prematureGarbageCollectionPreventionParameter(pt, p)) {
- String *pgcppname = Getattr(p, "tmap:javain:pgcppname");
- if (pgcppname) {
- String *argname = Copy(pgcppname);
- Replaceall(argname, "$javainput", arg);
- Printf(imcall, ", %s", argname);
- Delete(argname);
- } else {
- Printf(imcall, ", %s", arg);
- }
- }
-
- p = Getattr(p, "tmap:in:next");
- Delete(arg);
- Delete(param_type);
- }
-
- Printf(imcall, ")");
- Printf(function_code, ")");
-
- // Transform return type used in JNI function (in intermediary class) to type used in Java wrapper function (in module class)
- if ((tm = Swig_typemap_lookup("javaout", n, "", 0))) {
- addThrows(n, "tmap:javaout", n);
- bool is_pre_code = Len(pre_code) > 0;
- bool is_post_code = Len(post_code) > 0;
- if (is_pre_code || is_post_code) {
- Replaceall(tm, "\n ", "\n "); // add extra indentation to code in typemap
- if (is_post_code) {
- Insert(tm, 0, "\n try ");
- Printv(tm, " finally {\n", post_code, "\n }", NIL);
- } else {
- Insert(tm, 0, "\n ");
- }
- if (is_pre_code) {
- Insert(tm, 0, pre_code);
- Insert(tm, 0, "\n");
- }
- Insert(tm, 0, "{");
- Printf(tm, "\n }");
- }
- if (GetFlag(n, "feature:new"))
- Replaceall(tm, "$owner", "true");
- else
- Replaceall(tm, "$owner", "false");
- substituteClassname(t, tm);
- Replaceall(tm, "$imfuncname", overloaded_name);
- Replaceall(tm, "$jnicall", imcall);
- } else {
- Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number, "No javaout typemap defined for %s\n", SwigType_str(t, 0));
- }
-
- generateThrowsClause(n, function_code);
- Printf(function_code, " %s\n\n", tm ? tm : empty_string);
- Printv(module_class_code, function_code, NIL);
-
- Delete(pre_code);
- Delete(post_code);
- Delete(function_code);
- Delete(return_type);
- Delete(imcall);
- Delete(func_name);
- }
-
- /*----------------------------------------------------------------------
- * replaceSpecialVariables()
- *--------------------------------------------------------------------*/
-
- virtual void replaceSpecialVariables(String *method, String *tm, Parm *parm) {
- (void)method;
- SwigType *type = Getattr(parm, "type");
- substituteClassname(type, tm);
- }
-
- /*----------------------------------------------------------------------
- * decodeEnumFeature()
- * Decode the possible enum features, which are one of:
- * %javaenum(simple)
- * %javaenum(typeunsafe) - default
- * %javaenum(typesafe)
- * %javaenum(proper)
- *--------------------------------------------------------------------*/
-
- EnumFeature decodeEnumFeature(Node *n) {
- EnumFeature enum_feature = TypeunsafeEnum;
- String *feature = Getattr(n, "feature:java:enum");
- if (feature) {
- if (Cmp(feature, "simple") == 0)
- enum_feature = SimpleEnum;
- else if (Cmp(feature, "typesafe") == 0)
- enum_feature = TypesafeEnum;
- else if (Cmp(feature, "proper") == 0)
- enum_feature = ProperEnum;
- }
- return enum_feature;
- }
-
- /* -----------------------------------------------------------------------
- * enumValue()
- * This method will return a string with an enum value to use in Java generated
- * code. If the %javaconst feature is not used, the string will contain the intermediary
- * class call to obtain the enum value. The intermediary class and JNI methods to obtain
- * the enum value will be generated. Otherwise the C/C++ enum value will be used if there
- * is one and hopefully it will compile as Java code - e.g. 20 as in: enum E{e=20};
- * The %javaconstvalue feature overrides all other ways to generate the constant value.
- * The caller must delete memory allocated for the returned string.
- * ------------------------------------------------------------------------ */
-
- String *enumValue(Node *n) {
- String *symname = Getattr(n, "sym:name");
-
- // Check for the %javaconstvalue feature
- String *value = Getattr(n, "feature:java:constvalue");
-
- if (!value) {
- // The %javaconst feature determines how the constant value is obtained
- int const_feature_flag = GetFlag(n, "feature:java:const");
-
- if (const_feature_flag) {
- // Use the C syntax to make a true Java constant and hope that it compiles as Java code
- value = Getattr(n, "enumvalue") ? Copy(Getattr(n, "enumvalue")) : Copy(Getattr(n, "enumvalueex"));
- } else {
- String *newsymname = 0;
- if (!getCurrentClass() || !proxy_flag) {
- String *enumClassPrefix = getEnumClassPrefix();
- if (enumClassPrefix) {
- // A global scoped enum
- newsymname = Swig_name_member(0, enumClassPrefix, symname);
- symname = newsymname;
- }
- }
-
- // Get the enumvalue from a JNI call
- if (!getCurrentClass() || !cparse_cplusplus || !proxy_flag) {
- // Strange hack to change the name
- Setattr(n, "name", Getattr(n, "value")); /* for wrapping of enums in a namespace when emit_action is used */
- constantWrapper(n);
- value = NewStringf("%s.%s()", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname));
- } else {
- memberconstantHandler(n);
- value = NewStringf("%s.%s()", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), Swig_name_member(0, getEnumClassPrefix(), symname)));
- }
- Delete(newsymname);
- }
- }
- return value;
- }
-
- /* -----------------------------------------------------------------------------
- * getEnumName()
- *
- * If jnidescriptor is set, inner class names are separated with '$' otherwise a '.'
- * and the package is also not added to the name.
- * ----------------------------------------------------------------------------- */
-
- String *getEnumName(SwigType *t, bool jnidescriptor) {
- Node *enumname = NULL;
- Node *n = enumLookup(t);
- if (n) {
- enumname = Getattr(n, "enumname");
- if (!enumname || jnidescriptor) {
- String *symname = Getattr(n, "sym:name");
- if (symname) {
- // Add in class scope when referencing enum if not a global enum
- String *scopename_prefix = Swig_scopename_prefix(Getattr(n, "name"));
- String *proxyname = 0;
- if (scopename_prefix) {
- proxyname = getProxyName(scopename_prefix, jnidescriptor);
- }
- if (proxyname) {
- const char *class_separator = jnidescriptor ? "$" : ".";
- enumname = NewStringf("%s%s%s", proxyname, class_separator, symname);
- } else {
- // global enum or enum in a namespace
- String *nspace = Getattr(n, "sym:nspace");
- if (nspace) {
- if (package && !jnidescriptor)
- enumname = NewStringf("%s.%s.%s", package, nspace, symname);
- else
- enumname = NewStringf("%s.%s", nspace, symname);
- } else {
- enumname = Copy(symname);
- }
- }
- if (!jnidescriptor) {
- Setattr(n, "enumname", enumname); // Cache it
- Delete(enumname);
- }
- Delete(scopename_prefix);
- }
- }
- }
-
- return enumname;
- }
-
- /* -----------------------------------------------------------------------------
- * substituteClassname()
- *
- * Substitute the special variable $javaclassname with the proxy class name for classes/structs/unions
- * that SWIG knows about. Also substitutes enums with enum name.
- * Otherwise use the $descriptor name for the Java class name. Note that the $&javaclassname substitution
- * is the same as a $&descriptor substitution, ie one pointer added to descriptor name.
- * Note that the path separator is a '.' unless jnidescriptor is set.
- * Inputs:
- * pt - parameter type
- * tm - typemap contents that might contain the special variable to be replaced
- * jnidescriptor - if set, inner class names are separated with '$' otherwise a '/' is used for the path separator
- * Outputs:
- * tm - typemap contents complete with the special variable substitution
- * Return:
- * substitution_performed - flag indicating if a substitution was performed
- * ----------------------------------------------------------------------------- */
-
- bool substituteClassname(SwigType *pt, String *tm, bool jnidescriptor = false) {
- bool substitution_performed = false;
- SwigType *type = Copy(SwigType_typedef_resolve_all(pt));
- SwigType *strippedtype = SwigType_strip_qualifiers(type);
-
- if (Strstr(tm, "$javaclassname")) {
- SwigType *classnametype = Copy(strippedtype);
- substituteClassnameSpecialVariable(classnametype, tm, "$javaclassname", jnidescriptor);
- substitution_performed = true;
- Delete(classnametype);
- }
- if (Strstr(tm, "$*javaclassname")) {
- SwigType *classnametype = Copy(strippedtype);
- Delete(SwigType_pop(classnametype));
- if (Len(classnametype) > 0) {
- substituteClassnameSpecialVariable(classnametype, tm, "$*javaclassname", jnidescriptor);
- substitution_performed = true;
- }
- Delete(classnametype);
- }
- if (Strstr(tm, "$&javaclassname")) {
- SwigType *classnametype = Copy(strippedtype);
- SwigType_add_pointer(classnametype);
- substituteClassnameSpecialVariable(classnametype, tm, "$&javaclassname", jnidescriptor);
- substitution_performed = true;
- Delete(classnametype);
- }
- if (Strstr(tm, "$javainterfacename")) {
- SwigType *interfacenametype = Copy(strippedtype);
- substituteInterfacenameSpecialVariable(interfacenametype, tm, "$javainterfacename", jnidescriptor, true);
- substitution_performed = true;
- Delete(interfacenametype);
- }
- if (Strstr(tm, "$*javainterfacename")) {
- SwigType *interfacenametype = Copy(strippedtype);
- Delete(SwigType_pop(interfacenametype));
- if (Len(interfacenametype) > 0) {
- substituteInterfacenameSpecialVariable(interfacenametype, tm, "$*javainterfacename", jnidescriptor, true);
- substitution_performed = true;
- }
- Delete(interfacenametype);
- }
- if (Strstr(tm, "$&javainterfacename")) {
- SwigType *interfacenametype = Copy(strippedtype);
- SwigType_add_pointer(interfacenametype);
- substituteInterfacenameSpecialVariable(interfacenametype, tm, "$&javainterfacename", jnidescriptor, true);
- substitution_performed = true;
- Delete(interfacenametype);
- }
- if (Strstr(tm, "$interfacename")) {
- SwigType *interfacenametype = Copy(strippedtype);
- substituteInterfacenameSpecialVariable(interfacenametype, tm, "$interfacename", jnidescriptor, false);
- substitution_performed = true;
- Delete(interfacenametype);
- }
- if (Strstr(tm, "$*interfacename")) {
- SwigType *interfacenametype = Copy(strippedtype);
- Delete(SwigType_pop(interfacenametype));
- if (Len(interfacenametype) > 0) {
- substituteInterfacenameSpecialVariable(interfacenametype, tm, "$*interfacename", jnidescriptor, false);
- substitution_performed = true;
- }
- Delete(interfacenametype);
- }
- if (Strstr(tm, "$&interfacename")) {
- SwigType *interfacenametype = Copy(strippedtype);
- SwigType_add_pointer(interfacenametype);
- substituteInterfacenameSpecialVariable(interfacenametype, tm, "$&interfacename", jnidescriptor, false);
- substitution_performed = true;
- Delete(interfacenametype);
- }
-
- Delete(strippedtype);
- Delete(type);
-
- return substitution_performed;
- }
-
- /* -----------------------------------------------------------------------------
- * substituteClassnameSpecialVariable()
- * ----------------------------------------------------------------------------- */
-
- void substituteClassnameSpecialVariable(SwigType *classnametype, String *tm, const char *classnamespecialvariable, bool jnidescriptor) {
- String *replacementname;
-
- if (SwigType_isenum(classnametype)) {
- String *enumname = getEnumName(classnametype, jnidescriptor);
- if (enumname) {
- replacementname = Copy(enumname);
- } else {
- bool anonymous_enum = (Cmp(classnametype, "enum ") == 0);
- if (anonymous_enum) {
- replacementname = NewString("int");
- } else {
- // An unknown enum - one that has not been parsed (neither a C enum forward reference nor a definition) or an ignored enum
- replacementname = NewStringf("SWIGTYPE%s", SwigType_manglestr(classnametype));
- Replace(replacementname, "enum ", "", DOH_REPLACE_ANY);
- Setattr(swig_types_hash, replacementname, classnametype);
- }
- }
- } else {
- String *classname = getProxyName(classnametype, jnidescriptor); // getProxyName() works for pointers to classes too
- if (classname) {
- replacementname = Copy(classname);
- } else {
- // use $descriptor if SWIG does not know anything about this type. Note that any typedefs are resolved.
- replacementname = NewStringf("SWIGTYPE%s", SwigType_manglestr(classnametype));
-
- // Add to hash table so that the type wrapper classes can be created later
- Setattr(swig_types_hash, replacementname, classnametype);
- }
- }
- if (jnidescriptor)
- Replaceall(replacementname,".","/");
- Replaceall(tm, classnamespecialvariable, replacementname);
-
- Delete(replacementname);
- }
-
- /* -----------------------------------------------------------------------------
- * substituteInterfacenameSpecialVariable()
- * ----------------------------------------------------------------------------- */
-
- void substituteInterfacenameSpecialVariable(SwigType *interfacenametype, String *tm, const char *interfacenamespecialvariable, bool jnidescriptor, bool qualified) {
-
- String *interfacename = getInterfaceName(interfacenametype/*, jnidescriptor*/, qualified);
- if (interfacename) {
- String *replacementname = Copy(interfacename);
-
- if (jnidescriptor)
- Replaceall(replacementname,".","/");
- Replaceall(tm, interfacenamespecialvariable, replacementname);
-
- Delete(replacementname);
- }
- }
-
- /* -----------------------------------------------------------------------------
- * emitTypeWrapperClass()
- * ----------------------------------------------------------------------------- */
-
- void emitTypeWrapperClass(String *classname, SwigType *type) {
- Node *n = NewHash();
- Setfile(n, input_file);
- Setline(n, line_number);
-
- String *swigtype = NewString("");
- String *filen = NewStringf("%s%s.java", SWIG_output_directory(), classname);
- File *f_swigtype = NewFile(filen, "w", SWIG_output_files());
- if (!f_swigtype) {
- FileErrorDisplay(filen);
- Exit(EXIT_FAILURE);
- }
- Append(filenames_list, Copy(filen));
- Delete(filen);
- filen = NULL;
-
- // Start writing out the type wrapper class file
- emitBanner(f_swigtype);
-
- if (package)
- Printf(f_swigtype, "package %s;\n", package);
-
- // Pure Java baseclass and interfaces
- const String *pure_baseclass = typemapLookup(n, "javabase", type, WARN_NONE);
- const String *pure_interfaces = typemapLookup(n, "javainterfaces", type, WARN_NONE);
-
- // Emit the class
- Printv(swigtype, typemapLookup(n, "javaimports", type, WARN_NONE), // Import statements
- "\n", typemapLookup(n, "javaclassmodifiers", type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
- " $javaclassname", // Class name and bases
- *Char(pure_baseclass) ? " extends " : "", pure_baseclass, *Char(pure_interfaces) ? // Interfaces
- " implements " : "", pure_interfaces, " {", typemapLookup(n, "javabody", type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF), // main body of class
- typemapLookup(n, "javacode", type, WARN_NONE), // extra Java code
- "}\n", "\n", NIL);
-
- Replaceall(swigtype, "$javaclassname", classname);
- Replaceall(swigtype, "$module", module_class_name);
- Replaceall(swigtype, "$imclassname", imclass_name);
-
- // For unknown enums
- Replaceall(swigtype, "$static ", "");
- Replaceall(swigtype, "$enumvalues", "");
-
- Printv(f_swigtype, swigtype, NIL);
-
- Delete(f_swigtype);
- Delete(swigtype);
- Delete(n);
- }
-
- /* -----------------------------------------------------------------------------
- * typemapLookup()
- * n - for input only and must contain info for Getfile(n) and Getline(n) to work
- * tmap_method - typemap method name
- * type - typemap type to lookup
- * warning - warning number to issue if no typemaps found
- * typemap_attributes - the typemap attributes are attached to this node and will
- * also be used for temporary storage if non null
- * return is never NULL, unlike Swig_typemap_lookup()
- * ----------------------------------------------------------------------------- */
-
- const String *typemapLookup(Node *n, const_String_or_char_ptr tmap_method, SwigType *type, int warning, Node *typemap_attributes = 0) {
- Node *node = !typemap_attributes ? NewHash() : typemap_attributes;
- Setattr(node, "type", type);
- Setfile(node, Getfile(n));
- Setline(node, Getline(n));
- const String *tm = Swig_typemap_lookup(tmap_method, node, "", 0);
- if (!tm) {
- tm = empty_string;
- if (warning != WARN_NONE)
- Swig_warning(warning, Getfile(n), Getline(n), "No %s typemap defined for %s\n", tmap_method, SwigType_str(type, 0));
- }
- if (!typemap_attributes)
- Delete(node);
- return tm;
- }
-
- /* -----------------------------------------------------------------------------
- * addThrows()
- *
- * Adds exception classes to a throws list. The throws list is the list of classes
- * that will form the Java throws clause. Mainly for checked exceptions.
- * ----------------------------------------------------------------------------- */
-
- void addThrows(Node *n, const String *attribute, Node *parameter) {
- // Get the comma separated exception classes for the throws clause - held in typemap/feature's "throws" attribute
- String *throws_attribute = NewStringf("%s:throws", attribute);
- String *throws = Getattr(parameter, throws_attribute);
-
- if (throws && Len(throws) > 0) {
- String *throws_list = Getattr(n, "java:throwslist");
- if (!throws_list) {
- throws_list = NewList();
- Setattr(n, "java:throwslist", throws_list);
- }
- // Put the exception classes in the throws clause into a temporary List
- List *temp_classes_list = Split(throws, ',', INT_MAX);
-
- // Add the exception classes to the node throws list, but don't duplicate if already in list
- if (temp_classes_list && Len(temp_classes_list) > 0) {
- for (Iterator cls = First(temp_classes_list); cls.item; cls = Next(cls)) {
- String *exception_class = NewString(cls.item);
- Replaceall(exception_class, " ", ""); // remove spaces
- Replaceall(exception_class, "\t", ""); // remove tabs
- if (Len(exception_class) > 0) {
- // $javaclassname substitution
- SwigType *pt = Getattr(parameter, "type");
- substituteClassname(pt, exception_class);
-
- // Don't duplicate the Java exception class in the throws clause
- bool found_flag = false;
- for (Iterator item = First(throws_list); item.item; item = Next(item)) {
- if (Strcmp(item.item, exception_class) == 0)
- found_flag = true;
- }
- if (!found_flag)
- Append(throws_list, exception_class);
- }
- Delete(exception_class);
- }
- }
- Delete(temp_classes_list);
- }
- Delete(throws_attribute);
- }
-
- /* -----------------------------------------------------------------------------
- * generateThrowsClause()
- *
- * Generates throws clause for checked exception
- * ----------------------------------------------------------------------------- */
-
- void generateThrowsClause(Node *n, String *code) {
- // Add the throws clause into code
- List *throws_list = Getattr(n, "java:throwslist");
- if (throws_list) {
- Iterator cls = First(throws_list);
- Printf(code, " throws %s", cls.item);
- while ((cls = Next(cls)).item)
- Printf(code, ", %s", cls.item);
- }
- }
-
- /* -----------------------------------------------------------------------------
- * prematureGarbageCollectionPreventionParameter()
- *
- * Get the proxy class name for use in an additional generated parameter. The
- * additional parameter is added to a native method call purely to prevent
- * premature garbage collection of proxy classes which pass their C++ class pointer
- * in a Java long to the JNI layer.
- * ----------------------------------------------------------------------------- */
-
- String *prematureGarbageCollectionPreventionParameter(SwigType *t, Parm *p) {
- String *pgcpp_java_type = 0;
- String *jtype = NewString(Getattr(p, "tmap:jtype"));
-
- // Strip C comments
- String *stripped_jtype = Swig_strip_c_comments(jtype);
- if (stripped_jtype) {
- Delete(jtype);
- jtype = stripped_jtype;
- }
-
- // Remove whitespace
- Replaceall(jtype, " ", "");
- Replaceall(jtype, "\t", "");
-
- if (Cmp(jtype, "long") == 0) {
- if (proxy_flag) {
- if (!GetFlag(p, "tmap:jtype:nopgcpp") && !nopgcpp_flag) {
- String *interface_name = getInterfaceName(t, true);
- pgcpp_java_type = interface_name ? interface_name : getProxyName(t);
- if (!pgcpp_java_type) {
- // Look for proxy class parameters passed to C++ layer using non-default typemaps, ie not one of above types
- String *jstype = NewString(Getattr(p, "tmap:jstype"));
- if (jstype) {
- Hash *classes = getClassHash();
- if (classes) {
- // Strip C comments
- String *stripped_jstype = Swig_strip_c_comments(jstype);
- if (stripped_jstype) {
- Delete(jstype);
- jstype = stripped_jstype;
- }
- // Remove whitespace
- Replaceall(jstype, " ", "");
- Replaceall(jstype, "\t", "");
-
- Iterator ki;
- for (ki = First(classes); ki.key; ki = Next(ki)) {
- Node *cls = ki.item;
- if (cls && !Getattr(cls, "feature:ignore")) {
- String *symname = Getattr(cls, "sym:name");
- if (symname && Strcmp(symname, jstype) == 0) {
- pgcpp_java_type = symname;
- }
- }
- }
- }
- }
- Delete(jstype);
- }
- }
- }
- }
- Delete(jtype);
- return pgcpp_java_type;
- }
-
- /* -----------------------------------------------------------------------------
- * outputDirectory()
- *
- * Return the directory to use for generating Java classes/enums and create the
- * subdirectory (does not create if language specific outdir does not exist).
- * ----------------------------------------------------------------------------- */
-
- String *outputDirectory(String *nspace) {
- String *output_directory = Copy(SWIG_output_directory());
- if (nspace) {
- String *nspace_subdirectory = Copy(nspace);
- Replaceall(nspace_subdirectory, ".", SWIG_FILE_DELIMITER);
- String *newdir_error = Swig_new_subdirectory(output_directory, nspace_subdirectory);
- if (newdir_error) {
- Printf(stderr, "%s\n", newdir_error);
- Delete(newdir_error);
- Exit(EXIT_FAILURE);
- }
- Printv(output_directory, nspace_subdirectory, SWIG_FILE_DELIMITER, 0);
- Delete(nspace_subdirectory);
- }
- return output_directory;
- }
-
- /*----------------------------------------------------------------------
- * Start of director methods
- *--------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------------
- * getUpcallJNIMethod()
- *--------------------------------------------------------------------*/
-
- String *getUpcallJNIMethod(String *descrip) {
- static struct {
- char code;
- const char *method;
- } upcall_methods[] = {
- {
- 'B', "CallStaticByteMethod"}, {
- 'C', "CallStaticCharMethod"}, {
- 'D', "CallStaticDoubleMethod"}, {
- 'F', "CallStaticFloatMethod"}, {
- 'I', "CallStaticIntMethod"}, {
- 'J', "CallStaticLongMethod"}, {
- 'L', "CallStaticObjectMethod"}, {
- 'S', "CallStaticShortMethod"}, {
- 'V', "CallStaticVoidMethod"}, {
- 'Z', "CallStaticBooleanMethod"}, {
- '[', "CallStaticObjectMethod"}
- };
-
- char code;
- int i;
-
- code = *Char(descrip);
- for (i = 0; i < (int) (sizeof(upcall_methods) / sizeof(upcall_methods[0])); ++i)
- if (code == upcall_methods[i].code)
- return NewString(upcall_methods[i].method);
- return NULL;
- }
-
- /*----------------------------------------------------------------------
- * emitDirectorUpcalls()
- *--------------------------------------------------------------------*/
-
- void emitDirectorUpcalls() {
- if (n_dmethods) {
- Wrapper *w = NewWrapper();
- String *jni_imclass_name = makeValidJniName(imclass_name);
- String *swig_module_init = NewString("swig_module_init");
- String *swig_module_init_jni = makeValidJniName(swig_module_init);
- String *dmethod_data = NewString("");
- int n_methods = 0;
- Iterator udata_iter;
-
- udata_iter = First(dmethods_seq);
- while (udata_iter.item) {
- UpcallData *udata = udata_iter.item;
- Printf(dmethod_data, " { \"%s\", \"%s\" }", Getattr(udata, "imclass_method"), Getattr(udata, "imclass_fdesc"));
- ++n_methods;
-
- udata_iter = Next(udata_iter);
-
- if (udata_iter.item)
- Putc(',', dmethod_data);
- Putc('\n', dmethod_data);
- }
-
- Printf(f_runtime, "namespace Swig {\n");
- Printf(f_runtime, " namespace {\n");
- Printf(f_runtime, " jclass jclass_%s = NULL;\n", imclass_name);
- Printf(f_runtime, " jmethodID director_method_ids[%d];\n", n_methods);
- Printf(f_runtime, " }\n");
- Printf(f_runtime, "}\n");
-
- Printf(w->def, "SWIGEXPORT void JNICALL Java_%s%s_%s(JNIEnv *jenv, jclass jcls) {", jnipackage, jni_imclass_name, swig_module_init_jni);
- Printf(w->code, "static struct {\n");
- Printf(w->code, " const char *method;\n");
- Printf(w->code, " const char *signature;\n");
- Printf(w->code, "} methods[%d] = {\n", n_methods);
- Printv(w->code, dmethod_data, NIL);
- Printf(w->code, "};\n");
-
- Wrapper_add_local(w, "i", "int i");
-
- Printf(w->code, "Swig::jclass_%s = (jclass) jenv->NewGlobalRef(jcls);\n", imclass_name);
- Printf(w->code, "if (!Swig::jclass_%s) return;\n", imclass_name);
- Printf(w->code, "for (i = 0; i < (int) (sizeof(methods)/sizeof(methods[0])); ++i) {\n");
- Printf(w->code, " Swig::director_method_ids[i] = jenv->GetStaticMethodID(jcls, methods[i].method, methods[i].signature);\n");
- Printf(w->code, " if (!Swig::director_method_ids[i]) return;\n");
- Printf(w->code, "}\n");
-
- Printf(w->code, "}\n");
-
- Wrapper_print(w, f_wrappers);
- Delete(dmethod_data);
- Delete(swig_module_init_jni);
- Delete(swig_module_init);
- Delete(jni_imclass_name);
- DelWrapper(w);
- }
- }
-
- /*----------------------------------------------------------------------
- * emitDirectorExtraMethods()
- *
- * This is where the director connect method is generated.
- *--------------------------------------------------------------------*/
- void emitDirectorExtraMethods(Node *n) {
- if (!Swig_directorclass(n))
- return;
-
- // Output the director connect method:
- String *jni_imclass_name = makeValidJniName(imclass_name);
- String *norm_name = SwigType_namestr(Getattr(n, "name"));
- String *swig_director_connect = Swig_name_member(getNSpace(), getClassPrefix(), "director_connect");
- String *swig_director_connect_jni = makeValidJniName(swig_director_connect);
- String *smartptr = Getattr(n, "feature:smartptr");
- String *dirClassName = directorClassName(n);
- Wrapper *code_wrap;
-
- Printf(imclass_class_code, " public final static native void %s(%s obj, long cptr, boolean mem_own, boolean weak_global);\n",
- swig_director_connect, full_proxy_class_name);
-
- code_wrap = NewWrapper();
- Printf(code_wrap->def,
- "SWIGEXPORT void JNICALL Java_%s%s_%s(JNIEnv *jenv, jclass jcls, jobject jself, jlong objarg, jboolean jswig_mem_own, "
- "jboolean jweak_global) {\n", jnipackage, jni_imclass_name, swig_director_connect_jni);
-
- if (smartptr) {
- Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", smartptr, smartptr);
- Printf(code_wrap->code, " (void)jcls;\n");
- Printf(code_wrap->code, " // Keep a local instance of the smart pointer around while we are using the raw pointer\n");
- Printf(code_wrap->code, " // Avoids using smart pointer specific API.\n");
- Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj->operator->());\n", dirClassName, dirClassName);
- }
- else {
- Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", norm_name, norm_name);
- Printf(code_wrap->code, " (void)jcls;\n");
- Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj);\n", dirClassName, dirClassName);
- }
-
- Printf(code_wrap->code, " director->swig_connect_director(jenv, jself, jenv->GetObjectClass(jself), "
- "(jswig_mem_own == JNI_TRUE), (jweak_global == JNI_TRUE));\n");
- Printf(code_wrap->code, "}\n");
-
- Wrapper_print(code_wrap, f_wrappers);
- DelWrapper(code_wrap);
-
- Delete(swig_director_connect_jni);
- Delete(swig_director_connect);
-
- // Output the swigReleaseOwnership, swigTakeOwnership methods:
- String *changeown_method_name = Swig_name_member(getNSpace(), getClassPrefix(), "change_ownership");
- String *changeown_jnimethod_name = makeValidJniName(changeown_method_name);
-
- Printf(imclass_class_code, " public final static native void %s(%s obj, long cptr, boolean take_or_release);\n", changeown_method_name, full_proxy_class_name);
-
- code_wrap = NewWrapper();
- Printf(code_wrap->def,
- "SWIGEXPORT void JNICALL Java_%s%s_%s(JNIEnv *jenv, jclass jcls, jobject jself, jlong objarg, jboolean jtake_or_release) {\n",
- jnipackage, jni_imclass_name, changeown_jnimethod_name);
-
- if (Len(smartptr)) {
- Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", smartptr, smartptr);
- Printf(code_wrap->code, " // Keep a local instance of the smart pointer around while we are using the raw pointer\n");
- Printf(code_wrap->code, " // Avoids using smart pointer specific API.\n");
- Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj->operator->());\n", dirClassName, dirClassName);
- } else {
- Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", norm_name, norm_name);
- Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj);\n", dirClassName, dirClassName);
- }
-
- Printf(code_wrap->code, " (void)jcls;\n");
- Printf(code_wrap->code, " if (director) {\n");
- Printf(code_wrap->code, " director->swig_java_change_ownership(jenv, jself, jtake_or_release ? true : false);\n");
- Printf(code_wrap->code, " }\n");
- Printf(code_wrap->code, "}\n");
-
- Wrapper_print(code_wrap, f_wrappers);
- DelWrapper(code_wrap);
-
- Delete(changeown_method_name);
- Delete(changeown_jnimethod_name);
- Delete(norm_name);
- Delete(dirClassName);
- Delete(jni_imclass_name);
- }
-
- /*----------------------------------------------------------------------
- * emitCodeTypemap()
- *
- * Output a code typemap that uses $methodname and $jnicall, as used
- * in the directordisconnect, director_release and director_take
- * typemaps.
- *--------------------------------------------------------------------*/
-
- void emitCodeTypemap(Node *n, bool derived, SwigType *lookup_type, const String *typemap, const String *methodname, const String *jnicall) {
- const String *tm = NULL;
- Node *tmattrs = NewHash();
- String *lookup_tmname = NewString(typemap);
- String *method_attr_name;
- String *method_attr;
-
- if (derived) {
- Append(lookup_tmname, "_derived");
- }
-
- tm = typemapLookup(n, lookup_tmname, lookup_type, WARN_NONE, tmattrs);
- method_attr_name = NewStringf("tmap:%s:%s", lookup_tmname, methodname);
- method_attr = Getattr(tmattrs, method_attr_name);
-
- if (*Char(tm)) {
- if (method_attr) {
- String *codebody = Copy(tm);
- Replaceall(codebody, "$methodname", method_attr);
- Replaceall(codebody, "$jnicall", jnicall);
- Append(proxy_class_def, codebody);
- Delete(codebody);
- } else {
- Swig_error(input_file, line_number, "No %s method name attribute for %s\n", lookup_tmname, proxy_class_name);
- }
- } else {
- Swig_error(input_file, line_number, "No %s typemap for %s\n", lookup_tmname, proxy_class_name);
- }
-
- Delete(tmattrs);
- Delete(lookup_tmname);
- // Delete(method_attr);
- }
-
- /* -----------------------------------------------------------------------------
- * substitutePackagePath()
- *
- * Replace $packagepath using the javapackage typemap associated with passed
- * parm or global package if p is 0. "$packagepath/" is replaced with "" if
- * no package is set. Note that the path separator is a '/'.
- * ----------------------------------------------------------------------------- */
-
- void substitutePackagePath(String *text, Parm *p) {
- String *pkg_path= 0;
-
- if (p)
- pkg_path = Swig_typemap_lookup("javapackage", p, "", 0);
- if (!pkg_path || Len(pkg_path) == 0)
- pkg_path = Copy(package_path);
-
- if (Len(pkg_path) > 0) {
- Replaceall(pkg_path, ".", "/");
- Replaceall(text, "$packagepath", pkg_path);
- } else {
- Replaceall(text, "$packagepath/", empty_string);
- Replaceall(text, "$packagepath", empty_string);
- }
- Delete(pkg_path);
- }
-
- /* ---------------------------------------------------------------
- * Canonicalize the JNI field descriptor
- *
- * Replace the $packagepath and $javaclassname family of special
- * variables with the desired package and Java proxy name as
- * required in the JNI field descriptors.
- *
- * !!SFM!! If $packagepath occurs in the field descriptor, but
- * package_path isn't set (length == 0), then strip it and the
- * optional trailing '/' from the resulting name.
- *
- * --------------------------------------------------------------- */
-
- String *canonicalizeJNIDescriptor(String *descriptor_in, Parm *p) {
- SwigType *type = Getattr(p, "type");
- String *descriptor_out = Copy(descriptor_in);
-
- substituteClassname(type, descriptor_out, true);
- substitutePackagePath(descriptor_out, p);
-
- return descriptor_out;
- }
-
- /* ---------------------------------------------------------------
- * classDirectorMethod()
- *
- * Emit a virtual director method to pass a method call on to the
- * underlying Java object.
- *
- * --------------------------------------------------------------- */
-
- int classDirectorMethod(Node *n, Node *parent, String *super) {
- String *c_classname = Getattr(parent, "name");
- String *name = Getattr(n, "name");
- String *symname = Getattr(n, "sym:name");
- SwigType *returntype = Getattr(n, "type");
- String *overloaded_name = getOverloadedName(n);
- String *storage = Getattr(n, "storage");
- String *value = Getattr(n, "value");
- String *decl = Getattr(n, "decl");
- String *declaration = NewString("");
- String *tm;
- Parm *p;
- int i;
- Wrapper *w = NewWrapper();
- ParmList *l = Getattr(n, "parms");
- bool is_void = !(Cmp(returntype, "void"));
- String *qualified_return = 0;
- bool pure_virtual = (!(Cmp(storage, "virtual")) && !(Cmp(value, "0")));
- int status = SWIG_OK;
- bool output_director = true;
- String *dirclassname = directorClassName(parent);
- String *qualified_name = NewStringf("%s::%s", dirclassname, name);
- String *jnidesc = NewString("");
- String *classdesc = NewString("");
- String *jniret_desc = NewString("");
- String *classret_desc = NewString("");
- SwigType *c_ret_type = NULL;
- String *jupcall_args = NewString("swigjobj");
- String *imclass_dmethod;
- String *callback_def = NewString("");
- String *callback_code = NewString("");
- String *imcall_args = NewString("");
- int classmeth_off = curr_class_dmethod - first_class_dmethod;
- bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
- String *qualified_classname = getProxyName(getClassName());
-
- // Kludge Alert: functionWrapper sets sym:overload properly, but it
- // isn't at this point, so we have to manufacture it ourselves. At least
- // we're consistent with the sym:overload name in functionWrapper. (?? when
- // does the overloaded method name get set?)
-
- imclass_dmethod = NewStringf("%s", Swig_name_member(getNSpace(), dirclassname, overloaded_name));
-
- qualified_return = SwigType_rcaststr(returntype, "c_result");
-
- if (!is_void && (!ignored_method || pure_virtual)) {
- if (!SwigType_isclass(returntype)) {
- if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
- String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
- Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL);
- Delete(construct_result);
- } else {
- String *base_typename = SwigType_base(returntype);
- String *resolved_typename = SwigType_typedef_resolve_all(base_typename);
- Symtab *symtab = Getattr(n, "sym:symtab");
- Node *typenode = Swig_symbol_clookup(resolved_typename, symtab);
-
- if (SwigType_ispointer(returntype) || (typenode && Getattr(typenode, "abstracts"))) {
- /* initialize pointers to something sane. Same for abstract
- classes when a reference is returned. */
- Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL);
- } else {
- /* If returning a reference, initialize the pointer to a sane
- default - if a Java exception occurs, then the pointer returns
- something other than a NULL-initialized reference. */
- SwigType *noref_type = SwigType_del_reference(Copy(returntype));
- String *noref_ltype = SwigType_lstr(noref_type, 0);
- String *return_ltype = SwigType_lstr(returntype, 0);
-
- Wrapper_add_localv(w, "result_default", "static", noref_ltype, "result_default", NIL);
- Wrapper_add_localv(w, "c_result", return_ltype, "c_result", NIL);
- Printf(w->code, "result_default = SwigValueInit< %s >();\n", noref_ltype);
- Printf(w->code, "c_result = &result_default;\n");
- Delete(return_ltype);
- Delete(noref_ltype);
- Delete(noref_type);
- }
-
- Delete(base_typename);
- Delete(resolved_typename);
- }
- } else {
- SwigType *vt;
-
- vt = cplus_value_type(returntype);
- if (!vt) {
- Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), NIL);
- } else {
- Wrapper_add_localv(w, "c_result", SwigType_lstr(vt, "c_result"), NIL);
- Delete(vt);
- }
- }
- }
-
- /* Create the intermediate class wrapper */
- tm = Swig_typemap_lookup("jtype", n, "", 0);
- if (tm) {
- Printf(callback_def, " public static %s %s(%s jself", tm, imclass_dmethod, qualified_classname);
- } else {
- Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s\n", SwigType_str(returntype, 0));
- }
-
- String *cdesc = NULL;
- SwigType *covariant = Getattr(n, "covariant");
- SwigType *adjustedreturntype = covariant ? covariant : returntype;
- Parm *adjustedreturntypeparm = NewParmNode(adjustedreturntype, n);
-
- if (Swig_typemap_lookup("directorin", adjustedreturntypeparm, "", 0)
- && (cdesc = Getattr(adjustedreturntypeparm, "tmap:directorin:descriptor"))) {
-
- // Note that in the case of polymorphic (covariant) return types, the
- // method's return type is changed to be the base of the C++ return
- // type
- String *jnidesc_canon = canonicalizeJNIDescriptor(cdesc, adjustedreturntypeparm);
- Append(classret_desc, jnidesc_canon);
- Delete(jnidesc_canon);
- } else {
- Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, "No or improper directorin typemap defined for %s for use in %s::%s (skipping director method)\n",
- SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- output_director = false;
- }
-
- /* Get the JNI field descriptor for this return type, add the JNI field descriptor
- to jniret_desc */
- if ((c_ret_type = Swig_typemap_lookup("jni", n, "", 0))) {
- Parm *tp = NewParmNode(c_ret_type, n);
-
- if (!is_void && !ignored_method) {
- String *jretval_decl = NewStringf("%s jresult", c_ret_type);
- Wrapper_add_localv(w, "jresult", jretval_decl, "= 0", NIL);
- Delete(jretval_decl);
- }
-
- String *jdesc = NULL;
- if (Swig_typemap_lookup("directorin", tp, "", 0)
- && (jdesc = Getattr(tp, "tmap:directorin:descriptor"))) {
-
- // Objects marshalled passing a Java class across JNI boundary use jobject - the nouse flag indicates this
- // We need the specific Java class name instead of the generic 'Ljava/lang/Object;'
- if (GetFlag(tp, "tmap:directorin:nouse"))
- jdesc = cdesc;
- String *jnidesc_canon = canonicalizeJNIDescriptor(jdesc, tp);
- Append(jniret_desc, jnidesc_canon);
- Delete(jnidesc_canon);
- } else {
- Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
- "No or improper directorin typemap defined for %s for use in %s::%s (skipping director method)\n",
- SwigType_str(c_ret_type, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- output_director = false;
- }
-
- Delete(tp);
- } else {
- Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number, "No jni typemap defined for %s for use in %s::%s (skipping director method)\n",
- SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- output_director = false;
- }
-
- Delete(adjustedreturntypeparm);
-
- Swig_director_parms_fixup(l);
-
- /* Attach the standard typemaps */
- Swig_typemap_attach_parms("out", l, 0);
- Swig_typemap_attach_parms("jni", l, 0);
- Swig_typemap_attach_parms("jtype", l, 0);
- Swig_typemap_attach_parms("directorin", l, w);
- Swig_typemap_attach_parms("javadirectorin", l, 0);
- Swig_typemap_attach_parms("directorargout", l, w);
-
- if (!ignored_method) {
- /* Add Java environment pointer to wrapper */
- String *jenvstr = NewString("jenv");
- String *jobjstr = NewString("swigjobj");
-
- Wrapper_add_localv(w, "swigjnienv", "JNIEnvWrapper", "swigjnienv(this)", NIL, NIL);
- Wrapper_add_localv(w, jenvstr, "JNIEnv *", jenvstr, "= swigjnienv.getJNIEnv()", NIL);
- Wrapper_add_localv(w, jobjstr, "jobject", jobjstr, "= (jobject) NULL", NIL);
- Delete(jenvstr);
- Delete(jobjstr);
-
- /* Preamble code */
- Printf(w->code, "if (!swig_override[%d]) {\n", classmeth_off);
- }
-
- if (!pure_virtual) {
- String *super_call = Swig_method_call(super, l);
- if (is_void) {
- Printf(w->code, "%s;\n", super_call);
- if (!ignored_method)
- Printf(w->code, "return;\n");
- } else {
- Printf(w->code, "return %s;\n", super_call);
- }
- Delete(super_call);
- } else {
- Printf(w->code, "SWIG_JavaThrowException(JNIEnvWrapper(this).getJNIEnv(), SWIG_JavaDirectorPureVirtual, ");
- Printf(w->code, "\"Attempted to invoke pure virtual method %s::%s.\");\n", SwigType_namestr(c_classname), SwigType_namestr(name));
-
- /* Make sure that we return something in the case of a pure
- * virtual method call for syntactical reasons. */
- if (!is_void)
- Printf(w->code, "return %s;", qualified_return);
- else if (!ignored_method)
- Printf(w->code, "return;\n");
- }
-
- if (!ignored_method) {
- Printf(w->code, "}\n");
- Printf(w->code, "swigjobj = swig_get_self(jenv);\n");
- Printf(w->code, "if (swigjobj && jenv->IsSameObject(swigjobj, NULL) == JNI_FALSE) {\n");
- }
-
- /* Start the Java field descriptor for the intermediate class's upcall (insert jself object) */
- Parm *tp = NewParmNode(c_classname, n);
- String *jdesc;
-
- if ((tm = Swig_typemap_lookup("directorin", tp, "", 0))
- && (jdesc = Getattr(tp, "tmap:directorin:descriptor"))) {
- String *jni_canon = canonicalizeJNIDescriptor(jdesc, tp);
- Append(jnidesc, jni_canon);
- Delete(jni_canon);
- Delete(tm);
- } else {
- Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
- "No or improper directorin typemap for type %s for use in %s::%s (skipping director method)\n",
- SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- output_director = false;
- }
-
- Delete(tp);
-
- /* Go through argument list, convert from native to Java */
- for (i = 0, p = l; p; ++i) {
- /* Is this superfluous? */
- while (checkAttribute(p, "tmap:directorin:numinputs", "0")) {
- p = Getattr(p, "tmap:directorin:next");
- }
-
- SwigType *pt = Getattr(p, "type");
- String *ln = makeParameterName(n, p, i, false);
- String *c_param_type = NULL;
- String *c_decl = NewString("");
- String *arg = NewString("");
-
- Printf(arg, "j%s", ln);
-
- /* Add various typemap's 'throws' clauses */
- addThrows(n, "tmap:directorin", p);
- addThrows(n, "tmap:out", p);
-
- /* And add to the upcall args */
- Printf(jupcall_args, ", %s", arg);
-
- /* Get parameter's intermediary C type */
- if ((c_param_type = Getattr(p, "tmap:jni"))) {
- Parm *tp = NewParm(c_param_type, Getattr(p, "name"), n);
- String *desc_tm = NULL, *jdesc = NULL, *cdesc = NULL;
-
- /* Add to local variables */
- Printf(c_decl, "%s %s", c_param_type, arg);
- if (!ignored_method)
- Wrapper_add_localv(w, arg, c_decl, (!(SwigType_ispointer(pt) || SwigType_isreference(pt)) ? "" : "= 0"), NIL);
-
- /* Add input marshalling code and update JNI field descriptor */
- if ((desc_tm = Swig_typemap_lookup("directorin", tp, "", 0))
- && (jdesc = Getattr(tp, "tmap:directorin:descriptor"))
- && (tm = Getattr(p, "tmap:directorin"))
- && (cdesc = Getattr(p, "tmap:directorin:descriptor"))) {
-
- // Objects marshalled by passing a Java class across the JNI boundary use jobject as the JNI type -
- // the nouse flag indicates this. We need the specific Java class name instead of the generic 'Ljava/lang/Object;'
- if (GetFlag(tp, "tmap:directorin:nouse"))
- jdesc = cdesc;
- String *jni_canon = canonicalizeJNIDescriptor(jdesc, tp);
- Append(jnidesc, jni_canon);
- Delete(jni_canon);
-
- Setattr(p, "emit:directorinput", arg);
- Replaceall(tm, "$input", arg);
- Replaceall(tm, "$owner", "0");
-
- if (Len(tm))
- if (!ignored_method)
- Printf(w->code, "%s\n", tm);
-
- /* Add parameter to the intermediate class code if generating the
- * intermediate's upcall code */
- if ((tm = Getattr(p, "tmap:jtype"))) {
- String *din = Copy(Getattr(p, "tmap:javadirectorin"));
- addThrows(n, "tmap:javadirectorin", p);
-
- if (din) {
- Replaceall(din, "$module", module_class_name);
- Replaceall(din, "$imclassname", imclass_name);
- substituteClassname(pt, din);
- Replaceall(din, "$jniinput", ln);
-
- if (i > 0)
- Printf(imcall_args, ", ");
- Printf(callback_def, ", %s %s", tm, ln);
-
- if (Cmp(din, ln)) {
- Printv(imcall_args, din, NIL);
- } else
- Printv(imcall_args, ln, NIL);
-
- jni_canon = canonicalizeJNIDescriptor(cdesc, p);
- Append(classdesc, jni_canon);
- Delete(jni_canon);
- } else {
- Swig_warning(WARN_JAVA_TYPEMAP_JAVADIRECTORIN_UNDEF, input_file, line_number, "No javadirectorin typemap defined for %s for use in %s::%s (skipping director method)\n",
- SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- output_director = false;
- }
- } else {
- Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s for use in %s::%s (skipping director method)\n",
- SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- output_director = false;
- }
-
- p = Getattr(p, "tmap:directorin:next");
-
- Delete(desc_tm);
- } else {
- if (!desc_tm) {
- Swig_warning(WARN_JAVA_TYPEMAP_JAVADIRECTORIN_UNDEF, input_file, line_number,
- "No or improper directorin typemap defined for %s for use in %s::%s (skipping director method)\n",
- SwigType_str(c_param_type, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- p = nextSibling(p);
- } else if (!jdesc) {
- Swig_warning(WARN_JAVA_TYPEMAP_DIRECTORIN_NODESC, input_file, line_number,
- "Missing JNI descriptor in directorin typemap defined for %s for use in %s::%s (skipping director method)\n",
- SwigType_str(c_param_type, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- p = Getattr(p, "tmap:directorin:next");
- } else if (!tm) {
- Swig_warning(WARN_JAVA_TYPEMAP_JAVADIRECTORIN_UNDEF, input_file, line_number,
- "No or improper directorin typemap defined for argument %s for use in %s::%s (skipping director method)\n",
- SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- p = nextSibling(p);
- } else if (!cdesc) {
- Swig_warning(WARN_JAVA_TYPEMAP_DIRECTORIN_NODESC, input_file, line_number,
- "Missing JNI descriptor in directorin typemap defined for %s for use in %s::%s (skipping director method)\n",
- SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- p = Getattr(p, "tmap:directorin:next");
- }
-
- output_director = false;
- }
-
- } else {
- Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number, "No jni typemap defined for %s for use in %s::%s (skipping director method)\n",
- SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- output_director = false;
- p = nextSibling(p);
- }
-
- Delete(arg);
- Delete(c_decl);
- Delete(ln);
- }
-
- /* header declaration, start wrapper definition */
- String *target;
- SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
- target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
- Printf(w->def, "%s", target);
- Delete(qualified_name);
- Delete(target);
- target = Swig_method_decl(rtype, decl, name, l, 1);
- Printf(declaration, " virtual %s", target);
- Delete(target);
-
- // Add any exception specifications to the methods in the director class
- // Get any Java exception classes in the throws typemap
- ParmList *throw_parm_list = NULL;
-
- // May need to add Java throws clause to director methods if %catches defined
- // Get any Java exception classes in the throws typemap
- ParmList *catches_list = Getattr(n, "catchlist");
- if (catches_list) {
- Swig_typemap_attach_parms("throws", catches_list, 0);
- Swig_typemap_attach_parms("directorthrows", catches_list, 0);
- for (p = catches_list; p; p = nextSibling(p)) {
- addThrows(n, "tmap:throws", p);
- }
- }
-
- if (Getattr(n, "noexcept")) {
- Append(w->def, " noexcept");
- Append(declaration, " noexcept");
- }
- if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
- int gencomma = 0;
-
- Append(w->def, " throw(");
- Append(declaration, " throw(");
-
- if (throw_parm_list) {
- Swig_typemap_attach_parms("throws", throw_parm_list, 0);
- Swig_typemap_attach_parms("directorthrows", throw_parm_list, 0);
- }
- for (p = throw_parm_list; p; p = nextSibling(p)) {
- if (Getattr(p, "tmap:throws")) {
- // %catches replaces the specified exception specification
- if (!catches_list) {
- addThrows(n, "tmap:throws", p);
- }
-
- if (gencomma++) {
- Append(w->def, ", ");
- Append(declaration, ", ");
- }
-
- Printf(w->def, "%s", SwigType_str(Getattr(p, "type"), 0));
- Printf(declaration, "%s", SwigType_str(Getattr(p, "type"), 0));
- }
- }
-
- Append(w->def, ")");
- Append(declaration, ")");
- }
-
- Append(w->def, " {");
- Append(declaration, ";\n");
-
- /* Emit the intermediate class's upcall to the actual class */
-
- String *upcall = NewStringf("jself.%s(%s)", symname, imcall_args);
-
- // Handle exception classes specified in the "except" feature's "throws" attribute
- addThrows(n, "feature:except", n);
-
- if (!is_void) {
- if ((tm = Swig_typemap_lookup("javadirectorout", n, "", 0))) {
- addThrows(n, "tmap:javadirectorout", n);
- substituteClassname(returntype, tm);
- Replaceall(tm, "$javacall", upcall);
-
- Printf(callback_code, " return %s;\n", tm);
- }
-
- if ((tm = Swig_typemap_lookup("out", n, "", 0)))
- addThrows(n, "tmap:out", n);
-
- Delete(tm);
- } else
- Printf(callback_code, " %s;\n", upcall);
-
- Printf(callback_code, " }\n");
- Delete(upcall);
-
- /* Finish off the inherited upcall's definition */
- Putc(')', callback_def);
- generateThrowsClause(n, callback_def);
- Printf(callback_def, " {\n");
-
- if (!ignored_method) {
- /* Emit the actual upcall through */
- String *imclass_desc = NewStringf("(%s)%s", jnidesc, jniret_desc);
- String *class_desc = NewStringf("(%s)%s", classdesc, classret_desc);
- UpcallData *udata = addUpcallMethod(imclass_dmethod, symname, imclass_desc, class_desc, decl);
- String *methid = Getattr(udata, "imclass_methodidx");
- String *methop = getUpcallJNIMethod(jniret_desc);
-
- if (!is_void)
- Printf(w->code, "jresult = (%s) ", c_ret_type);
-
- Printf(w->code, "jenv->%s(Swig::jclass_%s, Swig::director_method_ids[%s], %s);\n", methop, imclass_name, methid, jupcall_args);
-
- // Generate code to handle any Java exception thrown by director delegation
- directorExceptHandler(n, catches_list ? catches_list : throw_parm_list, w);
-
- if (!is_void) {
- String *jresult_str = NewString("jresult");
- String *result_str = NewString("c_result");
-
- /* Copy jresult into c_result... */
- if ((tm = Swig_typemap_lookup("directorout", n, result_str, w))) {
- addThrows(n, "tmap:directorout", n);
- Replaceall(tm, "$input", jresult_str);
- Replaceall(tm, "$result", result_str);
- Printf(w->code, "%s\n", tm);
- } else {
- Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
- "Unable to use return type %s used in %s::%s (skipping director method)\n",
- SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- output_director = false;
- }
-
- Delete(jresult_str);
- Delete(result_str);
- }
-
- /* Marshal outputs */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:directorargout"))) {
- addThrows(n, "tmap:directorargout", p);
- Replaceall(tm, "$result", makeParameterName(n, p, i, false));
- Replaceall(tm, "$input", Getattr(p, "emit:directorinput"));
- Printv(w->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:directorargout:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- Delete(imclass_desc);
- Delete(class_desc);
-
- /* Terminate wrapper code */
- Printf(w->code, "} else {\n");
- Printf(w->code, "SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, \"null upcall object in %s::%s \");\n",
- SwigType_namestr(c_classname), SwigType_namestr(name));
- Printf(w->code, "}\n");
-
- Printf(w->code, "if (swigjobj) jenv->DeleteLocalRef(swigjobj);\n");
-
- if (!is_void)
- Printf(w->code, "return %s;", qualified_return);
- }
-
- Printf(w->code, "}");
-
- // We expose virtual protected methods via an extra public inline method which makes a straight call to the wrapped class' method
- String *inline_extra_method = NewString("");
- if (dirprot_mode() && !is_public(n) && !pure_virtual) {
- Printv(inline_extra_method, declaration, NIL);
- String *extra_method_name = NewStringf("%sSwigPublic", name);
- Replaceall(inline_extra_method, name, extra_method_name);
- Replaceall(inline_extra_method, ";\n", " {\n ");
- if (!is_void)
- Printf(inline_extra_method, "return ");
- String *methodcall = Swig_method_call(super, l);
- Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
- Delete(methodcall);
- Delete(extra_method_name);
- }
-
- /* emit the director method */
- if (status == SWIG_OK && output_director) {
- if (!is_void) {
- Replaceall(w->code, "$null", qualified_return);
- } else {
- Replaceall(w->code, "$null", "");
- }
- if (!GetFlag(n, "feature:ignore"))
- Printv(imclass_directors, callback_def, callback_code, NIL);
- if (!Getattr(n, "defaultargs")) {
- Replaceall(w->code, "$symname", symname);
- Wrapper_print(w, f_directors);
- Printv(f_directors_h, declaration, NIL);
- Printv(f_directors_h, inline_extra_method, NIL);
- }
- }
-
- Delete(inline_extra_method);
- Delete(qualified_return);
- Delete(jnidesc);
- Delete(c_ret_type);
- Delete(jniret_desc);
- Delete(declaration);
- Delete(callback_def);
- Delete(callback_code);
- DelWrapper(w);
-
- return status;
- }
-
- /* ------------------------------------------------------------
- * directorExceptHandler()
- *
- * Emit code to map Java exceptions back to C++ exceptions when
- * feature("director:except") is applied to a method node.
- * This is generated after the Java method upcall.
- * ------------------------------------------------------------ */
-
- void directorExceptHandler(Node *n, ParmList *throw_parm_list, Wrapper *w) {
-
- String *directorexcept = Getattr(n, "feature:director:except");
- if (!directorexcept) {
- directorexcept = NewString("");
- Printf(directorexcept, "jthrowable $error = jenv->ExceptionOccurred();\n");
- Printf(directorexcept, "if ($error) {");
- Printf(directorexcept, "$directorthrowshandlers\n");
- Printf(directorexcept, " Swig::DirectorException::raise(jenv, $error);\n");
- Printf(directorexcept, "}\n");
- } else {
- directorexcept = Copy(directorexcept);
- }
-
- // Can explicitly disable director:except by setting to "" or "0"
- if (Len(directorexcept) > 0 && Cmp(directorexcept, "0") != 0) {
-
- // Replace $packagepath
- substitutePackagePath(directorexcept, 0);
-
- // Replace $directorthrowshandlers with any defined typemap handlers (or nothing)
- if (Strstr(directorexcept, "$directorthrowshandlers")) {
- String *directorthrowshandlers_code = NewString("");
-
- for (Parm *p = throw_parm_list; p; p = nextSibling(p)) {
- String *tm = Getattr(p, "tmap:directorthrows");
-
- if (tm) {
- // replace $packagepath/$javaclassname
- String *directorthrows = canonicalizeJNIDescriptor(tm, p);
- Printv(directorthrowshandlers_code, directorthrows, NIL);
- Delete(directorthrows);
- } else {
- String *t = Getattr(p,"type");
- Swig_warning(WARN_TYPEMAP_DIRECTORTHROWS_UNDEF, Getfile(n), Getline(n), "No directorthrows typemap defined for %s\n", SwigType_str(t, 0));
- }
- }
- Replaceall(directorexcept, "$directorthrowshandlers", directorthrowshandlers_code);
- Delete(directorthrowshandlers_code);
- }
-
- Replaceall(directorexcept, "$error", "swigerror");
- Printf(w->code, " %s\n", directorexcept);
- }
- Delete(directorexcept);
- }
-
- /* ------------------------------------------------------------
- * directorPrefixArgs()
- * ------------------------------------------------------------ */
-
- void directorPrefixArgs(Node *n) {
- Parm *p;
-
- /* Need to prepend 'jenv' to the director constructor's argument list */
-
- String *jenv_type = NewString("JNIEnv");
-
- SwigType_add_pointer(jenv_type);
-
- p = NewParm(jenv_type, NewString("jenv"), n);
- Setattr(p, "arg:byname", "1");
- set_nextSibling(p, NULL);
-
- Setattr(n, "director:prefix_args", p);
- }
-
- /* ------------------------------------------------------------
- * classDirectorConstructor()
- * ------------------------------------------------------------ */
-
- int classDirectorConstructor(Node *n) {
- Node *parent = parentNode(n);
- String *decl = Getattr(n, "decl");
- String *supername = Swig_class_name(parent);
- String *dirclassname = directorClassName(parent);
- String *sub = NewString("");
- Parm *p;
- ParmList *superparms = Getattr(n, "parms");
- ParmList *parms;
- int argidx = 0;
-
- /* Assign arguments to superclass's parameters, if not already done */
- for (p = superparms; p; p = nextSibling(p)) {
- String *pname = Getattr(p, "name");
-
- if (!pname) {
- pname = NewStringf("arg%d", argidx++);
- Setattr(p, "name", pname);
- }
- }
-
- /* insert jenv prefix argument */
- parms = CopyParmList(superparms);
-
- String *jenv_type = NewString("JNIEnv");
- SwigType_add_pointer(jenv_type);
- p = NewParm(jenv_type, NewString("jenv"), n);
- set_nextSibling(p, parms);
- parms = p;
-
- directorPrefixArgs(n);
-
- if (!Getattr(n, "defaultargs")) {
- /* constructor */
- {
- String *basetype = Getattr(parent, "classtype");
- String *target = Swig_method_decl(0, decl, dirclassname, parms, 0);
- String *call = Swig_csuperclass_call(0, basetype, superparms);
- String *classtype = SwigType_namestr(Getattr(n, "name"));
-
- Printf(f_directors, "%s::%s : %s, %s {\n", dirclassname, target, call, Getattr(parent, "director:ctor"));
- Printf(f_directors, "}\n\n");
-
- Delete(classtype);
- Delete(target);
- Delete(call);
- }
-
- /* constructor header */
- {
- String *target = Swig_method_decl(0, decl, dirclassname, parms, 1);
- Printf(f_directors_h, " %s;\n", target);
- Delete(target);
- }
- }
-
- Delete(sub);
- Delete(supername);
- Delete(jenv_type);
- Delete(parms);
- Delete(dirclassname);
- return Language::classDirectorConstructor(n);
- }
-
- /* ------------------------------------------------------------
- * classDirectorDefaultConstructor()
- * ------------------------------------------------------------ */
-
- int classDirectorDefaultConstructor(Node *n) {
- String *classname = Swig_class_name(n);
- String *classtype = SwigType_namestr(Getattr(n, "name"));
- String *dirClassName = directorClassName(n);
- Wrapper *w = NewWrapper();
-
- Printf(w->def, "%s::%s(JNIEnv *jenv) : %s {", dirClassName, dirClassName, Getattr(n, "director:ctor"));
- Printf(w->code, "}\n");
- Wrapper_print(w, f_directors);
-
- Printf(f_directors_h, " %s(JNIEnv *jenv);\n", dirClassName);
- DelWrapper(w);
- Delete(classtype);
- Delete(classname);
- Delete(dirClassName);
- directorPrefixArgs(n);
- return Language::classDirectorDefaultConstructor(n);
- }
-
-
- /* ------------------------------------------------------------
- * classDirectorInit()
- * ------------------------------------------------------------ */
-
- int classDirectorInit(Node *n) {
- Delete(none_comparison);
- none_comparison = NewString(""); // not used
-
- Delete(director_ctor_code);
- director_ctor_code = NewString("$director_new");
-
- directorDeclaration(n);
-
- Printf(f_directors_h, "%s {\n", Getattr(n, "director:decl"));
- Printf(f_directors_h, "\npublic:\n");
- Printf(f_directors_h, " void swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls, bool swig_mem_own, bool weak_global);\n");
-
- /* Keep track of the director methods for this class */
- first_class_dmethod = curr_class_dmethod = n_dmethods;
-
- return Language::classDirectorInit(n);
- }
-
- /* ----------------------------------------------------------------------
- * classDirectorDestructor()
- * ---------------------------------------------------------------------- */
-
- int classDirectorDestructor(Node *n) {
- Node *current_class = getCurrentClass();
- String *full_classname = Getattr(current_class, "name");
- String *classname = Swig_class_name(current_class);
- String *dirClassName = directorClassName(current_class);
- Wrapper *w = NewWrapper();
-
- if (Getattr(n, "noexcept")) {
- Printf(f_directors_h, " virtual ~%s() noexcept;\n", dirClassName);
- Printf(w->def, "%s::~%s() noexcept {\n", dirClassName, dirClassName);
- } else if (Getattr(n, "throw")) {
- Printf(f_directors_h, " virtual ~%s() throw();\n", dirClassName);
- Printf(w->def, "%s::~%s() throw() {\n", dirClassName, dirClassName);
- } else {
- Printf(f_directors_h, " virtual ~%s();\n", dirClassName);
- Printf(w->def, "%s::~%s() {\n", dirClassName, dirClassName);
- }
-
- /* Ensure that correct directordisconnect typemap's method name is called
- * here: */
-
- Node *disconn_attr = NewHash();
- String *disconn_methodname = NULL;
-
- typemapLookup(n, "directordisconnect", full_classname, WARN_NONE, disconn_attr);
- disconn_methodname = Getattr(disconn_attr, "tmap:directordisconnect:methodname");
-
- Printv(w->code, " swig_disconnect_director_self(\"", disconn_methodname, "\");\n", "}\n", NIL);
-
- Wrapper_print(w, f_directors);
-
- DelWrapper(w);
- Delete(disconn_attr);
- Delete(classname);
- Delete(dirClassName);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * classDirectorEnd()
- * ------------------------------------------------------------ */
-
- int classDirectorEnd(Node *n) {
- String *full_classname = Getattr(n, "name");
- String *classname = getProxyName(full_classname, true);
- String *director_classname = directorClassName(n);
- String *internal_classname;
-
- Wrapper *w = NewWrapper();
-
- if (Len(package_path) > 0)
- internal_classname = NewStringf("%s/%s", package_path, classname);
- else
- internal_classname = NewStringf("%s", classname);
-
- // If the namespace is multiple levels, the result of getNSpace() will have inserted
- // .'s to delimit namespaces, so we need to replace those with /'s
- Replace(internal_classname, NSPACE_SEPARATOR, "/", DOH_REPLACE_ANY);
-
- Printf(w->def, "void %s::swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls, bool swig_mem_own, bool weak_global) {", director_classname);
-
- Printf(w->def, "static jclass baseclass = swig_new_global_ref(jenv, \"%s\");\n", internal_classname);
- Printf(w->def, "if (!baseclass) return;\n");
-
- if (first_class_dmethod != curr_class_dmethod) {
- Printf(w->def, "static SwigDirectorMethod methods[] = {\n");
-
- for (int i = first_class_dmethod; i < curr_class_dmethod; ++i) {
- UpcallData *udata = Getitem(dmethods_seq, i);
-
- Printf(w->def, "SwigDirectorMethod(jenv, baseclass, \"%s\", \"%s\")", Getattr(udata, "method"), Getattr(udata, "fdesc"));
- if (i != curr_class_dmethod - 1)
- Putc(',', w->def);
- Putc('\n', w->def);
- }
-
- Printf(w->def, "};");
- }
-
- Printf(w->code, "if (swig_set_self(jenv, jself, swig_mem_own, weak_global)) {\n");
-
- int n_methods = curr_class_dmethod - first_class_dmethod;
-
- if (n_methods) {
- /* Emit the swig_overrides() method and the swig_override array */
- Printf(f_directors_h, "public:\n");
- Printf(f_directors_h, " bool swig_overrides(int n) {\n");
- Printf(f_directors_h, " return (n < %d ? swig_override[n] : false);\n", n_methods);
- Printf(f_directors_h, " }\n");
- Printf(f_directors_h, "protected:\n");
- Printf(f_directors_h, " Swig::BoolArray<%d> swig_override;\n", n_methods);
-
- /* Emit the code to look up the class's methods, initialize the override array */
-
- Printf(w->code, " bool derived = (jenv->IsSameObject(baseclass, jcls) ? false : true);\n");
- Printf(w->code, " for (int i = 0; i < %d; ++i) {\n", n_methods);
- // Generally, derived classes have a mix of overridden and
- // non-overridden methods and it is worth making a GetMethodID
- // check during initialization to determine if each method is
- // overridden, thus avoiding unnecessary calls into Java.
- //
- // On the other hand, when derived classes are
- // expected to override all director methods then the
- // GetMethodID calls are inefficient, and it is better to let
- // the director unconditionally call up into Java. The resulting code
- // will still behave correctly (though less efficiently) when Java
- // code doesn't override a given method.
- //
- // The assumeoverride feature on a director controls whether or not
- // overrides are assumed.
- if (GetFlag(n, "feature:director:assumeoverride")) {
- Printf(w->code, " swig_override[i] = derived;\n");
- } else {
- Printf(w->code, " swig_override[i] = false;\n");
- Printf(w->code, " if (derived) {\n");
- Printf(w->code, " jmethodID methid = jenv->GetMethodID(jcls, methods[i].name, methods[i].desc);\n");
- Printf(w->code, " swig_override[i] = methods[i].methid && (methid != methods[i].methid);\n");
- Printf(w->code, " jenv->ExceptionClear();\n");
- Printf(w->code, " }\n");
- }
- Printf(w->code, "}\n");
- } else {
- Printf(f_directors_h, "public:\n");
- Printf(f_directors_h, " bool swig_overrides(int n) {\n");
- Printf(f_directors_h, " return false;\n");
- Printf(f_directors_h, " }\n");
- }
-
- Printf(f_directors_h, "};\n\n");
- Printf(w->code, "}\n");
- Printf(w->code, "}\n");
-
- Wrapper_print(w, f_directors);
-
- DelWrapper(w);
- Delete(internal_classname);
-
- return Language::classDirectorEnd(n);
- }
-
- /* --------------------------------------------------------------------
- * classDirectorDisown()
- * ------------------------------------------------------------------*/
-
- virtual int classDirectorDisown(Node *n) {
- (void) n;
- return SWIG_OK;
- }
-
- /*----------------------------------------------------------------------
- * extraDirectorProtectedCPPMethodsRequired()
- *--------------------------------------------------------------------*/
-
- bool extraDirectorProtectedCPPMethodsRequired() const {
- return false;
- }
-
- /*----------------------------------------------------------------------
- * directorDeclaration()
- *
- * Generate the director class's declaration
- * e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {"
- *--------------------------------------------------------------------*/
-
- void directorDeclaration(Node *n) {
- String *base = Getattr(n, "classtype");
- String *class_ctor = NewString("Swig::Director(jenv)");
-
- String *directorname = directorClassName(n);
- String *declaration = Swig_class_declaration(n, directorname);
-
- Printf(declaration, " : public %s, public Swig::Director", base);
-
- // Stash stuff for later.
- Setattr(n, "director:decl", declaration);
- Setattr(n, "director:ctor", class_ctor);
- }
-
- /*----------------------------------------------------------------------
- * nestedClassesSupport()
- *--------------------------------------------------------------------*/
-
- NestedClassSupport nestedClassesSupport() const {
- return NCS_Full;
- }
-}; /* class JAVA */
-
-/* -----------------------------------------------------------------------------
- * swig_java() - Instantiate module
- * ----------------------------------------------------------------------------- */
-
-static Language *new_swig_java() {
- return new JAVA();
-}
-extern "C" Language *swig_java(void) {
- return new_swig_java();
-}
-
-/* -----------------------------------------------------------------------------
- * Static member variables
- * ----------------------------------------------------------------------------- */
-
-const char *JAVA::usage = "\
-Java Options (available with -java)\n\
- -doxygen - Convert C++ doxygen comments to JavaDoc comments in proxy classes\n\
- -debug-doxygen-parser - Display doxygen parser module debugging information\n\
- -debug-doxygen-translator - Display doxygen translator module debugging information\n\
- -nopgcpp - Suppress premature garbage collection prevention parameter\n\
- -noproxy - Generate the low-level functional interface instead\n\
- of proxy classes\n\
- -oldvarnames - Old intermediary method names for variable wrappers\n\
- -package <name> - Set name of the Java package to <name>\n\
-\n";
diff --git a/contrib/tools/swig/Source/Modules/javascript.cxx b/contrib/tools/swig/Source/Modules/javascript.cxx
deleted file mode 100644
index 17effc220f..0000000000
--- a/contrib/tools/swig/Source/Modules/javascript.cxx
+++ /dev/null
@@ -1,2490 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * javascript.cxx
- *
- * Javascript language module for SWIG.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include "cparse.h"
-
-/**
- * Enables extra debugging information in typemaps.
- */
-static bool js_template_enable_debug = false;
-
-#define ERR_MSG_ONLY_ONE_ENGINE_PLEASE "Only one engine can be specified at a time."
-
-// keywords used for state variables
-#define NAME "name"
-#define NAME_MANGLED "name_mangled"
-#define TYPE "type"
-#define TYPE_MANGLED "type_mangled"
-#define WRAPPER_NAME "wrapper"
-#define IS_IMMUTABLE "is_immutable"
-#define IS_STATIC "is_static"
-#define IS_ABSTRACT "is_abstract"
-#define GETTER "getter"
-#define SETTER "setter"
-#define PARENT "parent"
-#define PARENT_MANGLED "parent_mangled"
-#define CTOR "ctor"
-#define CTOR_WRAPPERS "ctor_wrappers"
-#define CTOR_DISPATCHERS "ctor_dispatchers"
-#define DTOR "dtor"
-#define ARGCOUNT "wrap:argc"
-#define HAS_TEMPLATES "has_templates"
-#define FORCE_CPP "force_cpp"
-#define RESET true
-
-// keys for global state variables
-#define CREATE_NAMESPACES "create_namespaces"
-#define REGISTER_NAMESPACES "register_namespaces"
-#define INITIALIZER "initializer"
-
-// keys for class scoped state variables
-#define MEMBER_VARIABLES "member_variables"
-#define MEMBER_FUNCTIONS "member_functions"
-#define STATIC_FUNCTIONS "static_functions"
-#define STATIC_VARIABLES "static_variables"
-
-
-/**
- * A convenience class to manage state variables for emitters.
- * The implementation delegates to SWIG Hash DOHs and provides
- * named sub-hashes for class, variable, and function states.
- */
-class JSEmitterState {
-
-public:
- JSEmitterState();
- ~JSEmitterState();
- DOH *globals();
- DOH *globals(const char *key, DOH *initial = 0);
- DOH *clazz(bool reset = false);
- DOH *clazz(const char *key, DOH *initial = 0);
- DOH *function(bool reset = false);
- DOH *function(const char *key, DOH *initial = 0);
- DOH *variable(bool reset = false);
- DOH *variable(const char *key, DOH *initial = 0);
- static int IsSet(DOH *val);
-
-private:
- DOH *getState(const char *key, bool reset = false);
- Hash *globalHash;
-};
-
-/**
- * A convenience class that wraps a code snippet used as template
- * for code generation.
- */
-class Template {
-
-public:
- Template(const String *code);
- Template(const String *code, const String *templateName);
- Template(const Template & other);
- ~Template();
- String *str();
- Template & replace(const String *pattern, const String *repl);
- Template & print(DOH *doh);
- Template & pretty_print(DOH *doh);
- void operator=(const Template & t);
- Template & trim();
-
-private:
- String *code;
- String *templateName;
-};
-
-/**
- * JSEmitter represents an abstraction of javascript code generators
- * for different javascript engines.
- **/
-class JSEmitter {
-
-protected:
-
- typedef JSEmitterState State;
-
- enum MarshallingMode {
- Setter,
- Getter,
- Ctor,
- Function
- };
-
-public:
-
- enum JSEngine {
- JavascriptCore,
- V8,
- NodeJS
- };
-
- JSEmitter(JSEngine engine);
-
- virtual ~ JSEmitter();
-
- /**
- * Opens output files and temporary output DOHs.
- */
- virtual int initialize(Node *n);
-
- /**
- * Writes all collected code into the output file(s).
- */
- virtual int dump(Node *n) = 0;
-
- /**
- * Cleans up all open output DOHs.
- */
- virtual int close() = 0;
-
- /**
- * Switches the context for code generation.
- *
- * Classes, global variables and global functions may need to
- * be registered in certain static tables.
- * This method should be used to switch output DOHs correspondingly.
- */
- virtual int switchNamespace(Node *);
-
- /**
- * Invoked at the beginning of the classHandler.
- */
- virtual int enterClass(Node *);
-
- /**
- * Invoked at the end of the classHandler.
- */
- virtual int exitClass(Node *) {
- return SWIG_OK;
- }
-
- /**
- * Invoked at the beginning of the variableHandler.
- */
- virtual int enterVariable(Node *);
-
- /**
- * Invoked at the end of the variableHandler.
- */
- virtual int exitVariable(Node *) {
- return SWIG_OK;
- }
-
- /**
- * Invoked at the beginning of the functionHandler.
- */
- virtual int enterFunction(Node *);
-
- /**
- * Invoked at the end of the functionHandler.
- */
- virtual int exitFunction(Node *) {
- return SWIG_OK;
- }
-
- /**
- * Invoked by functionWrapper callback after call to Language::functionWrapper.
- */
- virtual int emitWrapperFunction(Node *n);
-
- /**
- * Invoked by nativeWrapper callback
- */
- virtual int emitNativeFunction(Node *n);
-
- /**
- * Invoked from constantWrapper after call to Language::constantWrapper.
- **/
- virtual int emitConstant(Node *n);
-
- /**
- * Registers a given code snippet for a given key name.
- *
- * This method is called by the fragmentDirective handler
- * of the JAVASCRIPT language module.
- **/
- int registerTemplate(const String *name, const String *code);
-
- /**
- * Retrieve the code template registered for a given name.
- */
- Template getTemplate(const String *name);
-
- State & getState();
-
-protected:
-
- /**
- * Generates code for a constructor function.
- */
- virtual int emitCtor(Node *n);
-
- /**
- * Generates code for a destructor function.
- */
- virtual int emitDtor(Node *n);
-
- /**
- * Generates code for a function.
- */
- virtual int emitFunction(Node *n, bool is_member, bool is_static);
-
- virtual int emitFunctionDispatcher(Node *n, bool /*is_member */ );
-
- /**
- * Generates code for a getter function.
- */
- virtual int emitGetter(Node *n, bool is_member, bool is_static);
-
- /**
- * Generates code for a setter function.
- */
- virtual int emitSetter(Node *n, bool is_member, bool is_static);
-
- virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) = 0;
-
- virtual String *emitInputTypemap(Node *n, Parm *params, Wrapper *wrapper, String *arg);
-
- virtual void marshalOutput(Node *n, ParmList *params, Wrapper *wrapper, String *actioncode, const String *cresult = 0, bool emitReturnVariable = true);
-
- virtual void emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params);
-
- /**
- * Helper function to retrieve the first parent class node.
- */
- Node *getBaseClass(Node *n);
-
- Parm *skipIgnoredArgs(Parm *p);
-
- virtual int createNamespace(String *scope);
-
- virtual Hash *createNamespaceEntry(const char *name, const char *parent, const char *parent_mangled);
-
- virtual int emitNamespaces() = 0;
-
-
-protected:
-
- JSEngine engine;
- Hash *templates;
- State state;
-
- // contains context specific data (DOHs)
- // to allow generation of namespace related code
- // which are switched on namespace change
- Hash *namespaces;
- Hash *current_namespace;
- String *defaultResultName;
- File *f_wrappers;
-};
-
-/* factory methods for concrete JSEmitters: */
-
-JSEmitter *swig_javascript_create_JSCEmitter();
-JSEmitter *swig_javascript_create_V8Emitter();
-JSEmitter *swig_javascript_create_NodeJSEmitter();
-
-/**********************************************************************
- * JAVASCRIPT: SWIG module implementation
- **********************************************************************/
-
-class JAVASCRIPT:public Language {
-
-public:
-
- JAVASCRIPT():emitter(NULL) {
- }
- ~JAVASCRIPT() {
- delete emitter;
- }
-
- virtual int functionHandler(Node *n);
- virtual int globalfunctionHandler(Node *n);
- virtual int variableHandler(Node *n);
- virtual int globalvariableHandler(Node *n);
- virtual int staticmemberfunctionHandler(Node *n);
- virtual int classHandler(Node *n);
- virtual int functionWrapper(Node *n);
- virtual int constantWrapper(Node *n);
- virtual int nativeWrapper(Node *n);
- virtual void main(int argc, char *argv[]);
- virtual int top(Node *n);
-
- /**
- * Registers all %fragments assigned to section "templates".
- **/
- virtual int fragmentDirective(Node *n);
-
-public:
-
- virtual String *getNSpace() const;
-
-private:
-
- JSEmitter *emitter;
-};
-
-/* ---------------------------------------------------------------------
- * functionWrapper()
- *
- * Low level code generator for functions
- * --------------------------------------------------------------------- */
-
-int JAVASCRIPT::functionWrapper(Node *n) {
-
- // note: the default implementation only prints a message
- // Language::functionWrapper(n);
- emitter->emitWrapperFunction(n);
-
- return SWIG_OK;
-}
-
-/* ---------------------------------------------------------------------
- * functionHandler()
- *
- * Function handler for generating wrappers for functions
- * --------------------------------------------------------------------- */
-int JAVASCRIPT::functionHandler(Node *n) {
-
- if (GetFlag(n, "isextension") == 1) {
- SetFlag(n, "ismember");
- }
-
- emitter->enterFunction(n);
- Language::functionHandler(n);
- emitter->exitFunction(n);
-
- return SWIG_OK;
-}
-
-/* ---------------------------------------------------------------------
- * globalfunctionHandler()
- *
- * Function handler for generating wrappers for functions
- * --------------------------------------------------------------------- */
-
-int JAVASCRIPT::globalfunctionHandler(Node *n) {
- emitter->switchNamespace(n);
- Language::globalfunctionHandler(n);
-
- return SWIG_OK;
-}
-
-/* ---------------------------------------------------------------------
- * staticmemberfunctionHandler()
- *
- * Function handler for generating wrappers for static member functions
- * --------------------------------------------------------------------- */
-
-int JAVASCRIPT::staticmemberfunctionHandler(Node *n) {
- /*
- * Note: storage=static is removed by Language::staticmemberfunctionHandler.
- * So, don't rely on that after here. Instead use the state variable which is
- * set by JSEmitter::enterFunction().
- */
- Language::staticmemberfunctionHandler(n);
- return SWIG_OK;
-}
-
-/* ---------------------------------------------------------------------
- * variableHandler()
- *
- * Function handler for generating wrappers for variables
- * --------------------------------------------------------------------- */
-
-int JAVASCRIPT::variableHandler(Node *n) {
-
- emitter->enterVariable(n);
- Language::variableHandler(n);
- emitter->exitVariable(n);
-
- return SWIG_OK;
-}
-
-/* ---------------------------------------------------------------------
- * globalvariableHandler()
- *
- * Function handler for generating wrappers for global variables
- * --------------------------------------------------------------------- */
-
-int JAVASCRIPT::globalvariableHandler(Node *n) {
- emitter->switchNamespace(n);
- Language::globalvariableHandler(n);
-
- return SWIG_OK;
-}
-
-/* ---------------------------------------------------------------------
- * constantHandler()
- *
- * Function handler for generating wrappers for constants
- * --------------------------------------------------------------------- */
-
-int JAVASCRIPT::constantWrapper(Node *n) {
- emitter->switchNamespace(n);
-
- // Note: callbacks trigger this wrapper handler
- // TODO: handle callback declarations
- if (Equal(Getattr(n, "kind"), "function")) {
- return SWIG_OK;
- }
- // TODO: the emitter for constants must be implemented in a cleaner way
- // currently we treat it like a read-only variable
- // however, there is a remaining bug with function pointer constants
- // which could be fixed with a cleaner approach
- emitter->emitConstant(n);
-
- return SWIG_OK;
-}
-
-/* ---------------------------------------------------------------------
- * nativeWrapper()
- *
- * Function wrapper for generating placeholders for native functions
- * --------------------------------------------------------------------- */
-
-int JAVASCRIPT::nativeWrapper(Node *n) {
- emitter->emitNativeFunction(n);
-
- return SWIG_OK;
-}
-
-/* ---------------------------------------------------------------------
- * classHandler()
- *
- * Function handler for generating wrappers for class
- * --------------------------------------------------------------------- */
-
-int JAVASCRIPT::classHandler(Node *n) {
- emitter->switchNamespace(n);
-
- emitter->enterClass(n);
- Language::classHandler(n);
- emitter->exitClass(n);
-
- return SWIG_OK;
-}
-
-int JAVASCRIPT::fragmentDirective(Node *n) {
-
- // catch all fragment directives that have "templates" as location
- // and register them at the emitter.
- String *section = Getattr(n, "section");
-
- if (Equal(section, "templates") && !ImportMode) {
- emitter->registerTemplate(Getattr(n, "value"), Getattr(n, "code"));
- } else {
- return Language::fragmentDirective(n);
- }
-
- return SWIG_OK;
-}
-
-String *JAVASCRIPT::getNSpace() const {
- return Language::getNSpace();
-}
-
-/* ---------------------------------------------------------------------
- * top()
- *
- * Function handler for processing top node of the parse tree
- * Wrapper code generation essentially starts from here
- * --------------------------------------------------------------------- */
-
-int JAVASCRIPT::top(Node *n) {
- emitter->initialize(n);
-
- Language::top(n);
-
- emitter->dump(n);
- emitter->close();
-
- return SWIG_OK;
-}
-
-static const char *usage = (char *) "\
-Javascript Options (available with -javascript)\n\
- -jsc - creates a JavascriptCore extension \n\
- -v8 - creates a v8 extension \n\
- -node - creates a node.js extension \n\
- -debug-codetemplates - generates information about the origin of code templates\n";
-
-
-/* ---------------------------------------------------------------------
- * main()
- *
- * Entry point for the JAVASCRIPT module
- * --------------------------------------------------------------------- */
-
-void JAVASCRIPT::main(int argc, char *argv[]) {
- // Set javascript subdirectory in SWIG library
- SWIG_library_directory("javascript");
-
- int engine = -1;
-
- for (int i = 1; i < argc; i++) {
- if (argv[i]) {
- if (strcmp(argv[i], "-v8") == 0) {
- if (engine != -1) {
- Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE);
- Exit(EXIT_FAILURE);
- }
- Swig_mark_arg(i);
- engine = JSEmitter::V8;
- } else if (strcmp(argv[i], "-jsc") == 0) {
- if (engine != -1) {
- Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE);
- Exit(EXIT_FAILURE);
- }
- Swig_mark_arg(i);
- engine = JSEmitter::JavascriptCore;
- } else if (strcmp(argv[i], "-node") == 0) {
- if (engine != -1) {
- Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE);
- Exit(EXIT_FAILURE);
- }
- Swig_mark_arg(i);
- engine = JSEmitter::NodeJS;
- } else if (strcmp(argv[i], "-debug-codetemplates") == 0) {
- Swig_mark_arg(i);
- js_template_enable_debug = true;
- } else if (strcmp(argv[i], "-help") == 0) {
- fputs(usage, stdout);
- return;
- }
- }
- }
-
- switch (engine) {
- case JSEmitter::V8:
- {
- emitter = swig_javascript_create_V8Emitter();
- Preprocessor_define("SWIG_JAVASCRIPT_V8 1", 0);
- SWIG_library_directory("javascript/v8");
- // V8 API is C++, so output must be C++ compatible even when wrapping C code
- if (!cparse_cplusplus) {
- Swig_cparse_cplusplusout(1);
- }
- break;
- }
- case JSEmitter::JavascriptCore:
- {
- emitter = swig_javascript_create_JSCEmitter();
- Preprocessor_define("SWIG_JAVASCRIPT_JSC 1", 0);
- SWIG_library_directory("javascript/jsc");
- break;
- }
- case JSEmitter::NodeJS:
- {
- emitter = swig_javascript_create_V8Emitter();
- Preprocessor_define("SWIG_JAVASCRIPT_V8 1", 0);
- Preprocessor_define("BUILDING_NODE_EXTENSION 1", 0);
- SWIG_library_directory("javascript/v8");
- break;
- }
- default:
- {
- Printf(stderr, "SWIG Javascript: Unknown engine. Please specify one of '-jsc', '-v8' or '-node'.\n");
- Exit(EXIT_FAILURE);
- break;
- }
- }
-
- // Add a symbol to the parser for conditional compilation
- Preprocessor_define("SWIGJAVASCRIPT 1", 0);
-
- // Add typemap definitions
- SWIG_typemap_lang("javascript");
-
- // Set configuration file
- SWIG_config_file("javascript.swg");
-
- allow_overloading();
-}
-
-/* -----------------------------------------------------------------------------
- * swig_javascript() - Instantiate module
- * ----------------------------------------------------------------------------- */
-
-static Language *new_swig_javascript() {
- return new JAVASCRIPT();
-}
-
-extern "C" Language *swig_javascript(void) {
- return new_swig_javascript();
-}
-
-/**********************************************************************
- * Emitter implementations
- **********************************************************************/
-
-/* -----------------------------------------------------------------------------
- * JSEmitter()
- * ----------------------------------------------------------------------------- */
-
-JSEmitter::JSEmitter(JSEmitter::JSEngine engine)
-: engine(engine), templates(NewHash()), namespaces(NULL), current_namespace(NULL), defaultResultName(NewString("result")), f_wrappers(NULL) {
-}
-
-/* -----------------------------------------------------------------------------
- * ~JSEmitter()
- * ----------------------------------------------------------------------------- */
-
-JSEmitter::~JSEmitter() {
- Delete(templates);
-}
-
-/* -----------------------------------------------------------------------------
- * JSEmitter::RegisterTemplate() : Registers a code template
- *
- * Note: this is used only by JAVASCRIPT::fragmentDirective().
- * ----------------------------------------------------------------------------- */
-
-int JSEmitter::registerTemplate(const String *name, const String *code) {
- if (!State::IsSet(state.globals(HAS_TEMPLATES))) {
- SetFlag(state.globals(), HAS_TEMPLATES);
- }
- return Setattr(templates, name, code);
-}
-
-/* -----------------------------------------------------------------------------
- * JSEmitter::getTemplate() : Provides a registered code template
- * ----------------------------------------------------------------------------- */
-
-Template JSEmitter::getTemplate(const String *name) {
- String *templ = Getattr(templates, name);
-
- if (!templ) {
- Printf(stderr, "Could not find template %s\n.", name);
- Exit(EXIT_FAILURE);
- }
-
- Template t(templ, name);
- return t;
-}
-
-JSEmitterState & JSEmitter::getState() {
- return state;
-}
-
-int JSEmitter::initialize(Node * /*n */ ) {
-
- if (namespaces != NULL) {
- Delete(namespaces);
- }
- namespaces = NewHash();
- Hash *global_namespace = createNamespaceEntry("exports", 0, 0);
-
- Setattr(namespaces, "::", global_namespace);
- current_namespace = global_namespace;
-
- f_wrappers = NewString("");
-
- return SWIG_OK;
-}
-
-/* ---------------------------------------------------------------------
- * skipIgnoredArgs()
- * --------------------------------------------------------------------- */
-
-Parm *JSEmitter::skipIgnoredArgs(Parm *p) {
- while (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- }
- return p;
-}
-
-/* -----------------------------------------------------------------------------
- * JSEmitter::getBaseClass() : the node of the base class or NULL
- *
- * Note: the first base class is provided. Multiple inheritance is not
- * supported.
- * ----------------------------------------------------------------------------- */
-
-Node *JSEmitter::getBaseClass(Node *n) {
- // retrieve the first base class that is not %ignored
- List *baselist = Getattr(n, "bases");
- if (baselist) {
- Iterator base = First(baselist);
- while (base.item && GetFlag(base.item, "feature:ignore")) {
- base = Next(base);
- }
- return base.item;
- }
- return NULL;
-}
-
- /* -----------------------------------------------------------------------------
- * JSEmitter::emitWrapperFunction() : dispatches emitter functions.
- *
- * This allows having small sized, dedicated emitting functions.
- * All state dependent branching is done here.
- * ----------------------------------------------------------------------------- */
-
-int JSEmitter::emitWrapperFunction(Node *n) {
- int ret = SWIG_OK;
-
- String *kind = Getattr(n, "kind");
-
- if (kind) {
-
- if (Equal(kind, "function")
- // HACK: sneaky.ctest revealed that typedef'd (global) functions must be
- // detected via the 'view' attribute.
- || (Equal(kind, "variable") && Equal(Getattr(n, "view"), "globalfunctionHandler"))
- ) {
- bool is_member = GetFlag(n, "ismember") != 0 || GetFlag(n, "feature:extend") != 0;
- bool is_static = GetFlag(state.function(), IS_STATIC) != 0;
- ret = emitFunction(n, is_member, is_static);
- } else if (Cmp(kind, "variable") == 0) {
- bool is_static = GetFlag(state.variable(), IS_STATIC) != 0;
- // HACK: smartpointeraccessed static variables are not treated as statics
- if (GetFlag(n, "allocate:smartpointeraccess")) {
- is_static = false;
- }
-
- bool is_member = GetFlag(n, "ismember") != 0;
- bool is_setter = GetFlag(n, "memberset") != 0 || GetFlag(n, "varset") != 0;
- bool is_getter = GetFlag(n, "memberget") != 0 || GetFlag(n, "varget") != 0;
- if (is_setter) {
- ret = emitSetter(n, is_member, is_static);
- } else if (is_getter) {
- ret = emitGetter(n, is_member, is_static);
- }
-
- } else {
- Printf(stderr, "Warning: unsupported wrapper function type\n");
- ret = SWIG_ERROR;
- }
- } else {
- String *view = Getattr(n, "view");
-
- if (Cmp(view, "constructorHandler") == 0) {
- ret = emitCtor(n);
- } else if (Cmp(view, "destructorHandler") == 0) {
- ret = emitDtor(n);
- } else {
- Printf(stderr, "Warning: unsupported wrapper function type");
- ret = SWIG_ERROR;
- }
- }
-
- return ret;
-}
-
-int JSEmitter::emitNativeFunction(Node *n) {
- String *wrapname = Getattr(n, "wrap:name");
- enterFunction(n);
- state.function(WRAPPER_NAME, wrapname);
- exitFunction(n);
- return SWIG_OK;
-}
-
-int JSEmitter::enterClass(Node *n) {
- state.clazz(RESET);
- state.clazz(NAME, Getattr(n, "sym:name"));
- state.clazz("nspace", current_namespace);
-
- // Creating a mangled name using the current namespace and the symbol name
- String *mangled_name = NewString("");
- Printf(mangled_name, "%s_%s", Getattr(current_namespace, NAME_MANGLED), Getattr(n, "sym:name"));
- state.clazz(NAME_MANGLED, SwigType_manglestr(mangled_name));
- Delete(mangled_name);
-
- state.clazz(TYPE, NewString(Getattr(n, "classtype")));
-
- String *type = SwigType_manglestr(Getattr(n, "classtypeobj"));
- String *classtype_mangled = NewString("");
- Printf(classtype_mangled, "p%s", type);
- state.clazz(TYPE_MANGLED, classtype_mangled);
- Delete(type);
-
- String *ctor_wrapper = NewString("_wrap_new_veto_");
- Append(ctor_wrapper, state.clazz(NAME));
- state.clazz(CTOR, ctor_wrapper);
- state.clazz(CTOR_DISPATCHERS, NewString(""));
- state.clazz(DTOR, NewString("0"));
-
- // HACK: assume that a class is abstract
- // this is resolved by emitCtor (which is only called for non abstract classes)
- SetFlag(state.clazz(), IS_ABSTRACT);
-
- return SWIG_OK;
-}
-
-int JSEmitter::enterFunction(Node *n) {
- state.function(RESET);
- state.function(NAME, Getattr(n, "sym:name"));
- if (Equal(Getattr(n, "storage"), "static")) {
- SetFlag(state.function(), IS_STATIC);
- }
- return SWIG_OK;
-}
-
-int JSEmitter::enterVariable(Node *n) {
- // reset the state information for variables.
- state.variable(RESET);
-
- // Retrieve a pure symbol name. Using 'sym:name' as a basis, as it considers %renamings.
- if (Equal(Getattr(n, "view"), "memberconstantHandler")) {
- // Note: this is kind of hacky/experimental
- // For constants/enums 'sym:name' contains e.g., 'Foo_Hello' instead of 'Hello'
- state.variable(NAME, Getattr(n, "memberconstantHandler:sym:name"));
- } else {
- state.variable(NAME, Swig_scopename_last(Getattr(n, "sym:name")));
- }
-
- if (Equal(Getattr(n, "storage"), "static")) {
- SetFlag(state.variable(), IS_STATIC);
- }
-
- if (!Language::instance()->is_assignable(n)) {
- SetFlag(state.variable(), IS_IMMUTABLE);
- }
- // FIXME: test "arrays_global" does not compile with that as it is not allowed to assign to char[]
- if (Equal(Getattr(n, "type"), "a().char")) {
- SetFlag(state.variable(), IS_IMMUTABLE);
- }
-
- return SWIG_OK;
-}
-
-int JSEmitter::emitCtor(Node *n) {
-
- Wrapper *wrapper = NewWrapper();
-
- bool is_overloaded = GetFlag(n, "sym:overloaded") != 0;
-
- Template t_ctor(getTemplate("js_ctor"));
-
- String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name"));
- if (is_overloaded) {
- t_ctor = getTemplate("js_overloaded_ctor");
- Append(wrap_name, Getattr(n, "sym:overname"));
- }
- Setattr(n, "wrap:name", wrap_name);
- // note: we can remove the is_abstract flag now, as this
- // is called for non-abstract classes only.
- Setattr(state.clazz(), IS_ABSTRACT, 0);
-
- ParmList *params = Getattr(n, "parms");
- emit_parameter_variables(params, wrapper);
- emit_attach_parmmaps(params, wrapper);
- // HACK: in test-case `ignore_parameter` emit_attach_parmmaps generated an extra line of applied typemaps.
- // Deleting wrapper->code here, to reset, and as it seemed to have no side effect elsewhere
- Delete(wrapper->code);
- wrapper->code = NewString("");
-
- Printf(wrapper->locals, "%sresult;", SwigType_str(Getattr(n, "type"), 0));
-
- marshalInputArgs(n, params, wrapper, Ctor, true, false);
- String *action = emit_action(n);
- Printv(wrapper->code, action, "\n", 0);
-
- emitCleanupCode(n, wrapper, params);
-
- t_ctor.replace("$jswrapper", wrap_name)
- .replace("$jsmangledtype", state.clazz(TYPE_MANGLED))
- .replace("$jslocals", wrapper->locals)
- .replace("$jscode", wrapper->code)
- .replace("$jsargcount", Getattr(n, ARGCOUNT))
- .pretty_print(f_wrappers);
-
- Template t_ctor_case(getTemplate("js_ctor_dispatch_case"));
- t_ctor_case.replace("$jswrapper", wrap_name)
- .replace("$jsargcount", Getattr(n, ARGCOUNT));
- Append(state.clazz(CTOR_DISPATCHERS), t_ctor_case.str());
-
- DelWrapper(wrapper);
-
- // create a dispatching ctor
- if (is_overloaded) {
- if (!Getattr(n, "sym:nextSibling")) {
- String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name"));
- Template t_mainctor(getTemplate("js_ctor_dispatcher"));
- t_mainctor.replace("$jswrapper", wrap_name)
- .replace("$jsmangledname", state.clazz(NAME_MANGLED))
- .replace("$jsdispatchcases", state.clazz(CTOR_DISPATCHERS))
- .pretty_print(f_wrappers);
- state.clazz(CTOR, wrap_name);
- }
- } else {
- state.clazz(CTOR, wrap_name);
- }
-
- return SWIG_OK;
-}
-
-int JSEmitter::emitDtor(Node *n) {
-
- String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name"));
-
- SwigType *type = state.clazz(TYPE);
- String *p_classtype = SwigType_add_pointer(state.clazz(TYPE));
- String *ctype = SwigType_lstr(p_classtype, "");
- String *jsfree = NewString("");
-
- // (Taken from JSCore implementation.)
- /* The if (Extend) block was taken from the Ruby implementation.
- * The problem is that in the case of an %extend to create a destructor for a struct to coordinate automatic memory cleanup with the Javascript collector,
- * the SWIG function was not being generated. More specifically:
- struct MyData {
- %extend {
- ~MyData() {
- FreeData($self);
- }
- }
- };
- %newobject CreateData;
- struct MyData* CreateData(void);
- %delobject FreeData;
- void FreeData(struct MyData* the_data);
-
- where the use case is something like:
- var my_data = example.CreateData();
- my_data = null;
-
- This function was not being generated:
- SWIGINTERN void delete_MyData(struct MyData *self){
- FreeData(self);
- }
-
- I don't understand fully why it wasn't being generated. It just seems to happen in the Lua generator.
- There is a comment about staticmemberfunctionHandler having an inconsistency and I tracked down dome of the SWIGINTERN void delete_*
- code to that function in the Language base class.
- The Ruby implementation seems to have an explicit check for if(Extend) and explicitly generates the code, so that's what I'm doing here.
- The Ruby implementation does other stuff which I omit.
- */
- if (Extend) {
- String *wrap = Getattr(n, "wrap:code");
- if (wrap) {
- Printv(f_wrappers, wrap, NIL);
- }
- }
- // HACK: this is only for the v8 emitter. maybe set an attribute wrap:action of node
- // TODO: generate dtors more similar to other wrappers
- // EW: I think this is wrong. delete should only be used when new was used to create. If malloc was used, free needs to be used.
- if (SwigType_isarray(type)) {
- Printf(jsfree, "delete [] (%s)", ctype);
- } else {
- Printf(jsfree, "delete (%s)", ctype);
- }
-
- String *destructor_action = Getattr(n, "wrap:action");
- // Adapted from the JSCore implementation.
- /* The next challenge is to generate the correct finalize function for JavaScriptCore to call.
- Originally, it would use this fragment from javascriptcode.swg
- %fragment ("JS_destructordefn", "templates")
- %{
- void _wrap_${classname_mangled}_finalize(JSObjectRef thisObject)
- {
- SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject);
- if(t && t->swigCMemOwn) free ((${type}*)t->swigCObject);
- free(t);
- }
- %}
-
- But for the above example case of %extend to define a destructor on a struct, we need to override the system to not call
- free ((${type}*)t->swigCObject);
- and substitute it with what the user has provided.
- To solve this, I created a variation fragment called JS_destructoroverridedefn:
- SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject);
- if(t && t->swigCMemOwn) {
- ${type}* arg1 = (${type}*)t->swigCObject;
- ${destructor_action}
- }
- free(t);
-
- Based on what I saw in the Lua and Ruby modules, I use Getattr(n, "wrap:action")
- to decide if the user has a preferred destructor action.
- Based on that, I decide which fragment to use.
- And in the case of the custom action, I substitute that action in.
- I noticed that destructor_action has the form
- delete_MyData(arg1);
- The explicit arg1 is a little funny, so I structured the fragment to create a temporary variable called arg1 to make the generation easier.
- This might suggest this solution misunderstands a more complex case.
-
- Also, there is a problem where destructor_action is always true for me, even when not requesting %extend as above.
- So this code doesn't actually quite work as I expect. The end result is that the code still works because
- destructor_action calls free like the original template. The one caveat is the string in destructor_action casts to char* which is weird.
- I think there is a deeper underlying SWIG issue because I don't think it should be char*. However, it doesn't really matter for free.
-
- Maybe the fix for the destructor_action always true problem is that this is supposed to be embedded in the if(Extend) block above.
- But I don't fully understand the conditions of any of these things, and since it works for the moment, I don't want to break more stuff.
- */
- if (destructor_action) {
- Template t_dtor = getTemplate("js_dtoroverride");
- state.clazz(DTOR, wrap_name);
- t_dtor.replace("${classname_mangled}", state.clazz(NAME_MANGLED))
- .replace("$jswrapper", wrap_name)
- .replace("$jsfree", jsfree)
- .replace("$jstype", ctype);
-
- t_dtor.replace("${destructor_action}", destructor_action);
- Wrapper_pretty_print(t_dtor.str(), f_wrappers);
- } else {
- Template t_dtor = getTemplate("js_dtor");
- state.clazz(DTOR, wrap_name);
- t_dtor.replace("$jsmangledname", state.clazz(NAME_MANGLED))
- .replace("$jswrapper", wrap_name)
- .replace("$jsfree", jsfree)
- .replace("$jstype", ctype)
- .pretty_print(f_wrappers);
- }
-
- Delete(p_classtype);
- Delete(ctype);
- Delete(jsfree);
-
- return SWIG_OK;
-}
-
-int JSEmitter::emitGetter(Node *n, bool is_member, bool is_static) {
- Wrapper *wrapper = NewWrapper();
- Template t_getter(getTemplate("js_getter"));
-
- // prepare wrapper name
- String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name"));
- Setattr(n, "wrap:name", wrap_name);
- state.variable(GETTER, wrap_name);
-
- // prepare local variables
- ParmList *params = Getattr(n, "parms");
- emit_parameter_variables(params, wrapper);
- emit_attach_parmmaps(params, wrapper);
-
- // prepare code part
- String *action = emit_action(n);
- marshalInputArgs(n, params, wrapper, Getter, is_member, is_static);
- marshalOutput(n, params, wrapper, action);
-
- emitCleanupCode(n, wrapper, params);
-
- t_getter.replace("$jswrapper", wrap_name)
- .replace("$jslocals", wrapper->locals)
- .replace("$jscode", wrapper->code)
- .pretty_print(f_wrappers);
-
- DelWrapper(wrapper);
-
- return SWIG_OK;
-}
-
-int JSEmitter::emitSetter(Node *n, bool is_member, bool is_static) {
-
- // skip variables that are immutable
- if (State::IsSet(state.variable(IS_IMMUTABLE))) {
- return SWIG_OK;
- }
-
- Wrapper *wrapper = NewWrapper();
-
- Template t_setter(getTemplate("js_setter"));
-
- // prepare wrapper name
- String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name"));
- Setattr(n, "wrap:name", wrap_name);
- state.variable(SETTER, wrap_name);
-
- // prepare local variables
- ParmList *params = Getattr(n, "parms");
- emit_parameter_variables(params, wrapper);
- emit_attach_parmmaps(params, wrapper);
-
- // prepare code part
- String *action = emit_action(n);
- marshalInputArgs(n, params, wrapper, Setter, is_member, is_static);
- Append(wrapper->code, action);
-
- emitCleanupCode(n, wrapper, params);
-
- t_setter.replace("$jswrapper", wrap_name)
- .replace("$jslocals", wrapper->locals)
- .replace("$jscode", wrapper->code)
- .pretty_print(f_wrappers);
-
- DelWrapper(wrapper);
-
- return SWIG_OK;
-}
-
-/* -----------------------------------------------------------------------------
- * JSEmitter::emitConstant() : triggers code generation for constants
- * ----------------------------------------------------------------------------- */
-
-int JSEmitter::emitConstant(Node *n) {
- // HACK: somehow it happened under Mac OS X that before everything started
- // a lot of SWIG internal constants were emitted
- // This didn't happen on other platforms yet...
- // we ignore those premature definitions
- if (!State::IsSet(state.globals(HAS_TEMPLATES))) {
- return SWIG_ERROR;
- }
-
- Wrapper *wrapper = NewWrapper();
- SwigType *type = Getattr(n, "type");
- String *name = Getattr(n, "name");
- String *iname = Getattr(n, "sym:name");
- String *wname = Swig_name_wrapper(name);
- String *rawval = Getattr(n, "rawval");
- String *value = rawval ? rawval : Getattr(n, "value");
-
- // HACK: forcing usage of cppvalue for v8 (which turned out to fix typedef_struct.i, et. al)
- if (State::IsSet(state.globals(FORCE_CPP)) && Getattr(n, "cppvalue") != NULL) {
- value = Getattr(n, "cppvalue");
- }
-
- Template t_getter(getTemplate("js_getter"));
-
- // call the variable methods as a constants are
- // registered in same way
- enterVariable(n);
- state.variable(GETTER, wname);
- // TODO: why do we need this?
- Setattr(n, "wrap:name", wname);
-
- // special treatment of member pointers
- if (SwigType_type(type) == T_MPOINTER) {
- // TODO: this could go into a code-template
- String *mpointer_wname = NewString("");
- Printf(mpointer_wname, "_wrapConstant_%s", iname);
- Setattr(n, "memberpointer:constant:wrap:name", mpointer_wname);
- String *str = SwigType_str(type, mpointer_wname);
- Printf(f_wrappers, "static %s = %s;\n", str, value);
- Delete(str);
- value = mpointer_wname;
- }
-
- marshalOutput(n, 0, wrapper, NewString(""), value, false);
-
- t_getter.replace("$jswrapper", wname)
- .replace("$jslocals", wrapper->locals)
- .replace("$jscode", wrapper->code)
- .pretty_print(f_wrappers);
-
- exitVariable(n);
-
- DelWrapper(wrapper);
-
- return SWIG_OK;
-}
-
-int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) {
- Wrapper *wrapper = NewWrapper();
- Template t_function(getTemplate("js_function"));
-
- bool is_overloaded = GetFlag(n, "sym:overloaded") != 0;
-
- // prepare the function wrapper name
- String *iname = Getattr(n, "sym:name");
- String *wrap_name = Swig_name_wrapper(iname);
- if (is_overloaded) {
- t_function = getTemplate("js_overloaded_function");
- Append(wrap_name, Getattr(n, "sym:overname"));
- }
- Setattr(n, "wrap:name", wrap_name);
- state.function(WRAPPER_NAME, wrap_name);
-
- // prepare local variables
- ParmList *params = Getattr(n, "parms");
- emit_parameter_variables(params, wrapper);
- emit_attach_parmmaps(params, wrapper);
-
- // HACK: in test-case `ignore_parameter` emit_attach_parmmaps generates an extra line of applied typemap.
- // Deleting wrapper->code here fixes the problem, and seems to have no side effect elsewhere
- Delete(wrapper->code);
- wrapper->code = NewString("");
-
- marshalInputArgs(n, params, wrapper, Function, is_member, is_static);
- String *action = emit_action(n);
- marshalOutput(n, params, wrapper, action);
- emitCleanupCode(n, wrapper, params);
- Replaceall(wrapper->code, "$symname", iname);
-
- t_function.replace("$jswrapper", wrap_name)
- .replace("$jslocals", wrapper->locals)
- .replace("$jscode", wrapper->code)
- .replace("$jsargcount", Getattr(n, ARGCOUNT))
- .pretty_print(f_wrappers);
-
-
- DelWrapper(wrapper);
-
- return SWIG_OK;
-}
-
-int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) {
- Wrapper *wrapper = NewWrapper();
-
- // Generate call list, go to first node
- Node *sibl = n;
-
- while (Getattr(sibl, "sym:previousSibling"))
- sibl = Getattr(sibl, "sym:previousSibling"); // go all the way up
-
- do {
- String *siblname = Getattr(sibl, "wrap:name");
-
- if (siblname) {
- // handle function overloading
- Template t_dispatch_case = getTemplate("js_function_dispatch_case");
- t_dispatch_case.replace("$jswrapper", siblname)
- .replace("$jsargcount", Getattr(sibl, ARGCOUNT));
-
- Append(wrapper->code, t_dispatch_case.str());
- }
-
- } while ((sibl = Getattr(sibl, "sym:nextSibling")));
-
- Template t_function(getTemplate("js_function_dispatcher"));
-
- // Note: this dispatcher function gets called after the last overloaded function has been created.
- // At this time, n.wrap:name contains the name of the last wrapper function.
- // To get a valid function name for the dispatcher function we take the last wrapper name and
- // subtract the extension "sym:overname",
- String *wrap_name = NewString(Getattr(n, "wrap:name"));
- String *overname = Getattr(n, "sym:overname");
-
- Node *methodclass = Swig_methodclass(n);
- String *class_name = Getattr(methodclass, "sym:name");
-
- int l1 = Len(wrap_name);
- int l2 = Len(overname);
- Delslice(wrap_name, l1 - l2, l1);
-
- String *new_string = NewStringf("%s_%s", class_name, wrap_name);
- String *final_wrap_name = Swig_name_wrapper(new_string);
-
- Setattr(n, "wrap:name", final_wrap_name);
- state.function(WRAPPER_NAME, final_wrap_name);
-
-
-
- t_function.replace("$jslocals", wrapper->locals)
- .replace("$jscode", wrapper->code);
-
- // call this here, to replace all variables
- t_function.replace("$jswrapper", final_wrap_name)
- .replace("$jsname", state.function(NAME))
- .pretty_print(f_wrappers);
-
- // Delete the state variable
- DelWrapper(wrapper);
-
- return SWIG_OK;
-}
-
-String *JSEmitter::emitInputTypemap(Node *n, Parm *p, Wrapper *wrapper, String *arg) {
- // Get input typemap for current param
- String *tm = Getattr(p, "tmap:in");
- SwigType *type = Getattr(p, "type");
-
- if (tm != NULL) {
- Replaceall(tm, "$input", arg);
- Setattr(p, "emit:input", arg);
- // do replacements for built-in variables
- if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
- Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
- } else {
- Replaceall(tm, "$disown", "0");
- }
- Replaceall(tm, "$symname", Getattr(n, "sym:name"));
- Printf(wrapper->code, "%s\n", tm);
- } else {
- Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(type, 0));
- }
-
- return tm;
-}
-
-void JSEmitter::marshalOutput(Node *n, ParmList *params, Wrapper *wrapper, String *actioncode, const String *cresult, bool emitReturnVariable) {
- SwigType *type = Getattr(n, "type");
- String *tm;
- Parm *p;
-
- // adds a declaration for the result variable
- if (emitReturnVariable)
- emit_return_variable(n, type, wrapper);
- // if not given, use default result identifier ('result') for output typemap
- if (cresult == 0)
- cresult = defaultResultName;
-
- tm = Swig_typemap_lookup_out("out", n, cresult, wrapper, actioncode);
- bool should_own = GetFlag(n, "feature:new") != 0;
-
- if (tm) {
- Replaceall(tm, "$objecttype", Swig_scopename_last(SwigType_str(SwigType_strip_qualifiers(type), 0)));
-
- if (should_own) {
- Replaceall(tm, "$owner", "SWIG_POINTER_OWN");
- } else {
- Replaceall(tm, "$owner", "0");
- }
- Append(wrapper->code, tm);
-
- if (Len(tm) > 0) {
- Printf(wrapper->code, "\n");
- }
- } else {
- Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(type, 0), Getattr(n, "name"));
- }
-
- if (params) {
- for (p = params; p;) {
- if ((tm = Getattr(p, "tmap:argout"))) {
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(wrapper->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:argout:next");
- } else {
- p = nextSibling(p);
- }
- }
- }
-
- Replaceall(wrapper->code, "$result", "jsresult");
-}
-
-void JSEmitter::emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params) {
- Parm *p;
- String *tm;
-
- for (p = params; p;) {
- if ((tm = Getattr(p, "tmap:freearg"))) {
- //addThrows(n, "tmap:freearg", p);
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(wrapper->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:freearg:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- if (GetFlag(n, "feature:new")) {
- tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0);
- if (tm != NIL) {
- //addThrows(throws_hash, "newfree", n);
- Printv(wrapper->code, tm, "\n", NIL);
- }
- }
-
- /* See if there is any return cleanup code */
- if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
- Printf(wrapper->code, "%s\n", tm);
- Delete(tm);
- }
-}
-
-int JSEmitter::switchNamespace(Node *n) {
- // HACK: somehow this gets called for member functions.
- // We can safely ignore them, as members are not associated to a namespace (only their class)
- if (GetFlag(n, "ismember")) {
- return SWIG_OK;
- }
-
- // if nspace is deactivated, everything goes into the global scope
- if (!GetFlag(n, "feature:nspace")) {
- current_namespace = Getattr(namespaces, "::");
- return SWIG_OK;
- }
-
-// EXPERIMENTAL: we want to use Language::getNSpace() here
-// However, it is not working yet.
-// For namespace functions Language::getNSpace() does not give a valid result
-#if 0
- JAVASCRIPT *lang = static_cast<JAVASCRIPT*>(Language::instance());
- String *_nspace = lang->getNSpace();
- if (!Equal(nspace, _nspace)) {
- Printf(stdout, "##### Custom vs Language::getNSpace(): %s | %s\n", nspace, _nspace);
- }
-#endif
-
- String *nspace = Getattr(n, "sym:nspace");
-
- if (nspace == NULL) {
- // It seems that only classes have 'sym:nspace' set.
- // We try to get the namespace from the qualified name (i.e., everything before the last '::')
- nspace = Swig_scopename_prefix(Getattr(n, "name"));
- }
-
- // If there is not even a scopename prefix then it must be global scope
- if (nspace == NULL) {
- current_namespace = Getattr(namespaces, "::");
- return SWIG_OK;
- }
-
- String *scope = NewString(nspace);
- // replace "." with "::" that we can use Swig_scopename_last
- Replaceall(scope, ".", "::");
-
- // if the scope is not yet registered
- // create (parent) namespaces recursively
- if (!Getattr(namespaces, scope)) {
- createNamespace(scope);
- }
- current_namespace = Getattr(namespaces, scope);
-
- return SWIG_OK;
-}
-
-int JSEmitter::createNamespace(String *scope) {
-
- String *parent_scope = Swig_scopename_prefix(scope);
- Hash *parent_namespace;
- if (parent_scope == 0) {
- parent_namespace = Getattr(namespaces, "::");
- } else if (!Getattr(namespaces, parent_scope)) {
- createNamespace(parent_scope);
- parent_namespace = Getattr(namespaces, parent_scope);
- } else {
- parent_namespace = Getattr(namespaces, parent_scope);
- }
- assert(parent_namespace != 0);
-
- Hash *new_namespace = createNamespaceEntry(Char(scope), Char(Getattr(parent_namespace, "name")), Char(Getattr(parent_namespace, "name_mangled")));
- Setattr(namespaces, scope, new_namespace);
-
- Delete(parent_scope);
- return SWIG_OK;
-}
-
-Hash *JSEmitter::createNamespaceEntry(const char *_name, const char *parent, const char *parent_mangled) {
- Hash *entry = NewHash();
- String *name = NewString(_name);
- Setattr(entry, NAME, Swig_scopename_last(name));
- Setattr(entry, NAME_MANGLED, Swig_name_mangle(name));
- Setattr(entry, PARENT, NewString(parent));
- Setattr(entry, PARENT_MANGLED, NewString(parent_mangled));
-
- Delete(name);
- return entry;
-}
-
-/**********************************************************************
- * JavascriptCore: JSEmitter implementation for JavascriptCore engine
- **********************************************************************/
-
-class JSCEmitter:public JSEmitter {
-
-public:
- JSCEmitter();
- virtual ~ JSCEmitter();
- virtual int initialize(Node *n);
- virtual int dump(Node *n);
- virtual int close();
-
-protected:
- virtual int enterVariable(Node *n);
- virtual int exitVariable(Node *n);
- virtual int enterFunction(Node *n);
- virtual int exitFunction(Node *n);
- virtual int enterClass(Node *n);
- virtual int exitClass(Node *n);
- virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static);
- virtual Hash *createNamespaceEntry(const char *name, const char *parent, const char *parent_mangled);
- virtual int emitNamespaces();
-
-private:
-
- String *NULL_STR;
- String *VETO_SET;
-
- // output file and major code parts
- File *f_wrap_cpp;
- File *f_runtime;
- File *f_header;
- File *f_init;
-
-};
-
-JSCEmitter::JSCEmitter()
-: JSEmitter(JSEmitter::JavascriptCore), NULL_STR(NewString("NULL")), VETO_SET(NewString("JS_veto_set_variable")), f_wrap_cpp(NULL), f_runtime(NULL), f_header(NULL), f_init(NULL) {
-}
-
-JSCEmitter::~JSCEmitter() {
- Delete(NULL_STR);
- Delete(VETO_SET);
-}
-
-
-/* ---------------------------------------------------------------------
- * marshalInputArgs()
- *
- * Process all of the arguments passed into the argv array
- * and convert them into C/C++ function arguments using the
- * supplied typemaps.
- * --------------------------------------------------------------------- */
-
-void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) {
- Parm *p;
- String *tm;
-
- // determine an offset index, as members have an extra 'this' argument
- // except: static members and ctors.
- int startIdx = 0;
- if (is_member && !is_static && mode != Ctor) {
- startIdx = 1;
- }
- // store number of arguments for argument checks
- int num_args = emit_num_arguments(parms) - startIdx;
- String *argcount = NewString("");
- Printf(argcount, "%d", num_args);
- Setattr(n, ARGCOUNT, argcount);
-
- // process arguments
- int i = 0;
- for (p = parms; p; i++) {
- String *arg = NewString("");
- String *type = Getattr(p, "type");
-
- // ignore varargs
- if (SwigType_isvarargs(type))
- break;
-
- switch (mode) {
- case Getter:
- case Function:
- if (is_member && !is_static && i == 0) {
- Printv(arg, "thisObject", 0);
- } else {
- Printf(arg, "argv[%d]", i - startIdx);
- }
- break;
- case Setter:
- if (is_member && !is_static && i == 0) {
- Printv(arg, "thisObject", 0);
- } else {
- Printv(arg, "value", 0);
- }
- break;
- case Ctor:
- Printf(arg, "argv[%d]", i);
- break;
- default:
- Printf(stderr, "Illegal MarshallingMode.");
- Exit(EXIT_FAILURE);
- }
- tm = emitInputTypemap(n, p, wrapper, arg);
- Delete(arg);
- if (tm) {
- p = Getattr(p, "tmap:in:next");
- } else {
- p = nextSibling(p);
- }
- }
-}
-
-int JSCEmitter::initialize(Node *n) {
-
- JSEmitter::initialize(n);
-
- /* Get the output file name */
- String *outfile = Getattr(n, "outfile");
-
- /* Initialize I/O */
- f_wrap_cpp = NewFile(outfile, "w", SWIG_output_files());
- if (!f_wrap_cpp) {
- FileErrorDisplay(outfile);
- Exit(EXIT_FAILURE);
- }
-
- /* Initialization of members */
- f_runtime = NewString("");
- f_init = NewString("");
- f_header = NewString("");
-
- state.globals(CREATE_NAMESPACES, NewString(""));
- state.globals(REGISTER_NAMESPACES, NewString(""));
- state.globals(INITIALIZER, NewString(""));
-
- /* Register file targets with the SWIG file handler */
- Swig_register_filebyname("begin", f_wrap_cpp);
- Swig_register_filebyname("header", f_header);
- Swig_register_filebyname("wrapper", f_wrappers);
- Swig_register_filebyname("runtime", f_runtime);
- Swig_register_filebyname("init", f_init);
-
- Swig_banner(f_wrap_cpp);
-
- Swig_obligatory_macros(f_runtime, "JAVASCRIPT");
-
- return SWIG_OK;
-}
-
-int JSCEmitter::dump(Node *n) {
- /* Get the module name */
- String *module = Getattr(n, "name");
-
- Template initializer_define(getTemplate("js_initializer_define"));
- initializer_define.replace("$jsname", module).pretty_print(f_header);
-
- SwigType_emit_type_table(f_runtime, f_wrappers);
-
- Printv(f_wrap_cpp, f_runtime, "\n", 0);
- Printv(f_wrap_cpp, f_header, "\n", 0);
- Printv(f_wrap_cpp, f_wrappers, "\n", 0);
-
- emitNamespaces();
-
- // compose the initializer function using a template
- Template initializer(getTemplate("js_initializer"));
- initializer.replace("$jsname", module)
- .replace("$jsregisterclasses", state.globals(INITIALIZER))
- .replace("$jscreatenamespaces", state.globals(CREATE_NAMESPACES))
- .replace("$jsregisternamespaces", state.globals(REGISTER_NAMESPACES))
- .pretty_print(f_init);
-
- Printv(f_wrap_cpp, f_init, 0);
-
- return SWIG_OK;
-}
-
-int JSCEmitter::close() {
- Delete(f_runtime);
- Delete(f_header);
- Delete(f_wrappers);
- Delete(f_init);
- Delete(namespaces);
- Delete(f_wrap_cpp);
- return SWIG_OK;
-}
-
-int JSCEmitter::enterFunction(Node *n) {
-
- JSEmitter::enterFunction(n);
-
- return SWIG_OK;
-}
-
-int JSCEmitter::exitFunction(Node *n) {
- Template t_function = getTemplate("jsc_function_declaration");
-
- bool is_member = GetFlag(n, "ismember") != 0 || GetFlag(n, "feature:extend") != 0;
- bool is_overloaded = GetFlag(n, "sym:overloaded") != 0;
-
- // handle overloaded functions
- if (is_overloaded) {
- if (!Getattr(n, "sym:nextSibling")) {
- //state.function(WRAPPER_NAME, Swig_name_wrapper(Getattr(n, "name")));
- // create dispatcher
- emitFunctionDispatcher(n, is_member);
- } else {
- //don't register wrappers of overloaded functions in function tables
- return SWIG_OK;
- }
- }
-
- t_function.replace("$jsname", state.function(NAME))
- .replace("$jswrapper", state.function(WRAPPER_NAME));
-
- if (is_member) {
- if (GetFlag(state.function(), IS_STATIC)) {
- t_function.pretty_print(state.clazz(STATIC_FUNCTIONS));
- } else {
- t_function.pretty_print(state.clazz(MEMBER_FUNCTIONS));
- }
- } else {
- t_function.pretty_print(Getattr(current_namespace, "functions"));
- }
-
- return SWIG_OK;
-}
-
-int JSCEmitter::enterVariable(Node *n) {
- JSEmitter::enterVariable(n);
- state.variable(GETTER, NULL_STR);
- state.variable(SETTER, VETO_SET);
- return SWIG_OK;
-}
-
-int JSCEmitter::exitVariable(Node *n) {
- Template t_variable(getTemplate("jsc_variable_declaration"));
- t_variable.replace("$jsname", state.variable(NAME))
- .replace("$jsgetter", state.variable(GETTER))
- .replace("$jssetter", state.variable(SETTER));
-
- if (GetFlag(n, "ismember")) {
- if (GetFlag(state.variable(), IS_STATIC)
- || Equal(Getattr(n, "nodeType"), "enumitem")) {
- t_variable.pretty_print(state.clazz(STATIC_VARIABLES));
- } else {
- t_variable.pretty_print(state.clazz(MEMBER_VARIABLES));
- }
- } else {
- t_variable.pretty_print(Getattr(current_namespace, "values"));
- }
-
- return SWIG_OK;
-}
-
-int JSCEmitter::enterClass(Node *n) {
- JSEmitter::enterClass(n);
- state.clazz(MEMBER_VARIABLES, NewString(""));
- state.clazz(MEMBER_FUNCTIONS, NewString(""));
- state.clazz(STATIC_VARIABLES, NewString(""));
- state.clazz(STATIC_FUNCTIONS, NewString(""));
-
- Template t_class_decl = getTemplate("jsc_class_declaration");
- t_class_decl.replace("$jsmangledname", state.clazz(NAME_MANGLED))
- .pretty_print(f_wrappers);
-
- return SWIG_OK;
-}
-
-int JSCEmitter::exitClass(Node *n) {
- Template t_class_tables(getTemplate("jsc_class_tables"));
- t_class_tables.replace("$jsmangledname", state.clazz(NAME_MANGLED))
- .replace("$jsclassvariables", state.clazz(MEMBER_VARIABLES))
- .replace("$jsclassfunctions", state.clazz(MEMBER_FUNCTIONS))
- .replace("$jsstaticclassfunctions", state.clazz(STATIC_FUNCTIONS))
- .replace("$jsstaticclassvariables", state.clazz(STATIC_VARIABLES))
- .pretty_print(f_wrappers);
-
- /* adds the ctor wrappers at this position */
- // Note: this is necessary to avoid extra forward declarations.
- //Append(f_wrappers, state.clazz(CTOR_WRAPPERS));
-
- // for abstract classes add a vetoing ctor
- if (GetFlag(state.clazz(), IS_ABSTRACT)) {
- Template t_veto_ctor(getTemplate("js_veto_ctor"));
- t_veto_ctor.replace("$jswrapper", state.clazz(CTOR))
- .replace("$jsname", state.clazz(NAME))
- .pretty_print(f_wrappers);
- }
-
- /* adds a class template statement to initializer function */
- Template t_classtemplate(getTemplate("jsc_class_definition"));
-
- /* prepare registration of base class */
- String *jsclass_inheritance = NewString("");
- Node *base_class = getBaseClass(n);
- if (base_class != NULL) {
- Template t_inherit(getTemplate("jsc_class_inherit"));
- t_inherit.replace("$jsmangledname", state.clazz(NAME_MANGLED))
- .replace("$jsbaseclassmangled", SwigType_manglestr(Getattr(base_class, "name")))
- .pretty_print(jsclass_inheritance);
- } else {
- Template t_inherit(getTemplate("jsc_class_noinherit"));
- t_inherit.replace("$jsmangledname", state.clazz(NAME_MANGLED))
- .pretty_print(jsclass_inheritance);
- }
-
- t_classtemplate.replace("$jsmangledname", state.clazz(NAME_MANGLED))
- .replace("$jsmangledtype", state.clazz(TYPE_MANGLED))
- .replace("$jsclass_inheritance", jsclass_inheritance)
- .replace("$jsctor", state.clazz(CTOR))
- .replace("$jsdtor", state.clazz(DTOR))
- .pretty_print(state.globals(INITIALIZER));
- Delete(jsclass_inheritance);
-
- /* Note: this makes sure that there is a swig_type added for this class */
- SwigType_remember_clientdata(state.clazz(TYPE_MANGLED), NewString("0"));
-
- /* adds a class registration statement to initializer function */
- Template t_registerclass(getTemplate("jsc_class_registration"));
- t_registerclass.replace("$jsname", state.clazz(NAME))
- .replace("$jsmangledname", state.clazz(NAME_MANGLED))
- .replace("$jsnspace", Getattr(state.clazz("nspace"), NAME_MANGLED))
- .pretty_print(state.globals(INITIALIZER));
-
- return SWIG_OK;
-}
-
-Hash *JSCEmitter::createNamespaceEntry(const char *name, const char *parent, const char *parent_mangled) {
- Hash *entry = JSEmitter::createNamespaceEntry(name, parent, parent_mangled);
- Setattr(entry, "functions", NewString(""));
- Setattr(entry, "values", NewString(""));
- return entry;
-}
-
-int JSCEmitter::emitNamespaces() {
- Iterator it;
- for (it = First(namespaces); it.item; it = Next(it)) {
- Hash *entry = it.item;
- String *name = Getattr(entry, NAME);
- String *name_mangled = Getattr(entry, NAME_MANGLED);
- String *parent_mangled = Getattr(entry, PARENT_MANGLED);
- String *functions = Getattr(entry, "functions");
- String *variables = Getattr(entry, "values");
-
- // skip the global namespace which is given by the application
-
- Template namespace_definition(getTemplate("jsc_nspace_declaration"));
- namespace_definition.replace("$jsglobalvariables", variables)
- .replace("$jsglobalfunctions", functions)
- .replace("$jsnspace", name_mangled)
- .replace("$jsmangledname", name_mangled)
- .pretty_print(f_wrap_cpp);
-
- Template t_createNamespace(getTemplate("jsc_nspace_definition"));
- t_createNamespace.replace("$jsmangledname", name_mangled);
- Append(state.globals(CREATE_NAMESPACES), t_createNamespace.str());
-
- // Don't register 'exports' as namespace. It is return to the application.
- if (!Equal("exports", name)) {
- Template t_registerNamespace(getTemplate("jsc_nspace_registration"));
- t_registerNamespace.replace("$jsmangledname", name_mangled)
- .replace("$jsname", name)
- .replace("$jsparent", parent_mangled);
- Append(state.globals(REGISTER_NAMESPACES), t_registerNamespace.str());
- }
- }
-
- return SWIG_OK;
-}
-
-JSEmitter *swig_javascript_create_JSCEmitter() {
- return new JSCEmitter();
-}
-
-/**********************************************************************
- * V8: JSEmitter implementation for V8 engine
- **********************************************************************/
-
-class V8Emitter:public JSEmitter {
-
-public:
- V8Emitter();
-
- virtual ~ V8Emitter();
- virtual int initialize(Node *n);
- virtual int dump(Node *n);
- virtual int close();
- virtual int enterClass(Node *n);
- virtual int exitClass(Node *n);
- virtual int enterVariable(Node *n);
- virtual int exitVariable(Node *n);
- virtual int exitFunction(Node *n);
-
-protected:
- virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static);
- virtual int emitNamespaces();
-
-protected:
- /* built-in parts */
- String *f_runtime;
- String *f_header;
- String *f_init;
- String *f_post_init;
-
- /* part for class templates */
- String *f_class_templates;
-
- /* parts for initilizer */
- String *f_init_namespaces;
- String *f_init_class_templates;
- String *f_init_wrappers;
- String *f_init_inheritance;
- String *f_init_class_instances;
- String *f_init_static_wrappers;
- String *f_init_register_classes;
- String *f_init_register_namespaces;
-
- // the output cpp file
- File *f_wrap_cpp;
-
- String *NULL_STR;
- String *VETO_SET;
- String *moduleName;
-
-};
-
-V8Emitter::V8Emitter()
-: JSEmitter(JSEmitter::V8), NULL_STR(NewString("0")), VETO_SET(NewString("JS_veto_set_variable")) {
-}
-
-V8Emitter::~V8Emitter() {
- Delete(NULL_STR);
- Delete(VETO_SET);
-}
-
-int V8Emitter::initialize(Node *n) {
- JSEmitter::initialize(n);
-
- moduleName = Getattr(n, "name");
-
- // Get the output file name
- String *outfile = Getattr(n, "outfile");
- f_wrap_cpp = NewFile(outfile, "w", SWIG_output_files());
- if (!f_wrap_cpp) {
- FileErrorDisplay(outfile);
- Exit(EXIT_FAILURE);
- }
-
- f_runtime = NewString("");
- f_header = NewString("");
- f_class_templates = NewString("");
- f_init = NewString("");
- f_post_init = NewString("");
-
- f_init_namespaces = NewString("");
- f_init_class_templates = NewString("");
- f_init_wrappers = NewString("");
- f_init_inheritance = NewString("");
- f_init_class_instances = NewString("");
- f_init_static_wrappers = NewString("");
- f_init_register_classes = NewString("");
- f_init_register_namespaces = NewString("");
-
- // note: this is necessary for built-in generation of SWIG runtime code
- Swig_register_filebyname("begin", f_wrap_cpp);
- Swig_register_filebyname("runtime", f_runtime);
- Swig_register_filebyname("header", f_header);
- Swig_register_filebyname("wrapper", f_wrappers);
- Swig_register_filebyname("init", f_init);
- Swig_register_filebyname("post-init", f_post_init);
-
- state.globals(FORCE_CPP, NewString("1"));
-
- Swig_banner(f_wrap_cpp);
-
- Swig_obligatory_macros(f_runtime, "JAVASCRIPT");
-
- return SWIG_OK;
-}
-
-int V8Emitter::dump(Node *n) {
- /* Get the module name */
- String *module = Getattr(n, "name");
-
- Template initializer_define(getTemplate("js_initializer_define"));
- initializer_define.replace("$jsname", module).pretty_print(f_header);
-
- SwigType_emit_type_table(f_runtime, f_wrappers);
-
- Printv(f_wrap_cpp, f_runtime, "\n", 0);
- Printv(f_wrap_cpp, f_header, "\n", 0);
- Printv(f_wrap_cpp, f_class_templates, "\n", 0);
- Printv(f_wrap_cpp, f_wrappers, "\n", 0);
-
- emitNamespaces();
-
- // compose the initializer function using a template
- // filled with sub-parts
- Template initializer(getTemplate("js_initializer"));
- initializer.replace("$jsname", moduleName)
- .replace("$jsv8nspaces", f_init_namespaces)
- .replace("$jsv8classtemplates", f_init_class_templates)
- .replace("$jsv8wrappers", f_init_wrappers)
- .replace("$jsv8inheritance", f_init_inheritance)
- .replace("$jsv8classinstances", f_init_class_instances)
- .replace("$jsv8staticwrappers", f_init_static_wrappers)
- .replace("$jsv8registerclasses", f_init_register_classes)
- .replace("$jsv8registernspaces", f_init_register_namespaces);
- Printv(f_init, initializer.str(), 0);
-
- Printv(f_wrap_cpp, f_init, 0);
-
- Printv(f_wrap_cpp, f_post_init, 0);
-
- return SWIG_OK;
-}
-
-int V8Emitter::close() {
- Delete(f_runtime);
- Delete(f_header);
- Delete(f_class_templates);
- Delete(f_init_namespaces);
- Delete(f_init_class_templates);
- Delete(f_init_wrappers);
- Delete(f_init_inheritance);
- Delete(f_init_class_instances);
- Delete(f_init_static_wrappers);
- Delete(f_init_register_classes);
- Delete(f_init_register_namespaces);
- Delete(f_init);
- Delete(f_post_init);
- Delete(f_wrap_cpp);
- return SWIG_OK;
-}
-
-int V8Emitter::enterClass(Node *n) {
- JSEmitter::enterClass(n);
-
- // emit declaration of a v8 class template
- Template t_decl_class(getTemplate("jsv8_declare_class_template"));
- t_decl_class.replace("$jsmangledname", state.clazz(NAME_MANGLED))
- .trim()
- .pretty_print(f_class_templates);
-
- return SWIG_OK;
-}
-
-int V8Emitter::exitClass(Node *n) {
- if (GetFlag(state.clazz(), IS_ABSTRACT)) {
- Template t_veto_ctor(getTemplate("js_veto_ctor"));
- t_veto_ctor.replace("$jswrapper", state.clazz(CTOR))
- .replace("$jsname", state.clazz(NAME))
- .pretty_print(f_wrappers);
- }
-
- /* Note: this makes sure that there is a swig_type added for this class */
- String *clientData = NewString("");
- Printf(clientData, "&%s_clientData", state.clazz(NAME_MANGLED));
-
- /* Note: this makes sure that there is a swig_type added for this class */
- SwigType_remember_clientdata(state.clazz(TYPE_MANGLED), NewString("0"));
-
- // emit definition of v8 class template
- Template t_def_class = getTemplate("jsv8_define_class_template");
- t_def_class.replace("$jsmangledname", state.clazz(NAME_MANGLED))
- .replace("$jsname", state.clazz(NAME))
- .replace("$jsmangledtype", state.clazz(TYPE_MANGLED))
- .replace("$jsdtor", state.clazz(DTOR))
- .trim()
- .pretty_print(f_init_class_templates);
-
- Template t_class_instance = getTemplate("jsv8_create_class_instance");
- t_class_instance.replace("$jsname", state.clazz(NAME))
- .replace("$jsmangledname", state.clazz(NAME_MANGLED))
- .replace("$jsctor", state.clazz(CTOR))
- .trim()
- .pretty_print(f_init_class_instances);
-
- // emit inheritance setup
- Node *baseClass = getBaseClass(n);
- if (baseClass) {
- String *base_name = Getattr(baseClass, "name");
-
- Template t_inherit = getTemplate("jsv8_inherit");
-
- String *base_name_mangled = SwigType_manglestr(base_name);
- t_inherit.replace("$jsmangledname", state.clazz(NAME_MANGLED))
- .replace("$jsbaseclass", base_name_mangled)
- .trim()
- .pretty_print(f_init_inheritance);
- Delete(base_name_mangled);
- }
- // emit registration of class template
- Template t_register = getTemplate("jsv8_register_class");
- t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED))
- .replace("$jsname", state.clazz(NAME))
- .replace("$jsparent", Getattr(state.clazz("nspace"), NAME_MANGLED))
- .trim()
- .pretty_print(f_init_register_classes);
-
- return SWIG_OK;
-}
-
-int V8Emitter::enterVariable(Node *n) {
- JSEmitter::enterVariable(n);
-
- state.variable(GETTER, NULL_STR);
- state.variable(SETTER, VETO_SET);
-
- return SWIG_OK;
-}
-
-int V8Emitter::exitVariable(Node *n) {
- if (GetFlag(n, "ismember")) {
- if (GetFlag(state.variable(), IS_STATIC) || Equal(Getattr(n, "nodeType"), "enumitem")) {
- Template t_register = getTemplate("jsv8_register_static_variable");
- t_register.replace("$jsparent", state.clazz(NAME_MANGLED))
- .replace("$jsname", state.variable(NAME))
- .replace("$jsgetter", state.variable(GETTER))
- .replace("$jssetter", state.variable(SETTER))
- .trim()
- .pretty_print(f_init_static_wrappers);
- } else {
- Template t_register = getTemplate("jsv8_register_member_variable");
- t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED))
- .replace("$jsname", state.variable(NAME))
- .replace("$jsgetter", state.variable(GETTER))
- .replace("$jssetter", state.variable(SETTER))
- .trim()
- .pretty_print(f_init_wrappers);
- }
- } else {
- // Note: a global variable is treated like a static variable
- // with the parent being a nspace object (instead of class object)
- Template t_register = getTemplate("jsv8_register_static_variable");
- t_register.replace("$jsparent", Getattr(current_namespace, NAME_MANGLED))
- .replace("$jsname", state.variable(NAME))
- .replace("$jsgetter", state.variable(GETTER))
- .replace("$jssetter", state.variable(SETTER))
- .trim()
- .pretty_print(f_init_wrappers);
- }
-
- return SWIG_OK;
-}
-
-int V8Emitter::exitFunction(Node *n) {
- bool is_member = GetFlag(n, "ismember") != 0 || GetFlag(n, "feature:extend") != 0;
-
- // create a dispatcher for overloaded functions
- bool is_overloaded = GetFlag(n, "sym:overloaded") != 0;
- if (is_overloaded) {
- if (!Getattr(n, "sym:nextSibling")) {
- //state.function(WRAPPER_NAME, Swig_name_wrapper(Getattr(n, "name")));
- emitFunctionDispatcher(n, is_member);
- } else {
- //don't register wrappers of overloaded functions in function tables
- return SWIG_OK;
- }
- }
- // register the function at the specific context
- if (is_member) {
- if (GetFlag(state.function(), IS_STATIC)) {
- Template t_register = getTemplate("jsv8_register_static_function");
- t_register.replace("$jsparent", state.clazz(NAME_MANGLED))
- .replace("$jsname", state.function(NAME))
- .replace("$jswrapper", state.function(WRAPPER_NAME))
- .trim()
- .pretty_print(f_init_static_wrappers);
- } else {
- Template t_register = getTemplate("jsv8_register_member_function");
- t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED))
- .replace("$jsname", state.function(NAME))
- .replace("$jswrapper", state.function(WRAPPER_NAME))
- .trim()
- .pretty_print(f_init_wrappers);
- }
- } else {
- // Note: a global function is treated like a static function
- // with the parent being a nspace object instead of class object
- Template t_register = getTemplate("jsv8_register_static_function");
- t_register.replace("$jsparent", Getattr(current_namespace, NAME_MANGLED))
- .replace("$jsname", state.function(NAME))
- .replace("$jswrapper", state.function(WRAPPER_NAME))
- .trim()
- .pretty_print(f_init_static_wrappers);
- }
-
- return SWIG_OK;
-}
-
-void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) {
- Parm *p;
- String *tm;
-
- int startIdx = 0;
- if (is_member && !is_static && mode != Ctor) {
- startIdx = 1;
- }
- // store number of arguments for argument checks
- int num_args = emit_num_arguments(parms) - startIdx;
- String *argcount = NewString("");
- Printf(argcount, "%d", num_args);
- Setattr(n, ARGCOUNT, argcount);
-
- int i = 0;
- for (p = parms; p; i++) {
- String *arg = NewString("");
- String *type = Getattr(p, "type");
-
- // ignore varargs
- if (SwigType_isvarargs(type))
- break;
-
- switch (mode) {
- case Getter:
- if (is_member && !is_static && i == 0) {
- Printv(arg, "info.Holder()", 0);
- } else {
- Printf(arg, "args[%d]", i - startIdx);
- }
- break;
- case Function:
- if (is_member && !is_static && i == 0) {
- Printv(arg, "args.Holder()", 0);
- } else {
- Printf(arg, "args[%d]", i - startIdx);
- }
- break;
- case Setter:
- if (is_member && !is_static && i == 0) {
- Printv(arg, "info.Holder()", 0);
- } else {
- Printv(arg, "value", 0);
- }
- break;
- case Ctor:
- Printf(arg, "args[%d]", i);
- break;
- default:
- Printf(stderr, "Illegal MarshallingMode.");
- Exit(EXIT_FAILURE);
- }
-
- tm = emitInputTypemap(n, p, wrapper, arg);
- Delete(arg);
-
- if (tm) {
- p = Getattr(p, "tmap:in:next");
- } else {
- p = nextSibling(p);
- }
- }
-}
-
-int V8Emitter::emitNamespaces() {
- Iterator it;
- for (it = First(namespaces); it.item; it = Next(it)) {
- Hash *entry = it.item;
- String *name = Getattr(entry, NAME);
- String *name_mangled = Getattr(entry, NAME_MANGLED);
- String *parent = Getattr(entry, PARENT);
- String *parent_mangled = Getattr(entry, PARENT_MANGLED);
-
- bool do_create = true;
- bool do_register = true;
-
- if (Equal(parent, "")) {
- do_register = false;
- }
- // Note: 'exports' is by convention the name of the object where
- // globals are stored into
- if (Equal(name, "exports")) {
- do_create = false;
- }
-
- if (do_create) {
- // create namespace object and register it to the parent scope
- Template t_create_ns = getTemplate("jsv8_create_namespace");
- t_create_ns.replace("$jsmangledname", name_mangled)
- .trim()
- .pretty_print(f_init_namespaces);
- }
-
- if (do_register) {
- Template t_register_ns = getTemplate("jsv8_register_namespace");
- t_register_ns.replace("$jsmangledname", name_mangled)
- .replace("$jsname", name)
- .replace("$jsparent", parent_mangled)
- .trim();
-
- // prepend in order to achieve reversed order of registration statements
- String *tmp_register_stmt = NewString("");
- t_register_ns.pretty_print(tmp_register_stmt);
- Insert(f_init_register_namespaces, 0, tmp_register_stmt);
- Delete(tmp_register_stmt);
- }
- }
-
- return SWIG_OK;
-}
-
-JSEmitter *swig_javascript_create_V8Emitter() {
- return new V8Emitter();
-}
-
-/**********************************************************************
- * Helper implementations
- **********************************************************************/
-
-JSEmitterState::JSEmitterState()
-: globalHash(NewHash()) {
- // initialize sub-hashes
- Setattr(globalHash, "class", NewHash());
- Setattr(globalHash, "function", NewHash());
- Setattr(globalHash, "variable", NewHash());
-}
-
-JSEmitterState::~JSEmitterState() {
- Delete(globalHash);
-}
-
-DOH *JSEmitterState::getState(const char *key, bool new_key) {
- if (new_key) {
- Hash *hash = NewHash();
- Setattr(globalHash, key, hash);
- }
- return Getattr(globalHash, key);
-}
-
-DOH *JSEmitterState::globals() {
- return globalHash;
-}
-
-DOH *JSEmitterState::globals(const char *key, DOH *initial) {
- if (initial != 0) {
- Setattr(globalHash, key, initial);
- }
- return Getattr(globalHash, key);
-}
-
-DOH *JSEmitterState::clazz(bool new_key) {
- return getState("class", new_key);
-}
-
-DOH *JSEmitterState::clazz(const char *key, DOH *initial) {
- DOH *c = clazz();
- if (initial != 0) {
- Setattr(c, key, initial);
- }
- return Getattr(c, key);
-}
-
-DOH *JSEmitterState::function(bool new_key) {
- return getState("function", new_key);
-}
-
-DOH *JSEmitterState::function(const char *key, DOH *initial) {
- DOH *f = function();
- if (initial != 0) {
- Setattr(f, key, initial);
- }
- return Getattr(f, key);
-}
-
-DOH *JSEmitterState::variable(bool new_key) {
- return getState("variable", new_key);
-}
-
-DOH *JSEmitterState::variable(const char *key, DOH *initial) {
- DOH *v = variable();
- if (initial != 0) {
- Setattr(v, key, initial);
- }
- return Getattr(v, key);
-}
-
-/*static*/
-int JSEmitterState::IsSet(DOH *val) {
- if (!val) {
- return 0;
- } else {
- const char *cval = Char(val);
- if (!cval)
- return 0;
- return (strcmp(cval, "0") != 0) ? 1 : 0;
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Template::Template() : creates a Template class for given template code
- * ----------------------------------------------------------------------------- */
-
-Template::Template(const String *code_) {
-
- if (!code_) {
- Printf(stdout, "Template code was null. Illegal input for template.");
- Exit(EXIT_FAILURE);
- }
- code = NewString(code_);
- templateName = NewString("");
-}
-
-Template::Template(const String *code_, const String *templateName_) {
-
- if (!code_) {
- Printf(stdout, "Template code was null. Illegal input for template.");
- Exit(EXIT_FAILURE);
- }
-
- code = NewString(code_);
- templateName = NewString(templateName_);
-}
-
-
-/* -----------------------------------------------------------------------------
- * Template::~Template() : cleans up of Template.
- * ----------------------------------------------------------------------------- */
-
-Template::~Template() {
- Delete(code);
- Delete(templateName);
-}
-
-/* -----------------------------------------------------------------------------
- * String* Template::str() : retrieves the current content of the template.
- * ----------------------------------------------------------------------------- */
-
-String *Template::str() {
- if (js_template_enable_debug) {
- String *pre_code = NewString("");
- String *post_code = NewString("");
- String *debug_code = NewString("");
- Printf(pre_code, "/* begin fragment(\"%s\") */", templateName);
- Printf(post_code, "/* end fragment(\"%s\") */", templateName);
- Printf(debug_code, "%s\n%s\n%s\n", pre_code, code, post_code);
-
- Delete(code);
- Delete(pre_code);
- Delete(post_code);
-
- code = debug_code;
- }
- return code;
-}
-
-Template & Template::trim() {
- const char *str = Char(code);
- if (str == 0)
- return *this;
-
- int length = Len(code);
- if (length == 0)
- return *this;
-
- int idx;
- for (idx = 0; idx < length; ++idx) {
- if (str[idx] != ' ' && str[idx] != '\t' && str[idx] != '\r' && str[idx] != '\n')
- break;
- }
- int start_pos = idx;
-
- for (idx = length - 1; idx >= start_pos; --idx) {
- if (str[idx] != ' ' && str[idx] != '\t' && str[idx] != '\r' && str[idx] != '\n')
- break;
- }
- int end_pos = idx;
-
- int new_length = end_pos - start_pos + 1;
- char *newstr = new char[new_length + 1];
- memcpy(newstr, str + start_pos, new_length);
- newstr[new_length] = 0;
-
- Delete(code);
- code = NewString(newstr);
- delete[]newstr;
-
- return *this;
-}
-
-/* -----------------------------------------------------------------------------
- * Template& Template::replace(const String* pattern, const String* repl) :
- *
- * replaces all occurrences of a given pattern with a given replacement.
- *
- * - pattern: the pattern to be replaced
- * - repl: the replacement string
- * - returns a reference to the Template to allow chaining of methods.
- * ----------------------------------------------------------------------------- */
-
-Template & Template::replace(const String *pattern, const String *repl) {
- Replaceall(code, pattern, repl);
- return *this;
-}
-
-Template & Template::print(DOH *doh) {
- Printv(doh, str(), 0);
- return *this;
-}
-
-Template & Template::pretty_print(DOH *doh) {
- Wrapper_pretty_print(str(), doh);
- return *this;
-}
-
-Template::Template(const Template & t) {
- code = NewString(t.code);
- templateName = NewString(t.templateName);
-}
-
-void Template::operator=(const Template & t) {
- Delete(code);
- Delete(templateName);
- code = NewString(t.code);
- templateName = NewString(t.templateName);
-}
diff --git a/contrib/tools/swig/Source/Modules/lang.cxx b/contrib/tools/swig/Source/Modules/lang.cxx
deleted file mode 100644
index 1e10e51d67..0000000000
--- a/contrib/tools/swig/Source/Modules/lang.cxx
+++ /dev/null
@@ -1,3902 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * lang.cxx
- *
- * Language base class functions. Default C++ handling is also implemented here.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include "cparse.h"
-#include <ctype.h>
-
-/* default mode settings */
-static int director_mode = 0;
-static int director_protected_mode = 1;
-static int all_protected_mode = 0;
-static int naturalvar_mode = 0;
-Language *Language::this_ = 0;
-
-/* Set director_protected_mode */
-void Wrapper_director_mode_set(int flag) {
- director_mode = flag;
-}
-
-void Wrapper_director_protected_mode_set(int flag) {
- director_protected_mode = flag;
-}
-
-void Wrapper_all_protected_mode_set(int flag) {
- all_protected_mode = flag;
-}
-
-void Wrapper_naturalvar_mode_set(int flag) {
- naturalvar_mode = flag;
-}
-
-extern "C" {
- int Swig_director_mode() {
- return director_mode;
- }
- int Swig_director_protected_mode() {
- return director_protected_mode;
- }
- int Swig_all_protected_mode() {
- return all_protected_mode;
- }
- void Language_replace_special_variables(String *method, String *tm, Parm *parm) {
- Language::instance()->replaceSpecialVariables(method, tm, parm);
- }
-}
-
-/* Some status variables used during parsing */
-static int InClass = 0; /* Parsing C++ or not */
-static String *ClassName = 0; /* This is the real name of the current class */
-static String *EnumClassName = 0; /* Enum class name */
-static String *ClassPrefix = 0; /* Class prefix */
-static String *EnumClassPrefix = 0; /* Prefix for strongly typed enums (including ClassPrefix) */
-static String *NSpace = 0; /* Namespace for the nspace feature */
-static String *ClassType = 0; /* Fully qualified type name to use */
-static String *DirectorClassName = 0; /* Director name of the current class */
-int Abstract = 0;
-int ImportMode = 0;
-int IsVirtual = 0;
-static String *AttributeFunctionGet = 0;
-static String *AttributeFunctionSet = 0;
-static Node *CurrentClass = 0;
-int line_number = 0;
-String *input_file = 0;
-int SmartPointer = 0;
-static Hash *classhash;
-
-extern int GenerateDefault;
-extern int ForceExtern;
-extern int AddExtern;
-extern "C" {
- extern int UseWrapperSuffix;
-}
-
-/* import modes */
-
-#define IMPORT_MODE 1
-
-/* ----------------------------------------------------------------------
- * Dispatcher::emit_one()
- *
- * Dispatch a single node
- * ---------------------------------------------------------------------- */
-
-int Dispatcher::emit_one(Node *n) {
- int ret = SWIG_OK;
-
- char *tag = Char(nodeType(n));
- if (!tag) {
- /* Printf(stderr,"SWIG: Fatal internal error. Malformed parse tree
- node!\n"); */
- return SWIG_OK;
- }
-
- /* Do not proceed if marked with an error */
-
- if (Getattr(n, "error"))
- return SWIG_OK;
-
- /* Look for warnings */
- String *wrn = Getattr(n, "feature:warnfilter");
- if (wrn)
- Swig_warnfilter(wrn, 1);
-
- /* ============================================================
- * C/C++ parsing
- * ============================================================ */
-
- if (strcmp(tag, "extern") == 0) {
- ret = externDeclaration(n);
- } else if (strcmp(tag, "cdecl") == 0) {
- ret = cDeclaration(n);
- } else if (strcmp(tag, "enum") == 0) {
- ret = enumDeclaration(n);
- } else if (strcmp(tag, "enumitem") == 0) {
- ret = enumvalueDeclaration(n);
- } else if (strcmp(tag, "enumforward") == 0) {
- ret = enumforwardDeclaration(n);
- } else if (strcmp(tag, "class") == 0) {
- ret = classDeclaration(n);
- } else if (strcmp(tag, "classforward") == 0) {
- ret = classforwardDeclaration(n);
- } else if (strcmp(tag, "constructor") == 0) {
- ret = constructorDeclaration(n);
- } else if (strcmp(tag, "destructor") == 0) {
- ret = destructorDeclaration(n);
- } else if (strcmp(tag, "access") == 0) {
- ret = accessDeclaration(n);
- } else if (strcmp(tag, "using") == 0) {
- ret = usingDeclaration(n);
- } else if (strcmp(tag, "namespace") == 0) {
- ret = namespaceDeclaration(n);
- } else if (strcmp(tag, "template") == 0) {
- ret = templateDeclaration(n);
- } else if (strcmp(tag, "lambda") == 0) {
- ret = lambdaDeclaration(n);
- }
-
- /* ===============================================================
- * SWIG directives
- * =============================================================== */
-
- else if (strcmp(tag, "top") == 0) {
- ret = top(n);
- } else if (strcmp(tag, "extend") == 0) {
- ret = extendDirective(n);
- } else if (strcmp(tag, "apply") == 0) {
- ret = applyDirective(n);
- } else if (strcmp(tag, "clear") == 0) {
- ret = clearDirective(n);
- } else if (strcmp(tag, "constant") == 0) {
- ret = constantDirective(n);
- } else if (strcmp(tag, "fragment") == 0) {
- ret = fragmentDirective(n);
- } else if (strcmp(tag, "import") == 0) {
- ret = importDirective(n);
- } else if (strcmp(tag, "include") == 0) {
- ret = includeDirective(n);
- } else if (strcmp(tag, "insert") == 0) {
- ret = insertDirective(n);
- } else if (strcmp(tag, "module") == 0) {
- ret = moduleDirective(n);
- } else if (strcmp(tag, "native") == 0) {
- ret = nativeDirective(n);
- } else if (strcmp(tag, "pragma") == 0) {
- ret = pragmaDirective(n);
- } else if (strcmp(tag, "typemap") == 0) {
- ret = typemapDirective(n);
- } else if (strcmp(tag, "typemapcopy") == 0) {
- ret = typemapcopyDirective(n);
- } else if (strcmp(tag, "typemapitem") == 0) {
- ret = typemapitemDirective(n);
- } else if (strcmp(tag, "types") == 0) {
- ret = typesDirective(n);
- } else {
- Swig_error(input_file, line_number, "Unrecognized parse tree node type '%s'\n", tag);
- ret = SWIG_ERROR;
- }
- if (wrn)
- Swig_warnfilter(wrn, 0);
- return ret;
-}
-
-/* ----------------------------------------------------------------------
- * Dispatcher::emit_children()
- *
- * Emit all children that match the given type. type = 0 means all types.
- * ---------------------------------------------------------------------- */
-
-int Dispatcher::emit_children(Node *n) {
- Node *c;
- char *eo = Char(Getattr(n, "feature:emitonlychildren"));
- for (c = firstChild(n); c; c = nextSibling(c)) {
- if (eo) {
- const char *tag = Char(nodeType(c));
- if (strcmp(tag, "cdecl") == 0) {
- if (checkAttribute(c, "storage", "typedef"))
- tag = "typedef";
- }
- if (strstr(eo, tag) == 0) {
- continue;
- }
- }
- emit_one(c);
- }
- return SWIG_OK;
-}
-
-
-/* Stubs for dispatcher class. We don't do anything by default---up to derived class
- to fill in traversal code */
-
-int Dispatcher::defaultHandler(Node *) {
- return SWIG_OK;
-}
-int Dispatcher::extendDirective(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::applyDirective(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::clearDirective(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::constantDirective(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::fragmentDirective(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::importDirective(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::includeDirective(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::insertDirective(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::moduleDirective(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::nativeDirective(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::pragmaDirective(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::typemapDirective(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::typemapitemDirective(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::typemapcopyDirective(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::typesDirective(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::cDeclaration(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::externDeclaration(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::enumDeclaration(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::enumvalueDeclaration(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::enumforwardDeclaration(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::classDeclaration(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::templateDeclaration(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::lambdaDeclaration(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::classforwardDeclaration(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::constructorDeclaration(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::destructorDeclaration(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::accessDeclaration(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::usingDeclaration(Node *n) {
- return defaultHandler(n);
-}
-int Dispatcher::namespaceDeclaration(Node *n) {
- return defaultHandler(n);
-}
-
-/* Allocators */
-Language::Language():
-none_comparison(NewString("$arg != 0")),
-director_ctor_code(NewString("")),
-director_prot_ctor_code(0),
-symtabs(NewHash()),
-overloading(0),
-multiinput(0),
-cplus_runtime(0),
-directors(0) {
- symbolAddScope(""); // create top level/global symbol table scope
- argc_template_string = NewString("argc");
- argv_template_string = NewString("argv[%d]");
-
- /* Default director constructor code, passed to Swig_ConstructorToFunction */
- Printv(director_ctor_code, "if ( $comparison ) { /* subclassed */\n", " $director_new \n", "} else {\n", " $nondirector_new \n", "}\n", NIL);
-
- /*
- Default director 'protected' constructor code, disabled by
- default. Each language that needs it, has to define it.
- */
- director_prot_ctor_code = 0;
- director_multiple_inheritance = 1;
- director_language = 0;
- assert(!this_);
- this_ = this;
-
- doxygenTranslator = NULL;
-}
-
-Language::~Language() {
- Delete(symtabs);
- Delete(director_ctor_code);
- Delete(none_comparison);
- this_ = 0;
-}
-
- /* -----------------------------------------------------------------------------
- * directorClassName()
- * ----------------------------------------------------------------------------- */
-
- String *Language::directorClassName(Node *n) {
- String *dirclassname;
- String *nspace = NewString(Getattr(n, "sym:nspace"));
- const char *attrib = "director:classname";
- String *classname = getClassPrefix();
-
- Replace(nspace, NSPACE_SEPARATOR, "_", DOH_REPLACE_ANY);
- if (Len(nspace) > 0)
- dirclassname = NewStringf("SwigDirector_%s_%s", nspace, classname);
- else
- dirclassname = NewStringf("SwigDirector_%s", classname);
- Setattr(n, attrib, dirclassname);
-
- Delete(nspace);
- return dirclassname;
- }
-
-/* ----------------------------------------------------------------------
- emit_one()
- ---------------------------------------------------------------------- */
-
-int Language::emit_one(Node *n) {
- int ret;
- int oldext;
- if (!n)
- return SWIG_OK;
-
- if (GetFlag(n, "feature:ignore")
- && !Getattr(n, "feature:onlychildren"))
- return SWIG_OK;
-
- oldext = Extend;
- if (Getattr(n, "feature:extend"))
- Extend = 1;
-
- line_number = Getline(n);
- input_file = Getfile(n);
-
- /*
- symtab = Getattr(n,"symtab");
- if (symtab) {
- symtab = Swig_symbol_setscope(symtab);
- }
- */
- ret = Dispatcher::emit_one(n);
- /*
- if (symtab) {
- Swig_symbol_setscope(symtab);
- }
- */
- Extend = oldext;
- return ret;
-}
-
-
-static Parm *nonvoid_parms(Parm *p) {
- if (p) {
- SwigType *t = Getattr(p, "type");
- if (SwigType_type(t) == T_VOID)
- return 0;
- }
- return p;
-}
-
-/* -----------------------------------------------------------------------------
- * cplus_value_type()
- *
- * Returns the alternative value type needed in C++ for class value
- * types. When swig is not sure about using a plain $ltype value,
- * since the class doesn't have a default constructor, or it can't be
- * assigned, you will get back 'SwigValueWrapper<type >'.
- *
- * ----------------------------------------------------------------------------- */
-
-SwigType *cplus_value_type(SwigType *t) {
- return SwigType_alttype(t, 0);
-}
-
-static Node *first_nontemplate(Node *n) {
- while (n) {
- if (Strcmp(nodeType(n), "template") != 0)
- return n;
- n = Getattr(n, "sym:nextSibling");
- }
- return n;
-}
-
-
-
-/* --------------------------------------------------------------------------
- * swig_pragma()
- *
- * Handle swig pragma directives.
- * -------------------------------------------------------------------------- */
-
-void swig_pragma(char *lang, char *name, char *value) {
- if (strcmp(lang, "swig") == 0) {
- if ((strcmp(name, "make_default") == 0) || ((strcmp(name, "makedefault") == 0))) {
- GenerateDefault = 1;
- } else if ((strcmp(name, "no_default") == 0) || ((strcmp(name, "nodefault") == 0))) {
- Swig_warning(WARN_DEPRECATED_NODEFAULT, "SWIG", 1, "dangerous, use %%nodefaultctor, %%nodefaultdtor instead.\n");
- GenerateDefault = 0;
- } else if (strcmp(name, "attributefunction") == 0) {
- String *nvalue = NewString(value);
- char *s = strchr(Char(nvalue), ':');
- if (!s) {
- Swig_error(input_file, line_number, "Bad value for attributefunction. Expected \"fmtget:fmtset\".\n");
- } else {
- *s = 0;
- AttributeFunctionGet = NewString(Char(nvalue));
- AttributeFunctionSet = NewString(s + 1);
- }
- Delete(nvalue);
- } else if (strcmp(name, "noattributefunction") == 0) {
- AttributeFunctionGet = 0;
- AttributeFunctionSet = 0;
- }
- }
-}
-
-/* --------------------------------------------------------------------------
- * Language::use_naturalvar_mode()
- *
- * Determine whether to use const ref typemaps instead of pointer typemaps
- * for variable access.
- * -------------------------------------------------------------------------- */
-int Language::use_naturalvar_mode(Node *n) const {
- if (Getattr(n, "unnamed"))
- return 0;
-
- // The naturalvar feature can be attached to either the variable name or the variable's type
- // naturalvar on the variable name is more specific and overrides naturalvar on the variable's type
- String *naturalvar = Getattr(n, "feature:naturalvar");
- bool explicitly_off = naturalvar && Strcmp(naturalvar, "0") == 0;
- int nvar = GetFlag(n, "feature:naturalvar");
-
- if (!explicitly_off && !nvar) {
- /* look for feature in the class */
- SwigType *ty = Getattr(n, "type");
- SwigType *fullty = SwigType_typedef_resolve_all(ty);
- if (SwigType_isclass(fullty)) {
- SwigType *tys = SwigType_strip_qualifiers(fullty);
- if (!CPlusPlus) {
- Replaceall(tys, "struct ", "");
- Replaceall(tys, "union ", "");
- Replaceall(tys, "class ", "");
- }
- Node *typenode = Swig_symbol_clookup(tys, 0);
- if (typenode) {
- naturalvar = Getattr(typenode, "feature:naturalvar");
- explicitly_off = naturalvar && Strcmp(naturalvar, "0") == 0;
- nvar = nvar || GetFlag(typenode, "feature:naturalvar");
- }
- Delete(tys);
- }
- Delete(fullty);
- }
- nvar = nvar || naturalvar_mode;
- return explicitly_off ? 0 : nvar ? CWRAP_NATURAL_VAR : 0;
-}
-
-/* ----------------------------------------------------------------------
- * Language::top() - Top of parsing tree
- * ---------------------------------------------------------------------- */
-
-int Language::top(Node *n) {
- Node *mod = Getattr(n, "module");
- if (mod) {
- Node *options = Getattr(mod, "options");
- if (options) {
- if (Getattr(options, "naturalvar")) {
- naturalvar_mode = 1;
- }
- }
- }
- classhash = Getattr(n, "classes");
- return emit_children(n);
-}
-
-/* ----------------------------------------------------------------------
- * Language::extendDirective()
- * ---------------------------------------------------------------------- */
-
-int Language::extendDirective(Node *n) {
- save_value<int> oldam(Extend, CWRAP_EXTEND);
- save_value<AccessMode> oldmode(cplus_mode, PUBLIC);
- emit_children(n);
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::applyDirective()
- * ---------------------------------------------------------------------- */
-
-int Language::applyDirective(Node *n) {
-
- Parm *pattern = Getattr(n, "pattern");
- Node *c = firstChild(n);
- while (c) {
- Parm *apattern = Getattr(c, "pattern");
- if (ParmList_len(pattern) != ParmList_len(apattern)) {
- Swig_error(input_file, line_number, "Can't apply (%s) to (%s). Number of arguments don't match.\n", ParmList_str(pattern), ParmList_str(apattern));
- } else {
- if (!Swig_typemap_apply(pattern, apattern)) {
- Swig_warning(WARN_TYPEMAP_APPLY_UNDEF, input_file, line_number, "Can't apply (%s). No typemaps are defined.\n", ParmList_str(pattern));
- }
- }
- c = nextSibling(c);
- }
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::clearDirective()
- * ---------------------------------------------------------------------- */
-
-int Language::clearDirective(Node *n) {
- Node *p;
- for (p = firstChild(n); p; p = nextSibling(p)) {
- ParmList *pattern = Getattr(p, "pattern");
- Swig_typemap_clear_apply(pattern);
- }
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::constantDirective()
- * ---------------------------------------------------------------------- */
-
-int Language::constantDirective(Node *n) {
-
- if (CurrentClass && (cplus_mode != PUBLIC))
- return SWIG_NOWRAP;
-
- if (!GetFlag(n, "feature:allowexcept")) {
- UnsetFlag(n, "feature:except");
- }
- if (Getattr(n, "feature:exceptvar")) {
- Setattr(n, "feature:except", Getattr(n, "feature:exceptvar"));
- }
-
- if (!ImportMode) {
- Swig_require("constantDirective", n, "name", "?value", NIL);
- String *name = Getattr(n, "name");
- String *value = Getattr(n, "value");
- if (!value) {
- value = Copy(name);
- } else {
- /* if (checkAttribute(n,"type","char")) {
- value = NewString(value);
- } else {
- value = NewStringf("%(escape)s", value);
- }
- */
- Setattr(n, "rawvalue", value);
- value = NewStringf("%(escape)s", value);
- if (!Len(value))
- Append(value, "\\0");
- /* Printf(stdout,"'%s' = '%s'\n", name, value); */
- }
- Setattr(n, "value", value);
- this->constantWrapper(n);
- Swig_restore(n);
- return SWIG_OK;
- }
- return SWIG_NOWRAP;
-}
-
-/* ----------------------------------------------------------------------
- * Language::fragmentDirective()
- * ---------------------------------------------------------------------- */
-
-int Language::fragmentDirective(Node *n) {
- if (!(Getattr(n, "emitonly") && ImportMode))
- Swig_fragment_register(n);
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::importDirective()
- * ---------------------------------------------------------------------- */
-
-int Language::importDirective(Node *n) {
- int oldim = ImportMode;
- ImportMode = IMPORT_MODE;
- emit_children(n);
- ImportMode = oldim;
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::includeDirective()
- * ---------------------------------------------------------------------- */
-
-int Language::includeDirective(Node *n) {
- emit_children(n);
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::insertDirective()
- * ---------------------------------------------------------------------- */
-
-int Language::insertDirective(Node *n) {
- /* %insert directive */
- if ((!ImportMode) || Getattr(n, "generated")) {
- String *code = Getattr(n, "code");
- String *section = Getattr(n, "section");
- File *f = 0;
- if (!section) { /* %{ ... %} */
- f = Swig_filebyname("header");
- } else {
- f = Swig_filebyname(section);
- }
- if (f) {
- Printf(f, "%s\n", code);
- } else {
- Swig_error(input_file, line_number, "Unknown target '%s' for %%insert directive.\n", section);
- }
- return SWIG_OK;
- } else {
- return SWIG_NOWRAP;
- }
-}
-
-/* ----------------------------------------------------------------------
- * Language::moduleDirective()
- * ---------------------------------------------------------------------- */
-
-int Language::moduleDirective(Node *n) {
- (void) n;
- /* %module directive */
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::nativeDirective()
- * ---------------------------------------------------------------------- */
-
-int Language::nativeDirective(Node *n) {
- if (!ImportMode) {
- return nativeWrapper(n);
- } else {
- return SWIG_NOWRAP;
- }
-}
-
-/* ----------------------------------------------------------------------
- * Language::pragmaDirective()
- * ---------------------------------------------------------------------- */
-
-int Language::pragmaDirective(Node *n) {
- /* %pragma directive */
- if (!ImportMode) {
- String *lan = Getattr(n, "lang");
- String *name = Getattr(n, "name");
- String *value = Getattr(n, "value");
- swig_pragma(Char(lan), Char(name), Char(value));
- /* pragma(Char(lan),Char(name),Char(value)); */
- return SWIG_OK;
- }
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::typemapDirective()
- * ---------------------------------------------------------------------- */
-
-int Language::typemapDirective(Node *n) {
- /* %typemap directive */
- String *method = Getattr(n, "method");
- String *code = Getattr(n, "code");
- Parm *kwargs = Getattr(n, "kwargs");
- Node *items = firstChild(n);
- static int nameerror = 0;
-
-
- if (code && (Strstr(code, "$source") || (Strstr(code, "$target")))) {
- Swig_error(Getfile(n), Getline(n), "Obsolete typemap feature ($source/$target).\n");
- if (!nameerror) {
- Swig_error(Getfile(n), Getline(n), "The use of $source and $target in a typemap declaration is no longer supported.\n\
-For typemaps related to argument input (in,ignore,default,arginit,check), replace\n\
-$source by $input and $target by $1. For typemaps related to return values (out,\n\
-argout,ret,except), replace $source by $1 and $target by $result. See the file\n\
-Doc/Manual/Typemaps.html for complete details.\n");
- nameerror = 1;
- }
- }
-
- if (Strcmp(method, "except") == 0) {
- Swig_warning(WARN_DEPRECATED_EXCEPT_TM, Getfile(n), Getline(n), "%%typemap(except) is deprecated. Use the %%exception directive.\n");
- }
-
- if (Strcmp(method, "in") == 0) {
- Hash *k;
- k = kwargs;
- while (k) {
- if (checkAttribute(k, "name", "numinputs")) {
- if (!multiinput && (GetInt(k, "value") > 1)) {
- Swig_error(Getfile(n), Getline(n), "Multiple-input typemaps (numinputs > 1) not supported by this target language module.\n");
- return SWIG_ERROR;
- }
- break;
- }
- k = nextSibling(k);
- }
- if (!k) {
- k = NewHash();
- Setattr(k, "name", "numinputs");
- Setattr(k, "value", "1");
- set_nextSibling(k, kwargs);
- Setattr(n, "kwargs", k);
- kwargs = k;
- }
- }
-
- if (Strcmp(method, "ignore") == 0) {
- Swig_warning(WARN_DEPRECATED_IGNORE_TM, Getfile(n), Getline(n), "%%typemap(ignore) has been replaced by %%typemap(in,numinputs=0).\n");
-
- Clear(method);
- Append(method, "in");
- Hash *k = NewHash();
- Setattr(k, "name", "numinputs");
- Setattr(k, "value", "0");
- set_nextSibling(k, kwargs);
- Setattr(n, "kwargs", k);
- kwargs = k;
- }
-
- /* Replace $descriptor() macros */
-
- if (code) {
- Setfile(code, Getfile(n));
- Setline(code, Getline(n));
- Swig_cparse_replace_descriptor(code);
- }
-
- while (items) {
- Parm *pattern = Getattr(items, "pattern");
- Parm *parms = Getattr(items, "parms");
-
- if (code) {
- Swig_typemap_register(method, pattern, code, parms, kwargs);
- } else {
- Swig_typemap_clear(method, pattern);
- }
- items = nextSibling(items);
- }
- return SWIG_OK;
-
-}
-
-/* ----------------------------------------------------------------------
- * Language::typemapcopyDirective()
- * ---------------------------------------------------------------------- */
-
-int Language::typemapcopyDirective(Node *n) {
- String *method = Getattr(n, "method");
- Parm *pattern = Getattr(n, "pattern");
- Node *items = firstChild(n);
- int nsrc = 0;
- nsrc = ParmList_len(pattern);
- while (items) {
- ParmList *npattern = Getattr(items, "pattern");
- if (nsrc != ParmList_len(npattern)) {
- Swig_error(input_file, line_number, "Can't copy typemap. Number of types differ.\n");
- } else {
- if (Swig_typemap_copy(method, pattern, npattern) < 0) {
- Swig_error(input_file, line_number, "Can't copy typemap (%s) %s = %s\n", method, ParmList_str(pattern), ParmList_str(npattern));
- }
- }
- items = nextSibling(items);
- }
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::typesDirective()
- * ---------------------------------------------------------------------- */
-
-int Language::typesDirective(Node *n) {
- Parm *parms = Getattr(n, "parms");
- String *convcode = Getattr(n, "convcode"); /* optional user supplied conversion code for custom casting */
- while (parms) {
- SwigType *t = Getattr(parms, "type");
- String *v = Getattr(parms, "value");
- if (!v) {
- SwigType_remember(t);
- } else {
- if (SwigType_issimple(t)) {
- SwigType_inherit(t, v, 0, convcode);
- }
- }
- parms = nextSibling(parms);
- }
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::cDeclaration()
- * ---------------------------------------------------------------------- */
-
-int Language::cDeclaration(Node *n) {
-
- String *name = Getattr(n, "name");
- String *symname = Getattr(n, "sym:name");
- SwigType *type = Getattr(n, "type");
- SwigType *decl = Getattr(n, "decl");
- String *storage = Getattr(n, "storage");
- Node *over;
- File *f_header = 0;
- SwigType *ty, *fullty;
-
- if (Getattr(n, "feature:onlychildren")) {
- if (GetFlag(n, "feature:ignore")) {
- return SWIG_NOWRAP;
- } else {
- // Found an unignored templated method that has an empty template instantiation (%template())
- // Ignore it unless it has been %rename'd
- if (Strncmp(symname, "__dummy_", 8) == 0 && Cmp(storage, "typedef") != 0) {
- SetFlag(n, "feature:ignore");
- Swig_warning(WARN_LANG_TEMPLATE_METHOD_IGNORE, input_file, line_number,
- "%%template() contains no name. Template method ignored: %s\n", Swig_name_decl(n));
- return SWIG_NOWRAP;
- }
- }
- }
-
- /* discards nodes following the access control rules */
- if (cplus_mode != PUBLIC || !is_public(n)) {
- /* except for friends, they are not affected by access control */
- int isfriend = Cmp(storage, "friend") == 0;
- if (!isfriend) {
- /* Check what the director needs. If the method is pure virtual, it is always needed.
- * Also wrap non-virtual protected members if asked for (allprotected mode). */
- if (!(directorsEnabled() && ((is_member_director(CurrentClass, n) && need_nonpublic_member(n)) || isNonVirtualProtectedAccess(n)))) {
- return SWIG_NOWRAP;
- }
- // Prevent wrapping protected overloaded director methods more than once -
- // This bit of code is only needed due to the cDeclaration call in classHandler()
- String *wrapname = NewStringf("nonpublic_%s%s", symname, Getattr(n, "sym:overname"));
- if (Getattr(CurrentClass, wrapname)) {
- Delete(wrapname);
- return SWIG_NOWRAP;
- }
- SetFlag(CurrentClass, wrapname);
- Delete(wrapname);
- }
- }
-
- if (Cmp(storage, "typedef") == 0) {
- Swig_save("cDeclaration", n, "type", NIL);
- SwigType *t = Copy(type);
- if (t) {
- SwigType_push(t, decl);
- Setattr(n, "type", t);
- typedefHandler(n);
- }
- Swig_restore(n);
- return SWIG_OK;
- }
-
- /* If in import mode, we proceed no further */
- if (ImportMode)
- return SWIG_NOWRAP;
-
- /* If we're in extend mode and there is code, replace the $descriptor macros */
- if (Extend) {
- String *code = Getattr(n, "code");
- if (code) {
- Setfile(code, Getfile(n));
- Setline(code, Getline(n));
- Swig_cparse_replace_descriptor(code);
- }
- }
-
- /* Overloaded symbol check */
- over = Swig_symbol_isoverloaded(n);
- if (!overloading) {
- if (over)
- over = first_nontemplate(over);
- if (over && (over != n)) {
- Swig_warning(WARN_LANG_OVERLOAD_DECL, input_file, line_number, "Overloaded declaration ignored. %s\n", Swig_name_decl(n));
- Swig_warning(WARN_LANG_OVERLOAD_DECL, Getfile(over), Getline(over), "Previous declaration is %s\n", Swig_name_decl(over));
- return SWIG_NOWRAP;
- }
- }
-
- if (!validIdentifier(symname)) {
- Swig_warning(WARN_LANG_IDENTIFIER, input_file, line_number, "Can't wrap '%s' unless renamed to a valid identifier.\n", SwigType_namestr(symname));
- return SWIG_NOWRAP;
- }
-
- ty = NewString(type);
- SwigType_push(ty, decl);
- fullty = SwigType_typedef_resolve_all(ty);
- if (SwigType_isfunction(fullty)) {
- if (!SwigType_isfunction(ty)) {
- Delete(ty);
- ty = fullty;
- fullty = 0;
- ParmList *parms = SwigType_function_parms(ty, n);
- Setattr(n, "parms", parms);
- }
- /* Transform the node into a 'function' node and emit */
- if (!CurrentClass) {
- f_header = Swig_filebyname("header");
-
- if (AddExtern) {
- if (f_header) {
- if (Swig_storage_isextern(n) || (ForceExtern && !storage)) {
- /* we don't need the 'extern' part in the C/C++ declaration,
- and it produces some problems when namespace and SUN
- Studio is used.
-
- Printf(f_header,"extern %s", SwigType_str(ty,name));
-
- In fact generating extern declarations is quite error prone and is
- no longer the default. Getting it right seems impossible with namespaces
- and default arguments and when a method is declared with the various Windows
- calling conventions - SWIG doesn't understand Windows (non standard) calling
- conventions in the first place, so can't regenerate them.
- */
- String *str = SwigType_str(ty, name);
- Printf(f_header, "%s", str);
- Delete(str);
- {
- DOH *t = Getattr(n, "throws");
- if (t) {
- Printf(f_header, " throw(");
- while (t) {
- Printf(f_header, "%s", Getattr(t, "type"));
- t = nextSibling(t);
- if (t)
- Printf(f_header, ",");
- }
- Printf(f_header, ")");
- }
- }
- Printf(f_header, ";\n");
- } else if (Swig_storage_isexternc(n)) {
- /* here 'extern "C"' is needed */
- String *str = SwigType_str(ty, name);
- Printf(f_header, "extern \"C\" %s;\n", str);
- Delete(str);
- }
- }
- }
- }
- /* This needs to check qualifiers */
- if (SwigType_isqualifier(ty)) {
- SwigType *qual = SwigType_pop(ty);
- Setattr(n, "qualifier", qual);
- Delete(qual);
- }
- Delete(SwigType_pop_function(ty));
- DohIncref(type);
- Setattr(n, "type", ty);
-
- functionHandler(n);
-
- Setattr(n, "type", type);
- Delete(ty);
- Delete(type);
- return SWIG_OK;
- } else {
- /* Some kind of variable declaration */
- String *declaration = Copy(decl);
- Delattr(n, "decl");
- if (!CurrentClass) {
- if (Swig_storage_isextern(n) || ForceExtern) {
- if (AddExtern) {
- f_header = Swig_filebyname("header");
- if (f_header) {
- String *str = SwigType_str(ty, name);
- Printf(f_header, "%s %s;\n", Getattr(n, "storage"), str);
- Delete(str);
- }
- }
- }
- }
- if (!SwigType_ismutable(ty)) {
- SetFlag(n, "feature:immutable");
- }
- /* If an array and elements are const, then read-only */
- if (SwigType_isarray(ty)) {
- SwigType *tya = SwigType_array_type(ty);
- if (SwigType_isconst(tya)) {
- SetFlag(n, "feature:immutable");
- }
- Delete(tya);
- }
- DohIncref(type);
- Setattr(n, "type", ty);
- variableHandler(n);
- Setattr(n, "type", type);
- Setattr(n, "decl", declaration);
- Delete(ty);
- Delete(type);
- Delete(fullty);
- return SWIG_OK;
- }
-}
-
-/* ----------------------------------------------------------------------
- * Language::functionHandler()
- * ---------------------------------------------------------------------- */
-
-int Language::functionHandler(Node *n) {
- String *storage = Getattr(n, "storage");
- int isfriend = CurrentClass && Cmp(storage, "friend") == 0;
- int isstatic = CurrentClass && Swig_storage_isstatic(n) && !(SmartPointer && Getattr(n, "allocate:smartpointeraccess"));
- Parm *p = Getattr(n, "parms");
- if (GetFlag(n, "feature:del")) {
- /* the method acts like a delete operator, ie, we need to disown the parameter */
- if (CurrentClass && !isstatic && !isfriend) {
- SetFlag(n, "feature:self:disown");
- } else {
- if (p)
- SetFlag(p, "wrap:disown");
- }
- }
- if (!CurrentClass) {
- globalfunctionHandler(n);
- } else {
- if (isstatic) {
- staticmemberfunctionHandler(n);
- } else if (isfriend) {
- int oldInClass = InClass;
- InClass = 0;
- globalfunctionHandler(n);
- InClass = oldInClass;
- } else {
- // This is a member function, set a flag so the documentation type is correct
- SetFlag(n, "memberfunction");
- Node *explicit_n = 0;
- if (directorsEnabled() && is_member_director(CurrentClass, n) && !extraDirectorProtectedCPPMethodsRequired()) {
- bool virtual_but_not_pure_virtual = (!(Cmp(storage, "virtual")) && (Cmp(Getattr(n, "value"), "0") != 0));
- if (virtual_but_not_pure_virtual) {
- // Add additional wrapper which makes an explicit call to the virtual method (ie not a virtual call)
- explicit_n = Copy(n);
- String *new_symname = Copy(Getattr(n, "sym:name"));
- String *suffix = Getattr(parentNode(n), "sym:name");
- Printv(new_symname, "SwigExplicit", suffix, NIL);
- Setattr(explicit_n, "sym:name", new_symname);
- Delattr(explicit_n, "storage");
- Delattr(explicit_n, "override");
- Delattr(explicit_n, "hides");
- SetFlag(explicit_n, "explicitcall");
- Setattr(n, "explicitcallnode", explicit_n);
- }
- }
-
- memberfunctionHandler(n);
-
- if (explicit_n) {
- memberfunctionHandler(explicit_n);
- Delattr(explicit_n, "explicitcall");
- Delete(explicit_n);
- }
- }
- }
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::globalfunctionHandler()
- * ---------------------------------------------------------------------- */
-
-int Language::globalfunctionHandler(Node *n) {
-
- Swig_require("globalfunctionHandler", n, "name", "sym:name", "type", "?parms", NIL);
-
- String *name = Getattr(n, "name");
- String *symname = Getattr(n, "sym:name");
- SwigType *type = Getattr(n, "type");
- ParmList *parms = Getattr(n, "parms");
-
- /* Check for callback mode */
- String *cb = GetFlagAttr(n, "feature:callback");
- if (cb) {
- String *cbname = Getattr(n, "feature:callback:name");
- if (!cbname) {
- cbname = NewStringf(cb, symname);
- Setattr(n, "feature:callback:name", cbname);
- }
-
- callbackfunctionHandler(n);
- if (Cmp(cbname, symname) == 0) {
- Delete(cbname);
- Swig_restore(n);
- return SWIG_NOWRAP;
- }
- Delete(cbname);
- }
- Setattr(n, "parms", nonvoid_parms(parms));
-
- String *extendname = Getattr(n, "extendname");
- String *call = Swig_cfunction_call(extendname ? extendname : name, parms);
- String *cres = Swig_cresult(type, Swig_cresult_name(), call);
- Setattr(n, "wrap:action", cres);
- Delete(cres);
- Delete(call);
- functionWrapper(n);
-
- Swig_restore(n);
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::callbackfunctionHandler()
- * ---------------------------------------------------------------------- */
-
-int Language::callbackfunctionHandler(Node *n) {
- Swig_require("callbackfunctionHandler", n, "name", "*sym:name", "*type", "?value", NIL);
- String *type = Getattr(n, "type");
- String *name = Getattr(n, "name");
- String *parms = Getattr(n, "parms");
- String *cbname = Getattr(n, "feature:callback:name");
- String *calltype = NewStringf("(%s (*)(%s))(%s)", SwigType_str(type, 0), ParmList_str(parms), SwigType_namestr(name));
- SwigType *cbty = Copy(type);
- SwigType_add_function(cbty, parms);
- SwigType_add_pointer(cbty);
-
- Setattr(n, "sym:name", cbname);
- Setattr(n, "type", cbty);
- Setattr(n, "value", calltype);
-
- Node *ns = symbolLookup(cbname);
- if (!ns)
- constantWrapper(n);
-
- Delete(cbty);
-
- Swig_restore(n);
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::memberfunctionHandler()
- * ---------------------------------------------------------------------- */
-
-int Language::memberfunctionHandler(Node *n) {
-
- Swig_require("memberfunctionHandler", n, "*name", "*sym:name", "*type", "?parms", "?value", NIL);
-
- String *storage = Getattr(n, "storage");
- String *name = Getattr(n, "name");
- String *symname = Getattr(n, "sym:name");
- SwigType *type = Getattr(n, "type");
- String *value = Getattr(n, "value");
- ParmList *parms = Getattr(n, "parms");
- String *cb = GetFlagAttr(n, "feature:callback");
-
- if (Cmp(storage, "virtual") == 0) {
- if (Cmp(value, "0") == 0) {
- IsVirtual = PURE_VIRTUAL;
- } else {
- IsVirtual = PLAIN_VIRTUAL;
- }
- } else {
- IsVirtual = 0;
- }
- if (cb) {
- Node *cbn = NewHash();
- String *cbname = Getattr(n, "feature:callback:name");
- if (!cbname) {
- cbname = NewStringf(cb, symname);
- }
-
- SwigType *cbty = Copy(type);
- SwigType_add_function(cbty, parms);
- SwigType_add_memberpointer(cbty, ClassName);
- String *cbvalue = NewStringf("&%s::%s", ClassName, name);
- Setattr(cbn, "sym:name", cbname);
- Setattr(cbn, "type", cbty);
- Setattr(cbn, "value", cbvalue);
- Setattr(cbn, "name", name);
- Setfile(cbn, Getfile(n));
- Setline(cbn, Getline(n));
-
- memberconstantHandler(cbn);
- Setattr(n, "feature:callback:name", Swig_name_member(NSpace, ClassPrefix, cbname));
-
- Delete(cb);
- Delete(cbn);
- Delete(cbvalue);
- Delete(cbty);
- Delete(cbname);
- if (Cmp(cbname, symname) == 0) {
- Swig_restore(n);
- return SWIG_NOWRAP;
- }
- }
-
- String *fname = Swig_name_member(NSpace, ClassPrefix, symname);
- if (Extend && SmartPointer) {
- if (!Getattr(n, "extendsmartclassname")) {
- Setattr(n, "extendsmartclassname", Getattr(CurrentClass, "allocate:smartpointerpointeeclassname"));
- }
- }
- // Set up the type for the cast to this class for use when wrapping const director (virtual) methods.
- // Note: protected director methods or when allprotected mode turned on.
- String *director_type = 0;
- if (!is_public(n) && (is_member_director(CurrentClass, n) || GetFlag(n, "explicitcall") || isNonVirtualProtectedAccess(n))) {
- director_type = Copy(DirectorClassName);
- String *qualifier = Getattr(n, "qualifier");
- if (qualifier)
- SwigType_push(director_type, qualifier);
- SwigType_add_pointer(director_type);
- }
-
- int DirectorExtraCall = 0;
- if (directorsEnabled() && is_member_director(CurrentClass, n) && !SmartPointer)
- if (extraDirectorProtectedCPPMethodsRequired())
- DirectorExtraCall = CWRAP_DIRECTOR_TWO_CALLS;
-
- if (GetFlag(n, "explicitcall"))
- DirectorExtraCall = CWRAP_DIRECTOR_ONE_CALL;
-
- int extendmember = GetFlag(n, "isextendmember") ? Extend : 0;
- int flags = Getattr(n, "template") ? extendmember | SmartPointer : Extend | SmartPointer | DirectorExtraCall;
- Swig_MethodToFunction(n, NSpace, ClassType, flags, director_type, is_member_director(CurrentClass, n));
- Setattr(n, "sym:name", fname);
- /* Explicitly save low-level and high-level documentation names */
- Setattr(n, "doc:low:name", fname);
- Setattr(n, "doc:high:name", symname);
-
- functionWrapper(n);
-
- Delete(director_type);
- Delete(fname);
- Swig_restore(n);
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::staticmemberfunctionHandler()
- * ---------------------------------------------------------------------- */
-
-int Language::staticmemberfunctionHandler(Node *n) {
-
- Swig_require("staticmemberfunctionHandler", n, "*name", "*sym:name", "*type", NIL);
- Swig_save("staticmemberfunctionHandler", n, "storage", NIL);
- String *name = Getattr(n, "name");
- String *symname = Getattr(n, "sym:name");
- SwigType *type = Getattr(n, "type");
- ParmList *parms = Getattr(n, "parms");
- String *cb = GetFlagAttr(n, "feature:callback");
- String *cname, *mrename;
-
- if (!Extend) {
- Node *sb = Getattr(n, "cplus:staticbase");
- String *sname = Getattr(sb, "name");
- if (isNonVirtualProtectedAccess(n))
- cname = NewStringf("%s::%s", DirectorClassName, name);
- else
- cname = NewStringf("%s::%s", sname, name);
- } else {
- String *mname = Swig_name_mangle(ClassName);
- cname = Swig_name_member(NSpace, mname, name);
- Delete(mname);
- }
- mrename = Swig_name_member(NSpace, ClassPrefix, symname);
-
- if (Extend) {
- String *code = Getattr(n, "code");
- String *defaultargs = Getattr(n, "defaultargs");
- String *mangled = Swig_name_mangle(mrename);
- Delete(mrename);
- mrename = mangled;
-
- if (code) {
- // See Swig_MethodToFunction() for the explanation of this code.
- if (Getattr(n, "sym:overloaded")) {
- Append(cname, Getattr(defaultargs ? defaultargs : n, "sym:overname"));
- } else if (UseWrapperSuffix) {
- Append(cname, "__SWIG");
- }
-
- if (!defaultargs) {
- /* Hmmm. An added static member. We have to create a little wrapper for this */
- String *mangled_cname = Swig_name_mangle(cname);
- Swig_add_extension_code(n, mangled_cname, parms, type, code, CPlusPlus, 0);
- Setattr(n, "extendname", mangled_cname);
- Delete(mangled_cname);
- }
- }
- }
-
- Setattr(n, "name", cname);
- Setattr(n, "sym:name", mrename);
- /* Explicitly save low-level and high-level documentation names */
- Setattr(n, "doc:low:name", mrename);
- Setattr(n, "doc:high:name", symname);
-
- if (cb) {
- String *cbname = NewStringf(cb, symname);
- Setattr(n, "feature:callback:name", Swig_name_member(NSpace, ClassPrefix, cbname));
- Setattr(n, "feature:callback:staticname", name);
- }
- Delattr(n, "storage");
-
- globalfunctionHandler(n);
-
- Delete(cname);
- Delete(mrename);
- Swig_restore(n);
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::variableHandler()
- * ---------------------------------------------------------------------- */
-
-int Language::variableHandler(Node *n) {
-
- /* If not a smart-pointer access or added method. We clear
- feature:except. There is no way C++ or C would throw
- an exception merely for accessing a member data.
-
- Caveat: Some compilers seem to route attribute access through
- methods which can generate exceptions. The feature:allowexcept
- allows this. Also, the feature:exceptvar can be used to match
- only variables.
- */
- if (!(Extend | SmartPointer)) {
- if (!GetFlag(n, "feature:allowexcept")) {
- UnsetFlag(n, "feature:except");
- }
- if (Getattr(n, "feature:exceptvar")) {
- Setattr(n, "feature:except", Getattr(n, "feature:exceptvar"));
- }
- }
-
- if (!CurrentClass) {
- globalvariableHandler(n);
- } else {
- Swig_save("variableHandler", n, "feature:immutable", NIL);
- if (SmartPointer) {
- /* If a smart-pointer and it's a constant access, we have to set immutable */
- if (!Getattr(CurrentClass, "allocate:smartpointermutable")) {
- SetFlag(n, "feature:immutable");
- }
- }
- if (Swig_storage_isstatic(n) && !(SmartPointer && Getattr(n, "allocate:smartpointeraccess"))) {
- staticmembervariableHandler(n);
- } else {
- membervariableHandler(n);
- }
- Swig_restore(n);
- }
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::globalvariableHandler()
- * ---------------------------------------------------------------------- */
-
-int Language::globalvariableHandler(Node *n) {
- variableWrapper(n);
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::membervariableHandler()
- * ---------------------------------------------------------------------- */
-
-int Language::membervariableHandler(Node *n) {
-
- Swig_require("membervariableHandler", n, "*name", "*sym:name", "*type", NIL);
- Swig_save("membervariableHandler", n, "parms", NIL);
-
- String *name = Getattr(n, "name");
- String *symname = Getattr(n, "sym:name");
- SwigType *type = Getattr(n, "type");
-
- if (!AttributeFunctionGet) {
- String *mname = Swig_name_member(0, ClassPrefix, symname);
- String *mrename_get = Swig_name_get(NSpace, mname);
- String *mrename_set = Swig_name_set(NSpace, mname);
- Delete(mname);
-
- /* Create a function to set the value of the variable */
-
- int assignable = is_assignable(n);
-
- if (SmartPointer) {
- if (!Getattr(CurrentClass, "allocate:smartpointermutable")) {
- assignable = 0;
- }
- }
-
- if (assignable) {
- int make_set_wrapper = 1;
- String *tm = 0;
- String *target = 0;
- if (!Extend) {
- if (SmartPointer) {
- if (Swig_storage_isstatic(n)) {
- Node *sn = Getattr(n, "cplus:staticbase");
- String *base = Getattr(sn, "name");
- target = NewStringf("%s::%s", base, name);
- } else {
- String *pname = Swig_cparm_name(0, 0);
- target = NewStringf("(*%s)->%s", pname, name);
- Delete(pname);
- }
- } else {
- String *pname = isNonVirtualProtectedAccess(n) ? NewString("darg") : Swig_cparm_name(0, 0);
- target = NewStringf("%s->%s", pname, name);
- Delete(pname);
- }
-
- // This is an input type typemap lookup and so it should not use Node n
- // otherwise qualification is done on the parameter name for the setter function
- Parm *nin = NewParm(type, name, n);
- tm = Swig_typemap_lookup("memberin", nin, target, 0);
- Delete(nin);
- }
-
- int flags = Extend | SmartPointer | use_naturalvar_mode(n);
- if (isNonVirtualProtectedAccess(n))
- flags = flags | CWRAP_ALL_PROTECTED_ACCESS;
-
- Swig_MembersetToFunction(n, ClassType, flags);
- Setattr(n, "memberset", "1");
- if (!Extend) {
- /* Check for a member in typemap here */
-
- if (!tm) {
- if (SwigType_isarray(type)) {
- Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(type, 0));
- make_set_wrapper = 0;
- }
- } else {
- String *pname0 = Swig_cparm_name(0, 0);
- String *pname1 = Swig_cparm_name(0, 1);
- Replace(tm, "$input", pname1, DOH_REPLACE_ANY);
- Replace(tm, "$self", pname0, DOH_REPLACE_ANY);
- Setattr(n, "wrap:action", tm);
- Delete(tm);
- Delete(pname0);
- Delete(pname1);
- }
- Delete(target);
- }
- if (make_set_wrapper) {
- Setattr(n, "sym:name", mrename_set);
- functionWrapper(n);
- } else {
- SetFlag(n, "feature:immutable");
- }
- /* Restore parameters */
- Setattr(n, "type", type);
- Setattr(n, "name", name);
- Setattr(n, "sym:name", symname);
- Delattr(n, "memberset");
-
- /* Delete all attached typemaps and typemap attributes */
- Iterator ki;
- for (ki = First(n); ki.key; ki = Next(ki)) {
- if (Strncmp(ki.key, "tmap:", 5) == 0)
- Delattr(n, ki.key);
- }
- }
- /* Emit get function */
- {
- int flags = Extend | SmartPointer | use_naturalvar_mode(n);
- if (isNonVirtualProtectedAccess(n))
- flags = flags | CWRAP_ALL_PROTECTED_ACCESS;
- Swig_MembergetToFunction(n, ClassType, flags);
- Setattr(n, "sym:name", mrename_get);
- Setattr(n, "memberget", "1");
- functionWrapper(n);
- Delattr(n, "memberget");
- }
- Delete(mrename_get);
- Delete(mrename_set);
-
- } else {
-
- /* This code is used to support the attributefunction directive
- where member variables are converted automagically to
- accessor functions */
-
-#if 0
- Parm *p;
- String *gname;
- SwigType *vty;
- p = NewParm(type, 0, n);
- gname = NewStringf(AttributeFunctionGet, symname);
- if (!Extend) {
- ActionFunc = Copy(Swig_cmemberget_call(name, type));
- cpp_member_func(Char(gname), Char(gname), type, 0);
- Delete(ActionFunc);
- } else {
- String *cname = Swig_name_get(NSpace, name);
- cpp_member_func(Char(cname), Char(gname), type, 0);
- Delete(cname);
- }
- Delete(gname);
- if (!GetFlag(n, "feature:immutable")) {
- gname = NewStringf(AttributeFunctionSet, symname);
- vty = NewString("void");
- if (!Extend) {
- ActionFunc = Copy(Swig_cmemberset_call(name, type));
- cpp_member_func(Char(gname), Char(gname), vty, p);
- Delete(ActionFunc);
- } else {
- String *cname = Swig_name_set(NSpace, name);
- cpp_member_func(Char(cname), Char(gname), vty, p);
- Delete(cname);
- }
- Delete(gname);
- }
- ActionFunc = 0;
-#endif
- }
- Swig_restore(n);
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::staticmembervariableHandler()
- * ---------------------------------------------------------------------- */
-
-int Language::staticmembervariableHandler(Node *n) {
- Swig_require("staticmembervariableHandler", n, "*name", "*sym:name", "*type", "?value", NIL);
- String *value = Getattr(n, "value");
- String *classname = !SmartPointer ? (isNonVirtualProtectedAccess(n) ? DirectorClassName : ClassName) : Getattr(CurrentClass, "allocate:smartpointerpointeeclassname");
-
- if (!value || !Getattr(n, "hasconsttype")) {
- String *name = Getattr(n, "name");
- String *symname = Getattr(n, "sym:name");
- String *cname, *mrename;
-
- /* Create the variable name */
- mrename = Swig_name_member(0, ClassPrefix, symname);
- cname = NewStringf("%s::%s", classname, name);
-
- Setattr(n, "sym:name", mrename);
- Setattr(n, "name", cname);
-
- /* Wrap as an ordinary global variable */
- variableWrapper(n);
-
- Delete(mrename);
- Delete(cname);
- } else {
-
- /* This is a C++ static member declaration with an initializer and it's const.
- Certain C++ compilers optimize this out so that there is no linkage to a
- memory address. Example:
-
- class Foo {
- public:
- static const int x = 3;
- };
-
- Some discussion of this in section 9.4 of the C++ draft standard.
-
- Also, we have to manage the case:
-
- class Foo {
- public:
- %extend {
- static const int x = 3;
- }
- };
-
- in which there's no actual Foo::x variable to refer to. In this case,
- the best we can do is to wrap the given value verbatim.
- */
-
-
- String *name = Getattr(n, "name");
- String *cname = NewStringf("%s::%s", classname, name);
- if (Extend) {
- /* the variable is a synthesized one.
- There's nothing we can do; we just keep the given value */
- } else {
- /* we refer to the value as Foo::x */
- String *value = SwigType_namestr(cname);
- Setattr(n, "value", value);
- }
-
- SwigType *t1 = SwigType_typedef_resolve_all(Getattr(n, "type"));
- SwigType *t2 = SwigType_strip_qualifiers(t1);
- Setattr(n, "type", t2);
- Delete(t1);
- Delete(t2);
- SetFlag(n, "wrappedasconstant");
- memberconstantHandler(n);
- Delete(cname);
- }
-
- Swig_restore(n);
- return SWIG_OK;
-}
-
-
-/* ----------------------------------------------------------------------
- * Language::externDeclaration()
- * ---------------------------------------------------------------------- */
-
-int Language::externDeclaration(Node *n) {
- return emit_children(n);
-}
-
-/* ----------------------------------------------------------------------
- * Language::enumDeclaration()
- * ---------------------------------------------------------------------- */
-
-int Language::enumDeclaration(Node *n) {
- if (CurrentClass && (cplus_mode != PUBLIC))
- return SWIG_NOWRAP;
-
- String *oldNSpace = NSpace;
- NSpace = Getattr(n, "sym:nspace");
-
- String *oldEnumClassPrefix = EnumClassPrefix;
- if (GetFlag(n, "scopedenum")) {
- assert(Getattr(n, "sym:name"));
- assert(Getattr(n, "name"));
- EnumClassPrefix = ClassPrefix ? NewStringf("%s_", ClassPrefix) : NewString("");
- Printv(EnumClassPrefix, Getattr(n, "sym:name"), NIL);
- EnumClassName = Copy(Getattr(n, "name"));
- }
- if (!ImportMode) {
- emit_children(n);
- }
-
- if (GetFlag(n, "scopedenum")) {
- Delete(EnumClassName);
- EnumClassName = 0;
- Delete(EnumClassPrefix);
- EnumClassPrefix = oldEnumClassPrefix;
- }
- NSpace = oldNSpace;
-
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::enumvalueDeclaration()
- * ---------------------------------------------------------------------- */
-
-int Language::enumvalueDeclaration(Node *n) {
- if (CurrentClass && (cplus_mode != PUBLIC))
- return SWIG_NOWRAP;
-
- Swig_require("enumvalueDeclaration", n, "*name", "*sym:name", "?value", NIL);
- String *value = Getattr(n, "value");
- String *name = Getattr(n, "name");
- String *tmpValue;
-
- if (value)
- tmpValue = NewString(value);
- else
- tmpValue = NewString(name);
- Setattr(n, "value", tmpValue);
-
- Node *parent = parentNode(n);
- if (GetFlag(parent, "scopedenum")) {
- String *symname = Swig_name_member(0, Getattr(parent, "sym:name"), Getattr(n, "sym:name"));
- Setattr(n, "sym:name", symname);
- Delete(symname);
- }
-
- if (!CurrentClass || !cparse_cplusplus) {
- Setattr(n, "name", tmpValue); /* for wrapping of enums in a namespace when emit_action is used */
- constantWrapper(n);
- } else {
- memberconstantHandler(n);
- }
-
- Delete(tmpValue);
- Swig_restore(n);
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::enumforwardDeclaration()
- * ---------------------------------------------------------------------- */
-
-int Language::enumforwardDeclaration(Node *n) {
- (void) n;
- if (GetFlag(n, "enumMissing"))
- enumDeclaration(n); // Generate an empty enum in target language
- return SWIG_OK;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::memberconstantHandler()
- * ----------------------------------------------------------------------------- */
-
-int Language::memberconstantHandler(Node *n) {
-
- Swig_require("memberconstantHandler", n, "*name", "*sym:name", "value", NIL);
-
- if (!GetFlag(n, "feature:allowexcept")) {
- UnsetFlag(n, "feature:except");
- }
- if (Getattr(n, "feature:exceptvar")) {
- Setattr(n, "feature:except", Getattr(n, "feature:exceptvar"));
- }
-
- String *enumvalue_symname = Getattr(n, "enumvalueDeclaration:sym:name"); // Only set if a strongly typed enum
- String *name = Getattr(n, "name");
- String *symname = Getattr(n, "sym:name");
- String *value = Getattr(n, "value");
-
- String *mrename = Swig_name_member(0, EnumClassPrefix, enumvalue_symname ? enumvalue_symname : symname);
- Setattr(n, "sym:name", mrename);
-
- String *new_name = 0;
- if (Extend)
- new_name = Copy(value);
- else if (EnumClassName)
- new_name = NewStringf("%s::%s", isNonVirtualProtectedAccess(n) ? DirectorClassName : EnumClassName, name);
- else
- new_name = NewStringf("%s::%s", isNonVirtualProtectedAccess(n) ? DirectorClassName : ClassName, name);
- Setattr(n, "name", new_name);
-
- constantWrapper(n);
- Delete(mrename);
- Delete(new_name);
- Swig_restore(n);
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::typedefHandler()
- * ---------------------------------------------------------------------- */
-
-int Language::typedefHandler(Node *n) {
- /* since this is a recurring issue, we are going to remember the
- typedef pointer, if already it is not a pointer or reference, as
- in
-
- typedef void NT;
- int func(NT *p);
-
- see director_basic.i for example.
- */
- SwigType *name = Getattr(n, "name");
- SwigType *decl = Getattr(n, "decl");
- if (!SwigType_ispointer(decl) && !SwigType_isreference(decl)) {
- SwigType *pname = Copy(name);
- SwigType_add_pointer(pname);
- SwigType_remember(pname);
- Delete(pname);
- }
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::classDirectorMethod()
- * ---------------------------------------------------------------------- */
-
-int Language::classDirectorMethod(Node *n, Node *parent, String *super) {
- (void) n;
- (void) parent;
- (void) super;
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::classDirectorConstructor()
- * ---------------------------------------------------------------------- */
-
-int Language::classDirectorConstructor(Node *n) {
- (void) n;
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::classDirectorDefaultConstructor()
- * ---------------------------------------------------------------------- */
-
-int Language::classDirectorDefaultConstructor(Node *n) {
- (void) n;
- return SWIG_OK;
-}
-
-static String *vtable_method_id(Node *n) {
- String *nodeType = Getattr(n, "nodeType");
- int is_destructor = (Cmp(nodeType, "destructor") == 0);
- if (is_destructor)
- return 0;
- String *name = Getattr(n, "name");
- String *decl = Getattr(n, "decl");
- String *local_decl = SwigType_typedef_resolve_all(decl);
- String *tmp = SwigType_pop_function(local_decl);
- Delete(local_decl);
- local_decl = tmp;
- String *method_id = NewStringf("%s|%s", name, local_decl);
- Delete(local_decl);
- return method_id;
-}
-
-/* ----------------------------------------------------------------------
- * Language::unrollOneVirtualMethod()
- * ---------------------------------------------------------------------- */
-
-void Language::unrollOneVirtualMethod(String *classname, Node *n, Node *parent, List *vm, int &virtual_destructor, int protectedbase) {
- if (!checkAttribute(n, "storage", "virtual"))
- return;
- if (GetFlag(n, "final"))
- return;
-
- String *nodeType = Getattr(n, "nodeType");
-
- /* we need to add methods(cdecl) and destructor (to check for throw decl) */
- int is_destructor = (Cmp(nodeType, "destructor") == 0);
- if ((Cmp(nodeType, "cdecl") == 0) || is_destructor) {
- String *decl = Getattr(n, "decl");
- /* extra check for function type and proper access */
- if (SwigType_isfunction(decl) && (((!protectedbase || dirprot_mode()) && is_public(n)) || need_nonpublic_member(n))) {
- String *name = Getattr(n, "name");
- String *method_id = is_destructor ? NewStringf("~destructor") : vtable_method_id(n);
- /* Make sure that the new method overwrites the existing: */
- int len = Len(vm);
- const int DO_NOT_REPLACE = -1;
- int replace = DO_NOT_REPLACE;
- for (int i = 0; i < len; i++) {
- Node *item = Getitem(vm, i);
- String *check_vmid = Getattr(item, "vmid");
-
- if (Strcmp(method_id, check_vmid) == 0) {
- replace = i;
- break;
- }
- }
- /* filling a new method item */
- String *fqdname = NewStringf("%s::%s", classname, name);
- Hash *item = NewHash();
- Setattr(item, "fqdname", fqdname);
- Node *m = Copy(n);
-
- /* Store the complete return type - needed for non-simple return types (pointers, references etc.) */
- SwigType *ty = NewString(Getattr(m, "type"));
- SwigType_push(ty, decl);
- if (SwigType_isqualifier(ty)) {
- Delete(SwigType_pop(ty));
- }
- Delete(SwigType_pop_function(ty));
- Setattr(m, "returntype", ty);
-
- String *mname = NewStringf("%s::%s", Getattr(parent, "name"), name);
- /* apply the features of the original method found in the base class */
- Swig_features_get(Swig_cparse_features(), 0, mname, Getattr(m, "decl"), m);
- Setattr(item, "methodNode", m);
- Setattr(item, "vmid", method_id);
- if (replace == DO_NOT_REPLACE)
- Append(vm, item);
- else
- Setitem(vm, replace, item);
- Setattr(n, "directorNode", m);
-
- Delete(mname);
- }
- if (is_destructor) {
- virtual_destructor = 1;
- }
- }
-}
-
-/* ----------------------------------------------------------------------
- * Language::unrollVirtualMethods()
- * ---------------------------------------------------------------------- */
-int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int &virtual_destructor, int protectedbase) {
- bool first_base = false;
- // recurse through all base classes to build the vtable
- List *bl = Getattr(n, "bases");
- if (bl) {
- Iterator bi;
- for (bi = First(bl); bi.item; bi = Next(bi)) {
- if (first_base && !director_multiple_inheritance)
- break;
- unrollVirtualMethods(bi.item, parent, vm, virtual_destructor);
- first_base = true;
- }
- }
-
- // recurse through all protected base classes to build the vtable, as needed
- bl = Getattr(n, "protectedbases");
- if (bl) {
- Iterator bi;
- for (bi = First(bl); bi.item; bi = Next(bi)) {
- if (first_base && !director_multiple_inheritance)
- break;
- unrollVirtualMethods(bi.item, parent, vm, virtual_destructor, 1);
- first_base = true;
- }
- }
-
- // find the methods that need directors
- String *classname = Getattr(n, "name");
- for (Node *ni = firstChild(n); ni; ni = nextSibling(ni)) {
- /* we only need to check the virtual members */
- if (Equal(nodeType(ni), "using")) {
- for (Node *nn = firstChild(ni); nn; nn = Getattr(nn, "sym:nextSibling")) {
- unrollOneVirtualMethod(classname, nn, parent, vm, virtual_destructor, protectedbase);
- }
- }
- unrollOneVirtualMethod(classname, ni, parent, vm, virtual_destructor, protectedbase);
- }
-
- /*
- We delete all the nodirector methods. This prevents the
- generation of 'empty' director classes.
-
- Done once we've collated all the virtual methods into vm.
- */
- if (n == parent) {
- int len = Len(vm);
- for (int i = 0; i < len; i++) {
- Node *item = Getitem(vm, i);
- Node *m = Getattr(item, "methodNode");
- /* retrieve the director features */
- int mdir = GetFlag(m, "feature:director");
- int mndir = GetFlag(m, "feature:nodirector");
- /* 'nodirector' has precedence over 'director' */
- int dir = (mdir || mndir) ? (mdir && !mndir) : 1;
- /* check if the method was found only in a base class */
- Node *p = Getattr(m, "parentNode");
- if (p != n) {
- Node *c = Copy(m);
- Setattr(c, "parentNode", n);
- int cdir = GetFlag(c, "feature:director");
- int cndir = GetFlag(c, "feature:nodirector");
- dir = (cdir || cndir) ? (cdir && !cndir) : dir;
- Delete(c);
- }
- if (dir) {
- /* be sure the 'nodirector' feature is disabled */
- if (mndir)
- Delattr(m, "feature:nodirector");
- } else {
- /* or just delete from the vm, since is not a director method */
- Delitem(vm, i);
- len--;
- i--;
- }
- }
- }
-
- return SWIG_OK;
-}
-
-
-/* ----------------------------------------------------------------------
- * Language::classDirectorDisown()
- * ---------------------------------------------------------------------- */
-
-int Language::classDirectorDisown(Node *n) {
- Node *disown = NewHash();
- String *mrename;
- String *symname = Getattr(n, "sym:name");
- mrename = Swig_name_disown(NSpace, symname);
- String *type = NewString(ClassType);
- String *name = NewString("self");
- SwigType_add_pointer(type);
- Parm *p = NewParm(type, name, n);
- Delete(name);
- Delete(type);
- type = NewString("void");
- String *action = NewString("");
- Printv(action, "{\n", "Swig::Director *director = SWIG_DIRECTOR_CAST(arg1);\n", "if (director) director->swig_disown();\n", "}\n", NULL);
- Setfile(disown, Getfile(n));
- Setline(disown, Getline(n));
- Setattr(disown, "wrap:action", action);
- Setattr(disown, "name", mrename);
- Setattr(disown, "sym:name", mrename);
- Setattr(disown, "type", type);
- Setattr(disown, "parms", p);
- Delete(action);
- Delete(mrename);
- Delete(type);
- Delete(p);
-
- functionWrapper(disown);
- Delete(disown);
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::classDirectorConstructors()
- * ---------------------------------------------------------------------- */
-
-int Language::classDirectorConstructors(Node *n) {
- Node *ni;
- String *nodeType;
- Node *parent = Swig_methodclass(n);
- int default_ctor = Getattr(parent, "allocate:default_constructor") ? 1 : 0;
- int protected_ctor = 0;
- int constructor = 0;
-
- /* emit constructors */
- for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
- nodeType = Getattr(ni, "nodeType");
- if (Cmp(nodeType, "constructor") == 0) {
- if (GetFlag(ni, "feature:ignore"))
- continue;
-
- Parm *parms = Getattr(ni, "parms");
- if (is_public(ni)) {
- /* emit public constructor */
- classDirectorConstructor(ni);
- constructor = 1;
- if (default_ctor)
- default_ctor = !ParmList_numrequired(parms);
- } else {
- /* emit protected constructor if needed */
- if (need_nonpublic_ctor(ni)) {
- classDirectorConstructor(ni);
- constructor = 1;
- protected_ctor = 1;
- if (default_ctor)
- default_ctor = !ParmList_numrequired(parms);
- }
- }
- }
- }
- /* emit default constructor if needed */
- if (!constructor) {
- if (!default_ctor) {
- /* we get here because the class has no public, protected or
- default constructor, therefore, the director class can't be
- created, ie, is kind of abstract. */
- Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n), "Director class '%s' can't be constructed\n", SwigType_namestr(Getattr(n, "name")));
- return SWIG_OK;
- }
- classDirectorDefaultConstructor(n);
- default_ctor = 1;
- }
- /* this is just to support old java behavior, ie, the default
- constructor is always emitted, even when protected, and not
- needed, since there is a public constructor already defined.
-
- (scottm) This code is needed here to make the director_abstract +
- test generate compilable code (Example2 in director_abstract.i).
-
- (mmatus) This is very strange, since swig compiled with gcc3.2.3
- doesn't need it here....
- */
- if (!default_ctor && !protected_ctor) {
- if (Getattr(parent, "allocate:default_base_constructor")) {
- classDirectorDefaultConstructor(n);
- }
- }
-
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::classDirectorMethods()
- * ---------------------------------------------------------------------- */
-
-int Language::classDirectorMethods(Node *n) {
- Node *vtable = Getattr(n, "vtable");
-
- int len = Len(vtable);
- for (int i = 0; i < len; i++) {
- Node *item = Getitem(vtable, i);
- String *method = Getattr(item, "methodNode");
- String *fqdname = Getattr(item, "fqdname");
- if (GetFlag(method, "feature:nodirector") || GetFlag(method, "final"))
- continue;
-
- String *wrn = Getattr(method, "feature:warnfilter");
- if (wrn)
- Swig_warnfilter(wrn, 1);
-
- String *type = Getattr(method, "nodeType");
- if (!Cmp(type, "destructor")) {
- classDirectorDestructor(method);
- } else {
- Swig_require("classDirectorMethods", method, "*type", NIL);
- assert(Getattr(method, "returntype"));
- Setattr(method, "type", Getattr(method, "returntype"));
- if (classDirectorMethod(method, n, fqdname) == SWIG_OK)
- SetFlag(item, "director");
- Swig_restore(method);
- }
- if (wrn)
- Swig_warnfilter(wrn, 0);
- }
-
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::classDirectorInit()
- * ---------------------------------------------------------------------- */
-
-int Language::classDirectorInit(Node *n) {
- (void) n;
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::classDirectorDestructor()
- * ---------------------------------------------------------------------- */
-
-int Language::classDirectorDestructor(Node *n) {
- /*
- Always emit the virtual destructor in the declaration and in the
- compilation unit. Been explicit here can't make any damage, and
- can solve some nasty C++ compiler problems.
- */
- File *f_directors = Swig_filebyname("director");
- File *f_directors_h = Swig_filebyname("director_h");
- if (Getattr(n, "throw")) {
- Printf(f_directors_h, " virtual ~%s() throw();\n", DirectorClassName);
- Printf(f_directors, "%s::~%s() throw() {\n}\n\n", DirectorClassName, DirectorClassName);
- } else {
- Printf(f_directors_h, " virtual ~%s();\n", DirectorClassName);
- Printf(f_directors, "%s::~%s() {\n}\n\n", DirectorClassName, DirectorClassName);
- }
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::classDirectorEnd()
- * ---------------------------------------------------------------------- */
-
-int Language::classDirectorEnd(Node *n) {
- (void) n;
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::classDirector()
- * ---------------------------------------------------------------------- */
-
-int Language::classDirector(Node *n) {
- Node *module = Getattr(n, "module");
- String *classtype = Getattr(n, "classtype");
- Hash *directormap = 0;
- if (module) {
- directormap = Getattr(module, "wrap:directormap");
- if (directormap == 0) {
- directormap = NewHash();
- Setattr(module, "wrap:directormap", directormap);
- }
- }
- List *vtable = NewList();
- int virtual_destructor = 0;
- unrollVirtualMethods(n, n, vtable, virtual_destructor);
-
- // Emit all the using base::member statements for non virtual members (allprotected mode)
- Node *ni;
- String *using_protected_members_code = NewString("");
- for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
- Node *nodeType = Getattr(ni, "nodeType");
- if (Cmp(nodeType, "destructor") == 0 && GetFlag(ni, "final")) {
- String *classtype = Getattr(n, "classtype");
- SWIG_WARN_NODE_BEGIN(ni);
- Swig_warning(WARN_LANG_DIRECTOR_FINAL, input_file, line_number, "Destructor %s is final, %s cannot be a director class.\n", Swig_name_decl(ni), classtype);
- SWIG_WARN_NODE_END(ni);
- SetFlag(n, "feature:nodirector");
- Delete(vtable);
- Delete(using_protected_members_code);
- return SWIG_OK;
- }
- bool cdeclaration = (Cmp(nodeType, "cdecl") == 0);
- if (cdeclaration && !GetFlag(ni, "feature:ignore")) {
- if (isNonVirtualProtectedAccess(ni)) {
- Node *overloaded = Getattr(ni, "sym:overloaded");
- // emit the using base::member statement (but only once if the method is overloaded)
- if (!overloaded || (overloaded && (overloaded == ni)))
- Printf(using_protected_members_code, " using %s::%s;\n", SwigType_namestr(ClassName), Getattr(ni, "name"));
- }
- }
- }
-
- if (virtual_destructor || Len(vtable) > 0) {
- if (!virtual_destructor) {
- String *classtype = Getattr(n, "classtype");
- Swig_warning(WARN_LANG_DIRECTOR_VDESTRUCT, input_file, line_number, "Director base class %s has no virtual destructor.\n", classtype);
- }
-
- Setattr(n, "vtable", vtable);
- if (directormap != 0) {
- Setattr(directormap, classtype, n);
- }
- classDirectorInit(n);
- classDirectorConstructors(n);
- classDirectorMethods(n);
-
- File *f_directors_h = Swig_filebyname("director_h");
- Printv(f_directors_h, using_protected_members_code, NIL);
-
- classDirectorEnd(n);
- }
- Delete(vtable);
- Delete(using_protected_members_code);
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::classDeclaration()
- * ---------------------------------------------------------------------- */
-
-static void addCopyConstructor(Node *n) {
- Node *cn = NewHash();
- set_nodeType(cn, "constructor");
- Setattr(cn, "access", "public");
- Setfile(cn, Getfile(n));
- Setline(cn, Getline(n));
-
- String *cname = Getattr(n, "name");
- SwigType *type = Copy(cname);
- String *name = Swig_scopename_last(cname);
- String *cc = NewStringf("r.q(const).%s", type);
- String *decl = NewStringf("f(%s).", cc);
- String *oldname = Getattr(n, "sym:name");
-
- if (Getattr(n, "allocate:has_constructor")) {
- // to work properly with '%rename Class', we must look
- // for any other constructor in the class, which has not been
- // renamed, and use its name as oldname.
- Node *c;
- for (c = firstChild(n); c; c = nextSibling(c)) {
- const char *tag = Char(nodeType(c));
- if (strcmp(tag, "constructor") == 0) {
- String *cname = Getattr(c, "name");
- String *csname = Getattr(c, "sym:name");
- String *clast = Swig_scopename_last(cname);
- if (Equal(csname, clast)) {
- oldname = csname;
- break;
- }
- }
- }
- }
-
- String *symname = Swig_name_make(cn, cname, name, decl, oldname);
- if (Strcmp(symname, "$ignore") != 0) {
- Parm *p = NewParm(cc, "other", n);
-
- Setattr(cn, "name", name);
- Setattr(cn, "sym:name", symname);
- SetFlag(cn, "feature:new");
- Setattr(cn, "decl", decl);
- Setattr(cn, "parentNode", n);
- Setattr(cn, "parms", p);
- Setattr(cn, "copy_constructor", "1");
-
- Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
- Node *on = Swig_symbol_add(symname, cn);
- Swig_features_get(Swig_cparse_features(), Swig_symbol_qualifiedscopename(0), name, decl, cn);
- Swig_symbol_setscope(oldscope);
-
- if (on == cn) {
- Node *access = NewHash();
- set_nodeType(access, "access");
- Setattr(access, "kind", "public");
- appendChild(n, access);
- appendChild(n, cn);
- Setattr(n, "has_copy_constructor", "1");
- Setattr(n, "copy_constructor_decl", decl);
- Setattr(n, "allocate:copy_constructor", "1");
- Delete(access);
- }
- }
- Delete(cn);
- Delete(name);
- Delete(decl);
- Delete(symname);
-}
-
-static void addDefaultConstructor(Node *n) {
- Node *cn = NewHash();
- set_nodeType(cn, "constructor");
- Setattr(cn, "access", "public");
- Setfile(cn, Getfile(n));
- Setline(cn, Getline(n));
-
- String *cname = Getattr(n, "name");
- String *name = Swig_scopename_last(cname);
- String *decl = NewString("f().");
- String *oldname = Getattr(n, "sym:name");
- String *symname = Swig_name_make(cn, cname, name, decl, oldname);
- if (Strcmp(symname, "$ignore") != 0) {
- Setattr(cn, "name", name);
- Setattr(cn, "sym:name", symname);
- SetFlag(cn, "feature:new");
- Setattr(cn, "decl", decl);
- Setattr(cn, "parentNode", n);
- Setattr(cn, "default_constructor", "1");
- Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
- Node *on = Swig_symbol_add(symname, cn);
- Swig_features_get(Swig_cparse_features(), Swig_symbol_qualifiedscopename(0), name, decl, cn);
- Swig_symbol_setscope(oldscope);
-
- if (on == cn) {
- Node *access = NewHash();
- set_nodeType(access, "access");
- Setattr(access, "kind", "public");
- appendChild(n, access);
- appendChild(n, cn);
- Setattr(n, "has_default_constructor", "1");
- Setattr(n, "allocate:default_constructor", "1");
- Delete(access);
- }
- }
- Delete(cn);
- Delete(name);
- Delete(decl);
- Delete(symname);
-}
-
-static void addDestructor(Node *n) {
- Node *cn = NewHash();
- set_nodeType(cn, "destructor");
- Setattr(cn, "access", "public");
- Setfile(cn, Getfile(n));
- Setline(cn, Getline(n));
-
- String *cname = Getattr(n, "name");
- String *name = Swig_scopename_last(cname);
- Insert(name, 0, "~");
- String *decl = NewString("f().");
- String *symname = Swig_name_make(cn, cname, name, decl, 0);
- if (Strcmp(symname, "$ignore") != 0) {
- String *possible_nonstandard_symname = NewStringf("~%s", Getattr(n, "sym:name"));
-
- Setattr(cn, "name", name);
- Setattr(cn, "sym:name", symname);
- Setattr(cn, "decl", "f().");
- Setattr(cn, "parentNode", n);
-
- Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
- Node *nonstandard_destructor = Equal(possible_nonstandard_symname, symname) ? 0 : Swig_symbol_clookup(possible_nonstandard_symname, 0);
- Node *on = Swig_symbol_add(symname, cn);
- Swig_features_get(Swig_cparse_features(), Swig_symbol_qualifiedscopename(0), name, decl, cn);
- Swig_symbol_setscope(oldscope);
-
- if (on == cn) {
- // SWIG accepts a non-standard named destructor in %extend that uses a typedef for the destructor name
- // For example: typedef struct X {} XX; %extend X { ~XX() {...} }
- // Don't add another destructor if a nonstandard one has been declared
- if (!nonstandard_destructor) {
- Node *access = NewHash();
- set_nodeType(access, "access");
- Setattr(access, "kind", "public");
- appendChild(n, access);
- appendChild(n, cn);
- Setattr(n, "has_destructor", "1");
- Setattr(n, "allocate:destructor", "1");
- Delete(access);
- }
- }
- Delete(possible_nonstandard_symname);
- }
- Delete(cn);
- Delete(name);
- Delete(decl);
- Delete(symname);
-}
-
-int Language::classDeclaration(Node *n) {
- String *ochildren = Getattr(n, "feature:onlychildren");
- if (ochildren) {
- Setattr(n, "feature:emitonlychildren", ochildren);
- emit_children(n);
- Delattr(n, "feature:emitonlychildren");
- SetFlag(n, "feature:ignore");
- return SWIG_NOWRAP;
- }
-
- // save class local variables for nested classes support
- int oldInClass = InClass;
- String *oldClassType = ClassType;
- String *oldClassPrefix = ClassPrefix;
- String *oldEnumClassPrefix = EnumClassPrefix;
- String *oldClassName = ClassName;
- String *oldDirectorClassName = DirectorClassName;
- String *oldNSpace = NSpace;
- Node *oldCurrentClass = CurrentClass;
- int dir = 0;
-
- String *kind = Getattr(n, "kind");
- String *name = Getattr(n, "name");
- String *tdname = Getattr(n, "tdname");
- String *unnamed = Getattr(n, "unnamed");
- String *symname = Getattr(n, "sym:name");
-
- int strip = CPlusPlus ? 1 : unnamed && tdname;
-
- if (cplus_mode != PUBLIC)
- return SWIG_NOWRAP;
- if (!name) {
- Swig_warning(WARN_LANG_CLASS_UNNAMED, input_file, line_number, "Can't generate wrappers for unnamed struct/class.\n");
- return SWIG_NOWRAP;
- }
-
- /* Check symbol name for template. If not renamed. Issue a warning */
- if (!validIdentifier(symname)) {
- Swig_warning(WARN_LANG_IDENTIFIER, input_file, line_number, "Can't wrap class %s unless renamed to a valid identifier.\n", SwigType_namestr(symname));
- return SWIG_NOWRAP;
- }
- AccessMode oldAccessMode = cplus_mode;
- Node *outerClass = Getattr(n, "nested:outer");
- if (outerClass && oldAccessMode != PUBLIC)
- return SWIG_NOWRAP;
- ClassName = Copy(name);
- ClassPrefix = Copy(symname);
- if (Cmp(kind, "class") == 0) {
- cplus_mode = PRIVATE;
- } else {
- cplus_mode = PUBLIC;
- }
- for (; outerClass; outerClass = Getattr(outerClass, "nested:outer")) {
- Push(ClassPrefix, "_");
- Push(ClassPrefix, Getattr(outerClass, "sym:name"));
- }
- EnumClassPrefix = Copy(ClassPrefix);
- if (strip) {
- ClassType = Copy(name);
- } else {
- ClassType = NewStringf("%s %s", kind, name);
- }
- Setattr(n, "classtypeobj", Copy(ClassType));
- Setattr(n, "classtype", SwigType_namestr(ClassType));
-
- InClass = 1;
- CurrentClass = n;
- NSpace = Getattr(n, "sym:nspace");
- int oldAbstract = Abstract;
-
- /* Call classHandler() here */
- if (!ImportMode) {
- if (directorsEnabled()) {
- int ndir = GetFlag(n, "feature:director");
- int nndir = GetFlag(n, "feature:nodirector");
- /* 'nodirector' has precedence over 'director' */
- dir = (ndir || nndir) ? (ndir && !nndir) : 0;
- }
- int abstract = !dir && abstractClassTest(n);
- int odefault = (GenerateDefault && !GetFlag(n, "feature:nodefault"));
-
- /* default constructor */
- if (!abstract && !GetFlag(n, "feature:nodefaultctor") && odefault) {
- if (!Getattr(n, "has_constructor") && !Getattr(n, "allocate:has_constructor") && (Getattr(n, "allocate:default_constructor"))) {
- addDefaultConstructor(n);
- }
- }
- /* copy constructor */
- if (CPlusPlus && !abstract && GetFlag(n, "feature:copyctor")) {
- if (!Getattr(n, "has_copy_constructor") && !Getattr(n, "allocate:has_copy_constructor")
- && (Getattr(n, "allocate:copy_constructor"))
- && (!GetFlag(n, "feature:ignore"))) {
- addCopyConstructor(n);
- }
- }
- /* default destructor */
- if (!GetFlag(n, "feature:nodefaultdtor") && odefault) {
- if (!Getattr(n, "has_destructor") && (!Getattr(n, "allocate:has_destructor"))
- && (Getattr(n, "allocate:default_destructor"))
- && (!GetFlag(n, "feature:ignore"))) {
- addDestructor(n);
- }
- }
-
- if (dir) {
- DirectorClassName = directorClassName(n);
- classDirector(n);
- }
- /* check for abstract after resolving directors */
-
- Abstract = abstractClassTest(n);
- classHandler(n);
- } else {
- Abstract = abstractClassTest(n);
- Language::classHandler(n);
- }
-
- Abstract = oldAbstract;
- cplus_mode = oldAccessMode;
- NSpace = oldNSpace;
- InClass = oldInClass;
- CurrentClass = oldCurrentClass;
- Delete(ClassType);
- ClassType = oldClassType;
- Delete(EnumClassPrefix);
- EnumClassPrefix = oldEnumClassPrefix;
- Delete(ClassPrefix);
- ClassPrefix = oldClassPrefix;
- Delete(ClassName);
- ClassName = oldClassName;
- if (dir) {
- Delete(DirectorClassName);
- }
- DirectorClassName = oldDirectorClassName;
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::classHandler()
- * ---------------------------------------------------------------------- */
-
-int Language::classHandler(Node *n) {
- save_value<int> oldExtend(Extend);
- if (Getattr(n, "template"))
- Extend = 0;
- bool hasDirector = Swig_directorclass(n) ? true : false;
-
- /* Emit all of the class members */
- emit_children(n);
-
- /* Look for smart pointer handling */
- if (Getattr(n, "allocate:smartpointer")) {
- List *methods = Getattr(n, "allocate:smartpointer");
- cplus_mode = PUBLIC;
- SmartPointer = CWRAP_SMART_POINTER;
- if (Getattr(n, "allocate:smartpointerconst") && Getattr(n, "allocate:smartpointermutable")) {
- SmartPointer |= CWRAP_SMART_POINTER_OVERLOAD;
- }
- Iterator c;
- for (c = First(methods); c.item; c = Next(c)) {
- emit_one(c.item);
- }
- SmartPointer = 0;
- }
-
- cplus_mode = PUBLIC;
-
- /* emit director disown method */
- if (hasDirector) {
- classDirectorDisown(n);
-
- /* Emit additional protected virtual methods - only needed if the language module
- * codes logic in the C++ layer instead of the director proxy class method - primarily
- * to catch public use of protected methods by the scripting languages. */
- if (dirprot_mode() && extraDirectorProtectedCPPMethodsRequired()) {
- Node *vtable = Getattr(n, "vtable");
- String *symname = Getattr(n, "sym:name");
- save_value<AccessMode> old_mode(cplus_mode);
- cplus_mode = PROTECTED;
- int len = Len(vtable);
- for (int i = 0; i < len; i++) {
- Node *item = Getitem(vtable, i);
- Node *method = Getattr(item, "methodNode");
- SwigType *type = Getattr(method, "nodeType");
- if (Strcmp(type, "cdecl") != 0)
- continue;
- if (GetFlag(method, "feature:ignore"))
- continue;
- String *methodname = Getattr(method, "sym:name");
- String *wrapname = NewStringf("%s_%s", symname, methodname);
- if (!symbolLookup(wrapname, "") && (!is_public(method))) {
- Node *m = Copy(method);
- Setattr(m, "director", "1");
- Setattr(m, "parentNode", n);
- /*
- * There is a bug that needs fixing still...
- * This area of code is creating methods which have not been overridden in a derived class (director methods that are protected in the base)
- * If the method is overloaded, then Swig_overload_dispatch() incorrectly generates a call to the base wrapper, _wrap_xxx method
- * See director_protected_overloaded.i - Possibly sym:overname needs correcting here.
- Printf(stdout, "new method: %s::%s(%s)\n", Getattr(parentNode(m), "name"), Getattr(m, "name"), ParmList_str_defaultargs(Getattr(m, "parms")));
- */
- cDeclaration(m);
- Delete(m);
- }
- Delete(wrapname);
- }
- }
- }
-
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::classforwardDeclaration()
- * ---------------------------------------------------------------------- */
-
-int Language::classforwardDeclaration(Node *n) {
- (void) n;
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::constructorDeclaration()
- * ---------------------------------------------------------------------- */
-
-int Language::constructorDeclaration(Node *n) {
- String *name = Getattr(n, "name");
- String *symname = Getattr(n, "sym:name");
-
- if (!symname)
- return SWIG_NOWRAP;
- if (!CurrentClass)
- return SWIG_NOWRAP;
- if (ImportMode)
- return SWIG_NOWRAP;
-
- if (Extend) {
- /* extend default constructor can be safely ignored if there is already one */
- int num_required = ParmList_numrequired(Getattr(n, "parms"));
- if ((num_required == 0) && Getattr(CurrentClass, "has_default_constructor")) {
- return SWIG_NOWRAP;
- }
- if ((num_required == 1) && Getattr(CurrentClass, "has_copy_constructor")) {
- String *ccdecl = Getattr(CurrentClass, "copy_constructor_decl");
- if (ccdecl && (Strcmp(ccdecl, Getattr(n, "decl")) == 0)) {
- return SWIG_NOWRAP;
- }
- }
- }
-
- /* clean protected overloaded constructors, in case they are not needed anymore */
- Node *over = Swig_symbol_isoverloaded(n);
- if (over && !Getattr(CurrentClass, "sym:cleanconstructor")) {
- int dirclass = Swig_directorclass(CurrentClass);
- Node *nn = over;
- while (nn) {
- if (!is_public(nn)) {
- if (!dirclass || !need_nonpublic_ctor(nn)) {
- SetFlag(nn, "feature:ignore");
- }
- }
- nn = Getattr(nn, "sym:nextSibling");
- }
- clean_overloaded(over);
- Setattr(CurrentClass, "sym:cleanconstructor", "1");
- }
-
- if ((cplus_mode != PUBLIC)) {
- /* check only for director classes */
- if (!Swig_directorclass(CurrentClass) || !need_nonpublic_ctor(n))
- return SWIG_NOWRAP;
- }
-
- /* Name adjustment for %name */
- Swig_save("constructorDeclaration", n, "sym:name", NIL);
-
- {
- String *base = Swig_scopename_last(name);
- if ((Strcmp(base, symname) == 0) && (Strcmp(symname, ClassPrefix) != 0)) {
- Setattr(n, "sym:name", ClassPrefix);
- }
- Delete(base);
- }
-
- /* Only create a constructor if the class is not abstract */
- if (!Abstract) {
- Node *over;
- over = Swig_symbol_isoverloaded(n);
- if (over)
- over = first_nontemplate(over);
- if ((over) && (!overloading)) {
- /* If the symbol is overloaded. We check to see if it is a copy constructor. If so,
- we invoke copyconstructorHandler() as a special case. */
- if (Getattr(n, "copy_constructor") && (!Getattr(CurrentClass, "has_copy_constructor"))) {
- copyconstructorHandler(n);
- Setattr(CurrentClass, "has_copy_constructor", "1");
- } else {
- if (Getattr(over, "copy_constructor"))
- over = Getattr(over, "sym:nextSibling");
- if (over != n) {
- Swig_warning(WARN_LANG_OVERLOAD_CONSTRUCT, input_file, line_number,
- "Overloaded constructor ignored. %s\n", Swig_name_decl(n));
- Swig_warning(WARN_LANG_OVERLOAD_CONSTRUCT, Getfile(over), Getline(over),
- "Previous declaration is %s\n", Swig_name_decl(over));
- } else {
- constructorHandler(n);
- }
- }
- } else {
- String *expected_name = ClassName;
- String *scope = Swig_scopename_check(ClassName) ? Swig_scopename_prefix(ClassName) : 0;
- String *actual_name = scope ? NewStringf("%s::%s", scope, name) : NewString(name);
- Delete(scope);
- if (!Equal(actual_name, expected_name) && !SwigType_istemplate(expected_name) && !SwigType_istemplate(actual_name)) {
- // Checking templates is skipped but they ought to be checked... they are just somewhat more tricky to check correctly
- bool illegal_name = true;
- if (Extend) {
- // Check for typedef names used as a constructor name in %extend. This is deprecated except for anonymous
- // typedef structs which have had their symbol names adjusted to the typedef name in the parser.
- SwigType *name_resolved = SwigType_typedef_resolve_all(actual_name);
- SwigType *expected_name_resolved = SwigType_typedef_resolve_all(expected_name);
-
- if (!CPlusPlus) {
- if (Strncmp(name_resolved, "struct ", 7) == 0)
- Replace(name_resolved, "struct ", "", DOH_REPLACE_FIRST);
- else if (Strncmp(name_resolved, "union ", 6) == 0)
- Replace(name_resolved, "union ", "", DOH_REPLACE_FIRST);
- }
-
- illegal_name = !Equal(name_resolved, expected_name_resolved);
- if (!illegal_name)
- Swig_warning(WARN_LANG_EXTEND_CONSTRUCTOR, input_file, line_number, "Use of an illegal constructor name '%s' in %%extend is deprecated, the constructor name should be '%s'.\n",
- SwigType_str(Swig_scopename_last(actual_name), 0), SwigType_str(Swig_scopename_last(expected_name), 0));
- Delete(name_resolved);
- Delete(expected_name_resolved);
- }
- if (illegal_name) {
- Swig_warning(WARN_LANG_RETURN_TYPE, input_file, line_number, "Function %s must have a return type. Ignored.\n", Swig_name_decl(n));
- Swig_restore(n);
- return SWIG_NOWRAP;
- }
- }
- constructorHandler(n);
- }
- }
- Setattr(CurrentClass, "has_constructor", "1");
-
- Swig_restore(n);
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * get_director_ctor_code()
- * ---------------------------------------------------------------------- */
-
-static String *get_director_ctor_code(Node *n, String *director_ctor_code, String *director_prot_ctor_code, List *&abstracts) {
- String *director_ctor = director_ctor_code;
- int use_director = Swig_directorclass(n);
- if (use_director) {
- Node *pn = Swig_methodclass(n);
- abstracts = Getattr(pn, "abstracts");
- if (director_prot_ctor_code) {
- int is_notabstract = GetFlag(pn, "feature:notabstract");
- int is_abstract = abstracts && !is_notabstract;
- if (is_protected(n) || is_abstract) {
- director_ctor = director_prot_ctor_code;
- abstracts = Copy(abstracts);
- Delattr(pn, "abstracts");
- } else {
- if (is_notabstract) {
- abstracts = Copy(abstracts);
- Delattr(pn, "abstracts");
- } else {
- abstracts = 0;
- }
- }
- }
- }
- return director_ctor;
-}
-
-
-/* ----------------------------------------------------------------------
- * Language::constructorHandler()
- * ---------------------------------------------------------------------- */
-
-int Language::constructorHandler(Node *n) {
- Swig_require("constructorHandler", n, "?name", "*sym:name", "?type", "?parms", NIL);
- String *symname = Getattr(n, "sym:name");
- String *mrename = Swig_name_construct(NSpace, symname);
- String *nodeType = Getattr(n, "nodeType");
- int constructor = (!Cmp(nodeType, "constructor"));
- List *abstracts = 0;
- String *director_ctor = get_director_ctor_code(n, director_ctor_code,
- director_prot_ctor_code,
- abstracts);
- if (!constructor) {
- /* if not originally a constructor, still handle it as one */
- Setattr(n, "handled_as_constructor", "1");
- }
-
- int extendmember = GetFlag(n, "isextendmember") ? Extend : 0;
- int flags = Getattr(n, "template") ? extendmember : Extend;
- Swig_ConstructorToFunction(n, NSpace, ClassType, none_comparison, director_ctor, CPlusPlus, flags, DirectorClassName);
- Setattr(n, "sym:name", mrename);
- functionWrapper(n);
- Delete(mrename);
- Swig_restore(n);
- if (abstracts)
- Setattr(Swig_methodclass(n), "abstracts", abstracts);
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::copyconstructorHandler()
- * ---------------------------------------------------------------------- */
-
-int Language::copyconstructorHandler(Node *n) {
- Swig_require("copyconstructorHandler", n, "?name", "*sym:name", "?type", "?parms", NIL);
- String *symname = Getattr(n, "sym:name");
- String *mrename = Swig_name_copyconstructor(NSpace, symname);
- List *abstracts = 0;
- String *director_ctor = get_director_ctor_code(n, director_ctor_code,
- director_prot_ctor_code,
- abstracts);
- Swig_ConstructorToFunction(n, NSpace, ClassType, none_comparison, director_ctor, CPlusPlus, Getattr(n, "template") ? 0 : Extend, DirectorClassName);
- Setattr(n, "sym:name", mrename);
- functionWrapper(n);
- Delete(mrename);
- Swig_restore(n);
- if (abstracts)
- Setattr(Swig_methodclass(n), "abstracts", abstracts);
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::destructorDeclaration()
- * ---------------------------------------------------------------------- */
-
-int Language::destructorDeclaration(Node *n) {
-
- if (!CurrentClass)
- return SWIG_NOWRAP;
- if (cplus_mode != PUBLIC && !Getattr(CurrentClass, "feature:unref"))
- return SWIG_NOWRAP;
- if (ImportMode)
- return SWIG_NOWRAP;
-
- Swig_save("destructorDeclaration", n, "name", "sym:name", NIL);
-
- char *c = GetChar(n, "sym:name");
- if (c && (*c == '~')) {
- Setattr(n, "sym:name", c + 1);
- }
-
- String *name = Getattr(n, "name");
- String *symname = Getattr(n, "sym:name");
-
- if ((Strcmp(name, symname) == 0) || (Strcmp(symname, ClassPrefix) != 0)) {
- Setattr(n, "sym:name", ClassPrefix);
- }
-
- String *expected_name = ClassName;
- String *scope = Swig_scopename_check(ClassName) ? Swig_scopename_prefix(ClassName) : 0;
- String *actual_name = scope ? NewStringf("%s::%s", scope, name) : NewString(name);
- Delete(scope);
- Replace(actual_name, "~", "", DOH_REPLACE_FIRST);
- if (!Equal(actual_name, expected_name) && !(Getattr(n, "template"))) {
- bool illegal_name = true;
- if (Extend) {
- // Check for typedef names used as a destructor name in %extend. This is deprecated except for anonymous
- // typedef structs which have had their symbol names adjusted to the typedef name in the parser.
- SwigType *name_resolved = SwigType_typedef_resolve_all(actual_name);
- SwigType *expected_name_resolved = SwigType_typedef_resolve_all(expected_name);
-
- if (!CPlusPlus) {
- if (Strncmp(name_resolved, "struct ", 7) == 0)
- Replace(name_resolved, "struct ", "", DOH_REPLACE_FIRST);
- else if (Strncmp(name_resolved, "union ", 6) == 0)
- Replace(name_resolved, "union ", "", DOH_REPLACE_FIRST);
- }
-
- illegal_name = !Equal(name_resolved, expected_name_resolved);
- if (!illegal_name)
- Swig_warning(WARN_LANG_EXTEND_DESTRUCTOR, input_file, line_number, "Use of an illegal destructor name '%s' in %%extend is deprecated, the destructor name should be '%s'.\n",
- SwigType_str(Swig_scopename_last(actual_name), 0), SwigType_str(Swig_scopename_last(expected_name), 0));
- Delete(name_resolved);
- Delete(expected_name_resolved);
- }
-
- if (illegal_name) {
- Swig_warning(WARN_LANG_ILLEGAL_DESTRUCTOR, input_file, line_number, "Illegal destructor name %s. Ignored.\n", Swig_name_decl(n));
- Swig_restore(n);
- return SWIG_NOWRAP;
- }
- }
- destructorHandler(n);
-
- Setattr(CurrentClass, "has_destructor", "1");
- Swig_restore(n);
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::destructorHandler()
- * ---------------------------------------------------------------------- */
-
-int Language::destructorHandler(Node *n) {
- Swig_require("destructorHandler", n, "?name", "*sym:name", NIL);
- Swig_save("destructorHandler", n, "type", "parms", NIL);
-
- String *symname = Getattr(n, "sym:name");
- String *mrename;
- char *csymname = Char(symname);
- if (*csymname == '~')
- csymname += 1;
-
- mrename = Swig_name_destroy(NSpace, csymname);
-
- Swig_DestructorToFunction(n, NSpace, ClassType, CPlusPlus, Extend);
- Setattr(n, "sym:name", mrename);
- functionWrapper(n);
- Delete(mrename);
- Swig_restore(n);
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::accessDeclaration()
- * ---------------------------------------------------------------------- */
-
-int Language::accessDeclaration(Node *n) {
- String *kind = Getattr(n, "kind");
- if (Cmp(kind, "public") == 0) {
- cplus_mode = PUBLIC;
- } else if (Cmp(kind, "private") == 0) {
- cplus_mode = PRIVATE;
- } else if (Cmp(kind, "protected") == 0) {
- cplus_mode = PROTECTED;
- }
- return SWIG_OK;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::namespaceDeclaration()
- * ----------------------------------------------------------------------------- */
-
-int Language::namespaceDeclaration(Node *n) {
- if (Getattr(n, "alias"))
- return SWIG_OK;
- if (Getattr(n, "unnamed"))
- return SWIG_OK;
- emit_children(n);
- return SWIG_OK;
-}
-
-int Language::validIdentifier(String *s) {
- char *c = Char(s);
- while (*c) {
- if (!(isalnum(*c) || (*c == '_')))
- return 0;
- c++;
- }
- return 1;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::usingDeclaration()
- * ----------------------------------------------------------------------------- */
-
-int Language::usingDeclaration(Node *n) {
- if ((cplus_mode == PUBLIC) || (!is_public(n) && dirprot_mode())) {
- Node *np = Copy(n);
- Node *c;
- for (c = firstChild(np); c; c = nextSibling(c)) {
- /* it seems for some cases this is needed, like A* A::boo() */
- if (CurrentClass)
- Setattr(c, "parentNode", CurrentClass);
- emit_one(c);
- }
- Delete(np);
- }
- return SWIG_OK;
-}
-
-/* Stubs. Language modules need to implement these */
-
-/* ----------------------------------------------------------------------
- * Language::constantWrapper()
- * ---------------------------------------------------------------------- */
-
-int Language::constantWrapper(Node *n) {
- String *name = Getattr(n, "sym:name");
- SwigType *type = Getattr(n, "type");
- String *value = Getattr(n, "value");
- String *str = SwigType_str(type, name);
- Printf(stdout, "constantWrapper : %s = %s\n", str, value);
- Delete(str);
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::variableWrapper()
- * ---------------------------------------------------------------------- */
-
-int Language::variableWrapper(Node *n) {
- Swig_require("variableWrapper", n, "*name", "*sym:name", "*type", "?parms", "?varset", "?varget", NIL);
- String *symname = Getattr(n, "sym:name");
- SwigType *type = Getattr(n, "type");
- String *name = Getattr(n, "name");
-
- Delattr(n,"varset");
- Delattr(n,"varget");
-
- String *newsymname = 0;
- if (!CurrentClass && EnumClassPrefix) {
- newsymname = Swig_name_member(0, EnumClassPrefix, symname);
- symname = newsymname;
- }
-
- /* If no way to set variables. We simply create functions */
- int assignable = is_assignable(n);
- int flags = use_naturalvar_mode(n);
- if (!GetFlag(n, "wrappedasconstant"))
- flags = flags | Extend;
-
- if (assignable) {
- int make_set_wrapper = 1;
- String *tm = Swig_typemap_lookup("globalin", n, name, 0);
-
- Swig_VarsetToFunction(n, flags);
- String *sname = Swig_name_set(NSpace, symname);
- Setattr(n, "sym:name", sname);
- Delete(sname);
-
- if (!tm) {
- if (SwigType_isarray(type)) {
- Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(type, 0));
- make_set_wrapper = 0;
- }
- } else {
- String *pname0 = Swig_cparm_name(0, 0);
- Replace(tm, "$input", pname0, DOH_REPLACE_ANY);
- Setattr(n, "wrap:action", tm);
- Delete(tm);
- Delete(pname0);
- }
- if (make_set_wrapper) {
- Setattr(n, "varset", "1");
- functionWrapper(n);
- } else {
- SetFlag(n, "feature:immutable");
- }
- /* Restore parameters */
- Setattr(n, "sym:name", symname);
- Setattr(n, "type", type);
- Setattr(n, "name", name);
- Delattr(n, "varset");
-
- /* Delete all attached typemaps and typemap attributes */
- Iterator ki;
- for (ki = First(n); ki.key; ki = Next(ki)) {
- if (Strncmp(ki.key, "tmap:", 5) == 0)
- Delattr(n, ki.key);
- }
- }
-
- Swig_VargetToFunction(n, flags);
- String *gname = Swig_name_get(NSpace, symname);
- Setattr(n, "sym:name", gname);
- Delete(gname);
- Setattr(n, "varget", "1");
- functionWrapper(n);
- Delattr(n, "varget");
- Swig_restore(n);
- Delete(newsymname);
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * Language::functionWrapper()
- * ---------------------------------------------------------------------- */
-
-int Language::functionWrapper(Node *n) {
- String *name = Getattr(n, "sym:name");
- SwigType *type = Getattr(n, "type");
- ParmList *parms = Getattr(n, "parms");
-
- Printf(stdout, "functionWrapper : %s\n", SwigType_str(type, NewStringf("%s(%s)", name, ParmList_str_defaultargs(parms))));
- Printf(stdout, " action : %s\n", Getattr(n, "wrap:action"));
- return SWIG_OK;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::nativeWrapper()
- * ----------------------------------------------------------------------------- */
-
-int Language::nativeWrapper(Node *n) {
- (void) n;
- return SWIG_OK;
-}
-
-void Language::main(int argc, char *argv[]) {
- (void) argc;
- (void) argv;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::addSymbol()
- *
- * Adds a symbol entry into the target language symbol tables.
- * Returns 1 if the symbol is added successfully.
- * Prints an error message and returns 0 if a conflict occurs.
- * The scope is optional for target languages and if supplied must be a fully
- * qualified scope and the symbol s must not contain any scope qualifiers.
- * ----------------------------------------------------------------------------- */
-
-int Language::addSymbol(const String *s, const Node *n, const_String_or_char_ptr scope) {
- //Printf( stdout, "addSymbol: %s %s\n", s, scope );
- Hash *symbols = Getattr(symtabs, scope ? scope : "");
- if (!symbols) {
- symbols = symbolAddScope(scope);
- } else {
- Node *c = Getattr(symbols, s);
- if (c && (c != n)) {
- if (scope && Len(scope) > 0)
- Swig_error(input_file, line_number, "'%s' is multiply defined in the generated target language module in scope '%s'.\n", s, scope);
- else
- Swig_error(input_file, line_number, "'%s' is multiply defined in the generated target language module.\n", s);
- Swig_error(Getfile(c), Getline(c), "Previous declaration of '%s'\n", s);
- return 0;
- }
- }
- Setattr(symbols, s, n);
- return 1;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::addInterfaceSymbol()
- *
- * Adds a symbol entry into the target language symbol tables - for the interface
- * feature only.
- * Returns 1 if the symbol is added successfully.
- * The scope is as per addSymbol.
- * ----------------------------------------------------------------------------- */
-
-int Language::addInterfaceSymbol(const String *interface_name, Node *n, const_String_or_char_ptr scope) {
- if (interface_name) {
- Node *existing_symbol = symbolLookup(interface_name, scope);
- if (existing_symbol) {
- String *proxy_class_name = Getattr(n, "sym:name");
- Swig_error(input_file, line_number, "The interface feature name '%s' for proxy class '%s' is already defined in the generated target language module in scope '%s'.\n",
- interface_name, proxy_class_name, scope);
- Swig_error(Getfile(existing_symbol), Getline(existing_symbol), "Previous declaration of '%s'\n", interface_name);
- return 0;
- }
- if (!addSymbol(interface_name, n, scope))
- return 0;
- }
- return 1;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::symbolAddScope()
- *
- * Creates a scope (symbols Hash) for given name. This method is auxiliary,
- * you don't have to call it - addSymbols will lazily create scopes automatically.
- * If scope with given name already exists, then do nothing.
- * Returns newly created (or already existing) scope.
- * ----------------------------------------------------------------------------- */
-Hash* Language::symbolAddScope(const_String_or_char_ptr scope) {
- Hash *symbols = symbolScopeLookup(scope);
- if(!symbols) {
- // The order in which the following code is executed is important. In the Language
- // constructor addScope("") is called to create a top level scope.
- // Thus we must first add a symbols hash to symtab and only then add pseudo
- // symbols to the top-level scope.
-
- // New scope which has not been added by the target language - lazily created.
- symbols = NewHash();
- Setattr(symtabs, scope, symbols);
-
- // Add the new scope as a symbol in the top level scope.
- // Alternatively the target language must add it in before attempting to add symbols into the scope.
- const_String_or_char_ptr top_scope = "";
- Hash *topscope_symbols = Getattr(symtabs, top_scope);
- Hash *pseudo_symbol = NewHash();
- Setattr(pseudo_symbol, "sym:scope", "1");
- Setattr(topscope_symbols, scope, pseudo_symbol);
- }
- return symbols;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::symbolScopeLookup()
- *
- * Lookup and returns a symtable (hash) representing given scope. Hash contains
- * all symbols in this scope.
- * ----------------------------------------------------------------------------- */
-Hash* Language::symbolScopeLookup( const_String_or_char_ptr scope ) {
- Hash *symbols = Getattr(symtabs, scope ? scope : "");
- return symbols;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::symbolScopePseudoSymbolLookup()
- *
- * For every scope there is a special pseudo-symbol in the top scope (""). It
- * exists solely to detect name clashes. This pseudo symbol may contain a few properties,
- * but more could be added. This is also true for the top level scope ("").
- * It contains a pseudo symbol with name "" (empty). Pseudo symbol contains the
- * following properties:
- * sym:scope = "1" - a flag that this is a scope pseudo symbol
- *
- * Pseudo symbols are a Hash*, not a Node*.
- * There is no difference from symbolLookup() method except for signature
- * and return type.
- * ----------------------------------------------------------------------------- */
-Hash* Language::symbolScopePseudoSymbolLookup( const_String_or_char_ptr scope )
-{
- /* Getting top scope */
- const_String_or_char_ptr top_scope = "";
- Hash *symbols = Getattr(symtabs, top_scope);
- return Getattr(symbols, scope);
-}
-
-/* -----------------------------------------------------------------------------
- * Language::dumpSymbols()
- * ----------------------------------------------------------------------------- */
-
-void Language::dumpSymbols() {
- Printf(stdout, "LANGUAGE SYMBOLS start =======================================\n");
-
- Node *table = symtabs;
- Iterator ki = First(table);
- while (ki.key) {
- String *k = ki.key;
- Printf(stdout, "===================================================\n");
- Printf(stdout, "%s -\n", k);
- {
- Symtab *symtab = Getattr(table, k);
- Iterator it = First(symtab);
- while (it.key) {
- String *symname = it.key;
- Printf(stdout, " %s\n", symname);
- it = Next(it);
- }
- }
- ki = Next(ki);
- }
-
- Printf(stdout, "LANGUAGE SYMBOLS finish =======================================\n");
-}
-
-/* -----------------------------------------------------------------------------
- * Language::symbolLookup()
- * ----------------------------------------------------------------------------- */
-
-Node *Language::symbolLookup(const String *s, const_String_or_char_ptr scope) {
- Hash *symbols = Getattr(symtabs, scope ? scope : "");
- if (!symbols) {
- return NULL;
- }
- return Getattr(symbols, s);
-}
-
-/* -----------------------------------------------------------------------------
- * Language::classLookup()
- *
- * Tries to locate a class from a type definition
- * ----------------------------------------------------------------------------- */
-
-Node *Language::classLookup(const SwigType *s) {
- static Hash *classtypes = 0;
-
- Node *n = 0;
-
- /* Look in hash of cached values */
- n = classtypes ? Getattr(classtypes, s) : 0;
- if (!n) {
- Symtab *stab = 0;
- SwigType *ty1 = SwigType_typedef_resolve_all(s);
- SwigType *ty2 = SwigType_strip_qualifiers(ty1);
-
- String *base = SwigType_base(ty2);
-
- Replaceall(base, "class ", "");
- Replaceall(base, "struct ", "");
- Replaceall(base, "union ", "");
-
- if (strncmp(Char(base), "::", 2) == 0) {
- String *oldbase = base;
- base = NewString(Char(base) + 2);
- Delete(oldbase);
- }
-
- String *prefix = SwigType_prefix(ty2);
-
- /* Do a symbol table search on the base type */
- while (!n) {
- Hash *nstab;
- n = Swig_symbol_clookup(base, stab);
- if (!n)
- break;
- if (Strcmp(nodeType(n), "class") == 0)
- break;
- Node *sibling = n;
- while (sibling) {
- sibling = Getattr(sibling, "csym:nextSibling");
- if (sibling && Strcmp(nodeType(sibling), "class") == 0)
- break;
- }
- if (sibling)
- break;
- n = parentNode(n);
- if (!n)
- break;
- nstab = Getattr(n, "sym:symtab");
- n = 0;
- if ((!nstab) || (nstab == stab)) {
- break;
- }
- stab = nstab;
- }
- if (n) {
- /* Found a match. Look at the prefix. We only allow
- the cases where we want a proxy class for the particular type */
- bool acceptable_prefix =
- (Len(prefix) == 0) || // simple type (pass by value)
- (Strcmp(prefix, "p.") == 0) || // pointer
- (Strcmp(prefix, "r.") == 0) || // reference
- (Strcmp(prefix, "z.") == 0) || // rvalue reference
- SwigType_prefix_is_simple_1D_array(prefix); // Simple 1D array (not arrays of pointers/references)
- // Also accept pointer by const reference, not non-const pointer reference
- if (!acceptable_prefix && (Strcmp(prefix, "r.p.") == 0)) {
- Delete(prefix);
- prefix = SwigType_prefix(ty1);
- acceptable_prefix = (Strncmp(prefix, "r.q(const", 9) == 0);
- }
- if (acceptable_prefix) {
- SwigType *cs = Copy(s);
- if (!classtypes)
- classtypes = NewHash();
- Setattr(classtypes, cs, n);
- Delete(cs);
- } else {
- n = 0;
- }
- }
- Delete(prefix);
- Delete(base);
- Delete(ty2);
- Delete(ty1);
- }
- if (n && (GetFlag(n, "feature:ignore") || Getattr(n, "feature:onlychildren"))) {
- n = 0;
- }
-
- return n;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::enumLookup()
- *
- * Finds and returns the Node containing the enum declaration for the (enum)
- * type passed in.
- * ----------------------------------------------------------------------------- */
-
-Node *Language::enumLookup(SwigType *s) {
- static Hash *enumtypes = 0;
-
- Node *n = 0;
-
- /* Look in hash of cached values */
- n = enumtypes ? Getattr(enumtypes, s) : 0;
- if (!n) {
- Symtab *stab = 0;
- SwigType *lt = SwigType_ltype(s);
- SwigType *ty1 = SwigType_typedef_resolve_all(lt);
- SwigType *ty2 = SwigType_strip_qualifiers(ty1);
-
- String *base = SwigType_base(ty2);
-
- Replaceall(base, "enum ", "");
- String *prefix = SwigType_prefix(ty2);
-
- if (strncmp(Char(base), "::", 2) == 0) {
- String *oldbase = base;
- base = NewString(Char(base) + 2);
- Delete(oldbase);
- }
-
- /* Look for type in symbol table */
- while (!n) {
- Hash *nstab;
- n = Swig_symbol_clookup(base, stab);
- if (!n)
- break;
- if (Equal(nodeType(n), "enum"))
- break;
- if (Equal(nodeType(n), "enumforward") && GetFlag(n, "enumMissing"))
- break;
- n = parentNode(n);
- if (!n)
- break;
- nstab = Getattr(n, "sym:symtab");
- n = 0;
- if ((!nstab) || (nstab == stab)) {
- break;
- }
- stab = nstab;
- }
- if (n) {
- /* Found a match. Look at the prefix. We only allow simple types. */
- if (Len(prefix) == 0) { /* Simple type */
- if (!enumtypes)
- enumtypes = NewHash();
- Setattr(enumtypes, Copy(s), n);
- } else {
- n = 0;
- }
- }
- Delete(prefix);
- Delete(base);
- Delete(ty2);
- Delete(ty1);
- Delete(lt);
- }
- if (n && (GetFlag(n, "feature:ignore"))) {
- n = 0;
- }
-
- return n;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::allow_overloading()
- * ----------------------------------------------------------------------------- */
-
-void Language::allow_overloading(int val) {
- overloading = val;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::allow_multiple_input()
- * ----------------------------------------------------------------------------- */
-
-void Language::allow_multiple_input(int val) {
- multiinput = val;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::enable_cplus_runtime_mode()
- * ----------------------------------------------------------------------------- */
-
-void Language::enable_cplus_runtime_mode() {
- cplus_runtime = 1;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::cplus_runtime_mode()
- * ----------------------------------------------------------------------------- */
-
-int Language::cplus_runtime_mode() {
- return cplus_runtime;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::allow_directors()
- * ----------------------------------------------------------------------------- */
-
-void Language::allow_directors(int val) {
- directors = val;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::directorsEnabled()
- * ----------------------------------------------------------------------------- */
-
-int Language::directorsEnabled() const {
- return director_language && CPlusPlus && (directors || director_mode);
-}
-
-/* -----------------------------------------------------------------------------
- * Language::allow_dirprot()
- * ----------------------------------------------------------------------------- */
-
-void Language::allow_dirprot(int val) {
- director_protected_mode = val;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::allow_allprotected()
- * ----------------------------------------------------------------------------- */
-
-void Language::allow_allprotected(int val) {
- all_protected_mode = val;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::dirprot_mode()
- * ----------------------------------------------------------------------------- */
-
-int Language::dirprot_mode() const {
- return directorsEnabled() ? director_protected_mode : 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::need_nonpublic_ctor()
- * ----------------------------------------------------------------------------- */
-
-int Language::need_nonpublic_ctor(Node *n) {
- /*
- detects when a protected constructor is needed, which is always
- the case if 'dirprot' mode is used. However, if that is not the
- case, we will try to strictly emit what is minimal to don't break
- the generated, while preserving compatibility with java, which
- always try to emit the default constructor.
-
- rules:
-
- - when dirprot mode is used, the protected constructors are
- always needed.
-
- - the protected default constructor is always needed.
-
- - if dirprot mode is not used, the protected constructors will be
- needed only if:
-
- - there is no any public constructor in the class, and
- - there is no protected default constructor
-
- In that case, all the declared protected constructors are
- needed since we don't know which one to pick up.
-
- Note: given all the complications here, I am always in favor to
- always enable 'dirprot', since is the C++ idea of protected
- members, and use %ignore for the method you don't want to add in
- the director class.
- */
- if (directorsEnabled()) {
- if (is_protected(n)) {
- if (dirprot_mode()) {
- /* when using dirprot mode, the protected constructors are
- always needed */
- return 1;
- } else {
- int is_default_ctor = !ParmList_numrequired(Getattr(n, "parms"));
- if (is_default_ctor) {
- /* the default protected constructor is always needed, for java compatibility */
- return 1;
- } else {
- /* check if there is a public constructor */
- Node *parent = Swig_methodclass(n);
- int public_ctor = Getattr(parent, "allocate:default_constructor")
- || Getattr(parent, "allocate:public_constructor");
- if (!public_ctor) {
- /* if not, the protected constructor will be needed only
- if there is no protected default constructor declared */
- int no_prot_default_ctor = !Getattr(parent, "allocate:default_base_constructor");
- return no_prot_default_ctor;
- }
- }
- }
- }
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::need_nonpublic_member()
- * ----------------------------------------------------------------------------- */
-int Language::need_nonpublic_member(Node *n) {
- if (directorsEnabled() && DirectorClassName) {
- if (is_protected(n)) {
- if (dirprot_mode()) {
- /* when using dirprot mode, the protected members are always needed. */
- return 1;
- } else {
- /* if the method is pure virtual, we need it. */
- int pure_virtual = (Cmp(Getattr(n, "value"), "0") == 0);
- return pure_virtual;
- }
- }
- }
- return 0;
-}
-
-
-/* -----------------------------------------------------------------------------
- * Language::is_smart_pointer()
- * ----------------------------------------------------------------------------- */
-
-int Language::is_smart_pointer() const {
- return SmartPointer;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::makeParameterName()
- *
- * Inputs:
- * n - Node
- * p - parameter node
- * arg_num - parameter argument number
- * setter - set this flag when wrapping variables
- * Return:
- * arg - a unique parameter name
- * ----------------------------------------------------------------------------- */
-String *Language::makeParameterName(Node *n, Parm *p, int arg_num, bool setter) const {
-
- String *arg = 0;
- String *pn = Getattr(p, "name");
-
- // Check if parameter name is a duplicate.
- int count = 0;
- ParmList *plist = Getattr(n, "parms");
- while (plist) {
- if ((Cmp(pn, Getattr(plist, "name")) == 0))
- count++;
- plist = nextSibling(plist);
- }
-
- // If the parameter has no name at all or has a non-unique name, replace it with "argN".
- if (!pn || count > 1) {
- arg = NewStringf("arg%d", arg_num);
- } else {
- // Otherwise, try to use the original C name, but modify it if necessary to avoid conflicting with the language keywords.
- arg = Swig_name_make(p, 0, pn, 0, 0);
- }
-
- if (setter && Cmp(arg, "self") != 0) {
- // Some languages (C#) insist on calling the input variable "value" while
- // others (D, Java) could, in principle, use something different but this
- // would require more work, and so we just use "value" for them too.
- // For setters the parameter name sometimes includes C++ scope resolution which needs removing.
- Delete(arg);
- arg = NewString("value");
- }
-
- return arg;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::()
- * ----------------------------------------------------------------------------- */
-
-bool Language::isNonVirtualProtectedAccess(Node *n) const {
- // Ideally is_non_virtual_protected_access() would contain all this logic, see
- // comments therein about vtable.
- return DirectorClassName && is_non_virtual_protected_access(n);
-}
-
-/* -----------------------------------------------------------------------------
- * Language::extraDirectorProtectedCPPMethodsRequired()
- * ----------------------------------------------------------------------------- */
-
-bool Language::extraDirectorProtectedCPPMethodsRequired() const {
- return true;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::nestedClassesSupport()
- * ----------------------------------------------------------------------------- */
-
-Language::NestedClassSupport Language::nestedClassesSupport() const {
- return NCS_Unknown;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::kwargsSupport()
- * ----------------------------------------------------------------------------- */
-
-bool Language::kwargsSupport() const {
- return false;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::is_wrapping_class()
- * ----------------------------------------------------------------------------- */
-
-int Language::is_wrapping_class() const {
- return InClass;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::getCurrentClass()
- * ----------------------------------------------------------------------------- */
-
-Node *Language::getCurrentClass() const {
- return CurrentClass;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::getNSpace()
- * ----------------------------------------------------------------------------- */
-
-String *Language::getNSpace() const {
- return NSpace;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::getClassName()
- * ----------------------------------------------------------------------------- */
-
-String *Language::getClassName() const {
- return ClassName;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::getClassPrefix()
- * ----------------------------------------------------------------------------- */
-
-String *Language::getClassPrefix() const {
- return ClassPrefix;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::getEnumClassPrefix()
- * ----------------------------------------------------------------------------- */
-
-String *Language::getEnumClassPrefix() const {
- return EnumClassPrefix;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::getClassType()
- * ----------------------------------------------------------------------------- */
-
-String *Language::getClassType() const {
- return ClassType;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::abstractClassTest()
- * ----------------------------------------------------------------------------- */
-//#define SWIG_DEBUG
-int Language::abstractClassTest(Node *n) {
- /* check for non public operator new */
- if (GetFlag(n, "feature:notabstract"))
- return 0;
- if (Getattr(n, "allocate:nonew"))
- return 1;
-
- // A class cannot be instantiated if one of its bases has a private destructor
- // Note that if the above does not hold the class can be instantiated if its own destructor is private
- List *bases = Getattr(n, "bases");
- if (bases) {
- for (int i = 0; i < Len(bases); i++) {
- Node *b = Getitem(bases, i);
- if (GetFlag(b, "allocate:private_destructor"))
- return 1;
- }
- }
-
- /* now check for the rest */
- List *abstracts = Getattr(n, "abstracts");
- if (!abstracts)
- return 0;
- int labs = Len(abstracts);
-#ifdef SWIG_DEBUG
- List *allbases = Getattr(n, "allbases");
- Printf(stderr, "testing %s %d %d\n", Getattr(n, "name"), labs, Len(allbases));
-#endif
- if (!labs)
- return 0; /*strange, but need to be fixed */
- if (abstracts && !directorsEnabled())
- return 1;
- if (!GetFlag(n, "feature:director"))
- return 1;
-
- Node *dirabstract = 0;
- Node *vtable = Getattr(n, "vtable");
- if (vtable) {
-#ifdef SWIG_DEBUG
- Printf(stderr, "vtable %s %d %d\n", Getattr(n, "name"), Len(vtable), labs);
-#endif
- for (int i = 0; i < labs; i++) {
- Node *ni = Getitem(abstracts, i);
- String *method_id = vtable_method_id(ni);
- if (!method_id)
- continue;
- bool exists_item = false;
- int len = Len(vtable);
- for (int i = 0; i < len; i++) {
- Node *item = Getitem(vtable, i);
- String *check_item = Getattr(item, "vmid");
- if (Strcmp(method_id, check_item) == 0) {
- exists_item = true;
- break;
- }
- }
-#ifdef SWIG_DEBUG
- Printf(stderr, "method %s %d\n", method_id, exists_item ? 1 : 0);
-#endif
- Delete(method_id);
- if (!exists_item) {
- dirabstract = ni;
- break;
- }
- }
- if (dirabstract) {
- if (is_public(dirabstract)) {
- Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n),
- "Director class '%s' is abstract, abstract method '%s' is not accessible, maybe due to multiple inheritance or 'nodirector' feature\n",
- SwigType_namestr(Getattr(n, "name")), Getattr(dirabstract, "name"));
- } else {
- Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n),
- "Director class '%s' is abstract, abstract method '%s' is private\n", SwigType_namestr(Getattr(n, "name")), Getattr(dirabstract, "name"));
- }
- return 1;
- }
- } else {
- return 1;
- }
- return 0;
-}
-
-void Language::setSubclassInstanceCheck(String *nc) {
- none_comparison = nc;
-}
-
-void Language::setOverloadResolutionTemplates(String *argc, String *argv) {
- Delete(argc_template_string);
- argc_template_string = Copy(argc);
- Delete(argv_template_string);
- argv_template_string = Copy(argv);
-}
-
-int Language::is_assignable(Node *n) {
- if (GetFlag(n, "feature:immutable"))
- return 0;
- SwigType *type = Getattr(n, "type");
- Node *cn = 0;
- SwigType *ftd = SwigType_typedef_resolve_all(type);
- SwigType *td = SwigType_strip_qualifiers(ftd);
- if (SwigType_type(td) == T_USER) {
- cn = Swig_symbol_clookup(td, 0);
- if (cn) {
- if ((Strcmp(nodeType(cn), "class") == 0)) {
- if (Getattr(cn, "allocate:noassign")) {
- SetFlag(n, "feature:immutable");
- Delete(ftd);
- Delete(td);
- return 0;
- }
- }
- }
- }
- Delete(ftd);
- Delete(td);
- return 1;
-}
-
-String *Language::runtimeCode() {
- return NewString("");
-}
-
-String *Language::defaultExternalRuntimeFilename() {
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::replaceSpecialVariables()
- *
- * Language modules should implement this if special variables are to be handled
- * correctly in the $typemap(...) special variable macro.
- * method - typemap method name
- * tm - string containing typemap contents
- * parm - a parameter describing the typemap type to be handled
- * ----------------------------------------------------------------------------- */
-void Language::replaceSpecialVariables(String *method, String *tm, Parm *parm) {
- (void)method;
- (void)tm;
- (void)parm;
-}
-
-Language *Language::instance() {
- return this_;
-}
-
-Hash *Language::getClassHash() const {
- return classhash;
-}
-
diff --git a/contrib/tools/swig/Source/Modules/lua.cxx b/contrib/tools/swig/Source/Modules/lua.cxx
deleted file mode 100644
index d3cf96b526..0000000000
--- a/contrib/tools/swig/Source/Modules/lua.cxx
+++ /dev/null
@@ -1,2240 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * lua.cxx
- *
- * Lua language module for SWIG.
- * ----------------------------------------------------------------------------- */
-
-/* NEW LANGUAGE NOTE:
- * ver001
- this is simply a copy of tcl8.cxx, which has been renamed
- * ver002
- all non essential code commented out, program now does virtually nothing
- it prints to stderr the list of functions to wrap, but does not create
- the XXX_wrap.c file
- * ver003
- added back top(), still prints the list of fns to stderr
- but now creates a rather empty XXX_wrap.c with some basic boilerplate code
- * ver004
- very basic version of functionWrapper()
- also uncommented usage_string() to keep compiler happy
- this will start producing proper looking code soon (I hope)
- produced the wrapper code, but without any type conversion (in or out)
- generates a few warning because of no wrappering
- does not generate SWIG_init()
- reason for this is that lua.swg is empty
- we will need to add code into this to make it work
- * ver005/6
- massive rework, basing work on the pike module instead of tcl
- (pike module it only 1/3 of the size)(though not as complete)
- * ver007
- added simple type checking
- * ver008
- INPUT, OUTPUT, INOUT typemaps handled (though not all types yet)
- * ver009
- class support: ok for basic types, but methods still TDB
- (code is VERY messed up & needs to be cleaned)
- * ver010
- Added support for embedded Lua. Try swig -lua -help for more information
-*/
-
-#include "swigmod.h"
-#include "cparse.h"
-
-/**** Diagnostics:
- With the #define REPORT(), you can change the amount of diagnostics given
- This helps me search the parse tree & figure out what is going on inside SWIG
- (because it's not clear or documented)
-*/
-#define REPORT(T,D) // no info:
-//#define REPORT(T,D) {Printf(stdout,T"\n");} // only title
-//#define REPORT(T,D) {Printf(stdout,T" %p\n",n);} // title & pointer
-//#define REPORT(T,D) {Printf(stdout,T"\n");display_mapping(D);} // the works
-//#define REPORT(T,D) {Printf(stdout,T"\n");if(D)Swig_print_node(D);} // the works
-
-void display_mapping(DOH *d) {
- if (d == 0 || !DohIsMapping(d))
- return;
- for (Iterator it = First(d); it.item; it = Next(it)) {
- if (DohIsString(it.item))
- Printf(stdout, " %s = %s\n", it.key, it.item);
- else if (DohIsMapping(it.item))
- Printf(stdout, " %s = <mapping>\n", it.key);
- else if (DohIsSequence(it.item))
- Printf(stdout, " %s = <sequence>\n", it.key);
- else
- Printf(stdout, " %s = <unknown>\n", it.key);
- }
-}
-
-extern "C"
-{
- static int compareByLen(const DOH *f, const DOH *s) {
- return Len(s) - Len(f);
- }
-}
-
-
-/* NEW LANGUAGE NOTE:***********************************************
- most of the default options are handled by SWIG
- you can add new ones here
- (though for now I have not bothered)
-NEW LANGUAGE NOTE:END ************************************************/
-static const char *usage = "\
-Lua Options (available with -lua)\n\
- -elua - Generates LTR compatible wrappers for smaller devices running elua\n\
- -eluac - LTR compatible wrappers in \"crass compress\" mode for elua\n\
- -elua-emulate - Emulates behaviour of eLua. Useful only for testing.\n\
- Incompatible with -elua/-eluac options.\n\
- -nomoduleglobal - Do not register the module name as a global variable \n\
- but return the module table from calls to require.\n\
- -no-old-metatable-bindings\n\
- - Disable support for old-style bindings name generation, some\n\
- old-style members scheme etc.\n\
- -squash-bases - Squashes symbols from all inheritance tree of a given class\n\
- into itself. Emulates pre-SWIG3.0 inheritance. Insignificantly\n\
- speeds things up, but increases memory consumption.\n\
-\n";
-
-static int nomoduleglobal = 0;
-static int elua_ltr = 0;
-static int eluac_ltr = 0;
-static int elua_emulate = 0;
-static int squash_bases = 0;
-/* The new metatable bindings were introduced in SWIG 3.0.0.
- * old_metatable_bindings in v2:
- * 1. static methods will be put into the scope their respective class
- * belongs to as well as into the class scope itself. (only for classes without %nspace given)
- * 2. The layout in elua mode is somewhat different
- */
-static int old_metatable_bindings = 1;
-static int old_compatible_names = 1; // This flag can temporarily disable backward compatible names generation if old_metatable_bindings is enabled
-
-/* NEW LANGUAGE NOTE:***********************************************
- To add a new language, you need to derive your class from
- Language and the overload various virtual functions
- (more on this as I figure it out)
-NEW LANGUAGE NOTE:END ************************************************/
-
-class LUA:public Language {
-private:
-
- File *f_begin;
- File *f_runtime;
- File *f_header;
- File *f_wrappers;
- File *f_init;
- File *f_initbeforefunc;
- String *s_luacode; // luacode to be called during init
- String *module; //name of the module
-
- // Parameters for current class. NIL if not parsing class
- int have_constructor;
- int have_destructor;
- String *destructor_action;
- // This variable holds the name of the current class in Lua. Usually it is
- // the same as C++ class name, but rename directives can change it.
- String *proxy_class_name;
- // This is a so called fully qualified symname - the above proxy class name
- // prepended with class namespace. If class Lua name is the same as class C++ name,
- // then it is basically C++ fully qualified name with colons replaced with dots.
- String *full_proxy_class_name;
- // All static methods and/or variables are treated as if they were in the
- // special C++ namespace $(classname).SwigStatic. This is internal mechanism only
- // and is not visible to user in any manner. This variable holds the name
- // of such pseudo-namespace a.k.a the result of above expression evaluation
- String *class_static_nspace;
- // This variable holds the name of generated C function that acts as a constructor
- // for the currently parsed class.
- String *constructor_name;
-
- // Many wrappers forward calls to each other, for example staticmembervariableHandler
- // forwards calls to variableHandler, which, in turn, makes to call to functionWrapper.
- // In order to access information about whether it is a static member of class or just
- // a plain old variable, the current array is kept and used as a 'log' of the call stack.
- enum TState {
- NO_CPP,
- VARIABLE,
- GLOBAL_FUNC,
- GLOBAL_VAR,
- MEMBER_FUNC,
- CONSTRUCTOR,
- DESTRUCTOR,
- MEMBER_VAR,
- STATIC_FUNC,
- STATIC_VAR,
- STATIC_CONST, // enums and things like static const int x = 5;
- ENUM_CONST, // This is only needed for backward compatibility in C mode
-
- STATES_COUNT
- };
- bool current[STATES_COUNT];
-
-public:
-
- /* ---------------------------------------------------------------------
- * LUA()
- *
- * Initialize member data
- * --------------------------------------------------------------------- */
-
- LUA():
- f_begin(0),
- f_runtime(0),
- f_header(0),
- f_wrappers(0),
- f_init(0),
- f_initbeforefunc(0),
- s_luacode(0),
- module(0),
- have_constructor(0),
- have_destructor(0),
- destructor_action(0),
- proxy_class_name(0),
- full_proxy_class_name(0),
- class_static_nspace(0),
- constructor_name(0) {
- for (int i = 0; i < STATES_COUNT; i++)
- current[i] = false;
- }
-
- /* NEW LANGUAGE NOTE:***********************************************
- This is called to initialise the system & read any command line args
- most of this is boilerplate code, except the command line args
- which depends upon what args your code supports
- NEW LANGUAGE NOTE:END *********************************************** */
-
- /* ---------------------------------------------------------------------
- * main()
- *
- * Parse command line options and initializes variables.
- * --------------------------------------------------------------------- */
-
- virtual void main(int argc, char *argv[]) {
-
- /* Set location of SWIG library */
- SWIG_library_directory("lua");
-
- /* Look for certain command line options */
- for (int i = 1; i < argc; i++) {
- if (argv[i]) {
- if (strcmp(argv[i], "-help") == 0) { // usage flags
- fputs(usage, stdout);
- } else if (strcmp(argv[i], "-nomoduleglobal") == 0) {
- nomoduleglobal = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-elua") == 0) {
- elua_ltr = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-eluac") == 0) {
- eluac_ltr = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-no-old-metatable-bindings") == 0) {
- Swig_mark_arg(i);
- old_metatable_bindings = 0;
- } else if (strcmp(argv[i], "-squash-bases") == 0) {
- Swig_mark_arg(i);
- squash_bases = 1;
- } else if (strcmp(argv[i], "-elua-emulate") == 0) {
- Swig_mark_arg(i);
- elua_emulate = 1;
- }
- }
- }
-
- if (elua_emulate && (eluac_ltr || elua_ltr )) {
- Printf(stderr, "Cannot have -elua-emulate with either -eluac or -elua\n");
- Swig_arg_error();
- }
-
- // Set elua_ltr if elua_emulate is requested
- if(elua_emulate)
- elua_ltr = 1;
-
- /* NEW LANGUAGE NOTE:***********************************************
- This is the boilerplate code, setting a few #defines
- and which lib directory to use
- the SWIG_library_directory() is also boilerplate code
- but it always seems to be the first line of code
- NEW LANGUAGE NOTE:END *********************************************** */
- /* Add a symbol to the parser for conditional compilation */
- Preprocessor_define("SWIGLUA 1", 0);
-
- /* Set language-specific configuration file */
- SWIG_config_file("lua.swg");
-
- /* Set typemap language */
- SWIG_typemap_lang("lua");
-
- /* Enable overloaded methods support */
- allow_overloading();
- }
-
-
-
-
- /* NEW LANGUAGE NOTE:***********************************************
- After calling main, SWIG parses the code to wrap (I believe)
- then calls top()
- in this is more boilerplate code to set everything up
- and a call to Language::top()
- which begins the code generations by calling the member fns
- after all that is more boilerplate code to close all down
- (overall there is virtually nothing here that needs to be edited
- just use as is)
- NEW LANGUAGE NOTE:END *********************************************** */
- /* ---------------------------------------------------------------------
- * top()
- * --------------------------------------------------------------------- */
-
- virtual int top(Node *n) {
- /* Get the module name */
- module = Getattr(n, "name");
-
- /* Get the output file name */
- String *outfile = Getattr(n, "outfile");
-
- /* Open the output file */
- f_begin = NewFile(outfile, "w", SWIG_output_files());
- if (!f_begin) {
- FileErrorDisplay(outfile);
- Exit(EXIT_FAILURE);
- }
- f_runtime = NewString("");
- f_init = NewString("");
- f_header = NewString("");
- f_wrappers = NewString("");
- f_initbeforefunc = NewString("");
-
- /* Register file targets with the SWIG file handler */
- Swig_register_filebyname("header", f_header);
- Swig_register_filebyname("wrapper", f_wrappers);
- Swig_register_filebyname("begin", f_begin);
- Swig_register_filebyname("runtime", f_runtime);
- Swig_register_filebyname("init", f_init);
- Swig_register_filebyname("initbeforefunc", f_initbeforefunc);
-
-
- s_luacode = NewString("");
- Swig_register_filebyname("luacode", s_luacode);
-
- current[NO_CPP] = true;
-
- /* Standard stuff for the SWIG runtime section */
- Swig_banner(f_begin);
-
- Swig_obligatory_macros(f_runtime, "LUA");
-
- emitLuaFlavor(f_runtime);
-
- if (nomoduleglobal) {
- Printf(f_runtime, "#define SWIG_LUA_NO_MODULE_GLOBAL\n");
- } else {
- Printf(f_runtime, "#define SWIG_LUA_MODULE_GLOBAL\n");
- }
- if (squash_bases)
- Printf(f_runtime, "#define SWIG_LUA_SQUASH_BASES\n");
-
- // if (NoInclude) {
- // Printf(f_runtime, "#define SWIG_NOINCLUDE\n");
- // }
-
- Printf(f_runtime, "\n");
-
- //String *init_name = NewStringf("%(title)s_Init", module);
- //Printf(f_header, "#define SWIG_init %s\n", init_name);
- //Printf(f_header, "#define SWIG_name \"%s\"\n", module);
- /* SWIG_import is a special function name for importing within Lua5.1 */
- //Printf(f_header, "#define SWIG_import luaopen_%s\n\n", module);
- Printf(f_header, "#define SWIG_name \"%s\"\n", module);
- Printf(f_header, "#define SWIG_init luaopen_%s\n", module);
- Printf(f_header, "#define SWIG_init_user luaopen_%s_user\n\n", module);
- Printf(f_header, "#define SWIG_LUACODE luaopen_%s_luacode\n", module);
-
- Printf(f_wrappers, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
-
- /* %init code inclusion, effectively in the SWIG_init function */
- Printf(f_init, "void SWIG_init_user(lua_State* L)\n{\n");
- Language::top(n);
- Printf(f_init, "/* exec Lua code if applicable */\nSWIG_Lua_dostring(L,SWIG_LUACODE);\n");
- Printf(f_init, "}\n");
-
- // Done. Close up the module & write to the wrappers
- closeNamespaces(f_wrappers);
- Printf(f_wrappers, "#ifdef __cplusplus\n}\n#endif\n");
-
- SwigType_emit_type_table(f_runtime, f_wrappers);
-
- /* NEW LANGUAGE NOTE:***********************************************
- this basically combines several of the strings together
- and then writes it all to a file
- NEW LANGUAGE NOTE:END *********************************************** */
- Dump(f_runtime, f_begin);
- Dump(f_header, f_begin);
- Dump(f_wrappers, f_begin);
- Dump(f_initbeforefunc, f_begin);
- /* for the Lua code it needs to be properly escaped to be added into the C/C++ code */
- escapeCode(s_luacode);
- Printf(f_begin, "const char* SWIG_LUACODE=\n \"%s\";\n\n", s_luacode);
- Wrapper_pretty_print(f_init, f_begin);
- /* Close all of the files */
- Delete(s_luacode);
- Delete(f_header);
- Delete(f_wrappers);
- Delete(f_init);
- Delete(f_initbeforefunc);
- Delete(f_runtime);
- Delete(f_begin);
-
- /* Done */
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * importDirective()
- * ------------------------------------------------------------ */
-
- virtual int importDirective(Node *n) {
- return Language::importDirective(n);
- }
-
- /* ------------------------------------------------------------
- * cDeclaration()
- * It copies sym:name to lua:name to preserve its original value
- * ------------------------------------------------------------ */
-
- virtual int cDeclaration(Node *n) {
- // class 'Language' is messing with symname in a really heavy way.
- // Although documentation states that sym:name is a name in
- // the target language space, it is not true. sym:name and
- // its derivatives are used in various places, including
- // behind-the-scene C code generation. The best way is not to
- // touch it at all.
- // But we need to know what was the name of function/variable
- // etc that user desired, that's why we store correct symname
- // as lua:name
- String *symname = Getattr(n, "sym:name");
- if (symname)
- Setattr(n, "lua:name", symname);
- return Language::cDeclaration(n);
- }
- virtual int constructorDeclaration(Node *n) {
- Setattr(n, "lua:name", Getattr(n, "sym:name"));
- return Language::constructorDeclaration(n);
- }
- virtual int destructorDeclaration(Node *n) {
- Setattr(n, "lua:name", Getattr(n, "sym:name"));
- return Language::destructorDeclaration(n);
- }
- /* NEW LANGUAGE NOTE:***********************************************
- This is it!
- you get this one right, and most of your work is done
- but it's going to take some file to get it working right
- quite a bit of this is generally boilerplate code
- (or stuff I don't understand)
- that which matters will have extra added comments
- NEW LANGUAGE NOTE:END *********************************************** */
- /* ---------------------------------------------------------------------
- * functionWrapper()
- *
- * Create a function declaration and register it with the interpreter.
- * --------------------------------------------------------------------- */
-
- /* -----------------------------------------------------------------------
- * registerMethod()
- *
- * Determines wrap name of a method, its scope etc and calls
- * registerMethod overload with correct arguments
- * Overloaded variant adds method to the "methods" array of specified lua scope/class
- * ---------------------------------------------------------------------- */
-
- void registerMethod(Node *n, bool overwrite = false, String *overwriteLuaScope = 0) {
- String *symname = Getattr(n, "sym:name");
- assert(symname);
-
- if (Getattr(n, "sym:nextSibling"))
- return;
-
- // Lua scope. It is not symbol NSpace, it is the actual key to retrieve getCArraysHash.
- String *luaScope = luaCurrentSymbolNSpace();
- if (overwrite)
- luaScope = overwriteLuaScope;
-
- String *wrapname = 0;
- String *mrename;
- if (current[NO_CPP] || !getCurrentClass()) {
- mrename = symname;
- } else {
- assert(!current[NO_CPP]);
- if (current[STATIC_FUNC] || current[MEMBER_FUNC]) {
- mrename = Swig_name_member(getNSpace(), getClassPrefix(), symname);
- } else {
- mrename = symname;
- }
- }
- wrapname = Swig_name_wrapper(mrename);
- registerMethod(n, wrapname, luaScope);
- }
-
- /* -----------------------------------------------------------------------
- * registerMethod()
- *
- * Add method to the "methods" C array of given namespace/class
- * ---------------------------------------------------------------------- */
-
- void registerMethod(Node *n, String* wname, String *luaScope) {
- assert(n);
- Hash *nspaceHash = getCArraysHash(luaScope);
- String *s_ns_methods_tab = Getattr(nspaceHash, "methods");
- String *lua_name = Getattr(n, "lua:name");
- if (elua_ltr || eluac_ltr)
- Printv(s_ns_methods_tab, tab4, "{LSTRKEY(\"", lua_name, "\")", ", LFUNCVAL(", wname, ")", "},\n", NIL);
- else
- Printv(s_ns_methods_tab, tab4, "{ \"", lua_name, "\", ", wname, "},\n", NIL);
- // Add to the metatable if method starts with '__'
- const char * tn = Char(lua_name);
- if (tn[0]=='_' && tn[1] == '_' && !eluac_ltr) {
- String *metatable_tab = Getattr(nspaceHash, "metatable");
- assert(metatable_tab);
- if (elua_ltr)
- Printv(metatable_tab, tab4, "{LSTRKEY(\"", lua_name, "\")", ", LFUNCVAL(", wname, ")", "},\n", NIL);
- else
- Printv(metatable_tab, tab4, "{ \"", lua_name, "\", ", wname, "},\n", NIL);
- }
- }
-
- virtual int functionWrapper(Node *n) {
- REPORT("functionWrapper", n);
-
- String *name = Getattr(n, "name");
- String *iname = Getattr(n, "sym:name");
- String *lua_name = Getattr(n, "lua:name");
- assert(lua_name);
- SwigType *d = Getattr(n, "type");
- ParmList *l = Getattr(n, "parms");
- Parm *p;
- String *tm;
- int i;
- //Printf(stdout,"functionWrapper %s %s %d\n",name,iname,current);
-
- String *overname = 0;
- if (Getattr(n, "sym:overloaded")) {
- overname = Getattr(n, "sym:overname");
- } else {
- if (!luaAddSymbol(lua_name, n)) {
- return SWIG_ERROR;
- }
- }
-
- /* NEW LANGUAGE NOTE:***********************************************
- the wrapper object holds all the wrapper code
- we need to add a couple of local variables
- NEW LANGUAGE NOTE:END *********************************************** */
- Wrapper *f = NewWrapper();
- Wrapper_add_local(f, "SWIG_arg", "int SWIG_arg = 0");
-
-
- String *wname = Swig_name_wrapper(iname);
- if (overname) {
- Append(wname, overname);
- }
- if (current[CONSTRUCTOR]) {
- if (constructor_name != 0)
- Delete(constructor_name);
- constructor_name = Copy(wname);
- }
-
- /* NEW LANGUAGE NOTE:***********************************************
- the format of a lua fn is:
- static int wrap_XXX(lua_State* L){...}
- this line adds this into the wrapper code
- NEW LANGUAGE NOTE:END *********************************************** */
- Printv(f->def, "static int ", wname, "(lua_State* L) {", NIL);
- // SWIG_fail in lua leads to a call to lua_error() which calls longjmp()
- // which means the destructors of any live function-local C++ objects won't
- // get run. To avoid this happening, we wrap almost everything in the
- // function in a block, and end that right before lua_error() at which
- // point those destructors will get called.
- if (CPlusPlus) Append(f->def, "\n{");
-
- /* NEW LANGUAGE NOTE:***********************************************
- this prints the list of args, eg for a C fn
- int gcd(int x,int y);
- it will print
- int arg1;
- int arg2;
- NEW LANGUAGE NOTE:END *********************************************** */
- /* Write code to extract function parameters. */
- emit_parameter_variables(l, f);
-
- /* Attach the standard typemaps */
- emit_attach_parmmaps(l, f);
- Setattr(n, "wrap:parms", l);
-
- /* Get number of required and total arguments */
- int num_arguments = emit_num_arguments(l);
- int num_required = emit_num_required(l);
- int varargs = emit_isvarargs(l);
-
- // Check if we have to ignore arguments that are passed by LUA.
- // Needed for unary minus, where lua passes two arguments and
- // we have to ignore the second.
-
- int args_to_ignore = 0;
- if (Getattr(n, "lua:ignore_args")) {
- args_to_ignore = GetInt(n, "lua:ignore_args");
- }
-
-
- /* NEW LANGUAGE NOTE:***********************************************
- from here on in, it gets rather hairy
- this is the code to convert from the scripting language to C/C++
- some of the stuff will refer to the typemaps code written in your swig file
- (lua.swg), and some is done in the code here
- I suppose you could do all the conversion in C, but it would be a nightmare to do
- NEW LANGUAGE NOTE:END *********************************************** */
- /* Generate code for argument marshalling */
- // String *description = NewString("");
- /* NEW LANGUAGE NOTE:***********************************************
- argument_check is a new feature I added to check types of arguments:
- eg for int gcd(int,int)
- I want to check that arg1 & arg2 really are integers
- NEW LANGUAGE NOTE:END *********************************************** */
- String *argument_check = NewString("");
- String *argument_parse = NewString("");
- String *checkfn = NULL;
- char source[64];
- Printf(argument_check, "SWIG_check_num_args(\"%s\",%d,%d)\n", Swig_name_str(n), num_required + args_to_ignore, num_arguments + args_to_ignore);
-
- for (i = 0, p = l; i < num_arguments; i++) {
-
- while (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- }
-
- SwigType *pt = Getattr(p, "type");
- /* Look for an input typemap */
- sprintf(source, "%d", i + 1);
- if ((tm = Getattr(p, "tmap:in"))) {
- Replaceall(tm, "$input", source);
- Setattr(p, "emit:input", source);
- if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
- Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
- } else {
- Replaceall(tm, "$disown", "0");
- }
- /* NEW LANGUAGE NOTE:***********************************************
- look for a 'checkfn' typemap
- this an additional parameter added to the in typemap
- if found the type will be tested for
- this will result in code either in the
- argument_check or argument_parse string
- NEW LANGUAGE NOTE:END *********************************************** */
- if ((checkfn = Getattr(p, "tmap:in:checkfn"))) {
- if (i < num_required) {
- Printf(argument_check, "if(!%s(L,%s))", checkfn, source);
- } else {
- Printf(argument_check, "if(lua_gettop(L)>=%s && !%s(L,%s))", source, checkfn, source);
- }
- Printf(argument_check, " SWIG_fail_arg(\"%s\",%s,\"%s\");\n", Swig_name_str(n), source, SwigType_str(pt, 0));
- }
- /* NEW LANGUAGE NOTE:***********************************************
- lua states the number of arguments passed to a function using the fn
- lua_gettop()
- we can use this to deal with default arguments
- NEW LANGUAGE NOTE:END *********************************************** */
- if (i < num_required) {
- Printf(argument_parse, "%s\n", tm);
- } else {
- Printf(argument_parse, "if(lua_gettop(L)>=%s){%s}\n", source, tm);
- }
- p = Getattr(p, "tmap:in:next");
- continue;
- } else {
- /* NEW LANGUAGE NOTE:***********************************************
- // why is this code not called when I don't have a typemap?
- // instead of giving a warning, no code is generated
- NEW LANGUAGE NOTE:END *********************************************** */
- Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
- break;
- }
- }
-
- // add all argcheck code
- Printv(f->code, argument_check, argument_parse, NIL);
-
- /* Check for trailing varargs */
- if (varargs) {
- if (p && (tm = Getattr(p, "tmap:in"))) {
- Replaceall(tm, "$input", "varargs");
- Printv(f->code, tm, "\n", NIL);
- }
- }
-
- /* Insert constraint checking code */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:check"))) {
- Printv(f->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:check:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* Insert cleanup code */
- String *cleanup = NewString("");
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:freearg"))) {
- Printv(cleanup, tm, "\n", NIL);
- p = Getattr(p, "tmap:freearg:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* Insert argument output code */
- String *outarg = NewString("");
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:argout"))) {
- // // managing the number of returning variables
- // if (numoutputs=Getattr(p,"tmap:argout:numoutputs")){
- // int i=GetInt(p,"tmap:argout:numoutputs");
- // printf("got argout:numoutputs of %d\n",i);
- // returnval+=GetInt(p,"tmap:argout:numoutputs");
- // }
- // else returnval++;
- Replaceall(tm, "$arg", Getattr(p, "emit:input"));
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(outarg, tm, "\n", NIL);
- p = Getattr(p, "tmap:argout:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- // Remember C name of the wrapping function
- Setattr(n, "wrap:name", wname);
-
- /* Emit the function call */
- String *actioncode = emit_action(n);
-
- /* NEW LANGUAGE NOTE:***********************************************
- FIXME:
- returns 1 if there is a void return type
- this is because there is a typemap for void
- NEW LANGUAGE NOTE:END *********************************************** */
- // Return value if necessary
- if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
- // managing the number of returning variables
- // if (numoutputs=Getattr(tm,"numoutputs")){
- // int i=GetInt(tm,"numoutputs");
- // printf("return numoutputs %d\n",i);
- // returnval+=GetInt(tm,"numoutputs");
- // }
- // else returnval++;
- if (GetFlag(n, "feature:new")) {
- Replaceall(tm, "$owner", "1");
- } else {
- Replaceall(tm, "$owner", "0");
- }
- Printf(f->code, "%s\n", tm);
- // returnval++;
- } else {
- Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);
- }
- emit_return_variable(n, d, f);
-
- /* Output argument output code */
- Printv(f->code, outarg, NIL);
-
- /* Output cleanup code */
- Printv(f->code, cleanup, NIL);
-
- /* Look to see if there is any newfree cleanup code */
- if (GetFlag(n, "feature:new")) {
- if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
- Printf(f->code, "%s\n", tm);
- }
- }
-
- /* See if there is any return cleanup code */
- if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
- Printf(f->code, "%s\n", tm);
- }
-
-
- /* Close the function */
- Printv(f->code, "return SWIG_arg;\n", NIL);
- // add the failure cleanup code:
- Printv(f->code, "\nfail: SWIGUNUSED;\n", "$cleanup", NIL);
- if (CPlusPlus) Append(f->code, "}\n");
- Printv(f->code, "lua_error(L);\n", NIL);
- // lua_error() calls longjmp() but we need a dummy return to avoid compiler
- // warnings.
- Printv(f->code, "return 0;\n", NIL);
- Printf(f->code, "}\n");
-
- /* Substitute the cleanup code */
- Replaceall(f->code, "$cleanup", cleanup);
-
- /* Substitute the function name */
- Replaceall(f->code, "$symname", iname);
- Replaceall(f->code, "$result", Swig_cresult_name());
-
- /* Dump the function out */
- /* in Lua we will not emit the destructor as a wrapper function,
- Lua will automatically call the destructor when the object is free'd
- However: you cannot just skip this function as it will not emit
- any custom destructor (using %extend), as you need to call emit_action()
- Therefore we go though the whole function,
- but do not write the code into the wrapper
- */
- if (!current[DESTRUCTOR]) {
- Wrapper_print(f, f_wrappers);
- }
-
- /* NEW LANGUAGE NOTE:***********************************************
- register the function in SWIG
- different language mappings seem to use different ideas
- NEW LANGUAGE NOTE:END *********************************************** */
- /* Now register the function with the interpreter. */
- int result = SWIG_OK;
- if (Getattr(n, "sym:overloaded")) {
- if (!Getattr(n, "sym:nextSibling")) {
- result = dispatchFunction(n);
- }
- }
-
- Delete(argument_check);
- Delete(argument_parse);
-
- Delete(cleanup);
- Delete(outarg);
- // Delete(description);
- DelWrapper(f);
-
- return result;
- }
-
- /* ------------------------------------------------------------
- * dispatchFunction()
- *
- * Emit overloading dispatch function
- * ------------------------------------------------------------ */
-
- /* NEW LANGUAGE NOTE:***********************************************
- This is an extra function used for overloading of functions
- it checks the args & then calls the relevant fn
- most of the real work in again typemaps:
- look for %typecheck(SWIG_TYPECHECK_*) in the .swg file
- NEW LANGUAGE NOTE:END *********************************************** */
- int dispatchFunction(Node *n) {
- //REPORT("dispatchFunction", n);
- /* Last node in overloaded chain */
-
- int maxargs;
- String *tmp = NewString("");
- String *dispatch = Swig_overload_dispatch(n, "return %s(L);", &maxargs);
-
- /* Generate a dispatch wrapper for all overloaded functions */
-
- Wrapper *f = NewWrapper();
- String *symname = Getattr(n, "sym:name");
- String *lua_name = Getattr(n, "lua:name");
- assert(lua_name);
- String *wname = Swig_name_wrapper(symname);
-
- //Printf(stdout,"Swig_overload_dispatch %s %s '%s' %d\n",symname,wname,dispatch,maxargs);
-
- if (!luaAddSymbol(lua_name, n)) {
- DelWrapper(f);
- Delete(dispatch);
- Delete(tmp);
- return SWIG_ERROR;
- }
-
- Printv(f->def, "static int ", wname, "(lua_State* L) {", NIL);
- Wrapper_add_local(f, "argc", "int argc");
- Printf(tmp, "int argv[%d]={1", maxargs + 1);
- for (int i = 1; i <= maxargs; i++) {
- Printf(tmp, ",%d", i + 1);
- }
- Printf(tmp, "}");
- Wrapper_add_local(f, "argv", tmp);
- Printf(f->code, "argc = lua_gettop(L);\n");
-
- Replaceall(dispatch, "$args", "self,args");
- Printv(f->code, dispatch, "\n", NIL);
-
- Node *sibl = n;
- while (Getattr(sibl, "sym:previousSibling"))
- sibl = Getattr(sibl, "sym:previousSibling"); // go all the way up
- String *protoTypes = NewString("");
- do {
- String *fulldecl = Swig_name_decl(sibl);
- Printf(protoTypes, "\n\" %s\\n\"", fulldecl);
- Delete(fulldecl);
- } while ((sibl = Getattr(sibl, "sym:nextSibling")));
- Printf(f->code, "SWIG_Lua_pusherrstring(L,\"Wrong arguments for overloaded function '%s'\\n\"\n"
- "\" Possible C/C++ prototypes are:\\n\"%s);\n", symname, protoTypes);
- Delete(protoTypes);
-
- Printf(f->code, "lua_error(L);return 0;\n");
- Printv(f->code, "}\n", NIL);
- Wrapper_print(f, f_wrappers);
-
- // Remember C name of the wrapping function
- Setattr(n, "wrap:name", wname);
-
- if (current[CONSTRUCTOR]) {
- if (constructor_name != 0)
- Delete(constructor_name);
- constructor_name = Copy(wname);
- }
-
- DelWrapper(f);
- Delete(dispatch);
- Delete(tmp);
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * Add variable to "attributes" C arrays of given namespace or class.
- * Input is node. Based on the state of "current" array it determines
- * the name of the getter function, setter function etc and calls
- * registerVariable overload with necessary params.
- * Lua scope could be overwritten. (Used only for backward compatibility)
- * ------------------------------------------------------------ */
-
- void registerVariable(Node *n, bool overwrite = false, String *overwriteLuaScope = 0) {
- int assignable = is_assignable(n);
- String *symname = Getattr(n, "sym:name");
- assert(symname);
-
- // Lua scope. It is not symbol NSpace, it is the actual key to retrieve getCArraysHash.
- String *luaScope = luaCurrentSymbolNSpace();
- if (overwrite)
- luaScope = overwriteLuaScope;
-
- // Getter and setter
- String *getName = 0;
- String *setName = 0;
- String *mrename = 0;
- if (current[NO_CPP] || !getCurrentClass()) {
- // Global variable
- getName = Swig_name_get(getNSpace(), symname);
- if (assignable)
- setName = Swig_name_set(getNSpace(), symname);
- } else {
- assert(!current[NO_CPP]);
- if (current[STATIC_VAR] ) {
- mrename = Swig_name_member(getNSpace(), getClassPrefix(), symname);
- getName = Swig_name_get(0, mrename);
- if (assignable)
- setName = Swig_name_set(0, mrename);
- } else if (current[MEMBER_VAR]) {
- mrename = Swig_name_member(0, getClassPrefix(), symname);
- getName = Swig_name_get(getNSpace(), mrename);
- if (assignable)
- setName = Swig_name_set(getNSpace(), mrename);
- } else {
- assert(false);
- }
- }
-
- getName = Swig_name_wrapper(getName);
- if (setName)
- setName = Swig_name_wrapper(setName);
- registerVariable(luaScope, n, getName, setName);
- }
-
- /* ------------------------------------------------------------
- * registerVariable()
- *
- * Add variable to the "attributes" (or "get"/"set" in
- * case of elua_ltr) C arrays of given namespace or class
- * ------------------------------------------------------------ */
-
- void registerVariable(String *lua_nspace_or_class_name, Node *n, String *getName, String *setName) {
- String *unassignable = NewString("SWIG_Lua_set_immutable");
- if (setName == 0 || GetFlag(n, "feature:immutable")) {
- setName = unassignable;
- }
- Hash *nspaceHash = getCArraysHash(lua_nspace_or_class_name);
- String *s_ns_methods_tab = Getattr(nspaceHash, "methods");
- String *s_ns_var_tab = Getattr(nspaceHash, "attributes");
- String *lua_name = Getattr(n, "lua:name");
- if (elua_ltr) {
- String *s_ns_dot_get = Getattr(nspaceHash, "get");
- String *s_ns_dot_set = Getattr(nspaceHash, "set");
- Printf(s_ns_dot_get, "%s{LSTRKEY(\"%s\"), LFUNCVAL(%s)},\n", tab4, lua_name, getName);
- Printf(s_ns_dot_set, "%s{LSTRKEY(\"%s\"), LFUNCVAL(%s)},\n", tab4, lua_name, setName);
- } else if (eluac_ltr) {
- Printv(s_ns_methods_tab, tab4, "{LSTRKEY(\"", lua_name, "_get", "\")", ", LFUNCVAL(", getName, ")", "},\n", NIL);
- Printv(s_ns_methods_tab, tab4, "{LSTRKEY(\"", lua_name, "_set", "\")", ", LFUNCVAL(", setName, ")", "},\n", NIL);
- } else {
- Printf(s_ns_var_tab, "%s{ \"%s\", %s, %s },\n", tab4, lua_name, getName, setName);
- }
- }
-
- /* ------------------------------------------------------------
- * variableWrapper()
- * ------------------------------------------------------------ */
-
- virtual int variableWrapper(Node *n) {
- /* NEW LANGUAGE NOTE:***********************************************
- Language::variableWrapper(n) will generate two wrapper fns
- Foo_get & Foo_set by calling functionWrapper()
- so we will just add these into the variable lists
- ideally we should not have registered these as functions,
- only WRT this variable will look into this later.
- NEW LANGUAGE NOTE:END *********************************************** */
- // REPORT("variableWrapper", n);
- String *lua_name = Getattr(n, "lua:name");
- assert(lua_name);
- (void)lua_name;
- current[VARIABLE] = true;
- // let SWIG generate the wrappers
- int result = Language::variableWrapper(n);
-
- // It is impossible to use registerVariable, because sym:name of the Node is currently
- // in an undefined state - the callees of this function may have modified it.
- // registerVariable should be used from respective callees.*
- current[VARIABLE] = false;
- return result;
- }
-
-
- /* ------------------------------------------------------------
- * Add constant to appropriate C array. constantRecord is an array record.
- * Actually, in current implementation it is resolved consttab typemap
- * ------------------------------------------------------------ */
-
- void registerConstant(String *nspace, String *constantRecord) {
- Hash *nspaceHash = getCArraysHash(nspace);
- String *s_const_tab = 0;
- if (eluac_ltr || elua_ltr)
- // In elua everything goes to "methods" tab
- s_const_tab = Getattr(nspaceHash, "methods");
- else
- s_const_tab = Getattr(nspaceHash, "constants");
-
- assert(s_const_tab);
- Printf(s_const_tab, " %s,\n", constantRecord);
-
- if ((eluac_ltr || elua_ltr) && old_metatable_bindings) {
- s_const_tab = Getattr(nspaceHash, "constants");
- assert(s_const_tab);
- Printf(s_const_tab, " %s,\n", constantRecord);
- }
-
- }
-
- /* ------------------------------------------------------------
- * constantWrapper()
- * ------------------------------------------------------------ */
-
- virtual int constantWrapper(Node *n) {
- REPORT("constantWrapper", n);
- String *name = Getattr(n, "name");
- String *iname = Getattr(n, "sym:name");
- String *lua_name = Getattr(n, "lua:name");
- if (lua_name == 0)
- lua_name = iname;
- String *nsname = Copy(iname);
- SwigType *type = Getattr(n, "type");
- String *rawval = Getattr(n, "rawval");
- String *value = rawval ? rawval : Getattr(n, "value");
- String *tm;
- String *lua_name_v2 = 0;
- String *tm_v2 = 0;
- String *iname_v2 = 0;
- Node *n_v2 = 0;
-
- if (!luaAddSymbol(lua_name, n))
- return SWIG_ERROR;
-
- Swig_save("lua_constantMember", n, "sym:name", NIL);
- Setattr(n, "sym:name", lua_name);
- /* Special hook for member pointer */
- if (SwigType_type(type) == T_MPOINTER) {
- String *wname = Swig_name_wrapper(iname);
- Printf(f_wrappers, "static %s = %s;\n", SwigType_str(type, wname), value);
- value = Char(wname);
- }
-
- if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) {
- Replaceall(tm, "$value", value);
- Replaceall(tm, "$nsname", nsname);
- registerConstant(luaCurrentSymbolNSpace(), tm);
- } else if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
- Replaceall(tm, "$value", value);
- Replaceall(tm, "$nsname", nsname);
- Printf(f_init, "%s\n", tm);
- } else {
- Delete(nsname);
- nsname = 0;
- Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n");
- Swig_restore(n);
- return SWIG_NOWRAP;
- }
-
- bool make_v2_compatible = old_metatable_bindings && getCurrentClass() && old_compatible_names;
-
- if (make_v2_compatible) {
- // Don't do anything for enums in C mode - they are already
- // wrapped correctly
- if (CPlusPlus || !current[ENUM_CONST]) {
- lua_name_v2 = Swig_name_member(0, proxy_class_name, lua_name);
- iname_v2 = Swig_name_member(0, proxy_class_name, iname);
- n_v2 = Copy(n);
- if (!luaAddSymbol(iname_v2, n, getNSpace())) {
- Swig_restore(n);
- return SWIG_ERROR;
- }
-
- Setattr(n_v2, "sym:name", lua_name_v2);
- tm_v2 = Swig_typemap_lookup("consttab", n_v2, name, 0);
- if (tm_v2) {
- Replaceall(tm_v2, "$value", value);
- Replaceall(tm_v2, "$nsname", nsname);
- registerConstant(getNSpace(), tm_v2);
- } else {
- tm_v2 = Swig_typemap_lookup("constcode", n_v2, name, 0);
- if (!tm_v2) {
- // This can't be.
- assert(false);
- Swig_restore(n);
- return SWIG_ERROR;
- }
- Replaceall(tm_v2, "$value", value);
- Replaceall(tm_v2, "$nsname", nsname);
- Printf(f_init, "%s\n", tm_v2);
- }
- Delete(n_v2);
- }
- }
-
- Swig_restore(n);
- Delete(nsname);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * nativeWrapper()
- * ------------------------------------------------------------ */
-
- virtual int nativeWrapper(Node *n) {
- // REPORT("nativeWrapper", n);
- String *symname = Getattr(n, "sym:name");
- String *wrapname = Getattr(n, "wrap:name");
- if (!luaAddSymbol(wrapname, n))
- return SWIG_ERROR;
-
- Hash *nspaceHash = getCArraysHash(getNSpace());
- String *s_ns_methods_tab = Getattr(nspaceHash, "methods");
- Printv(s_ns_methods_tab, tab4, "{ \"", symname, "\",", wrapname, "},\n", NIL);
- // return Language::nativeWrapper(n); // this does nothing...
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * enumDeclaration()
- * ------------------------------------------------------------ */
-
- virtual int enumDeclaration(Node *n) {
- if (getCurrentClass() && (cplus_mode != PUBLIC))
- return SWIG_NOWRAP;
-
- current[STATIC_CONST] = true;
- current[ENUM_CONST] = true;
- // There is some slightly specific behaviour with enums. Basically,
- // their NSpace may be tracked separately. The code below tries to work around
- // this issue to some degree.
- // The idea is the same as in classHandler - to drop old names generation if
- // enum is in class in namespace.
- const int old_compatible_names_saved = old_compatible_names;
- if (getNSpace() || ( Getattr(n, "sym:nspace") != 0 && Len(Getattr(n, "sym:nspace")) > 0 ) ) {
- old_compatible_names = 0;
- }
- int result = Language::enumDeclaration(n);
- current[STATIC_CONST] = false;
- current[ENUM_CONST] = false;
- old_compatible_names = old_compatible_names_saved;
- return result;
- }
-
- /* ------------------------------------------------------------
- * enumvalueDeclaration()
- * ------------------------------------------------------------ */
-
- virtual int enumvalueDeclaration(Node *n) {
- if (getCurrentClass() && (cplus_mode != PUBLIC))
- return SWIG_NOWRAP;
-
- Swig_require("enumvalueDeclaration", n, "*name", "?value", "*sym:name", NIL);
- String *symname = Getattr(n, "sym:name");
- String *value = Getattr(n, "value");
- String *name = Getattr(n, "name");
- String *tmpValue;
- Node *parent = parentNode(n);
-
- if (value)
- tmpValue = NewString(value);
- else
- tmpValue = NewString(name);
- Setattr(n, "value", tmpValue);
-
- Setattr(n, "name", tmpValue); /* for wrapping of enums in a namespace when emit_action is used */
-
- if (GetFlag(parent, "scopedenum")) {
- symname = Swig_name_member(0, Getattr(parent, "sym:name"), symname);
- Setattr(n, "sym:name", symname);
- Delete(symname);
- }
-
- int result = constantWrapper(n);
-
- Delete(tmpValue);
- Swig_restore(n);
- return result;
- }
-
- /* ------------------------------------------------------------
- * classDeclaration()
- * ------------------------------------------------------------ */
-
- virtual int classDeclaration(Node *n) {
- return Language::classDeclaration(n);
- }
-
-
- /* ------------------------------------------------------------
- * Helper function that adds record to appropriate C arrays
- * ------------------------------------------------------------ */
-
- void registerClass(String *scope, String *wrap_class) {
- assert(wrap_class);
- Hash *nspaceHash = getCArraysHash(scope);
- String *ns_classes = Getattr(nspaceHash, "classes");
- Printv(ns_classes, "&", wrap_class, ",\n", NIL);
- if (elua_ltr || eluac_ltr) {
- String *ns_methods = Getattr(nspaceHash, "methods");
- Hash *class_hash = getCArraysHash(class_static_nspace);
- assert(class_hash);
- String *cls_methods = Getattr(class_hash, "methods:name");
- assert(cls_methods);
- Printv(ns_methods, tab4, "{LSTRKEY(\"", proxy_class_name, "\")", ", LROVAL(", cls_methods, ")", "},\n", NIL);
- }
- }
-
- /* ------------------------------------------------------------
- * classHandler()
- * ------------------------------------------------------------ */
-
- virtual int classHandler(Node *n) {
- //REPORT("classHandler", n);
-
- String *mangled_full_proxy_class_name = 0;
- String *destructor_name = 0;
- String *nspace = getNSpace();
-
- constructor_name = 0;
- have_constructor = 0;
- have_destructor = 0;
- destructor_action = 0;
- assert(class_static_nspace == 0);
- assert(full_proxy_class_name == 0);
- assert(proxy_class_name == 0);
-
- current[NO_CPP] = false;
-
- proxy_class_name = Getattr(n, "sym:name");
- // We have to enforce nspace here, because technically we are already
- // inside class parsing (getCurrentClass != 0), but we should register
- // class in its parent namespace
- if (!luaAddSymbol(proxy_class_name, n, nspace))
- return SWIG_ERROR;
-
- if (nspace == 0)
- full_proxy_class_name = NewStringf("%s", proxy_class_name);
- else
- full_proxy_class_name = NewStringf("%s.%s", nspace, proxy_class_name);
-
- assert(full_proxy_class_name);
- mangled_full_proxy_class_name = Swig_name_mangle(full_proxy_class_name);
-
- SwigType *t = Copy(Getattr(n, "name"));
- SwigType *fr_t = SwigType_typedef_resolve_all(t); /* Create fully resolved type */
- SwigType *t_tmp = 0;
- t_tmp = SwigType_typedef_qualified(fr_t); // Temporal variable
- Delete(fr_t);
- fr_t = SwigType_strip_qualifiers(t_tmp);
- String *mangled_fr_t = 0;
- mangled_fr_t = SwigType_manglestr(fr_t);
- // not sure exactly how this works,
- // but tcl has a static hashtable of all classes emitted and then only emits code for them once.
- // this fixes issues in test suites: template_default2 & template_specialization
-
- // * if i understand correctly, this is a bug.
- // * consider effect on template_specialization_defarg
-
- static Hash *emitted = NewHash();
- if (GetFlag(emitted, mangled_fr_t)) {
- full_proxy_class_name = 0;
- proxy_class_name = 0;
- return SWIG_NOWRAP;
- }
- SetFlag(emitted, mangled_fr_t);
-
- // We treat class T as both 'class' and 'namespace'. All static members, attributes
- // and constants are considered part of namespace T, all members - part of the 'class'
- // Now, here is a trick. Static methods, attributes and non-static methods and attributes
- // are described with same structures - swig_lua_attribute/swig_lua_method. Instead of calling
- // getCArraysHash(class name) to initialize things for static methods/attributes and then
- // manually doing same initialization for non-static methods, we call getCArraysHash 2 times:
- // 1) With name "class name" + "." + "SwigStatic" to initialize static things
- // 2) With "class name" to initialize non-static things
- Hash *instance_cls = getCArraysHash(full_proxy_class_name, false);
- assert(instance_cls);
- String *s_attr_tab_name = Getattr(instance_cls, "attributes:name");
- String *s_methods_tab_name = Getattr(instance_cls, "methods:name");
- SetFlag(instance_cls, "lua:no_namespaces");
- SetFlag(instance_cls, "lua:no_classes");
- SetFlag(instance_cls, "lua:class_instance");
-
- /* There is no use for "constants", "classes" and "namespaces" arrays.
- * All constants are considered part of static part of class.
- */
-
- class_static_nspace = NewStringf("%s%sSwigStatic", full_proxy_class_name, NSPACE_SEPARATOR);
- Hash *static_cls = getCArraysHash(class_static_nspace, false);
- assert(static_cls);
- SetFlag(static_cls, "lua:no_namespaces");
- SetFlag(static_cls, "lua:class_static");
-
- // Notifying instance_cls and static_cls hashes about each other
- Setattr(instance_cls, "lua:class_instance:static_hash", static_cls);
- Setattr(static_cls, "lua:class_static:instance_hash", instance_cls);
-
- const int old_compatible_names_saved = old_compatible_names;
- // If class has %nspace enabled, then generation of backward compatible names
- // should be disabled
- if (getNSpace()) {
- old_compatible_names = 0;
- }
-
- /* There is no use for "classes" and "namespaces" arrays. Subclasses are not supported
- * by SWIG and namespaces couldn't be nested inside classes (C++ Standard)
- */
- // Generate normal wrappers
- Language::classHandler(n);
-
- old_compatible_names = old_compatible_names_saved;
-
- SwigType_add_pointer(t);
-
- // Catch all: eg. a class with only static functions and/or variables will not have 'remembered'
- String *wrap_class_name = Swig_name_wrapper(NewStringf("class_%s", mangled_full_proxy_class_name));
- String *wrap_class = NewStringf("&%s", wrap_class_name);
- SwigType_remember_clientdata(t, wrap_class);
-
- String *rt = Copy(getClassType());
- SwigType_add_pointer(rt);
-
- // Adding class to appropriate namespace
- registerClass(nspace, wrap_class_name);
- Hash *nspaceHash = getCArraysHash(nspace);
-
- // Register the class structure with the type checker
- // Printf(f_init,"SWIG_TypeClientData(SWIGTYPE%s, (void *) &_wrap_class_%s);\n", SwigType_manglestr(t), mangled_full_proxy_class_name);
-
- // emit a function to be called to delete the object
- if (have_destructor) {
- destructor_name = NewStringf("swig_delete_%s", mangled_full_proxy_class_name);
- Printv(f_wrappers, "static void ", destructor_name, "(void *obj) {\n", NIL);
- if (destructor_action) {
- Printv(f_wrappers, SwigType_str(rt, "arg1"), " = (", SwigType_str(rt, 0), ") obj;\n", NIL);
- Printv(f_wrappers, destructor_action, "\n", NIL);
- } else {
- if (CPlusPlus) {
- Printv(f_wrappers, " delete (", SwigType_str(rt, 0), ") obj;\n", NIL);
- } else {
- Printv(f_wrappers, " free((char *) obj);\n", NIL);
- }
- }
- Printf(f_wrappers, "}\n");
- }
- // Wrap constructor wrapper into one more proxy function. It will be used as class namespace __call method, thus
- // allowing both
- // Module.ClassName.StaticMethod to access static method/variable/constant
- // Module.ClassName() to create new object
- if (have_constructor) {
- assert(constructor_name);
- String *constructor_proxy_name = NewStringf("_proxy_%s", constructor_name);
- Printv(f_wrappers, "static int ", constructor_proxy_name, "(lua_State *L) {\n", NIL);
- Printv(f_wrappers,
- tab4, "assert(lua_istable(L,1));\n",
- tab4, "lua_pushcfunction(L,", constructor_name, ");\n",
- tab4, "assert(!lua_isnil(L,-1));\n",
- tab4, "lua_replace(L,1); /* replace our table with real constructor */\n",
- tab4, "lua_call(L,lua_gettop(L)-1,1);\n",
- tab4, "return 1;\n}\n", NIL);
- Delete(constructor_name);
- constructor_name = constructor_proxy_name;
- if (elua_ltr) {
- String *static_cls_metatable_tab = Getattr(static_cls, "metatable");
- assert(static_cls_metatable_tab);
- Printf(static_cls_metatable_tab, " {LSTRKEY(\"__call\"), LFUNCVAL(%s)},\n", constructor_name);
- } else if (eluac_ltr) {
- String *ns_methods_tab = Getattr(nspaceHash, "methods");
- assert(ns_methods_tab);
- Printv(ns_methods_tab, tab4, "{LSTRKEY(\"", "new_", proxy_class_name, "\")", ", LFUNCVAL(", constructor_name, ")", "},\n", NIL);
- }
- }
- if (have_destructor) {
- if (eluac_ltr) {
- String *ns_methods_tab = Getattr(nspaceHash, "methods");
- assert(ns_methods_tab);
- Printv(ns_methods_tab, tab4, "{LSTRKEY(\"", "free_", mangled_full_proxy_class_name, "\")", ", LFUNCVAL(", destructor_name, ")", "},\n", NIL);
- }
- }
-
- closeCArraysHash(full_proxy_class_name, f_wrappers);
- closeCArraysHash(class_static_nspace, f_wrappers);
-
-
- // Handle inheritance
- // note: with the idea of class hierarchies spread over multiple modules
- // cf test-suite: imports.i
- // it is not possible to just add the pointers to the base classes to the code
- // (as sometimes these classes are not present)
- // therefore we instead hold the name of the base class and a null pointer
- // at runtime: we can query the swig type manager & see if the class exists
- // if so, we can get the pointer to the base class & replace the null pointer
- // if the type does not exist, then we cannot...
- String *base_class = NewString("");
- String *base_class_names = NewString("");
-
- List *baselist = Getattr(n, "bases");
- if (baselist && Len(baselist)) {
- Iterator b;
- b = First(baselist);
- while (b.item) {
- String *bname = Getattr(b.item, "name");
- if ((!bname) || GetFlag(b.item, "feature:ignore") || (!Getattr(b.item, "module"))) {
- b = Next(b);
- continue;
- }
- // stores a null pointer & the name
- Printf(base_class, "0,");
- Printf(base_class_names, "\"%s *\",", SwigType_namestr(bname));
-
- b = Next(b);
- }
- }
- // First, print class static part
- printCArraysDefinition(class_static_nspace, proxy_class_name, f_wrappers);
-
- assert(mangled_full_proxy_class_name);
- assert(base_class);
- assert(base_class_names);
- assert(proxy_class_name);
- assert(full_proxy_class_name);
-
- // Then print class instance part
- Printv(f_wrappers, "static swig_lua_class *swig_", mangled_full_proxy_class_name, "_bases[] = {", base_class, "0};\n", NIL);
- Delete(base_class);
- Printv(f_wrappers, "static const char *swig_", mangled_full_proxy_class_name, "_base_names[] = {", base_class_names, "0};\n", NIL);
- Delete(base_class_names);
-
- Printv(f_wrappers, "static swig_lua_class _wrap_class_", mangled_full_proxy_class_name, " = { \"", proxy_class_name, "\", \"", full_proxy_class_name, "\", &SWIGTYPE",
- SwigType_manglestr(t), ",", NIL);
-
- if (have_constructor) {
- Printv(f_wrappers, constructor_name, NIL);
- Delete(constructor_name);
- constructor_name = 0;
- } else {
- Printf(f_wrappers, "0");
- }
-
- if (have_destructor) {
- Printv(f_wrappers, ", ", destructor_name, NIL);
- } else {
- Printf(f_wrappers, ",0");
- }
- Printf(f_wrappers, ", %s, %s, &%s", s_methods_tab_name, s_attr_tab_name, Getattr(static_cls, "cname"));
-
- if (!eluac_ltr) {
- Printf(f_wrappers, ", %s", Getattr(instance_cls,"metatable:name"));
- }
- else
- Printf(f_wrappers, ", 0");
-
- Printf(f_wrappers, ", swig_%s_bases, swig_%s_base_names };\n\n", mangled_full_proxy_class_name, mangled_full_proxy_class_name);
-
- current[NO_CPP] = true;
- Delete(class_static_nspace);
- class_static_nspace = 0;
- Delete(mangled_full_proxy_class_name);
- mangled_full_proxy_class_name = 0;
- Delete(destructor_name);
- destructor_name = 0;
- Delete(full_proxy_class_name);
- full_proxy_class_name = 0;
- proxy_class_name = 0;
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * memberfunctionHandler()
- * ------------------------------------------------------------ */
-
- virtual int memberfunctionHandler(Node *n) {
- String *symname = GetChar(n, "sym:name");
- //Printf(stdout,"memberfunctionHandler %s %s\n",name,iname);
-
- // Special case unary minus: LUA passes two parameters for the
- // wrapper function while we want only one. Tell our
- // functionWrapper to ignore a parameter.
-
- if (Cmp(symname, "__unm") == 0) {
- //Printf(stdout, "unary minus: ignore one argument\n");
- SetInt(n, "lua:ignore_args", 1);
- }
-
- current[MEMBER_FUNC] = true;
- Language::memberfunctionHandler(n);
-
- registerMethod(n);
- current[MEMBER_FUNC] = false;
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * membervariableHandler()
- * ------------------------------------------------------------ */
-
- virtual int membervariableHandler(Node *n) {
- // REPORT("membervariableHandler",n);
- current[MEMBER_VAR] = true;
- Language::membervariableHandler(n);
- registerVariable(n);
- current[MEMBER_VAR] = false;
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * constructorHandler()
- *
- * Method for adding C++ member constructor
- * ------------------------------------------------------------ */
-
- virtual int constructorHandler(Node *n) {
- // REPORT("constructorHandler", n);
- current[CONSTRUCTOR] = true;
- Language::constructorHandler(n);
- current[CONSTRUCTOR] = false;
- //constructor_name = NewString(Getattr(n, "sym:name"));
- have_constructor = 1;
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * destructorHandler()
- * ------------------------------------------------------------ */
-
- virtual int destructorHandler(Node *n) {
- REPORT("destructorHandler", n);
- current[DESTRUCTOR] = true;
- Language::destructorHandler(n);
- current[DESTRUCTOR] = false;
- have_destructor = 1;
- destructor_action = Getattr(n, "wrap:action");
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * globalfunctionHandler()
- *
- * It can be called:
- * 1. Usual C/C++ global function.
- * 2. During class parsing for functions declared/defined as friend
- * 3. During class parsing from staticmemberfunctionHandler
- * ---------------------------------------------------------------------- */
-
- virtual int globalfunctionHandler(Node *n) {
- bool oldVal = current[NO_CPP];
- if (!current[STATIC_FUNC]) // If static function, don't switch to NO_CPP
- current[NO_CPP] = true;
- const int result = Language::globalfunctionHandler(n);
-
- if (!current[STATIC_FUNC]) // Register only if not called from static function handler
- registerMethod(n);
- current[NO_CPP] = oldVal;
- return result;
- }
-
- /* ----------------------------------------------------------------------
- * globalvariableHandler()
- *
- * Sets "current" array correctly
- * ---------------------------------------------------------------------- */
-
- virtual int globalvariableHandler(Node *n) {
- bool oldVal = current[NO_CPP];
- current[GLOBAL_VAR] = true;
- current[NO_CPP] = true;
-
- const int result = Language::globalvariableHandler(n);
- registerVariable(n);
-
- current[GLOBAL_VAR] = false;
- current[NO_CPP] = oldVal;
- return result;
- }
-
-
- /* -----------------------------------------------------------------------
- * staticmemberfunctionHandler()
- *
- * Wrap a static C++ function
- * ---------------------------------------------------------------------- */
-
- virtual int staticmemberfunctionHandler(Node *n) {
- REPORT("staticmemberfunctionHandler", n);
- current[STATIC_FUNC] = true;
-
- const int result = Language::staticmemberfunctionHandler(n);
- registerMethod(n);
-
- if (old_metatable_bindings && result == SWIG_OK && old_compatible_names) {
- Swig_require("lua_staticmemberfunctionHandler", n, "*lua:name", NIL);
- String *lua_name = Getattr(n, "lua:name");
- // Although this function uses Swig_name_member, it actually generates the Lua name,
- // not the C++ name. This is because an earlier version used such a scheme for static function
- // name generation and we have to maintain backward compatibility.
- String *compat_name = Swig_name_member(0, proxy_class_name, lua_name);
- Setattr(n, "lua:name", compat_name);
- registerMethod(n, true, getNSpace());
- Delete(compat_name);
- Swig_restore(n);
- }
-
- current[STATIC_FUNC] = false;;
- return result;
- }
-
- /* ------------------------------------------------------------
- * memberconstantHandler()
- *
- * Create a C++ constant
- * ------------------------------------------------------------ */
-
- virtual int memberconstantHandler(Node *n) {
- REPORT("memberconstantHandler", n);
- int result = Language::memberconstantHandler(n);
-
- return result;
- }
-
- /* ---------------------------------------------------------------------
- * staticmembervariableHandler()
- * --------------------------------------------------------------------- */
-
- virtual int staticmembervariableHandler(Node *n) {
- REPORT("staticmembervariableHandler", n);
- current[STATIC_VAR] = true;
- //String *symname = Getattr(n, "sym:name");
- int result = Language::staticmembervariableHandler(n);
- if (!GetFlag(n, "wrappedasconstant")) {
- registerVariable(n);
- }
-
- if (result == SWIG_OK) {
- // This will add static member variable to the class namespace with name ClassName_VarName
- if (old_metatable_bindings && old_compatible_names) {
- Swig_save("lua_staticmembervariableHandler", n, "lua:name", NIL);
- String *lua_name = Getattr(n, "lua:name");
- // Although this function uses Swig_name_member, it actually generates the Lua name,
- // not the C++ name. This is because an earlier version used such a scheme for static function
- // name generation and we have to maintain backward compatibility.
- String *v2_name = Swig_name_member(NIL, proxy_class_name, lua_name);
- if (!GetFlag(n, "wrappedasconstant")) {
- Setattr(n, "lua:name", v2_name);
- // Registering static var in the class parent nspace
- registerVariable(n, true, getNSpace());
- }
- // If static member variable was wrapped as a constant, then
- // constant wrapper has already performed all actions necessary for old_metatable_bindings
- Delete(v2_name);
- Swig_restore(n);
- }
- }
- current[STATIC_VAR] = false;
-
- return result;
- }
-
-
- /* ---------------------------------------------------------------------
- * external runtime generation
- * --------------------------------------------------------------------- */
-
- /* This is to support the usage
- SWIG -external-runtime <filename>
- The code consists of two functions:
- String *runtimeCode() // returns a large string with all the runtimes in
- String *defaultExternalRuntimeFilename() // returns the default filename
- I am writing a generic solution, even though SWIG-Lua only has one file right now...
- */
- String *runtimeCode() {
- String *s = NewString("");
- const char *filenames[] = { "luarun.swg", 0 }; // must be 0 terminated
-
- emitLuaFlavor(s);
-
- String *sfile = 0;
- for (int i = 0; filenames[i] != 0; i++) {
- sfile = Swig_include_sys(filenames[i]);
- if (!sfile) {
- Printf(stderr, "*** Unable to open '%s'\n", filenames[i]);
- } else {
- Append(s, sfile);
- Delete(sfile);
- }
- }
-
- return s;
- }
-
- String *defaultExternalRuntimeFilename() {
- return NewString("swigluarun.h");
- }
-
- /* ---------------------------------------------------------------------
- * helpers
- * --------------------------------------------------------------------- */
-
- void emitLuaFlavor(String *s) {
- if (elua_emulate) {
- Printf(s, "/*This is only emulation!*/\n");
- Printf(s, "#define SWIG_LUA_TARGET SWIG_LUA_FLAVOR_ELUA\n");
- Printf(s, "#define SWIG_LUA_ELUA_EMULATE\n");
- } else if (elua_ltr)
- Printf(s, "#define SWIG_LUA_TARGET SWIG_LUA_FLAVOR_ELUA\n");
- else if (eluac_ltr)
- Printf(s, "#define SWIG_LUA_TARGET SWIG_LUA_FLAVOR_ELUAC\n");
- else
- Printf(s, "#define SWIG_LUA_TARGET SWIG_LUA_FLAVOR_LUA\n");
- }
-
-
- /* -----------------------------------------------------------------------------
- * escapeCode()
- *
- * This is to convert the string of Lua code into a proper string, which can then be
- * emitted into the C/C++ code.
- * Basically it is a lot of search & replacing of odd sequences
- * ---------------------------------------------------------------------------- */
-
- void escapeCode(String *str) {
- //Printf(f_runtime,"/* original luacode:[[[\n%s\n]]]\n*/\n",str);
- Chop(str); // trim
- Replace(str, "\\", "\\\\", DOH_REPLACE_ANY); // \ to \\ (this must be done first)
- Replace(str, "\"", "\\\"", DOH_REPLACE_ANY); // " to \"
- Replace(str, "\n", "\\n\"\n \"", DOH_REPLACE_ANY); // \n to \n"\n" (ie quoting every line)
- //Printf(f_runtime,"/* hacked luacode:[[[\n%s\n]]]\n*/\n",str);
- }
-
- /* -----------------------------------------------------------------------------
- * rawGetCArraysHash(String *name)
- *
- * A small helper to hide implementation of how CArrays hashes are stored
- * ---------------------------------------------------------------------------- */
-
- Hash *rawGetCArraysHash(const_String_or_char_ptr name) {
- Hash *scope = symbolScopeLookup( name ? name : "" );
- if(!scope)
- return 0;
-
- Hash *carrays_hash = Getattr(scope, "lua:cdata");
- return carrays_hash;
- }
-
- /* -----------------------------------------------------------------------------
- * getCArraysHash()
- *
- * Each namespace can be described with a hash that stores C arrays
- * where members of the namespace should be added. All these hashes are stored
- * inside the symbols table, in pseudo-symbol for every namespace.
- * nspace could be NULL (NSPACE_TODO), that means functions and variables and classes
- * that are not in any namespace (this is default for SWIG unless %nspace feature is used).
- * You can later set some attributes that will affect behaviour of functions that use this hash:
- * "lua:no_namespaces" will disable "namespaces" array.
- * "lua:no_classes" will disable "classes" array.
- * For every component ("attributes", "methods", etc) there are subcomponents:
- * XXX:name - name of the C array that stores data for component
- * XXX:decl - statement with forward declaration of this array;
- * Namespace could be automatically registered to its parent if 'reg' == true. This can only be
- * done during the first call (a.k.a when nspace is created).
- * ---------------------------------------------------------------------------- */
-
- Hash *getCArraysHash(String *nspace, bool reg = true) {
- Hash *scope = symbolScopeLookup(nspace ? nspace : "");
- if(!scope) {
- symbolAddScope( nspace ? nspace : "" );
- scope = symbolScopeLookup(nspace ? nspace : "");
- assert(scope);
- }
- Hash *carrays_hash = Getattr(scope, "lua:cdata");
- if (carrays_hash != 0)
- return carrays_hash;
- carrays_hash = NewHash();
- String *mangled_name = 0;
- if (nspace == 0 || Len(nspace) == 0)
- mangled_name = NewString("SwigModule");
- else
- mangled_name = Swig_name_mangle(nspace);
- String *cname = NewStringf("swig_%s", mangled_name);
-
- Setattr(carrays_hash, "cname", cname);
-
- String *attr_tab = NewString("");
- String *attr_tab_name = NewStringf("swig_%s_attributes", mangled_name);
- String *attr_tab_decl = NewString("");
- Printv(attr_tab, "static swig_lua_attribute ", NIL);
- Printv(attr_tab, attr_tab_name, "[]", NIL);
- Printv(attr_tab_decl, attr_tab, ";\n", NIL);
- Printv(attr_tab, " = {\n", NIL);
- Setattr(carrays_hash, "attributes", attr_tab);
- Setattr(carrays_hash, "attributes:name", attr_tab_name);
- Setattr(carrays_hash, "attributes:decl", attr_tab_decl);
-
- String *methods_tab = NewString("");
- String *methods_tab_name = NewStringf("swig_%s_methods", mangled_name);
- String *methods_tab_decl = NewString("");
- if (elua_ltr || eluac_ltr) // In this case methods array also acts as namespace rotable
- Printf(methods_tab, "const LUA_REG_TYPE ");
- else
- Printf(methods_tab, "static swig_lua_method ");
- Printv(methods_tab, methods_tab_name, "[]", NIL);
- Printv(methods_tab_decl, methods_tab, ";\n", NIL);
- Printv(methods_tab, "= {\n", NIL);
- Setattr(carrays_hash, "methods", methods_tab);
- Setattr(carrays_hash, "methods:name", methods_tab_name);
- Setattr(carrays_hash, "methods:decl", methods_tab_decl);
-
- String *const_tab = NewString("");
- String *const_tab_name = NewStringf("swig_%s_constants", mangled_name);
- String *const_tab_decl = NewString("");
- if (elua_ltr || eluac_ltr) // In this case const array holds rotable with namespace constants
- Printf(const_tab, "const LUA_REG_TYPE ");
- else
- Printf(const_tab, "static swig_lua_const_info ");
- Printv(const_tab, const_tab_name, "[]", NIL);
- Printv(const_tab_decl, const_tab, ";", NIL);
- Printv(const_tab, "= {\n", NIL);
- Setattr(carrays_hash, "constants", const_tab);
- Setattr(carrays_hash, "constants:name", const_tab_name);
- Setattr(carrays_hash, "constants:decl", const_tab_decl);
-
- String *classes_tab = NewString("");
- String *classes_tab_name = NewStringf("swig_%s_classes", mangled_name);
- String *classes_tab_decl = NewString("");
- Printf(classes_tab, "static swig_lua_class* ");
- Printv(classes_tab, classes_tab_name, "[]", NIL);
- Printv(classes_tab_decl, classes_tab, ";", NIL);
- Printv(classes_tab, "= {\n", NIL);
- Setattr(carrays_hash, "classes", classes_tab);
- Setattr(carrays_hash, "classes:name", classes_tab_name);
- Setattr(carrays_hash, "classes:decl", classes_tab_decl);
-
- String *namespaces_tab = NewString("");
- String *namespaces_tab_name = NewStringf("swig_%s_namespaces", mangled_name);
- String *namespaces_tab_decl = NewString("");
- Printf(namespaces_tab, "static swig_lua_namespace* ");
- Printv(namespaces_tab, namespaces_tab_name, "[]", NIL);
- Printv(namespaces_tab_decl, namespaces_tab, ";", NIL);
- Printv(namespaces_tab, " = {\n", NIL);
- Setattr(carrays_hash, "namespaces", namespaces_tab);
- Setattr(carrays_hash, "namespaces:name", namespaces_tab_name);
- Setattr(carrays_hash, "namespaces:decl", namespaces_tab_decl);
-
- if (elua_ltr) {
- String *get_tab = NewString("");
- String *get_tab_name = NewStringf("swig_%s_get", mangled_name);
- String *get_tab_decl = NewString("");
- Printv(get_tab, "const LUA_REG_TYPE ", get_tab_name, "[]", NIL);
- Printv(get_tab_decl, get_tab, ";", NIL);
- Printv(get_tab, " = {\n", NIL);
- Setattr(carrays_hash, "get", get_tab);
- Setattr(carrays_hash, "get:name", get_tab_name);
- Setattr(carrays_hash, "get:decl", get_tab_decl);
-
- String *set_tab = NewString("");
- String *set_tab_name = NewStringf("swig_%s_set", mangled_name);
- String *set_tab_decl = NewString("");
- Printv(set_tab, "const LUA_REG_TYPE ", set_tab_name, "[]", NIL);
- Printv(set_tab_decl, set_tab, ";", NIL);
- Printv(set_tab, " = {\n", NIL);
- Setattr(carrays_hash, "set", set_tab);
- Setattr(carrays_hash, "set:name", set_tab_name);
- Setattr(carrays_hash, "set:decl", set_tab_decl);
-
- }
- if (!eluac_ltr) {
- String *metatable_tab = NewString("");
- String *metatable_tab_name = NewStringf("swig_%s_meta", mangled_name);
- String *metatable_tab_decl = NewString("");
- if (elua_ltr) // In this case const array holds rotable with namespace constants
- Printf(metatable_tab, "const LUA_REG_TYPE ");
- else
- Printf(metatable_tab, "static swig_lua_method ");
- Printv(metatable_tab, metatable_tab_name, "[]", NIL);
- Printv(metatable_tab_decl, metatable_tab, ";", NIL);
- Printv(metatable_tab, " = {\n", NIL);
- Setattr(carrays_hash, "metatable", metatable_tab);
- Setattr(carrays_hash, "metatable:name", metatable_tab_name);
- Setattr(carrays_hash, "metatable:decl", metatable_tab_decl);
- }
-
- Setattr(scope, "lua:cdata", carrays_hash);
- assert(rawGetCArraysHash(nspace));
-
- if (reg && nspace != 0 && Len(nspace) != 0 && GetFlag(carrays_hash, "lua:no_reg") == 0) {
- // Split names into components
- List *components = Split(nspace, '.', -1);
- String *parent_path = NewString("");
- int len = Len(components);
- String *name = Copy(Getitem(components, len - 1));
- for (int i = 0; i < len - 1; i++) {
- if (i > 0)
- Printv(parent_path, NSPACE_SEPARATOR, NIL);
- String *item = Getitem(components, i);
- Printv(parent_path, item, NIL);
- }
- Hash *parent = getCArraysHash(parent_path, true);
- String *namespaces_tab = Getattr(parent, "namespaces");
- Printv(namespaces_tab, "&", cname, ",\n", NIL);
- if (elua_ltr || eluac_ltr) {
- String *methods_tab = Getattr(parent, "methods");
- Printv(methods_tab, tab4, "{LSTRKEY(\"", name, "\")", ", LROVAL(", methods_tab_name, ")", "},\n", NIL);
- }
- Setattr(carrays_hash, "name", name);
-
- Delete(components);
- Delete(parent_path);
- } else if (!reg) // This namespace shouldn't be registered. Lets remember it.
- SetFlag(carrays_hash, "lua:no_reg");
-
- Delete(mangled_name);
- mangled_name = 0;
- return carrays_hash;
- }
-
- /* -----------------------------------------------------------------------------
- * closeCArraysHash()
- *
- * Functions add end markers {0,0,...,0} to all arrays, prints them to
- * output and marks hash as closed (lua:closed). Consequent attempts to
- * close the same hash will result in an error.
- * closeCArraysHash DOES NOT print structure that describes namespace, it only
- * prints array. You can use printCArraysDefinition to print structure.
- * if "lua:no_namespaces" is set, then array for "namespaces" won't be printed
- * if "lua:no_classes" is set, then array for "classes" won't be printed
- * ----------------------------------------------------------------------------- */
-
- void closeCArraysHash(String *nspace, File *output) {
- Hash *carrays_hash = rawGetCArraysHash(nspace);
- assert(carrays_hash);
- assert(GetFlag(carrays_hash, "lua:closed") == 0);
-
- SetFlag(carrays_hash, "lua:closed");
-
- // Do arrays describe class instance part or class static part
- const int is_instance = GetFlag(carrays_hash, "lua:class_instance");
-
-
- String *attr_tab = Getattr(carrays_hash, "attributes");
- Printf(attr_tab, " {0,0,0}\n};\n");
- Printv(output, attr_tab, NIL);
-
- String *const_tab = Getattr(carrays_hash, "constants");
- String *const_tab_name = Getattr(carrays_hash, "constants:name");
- if (elua_ltr || eluac_ltr)
- Printv(const_tab, tab4, "{LNILKEY, LNILVAL}\n", "};\n", NIL);
- else
- Printf(const_tab, " {0,0,0,0,0,0}\n};\n");
-
- // For the sake of compiling with -Wall -Werror we print constants
- // only when necessary
- int need_constants = 0;
- if ( (elua_ltr || eluac_ltr) && (old_metatable_bindings) )
- need_constants = 1;
- else if (!is_instance) // static part need constants tab
- need_constants = 1;
-
- if (need_constants)
- Printv(output, const_tab, NIL);
-
- if (elua_ltr) {
- // Put forward declaration of metatable array
- Printv(output, "extern ", Getattr(carrays_hash, "metatable:decl"), "\n", NIL);
- }
- String *methods_tab = Getattr(carrays_hash, "methods");
- String *metatable_tab_name = Getattr(carrays_hash, "metatable:name");
- if (elua_ltr || eluac_ltr) {
- if (old_metatable_bindings)
- Printv(methods_tab, tab4, "{LSTRKEY(\"const\"), LROVAL(", const_tab_name, ")},\n", NIL);
- if (elua_ltr) {
- Printv(methods_tab, tab4, "{LSTRKEY(\"__metatable\"), LROVAL(", metatable_tab_name, ")},\n", NIL);
- }
-
- Printv(methods_tab, tab4, "{LSTRKEY(\"__disown\"), LFUNCVAL(SWIG_Lua_class_disown)},\n", NIL);
- Printv(methods_tab, tab4, "{LNILKEY, LNILVAL}\n};\n", NIL);
- } else
- Printf(methods_tab, " {0,0}\n};\n");
- Printv(output, methods_tab, NIL);
-
- if (!GetFlag(carrays_hash, "lua:no_classes")) {
- String *classes_tab = Getattr(carrays_hash, "classes");
- Printf(classes_tab, " 0\n};\n");
- Printv(output, classes_tab, NIL);
- }
-
- if (!GetFlag(carrays_hash, "lua:no_namespaces")) {
- String *namespaces_tab = Getattr(carrays_hash, "namespaces");
- Printf(namespaces_tab, " 0\n};\n");
- Printv(output, namespaces_tab, NIL);
- }
- if (elua_ltr) {
- String *get_tab = Getattr(carrays_hash, "get");
- String *set_tab = Getattr(carrays_hash, "set");
- Printv(get_tab, tab4, "{LNILKEY, LNILVAL}\n};\n", NIL);
- Printv(set_tab, tab4, "{LNILKEY, LNILVAL}\n};\n", NIL);
- Printv(output, get_tab, NIL);
- Printv(output, set_tab, NIL);
- }
-
- // Heuristic whether we need to print metatable or not.
- // For the sake of compiling with -Wall -Werror we don't print
- // metatable for static part.
- int need_metatable = 0;
- if (eluac_ltr)
- need_metatable = 0;
- else if(!is_instance)
- need_metatable = 0;
- else
- need_metatable = 1;
-
- if (need_metatable) {
- String *metatable_tab = Getattr(carrays_hash, "metatable");
- assert(metatable_tab);
- if (elua_ltr) {
- String *get_tab_name = Getattr(carrays_hash, "get:name");
- String *set_tab_name = Getattr(carrays_hash, "set:name");
-
- if (GetFlag(carrays_hash, "lua:class_instance")) {
- Printv(metatable_tab, tab4, "{LSTRKEY(\"__index\"), LFUNCVAL(SWIG_Lua_class_get)},\n", NIL);
- Printv(metatable_tab, tab4, "{LSTRKEY(\"__newindex\"), LFUNCVAL(SWIG_Lua_class_set)},\n", NIL);
- } else {
- Printv(metatable_tab, tab4, "{LSTRKEY(\"__index\"), LFUNCVAL(SWIG_Lua_namespace_get)},\n", NIL);
- Printv(metatable_tab, tab4, "{LSTRKEY(\"__newindex\"), LFUNCVAL(SWIG_Lua_namespace_set)},\n", NIL);
- }
-
- Printv(metatable_tab, tab4, "{LSTRKEY(\"__gc\"), LFUNCVAL(SWIG_Lua_class_destruct)},\n", NIL);
- Printv(metatable_tab, tab4, "{LSTRKEY(\".get\"), LROVAL(", get_tab_name, ")},\n", NIL);
- Printv(metatable_tab, tab4, "{LSTRKEY(\".set\"), LROVAL(", set_tab_name, ")},\n", NIL);
- Printv(metatable_tab, tab4, "{LSTRKEY(\".fn\"), LROVAL(", Getattr(carrays_hash, "methods:name"), ")},\n", NIL);
-
- if (GetFlag(carrays_hash, "lua:class_instance")) {
- String *static_cls = Getattr(carrays_hash, "lua:class_instance:static_hash");
- assert(static_cls);
- // static_cls is swig_lua_namespace. This structure can't be used with eLua(LTR)
- // Instead a structure describing its methods is used
- String *static_cls_cname = Getattr(static_cls, "methods:name");
- assert(static_cls_cname);
- Printv(metatable_tab, tab4, "{LSTRKEY(\".static\"), LROVAL(", static_cls_cname, ")},\n", NIL);
- // Put forward declaration of this array
- Printv(output, "extern ", Getattr(static_cls, "methods:decl"), "\n", NIL);
- } else if (GetFlag(carrays_hash, "lua:class_static")) {
- Hash *instance_cls = Getattr(carrays_hash, "lua:class_static:instance_hash");
- assert(instance_cls);
- String *instance_cls_metatable_name = Getattr(instance_cls, "metatable:name");
- assert(instance_cls_metatable_name);
- Printv(metatable_tab, tab4, "{LSTRKEY(\".instance\"), LROVAL(", instance_cls_metatable_name, ")},\n", NIL);
- }
-
- Printv(metatable_tab, tab4, "{LNILKEY, LNILVAL}\n};\n", NIL);
- } else {
- Printf(metatable_tab, " {0,0}\n};\n");
- }
-
- Printv(output, metatable_tab, NIL);
- }
-
- Printv(output, "\n", NIL);
- }
-
- /* -----------------------------------------------------------------------------
- * closeNamespaces()
- *
- * Recursively close all non-closed namespaces. Prints data to dataOutput.
- * ----------------------------------------------------------------------------- */
-
- void closeNamespaces(File *dataOutput) {
- // Special handling for empty module.
- if (symbolScopeLookup("") == 0 || rawGetCArraysHash("") == 0) {
- // Module is empty. Create hash for global scope in order to have swig_SwigModule
- // variable in resulting file
- getCArraysHash(0);
- }
- // Because we can't directly access 'symtabs', instead we access
- // top-level scope and look on all scope pseudo-symbols in it.
- Hash *top_scope = symbolScopeLookup("");
- assert(top_scope);
- Iterator ki = First(top_scope);
- List *to_close = NewList();
- while (ki.key) {
- assert(ki.item);
- if (Getattr(ki.item, "sym:scope")) {
- // We have a pseudo symbol. Lets get actual scope for this pseudo symbol
- Hash *carrays_hash = rawGetCArraysHash(ki.key);
- assert(carrays_hash);
- if (GetFlag(carrays_hash, "lua:closed") == 0)
- Append(to_close, ki.key);
- }
- ki = Next(ki);
- }
- SortList(to_close, &compareByLen);
- int len = Len(to_close);
- for (int i = 0; i < len; i++) {
- String *key = Getitem(to_close, i);
- closeCArraysHash(key, dataOutput);
- Hash *carrays_hash = rawGetCArraysHash(key);
- String *name = 0; // name - name of the namespace as it should be visible in Lua
- if (DohLen(key) == 0) // This is global module
- name = module;
- else
- name = Getattr(carrays_hash, "name");
- assert(name);
- printCArraysDefinition(key, name, dataOutput);
- }
- Delete(to_close);
- }
-
- /* -----------------------------------------------------------------------------
- * printCArraysDefinition()
- *
- * This function prints to output a definition of namespace in form
- * swig_lua_namespace $cname = { attr_array, methods_array, ... , namespaces_array };
- * You can call this function as many times as is necessary.
- * 'name' is a user-visible name that this namespace will have in Lua. It shouldn't
- * be a fully qualified name, just its own name.
- * ----------------------------------------------------------------------------- */
-
- void printCArraysDefinition(String *nspace, String *name, File *output) {
- Hash *carrays_hash = getCArraysHash(nspace, false);
-
- String *cname = Getattr(carrays_hash, "cname"); // cname - name of the C structure that describes namespace
- assert(cname);
- Printv(output, "static swig_lua_namespace ", cname, " = ", NIL);
-
- String *null_string = NewString("0");
- String *attr_tab_name = Getattr(carrays_hash, "attributes:name");
- String *methods_tab_name = Getattr(carrays_hash, "methods:name");
- String *const_tab_name = Getattr(carrays_hash, "constants:name");
- String *classes_tab_name = Getattr(carrays_hash, "classes:name");
- String *namespaces_tab_name = Getattr(carrays_hash, "namespaces:name");
- bool has_classes = GetFlag(carrays_hash, "lua:no_classes") == 0;
- bool has_namespaces = GetFlag(carrays_hash, "lua:no_namespaces") == 0;
-
- Printv(output, "{\n",
- tab4, "\"", name, "\",\n",
- tab4, methods_tab_name, ",\n",
- tab4, attr_tab_name, ",\n",
- tab4, const_tab_name, ",\n",
- tab4, (has_classes) ? classes_tab_name : null_string, ",\n",
- tab4, (has_namespaces) ? namespaces_tab_name : null_string, "\n};\n", NIL);
- Delete(null_string);
- }
-
- /* -----------------------------------------------------------------------------
- * luaCurrentSymbolNSpace()
- *
- * This function determines actual namespace/scope where any symbol at the
- * current moment should be placed. It looks at the 'current' array
- * and depending on where are we - static class member/function,
- * instance class member/function or just global functions decides
- * where symbol should be put.
- * The namespace/scope doesn't depend from symbol, only from 'current'
- * ----------------------------------------------------------------------------- */
-
- String *luaCurrentSymbolNSpace() {
- String *scope = 0;
- // If outside class, than NSpace is used.
- // If inside class, but current[NO_CPP], then this is friend function. It belongs to NSpace
- if (!getCurrentClass() || current[NO_CPP]) {
- scope = getNSpace();
- } else if (current[ENUM_CONST] && !CPlusPlus ) {
- // Enums in C mode go to NSpace
- scope = getNSpace();
- } else {
- // If inside class, then either class static namespace or class fully qualified name is used
- assert(!current[NO_CPP]);
- if (current[STATIC_FUNC] || current[STATIC_VAR] || current[STATIC_CONST]) {
- scope = class_static_nspace;
- } else if (current[MEMBER_VAR] || current[CONSTRUCTOR] || current[DESTRUCTOR]
- || current[MEMBER_FUNC]) {
- scope = full_proxy_class_name;
- } else { // Friend functions are handled this way
- scope = class_static_nspace;
- }
- assert(scope);
- }
- return scope;
- }
-
- /* -----------------------------------------------------------------------------
- * luaAddSymbol()
- *
- * Our implementation of addSymbol. Determines scope correctly, then
- * forwards to Language::addSymbol
- * ----------------------------------------------------------------------------- */
-
- int luaAddSymbol(const String *s, const Node *n) {
- String *scope = luaCurrentSymbolNSpace();
- return luaAddSymbol(s, n, scope);
- }
-
- /* -----------------------------------------------------------------------------
- * luaAddSymbol()
- *
- * Overload. Enforces given scope. Actually, it simply forwards call to Language::addSymbol
- * ----------------------------------------------------------------------------- */
-
- int luaAddSymbol(const String *s, const Node *n, const_String_or_char_ptr scope) {
- int result = Language::addSymbol(s, n, scope);
- if (!result)
- Printf(stderr, "addSymbol(%s to scope %s) failed\n", s, scope);
- return result;
- }
-
-};
-
-/* -----------------------------------------------------------------------------
- * swig_lua() - Instantiate module
- * ----------------------------------------------------------------------------- */
-
-extern "C" Language *swig_lua(void) {
- return new LUA();
-}
diff --git a/contrib/tools/swig/Source/Modules/main.cxx b/contrib/tools/swig/Source/Modules/main.cxx
deleted file mode 100644
index f5bdec644c..0000000000
--- a/contrib/tools/swig/Source/Modules/main.cxx
+++ /dev/null
@@ -1,1407 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * main.cxx
- *
- * Main entry point to the SWIG core.
- * ----------------------------------------------------------------------------- */
-
-#include "swigconfig.h"
-
-#if defined(_WIN32)
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#endif
-
-#include "swigmod.h"
-
-#include "swigwarn.h"
-#include "cparse.h"
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h> // for INT_MAX
-
-// Global variables
-
-static Language *lang = 0; // Language method
-int CPlusPlus = 0;
-int Extend = 0; // Extend flag
-int ForceExtern = 0; // Force extern mode
-int GenerateDefault = 1; // Generate default constructors
-int Verbose = 0;
-int AddExtern = 0;
-int NoExcept = 0;
-int SwigRuntime = 0; // 0 = no option, 1 = -runtime, 2 = -noruntime
-extern "C" {
- int UseWrapperSuffix = 0; // If 1, append suffix to non-overloaded functions too.
-}
-
-/* Suppress warning messages for private inheritance, etc by default.
- These are enabled by command line option -Wextra.
-
- WARN_PARSE_PRIVATE_INHERIT 309
- WARN_PARSE_BUILTIN_NAME 321
- WARN_PARSE_REDUNDANT 322
- WARN_TYPE_ABSTRACT 403
- WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED 405
- WARN_LANG_OVERLOAD_CONST 512
- */
-#define EXTRA_WARNINGS "309,403,405,512,321,322"
-
-extern "C" {
- extern String *ModuleName;
- extern int ignore_nested_classes;
- extern int kwargs_supported;
-}
-
-/* usage string split into multiple parts otherwise string is too big for some compilers */
-/* naming conventions for commandline options - no underscores, no capital letters, join words together
- * except when using a common prefix, then use '-' to separate, eg the debug-xxx options */
-static const char *usage1 = (const char *) "\
-\nGeneral Options\n\
- -addextern - Add extra extern declarations\n\
- -c++ - Enable C++ processing\n\
- -co <file> - Check <file> out of the SWIG library\n\
- -copyctor - Automatically generate copy constructors wherever possible\n\
- -cpperraswarn - Treat the preprocessor #error statement as #warning (default)\n\
- -cppext <ext> - Change file extension of generated C++ files to <ext>\n\
- (default is cxx)\n\
- -copyright - Display copyright notices\n\
- -debug-classes - Display information about the classes found in the interface\n\
- -debug-module <n>- Display module parse tree at stages 1-4, <n> is a csv list of stages\n\
- -debug-symtabs - Display symbol tables information\n\
- -debug-symbols - Display target language symbols in the symbol tables\n\
- -debug-csymbols - Display C symbols in the symbol tables\n\
- -debug-lsymbols - Display target language layer symbols\n\
- -debug-quiet - Display less parse tree node debug info when using other -debug options\n\
- -debug-tags - Display information about the tags found in the interface\n\
- -debug-template - Display information for debugging templates\n\
- -debug-top <n> - Display entire parse tree at stages 1-4, <n> is a csv list of stages\n\
- -debug-typedef - Display information about the types and typedefs in the interface\n\
- -debug-typemap - Display typemap debugging information\n\
- -debug-tmsearch - Display typemap search debugging information\n\
- -debug-tmused - Display typemaps used debugging information\n\
- -directors - Turn on director mode for all the classes, mainly for testing\n\
- -dirprot - Turn on wrapping of protected members for director classes (default)\n\
- -D<symbol> - Define a symbol <symbol> (for conditional compilation)\n\
-";
-
-static const char *usage2 = (const char *) "\
- -E - Preprocess only, does not generate wrapper code\n\
- -external-runtime [file] - Export the SWIG runtime stack\n\
- -fakeversion <v>- Make SWIG fake the program version number to <v>\n\
- -fcompact - Compile in compact mode\n\
- -features <list>- Set global features, where <list> is a comma separated list of\n\
- features, eg -features directors,autodoc=1\n\
- If no explicit value is given to the feature, a default of 1 is used\n\
- -fastdispatch - Enable fast dispatch mode to produce faster overload dispatcher code\n\
- -Fmicrosoft - Display error/warning messages in Microsoft format\n\
- -Fstandard - Display error/warning messages in commonly used format\n\
- -fvirtual - Compile in virtual elimination mode\n\
- -help - Display help\n\
- -I- - Don't search the current directory\n\
- -I<dir> - Look for SWIG files in directory <dir>\n\
- -ignoremissing - Ignore missing include files\n\
- -importall - Follow all #include statements as imports\n\
- -includeall - Follow all #include statements\n\
- -l<ifile> - Include SWIG library file <ifile>\n\
-";
-
-static const char *usage3 = (const char *) "\
- -macroerrors - Report errors inside macros\n\
- -makedefault - Create default constructors/destructors (the default)\n\
- -M - List all dependencies\n\
- -MD - Is equivalent to `-M -MF <file>', except `-E' is not implied\n\
- -MF <file> - Generate dependencies into <file> and continue generating wrappers\n\
- -MM - List dependencies, but omit files in SWIG library\n\
- -MMD - Like `-MD', but omit files in SWIG library\n\
- -module <name> - Set module name to <name>\n\
- -MP - Generate phony targets for all dependencies\n\
- -MT <target> - Set the target of the rule emitted by dependency generation\n\
- -nocontract - Turn off contract checking\n\
- -nocpperraswarn - Do not treat the preprocessor #error statement as #warning\n\
- -nodefault - Do not generate default constructors nor default destructors\n\
- -nodefaultctor - Do not generate implicit default constructors\n\
- -nodefaultdtor - Do not generate implicit default destructors\n\
- -nodirprot - Do not wrap director protected members\n\
- -noexcept - Do not wrap exception specifiers\n\
- -nofastdispatch - Disable fast dispatch mode (default)\n\
- -nopreprocess - Skip the preprocessor step\n\
- -notemplatereduce - Disable reduction of the typedefs in templates\n\
-";
-
-static const char *usage4 = (const char *) "\
- -O - Enable the optimization options:\n\
- -fastdispatch -fvirtual\n\
- -o <outfile> - Set name of C/C++ output file to <outfile>\n\
- -oh <headfile> - Set name of C++ output header file for directors to <headfile>\n\
- -outcurrentdir - Set default output dir to current dir instead of input file's path\n\
- -outdir <dir> - Set language specific files output directory to <dir>\n\
- -pcreversion - Display PCRE2 version information\n\
- -small - Compile in virtual elimination and compact mode\n\
- -swiglib - Report location of SWIG library and exit\n\
- -templatereduce - Reduce all the typedefs in templates\n\
- -v - Run in verbose mode\n\
- -version - Display SWIG version number\n\
- -Wall - Remove all warning suppression, also implies -Wextra\n\
- -Wallkw - Enable keyword warnings for all the supported languages\n\
- -Werror - Treat warnings as errors\n\
- -Wextra - Adds the following additional warnings: " EXTRA_WARNINGS "\n\
- -w<list> - Suppress/add warning messages, eg -w401,+321 - see Warnings.html\n\
- -xmlout <file> - Write XML version of the parse tree to <file> after normal processing\n\
-\n\
-Options can also be defined using the SWIG_FEATURES environment variable, for example:\n\
-\n\
- $ SWIG_FEATURES=\"-Wall\"\n\
- $ export SWIG_FEATURES\n\
- $ swig -python interface.i\n\
-\n\
-is equivalent to:\n\
-\n\
- $ swig -Wall -python interface.i\n\
-\n\
-Arguments may also be passed in a file, separated by whitespace. For example:\n\
-\n\
- $ echo \"-Wall -python interface.i\" > args.txt\n\
- $ swig @args.txt\n\
-\n";
-
-// Local variables
-static String *LangSubDir = 0; // Target language library subdirectory
-static String *SwigLib = 0; // Library directory
-static String *SwigLibWinUnix = 0; // Extra library directory on Windows
-static int freeze = 0;
-static String *lang_config = 0;
-static const char *hpp_extension = "h";
-static const char *cpp_extension = "cxx";
-static const char *depends_extension = "d";
-static String *outdir = 0;
-static String *xmlout = 0;
-static int outcurrentdir = 0;
-static int help = 0;
-static int checkout = 0;
-static int cpp_only = 0;
-static int no_cpp = 0;
-static String *outfile_name = 0;
-static String *outfile_name_h = 0;
-static int tm_debug = 0;
-static int dump_symtabs = 0;
-static int dump_symbols = 0;
-static int dump_csymbols = 0;
-static int dump_lang_symbols = 0;
-static int dump_tags = 0;
-static int dump_module = 0;
-static int dump_top = 0;
-static int dump_xml = 0;
-static int dump_typedef = 0;
-static int dump_classes = 0;
-static int werror = 0;
-static int depend = 0;
-static int depend_only = 0;
-static int depend_phony = 0;
-static int memory_debug = 0;
-static int allkw = 0;
-static DOH *cpps = 0;
-static String *dependencies_file = 0;
-static String *dependencies_target = 0;
-static int external_runtime = 0;
-static String *external_runtime_name = 0;
-enum { STAGE1=1, STAGE2=2, STAGE3=4, STAGE4=8, STAGEOVERFLOW=16 };
-static List *libfiles = 0;
-static List *all_output_files = 0;
-
-/* -----------------------------------------------------------------------------
- * check_extension()
- *
- * Checks the extension of a file to see if we should emit extern declarations.
- * ----------------------------------------------------------------------------- */
-
-static bool check_extension(String *filename) {
- bool wanted = false;
- const char *name = Char(filename);
- if (!name)
- return 0;
- String *extension = Swig_file_extension(name);
- const char *c = Char(extension);
- if ((strcmp(c, ".c") == 0) ||
- (strcmp(c, ".C") == 0) || (strcmp(c, ".cc") == 0) || (strcmp(c, ".cxx") == 0) || (strcmp(c, ".c++") == 0) || (strcmp(c, ".cpp") == 0)) {
- wanted = true;
- }
- Delete(extension);
- return wanted;
-}
-
-/* -----------------------------------------------------------------------------
- * install_opts()
- *
- * Install all command line options as preprocessor symbols
- * ----------------------------------------------------------------------------- */
-
-static void install_opts(int argc, char *argv[]) {
- int i;
- int noopt = 0;
- char *c;
- for (i = 1; i < (argc - 1); i++) {
- if (argv[i]) {
- if ((*argv[i] == '-') && (!isupper(*(argv[i] + 1)))) {
- String *opt = NewStringf("SWIGOPT%(upper)s", argv[i]);
- Replaceall(opt, "-", "_");
- c = Char(opt);
- noopt = 0;
- while (*c) {
- if (!(isalnum(*c) || (*c == '_'))) {
- noopt = 1;
- break;
- }
- c++;
- }
- if (((i + 1) < (argc - 1)) && (argv[i + 1]) && (*argv[i + 1] != '-')) {
- Printf(opt, " %s", argv[i + 1]);
- i++;
- } else {
- Printf(opt, " 1");
- }
- if (!noopt) {
- /* Printf(stdout,"%s\n", opt); */
- Preprocessor_define(opt, 0);
- }
- Delete(opt);
- }
- }
- }
-}
-
-/* -----------------------------------------------------------------------------
- * decode_numbers_list()
- *
- * Decode comma separated list into a binary number of the inputs or'd together
- * eg list="1,4" will return (2^0 || 2^3) = 0x1001
- * ----------------------------------------------------------------------------- */
-
-static unsigned int decode_numbers_list(String *numlist) {
- unsigned int decoded_number = 0;
- if (numlist) {
- List *numbers = Split(numlist, ',', INT_MAX);
- if (numbers && Len(numbers) > 0) {
- for (Iterator it = First(numbers); it.item; it = Next(it)) {
- String *numstring = it.item;
- // TODO: check that it is a number
- int number = atoi(Char(numstring));
- if (number > 0 && number <= 16) {
- decoded_number |= (1 << (number-1));
- }
- }
- }
- }
- return decoded_number;
-}
-
-/* -----------------------------------------------------------------------------
- * Sets the output directory for language specific (proxy) files from the
- * C wrapper file if not set and corrects the directory name and adds a trailing
- * file separator if necessary.
- * ----------------------------------------------------------------------------- */
-
-static void configure_outdir(const String *c_wrapper_outfile) {
-
- // Use the C wrapper file's directory if the output directory has not been set by user
- if (!outdir || Len(outdir) == 0)
- outdir = Swig_file_dirname(c_wrapper_outfile);
-
- Swig_filename_correct(outdir);
-
- // Add trailing file delimiter if not present in output directory name
- if (Len(outdir) > 0) {
- const char *outd = Char(outdir);
- if (strcmp(outd + strlen(outd) - strlen(SWIG_FILE_DELIMITER), SWIG_FILE_DELIMITER) != 0)
- Printv(outdir, SWIG_FILE_DELIMITER, NIL);
- }
-}
-
-/* This function sets the name of the configuration file */
-void SWIG_config_file(const_String_or_char_ptr filename) {
- lang_config = NewString(filename);
-}
-
-/* Sets the target language subdirectory name */
-void SWIG_library_directory(const char *subdirectory) {
- LangSubDir = NewString(subdirectory);
-}
-
-// Returns the directory for generating language specific files (non C/C++ files)
-const String *SWIG_output_directory() {
- assert(outdir);
- return outdir;
-}
-
-void SWIG_config_cppext(const char *ext) {
- cpp_extension = ext;
-}
-
-List *SWIG_output_files() {
- assert(all_output_files);
- return all_output_files;
-}
-
-void SWIG_setfeature(const char *cfeature, const char *cvalue) {
- Hash *features_hash = Swig_cparse_features();
- String *name = NewString("");
- String *fname = NewString(cfeature);
- String *fvalue = NewString(cvalue);
- Swig_feature_set(features_hash, name, 0, fname, fvalue, 0);
- Delete(name);
- Delete(fname);
- Delete(fvalue);
-}
-
-
-void SWIG_setfeatures(const char *c) {
- char feature[64];
- char *fb = feature;
- char *fe = fb + 63;
- Hash *features_hash = Swig_cparse_features();
- String *name = NewString("");
- /* Printf(stderr,"all features %s\n", c); */
- while (*c) {
- char *f = fb;
- String *fname = NewString("feature:");
- String *fvalue = NewString("");
- while ((f != fe) && *c != '=' && *c != ',' && *c) {
- *(f++) = *(c++);
- }
- *f = 0;
- Printf(fname, "%s", feature);
- if (*c && *(c++) == '=') {
- char value[64];
- char *v = value;
- char *ve = v + 63;
- while ((v != ve) && *c != ',' && *c && !isspace(*c)) {
- *(v++) = *(c++);
- }
- *v = 0;
- Printf(fvalue, "%s", value);
- } else {
- Printf(fvalue, "1");
- }
- /* Printf(stderr,"%s %s\n", fname, fvalue); */
- Swig_feature_set(features_hash, name, 0, fname, fvalue, 0);
- Delete(fname);
- Delete(fvalue);
- }
- Delete(name);
-}
-
-/* This function handles the -external-runtime command option */
-static void SWIG_dump_runtime() {
- String *outfile;
- File *runtime;
- String *s;
-
- outfile = external_runtime_name;
- if (!outfile) {
- outfile = lang->defaultExternalRuntimeFilename();
- if (!outfile) {
- Printf(stderr, "*** Please provide a filename for the external runtime\n");
- Exit(EXIT_FAILURE);
- }
- }
-
- runtime = NewFile(outfile, "w", SWIG_output_files());
- if (!runtime) {
- FileErrorDisplay(outfile);
- Exit(EXIT_FAILURE);
- }
-
- Swig_banner(runtime);
- Printf(runtime, "\n");
-
- s = Swig_include_sys("swiglabels.swg");
- if (!s) {
- Printf(stderr, "*** Unable to open 'swiglabels.swg'\n");
- Delete(runtime);
- Exit(EXIT_FAILURE);
- }
- Printf(runtime, "%s", s);
- Delete(s);
-
- s = Swig_include_sys("swigerrors.swg");
- if (!s) {
- Printf(stderr, "*** Unable to open 'swigerrors.swg'\n");
- Delete(runtime);
- Exit(EXIT_FAILURE);
- }
- Printf(runtime, "%s", s);
- Delete(s);
-
- s = Swig_include_sys("swigrun.swg");
- if (!s) {
- Printf(stderr, "*** Unable to open 'swigrun.swg'\n");
- Delete(runtime);
- Exit(EXIT_FAILURE);
- }
- Printf(runtime, "%s", s);
- Delete(s);
-
- s = lang->runtimeCode();
- Printf(runtime, "%s", s);
- Delete(s);
-
- s = Swig_include_sys("runtime.swg");
- if (!s) {
- Printf(stderr, "*** Unable to open 'runtime.swg'\n");
- Delete(runtime);
- Exit(EXIT_FAILURE);
- }
- Printf(runtime, "%s", s);
- Delete(s);
-
- Delete(runtime);
- Exit(EXIT_SUCCESS);
-}
-
-static void getoptions(int argc, char *argv[]) {
- int i;
- // Get options
- for (i = 1; i < argc; i++) {
- if (argv[i] && !Swig_check_marked(i)) {
- if (strncmp(argv[i], "-I-", 3) == 0) {
- // Don't push/pop directories
- Swig_set_push_dir(0);
- Swig_mark_arg(i);
- } else if (strncmp(argv[i], "-I", 2) == 0) {
- // Add a new directory search path
- Swig_add_directory((String_or_char*)(argv[i] + 2));
- Swig_mark_arg(i);
- } else if (strncmp(argv[i], "-D", 2) == 0) {
- String *d = NewString(argv[i] + 2);
- if (Replace(d, "=", " ", DOH_REPLACE_FIRST) == 0) {
- // Match C preprocessor behaviour whereby -DFOO sets FOO=1.
- Append(d, " 1");
- }
- Preprocessor_define((DOH *) d, 0);
- Delete(d);
- // Create a symbol
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-E") == 0) {
- cpp_only = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nopreprocess") == 0) {
- no_cpp = 1;
- Swig_mark_arg(i);
- } else if ((strcmp(argv[i], "-verbose") == 0) || (strcmp(argv[i], "-v") == 0)) {
- Verbose = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-c++") == 0) {
- CPlusPlus = 1;
- Preprocessor_define((DOH *) "__cplusplus __cplusplus", 0);
- Swig_cparse_cplusplus(1);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-c++out") == 0) {
- // Undocumented
- Swig_cparse_cplusplusout(1);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-fcompact") == 0) {
- Wrapper_compact_print_mode_set(1);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-fvirtual") == 0) {
- Wrapper_virtual_elimination_mode_set(1);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-fastdispatch") == 0) {
- Wrapper_fast_dispatch_mode_set(1);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nofastdispatch") == 0) {
- Wrapper_fast_dispatch_mode_set(0);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-naturalvar") == 0) {
- Wrapper_naturalvar_mode_set(1);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-directors") == 0) {
- SWIG_setfeature("feature:director", "1");
- Wrapper_director_mode_set(1);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-dirprot") == 0) {
- Wrapper_director_protected_mode_set(1);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nodirprot") == 0) {
- Wrapper_director_protected_mode_set(0);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-pcreversion") == 0) {
- String *version = Swig_pcre_version();
- Printf(stdout, "%s\n", version);
- Delete(version);
- Swig_mark_arg(i);
- Exit(EXIT_SUCCESS);
- } else if (strcmp(argv[i], "-small") == 0) {
- Wrapper_compact_print_mode_set(1);
- Wrapper_virtual_elimination_mode_set(1);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-runtime") == 0) { // Used to also accept -c. removed in swig-1.3.36
- Swig_mark_arg(i);
- Swig_warning(WARN_DEPRECATED_OPTC, "SWIG", 1, "-runtime, -noruntime command line options are deprecated.\n");
- SwigRuntime = 1;
- } else if (strcmp(argv[i], "-noruntime") == 0) {
- Swig_mark_arg(i);
- Swig_warning(WARN_DEPRECATED_OPTC, "SWIG", 1, "-runtime, -noruntime command line options are deprecated.\n");
- SwigRuntime = 2;
- } else if (strcmp(argv[i], "-external-runtime") == 0) {
- external_runtime = 1;
- Swig_mark_arg(i);
- if (argv[i + 1]) {
- external_runtime_name = NewString(argv[i + 1]);
- Swig_mark_arg(i + 1);
- i++;
- }
- } else if ((strcmp(argv[i], "-make_default") == 0) || (strcmp(argv[i], "-makedefault") == 0)) {
- GenerateDefault = 1;
- Swig_mark_arg(i);
- } else if ((strcmp(argv[i], "-no_default") == 0) || (strcmp(argv[i], "-nodefault") == 0)) {
- GenerateDefault = 0;
- Swig_warning(WARN_DEPRECATED_NODEFAULT, "SWIG", 1, "dangerous, use -nodefaultctor, -nodefaultdtor instead.\n");
- Swig_mark_arg(i);
- } else if ((strcmp(argv[i], "-nodefaultctor") == 0)) {
- SWIG_setfeature("feature:nodefaultctor", "1");
- Swig_mark_arg(i);
- } else if ((strcmp(argv[i], "-nodefaultdtor") == 0)) {
- SWIG_setfeature("feature:nodefaultdtor", "1");
- Swig_mark_arg(i);
- } else if ((strcmp(argv[i], "-copyctor") == 0)) {
- SWIG_setfeature("feature:copyctor", "1");
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-noexcept") == 0) {
- NoExcept = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-noextern") == 0) {
- Swig_warning(WARN_DEPRECATED_NOEXTERN, "SWIG", 1, "-noextern command line option is deprecated; extern is no longer generated by default.\n");
- AddExtern = 0;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-addextern") == 0) {
- AddExtern = 1;
- Swig_mark_arg(i);
- } else if ((strcmp(argv[i], "-debug-template") == 0) || (strcmp(argv[i], "-debug_template") == 0) || (strcmp(argv[i], "-show_templates") == 0)) {
- Swig_cparse_debug_templates(1);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-templatereduce") == 0) {
- SWIG_cparse_template_reduce(1);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-notemplatereduce") == 0) {
- SWIG_cparse_template_reduce(0);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-macroerrors") == 0) {
- Swig_cparse_follow_locators(1);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-swiglib") == 0) {
- Printf(stdout, "%s\n", SwigLib);
- if (SwigLibWinUnix)
- Printf(stdout, "%s\n", SwigLibWinUnix);
- Exit(EXIT_SUCCESS);
- } else if (strcmp(argv[i], "-o") == 0) {
- Swig_mark_arg(i);
- if (argv[i + 1]) {
- outfile_name = NewString(argv[i + 1]);
- Swig_filename_correct(outfile_name);
- if (!outfile_name_h || !dependencies_file) {
- char *ext = strrchr(Char(outfile_name), '.');
- String *basename = ext ? NewStringWithSize(Char(outfile_name), (int)(Char(ext) - Char(outfile_name))) : NewString(outfile_name);
- if (!dependencies_file) {
- dependencies_file = NewStringf("%s.%s", basename, depends_extension);
- }
- if (!outfile_name_h) {
- Printf(basename, ".%s", hpp_extension);
- outfile_name_h = NewString(basename);
- }
- Delete(basename);
- }
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-oh") == 0) {
- Swig_mark_arg(i);
- if (argv[i + 1]) {
- outfile_name_h = NewString(argv[i + 1]);
- Swig_filename_correct(outfile_name_h);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-fakeversion") == 0) {
- Swig_mark_arg(i);
- if (argv[i + 1]) {
- Swig_set_fakeversion(argv[i + 1]);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-version") == 0) {
- fprintf(stdout, "\nSWIG Version %s\n", Swig_package_version());
- fprintf(stdout, "\nCompiled with %s [%s]\n", SWIG_CXX, SWIG_PLATFORM);
- fprintf(stdout, "\nConfigured options: %cpcre\n",
-#ifdef HAVE_PCRE
- '+'
-#else
- '-'
-#endif
- );
- fprintf(stdout, "\nPlease see %s for reporting bugs and further information\n", PACKAGE_BUGREPORT);
- Exit(EXIT_SUCCESS);
- } else if (strcmp(argv[i], "-copyright") == 0) {
- fprintf(stdout, "\nSWIG Version %s\n", Swig_package_version());
- fprintf(stdout, "Copyright (c) 1995-1998\n");
- fprintf(stdout, "University of Utah and the Regents of the University of California\n");
- fprintf(stdout, "Copyright (c) 1998-2005\n");
- fprintf(stdout, "University of Chicago\n");
- fprintf(stdout, "Copyright (c) 2005-2006\n");
- fprintf(stdout, "Arizona Board of Regents (University of Arizona)\n");
- Exit(EXIT_SUCCESS);
- } else if (strncmp(argv[i], "-l", 2) == 0) {
- // Add a new directory search path
- Append(libfiles, argv[i] + 2);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-co") == 0) {
- checkout = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-features") == 0) {
- Swig_mark_arg(i);
- if (argv[i + 1]) {
- SWIG_setfeatures(argv[i + 1]);
- Swig_mark_arg(i + 1);
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-freeze") == 0) {
- freeze = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-includeall") == 0) {
- Preprocessor_include_all(1);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-importall") == 0) {
- Preprocessor_import_all(1);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-ignoremissing") == 0) {
- Preprocessor_ignore_missing(1);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-cpperraswarn") == 0) {
- Preprocessor_error_as_warning(1);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nocpperraswarn") == 0) {
- Preprocessor_error_as_warning(0);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-cppext") == 0) {
- Swig_mark_arg(i);
- if (argv[i + 1]) {
- SWIG_config_cppext(argv[i + 1]);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if ((strcmp(argv[i], "-debug-typemap") == 0) || (strcmp(argv[i], "-debug_typemap") == 0) || (strcmp(argv[i], "-tm_debug") == 0)) {
- tm_debug = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-debug-tmsearch") == 0) {
- Swig_typemap_search_debug_set();
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-debug-tmused") == 0) {
- Swig_typemap_used_debug_set();
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-module") == 0) {
- Swig_mark_arg(i);
- if (argv[i + 1]) {
- ModuleName = NewString(argv[i + 1]);
- Swig_mark_arg(i + 1);
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-M") == 0) {
- depend = 1;
- depend_only = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-MM") == 0) {
- depend = 2;
- depend_only = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-MF") == 0) {
- Swig_mark_arg(i);
- if (argv[i + 1]) {
- dependencies_file = NewString(argv[i + 1]);
- Swig_mark_arg(i + 1);
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-MD") == 0) {
- depend = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-MMD") == 0) {
- depend = 2;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-MP") == 0) {
- depend_phony = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-MT") == 0) {
- Swig_mark_arg(i);
- if (argv[i + 1]) {
- if (!dependencies_target)
- dependencies_target = NewString(argv[i + 1]);
- else
- Printf(dependencies_target, " %s", argv[i + 1]);
- Swig_mark_arg(i + 1);
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-outdir") == 0) {
- Swig_mark_arg(i);
- if (argv[i + 1]) {
- outdir = NewString(argv[i + 1]);
- Swig_mark_arg(i + 1);
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-outcurrentdir") == 0) {
- Swig_mark_arg(i);
- outcurrentdir = 1;
- } else if (strcmp(argv[i], "-Wall") == 0) {
- Swig_mark_arg(i);
- Swig_warnall();
- } else if (strcmp(argv[i], "-Wallkw") == 0) {
- allkw = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-Werror") == 0) {
- werror = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-Wextra") == 0) {
- Swig_mark_arg(i);
- Swig_warnfilter(EXTRA_WARNINGS, 0);
- } else if (strncmp(argv[i], "-w", 2) == 0) {
- Swig_mark_arg(i);
- Swig_warnfilter(argv[i] + 2, 1);
- } else if (strcmp(argv[i], "-debug-quiet") == 0) {
- Swig_print_quiet(1);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-debug-symtabs") == 0) {
- dump_symtabs = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-debug-symbols") == 0) {
- dump_symbols = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-debug-csymbols") == 0) {
- dump_csymbols = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-debug-lsymbols") == 0) {
- dump_lang_symbols = 1;
- Swig_mark_arg(i);
- } else if ((strcmp(argv[i], "-debug-tags") == 0) || (strcmp(argv[i], "-dump_tags") == 0)) {
- dump_tags = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-debug-top") == 0) {
- Swig_mark_arg(i);
- if (argv[i + 1]) {
- String *dump_list = NewString(argv[i + 1]);
- dump_top = decode_numbers_list(dump_list);
- if (dump_top < STAGE1 || dump_top >= STAGEOVERFLOW)
- Swig_arg_error();
- else
- Swig_mark_arg(i + 1);
- Delete(dump_list);
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-debug-module") == 0) {
- Swig_mark_arg(i);
- if (argv[i + 1]) {
- String *dump_list = NewString(argv[i + 1]);
- dump_module = decode_numbers_list(dump_list);
- if (dump_module < STAGE1 || dump_module >= STAGEOVERFLOW)
- Swig_arg_error();
- else
- Swig_mark_arg(i + 1);
- Delete(dump_list);
- } else {
- Swig_arg_error();
- }
- } else if ((strcmp(argv[i], "-dump_tree") == 0) || (strcmp(argv[i], "-dump_top") == 0)) {
- dump_top |= STAGE4;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-dump_module") == 0) {
- dump_module |= STAGE4;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-dump_parse_module") == 0) {
- dump_module |= STAGE1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-dump_parse_top") == 0) {
- dump_top |= STAGE1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-dump_xml") == 0) {
- dump_xml = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-xmlout") == 0) {
- dump_xml = 1;
- Swig_mark_arg(i);
- if (argv[i + 1]) {
- xmlout = NewString(argv[i + 1]);
- Swig_mark_arg(i + 1);
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-nocontract") == 0) {
- Swig_mark_arg(i);
- Swig_contract_mode_set(0);
- } else if ((strcmp(argv[i], "-debug-typedef") == 0) || (strcmp(argv[i], "-dump_typedef") == 0)) {
- dump_typedef = 1;
- Swig_mark_arg(i);
- } else if ((strcmp(argv[i], "-debug-classes") == 0) || (strcmp(argv[i], "-dump_classes") == 0)) {
- dump_classes = 1;
- Swig_mark_arg(i);
- } else if ((strcmp(argv[i], "-debug-memory") == 0) || (strcmp(argv[i], "-dump_memory") == 0)) {
- memory_debug = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-Fstandard") == 0) {
- Swig_error_msg_format(EMF_STANDARD);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-Fmicrosoft") == 0) {
- Swig_error_msg_format(EMF_MICROSOFT);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-O") == 0) {
- Wrapper_virtual_elimination_mode_set(1);
- Wrapper_fast_dispatch_mode_set(1);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-help") == 0) {
- fputs(usage1, stdout);
- fputs(usage2, stdout);
- fputs(usage3, stdout);
- fputs(usage4, stdout);
- Swig_mark_arg(i);
- help = 1;
- }
- }
- }
-}
-
-static void SWIG_exit_handler(int status);
-
-int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
- char *c;
-
- /* Set function for Exit() to call. */
- SetExitHandler(SWIG_exit_handler);
-
- /* Initialize the SWIG core */
- Swig_init();
-
- // Default warning suppression
- Swig_warnfilter(EXTRA_WARNINGS, 1);
-
- // Initialize the preprocessor
- Preprocessor_init();
-
- // Set lang to a dummy value if no target language was specified so we
- // can process options enough to handle -version, etc.
- lang = tlm ? tlm->fac() : new Language;
-
- // Set up some default symbols (available in both SWIG interface files
- // and C files)
-
- Preprocessor_define((DOH *) "SWIG 1", 0);
- Preprocessor_define((DOH *) "__STDC__", 0);
-
- String *vers = Swig_package_version_hex();
- Preprocessor_define(vers, 0);
- Delete(vers);
-
- Swig_contract_mode_set(1);
-
- /* Turn off directors mode */
- Wrapper_director_mode_set(0);
- Wrapper_director_protected_mode_set(1);
-
- // Inform the parser if the nested classes should be ignored unless explicitly told otherwise via feature:flatnested
- ignore_nested_classes = lang->nestedClassesSupport() == Language::NCS_Unknown ? 1 : 0;
-
- kwargs_supported = lang->kwargsSupport() ? 1 : 0;
-
- // Create Library search directories
-
- // Check for SWIG_LIB environment variable
- if ((c = getenv("SWIG_LIB")) == (char *) 0) {
-#if defined(_WIN32)
- char buf[MAX_PATH];
- char *p;
- if (!(GetModuleFileName(0, buf, MAX_PATH) == 0 || (p = strrchr(buf, '\\')) == 0)) {
- *(p + 1) = '\0';
- SwigLib = NewStringf("%sLib", buf); // Native windows installation path
- } else {
- SwigLib = NewStringf(""); // Unexpected error
- }
- if (Len(SWIG_LIB_WIN_UNIX) > 0)
- SwigLibWinUnix = NewString(SWIG_LIB_WIN_UNIX); // Unix installation path using a drive letter (for msys/mingw)
-#else
- SwigLib = NewString(SWIG_LIB);
-#endif
- } else {
- SwigLib = NewString(c);
- }
-
- libfiles = NewList();
- all_output_files = NewList();
-
- /* Check for SWIG_FEATURES environment variable */
-
- getoptions(argc, argv);
-
- // Define the __cplusplus symbol
- if (CPlusPlus)
- Preprocessor_define((DOH *) "__cplusplus __cplusplus", 0);
-
- // Parse language dependent options
- lang->main(argc, argv);
-
- if (help) {
- Printf(stdout, "\nNote: 'swig -<lang> -help' displays options for a specific target language.\n\n");
- Exit(EXIT_SUCCESS); // Exit if we're in help mode
- }
-
- // Check all of the options to make sure we're cool.
- // Don't check for an input file if -external-runtime is passed
- Swig_check_options(external_runtime ? 0 : 1);
-
- if (CPlusPlus && cparse_cplusplusout) {
- Printf(stderr, "The -c++out option is for C input but C++ input has been requested via -c++\n");
- Exit(EXIT_FAILURE);
- }
-
- install_opts(argc, argv);
-
- // Add language dependent directory to the search path
- {
- String *rl = NewString("");
- Printf(rl, ".%sswig_lib%s%s", SWIG_FILE_DELIMITER, SWIG_FILE_DELIMITER, LangSubDir);
- Swig_add_directory(rl);
- if (SwigLibWinUnix) {
- rl = NewString("");
- Printf(rl, "%s%s%s", SwigLibWinUnix, SWIG_FILE_DELIMITER, LangSubDir);
- Swig_add_directory(rl);
- }
- rl = NewString("");
- Printf(rl, "%s%s%s", SwigLib, SWIG_FILE_DELIMITER, LangSubDir);
- Swig_add_directory(rl);
- }
-
- Swig_add_directory((String *) "." SWIG_FILE_DELIMITER "swig_lib");
- if (SwigLibWinUnix)
- Swig_add_directory((String *) SwigLibWinUnix);
- Swig_add_directory(SwigLib);
-
- if (Verbose) {
- Printf(stdout, "Language subdirectory: %s\n", LangSubDir);
- Printf(stdout, "Search paths:\n");
- List *sp = Swig_search_path();
- Iterator s;
- for (s = First(sp); s.item; s = Next(s)) {
- Printf(stdout, " %s\n", s.item);
- }
- }
- // handle the -external-runtime argument
- if (external_runtime)
- SWIG_dump_runtime();
-
- // If we made it this far, looks good. go for it....
-
- input_file = NewString(argv[argc - 1]);
- Swig_filename_correct(input_file);
-
- // If the user has requested to check out a file, handle that
- if (checkout) {
- DOH *s;
- String *outfile = input_file;
- if (outfile_name)
- outfile = outfile_name;
-
- if (Verbose)
- Printf(stdout, "Handling checkout...\n");
-
- s = Swig_include(input_file);
- if (!s) {
- Printf(stderr, "Unable to locate '%s' in the SWIG library.\n", input_file);
- } else {
- FILE *f = Swig_open(outfile);
- if (f) {
- fclose(f);
- Printf(stderr, "File '%s' already exists. Checkout aborted.\n", outfile);
- } else {
- File *f_outfile = NewFile(outfile, "w", SWIG_output_files());
- if (!f_outfile) {
- FileErrorDisplay(outfile);
- Exit(EXIT_FAILURE);
- } else {
- if (Verbose)
- Printf(stdout, "'%s' checked out from the SWIG library.\n", outfile);
- Printv(f_outfile, s, NIL);
- Delete(f_outfile);
- }
- }
- }
- } else {
- // Run the preprocessor
- if (Verbose)
- Printf(stdout, "Preprocessing...\n");
-
- {
- int i;
- String *fs = NewString("");
- FILE *df = Swig_open(input_file);
- if (!df) {
- df = Swig_include_open(input_file);
- if (!df) {
- char *cfile = Char(input_file);
- if (cfile && cfile[0] == '-') {
- Printf(stderr, "Unable to find option or file '%s', ", input_file);
- Printf(stderr, "Use 'swig -help' for more information.\n");
- } else {
- Printf(stderr, "Unable to find file '%s'.\n", input_file);
- }
- Exit(EXIT_FAILURE);
- } else {
- Swig_warning(WARN_DEPRECATED_INPUT_FILE, "SWIG", 1, "Use of the include path to find the input file is deprecated and will not work with ccache. Please include the path when specifying the input file.\n"); // so that behaviour is like c/c++ compilers
- }
- }
-
- if (!tlm) {
- Printf(stderr, "No target language specified.\n");
- Printf(stderr, "Use 'swig -help' for more information.\n");
- Exit(EXIT_FAILURE);
- }
-
- if (!no_cpp) {
- fclose(df);
- Printf(fs, "%%include <swig.swg>\n");
- if (allkw) {
- Printf(fs, "%%include <allkw.swg>\n");
- }
- if (lang_config) {
- Printf(fs, "\n%%include <%s>\n", lang_config);
- }
- Printf(fs, "%%include(maininput=\"%s\") \"%s\"\n", Swig_filename_escape(input_file), Swig_filename_escape(Swig_last_file()));
- for (i = 0; i < Len(libfiles); i++) {
- Printf(fs, "\n%%include \"%s\"\n", Swig_filename_escape(Getitem(libfiles, i)));
- }
- Seek(fs, 0, SEEK_SET);
- cpps = Preprocessor_parse(fs);
- Delete(fs);
- } else {
- cpps = Swig_read_file(df);
- fclose(df);
- }
- if (Swig_error_count()) {
- Exit(EXIT_FAILURE);
- }
- if (cpp_only) {
- Printf(stdout, "%s", cpps);
- Exit(EXIT_SUCCESS);
- }
- if (depend) {
- if (!no_cpp) {
- String *outfile;
- File *f_dependencies_file = 0;
-
- String *inputfile_filename = outcurrentdir ? Swig_file_filename(input_file): Copy(input_file);
- String *basename = Swig_file_basename(inputfile_filename);
- if (!outfile_name) {
- if (CPlusPlus || lang->cplus_runtime_mode()) {
- outfile = NewStringf("%s_wrap.%s", basename, cpp_extension);
- } else {
- outfile = NewStringf("%s_wrap.c", basename);
- }
- } else {
- outfile = NewString(outfile_name);
- }
- if (dependencies_file && Len(dependencies_file) != 0) {
- f_dependencies_file = NewFile(dependencies_file, "w", SWIG_output_files());
- if (!f_dependencies_file) {
- FileErrorDisplay(dependencies_file);
- Exit(EXIT_FAILURE);
- }
- } else if (!depend_only) {
- String *filename = NewStringf("%s_wrap.%s", basename, depends_extension);
- f_dependencies_file = NewFile(filename, "w", SWIG_output_files());
- if (!f_dependencies_file) {
- FileErrorDisplay(filename);
- Exit(EXIT_FAILURE);
- }
- } else
- f_dependencies_file = stdout;
- if (dependencies_target) {
- Printf(f_dependencies_file, "%s: ", Swig_filename_escape_space(dependencies_target));
- } else {
- Printf(f_dependencies_file, "%s: ", Swig_filename_escape_space(outfile));
- }
- List *files = Preprocessor_depend();
- List *phony_targets = NewList();
- for (int i = 0; i < Len(files); i++) {
- int use_file = 1;
- if (depend == 2) {
- if ((Strncmp(Getitem(files, i), SwigLib, Len(SwigLib)) == 0) || (SwigLibWinUnix && (Strncmp(Getitem(files, i), SwigLibWinUnix, Len(SwigLibWinUnix)) == 0)))
- use_file = 0;
- }
- if (use_file) {
- Printf(f_dependencies_file, "\\\n %s ", Swig_filename_escape_space(Getitem(files, i)));
- if (depend_phony)
- Append(phony_targets, Getitem(files, i));
- }
- }
- Printf(f_dependencies_file, "\n");
- if (depend_phony) {
- for (int i = 0; i < Len(phony_targets); i++) {
- Printf(f_dependencies_file, "\n%s:\n", Swig_filename_escape_space(Getitem(phony_targets, i)));
- }
- }
-
- if (f_dependencies_file != stdout)
- Delete(f_dependencies_file);
- if (depend_only)
- Exit(EXIT_SUCCESS);
- Delete(inputfile_filename);
- Delete(basename);
- Delete(phony_targets);
- } else {
- Printf(stderr, "Cannot generate dependencies with -nopreprocess\n");
- // Actually we could but it would be inefficient when just generating dependencies, as it would be done after Swig_cparse
- Exit(EXIT_FAILURE);
- }
- }
- Seek(cpps, 0, SEEK_SET);
- }
-
- /* Register a null file with the file handler */
- Swig_register_filebyname("null", NewString(""));
-
- // Pass control over to the specific language interpreter
- if (Verbose) {
- fprintf(stdout, "Starting language-specific parse...\n");
- fflush(stdout);
- }
-
- Node *top = Swig_cparse(cpps);
-
- if (dump_top & STAGE1) {
- Printf(stdout, "debug-top stage 1\n");
- Swig_print_tree(top);
- }
- if (dump_module & STAGE1) {
- Printf(stdout, "debug-module stage 1\n");
- Swig_print_tree(Getattr(top, "module"));
- }
- if (!CPlusPlus) {
- if (Verbose)
- Printf(stdout, "Processing unnamed structs...\n");
- Swig_nested_name_unnamed_c_structs(top);
- }
- Swig_extend_unused_check();
-
- if (Verbose) {
- Printf(stdout, "Processing types...\n");
- }
- Swig_process_types(top);
-
- if (dump_top & STAGE2) {
- Printf(stdout, "debug-top stage 2\n");
- Swig_print_tree(top);
- }
- if (dump_module & STAGE2) {
- Printf(stdout, "debug-module stage 2\n");
- Swig_print_tree(Getattr(top, "module"));
- }
-
- if (Verbose) {
- Printf(stdout, "C++ analysis...\n");
- }
- Swig_default_allocators(top);
-
- if (CPlusPlus) {
- if (Verbose)
- Printf(stdout, "Processing nested classes...\n");
- Swig_nested_process_classes(top);
- }
-
- if (dump_top & STAGE3) {
- Printf(stdout, "debug-top stage 3\n");
- Swig_print_tree(top);
- }
- if (top && (dump_module & STAGE3)) {
- Printf(stdout, "debug-module stage 3\n");
- Swig_print_tree(Getattr(top, "module"));
- }
-
- if (Verbose) {
- Printf(stdout, "Generating wrappers...\n");
- }
-
- if (top && dump_classes) {
- Hash *classes = Getattr(top, "classes");
- if (classes) {
- Printf(stdout, "Classes\n");
- Printf(stdout, "------------\n");
- Iterator ki;
- for (ki = First(classes); ki.key; ki = Next(ki)) {
- Printf(stdout, "%s\n", ki.key);
- }
- }
- }
-
- if (dump_typedef) {
- SwigType_print_scope();
- }
-
- if (dump_symtabs) {
- Swig_symbol_print_tables(Swig_symbol_global_scope());
- Swig_symbol_print_tables_summary();
- }
-
- if (dump_symbols) {
- Swig_symbol_print_symbols();
- }
-
- if (dump_csymbols) {
- Swig_symbol_print_csymbols();
- }
-
- if (dump_tags) {
- Swig_print_tags(top, 0);
- }
- if (top) {
- if (!Getattr(top, "name")) {
- Printf(stderr, "No module name specified using %%module or -module.\n");
- Exit(EXIT_FAILURE);
- } else {
- /* Set some filename information on the object */
- String *infile = scanner_get_main_input_file();
- if (!infile) {
- Printf(stderr, "Missing input file in preprocessed output.\n");
- Exit(EXIT_FAILURE);
- }
- Setattr(top, "infile", infile); // Note: if nopreprocess then infile is the original input file, otherwise input_file
- Setattr(top, "inputfile", input_file);
-
- String *infile_filename = outcurrentdir ? Swig_file_filename(infile): Copy(infile);
- String *basename = Swig_file_basename(infile_filename);
- if (!outfile_name) {
- if (CPlusPlus || lang->cplus_runtime_mode()) {
- Setattr(top, "outfile", NewStringf("%s_wrap.%s", basename, cpp_extension));
- } else {
- Setattr(top, "outfile", NewStringf("%s_wrap.c", basename));
- }
- } else {
- Setattr(top, "outfile", outfile_name);
- }
- if (!outfile_name_h) {
- Setattr(top, "outfile_h", NewStringf("%s_wrap.%s", basename, hpp_extension));
- } else {
- Setattr(top, "outfile_h", outfile_name_h);
- }
- configure_outdir(Getattr(top, "outfile"));
- if (Swig_contract_mode_get()) {
- Swig_contracts(top);
- }
-
- // Check the extension for a c/c++ file. If so, we're going to declare everything we see as "extern"
- ForceExtern = check_extension(input_file);
-
- if (tlm->status == Experimental) {
- Swig_warning(WARN_LANG_EXPERIMENTAL, "SWIG", 1, "Experimental target language. "
- "Target language %s specified by %s is an experimental language. "
- "Please read about SWIG experimental languages, https://swig.org/Doc4.0/Introduction.html#Introduction_experimental_status.\n",
- tlm->help ? tlm->help : "", tlm->name);
- }
-
- lang->top(top);
-
- Delete(infile_filename);
- Delete(basename);
- }
- }
- if (dump_lang_symbols) {
- lang->dumpSymbols();
- }
- if (dump_top & STAGE4) {
- Printf(stdout, "debug-top stage 4\n");
- Swig_print_tree(top);
- }
- if (dump_module & STAGE4) {
- Printf(stdout, "debug-module stage 4\n");
- Swig_print_tree(Getattr(top, "module"));
- }
- if (dump_xml && top) {
- delete lang;
- lang = 0;
- Swig_print_xml(top, xmlout);
- }
- Delete(top);
- }
- if (tm_debug)
- Swig_typemap_debug();
- if (memory_debug)
- DohMemoryDebug();
-
- char *outfiles = getenv("CCACHE_OUTFILES");
- if (outfiles) {
- File *f_outfiles = NewFile(outfiles, "w", 0);
- if (!f_outfiles) {
- Printf(stderr, "Failed to write list of output files to the filename '%s' specified in CCACHE_OUTFILES environment variable - ", outfiles);
- FileErrorDisplay(outfiles);
- Exit(EXIT_FAILURE);
- } else {
- int i;
- for (i = 0; i < Len(all_output_files); i++)
- Printf(f_outfiles, "%s\n", Getitem(all_output_files, i));
- Delete(f_outfiles);
- }
- }
-
- // Deletes
- Delete(libfiles);
- Preprocessor_delete();
-
- while (freeze) {
- }
-
- delete lang;
-
- int error_count = werror ? Swig_warn_count() : 0;
- error_count += Swig_error_count();
-
- if (error_count != 0)
- Exit(EXIT_FAILURE);
-
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * SWIG_exit_handler()
- *
- * Cleanup and either freeze or exit
- * ----------------------------------------------------------------------------- */
-
-static void SWIG_exit_handler(int status) {
- while (freeze) {
- }
-
- if (status > 0) {
- CloseAllOpenFiles();
-
- /* Remove all generated files */
- if (all_output_files) {
- for (int i = 0; i < Len(all_output_files); i++) {
- String *filename = Getitem(all_output_files, i);
- int removed = remove(Char(filename));
- if (removed == -1)
- fprintf(stderr, "On exit, could not delete file %s: %s\n", Char(filename), strerror(errno));
- }
- }
- }
-}
diff --git a/contrib/tools/swig/Source/Modules/mzscheme.cxx b/contrib/tools/swig/Source/Modules/mzscheme.cxx
deleted file mode 100644
index e22f8bb7ad..0000000000
--- a/contrib/tools/swig/Source/Modules/mzscheme.cxx
+++ /dev/null
@@ -1,802 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * mzscheme.cxx
- *
- * Mzscheme language module for SWIG.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include <ctype.h>
-
-static const char *usage = "\
-Mzscheme Options (available with -mzscheme)\n\
- -declaremodule - Create extension that declares a module\n\
- -dynamic-load <lib>,[lib,...] - Do not link with these libraries, dynamic load them\n\
- -noinit - Do not emit module initialization code\n\
- -prefix <name> - Set a prefix <name> to be prepended to all names\n\
-";
-
-static String *fieldnames_tab = 0;
-static String *convert_tab = 0;
-static String *convert_proto_tab = 0;
-static String *struct_name = 0;
-static String *mangled_struct_name = 0;
-
-static String *prefix = 0;
-static bool declaremodule = false;
-static bool noinit = false;
-static String *load_libraries = NULL;
-static String *module = 0;
-static const char *mzscheme_path = "mzscheme";
-static String *init_func_def = 0;
-
-static File *f_begin = 0;
-static File *f_runtime = 0;
-static File *f_header = 0;
-static File *f_wrappers = 0;
-static File *f_init = 0;
-
-// Used for garbage collection
-static int exporting_destructor = 0;
-static String *swigtype_ptr = 0;
-static String *cls_swigtype = 0;
-
-class MZSCHEME:public Language {
-public:
-
- /* ------------------------------------------------------------
- * main()
- * ------------------------------------------------------------ */
-
- virtual void main(int argc, char *argv[]) {
-
- int i;
-
- SWIG_library_directory(mzscheme_path);
-
- // Look for certain command line options
- for (i = 1; i < argc; i++) {
- if (argv[i]) {
- if (strcmp(argv[i], "-help") == 0) {
- fputs(usage, stdout);
- Exit(EXIT_SUCCESS);
- } else if (strcmp(argv[i], "-prefix") == 0) {
- if (argv[i + 1]) {
- prefix = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-declaremodule") == 0) {
- declaremodule = true;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-noinit") == 0) {
- noinit = true;
- Swig_mark_arg(i);
- }
- else if (strcmp(argv[i], "-dynamic-load") == 0) {
- if (argv[i + 1]) {
- Delete(load_libraries);
- load_libraries = NewString(argv[i + 1]);
- Swig_mark_arg(i++);
- Swig_mark_arg(i);
- } else {
- Swig_arg_error();
- }
- }
- }
- }
-
- // If a prefix has been specified make sure it ends in a '_' (not actually used!)
- if (prefix) {
- const char *px = Char(prefix);
- if (px[Len(prefix) - 1] != '_')
- Printf(prefix, "_");
- } else
- prefix = NewString("swig_");
-
- // Add a symbol for this module
-
- Preprocessor_define("SWIGMZSCHEME 1", 0);
-
- // Set name of typemaps
-
- SWIG_typemap_lang("mzscheme");
-
- // Read in default typemaps */
- SWIG_config_file("mzscheme.swg");
- allow_overloading();
-
- }
-
- /* ------------------------------------------------------------
- * top()
- * ------------------------------------------------------------ */
-
- virtual int top(Node *n) {
-
- /* Initialize all of the output files */
- String *outfile = Getattr(n, "outfile");
-
- f_begin = NewFile(outfile, "w", SWIG_output_files());
- if (!f_begin) {
- FileErrorDisplay(outfile);
- Exit(EXIT_FAILURE);
- }
- f_runtime = NewString("");
- f_init = NewString("");
- f_header = NewString("");
- f_wrappers = NewString("");
-
- /* Register file targets with the SWIG file handler */
- Swig_register_filebyname("header", f_header);
- Swig_register_filebyname("wrapper", f_wrappers);
- Swig_register_filebyname("begin", f_begin);
- Swig_register_filebyname("runtime", f_runtime);
-
- init_func_def = NewString("");
- Swig_register_filebyname("init", init_func_def);
-
- Swig_banner(f_begin);
-
- Swig_obligatory_macros(f_runtime, "MZSCHEME");
-
- module = Getattr(n, "name");
-
- Language::top(n);
-
- SwigType_emit_type_table(f_runtime, f_wrappers);
- if (!noinit) {
- if (declaremodule) {
- Printf(f_init, "#define SWIG_MZSCHEME_CREATE_MENV(env) scheme_primitive_module(scheme_intern_symbol(\"%s\"), env)\n", module);
- } else {
- Printf(f_init, "#define SWIG_MZSCHEME_CREATE_MENV(env) (env)\n");
- }
- Printf(f_init, "%s\n", Char(init_func_def));
- if (declaremodule) {
- Printf(f_init, "\tscheme_finish_primitive_module(menv);\n");
- }
- Printf(f_init, "\treturn scheme_void;\n}\n");
- Printf(f_init, "Scheme_Object *scheme_initialize(Scheme_Env *env) {\n");
-
- if (load_libraries) {
- Printf(f_init, "mz_set_dlopen_libraries(\"%s\");\n", load_libraries);
- }
-
- Printf(f_init, "\treturn scheme_reload(env);\n");
- Printf(f_init, "}\n");
-
- Printf(f_init, "Scheme_Object *scheme_module_name(void) {\n");
- if (declaremodule) {
- Printf(f_init, " return scheme_intern_symbol((char*)\"%s\");\n", module);
- } else {
- Printf(f_init, " return scheme_make_symbol((char*)\"%s\");\n", module);
- }
- Printf(f_init, "}\n");
- }
-
- /* Close all of the files */
- Dump(f_runtime, f_begin);
- Dump(f_header, f_begin);
- Dump(f_wrappers, f_begin);
- Wrapper_pretty_print(f_init, f_begin);
- Delete(f_header);
- Delete(f_wrappers);
- Delete(f_init);
- Delete(f_runtime);
- Delete(f_begin);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * functionWrapper()
- * Create a function declaration and register it with the interpreter.
- * ------------------------------------------------------------ */
-
- void throw_unhandled_mzscheme_type_error(SwigType *d) {
- Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, "Unable to handle type %s.\n", SwigType_str(d, 0));
- }
-
- /* Return true iff T is a pointer type */
-
- int
- is_a_pointer(SwigType *t) {
- return SwigType_ispointer(SwigType_typedef_resolve_all(t));
- }
-
- virtual int functionWrapper(Node *n) {
- char *iname = GetChar(n, "sym:name");
- SwigType *d = Getattr(n, "type");
- ParmList *l = Getattr(n, "parms");
- Parm *p;
-
- Wrapper *f = NewWrapper();
- String *proc_name = NewString("");
- String *target = NewString("");
- String *arg = NewString("");
- String *cleanup = NewString("");
- String *outarg = NewString("");
- String *build = NewString("");
- String *tm;
- int i = 0;
- int numargs;
- int numreq;
- String *overname = 0;
-
- if (load_libraries) {
- ParmList *parms = Getattr(n, "parms");
- SwigType *type = Getattr(n, "type");
- String *name = NewString("caller");
- Setattr(n, "wrap:action", Swig_cresult(type, Swig_cresult_name(), Swig_cfunction_call(name, parms)));
- }
-
- // Make a wrapper name for this
- String *wname = Swig_name_wrapper(iname);
- if (Getattr(n, "sym:overloaded")) {
- overname = Getattr(n, "sym:overname");
- } else {
- if (!addSymbol(iname, n)) {
- DelWrapper(f);
- return SWIG_ERROR;
- }
- }
- if (overname) {
- Append(wname, overname);
- }
- Setattr(n, "wrap:name", wname);
-
- // Build the name for Scheme.
- Printv(proc_name, iname, NIL);
- Replaceall(proc_name, "_", "-");
-
- // writing the function wrapper function
- Printv(f->def, "static Scheme_Object *", wname, " (", NIL);
- Printv(f->def, "int argc, Scheme_Object **argv", NIL);
- Printv(f->def, ")\n{", NIL);
-
- /* Define the scheme name in C. This define is used by several
- macros. */
- Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
-
- // Emit all of the local variables for holding arguments.
- emit_parameter_variables(l, f);
-
- /* Attach the standard typemaps */
- emit_attach_parmmaps(l, f);
- Setattr(n, "wrap:parms", l);
-
- numargs = emit_num_arguments(l);
- numreq = emit_num_required(l);
-
- /* Add the holder for the pointer to the function to be opened */
- if (load_libraries) {
- Wrapper_add_local(f, "_function_loaded", "static int _function_loaded=(1==0)");
- Wrapper_add_local(f, "_the_function", "static void *_the_function=NULL");
- {
- String *parms = ParmList_protostr(l);
- String *func = NewStringf("(*caller)(%s)", parms);
- Wrapper_add_local(f, "caller", SwigType_lstr(d, func)); /*"(*caller)()")); */
- }
- }
-
- // adds local variables
- Wrapper_add_local(f, "lenv", "int lenv = 1");
- Wrapper_add_local(f, "values", "Scheme_Object *values[MAXVALUES]");
-
- if (load_libraries) {
- Printf(f->code, "if (!_function_loaded) { _the_function=mz_load_function(\"%s\");_function_loaded=(1==1); }\n", iname);
- Printf(f->code, "if (!_the_function) { scheme_signal_error(\"Cannot load C function '%s'\"); }\n", iname);
- Printf(f->code, "caller=_the_function;\n");
- }
-
- // Now write code to extract the parameters (this is super ugly)
-
- for (i = 0, p = l; i < numargs; i++) {
- /* Skip ignored arguments */
-
- while (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- }
-
- SwigType *pt = Getattr(p, "type");
- String *ln = Getattr(p, "lname");
-
- // Produce names of source and target
- Clear(target);
- Clear(arg);
- String *source = NewStringf("argv[%d]", i);
- Printf(target, "%s", ln);
- Printv(arg, Getattr(p, "name"), NIL);
-
- if (i >= numreq) {
- Printf(f->code, "if (argc > %d) {\n", i);
- }
- // Handle parameter types.
- if ((tm = Getattr(p, "tmap:in"))) {
- Replaceall(tm, "$input", source);
- Setattr(p, "emit:input", source);
- Printv(f->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:in:next");
- } else {
- // no typemap found
- // check if typedef and resolve
- throw_unhandled_mzscheme_type_error(pt);
- p = nextSibling(p);
- }
- if (i >= numreq) {
- Printf(f->code, "}\n");
- }
- Delete(source);
- }
-
- /* Insert constraint checking code */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:check"))) {
- Printv(f->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:check:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- // Pass output arguments back to the caller.
-
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:argout"))) {
- Replaceall(tm, "$arg", Getattr(p, "emit:input"));
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(outarg, tm, "\n", NIL);
- p = Getattr(p, "tmap:argout:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- // Free up any memory allocated for the arguments.
-
- /* Insert cleanup code */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:freearg"))) {
- Printv(cleanup, tm, "\n", NIL);
- p = Getattr(p, "tmap:freearg:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- // Now write code to make the function call
-
- String *actioncode = emit_action(n);
-
- // Now have return value, figure out what to do with it.
- if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
- Replaceall(tm, "$result", "values[0]");
- if (GetFlag(n, "feature:new"))
- Replaceall(tm, "$owner", "1");
- else
- Replaceall(tm, "$owner", "0");
- Printv(f->code, tm, "\n", NIL);
- } else {
- throw_unhandled_mzscheme_type_error(d);
- }
- emit_return_variable(n, d, f);
-
- // Dump the argument output code
- Printv(f->code, Char(outarg), NIL);
-
- // Dump the argument cleanup code
- Printv(f->code, Char(cleanup), NIL);
-
- // Look for any remaining cleanup
-
- if (GetFlag(n, "feature:new")) {
- if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
- Printv(f->code, tm, "\n", NIL);
- }
- }
- // Free any memory allocated by the function being wrapped..
-
- if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
- Printv(f->code, tm, "\n", NIL);
- }
- // Wrap things up (in a manner of speaking)
-
- Printv(f->code, tab4, "return SWIG_MzScheme_PackageValues(lenv, values);\n", NIL);
- Printf(f->code, "#undef FUNC_NAME\n");
- Printv(f->code, "}\n", NIL);
-
- /* Substitute the function name */
- Replaceall(f->code, "$symname", iname);
-
- Wrapper_print(f, f_wrappers);
-
- if (!Getattr(n, "sym:overloaded")) {
-
- // Now register the function
- char temp[256];
- sprintf(temp, "%d", numargs);
- if (exporting_destructor) {
- Printf(init_func_def, "SWIG_TypeClientData(SWIGTYPE%s, (void *) %s);\n", swigtype_ptr, wname);
- }
- Printf(init_func_def, "scheme_add_global(\"%s\", scheme_make_prim_w_arity(%s,\"%s\",%d,%d),menv);\n", proc_name, wname, proc_name, numreq, numargs);
- } else {
- if (!Getattr(n, "sym:nextSibling")) {
- /* Emit overloading dispatch function */
-
- int maxargs;
- String *dispatch = Swig_overload_dispatch(n, "return %s(argc,argv);", &maxargs);
-
- /* Generate a dispatch wrapper for all overloaded functions */
-
- Wrapper *df = NewWrapper();
- String *dname = Swig_name_wrapper(iname);
-
- Printv(df->def, "static Scheme_Object *\n", dname, "(int argc, Scheme_Object **argv) {", NIL);
- Printv(df->code, dispatch, "\n", NIL);
- Printf(df->code, "scheme_signal_error(\"No matching function for overloaded '%s'\");\n", iname);
- Printf(df->code, "return NULL;\n");
- Printv(df->code, "}\n", NIL);
- Wrapper_print(df, f_wrappers);
- Printf(init_func_def, "scheme_add_global(\"%s\", scheme_make_prim_w_arity(%s,\"%s\",%d,%d),menv);\n", proc_name, dname, proc_name, 0, maxargs);
- DelWrapper(df);
- Delete(dispatch);
- Delete(dname);
- }
- }
-
- Delete(proc_name);
- Delete(target);
- Delete(arg);
- Delete(outarg);
- Delete(cleanup);
- Delete(build);
- DelWrapper(f);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * variableWrapper()
- *
- * Create a link to a C variable.
- * This creates a single function _wrap_swig_var_varname().
- * This function takes a single optional argument. If supplied, it means
- * we are setting this variable to some value. If omitted, it means we are
- * simply evaluating this variable. Either way, we return the variables
- * value.
- * ------------------------------------------------------------ */
-
- virtual int variableWrapper(Node *n) {
-
- char *name = GetChar(n, "name");
- char *iname = GetChar(n, "sym:name");
- SwigType *t = Getattr(n, "type");
-
- String *proc_name = NewString("");
- String *tm;
- String *tm2 = NewString("");
- String *argnum = NewString("0");
- String *arg = NewString("argv[0]");
- Wrapper *f;
-
- if (!addSymbol(iname, n))
- return SWIG_ERROR;
-
- f = NewWrapper();
-
- // evaluation function names
- String *var_name = Swig_name_wrapper(iname);
-
- // Build the name for scheme.
- Printv(proc_name, iname, NIL);
- Replaceall(proc_name, "_", "-");
- Setattr(n, "wrap:name", proc_name);
-
- if ((SwigType_type(t) != T_USER) || (is_a_pointer(t))) {
-
- Printf(f->def, "static Scheme_Object *%s(int argc, Scheme_Object** argv) {\n", var_name);
- Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
-
- Wrapper_add_local(f, "swig_result", "Scheme_Object *swig_result");
-
- if (!GetFlag(n, "feature:immutable")) {
- /* Check for a setting of the variable value */
- Printf(f->code, "if (argc) {\n");
- if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
- Replaceall(tm, "$input", "argv[0]");
- Replaceall(tm, "$argnum", "1");
- emit_action_code(n, f->code, tm);
- } else {
- throw_unhandled_mzscheme_type_error(t);
- }
- Printf(f->code, "}\n");
- }
- // Now return the value of the variable (regardless
- // of evaluating or setting)
-
- if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
- Replaceall(tm, "$result", "swig_result");
- /* Printf (f->code, "%s\n", tm); */
- emit_action_code(n, f->code, tm);
- } else {
- throw_unhandled_mzscheme_type_error(t);
- }
- Printf(f->code, "\nreturn swig_result;\n");
- Printf(f->code, "#undef FUNC_NAME\n");
- Printf(f->code, "}\n");
-
- Wrapper_print(f, f_wrappers);
-
- // Now add symbol to the MzScheme interpreter
-
- Printv(init_func_def,
- "scheme_add_global(\"", proc_name, "\", scheme_make_prim_w_arity(", var_name, ", \"", proc_name, "\", ", "0", ", ", "1", "), menv);\n", NIL);
-
- } else {
- Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number, "Unsupported variable type %s (ignored).\n", SwigType_str(t, 0));
- }
- Delete(var_name);
- Delete(proc_name);
- Delete(argnum);
- Delete(arg);
- Delete(tm2);
- DelWrapper(f);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * constantWrapper()
- * ------------------------------------------------------------ */
-
- virtual int constantWrapper(Node *n) {
- char *name = GetChar(n, "name");
- char *iname = GetChar(n, "sym:name");
- SwigType *type = Getattr(n, "type");
- String *value = Getattr(n, "value");
-
- String *var_name = NewString("");
- String *proc_name = NewString("");
- String *rvalue = NewString("");
- String *temp = NewString("");
- String *tm;
-
- // Make a static variable;
-
- Printf(var_name, "_wrap_const_%s", Swig_name_mangle(Getattr(n, "sym:name")));
-
- // Build the name for scheme.
- Printv(proc_name, iname, NIL);
- Replaceall(proc_name, "_", "-");
-
- if ((SwigType_type(type) == T_USER) && (!is_a_pointer(type))) {
- Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n");
- return SWIG_NOWRAP;
- }
- // See if there's a typemap
-
- Printv(rvalue, value, NIL);
- if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 1)) {
- temp = Copy(rvalue);
- Clear(rvalue);
- Printv(rvalue, "\"", temp, "\"", NIL);
- }
- if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 0)) {
- Delete(temp);
- temp = Copy(rvalue);
- Clear(rvalue);
- Printv(rvalue, "'", temp, "'", NIL);
- }
- if ((tm = Swig_typemap_lookup("constant", n, name, 0))) {
- Replaceall(tm, "$value", rvalue);
- Printf(f_init, "%s\n", tm);
- } else {
- // Create variable and assign it a value
-
- Printf(f_header, "static %s = ", SwigType_lstr(type, var_name));
- bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0);
- if ((SwigType_type(type) == T_STRING)) {
- Printf(f_header, "\"%s\";\n", value);
- } else if (SwigType_type(type) == T_CHAR && !is_enum_item) {
- Printf(f_header, "\'%s\';\n", value);
- } else {
- Printf(f_header, "%s;\n", value);
- }
-
- // Now create a variable declaration
-
- {
- /* Hack alert: will cleanup later -- Dave */
- Node *nn = NewHash();
- Setfile(nn, Getfile(n));
- Setline(nn, Getline(n));
- Setattr(nn, "name", var_name);
- Setattr(nn, "sym:name", iname);
- Setattr(nn, "type", type);
- SetFlag(nn, "feature:immutable");
- variableWrapper(nn);
- Delete(nn);
- }
- }
- Delete(proc_name);
- Delete(rvalue);
- Delete(temp);
- return SWIG_OK;
- }
-
- virtual int destructorHandler(Node *n) {
- exporting_destructor = true;
- Language::destructorHandler(n);
- exporting_destructor = false;
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * classHandler()
- * ------------------------------------------------------------ */
- virtual int classHandler(Node *n) {
- String *mangled_classname = 0;
- String *real_classname = 0;
- String *scm_structname = NewString("");
- SwigType *ctype_ptr = NewStringf("p.%s", getClassType());
-
- SwigType *t = NewStringf("p.%s", Getattr(n, "name"));
- swigtype_ptr = SwigType_manglestr(t);
- Delete(t);
-
- cls_swigtype = SwigType_manglestr(Getattr(n, "name"));
-
-
- fieldnames_tab = NewString("");
- convert_tab = NewString("");
- convert_proto_tab = NewString("");
-
- struct_name = Getattr(n, "sym:name");
- mangled_struct_name = Swig_name_mangle(Getattr(n, "sym:name"));
-
- Printv(scm_structname, struct_name, NIL);
- Replaceall(scm_structname, "_", "-");
-
- real_classname = Getattr(n, "name");
- mangled_classname = Swig_name_mangle(real_classname);
-
- Printv(fieldnames_tab, "static const char *_swig_struct_", cls_swigtype, "_field_names[] = { \n", NIL);
-
- Printv(convert_proto_tab, "static Scheme_Object *_swig_convert_struct_", cls_swigtype, "(", SwigType_str(ctype_ptr, "ptr"), ");\n", NIL);
-
- Printv(convert_tab, "static Scheme_Object *_swig_convert_struct_", cls_swigtype, "(", SwigType_str(ctype_ptr, "ptr"), ")\n {\n", NIL);
-
- Printv(convert_tab,
- tab4, "Scheme_Object *obj;\n", tab4, "Scheme_Object *fields[_swig_struct_", cls_swigtype, "_field_names_cnt];\n", tab4, "int i = 0;\n\n", NIL);
-
- /* Generate normal wrappers */
- Language::classHandler(n);
-
- Printv(convert_tab, tab4, "obj = scheme_make_struct_instance(", "_swig_struct_type_", cls_swigtype, ", i, fields);\n", NIL);
- Printv(convert_tab, tab4, "return obj;\n}\n\n", NIL);
-
- Printv(fieldnames_tab, "};\n", NIL);
-
- Printv(f_header, "static Scheme_Object *_swig_struct_type_", cls_swigtype, ";\n", NIL);
-
- Printv(f_header, fieldnames_tab, NIL);
- Printv(f_header, "#define _swig_struct_", cls_swigtype, "_field_names_cnt (sizeof(_swig_struct_", cls_swigtype, "_field_names)/sizeof(char*))\n", NIL);
-
- Printv(f_header, convert_proto_tab, NIL);
- Printv(f_wrappers, convert_tab, NIL);
-
- Printv(init_func_def, "_swig_struct_type_", cls_swigtype,
- " = SWIG_MzScheme_new_scheme_struct(menv, \"", scm_structname, "\", ",
- "_swig_struct_", cls_swigtype, "_field_names_cnt,", "(char**) _swig_struct_", cls_swigtype, "_field_names);\n", NIL);
-
- Delete(mangled_classname);
- Delete(swigtype_ptr);
- swigtype_ptr = 0;
- Delete(fieldnames_tab);
- Delete(convert_tab);
- Delete(ctype_ptr);
- Delete(convert_proto_tab);
- struct_name = 0;
- mangled_struct_name = 0;
- Delete(cls_swigtype);
- cls_swigtype = 0;
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * membervariableHandler()
- * ------------------------------------------------------------ */
-
- virtual int membervariableHandler(Node *n) {
- Language::membervariableHandler(n);
-
- if (!is_smart_pointer()) {
- String *symname = Getattr(n, "sym:name");
- String *name = Getattr(n, "name");
- SwigType *type = Getattr(n, "type");
- String *swigtype = SwigType_manglestr(Getattr(n, "type"));
- String *tm = 0;
- String *access_mem = NewString("");
- SwigType *ctype_ptr = NewStringf("p.%s", Getattr(n, "type"));
-
- Printv(fieldnames_tab, tab4, "\"", symname, "\",\n", NIL);
- Printv(access_mem, "(ptr)->", name, NIL);
- if ((SwigType_type(type) == T_USER) && (!is_a_pointer(type))) {
- Printv(convert_tab, tab4, "fields[i++] = ", NIL);
- Printv(convert_tab, "_swig_convert_struct_", swigtype, "((", SwigType_str(ctype_ptr, 0), ")&((ptr)->", name, "));\n", NIL);
- } else if ((tm = Swig_typemap_lookup("varout", n, access_mem, 0))) {
- Replaceall(tm, "$result", "fields[i++]");
- Printv(convert_tab, tm, "\n", NIL);
- } else
- Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number, "Unsupported member variable type %s (ignored).\n", SwigType_str(type, 0));
-
- Delete(access_mem);
- }
- return SWIG_OK;
- }
-
-
- /* ------------------------------------------------------------
- * validIdentifier()
- * ------------------------------------------------------------ */
-
- virtual int validIdentifier(String *s) {
- char *c = Char(s);
- /* Check whether we have an R5RS identifier. */
- /* <identifier> --> <initial> <subsequent>* | <peculiar identifier> */
- /* <initial> --> <letter> | <special initial> */
- if (!(isalpha(*c) || (*c == '!') || (*c == '$') || (*c == '%')
- || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
- || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
- || (*c == '^') || (*c == '_') || (*c == '~'))) {
- /* <peculiar identifier> --> + | - | ... */
- if ((strcmp(c, "+") == 0)
- || strcmp(c, "-") == 0 || strcmp(c, "...") == 0)
- return 1;
- else
- return 0;
- }
- /* <subsequent> --> <initial> | <digit> | <special subsequent> */
- while (*c) {
- if (!(isalnum(*c) || (*c == '!') || (*c == '$') || (*c == '%')
- || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
- || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
- || (*c == '^') || (*c == '_') || (*c == '~') || (*c == '+')
- || (*c == '-') || (*c == '.') || (*c == '@')))
- return 0;
- c++;
- }
- return 1;
- }
-
- String *runtimeCode() {
- String *s = Swig_include_sys("mzrun.swg");
- if (!s) {
- Printf(stderr, "*** Unable to open 'mzrun.swg'\n");
- s = NewString("");
- }
- return s;
- }
-
- String *defaultExternalRuntimeFilename() {
- return NewString("swigmzrun.h");
- }
-};
-
-/* -----------------------------------------------------------------------------
- * swig_mzscheme() - Instantiate module
- * ----------------------------------------------------------------------------- */
-
-static Language *new_swig_mzscheme() {
- return new MZSCHEME();
-}
-extern "C" Language *swig_mzscheme(void) {
- return new_swig_mzscheme();
-}
diff --git a/contrib/tools/swig/Source/Modules/nested.cxx b/contrib/tools/swig/Source/Modules/nested.cxx
deleted file mode 100644
index d027eebe5b..0000000000
--- a/contrib/tools/swig/Source/Modules/nested.cxx
+++ /dev/null
@@ -1,453 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * nested.cxx
- *
- * Nested structs support
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include "cparse.h"
-
-// Nested classes processing section
-static Hash *classhash = 0;
-
-static String *make_name(Node *n, String *name, SwigType *decl) {
- int destructor = name && (*(Char(name)) == '~');
- if (String *yyrename = Getattr(n, "class_rename")) {
- String *s = NewString(yyrename);
- Delattr(n, "class_rename");
- if (destructor && (*(Char(s)) != '~')) {
- Insert(s, 0, "~");
- }
- return s;
- }
-
- if (!name)
- return 0;
- return Swig_name_make(n, 0, name, decl, 0);
-}
-
-// C version of add_symbols()
-static void add_symbols_c(Node *n) {
- String *decl;
- String *wrn = 0;
- String *symname = 0;
- int iscdecl = Cmp(nodeType(n), "cdecl") == 0;
- Setattr(n, "ismember", "1");
- Setattr(n, "access", "public");
- if (Getattr(n, "sym:name"))
- return;
- decl = Getattr(n, "decl");
- if (!SwigType_isfunction(decl)) {
- String *name = Getattr(n, "name");
- String *makename = Getattr(n, "parser:makename");
- if (iscdecl) {
- String *storage = Getattr(n, "storage");
- if (Cmp(storage, "typedef") == 0) {
- Setattr(n, "kind", "typedef");
- } else {
- SwigType *type = Getattr(n, "type");
- String *value = Getattr(n, "value");
- Setattr(n, "kind", "variable");
- if (value && Len(value)) {
- Setattr(n, "hasvalue", "1");
- }
- if (type) {
- SwigType *ty;
- SwigType *tmp = 0;
- if (decl) {
- ty = tmp = Copy(type);
- SwigType_push(ty, decl);
- } else {
- ty = type;
- }
- if (!SwigType_ismutable(ty)) {
- SetFlag(n, "hasconsttype");
- SetFlag(n, "feature:immutable");
- }
- if (tmp)
- Delete(tmp);
- }
- if (!type) {
- Printf(stderr, "notype name %s\n", name);
- }
- }
- }
- Swig_features_get(Swig_cparse_features(), 0, name, 0, n);
- if (makename) {
- symname = make_name(n, makename, 0);
- Delattr(n, "parser:makename"); /* temporary information, don't leave it hanging around */
- } else {
- makename = name;
- symname = make_name(n, makename, 0);
- }
-
- if (!symname) {
- symname = Copy(Getattr(n, "unnamed"));
- }
- if (symname) {
- wrn = Swig_name_warning(n, 0, symname, 0);
- }
- } else {
- String *name = Getattr(n, "name");
- SwigType *fdecl = Copy(decl);
- SwigType *fun = SwigType_pop_function(fdecl);
- if (iscdecl) {
- Setattr(n, "kind", "function");
- }
-
- Swig_features_get(Swig_cparse_features(), 0, name, fun, n);
-
- symname = make_name(n, name, fun);
- wrn = Swig_name_warning(n, 0, symname, fun);
-
- Delete(fdecl);
- Delete(fun);
-
- }
- if (!symname)
- return;
- if (GetFlag(n, "feature:ignore")) {
- /* Only add to C symbol table and continue */
- Swig_symbol_add(0, n);
- } else if (strncmp(Char(symname), "$ignore", 7) == 0) {
- char *c = Char(symname) + 7;
- SetFlag(n, "feature:ignore");
- if (strlen(c)) {
- SWIG_WARN_NODE_BEGIN(n);
- Swig_warning(0, Getfile(n), Getline(n), "%s\n", c + 1);
- SWIG_WARN_NODE_END(n);
- }
- Swig_symbol_add(0, n);
- } else {
- Node *c;
- if ((wrn) && (Len(wrn))) {
- String *metaname = symname;
- if (!Getmeta(metaname, "already_warned")) {
- SWIG_WARN_NODE_BEGIN(n);
- Swig_warning(0, Getfile(n), Getline(n), "%s\n", wrn);
- SWIG_WARN_NODE_END(n);
- Setmeta(metaname, "already_warned", "1");
- }
- }
- c = Swig_symbol_add(symname, n);
-
- if (c != n) {
- /* symbol conflict attempting to add in the new symbol */
- if (Getattr(n, "sym:weak")) {
- Setattr(n, "sym:name", symname);
- } else {
- String *e = NewStringEmpty();
- String *en = NewStringEmpty();
- String *ec = NewStringEmpty();
- int redefined = Swig_need_redefined_warn(n, c, true);
- if (redefined) {
- Printf(en, "Identifier '%s' redefined (ignored)", symname);
- Printf(ec, "previous definition of '%s'", symname);
- } else {
- Printf(en, "Redundant redeclaration of '%s'", symname);
- Printf(ec, "previous declaration of '%s'", symname);
- }
- if (Cmp(symname, Getattr(n, "name"))) {
- Printf(en, " (Renamed from '%s')", SwigType_namestr(Getattr(n, "name")));
- }
- Printf(en, ",");
- if (Cmp(symname, Getattr(c, "name"))) {
- Printf(ec, " (Renamed from '%s')", SwigType_namestr(Getattr(c, "name")));
- }
- Printf(ec, ".");
- SWIG_WARN_NODE_BEGIN(n);
- if (redefined) {
- Swig_warning(WARN_PARSE_REDEFINED, Getfile(n), Getline(n), "%s\n", en);
- Swig_warning(WARN_PARSE_REDEFINED, Getfile(c), Getline(c), "%s\n", ec);
- } else {
- Swig_warning(WARN_PARSE_REDUNDANT, Getfile(n), Getline(n), "%s\n", en);
- Swig_warning(WARN_PARSE_REDUNDANT, Getfile(c), Getline(c), "%s\n", ec);
- }
- SWIG_WARN_NODE_END(n);
- Printf(e, "%s:%d:%s\n%s:%d:%s\n", Getfile(n), Getline(n), en, Getfile(c), Getline(c), ec);
- Setattr(n, "error", e);
- Delete(e);
- Delete(en);
- Delete(ec);
- }
- }
- }
- Delete(symname);
-}
-
-/* Strips C-style and C++-style comments from string in-place. */
-static void strip_comments(char *string) {
- int state = 0;
- /*
- * 0 - not in comment
- * 1 - in c-style comment
- * 2 - in c++-style comment
- * 3 - in string
- * 4 - after reading / not in comments
- * 5 - after reading * in c-style comments
- * 6 - after reading \ in strings
- */
- char *c = string;
- while (*c) {
- switch (state) {
- case 0:
- if (*c == '\"')
- state = 3;
- else if (*c == '/')
- state = 4;
- break;
- case 1:
- if (*c == '*')
- state = 5;
- *c = ' ';
- break;
- case 2:
- if (*c == '\n')
- state = 0;
- else
- *c = ' ';
- break;
- case 3:
- if (*c == '\"')
- state = 0;
- else if (*c == '\\')
- state = 6;
- break;
- case 4:
- if (*c == '/') {
- *(c - 1) = ' ';
- *c = ' ';
- state = 2;
- } else if (*c == '*') {
- *(c - 1) = ' ';
- *c = ' ';
- state = 1;
- } else
- state = 0;
- break;
- case 5:
- if (*c == '/')
- state = 0;
- else
- state = 1;
- *c = ' ';
- break;
- case 6:
- state = 3;
- break;
- }
- ++c;
- }
-}
-
-// Create a %insert with a typedef to make a new name visible to C
-static Node *create_insert(Node *n, bool noTypedef = false) {
- // format a typedef
- String *ccode = Getattr(n, "code");
- Push(ccode, " ");
- if (noTypedef) {
- Push(ccode, Getattr(n, "name"));
- Push(ccode, " ");
- Push(ccode, Getattr(n, "kind"));
- } else {
- Push(ccode, Getattr(n, "kind"));
- Push(ccode, "typedef ");
- Append(ccode, " ");
- Append(ccode, Getattr(n, "tdname"));
- }
- Append(ccode, ";");
-
- /* Strip comments - further code may break in presence of comments. */
- strip_comments(Char(ccode));
-
- /* Make all SWIG created typedef structs/unions/classes unnamed else
- redefinition errors occur - nasty hack alert. */
- if (!noTypedef) {
- const char *types_array[3] = { "struct", "union", "class" };
- for (int i = 0; i < 3; i++) {
- char *code_ptr = Char(ccode);
- while (code_ptr) {
- /* Replace struct name (as in 'struct name {...}' ) with whitespace
- name will be between struct and opening brace */
-
- code_ptr = strstr(code_ptr, types_array[i]);
- if (code_ptr) {
- char *open_bracket_pos;
- code_ptr += strlen(types_array[i]);
- open_bracket_pos = strchr(code_ptr, '{');
- if (open_bracket_pos) {
- /* Make sure we don't have something like struct A a; */
- char *semi_colon_pos = strchr(code_ptr, ';');
- if (!(semi_colon_pos && (semi_colon_pos < open_bracket_pos)))
- while (code_ptr < open_bracket_pos)
- *code_ptr++ = ' ';
- }
- }
- }
- }
- }
- {
- /* Remove SWIG directive %constant which may be left in the SWIG created typedefs */
- char *code_ptr = Char(ccode);
- while (code_ptr) {
- code_ptr = strstr(code_ptr, "%constant");
- if (code_ptr) {
- char *directive_end_pos = strchr(code_ptr, ';');
- if (directive_end_pos) {
- while (code_ptr <= directive_end_pos)
- *code_ptr++ = ' ';
- }
- }
- }
- }
- Node *newnode = NewHash();
- set_nodeType(newnode, "insert");
- Setfile(newnode, Getfile(n));
- Setline(newnode, Getline(n));
- String *code = NewStringEmpty();
- Wrapper_pretty_print(ccode, code);
- Setattr(newnode, "code", code);
- Delete(code);
- Delattr(n, "code");
- return newnode;
-}
-
-static void insertNodeAfter(Node *n, Node *c) {
- Node *g = parentNode(n);
- set_parentNode(c, g);
- Node *ns = nextSibling(n);
- if (Node *outer = Getattr(c, "nested:outer")) {
- while (ns && outer == Getattr(ns, "nested:outer")) {
- n = ns;
- ns = nextSibling(n);
- }
- }
- if (!ns) {
- set_lastChild(g, c);
- } else {
- set_nextSibling(c, ns);
- set_previousSibling(ns, c);
- }
- set_nextSibling(n, c);
- set_previousSibling(c, n);
-}
-
-void Swig_nested_name_unnamed_c_structs(Node *n) {
- if (!n)
- return;
- if (!classhash)
- classhash = Getattr(n, "classes");
- Node *c = firstChild(n);
- while (c) {
- Node *next = nextSibling(c);
- if (String *declName = Getattr(c, "nested:unnamed")) {
- if (Node *outer = Getattr(c, "nested:outer")) {
- // generate a name
- String *name = NewStringf("%s_%s", Getattr(outer, "name"), declName);
- Delattr(c, "nested:unnamed");
- // set the name to the class and symbol table
- Setattr(c, "tdname", name);
- Setattr(c, "name", name);
- Swig_symbol_setscope(Getattr(c, "symtab"));
- Swig_symbol_setscopename(name);
- // now that we have a name - gather base symbols
- if (List *publicBases = Getattr(c, "baselist")) {
- List *bases = Swig_make_inherit_list(name, publicBases, 0);
- Swig_inherit_base_symbols(bases);
- Delete(bases);
- }
- Setattr(classhash, name, c);
-
- // Merge the extension into the symbol table
- if (Node *am = Getattr(Swig_extend_hash(), name)) {
- Swig_extend_merge(c, am);
- Swig_extend_append_previous(c, am);
- Delattr(Swig_extend_hash(), name);
- }
- Swig_symbol_popscope();
-
- // process declarations following this type (assign correct new type)
- SwigType *ty = Copy(name);
- Node *decl = nextSibling(c);
- List *declList = NewList();
- while (decl && Getattr(decl, "nested:unnamedtype") == c) {
- Setattr(decl, "type", ty);
- Append(declList, decl);
- Delattr(decl, "nested:unnamedtype");
- SetFlag(decl, "feature:immutable");
- add_symbols_c(decl);
- decl = nextSibling(decl);
- }
- Delete(ty);
- Swig_symbol_setscope(Swig_symbol_global_scope());
- add_symbols_c(c);
-
- Node *ins = create_insert(c);
- insertNodeAfter(c, ins);
- removeNode(c);
- insertNodeAfter(n, c);
- Delete(ins);
- Delattr(c, "nested:outer");
- } else {
- // global unnamed struct - ignore it and its instances
- SetFlag(c, "feature:ignore");
- while (next && Getattr(next, "nested:unnamedtype") == c) {
- SetFlag(next, "feature:ignore");
- next = nextSibling(next);
- }
- c = next;
- continue;
- }
- } else if (cparse_cplusplusout) {
- if (Getattr(c, "nested:outer")) {
- Node *ins = create_insert(c, true);
- insertNodeAfter(c, ins);
- Delete(ins);
- Delattr(c, "nested:outer");
- }
- }
- // process children
- Swig_nested_name_unnamed_c_structs(c);
- c = next;
- }
-}
-
-static void remove_outer_class_reference(Node *n) {
- for (Node *c = firstChild(n); c; c = nextSibling(c)) {
- if (GetFlag(c, "feature:flatnested") || Language::instance()->nestedClassesSupport() == Language::NCS_None) {
- Delattr(c, "nested:outer");
- remove_outer_class_reference(c);
- }
- }
-}
-
-void Swig_nested_process_classes(Node *n) {
- if (!n)
- return;
- Node *c = firstChild(n);
- while (c) {
- Node *next = nextSibling(c);
- if (!Getattr(c, "templatetype")) {
- if (GetFlag(c, "nested") && (GetFlag(c, "feature:flatnested") || Language::instance()->nestedClassesSupport() == Language::NCS_None)) {
- removeNode(c);
- if (!checkAttribute(c, "access", "public"))
- SetFlag(c, "feature:ignore");
- else if (Strcmp(nodeType(n),"extend") == 0 && Strcmp(nodeType(parentNode(n)),"class") == 0)
- insertNodeAfter(parentNode(n), c);
- else
- insertNodeAfter(n, c);
- }
- Swig_nested_process_classes(c);
- }
- c = next;
- }
- remove_outer_class_reference(n);
-}
-
diff --git a/contrib/tools/swig/Source/Modules/ocaml.cxx b/contrib/tools/swig/Source/Modules/ocaml.cxx
deleted file mode 100644
index 963a0c2d10..0000000000
--- a/contrib/tools/swig/Source/Modules/ocaml.cxx
+++ /dev/null
@@ -1,1848 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * ocaml.cxx
- *
- * Ocaml language module for SWIG.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include <ctype.h>
-
-static const char *usage = "\
-Ocaml Options (available with -ocaml)\n\
- -oldvarnames - Old intermediary method names for variable wrappers\n\
- -prefix <name> - Set a prefix <name> to be prepended to all names\n\
- -suffix <name> - Deprecated alias for general option -cppext\n\
- -where - Emit library location\n\
-\n";
-
-static int classmode = 0;
-static int in_constructor = 0, in_destructor = 0, in_copyconst = 0;
-static int const_enum = 0;
-static int static_member_function = 0;
-static int generate_sizeof = 0;
-static String *prefix = 0;
-static const char *ocaml_path = "ocaml";
-static bool old_variable_names = false;
-static String *classname = 0;
-static String *module = 0;
-static String *init_func_def = 0;
-static String *f_classtemplate = 0;
-static SwigType *name_qualifier_type = 0;
-
-static Hash *seen_enums = 0;
-static Hash *seen_enumvalues = 0;
-static Hash *seen_constructors = 0;
-
-static File *f_header = 0;
-static File *f_begin = 0;
-static File *f_runtime = 0;
-static File *f_wrappers = 0;
-static File *f_directors = 0;
-static File *f_directors_h = 0;
-static File *f_init = 0;
-static File *f_mlout = 0;
-static File *f_mliout = 0;
-static File *f_mlbody = 0;
-static File *f_mlibody = 0;
-static File *f_mltail = 0;
-static File *f_mlitail = 0;
-static File *f_enumtypes_type = 0;
-static File *f_enumtypes_value = 0;
-static File *f_class_ctors = 0;
-static File *f_class_ctors_end = 0;
-static File *f_enum_to_int = 0;
-static File *f_int_to_enum = 0;
-
-class OCAML:public Language {
-public:
-
- OCAML() {
- director_prot_ctor_code = NewString("");
- Printv(director_prot_ctor_code,
- "if ( $comparison ) { /* subclassed */\n",
- " $director_new \n", "} else {\n", " caml_failwith(\"accessing abstract class or protected constructor\"); \n", "}\n", NIL);
- director_multiple_inheritance = 1;
- director_language = 1;
- }
-
- String *Swig_class_name(Node *n) {
- String *name;
- name = Copy(Getattr(n, "sym:name"));
- return name;
- }
-
- void PrintIncludeArg() {
- Printv(stdout, SWIG_LIB, SWIG_FILE_DELIMITER, ocaml_path, "\n", NIL);
- }
-
- /* ------------------------------------------------------------
- * main()
- * ------------------------------------------------------------ */
-
- virtual void main(int argc, char *argv[]) {
- int i;
-
- prefix = 0;
-
- SWIG_library_directory(ocaml_path);
-
- // Look for certain command line options
- for (i = 1; i < argc; i++) {
- if (argv[i]) {
- if (strcmp(argv[i], "-help") == 0) {
- fputs(usage, stdout);
- Exit(EXIT_SUCCESS);
- } else if (strcmp(argv[i], "-where") == 0) {
- PrintIncludeArg();
- Exit(EXIT_SUCCESS);
- } else if (strcmp(argv[i], "-prefix") == 0) {
- if (argv[i + 1]) {
- prefix = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-suffix") == 0) {
- if (argv[i + 1]) {
- Printf(stderr, "swig: warning: -suffix option deprecated. SWIG 3.0.4 and later provide a -cppext option which should be used instead.\n");
- SWIG_config_cppext(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else
- Swig_arg_error();
- } else if (strcmp(argv[i], "-oldvarnames") == 0) {
- Swig_mark_arg(i);
- old_variable_names = true;
- }
- }
- }
-
- // If a prefix has been specified make sure it ends in a '_' (not actually used!)
- if (prefix) {
- const char *px = Char(prefix);
- if (px[Len(prefix) - 1] != '_')
- Printf(prefix, "_");
- } else
- prefix = NewString("swig_");
-
- // Add a symbol for this module
-
- Preprocessor_define("SWIGOCAML 1", 0);
- // Set name of typemaps
-
- SWIG_typemap_lang("ocaml");
-
- // Read in default typemaps */
- SWIG_config_file("ocaml.i");
- allow_overloading();
-
- }
-
- /* Swig_director_declaration()
- *
- * Generate the full director class declaration, complete with base classes.
- * e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {"
- *
- */
-
- String *Swig_director_declaration(Node *n) {
- String *classname = Swig_class_name(n);
- String *directorname = NewStringf("SwigDirector_%s", classname);
- String *base = Getattr(n, "classtype");
- String *declaration = Swig_class_declaration(n, directorname);
- Printf(declaration, " : public %s, public Swig::Director {\n", base);
- Delete(classname);
- Delete(directorname);
- return declaration;
- }
-
- void emitBanner(File *f) {
- Printf(f, "(* ----------------------------------------------------------------------------\n");
- Swig_banner_target_lang(f, " *");
- Printf(f, " * ---------------------------------------------------------------------------- *)\n\n");
- }
-
- /* ------------------------------------------------------------
- * top()
- *
- * Recognize the %module, and capture the module name.
- * Create the default enum cases.
- * Set up the named outputs:
- *
- * init
- * ml
- * mli
- * wrapper
- * header
- * runtime
- * directors
- * directors_h
- * ------------------------------------------------------------ */
-
- virtual int top(Node *n) {
- /* Set comparison with none for ConstructorToFunction */
- setSubclassInstanceCheck(NewString("caml_list_nth(args,0) != Val_unit"));
-
- /* check if directors are enabled for this module. note: this
- * is a "master" switch, without which no director code will be
- * emitted. %feature("director") statements are also required
- * to enable directors for individual classes or methods.
- *
- * use %module(directors="1") modulename at the start of the
- * interface file to enable director generation.
- */
- String *mod_docstring = NULL;
- {
- Node *module = Getattr(n, "module");
- if (module) {
- Node *options = Getattr(module, "options");
- if (options) {
- if (Getattr(options, "directors")) {
- allow_directors();
- }
- if (Getattr(options, "dirprot")) {
- allow_dirprot();
- }
- if (Getattr(options, "sizeof")) {
- generate_sizeof = 1;
- }
- mod_docstring = Getattr(options, "docstring");
- }
- }
- }
-
- /* Initialize all of the output files */
- String *outfile = Getattr(n, "outfile");
-
- f_begin = NewFile(outfile, "w", SWIG_output_files());
- if (!f_begin) {
- FileErrorDisplay(outfile);
- Exit(EXIT_FAILURE);
- }
- f_runtime = NewString("");
- f_init = NewString("");
- f_header = NewString("");
- f_wrappers = NewString("");
- f_directors = NewString("");
- f_directors_h = NewString("");
- f_enumtypes_type = NewString("");
- f_enumtypes_value = NewString("");
- init_func_def = NewString("");
- f_mlbody = NewString("");
- f_mlibody = NewString("");
- f_mltail = NewString("");
- f_mlitail = NewString("");
- f_class_ctors = NewString("");
- f_class_ctors_end = NewString("");
- f_enum_to_int = NewString("");
- f_int_to_enum = NewString("");
- f_classtemplate = NewString("");
-
- module = Getattr(n, "name");
-
- seen_constructors = NewHash();
- seen_enums = NewHash();
- seen_enumvalues = NewHash();
-
- /* Register file targets with the SWIG file handler */
- Swig_register_filebyname("init", init_func_def);
- Swig_register_filebyname("header", f_header);
- Swig_register_filebyname("wrapper", f_wrappers);
- Swig_register_filebyname("begin", f_begin);
- Swig_register_filebyname("runtime", f_runtime);
- Swig_register_filebyname("mli", f_mlibody);
- Swig_register_filebyname("ml", f_mlbody);
- Swig_register_filebyname("mlitail", f_mlitail);
- Swig_register_filebyname("mltail", f_mltail);
- Swig_register_filebyname("director", f_directors);
- Swig_register_filebyname("director_h", f_directors_h);
- Swig_register_filebyname("classtemplate", f_classtemplate);
- Swig_register_filebyname("class_ctors", f_class_ctors);
-
- if (old_variable_names) {
- Swig_name_register("set", "%n%v__set__");
- Swig_name_register("get", "%n%v__get__");
- }
-
- Swig_banner(f_begin);
-
- Swig_obligatory_macros(f_runtime, "OCAML");
-
- Printf(f_runtime, "#define SWIG_MODULE \"%s\"\n", module);
- /* Module name */
- Printf(f_mlbody, "let module_name = \"%s\"\n", module);
- Printf(f_mlibody, "val module_name : string\n");
- Printf(f_enum_to_int,
- "let enum_to_int x (v : c_obj) =\n"
- " match v with\n"
- " C_enum _y ->\n"
- " (let y = _y in match (x : c_enum_type) with\n"
- " `unknown -> " " (match y with\n" " `Int x -> (Swig.C_int x)\n" " | _ -> raise (LabelNotFromThisEnum v))\n");
-
- Printf(f_int_to_enum, "let int_to_enum x y =\n" " match (x : c_enum_type) with\n" " `unknown -> C_enum (`Int y)\n");
-
- if (directorsEnabled()) {
- Printf(f_runtime, "#define SWIG_DIRECTORS\n");
- }
-
- Printf(f_runtime, "\n");
-
- /* Produce the enum_to_int and int_to_enum functions */
-
- Printf(f_enumtypes_type, "open Swig\n" "type c_enum_type = [ \n `unknown\n");
- Printf(f_enumtypes_value, "type c_enum_value = [ \n `Int of int\n");
- String *mlfile = NewString("");
- String *mlifile = NewString("");
-
- Printv(mlfile, module, ".ml", NIL);
- Printv(mlifile, module, ".mli", NIL);
-
- String *mlfilen = NewStringf("%s%s", SWIG_output_directory(), mlfile);
- if ((f_mlout = NewFile(mlfilen, "w", SWIG_output_files())) == 0) {
- FileErrorDisplay(mlfilen);
- Exit(EXIT_FAILURE);
- }
- String *mlifilen = NewStringf("%s%s", SWIG_output_directory(), mlifile);
- if ((f_mliout = NewFile(mlifilen, "w", SWIG_output_files())) == 0) {
- FileErrorDisplay(mlifilen);
- Exit(EXIT_FAILURE);
- }
- emitBanner(f_mlout);
- emitBanner(f_mliout);
-
- Language::top(n);
-
- if (mod_docstring) {
- if (Len(mod_docstring)) {
- Printv(f_mliout, "(** ", mod_docstring, " *)\n", NIL);
- }
- Delete(mod_docstring);
- mod_docstring = NULL;
- }
-
- Printf(f_enum_to_int, ") | _ -> (C_int (get_int v))\n" "let _ = Callback.register \"%s_enum_to_int\" enum_to_int\n", module);
- Printf(f_mlibody, "val enum_to_int : c_enum_type -> c_obj -> Swig.c_obj\n");
-
- Printf(f_int_to_enum, "let _ = Callback.register \"%s_int_to_enum\" int_to_enum\n", module);
- Printf(f_mlibody, "val int_to_enum : c_enum_type -> int -> c_obj\n");
- Printf(f_init, "#define SWIG_init f_%s_init\n" "%s" "}\n", module, init_func_def);
- Printf(f_mlbody, "external f_init : unit -> unit = \"f_%s_init\" ;;\n" "let _ = f_init ()\n", module);
- Printf(f_enumtypes_type, "]\n");
- Printf(f_enumtypes_value, "]\n\n" "type c_obj = c_enum_value c_obj_t\n");
-
- if (directorsEnabled()) {
- // Insert director runtime into the f_runtime file (make it occur before %header section)
- Swig_insert_file("director_common.swg", f_runtime);
- Swig_insert_file("director.swg", f_runtime);
- }
-
- SwigType_emit_type_table(f_runtime, f_wrappers);
- /* Close all of the files */
- Dump(f_runtime, f_begin);
- Dump(f_directors_h, f_header);
- Dump(f_header, f_begin);
- Dump(f_directors, f_wrappers);
- Dump(f_wrappers, f_begin);
- Wrapper_pretty_print(f_init, f_begin);
- Delete(f_header);
- Delete(f_wrappers);
- Delete(f_init);
- Delete(f_runtime);
- Delete(f_begin);
-
- Dump(f_enumtypes_type, f_mlout);
- Dump(f_enumtypes_value, f_mlout);
- Dump(f_mlbody, f_mlout);
- Dump(f_enum_to_int, f_mlout);
- Dump(f_int_to_enum, f_mlout);
- Delete(f_int_to_enum);
- Delete(f_enum_to_int);
- Dump(f_class_ctors, f_mlout);
- Dump(f_class_ctors_end, f_mlout);
- Dump(f_mltail, f_mlout);
- Delete(f_mlout);
-
- Dump(f_enumtypes_type, f_mliout);
- Dump(f_enumtypes_value, f_mliout);
- Dump(f_mlibody, f_mliout);
- Dump(f_mlitail, f_mliout);
- Delete(f_mliout);
-
- return SWIG_OK;
- }
-
- /* Produce an error for the given type */
- void throw_unhandled_ocaml_type_error(SwigType *d, const char *types) {
- Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, "Unable to handle type %s (%s).\n", SwigType_str(d, 0), types);
- }
-
- /* Return true iff T is a pointer type */
- int
- is_a_pointer(SwigType *t) {
- return SwigType_ispointer(SwigType_typedef_resolve_all(t));
- }
-
- /*
- * Delete one reference from a given type.
- */
-
- void oc_SwigType_del_reference(SwigType *t) {
- if (SwigType_isqualifier(t)) {
- SwigType_del_qualifier(t);
- }
- SwigType_del_reference(t);
- }
-
- void oc_SwigType_del_array(SwigType *t) {
- if (SwigType_isqualifier(t)) {
- SwigType_del_qualifier(t);
- }
- if (SwigType_isarray(t)) {
- SwigType_del_array(t);
- }
- }
-
- /*
- * Return true iff T is a reference type
- */
-
- int
- is_a_reference(SwigType *t) {
- return SwigType_isreference(SwigType_typedef_resolve_all(t));
- }
-
- int
- is_an_array(SwigType *t) {
- return SwigType_isarray(SwigType_typedef_resolve_all(t));
- }
-
- virtual int membervariableHandler(Node *n) {
- String *symname = Getattr(n, "sym:name");
- Language::membervariableHandler(n);
-
- String *mname = Swig_name_member(NSPACE_TODO, classname, symname);
- String *getname = Swig_name_get(NSPACE_TODO, mname);
- String *mangled_getname = mangleNameForCaml(getname);
- Delete(getname);
-
- if (!GetFlag(n, "feature:immutable")) {
- String *setname = Swig_name_set(NSPACE_TODO, mname);
- String *mangled_setname = mangleNameForCaml(setname);
- Delete(setname);
- Printf(f_class_ctors, " \"[%s]\", (fun args -> " "if args = (C_list [ raw_ptr ]) then _%s args else _%s args) ;\n", symname, mangled_getname, mangled_setname);
- Delete(mangled_setname);
- } else {
- Printf(f_class_ctors, " \"[%s]\", (fun args -> " "if args = (C_list [ raw_ptr ]) then _%s args else C_void) ;\n", symname, mangled_getname);
- }
- Delete(mangled_getname);
- Delete(mname);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * functionWrapper()
- * Create a function declaration and register it with the interpreter.
- * ------------------------------------------------------------ */
-
- virtual int functionWrapper(Node *n) {
- char *iname = GetChar(n, "sym:name");
- SwigType *d = Getattr(n, "type");
- String *return_type_normalized = normalizeTemplatedClassName(d);
- ParmList *l = Getattr(n, "parms");
- int director_method = 0;
- Parm *p;
-
- Wrapper *f = NewWrapper();
- String *proc_name = NewString("");
- String *target = NewString("");
- String *arg = NewString("");
- String *cleanup = NewString("");
- String *outarg = NewString("");
- String *build = NewString("");
- String *tm;
- int i = 0;
- int numargs;
- int numreq;
- int newobj = GetFlag(n, "feature:new");
- String *nodeType = Getattr(n, "nodeType");
- int destructor = (!Cmp(nodeType, "destructor"));
- String *overname = 0;
- bool isOverloaded = Getattr(n, "sym:overloaded") ? true : false;
- // For overloaded functions, only the dispatch function needs to be exposed in the ml and mli files.
- bool expose_func = !isOverloaded || !Getattr(n, "sym:nextSibling");
-
- // Make a wrapper name for this
- String *wname = Swig_name_wrapper(iname);
- if (isOverloaded) {
- overname = Getattr(n, "sym:overname");
- } else {
- if (!addSymbol(iname, n)) {
- DelWrapper(f);
- return SWIG_ERROR;
- }
- }
- if (overname) {
- Append(wname, overname);
- }
- /* Do this to disambiguate functions emitted from different modules */
- Append(wname, module);
-
- Setattr(n, "wrap:name", wname);
-
- // Build the name for Scheme.
- Printv(proc_name, "_", iname, NIL);
- String *mangled_name = mangleNameForCaml(proc_name);
-
- if (classmode && in_constructor && expose_func) { // Emit constructor for object
- String *mangled_name_nounder = NewString((char *) (Char(mangled_name)) + 1);
- Printf(f_class_ctors_end, "let %s clst = _%s clst\n", mangled_name_nounder, mangled_name_nounder);
- Printf(f_mlibody, "val %s : c_obj -> c_obj\n", mangled_name_nounder);
- Delete(mangled_name_nounder);
- } else if (classmode && in_destructor) {
- Printf(f_class_ctors, " \"~\", %s ;\n", mangled_name);
- } else if (classmode && !in_constructor && !in_destructor && !static_member_function &&
- !Getattr(n, "membervariableHandler:sym:name") && expose_func) {
- String *opname = Copy(Getattr(n, "memberfunctionHandler:sym:name"));
-
- Replaceall(opname, "operator ", "");
- Printf(f_class_ctors, " \"%s\", %s ;\n", opname, mangled_name);
- Delete(opname);
- }
-
- if (classmode && in_constructor) {
- Setattr(seen_constructors, mangled_name, "true");
- }
- // writing the function wrapper function
- Printv(f->def, "SWIGEXT CAML_VALUE ", wname, " (", NIL);
- Printv(f->def, "CAML_VALUE args", NIL);
- Printv(f->def, ")\n{", NIL);
-
- /* Define the scheme name in C. This define is used by several
- macros. */
- //Printv(f->def, "#define FUNC_NAME \"", mangled_name, "\"", NIL);
-
- // adds local variables
- Wrapper_add_local(f, "args", "CAMLparam1(args)");
- Wrapper_add_local(f, "ret", "SWIG_CAMLlocal2(swig_result,rv)");
- d = SwigType_typedef_qualified(d);
- emit_parameter_variables(l, f);
-
- /* Attach the standard typemaps */
- emit_attach_parmmaps(l, f);
- Setattr(n, "wrap:parms", l);
-
- numargs = emit_num_arguments(l);
- numreq = emit_num_required(l);
- if (!isOverloaded) {
- if (numargs > 0) {
- if (numreq > 0) {
- Printf(f->code, "if (caml_list_length(args) < %d || caml_list_length(args) > %d) {\n", numreq, numargs);
- } else {
- Printf(f->code, "if (caml_list_length(args) > %d) {\n", numargs);
- }
- Printf(f->code, "caml_invalid_argument(\"Incorrect number of arguments passed to '%s'\");\n}\n", iname);
- } else {
- Printf(f->code, "if (caml_list_length(args) > 0) caml_invalid_argument(\"'%s' takes no arguments\");\n", iname);
- }
- }
- Printf(f->code, "swig_result = Val_unit;\n");
-
- // Now write code to extract the parameters (this is super ugly)
-
- for (i = 0, p = l; i < numargs; i++) {
- /* Skip ignored arguments */
- while (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- }
-
- SwigType *pt = Getattr(p, "type");
- String *ln = Getattr(p, "lname");
- pt = SwigType_typedef_qualified(pt);
-
- // Produce names of source and target
- Clear(target);
- Clear(arg);
- String *source = NewStringf("caml_list_nth(args,%d)", i);
- Printf(target, "%s", ln);
- Printv(arg, Getattr(p, "name"), NIL);
-
- if (i >= numreq) {
- Printf(f->code, "if (caml_list_length(args) > %d) {\n", i);
- }
- // Handle parameter types.
- if ((tm = Getattr(p, "tmap:in"))) {
- Replaceall(tm, "$input", source);
- Setattr(p, "emit:input", source);
- Printv(f->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:in:next");
- } else {
- // no typemap found
- // check if typedef and resolve
- throw_unhandled_ocaml_type_error(pt, "in");
- p = nextSibling(p);
- }
- if (i >= numreq) {
- Printf(f->code, "}\n");
- }
- Delete(source);
- }
-
- /* Insert constraint checking code */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:check"))) {
- Printv(f->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:check:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- // Pass output arguments back to the caller.
-
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:argout"))) {
- Replaceall(tm, "$arg", Getattr(p, "emit:input"));
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Replaceall(tm, "$ntype", normalizeTemplatedClassName(Getattr(p, "type")));
- Printv(outarg, tm, "\n", NIL);
- p = Getattr(p, "tmap:argout:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- // Free up any memory allocated for the arguments.
-
- /* Insert cleanup code */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:freearg"))) {
- Printv(cleanup, tm, "\n", NIL);
- p = Getattr(p, "tmap:freearg:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* if the object is a director, and the method call originated from its
- * underlying ocaml object, resolve the call by going up the c++
- * inheritance chain. otherwise try to resolve the method in ocaml.
- * without this check an infinite loop is set up between the director and
- * shadow class method calls.
- */
-
- // NOTE: this code should only be inserted if this class is the
- // base class of a director class. however, in general we haven't
- // yet analyzed all classes derived from this one to see if they are
- // directors. furthermore, this class may be used as the base of
- // a director class defined in a completely different module at a
- // later time, so this test must be included whether or not directorbase
- // is true. we do skip this code if directors have not been enabled
- // at the command line to preserve source-level compatibility with
- // non-polymorphic swig. also, if this wrapper is for a smart-pointer
- // method, there is no need to perform the test since the calling object
- // (the smart-pointer) and the director object (the "pointee") are
- // distinct.
-
- director_method = is_member_director(n) && !is_smart_pointer() && !destructor;
- if (director_method) {
- Wrapper_add_local(f, "director", "Swig::Director *director = 0");
- Printf(f->code, "director = dynamic_cast<Swig::Director *>(arg1);\n");
- Wrapper_add_local(f, "upcall", "bool upcall = false");
- Append(f->code, "upcall = (director);\n");
- }
-
- // Now write code to make the function call
- Swig_director_emit_dynamic_cast(n, f);
- String *actioncode = emit_action(n);
-
- if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
- Replaceall(tm, "$result", "rv");
- Replaceall(tm, "$ntype", return_type_normalized);
- Printv(f->code, tm, "\n", NIL);
- } else {
- throw_unhandled_ocaml_type_error(d, "out");
- }
- emit_return_variable(n, d, f);
-
- // Dump the argument output code
- Printv(f->code, Char(outarg), NIL);
-
- // Dump the argument cleanup code
- Printv(f->code, Char(cleanup), NIL);
-
- // Look for any remaining cleanup
-
- if (GetFlag(n, "feature:new")) {
- if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
- Printv(f->code, tm, "\n", NIL);
- }
- }
-
- /* See if there is any return cleanup code */
- if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
- Printf(f->code, "%s\n", tm);
- Delete(tm);
- }
-
- // Free any memory allocated by the function being wrapped..
-
- if ((tm = Swig_typemap_lookup("swig_result", n, Swig_cresult_name(), 0))) {
- Printv(f->code, tm, "\n", NIL);
- }
- // Wrap things up (in a manner of speaking)
-
- Printv(f->code, tab4, "swig_result = caml_list_append(swig_result,rv);\n", NIL);
- Printv(f->code, tab4, "CAMLreturn(swig_result);\n", NIL);
- Printv(f->code, "}\n", NIL);
-
- /* Substitute the function name */
- Replaceall(f->code, "$symname", iname);
-
- Wrapper_print(f, f_wrappers);
-
- if (isOverloaded) {
- if (!Getattr(n, "sym:nextSibling")) {
- int maxargs;
- Wrapper *df = NewWrapper();
- String *dispatch = Swig_overload_dispatch(n,
- "free(argv);\n" "CAMLreturn(%s(args));\n",
- &maxargs);
-
- Wrapper_add_local(df, "argv", "CAML_VALUE *argv");
-
- /* Undifferentiate name .. this is the dispatch function */
- wname = Swig_name_wrapper(iname);
- /* Do this to disambiguate functions emitted from different
- * modules */
- Append(wname, module);
-
- Printv(df->def,
- "SWIGEXT CAML_VALUE ", wname, "(CAML_VALUE args) {\n" " CAMLparam1(args);\n" " int i;\n" " int argc = caml_list_length(args);\n", NIL);
- Printv(df->code,
- "argv = (CAML_VALUE *)malloc( argc * sizeof( CAML_VALUE ) );\n"
- "for( i = 0; i < argc; i++ ) {\n" " argv[i] = caml_list_nth(args,i);\n" "}\n", NIL);
- Printv(df->code, dispatch, "\nfree(argv);\n", NIL);
- Node *sibl = n;
- while (Getattr(sibl, "sym:previousSibling"))
- sibl = Getattr(sibl, "sym:previousSibling");
- String *protoTypes = NewString("");
- do {
- String *fulldecl = Swig_name_decl(sibl);
- Printf(protoTypes, "\n\" %s\\n\"", fulldecl);
- Delete(fulldecl);
- } while ((sibl = Getattr(sibl, "sym:nextSibling")));
- Printf(df->code, "caml_failwith(\"Wrong number or type of arguments for overloaded function '%s'.\\n\""
- "\n\" Possible C/C++ prototypes are:\\n\"%s);\n", iname, protoTypes);
- Delete(protoTypes);
- Printv(df->code, "}\n", NIL);
- Wrapper_print(df, f_wrappers);
-
- DelWrapper(df);
- Delete(dispatch);
- }
- }
-
- if (expose_func) {
- Printf(f_mlbody, "external %s_f : c_obj list -> c_obj list = \"%s\" ;;\n", mangled_name, wname);
- Printf(f_mlbody, "let %s arg = match %s_f (%s(fnhelper arg)) with\n", mangled_name, mangled_name,
- in_constructor && Swig_directorclass(getCurrentClass()) ? "director_core_helper " : "");
- Printf(f_mlbody, " [] -> C_void\n"
- "| [x] -> (if %s then Gc.finalise \n"
- " (fun x -> ignore ((invoke x) \"~\" C_void)) x) ; x\n"
- "| lst -> C_list lst ;;\n", newobj ? "true" : "false");
- }
-
- if ((!classmode || in_constructor || in_destructor || static_member_function) && expose_func)
- Printf(f_mlibody, "val %s : c_obj -> c_obj\n", mangled_name);
-
- Delete(proc_name);
- Delete(target);
- Delete(arg);
- Delete(outarg);
- Delete(cleanup);
- Delete(build);
- DelWrapper(f);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * variableWrapper()
- *
- * Create a link to a C variable.
- * This creates a single function _wrap_varname().
- * This function takes a single optional argument. If supplied, it means
- * we are setting this variable to some value. If omitted, it means we are
- * simply evaluating this variable. We return the value of the variable
- * in both cases.
- *
- * symname is the name of the variable with respect to C. This
- * may need to differ from the original name in the case of enums.
- * enumvname is the name of the variable with respect to ocaml. This
- * will vary if the variable has been renamed.
- * ------------------------------------------------------------ */
-
- virtual int variableWrapper(Node *n) {
- char *name = GetChar(n, "feature:symname");
- String *iname = Getattr(n, "feature:enumvname");
- String *mname = mangleNameForCaml(iname);
- SwigType *t = Getattr(n, "type");
-
- String *proc_name = NewString("");
- String *tm;
- Wrapper *f;
-
- if (!name) {
- name = GetChar(n, "name");
- }
-
- if (!iname) {
- iname = Getattr(n, "sym:name");
- mname = mangleNameForCaml(NewString(iname));
- }
-
- if (!iname || !addSymbol(iname, n))
- return SWIG_ERROR;
-
- f = NewWrapper();
-
- // evaluation function names
- String *var_name = Swig_name_wrapper(iname);
-
- // Build the name for OCaml.
- Printv(proc_name, iname, NIL);
- Setattr(n, "wrap:name", proc_name);
-
- Printf(f->def, "SWIGEXT CAML_VALUE %s(CAML_VALUE args) {\n", var_name);
- // Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
-
- Wrapper_add_local(f, "args", "CAMLparam1(args)");
- Wrapper_add_local(f, "swig_result", "SWIG_CAMLlocal1(swig_result)");
- Printf(f->code, "swig_result = Val_unit;\n");
-
- if (!GetFlag(n, "feature:immutable")) {
- /* Check for a setting of the variable value */
- Printf(f->code, "if (args != Val_int(0)) {\n");
- if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
- Replaceall(tm, "$input", "args");
- emit_action_code(n, f->code, tm);
- } else if ((tm = Swig_typemap_lookup("in", n, name, 0))) {
- Replaceall(tm, "$input", "args");
- emit_action_code(n, f->code, tm);
- } else {
- throw_unhandled_ocaml_type_error(t, "varin/in");
- }
- Printf(f->code, "}\n");
- }
- // Now return the value of the variable (regardless
- // of evaluating or setting)
-
- if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
- Replaceall(tm, "$result", "swig_result");
- emit_action_code(n, f->code, tm);
- } else if ((tm = Swig_typemap_lookup("out", n, name, 0))) {
- Replaceall(tm, "$result", "swig_result");
- emit_action_code(n, f->code, tm);
- } else {
- throw_unhandled_ocaml_type_error(t, "varout/out");
- }
-
- Printf(f->code, "\nCAMLreturn(swig_result);\n");
- Printf(f->code, "}\n");
-
- Wrapper_print(f, f_wrappers);
-
- // Now add symbol to the Ocaml interpreter
-
- if (GetFlag(n, "feature:immutable")) {
- Printf(f_mlbody, "external _%s : c_obj -> Swig.c_obj = \"%s\" \n", mname, var_name);
- Printf(f_mlibody, "val _%s : c_obj -> Swig.c_obj\n", iname);
- if (const_enum) {
- Printf(f_enum_to_int, " | `%s -> _%s C_void\n", mname, mname);
- Printf(f_int_to_enum, " if y = (get_int (_%s C_void)) then `%s else\n", mname, mname);
- }
- } else {
- Printf(f_mlbody, "external _%s : c_obj -> c_obj = \"%s\"\n", mname, var_name);
- Printf(f_mlibody, "external _%s : c_obj -> c_obj = \"%s\"\n", mname, var_name);
- }
-
- Delete(var_name);
- Delete(proc_name);
- DelWrapper(f);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * staticmemberfunctionHandler --
- * Overridden to set static_member_function
- * ------------------------------------------------------------ */
-
- virtual int staticmemberfunctionHandler(Node *n) {
- static_member_function = 1;
- Language::staticmemberfunctionHandler(n);
- static_member_function = 0;
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * constantWrapper()
- *
- * The one trick here is that we have to make sure we rename the
- * constant to something useful that doesn't collide with the
- * original if any exists.
- * ------------------------------------------------------------ */
-
- virtual int constantWrapper(Node *n) {
- String *name = Getattr(n, "feature:symname");
- SwigType *type = Getattr(n, "type");
- String *rawval = Getattr(n, "rawval");
- String *value = rawval ? rawval : Getattr(n, "value");
- SwigType *qname = Getattr(n, "qualified:name");
-
- if (qname)
- value = qname;
-
- if (!name) {
- name = mangleNameForCaml(Getattr(n, "name"));
- Insert(name, 0, "_swig_wrap_");
- Setattr(n, "feature:symname", name);
- }
- // See if there's a typemap
-
- // Create variable and assign it a value
- Printf(f_header, "static %s = %s;\n", SwigType_str(type, name), value);
- SetFlag(n, "feature:immutable");
- variableWrapper(n);
- return SWIG_OK;
- }
-
- int constructorHandler(Node *n) {
- int ret;
-
- in_constructor = 1;
- ret = Language::constructorHandler(n);
- in_constructor = 0;
-
- return ret;
- }
-
- /* destructorHandler:
- * Turn on destructor flag to inform decisions in functionWrapper
- */
-
- int destructorHandler(Node *n) {
- int ret;
-
- in_destructor = 1;
- ret = Language::destructorHandler(n);
- in_destructor = 0;
-
- return ret;
- }
-
- /* copyconstructorHandler:
- * Turn on constructor and copyconstructor flags for functionWrapper
- */
-
- int copyconstructorHandler(Node *n) {
- int ret;
-
- in_copyconst = 1;
- in_constructor = 1;
- ret = Language::copyconstructorHandler(n);
- in_constructor = 0;
- in_copyconst = 0;
-
- return ret;
- }
-
- /**
- * A simple, somewhat general purpose function for writing to multiple
- * streams from a source template. This allows the user to define the
- * class definition in ways different from the one I have here if they
- * want to. It will also make the class definition system easier to
- * fiddle with when I want to change methods, etc.
- */
-
- void Multiwrite(String *s) {
- char *find_marker = strstr(Char(s), "(*Stream:");
- while (find_marker) {
- char *next = strstr(find_marker, "*)");
- find_marker += strlen("(*Stream:");
-
- if (next) {
- int num_chars = (int)(next - find_marker);
- String *stream_name = NewString(find_marker);
- Delslice(stream_name, num_chars, Len(stream_name));
- File *fout = Swig_filebyname(stream_name);
- if (fout) {
- next += strlen("*)");
- char *following = strstr(next, "(*Stream:");
- find_marker = following;
- if (!following)
- following = next + strlen(next);
- String *chunk = NewString(next);
- Delslice(chunk, (int)(following - next), Len(chunk));
- Printv(fout, chunk, NIL);
- }
- }
- }
- }
-
- bool isSimpleType(String *name) {
- char *ch = Char(name);
-
- return !(strchr(ch, '(') || strchr(ch, '<') || strchr(ch, ')') || strchr(ch, '>'));
- }
-
- /* We accept all chars in identifiers because we use strings to index
- * them. */
- int validIdentifier(String *name) {
- return Len(name) > 0 ? 1 : 0;
- }
-
- /* classHandler
- *
- * Create a "class" definition for ocaml. I thought quite a bit about
- * how I should do this part of it, and arrived here, using a function
- * invocation to select a method, and dispatch. This can obviously be
- * done better, but I can't see how, given that I want to support
- * overloaded methods, out parameters, and operators.
- *
- * I needed a system that would do this:
- *
- * a Be able to call these methods:
- * int foo( int x );
- * float foo( int x, int &out );
- *
- * b Be typeable, even in the presence of mutually dependent classes.
- *
- * c Support some form of operator invocation.
- *
- * (c) I chose strings for the method names so that "+=" would be a
- * valid method name, and the somewhat natural << (invoke x) "+=" y >>
- * would work.
- *
- * (a) (b) Since the c_obj type exists, it's easy to return C_int in one
- * case and C_list [ C_float ; C_int ] in the other. This makes tricky
- * problems with out parameters disappear; they're simply appended to the
- * return list.
- *
- * (b) Since every item that comes from C++ is the same type, there is no
- * problem with the following:
- *
- * class Foo;
- * class Bar { Foo *toFoo(); }
- * class Foo { Bar *toBar(); }
- *
- * Since the Objective caml types of Foo and Bar are the same. Now that
- * I correctly incorporate SWIG's typechecking, this isn't a big deal.
- *
- * The class is in the form of a function returning a c_obj. The c_obj
- * is a C_obj containing a function which invokes a method on the
- * underlying object given its type.
- *
- * The name emitted here is normalized before being sent to
- * Callback.register, because we need this string to look up properly
- * when the typemap passes the descriptor string. I've been considering
- * some, possibly more forgiving method that would do some transformations
- * on the $descriptor in order to find a potential match. This is for
- * later.
- *
- * Important things to note:
- *
- * We rely on exception handling (BadMethodName) in order to call an
- * ancestor. This can be improved.
- *
- * The method used to get :classof could be improved to look at the type
- * info that the base pointer contains. It's really an error to have a
- * SWIG-generated object that does not contain type info, since the
- * existence of the object means that SWIG knows the type.
- *
- * :parents could use :classof to tell what class it is and make a better
- * decision. This could be nice, (i.e. provide a run-time graph of C++
- * classes represented);.
- *
- * I can't think of a more elegant way of converting a C_obj fun to a
- * pointer than "operator &"...
- *
- * Added a 'sizeof' that will allow you to do the expected thing.
- * This should help users to fill buffer structs and the like (as is
- * typical in windows-styled code). It's only enabled if you give
- * %feature(sizeof) and then, only for simple types.
- *
- * Overall, carrying the list of methods and base classes has worked well.
- * It allows me to give the Ocaml user introspection over their objects.
- */
-
- int classHandler(Node *n) {
- String *name = Getattr(n, "name");
- classname = Getattr(n, "sym:name");
-
- if (!name)
- return SWIG_OK;
-
- String *mangled_name = mangleNameForCaml(name);
- String *this_class_def = NewString(f_classtemplate);
- String *name_normalized = normalizeTemplatedClassName(name);
- String *old_class_ctors = f_class_ctors;
- String *base_classes = NewString("");
- f_class_ctors = NewString("");
- bool sizeof_feature = generate_sizeof && isSimpleType(name);
-
-
- classmode = true;
- int rv = Language::classHandler(n);
- classmode = false;
-
- if (sizeof_feature) {
- Printf(f_wrappers,
- "SWIGEXT CAML_VALUE _wrap_%s_sizeof( CAML_VALUE args ) {\n"
- " CAMLparam1(args);\n" " CAMLreturn(Val_int(sizeof(%s)));\n" "}\n", mangled_name, name_normalized);
-
- Printf(f_mlbody, "external __%s_sizeof : unit -> int = " "\"_wrap_%s_sizeof\"\n", mangled_name, mangled_name);
- }
-
-
- /* Insert sizeof operator for concrete classes */
- if (sizeof_feature) {
- Printv(f_class_ctors, "\"sizeof\" , (fun args -> C_int (__", mangled_name, "_sizeof ())) ;\n", NIL);
- }
- /* Handle up-casts in a nice way */
- List *baselist = Getattr(n, "bases");
- if (baselist && Len(baselist)) {
- Iterator b;
- b = First(baselist);
- while (b.item) {
- String *bname = Getattr(b.item, "name");
- if (bname) {
- String *base_create = NewString("");
- Printv(base_create, "(create_class \"", bname, "\")", NIL);
- Printv(f_class_ctors, " \"::", bname, "\", (fun args -> ", base_create, " args) ;\n", NIL);
- Printv(base_classes, base_create, " ;\n", NIL);
- }
- b = Next(b);
- }
- }
-
- Replaceall(this_class_def, "$classname", mangled_name);
- Replaceall(this_class_def, "$normalized", name_normalized);
- Replaceall(this_class_def, "$realname", name);
- Replaceall(this_class_def, "$baselist", base_classes);
- Replaceall(this_class_def, "$classbody", f_class_ctors);
-
- Delete(f_class_ctors);
- f_class_ctors = old_class_ctors;
-
- // Actually write out the class definition
-
- Multiwrite(this_class_def);
-
- Setattr(n, "ocaml:ctor", mangled_name);
-
- return rv;
- }
-
- String *normalizeTemplatedClassName(String *name) {
- String *name_normalized = SwigType_typedef_resolve_all(name);
- bool took_action;
-
- do {
- took_action = false;
-
- if (is_a_pointer(name_normalized)) {
- SwigType_del_pointer(name_normalized);
- took_action = true;
- }
-
- if (is_a_reference(name_normalized)) {
- oc_SwigType_del_reference(name_normalized);
- took_action = true;
- }
-
- if (is_an_array(name_normalized)) {
- oc_SwigType_del_array(name_normalized);
- took_action = true;
- }
- } while (took_action);
-
- return SwigType_str(name_normalized, 0);
- }
-
- /*
- * Produce the symbol name that ocaml will use when referring to the
- * target item. I wonder if there's a better way to do this:
- *
- * I shudder to think about doing it with a hash lookup, but that would
- * make a couple of things easier:
- */
-
- String *mangleNameForCaml(String *s) {
- String *out = Copy(s);
- Replaceall(out, " ", "_xx");
- Replaceall(out, "::", "_xx");
- Replaceall(out, ",", "_x");
- Replaceall(out, "+", "_xx_plus");
- Replaceall(out, "-", "_xx_minus");
- Replaceall(out, "<", "_xx_ldbrace");
- Replaceall(out, ">", "_xx_rdbrace");
- Replaceall(out, "!", "_xx_not");
- Replaceall(out, "%", "_xx_mod");
- Replaceall(out, "^", "_xx_xor");
- Replaceall(out, "*", "_xx_star");
- Replaceall(out, "&", "_xx_amp");
- Replaceall(out, "|", "_xx_or");
- Replaceall(out, "(", "_xx_lparen");
- Replaceall(out, ")", "_xx_rparen");
- Replaceall(out, "[", "_xx_lbrace");
- Replaceall(out, "]", "_xx_rbrace");
- Replaceall(out, "~", "_xx_bnot");
- Replaceall(out, "=", "_xx_equals");
- Replaceall(out, "/", "_xx_slash");
- Replaceall(out, ".", "_xx_dot");
- return out;
- }
-
- SwigType *fully_qualified_enum_type(Node *n) {
- Node *parent = 0;
- String *fully_qualified_name = NewString("");
- String *parent_type = 0;
-
- parent = parentNode(n);
- while (parent) {
- parent_type = nodeType(parent);
- if (Getattr(parent, "name")) {
- String *parent_copy = NewStringf("%s::", Getattr(parent, "name"));
- if (Cmp(parent_type, "class") == 0 || Cmp(parent_type, "namespace") == 0)
- Insert(fully_qualified_name, 0, parent_copy);
- Delete(parent_copy);
- }
- if (!Cmp(parent_type, "class"))
- break;
- parent = parentNode(parent);
- }
-
- return fully_qualified_name;
- }
-
- /* Benedikt Grundmann inspired --> Enum wrap styles */
-
- int enumvalueDeclaration(Node *n) {
- String *name = Getattr(n, "name");
- String *symname = Getattr(n, "sym:name");
- SwigType *qtype = 0;
-
- if (name_qualifier_type) {
- qtype = Copy(name_qualifier_type);
- Printv(qtype, name, NIL);
- }
-
- if (const_enum && qtype && symname && !Getattr(seen_enumvalues, symname)) {
- Setattr(seen_enumvalues, symname, "true");
- SetFlag(n, "feature:immutable");
- Setattr(n, "feature:enumvalue", "1"); // this does not appear to be used
-
- Setattr(n, "qualified:name", SwigType_namestr(qtype));
-
- String *evname = SwigType_manglestr(qtype);
- Insert(evname, 0, "SWIG_ENUM_");
-
- Setattr(n, "feature:enumvname", symname);
- Setattr(n, "feature:symname", evname);
- Delete(evname);
- Printf(f_enumtypes_value, "| `%s\n", symname);
-
- return Language::enumvalueDeclaration(n);
- } else
- return SWIG_OK;
- }
-
- /* -------------------------------------------------------------------
- * This function is a bit uglier than it deserves.
- *
- * I used to direct lookup the name of the enum. Now that certain fixes
- * have been made in other places, the names of enums are now fully
- * qualified, which is a good thing, overall, but requires me to do
- * some legwork.
- *
- * The other thing that uglifies this function is the varying way that
- * typedef enum and enum are handled. I need to produce consistent names,
- * which means looking up and registering by typedef and enum name. */
- int enumDeclaration(Node *n) {
- if (getCurrentClass() && (cplus_mode != PUBLIC))
- return SWIG_NOWRAP;
-
- String *name = Getattr(n, "name");
- if (name) {
- String *oname = NewString(name);
- /* name is now fully qualified */
- String *fully_qualified_name = NewString(name);
- bool seen_enum = false;
- if (name_qualifier_type)
- Delete(name_qualifier_type);
- char *strip_position;
- name_qualifier_type = fully_qualified_enum_type(n);
-
- strip_position = strstr(Char(oname), "::");
-
- while (strip_position) {
- strip_position += 2;
- oname = NewString(strip_position);
- strip_position = strstr(Char(oname), "::");
- }
-
- seen_enum = (Getattr(seen_enums, fully_qualified_name) ? true : false);
-
- if (!seen_enum) {
- const_enum = true;
- Printf(f_enum_to_int, "| `%s -> (match y with\n", oname);
- Printf(f_int_to_enum, "| `%s -> C_enum (\n", oname);
- /* * * * A note about enum name resolution * * * *
- * This code should now work, but I think we can do a bit better.
- * The problem I'm having is that swig isn't very precise about
- * typedef name resolution. My opinion is that SwigType_typedef
- * resolve_all should *always* return the enum tag if one exists,
- * rather than the admittedly friendlier enclosing typedef.
- *
- * This would make one of the cases below unnecessary.
- * * * */
- Printf(f_mlbody, "let _ = Callback.register \"%s_marker\" (`%s)\n", fully_qualified_name, oname);
- if (!strncmp(Char(fully_qualified_name), "enum ", 5)) {
- String *fq_noenum = NewString(Char(fully_qualified_name) + 5);
- Printf(f_mlbody,
- "let _ = Callback.register \"%s_marker\" (`%s)\n" "let _ = Callback.register \"%s_marker\" (`%s)\n", fq_noenum, oname, fq_noenum, name);
- }
-
- Printf(f_enumtypes_type, "| `%s\n", oname);
- Insert(fully_qualified_name, 0, "enum ");
- Setattr(seen_enums, fully_qualified_name, n);
- }
- }
-
- int ret = Language::enumDeclaration(n);
-
- if (const_enum) {
- Printf(f_int_to_enum, "`Int y)\n");
- Printf(f_enum_to_int, "| `Int x -> Swig.C_int x\n" "| _ -> raise (LabelNotFromThisEnum v))\n");
- }
-
- const_enum = false;
-
- return ret;
- }
-
- /* ----------------------------------------------------------------------------
- * BEGIN C++ Director Class modifications
- * ------------------------------------------------------------------------- */
-
- /*
- * Modified polymorphism code for Ocaml language module.
- *
- * TODO
- *
- * Move some boilerplate code generation to Swig_...() functions.
- *
- */
-
- /* ---------------------------------------------------------------
- * classDirectorMethod()
- *
- * Emit a virtual director method to pass a method call on to the
- * underlying Python object.
- *
- * --------------------------------------------------------------- */
-
- int classDirectorMethod(Node *n, Node *parent, String *super) {
- int is_void = 0;
- int is_pointer = 0;
- String *storage = Getattr(n, "storage");
- String *value = Getattr(n, "value");
- String *decl = Getattr(n, "decl");
- String *returntype = Getattr(n, "type");
- String *name = Getattr(n, "name");
- String *classname = Getattr(parent, "sym:name");
- String *c_classname = Getattr(parent, "name");
- String *symname = Getattr(n, "sym:name");
- String *declaration = NewString("");
- ParmList *l = Getattr(n, "parms");
- Wrapper *w = NewWrapper();
- String *tm;
- String *wrap_args = NewString("");
- int status = SWIG_OK;
- int idx;
- bool pure_virtual = false;
- bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
-
- if (Cmp(storage, "virtual") == 0) {
- if (Cmp(value, "0") == 0) {
- pure_virtual = true;
- }
- }
- Printf(w->locals, "CAMLparam0();\n");
-
- /* determine if the method returns a pointer */
- is_pointer = SwigType_ispointer_return(decl);
- is_void = (!Cmp(returntype, "void") && !is_pointer);
-
- /* virtual method definition */
- String *target;
- String *pclassname = NewStringf("SwigDirector_%s", classname);
- String *qualified_name = NewStringf("%s::%s", pclassname, name);
- SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
- target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
- Printf(w->def, "%s", target);
- Delete(qualified_name);
- Delete(target);
- /* header declaration */
- target = Swig_method_decl(rtype, decl, name, l, 1);
- Printf(declaration, " virtual %s", target);
- Delete(target);
-
- // Get any exception classes in the throws typemap
- if (Getattr(n, "noexcept")) {
- Append(w->def, " noexcept");
- Append(declaration, " noexcept");
- }
- ParmList *throw_parm_list = 0;
- if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
- Parm *p;
- int gencomma = 0;
-
- Append(w->def, " throw(");
- Append(declaration, " throw(");
-
- if (throw_parm_list)
- Swig_typemap_attach_parms("throws", throw_parm_list, 0);
- for (p = throw_parm_list; p; p = nextSibling(p)) {
- if (Getattr(p, "tmap:throws")) {
- if (gencomma++) {
- Append(w->def, ", ");
- Append(declaration, ", ");
- }
- String *str = SwigType_str(Getattr(p, "type"), 0);
- Append(w->def, str);
- Append(declaration, str);
- Delete(str);
- }
- }
- Append(w->def, ")");
- Append(declaration, ")");
- }
- Append(w->def, " {");
- Append(declaration, ";\n");
- /* declare method return value
- * if the return value is a reference or const reference, a specialized typemap must
- * handle it, including declaration of c_result ($result).
- */
- if (!is_void && (!ignored_method || pure_virtual)) {
- if (!SwigType_isclass(returntype)) {
- if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
- String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
- Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL);
- Delete(construct_result);
- } else {
- Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL);
- }
- } else {
- String *cres = SwigType_lstr(returntype, "c_result");
- Printf(w->code, "%s;\n", cres);
- Delete(cres);
- }
- }
-
- if (ignored_method) {
- if (!pure_virtual) {
- String *super_call = Swig_method_call(super, l);
- if (is_void)
- Printf(w->code, "%s;\n", super_call);
- else
- Printf(w->code, "CAMLreturn_type(%s);\n", super_call);
- Delete(super_call);
- } else {
- Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
- SwigType_namestr(name));
- }
- } else {
- Wrapper_add_local(w, "swig_result", "SWIG_CAMLlocal2(swig_result, args)");
- /* attach typemaps to arguments (C/C++ -> Ocaml) */
- String *arglist = NewString("");
-
- Swig_director_parms_fixup(l);
-
- Swig_typemap_attach_parms("in", l, 0);
- Swig_typemap_attach_parms("directorin", l, w);
- Swig_typemap_attach_parms("directorargout", l, w);
-
- Parm *p;
- int num_arguments = emit_num_arguments(l);
- int i;
- char source[256];
-
- /* build argument list and type conversion string */
- for (i = 0, idx = 0, p = l; i < num_arguments; i++) {
-
- while (Getattr(p, "tmap:ignore")) {
- p = Getattr(p, "tmap:ignore:next");
- }
-
- String *pname = Getattr(p, "name");
- String *ptype = Getattr(p, "type");
-
- Putc(',', arglist);
- if ((tm = Getattr(p, "tmap:directorin")) != 0) {
- Setattr(p, "emit:directorinput", pname);
- Replaceall(tm, "$input", pname);
- Replaceall(tm, "$owner", "0");
- if (Len(tm) == 0)
- Append(tm, pname);
- Printv(wrap_args, tm, "\n", NIL);
- p = Getattr(p, "tmap:directorin:next");
- continue;
- } else if (Cmp(ptype, "void")) {
- /* special handling for pointers to other C++ director classes.
- * ideally this would be left to a typemap, but there is currently no
- * way to selectively apply the dynamic_cast<> to classes that have
- * directors. in other words, the type "SwigDirector_$1_lname" only exists
- * for classes with directors. we avoid the problem here by checking
- * module.wrap::directormap, but it's not clear how to get a typemap to
- * do something similar. perhaps a new default typemap (in addition
- * to SWIGTYPE) called DIRECTORTYPE?
- */
- if (SwigType_ispointer(ptype) || SwigType_isreference(ptype)) {
- Node *module = Getattr(parent, "module");
- Node *target = Swig_directormap(module, ptype);
- sprintf(source, "obj%d", idx++);
- String *nonconst = 0;
- /* strip pointer/reference --- should move to Swig/stype.c */
- String *nptype = NewString(Char(ptype) + 2);
- /* name as pointer */
- String *ppname = Copy(pname);
- if (SwigType_isreference(ptype)) {
- Insert(ppname, 0, "&");
- }
- /* if necessary, cast away const since Python doesn't support it! */
- if (SwigType_isconst(nptype)) {
- nonconst = NewStringf("nc_tmp_%s", pname);
- String *nonconst_i = NewStringf("= const_cast< %s >(%s)", SwigType_lstr(ptype, 0), ppname);
- Wrapper_add_localv(w, nonconst, SwigType_lstr(ptype, 0), nonconst, nonconst_i, NIL);
- Delete(nonconst_i);
- Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number,
- "Target language argument '%s' discards const in director method %s::%s.\n", SwigType_str(ptype, pname),
- SwigType_namestr(c_classname), SwigType_namestr(name));
- } else {
- nonconst = Copy(ppname);
- }
- Delete(nptype);
- Delete(ppname);
- String *mangle = SwigType_manglestr(ptype);
- if (target) {
- String *director = NewStringf("director_%s", mangle);
- Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL);
- Wrapper_add_localv(w, source, "CAML_VALUE", source, "= Val_unit", NIL);
- Printf(wrap_args, "%s = dynamic_cast<Swig::Director *>(%s);\n", director, nonconst);
- Printf(wrap_args, "if (!%s) {\n", director);
- Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
- Printf(wrap_args, "} else {\n");
- Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director);
- Printf(wrap_args, "}\n");
- Delete(director);
- Printv(arglist, source, NIL);
- } else {
- Wrapper_add_localv(w, source, "CAML_VALUE", source, "= Val_unit", NIL);
- Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
- //Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n",
- // source, nonconst, base);
- Printv(arglist, source, NIL);
- }
- Delete(mangle);
- Delete(nonconst);
- } else {
- Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
- "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0),
- SwigType_namestr(c_classname), SwigType_namestr(name));
- status = SWIG_NOWRAP;
- break;
- }
- }
- p = nextSibling(p);
- }
-
- Printv(w->code, "swig_result = Val_unit;\n", 0);
- Printf(w->code, "args = Val_unit;\n");
-
- /* wrap complex arguments to values */
- Printv(w->code, wrap_args, NIL);
-
- /* pass the method call on to the OCaml object */
- Printv(w->code,
- "swig_result = caml_swig_alloc(1,C_list);\n" "SWIG_Store_field(swig_result,0,args);\n" "args = swig_result;\n" "swig_result = Val_unit;\n", 0);
- Printf(w->code, "static const CAML_VALUE *swig_ocaml_func_val = NULL;\n" "if (!swig_ocaml_func_val) {\n");
- Printf(w->code, " swig_ocaml_func_val = caml_named_value(\"swig_runmethod\");\n }\n");
- Printf(w->code, "swig_result = caml_callback3(*swig_ocaml_func_val,swig_get_self(),caml_copy_string(\"%s\"),args);\n", Getattr(n, "name"));
- /* exception handling */
- tm = Swig_typemap_lookup("director:except", n, Swig_cresult_name(), 0);
- if (!tm) {
- tm = Getattr(n, "feature:director:except");
- }
- if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
- Printf(w->code, "if (!%s) {\n", Swig_cresult_name());
- Printf(w->code, " CAML_VALUE error = *caml_named_value(\"director_except\");\n");
- Replaceall(tm, "$error", "error");
- Printv(w->code, Str(tm), "\n", NIL);
- Printf(w->code, "}\n");
- }
-
- /*
- * Python method may return a simple object, or a tuple.
- * for in/out arguments, we have to extract the appropriate values from the
- * argument list, then marshal everything back to C/C++ (return value and
- * output arguments).
- */
-
- /* marshal return value and other outputs (if any) from value to C/C++
- * type */
-
- String *cleanup = NewString("");
- String *outarg = NewString("");
-
- tm = Swig_typemap_lookup("directorout", n, "c_result", w);
- if (tm != 0) {
- Replaceall(tm, "$input", "swig_result");
- /* TODO check this */
- if (Getattr(n, "wrap:disown")) {
- Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
- } else {
- Replaceall(tm, "$disown", "0");
- }
- Replaceall(tm, "$result", "c_result");
- Printv(w->code, tm, "\n", NIL);
- }
-
- /* marshal outputs */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
- Replaceall(tm, "$result", "swig_result");
- Replaceall(tm, "$input", Getattr(p, "emit:directorinput"));
- Printv(w->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:directorargout:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- Delete(arglist);
- Delete(cleanup);
- Delete(outarg);
- }
-
- /* any existing helper functions to handle this? */
- if (!is_void) {
- if (!(ignored_method && !pure_virtual)) {
- String *rettype = SwigType_str(returntype, 0);
- if (!SwigType_isreference(returntype)) {
- Printf(w->code, "CAMLreturn_type((%s)c_result);\n", rettype);
- } else {
- Printf(w->code, "CAMLreturn_type((%s)*c_result);\n", rettype);
- }
- Delete(rettype);
- }
- } else {
- Printf(w->code, "CAMLreturn0;\n");
- }
-
- Printf(w->code, "}\n");
-
- // We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
- String *inline_extra_method = NewString("");
- if (dirprot_mode() && !is_public(n) && !pure_virtual) {
- Printv(inline_extra_method, declaration, NIL);
- String *extra_method_name = NewStringf("%sSwigPublic", name);
- Replaceall(inline_extra_method, name, extra_method_name);
- Replaceall(inline_extra_method, ";\n", " {\n ");
- if (!is_void)
- Printf(inline_extra_method, "return ");
- String *methodcall = Swig_method_call(super, l);
- Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
- Delete(methodcall);
- Delete(extra_method_name);
- }
-
- /* emit the director method */
- if (status == SWIG_OK) {
- if (!Getattr(n, "defaultargs")) {
- Replaceall(w->code, "$symname", symname);
- Wrapper_print(w, f_directors);
- Printv(f_directors_h, declaration, NIL);
- Printv(f_directors_h, inline_extra_method, NIL);
- }
- }
-
- /* clean up */
- Delete(wrap_args);
- Delete(pclassname);
- DelWrapper(w);
- return status;
- }
-
- /* ------------------------------------------------------------
- * classDirectorConstructor()
- * ------------------------------------------------------------ */
-
- int classDirectorConstructor(Node *n) {
- Node *parent = Getattr(n, "parentNode");
- String *sub = NewString("");
- String *decl = Getattr(n, "decl");
- String *supername = Swig_class_name(parent);
- String *classname = NewString("");
- Printf(classname, "SwigDirector_%s", supername);
-
- /* insert self parameter */
- Parm *p, *q;
- ParmList *superparms = Getattr(n, "parms");
- ParmList *parms = CopyParmList(superparms);
- String *type = NewString("CAML_VALUE");
- p = NewParm(type, NewString("self"), n);
- q = Copy(p);
- set_nextSibling(q, superparms);
- set_nextSibling(p, parms);
- parms = p;
-
- if (!Getattr(n, "defaultargs")) {
- /* constructor */
- {
- Wrapper *w = NewWrapper();
- String *call;
- String *basetype = Getattr(parent, "classtype");
- String *target = Swig_method_decl(0, decl, classname, parms, 0);
- call = Swig_csuperclass_call(0, basetype, superparms);
- Printf(w->def, "%s::%s: %s, Swig::Director(self) { }", classname, target, call);
- Delete(target);
- Wrapper_print(w, f_directors);
- Delete(call);
- DelWrapper(w);
- }
-
- /* constructor header */
- {
- String *target = Swig_method_decl(0, decl, classname, parms, 1);
- Printf(f_directors_h, " %s;\n", target);
- Delete(target);
- }
- }
-
- Setattr(n, "parms", q);
- Language::classDirectorConstructor(n);
-
- Delete(sub);
- Delete(classname);
- Delete(supername);
- //Delete(parms);
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * classDirectorDefaultConstructor()
- * ------------------------------------------------------------ */
-
- int classDirectorDefaultConstructor(Node *n) {
- String *classname;
- classname = Swig_class_name(n);
-
- /* insert self parameter */
- Parm *p, *q;
- ParmList *superparms = Getattr(n, "parms");
- ParmList *parms = CopyParmList(superparms);
- String *type = NewString("CAML_VALUE");
- p = NewParm(type, NewString("self"), n);
- q = Copy(p);
- set_nextSibling(p, parms);
-
- {
- Wrapper *w = NewWrapper();
- Printf(w->def, "SwigDirector_%s::SwigDirector_%s(CAML_VALUE self) : Swig::Director(self) { }", classname, classname);
- Wrapper_print(w, f_directors);
- DelWrapper(w);
- }
- Printf(f_directors_h, " SwigDirector_%s(CAML_VALUE self);\n", classname);
- Delete(classname);
- Setattr(n, "parms", q);
- return Language::classDirectorDefaultConstructor(n);
- }
-
- int classDirectorInit(Node *n) {
- String *declaration = Swig_director_declaration(n);
- Printf(f_directors_h, "\n" "%s\n" "public:\n", declaration);
- Delete(declaration);
- return Language::classDirectorInit(n);
- }
-
- int classDirectorEnd(Node *n) {
- Printf(f_directors_h, "};\n\n");
- return Language::classDirectorEnd(n);
- }
-
- /* ---------------------------------------------------------------------
- * typedefHandler
- *
- * This is here in order to maintain the correct association between
- * typedef names and enum names.
- *
- * Since I implement enums as polymorphic variant tags, I need to call
- * back into ocaml to evaluate them. This requires a string that can
- * be generated in the typemaps, and also at SWIG time to be the same
- * string. The problem that arises is that SWIG variously generates
- * enum e_name_tag
- * e_name_tag
- * e_typedef_name
- * for
- * typedef enum e_name_tag { ... } e_typedef_name;
- *
- * Since I need these strings to be consistent, I must maintain a correct
- * association list between typedef and enum names.
- * --------------------------------------------------------------------- */
- int typedefHandler(Node *n) {
- String *type = Getattr(n, "type");
- Node *enum_node = type ? Getattr(seen_enums, type) : 0;
- if (enum_node) {
- String *name = Getattr(enum_node, "name");
-
- Printf(f_mlbody, "let _ = Callback.register \"%s_marker\" (`%s)\n", Getattr(n, "name"), name);
-
- }
- return SWIG_OK;
- }
-
- String *runtimeCode() {
- String *s = Swig_include_sys("ocamlrun.swg");
- if (!s) {
- Printf(stderr, "*** Unable to open 'ocamlrun.swg'\n");
- s = NewString("");
- }
- return s;
- }
-
- String *defaultExternalRuntimeFilename() {
- return NewString("swigocamlrun.h");
- }
-};
-
-/* -------------------------------------------------------------------------
- * swig_ocaml() - Instantiate module
- * ------------------------------------------------------------------------- */
-
-static Language *new_swig_ocaml() {
- return new OCAML();
-}
-extern "C" Language *swig_ocaml(void) {
- return new_swig_ocaml();
-}
diff --git a/contrib/tools/swig/Source/Modules/octave.cxx b/contrib/tools/swig/Source/Modules/octave.cxx
deleted file mode 100644
index 352105b9bd..0000000000
--- a/contrib/tools/swig/Source/Modules/octave.cxx
+++ /dev/null
@@ -1,1572 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * octave.cxx
- *
- * Octave language module for SWIG.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include "cparse.h"
-
-static String *global_name = 0;
-static String *op_prefix = 0;
-
-static const char *usage = "\
-Octave Options (available with -octave)\n\
- -globals <name> - Set <name> used to access C global variables [default: 'cvar']\n\
- Use '.' to load C global variables into module namespace\n\
- -opprefix <str> - Prefix <str> for global operator functions [default: 'op_']\n\
-\n";
-
-
-class OCTAVE:public Language {
-private:
- File *f_begin;
- File *f_runtime;
- File *f_header;
- File *f_doc;
- File *f_wrappers;
- File *f_init;
- File *f_initbeforefunc;
- File *f_directors;
- File *f_directors_h;
- String *s_global_tab;
- String *s_members_tab;
- String *class_name;
-
- int have_constructor;
- int have_destructor;
- String *constructor_name;
-
- Hash *docs;
-
- void Octave_begin_function(Node *n, File *f, const_String_or_char_ptr cname, const_String_or_char_ptr wname, bool dld) {
- if (dld) {
- String *tname = texinfo_name(n, "std::string()");
- Printf(f, "SWIG_DEFUN( %s, %s, %s ) {", cname, wname, tname);
- }
- else {
- Printf(f, "static octave_value_list %s (const octave_value_list& args, int nargout) {", wname);
- }
- }
-
-public:
- OCTAVE():
- f_begin(0),
- f_runtime(0),
- f_header(0),
- f_doc(0),
- f_wrappers(0),
- f_init(0),
- f_initbeforefunc(0),
- f_directors(0),
- f_directors_h(0),
- s_global_tab(0),
- s_members_tab(0),
- class_name(0),
- have_constructor(0),
- have_destructor(0),
- constructor_name(0),
- docs(0)
- {
- /* Add code to manage protected constructors and directors */
- director_prot_ctor_code = NewString("");
- Printv(director_prot_ctor_code,
- "if ( $comparison ) { /* subclassed */\n",
- " $director_new \n",
- "} else {\n", " error(\"accessing abstract class or protected constructor\"); \n", " SWIG_fail;\n", "}\n", NIL);
-
- enable_cplus_runtime_mode();
- allow_overloading();
- director_multiple_inheritance = 1;
- director_language = 1;
- docs = NewHash();
- }
-
- virtual void main(int argc, char *argv[]) {
-
- for (int i = 1; i < argc; i++) {
- if (argv[i]) {
- if (strcmp(argv[i], "-help") == 0) {
- fputs(usage, stdout);
- } else if (strcmp(argv[i], "-globals") == 0) {
- if (argv[i + 1]) {
- global_name = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-opprefix") == 0) {
- if (argv[i + 1]) {
- op_prefix = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-cppcast") == 0) {
- Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nocppcast") == 0) {
- Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
- Swig_mark_arg(i);
- Exit(EXIT_FAILURE);
- }
- }
- }
-
- if (!global_name)
- global_name = NewString("cvar");
- if (!op_prefix)
- op_prefix = NewString("op_");
-
- SWIG_library_directory("octave");
- Preprocessor_define("SWIGOCTAVE 1", 0);
- SWIG_config_file("octave.swg");
- SWIG_typemap_lang("octave");
- allow_overloading();
-
- // Octave API is C++, so output must be C++ compatible even when wrapping C code
- if (!cparse_cplusplus)
- Swig_cparse_cplusplusout(1);
- }
-
- virtual int top(Node *n) {
- {
- Node *mod = Getattr(n, "module");
- if (mod) {
- Node *options = Getattr(mod, "options");
- if (options) {
- int dirprot = 0;
- if (Getattr(options, "dirprot")) {
- dirprot = 1;
- }
- if (Getattr(options, "nodirprot")) {
- dirprot = 0;
- }
- if (Getattr(options, "directors")) {
- allow_directors();
- if (dirprot)
- allow_dirprot();
- }
- }
- }
- }
-
- String *module = Getattr(n, "name");
- String *outfile = Getattr(n, "outfile");
- f_begin = NewFile(outfile, "w", SWIG_output_files());
- if (!f_begin) {
- FileErrorDisplay(outfile);
- Exit(EXIT_FAILURE);
- }
- f_runtime = NewString("");
- f_header = NewString("");
- f_doc = NewString("");
- f_wrappers = NewString("");
- f_init = NewString("");
- f_initbeforefunc = NewString("");
- f_directors_h = NewString("");
- f_directors = NewString("");
- s_global_tab = NewString("");
- Swig_register_filebyname("begin", f_begin);
- Swig_register_filebyname("runtime", f_runtime);
- Swig_register_filebyname("header", f_header);
- Swig_register_filebyname("doc", f_doc);
- Swig_register_filebyname("wrapper", f_wrappers);
- Swig_register_filebyname("init", f_init);
- Swig_register_filebyname("initbeforefunc", f_initbeforefunc);
- Swig_register_filebyname("director", f_directors);
- Swig_register_filebyname("director_h", f_directors_h);
-
- Swig_banner(f_begin);
-
- Swig_obligatory_macros(f_runtime, "OCTAVE");
-
- Printf(f_runtime, "#define SWIG_name_d \"%s\"\n", module);
- Printf(f_runtime, "#define SWIG_name %s\n", module);
-
- Printf(f_runtime, "\n");
- Printf(f_runtime, "#define SWIG_global_name \"%s\"\n", global_name);
- Printf(f_runtime, "#define SWIG_op_prefix \"%s\"\n", op_prefix);
-
- if (directorsEnabled()) {
- Printf(f_runtime, "#define SWIG_DIRECTORS\n");
- Swig_banner(f_directors_h);
- if (dirprot_mode()) {
- // Printf(f_directors_h, "#include <map>\n");
- // Printf(f_directors_h, "#include <string>\n\n");
- }
- }
-
- Printf(f_runtime, "\n");
-
- Printf(s_global_tab, "\nstatic const struct swig_octave_member swig_globals[] = {\n");
- Printf(f_init, "static bool SWIG_init_user(octave_swig_type* module_ns)\n{\n");
-
- if (!CPlusPlus)
- Printf(f_header,"extern \"C\" {\n");
-
- Language::top(n);
-
- if (!CPlusPlus)
- Printf(f_header,"}\n");
-
- if (Len(docs))
- emit_doc_texinfo();
-
- if (directorsEnabled()) {
- Swig_insert_file("director_common.swg", f_runtime);
- Swig_insert_file("director.swg", f_runtime);
- }
-
- Printf(f_init, "return true;\n}\n");
- Printf(s_global_tab, "{0,0,0,0,0,0}\n};\n");
-
- Printv(f_wrappers, s_global_tab, NIL);
- SwigType_emit_type_table(f_runtime, f_wrappers);
- Dump(f_runtime, f_begin);
- Dump(f_header, f_begin);
- Dump(f_doc, f_begin);
- if (directorsEnabled()) {
- Dump(f_directors_h, f_begin);
- Dump(f_directors, f_begin);
- }
- Dump(f_wrappers, f_begin);
- Dump(f_initbeforefunc, f_begin);
- Wrapper_pretty_print(f_init, f_begin);
-
- Delete(s_global_tab);
- Delete(f_initbeforefunc);
- Delete(f_init);
- Delete(f_wrappers);
- Delete(f_doc);
- Delete(f_header);
- Delete(f_directors);
- Delete(f_directors_h);
- Delete(f_runtime);
- Delete(f_begin);
-
- return SWIG_OK;
- }
-
- String *texinfo_escape(String *_s) {
- const char* s=(const char*)Data(_s);
- while (*s&&(*s=='\t'||*s=='\r'||*s=='\n'||*s==' '))
- ++s;
- String *r = NewString("");
- for (int j=0;s[j];++j) {
- if (s[j] == '\n') {
- Append(r, "\\n\\\n");
- } else if (s[j] == '\r') {
- Append(r, "\\r");
- } else if (s[j] == '\t') {
- Append(r, "\\t");
- } else if (s[j] == '\\') {
- Append(r, "\\\\");
- } else if (s[j] == '\'') {
- Append(r, "\\\'");
- } else if (s[j] == '\"') {
- Append(r, "\\\"");
- } else
- Putc(s[j], r);
- }
- return r;
- }
- void emit_doc_texinfo() {
- for (Iterator it = First(docs); it.key; it = Next(it)) {
- String *wrap_name = it.key;
-
- String *synopsis = Getattr(it.item, "synopsis");
- String *decl_info = Getattr(it.item, "decl_info");
- String *cdecl_info = Getattr(it.item, "cdecl_info");
- String *args_info = Getattr(it.item, "args_info");
-
- String *doc_str = NewString("");
- Printv(doc_str, synopsis, decl_info, cdecl_info, args_info, NIL);
- String *escaped_doc_str = texinfo_escape(doc_str);
-
- if (Len(doc_str)>0) {
- Printf(f_doc,"static const char* %s_texinfo = ",wrap_name);
- Printf(f_doc,"\"-*- texinfo -*-\\n\\\n%s", escaped_doc_str);
- if (Len(decl_info))
- Printf(f_doc,"\\n\\\n@end deftypefn");
- Printf(f_doc,"\";\n");
- }
-
- Delete(escaped_doc_str);
- Delete(doc_str);
- Delete(wrap_name);
- }
- Printf(f_doc,"\n");
- }
- bool is_empty_doc_node(Node* n) {
- if (!n)
- return true;
- String *synopsis = Getattr(n, "synopsis");
- String *decl_info = Getattr(n, "decl_info");
- String *cdecl_info = Getattr(n, "cdecl_info");
- String *args_info = Getattr(n, "args_info");
- return !Len(synopsis) && !Len(decl_info) &&
- !Len(cdecl_info) && !Len(args_info);
- }
- String *texinfo_name(Node* n, const char* defval = "0") {
- String *tname = NewString("");
- String *iname = Getattr(n, "sym:name");
- String *wname = Swig_name_wrapper(iname);
- Node* d = Getattr(docs, wname);
-
- if (is_empty_doc_node(d))
- Printf(tname, defval);
- else
- Printf(tname, "%s_texinfo", wname);
-
- return tname;
- }
- void process_autodoc(Node *n) {
- String *iname = Getattr(n, "sym:name");
- String *name = Getattr(n, "name");
- String *wname = Swig_name_wrapper(iname);
- String *str = Getattr(n, "feature:docstring");
- bool autodoc_enabled = !Cmp(Getattr(n, "feature:autodoc"), "1");
- Node* d = Getattr(docs, wname);
- if (!d) {
- d = NewHash();
- Setattr(d, "synopsis", NewString(""));
- Setattr(d, "decl_info", NewString(""));
- Setattr(d, "cdecl_info", NewString(""));
- Setattr(d, "args_info", NewString(""));
- Setattr(docs, wname, d);
- }
-
- String *synopsis = Getattr(d, "synopsis");
- String *decl_info = Getattr(d, "decl_info");
- // String *cdecl_info = Getattr(d, "cdecl_info");
- String *args_info = Getattr(d, "args_info");
-
- // * couldn't we just emit the docs here?
-
- if (autodoc_enabled) {
- String *decl_str = NewString("");
- String *args_str = NewString("");
- make_autodocParmList(n, decl_str, args_str);
- Append(decl_info, "@deftypefn {Loadable Function} ");
-
- SwigType *type = Getattr(n, "type");
- if (type && Strcmp(type, "void")) {
- Node *nn = classLookup(Getattr(n, "type"));
- String *type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0);
- Append(decl_info, "@var{retval} = ");
- Printf(args_str, "%s@var{retval} is of type %s. ", args_str, type_str);
- Delete(type_str);
- }
-
- Append(decl_info, name);
- Append(decl_info, " (");
- Append(decl_info, decl_str);
- Append(decl_info, ")\n");
- Append(args_info, args_str);
- Delete(decl_str);
- Delete(args_str);
- }
-
- if (str && Len(str) > 0) {
- // strip off {} if necessary
- char *t = Char(str);
- if (*t == '{') {
- Delitem(str, 0);
- Delitem(str, DOH_END);
- }
-
- // emit into synopsis section
- Append(synopsis, str);
- }
- }
-
- virtual int importDirective(Node *n) {
- String *modname = Getattr(n, "module");
- if (modname)
- Printf(f_init, "if (!SWIG_Octave_LoadModule(\"%s\")) return false;\n", modname);
- return Language::importDirective(n);
- }
-
- const char *get_implicitconv_flag(Node *n) {
- int conv = 0;
- if (n && GetFlag(n, "feature:implicitconv")) {
- conv = 1;
- }
- return conv ? "SWIG_POINTER_IMPLICIT_CONV" : "0";
- }
-
- /* -----------------------------------------------------------------------------
- * addMissingParameterNames()
- * For functions that have not had nameless parameters set in the Language class.
- *
- * Inputs:
- * plist - entire parameter list
- * arg_offset - argument number for first parameter
- * Side effects:
- * The "lname" attribute in each parameter in plist will be contain a parameter name
- * ----------------------------------------------------------------------------- */
-
- void addMissingParameterNames(Node* n, ParmList *plist, int arg_offset) {
- Parm *p = plist;
- int i = arg_offset;
- while (p) {
- if (!Getattr(p, "lname")) {
- String *name = makeParameterName(n, p, i);
- Setattr(p, "lname", name);
- Delete(name);
- }
- i++;
- p = nextSibling(p);
- }
- }
-
- void make_autodocParmList(Node *n, String *decl_str, String *args_str) {
- String *pdocs = 0;
- ParmList *plist = CopyParmList(Getattr(n, "parms"));
- Parm *p;
- Parm *pnext;
- int arg_num = is_wrapping_class() ? 1 : 0;
-
- addMissingParameterNames(n, plist, arg_num); // for $1_name substitutions done in Swig_typemap_attach_parms
-
- Swig_typemap_attach_parms("in", plist, 0);
- Swig_typemap_attach_parms("doc", plist, 0);
-
- for (p = plist; p; p = pnext, arg_num++) {
-
- String *tm = Getattr(p, "tmap:in");
- if (tm) {
- pnext = Getattr(p, "tmap:in:next");
- if (checkAttribute(p, "tmap:in:numinputs", "0")) {
- continue;
- }
- } else {
- pnext = nextSibling(p);
- }
-
- String *name = 0;
- String *type = 0;
- String *value = 0;
- String *pdoc = Getattr(p, "tmap:doc");
- if (pdoc) {
- name = Getattr(p, "tmap:doc:name");
- type = Getattr(p, "tmap:doc:type");
- value = Getattr(p, "tmap:doc:value");
- }
-
- String *made_name = 0;
- if (!name) {
- name = made_name = makeParameterName(n, p, arg_num);
- }
-
- type = type ? type : Getattr(p, "type");
- value = value ? value : Getattr(p, "value");
-
- if (SwigType_isvarargs(type))
- break;
-
- String *tex_name = NewString("");
- if (name)
- Printf(tex_name, "@var{%s}", name);
- else
- Printf(tex_name, "@var{?}");
-
- if (Len(decl_str))
- Append(decl_str, ", ");
- Append(decl_str, tex_name);
-
- if (value) {
- String *new_value = convertValue(value, Getattr(p, "type"));
- if (new_value) {
- value = new_value;
- } else {
- Node *lookup = Swig_symbol_clookup(value, 0);
- if (lookup)
- value = Getattr(lookup, "sym:name");
- }
- Printf(decl_str, " = %s", value);
- }
-
- Node *nn = classLookup(Getattr(p, "type"));
- String *type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0);
- Printf(args_str, "%s is of type %s. ", tex_name, type_str);
-
- Delete(type_str);
- Delete(tex_name);
- Delete(made_name);
- }
- if (pdocs)
- Setattr(n, "feature:pdocs", pdocs);
- Delete(plist);
- }
-
- /* ------------------------------------------------------------
- * convertValue()
- * Check if string v can be an Octave value literal,
- * (eg. number or string), or translate it to an Octave literal.
- * ------------------------------------------------------------ */
- String *convertValue(String *v, SwigType *t) {
- if (v && Len(v) > 0) {
- char fc = (Char(v))[0];
- if (('0' <= fc && fc <= '9') || '\'' == fc || '"' == fc) {
- /* number or string (or maybe NULL pointer) */
- if (SwigType_ispointer(t) && Strcmp(v, "0") == 0)
- return NewString("None");
- else
- return v;
- }
- if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0)
- return SwigType_ispointer(t) ? NewString("nil") : NewString("0");
- if (Strcmp(v, "true") == 0 || Strcmp(v, "TRUE") == 0)
- return NewString("true");
- if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0)
- return NewString("false");
- }
- return 0;
- }
-
- virtual int functionWrapper(Node *n) {
- Parm *p;
- String *tm;
- int j;
-
- String *nodeType = Getattr(n, "nodeType");
- int constructor = (!Cmp(nodeType, "constructor"));
- int destructor = (!Cmp(nodeType, "destructor"));
- String *storage = Getattr(n, "storage");
-
- bool overloaded = !!Getattr(n, "sym:overloaded");
- bool last_overload = overloaded && !Getattr(n, "sym:nextSibling");
- String *iname = Getattr(n, "sym:name");
- String *wname = Swig_name_wrapper(iname);
- String *overname = Copy(wname);
- SwigType *d = Getattr(n, "type");
- ParmList *l = Getattr(n, "parms");
-
- if (!overloaded && !addSymbol(iname, n))
- return SWIG_ERROR;
-
- if (overloaded)
- Append(overname, Getattr(n, "sym:overname"));
-
- if (!overloaded || last_overload)
- process_autodoc(n);
-
- Wrapper *f = NewWrapper();
- Octave_begin_function(n, f->def, iname, overname, !overloaded);
-
- // Start default try block to execute
- // cleanup code if exception is thrown
- Printf(f->code, "try {\n");
-
- emit_parameter_variables(l, f);
- emit_attach_parmmaps(l, f);
- Setattr(n, "wrap:parms", l);
-
- int num_arguments = emit_num_arguments(l);
- int num_required = emit_num_required(l);
- int varargs = emit_isvarargs(l);
- char source[64];
-
- Printf(f->code, "if (!SWIG_check_num_args(\"%s\",args.length(),%i,%i,%i)) "
- "{\n SWIG_fail;\n }\n", iname, num_arguments, num_required, varargs);
-
- if (constructor && num_arguments == 1 && num_required == 1) {
- if (Cmp(storage, "explicit") == 0) {
- Node *parent = Swig_methodclass(n);
- if (GetFlag(parent, "feature:implicitconv")) {
- String *desc = NewStringf("SWIGTYPE%s", SwigType_manglestr(Getattr(n, "type")));
- Printf(f->code, "if (SWIG_CheckImplicit(%s)) SWIG_fail;\n", desc);
- Delete(desc);
- }
- }
- }
-
- for (j = 0, p = l; j < num_arguments; ++j) {
- while (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- }
-
- SwigType *pt = Getattr(p, "type");
-
- String *tm = Getattr(p, "tmap:in");
- if (tm) {
- if (!tm || checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = nextSibling(p);
- continue;
- }
-
- sprintf(source, "args(%d)", j);
- Setattr(p, "emit:input", source);
-
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
-
- if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
- Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
- } else {
- Replaceall(tm, "$disown", "0");
- }
-
- if (Getattr(p, "tmap:in:implicitconv")) {
- const char *convflag = "0";
- if (!Getattr(p, "hidden")) {
- SwigType *ptype = Getattr(p, "type");
- convflag = get_implicitconv_flag(classLookup(ptype));
- }
- Replaceall(tm, "$implicitconv", convflag);
- Setattr(p, "implicitconv", convflag);
- }
-
- String *getargs = NewString("");
- if (j >= num_required)
- Printf(getargs, "if (%d<args.length()) {\n%s\n}", j, tm);
- else
- Printv(getargs, tm, NIL);
- Printv(f->code, getargs, "\n", NIL);
- Delete(getargs);
-
- p = Getattr(p, "tmap:in:next");
- continue;
- } else {
- Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
- break;
- }
- }
-
- // Check for trailing varargs
- if (varargs) {
- if (p && (tm = Getattr(p, "tmap:in"))) {
- Replaceall(tm, "$input", "varargs");
- Printv(f->code, tm, "\n", NIL);
- }
- }
-
- // Insert constraint checking code
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:check"))) {
- Printv(f->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:check:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- // Insert cleanup code
- String *cleanup = NewString("");
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:freearg"))) {
- if (Getattr(p, "tmap:freearg:implicitconv")) {
- const char *convflag = "0";
- if (!Getattr(p, "hidden")) {
- SwigType *ptype = Getattr(p, "type");
- convflag = get_implicitconv_flag(classLookup(ptype));
- }
- if (strcmp(convflag, "0") == 0) {
- tm = 0;
- }
- }
- if (tm && (Len(tm) != 0)) {
- Printv(cleanup, tm, "\n", NIL);
- }
- p = Getattr(p, "tmap:freearg:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- // Insert argument output code
- String *outarg = NewString("");
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:argout"))) {
- Replaceall(tm, "$result", "_outp");
- Replaceall(tm, "$arg", Getattr(p, "emit:input"));
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(outarg, tm, "\n", NIL);
- p = Getattr(p, "tmap:argout:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- int director_method = is_member_director(n) && !is_smart_pointer() && !destructor;
- if (director_method) {
- Wrapper_add_local(f, "upcall", "bool upcall = false");
- Append(f->code, "upcall = !!dynamic_cast<Swig::Director*>(arg1);\n");
- }
-
- Setattr(n, "wrap:name", overname);
-
- Swig_director_emit_dynamic_cast(n, f);
- String *actioncode = emit_action(n);
-
- Wrapper_add_local(f, "_out", "octave_value_list _out");
- Wrapper_add_local(f, "_outp", "octave_value_list *_outp=&_out");
- Wrapper_add_local(f, "_outv", "octave_value _outv");
-
- // Return the function value
- if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
- Replaceall(tm, "$result", "_outv");
-
- if (GetFlag(n, "feature:new"))
- Replaceall(tm, "$owner", "1");
- else
- Replaceall(tm, "$owner", "0");
-
- Printf(f->code, "%s\n", tm);
- Printf(f->code, "if (_outv.is_defined()) _outp = " "SWIG_Octave_AppendOutput(_outp, _outv);\n");
- Delete(tm);
- } else {
- Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), iname);
- }
- emit_return_variable(n, d, f);
-
- Printv(f->code, outarg, NIL);
- Printv(f->code, cleanup, NIL);
-
- if (GetFlag(n, "feature:new")) {
- if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
- Printf(f->code, "%s\n", tm);
- }
- }
-
- if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
- Replaceall(tm, "$result", "_outv");
- Printf(f->code, "%s\n", tm);
- Delete(tm);
- }
-
- Printf(f->code, "return _out;\n");
-
- // Execute cleanup code if branched to fail: label
- Printf(f->code, "fail:\n");
- Printv(f->code, cleanup, NIL);
- Printf(f->code, "return octave_value_list();\n");
-
- // Execute cleanup code if exception was thrown
- Printf(f->code, "}\n");
- Printf(f->code, "catch(...) {\n");
- Printv(f->code, cleanup, NIL);
- Printf(f->code, "throw;\n");
- Printf(f->code, "}\n");
-
- // End wrapper function
- Printf(f->code, "}\n");
-
- /* Substitute the cleanup code */
- Replaceall(f->code, "$cleanup", cleanup);
-
- Replaceall(f->code, "$symname", iname);
- Wrapper_print(f, f_wrappers);
- DelWrapper(f);
-
- if (last_overload)
- dispatchFunction(n);
-
- if (!overloaded || last_overload) {
- String *tname = texinfo_name(n);
- Printf(s_global_tab, "{\"%s\",%s,0,0,2,%s},\n", iname, wname, tname);
- Delete(tname);
- }
-
- Delete(overname);
- Delete(wname);
- Delete(cleanup);
- Delete(outarg);
-
- return SWIG_OK;
- }
-
- void dispatchFunction(Node *n) {
- Wrapper *f = NewWrapper();
-
- String *iname = Getattr(n, "sym:name");
- String *wname = Swig_name_wrapper(iname);
- int maxargs;
- String *dispatch = Swig_overload_dispatch(n, "return %s(args, nargout);", &maxargs);
- String *tmp = NewString("");
-
- Octave_begin_function(n, f->def, iname, wname, true);
- Wrapper_add_local(f, "argc", "int argc = args.length()");
- Printf(tmp, "octave_value_ref argv[%d]={", maxargs);
- for (int j = 0; j < maxargs; ++j)
- Printf(tmp, "%soctave_value_ref(args,%d)", j ? "," : " ", j);
- Printf(tmp, "}");
- Wrapper_add_local(f, "argv", tmp);
- Printv(f->code, dispatch, "\n", NIL);
- Printf(f->code, "error(\"No matching function for overload\");\n");
- Printf(f->code, "return octave_value_list();\n");
- Printv(f->code, "}\n", NIL);
-
- Wrapper_print(f, f_wrappers);
- Delete(tmp);
- DelWrapper(f);
- Delete(dispatch);
- Delete(wname);
- }
-
- virtual int variableWrapper(Node *n) {
- String *name = Getattr(n, "name");
- String *iname = Getattr(n, "sym:name");
- SwigType *t = Getattr(n, "type");
-
- if (!addSymbol(iname, n))
- return SWIG_ERROR;
-
- String *tm;
- Wrapper *getf = NewWrapper();
- Wrapper *setf = NewWrapper();
-
- String *getname = Swig_name_get(NSPACE_TODO, iname);
- String *setname = Swig_name_set(NSPACE_TODO, iname);
-
- String *getwname = Swig_name_wrapper(getname);
- String *setwname = Swig_name_wrapper(setname);
-
- Octave_begin_function(n, setf->def, setname, setwname, true);
- Printf(setf->code, "if (!SWIG_check_num_args(\"%s_set\",args.length(),1,1,0)) return octave_value_list();\n", iname);
- if (is_assignable(n)) {
- Setattr(n, "wrap:name", setname);
- if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
- Replaceall(tm, "$input", "args(0)");
- if (Getattr(n, "tmap:varin:implicitconv")) {
- Replaceall(tm, "$implicitconv", get_implicitconv_flag(n));
- }
- emit_action_code(n, setf->code, tm);
- Delete(tm);
- } else {
- Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
- }
- Append(setf->code, "return octave_value_list();\n");
- Append(setf->code, "fail:\n");
- Append(setf->code, "return octave_value_list();\n");
- } else {
- Printf(setf->code, "return octave_set_immutable(args,nargout);");
- }
- Append(setf->code, "}\n");
- Wrapper_print(setf, f_wrappers);
-
- Setattr(n, "wrap:name", getname);
- int addfail = 0;
- Octave_begin_function(n, getf->def, getname, getwname, true);
- Wrapper_add_local(getf, "obj", "octave_value obj");
- if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
- Replaceall(tm, "$result", "obj");
- addfail = emit_action_code(n, getf->code, tm);
- Delete(tm);
- } else {
- Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
- }
- Append(getf->code, "return obj;\n");
- if (addfail) {
- Append(getf->code, "fail:\n");
- Append(getf->code, "return octave_value_list();\n");
- }
- Append(getf->code, "}\n");
- Wrapper_print(getf, f_wrappers);
-
- Printf(s_global_tab, "{\"%s\",0,%s,%s,2,0},\n", iname, getwname, setwname);
-
- Delete(getwname);
- Delete(setwname);
- DelWrapper(setf);
- DelWrapper(getf);
-
- return SWIG_OK;
- }
-
- virtual int constantWrapper(Node *n) {
- String *name = Getattr(n, "name");
- String *iname = Getattr(n, "sym:name");
- SwigType *type = Getattr(n, "type");
- String *rawval = Getattr(n, "rawval");
- String *value = rawval ? rawval : Getattr(n, "value");
- String *cppvalue = Getattr(n, "cppvalue");
- String *tm;
-
- if (!addSymbol(iname, n))
- return SWIG_ERROR;
-
- if (SwigType_type(type) == T_MPOINTER) {
- String *wname = Swig_name_wrapper(iname);
- String *str = SwigType_str(type, wname);
- Printf(f_header, "static %s = %s;\n", str, value);
- Delete(str);
- value = wname;
- }
- if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
- Replaceall(tm, "$value", cppvalue ? cppvalue : value);
- Replaceall(tm, "$nsname", iname);
- Printf(f_init, "%s\n", tm);
- } else {
- Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n");
- return SWIG_NOWRAP;
- }
-
- return SWIG_OK;
- }
-
- virtual int nativeWrapper(Node *n) {
- return Language::nativeWrapper(n);
- }
-
- virtual int enumDeclaration(Node *n) {
- return Language::enumDeclaration(n);
- }
-
- virtual int enumvalueDeclaration(Node *n) {
- return Language::enumvalueDeclaration(n);
- }
-
- virtual int classDeclaration(Node *n) {
- return Language::classDeclaration(n);
- }
-
- virtual int classHandler(Node *n) {
- have_constructor = 0;
- have_destructor = 0;
- constructor_name = 0;
-
- class_name = Getattr(n, "sym:name");
-
- if (!addSymbol(class_name, n))
- return SWIG_ERROR;
-
- // This is a bug, due to the fact that swig_type -> octave_class mapping
- // is 1-to-n.
- static Hash *emitted = NewHash();
- String *mangled_classname = Swig_name_mangle(Getattr(n, "name"));
- if (Getattr(emitted, mangled_classname)) {
- Delete(mangled_classname);
- return SWIG_NOWRAP;
- }
- Setattr(emitted, mangled_classname, "1");
- Delete(mangled_classname);
-
- assert(!s_members_tab);
- s_members_tab = NewString("");
- Printv(s_members_tab, "static swig_octave_member swig_", class_name, "_members[] = {\n", NIL);
-
- Language::classHandler(n);
-
- SwigType *t = Copy(Getattr(n, "name"));
- SwigType_add_pointer(t);
-
- // Replace storing a pointer to underlying class with a smart pointer (intended for use with non-intrusive smart pointers)
- SwigType *smart = Swig_cparse_smartptr(n);
- String *wrap_class = NewStringf("&_wrap_class_%s", class_name);
- if (smart) {
- SwigType_add_pointer(smart);
- SwigType_remember_clientdata(smart, wrap_class);
- }
- //String *wrap_class = NewStringf("&_wrap_class_%s", class_name);
- SwigType_remember_clientdata(t, wrap_class);
-
- int use_director = Swig_directorclass(n);
- if (use_director) {
- String *nspace = Getattr(n, "sym:nspace");
- String *cname = Swig_name_disown(nspace, class_name);
- String *wcname = Swig_name_wrapper(cname);
- String *cnameshdw = NewStringf("%s_shadow", cname);
- String *wcnameshdw = Swig_name_wrapper(cnameshdw);
- Octave_begin_function(n, f_wrappers, cnameshdw, wcnameshdw, true);
- Printf(f_wrappers, " if (args.length()!=1) {\n");
- Printf(f_wrappers, " error(\"disown takes no arguments\");\n");
- Printf(f_wrappers, " return octave_value_list();\n");
- Printf(f_wrappers, " }\n");
- Printf(f_wrappers, " %s (args, nargout);\n", wcname);
- Printf(f_wrappers, " return args;\n");
- Printf(f_wrappers, "}\n");
- Printf(s_members_tab, "{\"__disown\",%s,0,0,0,0},\n", wcnameshdw);
- Delete(wcname);
- Delete(cname);
- Delete(wcnameshdw);
- Delete(cnameshdw);
- }
-
- Printf(s_members_tab, "{0,0,0,0,0,0}\n};\n");
- Printv(f_wrappers, s_members_tab, NIL);
-
- String *base_class_names = NewString("");
- String *base_class = NewString("");
- List *baselist = Getattr(n, "bases");
- if (baselist && Len(baselist)) {
- Iterator b;
- b = First(baselist);
- while (b.item) {
- String *bname = Getattr(b.item, "name");
- if ((!bname) || GetFlag(b.item, "feature:ignore") || (!Getattr(b.item, "module"))) {
- b = Next(b);
- continue;
- }
-
- String *bname_mangled = SwigType_manglestr(SwigType_add_pointer(Copy(bname)));
- Printf(base_class_names, "\"%s\",", bname_mangled);
- Printf(base_class, "0,");
- b = Next(b);
- Delete(bname_mangled);
- }
- }
-
- Printv(f_wrappers, "static const char *swig_", class_name, "_base_names[] = {", base_class_names, "0};\n", NIL);
- Printv(f_wrappers, "static const swig_type_info *swig_", class_name, "_base[] = {", base_class, "0};\n", NIL);
- Printv(f_wrappers, "static swig_octave_class _wrap_class_", class_name, " = {\"", class_name, "\", &SWIGTYPE", SwigType_manglestr(t), ",", NIL);
- Printv(f_wrappers, Swig_directorclass(n) ? "1," : "0,", NIL);
- if (have_constructor) {
- String *nspace = Getattr(n, "sym:nspace");
- String *cname = Swig_name_construct(nspace, constructor_name);
- String *wcname = Swig_name_wrapper(cname);
- String *tname = texinfo_name(n);
- Printf(f_wrappers, "%s,%s,", wcname, tname);
- Delete(tname);
- Delete(wcname);
- Delete(cname);
- } else
- Printv(f_wrappers, "0,0,", NIL);
- if (have_destructor) {
- String *nspace = Getattr(n, "sym:nspace");
- String *cname = Swig_name_destroy(nspace, class_name);
- String *wcname = Swig_name_wrapper(cname);
- Printf(f_wrappers, "%s,", wcname);
- Delete(wcname);
- Delete(cname);
- } else
- Printv(f_wrappers, "0", ",", NIL);
- Printf(f_wrappers, "swig_%s_members,swig_%s_base_names,swig_%s_base };\n\n", class_name, class_name, class_name);
-
- Delete(base_class);
- Delete(base_class_names);
- Delete(smart);
- Delete(t);
- Delete(s_members_tab);
- s_members_tab = 0;
- class_name = 0;
-
- return SWIG_OK;
- }
-
- virtual int memberfunctionHandler(Node *n) {
- Language::memberfunctionHandler(n);
-
- assert(s_members_tab);
- assert(class_name);
- String *name = Getattr(n, "name");
- String *iname = GetChar(n, "sym:name");
- String *realname = iname ? iname : name;
- String *wname = Getattr(n, "wrap:name");
- assert(wname);
-
- if (!Getattr(n, "sym:nextSibling")) {
- String *tname = texinfo_name(n);
- String *rname = Copy(wname);
- bool overloaded = !!Getattr(n, "sym:overloaded");
- if (overloaded)
- Delslice(rname, Len(rname) - Len(Getattr(n, "sym:overname")), DOH_END);
- Printf(s_members_tab, "{\"%s\",%s,0,0,0,%s},\n",
- realname, rname, tname);
- Delete(rname);
- Delete(tname);
- }
-
- return SWIG_OK;
- }
-
- virtual int membervariableHandler(Node *n) {
- Setattr(n, "feature:autodoc", "0");
-
- Language::membervariableHandler(n);
-
- assert(s_members_tab);
- assert(class_name);
- String *symname = Getattr(n, "sym:name");
- String *getname = Swig_name_get(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname));
- String *setname = Swig_name_set(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname));
- String *getwname = Swig_name_wrapper(getname);
- String *setwname = GetFlag(n, "feature:immutable") ? NewString("octave_set_immutable") : Swig_name_wrapper(setname);
- assert(s_members_tab);
-
- Printf(s_members_tab, "{\"%s\",0,%s,%s,0,0},\n", symname, getwname, setwname);
-
- Delete(getname);
- Delete(setname);
- Delete(getwname);
- Delete(setwname);
- return SWIG_OK;
- }
-
- virtual int constructorHandler(Node *n) {
- have_constructor = 1;
- if (!constructor_name)
- constructor_name = NewString(Getattr(n, "sym:name"));
-
- int use_director = Swig_directorclass(n);
- if (use_director) {
- Parm *parms = Getattr(n, "parms");
- Parm *self;
- String *name = NewString("self");
- String *type = NewString("void");
- SwigType_add_pointer(type);
- self = NewParm(type, name, n);
- Delete(type);
- Delete(name);
- Setattr(self, "lname", "self_obj");
- if (parms)
- set_nextSibling(self, parms);
- Setattr(n, "parms", self);
- Setattr(n, "wrap:self", "1");
- Setattr(n, "hidden", "1");
- Delete(self);
- }
-
- return Language::constructorHandler(n);
- }
-
- virtual int destructorHandler(Node *n) {
- have_destructor = 1;
- return Language::destructorHandler(n);
- }
-
- virtual int staticmemberfunctionHandler(Node *n) {
- Language::staticmemberfunctionHandler(n);
-
- assert(s_members_tab);
- assert(class_name);
- String *name = Getattr(n, "name");
- String *iname = GetChar(n, "sym:name");
- String *realname = iname ? iname : name;
- String *wname = Getattr(n, "wrap:name");
- assert(wname);
-
- if (!Getattr(n, "sym:nextSibling")) {
- String *tname = texinfo_name(n);
- String *rname = Copy(wname);
- bool overloaded = !!Getattr(n, "sym:overloaded");
- if (overloaded)
- Delslice(rname, Len(rname) - Len(Getattr(n, "sym:overname")), DOH_END);
- Printf(s_members_tab, "{\"%s\",%s,0,0,1,%s},\n",
- realname, rname, tname);
- Delete(rname);
- Delete(tname);
- }
-
- return SWIG_OK;
- }
-
- virtual int memberconstantHandler(Node *n) {
- return Language::memberconstantHandler(n);
- }
-
- virtual int staticmembervariableHandler(Node *n) {
- Setattr(n, "feature:autodoc", "0");
-
- Language::staticmembervariableHandler(n);
-
- if (!GetFlag(n, "wrappedasconstant")) {
- assert(s_members_tab);
- assert(class_name);
- String *symname = Getattr(n, "sym:name");
- String *getname = Swig_name_get(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname));
- String *setname = Swig_name_set(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname));
- String *getwname = Swig_name_wrapper(getname);
- String *setwname = GetFlag(n, "feature:immutable") ? NewString("octave_set_immutable") : Swig_name_wrapper(setname);
- assert(s_members_tab);
-
- Printf(s_members_tab, "{\"%s\",0,%s,%s,1,0},\n", symname, getwname, setwname);
-
- Delete(getname);
- Delete(setname);
- Delete(getwname);
- Delete(setwname);
- }
- return SWIG_OK;
- }
-
- int classDirectorInit(Node *n) {
- String *declaration = Swig_director_declaration(n);
- Printf(f_directors_h, "\n");
- Printf(f_directors_h, "%s\n", declaration);
- Printf(f_directors_h, "public:\n");
- Delete(declaration);
- return Language::classDirectorInit(n);
- }
-
- int classDirectorEnd(Node *n) {
- Printf(f_directors_h, "};\n\n");
- return Language::classDirectorEnd(n);
- }
-
- int classDirectorConstructor(Node *n) {
- Node *parent = Getattr(n, "parentNode");
- String *sub = NewString("");
- String *decl = Getattr(n, "decl");
- String *supername = Swig_class_name(parent);
- String *classname = NewString("");
- Printf(classname, "SwigDirector_%s", supername);
-
- // insert self parameter
- Parm *p;
- ParmList *superparms = Getattr(n, "parms");
- ParmList *parms = CopyParmList(superparms);
- String *type = NewString("void");
- SwigType_add_pointer(type);
- p = NewParm(type, NewString("self"), n);
- set_nextSibling(p, parms);
- parms = p;
-
- if (!Getattr(n, "defaultargs")) {
- // constructor
- {
- Wrapper *w = NewWrapper();
- String *call;
- String *basetype = Getattr(parent, "classtype");
- String *target = Swig_method_decl(0, decl, classname, parms, 0);
- call = Swig_csuperclass_call(0, basetype, superparms);
- Printf(w->def, "%s::%s: %s," "\nSwig::Director(static_cast<%s*>(this)) { \n", classname, target, call, basetype);
- Append(w->def, "}\n");
- Delete(target);
- Wrapper_print(w, f_directors);
- Delete(call);
- DelWrapper(w);
- }
-
- // constructor header
- {
- String *target = Swig_method_decl(0, decl, classname, parms, 1);
- Printf(f_directors_h, " %s;\n", target);
- Delete(target);
- }
- }
-
- Delete(sub);
- Delete(classname);
- Delete(supername);
- Delete(parms);
- return Language::classDirectorConstructor(n);
- }
-
- int classDirectorDefaultConstructor(Node *n) {
- String *classname = Swig_class_name(n);
- {
- Wrapper *w = NewWrapper();
- Printf(w->def, "SwigDirector_%s::SwigDirector_%s(void* self) :"
- "\nSwig::Director((octave_swig_type*)self,static_cast<%s*>(this)) { \n", classname, classname, classname);
- Append(w->def, "}\n");
- Wrapper_print(w, f_directors);
- DelWrapper(w);
- }
- Printf(f_directors_h, " SwigDirector_%s(octave_swig_type* self);\n", classname);
- Delete(classname);
- return Language::classDirectorDefaultConstructor(n);
- }
-
- int classDirectorMethod(Node *n, Node *parent, String *super) {
- int is_void = 0;
- int is_pointer = 0;
- String *decl = Getattr(n, "decl");
- String *returntype = Getattr(n, "type");
- String *name = Getattr(n, "name");
- String *classname = Getattr(parent, "sym:name");
- String *c_classname = Getattr(parent, "name");
- String *symname = Getattr(n, "sym:name");
- String *declaration = NewString("");
- ParmList *l = Getattr(n, "parms");
- Wrapper *w = NewWrapper();
- String *tm;
- String *wrap_args = NewString("");
- String *value = Getattr(n, "value");
- String *storage = Getattr(n, "storage");
- bool pure_virtual = false;
- int status = SWIG_OK;
- int idx;
- bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
-
- if (Cmp(storage, "virtual") == 0) {
- if (Cmp(value, "0") == 0) {
- pure_virtual = true;
- }
- }
-
- // determine if the method returns a pointer
- is_pointer = SwigType_ispointer_return(decl);
- is_void = (!Cmp(returntype, "void") && !is_pointer);
-
- // virtual method definition
- String *target;
- String *pclassname = NewStringf("SwigDirector_%s", classname);
- String *qualified_name = NewStringf("%s::%s", pclassname, name);
- SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
- target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
- Printf(w->def, "%s", target);
- Delete(qualified_name);
- Delete(target);
-
- // header declaration
- target = Swig_method_decl(rtype, decl, name, l, 1);
- Printf(declaration, " virtual %s", target);
- Delete(target);
-
- // Get any exception classes in the throws typemap
- if (Getattr(n, "noexcept")) {
- Append(w->def, " noexcept");
- Append(declaration, " noexcept");
- }
- ParmList *throw_parm_list = 0;
-
- if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
- Parm *p;
- int gencomma = 0;
-
- Append(w->def, " throw(");
- Append(declaration, " throw(");
-
- if (throw_parm_list)
- Swig_typemap_attach_parms("throws", throw_parm_list, 0);
- for (p = throw_parm_list; p; p = nextSibling(p)) {
- if (Getattr(p, "tmap:throws")) {
- if (gencomma++) {
- Append(w->def, ", ");
- Append(declaration, ", ");
- }
- String *str = SwigType_str(Getattr(p, "type"), 0);
- Append(w->def, str);
- Append(declaration, str);
- Delete(str);
- }
- }
-
- Append(w->def, ")");
- Append(declaration, ")");
- }
-
- Append(w->def, " {");
- Append(declaration, ";\n");
-
- // declare method return value
- // if the return value is a reference or const reference, a specialized typemap must
- // handle it, including declaration of c_result ($result).
- if (!is_void && (!ignored_method || pure_virtual)) {
- if (!SwigType_isclass(returntype)) {
- if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
- String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
- Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL);
- Delete(construct_result);
- } else {
- Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL);
- }
- } else {
- String *cres = SwigType_lstr(returntype, "c_result");
- Printf(w->code, "%s;\n", cres);
- Delete(cres);
- }
- }
-
- if (ignored_method) {
- if (!pure_virtual) {
- if (!is_void)
- Printf(w->code, "return ");
- String *super_call = Swig_method_call(super, l);
- Printf(w->code, "%s;\n", super_call);
- Delete(super_call);
- } else {
- Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
- SwigType_namestr(name));
- }
- } else {
- // attach typemaps to arguments (C/C++ -> Octave)
- String *parse_args = NewString("");
-
- Swig_director_parms_fixup(l);
-
- Swig_typemap_attach_parms("in", l, 0);
- Swig_typemap_attach_parms("directorin", l, w);
- Swig_typemap_attach_parms("directorargout", l, w);
-
- Parm *p;
-
- int outputs = 0;
- if (!is_void)
- outputs++;
-
- // build argument list and type conversion string
- p = l;
- while (p) {
- if (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- continue;
- }
-
- if (Getattr(p, "tmap:directorargout") != 0)
- outputs++;
-
- String *pname = Getattr(p, "name");
- String *ptype = Getattr(p, "type");
- Wrapper_add_local(w, "tmpv", "octave_value tmpv");
-
- if ((tm = Getattr(p, "tmap:directorin")) != 0) {
- String *parse = Getattr(p, "tmap:directorin:parse");
- if (!parse) {
- Setattr(p, "emit:directorinput", "tmpv");
- Replaceall(tm, "$input", "tmpv");
- Replaceall(tm, "$owner", "0");
- Printv(wrap_args, tm, "\n", NIL);
- Printf(wrap_args, "args.append(tmpv);\n");
- Putc('O', parse_args);
- } else {
- Append(parse_args, parse);
- Setattr(p, "emit:directorinput", pname);
- Replaceall(tm, "$input", pname);
- Replaceall(tm, "$owner", "0");
- if (Len(tm) == 0)
- Append(tm, pname);
- }
- p = Getattr(p, "tmap:directorin:next");
- continue;
- } else if (Cmp(ptype, "void")) {
- Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
- "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0),
- SwigType_namestr(c_classname), SwigType_namestr(name));
- status = SWIG_NOWRAP;
- break;
- }
- p = nextSibling(p);
- }
-
- String *method_name = Getattr(n, "sym:name");
-
- Printv(w->code, wrap_args, NIL);
-
- // emit method invocation
- Wrapper_add_local(w, "args", "octave_value_list args");
- Wrapper_add_local(w, "out", "octave_value_list out");
- Wrapper_add_local(w, "idx", "std::list<octave_value_list> idx");
- Printf(w->code, "idx.push_back(octave_value_list(\"%s\"));\n", method_name);
- Printf(w->code, "idx.push_back(args);\n");
- Printf(w->code, "out=swig_get_self()->subsref(\".(\",idx,%d);\n", outputs);
-
- String *cleanup = NewString("");
- String *outarg = NewString("");
- idx = 0;
-
- // marshal return value
- if (!is_void) {
- Printf(w->code, "if (out.length()<%d) {\n", outputs);
- Printf(w->code, "Swig::DirectorTypeMismatchException::raise(\"Octave "
- "method %s.%s failed to return the required number " "of arguments.\");\n", classname, method_name);
- Printf(w->code, "}\n");
-
- tm = Swig_typemap_lookup("directorout", n, Swig_cresult_name(), w);
- if (tm != 0) {
- char temp[24];
- sprintf(temp, "out(%d)", idx);
- Replaceall(tm, "$input", temp);
- // Replaceall(tm, "$argnum", temp);
- Replaceall(tm, "$disown", Getattr(n, "wrap:disown") ? "SWIG_POINTER_DISOWN" : "0");
- if (Getattr(n, "tmap:directorout:implicitconv")) {
- Replaceall(tm, "$implicitconv", get_implicitconv_flag(n));
- }
- Replaceall(tm, "$result", "c_result");
- Printv(w->code, tm, "\n", NIL);
- Delete(tm);
- } else {
- Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
- "Unable to use return type %s in director method %s::%s (skipping method).\n",
- SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
- status = SWIG_ERROR;
- }
- }
- idx++;
-
- // marshal outputs
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
- char temp[24];
- sprintf(temp, "out(%d)", idx);
- Replaceall(tm, "$result", temp);
- Replaceall(tm, "$input", Getattr(p, "emit:directorinput"));
- Printv(w->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:directorargout:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- Delete(parse_args);
- Delete(cleanup);
- Delete(outarg);
- }
-
- if (!is_void) {
- if (!(ignored_method && !pure_virtual)) {
- String *rettype = SwigType_str(returntype, 0);
- if (!SwigType_isreference(returntype)) {
- Printf(w->code, "return (%s) c_result;\n", rettype);
- } else {
- Printf(w->code, "return (%s) *c_result;\n", rettype);
- }
- Delete(rettype);
- }
- }
-
- Append(w->code, "}\n");
-
- // We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
- String *inline_extra_method = NewString("");
- if (dirprot_mode() && !is_public(n) && !pure_virtual) {
- Printv(inline_extra_method, declaration, NIL);
- String *extra_method_name = NewStringf("%sSwigPublic", name);
- Replaceall(inline_extra_method, name, extra_method_name);
- Replaceall(inline_extra_method, ";\n", " {\n ");
- if (!is_void)
- Printf(inline_extra_method, "return ");
- String *methodcall = Swig_method_call(super, l);
- Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
- Delete(methodcall);
- Delete(extra_method_name);
- }
- // emit the director method
- if (status == SWIG_OK) {
- if (!Getattr(n, "defaultargs")) {
- Replaceall(w->code, "$symname", symname);
- Wrapper_print(w, f_directors);
- Printv(f_directors_h, declaration, NIL);
- Printv(f_directors_h, inline_extra_method, NIL);
- }
- }
- // clean up
- Delete(wrap_args);
- Delete(pclassname);
- DelWrapper(w);
- return status;
- }
-
- String *runtimeCode() {
- String *s = NewString("");
- String *srun = Swig_include_sys("octrun.swg");
- if (!srun) {
- Printf(stderr, "*** Unable to open 'octrun.swg'\n");
- } else {
- Append(s, srun);
- Delete(srun);
- }
- return s;
- }
-
- String *defaultExternalRuntimeFilename() {
- return NewString("swigoctaverun.h");
- }
-};
-
-extern "C" Language *swig_octave(void) {
- return new OCTAVE();
-}
diff --git a/contrib/tools/swig/Source/Modules/overload.cxx b/contrib/tools/swig/Source/Modules/overload.cxx
deleted file mode 100644
index b94e87ebb7..0000000000
--- a/contrib/tools/swig/Source/Modules/overload.cxx
+++ /dev/null
@@ -1,866 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * overload.cxx
- *
- * This file is used to analyze overloaded functions and methods.
- * It looks at signatures and tries to gather information for
- * building a dispatch function.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-
-#define MAX_OVERLOAD 4096
-
-/* Overload "argc" and "argv" */
-String *argv_template_string;
-String *argc_template_string;
-
-namespace {
-struct Overloaded {
- Node *n; /* Node */
- int argc; /* Argument count */
- ParmList *parms; /* Parameters used for overload check */
- int error; /* Ambiguity error */
- bool implicitconv_function; /* For ordering implicitconv functions*/
-};
-}
-
-static int fast_dispatch_mode = 0;
-static int cast_dispatch_mode = 0;
-
-/* Set fast_dispatch_mode */
-void Wrapper_fast_dispatch_mode_set(int flag) {
- fast_dispatch_mode = flag;
-}
-
-void Wrapper_cast_dispatch_mode_set(int flag) {
- cast_dispatch_mode = flag;
-}
-
-/* -----------------------------------------------------------------------------
- * mark_implicitconv_function()
- *
- * Mark function if it contains an implicitconv type in the parameter list
- * ----------------------------------------------------------------------------- */
-static void mark_implicitconv_function(Overloaded& onode) {
- Parm *parms = onode.parms;
- if (parms) {
- bool is_implicitconv_function = false;
- Parm *p = parms;
- while (p) {
- if (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- continue;
- }
- if (GetFlag(p, "implicitconv")) {
- is_implicitconv_function = true;
- break;
- }
- p = nextSibling(p);
- }
- if (is_implicitconv_function)
- onode.implicitconv_function = true;
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_overload_rank()
- *
- * This function takes an overloaded declaration and creates a list that ranks
- * all overloaded methods in an order that can be used to generate a dispatch
- * function.
- * Slight difference in the way this function is used by scripting languages and
- * statically typed languages. The script languages call this method via
- * Swig_overload_dispatch() - where wrappers for all overloaded methods are generated,
- * however sometimes the code can never be executed. The non-scripting languages
- * call this method via Swig_overload_check() for each overloaded method in order
- * to determine whether or not the method should be wrapped. Note the slight
- * difference when overloading methods that differ by const only. The
- * scripting languages will ignore the const method, whereas the non-scripting
- * languages ignore the first method parsed.
- * ----------------------------------------------------------------------------- */
-
-List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
- Overloaded nodes[MAX_OVERLOAD];
- int nnodes = 0;
- Node *o = Getattr(n, "sym:overloaded");
- Node *c;
-
- if (!o)
- return 0;
-
- c = o;
- while (c) {
- if (Getattr(c, "error")) {
- c = Getattr(c, "sym:nextSibling");
- continue;
- }
- /* if (SmartPointer && Getattr(c,"cplus:staticbase")) {
- c = Getattr(c,"sym:nextSibling");
- continue;
- } */
-
- /* Make a list of all the declarations (methods) that are overloaded with
- * this one particular method name */
- if (Getattr(c, "wrap:name")) {
- assert(nnodes < MAX_OVERLOAD);
- nodes[nnodes].n = c;
- nodes[nnodes].parms = Getattr(c, "wrap:parms");
- nodes[nnodes].argc = emit_num_required(nodes[nnodes].parms);
- nodes[nnodes].error = 0;
- nodes[nnodes].implicitconv_function = false;
-
- mark_implicitconv_function(nodes[nnodes]);
- nnodes++;
- }
- c = Getattr(c, "sym:nextSibling");
- }
-
- /* Sort the declarations by required argument count */
- {
- int i, j;
- for (i = 0; i < nnodes; i++) {
- for (j = i + 1; j < nnodes; j++) {
- if (nodes[i].argc > nodes[j].argc) {
- Overloaded t = nodes[i];
- nodes[i] = nodes[j];
- nodes[j] = t;
- }
- }
- }
- }
-
- /* Sort the declarations by argument types */
- {
- int i, j;
- for (i = 0; i < nnodes - 1; i++) {
- if (nodes[i].argc == nodes[i + 1].argc) {
- for (j = i + 1; (j < nnodes) && (nodes[j].argc == nodes[i].argc); j++) {
- Parm *p1 = nodes[i].parms;
- Parm *p2 = nodes[j].parms;
- int differ = 0;
- int num_checked = 0;
- while (p1 && p2 && (num_checked < nodes[i].argc)) {
- // Printf(stdout,"p1 = '%s', p2 = '%s'\n", Getattr(p1,"type"), Getattr(p2,"type"));
- if (checkAttribute(p1, "tmap:in:numinputs", "0")) {
- p1 = Getattr(p1, "tmap:in:next");
- continue;
- }
- if (checkAttribute(p2, "tmap:in:numinputs", "0")) {
- p2 = Getattr(p2, "tmap:in:next");
- continue;
- }
- String *t1 = Getattr(p1, "tmap:typecheck:precedence");
- String *t2 = Getattr(p2, "tmap:typecheck:precedence");
- if ((!t1) && (!nodes[i].error)) {
- Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[i].n), Getline(nodes[i].n),
- "Overloaded method %s not supported (incomplete type checking rule - no precedence level in typecheck typemap for '%s').\n",
- Swig_name_decl(nodes[i].n), SwigType_str(Getattr(p1, "type"), 0));
- nodes[i].error = 1;
- } else if ((!t2) && (!nodes[j].error)) {
- Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[j].n), Getline(nodes[j].n),
- "Overloaded method %s not supported (incomplete type checking rule - no precedence level in typecheck typemap for '%s').\n",
- Swig_name_decl(nodes[j].n), SwigType_str(Getattr(p2, "type"), 0));
- nodes[j].error = 1;
- }
- if (t1 && t2) {
- int t1v, t2v;
- t1v = atoi(Char(t1));
- t2v = atoi(Char(t2));
- differ = t1v - t2v;
- } else if (!t1 && t2)
- differ = 1;
- else if (t1 && !t2)
- differ = -1;
- else if (!t1 && !t2)
- differ = -1;
- num_checked++;
- if (differ > 0) {
- Overloaded t = nodes[i];
- nodes[i] = nodes[j];
- nodes[j] = t;
- break;
- } else if ((differ == 0) && (Strcmp(t1, "0") == 0)) {
- t1 = Getattr(p1, "equivtype");
- t1 = t1 ? t1 : Getattr(p1, "ltype");
- if (!t1) {
- t1 = SwigType_ltype(Getattr(p1, "type"));
- if (Getattr(p1, "tmap:typecheck:SWIGTYPE")) {
- SwigType_add_pointer(t1);
- }
- Setattr(p1, "ltype", t1);
- }
- t2 = Getattr(p2, "equivtype");
- t2 = t2 ? t2 : Getattr(p2, "ltype");
- if (!t2) {
- t2 = SwigType_ltype(Getattr(p2, "type"));
- if (Getattr(p2, "tmap:typecheck:SWIGTYPE")) {
- SwigType_add_pointer(t2);
- }
- Setattr(p2, "ltype", t2);
- }
-
- /* Need subtype check here. If t2 is a subtype of t1, then we need to change the
- order */
-
- if (SwigType_issubtype(t2, t1)) {
- Overloaded t = nodes[i];
- nodes[i] = nodes[j];
- nodes[j] = t;
- }
-
- if (Strcmp(t1, t2) != 0) {
- differ = 1;
- break;
- }
- } else if (differ) {
- break;
- }
- if (Getattr(p1, "tmap:in:next")) {
- p1 = Getattr(p1, "tmap:in:next");
- } else {
- p1 = nextSibling(p1);
- }
- if (Getattr(p2, "tmap:in:next")) {
- p2 = Getattr(p2, "tmap:in:next");
- } else {
- p2 = nextSibling(p2);
- }
- }
- if (!differ) {
- /* See if declarations differ by const only */
- String *decl1 = Getattr(nodes[i].n, "decl");
- String *decl2 = Getattr(nodes[j].n, "decl");
- if (decl1 && decl2) {
- /* Remove ref-qualifiers. Note that rvalue ref-qualifiers are already ignored and
- * it is illegal to overload a function with and without ref-qualifiers. So with
- * all the combinations of ref-qualifiers and cv-qualifiers, we just detect
- * the cv-qualifier (const) overloading. */
- String *d1 = Copy(decl1);
- String *d2 = Copy(decl2);
- if (SwigType_isreference(d1) || SwigType_isrvalue_reference(d1)) {
- Delete(SwigType_pop(d1));
- }
- if (SwigType_isreference(d2) || SwigType_isrvalue_reference(d2)) {
- Delete(SwigType_pop(d2));
- }
- String *dq1 = Copy(d1);
- String *dq2 = Copy(d2);
- if (SwigType_isconst(d1)) {
- Delete(SwigType_pop(dq1));
- }
- if (SwigType_isconst(d2)) {
- Delete(SwigType_pop(dq2));
- }
- if (Strcmp(dq1, dq2) == 0) {
-
- if (SwigType_isconst(d1) && !SwigType_isconst(d2)) {
- if (script_lang_wrapping) {
- // Swap nodes so that the const method gets ignored (shadowed by the non-const method)
- Overloaded t = nodes[i];
- nodes[i] = nodes[j];
- nodes[j] = t;
- }
- differ = 1;
- if (!nodes[j].error) {
- if (script_lang_wrapping) {
- Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n),
- "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
- Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n),
- "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n));
- } else {
- if (!Getattr(nodes[j].n, "overload:ignore")) {
- Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
- "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
- Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n),
- "using %s instead.\n", Swig_name_decl(nodes[i].n));
- }
- }
- }
- nodes[j].error = 1;
- } else if (!SwigType_isconst(d1) && SwigType_isconst(d2)) {
- differ = 1;
- if (!nodes[j].error) {
- if (script_lang_wrapping) {
- Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n),
- "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
- Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n),
- "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n));
- } else {
- if (!Getattr(nodes[j].n, "overload:ignore")) {
- Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
- "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
- Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n),
- "using %s instead.\n", Swig_name_decl(nodes[i].n));
- }
- }
- }
- nodes[j].error = 1;
- }
- }
- Delete(dq1);
- Delete(dq2);
- }
- }
- if (!differ) {
- if (!nodes[j].error) {
- if (script_lang_wrapping) {
- Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[j].n), Getline(nodes[j].n),
- "Overloaded method %s effectively ignored,\n", Swig_name_decl(nodes[j].n));
- Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[i].n), Getline(nodes[i].n),
- "as it is shadowed by %s.\n", Swig_name_decl(nodes[i].n));
- } else {
- if (!Getattr(nodes[j].n, "overload:ignore")) {
- Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
- "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
- Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n),
- "using %s instead.\n", Swig_name_decl(nodes[i].n));
- }
- }
- nodes[j].error = 1;
- }
- }
- }
- }
- }
- }
- List *result = NewList();
- {
- int i;
- int argc_changed_index = -1;
- for (i = 0; i < nnodes; i++) {
- if (nodes[i].error)
- Setattr(nodes[i].n, "overload:ignore", "1");
- Append(result, nodes[i].n);
- // Printf(stdout,"[ %d ] %d %s\n", i, nodes[i].implicitconv_function, ParmList_errorstr(nodes[i].parms));
- if (i == nnodes-1 || nodes[i].argc != nodes[i+1].argc) {
- if (argc_changed_index+2 < nnodes && (nodes[argc_changed_index+1].argc == nodes[argc_changed_index+2].argc)) {
- // Add additional implicitconv functions in same order as already ranked.
- // Consider overloaded functions by argument count... only add additional implicitconv functions if
- // the number of functions with the same arg count > 1, ie, only if overloaded by same argument count.
- int j;
- for (j = argc_changed_index + 1; j <= i; j++) {
- if (nodes[j].implicitconv_function) {
- SetFlag(nodes[j].n, "implicitconvtypecheckoff");
- Append(result, nodes[j].n);
- // Printf(stdout,"[ %d ] %d + %s\n", j, nodes[j].implicitconv_function, ParmList_errorstr(nodes[j].parms));
- }
- }
- }
- argc_changed_index = i;
- }
- }
- }
- return result;
-}
-
-// /* -----------------------------------------------------------------------------
-// * print_typecheck()
-// * ----------------------------------------------------------------------------- */
-
-static bool print_typecheck(String *f, int j, Parm *pj, bool implicitconvtypecheckoff) {
- char tmp[256];
- sprintf(tmp, Char(argv_template_string), j);
- String *tm = Getattr(pj, "tmap:typecheck");
- if (tm) {
- tm = Copy(tm);
- Replaceid(tm, Getattr(pj, "lname"), "_v");
- String *conv = Getattr(pj, "implicitconv");
- if (conv && !implicitconvtypecheckoff) {
- Replaceall(tm, "$implicitconv", conv);
- } else {
- Replaceall(tm, "$implicitconv", "0");
- }
- Replaceall(tm, "$input", tmp);
- Printv(f, tm, "\n", NIL);
- Delete(tm);
- return true;
- } else
- return false;
-}
-
-/* -----------------------------------------------------------------------------
- * ReplaceFormat()
- * ----------------------------------------------------------------------------- */
-
-static String *ReplaceFormat(const_String_or_char_ptr fmt, int j) {
- String *lfmt = NewString(fmt);
- char buf[50];
- sprintf(buf, "%d", j);
- Replaceall(lfmt, "$numargs", buf);
- int i;
- String *commaargs = NewString("");
- for (i = 0; i < j; i++) {
- Printv(commaargs, ", ", NIL);
- Printf(commaargs, Char(argv_template_string), i);
- }
- Replaceall(lfmt, "$commaargs", commaargs);
- return lfmt;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_overload_dispatch()
- *
- * Generate a dispatch function. argc is assumed to hold the argument count.
- * argv is the argument vector.
- *
- * Note that for C++ class member functions, Swig_overload_dispatch() assumes
- * that argc includes the "self" argument and that the first element of argv[]
- * is the "self" argument. So for a member function:
- *
- * Foo::bar(int x, int y, int z);
- *
- * the argc should be 4 (not 3!) and the first element of argv[] would be
- * the appropriate scripting language reference to "self". For regular
- * functions (and static class functions) the argc and argv only include
- * the regular function arguments.
- * ----------------------------------------------------------------------------- */
-
-/*
- Cast dispatch mechanism.
-*/
-String *Swig_overload_dispatch_cast(Node *n, const_String_or_char_ptr fmt, int *maxargs) {
- int i, j;
-
- *maxargs = 1;
-
- String *f = NewString("");
- String *sw = NewString("");
- Printf(f, "{\n");
- Printf(f, "unsigned long _index = 0;\n");
- Printf(f, "SWIG_TypeRank _rank = 0; \n");
-
- /* Get a list of methods ranked by precedence values and argument count */
- List *dispatch = Swig_overload_rank(n, true);
- int nfunc = Len(dispatch);
-
- /* Loop over the functions */
-
- bool emitcheck = true;
- for (i = 0; i < nfunc; i++) {
- int fn = 0;
- Node *ni = Getitem(dispatch, i);
- Parm *pi = Getattr(ni, "wrap:parms");
- bool implicitconvtypecheckoff = GetFlag(ni, "implicitconvtypecheckoff") != 0;
- int num_required = emit_num_required(pi);
- int num_arguments = emit_num_arguments(pi);
- if (num_arguments > *maxargs)
- *maxargs = num_arguments;
-
- if (num_required == num_arguments) {
- Printf(f, "if (%s == %d) {\n", argc_template_string, num_required);
- } else {
- Printf(f, "if ((%s >= %d) && (%s <= %d)) {\n", argc_template_string, num_required, argc_template_string, num_arguments);
- }
- Printf(f, "SWIG_TypeRank _ranki = 0;\n");
- Printf(f, "SWIG_TypeRank _rankm = 0;\n");
- if (num_arguments)
- Printf(f, "SWIG_TypeRank _pi = 1;\n");
-
- /* create a list with the wrappers that collide with the
- current one based on argument number */
- List *coll = NewList();
- for (int k = i + 1; k < nfunc; k++) {
- Node *nk = Getitem(dispatch, k);
- Parm *pk = Getattr(nk, "wrap:parms");
- int nrk = emit_num_required(pk);
- int nak = emit_num_arguments(pk);
- if ((nrk >= num_required && nrk <= num_arguments) || (nak >= num_required && nak <= num_arguments) || (nrk <= num_required && nak >= num_arguments))
- Append(coll, nk);
- }
-
- // printf("overload: %s coll=%d\n", Char(Getattr(n, "sym:name")), Len(coll));
-
- int num_braces = 0;
- bool test = (num_arguments > 0);
- if (test) {
- int need_v = 1;
- j = 0;
- Parm *pj = pi;
- while (pj) {
- if (checkAttribute(pj, "tmap:in:numinputs", "0")) {
- pj = Getattr(pj, "tmap:in:next");
- continue;
- }
-
- String *tm = Getattr(pj, "tmap:typecheck");
- if (tm) {
- tm = Copy(tm);
- /* normalise for comparison later */
- Replaceid(tm, Getattr(pj, "lname"), "_v");
-
- /* if all the wrappers have the same type check on this
- argument we can optimize it out */
- for (int k = 0; k < Len(coll) && !emitcheck; k++) {
- Node *nk = Getitem(coll, k);
- Parm *pk = Getattr(nk, "wrap:parms");
- int nak = emit_num_arguments(pk);
- if (nak <= j)
- continue;
- int l = 0;
- Parm *pl = pk;
- /* finds arg j on the collider wrapper */
- while (pl && l <= j) {
- if (checkAttribute(pl, "tmap:in:numinputs", "0")) {
- pl = Getattr(pl, "tmap:in:next");
- continue;
- }
- if (l == j) {
- /* we are at arg j, so we compare the tmaps now */
- String *tml = Getattr(pl, "tmap:typecheck");
- /* normalise it before comparing */
- if (tml)
- Replaceid(tml, Getattr(pl, "lname"), "_v");
- if (!tml || Cmp(tm, tml))
- emitcheck = true;
- //printf("tmap: %s[%d] (%d) => %s\n\n",
- // Char(Getattr(nk, "sym:name")),
- // l, emitcheck, tml?Char(tml):0);
- }
- Parm *pl1 = Getattr(pl, "tmap:in:next");
- if (pl1)
- pl = pl1;
- else
- pl = nextSibling(pl);
- l++;
- }
- }
-
- if (emitcheck) {
- if (need_v) {
- Printf(f, "int _v = 0;\n");
- need_v = 0;
- }
- if (j >= num_required) {
- Printf(f, "if (%s > %d) {\n", argc_template_string, j);
- num_braces++;
- }
- String *tmp = NewStringf(argv_template_string, j);
-
- String *conv = Getattr(pj, "implicitconv");
- if (conv && !implicitconvtypecheckoff) {
- Replaceall(tm, "$implicitconv", conv);
- } else {
- Replaceall(tm, "$implicitconv", "0");
- }
- Replaceall(tm, "$input", tmp);
- Printv(f, "{\n", tm, "}\n", NIL);
- Delete(tm);
- fn = i + 1;
- Printf(f, "if (!_v) goto check_%d;\n", fn);
- Printf(f, "_ranki += _v*_pi;\n");
- Printf(f, "_rankm += _pi;\n");
- Printf(f, "_pi *= SWIG_MAXCASTRANK;\n");
- }
- }
- if (!Getattr(pj, "tmap:in:SWIGTYPE") && Getattr(pj, "tmap:typecheck:SWIGTYPE")) {
- /* we emit a warning if the argument defines the 'in' typemap, but not the 'typecheck' one */
- Swig_warning(WARN_TYPEMAP_TYPECHECK_UNDEF, Getfile(ni), Getline(ni),
- "Overloaded method %s with no explicit typecheck typemap for arg %d of type '%s'\n",
- Swig_name_decl(n), j, SwigType_str(Getattr(pj, "type"), 0));
- }
- Parm *pj1 = Getattr(pj, "tmap:in:next");
- if (pj1)
- pj = pj1;
- else
- pj = nextSibling(pj);
- j++;
- }
- }
-
- /* close braces */
- for ( /* empty */ ; num_braces > 0; num_braces--)
- Printf(f, "}\n");
-
- Printf(f, "if (!_index || (_ranki < _rank)) {\n");
- Printf(f, " _rank = _ranki; _index = %d;\n", i + 1);
- Printf(f, " if (_rank == _rankm) goto dispatch;\n");
- Printf(f, "}\n");
- String *lfmt = ReplaceFormat(fmt, num_arguments);
- Printf(sw, "case %d:\n", i + 1);
- Printf(sw, Char(lfmt), Getattr(ni, "wrap:name"));
- Printf(sw, "\n");
-
- Printf(f, "}\n"); /* braces closes "if" for this method */
- if (fn)
- Printf(f, "check_%d:\n\n", fn);
-
- if (implicitconvtypecheckoff)
- Delattr(ni, "implicitconvtypecheckoff");
-
- Delete(lfmt);
- Delete(coll);
- }
- Delete(dispatch);
- Printf(f, "dispatch:\n");
- Printf(f, "switch(_index) {\n");
- Printf(f, "%s", sw);
- Printf(f, "}\n");
-
- Printf(f, "}\n");
- return f;
-}
-
-/*
- Fast dispatch mechanism, provided by Salvador Fandi~no Garc'ia (#930586).
-*/
-static String *overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int *maxargs, const_String_or_char_ptr fmt_fastdispatch) {
- int i, j;
-
- *maxargs = 1;
-
- String *f = NewString("");
-
- /* Get a list of methods ranked by precedence values and argument count */
- List *dispatch = Swig_overload_rank(n, true);
- int nfunc = Len(dispatch);
-
- /* Loop over the functions */
-
- for (i = 0; i < nfunc; i++) {
- int fn = 0;
- Node *ni = Getitem(dispatch, i);
- Parm *pi = Getattr(ni, "wrap:parms");
- bool implicitconvtypecheckoff = GetFlag(ni, "implicitconvtypecheckoff") != 0;
- int num_required = emit_num_required(pi);
- int num_arguments = emit_num_arguments(pi);
- if (num_arguments > *maxargs)
- *maxargs = num_arguments;
-
- if (num_required == num_arguments) {
- Printf(f, "if (%s == %d) {\n", argc_template_string, num_required);
- } else {
- Printf(f, "if ((%s >= %d) && (%s <= %d)) {\n", argc_template_string, num_required, argc_template_string, num_arguments);
- }
-
- /* create a list with the wrappers that collide with the
- current one based on argument number */
- List *coll = NewList();
- for (int k = i + 1; k < nfunc; k++) {
- Node *nk = Getitem(dispatch, k);
- Parm *pk = Getattr(nk, "wrap:parms");
- int nrk = emit_num_required(pk);
- int nak = emit_num_arguments(pk);
- if ((nrk >= num_required && nrk <= num_arguments) || (nak >= num_required && nak <= num_arguments) || (nrk <= num_required && nak >= num_arguments))
- Append(coll, nk);
- }
-
- // printf("overload: %s coll=%d\n", Char(Getattr(n, "sym:name")), Len(coll));
-
- bool emitcheck = false;
- int num_braces = 0;
- bool test = (Len(coll) > 0 && num_arguments);
- if (test) {
- int need_v = 1;
- j = 0;
- Parm *pj = pi;
- while (pj) {
- if (checkAttribute(pj, "tmap:in:numinputs", "0")) {
- pj = Getattr(pj, "tmap:in:next");
- continue;
- }
-
- String *tm = Getattr(pj, "tmap:typecheck");
- if (tm) {
- tm = Copy(tm);
- /* normalise for comparison later */
- Replaceid(tm, Getattr(pj, "lname"), "_v");
-
- /* if all the wrappers have the same type check on this
- argument we can optimize it out */
- emitcheck = false;
- for (int k = 0; k < Len(coll) && !emitcheck; k++) {
- Node *nk = Getitem(coll, k);
- Parm *pk = Getattr(nk, "wrap:parms");
- int nak = emit_num_arguments(pk);
- if (nak <= j)
- continue;
- int l = 0;
- Parm *pl = pk;
- /* finds arg j on the collider wrapper */
- while (pl && l <= j) {
- if (checkAttribute(pl, "tmap:in:numinputs", "0")) {
- pl = Getattr(pl, "tmap:in:next");
- continue;
- }
- if (l == j) {
- /* we are at arg j, so we compare the tmaps now */
- String *tml = Getattr(pl, "tmap:typecheck");
- /* normalise it before comparing */
- if (tml)
- Replaceid(tml, Getattr(pl, "lname"), "_v");
- if (!tml || Cmp(tm, tml))
- emitcheck = true;
- //printf("tmap: %s[%d] (%d) => %s\n\n",
- // Char(Getattr(nk, "sym:name")),
- // l, emitcheck, tml?Char(tml):0);
- }
- Parm *pl1 = Getattr(pl, "tmap:in:next");
- if (pl1)
- pl = pl1;
- else
- pl = nextSibling(pl);
- l++;
- }
- }
-
- if (emitcheck) {
- if (need_v) {
- Printf(f, "int _v = 0;\n");
- need_v = 0;
- }
- if (j >= num_required) {
- Printf(f, "if (%s > %d) {\n", argc_template_string, j);
- num_braces++;
- }
- String *tmp = NewStringf(argv_template_string, j);
-
- String *conv = Getattr(pj, "implicitconv");
- if (conv && !implicitconvtypecheckoff) {
- Replaceall(tm, "$implicitconv", conv);
- } else {
- Replaceall(tm, "$implicitconv", "0");
- }
- Replaceall(tm, "$input", tmp);
- Printv(f, "{\n", tm, "}\n", NIL);
- Delete(tm);
- fn = i + 1;
- Printf(f, "if (!_v) goto check_%d;\n", fn);
- }
- }
- if (!Getattr(pj, "tmap:in:SWIGTYPE") && Getattr(pj, "tmap:typecheck:SWIGTYPE")) {
- /* we emit a warning if the argument defines the 'in' typemap, but not the 'typecheck' one */
- Swig_warning(WARN_TYPEMAP_TYPECHECK_UNDEF, Getfile(ni), Getline(ni),
- "Overloaded method %s with no explicit typecheck typemap for arg %d of type '%s'\n",
- Swig_name_decl(n), j, SwigType_str(Getattr(pj, "type"), 0));
- }
- Parm *pj1 = Getattr(pj, "tmap:in:next");
- if (pj1)
- pj = pj1;
- else
- pj = nextSibling(pj);
- j++;
- }
- }
-
- /* close braces */
- for ( /* empty */ ; num_braces > 0; num_braces--)
- Printf(f, "}\n");
-
- // The language module may want to generate different code for last overloaded function called (with same number of arguments)
- String *lfmt = ReplaceFormat(!emitcheck && fmt_fastdispatch ? fmt_fastdispatch : fmt, num_arguments);
- Printf(f, Char(lfmt), Getattr(ni, "wrap:name"));
-
- Printf(f, "}\n"); /* braces closes "if" for this method */
- if (fn)
- Printf(f, "check_%d:\n\n", fn);
-
- if (implicitconvtypecheckoff)
- Delattr(ni, "implicitconvtypecheckoff");
-
- Delete(lfmt);
- Delete(coll);
- }
- Delete(dispatch);
- return f;
-}
-
-String *Swig_overload_dispatch(Node *n, const_String_or_char_ptr fmt, int *maxargs, const_String_or_char_ptr fmt_fastdispatch) {
-
- if (fast_dispatch_mode || GetFlag(n, "feature:fastdispatch")) {
- return overload_dispatch_fast(n, fmt, maxargs, fmt_fastdispatch);
- }
-
- int i, j;
-
- *maxargs = 1;
-
- String *f = NewString("");
-
- /* Get a list of methods ranked by precedence values and argument count */
- List *dispatch = Swig_overload_rank(n, true);
- int nfunc = Len(dispatch);
-
- /* Loop over the functions */
-
- for (i = 0; i < nfunc; i++) {
- Node *ni = Getitem(dispatch, i);
- Parm *pi = Getattr(ni, "wrap:parms");
- bool implicitconvtypecheckoff = GetFlag(ni, "implicitconvtypecheckoff") != 0;
- int num_required = emit_num_required(pi);
- int num_arguments = emit_num_arguments(pi);
- if (GetFlag(n, "wrap:this")) {
- num_required++;
- num_arguments++;
- }
- if (num_arguments > *maxargs)
- *maxargs = num_arguments;
-
- if (num_required == num_arguments) {
- Printf(f, "if (%s == %d) {\n", argc_template_string, num_required);
- } else {
- Printf(f, "if ((%s >= %d) && (%s <= %d)) {\n", argc_template_string, num_required, argc_template_string, num_arguments);
- }
-
- if (num_arguments) {
- Printf(f, "int _v = 0;\n");
- }
-
- int num_braces = 0;
- j = 0;
- Parm *pj = pi;
- while (pj) {
- if (checkAttribute(pj, "tmap:in:numinputs", "0")) {
- pj = Getattr(pj, "tmap:in:next");
- continue;
- }
- if (j >= num_required) {
- String *lfmt = ReplaceFormat(fmt, num_arguments);
- Printf(f, "if (%s <= %d) {\n", argc_template_string, j);
- Printf(f, Char(lfmt), Getattr(ni, "wrap:name"));
- Printf(f, "}\n");
- Delete(lfmt);
- }
- if (print_typecheck(f, (GetFlag(n, "wrap:this") ? j + 1 : j), pj, implicitconvtypecheckoff)) {
- Printf(f, "if (_v) {\n");
- num_braces++;
- }
- if (!Getattr(pj, "tmap:in:SWIGTYPE") && Getattr(pj, "tmap:typecheck:SWIGTYPE")) {
- /* we emit a warning if the argument defines the 'in' typemap, but not the 'typecheck' one */
- Swig_warning(WARN_TYPEMAP_TYPECHECK_UNDEF, Getfile(ni), Getline(ni),
- "Overloaded method %s with no explicit typecheck typemap for arg %d of type '%s'\n",
- Swig_name_decl(n), j, SwigType_str(Getattr(pj, "type"), 0));
- }
- Parm *pk = Getattr(pj, "tmap:in:next");
- if (pk)
- pj = pk;
- else
- pj = nextSibling(pj);
- j++;
- }
- String *lfmt = ReplaceFormat(fmt, num_arguments);
- Printf(f, Char(lfmt), Getattr(ni, "wrap:name"));
- Delete(lfmt);
- /* close braces */
- for ( /* empty */ ; num_braces > 0; num_braces--)
- Printf(f, "}\n");
- Printf(f, "}\n"); /* braces closes "if" for this method */
- if (implicitconvtypecheckoff)
- Delattr(ni, "implicitconvtypecheckoff");
- }
- Delete(dispatch);
- return f;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_overload_check()
- * ----------------------------------------------------------------------------- */
-void Swig_overload_check(Node *n) {
- Swig_overload_rank(n, false);
-}
diff --git a/contrib/tools/swig/Source/Modules/perl5.cxx b/contrib/tools/swig/Source/Modules/perl5.cxx
deleted file mode 100644
index 0cbf6b17a7..0000000000
--- a/contrib/tools/swig/Source/Modules/perl5.cxx
+++ /dev/null
@@ -1,2502 +0,0 @@
-/* ----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * perl5.cxx
- *
- * Perl5 language module for SWIG.
- * ------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include "cparse.h"
-#include <ctype.h>
-
-static const char *usage = "\
-Perl 5 Options (available with -perl5)\n\
- -compat - Compatibility mode\n\
- -const - Wrap constants as constants and not variables (implies -proxy)\n\
- -nopm - Do not generate the .pm file\n\
- -noproxy - Don't create proxy classes\n\
- -proxy - Create proxy classes (enabled by default)\n\
- -static - Omit code related to dynamic loading\n\
-\n";
-
-static int compat = 0;
-
-static int no_pmfile = 0;
-
-static int export_all = 0;
-
-/*
- * pmfile
- * set by the -pm flag, overrides the name of the .pm file
- */
-static String *pmfile = 0;
-
-/*
- * module
- * set by the %module directive, e.g. "Xerces". It will determine
- * the name of the .pm file, and the dynamic library, and the name
- * used by any module wanting to %import the module.
- */
-static String *module = 0;
-
-/*
- * namespace_module
- * the fully namespace qualified name of the module. It will be used
- * to set the package namespace in the .pm file, as well as the name
- * of the initialization methods in the glue library. This will be
- * the same as module, above, unless the %module directive is given
- * the 'package' option, e.g. %module(package="Foo::Bar") "baz"
- */
-static String *namespace_module = 0;
-
-/*
- * cmodule
- * the namespace of the internal glue code, set to the value of
- * module with a 'c' appended
- */
-static String *cmodule = 0;
-
-/*
- * dest_package
- * an optional namespace to put all classes into. Specified by using
- * the %module(package="Foo::Bar") "baz" syntax
- */
-static String *dest_package = 0;
-
-static String *command_tab = 0;
-static String *constant_tab = 0;
-static String *variable_tab = 0;
-
-static File *f_begin = 0;
-static File *f_runtime = 0;
-static File *f_runtime_h = 0;
-static File *f_header = 0;
-static File *f_wrappers = 0;
-static File *f_directors = 0;
-static File *f_directors_h = 0;
-static File *f_init = 0;
-static File *f_pm = 0;
-static String *pm; /* Package initialization code */
-static String *magic; /* Magic variable wrappers */
-
-static int staticoption = 0;
-
-// controlling verbose output
-static int verbose = 0;
-
-/* The following variables are used to manage Perl5 classes */
-
-static int blessed = 1; /* Enable object oriented features */
-static int do_constants = 0; /* Constant wrapping */
-static List *classlist = 0; /* List of classes */
-static int have_constructor = 0;
-static int have_destructor = 0;
-static int have_data_members = 0;
-static String *class_name = 0; /* Name of the class (what Perl thinks it is) */
-static String *real_classname = 0; /* Real name of C/C++ class */
-static String *fullclassname = 0;
-
-static String *pcode = 0; /* Perl code associated with each class */
- /* static String *blessedmembers = 0; *//* Member data associated with each class */
-static int member_func = 0; /* Set to 1 when wrapping a member function */
-static String *func_stubs = 0; /* Function stubs */
-static String *const_stubs = 0; /* Constant stubs */
-static int num_consts = 0; /* Number of constants */
-static String *var_stubs = 0; /* Variable stubs */
-static String *exported = 0; /* Exported symbols */
-static String *pragma_include = 0;
-static String *additional_perl_code = 0; /* Additional Perl code from %perlcode %{ ... %} */
-static Hash *operators = 0;
-static int have_operators = 0;
-
-class PERL5:public Language {
-public:
-
- PERL5():Language () {
- Clear(argc_template_string);
- Printv(argc_template_string, "items", NIL);
- Clear(argv_template_string);
- Printv(argv_template_string, "ST(%d)", NIL);
- director_language = 1;
- }
-
- /* Test to see if a type corresponds to something wrapped with a shadow class */
- Node *is_shadow(SwigType *t) {
- Node *n;
- n = classLookup(t);
- /* Printf(stdout,"'%s' --> '%p'\n", t, n); */
- if (n) {
- if (!Getattr(n, "perl5:proxy")) {
- setclassname(n);
- }
- return Getattr(n, "perl5:proxy");
- }
- return 0;
- }
-
- /* ------------------------------------------------------------
- * main()
- * ------------------------------------------------------------ */
-
- virtual void main(int argc, char *argv[]) {
- int i = 1;
-
- SWIG_library_directory("perl5");
-
- for (i = 1; i < argc; i++) {
- if (argv[i]) {
- if (strcmp(argv[i], "-package") == 0) {
- Printv(stderr,
- "*** -package is no longer supported\n*** use the directive '%module A::B::C' in your interface file instead\n*** see the Perl section in the manual for details.\n", NIL);
- Exit(EXIT_FAILURE);
- } else if (strcmp(argv[i], "-interface") == 0) {
- Printv(stderr,
- "*** -interface is no longer supported\n*** use the directive '%module A::B::C' in your interface file instead\n*** see the Perl section in the manual for details.\n", NIL);
- Exit(EXIT_FAILURE);
- } else if (strcmp(argv[i], "-exportall") == 0) {
- export_all = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-static") == 0) {
- staticoption = 1;
- Swig_mark_arg(i);
- } else if ((strcmp(argv[i], "-shadow") == 0) || ((strcmp(argv[i], "-proxy") == 0))) {
- blessed = 1;
- Swig_mark_arg(i);
- } else if ((strcmp(argv[i], "-noproxy") == 0)) {
- blessed = 0;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-const") == 0) {
- do_constants = 1;
- blessed = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nopm") == 0) {
- no_pmfile = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-pm") == 0) {
- Swig_mark_arg(i);
- i++;
- pmfile = NewString(argv[i]);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i],"-v") == 0) {
- Swig_mark_arg(i);
- verbose++;
- } else if (strcmp(argv[i], "-compat") == 0) {
- compat = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-help") == 0) {
- fputs(usage, stdout);
- } else if (strcmp(argv[i], "-cppcast") == 0) {
- Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nocppcast") == 0) {
- Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
- Swig_mark_arg(i);
- Exit(EXIT_FAILURE);
- }
- }
- }
-
- Preprocessor_define("SWIGPERL 1", 0);
- // SWIGPERL5 is deprecated, and no longer documented.
- Preprocessor_define("SWIGPERL5 1", 0);
- SWIG_typemap_lang("perl5");
- SWIG_config_file("perl5.swg");
- allow_overloading();
- }
-
- /* ------------------------------------------------------------
- * top()
- * ------------------------------------------------------------ */
-
- virtual int top(Node *n) {
- /* check if directors are enabled for this module. note: this
- * is a "master" switch, without which no director code will be
- * emitted. %feature("director") statements are also required
- * to enable directors for individual classes or methods.
- *
- * use %module(directors="1") modulename at the start of the
- * interface file to enable director generation.
- *
- * TODO: directors are disallowed in conjunction with many command
- * line options. Some of them are probably safe, but it will take
- * some effort to validate each one.
- */
- {
- Node *mod = Getattr(n, "module");
- if (mod) {
- Node *options = Getattr(mod, "options");
- if (options) {
- int dirprot = 0;
- if (Getattr(options, "dirprot"))
- dirprot = 1;
- if (Getattr(options, "nodirprot"))
- dirprot = 0;
- if (Getattr(options, "directors")) {
- int allow = 1;
- if (export_all) {
- Printv(stderr, "*** directors are not supported with -exportall\n", NIL);
- allow = 0;
- }
- if (staticoption) {
- Printv(stderr, "*** directors are not supported with -static\n", NIL);
- allow = 0;
- }
- if (!blessed) {
- Printv(stderr, "*** directors are not supported with -noproxy\n", NIL);
- allow = 0;
- }
- if (no_pmfile) {
- Printv(stderr, "*** directors are not supported with -nopm\n", NIL);
- allow = 0;
- }
- if (compat) {
- Printv(stderr, "*** directors are not supported with -compat\n", NIL);
- allow = 0;
- }
- if (allow) {
- allow_directors();
- if (dirprot)
- allow_dirprot();
- }
- }
- }
- }
- }
-
- /* Initialize all of the output files */
- String *outfile = Getattr(n, "outfile");
- String *outfile_h = Getattr(n, "outfile_h");
-
- f_begin = NewFile(outfile, "w", SWIG_output_files());
- if (!f_begin) {
- FileErrorDisplay(outfile);
- Exit(EXIT_FAILURE);
- }
- f_runtime = NewString("");
- f_init = NewString("");
- f_header = NewString("");
- f_wrappers = NewString("");
- f_directors_h = NewString("");
- f_directors = NewString("");
-
- if (directorsEnabled()) {
- f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
- if (!f_runtime_h) {
- FileErrorDisplay(outfile_h);
- Exit(EXIT_FAILURE);
- }
- }
-
- /* Register file targets with the SWIG file handler */
- Swig_register_filebyname("header", f_header);
- Swig_register_filebyname("wrapper", f_wrappers);
- Swig_register_filebyname("begin", f_begin);
- Swig_register_filebyname("runtime", f_runtime);
- Swig_register_filebyname("init", f_init);
- Swig_register_filebyname("director", f_directors);
- Swig_register_filebyname("director_h", f_directors_h);
-
- classlist = NewList();
-
- pm = NewString("");
- func_stubs = NewString("");
- var_stubs = NewString("");
- const_stubs = NewString("");
- exported = NewString("");
- magic = NewString("");
- pragma_include = NewString("");
- additional_perl_code = NewString("");
-
- command_tab = NewString("static swig_command_info swig_commands[] = {\n");
- constant_tab = NewString("static swig_constant_info swig_constants[] = {\n");
- variable_tab = NewString("static swig_variable_info swig_variables[] = {\n");
-
- Swig_banner(f_begin);
-
- Swig_obligatory_macros(f_runtime, "PERL");
-
- if (directorsEnabled()) {
- Printf(f_runtime, "#define SWIG_DIRECTORS\n");
- }
- Printf(f_runtime, "#define SWIG_CASTRANK_MODE\n");
- Printf(f_runtime, "\n");
-
- // Is the imported module in another package? (IOW, does it use the
- // %module(package="name") option and it's different than the package
- // of this module.)
- Node *mod = Getattr(n, "module");
- Node *options = Getattr(mod, "options");
- module = Copy(Getattr(n,"name"));
-
- String *underscore_module = Copy(module);
- Replaceall(underscore_module,":","_");
-
- if (verbose > 0) {
- fprintf(stdout, "top: using namespace_module: %s\n", Char(namespace_module));
- }
-
- if (directorsEnabled()) {
- Swig_banner(f_directors_h);
- Printf(f_directors_h, "\n");
- Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", underscore_module);
- Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", underscore_module);
- if (dirprot_mode()) {
- Printf(f_directors_h, "#include <map>\n");
- Printf(f_directors_h, "#include <string>\n\n");
- }
-
- Printf(f_directors, "\n\n");
- Printf(f_directors, "/* ---------------------------------------------------\n");
- Printf(f_directors, " * C++ director class methods\n");
- Printf(f_directors, " * --------------------------------------------------- */\n\n");
- if (outfile_h) {
- String *filename = Swig_file_filename(outfile_h);
- Printf(magic, "#include \"%s\"\n\n", filename);
- Delete(filename);
- }
- }
-
- if (verbose > 0) {
- fprintf(stdout, "top: using module: %s\n", Char(module));
- }
-
- dest_package = options ? Getattr(options, "package") : 0;
- if (dest_package) {
- namespace_module = Copy(dest_package);
- if (verbose > 0) {
- fprintf(stdout, "top: Found package: %s\n",Char(dest_package));
- }
- } else {
- namespace_module = Copy(module);
- if (verbose > 0) {
- fprintf(stdout, "top: No package found\n");
- }
- }
- /* If we're in blessed mode, change the package name to "packagec" */
-
- if (blessed) {
- cmodule = NewStringf("%sc",namespace_module);
- } else {
- cmodule = NewString(namespace_module);
- }
-
- /* Create a .pm file
- * Need to strip off any prefixes that might be found in
- * the module name */
-
- if (no_pmfile) {
- f_pm = NewString(0);
- } else {
- if (!pmfile) {
- char *m = Char(module) + Len(module);
- while (m != Char(module)) {
- if (*m == ':') {
- m++;
- break;
- }
- m--;
- }
- pmfile = NewStringf("%s.pm", m);
- }
- String *filen = NewStringf("%s%s", SWIG_output_directory(), pmfile);
- if ((f_pm = NewFile(filen, "w", SWIG_output_files())) == 0) {
- FileErrorDisplay(filen);
- Exit(EXIT_FAILURE);
- }
- Delete(filen);
- filen = NULL;
- Swig_register_filebyname("pm", f_pm);
- Swig_register_filebyname("perl", f_pm);
- }
- {
- String *boot_name = NewStringf("boot_%s", underscore_module);
- Printf(f_header,"#define SWIG_init %s\n\n", boot_name);
- Printf(f_header,"#define SWIG_name \"%s::%s\"\n", cmodule, boot_name);
- Printf(f_header,"#define SWIG_prefix \"%s::\"\n", cmodule);
- Delete(boot_name);
- }
-
- Swig_banner_target_lang(f_pm, "#");
- Printf(f_pm, "\n");
-
- Printf(f_pm, "package %s;\n", module);
-
- /*
- * If the package option has been given we are placing our
- * symbols into some other packages namespace, so we do not
- * mess with @ISA or require for that package
- */
- if (dest_package) {
- Printf(f_pm,"use base qw(DynaLoader);\n");
- } else {
- Printf(f_pm,"use base qw(Exporter);\n");
- if (!staticoption) {
- Printf(f_pm,"use base qw(DynaLoader);\n");
- }
- }
-
- /* Start creating magic code */
-
- Printv(magic,
- "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n",
- "#define MAGIC_CLASS\n",
- "SWIGCLASS_STATIC int swig_magic_readonly(pTHX_ SV *SWIGUNUSEDPARM(sv), MAGIC *SWIGUNUSEDPARM(mg)) {\n",
- tab4, "MAGIC_PPERL\n", tab4, "croak(\"Value is read-only.\");\n", tab4, "return 0;\n", "}\n", NIL);
-
- Printf(f_wrappers, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
-
- /* emit wrappers */
- Language::top(n);
-
- if (directorsEnabled()) {
- // Insert director runtime into the f_runtime file (make it occur before %header section)
- Swig_insert_file("director_common.swg", f_runtime);
- Swig_insert_file("director.swg", f_runtime);
- }
-
- String *base = NewString("");
-
- /* Dump out variable wrappers */
-
- Printv(magic, "\n#ifdef __cplusplus\n}\n#endif\n", NIL);
-
- Printf(f_header, "%s\n", magic);
-
- String *type_table = NewString("");
-
- /* Patch the type table to reflect the names used by shadow classes */
- if (blessed) {
- Iterator cls;
- for (cls = First(classlist); cls.item; cls = Next(cls)) {
- String *pname = Getattr(cls.item, "perl5:proxy");
- if (pname) {
- SwigType *type = Getattr(cls.item, "classtypeobj");
- if (!type)
- continue; /* If unnamed class, no type will be found */
- type = Copy(type);
-
- SwigType_add_pointer(type);
- String *mangled = SwigType_manglestr(type);
- SwigType_remember_mangleddata(mangled, NewStringf("\"%s\"", pname));
- Delete(type);
- Delete(mangled);
- }
- }
- }
- SwigType_emit_type_table(f_runtime, type_table);
-
- Printf(f_wrappers, "%s", type_table);
- Delete(type_table);
-
- Printf(constant_tab, "{0,0,0,0,0,0}\n};\n");
- Printv(f_wrappers, constant_tab, NIL);
-
- Printf(f_wrappers, "#ifdef __cplusplus\n}\n#endif\n");
-
- Printf(f_init, "\t ST(0) = &PL_sv_yes;\n");
- Printf(f_init, "\t XSRETURN(1);\n");
- Printf(f_init, "}\n");
-
- /* Finish off tables */
- Printf(variable_tab, "{0,0,0,0}\n};\n");
- Printv(f_wrappers, variable_tab, NIL);
-
- Printf(command_tab, "{0,0}\n};\n");
- Printv(f_wrappers, command_tab, NIL);
-
-
- Printf(f_pm, "package %s;\n", cmodule);
-
- if (!staticoption) {
- Printf(f_pm,"bootstrap %s;\n", module);
- } else {
- Printf(f_pm,"package %s;\n", cmodule);
- Printf(f_pm,"boot_%s();\n", underscore_module);
- }
-
- Printf(f_pm, "package %s;\n", module);
- /*
- * If the package option has been given we are placing our
- * symbols into some other packages namespace, so we do not
- * mess with @EXPORT
- */
- if (!dest_package) {
- Printf(f_pm,"@EXPORT = qw(%s);\n", exported);
- }
-
- Printf(f_pm, "%s", pragma_include);
-
- if (blessed) {
-
- /*
- * These methods will be duplicated if package
- * has been specified, so we do not output them
- */
- if (!dest_package) {
- Printv(base, "\n# ---------- BASE METHODS -------------\n\n", "package ", namespace_module, ";\n\n", NIL);
-
- /* Write out the TIE method */
-
- Printv(base, "sub TIEHASH {\n", tab4, "my ($classname,$obj) = @_;\n", tab4, "return bless $obj, $classname;\n", "}\n\n", NIL);
-
- /* Output a CLEAR method. This is just a place-holder, but by providing it we
- * can make declarations such as
- * %$u = ( x => 2, y=>3, z =>4 );
- *
- * Where x,y,z are the members of some C/C++ object. */
-
- Printf(base, "sub CLEAR { }\n\n");
-
- /* Output default firstkey/nextkey methods */
-
- Printf(base, "sub FIRSTKEY { }\n\n");
- Printf(base, "sub NEXTKEY { }\n\n");
-
- /* Output a FETCH method. This is actually common to all classes */
- Printv(base,
- "sub FETCH {\n",
- tab4, "my ($self,$field) = @_;\n", tab4, "my $member_func = \"swig_${field}_get\";\n", tab4, "$self->$member_func();\n", "}\n\n", NIL);
-
- /* Output a STORE method. This is also common to all classes (might move to base class) */
-
- Printv(base,
- "sub STORE {\n",
- tab4, "my ($self,$field,$newval) = @_;\n",
- tab4, "my $member_func = \"swig_${field}_set\";\n", tab4, "$self->$member_func($newval);\n", "}\n\n", NIL);
-
- /* Output a 'this' method */
-
- Printv(base, "sub this {\n", tab4, "my $ptr = shift;\n", tab4, "return tied(%$ptr);\n", "}\n\n", NIL);
-
- Printf(f_pm, "%s", base);
- }
-
- /* Emit function stubs for stand-alone functions */
- Printf(f_pm, "\n# ------- FUNCTION WRAPPERS --------\n\n");
- Printf(f_pm, "package %s;\n\n", namespace_module);
- Printf(f_pm, "%s", func_stubs);
-
- /* Emit package code for different classes */
- Printf(f_pm, "%s", pm);
-
- if (num_consts > 0) {
- /* Emit constant stubs */
- Printf(f_pm, "\n# ------- CONSTANT STUBS -------\n\n");
- Printf(f_pm, "package %s;\n\n", namespace_module);
- Printf(f_pm, "%s", const_stubs);
- }
-
- /* Emit variable stubs */
-
- Printf(f_pm, "\n# ------- VARIABLE STUBS --------\n\n");
- Printf(f_pm, "package %s;\n\n", namespace_module);
- Printf(f_pm, "%s", var_stubs);
- }
-
- /* Add additional Perl code at the end */
- Printf(f_pm, "%s", additional_perl_code);
-
- Printf(f_pm, "1;\n");
- Delete(f_pm);
- Delete(base);
- Delete(dest_package);
- Delete(underscore_module);
-
- /* Close all of the files */
- Dump(f_runtime, f_begin);
- Dump(f_header, f_begin);
-
- if (directorsEnabled()) {
- Dump(f_directors_h, f_runtime_h);
- Printf(f_runtime_h, "\n");
- Printf(f_runtime_h, "#endif\n");
- Dump(f_directors, f_begin);
- }
-
- Dump(f_wrappers, f_begin);
- Wrapper_pretty_print(f_init, f_begin);
- Delete(f_header);
- Delete(f_wrappers);
- Delete(f_init);
- Delete(f_directors);
- Delete(f_directors_h);
- Delete(f_runtime);
- Delete(f_begin);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * importDirective(Node *n)
- * ------------------------------------------------------------ */
-
- virtual int importDirective(Node *n) {
- if (blessed) {
- String *modname = Getattr(n, "module");
- if (modname) {
- Printf(f_pm, "require %s;\n", modname);
- }
- }
- return Language::importDirective(n);
- }
-
- /* ------------------------------------------------------------
- * functionWrapper()
- * ------------------------------------------------------------ */
-
- virtual int functionWrapper(Node *n) {
- String *name = Getattr(n, "name");
- String *iname = Getattr(n, "sym:name");
- SwigType *d = Getattr(n, "type");
- ParmList *l = Getattr(n, "parms");
- String *overname = 0;
- int director_method = 0;
-
- Parm *p;
- int i;
- Wrapper *f;
- char source[256], temp[256];
- String *tm;
- String *cleanup, *outarg;
- int num_saved = 0;
- int num_arguments, num_required;
- int varargs = 0;
-
- if (Getattr(n, "sym:overloaded")) {
- overname = Getattr(n, "sym:overname");
- } else {
- if (!addSymbol(iname, n))
- return SWIG_ERROR;
- }
-
- f = NewWrapper();
- cleanup = NewString("");
- outarg = NewString("");
-
- String *wname = Swig_name_wrapper(iname);
- if (overname) {
- Append(wname, overname);
- }
- Setattr(n, "wrap:name", wname);
- Printv(f->def, "XS(", wname, ") {\n", "{\n", /* scope to destroy C++ objects before croaking */
- NIL);
-
- emit_parameter_variables(l, f);
- emit_attach_parmmaps(l, f);
- Setattr(n, "wrap:parms", l);
-
- num_arguments = emit_num_arguments(l);
- num_required = emit_num_required(l);
- varargs = emit_isvarargs(l);
-
- Wrapper_add_local(f, "argvi", "int argvi = 0");
-
- /* Check the number of arguments */
- if (!varargs) {
- Printf(f->code, " if ((items < %d) || (items > %d)) {\n", num_required, num_arguments);
- } else {
- Printf(f->code, " if (items < %d) {\n", num_required);
- }
- Printf(f->code, " SWIG_croak(\"Usage: %s\");\n", usage_func(Char(iname), d, l));
- Printf(f->code, "}\n");
-
- /* Write code to extract parameters. */
- for (i = 0, p = l; i < num_arguments; i++) {
-
- /* Skip ignored arguments */
-
- while (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- }
-
- SwigType *pt = Getattr(p, "type");
-
- /* Produce string representation of source and target arguments */
- sprintf(source, "ST(%d)", i);
-
- if (i >= num_required) {
- Printf(f->code, " if (items > %d) {\n", i);
- }
- if ((tm = Getattr(p, "tmap:in"))) {
- Replaceall(tm, "$input", source);
- Setattr(p, "emit:input", source); /* Save input location */
-
- if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
- Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
- } else {
- Replaceall(tm, "$disown", "0");
- }
-
- Printf(f->code, "%s\n", tm);
- p = Getattr(p, "tmap:in:next");
- } else {
- Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
- p = nextSibling(p);
- }
- if (i >= num_required) {
- Printf(f->code, " }\n");
- }
- }
-
- if (varargs) {
- if (p && (tm = Getattr(p, "tmap:in"))) {
- sprintf(source, "ST(%d)", i);
- Replaceall(tm, "$input", source);
- Setattr(p, "emit:input", source);
- Printf(f->code, "if (items >= %d) {\n", i);
- Printv(f->code, tm, "\n", NIL);
- Printf(f->code, "}\n");
- }
- }
-
- /* Insert constraint checking code */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:check"))) {
- Printv(f->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:check:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* Insert cleanup code */
- for (i = 0, p = l; p; i++) {
- if ((tm = Getattr(p, "tmap:freearg"))) {
- Replaceall(tm, "$arg", Getattr(p, "emit:input"));
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(cleanup, tm, "\n", NIL);
- p = Getattr(p, "tmap:freearg:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* Insert argument output code */
- num_saved = 0;
- for (i = 0, p = l; p; i++) {
- if ((tm = Getattr(p, "tmap:argout"))) {
- SwigType *t = Getattr(p, "type");
- Replaceall(tm, "$result", "ST(argvi)");
- if (is_shadow(t)) {
- Replaceall(tm, "$shadow", "SWIG_SHADOW");
- } else {
- Replaceall(tm, "$shadow", "0");
- }
-
- String *in = Getattr(p, "emit:input");
- if (in) {
- sprintf(temp, "_saved[%d]", num_saved);
- Replaceall(tm, "$arg", temp);
- Replaceall(tm, "$input", temp);
- Printf(f->code, "_saved[%d] = %s;\n", num_saved, in);
- num_saved++;
- }
- Printv(outarg, tm, "\n", NIL);
- p = Getattr(p, "tmap:argout:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* If there were any saved arguments, emit a local variable for them */
- if (num_saved) {
- sprintf(temp, "_saved[%d]", num_saved);
- Wrapper_add_localv(f, "_saved", "SV *", temp, NIL);
- }
-
- director_method = is_member_director(n) && !is_smart_pointer() && 0 != Cmp(nodeType(n), "destructor");
- if (director_method) {
- Wrapper_add_local(f, "director", "Swig::Director *director = 0");
- Append(f->code, "director = SWIG_DIRECTOR_CAST(arg1);\n");
- if (dirprot_mode() && !is_public(n)) {
- Printf(f->code, "if (!director || !(director->swig_get_inner(\"%s\"))) {\n", name);
- Printf(f->code, "SWIG_exception_fail(SWIG_RuntimeError, \"accessing protected member %s\");\n", name);
- Append(f->code, "}\n");
- }
- Wrapper_add_local(f, "upcall", "bool upcall = false");
- Printf(f->code, "upcall = director && SvSTASH(SvRV(ST(0))) == gv_stashpv(director->swig_get_class(), 0);\n");
- }
-
- /* Emit the function call */
- if (director_method) {
- Append(f->code, "try {\n");
- }
-
- /* Now write code to make the function call */
-
- Swig_director_emit_dynamic_cast(n, f);
- String *actioncode = emit_action(n);
-
- if (director_method) {
- Append(actioncode, "} catch (Swig::DirectorException& swig_err) {\n");
- Append(actioncode, " sv_setsv(ERRSV, swig_err.getNative());\n");
- Append(actioncode, " SWIG_fail;\n");
- Append(actioncode, "}\n");
- }
-
- if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
- SwigType *t = Getattr(n, "type");
- Replaceall(tm, "$result", "ST(argvi)");
- if (is_shadow(t)) {
- Replaceall(tm, "$shadow", "SWIG_SHADOW");
- } else {
- Replaceall(tm, "$shadow", "0");
- }
- if (GetFlag(n, "feature:new")) {
- Replaceall(tm, "$owner", "SWIG_OWNER");
- } else {
- Replaceall(tm, "$owner", "0");
- }
- Printf(f->code, "%s\n", tm);
- } else {
- Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);
- }
- emit_return_variable(n, d, f);
-
- /* If there were any output args, take care of them. */
-
- Printv(f->code, outarg, NIL);
-
- /* If there was any cleanup, do that. */
-
- Printv(f->code, cleanup, NIL);
-
- if (GetFlag(n, "feature:new")) {
- if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
- Printf(f->code, "%s\n", tm);
- }
- }
-
- if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
- Printf(f->code, "%s\n", tm);
- }
-
- if (director_method) {
- if ((tm = Swig_typemap_lookup("directorfree", n, Swig_cresult_name(), 0))) {
- Replaceall(tm, "$input", Swig_cresult_name());
- Replaceall(tm, "$result", "ST(argvi)");
- Printf(f->code, "%s\n", tm);
- Delete(tm);
- }
- }
-
- Printv(f->code, "XSRETURN(argvi);\n", "fail:\n", cleanup, "SWIG_croak_null();\n" "}\n" "}\n", NIL);
-
- /* Add the dXSARGS last */
-
- Wrapper_add_local(f, "dXSARGS", "dXSARGS");
-
- /* Substitute the cleanup code */
- Replaceall(f->code, "$cleanup", cleanup);
- Replaceall(f->code, "$symname", iname);
-
- /* Dump the wrapper function */
-
- Wrapper_print(f, f_wrappers);
-
- /* Now register the function */
-
- if (!Getattr(n, "sym:overloaded")) {
- Printf(command_tab, "{\"%s::%s\", %s},\n", cmodule, iname, wname);
- } else if (!Getattr(n, "sym:nextSibling")) {
- /* Generate overloaded dispatch function */
- int maxargs;
- String *dispatch = Swig_overload_dispatch_cast(n, "PUSHMARK(MARK); SWIG_CALLXS(%s); return;", &maxargs);
-
- /* Generate a dispatch wrapper for all overloaded functions */
-
- Wrapper *df = NewWrapper();
- String *dname = Swig_name_wrapper(iname);
-
- Printv(df->def, "XS(", dname, ") {\n", NIL);
-
- Wrapper_add_local(df, "dXSARGS", "dXSARGS");
- Printv(df->code, dispatch, "\n", NIL);
- Printf(df->code, "croak(\"No matching function for overloaded '%s'\");\n", iname);
- Printf(df->code, "XSRETURN(0);\n");
- Printv(df->code, "}\n", NIL);
- Wrapper_print(df, f_wrappers);
- Printf(command_tab, "{\"%s::%s\", %s},\n", cmodule, iname, dname);
- DelWrapper(df);
- Delete(dispatch);
- Delete(dname);
- }
- if (!Getattr(n, "sym:nextSibling")) {
- if (export_all) {
- Printf(exported, "%s ", iname);
- }
-
- /* --------------------------------------------------------------------
- * Create a stub for this function, provided it's not a member function
- * -------------------------------------------------------------------- */
-
- if ((blessed) && (!member_func)) {
- Printv(func_stubs, "*", iname, " = *", cmodule, "::", iname, ";\n", NIL);
- }
-
- }
- Delete(cleanup);
- Delete(outarg);
- DelWrapper(f);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * variableWrapper()
- * ------------------------------------------------------------ */
- virtual int variableWrapper(Node *n) {
- String *name = Getattr(n, "name");
- String *iname = Getattr(n, "sym:name");
- SwigType *t = Getattr(n, "type");
- Wrapper *getf, *setf;
- String *tm;
- String *getname = Swig_name_get(NSPACE_TODO, iname);
- String *setname = Swig_name_set(NSPACE_TODO, iname);
-
- String *get_name = Swig_name_wrapper(getname);
- String *set_name = Swig_name_wrapper(setname);
-
- if (!addSymbol(iname, n))
- return SWIG_ERROR;
-
- getf = NewWrapper();
- setf = NewWrapper();
-
- /* Create a Perl function for setting the variable value */
-
- if (!GetFlag(n, "feature:immutable")) {
- Setattr(n, "wrap:name", set_name);
- Printf(setf->def, "SWIGCLASS_STATIC int %s(pTHX_ SV* sv, MAGIC * SWIGUNUSEDPARM(mg)) {\n", set_name);
- Printv(setf->code, tab4, "MAGIC_PPERL\n", NIL);
-
- /* Check for a few typemaps */
- tm = Swig_typemap_lookup("varin", n, name, 0);
- if (tm) {
- Replaceall(tm, "$input", "sv");
- /* Printf(setf->code,"%s\n", tm); */
- emit_action_code(n, setf->code, tm);
- } else {
- Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
- DelWrapper(setf);
- DelWrapper(getf);
- return SWIG_NOWRAP;
- }
- Printf(setf->code, "fail:\n");
- Printf(setf->code, " return 1;\n}\n");
- Replaceall(setf->code, "$symname", iname);
- Wrapper_print(setf, magic);
- }
-
- /* Now write a function to evaluate the variable */
- Setattr(n, "wrap:name", get_name);
- int addfail = 0;
- Printf(getf->def, "SWIGCLASS_STATIC int %s(pTHX_ SV *sv, MAGIC *SWIGUNUSEDPARM(mg)) {\n", get_name);
- Printv(getf->code, tab4, "MAGIC_PPERL\n", NIL);
-
- if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
- Replaceall(tm, "$result", "sv");
- if (is_shadow(t)) {
- Replaceall(tm, "$shadow", "SWIG_SHADOW");
- } else {
- Replaceall(tm, "$shadow", "0");
- }
- /* Printf(getf->code,"%s\n", tm); */
- addfail = emit_action_code(n, getf->code, tm);
- } else {
- Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
- DelWrapper(setf);
- DelWrapper(getf);
- return SWIG_NOWRAP;
- }
- Printf(getf->code, " return 1;\n");
- if (addfail) {
- Append(getf->code, "fail:\n");
- Append(getf->code, " return 0;\n");
- }
- Append(getf->code, "}\n");
-
-
- Replaceall(getf->code, "$symname", iname);
- Wrapper_print(getf, magic);
-
- String *tt = Getattr(n, "tmap:varout:type");
- if (tt) {
- tt = NewStringf("&%s", tt);
- } else {
- tt = NewString("0");
- }
- /* Now add symbol to the PERL interpreter */
- if (GetFlag(n, "feature:immutable")) {
- Printv(variable_tab, tab4, "{ \"", cmodule, "::", iname, "\", MAGIC_CLASS swig_magic_readonly, MAGIC_CLASS ", get_name, ",", tt, " },\n", NIL);
-
- } else {
- Printv(variable_tab, tab4, "{ \"", cmodule, "::", iname, "\", MAGIC_CLASS ", set_name, ", MAGIC_CLASS ", get_name, ",", tt, " },\n", NIL);
- }
-
- /* If we're blessed, try to figure out what to do with the variable
- 1. If it's a Perl object of some sort, create a tied-hash
- around it.
- 2. Otherwise, just hack Perl's symbol table */
-
- if (blessed) {
- if (is_shadow(t)) {
- Printv(var_stubs,
- "\nmy %__", iname, "_hash;\n",
- "tie %__", iname, "_hash,\"", is_shadow(t), "\", $",
- cmodule, "::", iname, ";\n", "$", iname, "= \\%__", iname, "_hash;\n", "bless $", iname, ", ", is_shadow(t), ";\n", NIL);
- } else {
- Printv(var_stubs, "*", iname, " = *", cmodule, "::", iname, ";\n", NIL);
- }
- }
- if (export_all)
- Printf(exported, "$%s ", iname);
-
- Delete(tt);
- DelWrapper(setf);
- DelWrapper(getf);
- Delete(getname);
- Delete(setname);
- Delete(set_name);
- Delete(get_name);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * constantWrapper()
- * ------------------------------------------------------------ */
-
- virtual int constantWrapper(Node *n) {
- String *name = Getattr(n, "name");
- String *iname = Getattr(n, "sym:name");
- SwigType *type = Getattr(n, "type");
- String *rawval = Getattr(n, "rawval");
- String *value = rawval ? rawval : Getattr(n, "value");
- String *tm;
-
- if (!addSymbol(iname, n))
- return SWIG_ERROR;
-
- /* Special hook for member pointer */
- if (SwigType_type(type) == T_MPOINTER) {
- String *wname = Swig_name_wrapper(iname);
- Printf(f_wrappers, "static %s = %s;\n", SwigType_str(type, wname), value);
- value = Char(wname);
- }
-
- if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) {
- Replaceall(tm, "$value", value);
- if (is_shadow(type)) {
- Replaceall(tm, "$shadow", "SWIG_SHADOW");
- } else {
- Replaceall(tm, "$shadow", "0");
- }
- Printf(constant_tab, "%s,\n", tm);
- } else if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
- Replaceall(tm, "$value", value);
- if (is_shadow(type)) {
- Replaceall(tm, "$shadow", "SWIG_SHADOW");
- } else {
- Replaceall(tm, "$shadow", "0");
- }
- Printf(f_init, "%s\n", tm);
- } else {
- Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n");
- return SWIG_NOWRAP;
- }
-
- if (blessed) {
- if (is_shadow(type)) {
- Printv(var_stubs,
- "\nmy %__", iname, "_hash;\n",
- "tie %__", iname, "_hash,\"", is_shadow(type), "\", $",
- cmodule, "::", iname, ";\n", "$", iname, "= \\%__", iname, "_hash;\n", "bless $", iname, ", ", is_shadow(type), ";\n", NIL);
- } else if (do_constants) {
- Printv(const_stubs, "sub ", name, " () { $", cmodule, "::", name, " }\n", NIL);
- num_consts++;
- } else {
- Printv(var_stubs, "*", iname, " = *", cmodule, "::", iname, ";\n", NIL);
- }
- }
- if (export_all) {
- if (do_constants && !is_shadow(type)) {
- Printf(exported, "%s ", name);
- } else {
- Printf(exported, "$%s ", iname);
- }
- }
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * usage_func()
- * ------------------------------------------------------------ */
- char *usage_func(char *iname, SwigType *, ParmList *l) {
- static String *temp = 0;
- Parm *p;
- int i;
-
- if (!temp)
- temp = NewString("");
- Clear(temp);
- Printf(temp, "%s(", iname);
-
- /* Now go through and print parameters */
- p = l;
- i = 0;
- while (p != 0) {
- SwigType *pt = Getattr(p, "type");
- String *pn = Getattr(p, "name");
- if (!checkAttribute(p,"tmap:in:numinputs","0")) {
- /* If parameter has been named, use that. Otherwise, just print a type */
- if (SwigType_type(pt) != T_VOID) {
- if (Len(pn) > 0) {
- Printf(temp, "%s", pn);
- } else {
- Printf(temp, "%s", SwigType_str(pt, 0));
- }
- }
- i++;
- p = nextSibling(p);
- if (p)
- if (!checkAttribute(p,"tmap:in:numinputs","0"))
- Putc(',', temp);
- } else {
- p = nextSibling(p);
- if (p)
- if ((i > 0) && (!checkAttribute(p,"tmap:in:numinputs","0")))
- Putc(',', temp);
- }
- }
- Printf(temp, ");");
- return Char(temp);
- }
-
- /* ------------------------------------------------------------
- * nativeWrapper()
- * ------------------------------------------------------------ */
-
- virtual int nativeWrapper(Node *n) {
- String *name = Getattr(n, "sym:name");
- String *funcname = Getattr(n, "wrap:name");
-
- if (!addSymbol(funcname, n))
- return SWIG_ERROR;
-
- Printf(command_tab, "{\"%s::%s\", %s},\n", cmodule, name, funcname);
- if (export_all)
- Printf(exported, "%s ", name);
- if (blessed) {
- Printv(func_stubs, "*", name, " = *", cmodule, "::", name, ";\n", NIL);
- }
- return SWIG_OK;
- }
-
-/* ----------------------------------------------------------------------------
- * OBJECT-ORIENTED FEATURES
- *
- * These extensions provide a more object-oriented interface to C++
- * classes and structures. The code here is based on extensions
- * provided by David Fletcher and Gary Holt.
- *
- * I have generalized these extensions to make them more general purpose
- * and to resolve object-ownership problems.
- *
- * The approach here is very similar to the Python module :
- * 1. All of the original methods are placed into a single
- * package like before except that a 'c' is appended to the
- * package name.
- *
- * 2. All methods and function calls are wrapped with a new
- * perl function. While possibly inefficient this allows
- * us to catch complex function arguments (which are hard to
- * track otherwise).
- *
- * 3. Classes are represented as tied-hashes in a manner similar
- * to Gary Holt's extension. This allows us to access
- * member data.
- *
- * 4. Stand-alone (global) C functions are modified to take
- * tied hashes as arguments for complex datatypes (if
- * appropriate).
- *
- * 5. Global variables involving a class/struct is encapsulated
- * in a tied hash.
- *
- * ------------------------------------------------------------------------- */
-
-
- void setclassname(Node *n) {
- String *symname = Getattr(n, "sym:name");
- String *fullname;
- String *actualpackage;
- Node *clsmodule = Getattr(n, "module");
-
- if (!clsmodule) {
- /* imported module does not define a module name. Oh well */
- return;
- }
-
- /* Do some work on the class name */
- if (verbose > 0) {
- String *modulename = Getattr(clsmodule, "name");
- fprintf(stdout, "setclassname: Found sym:name: %s\n", Char(symname));
- fprintf(stdout, "setclassname: Found module: %s\n", Char(modulename));
- fprintf(stdout, "setclassname: No package found\n");
- }
-
- if (dest_package) {
- fullname = NewStringf("%s::%s", namespace_module, symname);
- } else {
- actualpackage = Getattr(clsmodule,"name");
-
- if (verbose > 0) {
- fprintf(stdout, "setclassname: Found actualpackage: %s\n", Char(actualpackage));
- }
- if ((!compat) && (!Strchr(symname,':'))) {
- fullname = NewStringf("%s::%s",actualpackage,symname);
- } else {
- fullname = NewString(symname);
- }
- }
- if (verbose > 0) {
- fprintf(stdout, "setclassname: setting proxy: %s\n", Char(fullname));
- }
- Setattr(n, "perl5:proxy", fullname);
- }
-
- /* ------------------------------------------------------------
- * classDeclaration()
- * ------------------------------------------------------------ */
- virtual int classDeclaration(Node *n) {
- /* Do some work on the class name */
- if (!Getattr(n, "feature:onlychildren")) {
- if (blessed) {
- setclassname(n);
- Append(classlist, n);
- }
- }
-
- return Language::classDeclaration(n);
- }
-
- /* ------------------------------------------------------------
- * classHandler()
- * ------------------------------------------------------------ */
-
- virtual int classHandler(Node *n) {
-
- if (blessed) {
- have_constructor = 0;
- have_operators = 0;
- have_destructor = 0;
- have_data_members = 0;
- operators = NewHash();
-
- class_name = Getattr(n, "sym:name");
-
- if (!addSymbol(class_name, n))
- return SWIG_ERROR;
-
- /* Use the fully qualified name of the Perl class */
- if (!compat) {
- fullclassname = NewStringf("%s::%s", namespace_module, class_name);
- } else {
- fullclassname = NewString(class_name);
- }
- real_classname = Getattr(n, "name");
- pcode = NewString("");
- // blessedmembers = NewString("");
- }
-
- /* Emit all of the members */
- Language::classHandler(n);
-
-
- /* Finish the rest of the class */
- if (blessed) {
- /* Generate a client-data entry */
- SwigType *ct = NewStringf("p.%s", real_classname);
- Printv(f_init, "SWIG_TypeClientData(SWIGTYPE", SwigType_manglestr(ct), ", (void*) \"", fullclassname, "\");\n", NIL);
- SwigType_remember(ct);
- Delete(ct);
-
- Printv(pm, "\n############# Class : ", fullclassname, " ##############\n", "\npackage ", fullclassname, ";\n", NIL);
-
- if (have_operators) {
- Printf(pm, "use overload\n");
- Iterator ki;
- for (ki = First(operators); ki.key; ki = Next(ki)) {
- char *name = Char(ki.key);
- // fprintf(stderr,"found name: <%s>\n", name);
- if (strstr(name, "__eq__")) {
- Printv(pm, tab4, "\"==\" => sub { $_[0]->__eq__($_[1])},\n",NIL);
- } else if (strstr(name, "__ne__")) {
- Printv(pm, tab4, "\"!=\" => sub { $_[0]->__ne__($_[1])},\n",NIL);
- // there are no tests for this in operator_overload_runme.pl
- // it is likely to be broken
- // } else if (strstr(name, "__assign__")) {
- // Printv(pm, tab4, "\"=\" => sub { $_[0]->__assign__($_[1])},\n",NIL);
- } else if (strstr(name, "__str__")) {
- Printv(pm, tab4, "'\"\"' => sub { $_[0]->__str__()},\n",NIL);
- } else if (strstr(name, "__plusplus__")) {
- Printv(pm, tab4, "\"++\" => sub { $_[0]->__plusplus__()},\n",NIL);
- } else if (strstr(name, "__minmin__")) {
- Printv(pm, tab4, "\"--\" => sub { $_[0]->__minmin__()},\n",NIL);
- } else if (strstr(name, "__add__")) {
- Printv(pm, tab4, "\"+\" => sub { $_[0]->__add__($_[1])},\n",NIL);
- } else if (strstr(name, "__sub__")) {
- Printv(pm, tab4, "\"-\" => sub { if( not $_[2] ) { $_[0]->__sub__($_[1]) }\n",NIL);
- Printv(pm, tab8, "elsif( $_[0]->can('__rsub__') ) { $_[0]->__rsub__($_[1]) }\n",NIL);
- Printv(pm, tab8, "else { die(\"reverse subtraction not supported\") }\n",NIL);
- Printv(pm, tab8, "},\n",NIL);
- } else if (strstr(name, "__mul__")) {
- Printv(pm, tab4, "\"*\" => sub { $_[0]->__mul__($_[1])},\n",NIL);
- } else if (strstr(name, "__div__")) {
- Printv(pm, tab4, "\"/\" => sub { $_[0]->__div__($_[1])},\n",NIL);
- } else if (strstr(name, "__mod__")) {
- Printv(pm, tab4, "\"%\" => sub { $_[0]->__mod__($_[1])},\n",NIL);
- // there are no tests for this in operator_overload_runme.pl
- // it is likely to be broken
- // } else if (strstr(name, "__and__")) {
- // Printv(pm, tab4, "\"&\" => sub { $_[0]->__and__($_[1])},\n",NIL);
-
- // there are no tests for this in operator_overload_runme.pl
- // it is likely to be broken
- // } else if (strstr(name, "__or__")) {
- // Printv(pm, tab4, "\"|\" => sub { $_[0]->__or__($_[1])},\n",NIL);
- } else if (strstr(name, "__gt__")) {
- Printv(pm, tab4, "\">\" => sub { $_[0]->__gt__($_[1])},\n",NIL);
- } else if (strstr(name, "__ge__")) {
- Printv(pm, tab4, "\">=\" => sub { $_[0]->__ge__($_[1])},\n",NIL);
- } else if (strstr(name, "__not__")) {
- Printv(pm, tab4, "\"!\" => sub { $_[0]->__not__()},\n",NIL);
- } else if (strstr(name, "__lt__")) {
- Printv(pm, tab4, "\"<\" => sub { $_[0]->__lt__($_[1])},\n",NIL);
- } else if (strstr(name, "__le__")) {
- Printv(pm, tab4, "\"<=\" => sub { $_[0]->__le__($_[1])},\n",NIL);
- } else if (strstr(name, "__pluseq__")) {
- Printv(pm, tab4, "\"+=\" => sub { $_[0]->__pluseq__($_[1])},\n",NIL);
- } else if (strstr(name, "__mineq__")) {
- Printv(pm, tab4, "\"-=\" => sub { $_[0]->__mineq__($_[1])},\n",NIL);
- } else if (strstr(name, "__neg__")) {
- Printv(pm, tab4, "\"neg\" => sub { $_[0]->__neg__()},\n",NIL);
- } else {
- fprintf(stderr,"Unknown operator: %s\n", name);
- }
- }
- Printv(pm, tab4,
- "\"=\" => sub { my $class = ref($_[0]); $class->new($_[0]) },\n", NIL);
- Printv(pm, tab4, "\"fallback\" => 1;\n", NIL);
- }
- // make use strict happy
- Printv(pm, "use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);\n", NIL);
-
- /* If we are inheriting from a base class, set that up */
-
- Printv(pm, "@ISA = qw(", NIL);
-
- /* Handle inheritance */
- List *baselist = Getattr(n, "bases");
- if (baselist && Len(baselist)) {
- Iterator b;
- b = First(baselist);
- while (b.item) {
- String *bname = Getattr(b.item, "perl5:proxy");
- if (!bname) {
- b = Next(b);
- continue;
- }
- Printv(pm, " ", bname, NIL);
- b = Next(b);
- }
- }
-
- /* Module comes last */
- if (!compat || Cmp(namespace_module, fullclassname)) {
- Printv(pm, " ", namespace_module, NIL);
- }
-
- Printf(pm, " );\n");
-
- /* Dump out a hash table containing the pointers that we own */
- Printf(pm, "%%OWNER = ();\n");
- if (have_data_members || have_destructor)
- Printf(pm, "%%ITERATORS = ();\n");
-
- /* Dump out the package methods */
-
- Printv(pm, pcode, NIL);
- Delete(pcode);
-
- /* Output methods for managing ownership */
-
- String *director_disown;
- if (Getattr(n, "perl5:directordisown")) {
- director_disown = NewStringf("%s%s($self);\n", tab4, Getattr(n, "perl5:directordisown"));
- } else {
- director_disown = NewString("");
- }
- Printv(pm,
- "sub DISOWN {\n",
- tab4, "my $self = shift;\n",
- director_disown,
- tab4, "my $ptr = tied(%$self);\n",
- tab4, "delete $OWNER{$ptr};\n",
- "}\n\n", "sub ACQUIRE {\n", tab4, "my $self = shift;\n", tab4, "my $ptr = tied(%$self);\n", tab4, "$OWNER{$ptr} = 1;\n", "}\n\n", NIL);
- Delete(director_disown);
-
- /* Only output the following methods if a class has member data */
-
- Delete(operators);
- operators = 0;
- if (Swig_directorclass(n)) {
- /* director classes need a way to recover subclass instance attributes */
- Node *get_attr = NewHash();
- String *mrename;
- String *symname = Getattr(n, "sym:name");
- mrename = Swig_name_disown(NSPACE_TODO, symname);
- Replaceall(mrename, "disown", "swig_get_attr");
- String *type = NewString(getClassType());
- String *name = NewString("self");
- SwigType_add_pointer(type);
- Parm *p = NewParm(type, name, n);
- Delete(name);
- Delete(type);
- type = NewString("SV");
- SwigType_add_pointer(type);
- String *action = NewString("");
- Printv(action, "{\n", " Swig::Director *director = SWIG_DIRECTOR_CAST(arg1);\n",
- " result = sv_newmortal();\n" " if (director) sv_setsv(result, director->swig_get_self());\n", "}\n", NIL);
- Setfile(get_attr, Getfile(n));
- Setline(get_attr, Getline(n));
- Setattr(get_attr, "wrap:action", action);
- Setattr(get_attr, "name", mrename);
- Setattr(get_attr, "sym:name", mrename);
- Setattr(get_attr, "type", type);
- Setattr(get_attr, "parms", p);
- Delete(action);
- Delete(type);
- Delete(p);
-
- member_func = 1;
- functionWrapper(get_attr);
- member_func = 0;
- Delete(get_attr);
-
- Printv(pm, "sub FETCH {\n", tab4, "my ($self,$field) = @_;\n", tab4, "my $member_func = \"swig_${field}_get\";\n", tab4,
- "if (not $self->can($member_func)) {\n", tab8, "my $h = ", cmodule, "::", mrename, "($self);\n", tab8, "return $h->{$field} if $h;\n",
- tab4, "}\n", tab4, "return $self->$member_func;\n", "}\n", "\n", "sub STORE {\n", tab4, "my ($self,$field,$newval) = @_;\n", tab4,
- "my $member_func = \"swig_${field}_set\";\n", tab4, "if (not $self->can($member_func)) {\n", tab8, "my $h = ", cmodule, "::", mrename,
- "($self);\n", tab8, "return $h->{$field} = $newval if $h;\n", tab4, "}\n", tab4, "return $self->$member_func($newval);\n", "}\n", NIL);
-
- Delete(mrename);
- }
- }
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * memberfunctionHandler()
- * ------------------------------------------------------------ */
-
- virtual int memberfunctionHandler(Node *n) {
- String *symname = Getattr(n, "sym:name");
-
- member_func = 1;
- Language::memberfunctionHandler(n);
- member_func = 0;
-
- if ((blessed) && (!Getattr(n, "sym:nextSibling"))) {
-
- if (Strstr(symname, "__eq__")) {
- DohSetInt(operators, "__eq__", 1);
- have_operators = 1;
- } else if (Strstr(symname, "__ne__")) {
- DohSetInt(operators, "__ne__", 1);
- have_operators = 1;
- } else if (Strstr(symname, "__assign__")) {
- DohSetInt(operators, "__assign__", 1);
- have_operators = 1;
- } else if (Strstr(symname, "__str__")) {
- DohSetInt(operators, "__str__", 1);
- have_operators = 1;
- } else if (Strstr(symname, "__add__")) {
- DohSetInt(operators, "__add__", 1);
- have_operators = 1;
- } else if (Strstr(symname, "__sub__")) {
- DohSetInt(operators, "__sub__", 1);
- have_operators = 1;
- } else if (Strstr(symname, "__mul__")) {
- DohSetInt(operators, "__mul__", 1);
- have_operators = 1;
- } else if (Strstr(symname, "__div__")) {
- DohSetInt(operators, "__div__", 1);
- have_operators = 1;
- } else if (Strstr(symname, "__mod__")) {
- DohSetInt(operators, "__mod__", 1);
- have_operators = 1;
- } else if (Strstr(symname, "__and__")) {
- DohSetInt(operators, "__and__", 1);
- have_operators = 1;
- } else if (Strstr(symname, "__or__")) {
- DohSetInt(operators, "__or__", 1);
- have_operators = 1;
- } else if (Strstr(symname, "__not__")) {
- DohSetInt(operators, "__not__", 1);
- have_operators = 1;
- } else if (Strstr(symname, "__gt__")) {
- DohSetInt(operators, "__gt__", 1);
- have_operators = 1;
- } else if (Strstr(symname, "__ge__")) {
- DohSetInt(operators, "__ge__", 1);
- have_operators = 1;
- } else if (Strstr(symname, "__lt__")) {
- DohSetInt(operators, "__lt__", 1);
- have_operators = 1;
- } else if (Strstr(symname, "__le__")) {
- DohSetInt(operators, "__le__", 1);
- have_operators = 1;
- } else if (Strstr(symname, "__neg__")) {
- DohSetInt(operators, "__neg__", 1);
- have_operators = 1;
- } else if (Strstr(symname, "__plusplus__")) {
- DohSetInt(operators, "__plusplus__", 1);
- have_operators = 1;
- } else if (Strstr(symname, "__minmin__")) {
- DohSetInt(operators, "__minmin__", 1);
- have_operators = 1;
- } else if (Strstr(symname, "__mineq__")) {
- DohSetInt(operators, "__mineq__", 1);
- have_operators = 1;
- } else if (Strstr(symname, "__pluseq__")) {
- DohSetInt(operators, "__pluseq__", 1);
- have_operators = 1;
- }
-
- if (Getattr(n, "feature:shadow")) {
- String *plcode = perlcode(Getattr(n, "feature:shadow"), 0);
- String *plaction = NewStringf("%s::%s", cmodule, Swig_name_member(NSPACE_TODO, class_name, symname));
- Replaceall(plcode, "$action", plaction);
- Delete(plaction);
- Printv(pcode, plcode, NIL);
- } else {
- Printv(pcode, "*", symname, " = *", cmodule, "::", Swig_name_member(NSPACE_TODO, class_name, symname), ";\n", NIL);
- }
- }
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * membervariableHandler()
- *
- * Adds an instance member.
- * ----------------------------------------------------------------------------- */
-
- virtual int membervariableHandler(Node *n) {
-
- String *symname = Getattr(n, "sym:name");
- /* SwigType *t = Getattr(n,"type"); */
-
- /* Emit a pair of get/set functions for the variable */
-
- member_func = 1;
- Language::membervariableHandler(n);
- member_func = 0;
-
- if (blessed) {
-
- Printv(pcode, "*swig_", symname, "_get = *", cmodule, "::", Swig_name_get(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname)), ";\n", NIL);
- Printv(pcode, "*swig_", symname, "_set = *", cmodule, "::", Swig_name_set(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname)), ";\n", NIL);
-
- /* Now we need to generate a little Perl code for this */
-
- /* if (is_shadow(t)) {
-
- *//* This is a Perl object that we have already seen. Add an
- entry to the members list *//*
- Printv(blessedmembers,
- tab4, symname, " => '", is_shadow(t), "',\n",
- NIL);
-
- }
- */
- }
- have_data_members++;
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * constructorDeclaration()
- *
- * Emits a blessed constructor for our class. In addition to our construct
- * we manage a Perl hash table containing all of the pointers created by
- * the constructor. This prevents us from accidentally trying to free
- * something that wasn't necessarily allocated by malloc or new
- * ------------------------------------------------------------ */
-
- virtual int constructorHandler(Node *n) {
-
- String *symname = Getattr(n, "sym:name");
-
- member_func = 1;
-
- Swig_save("perl5:constructorHandler", n, "parms", NIL);
- if (Swig_directorclass(n)) {
- Parm *parms = Getattr(n, "parms");
- Parm *self;
- String *name = NewString("self");
- String *type = NewString("SV");
- SwigType_add_pointer(type);
- self = NewParm(type, name, n);
- Delete(type);
- Delete(name);
- Setattr(self, "lname", "O");
- if (parms)
- set_nextSibling(self, parms);
- Setattr(n, "parms", self);
- Setattr(n, "wrap:self", "1");
- Setattr(n, "hidden", "1");
- Delete(self);
- }
-
- String *saved_nc = none_comparison;
- none_comparison = NewStringf("strcmp(SvPV_nolen(ST(0)), \"%s::%s\") != 0", module, class_name);
- String *saved_director_prot_ctor_code = director_prot_ctor_code;
- director_prot_ctor_code = NewStringf("if ($comparison) { /* subclassed */\n" " $director_new\n" "} else {\n"
- "SWIG_exception_fail(SWIG_RuntimeError, \"accessing abstract class or protected constructor\");\n" "}\n");
- Language::constructorHandler(n);
- Delete(none_comparison);
- none_comparison = saved_nc;
- Delete(director_prot_ctor_code);
- director_prot_ctor_code = saved_director_prot_ctor_code;
- Swig_restore(n);
-
- if ((blessed) && (!Getattr(n, "sym:nextSibling"))) {
- if (Getattr(n, "feature:shadow")) {
- String *plcode = perlcode(Getattr(n, "feature:shadow"), 0);
- String *plaction = NewStringf("%s::%s", module, Swig_name_member(NSPACE_TODO, class_name, symname));
- Replaceall(plcode, "$action", plaction);
- Delete(plaction);
- Printv(pcode, plcode, NIL);
- } else {
- if ((Cmp(symname, class_name) == 0)) {
- /* Emit a blessed constructor */
- Printf(pcode, "sub new {\n");
- } else {
- /* Constructor doesn't match classname so we'll just use the normal name */
- Printv(pcode, "sub ", Swig_name_construct(NSPACE_TODO, symname), " {\n", NIL);
- }
-
- const char *pkg = getCurrentClass() && Swig_directorclass(getCurrentClass())? "$_[0]" : "shift";
- Printv(pcode,
- tab4, "my $pkg = ", pkg, ";\n",
- tab4, "my $self = ", cmodule, "::", Swig_name_construct(NSPACE_TODO, symname), "(@_);\n", tab4, "bless $self, $pkg if defined($self);\n", "}\n\n", NIL);
-
- have_constructor = 1;
- }
- }
- member_func = 0;
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * destructorHandler()
- * ------------------------------------------------------------ */
-
- virtual int destructorHandler(Node *n) {
- String *symname = Getattr(n, "sym:name");
- member_func = 1;
- Language::destructorHandler(n);
- if (blessed) {
- if (Getattr(n, "feature:shadow")) {
- String *plcode = perlcode(Getattr(n, "feature:shadow"), 0);
- String *plaction = NewStringf("%s::%s", module, Swig_name_member(NSPACE_TODO, class_name, symname));
- Replaceall(plcode, "$action", plaction);
- Delete(plaction);
- Printv(pcode, plcode, NIL);
- } else {
- Printv(pcode,
- "sub DESTROY {\n",
- tab4, "return unless $_[0]->isa('HASH');\n",
- tab4, "my $self = tied(%{$_[0]});\n",
- tab4, "return unless defined $self;\n",
- tab4, "delete $ITERATORS{$self};\n",
- tab4, "if (exists $OWNER{$self}) {\n",
- tab8, cmodule, "::", Swig_name_destroy(NSPACE_TODO, symname), "($self);\n", tab8, "delete $OWNER{$self};\n", tab4, "}\n}\n\n", NIL);
- have_destructor = 1;
- }
- }
- member_func = 0;
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * staticmemberfunctionHandler()
- * ------------------------------------------------------------ */
-
- virtual int staticmemberfunctionHandler(Node *n) {
- member_func = 1;
- Language::staticmemberfunctionHandler(n);
- member_func = 0;
- if ((blessed) && (!Getattr(n, "sym:nextSibling"))) {
- String *symname = Getattr(n, "sym:name");
- Printv(pcode, "*", symname, " = *", cmodule, "::", Swig_name_member(NSPACE_TODO, class_name, symname), ";\n", NIL);
- }
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * staticmembervariableHandler()
- * ------------------------------------------------------------ */
-
- virtual int staticmembervariableHandler(Node *n) {
- Language::staticmembervariableHandler(n);
- if (blessed) {
- String *symname = Getattr(n, "sym:name");
- Printv(pcode, "*", symname, " = *", cmodule, "::", Swig_name_member(NSPACE_TODO, class_name, symname), ";\n", NIL);
- }
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * memberconstantHandler()
- * ------------------------------------------------------------ */
-
- virtual int memberconstantHandler(Node *n) {
- String *symname = Getattr(n, "sym:name");
- int oldblessed = blessed;
-
- /* Create a normal constant */
- blessed = 0;
- Language::memberconstantHandler(n);
- blessed = oldblessed;
-
- if (blessed) {
- Printv(pcode, "*", symname, " = *", cmodule, "::", Swig_name_member(NSPACE_TODO, class_name, symname), ";\n", NIL);
- }
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * pragma()
- *
- * Pragma directive.
- *
- * %pragma(perl5) code="String" # Includes a string in the .pm file
- * %pragma(perl5) include="file.pl" # Includes a file in the .pm file
- * ------------------------------------------------------------ */
-
- virtual int pragmaDirective(Node *n) {
- String *lang;
- String *code;
- String *value;
- if (!ImportMode) {
- lang = Getattr(n, "lang");
- code = Getattr(n, "name");
- value = Getattr(n, "value");
- if (Strcmp(lang, "perl5") == 0) {
- if (Strcmp(code, "code") == 0) {
- /* Dump the value string into the .pm file */
- if (value) {
- Printf(pragma_include, "%s\n", value);
- }
- } else if (Strcmp(code, "include") == 0) {
- /* Include a file into the .pm file */
- if (value) {
- FILE *f = Swig_include_open(value);
- if (!f) {
- Swig_error(input_file, line_number, "Unable to locate file %s\n", value);
- } else {
- char buffer[4096];
- while (fgets(buffer, 4095, f)) {
- Printf(pragma_include, "%s", buffer);
- }
- fclose(f);
- }
- }
- } else {
- Swig_error(input_file, line_number, "Unrecognized pragma.\n");
- }
- }
- }
- return Language::pragmaDirective(n);
- }
-
- /* ------------------------------------------------------------
- * perlcode() - Output perlcode code into the shadow file
- * ------------------------------------------------------------ */
-
- String *perlcode(String *code, const String *indent) {
- String *out = NewString("");
- String *temp;
- char *t;
- if (!indent)
- indent = "";
-
- temp = NewString(code);
-
- t = Char(temp);
- if (*t == '{') {
- Delitem(temp, 0);
- Delitem(temp, DOH_END);
- }
-
- /* Split the input text into lines */
- List *clist = SplitLines(temp);
- Delete(temp);
- int initial = 0;
- String *s = 0;
- Iterator si;
- /* Get the initial indentation */
-
- for (si = First(clist); si.item; si = Next(si)) {
- s = si.item;
- if (Len(s)) {
- char *c = Char(s);
- while (*c) {
- if (!isspace(*c))
- break;
- initial++;
- c++;
- }
- if (*c && !isspace(*c))
- break;
- else {
- initial = 0;
- }
- }
- }
- while (si.item) {
- s = si.item;
- if (Len(s) > initial) {
- char *c = Char(s);
- c += initial;
- Printv(out, indent, c, "\n", NIL);
- } else {
- Printv(out, "\n", NIL);
- }
- si = Next(si);
- }
- Delete(clist);
- return out;
- }
-
- /* ------------------------------------------------------------
- * insertDirective()
- *
- * Hook for %insert directive.
- * ------------------------------------------------------------ */
-
- virtual int insertDirective(Node *n) {
- String *code = Getattr(n, "code");
- String *section = Getattr(n, "section");
-
- if ((!ImportMode) && (Cmp(section, "perl") == 0)) {
- Printv(additional_perl_code, code, NIL);
- } else {
- Language::insertDirective(n);
- }
- return SWIG_OK;
- }
-
- String *runtimeCode() {
- String *s = NewString("");
- String *shead = Swig_include_sys("perlhead.swg");
- if (!shead) {
- Printf(stderr, "*** Unable to open 'perlhead.swg'\n");
- } else {
- Append(s, shead);
- Delete(shead);
- }
- String *serrors = Swig_include_sys("perlerrors.swg");
- if (!serrors) {
- Printf(stderr, "*** Unable to open 'perlerrors.swg'\n");
- } else {
- Append(s, serrors);
- Delete(serrors);
- }
- String *srun = Swig_include_sys("perlrun.swg");
- if (!srun) {
- Printf(stderr, "*** Unable to open 'perlrun.swg'\n");
- } else {
- Append(s, srun);
- Delete(srun);
- }
- return s;
- }
-
- String *defaultExternalRuntimeFilename() {
- return NewString("swigperlrun.h");
- }
-
- virtual int classDirectorInit(Node *n) {
- String *declaration = Swig_director_declaration(n);
- Printf(f_directors_h, "\n");
- Printf(f_directors_h, "%s\n", declaration);
- Printf(f_directors_h, "public:\n");
- Delete(declaration);
- return Language::classDirectorInit(n);
- }
-
- virtual int classDirectorEnd(Node *n) {
- if (dirprot_mode()) {
- /*
- This implementation uses a std::map<std::string,int>.
-
- It should be possible to rewrite it using a more elegant way,
- like copying the Java approach for the 'override' array.
-
- But for now, this seems to be the least intrusive way.
- */
- Printf(f_directors_h, "\n");
- Printf(f_directors_h, "/* Internal director utilities */\n");
- Printf(f_directors_h, "public:\n");
- Printf(f_directors_h, " bool swig_get_inner(const char *swig_protected_method_name) const {\n");
- Printf(f_directors_h, " std::map<std::string, bool>::const_iterator iv = swig_inner.find(swig_protected_method_name);\n");
- Printf(f_directors_h, " return (iv != swig_inner.end() ? iv->second : false);\n");
- Printf(f_directors_h, " }\n");
-
- Printf(f_directors_h, " void swig_set_inner(const char *swig_protected_method_name, bool swig_val) const {\n");
- Printf(f_directors_h, " swig_inner[swig_protected_method_name] = swig_val;\n");
- Printf(f_directors_h, " }\n");
- Printf(f_directors_h, "private:\n");
- Printf(f_directors_h, " mutable std::map<std::string, bool> swig_inner;\n");
- }
- Printf(f_directors_h, "};\n");
- return Language::classDirectorEnd(n);
- }
-
- virtual int classDirectorConstructor(Node *n) {
- Node *parent = Getattr(n, "parentNode");
- String *sub = NewString("");
- String *decl = Getattr(n, "decl");
- String *supername = Swig_class_name(parent);
- String *classname = NewString("");
- Printf(classname, "SwigDirector_%s", supername);
-
- /* insert self parameter */
- Parm *p;
- ParmList *superparms = Getattr(n, "parms");
- ParmList *parms = CopyParmList(superparms);
- String *type = NewString("SV");
- SwigType_add_pointer(type);
- p = NewParm(type, NewString("self"), n);
- set_nextSibling(p, parms);
- parms = p;
-
- if (!Getattr(n, "defaultargs")) {
- /* constructor */
- {
- Wrapper *w = NewWrapper();
- String *call;
- String *basetype = Getattr(parent, "classtype");
- String *target = Swig_method_decl(0, decl, classname, parms, 0);
- call = Swig_csuperclass_call(0, basetype, superparms);
- Printf(w->def, "%s::%s: %s, Swig::Director(self) { \n", classname, target, call);
- Printf(w->def, " SWIG_DIRECTOR_RGTR((%s *)this, this); \n", basetype);
- Append(w->def, "}\n");
- Delete(target);
- Wrapper_print(w, f_directors);
- Delete(call);
- DelWrapper(w);
- }
-
- /* constructor header */
- {
- String *target = Swig_method_decl(0, decl, classname, parms, 1);
- Printf(f_directors_h, " %s;\n", target);
- Delete(target);
- }
- }
-
- Delete(sub);
- Delete(classname);
- Delete(supername);
- Delete(parms);
- return Language::classDirectorConstructor(n);
- }
-
- virtual int classDirectorMethod(Node *n, Node *parent, String *super) {
- int is_void = 0;
- int is_pointer = 0;
- String *decl = Getattr(n, "decl");
- String *name = Getattr(n, "name");
- String *classname = Getattr(parent, "sym:name");
- String *c_classname = Getattr(parent, "name");
- String *symname = Getattr(n, "sym:name");
- String *declaration = NewString("");
- ParmList *l = Getattr(n, "parms");
- Wrapper *w = NewWrapper();
- String *tm;
- String *wrap_args = NewString("");
- String *returntype = Getattr(n, "type");
- String *value = Getattr(n, "value");
- String *storage = Getattr(n, "storage");
- bool pure_virtual = false;
- int status = SWIG_OK;
- int idx;
- bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
-
- if (Cmp(storage, "virtual") == 0) {
- if (Cmp(value, "0") == 0) {
- pure_virtual = true;
- }
- }
-
- /* determine if the method returns a pointer */
- is_pointer = SwigType_ispointer_return(decl);
- is_void = (!Cmp(returntype, "void") && !is_pointer);
-
- /* virtual method definition */
- String *target;
- String *pclassname = NewStringf("SwigDirector_%s", classname);
- String *qualified_name = NewStringf("%s::%s", pclassname, name);
- SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
- target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
- Printf(w->def, "%s", target);
- Delete(qualified_name);
- Delete(target);
- /* header declaration */
- target = Swig_method_decl(rtype, decl, name, l, 1);
- Printf(declaration, " virtual %s", target);
- Delete(target);
-
- // Get any exception classes in the throws typemap
- if (Getattr(n, "noexcept")) {
- Append(w->def, " noexcept");
- Append(declaration, " noexcept");
- }
- ParmList *throw_parm_list = 0;
-
- if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
- Parm *p;
- int gencomma = 0;
-
- Append(w->def, " throw(");
- Append(declaration, " throw(");
-
- if (throw_parm_list)
- Swig_typemap_attach_parms("throws", throw_parm_list, 0);
- for (p = throw_parm_list; p; p = nextSibling(p)) {
- if (Getattr(p, "tmap:throws")) {
- if (gencomma++) {
- Append(w->def, ", ");
- Append(declaration, ", ");
- }
- String *str = SwigType_str(Getattr(p, "type"), 0);
- Append(w->def, str);
- Append(declaration, str);
- Delete(str);
- }
- }
-
- Append(w->def, ")");
- Append(declaration, ")");
- }
-
- Append(w->def, " {");
- Append(declaration, ";\n");
-
- /* declare method return value
- * if the return value is a reference or const reference, a specialized typemap must
- * handle it, including declaration of c_result ($result).
- */
- if (!is_void && (!ignored_method || pure_virtual)) {
- if (!SwigType_isclass(returntype)) {
- if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
- String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
- Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL);
- Delete(construct_result);
- } else {
- Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL);
- }
- } else {
- String *cres = SwigType_lstr(returntype, "c_result");
- Printf(w->code, "%s;\n", cres);
- Delete(cres);
- }
- }
-
- if (!is_void && !ignored_method) {
- String *pres = NewStringf("SV *%s", Swig_cresult_name());
- Wrapper_add_local(w, Swig_cresult_name(), pres);
- Delete(pres);
- }
-
- if (ignored_method) {
- if (!pure_virtual) {
- if (!is_void)
- Printf(w->code, "return ");
- String *super_call = Swig_method_call(super, l);
- Printf(w->code, "%s;\n", super_call);
- Delete(super_call);
- } else {
- Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
- SwigType_namestr(name));
- }
- } else {
- /* attach typemaps to arguments (C/C++ -> Perl) */
- String *parse_args = NewString("");
- String *pstack = NewString("");
-
- Swig_director_parms_fixup(l);
-
- /* remove the wrapper 'w' since it was producing spurious temps */
- Swig_typemap_attach_parms("in", l, 0);
- Swig_typemap_attach_parms("directorin", l, w);
- Swig_typemap_attach_parms("directorargout", l, w);
-
- Wrapper_add_local(w, "SP", "dSP");
-
- {
- String *ptype = Copy(getClassType());
- SwigType_add_pointer(ptype);
- String *mangle = SwigType_manglestr(ptype);
-
- Wrapper_add_local(w, "swigself", "SV *swigself");
- Printf(w->code, "swigself = SWIG_NewPointerObj(SWIG_as_voidptr(this), SWIGTYPE%s, SWIG_SHADOW);\n", mangle);
- Printf(w->code, "sv_bless(swigself, gv_stashpv(swig_get_class(), 0));\n");
- Delete(mangle);
- Delete(ptype);
- Append(pstack, "XPUSHs(swigself);\n");
- }
-
- Parm *p;
- char source[256];
-
- int outputs = 0;
- if (!is_void)
- outputs++;
-
- /* build argument list and type conversion string */
- idx = 0;
- p = l;
- while (p) {
- if (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- continue;
- }
-
- /* old style? caused segfaults without the p!=0 check
- in the for() condition, and seems dangerous in the
- while loop as well.
- while (Getattr(p, "tmap:ignore")) {
- p = Getattr(p, "tmap:ignore:next");
- }
- */
-
- if (Getattr(p, "tmap:directorargout") != 0)
- outputs++;
-
- String *pname = Getattr(p, "name");
- String *ptype = Getattr(p, "type");
-
- if ((tm = Getattr(p, "tmap:directorin")) != 0) {
- sprintf(source, "obj%d", idx++);
- String *input = NewString(source);
- Setattr(p, "emit:directorinput", input);
- Replaceall(tm, "$input", input);
- Delete(input);
- Replaceall(tm, "$owner", "0");
- Replaceall(tm, "$shadow", "0");
- /* Wrapper_add_localv(w, source, "SV *", source, "= 0", NIL); */
- Printv(wrap_args, "SV *", source, ";\n", NIL);
-
- Printv(wrap_args, tm, "\n", NIL);
- Putc('O', parse_args);
- Printv(pstack, "XPUSHs(", source, ");\n", NIL);
- p = Getattr(p, "tmap:directorin:next");
- continue;
- } else if (Cmp(ptype, "void")) {
- /* special handling for pointers to other C++ director classes.
- * ideally this would be left to a typemap, but there is currently no
- * way to selectively apply the dynamic_cast<> to classes that have
- * directors. in other words, the type "SwigDirector_$1_lname" only exists
- * for classes with directors. we avoid the problem here by checking
- * module.wrap::directormap, but it's not clear how to get a typemap to
- * do something similar. perhaps a new default typemap (in addition
- * to SWIGTYPE) called DIRECTORTYPE?
- */
- if (SwigType_ispointer(ptype) || SwigType_isreference(ptype)) {
- Node *module = Getattr(parent, "module");
- Node *target = Swig_directormap(module, ptype);
- sprintf(source, "obj%d", idx++);
- String *nonconst = 0;
- /* strip pointer/reference --- should move to Swig/stype.c */
- String *nptype = NewString(Char(ptype) + 2);
- /* name as pointer */
- String *ppname = Copy(pname);
- if (SwigType_isreference(ptype)) {
- Insert(ppname, 0, "&");
- }
- /* if necessary, cast away const since Perl doesn't support it! */
- if (SwigType_isconst(nptype)) {
- nonconst = NewStringf("nc_tmp_%s", pname);
- String *nonconst_i = NewStringf("= const_cast< %s >(%s)", SwigType_lstr(ptype, 0), ppname);
- Wrapper_add_localv(w, nonconst, SwigType_lstr(ptype, 0), nonconst, nonconst_i, NIL);
- Delete(nonconst_i);
- Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number,
- "Target language argument '%s' discards const in director method %s::%s.\n",
- SwigType_str(ptype, pname), SwigType_namestr(c_classname), SwigType_namestr(name));
- } else {
- nonconst = Copy(ppname);
- }
- Delete(nptype);
- Delete(ppname);
- String *mangle = SwigType_manglestr(ptype);
- if (target) {
- String *director = NewStringf("director_%s", mangle);
- Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL);
- Wrapper_add_localv(w, source, "SV *", source, "= 0", NIL);
- Printf(wrap_args, "%s = SWIG_DIRECTOR_CAST(%s);\n", director, nonconst);
- Printf(wrap_args, "if (!%s) {\n", director);
- Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
- Append(wrap_args, "} else {\n");
- Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director);
- Printf(wrap_args, "SvREFCNT_inc((SV *)%s);\n", source);
- Append(wrap_args, "}\n");
- Delete(director);
- } else {
- Wrapper_add_localv(w, source, "SV *", source, "= 0", NIL);
- Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
- Printf(pstack, "XPUSHs(sv_2mortal(%s));\n", source);
- }
- Putc('O', parse_args);
- Delete(mangle);
- Delete(nonconst);
- } else {
- Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
- "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0),
- SwigType_namestr(c_classname), SwigType_namestr(name));
- status = SWIG_NOWRAP;
- break;
- }
- }
- p = nextSibling(p);
- }
-
- /* add the method name as a PyString */
- String *pyname = Getattr(n, "sym:name");
-
- /* wrap complex arguments to PyObjects */
- Printv(w->code, wrap_args, NIL);
-
- /* pass the method call on to the Python object */
- if (dirprot_mode() && !is_public(n)) {
- Printf(w->code, "swig_set_inner(\"%s\", true);\n", name);
- }
-
- Append(w->code, "ENTER;\n");
- Append(w->code, "SAVETMPS;\n");
- Append(w->code, "PUSHMARK(SP);\n");
- Append(w->code, pstack);
- Delete(pstack);
- Append(w->code, "PUTBACK;\n");
- Printf(w->code, "call_method(\"%s\", G_EVAL | G_SCALAR);\n", pyname);
-
- if (dirprot_mode() && !is_public(n))
- Printf(w->code, "swig_set_inner(\"%s\", false);\n", name);
-
- /* exception handling */
- tm = Swig_typemap_lookup("director:except", n, Swig_cresult_name(), 0);
- if (!tm) {
- tm = Getattr(n, "feature:director:except");
- if (tm)
- tm = Copy(tm);
- }
- Append(w->code, "if (SvTRUE(ERRSV)) {\n");
- Append(w->code, " PUTBACK;\n FREETMPS;\n LEAVE;\n");
- if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
- Replaceall(tm, "$error", "ERRSV");
- Printv(w->code, Str(tm), "\n", NIL);
- } else {
- Printf(w->code, " Swig::DirectorMethodException::raise(ERRSV);\n");
- }
- Append(w->code, "}\n");
- Delete(tm);
-
- /*
- * Python method may return a simple object, or a tuple.
- * for in/out arguments, we have to extract the appropriate PyObjects from the tuple,
- * then marshal everything back to C/C++ (return value and output arguments).
- *
- */
-
- /* marshal return value and other outputs (if any) from PyObject to C/C++ type */
-
- String *cleanup = NewString("");
- String *outarg = NewString("");
-
- if (outputs > 1) {
- Wrapper_add_local(w, "output", "SV *output");
- Printf(w->code, "if (count != %d) {\n", outputs);
- Printf(w->code, " Swig::DirectorTypeMismatchException::raise(\"Perl method %s.%sfailed to return a list.\");\n", classname, pyname);
- Append(w->code, "}\n");
- }
-
- idx = 0;
-
- /* marshal return value */
- if (!is_void) {
- Append(w->code, "SPAGAIN;\n");
- Printf(w->code, "%s = POPs;\n", Swig_cresult_name());
- tm = Swig_typemap_lookup("directorout", n, Swig_cresult_name(), w);
- if (tm != 0) {
- if (outputs > 1) {
- Printf(w->code, "output = POPs;\n");
- Replaceall(tm, "$input", "output");
- } else {
- Replaceall(tm, "$input", Swig_cresult_name());
- }
- char temp[24];
- sprintf(temp, "%d", idx);
- Replaceall(tm, "$argnum", temp);
-
- /* TODO check this */
- if (Getattr(n, "wrap:disown")) {
- Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
- } else {
- Replaceall(tm, "$disown", "0");
- }
- Replaceall(tm, "$result", "c_result");
- Printv(w->code, tm, "\n", NIL);
- Delete(tm);
- } else {
- Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
- "Unable to use return type %s in director method %s::%s (skipping method).\n", SwigType_str(returntype, 0),
- SwigType_namestr(c_classname), SwigType_namestr(name));
- status = SWIG_ERROR;
- }
- }
-
- /* marshal outputs */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
- if (outputs > 1) {
- Printf(w->code, "output = POPs;\n");
- Replaceall(tm, "$result", "output");
- } else {
- Replaceall(tm, "$result", Swig_cresult_name());
- }
- Replaceall(tm, "$input", Getattr(p, "emit:directorinput"));
- Printv(w->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:directorargout:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- Delete(parse_args);
- Delete(cleanup);
- Delete(outarg);
- }
-
- if (!ignored_method) {
- Append(w->code, "PUTBACK;\n");
- Append(w->code, "FREETMPS;\n");
- Append(w->code, "LEAVE;\n");
- }
-
- if (!is_void) {
- if (!(ignored_method && !pure_virtual)) {
- String *rettype = SwigType_str(returntype, 0);
- if (!SwigType_isreference(returntype)) {
- Printf(w->code, "return (%s) c_result;\n", rettype);
- } else {
- Printf(w->code, "return (%s) *c_result;\n", rettype);
- }
- Delete(rettype);
- }
- }
-
- Append(w->code, "}\n");
-
- // We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
- String *inline_extra_method = NewString("");
- if (dirprot_mode() && !is_public(n) && !pure_virtual) {
- Printv(inline_extra_method, declaration, NIL);
- String *extra_method_name = NewStringf("%sSwigPublic", name);
- Replaceall(inline_extra_method, name, extra_method_name);
- Replaceall(inline_extra_method, ";\n", " {\n ");
- if (!is_void)
- Printf(inline_extra_method, "return ");
- String *methodcall = Swig_method_call(super, l);
- Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
- Delete(methodcall);
- Delete(extra_method_name);
- }
-
- /* emit the director method */
- if (status == SWIG_OK) {
- if (!Getattr(n, "defaultargs")) {
- Replaceall(w->code, "$symname", symname);
- Wrapper_print(w, f_directors);
- Printv(f_directors_h, declaration, NIL);
- Printv(f_directors_h, inline_extra_method, NIL);
- }
- }
-
- /* clean up */
- Delete(wrap_args);
- Delete(pclassname);
- DelWrapper(w);
- return status;
- }
- int classDirectorDisown(Node *n) {
- int rv;
- member_func = 1;
- rv = Language::classDirectorDisown(n);
- member_func = 0;
- if (rv == SWIG_OK && Swig_directorclass(n)) {
- String *symname = Getattr(n, "sym:name");
- String *disown = Swig_name_disown(NSPACE_TODO, symname);
- Setattr(n, "perl5:directordisown", NewStringf("%s::%s", cmodule, disown));
- }
- return rv;
- }
- int classDirectorDestructor(Node *n) {
- /* TODO: it would be nice if this didn't have to copy the body of Language::classDirectorDestructor() */
- String *DirectorClassName = directorClassName(getCurrentClass());
- String *body = NewString("\n");
-
- String *ptype = Copy(getClassType());
- SwigType_add_pointer(ptype);
- String *mangle = SwigType_manglestr(ptype);
-
- Printv(body, tab4, "dSP;\n", tab4, "SV *self = SWIG_NewPointerObj(SWIG_as_voidptr(this), SWIGTYPE", mangle, ", SWIG_SHADOW);\n", tab4, "\n", tab4,
- "sv_bless(self, gv_stashpv(swig_get_class(), 0));\n", tab4, "ENTER;\n", tab4, "SAVETMPS;\n", tab4, "PUSHMARK(SP);\n", tab4,
- "XPUSHs(self);\n", tab4, "XPUSHs(&PL_sv_yes);\n", tab4, "PUTBACK;\n", tab4, "call_method(\"DESTROY\", G_EVAL | G_VOID);\n", tab4,
- "FREETMPS;\n", tab4, "LEAVE;\n", NIL);
-
- Delete(mangle);
- Delete(ptype);
-
- if (Getattr(n, "noexcept")) {
- Printf(f_directors_h, " virtual ~%s() noexcept;\n", DirectorClassName);
- Printf(f_directors, "%s::~%s() noexcept {%s}\n\n", DirectorClassName, DirectorClassName, body);
- } else if (Getattr(n, "throw")) {
- Printf(f_directors_h, " virtual ~%s() throw();\n", DirectorClassName);
- Printf(f_directors, "%s::~%s() throw() {%s}\n\n", DirectorClassName, DirectorClassName, body);
- } else {
- Printf(f_directors_h, " virtual ~%s();\n", DirectorClassName);
- Printf(f_directors, "%s::~%s() {%s}\n\n", DirectorClassName, DirectorClassName, body);
- }
- return SWIG_OK;
- }
-};
-
-/* -----------------------------------------------------------------------------
- * swig_perl5() - Instantiate module
- * ----------------------------------------------------------------------------- */
-
-static Language *new_swig_perl5() {
- return new PERL5();
-}
-extern "C" Language *swig_perl5(void) {
- return new_swig_perl5();
-}
diff --git a/contrib/tools/swig/Source/Modules/php.cxx b/contrib/tools/swig/Source/Modules/php.cxx
deleted file mode 100644
index c8cc9212b1..0000000000
--- a/contrib/tools/swig/Source/Modules/php.cxx
+++ /dev/null
@@ -1,2702 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * php.cxx
- *
- * PHP language module for SWIG.
- * -----------------------------------------------------------------------------
- */
-
-#include "swigmod.h"
-#include <algorithm>
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-
-static const char *usage = "\
-PHP Options (available with -php7)\n\
- -prefix <prefix> - Prepend <prefix> to all class names in PHP wrappers\n\
-\n";
-
-// How to wrap non-class functions, variables and constants:
-// FIXME: Make this specifiable and also allow a real namespace.
-
-// Wrap as global PHP names.
-static bool wrap_nonclass_global = true;
-
-// Wrap in a class to fake a namespace (for compatibility with SWIG's behaviour
-// before PHP added namespaces.
-static bool wrap_nonclass_fake_class = true;
-
-static String *module = 0;
-static String *cap_module = 0;
-static String *prefix = 0;
-
-static File *f_begin = 0;
-static File *f_runtime = 0;
-static File *f_runtime_h = 0;
-static File *f_h = 0;
-static File *f_directors = 0;
-static File *f_directors_h = 0;
-
-static String *s_header;
-static String *s_wrappers;
-static String *s_init;
-static String *r_init; // RINIT user code
-static String *s_shutdown; // MSHUTDOWN user code
-static String *r_shutdown; // RSHUTDOWN user code
-static String *s_vdecl;
-static String *s_cinit; // consttab initialization code.
-static String *s_oinit;
-static String *s_arginfo;
-static String *s_entry;
-static String *cs_entry;
-static String *all_cs_entry;
-static String *fake_cs_entry;
-static String *s_creation;
-static String *pragma_incl;
-static String *pragma_code;
-static String *pragma_phpinfo;
-static String *pragma_version;
-
-static String *class_name = NULL;
-static String *base_class = NULL;
-static String *destructor_action = NULL;
-static String *magic_set = NULL;
-static String *magic_get = NULL;
-static String *magic_isset = NULL;
-
-// Class used as pseudo-namespace for compatibility.
-static String *fake_class_name() {
- static String *result = NULL;
- if (!result) {
- result = Len(prefix) ? prefix : module;
- if (!fake_cs_entry) {
- fake_cs_entry = NewStringf("static const zend_function_entry class_%s_functions[] = {\n", result);
- }
-
- Printf(s_creation, "static zend_class_entry *SWIG_Php_ce_%s;\n\n",result);
-
- Printf(s_oinit, " INIT_CLASS_ENTRY(internal_ce, \"%s\", class_%s_functions);\n", result, result);
- Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class(&internal_ce);\n", result);
- Printf(s_oinit, "\n");
- }
- return result;
-}
-
-static String *swig_wrapped_interface_ce() {
- static String *result = NULL;
- if (!result) {
- result = NewStringf("SWIG_Php_swig_wrapped_interface_ce");
- Printf(s_oinit, " INIT_CLASS_ENTRY(%s, \"SWIG\\\\wrapped\", NULL);\n", result);
- }
- return result;
-}
-
-/* To reduce code size (generated and compiled) we only want to emit each
- * different arginfo once, so we need to track which have been used.
- */
-static Hash *arginfo_used;
-
-/* Track non-class pointer types we need to to wrap */
-static Hash *raw_pointer_types = 0;
-
-static int shadow = 1;
-
-// These static variables are used to pass some state from Handlers into functionWrapper
-static enum {
- standard = 0,
- memberfn,
- staticmemberfn,
- membervar,
- staticmembervar,
- constructor,
- destructor,
- directorconstructor,
- directordisown
-} wrapperType = standard;
-
-extern "C" {
- static void (*r_prevtracefunc) (const SwigType *t, String *mangled, String *clientdata) = 0;
-}
-
-static void SwigPHP_emit_pointer_type_registrations() {
- if (!raw_pointer_types)
- return;
-
- Iterator ki = First(raw_pointer_types);
- if (!ki.key)
- return;
-
- Printf(s_wrappers, "/* class object handlers for pointer wrappers */\n");
- Printf(s_wrappers, "static zend_object_handlers swig_ptr_object_handlers;\n\n");
-
- Printf(s_wrappers, "/* Object Creation Method for pointer wrapping class */\n");
- Printf(s_wrappers, "static zend_object *swig_ptr_object_new(zend_class_entry *ce) {\n");
- Printf(s_wrappers, " swig_object_wrapper *obj = (swig_object_wrapper*)zend_object_alloc(sizeof(swig_object_wrapper), ce);\n");
- Printf(s_wrappers, " zend_object_std_init(&obj->std, ce);\n");
- Printf(s_wrappers, " object_properties_init(&obj->std, ce);\n");
- Printf(s_wrappers, " obj->std.handlers = &swig_ptr_object_handlers;\n");
- Printf(s_wrappers, " obj->newobject = 0;\n");
- Printf(s_wrappers, " return &obj->std;\n");
- Printf(s_wrappers, "}\n\n");
-
- Printf(s_wrappers, "/* Implement __toString equivalent, since that worked for the old-style resource wrapped pointers. */\n");
- Append(s_wrappers, "#if PHP_MAJOR_VERSION < 8\n");
- Printf(s_wrappers, "static int swig_ptr_cast_object(zval *z, zval *retval, int type) {\n");
- Append(s_wrappers, "#elif PHP_MAJOR_VERSION > 8 || PHP_MINOR_VERSION >= 2\n");
- Printf(s_wrappers, "static ZEND_RESULT_CODE swig_ptr_cast_object(zend_object *zobj, zval *retval, int type) {\n");
- Append(s_wrappers, "#else\n");
- Printf(s_wrappers, "static int swig_ptr_cast_object(zend_object *zobj, zval *retval, int type) {\n");
- Append(s_wrappers, "#endif\n");
- Printf(s_wrappers, " if (type == IS_STRING) {\n");
- Append(s_wrappers, "#if PHP_MAJOR_VERSION < 8\n");
- Printf(s_wrappers, " swig_object_wrapper *obj = SWIG_Z_FETCH_OBJ_P(z);\n");
- Append(s_wrappers, "#else\n");
- Printf(s_wrappers, " swig_object_wrapper *obj = swig_php_fetch_object(zobj);\n");
- Append(s_wrappers, "#endif\n");
- Printv(s_wrappers, " ZVAL_NEW_STR(retval, zend_strpprintf(0, \"SWIGPointer(%p,owned=%d)\", obj->ptr, obj->newobject));\n", NIL);
- Printf(s_wrappers, " return SUCCESS;\n");
- Printf(s_wrappers, " }\n");
- Printf(s_wrappers, " return FAILURE;\n");
- Printf(s_wrappers, "}\n\n");
-
- Printf(s_oinit, "\n /* Register classes to represent non-class pointer types */\n");
- Printf(s_oinit, " swig_ptr_object_handlers = *zend_get_std_object_handlers();\n");
- Printf(s_oinit, " swig_ptr_object_handlers.offset = XtOffsetOf(swig_object_wrapper, std);\n");
- Printf(s_oinit, " swig_ptr_object_handlers.cast_object = swig_ptr_cast_object;\n");
-
- while (ki.key) {
- String *type = ki.key;
-
- String *swig_wrapped = swig_wrapped_interface_ce();
- Printf(s_creation, "/* class entry for pointer to %s */\n", type);
- Printf(s_creation, "static zend_class_entry *SWIG_Php_ce_%s;\n\n", type);
-
- Printf(s_oinit, " INIT_CLASS_ENTRY(internal_ce, \"%s\\\\%s\", NULL);\n", "SWIG", type);
- Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class(&internal_ce);\n", type);
- Printf(s_oinit, " SWIG_Php_ce_%s->create_object = swig_ptr_object_new;\n", type);
- Printv(s_oinit, " zend_do_implement_interface(SWIG_Php_ce_", type, ", &", swig_wrapped, ");\n", NIL);
- Printf(s_oinit, " SWIG_TypeClientData(SWIGTYPE%s,SWIG_Php_ce_%s);\n", type, type);
- Printf(s_oinit, "\n");
-
- ki = Next(ki);
- }
-}
-
-static Hash *create_php_type_flags() {
- Hash *h = NewHash();
- Setattr(h, "array", "MAY_BE_ARRAY");
- Setattr(h, "bool", "MAY_BE_BOOL");
- Setattr(h, "callable", "MAY_BE_CALLABLE");
- Setattr(h, "float", "MAY_BE_DOUBLE");
- Setattr(h, "int", "MAY_BE_LONG");
- Setattr(h, "iterable", "MAY_BE_ITERABLE");
- Setattr(h, "mixed", "MAY_BE_MIXED");
- Setattr(h, "null", "MAY_BE_NULL");
- Setattr(h, "object", "MAY_BE_OBJECT");
- Setattr(h, "resource", "MAY_BE_RESOURCE");
- Setattr(h, "string", "MAY_BE_STRING");
- Setattr(h, "void", "MAY_BE_VOID");
- return h;
-}
-
-static Hash *php_type_flags = create_php_type_flags();
-
-// php_class + ":" + php_method -> PHPTypes*
-// ":" + php_function -> PHPTypes*
-static Hash *all_phptypes = NewHash();
-
-// php_class_name -> php_parent_class_name
-static Hash *php_parent_class = NewHash();
-
-// Track if a method is directed in a descendent class.
-// php_class + ":" + php_method -> boolean (using SetFlag()/GetFlag()).
-static Hash *has_directed_descendent = NewHash();
-
-// Track required return type for parent class methods.
-// php_class + ":" + php_method -> List of php types.
-static Hash *parent_class_method_return_type = NewHash();
-
-// Class encapsulating the machinery to add PHP type declarations.
-class PHPTypes {
- // List with an entry for each parameter and one for the return type.
- //
- // We assemble the types in here before emitting them so for an overloaded
- // function we combine the type declarations from each overloaded form.
- List *merged_types;
-
- // List with an entry for each parameter which is passed "byref" in any
- // overloaded form. We use this to pass such parameters by reference in
- // the dispatch function. If NULL, no parameters are passed by reference.
- List *byref;
-
- // The id string used in the name of the arginfo for this object.
- String *arginfo_id;
-
- // The feature:php:type value: 0, 1 or -1 for "compatibility".
- int php_type_flag;
-
- // Does the node for this have directorNode set?
- bool has_director_node;
-
- // Used to clamp the required number of parameters in the arginfo to be
- // compatible with any parent class version of the method.
- int num_required;
-
- int get_byref(int key) const {
- return byref && key < Len(byref) && Getitem(byref, key) != None;
- }
-
- int size() const {
- return std::max(Len(merged_types), Len(byref));
- }
-
- String *get_phptype(int key, String *classtypes, List *more_return_types = NULL) {
- Clear(classtypes);
- // We want to minimise the list of class types by not redundantly listing
- // a class for which a super-class is also listed. This canonicalisation
- // allows for more sharing of arginfo (which reduces module size), makes
- // for a cleaner list if it's shown to the user, and also will speed up
- // module load a bit.
- Hash *classes = NewHash();
- DOH *types = Getitem(merged_types, key);
- String *result = NewStringEmpty();
- if (more_return_types) {
- if (types != None) {
- merge_type_lists(types, more_return_types);
- }
- }
- if (types != None) {
- SortList(types, NULL);
- String *prev = NULL;
- for (Iterator i = First(types); i.item; i = Next(i)) {
- if (prev && Equal(prev, i.item)) {
- // Skip duplicates when merging.
- continue;
- }
- String *c = Getattr(php_type_flags, i.item);
- if (c) {
- if (Len(result) > 0) Append(result, "|");
- Append(result, c);
- } else {
- SetFlag(classes, i.item);
- }
- prev = i.item;
- }
- }
-
- // Remove entries for which a super-class is also listed.
- Iterator i = First(classes);
- while (i.key) {
- String *this_class = i.key;
- // We must advance the iterator early so we don't delete the element it
- // points to.
- i = Next(i);
- String *parent = this_class;
- while ((parent = Getattr(php_parent_class, parent)) != NULL) {
- if (GetFlag(classes, parent)) {
- Delattr(classes, this_class);
- break;
- }
- }
- }
-
- List *sorted_classes = SortedKeys(classes, Strcmp);
- for (i = First(sorted_classes); i.item; i = Next(i)) {
- if (Len(classtypes) > 0) Append(classtypes, "|");
- Append(classtypes, prefix);
- Append(classtypes, i.item);
- }
- Delete(sorted_classes);
-
- // Make the mask 0 if there are only class names specified.
- if (Len(result) == 0) {
- Append(result, "0");
- }
- return result;
- }
-
-public:
- PHPTypes(Node *n)
- : merged_types(NewList()),
- byref(NULL),
- num_required(INT_MAX) {
- String *php_type_feature = Getattr(n, "feature:php:type");
- php_type_flag = 0;
- if (php_type_feature != NULL) {
- if (Equal(php_type_feature, "1")) {
- php_type_flag = 1;
- } else if (!Equal(php_type_feature, "0")) {
- php_type_flag = -1;
- }
- }
- arginfo_id = Copy(Getattr(n, "sym:name"));
- has_director_node = (Getattr(n, "directorNode") != NULL);
- }
-
- ~PHPTypes() {
- Delete(merged_types);
- Delete(byref);
- }
-
- void adjust(int num_required_, bool php_constructor) {
- num_required = std::min(num_required, num_required_);
- if (php_constructor) {
- // Don't add a return type declaration for a PHP __construct method
- // (because there it has no return type as far as PHP is concerned).
- php_type_flag = 0;
- }
- }
-
- String *get_arginfo_id() const {
- return arginfo_id;
- }
-
- // key is 0 for return type, or >= 1 for parameters numbered from 1
- List *process_phptype(Node *n, int key, const String_or_char *attribute_name);
-
- // Merge entries from o_merge_list into merge_list, skipping any entries
- // already present.
- //
- // Both merge_list and o_merge_list should be in sorted order.
- static void merge_type_lists(List *merge_list, List *o_merge_list);
-
- void merge_from(const PHPTypes* o);
-
- void set_byref(int key) {
- if (!byref) {
- byref = NewList();
- }
- while (Len(byref) <= key) {
- Append(byref, None);
- }
- // If any overload takes a particular parameter by reference then the
- // dispatch function also needs to take that parameter by reference so
- // we can just set unconditionally here.
- Setitem(byref, key, ""); // Just needs to be something != None.
- }
-
- void emit_arginfo(DOH *item, String *key) {
- Setmark(item, 1);
- char *colon_ptr = Strchr(key, ':');
- assert(colon_ptr);
- int colon = (int)(colon_ptr - Char(key));
- if (colon > 0 && Strcmp(colon_ptr + 1, "__construct") != 0) {
- // See if there's a parent class which implements this method, and if so
- // emit its arginfo and then merge its PHPTypes into ours as we need to
- // be compatible with it (whether it is virtual or not).
- String *this_class = NewStringWithSize(Char(key), colon);
- String *parent = this_class;
- while ((parent = Getattr(php_parent_class, parent)) != NULL) {
- String *k = NewStringf("%s%s", parent, colon_ptr);
- DOH *item = Getattr(all_phptypes, k);
- if (item) {
- PHPTypes *p = (PHPTypes*)Data(item);
- if (!Getmark(item)) {
- p->emit_arginfo(item, k);
- }
- merge_from(p);
- Delete(k);
- break;
- }
- Delete(k);
- }
- Delete(this_class);
- }
-
- // We want to only emit each different arginfo once, as that reduces the
- // size of both the generated source code and the compiled extension
- // module. The parameters at this level are just named arg1, arg2, etc
- // so the arginfo will be the same for any function with the same number
- // of parameters and (if present) PHP type declarations for parameters and
- // return type.
- //
- // We generate the arginfo we want (taking care to normalise, e.g. the
- // lists of types are unique and in sorted order), then use the
- // arginfo_used Hash to see if we've already generated it.
- String *out_phptype = NULL;
- String *out_phpclasses = NewStringEmpty();
-
- // We provide a simple way to generate PHP return type declarations
- // except for directed methods. The point of directors is to allow
- // subclassing in the target language, and if the wrapped method has
- // a return type declaration then an overriding method in user code
- // needs to have a compatible declaration.
- //
- // The upshot of this is that enabling return type declarations for
- // existing bindings would break compatibility with user code written
- // for an older version. For parameters however the situation is
- // different because if the parent class declares types for parameters
- // a subclass overriding the function will be compatible whether it
- // declares them or not.
- //
- // directorNode being present seems to indicate if this method or one
- // it inherits from is directed, which is what we care about here.
- // Using (!is_member_director(n)) would get it wrong for testcase
- // director_frob.
- if (php_type_flag && (php_type_flag > 0 || !has_director_node)) {
- if (!GetFlag(has_directed_descendent, key)) {
- out_phptype = get_phptype(0, out_phpclasses, Getattr(parent_class_method_return_type, key));
- }
- }
-
- // ### in arginfo_code will be replaced with the id once that is known.
- String *arginfo_code = NewStringEmpty();
- if (out_phptype) {
- if (Len(out_phpclasses)) {
- Replace(out_phpclasses, "\\", "\\\\", DOH_REPLACE_ANY);
- Printf(arginfo_code, "ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(swig_arginfo_###, 0, %d, %s, %s)\n", num_required, out_phpclasses, out_phptype);
- } else {
- Printf(arginfo_code, "ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(swig_arginfo_###, 0, %d, %s)\n", num_required, out_phptype);
- }
- } else {
- Printf(arginfo_code, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_###, 0, 0, %d)\n", num_required);
- }
-
- int phptypes_size = size();
- for (int param_count = 1; param_count < phptypes_size; ++param_count) {
- String *phpclasses = NewStringEmpty();
- String *phptype = get_phptype(param_count, phpclasses);
-
- int byref = get_byref(param_count);
-
- // FIXME: Should we be doing byref for return value as well?
-
- if (phptype) {
- if (Len(phpclasses)) {
- // We need to double any backslashes (which are PHP namespace
- // separators) in the PHP class names as they get turned into
- // C strings by the ZEND_ARG_OBJ_TYPE_MASK macro.
- Replace(phpclasses, "\\", "\\\\", DOH_REPLACE_ANY);
- Printf(arginfo_code, " ZEND_ARG_OBJ_TYPE_MASK(%d,arg%d,%s,%s,NULL)\n", byref, param_count, phpclasses, phptype);
- } else {
- Printf(arginfo_code, " ZEND_ARG_TYPE_MASK(%d,arg%d,%s,NULL)\n", byref, param_count, phptype);
- }
- } else {
- Printf(arginfo_code, " ZEND_ARG_INFO(%d,arg%d)\n", byref, param_count);
- }
- }
- Printf(arginfo_code, "ZEND_END_ARG_INFO()\n");
-
- String *arginfo_id_same = Getattr(arginfo_used, arginfo_code);
- if (arginfo_id_same) {
- Printf(s_arginfo, "#define swig_arginfo_%s swig_arginfo_%s\n", arginfo_id, arginfo_id_same);
- } else {
- // Not had this arginfo before.
- Setattr(arginfo_used, arginfo_code, arginfo_id);
- arginfo_code = Copy(arginfo_code);
- Replace(arginfo_code, "###", arginfo_id, DOH_REPLACE_FIRST);
- Append(s_arginfo, arginfo_code);
- }
- Delete(arginfo_code);
- arginfo_code = NULL;
- }
-};
-
-static PHPTypes *phptypes = NULL;
-
-class PHP : public Language {
-public:
- PHP() {
- director_language = 1;
- }
-
- /* ------------------------------------------------------------
- * main()
- * ------------------------------------------------------------ */
-
- virtual void main(int argc, char *argv[]) {
- SWIG_library_directory("php");
-
- for (int i = 1; i < argc; i++) {
- if (strcmp(argv[i], "-prefix") == 0) {
- if (argv[i + 1]) {
- prefix = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if ((strcmp(argv[i], "-noshadow") == 0)) {
- shadow = 0;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-help") == 0) {
- fputs(usage, stdout);
- }
- }
-
- Preprocessor_define("SWIGPHP 1", 0);
- Preprocessor_define("SWIGPHP7 1", 0);
- SWIG_typemap_lang("php");
- SWIG_config_file("php.swg");
- allow_overloading();
- }
-
- /* ------------------------------------------------------------
- * top()
- * ------------------------------------------------------------ */
-
- virtual int top(Node *n) {
-
- String *filen;
-
- /* Check if directors are enabled for this module. */
- Node *mod = Getattr(n, "module");
- if (mod) {
- Node *options = Getattr(mod, "options");
- if (options && Getattr(options, "directors")) {
- allow_directors();
- }
- }
-
- /* Set comparison with null for ConstructorToFunction */
- setSubclassInstanceCheck(NewString("Z_TYPE_P($arg) != IS_NULL"));
-
- /* Initialize all of the output files */
- String *outfile = Getattr(n, "outfile");
- String *outfile_h = Getattr(n, "outfile_h");
-
- /* main output file */
- f_begin = NewFile(outfile, "w", SWIG_output_files());
- if (!f_begin) {
- FileErrorDisplay(outfile);
- Exit(EXIT_FAILURE);
- }
- f_runtime = NewStringEmpty();
-
- /* sections of the output file */
- s_init = NewStringEmpty();
- r_init = NewStringEmpty();
- s_shutdown = NewStringEmpty();
- r_shutdown = NewStringEmpty();
- s_header = NewString("/* header section */\n");
- s_wrappers = NewString("/* wrapper section */\n");
- s_creation = NewStringEmpty();
- /* subsections of the init section */
- s_vdecl = NewString("/* vdecl subsection */\n");
- s_cinit = NewString(" /* cinit subsection */\n");
- s_oinit = NewString(" /* oinit subsection */\n");
- pragma_phpinfo = NewStringEmpty();
- f_directors_h = NewStringEmpty();
- f_directors = NewStringEmpty();
-
- if (directorsEnabled()) {
- f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
- if (!f_runtime_h) {
- FileErrorDisplay(outfile_h);
- Exit(EXIT_FAILURE);
- }
- }
-
- /* Register file targets with the SWIG file handler */
- Swig_register_filebyname("begin", f_begin);
- Swig_register_filebyname("runtime", f_runtime);
- Swig_register_filebyname("init", s_init);
- Swig_register_filebyname("rinit", r_init);
- Swig_register_filebyname("shutdown", s_shutdown);
- Swig_register_filebyname("rshutdown", r_shutdown);
- Swig_register_filebyname("header", s_header);
- Swig_register_filebyname("wrapper", s_wrappers);
- Swig_register_filebyname("director", f_directors);
- Swig_register_filebyname("director_h", f_directors_h);
-
- Swig_banner(f_begin);
-
- Swig_obligatory_macros(f_runtime, "PHP");
-
- if (directorsEnabled()) {
- Printf(f_runtime, "#define SWIG_DIRECTORS\n");
- }
-
- // We need to include php.h before string.h gets included, at least with
- // PHP 8.2. Otherwise string.h is included without _GNU_SOURCE being
- // included and memrchr() doesn't get declared, and then inline code in
- // the PHP headers defines _GNU_SOURCE, includes string.h (which is a
- // no op thanks to the include gaurds), then tries to use memrchr() and
- // fails.
- //
- // We also need to suppress -Wdeclaration-after-statement if enabled
- // since with PHP 8.2 zend_operators.h contains inline code which triggers
- // this warning and our testsuite uses with option and -Werror. I don't
- // see a good way to only do this within our testsuite, but disabling
- // it globally like this shouldn't be problematic.
- Append(f_runtime,
- "\n"
- "#if defined __GNUC__ && !defined __cplusplus\n"
- "# if __GNUC__ >= 4\n"
- "# pragma GCC diagnostic push\n"
- "# pragma GCC diagnostic ignored \"-Wdeclaration-after-statement\"\n"
- "# endif\n"
- "#endif\n"
- "#include \"php.h\"\n"
- "#if defined __GNUC__ && !defined __cplusplus\n"
- "# if __GNUC__ >= 4\n"
- "# pragma GCC diagnostic pop\n"
- "# endif\n"
- "#endif\n\n");
-
- /* Set the module name */
- module = Copy(Getattr(n, "name"));
- cap_module = NewStringf("%(upper)s", module);
- if (!prefix)
- prefix = NewStringEmpty();
-
- if (directorsEnabled()) {
- Swig_banner(f_directors_h);
- Printf(f_directors_h, "\n");
- Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", cap_module);
- Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", cap_module);
-
- String *filename = Swig_file_filename(outfile_h);
- Printf(f_directors, "\n#include \"%s\"\n\n", filename);
- Delete(filename);
- }
-
- /* sub-sections of the php file */
- pragma_code = NewStringEmpty();
- pragma_incl = NewStringEmpty();
- pragma_version = NULL;
-
- /* Initialize the rest of the module */
-
- /* start the header section */
- Printf(s_header, "#define SWIG_name \"%s\"\n", module);
- Printf(s_header, "#ifdef __cplusplus\n");
- Printf(s_header, "extern \"C\" {\n");
- Printf(s_header, "#endif\n");
- Printf(s_header, "#include \"php_ini.h\"\n");
- Printf(s_header, "#include \"ext/standard/info.h\"\n");
- Printf(s_header, "#include \"php_%s.h\"\n", module);
- Printf(s_header, "#ifdef __cplusplus\n");
- Printf(s_header, "}\n");
- Printf(s_header, "#endif\n\n");
-
- if (directorsEnabled()) {
- // Insert director runtime
- Swig_insert_file("director_common.swg", s_header);
- Swig_insert_file("director.swg", s_header);
- }
-
- /* Create the .h file too */
- filen = NewStringEmpty();
- Printv(filen, SWIG_output_directory(), "php_", module, ".h", NIL);
- f_h = NewFile(filen, "w", SWIG_output_files());
- if (!f_h) {
- FileErrorDisplay(filen);
- Exit(EXIT_FAILURE);
- }
-
- Swig_banner(f_h);
-
- Printf(f_h, "\n");
- Printf(f_h, "#ifndef PHP_%s_H\n", cap_module);
- Printf(f_h, "#define PHP_%s_H\n\n", cap_module);
- Printf(f_h, "extern zend_module_entry %s_module_entry;\n", module);
- Printf(f_h, "#define phpext_%s_ptr &%s_module_entry\n\n", module, module);
- Printf(f_h, "#ifdef PHP_WIN32\n");
- Printf(f_h, "# define PHP_%s_API __declspec(dllexport)\n", cap_module);
- Printf(f_h, "#else\n");
- Printf(f_h, "# define PHP_%s_API\n", cap_module);
- Printf(f_h, "#endif\n\n");
-
- /* start the arginfo section */
- s_arginfo = NewString("/* arginfo subsection */\n");
- arginfo_used = NewHash();
-
- /* start the function entry section */
- s_entry = NewString("/* entry subsection */\n");
-
- /* holds all the per-class function entry sections */
- all_cs_entry = NewString("/* class entry subsection */\n");
- cs_entry = NULL;
- fake_cs_entry = NULL;
-
- Printf(s_entry, "/* Every non-class user visible function must have an entry here */\n");
- Printf(s_entry, "static const zend_function_entry module_%s_functions[] = {\n", module);
-
- /* Emit all of the code */
- Language::top(n);
-
- /* Emit all the arginfo. We sort the keys so the output order doesn't depend on
- * hashkey order.
- */
- {
- List *sorted_keys = SortedKeys(all_phptypes, Strcmp);
- for (Iterator k = First(sorted_keys); k.item; k = Next(k)) {
- DOH *val = Getattr(all_phptypes, k.item);
- if (!Getmark(val)) {
- PHPTypes *p = (PHPTypes*)Data(val);
- p->emit_arginfo(val, k.item);
- }
- }
- Delete(sorted_keys);
- }
-
- SwigPHP_emit_pointer_type_registrations();
- Dump(s_creation, s_header);
- Delete(s_creation);
- s_creation = NULL;
-
- /* start the init section */
- {
- String *s_init_old = s_init;
- s_init = NewString("/* init section */\n");
- Printv(s_init, "zend_module_entry ", module, "_module_entry = {\n", NIL);
- Printf(s_init, " STANDARD_MODULE_HEADER,\n");
- Printf(s_init, " \"%s\",\n", module);
- Printf(s_init, " module_%s_functions,\n", module);
- Printf(s_init, " PHP_MINIT(%s),\n", module);
- if (Len(s_shutdown) > 0) {
- Printf(s_init, " PHP_MSHUTDOWN(%s),\n", module);
- } else {
- Printf(s_init, " NULL, /* No MSHUTDOWN code */\n");
- }
- if (Len(r_init) > 0) {
- Printf(s_init, " PHP_RINIT(%s),\n", module);
- } else {
- Printf(s_init, " NULL, /* No RINIT code */\n");
- }
- if (Len(r_shutdown) > 0) {
- Printf(s_init, " PHP_RSHUTDOWN(%s),\n", module);
- } else {
- Printf(s_init, " NULL, /* No RSHUTDOWN code */\n");
- }
- if (Len(pragma_phpinfo) > 0) {
- Printf(s_init, " PHP_MINFO(%s),\n", module);
- } else {
- Printf(s_init, " NULL, /* No MINFO code */\n");
- }
- if (Len(pragma_version) > 0) {
- Printf(s_init, " \"%s\",\n", pragma_version);
- } else {
- Printf(s_init, " NO_VERSION_YET,\n");
- }
- Printf(s_init, " STANDARD_MODULE_PROPERTIES\n");
- Printf(s_init, "};\n\n");
-
- Printf(s_init, "#ifdef __cplusplus\n");
- Printf(s_init, "extern \"C\" {\n");
- Printf(s_init, "#endif\n");
- // We want to write "SWIGEXPORT ZEND_GET_MODULE(%s)" but ZEND_GET_MODULE
- // in PHP7 has "extern "C" { ... }" around it so we can't do that.
- Printf(s_init, "SWIGEXPORT zend_module_entry *get_module(void) { return &%s_module_entry; }\n", module);
- Printf(s_init, "#ifdef __cplusplus\n");
- Printf(s_init, "}\n");
- Printf(s_init, "#endif\n\n");
-
- Printf(s_init, "#define SWIG_php_minit PHP_MINIT_FUNCTION(%s)\n\n", module);
-
- Printv(s_init, s_init_old, NIL);
- Delete(s_init_old);
- }
-
- /* We have to register the constants before they are (possibly) used
- * by the pointer typemaps. This all needs re-arranging really as
- * things are being called in the wrong order
- */
-
- Printf(s_oinit, " /* end oinit subsection */\n");
- Printf(s_init, "%s\n", s_oinit);
-
- /* Constants generated during top call */
- Printf(s_cinit, " /* end cinit subsection */\n");
- Printf(s_init, "%s\n", s_cinit);
- Clear(s_cinit);
- Delete(s_cinit);
-
- Printf(s_init, " return SUCCESS;\n");
- Printf(s_init, "}\n\n");
-
- // Now do REQUEST init which holds any user specified %rinit, and also vinit
- if (Len(r_init) > 0) {
- Printf(f_h, "PHP_RINIT_FUNCTION(%s);\n", module);
-
- Printf(s_init, "PHP_RINIT_FUNCTION(%s)\n{\n", module);
- Printv(s_init,
- "/* rinit section */\n",
- r_init, "\n",
- NIL);
-
- Printf(s_init, " return SUCCESS;\n");
- Printf(s_init, "}\n\n");
- }
-
- Printf(f_h, "PHP_MINIT_FUNCTION(%s);\n", module);
-
- if (Len(s_shutdown) > 0) {
- Printf(f_h, "PHP_MSHUTDOWN_FUNCTION(%s);\n", module);
-
- Printv(s_init, "PHP_MSHUTDOWN_FUNCTION(", module, ")\n"
- "/* shutdown section */\n"
- "{\n",
- s_shutdown,
- " return SUCCESS;\n"
- "}\n\n", NIL);
- }
-
- if (Len(r_shutdown) > 0) {
- Printf(f_h, "PHP_RSHUTDOWN_FUNCTION(%s);\n", module);
-
- Printf(s_init, "PHP_RSHUTDOWN_FUNCTION(%s)\n{\n", module);
- Printf(s_init, "/* rshutdown section */\n");
- Printf(s_init, "%s\n", r_shutdown);
- Printf(s_init, " return SUCCESS;\n");
- Printf(s_init, "}\n\n");
- }
-
- if (Len(pragma_phpinfo) > 0) {
- Printf(f_h, "PHP_MINFO_FUNCTION(%s);\n", module);
-
- Printf(s_init, "PHP_MINFO_FUNCTION(%s)\n{\n", module);
- Printf(s_init, "%s", pragma_phpinfo);
- Printf(s_init, "}\n");
- }
-
- Printf(s_init, "/* end init section */\n");
-
- Printf(f_h, "\n#endif /* PHP_%s_H */\n", cap_module);
-
- Delete(f_h);
-
- String *type_table = NewStringEmpty();
- SwigType_emit_type_table(f_runtime, type_table);
- Printf(s_header, "%s", type_table);
- Delete(type_table);
-
- /* Oh dear, more things being called in the wrong order. This whole
- * function really needs totally redoing.
- */
-
- if (directorsEnabled()) {
- Dump(f_directors_h, f_runtime_h);
- Printf(f_runtime_h, "\n");
- Printf(f_runtime_h, "#endif\n");
- Delete(f_runtime_h);
- }
-
- Printf(s_header, "/* end header section */\n");
- Printf(s_wrappers, "/* end wrapper section */\n");
- Printf(s_vdecl, "/* end vdecl subsection */\n");
-
- Dump(f_runtime, f_begin);
- Printv(f_begin, s_header, NIL);
- if (directorsEnabled()) {
- Dump(f_directors, f_begin);
- }
- Printv(f_begin, s_vdecl, s_wrappers, NIL);
- Printv(f_begin, s_arginfo, "\n\n", all_cs_entry, "\n\n", s_entry,
- " ZEND_FE_END\n};\n\n", NIL);
- if (fake_cs_entry) {
- Printv(f_begin, fake_cs_entry, " ZEND_FE_END\n};\n\n", NIL);
- Delete(fake_cs_entry);
- fake_cs_entry = NULL;
- }
- Printv(f_begin, s_init, NIL);
- Delete(s_header);
- Delete(s_wrappers);
- Delete(s_init);
- Delete(s_vdecl);
- Delete(all_cs_entry);
- Delete(s_entry);
- Delete(s_arginfo);
- Delete(f_runtime);
- Delete(f_begin);
- Delete(arginfo_used);
-
- if (Len(pragma_incl) > 0 || Len(pragma_code) > 0) {
- /* PHP module file */
- String *php_filename = NewStringEmpty();
- Printv(php_filename, SWIG_output_directory(), module, ".php", NIL);
-
- File *f_phpcode = NewFile(php_filename, "w", SWIG_output_files());
- if (!f_phpcode) {
- FileErrorDisplay(php_filename);
- Exit(EXIT_FAILURE);
- }
-
- Printf(f_phpcode, "<?php\n\n");
-
- if (Len(pragma_incl) > 0) {
- Printv(f_phpcode, pragma_incl, "\n", NIL);
- }
-
- if (Len(pragma_code) > 0) {
- Printv(f_phpcode, pragma_code, "\n", NIL);
- }
-
- Delete(f_phpcode);
- Delete(php_filename);
- }
-
- return SWIG_OK;
- }
-
- /* Just need to append function names to function table to register with PHP. */
- void create_command(String *cname, String *fname, Node *n, bool dispatch, String *modes = NULL) {
- // This is for the single main zend_function_entry record
- ParmList *l = Getattr(n, "parms");
- if (cname && !Equal(Getattr(n, "storage"), "friend")) {
- Printf(f_h, "static PHP_METHOD(%s%s,%s);\n", prefix, cname, fname);
- if (wrapperType != staticmemberfn &&
- wrapperType != staticmembervar &&
- !Equal(fname, "__construct")) {
- // Skip the first entry in the parameter list which is the this pointer.
- if (l) l = Getattr(l, "tmap:in:next");
- // FIXME: does this throw the phptype key value off?
- }
- } else {
- if (dispatch) {
- Printf(f_h, "static ZEND_NAMED_FUNCTION(%s);\n", fname);
- } else {
- Printf(f_h, "static PHP_FUNCTION(%s);\n", fname);
- }
- }
-
- phptypes->adjust(emit_num_required(l), Equal(fname, "__construct") ? true : false);
-
- String *arginfo_id = phptypes->get_arginfo_id();
- String *s = cs_entry;
- if (!s) s = s_entry;
- if (cname && !Equal(Getattr(n, "storage"), "friend")) {
- Printf(all_cs_entry, " PHP_ME(%s%s,%s,swig_arginfo_%s,%s)\n", prefix, cname, fname, arginfo_id, modes);
- } else {
- if (dispatch) {
- if (wrap_nonclass_global) {
- Printf(s, " ZEND_NAMED_FE(%(lower)s,%s,swig_arginfo_%s)\n", Getattr(n, "sym:name"), fname, arginfo_id);
- }
-
- if (wrap_nonclass_fake_class) {
- (void)fake_class_name();
- Printf(fake_cs_entry, " ZEND_NAMED_ME(%(lower)s,%s,swig_arginfo_%s,ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)\n", Getattr(n, "sym:name"), fname, arginfo_id);
- }
- } else {
- if (wrap_nonclass_global) {
- Printf(s, " PHP_FE(%s,swig_arginfo_%s)\n", fname, arginfo_id);
- }
-
- if (wrap_nonclass_fake_class) {
- String *fake_class = fake_class_name();
- Printf(fake_cs_entry, " PHP_ME(%s,%s,swig_arginfo_%s,ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)\n", fake_class, fname, arginfo_id);
- }
- }
- }
- }
-
- /* ------------------------------------------------------------
- * dispatchFunction()
- * ------------------------------------------------------------ */
- void dispatchFunction(Node *n, int constructor) {
- /* Last node in overloaded chain */
-
- int maxargs;
- String *tmp = NewStringEmpty();
- String *dispatch = Swig_overload_dispatch(n, "%s(INTERNAL_FUNCTION_PARAM_PASSTHRU); return;", &maxargs);
-
- /* Generate a dispatch wrapper for all overloaded functions */
-
- Wrapper *f = NewWrapper();
- String *symname = Getattr(n, "sym:name");
- String *wname = NULL;
- String *modes = NULL;
- bool constructorRenameOverload = false;
-
- if (constructor) {
- if (!Equal(class_name, Getattr(n, "constructorHandler:sym:name"))) {
- // Renamed constructor - turn into static factory method
- constructorRenameOverload = true;
- wname = Copy(Getattr(n, "constructorHandler:sym:name"));
- } else {
- wname = NewString("__construct");
- }
- } else if (class_name) {
- wname = Getattr(n, "wrapper:method:name");
- } else {
- wname = Swig_name_wrapper(symname);
- }
-
- if (constructor) {
- modes = NewString("ZEND_ACC_PUBLIC | ZEND_ACC_CTOR");
- if (constructorRenameOverload) {
- Append(modes, " | ZEND_ACC_STATIC");
- }
- } else if (wrapperType == staticmemberfn || Cmp(Getattr(n, "storage"), "static") == 0) {
- modes = NewString("ZEND_ACC_PUBLIC | ZEND_ACC_STATIC");
- } else {
- modes = NewString("ZEND_ACC_PUBLIC");
- }
-
- create_command(class_name, wname, n, true, modes);
-
- if (class_name && !Equal(Getattr(n, "storage"), "friend")) {
- Printv(f->def, "static PHP_METHOD(", prefix, class_name, ",", wname, ") {\n", NIL);
- } else {
- Printv(f->def, "static ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL);
- }
-
- Wrapper_add_local(f, "argc", "int argc");
-
- Printf(tmp, "zval argv[%d]", maxargs);
- Wrapper_add_local(f, "argv", tmp);
-
- Printf(f->code, "argc = ZEND_NUM_ARGS();\n");
-
- Printf(f->code, "zend_get_parameters_array_ex(argc, argv);\n");
-
- Replaceall(dispatch, "$args", "self,args");
-
- Printv(f->code, dispatch, "\n", NIL);
-
- Printf(f->code, "zend_throw_exception(zend_ce_type_error, \"No matching function for overloaded '%s'\", 0);\n", symname);
- Printv(f->code, "fail:\n", NIL);
- Printv(f->code, "return;\n", NIL);
- Printv(f->code, "}\n", NIL);
- Wrapper_print(f, s_wrappers);
-
- DelWrapper(f);
- Delete(dispatch);
- Delete(tmp);
- }
-
- /* ------------------------------------------------------------
- * functionWrapper()
- * ------------------------------------------------------------ */
-
- /* Helper function to check if class is wrapped */
- bool is_class_wrapped(String *className) {
- if (!className)
- return false;
- Node *n = symbolLookup(className);
- return n && Getattr(n, "classtype") != NULL;
- }
-
- void generate_magic_property_methods(Node *class_node) {
- String *swig_base = base_class;
- if (Equal(swig_base, "Exception") || !is_class_wrapped(swig_base)) {
- swig_base = NULL;
- }
-
- static bool generated_magic_arginfo = false;
- if (!generated_magic_arginfo) {
- // Create arginfo entries for __get, __set and __isset.
- Append(s_arginfo,
- "ZEND_BEGIN_ARG_INFO_EX(swig_magic_arginfo_get, 0, 0, 1)\n"
- " ZEND_ARG_TYPE_MASK(0,arg1,MAY_BE_STRING,NULL)\n"
- "ZEND_END_ARG_INFO()\n");
- Append(s_arginfo,
- "ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(swig_magic_arginfo_set, 0, 1, MAY_BE_VOID)\n"
- " ZEND_ARG_TYPE_MASK(0,arg1,MAY_BE_STRING,NULL)\n"
- " ZEND_ARG_INFO(0,arg2)\n"
- "ZEND_END_ARG_INFO()\n");
- Append(s_arginfo,
- "ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(swig_magic_arginfo_isset, 0, 1, MAY_BE_BOOL)\n"
- " ZEND_ARG_TYPE_MASK(0,arg1,MAY_BE_STRING,NULL)\n"
- "ZEND_END_ARG_INFO()\n");
- generated_magic_arginfo = true;
- }
-
- Wrapper *f = NewWrapper();
-
- Printf(f_h, "PHP_METHOD(%s%s,__set);\n", prefix, class_name);
- Printf(all_cs_entry, " PHP_ME(%s%s,__set,swig_magic_arginfo_set,ZEND_ACC_PUBLIC)\n", prefix, class_name);
- Printf(f->code, "PHP_METHOD(%s%s,__set) {\n", prefix, class_name);
-
- Printf(f->code, " swig_object_wrapper *arg = SWIG_Z_FETCH_OBJ_P(ZEND_THIS);\n");
- Printf(f->code, " zval args[2];\n zval tempZval;\n zend_string *arg2 = 0;\n\n");
- Printf(f->code, " if(ZEND_NUM_ARGS() != 2 || zend_get_parameters_array_ex(2, args) != SUCCESS) {\n");
- Printf(f->code, "\tWRONG_PARAM_COUNT;\n}\n\n");
- Printf(f->code, " if (!arg) {\n");
- Printf(f->code, " zend_throw_exception(zend_ce_type_error, \"this pointer is NULL\", 0);\n");
- Printf(f->code, " return;\n");
- Printf(f->code, " }\n");
- Printf(f->code, " arg2 = Z_STR(args[0]);\n\n");
-
- Printf(f->code, "if (!arg2) {\n RETVAL_NULL();\n}\n");
- if (magic_set) {
- Append(f->code, magic_set);
- }
- Printf(f->code, "\nelse if (strcmp(ZSTR_VAL(arg2),\"thisown\") == 0) {\n");
- Printf(f->code, "arg->newobject = zval_get_long(&args[1]);\n");
- if (Swig_directorclass(class_node)) {
- Printv(f->code, "if (arg->newobject == 0) {\n",
- " Swig::Director *director = SWIG_DIRECTOR_CAST((", Getattr(class_node, "classtype"), "*)(arg->ptr));\n",
- " if (director) director->swig_disown();\n",
- "}\n", NIL);
- }
- if (swig_base) {
- Printf(f->code, "} else {\nPHP_MN(%s%s___set)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n", prefix, swig_base);
- } else if (Getattr(class_node, "feature:php:allowdynamicproperties")) {
- Printf(f->code, "} else {\nadd_property_zval_ex(ZEND_THIS, ZSTR_VAL(arg2), ZSTR_LEN(arg2), &args[1]);\n");
- }
- Printf(f->code, "}\n");
-
- Printf(f->code, "fail:\n");
- Printf(f->code, "return;\n");
- Printf(f->code, "}\n\n\n");
-
-
- Printf(f_h, "PHP_METHOD(%s%s,__get);\n", prefix, class_name);
- Printf(all_cs_entry, " PHP_ME(%s%s,__get,swig_magic_arginfo_get,ZEND_ACC_PUBLIC)\n", prefix, class_name);
- Printf(f->code, "PHP_METHOD(%s%s,__get) {\n",prefix, class_name);
-
- Printf(f->code, " swig_object_wrapper *arg = SWIG_Z_FETCH_OBJ_P(ZEND_THIS);\n");
- Printf(f->code, " zval args[1];\n zval tempZval;\n zend_string *arg2 = 0;\n\n");
- Printf(f->code, " if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_array_ex(1, args) != SUCCESS) {\n");
- Printf(f->code, "\tWRONG_PARAM_COUNT;\n}\n\n");
- Printf(f->code, " if (!arg) {\n");
- Printf(f->code, " zend_throw_exception(zend_ce_type_error, \"this pointer is NULL\", 0);\n");
- Printf(f->code, " return;\n");
- Printf(f->code, " }\n");
- Printf(f->code, " arg2 = Z_STR(args[0]);\n\n");
-
- Printf(f->code, "if (!arg2) {\n RETVAL_NULL();\n}\n");
- if (magic_get) {
- Append(f->code, magic_get);
- }
- Printf(f->code, "\nelse if (strcmp(ZSTR_VAL(arg2),\"thisown\") == 0) {\n");
- Printf(f->code, "if(arg->newobject) {\nRETVAL_LONG(1);\n}\nelse {\nRETVAL_LONG(0);\n}\n}\n\n");
- Printf(f->code, "else {\n");
- if (swig_base) {
- Printf(f->code, "PHP_MN(%s%s___get)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, swig_base);
- } else {
- // __get is only called if the property isn't set on the zend_object.
- Printf(f->code, "RETVAL_NULL();\n}\n");
- }
-
- Printf(f->code, "fail:\n");
- Printf(f->code, "return;\n");
- Printf(f->code, "}\n\n\n");
-
-
- Printf(f_h, "PHP_METHOD(%s%s,__isset);\n", prefix, class_name);
- Printf(all_cs_entry, " PHP_ME(%s%s,__isset,swig_magic_arginfo_isset,ZEND_ACC_PUBLIC)\n", prefix, class_name);
- Printf(f->code, "PHP_METHOD(%s%s,__isset) {\n",prefix, class_name);
-
- Printf(f->code, " swig_object_wrapper *arg = SWIG_Z_FETCH_OBJ_P(ZEND_THIS);\n");
- Printf(f->code, " zval args[1];\n zend_string *arg2 = 0;\n\n");
- Printf(f->code, " if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_array_ex(1, args) != SUCCESS) {\n");
- Printf(f->code, "\tWRONG_PARAM_COUNT;\n}\n\n");
- Printf(f->code, " if(!arg) {\n");
- Printf(f->code, " zend_throw_exception(zend_ce_type_error, \"this pointer is NULL\", 0);\n");
- Printf(f->code, " return;\n");
- Printf(f->code, " }\n");
- Printf(f->code, " arg2 = Z_STR(args[0]);\n\n");
-
- Printf(f->code, "if (!arg2) {\n RETVAL_FALSE;\n}\n");
- Printf(f->code, "\nelse if (strcmp(ZSTR_VAL(arg2),\"thisown\") == 0) {\n");
- Printf(f->code, "RETVAL_TRUE;\n}\n\n");
- if (magic_isset) {
- Append(f->code, magic_isset);
- }
- Printf(f->code, "else {\n");
- if (swig_base) {
- Printf(f->code, "PHP_MN(%s%s___isset)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, swig_base);
- } else {
- // __isset is only called if the property isn't set on the zend_object.
- Printf(f->code, "RETVAL_FALSE;\n}\n");
- }
-
- Printf(f->code, "fail:\n");
- Printf(f->code, "return;\n");
- Printf(f->code, "}\n\n\n");
-
- Wrapper_print(f, s_wrappers);
- DelWrapper(f);
- f = NULL;
-
- Delete(magic_set);
- Delete(magic_get);
- Delete(magic_isset);
- magic_set = NULL;
- magic_get = NULL;
- magic_isset = NULL;
- }
-
- String *getAccessMode(String *access) {
- if (Cmp(access, "protected") == 0) {
- return NewString("ZEND_ACC_PROTECTED");
- } else if (Cmp(access, "private") == 0) {
- return NewString("ZEND_ACC_PRIVATE");
- }
- return NewString("ZEND_ACC_PUBLIC");
- }
-
- bool is_setter_method(Node *n) {
- const char *p = GetChar(n, "sym:name");
- if (strlen(p) > 4) {
- p += strlen(p) - 4;
- if (strcmp(p, "_set") == 0) {
- return true;
- }
- }
- return false;
- }
-
- bool is_getter_method(Node *n) {
- const char *p = GetChar(n, "sym:name");
- if (strlen(p) > 4) {
- p += strlen(p) - 4;
- if (strcmp(p, "_get") == 0) {
- return true;
- }
- }
- return false;
- }
-
- virtual int functionWrapper(Node *n) {
- if (wrapperType == directordisown) {
- // Handled via __set magic method - no explicit wrapper method wanted.
- return SWIG_OK;
- }
- String *name = GetChar(n, "name");
- String *iname = GetChar(n, "sym:name");
- SwigType *d = Getattr(n, "type");
- ParmList *l = Getattr(n, "parms");
- String *nodeType = Getattr(n, "nodeType");
- int newobject = GetFlag(n, "feature:new");
- int constructor = (Cmp(nodeType, "constructor") == 0);
-
- Parm *p;
- int i;
- int numopt;
- String *tm;
- Wrapper *f;
-
- String *wname = NewStringEmpty();
- String *overloadwname = NULL;
- int overloaded = 0;
- String *modes = NULL;
- bool static_setter = false;
- bool static_getter = false;
-
- modes = getAccessMode(Getattr(n, "access"));
-
- if (constructor) {
- Append(modes, " | ZEND_ACC_CTOR");
- }
- if (wrapperType == staticmemberfn || Cmp(Getattr(n, "storage"), "static") == 0) {
- Append(modes, " | ZEND_ACC_STATIC");
- }
- if (GetFlag(n, "abstract") && Swig_directorclass(Swig_methodclass(n)) && !is_member_director(n))
- Append(modes, " | ZEND_ACC_ABSTRACT");
-
- if (Getattr(n, "sym:overloaded")) {
- overloaded = 1;
- overloadwname = NewString(Swig_name_wrapper(iname));
- Printf(overloadwname, "%s", Getattr(n, "sym:overname"));
- } else {
- if (!addSymbol(iname, n))
- return SWIG_ERROR;
- }
-
- if (constructor) {
- if (!Equal(class_name, Getattr(n, "constructorHandler:sym:name"))) {
- // Renamed constructor - turn into static factory method
- wname = Copy(Getattr(n, "constructorHandler:sym:name"));
- } else {
- wname = NewString("__construct");
- }
- } else if (wrapperType == membervar) {
- wname = Copy(Getattr(n, "membervariableHandler:sym:name"));
- if (is_setter_method(n)) {
- Append(wname, "_set");
- } else if (is_getter_method(n)) {
- Append(wname, "_get");
- }
- } else if (wrapperType == memberfn) {
- wname = Getattr(n, "memberfunctionHandler:sym:name");
- } else if (wrapperType == staticmembervar) {
- // Shape::nshapes -> nshapes
- wname = Getattr(n, "staticmembervariableHandler:sym:name");
-
- /* We get called twice for getter and setter methods. But to maintain
- compatibility, Shape::nshapes() is being used for both setter and
- getter methods. So using static_setter and static_getter variables
- to generate half of the code each time.
- */
- static_setter = is_setter_method(n);
-
- if (is_getter_method(n)) {
- // This is to overcome types that can't be set and hence no setter.
- if (!Equal(Getattr(n, "feature:immutable"), "1"))
- static_getter = true;
- }
- } else if (wrapperType == staticmemberfn) {
- wname = Getattr(n, "staticmemberfunctionHandler:sym:name");
- } else {
- if (class_name) {
- if (Cmp(Getattr(n, "storage"), "friend") == 0 && Cmp(Getattr(n, "view"), "globalfunctionHandler") == 0) {
- wname = iname;
- } else {
- wname = Getattr(n, "destructorHandler:sym:name");
- }
- } else {
- wname = iname;
- }
- }
-
- if (wrapperType == destructor) {
- // We don't explicitly wrap the destructor for PHP - Zend manages the
- // reference counting, and the user can just do `$obj = null;' or similar
- // to remove a reference to an object.
- Setattr(n, "wrap:name", wname);
- (void)emit_action(n);
- return SWIG_OK;
- }
-
- if (!static_getter) {
- // Create or find existing PHPTypes.
- phptypes = NULL;
-
- String *key;
- if (class_name && !Equal(Getattr(n, "storage"), "friend")) {
- key = NewStringf("%s:%s", class_name, wname);
- } else {
- key = NewStringf(":%s", wname);
- }
-
- PHPTypes *p = (PHPTypes*)GetVoid(all_phptypes, key);
- if (p) {
- // We already have an entry so use it.
- phptypes = p;
- Delete(key);
- } else {
- phptypes = new PHPTypes(n);
- SetVoid(all_phptypes, key, phptypes);
- }
- }
-
- f = NewWrapper();
-
- if (static_getter) {
- Printf(f->def, "{\n");
- }
-
- String *outarg = NewStringEmpty();
- String *cleanup = NewStringEmpty();
-
- if (!overloaded) {
- if (!static_getter) {
- if (class_name && !Equal(Getattr(n, "storage"), "friend")) {
- Printv(f->def, "static PHP_METHOD(", prefix, class_name, ",", wname, ") {\n", NIL);
- } else {
- if (wrap_nonclass_global) {
- Printv(f->def, "static PHP_METHOD(", fake_class_name(), ",", wname, ") {\n",
- " PHP_FN(", wname, ")(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n",
- "}\n\n", NIL);
- }
-
- if (wrap_nonclass_fake_class) {
- Printv(f->def, "static PHP_FUNCTION(", wname, ") {\n", NIL);
- }
- }
- }
- } else {
- Printv(f->def, "static ZEND_NAMED_FUNCTION(", overloadwname, ") {\n", NIL);
- }
-
- emit_parameter_variables(l, f);
- /* Attach standard typemaps */
-
- emit_attach_parmmaps(l, f);
-
- if (wrapperType == memberfn || wrapperType == membervar) {
- // Assign "this" to arg1 and remove first entry from ParmList l.
- Printf(f->code, "arg1 = (%s)SWIG_Z_FETCH_OBJ_P(ZEND_THIS)->ptr;\n", SwigType_lstr(Getattr(l, "type"), ""));
- l = nextSibling(l);
- }
-
- // wrap:parms is used by overload resolution.
- Setattr(n, "wrap:parms", l);
-
- int num_arguments = emit_num_arguments(l);
- int num_required = emit_num_required(l);
- numopt = num_arguments - num_required;
-
- if (num_arguments > 0) {
- String *args = NewStringEmpty();
- Printf(args, "zval args[%d]", num_arguments);
- Wrapper_add_local(f, "args", args);
- Delete(args);
- args = NULL;
- }
- if (wrapperType == directorconstructor) {
- Wrapper_add_local(f, "arg0", "zval *arg0 = ZEND_THIS");
- }
-
- // This generated code may be called:
- // 1) as an object method, or
- // 2) as a class-method/function (without a "this_ptr")
- // Option (1) has "this_ptr" for "this", option (2) needs it as
- // first parameter
-
- // NOTE: possible we ignore this_ptr as a param for native constructor
-
- if (numopt > 0) { // membervariable wrappers do not have optional args
- Wrapper_add_local(f, "arg_count", "int arg_count");
- Printf(f->code, "arg_count = ZEND_NUM_ARGS();\n");
- Printf(f->code, "if(arg_count<%d || arg_count>%d ||\n", num_required, num_arguments);
- Printf(f->code, " zend_get_parameters_array_ex(arg_count,args)!=SUCCESS)\n");
- Printf(f->code, "\tWRONG_PARAM_COUNT;\n\n");
- } else if (static_setter || static_getter) {
- if (num_arguments == 0) {
- Printf(f->code, "if(ZEND_NUM_ARGS() == 0) {\n");
- } else {
- Printf(f->code, "if(ZEND_NUM_ARGS() == %d && zend_get_parameters_array_ex(%d, args) == SUCCESS) {\n", num_arguments, num_arguments);
- }
- } else {
- if (num_arguments == 0) {
- Printf(f->code, "if(ZEND_NUM_ARGS() != 0) {\n");
- } else {
- Printf(f->code, "if(ZEND_NUM_ARGS() != %d || zend_get_parameters_array_ex(%d, args) != SUCCESS) {\n", num_arguments, num_arguments);
- }
- Printf(f->code, "WRONG_PARAM_COUNT;\n}\n\n");
- }
-
- /* Now convert from PHP to C variables */
- // At this point, argcount if used is the number of deliberately passed args
- // not including this_ptr even if it is used.
- // It means error messages may be out by argbase with error
- // reports. We can either take argbase into account when raising
- // errors, or find a better way of dealing with _thisptr.
- // I would like, if objects are wrapped, to assume _thisptr is always
- // _this and not the first argument.
- // This may mean looking at Language::memberfunctionHandler
-
- for (i = 0, p = l; i < num_arguments; i++) {
- /* Skip ignored arguments */
- while (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- }
-
- /* Check if optional */
- if (i >= num_required) {
- Printf(f->code, "\tif(arg_count > %d) {\n", i);
- }
-
- tm = Getattr(p, "tmap:in");
- if (!tm) {
- SwigType *pt = Getattr(p, "type");
- Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
- p = nextSibling(p);
- continue;
- }
-
- phptypes->process_phptype(p, i + 1, "tmap:in:phptype");
- if (GetFlag(p, "tmap:in:byref")) phptypes->set_byref(i + 1);
-
- String *source = NewStringf("args[%d]", i);
- Replaceall(tm, "$input", source);
- Setattr(p, "emit:input", source);
- Printf(f->code, "%s\n", tm);
- if (i == 0 && Getattr(p, "self")) {
- Printf(f->code, "\tif(!arg1) {\n");
- Printf(f->code, "\t zend_throw_exception(zend_ce_type_error, \"this pointer is NULL\", 0);\n");
- Printf(f->code, "\t return;\n");
- Printf(f->code, "\t}\n");
- }
-
- if (i >= num_required) {
- Printf(f->code, "}\n");
- }
-
- p = Getattr(p, "tmap:in:next");
-
- Delete(source);
- }
-
- if (is_member_director(n)) {
- Wrapper_add_local(f, "director", "Swig::Director *director = 0");
- Append(f->code, "director = SWIG_DIRECTOR_CAST(arg1);\n");
- Wrapper_add_local(f, "upcall", "bool upcall = false");
- Printf(f->code, "upcall = (director && (director->swig_get_self()==Z_OBJ_P(ZEND_THIS)));\n");
- }
-
- Swig_director_emit_dynamic_cast(n, f);
-
- /* Insert constraint checking code */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:check"))) {
- Printv(f->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:check:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* Insert cleanup code */
- for (i = 0, p = l; p; i++) {
- if ((tm = Getattr(p, "tmap:freearg"))) {
- Printv(cleanup, tm, "\n", NIL);
- p = Getattr(p, "tmap:freearg:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* Insert argument output code */
- for (i = 0, p = l; p; i++) {
- if ((tm = Getattr(p, "tmap:argout")) && Len(tm)) {
- Replaceall(tm, "$result", "return_value");
- Replaceall(tm, "$arg", Getattr(p, "emit:input"));
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(outarg, tm, "\n", NIL);
- p = Getattr(p, "tmap:argout:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- if (!overloaded) {
- Setattr(n, "wrap:name", wname);
- } else {
- Setattr(n, "wrap:name", overloadwname);
- }
- Setattr(n, "wrapper:method:name", wname);
-
- bool php_constructor = (constructor && Cmp(class_name, Getattr(n, "constructorHandler:sym:name")) == 0);
-
- /* emit function call */
- String *actioncode = emit_action(n);
-
- if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
- Replaceall(tm, "$input", Swig_cresult_name());
- Replaceall(tm, "$result", php_constructor ? "ZEND_THIS" : "return_value");
- Replaceall(tm, "$owner", newobject ? "1" : "0");
- Printf(f->code, "%s\n", tm);
- } else {
- Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);
- }
- emit_return_variable(n, d, f);
-
- List *return_types = phptypes->process_phptype(n, 0, "tmap:out:phptype");
-
- if (class_name && !Equal(Getattr(n, "storage"), "friend")) {
- if (is_member_director(n)) {
- String *parent = class_name;
- while ((parent = Getattr(php_parent_class, parent)) != NULL) {
- // Mark this method name as having no return type declaration for all
- // classes we're derived from.
- SetFlag(has_directed_descendent, NewStringf("%s:%s", parent, wname));
- }
- } else if (return_types) {
- String *parent = class_name;
- while ((parent = Getattr(php_parent_class, parent)) != NULL) {
- String *key = NewStringf("%s:%s", parent, wname);
- // The parent class method needs to have a superset of the possible
- // return types of methods with the same name in subclasses.
- List *v = Getattr(parent_class_method_return_type, key);
- if (!v) {
- // New entry.
- Setattr(parent_class_method_return_type, key, Copy(return_types));
- } else {
- // Update existing entry.
- PHPTypes::merge_type_lists(v, return_types);
- }
- }
- }
- }
-
- if (outarg) {
- Printv(f->code, outarg, NIL);
- }
-
- if (static_setter && cleanup) {
- Printv(f->code, cleanup, NIL);
- }
-
- /* Look to see if there is any newfree cleanup code */
- if (GetFlag(n, "feature:new")) {
- if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
- Printf(f->code, "%s\n", tm);
- Delete(tm);
- }
- }
-
- /* See if there is any return cleanup code */
- if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
- Printf(f->code, "%s\n", tm);
- Delete(tm);
- }
-
- if (static_getter) {
- Printf(f->code, "}\n");
- }
-
- if (static_setter || static_getter) {
- Printf(f->code, "}\n");
- }
-
- if (!static_setter) {
- Printf(f->code, "fail:\n");
- Printv(f->code, cleanup, NIL);
- Printf(f->code, "return;\n");
- Printf(f->code, "}\n");
- }
-
- Replaceall(f->code, "$cleanup", cleanup);
- Replaceall(f->code, "$symname", iname);
-
- Wrapper_print(f, s_wrappers);
- DelWrapper(f);
- f = NULL;
-
- if (overloaded) {
- if (!Getattr(n, "sym:nextSibling")) {
- dispatchFunction(n, constructor);
- }
- } else {
- if (!static_setter) {
- create_command(class_name, wname, n, false, modes);
- }
- }
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * globalvariableHandler()
- * ------------------------------------------------------------ */
-
- /* PHP doesn't support intercepting reads and writes to global variables
- * (nor static property reads and writes so we can't wrap them as static
- * properties on a dummy class) so just let SWIG do its default thing and
- * wrap them as name_get() and name_set().
- */
- //virtual int globalvariableHandler(Node *n) {
- //}
-
- /* ------------------------------------------------------------
- * constantWrapper()
- * ------------------------------------------------------------ */
-
- virtual int constantWrapper(Node *n) {
- String *name = GetChar(n, "name");
- String *iname = GetChar(n, "sym:name");
- SwigType *type = Getattr(n, "type");
- String *rawval = Getattr(n, "rawval");
- String *value = rawval ? rawval : Getattr(n, "value");
- String *tm;
-
- if (!addSymbol(iname, n))
- return SWIG_ERROR;
-
- SwigType_remember(type);
-
- String *wrapping_member_constant = Getattr(n, "memberconstantHandler:sym:name");
- if (!wrapping_member_constant) {
- {
- tm = Swig_typemap_lookup("consttab", n, name, 0);
- Replaceall(tm, "$value", value);
- if (Getattr(n, "tmap:consttab:rinit")) {
- Printf(r_init, "%s\n", tm);
- } else {
- Printf(s_cinit, "%s\n", tm);
- }
- }
-
- {
- tm = Swig_typemap_lookup("classconsttab", n, name, 0);
-
- Replaceall(tm, "$class", fake_class_name());
- Replaceall(tm, "$const_name", iname);
- Replaceall(tm, "$value", value);
- if (Getattr(n, "tmap:classconsttab:rinit")) {
- Printf(r_init, "%s\n", tm);
- } else {
- Printf(s_cinit, "%s\n", tm);
- }
- }
- } else {
- tm = Swig_typemap_lookup("classconsttab", n, name, 0);
- Replaceall(tm, "$class", class_name);
- Replaceall(tm, "$const_name", wrapping_member_constant);
- Replaceall(tm, "$value", value);
- if (Getattr(n, "tmap:classconsttab:rinit")) {
- Printf(r_init, "%s\n", tm);
- } else {
- Printf(s_cinit, "%s\n", tm);
- }
- }
-
- wrapperType = standard;
- return SWIG_OK;
- }
-
- /*
- * PHP::pragma()
- *
- * Pragma directive.
- *
- * %pragma(php) code="String" # Includes a string in the .php file
- * %pragma(php) include="file.php" # Includes a file in the .php file
- */
-
- virtual int pragmaDirective(Node *n) {
- if (!ImportMode) {
- String *lang = Getattr(n, "lang");
- String *type = Getattr(n, "name");
- String *value = Getattr(n, "value");
-
- if (Strcmp(lang, "php") == 0) {
- if (Strcmp(type, "code") == 0) {
- if (value) {
- Printf(pragma_code, "%s\n", value);
- }
- } else if (Strcmp(type, "include") == 0) {
- if (value) {
- Printf(pragma_incl, "include '%s';\n", value);
- }
- } else if (Strcmp(type, "phpinfo") == 0) {
- if (value) {
- Printf(pragma_phpinfo, "%s\n", value);
- }
- } else if (Strcmp(type, "version") == 0) {
- if (value) {
- pragma_version = value;
- }
- } else {
- Swig_warning(WARN_PHP_UNKNOWN_PRAGMA, input_file, line_number, "Unrecognized pragma <%s>.\n", type);
- }
- }
- }
- return Language::pragmaDirective(n);
- }
-
- /* ------------------------------------------------------------
- * classDeclaration()
- * ------------------------------------------------------------ */
-
- virtual int classDeclaration(Node *n) {
- return Language::classDeclaration(n);
- }
-
- /* ------------------------------------------------------------
- * classHandler()
- * ------------------------------------------------------------ */
-
- virtual int classHandler(Node *n) {
- String *symname = Getattr(n, "sym:name");
-
- class_name = symname;
- base_class = NULL;
- destructor_action = NULL;
-
- Printf(all_cs_entry, "static const zend_function_entry class_%s_functions[] = {\n", class_name);
-
- // namespace code to introduce namespaces into wrapper classes.
- //if (nameSpace != NULL)
- //Printf(s_oinit, "INIT_CLASS_ENTRY(internal_ce, \"%s\\\\%s\", class_%s_functions);\n", nameSpace, class_name, class_name);
- //else
- Printf(s_oinit, " INIT_CLASS_ENTRY(internal_ce, \"%s%s\", class_%s_functions);\n", prefix, class_name, class_name);
-
- if (shadow) {
- char *rename = GetChar(n, "sym:name");
-
- if (!addSymbol(rename, n))
- return SWIG_ERROR;
-
- /* Deal with inheritance */
- List *baselist = Getattr(n, "bases");
- if (baselist) {
- Iterator base = First(baselist);
- while (base.item) {
- if (!GetFlag(base.item, "feature:ignore")) {
- if (!base_class) {
- base_class = Getattr(base.item, "sym:name");
- } else {
- /* Warn about multiple inheritance for additional base class(es) */
- String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0);
- String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0);
- Swig_warning(WARN_PHP_MULTIPLE_INHERITANCE, input_file, line_number,
- "Warning for %s, base %s ignored. Multiple inheritance is not supported in PHP.\n", proxyclassname, baseclassname);
- }
- }
- base = Next(base);
- }
- }
- }
-
- if (GetFlag(n, "feature:exceptionclass") && Getattr(n, "feature:except")) {
- /* PHP requires thrown objects to be instances of or derived from
- * Exception, so that really needs to take priority over any
- * explicit base class.
- */
- if (base_class) {
- String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0);
- Swig_warning(WARN_PHP_MULTIPLE_INHERITANCE, input_file, line_number,
- "Warning for %s, base %s ignored. Multiple inheritance is not supported in PHP.\n", proxyclassname, base_class);
- }
- base_class = NewString("Exception");
- }
-
- if (!base_class) {
- Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class(&internal_ce);\n", class_name);
- } else if (Equal(base_class, "Exception")) {
- Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, zend_ce_exception);\n", class_name);
- } else if (is_class_wrapped(base_class)) {
- Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, SWIG_Php_ce_%s);\n", class_name, base_class);
- Setattr(php_parent_class, class_name, base_class);
- } else {
- Printf(s_oinit, " {\n");
- Printf(s_oinit, " swig_type_info *type_info = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, \"_p_%s\");\n", base_class);
- Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, (zend_class_entry*)(type_info ? type_info->clientdata : NULL));\n", class_name);
- Printf(s_oinit, " }\n");
- }
-
- if (Getattr(n, "abstracts") && !GetFlag(n, "feature:notabstract")) {
- Printf(s_oinit, " SWIG_Php_ce_%s->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;\n", class_name);
- }
- if (Getattr(n, "feature:php:allowdynamicproperties")) {
- Append(s_oinit, "#ifdef ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES\n");
- Printf(s_oinit, " SWIG_Php_ce_%s->ce_flags |= ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES;\n", class_name);
- Append(s_oinit, "#endif\n");
- } else {
- Append(s_oinit, "#ifdef ZEND_ACC_NO_DYNAMIC_PROPERTIES\n");
- Printf(s_oinit, " SWIG_Php_ce_%s->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES;\n", class_name);
- Append(s_oinit, "#endif\n");
- }
- String *swig_wrapped = swig_wrapped_interface_ce();
- Printv(s_oinit, " zend_do_implement_interface(SWIG_Php_ce_", class_name, ", &", swig_wrapped, ");\n", NIL);
-
- {
- Node *node = NewHash();
- Setattr(node, "type", Getattr(n, "name"));
- Setfile(node, Getfile(n));
- Setline(node, Getline(n));
- String *interfaces = Swig_typemap_lookup("phpinterfaces", node, "", 0);
- Replaceall(interfaces, " ", "");
- if (interfaces && Len(interfaces) > 0) {
- // It seems we need to wait until RINIT time to look up class entries
- // for interfaces by name. The downside is that this then happens for
- // every request.
- //
- // Most pre-defined interfaces are accessible via zend_class_entry*
- // variables declared in the PHP C API - these we can use at MINIT
- // time, so we special case them. This will also be a little faster
- // than looking up by name.
- Printv(s_header,
- "#ifdef __cplusplus\n",
- "extern \"C\" {\n",
- "#endif\n",
- NIL);
-
- String *r_init_prefix = NewStringEmpty();
-
- List *interface_list = Split(interfaces, ',', -1);
- int num_interfaces = Len(interface_list);
- for (int i = 0; i < num_interfaces; ++i) {
- String *interface = Getitem(interface_list, i);
- // We generate conditional code in both minit and rinit - then we or the user
- // just need to define SWIG_PHP_INTERFACE_xxx_CE (and optionally
- // SWIG_PHP_INTERFACE_xxx_HEADER) to handle interface `xxx` at minit-time.
- Printv(s_header,
- "#ifdef SWIG_PHP_INTERFACE_", interface, "_HEADER\n",
- "# include SWIG_PHP_INTERFACE_", interface, "_HEADER\n",
- "#endif\n",
- NIL);
- Printv(s_oinit,
- "#ifdef SWIG_PHP_INTERFACE_", interface, "_CE\n",
- " zend_do_implement_interface(SWIG_Php_ce_", class_name, ", SWIG_PHP_INTERFACE_", interface, "_CE);\n",
- "#endif\n",
- NIL);
- Printv(r_init_prefix,
- "#ifndef SWIG_PHP_INTERFACE_", interface, "_CE\n",
- " {\n",
- " zend_class_entry *swig_interface_ce = zend_lookup_class(zend_string_init(\"", interface, "\", sizeof(\"", interface, "\") - 1, 0));\n",
- " if (swig_interface_ce)\n",
- " zend_do_implement_interface(SWIG_Php_ce_", class_name, ", swig_interface_ce);\n",
- " else\n",
- " zend_throw_exception(zend_ce_error, \"Interface \\\"", interface, "\\\" not found\", 0);\n",
- " }\n",
- "#endif\n",
- NIL);
- }
-
- // Handle interfaces at the start of rinit so that they're added
- // before any potential constant objects, etc which might be created
- // later in rinit.
- Insert(r_init, 0, r_init_prefix);
- Delete(r_init_prefix);
-
- Printv(s_header,
- "#ifdef __cplusplus\n",
- "}\n",
- "#endif\n",
- NIL);
- }
- Delete(interfaces);
- }
-
- Language::classHandler(n);
-
- static bool emitted_base_object_handlers = false;
- if (!emitted_base_object_handlers) {
- Printf(s_creation, "static zend_object_handlers Swig_Php_base_object_handlers;\n\n");
-
- // Set up a base zend_object_handlers structure which we can use as-is
- // for classes without a destructor, and copy as the basis for other
- // classes.
- Printf(s_oinit, " Swig_Php_base_object_handlers = *zend_get_std_object_handlers();\n");
- Printf(s_oinit, " Swig_Php_base_object_handlers.offset = XtOffsetOf(swig_object_wrapper, std);\n");
- Printf(s_oinit, " Swig_Php_base_object_handlers.clone_obj = NULL;\n");
- emitted_base_object_handlers = true;
- }
-
- Printf(s_creation, "static zend_class_entry *SWIG_Php_ce_%s;\n\n", class_name);
-
- if (Getattr(n, "has_destructor")) {
- if (destructor_action ? Equal(destructor_action, "free((char *) arg1);") : !CPlusPlus) {
- // We can use a single function if the destructor action calls free()
- // (either explicitly or as the default in C-mode) since free() doesn't
- // care about the object's type. We currently only check for the exact
- // code that Swig_cdestructor_call() emits.
- static bool emitted_common_cdestructor = false;
- if (!emitted_common_cdestructor) {
- Printf(s_creation, "static zend_object_handlers Swig_Php_common_c_object_handlers;\n\n");
- Printf(s_creation, "static void SWIG_Php_common_c_free_obj(zend_object *object) {free(SWIG_Php_free_obj(object));}\n\n");
- Printf(s_creation, "static zend_object *SWIG_Php_common_c_create_object(zend_class_entry *ce) {return SWIG_Php_do_create_object(ce, &Swig_Php_common_c_object_handlers);}\n");
-
- Printf(s_oinit, " Swig_Php_common_c_object_handlers = Swig_Php_base_object_handlers;\n");
- Printf(s_oinit, " Swig_Php_common_c_object_handlers.free_obj = SWIG_Php_common_c_free_obj;\n");
-
- emitted_common_cdestructor = true;
- }
-
- Printf(s_oinit, " SWIG_Php_ce_%s->create_object = SWIG_Php_common_c_create_object;\n", class_name);
- } else {
- Printf(s_creation, "static zend_object_handlers %s_object_handlers;\n", class_name);
- Printf(s_creation, "static zend_object *SWIG_Php_create_object_%s(zend_class_entry *ce) {return SWIG_Php_do_create_object(ce, &%s_object_handlers);}\n", class_name, class_name);
-
- Printf(s_creation, "static void SWIG_Php_free_obj_%s(zend_object *object) {",class_name);
- String *type = Getattr(n, "classtype");
- // Special case handling the delete call generated by
- // Swig_cppdestructor_call() and generate simpler code.
- if (destructor_action && !Equal(destructor_action, "delete arg1;")) {
- Printv(s_creation, "\n"
- " ", type, " *arg1 = (" , type, " *)SWIG_Php_free_obj(object);\n"
- " if (arg1) {\n"
- " ", destructor_action, "\n"
- " }\n", NIL);
- } else {
- Printf(s_creation, "delete (%s *)SWIG_Php_free_obj(object);", type);
- }
- Printf(s_creation, "}\n\n");
-
- Printf(s_oinit, " SWIG_Php_ce_%s->create_object = SWIG_Php_create_object_%s;\n", class_name, class_name);
- Printf(s_oinit, " %s_object_handlers = Swig_Php_base_object_handlers;\n", class_name);
- Printf(s_oinit, " %s_object_handlers.free_obj = SWIG_Php_free_obj_%s;\n", class_name, class_name);
- }
- } else {
- static bool emitted_destructorless_create_object = false;
- if (!emitted_destructorless_create_object) {
- emitted_destructorless_create_object = true;
- Printf(s_creation, "static zend_object *SWIG_Php_create_object(zend_class_entry *ce) {return SWIG_Php_do_create_object(ce, &Swig_Php_base_object_handlers);}\n", class_name);
- }
-
- Printf(s_oinit, " SWIG_Php_ce_%s->create_object = SWIG_Php_create_object;\n", class_name);
- }
-
- // If not defined we aren't wrapping any functions which use this type as a
- // parameter or return value, in which case we don't need the clientdata
- // set.
- Printf(s_oinit, "#ifdef SWIGTYPE_p%s\n", SwigType_manglestr(Getattr(n, "classtypeobj")));
- Printf(s_oinit, " SWIG_TypeClientData(SWIGTYPE_p%s,SWIG_Php_ce_%s);\n", SwigType_manglestr(Getattr(n, "classtypeobj")), class_name);
- Printf(s_oinit, "#endif\n");
- Printf(s_oinit, "\n");
-
- generate_magic_property_methods(n);
- Printf(all_cs_entry, " ZEND_FE_END\n};\n\n");
-
- class_name = NULL;
- base_class = NULL;
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * memberfunctionHandler()
- * ------------------------------------------------------------ */
-
- virtual int memberfunctionHandler(Node *n) {
- wrapperType = memberfn;
- Language::memberfunctionHandler(n);
- wrapperType = standard;
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * membervariableHandler()
- * ------------------------------------------------------------ */
-
- virtual int membervariableHandler(Node *n) {
- if (magic_set == NULL) {
- magic_set = NewStringEmpty();
- magic_get = NewStringEmpty();
- magic_isset = NewStringEmpty();
- }
-
- String *v_name = GetChar(n, "name");
-
- Printf(magic_set, "\nelse if (strcmp(ZSTR_VAL(arg2),\"%s\") == 0) {\n", v_name);
- Printf(magic_set, "ZVAL_STRING(&tempZval, \"%s_set\");\n", v_name);
- Printf(magic_set, "call_user_function(EG(function_table),ZEND_THIS,&tempZval,return_value,1,&args[1]);\n}\n");
-
- Printf(magic_get, "\nelse if (strcmp(ZSTR_VAL(arg2),\"%s\") == 0) {\n", v_name);
- Printf(magic_get, "ZVAL_STRING(&tempZval, \"%s_get\");\n", v_name);
- Printf(magic_get, "call_user_function(EG(function_table),ZEND_THIS,&tempZval,return_value,0,NULL);\n}\n");
-
- Printf(magic_isset, "\nelse if (strcmp(ZSTR_VAL(arg2),\"%s\") == 0) {\n", v_name);
- Printf(magic_isset, "RETVAL_TRUE;\n}\n");
-
- wrapperType = membervar;
- Language::membervariableHandler(n);
- wrapperType = standard;
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * staticmembervariableHandler()
- * ------------------------------------------------------------ */
-
- virtual int staticmembervariableHandler(Node *n) {
- wrapperType = staticmembervar;
- Language::staticmembervariableHandler(n);
- wrapperType = standard;
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * staticmemberfunctionHandler()
- * ------------------------------------------------------------ */
-
- virtual int staticmemberfunctionHandler(Node *n) {
- wrapperType = staticmemberfn;
- Language::staticmemberfunctionHandler(n);
- wrapperType = standard;
-
- return SWIG_OK;
- }
-
- int abstractConstructorHandler(Node *) {
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * constructorHandler()
- * ------------------------------------------------------------ */
-
- virtual int constructorHandler(Node *n) {
- if (Swig_directorclass(n)) {
- String *ctype = GetChar(Swig_methodclass(n), "classtype");
- String *sname = GetChar(Swig_methodclass(n), "sym:name");
- String *args = NewStringEmpty();
- ParmList *p = Getattr(n, "parms");
- int i;
-
- for (i = 0; p; p = nextSibling(p), i++) {
- if (i) {
- Printf(args, ", ");
- }
- if (Strcmp(GetChar(p, "type"), SwigType_str(GetChar(p, "type"), 0))) {
- SwigType *t = Getattr(p, "type");
- Printf(args, "%s", SwigType_rcaststr(t, 0));
- if (SwigType_isreference(t)) {
- Append(args, "*");
- }
- }
- Printf(args, "arg%d", i+1);
- }
-
- /* director ctor code is specific for each class */
- Delete(director_ctor_code);
- director_ctor_code = NewStringEmpty();
- director_prot_ctor_code = NewStringEmpty();
- Printf(director_ctor_code, "if (Z_OBJCE_P(arg0) == SWIG_Php_ce_%s) { /* not subclassed */\n", class_name);
- Printf(director_prot_ctor_code, "if (Z_OBJCE_P(arg0) == SWIG_Php_ce_%s) { /* not subclassed */\n", class_name);
- Printf(director_ctor_code, " %s = new %s(%s);\n", Swig_cresult_name(), ctype, args);
- Printf(director_prot_ctor_code,
- " zend_throw_exception(zend_ce_type_error, \"accessing abstract class or protected constructor\", 0);\n"
- " return;\n");
- if (i) {
- Insert(args, 0, ", ");
- }
- Printf(director_ctor_code, "} else {\n %s = (%s *)new SwigDirector_%s(arg0%s);\n}\n", Swig_cresult_name(), ctype, sname, args);
- Printf(director_prot_ctor_code, "} else {\n %s = (%s *)new SwigDirector_%s(arg0%s);\n}\n", Swig_cresult_name(), ctype, sname, args);
- Delete(args);
-
- wrapperType = directorconstructor;
- } else {
- wrapperType = constructor;
- }
- Language::constructorHandler(n);
- wrapperType = standard;
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * destructorHandler()
- * ------------------------------------------------------------ */
- virtual int destructorHandler(Node *n) {
- wrapperType = destructor;
- Language::destructorHandler(n);
- destructor_action = Getattr(n, "wrap:action");
- wrapperType = standard;
- return SWIG_OK;
- }
-
- int classDirectorInit(Node *n) {
- String *declaration = Swig_director_declaration(n);
- Printf(f_directors_h, "%s\n", declaration);
- Printf(f_directors_h, "public:\n");
- Delete(declaration);
- return Language::classDirectorInit(n);
- }
-
- int classDirectorEnd(Node *n) {
- Printf(f_directors_h, "};\n");
- return Language::classDirectorEnd(n);
- }
-
- int classDirectorConstructor(Node *n) {
- Node *parent = Getattr(n, "parentNode");
- String *decl = Getattr(n, "decl");
- String *supername = Swig_class_name(parent);
- String *classname = NewStringEmpty();
- Printf(classname, "SwigDirector_%s", supername);
-
- /* insert self parameter */
- Parm *p;
- ParmList *superparms = Getattr(n, "parms");
- ParmList *parms = CopyParmList(superparms);
- String *type = NewString("zval");
- SwigType_add_pointer(type);
- p = NewParm(type, NewString("self"), n);
- set_nextSibling(p, parms);
- parms = p;
-
- if (!Getattr(n, "defaultargs")) {
- // There should always be a "self" parameter first.
- assert(ParmList_len(parms) > 0);
-
- /* constructor */
- {
- Wrapper *w = NewWrapper();
- String *call;
- String *basetype = Getattr(parent, "classtype");
-
- String *target = Swig_method_decl(0, decl, classname, parms, 0);
- call = Swig_csuperclass_call(0, basetype, superparms);
- Printf(w->def, "%s::%s: %s, Swig::Director(self) {", classname, target, call);
- Append(w->def, "}");
- Delete(target);
- Wrapper_print(w, f_directors);
- Delete(call);
- DelWrapper(w);
- }
-
- /* constructor header */
- {
- String *target = Swig_method_decl(0, decl, classname, parms, 1);
- Printf(f_directors_h, " %s;\n", target);
- Delete(target);
- }
- }
- return Language::classDirectorConstructor(n);
- }
-
- int classDirectorMethod(Node *n, Node *parent, String *super) {
- int is_void = 0;
- int is_pointer = 0;
- String *decl = Getattr(n, "decl");
- String *returntype = Getattr(n, "type");
- String *name = Getattr(n, "name");
- String *classname = Getattr(parent, "sym:name");
- String *c_classname = Getattr(parent, "name");
- String *symname = Getattr(n, "sym:name");
- String *declaration = NewStringEmpty();
- ParmList *l = Getattr(n, "parms");
- Wrapper *w = NewWrapper();
- String *tm;
- String *wrap_args = NewStringEmpty();
- String *value = Getattr(n, "value");
- String *storage = Getattr(n, "storage");
- bool pure_virtual = false;
- int status = SWIG_OK;
- int idx;
- bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
-
- if (Cmp(storage, "virtual") == 0) {
- if (Cmp(value, "0") == 0) {
- pure_virtual = true;
- }
- }
-
- /* determine if the method returns a pointer */
- is_pointer = SwigType_ispointer_return(decl);
- is_void = (Cmp(returntype, "void") == 0 && !is_pointer);
-
- /* virtual method definition */
- String *target;
- String *pclassname = NewStringf("SwigDirector_%s", classname);
- String *qualified_name = NewStringf("%s::%s", pclassname, name);
- SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
- target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
- Printf(w->def, "%s", target);
- Delete(qualified_name);
- Delete(target);
- /* header declaration */
- target = Swig_method_decl(rtype, decl, name, l, 1);
- Printf(declaration, " virtual %s", target);
- Delete(target);
-
- // Get any exception classes in the throws typemap
- if (Getattr(n, "noexcept")) {
- Append(w->def, " noexcept");
- Append(declaration, " noexcept");
- }
- ParmList *throw_parm_list = 0;
-
- if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
- Parm *p;
- int gencomma = 0;
-
- Append(w->def, " throw(");
- Append(declaration, " throw(");
-
- if (throw_parm_list)
- Swig_typemap_attach_parms("throws", throw_parm_list, 0);
- for (p = throw_parm_list; p; p = nextSibling(p)) {
- if (Getattr(p, "tmap:throws")) {
- if (gencomma++) {
- Append(w->def, ", ");
- Append(declaration, ", ");
- }
- String *str = SwigType_str(Getattr(p, "type"), 0);
- Append(w->def, str);
- Append(declaration, str);
- Delete(str);
- }
- }
-
- Append(w->def, ")");
- Append(declaration, ")");
- }
-
- Append(w->def, " {");
- Append(declaration, ";\n");
-
- /* declare method return value
- * if the return value is a reference or const reference, a specialized typemap must
- * handle it, including declaration of c_result ($result).
- */
- if (!is_void && (!ignored_method || pure_virtual)) {
- if (!SwigType_isclass(returntype)) {
- if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
- String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
- Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL);
- Delete(construct_result);
- } else {
- Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL);
- }
- } else {
- String *cres = SwigType_lstr(returntype, "c_result");
- Printf(w->code, "%s;\n", cres);
- Delete(cres);
- }
- }
-
- if (ignored_method) {
- if (!pure_virtual) {
- if (!is_void)
- Printf(w->code, "return ");
- String *super_call = Swig_method_call(super, l);
- Printf(w->code, "%s;\n", super_call);
- Delete(super_call);
- } else {
- Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
- SwigType_namestr(name));
- }
- } else {
- /* attach typemaps to arguments (C/C++ -> PHP) */
- Swig_director_parms_fixup(l);
-
- /* remove the wrapper 'w' since it was producing spurious temps */
- Swig_typemap_attach_parms("in", l, 0);
- Swig_typemap_attach_parms("directorin", l, w);
- Swig_typemap_attach_parms("directorargout", l, w);
-
- Parm *p;
-
- /* build argument list and type conversion string */
- idx = 0;
- p = l;
- while (p) {
- if (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- continue;
- }
-
- String *pname = Getattr(p, "name");
- String *ptype = Getattr(p, "type");
-
- if ((tm = Getattr(p, "tmap:directorin")) != 0) {
- String *parse = Getattr(p, "tmap:directorin:parse");
- if (!parse) {
- String *input = NewStringf("&args[%d]", idx++);
- Setattr(p, "emit:directorinput", input);
- Replaceall(tm, "$input", input);
- Delete(input);
- Replaceall(tm, "$owner", "0");
- Printv(wrap_args, tm, "\n", NIL);
- } else {
- Setattr(p, "emit:directorinput", pname);
- Replaceall(tm, "$input", pname);
- Replaceall(tm, "$owner", "0");
- if (Len(tm) == 0)
- Append(tm, pname);
- }
- p = Getattr(p, "tmap:directorin:next");
- continue;
- } else if (Cmp(ptype, "void")) {
- Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
- "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0),
- SwigType_namestr(c_classname), SwigType_namestr(name));
- status = SWIG_NOWRAP;
- break;
- }
- p = nextSibling(p);
- }
-
- if (!idx) {
- Printf(w->code, "zval *args = NULL;\n");
- } else {
- Printf(w->code, "zval args[%d];\n", idx);
- }
- // typemap_directorout testcase requires that 0 can be assigned to the
- // variable named after the result of Swig_cresult_name(), so that can't
- // be a zval - make it a pointer to one instead.
- Printf(w->code, "zval swig_zval_result;\n");
- Printf(w->code, "zval * SWIGUNUSED %s = &swig_zval_result;\n", Swig_cresult_name());
-
- /* wrap complex arguments to zvals */
- Append(w->code, wrap_args);
-
- const char *funcname = GetChar(n, "sym:name");
- Append(w->code, "{\n");
- Append(w->code, "#if PHP_MAJOR_VERSION < 8\n");
- Printf(w->code, "zval swig_funcname;\n");
- Printf(w->code, "ZVAL_STRINGL(&swig_funcname, \"%s\", %d);\n", funcname, strlen(funcname));
- Printf(w->code, "call_user_function(EG(function_table), &swig_self, &swig_funcname, &swig_zval_result, %d, args);\n", idx);
- Append(w->code, "#else\n");
- Printf(w->code, "zend_string *swig_funcname = zend_string_init(\"%s\", %d, 0);\n", funcname, strlen(funcname));
- Append(w->code, "zend_function *swig_zend_func = zend_std_get_method(&Z_OBJ(swig_self), swig_funcname, NULL);\n");
- Append(w->code, "zend_string_release(swig_funcname);\n");
- Printf(w->code, "if (swig_zend_func) zend_call_known_instance_method(swig_zend_func, Z_OBJ(swig_self), &swig_zval_result, %d, args);\n", idx);
- Append(w->code, "#endif\n");
-
- /* exception handling */
- tm = Swig_typemap_lookup("director:except", n, Swig_cresult_name(), 0);
- if (!tm) {
- tm = Getattr(n, "feature:director:except");
- if (tm)
- tm = Copy(tm);
- }
- if (!tm || Len(tm) == 0 || Equal(tm, "1")) {
- // Skip marshalling the return value as there isn't one.
- tm = NewString("if ($error) SWIG_fail;");
- }
-
- Replaceall(tm, "$error", "EG(exception)");
- Printv(w->code, Str(tm), "\n}\n{\n", NIL);
- Delete(tm);
-
- /* marshal return value from PHP to C/C++ type */
-
- String *cleanup = NewStringEmpty();
- String *outarg = NewStringEmpty();
-
- idx = 0;
-
- /* marshal return value */
- if (!is_void) {
- tm = Swig_typemap_lookup("directorout", n, Swig_cresult_name(), w);
- if (tm != 0) {
- Replaceall(tm, "$input", Swig_cresult_name());
- char temp[24];
- sprintf(temp, "%d", idx);
- Replaceall(tm, "$argnum", temp);
-
- /* TODO check this */
- if (Getattr(n, "wrap:disown")) {
- Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
- } else {
- Replaceall(tm, "$disown", "0");
- }
- Replaceall(tm, "$result", "c_result");
- Printv(w->code, tm, "\n", NIL);
- Delete(tm);
- } else {
- Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
- "Unable to use return type %s in director method %s::%s (skipping method).\n", SwigType_str(returntype, 0),
- SwigType_namestr(c_classname), SwigType_namestr(name));
- status = SWIG_ERROR;
- }
- }
-
- /* marshal outputs */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
- Replaceall(tm, "$result", Swig_cresult_name());
- Replaceall(tm, "$input", Getattr(p, "emit:directorinput"));
- Printv(w->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:directorargout:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- Append(w->code, "}\n");
-
- Delete(cleanup);
- Delete(outarg);
- }
-
- Append(w->code, "fail: ;\n");
- if (!is_void) {
- if (!(ignored_method && !pure_virtual)) {
- String *rettype = SwigType_str(returntype, 0);
- if (!SwigType_isreference(returntype)) {
- Printf(w->code, "return (%s) c_result;\n", rettype);
- } else {
- Printf(w->code, "return (%s) *c_result;\n", rettype);
- }
- Delete(rettype);
- }
- }
- Append(w->code, "}\n");
-
- // We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
- String *inline_extra_method = NewStringEmpty();
- if (dirprot_mode() && !is_public(n) && !pure_virtual) {
- Printv(inline_extra_method, declaration, NIL);
- String *extra_method_name = NewStringf("%sSwigPublic", name);
- Replaceall(inline_extra_method, name, extra_method_name);
- Replaceall(inline_extra_method, ";\n", " {\n ");
- if (!is_void)
- Printf(inline_extra_method, "return ");
- String *methodcall = Swig_method_call(super, l);
- Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
- Delete(methodcall);
- Delete(extra_method_name);
- }
-
- /* emit the director method */
- if (status == SWIG_OK) {
- if (!Getattr(n, "defaultargs")) {
- Replaceall(w->code, "$symname", symname);
- Wrapper_print(w, f_directors);
- Printv(f_directors_h, declaration, NIL);
- Printv(f_directors_h, inline_extra_method, NIL);
- }
- }
-
- /* clean up */
- Delete(wrap_args);
- Delete(pclassname);
- DelWrapper(w);
- return status;
- }
-
- int classDirectorDisown(Node *n) {
- wrapperType = directordisown;
- int result = Language::classDirectorDisown(n);
- wrapperType = standard;
- return result;
- }
-}; /* class PHP */
-
-static PHP *maininstance = 0;
-
-List *PHPTypes::process_phptype(Node *n, int key, const String_or_char *attribute_name) {
-
- while (Len(merged_types) <= key) {
- Append(merged_types, NewList());
- }
-
- String *phptype = Getattr(n, attribute_name);
- if (!phptype || Len(phptype) == 0) {
- // There's no type declaration, so any merged version has no type declaration.
- //
- // Use a DOH None object as a marker to indicate there's no type
- // declaration for this parameter/return value (you can't store NULL as a
- // value in a DOH List).
- Setitem(merged_types, key, None);
- return NULL;
- }
-
- DOH *merge_list = Getitem(merged_types, key);
- if (merge_list == None) return NULL;
-
- List *types = Split(phptype, '|', -1);
- String *first_type = Getitem(types, 0);
- if (Char(first_type)[0] == '?') {
- if (Len(types) > 1) {
- Printf(stderr, "warning: Invalid phptype: '%s' (can't use ? and | together)\n", phptype);
- }
- // Treat `?foo` just like `foo|null`.
- Append(types, "null");
- Setitem(types, 0, NewString(Char(first_type) + 1));
- }
-
- SortList(types, NULL);
- String *prev = NULL;
- for (Iterator i = First(types); i.item; i = Next(i)) {
- if (prev && Equal(prev, i.item)) {
- Printf(stderr, "warning: Invalid phptype: '%s' (duplicate entry for '%s')\n", phptype, i.item);
- continue;
- }
-
- if (key > 0 && Equal(i.item, "void")) {
- // Reject void for parameter type.
- Printf(stderr, "warning: Invalid phptype: '%s' ('%s' can't be used as a parameter phptype)\n", phptype, i.item);
- continue;
- }
-
- if (Equal(i.item, "SWIGTYPE")) {
- String *type = Getattr(n, "type");
- Node *class_node = maininstance->classLookup(type);
- if (class_node) {
- // FIXME: Prefix classname with a backslash to prevent collisions
- // with built-in types? Or are non of those valid anyway and so will
- // have been renamed at this point?
- Append(merge_list, Getattr(class_node, "sym:name"));
- } else {
- // SWIG wraps a pointer to a non-object type as an object in a PHP
- // class named based on the SWIG-mangled C/C++ type.
- //
- // FIXME: We should check this is actually a known pointer to
- // non-object type so we complain about `phptype="SWIGTYPE"` being
- // used for PHP types like `int` or `string` (currently this only
- // fails at runtime and the error isn't very helpful). We could
- // check the condition
- //
- // raw_pointer_types && Getattr(raw_pointer_types, SwigType_manglestr(type))
- //
- // except that raw_pointer_types may not have been fully filled in when
- // we are called.
- Append(merge_list, NewStringf("SWIG\\%s", SwigType_manglestr(type)));
- }
- } else {
- Append(merge_list, i.item);
- }
- prev = i.item;
- }
- SortList(merge_list, NULL);
- return merge_list;
-}
-
-void PHPTypes::merge_type_lists(List *merge_list, List *o_merge_list) {
- int i = 0, j = 0;
- while (j < Len(o_merge_list)) {
- String *candidate = Getitem(o_merge_list, j);
- while (i < Len(merge_list)) {
- int cmp = Cmp(Getitem(merge_list, i), candidate);
- if (cmp == 0)
- goto handled;
- if (cmp > 0)
- break;
- ++i;
- }
- Insert(merge_list, i, candidate);
- ++i;
-handled:
- ++j;
- }
-}
-
-void PHPTypes::merge_from(const PHPTypes* o) {
- num_required = std::min(num_required, o->num_required);
-
- if (o->byref) {
- if (byref == NULL) {
- byref = Copy(o->byref);
- } else {
- int len = std::min(Len(byref), Len(o->byref));
- // Start at 1 because we only want to merge parameter types, and key 0 is
- // the return type.
- for (int key = 1; key < len; ++key) {
- if (Getitem(byref, key) == None &&
- Getitem(o->byref, key) != None) {
- Setitem(byref, key, "");
- }
- }
- for (int key = len; key < Len(o->byref); ++key) {
- Append(byref, Getitem(o->byref, key));
- }
- }
- }
-
- int len = std::min(Len(merged_types), Len(o->merged_types));
- for (int key = 0; key < len; ++key) {
- DOH *merge_list = Getitem(merged_types, key);
- // None trumps anything else in the merge.
- if (merge_list == None) continue;
- DOH *o_merge_list = Getitem(o->merged_types, key);
- if (o_merge_list == None) {
- Setitem(merged_types, key, None);
- continue;
- }
- merge_type_lists(merge_list, o_merge_list);
- }
- // Copy over any additional entries.
- for (int key = len; key < Len(o->merged_types); ++key) {
- Append(merged_types, Copy(Getitem(o->merged_types, key)));
- }
-}
-
-// Collect non-class pointer types from the type table so we can set up PHP
-// classes for them later.
-//
-// NOTE: it's a function NOT A PHP::METHOD
-extern "C" {
-static void typetrace(const SwigType *ty, String *mangled, String *clientdata) {
- if (maininstance->classLookup(ty) == NULL) {
- // a non-class pointer
- if (!raw_pointer_types) {
- raw_pointer_types = NewHash();
- }
- Setattr(raw_pointer_types, mangled, mangled);
- }
- if (r_prevtracefunc)
- (*r_prevtracefunc) (ty, mangled, clientdata);
-}
-}
-
-/* -----------------------------------------------------------------------------
- * new_swig_php() - Instantiate module
- * ----------------------------------------------------------------------------- */
-
-static Language *new_swig_php() {
- maininstance = new PHP;
- if (!r_prevtracefunc) {
- r_prevtracefunc = SwigType_remember_trace(typetrace);
- } else {
- Printf(stderr, "php Typetrace vector already saved!\n");
- assert(0);
- }
- return maininstance;
-}
-
-extern "C" Language *swig_php(void) {
- return new_swig_php();
-}
diff --git a/contrib/tools/swig/Source/Modules/python.cxx b/contrib/tools/swig/Source/Modules/python.cxx
deleted file mode 100644
index 63f0c1650d..0000000000
--- a/contrib/tools/swig/Source/Modules/python.cxx
+++ /dev/null
@@ -1,5768 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * python.cxx
- *
- * Python language module for SWIG.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include "cparse.h"
-#include <limits.h>
-#include <ctype.h>
-#include <errno.h>
-#include <stdint.h>
-#include "pydoc.h"
-
-#define PYSHADOW_MEMBER 0x2
-#define WARN_PYTHON_MULTIPLE_INH 405
-
-#define PYTHON_INT_MAX (2147483647)
-#define PYTHON_INT_MIN (-2147483647-1)
-
-static String *const_code = 0;
-static String *module = 0;
-static String *package = 0;
-static String *mainmodule = 0;
-static String *interface = 0;
-static String *global_name = 0;
-static int shadow = 1;
-static int use_kw = 0;
-static int director_method_index = 0;
-static int builtin = 0;
-
-static File *f_begin = 0;
-static File *f_runtime = 0;
-static File *f_runtime_h = 0;
-static File *f_header = 0;
-static File *f_wrappers = 0;
-static File *f_directors = 0;
-static File *f_directors_h = 0;
-static File *f_init = 0;
-static File *f_shadow_py = 0;
-static String *f_shadow = 0;
-static String *f_shadow_begin = 0;
-static Hash *f_shadow_imports = 0;
-static String *f_shadow_after_begin = 0;
-static String *f_shadow_stubs = 0;
-static Hash *builtin_getset = 0;
-static Hash *builtin_closures = 0;
-static Hash *class_members = 0;
-static File *f_builtins = 0;
-static String *builtin_tp_init = 0;
-static String *builtin_methods = 0;
-static String *builtin_default_unref = 0;
-static String *builtin_closures_code = 0;
-
-static String *methods;
-static String *methods_proxydocs;
-static String *class_name;
-static String *shadow_indent = 0;
-static int in_class = 0;
-static int no_header_file = 0;
-static int max_bases = 0;
-static int builtin_bases_needed = 0;
-
-/* C++ Support + Shadow Classes */
-
-static int have_constructor = 0;
-static int have_repr = 0;
-static bool have_builtin_static_member_method_callback = false;
-static bool have_fast_proxy_static_member_method_callback = false;
-static String *real_classname;
-
-/* Thread Support */
-static int threads = 0;
-static int nothreads = 0;
-
-/* Other options */
-static int dirvtable = 0;
-static int doxygen = 0;
-static int fastunpack = 1;
-static int fastproxy = 0;
-static int olddefs = 0;
-static int castmode = 0;
-static int extranative = 0;
-static int nortti = 0;
-static int relativeimport = 0;
-static int flat_static_method = 0;
-
-/* flags for the make_autodoc function */
-namespace {
-enum autodoc_t {
- AUTODOC_CLASS,
- AUTODOC_CTOR,
- AUTODOC_DTOR,
- AUTODOC_STATICFUNC,
- AUTODOC_FUNC,
- AUTODOC_METHOD,
- AUTODOC_CONST,
- AUTODOC_VAR
-};
-}
-
-static const char *usage1 = "\
-Python Options (available with -python)\n\
- -builtin - Create Python built-in types rather than proxy classes, for better performance\n\
- -castmode - Enable the casting mode, which allows implicit cast between types in Python\n\
- -debug-doxygen-parser - Display doxygen parser module debugging information\n\
- -debug-doxygen-translator - Display doxygen translator module debugging information\n\
- -dirvtable - Generate a pseudo virtual table for directors for faster dispatch\n\
- -doxygen - Convert C++ doxygen comments to pydoc comments in proxy classes\n\
- -extranative - Return extra native wrappers for C++ std containers wherever possible\n\
- -fastproxy - Use fast proxy mechanism for member methods\n\
- -flatstaticmethod - Generate additional flattened Python methods for C++ static methods\n\
- -globals <name> - Set <name> used to access C global variable (default: 'cvar')\n\
- -interface <mod>- Set low-level C/C++ module name to <mod> (default: module name prefixed by '_')\n\
- -keyword - Use keyword arguments\n";
-static const char *usage2 = "\
- -nofastunpack - Use traditional UnpackTuple method to parse the argument functions\n\
- -noh - Don't generate the output header file\n";
-static const char *usage3 = "\
- -noproxy - Don't generate proxy classes\n\
- -nortti - Disable the use of the native C++ RTTI with directors\n\
- -nothreads - Disable thread support for the entire interface\n\
- -olddefs - Keep the old method definitions when using -fastproxy\n\
- -relativeimport - Use relative Python imports\n\
- -threads - Add thread support for all the interface\n\
- -O - Enable the following optimization options:\n\
- -fastdispatch -fastproxy -fvirtual\n\
-\n";
-
-static String *getSlot(Node *n = NULL, const char *key = NULL, String *default_slot = NULL) {
- static String *zero = NewString("0");
- String *val = n && key && *key ? Getattr(n, key) : NULL;
- return val ? val : default_slot ? default_slot : zero;
-}
-
-static void printSlot(File *f, String *slotval, const char *slotname, const char *functype = NULL) {
- String *slotval_override = 0;
- if (functype && Strcmp(slotval, "0") == 0)
- slotval = slotval_override = NewStringf("(%s) %s", functype, slotval);
- int len = Len(slotval);
- int fieldwidth = len > 41 ? (len > 61 ? 0 : 61 - len) : 41 - len;
- Printf(f, " %s,%*s/* %s */\n", slotval, fieldwidth, "", slotname);
- Delete(slotval_override);
-}
-
-static String *getClosure(String *functype, String *wrapper, int funpack = 0) {
- static const char *functypes[] = {
- "unaryfunc", "SWIGPY_UNARYFUNC_CLOSURE",
- "destructor", "SWIGPY_DESTRUCTOR_CLOSURE",
- "inquiry", "SWIGPY_INQUIRY_CLOSURE",
- "getiterfunc", "SWIGPY_GETITERFUNC_CLOSURE",
- "binaryfunc", "SWIGPY_BINARYFUNC_CLOSURE",
- "ternaryfunc", "SWIGPY_TERNARYFUNC_CLOSURE",
- "ternarycallfunc", "SWIGPY_TERNARYCALLFUNC_CLOSURE",
- "lenfunc", "SWIGPY_LENFUNC_CLOSURE",
- "ssizeargfunc", "SWIGPY_SSIZEARGFUNC_CLOSURE",
- "ssizessizeargfunc", "SWIGPY_SSIZESSIZEARGFUNC_CLOSURE",
- "ssizeobjargproc", "SWIGPY_SSIZEOBJARGPROC_CLOSURE",
- "ssizessizeobjargproc", "SWIGPY_SSIZESSIZEOBJARGPROC_CLOSURE",
- "objobjproc", "SWIGPY_OBJOBJPROC_CLOSURE",
- "objobjargproc", "SWIGPY_OBJOBJARGPROC_CLOSURE",
- "reprfunc", "SWIGPY_REPRFUNC_CLOSURE",
- "hashfunc", "SWIGPY_HASHFUNC_CLOSURE",
- "iternextfunc", "SWIGPY_ITERNEXTFUNC_CLOSURE",
- NULL
- };
-
- static const char *funpack_functypes[] = {
- "unaryfunc", "SWIGPY_UNARYFUNC_CLOSURE",
- "destructor", "SWIGPY_DESTRUCTOR_CLOSURE",
- "inquiry", "SWIGPY_INQUIRY_CLOSURE",
- "getiterfunc", "SWIGPY_GETITERFUNC_CLOSURE",
- "ternaryfunc", "SWIGPY_TERNARYFUNC_CLOSURE",
- "ternarycallfunc", "SWIGPY_TERNARYCALLFUNC_CLOSURE",
- "lenfunc", "SWIGPY_LENFUNC_CLOSURE",
- "ssizeargfunc", "SWIGPY_FUNPACK_SSIZEARGFUNC_CLOSURE",
- "ssizessizeargfunc", "SWIGPY_SSIZESSIZEARGFUNC_CLOSURE",
- "ssizeobjargproc", "SWIGPY_SSIZEOBJARGPROC_CLOSURE",
- "ssizessizeobjargproc", "SWIGPY_SSIZESSIZEOBJARGPROC_CLOSURE",
- "objobjproc", "SWIGPY_FUNPACK_OBJOBJPROC_CLOSURE",
- "objobjargproc", "SWIGPY_OBJOBJARGPROC_CLOSURE",
- "reprfunc", "SWIGPY_REPRFUNC_CLOSURE",
- "hashfunc", "SWIGPY_HASHFUNC_CLOSURE",
- "iternextfunc", "SWIGPY_ITERNEXTFUNC_CLOSURE",
- NULL
- };
-
- if (!functype)
- return NULL;
- char *c = Char(functype);
- int i;
- if (funpack) {
- for (i = 0; funpack_functypes[i] != NULL; i += 2) {
- if (!strcmp(c, funpack_functypes[i]))
- return NewStringf("%s(%s)", funpack_functypes[i + 1], wrapper);
- }
- } else {
- for (i = 0; functypes[i] != NULL; i += 2) {
- if (!strcmp(c, functypes[i]))
- return NewStringf("%s(%s)", functypes[i + 1], wrapper);
- }
- }
- return NULL;
-}
-
-class PYTHON:public Language {
-public:
- PYTHON() {
- /* Add code to manage protected constructors and directors */
- director_prot_ctor_code = NewString("");
- Printv(director_prot_ctor_code,
- "if ( $comparison ) { /* subclassed */\n",
- " $director_new \n",
- "} else {\n", " SWIG_SetErrorMsg(PyExc_RuntimeError,\"accessing abstract class or protected constructor\"); \n", " SWIG_fail;\n", "}\n", NIL);
- director_multiple_inheritance = 1;
- director_language = 1;
- }
-
- ~PYTHON() {
- delete doxygenTranslator;
- }
-
- /* ------------------------------------------------------------
- * Thread Implementation
- * ------------------------------------------------------------ */
- int threads_enable(Node *n) const {
- return threads && !GetFlagAttr(n, "feature:nothread");
- }
-
- int initialize_threads(String *f_init) {
- if (!threads) {
- return SWIG_OK;
- }
- Printf(f_init, "\n");
- Printf(f_init, "/* Initialize threading */\n");
- Printf(f_init, "SWIG_PYTHON_INITIALIZE_THREADS;\n");
-
- return SWIG_OK;
- }
-
- virtual void thread_begin_block(Node *n, String *f) {
- if (!GetFlag(n, "feature:nothreadblock")) {
- String *bb = Getattr(n, "feature:threadbeginblock");
- if (bb) {
- Append(f, bb);
- } else {
- Append(f, "SWIG_PYTHON_THREAD_BEGIN_BLOCK;\n");
- }
- }
- }
-
- virtual void thread_end_block(Node *n, String *f) {
- if (!GetFlag(n, "feature:nothreadblock")) {
- String *eb = Getattr(n, "feature:threadendblock");
- if (eb) {
- Append(f, eb);
- } else {
- Append(f, "SWIG_PYTHON_THREAD_END_BLOCK;\n");
- }
- }
- }
-
- virtual void thread_begin_allow(Node *n, String *f) {
- if (!GetFlag(n, "feature:nothreadallow")) {
- String *bb = Getattr(n, "feature:threadbeginallow");
- Append(f, "{\n");
- if (bb) {
- Append(f, bb);
- } else {
- Append(f, "SWIG_PYTHON_THREAD_BEGIN_ALLOW;\n");
- }
- }
- }
-
- virtual void thread_end_allow(Node *n, String *f) {
- if (!GetFlag(n, "feature:nothreadallow")) {
- String *eb = Getattr(n, "feature:threadendallow");
- Append(f, "\n");
- if (eb) {
- Append(f, eb);
- } else {
- Append(f, "SWIG_PYTHON_THREAD_END_ALLOW;");
- }
- Append(f, "\n}");
- }
- }
-
-
- /* ------------------------------------------------------------
- * main()
- * ------------------------------------------------------------ */
-
- virtual void main(int argc, char *argv[]) {
-
- SWIG_library_directory("python");
-
- int doxygen_translator_flags = 0;
-
- for (int i = 1; i < argc; i++) {
- if (argv[i]) {
- if (strcmp(argv[i], "-interface") == 0) {
- if (argv[i + 1]) {
- interface = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-globals") == 0) {
- if (argv[i + 1]) {
- global_name = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if ((strcmp(argv[i], "-shadow") == 0) || ((strcmp(argv[i], "-proxy") == 0))) {
- shadow = 1;
- Swig_mark_arg(i);
- } else if ((strcmp(argv[i], "-noproxy") == 0)) {
- shadow = 0;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-keyword") == 0) {
- use_kw = 1;
- SWIG_cparse_set_compact_default_args(1);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nortti") == 0) {
- nortti = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-threads") == 0) {
- threads = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nothreads") == 0) {
- /* Turn off thread support mode */
- nothreads = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-dirvtable") == 0) {
- dirvtable = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-doxygen") == 0) {
- doxygen = 1;
- scan_doxygen_comments = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-debug-doxygen-translator") == 0) {
- doxygen_translator_flags |= DoxygenTranslator::debug_translator;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-debug-doxygen-parser") == 0) {
- doxygen_translator_flags |= DoxygenTranslator::debug_parser;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nofastunpack") == 0) {
- fastunpack = 0;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-fastproxy") == 0) {
- fastproxy = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-olddefs") == 0) {
- olddefs = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-castmode") == 0) {
- castmode = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-extranative") == 0) {
- extranative = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-flatstaticmethod") == 0) {
- flat_static_method = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-noh") == 0) {
- no_header_file = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-newvwm") == 0) {
- /* Turn on new value wrapper mode */
- /* Undocumented option, did have -help text: New value wrapper mode, use only when everything else fails */
- Swig_value_wrapper_mode(1);
- no_header_file = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-O") == 0) {
- fastproxy = 1;
- Wrapper_fast_dispatch_mode_set(1);
- Wrapper_virtual_elimination_mode_set(1);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-help") == 0) {
- fputs(usage1, stdout);
- fputs(usage2, stdout);
- fputs(usage3, stdout);
- } else if (strcmp(argv[i], "-builtin") == 0) {
- builtin = 1;
- Preprocessor_define("SWIGPYTHON_BUILTIN", 0);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-relativeimport") == 0) {
- relativeimport = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-cppcast") == 0 ||
- strcmp(argv[i], "-fastinit") == 0 ||
- strcmp(argv[i], "-fastquery") == 0 ||
- strcmp(argv[i], "-fastunpack") == 0 ||
- strcmp(argv[i], "-modern") == 0 ||
- strcmp(argv[i], "-modernargs") == 0 ||
- strcmp(argv[i], "-noproxydel") == 0 ||
- strcmp(argv[i], "-safecstrings") == 0) {
- Printf(stderr, "Deprecated command line option: %s. Ignored, this option is now always on.\n", argv[i]);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-py3") == 0) {
- Printf(stderr, "Deprecated command line option: %s. Ignored, this option is no longer supported.\n", argv[i]);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-aliasobj0") == 0 ||
- strcmp(argv[i], "-buildnone") == 0 ||
- strcmp(argv[i], "-classic") == 0 ||
- strcmp(argv[i], "-classptr") == 0 ||
- strcmp(argv[i], "-new_repr") == 0 ||
- strcmp(argv[i], "-new_vwm") == 0 ||
- strcmp(argv[i], "-newrepr") == 0 ||
- strcmp(argv[i], "-noaliasobj0") == 0 ||
- strcmp(argv[i], "-nobuildnone") == 0 ||
- strcmp(argv[i], "-nocastmode") == 0 ||
- strcmp(argv[i], "-nocppcast") == 0 ||
- strcmp(argv[i], "-nodirvtable") == 0 ||
- strcmp(argv[i], "-noextranative") == 0 ||
- strcmp(argv[i], "-nofastinit") == 0 ||
- strcmp(argv[i], "-nofastproxy") == 0 ||
- strcmp(argv[i], "-nofastquery") == 0 ||
- strcmp(argv[i], "-nomodern") == 0 ||
- strcmp(argv[i], "-nomodernargs") == 0 ||
- strcmp(argv[i], "-noolddefs") == 0 ||
- strcmp(argv[i], "-nooutputtuple") == 0 ||
- strcmp(argv[i], "-noproxyimport") == 0 ||
- strcmp(argv[i], "-nosafecstrings") == 0 ||
- strcmp(argv[i], "-old_repr") == 0 ||
- strcmp(argv[i], "-oldrepr") == 0 ||
- strcmp(argv[i], "-outputtuple") == 0 ||
- strcmp(argv[i], "-proxydel") == 0) {
- Printf(stderr, "Deprecated command line option: %s. This option is no longer available.\n", argv[i]);
- Swig_mark_arg(i);
- Exit(EXIT_FAILURE);
- }
-
- }
- }
-
- if (builtin && !shadow) {
- Printf(stderr, "Incompatible options -builtin and -noproxy specified.\n");
- Exit(EXIT_FAILURE);
- }
-
- if (fastproxy) {
- Preprocessor_define("SWIGPYTHON_FASTPROXY", 0);
- }
-
- if (doxygen)
- doxygenTranslator = new PyDocConverter(doxygen_translator_flags);
-
- if (!global_name)
- global_name = NewString("cvar");
- Preprocessor_define("SWIGPYTHON 1", 0);
- SWIG_typemap_lang("python");
- SWIG_config_file("python.swg");
- allow_overloading();
- }
-
-
- /* ------------------------------------------------------------
- * top()
- * ------------------------------------------------------------ */
-
- virtual int top(Node *n) {
- /* check if directors are enabled for this module. note: this
- * is a "master" switch, without which no director code will be
- * emitted. %feature("director") statements are also required
- * to enable directors for individual classes or methods.
- *
- * use %module(directors="1") modulename at the start of the
- * interface file to enable director generation.
- */
- String *mod_docstring = NULL;
- String *moduleimport = NULL;
- {
- Node *mod = Getattr(n, "module");
- if (mod) {
- Node *options = Getattr(mod, "options");
- if (options) {
- int dirprot = 0;
- if (Getattr(options, "dirprot")) {
- dirprot = 1;
- }
- if (Getattr(options, "nodirprot")) {
- dirprot = 0;
- }
- if (Getattr(options, "directors")) {
- allow_directors();
- if (dirprot)
- allow_dirprot();
- }
- if (Getattr(options, "threads")) {
- threads = 1;
- }
- if (Getattr(options, "castmode")) {
- castmode = 1;
- }
- if (Getattr(options, "nocastmode")) {
- Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "nocastmode");
- Exit(EXIT_FAILURE);
- }
- if (Getattr(options, "extranative")) {
- extranative = 1;
- }
- if (Getattr(options, "noextranative")) {
- Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "noextranative");
- Exit(EXIT_FAILURE);
- }
- if (Getattr(options, "outputtuple")) {
- Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "outputtuple");
- Exit(EXIT_FAILURE);
- }
- if (Getattr(options, "nooutputtuple")) {
- Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "nooutputtuple");
- Exit(EXIT_FAILURE);
- }
- mod_docstring = Getattr(options, "docstring");
- package = Getattr(options, "package");
- moduleimport = Getattr(options, "moduleimport");
- }
- }
- }
-
- /* Set comparison with none for ConstructorToFunction */
- setSubclassInstanceCheck(NewString("$arg != Py_None"));
-
- /* Initialize all of the output files */
- String *outfile = Getattr(n, "outfile");
- String *outfile_h = !no_header_file ? Getattr(n, "outfile_h") : 0;
-
- f_begin = NewFile(outfile, "w", SWIG_output_files());
- if (!f_begin) {
- FileErrorDisplay(outfile);
- Exit(EXIT_FAILURE);
- }
- f_runtime = NewString("");
- f_init = NewString("");
- f_header = NewString("");
- f_wrappers = NewString("");
- f_directors_h = NewString("");
- f_directors = NewString("");
- builtin_getset = NewHash();
- builtin_closures = NewHash();
- builtin_closures_code = NewString("");
- class_members = NewHash();
- builtin_methods = NewString("");
- builtin_default_unref = NewString("delete $self;");
-
- if (builtin) {
- f_builtins = NewString("");
- }
-
- if (directorsEnabled()) {
- if (!no_header_file) {
- f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
- if (!f_runtime_h) {
- FileErrorDisplay(outfile_h);
- Exit(EXIT_FAILURE);
- }
- } else {
- f_runtime_h = f_runtime;
- }
- }
-
- /* Register file targets with the SWIG file handler */
- Swig_register_filebyname("header", f_header);
- Swig_register_filebyname("wrapper", f_wrappers);
- Swig_register_filebyname("begin", f_begin);
- Swig_register_filebyname("runtime", f_runtime);
- Swig_register_filebyname("init", f_init);
- Swig_register_filebyname("director", f_directors);
- Swig_register_filebyname("director_h", f_directors_h);
-
- const_code = NewString("");
- methods = NewString("");
- methods_proxydocs = NewString("");
-
- Swig_banner(f_begin);
-
- Swig_obligatory_macros(f_runtime, "PYTHON");
-
- if (directorsEnabled()) {
- Printf(f_runtime, "#define SWIG_DIRECTORS\n");
- }
-
- if (nothreads) {
- Printf(f_runtime, "#define SWIG_PYTHON_NO_THREADS\n");
- } else if (threads) {
- Printf(f_runtime, "#define SWIG_PYTHON_THREADS\n");
- }
-
- if (!dirvtable) {
- Printf(f_runtime, "#define SWIG_PYTHON_DIRECTOR_NO_VTABLE\n");
- }
-
- if (nortti) {
- Printf(f_runtime, "#ifndef SWIG_DIRECTOR_NORTTI\n");
- Printf(f_runtime, "#define SWIG_DIRECTOR_NORTTI\n");
- Printf(f_runtime, "#endif\n");
- }
-
- if (castmode) {
- Printf(f_runtime, "#define SWIG_CASTRANK_MODE\n");
- Printf(f_runtime, "#define SWIG_PYTHON_CAST_MODE\n");
- }
-
- if (extranative) {
- Printf(f_runtime, "#define SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS\n");
- }
-
- if (builtin) {
- Printf(f_runtime, "#define SWIGPYTHON_BUILTIN\n");
- }
-
- if (fastproxy) {
- Printf(f_runtime, "#define SWIGPYTHON_FASTPROXY\n");
- }
-
- Printf(f_runtime, "\n");
-
- Printf(f_header, "#ifdef SWIG_TypeQuery\n");
- Printf(f_header, "# undef SWIG_TypeQuery\n");
- Printf(f_header, "#endif\n");
- Printf(f_header, "#define SWIG_TypeQuery SWIG_Python_TypeQuery\n");
-
-
- /* Set module name */
- module = Copy(Getattr(n, "name"));
- mainmodule = Getattr(n, "name");
-
- if (directorsEnabled()) {
- Swig_banner(f_directors_h);
- Printf(f_directors_h, "\n");
- Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module);
- Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module);
- if (dirprot_mode()) {
- Printf(f_directors_h, "#include <map>\n");
- Printf(f_directors_h, "#include <string>\n\n");
- }
-
- Printf(f_directors, "\n\n");
- Printf(f_directors, "/* ---------------------------------------------------\n");
- Printf(f_directors, " * C++ director class methods\n");
- Printf(f_directors, " * --------------------------------------------------- */\n\n");
- if (outfile_h) {
- String *filename = Swig_file_filename(outfile_h);
- Printf(f_directors, "#include \"%s\"\n\n", filename);
- Delete(filename);
- }
- }
-
- /* If shadow classing is enabled, we're going to change the module name to "_module" */
- String *default_import_code = NewString("");
- if (shadow) {
- String *filen = NewStringf("%s%s.py", SWIG_output_directory(), Char(module));
- // If we don't have an interface then change the module name X to _X
- if (interface)
- module = interface;
- else
- Insert(module, 0, "_");
- if ((f_shadow_py = NewFile(filen, "w", SWIG_output_files())) == 0) {
- FileErrorDisplay(filen);
- Exit(EXIT_FAILURE);
- }
- Delete(filen);
- filen = NULL;
-
- f_shadow = NewString("");
- f_shadow_begin = NewString("");
- f_shadow_imports = NewHash();
- f_shadow_after_begin = NewString("");
- f_shadow_stubs = NewString("");
-
- Swig_register_filebyname("shadow", f_shadow);
- Swig_register_filebyname("python", f_shadow);
-
- if (!builtin) {
- /* Import the low-level C/C++ module. This should be a relative import,
- * since the shadow module may also have been imported by a relative
- * import, and there is thus no guarantee that the low-level C/C++ module is on
- * sys.path. Relative imports must be explicitly specified from 2.6.0
- * onwards (implicit relative imports raised a DeprecationWarning in 2.6,
- * and fail in 2.7 onwards).
- *
- * First check for __package__ which is available from 2.6 onwards, see PEP366.
- * Next try determine the shadow wrapper's package based on the __name__ it
- * was given by the importer that loaded it.
- * If the module is in a package, load the low-level C/C++ module from the
- * same package, otherwise load it as a global module.
- */
- Printv(default_import_code, "# Import the low-level C/C++ module\n", NULL);
- Printv(default_import_code, "if __package__ or \".\" in __name__:\n", NULL);
- Printv(default_import_code, tab4, "from . import ", module, "\n", NULL);
- Printv(default_import_code, "else:\n", NULL);
- Printv(default_import_code, tab4, "import ", module, "\n", NULL);
- } else {
- Printv(default_import_code, "# Pull in all the attributes from the low-level C/C++ module\n", NULL);
- Printv(default_import_code, "if __package__ or \".\" in __name__:\n", NULL);
- Printv(default_import_code, tab4, "from .", module, " import *\n", NULL);
- Printv(default_import_code, "else:\n", NULL);
- Printv(default_import_code, tab4, "from ", module, " import *\n", NULL);
- }
-
- if (!builtin) {
- /* Need builtins to qualify names like Exception that might also be
- defined in this module (try both Python 3 and Python 2 names) */
- Printv(f_shadow, "try:\n", tab4, "import builtins as __builtin__\n", "except ImportError:\n", tab4, "import __builtin__\n", NULL);
- }
-
- if (!builtin && fastproxy) {
- Printf(f_shadow, "\n");
- Printf(f_shadow, "_swig_new_instance_method = %s.SWIG_PyInstanceMethod_New\n", module);
- Printf(f_shadow, "_swig_new_static_method = %s.SWIG_PyStaticMethod_New\n", module);
- }
-
- if (!builtin) {
- Printv(f_shadow, "\n",
- "def _swig_repr(self):\n",
- tab4, "try:\n",
- tab4, tab4, "strthis = \"proxy of \" + self.this.__repr__()\n",
- tab4, "except __builtin__.Exception:\n",
- tab4, tab4, "strthis = \"\"\n",
- tab4, "return \"<%s.%s; %s >\" % (self.__class__.__module__, self.__class__.__name__, strthis,)\n\n", NIL);
-
- Printv(f_shadow, "\n",
- "def _swig_setattr_nondynamic_instance_variable(set):\n",
- tab4, "def set_instance_attr(self, name, value):\n",
- tab4, tab4, "if name == \"this\":\n",
- tab4, tab4, tab4, "set(self, name, value)\n",
- tab4, tab4, "elif name == \"thisown\":\n",
- tab4, tab4, tab4, "self.this.own(value)\n",
- tab4, tab4, "elif hasattr(self, name) and isinstance(getattr(type(self), name), property):\n",
- tab4, tab4, tab4, "set(self, name, value)\n",
- tab4, tab4, "else:\n",
- tab4, tab4, tab4, "raise AttributeError(\"You cannot add instance attributes to %s\" % self)\n",
- tab4, "return set_instance_attr\n\n", NIL);
-
- Printv(f_shadow, "\n",
- "def _swig_setattr_nondynamic_class_variable(set):\n",
- tab4, "def set_class_attr(cls, name, value):\n",
- tab4, tab4, "if hasattr(cls, name) and not isinstance(getattr(cls, name), property):\n",
- tab4, tab4, tab4, "set(cls, name, value)\n",
- tab4, tab4, "else:\n",
- tab4, tab4, tab4, "raise AttributeError(\"You cannot add class attributes to %s\" % cls)\n",
- tab4, "return set_class_attr\n\n", NIL);
-
- Printv(f_shadow, "\n",
- "def _swig_add_metaclass(metaclass):\n",
- tab4, "\"\"\"Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass\"\"\"\n",
- tab4, "def wrapper(cls):\n",
- tab4, tab4, "return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())\n",
- tab4, "return wrapper\n\n", NIL);
-
- Printv(f_shadow, "\n",
- "class _SwigNonDynamicMeta(type):\n",
- tab4, "\"\"\"Meta class to enforce nondynamic attributes (no new attributes) for a class\"\"\"\n",
- tab4, "__setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)\n",
- "\n", NIL);
-
- Printv(f_shadow, "\n", NIL);
-
- if (directorsEnabled())
- Printv(f_shadow, "import weakref\n\n", NIL);
- }
- }
- // Include some information in the code
- Printf(f_header, "\n/*-----------------------------------------------\n @(target):= %s.so\n\
- ------------------------------------------------*/\n", module);
-
- Printf(f_header, "#if PY_VERSION_HEX >= 0x03000000\n");
- Printf(f_header, "# define SWIG_init PyInit_%s\n\n", module);
- Printf(f_header, "#else\n");
- Printf(f_header, "# define SWIG_init init%s\n\n", module);
- Printf(f_header, "#endif\n");
- Printf(f_header, "#define SWIG_name \"%s\"\n", module);
-
- Printf(f_wrappers, "#ifdef __cplusplus\n");
- Printf(f_wrappers, "extern \"C\" {\n");
- Printf(f_wrappers, "#endif\n");
- Append(const_code, "static swig_const_info swig_const_table[] = {\n");
- Append(methods, "static PyMethodDef SwigMethods[] = {\n");
- Append(methods_proxydocs, "static PyMethodDef SwigMethods_proxydocs[] = {\n");
-
- /* the method exported for replacement of new.instancemethod in Python 3 */
- add_pyinstancemethod_new();
- add_pystaticmethod_new();
-
- if (builtin) {
- SwigType *s = NewString("SwigPyObject");
- SwigType_add_pointer(s);
- SwigType_remember(s);
- Delete(s);
- }
-
- /* emit code */
- Language::top(n);
-
- if (directorsEnabled()) {
- // Insert director runtime into the f_runtime file (make it occur before %header section)
- Swig_insert_file("director_common.swg", f_runtime);
- Swig_insert_file("director.swg", f_runtime);
- }
-
- /* Close language module */
- Append(methods, "\t { NULL, NULL, 0, NULL }\n");
- Append(methods, "};\n");
- Printf(f_wrappers, "%s\n", methods);
- Append(methods_proxydocs, "\t { NULL, NULL, 0, NULL }\n");
- Append(methods_proxydocs, "};\n");
- if ((fastproxy && !builtin) || have_fast_proxy_static_member_method_callback)
- Printf(f_wrappers, "%s\n", methods_proxydocs);
-
- if (builtin) {
- Dump(f_builtins, f_wrappers);
- }
-
- SwigType_emit_type_table(f_runtime, f_wrappers);
-
- Append(const_code, "{0, 0, 0, 0.0, 0, 0}};\n");
- Printf(f_wrappers, "%s\n", const_code);
-
- if (have_fast_proxy_static_member_method_callback)
- Printf(f_init, " SWIG_Python_FixMethods(SwigMethods_proxydocs, swig_const_table, swig_types, swig_type_initial);\n\n");
-
- initialize_threads(f_init);
-
- Printf(f_init, "#if PY_VERSION_HEX >= 0x03000000\n");
- Printf(f_init, " return m;\n");
- Printf(f_init, "#else\n");
- Printf(f_init, " return;\n");
- Printf(f_init, "#endif\n");
- Printf(f_init, "}\n");
-
- Printf(f_wrappers, "#ifdef __cplusplus\n");
- Printf(f_wrappers, "}\n");
- Printf(f_wrappers, "#endif\n");
-
- if (shadow) {
- Swig_banner_target_lang(f_shadow_py, "#");
-
- if (mod_docstring) {
- if (Len(mod_docstring)) {
- const char *triple_double = "\"\"\"";
- // follow PEP257 rules: https://www.python.org/dev/peps/pep-0257/
- // reported by pep257: https://github.com/GreenSteam/pep257
- bool multi_line_ds = Strchr(mod_docstring, '\n') != 0;
- Printv(f_shadow_py, "\n", triple_double, multi_line_ds ? "\n":"", mod_docstring, multi_line_ds ? "\n":"", triple_double, "\n", NIL);
- }
- Delete(mod_docstring);
- mod_docstring = NULL;
- }
-
- if (Len(f_shadow_begin) > 0)
- Printv(f_shadow_py, "\n", f_shadow_begin, "\n", NIL);
-
- Printv(f_shadow_py, "\nfrom sys import version_info as _swig_python_version_info\n", NULL);
-
- if (Len(f_shadow_after_begin) > 0)
- Printv(f_shadow_py, f_shadow_after_begin, "\n", NIL);
-
- if (moduleimport) {
- Replaceall(moduleimport, "$module", module);
- Printv(f_shadow_py, moduleimport, "\n", NIL);
- } else {
- Printv(f_shadow_py, default_import_code, NIL);
- }
-
- if (Len(f_shadow) > 0)
- Printv(f_shadow_py, "\n", f_shadow, "\n", NIL);
- if (Len(f_shadow_stubs) > 0)
- Printv(f_shadow_py, f_shadow_stubs, "\n", NIL);
- Delete(f_shadow_py);
- }
-
- /* Close all of the files */
- Dump(f_runtime, f_begin);
- Dump(f_header, f_begin);
-
- if (directorsEnabled()) {
- Dump(f_directors_h, f_runtime_h);
- Printf(f_runtime_h, "\n");
- Printf(f_runtime_h, "#endif\n");
- if (f_runtime_h != f_begin)
- Delete(f_runtime_h);
- Dump(f_directors, f_begin);
- }
-
- Dump(f_wrappers, f_begin);
- if (builtin && builtin_bases_needed)
- Printf(f_begin, "static PyTypeObject *builtin_bases[%d];\n\n", max_bases + 2);
- Wrapper_pretty_print(f_init, f_begin);
-
- Delete(default_import_code);
- Delete(f_shadow_after_begin);
- Delete(f_shadow_imports);
- Delete(f_shadow_begin);
- Delete(f_shadow);
- Delete(f_header);
- Delete(f_wrappers);
- Delete(f_builtins);
- Delete(f_init);
- Delete(f_directors);
- Delete(f_directors_h);
- Delete(f_runtime);
- Delete(f_begin);
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * Emit the wrapper for PyInstanceMethod_New to MethodDef array.
- * This wrapper is used to implement -fastproxy,
- * as a replacement of new.instancemethod in Python 3.
- * ------------------------------------------------------------ */
- int add_pyinstancemethod_new() {
- if (!builtin && fastproxy) {
- String *name = NewString("SWIG_PyInstanceMethod_New");
- String *line = NewString("");
- Printf(line, "\t { \"%s\", %s, METH_O, NULL},\n", name, name);
- Append(methods, line);
- Append(methods_proxydocs, line);
- Delete(line);
- Delete(name);
- }
- return 0;
- }
-
- /* ------------------------------------------------------------
- * Emit the wrapper for PyStaticMethod_New to MethodDef array.
- * This wrapper is used to ensure the correct documentation is
- * generated for static methods when using -fastproxy
- * ------------------------------------------------------------ */
- int add_pystaticmethod_new() {
- if (!builtin && fastproxy) {
- String *name = NewString("SWIG_PyStaticMethod_New");
- String *line = NewString("");
- Printf(line, "\t { \"%s\", %s, METH_O, NULL},\n", name, name);
- Append(methods, line);
- Append(methods_proxydocs, line);
- Delete(line);
- Delete(name);
- }
- return 0;
- }
-
- /* ------------------------------------------------------------
- * subpkg_tail()
- *
- * Return the name of 'other' package relative to 'base'.
- *
- * 1. If 'other' is a sub-package of 'base', returns the 'other' relative to
- * 'base'.
- * 2. If 'other' and 'base' are equal, returns empty string "".
- * 3. In any other case, NULL pointer is returned.
- *
- * The 'base' and 'other' are expected to be fully qualified names.
- *
- * NOTE: none of 'base' nor 'other' can be null.
- *
- * Examples:
- *
- * # base other tail
- * -- ---- ----- ----
- * 1 "Foo" "Foo.Bar" -> "Bar"
- * 2 "Foo" "Foo." -> ""
- * 3 "Foo" "FooB.ar" -> NULL
- * 4 "Foo.Bar" "Foo.Bar" -> ""
- * 5 "Foo.Bar" "Foo" -> NULL
- * 6 "Foo.Bar" "Foo.Gez" -> NULL
- *
- * NOTE: the example #2 is actually a syntax error (at input). I believe
- * swig parser prevents us from this case happening here.
- * ------------------------------------------------------------ */
-
- static String *subpkg_tail(const String *base, const String *other) {
- int baselen = Len(base);
- int otherlen = Len(other);
-
- if (Strncmp(other, base, baselen) == 0) {
- if ((baselen < otherlen) && (Char(other))[baselen] == '.') {
- return NewString((Char(other)) + baselen + 1);
- } else if (baselen == otherlen) {
- return NewString("");
- } else {
- return 0;
- }
- } else {
- return 0;
- }
- }
-
- /* ------------------------------------------------------------
- * abs_import_directive_string()
- *
- * Return a string containing python code to import module.
- *
- * pkg package name or the module being imported
- * mod module name of the module being imported
- * pfx optional prefix to module name
- *
- * NOTE: keep this function consistent with abs_import_name_string().
- * ------------------------------------------------------------ */
-
- static String *abs_import_directive_string(const String *pkg, const String *mod, const char *pfx = "") {
- String *out = NewString("");
-
- if (pkg && *Char(pkg)) {
- Printf(out, "import %s.%s%s\n", pkg, pfx, mod);
- } else {
- Printf(out, "import %s%s\n", pfx, mod);
- }
- return out;
- }
-
- /* ------------------------------------------------------------
- * rel_import_directive_string()
- *
- * Return a string containing python code to import module that
- * is potentially within a package.
- *
- * mainpkg package name of the module which imports the other module
- * pkg package name or the module being imported
- * mod module name of the module being imported
- * pfx optional prefix to module name
- *
- * NOTE: keep this function consistent with rel_import_name_string().
- * ------------------------------------------------------------ */
-
- static String *rel_import_directive_string(const String *mainpkg, const String *pkg, const String *mod, const char *pfx = "") {
-
- /* NOTE: things are not so trivial. This is what we do here (by examples):
- *
- * 0. To import module 'foo', which is not in any package, we do absolute
- * import:
- *
- * import foo
- *
- * 1. To import 'pkg1.pkg2.foo', when mainpkg != "pkg1" and
- * mainpkg != "pkg1.pkg2" or when mainpkg is not given we do absolute
- * import:
- *
- * import pkg1.pkg2.foo
- *
- * 2. To import module pkg1.foo, when mainpkg == "pkg1", we do:
- *
- * - for py3 = 0:
- *
- * import foo
- *
- * - for py3 = 1:
- *
- * from . import foo
- *
- * 3. To import "pkg1.pkg2.pkg3.foo", when mainpkg = "pkg1", we do:
- *
- * - for py3 == 0:
- *
- * import pkg2.pkg3.foo
- *
- * - for py3 == 1:
- *
- * from . import pkg2 # [1]
- * import pkg1.pkg2.pkg3.foo
- *
- * NOTE: [1] is necessary for pkg2.foo to be present in the importing module
- */
-
- String *apkg = 0; // absolute (FQDN) package name of pkg
- String *rpkg = 0; // relative package name
- int py3_rlen1 = 0; // length of 1st level sub-package name, used by py3
- String *out = NewString("");
-
- if (pkg && *Char(pkg)) {
- if (mainpkg) {
- String *tail = subpkg_tail(mainpkg, pkg);
- if (tail) {
- if (*Char(tail)) {
- rpkg = NewString(tail);
- const char *py3_end1 = Strchr(rpkg, '.');
- if (!py3_end1)
- py3_end1 = (Char(rpkg)) + Len(rpkg);
- py3_rlen1 = (int)(py3_end1 - Char(rpkg));
- } else {
- rpkg = NewString("");
- }
- Delete(tail);
- } else {
- apkg = NewString(pkg);
- }
- } else {
- apkg = NewString(pkg);
- }
- } else {
- apkg = NewString("");
- }
-
- if (apkg) {
- Printf(out, "import %s%s%s%s\n", apkg, *Char(apkg) ? "." : "", pfx, mod);
- Delete(apkg);
- } else {
- if (py3_rlen1)
- Printf(out, "from . import %.*s\n", py3_rlen1, rpkg);
- Printf(out, "from .%s import %s%s\n", rpkg, pfx, mod);
- Delete(rpkg);
- }
- return out;
- }
-
- /* ------------------------------------------------------------
- * import_directive_string()
- * ------------------------------------------------------------ */
-
- static String *import_directive_string(const String *mainpkg, const String *pkg, const String *mod, const char *pfx = "") {
- if (!relativeimport) {
- return abs_import_directive_string(pkg, mod, pfx);
- } else {
- return rel_import_directive_string(mainpkg, pkg, mod, pfx);
- }
- }
-
- /* ------------------------------------------------------------
- * abs_import_name_string()
- *
- * Return a string with the name of a symbol (perhaps imported
- * from external module by absolute import directive).
- *
- * mainpkg package name of current module
- * mainmod module name of current module
- * pkg package name of (perhaps other) module
- * mod module name of (perhaps other) module
- * sym symbol name
- *
- * NOTE: mainmod, mod, and sym can't be NULL.
- * NOTE: keep this function consistent with abs_import_directive_string()
- * ------------------------------------------------------------ */
-
- static String *abs_import_name_string(const String *mainpkg, const String *mainmod, const String *pkg, const String *mod, const String *sym) {
- String *out = NewString("");
- if (pkg && *Char(pkg)) {
- if (mainpkg && *Char(mainpkg)) {
- if (Strcmp(mainpkg,pkg) != 0 || Strcmp(mainmod, mod) != 0) {
- Printf(out, "%s.%s.", pkg, mod);
- }
- } else {
- Printf(out, "%s.%s.", pkg, mod);
- }
- } else if ((mainpkg && *Char(mainpkg)) || Strcmp(mainmod, mod) != 0) {
- Printf(out, "%s.", mod);
- }
- Append(out, sym);
- return out;
- }
-
- /* ------------------------------------------------------------
- * rel_import_name_string()
- *
- * Return a string with the name of a symbol (perhaps imported
- * from external module by relative import directive).
- *
- * mainpkg package name of current module
- * mainmod module name of current module
- * pkg package name of (perhaps other) module
- * mod module name of (perhaps other) module
- * sym symbol name
- *
- * NOTE: mainmod, mod, and sym can't be NULL.
- * NOTE: keep this function consistent with rel_import_directive_string()
- * ------------------------------------------------------------ */
-
- static String *rel_import_name_string(const String *mainpkg, const String *mainmod, const String *pkg, const String *mod, const String *sym) {
- String *out = NewString("");
- if (pkg && *Char(pkg)) {
- String *tail = 0;
- if (mainpkg)
- tail = subpkg_tail(mainpkg, pkg);
- if (!tail)
- tail = NewString(pkg);
- if (*Char(tail)) {
- Printf(out, "%s.%s.", tail, mod);
- } else if (Strcmp(mainmod, mod) != 0) {
- Printf(out, "%s.", mod);
- }
- Delete(tail);
- } else if ((mainpkg && *Char(mainpkg)) || Strcmp(mainmod, mod) != 0) {
- Printf(out, "%s.", mod);
- }
- Append(out, sym);
- return out;
- }
-
- /* ------------------------------------------------------------
- * import_name_string()
- * ------------------------------------------------------------ */
-
- static String *import_name_string(const String *mainpkg, const String *mainmod, const String *pkg, const String *mod, const String *sym) {
- if (!relativeimport) {
- return abs_import_name_string(mainpkg,mainmod,pkg,mod,sym);
- } else {
- return rel_import_name_string(mainpkg,mainmod,pkg,mod,sym);
- }
- }
-
- /* ------------------------------------------------------------
- * importDirective()
- * ------------------------------------------------------------ */
-
- virtual int importDirective(Node *n) {
- if (shadow) {
- String *modname = Getattr(n, "module");
-
- if (modname) {
- // Find the module node for this imported module. It should be the
- // first child but search just in case.
- Node *mod = firstChild(n);
- while (mod && Strcmp(nodeType(mod), "module") != 0)
- mod = nextSibling(mod);
-
- Node *options = Getattr(mod, "options");
- String *pkg = options ? Getattr(options, "package") : 0;
-
- if (!options || (!Getattr(options, "noshadow") && !Getattr(options, "noproxy"))) {
- String *_import = import_directive_string(package, pkg, modname, "_");
- if (!GetFlagAttr(f_shadow_imports, _import)) {
- String *import = import_directive_string(package, pkg, modname);
- Printf(builtin ? f_shadow_after_begin : f_shadow, "%s", import);
- Delete(import);
- SetFlag(f_shadow_imports, _import);
- }
- Delete(_import);
- }
-
- }
- }
- return Language::importDirective(n);
- }
-
- /* ------------------------------------------------------------
- * funcCall()
- *
- * Emit shadow code to call a function in the extension
- * module. Using proper argument and calling style for
- * given node n.
- * ------------------------------------------------------------ */
- String *funcCall(String *name, String *parms) {
- String *str = NewString("");
-
- Printv(str, module, ".", name, "(", parms, ")", NIL);
- return str;
- }
-
- /* ------------------------------------------------------------
- * indent_pythoncode()
- *
- * Format (indent) Python code.
- * Remove leading whitespace from 'code' and re-indent using
- * the indentation string in 'indent'.
- * ------------------------------------------------------------ */
-
- String *indent_pythoncode(const String *code, const_String_or_char_ptr indent, String *file, int line, const char *directive_name) {
- String *out = NewString("");
- String *temp;
- char *t;
- if (!indent)
- indent = "";
-
- temp = NewString(code);
-
- t = Char(temp);
- if (*t == '{') {
- Delitem(temp, 0);
- Delitem(temp, DOH_END);
- }
-
- /* Split the input text into lines */
- List *clist = SplitLines(temp);
- Delete(temp);
-
- // Line number within the pythoncode.
- int py_line = 0;
-
- String *initial = 0;
- Iterator si;
-
- /* Get the initial indentation. Skip lines which only contain whitespace
- * and/or a comment, as the indentation of those doesn't matter:
- *
- * A logical line that contains only spaces, tabs, formfeeds and
- * possibly a comment, is ignored (i.e., no NEWLINE token is
- * generated).
- *
- * see:
- * https://docs.python.org/2/reference/lexical_analysis.html#blank-lines
- * https://docs.python.org/3/reference/lexical_analysis.html#blank-lines
- */
- for (si = First(clist); si.item; si = Next(si), ++py_line) {
- const char *c = Char(si.item);
- int i;
- for (i = 0; isspace((unsigned char)c[i]); i++) {
- // Scan forward until we find a non-space (which may be a null byte).
- }
- char ch = c[i];
- if (ch && ch != '#') {
- // Found a line with actual content.
- initial = NewStringWithSize(c, i);
- break;
- }
- if (ch) {
- Printv(out, indent, c, NIL);
- }
- Putc('\n', out);
- }
-
- // Process remaining lines.
- for ( ; si.item; si = Next(si), ++py_line) {
- const char *c = Char(si.item);
- // If no prefixed line was found, the above loop should have completed.
- assert(initial);
-
- int i;
- for (i = 0; isspace((unsigned char)c[i]); i++) {
- // Scan forward until we find a non-space (which may be a null byte).
- }
- char ch = c[i];
- if (!ch) {
- // Line is just whitespace - emit an empty line.
- Putc('\n', out);
- continue;
- }
-
- if (ch == '#') {
- // Comment - the indentation doesn't matter to python, but try to
- // adjust the whitespace for the benefit of human readers (though SWIG
- // currently seems to always remove any whitespace before a '#' before
- // we get here, in which case we'll just leave the comment at the start
- // of the line).
- if (i >= Len(initial)) {
- Printv(out, indent, NIL);
- }
-
- Printv(out, c + i, "\n", NIL);
- continue;
- }
-
- if (i < Len(initial)) {
- // There's non-whitespace in the initial prefix of this line.
- Swig_error(file, line, "Line indented less than expected (line %d of %s) as no line should be indented less than the indentation in line 1\n", py_line, directive_name);
- Printv(out, indent, c, "\n", NIL);
- } else {
- if (memcmp(c, Char(initial), Len(initial)) == 0) {
- // Prefix matches initial, so just remove it.
- Printv(out, indent, c + Len(initial), "\n", NIL);
- continue;
- }
- Swig_warning(WARN_PYTHON_INDENT_MISMATCH,
- file, line, "Whitespace indentation is inconsistent compared to earlier lines (line %d of %s)\n", py_line, directive_name);
- // To avoid gratuitously breaking interface files which worked with
- // SWIG <= 3.0.5, we remove a prefix of the same number of bytes for
- // lines which start with different whitespace to the line we got
- // 'initial' from.
- Printv(out, indent, c + Len(initial), "\n", NIL);
- }
- }
- Delete(clist);
- return out;
- }
-
- /* ------------------------------------------------------------
- * indent_docstring()
- *
- * Format (indent) a Python docstring.
- * Remove leading whitespace from 'code' and re-indent using
- * the indentation string in 'indent'.
- * ------------------------------------------------------------ */
-
- String *indent_docstring(const String *code, const_String_or_char_ptr indent) {
- String *out = NewString("");
- String *temp;
- char *t;
- if (!indent)
- indent = "";
-
- temp = NewString(code);
-
- t = Char(temp);
- if (*t == '{') {
- Delitem(temp, 0);
- Delitem(temp, DOH_END);
- }
-
- /* Split the input text into lines */
- List *clist = SplitLines(temp);
- Delete(temp);
-
- Iterator si;
-
- int truncate_characters_count = INT_MAX;
- for (si = First(clist); si.item; si = Next(si)) {
- const char *c = Char(si.item);
- int i;
- for (i = 0; isspace((unsigned char)c[i]); i++) {
- // Scan forward until we find a non-space (which may be a null byte).
- }
- char ch = c[i];
- if (ch) {
- // Found a line which isn't just whitespace
- if (i < truncate_characters_count)
- truncate_characters_count = i;
- }
- }
-
- if (truncate_characters_count == INT_MAX)
- truncate_characters_count = 0;
-
- for (si = First(clist); si.item; si = Next(si)) {
- const char *c = Char(si.item);
-
- int i;
- for (i = 0; isspace((unsigned char)c[i]); i++) {
- // Scan forward until we find a non-space (which may be a null byte).
- }
- char ch = c[i];
- if (!ch) {
- // Line is just whitespace - emit an empty line.
- Putc('\n', out);
- continue;
- }
-
- Printv(out, indent, c + truncate_characters_count, "\n", NIL);
- }
- Delete(clist);
- return out;
- }
-
- /* ------------------------------------------------------------
- * autodoc level declarations
- * ------------------------------------------------------------ */
-
- enum autodoc_l {
- NO_AUTODOC = -2, // no autodoc
- STRING_AUTODOC = -1, // use provided string
- NAMES_AUTODOC = 0, // only parameter names
- TYPES_AUTODOC = 1, // parameter names and types
- EXTEND_AUTODOC = 2, // extended documentation and parameter names
- EXTEND_TYPES_AUTODOC = 3 // extended documentation and parameter types + names
- };
-
-
- autodoc_l autodoc_level(String *autodoc) {
- autodoc_l dlevel = NO_AUTODOC;
- char *c = Char(autodoc);
- if (c) {
- if (isdigit(c[0])) {
- dlevel = (autodoc_l) atoi(c);
- } else {
- if (strcmp(c, "extended") == 0) {
- dlevel = EXTEND_AUTODOC;
- } else {
- dlevel = STRING_AUTODOC;
- }
- }
- }
- return dlevel;
- }
-
-
- /* ------------------------------------------------------------
- * have_docstring()
- *
- * Check if there is a docstring directive and it has text,
- * or there is an autodoc flag set
- * ------------------------------------------------------------ */
-
- bool have_docstring(Node *n) {
- String *str = Getattr(n, "feature:docstring");
- return ((str && Len(str) > 0)
- || (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc"))
- || (doxygen && doxygenTranslator->hasDocumentation(n))
- );
- }
-
- /* ------------------------------------------------------------
- * build_combined_docstring()
- *
- * Build the full docstring:
- * Use the docstring if there is one present otherwise
- * use the Doxygen comment if there is one present.
- * Ignore autodoc if there is a Doxygen comment, otherwise
- * create the autodoc string and append to any docstring.
- *
- * Return new string to be deleted by caller (never NIL but
- * may be empty if there is no docstring).
- * ------------------------------------------------------------ */
-
- String *build_combined_docstring(Node *n, autodoc_t ad_type, const String *indent = "", bool low_level = false) {
- bool add_autodoc = true;
- String *docstr = Getattr(n, "feature:docstring");
- if (docstr) {
- // Simplify the code below by just ignoring empty docstrings.
- if (!Len(docstr))
- docstr = NULL;
- else
- docstr = Copy(docstr);
- }
-
- if (docstr) {
- char *t = Char(docstr);
- if (*t == '{') {
- Delitem(docstr, 0);
- Delitem(docstr, DOH_END);
- }
- }
-
- if (!docstr) {
- if (doxygen && doxygenTranslator->hasDocumentation(n)) {
- docstr = Getattr(n, "python:docstring");
- if (!docstr) {
- docstr = doxygenTranslator->getDocumentation(n, 0);
-
- // Avoid rebuilding it again the next time: notice that we can't do
- // this for the combined doc string as autodoc part of it depends on
- // the sym:name of the node and it is changed while handling it, so
- // the cached results become incorrect. But Doxygen docstring only
- // depends on the comment which is not going to change, so we can
- // safely cache it.
- Setattr(n, "python:docstring", Copy(docstr));
- } else {
- // Must copy here since if the docstring is multi-line, the String*
- // here will get Deleted below, which is bad if it is a pointer to
- // the cached object!
- docstr = Copy(docstr);
- }
- add_autodoc = false;
- }
- }
-
- if (add_autodoc && Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")) {
- String *autodoc = make_autodoc(n, ad_type, low_level);
- if (autodoc && Len(autodoc) > 0) {
- if (docstr) {
- Append(autodoc, "\n");
- Append(autodoc, docstr);
- }
-
- String *tmp = autodoc;
- autodoc = docstr;
- docstr = tmp;
- }
-
- Delete(autodoc);
- }
-
- if (!docstr)
- docstr = NewString("");
-
- // If there is more than one line then make docstrings like this:
- //
- // """
- // This is line1
- // And here is line2 followed by the rest of them
- // """
- //
- // otherwise, put it all on a single line
- if (Strchr(docstr, '\n')) {
- String *tmp = NewString("");
- Append(tmp, "\n");
- Append(tmp, indent_docstring(docstr, indent));
- Append(tmp, indent);
- Delete(docstr);
- docstr = tmp;
- }
-
- return docstr;
- }
-
- /* ------------------------------------------------------------
- * docstring()
- *
- * Get the docstring text, stripping off {} if necessary,
- * and enclose in triple double quotes. If autodoc is also
- * set then it will build a combined docstring.
- * ------------------------------------------------------------ */
-
- String *docstring(Node *n, autodoc_t ad_type, const String *indent, bool low_level = false) {
- String *docstr = build_combined_docstring(n, ad_type, indent, low_level);
- const int len = Len(docstr);
- if (!len)
- return docstr;
-
- // Notice that all comments are created as raw strings (prefix "r"),
- // because '\' is used often in comments, but may break Python module from
- // loading. For example, in doxy comment one may write path in quotes:
- //
- // This is path to file "C:\x\file.txt"
- //
- // Python will not load the module with such comment because of illegal
- // escape '\x'. '\' may additionally appear in verbatim or htmlonly sections
- // of doxygen doc, Latex expressions, ...
- String *doc = NewString("");
-
- // Determine which kind of quotes to use as delimiters: for single line
- // strings we can avoid problems with having a quote as the last character
- // of the docstring by using different kind of quotes as delimiters. For
- // multi-line strings this problem doesn't arise, as we always have a new
- // line or spaces at the end of it, but it still does no harm to do it for
- // them too.
- //
- // Note: we use double quotes by default, i.e. if there is no reason to
- // prefer using single ones, for consistency with the older SWIG versions.
- const bool useSingleQuotes = (Char(docstr))[len - 1] == '"';
-
- Append(doc, useSingleQuotes ? "r'''" : "r\"\"\"");
-
- // We also need to avoid having triple quotes of whichever type we use, as
- // this would break Python doc string syntax too. Unfortunately there is no
- // way to have triple quotes inside of raw-triple-quoted string, so we have
- // to break the string in parts and rely on concatenation of the adjacent
- // string literals.
- if (useSingleQuotes)
- Replaceall(docstr, "'''", "''' \"'''\" '''");
- else
- Replaceall(docstr, "\"\"\"", "\"\"\" '\"\"\"' \"\"\"");
-
- Append(doc, docstr);
- Append(doc, useSingleQuotes ? "'''" : "\"\"\"");
- Delete(docstr);
-
- return doc;
- }
-
- /* ------------------------------------------------------------
- * cdocstring()
- *
- * Get the docstring text as it would appear in C-language
- * source code (but without quotes around it).
- * ------------------------------------------------------------ */
-
- String *cdocstring(Node *n, autodoc_t ad_type, bool low_level = false) {
- String *ds = build_combined_docstring(n, ad_type, "", low_level);
- Replaceall(ds, "\\", "\\\\");
- Replaceall(ds, "\"", "\\\"");
- Replaceall(ds, "\n", "\\n\"\n\t\t\"");
- return ds;
- }
-
- /* -----------------------------------------------------------------------------
- * addMissingParameterNames()
- *
- * For functions that have not had nameless parameters set in the Language class.
- *
- * Inputs:
- * plist - entire parameter list
- * arg_num - the number to start from when naming arguments
- * Side effects:
- * The "lname" attribute in each parameter in plist will be contain a parameter name
- * ----------------------------------------------------------------------------- */
-
- void addMissingParameterNames(Node *n, ParmList *plist, int arg_num) {
- Parm *p = plist;
- int i = arg_num;
- while (p) {
- if (!Getattr(p, "lname")) {
- String *name = makeParameterName(n, p, i);
- Setattr(p, "lname", name);
- Delete(name);
- }
- i++;
- p = nextSibling(p);
- }
- }
-
- /* ------------------------------------------------------------
- * make_autodocParmList()
- *
- * Generate the documentation for the function parameters
- * Parameters:
- * arg_num: The number to start assigning unnamed arguments from
- * func_annotation: Function annotation support
- * ------------------------------------------------------------ */
-
- String *make_autodocParmList(Node *n, bool showTypes, int arg_num = 1, bool calling = false, bool func_annotation = false) {
-
- String *doc = NewString("");
- String *pdocs = 0;
- ParmList *plist = CopyParmList(Getattr(n, "parms"));
- Parm *p;
- Parm *pnext;
-
- if (calling)
- func_annotation = false;
-
- addMissingParameterNames(n, plist, arg_num); // for $1_name substitutions done in Swig_typemap_attach_parms
- Swig_typemap_attach_parms("in", plist, 0);
- Swig_typemap_attach_parms("doc", plist, 0);
-
- if (Strcmp(ParmList_protostr(plist), "void") == 0) {
- //No parameters actually
- return doc;
- }
-
- for (p = plist; p; p = pnext) {
- String *tm = Getattr(p, "tmap:in");
- if (tm) {
- pnext = Getattr(p, "tmap:in:next");
- if (checkAttribute(p, "tmap:in:numinputs", "0")) {
- continue;
- }
- } else {
- pnext = nextSibling(p);
- }
-
- String *name = 0;
- String *type = 0;
- String *value = 0;
- String *pdoc = Getattr(p, "tmap:doc");
- if (pdoc) {
- name = Getattr(p, "tmap:doc:name");
- type = Getattr(p, "tmap:doc:type");
- value = Getattr(p, "tmap:doc:value");
- }
-
- // Skip the "self" argument - it is added to the parameter list automatically
- // and shouldn't be included in the Parameters block
- if (Getattr(p, "self")) {
- continue;
- }
-
- // Note: the generated name should be consistent with that in kwnames[]
- String *made_name = 0;
- if (!name) {
- name = made_name = makeParameterName(n, p, arg_num);
- }
-
- // Increment the argument number once we are sure this is a real argument to count
- arg_num++;
-
- type = type ? type : Getattr(p, "type");
- value = value ? value : Getattr(p, "value");
-
- if (SwigType_isvarargs(type)) {
- Delete(made_name);
- break;
- }
-
- if (Len(doc)) {
- // add a comma to the previous one if any
- Append(doc, ", ");
- }
-
- // Do the param type too?
- Node *nn = classLookup(Getattr(p, "type"));
- String *type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0);
- if (showTypes)
- Printf(doc, "%s ", type_str);
-
- Append(doc, name);
- if (pdoc) {
- if (!pdocs)
- // numpydoc style: https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
- pdocs = NewString("\nParameters\n----------\n");
- Printf(pdocs, "%s\n", pdoc);
- }
- // Write the function annotation
- if (func_annotation)
- Printf(doc, ": \"%s\"", type_str);
-
- // Write default value
- if (value && !calling) {
- String *new_value = convertValue(value, Getattr(p, "type"));
- if (new_value) {
- value = new_value;
- } else {
- // Even if the value is not representable in the target language, still use it in the documentation, for compatibility with the previous SWIG versions
- // and because it can still be useful to see the C++ expression there.
- Node *lookup = Swig_symbol_clookup(value, 0);
- if (lookup)
- value = Getattr(lookup, "sym:name");
- }
- Printf(doc, "=%s", value);
-
- if (new_value)
- Delete(new_value);
- }
- Delete(type_str);
- Delete(made_name);
- }
- if (pdocs)
- Setattr(n, "feature:pdocs", pdocs);
- Delete(plist);
- return doc;
- }
-
- /* ------------------------------------------------------------
- * make_autodoc()
- *
- * Build a docstring for the node, using parameter and other
- * info in the parse tree. If the value of the autodoc
- * attribute is "0" then do not include parameter types, if
- * it is "1" (the default) then do. If it has some other
- * value then assume it is supplied by the extension writer
- * and use it directly.
- * ------------------------------------------------------------ */
-
- String *make_autodoc(Node *n, autodoc_t ad_type, bool low_level = false) {
- int extended = 0;
- bool first_func = true;
- // If the function is overloaded then this function is called
- // for the last one. Rewind to the first so the docstrings are
- // in order.
- while (Getattr(n, "sym:previousSibling"))
- n = Getattr(n, "sym:previousSibling");
-
- String *doc = NewString("");
- while (n) {
- bool showTypes = false;
- bool skipAuto = false;
- String *autodoc = Getattr(n, "feature:autodoc");
- autodoc_l dlevel = autodoc_level(autodoc);
- switch (dlevel) {
- case NO_AUTODOC:
- break;
- case NAMES_AUTODOC:
- showTypes = false;
- break;
- case TYPES_AUTODOC:
- showTypes = true;
- break;
- case EXTEND_AUTODOC:
- extended = 1;
- showTypes = false;
- break;
- case EXTEND_TYPES_AUTODOC:
- extended = 1;
- showTypes = true;
- break;
- case STRING_AUTODOC:
- Append(doc, autodoc);
- skipAuto = true;
- break;
- }
-
- if (!skipAuto) {
- /* Check if a documentation name was given for either the low-level C API or high-level Python shadow API */
- String *symname = Getattr(n, low_level ? "doc:low:name" : "doc:high:name");
- if (!symname) {
- symname = Getattr(n, "sym:name");
- }
-
- SwigType *type = Getattr(n, "type");
- String *type_str = NULL;
-
- // If the function has default arguments, then that documentation covers this version too
- if (Getattr(n, "defaultargs") != NULL) {
- n = Getattr(n, "sym:nextSibling");
- continue;
- }
-
- if (!first_func)
- Append(doc, "\n");
-
- if (type) {
- if (Strcmp(type, "void") == 0) {
- type_str = NULL;
- } else {
- Node *nn = classLookup(type);
- type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0);
- }
- }
-
- /* Treat the low-level C API functions for getting/setting variables as methods for documentation purposes */
- String *kind = Getattr(n, "kind");
- if (kind && Strcmp(kind, "variable") == 0) {
- if (ad_type == AUTODOC_FUNC) {
- ad_type = AUTODOC_METHOD;
- }
- }
- /* Treat destructors as methods for documentation purposes */
- String *nodeType = Getattr(n, "nodeType");
- if (nodeType && Strcmp(nodeType, "destructor") == 0) {
- if (ad_type == AUTODOC_FUNC) {
- ad_type = AUTODOC_METHOD;
- }
- }
-
- switch (ad_type) {
- case AUTODOC_CLASS:
- {
- // Only do the autodoc if there isn't a docstring for the class
- String *str = Getattr(n, "feature:docstring");
- if (!str || Len(str) == 0) {
- if (builtin) {
- String *name = Getattr(n, "name");
- String *rname = add_explicit_scope(SwigType_namestr(name));
- Printf(doc, "%s", rname);
- Delete(rname);
- } else {
- if (CPlusPlus) {
- Printf(doc, "Proxy of C++ %s class.", SwigType_namestr(real_classname));
- } else {
- Printf(doc, "Proxy of C %s struct.", SwigType_namestr(real_classname));
- }
- }
- }
- }
- break;
- case AUTODOC_CTOR:
- if (Strcmp(class_name, symname) == 0) {
- String *paramList = make_autodocParmList(n, showTypes, 2);
- Printf(doc, "__init__(");
- if (showTypes)
- Printf(doc, "%s ", class_name);
- if (Len(paramList))
- Printf(doc, "self, %s) -> %s", paramList, class_name);
- else
- Printf(doc, "self) -> %s", class_name);
- } else
- Printf(doc, "%s(%s) -> %s", symname, make_autodocParmList(n, showTypes), class_name);
- break;
-
- case AUTODOC_DTOR:
- if (showTypes)
- Printf(doc, "__del__(%s self)", class_name);
- else
- Printf(doc, "__del__(self)");
- break;
-
- case AUTODOC_STATICFUNC:
- Printf(doc, "%s(%s)", symname, make_autodocParmList(n, showTypes));
- if (type_str)
- Printf(doc, " -> %s", type_str);
- break;
-
- case AUTODOC_FUNC:
- Printf(doc, "%s(%s)", symname, make_autodocParmList(n, showTypes));
- if (type_str)
- Printf(doc, " -> %s", type_str);
- break;
-
- case AUTODOC_METHOD:
- {
- String *paramList = make_autodocParmList(n, showTypes, 2);
- Printf(doc, "%s(", symname);
- if (showTypes)
- Printf(doc, "%s ", class_name);
- if (Len(paramList))
- Printf(doc, "self, %s)", paramList);
- else
- Printf(doc, "self)");
- if (type_str)
- Printf(doc, " -> %s", type_str);
- }
- break;
-
- case AUTODOC_CONST:
- // There is no autodoc support for constants currently, this enum
- // element only exists to allow calling docstring() with it.
- return NULL;
- case AUTODOC_VAR:
- // Variables can also be documented (e.g. through the property() function in python)
- Printf(doc, "%s", symname);
- if (showTypes) {
- String *type = Getattr(n, "tmap:doc:type");
- if (!type)
- type = Getattr(n, "membervariableHandler:type");
- if (!type)
- type = Getattr(n, "type");
- Printf(doc, " : %s", type);
- }
- break;
- }
- Delete(type_str);
-
- // Special case: wrapper functions to get a variable should have no parameters.
- // Because the node is re-used for the setter and getter, the feature:pdocs field will
- // exist for the getter function, so explicitly avoid printing parameters in this case.
- bool variable_getter = kind && Strcmp(kind, "variable") == 0 && Getattr(n, "memberget");
- if (extended && ad_type != AUTODOC_VAR && !variable_getter) {
- String *pdocs = Getattr(n, "feature:pdocs");
- if (pdocs) {
- Printv(doc, "\n", pdocs, NULL);
- }
- }
- }
- // if it's overloaded then get the next decl and loop around again
- n = Getattr(n, "sym:nextSibling");
- if (n)
- first_func = false;
- }
-
- return doc;
- }
-
- /* ------------------------------------------------------------
- * convertIntegerValue()
- *
- * Check if string v is an integer and can be represented in
- * Python. If so, return an appropriate Python representation,
- * otherwise (or if we are unsure), return NIL.
- * ------------------------------------------------------------ */
- String *convertIntegerValue(String *v, SwigType *resolved_type) {
- const char *const s = Char(v);
- char *end;
- String *result = NIL;
-
- // Check if this is an integer number in any base.
- errno = 0;
- long value = strtol(s, &end, 0);
- if (errno == ERANGE || end == s)
- return NIL;
-
- if (*end != '\0') {
- // If there is a suffix after the number, we can safely ignore "l"
- // and (provided the number is unsigned) "u", and also combinations of
- // these, but not anything else.
- for (char *p = end; *p != '\0'; ++p) {
- switch (*p) {
- case 'l':
- case 'L':
- break;
- case 'u':
- case 'U':
- if (value < 0)
- return NIL;
- break;
- default:
- return NIL;
- }
- }
- }
- // So now we are certain that we are indeed dealing with an integer
- // that has a representation as long given by value.
-
- // Restrict to guaranteed supported range in Python, see maxint docs: https://docs.python.org/2/library/sys.html#sys.maxint
- // Don't do this pointless check when long is 32 bits or smaller as strtol will have already failed with ERANGE
-#if LONG_MAX > PYTHON_INT_MAX || LONG_MIN < PYTHON_INT_MIN
- if (value > PYTHON_INT_MAX || value < PYTHON_INT_MIN) {
- return NIL;
- }
-#endif
-
- if (Cmp(resolved_type, "bool") == 0)
- // Allow integers as the default value for a bool parameter.
- return NewString(value ? "True" : "False");
-
- if (value == 0)
- return NewString(SwigType_ispointer(resolved_type) ? "None" : "0");
-
- // v may still be octal or hexadecimal:
- const char *p = s;
- if (*p == '+' || *p == '-')
- ++p;
- if (*p == '0' && *(p+1) != 'x' && *(p+1) != 'X') {
- // This must have been an octal number. This is the only case we
- // cannot use in Python directly, since Python 2 and 3 use non-
- // compatible representations.
- result = NewString(*s == '-' ? "int(\"-" : "int(\"");
- String *octal_string = NewStringWithSize(p, (int) (end - p));
- Append(result, octal_string);
- Append(result, "\", 8)");
- Delete(octal_string);
- return result;
- }
- result = *end == '\0' ? Copy(v) : NewStringWithSize(s, (int) (end - s));
- return result;
- }
-
- /* ------------------------------------------------------------
- * convertDoubleValue()
- *
- * Check if the given string looks like a decimal floating point constant
- * and return it if it does, otherwise return NIL.
- * ------------------------------------------------------------ */
- String *convertDoubleValue(String *v) {
- const char *const s = Char(v);
- char *end;
-
- errno = 0;
- double value = strtod(s, &end);
- (void) value;
- if (errno != ERANGE && end != s) {
- // An added complication: at least some versions of strtod() recognize
- // hexadecimal floating point numbers which don't exist in Python, so
- // detect them ourselves and refuse to convert them (this can't be done
- // without loss of precision in general).
- //
- // Also don't accept neither "NAN" nor "INFINITY" (both of which
- // conveniently contain "n").
- if (strpbrk(s, "xXnN"))
- return NIL;
-
- // Disregard optional "f" suffix, it can be just dropped in Python as it
- // uses doubles for everything anyhow.
- for (char * p = end; *p != '\0'; ++p) {
- switch (*p) {
- case 'f':
- case 'F':
- break;
-
- default:
- return NIL;
- }
- }
-
- // Avoid unnecessary string allocation in the common case when we don't
- // need to remove any suffix.
- return *end == '\0' ? Copy(v) : NewStringWithSize(s, (int)(end - s));
- }
-
- return NIL;
- }
-
- /* ------------------------------------------------------------
- * convertValue()
- *
- * Check if string v can be a Python value literal or a
- * constant. Return an equivalent Python representation,
- * or NIL if it isn't, or we are unsure.
- * ------------------------------------------------------------ */
- String *convertValue(String *v, SwigType *type) {
- const char *const s = Char(v);
- String *result = NIL;
- SwigType *resolved_type = SwigType_typedef_resolve_all(type);
-
- result = convertIntegerValue(v, resolved_type);
- if (!result) {
- result = convertDoubleValue(v);
- if (!result) {
- if (Strcmp(v, "true") == 0)
- result = NewString("True");
- else if (Strcmp(v, "false") == 0)
- result = NewString("False");
- else if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0)
- result = SwigType_ispointer(resolved_type) ? NewString("None") : NewString("0");
- // This could also be an enum type, default value of which could be
- // representable in Python if it doesn't include any scope (which could,
- // but currently is not, translated).
- else if (!Strchr(s, ':')) {
- Node *lookup = Swig_symbol_clookup(v, 0);
- if (lookup) {
- if (Cmp(Getattr(lookup, "nodeType"), "enumitem") == 0)
- result = Copy(Getattr(lookup, "sym:name"));
- }
- }
- }
- }
-
- Delete(resolved_type);
- return result;
- }
-
- /* ------------------------------------------------------------
- * is_representable_as_pyargs()
- *
- * Check if the function parameters default argument values
- * can be represented in Python.
- *
- * If this method returns false, the parameters will be translated
- * to a generic "*args" which allows us to deal with default values
- * at C++ code level where they can always be handled.
- * ------------------------------------------------------------ */
- bool is_representable_as_pyargs(Node *n) {
- ParmList *plist = CopyParmList(Getattr(n, "parms"));
- Swig_typemap_attach_parms("default", plist, NULL);
-
- Parm *p;
- Parm *pnext;
-
- for (p = plist; p; p = pnext) {
- pnext = nextSibling(p);
- String *tm = Getattr(p, "tmap:in");
- if (tm) {
- Parm *in_next = Getattr(p, "tmap:in:next");
- if (in_next)
- pnext = in_next;
- if (checkAttribute(p, "tmap:in:numinputs", "0")) {
- continue;
- }
- }
-
- // "default" typemap can contain arbitrary C++ code, so while it could, in
- // principle, be possible to examine it and check if it's just something
- // simple of the form "$1 = expression" and then use convertValue() to
- // check if expression can be used in Python, but for now we just
- // pessimistically give up and prefer to handle this at C++ level only.
- if (Getattr(p, "tmap:default"))
- return false;
-
- String *value = Getattr(p, "value");
- if (value) {
- String *convertedValue = convertValue(value, Getattr(p, "type"));
- if (!convertedValue)
- return false;
- Delete(convertedValue);
- }
- }
-
- return true;
- }
-
-
- /* ------------------------------------------------------------
- * is_real_overloaded()
- *
- * Check if the function is overloaded, but not just have some
- * siblings generated due to the original function having
- * default arguments.
- * ------------------------------------------------------------ */
- bool is_real_overloaded(Node *n) {
- Node *h = Getattr(n, "sym:overloaded");
- Node *i;
- if (!h)
- return false;
-
- i = Getattr(h, "sym:nextSibling");
- while (i) {
- Node *nn = Getattr(i, "defaultargs");
- if (nn != h) {
- /* Check if overloaded function has defaultargs and
- * pointed to the first overloaded. */
- return true;
- }
- i = Getattr(i, "sym:nextSibling");
- }
-
- return false;
- }
-
- /* ------------------------------------------------------------
- * make_pyParmList()
- *
- * Generate parameter list for Python functions or methods,
- * reuse make_autodocParmList() to do so.
- * ------------------------------------------------------------ */
- String *make_pyParmList(Node *n, bool in_class, bool is_calling, int kw, bool has_self_for_count = false) {
- /* Get the original function for a defaultargs copy,
- * see default_arguments() in parser.y. */
- Node *nn = Getattr(n, "defaultargs");
- if (nn)
- n = nn;
-
- Parm *parms = Getattr(n, "parms");
- int varargs = parms ? emit_isvarargs(parms) : 0;
-
- /* We prefer to explicitly list all parameters of the C function in the
- generated Python code as this makes the function more convenient to use,
- however in some cases we must replace the real parameters list with just
- the catch all "*args". This happens when:
-
- 1. The function is overloaded as Python doesn't support this.
- 2. We were explicitly asked to use the "compact" arguments form.
- 3. We were explicitly asked to use default args from C via the "python:cdefaultargs" feature.
- 4. One of the default argument values can't be represented in Python.
- 5. Varargs that haven't been forced to use a fixed number of arguments with %varargs.
- */
- if (is_real_overloaded(n) || GetFlag(n, "feature:compactdefaultargs") || GetFlag(n, "feature:python:cdefaultargs") || !is_representable_as_pyargs(n) || varargs) {
- String *parms = NewString("");
- if (in_class)
- Printf(parms, "self, ");
- Printf(parms, "*args");
- if (kw)
- Printf(parms, ", **kwargs");
- return parms;
- }
-
- bool funcanno = Equal(Getattr(n, "feature:python:annotations"), "c") ? true : false;
- String *params = NewString("");
- String *_params = make_autodocParmList(n, false, ((in_class || has_self_for_count)? 2 : 1), is_calling, funcanno);
-
- if (in_class) {
- Printf(params, "self");
- if (Len(_params) > 0)
- Printf(params, ", ");
- }
-
- Printv(params, _params, NULL);
-
- return params;
- }
-
- /* ------------------------------------------------------------
- * have_pythonprepend()
- *
- * Check if there is a %pythonprepend directive and it has text
- * ------------------------------------------------------------ */
-
- bool have_pythonprepend(Node *n) {
- String *str = Getattr(n, "feature:pythonprepend");
- return (str && Len(str) > 0);
- }
-
- /* ------------------------------------------------------------
- * pythonprepend()
- *
- * Get the %pythonprepend code, stripping off {} if necessary
- * ------------------------------------------------------------ */
-
- String *pythonprepend(Node *n) {
- String *str = Getattr(n, "feature:pythonprepend");
- char *t = Char(str);
- if (*t == '{') {
- Delitem(str, 0);
- Delitem(str, DOH_END);
- }
- return str;
- }
-
- /* ------------------------------------------------------------
- * have_pythonappend()
- *
- * Check if there is a %pythonappend directive and it has text
- * ------------------------------------------------------------ */
-
- bool have_pythonappend(Node *n) {
- String *str = Getattr(n, "feature:pythonappend");
- if (!str)
- str = Getattr(n, "feature:addtofunc");
- return (str && Len(str) > 0);
- }
-
- /* ------------------------------------------------------------
- * pythonappend()
- *
- * Get the %pythonappend code, stripping off {} if necessary
- * ------------------------------------------------------------ */
-
- String *pythonappend(Node *n) {
- String *str = Getattr(n, "feature:pythonappend");
- if (!str)
- str = Getattr(n, "feature:addtofunc");
-
- char *t = Char(str);
- if (*t == '{') {
- Delitem(str, 0);
- Delitem(str, DOH_END);
- }
- return str;
- }
-
- /* ------------------------------------------------------------
- * have_addtofunc()
- *
- * Check if there is a %addtofunc directive and it has text
- * ------------------------------------------------------------ */
-
- bool have_addtofunc(Node *n) {
- return have_pythonappend(n) || have_pythonprepend(n);
- }
-
-
- /* ------------------------------------------------------------
- * returnTypeAnnotation()
- *
- * Helper function for constructing the function annotation
- * of the returning type, return a empty string for Python 2.x
- * ------------------------------------------------------------ */
- String *returnTypeAnnotation(Node *n) {
- String *ret = 0;
- Parm *p = Getattr(n, "parms");
- String *tm;
- /* Try to guess the returning type by argout typemap,
- * however the result may not accurate. */
- while (p) {
- if ((tm = Getattr(p, "tmap:argout:match_type"))) {
- tm = SwigType_str(tm, 0);
- if (ret)
- Printv(ret, ", ", tm, NULL);
- else
- ret = tm;
- p = Getattr(p, "tmap:argout:next");
- } else {
- p = nextSibling(p);
- }
- }
- /* If no argout typemap, then get the returning type from
- * the function prototype. */
- if (!ret) {
- ret = Getattr(n, "type");
- if (ret)
- ret = SwigType_str(ret, 0);
- }
- bool funcanno = Equal(Getattr(n, "feature:python:annotations"), "c") ? true : false;
- return (ret && funcanno) ? NewStringf(" -> \"%s\"", ret) : NewString("");
- }
-
- /* ------------------------------------------------------------
- * variableAnnotation()
- *
- * Helper function for constructing a variable annotation
- * ------------------------------------------------------------ */
-
- String *variableAnnotation(Node *n) {
- String *type = Getattr(n, "type");
- if (type)
- type = SwigType_str(type, 0);
- bool anno = Equal(Getattr(n, "feature:python:annotations"), "c") ? true : false;
- anno = GetFlag(n, "feature:python:annotations:novar") ? false : anno;
- String *annotation = (type && anno) ? NewStringf(": \"%s\"", type) : NewString("");
- Delete(type);
- return annotation;
- }
-
- /* ------------------------------------------------------------
- * emitFunctionShadowHelper()
- *
- * Refactoring some common code out of functionWrapper and
- * dispatchFunction that writes the proxy code for non-member
- * functions.
- * ------------------------------------------------------------ */
-
- void emitFunctionShadowHelper(Node *n, File *f_dest, String *name, int kw) {
- String *parms = make_pyParmList(n, false, false, kw);
- String *callParms = make_pyParmList(n, false, true, kw);
-
- // Callbacks need the C function in order to extract the pointer from the swig_ptr: string
- bool fast = (fastproxy && !have_addtofunc(n)) || Getattr(n, "feature:callback");
-
- if (!fast || olddefs) {
- /* Make a wrapper function to insert the code into */
- Printv(f_dest, "\n", "def ", name, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
- if (have_docstring(n))
- Printv(f_dest, tab4, docstring(n, AUTODOC_FUNC, tab4, true), "\n", NIL);
- if (have_pythonprepend(n))
- Printv(f_dest, indent_pythoncode(pythonprepend(n), tab4, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
- if (have_pythonappend(n)) {
- Printv(f_dest, tab4 "val = ", funcCall(name, callParms), "\n", NIL);
- Printv(f_dest, indent_pythoncode(pythonappend(n), tab4, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
- Printv(f_dest, tab4 "return val\n", NIL);
- } else {
- Printv(f_dest, tab4 "return ", funcCall(name, callParms), "\n", NIL);
- }
- }
-
- // Below may result in a 2nd definition of the method when -olddefs is used. The Python interpreter will use the second definition as it overwrites the first.
- if (fast) {
- /* If there is no addtofunc directive then just assign from the extension module (for speed up) */
- Printv(f_dest, name, " = ", module, ".", name, "\n", NIL);
- }
- }
-
-
- /* ------------------------------------------------------------
- * check_kwargs()
- *
- * check if using kwargs is allowed for this Node
- * ------------------------------------------------------------ */
-
- int check_kwargs(Node *n) const {
- return (use_kw || GetFlag(n, "feature:kwargs"))
- && !GetFlag(n, "memberset") && !GetFlag(n, "memberget");
- }
-
-
-
- /* ------------------------------------------------------------
- * add_method()
- * ------------------------------------------------------------ */
-
- void add_method(String *name, String *function, int kw, Node *n = 0, int funpack = 0, int num_required = -1, int num_arguments = -1) {
- String * meth_str = NewString("");
- if (!kw) {
- if (funpack) {
- if (num_required == 0 && num_arguments == 0) {
- Printf(meth_str, "\t { \"%s\", %s, METH_NOARGS, ", name, function);
- } else if (num_required == 1 && num_arguments == 1) {
- Printf(meth_str, "\t { \"%s\", %s, METH_O, ", name, function);
- } else {
- Printf(meth_str, "\t { \"%s\", %s, METH_VARARGS, ", name, function);
- }
- } else {
- Printf(meth_str, "\t { \"%s\", %s, METH_VARARGS, ", name, function);
- }
- } else {
- // Cast via void(*)(void) to suppress GCC -Wcast-function-type warning.
- // Python should always call the function correctly, but the Python C API
- // requires us to store it in function pointer of a different type.
- Printf(meth_str, "\t { \"%s\", (PyCFunction)(void(*)(void))%s, METH_VARARGS|METH_KEYWORDS, ", name, function);
- }
- Append(methods, meth_str);
- if (fastproxy) {
- Append(methods_proxydocs, meth_str);
- }
- Delete(meth_str);
-
- if (!n) {
- Append(methods, "NULL");
- if (fastproxy) {
- Append(methods_proxydocs, "NULL");
- }
- } else if (have_docstring(n)) {
- /* Use the low-level docstring here since this is the docstring that will be used for the C API */
- String *ds = cdocstring(n, Getattr(n, "memberfunction") ? AUTODOC_METHOD : AUTODOC_FUNC, true);
- Printf(methods, "\"%s\"", ds);
- if (fastproxy) {
- /* In the fastproxy case, we must also record the high-level docstring for use in the Python shadow API */
- Delete(ds);
- ds = cdocstring(n, Getattr(n, "memberfunction") ? AUTODOC_METHOD : AUTODOC_FUNC);
- Printf(methods_proxydocs, "\"%s\"", ds);
- }
- Delete(ds);
- } else if (Getattr(n, "feature:callback")) {
- Printf(methods, "\"swig_ptr: %s\"", Getattr(n, "feature:callback:name"));
- if (fastproxy) {
- Printf(methods_proxydocs, "\"swig_ptr: %s\"", Getattr(n, "feature:callback:name"));
- have_fast_proxy_static_member_method_callback = true;
- }
- } else {
- Append(methods, "NULL");
- if (fastproxy) {
- Append(methods_proxydocs, "NULL");
- }
- }
-
- Append(methods, "},\n");
- if (fastproxy) {
- Append(methods_proxydocs, "},\n");
- }
- }
-
- /* ------------------------------------------------------------
- * dispatchFunction()
- * ------------------------------------------------------------ */
- void dispatchFunction(Node *n, String *linkage, int funpack = 0, bool builtin_self = false, bool builtin_ctor = false, bool director_class = false, bool use_static_method = false) {
- /* Last node in overloaded chain */
-
- bool add_self = builtin_self && (!builtin_ctor || director_class);
-
- int maxargs;
-
- String *tmp = NewString("");
- String *dispatch;
-
- const char *dispatch_call = funpack ? "%s(self, argc, argv);" : (builtin_ctor ? "%s(self, args, NULL);" : "%s(self, args);");
- String *dispatch_code = NewStringf("return %s", dispatch_call);
-
- if (castmode) {
- dispatch = Swig_overload_dispatch_cast(n, dispatch_code, &maxargs);
- } else {
- String *fastdispatch_code;
- if (builtin_ctor)
- fastdispatch_code = NewStringf("int retval = %s\nif (retval == 0 || !SWIG_Python_TypeErrorOccurred(NULL)) return retval;\nSWIG_fail;", dispatch_call);
- else
- fastdispatch_code = NewStringf("PyObject *retobj = %s\nif (!SWIG_Python_TypeErrorOccurred(retobj)) return retobj;\nSWIG_fail;", dispatch_call);
- if (!CPlusPlus) {
- Insert(fastdispatch_code, 0, "{\n");
- Append(fastdispatch_code, "\n}");
- }
- dispatch = Swig_overload_dispatch(n, dispatch_code, &maxargs, fastdispatch_code);
- Delete(fastdispatch_code);
- }
-
- /* Generate a dispatch wrapper for all overloaded functions */
-
- Wrapper *f = NewWrapper();
- String *symname = Getattr(n, "sym:name");
- String *wname = Swig_name_wrapper(symname);
-
- const char *builtin_kwargs = builtin_ctor ? ", PyObject *kwargs" : "";
- Printv(f->def, linkage, builtin_ctor ? "int " : "PyObject *", wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL);
-
- if (builtin) {
- /* Avoid warning if the self parameter is not used. */
- Append(f->code, "(void)self;\n");
- }
-
- Wrapper_add_local(f, "argc", "Py_ssize_t argc");
- Printf(tmp, "PyObject *argv[%d] = {0}", maxargs + 1);
- Wrapper_add_local(f, "argv", tmp);
-
- if (!fastunpack) {
- Wrapper_add_local(f, "ii", "Py_ssize_t ii");
-
- if (builtin_ctor)
- Printf(f->code, "if (!SWIG_Python_CheckNoKeywords(kwargs, \"%s\")) SWIG_fail;\n", symname);
-
- if (maxargs - (add_self ? 1 : 0) > 0) {
- Append(f->code, "if (!PyTuple_Check(args)) SWIG_fail;\n");
- Append(f->code, "argc = PyObject_Length(args);\n");
- } else {
- Append(f->code, "argc = args ? PyObject_Length(args) : 0;\n");
- }
-
- if (add_self)
- Append(f->code, "argv[0] = self;\n");
- Printf(f->code, "for (ii = 0; (ii < %d) && (ii < argc); ii++) {\n", add_self ? maxargs - 1 : maxargs);
- Printf(f->code, "argv[ii%s] = PyTuple_GET_ITEM(args,ii);\n", add_self ? " + 1" : "");
- Append(f->code, "}\n");
- if (add_self)
- Append(f->code, "argc++;\n");
- } else {
- if (builtin_ctor)
- Printf(f->code, "if (!SWIG_Python_CheckNoKeywords(kwargs, \"%s\")) SWIG_fail;\n", symname);
- Printf(f->code, "if (!(argc = SWIG_Python_UnpackTuple(args, \"%s\", 0, %d, argv%s))) SWIG_fail;\n", symname, maxargs, add_self ? "+1" : "");
- if (add_self)
- Append(f->code, "argv[0] = self;\n");
- else
- Append(f->code, "--argc;\n");
- }
-
- Replaceall(dispatch, "$args", "self, args");
-
- Printv(f->code, dispatch, "\n", NIL);
-
- if (GetFlag(n, "feature:python:maybecall")) {
- Append(f->code, "fail:\n");
- Append(f->code, " Py_INCREF(Py_NotImplemented);\n");
- Append(f->code, " return Py_NotImplemented;\n");
- } else {
- Node *sibl = n;
- while (Getattr(sibl, "sym:previousSibling"))
- sibl = Getattr(sibl, "sym:previousSibling"); // go all the way up
- String *protoTypes = NewString("");
- do {
- String *fulldecl = Swig_name_decl(sibl);
- Printf(protoTypes, "\n\" %s\\n\"", fulldecl);
- Delete(fulldecl);
- } while ((sibl = Getattr(sibl, "sym:nextSibling")));
- Append(f->code, "fail:\n");
- Printf(f->code, " SWIG_Python_RaiseOrModifyTypeError("
- "\"Wrong number or type of arguments for overloaded function '%s'.\\n\"" "\n\" Possible C/C++ prototypes are:\\n\"%s);\n", symname, protoTypes);
- Printf(f->code, "return %s;\n", builtin_ctor ? "-1" : "0");
- Delete(protoTypes);
- }
- Printv(f->code, "}\n", NIL);
- Wrapper_print(f, f_wrappers);
- Node *p = Getattr(n, "sym:previousSibling");
- if (!builtin_self && (use_static_method || !builtin))
- add_method(symname, wname, 0, p);
-
- /* Create a shadow for this function (if enabled and not in a member function) */
- if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER) && use_static_method) {
- emitFunctionShadowHelper(n, in_class ? f_shadow_stubs : f_shadow, symname, 0);
- }
- DelWrapper(f);
- Delete(dispatch);
- Delete(dispatch_code);
- Delete(tmp);
- Delete(wname);
- }
-
- /* ------------------------------------------------------------
- * functionWrapper()
- * ------------------------------------------------------------ */
-
- /*
- A note about argument marshalling with built-in types.
- There are three distinct cases for member (non-static) methods:
-
- 1) An ordinary member function. In this case, the first param in
- the param list is 'this'. For builtin types, 'this' is taken from
- the first argument to the wrapper (usually called 'self); it's not
- extracted from the second argument (which is usually a tuple).
-
- 2) A constructor for a non-director class. In this case, the
- param list doesn't contain an entry for 'this', but the first ('self')
- argument to the wrapper *does* contain the newly-allocated,
- uninitialized object.
-
- 3) A constructor for a director class. In this case, the param
- list contains a 'self' param, which comes from the first argument
- to the wrapper function.
- */
-
- const char *get_implicitconv_flag(Node *klass) {
- int conv = 0;
- if (klass && GetFlag(klass, "feature:implicitconv")) {
- conv = 1;
- }
- return conv ? "SWIG_POINTER_IMPLICIT_CONV" : "0";
- }
-
-
- virtual int functionWrapper(Node *n) {
-
- String *name = Getattr(n, "name");
- String *iname = Getattr(n, "sym:name");
- SwigType *d = Getattr(n, "type");
- ParmList *l = Getattr(n, "parms");
- Node *parent = Swig_methodclass(n);
-
- int director_method = 0;
-
- Parm *p;
- int i;
- char source[64];
- Wrapper *f;
- String *self_parse;
- String *parse_args;
- String *arglist;
- String *get_pointers;
- String *cleanup;
- String *outarg;
- String *kwargs;
- String *tm;
- String *overname = 0;
-
- int num_required;
- int num_arguments;
- int num_fixed_arguments;
- int tuple_required;
- int tuple_arguments;
- int varargs = 0;
- int allow_kwargs = check_kwargs(n);
-
- String *nodeType = Getattr(n, "nodeType");
- int constructor = (!Cmp(nodeType, "constructor"));
- int destructor = (!Cmp(nodeType, "destructor"));
- String *storage = Getattr(n, "storage");
- /* Only the first constructor is handled as init method. Others
- constructor can be emitted via %rename */
- int handled_as_init = 0;
- if (!have_constructor && (constructor || Getattr(n, "handled_as_constructor"))
- && ((shadow & PYSHADOW_MEMBER))) {
- String *nname = Getattr(n, "sym:name");
- String *sname = Getattr(getCurrentClass(), "sym:name");
- String *cname = Swig_name_construct(NSPACE_TODO, sname);
- handled_as_init = (Strcmp(nname, sname) == 0) || (Strcmp(nname, cname) == 0);
- Delete(cname);
- }
- bool builtin_self = builtin && in_class && (constructor || (l && Getattr(l, "self")));
- bool builtin_ctor = false;
- if (builtin_self && constructor) {
- String *class_mname = Getattr(getCurrentClass(), "sym:name");
- String *mrename = Swig_name_construct(getNSpace(), class_mname);
- if (Cmp(iname, mrename))
- builtin_self = false;
- else
- builtin_ctor = true;
- Delete(mrename);
- }
- bool director_class = (getCurrentClass() && Swig_directorclass(getCurrentClass()));
- bool add_self = builtin_self && (!builtin_ctor || director_class);
- bool builtin_getter = (builtin && GetFlag(n, "memberget"));
- bool builtin_setter = (builtin && GetFlag(n, "memberset") && !builtin_getter);
- char const *wrap_return = builtin_ctor ? "int " : "PyObject *";
- String *linkage = NewString("SWIGINTERN ");
- String *wrapper_name = Swig_name_wrapper(iname);
-
- if (Getattr(n, "sym:overloaded")) {
- overname = Getattr(n, "sym:overname");
- } else {
- if (!addSymbol(iname, n))
- return SWIG_ERROR;
- }
-
- f = NewWrapper();
- self_parse = NewString("");
- parse_args = NewString("");
- arglist = NewString("");
- get_pointers = NewString("");
- cleanup = NewString("");
- outarg = NewString("");
- kwargs = NewString("");
-
- int allow_thread = threads_enable(n);
-
- Wrapper_add_local(f, "resultobj", "PyObject *resultobj = 0");
-
- // Emit all of the local variables for holding arguments.
- emit_parameter_variables(l, f);
-
- /* Attach the standard typemaps */
- emit_attach_parmmaps(l, f);
- Setattr(n, "wrap:parms", l);
- /* Get number of required and total arguments */
- tuple_arguments = num_arguments = emit_num_arguments(l);
- tuple_required = num_required = emit_num_required(l);
- if (add_self) {
- --tuple_arguments;
- --tuple_required;
- }
- num_fixed_arguments = tuple_required;
-
- // builtin handles/checks kwargs by default except in constructor wrappers so we need to explicitly handle them in the C constructor wrapper
- // The check below is for zero arguments. Sometimes (eg directors) self is the first argument for a method with zero arguments.
- if (((num_arguments == 0) && (num_required == 0)) || ((num_arguments == 1) && (num_required == 1) && Getattr(l, "self")))
- if (!builtin_ctor)
- allow_kwargs = 0;
- varargs = emit_isvarargs(l);
-
- String *wname = Copy(wrapper_name);
- if (overname) {
- Append(wname, overname);
- }
-
- const char *builtin_kwargs = builtin_ctor ? ", PyObject *kwargs" : "";
- if (!allow_kwargs || overname) {
- if (!varargs) {
- Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL);
- } else {
- Printv(f->def, linkage, wrap_return, wname, "__varargs__", "(PyObject *self, PyObject *args, PyObject *varargs", builtin_kwargs, ") {", NIL);
- }
- if (allow_kwargs) {
- Swig_warning(WARN_LANG_OVERLOAD_KEYWORD, input_file, line_number, "Can't use keyword arguments with overloaded functions (%s).\n", Swig_name_decl(n));
- allow_kwargs = 0;
- }
- } else {
- if (varargs) {
- Swig_warning(WARN_LANG_VARARGS_KEYWORD, input_file, line_number, "Can't wrap varargs with keyword arguments enabled\n");
- varargs = 0;
- }
- Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, PyObject *args, PyObject *kwargs) {", NIL);
- /* Avoid warning if the self parameter is not used. */
- Append(f->def, "(void)self;\n");
- }
-
- if (builtin) {
- /* Avoid warning if the self parameter is not used. */
- Append(f->code, "(void)self;\n");
- }
-
- if (!builtin || !in_class || tuple_arguments > 0 || builtin_ctor) {
- if (!allow_kwargs) {
- Append(parse_args, " if (!PyArg_ParseTuple(args, \"");
- } else {
- Append(parse_args, " if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"");
- Append(arglist, ", kwnames");
- }
- }
-
- bool over_varargs = emit_isvarargs_function(n);
-
- int funpack = fastunpack && !varargs && !over_varargs && !allow_kwargs;
- int noargs = funpack && (tuple_required == 0 && tuple_arguments == 0);
- int onearg = funpack && (tuple_required == 1 && tuple_arguments == 1);
-
- if (builtin && funpack && !overname && !builtin_ctor) {
- int compactdefargs = ParmList_is_compactdefargs(l);
- if (!(compactdefargs && (tuple_arguments > tuple_required || varargs))) {
- String *argattr = NewStringf("%d", tuple_arguments);
- Setattr(n, "python:argcount", argattr);
- Delete(argattr);
- }
- }
-
- /* Generate code for argument marshalling */
- if (funpack) {
- if (num_arguments > (builtin_self && !constructor ? 1 : 0) && !overname) {
- sprintf(source, "PyObject *swig_obj[%d]", num_arguments);
- Wrapper_add_localv(f, "swig_obj", source, NIL);
- }
- }
-
-
- if (constructor && num_arguments == 1 && num_required == 1) {
- if (Cmp(storage, "explicit") == 0) {
- if (GetFlag(parent, "feature:implicitconv")) {
- String *desc = NewStringf("SWIGTYPE%s", SwigType_manglestr(Getattr(n, "type")));
- Printf(f->code, "if (SWIG_CheckImplicit(%s)) SWIG_fail;\n", desc);
- Delete(desc);
- }
- }
- }
-
- if (builtin_ctor && checkAttribute(n, "access", "protected")) {
- String *tmp_none_comparison = Copy(none_comparison);
- Replaceall(tmp_none_comparison, "$arg", "self");
- Printf(self_parse, "if (!(%s)) {\n", tmp_none_comparison);
- Printv(self_parse, " SWIG_SetErrorMsg(PyExc_RuntimeError, \"accessing abstract class or protected constructor\");\n SWIG_fail;\n}\n", NIL);
- Delete(tmp_none_comparison);
- }
-
- int use_parse = 0;
- Append(kwargs, "{");
- for (i = 0, p = l; i < num_arguments; i++) {
- while (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- }
-
- SwigType *pt = Getattr(p, "type");
- String *ln = Getattr(p, "lname");
- bool parse_from_tuple = (i > 0 || !add_self);
- if (SwigType_type(pt) == T_VARARGS) {
- parse_from_tuple = false;
- num_fixed_arguments -= atoi(Char(Getattr(p, "tmap:in:numinputs")));
- }
- if (!parse_from_tuple)
- sprintf(source, "self");
- else if (funpack)
- sprintf(source, "swig_obj[%d]", add_self && !overname ? i - 1 : i);
- else
- sprintf(source, "obj%d", builtin_ctor ? i + 1 : i);
-
- if (parse_from_tuple) {
- Printf(arglist, ", ");
- if (i == num_required)
- Putc('|', parse_args); /* Optional argument separator */
- }
-
- /* Keyword argument handling */
- if (allow_kwargs && parse_from_tuple) {
- String *name = makeParameterName(n, p, i + 1);
- Printf(kwargs, " (char *)\"%s\", ", name);
- Delete(name);
- }
-
- /* Look for an input typemap */
- if ((tm = Getattr(p, "tmap:in"))) {
- String *parse = Getattr(p, "tmap:in:parse");
- if (!parse) {
- if (builtin_self) {
- Replaceall(tm, "$self", "self");
- } else if (funpack) {
- Replaceall(tm, "$self", "swig_obj[0]");
- } else {
- Replaceall(tm, "$self", "obj0");
- }
- Replaceall(tm, "$input", source);
- Setattr(p, "emit:input", source); /* Save the location of the object */
-
- if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
- Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
- } else {
- Replaceall(tm, "$disown", "0");
- }
-
- if (Getattr(p, "tmap:in:implicitconv")) {
- const char *convflag = "0";
- if (!Getattr(p, "hidden")) {
- SwigType *ptype = Getattr(p, "type");
- convflag = get_implicitconv_flag(classLookup(ptype));
- }
- Replaceall(tm, "$implicitconv", convflag);
- Setattr(p, "implicitconv", convflag);
- }
-
- if (parse_from_tuple)
- Putc('O', parse_args);
- if (!funpack && parse_from_tuple) {
- Wrapper_add_localv(f, source, "PyObject *", source, "= 0", NIL);
- Printf(arglist, "&%s", source);
- }
- if (i >= num_required)
- Printv(get_pointers, "if (", source, ") {\n", NIL);
- Printv(get_pointers, tm, "\n", NIL);
- if (i >= num_required)
- Printv(get_pointers, "}\n", NIL);
-
- } else {
- use_parse = 1;
- Append(parse_args, parse);
- if (parse_from_tuple)
- Printf(arglist, "&%s", ln);
- }
- p = Getattr(p, "tmap:in:next");
- continue;
- } else {
- Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
- break;
- }
- }
-
- /* finish argument marshalling */
- Append(kwargs, " NULL }");
- if (allow_kwargs) {
- Printv(f->locals, " char * kwnames[] = ", kwargs, ";\n", NIL);
- }
-
- if (use_parse || allow_kwargs) {
- Printf(parse_args, ":%s\"", iname);
- Printv(parse_args, arglist, ")) SWIG_fail;\n", NIL);
- funpack = 0;
- } else {
- Clear(parse_args);
-
- if (funpack) {
- Clear(f->def);
- if (overname) {
- if (noargs) {
- Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) {", NIL);
- } else {
- Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) {", NIL);
- }
- /* Avoid warning if the self parameter is not used. */
- Append(f->def, "(void)self;\n");
- Printf(parse_args, "if ((nobjs < %d) || (nobjs > %d)) SWIG_fail;\n", num_required, num_arguments);
- } else {
- int is_tp_call = Equal(Getattr(n, "feature:python:slot"), "tp_call");
- Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL);
- /* Avoid warning if the self parameter is not used. */
- Append(f->def, "(void)self;\n");
- if (builtin_ctor)
- Printf(parse_args, "if (!SWIG_Python_CheckNoKeywords(kwargs, \"%s\")) SWIG_fail;\n", iname);
- if (onearg && !builtin_ctor && !is_tp_call) {
- Printf(parse_args, "if (!args) SWIG_fail;\n");
- Append(parse_args, "swig_obj[0] = args;\n");
- } else if (!noargs) {
- Printf(parse_args, "if (!SWIG_Python_UnpackTuple(args, \"%s\", %d, %d, swig_obj)) SWIG_fail;\n", iname, num_fixed_arguments, tuple_arguments);
- } else if (noargs) {
- Printf(parse_args, "if (!SWIG_Python_UnpackTuple(args, \"%s\", %d, %d, 0)) SWIG_fail;\n", iname, num_fixed_arguments, tuple_arguments);
- }
- }
- } else {
- if (builtin_ctor)
- Printf(parse_args, "if (!SWIG_Python_CheckNoKeywords(kwargs, \"%s\")) SWIG_fail;\n", iname);
- if (builtin && in_class && tuple_arguments == 0) {
- Printf(parse_args, " if (args && PyTuple_Check(args) && PyTuple_GET_SIZE(args) > 0) SWIG_exception_fail(SWIG_TypeError, \"%s takes no arguments\");\n", iname);
- } else {
- Printf(parse_args, "if (!PyArg_UnpackTuple(args, \"%s\", %d, %d", iname, num_fixed_arguments, tuple_arguments);
- Printv(parse_args, arglist, ")) SWIG_fail;\n", NIL);
- }
- }
- }
-
- /* Now piece together the first part of the wrapper function */
- Printv(f->code, self_parse, parse_args, get_pointers, NIL);
-
- /* Check for trailing varargs */
- if (varargs) {
- if (p && (tm = Getattr(p, "tmap:in"))) {
- Replaceall(tm, "$input", "varargs");
- Printv(f->code, tm, "\n", NIL);
- }
- }
-
- /* Insert constraint checking code */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:check"))) {
- Printv(f->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:check:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* Insert cleanup code */
- for (p = l; p;) {
- if (!Getattr(p, "tmap:in:parse") && (tm = Getattr(p, "tmap:freearg"))) {
- if (Getattr(p, "tmap:freearg:implicitconv")) {
- const char *convflag = "0";
- if (!Getattr(p, "hidden")) {
- SwigType *ptype = Getattr(p, "type");
- convflag = get_implicitconv_flag(classLookup(ptype));
- }
- if (strcmp(convflag, "0") == 0) {
- tm = 0;
- }
- }
- if (tm && (Len(tm) != 0)) {
- Printv(cleanup, tm, "\n", NIL);
- }
- p = Getattr(p, "tmap:freearg:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* Insert argument output code */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:argout"))) {
- Replaceall(tm, "$arg", Getattr(p, "emit:input"));
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(outarg, tm, "\n", NIL);
- p = Getattr(p, "tmap:argout:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* if the object is a director, and the method call originated from its
- * underlying python object, resolve the call by going up the c++
- * inheritance chain. otherwise try to resolve the method in python.
- * without this check an infinite loop is set up between the director and
- * shadow class method calls.
- */
-
- // NOTE: this code should only be inserted if this class is the
- // base class of a director class. however, in general we haven't
- // yet analyzed all classes derived from this one to see if they are
- // directors. furthermore, this class may be used as the base of
- // a director class defined in a completely different module at a
- // later time, so this test must be included whether or not directorbase
- // is true. we do skip this code if directors have not been enabled
- // at the command line to preserve source-level compatibility with
- // non-polymorphic swig. also, if this wrapper is for a smart-pointer
- // method, there is no need to perform the test since the calling object
- // (the smart-pointer) and the director object (the "pointee") are
- // distinct.
-
- director_method = is_member_director(n) && !is_smart_pointer() && !destructor;
- if (director_method) {
- Wrapper_add_local(f, "director", "Swig::Director *director = 0");
- Append(f->code, "director = SWIG_DIRECTOR_CAST(arg1);\n");
- if (dirprot_mode() && !is_public(n)) {
- Printf(f->code, "if (!director || !(director->swig_get_inner(\"%s\"))) {\n", name);
- Printf(f->code, "SWIG_SetErrorMsg(PyExc_RuntimeError,\"accessing protected member %s\");\n", name);
- Append(f->code, "SWIG_fail;\n");
- Append(f->code, "}\n");
- }
- Wrapper_add_local(f, "upcall", "bool upcall = false");
- if (funpack) {
- const char *self_parm = builtin_self ? "self" : "swig_obj[0]";
- Printf(f->code, "upcall = (director && (director->swig_get_self()==%s));\n", self_parm);
- } else {
- const char *self_parm = builtin_self ? "self" : "obj0";
- Printf(f->code, "upcall = (director && (director->swig_get_self()==%s));\n", self_parm);
- }
- }
-
- /* Emit the function call */
- if (director_method) {
- Append(f->code, "try {\n");
- } else {
- if (allow_thread) {
- String *preaction = NewString("");
- thread_begin_allow(n, preaction);
- Setattr(n, "wrap:preaction", preaction);
-
- String *postaction = NewString("");
- thread_end_allow(n, postaction);
- Setattr(n, "wrap:postaction", postaction);
- }
- }
-
- Setattr(n, "wrap:name", wname);
-
- Swig_director_emit_dynamic_cast(n, f);
- String *actioncode = emit_action(n);
-
- if (director_method) {
- Append(actioncode, "} catch (Swig::DirectorException&) {\n");
- Append(actioncode, " SWIG_fail;\n");
- Append(actioncode, "}\n");
- }
-
- /* This part below still needs cleanup */
-
- /* Return the function value */
- tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode);
-
- if (tm) {
- if (builtin_self) {
- Replaceall(tm, "$self", "self");
- } else if (funpack) {
- Replaceall(tm, "$self", "swig_obj[0]");
- } else {
- Replaceall(tm, "$self", "obj0");
- }
- Replaceall(tm, "$result", "resultobj");
- if (builtin_ctor) {
- Replaceall(tm, "$owner", "SWIG_BUILTIN_INIT");
- } else if (handled_as_init) {
- Replaceall(tm, "$owner", "SWIG_POINTER_NEW");
- } else {
- if (GetFlag(n, "feature:new")) {
- Replaceall(tm, "$owner", "SWIG_POINTER_OWN");
- } else {
- Replaceall(tm, "$owner", "0");
- }
- }
-
- // Unwrap return values that are director classes so that the original Python object is returned instead.
- if (!constructor && Swig_director_can_unwrap(n)) {
- Wrapper_add_local(f, "director", "Swig::Director *director = 0");
- Printf(f->code, "director = SWIG_DIRECTOR_CAST(%s);\n", Swig_cresult_name());
- Append(f->code, "if (director) {\n");
- Append(f->code, " resultobj = director->swig_get_self();\n");
- Append(f->code, " Py_INCREF(resultobj);\n");
- Append(f->code, "} else {\n");
- Printf(f->code, "%s\n", tm);
- Append(f->code, "}\n");
- } else {
- Printf(f->code, "%s\n", tm);
- }
-
- Delete(tm);
- } else {
- Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);
- }
- emit_return_variable(n, d, f);
-
- /* Output argument output code */
- Printv(f->code, outarg, NIL);
-
- /* Output cleanup code */
- int need_cleanup = Len(cleanup) != 0;
- if (need_cleanup) {
- Printv(f->code, cleanup, NIL);
- }
-
- /* Look to see if there is any newfree cleanup code */
- if (GetFlag(n, "feature:new")) {
- if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
- Printf(f->code, "%s\n", tm);
- Delete(tm);
- }
- }
-
- /* See if there is any return cleanup code */
- if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
- Printf(f->code, "%s\n", tm);
- Delete(tm);
- }
-
- if (director_method) {
- if ((tm = Swig_typemap_lookup("directorfree", n, Swig_cresult_name(), 0))) {
- Replaceall(tm, "$input", Swig_cresult_name());
- Replaceall(tm, "$result", "resultobj");
- Printf(f->code, "%s\n", tm);
- Delete(tm);
- }
- }
-
- if (builtin_ctor)
- Append(f->code, " return resultobj == Py_None ? -1 : 0;\n");
- else
- Append(f->code, " return resultobj;\n");
-
- /* Error handling code */
-
- Append(f->code, "fail:\n");
- if (need_cleanup) {
- Printv(f->code, cleanup, NIL);
- }
- if (builtin_ctor) {
- Printv(f->code, " return -1;\n", NIL);
- } else {
- if (GetFlag(n, "feature:python:maybecall")) {
- Append(f->code, " PyErr_Clear();\n");
- Append(f->code, " Py_INCREF(Py_NotImplemented);\n");
- Append(f->code, " return Py_NotImplemented;\n");
- } else {
- Printv(f->code, " return NULL;\n", NIL);
- }
- }
-
- Append(f->code, "}\n");
-
- /* Substitute the cleanup code */
- Replaceall(f->code, "$cleanup", cleanup);
-
- /* Substitute the function name */
- Replaceall(f->code, "$symname", iname);
- Replaceall(f->code, "$result", "resultobj");
-
- if (builtin_self) {
- Replaceall(f->code, "$self", "self");
- } else if (funpack) {
- Replaceall(f->code, "$self", "swig_obj[0]");
- } else {
- Replaceall(f->code, "$self", "obj0");
- }
-
- /* Dump the function out */
- Wrapper_print(f, f_wrappers);
-
- /* If varargs. Need to emit a varargs stub */
- if (varargs) {
- DelWrapper(f);
- f = NewWrapper();
- if (funpack) {
- // Note: funpack is currently always false for varargs
- Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) {", NIL);
- } else {
- Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL);
- }
- Wrapper_add_local(f, "resultobj", builtin_ctor ? "int resultobj" : "PyObject *resultobj");
- Wrapper_add_local(f, "varargs", "PyObject *varargs");
- Wrapper_add_local(f, "newargs", "PyObject *newargs");
- if (funpack) {
- Wrapper_add_local(f, "i", "int i");
- Printf(f->code, "newargs = PyTuple_New(%d);\n", num_fixed_arguments);
- Printf(f->code, "for (i = 0; i < %d; ++i) {\n", num_fixed_arguments);
- Printf(f->code, " PyTuple_SET_ITEM(newargs, i, swig_obj[i]);\n");
- Printf(f->code, " Py_XINCREF(swig_obj[i]);\n");
- Printf(f->code, "}\n");
- Printf(f->code, "varargs = PyTuple_New(nobjs > %d ? nobjs - %d : 0);\n", num_fixed_arguments, num_fixed_arguments);
- Printf(f->code, "for (i = 0; i < nobjs - %d; ++i) {\n", num_fixed_arguments);
- Printf(f->code, " PyTuple_SET_ITEM(newargs, i, swig_obj[i + %d]);\n", num_fixed_arguments);
- Printf(f->code, " Py_XINCREF(swig_obj[i + %d]);\n", num_fixed_arguments);
- Printf(f->code, "}\n");
- } else {
- Printf(f->code, "newargs = PyTuple_GetSlice(args, 0, %d);\n", num_fixed_arguments);
- Printf(f->code, "varargs = PyTuple_GetSlice(args, %d, PyTuple_Size(args));\n", num_fixed_arguments);
- }
- Printf(f->code, "resultobj = %s__varargs__(%s, newargs, varargs%s);\n", wname, builtin ? "self" : "NULL", strlen(builtin_kwargs) == 0 ? "" : ", kwargs");
- Append(f->code, "Py_XDECREF(newargs);\n");
- Append(f->code, "Py_XDECREF(varargs);\n");
- Append(f->code, "return resultobj;\n");
- Append(f->code, "}\n");
- Wrapper_print(f, f_wrappers);
- }
-
- bool use_static_method = flat_static_method || !Swig_storage_isstatic_custom(n, "staticmemberfunctionHandler:storage");
- /* Now register the function with the interpreter. */
- if (!Getattr(n, "sym:overloaded")) {
- if (!builtin_self && (use_static_method || !builtin))
- add_method(iname, wname, allow_kwargs, n, funpack, num_required, num_arguments);
-
- /* Create a shadow for this function (if enabled and not in a member function) */
- if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER) && use_static_method) {
- emitFunctionShadowHelper(n, in_class ? f_shadow_stubs : f_shadow, iname, allow_kwargs);
- }
-
- } else {
- if (!Getattr(n, "sym:nextSibling")) {
- dispatchFunction(n, linkage, funpack, builtin_self, builtin_ctor, director_class, use_static_method);
- }
- }
-
- // Put this in tp_init of the PyTypeObject
- if (builtin_ctor) {
- if ((director_method || !is_private(n)) && !Getattr(class_members, iname)) {
- Setattr(class_members, iname, n);
- if (!builtin_tp_init)
- builtin_tp_init = Swig_name_wrapper(iname);
- }
- }
-
- /* If this is a builtin type, create a PyGetSetDef entry for this member variable. */
- if (builtin) {
- const char *memname = "__dict__";
- Hash *h = Getattr(builtin_getset, memname);
- if (!h) {
- h = NewHash();
- Setattr(builtin_getset, memname, h);
- Delete(h);
- }
- Setattr(h, "getter", "SwigPyObject_get___dict__");
- if (!Getattr(h, "doc")) {
- Setattr(n, "doc:high:name", Getattr(n, "name"));
- Setattr(h, "doc", cdocstring(n, AUTODOC_VAR));
- }
- }
-
- if (builtin_getter) {
- String *memname = Getattr(n, "membervariableHandler:sym:name");
- if (!memname)
- memname = iname;
- Hash *h = Getattr(builtin_getset, memname);
- if (!h) {
- h = NewHash();
- Setattr(builtin_getset, memname, h);
- Delete(h);
- }
- Setattr(h, "getter", wrapper_name);
- Delattr(n, "memberget");
- if (!Getattr(h, "doc")) {
- Setattr(n, "doc:high:name", Getattr(n, "name"));
- String *ds = cdocstring(n, AUTODOC_VAR);
- Setattr(h, "doc", ds);
- Delete(ds);
- }
- }
- if (builtin_setter) {
- String *memname = Getattr(n, "membervariableHandler:sym:name");
- if (!memname)
- memname = iname;
- Hash *h = Getattr(builtin_getset, memname);
- if (!h) {
- h = NewHash();
- Setattr(builtin_getset, memname, h);
- Delete(h);
- }
- Setattr(h, "setter", wrapper_name);
- Delattr(n, "memberset");
- if (!Getattr(h, "doc")) {
- Setattr(n, "doc:high:name", Getattr(n, "name"));
- String *ds = cdocstring(n, AUTODOC_VAR);
- Setattr(h, "doc", ds);
- Delete(ds);
- }
- }
-
- if (in_class && builtin) {
- /* Handle operator overloads for builtin types */
- String *slot = Getattr(n, "feature:python:slot");
- if (slot) {
- String *func_type = Getattr(n, "feature:python:slot:functype");
- String *closure_decl = getClosure(func_type, wrapper_name, overname ? 0 : funpack);
- String *feature_name = NewStringf("feature:python:%s", slot);
- String *closure_name = 0;
- if (closure_decl) {
- closure_name = NewStringf("%s_%s_closure", wrapper_name, func_type);
- if (!GetFlag(builtin_closures, closure_name))
- Printf(builtin_closures_code, "%s /* defines %s */\n\n", closure_decl, closure_name);
- SetFlag(builtin_closures, closure_name);
- Delete(closure_decl);
- } else {
- closure_name = Copy(wrapper_name);
- }
- if (func_type) {
- String *s = NewStringf("%s", closure_name);
- Delete(closure_name);
- closure_name = s;
- }
- Setattr(parent, feature_name, closure_name);
- Delete(feature_name);
- Delete(closure_name);
- }
-
- /* Handle comparison operators for builtin types */
- String *compare = Getattr(n, "feature:python:compare");
- if (compare) {
- Hash *richcompare = Getattr(parent, "python:richcompare");
- assert(richcompare);
- Setattr(richcompare, compare, wrapper_name);
- }
- }
-
- Delete(self_parse);
- Delete(parse_args);
- Delete(linkage);
- Delete(arglist);
- Delete(get_pointers);
- Delete(cleanup);
- Delete(outarg);
- Delete(kwargs);
- Delete(wname);
- DelWrapper(f);
- Delete(wrapper_name);
- return SWIG_OK;
- }
-
-
-
- /* ------------------------------------------------------------
- * variableWrapper()
- * ------------------------------------------------------------ */
-
- virtual int variableWrapper(Node *n) {
- String *name = Getattr(n, "name");
- String *iname = Getattr(n, "sym:name");
- SwigType *t = Getattr(n, "type");
-
- static int have_globals = 0;
- String *tm;
- Wrapper *getf, *setf;
-
- if (!addSymbol(iname, n))
- return SWIG_ERROR;
-
- getf = NewWrapper();
- setf = NewWrapper();
-
- /* If this is our first call, add the globals variable to the
- Python dictionary. */
-
- if (!have_globals) {
- Printf(f_init, "\t globals = SWIG_globals();\n");
- Printf(f_init, "\t if (!globals) {\n");
- Printf(f_init, " PyErr_SetString(PyExc_TypeError, \"Failure to create SWIG globals.\");\n");
- Printf(f_init, "#if PY_VERSION_HEX >= 0x03000000\n");
- Printf(f_init, "\t return NULL;\n");
- Printf(f_init, "#else\n");
- Printf(f_init, "\t return;\n");
- Printf(f_init, "#endif\n");
- Printf(f_init, "\t }\n");
- Printf(f_init, "\t PyDict_SetItemString(md, \"%s\", globals);\n", global_name);
- if (builtin)
- Printf(f_init, "\t SwigPyBuiltin_AddPublicSymbol(public_interface, \"%s\");\n", global_name);
- have_globals = 1;
- if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER)) {
- Printf(f_shadow_stubs, "%s = %s.%s\n", global_name, module, global_name);
- }
- }
- int assignable = is_assignable(n);
-
- if (!builtin && shadow && !assignable && !in_class)
- Printf(f_shadow_stubs, "%s = %s.%s\n", iname, global_name, iname);
-
- String *getname = Swig_name_get(NSPACE_TODO, iname);
- String *setname = Swig_name_set(NSPACE_TODO, iname);
- String *vargetname = NewStringf("Swig_var_%s", getname);
- String *varsetname = NewStringf("Swig_var_%s", setname);
-
- /* Create a function for setting the value of the variable */
- if (assignable) {
- Setattr(n, "wrap:name", varsetname);
- if (builtin && in_class) {
- String *set_wrapper = Swig_name_wrapper(setname);
- Setattr(n, "pybuiltin:setter", set_wrapper);
- Delete(set_wrapper);
- }
- Printf(setf->def, "SWIGINTERN int %s(PyObject *_val) {", varsetname);
- if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
- Replaceall(tm, "$input", "_val");
- if (Getattr(n, "tmap:varin:implicitconv")) {
- Replaceall(tm, "$implicitconv", get_implicitconv_flag(n));
- }
- emit_action_code(n, setf->code, tm);
- Delete(tm);
- } else {
- Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
- }
- Printv(setf->code, " return 0;\n", NULL);
- Append(setf->code, "fail:\n");
- Printv(setf->code, " return 1;\n", NULL);
- } else {
- /* Is a readonly variable. Issue an error */
- if (CPlusPlus) {
- Printf(setf->def, "SWIGINTERN int %s(PyObject *) {", varsetname);
- } else {
- Printf(setf->def, "SWIGINTERN int %s(PyObject *_val SWIGUNUSED) {", varsetname);
- }
- Printv(setf->code, " SWIG_Error(SWIG_AttributeError,\"Variable ", iname, " is read-only.\");\n", " return 1;\n", NIL);
- }
-
- Append(setf->code, "}\n");
- Wrapper_print(setf, f_wrappers);
-
- /* Create a function for getting the value of a variable */
- Setattr(n, "wrap:name", vargetname);
- if (builtin && in_class) {
- String *get_wrapper = Swig_name_wrapper(getname);
- Setattr(n, "pybuiltin:getter", get_wrapper);
- Delete(get_wrapper);
- }
- int addfail = 0;
- Printf(getf->def, "SWIGINTERN PyObject *%s(void) {", vargetname);
- Wrapper_add_local(getf, "pyobj", "PyObject *pyobj = 0");
- if (builtin) {
- Wrapper_add_local(getf, "self", "PyObject *self = 0");
- Append(getf->code, " (void)self;\n");
- }
- if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
- Replaceall(tm, "$result", "pyobj");
- addfail = emit_action_code(n, getf->code, tm);
- Delete(tm);
- } else {
- Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
- }
- Append(getf->code, " return pyobj;\n");
- if (addfail) {
- Append(getf->code, "fail:\n");
- Append(getf->code, " return NULL;\n");
- }
- Append(getf->code, "}\n");
-
- Wrapper_print(getf, f_wrappers);
-
- /* Now add this to the variable linking mechanism */
- Printf(f_init, "\t SWIG_addvarlink(globals, \"%s\", %s, %s);\n", iname, vargetname, varsetname);
- if (builtin && shadow && !assignable && !in_class) {
- Printf(f_init, "\t PyDict_SetItemString(md, \"%s\", PyObject_GetAttrString(globals, \"%s\"));\n", iname, iname);
- Printf(f_init, "\t SwigPyBuiltin_AddPublicSymbol(public_interface, \"%s\");\n", iname);
- }
- Delete(vargetname);
- Delete(varsetname);
- Delete(getname);
- Delete(setname);
- DelWrapper(setf);
- DelWrapper(getf);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * constantWrapper()
- * ------------------------------------------------------------ */
-
- /* Determine if the node requires the _swigconstant code to be generated */
- bool needs_swigconstant(Node *n) {
- SwigType *type = Getattr(n, "type");
- SwigType *qtype = SwigType_typedef_resolve_all(type);
- SwigType *uqtype = SwigType_strip_qualifiers(qtype);
- bool result = false;
-
- /* Note, that we need special handling for function pointers, as
- * SwigType_base(fptr) does not return the underlying pointer-to-function
- * type but the return-type of function. */
- if (!SwigType_isfunction(uqtype) && !SwigType_isfunctionpointer(uqtype)) {
- SwigType *basetype = SwigType_base(uqtype);
- result = SwigType_isclass(basetype) != 0;
- Delete(basetype);
- }
-
- Delete(qtype);
- Delete(uqtype);
-
- return result;
- }
-
- virtual int constantWrapper(Node *n) {
- String *name = Getattr(n, "name");
- String *iname = Getattr(n, "sym:name");
- SwigType *type = Getattr(n, "type");
- String *rawval = Getattr(n, "rawval");
- String *value = rawval ? rawval : Getattr(n, "value");
- String *tm;
- int have_tm = 0;
- int have_builtin_symname = 0;
-
- if (!addSymbol(iname, n))
- return SWIG_ERROR;
-
- /* Special hook for member pointer */
- if (SwigType_type(type) == T_MPOINTER) {
- String *wname = Swig_name_wrapper(iname);
- String *str = SwigType_str(type, wname);
- Printf(f_header, "static %s = %s;\n", str, value);
- Delete(str);
- value = wname;
- }
-
- if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) {
- Replaceall(tm, "$value", value);
- Printf(const_code, "%s,\n", tm);
- Delete(tm);
- have_tm = 1;
- }
-
-
- if (builtin && in_class && Getattr(n, "pybuiltin:symname")) {
- have_builtin_symname = 1;
- Swig_require("builtin_constantWrapper", n, "*sym:name", "pybuiltin:symname", NIL);
- Setattr(n, "sym:name", Getattr(n, "pybuiltin:symname"));
- }
-
- if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
- Replaceall(tm, "$value", value);
- if (needs_swigconstant(n) && !builtin && shadow && !(shadow & PYSHADOW_MEMBER) && (!in_class || !Getattr(n, "feature:python:callback"))) {
- // Generate `*_swigconstant()` method which registers the new constant.
- //
- // *_swigconstant methods are required for constants of class type.
- // Class types are registered in shadow file (see *_swigregister). The
- // instances of class must be created (registered) after the type is
- // registered, so we can't let SWIG_init() to register constants of
- // class type (the SWIG_init() is called before shadow classes are
- // defined and registered).
- Printf(f_wrappers, "SWIGINTERN PyObject *%s_swigconstant(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {\n", iname);
- Printf(f_wrappers, tab2 "PyObject *module;\n");
- Printf(f_wrappers, tab2 "PyObject *d;\n");
- Printf(f_wrappers, tab2 "if (!SWIG_Python_UnpackTuple(args, \"swigconstant\", 1, 1, &module)) return NULL;\n");
- Printf(f_wrappers, tab2 "d = PyModule_GetDict(module);\n");
- Printf(f_wrappers, tab2 "if (!d) return NULL;\n");
- Printf(f_wrappers, tab2 "%s\n", tm);
- Printf(f_wrappers, tab2 "return SWIG_Py_Void();\n");
- Printf(f_wrappers, "}\n\n\n");
-
- // Register the method in SwigMethods array
- String *cname = NewStringf("%s_swigconstant", iname);
- add_method(cname, cname, 0, 0, 1, 1, 1);
- Delete(cname);
- } else {
- Printf(f_init, "%s\n", tm);
- }
- Delete(tm);
- have_tm = 1;
- }
-
- if (have_builtin_symname)
- Swig_restore(n);
-
- if (!have_tm) {
- Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n");
- return SWIG_NOWRAP;
- }
-
- if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER)) {
- String *f_s;
- if (!in_class) {
- f_s = f_shadow;
- } else {
- f_s = Getattr(n, "feature:python:callback") ? NIL : f_shadow_stubs;
- }
-
- if (f_s) {
- if (needs_swigconstant(n)) {
- Printv(f_s, "\n",NIL);
- Printv(f_s, module, ".", iname, "_swigconstant(",module,")\n", NIL);
- }
- Printv(f_s, iname, " = ", module, ".", iname, "\n", NIL);
- if (have_docstring(n))
- Printv(f_s, docstring(n, AUTODOC_CONST, tab4), "\n", NIL);
- }
- }
- return SWIG_OK;
- }
-
-
- /* ------------------------------------------------------------
- * nativeWrapper()
- * ------------------------------------------------------------ */
-
- virtual int nativeWrapper(Node *n) {
- String *name = Getattr(n, "sym:name");
- String *wrapname = Getattr(n, "wrap:name");
-
- if (!addSymbol(wrapname, n))
- return SWIG_ERROR;
-
- add_method(name, wrapname, 0);
- if (!builtin && shadow) {
- Printv(f_shadow_stubs, name, " = ", module, ".", name, "\n", NIL);
- }
- return SWIG_OK;
- }
-
-
-
- /* ----------------------------------------------------------------------------
- * BEGIN C++ Director Class modifications
- * ------------------------------------------------------------------------- */
-
- /* C++/Python polymorphism demo code
- *
- * TODO
- *
- * Move some boilerplate code generation to Swig_...() functions.
- *
- */
-
- /* ---------------------------------------------------------------
- * classDirectorMethod()
- *
- * Emit a virtual director method to pass a method call on to the
- * underlying Python object.
- * ** Moved down due to gcc-2.96 internal error **
- * --------------------------------------------------------------- */
-
- int classDirectorMethods(Node *n);
-
- int classDirectorMethod(Node *n, Node *parent, String *super);
-
- /* ------------------------------------------------------------
- * classDirectorConstructor()
- * ------------------------------------------------------------ */
-
- int classDirectorConstructor(Node *n) {
- Node *parent = Getattr(n, "parentNode");
- String *sub = NewString("");
- String *decl = Getattr(n, "decl");
- String *supername = Swig_class_name(parent);
- String *classname = NewString("");
- Printf(classname, "SwigDirector_%s", supername);
-
- /* insert self parameter */
- Parm *p;
- ParmList *superparms = Getattr(n, "parms");
- ParmList *parms = CopyParmList(superparms);
- String *type = NewString("PyObject");
- SwigType_add_pointer(type);
- p = NewParm(type, NewString("self"), n);
- set_nextSibling(p, parms);
- parms = p;
-
- if (!Getattr(n, "defaultargs")) {
- /* constructor */
- {
- Wrapper *w = NewWrapper();
- String *call;
- String *basetype = Getattr(parent, "classtype");
- String *target = Swig_method_decl(0, decl, classname, parms, 0);
- call = Swig_csuperclass_call(0, basetype, superparms);
- Printf(w->def, "%s::%s: %s, Swig::Director(self) { \n", classname, target, call);
- Printf(w->def, " SWIG_DIRECTOR_RGTR((%s *)this, this); \n", basetype);
- Append(w->def, "}\n");
- Delete(target);
- Wrapper_print(w, f_directors);
- Delete(call);
- DelWrapper(w);
- }
-
- /* constructor header */
- {
- String *target = Swig_method_decl(0, decl, classname, parms, 1);
- Printf(f_directors_h, " %s;\n", target);
- Delete(target);
- }
- }
-
- Delete(sub);
- Delete(classname);
- Delete(supername);
- Delete(parms);
- return Language::classDirectorConstructor(n);
- }
-
- /* ------------------------------------------------------------
- * classDirectorDefaultConstructor()
- * ------------------------------------------------------------ */
-
- int classDirectorDefaultConstructor(Node *n) {
- String *classname = Swig_class_name(n);
- {
- Node *parent = Swig_methodclass(n);
- String *basetype = Getattr(parent, "classtype");
- Wrapper *w = NewWrapper();
- Printf(w->def, "SwigDirector_%s::SwigDirector_%s(PyObject *self) : Swig::Director(self) { \n", classname, classname);
- Printf(w->def, " SWIG_DIRECTOR_RGTR((%s *)this, this); \n", basetype);
- Append(w->def, "}\n");
- Wrapper_print(w, f_directors);
- DelWrapper(w);
- }
- Printf(f_directors_h, " SwigDirector_%s(PyObject *self);\n", classname);
- Delete(classname);
- return Language::classDirectorDefaultConstructor(n);
- }
-
-
- /* ------------------------------------------------------------
- * classDirectorInit()
- * ------------------------------------------------------------ */
-
- int classDirectorInit(Node *n) {
- String *declaration = Swig_director_declaration(n);
- Printf(f_directors_h, "\n");
- Printf(f_directors_h, "%s\n", declaration);
- Printf(f_directors_h, "public:\n");
- Delete(declaration);
- return Language::classDirectorInit(n);
- }
-
- /* ------------------------------------------------------------
- * classDirectorEnd()
- * ------------------------------------------------------------ */
-
- int classDirectorEnd(Node *n) {
- String *classname = Swig_class_name(n);
-
- if (dirprot_mode()) {
- /*
- This implementation uses a std::map<std::string,int>.
-
- It should be possible to rewrite it using a more elegant way,
- like copying the Java approach for the 'override' array.
-
- But for now, this seems to be the least intrusive way.
- */
- Printf(f_directors_h, "\n");
- Printf(f_directors_h, "/* Internal director utilities */\n");
- Printf(f_directors_h, "public:\n");
- Printf(f_directors_h, " bool swig_get_inner(const char *swig_protected_method_name) const {\n");
- Printf(f_directors_h, " std::map<std::string, bool>::const_iterator iv = swig_inner.find(swig_protected_method_name);\n");
- Printf(f_directors_h, " return (iv != swig_inner.end() ? iv->second : false);\n");
- Printf(f_directors_h, " }\n");
-
- Printf(f_directors_h, " void swig_set_inner(const char *swig_protected_method_name, bool swig_val) const {\n");
- Printf(f_directors_h, " swig_inner[swig_protected_method_name] = swig_val;\n");
- Printf(f_directors_h, " }\n");
- Printf(f_directors_h, "private:\n");
- Printf(f_directors_h, " mutable std::map<std::string, bool> swig_inner;\n");
-
- }
- if (director_method_index) {
- Printf(f_directors_h, "\n");
- Printf(f_directors_h, "#if defined(SWIG_PYTHON_DIRECTOR_VTABLE)\n");
- Printf(f_directors_h, "/* VTable implementation */\n");
- Printf(f_directors_h, " PyObject *swig_get_method(size_t method_index, const char *method_name) const {\n");
- Printf(f_directors_h, " PyObject *method = vtable[method_index];\n");
- Printf(f_directors_h, " if (!method) {\n");
- Printf(f_directors_h, " swig::SwigVar_PyObject name = SWIG_Python_str_FromChar(method_name);\n");
- Printf(f_directors_h, " method = PyObject_GetAttr(swig_get_self(), name);\n");
- Printf(f_directors_h, " if (!method) {\n");
- Printf(f_directors_h, " std::string msg = \"Method in class %s doesn't exist, undefined \";\n", classname);
- Printf(f_directors_h, " msg += method_name;\n");
- Printf(f_directors_h, " Swig::DirectorMethodException::raise(msg.c_str());\n");
- Printf(f_directors_h, " }\n");
- Printf(f_directors_h, " vtable[method_index] = method;\n");
- Printf(f_directors_h, " }\n");
- Printf(f_directors_h, " return method;\n");
- Printf(f_directors_h, " }\n");
- Printf(f_directors_h, "private:\n");
- Printf(f_directors_h, " mutable swig::SwigVar_PyObject vtable[%d];\n", director_method_index);
- Printf(f_directors_h, "#endif\n\n");
- }
-
- Printf(f_directors_h, "};\n\n");
- return Language::classDirectorEnd(n);
- }
-
-
- /* ------------------------------------------------------------
- * classDirectorDisown()
- * ------------------------------------------------------------ */
-
- int classDirectorDisown(Node *n) {
- int result;
- int oldshadow = shadow;
- /* disable shadowing */
- if (shadow)
- shadow = shadow | PYSHADOW_MEMBER;
- result = Language::classDirectorDisown(n);
- shadow = oldshadow;
- if (shadow) {
- if (builtin) {
- String *rname = SwigType_namestr(real_classname);
- Printf(builtin_methods, " { \"__disown__\", Swig::Director::swig_pyobj_disown< %s >, METH_NOARGS, \"\" },\n", rname);
- Delete(rname);
- } else {
- String *symname = Getattr(n, "sym:name");
- String *mrename = Swig_name_disown(NSPACE_TODO, symname); //Getattr(n, "name"));
- Printv(f_shadow, tab4, "def __disown__(self):\n", NIL);
- Printv(f_shadow, tab8, "self.this.disown()\n", NIL);
- Printv(f_shadow, tab8, module, ".", mrename, "(self)\n", NIL);
- Printv(f_shadow, tab8, "return weakref.proxy(self)\n", NIL);
- Delete(mrename);
- }
- }
- return result;
- }
-
- /* ----------------------------------------------------------------------------
- * END of C++ Director Class modifications
- * ------------------------------------------------------------------------- */
-
-
- /* ------------------------------------------------------------
- * classDeclaration()
- * ------------------------------------------------------------ */
-
- virtual int classDeclaration(Node *n) {
- if (shadow && !Getattr(n, "feature:onlychildren")) {
- Node *mod = Getattr(n, "module");
- if (mod) {
- String *modname = Getattr(mod, "name");
- Node *options = Getattr(mod, "options");
- String *pkg = options ? Getattr(options, "package") : 0;
- String *sym = Getattr(n, "sym:name");
- String *importname = import_name_string(package, mainmodule, pkg, modname, sym);
- Setattr(n, "python:proxy", importname);
- Delete(importname);
- }
- }
- int result = Language::classDeclaration(n);
- return result;
- }
-
- /* ------------------------------------------------------------
- * classHandler()
- * ------------------------------------------------------------ */
-
- String *add_explicit_scope(String *s) {
- if (!Strstr(s, "::")) {
- String *ss = NewStringf("::%s", s);
- Delete(s);
- s = ss;
- }
- return s;
- }
-
- void builtin_pre_decl(Node *n) {
- String *name = Getattr(n, "name");
- String *rname = add_explicit_scope(SwigType_namestr(name));
- String *mname = SwigType_manglestr(rname);
-
- Printf(f_init, "\n/* type '%s' */\n", rname);
- Printf(f_init, " builtin_pytype = (PyTypeObject *)&SwigPyBuiltin_%s_type;\n", mname);
- Printf(f_init, " builtin_pytype->tp_dict = d = PyDict_New();\n");
-
- Delete(rname);
- Delete(mname);
- }
-
- void builtin_post_decl(File *f, Node *n) {
- String *name = Getattr(n, "name");
- String *pname = Copy(name);
- SwigType_add_pointer(pname);
- String *symname = Getattr(n, "sym:name");
- String *rname = add_explicit_scope(SwigType_namestr(name));
- String *mname = SwigType_manglestr(rname);
- String *pmname = SwigType_manglestr(pname);
- String *templ = NewStringf("SwigPyBuiltin_%s", mname);
- int funpack = fastunpack;
- static String *tp_new = NewString("PyType_GenericNew");
-
- if (have_builtin_static_member_method_callback) {
- Printf(f_init, " SWIG_Python_FixMethods(SwigPyBuiltin_%s_methods, swig_const_table, swig_types, swig_type_initial);\n", mname);
- }
-
- Printv(f_init, " SwigPyBuiltin_SetMetaType(builtin_pytype, metatype);\n", NIL);
-
- // We can’t statically initialize a structure member with a function defined in another C module
- // So this is done in the initialization function instead, see https://docs.python.org/2/extending/newtypes.html
- Printf(f_init, " builtin_pytype->tp_new = %s;\n", getSlot(n, "feature:python:tp_new", tp_new));
-
- Printv(f_init, " builtin_base_count = 0;\n", NIL);
- List *baselist = Getattr(n, "bases");
- if (baselist) {
- int base_count = 0;
- for (Iterator b = First(baselist); b.item; b = Next(b)) {
- String *bname = Getattr(b.item, "name");
- if (!bname || GetFlag(b.item, "feature:ignore"))
- continue;
- base_count++;
- String *base_name = Copy(bname);
- SwigType_add_pointer(base_name);
- String *base_mname = SwigType_manglestr(base_name);
- Printf(f_init, " builtin_basetype = SWIG_MangledTypeQuery(\"%s\");\n", base_mname);
- Printv(f_init, " if (builtin_basetype && builtin_basetype->clientdata && ((SwigPyClientData *) builtin_basetype->clientdata)->pytype) {\n", NIL);
- Printv(f_init, " builtin_bases[builtin_base_count++] = ((SwigPyClientData *) builtin_basetype->clientdata)->pytype;\n", NIL);
- Printv(f_init, " } else {\n", NIL);
- Printf(f_init, " PyErr_SetString(PyExc_TypeError, \"Could not create type '%s' as base '%s' has not been initialized.\\n\");\n", symname, bname);
- Printv(f_init, "#if PY_VERSION_HEX >= 0x03000000\n", NIL);
- Printv(f_init, " return NULL;\n", NIL);
- Printv(f_init, "#else\n", NIL);
- Printv(f_init, " return;\n", NIL);
- Printv(f_init, "#endif\n", NIL);
- Printv(f_init, " }\n", NIL);
- Delete(base_name);
- Delete(base_mname);
- }
- if (base_count > max_bases)
- max_bases = base_count;
- }
- Printv(f_init, " builtin_bases[builtin_base_count] = NULL;\n", NIL);
- Printv(f_init, " SwigPyBuiltin_InitBases(builtin_pytype, builtin_bases);\n", NIL);
- builtin_bases_needed = 1;
-
- // Check for non-public destructor, in which case tp_dealloc will issue
- // a warning and allow the memory to leak. Any class that doesn't explicitly
- // have a private/protected destructor has an implicit public destructor.
- static String *tp_dealloc_bad = NewString("SwigPyBuiltin_BadDealloc");
-
- String *getset_name = NewStringf("%s_getset", templ);
- String *methods_name = NewStringf("%s_methods", templ);
- String *getset_def = NewString("");
- Printf(getset_def, "SWIGINTERN PyGetSetDef %s[] = {\n", getset_name);
-
- // All objects have 'this' and 'thisown' attributes
- Printv(f_init, "PyDict_SetItemString(d, \"this\", this_descr);\n", NIL);
- Printv(f_init, "PyDict_SetItemString(d, \"thisown\", thisown_descr);\n", NIL);
-
- // Now, the rest of the attributes
- for (Iterator member_iter = First(builtin_getset); member_iter.item; member_iter = Next(member_iter)) {
- String *memname = member_iter.key;
- Hash *mgetset = member_iter.item;
- String *getter = Getattr(mgetset, "getter");
- String *setter = Getattr(mgetset, "setter");
- const char *getter_closure = getter ? funpack ? "SwigPyBuiltin_FunpackGetterClosure" : "SwigPyBuiltin_GetterClosure" : "0";
- const char *setter_closure = setter ? funpack ? "SwigPyBuiltin_FunpackSetterClosure" : "SwigPyBuiltin_SetterClosure" : "0";
- String *gspair = NewStringf("%s_%s_getset", symname, memname);
- Printf(f, "static SwigPyGetSet %s = { %s, %s };\n", gspair, getter ? getter : "0", setter ? setter : "0");
- String *doc = Getattr(mgetset, "doc");
- if (!doc)
- doc = NewStringf("%s.%s", name, memname);
- String *entry = NewStringf("{ (char *)\"%s\", %s, %s, (char *)\"%s\", &%s }", memname, getter_closure, setter_closure, doc, gspair);
- if (GetFlag(mgetset, "static")) {
- Printf(f, "static PyGetSetDef %s_def = %s;\n", gspair, entry);
- Printf(f_init, "static_getset = SwigPyStaticVar_new_getset(metatype, &%s_def);\n", gspair);
- Printf(f_init, "PyDict_SetItemString(d, static_getset->d_getset->name, (PyObject *) static_getset);\n");
- Printf(f_init, "Py_DECREF(static_getset);\n");
- } else {
- Printf(getset_def, " %s,\n", entry);
- }
- Delete(gspair);
- Delete(entry);
- }
- Printv(f, getset_def, " { NULL, NULL, NULL, NULL, NULL } /* Sentinel */\n", "};\n\n", NIL);
-
- // Rich compare function
- Hash *richcompare = Getattr(n, "python:richcompare");
- String *richcompare_func = NewStringf("%s_richcompare", templ);
- assert(richcompare);
- Printf(f, "SWIGINTERN PyObject *\n");
- Printf(f, "%s(PyObject *self, PyObject *other, int op) {\n", richcompare_func);
- Printf(f, " PyObject *result = NULL;\n");
- if (!funpack) {
- Printf(f, " PyObject *tuple = PyTuple_New(1);\n");
- Printf(f, " assert(tuple);\n");
- Printf(f, " PyTuple_SET_ITEM(tuple, 0, other);\n");
- Printf(f, " Py_XINCREF(other);\n");
- }
- List *richcompare_list = SortedKeys(richcompare, 0);
- Iterator rich_iter = First(richcompare_list);
- if (rich_iter.item) {
- Printf(f, " switch (op) {\n");
- for (; rich_iter.item; rich_iter = Next(rich_iter))
- Printf(f, " case %s : result = %s(self, %s); break;\n", rich_iter.item, Getattr(richcompare, rich_iter.item), funpack ? "other" : "tuple");
- Printv(f, " default : break;\n", NIL);
- Printf(f, " }\n");
- }
- Delete(richcompare_list);
- Printv(f, " if (!result) {\n", NIL);
- Printv(f, " if (SwigPyObject_Check(self) && SwigPyObject_Check(other)) {\n", NIL);
- Printv(f, " result = SwigPyObject_richcompare((SwigPyObject *)self, (SwigPyObject *)other, op);\n", NIL);
- Printv(f, " } else {\n", NIL);
- Printv(f, " result = Py_NotImplemented;\n", NIL);
- Printv(f, " Py_INCREF(result);\n", NIL);
- Printv(f, " }\n", NIL);
- Printv(f, " }\n", NIL);
- if (!funpack)
- Printf(f, " Py_DECREF(tuple);\n");
- Printf(f, " return result;\n");
- Printf(f, "}\n\n");
-
- // Methods
- Printf(f, "SWIGINTERN PyMethodDef %s_methods[] = {\n", templ);
- Dump(builtin_methods, f);
- Printf(f, " { NULL, NULL, 0, NULL } /* Sentinel */\n};\n\n");
-
- // No instance dict for nondynamic objects
- if (GetFlag(n, "feature:python:nondynamic"))
- Setattr(n, "feature:python:tp_setattro", "SWIG_Python_NonDynamicSetAttr");
-
- Node *mod = Getattr(n, "module");
- String *modname = mod ? Getattr(mod, "name") : 0;
- String *quoted_symname;
- if (package) {
- if (modname)
- quoted_symname = NewStringf("\"%s.%s.%s\"", package, modname, symname);
- else
- quoted_symname = NewStringf("\"%s.%s\"", package, symname);
- } else {
- if (modname)
- quoted_symname = NewStringf("\"%s.%s\"", modname, symname);
- else
- quoted_symname = NewStringf("\"%s\"", symname);
- }
- String *quoted_tp_doc_str = NewStringf("\"%s\"", getSlot(n, "feature:python:tp_doc"));
- String *tp_init = NewString(builtin_tp_init ? Char(builtin_tp_init) : Swig_directorclass(n) ? "0" : "SwigPyBuiltin_BadInit");
- String *tp_flags = NewString("Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_CHECKTYPES");
- String *tp_flags_py3 = NewString("Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE");
-
- static String *tp_basicsize = NewStringf("sizeof(SwigPyObject)");
- static String *tp_dictoffset_default = NewString("offsetof(SwigPyObject, dict)");
- static String *tp_hash = NewString("SwigPyObject_hash");
- String *tp_as_number = NewStringf("&%s_type.as_number", templ);
- String *tp_as_sequence = NewStringf("&%s_type.as_sequence", templ);
- String *tp_as_mapping = NewStringf("&%s_type.as_mapping", templ);
- String *tp_as_buffer = NewStringf("&%s_type.as_buffer", templ);
-
- Printf(f, "static PyHeapTypeObject %s_type = {\n", templ);
-
- // PyTypeObject ht_type
- Printf(f, " {\n");
- Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL);
- Printv(f, " PyVarObject_HEAD_INIT(NULL, 0)\n", NIL);
- Printv(f, "#else\n", NIL);
- Printf(f, " PyObject_HEAD_INIT(NULL)\n");
- printSlot(f, getSlot(), "ob_size");
- Printv(f, "#endif\n", NIL);
- printSlot(f, quoted_symname, "tp_name");
- printSlot(f, getSlot(n, "feature:python:tp_basicsize", tp_basicsize), "tp_basicsize");
- printSlot(f, getSlot(n, "feature:python:tp_itemsize"), "tp_itemsize");
- printSlot(f, getSlot(n, "feature:python:tp_dealloc", tp_dealloc_bad), "tp_dealloc", "destructor");
- Printv(f, "#if PY_VERSION_HEX < 0x030800b4\n", NIL);
- printSlot(f, getSlot(n, "feature:python:tp_print"), "tp_print", "printfunc");
- Printv(f, "#else\n", NIL);
- printSlot(f, getSlot(n, "feature:python:tp_vectorcall_offset"), "tp_vectorcall_offset", "Py_ssize_t");
- Printv(f, "#endif\n", NIL);
- printSlot(f, getSlot(n, "feature:python:tp_getattr"), "tp_getattr", "getattrfunc");
- printSlot(f, getSlot(n, "feature:python:tp_setattr"), "tp_setattr", "setattrfunc");
- Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL);
- printSlot(f, getSlot(n, "feature:python:tp_compare"), "tp_compare");
- Printv(f, "#else\n", NIL);
- printSlot(f, getSlot(n, "feature:python:tp_compare"), "tp_compare", "cmpfunc");
- Printv(f, "#endif\n", NIL);
- printSlot(f, getSlot(n, "feature:python:tp_repr"), "tp_repr", "reprfunc");
- printSlot(f, getSlot(n, "feature:python:tp_as_number", tp_as_number), "tp_as_number");
- printSlot(f, getSlot(n, "feature:python:tp_as_sequence", tp_as_sequence), "tp_as_sequence");
- printSlot(f, getSlot(n, "feature:python:tp_as_mapping", tp_as_mapping), "tp_as_mapping");
- printSlot(f, getSlot(n, "feature:python:tp_hash", tp_hash), "tp_hash", "hashfunc");
- printSlot(f, getSlot(n, "feature:python:tp_call"), "tp_call", "ternaryfunc");
- printSlot(f, getSlot(n, "feature:python:tp_str"), "tp_str", "reprfunc");
- printSlot(f, getSlot(n, "feature:python:tp_getattro"), "tp_getattro", "getattrofunc");
- printSlot(f, getSlot(n, "feature:python:tp_setattro"), "tp_setattro", "setattrofunc");
- printSlot(f, getSlot(n, "feature:python:tp_as_buffer", tp_as_buffer), "tp_as_buffer");
- Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL);
- printSlot(f, getSlot(n, "feature:python:tp_flags", tp_flags_py3), "tp_flags");
- Printv(f, "#else\n", NIL);
- printSlot(f, getSlot(n, "feature:python:tp_flags", tp_flags), "tp_flags");
- Printv(f, "#endif\n", NIL);
- if (have_docstring(n)) {
- String *ds = cdocstring(n, AUTODOC_CLASS);
- String *tp_doc = NewString("");
- Printf(tp_doc, "\"%s\"", ds);
- Delete(ds);
- printSlot(f, tp_doc, "tp_doc");
- Delete(tp_doc);
- } else {
- printSlot(f, quoted_tp_doc_str, "tp_doc");
- }
- printSlot(f, getSlot(n, "feature:python:tp_traverse"), "tp_traverse", "traverseproc");
- printSlot(f, getSlot(n, "feature:python:tp_clear"), "tp_clear", "inquiry");
- printSlot(f, getSlot(n, "feature:python:tp_richcompare", richcompare_func), "tp_richcompare", "richcmpfunc");
- printSlot(f, getSlot(n, "feature:python:tp_weaklistoffset"), "tp_weaklistoffset");
- printSlot(f, getSlot(n, "feature:python:tp_iter"), "tp_iter", "getiterfunc");
- printSlot(f, getSlot(n, "feature:python:tp_iternext"), "tp_iternext", "iternextfunc");
- printSlot(f, getSlot(n, "feature:python:tp_methods", methods_name), "tp_methods");
- printSlot(f, getSlot(n, "feature:python:tp_members"), "tp_members");
- printSlot(f, getSlot(n, "feature:python:tp_getset", getset_name), "tp_getset");
- printSlot(f, getSlot(n, "feature:python:tp_base"), "tp_base");
- printSlot(f, getSlot(n, "feature:python:tp_dict"), "tp_dict");
- printSlot(f, getSlot(n, "feature:python:tp_descr_get"), "tp_descr_get", "descrgetfunc");
- printSlot(f, getSlot(n, "feature:python:tp_descr_set"), "tp_descr_set", "descrsetfunc");
- printSlot(f, getSlot(n, "feature:python:tp_dictoffset", tp_dictoffset_default), "tp_dictoffset", "Py_ssize_t");
- printSlot(f, getSlot(n, "feature:python:tp_init", tp_init), "tp_init", "initproc");
- printSlot(f, getSlot(n, "feature:python:tp_alloc"), "tp_alloc", "allocfunc");
- printSlot(f, getSlot(), "tp_new", "newfunc");
- printSlot(f, getSlot(n, "feature:python:tp_free"), "tp_free", "freefunc");
- printSlot(f, getSlot(n, "feature:python:tp_is_gc"), "tp_is_gc", "inquiry");
- printSlot(f, getSlot(n, "feature:python:tp_bases"), "tp_bases", "PyObject *");
- printSlot(f, getSlot(n, "feature:python:tp_mro"), "tp_mro", "PyObject *");
- printSlot(f, getSlot(n, "feature:python:tp_cache"), "tp_cache", "PyObject *");
- printSlot(f, getSlot(n, "feature:python:tp_subclasses"), "tp_subclasses", "PyObject *");
- printSlot(f, getSlot(n, "feature:python:tp_weaklist"), "tp_weaklist", "PyObject *");
- printSlot(f, getSlot(n, "feature:python:tp_del"), "tp_del", "destructor");
- printSlot(f, getSlot(n, "feature:python:tp_version_tag"), "tp_version_tag", "int");
- Printv(f, "#if PY_VERSION_HEX >= 0x03040000\n", NIL);
- printSlot(f, getSlot(n, "feature:python:tp_finalize"), "tp_finalize", "destructor");
- Printv(f, "#endif\n", NIL);
- Printv(f, "#if PY_VERSION_HEX >= 0x03080000\n", NIL);
- printSlot(f, getSlot(n, "feature:python:tp_vectorcall"), "tp_vectorcall", "vectorcallfunc");
- Printv(f, "#endif\n", NIL);
- Printv(f, "#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000)\n", NIL);
- printSlot(f, getSlot(), "tp_print");
- Printv(f, "#endif\n", NIL);
-
- Printv(f, "#ifdef COUNT_ALLOCS\n", NIL);
- printSlot(f, getSlot(n, "feature:python:tp_allocs"), "tp_allocs", "Py_ssize_t");
- printSlot(f, getSlot(n, "feature:python:tp_frees"), "tp_frees", "Py_ssize_t");
- printSlot(f, getSlot(n, "feature:python:tp_maxalloc"), "tp_maxalloc", "Py_ssize_t");
- printSlot(f, getSlot(n, "feature:python:tp_prev"), "tp_prev");
- printSlot(f, getSlot(n, "feature:python:tp_next"), "tp_next");
- Printv(f, "#endif\n", NIL);
- Printf(f, " },\n");
-
- // PyAsyncMethods as_async
- Printv(f, "#if PY_VERSION_HEX >= 0x03050000\n", NIL);
- Printf(f, " {\n");
- printSlot(f, getSlot(n, "feature:python:am_await"), "am_await", "unaryfunc");
- printSlot(f, getSlot(n, "feature:python:am_aiter"), "am_aiter", "unaryfunc");
- printSlot(f, getSlot(n, "feature:python:am_anext"), "am_anext", "unaryfunc");
- Printv(f, "# if PY_VERSION_HEX >= 0x030a0000\n", NIL);
- printSlot(f, getSlot(n, "feature:python:am_send"), "am_send", "sendfunc");
- Printv(f, "# endif\n", NIL);
- Printf(f, " },\n");
- Printv(f, "#endif\n", NIL);
-
- // PyNumberMethods as_number
- Printf(f, " {\n");
- printSlot(f, getSlot(n, "feature:python:nb_add"), "nb_add", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_subtract"), "nb_subtract", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_multiply"), "nb_multiply", "binaryfunc");
- Printv(f, "#if PY_VERSION_HEX < 0x03000000\n", NIL);
- printSlot(f, getSlot(n, "feature:python:nb_divide"), "nb_divide", "binaryfunc");
- Printv(f, "#endif\n", NIL);
- printSlot(f, getSlot(n, "feature:python:nb_remainder"), "nb_remainder", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_divmod"), "nb_divmod", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_power"), "nb_power", "ternaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_negative"), "nb_negative", "unaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_positive"), "nb_positive", "unaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_absolute"), "nb_absolute", "unaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_nonzero"), "nb_nonzero", "inquiry");
- printSlot(f, getSlot(n, "feature:python:nb_invert"), "nb_invert", "unaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_lshift"), "nb_lshift", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_rshift"), "nb_rshift", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_and"), "nb_and", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_xor"), "nb_xor", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_or"), "nb_or", "binaryfunc");
- Printv(f, "#if PY_VERSION_HEX < 0x03000000\n", NIL);
- printSlot(f, getSlot(n, "feature:python:nb_coerce"), "nb_coerce", "coercion");
- Printv(f, "#endif\n", NIL);
- printSlot(f, getSlot(n, "feature:python:nb_int"), "nb_int", "unaryfunc");
- Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL);
- printSlot(f, getSlot(n, "feature:python:nb_reserved"), "nb_reserved", "void *");
- Printv(f, "#else\n", NIL);
- printSlot(f, getSlot(n, "feature:python:nb_long"), "nb_long", "unaryfunc");
- Printv(f, "#endif\n", NIL);
- printSlot(f, getSlot(n, "feature:python:nb_float"), "nb_float", "unaryfunc");
- Printv(f, "#if PY_VERSION_HEX < 0x03000000\n", NIL);
- printSlot(f, getSlot(n, "feature:python:nb_oct"), "nb_oct", "unaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_hex"), "nb_hex", "unaryfunc");
- Printv(f, "#endif\n", NIL);
- printSlot(f, getSlot(n, "feature:python:nb_inplace_add"), "nb_inplace_add", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_inplace_subtract"), "nb_inplace_subtract", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_inplace_multiply"), "nb_inplace_multiply", "binaryfunc");
- Printv(f, "#if PY_VERSION_HEX < 0x03000000\n", NIL);
- printSlot(f, getSlot(n, "feature:python:nb_inplace_divide"), "nb_inplace_divide", "binaryfunc");
- Printv(f, "#endif\n", NIL);
- printSlot(f, getSlot(n, "feature:python:nb_inplace_remainder"), "nb_inplace_remainder", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_inplace_power"), "nb_inplace_power", "ternaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_inplace_lshift"), "nb_inplace_lshift", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_inplace_rshift"), "nb_inplace_rshift", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_inplace_and"), "nb_inplace_and", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_inplace_xor"), "nb_inplace_xor", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_inplace_or"), "nb_inplace_or", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_floor_divide"), "nb_floor_divide", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_divide"), "nb_true_divide", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_inplace_floor_divide"), "nb_inplace_floor_divide", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_inplace_divide"), "nb_inplace_true_divide", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_index"), "nb_index", "unaryfunc");
- Printv(f, "#if PY_VERSION_HEX >= 0x03050000\n", NIL);
- printSlot(f, getSlot(n, "feature:python:nb_matrix_multiply"), "nb_matrix_multiply", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_inplace_matrix_multiply"), "nb_inplace_matrix_multiply", "binaryfunc");
- Printv(f, "#endif\n", NIL);
- Printf(f, " },\n");
-
- // PyMappingMethods as_mapping;
- Printf(f, " {\n");
- printSlot(f, getSlot(n, "feature:python:mp_length"), "mp_length", "lenfunc");
- printSlot(f, getSlot(n, "feature:python:mp_subscript"), "mp_subscript", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:mp_ass_subscript"), "mp_ass_subscript", "objobjargproc");
- Printf(f, " },\n");
-
- // PySequenceMethods as_sequence;
- Printf(f, " {\n");
- printSlot(f, getSlot(n, "feature:python:sq_length"), "sq_length", "lenfunc");
- printSlot(f, getSlot(n, "feature:python:sq_concat"), "sq_concat", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:sq_repeat"), "sq_repeat", "ssizeargfunc");
- printSlot(f, getSlot(n, "feature:python:sq_item"), "sq_item", "ssizeargfunc");
- Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL);
- printSlot(f, getSlot(n, "feature:python:was_sq_slice"), "was_sq_slice", "void *");
- Printv(f, "#else\n", NIL);
- printSlot(f, getSlot(n, "feature:python:sq_slice"), "sq_slice", "ssizessizeargfunc");
- Printv(f, "#endif\n", NIL);
- printSlot(f, getSlot(n, "feature:python:sq_ass_item"), "sq_ass_item", "ssizeobjargproc");
- Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL);
- printSlot(f, getSlot(n, "feature:python:was_sq_ass_slice"), "was_sq_ass_slice", "void *");
- Printv(f, "#else\n", NIL);
- printSlot(f, getSlot(n, "feature:python:sq_ass_slice"), "sq_ass_slice", "ssizessizeobjargproc");
- Printv(f, "#endif\n", NIL);
- printSlot(f, getSlot(n, "feature:python:sq_contains"), "sq_contains", "objobjproc");
- printSlot(f, getSlot(n, "feature:python:sq_inplace_concat"), "sq_inplace_concat", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:sq_inplace_repeat"), "sq_inplace_repeat", "ssizeargfunc");
- Printf(f, " },\n");
-
- // PyBufferProcs as_buffer;
- Printf(f, " {\n");
- Printv(f, "#if PY_VERSION_HEX < 0x03000000\n", NIL);
- printSlot(f, getSlot(n, "feature:python:bf_getreadbuffer"), "bf_getreadbuffer", "readbufferproc");
- printSlot(f, getSlot(n, "feature:python:bf_getwritebuffer"), "bf_getwritebuffer", "writebufferproc");
- printSlot(f, getSlot(n, "feature:python:bf_getsegcount"), "bf_getsegcount", "segcountproc");
- printSlot(f, getSlot(n, "feature:python:bf_getcharbuffer"), "bf_getcharbuffer", "charbufferproc");
- Printv(f, "#endif\n", NIL);
- printSlot(f, getSlot(n, "feature:python:bf_getbuffer"), "bf_getbuffer", "getbufferproc");
- printSlot(f, getSlot(n, "feature:python:bf_releasebuffer"), "bf_releasebuffer", "releasebufferproc");
- Printf(f, " },\n");
-
- // PyObject *ht_name, *ht_slots, *ht_qualname;
- printSlot(f, getSlot(n, "feature:python:ht_name"), "ht_name", "PyObject *");
- printSlot(f, getSlot(n, "feature:python:ht_slots"), "ht_slots", "PyObject *");
- Printv(f, "#if PY_VERSION_HEX >= 0x03030000\n", NIL);
- printSlot(f, getSlot(n, "feature:python:ht_qualname"), "ht_qualname", "PyObject *");
-
- // struct _dictkeysobject *ht_cached_keys;
- printSlot(f, getSlot(n, "feature:python:ht_cached_keys"), "ht_cached_keys");
- Printv(f, "#endif\n", NIL);
-
- // PyObject *ht_module;
- Printv(f, "#if PY_VERSION_HEX >= 0x03090000\n", NIL);
- printSlot(f, getSlot(n, "feature:python:ht_module"), "ht_module", "PyObject *");
- Printv(f, "#endif\n", NIL);
-
- // char *_ht_tpname;
- Printv(f, "#if PY_VERSION_HEX >= 0x030b0000\n", NIL);
- printSlot(f, getSlot(n, "feature:python:_ht_tpname"), "_ht_tpname", "char *");
-
- // struct _specialization_cache _spec_cache;
- Printf(f, " {\n");
- printSlot(f, getSlot(n, "feature:python:getitem"), "getitem", "PyObject *");
- Printf(f, " }\n");
- Printv(f, "#endif\n", NIL);
- Printf(f, "};\n\n");
-
- String *clientdata = NewString("");
- Printf(clientdata, "&%s_clientdata", templ);
- SwigType_remember_mangleddata(pmname, clientdata);
-
- SwigType *smart = Swig_cparse_smartptr(n);
- if (smart) {
- SwigType_add_pointer(smart);
- String *smart_pmname = SwigType_manglestr(smart);
- SwigType_remember_mangleddata(smart_pmname, clientdata);
- Delete(smart_pmname);
- }
-
- String *clientdata_klass = NewString("0");
- if (GetFlag(n, "feature:implicitconv")) {
- Clear(clientdata_klass);
- Printf(clientdata_klass, "(PyObject *) &%s_type", templ);
- }
-
- Printf(f, "SWIGINTERN SwigPyClientData %s_clientdata = {%s, 0, 0, 0, 0, 0, (PyTypeObject *)&%s_type};\n\n", templ, clientdata_klass, templ);
-
- Printv(f_init, " if (PyType_Ready(builtin_pytype) < 0) {\n", NIL);
- Printf(f_init, " PyErr_SetString(PyExc_TypeError, \"Could not create type '%s'.\");\n", symname);
- Printv(f_init, "#if PY_VERSION_HEX >= 0x03000000\n", NIL);
- Printv(f_init, " return NULL;\n", NIL);
- Printv(f_init, "#else\n", NIL);
- Printv(f_init, " return;\n", NIL);
- Printv(f_init, "#endif\n", NIL);
- Printv(f_init, " }\n", NIL);
- Printv(f_init, " Py_INCREF(builtin_pytype);\n", NIL);
- Printf(f_init, " PyModule_AddObject(m, \"%s\", (PyObject *)builtin_pytype);\n", symname);
- Printf(f_init, " SwigPyBuiltin_AddPublicSymbol(public_interface, \"%s\");\n", symname);
- Printv(f_init, " d = md;\n", NIL);
-
- Delete(clientdata);
- Delete(smart);
- Delete(rname);
- Delete(pname);
- Delete(mname);
- Delete(pmname);
- Delete(templ);
- Delete(tp_flags);
- Delete(tp_flags_py3);
- Delete(tp_as_buffer);
- Delete(tp_as_mapping);
- Delete(tp_as_sequence);
- Delete(tp_as_number);
- Delete(quoted_symname);
- Delete(quoted_tp_doc_str);
- Delete(tp_init);
- Delete(clientdata_klass);
- Delete(richcompare_func);
- Delete(getset_name);
- Delete(methods_name);
- }
-
- virtual int classHandler(Node *n) {
- File *f_shadow_file = f_shadow;
- Node *base_node = NULL;
-
- if (shadow) {
-
- /* Create new strings for building up a wrapper function */
- have_constructor = 0;
- have_repr = 0;
- have_builtin_static_member_method_callback = false;
-
- class_name = Getattr(n, "sym:name");
- real_classname = Getattr(n, "name");
-
- if (!addSymbol(class_name, n))
- return SWIG_ERROR;
-
- if (builtin) {
- List *baselist = Getattr(n, "bases");
- if (baselist && Len(baselist) > 0) {
- Iterator b = First(baselist);
- base_node = b.item;
- }
- }
-
- shadow_indent = (String *) tab4;
-
- /* Handle inheritance */
- String *base_class = NewString("");
- List *baselist = Getattr(n, "bases");
- if (baselist && Len(baselist)) {
- Iterator b;
- b = First(baselist);
- while (b.item) {
- String *bname = Getattr(b.item, "python:proxy");
- bool ignore = GetFlag(b.item, "feature:ignore") ? true : false;
- if (!bname || ignore) {
- if (!bname && !ignore) {
- Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(n), Getline(n),
- "Base class '%s' ignored - unknown module name for base. Either import the appropriate module interface file or specify the name of the module in the %%import directive.\n",
- SwigType_namestr(Getattr(b.item, "name")));
- }
- b = Next(b);
- continue;
- }
- Printv(base_class, bname, NIL);
- b = Next(b);
- if (b.item) {
- Printv(base_class, ", ", NIL);
- }
- }
- }
-
- if (builtin) {
- Hash *base_richcompare = NULL;
- Hash *richcompare = NULL;
- if (base_node)
- base_richcompare = Getattr(base_node, "python:richcompare");
- if (base_richcompare)
- richcompare = Copy(base_richcompare);
- else
- richcompare = NewHash();
- Setattr(n, "python:richcompare", richcompare);
- }
-
- /* dealing with abstract base class */
- String *abcs = Getattr(n, "feature:python:abc");
- if (abcs) {
- if (Len(base_class) > 0)
- Printv(base_class, ", ", NIL);
- Printv(base_class, abcs, NIL);
- }
-
- if (builtin) {
- if (have_docstring(n)) {
- String *ds = cdocstring(n, AUTODOC_CLASS);
- Setattr(n, "feature:python:tp_doc", ds);
- Delete(ds);
- } else {
- String *name = Getattr(n, "name");
- String *rname = add_explicit_scope(SwigType_namestr(name));
- Setattr(n, "feature:python:tp_doc", rname);
- Delete(rname);
- }
- } else {
- if (GetFlag(n, "feature:python:nondynamic"))
- Printv(f_shadow, "@_swig_add_metaclass(_SwigNonDynamicMeta)\n", NIL);
- Printv(f_shadow, "class ", class_name, NIL);
-
- if (Len(base_class)) {
- Printf(f_shadow, "(%s)", base_class);
- } else {
- if (GetFlag(n, "feature:exceptionclass")) {
- Printf(f_shadow, "(Exception)");
- } else {
- Printf(f_shadow, "(object");
- /* Replace @_swig_add_metaclass above with below when support for python 2.7 is dropped
- if (GetFlag(n, "feature:python:nondynamic")) {
- Printf(f_shadow, ", metaclass=_SwigNonDynamicMeta");
- }
- */
- Printf(f_shadow, ")");
- }
- }
-
- Printf(f_shadow, ":\n");
-
- // write docstrings if requested
- if (have_docstring(n)) {
- String *str = docstring(n, AUTODOC_CLASS, tab4);
- if (str && Len(str))
- Printv(f_shadow, tab4, str, "\n\n", NIL);
- }
-
- Printv(f_shadow, tab4, "thisown = property(lambda x: x.this.own(), ", "lambda x, v: x.this.own(v), doc=\"The membership flag\")\n", NIL);
- /* Add static attribute */
- if (GetFlag(n, "feature:python:nondynamic")) {
- Printv(f_shadow_file, tab4, "__setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)\n", NIL);
- }
- }
- }
-
- /* Emit all of the members */
-
- in_class = 1;
- if (builtin)
- builtin_pre_decl(n);
-
- /* Override the shadow file so we can capture its methods */
- f_shadow = NewString("");
-
- // Set up type check for director class constructor
- Clear(none_comparison);
- if (builtin && Swig_directorclass(n)) {
- String *p_real_classname = Copy(real_classname);
- SwigType_add_pointer(p_real_classname);
- String *mangle = SwigType_manglestr(p_real_classname);
- String *descriptor = NewStringf("SWIGTYPE%s", mangle);
- Printv(none_comparison, "self->ob_type != ((SwigPyClientData *)(", descriptor, ")->clientdata)->pytype", NIL);
- Delete(descriptor);
- Delete(mangle);
- Delete(p_real_classname);
- } else {
- Printv(none_comparison, "$arg != Py_None", NIL);
- }
-
- Language::classHandler(n);
-
- in_class = 0;
-
- /* Complete the class */
- if (shadow) {
- /* Generate a class registration function */
- // Replace storing a pointer to underlying class with a smart pointer (intended for use with non-intrusive smart pointers)
- SwigType *smart = Swig_cparse_smartptr(n);
- SwigType *ct = Copy(smart ? smart : real_classname);
- SwigType_add_pointer(ct);
- SwigType *realct = Copy(real_classname);
- SwigType_add_pointer(realct);
- SwigType_remember(realct);
- if (builtin) {
- Printv(f_wrappers, builtin_closures_code, NIL);
- Delete(builtin_closures_code);
- builtin_closures_code = NewString("");
- Clear(builtin_closures);
- } else {
- Printv(f_wrappers, "SWIGINTERN PyObject *", class_name, "_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {\n", NIL);
- Printv(f_wrappers, " PyObject *obj;\n", NIL);
- Printv(f_wrappers, " if (!SWIG_Python_UnpackTuple(args, \"swigregister\", 1, 1, &obj)) return NULL;\n", NIL);
-
- Printv(f_wrappers,
- " SWIG_TypeNewClientData(SWIGTYPE", SwigType_manglestr(ct), ", SWIG_NewClientData(obj));\n", " return SWIG_Py_Void();\n", "}\n\n", NIL);
- String *cname = NewStringf("%s_swigregister", class_name);
- add_method(cname, cname, 0, 0, 1, 1, 1);
- Delete(cname);
- }
- Delete(smart);
- Delete(ct);
- Delete(realct);
- if (!have_constructor) {
- if (!builtin)
- Printv(f_shadow_file, "\n", tab4, "def __init__(self, *args, **kwargs):\n", tab8, "raise AttributeError(\"", "No constructor defined",
- (Getattr(n, "abstracts") ? " - class is abstract" : ""), "\")\n", NIL);
- } else if (!builtin) {
-
- Printv(f_wrappers, "SWIGINTERN PyObject *", class_name, "_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {\n", NIL);
- Printv(f_wrappers, " return SWIG_Python_InitShadowInstance(args);\n", "}\n\n", NIL);
- String *cname = NewStringf("%s_swiginit", class_name);
- add_method(cname, cname, 0);
- Delete(cname);
- }
- if (!have_repr && !builtin) {
- /* Supply a repr method for this class */
- String *rname = SwigType_namestr(real_classname);
- Printv(f_shadow_file, tab4, "__repr__ = _swig_repr\n", NIL);
- Delete(rname);
- }
-
- if (builtin)
- builtin_post_decl(f_builtins, n);
-
- if (builtin_tp_init) {
- Delete(builtin_tp_init);
- builtin_tp_init = 0;
- }
-
- if (!builtin) {
- /* Now emit methods */
- Printv(f_shadow_file, f_shadow, NIL);
- Printf(f_shadow_file, "\n");
- Printf(f_shadow_file, "# Register %s in %s:\n", class_name, module);
- Printf(f_shadow_file, "%s.%s_swigregister(%s)\n", module, class_name, class_name);
- }
-
- shadow_indent = 0;
- if (Len(f_shadow_stubs) > 0)
- Printf(f_shadow_file, "%s\n", f_shadow_stubs);
- Clear(f_shadow_stubs);
- }
-
- if (builtin) {
- Clear(class_members);
- Clear(builtin_getset);
- Clear(builtin_methods);
- }
-
- /* Restore shadow file back to original version */
- Delete(f_shadow);
- f_shadow = f_shadow_file;
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * functionHandler() - Mainly overloaded for callback handling
- * ------------------------------------------------------------ */
-
- virtual int functionHandler(Node *n) {
- String *pcb = GetFlagAttr(n, "feature:python:callback");
- if (pcb) {
- if (Strcmp(pcb, "1") == 0) {
- SetFlagAttr(n, "feature:callback", "%s_cb_ptr");
- } else {
- SetFlagAttr(n, "feature:callback", pcb);
- }
- autodoc_l dlevel = autodoc_level(Getattr(n, "feature:autodoc"));
- if (dlevel != NO_AUTODOC && dlevel > TYPES_AUTODOC) {
- Setattr(n, "feature:autodoc", "1");
- }
- }
- return Language::functionHandler(n);
- }
-
- /* ------------------------------------------------------------
- * memberfunctionHandler()
- * ------------------------------------------------------------ */
-
- virtual int memberfunctionHandler(Node *n) {
- String *symname = Getattr(n, "sym:name");
- int oldshadow;
-
- if (builtin)
- Swig_save("builtin_memberfunc", n, "python:argcount", NIL);
-
- /* Create the default member function */
- oldshadow = shadow; /* Disable shadowing when wrapping member functions */
- if (shadow)
- shadow = shadow | PYSHADOW_MEMBER;
- Language::memberfunctionHandler(n);
- shadow = oldshadow;
-
- if (builtin && in_class) {
- // Can't use checkAttribute(n, "access", "public") because
- // "access" attr isn't set on %extend methods
- if (!checkAttribute(n, "access", "private") && strncmp(Char(symname), "operator ", 9) && !Getattr(class_members, symname)) {
- String *fullname = Swig_name_member(NSPACE_TODO, class_name, symname);
- String *wname = Swig_name_wrapper(fullname);
- Setattr(class_members, symname, n);
- int argcount = Getattr(n, "python:argcount") ? atoi(Char(Getattr(n, "python:argcount"))) : 2;
- String *ds = have_docstring(n) ? cdocstring(n, AUTODOC_METHOD) : NewString("");
- if (check_kwargs(n)) {
- // Cast via void(*)(void) to suppress GCC -Wcast-function-type
- // warning. Python should always call the function correctly, but
- // the Python C API requires us to store it in function pointer of a
- // different type.
- Printf(builtin_methods, " { \"%s\", (PyCFunction)(void(*)(void))%s, METH_VARARGS|METH_KEYWORDS, \"%s\" },\n", symname, wname, ds);
- } else if (argcount == 0) {
- Printf(builtin_methods, " { \"%s\", %s, METH_NOARGS, \"%s\" },\n", symname, wname, ds);
- } else if (argcount == 1) {
- Printf(builtin_methods, " { \"%s\", %s, METH_O, \"%s\" },\n", symname, wname, ds);
- } else {
- Printf(builtin_methods, " { \"%s\", %s, METH_VARARGS, \"%s\" },\n", symname, wname, ds);
- }
- Delete(fullname);
- Delete(wname);
- Delete(ds);
- }
- }
-
- if (builtin)
- Swig_restore(n);
-
- if (!Getattr(n, "sym:nextSibling")) {
- if (shadow && !builtin) {
- int fproxy = fastproxy;
- String *fullname = Swig_name_member(NSPACE_TODO, class_name, symname);
- if (Strcmp(symname, "__repr__") == 0) {
- have_repr = 1;
- }
- if (Getattr(n, "feature:shadow")) {
- String *pycode = indent_pythoncode(Getattr(n, "feature:shadow"), tab4, Getfile(n), Getline(n), "%feature(\"shadow\")");
- String *pyaction = NewStringf("%s.%s", module, fullname);
- Replaceall(pycode, "$action", pyaction);
- Delete(pyaction);
- Printv(f_shadow, pycode, "\n", NIL);
- Delete(pycode);
- fproxy = 0;
- } else {
- int allow_kwargs = (check_kwargs(n) && !Getattr(n, "sym:overloaded")) ? 1 : 0;
- String *parms = make_pyParmList(n, true, false, allow_kwargs);
- String *callParms = make_pyParmList(n, true, true, allow_kwargs);
- if (!have_addtofunc(n)) {
- if (!fastproxy || olddefs) {
- Printv(f_shadow, "\n", tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
- if (have_docstring(n))
- Printv(f_shadow, tab8, docstring(n, AUTODOC_METHOD, tab8), "\n", NIL);
- Printv(f_shadow, tab8, "return ", funcCall(fullname, callParms), "\n", NIL);
- }
- } else {
- Printv(f_shadow, "\n", tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
- if (have_docstring(n))
- Printv(f_shadow, tab8, docstring(n, AUTODOC_METHOD, tab8), "\n", NIL);
- if (have_pythonprepend(n)) {
- fproxy = 0;
- Printv(f_shadow, indent_pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
- }
- if (have_pythonappend(n)) {
- fproxy = 0;
- Printv(f_shadow, tab8, "val = ", funcCall(fullname, callParms), "\n", NIL);
- Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
- Printv(f_shadow, tab8, "return val\n\n", NIL);
- } else {
- Printv(f_shadow, tab8, "return ", funcCall(fullname, callParms), "\n\n", NIL);
- }
- }
- }
- if (fproxy) {
- Printf(f_shadow, tab4);
- Printf(f_shadow, "%s = _swig_new_instance_method(%s.%s)\n", symname, module, Swig_name_member(NSPACE_TODO, class_name, symname));
- }
- Delete(fullname);
- }
- }
- return SWIG_OK;
- }
-
-
- /* ------------------------------------------------------------
- * staticmemberfunctionHandler()
- * ------------------------------------------------------------ */
-
- virtual int staticmemberfunctionHandler(Node *n) {
- String *symname = Getattr(n, "sym:name");
- if (builtin && in_class) {
- Swig_save("builtin_memberconstantHandler", n, "pybuiltin:symname", NIL);
- Setattr(n, "pybuiltin:symname", symname);
- }
- Language::staticmemberfunctionHandler(n);
- if (builtin && in_class) {
- Swig_restore(n);
- }
-
- int kw = (check_kwargs(n) && !Getattr(n, "sym:overloaded")) ? 1 : 0;
- if (builtin && in_class) {
- if ((GetFlagAttr(n, "feature:extend") || checkAttribute(n, "access", "public"))
- && !Getattr(class_members, symname)) {
- String *fullname = Swig_name_member(NSPACE_TODO, class_name, symname);
- String *wname = Swig_name_wrapper(fullname);
- Setattr(class_members, symname, n);
- int funpack = fastunpack && !Getattr(n, "sym:overloaded");
- String *pyflags = NewString("METH_STATIC|");
- int argcount = Getattr(n, "python:argcount") ? atoi(Char(Getattr(n, "python:argcount"))) : 2;
- if (funpack && argcount == 0)
- Append(pyflags, "METH_NOARGS");
- else if (funpack && argcount == 1)
- Append(pyflags, "METH_O");
- else
- Append(pyflags, kw ? "METH_VARARGS|METH_KEYWORDS" : "METH_VARARGS");
- // Cast via void(*)(void) to suppress GCC -Wcast-function-type warning.
- // Python should always call the function correctly, but the Python C
- // API requires us to store it in function pointer of a different type.
- if (have_docstring(n)) {
- String *ds = cdocstring(n, AUTODOC_STATICFUNC);
- Printf(builtin_methods, " { \"%s\", (PyCFunction)(void(*)(void))%s, %s, \"%s\" },\n", symname, wname, pyflags, ds);
- Delete(ds);
- } else if (Getattr(n, "feature:callback")) {
- String *ds = NewStringf("swig_ptr: %s", Getattr(n, "feature:callback:name"));
- Printf(builtin_methods, " { \"%s\", (PyCFunction)(void(*)(void))%s, %s, \"%s\" },\n", symname, wname, pyflags, ds);
- Delete(ds);
- have_builtin_static_member_method_callback = true;
- } else {
- Printf(builtin_methods, " { \"%s\", (PyCFunction)(void(*)(void))%s, %s, \"\" },\n", symname, wname, pyflags);
- }
- Delete(fullname);
- Delete(wname);
- Delete(pyflags);
- }
- return SWIG_OK;
- }
-
- if (Getattr(n, "sym:nextSibling")) {
- return SWIG_OK;
- }
-
- if (shadow) {
- String *staticfunc_name = NewString(fastproxy ? "_swig_new_static_method" : "staticmethod");
- bool fast = (fastproxy && !have_addtofunc(n)) || Getattr(n, "feature:callback");
- if (!fast || olddefs) {
- String *parms = make_pyParmList(n, false, false, kw);
- String *callParms = make_pyParmList(n, false, true, kw);
- Printv(f_shadow, "\n", tab4, "@staticmethod", NIL);
- Printv(f_shadow, "\n", tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
- if (have_docstring(n))
- Printv(f_shadow, tab8, docstring(n, AUTODOC_STATICFUNC, tab8), "\n", NIL);
- if (have_pythonprepend(n))
- Printv(f_shadow, indent_pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
- if (have_pythonappend(n)) {
- Printv(f_shadow, tab8, "val = ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n", NIL);
- Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
- Printv(f_shadow, tab8, "return val\n", NIL);
- } else {
- Printv(f_shadow, tab8, "return ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n", NIL);
- }
- }
-
- // Below may result in a 2nd definition of the method when -olddefs is used. The Python interpreter will use the second definition as it overwrites the first.
- if (fast) {
- Printv(f_shadow, tab4, symname, " = ", staticfunc_name, "(", module, ".", Swig_name_member(NSPACE_TODO, class_name, symname),
- ")\n", NIL);
- }
- Delete(staticfunc_name);
- }
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * constructorDeclaration()
- * ------------------------------------------------------------ */
-
- virtual int constructorHandler(Node *n) {
- String *symname = Getattr(n, "sym:name");
- int oldshadow = shadow;
- int use_director = Swig_directorclass(n);
-
- /*
- * If we're wrapping the constructor of a C++ director class, prepend a new parameter
- * to receive the scripting language object (e.g. 'self')
- *
- */
- Swig_save("python:constructorHandler", n, "parms", NIL);
- if (use_director) {
- Parm *parms = Getattr(n, "parms");
- Parm *self;
- String *name = NewString("self");
- String *type = NewString("PyObject");
- SwigType_add_pointer(type);
- self = NewParm(type, name, n);
- Delete(type);
- Delete(name);
- Setattr(self, "lname", "O");
- if (parms)
- set_nextSibling(self, parms);
- Setattr(n, "parms", self);
- Setattr(n, "wrap:self", "1");
- Setattr(n, "hidden", "1");
- Delete(self);
- }
-
- if (shadow)
- shadow = shadow | PYSHADOW_MEMBER;
- Language::constructorHandler(n);
- shadow = oldshadow;
-
- Delattr(n, "wrap:self");
- Swig_restore(n);
-
- if (!Getattr(n, "sym:nextSibling")) {
- if (shadow) {
- int allow_kwargs = (check_kwargs(n) && (!Getattr(n, "sym:overloaded"))) ? 1 : 0;
- int handled_as_init = 0;
- if (!have_constructor) {
- String *nname = Getattr(n, "sym:name");
- String *sname = Getattr(getCurrentClass(), "sym:name");
- String *cname = Swig_name_construct(NSPACE_TODO, sname);
- handled_as_init = (Strcmp(nname, sname) == 0) || (Strcmp(nname, cname) == 0);
- Delete(cname);
- }
-
- String *subfunc = Swig_name_construct(NSPACE_TODO, symname);
- if (!have_constructor && handled_as_init) {
- if (!builtin) {
- if (Getattr(n, "feature:shadow")) {
- String *pycode = indent_pythoncode(Getattr(n, "feature:shadow"), tab4, Getfile(n), Getline(n), "%feature(\"shadow\")");
- String *pyaction = NewStringf("%s.%s", module, subfunc);
- Replaceall(pycode, "$action", pyaction);
- Delete(pyaction);
- Printv(f_shadow, pycode, "\n", NIL);
- Delete(pycode);
- } else {
- String *pass_self = NewString("");
- Node *parent = Swig_methodclass(n);
- String *classname = Swig_class_name(parent);
- String *rclassname = Swig_class_name(getCurrentClass());
- assert(rclassname);
- (void)rclassname;
-
- String *parms = make_pyParmList(n, true, false, allow_kwargs);
- /* Pass 'self' only if using director */
- String *callParms = make_pyParmList(n, false, true, allow_kwargs, true);
-
- if (use_director) {
- Insert(callParms, 0, "_self, ");
- Printv(pass_self, tab8, NIL);
- Printf(pass_self, "if self.__class__ == %s:\n", classname);
- //Printv(pass_self, tab8, tab4, "args = (None,) + args\n", tab8, "else:\n", tab8, tab4, "args = (self,) + args\n", NIL);
- Printv(pass_self, tab8, tab4, "_self = None\n", tab8, "else:\n", tab8, tab4, "_self = self\n", NIL);
- }
-
- Printv(f_shadow, "\n", tab4, "def __init__(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
- if (have_docstring(n))
- Printv(f_shadow, tab8, docstring(n, AUTODOC_CTOR, tab8), "\n", NIL);
- if (have_pythonprepend(n))
- Printv(f_shadow, indent_pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
- Printv(f_shadow, pass_self, NIL);
- Printv(f_shadow, tab8, module, ".", class_name, "_swiginit(self, ", funcCall(subfunc, callParms), ")\n", NIL);
- if (have_pythonappend(n))
- Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n\n", NIL);
- Delete(pass_self);
- }
- have_constructor = 1;
- }
- } else {
- /* Hmmm. We seem to be creating a different constructor. We're just going to create a
- function for it. */
- if (!builtin) {
- if (Getattr(n, "feature:shadow")) {
- String *pycode = indent_pythoncode(Getattr(n, "feature:shadow"), "", Getfile(n), Getline(n), "%feature(\"shadow\")");
- String *pyaction = NewStringf("%s.%s", module, subfunc);
- Replaceall(pycode, "$action", pyaction);
- Delete(pyaction);
- Printv(f_shadow_stubs, pycode, "\n", NIL);
- Delete(pycode);
- } else {
- String *parms = make_pyParmList(n, false, false, allow_kwargs);
- String *callParms = make_pyParmList(n, false, true, allow_kwargs);
-
- Printv(f_shadow_stubs, "\ndef ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
- if (have_docstring(n))
- Printv(f_shadow_stubs, tab4, docstring(n, AUTODOC_CTOR, tab4), "\n", NIL);
- if (have_pythonprepend(n))
- Printv(f_shadow_stubs, indent_pythoncode(pythonprepend(n), tab4, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
- Printv(f_shadow_stubs, tab4, "val = ", funcCall(subfunc, callParms), "\n", NIL);
- if (have_pythonappend(n))
- Printv(f_shadow_stubs, indent_pythoncode(pythonappend(n), tab4, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
- Printv(f_shadow_stubs, tab4, "return val\n", NIL);
- }
- } else {
- Printf(f_shadow_stubs, "%s = %s\n", symname, subfunc);
- }
- }
- Delete(subfunc);
- }
- }
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * destructorHandler()
- * ------------------------------------------------------------ */
-
- virtual int destructorHandler(Node *n) {
- String *symname = Getattr(n, "sym:name");
- int oldshadow = shadow;
-
- if (builtin && in_class) {
- Node *cls = Swig_methodclass(n);
- // Use the destructor for the tp_dealloc slot unless a user overrides it with another method
- if (!Getattr(cls, "feature:python:tp_dealloc")) {
- Setattr(n, "feature:python:slot", "tp_dealloc");
- Setattr(n, "feature:python:slot:functype", "destructor");
- }
- }
-
- if (shadow)
- shadow = shadow | PYSHADOW_MEMBER;
- //Setattr(n,"emit:dealloc","1");
- Language::destructorHandler(n);
- shadow = oldshadow;
-
- if (shadow) {
- if (Getattr(n, "feature:shadow")) {
- String *pycode = indent_pythoncode(Getattr(n, "feature:shadow"), tab4, Getfile(n), Getline(n), "%feature(\"shadow\")");
- String *pyaction = NewStringf("%s.%s", module, Swig_name_destroy(NSPACE_TODO, symname));
- Replaceall(pycode, "$action", pyaction);
- Delete(pyaction);
- Printv(f_shadow, pycode, "\n", NIL);
- Delete(pycode);
- } else {
- Printv(f_shadow, tab4, "__swig_destroy__ = ", module, ".", Swig_name_destroy(NSPACE_TODO, symname), "\n", NIL);
- if (!have_pythonprepend(n) && !have_pythonappend(n)) {
- return SWIG_OK;
- }
- Printv(f_shadow, tab4, "def __del__(self):\n", NIL);
- if (have_docstring(n))
- Printv(f_shadow, tab8, docstring(n, AUTODOC_DTOR, tab8), "\n", NIL);
- if (have_pythonprepend(n))
- Printv(f_shadow, indent_pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
- if (have_pythonappend(n))
- Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
- Printv(f_shadow, tab8, "pass\n", NIL);
- Printv(f_shadow, "\n", NIL);
- }
- }
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * membervariableHandler()
- * ------------------------------------------------------------ */
-
- virtual int membervariableHandler(Node *n) {
- String *symname = Getattr(n, "sym:name");
-
- int oldshadow = shadow;
- if (shadow)
- shadow = shadow | PYSHADOW_MEMBER;
- Language::membervariableHandler(n);
- shadow = oldshadow;
-
- if (shadow && !builtin) {
- String *mname = Swig_name_member(NSPACE_TODO, class_name, symname);
- String *setname = Swig_name_set(NSPACE_TODO, mname);
- String *getname = Swig_name_get(NSPACE_TODO, mname);
- int assignable = is_assignable(n);
- String *variable_annotation = variableAnnotation(n);
- Printv(f_shadow, tab4, symname, variable_annotation, " = property(", module, ".", getname, NIL);
- if (assignable)
- Printv(f_shadow, ", ", module, ".", setname, NIL);
- if (have_docstring(n)) {
- String *s = docstring(n, AUTODOC_VAR, tab4);
- if (Len(s))
- Printv(f_shadow, ", doc=", s, NIL);
- }
- Printv(f_shadow, ")\n", NIL);
- Delete(variable_annotation);
- Delete(mname);
- Delete(setname);
- Delete(getname);
- }
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * staticmembervariableHandler()
- * ------------------------------------------------------------ */
-
- virtual int staticmembervariableHandler(Node *n) {
- Swig_save("builtin_staticmembervariableHandler", n, "builtin_symname", NIL);
- Language::staticmembervariableHandler(n);
- Swig_restore(n);
-
- if (GetFlag(n, "wrappedasconstant"))
- return SWIG_OK;
-
- String *symname = Getattr(n, "sym:name");
-
- if (shadow) {
- if (!builtin && GetFlag(n, "hasconsttype")) {
- String *mname = Swig_name_member(NSPACE_TODO, class_name, symname);
- Printf(f_shadow_stubs, "%s.%s = %s.%s.%s\n", class_name, symname, module, global_name, mname);
- Delete(mname);
- } else {
- String *mname = Swig_name_member(NSPACE_TODO, class_name, symname);
- String *getname = Swig_name_get(NSPACE_TODO, mname);
- String *wrapgetname = Swig_name_wrapper(getname);
- String *vargetname = NewStringf("Swig_var_%s", getname);
- String *setname = Swig_name_set(NSPACE_TODO, mname);
- String *wrapsetname = Swig_name_wrapper(setname);
- String *varsetname = NewStringf("Swig_var_%s", setname);
-
- Wrapper *f = NewWrapper();
- Printv(f->def, "SWIGINTERN PyObject *", wrapgetname, "(PyObject *SWIGUNUSEDPARM(self), PyObject *SWIGUNUSEDPARM(args)) {", NIL);
- Printv(f->code, " return ", vargetname, "();\n", NIL);
- Append(f->code, "}\n");
- add_method(getname, wrapgetname, 0);
- Wrapper_print(f, f_wrappers);
- DelWrapper(f);
- int assignable = is_assignable(n);
- if (assignable) {
- int funpack = fastunpack;
- Wrapper *f = NewWrapper();
- Printv(f->def, "SWIGINTERN PyObject *", wrapsetname, "(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {", NIL);
- Wrapper_add_local(f, "res", "int res");
- if (!funpack) {
- Wrapper_add_local(f, "value", "PyObject *value");
- Append(f->code, "if (!PyArg_ParseTuple(args, \"O:set\", &value)) return NULL;\n");
- }
- Printf(f->code, "res = %s(%s);\n", varsetname, funpack ? "args" : "value");
- Append(f->code, "return !res ? SWIG_Py_Void() : NULL;\n");
- Append(f->code, "}\n");
- Wrapper_print(f, f_wrappers);
- add_method(setname, wrapsetname, 0, 0, funpack, 1, 1);
- DelWrapper(f);
- }
- if (!builtin) {
- Printv(f_shadow, tab4, symname, " = property(", module, ".", getname, NIL);
- if (assignable)
- Printv(f_shadow, ", ", module, ".", setname, NIL);
- if (have_docstring(n)) {
- String *s = docstring(n, AUTODOC_VAR, tab4);
- if (Len(s))
- Printv(f_shadow, ", doc=", s, NIL);
- }
- Printv(f_shadow, ")\n", NIL);
- }
- String *getter = Getattr(n, "pybuiltin:getter");
- String *setter = Getattr(n, "pybuiltin:setter");
- Hash *h = NULL;
- if (getter || setter) {
- h = Getattr(builtin_getset, symname);
- if (!h) {
- h = NewHash();
- Setattr(h, "static", "1");
- Setattr(builtin_getset, symname, h);
- }
- }
- if (getter)
- Setattr(h, "getter", getter);
- if (setter)
- Setattr(h, "setter", setter);
- if (h)
- Delete(h);
- Delete(mname);
- Delete(getname);
- Delete(wrapgetname);
- Delete(vargetname);
- Delete(setname);
- Delete(wrapsetname);
- Delete(varsetname);
- }
- }
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * memberconstantHandler()
- * ------------------------------------------------------------ */
-
- virtual int memberconstantHandler(Node *n) {
- String *symname = Getattr(n, "sym:name");
- if (builtin && in_class) {
- Swig_save("builtin_memberconstantHandler", n, "pybuiltin:symname", NIL);
- Setattr(n, "pybuiltin:symname", symname);
- }
- int oldshadow = shadow;
- if (shadow)
- shadow = shadow | PYSHADOW_MEMBER;
- Language::memberconstantHandler(n);
- shadow = oldshadow;
-
- if (builtin && in_class) {
- Swig_restore(n);
- } else if (shadow) {
- Printv(f_shadow, tab4, symname, " = ", module, ".", Swig_name_member(NSPACE_TODO, class_name, symname), "\n", NIL);
- if (have_docstring(n))
- Printv(f_shadow, tab4, docstring(n, AUTODOC_CONST, tab4), "\n", NIL);
- }
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * insertDirective()
- *
- * Hook for %insert directive. We're going to look for special %shadow inserts
- * as a special case so we can do indenting correctly
- * ------------------------------------------------------------ */
-
- virtual int insertDirective(Node *n) {
- String *code = Getattr(n, "code");
- String *section = Getattr(n, "section");
-
- if (!ImportMode && (Cmp(section, "python") == 0 || Cmp(section, "shadow") == 0)) {
- if (shadow) {
- String *pycode = indent_pythoncode(code, shadow_indent, Getfile(n), Getline(n), "%pythoncode or %insert(\"python\") block");
- Printv(f_shadow, pycode, NIL);
- Delete(pycode);
- }
- } else if (!ImportMode && (Cmp(section, "pythonbegin") == 0)) {
- if (shadow) {
- String *pycode = indent_pythoncode(code, "", Getfile(n), Getline(n), "%pythonbegin or %insert(\"pythonbegin\") block");
- Printv(f_shadow_begin, pycode, NIL);
- Delete(pycode);
- }
- } else {
- Language::insertDirective(n);
- }
- return SWIG_OK;
- }
-
- virtual String *runtimeCode() {
- String *s = NewString("");
- String *shead = Swig_include_sys("pyhead.swg");
- if (!shead) {
- Printf(stderr, "*** Unable to open 'pyhead.swg'\n");
- } else {
- Append(s, shead);
- Delete(shead);
- }
- String *serrors = Swig_include_sys("pyerrors.swg");
- if (!serrors) {
- Printf(stderr, "*** Unable to open 'pyerrors.swg'\n");
- } else {
- Append(s, serrors);
- Delete(serrors);
- }
- String *sthread = Swig_include_sys("pythreads.swg");
- if (!sthread) {
- Printf(stderr, "*** Unable to open 'pythreads.swg'\n");
- } else {
- Append(s, sthread);
- Delete(sthread);
- }
- String *sapi = Swig_include_sys("pyapi.swg");
- if (!sapi) {
- Printf(stderr, "*** Unable to open 'pyapi.swg'\n");
- } else {
- Append(s, sapi);
- Delete(sapi);
- }
- String *srun = Swig_include_sys("pyrun.swg");
- if (!srun) {
- Printf(stderr, "*** Unable to open 'pyrun.swg'\n");
- } else {
- Append(s, srun);
- Delete(srun);
- }
- return s;
- }
-
- virtual String *defaultExternalRuntimeFilename() {
- return NewString("swigpyrun.h");
- }
-
- /*----------------------------------------------------------------------
- * kwargsSupport()
- *--------------------------------------------------------------------*/
-
- bool kwargsSupport() const {
- return true;
- }
-};
-
-/* ---------------------------------------------------------------
- * classDirectorMethod()
- *
- * Emit a virtual director method to pass a method call on to the
- * underlying Python object.
- *
- * ** Moved it here due to internal error on gcc-2.96 **
- * --------------------------------------------------------------- */
-int PYTHON::classDirectorMethods(Node *n) {
- director_method_index = 0;
- return Language::classDirectorMethods(n);
-}
-
-
-int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) {
- int is_void = 0;
- int is_pointer = 0;
- String *decl = Getattr(n, "decl");
- String *name = Getattr(n, "name");
- String *classname = Getattr(parent, "sym:name");
- String *c_classname = Getattr(parent, "name");
- String *symname = Getattr(n, "sym:name");
- String *declaration = NewString("");
- ParmList *l = Getattr(n, "parms");
- Wrapper *w = NewWrapper();
- String *tm;
- String *wrap_args = NewString("");
- String *returntype = Getattr(n, "type");
- String *value = Getattr(n, "value");
- String *storage = Getattr(n, "storage");
- bool pure_virtual = false;
- int status = SWIG_OK;
- int idx;
- bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
-
- if (builtin) {
- // Rename any wrapped parameters called 'self' as the generated code contains a variable with same name
- Parm *p;
- for (p = l; p; p = nextSibling(p)) {
- String *arg = Getattr(p, "name");
- if (arg && Cmp(arg, "self") == 0)
- Delattr(p, "name");
- }
- }
-
- if (Cmp(storage, "virtual") == 0) {
- if (Cmp(value, "0") == 0) {
- pure_virtual = true;
- }
- }
-
- /* determine if the method returns a pointer */
- is_pointer = SwigType_ispointer_return(decl);
- is_void = (!Cmp(returntype, "void") && !is_pointer);
-
- /* virtual method definition */
- String *target;
- String *pclassname = NewStringf("SwigDirector_%s", classname);
- String *qualified_name = NewStringf("%s::%s", pclassname, name);
- SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
- target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
- Printf(w->def, "%s", target);
- Delete(qualified_name);
- Delete(target);
- /* header declaration */
- target = Swig_method_decl(rtype, decl, name, l, 1);
- Printf(declaration, " virtual %s", target);
- Delete(target);
-
- // Get any exception classes in the throws typemap
- if (Getattr(n, "noexcept")) {
- Append(w->def, " noexcept");
- Append(declaration, " noexcept");
- }
- ParmList *throw_parm_list = 0;
- if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
- Parm *p;
- int gencomma = 0;
-
- Append(w->def, " throw(");
- Append(declaration, " throw(");
-
- if (throw_parm_list)
- Swig_typemap_attach_parms("throws", throw_parm_list, 0);
- for (p = throw_parm_list; p; p = nextSibling(p)) {
- if (Getattr(p, "tmap:throws")) {
- if (gencomma++) {
- Append(w->def, ", ");
- Append(declaration, ", ");
- }
- String *str = SwigType_str(Getattr(p, "type"), 0);
- Append(w->def, str);
- Append(declaration, str);
- Delete(str);
- }
- }
-
- Append(w->def, ")");
- Append(declaration, ")");
- }
-
- Append(w->def, " {");
- Append(declaration, ";\n");
-
- /* declare method return value
- * if the return value is a reference or const reference, a specialized typemap must
- * handle it, including declaration of c_result ($result).
- */
- if (!is_void && (!ignored_method || pure_virtual)) {
- if (!SwigType_isclass(returntype)) {
- if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
- String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
- Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL);
- Delete(construct_result);
- } else {
- Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL);
- }
- } else {
- String *cres = SwigType_lstr(returntype, "c_result");
- Printf(w->code, "%s;\n", cres);
- Delete(cres);
- }
- }
-
- if (builtin) {
- Printv(w->code, "PyObject *self = NULL;\n", NIL);
- Printv(w->code, "(void)self;\n", NIL);
- }
-
- if (ignored_method) {
- if (!pure_virtual) {
- if (!is_void)
- Printf(w->code, "return ");
- String *super_call = Swig_method_call(super, l);
- Printf(w->code, "%s;\n", super_call);
- Delete(super_call);
- } else {
- Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
- SwigType_namestr(name));
- }
- } else {
- /* attach typemaps to arguments (C/C++ -> Python) */
- String *arglist = NewString("");
- String *parse_args = NewString("");
-
- Swig_director_parms_fixup(l);
-
- /* remove the wrapper 'w' since it was producing spurious temps */
- Swig_typemap_attach_parms("in", l, 0);
- Swig_typemap_attach_parms("directorin", l, w);
- Swig_typemap_attach_parms("directorargout", l, w);
-
- Parm *p;
- char source[256];
-
- int outputs = 0;
- if (!is_void)
- outputs++;
-
- /* build argument list and type conversion string */
- idx = 0;
- p = l;
- int use_parse = 0;
- while (p) {
- if (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- continue;
- }
-
- /* old style? caused segfaults without the p!=0 check
- in the for() condition, and seems dangerous in the
- while loop as well.
- while (Getattr(p, "tmap:ignore")) {
- p = Getattr(p, "tmap:ignore:next");
- }
- */
-
- if (Getattr(p, "tmap:directorargout") != 0)
- outputs++;
-
- String *pname = Getattr(p, "name");
- String *ptype = Getattr(p, "type");
-
- Putc(',', arglist);
- if ((tm = Getattr(p, "tmap:directorin")) != 0) {
- String *parse = Getattr(p, "tmap:directorin:parse");
- if (!parse) {
- sprintf(source, "obj%d", idx++);
- String *input = NewString(source);
- Setattr(p, "emit:directorinput", input);
- Replaceall(tm, "$input", input);
- Delete(input);
- Replaceall(tm, "$owner", "0");
- /* Wrapper_add_localv(w, source, "swig::SwigVar_PyObject", source, "= 0", NIL); */
- Printv(wrap_args, "swig::SwigVar_PyObject ", source, ";\n", NIL);
-
- Printv(wrap_args, tm, "\n", NIL);
- Printv(arglist, "(PyObject *)", source, NIL);
- Putc('O', parse_args);
- } else {
- use_parse = 1;
- Append(parse_args, parse);
- Setattr(p, "emit:directorinput", pname);
- Replaceall(tm, "$input", pname);
- Replaceall(tm, "$owner", "0");
- if (Len(tm) == 0)
- Append(tm, pname);
- Append(arglist, tm);
- }
- p = Getattr(p, "tmap:directorin:next");
- continue;
- } else if (Cmp(ptype, "void")) {
- /* special handling for pointers to other C++ director classes.
- * ideally this would be left to a typemap, but there is currently no
- * way to selectively apply the dynamic_cast<> to classes that have
- * directors. in other words, the type "SwigDirector_$1_lname" only exists
- * for classes with directors. we avoid the problem here by checking
- * module.wrap::directormap, but it's not clear how to get a typemap to
- * do something similar. perhaps a new default typemap (in addition
- * to SWIGTYPE) called DIRECTORTYPE?
- */
- if (SwigType_ispointer(ptype) || SwigType_isreference(ptype)) {
- Node *module = Getattr(parent, "module");
- Node *target = Swig_directormap(module, ptype);
- sprintf(source, "obj%d", idx++);
- String *nonconst = 0;
- /* strip pointer/reference --- should move to Swig/stype.c */
- String *nptype = NewString(Char(ptype) + 2);
- /* name as pointer */
- String *ppname = Copy(pname);
- if (SwigType_isreference(ptype)) {
- Insert(ppname, 0, "&");
- }
- /* if necessary, cast away const since Python doesn't support it! */
- if (SwigType_isconst(nptype)) {
- nonconst = NewStringf("nc_tmp_%s", pname);
- String *nonconst_i = NewStringf("= const_cast< %s >(%s)", SwigType_lstr(ptype, 0), ppname);
- Wrapper_add_localv(w, nonconst, SwigType_lstr(ptype, 0), nonconst, nonconst_i, NIL);
- Delete(nonconst_i);
- Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number,
- "Target language argument '%s' discards const in director method %s::%s.\n",
- SwigType_str(ptype, pname), SwigType_namestr(c_classname), SwigType_namestr(name));
- } else {
- nonconst = Copy(ppname);
- }
- Delete(nptype);
- Delete(ppname);
- String *mangle = SwigType_manglestr(ptype);
- if (target) {
- String *director = NewStringf("director_%s", mangle);
- Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL);
- Wrapper_add_localv(w, source, "swig::SwigVar_PyObject", source, "= 0", NIL);
- Printf(wrap_args, "%s = SWIG_DIRECTOR_CAST(%s);\n", director, nonconst);
- Printf(wrap_args, "if (!%s) {\n", director);
- Printf(wrap_args, "%s = SWIG_InternalNewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
- Append(wrap_args, "} else {\n");
- Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director);
- Printf(wrap_args, "Py_INCREF((PyObject *)%s);\n", source);
- Append(wrap_args, "}\n");
- Delete(director);
- Printv(arglist, source, NIL);
- } else {
- Wrapper_add_localv(w, source, "swig::SwigVar_PyObject", source, "= 0", NIL);
- Printf(wrap_args, "%s = SWIG_InternalNewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
- //Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n",
- // source, nonconst, base);
- Printv(arglist, source, NIL);
- }
- Putc('O', parse_args);
- Delete(mangle);
- Delete(nonconst);
- } else {
- Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
- "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0),
- SwigType_namestr(c_classname), SwigType_namestr(name));
- status = SWIG_NOWRAP;
- break;
- }
- }
- p = nextSibling(p);
- }
-
- /* add the method name as a PyString */
- String *pyname = Getattr(n, "sym:name");
-
- int allow_thread = threads_enable(n);
-
- if (allow_thread) {
- thread_begin_block(n, w->code);
- Append(w->code, "{\n");
- }
-
- /* wrap complex arguments to PyObjects */
- Printv(w->code, wrap_args, NIL);
-
- /* pass the method call on to the Python object */
- if (dirprot_mode() && !is_public(n)) {
- Printf(w->code, "swig_set_inner(\"%s\", true);\n", name);
- }
-
-
- Append(w->code, "if (!swig_get_self()) {\n");
- Printf(w->code, " Swig::DirectorException::raise(\"'self' uninitialized, maybe you forgot to call %s.__init__.\");\n", classname);
- Append(w->code, "}\n");
- Append(w->code, "#if defined(SWIG_PYTHON_DIRECTOR_VTABLE)\n");
- Printf(w->code, "const size_t swig_method_index = %d;\n", director_method_index++);
- Printf(w->code, "const char *const swig_method_name = \"%s\";\n", pyname);
-
- Append(w->code, "PyObject *method = swig_get_method(swig_method_index, swig_method_name);\n");
- if (Len(parse_args) > 0) {
- if (use_parse) {
- Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallFunction(method, (char *)\"(%s)\" %s);\n", Swig_cresult_name(), parse_args, arglist);
- } else {
- Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallFunctionObjArgs(method %s, NULL);\n", Swig_cresult_name(), arglist);
- }
- } else {
- Append(w->code, "swig::SwigVar_PyObject args = PyTuple_New(0);\n");
- Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_Call(method, (PyObject *) args, NULL);\n", Swig_cresult_name());
- }
- Append(w->code, "#else\n");
- if (Len(parse_args) > 0) {
- if (use_parse) {
- Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallMethod(swig_get_self(), (char *)\"%s\", (char *)\"(%s)\" %s);\n", Swig_cresult_name(), pyname, parse_args, arglist);
- } else {
- Printf(w->code, "swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar(\"%s\");\n", pyname);
- Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name %s, NULL);\n", Swig_cresult_name(), arglist);
- }
- } else {
- Printf(w->code, "swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar(\"%s\");\n", pyname);
- Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name, NULL);\n", Swig_cresult_name());
- }
- Append(w->code, "#endif\n");
-
- if (dirprot_mode() && !is_public(n))
- Printf(w->code, "swig_set_inner(\"%s\", false);\n", name);
-
- /* exception handling */
- tm = Swig_typemap_lookup("director:except", n, Swig_cresult_name(), 0);
- if (!tm) {
- tm = Getattr(n, "feature:director:except");
- if (tm)
- tm = Copy(tm);
- }
- Printf(w->code, "if (!%s) {\n", Swig_cresult_name());
- Append(w->code, " PyObject *error = PyErr_Occurred();\n");
- if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
- Replaceall(tm, "$error", "error");
- Printv(w->code, Str(tm), "\n", NIL);
- } else {
- Append(w->code, " if (error) {\n");
- Printf(w->code, " Swig::DirectorMethodException::raise(\"Error detected when calling '%s.%s'\");\n", classname, pyname);
- Append(w->code, " }\n");
- }
- Append(w->code, "}\n");
- Delete(tm);
-
- /*
- * Python method may return a simple object, or a tuple.
- * for in/out arguments, we have to extract the appropriate PyObjects from the tuple,
- * then marshal everything back to C/C++ (return value and output arguments).
- *
- */
-
- /* marshal return value and other outputs (if any) from PyObject to C/C++ type */
-
- String *cleanup = NewString("");
- String *outarg = NewString("");
-
- if (outputs > 1) {
- Wrapper_add_local(w, "output", "PyObject *output");
- Printf(w->code, "if (!PyTuple_Check(%s)) {\n", Swig_cresult_name());
- Printf(w->code, " Swig::DirectorTypeMismatchException::raise(\"Python method %s.%sfailed to return a tuple.\");\n", classname, pyname);
- Append(w->code, "}\n");
- }
-
- idx = 0;
-
- /* marshal return value */
- if (!is_void) {
- tm = Swig_typemap_lookup("directorout", n, Swig_cresult_name(), w);
- if (tm != 0) {
- if (outputs > 1) {
- Printf(w->code, "output = PyTuple_GetItem(%s, %d);\n", Swig_cresult_name(), idx++);
- Replaceall(tm, "$input", "output");
- } else {
- Replaceall(tm, "$input", Swig_cresult_name());
- }
- char temp[24];
- sprintf(temp, "%d", idx);
- Replaceall(tm, "$argnum", temp);
-
- /* TODO check this */
- if (Getattr(n, "wrap:disown")) {
- Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
- } else {
- Replaceall(tm, "$disown", "0");
- }
- if (Getattr(n, "tmap:directorout:implicitconv")) {
- Replaceall(tm, "$implicitconv", get_implicitconv_flag(n));
- }
- Replaceall(tm, "$result", "c_result");
- Printv(w->code, tm, "\n", NIL);
- Delete(tm);
- } else {
- Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
- "Unable to use return type %s in director method %s::%s (skipping method).\n", SwigType_str(returntype, 0), SwigType_namestr(c_classname),
- SwigType_namestr(name));
- status = SWIG_ERROR;
- }
- }
-
- /* marshal outputs */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
- if (outputs > 1) {
- Printf(w->code, "output = PyTuple_GetItem(%s, %d);\n", Swig_cresult_name(), idx++);
- Replaceall(tm, "$result", "output");
- } else {
- Replaceall(tm, "$result", Swig_cresult_name());
- }
- Replaceall(tm, "$input", Getattr(p, "emit:directorinput"));
- Printv(w->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:directorargout:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* any existing helper functions to handle this? */
- if (allow_thread) {
- Append(w->code, "}\n");
- thread_end_block(n, w->code);
- }
-
- Delete(parse_args);
- Delete(arglist);
- Delete(cleanup);
- Delete(outarg);
- }
-
- if (!is_void) {
- if (!(ignored_method && !pure_virtual)) {
- String *rettype = SwigType_str(returntype, 0);
- if (!SwigType_isreference(returntype)) {
- Printf(w->code, "return (%s) c_result;\n", rettype);
- } else {
- Printf(w->code, "return (%s) *c_result;\n", rettype);
- }
- Delete(rettype);
- }
- }
-
- Append(w->code, "}\n");
-
- // We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
- String *inline_extra_method = NewString("");
- if (dirprot_mode() && !is_public(n) && !pure_virtual) {
- Printv(inline_extra_method, declaration, NIL);
- String *extra_method_name = NewStringf("%sSwigPublic", name);
- Replaceall(inline_extra_method, name, extra_method_name);
- Replaceall(inline_extra_method, ";\n", " {\n ");
- if (!is_void)
- Printf(inline_extra_method, "return ");
- String *methodcall = Swig_method_call(super, l);
- Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
- Delete(methodcall);
- Delete(extra_method_name);
- }
-
- /* emit the director method */
- if (status == SWIG_OK) {
- if (!Getattr(n, "defaultargs")) {
- Replaceall(w->code, "$symname", symname);
- Wrapper_print(w, f_directors);
- Printv(f_directors_h, declaration, NIL);
- Printv(f_directors_h, inline_extra_method, NIL);
- }
- }
-
- /* clean up */
- Delete(wrap_args);
- Delete(pclassname);
- DelWrapper(w);
- return status;
-}
-
-/* -----------------------------------------------------------------------------
- * swig_python() - Instantiate module
- * ----------------------------------------------------------------------------- */
-
-static Language *new_swig_python() {
- return new PYTHON();
-}
-extern "C" Language *swig_python(void) {
- return new_swig_python();
-}
diff --git a/contrib/tools/swig/Source/Modules/r.cxx b/contrib/tools/swig/Source/Modules/r.cxx
deleted file mode 100644
index 9b465a5716..0000000000
--- a/contrib/tools/swig/Source/Modules/r.cxx
+++ /dev/null
@@ -1,2889 +0,0 @@
-
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * r.cxx
- *
- * R language module for SWIG.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include "cparse.h"
-
-static String* replaceInitialDash(const String *name)
-{
- String *retval;
- if (!Strncmp(name, "_", 1)) {
- retval = Copy(name);
- Insert(retval, 0, "s");
- } else {
- retval = Copy(name);
- }
- return retval;
-}
-
-static String * getRTypeName(SwigType *t, int *outCount = NULL) {
- String *b = SwigType_base(t);
- List *els = SwigType_split(t);
- int count = 0;
- int i;
-
- if(Strncmp(b, "struct ", 7) == 0)
- Replace(b, "struct ", "", DOH_REPLACE_FIRST);
-
- for(i = 0; i < Len(els); i++) {
- String *el = Getitem(els, i);
- if(Strcmp(el, "p.") == 0 || Strncmp(el, "a(", 2) == 0) {
- count++;
- Append(b, "Ref");
- }
- }
- if(outCount)
- *outCount = count;
-
- String *tmp = NewString("");
- char *retName = Char(SwigType_manglestr(t));
- Insert(tmp, 0, retName);
- return tmp;
-
-}
-
-/* --------------------------------------------------------------
- * Tries to get the resolved name, with options of adding
- * or removing a layer of references. Take care not
- * to request both
- * --------------------------------------------------------------*/
-
-static String *getRClassName(String *retType, int deRef=0, int upRef=0) {
- SwigType *resolved = SwigType_typedef_resolve_all(retType);
- int ispointer = SwigType_ispointer(resolved);
- int isreference = SwigType_isreference(resolved);
- if (upRef) {
- SwigType_add_pointer(resolved);
- }
- if (deRef) {
- if (ispointer) {
- SwigType_del_pointer(resolved);
- }
- if (isreference) {
- SwigType_del_reference(resolved);
- }
- }
- String *tmp = NewString("");
- Insert(tmp, 0, Char(SwigType_manglestr(resolved)));
- return(tmp);
-}
-
-/* --------------------------------------------------------------
- * Tries to get the name of the R class corresponding to the given type
- * e.g. struct A * is ARef, struct A** is ARefRef.
- * Now handles arrays, i.e. struct A[2]
- * --------------------------------------------------------------*/
-
-
-static String * getRClassNameCopyStruct(String *retType, int addRef) {
- String *tmp = NewString("");
-
- List *l = SwigType_split(retType);
- int n = Len(l);
- if(!l || n == 0) {
-#ifdef R_SWIG_VERBOSE
- Printf(stdout, "SwigType_split return an empty list for %s\n", retType);
-#endif
- return(tmp);
- }
-
-
- String *el = Getitem(l, n-1);
- char *ptr = Char(el);
- if(strncmp(ptr, "struct ", 7) == 0)
- ptr += 7;
-
- Printf(tmp, "%s", ptr);
-
- if(addRef) {
- for(int i = 0; i < n; i++) {
- if(Strcmp(Getitem(l, i), "p.") == 0 ||
- Strncmp(Getitem(l, i), "a(", 2) == 0)
- Printf(tmp, "Ref");
- }
- }
-
- return tmp;
-}
-
-
-/* -------------------------------------------------------------
- * Write the elements of a list to the File*, one element per line.
- * If quote is true, surround the element with "element".
- * This takes care of inserting a tab in front of each line and also
- * a comma after each element, except the last one.
- * --------------------------------------------------------------*/
-
-
-static void writeListByLine(List *l, File *out, bool quote = 0) {
- int i, n = Len(l);
- for(i = 0; i < n; i++)
- Printf(out, "%s%s%s%s%s\n", tab8,
- quote ? "\"" :"",
- Getitem(l, i),
- quote ? "\"" :"", i < n-1 ? "," : "");
-}
-
-
-static const char *usage = "\
-R Options (available with -r)\n\
- -copystruct - Emit R code to copy C structs (on by default)\n\
- -debug - Output debug\n\
- -dll <name> - Name of the DLL (without the .dll or .so suffix).\n\
- Default is the module name.\n\
- -gc - Aggressive garbage collection\n\
- -memoryprof - Add memory profile\n\
- -namespace - Output NAMESPACE file\n\
- -no-init-code - Turn off the generation of the R_init_<pkgname> code\n\
- (registration information still generated)\n\
- -package <name> - Package name for the PACKAGE argument of the R .Call()\n\
- invocations. Default is the module name.\n\
-";
-
-
-
-/* -------------------------------------------------------------
- * Display the help for this module on the screen/console.
- * --------------------------------------------------------------*/
-
-static void showUsage() {
- fputs(usage, stdout);
-}
-
-static bool expandTypedef(SwigType *t) {
- if (SwigType_isenum(t)) return false;
- String *prefix = SwigType_prefix(t);
- if (Strncmp(prefix, "f", 1)) return false;
- if (Strncmp(prefix, "p.f", 3)) return false;
- return true;
-}
-
-
-/* -------------------------------------------------------------
- * Determine whether we should add a .copy argument to the S function
- * that wraps/interfaces to the routine that returns the given type.
- * --------------------------------------------------------------*/
-
-static int addCopyParameter(SwigType *type) {
- int ok = 0;
- ok = Strncmp(type, "struct ", 7) == 0 || Strncmp(type, "p.struct ", 9) == 0;
- if(!ok) {
- ok = Strncmp(type, "p.", 2);
- }
-
- return(ok);
-}
-
-static void replaceRClass(String *tm, SwigType *type) {
- String *tmp = getRClassName(type, 0, 0);
- String *tmp_base = getRClassName(type, 1, 0);
- String *tmp_ref = getRClassName(type, 0, 1);
- Replaceall(tm, "$R_class", tmp);
- Replaceall(tm, "$*R_class", tmp_base);
- Replaceall(tm, "$&R_class", tmp_ref);
- Delete(tmp); Delete(tmp_base); Delete(tmp_ref);
-}
-
-class R : public Language {
-public:
- R();
- void registerClass(Node *n);
- void main(int argc, char *argv[]);
- int top(Node *n);
-
- void dispatchFunction(Node *n);
- int functionWrapper(Node *n);
- int constantWrapper(Node *n);
- int variableWrapper(Node *n);
-
- int classDeclaration(Node *n);
- int enumDeclaration(Node *n);
- String *enumValue(Node *n);
- virtual int enumvalueDeclaration(Node *n);
- int membervariableHandler(Node *n);
-
- int typedefHandler(Node *n);
-
- static List *Swig_overload_rank(Node *n, bool script_lang_wrapping);
-
- int memberfunctionHandler(Node *n) {
- if (debugMode)
- Printf(stdout, "<memberfunctionHandler> %s %s\n",
- Getattr(n, "name"),
- Getattr(n, "type"));
- member_name = Getattr(n, "sym:name");
- processing_class_member_function = 1;
- int status = Language::memberfunctionHandler(n);
- processing_class_member_function = 0;
- return status;
- }
-
- /* Grab the name of the current class being processed so that we can
- deal with members of that class. */
- int classHandler(Node *n){
- if(!ClassMemberTable)
- ClassMemberTable = NewHash();
-
- class_name = Getattr(n, "name");
- int status = Language::classHandler(n);
-
- class_name = NULL;
- return status;
- }
-
- String *runtimeCode();
- void replaceSpecialVariables(String *method, String *tm, Parm *parm);
-
-protected:
- int addRegistrationRoutine(String *rname, int nargs);
- int outputRegistrationRoutines(File *out);
-
- int outputCommandLineArguments(File *out);
- int generateCopyRoutines(Node *n);
- int DumpCode(Node *n);
-
- int OutputMemberReferenceMethod(String *className, int isSet, List *memberList, List *nameList, List *typeList, File *out);
- int defineArrayAccessors(SwigType *type);
-
- void addNamespaceFunction(String *name) {
- if(!namespaceFunctions)
- namespaceFunctions = NewList();
- Append(namespaceFunctions, name);
- }
-
- void addNamespaceMethod(String *name) {
- if(!namespaceMethods)
- namespaceMethods = NewList();
- Append(namespaceMethods, name);
- }
-
- String* processType(SwigType *t, Node *n, int *nargs = NULL);
- String *createFunctionPointerHandler(SwigType *t, Node *n, int *nargs);
- int addFunctionPointerProxy(String *name, Node *n, SwigType *t, String *s_paramTypes) {
- /*XXX Do we need to put the t in there to get the return type later. */
- if(!functionPointerProxyTable)
- functionPointerProxyTable = NewHash();
-
- Setattr(functionPointerProxyTable, name, n);
-
- Setattr(SClassDefs, name, name);
- Printv(s_classes, "setClass('",
- name,
- "',\n", tab8,
- "prototype = list(parameterTypes = c(", s_paramTypes, "),\n",
- tab8, tab8, tab8,
- "returnType = '", SwigType_manglestr(t), "'),\n", tab8,
- "contains = 'CRoutinePointer')\n\n##\n", NIL);
-
- return SWIG_OK;
- }
-
-
- void addSMethodInfo(String *name,
- String *argType, int nargs);
- // Simple initialization such as constant strings that can be reused.
- void init();
-
-
- void addAccessor(String *memberName, Wrapper *f,
- String *name, String *methodSetGet);
-
- static int getFunctionPointerNumArgs(Node *n, SwigType *tt);
-
- // filtering of class member lists by function type. Used in constructing accessors
- // are we allowed to use stl style functors to customise this?
- List* filterMemberList(List *class_member_function_types, List *class_member_other, String *R_MEMBER, bool equal);
-
-protected:
- bool copyStruct;
- bool memoryProfile;
- bool aggressiveGc;
-
- // Strings into which we cumulate the generated code that is to be written
- //vto the files.
- String *enum_values;
- String *enum_def_calls;
- String *sfile;
- String *f_init;
- String *s_classes;
- String *f_begin;
- String *f_runtime;
- String *f_wrapper;
- String *s_header;
- String *f_wrappers;
- String *s_init;
- String *s_init_routine;
- String *s_namespace;
-
- // State variables that carry information across calls to functionWrapper()
- // from member accessors and class declarations.
- String *opaqueClassDeclaration;
- int processing_variable;
- int processing_member_access_function;
- String *member_name;
- String *class_name;
-
- String *R_MEMBER_NORMAL;
- String *R_MEMBER_SET;
- String *R_MEMBER_GET;
-
- int processing_class_member_function;
- // Spread out the lists so that they are simpler to process
- // by storing the type of the method (i.e. set, get or nothing)
- // and having separate lists for name, membername and wrapper
- List *class_member_function_types;
- List *class_member_function_names;
- List *class_member_function_membernames;
- List *class_member_function_wrappernames;
- /* */
- Hash *ClassMemberTable;
- Hash *ClassMethodsTable;
- Hash *SClassDefs;
- Hash *SMethodInfo;
-
- // Information about routines that are generated and to be registered with
- // R for dynamic lookup.
- Hash *registrationTable;
- Hash *functionPointerProxyTable;
-
- List *namespaceFunctions;
- List *namespaceMethods;
- List *namespaceClasses; // Probably can do this from ClassMemberTable.
-
-
- // Store a copy of the command line.
- // Need only keep a string that has it formatted.
- char **Argv;
- int Argc;
- bool inCPlusMode;
-
- // State variables that we remember from the command line settings
- // potentially that govern the code we generate.
- String *DllName;
- String *Rpackage;
- bool noInitializationCode;
- bool outputNamespaceInfo;
-
- String *UnProtectWrapupCode;
-
- // Static members
- static bool debugMode;
-};
-
-R::R() :
- copyStruct(false),
- memoryProfile(false),
- aggressiveGc(false),
- enum_values(0),
- enum_def_calls(0),
- sfile(0),
- f_init(0),
- s_classes(0),
- f_begin(0),
- f_runtime(0),
- f_wrapper(0),
- s_header(0),
- f_wrappers(0),
- s_init(0),
- s_init_routine(0),
- s_namespace(0),
- opaqueClassDeclaration(0),
- processing_variable(0),
- processing_member_access_function(0),
- member_name(0),
- class_name(0),
- R_MEMBER_NORMAL(NewString("normal")),
- R_MEMBER_SET(NewString("set")),
- R_MEMBER_GET(NewString("get")),
- processing_class_member_function(0),
- class_member_function_types(0),
- class_member_function_names(0),
- class_member_function_membernames(0),
- class_member_function_wrappernames(0),
- ClassMemberTable(0),
- ClassMethodsTable(0),
- SClassDefs(0),
- SMethodInfo(0),
- registrationTable(0),
- functionPointerProxyTable(0),
- namespaceFunctions(0),
- namespaceMethods(0),
- namespaceClasses(0),
- Argv(0),
- Argc(0),
- inCPlusMode(false),
- DllName(0),
- Rpackage(0),
- noInitializationCode(false),
- outputNamespaceInfo(false),
- UnProtectWrapupCode(0) {
-}
-
-bool R::debugMode = false;
-
-int R::getFunctionPointerNumArgs(Node *n, SwigType *tt) {
- (void) tt;
- n = Getattr(n, "type");
- if (debugMode)
- Printf(stdout, "type: %s\n", n);
-
- ParmList *parms = Getattr(n, "parms");
- if (debugMode)
- Printf(stdout, "parms = %p\n", parms);
- return ParmList_len(parms);
-}
-
-
-void R::addSMethodInfo(String *name, String *argType, int nargs) {
- (void) argType;
-
- if(!SMethodInfo)
- SMethodInfo = NewHash();
- if (debugMode)
- Printf(stdout, "[addMethodInfo] %s\n", name);
-
- Hash *tb = Getattr(SMethodInfo, name);
-
- if(!tb) {
- tb = NewHash();
- Setattr(SMethodInfo, name, tb);
- }
-
- String *str = Getattr(tb, "max");
- int max = -1;
- if(str)
- max = atoi(Char(str));
- if(max < nargs) {
- if(str) Delete(str);
- str = NewStringf("%d", max);
- Setattr(tb, "max", str);
- }
-}
-
-/* ----------------------------------------
- * Returns the name of the new routine.
- * ------------------------------------------ */
-
-String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) {
- String *funName = SwigType_manglestr(t);
-
- /* See if we have already processed this one. */
- if(functionPointerProxyTable && Getattr(functionPointerProxyTable, funName))
- return funName;
-
- if (debugMode)
- Printf(stdout, "<createFunctionPointerHandler> Defining %s\n", t);
-
- SwigType *rettype = Copy(Getattr(n, "type"));
- SwigType *funcparams = SwigType_functionpointer_decompose(rettype);
- String *rtype = SwigType_str(rettype, 0);
-
- // ParmList *parms = Getattr(n, "parms");
- // memory leak
- ParmList *parms = SwigType_function_parms(SwigType_del_pointer(Copy(t)), n);
-
-
- if (debugMode) {
- Printf(stdout, "Type: %s\n", t);
- Printf(stdout, "Return type: %s\n", SwigType_base(t));
- }
-
- bool isVoidType = Strcmp(rettype, "void") == 0;
- if (debugMode)
- Printf(stdout, "%s is void ? %s (%s)\n", funName, isVoidType ? "yes" : "no", rettype);
-
- Wrapper *f = NewWrapper();
-
- /* Go through argument list, attach lnames for arguments */
- int i = 0;
- Parm *p = parms;
- for (i = 0; p; p = nextSibling(p), ++i) {
- String *arg = Getattr(p, "name");
- String *lname;
- if (!arg && Cmp(Getattr(p, "type"), "void")) {
- lname = NewStringf("arg%d", i+1);
- Setattr(p, "name", lname);
- } else
- lname = arg;
-
- Setattr(p, "lname", lname);
- }
-
- Swig_typemap_attach_parms("out", parms, f);
- Swig_typemap_attach_parms("scoerceout", parms, f);
- Swig_typemap_attach_parms("scheck", parms, f);
-
- Printf(f->def, "%s %s(", rtype, funName);
-
- emit_parameter_variables(parms, f);
- emit_return_variable(n, rettype, f);
- // emit_attach_parmmaps(parms,f);
-
- /* Using weird name and struct to avoid potential conflicts. */
- Wrapper_add_local(f, "r_swig_cb_data", "RCallbackFunctionData *r_swig_cb_data = R_SWIG_getCallbackFunctionData()");
- String *lvar = NewString("r_swig_cb_data");
-
- Wrapper_add_local(f, "r_tmp", "SEXP r_tmp"); // for use in converting arguments to R objects for call.
- Wrapper_add_local(f, "r_nprotect", "int r_nprotect = 0"); // for use in converting arguments to R objects for call.
- Wrapper_add_local(f, "r_vmax", "char * r_vmax= 0"); // for use in converting arguments to R objects for call.
-
- // Add local for error code in return value. This is not in emit_return_variable because that assumes an out typemap
- // whereas the type makes are reverse
- Wrapper_add_local(f, "ecode", "int ecode = 0");
-
- p = parms;
- int nargs = ParmList_len(parms);
- if(numArgs) {
- *numArgs = nargs;
- if (debugMode)
- Printf(stdout, "Setting number of parameters to %d\n", *numArgs);
- }
- String *setExprElements = NewString("");
-
- String *s_paramTypes = NewString("");
- for(i = 0; p; i++) {
- SwigType *tt = Getattr(p, "type");
- SwigType *name = Getattr(p, "name");
- SwigType *swig_parm_name = NewStringf("swigarg_%s", name);
- String *tm = Getattr(p, "tmap:out");
- bool isVoidParm = Strcmp(tt, "void") == 0;
- if (isVoidParm)
- Printf(f->def, "%s", SwigType_str(tt, 0));
- else
- Printf(f->def, "%s %s", SwigType_str(tt, 0), swig_parm_name);
- if (tm) {
- String *lstr = SwigType_lstr(tt, 0);
- if (SwigType_isreference(tt) || SwigType_isrvalue_reference(tt)) {
- Printf(f->code, "%s = (%s) &%s;\n", Getattr(p, "lname"), lstr, swig_parm_name);
- } else if (!isVoidParm) {
- Printf(f->code, "%s = (%s) %s;\n", Getattr(p, "lname"), lstr, swig_parm_name);
- }
- Replaceall(tm, "$1", name);
- Replaceall(tm, "$result", "r_tmp");
- if (debugMode) {
- Printf(stdout, "Calling Replace A: %s\n", Getattr(p,"type"));
- }
- replaceRClass(tm, Getattr(p,"type"));
- Replaceall(tm,"$owner", "0");
- Delete(lstr);
- }
-
- Printf(setExprElements, "%s\n", tm);
- Printf(setExprElements, "SETCAR(r_swig_cb_data->el, %s);\n", "r_tmp");
- Printf(setExprElements, "r_swig_cb_data->el = CDR(r_swig_cb_data->el);\n\n");
-
- Printf(s_paramTypes, "'%s'", SwigType_manglestr(tt));
-
-
- p = nextSibling(p);
- if(p) {
- Printf(f->def, ", ");
- Printf(s_paramTypes, ", ");
- }
- }
-
- Printf(f->def, ") {\n");
-
- Printf(f->code, "Rf_protect(%s->expr = Rf_allocVector(LANGSXP, %d));\n", lvar, nargs + 1);
- Printf(f->code, "r_nprotect++;\n");
- Printf(f->code, "r_swig_cb_data->el = r_swig_cb_data->expr;\n\n");
-
- Printf(f->code, "SETCAR(r_swig_cb_data->el, r_swig_cb_data->fun);\n");
- Printf(f->code, "r_swig_cb_data->el = CDR(r_swig_cb_data->el);\n\n");
-
- Printf(f->code, "%s\n\n", setExprElements);
-
- Printv(f->code, "r_swig_cb_data->retValue = R_tryEval(",
- "r_swig_cb_data->expr,",
- " R_GlobalEnv,",
- " &r_swig_cb_data->errorOccurred",
- ");\n",
- NIL);
-
- Printv(f->code, "\n",
- "if(r_swig_cb_data->errorOccurred) {\n",
- "R_SWIG_popCallbackFunctionData(1);\n",
- "Rf_error(\"error in calling R function as a function pointer (",
- funName,
- ")\");\n",
- "}\n",
- NIL);
-
-
-
- if(!isVoidType) {
- /* Need to deal with the return type of the function pointer, not the function pointer itself.
- So build a new node that has the relevant pieces.
- XXX Have to be a little more clever so that we can deal with struct A * - the * is getting lost.
- Is this still true? If so, will a SwigType_push() solve things?
- */
- Parm *bbase = NewParmNode(rettype, n);
- String *returnTM = Swig_typemap_lookup("in", bbase, Swig_cresult_name(), f);
- if(returnTM) {
- String *tm = returnTM;
- Replaceall(tm,"$input", "r_swig_cb_data->retValue");
- replaceRClass(tm, rettype);
- Replaceall(tm,"$owner", "0");
- Replaceall(tm,"$disown","0");
- Printf(f->code, "%s\n", tm);
- }
- Delete(bbase);
- }
-
- Printv(f->code, "R_SWIG_popCallbackFunctionData(1);\n", NIL);
- Printv(f->code, "\n", UnProtectWrapupCode, NIL);
-
- if (SwigType_isreference(rettype)) {
- Printv(f->code, "return *", Swig_cresult_name(), ";\n", NIL);
- } else if (SwigType_isrvalue_reference(rettype)) {
- Printv(f->code, "return std::move(*", Swig_cresult_name(), ");\n", NIL);
- } else if (!isVoidType) {
- Printv(f->code, "return ", Swig_cresult_name(), ";\n", NIL);
- }
-
- Printv(f->code, "\n}\n", NIL);
- Replaceall(f->code, "SWIG_exception_fail", "SWIG_exception_noreturn");
-
- /* To coerce correctly in S, we really want to have an extra/intermediate
- function that handles the scoerceout.
- We need to check if any of the argument types have an entry in
- that map. If none do, the ignore and call the function straight.
- Otherwise, generate a marshalling function.
- Need to be able to find it in S. Or use an entirely generic one
- that evaluates the expressions.
- Handle errors in the evaluation of the function by restoring
- the stack, if there is one in use for this function (i.e. no
- userData).
- */
-
- Wrapper_print(f, f_wrapper);
-
- addFunctionPointerProxy(funName, n, t, s_paramTypes);
- Delete(s_paramTypes);
- Delete(rtype);
- Delete(rettype);
- Delete(funcparams);
- DelWrapper(f);
-
- return funName;
-}
-
-void R::init() {
- UnProtectWrapupCode =
- NewStringf("%s", "vmaxset(r_vmax);\nif(r_nprotect) Rf_unprotect(r_nprotect);\n\n");
-
- SClassDefs = NewHash();
-
- sfile = NewString("");
- f_init = NewString("");
- s_header = NewString("");
- f_begin = NewString("");
- f_runtime = NewString("");
- f_wrapper = NewString("");
- s_classes = NewString("");
- s_init = NewString("");
- s_init_routine = NewString("");
- enum_def_calls = NewString("");
-}
-
-
-/* -------------------------------------------------------------
- * Method from Language that is called to start the entire
- * processing off, i.e. the generation of the code.
- * It is called after the input has been read and parsed.
- * Here we open the output streams and generate the code.
- * ------------------------------------------------------------- */
-int R::top(Node *n) {
- String *module = Getattr(n, "name");
-
- if (debugMode) {
- Printf(stdout, "<Top> %s\n", module);
- }
-
- if(!Rpackage)
- Rpackage = Copy(module);
- if(!DllName)
- DllName = Copy(module);
-
- if(outputNamespaceInfo) {
- s_namespace = NewString("");
- Swig_register_filebyname("snamespace", s_namespace);
- Printf(s_namespace, "useDynLib(%s)\n", DllName);
- }
- // Register the naming functions
- Swig_name_register("wrapper", "R_swig_%f");
-
- /* Associate the different streams with names so that they can be used in %insert directives by the
- typemap code. */
- Swig_register_filebyname("sinit", s_init);
- Swig_register_filebyname("sinitroutine", s_init_routine);
-
- Swig_register_filebyname("begin", f_begin);
- Swig_register_filebyname("runtime", f_runtime);
- Swig_register_filebyname("init", f_init);
- Swig_register_filebyname("header", s_header);
- Swig_register_filebyname("wrapper", f_wrapper);
- Swig_register_filebyname("s", sfile);
- Swig_register_filebyname("sclasses", s_classes);
-
- Swig_banner(f_begin);
-
- Swig_obligatory_macros(f_runtime, "R");
-
- Swig_banner_target_lang(s_init, "#");
- outputCommandLineArguments(s_init);
-
- Printf(f_wrapper, "#ifdef __cplusplus\n");
- Printf(f_wrapper, "extern \"C\" {\n");
- Printf(f_wrapper, "#endif\n\n");
-
- Language::top(n);
-
- Printf(f_wrapper, "#ifdef __cplusplus\n");
- Printf(f_wrapper, "}\n");
- Printf(f_wrapper, "#endif\n");
-
- String *type_table = NewString("");
- SwigType_emit_type_table(f_runtime,f_wrapper);
- Delete(type_table);
-
- if(ClassMemberTable) {
- //XXX OutputClassAccessInfo(ClassMemberTable, sfile);
- Delete(ClassMemberTable);
- ClassMemberTable = NULL;
- }
-
- Printf(f_init,"}\n");
- if(registrationTable)
- outputRegistrationRoutines(f_init);
-
- /* Now arrange to write the 2 files - .S and .c. */
-
- DumpCode(n);
-
- Delete(sfile);
- Delete(s_classes);
- Delete(s_init);
- Delete(f_wrapper);
- Delete(f_init);
-
- Delete(s_header);
- Delete(f_runtime);
- Delete(f_begin);
-
- return SWIG_OK;
-}
-
-
-/* -------------------------------------------------------------
- * Write the generated code to the .S and the .c files.
- * ------------------------------------------------------------- */
-int R::DumpCode(Node *n) {
- String *output_filename = NewString("");
-
-
- /* The name of the file in which we will generate the S code. */
- Printf(output_filename, "%s%s.R", SWIG_output_directory(), Rpackage);
-
-#ifdef R_SWIG_VERBOSE
- Printf(stdout, "Writing S code to %s\n", output_filename);
-#endif
-
- File *scode = NewFile(output_filename, "w", SWIG_output_files());
- if (!scode) {
- FileErrorDisplay(output_filename);
- Exit(EXIT_FAILURE);
- }
- Delete(output_filename);
-
-
- Printf(scode, "%s\n\n", s_init);
- Printf(scode, "%s\n\n", s_classes);
- Printf(scode, "%s\n", sfile);
- Printf(scode, "%s\n", enum_def_calls);
-
- Delete(scode);
- String *outfile = Getattr(n,"outfile");
- File *runtime = NewFile(outfile,"w", SWIG_output_files());
- if (!runtime) {
- FileErrorDisplay(outfile);
- Exit(EXIT_FAILURE);
- }
-
- Printf(runtime, "%s", f_begin);
- Printf(runtime, "%s\n", f_runtime);
- Printf(runtime, "%s\n", s_header);
- Printf(runtime, "%s\n", f_wrapper);
- Printf(runtime, "%s\n", f_init);
-
- Delete(runtime);
-
- if(outputNamespaceInfo) {
- output_filename = NewString("");
- Printf(output_filename, "%sNAMESPACE", SWIG_output_directory());
- File *ns = NewFile(output_filename, "w", SWIG_output_files());
- if (!ns) {
- FileErrorDisplay(output_filename);
- Exit(EXIT_FAILURE);
- }
- Delete(output_filename);
-
- Printf(ns, "%s\n", s_namespace);
-
- Printf(ns, "\nexport(\n");
- writeListByLine(namespaceFunctions, ns);
- Printf(ns, ")\n");
- Printf(ns, "\nexportMethods(\n");
- writeListByLine(namespaceMethods, ns, 1);
- Printf(ns, ")\n");
- Delete(ns);
- Delete(s_namespace);
- }
-
- return SWIG_OK;
-}
-
-
-List *R::filterMemberList(List *class_member_types,
- List *class_member_other,
- String *R_MEMBER, bool equal) {
- // filters class_member_other based on whether corresponding elements of
- // class_member_function_types are equal or notequal to R_MEMBER
- List *CM = NewList();
- Iterator ftype, other;
-
- for (ftype = First(class_member_types), other = First(class_member_other);
- ftype.item;
- ftype=Next(ftype), other=Next(other)) {
- // verbose, clean up later if the overall structure works
- if (equal) {
- if (ftype.item == R_MEMBER) {
- Append(CM, other.item);
- }
- } else {
- if (ftype.item != R_MEMBER) {
- Append(CM, other.item);
- }
- }
- }
- return(CM);
-}
-
-# if 0
-// not called
-/* -------------------------------------------------------------
- * We may need to do more.... so this is left as a
- * stub for the moment.
- * -------------------------------------------------------------*/
-int R::OutputClassAccessInfo(Hash *tb, File *out) {
- int n = OutputClassMemberTable(tb, out);
- OutputClassMethodsTable(out);
- return n;
-}
-
-/* -------------------------------------------------------------
- * Currently this just writes the information collected about the
- * different methods of the C++ classes that have been processed
- * to the console.
- * This will be used later to define S4 generics and methods.
- * --------------------------------------------------------------*/
-
-int R::OutputClassMethodsTable(File *) {
- Hash *tb = ClassMethodsTable;
-
- if(!tb)
- return SWIG_OK;
-
- List *keys = Keys(tb);
- String *key;
- int i, n = Len(keys);
- if (debugMode) {
- for(i = 0; i < n ; i++ ) {
- key = Getitem(keys, i);
- Printf(stdout, "%d) %s\n", i, key);
- List *els = Getattr(tb, key);
- int nels = Len(els);
- Printf(stdout, "\t");
- for(int j = 0; j < nels; j+=2) {
- Printf(stdout, "%s%s", Getitem(els, j), j < nels - 1 ? ", " : "");
- Printf(stdout, "%s\n", Getitem(els, j+1));
- }
- Printf(stdout, "\n");
- }
- }
-
- return SWIG_OK;
-}
-
-
-/* --------------------------------------------------------------
- * Iterate over the <class name>_set and <>_get
- * elements and generate the $ and $<- functions
- * that provide constrained access to the member
- * fields in these elements.
-
- * tb - a hash table that is built up in functionWrapper
- * as we process each membervalueHandler.
- * The entries are indexed by <class name>_set and
- * <class_name>_get. Each entry is a List *.
-
- * out - the stream where the code is to be written. This is the S
- * code stream as we generate only S code here.
- * --------------------------------------------------------------*/
-
-int R::OutputClassMemberTable(Hash *tb, File *out) {
- List *keys = Keys(tb), *el;
-
- String *key;
- int i, n = Len(keys);
- /* Loop over all the <Class>_set and <Class>_get entries in the table. */
- /* This function checks for names ending in _set - perhaps it should */
- /* use attributes of some other form, as it potentially clashes with */
- /* methods ending in _set */
-
- if(n && outputNamespaceInfo) {
- Printf(s_namespace, "exportClasses(");
- }
- for(i = 0; i < n; i++) {
- key = Getitem(keys, i);
- el = Getattr(tb, key);
-
- String *className = Getitem(el, 0);
- char *ptr = Char(key);
- int klen = Len(key);
- int isSet = 0;
- if (klen > 4) {
- ptr = &ptr[klen - 4];
- isSet = strcmp(ptr, "_set") == 0;
- }
-
- if(outputNamespaceInfo)
- Printf(s_namespace, "\"%s\"%s", className, i < n-1 ? "," : "");
- }
- if(n && outputNamespaceInfo) {
- Printf(s_namespace, ")\n");
- }
-
- return n;
-}
-
-// end not used
-#endif
-/* --------------------------------------------------------------
- * Write the methods for $ or $<- for accessing a member field in an
- * struct or union (or class).
- * className - the name of the struct or union (e.g. Bar for struct Bar)
- * isSet - a logical value indicating whether the method is for
- * modifying ($<-) or accessing ($) the member field.
- * el - a list of length 2 * # accessible member elements + 1.
- * The first element is the name of the class.
- * The other pairs are member name and the name of the R function to access it.
- * out - the stream where we write the code.
- * --------------------------------------------------------------*/
-
-int R::OutputMemberReferenceMethod(String *className, int isSet,
- List *memberList, List *nameList,
- List *typeList, File *out) {
- int numMems = Len(memberList), j;
- int varaccessor = 0;
- if (numMems == 0)
- return SWIG_OK;
-
- Wrapper *f = NewWrapper(), *attr = NewWrapper();
-
- Printf(f->def, "function(x, name%s)", isSet ? ", value" : "");
- Printf(attr->def, "function(x, i, j, ...%s)", isSet ? ", value" : "");
-
- Printf(f->code, "{\n");
- Printf(f->code, "%saccessorFuns = list(", tab8);
-
- Node *itemList = NewHash();
- bool has_prev = false;
- for(j = 0; j < numMems; j++) {
- String *item = Getitem(memberList, j);
- String *dup = Getitem(nameList, j);
- String *setgetmethod = Getitem(typeList, j);
-
- if (setgetmethod == R_MEMBER_GET)
- varaccessor++;
-
- if (Getattr(itemList, item))
- continue;
- Setattr(itemList, item, "1");
-
- String *pitem;
- if (!Strcmp(item, "operator ()")) {
- pitem = NewString("call");
- } else if (!Strcmp(item, "operator ->")) {
- pitem = NewString("deref");
- } else if (!Strcmp(item, "operator +")) {
- pitem = NewString("add");
- } else if (!Strcmp(item, "operator -")) {
- pitem = NewString("sub");
- } else {
- pitem = Copy(item);
- }
- if (has_prev)
- Printf(f->code, ", ");
- Printf(f->code, "'%s' = %s", pitem, dup);
- has_prev = true;
- Delete(pitem);
- }
- Delete(itemList);
- Printf(f->code, ");\n");
-
- if (!isSet && varaccessor > 0) {
- Printf(f->code, "%svaccessors = c(", tab8);
- bool first = true;
- for(j = 0; j < numMems; j++) {
- String *item = Getitem(memberList, j);
- String *setgetmethod = Getitem(typeList, j);
-
- // Check the type here instead of the name
- if (setgetmethod == R_MEMBER_GET) {
- Printf(f->code, "%s'%s'", first ? "" : ", ", item);
- first = false;
- }
- }
- Printf(f->code, ");\n");
- }
-
- Printv(f->code, ";", tab8,
- "idx = pmatch(name, names(accessorFuns));\n",
- tab8,
- "if(is.na(idx)) \n",
- tab8, tab4, NIL);
- Printf(f->code, "return(callNextMethod(x, name%s));\n",
- isSet ? ", value" : "");
- Printv(f->code, tab8, "f = accessorFuns[[idx]];\n", NIL);
- if(isSet) {
- Printv(f->code, tab8, "f(x, value);\n", NIL);
- Printv(f->code, tab8, "x;\n", NIL); // make certain to return the S value.
- } else {
- if (varaccessor) {
- Printv(f->code, tab8,
- "if (is.na(match(name, vaccessors))) function(...){f(x, ...)} else f(x);\n", NIL);
- } else {
- Printv(f->code, tab8, "function(...){f(x, ...)};\n", NIL);
- }
- }
- Printf(f->code, "}\n");
-
- String *classname_str = SwigType_namestr(className);
- Printf(out, "# Start of accessor method for %s\n", classname_str);
- Printf(out, "setMethod('$%s', '_p%s', ",
- isSet ? "<-" : "",
- getRClassName(className));
- Wrapper_print(f, out);
- Printf(out, ");\n");
-
- if(isSet) {
- Printf(out, "setMethod('[[<-', c('_p%s', 'character'),",
- getRClassName(className));
- Insert(f->code, 2, "name = i;\n");
- Printf(attr->code, "%s", f->code);
- Wrapper_print(attr, out);
- Printf(out, ");\n");
- }
-
- Printf(out, "# end of accessor method for %s\n", classname_str);
-
- Delete(classname_str);
- DelWrapper(attr);
- DelWrapper(f);
-
- return SWIG_OK;
-}
-
-/* -------------------------------------------------------------
- * Called when a enumeration is to be processed.
- * We want to call the R function defineEnumeration().
- * tdname is the typedef of the enumeration, i.e. giving its name.
- * --------------------------------------------------------------*/
-
-int R::enumDeclaration(Node *n) {
- if (!ImportMode) {
- if (getCurrentClass() && (cplus_mode != PUBLIC))
- return SWIG_NOWRAP;
-
- String *symname = Getattr(n, "sym:name");
-
- // TODO - deal with anonymous enumerations
- // Previous enum code for R didn't wrap them
- if (!symname || Getattr(n, "unnamedinstance"))
- return SWIG_NOWRAP;
-
- // create mangled name for the enum
- // This will have content if the %nspace feature is set on
- // the input file
- String *nspace = Getattr(n, "sym:nspace"); // NSpace/getNSpace() only works during Language::enumDeclaration call
- String *ename;
-
- String *name = Getattr(n, "name");
- ename = getRClassName(name);
- if (debugMode) {
- Node *current_class = getCurrentClass();
- String *cl = NewString("");
- if (current_class) {
- cl = getEnumClassPrefix();
- }
- Printf(stdout, "enumDeclaration: %s, %s, %s, %s, %s\n", name, symname, nspace, ename, cl);
- }
- Delete(name);
- // set up a call to create the R enum structure. The list of
- // individual elements will be built in enum_code
- enum_values = 0;
- // Emit each enum item
- Language::enumDeclaration(n);
-
- Printf(enum_def_calls, "defineEnumeration(\"%s\",\n .values=c(%s))\n\n", ename, enum_values);
- Delete(enum_values);
- Delete(ename);
- }
- return SWIG_OK;
-}
-
-/* -------------------------------------------------------------
-* --------------------------------------------------------------*/
-
-int R::enumvalueDeclaration(Node *n) {
- if (getCurrentClass() && (cplus_mode != PUBLIC)) {
- Printf(stdout, "evd: Not public\n");
- return SWIG_NOWRAP;
- }
-
- Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL);
- String *symname = Getattr(n, "sym:name");
- String *value = Getattr(n, "value");
- String *name = Getattr(n, "name");
- Node *parent = parentNode(n);
- String *parent_name = Getattr(parent, "name");
- String *newsymname = 0;
- String *tmpValue;
-
- // Strange hack from parent method
- if (value)
- tmpValue = NewString(value);
- else
- tmpValue = NewString(name);
- // Note that this is used in enumValue() amongst other places
- Setattr(n, "value", tmpValue);
-
- // Deal with enum values that are not int
- int swigtype = SwigType_type(Getattr(n, "type"));
- if (swigtype == T_BOOL) {
- const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0";
- Setattr(n, "enumvalue", val);
- } else if (swigtype == T_CHAR) {
- String *val = NewStringf("'%s'", Getattr(n, "enumvalue"));
- Setattr(n, "enumvalue", val);
- Delete(val);
- }
-
- if (GetFlag(parent, "scopedenum")) {
- newsymname = Swig_name_member(0, Getattr(parent, "sym:name"), symname);
- symname = newsymname;
- }
-
- {
- // Wrap C/C++ enums with constant integers or use the typesafe enum pattern
- SwigType *typemap_lookup_type = parent_name ? parent_name : NewString("enum ");
- if (debugMode) {
- Printf(stdout, "Setting type: %s\n", Copy(typemap_lookup_type));
- }
- Setattr(n, "type", typemap_lookup_type);
-
- // Simple integer constants
- // Note these are always generated for anonymous enums, no matter what enum_feature is specified
- // Code generated is the same for SimpleEnum and TypeunsafeEnum -> the class it is generated into is determined later
-
- String *value = enumValue(n);
- if (enum_values) {
- Printf(enum_values, ",\n\"%s\" = %s", name, value);
- } else {
- enum_values = NewString("");
- Printf(enum_values, "\"%s\" = %s", name, value);
- }
-
- Delete(value);
- }
-
- return SWIG_OK;
-}
-
-
-/* -------------------------------------------------------------
- * Create accessor functions for variables.
- * Does not create equivalent wrappers for enumerations,
- * which are handled differently
- * --------------------------------------------------------------*/
-
-int R::variableWrapper(Node *n) {
- String *name = Getattr(n, "sym:name");
- if (debugMode) {
- Printf(stdout, "variableWrapper %s\n", n);
- }
- processing_variable = 1;
- Language::variableWrapper(n); // Force the emission of the _set and _get function wrappers.
- processing_variable = 0;
-
-
- SwigType *ty = Getattr(n, "type");
- String *nodeType = nodeType(n);
- int addCopyParam = addCopyParameter(ty);
-
- //XXX
- processType(ty, n);
-
- if (nodeType && !Strcmp(nodeType, "enumitem")) {
- /* special wrapper for enums - don't want the R _set, _get functions*/
- if (debugMode) {
- Printf(stdout, "variableWrapper enum branch\n");
- }
- } else if(!SwigType_isconst(ty)) {
- Wrapper *f = NewWrapper();
- Printf(f->def, "%s = \nfunction(value%s)\n{\n",
- name, addCopyParam ? ", .copy = FALSE" : "");
- Printv(f->code, "if(missing(value)) {\n",
- name, "_get(", addCopyParam ? ".copy" : "", ")\n}", NIL);
- Printv(f->code, " else {\n",
- name, "_set(value)\n}\n}", NIL);
-
- Wrapper_print(f, sfile);
- DelWrapper(f);
- } else {
- Printf(sfile, "%s = %s_get\n", name, name);
- }
-
- return SWIG_OK;
-}
-
-/* -------------------------------------------------------------
- * Creates accessor functions for class members.
-
- * ToDo - this version depends on naming conventions and needs
- * to be replaced.
- * --------------------------------------------------------------*/
-
-void R::addAccessor(String *memberName, Wrapper *wrapper, String *name,
- String *methodSetGet) {
-
- if (!class_member_function_names) {
- class_member_function_names = NewList();
- class_member_function_membernames = NewList();
- class_member_function_wrappernames = NewList();
- class_member_function_types = NewList();
- }
- Append(class_member_function_types, methodSetGet);
- Append(class_member_function_names, name);
- Append(class_member_function_membernames, memberName);
-
- String *tmp = NewString("");
- Wrapper_print(wrapper, tmp);
- Append(class_member_function_wrappernames, tmp);
- // if we could put the wrapper in directly: Append(l, Copy(sfun));
- if (debugMode)
- Printf(stdout, "Adding accessor: %s (%s) => %s\n", memberName, name, tmp);
-}
-
-#define MAX_OVERLOAD 256
-
-namespace {
-struct Overloaded {
- Node *n; /* Node */
- int argc; /* Argument count */
- ParmList *parms; /* Parameters used for overload check */
- int error; /* Ambiguity error */
-};
-}
-
-List * R::Swig_overload_rank(Node *n,
- bool script_lang_wrapping) {
- Overloaded nodes[MAX_OVERLOAD];
- int nnodes = 0;
- Node *o = Getattr(n,"sym:overloaded");
-
-
- if (!o) return 0;
-
- Node *c = o;
- while (c) {
- if (Getattr(c,"error")) {
- c = Getattr(c,"sym:nextSibling");
- continue;
- }
- /* Make a list of all the declarations (methods) that are overloaded with
- * this one particular method name */
-
- if (Getattr(c,"wrap:name")) {
- nodes[nnodes].n = c;
- nodes[nnodes].parms = Getattr(c,"wrap:parms");
- nodes[nnodes].argc = emit_num_required(nodes[nnodes].parms);
- nodes[nnodes].error = 0;
- nnodes++;
- }
- c = Getattr(c,"sym:nextSibling");
- }
-
- /* Sort the declarations by required argument count */
- {
- int i,j;
- for (i = 0; i < nnodes; i++) {
- for (j = i+1; j < nnodes; j++) {
- if (nodes[i].argc > nodes[j].argc) {
- Overloaded t = nodes[i];
- nodes[i] = nodes[j];
- nodes[j] = t;
- }
- }
- }
- }
-
- /* Sort the declarations by argument types */
- {
- int i,j;
- for (i = 0; i < nnodes-1; i++) {
- if (nodes[i].argc == nodes[i+1].argc) {
- for (j = i+1; (j < nnodes) && (nodes[j].argc == nodes[i].argc); j++) {
- Parm *p1 = nodes[i].parms;
- Parm *p2 = nodes[j].parms;
- int differ = 0;
- int num_checked = 0;
- while (p1 && p2 && (num_checked < nodes[i].argc)) {
- if (debugMode) {
- Printf(stdout,"p1 = '%s', p2 = '%s'\n", Getattr(p1,"type"), Getattr(p2,"type"));
- }
- if (checkAttribute(p1,"tmap:in:numinputs","0")) {
- p1 = Getattr(p1,"tmap:in:next");
- continue;
- }
- if (checkAttribute(p2,"tmap:in:numinputs","0")) {
- p2 = Getattr(p2,"tmap:in:next");
- continue;
- }
- String *t1 = Getattr(p1,"tmap:typecheck:precedence");
- String *t2 = Getattr(p2,"tmap:typecheck:precedence");
- if (debugMode) {
- Printf(stdout,"t1 = '%s', t2 = '%s'\n", t1, t2);
- }
- if ((!t1) && (!nodes[i].error)) {
- Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[i].n), Getline(nodes[i].n),
- "Overloaded method %s not supported (incomplete type checking rule - no precedence level in typecheck typemap for '%s').\n",
- Swig_name_decl(nodes[i].n), SwigType_str(Getattr(p1, "type"), 0));
- nodes[i].error = 1;
- } else if ((!t2) && (!nodes[j].error)) {
- Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[j].n), Getline(nodes[j].n),
- "Overloaded method %s not supported (incomplete type checking rule - no precedence level in typecheck typemap for '%s').\n",
- Swig_name_decl(nodes[j].n), SwigType_str(Getattr(p2, "type"), 0));
- nodes[j].error = 1;
- }
- if (t1 && t2) {
- int t1v, t2v;
- t1v = atoi(Char(t1));
- t2v = atoi(Char(t2));
- differ = t1v-t2v;
- }
- else if (!t1 && t2) differ = 1;
- else if (t1 && !t2) differ = -1;
- else if (!t1 && !t2) differ = -1;
- num_checked++;
- if (differ > 0) {
- Overloaded t = nodes[i];
- nodes[i] = nodes[j];
- nodes[j] = t;
- break;
- } else if ((differ == 0) && (Strcmp(t1,"0") == 0)) {
- t1 = Getattr(p1,"ltype");
- if (!t1) {
- t1 = SwigType_ltype(Getattr(p1,"type"));
- if (Getattr(p1,"tmap:typecheck:SWIGTYPE")) {
- SwigType_add_pointer(t1);
- }
- Setattr(p1,"ltype",t1);
- }
- t2 = Getattr(p2,"ltype");
- if (!t2) {
- t2 = SwigType_ltype(Getattr(p2,"type"));
- if (Getattr(p2,"tmap:typecheck:SWIGTYPE")) {
- SwigType_add_pointer(t2);
- }
- Setattr(p2,"ltype",t2);
- }
-
- /* Need subtype check here. If t2 is a subtype of t1, then we need to change the
- order */
-
- if (SwigType_issubtype(t2,t1)) {
- Overloaded t = nodes[i];
- nodes[i] = nodes[j];
- nodes[j] = t;
- }
-
- if (Strcmp(t1,t2) != 0) {
- differ = 1;
- break;
- }
- } else if (differ) {
- break;
- }
- if (Getattr(p1,"tmap:in:next")) {
- p1 = Getattr(p1,"tmap:in:next");
- } else {
- p1 = nextSibling(p1);
- }
- if (Getattr(p2,"tmap:in:next")) {
- p2 = Getattr(p2,"tmap:in:next");
- } else {
- p2 = nextSibling(p2);
- }
- }
- if (!differ) {
- /* See if declarations differ by const only */
- String *d1 = Getattr(nodes[i].n, "decl");
- String *d2 = Getattr(nodes[j].n, "decl");
- if (d1 && d2) {
- String *dq1 = Copy(d1);
- String *dq2 = Copy(d2);
- if (SwigType_isconst(d1)) {
- Delete(SwigType_pop(dq1));
- }
- if (SwigType_isconst(d2)) {
- Delete(SwigType_pop(dq2));
- }
- if (Strcmp(dq1, dq2) == 0) {
-
- if (SwigType_isconst(d1) && !SwigType_isconst(d2)) {
- if (script_lang_wrapping) {
- // Swap nodes so that the const method gets ignored (shadowed by the non-const method)
- Overloaded t = nodes[i];
- nodes[i] = nodes[j];
- nodes[j] = t;
- }
- differ = 1;
- if (!nodes[j].error) {
- if (script_lang_wrapping) {
- Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n),
- "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
- Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n),
- "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n));
- } else {
- if (!Getattr(nodes[j].n, "overload:ignore")) {
- Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
- "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
- Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n),
- "using %s instead.\n", Swig_name_decl(nodes[i].n));
- }
- }
- }
- nodes[j].error = 1;
- } else if (!SwigType_isconst(d1) && SwigType_isconst(d2)) {
- differ = 1;
- if (!nodes[j].error) {
- if (script_lang_wrapping) {
- Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n),
- "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
- Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n),
- "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n));
- } else {
- if (!Getattr(nodes[j].n, "overload:ignore")) {
- Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
- "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
- Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n),
- "using %s instead.\n", Swig_name_decl(nodes[i].n));
- }
- }
- }
- nodes[j].error = 1;
- }
- }
- Delete(dq1);
- Delete(dq2);
- }
- }
- if (!differ) {
- if (!nodes[j].error) {
- if (script_lang_wrapping) {
- Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[j].n), Getline(nodes[j].n),
- "Overloaded method %s effectively ignored,\n", Swig_name_decl(nodes[j].n));
- Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[i].n), Getline(nodes[i].n),
- "as it is shadowed by %s.\n", Swig_name_decl(nodes[i].n));
- } else {
- if (!Getattr(nodes[j].n, "overload:ignore")) {
- Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
- "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
- Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n),
- "using %s instead.\n", Swig_name_decl(nodes[i].n));
- }
- }
- nodes[j].error = 1;
- }
- }
- }
- }
- }
- }
- List *result = NewList();
- {
- int i;
- for (i = 0; i < nnodes; i++) {
- if (nodes[i].error)
- Setattr(nodes[i].n, "overload:ignore", "1");
- Append(result,nodes[i].n);
- }
- }
- return result;
-}
-
-void R::dispatchFunction(Node *n) {
- Wrapper *f = NewWrapper();
- String *symname = Getattr(n, "sym:name");
- String *nodeType = Getattr(n, "nodeType");
- bool constructor = (!Cmp(nodeType, "constructor"));
-
- String *sfname = NewString(symname);
-
- if (constructor)
- Replace(sfname, "new_", "", DOH_REPLACE_FIRST);
-
- Printf(f->def,
- "`%s` <- function(...) {", sfname);
- if (debugMode) {
- Swig_print_node(n);
- }
- List *dispatch = Swig_overload_rank(n, true);
- int nfunc = Len(dispatch);
- Printv(f->code,
- "argtypes <- mapply(class, list(...));\n",
- "argv <- list(...);\n",
- "argc <- length(argtypes);\n",
- "f <- NULL;\n", NIL);
-
- Printf(f->code, "# dispatch functions %d\n", nfunc);
- int cur_args = -1;
- bool first_compare = true;
- for (int i=0; i < nfunc; i++) {
- Node *ni = Getitem(dispatch,i);
- Parm *pi = Getattr(ni,"wrap:parms");
- int num_arguments = emit_num_arguments(pi);
-
- String *overname = Getattr(ni,"sym:overname");
- if (cur_args != num_arguments) {
- if (cur_args != -1) {
- Printv(f->code, "} else ", NIL);
- }
- Printf(f->code, "if (argc == %d) {", num_arguments);
- cur_args = num_arguments;
- first_compare = true;
- }
- Parm *p;
- int j;
- if (num_arguments > 0) {
- if (!first_compare) {
- Printv(f->code, " else ", NIL);
- } else {
- first_compare = false;
- }
- Printv(f->code, "if (", NIL);
- for (p = pi, j = 0 ; j < num_arguments ; j++) {
- if (debugMode) {
- Swig_print_node(p);
- }
- String *tm = Swig_typemap_lookup("rtype", p, "", 0);
- if (tm) {
- replaceRClass(tm, Getattr(p, "type"));
- }
-
- String *tmcheck = Swig_typemap_lookup("rtypecheck", p, "", 0);
- if (tmcheck) {
- String *tmp_argtype = NewStringf("argtypes[%d]", j+1);
- Replaceall(tmcheck, "$argtype", tmp_argtype);
- String *tmp_arg = NewStringf("argv[[%d]]", j+1);
- Replaceall(tmcheck, "$arg", tmp_arg);
- replaceRClass(tmcheck, Getattr(p, "type"));
- if (debugMode) {
- Printf(stdout, "<rtypecheck>%s\n", tmcheck);
- }
- if (num_arguments == 1) {
- Printf(f->code, "%s", tmcheck);
- } else {
- Printf(f->code, "%s(%s)", j == 0 ? "" : " && ", tmcheck);
- }
- p = Getattr(p, "tmap:in:next");
- Delete(tmp_arg);
- Delete(tmp_argtype);
- continue;
- }
- // Below should be migrated into rtypecheck typemaps
- // Preparation for this has started by warning in swig-4.1.1 for "numeric", "integer", "character" typemaps
- // For swig-4.2: remove the code block below and uncomment typemaps marked 'Replacement rtypecheck typemaps' in rtype.swg.
- // There is a slight difference in output as the typemap approach fixes some bugs due to a missing type resolution below
- if (tm) {
- String *tmcode = NULL;
- Printf(f->code, "%s", j == 0 ? "" : " && ");
- if (num_arguments != 1)
- Printf(f->code, "(");
- Printf(f->code, " ");
- if (Strcmp(tm, "numeric") == 0) {
- tmcode = NewString("is.numeric($arg)");
- } else if (Strcmp(tm, "integer") == 0) {
- tmcode = NewString("(is.integer($arg) || is.numeric($arg))");
- } else if (Strcmp(tm, "character") == 0) {
- tmcode = NewString("is.character($arg)");
- } else {
- if (SwigType_ispointer(Getattr(p, "type")))
- Printf(f->code, "extends(argtypes[%d], '%s') || is.null(argv[[%d]])", j+1, tm, j+1);
- else
- Printf(f->code, "extends(argtypes[%d], '%s') && length(argv[[%d]]) == 1", j+1, tm, j+1);
- }
- if (tmcode) {
- if (!SwigType_ispointer(Getattr(p, "type")))
- Printf(tmcode, " && length($arg) == 1");
- Swig_warning(WARN_R_MISSING_RTYPECHECK_TYPEMAP, input_file, line_number,
- "Optional rtypecheck code is deprecated. Add the following typemap to fix as the next version of SWIG will not work without it: %%typemap(\"rtypecheck\") %s %%{ %s %%}\n",
- SwigType_str(Getattr(p, "type"), 0), tmcode);
- String *tmp_arg = NewStringf("argv[[%d]]", j+1);
- Replaceall(tmcode, "$arg", tmp_arg);
- Printv(f->code, tmcode, NIL);
- Delete(tmp_arg);
- }
- Printf(f->code, " ");
- if (num_arguments != 1)
- Printf(f->code, ")");
- Delete(tmcode);
- }
- p = Getattr(p, "tmap:in:next");
- }
- Printf(f->code, ") { f <- %s%s; }\n", sfname, overname);
- } else {
- Printf(f->code, "f <- %s%s; ", sfname, overname);
- }
- }
- if (cur_args != -1) {
- Printf(f->code, "};\n");
- }
- Printf(f->code, "if (is.null(f)) {\n"
- "stop(\"cannot find overloaded function for %s with argtypes (\","
- "toString(argtypes),\")\");\n"
- "}", sfname);
- Printv(f->code, ";\nf(...)", NIL);
- Printv(f->code, ";\n}", NIL);
- Wrapper_print(f, sfile);
- Printv(sfile, "# Dispatch function\n", NIL);
- DelWrapper(f);
-}
-
-/*--------------------------------------------------------------
-
-* --------------------------------------------------------------*/
-
-int R::functionWrapper(Node *n) {
- String *fname = Getattr(n, "name");
- String *iname = Getattr(n, "sym:name");
- String *type = Getattr(n, "type");
-
- if (debugMode) {
- Printf(stdout,
- "<functionWrapper> %s %s %s\n", fname, iname, type);
- }
- String *overname = 0;
- String *nodeType = Getattr(n, "nodeType");
- bool constructor = (!Cmp(nodeType, "constructor"));
- bool destructor = (!Cmp(nodeType, "destructor"));
-
- String *sfname = NewString(iname);
-
- if (constructor)
- Replace(sfname, "new_", "", DOH_REPLACE_FIRST);
-
- if (Getattr(n,"sym:overloaded")) {
- overname = Getattr(n,"sym:overname");
- Append(sfname, overname);
- }
-
- if (debugMode)
- Printf(stdout,
- "<functionWrapper> processing parameters\n");
-
-
- ParmList *l = Getattr(n, "parms");
- Parm *p;
- String *tm;
-
- p = l;
- while(p) {
- SwigType *resultType = Getattr(p, "type");
- if (expandTypedef(resultType) &&
- SwigType_istypedef(resultType)) {
- SwigType *resolved =
- SwigType_typedef_resolve_all(resultType);
- if (expandTypedef(resolved)) {
- if (debugMode) {
- Printf(stdout, "Setting type: %s\n", resolved);
- }
- Setattr(p, "type", Copy(resolved));
- }
- }
- p = nextSibling(p);
- }
-
- String *unresolved_return_type =
- Copy(type);
- if (expandTypedef(type) &&
- SwigType_istypedef(type)) {
- SwigType *resolved =
- SwigType_typedef_resolve_all(type);
- if (debugMode)
- Printf(stdout, "<functionWrapper> resolved %s\n", Copy(unresolved_return_type));
- if (expandTypedef(resolved)) {
- type = Copy(resolved);
- Setattr(n, "type", type);
- }
- }
- if (debugMode)
- Printf(stdout, "<functionWrapper> unresolved_return_type %s\n", unresolved_return_type);
- if(processing_member_access_function) {
- if (debugMode)
- Printf(stdout, "<functionWrapper memberAccess> '%s' '%s' '%s' '%s'\n", fname, iname, member_name, class_name);
-
- if(opaqueClassDeclaration)
- return SWIG_OK;
-
-
- /* Add the name of this member to a list for this class_name.
- We will dump all these at the end. */
-
- bool isSet = GetFlag(n, "memberset") ? true : false;
-
- String *tmp = NewString(isSet ? Swig_name_set(NSPACE_TODO, class_name) : Swig_name_get(NSPACE_TODO, class_name));
-
- List *memList = Getattr(ClassMemberTable, tmp);
- if(!memList) {
- memList = NewList();
- Append(memList, class_name);
- Setattr(ClassMemberTable, tmp, memList);
- }
- Delete(tmp);
- Append(memList, member_name);
- Append(memList, iname);
- }
-
- int i;
- int nargs;
-
- String *wname = Swig_name_wrapper(iname);
-
- if(overname)
- Append(wname, overname);
- Setattr(n,"wrap:name", wname);
-
- Wrapper *f = NewWrapper();
- Wrapper *sfun = NewWrapper();
-
- int isVoidReturnType = (Strcmp(type, "void") == 0);
- // Need to use the unresolved return type since
- // typedef resolution removes the const which causes a
- // mismatch with the function action
- emit_return_variable(n, unresolved_return_type, f);
-
- SwigType *rtype = Getattr(n, "type");
- int addCopyParam = 0;
-
- if(!isVoidReturnType)
- addCopyParam = addCopyParameter(rtype);
-
- if (debugMode)
- Printf(stdout, "Adding a .copy argument to %s for %s = %s\n",
- iname, type, addCopyParam ? "yes" : "no");
-
- Printv(f->def, "SWIGEXPORT SEXP\n", wname, " ( ", NIL);
-
- Printf(sfun->def, "# Start of %s\n", iname);
- Printv(sfun->def, "\n`", sfname, "` = function(", NIL);
-
- if(outputNamespaceInfo) {//XXX Need to be a little more discriminating
- if (constructor) {
- String *niname = Copy(iname);
- Replace(niname, "new_", "", DOH_REPLACE_FIRST);
- addNamespaceFunction(niname);
- Delete(niname);
- } else {
- addNamespaceFunction(iname);
- }
- }
-
- Swig_typemap_attach_parms("scoercein", l, f);
- Swig_typemap_attach_parms("scoerceout", l, f);
- Swig_typemap_attach_parms("scheck", l, f);
-
- emit_parameter_variables(l, f);
- emit_attach_parmmaps(l,f);
- Setattr(n,"wrap:parms",l);
-
- nargs = emit_num_arguments(l);
-
- Wrapper_add_local(f, "r_nprotect", "unsigned int r_nprotect = 0");
- Wrapper_add_localv(f, "r_ans", "SEXP", "r_ans = R_NilValue", NIL);
- Wrapper_add_localv(f, "r_vmax", "VMAXTYPE", "r_vmax = vmaxget()", NIL);
-
- String *sargs = NewString("");
-
-
- String *s_inputTypes = NewString("");
- String *s_inputMap = NewString("");
- bool inFirstArg = true;
- bool inFirstType = true;
- Parm *curP;
- for (p =l, i = 0 ; i < nargs ; i++) {
-
- while (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- }
-
- SwigType *tt = Getattr(p, "type");
- int nargs = -1;
- String *funcptr_name = processType(tt, p, &nargs);
-
- // SwigType *tp = Getattr(p, "type");
- String *name = Getattr(p,"name");
- String *lname = Getattr(p,"lname");
-
- // R keyword renaming
- if (name) {
- if (Swig_name_warning(p, 0, name, 0)) {
- name = 0;
- } else {
- /* If we have a :: in the parameter name because we are accessing a static member of a class, say, then
- we need to remove that prefix. */
- while (Strstr(name, "::")) {
- //XXX need to free.
- name = NewStringf("%s", Strchr(name, ':') + 2);
- if (debugMode)
- Printf(stdout, "+++ parameter name with :: in it %s\n", name);
- }
- }
- }
- if (!name || Len(name) == 0)
- name = NewStringf("s_arg%d", i+1);
-
- name = replaceInitialDash(name);
-
- if (!Strncmp(name, "arg", 3)) {
- name = Copy(name);
- Insert(name, 0, "s_");
- }
-
- if(processing_variable) {
- name = Copy(name);
- Insert(name, 0, "s_");
- }
-
- if(!Strcmp(name, fname)) {
- name = Copy(name);
- Insert(name, 0, "s_");
- }
-
- Printf(sargs, "%s, ", name);
-
- String *tm;
- if((tm = Getattr(p, "tmap:scoercein"))) {
- Replaceall(tm, "$input", name);
- replaceRClass(tm, Getattr(p, "type"));
-
- if(funcptr_name) {
- //XXX need to get this to return non-zero
- if(nargs == -1)
- nargs = getFunctionPointerNumArgs(p, tt);
-
- String *snargs = NewStringf("%d", nargs);
- Printv(sfun->code, "if(is.function(", name, ")) {", "\n",
- "assert('...' %in% names(formals(", name,
- ")) || length(formals(", name, ")) >= ", snargs, ");\n} ", NIL);
- Delete(snargs);
-
- Printv(sfun->code, "else {\n",
- "if(is.character(", name, ")) {\n",
- name, " = getNativeSymbolInfo(", name, ");",
- "\n};\n",
- "if(is(", name, ", \"NativeSymbolInfo\")) {\n",
- name, " = ", name, "$address", ";\n};\n",
- "if(is(", name, ", \"ExternalReference\")) {\n",
- name, " = ", name, "@ref;\n}\n",
- "}; \n",
- NIL);
- } else {
- Printf(sfun->code, "%s\n", tm);
- }
- }
-
- Printv(sfun->def, inFirstArg ? "" : ", ", name, NIL);
-
- if ((tm = Getattr(p,"tmap:scheck"))) {
-
- Replaceall(tm,"$input", name);
- replaceRClass(tm, Getattr(p, "type"));
- Printf(sfun->code,"%s\n",tm);
- }
-
-
-
- curP = p;
- if ((tm = Getattr(p,"tmap:in"))) {
-
- Replaceall(tm,"$input", name);
-
- if (Getattr(p,"wrap:disown") || (Getattr(p,"tmap:in:disown"))) {
- Replaceall(tm,"$disown","SWIG_POINTER_DISOWN");
- } else {
- Replaceall(tm,"$disown","0");
- }
-
- if(funcptr_name) {
- /* have us a function pointer */
- Printf(f->code, "if(TYPEOF(%s) != CLOSXP) {\n", name);
- Replaceall(tm,"$R_class", "");
- } else {
- replaceRClass(tm, Getattr(p, "type"));
- }
-
-
- Printf(f->code,"%s\n",tm);
- if(funcptr_name)
- Printf(f->code, "} else {\n%s = %s;\nR_SWIG_pushCallbackFunctionData(%s, NULL);\n}\n",
- lname, funcptr_name, name);
- Printv(f->def, inFirstArg ? "" : ", ", "SEXP ", name, NIL);
- if (Len(name) != 0)
- inFirstArg = false;
- p = Getattr(p,"tmap:in:next");
-
- } else {
- p = nextSibling(p);
- }
-
-
- tm = Swig_typemap_lookup("rtype", curP, "", 0);
- if(tm) {
- replaceRClass(tm, Getattr(curP, "type"));
- }
- Printf(s_inputTypes, "%s'%s'", inFirstType ? "" : ", ", tm);
- Printf(s_inputMap, "%s%s='%s'", inFirstType ? "" : ", ", name, tm);
- inFirstType = false;
-
- if(funcptr_name)
- Delete(funcptr_name);
- } /* end of looping over parameters. */
-
- if(addCopyParam) {
- Printf(sfun->def, "%s.copy = FALSE", nargs > 0 ? ", " : "");
- Printf(f->def, "%sSEXP s_swig_copy", nargs > 0 ? ", " : "");
-
- Printf(sargs, "as.logical(.copy), ");
- }
-
- Printv(f->def, ")\n{\n", NIL);
- // SWIG_fail in R leads to a call to Rf_error() which calls longjmp()
- // which means the destructors of any live function-local C++ objects won't
- // get run. To avoid this happening, we wrap almost everything in the
- // function in a block, and end that right before Rf_error() at which
- // point those destructors will get called.
- if (CPlusPlus) Append(f->def, "{\n");
-
- Printv(sfun->def, ")\n{\n", NIL);
-
-
- /* Insert cleanup code */
- String *cleanup = NewString("");
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:freearg"))) {
- if (tm && (Len(tm) != 0)) {
- Printv(cleanup, tm, "\n", NIL);
- }
- p = Getattr(p, "tmap:freearg:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- String *outargs = NewString("");
- int numOutArgs = isVoidReturnType ? -1 : 0;
- for(p = l, i = 0; p; i++) {
- if((tm = Getattr(p, "tmap:argout"))) {
- // String *lname = Getattr(p, "lname");
- numOutArgs++;
- String *pos = NewStringf("%d", numOutArgs);
- Replaceall(tm,"$result", "r_ans");
- Replaceall(tm,"$n", pos); // The position into which to store the answer.
- Replaceall(tm,"$arg", Getattr(p, "emit:input"));
- Replaceall(tm,"$input", Getattr(p, "emit:input"));
- Replaceall(tm,"$owner", "0");
-
-
- Printf(outargs, "%s\n", tm);
- p = Getattr(p,"tmap:argout:next");
- } else
- p = nextSibling(p);
- }
-
- String *actioncode = emit_action(n);
-
- /* Deal with the explicit return value. */
- if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
- SwigType *retType = Getattr(n, "type");
-
- Replaceall(tm,"$1", Swig_cresult_name());
- Replaceall(tm,"$result", "r_ans");
- if (debugMode){
- Printf(stdout, "Calling replace D: %s, %s, %s\n", retType, n, tm);
- }
- replaceRClass(tm, retType);
-
- if (GetFlag(n,"feature:new")) {
- Replaceall(tm, "$owner", "SWIG_POINTER_OWN");
- } else {
- Replaceall(tm,"$owner", "0");
- }
-
- Printf(f->code, "%s\n", tm);
-
- } else {
- Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number,
- "Unable to use return type %s in function %s.\n", SwigType_str(type, 0), fname);
- }
-
-
- if(Len(outargs)) {
- Wrapper_add_local(f, "R_OutputValues", "SEXP R_OutputValues");
-
- String *tmp = NewString("");
- if(!isVoidReturnType)
- Printf(tmp, "Rf_protect(r_ans);\n");
-
- Printf(tmp, "Rf_protect(R_OutputValues = Rf_allocVector(VECSXP,%d));\nr_nprotect += %d;\n",
- numOutArgs + !isVoidReturnType,
- isVoidReturnType ? 1 : 2);
-
- if(!isVoidReturnType)
- Printf(tmp, "SET_VECTOR_ELT(R_OutputValues, 0, r_ans);\n");
- Printf(tmp, "r_ans = R_OutputValues;\n");
-
- Insert(outargs, 0, tmp);
- Delete(tmp);
-
-
-
- Printv(f->code, outargs, NIL);
- Delete(outargs);
-
- }
-
- /* Output cleanup code */
- int need_cleanup = Len(cleanup) != 0;
- if (need_cleanup) {
- Printv(f->code, cleanup, NIL);
- }
-
- /* Look to see if there is any newfree cleanup code */
- if (GetFlag(n, "feature:new")) {
- if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
- Printf(f->code, "%s\n", tm);
- }
- }
-
- /* See if there is any return cleanup code */
- if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
- Printf(f->code, "%s\n", tm);
- Delete(tm);
- }
-
- Printv(f->code, UnProtectWrapupCode, NIL);
-
- /*If the user gave us something to convert the result in */
- if ((tm = Swig_typemap_lookup("scoerceout", n, Swig_cresult_name(), sfun))) {
- Replaceall(tm,"$result","ans");
- if (debugMode) {
- Printf(stdout, "Calling replace B: %s, %s, %s\n", Getattr(n, "type"), Getattr(n, "sym:name"), getNSpace());
- }
- replaceRClass(tm, Getattr(n, "type"));
- Chop(tm);
- }
-
-
- Printv(sfun->code, ";", (Len(tm) ? "ans = " : ""), ".Call('", wname,
- "', ", sargs, "PACKAGE='", Rpackage, "');\n", NIL);
- if(Len(tm))
- {
- Printf(sfun->code, "%s\n\n", tm);
- if (constructor)
- {
- String *finalizer = NewString(iname);
- Replace(finalizer, "new_", "", DOH_REPLACE_FIRST);
- Printf(sfun->code, "reg.finalizer(ans@ref, delete_%s);\n", finalizer);
- }
- Printf(sfun->code, "ans\n");
- }
-
- if (destructor)
- Printv(f->code, "R_ClearExternalPtr(self);\n", NIL);
-
- Printv(f->code, "return r_ans;\n", NIL);
-
- /* Error handling code */
- Printv(f->code, "fail: SWIGUNUSED;\n", NIL);
- if (need_cleanup) {
- Printv(f->code, cleanup, NIL);
- }
- if (CPlusPlus) Append(f->code, "}\n");
- Printv(f->code, " Rf_error(\"%s %s\", SWIG_ErrorType(SWIG_lasterror_code), SWIG_lasterror_msg);\n", NIL);
- Printv(f->code, " return R_NilValue;\n", NIL);
- Delete(cleanup);
-
- Printv(f->code, "}\n", NIL);
- Printv(sfun->code, "\n}", NIL);
-
- /* Substitute the function name */
- Replaceall(f->code,"$symname",iname);
-
- Wrapper_print(f, f_wrapper);
- Wrapper_print(sfun, sfile);
-
- Printf(sfun->code, "\n# End of %s\n", iname);
- tm = Swig_typemap_lookup("rtype", n, "", 0);
- if(tm) {
- SwigType *retType = Getattr(n, "type");
- if (debugMode) {
- Printf(stdout, "Calling replace C: %s\n", Copy(retType));
- }
- replaceRClass(tm, retType);
- }
-
- Printv(sfile, "attr(`", sfname, "`, 'returnType') = '",
- isVoidReturnType ? "void" : (tm ? tm : ""),
- "'\n", NIL);
-
- if(nargs > 0)
- Printv(sfile, "attr(`", sfname, "`, \"inputTypes\") = c(",
- s_inputTypes, ")\n", NIL);
- Printv(sfile, "class(`", sfname, "`) = c(\"SWIGFunction\", class('",
- sfname, "'))\n\n", NIL);
-
- if (memoryProfile) {
- Printv(sfile, "memory.profile()\n", NIL);
- }
- if (aggressiveGc) {
- Printv(sfile, "gc()\n", NIL);
- }
-
- // Printv(sfile, "setMethod('", name, "', '", name, "', ", iname, ")\n\n\n");
-
-
-
- /* If we are dealing with a method in an C++ class, then
- add the name of the R function and its definition.
- XXX need to figure out how to store the Wrapper if possible in the hash/list.
- Would like to be able to do this so that we can potentially insert
- */
- if(processing_member_access_function || processing_class_member_function) {
- String *method_type = R_MEMBER_NORMAL;
- if (GetFlag(n, "memberset")) {
- method_type = R_MEMBER_SET;
- } else if (GetFlag(n, "memberget")) {
- method_type = R_MEMBER_GET;
- }
- addAccessor(member_name, sfun, iname, method_type);
- }
-
- if (Getattr(n, "sym:overloaded") &&
- !Getattr(n, "sym:nextSibling")) {
- dispatchFunction(n);
- }
-
- addRegistrationRoutine(wname, addCopyParam ? nargs +1 : nargs);
-
- DelWrapper(f);
- DelWrapper(sfun);
-
- Delete(sargs);
- Delete(sfname);
- return SWIG_OK;
-}
-
-/* ----------------------------------------------------------------------
- * R::constantWrapper()
- * ---------------------------------------------------------------------- */
-
-int R::constantWrapper(Node *n) {
- (void) n;
- // TODO
- return SWIG_OK;
-}
-
-/*--------------------------------------------------------------
- * Add the specified routine name to the collection of
- * generated routines that are called from R functions.
- * This is used to register the routines with R for
- * resolving symbols.
-
- * rname - the name of the routine
- * nargs - the number of arguments it expects.
- * --------------------------------------------------------------*/
-
-int R::addRegistrationRoutine(String *rname, int nargs) {
- if(!registrationTable)
- registrationTable = NewHash();
-
- String *el =
- NewStringf("{\"%s\", (DL_FUNC) &%s, %d}", rname, rname, nargs);
-
- Setattr(registrationTable, rname, el);
-
- return SWIG_OK;
-}
-
-/* -------------------------------------------------------------
- * Write the registration information to an array and
- * create the initialization routine for registering
- * these.
- * --------------------------------------------------------------*/
-
-int R::outputRegistrationRoutines(File *out) {
- int i, n;
- if(!registrationTable)
- return(0);
- if(inCPlusMode)
- Printf(out, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n");
-
- Printf(out, "#include <R_ext/Rdynload.h>\n\n");
- if(inCPlusMode)
- Printf(out, "#ifdef __cplusplus\n}\n#endif\n\n");
-
- Printf(out, "SWIGINTERN R_CallMethodDef CallEntries[] = {\n");
-
- List *keys = Keys(registrationTable);
- n = Len(keys);
- for(i = 0; i < n; i++)
- Printf(out, " %s,\n", Getattr(registrationTable, Getitem(keys, i)));
-
- Printf(out, " {NULL, NULL, 0}\n};\n\n");
-
- if(!noInitializationCode) {
- if (inCPlusMode)
- Printv(out, "extern \"C\" ", NIL);
- { /* R allows pckage names to have '.' in the name, which is not allowed in C++ var names
- we simply replace all occurrences of '.' with '_' to construct the var name */
- String * Rpackage_sane = Copy(Rpackage);
- Replace(Rpackage_sane, ".", "_", DOH_REPLACE_ANY);
- Printf(out, "SWIGEXPORT void R_init_%s(DllInfo *dll) {\n", Rpackage_sane);
- Delete(Rpackage_sane);
- }
- Printf(out, "%sR_registerRoutines(dll, NULL, CallEntries, NULL, NULL);\n", tab4);
- if(Len(s_init_routine)) {
- Printf(out, "\n%s\n", s_init_routine);
- }
- Printf(out, "}\n");
- }
-
- return n;
-}
-
-
-
-/* -------------------------------------------------------------
- * Process a struct, union or class declaration in the source code,
- * or an anonymous typedef struct
- * --------------------------------------------------------------*/
-
-//XXX What do we need to do here -
-// Define an S4 class to refer to this.
-
-void R::registerClass(Node *n) {
- String *name = Getattr(n, "name");
-
- if (debugMode)
- Swig_print_node(n);
- String *sname = NewStringf("_p%s", SwigType_manglestr(name));
- if(!Getattr(SClassDefs, sname)) {
- Setattr(SClassDefs, sname, sname);
- String *base;
-
- if (CPlusPlus && (Strcmp(nodeType(n), "class") == 0)) {
- base = NewString("");
- List *l = Getattr(n, "bases");
- if(Len(l)) {
- Printf(base, "c(");
- for(int i = 0; i < Len(l); i++) {
- registerClass(Getitem(l, i));
- Printf(base, "'_p%s'%s",
- SwigType_manglestr(Getattr(Getitem(l, i), "name")),
- i < Len(l)-1 ? ", " : "");
- }
- Printf(base, ")");
- } else {
- base = NewString("'C++Reference'");
- }
- } else
- base = NewString("'ExternalReference'");
-
- Printf(s_classes, "setClass('%s', contains = %s)\n", sname, base);
- Delete(base);
- }
-}
-
-int R::classDeclaration(Node *n) {
-
- String *name = Getattr(n, "name");
- String *kind = Getattr(n, "kind");
-
- if (debugMode)
- Swig_print_node(n);
- registerClass(n);
-
-
- /* If we have a typedef union { ... } U, then we never get to see the typedef
- via a regular call to typedefHandler. Instead, */
- if(Getattr(n, "unnamed") && Getattr(n, "storage") && Strcmp(Getattr(n, "storage"), "typedef") == 0
- && Getattr(n, "tdname") && Strcmp(Getattr(n, "tdname"), name) == 0) {
- if (debugMode)
- Printf(stdout, "Typedef in the class declaration for %s\n", name);
- // typedefHandler(n);
- }
-
- bool opaque = GetFlag(n, "feature:opaque") ? true : false;
-
- if(opaque)
- opaqueClassDeclaration = name;
-
- int status = Language::classDeclaration(n);
-
- opaqueClassDeclaration = NULL;
-
-
- if (class_member_function_types) {
-
- // collect the "set" methods
- List *class_set_membernames = filterMemberList(class_member_function_types,
- class_member_function_membernames, R_MEMBER_SET, true);
- List *class_set_functionnames = filterMemberList(class_member_function_types,
- class_member_function_names, R_MEMBER_SET, true);
- // this one isn't used - collecting to keep code simpler
- List *class_set_functiontypes = filterMemberList(class_member_function_types,
- class_member_function_types, R_MEMBER_SET, true);
-
- // collect the others
- List *class_other_membernames = filterMemberList(class_member_function_types,
- class_member_function_membernames, R_MEMBER_SET, false);
- List *class_other_functionnames = filterMemberList(class_member_function_types,
- class_member_function_names, R_MEMBER_SET, false);
- List *class_other_functiontypes = filterMemberList(class_member_function_types,
- class_member_function_types, R_MEMBER_SET, false);
-
- if (Len(class_other_membernames) > 0) {
- OutputMemberReferenceMethod(name, 0, class_other_membernames, class_other_functionnames, class_other_functiontypes, sfile);
- }
- if (Len(class_set_membernames) > 0) {
- OutputMemberReferenceMethod(name, 1, class_set_membernames, class_set_functionnames, class_set_functiontypes, sfile);
- }
- Delete(class_set_membernames);
- Delete(class_set_functionnames);
- Delete(class_set_functiontypes);
- Delete(class_other_membernames);
- Delete(class_other_functionnames);
- Delete(class_other_functiontypes);
- }
-
- if (class_member_function_types) {
- Delete(class_member_function_types);
- class_member_function_types = NULL;
- Delete(class_member_function_names);
- class_member_function_names = NULL;
- Delete(class_member_function_membernames);
- class_member_function_membernames = NULL;
- Delete(class_member_function_wrappernames);
- class_member_function_wrappernames = NULL;
- }
- if (Getattr(n, "has_destructor")) {
- Printf(sfile, "setMethod('delete', '_p%s', function(obj) {delete%s(obj)})\n", getRClassName(name), getRClassName(name));
-
- }
- if(!opaque && !Strcmp(kind, "struct") && copyStruct) {
-
- String *def =
- NewStringf("setClass(\"%s\",\n%srepresentation(\n", name, tab4);
- bool firstItem = true;
-
- for(Node *c = firstChild(n); c; ) {
- String *elName;
- String *tp;
-
- elName = Getattr(c, "name");
-
- String *elKind = Getattr(c, "kind");
- if (!Equal(elKind, "variable")) {
- c = nextSibling(c);
- continue;
- }
- if (!Len(elName)) {
- c = nextSibling(c);
- continue;
- }
- tp = Swig_typemap_lookup("rtype", c, "", 0);
- if(!tp) {
- c = nextSibling(c);
- continue;
- }
- if (Strstr(tp, "R_class")) {
- c = nextSibling(c);
- continue;
- }
- if (Strcmp(tp, "character") &&
- Strstr(Getattr(c, "decl"), "p.")) {
- c = nextSibling(c);
- continue;
- }
-
- if (!firstItem) {
- Printf(def, ",\n");
- }
- // else
- //XXX How can we tell if this is already done.
- // SwigType_push(elType, elDecl);
-
-
- // returns "" tp = processType(elType, c, NULL);
- // Printf(stdout, "<classDeclaration> elType %p\n", elType);
- // tp = getRClassNameCopyStruct(Getattr(c, "type"), 1);
-
- String *elNameT = replaceInitialDash(elName);
- Printf(def, "%s%s = \"%s\"", tab8, elNameT, tp);
- firstItem = false;
- Delete(tp);
- Delete(elNameT);
- c = nextSibling(c);
- }
- Printf(def, "),\n%scontains = \"RSWIGStruct\")\n", tab8);
- Printf(s_classes, "%s\n\n# End class %s\n\n", def, name);
-
- generateCopyRoutines(n);
-
- Delete(def);
- }
-
- return status;
-}
-
-
-
-/* -------------------------------------------------------------
- * Create the C routines that copy an S object of the class given
- * by the given struct definition in Node *n to the C value
- * and also the routine that goes from the C routine to an object
- * of this S class.
- * --------------------------------------------------------------*/
-
-/*XXX
- Clean up the toCRef - make certain the names are correct for the types, etc.
- in all cases.
-*/
-
-int R::generateCopyRoutines(Node *n) {
- Wrapper *copyToR = NewWrapper();
- Wrapper *copyToC = NewWrapper();
-
- String *name = Getattr(n, "name");
- String *tdname = Getattr(n, "tdname");
- String *kind = Getattr(n, "kind");
- String *type;
-
- if(Len(tdname)) {
- type = Copy(tdname);
- } else {
- type = NewStringf("%s %s", kind, name);
- }
-
- String *mangledName = SwigType_manglestr(name);
-
- if (debugMode)
- Printf(stdout, "generateCopyRoutines: name = %s, %s\n", name, type);
-
- Printf(copyToR->def, "CopyToR%s = function(value, obj = new(\"%s\"))\n{\n",
- mangledName, name);
- Printf(copyToC->def, "CopyToC%s = function(value, obj)\n{\n",
- mangledName);
-
- Node *c = firstChild(n);
-
- for(; c; c = nextSibling(c)) {
- String *elName = Getattr(c, "name");
- if (!Len(elName)) {
- continue;
- }
- String *elKind = Getattr(c, "kind");
- if (!Equal(elKind, "variable")) {
- continue;
- }
-
- String *tp = Swig_typemap_lookup("rtype", c, "", 0);
- if(!tp) {
- continue;
- }
- if (Strstr(tp, "R_class")) {
- continue;
- }
- if (Strcmp(tp, "character") &&
- Strstr(Getattr(c, "decl"), "p.")) {
- continue;
- }
-
-
- /* The S functions to get and set the member value. */
- String *elNameT = replaceInitialDash(elName);
- Printf(copyToR->code, "obj@%s = value$%s;\n", elNameT, elNameT);
- Printf(copyToC->code, "obj$%s = value@%s;\n", elNameT, elNameT);
- Delete(elNameT);
- }
- Printf(copyToR->code, "obj;\n}\n\n");
- String *rclassName = getRClassNameCopyStruct(type, 0); // without the Ref.
- Printf(sfile, "# Start definition of copy functions & methods for %s\n", rclassName);
-
- Wrapper_print(copyToR, sfile);
- Printf(copyToC->code, "obj\n}\n\n");
- Wrapper_print(copyToC, sfile);
-
-
- Printf(sfile, "# Start definition of copy methods for %s\n", rclassName);
- Printf(sfile, "setMethod('copyToR', '_p%s', CopyToR%s);\n", mangledName,
- mangledName);
- Printf(sfile, "setMethod('copyToC', '%s', CopyToC%s);\n\n", rclassName,
- mangledName);
-
- Printf(sfile, "# End definition of copy methods for %s\n", rclassName);
- Printf(sfile, "# End definition of copy functions & methods for %s\n", rclassName);
-
- String *m = NewStringf("%sCopyToR", name);
- addNamespaceMethod(m);
- char *tt = Char(m); tt[Len(m)-1] = 'C';
- addNamespaceMethod(m);
- Delete(m);
- Delete(rclassName);
- Delete(mangledName);
- DelWrapper(copyToR);
- DelWrapper(copyToC);
-
- return SWIG_OK;
-}
-
-
-
-/* -------------------------------------------------------------
- * Called when there is a typedef to be invoked.
- *
- * XXX Needs to be enhanced or split to handle the case where we have a
- * typedef within a classDeclaration emission because the struct/union/etc.
- * is anonymous.
- * --------------------------------------------------------------*/
-
-int R::typedefHandler(Node *n) {
- SwigType *tp = Getattr(n, "type");
- String *type = Getattr(n, "type");
- if (debugMode)
- Printf(stdout, "<typedefHandler> %s\n", Getattr(n, "name"));
-
- processType(tp, n);
-
- if(Strncmp(type, "struct ", 7) == 0) {
- String *name = Getattr(n, "name");
- char *trueName = Char(type);
- trueName += 7;
- if (debugMode)
- Printf(stdout, "<typedefHandler> Defining S class %s\n", trueName);
- Printf(s_classes, "setClass('_p%s', contains = 'ExternalReference')\n",
- SwigType_manglestr(name));
- }
-
- return Language::typedefHandler(n);
-}
-
-
-
-/* --------------------------------------------------------------
- * Called when processing a field in a "class", i.e. struct, union or
- * actual class. We set a state variable so that we can correctly
- * interpret the resulting functionWrapper() call and understand that
- * it is for a field element.
- * --------------------------------------------------------------*/
-
-int R::membervariableHandler(Node *n) {
- SwigType *t = Getattr(n, "type");
- processType(t, n, NULL);
- processing_member_access_function = 1;
- member_name = Getattr(n,"sym:name");
- if (debugMode)
- Printf(stdout, "<membervariableHandler> name = %s, sym:name = %s\n",
- Getattr(n, "name"), member_name);
-
- int status(Language::membervariableHandler(n));
-
- if(!opaqueClassDeclaration && debugMode)
- Printf(stdout, "<membervariableHandler> %s %s\n", Getattr(n, "name"), Getattr(n, "type"));
-
- processing_member_access_function = 0;
- member_name = NULL;
-
- return status;
-}
-
-
-/*
- This doesn't seem to get used so leave it out for the moment.
-*/
-String * R::runtimeCode() {
- String *s = Swig_include_sys("rrun.swg");
- if (!s) {
- Printf(stdout, "*** Unable to open 'rrun.swg'\n");
- s = NewString("");
- }
- return s;
-}
-
-/*----------------------------------------------------------------------
- * replaceSpecialVariables()
- *--------------------------------------------------------------------*/
-
-void R::replaceSpecialVariables(String *method, String *tm, Parm *parm) {
- (void)method;
- SwigType *type = Getattr(parm, "type");
- replaceRClass(tm, type);
-}
-
-
-/* -----------------------------------------------------------------------
- * Called when SWIG wants to initialize this
- * We initialize anythin we want here.
- * Most importantly, tell SWIG where to find the files (e.g. r.swg) for this module.
- * Use Swig_mark_arg() to tell SWIG that it is understood and not to
- * throw an error.
- * --------------------------------------------------------------*/
-
-void R::main(int argc, char *argv[]) {
- init();
- Preprocessor_define("SWIGR 1", 0);
- SWIG_library_directory("r");
- SWIG_config_file("r.swg");
- debugMode = false;
- copyStruct = true;
- memoryProfile = false;
- aggressiveGc = false;
- inCPlusMode = false;
- outputNamespaceInfo = false;
- noInitializationCode = false;
-
- this->Argc = argc;
- this->Argv = argv;
-
- allow_overloading();// can we support this?
-
- for(int i = 0; i < argc; i++) {
- if(strcmp(argv[i], "-package") == 0) {
- Swig_mark_arg(i);
- i++;
- Swig_mark_arg(i);
- Rpackage = argv[i];
- } else if(strcmp(argv[i], "-dll") == 0) {
- Swig_mark_arg(i);
- i++;
- Swig_mark_arg(i);
- DllName = argv[i];
- } else if(strcmp(argv[i], "-help") == 0) {
- showUsage();
- } else if(strcmp(argv[i], "-namespace") == 0) {
- outputNamespaceInfo = true;
- Swig_mark_arg(i);
- } else if(!strcmp(argv[i], "-no-init-code")) {
- noInitializationCode = true;
- Swig_mark_arg(i);
- } else if(!strcmp(argv[i], "-c++")) {
- inCPlusMode = true;
- Swig_mark_arg(i);
- Printf(s_classes, "setClass('C++Reference', contains = 'ExternalReference')\n");
- } else if(!strcmp(argv[i], "-debug")) {
- debugMode = true;
- Swig_mark_arg(i);
- } else if (!strcmp(argv[i],"-copystruct")) {
- copyStruct = true;
- Swig_mark_arg(i);
- } else if (!strcmp(argv[i], "-nocopystruct")) {
- copyStruct = false;
- Swig_mark_arg(i);
- } else if (!strcmp(argv[i], "-memoryprof")) {
- memoryProfile = true;
- Swig_mark_arg(i);
- } else if (!strcmp(argv[i], "-nomemoryprof")) {
- memoryProfile = false;
- Swig_mark_arg(i);
- } else if (!strcmp(argv[i], "-aggressivegc")) {
- aggressiveGc = true;
- Swig_mark_arg(i);
- } else if (!strcmp(argv[i], "-noaggressivegc")) {
- aggressiveGc = false;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-cppcast") == 0) {
- Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nocppcast") == 0) {
- Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
- Swig_mark_arg(i);
- Exit(EXIT_FAILURE);
- }
-
- if (debugMode) {
- Swig_typemap_search_debug_set();
- Swig_typemap_used_debug_set();
- Swig_typemap_register_debug_set();
- Swig_file_debug_set();
- }
- /// copyToR copyToC functions.
-
- }
-}
-
-/* -----------------------------------------------------------------------
- * Could make this work for String or File and then just store the resulting string
- * rather than the collection of arguments and argc.
- * ----------------------------------------------------------------------- */
-int R::outputCommandLineArguments(File *out)
-{
- if(Argc < 1 || !Argv || !Argv[0])
- return(-1);
-
- Printf(out, "\n## Generated via the command line invocation:\n##\t");
- for(int i = 0; i < Argc ; i++) {
- Printf(out, " %s", Argv[i]);
- }
- Printf(out, "\n\n\n");
-
- return Argc;
-}
-
-
-
-/* How SWIG instantiates an object from this module.
- See swigmain.cxx */
-extern "C"
-Language *swig_r(void) {
- return new R();
-}
-
-
-
-
-/* -----------------------------------------------------------------------
- * Needs to be reworked.
- *----------------------------------------------------------------------- */
-String * R::processType(SwigType *t, Node *n, int *nargs) {
- //XXX Need to handle typedefs, e.g.
- // a type which is a typedef to a function pointer.
-
- SwigType *tmp = Getattr(n, "tdname");
- if (debugMode)
- Printf(stdout, "processType %s (tdname = %s)(SwigType = %s)\n", Getattr(n, "name"), tmp, Copy(t));
-
- SwigType *td = t;
- if (expandTypedef(t) &&
- SwigType_istypedef(t)) {
- SwigType *resolved =
- SwigType_typedef_resolve_all(t);
- if (expandTypedef(resolved)) {
- td = Copy(resolved);
- }
- }
-
- if(!td) {
- int count = 0;
- String *b = getRTypeName(t, &count);
- if(count && b && !Getattr(SClassDefs, b)) {
- if (debugMode)
- Printf(stdout, "<processType> Defining class %s\n", b);
-
- Printf(s_classes, "setClass('%s', contains = 'ExternalReference')\n", b);
- Setattr(SClassDefs, b, b);
- }
-
- }
-
-
- if(td)
- t = td;
-
- if(SwigType_isfunctionpointer(t)) {
- if (debugMode)
- Printf(stdout,
- "<processType> Defining pointer handler %s\n", t);
-
- String *tmp = createFunctionPointerHandler(t, n, nargs);
- return tmp;
- }
-
- return NULL;
-}
-
-
-/* -----------------------------------------------------------------------
- * enumValue()
- * This method will return a string with an enum value to use in from R when
- * setting up an enum variable
- * ------------------------------------------------------------------------ */
-
-String *R::enumValue(Node *n) {
- String *symname = Getattr(n, "sym:name");
- String *value = Getattr(n, "value");
- String *newsymname = 0;
-
- Node *parent = parentNode(n);
- symname = Getattr(n, "sym:name");
-
- // parent enumtype has namespace mangled in
- String *etype = Getattr(parent, "enumtype");
- // we have to directly call the c wrapper function, as the
- // R wrapper to the enum is designed to be used after the enum
- // structures have been created on the R side. This means
- // that we'll need to construct a .Call expression
-
- // change the type for variableWrapper
- if (debugMode) {
- Printf(stdout, "<enumValue> type set: %s\n", etype);
- }
-
- Setattr(n, "type", etype);
-
- if (!getCurrentClass()) {
- newsymname = Swig_name_member(0, Getattr(parent, "sym:name"), symname);
- // Strange hack to change the name
- Setattr(n, "name", Getattr(n, "value"));
- Setattr(n, "sym:name", newsymname);
- variableWrapper(n);
- value = Swig_name_get(NSPACE_TODO, newsymname);
- } else {
- String *enumClassPrefix = getEnumClassPrefix();
- newsymname = Swig_name_member(0, enumClassPrefix, symname);
- Setattr(n, "name", Getattr(n, "value"));
- Setattr(n, "sym:name", newsymname);
- variableWrapper(n);
- value = Swig_name_get(NSPACE_TODO, newsymname);
- }
- value = Swig_name_wrapper(value);
- Replace(value, "_wrap", "R_swig", DOH_REPLACE_FIRST);
-
- String *valuecall=NewString("");
- Printv(valuecall, ".Call('", value, "',FALSE, PACKAGE='", Rpackage, "')", NIL);
- Delete(value);
- return valuecall;
-}
diff --git a/contrib/tools/swig/Source/Modules/ruby.cxx b/contrib/tools/swig/Source/Modules/ruby.cxx
deleted file mode 100644
index 0208435f03..0000000000
--- a/contrib/tools/swig/Source/Modules/ruby.cxx
+++ /dev/null
@@ -1,3470 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * ruby.cxx
- *
- * Ruby language module for SWIG.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include "cparse.h"
-#include <ctype.h>
-#include <string.h>
-#include <limits.h> /* for INT_MAX */
-
-#define SWIG_PROTECTED_TARGET_METHODS 1
-
-class RClass {
-private:
- String *temp;
-
-public:
- String *name; /* class name (renamed) */
- String *cname; /* original C class/struct name */
- String *mname; /* Mangled name */
-
- /**
- * The C variable name used in the SWIG-generated wrapper code to refer to
- * this class; usually it is of the form "SwigClassXXX.klass", where SwigClassXXX
- * is a swig_class struct instance and klass is a member of that struct.
- */
- String *vname;
-
- /**
- * The C variable name used in the SWIG-generated wrapper code to refer to
- * the module that implements this class's methods (when we're trying to
- * support C++ multiple inheritance). Usually it is of the form
- * "SwigClassClassName.mImpl", where SwigClassXXX is a swig_class struct instance
- * and mImpl is a member of that struct.
- */
- String *mImpl;
-
- String *type;
- String *prefix;
- String *init;
-
-
- int constructor_defined;
- int destructor_defined;
-
- RClass() {
- temp = NewString("");
- name = NewString("");
- cname = NewString("");
- mname = NewString("");
- vname = NewString("");
- mImpl = NewString("");
- type = NewString("");
- prefix = NewString("");
- init = NewString("");
- constructor_defined = 0;
- destructor_defined = 0;
- }
-
- ~RClass() {
- Delete(name);
- Delete(cname);
- Delete(vname);
- Delete(mImpl);
- Delete(mname);
- Delete(type);
- Delete(prefix);
- Delete(init);
- Delete(temp);
- }
-
- void set_name(const_String_or_char_ptr cn, const_String_or_char_ptr rn, const_String_or_char_ptr valn) {
- /* Original C/C++ class (or struct) name */
- Clear(cname);
- Append(cname, cn);
-
- /* Mangled name */
- Delete(mname);
- mname = Swig_name_mangle(cname);
-
- /* Renamed class name */
- Clear(name);
- Append(name, valn);
-
- /* Variable name for the VALUE that refers to the Ruby Class object */
- Clear(vname);
- Printf(vname, "SwigClass%s.klass", name);
-
- /* Variable name for the VALUE that refers to the Ruby Class object */
- Clear(mImpl);
- Printf(mImpl, "SwigClass%s.mImpl", name);
-
- /* Prefix */
- Clear(prefix);
- Printv(prefix, (rn ? rn : cn), "_", NIL);
- }
-
- char *strip(const_String_or_char_ptr s) {
- Clear(temp);
- if (Strncmp(s, prefix, Len(prefix)) == 0) {
- Append(temp, Char(s) + Len(prefix));
- } else {
- Append(temp, s);
- }
- return Char(temp);
- }
-};
-
-
-/* flags for the make_autodoc function */
-namespace {
-enum autodoc_t {
- AUTODOC_CLASS,
- AUTODOC_CTOR,
- AUTODOC_DTOR,
- AUTODOC_STATICFUNC,
- AUTODOC_FUNC,
- AUTODOC_METHOD,
- AUTODOC_GETTER,
- AUTODOC_SETTER,
- AUTODOC_NONE
-};
-}
-
-static const char *usage = "\
-Ruby Options (available with -ruby)\n\
- -autorename - Enable renaming of classes and methods to follow Ruby coding standards\n\
- -globalmodule - Wrap everything into the global module\n\
- -initname <name>- Set entry function to Init_<name> (used by `require')\n\
- -minherit - Attempt to support multiple inheritance\n\
- -noautorename - Disable renaming of classes and methods (default)\n\
- -prefix <name> - Set a prefix <name> to be prepended to all names\n\
-";
-
-
-#define RCLASS(hash, name) (RClass*)(Getattr(hash, name) ? Data(Getattr(hash, name)) : 0)
-#define SET_RCLASS(hash, name, klass) Setattr(hash, name, NewVoid(klass, 0))
-
-
-class RUBY:public Language {
-private:
-
- String *module;
- String *modvar;
- String *feature;
- String *prefix;
- int current;
- Hash *classes; /* key=cname val=RClass */
- RClass *klass; /* Currently processing class */
- Hash *special_methods; /* Python style special method name table */
-
- File *f_directors;
- File *f_directors_h;
- File *f_directors_helpers;
- File *f_begin;
- File *f_runtime;
- File *f_runtime_h;
- File *f_header;
- File *f_wrappers;
- File *f_init;
- File *f_initbeforefunc;
-
- bool useGlobalModule;
- bool multipleInheritance;
-
- // Wrap modes
- enum WrapperMode {
- NO_CPP,
- MEMBER_FUNC,
- CONSTRUCTOR_ALLOCATE,
- CONSTRUCTOR_INITIALIZE,
- DESTRUCTOR,
- MEMBER_VAR,
- CLASS_CONST,
- STATIC_FUNC,
- STATIC_VAR
- };
-
- /* ------------------------------------------------------------
- * autodoc level declarations
- * ------------------------------------------------------------ */
-
- enum autodoc_l {
- NO_AUTODOC = -2, // no autodoc
- STRING_AUTODOC = -1, // use provided string
- NAMES_AUTODOC = 0, // only parameter names
- TYPES_AUTODOC = 1, // parameter names and types
- EXTEND_AUTODOC = 2, // extended documentation and parameter names
- EXTEND_TYPES_AUTODOC = 3 // extended documentation and parameter types + names
- };
-
- autodoc_t last_mode;
- String* last_autodoc;
-
- autodoc_l autodoc_level(String *autodoc) {
- autodoc_l dlevel = NO_AUTODOC;
- char *c = Char(autodoc);
- if (c) {
- if (isdigit(c[0])) {
- dlevel = (autodoc_l) atoi(c);
- } else {
- if (strcmp(c, "extended") == 0) {
- dlevel = EXTEND_AUTODOC;
- } else {
- dlevel = STRING_AUTODOC;
- }
- }
- }
- return dlevel;
- }
-
-
-
- /* ------------------------------------------------------------
- * have_docstring()
- * Check if there is a docstring directive and it has text,
- * or there is an autodoc flag set
- * ------------------------------------------------------------ */
-
- bool have_docstring(Node *n) {
- String *str = Getattr(n, "feature:docstring");
- return (str && Len(str) > 0) || (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc"));
- }
-
- /* ------------------------------------------------------------
- * docstring()
- * Get the docstring text, stripping off {} if necessary,
- * and enclose in triple double quotes. If autodoc is also
- * set then it will build a combined docstring.
- * ------------------------------------------------------------ */
-
- String *docstring(Node *n, autodoc_t ad_type) {
-
- String *str = Getattr(n, "feature:docstring");
- bool have_ds = (str && Len(str) > 0);
- bool have_auto = (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc"));
- String *autodoc = NULL;
- String *doc = NULL;
-
- if (have_ds) {
- char *t = Char(str);
- if (*t == '{') {
- Delitem(str, 0);
- Delitem(str, DOH_END);
- }
- }
-
- if (have_auto) {
- autodoc = make_autodoc(n, ad_type);
- have_auto = (autodoc && Len(autodoc) > 0);
- }
-
- if (have_auto || have_ds)
- doc = NewString("/*");
-
- if (have_auto && have_ds) { // Both autodoc and docstring are present
- Printv(doc, "\n", autodoc, "\n", str, "\n", NIL);
- } else if (!have_auto && have_ds) { // only docstring
- Printv(doc, str, NIL);
- } else if (have_auto && !have_ds) { // only autodoc
- Printv(doc, "\n", autodoc, "\n", NIL);
- } else {
- doc = NewString("");
- }
-
- if (have_auto || have_ds)
- Append(doc, "*/\n");
-
- // Save the generated strings in the parse tree in case they are used later
- // by post processing tools
- Setattr(n, "ruby:docstring", doc);
- Setattr(n, "ruby:autodoc", autodoc);
- return doc;
- }
-
- /* -----------------------------------------------------------------------------
- * addMissingParameterNames()
- * For functions that have not had nameless parameters set in the Language class.
- *
- * Inputs:
- * plist - entire parameter list
- * arg_offset - argument number for first parameter
- * Side effects:
- * The "lname" attribute in each parameter in plist will be contain a parameter name
- * ----------------------------------------------------------------------------- */
-
- void addMissingParameterNames(Node* n, ParmList *plist, int arg_offset) {
- Parm *p = plist;
- int i = arg_offset;
- while (p) {
- if (!Getattr(p, "lname")) {
- String *name = makeParameterName(n, p, i);
- Setattr(p, "lname", name);
- Delete(name);
- }
- i++;
- p = nextSibling(p);
- }
- }
-
- /* ------------------------------------------------------------
- * make_autodocParmList()
- * Generate the documentation for the function parameters
- * ------------------------------------------------------------ */
-
- String *make_autodocParmList(Node *n, bool showTypes) {
- String *doc = NewString("");
- String *pdocs = 0;
- ParmList *plist = CopyParmList(Getattr(n, "parms"));
- Parm *p;
- Parm *pnext;
- int lines = 0;
- int arg_num = is_wrapping_class() ? 1 : 0;
- const int maxwidth = 80;
-
- addMissingParameterNames(n, plist, arg_num); // for $1_name substitutions done in Swig_typemap_attach_parms
-
- Swig_typemap_attach_parms("in", plist, 0);
- Swig_typemap_attach_parms("doc", plist, 0);
-
- if (Strcmp(ParmList_protostr(plist), "void") == 0) {
- //No parameters actually
- return doc;
- }
-
- for (p = plist; p; p = pnext, arg_num++) {
-
- String *tm = Getattr(p, "tmap:in");
- if (tm) {
- pnext = Getattr(p, "tmap:in:next");
- if (checkAttribute(p, "tmap:in:numinputs", "0")) {
- continue;
- }
- } else {
- pnext = nextSibling(p);
- }
-
- String *name = 0;
- String *type = 0;
- String *value = 0;
- String *pdoc = Getattr(p, "tmap:doc");
- if (pdoc) {
- name = Getattr(p, "tmap:doc:name");
- type = Getattr(p, "tmap:doc:type");
- value = Getattr(p, "tmap:doc:value");
- }
-
- // Note: the generated name should be consistent with that in kwnames[]
- String *made_name = 0;
- if (!name) {
- name = made_name = makeParameterName(n, p, arg_num);
- }
-
- type = type ? type : Getattr(p, "type");
- value = value ? value : Getattr(p, "value");
-
- if (SwigType_isvarargs(type))
- break;
-
- // Skip the 'self' parameter which in ruby is implicit
- if ( Cmp(name, "self") == 0 )
- continue;
-
- // Make __p parameters just p (as used in STL)
- Replace( name, "__", "", DOH_REPLACE_FIRST );
-
- if (Len(doc)) {
- // add a comma to the previous one if any
- Append(doc, ", ");
-
- // Do we need to wrap a long line?
- if ((Len(doc) - lines * maxwidth) > maxwidth) {
- Printf(doc, "\n%s", tab4);
- lines += 1;
- }
- }
-
- // Do the param type too?
- Node *nn = classLookup(Getattr(p, "type"));
- String *type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0);
- if (showTypes)
- Printf(doc, "%s ", type_str);
-
- Append(doc, name);
- if (pdoc) {
- if (!pdocs)
- pdocs = NewString("Parameters:\n");
- Printf(pdocs, " %s.\n", pdoc);
- }
-
- if (value) {
- String *new_value = convertValue(value, Getattr(p, "type"));
- if (new_value) {
- value = new_value;
- } else {
- Node *lookup = Swig_symbol_clookup(value, 0);
- if (lookup)
- value = Getattr(lookup, "sym:name");
- }
- Printf(doc, "=%s", value);
- }
- Delete(type_str);
- Delete(made_name);
- }
- if (pdocs)
- Setattr(n, "feature:pdocs", pdocs);
- Delete(plist);
- return doc;
- }
-
- /* ------------------------------------------------------------
- * make_autodoc()
- * Build a docstring for the node, using parameter and other
- * info in the parse tree. If the value of the autodoc
- * attribute is "0" then do not include parameter types, if
- * it is "1" (the default) then do. If it has some other
- * value then assume it is supplied by the extension writer
- * and use it directly.
- * ------------------------------------------------------------ */
-
- String *make_autodoc(Node *n, autodoc_t ad_type) {
- int extended = 0;
- // If the function is overloaded then this function is called
- // for the last one. Rewind to the first so the docstrings are
- // in order.
- while (Getattr(n, "sym:previousSibling"))
- n = Getattr(n, "sym:previousSibling");
-
- Node *pn = Swig_methodclass(n);
- String* super_names = NewString("");
- String* class_name = Getattr(pn, "sym:name") ;
-
- if ( !class_name ) {
- class_name = NewString("");
- } else {
- class_name = Copy(class_name);
- List *baselist = Getattr(pn, "bases");
- if (baselist && Len(baselist)) {
- Iterator base = First(baselist);
- while (base.item && GetFlag(base.item, "feature:ignore")) {
- base = Next(base);
- }
-
- int count = 0;
- for ( ;base.item; ++count) {
- if ( count ) Append(super_names, ", ");
- String *basename = Getattr(base.item, "sym:name");
-
- String* basenamestr = NewString(basename);
- Node* parent = parentNode(base.item);
- while (parent)
- {
- String *parent_name = Copy( Getattr(parent, "sym:name") );
- if ( !parent_name ) {
- Node* mod = Getattr(parent, "module");
- if ( mod )
- parent_name = Copy( Getattr(mod, "name") );
- if ( parent_name )
- (Char(parent_name))[0] = (char)toupper((Char(parent_name))[0]);
- }
- if ( parent_name ) {
- Insert(basenamestr, 0, "::");
- Insert(basenamestr, 0, parent_name);
- Delete(parent_name);
- }
- parent = parentNode(parent);
- }
-
- Append(super_names, basenamestr );
- Delete(basenamestr);
- base = Next(base);
- }
- }
- }
- String* full_name;
- if ( module ) {
- full_name = NewString(module);
- if (Len(class_name) > 0)
- Append(full_name, "::");
- }
- else
- full_name = NewString("");
- Append(full_name, class_name);
-
- String* symname = Getattr(n, "sym:name");
- if ( Getattr( special_methods, symname ) )
- symname = Getattr( special_methods, symname );
-
- String* methodName = NewString(full_name);
- Append(methodName, symname);
-
-
- // Each overloaded function will try to get documented,
- // so we keep the name of the last overloaded function and its type.
- // Documenting just from functionWrapper() is not possible as
- // sym:name has already been changed to include the class name
- if ( last_mode == ad_type && Cmp(methodName, last_autodoc) == 0 ) {
- Delete(full_name);
- Delete(class_name);
- Delete(super_names);
- Delete(methodName);
- return NewString("");
- }
-
-
- last_mode = ad_type;
- last_autodoc = Copy(methodName);
-
- String *doc = NewString("");
- int counter = 0;
- bool skipAuto = false;
- Node* on = n;
- for ( ; n; ++counter ) {
- String *type_str = NULL;
- skipAuto = false;
- bool showTypes = false;
- String *autodoc = Getattr(n, "feature:autodoc");
- autodoc_l dlevel = autodoc_level(autodoc);
- switch (dlevel) {
- case NO_AUTODOC:
- break;
- case NAMES_AUTODOC:
- showTypes = false;
- break;
- case TYPES_AUTODOC:
- showTypes = true;
- break;
- case EXTEND_AUTODOC:
- extended = 1;
- showTypes = false;
- break;
- case EXTEND_TYPES_AUTODOC:
- extended = 1;
- showTypes = true;
- break;
- case STRING_AUTODOC:
- skipAuto = true;
- break;
- }
-
- SwigType *type = Getattr(n, "type");
-
- if (type) {
- if (Strcmp(type, "void") == 0) {
- type_str = NULL;
- } else {
- SwigType *qt = SwigType_typedef_resolve_all(type);
- if (SwigType_isenum(qt)) {
- type_str = NewString("int");
- } else {
- Node *nn = classLookup(type);
- type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0);
- }
- }
- }
-
- if (counter == 0) {
- switch (ad_type) {
- case AUTODOC_CLASS:
- Printf(doc, " Document-class: %s", full_name);
- if ( Len(super_names) > 0 )
- Printf( doc, " < %s", super_names);
- Append(doc, "\n\n");
- break;
- case AUTODOC_CTOR:
- Printf(doc, " Document-method: %s.new\n\n", full_name);
- break;
-
- case AUTODOC_DTOR:
- break;
-
- case AUTODOC_STATICFUNC:
- Printf(doc, " Document-method: %s.%s\n\n", full_name, symname);
- break;
-
- case AUTODOC_FUNC:
- case AUTODOC_METHOD:
- case AUTODOC_GETTER:
- Printf(doc, " Document-method: %s.%s\n\n", full_name, symname);
- break;
- case AUTODOC_SETTER:
- Printf(doc, " Document-method: %s.%s=\n\n", full_name, symname);
- break;
- case AUTODOC_NONE:
- break;
- }
- }
-
- if (skipAuto) {
- if ( counter == 0 ) Printf(doc, " call-seq:\n");
- switch( ad_type )
- {
- case AUTODOC_STATICFUNC:
- case AUTODOC_FUNC:
- case AUTODOC_METHOD:
- case AUTODOC_GETTER:
- {
- String *paramList = make_autodocParmList(n, showTypes);
- if (Len(paramList))
- Printf(doc, " %s(%s)", symname, paramList);
- else
- Printf(doc, " %s", symname);
- if (type_str)
- Printf(doc, " -> %s", type_str);
- break;
- }
- case AUTODOC_SETTER:
- {
- Printf(doc, " %s=(x)", symname);
- if (type_str)
- Printf(doc, " -> %s", type_str);
- break;
- }
- default:
- break;
- }
- } else {
- switch (ad_type) {
- case AUTODOC_CLASS:
- {
- // Only do the autodoc if there isn't a docstring for the class
- String *str = Getattr(n, "feature:docstring");
- if (counter == 0 && (str == 0 || Len(str) == 0)) {
- if (CPlusPlus) {
- Printf(doc, " Proxy of C++ %s class", full_name);
- } else {
- Printf(doc, " Proxy of C %s struct", full_name);
- }
- }
- }
- break;
- case AUTODOC_CTOR:
- if (counter == 0)
- Printf(doc, " call-seq:\n");
- if (Strcmp(class_name, symname) == 0) {
- String *paramList = make_autodocParmList(n, showTypes);
- if (Len(paramList))
- Printf(doc, " %s.new(%s)", class_name, paramList);
- else
- Printf(doc, " %s.new", class_name);
- } else {
- Printf(doc, " %s.new(%s)", class_name, make_autodocParmList(n, showTypes));
- }
- break;
-
- case AUTODOC_DTOR:
- break;
-
- case AUTODOC_STATICFUNC:
- case AUTODOC_FUNC:
- case AUTODOC_METHOD:
- case AUTODOC_GETTER:
- {
- if (counter == 0)
- Printf(doc, " call-seq:\n");
- String *paramList = make_autodocParmList(n, showTypes);
- if (Len(paramList))
- Printf(doc, " %s(%s)", symname, paramList);
- else
- Printf(doc, " %s", symname);
- if (type_str)
- Printf(doc, " -> %s", type_str);
- break;
- }
- case AUTODOC_SETTER:
- {
- Printf(doc, " call-seq:\n");
- Printf(doc, " %s=(x)", symname);
- if (type_str)
- Printf(doc, " -> %s", type_str);
- break;
- }
- case AUTODOC_NONE:
- break;
- }
- }
-
- // if it's overloaded then get the next decl and loop around again
- n = Getattr(n, "sym:nextSibling");
- if (n)
- Append(doc, "\n");
- Delete(type_str);
- }
-
- Printf(doc, "\n\n");
- if (!skipAuto) {
- switch (ad_type) {
- case AUTODOC_CLASS:
- case AUTODOC_DTOR:
- break;
- case AUTODOC_CTOR:
- Printf(doc, "Class constructor.\n");
- break;
- case AUTODOC_STATICFUNC:
- Printf(doc, "A class method.\n");
- break;
- case AUTODOC_FUNC:
- Printf(doc, "A module function.\n");
- break;
- case AUTODOC_METHOD:
- Printf(doc, "An instance method.\n");
- break;
- case AUTODOC_GETTER:
- Printf(doc, "Get value of attribute.\n");
- break;
- case AUTODOC_SETTER:
- Printf(doc, "Set new value for attribute.\n");
- break;
- case AUTODOC_NONE:
- break;
- }
- }
-
-
- n = on;
- while ( n ) {
- String *autodoc = Getattr(n, "feature:autodoc");
- autodoc_l dlevel = autodoc_level(autodoc);
-
- switch (dlevel) {
- case NO_AUTODOC:
- case NAMES_AUTODOC:
- case TYPES_AUTODOC:
- extended = 0;
- break;
- case STRING_AUTODOC:
- extended = 2;
- Replaceall( autodoc, "$class", class_name );
- Printv(doc, autodoc, ".", NIL);
- break;
- case EXTEND_AUTODOC:
- case EXTEND_TYPES_AUTODOC:
- extended = 1;
- break;
- }
-
-
- if (extended) {
- String *pdocs = Getattr(n, "feature:pdocs");
- if (pdocs) {
- Printv(doc, "\n\n", pdocs, NULL);
- break;
- }
- if ( extended == 2 ) break;
- }
- n = Getattr(n, "sym:nextSibling");
- }
-
- Delete(full_name);
- Delete(class_name);
- Delete(super_names);
- Delete(methodName);
-
- return doc;
- }
-
- /* ------------------------------------------------------------
- * convertValue()
- * Check if string v can be a Ruby value literal,
- * (eg. number or string), or translate it to a Ruby literal.
- * ------------------------------------------------------------ */
- String *convertValue(String *v, SwigType *t) {
- if (v && Len(v) > 0) {
- char fc = (Char(v))[0];
- if (('0' <= fc && fc <= '9') || '\'' == fc || '"' == fc) {
- /* number or string (or maybe NULL pointer) */
- if (SwigType_ispointer(t) && Strcmp(v, "0") == 0)
- return NewString("None");
- else
- return v;
- }
- if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0)
- return SwigType_ispointer(t) ? NewString("nil") : NewString("0");
- if (Strcmp(v, "true") == 0 || Strcmp(v, "TRUE") == 0)
- return NewString("True");
- if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0)
- return NewString("False");
- }
- return 0;
- }
-
-public:
-
- /* ---------------------------------------------------------------------
- * RUBY()
- *
- * Initialize member data
- * --------------------------------------------------------------------- */
- RUBY() :
- module(0),
- modvar(0),
- feature(0),
- prefix(0),
- current(0),
- classes(0),
- klass(0),
- special_methods(0),
- f_directors(0),
- f_directors_h(0),
- f_directors_helpers(0),
- f_begin(0),
- f_runtime(0),
- f_runtime_h(0),
- f_header(0),
- f_wrappers(0),
- f_init(0),
- f_initbeforefunc(0),
- useGlobalModule(false),
- multipleInheritance(false),
- last_mode(AUTODOC_NONE),
- last_autodoc(NewString("")) {
- current = NO_CPP;
- director_prot_ctor_code = NewString("");
- Printv(director_prot_ctor_code,
- "if ( $comparison ) { /* subclassed */\n",
- " $director_new \n",
- "} else {\n", " rb_raise(rb_eRuntimeError,\"accessing abstract class or protected constructor\"); \n", " return Qnil;\n", "}\n", NIL);
- director_multiple_inheritance = 0;
- director_language = 1;
- }
-
- /* ---------------------------------------------------------------------
- * main()
- *
- * Parse command line options and initializes variables.
- * --------------------------------------------------------------------- */
-
- virtual void main(int argc, char *argv[]) {
-
- int autorename = 0;
-
- /* Set location of SWIG library */
- SWIG_library_directory("ruby");
-
- /* Look for certain command line options */
- for (int i = 1; i < argc; i++) {
- if (argv[i]) {
- if (strcmp(argv[i], "-initname") == 0) {
- if (argv[i + 1]) {
- char *name = argv[i + 1];
- feature = NewString(name);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- }
- else if (strcmp(argv[i], "-feature") == 0) {
- fprintf( stderr, "Warning: Ruby -feature option is deprecated, "
- "please use -initname instead.\n");
- if (argv[i + 1]) {
- char *name = argv[i + 1];
- feature = NewString(name);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-globalmodule") == 0) {
- useGlobalModule = true;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-minherit") == 0) {
- multipleInheritance = true;
- director_multiple_inheritance = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-autorename") == 0) {
- autorename = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-noautorename") == 0) {
- autorename = 0;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-prefix") == 0) {
- if (argv[i + 1]) {
- char *name = argv[i + 1];
- prefix = NewString(name);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-help") == 0) {
- Printf(stdout, "%s\n", usage);
- } else if (strcmp(argv[i], "-cppcast") == 0) {
- Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nocppcast") == 0) {
- Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
- Swig_mark_arg(i);
- Exit(EXIT_FAILURE);
- }
- }
- }
-
- if (autorename) {
- /* Turn on the autorename mode */
- Preprocessor_define((DOH *) "SWIG_RUBY_AUTORENAME", 0);
- }
-
- /* Add a symbol to the parser for conditional compilation */
- Preprocessor_define("SWIGRUBY 1", 0);
-
- /* Add typemap definitions */
- SWIG_typemap_lang("ruby");
- SWIG_config_file("ruby.swg");
- allow_overloading();
- }
-
- /**
- * Generate initialization code to define the Ruby module(s),
- * accounting for nested modules as necessary.
- */
- void defineRubyModule() {
- List *modules = Split(module, ':', INT_MAX);
- if (modules != 0 && Len(modules) > 0) {
- String *mv = 0;
- Iterator m;
- m = First(modules);
- while (m.item) {
- if (Len(m.item) > 0) {
- if (mv != 0) {
- Printv(f_init, tab4, modvar, " = rb_define_module_under(", modvar, ", \"", m.item, "\");\n", NIL);
- } else {
- Printv(f_init, tab4, modvar, " = rb_define_module(\"", m.item, "\");\n", NIL);
- mv = NewString(modvar);
- }
- }
- m = Next(m);
- }
- Delete(mv);
- Delete(modules);
- }
- }
-
- void registerMagicMethods() {
-
- special_methods = NewHash();
-
- /* Python->Ruby style special method name. */
- /* Basic */
- Setattr(special_methods, "__repr__", "inspect");
- Setattr(special_methods, "__str__", "to_s");
- Setattr(special_methods, "__cmp__", "<=>");
- Setattr(special_methods, "__hash__", "hash");
- Setattr(special_methods, "__nonzero__", "nonzero?");
-
- /* Callable */
- Setattr(special_methods, "__call__", "call");
-
- /* Collection */
- Setattr(special_methods, "__len__", "length");
- Setattr(special_methods, "__getitem__", "[]");
- Setattr(special_methods, "__setitem__", "[]=");
-
- /* Operators */
- Setattr(special_methods, "__add__", "+");
- Setattr(special_methods, "__pos__", "+@");
- Setattr(special_methods, "__sub__", "-");
- Setattr(special_methods, "__neg__", "-@");
- Setattr(special_methods, "__mul__", "*");
- Setattr(special_methods, "__div__", "/");
- Setattr(special_methods, "__mod__", "%");
- Setattr(special_methods, "__lshift__", "<<");
- Setattr(special_methods, "__rshift__", ">>");
- Setattr(special_methods, "__and__", "&");
- Setattr(special_methods, "__or__", "|");
- Setattr(special_methods, "__xor__", "^");
- Setattr(special_methods, "__invert__", "~");
- Setattr(special_methods, "__lt__", "<");
- Setattr(special_methods, "__le__", "<=");
- Setattr(special_methods, "__gt__", ">");
- Setattr(special_methods, "__ge__", ">=");
- Setattr(special_methods, "__eq__", "==");
-
- /* Other numeric */
- Setattr(special_methods, "__divmod__", "divmod");
- Setattr(special_methods, "__pow__", "**");
- Setattr(special_methods, "__abs__", "abs");
- Setattr(special_methods, "__int__", "to_i");
- Setattr(special_methods, "__float__", "to_f");
- Setattr(special_methods, "__coerce__", "coerce");
- }
-
- /* ---------------------------------------------------------------------
- * top()
- * --------------------------------------------------------------------- */
-
- virtual int top(Node *n) {
-
- String *mod_docstring = NULL;
-
- /**
- * See if any Ruby module options have been specified as options
- * to the %module directive.
- */
- Node *swigModule = Getattr(n, "module");
- if (swigModule) {
- Node *options = Getattr(swigModule, "options");
- if (options) {
- if (Getattr(options, "directors")) {
- allow_directors();
- }
- if (Getattr(options, "dirprot")) {
- allow_dirprot();
- }
- if (Getattr(options, "ruby_globalmodule")) {
- useGlobalModule = true;
- }
- if (Getattr(options, "ruby_minherit")) {
- multipleInheritance = true;
- director_multiple_inheritance = 1;
- }
- mod_docstring = Getattr(options, "docstring");
- }
- }
-
- /* Set comparison with none for ConstructorToFunction */
-
-
- setSubclassInstanceCheck(NewStringf("strcmp(rb_obj_classname(self), classname) != 0"));
- // setSubclassInstanceCheck(NewString("CLASS_OF(self) != cFoo.klass"));
-
- /* Initialize all of the output files */
- String *outfile = Getattr(n, "outfile");
- String *outfile_h = Getattr(n, "outfile_h");
-
- if (!outfile) {
- Printf(stderr, "Unable to determine outfile\n");
- Exit(EXIT_FAILURE);
- }
-
- f_begin = NewFile(outfile, "w", SWIG_output_files());
- if (!f_begin) {
- FileErrorDisplay(outfile);
- Exit(EXIT_FAILURE);
- }
-
- f_runtime = NewString("");
- f_init = NewString("");
- f_header = NewString("");
- f_wrappers = NewString("");
- f_directors_h = NewString("");
- f_directors = NewString("");
- f_directors_helpers = NewString("");
- f_initbeforefunc = NewString("");
-
- if (directorsEnabled()) {
- if (!outfile_h) {
- Printf(stderr, "Unable to determine outfile_h\n");
- Exit(EXIT_FAILURE);
- }
- f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
- if (!f_runtime_h) {
- FileErrorDisplay(outfile_h);
- Exit(EXIT_FAILURE);
- }
- }
-
- /* Register file targets with the SWIG file handler */
- Swig_register_filebyname("header", f_header);
- Swig_register_filebyname("wrapper", f_wrappers);
- Swig_register_filebyname("begin", f_begin);
- Swig_register_filebyname("runtime", f_runtime);
- Swig_register_filebyname("init", f_init);
- Swig_register_filebyname("director", f_directors);
- Swig_register_filebyname("director_h", f_directors_h);
- Swig_register_filebyname("director_helpers", f_directors_helpers);
- Swig_register_filebyname("initbeforefunc", f_initbeforefunc);
-
- modvar = 0;
- current = NO_CPP;
- klass = 0;
- classes = NewHash();
-
- registerMagicMethods();
-
- Swig_banner(f_begin);
-
- Swig_obligatory_macros(f_runtime, "RUBY");
-
- if (directorsEnabled()) {
- Printf(f_runtime, "#define SWIG_DIRECTORS\n");
- }
-
- Printf(f_runtime, "\n");
-
- /* typedef void *VALUE */
- SwigType *value = NewSwigType(T_VOID);
- SwigType_add_pointer(value);
- SwigType_typedef(value, "VALUE");
- Delete(value);
-
- /* Set module name */
- set_module(Char(Getattr(n, "name")));
-
- if (directorsEnabled()) {
- /* Build a version of the module name for use in a C macro name. */
- String *module_macro = Copy(module);
- Replaceall(module_macro, "::", "__");
-
- Swig_banner(f_directors_h);
- Printf(f_directors_h, "\n");
- Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module_macro);
- Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module_macro);
- Printf(f_directors_h, "namespace Swig {\n");
- Printf(f_directors_h, " class Director;\n");
- Printf(f_directors_h, "}\n\n");
-
- Printf(f_directors_helpers, "/* ---------------------------------------------------\n");
- Printf(f_directors_helpers, " * C++ director class helpers\n");
- Printf(f_directors_helpers, " * --------------------------------------------------- */\n\n");
-
- Printf(f_directors, "\n\n");
- Printf(f_directors, "/* ---------------------------------------------------\n");
- Printf(f_directors, " * C++ director class methods\n");
- Printf(f_directors, " * --------------------------------------------------- */\n\n");
- if (outfile_h) {
- String *filename = Swig_file_filename(outfile_h);
- Printf(f_directors, "#include \"%s\"\n\n", filename);
- Delete(filename);
- }
-
- Delete(module_macro);
- }
-
- Printf(f_header, "#define SWIG_init Init_%s\n", feature);
- Printf(f_header, "#define SWIG_name \"%s\"\n\n", module);
-
- if (mod_docstring) {
- if (Len(mod_docstring)) {
- Printf(f_header, "/*\n Document-module: %s\n\n%s\n*/\n", module, mod_docstring);
- }
- Delete(mod_docstring);
- mod_docstring = NULL;
- }
-
- Printf(f_header, "static VALUE %s;\n", modvar);
-
- /* Start generating the initialization function */
- String* docs = docstring(n, AUTODOC_CLASS);
- Printf(f_init, "/*\n%s\n*/", docs );
- Printv(f_init, "\n", "#ifdef __cplusplus\n", "extern \"C\"\n", "#endif\n", "SWIGEXPORT void Init_", feature, "(void) {\n", "size_t i;\n", "\n", NIL);
-
- Printv(f_init, tab4, "SWIG_InitRuntime();\n", NIL);
-
- if (!useGlobalModule)
- defineRubyModule();
-
- Printv(f_init, "\n", "SWIG_InitializeModule(0);\n", "for (i = 0; i < swig_module.size; i++) {\n", "SWIG_define_class(swig_module.types[i]);\n", "}\n", NIL);
- Printf(f_init, "\n");
-
- /* Initialize code to keep track of objects */
- Printf(f_init, "SWIG_RubyInitializeTrackings();\n");
-
- Language::top(n);
-
- if (directorsEnabled()) {
- // Insert director runtime into the f_runtime file (make it occur before %header section)
- Swig_insert_file("director_common.swg", f_runtime);
- Swig_insert_file("director.swg", f_runtime);
- }
-
- /* Finish off our init function */
- Printf(f_init, "}\n");
- SwigType_emit_type_table(f_runtime, f_wrappers);
-
- /* Close all of the files */
- Dump(f_runtime, f_begin);
- Dump(f_header, f_begin);
-
- if (directorsEnabled()) {
- Dump(f_directors_helpers, f_begin);
- Dump(f_directors, f_begin);
- Dump(f_directors_h, f_runtime_h);
- Printf(f_runtime_h, "\n");
- Printf(f_runtime_h, "#endif\n");
- Delete(f_runtime_h);
- }
-
- Dump(f_wrappers, f_begin);
- Dump(f_initbeforefunc, f_begin);
- Wrapper_pretty_print(f_init, f_begin);
-
- Delete(f_header);
- Delete(f_wrappers);
- Delete(f_init);
- Delete(f_initbeforefunc);
- Delete(f_runtime);
- Delete(f_begin);
-
- return SWIG_OK;
- }
-
- /* -----------------------------------------------------------------------------
- * importDirective()
- * ----------------------------------------------------------------------------- */
-
- virtual int importDirective(Node *n) {
- String *modname = Getattr(n, "module");
- if (modname) {
- if (prefix) {
- Insert(modname, 0, prefix);
- }
-
- List *modules = Split(modname, ':', INT_MAX);
- if (modules && Len(modules) > 0) {
- modname = NewString("");
- String *last = NULL;
- Iterator m = First(modules);
- while (m.item) {
- if (Len(m.item) > 0) {
- if (last) {
- Append(modname, "/");
- }
- Append(modname, m.item);
- last = m.item;
- }
- m = Next(m);
- }
- Printf(f_init, "rb_require(\"%s\");\n", modname);
- Delete(modname);
- }
- Delete(modules);
- }
- return Language::importDirective(n);
- }
-
- /* ---------------------------------------------------------------------
- * set_module(const char *mod_name)
- *
- * Sets the module name. Does nothing if it's already set (so it can
- * be overridden as a command line option).
- *---------------------------------------------------------------------- */
-
- void set_module(const char *s) {
- String *mod_name = NewString(s);
- if (module == 0) {
- /* Start with the empty string */
- module = NewString("");
-
- if (prefix) {
- Insert(mod_name, 0, prefix);
- }
-
- /* Account for nested modules */
- List *modules = Split(mod_name, ':', INT_MAX);
- if (modules != 0 && Len(modules) > 0) {
- String *last = 0;
- Iterator m = First(modules);
- while (m.item) {
- if (Len(m.item) > 0) {
- String *cap = NewString(m.item);
- (Char(cap))[0] = (char)toupper((Char(cap))[0]);
- if (last != 0) {
- Append(module, "::");
- }
- Append(module, cap);
- last = m.item;
- }
- m = Next(m);
- }
- if (last) {
- if (feature == 0) {
- feature = Copy(last);
- }
- (Char(last))[0] = (char)toupper((Char(last))[0]);
- modvar = NewStringf("m%s", last);
- }
- }
- Delete(modules);
- }
- Delete(mod_name);
- }
-
- /* --------------------------------------------------------------------------
- * nativeWrapper()
- * -------------------------------------------------------------------------- */
- virtual int nativeWrapper(Node *n) {
- String *funcname = Getattr(n, "wrap:name");
- Swig_warning(WARN_LANG_NATIVE_UNIMPL, input_file, line_number, "Adding native function %s not supported (ignored).\n", funcname);
- return SWIG_NOWRAP;
- }
-
- /**
- * Process the comma-separated list of aliases (if any).
- */
- void defineAliases(Node *n, const_String_or_char_ptr iname) {
- String *aliasv = Getattr(n, "feature:alias");
- if (aliasv) {
- List *aliases = Split(aliasv, ',', INT_MAX);
- if (aliases && Len(aliases) > 0) {
- Iterator alias = First(aliases);
- while (alias.item) {
- if (Len(alias.item) > 0) {
- if (current == NO_CPP) {
- if (useGlobalModule) {
- Printv(f_init, tab4, "rb_define_alias(rb_cObject, \"", alias.item, "\", \"", iname, "\");\n", NIL);
- } else {
- Printv(f_init, tab4, "rb_define_alias(rb_singleton_class(", modvar, "), \"", alias.item, "\", \"", iname, "\");\n", NIL);
- }
- } else if (multipleInheritance) {
- Printv(klass->init, tab4, "rb_define_alias(", klass->mImpl, ", \"", alias.item, "\", \"", iname, "\");\n", NIL);
- } else {
- Printv(klass->init, tab4, "rb_define_alias(", klass->vname, ", \"", alias.item, "\", \"", iname, "\");\n", NIL);
- }
- }
- alias = Next(alias);
- }
- }
- Delete(aliases);
- }
- }
-
- /* ---------------------------------------------------------------------
- * create_command(Node *n, char *iname)
- *
- * Creates a new command from a C function.
- * iname = Name of function in scripting language
- *
- * A note about what "protected" and "private" mean in Ruby:
- *
- * A private method is accessible only within the class or its subclasses,
- * and it is callable only in "function form", with 'self' (implicit or
- * explicit) as a receiver.
- *
- * A protected method is callable only from within its class, but unlike
- * a private method, it can be called with a receiver other than self, such
- * as another instance of the same class.
- * --------------------------------------------------------------------- */
-
- void create_command(Node *n, const_String_or_char_ptr iname) {
-
- String *alloc_func = Swig_name_wrapper(iname);
- String *wname = Swig_name_wrapper(iname);
- if (CPlusPlus) {
- Insert(wname, 0, "VALUEFUNC(");
- Append(wname, ")");
- }
- if (current != NO_CPP)
- iname = klass->strip(iname);
- if (Getattr(special_methods, iname)) {
- iname = GetChar(special_methods, iname);
- }
-
- String *s = NewString("");
- String *temp = NewString("");
-
-#ifdef SWIG_PROTECTED_TARGET_METHODS
- const char *rb_define_method = is_public(n) ? "rb_define_method" : "rb_define_protected_method";
-#else
- const char *rb_define_method = "rb_define_method";
-#endif
- switch (current) {
- case MEMBER_FUNC:
- {
- if (multipleInheritance) {
- Printv(klass->init, tab4, rb_define_method, "(", klass->mImpl, ", \"", iname, "\", ", wname, ", -1);\n", NIL);
- } else {
- Printv(klass->init, tab4, rb_define_method, "(", klass->vname, ", \"", iname, "\", ", wname, ", -1);\n", NIL);
- }
- }
- break;
- case CONSTRUCTOR_ALLOCATE:
- Printv(s, tab4, "rb_define_alloc_func(", klass->vname, ", ", alloc_func, ");\n", NIL);
- Replaceall(klass->init, "$allocator", s);
- break;
- case CONSTRUCTOR_INITIALIZE:
- Printv(s, tab4, rb_define_method, "(", klass->vname, ", \"initialize\", ", wname, ", -1);\n", NIL);
- Replaceall(klass->init, "$initializer", s);
- break;
- case MEMBER_VAR:
- Append(temp, iname);
- /* Check for _set or _get at the end of the name. */
- if (Len(temp) > 4) {
- const char *p = Char(temp) + (Len(temp) - 4);
- if (strcmp(p, "_set") == 0) {
- Delslice(temp, Len(temp) - 4, DOH_END);
- Append(temp, "=");
- } else if (strcmp(p, "_get") == 0) {
- Delslice(temp, Len(temp) - 4, DOH_END);
- }
- }
- if (multipleInheritance) {
- Printv(klass->init, tab4, "rb_define_method(", klass->mImpl, ", \"", temp, "\", ", wname, ", -1);\n", NIL);
- } else {
- Printv(klass->init, tab4, "rb_define_method(", klass->vname, ", \"", temp, "\", ", wname, ", -1);\n", NIL);
- }
- break;
- case STATIC_FUNC:
- Printv(klass->init, tab4, "rb_define_singleton_method(", klass->vname, ", \"", iname, "\", ", wname, ", -1);\n", NIL);
- break;
- case NO_CPP:
- if (!useGlobalModule) {
- Printv(s, tab4, "rb_define_module_function(", modvar, ", \"", iname, "\", ", wname, ", -1);\n", NIL);
- Printv(f_init, s, NIL);
- } else {
- Printv(s, tab4, "rb_define_global_function(\"", iname, "\", ", wname, ", -1);\n", NIL);
- Printv(f_init, s, NIL);
- }
- break;
- case DESTRUCTOR:
- case CLASS_CONST:
- case STATIC_VAR:
- default:
- assert(false); // Should not have gotten here for these types
- }
-
- defineAliases(n, iname);
-
- Delete(temp);
- Delete(s);
- Delete(wname);
- Delete(alloc_func);
- }
-
- /* ---------------------------------------------------------------------
- * applyInputTypemap()
- *
- * Look up the appropriate "in" typemap for this parameter (p),
- * substitute the correct strings for the typemap parameters, and dump the
- * resulting code to the wrapper file.
- * --------------------------------------------------------------------- */
-
- Parm *applyInputTypemap(Parm *p, String *source, Wrapper *f, String *symname) {
- String *tm;
- SwigType *pt = Getattr(p, "type");
- if ((tm = Getattr(p, "tmap:in"))) {
- Replaceall(tm, "$input", source);
- Replaceall(tm, "$symname", symname);
-
- if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
- Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
- } else {
- Replaceall(tm, "$disown", "0");
- }
-
- Setattr(p, "emit:input", Copy(source));
- Printf(f->code, "%s\n", tm);
- p = Getattr(p, "tmap:in:next");
- } else {
- Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
- p = nextSibling(p);
- }
- return p;
- }
-
- Parm *skipIgnoredArgs(Parm *p) {
- while (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- }
- return p;
- }
-
- /* ---------------------------------------------------------------------
- * marshalInputArgs()
- *
- * Process all of the arguments passed into the scripting language
- * method and convert them into C/C++ function arguments using the
- * supplied typemaps.
- * --------------------------------------------------------------------- */
-
- void marshalInputArgs(Node *n, ParmList *l, int numarg, int numreq, String *kwargs, bool allow_kwargs, Wrapper *f) {
- int i;
- Parm *p;
- String *tm;
- String *source;
-
- source = NewString("");
-
- bool ctor_director = (current == CONSTRUCTOR_INITIALIZE && Swig_directorclass(n));
-
- /**
- * The 'start' value indicates which of the C/C++ function arguments
- * produced here corresponds to the first value in Ruby's argv[] array.
- * The value of start is either zero or one. If start is zero, then
- * the first argument (with name arg1) is based on the value of argv[0].
- * If start is one, then arg1 is based on the value of argv[1].
- */
- int start = (current == MEMBER_FUNC || current == MEMBER_VAR || ctor_director) ? 1 : 0;
-
- int varargs = emit_isvarargs(l);
-
- Printf(kwargs, "{ ");
- for (i = 0, p = l; i < numarg; i++) {
-
- p = skipIgnoredArgs(p);
-
- String *pn = Getattr(p, "name");
-
- /* Produce string representation of source argument */
- Clear(source);
-
- /* First argument is a special case */
- if (i == 0) {
- Printv(source, (start == 0) ? "argv[0]" : "self", NIL);
- } else {
- Printf(source, "argv[%d]", i - start);
- }
-
- if (i >= (numreq)) { /* Check if parsing an optional argument */
- Printf(f->code, " if (argc > %d) {\n", i - start);
- }
-
- /* Record argument name for keyword argument handling */
- if (Len(pn)) {
- Printf(kwargs, "\"%s\",", pn);
- } else {
- Printf(kwargs, "\"arg%d\",", i + 1);
- }
-
- /* Look for an input typemap */
- p = applyInputTypemap(p, source, f, Getattr(n, "name"));
- if (i >= numreq) {
- Printf(f->code, "}\n");
- }
- }
-
- /* Finish argument marshalling */
- Printf(kwargs, " NULL }");
- if (allow_kwargs) {
-// kwarg support not implemented
-// Printv(f->locals, tab4, "const char *kwnames[] = ", kwargs, ";\n", NIL);
- }
-
- /* Trailing varargs */
- if (varargs) {
- if (p && (tm = Getattr(p, "tmap:in"))) {
- Clear(source);
- Printf(source, "argv[%d]", i - start);
- Replaceall(tm, "$input", source);
- Setattr(p, "emit:input", Copy(source));
- Printf(f->code, "if (argc > %d) {\n", i - start);
- Printv(f->code, tm, "\n", NIL);
- Printf(f->code, "}\n");
- }
- }
-
- Delete(source);
- }
-
- /* ---------------------------------------------------------------------
- * insertConstraintCheckingCode(ParmList *l, Wrapper *f)
- *
- * Checks each of the parameters in the parameter list for a "check"
- * typemap and (if it finds one) inserts the typemapping code into
- * the function wrapper.
- * --------------------------------------------------------------------- */
-
- void insertConstraintCheckingCode(ParmList *l, Wrapper *f) {
- Parm *p;
- String *tm;
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:check"))) {
- Printv(f->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:check:next");
- } else {
- p = nextSibling(p);
- }
- }
- }
-
- /* ---------------------------------------------------------------------
- * insertCleanupCode(ParmList *l, String *cleanup)
- *
- * Checks each of the parameters in the parameter list for a "freearg"
- * typemap and (if it finds one) inserts the typemapping code into
- * the function wrapper.
- * --------------------------------------------------------------------- */
-
- void insertCleanupCode(ParmList *l, String *cleanup) {
- String *tm;
- for (Parm *p = l; p;) {
- if ((tm = Getattr(p, "tmap:freearg"))) {
- if (Len(tm) != 0) {
- Printv(cleanup, tm, "\n", NIL);
- }
- p = Getattr(p, "tmap:freearg:next");
- } else {
- p = nextSibling(p);
- }
- }
- }
-
- /* ---------------------------------------------------------------------
- * insertArgOutputCode(ParmList *l, String *outarg, int& need_result)
- *
- * Checks each of the parameters in the parameter list for a "argout"
- * typemap and (if it finds one) inserts the typemapping code into
- * the function wrapper.
- * --------------------------------------------------------------------- */
-
- void insertArgOutputCode(ParmList *l, String *outarg, int &need_result) {
- String *tm;
- for (Parm *p = l; p;) {
- if ((tm = Getattr(p, "tmap:argout"))) {
- Replaceall(tm, "$result", "vresult");
- Replaceall(tm, "$arg", Getattr(p, "emit:input"));
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
-
- Printv(outarg, tm, "\n", NIL);
- need_result += 1;
- p = Getattr(p, "tmap:argout:next");
- } else {
- p = nextSibling(p);
- }
- }
- }
-
- /* ---------------------------------------------------------------------
- * validIdentifier()
- *
- * Is this a valid identifier in the scripting language?
- * Ruby method names can include any combination of letters, numbers
- * and underscores. A Ruby method name may optionally end with
- * a question mark ("?"), exclamation point ("!") or equals sign ("=").
- *
- * Methods whose names end with question marks are, by convention,
- * predicate methods that return true or false (e.g. Array#empty?).
- *
- * Methods whose names end with exclamation points are, by convention,
- * called bang methods that modify the instance in place (e.g. Array#sort!).
- *
- * Methods whose names end with an equals sign are attribute setters
- * (e.g. Thread#critical=).
- * --------------------------------------------------------------------- */
-
- virtual int validIdentifier(String *s) {
- char *c = Char(s);
- while (*c) {
- if (!(isalnum(*c) || (*c == '_') || (*c == '?') || (*c == '!') || (*c == '=')))
- return 0;
- c++;
- }
- return 1;
- }
-
- /* ---------------------------------------------------------------------
- * functionWrapper()
- *
- * Create a function declaration and register it with the interpreter.
- * --------------------------------------------------------------------- */
-
- virtual int functionWrapper(Node *n) {
-
- String *nodeType;
- bool destructor;
-
- String *symname = Copy(Getattr(n, "sym:name"));
- SwigType *t = Getattr(n, "type");
- ParmList *l = Getattr(n, "parms");
- int director_method = 0;
- String *tm;
-
- int need_result = 0;
-
- /* Ruby needs no destructor wrapper */
- if (current == DESTRUCTOR)
- return SWIG_NOWRAP;
-
- nodeType = Getattr(n, "nodeType");
- destructor = (!Cmp(nodeType, "destructor"));
-
- /* If the C++ class constructor is overloaded, we only want to
- * write out the "new" singleton method once since it is always
- * the same. (It's the "initialize" method that will handle the
- * overloading). */
-
- if (current == CONSTRUCTOR_ALLOCATE && Swig_symbol_isoverloaded(n) && Getattr(n, "sym:nextSibling") != 0)
- return SWIG_OK;
-
- String *overname = 0;
- if (Getattr(n, "sym:overloaded")) {
- overname = Getattr(n, "sym:overname");
- } else {
- if (!addSymbol(symname, n))
- return SWIG_ERROR;
- }
-
- String *cleanup = NewString("");
- String *outarg = NewString("");
- String *kwargs = NewString("");
- Wrapper *f = NewWrapper();
-
- /* Rename predicate methods */
- if (GetFlag(n, "feature:predicate")) {
- Append(symname, "?");
- }
-
- /* Rename bang methods */
- if (GetFlag(n, "feature:bang")) {
- Append(symname, "!");
- }
-
- /* Determine the name of the SWIG wrapper function */
- String *wname = Swig_name_wrapper(symname);
- if (overname && current != CONSTRUCTOR_ALLOCATE) {
- Append(wname, overname);
- }
-
- /* Emit arguments */
- if (current != CONSTRUCTOR_ALLOCATE) {
- emit_parameter_variables(l, f);
- }
-
- /* Attach standard typemaps */
- if (current != CONSTRUCTOR_ALLOCATE) {
- emit_attach_parmmaps(l, f);
- }
- Setattr(n, "wrap:parms", l);
-
- /* Get number of arguments */
- int numarg = emit_num_arguments(l);
- int numreq = emit_num_required(l);
- int varargs = emit_isvarargs(l);
- bool allow_kwargs = GetFlag(n, "feature:kwargs") ? true : false;
-
- bool ctor_director = (current == CONSTRUCTOR_INITIALIZE && Swig_directorclass(n));
- int start = (current == MEMBER_FUNC || current == MEMBER_VAR || ctor_director) ? 1 : 0;
-
- /* Now write the wrapper function itself */
- if (current == CONSTRUCTOR_ALLOCATE) {
- Printv(f->def, "SWIGINTERN VALUE\n", NIL);
- Printf(f->def, "#ifdef HAVE_RB_DEFINE_ALLOC_FUNC\n");
- Printv(f->def, wname, "(VALUE self)\n", NIL);
- Printf(f->def, "#else\n");
- Printv(f->def, wname, "(int argc, VALUE *argv, VALUE self)\n", NIL);
- Printf(f->def, "#endif\n");
- Printv(f->def, "{\n", NIL);
- } else if (current == CONSTRUCTOR_INITIALIZE) {
- Printv(f->def, "SWIGINTERN VALUE\n", wname, "(int argc, VALUE *argv, VALUE self) {", NIL);
- if (!varargs) {
- Printf(f->code, "if ((argc < %d) || (argc > %d)) ", numreq - start, numarg - start);
- } else {
- Printf(f->code, "if (argc < %d) ", numreq - start);
- }
- Printf(f->code, "{rb_raise(rb_eArgError, \"wrong # of arguments(%%d for %d)\",argc); SWIG_fail;}\n", numreq - start);
- } else {
-
- if ( current == NO_CPP )
- {
- String* docs = docstring(n, AUTODOC_FUNC);
- Printf(f_wrappers, "%s", docs);
- Delete(docs);
- }
-
- Printv(f->def, "SWIGINTERN VALUE\n", wname, "(int argc, VALUE *argv, VALUE self) {", NIL);
- if (!varargs) {
- Printf(f->code, "if ((argc < %d) || (argc > %d)) ", numreq - start, numarg - start);
- } else {
- Printf(f->code, "if (argc < %d) ", numreq - start);
- }
- Printf(f->code, "{rb_raise(rb_eArgError, \"wrong # of arguments(%%d for %d)\",argc); SWIG_fail;}\n", numreq - start);
- }
-
- /* Now walk the function parameter list and generate code */
- /* to get arguments */
- if (current != CONSTRUCTOR_ALLOCATE) {
- marshalInputArgs(n, l, numarg, numreq, kwargs, allow_kwargs, f);
- }
- // FIXME?
- if (ctor_director) {
- numarg--;
- numreq--;
- }
-
- /* Insert constraint checking code */
- insertConstraintCheckingCode(l, f);
-
- /* Insert cleanup code */
- insertCleanupCode(l, cleanup);
-
- /* Insert argument output code */
- insertArgOutputCode(l, outarg, need_result);
-
- /* if the object is a director, and the method call originated from its
- * underlying Ruby object, resolve the call by going up the c++
- * inheritance chain. otherwise try to resolve the method in Ruby.
- * without this check an infinite loop is set up between the director and
- * shadow class method calls.
- */
-
- // NOTE: this code should only be inserted if this class is the
- // base class of a director class. however, in general we haven't
- // yet analyzed all classes derived from this one to see if they are
- // directors. furthermore, this class may be used as the base of
- // a director class defined in a completely different module at a
- // later time, so this test must be included whether or not directorbase
- // is true. we do skip this code if directors have not been enabled
- // at the command line to preserve source-level compatibility with
- // non-polymorphic swig. also, if this wrapper is for a smart-pointer
- // method, there is no need to perform the test since the calling object
- // (the smart-pointer) and the director object (the "pointee") are
- // distinct.
-
- director_method = is_member_director(n) && !is_smart_pointer() && !destructor;
- if (director_method) {
- Wrapper_add_local(f, "director", "Swig::Director *director = 0");
- Printf(f->code, "director = dynamic_cast<Swig::Director *>(arg1);\n");
- Wrapper_add_local(f, "upcall", "bool upcall = false");
- Append(f->code, "upcall = (director && (director->swig_get_self() == self));\n");
- }
-
- /* Now write code to make the function call */
- if (current != CONSTRUCTOR_ALLOCATE) {
- if (current == CONSTRUCTOR_INITIALIZE) {
- Node *pn = Swig_methodclass(n);
- String *symname = Getattr(pn, "sym:name");
- String *action = Getattr(n, "wrap:action");
- if (directorsEnabled()) {
- String *classname = NewStringf("const char *classname SWIGUNUSED = \"%s::%s\"", module, symname);
- Wrapper_add_local(f, "classname", classname);
- }
- if (action) {
- SwigType *smart = Swig_cparse_smartptr(pn);
- String *result_name = NewStringf("%s%s", smart ? "smart" : "", Swig_cresult_name());
- if (smart) {
- String *result_var = NewStringf("%s *%s = 0", SwigType_namestr(smart), result_name);
- Wrapper_add_local(f, result_name, result_var);
- Printf(action, "\n%s = new %s(%s);", result_name, SwigType_namestr(smart), Swig_cresult_name());
- }
- Printf(action, "\nDATA_PTR(self) = %s;", result_name);
- if (GetFlag(pn, "feature:trackobjects")) {
- Printf(action, "\nSWIG_RubyAddTracking(%s, self);", result_name);
- }
- Delete(result_name);
- Delete(smart);
- }
- }
-
- /* Emit the function call */
- if (director_method) {
- Printf(f->code, "try {\n");
- }
-
- Setattr(n, "wrap:name", wname);
-
- Swig_director_emit_dynamic_cast(n, f);
- String *actioncode = emit_action(n);
-
- if (director_method) {
- Printf(actioncode, "} catch (Swig::DirectorException& e) {\n");
- Printf(actioncode, " rb_exc_raise(e.getError());\n");
- Printf(actioncode, " SWIG_fail;\n");
- Printf(actioncode, "}\n");
- }
-
- /* Return value if necessary */
- if (SwigType_type(t) != T_VOID && current != CONSTRUCTOR_INITIALIZE) {
- need_result = 1;
- if (GetFlag(n, "feature:predicate")) {
- Printv(actioncode, tab4, "vresult = (", Swig_cresult_name(), " ? Qtrue : Qfalse);\n", NIL);
- } else {
- tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode);
- actioncode = 0;
- if (tm) {
- Replaceall(tm, "$result", "vresult");
-
- if (GetFlag(n, "feature:new"))
- Replaceall(tm, "$owner", "SWIG_POINTER_OWN");
- else
- Replaceall(tm, "$owner", "0");
-
- // Unwrap return values that are director classes so that the original Ruby object is returned instead.
- if (Swig_director_can_unwrap(n)) {
- Wrapper_add_local(f, "director", "Swig::Director *director = 0");
- Printf(f->code, "director = dynamic_cast<Swig::Director *>(%s);\n", Swig_cresult_name());
- Printf(f->code, "if (director) {\n");
- Printf(f->code, " vresult = director->swig_get_self();\n");
- Printf(f->code, "} else {\n");
- Printf(f->code, "%s\n", tm);
- Printf(f->code, "}\n");
- director_method = 0;
- } else {
- Printf(f->code, "%s\n", tm);
- }
-
- Delete(tm);
- } else {
- Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s.\n", SwigType_str(t, 0));
- }
- }
- }
- if (actioncode) {
- Append(f->code, actioncode);
- Delete(actioncode);
- }
- emit_return_variable(n, t, f);
- }
-
- /* Extra code needed for new and initialize methods */
- if (current == CONSTRUCTOR_ALLOCATE) {
- Node *pn = Swig_methodclass(n);
- SwigType *smart = Swig_cparse_smartptr(pn);
- if (smart)
- SwigType_add_pointer(smart);
- String *classtype = smart ? smart : t;
- need_result = 1;
- Printf(f->code, "VALUE vresult = SWIG_NewClassInstance(self, SWIGTYPE%s);\n", Char(SwigType_manglestr(classtype)));
- Printf(f->code, "#ifndef HAVE_RB_DEFINE_ALLOC_FUNC\n");
- Printf(f->code, "rb_obj_call_init(vresult, argc, argv);\n");
- Printf(f->code, "#endif\n");
- Delete(smart);
- } else if (current == CONSTRUCTOR_INITIALIZE) {
- need_result = 1;
- }
- else
- {
- if ( need_result > 1 ) {
- if ( SwigType_type(t) == T_VOID )
- Printf(f->code, "vresult = rb_ary_new();\n");
- else
- {
- Printf(f->code, "if (vresult == Qnil) vresult = rb_ary_new();\n");
- Printf(f->code, "else vresult = SWIG_Ruby_AppendOutput( "
- "rb_ary_new(), vresult);\n");
- }
- }
- }
-
- /* Dump argument output code; */
- Printv(f->code, outarg, NIL);
-
- /* Dump the argument cleanup code */
- int need_cleanup = (current != CONSTRUCTOR_ALLOCATE) && (Len(cleanup) != 0);
- if (need_cleanup) {
- Printv(f->code, cleanup, NIL);
- }
-
-
- /* Look for any remaining cleanup. This processes the %new directive */
- if (current != CONSTRUCTOR_ALLOCATE && GetFlag(n, "feature:new")) {
- tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0);
- if (tm) {
- Printv(f->code, tm, "\n", NIL);
- Delete(tm);
- }
- }
-
- /* Special processing on return value. */
- tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0);
- if (tm) {
- Printv(f->code, tm, NIL);
- Delete(tm);
- }
-
- if (director_method) {
- if ((tm = Swig_typemap_lookup("directorfree", n, Swig_cresult_name(), 0))) {
- Replaceall(tm, "$input", Swig_cresult_name());
- Replaceall(tm, "$result", "vresult");
- Printf(f->code, "%s\n", tm);
- }
- }
-
-
- /* Wrap things up (in a manner of speaking) */
- if (need_result) {
- if (current == CONSTRUCTOR_ALLOCATE) {
- Printv(f->code, tab4, "return vresult;\n", NIL);
- } else if (current == CONSTRUCTOR_INITIALIZE) {
- Printv(f->code, tab4, "return self;\n", NIL);
- Printv(f->code, "fail:\n", NIL);
- if (need_cleanup) {
- Printv(f->code, cleanup, NIL);
- }
- Printv(f->code, tab4, "return Qnil;\n", NIL);
- } else {
- Wrapper_add_local(f, "vresult", "VALUE vresult = Qnil");
- Printv(f->code, tab4, "return vresult;\n", NIL);
- Printv(f->code, "fail:\n", NIL);
- if (need_cleanup) {
- Printv(f->code, cleanup, NIL);
- }
- Printv(f->code, tab4, "return Qnil;\n", NIL);
- }
- } else {
- Printv(f->code, tab4, "return Qnil;\n", NIL);
- Printv(f->code, "fail:\n", NIL);
- if (need_cleanup) {
- Printv(f->code, cleanup, NIL);
- }
- Printv(f->code, tab4, "return Qnil;\n", NIL);
- }
-
- Printf(f->code, "}\n");
-
- /* Substitute the cleanup code */
- Replaceall(f->code, "$cleanup", cleanup);
-
- /* Substitute the function name */
- Replaceall(f->code, "$symname", symname);
-
- /* Emit the function */
- Wrapper_print(f, f_wrappers);
-
- /* Now register the function with the interpreter */
- if (!Swig_symbol_isoverloaded(n)) {
- create_command(n, symname);
- } else {
- if (current == CONSTRUCTOR_ALLOCATE) {
- create_command(n, symname);
- } else {
- if (!Getattr(n, "sym:nextSibling"))
- dispatchFunction(n);
- }
- }
-
- Delete(kwargs);
- Delete(cleanup);
- Delete(outarg);
- DelWrapper(f);
- Delete(symname);
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * dispatchFunction()
- * ------------------------------------------------------------ */
-
- void dispatchFunction(Node *n) {
- /* Last node in overloaded chain */
-
- int maxargs;
- String *tmp = NewString("");
- String *dispatch = Swig_overload_dispatch(n, "return %s(nargs, args, self);", &maxargs);
-
- /* Generate a dispatch wrapper for all overloaded functions */
-
- Wrapper *f = NewWrapper();
- String *symname = Getattr(n, "sym:name");
- String *wname = Swig_name_wrapper(symname);
-
- Printv(f->def, "SWIGINTERN VALUE ", wname, "(int nargs, VALUE *args, VALUE self) {", NIL);
-
- Wrapper_add_local(f, "argc", "int argc");
- bool ctor_director = (current == CONSTRUCTOR_INITIALIZE && Swig_directorclass(n));
- if (current == MEMBER_FUNC || current == MEMBER_VAR || ctor_director) {
- Printf(tmp, "VALUE argv[%d]", maxargs + 1);
- } else {
- Printf(tmp, "VALUE argv[%d]", maxargs);
- }
- Wrapper_add_local(f, "argv", tmp);
- Wrapper_add_local(f, "ii", "int ii");
-
- if (current == MEMBER_FUNC || current == MEMBER_VAR || ctor_director) {
- maxargs += 1;
- Printf(f->code, "argc = nargs + 1;\n");
- Printf(f->code, "argv[0] = self;\n");
- Printf(f->code, "if (argc > %d) SWIG_fail;\n", maxargs);
- Printf(f->code, "for (ii = 1; (ii < argc); ++ii) {\n");
- Printf(f->code, "argv[ii] = args[ii-1];\n");
- Printf(f->code, "}\n");
- } else {
- Printf(f->code, "argc = nargs;\n");
- Printf(f->code, "if (argc > %d) SWIG_fail;\n", maxargs);
- Printf(f->code, "for (ii = 0; (ii < argc); ++ii) {\n");
- Printf(f->code, "argv[ii] = args[ii];\n");
- Printf(f->code, "}\n");
- }
-
- Replaceall(dispatch, "$args", "nargs, args, self");
- Printv(f->code, dispatch, "\n", NIL);
-
-
-
- // Generate prototype list, go to first node
- Node *sibl = n;
-
- while (Getattr(sibl, "sym:previousSibling"))
- sibl = Getattr(sibl, "sym:previousSibling"); // go all the way up
-
- // Constructors will be treated specially
- const bool isCtor = (!Cmp(Getattr(sibl, "nodeType"), "constructor"));
- const bool isMethod = ( Cmp(Getattr(sibl, "ismember"), "1") == 0 &&
- (!isCtor) );
-
- // Construct real method name
- String* methodName = NewString("");
- if ( isMethod ) {
- // Sometimes a method node has no parent (SF#3034054).
- // This value is used in an exception message, so just skip the class
- // name in this case so at least we don't segfault. This is probably
- // just working around a problem elsewhere though.
- Node *parent_node = parentNode(sibl);
- if (parent_node)
- Printv( methodName, Getattr(parent_node,"sym:name"), ".", NIL );
- }
- Append( methodName, Getattr(sibl,"sym:name" ) );
- if ( isCtor ) Append( methodName, ".new" );
-
- // Generate prototype list
- String *protoTypes = NewString("");
- do {
- Append( protoTypes, "\n\" ");
- if (!isCtor) {
- SwigType *type = SwigType_str(Getattr(sibl, "type"), NULL);
- Printv(protoTypes, type, " ", NIL);
- Delete(type);
- }
- Printv(protoTypes, methodName, NIL );
- Parm* p = Getattr(sibl, "wrap:parms");
- if (p && (current == MEMBER_FUNC || current == MEMBER_VAR ||
- ctor_director) )
- p = nextSibling(p); // skip self
- Append( protoTypes, "(" );
- while(p)
- {
- Append( protoTypes, SwigType_str(Getattr(p,"type"), Getattr(p,"name")) );
- if ( ( p = nextSibling(p)) ) Append(protoTypes, ", ");
- }
- Append( protoTypes, ")\\n\"" );
- } while ((sibl = Getattr(sibl, "sym:nextSibling")));
-
- Append(f->code, "fail:\n");
- Printf(f->code, "Ruby_Format_OverloadedError( argc, %d, \"%s\", %s);\n",
- maxargs, methodName, protoTypes);
- Append(f->code, "\nreturn Qnil;\n");
-
- Delete(methodName);
- Delete(protoTypes);
-
- Printv(f->code, "}\n", NIL);
- Wrapper_print(f, f_wrappers);
- create_command(n, Char(symname));
-
- DelWrapper(f);
- Delete(dispatch);
- Delete(tmp);
- Delete(wname);
- }
-
- /* ---------------------------------------------------------------------
- * variableWrapper()
- * --------------------------------------------------------------------- */
-
- virtual int variableWrapper(Node *n) {
- String* docs = docstring(n, AUTODOC_GETTER);
- Printf(f_wrappers, "%s", docs);
- Delete(docs);
-
-
- char *name = GetChar(n, "name");
- char *iname = GetChar(n, "sym:name");
- SwigType *t = Getattr(n, "type");
- String *tm;
- String *getfname, *setfname;
- Wrapper *getf, *setf;
- const int assignable = is_assignable(n);
-
- // Determine whether virtual global variables shall be used
- // which have different getter and setter signatures,
- // see https://docs.ruby-lang.org/en/2.6.0/extension_rdoc.html#label-Global+Variables+Shared+Between+C+and+Ruby
- const bool use_virtual_var = (current == NO_CPP && useGlobalModule);
-
- getf = NewWrapper();
- setf = NewWrapper();
-
- /* create getter */
- int addfail = 0;
- String *getname = Swig_name_get(NSPACE_TODO, iname);
- getfname = Swig_name_wrapper(getname);
- Setattr(n, "wrap:name", getfname);
- Printv(getf->def, "SWIGINTERN VALUE\n", getfname, "(", NIL);
- Printf(getf->def, (use_virtual_var) ? "ID id, VALUE *data" : "VALUE self");
- Printf(getf->def, ") {");
- Wrapper_add_local(getf, "_val", "VALUE _val");
-
- tm = Swig_typemap_lookup("varout", n, name, 0);
- if (tm) {
- Replaceall(tm, "$result", "_val");
- /* Printv(getf->code,tm, NIL); */
- addfail = emit_action_code(n, getf->code, tm);
- } else {
- Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
- }
- Printv(getf->code, tab4, "return _val;\n", NIL);
- if (addfail) {
- Append(getf->code, "fail:\n");
- Append(getf->code, " return Qnil;\n");
- }
- Append(getf->code, "}\n");
-
- Wrapper_print(getf, f_wrappers);
-
- if (!assignable) {
- setfname = NewString("(rb_gvar_setter_t *)NULL");
- } else {
- /* create setter */
- String* docs = docstring(n, AUTODOC_SETTER);
- Printf(f_wrappers, "%s", docs);
- Delete(docs);
-
- String *setname = Swig_name_set(NSPACE_TODO, iname);
- setfname = Swig_name_wrapper(setname);
- Setattr(n, "wrap:name", setfname);
- Printf(setf->def, "SWIGINTERN ");
- if (use_virtual_var) {
- Printv(setf->def, "void\n", setfname, "(VALUE _val, ID id, VALUE *data) {", NIL);
- } else {
- Printv(setf->def, "VALUE\n", setfname, "(VALUE self, VALUE _val) {", NIL);
- }
- tm = Swig_typemap_lookup("varin", n, name, 0);
- if (tm) {
- Replaceall(tm, "$input", "_val");
- /* Printv(setf->code,tm,"\n",NIL); */
- emit_action_code(n, setf->code, tm);
- } else {
- Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s\n", SwigType_str(t, 0));
- }
- if (use_virtual_var) {
- Printf(setf->code, "fail:\n");
- Printv(setf->code, tab4, "return;\n", NIL);
- } else {
- Printv(setf->code, tab4, "return _val;\n", NIL);
- Printf(setf->code, "fail:\n");
- Printv(setf->code, tab4, "return Qnil;\n", NIL);
- }
- Printf(setf->code, "}\n");
- Wrapper_print(setf, f_wrappers);
- Delete(setname);
- }
-
- /* define accessor methods */
- Insert(getfname, 0, "VALUEFUNC(");
- Append(getfname, ")");
- Insert(setfname, 0, (use_virtual_var) ? "SWIG_RUBY_VOID_ANYARGS_FUNC(" : "VALUEFUNC(");
- Append(setfname, ")");
-
- String *s = NewString("");
- switch (current) {
- case STATIC_VAR:
- /* C++ class variable */
- Printv(s, tab4, "rb_define_singleton_method(", klass->vname, ", \"", klass->strip(iname), "\", ", getfname, ", 0);\n", NIL);
- if (assignable) {
- Printv(s, tab4, "rb_define_singleton_method(", klass->vname, ", \"", klass->strip(iname), "=\", ", setfname, ", 1);\n", NIL);
- }
- Printv(klass->init, s, NIL);
- break;
- default:
- /* C global variable */
- /* wrapped in Ruby module attribute */
- assert(current == NO_CPP);
- if (!useGlobalModule) {
- Printv(s, tab4, "rb_define_singleton_method(", modvar, ", \"", iname, "\", ", getfname, ", 0);\n", NIL);
- if (assignable) {
- Printv(s, tab4, "rb_define_singleton_method(", modvar, ", \"", iname, "=\", ", setfname, ", 1);\n", NIL);
- }
- } else {
- Printv(s, tab4, "rb_define_virtual_variable(\"$", iname, "\", ", getfname, ", ", setfname, ");\n", NIL);
- }
- Printv(f_init, s, NIL);
- Delete(s);
- break;
- }
- Delete(getname);
- Delete(getfname);
- Delete(setfname);
- DelWrapper(setf);
- DelWrapper(getf);
- return SWIG_OK;
- }
-
-
- /* ---------------------------------------------------------------------
- * validate_const_name(char *name)
- *
- * Validate constant name.
- * --------------------------------------------------------------------- */
-
- char *validate_const_name(char *name, const char *reason) {
- if (!name || name[0] == '\0')
- return name;
-
- if (isupper(name[0]))
- return name;
-
- if (islower(name[0])) {
- name[0] = (char)toupper(name[0]);
- Swig_warning(WARN_RUBY_WRONG_NAME, input_file, line_number, "Wrong %s name (corrected to `%s')\n", reason, name);
- return name;
- }
-
- Swig_warning(WARN_RUBY_WRONG_NAME, input_file, line_number, "Wrong %s name %s\n", reason, name);
-
- return name;
- }
-
- /* ---------------------------------------------------------------------
- * constantWrapper()
- * --------------------------------------------------------------------- */
-
- virtual int constantWrapper(Node *n) {
- Swig_require("constantWrapper", n, "*sym:name", "type", "value", NIL);
-
- char *iname = GetChar(n, "sym:name");
- SwigType *type = Getattr(n, "type");
- String *rawval = Getattr(n, "rawval");
- String *value = rawval ? rawval : Getattr(n, "value");
-
- if (current == CLASS_CONST) {
- iname = klass->strip(iname);
- }
- validate_const_name(iname, "constant");
- SetChar(n, "sym:name", iname);
-
- /* Special hook for member pointer */
- if (SwigType_type(type) == T_MPOINTER) {
- String *wname = Swig_name_wrapper(iname);
- Printf(f_header, "static %s = %s;\n", SwigType_str(type, wname), value);
- value = Char(wname);
- }
- String *tm = Swig_typemap_lookup("constant", n, value, 0);
- if (!tm)
- tm = Swig_typemap_lookup("constcode", n, value, 0);
- if (tm) {
- Replaceall(tm, "$symname", iname);
- Replaceall(tm, "$value", value);
- if (current == CLASS_CONST) {
- if (multipleInheritance) {
- Replaceall(tm, "$module", klass->mImpl);
- Printv(klass->init, tm, "\n", NIL);
- } else {
- Replaceall(tm, "$module", klass->vname);
- Printv(klass->init, tm, "\n", NIL);
- }
- } else {
- if (!useGlobalModule) {
- Replaceall(tm, "$module", modvar);
- } else {
- Replaceall(tm, "$module", "rb_cObject");
- }
- Printf(f_init, "%s\n", tm);
- }
- } else {
- Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value %s = %s\n", SwigType_str(type, 0), value);
- }
- Swig_restore(n);
- return SWIG_OK;
- }
-
- /* -----------------------------------------------------------------------------
- * classDeclaration()
- *
- * Records information about classes---even classes that might be defined in
- * other modules referenced by %import.
- * ----------------------------------------------------------------------------- */
-
- virtual int classDeclaration(Node *n) {
- if (!Getattr(n, "feature:onlychildren")) {
- String *name = Getattr(n, "name");
- String *symname = Getattr(n, "sym:name");
-
- String *namestr = SwigType_namestr(name);
- klass = RCLASS(classes, Char(namestr));
- if (!klass) {
- klass = new RClass();
- String *valid_name = NewString(symname ? symname : namestr);
- validate_const_name(Char(valid_name), "class");
- klass->set_name(namestr, symname, valid_name);
- SET_RCLASS(classes, Char(namestr), klass);
- Delete(valid_name);
- }
- Delete(namestr);
- }
- return Language::classDeclaration(n);
- }
-
- /**
- * Process the comma-separated list of mixed-in module names (if any).
- */
- void includeRubyModules(Node *n) {
- String *mixin = Getattr(n, "feature:mixin");
- if (mixin) {
- List *modules = Split(mixin, ',', INT_MAX);
- if (modules && Len(modules) > 0) {
- Iterator mod = First(modules);
- while (mod.item) {
- if (Len(mod.item) > 0) {
- Printf(klass->init, "rb_include_module(%s, rb_eval_string(\"%s\"));\n", klass->vname, mod.item);
- }
- mod = Next(mod);
- }
- }
- Delete(modules);
- }
- }
-
- void handleBaseClasses(Node *n) {
- List *baselist = Getattr(n, "bases");
- if (baselist && Len(baselist)) {
- Iterator base = First(baselist);
- while (base.item && GetFlag(base.item, "feature:ignore")) {
- base = Next(base);
- }
- while (base.item) {
- String *basename = Getattr(base.item, "name");
- String *basenamestr = SwigType_namestr(basename);
- RClass *super = RCLASS(classes, Char(basenamestr));
- Delete(basenamestr);
- if (super) {
- SwigType *btype = NewString(basename);
- SwigType_add_pointer(btype);
- SwigType_remember(btype);
- SwigType *smart = Swig_cparse_smartptr(base.item);
- if (smart) {
- SwigType_add_pointer(smart);
- SwigType_remember(smart);
- }
- String *bmangle = SwigType_manglestr(smart ? smart : btype);
- if (multipleInheritance) {
- Insert(bmangle, 0, "((swig_class *) SWIGTYPE");
- Append(bmangle, "->clientdata)->mImpl");
- Printv(klass->init, "rb_include_module(", klass->mImpl, ", ", bmangle, ");\n", NIL);
- } else {
- Insert(bmangle, 0, "((swig_class *) SWIGTYPE");
- Append(bmangle, "->clientdata)->klass");
- Replaceall(klass->init, "$super", bmangle);
- }
- Delete(bmangle);
- Delete(smart);
- Delete(btype);
- }
- base = Next(base);
- while (base.item && GetFlag(base.item, "feature:ignore")) {
- base = Next(base);
- }
- if (!multipleInheritance) {
- /* Warn about multiple inheritance for additional base class(es) */
- while (base.item) {
- if (GetFlag(base.item, "feature:ignore")) {
- base = Next(base);
- continue;
- }
- String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0);
- String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0);
- Swig_warning(WARN_RUBY_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
- "Warning for %s, base %s ignored. Multiple inheritance is not supported in Ruby.\n", proxyclassname, baseclassname);
- base = Next(base);
- }
- }
- }
- }
- }
-
- /**
- * Check to see if a %markfunc was specified.
- */
- void handleMarkFuncDirective(Node *n) {
- String *markfunc = Getattr(n, "feature:markfunc");
- if (markfunc) {
- Printf(klass->init, "SwigClass%s.mark = (void (*)(void *)) %s;\n", klass->name, markfunc);
- } else {
- Printf(klass->init, "SwigClass%s.mark = 0;\n", klass->name);
- }
- }
-
- /**
- * Check to see if a %freefunc was specified.
- */
- void handleFreeFuncDirective(Node *n) {
- String *freefunc = Getattr(n, "feature:freefunc");
- if (freefunc) {
- Printf(klass->init, "SwigClass%s.destroy = (void (*)(void *)) %s;\n", klass->name, freefunc);
- } else {
- if (klass->destructor_defined) {
- Printf(klass->init, "SwigClass%s.destroy = (void (*)(void *)) free_%s;\n", klass->name, klass->mname);
- }
- }
- }
-
- /**
- * Check to see if tracking is enabled for this class.
- */
- void handleTrackDirective(Node *n) {
- int trackObjects = GetFlag(n, "feature:trackobjects");
- if (trackObjects) {
- Printf(klass->init, "SwigClass%s.trackObjects = 1;\n", klass->name);
- } else {
- Printf(klass->init, "SwigClass%s.trackObjects = 0;\n", klass->name);
- }
- }
-
- /* ----------------------------------------------------------------------
- * classHandler()
- * ---------------------------------------------------------------------- */
-
- virtual int classHandler(Node *n) {
- String* docs = docstring(n, AUTODOC_CLASS);
- Printf(f_wrappers, "%s", docs);
- Delete(docs);
-
- String *name = Getattr(n, "name");
- String *symname = Getattr(n, "sym:name");
- String *namestr = SwigType_namestr(name); // does template expansion
-
- klass = RCLASS(classes, Char(namestr));
- assert(klass != 0);
- Delete(namestr);
- String *valid_name = NewString(symname);
- validate_const_name(Char(valid_name), "class");
-
- Clear(klass->type);
- Printv(klass->type, Getattr(n, "classtype"), NIL);
- Printv(f_wrappers, "static swig_class SwigClass", valid_name, ";\n\n", NIL);
- Printv(klass->init, "\n", tab4, NIL);
-
- if (!useGlobalModule) {
- Printv(klass->init, klass->vname, " = rb_define_class_under(", modvar, ", \"", klass->name, "\", $super);\n", NIL);
- } else {
- Printv(klass->init, klass->vname, " = rb_define_class(\"", klass->name,
- "\", $super);\n", NIL);
- }
-
- if (multipleInheritance) {
- Printv(klass->init, klass->mImpl, " = rb_define_module_under(", klass->vname, ", \"Impl\");\n", NIL);
- }
-
- SwigType *tt = NewString(name);
- SwigType_add_pointer(tt);
- SwigType_remember(tt);
- SwigType *smart = Swig_cparse_smartptr(n);
- if (smart) {
- SwigType_add_pointer(smart);
- SwigType_remember(smart);
- }
- String *tm = SwigType_manglestr(smart ? smart : tt);
- Printf(klass->init, "SWIG_TypeClientData(SWIGTYPE%s, (void *) &SwigClass%s);\n", tm, valid_name);
- Delete(tm);
- Delete(smart);
- Delete(tt);
- Delete(valid_name);
-
- includeRubyModules(n);
-
- Printv(klass->init, "$allocator", NIL);
- Printv(klass->init, "$initializer", NIL);
-
- Language::classHandler(n);
-
- handleBaseClasses(n);
- handleMarkFuncDirective(n);
- handleFreeFuncDirective(n);
- handleTrackDirective(n);
-
- if (multipleInheritance) {
- Printv(klass->init, "rb_include_module(", klass->vname, ", ", klass->mImpl, ");\n", NIL);
- }
-
- String *s = NewString("");
- Printv(s, tab4, "rb_undef_alloc_func(", klass->vname, ");\n", NIL);
- Replaceall(klass->init, "$allocator", s);
- Replaceall(klass->init, "$initializer", "");
-
- if (GetFlag(n, "feature:exceptionclass")) {
- Replaceall(klass->init, "$super", "rb_eRuntimeError");
- } else {
- Replaceall(klass->init, "$super", "rb_cObject");
- }
- Delete(s);
-
- Printv(f_init, klass->init, NIL);
- klass = 0;
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * memberfunctionHandler()
- *
- * Method for adding C++ member function
- *
- * By default, we're going to create a function of the form :
- *
- * Foo_bar(this,args)
- *
- * Where Foo is the classname, bar is the member name and the this pointer
- * is explicitly attached to the beginning.
- *
- * The renaming only applies to the member function part, not the full
- * classname.
- *
- * --------------------------------------------------------------------- */
-
- virtual int memberfunctionHandler(Node *n) {
- current = MEMBER_FUNC;
-
- String* docs = docstring(n, AUTODOC_METHOD);
- Printf(f_wrappers, "%s", docs);
- Delete(docs);
-
- Language::memberfunctionHandler(n);
- current = NO_CPP;
- return SWIG_OK;
- }
-
- /* ---------------------------------------------------------------------
- * constructorHandler()
- *
- * Method for adding C++ member constructor
- * -------------------------------------------------------------------- */
-
- void set_director_ctor_code(Node *n) {
- /* director ctor code is specific for each class */
- Delete(director_prot_ctor_code);
- director_prot_ctor_code = NewString("");
- Node *pn = Swig_methodclass(n);
- String *symname = Getattr(pn, "sym:name");
- String *name = Copy(symname);
- char *cname = Char(name);
- if (cname)
- cname[0] = (char)toupper(cname[0]);
- Printv(director_prot_ctor_code,
- "if ( $comparison ) { /* subclassed */\n",
- " $director_new \n",
- "} else {\n", " rb_raise(rb_eNameError,\"accessing abstract class or protected constructor\"); \n", " return Qnil;\n", "}\n", NIL);
- Delete(director_ctor_code);
- director_ctor_code = NewString("");
- Printv(director_ctor_code, "if ( $comparison ) { /* subclassed */\n", " $director_new \n", "} else {\n", " $nondirector_new \n", "}\n", NIL);
- Delete(name);
- }
-
- virtual int constructorHandler(Node *n) {
- int use_director = Swig_directorclass(n);
- if (use_director) {
- set_director_ctor_code(n);
- }
-
- /* First wrap the allocate method */
- current = CONSTRUCTOR_ALLOCATE;
- Swig_name_register("construct", "%n%c_allocate");
-
- Language::constructorHandler(n);
-
- String* docs = docstring(n, AUTODOC_CTOR);
- Printf(f_wrappers, "%s", docs);
- Delete(docs);
-
- /*
- * If we're wrapping the constructor of a C++ director class, prepend a new parameter
- * to receive the scripting language object (e.g. 'self')
- *
- */
- Swig_save("ruby:constructorHandler", n, "parms", NIL);
- if (use_director) {
- Parm *parms = Getattr(n, "parms");
- Parm *self;
- String *name = NewString("self");
- String *type = NewString("VALUE");
- self = NewParm(type, name, n);
- Delete(type);
- Delete(name);
- Setattr(self, "lname", "Qnil");
- if (parms)
- set_nextSibling(self, parms);
- Setattr(n, "parms", self);
- Setattr(n, "wrap:self", "1");
- Delete(self);
- }
-
- /* Now do the instance initialize method */
- current = CONSTRUCTOR_INITIALIZE;
- Swig_name_register("construct", "new_%n%c");
- Language::constructorHandler(n);
-
- /* Restore original parameter list */
- Delattr(n, "wrap:self");
- Swig_restore(n);
-
- /* Done */
- Swig_name_unregister("construct");
- current = NO_CPP;
- klass->constructor_defined = 1;
- return SWIG_OK;
- }
-
- virtual int copyconstructorHandler(Node *n) {
- int use_director = Swig_directorclass(n);
- if (use_director) {
- set_director_ctor_code(n);
- }
-
- /* First wrap the allocate method */
- current = CONSTRUCTOR_ALLOCATE;
- Swig_name_register("construct", "%n%c_allocate");
-
- return Language::copyconstructorHandler(n);
- }
-
-
- /* ---------------------------------------------------------------------
- * destructorHandler()
- * -------------------------------------------------------------------- */
-
- virtual int destructorHandler(Node *n) {
-
- /* Do no spit free function if user defined his own for this class */
- Node *pn = Swig_methodclass(n);
- String *freefunc = Getattr(pn, "feature:freefunc");
- if (freefunc) return SWIG_OK;
-
- current = DESTRUCTOR;
- Language::destructorHandler(n);
-
- freefunc = NewString("");
- String *freebody = NewString("");
- String *pname0 = Swig_cparm_name(0, 0);
-
- Printv(freefunc, "free_", klass->mname, NIL);
- Printv(freebody, "SWIGINTERN void\n", freefunc, "(void *self) {\n", NIL);
- Printv(freebody, tab4, klass->type, " *", pname0, " = (", klass->type, " *)self;\n", NIL);
- Printv(freebody, tab4, NIL);
-
- /* Check to see if object tracking is activated for the class
- that owns this destructor. */
- if (GetFlag(pn, "feature:trackobjects")) {
- Printf(freebody, "SWIG_RubyRemoveTracking(%s);\n", pname0);
- Printv(freebody, tab4, NIL);
- }
-
- if (Extend) {
- String *wrap = Getattr(n, "wrap:code");
- if (wrap) {
- Printv(f_wrappers, wrap, NIL);
- }
- /* Printv(freebody, Swig_name_destroy(name), "(", pname0, ")", NIL); */
- Printv(freebody, Getattr(n, "wrap:action"), "\n", NIL);
- } else {
- String *action = Getattr(n, "wrap:action");
- if (action) {
- Printv(freebody, action, "\n", NIL);
- } else {
- /* In the case swig emits no destroy function. */
- if (CPlusPlus)
- Printf(freebody, "delete %s;\n", pname0);
- else
- Printf(freebody, "free((char*) %s);\n", pname0);
- }
- }
-
- Printv(freebody, "}\n\n", NIL);
-
- Printv(f_wrappers, freebody, NIL);
-
- klass->destructor_defined = 1;
- current = NO_CPP;
- Delete(freefunc);
- Delete(freebody);
- Delete(pname0);
- return SWIG_OK;
- }
-
- /* ---------------------------------------------------------------------
- * membervariableHandler()
- *
- * This creates a pair of functions to set/get the variable of a member.
- * -------------------------------------------------------------------- */
-
- virtual int membervariableHandler(Node *n) {
- String* docs = docstring(n, AUTODOC_GETTER);
- Printf(f_wrappers, "%s", docs);
- Delete(docs);
-
- if (is_assignable(n)) {
- String* docs = docstring(n, AUTODOC_SETTER);
- Printf(f_wrappers, "%s", docs);
- Delete(docs);
- }
-
- current = MEMBER_VAR;
- Language::membervariableHandler(n);
- current = NO_CPP;
- return SWIG_OK;
- }
-
- /* -----------------------------------------------------------------------
- * staticmemberfunctionHandler()
- *
- * Wrap a static C++ function
- * ---------------------------------------------------------------------- */
-
- virtual int staticmemberfunctionHandler(Node *n) {
- String* docs = docstring(n, AUTODOC_STATICFUNC);
- Printf(f_wrappers, "%s", docs);
- Delete(docs);
-
- current = STATIC_FUNC;
- Language::staticmemberfunctionHandler(n);
- current = NO_CPP;
- return SWIG_OK;
- }
-
- /* ----------------------------------------------------------------------
- * memberconstantHandler()
- *
- * Create a C++ constant
- * --------------------------------------------------------------------- */
-
- virtual int memberconstantHandler(Node *n) {
- String* docs = docstring(n, AUTODOC_STATICFUNC);
- Printf(f_wrappers, "%s", docs);
- Delete(docs);
-
- current = CLASS_CONST;
- Language::memberconstantHandler(n);
- current = NO_CPP;
- return SWIG_OK;
- }
-
- /* ---------------------------------------------------------------------
- * staticmembervariableHandler()
- * --------------------------------------------------------------------- */
-
- virtual int staticmembervariableHandler(Node *n) {
- String* docs = docstring(n, AUTODOC_GETTER);
- Printf(f_wrappers, "%s", docs);
- Delete(docs);
-
- if (is_assignable(n)) {
- String* docs = docstring(n, AUTODOC_SETTER);
- Printf(f_wrappers, "%s", docs);
- Delete(docs);
- }
-
- current = STATIC_VAR;
- Language::staticmembervariableHandler(n);
- current = NO_CPP;
- return SWIG_OK;
- }
-
- /* C++ director class generation */
- virtual int classDirector(Node *n) {
- return Language::classDirector(n);
- }
-
- virtual int classDirectorInit(Node *n) {
- String *declaration;
- declaration = Swig_director_declaration(n);
- Printf(f_directors_h, "\n");
- Printf(f_directors_h, "%s\n", declaration);
- Printf(f_directors_h, "public:\n");
- Delete(declaration);
- return Language::classDirectorInit(n);
- }
-
- virtual int classDirectorEnd(Node *n) {
- Printf(f_directors_h, "};\n\n");
- return Language::classDirectorEnd(n);
- }
-
- /* ------------------------------------------------------------
- * classDirectorConstructor()
- * ------------------------------------------------------------ */
-
- virtual int classDirectorConstructor(Node *n) {
- Node *parent = Getattr(n, "parentNode");
- String *sub = NewString("");
- String *decl = Getattr(n, "decl");
- String *supername = Swig_class_name(parent);
- String *classname = NewString("");
- Printf(classname, "SwigDirector_%s", supername);
-
- /* insert self parameter */
- Parm *p;
- ParmList *superparms = Getattr(n, "parms");
- ParmList *parms = CopyParmList(superparms);
- String *type = NewString("VALUE");
- p = NewParm(type, NewString("self"), n);
- set_nextSibling(p, parms);
- parms = p;
-
- if (!Getattr(n, "defaultargs")) {
- /* constructor */
- {
- Wrapper *w = NewWrapper();
- String *call;
- String *basetype = Getattr(parent, "classtype");
- String *target = Swig_method_decl(0, decl, classname, parms, 0);
- call = Swig_csuperclass_call(0, basetype, superparms);
- Printf(w->def, "%s::%s: %s, Swig::Director(self) { }", classname, target, call);
- Delete(target);
- Wrapper_print(w, f_directors);
- Delete(call);
- DelWrapper(w);
- }
-
- /* constructor header */
- {
- String *target = Swig_method_decl(0, decl, classname, parms, 1);
- Printf(f_directors_h, " %s;\n", target);
- Delete(target);
- }
- }
-
- Delete(sub);
- Delete(classname);
- Delete(supername);
- Delete(parms);
- return Language::classDirectorConstructor(n);
- }
-
- /* ------------------------------------------------------------
- * classDirectorDefaultConstructor()
- * ------------------------------------------------------------ */
-
- virtual int classDirectorDefaultConstructor(Node *n) {
- String *classname;
- Wrapper *w;
- classname = Swig_class_name(n);
- w = NewWrapper();
- Printf(w->def, "SwigDirector_%s::SwigDirector_%s(VALUE self) : Swig::Director(self) { }", classname, classname);
- Wrapper_print(w, f_directors);
- DelWrapper(w);
- Printf(f_directors_h, " SwigDirector_%s(VALUE self);\n", classname);
- Delete(classname);
- return Language::classDirectorDefaultConstructor(n);
- }
-
- /* ---------------------------------------------------------------
- * exceptionSafeMethodCall()
- *
- * Emit a virtual director method to pass a method call on to the
- * underlying Ruby instance.
- *
- * --------------------------------------------------------------- */
-
- void exceptionSafeMethodCall(String *className, Node *n, Wrapper *w, int argc, String *args, bool initstack) {
- Wrapper *body = NewWrapper();
- Wrapper *rescue = NewWrapper();
-
- String *methodName = Getattr(n, "sym:name");
-
- String *bodyName = NewStringf("%s_%s_body", className, methodName);
- String *rescueName = NewStringf("%s_%s_rescue", className, methodName);
- String *depthCountName = NewStringf("%s_%s_call_depth", className, methodName);
-
- // Check for an exception typemap of some kind
- String *tm = Swig_typemap_lookup("director:except", n, Swig_cresult_name(), 0);
- if (!tm) {
- tm = Getattr(n, "feature:director:except");
- }
-
- if ((tm != 0) && (Len(tm) > 0) && (Strcmp(tm, "1") != 0)) {
- // Declare a global to hold the depth count
- if (!Getattr(n, "sym:nextSibling")) {
- Printf(body->def, "static int %s = 0;\n", depthCountName);
-
- // Function body
- Printf(body->def, "VALUE %s(VALUE data) {\n", bodyName);
- Wrapper_add_localv(body, "args", "Swig::body_args *", "args", "= reinterpret_cast<Swig::body_args *>(data)", NIL);
- Wrapper_add_localv(body, Swig_cresult_name(), "VALUE", Swig_cresult_name(), "= Qnil", NIL);
- Printf(body->code, "%s++;\n", depthCountName);
- Printv(body->code, Swig_cresult_name(), " = rb_funcall2(args->recv, args->id, args->argc, args->argv);\n", NIL);
- Printf(body->code, "%s--;\n", depthCountName);
- Printv(body->code, "return ", Swig_cresult_name(), ";\n", NIL);
- Printv(body->code, "}", NIL);
-
- // Exception handler
- Printf(rescue->def, "VALUE %s(VALUE args, VALUE error) {\n", rescueName);
- Replaceall(tm, "$error", "error");
- Printf(rescue->code, "%s--;\n", depthCountName);
- Printf(rescue->code, "if (%s == 0) ", depthCountName);
- Printv(rescue->code, Str(tm), "\n", NIL);
- Printv(rescue->code, "rb_exc_raise(error);\n", NIL);
- Printv(rescue->code, "return Qnil;\n", NIL);
- Printv(rescue->code, "}", NIL);
- }
-
- // Main code
- Wrapper_add_localv(w, "args", "Swig::body_args", "args", NIL);
- Wrapper_add_localv(w, "status", "int", "status", NIL);
- Printv(w->code, "args.recv = swig_get_self();\n", NIL);
- Printf(w->code, "args.id = rb_intern(\"%s\");\n", methodName);
- Printf(w->code, "args.argc = %d;\n", argc);
- if (argc > 0) {
- Printf(w->code, "args.argv = new VALUE[%d];\n", argc);
- for (int i = 0; i < argc; i++) {
- Printf(w->code, "args.argv[%d] = obj%d;\n", i, i);
- }
- } else {
- Printv(w->code, "args.argv = 0;\n", NIL);
- }
- Printf(w->code, "%s = rb_protect(PROTECTFUNC(%s), reinterpret_cast<VALUE>(&args), &status);\n", Swig_cresult_name(), bodyName);
- if ( initstack ) Printf(w->code, "SWIG_RELEASE_STACK;\n");
- Printf(w->code, "if (status) {\n");
- Printf(w->code, "VALUE lastErr = rb_gv_get(\"$!\");\n");
- Printf(w->code, "%s(reinterpret_cast<VALUE>(&args), lastErr);\n", rescueName);
- Printf(w->code, "}\n");
- if (argc > 0) {
- Printv(w->code, "delete [] args.argv;\n", NIL);
- }
- // Dump wrapper code
- Wrapper_print(body, f_directors_helpers);
- Wrapper_print(rescue, f_directors_helpers);
- } else {
- if (argc > 0) {
- Printf(w->code, "%s = rb_funcall(swig_get_self(), rb_intern(\"%s\"), %d%s);\n", Swig_cresult_name(), methodName, argc, args);
- } else {
- Printf(w->code, "%s = rb_funcall(swig_get_self(), rb_intern(\"%s\"), 0, Qnil);\n", Swig_cresult_name(), methodName);
- }
- if ( initstack ) Printf(w->code, "SWIG_RELEASE_STACK;\n");
- }
-
- // Clean up
- Delete(bodyName);
- Delete(rescueName);
- Delete(depthCountName);
- DelWrapper(body);
- DelWrapper(rescue);
- }
-
- virtual int classDirectorMethod(Node *n, Node *parent, String *super) {
- int is_void = 0;
- int is_pointer = 0;
- String *decl = Getattr(n, "decl");
- String *name = Getattr(n, "name");
- String *classname = Getattr(parent, "sym:name");
- String *c_classname = Getattr(parent, "name");
- String *symname = Getattr(n, "sym:name");
- String *declaration = NewString("");
- ParmList *l = Getattr(n, "parms");
- Wrapper *w = NewWrapper();
- String *tm;
- String *wrap_args = NewString("");
- String *returntype = Getattr(n, "type");
- Parm *p;
- String *value = Getattr(n, "value");
- String *storage = Getattr(n, "storage");
- bool pure_virtual = false;
- int status = SWIG_OK;
- int idx;
- bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
- bool asvoid = checkAttribute( n, "feature:numoutputs", "0") ? true : false;
- bool initstack = checkAttribute( n, "feature:initstack", "1") ? true : false;
-
- if (Cmp(storage, "virtual") == 0) {
- if (Cmp(value, "0") == 0) {
- pure_virtual = true;
- }
- }
- String *overnametmp = NewString(Getattr(n, "sym:name"));
- if (Getattr(n, "sym:overloaded")) {
- Printf(overnametmp, "::%s", Getattr(n, "sym:overname"));
- }
-
- /* determine if the method returns a pointer */
- is_pointer = SwigType_ispointer_return(decl);
- is_void = (!Cmp(returntype, "void") && !is_pointer);
-
- /* virtual method definition */
- String *target;
- String *pclassname = NewStringf("SwigDirector_%s", classname);
- String *qualified_name = NewStringf("%s::%s", pclassname, name);
- SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
- target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
- Printf(w->def, "%s", target);
- Delete(qualified_name);
- Delete(target);
- /* header declaration */
- target = Swig_method_decl(rtype, decl, name, l, 1);
- Printf(declaration, " virtual %s", target);
- Delete(target);
-
- // Get any exception classes in the throws typemap
- if (Getattr(n, "noexcept")) {
- Append(w->def, " noexcept");
- Append(declaration, " noexcept");
- }
- ParmList *throw_parm_list = 0;
-
- if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
- Parm *p;
- int gencomma = 0;
-
- Append(w->def, " throw(");
- Append(declaration, " throw(");
-
- if (throw_parm_list)
- Swig_typemap_attach_parms("throws", throw_parm_list, 0);
- for (p = throw_parm_list; p; p = nextSibling(p)) {
- if (Getattr(p, "tmap:throws")) {
- if (gencomma++) {
- Append(w->def, ", ");
- Append(declaration, ", ");
- }
-
- Printf(w->def, "%s", SwigType_str(Getattr(p, "type"), 0));
- Printf(declaration, "%s", SwigType_str(Getattr(p, "type"), 0));
- }
- }
-
- Append(w->def, ")");
- Append(declaration, ")");
- }
-
- Append(w->def, " {");
- Append(declaration, ";\n");
-
- if (initstack && !(ignored_method && !pure_virtual)) {
- Append(w->def, "\nSWIG_INIT_STACK;\n");
- }
-
- /* declare method return value
- * if the return value is a reference or const reference, a specialized typemap must
- * handle it, including declaration of c_result ($result).
- */
- if (!is_void && (!ignored_method || pure_virtual)) {
- if (!SwigType_isclass(returntype)) {
- if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
- String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
- Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL);
- Delete(construct_result);
- } else {
- Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL);
- }
- } else {
- String *cres = SwigType_lstr(returntype, "c_result");
- Printf(w->code, "%s;\n", cres);
- Delete(cres);
- }
- }
-
- if (ignored_method) {
- if (!pure_virtual) {
- if (!is_void)
- Printf(w->code, "return ");
- String *super_call = Swig_method_call(super, l);
- Printf(w->code, "%s;\n", super_call);
- Delete(super_call);
- } else {
- Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
- SwigType_namestr(name));
- }
- } else {
- /* attach typemaps to arguments (C/C++ -> Ruby) */
- String *arglist = NewString("");
-
- Swig_director_parms_fixup(l);
-
- Swig_typemap_attach_parms("in", l, 0);
- Swig_typemap_attach_parms("directorin", l, w);
- Swig_typemap_attach_parms("directorargout", l, w);
-
- char source[256];
-
- int outputs = 0;
- if (!is_void && !asvoid)
- outputs++;
-
- /* build argument list and type conversion string */
- idx = 0; p = l;
- while ( p ) {
-
- if (Getattr(p, "tmap:ignore")) {
- p = Getattr(p, "tmap:ignore:next");
- continue;
- }
-
- if (Getattr(p, "tmap:directorargout") != 0)
- outputs++;
-
- if ( checkAttribute( p, "tmap:in:numinputs", "0") ) {
- p = Getattr(p, "tmap:in:next");
- continue;
- }
-
- String *parameterName = Getattr(p, "name");
- String *parameterType = Getattr(p, "type");
-
- Putc(',', arglist);
- if ((tm = Getattr(p, "tmap:directorin")) != 0) {
- sprintf(source, "obj%d", idx++);
- String *input = NewString(source);
- Setattr(p, "emit:directorinput", input);
- Replaceall(tm, "$input", input);
- Replaceall(tm, "$owner", "0");
- Delete(input);
- Printv(wrap_args, tm, "\n", NIL);
- Wrapper_add_localv(w, source, "VALUE", source, "= Qnil", NIL);
- Printv(arglist, source, NIL);
- p = Getattr(p, "tmap:directorin:next");
- continue;
- } else if (Cmp(parameterType, "void")) {
- /**
- * Special handling for pointers to other C++ director classes.
- * Ideally this would be left to a typemap, but there is currently no
- * way to selectively apply the dynamic_cast<> to classes that have
- * directors. In other words, the type "SwigDirector_$1_lname" only exists
- * for classes with directors. We avoid the problem here by checking
- * module.wrap::directormap, but it's not clear how to get a typemap to
- * do something similar. Perhaps a new default typemap (in addition
- * to SWIGTYPE) called DIRECTORTYPE?
- */
- if (SwigType_ispointer(parameterType) || SwigType_isreference(parameterType)) {
- Node *modname = Getattr(parent, "module");
- Node *target = Swig_directormap(modname, parameterType);
- sprintf(source, "obj%d", idx++);
- String *nonconst = 0;
- /* strip pointer/reference --- should move to Swig/stype.c */
- String *nptype = NewString(Char(parameterType) + 2);
- /* name as pointer */
- String *ppname = Copy(parameterName);
- if (SwigType_isreference(parameterType)) {
- Insert(ppname, 0, "&");
- }
- /* if necessary, cast away const since Ruby doesn't support it! */
- if (SwigType_isconst(nptype)) {
- nonconst = NewStringf("nc_tmp_%s", parameterName);
- String *nonconst_i = NewStringf("= const_cast< %s >(%s)", SwigType_lstr(parameterType, 0), ppname);
- Wrapper_add_localv(w, nonconst, SwigType_lstr(parameterType, 0), nonconst, nonconst_i, NIL);
- Delete(nonconst_i);
- Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number,
- "Target language argument '%s' discards const in director method %s::%s.\n", SwigType_str(parameterType, parameterName),
- SwigType_namestr(c_classname), SwigType_namestr(name));
- } else {
- nonconst = Copy(ppname);
- }
- Delete(nptype);
- Delete(ppname);
- String *mangle = SwigType_manglestr(parameterType);
- if (target) {
- String *director = NewStringf("director_%s", mangle);
- Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL);
- Wrapper_add_localv(w, source, "VALUE", source, "= Qnil", NIL);
- Printf(wrap_args, "%s = dynamic_cast<Swig::Director *>(%s);\n", director, nonconst);
- Printf(wrap_args, "if (!%s) {\n", director);
- Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
- Printf(wrap_args, "} else {\n");
- Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director);
- Printf(wrap_args, "}\n");
- Delete(director);
- Printv(arglist, source, NIL);
- } else {
- Wrapper_add_localv(w, source, "VALUE", source, "= Qnil", NIL);
- Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
- //Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n",
- // source, nonconst, base);
- Printv(arglist, source, NIL);
- }
- Delete(mangle);
- Delete(nonconst);
- } else {
- Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
- "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(parameterType, 0),
- SwigType_namestr(c_classname), SwigType_namestr(name));
- status = SWIG_NOWRAP;
- break;
- }
- }
- p = nextSibling(p);
- }
-
- /* declare Ruby return value */
- String *value_result = NewStringf("VALUE SWIGUNUSED %s", Swig_cresult_name());
- Wrapper_add_local(w, Swig_cresult_name(), value_result);
- Delete(value_result);
-
- /* wrap complex arguments to VALUEs */
- Printv(w->code, wrap_args, NIL);
-
- /* pass the method call on to the Ruby object */
- exceptionSafeMethodCall(classname, n, w, idx, arglist, initstack);
-
- /*
- * Ruby method may return a simple object, or an Array of objects.
- * For in/out arguments, we have to extract the appropriate VALUEs from the Array,
- * then marshal everything back to C/C++ (return value and output arguments).
- */
-
- /* Marshal return value and other outputs (if any) from VALUE to C/C++ type */
-
- String *cleanup = NewString("");
- String *outarg = NewString("");
-
- if (outputs > 1) {
- Wrapper_add_local(w, "output", "VALUE output");
- Printf(w->code, "if (TYPE(%s) != T_ARRAY) {\n", Swig_cresult_name());
- Printf(w->code, "Ruby_DirectorTypeMismatchException(\"Ruby method failed to return an array.\");\n");
- Printf(w->code, "}\n");
- }
-
- idx = 0;
-
- /* Marshal return value */
- if (!is_void) {
- tm = Swig_typemap_lookup("directorout", n, Swig_cresult_name(), w);
- if (tm != 0) {
- if (outputs > 1 && !asvoid ) {
- Printf(w->code, "output = rb_ary_entry(%s, %d);\n", Swig_cresult_name(), idx++);
- Replaceall(tm, "$input", "output");
- } else {
- Replaceall(tm, "$input", Swig_cresult_name());
- }
- /* TODO check this */
- if (Getattr(n, "wrap:disown")) {
- Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
- } else {
- Replaceall(tm, "$disown", "0");
- }
- Replaceall(tm, "$result", "c_result");
- Printv(w->code, tm, "\n", NIL);
- } else {
- Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
- "Unable to use return type %s in director method %s::%s (skipping method).\n", SwigType_str(returntype, 0),
- SwigType_namestr(c_classname), SwigType_namestr(name));
- status = SWIG_ERROR;
- }
- }
-
- /* Marshal outputs */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
- if (outputs > 1) {
- Printf(w->code, "output = rb_ary_entry(%s, %d);\n", Swig_cresult_name(), idx++);
- Replaceall(tm, "$result", "output");
- } else {
- Replaceall(tm, "$result", Swig_cresult_name());
- }
- Replaceall(tm, "$input", Getattr(p, "emit:directorinput"));
- Printv(w->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:directorargout:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- Delete(arglist);
- Delete(cleanup);
- Delete(outarg);
- }
-
- /* any existing helper functions to handle this? */
- if (!is_void) {
- if (!(ignored_method && !pure_virtual)) {
- String *rettype = SwigType_str(returntype, 0);
- if (!SwigType_isreference(returntype)) {
- Printf(w->code, "return (%s) c_result;\n", rettype);
- } else {
- Printf(w->code, "return (%s) *c_result;\n", rettype);
- }
- Delete(rettype);
- }
- }
-
- Printf(w->code, "}\n");
-
- // We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
- String *inline_extra_method = NewString("");
- if (dirprot_mode() && !is_public(n) && !pure_virtual) {
- Printv(inline_extra_method, declaration, NIL);
- String *extra_method_name = NewStringf("%sSwigPublic", name);
- Replaceall(inline_extra_method, name, extra_method_name);
- Replaceall(inline_extra_method, ";\n", " {\n ");
- if (!is_void)
- Printf(inline_extra_method, "return ");
- String *methodcall = Swig_method_call(super, l);
- Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
- Delete(methodcall);
- Delete(extra_method_name);
- }
-
- /* emit the director method */
- if (status == SWIG_OK) {
- if (!Getattr(n, "defaultargs")) {
- Replaceall(w->code, "$symname", symname);
- Wrapper_print(w, f_directors);
- Printv(f_directors_h, declaration, NIL);
- Printv(f_directors_h, inline_extra_method, NIL);
- }
- }
-
- /* clean up */
- Delete(wrap_args);
- Delete(pclassname);
- DelWrapper(w);
- return status;
- }
-
- virtual int classDirectorConstructors(Node *n) {
- return Language::classDirectorConstructors(n);
- }
-
- virtual int classDirectorMethods(Node *n) {
- return Language::classDirectorMethods(n);
- }
-
- virtual int classDirectorDisown(Node *n) {
- return Language::classDirectorDisown(n);
- }
-
- String *runtimeCode() {
- String *s = NewString("");
- String *shead = Swig_include_sys("rubyhead.swg");
- if (!shead) {
- Printf(stderr, "*** Unable to open 'rubyhead.swg'\n");
- } else {
- Append(s, shead);
- Delete(shead);
- }
- String *serrors = Swig_include_sys("rubyerrors.swg");
- if (!serrors) {
- Printf(stderr, "*** Unable to open 'rubyerrors.swg'\n");
- } else {
- Append(s, serrors);
- Delete(serrors);
- }
- String *strack = Swig_include_sys("rubytracking.swg");
- if (!strack) {
- Printf(stderr, "*** Unable to open 'rubytracking.swg'\n");
- } else {
- Append(s, strack);
- Delete(strack);
- }
- String *sapi = Swig_include_sys("rubyapi.swg");
- if (!sapi) {
- Printf(stderr, "*** Unable to open 'rubyapi.swg'\n");
- } else {
- Append(s, sapi);
- Delete(sapi);
- }
- String *srun = Swig_include_sys("rubyrun.swg");
- if (!srun) {
- Printf(stderr, "*** Unable to open 'rubyrun.swg'\n");
- } else {
- Append(s, srun);
- Delete(srun);
- }
- return s;
- }
-
- String *defaultExternalRuntimeFilename() {
- return NewString("swigrubyrun.h");
- }
-
- /*----------------------------------------------------------------------
- * kwargsSupport()
- *--------------------------------------------------------------------*/
-
- bool kwargsSupport() const {
- // kwargs support isn't actually implemented, but changing to return false may break something now as it turns on compactdefaultargs
- return true;
- }
-}; /* class RUBY */
-
-/* -----------------------------------------------------------------------------
- * swig_ruby() - Instantiate module
- * ----------------------------------------------------------------------------- */
-
-static Language *new_swig_ruby() {
- return new RUBY();
-}
-extern "C" Language *swig_ruby(void) {
- return new_swig_ruby();
-}
-
-
-/*
- * Local Variables:
- * c-basic-offset: 2
- * End:
- */
diff --git a/contrib/tools/swig/Source/Modules/scilab.cxx b/contrib/tools/swig/Source/Modules/scilab.cxx
deleted file mode 100644
index aabd2d8426..0000000000
--- a/contrib/tools/swig/Source/Modules/scilab.cxx
+++ /dev/null
@@ -1,1167 +0,0 @@
-/* ----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * scilab.cxx
- *
- * Scilab language module for SWIG.
- * --------------------------------------------------------------------------*/
-
-#include "swigmod.h"
-#include <cstddef>
-#include <cstdlib>
-
-static const int SCILAB_IDENTIFIER_NAME_CHAR_MAX = 24;
-
-static const char *usage = (char *) " \
-Scilab options (available with -scilab)\n \
- -builder - Generate a Scilab builder script\n \
- -buildercflags <cflags> - Add <cflags> to the builder compiler flags\n \
- -builderflagscript <file> - Set the Scilab script <file> to use by builder to configure the build flags\n \
- -builderldflags <ldflags> - Add <ldflags> to the builder linker flags\n \
- -buildersources <files> - Add the (comma separated) files <files> to the builder sources\n \
- -builderverbositylevel <level> - Set the builder verbosity level to <level> (default 0: off, 2: high)\n \
- -gatewayxml <gateway_id> - Generate gateway xml with the given <gateway_id>\n \
-\n";
-
-
-class SCILAB:public Language {
-protected:
- /* General objects used for holding the strings */
- File *beginSection;
- File *runtimeSection;
- File *headerSection;
- File *wrappersSection;
- File *initSection;
-
- String *variablesCode;
-
- bool generateBuilder;
- File *builderFile;
- String *builderCode;
- String *builderCode5;
- String *builderCode6;
- int builderFunctionCount;
-
- List *sourceFileList;
- List *cflags;
- List *ldflags;
-
- String *verboseBuildLevel;
- String *buildFlagsScript;
-
- String *gatewayHeader;
- String *gatewayHeaderV5;
- String *gatewayHeaderV6;
-
- bool createGatewayXML;
- File *gatewayXMLFile;
- String *gatewayXML;
- String *gatewayID;
- int primitiveID;
-
- bool createLoader;
- File *loaderFile;
- String *loaderScript;
- String *loaderScript5;
- String *loaderScript6;
- int loaderFunctionCount;
-public:
-
- /* ------------------------------------------------------------------------
- * main()
- * ----------------------------------------------------------------------*/
-
- virtual void main(int argc, char *argv[]) {
- generateBuilder = false;
- sourceFileList = NewList();
- cflags = NewList();
- ldflags = NewList();
- verboseBuildLevel = NULL;
- buildFlagsScript = NULL;
-
- gatewayHeader = NULL;
- gatewayHeaderV5 = NULL;
- gatewayHeaderV6 = NULL;
-
- createGatewayXML = false;
- gatewayXML = NULL;
- gatewayXMLFile = NULL;
- gatewayID = NULL;
-
- createLoader = true;
- loaderFile = NULL;
- loaderScript = NULL;
-
- /* Manage command line arguments */
- for (int argIndex = 1; argIndex < argc; argIndex++) {
- if (argv[argIndex] != NULL) {
- if (strcmp(argv[argIndex], "-help") == 0) {
- Printf(stdout, "%s\n", usage);
- } else if (strcmp(argv[argIndex], "-builder") == 0) {
- Swig_mark_arg(argIndex);
- generateBuilder = true;
- createLoader = false;
- } else if (strcmp(argv[argIndex], "-buildersources") == 0) {
- if (argv[argIndex + 1] != NULL) {
- Swig_mark_arg(argIndex);
- char *sourceFile = strtok(argv[argIndex + 1], ",");
- while (sourceFile != NULL) {
- Insert(sourceFileList, Len(sourceFileList), sourceFile);
- sourceFile = strtok(NULL, ",");
- }
- Swig_mark_arg(argIndex + 1);
- }
- } else if (strcmp(argv[argIndex], "-buildercflags") == 0) {
- Swig_mark_arg(argIndex);
- if (argv[argIndex + 1] != NULL) {
- Insert(cflags, Len(cflags), argv[argIndex + 1]);
- Swig_mark_arg(argIndex + 1);
- }
- } else if (strcmp(argv[argIndex], "-builderldflags") == 0) {
- Swig_mark_arg(argIndex);
- if (argv[argIndex + 1] != NULL) {
- Insert(ldflags, Len(ldflags), argv[argIndex + 1]);
- Swig_mark_arg(argIndex + 1);
- }
- } else if (strcmp(argv[argIndex], "-builderverbositylevel") == 0) {
- Swig_mark_arg(argIndex);
- verboseBuildLevel = NewString(argv[argIndex + 1]);
- Swig_mark_arg(argIndex + 1);
- } else if (strcmp(argv[argIndex], "-builderflagscript") == 0) {
- Swig_mark_arg(argIndex);
- buildFlagsScript = NewString(argv[argIndex + 1]);
- Swig_mark_arg(argIndex + 1);
- } else if (strcmp(argv[argIndex], "-gatewayxml") == 0) {
- Swig_mark_arg(argIndex);
- createGatewayXML = true;
- gatewayID = NewString(argv[argIndex + 1]);
- Swig_mark_arg(argIndex + 1);
- }
- }
- }
-
- if (verboseBuildLevel == NULL) {
- verboseBuildLevel = NewString("0");
- }
-
- /* Set language-specific subdirectory in SWIG library */
- SWIG_library_directory("scilab");
-
- /* Add a symbol to the parser for conditional compilation */
- Preprocessor_define("SWIGSCILAB 1", 0);
-
- /* Set scilab configuration file */
- SWIG_config_file("scilab.swg");
-
- /* Set typemap for scilab */
- SWIG_typemap_lang("scilab");
-
- allow_overloading();
- }
-
- /* ------------------------------------------------------------------------
- * top()
- * ----------------------------------------------------------------------*/
-
- virtual int top(Node *node) {
-
- /* Get the module name */
- String *gatewayName = Getattr(node, "name");
-
- // Set library name
- String *gatewayLibraryName = NewStringf("lib%s", gatewayName);
-
- /* Get the output file name */
- String *outputFilename = Getattr(node, "outfile");
-
- /* Initialize I/O */
- beginSection = NewFile(outputFilename, "w", SWIG_output_files());
- if (!beginSection) {
- FileErrorDisplay(outputFilename);
- Exit(EXIT_FAILURE);
- }
- runtimeSection = NewString("");
- initSection = NewString("");
- headerSection = NewString("");
- wrappersSection = NewString("");
-
- /* Register file targets with the SWIG file handler */
- Swig_register_filebyname("begin", beginSection);
- Swig_register_filebyname("header", headerSection);
- Swig_register_filebyname("wrapper", wrappersSection);
- Swig_register_filebyname("runtime", runtimeSection);
- Swig_register_filebyname("init", initSection);
-
- /* Output module initialization code */
- Swig_banner(beginSection);
-
- Swig_obligatory_macros(runtimeSection, "SCILAB");
-
- // Gateway header source merged with wrapper source in nobuilder mode
- if (!generateBuilder)
- startGatewayHeader(gatewayLibraryName);
-
- // Create builder file if required
- if (generateBuilder) {
- createBuilderFile(outputFilename);
- }
-
- // Create gateway XML if required
- if (createGatewayXML) {
- createGatewayXMLFile(gatewayName);
- }
-
- // Create loader script if required
- if (createLoader) {
- createLoaderFile(gatewayLibraryName);
- }
-
- // Module initialization function
- String *smallFunctionName = createSmallIdentifierName(gatewayName, SCILAB_IDENTIFIER_NAME_CHAR_MAX - 5);
- String *gatewayInitFunctionName = NewStringf("%s_Init", gatewayName);
- String *gatewayInitSmallFunctionName = NewStringf("%s_Init", smallFunctionName);
- String *wrapperFunctionName = NewStringf("SWIG_%s_Init", gatewayName);
-
- /* Add initialization function to builder table */
- addFunctionToScilab(gatewayInitFunctionName, gatewayInitSmallFunctionName, wrapperFunctionName);
-
- // Add helper functions to builder table
- addHelperFunctions();
-
- // Open Scilab wrapper variables creation function
- variablesCode = NewString("");
- Printf(variablesCode, "int SWIG_CreateScilabVariables(void *_pvApiCtx) {");
-
- /* Emit code for children */
- if (CPlusPlus) {
- Printf(wrappersSection, "extern \"C\" {\n");
- }
-
- Language::top(node);
-
- if (CPlusPlus) {
- Printf(wrappersSection, "}\n");
- }
- // Close Scilab wrapper variables creation function
- Printf(variablesCode, " return SWIG_OK;\n}\n");
-
- // Add Builder footer code and save
- if (generateBuilder) {
- saveBuilderFile(gatewayLibraryName);
- }
-
- /* Close the init function and rename with module name */
- Printf(initSection, "return 0;\n}\n");
- Replaceall(initSection, "<module>", gatewayName);
-
- /* Write all to the wrapper file */
- SwigType_emit_type_table(runtimeSection, wrappersSection); // Declare pointer types, ... (Ex: SWIGTYPE_p_p_double)
-
- // Gateway header source merged with wrapper source in nobuilder mode
- if (!generateBuilder) {
- terminateGatewayHeader(gatewayLibraryName);
- Printv(initSection, gatewayHeader, NIL);
- }
-
- Dump(runtimeSection, beginSection);
- Dump(headerSection, beginSection);
- Dump(wrappersSection, beginSection);
- Dump(variablesCode, beginSection);
- Wrapper_pretty_print(initSection, beginSection);
-
- if (createGatewayXML) {
- saveGatewayXMLFile();
- }
-
- if (createLoader) {
- saveLoaderFile(gatewayLibraryName);
- }
-
- /* Cleanup files */
- Delete(runtimeSection);
- Delete(headerSection);
- Delete(wrappersSection);
- Delete(initSection);
- Delete(beginSection);
-
- Delete(sourceFileList);
- Delete(cflags);
- Delete(ldflags);
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------------------
- * emitBanner()
- * ----------------------------------------------------------------------*/
-
- void emitBanner(File *f) {
- Printf(f, "// ----------------------------------------------------------------------------\n");
- Swig_banner_target_lang(f, "// ");
- Printf(f, "// ----------------------------------------------------------------------------- */\n\n");
- }
-
- /* ------------------------------------------------------------------------
- * functionWrapper()
- * ----------------------------------------------------------------------*/
-
- virtual int functionWrapper(Node *node) {
-
- /* Get some useful attributes of this function */
- String *functionName = Getattr(node, "sym:name");
- String *smallFunctionName = createSmallIdentifierName(functionName);
-
- SwigType *functionReturnType = Getattr(node, "type");
- ParmList *functionParamsList = Getattr(node, "parms");
-
- int paramIndex = 0; // Used for loops over ParmsList
- Parm *param = NULL; // Used for loops over ParamsList
-
- /* Create the wrapper object */
- Wrapper *wrapper = NewWrapper();
-
- /* Create the function wrapper name */
- String *wrapperName = Swig_name_wrapper(functionName);
-
- /* Deal with overloading */
- String *overloadedName = Copy(wrapperName);
- /* Determine whether the function is overloaded or not */
- bool isOverloaded = ! !Getattr(node, "sym:overloaded");
- /* Determine whether the function is the last overloaded */
- bool isLastOverloaded = isOverloaded && !Getattr(node, "sym:nextSibling");
-
- if (!isOverloaded && !addSymbol(functionName, node)) {
- DelWrapper(wrapper);
- return SWIG_ERROR;
- }
-
- if (isOverloaded) {
- Append(overloadedName, Getattr(node, "sym:overname"));
- }
-
- /* Write the wrapper function definition (standard Scilab gateway function prototype) */
- Printv(wrapper->def, "SWIGEXPORT int ", overloadedName, "(SWIG_GatewayParameters) {", NIL);
-
- /* Emit all of the local variables for holding arguments */
- // E.g.: double arg1;
- emit_parameter_variables(functionParamsList, wrapper);
-
- /* Attach typemaps to the parameter list */
- // Add local variables used in typemaps (iRows, iCols, ...)
- emit_attach_parmmaps(functionParamsList, wrapper);
- Setattr(node, "wrap:parms", functionParamsList);
-
- /* Check input/output arguments count */
- int maxInputArguments = emit_num_arguments(functionParamsList);
- int minInputArguments = emit_num_required(functionParamsList);
- int minOutputArguments = 0;
- int maxOutputArguments = 1;
-
- if (!emit_isvarargs(functionParamsList)) {
- Printf(wrapper->code, "SWIG_CheckInputArgument(pvApiCtx, $mininputarguments, $maxinputarguments);\n");
- }
- else {
- Printf(wrapper->code, "SWIG_CheckInputArgumentAtLeast(pvApiCtx, $mininputarguments-1);\n");
- }
- Printf(wrapper->code, "SWIG_CheckOutputArgument(pvApiCtx, $minoutputarguments, $maxoutputarguments);\n");
-
- /* Set context */
- Printf(wrapper->code, "SWIG_Scilab_SetFuncName(fname);\n");
- Printf(wrapper->code, "SWIG_Scilab_SetApiContext(pvApiCtx);\n");
-
- /* Write typemaps(in) */
-
- for (paramIndex = 0, param = functionParamsList; paramIndex < maxInputArguments; ++paramIndex) {
- // Ignore parameter if the typemap specifies numinputs=0
- while (checkAttribute(param, "tmap:in:numinputs", "0")) {
- param = Getattr(param, "tmap:in:next");
- }
-
- SwigType *paramType = Getattr(param, "type");
- String *paramTypemap = Getattr(param, "tmap:in");
-
- if (paramTypemap) {
- // Replace $input by the position on Scilab stack
- String *source = NewString("");
- Printf(source, "%d", paramIndex + 1);
- Setattr(param, "emit:input", source);
- Replaceall(paramTypemap, "$input", Getattr(param, "emit:input"));
-
- if (Getattr(param, "wrap:disown") || (Getattr(param, "tmap:in:disown"))) {
- Replaceall(paramTypemap, "$disown", "SWIG_POINTER_DISOWN");
- } else {
- Replaceall(paramTypemap, "$disown", "0");
- }
-
- if (paramIndex >= minInputArguments) { /* Optional input argument management */
- Printf(wrapper->code, "if (SWIG_NbInputArgument(pvApiCtx) > %d) {\n%s\n}\n", paramIndex, paramTypemap);
- } else {
- Printf(wrapper->code, "%s\n", paramTypemap);
- }
- param = Getattr(param, "tmap:in:next");
- } else {
- Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(paramType, 0));
- break;
- }
- }
-
- /* TODO write constraints */
-
- Setattr(node, "wrap:name", overloadedName);
-
- /* Emit the function call */
- Swig_director_emit_dynamic_cast(node, wrapper);
- String *functionActionCode = emit_action(node);
-
- /* Insert the return variable */
- emit_return_variable(node, functionReturnType, wrapper);
-
- /* Return the function value if necessary */
- String *functionReturnTypemap = Swig_typemap_lookup_out("out", node, Swig_cresult_name(), wrapper, functionActionCode);
- if (functionReturnTypemap) {
- // Result is actually the position of output value on stack
- if (Len(functionReturnTypemap) > 0) {
- Printf(wrapper->code, "SWIG_Scilab_SetOutputPosition(%d);\n", 1);
- }
- Replaceall(functionReturnTypemap, "$result", "1");
-
- if (GetFlag(node, "feature:new")) {
- Replaceall(functionReturnTypemap, "$owner", "1");
- } else {
- Replaceall(functionReturnTypemap, "$owner", "0");
- }
-
- Printf(wrapper->code, "%s\n", functionReturnTypemap);
-
- /* If the typemap is not empty, the function return one more argument than the typemaps gives */
- if (Len(functionReturnTypemap) > 0) {
- minOutputArguments++;
- maxOutputArguments++;
- }
- Delete(functionReturnTypemap);
-
- } else {
- Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(functionReturnType, 0),
- functionName);
- }
-
- /* Write typemaps(out) */
- for (param = functionParamsList; param;) {
- String *paramTypemap = Getattr(param, "tmap:argout");
- if (paramTypemap) {
- minOutputArguments++;
- maxOutputArguments++;
- Printf(wrapper->code, "SWIG_Scilab_SetOutputPosition(%d);\n", minOutputArguments);
- String *result = NewString("");
- Printf(result, "%d", minOutputArguments);
- Replaceall(paramTypemap, "$result", result);
- Printf(wrapper->code, "%s\n", paramTypemap);
- Delete(paramTypemap);
- param = Getattr(param, "tmap:argout:next");
- } else {
- param = nextSibling(param);
- }
- }
- /* Add cleanup code */
- for (param = functionParamsList; param;) {
- String *tm;
- if ((tm = Getattr(param, "tmap:freearg"))) {
- if (tm && (Len(tm) != 0)) {
- Printf(wrapper->code, "%s\n", tm);
- }
- param = Getattr(param, "tmap:freearg:next");
- } else {
- param = nextSibling(param);
- }
- }
-
- /* See if there is any return cleanup code */
- String *tm;
- if ((tm = Swig_typemap_lookup("ret", node, Swig_cresult_name(), 0))) {
- Printf(wrapper->code, "%s\n", tm);
- Delete(tm);
- }
-
- /* Close the function(ok) */
- Printv(wrapper->code, "return SWIG_OK;\n", NIL);
- Printv(wrapper->code, "}\n", NIL);
-
- /* Add the failure cleanup code */
- /* TODO */
-
- /* Final substitutions if applicable */
- Replaceall(wrapper->code, "$symname", functionName);
-
- /* Set CheckInputArgument and CheckOutputArgument input arguments */
- if (maxOutputArguments < 1) {
- maxOutputArguments = 1;
- }
- if (minOutputArguments == 1) {
- minOutputArguments = 0;
- }
- String *argnumber = NewString("");
- Printf(argnumber, "%d", minInputArguments);
- Replaceall(wrapper->code, "$mininputarguments", argnumber);
-
- argnumber = NewString("");
- Printf(argnumber, "%d", maxInputArguments);
- Replaceall(wrapper->code, "$maxinputarguments", argnumber);
-
- argnumber = NewString("");
- Printf(argnumber, "%d", minOutputArguments);
- Replaceall(wrapper->code, "$minoutputarguments", argnumber);
-
- argnumber = NewString("");
- Printf(argnumber, "%d", maxOutputArguments);
- Replaceall(wrapper->code, "$maxoutputarguments", argnumber);
-
- /* Dump the function out */
- Wrapper_print(wrapper, wrappersSection);
-
- /* Update builder.sce contents */
- if (isLastOverloaded) {
- addFunctionToScilab(functionName, smallFunctionName, wrapperName);
- dispatchFunction(node);
- }
-
- if (!isOverloaded) {
- addFunctionToScilab(functionName, smallFunctionName, wrapperName);
- }
-
- /* tidy up */
- Delete(overloadedName);
- Delete(wrapperName);
- DelWrapper(wrapper);
-
- return SWIG_OK;
- }
-
- /* -----------------------------------------------------------------------
- * dispatchFunction()
- * ----------------------------------------------------------------------- */
-
- void dispatchFunction(Node *node) {
- Wrapper *wrapper = NewWrapper();
-
- String *functionName = Getattr(node, "sym:name");
- String *wrapperName = Swig_name_wrapper(functionName);
- int maxargs = 0;
-
- /* Generate the dispatch function */
- String *dispatch = Swig_overload_dispatch(node, "return %s(SWIG_GatewayArguments);", &maxargs);
- String *tmp = NewString("");
-
- Printv(wrapper->def, "SWIGEXPORT int ", wrapperName, "(SWIG_GatewayParameters) {\n", NIL);
-
- /* Get the number of the parameters */
- Wrapper_add_local(wrapper, "argc", "int argc = SWIG_NbInputArgument(pvApiCtx)");
- Printf(tmp, "int argv[%d] = {", maxargs);
- for (int j = 0; j < maxargs; ++j) {
- Printf(tmp, "%s%d", j ? "," : " ", j + 1);
- }
- Printf(tmp, "}");
- Wrapper_add_local(wrapper, "argv", tmp);
-
- Printf(wrapper->code, "SWIG_Scilab_SetApiContext(pvApiCtx);\n");
-
- /* Dump the dispatch function */
- Printv(wrapper->code, dispatch, "\n", NIL);
- Printf(wrapper->code, "Scierror(999, _(\"No matching function for overload\"));\n");
- Printf(wrapper->code, "return SWIG_ERROR;\n");
- Printv(wrapper->code, "}\n", NIL);
- Wrapper_print(wrapper, wrappersSection);
-
- Delete(tmp);
- DelWrapper(wrapper);
- Delete(dispatch);
- Delete(wrapperName);
- }
-
- /* -----------------------------------------------------------------------
- * variableWrapper()
- * ----------------------------------------------------------------------- */
-
- virtual int variableWrapper(Node *node) {
-
- /* Get information about variable */
- String *origVariableName = Getattr(node, "name"); // Ex: Shape::nshapes
- String *variableName = Getattr(node, "sym:name"); // Ex; Shape_nshapes (can be used for function names, ...)
- String *smallVariableName = createSmallIdentifierName(variableName, SCILAB_IDENTIFIER_NAME_CHAR_MAX - 4);
-
- /* Manage GET function */
- Wrapper *getFunctionWrapper = NewWrapper();
- String *getFunctionName = Swig_name_get(NSPACE_TODO, variableName);
- String *scilabGetFunctionName = Swig_name_get(NSPACE_TODO, variableName);
- String *scilabGetSmallFunctionName = Swig_name_get(NSPACE_TODO, smallVariableName);
-
- Setattr(node, "wrap:name", getFunctionName);
- Printv(getFunctionWrapper->def, "SWIGEXPORT int ", getFunctionName, "(SWIG_GatewayParameters) {\n", NIL);
-
- /* Check the number of input and output */
- Printf(getFunctionWrapper->def, "SWIG_CheckInputArgument(pvApiCtx, 0, 0);\n");
- Printf(getFunctionWrapper->def, "SWIG_CheckOutputArgument(pvApiCtx, 0, 1);\n");
- Printf(getFunctionWrapper->def, "SWIG_Scilab_SetApiContext(pvApiCtx);\n");
-
- String *varoutTypemap = Swig_typemap_lookup("varout", node, origVariableName, 0);
- if (varoutTypemap != NULL) {
- Printf(getFunctionWrapper->code, "SWIG_Scilab_SetOutputPosition(%d);\n", 1);
- Replaceall(varoutTypemap, "$value", origVariableName);
- Replaceall(varoutTypemap, "$result", "1");
- emit_action_code(node, getFunctionWrapper->code, varoutTypemap);
- Delete(varoutTypemap);
- }
- Append(getFunctionWrapper->code, "return SWIG_OK;\n");
- Append(getFunctionWrapper->code, "}\n");
- Wrapper_print(getFunctionWrapper, wrappersSection);
-
- /* Add function to builder table */
- addFunctionToScilab(scilabGetFunctionName, scilabGetSmallFunctionName, getFunctionName);
-
- /* Manage SET function */
- if (is_assignable(node)) {
- Wrapper *setFunctionWrapper = NewWrapper();
- String *setFunctionName = Swig_name_set(NSPACE_TODO, variableName);
- String *scilabSetFunctionName = Swig_name_set(NSPACE_TODO, variableName);
- String *scilabSetSmallFunctionName = Swig_name_set(NSPACE_TODO, smallVariableName);
-
- Setattr(node, "wrap:name", setFunctionName);
- Printv(setFunctionWrapper->def, "SWIGEXPORT int ", setFunctionName, "(SWIG_GatewayParameters) {\n", NIL);
-
- /* Check the number of input and output */
- Printf(setFunctionWrapper->def, "SWIG_CheckInputArgument(pvApiCtx, 1, 1);\n");
- Printf(setFunctionWrapper->def, "SWIG_CheckOutputArgument(pvApiCtx, 0, 1);\n");
- Printf(setFunctionWrapper->def, "SWIG_Scilab_SetApiContext(pvApiCtx);\n");
-
- String *varinTypemap = Swig_typemap_lookup("varin", node, origVariableName, 0);
- if (varinTypemap != NULL) {
- Replaceall(varinTypemap, "$input", "1");
- emit_action_code(node, setFunctionWrapper->code, varinTypemap);
- Delete(varinTypemap);
- }
- Append(setFunctionWrapper->code, "return SWIG_OK;\n");
- Append(setFunctionWrapper->code, "}\n");
- Wrapper_print(setFunctionWrapper, wrappersSection);
-
- /* Add function to builder table */
- addFunctionToScilab(scilabSetFunctionName, scilabSetSmallFunctionName, setFunctionName);
-
- DelWrapper(setFunctionWrapper);
- }
- DelWrapper(getFunctionWrapper);
-
- return SWIG_OK;
- }
-
- /* -----------------------------------------------------------------------
- * constantWrapper()
- * ----------------------------------------------------------------------- */
-
- virtual int constantWrapper(Node *node) {
-
- /* Get the useful information from the node */
- String *nodeName = Getattr(node, "name");
- SwigType *type = Getattr(node, "type");
- String *constantName = Getattr(node, "sym:name");
- String *rawValue = Getattr(node, "rawval");
- String *constantValue = rawValue ? rawValue : Getattr(node, "value");
- String *constantTypemap = NULL;
-
- // If feature scilab:const enabled, constants & enums are wrapped to Scilab variables
- if (GetFlag(node, "feature:scilab:const")) {
- bool isConstant = ((SwigType_issimple(type)) || (SwigType_type(type) == T_STRING));
- bool isEnum = (Cmp(nodeType(node), "enumitem") == 0);
-
- if (isConstant || isEnum) {
- if (isEnum) {
- Setattr(node, "type", "double");
- constantValue = Getattr(node, "value");
- }
-
- constantTypemap = Swig_typemap_lookup("scilabconstcode", node, nodeName, 0);
- if (constantTypemap != NULL) {
-
- Setattr(node, "wrap:name", constantName);
- Replaceall(constantTypemap, "$result", constantName);
- Replaceall(constantTypemap, "$value", constantValue);
-
- emit_action_code(node, variablesCode, constantTypemap);
- Delete(constantTypemap);
- return SWIG_OK;
- }
- }
- }
-
- /* Create variables for member pointer constants, not supported by typemaps (like Python wrapper does) */
- if (SwigType_type(type) == T_MPOINTER) {
- String *wname = Swig_name_wrapper(constantName);
- String *str = SwigType_str(type, wname);
- Printf(headerSection, "static %s = %s;\n", str, constantValue);
- Delete(str);
- constantValue = wname;
- }
-
- // Constant names can have SCILAB_VARIABLE_NAME_CHAR_MAX because of suffixes "_get" added to function
- String *smallConstantName = createSmallIdentifierName(constantName, SCILAB_IDENTIFIER_NAME_CHAR_MAX - 4);
-
- /* Create GET function to get the constant value */
- Wrapper *getFunctionWrapper = NewWrapper();
- String *getFunctionName = Swig_name_get(NSPACE_TODO, constantName);
- String *scilabGetSmallFunctionName = Swig_name_get(NSPACE_TODO, smallConstantName);
- Setattr(node, "wrap:name", getFunctionName);
- Setattr(node, "wrap:name", getFunctionName);
- Printv(getFunctionWrapper->def, "SWIGEXPORT int ", getFunctionName, "(SWIG_GatewayParameters) {\n", NIL);
-
- /* Check the number of input and output */
- Printf(getFunctionWrapper->def, "SWIG_CheckInputArgument(pvApiCtx, 0, 0);\n");
- Printf(getFunctionWrapper->def, "SWIG_CheckOutputArgument(pvApiCtx, 0, 1);\n");
- Printf(getFunctionWrapper->def, "SWIG_Scilab_SetApiContext(pvApiCtx);\n");
-
- constantTypemap = Swig_typemap_lookup("constcode", node, nodeName, 0);
- if (constantTypemap != NULL) {
- Printf(getFunctionWrapper->code, "SWIG_Scilab_SetOutputPosition(%d);\n", 1);
- Replaceall(constantTypemap, "$value", constantValue);
- Replaceall(constantTypemap, "$result", "1");
- emit_action_code(node, getFunctionWrapper->code, constantTypemap);
- Delete(constantTypemap);
- }
-
- /* Dump the wrapper function */
- Append(getFunctionWrapper->code, "return SWIG_OK;\n");
- Append(getFunctionWrapper->code, "}\n");
- Wrapper_print(getFunctionWrapper, wrappersSection);
-
- /* Add the function to Scilab */
- addFunctionToScilab(getFunctionName, scilabGetSmallFunctionName, getFunctionName);
-
- DelWrapper(getFunctionWrapper);
-
- return SWIG_OK;
- }
-
- /* ---------------------------------------------------------------------
- * enumvalueDeclaration()
- * --------------------------------------------------------------------- */
-
- virtual int enumvalueDeclaration(Node *node) {
- static int iPreviousEnumValue = 0;
-
- if (GetFlag(node, "feature:scilab:const")) {
- // Compute the "absolute" value of enum if needed
- // (most of time enum values are a linked list of relative values)
- String *enumValue = Getattr(node, "enumvalue");
- String *enumValueEx = Getattr(node, "enumvalueex");
-
- // First enum value ?
- String *firstenumitem = Getattr(node, "firstenumitem");
- if (firstenumitem) {
- if (enumValue) {
- // Value is in 'enumvalue'
- iPreviousEnumValue = atoi(Char(enumValue));
- } else if (enumValueEx) {
- // Or value is in 'enumValueEx'
- iPreviousEnumValue = atoi(Char(enumValueEx));
-
- enumValue = NewString("");
- Printf(enumValue, "%d", iPreviousEnumValue);
- Setattr(node, "enumvalue", enumValue);
- }
- } else if (!enumValue && enumValueEx) {
- // Value is not specified, set it by incrementing last value
- enumValue = NewString("");
- Printf(enumValue, "%d", ++iPreviousEnumValue);
- Setattr(node, "enumvalue", enumValue);
- }
- // Enums in Scilab are mapped to double
- Setattr(node, "type", "double");
- }
-
- return Language::enumvalueDeclaration(node);
- }
-
- /* -----------------------------------------------------------------------
- * addHelperFunctions()
- * ----------------------------------------------------------------------- */
-
- void addHelperFunctions() {
- addFunctionToScilab("SWIG_this", "SWIG_this", "SWIG_this");
- addFunctionToScilab("SWIG_ptr", "SWIG_ptr", "SWIG_ptr");
- }
-
- /* -----------------------------------------------------------------------
- * addFunctionToScilab()
- * Declare a wrapped function in Scilab (builder, gateway, XML, ...)
- * ----------------------------------------------------------------------- */
-
- void addFunctionToScilab(const_String_or_char_ptr scilabFunctionName, const_String_or_char_ptr scilabSmallFunctionName, const_String_or_char_ptr wrapperFunctionName) {
- if (!generateBuilder)
- addFunctionInGatewayHeader(scilabFunctionName, scilabSmallFunctionName, wrapperFunctionName);
-
- if (generateBuilder) {
- addFunctionInScriptTable(scilabFunctionName, scilabSmallFunctionName, wrapperFunctionName, builderCode5, builderCode6);
- }
-
- if (createLoader) {
- addFunctionInLoader(scilabFunctionName, scilabSmallFunctionName);
- }
-
- if (gatewayXMLFile) {
- Printf(gatewayXML, "<PRIMITIVE gatewayId=\"%s\" primitiveId=\"%d\" primitiveName=\"%s\"/>\n", gatewayID, primitiveID++, scilabSmallFunctionName);
- }
- }
-
-
- /* -----------------------------------------------------------------------
- * createBuilderCode()
- * ----------------------------------------------------------------------- */
-
- void createBuilderFile(String *outputFilename) {
- String *builderFilename = NewStringf("builder.sce");
- builderFile = NewFile(builderFilename, "w", SWIG_output_files());
- if (!builderFile) {
- FileErrorDisplay(builderFilename);
- Exit(EXIT_FAILURE);
- }
- emitBanner(builderFile);
-
- builderFunctionCount = 0;
- builderCode = NewString("");
- builderCode5 = NewString("");
- builderCode6 = NewString("");
- Printf(builderCode, "mode(-1);\n");
- Printf(builderCode, "lines(0);\n"); /* Useful for automatic tests */
-
- // Scilab needs to be in the build directory
- Printf(builderCode, "originaldir = pwd();\n");
- Printf(builderCode, "builddir = get_absolute_file_path('builder.sce');\n");
- Printf(builderCode, "cd(builddir);\n");
-
- Printf(builderCode, "ilib_verbose(%s);\n", verboseBuildLevel);
-
- Printf(builderCode, "libs = [];\n");
-
- // Flags from command line arguments
- Printf(builderCode, "cflags = \"\";\n");
- for (int i = 0; i < Len(cflags); i++) {
- String *cflag = Getitem(cflags, i);
- Printf(builderCode, "cflags = cflags + \" %s\";\n", cflag);
- }
-
- if (Len(ldflags) > 0) {
- for (int i = 0; i < Len(ldflags); i++) {
- String *ldflag = Getitem(ldflags, i);
- if (i == 0) {
- Printf(builderCode, "ldflags = \"%s\";\n", ldflag);
- } else {
- Printf(builderCode, "ldflags = ldflags + \" %s\";\n", ldflag);
- }
- }
- } else {
- Printf(builderCode, "ldflags = \"\";\n");
- }
-
- // External script to set flags
- if (buildFlagsScript) {
- Printf(builderCode, "exec(\"%s\");\n", buildFlagsScript);
- Printf(builderCode, "cflags = cflags + getCompilationFlags();\n");
- Printf(builderCode, "ldflags = ldflags + getLinkFlags();\n");
- }
- // Additional sources
- Insert(sourceFileList, 0, outputFilename);
- for (int i = 0; i < Len(sourceFileList); i++) {
- String *sourceFile = Getitem(sourceFileList, i);
- if (i == 0) {
- Printf(builderCode, "files = \"%s\";\n", sourceFile);
- } else {
- Printf(builderCode, "files($ + 1) = \"%s\";\n", sourceFile);
- }
- }
-
- Printf(builderCode5, "table = [ ..\n");
- Printf(builderCode6, "table = [ ..\n");
- }
-
- /* -----------------------------------------------------------------------
- * addFunctionInBuilderCode()
- * Add a function wrapper in the function table of generated builder script
- * ----------------------------------------------------------------------- */
-
- void addFunctionInScriptTable(const_String_or_char_ptr scilabFunctionName, const_String_or_char_ptr scilabSmallFunctionName, const_String_or_char_ptr wrapperFunctionName, String *scriptCode5, String *scriptCode6) {
- if (++builderFunctionCount % 10 == 0) {
- Printf(scriptCode5, "];\ntable = [table; ..\n");
- Printf(scriptCode6, "];\ntable = [table; ..\n");
- }
- Printf(scriptCode5, "\"%s\",\"%s\"; ..\n", scilabSmallFunctionName, wrapperFunctionName);
- Printf(scriptCode6, "\"%s\",\"%s\"; ..\n", scilabFunctionName, wrapperFunctionName);
- }
-
- /* -----------------------------------------------------------------------
- * saveBuilderFile()
- * ----------------------------------------------------------------------- */
-
- void saveBuilderFile(String *gatewayName) {
- Printf(builderCode5, "];\n");
- Printf(builderCode6, "];\n");
-
- if (Equal(builderCode5, builderCode6)) {
- Append(builderCode, builderCode6);
- } else {
- Printf(builderCode, "ver = getversion('scilab');\n");
- Printf(builderCode, "if ver(1) < 6 then\n");
- Printf(builderCode, " // version is less or equal to 5.5.2\n");
- Printf(builderCode, " \n");
- Append(builderCode, builderCode5);
- Printf(builderCode, " \n");
- Printf(builderCode, "else\n");
- Printf(builderCode, " // version is 6.0.0 or more\n");
- Printf(builderCode, " \n");
- Append(builderCode, builderCode6);
- Printf(builderCode, " \n");
- Printf(builderCode, "end\n");
- }
-
- Printf(builderCode, "ierr = 0;\n");
- Printf(builderCode, "if ~isempty(table) then\n");
- Printf(builderCode, " ierr = execstr(\"ilib_build(''%s'', table, files, libs, [], ldflags, cflags);\", 'errcatch');\n", gatewayName);
- Printf(builderCode, " if ierr <> 0 then\n");
- Printf(builderCode, " err_msg = lasterror();\n");
- Printf(builderCode, " end\n");
- Printf(builderCode, "end\n");
- Printf(builderCode, "cd(originaldir);\n");
- Printf(builderCode, "if ierr <> 0 then\n");
- Printf(builderCode, " error(ierr, err_msg);\n");
- Printf(builderCode, "end\n");
- Printv(builderFile, builderCode, NIL);
-
- Delete(builderCode);
- Delete(builderFile);
- }
-
- /* -----------------------------------------------------------------------
- * createGatewayXMLFile()
- * This XML file is used by Scilab in the context of internal modules
- * ----------------------------------------------------------------------- */
-
- void createGatewayXMLFile(String *gatewayName) {
- String *gatewayXMLFilename = NewStringf("%s_gateway.xml", gatewayName);
- gatewayXMLFile = NewFile(gatewayXMLFilename, "w", SWIG_output_files());
- if (!gatewayXMLFile) {
- FileErrorDisplay(gatewayXMLFilename);
- Exit(EXIT_FAILURE);
- }
- // Add a slightly modified SWIG banner to the gateway XML ("--modify" is illegal in XML)
- gatewayXML = NewString("");
- Printf(gatewayXML, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
- Printf(gatewayXML, "<!--\n");
- Swig_banner_target_lang(gatewayXML, "");
- Printf(gatewayXML, "-->\n");
- Printf(gatewayXML, "<GATEWAY name=\"%s\">\n", gatewayName);
-
- primitiveID = 1;
- }
-
- /* -----------------------------------------------------------------------
- * saveGatewayXMLFile()
- * ----------------------------------------------------------------------- */
-
- void saveGatewayXMLFile() {
- Printf(gatewayXML, "</GATEWAY>\n");
- Printv(gatewayXMLFile, gatewayXML, NIL);
- Delete(gatewayXMLFile);
- }
-
- /* -----------------------------------------------------------------------
- * startGatewayHeader()
- * Start the gateway header
- * ----------------------------------------------------------------------- */
- void startGatewayHeader(String *gatewayLibraryName) {
- gatewayHeader = NewString("");
- Printf(gatewayHeader, "\n");
-
- gatewayHeaderV6 = NewString("");
- Printf(gatewayHeaderV6, "#ifdef __cplusplus\n");
- Printf(gatewayHeaderV6, "extern \"C\" {\n");
- Printf(gatewayHeaderV6, "#endif\n");
- Printf(gatewayHeaderV6, "#include \"c_gateway_prototype.h\"\n");
- Printf(gatewayHeaderV6, "#include \"addfunction.h\"\n");
- Printf(gatewayHeaderV6, "#ifdef __cplusplus\n");
- Printf(gatewayHeaderV6, "}\n");
- Printf(gatewayHeaderV6, "#endif\n");
- Printf(gatewayHeaderV6, "\n");
- Printf(gatewayHeaderV6, "#define MODULE_NAME L\"%s\"\n", gatewayLibraryName);
- Printf(gatewayHeaderV6, "#ifdef __cplusplus\n");
- Printf(gatewayHeaderV6, "extern \"C\"\n");
- Printf(gatewayHeaderV6, "#endif\n");
- Printf(gatewayHeaderV6, "SWIGEXPORT int %s(wchar_t *pwstFuncName) {\n", gatewayLibraryName);
- Printf(gatewayHeaderV6, "\n");
- }
-
- /* -----------------------------------------------------------------------
- * addFunctionInGatewayHeader()
- * Add a function in the gateway header
- * ----------------------------------------------------------------------- */
-
- void addFunctionInGatewayHeader(const_String_or_char_ptr scilabFunctionName, const_String_or_char_ptr scilabSmallFunctionName, const_String_or_char_ptr wrapperFunctionName) {
- if (gatewayHeaderV5 == NULL) {
- gatewayHeaderV5 = NewString("");
- Printf(gatewayHeaderV5, "static GenericTable Tab[] = {\n");
- } else
- Printf(gatewayHeaderV5, ",\n");
- Printf(gatewayHeaderV5, " {(Myinterfun)sci_gateway, (GT)%s, (char *)\"%s\"}", wrapperFunctionName, scilabSmallFunctionName);
-
- Printf(gatewayHeaderV6, "if (wcscmp(pwstFuncName, L\"%s\") == 0) { addCStackFunction((wchar_t *)L\"%s\", &%s, (wchar_t *)MODULE_NAME); }\n", scilabFunctionName, scilabFunctionName, wrapperFunctionName);
- }
-
- /* -----------------------------------------------------------------------
- * terminateGatewayHeader()
- * Terminates the gateway header
- * ----------------------------------------------------------------------- */
-
- void terminateGatewayHeader(String *gatewayLibraryName) {
- Printf(gatewayHeaderV5, "};\n");
- Printf(gatewayHeaderV5, "\n");
- Printf(gatewayHeaderV5, "#ifdef __cplusplus\n");
- Printf(gatewayHeaderV5, "extern \"C\" {\n");
- Printf(gatewayHeaderV5, "#endif\n");
- Printf(gatewayHeaderV5, "SWIGEXPORT int C2F(%s)() {\n", gatewayLibraryName);
- Printf(gatewayHeaderV5, " Rhs = Max(0, Rhs);\n");
- Printf(gatewayHeaderV5, " if (*(Tab[Fin-1].f) != NULL) {\n");
- Printf(gatewayHeaderV5, " if(pvApiCtx == NULL) {\n");
- Printf(gatewayHeaderV5, " pvApiCtx = (StrCtx *)MALLOC(sizeof(StrCtx));\n");
- Printf(gatewayHeaderV5, " }\n");
- Printf(gatewayHeaderV5, " pvApiCtx->pstName = (char *)Tab[Fin-1].name;\n");
- Printf(gatewayHeaderV5, " (*(Tab[Fin-1].f))(Tab[Fin-1].name,(GatefuncH)Tab[Fin-1].F);\n");
- Printf(gatewayHeaderV5, " }\n");
- Printf(gatewayHeaderV5, " return 0;\n");
- Printf(gatewayHeaderV5, "}\n");
- Printf(gatewayHeaderV5, "\n");
- Printf(gatewayHeaderV5, "#ifdef __cplusplus\n");
- Printf(gatewayHeaderV5, "}\n");
- Printf(gatewayHeaderV5, "#endif\n");
-
- Printf(gatewayHeaderV6, "return 1;\n");
- Printf(gatewayHeaderV6, "};\n");
-
- Printf(gatewayHeader, "#if SWIG_SCILAB_VERSION >= 600\n");
- Printv(gatewayHeader, gatewayHeaderV6, NIL);
- Printf(gatewayHeader, "#else\n");
- Printv(gatewayHeader, gatewayHeaderV5, NIL);
- Printf(gatewayHeader, "#endif\n");
- }
-
-
- /* -----------------------------------------------------------------------
- * createLoaderScriptFile()
- * Creates the loader script file (loader.sce)
- * ----------------------------------------------------------------------- */
-
- void createLoaderFile(String *gatewayLibraryName) {
- String *loaderFilename = NewString("loader.sce");
- loaderFile = NewFile(loaderFilename, "w", SWIG_output_files());
- if (!loaderFile) {
- FileErrorDisplay(loaderFilename);
- Exit(EXIT_FAILURE);
- }
-
- emitBanner(loaderFile);
-
- loaderFunctionCount = 0;
- loaderScript = NewString("function loader_function()\n");
- Printf(loaderScript, " p = get_absolute_file_path('loader.sce');\n", gatewayLibraryName);
- Printf(loaderScript, " [bOK, ilib] = c_link('%s');\n", gatewayLibraryName);
- Printf(loaderScript, " if bOK then\n");
- Printf(loaderScript, " ulink(ilib);\n");
- Printf(loaderScript, " end\n");
- loaderScript5 = NewString(" list_functions = [ ..\n");
- loaderScript6 = NewString(" list_functions = [ ..\n");
- }
-
- /* -----------------------------------------------------------------------
- * addFunctionInLoaderScript()
- * Add a function in the loader script table
- * ----------------------------------------------------------------------- */
-
- void addFunctionInLoader(const_String_or_char_ptr scilabFunctionName, const_String_or_char_ptr scilabSmallFunctionName) {
- if (++loaderFunctionCount % 10 == 0) {
- Printf(loaderScript5, " ];\n list_functions = [list_functions; ..\n");
- Printf(loaderScript6, " ];\n list_functions = [list_functions; ..\n");
- }
- Printf(loaderScript5, " '%s'; ..\n", scilabSmallFunctionName);
- Printf(loaderScript6, " '%s'; ..\n", scilabFunctionName);
- }
-
- /* -----------------------------------------------------------------------
- * saveLoaderScriptFile()
- * Terminates and saves the loader script
- * ----------------------------------------------------------------------- */
-
- void saveLoaderFile(String *gatewayLibraryName) {
- Printf(loaderScript5, " ];\n");
- Printf(loaderScript6, " ];\n");
-
- if (Equal(loaderScript5, loaderScript6)) {
- Append(loaderScript, loaderScript6);
- } else {
- Printf(loaderScript, " ver = getversion('scilab');\n");
- Printf(loaderScript, " if ver(1) < 6 then\n");
- Printf(loaderScript, " // version is less or equal to 5.5.2\n");
- Printf(loaderScript, " \n");
- Append(loaderScript, loaderScript5);
- Delete(loaderScript5);
- Printf(loaderScript, " \n");
- Printf(loaderScript, " else\n");
- Printf(loaderScript, " // version is 6.0.0 or more\n");
- Printf(loaderScript, " \n");
- Append(loaderScript, loaderScript6);
- Delete(loaderScript6);
- Printf(loaderScript, " \n");
- Printf(loaderScript, " end\n");
- }
-
- Printf(loaderScript, " addinter(p + '%s' + getdynlibext(), '%s', list_functions);\n", gatewayLibraryName, gatewayLibraryName);
- Printf(loaderScript, "endfunction\n");
- Printf(loaderScript, "loader_function();\n");
- Printf(loaderScript, "clear loader_function;\n");
- Printv(loaderFile, loaderScript, NIL);
-
- Delete(loaderScript);
- Delete(loaderFile);
- }
-
- /* -----------------------------------------------------------------------
- * createSmallIdentifierName()
- * Create a Scilab small identifier to be used by Scilab 5
- * ----------------------------------------------------------------------- */
-
- String* createSmallIdentifierName(String* name, int outputLen = SCILAB_IDENTIFIER_NAME_CHAR_MAX) {
- char* s = Char(name);
- int nameLen = Len(s);
-
- // truncate and preserve common suffix
- if (outputLen > 4 && nameLen > outputLen) {
- String* smallName = NewStringWithSize(name, outputLen);
- char* smallNameStr = (char*) Data(smallName);
-
- if (s[nameLen-4] == '_' && s[nameLen - 3] == 'g' && s[nameLen - 2] == 'e' && s[nameLen - 1] == 't') {
- // get
- memcpy(&smallNameStr[outputLen - 4], &s[nameLen - 4], 4);
- } else if (s[nameLen-4] == '_' && s[nameLen - 3] == 's' && s[nameLen - 2] == 'e' && s[nameLen - 1] == 't') {
- // set
- memcpy(&smallNameStr[outputLen - 4], &s[nameLen - 4], 4);
- }
-
- return smallName;
- }
-
- return name;
- }
-
-};
-
-extern "C" Language *swig_scilab(void) {
- return new SCILAB();
-}
diff --git a/contrib/tools/swig/Source/Modules/swigmain.cxx b/contrib/tools/swig/Source/Modules/swigmain.cxx
deleted file mode 100644
index d553fe8930..0000000000
--- a/contrib/tools/swig/Source/Modules/swigmain.cxx
+++ /dev/null
@@ -1,265 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * swigmain.cxx
- *
- * Simplified Wrapper and Interface Generator (SWIG)
- *
- * This file is the main entry point to SWIG. It collects the command
- * line options, registers built-in language modules, and instantiates
- * a module for code generation. If adding new language modules
- * to SWIG, you would modify this file.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include <ctype.h>
-
-/* Module factories. These functions are used to instantiate
- the built-in language modules. If adding a new language
- module to SWIG, place a similar function here. Make sure
- the function has "C" linkage. This is required so that modules
- can be dynamically loaded in future versions. */
-
-extern "C" {
- Language *swig_csharp(void);
- Language *swig_d(void);
- Language *swig_go(void);
- Language *swig_guile(void);
- Language *swig_java(void);
- Language *swig_javascript(void);
- Language *swig_lua(void);
- Language *swig_mzscheme(void);
- Language *swig_ocaml(void);
- Language *swig_octave(void);
- Language *swig_perl5(void);
- Language *swig_php(void);
- Language *swig_python(void);
- Language *swig_r(void);
- Language *swig_ruby(void);
- Language *swig_scilab(void);
- Language *swig_tcl(void);
- Language *swig_xml(void);
-}
-
-/* Association of command line options to language modules.
- Place an entry for new language modules here, keeping the
- list sorted alphabetically. */
-
-static TargetLanguageModule modules[] = {
- {"-allegrocl", NULL, "ALLEGROCL", Disabled},
- {"-chicken", NULL, "CHICKEN", Disabled},
- {"-clisp", NULL, "CLISP", Disabled},
- {"-cffi", NULL, "CFFI", Disabled},
- {"-csharp", swig_csharp, "C#", Supported},
- {"-d", swig_d, "D", Supported},
- {"-go", swig_go, "Go", Supported},
- {"-guile", swig_guile, "Guile", Supported},
- {"-java", swig_java, "Java", Supported},
- {"-javascript", swig_javascript, "Javascript", Supported},
- {"-lua", swig_lua, "Lua", Supported},
- {"-modula3", NULL, "Modula 3", Disabled},
- {"-mzscheme", swig_mzscheme, "MzScheme/Racket", Experimental},
- {"-ocaml", swig_ocaml, "OCaml", Experimental},
- {"-octave", swig_octave, "Octave", Supported},
- {"-perl", swig_perl5, NULL, Supported},
- {"-perl5", swig_perl5, "Perl 5", Supported},
- {"-php", swig_php, NULL, Supported},
- {"-php5", NULL, "PHP 5", Disabled},
- {"-php7", swig_php, "PHP 7 or later", Supported},
- {"-pike", NULL, "Pike", Disabled},
- {"-python", swig_python, "Python", Supported},
- {"-r", swig_r, "R (aka GNU S)", Supported},
- {"-ruby", swig_ruby, "Ruby", Supported},
- {"-scilab", swig_scilab, "Scilab", Supported},
- {"-sexp", NULL, "Lisp S-Expressions", Disabled},
- {"-tcl", swig_tcl, NULL, Supported},
- {"-tcl8", swig_tcl, "Tcl 8", Supported},
- {"-uffi", NULL, "Common Lisp / UFFI", Disabled},
- {"-xml", swig_xml, "XML", Supported},
- {NULL, NULL, NULL, Disabled}
-};
-
-//-----------------------------------------------------------------
-// main()
-//
-// Main program. Initializes the files and starts the parser.
-//-----------------------------------------------------------------
-
-void SWIG_merge_envopt(const char *env, int oargc, char *oargv[], int *nargc, char ***nargv) {
- if (!env) {
- *nargc = oargc;
- *nargv = (char **)Malloc(sizeof(char *) * (oargc + 1));
- memcpy(*nargv, oargv, sizeof(char *) * (oargc + 1));
- return;
- }
-
- int argc = 1;
- int arge = oargc + 1024;
- char **argv = (char **) Malloc(sizeof(char *) * (arge + 1));
- char *buffer = (char *) Malloc(2048);
- char *b = buffer;
- char *be = b + 1023;
- const char *c = env;
- while ((b != be) && *c && (argc < arge)) {
- while (isspace(*c) && *c)
- ++c;
- if (*c) {
- argv[argc] = b;
- ++argc;
- }
- while ((b != be) && *c && !isspace(*c)) {
- *(b++) = *(c++);
- }
- *b++ = 0;
- }
-
- argv[0] = oargv[0];
- for (int i = 1; (i < oargc) && (argc < arge); ++i, ++argc) {
- argv[argc] = oargv[i];
- }
- argv[argc] = NULL;
-
- *nargc = argc;
- *nargv = argv;
-}
-
-static void insert_option(int *argc, char ***argv, int index, char const *start, char const *end) {
- int new_argc = *argc;
- char **new_argv = *argv;
- size_t option_len = end - start;
-
- // Preserve the NULL pointer at argv[argc]
- new_argv = (char **)Realloc(new_argv, (new_argc + 2) * sizeof(char *));
- memmove(&new_argv[index + 1], &new_argv[index], sizeof(char *) * (new_argc + 1 - index));
- new_argc++;
-
- new_argv[index] = (char *)Malloc(option_len + 1);
- memcpy(new_argv[index], start, option_len);
- new_argv[index][option_len] = '\0';
-
- *argc = new_argc;
- *argv = new_argv;
-}
-
-static void merge_options_files(int *argc, char ***argv) {
- static const int BUFFER_SIZE = 4096;
- char buffer[BUFFER_SIZE];
- int i;
- int insert;
- char **new_argv = *argv;
- int new_argc = *argc;
- FILE *f;
-
- i = 1;
- while (i < new_argc) {
- if (new_argv[i] && new_argv[i][0] == '@' && (f = fopen(&new_argv[i][1], "r"))) {
- int ci;
- char *b;
- char *be = &buffer[BUFFER_SIZE];
- int quote = 0;
- bool escape = false;
-
- new_argc--;
- memmove(&new_argv[i], &new_argv[i + 1], sizeof(char *) * (new_argc - i));
- insert = i;
- b = buffer;
-
- while ((ci = fgetc(f)) != EOF) {
- const char c = static_cast<char>(ci);
- if (escape) {
- if (b != be) {
- *b = c;
- ++b;
- }
- escape = false;
- } else if (c == '\\') {
- escape = true;
- } else if (!quote && (c == '\'' || c == '"')) {
- quote = c;
- } else if (quote && c == quote) {
- quote = 0;
- } else if (isspace(c) && !quote) {
- if (b != buffer) {
- insert_option(&new_argc, &new_argv, insert, buffer, b);
- insert++;
-
- b = buffer;
- }
- } else if (b != be) {
- *b = c;
- ++b;
- }
- }
- if (b != buffer)
- insert_option(&new_argc, &new_argv, insert, buffer, b);
- fclose(f);
- } else {
- ++i;
- }
- }
-
- *argv = new_argv;
- *argc = new_argc;
-}
-
-int main(int margc, char **margv) {
- int i;
- const TargetLanguageModule *language_module = 0;
-
- int argc;
- char **argv;
-
- SWIG_merge_envopt(getenv("SWIG_FEATURES"), margc, margv, &argc, &argv);
- merge_options_files(&argc, &argv);
-
- Swig_init_args(argc, argv);
-
- /* Get options */
- for (i = 1; i < argc; i++) {
- if (argv[i]) {
- bool is_target_language_module = false;
- for (int j = 0; modules[j].name; j++) {
- if (strcmp(modules[j].name, argv[i]) == 0) {
- language_module = &modules[j];
- is_target_language_module = true;
- break;
- }
- }
- if (is_target_language_module) {
- Swig_mark_arg(i);
- if (language_module->status == Disabled) {
- if (language_module->help)
- Printf(stderr, "Target language option %s (%s) is no longer supported.\n", language_module->name, language_module->help);
- else
- Printf(stderr, "Target language option %s is no longer supported.\n", language_module->name);
- Exit(EXIT_FAILURE);
- }
- } else if ((strcmp(argv[i], "-help") == 0) || (strcmp(argv[i], "--help") == 0)) {
- if (strcmp(argv[i], "--help") == 0)
- strcpy(argv[i], "-help");
- Printf(stdout, "Supported Target Language Options\n");
- for (int j = 0; modules[j].name; j++) {
- if (modules[j].help && modules[j].status == Supported) {
- Printf(stdout, " %-15s - Generate %s wrappers\n", modules[j].name, modules[j].help);
- }
- }
- Printf(stdout, "\nExperimental Target Language Options\n");
- for (int j = 0; modules[j].name; j++) {
- if (modules[j].help && modules[j].status == Experimental) {
- Printf(stdout, " %-15s - Generate %s wrappers\n", modules[j].name, modules[j].help);
- }
- }
- // Swig_mark_arg not called as the general -help options also need to be displayed later on
- }
- }
- }
-
- int res = SWIG_main(argc, argv, language_module);
-
- return res;
-}
diff --git a/contrib/tools/swig/Source/Modules/swigmod.h b/contrib/tools/swig/Source/Modules/swigmod.h
deleted file mode 100644
index c605edf9d0..0000000000
--- a/contrib/tools/swig/Source/Modules/swigmod.h
+++ /dev/null
@@ -1,463 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * swigmod.h
- *
- * Main header file for SWIG modules.
- * ----------------------------------------------------------------------------- */
-
-#ifndef SWIG_SWIGMOD_H
-#define SWIG_SWIGMOD_H
-
-#include "swig.h"
-#include "preprocessor.h"
-#include "swigwarn.h"
-
-#define NOT_VIRTUAL 0
-#define PLAIN_VIRTUAL 1
-#define PURE_VIRTUAL 2
-
-extern String *input_file;
-extern int line_number;
-extern int start_line;
-extern int CPlusPlus; // C++ mode
-extern int Extend; // Extend mode
-extern int Verbose;
-extern int IsVirtual;
-extern int ImportMode;
-extern int NoExcept; // -no_except option
-extern int Abstract; // abstract base class
-extern int SmartPointer; // smart pointer methods being emitted
-extern int SwigRuntime;
-
-/* Overload "argc" and "argv" */
-extern String *argv_template_string;
-extern String *argc_template_string;
-
-/* Miscellaneous stuff */
-
-#define tab2 " "
-#define tab4 " "
-#define tab8 " "
-
-class Dispatcher {
-public:
-
- Dispatcher ():cplus_mode(PUBLIC) {
- }
- virtual ~ Dispatcher () {
- }
-
- virtual int emit_one(Node *n);
- virtual int emit_children(Node *n);
- virtual int defaultHandler(Node *n);
-
- /* Top of the parse tree */
- virtual int top(Node *n) = 0;
-
- /* SWIG directives */
-
- virtual int applyDirective(Node *n);
- virtual int clearDirective(Node *n);
- virtual int constantDirective(Node *n);
- virtual int extendDirective(Node *n);
- virtual int fragmentDirective(Node *n);
- virtual int importDirective(Node *n);
- virtual int includeDirective(Node *n);
- virtual int insertDirective(Node *n);
- virtual int moduleDirective(Node *n);
- virtual int nativeDirective(Node *n);
- virtual int pragmaDirective(Node *n);
- virtual int typemapDirective(Node *n);
- virtual int typemapitemDirective(Node *n);
- virtual int typemapcopyDirective(Node *n);
- virtual int typesDirective(Node *n);
-
- /* C/C++ parsing */
-
- virtual int cDeclaration(Node *n);
- virtual int externDeclaration(Node *n);
- virtual int enumDeclaration(Node *n);
- virtual int enumvalueDeclaration(Node *n);
- virtual int enumforwardDeclaration(Node *n);
- virtual int classDeclaration(Node *n);
- virtual int classforwardDeclaration(Node *n);
- virtual int constructorDeclaration(Node *n);
- virtual int destructorDeclaration(Node *n);
- virtual int accessDeclaration(Node *n);
- virtual int usingDeclaration(Node *n);
- virtual int namespaceDeclaration(Node *n);
- virtual int templateDeclaration(Node *n);
- virtual int lambdaDeclaration(Node *n);
-
- enum AccessMode { PUBLIC, PRIVATE, PROTECTED };
-
-protected:
- AccessMode cplus_mode;
-};
-
-/* ----------------------------------------------------------------------------
- * class language:
- *
- * This class defines the functions that need to be supported by the
- * scripting language being used. The translator calls these virtual
- * functions to output different types of code for different languages.
- * ------------------------------------------------------------------------- */
-
-class Language:public Dispatcher {
-public:
- Language();
- virtual ~Language();
- virtual int emit_one(Node *n);
-
- String *directorClassName(Node *n);
-
- /* Parse command line options */
-
- virtual void main(int argc, char *argv[]);
-
- /* Top of the parse tree */
-
- virtual int top(Node *n);
-
- /* SWIG directives */
-
-
- virtual int applyDirective(Node *n);
- virtual int clearDirective(Node *n);
- virtual int constantDirective(Node *n);
- virtual int extendDirective(Node *n);
- virtual int fragmentDirective(Node *n);
- virtual int importDirective(Node *n);
- virtual int includeDirective(Node *n);
- virtual int insertDirective(Node *n);
- virtual int moduleDirective(Node *n);
- virtual int nativeDirective(Node *n);
- virtual int pragmaDirective(Node *n);
- virtual int typemapDirective(Node *n);
- virtual int typemapcopyDirective(Node *n);
- virtual int typesDirective(Node *n);
-
- /* C/C++ parsing */
-
- virtual int cDeclaration(Node *n);
- virtual int externDeclaration(Node *n);
- virtual int enumDeclaration(Node *n);
- virtual int enumvalueDeclaration(Node *n);
- virtual int enumforwardDeclaration(Node *n);
- virtual int classDeclaration(Node *n);
- virtual int classforwardDeclaration(Node *n);
- virtual int constructorDeclaration(Node *n);
- virtual int destructorDeclaration(Node *n);
- virtual int accessDeclaration(Node *n);
- virtual int namespaceDeclaration(Node *n);
- virtual int usingDeclaration(Node *n);
-
- /* Function handlers */
-
- virtual int functionHandler(Node *n);
- virtual int globalfunctionHandler(Node *n);
- virtual int memberfunctionHandler(Node *n);
- virtual int staticmemberfunctionHandler(Node *n);
- virtual int callbackfunctionHandler(Node *n);
-
- /* Variable handlers */
-
- virtual int variableHandler(Node *n);
- virtual int globalvariableHandler(Node *n);
- virtual int membervariableHandler(Node *n);
- virtual int staticmembervariableHandler(Node *n);
-
- /* C++ handlers */
-
- virtual int memberconstantHandler(Node *n);
- virtual int constructorHandler(Node *n);
- virtual int copyconstructorHandler(Node *n);
- virtual int destructorHandler(Node *n);
- virtual int classHandler(Node *n);
-
- /* Miscellaneous */
-
- virtual int typedefHandler(Node *n);
-
- /* Low-level code generation */
-
- virtual int constantWrapper(Node *n);
- virtual int variableWrapper(Node *n);
- virtual int functionWrapper(Node *n);
- virtual int nativeWrapper(Node *n);
-
- /* C++ director class generation */
- virtual int classDirector(Node *n);
- virtual int classDirectorInit(Node *n);
- virtual int classDirectorEnd(Node *n);
- virtual int unrollVirtualMethods(Node *n, Node *parent, List *vm, int &virtual_destructor, int protectedbase = 0);
- virtual int classDirectorConstructor(Node *n);
- virtual int classDirectorDefaultConstructor(Node *n);
- virtual int classDirectorMethod(Node *n, Node *parent, String *super);
- virtual int classDirectorConstructors(Node *n);
- virtual int classDirectorDestructor(Node *n);
- virtual int classDirectorMethods(Node *n);
- virtual int classDirectorDisown(Node *n);
-
- /* Miscellaneous */
- virtual int validIdentifier(String *s); /* valid identifier? */
- virtual int addSymbol(const String *s, const Node *n, const_String_or_char_ptr scope = ""); /* Add symbol */
- virtual int addInterfaceSymbol(const String *interface_name, Node *n, const_String_or_char_ptr scope = "");
- virtual void dumpSymbols();
- virtual Node *symbolLookup(const String *s, const_String_or_char_ptr scope = ""); /* Symbol lookup */
- virtual Hash* symbolAddScope(const_String_or_char_ptr scope);
- virtual Hash* symbolScopeLookup(const_String_or_char_ptr scope);
- virtual Hash* symbolScopePseudoSymbolLookup(const_String_or_char_ptr scope);
- static Node *classLookup(const SwigType *s); /* Class lookup */
- static Node *enumLookup(SwigType *s); /* Enum lookup */
- virtual int abstractClassTest(Node *n); /* Is class really abstract? */
- virtual int is_assignable(Node *n); /* Is variable assignable? */
- virtual String *runtimeCode(); /* returns the language specific runtime code */
- virtual String *defaultExternalRuntimeFilename(); /* the default filename for the external runtime */
- virtual void replaceSpecialVariables(String *method, String *tm, Parm *parm); /* Language specific special variable substitutions for $typemap() */
-
- /* Runtime is C++ based, so extern "C" header section */
- void enable_cplus_runtime_mode();
-
- /* Returns the cplus_runtime mode */
- int cplus_runtime_mode();
-
- /* Allow director related code generation */
- void allow_directors(int val = 1);
-
- /* Return true if directors are enabled */
- int directorsEnabled() const;
-
- /* Allow director protected members related code generation */
- void allow_dirprot(int val = 1);
-
- /* Allow all protected members code generation (for directors) */
- void allow_allprotected(int val = 0);
-
- /* Returns the dirprot mode */
- int dirprot_mode() const;
-
- /* Check if the non public constructor is needed (for directors) */
- int need_nonpublic_ctor(Node *n);
-
- /* Check if the non public member is needed (for directors) */
- int need_nonpublic_member(Node *n);
-
- /* Set none comparison string */
- void setSubclassInstanceCheck(String *s);
-
- /* Set overload variable templates argc and argv */
- void setOverloadResolutionTemplates(String *argc, String *argv);
-
- /* Language instance is a singleton - get instance */
- static Language* instance();
-
-protected:
- /* Allow multiple-input typemaps */
- void allow_multiple_input(int val = 1);
-
- /* Allow overloaded functions */
- void allow_overloading(int val = 1);
-
- /* Wrapping class query */
- int is_wrapping_class() const;
-
- /* Return the node for the current class */
- Node *getCurrentClass() const;
-
- /* Return C++ mode */
- int getCPlusMode() const;
-
- /* Return the namespace for the class/enum - the nspace feature */
- String *getNSpace() const;
-
- /* Return the real name of the current class */
- String *getClassName() const;
-
- /* Return the classes hash */
- Hash *getClassHash() const;
-
- /* Return the current class prefix */
- String *getClassPrefix() const;
-
- /* Return the current enum class prefix */
- String *getEnumClassPrefix() const;
-
- /* Fully qualified type name to use */
- String *getClassType() const;
-
- /* Return true if the current method is part of a smart-pointer */
- int is_smart_pointer() const;
-
- /* Return the name to use for the given parameter. */
- virtual String *makeParameterName(Node *n, Parm *p, int arg_num, bool setter = false) const;
-
- /* Some language modules require additional wrappers for virtual methods not declared in sub-classes */
- virtual bool extraDirectorProtectedCPPMethodsRequired() const;
-
-public:
- enum NestedClassSupport {
- NCS_None, // Target language does not have an equivalent to nested classes
- NCS_Full, // Target language does have an equivalent to nested classes and is fully implemented
- NCS_Unknown // Target language may or may not have an equivalent to nested classes. If it does, it has not been implemented yet.
- };
- /* Does target language support nested classes? Default is NCS_Unknown.
- If NCS_Unknown is returned, then the nested classes will be ignored unless
- %feature "flatnested" is applied to them, in which case they will appear in global space.
- If the target language does not support the notion of class
- nesting, the language module should return NCS_None from this function, and
- the nested classes will be moved to the global scope (like implicit global %feature "flatnested").
- */
- virtual NestedClassSupport nestedClassesSupport() const;
-
- /* Returns true if the target language supports key word arguments (kwargs) */
- virtual bool kwargsSupport() const;
-
-protected:
- /* Identifies if a protected members that are generated when the allprotected option is used.
- This does not include protected virtual methods as they are turned on with the dirprot option. */
- bool isNonVirtualProtectedAccess(Node *n) const;
-
- /* Identify if a wrapped global or member variable n should use the naturalvar feature */
- int use_naturalvar_mode(Node *n) const;
-
- /* Director subclass comparison test */
- String *none_comparison;
-
- /* Director constructor "template" code */
- String *director_ctor_code;
-
- /* Director 'protected' constructor "template" code */
- String *director_prot_ctor_code;
-
- /* Director allows multiple inheritance */
- int director_multiple_inheritance;
-
- /* Director language module */
- int director_language;
-
- /* Used to translate Doxygen comments to target documentation format */
- class DoxygenTranslator *doxygenTranslator;
-
-private:
- void unrollOneVirtualMethod(String *classname, Node *n, Node *parent, List *vm, int &virtual_destructor, int protectedbase);
-
- Hash *symtabs; /* symbol tables */
- int overloading;
- int multiinput;
- int cplus_runtime;
- int directors;
- static Language *this_;
-};
-
-extern "C" {
- void SWIG_typemap_lang(const char *);
- typedef Language *(*ModuleFactory) (void);
-}
-
-enum Status {Disabled, Experimental, Supported};
-
-struct TargetLanguageModule {
- const char *name;
- ModuleFactory fac;
- const char *help;
- Status status;
-};
-
-int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm);
-void emit_parameter_variables(ParmList *l, Wrapper *f);
-void emit_return_variable(Node *n, SwigType *rt, Wrapper *f);
-void SWIG_config_file(const_String_or_char_ptr );
-const String *SWIG_output_directory();
-void SWIG_config_cppext(const char *ext);
-void Swig_print_xml(Node *obj, String *filename);
-
-/* get the list of generated files */
-List *SWIG_output_files();
-
-void SWIG_library_directory(const char *);
-int emit_num_arguments(ParmList *);
-int emit_num_required(ParmList *);
-int emit_isvarargs(ParmList *p);
-bool emit_isvarargs_function(Node *n);
-void emit_attach_parmmaps(ParmList *, Wrapper *f);
-void emit_mark_varargs(ParmList *l);
-String *emit_action(Node *n);
-int emit_action_code(Node *n, String *wrappercode, String *action);
-void Swig_overload_check(Node *n);
-String *Swig_overload_dispatch(Node *n, const_String_or_char_ptr fmt, int *, const_String_or_char_ptr fmt_fastdispatch = 0);
-String *Swig_overload_dispatch_cast(Node *n, const_String_or_char_ptr fmt, int *);
-List *Swig_overload_rank(Node *n, bool script_lang_wrapping);
-SwigType *cplus_value_type(SwigType *t);
-
-/* directors.cxx start */
-String *Swig_csuperclass_call(String *base, String *method, ParmList *l);
-String *Swig_class_declaration(Node *n, String *name);
-String *Swig_class_name(Node *n);
-String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms);
-String *Swig_method_decl(SwigType *return_base_type, SwigType *decl, const_String_or_char_ptr id, List *args, int default_args);
-String *Swig_director_declaration(Node *n);
-void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f);
-void Swig_director_parms_fixup(ParmList *parms);
-bool Swig_director_can_unwrap(Node *n);
-/* directors.cxx end */
-
-/* Utilities */
-
-int is_public(Node *n);
-int is_private(Node *n);
-int is_protected(Node *n);
-int is_member_director(Node *parentnode, Node *member);
-int is_member_director(Node *member);
-int is_non_virtual_protected_access(Node *n); /* Check if the non-virtual protected members are required (for directors) */
-
-void Wrapper_virtual_elimination_mode_set(int);
-void Wrapper_fast_dispatch_mode_set(int);
-void Wrapper_cast_dispatch_mode_set(int);
-void Wrapper_naturalvar_mode_set(int);
-
-void clean_overloaded(Node *n);
-
-extern "C" {
- const char *Swig_to_string(DOH *object, int count = -1);
- const char *Swig_to_string_with_location(DOH *object, int count = -1);
- void Swig_print(DOH *object, int count = -1);
- void Swig_print_with_location(DOH *object, int count = -1);
-}
-
-void Swig_default_allocators(Node *n);
-void Swig_process_types(Node *n);
-
-/* Contracts */
-void Swig_contracts(Node *n);
-void Swig_contract_mode_set(int flag);
-int Swig_contract_mode_get();
-
-/* Nested classes */
-void Swig_nested_process_classes(Node *n);
-void Swig_nested_name_unnamed_c_structs(Node *n);
-
-/* Interface feature */
-void Swig_interface_feature_enable();
-void Swig_interface_propagate_methods(Node *n);
-
-/* Miscellaneous */
-template <class T> class save_value {
- T _value;
- T& _value_ptr;
- save_value(const save_value&);
- save_value& operator=(const save_value&);
-
-public:
- save_value(T& value) : _value(value), _value_ptr(value) {}
- save_value(T& value, T new_val) : _value(value), _value_ptr(value) { value = new_val; }
- ~save_value() { _value_ptr = _value; }
-};
-
-#endif
diff --git a/contrib/tools/swig/Source/Modules/tcl8.cxx b/contrib/tools/swig/Source/Modules/tcl8.cxx
deleted file mode 100644
index 975230e849..0000000000
--- a/contrib/tools/swig/Source/Modules/tcl8.cxx
+++ /dev/null
@@ -1,1291 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * tcl8.cxx
- *
- * Tcl8 language module for SWIG.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include "cparse.h"
-
-static const char *usage = "\
-Tcl 8 Options (available with -tcl8)\n\
- -itcl - Enable ITcl support\n\
- -nosafe - Leave out SafeInit module function.\n\
- -prefix <name> - Set a prefix <name> to be prepended to all names\n\
- -namespace - Build module into a Tcl 8 namespace\n\
- -pkgversion - Set package version\n\n";
-
-static String *cmd_tab = 0; /* Table of command names */
-static String *var_tab = 0; /* Table of global variables */
-static String *const_tab = 0; /* Constant table */
-static String *methods_tab = 0; /* Methods table */
-static String *attr_tab = 0; /* Attribute table */
-static String *prefix = 0;
-static String *module = 0;
-static int namespace_option = 0;
-static String *init_name = 0;
-static String *ns_name = 0;
-static int have_constructor;
-static String *constructor_name;
-static int have_destructor;
-static int have_base_classes;
-static String *destructor_action = 0;
-static String *version = (String *) "0.0";
-static String *class_name = 0;
-
-static int have_attributes;
-static int have_methods;
-static int nosafe = 0;
-
-static File *f_header = 0;
-static File *f_wrappers = 0;
-static File *f_init = 0;
-static File *f_begin = 0;
-static File *f_runtime = 0;
-
-
-// Itcl support
-static int itcl = 0;
-static File *f_shadow = 0;
-static File *f_shadow_stubs = 0;
-
-static String *constructor = 0;
-static String *destructor = 0;
-static String *base_classes = 0;
-static String *base_class_init = 0;
-static String *methods = 0;
-static String *imethods = 0;
-static String *attributes = 0;
-static String *attribute_traces = 0;
-static String *iattribute_traces = 0;
-
-
-
-class TCL8:public Language {
-public:
-
- /* ------------------------------------------------------------
- * TCL8::main()
- * ------------------------------------------------------------ */
-
- virtual void main(int argc, char *argv[]) {
-
- SWIG_library_directory("tcl");
-
- for (int i = 1; i < argc; i++) {
- if (argv[i]) {
- if (strcmp(argv[i], "-prefix") == 0) {
- if (argv[i + 1]) {
- prefix = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else
- Swig_arg_error();
- } else if (strcmp(argv[i], "-pkgversion") == 0) {
- if (argv[i + 1]) {
- version = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- }
- } else if (strcmp(argv[i], "-namespace") == 0) {
- namespace_option = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-itcl") == 0) {
- itcl = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nosafe") == 0) {
- nosafe = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-help") == 0) {
- fputs(usage, stdout);
- } else if (strcmp(argv[i], "-cppcast") == 0) {
- Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nocppcast") == 0) {
- Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
- Swig_mark_arg(i);
- Exit(EXIT_FAILURE);
- }
- }
- }
-
- Preprocessor_define("SWIGTCL 1", 0);
- // SWIGTCL8 is deprecated, and no longer documented.
- Preprocessor_define("SWIGTCL8 1", 0);
- SWIG_typemap_lang("tcl8");
- SWIG_config_file("tcl8.swg");
- allow_overloading();
- }
-
- /* ------------------------------------------------------------
- * top()
- * ------------------------------------------------------------ */
-
- virtual int top(Node *n) {
-
- /* Initialize all of the output files */
- String *outfile = Getattr(n, "outfile");
-
- f_begin = NewFile(outfile, "w", SWIG_output_files());
- if (!f_begin) {
- FileErrorDisplay(outfile);
- Exit(EXIT_FAILURE);
- }
- f_runtime = NewString("");
- f_init = NewString("");
- f_header = NewString("");
- f_wrappers = NewString("");
-
- /* Register file targets with the SWIG file handler */
- Swig_register_filebyname("header", f_header);
- Swig_register_filebyname("wrapper", f_wrappers);
- Swig_register_filebyname("begin", f_begin);
- Swig_register_filebyname("runtime", f_runtime);
- Swig_register_filebyname("init", f_init);
-
- /* Initialize some variables for the object interface */
-
- cmd_tab = NewString("");
- var_tab = NewString("");
- methods_tab = NewString("");
- const_tab = NewString("");
-
- Swig_banner(f_begin);
-
- Swig_obligatory_macros(f_runtime, "TCL");
-
- /* Set the module name, namespace, and prefix */
-
- module = NewStringf("%(lower)s", Getattr(n, "name"));
- init_name = NewStringf("%(title)s_Init", module);
-
- ns_name = prefix ? Copy(prefix) : Copy(module);
- if (prefix)
- Append(prefix, "_");
-
-
- /* If shadow classing is enabled, we're going to change the module name to "_module" */
- if (itcl) {
- String *filen;
- filen = NewStringf("%s%s.itcl", SWIG_output_directory(), module);
-
- Insert(module, 0, "_");
-
- if ((f_shadow = NewFile(filen, "w", SWIG_output_files())) == 0) {
- FileErrorDisplay(filen);
- Exit(EXIT_FAILURE);
- }
- f_shadow_stubs = NewString("");
-
- Swig_register_filebyname("shadow", f_shadow);
- Swig_register_filebyname("itcl", f_shadow);
-
- Swig_banner_target_lang(f_shadow, "#");
-
- Printv(f_shadow, "\npackage require Itcl\n\n", NIL);
- Delete(filen);
- }
-
- /* Generate some macros used throughout code generation */
-
- Printf(f_header, "#define SWIG_init %s\n", init_name);
- Printf(f_header, "#define SWIG_name \"%s\"\n", module);
- if (namespace_option) {
- Printf(f_header, "#define SWIG_prefix \"%s::\"\n", ns_name);
- Printf(f_header, "#define SWIG_namespace \"%s\"\n\n", ns_name);
- } else {
- Printf(f_header, "#define SWIG_prefix \"%s\"\n", prefix);
- }
- Printf(f_header, "#define SWIG_version \"%s\"\n", version);
-
- Printf(cmd_tab, "\nstatic swig_command_info swig_commands[] = {\n");
- Printf(var_tab, "\nstatic swig_var_info swig_variables[] = {\n");
- Printf(const_tab, "\nstatic swig_const_info swig_constants[] = {\n");
-
- Printf(f_wrappers, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
-
- /* Start emitting code */
- Language::top(n);
-
- /* Done. Close up the module */
- Printv(cmd_tab, tab4, "{0, 0, 0}\n", "};\n", NIL);
- Printv(var_tab, tab4, "{0,0,0,0}\n", "};\n", NIL);
- Printv(const_tab, tab4, "{0,0,0,0,0,0}\n", "};\n", NIL);
-
- Printv(f_wrappers, cmd_tab, var_tab, const_tab, NIL);
-
- /* Dump the pointer equivalency table */
- SwigType_emit_type_table(f_runtime, f_wrappers);
-
- Printf(f_wrappers, "#ifdef __cplusplus\n}\n#endif\n");
-
- /* Close the init function and quit */
- Printf(f_init, "return TCL_OK;\n}\n");
-
- if (!nosafe) {
- Printf(f_init, "SWIGEXPORT int %(title)s_SafeInit(Tcl_Interp *interp) {\n", module);
- Printf(f_init, " return SWIG_init(interp);\n");
- Printf(f_init, "}\n");
- }
-
- if (itcl) {
- Printv(f_shadow, f_shadow_stubs, "\n", NIL);
- Delete(f_shadow);
- }
-
- /* Close all of the files */
- Dump(f_runtime, f_begin);
- Printv(f_begin, f_header, f_wrappers, NIL);
- Wrapper_pretty_print(f_init, f_begin);
- Delete(f_header);
- Delete(f_wrappers);
- Delete(f_init);
- Delete(f_runtime);
- Delete(f_begin);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * functionWrapper()
- * ------------------------------------------------------------ */
-
- virtual int functionWrapper(Node *n) {
- String *name = Getattr(n, "name"); /* Like to get rid of this */
- String *iname = Getattr(n, "sym:name");
- SwigType *type = Getattr(n, "type");
- ParmList *parms = Getattr(n, "parms");
- String *overname = 0;
-
- Parm *p;
- int i;
- String *tm;
- Wrapper *f;
- String *incode, *cleanup, *outarg, *argstr, *args;
- int num_arguments = 0;
- int num_required = 0;
- int varargs = 0;
-
- char source[64];
-
- if (Getattr(n, "sym:overloaded")) {
- overname = Getattr(n, "sym:overname");
- } else {
- if (!addSymbol(iname, n))
- return SWIG_ERROR;
- }
-
- incode = NewString("");
- cleanup = NewString("");
- outarg = NewString("");
- argstr = NewString("\"");
- args = NewString("");
-
- f = NewWrapper();
-
-#ifdef SWIG_USE_RESULTOBJ
- Wrapper_add_local(f, "resultobj", "Tcl_Obj *resultobj = NULL");
-#endif
-
-
- String *wname = Swig_name_wrapper(iname);
- if (overname) {
- Append(wname, overname);
- }
- Setattr(n, "wrap:name", wname);
-
- Printv(f->def, "SWIGINTERN int\n ", wname, "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {", NIL);
-
- // Emit all of the local variables for holding arguments.
- emit_parameter_variables(parms, f);
-
- /* Attach standard typemaps */
- emit_attach_parmmaps(parms, f);
- Setattr(n, "wrap:parms", parms);
-
- /* Get number of require and total arguments */
- num_arguments = emit_num_arguments(parms);
- num_required = emit_num_required(parms);
- varargs = emit_isvarargs(parms);
-
- /* Unmarshal parameters */
-
- for (i = 0, p = parms; i < num_arguments; i++) {
- /* Skip ignored arguments */
-
- while (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- }
-
- SwigType *pt = Getattr(p, "type");
- String *ln = Getattr(p, "lname");
-
- /* Produce string representations of the source and target arguments */
- sprintf(source, "objv[%d]", i + 1);
-
- if (i == num_required)
- Putc('|', argstr);
- if ((tm = Getattr(p, "tmap:in"))) {
- String *parse = Getattr(p, "tmap:in:parse");
- if (!parse) {
- Replaceall(tm, "$input", source);
- Setattr(p, "emit:input", source);
-
- if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
- Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
- } else {
- Replaceall(tm, "$disown", "0");
- }
-
- Putc('o', argstr);
- Printf(args, ",(void *)0");
- if (i >= num_required) {
- Printf(incode, "if (objc > %d) {\n", i + 1);
- }
- Printf(incode, "%s\n", tm);
- if (i >= num_required) {
- Printf(incode, "}\n");
- }
- } else {
- Printf(argstr, "%s", parse);
- Printf(args, ",&%s", ln);
- if (Strcmp(parse, "p") == 0) {
- SwigType *lt = SwigType_ltype(pt);
- SwigType_remember(pt);
- if (Cmp(lt, "p.void") == 0) {
- Printf(args, ",(void *)0");
- } else {
- Printf(args, ",SWIGTYPE%s", SwigType_manglestr(pt));
- }
- Delete(lt);
- }
- }
- p = Getattr(p, "tmap:in:next");
- continue;
- } else {
- Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
- }
- p = nextSibling(p);
- }
-
- if (!varargs) {
- Putc(':', argstr);
- } else {
- Putc(';', argstr);
- /* If variable length arguments we need to emit the in typemap here */
- if (p && (tm = Getattr(p, "tmap:in"))) {
- sprintf(source, "objv[%d]", i + 1);
- Printf(incode, "if (objc > %d) {\n", i);
- Replaceall(tm, "$input", source);
- Printv(incode, tm, "\n", NIL);
- Printf(incode, "}\n");
- }
- }
-
- Printf(argstr, "%s\"", usage_string(Char(iname), type, parms));
-
- Printv(f->code, "if (SWIG_GetArgs(interp, objc, objv,", argstr, args, ") == TCL_ERROR) SWIG_fail;\n", NIL);
-
- Printv(f->code, incode, NIL);
-
- /* Insert constraint checking code */
- for (p = parms; p;) {
- if ((tm = Getattr(p, "tmap:check"))) {
- Printv(f->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:check:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* Insert cleanup code */
- for (i = 0, p = parms; p; i++) {
- if (!checkAttribute(p, "tmap:in:numinputs", "0")
- && !Getattr(p, "tmap:in:parse") && (tm = Getattr(p, "tmap:freearg"))) {
- if (Len(tm) != 0) {
- Printv(cleanup, tm, "\n", NIL);
- }
- p = Getattr(p, "tmap:freearg:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* Insert argument output code */
- for (i = 0, p = parms; p; i++) {
- if ((tm = Getattr(p, "tmap:argout"))) {
-#ifdef SWIG_USE_RESULTOBJ
- Replaceall(tm, "$result", "resultobj");
-#else
- Replaceall(tm, "$result", "(Tcl_GetObjResult(interp))");
-#endif
- Replaceall(tm, "$arg", Getattr(p, "emit:input"));
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(outarg, tm, "\n", NIL);
- p = Getattr(p, "tmap:argout:next");
- } else {
- p = nextSibling(p);
- }
- }
-
- /* Now write code to make the function call */
- String *actioncode = emit_action(n);
-
- /* Need to redo all of this code (eventually) */
-
- /* Return value if necessary */
- if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
-#ifdef SWIG_USE_RESULTOBJ
- Replaceall(tm, "$result", "resultobj");
-#else
- Replaceall(tm, "$result", "(Tcl_GetObjResult(interp))");
-#endif
- if (GetFlag(n, "feature:new")) {
- Replaceall(tm, "$owner", "SWIG_POINTER_OWN");
- } else {
- Replaceall(tm, "$owner", "0");
- }
- Printf(f->code, "%s\n", tm);
- } else {
- Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(type, 0), name);
- }
- emit_return_variable(n, type, f);
-
- /* Dump output argument code */
- Printv(f->code, outarg, NIL);
-
- /* Dump the argument cleanup code */
- Printv(f->code, cleanup, NIL);
-
- /* Look for any remaining cleanup */
- if (GetFlag(n, "feature:new")) {
- if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
- Printf(f->code, "%s\n", tm);
- }
- }
-
- if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
- Printf(f->code, "%s\n", tm);
- }
-#ifdef SWIG_USE_RESULTOBJ
- Printv(f->code, "if (resultobj) Tcl_SetObjResult(interp, resultobj);\n", NIL);
-#endif
- Printv(f->code, "return TCL_OK;\n", NIL);
- Printv(f->code, "fail:\n", cleanup, "return TCL_ERROR;\n", NIL);
- Printv(f->code, "}\n", NIL);
-
- /* Substitute the cleanup code */
- Replaceall(f->code, "$cleanup", cleanup);
- Replaceall(f->code, "$symname", iname);
-
- /* Dump out the function */
- Wrapper_print(f, f_wrappers);
-
- if (!Getattr(n, "sym:overloaded")) {
- /* Register the function with Tcl */
- Printv(cmd_tab, tab4, "{ SWIG_prefix \"", iname, "\", (swig_wrapper_func) ", Swig_name_wrapper(iname), ", NULL},\n", NIL);
- } else {
- if (!Getattr(n, "sym:nextSibling")) {
- /* Emit overloading dispatch function */
-
- int maxargs;
- String *dispatch = Swig_overload_dispatch(n, "return %s(clientData, interp, objc, argv - 1);", &maxargs);
-
- /* Generate a dispatch wrapper for all overloaded functions */
-
- Wrapper *df = NewWrapper();
- String *dname = Swig_name_wrapper(iname);
-
- Printv(df->def, "SWIGINTERN int\n", dname, "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {", NIL);
- Printf(df->code, "Tcl_Obj *CONST *argv = objv+1;\n");
- Printf(df->code, "int argc = objc-1;\n");
- Printv(df->code, dispatch, "\n", NIL);
- Node *sibl = n;
- while (Getattr(sibl, "sym:previousSibling"))
- sibl = Getattr(sibl, "sym:previousSibling"); // go all the way up
- String *protoTypes = NewString("");
- do {
- String *fulldecl = Swig_name_decl(sibl);
- Printf(protoTypes, "\n\" %s\\n\"", fulldecl);
- Delete(fulldecl);
- } while ((sibl = Getattr(sibl, "sym:nextSibling")));
- Printf(df->code, "Tcl_SetResult(interp,(char *) "
- "\"Wrong number or type of arguments for overloaded function '%s'.\\n\""
- "\n\" Possible C/C++ prototypes are:\\n\"%s, TCL_STATIC);\n", iname, protoTypes);
- Delete(protoTypes);
- Printf(df->code, "return TCL_ERROR;\n");
- Printv(df->code, "}\n", NIL);
- Wrapper_print(df, f_wrappers);
- Printv(cmd_tab, tab4, "{ SWIG_prefix \"", iname, "\", (swig_wrapper_func) ", dname, ", NULL},\n", NIL);
- DelWrapper(df);
- Delete(dispatch);
- Delete(dname);
- }
- }
-
- Delete(incode);
- Delete(cleanup);
- Delete(outarg);
- Delete(argstr);
- Delete(args);
- DelWrapper(f);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * variableWrapper()
- * ------------------------------------------------------------ */
-
- virtual int variableWrapper(Node *n) {
-
- String *name = Getattr(n, "name");
- String *iname = Getattr(n, "sym:name");
- SwigType *t = Getattr(n, "type");
-
- String *setname = 0;
- String *setfname = 0;
- Wrapper *setf = 0, *getf = 0;
- int readonly = 0;
- String *tm;
-
- if (!addSymbol(iname, n))
- return SWIG_ERROR;
-
- /* Create a function for getting a variable */
- int addfail = 0;
- getf = NewWrapper();
- String *getname = Swig_name_get(NSPACE_TODO, iname);
- String *getfname = Swig_name_wrapper(getname);
- Setattr(n, "wrap:name", getfname);
- Printv(getf->def, "SWIGINTERN const char *", getfname, "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, char *name1, char *name2, int flags) {", NIL);
- Wrapper_add_local(getf, "value", "Tcl_Obj *value = 0");
- if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
- Replaceall(tm, "$result", "value");
- /* Printf(getf->code, "%s\n",tm); */
- addfail = emit_action_code(n, getf->code, tm);
- Printf(getf->code, "if (value) {\n");
- Printf(getf->code, "Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n");
- Printf(getf->code, "Tcl_DecrRefCount(value);\n");
- Printf(getf->code, "}\n");
- Printf(getf->code, "return NULL;\n");
- if (addfail) {
- Append(getf->code, "fail:\n");
- Printf(getf->code, "return \"%s\";\n", iname);
- }
- Printf(getf->code, "}\n");
- Wrapper_print(getf, f_wrappers);
- } else {
- Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
- DelWrapper(getf);
- return SWIG_NOWRAP;
- }
- DelWrapper(getf);
-
- /* Try to create a function setting a variable */
- if (is_assignable(n)) {
- setf = NewWrapper();
- setname = Swig_name_set(NSPACE_TODO, iname);
- setfname = Swig_name_wrapper(setname);
- Setattr(n, "wrap:name", setfname);
- if (setf) {
- Printv(setf->def, "SWIGINTERN const char *", setfname,
- "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, char *name1, char *name2 SWIGUNUSED, int flags) {", NIL);
- Wrapper_add_local(setf, "value", "Tcl_Obj *value = 0");
- Wrapper_add_local(setf, "name1o", "Tcl_Obj *name1o = 0");
-
- if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
- Replaceall(tm, "$input", "value");
- Printf(setf->code, "name1o = Tcl_NewStringObj(name1,-1);\n");
- Printf(setf->code, "value = Tcl_ObjGetVar2(interp, name1o, 0, flags);\n");
- Printf(setf->code, "Tcl_DecrRefCount(name1o);\n");
- Printf(setf->code, "if (!value) SWIG_fail;\n");
- /* Printf(setf->code,"%s\n", tm); */
- emit_action_code(n, setf->code, tm);
- Printf(setf->code, "return NULL;\n");
- Printf(setf->code, "fail:\n");
- Printf(setf->code, "return \"%s\";\n", iname);
- Printf(setf->code, "}\n");
- Wrapper_print(setf, f_wrappers);
- } else {
- Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
- readonly = 1;
- }
- }
- DelWrapper(setf);
- } else {
- readonly = 1;
- }
-
-
- Printv(var_tab, tab4, "{ SWIG_prefix \"", iname, "\", 0, (swig_variable_func) ", getfname, ",", NIL);
- if (readonly) {
- static int readonlywrap = 0;
- if (!readonlywrap) {
- Wrapper *ro = NewWrapper();
- Printf(ro->def,
- "SWIGINTERN const char *swig_readonly(ClientData clientData SWIGUNUSED, Tcl_Interp *interp SWIGUNUSED, char *name1 SWIGUNUSED, char *name2 SWIGUNUSED, int flags SWIGUNUSED) {");
- Printv(ro->code, "return \"Variable is read-only\";\n", "}\n", NIL);
- Wrapper_print(ro, f_wrappers);
- readonlywrap = 1;
- DelWrapper(ro);
- }
- Printf(var_tab, "(swig_variable_func) swig_readonly},\n");
- } else {
- Printv(var_tab, "(swig_variable_func) ", setfname, "},\n", NIL);
- }
- Delete(getfname);
- Delete(setfname);
- Delete(setname);
- Delete(getname);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * constantWrapper()
- * ------------------------------------------------------------ */
-
- virtual int constantWrapper(Node *n) {
- String *name = Getattr(n, "name");
- String *iname = Getattr(n, "sym:name");
- String *nsname = !namespace_option ? Copy(iname) : NewStringf("%s::%s", ns_name, iname);
- SwigType *type = Getattr(n, "type");
- String *rawval = Getattr(n, "rawval");
- String *value = rawval ? rawval : Getattr(n, "value");
- String *tm;
-
- if (!addSymbol(iname, n))
- return SWIG_ERROR;
- if (namespace_option)
- Setattr(n, "sym:name", nsname);
-
- /* Special hook for member pointer */
- if (SwigType_type(type) == T_MPOINTER) {
- String *wname = Swig_name_wrapper(iname);
- Printf(f_wrappers, "static %s = %s;\n", SwigType_str(type, wname), value);
- value = Char(wname);
- }
-
- if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) {
- Replaceall(tm, "$value", value);
- Replaceall(tm, "$nsname", nsname);
- Printf(const_tab, "%s,\n", tm);
- } else if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
- Replaceall(tm, "$value", value);
- Replaceall(tm, "$nsname", nsname);
- Printf(f_init, "%s\n", tm);
- } else {
- Delete(nsname);
- Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n");
- return SWIG_NOWRAP;
- }
- Delete(nsname);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * nativeWrapper()
- * ------------------------------------------------------------ */
-
- virtual int nativeWrapper(Node *n) {
- String *name = Getattr(n, "sym:name");
- String *funcname = Getattr(n, "wrap:name");
- if (!addSymbol(funcname, n))
- return SWIG_ERROR;
-
- Printf(f_init, "\t Tcl_CreateObjCommand(interp, SWIG_prefix \"%s\", (swig_wrapper_func) %s, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);\n", name,
- funcname);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * classHandler()
- * ------------------------------------------------------------ */
-
- virtual int classHandler(Node *n) {
- static Hash *emitted = NewHash();
- String *mangled_classname = 0;
- String *real_classname = 0;
-
- have_constructor = 0;
- have_destructor = 0;
- destructor_action = 0;
- constructor_name = 0;
-
- if (itcl) {
- constructor = NewString("");
- destructor = NewString("");
- base_classes = NewString("");
- base_class_init = NewString("");
- methods = NewString("");
- imethods = NewString("");
- attributes = NewString("");
- attribute_traces = NewString("");
- iattribute_traces = NewString("");
-
- have_base_classes = 0;
- have_methods = 0;
- have_attributes = 0;
- }
-
- class_name = Getattr(n, "sym:name");
- if (!addSymbol(class_name, n))
- return SWIG_ERROR;
-
- real_classname = Getattr(n, "name");
- mangled_classname = Swig_name_mangle(real_classname);
-
- if (Getattr(emitted, mangled_classname))
- return SWIG_NOWRAP;
- Setattr(emitted, mangled_classname, "1");
-
- attr_tab = NewString("");
- Printf(attr_tab, "static swig_attribute swig_");
- Printv(attr_tab, mangled_classname, "_attributes[] = {\n", NIL);
-
- methods_tab = NewStringf("");
- Printf(methods_tab, "static swig_method swig_");
- Printv(methods_tab, mangled_classname, "_methods[] = {\n", NIL);
-
- /* Generate normal wrappers */
- Language::classHandler(n);
-
- SwigType *t = Copy(Getattr(n, "name"));
- SwigType_add_pointer(t);
-
- // Catch all: eg. a class with only static functions and/or variables will not have 'remembered'
- // SwigType_remember(t);
- String *wrap_class = NewStringf("&_wrap_class_%s", mangled_classname);
- SwigType_remember_clientdata(t, wrap_class);
-
- String *rt = Copy(getClassType());
- SwigType_add_pointer(rt);
-
- // Register the class structure with the type checker
- /* Printf(f_init,"SWIG_TypeClientData(SWIGTYPE%s, (void *) &_wrap_class_%s);\n", SwigType_manglestr(t), mangled_classname); */
- if (have_destructor) {
- Printv(f_wrappers, "SWIGINTERN void swig_delete_", class_name, "(void *obj) {\n", NIL);
- if (destructor_action) {
- Printv(f_wrappers, SwigType_str(rt, "arg1"), " = (", SwigType_str(rt, 0), ") obj;\n", NIL);
- Printv(f_wrappers, destructor_action, "\n", NIL);
- } else {
- if (CPlusPlus) {
- Printv(f_wrappers, " delete (", SwigType_str(rt, 0), ") obj;\n", NIL);
- } else {
- Printv(f_wrappers, " free((char *) obj);\n", NIL);
- }
- }
- Printf(f_wrappers, "}\n");
- }
-
- Printf(methods_tab, " {0,0}\n};\n");
- Printv(f_wrappers, methods_tab, NIL);
-
- Printf(attr_tab, " {0,0,0}\n};\n");
- Printv(f_wrappers, attr_tab, NIL);
-
- /* Handle inheritance */
-
- String *base_class = NewString("");
- String *base_class_names = NewString("");
-
- if (itcl) {
- base_classes = NewString("");
- }
-
- List *baselist = Getattr(n, "bases");
- if (baselist && Len(baselist)) {
- Iterator b;
- int index = 0;
- b = First(baselist);
- while (b.item) {
- String *bname = Getattr(b.item, "name");
- if ((!bname) || GetFlag(b.item, "feature:ignore") || (!Getattr(b.item, "module"))) {
- b = Next(b);
- continue;
- }
- if (itcl) {
- have_base_classes = 1;
- Printv(base_classes, bname, " ", NIL);
- Printv(base_class_init, " ", bname, "Ptr::constructor $ptr\n", NIL);
- }
- String *bmangle = Swig_name_mangle(bname);
- // Printv(f_wrappers,"extern swig_class _wrap_class_", bmangle, ";\n", NIL);
- // Printf(base_class,"&_wrap_class_%s",bmangle);
- Printf(base_class, "0");
- Printf(base_class_names, "\"%s *\",", SwigType_namestr(bname));
- /* Put code to register base classes in init function */
-
- //Printf(f_init,"/* Register base : %s */\n", bmangle);
- //Printf(f_init,"swig_%s_bases[%d] = (swig_class *) SWIG_TypeQuery(\"%s *\")->clientdata;\n", mangled_classname, index, SwigType_namestr(bname));
- (void)index;
- b = Next(b);
- index++;
- Putc(',', base_class);
- Delete(bmangle);
- }
- }
-
- if (itcl) {
- String *ptrclass = NewString("");
-
- // First, build the pointer base class
- Printv(ptrclass, "itcl::class ", class_name, "Ptr {\n", NIL);
- if (have_base_classes)
- Printv(ptrclass, " inherit ", base_classes, "\n", NIL);
-
- // Define protected variables for SWIG object pointer
- Printv(ptrclass, " protected variable swigobj\n", " protected variable thisown\n", NIL);
-
- // Define public variables
- if (have_attributes) {
- Printv(ptrclass, attributes, NIL);
-
- // base class swig_getset was being called for complex inheritance trees
- if (namespace_option) {
-
- Printv(ptrclass, " protected method ", class_name, "_swig_getset {var name1 name2 op} {\n", NIL);
-
- Printv(ptrclass,
- " switch -exact -- $op {\n",
- " r {set $var [", ns_name, "::", class_name, "_[set var]_get $swigobj]}\n",
- " w {", ns_name, "::", class_name, "_${var}_set $swigobj [set $var]}\n", " }\n", " }\n", NIL);
- } else {
- Printv(ptrclass,
- " protected method ", class_name, "_swig_getset {var name1 name2 op} {\n",
- " switch -exact -- $op {\n",
- " r {set $var [", class_name, "_[set var]_get $swigobj]}\n",
- " w {", class_name, "_${var}_set $swigobj [set $var]}\n", " }\n", " }\n", NIL);
- }
- }
- // Add the constructor, which may include
- // calls to base class class constructors
-
- Printv(ptrclass, " constructor { ptr } {\n", NIL);
- if (have_base_classes) {
- Printv(ptrclass, base_class_init, NIL);
- Printv(ptrclass, " } {\n", NIL);
- }
-
- Printv(ptrclass, " set swigobj $ptr\n", " set thisown 0\n", NIL);
-
- if (have_attributes) {
- Printv(ptrclass, attribute_traces, NIL);
- }
- Printv(ptrclass, " }\n", NIL);
-
-
- // Add destructor
- Printv(ptrclass, " destructor {\n",
- " set d_func delete_", class_name, "\n",
- " if { $thisown && ([info command $d_func] != \"\") } {\n" " $d_func $swigobj\n", " }\n", " }\n", NIL);
-
- // Add methods
- if (have_methods) {
- Printv(ptrclass, imethods, NIL);
- }
-
- // Close out the pointer class
- Printv(ptrclass, "}\n\n", NIL);
- Printv(f_shadow, ptrclass, NIL);
- // pointer class end
-
-
- // Create the "real" class.
- Printv(f_shadow, "itcl::class ", class_name, " {\n", NIL);
- Printv(f_shadow, " inherit ", class_name, "Ptr\n", NIL);
-
- // If we have a constructor, then use it.
- // If not, then we must have an abstract class without
- // any constructor. So we create a class constructor
- // which will fail for this class (but not for inherited
- // classes). Note that the constructor must fail before
- // calling the ptrclass constructor.
-
- if (have_constructor) {
- Printv(f_shadow, constructor, NIL);
- } else {
- Printv(f_shadow, " constructor { } {\n", NIL);
- Printv(f_shadow, " # This constructor will fail if called directly\n", NIL);
- Printv(f_shadow, " if { [info class] == \"::", class_name, "\" } {\n", NIL);
- Printv(f_shadow, " error \"No constructor for class ", class_name, (Getattr(n, "abstracts") ? " - class is abstract" : ""), "\"\n", NIL);
- Printv(f_shadow, " }\n", NIL);
- Printv(f_shadow, " }\n", NIL);
- }
-
- Printv(f_shadow, "}\n\n", NIL);
- }
-
- Printv(f_wrappers, "static swig_class *swig_", mangled_classname, "_bases[] = {", base_class, "0};\n", NIL);
- Printv(f_wrappers, "static const char * swig_", mangled_classname, "_base_names[] = {", base_class_names, "0};\n", NIL);
- Delete(base_class);
- Delete(base_class_names);
-
- Printv(f_wrappers, "static swig_class _wrap_class_", mangled_classname, " = { \"", class_name, "\", &SWIGTYPE", SwigType_manglestr(t), ",", NIL);
-
- if (have_constructor) {
- Printf(f_wrappers, "%s", Swig_name_wrapper(Swig_name_construct(NSPACE_TODO, constructor_name)));
- Delete(constructor_name);
- constructor_name = 0;
- } else {
- Printf(f_wrappers, "0");
- }
- if (have_destructor) {
- Printv(f_wrappers, ", swig_delete_", class_name, NIL);
- } else {
- Printf(f_wrappers, ",0");
- }
- Printv(f_wrappers, ", swig_", mangled_classname, "_methods, swig_", mangled_classname, "_attributes, swig_", mangled_classname, "_bases,",
- "swig_", mangled_classname, "_base_names, &swig_module, SWIG_TCL_HASHTABLE_INIT };\n", NIL);
-
- if (!itcl) {
- Printv(cmd_tab, tab4, "{ SWIG_prefix \"", class_name, "\", (swig_wrapper_func) SWIG_ObjectConstructor, (ClientData)&_wrap_class_", mangled_classname,
- "},\n", NIL);
- }
-
- Delete(t);
- Delete(mangled_classname);
- return SWIG_OK;
- }
-
-
- /* ------------------------------------------------------------
- * memberfunctionHandler()
- * ------------------------------------------------------------ */
-
- virtual int memberfunctionHandler(Node *n) {
- String *name = Getattr(n, "name");
- String *iname = GetChar(n, "sym:name");
-
- String *realname, *rname;
-
- Language::memberfunctionHandler(n);
-
- realname = iname ? iname : name;
- rname = Swig_name_wrapper(Swig_name_member(NSPACE_TODO, class_name, realname));
- if (!Getattr(n, "sym:nextSibling")) {
- Printv(methods_tab, tab4, "{\"", realname, "\", ", rname, "}, \n", NIL);
- }
-
- if (itcl) {
- ParmList *l = Getattr(n, "parms");
- Parm *p = 0;
- String *pname = NewString("");
-
- // Add this member to our class handler function
- Printv(imethods, tab2, "method ", realname, " [list ", NIL);
-
- int pnum = 0;
- for (p = l; p; p = nextSibling(p)) {
-
- String *pn = Getattr(p, "name");
- String *dv = Getattr(p, "value");
- SwigType *pt = Getattr(p, "type");
-
- Printv(pname, ",(", pt, ")", NIL);
- Clear(pname);
-
- /* Only print an argument if not void */
- if (Cmp(pt, "void") != 0) {
- if (Len(pn) > 0) {
- Printv(pname, pn, NIL);
- } else {
- Printf(pname, "p%d", pnum);
- }
-
- if (Len(dv) > 0) {
- String *defval = NewString(dv);
- if (namespace_option) {
- Insert(defval, 0, "::");
- Insert(defval, 0, ns_name);
- }
- if (Strncmp(dv, "(", 1) == 0) {
- Insert(defval, 0, "$");
- Replaceall(defval, "(", "");
- Replaceall(defval, ")", "");
- }
- Printv(imethods, "[list ", pname, " ", defval, "] ", NIL);
- } else {
- Printv(imethods, pname, " ", NIL);
- }
- }
- ++pnum;
- }
- Printv(imethods, "] ", NIL);
-
- if (namespace_option) {
- Printv(imethods, "{ ", ns_name, "::", class_name, "_", realname, " $swigobj", NIL);
- } else {
- Printv(imethods, "{ ", class_name, "_", realname, " $swigobj", NIL);
- }
-
- pnum = 0;
- for (p = l; p; p = nextSibling(p)) {
-
- String *pn = Getattr(p, "name");
- SwigType *pt = Getattr(p, "type");
- Clear(pname);
-
- /* Only print an argument if not void */
- if (Cmp(pt, "void") != 0) {
- if (Len(pn) > 0) {
- Printv(pname, pn, NIL);
- } else {
- Printf(pname, "p%d", pnum);
- }
- Printv(imethods, " $", pname, NIL);
- }
- ++pnum;
- }
- Printv(imethods, " }\n", NIL);
- have_methods = 1;
- }
-
- Delete(rname);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * membervariableHandler()
- * ------------------------------------------------------------ */
-
- virtual int membervariableHandler(Node *n) {
- String *symname = Getattr(n, "sym:name");
- String *rname;
-
- Language::membervariableHandler(n);
- Printv(attr_tab, tab4, "{ \"-", symname, "\",", NIL);
- rname = Swig_name_wrapper(Swig_name_get(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname)));
- Printv(attr_tab, rname, ", ", NIL);
- Delete(rname);
- if (!GetFlag(n, "feature:immutable")) {
- rname = Swig_name_wrapper(Swig_name_set(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname)));
- Printv(attr_tab, rname, "},\n", NIL);
- Delete(rname);
- } else {
- Printf(attr_tab, "0 },\n");
- }
-
- if (itcl) {
- Printv(attributes, " public variable ", symname, "\n", NIL);
-
- Printv(attribute_traces, " trace variable ", symname, " rw [list ", class_name, "_swig_getset ", symname, "]\n", NIL);
- Printv(attribute_traces, " set ", symname, "\n", NIL);
-
- have_attributes = 1;
- }
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * constructorHandler()
- * ------------------------------------------------------------ */
-
- virtual int constructorHandler(Node *n) {
- Language::constructorHandler(n);
-
- if (itcl) {
- String *name = Getattr(n, "name");
- String *iname = GetChar(n, "sym:name");
-
- String *realname;
-
- ParmList *l = Getattr(n, "parms");
- Parm *p = 0;
-
- String *pname = NewString("");
-
- realname = iname ? iname : name;
-
- if (!have_constructor) {
- // Add this member to our class handler function
- Printf(constructor, " constructor { ");
-
- // Add parameter list
- int pnum = 0;
- for (p = l; p; p = nextSibling(p)) {
-
- SwigType *pt = Getattr(p, "type");
- String *pn = Getattr(p, "name");
- String *dv = Getattr(p, "value");
- Clear(pname);
-
- /* Only print an argument if not void */
- if (Cmp(pt, "void") != 0) {
- if (Len(pn) > 0) {
- Printv(pname, pn, NIL);
- } else {
- Printf(pname, "p%d", pnum);
- }
-
- if (Len(dv) > 0) {
- Printv(constructor, "{", pname, " {", dv, "} } ", NIL);
- } else {
- Printv(constructor, pname, " ", NIL);
- }
- }
- ++pnum;
- }
- Printf(constructor, "} { \n");
-
- // [BRE] 08/17/00 Added test to see if we are instantiating this object
- // type, or, if this constructor is being called as part of the itcl
- // inheritance hierarchy.
- // In the former case, we need to call the C++ constructor, in the
- // latter we don't, or we end up with two C++ objects.
- // Check to see if we are instantiating a 'realname' or something
- // derived from it.
- //
- Printv(constructor, " if { [string equal -nocase \"", realname, "\" \"[namespace tail [info class]]\" ] } {\n", NIL);
-
- // Call to constructor wrapper and parent Ptr class
- // [BRE] add -namespace/-prefix support
-
- if (namespace_option) {
- Printv(constructor, " ", realname, "Ptr::constructor [", ns_name, "::new_", realname, NIL);
- } else {
- Printv(constructor, " ", realname, "Ptr::constructor [new_", realname, NIL);
- }
-
- pnum = 0;
- for (p = l; p; p = nextSibling(p)) {
-
- SwigType *pt = Getattr(p, "type");
- String *pn = Getattr(p, "name");
- Clear(pname);
-
- /* Only print an argument if not void */
- if (Cmp(pt, "void") != 0) {
- if (Len(pn) > 0) {
- Printv(pname, pn, NIL);
- } else {
- Printf(pname, "p%d", pnum);
- }
- Printv(constructor, " $", pname, NIL);
- }
- ++pnum;
- }
-
- Printv(constructor, "]\n", " }\n", " } {\n", " set thisown 1\n", " }\n", NIL);
- }
- }
-
- if (!have_constructor)
- constructor_name = NewString(Getattr(n, "sym:name"));
- have_constructor = 1;
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * destructorHandler()
- * ------------------------------------------------------------ */
-
- virtual int destructorHandler(Node *n) {
- Language::destructorHandler(n);
- have_destructor = 1;
- destructor_action = Getattr(n, "wrap:action");
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * validIdentifier()
- * ------------------------------------------------------------ */
-
- virtual int validIdentifier(String *s) {
- if (Strchr(s, ' '))
- return 0;
- return 1;
- }
-
- /* ------------------------------------------------------------
- * usage_string()
- * ------------------------------------------------------------ */
-
- char *usage_string(char *iname, SwigType *, ParmList *l) {
- static String *temp = 0;
- Parm *p;
- int i, numopt, pcount;
-
- if (!temp)
- temp = NewString("");
- Clear(temp);
- if (namespace_option) {
- Printf(temp, "%s::%s ", ns_name, iname);
- } else {
- Printf(temp, "%s ", iname);
- }
- /* Now go through and print parameters */
- i = 0;
- pcount = emit_num_arguments(l);
- numopt = pcount - emit_num_required(l);
- for (p = l; p; p = nextSibling(p)) {
-
- SwigType *pt = Getattr(p, "type");
- String *pn = Getattr(p, "name");
- /* Only print an argument if not ignored */
- if (!checkAttribute(p, "tmap:in:numinputs", "0")) {
- if (i >= (pcount - numopt))
- Putc('?', temp);
- if (Len(pn) > 0) {
- Printf(temp, "%s", pn);
- } else {
- Printf(temp, "%s", SwigType_str(pt, 0));
- }
- if (i >= (pcount - numopt))
- Putc('?', temp);
- Putc(' ', temp);
- i++;
- }
- }
- return Char(temp);
- }
-
- String *runtimeCode() {
- String *s = NewString("");
- String *serrors = Swig_include_sys("tclerrors.swg");
- if (!serrors) {
- Printf(stderr, "*** Unable to open 'tclerrors.swg'\n");
- } else {
- Append(s, serrors);
- Delete(serrors);
- }
- String *sapi = Swig_include_sys("tclapi.swg");
- if (!sapi) {
- Printf(stderr, "*** Unable to open 'tclapi.swg'\n");
- } else {
- Append(s, sapi);
- Delete(sapi);
- }
- String *srun = Swig_include_sys("tclrun.swg");
- if (!srun) {
- Printf(stderr, "*** Unable to open 'tclrun.swg'\n");
- } else {
- Append(s, srun);
- Delete(srun);
- }
-
- return s;
- }
-
- String *defaultExternalRuntimeFilename() {
- return NewString("swigtclrun.h");
- }
-};
-
-/* ----------------------------------------------------------------------
- * swig_tcl() - Instantiate module
- * ---------------------------------------------------------------------- */
-
-static Language *new_swig_tcl() {
- return new TCL8();
-}
-extern "C" Language *swig_tcl(void) {
- return new_swig_tcl();
-}
diff --git a/contrib/tools/swig/Source/Modules/typepass.cxx b/contrib/tools/swig/Source/Modules/typepass.cxx
deleted file mode 100644
index 2a1dadf735..0000000000
--- a/contrib/tools/swig/Source/Modules/typepass.cxx
+++ /dev/null
@@ -1,1322 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * typepass.cxx
- *
- * This module builds all of the internal type information by collecting
- * typedef declarations as well as registering classes, structures, and unions.
- * This information is needed to correctly handle shadow classes and other
- * advanced features. This phase of compilation is also used to perform
- * type-expansion. All types are fully qualified with namespace prefixes
- * and other information needed for compilation.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include "cparse.h"
-
-struct normal_node {
- Symtab *symtab;
- Hash *typescope;
- List *normallist;
- normal_node *next;
-};
-
-static normal_node *patch_list = 0;
-
-/* Singleton class - all non-static methods in this class are private */
-class TypePass:private Dispatcher {
- Node *inclass;
- Node *module;
- int importmode;
- String *nsname;
- String *nssymname;
- Hash *classhash;
- List *normalize;
-
- TypePass() :
- inclass(0),
- module(0),
- importmode(0),
- nsname(0),
- nssymname(0),
- classhash(0),
- normalize(0) {
- }
-
- /* Normalize a type. Replaces type with fully qualified version */
- void normalize_type(SwigType *ty) {
- SwigType *qty;
- if (CPlusPlus) {
- Replaceall(ty, "struct ", "");
- Replaceall(ty, "union ", "");
- Replaceall(ty, "class ", "");
- }
-
- qty = SwigType_typedef_qualified(ty);
- /* Printf(stdout,"%s --> %s\n", ty, qty); */
- Clear(ty);
- Append(ty, qty);
- Delete(qty);
- }
-
- /* Normalize a parameter list */
-
- void normalize_parms(ParmList *p) {
- while (p) {
- SwigType *ty = Getattr(p, "type");
- normalize_type(ty);
- /* This is a check for a function type */
- {
- SwigType *qty = SwigType_typedef_resolve_all(ty);
- if (SwigType_isfunction(qty)) {
- SwigType_add_pointer(ty);
- }
- Delete(qty);
- }
-
- String *value = Getattr(p, "value");
- if (value) {
- Node *n = Swig_symbol_clookup(value, 0);
- if (n) {
- String *q = Swig_symbol_qualified(n);
- if (q && Len(q)) {
- String *vb = Swig_scopename_last(value);
- Clear(value);
- Printf(value, "%s::%s", SwigType_namestr(q), vb);
- Delete(q);
- }
- }
- }
- if (value && SwigType_istemplate(value)) {
- String *nv = SwigType_namestr(value);
- Setattr(p, "value", nv);
- }
- p = nextSibling(p);
- }
- }
-
- void normalize_later(ParmList *p) {
- while (p) {
- SwigType *ty = Getattr(p, "type");
- Append(normalize, ty);
- p = nextSibling(p);
- }
- }
-
- /* Walk through entries in normalize list and patch them up */
- void normalize_list() {
- Hash *currentsym = Swig_symbol_current();
-
- normal_node *nn = patch_list;
- normal_node *np;
- while (nn) {
- Swig_symbol_setscope(nn->symtab);
- SwigType_set_scope(nn->typescope);
- Iterator t;
- for (t = First(nn->normallist); t.item; t = Next(t)) {
- normalize_type(t.item);
- }
- Delete(nn->normallist);
- np = nn->next;
- delete(nn);
- nn = np;
- }
- Swig_symbol_setscope(currentsym);
- }
-
- /* generate C++ inheritance type-relationships */
- void cplus_inherit_types_impl(Node *first, Node *cls, String *clsname, const char *bases, const char *baselist, int ispublic, String *cast = 0) {
-
- if (first == cls)
- return; /* The Marcelo check */
- if (!cls)
- cls = first;
- List *alist = 0;
- List *ilist = Getattr(cls, bases);
- if (!ilist) {
- List *nlist = Getattr(cls, baselist);
- if (nlist) {
- int len = Len(nlist);
- int i;
- for (i = 0; i < len; i++) {
- Node *bcls = 0;
- int clsforward = 0;
- String *bname = Getitem(nlist, i);
- String *sname = bname;
- String *tname = 0;
-
- /* Try to locate the base class. We look in the symbol table and we chase
- typedef declarations to get to the base class if necessary */
- Symtab *st = Getattr(cls, "sym:symtab");
-
- if (SwigType_istemplate(bname)) {
- tname = SwigType_typedef_resolve_all(bname);
- sname = tname;
- }
- while (1) {
- String *qsname = SwigType_typedef_qualified(sname);
- bcls = Swig_symbol_clookup(qsname, st);
- Delete(qsname);
- if (bcls) {
- if (Strcmp(nodeType(bcls), "class") != 0) {
- /* Not a class. The symbol could be a typedef. */
- if (checkAttribute(bcls, "storage", "typedef")) {
- SwigType *decl = Getattr(bcls, "decl");
- if (!decl || !(Len(decl))) {
- sname = Getattr(bcls, "type");
- st = Getattr(bcls, "sym:symtab");
- if (SwigType_istemplate(sname)) {
- if (tname)
- Delete(tname);
- tname = SwigType_typedef_resolve_all(sname);
- sname = tname;
- }
- continue;
- }
- // A case when both outer and nested classes inherit from the same parent. Constructor may be found instead of the class itself.
- } else if (GetFlag(cls, "nested") && checkAttribute(bcls, "nodeType", "constructor")) {
- bcls = Getattr(bcls, "parentNode");
- if (Getattr(bcls, "typepass:visit")) {
- if (!Getattr(bcls, "feature:onlychildren")) {
- if (!ilist)
- ilist = alist = NewList();
- Append(ilist, bcls);
- } else {
- if (!GetFlag(bcls, "feature:ignore")) {
- Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Base class '%s' has no name as it is an empty template instantiated with '%%template()'. Ignored.\n", SwigType_namestr(bname));
- Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bcls), Getline(bcls), "The %%template directive must be written before '%s' is used as a base class and be declared with a name.\n", SwigType_namestr(bname));
- }
- }
- }
- break;
- }
- if (Strcmp(nodeType(bcls), "classforward") != 0) {
- Swig_error(Getfile(bname), Getline(bname), "'%s' is not a valid base class.\n", SwigType_namestr(bname));
- Swig_error(Getfile(bcls), Getline(bcls), "See definition of '%s'.\n", SwigType_namestr(bname));
- } else {
- Swig_warning(WARN_TYPE_INCOMPLETE, Getfile(bname), Getline(bname), "Base class '%s' is incomplete.\n", SwigType_namestr(bname));
- Swig_warning(WARN_TYPE_INCOMPLETE, Getfile(bcls), Getline(bcls), "Only forward declaration '%s' was found.\n", SwigType_namestr(bname));
- clsforward = 1;
- }
- bcls = 0;
- } else {
- if (Getattr(bcls, "typepass:visit")) {
- if (!Getattr(bcls, "feature:onlychildren")) {
- if (!ilist)
- ilist = alist = NewList();
- Append(ilist, bcls);
- } else {
- if (!GetFlag(bcls, "feature:ignore")) {
- Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Base class '%s' has no name as it is an empty template instantiated with '%%template()'. Ignored.\n", SwigType_namestr(bname));
- Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bcls), Getline(bcls), "The %%template directive must be written before '%s' is used as a base class and be declared with a name.\n", SwigType_namestr(bname));
- }
- }
- } else {
- Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Base class '%s' undefined.\n", SwigType_namestr(bname));
- Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bcls), Getline(bcls), "'%s' must be defined before it is used as a base class.\n", SwigType_namestr(bname));
- }
- }
- }
- break;
- }
-
- if (tname)
- Delete(tname);
- if (!bcls) {
- if (!clsforward && !GetFlag(cls, "feature:ignore")) {
- if (ispublic && !Getmeta(bname, "already_warned")) {
- Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Nothing known about base class '%s'. Ignored.\n", SwigType_namestr(bname));
- if (Strchr(bname, '<')) {
- Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Maybe you forgot to instantiate '%s' using %%template.\n", SwigType_namestr(bname));
- }
- Setmeta(bname, "already_warned", "1");
- }
- }
- SwigType_inherit(clsname, bname, cast, 0);
- }
- }
- }
- if (ilist) {
- Setattr(cls, bases, ilist);
- }
- }
- if (alist)
- Delete(alist);
-
- if (!ilist)
- return;
- int len = Len(ilist);
- int i;
- for (i = 0; i < len; i++) {
- Node *n = Getitem(ilist, i);
- String *bname = Getattr(n, "name");
- Node *bclass = n; /* Getattr(n,"class"); */
- Hash *scopes = Getattr(bclass, "typescope");
- SwigType_inherit(clsname, bname, cast, 0);
- if (ispublic && !GetFlag(bclass, "feature:ignore")) {
- String *smartptr = Getattr(first, "feature:smartptr");
- if (smartptr) {
- SwigType *smart = Swig_cparse_smartptr(first);
- if (smart) {
- /* Record a (fake) inheritance relationship between smart pointer
- and smart pointer to base class, so that smart pointer upcasts
- are automatically generated. */
- SwigType *bsmart = Copy(smart);
-
- // TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
- SwigType *rclsname = SwigType_typedef_resolve_all(clsname);
- SwigType *rbname = SwigType_typedef_resolve_all(bname);
- int replace_count = Replaceall(bsmart, rclsname, rbname);
- if (replace_count == 0) {
- // If no replacement made, it will be because rclsname is fully resolved, but the
- // type in the smartptr feature used a typedef or not fully resolved name.
- String *firstname = Getattr(first, "name");
- Replaceall(bsmart, firstname, rbname);
- }
- // The code above currently creates a smartptr of the base class by substitution, replacing Derived
- // with Base resulting in something like: 'smartptr< Derived >' from 'smartptr< Base >'. Instead
- // the feature:smartptr should be used as it also contains 'smartptr< Base >' as specified by the user.
- // A similar fix should also be done in upcastsCode in java.cxx, csharp.cxx and writeClassUpcast in d.cxx.
- // Printf(stdout, "smartcomparison %s <=> %s\n", SwigType_namestr(bsmart), Getattr(bclass, "feature:smartptr"));
-
- Delete(rclsname);
- Delete(rbname);
- String *smartnamestr = SwigType_namestr(smart);
- String *bsmartnamestr = SwigType_namestr(bsmart);
- /* construct casting code */
- String *convcode = NewStringf("\n *newmemory = SWIG_CAST_NEW_MEMORY;\n return (void *) new %s(*(%s *)$from);\n", bsmartnamestr, smartnamestr);
- Delete(bsmartnamestr);
- Delete(smartnamestr);
- /* setup inheritance relationship between smart pointer templates */
- SwigType_inherit(smart, bsmart, 0, convcode);
- if (!GetFlag(bclass, "feature:smartptr"))
- Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Base class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(bclass, "name")), SwigType_namestr(Getattr(first, "name")));
- Delete(convcode);
- Delete(bsmart);
- }
- Delete(smart);
- } else {
- if (GetFlag(bclass, "feature:smartptr"))
- Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Derived class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(first, "name")), SwigType_namestr(Getattr(bclass, "name")));
- }
- }
- if (!importmode) {
- String *btype = Copy(bname);
- SwigType_add_pointer(btype);
- SwigType_remember(btype);
- Delete(btype);
- }
- if (scopes) {
- SwigType_inherit_scope(scopes);
- }
- /* Set up inheritance in the symbol table */
- Symtab *st = Getattr(cls, "symtab");
- Symtab *bst = Getattr(bclass, "symtab");
- if (st == bst) {
- Swig_warning(WARN_PARSE_REC_INHERITANCE, Getfile(cls), Getline(cls), "Recursive scope inheritance of '%s'.\n", SwigType_namestr(Getattr(cls, "name")));
- continue;
- }
- Symtab *s = Swig_symbol_current();
- Swig_symbol_setscope(st);
- Swig_symbol_inherit(bst);
- Swig_symbol_setscope(s);
-
- /* Recursively hit base classes */
- String *namestr = SwigType_namestr(Getattr(bclass, "name"));
- String *newcast = NewStringf("(%s *)%s", namestr, cast);
- Delete(namestr);
- cplus_inherit_types_impl(first, bclass, clsname, bases, baselist, ispublic, newcast);
- Delete(newcast);
- }
- }
-
- void append_list(List *lb, List *la) {
- if (la && lb) {
- for (Iterator bi = First(la); bi.item; bi = Next(bi)) {
- Append(lb, bi.item);
- }
- }
- }
-
- void cplus_inherit_types(Node *first, Node *cls, String *clsname, String *cast = 0) {
- cplus_inherit_types_impl(first, cls, clsname, "bases", "baselist", 1, cast);
- cplus_inherit_types_impl(first, cls, clsname, "protectedbases", "protectedbaselist", 0, cast);
- cplus_inherit_types_impl(first, cls, clsname, "privatebases", "privatebaselist", 0, cast);
-
- if (!cls)
- cls = first;
-
- List *allbases = NewList();
- append_list(allbases, Getattr(cls, "bases"));
- append_list(allbases, Getattr(cls, "protectedbases"));
- append_list(allbases, Getattr(cls, "privatebases"));
- if (Len(allbases)) {
- Setattr(cls, "allbases", allbases);
- }
- Delete(allbases);
- }
-
- /* ------------------------------------------------------------
- * top()
- * ------------------------------------------------------------ */
-
- virtual int top(Node *n) {
- importmode = 0;
- module = Getattr(n, "module");
- inclass = 0;
- normalize = 0;
- nsname = 0;
- nssymname = 0;
- classhash = Getattr(n, "classes");
- emit_children(n);
- normalize_list();
- SwigType_set_scope(0);
- return SWIG_OK;
- }
-
-
- /* ------------------------------------------------------------
- * moduleDirective()
- * ------------------------------------------------------------ */
-
- virtual int moduleDirective(Node *n) {
- if (!module) {
- module = n;
- }
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * importDirective()
- * ------------------------------------------------------------ */
-
- virtual int importDirective(Node *n) {
- String *oldmodule = module;
- int oldimport = importmode;
- importmode = 1;
- module = 0;
- emit_children(n);
- importmode = oldimport;
- module = oldmodule;
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * includeDirective()
- * externDirective()
- * extendDirective()
- * ------------------------------------------------------------ */
-
- virtual int includeDirective(Node *n) {
- return emit_children(n);
- }
- virtual int externDeclaration(Node *n) {
- return emit_children(n);
- }
- virtual int extendDirective(Node *n) {
- return emit_children(n);
- }
-
- /* ------------------------------------------------------------
- * classDeclaration()
- * ------------------------------------------------------------ */
-
- virtual int classDeclaration(Node *n) {
- String *name = Getattr(n, "name");
- String *tdname = Getattr(n, "tdname");
- String *unnamed = Getattr(n, "unnamed");
- String *storage = Getattr(n, "storage");
- String *kind = Getattr(n, "kind");
- save_value<Node*> oldinclass(inclass);
- List *olist = normalize;
- Symtab *symtab;
- String *nname = 0;
- String *fname = 0;
- String *scopename = 0;
- String *template_default_expanded = 0;
-
- normalize = NewList();
-
- if (name) {
- if (SwigType_istemplate(name)) {
- // We need to fully resolve the name and expand default template parameters to make templates work correctly */
- Node *cn;
- SwigType *resolved_name = SwigType_typedef_resolve_all(name);
- SwigType *deftype_name = Swig_symbol_template_deftype(resolved_name, 0);
- fname = Copy(resolved_name);
- if (!Equal(resolved_name, deftype_name))
- template_default_expanded = Copy(deftype_name);
- if (!Equal(fname, name) && (cn = Swig_symbol_clookup_local(fname, 0))) {
- if ((n == cn)
- || (Strcmp(nodeType(cn), "template") == 0)
- || (Getattr(cn, "feature:onlychildren") != 0)
- || (Getattr(n, "feature:onlychildren") != 0)) {
- Swig_symbol_cadd(fname, n);
- if (template_default_expanded)
- Swig_symbol_cadd(template_default_expanded, n);
- SwigType_typedef_class(fname);
- scopename = Copy(fname);
- } else {
- Swig_warning(WARN_TYPE_REDEFINED, Getfile(n), Getline(n), "Template '%s' was already wrapped,\n", SwigType_namestr(name));
- Swig_warning(WARN_TYPE_REDEFINED, Getfile(cn), Getline(cn), "previous wrap of '%s'.\n", SwigType_namestr(Getattr(cn, "name")));
- scopename = 0;
- }
- } else {
- Swig_symbol_cadd(fname, n);
- SwigType_typedef_class(fname);
- scopename = Copy(fname);
- }
- Delete(deftype_name);
- Delete(resolved_name);
- } else {
- if ((CPlusPlus) || (unnamed)) {
- SwigType_typedef_class(name);
- } else {
- SwigType_typedef_class(NewStringf("%s %s", kind, name));
- }
- scopename = Copy(name);
- }
- } else {
- scopename = 0;
- }
-
- Setattr(n, "typepass:visit", "1");
-
- /* Need to set up a typedef if unnamed */
- if (unnamed && tdname && (Cmp(storage, "typedef") == 0)) {
- SwigType_typedef(unnamed, tdname);
- }
- // name of the outer class should already be patched to contain its outer classes names, but not to contain namespaces
- // namespace name (if present) is added after processing child nodes
- if (Getattr(n, "nested:outer") && name) {
- String *outerName = Getattr(Getattr(n, "nested:outer"), "name");
- name = NewStringf("%s::%s", outerName, name);
- Setattr(n, "name", name);
- if (tdname) {
- tdname = NewStringf("%s::%s", outerName, tdname);
- Setattr(n, "tdname", tdname);
- }
- }
-
- if (nsname && name) {
- nname = NewStringf("%s::%s", nsname, name);
- String *tdname = Getattr(n, "tdname");
- if (tdname) {
- tdname = NewStringf("%s::%s", nsname, tdname);
- Setattr(n, "tdname", tdname);
- }
- }
- if (nssymname) {
- if (GetFlag(n, "feature:nspace"))
- Setattr(n, "sym:nspace", nssymname);
- }
- SwigType_new_scope(scopename);
- SwigType_attach_symtab(Getattr(n, "symtab"));
-
- /* Inherit type definitions into the class */
- if (name && !(GetFlag(n, "nested") && !checkAttribute(n, "access", "public") &&
- (GetFlag(n, "feature:flatnested") || Language::instance()->nestedClassesSupport() == Language::NCS_None))) {
- cplus_inherit_types(n, 0, nname ? nname : (fname ? fname : name));
- }
-
- inclass = n;
- symtab = Swig_symbol_setscope(Getattr(n, "symtab"));
- emit_children(n);
- Swig_symbol_setscope(symtab);
-
- Hash *ts = SwigType_pop_scope();
- Setattr(n, "typescope", ts);
- Delete(ts);
- Setattr(n, "module", module);
-
- // When a fully qualified templated type with default parameters is used in the parsed code,
- // the following additional symbols and scopes are needed for successful lookups
- if (template_default_expanded) {
- Swig_symbol_alias(template_default_expanded, Getattr(n, "symtab"));
- SwigType_scope_alias(template_default_expanded, Getattr(n, "typescope"));
- }
-
- /* Normalize deferred types */
- {
- normal_node *nn = new normal_node();
- nn->normallist = normalize;
- nn->symtab = Getattr(n, "symtab");
- nn->next = patch_list;
- nn->typescope = Getattr(n, "typescope");
- patch_list = nn;
- }
-
- normalize = olist;
-
- /* If in a namespace, patch the class name */
- if (nname) {
- Setattr(n, "name", nname);
- Delete(nname);
- }
- Delete(fname);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * templateDeclaration()
- * ------------------------------------------------------------ */
-
- virtual int templateDeclaration(Node *n) {
- String *name = Getattr(n, "name");
- String *ttype = Getattr(n, "templatetype");
- if (Strcmp(ttype, "class") == 0) {
- String *rname = SwigType_typedef_resolve_all(name);
- SwigType_typedef_class(rname);
- Delete(rname);
- } else if (Strcmp(ttype, "classforward") == 0) {
- String *rname = SwigType_typedef_resolve_all(name);
- SwigType_typedef_class(rname);
- Delete(rname);
- /* SwigType_typedef_class(name); */
- } else if (Strcmp(ttype, "cdecl") == 0) {
- String *rname = SwigType_typedef_resolve_all(name);
- SwigType_typedef_class(rname);
- Delete(rname);
- }
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * lambdaDeclaration()
- * ------------------------------------------------------------ */
-
- virtual int lambdaDeclaration(Node *) {
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * classforwardDeclaration()
- * ------------------------------------------------------------ */
-
- virtual int classforwardDeclaration(Node *n) {
-
- /* Can't do inside a C struct because it breaks C nested structure wrapping */
- if ((!inclass) || (CPlusPlus)) {
- String *name = Getattr(n, "name");
- SwigType_typedef_class(name);
- }
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * namespaceDeclaration()
- * ------------------------------------------------------------ */
-
- virtual int namespaceDeclaration(Node *n) {
- Symtab *symtab;
- String *name = Getattr(n, "name");
- String *alias = Getattr(n, "alias");
- List *olist = normalize;
- normalize = NewList();
- if (alias) {
- Typetab *ts = Getattr(n, "typescope");
- if (!ts) {
- /* Create an empty scope for the alias */
- Node *ns = Getattr(n, "namespace");
- SwigType_scope_alias(name, Getattr(ns, "typescope"));
- ts = Getattr(ns, "typescope");
- Setattr(n, "typescope", ts);
- }
- /* Namespace alias */
- return SWIG_OK;
- } else {
- if (name) {
- Node *nn = Swig_symbol_clookup(name, n);
- Hash *ts = 0;
- if (nn)
- ts = Getattr(nn, "typescope");
- if (!ts) {
- SwigType_new_scope(name);
- SwigType_attach_symtab(Getattr(n, "symtab"));
- } else {
- SwigType_set_scope(ts);
- }
- }
- String *oldnsname = nsname;
- String *oldnssymname = nssymname;
- nsname = Swig_symbol_qualified(Getattr(n, "symtab"));
- nssymname = Swig_symbol_qualified_language_scopename(Getattr(n, "symtab"));
- symtab = Swig_symbol_setscope(Getattr(n, "symtab"));
- emit_children(n);
- Swig_symbol_setscope(symtab);
-
- if (name) {
- Hash *ts = SwigType_pop_scope();
- Setattr(n, "typescope", ts);
- Delete(ts);
- }
-
- /* Normalize deferred types */
- {
- normal_node *nn = new normal_node();
- nn->normallist = normalize;
- nn->symtab = Getattr(n, "symtab");
- nn->next = patch_list;
- nn->typescope = Getattr(n, "typescope");
- patch_list = nn;
- }
- normalize = olist;
-
- Delete(nssymname);
- nssymname = oldnssymname;
- Delete(nsname);
- nsname = oldnsname;
- return SWIG_OK;
- }
- }
-
- /* ------------------------------------------------------------
- * cDeclaration()
- * ------------------------------------------------------------ */
-
- virtual int cDeclaration(Node *n) {
- if (NoExcept) {
- Delattr(n, "throws");
- }
-
- /* Normalize types. */
- SwigType *ty = Getattr(n, "type");
- if (!ty) {
- return SWIG_OK;
- }
- normalize_type(ty);
- SwigType *decl = Getattr(n, "decl");
- if (decl) {
- normalize_type(decl);
- }
- normalize_parms(Getattr(n, "parms"));
- normalize_parms(Getattr(n, "throws"));
- if (GetFlag(n, "conversion_operator")) {
- /* The call to the operator in the generated wrapper must be fully qualified in order to compile */
- SwigType *name = Getattr(n, "name");
- SwigType *qualifiedname = Swig_symbol_string_qualify(name, 0);
- Clear(name);
- Append(name, qualifiedname);
- Delete(qualifiedname);
- }
-
- if (checkAttribute(n, "storage", "typedef")) {
- String *name = Getattr(n, "name");
- ty = Getattr(n, "type");
- decl = Getattr(n, "decl");
- SwigType *t = Copy(ty);
- {
- /* If the typename is qualified, make sure the scopename is fully qualified when making a typedef */
- if (Swig_scopename_check(t) && strncmp(Char(t), "::", 2)) {
- String *base, *prefix, *qprefix;
- base = Swig_scopename_last(t);
- prefix = Swig_scopename_prefix(t);
- qprefix = SwigType_typedef_qualified(prefix);
- Delete(t);
- t = NewStringf("%s::%s", qprefix, base);
- Delete(base);
- Delete(prefix);
- Delete(qprefix);
- }
- }
- SwigType_push(t, decl);
- if (CPlusPlus) {
- Replaceall(t, "struct ", "");
- Replaceall(t, "union ", "");
- Replaceall(t, "class ", "");
- }
- SwigType_typedef(t, name);
- }
- /* If namespaces are active. We need to patch the name with a namespace prefix */
- if (nsname && !inclass) {
- String *name = Getattr(n, "name");
- if (name) {
- String *nname = NewStringf("%s::%s", nsname, name);
- Setattr(n, "name", nname);
- Delete(nname);
- }
- }
- clean_overloaded(n);
- return SWIG_OK;
- }
-
-
- /* ------------------------------------------------------------
- * constructorDeclaration()
- * ------------------------------------------------------------ */
-
- virtual int constructorDeclaration(Node *n) {
- if (NoExcept) {
- Delattr(n, "throws");
- }
-
- normalize_parms(Getattr(n, "parms"));
- normalize_parms(Getattr(n, "throws"));
-
- clean_overloaded(n);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * destructorDeclaration()
- * ------------------------------------------------------------ */
-
- virtual int destructorDeclaration(Node *) {
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * constantDirective()
- * ------------------------------------------------------------ */
-
- virtual int constantDirective(Node *n) {
- SwigType *ty = Getattr(n, "type");
- if (ty) {
- Setattr(n, "type", SwigType_typedef_qualified(ty));
- }
- return SWIG_OK;
- }
-
-
- /* ------------------------------------------------------------
- * enumDeclaration()
- * ------------------------------------------------------------ */
-
- virtual int enumDeclaration(Node *n) {
- String *name = Getattr(n, "name");
-
- if (name) {
- String *scope = 0;
-
- // Add a typedef to the type table so that we can use 'enum Name' as well as just 'Name'
- if (nsname || inclass) {
-
- // But first correct the name and tdname to contain the fully qualified scopename
- if (nsname && inclass) {
- scope = NewStringf("%s::%s", nsname, Getattr(inclass, "name"));
- } else if (nsname) {
- scope = NewStringf("%s", nsname);
- } else if (inclass) {
- scope = NewStringf("%s", Getattr(inclass, "name"));
- }
-
- String *nname = NewStringf("%s::%s", scope, name);
- Setattr(n, "name", nname);
-
- String *tdname = Getattr(n, "tdname");
- if (tdname) {
- tdname = NewStringf("%s::%s", scope, tdname);
- Setattr(n, "tdname", tdname);
- }
-
- SwigType *t = NewStringf("enum %s", nname);
- SwigType_typedef(t, name);
- } else {
- SwigType *t = NewStringf("enum %s", name);
- SwigType_typedef(t, name);
- }
- Delete(scope);
- }
-
- String *tdname = Getattr(n, "tdname");
- String *unnamed = Getattr(n, "unnamed");
- String *storage = Getattr(n, "storage");
-
- // Construct enumtype - for declaring an enum of this type with SwigType_ltype() etc
- String *enumtype = 0;
- if (unnamed && tdname && (Cmp(storage, "typedef") == 0)) {
- enumtype = Copy(Getattr(n, "tdname"));
- } else if (name) {
- enumtype = NewStringf("%s%s", CPlusPlus ? "" : "enum ", Getattr(n, "name"));
- } else {
- // anonymous enums
- enumtype = Copy(Getattr(n, "type"));
- }
- Setattr(n, "enumtype", enumtype);
-
- if (nssymname) {
- if (GetFlag(n, "feature:nspace"))
- Setattr(n, "sym:nspace", nssymname);
- }
-
- // This block of code is for dealing with %ignore on an enum item where the target language
- // attempts to use the C enum value in the target language itself and expects the previous enum value
- // to be one more than the previous value... the previous enum item might not exist if it is ignored!
- // - It sets the first non-ignored enum item with the "firstenumitem" attribute.
- // - It adds an enumvalue attribute if the previous enum item is ignored
- {
- Node *c;
- int count = 0;
- String *previous = 0;
- bool previous_ignored = false;
- bool firstenumitem = false;
- for (c = firstChild(n); c; c = nextSibling(c)) {
- assert(strcmp(Char(nodeType(c)), "enumitem") == 0);
-
- bool reset;
- String *enumvalue = Getattr(c, "enumvalue");
- if (GetFlag(c, "feature:ignore") || !Getattr(c, "sym:name")) {
- reset = enumvalue ? true : false;
- previous_ignored = true;
- } else {
- if (!enumvalue && previous_ignored) {
- if (previous)
- Setattr(c, "enumvalue", NewStringf("(%s) + %d", previous, count+1));
- else
- Setattr(c, "enumvalue", NewStringf("%d", count));
- SetFlag(c, "virtenumvalue"); // identify enumvalue as virtual, ie not from the parsed source
- }
- if (!firstenumitem) {
- SetFlag(c, "firstenumitem");
- firstenumitem = true;
- }
- reset = true;
- previous_ignored = false;
- }
- if (reset) {
- previous = enumvalue ? enumvalue : Getattr(c, "name");
- count = 0;
- } else {
- count++;
- }
- }
- }
-
- emit_children(n);
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * enumvalueDeclaration()
- * ------------------------------------------------------------ */
-
- virtual int enumvalueDeclaration(Node *n) {
- String *name = Getattr(n, "name");
- String *value = Getattr(n, "value");
- String *scopedenum = Getattr(parentNode(n), "scopedenum");
- if (!value)
- value = name;
- if (Strcmp(value, name) == 0) {
- String *new_value;
- if ((nsname || inclass || scopedenum) && cparse_cplusplus) {
- new_value = NewStringf("%s::%s", SwigType_namestr(Swig_symbol_qualified(n)), value);
- } else {
- new_value = NewString(value);
- }
- if ((nsname || inclass || scopedenum) && !cparse_cplusplus) {
- String *cppvalue = NewStringf("%s::%s", SwigType_namestr(Swig_symbol_qualified(n)), value);
- Setattr(n, "cppvalue", cppvalue); /* for target languages that always generate C++ code even when wrapping C code */
- }
- Setattr(n, "value", new_value);
- Delete(new_value);
- }
- Node *next = nextSibling(n);
-
- // Make up an enumvalue if one was not specified in the parsed code (not designed to be used on enum items and %ignore - enumvalue will be set instead)
- if (!GetFlag(n, "feature:ignore")) {
- if (Getattr(n, "_last") && !Getattr(n, "enumvalue")) { // Only the first enum item has _last set (Note: first non-ignored enum item has firstenumitem set)
- Setattr(n, "enumvalueex", "0");
- }
- if (next && !Getattr(next, "enumvalue")) {
- Setattr(next, "enumvalueex", NewStringf("%s + 1", Getattr(n, "sym:name")));
- }
- }
-
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * enumforwardDeclaration()
- * ------------------------------------------------------------ */
-
- virtual int enumforwardDeclaration(Node *n) {
-
- // Use enumDeclaration() to do all the hard work.
- // Note that no children can be emitted in a forward declaration as there aren't any.
- int result = enumDeclaration(n);
- if (result == SWIG_OK) {
- // Detect when the real enum matching the forward enum declaration has not been parsed/declared
- SwigType *ty = SwigType_typedef_resolve_all(Getattr(n, "type"));
- Replaceall(ty, "enum ", "");
- Node *nn = Swig_symbol_clookup(ty, 0);
-
- String *nodetype = nn ? nodeType(nn) : 0;
- if (nodetype) {
- if (Equal(nodetype, "enumforward")) {
- SetFlag(nn, "enumMissing");
- } // if a real enum was declared this would be an "enum" node type
- }
- Delete(ty);
- }
- return result;
- }
-
-#ifdef DEBUG_OVERLOADED
- static void show_overloaded(Node *n) {
- Node *c = Getattr(n, "sym:overloaded");
- Node *checkoverloaded = c;
- Printf(stdout, "-------------------- overloaded start %s sym:overloaded():%p -------------------------------\n", Getattr(n, "name"), c);
- while (c) {
- if (Getattr(c, "error")) {
- c = Getattr(c, "sym:nextSibling");
- continue;
- }
- if (Getattr(c, "sym:overloaded") != checkoverloaded) {
- Printf(stdout, "sym:overloaded error c:%p checkoverloaded:%p\n", c, checkoverloaded);
- Swig_print_node(c);
- Exit(EXIT_FAILURE);
- }
-
- String *decl = Strcmp(nodeType(c), "using") == 0 ? NewString("------") : Getattr(c, "decl");
- Printf(stdout, " show_overloaded %s::%s(%s) [%s] nodeType:%s\n", parentNode(c) ? Getattr(parentNode(c), "name") : "NOPARENT", Getattr(c, "name"), decl, Getattr(c, "sym:overname"), nodeType(c));
- if (!Getattr(c, "sym:overloaded")) {
- Printf(stdout, "sym:overloaded error.....%p\n", c);
- Swig_print_node(c);
- Exit(EXIT_FAILURE);
- }
- c = Getattr(c, "sym:nextSibling");
- }
- Printf(stdout, "-------------------- overloaded end %s -------------------------------\n", Getattr(n, "name"));
- }
-#endif
-
- /* ------------------------------------------------------------
- * usingDeclaration()
- * ------------------------------------------------------------ */
-
- virtual int usingDeclaration(Node *n) {
- if (Getattr(n, "namespace")) {
- /* using namespace id */
-
- /* For a namespace import. We set up inheritance in the type system */
- Node *ns = Getattr(n, "node");
- if (ns) {
- Typetab *ts = Getattr(ns, "typescope");
- if (ts) {
- SwigType_using_scope(ts);
- }
- }
- return SWIG_OK;
- } else {
- Node *ns;
- /* using id */
- Symtab *stab = Getattr(n, "sym:symtab");
- if (stab) {
- String *uname = Getattr(n, "uname");
- ns = Swig_symbol_clookup(uname, stab);
- if (!ns && SwigType_istemplate(uname)) {
- String *tmp = Swig_symbol_template_deftype(uname, 0);
- if (!Equal(tmp, uname)) {
- ns = Swig_symbol_clookup(tmp, stab);
- }
- Delete(tmp);
- }
- } else {
- ns = 0;
- }
- if (!ns) {
- if (is_public(n)) {
- Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(n), Getline(n), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(n, "uname")));
- }
- } else {
- /* Only a single symbol is being used. There are only a few symbols that
- we actually care about. These are typedef, class declarations, and enum */
- String *ntype = nodeType(ns);
- if (Strcmp(ntype, "cdecl") == 0) {
- if (checkAttribute(ns, "storage", "typedef")) {
- /* A typedef declaration */
- String *uname = Getattr(n, "uname");
- SwigType_typedef_using(uname);
- } else {
- /* A normal C declaration. */
- if ((inclass) && (!GetFlag(n, "feature:ignore")) && (Getattr(n, "sym:name"))) {
- Node *c = ns;
- Node *unodes = 0, *last_unodes = 0;
- int ccount = 0;
- String *symname = Getattr(n, "sym:name");
-
- // The overloaded functions in scope may not yet have had their parameters normalized yet (in cDeclaration).
- // Happens if the functions were declared after the using declaration. So use a normalized copy.
- List *n_decl_list = NewList();
- Node *over = Getattr(n, "sym:overloaded");
- while (over) {
- String *odecl = Copy(Getattr(over, "decl"));
- if (odecl) {
- normalize_type(odecl);
- Append(n_decl_list, odecl);
- Delete(odecl);
- }
- over = Getattr(over, "sym:nextSibling");
- }
-
- while (c) {
- if (Strcmp(nodeType(c), "cdecl") == 0) {
- if (!(Swig_storage_isstatic(c)
- || checkAttribute(c, "storage", "typedef")
- || checkAttribute(c, "storage", "friend")
- || (Getattr(c, "feature:extend") && !Getattr(c, "code"))
- || GetFlag(c, "feature:ignore"))) {
-
- String *csymname = Getattr(c, "sym:name");
- if (!csymname || (Strcmp(csymname, symname) == 0)) {
- String *decl = Getattr(c, "decl");
- int match = 0;
-
- for (Iterator it = First(n_decl_list); it.item; it = Next(it)) {
- String *odecl = it.item;
- if (Cmp(decl, odecl) == 0) {
- match = 1;
- break;
- }
- }
- if (match) {
- /* Don't generate a method if the method is overridden in this class,
- * for example don't generate another m(bool) should there be a Base::m(bool) :
- * struct Derived : Base {
- * void m(bool);
- * using Base::m;
- * };
- */
- c = Getattr(c, "csym:nextSibling");
- continue;
- }
-
- Node *nn = copyNode(c);
- Setfile(nn, Getfile(n));
- Setline(nn, Getline(n));
- Delattr(nn, "access"); // access might be different from the method in the base class
- Setattr(nn, "access", Getattr(n, "access"));
- if (!Getattr(nn, "sym:name"))
- Setattr(nn, "sym:name", symname);
- Symtab *st = Getattr(n, "sym:symtab");
- assert(st);
- Setattr(nn, "sym:symtab", st);
-
- if (!GetFlag(nn, "feature:ignore")) {
- ParmList *parms = CopyParmList(Getattr(c, "parms"));
- int is_pointer = SwigType_ispointer_return(Getattr(nn, "decl"));
- int is_void = checkAttribute(nn, "type", "void") && !is_pointer;
- Setattr(nn, "parms", parms);
- Delete(parms);
- if (Getattr(n, "feature:extend")) {
- String *ucode = is_void ? NewStringf("{ self->%s(", Getattr(n, "uname")) : NewStringf("{ return self->%s(", Getattr(n, "uname"));
-
- for (ParmList *p = parms; p;) {
- Append(ucode, Getattr(p, "name"));
- p = nextSibling(p);
- if (p)
- Append(ucode, ",");
- }
- Append(ucode, "); }");
- Setattr(nn, "code", ucode);
- Delete(ucode);
- }
- ParmList *throw_parm_list = Getattr(c, "throws");
- if (throw_parm_list)
- Setattr(nn, "throws", CopyParmList(throw_parm_list));
- ccount++;
- if (!last_unodes) {
- last_unodes = nn;
- unodes = nn;
- } else {
- Setattr(nn, "previousSibling", last_unodes);
- Setattr(last_unodes, "nextSibling", nn);
- Setattr(nn, "sym:previousSibling", last_unodes);
- Setattr(last_unodes, "sym:nextSibling", nn);
- Setattr(nn, "sym:overloaded", unodes);
- Setattr(unodes, "sym:overloaded", unodes);
- last_unodes = nn;
- }
- } else {
- Delete(nn);
- }
- } else {
- Swig_warning(WARN_LANG_USING_NAME_DIFFERENT, Getfile(n), Getline(n), "Using declaration %s, with name '%s', is not actually using\n", SwigType_namestr(Getattr(n, "uname")), symname);
- Swig_warning(WARN_LANG_USING_NAME_DIFFERENT, Getfile(c), Getline(c), "the method from %s, with name '%s', as the names are different.\n", Swig_name_decl(c), csymname);
- }
- }
- }
- c = Getattr(c, "csym:nextSibling");
- }
- if (unodes) {
- set_firstChild(n, unodes);
- if (ccount > 1) {
- if (!Getattr(n, "sym:overloaded")) {
- Setattr(n, "sym:overloaded", n);
- Setattr(n, "sym:overname", "_SWIG_0");
- }
- }
- }
-
- /* Hack the parse tree symbol table for overloaded methods. Replace the "using" node with the
- * list of overloaded methods we have just added in as child nodes to the "using" node.
- * The node will still exist, it is just the symbol table linked list of overloaded methods
- * which is hacked. */
- if (Getattr(n, "sym:overloaded")) {
- int cnt = 0;
- Node *ps = Getattr(n, "sym:previousSibling");
- Node *ns = Getattr(n, "sym:nextSibling");
- Node *fc = firstChild(n);
- Node *firstoverloaded = Getattr(n, "sym:overloaded");
-#ifdef DEBUG_OVERLOADED
- show_overloaded(firstoverloaded);
-#endif
-
- if (firstoverloaded == n) {
- // This 'using' node we are cutting out was the first node in the overloaded list.
- // Change the first node in the list
- Delattr(firstoverloaded, "sym:overloaded");
- firstoverloaded = fc ? fc : ns;
-
- // Correct all the sibling overloaded methods (before adding in new methods)
- Node *nnn = ns;
- while (nnn) {
- Setattr(nnn, "sym:overloaded", firstoverloaded);
- nnn = Getattr(nnn, "sym:nextSibling");
- }
- }
-
- if (!fc) {
- // Remove from overloaded list ('using' node does not actually end up adding in any methods)
- if (ps) {
- Setattr(ps, "sym:nextSibling", ns);
- }
- if (ns) {
- Setattr(ns, "sym:previousSibling", ps);
- }
- } else {
- // The 'using' node results in methods being added in - slot in these methods here
- Node *pp = fc;
- while (pp) {
- Node *ppn = Getattr(pp, "sym:nextSibling");
- Setattr(pp, "sym:overloaded", firstoverloaded);
- Setattr(pp, "sym:overname", NewStringf("%s_%d", Getattr(n, "sym:overname"), cnt++));
- if (ppn)
- pp = ppn;
- else
- break;
- }
- if (ps) {
- Setattr(ps, "sym:nextSibling", fc);
- Setattr(fc, "sym:previousSibling", ps);
- }
- if (ns) {
- Setattr(ns, "sym:previousSibling", pp);
- Setattr(pp, "sym:nextSibling", ns);
- }
- }
- Delattr(n, "sym:previousSibling");
- Delattr(n, "sym:nextSibling");
- Delattr(n, "sym:overloaded");
- Delattr(n, "sym:overname");
- clean_overloaded(firstoverloaded);
-#ifdef DEBUG_OVERLOADED
- show_overloaded(firstoverloaded);
-#endif
- }
- Delete(n_decl_list);
- }
- }
- } else if ((Strcmp(ntype, "class") == 0) || ((Strcmp(ntype, "classforward") == 0))) {
- /* We install the using class name as kind of a typedef back to the original class */
- String *uname = Getattr(n, "uname");
- /* Import into current type scope */
- SwigType_typedef_using(uname);
- } else if (Strcmp(ntype, "enum") == 0) {
- SwigType_typedef_using(Getattr(n, "uname"));
- } else if (Strcmp(ntype, "template") == 0) {
- SwigType_typedef_using(Getattr(n, "uname"));
- }
- }
- }
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * typemapDirective()
- * ------------------------------------------------------------ */
-
- virtual int typemapDirective(Node *n) {
- if (inclass || nsname) {
- Node *items = firstChild(n);
- while (items) {
- Parm *pattern = Getattr(items, "pattern");
- Parm *parms = Getattr(items, "parms");
- normalize_later(pattern);
- normalize_later(parms);
- items = nextSibling(items);
- }
- }
- return SWIG_OK;
- }
-
-
- /* ------------------------------------------------------------
- * typemapcopyDirective()
- * ------------------------------------------------------------ */
-
- virtual int typemapcopyDirective(Node *n) {
- if (inclass || nsname) {
- Node *items = firstChild(n);
- ParmList *pattern = Getattr(n, "pattern");
- normalize_later(pattern);
- while (items) {
- ParmList *npattern = Getattr(items, "pattern");
- normalize_later(npattern);
- items = nextSibling(items);
- }
- }
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * applyDirective()
- * ------------------------------------------------------------ */
-
- virtual int applyDirective(Node *n) {
- if (inclass || nsname) {
- ParmList *pattern = Getattr(n, "pattern");
- normalize_later(pattern);
- Node *items = firstChild(n);
- while (items) {
- Parm *apattern = Getattr(items, "pattern");
- normalize_later(apattern);
- items = nextSibling(items);
- }
- }
- return SWIG_OK;
- }
-
- /* ------------------------------------------------------------
- * clearDirective()
- * ------------------------------------------------------------ */
-
- virtual int clearDirective(Node *n) {
- if (inclass || nsname) {
- Node *p;
- for (p = firstChild(n); p; p = nextSibling(p)) {
- ParmList *pattern = Getattr(p, "pattern");
- normalize_later(pattern);
- }
- }
- return SWIG_OK;
- }
-
-public:
- static void pass(Node *n) {
- TypePass t;
- t.top(n);
- }
-};
-
-void Swig_process_types(Node *n) {
- if (!n)
- return;
- TypePass::pass(n);
-}
-
diff --git a/contrib/tools/swig/Source/Modules/utils.cxx b/contrib/tools/swig/Source/Modules/utils.cxx
deleted file mode 100644
index de6f87d8c3..0000000000
--- a/contrib/tools/swig/Source/Modules/utils.cxx
+++ /dev/null
@@ -1,218 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * utils.cxx
- *
- * Various utility functions.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-
-int is_public(Node *n) {
- String *access = Getattr(n, "access");
- return !access || !Cmp(access, "public");
-}
-
-int is_private(Node *n) {
- String *access = Getattr(n, "access");
- return access && !Cmp(access, "private");
-}
-
-int is_protected(Node *n) {
- String *access = Getattr(n, "access");
- return access && !Cmp(access, "protected");
-}
-
-static int is_member_director_helper(Node *parentnode, Node *member) {
- int parent_nodirector = GetFlag(parentnode, "feature:nodirector");
- if (parent_nodirector)
- return 0;
- int parent_director = Swig_director_mode() && GetFlag(parentnode, "feature:director");
- int cdecl_director = parent_director || GetFlag(member, "feature:director");
- int cdecl_nodirector = GetFlag(member, "feature:nodirector");
- return cdecl_director && !cdecl_nodirector && !GetFlag(member, "feature:extend");
-}
-
-int is_member_director(Node *parentnode, Node *member) {
- if (parentnode && checkAttribute(member, "storage", "virtual")) {
- return is_member_director_helper(parentnode, member);
- } else {
- return 0;
- }
-}
-
-int is_member_director(Node *member) {
- return is_member_director(Getattr(member, "parentNode"), member);
-}
-
-// Identifies the additional protected members that are generated when the allprotected option is used.
-// This does not include protected virtual methods as they are turned on with the dirprot option.
-int is_non_virtual_protected_access(Node *n) {
- int result = 0;
- if (Swig_director_mode() && Swig_director_protected_mode() && Swig_all_protected_mode() && is_protected(n) && !checkAttribute(n, "storage", "virtual")) {
- Node *parentNode = Getattr(n, "parentNode");
- // When vtable is empty, the director class does not get emitted, so a check for an empty vtable should be done.
- // However, vtable is set in Language and so is not yet set when methods in Typepass call clean_overloaded()
- // which calls is_non_virtual_protected_access. So commented out below.
- // Moving the director vtable creation into Typepass should solve this problem.
- if (is_member_director_helper(parentNode, n) /* && Getattr(parentNode, "vtable")*/)
- result = 1;
- }
- return result;
-}
-
-/* Clean overloaded list. Removes templates, ignored, and errors */
-
-void clean_overloaded(Node *n) {
- Node *nn = Getattr(n, "sym:overloaded");
- Node *first = 0;
- while (nn) {
- String *ntype = nodeType(nn);
- if ((GetFlag(nn, "feature:ignore")) ||
- (Getattr(nn, "error")) ||
- (Strcmp(ntype, "template") == 0) ||
- ((Strcmp(ntype, "cdecl") == 0) && is_protected(nn) && !is_member_director(nn) && !is_non_virtual_protected_access(n))) {
- /* Remove from overloaded list */
- Node *ps = Getattr(nn, "sym:previousSibling");
- Node *ns = Getattr(nn, "sym:nextSibling");
- if (ps) {
- Setattr(ps, "sym:nextSibling", ns);
- }
- if (ns) {
- Setattr(ns, "sym:previousSibling", ps);
- }
- Delattr(nn, "sym:previousSibling");
- Delattr(nn, "sym:nextSibling");
- Delattr(nn, "sym:overloaded");
- nn = ns;
- continue;
- } else {
- if (!first)
- first = nn;
- Setattr(nn, "sym:overloaded", first);
- }
- nn = Getattr(nn, "sym:nextSibling");
- }
- if (!first || (first && !Getattr(first, "sym:nextSibling"))) {
- if (Getattr(n, "sym:overloaded"))
- Delattr(n, "sym:overloaded");
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_set_max_hash_expand()
- *
- * Controls how many Hash objects are displayed when displaying nested Hash objects.
- * Makes DohSetMaxHashExpand an externally callable function (for debugger).
- * ----------------------------------------------------------------------------- */
-
-void Swig_set_max_hash_expand(int count) {
- SetMaxHashExpand(count);
-}
-
-extern "C" {
-
-/* -----------------------------------------------------------------------------
- * Swig_get_max_hash_expand()
- *
- * Returns how many Hash objects are displayed when displaying nested Hash objects.
- * Makes DohGetMaxHashExpand an externally callable function (for debugger).
- * ----------------------------------------------------------------------------- */
-
-int Swig_get_max_hash_expand() {
- return GetMaxHashExpand();
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_to_doh_string()
- *
- * DOH version of Swig_to_string()
- * ----------------------------------------------------------------------------- */
-
-static String *Swig_to_doh_string(DOH *object, int count) {
- int old_count = Swig_get_max_hash_expand();
- if (count >= 0)
- Swig_set_max_hash_expand(count);
-
- String *debug_string = object ? NewStringf("%s", object) : NewString("NULL");
-
- Swig_set_max_hash_expand(old_count);
- return debug_string;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_to_doh_string_with_location()
- *
- * DOH version of Swig_to_string_with_location()
- * ----------------------------------------------------------------------------- */
-
-static String *Swig_to_doh_string_with_location(DOH *object, int count) {
- int old_count = Swig_get_max_hash_expand();
- if (count >= 0)
- Swig_set_max_hash_expand(count);
-
- String *debug_string = Swig_stringify_with_location(object);
-
- Swig_set_max_hash_expand(old_count);
- return debug_string;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_to_string()
- *
- * Swig debug - return C string representation of any DOH type.
- * Nested Hash types expand count is value of Swig_get_max_hash_expand when count<0
- * Note: leaks memory.
- * ----------------------------------------------------------------------------- */
-
-const char *Swig_to_string(DOH *object, int count) {
- return Char(Swig_to_doh_string(object, count));
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_to_string_with_location()
- *
- * Swig debug - return C string representation of any DOH type, within [] brackets
- * for Hash and List types, prefixed by line and file information.
- * Nested Hash types expand count is value of Swig_get_max_hash_expand when count<0
- * Note: leaks memory.
- * ----------------------------------------------------------------------------- */
-
-const char *Swig_to_string_with_location(DOH *object, int count) {
- return Char(Swig_to_doh_string_with_location(object, count));
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_print()
- *
- * Swig debug - display string representation of any DOH type.
- * Nested Hash types expand count is value of Swig_get_max_hash_expand when count<0
- * ----------------------------------------------------------------------------- */
-
-void Swig_print(DOH *object, int count) {
- String *output = Swig_to_doh_string(object, count);
- Printf(stdout, "%s\n", output);
- Delete(output);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_to_string_with_location()
- *
- * Swig debug - display string representation of any DOH type, within [] brackets
- * for Hash and List types, prefixed by line and file information.
- * Nested Hash types expand count is value of Swig_get_max_hash_expand when count<0
- * ----------------------------------------------------------------------------- */
-
-void Swig_print_with_location(DOH *object, int count) {
- String *output = Swig_to_doh_string_with_location(object, count);
- Printf(stdout, "%s\n", output);
- Delete(output);
-}
-
-} // extern "C"
-
diff --git a/contrib/tools/swig/Source/Modules/xml.cxx b/contrib/tools/swig/Source/Modules/xml.cxx
deleted file mode 100644
index ed4213cc5c..0000000000
--- a/contrib/tools/swig/Source/Modules/xml.cxx
+++ /dev/null
@@ -1,326 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * xml.cxx
- *
- * An Xml parse tree generator.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-
-static const char *usage = "\
-XML Options (available with -xml)\n\
- -xmllang <lang> - Typedef language\n\
- -xmllite - More lightweight version of XML\n\
- ------\n\
- deprecated (use -o): -xml <output.xml> - Use <output.xml> as output file (extension .xml mandatory)\n";
-
-static File *out = 0;
-static int xmllite = 0;
-
-
-class XML:public Language {
-public:
-
- int indent_level;
- long id;
-
- XML() :indent_level(0) , id(0) {
- }
-
- virtual ~ XML() {
- }
-
- virtual void main(int argc, char *argv[]) {
- SWIG_typemap_lang("xml");
- for (int iX = 0; iX < argc; iX++) {
- if (strcmp(argv[iX], "-xml") == 0) {
- char *extension = 0;
- if (iX + 1 >= argc)
- continue;
- extension = argv[iX + 1] + strlen(argv[iX + 1]) - 4;
- if (strcmp(extension, ".xml"))
- continue;
- iX++;
- Swig_mark_arg(iX);
- String *outfile = NewString(argv[iX]);
- out = NewFile(outfile, "w", SWIG_output_files());
- if (!out) {
- FileErrorDisplay(outfile);
- Exit(EXIT_FAILURE);
- }
- continue;
- }
- if (strcmp(argv[iX], "-xmllang") == 0) {
- Swig_mark_arg(iX);
- iX++;
- SWIG_typemap_lang(argv[iX]);
- Swig_mark_arg(iX);
- continue;
- }
- if (strcmp(argv[iX], "-help") == 0) {
- fputs(usage, stdout);
- }
- if (strcmp(argv[iX], "-xmllite") == 0) {
- Swig_mark_arg(iX);
- xmllite = 1;
- }
- }
-
- // Add a symbol to the parser for conditional compilation
- Preprocessor_define("SWIGXML 1", 0);
- }
-
- /* Top of the parse tree */
-
- virtual int top(Node *n) {
- if (out == 0) {
- String *outfile = Getattr(n, "outfile");
- String *ext = Swig_file_extension(outfile);
- // If there's an extension, ext will include the ".".
- Delslice(outfile, Len(outfile) - Len(ext), DOH_END);
- Delete(ext);
- Append(outfile, ".xml");
- out = NewFile(outfile, "w", SWIG_output_files());
- if (!out) {
- FileErrorDisplay(outfile);
- Exit(EXIT_FAILURE);
- }
- }
- Printf(out, "<?xml version=\"1.0\" ?> \n");
- Xml_print_tree(n);
- return SWIG_OK;
- }
-
- void print_indent(int l) {
- int i;
- for (i = 0; i < indent_level; i++) {
- Printf(out, " ");
- }
- if (l) {
- Printf(out, " ");
- }
- }
-
- void Xml_print_tree(DOH *obj) {
- while (obj) {
- Xml_print_node(obj);
- obj = nextSibling(obj);
- }
- }
-
- void Xml_print_attributes(Node *obj) {
- String *k;
- indent_level += 4;
- print_indent(0);
- Printf(out, "<attributelist id=\"%ld\" addr=\"%p\">\n", ++id, obj);
- indent_level += 4;
- Iterator ki;
- ki = First(obj);
- while (ki.key) {
- k = ki.key;
- if ((Cmp(k, "nodeType") == 0)
- || (Cmp(k, "firstChild") == 0)
- || (Cmp(k, "lastChild") == 0)
- || (Cmp(k, "parentNode") == 0)
- || (Cmp(k, "nextSibling") == 0)
- || (Cmp(k, "previousSibling") == 0)
- || (*(Char(k)) == '$')) {
- /* Do nothing */
- } else if (Cmp(k, "module") == 0) {
- Xml_print_module(Getattr(obj, k));
- } else if (Cmp(k, "baselist") == 0) {
- Xml_print_baselist(Getattr(obj, k));
- } else if (!xmllite && Cmp(k, "typescope") == 0) {
- Xml_print_typescope(Getattr(obj, k));
- } else if (!xmllite && Cmp(k, "typetab") == 0) {
- Xml_print_typetab(Getattr(obj, k));
- } else if (Cmp(k, "kwargs") == 0) {
- Xml_print_kwargs(Getattr(obj, k));
- } else if (Cmp(k, "parms") == 0 || Cmp(k, "pattern") == 0) {
- Xml_print_parmlist(Getattr(obj, k));
- } else if (Cmp(k, "catchlist") == 0 || Cmp(k, "templateparms") == 0) {
- Xml_print_parmlist(Getattr(obj, k), Char(k));
- } else {
- DOH *o;
- print_indent(0);
- if (DohIsString(Getattr(obj, k))) {
- String *ck = NewString(k);
- o = Str(Getattr(obj, k));
- Replaceall(ck, ":", "_");
- Replaceall(ck, "<", "&lt;");
- /* Do first to avoid aliasing errors. */
- Replaceall(o, "&", "&amp;");
- Replaceall(o, "<", "&lt;");
- Replaceall(o, "\"", "&quot;");
- Replaceall(o, "\\", "\\\\");
- Replaceall(o, "\n", "&#10;");
- Printf(out, "<attribute name=\"%s\" value=\"%s\" id=\"%ld\" addr=\"%p\" />\n", ck, o, ++id, o);
- Delete(o);
- Delete(ck);
- } else {
- o = Getattr(obj, k);
- String *ck = NewString(k);
- Replaceall(ck, ":", "_");
- Printf(out, "<attribute name=\"%s\" value=\"%p\" id=\"%ld\" addr=\"%p\" />\n", ck, o, ++id, o);
- Delete(ck);
- }
- }
- ki = Next(ki);
- }
- indent_level -= 4;
- print_indent(0);
- Printf(out, "</attributelist>\n");
- indent_level -= 4;
- }
-
- void Xml_print_node(Node *obj) {
- Node *cobj;
-
- print_indent(0);
- Printf(out, "<%s id=\"%ld\" addr=\"%p\">\n", nodeType(obj), ++id, obj);
- Xml_print_attributes(obj);
- cobj = firstChild(obj);
- if (cobj) {
- indent_level += 4;
- Printf(out, "\n");
- Xml_print_tree(cobj);
- indent_level -= 4;
- } else {
- print_indent(1);
- Printf(out, "\n");
- }
- print_indent(0);
- Printf(out, "</%s>\n", nodeType(obj));
- }
-
-
- void Xml_print_parmlist(ParmList *p, const char* markup = "parmlist") {
-
- print_indent(0);
- Printf(out, "<%s id=\"%ld\" addr=\"%p\">\n", markup, ++id, p);
- indent_level += 4;
- while (p) {
- print_indent(0);
- Printf(out, "<parm id=\"%ld\">\n", ++id);
- Xml_print_attributes(p);
- print_indent(0);
- Printf(out, "</parm>\n");
- p = nextSibling(p);
- }
- indent_level -= 4;
- print_indent(0);
- Printf(out, "</%s>\n", markup);
- }
-
- void Xml_print_baselist(List *p) {
-
- print_indent(0);
- Printf(out, "<baselist id=\"%ld\" addr=\"%p\">\n", ++id, p);
- indent_level += 4;
- Iterator s;
- for (s = First(p); s.item; s = Next(s)) {
- print_indent(0);
- String *item_name = Xml_escape_string(s.item);
- Printf(out, "<base name=\"%s\" id=\"%ld\" addr=\"%p\" />\n", item_name, ++id, s.item);
- Delete(item_name);
- }
- indent_level -= 4;
- print_indent(0);
- Printf(out, "</baselist>\n");
- }
-
- String *Xml_escape_string(String *str) {
- String *escaped_str = 0;
- if (str) {
- escaped_str = NewString(str);
- Replaceall(escaped_str, "&", "&amp;");
- Replaceall(escaped_str, "<", "&lt;");
- Replaceall(escaped_str, "\"", "&quot;");
- Replaceall(escaped_str, "\\", "\\\\");
- Replaceall(escaped_str, "\n", "&#10;");
- }
- return escaped_str;
- }
-
- void Xml_print_module(Node *p) {
-
- print_indent(0);
- Printf(out, "<attribute name=\"module\" value=\"%s\" id=\"%ld\" addr=\"%p\" />\n", Getattr(p, "name"), ++id, p);
- }
-
- void Xml_print_kwargs(Hash *p) {
- Xml_print_hash(p, "kwargs");
- }
-
- void Xml_print_typescope(Hash *p) {
-
- Xml_print_hash(p, "typescope");
- }
-
- void Xml_print_typetab(Hash *p) {
-
- Xml_print_hash(p, "typetab");
- }
-
-
- void Xml_print_hash(Hash *p, const char *markup) {
-
- print_indent(0);
- Printf(out, "<%s id=\"%ld\" addr=\"%p\">\n", markup, ++id, p);
- Xml_print_attributes(p);
- indent_level += 4;
- Iterator n = First(p);
- while (n.key) {
- print_indent(0);
- Printf(out, "<%ssitem id=\"%ld\" addr=\"%p\">\n", markup, ++id, n.item);
- Xml_print_attributes(n.item);
- print_indent(0);
- Printf(out, "</%ssitem>\n", markup);
- n = Next(n);
- }
- indent_level -= 4;
- print_indent(0);
- Printf(out, "</%s>\n", markup);
- }
-
-};
-
-/* -----------------------------------------------------------------------------
- * Swig_print_xml
- *
- * Dump an XML version of the parse tree. This is different from using the -xml
- * language module normally as it allows the real language module to process the
- * tree first, possibly stuffing in new attributes, so the XML that is output ends
- * up being a post-processing version of the tree.
- * ----------------------------------------------------------------------------- */
-
-void Swig_print_xml(DOH *obj, String *filename) {
- XML xml;
- xmllite = 1;
-
- if (!filename) {
- out = stdout;
- } else {
- out = NewFile(filename, "w", SWIG_output_files());
- if (!out) {
- FileErrorDisplay(filename);
- Exit(EXIT_FAILURE);
- }
- }
-
- Printf(out, "<?xml version=\"1.0\" ?> \n");
- xml.Xml_print_tree(obj);
-}
-
-static Language *new_swig_xml() {
- return new XML();
-}
-extern "C" Language *swig_xml(void) {
- return new_swig_xml();
-}
diff --git a/contrib/tools/swig/Source/Preprocessor/cpp.c b/contrib/tools/swig/Source/Preprocessor/cpp.c
deleted file mode 100644
index a80434323c..0000000000
--- a/contrib/tools/swig/Source/Preprocessor/cpp.c
+++ /dev/null
@@ -1,2111 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * cpp.c
- *
- * An implementation of a C preprocessor plus some support for additional
- * SWIG directives.
- *
- * - SWIG directives such as %include, %extern, and %import are handled
- * - A new macro %define ... %enddef can be used for multiline macros
- * - No preprocessing is performed in %{ ... %} blocks
- * - Lines beginning with %# are stripped down to #... and passed through.
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-#include "preprocessor.h"
-#include <ctype.h>
-
-static Hash *cpp = 0; /* C preprocessor data */
-static int include_all = 0; /* Follow all includes */
-static int ignore_missing = 0;
-static int import_all = 0; /* Follow all includes, but as %import statements */
-static int imported_depth = 0; /* Depth of %imported files */
-static int single_include = 1; /* Only include each file once */
-static Hash *included_files = 0;
-static List *dependencies = 0;
-static Scanner *id_scan = 0;
-static int error_as_warning = 0; /* Understand the cpp #error directive as a special #warning */
-static int expand_defined_operator = 0;
-static int macro_level = 0;
-static int macro_start_line = 0;
-static const String * macro_start_file = 0;
-
-/* Test a character to see if it starts an identifier */
-#define isidentifier(c) ((isalpha(c)) || (c == '_') || (c == '$'))
-
-/* Test a character to see if it valid in an identifier (after the first letter) */
-#define isidchar(c) ((isalnum(c)) || (c == '_') || (c == '$'))
-
-static DOH *Preprocessor_replace(DOH *);
-
-/* Skip whitespace */
-static void skip_whitespace(String *s, String *out) {
- int c;
- while ((c = Getc(s)) != EOF) {
- if (!isspace(c)) {
- Ungetc(c, s);
- break;
- } else if (out)
- Putc(c, out);
- }
-}
-
-/* Skip to a specified character taking line breaks into account */
-static int skip_tochar(String *s, int ch, String *out) {
- int c;
- while ((c = Getc(s)) != EOF) {
- if (out)
- Putc(c, out);
- if (c == ch)
- break;
- if (c == '\\') {
- c = Getc(s);
- if ((c != EOF) && (out))
- Putc(c, out);
- }
- }
- if (c == EOF)
- return -1;
- return 0;
-}
-
-static void copy_location(const DOH *s1, DOH *s2) {
- Setfile(s2, Getfile((DOH *) s1));
- Setline(s2, Getline((DOH *) s1));
-}
-
-static String *cpp_include(const_String_or_char_ptr fn, int sysfile) {
- String *s = sysfile ? Swig_include_sys(fn) : Swig_include(fn);
- if (s && single_include) {
- String *file = Getfile(s);
- if (Getattr(included_files, file)) {
- Delete(s);
- return 0;
- }
- Setattr(included_files, file, file);
- }
- if (!s) {
- if (ignore_missing) {
- Swig_warning(WARN_PP_MISSING_FILE, Getfile(fn), Getline(fn), "Unable to find '%s'\n", fn);
- } else {
- Swig_error(Getfile(fn), Getline(fn), "Unable to find '%s'\n", fn);
- }
- } else {
- String *lf;
- Seek(s, 0, SEEK_SET);
- if (!dependencies) {
- dependencies = NewList();
- }
- lf = Copy(Swig_last_file());
- Append(dependencies, lf);
- Delete(lf);
- }
- return s;
-}
-
-static int is_digits(const String *str) {
- const char *s = Char(str);
- int isdigits = (*s != 0);
- while (*s) {
- if (!isdigit((int)*s)) {
- isdigits = 0;
- break;
- }
- s++;
- }
- return isdigits;
-}
-
-List *Preprocessor_depend(void) {
- return dependencies;
-}
-
-/* -----------------------------------------------------------------------------
- * void Preprocessor_cpp_init() - Initialize the preprocessor
- * ----------------------------------------------------------------------------- */
-static String *kpp_args = 0;
-static String *kpp_define = 0;
-static String *kpp_defined = 0;
-static String *kpp_elif = 0;
-static String *kpp_else = 0;
-static String *kpp_endif = 0;
-static String *kpp_expanded = 0;
-static String *kpp_if = 0;
-static String *kpp_ifdef = 0;
-static String *kpp_ifndef = 0;
-static String *kpp_name = 0;
-static String *kpp_swigmacro = 0;
-static String *kpp_symbols = 0;
-static String *kpp_undef = 0;
-static String *kpp_value = 0;
-static String *kpp_varargs = 0;
-static String *kpp_error = 0;
-static String *kpp_warning = 0;
-static String *kpp_line = 0;
-static String *kpp_include = 0;
-static String *kpp_pragma = 0;
-static String *kpp_level = 0;
-
-static String *kpp_dline = 0;
-static String *kpp_ddefine = 0;
-static String *kpp_dinclude = 0;
-static String *kpp_dimport = 0;
-static String *kpp_dbeginfile = 0;
-static String *kpp_dextern = 0;
-
-static String *kpp_LINE = 0;
-static String *kpp_FILE = 0;
-
-static String *kpp_hash_if = 0;
-static String *kpp_hash_elif = 0;
-
-void Preprocessor_init(void) {
- Hash *s;
-
- kpp_args = NewString("args");
- kpp_define = NewString("define");
- kpp_defined = NewString("defined");
- kpp_else = NewString("else");
- kpp_elif = NewString("elif");
- kpp_endif = NewString("endif");
- kpp_expanded = NewString("*expanded*");
- kpp_if = NewString("if");
- kpp_ifdef = NewString("ifdef");
- kpp_ifndef = NewString("ifndef");
- kpp_name = NewString("name");
- kpp_swigmacro = NewString("swigmacro");
- kpp_symbols = NewString("symbols");
- kpp_undef = NewString("undef");
- kpp_value = NewString("value");
- kpp_error = NewString("error");
- kpp_warning = NewString("warning");
- kpp_pragma = NewString("pragma");
- kpp_level = NewString("level");
- kpp_line = NewString("line");
- kpp_include = NewString("include");
- kpp_varargs = NewString("varargs");
-
- kpp_dinclude = NewString("%include");
- kpp_dimport = NewString("%import");
- kpp_dbeginfile = NewString("%beginfile");
- kpp_dextern = NewString("%extern");
- kpp_ddefine = NewString("%define");
- kpp_dline = NewString("%line");
-
-
- kpp_LINE = NewString("__LINE__");
- kpp_FILE = NewString("__FILE__");
-
- kpp_hash_if = NewString("#if");
- kpp_hash_elif = NewString("#elif");
-
- cpp = NewHash();
- s = NewHash();
- Setattr(cpp, kpp_symbols, s);
- Delete(s);
- Preprocessor_expr_init(); /* Initialize the expression evaluator */
- included_files = NewHash();
-
- id_scan = NewScanner();
-
-}
-
-void Preprocessor_delete(void) {
- Delete(kpp_args);
- Delete(kpp_define);
- Delete(kpp_defined);
- Delete(kpp_else);
- Delete(kpp_elif);
- Delete(kpp_endif);
- Delete(kpp_expanded);
- Delete(kpp_if);
- Delete(kpp_ifdef);
- Delete(kpp_ifndef);
- Delete(kpp_name);
- Delete(kpp_swigmacro);
- Delete(kpp_symbols);
- Delete(kpp_undef);
- Delete(kpp_value);
- Delete(kpp_error);
- Delete(kpp_warning);
- Delete(kpp_pragma);
- Delete(kpp_level);
- Delete(kpp_line);
- Delete(kpp_include);
- Delete(kpp_varargs);
-
- Delete(kpp_dinclude);
- Delete(kpp_dimport);
- Delete(kpp_dbeginfile);
- Delete(kpp_dextern);
- Delete(kpp_ddefine);
- Delete(kpp_dline);
-
- Delete(kpp_LINE);
- Delete(kpp_FILE);
-
- Delete(kpp_hash_if);
- Delete(kpp_hash_elif);
-
- Delete(cpp);
- Delete(included_files);
- Preprocessor_expr_delete();
- DelScanner(id_scan);
-
- Delete(dependencies);
-
- Delete(Swig_add_directory(0));
-}
-
-/* -----------------------------------------------------------------------------
- * void Preprocessor_include_all() - Instruct preprocessor to include all files
- * ----------------------------------------------------------------------------- */
-void Preprocessor_include_all(int a) {
- include_all = a;
-}
-
-void Preprocessor_import_all(int a) {
- import_all = a;
-}
-
-void Preprocessor_ignore_missing(int a) {
- ignore_missing = a;
-}
-
-void Preprocessor_error_as_warning(int a) {
- error_as_warning = a;
-}
-
-
-/* -----------------------------------------------------------------------------
- * Preprocessor_define()
- *
- * Defines a new C preprocessor symbol. swigmacro specifies whether or not the macro has
- * SWIG macro semantics.
- * ----------------------------------------------------------------------------- */
-
-
-String *Macro_vararg_name(const_String_or_char_ptr str, const_String_or_char_ptr line) {
- String *argname;
- String *varargname;
- char *s, *dots;
-
- argname = Copy(str);
- s = Char(argname);
- dots = strchr(s, '.');
- if (!dots) {
- Delete(argname);
- return NULL;
- }
-
- if (strcmp(dots, "...") != 0) {
- Swig_error(Getfile(line), Getline(line), "Illegal macro argument name '%s'\n", str);
- Delete(argname);
- return NULL;
- }
- if (dots == s) {
- varargname = NewString("__VA_ARGS__");
- } else {
- *dots = '\0';
- varargname = NewString(s);
- }
- Delete(argname);
- return varargname;
-}
-
-Hash *Preprocessor_define(const_String_or_char_ptr _str, int swigmacro) {
- String *macroname = 0, *argstr = 0, *macrovalue = 0, *file = 0, *s = 0;
- Hash *macro = 0, *symbols = 0, *m1;
- List *arglist = 0;
- int c, line;
- int varargs = 0;
- String *str;
-
- assert(cpp);
- assert(_str);
-
- /* First make sure that string is actually a string */
- if (DohCheck(_str)) {
- s = Copy(_str);
- copy_location(_str, s);
- str = s;
- } else {
- str = NewString((char *) _str);
- }
- Seek(str, 0, SEEK_SET);
- line = Getline(str);
- file = Getfile(str);
-
- /* Skip over any leading whitespace */
- skip_whitespace(str, 0);
-
- /* Now look for a macro name */
- macroname = NewStringEmpty();
- copy_location(str, macroname);
- while ((c = Getc(str)) != EOF) {
- if (c == '(') {
- argstr = NewStringEmpty();
- copy_location(str, argstr);
- /* It is a macro. Go extract its argument string */
- while ((c = Getc(str)) != EOF) {
- if (c == ')')
- break;
- else
- Putc(c, argstr);
- }
- if (c != ')') {
- Swig_error(Getfile(argstr), Getline(argstr), "Missing \')\' in macro parameters\n");
- goto macro_error;
- }
- break;
- } else if (isidchar(c) || (c == '%')) {
- Putc(c, macroname);
- } else if (isspace(c)) {
- break;
- } else if (c == '\\') {
- c = Getc(str);
- if (c != '\n') {
- Ungetc(c, str);
- Ungetc('\\', str);
- break;
- }
- } else {
- Ungetc(c, str);
- break;
- }
- }
- if (!swigmacro)
- skip_whitespace(str, 0);
- macrovalue = NewStringEmpty();
- copy_location(str, macrovalue);
- while ((c = Getc(str)) != EOF) {
- Putc(c, macrovalue);
- }
-
- /* If there are any macro arguments, convert into a list */
- if (argstr) {
- String *argname, *varargname;
- arglist = NewList();
- Seek(argstr, 0, SEEK_SET);
- argname = NewStringEmpty();
- while ((c = Getc(argstr)) != EOF) {
- if (c == ',') {
- varargname = Macro_vararg_name(argname, argstr);
- if (varargname) {
- Delete(varargname);
- Swig_error(Getfile(argstr), Getline(argstr), "Variable length macro argument must be last parameter\n");
- } else {
- Append(arglist, argname);
- }
- Delete(argname);
- argname = NewStringEmpty();
- } else if (isidchar(c) || (c == '.')) {
- Putc(c, argname);
- } else if (!(isspace(c) || (c == '\\'))) {
- Delete(argname);
- Swig_error(Getfile(argstr), Getline(argstr), "Illegal character in macro argument name\n");
- goto macro_error;
- }
- }
- if (Len(argname)) {
- /* Check for varargs */
- varargname = Macro_vararg_name(argname, argstr);
- if (varargname) {
- Append(arglist, varargname);
- Delete(varargname);
- varargs = 1;
- } else {
- Append(arglist, argname);
- }
- }
- Delete(argname);
- }
-
- if (!swigmacro) {
- Replace(macrovalue, "\\\n", " ", DOH_REPLACE_NOQUOTE);
- }
-
- /* Look for special # substitutions. We only consider # that appears
- outside of quotes and comments */
-
- {
- int state = 0;
- char *cc = Char(macrovalue);
- while (*cc) {
- switch (state) {
- case 0:
- if (*cc == '#')
- *cc = '\001';
- else if (*cc == '/')
- state = 10;
- else if (*cc == '\'')
- state = 20;
- else if (*cc == '\"')
- state = 30;
- break;
- case 10:
- if (*cc == '*')
- state = 11;
- else if (*cc == '/')
- state = 15;
- else {
- state = 0;
- cc--;
- }
- break;
- case 11:
- if (*cc == '*')
- state = 12;
- break;
- case 12:
- if (*cc == '/')
- state = 0;
- else if (*cc != '*')
- state = 11;
- break;
- case 15:
- if (*cc == '\n')
- state = 0;
- break;
- case 20:
- if (*cc == '\'')
- state = 0;
- if (*cc == '\\')
- state = 21;
- break;
- case 21:
- state = 20;
- break;
- case 30:
- if (*cc == '\"')
- state = 0;
- if (*cc == '\\')
- state = 31;
- break;
- case 31:
- state = 30;
- break;
- default:
- break;
- }
- cc++;
- }
- }
-
- /* Get rid of whitespace surrounding # */
- /* Replace(macrovalue,"#","\001",DOH_REPLACE_NOQUOTE); */
- while (strstr(Char(macrovalue), "\001 ")) {
- Replace(macrovalue, "\001 ", "\001", DOH_REPLACE_ANY);
- }
- while (strstr(Char(macrovalue), " \001")) {
- Replace(macrovalue, " \001", "\001", DOH_REPLACE_ANY);
- }
- /* Replace '##' with a special token */
- Replace(macrovalue, "\001\001", "\002", DOH_REPLACE_ANY);
- /* Replace '#@' with a special token */
- Replace(macrovalue, "\001@", "\004", DOH_REPLACE_ANY);
- /* Replace '##@' with a special token */
- Replace(macrovalue, "\002@", "\005", DOH_REPLACE_ANY);
-
- /* Go create the macro */
- macro = NewHash();
- Setattr(macro, kpp_name, macroname);
-
- if (arglist) {
- Setattr(macro, kpp_args, arglist);
- Delete(arglist);
- if (varargs) {
- Setattr(macro, kpp_varargs, "1");
- }
- }
- Setattr(macro, kpp_value, macrovalue);
- Setline(macro, line);
- Setfile(macro, file);
- if (swigmacro) {
- Setattr(macro, kpp_swigmacro, "1");
- }
- symbols = Getattr(cpp, kpp_symbols);
- if ((m1 = Getattr(symbols, macroname))) {
- if (!Checkattr(m1, kpp_value, macrovalue)) {
- Swig_error(Getfile(macroname), Getline(macroname), "Macro '%s' redefined,\n", macroname);
- Swig_error(Getfile(m1), Getline(m1), "previous definition of '%s'.\n", macroname);
- goto macro_error;
- }
- } else {
- Setattr(symbols, macroname, macro);
- Delete(macro);
- }
-
- Delete(macroname);
- Delete(macrovalue);
-
- Delete(str);
- Delete(argstr);
- return macro;
-
-macro_error:
- Delete(str);
- Delete(argstr);
- Delete(arglist);
- Delete(macroname);
- Delete(macrovalue);
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Preprocessor_undef()
- *
- * Undefines a macro.
- * ----------------------------------------------------------------------------- */
-void Preprocessor_undef(const_String_or_char_ptr str) {
- Hash *symbols;
- assert(cpp);
- symbols = Getattr(cpp, kpp_symbols);
- Delattr(symbols, str);
-}
-
-/* -----------------------------------------------------------------------------
- * find_args()
- *
- * Isolates macro arguments and returns them in a list. For each argument,
- * leading and trailing whitespace is stripped (ala K&R, pg. 230).
- * ----------------------------------------------------------------------------- */
-static List *find_args(String *s, int ismacro, String *macro_name) {
- List *args;
- String *str;
- int c, level;
- long pos;
-
- /* Create a new list */
- args = NewList();
- copy_location(s, args);
-
- /* First look for a '(' */
- pos = Tell(s);
- skip_whitespace(s, 0);
-
- /* Now see if the next character is a '(' */
- c = Getc(s);
- if (c != '(') {
- /* Not a macro, bail out now! */
- assert(pos != -1);
- (void)Seek(s, pos, SEEK_SET);
- Delete(args);
- return 0;
- }
- c = Getc(s);
- /* Okay. This appears to be a macro so we will start isolating arguments */
- while (c != EOF) {
- if (isspace(c)) {
- skip_whitespace(s, 0); /* Skip leading whitespace */
- c = Getc(s);
- }
- str = NewStringEmpty();
- copy_location(s, str);
- level = 0;
- while (c != EOF) {
- if (c == '\"') {
- Putc(c, str);
- skip_tochar(s, '\"', str);
- c = Getc(s);
- continue;
- } else if (c == '\'') {
- Putc(c, str);
- skip_tochar(s, '\'', str);
- c = Getc(s);
- continue;
- } else if (c == '/') {
- /* Ensure comments are ignored by eating up the characters */
- c = Getc(s);
- /* Handle / * ... * / type comments (multi-line) */
- if (c == '*') {
- while ((c = Getc(s)) != EOF) {
- if (c == '*') {
- c = Getc(s);
- if (c == '/' || c == EOF)
- break;
- }
- }
- c = Getc(s);
- continue;
- }
- /* Handle // ... type comments (single-line) */
- if (c == '/') {
- while ((c = Getc(s)) != EOF) {
- if (c == '\n') {
- break;
- }
- }
- c = Getc(s);
- continue;
- }
- /* ensure char is available in the stream as this was not a comment*/
- Ungetc(c, s);
- c = '/';
- }
- if ((c == ',') && (level == 0))
- break;
- if ((c == ')') && (level == 0))
- break;
- Putc(c, str);
- if (c == '(')
- level++;
- if (c == ')')
- level--;
- c = Getc(s);
- }
- if (level > 0) {
- goto unterm;
- }
- Chop(str);
- Append(args, str);
- Delete(str);
- if (c == ')')
- return args;
- c = Getc(s);
- }
-unterm:
- if (ismacro)
- Swig_error(Getfile(args), Getline(args), "Unterminated call invoking macro '%s'\n", macro_name);
- else
- Swig_error(Getfile(args), Getline(args), "Unterminated call to '%s'\n", macro_name);
- return args;
-}
-
-/* -----------------------------------------------------------------------------
- * DOH *get_filename()
- *
- * Read a filename from str. A filename can be enclosed in quotes, angle brackets,
- * or bare.
- * ----------------------------------------------------------------------------- */
-
-static String *get_filename(String *str, int *sysfile) {
- String *fn;
- int c;
-
- fn = NewStringEmpty();
- copy_location(str, fn);
- c = Getc(str);
- *sysfile = 0;
- if (c == '\"') {
- while (((c = Getc(str)) != EOF) && (c != '\"'))
- Putc(c, fn);
- } else if (c == '<') {
- *sysfile = 1;
- while (((c = Getc(str)) != EOF) && (c != '>'))
- Putc(c, fn);
- } else {
- String *preprocessed_str;
- Putc(c, fn);
- while (((c = Getc(str)) != EOF) && (!isspace(c)))
- Putc(c, fn);
- if (isspace(c))
- Ungetc(c, str);
- preprocessed_str = Preprocessor_replace(fn);
- Seek(preprocessed_str, 0, SEEK_SET);
- Delete(fn);
-
- fn = NewStringEmpty();
- copy_location(preprocessed_str, fn);
- c = Getc(preprocessed_str);
- if (c == '\"') {
- while (((c = Getc(preprocessed_str)) != EOF) && (c != '\"'))
- Putc(c, fn);
- } else if (c == '<') {
- *sysfile = 1;
- while (((c = Getc(preprocessed_str)) != EOF) && (c != '>'))
- Putc(c, fn);
- } else {
- fn = Copy(preprocessed_str);
- }
- Delete(preprocessed_str);
- }
- Swig_filename_unescape(fn);
- Swig_filename_correct(fn);
- Seek(fn, 0, SEEK_SET);
- return fn;
-}
-
-static String *get_options(String *str) {
- int c;
- c = Getc(str);
- if (c == '(') {
- String *opt;
- int level = 1;
- opt = NewString("(");
- while (((c = Getc(str)) != EOF)) {
- Putc(c, opt);
- switch (c) {
- case ')':
- level--;
- if (!level)
- return opt;
- break;
- case '(':
- level++;
- break;
- case '"':
- /* Skip over quoted strings */
- while (1) {
- c = Getc(str);
- if (c == EOF)
- goto bad;
- Putc(c, opt);
- if (c == '"')
- break;
- if (c == '\\') {
- c = Getc(str);
- if (c == EOF)
- goto bad;
- Putc(c, opt);
- }
- }
- break;
- }
- }
-bad:
- Delete(opt);
- return 0;
- } else {
- Ungetc(c, str);
- return 0;
- }
-}
-
-/* -----------------------------------------------------------------------------
- * expand_macro()
- *
- * Perform macro expansion and return a new string. Returns NULL if some sort
- * of error occurred.
- * name - name of the macro
- * args - arguments passed to the macro
- * line_file - only used for line/file name when reporting errors
- * ----------------------------------------------------------------------------- */
-
-static String *expand_macro(String *name, List *args, String *line_file) {
- String *ns;
- DOH *symbols, *macro, *margs, *mvalue, *temp, *tempa, *e;
- int i, l;
- int isvarargs = 0;
-
- symbols = Getattr(cpp, kpp_symbols);
- if (!symbols)
- return 0;
-
- /* See if the name is actually defined */
- macro = Getattr(symbols, name);
- if (!macro)
- return 0;
-
- if (macro_level == 0) {
- /* Store the start of the macro should the macro contain __LINE__ and __FILE__ for expansion */
- macro_start_line = Getline(args ? args : line_file);
- macro_start_file = Getfile(args ? args : line_file);
- }
- macro_level++;
-
- if (Getattr(macro, kpp_expanded)) {
- ns = NewStringEmpty();
- Append(ns, name);
- if (args) {
- int lenargs = Len(args);
- if (lenargs)
- Putc('(', ns);
- for (i = 0; i < lenargs; i++) {
- Append(ns, Getitem(args, i));
- if (i < (lenargs - 1))
- Putc(',', ns);
- }
- if (i)
- Putc(')', ns);
- }
- macro_level--;
- return ns;
- }
-
- /* Get macro arguments and value */
- mvalue = Getattr(macro, kpp_value);
- assert(mvalue);
- margs = Getattr(macro, kpp_args);
-
- if (args && Getattr(macro, kpp_varargs)) {
- isvarargs = 1;
- /* Variable length argument macro. We need to collect all of the extra arguments into a single argument */
- if (Len(args) >= (Len(margs) - 1)) {
- int i;
- int vi, na;
- String *vararg = NewStringEmpty();
- vi = Len(margs) - 1;
- na = Len(args);
- for (i = vi; i < na; i++) {
- Append(vararg, Getitem(args, i));
- if ((i + 1) < na) {
- Append(vararg, ",");
- }
- }
- /* Remove arguments */
- for (i = vi; i < na; i++) {
- Delitem(args, vi);
- }
- Append(args, vararg);
- Delete(vararg);
- }
- }
-
- if (args && margs && Len(margs) == 0 && Len(args) == 1 && Len(Getitem(args, 0)) == 0) {
- /* FOO() can invoke a macro defined as FOO(X) as well as one defined FOO().
- *
- * Handle this by removing the only argument if it's empty and the macro
- * expects no arguments.
- *
- * We don't need to worry about varargs here - a varargs macro will always have
- * Len(margs) >= 1, since the varargs are put in the final macro argument.
- */
- Delitem(args, 0);
- }
-
- /* If there are arguments, see if they match what we were given */
- if (args && (!margs || Len(margs) != Len(args))) {
- if (margs && Len(margs) > (1 + isvarargs))
- Swig_error(macro_start_file, macro_start_line, "Macro '%s' expects %d arguments\n", name, Len(margs) - isvarargs);
- else if (margs && Len(margs) == (1 + isvarargs))
- Swig_error(macro_start_file, macro_start_line, "Macro '%s' expects 1 argument\n", name);
- else
- Swig_error(macro_start_file, macro_start_line, "Macro '%s' expects no arguments\n", name);
- macro_level--;
- return 0;
- }
-
- /* If the macro expects arguments, but none were supplied, we leave it in place */
- if (!args && margs) {
- macro_level--;
- return NewString(name);
- }
-
- /* Copy the macro value */
- ns = Copy(mvalue);
- copy_location(mvalue, ns);
-
- /* Tag the macro as being expanded. This is to avoid recursion in
- macro expansion */
-
- temp = NewStringEmpty();
- tempa = NewStringEmpty();
- if (args && margs) {
- l = Len(margs);
- for (i = 0; i < l; i++) {
- DOH *arg, *aname;
- String *reparg;
- arg = Getitem(args, i); /* Get an argument value */
- reparg = Preprocessor_replace(arg);
- aname = Getitem(margs, i); /* Get macro argument name */
- if (strstr(Char(ns), "\001")) {
- /* Try to replace a quoted version of the argument */
- Clear(temp);
- Clear(tempa);
- Printf(temp, "\001%s", aname);
- Printf(tempa, "\"%s\"", arg);
- Replace(ns, temp, tempa, DOH_REPLACE_ID_END);
- }
- if (strstr(Char(ns), "\002")) {
- /* Look for concatenation tokens */
- Clear(temp);
- Clear(tempa);
- Printf(temp, "\002%s", aname);
- Append(tempa, "\002\003");
- Replace(ns, temp, tempa, DOH_REPLACE_ID_END);
- Clear(temp);
- Clear(tempa);
- Printf(temp, "%s\002", aname);
- Append(tempa, "\003\002");
- Replace(ns, temp, tempa, DOH_REPLACE_ID_BEGIN);
- }
-
- /* Non-standard macro expansion. The value `x` is replaced by a quoted
- version of the argument except that if the argument is already quoted
- nothing happens */
-
- if (strchr(Char(ns), '`')) {
- String *rep;
- char *c;
- Clear(temp);
- Printf(temp, "`%s`", aname);
- c = Char(arg);
- if (*c == '\"') {
- rep = arg;
- } else {
- Clear(tempa);
- Printf(tempa, "\"%s\"", arg);
- rep = tempa;
- }
- Replace(ns, temp, rep, DOH_REPLACE_ANY);
- }
-
- /* Non-standard mangle expansions.
- The #@Name is replaced by mangle_arg(Name). */
- if (strstr(Char(ns), "\004")) {
- String *marg = Swig_string_mangle(arg);
- Clear(temp);
- Printf(temp, "\004%s", aname);
- Replace(ns, temp, marg, DOH_REPLACE_ID_END);
- Delete(marg);
- }
- if (strstr(Char(ns), "\005")) {
- String *marg = Swig_string_mangle(arg);
- Clear(temp);
- Clear(tempa);
- Printf(temp, "\005%s", aname);
- Printf(tempa, "\"%s\"", marg);
- Replace(ns, temp, tempa, DOH_REPLACE_ID_END);
- Delete(marg);
- }
-
- if (isvarargs && i == l - 1 && Len(arg) == 0) {
- /* Zero length varargs macro argument. We search for commas that might appear before and nuke them */
- char *a, *s, *t, *name;
- int namelen;
- s = Char(ns);
- name = Char(aname);
- namelen = Len(aname);
- a = strstr(s, name);
- while (a) {
- char ca = a[namelen];
- if (!isidchar((int) ca)) {
- /* Matched the entire vararg name, not just a prefix */
- if (a > s) {
- t = a - 1;
- if (*t == '\002') {
- t--;
- while (t >= s) {
- if (isspace((int) *t))
- t--;
- else if (*t == ',') {
- *t = ' ';
- } else
- break;
- }
- }
- }
- }
- a = strstr(a + namelen, name);
- }
- }
- /* Replace(ns, aname, arg, DOH_REPLACE_ID); */
- Replace(ns, aname, reparg, DOH_REPLACE_ID); /* Replace expanded args */
- Replace(ns, "\003", arg, DOH_REPLACE_ANY); /* Replace unexpanded arg */
- Delete(reparg);
- }
- }
- Replace(ns, "\002", "", DOH_REPLACE_ANY); /* Get rid of concatenation tokens */
- Replace(ns, "\001", "#", DOH_REPLACE_ANY); /* Put # back (non-standard C) */
- Replace(ns, "\004", "#@", DOH_REPLACE_ANY); /* Put # back (non-standard C) */
-
- /* Expand this macro even further */
- Setattr(macro, kpp_expanded, "1");
-
- e = Preprocessor_replace(ns);
-
- Delattr(macro, kpp_expanded);
- Delete(ns);
-
- if (Getattr(macro, kpp_swigmacro)) {
- String *g;
- String *f = NewStringEmpty();
- Seek(e, 0, SEEK_SET);
- copy_location(macro, e);
- g = Preprocessor_parse(e);
-
-#if 0
- /* Drop the macro in place, but with a marker around it */
- Printf(f, "/*@%s,%d,%s@*/%s/*@@*/", Getfile(macro), Getline(macro), name, g);
-#else
- /* Use simplified around markers to properly count lines in cscanner.c */
- if (strchr(Char(g), '\n')) {
- Printf(f, "/*@SWIG:%s,%d,%s@*/%s/*@SWIG@*/", Getfile(macro), Getline(macro), name, g);
-#if 0
- Printf(f, "/*@SWIG:%s@*/%s/*@SWIG@*/", name, g);
-#endif
- } else {
- Append(f, g);
- }
-#endif
-
- Delete(g);
- Delete(e);
- e = f;
- }
- macro_level--;
- Delete(temp);
- Delete(tempa);
- return e;
-}
-
-/* -----------------------------------------------------------------------------
- * DOH *Preprocessor_replace(DOH *s)
- *
- * Performs a macro substitution on a string s. Returns a new string with
- * substitutions applied. This function works by walking down s and looking
- * for identifiers. When found, a check is made to see if they are macros
- * which are then expanded.
- * ----------------------------------------------------------------------------- */
-
-/* #define SWIG_PUT_BUFF */
-
-static DOH *Preprocessor_replace(DOH *s) {
- DOH *ns, *symbols, *m;
- int c, i, state = 0;
- String *id = NewStringEmpty();
-
- assert(cpp);
- symbols = Getattr(cpp, kpp_symbols);
-
- ns = NewStringEmpty();
- copy_location(s, ns);
- Seek(s, 0, SEEK_SET);
-
- /* Try to locate identifiers in s and replace them with macro replacements */
- while ((c = Getc(s)) != EOF) {
- switch (state) {
- case 0:
- if (isidentifier(c)) {
- Clear(id);
- Putc(c, id);
- state = 4;
- } else if (c == '%') {
- Clear(id);
- Putc(c, id);
- state = 2;
- } else if (c == '#') {
- Clear(id);
- Putc(c, id);
- state = 4;
- } else if (c == '\"') {
- Putc(c, ns);
- skip_tochar(s, '\"', ns);
- } else if (c == '\'') {
- Putc(c, ns);
- skip_tochar(s, '\'', ns);
- } else if (c == '/') {
- Putc(c, ns);
- state = 10;
- } else if (c == '\\') {
- Putc(c, ns);
- c = Getc(s);
- if (c == '\n') {
- Putc(c, ns);
- } else {
- Ungetc(c, s);
- }
- } else if (c == '\n') {
- Putc(c, ns);
- expand_defined_operator = 0;
- } else {
- Putc(c, ns);
- }
- break;
- case 2:
- /* Found '%#' */
- if (c == '#') {
- Putc(c, id);
- state = 4;
- } else {
- Ungetc(c, s);
- state = 4;
- }
- break;
- case 4: /* An identifier */
- if (isidchar(c)) {
- Putc(c, id);
- state = 4;
- } else {
- /* We found the end of a valid identifier */
- Ungetc(c, s);
- /* See if this is the special "defined" operator */
- if (Equal(kpp_defined, id)) {
- if (expand_defined_operator) {
- int lenargs = 0;
- DOH *args = 0;
- /* See whether or not a parenthesis has been used */
- skip_whitespace(s, 0);
- c = Getc(s);
- if (c == '(') {
- Ungetc(c, s);
- args = find_args(s, 0, kpp_defined);
- } else if (isidchar(c)) {
- DOH *arg = NewStringEmpty();
- args = NewList();
- Putc(c, arg);
- while (((c = Getc(s)) != EOF)) {
- if (!isidchar(c)) {
- Ungetc(c, s);
- break;
- }
- Putc(c, arg);
- }
- if (Len(arg))
- Append(args, arg);
- Delete(arg);
- } else {
- Seek(s, -1, SEEK_CUR);
- }
- lenargs = Len(args);
- if ((!args) || (!lenargs)) {
- /* This is not a defined() operator. */
- Append(ns, id);
- state = 0;
- break;
- }
- for (i = 0; i < lenargs; i++) {
- DOH *o = Getitem(args, i);
- if (!Getattr(symbols, o)) {
- break;
- }
- }
- if (i < lenargs)
- Putc('0', ns);
- else
- Putc('1', ns);
- Delete(args);
- } else {
- Append(ns, id);
- }
- state = 0;
- break;
- } else if (Equal(kpp_LINE, id)) {
- Printf(ns, "%d", macro_level > 0 ? macro_start_line : Getline(s));
- state = 0;
- break;
- } else if (Equal(kpp_FILE, id)) {
- String *fn = Copy(macro_level > 0 ? macro_start_file : Getfile(s));
- Replaceall(fn, "\\", "\\\\");
- Printf(ns, "\"%s\"", fn);
- Delete(fn);
- state = 0;
- break;
- } else if (Equal(kpp_hash_if, id) || Equal(kpp_hash_elif, id)) {
- expand_defined_operator = 1;
- Append(ns, id);
- /*
- } else if (Equal("%#if", id) || Equal("%#ifdef", id)) {
- Swig_warning(998, Getfile(s), Getline(s), "Found: %s preprocessor directive.\n", id);
- Append(ns, id);
- } else if (Equal("#ifdef", id) || Equal("#ifndef", id)) {
- Swig_warning(998, Getfile(s), Getline(s), "The %s preprocessor directive does not work in macros, try #if instead.\n", id);
- Append(ns, id);
- */
- } else if ((m = Getattr(symbols, id))) {
- /* See if the macro is defined in the preprocessor symbol table */
- DOH *args = 0;
- DOH *e;
- int macro_additional_lines = 0;
- /* See if the macro expects arguments */
- if (Getattr(m, kpp_args)) {
- /* Yep. We need to go find the arguments and do a substitution */
- int line = Getline(s);
- args = find_args(s, 1, id);
- macro_additional_lines = Getline(s) - line;
- assert(macro_additional_lines >= 0);
- } else {
- args = 0;
- }
- e = expand_macro(id, args, s);
- if (e) {
- Append(ns, e);
- }
- while (macro_additional_lines--) {
- Putc('\n', ns);
- }
- Delete(e);
- Delete(args);
- } else {
- Append(ns, id);
- }
- state = 0;
- }
- break;
- case 10:
- if (c == '/')
- state = 11;
- else if (c == '*')
- state = 12;
- else {
- Ungetc(c, s);
- state = 0;
- break;
- }
- Putc(c, ns);
- break;
- case 11:
- /* in C++ comment */
- Putc(c, ns);
- if (c == '\n') {
- expand_defined_operator = 0;
- state = 0;
- }
- break;
- case 12:
- /* in C comment */
- Putc(c, ns);
- if (c == '*')
- state = 13;
- break;
- case 13:
- Putc(c, ns);
- if (c == '/')
- state = 0;
- else if (c != '*')
- state = 12;
- break;
- default:
- state = 0;
- break;
- }
- }
-
- /* Identifier at the end */
- if (state == 2 || state == 4) {
- /* See if this is the special "defined" operator */
- if (Equal(kpp_defined, id)) {
- Swig_error(Getfile(s), Getline(s), "No arguments given to defined()\n");
- } else if (Equal(kpp_LINE, id)) {
- Printf(ns, "%d", macro_level > 0 ? macro_start_line : Getline(s));
- } else if (Equal(kpp_FILE, id)) {
- String *fn = Copy(macro_level > 0 ? macro_start_file : Getfile(s));
- Replaceall(fn, "\\", "\\\\");
- Printf(ns, "\"%s\"", fn);
- Delete(fn);
- } else if (Getattr(symbols, id)) {
- DOH *e;
- /* Yes. There is a macro here */
- /* See if the macro expects arguments */
- e = expand_macro(id, 0, s);
- if (e)
- Append(ns, e);
- Delete(e);
- } else {
- Append(ns, id);
- }
- }
- Delete(id);
- return ns;
-}
-
-
-/* -----------------------------------------------------------------------------
- * int checkpp_id(DOH *s)
- *
- * Checks the string s to see if it contains any unresolved identifiers. This
- * function contains the heuristic that determines whether or not a macro
- * definition passes through the preprocessor as a constant declaration.
- * ----------------------------------------------------------------------------- */
-static int checkpp_id(DOH *s) {
- int c;
- int hastok = 0;
- Scanner *scan = id_scan;
-
- Seek(s, 0, SEEK_SET);
-
- Scanner_clear(scan);
- s = Copy(s);
- Seek(s, SEEK_SET, 0);
- Scanner_push(scan, s);
- while ((c = Scanner_token(scan))) {
- hastok = 1;
- if ((c == SWIG_TOKEN_ID) || (c == SWIG_TOKEN_LBRACE) || (c == SWIG_TOKEN_RBRACE))
- return 1;
- }
- if (!hastok)
- return 1;
- return 0;
-}
-
-/* addline(). Utility function for adding lines to a chunk */
-static void addline(DOH *s1, DOH *s2, int allow) {
- if (allow) {
- Append(s1, s2);
- } else {
- char *c = Char(s2);
- while (*c) {
- if (*c == '\n')
- Putc('\n', s1);
- c++;
- }
- }
-}
-
-static void add_chunk(DOH *ns, DOH *chunk, int allow) {
- DOH *echunk;
- Seek(chunk, 0, SEEK_SET);
- if (allow) {
- echunk = Preprocessor_replace(chunk);
- addline(ns, echunk, allow);
- Delete(echunk);
- } else {
- addline(ns, chunk, 0);
- }
- Clear(chunk);
-}
-
-/*
- push/pop_imported(): helper functions for defining and undefining
- SWIGIMPORTED (when %importing a file).
- */
-static void push_imported(void) {
- if (imported_depth == 0) {
- Preprocessor_define("SWIGIMPORTED 1", 0);
- }
- ++imported_depth;
-}
-
-static void pop_imported(void) {
- --imported_depth;
- if (imported_depth == 0) {
- Preprocessor_undef("SWIGIMPORTED");
- }
-}
-
-
-/* -----------------------------------------------------------------------------
- * Preprocessor_parse()
- *
- * Parses the string s. Returns a new string containing the preprocessed version.
- *
- * Parsing rules :
- * 1. Lines starting with # are C preprocessor directives
- * 2. Macro expansion inside strings is not allowed
- * 3. All code inside false conditionals is changed to blank lines
- * 4. Code in %{, %} is not parsed because it may need to be
- * included inline (with all preprocessor directives included).
- * ----------------------------------------------------------------------------- */
-
-String *Preprocessor_parse(String *s) {
- String *ns; /* New string containing the preprocessed text */
- String *chunk, *decl;
- Hash *symbols;
- String *id = 0, *value = 0, *comment = 0;
- int i, state, e, c;
- int start_line = 0;
- int allow = 1;
- int level = 0;
- int dlevel = 0;
- int filelevel = 0;
- int mask = 0;
- int start_level = 0;
- int cpp_lines = 0;
- int cond_lines[256];
-
- /* Blow away all carriage returns */
- Replace(s, "\015", "", DOH_REPLACE_ANY);
-
- ns = NewStringEmpty(); /* Return result */
-
- decl = NewStringEmpty();
- id = NewStringEmpty();
- value = NewStringEmpty();
- comment = NewStringEmpty();
- chunk = NewStringEmpty();
- copy_location(s, chunk);
- copy_location(s, ns);
- symbols = Getattr(cpp, kpp_symbols);
-
- state = 0;
- while ((c = Getc(s)) != EOF) {
- switch (state) {
- case 0: /* Initial state - in first column */
- /* Look for C preprocessor directives. Otherwise, go directly to state 1 */
- if (c == '#') {
- copy_location(s, chunk);
- add_chunk(ns, chunk, allow);
- cpp_lines = 1;
- state = 40;
- } else if (isspace(c)) {
- Putc(c, chunk);
- skip_whitespace(s, chunk);
- } else {
- state = 1;
- Ungetc(c, s);
- }
- break;
- case 1: /* Non-preprocessor directive */
- /* Look for SWIG directives */
- if (c == '%') {
- state = 100;
- break;
- }
- Putc(c, chunk);
- if (c == '\n')
- state = 0;
- else if (c == '\"') {
- start_line = Getline(s);
- if (skip_tochar(s, '\"', chunk) < 0) {
- Swig_error(Getfile(s), start_line, "Unterminated string constant\n");
- }
- } else if (c == '\'') {
- start_line = Getline(s);
- if (skip_tochar(s, '\'', chunk) < 0) {
- Swig_error(Getfile(s), start_line, "Unterminated character constant\n");
- }
- } else if (c == '/')
- state = 30; /* Comment */
- break;
-
- case 30: /* Possibly a comment string of some sort */
- start_line = Getline(s);
- Putc(c, chunk);
- if (c == '/')
- state = 31;
- else if (c == '*')
- state = 32;
- else
- state = 1;
- break;
- case 31:
- Putc(c, chunk);
- if (c == '\n')
- state = 0;
- break;
- case 32:
- Putc(c, chunk);
- if (c == '*')
- state = 33;
- break;
- case 33:
- Putc(c, chunk);
- if (c == '/')
- state = 1;
- else if (c != '*')
- state = 32;
- break;
-
- case 40: /* Start of a C preprocessor directive */
- if (c == '\n') {
- Putc('\n', chunk);
- state = 0;
- } else if (isspace(c)) {
- state = 40;
- } else {
- /* Got the start of a preprocessor directive */
- Ungetc(c, s);
- Clear(id);
- copy_location(s, id);
- state = 41;
- }
- break;
-
- case 41: /* Build up the name of the preprocessor directive */
- if ((isspace(c) || (!isidchar(c)))) {
- Clear(value);
- Clear(comment);
- if (c == '\n') {
- Ungetc(c, s);
- state = 50;
- } else {
- state = 42;
- if (!isspace(c)) {
- Ungetc(c, s);
- }
- }
-
- copy_location(s, value);
- break;
- }
- Putc(c, id);
- break;
-
- case 42: /* Strip any leading space after the preprocessor directive (before preprocessor value) */
- if (isspace(c)) {
- if (c == '\n') {
- Ungetc(c, s);
- state = 50;
- }
- break;
- }
- state = 43;
- /* FALL THRU */
-
- case 43:
- /* Get preprocessor value */
- if (c == '\n') {
- Ungetc(c, s);
- state = 50;
- } else if (c == '/') {
- state = 45;
- } else if (c == '\"') {
- Putc(c, value);
- skip_tochar(s, '\"', value);
- } else if (c == '\'') {
- Putc(c, value);
- skip_tochar(s, '\'', value);
- } else {
- Putc(c, value);
- if (c == '\\')
- state = 44;
- }
- break;
-
- case 44:
- if (c == '\n') {
- Putc(c, value);
- cpp_lines++;
- } else {
- Ungetc(c, s);
- }
- state = 43;
- break;
-
- /* States 45-48 are used to remove, but retain comments from macro values. The comments
- will be placed in the output in an alternative form */
-
- case 45:
- if (c == '/')
- state = 46;
- else if (c == '*')
- state = 47;
- else if (c == '\n') {
- Putc('/', value);
- Ungetc(c, s);
- state = 50;
- } else {
- Putc('/', value);
- Putc(c, value);
- state = 43;
- }
- break;
- case 46: /* in C++ comment */
- if (c == '\n') {
- Ungetc(c, s);
- state = 50;
- } else
- Putc(c, comment);
- break;
- case 47: /* in C comment */
- if (c == '*')
- state = 48;
- else
- Putc(c, comment);
- break;
- case 48:
- if (c == '/')
- state = 43;
- else if (c == '*')
- Putc(c, comment);
- else {
- Putc('*', comment);
- Putc(c, comment);
- state = 47;
- }
- break;
- case 50:
- /* Check for various preprocessor directives */
- Chop(value);
- if (Equal(id, kpp_define)) {
- if (allow) {
- DOH *m, *v, *v1;
- Seek(value, 0, SEEK_SET);
- m = Preprocessor_define(value, 0);
- if ((m) && !(Getattr(m, kpp_args))) {
- v = Copy(Getattr(m, kpp_value));
- copy_location(m, v);
- if (Len(v)) {
- Swig_error_silent(1);
- v1 = Preprocessor_replace(v);
- Swig_error_silent(0);
- /* Printf(stdout,"checking '%s'\n", v1); */
- if (!checkpp_id(v1)) {
- if (Len(comment) == 0)
- Printf(ns, "%%constant %s = %s;\n", Getattr(m, kpp_name), v1);
- else
- Printf(ns, "%%constant %s = %s; /*%s*/\n", Getattr(m, kpp_name), v1, comment);
- cpp_lines--;
- }
- Delete(v1);
- }
- Delete(v);
- }
- }
- } else if (Equal(id, kpp_undef)) {
- if (allow)
- Preprocessor_undef(value);
- } else if (Equal(id, kpp_ifdef)) {
- cond_lines[level] = Getline(id);
- level++;
- if (allow) {
- start_level = level;
- if (Len(value) > 0) {
- /* See if the identifier is in the hash table */
- if (!Getattr(symbols, value))
- allow = 0;
- } else {
- Swig_error(Getfile(s), Getline(id), "Missing identifier for #ifdef.\n");
- allow = 0;
- }
- mask = 1;
- }
- } else if (Equal(id, kpp_ifndef)) {
- cond_lines[level] = Getline(id);
- level++;
- if (allow) {
- start_level = level;
- if (Len(value) > 0) {
- /* See if the identifier is in the hash table */
- if (Getattr(symbols, value))
- allow = 0;
- } else {
- Swig_error(Getfile(s), Getline(id), "Missing identifier for #ifndef.\n");
- allow = 0;
- }
- mask = 1;
- }
- } else if (Equal(id, kpp_else)) {
- if (level <= 0) {
- Swig_error(Getfile(s), Getline(id), "Misplaced #else.\n");
- } else {
- cond_lines[level - 1] = Getline(id);
- if (Len(value) != 0)
- Swig_warning(WARN_PP_UNEXPECTED_TOKENS, Getfile(s), Getline(id), "Unexpected tokens after #else directive.\n");
- if (allow) {
- allow = 0;
- mask = 0;
- } else if (level == start_level) {
- allow = 1 * mask;
- }
- }
- } else if (Equal(id, kpp_endif)) {
- level--;
- if (level < 0) {
- Swig_error(Getfile(id), Getline(id), "Extraneous #endif.\n");
- level = 0;
- } else {
- if (level < start_level) {
- if (Len(value) != 0)
- Swig_warning(WARN_PP_UNEXPECTED_TOKENS, Getfile(s), Getline(id), "Unexpected tokens after #endif directive.\n");
- allow = 1;
- start_level--;
- }
- }
- } else if (Equal(id, kpp_if)) {
- cond_lines[level] = Getline(id);
- level++;
- if (allow) {
- int val;
- String *sval;
- expand_defined_operator = 1;
- sval = Preprocessor_replace(value);
- start_level = level;
- Seek(sval, 0, SEEK_SET);
- /* Printf(stdout,"Evaluating '%s'\n", sval); */
- if (Len(sval) > 0) {
- val = Preprocessor_expr(sval, &e);
- if (e) {
- const char *msg = Preprocessor_expr_error();
- Seek(value, 0, SEEK_SET);
- Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "Could not evaluate expression '%s'\n", value);
- if (msg)
- Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "%s\n", msg);
- allow = 0;
- } else {
- if (val == 0)
- allow = 0;
- }
- } else {
- Swig_error(Getfile(s), Getline(id), "Missing expression for #if.\n");
- allow = 0;
- }
- expand_defined_operator = 0;
- mask = 1;
- }
- } else if (Equal(id, kpp_elif)) {
- if (level == 0) {
- Swig_error(Getfile(s), Getline(id), "Misplaced #elif.\n");
- } else {
- cond_lines[level - 1] = Getline(id);
- if (allow) {
- allow = 0;
- mask = 0;
- } else if (level == start_level) {
- int val;
- String *sval;
- expand_defined_operator = 1;
- sval = Preprocessor_replace(value);
- Seek(sval, 0, SEEK_SET);
- if (Len(sval) > 0) {
- val = Preprocessor_expr(sval, &e);
- if (e) {
- const char *msg = Preprocessor_expr_error();
- Seek(value, 0, SEEK_SET);
- Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "Could not evaluate expression '%s'\n", value);
- if (msg)
- Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "%s\n", msg);
- allow = 0;
- } else {
- if (val)
- allow = 1 * mask;
- else
- allow = 0;
- }
- } else {
- Swig_error(Getfile(s), Getline(id), "Missing expression for #elif.\n");
- allow = 0;
- }
- expand_defined_operator = 0;
- }
- }
- } else if (Equal(id, kpp_warning)) {
- if (allow) {
- Swig_warning(WARN_PP_CPP_WARNING, Getfile(s), Getline(id), "CPP #warning, \"%s\".\n", value);
- }
- } else if (Equal(id, kpp_error)) {
- if (allow) {
- if (error_as_warning) {
- Swig_warning(WARN_PP_CPP_ERROR, Getfile(s), Getline(id), "CPP #error \"%s\".\n", value);
- } else {
- Swig_error(Getfile(s), Getline(id), "CPP #error \"%s\". Use the -cpperraswarn option to continue swig processing.\n", value);
- }
- }
- } else if (Equal(id, kpp_line)) {
- } else if (Equal(id, kpp_include)) {
- if (((include_all) || (import_all)) && (allow)) {
- String *s1, *s2, *fn;
- String *dirname;
- int sysfile = 0;
- if (include_all && import_all) {
- Swig_warning(WARN_PP_INCLUDEALL_IMPORTALL, Getfile(s), Getline(id), "Both includeall and importall are defined: using includeall.\n");
- import_all = 0;
- }
- Seek(value, 0, SEEK_SET);
- fn = get_filename(value, &sysfile);
- s1 = cpp_include(fn, sysfile);
- if (s1) {
- if (include_all)
- Printf(ns, "%%includefile \"%s\" %%beginfile\n", Swig_filename_escape(Swig_last_file()));
- else if (import_all) {
- Printf(ns, "%%importfile \"%s\" %%beginfile\n", Swig_filename_escape(Swig_last_file()));
- push_imported();
- }
-
- /* See if the filename has a directory component */
- dirname = Swig_file_dirname(Swig_last_file());
- if (sysfile || !Len(dirname)) {
- Delete(dirname);
- dirname = 0;
- }
- if (dirname) {
- int len = Len(dirname);
- Delslice(dirname, len - 1, len); /* Kill trailing directory delimiter */
- Swig_push_directory(dirname);
- }
- s2 = Preprocessor_parse(s1);
- addline(ns, s2, allow);
- Append(ns, "%endoffile");
- if (dirname) {
- Swig_pop_directory();
- }
- if (import_all) {
- pop_imported();
- }
- Delete(s2);
- Delete(dirname);
- Delete(s1);
- }
- Delete(fn);
- }
- } else if (Equal(id, kpp_pragma)) {
- if (Strncmp(value, "SWIG ", 5) == 0) {
- char *c = Char(value) + 5;
- while (*c && (isspace((int) *c)))
- c++;
- if (*c) {
- if (strncmp(c, "nowarn=", 7) == 0) {
- String *val = NewString(c + 7);
- String *nowarn = Preprocessor_replace(val);
- Swig_warnfilter(nowarn, 1);
- Delete(nowarn);
- Delete(val);
- } else if (strncmp(c, "cpperraswarn=", 13) == 0) {
- error_as_warning = atoi(c + 13);
- } else {
- Swig_error(Getfile(s), Getline(id), "Unknown SWIG pragma: %s\n", c);
- }
- }
- }
- } else if (Equal(id, kpp_level)) {
- Swig_error(Getfile(s), Getline(id), "cpp debug: level = %d, startlevel = %d\n", level, start_level);
- } else if (Equal(id, "")) {
- /* Null directive */
- } else if (is_digits(id)) {
- /* A gcc linemarker of the form '# linenum filename flags' (resulting from running gcc -E) */
- } else {
- /* Ignore unknown preprocessor directives which are inside an inactive
- * conditional (github issue #394). */
- if (allow)
- Swig_error(Getfile(s), Getline(id), "Unknown SWIG preprocessor directive: %s (if this is a block of target language code, delimit it with %%{ and %%})\n", id);
- }
- for (i = 0; i < cpp_lines; i++)
- Putc('\n', ns);
- state = 0;
- break;
-
- /* SWIG directives */
- case 100:
- /* %{,%} block */
- if (c == '{') {
- start_line = Getline(s);
- copy_location(s, chunk);
- add_chunk(ns, chunk, allow);
- Putc('%', chunk);
- Putc(c, chunk);
- state = 105;
- }
- /* %#cpp - an embedded C preprocessor directive (we strip off the %) */
- else if (c == '#') {
- add_chunk(ns, chunk, allow);
- Putc(c, chunk);
- state = 107;
- } else if (isidentifier(c)) {
- Clear(decl);
- Putc('%', decl);
- Putc(c, decl);
- state = 110;
- } else {
- Putc('%', chunk);
- Putc(c, chunk);
- state = 1;
- }
- break;
-
- case 105:
- Putc(c, chunk);
- if (c == '%')
- state = 106;
- break;
-
- case 106:
- Putc(c, chunk);
- if (c == '}') {
- state = 1;
- addline(ns, chunk, allow);
- Clear(chunk);
- copy_location(s, chunk);
- } else {
- state = 105;
- }
- break;
-
- case 107:
- Putc(c, chunk);
- if (c == '\n') {
- addline(ns, chunk, allow);
- Clear(chunk);
- state = 0;
- } else if (c == '\\') {
- state = 108;
- }
- break;
-
- case 108:
- Putc(c, chunk);
- state = 107;
- break;
-
- case 110:
- if (!isidchar(c)) {
- Ungetc(c, s);
- /* Look for common SWIG directives */
- if (Equal(decl, kpp_dinclude) || Equal(decl, kpp_dimport) || Equal(decl, kpp_dextern)) {
- /* Got some kind of file inclusion directive, eg: %import(option1="value1") "filename" */
- if (allow) {
- DOH *s1, *s2, *fn, *opt;
- String *options_whitespace = NewStringEmpty();
- String *filename_whitespace = NewStringEmpty();
- int sysfile = 0;
-
- if (Equal(decl, kpp_dextern)) {
- Swig_warning(WARN_DEPRECATED_EXTERN, Getfile(s), Getline(s), "%%extern is deprecated. Use %%import instead.\n");
- Clear(decl);
- Append(decl, "%%import");
- }
- skip_whitespace(s, options_whitespace);
- opt = get_options(s);
-
- skip_whitespace(s, filename_whitespace);
- fn = get_filename(s, &sysfile);
- s1 = cpp_include(fn, sysfile);
- if (s1) {
- String *dirname;
- copy_location(s, chunk);
- add_chunk(ns, chunk, allow);
- Printf(ns, "%sfile%s%s%s\"%s\" %%beginfile\n", decl, options_whitespace, opt, filename_whitespace, Swig_filename_escape(Swig_last_file()));
- if (Equal(decl, kpp_dimport)) {
- push_imported();
- }
- dirname = Swig_file_dirname(Swig_last_file());
- if (sysfile || !Len(dirname)) {
- Delete(dirname);
- dirname = 0;
- }
- if (dirname) {
- int len = Len(dirname);
- Delslice(dirname, len - 1, len); /* Kill trailing directory delimiter */
- Swig_push_directory(dirname);
- }
- s2 = Preprocessor_parse(s1);
- if (dirname) {
- Swig_pop_directory();
- }
- if (Equal(decl, kpp_dimport)) {
- pop_imported();
- }
- addline(ns, s2, allow);
- Append(ns, "%endoffile");
- Delete(s2);
- Delete(dirname);
- Delete(s1);
- }
- Delete(fn);
- Delete(filename_whitespace);
- Delete(options_whitespace);
- }
- state = 1;
- } else if (Equal(decl, kpp_dbeginfile)) {
- /* Got an internal directive marking the beginning of an included file: %beginfile ... %endoffile */
- filelevel++;
- start_line = Getline(s);
- copy_location(s, chunk);
- add_chunk(ns, chunk, allow);
- Append(chunk, decl);
- state = 120;
- } else if (Equal(decl, kpp_dline)) {
- /* Got a line directive */
- state = 1;
- } else if (Equal(decl, kpp_ddefine)) {
- /* Got a define directive */
- dlevel++;
- copy_location(s, chunk);
- add_chunk(ns, chunk, allow);
- Clear(value);
- copy_location(s, value);
- state = 150;
- } else {
- Append(chunk, decl);
- state = 1;
- }
- } else {
- Putc(c, decl);
- }
- break;
-
- /* Searching for the end of a %beginfile block */
- case 120:
- Putc(c, chunk);
- if (c == '%') {
- const char *bf = "beginfile";
- const char *ef = "endoffile";
- char statement[10];
- int i = 0;
- for (i = 0; i < 9;) {
- c = Getc(s);
- Putc(c, chunk);
- statement[i++] = (char)c;
- if (strncmp(statement, bf, i) && strncmp(statement, ef, i))
- break;
- }
- c = Getc(s);
- Ungetc(c, s);
- if ((i == 9) && (isspace(c))) {
- if (strncmp(statement, bf, i) == 0) {
- ++filelevel;
- } else if (strncmp(statement, ef, i) == 0) {
- --filelevel;
- if (!filelevel) {
- /* Reached end of included file */
- addline(ns, chunk, allow);
- Clear(chunk);
- copy_location(s, chunk);
- state = 1;
- }
- }
- }
- }
- break;
-
- /* Searching for the end of a %define statement */
- case 150:
- Putc(c, value);
- if (c == '%') {
- const char *ed = "enddef";
- const char *df = "define";
- char statement[7];
- int i = 0;
- for (i = 0; i < 6;) {
- c = Getc(s);
- Putc(c, value);
- statement[i++] = (char)c;
- if (strncmp(statement, ed, i) && strncmp(statement, df, i))
- break;
- }
- c = Getc(s);
- Ungetc(c, s);
- if ((i == 6) && (isspace(c))) {
- if (strncmp(statement, df, i) == 0) {
- ++dlevel;
- } else {
- if (strncmp(statement, ed, i) == 0) {
- --dlevel;
- if (!dlevel) {
- /* Got the macro */
- for (i = 0; i < 7; i++) {
- Delitem(value, DOH_END);
- }
- if (allow) {
- Seek(value, 0, SEEK_SET);
- Preprocessor_define(value, 1);
- }
- addline(ns, value, 0);
- state = 0;
- }
- }
- }
- }
- }
- break;
- default:
- Printf(stderr, "cpp: Invalid parser state %d\n", state);
- Exit(EXIT_FAILURE);
- }
- }
- while (level > 0) {
- Swig_error(Getfile(s), cond_lines[level - 1], "Missing #endif for conditional starting here\n");
- level--;
- }
- if (state == 120) {
- Swig_error(Getfile(s), start_line, "Missing %%endoffile for file inclusion block starting here\n");
- }
- if (state == 150) {
- Seek(value, 0, SEEK_SET);
- Swig_error(Getfile(s), Getline(value), "Missing %%enddef for macro starting here\n", Getline(value));
- }
- if ((state >= 105) && (state < 107)) {
- Swig_error(Getfile(s), start_line, "Unterminated %%{ ... %%} block\n");
- }
- if ((state >= 30) && (state < 40)) {
- Swig_error(Getfile(s), start_line, "Unterminated comment\n");
- }
-
- copy_location(s, chunk);
- add_chunk(ns, chunk, allow);
-
- /* DelScope(scp); */
- Delete(decl);
- Delete(id);
- Delete(value);
- Delete(comment);
- Delete(chunk);
-
- return ns;
-}
diff --git a/contrib/tools/swig/Source/Preprocessor/expr.c b/contrib/tools/swig/Source/Preprocessor/expr.c
deleted file mode 100644
index 95e05cf562..0000000000
--- a/contrib/tools/swig/Source/Preprocessor/expr.c
+++ /dev/null
@@ -1,496 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * expr.c
- *
- * Integer arithmetic expression evaluator used to handle expressions
- * encountered during preprocessing.
- *
- * Note that this is used for expressions in `#if` and the like, but not
- * for expressions in `#define` which SWIG wraps as constants - for those
- * we inject a `%constant` directive which is handled by the parser in
- * `Source/CParse/parser.y`.
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-#include "preprocessor.h"
-
-static Scanner *scan = 0;
-
-typedef struct {
- /* One of the EXPR_xxx values defined below. */
- int op;
- /* op == EXPR_OP: value is the token specifying which operator.
- *
- * op == EXPR_VALUE && svalue == NULL: Numeric expression value.
- *
- * Otherwise unused.
- */
- long value;
- /* op == EXPR_VALUE: If non-NULL, string expression value; if NULL see value.
- *
- * Otherwise unused.
- */
- String *svalue;
-} exprval;
-
-#define EXPR_TOP 1
-#define EXPR_VALUE 2
-#define EXPR_OP 3
-#define EXPR_GROUP 4
-
-/* Special token values used here to distinguish from SWIG_TOKEN_MINUS
- * and SWIG_TOKEN_PLUS (which we use here for a two argument versions).
- */
-#define OP_UMINUS 100
-#define OP_UPLUS 101
-
-static exprval stack[256]; /* Parsing stack */
-static int sp = 0; /* Stack pointer */
-static int prec[256]; /* Precedence rules */
-static int expr_init = 0; /* Initialization flag */
-static const char *errmsg = 0; /* Parsing error */
-
-/* Initialize the precedence table for various operators. Low values have higher precedence */
-static void init_precedence(void) {
- prec[SWIG_TOKEN_NOT] = 10;
- prec[SWIG_TOKEN_LNOT] = 10;
- prec[OP_UMINUS] = 10;
- prec[OP_UPLUS] = 10;
- prec[SWIG_TOKEN_STAR] = 20;
- prec[SWIG_TOKEN_SLASH] = 20;
- prec[SWIG_TOKEN_PERCENT] = 20;
- prec[SWIG_TOKEN_PLUS] = 30;
- prec[SWIG_TOKEN_MINUS] = 30;
- prec[SWIG_TOKEN_LSHIFT] = 40;
- prec[SWIG_TOKEN_RSHIFT] = 40;
- prec[SWIG_TOKEN_LESSTHAN] = 50;
- prec[SWIG_TOKEN_GREATERTHAN] = 50;
- prec[SWIG_TOKEN_LTEQUAL] = 50;
- prec[SWIG_TOKEN_GTEQUAL] = 50;
- prec[SWIG_TOKEN_EQUALTO] = 60;
- prec[SWIG_TOKEN_NOTEQUAL] = 60;
- prec[SWIG_TOKEN_AND] = 70;
- prec[SWIG_TOKEN_XOR] = 80;
- prec[SWIG_TOKEN_OR] = 90;
- prec[SWIG_TOKEN_LAND] = 100;
- prec[SWIG_TOKEN_LOR] = 110;
- expr_init = 1;
-}
-
-#define UNARY_OP(token) (((token) == SWIG_TOKEN_NOT) || \
- ((token) == SWIG_TOKEN_LNOT) || \
- ((token) == OP_UMINUS) || \
- ((token) == OP_UPLUS))
-
-/* Reduce a single operator on the stack */
-/* return 0 on failure, 1 on success */
-static int reduce_op(void) {
- long op_token = stack[sp - 1].value;
- assert(sp > 0);
- assert(stack[sp - 1].op == EXPR_OP);
- /* do some basic checking first: */
- if (stack[sp].op != EXPR_VALUE) {
- errmsg = "Right-hand side is not value";
- return 0;
- }
- if (UNARY_OP(op_token)) {
- if (stack[sp].svalue) {
- errmsg = "Syntax error: attempt to apply unary operator to string";
- return 0;
- }
- } else {
- /* binary operator: */
- if (sp == 1) {
- /* top of stack: don't attempt to use sp-2! */
- errmsg = "Missing left-hand side for binary operator";
- return 0;
- }
- if (stack[sp].op != EXPR_VALUE) {
- errmsg = "Left-hand side of binary operator is not a value";
- return 0;
- }
- if ((!stack[sp - 2].svalue) != (!stack[sp].svalue)) {
- errmsg = "Can't mix strings and integers in expression";
- return 0;
- }
- }
- if (stack[sp].svalue) {
- /* A binary string expression */
- switch (stack[sp - 1].value) {
- case SWIG_TOKEN_EQUALTO:
- stack[sp - 2].value = (Strcmp(stack[sp - 2].svalue, stack[sp].svalue) == 0);
- Delete(stack[sp - 2].svalue);
- Delete(stack[sp].svalue);
- sp -= 2;
- break;
- case SWIG_TOKEN_NOTEQUAL:
- stack[sp - 2].value = (Strcmp(stack[sp - 2].svalue, stack[sp].svalue) != 0);
- Delete(stack[sp - 2].svalue);
- Delete(stack[sp].svalue);
- sp -= 2;
- break;
- default:
- errmsg = "Syntax error: bad binary operator for strings";
- return 0;
- break;
- }
- } else {
- switch (op_token) {
- case SWIG_TOKEN_STAR:
- stack[sp - 2].value = stack[sp - 2].value * stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_EQUALTO:
- stack[sp - 2].value = stack[sp - 2].value == stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_NOTEQUAL:
- stack[sp - 2].value = stack[sp - 2].value != stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_PLUS:
- stack[sp - 2].value = stack[sp - 2].value + stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_MINUS:
- stack[sp - 2].value = stack[sp - 2].value - stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_AND:
- stack[sp - 2].value = stack[sp - 2].value & stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_LAND:
- stack[sp - 2].value = stack[sp - 2].value && stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_OR:
- stack[sp - 2].value = stack[sp - 2].value | stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_LOR:
- stack[sp - 2].value = stack[sp - 2].value || stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_XOR:
- stack[sp - 2].value = stack[sp - 2].value ^ stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_LESSTHAN:
- stack[sp - 2].value = stack[sp - 2].value < stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_GREATERTHAN:
- stack[sp - 2].value = stack[sp - 2].value > stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_LTEQUAL:
- stack[sp - 2].value = stack[sp - 2].value <= stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_GTEQUAL:
- stack[sp - 2].value = stack[sp - 2].value >= stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_NOT:
- stack[sp - 1].value = ~stack[sp].value;
- sp--;
- break;
- case SWIG_TOKEN_LNOT:
- stack[sp - 1].value = !stack[sp].value;
- sp--;
- break;
- case OP_UMINUS:
- stack[sp - 1].value = -stack[sp].value;
- sp--;
- break;
- case OP_UPLUS:
- stack[sp - 1].value = stack[sp].value;
- sp--;
- break;
- case SWIG_TOKEN_SLASH:
- if (stack[sp].value != 0) {
- stack[sp - 2].value = stack[sp - 2].value / stack[sp].value;
- sp -= 2;
- } else {
- errmsg = "Division by zero in expression";
- return 0;
- }
- break;
- case SWIG_TOKEN_PERCENT:
- if (stack[sp].value != 0) {
- stack[sp - 2].value = stack[sp - 2].value % stack[sp].value;
- sp -= 2;
- } else {
- errmsg = "Modulo by zero in expression";
- return 0;
- }
- break;
- case SWIG_TOKEN_LSHIFT:
- stack[sp - 2].value = stack[sp - 2].value << stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_RSHIFT:
- stack[sp - 2].value = stack[sp - 2].value >> stack[sp].value;
- sp -= 2;
- break;
- default:
- errmsg = "Syntax error: bad operator";
- return 0;
- break;
- }
- }
- stack[sp].op = EXPR_VALUE;
- stack[sp].svalue = 0; /* ensure it's not a string! */
- return 1;
-}
-
-/* -----------------------------------------------------------------------------
- * Preprocessor_expr_init()
- *
- * Initialize the expression evaluator
- * ----------------------------------------------------------------------------- */
-
-void Preprocessor_expr_init(void) {
- if (!expr_init)
- init_precedence();
- if (!scan)
- scan = NewScanner();
-}
-
-void Preprocessor_expr_delete(void) {
- DelScanner(scan);
-}
-
-
-/* -----------------------------------------------------------------------------
- * Tokenizer
- * ----------------------------------------------------------------------------- */
-
-static int expr_token(Scanner * s) {
- int t;
- while (1) {
- t = Scanner_token(s);
- if (!((t == SWIG_TOKEN_BACKSLASH) || (t == SWIG_TOKEN_ENDLINE) || (t == SWIG_TOKEN_COMMENT)))
- break;
- }
- return t;
-}
-
-/* -----------------------------------------------------------------------------
- * Preprocessor_expr()
- *
- * Evaluates an arithmetic expression. Returns the result and sets an error code.
- * ----------------------------------------------------------------------------- */
-
-int Preprocessor_expr(DOH *s, int *error) {
- int token = 0;
- int op = 0;
-
- sp = 0;
- assert(s);
- assert(scan);
-
- Seek(s, 0, SEEK_SET);
- /* Printf(stdout,"evaluating : '%s'\n", s); */
- *error = 0;
- Scanner_clear(scan);
- Scanner_push(scan, s);
-
- /* Put initial state onto the stack */
- stack[sp].op = EXPR_TOP;
-
- while (1) {
- /* Look at the top of the stack */
- switch (stack[sp].op) {
- case EXPR_TOP:
- /* EXPR_TOP is a place-holder which can only appear on the top of the
- * stack. We can reduce it to any expression - a number, a string, an
- * unary operator, or another expression enclosed in parentheses.
- */
- token = expr_token(scan);
- if (!token) {
- errmsg = "Expected an expression";
- *error = 1;
- return 0;
- }
- if ((token == SWIG_TOKEN_INT) || (token == SWIG_TOKEN_UINT) || (token == SWIG_TOKEN_LONG) || (token == SWIG_TOKEN_ULONG)) {
- /* A number. Reduce EXPR_TOP to an EXPR_VALUE */
- char *c = Char(Scanner_text(scan));
- if (c[0] == '0' && (c[1] == 'b' || c[1] == 'B')) {
- /* strtol() doesn't handle binary constants */
- stack[sp].value = (long) strtol(c + 2, 0, 2);
- } else {
- stack[sp].value = (long) strtol(c, 0, 0);
- }
- stack[sp].svalue = 0;
- stack[sp].op = EXPR_VALUE;
- } else if ((token == SWIG_TOKEN_MINUS) || (token == SWIG_TOKEN_PLUS) || (token == SWIG_TOKEN_LNOT) || (token == SWIG_TOKEN_NOT)) {
- if (token == SWIG_TOKEN_MINUS)
- token = OP_UMINUS;
- else if (token == SWIG_TOKEN_PLUS)
- token = OP_UPLUS;
- stack[sp].value = token;
- stack[sp].op = EXPR_OP;
- sp++;
- stack[sp].op = EXPR_TOP;
- } else if (token == SWIG_TOKEN_LPAREN) {
- stack[sp].op = EXPR_GROUP;
- sp++;
- stack[sp].op = EXPR_TOP;
- } else if (token == SWIG_TOKEN_ENDLINE) {
- } else if (token == SWIG_TOKEN_STRING) {
- stack[sp].svalue = NewString(Scanner_text(scan));
- stack[sp].op = EXPR_VALUE;
- } else if (token == SWIG_TOKEN_ID) {
- /* Defined macros have been expanded already so this is an unknown
- * macro, which gets treated as zero.
- */
- stack[sp].value = 0;
- stack[sp].svalue = 0;
- stack[sp].op = EXPR_VALUE;
- } else if ((token == SWIG_TOKEN_FLOAT) || (token == SWIG_TOKEN_DOUBLE)) {
- errmsg = "Floating point constant in preprocessor expression";
- *error = 1;
- return 0;
- } else
- goto syntax_error;
- break;
- case EXPR_VALUE:
- /* A value is on top of the stack. We may reduce or evaluate depending
- * on what the next token is.
- */
- token = expr_token(scan);
- if (!token) {
- /* End of input. Might have to reduce if an operator is on stack */
- while (sp > 0) {
- if (stack[sp - 1].op == EXPR_OP) {
- if (!reduce_op())
- goto reduce_error;
- } else if (stack[sp - 1].op == EXPR_GROUP) {
- errmsg = "Missing \')\'";
- *error = 1;
- return 0;
- } else
- goto syntax_error;
- }
- return stack[sp].value;
- }
- /* Token must be an operator */
- switch (token) {
- case SWIG_TOKEN_STAR:
- case SWIG_TOKEN_EQUALTO:
- case SWIG_TOKEN_NOTEQUAL:
- case SWIG_TOKEN_PLUS:
- case SWIG_TOKEN_MINUS:
- case SWIG_TOKEN_AND:
- case SWIG_TOKEN_LAND:
- case SWIG_TOKEN_OR:
- case SWIG_TOKEN_LOR:
- case SWIG_TOKEN_XOR:
- case SWIG_TOKEN_LESSTHAN:
- case SWIG_TOKEN_GREATERTHAN:
- case SWIG_TOKEN_LTEQUAL:
- case SWIG_TOKEN_GTEQUAL:
- case SWIG_TOKEN_SLASH:
- case SWIG_TOKEN_PERCENT:
- case SWIG_TOKEN_LSHIFT:
- case SWIG_TOKEN_RSHIFT:
- if ((sp == 0) || (stack[sp - 1].op == EXPR_GROUP)) {
- /* No possibility of reduce. Push operator and expression */
- sp++;
- stack[sp].op = EXPR_OP;
- stack[sp].value = token;
- sp++;
- stack[sp].op = EXPR_TOP;
- } else {
- if (stack[sp - 1].op != EXPR_OP)
- goto syntax_error_expected_operator;
- op = stack[sp - 1].value; /* Previous operator */
-
- /* Now, depending on the precedence relationship between the last operator and the current
- we will reduce or push */
-
- if (prec[op] <= prec[token]) {
- /* Reduce the previous operator */
- if (!reduce_op())
- goto reduce_error;
- }
- sp++;
- stack[sp].op = EXPR_OP;
- stack[sp].value = token;
- sp++;
- stack[sp].op = EXPR_TOP;
- }
- break;
- case SWIG_TOKEN_RPAREN:
- if (sp == 0)
- goto extra_rparen;
-
- /* Might have to reduce operators first */
- while ((sp > 0) && (stack[sp - 1].op == EXPR_OP)) {
- if (!reduce_op())
- goto reduce_error;
- }
- if ((sp == 0) || (stack[sp - 1].op != EXPR_GROUP))
- goto extra_rparen;
- stack[sp - 1].op = EXPR_VALUE;
- stack[sp - 1].value = stack[sp].value;
- stack[sp - 1].svalue = stack[sp].svalue;
- sp--;
- break;
- case SWIG_TOKEN_LTEQUALGT:
- goto spaceship_not_allowed;
- default:
- goto syntax_error_expected_operator;
- break;
- }
- break;
-
- default:
- fprintf(stderr, "Internal error in expression evaluator.\n");
- Exit(EXIT_FAILURE);
- }
- }
-
-syntax_error:
- errmsg = "Syntax error";
- *error = 1;
- return 0;
-
-syntax_error_expected_operator:
- errmsg = "Syntax error: expected operator";
- *error = 1;
- return 0;
-
-reduce_error:
- /* errmsg has been set by reduce_op */
- *error = 1;
- return 0;
-
-extra_rparen:
- errmsg = "Extra \')\'";
- *error = 1;
- return 0;
-
-spaceship_not_allowed:
- errmsg = "Spaceship operator (<=>) not allowed in preprocessor expression";
- *error = 1;
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Preprocessor_expr_error()
- *
- * Return error message set by the evaluator (if any)
- * ----------------------------------------------------------------------------- */
-
-const char *Preprocessor_expr_error(void) {
- return errmsg;
-}
diff --git a/contrib/tools/swig/Source/Preprocessor/preprocessor.h b/contrib/tools/swig/Source/Preprocessor/preprocessor.h
deleted file mode 100644
index c1a30da793..0000000000
--- a/contrib/tools/swig/Source/Preprocessor/preprocessor.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * preprocessor.h
- *
- * SWIG preprocessor module.
- * ----------------------------------------------------------------------------- */
-
-#ifndef SWIG_PREPROCESSOR_H
-#define SWIG_PREPROCESSOR_H
-
-#include "swigwarn.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- extern int Preprocessor_expr(String *s, int *error);
- extern const char *Preprocessor_expr_error(void);
- extern Hash *Preprocessor_define(const_String_or_char_ptr str, int swigmacro);
- extern void Preprocessor_undef(const_String_or_char_ptr name);
- extern void Preprocessor_init(void);
- extern void Preprocessor_delete(void);
- extern String *Preprocessor_parse(String *s);
- extern void Preprocessor_include_all(int);
- extern void Preprocessor_import_all(int);
- extern void Preprocessor_ignore_missing(int);
- extern void Preprocessor_error_as_warning(int);
- extern List *Preprocessor_depend(void);
- extern void Preprocessor_expr_init(void);
- extern void Preprocessor_expr_delete(void);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/contrib/tools/swig/Source/README b/contrib/tools/swig/Source/README
deleted file mode 100644
index 0889333088..0000000000
--- a/contrib/tools/swig/Source/README
+++ /dev/null
@@ -1,15 +0,0 @@
-SWIG Source directory
-
- Source/DOH - A core set of basic datatypes including
- strings, lists, hashes, and files. Used
- extensively by the rest of SWIG.
-
- Source/Swig - Swig core. Type-system, utility functions.
-
- Source/Preprocessor - SWIG C Preprocessor
-
- Source/CParse - SWIG C Parser (still messy)
-
- Source/Modules - Language modules.
-
- Source/Include - Include files.
diff --git a/contrib/tools/swig/Source/Swig/cwrap.c b/contrib/tools/swig/Source/Swig/cwrap.c
deleted file mode 100644
index b7d01bc117..0000000000
--- a/contrib/tools/swig/Source/Swig/cwrap.c
+++ /dev/null
@@ -1,1661 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * cwrap.c
- *
- * This file defines a variety of wrapping rules for C/C++ handling including
- * the naming of local variables, calling conventions, and so forth.
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-#include "cparse.h"
-
-extern int UseWrapperSuffix;
-
-static const char *cresult_variable_name = "result";
-
-static Parm *nonvoid_parms(Parm *p) {
- if (p) {
- SwigType *t = Getattr(p, "type");
- if (SwigType_type(t) == T_VOID)
- return 0;
- }
- return p;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_cresult_name_set()
- *
- * Change the name of the variable used to hold the return value from C/C++ wrapper functions
- * from the default "result".
- * ----------------------------------------------------------------------------- */
-
-void Swig_cresult_name_set(const char *new_name) {
- cresult_variable_name = new_name;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_cresult_name()
- *
- * Get the name of the variable used to hold the return value from C/C++ wrapper functions
- * ----------------------------------------------------------------------------- */
-
-const char *Swig_cresult_name(void) {
- return cresult_variable_name;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_cparm_name()
- *
- * Generates a name for the ith argument in an argument list
- * ----------------------------------------------------------------------------- */
-
-String *Swig_cparm_name(Parm *p, int i) {
- String *name = NewStringf("arg%d", i + 1);
- if (p) {
- Setattr(p, "lname", name);
- }
-
- return name;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_clocal()
- *
- * Creates a string that declares a C local variable type. Converts references
- * and user defined types to pointers.
- * ----------------------------------------------------------------------------- */
-
-static String *Swig_clocal(SwigType *t, const_String_or_char_ptr name, const_String_or_char_ptr value) {
- String *decl;
-
- decl = NewStringEmpty();
-
- switch (SwigType_type(t)) {
- case T_REFERENCE:
- if (value) {
- String *lstrname = SwigType_lstr(t, name);
- String *lstr = SwigType_lstr(t, 0);
- Printf(decl, "%s = (%s) &%s_defvalue", lstrname, lstr, name);
- Delete(lstrname);
- Delete(lstr);
- } else {
- String *lstrname = SwigType_lstr(t, name);
- Printf(decl, "%s = 0", lstrname);
- Delete(lstrname);
- }
- break;
- case T_RVALUE_REFERENCE:
- if (value) {
- String *lstrname = SwigType_lstr(t, name);
- String *lstr = SwigType_lstr(t, 0);
- Printf(decl, "%s = (%s) &%s_defrvalue", lstrname, lstr, name);
- Delete(lstrname);
- Delete(lstr);
- } else {
- String *lstrname = SwigType_lstr(t, name);
- Printf(decl, "%s = 0", lstrname);
- Delete(lstrname);
- }
- break;
- case T_VOID:
- break;
- case T_VARARGS:
- Printf(decl, "void *%s = 0", name);
- break;
-
- default:
- if (value) {
- String *lcaststr = SwigType_lcaststr(t, value);
- String *lstr = SwigType_lstr(t, 0);
- String *lstrn = SwigType_lstr(t, name);
- Printf(decl, "%s = (%s) %s", lstrn, lstr, lcaststr);
- Delete(lcaststr);
- Delete(lstr);
- Delete(lstrn);
- } else {
- String *lstrname = SwigType_lstr(t, name);
- Append(decl, lstrname);
- Delete(lstrname);
- }
- }
- return decl;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_wrapped_var_convert()
- *
- * Converts a member variable for use in the get and set wrapper methods.
- * This function only converts user defined types to pointers.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_wrapped_var_type(SwigType *t, int varcref) {
- SwigType *ty;
-
- if (!Strstr(t, "enum $unnamed")) {
- ty = Copy(t);
- } else {
- /* Change the type for unnamed enum instance variables */
- ty = NewString("int");
- }
-
- if (SwigType_isclass(t)) {
- if (varcref) {
- if (cparse_cplusplus) {
- if (!SwigType_isconst(ty))
- SwigType_add_qualifier(ty, "const");
- SwigType_add_reference(ty);
- } else {
- return Copy(ty);
- }
- } else {
- SwigType_add_pointer(ty);
- }
- }
- return ty;
-}
-
-String *Swig_wrapped_member_var_type(SwigType *t, int varcref) {
- SwigType *ty;
-
- if (!Strstr(t, "enum $unnamed")) {
- ty = Copy(t);
- } else {
- /* Change the type for unnamed enum instance variables */
- ty = NewString("int");
- }
- if (SwigType_isclass(t)) {
- if (varcref) {
- if (cparse_cplusplus) {
- if (!SwigType_isconst(ty))
- SwigType_add_qualifier(ty, "const");
- SwigType_add_reference(ty);
- } else {
- return Copy(ty);
- }
- } else {
- SwigType_add_pointer(ty);
- }
- }
- return ty;
-}
-
-
-static String *Swig_wrapped_var_deref(SwigType *t, const_String_or_char_ptr name, int varcref) {
- if (SwigType_isclass(t)) {
- if (varcref) {
- if (cparse_cplusplus) {
- return NewStringf("*%s", name);
- } else {
- return NewStringf("%s", name);
- }
- } else {
- return NewStringf("*%s", name);
- }
- } else {
- return SwigType_rcaststr(t, name);
- }
-}
-
-static String *Swig_wrapped_var_assign(SwigType *t, const_String_or_char_ptr name, int varcref) {
- if (SwigType_isclass(t)) {
- if (varcref) {
- return NewStringf("%s", name);
- } else {
- return NewStringf("&%s", name);
- }
- } else {
- return SwigType_lcaststr(t, name);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_cargs()
- *
- * Emit all of the local variables for a list of parameters. Returns the
- * number of parameters.
- * Default values for the local variables are only emitted if the compact default
- * argument behaviour is required.
- * ----------------------------------------------------------------------------- */
-int Swig_cargs(Wrapper *w, ParmList *p) {
- int i = 0;
- int compactdefargs = ParmList_is_compactdefargs(p);
-
- while (p != 0) {
- String *lname = Swig_cparm_name(p, i);
- SwigType *pt = Getattr(p, "type");
- if ((SwigType_type(pt) != T_VOID)) {
- String *local = 0;
- String *type = Getattr(p, "type");
- /* default values only emitted if in compact default args mode */
- String *pvalue = (compactdefargs) ? Getattr(p, "value") : 0;
-
- /* When using compactdefaultargs, the code generated initialises a variable via a constructor call that accepts the
- * default value as a parameter. The default constructor is not called and therefore SwigValueWrapper is not needed. */
- SwigType *altty = pvalue ? 0 : SwigType_alttype(type, 0);
-
- int tycode = SwigType_type(type);
- if (tycode == T_REFERENCE) {
- if (pvalue) {
- SwigType *tvalue;
- String *defname, *defvalue, *rvalue, *qvalue;
- rvalue = SwigType_typedef_resolve_all(pvalue);
- qvalue = SwigType_typedef_qualified(rvalue);
- defname = NewStringf("%s_defvalue", lname);
- tvalue = Copy(type);
- SwigType_del_reference(tvalue);
- tycode = SwigType_type(tvalue);
- if (tycode != T_USER) {
- /* plain primitive type, we copy the def value */
- String *lstr = SwigType_lstr(tvalue, defname);
- defvalue = NewStringf("%s = %s", lstr, qvalue);
- Delete(lstr);
- } else {
- /* user type, we copy the reference value */
- String *str = SwigType_str(type, defname);
- defvalue = NewStringf("%s = %s", str, qvalue);
- Delete(str);
- }
- Wrapper_add_localv(w, defname, defvalue, NIL);
- Delete(tvalue);
- Delete(rvalue);
- Delete(qvalue);
- Delete(defname);
- Delete(defvalue);
- }
- } else if (tycode == T_RVALUE_REFERENCE) {
- if (pvalue) {
- SwigType *tvalue;
- String *defname, *defvalue, *rvalue, *qvalue;
- rvalue = SwigType_typedef_resolve_all(pvalue);
- qvalue = SwigType_typedef_qualified(rvalue);
- defname = NewStringf("%s_defrvalue", lname);
- tvalue = Copy(type);
- SwigType_del_rvalue_reference(tvalue);
- tycode = SwigType_type(tvalue);
- if (tycode != T_USER) {
- /* plain primitive type, we copy the def value */
- String *lstr = SwigType_lstr(tvalue, defname);
- defvalue = NewStringf("%s = %s", lstr, qvalue);
- Delete(lstr);
- } else {
- /* user type, we copy the reference value */
- String *str = SwigType_str(type, defname);
- defvalue = NewStringf("%s = %s", str, qvalue);
- Delete(str);
- }
- Wrapper_add_localv(w, defname, defvalue, NIL);
- Delete(tvalue);
- Delete(rvalue);
- Delete(qvalue);
- Delete(defname);
- Delete(defvalue);
- }
- } else if (!pvalue && ((tycode == T_POINTER) || (tycode == T_STRING) || (tycode == T_WSTRING))) {
- pvalue = (String *) "0";
- }
- if (!altty) {
- local = Swig_clocal(pt, lname, pvalue);
- } else {
- local = Swig_clocal(altty, lname, pvalue);
- Delete(altty);
- }
- Wrapper_add_localv(w, lname, local, NIL);
- Delete(local);
- i++;
- }
- Delete(lname);
- p = nextSibling(p);
- }
- return (i);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_cresult()
- *
- * This function generates the C code needed to set the result of a C
- * function call.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_cresult(SwigType *t, const_String_or_char_ptr name, const_String_or_char_ptr decl) {
- String *fcall;
-
- fcall = NewStringEmpty();
- switch (SwigType_type(t)) {
- case T_VOID:
- break;
- case T_REFERENCE:
- {
- String *lstr = SwigType_lstr(t, 0);
- Printf(fcall, "%s = (%s) &", name, lstr);
- Delete(lstr);
- }
- break;
- case T_RVALUE_REFERENCE:
- {
- String *const_lvalue_str;
- String *lstr = SwigType_lstr(t, 0);
- SwigType *tt = Copy(t);
- SwigType_del_rvalue_reference(tt);
- SwigType_add_qualifier(tt, "const");
- SwigType_add_reference(tt);
- const_lvalue_str = SwigType_rcaststr(tt, 0);
-
- Printf(fcall, "%s = (%s) &%s", name, lstr, const_lvalue_str);
-
- Delete(const_lvalue_str);
- Delete(tt);
- Delete(lstr);
- }
- break;
- case T_USER:
- Printf(fcall, "%s = ", name);
- break;
-
- default:
- /* Normal return value */
- {
- String *lstr = SwigType_lstr(t, 0);
- Printf(fcall, "%s = (%s)", name, lstr);
- Delete(lstr);
- }
- break;
- }
-
- /* Now print out function call */
- Append(fcall, decl);
-
- /* A sick hack */
- {
- char *c = Char(decl) + Len(decl) - 1;
- if (!((*c == ';') || (*c == '}')))
- Append(fcall, ";");
- }
-
- return fcall;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_cfunction_call()
- *
- * Creates a string that calls a C function using the local variable rules
- * defined above.
- *
- * name(arg0, arg1, arg2, ... argn)
- *
- * ----------------------------------------------------------------------------- */
-
-String *Swig_cfunction_call(const_String_or_char_ptr name, ParmList *parms) {
- String *func;
- int i = 0;
- int comma = 0;
- Parm *p = parms;
- String *nname;
-
- func = NewStringEmpty();
- nname = SwigType_namestr(name);
-
- /*
- SWIGTEMPLATEDISAMBIGUATOR is compiler dependent (swiglabels.swg),
- - SUN Studio 9 requires 'template',
- - gcc-3.4 forbids the use of 'template'.
- the rest seems not caring very much,
- */
- if (SwigType_istemplate(name)) {
- String *prefix = Swig_scopename_prefix(nname);
- if (!prefix || Len(prefix) == 0) {
- Printf(func, "%s(", nname);
- } else {
- String *last = Swig_scopename_last(nname);
- Printf(func, "%s::SWIGTEMPLATEDISAMBIGUATOR %s(", prefix, last);
- Delete(last);
- }
- Delete(prefix);
- } else {
- Printf(func, "%s(", nname);
- }
- Delete(nname);
-
- while (p) {
- SwigType *pt = Getattr(p, "type");
- if ((SwigType_type(pt) != T_VOID)) {
- SwigType *rpt = SwigType_typedef_resolve_all(pt);
- String *pname = Swig_cparm_name(p, i);
- String *rcaststr = SwigType_rcaststr(rpt, pname);
-
- if (comma) {
- Append(func, ",");
- }
-
- if (cparse_cplusplus && SwigType_type(rpt) == T_USER)
- Printv(func, "SWIG_STD_MOVE(", rcaststr, ")", NIL);
- else
- Printv(func, rcaststr, NIL);
-
- Delete(rpt);
- Delete(pname);
- Delete(rcaststr);
- comma = 1;
- i++;
- }
- p = nextSibling(p);
- }
- Append(func, ")");
- return func;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_cmethod_call()
- *
- * Generates a string that calls a C++ method from a list of parameters.
- *
- * arg0->name(arg1, arg2, arg3, ..., argn)
- *
- * self is an argument that defines how to handle the first argument. Normally,
- * it should be set to "this->". With C++ proxy classes enabled, it could be
- * set to "(*this)->" or some similar sequence.
- * ----------------------------------------------------------------------------- */
-
-static String *Swig_cmethod_call(const_String_or_char_ptr name, ParmList *parms, const_String_or_char_ptr self, String *explicit_qualifier, SwigType *director_type) {
- String *func, *nname;
- int i = 0;
- Parm *p = parms;
- SwigType *pt;
- int comma = 0;
-
- func = NewStringEmpty();
- if (!p)
- return func;
-
- if (!self)
- self = "(this)->";
- Append(func, self);
-
- if (SwigType_istemplate(name) && (strncmp(Char(name), "operator ", 9) == 0)) {
- /* fix for template + operators and compilers like gcc 3.3.5 */
- String *tprefix = SwigType_templateprefix(name);
- nname = tprefix;
- } else {
- nname = SwigType_namestr(name);
- }
-
- if (director_type) {
- const char *pname = "darg";
- String *rcaststr = SwigType_rcaststr(director_type, pname);
- Replaceall(func, "this", rcaststr);
- Delete(rcaststr);
- } else {
- pt = Getattr(p, "type");
-
- /* If the method is invoked through a dereferenced pointer, we don't add any casts
- (needed for smart pointers). Otherwise, we cast to the appropriate type */
-
- if (Strstr(func, "*this")) {
- String *pname = Swig_cparm_name(p, 0);
- Replaceall(func, "this", pname);
- Delete(pname);
- } else {
- String *pname = Swig_cparm_name(p, 0);
- String *rcaststr = SwigType_rcaststr(pt, pname);
- Replaceall(func, "this", rcaststr);
- Delete(rcaststr);
- Delete(pname);
- }
-
- /*
- SWIGTEMPLATEDESIMBUAGATOR is compiler dependent (swiglabels.swg),
- - SUN Studio 9 requires 'template',
- - gcc-3.4 forbids the use of 'template' (correctly implementing the ISO C++ standard)
- the others don't seem to care,
- */
- if (SwigType_istemplate(name))
- Printf(func, "SWIGTEMPLATEDISAMBIGUATOR ");
-
- if (explicit_qualifier) {
- Printv(func, explicit_qualifier, "::", NIL);
- }
- }
-
- Printf(func, "%s(", nname);
-
- i++;
- p = nextSibling(p);
- while (p) {
- pt = Getattr(p, "type");
- if ((SwigType_type(pt) != T_VOID)) {
- String *pname = Swig_cparm_name(p, i);
- String *rcaststr = SwigType_rcaststr(pt, pname);
- if (comma)
- Append(func, ",");
- Append(func, rcaststr);
- Delete(rcaststr);
- Delete(pname);
- comma = 1;
- i++;
- }
- p = nextSibling(p);
- }
- Append(func, ")");
- Delete(nname);
- return func;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_cconstructor_call()
- *
- * Creates a string that calls a C constructor function.
- *
- * calloc(1,sizeof(name));
- * ----------------------------------------------------------------------------- */
-
-String *Swig_cconstructor_call(const_String_or_char_ptr name) {
- DOH *func;
-
- func = NewStringEmpty();
- Printf(func, "calloc(1, sizeof(%s))", name);
- return func;
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_cppconstructor_call()
- *
- * Creates a string that calls a C function using the local variable rules
- * defined above.
- *
- * name(arg0, arg1, arg2, ... argn)
- *
- * ----------------------------------------------------------------------------- */
-
-String *Swig_cppconstructor_base_call(const_String_or_char_ptr name, ParmList *parms, int skip_self) {
- String *func;
- String *nname;
- int i = 0;
- int comma = 0;
- Parm *p = parms;
- SwigType *pt;
- if (skip_self) {
- if (p)
- p = nextSibling(p);
- i++;
- }
- nname = SwigType_namestr(name);
- func = NewStringEmpty();
- Printf(func, "new %s(", nname);
- while (p) {
- pt = Getattr(p, "type");
- if ((SwigType_type(pt) != T_VOID)) {
- String *rcaststr = 0;
- String *pname = 0;
- if (comma)
- Append(func, ",");
- if (!Getattr(p, "arg:byname")) {
- pname = Swig_cparm_name(p, i);
- i++;
- } else {
- pname = Getattr(p, "value");
- if (pname)
- pname = Copy(pname);
- else
- pname = Copy(Getattr(p, "name"));
- }
- rcaststr = SwigType_rcaststr(pt, pname);
- Append(func, rcaststr);
- Delete(rcaststr);
- comma = 1;
- Delete(pname);
- }
- p = nextSibling(p);
- }
- Append(func, ")");
- Delete(nname);
- return func;
-}
-
-String *Swig_cppconstructor_call(const_String_or_char_ptr name, ParmList *parms) {
- return Swig_cppconstructor_base_call(name, parms, 0);
-}
-
-String *Swig_cppconstructor_nodirector_call(const_String_or_char_ptr name, ParmList *parms) {
- return Swig_cppconstructor_base_call(name, parms, 1);
-}
-
-String *Swig_cppconstructor_director_call(const_String_or_char_ptr name, ParmList *parms) {
- return Swig_cppconstructor_base_call(name, parms, 0);
-}
-
-/* -----------------------------------------------------------------------------
- * recursive_flag_search()
- *
- * This function searches for the class attribute 'attr' in the class
- * 'n' or recursively in its bases.
- *
- * If you define SWIG_FAST_REC_SEARCH, the method will set the found
- * 'attr' in the target class 'n'. If not, the method will set the
- * 'noattr' one. This prevents of having to navigate the entire
- * hierarchy tree every time, so, it is an O(1) method... or something
- * like that. However, it populates all the parsed classes with the
- * 'attr' and/or 'noattr' attributes.
- *
- * If you undefine the SWIG_FAST_REC_SEARCH no attribute will be set
- * while searching. This could be slower for large projects with very
- * large hierarchy trees... or maybe not. But it will be cleaner.
- *
- * Maybe later a swig option can be added to switch at runtime.
- *
- * ----------------------------------------------------------------------------- */
-
-/* #define SWIG_FAST_REC_SEARCH 1 */
-static String *recursive_flag_search(Node *n, const String *attr, const String *noattr) {
- String *f = 0;
- n = Swig_methodclass(n);
- if (GetFlag(n, noattr)) {
- return 0;
- }
- f = GetFlagAttr(n, attr);
- if (f) {
- return f;
- } else {
- List *bl = Getattr(n, "bases");
- if (bl) {
- Iterator bi;
- for (bi = First(bl); bi.item; bi = Next(bi)) {
- f = recursive_flag_search(bi.item, attr, noattr);
- if (f) {
-#ifdef SWIG_FAST_REC_SEARCH
- SetFlagAttr(n, attr, f);
-#endif
- return f;
- }
- }
- }
- }
-#ifdef SWIG_FAST_REC_SEARCH
- SetFlag(n, noattr);
-#endif
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_unref_call()
- *
- * Find the "feature:unref" call, if any.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_unref_call(Node *n) {
- String *unref = recursive_flag_search(n, "feature:unref", "feature:nounref");
- if (unref) {
- String *pname = Swig_cparm_name(0, 0);
- unref = NewString(unref);
- Replaceall(unref, "$this", pname);
- Replaceall(unref, "$self", pname);
- Delete(pname);
- }
- return unref;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_ref_call()
- *
- * Find the "feature:ref" call, if any.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_ref_call(Node *n, const String *lname) {
- String *ref = recursive_flag_search(n, "feature:ref", "feature:noref");
- if (ref) {
- ref = NewString(ref);
- Replaceall(ref, "$this", lname);
- Replaceall(ref, "$self", lname);
- }
- return ref;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_cdestructor_call()
- *
- * Creates a string that calls a C destructor function.
- *
- * free((char *) arg0);
- * ----------------------------------------------------------------------------- */
-
-String *Swig_cdestructor_call(Node *n) {
- Node *cn = Swig_methodclass(n);
- String *unref = Swig_unref_call(cn);
-
- if (unref) {
- return unref;
- } else {
- String *pname = Swig_cparm_name(0, 0);
- String *call = NewStringf("free((char *) %s);", pname);
- Delete(pname);
- return call;
- }
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_cppdestructor_call()
- *
- * Creates a string that calls a C destructor function.
- *
- * delete arg1;
- * ----------------------------------------------------------------------------- */
-
-String *Swig_cppdestructor_call(Node *n) {
- Node *cn = Swig_methodclass(n);
- String *unref = Swig_unref_call(cn);
- if (unref) {
- return unref;
- } else {
- String *pname = Swig_cparm_name(0, 0);
- String *call = NewStringf("delete %s;", pname);
- Delete(pname);
- return call;
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_cmemberset_call()
- *
- * Generates a string that sets the name of a member in a C++ class or C struct.
- *
- * arg0->name = arg1
- *
- * ----------------------------------------------------------------------------- */
-
-String *Swig_cmemberset_call(const_String_or_char_ptr name, SwigType *type, String *self, int varcref) {
- String *func;
- String *pname0 = Swig_cparm_name(0, 0);
- String *pname1 = Swig_cparm_name(0, 1);
- func = NewStringEmpty();
- if (!self)
- self = NewString("(this)->");
- else
- self = NewString(self);
- Replaceall(self, "this", pname0);
- if (SwigType_type(type) != T_ARRAY) {
- if (!Strstr(type, "enum $unnamed")) {
- String *dref = Swig_wrapped_var_deref(type, pname1, varcref);
- int extra_cast = 0;
- if (cparse_cplusplusout) {
- /* Required for C nested structs compiled as C++ as a duplicate of the nested struct is put into the global namespace.
- * We could improve this by adding the extra casts just for nested structs rather than all structs. */
- String *base = SwigType_base(type);
- extra_cast = SwigType_isclass(base);
- Delete(base);
- }
- if (extra_cast) {
- String *lstr;
- SwigType *ptype = Copy(type);
- SwigType_add_pointer(ptype);
- lstr = SwigType_lstr(ptype, 0);
- Printf(func, "if (%s) *(%s)&%s%s = %s", pname0, lstr, self, name, dref);
- Delete(lstr);
- Delete(ptype);
- } else {
- Printf(func, "if (%s) %s%s = %s", pname0, self, name, dref);
- }
- Delete(dref);
- } else {
- Printf(func, "if (%s && sizeof(int) == sizeof(%s%s)) *(int*)(void*)&(%s%s) = %s", pname0, self, name, self, name, pname1);
- }
- }
- Delete(self);
- Delete(pname0);
- Delete(pname1);
- return (func);
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_cmemberget_call()
- *
- * Generates a string that sets the name of a member in a C++ class or C struct.
- *
- * arg0->name
- *
- * ----------------------------------------------------------------------------- */
-
-String *Swig_cmemberget_call(const_String_or_char_ptr name, SwigType *t, String *self, int varcref) {
- String *func;
- String *call;
- String *pname0 = Swig_cparm_name(0, 0);
- if (!self)
- self = NewString("(this)->");
- else
- self = NewString(self);
- Replaceall(self, "this", pname0);
- func = NewStringEmpty();
- call = Swig_wrapped_var_assign(t, "", varcref);
- Printf(func, "%s (%s%s)", call, self, name);
- Delete(self);
- Delete(call);
- Delete(pname0);
- return func;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_replace_special_variables()
- *
- * Replaces special variables with a value from the supplied node
- * ----------------------------------------------------------------------------- */
-void Swig_replace_special_variables(Node *n, Node *parentnode, String *code) {
- Node *parentclass = parentnode;
- String *overloaded = Getattr(n, "sym:overloaded");
- Replaceall(code, "$name", Getattr(n, "name"));
- Replaceall(code, "$symname", Getattr(n, "sym:name"));
- Replaceall(code, "$wrapname", Getattr(n, "wrap:name"));
- Replaceall(code, "$overname", overloaded ? Char(Getattr(n, "sym:overname")) : "");
-
- if (Strstr(code, "$decl")) {
- String *decl = Swig_name_decl(n);
- Replaceall(code, "$decl", decl);
- Delete(decl);
- }
- if (Strstr(code, "$fulldecl")) {
- String *fulldecl = Swig_name_fulldecl(n);
- Replaceall(code, "$fulldecl", fulldecl);
- Delete(fulldecl);
- }
-
- if (parentclass && !Equal(nodeType(parentclass), "class"))
- parentclass = 0;
- if (Strstr(code, "$parentclasssymname")) {
- String *parentclasssymname = 0;
- if (parentclass)
- parentclasssymname = Getattr(parentclass, "sym:name");
- Replaceall(code, "$parentclasssymname", parentclasssymname ? parentclasssymname : "");
- }
- if (Strstr(code, "$parentclassname")) {
- String *parentclassname = 0;
- if (parentclass)
- parentclassname = Getattr(parentclass, "name");
- Replaceall(code, "$parentclassname", parentclassname ? SwigType_str(parentclassname, "") : "");
- }
-}
-
-/* -----------------------------------------------------------------------------
- * extension_code()
- *
- * Generates an extension function (a function defined in %extend)
- *
- * return_type function_name(parms) code
- *
- * ----------------------------------------------------------------------------- */
-static String *extension_code(Node *n, const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self) {
- String *parms_str = cplusplus ? ParmList_str_defaultargs(parms) : ParmList_str(parms);
- String *sig = NewStringf("%s(%s)", function_name, (cplusplus || Len(parms_str)) ? parms_str : "void");
- String *rt_sig = SwigType_str(return_type, sig);
- String *body = NewStringf("SWIGINTERN %s", rt_sig);
- Printv(body, code, "\n", NIL);
- if (Strstr(body, "$")) {
- Swig_replace_special_variables(n, parentNode(parentNode(n)), body);
- if (self)
- Replaceall(body, "$self", self);
- }
- Delete(parms_str);
- Delete(sig);
- Delete(rt_sig);
- return body;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_add_extension_code()
- *
- * Generates an extension function (a function defined in %extend) and
- * adds it to the "wrap:code" attribute of a node
- *
- * See also extension_code()
- *
- * ----------------------------------------------------------------------------- */
-int Swig_add_extension_code(Node *n, const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self) {
- String *body = extension_code(n, function_name, parms, return_type, code, cplusplus, self);
- Setattr(n, "wrap:code", body);
- Delete(body);
- return SWIG_OK;
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_MethodToFunction(Node *n)
- *
- * Converts a C++ method node to a function accessor function.
- * ----------------------------------------------------------------------------- */
-
-int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, int flags, SwigType *director_type, int is_director) {
- String *name;
- ParmList *parms;
- SwigType *type;
- Parm *p;
- String *self = 0;
- int is_smart_pointer_overload = 0;
- String *qualifier = Getattr(n, "qualifier");
- String *directorScope = NewString(nspace);
-
- Replace(directorScope, NSPACE_SEPARATOR, "_", DOH_REPLACE_ANY);
-
- /* If smart pointer without const overload or mutable method, change self dereferencing */
- if (flags & CWRAP_SMART_POINTER) {
- if (flags & CWRAP_SMART_POINTER_OVERLOAD) {
- if (qualifier && strncmp(Char(qualifier), "q(const)", 8) == 0) {
- self = NewString("(*(this))->");
- is_smart_pointer_overload = 1;
- }
- else if (Swig_storage_isstatic(n)) {
- String *cname = Getattr(n, "extendsmartclassname") ? Getattr(n, "extendsmartclassname") : classname;
- String *ctname = SwigType_namestr(cname);
- self = NewStringf("(*(%s const *)this)->", ctname);
- is_smart_pointer_overload = 1;
- Delete(ctname);
- }
- else {
- self = NewString("(*this)->");
- }
- } else {
- self = NewString("(*this)->");
- }
- }
-
- /* If node is a member template expansion, we don't allow added code */
- if (Getattr(n, "templatetype"))
- flags &= ~(CWRAP_EXTEND);
-
- name = Getattr(n, "name");
- parms = CopyParmList(nonvoid_parms(Getattr(n, "parms")));
-
- type = NewString(classname);
- if (qualifier) {
- SwigType_push(type, qualifier);
- }
- SwigType_add_pointer(type);
- p = NewParm(type, "self", n);
- Setattr(p, "self", "1");
- Setattr(p, "hidden","1");
- /*
- Disable the 'this' ownership in 'self' to manage inplace
- operations like:
-
- A& A::operator+=(int i) { ...; return *this;}
-
- Here the 'self' parameter ownership needs to be disabled since
- there could be two objects sharing the same 'this' pointer: the
- input and the result one. And worse, the pointer could be deleted
- in one of the objects (input), leaving the other (output) with
- just a seg. fault to happen.
-
- To avoid the previous problem, use
-
- %feature("self:disown") *::operator+=;
- %feature("new") *::operator+=;
-
- These two lines just transfer the ownership of the 'this' pointer
- from the input to the output wrapping object.
-
- This happens in python, but may also happen in other target
- languages.
- */
- if (GetFlag(n, "feature:self:disown")) {
- Setattr(p, "wrap:disown", "1");
- }
- set_nextSibling(p, parms);
- Delete(type);
-
- /* Generate action code for the access */
- if (!(flags & CWRAP_EXTEND)) {
- String *explicit_qualifier = 0;
- String *call = 0;
- String *cres = 0;
- String *explicitcall_name = 0;
- int pure_virtual = !(Cmp(Getattr(n, "storage"), "virtual")) && !(Cmp(Getattr(n, "value"), "0"));
-
- /* Call the explicit method rather than allow for a polymorphic call */
- if ((flags & CWRAP_DIRECTOR_TWO_CALLS) || (flags & CWRAP_DIRECTOR_ONE_CALL)) {
- String *access = Getattr(n, "access");
- if (access && (Cmp(access, "protected") == 0)) {
- /* If protected access (can only be if a director method) then call the extra public accessor method (language module must provide this) */
- String *explicit_qualifier_tmp = SwigType_namestr(Getattr(Getattr(parentNode(n), "typescope"), "qname"));
- explicitcall_name = NewStringf("%sSwigPublic", name);
- if (Len(directorScope) > 0)
- explicit_qualifier = NewStringf("SwigDirector_%s_%s", directorScope, explicit_qualifier_tmp);
- else
- explicit_qualifier = NewStringf("SwigDirector_%s", explicit_qualifier_tmp);
- Delete(explicit_qualifier_tmp);
- } else {
- explicit_qualifier = SwigType_namestr(Getattr(Getattr(parentNode(n), "typescope"), "qname"));
- }
- }
-
- if (!self && SwigType_isrvalue_reference(Getattr(n, "refqualifier"))) {
- String *memory_header = NewString("<memory>");
- Setfile(memory_header, Getfile(n));
- Setline(memory_header, Getline(n));
- Swig_fragment_emit(memory_header);
- self = NewString("std::move(*this).");
- Delete(memory_header);
- }
-
- call = Swig_cmethod_call(explicitcall_name ? explicitcall_name : name, p, self, explicit_qualifier, director_type);
- cres = Swig_cresult(Getattr(n, "type"), Swig_cresult_name(), call);
-
- if (pure_virtual && is_director && (flags & CWRAP_DIRECTOR_TWO_CALLS)) {
- String *qualifier = SwigType_namestr(Getattr(Getattr(parentNode(n), "typescope"), "qname"));
- Delete(cres);
- cres = NewStringf("Swig::DirectorPureVirtualException::raise(\"%s::%s\");", qualifier, name);
- Delete(qualifier);
- }
-
- if (flags & CWRAP_DIRECTOR_TWO_CALLS) {
- /* Create two method calls, one to call the explicit method, the other a normal polymorphic function call */
- String *cres_both_calls = NewStringf("");
- String *call_extra = Swig_cmethod_call(name, p, self, 0, director_type);
- String *cres_extra = Swig_cresult(Getattr(n, "type"), Swig_cresult_name(), call_extra);
- Printv(cres_both_calls, "if (upcall) {\n", cres, "\n", "} else {", cres_extra, "\n}", NIL);
- Setattr(n, "wrap:action", cres_both_calls);
- Delete(cres_extra);
- Delete(call_extra);
- Delete(cres_both_calls);
- } else {
- Setattr(n, "wrap:action", cres);
- }
-
- Delete(explicitcall_name);
- Delete(call);
- Delete(cres);
- Delete(explicit_qualifier);
- } else {
- /* Methods with default arguments are wrapped with additional methods for each default argument,
- * however, only one extra %extend method is generated. */
-
- String *defaultargs = Getattr(n, "defaultargs");
- String *code = Getattr(n, "code");
- String *cname = Getattr(n, "extendsmartclassname") ? Getattr(n, "extendsmartclassname") : classname;
- String *membername = Swig_name_member(nspace, cname, name);
- String *mangled = Swig_name_mangle(membername);
- int is_smart_pointer = flags & CWRAP_SMART_POINTER;
-
- type = Getattr(n, "type");
-
- /* Check if the method is overloaded. If so, and it has code attached, we append an extra suffix
- to avoid a name-clash in the generated wrappers. This allows overloaded methods to be defined
- in C.
-
- But when not using the suffix used for overloaded functions, we still need to ensure that the
- wrapper name doesn't conflict with any wrapper functions for some languages, so optionally make
- it sufficiently unique by appending a suffix similar to the one used for overloaded functions to it.
- */
- if (code) {
- if (Getattr(n, "sym:overloaded")) {
- Append(mangled, Getattr(defaultargs ? defaultargs : n, "sym:overname"));
- } else if (UseWrapperSuffix) {
- Append(mangled, "__SWIG");
- }
- }
-
- /* See if there is any code that we need to emit */
- if (!defaultargs && code && !is_smart_pointer) {
- Swig_add_extension_code(n, mangled, p, type, code, cparse_cplusplus, "self");
- }
- if (is_smart_pointer) {
- int i = 0;
- Parm *pp = p;
- String *func = NewStringf("%s(", mangled);
- String *cres;
-
- if (!Swig_storage_isstatic(n)) {
- String *pname = Swig_cparm_name(pp, i);
- String *ctname = SwigType_namestr(cname);
- String *fadd = 0;
- if (is_smart_pointer_overload) {
- String *nclassname = SwigType_namestr(classname);
- fadd = NewStringf("(%s const *)((%s const *)%s)->operator ->()", ctname, nclassname, pname);
- Delete(nclassname);
- }
- else {
- fadd = NewStringf("(%s*)(%s)->operator ->()", ctname, pname);
- }
- Append(func, fadd);
- Delete(ctname);
- Delete(fadd);
- Delete(pname);
- pp = nextSibling(pp);
- if (pp)
- Append(func, ",");
- } else {
- pp = nextSibling(pp);
- }
- ++i;
- while (pp) {
- SwigType *pt = Getattr(pp, "type");
- if ((SwigType_type(pt) != T_VOID)) {
- String *pname = Swig_cparm_name(pp, i++);
- String *rcaststr = SwigType_rcaststr(pt, pname);
- Append(func, rcaststr);
- Delete(rcaststr);
- Delete(pname);
- pp = nextSibling(pp);
- if (pp)
- Append(func, ",");
- }
- }
- Append(func, ")");
- cres = Swig_cresult(Getattr(n, "type"), Swig_cresult_name(), func);
- Setattr(n, "wrap:action", cres);
- Delete(cres);
- } else {
- String *call = Swig_cfunction_call(mangled, p);
- String *cres = Swig_cresult(Getattr(n, "type"), Swig_cresult_name(), call);
- Setattr(n, "wrap:action", cres);
- Delete(call);
- Delete(cres);
- }
-
- Delete(membername);
- Delete(mangled);
- }
- Setattr(n, "parms", p);
- Delete(p);
- Delete(self);
- Delete(parms);
- Delete(directorScope);
- return SWIG_OK;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_methodclass()
- *
- * This function returns the class node for a given method or class.
- * ----------------------------------------------------------------------------- */
-
-Node *Swig_methodclass(Node *n) {
- Node *nodetype = nodeType(n);
- if (Cmp(nodetype, "class") == 0)
- return n;
- return GetFlag(n, "feature:extend") ? parentNode(parentNode(n)) : parentNode(n);
-}
-
-int Swig_directorclass(Node *n) {
- Node *classNode = Swig_methodclass(n);
- assert(classNode != 0);
- return (Getattr(classNode, "vtable") != 0);
-}
-
-Node *Swig_directormap(Node *module, String *type) {
- int is_void = !Cmp(type, "void");
- if (!is_void && module) {
- /* ?? follow the inheritance hierarchy? */
-
- String *base = SwigType_base(type);
-
- Node *directormap = Getattr(module, "wrap:directormap");
- if (directormap)
- return Getattr(directormap, base);
- }
- return 0;
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_ConstructorToFunction()
- *
- * This function creates a C wrapper for a C constructor function.
- * ----------------------------------------------------------------------------- */
-
-int Swig_ConstructorToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, String *none_comparison, String *director_ctor, int cplus, int flags, String *directorname) {
- Parm *p;
- ParmList *directorparms;
- SwigType *type;
- int use_director = Swig_directorclass(n);
- ParmList *parms = CopyParmList(nonvoid_parms(Getattr(n, "parms")));
- /* Prepend the list of prefix_args (if any) */
- Parm *prefix_args = Getattr(n, "director:prefix_args");
- if (prefix_args != NIL) {
- Parm *p2, *p3;
-
- directorparms = CopyParmList(prefix_args);
- for (p = directorparms; nextSibling(p); p = nextSibling(p));
- for (p2 = parms; p2; p2 = nextSibling(p2)) {
- p3 = CopyParm(p2);
- set_nextSibling(p, p3);
- Delete(p3);
- p = p3;
- }
- } else
- directorparms = parms;
-
- type = NewString(classname);
- SwigType_add_pointer(type);
-
- if (flags & CWRAP_EXTEND) {
- /* Constructors with default arguments are wrapped with additional constructor methods for each default argument,
- * however, only one extra %extend method is generated. */
- String *call;
- String *cres;
- String *defaultargs = Getattr(n, "defaultargs");
- String *code = Getattr(n, "code");
- String *membername = Swig_name_construct(nspace, classname);
- String *mangled = Swig_name_mangle(membername);
-
- /* Check if the constructor is overloaded. If so, and it has code attached, we append an extra suffix
- to avoid a name-clash in the generated wrappers. This allows overloaded constructors to be defined
- in C. */
- if (Getattr(n, "sym:overloaded") && code) {
- Append(mangled, Getattr(defaultargs ? defaultargs : n, "sym:overname"));
- }
-
- /* See if there is any code that we need to emit */
- if (!defaultargs && code) {
- Swig_add_extension_code(n, mangled, parms, type, code, cparse_cplusplus, "self");
- }
-
- call = Swig_cfunction_call(mangled, parms);
- cres = Swig_cresult(type, Swig_cresult_name(), call);
- Setattr(n, "wrap:action", cres);
- Delete(cres);
- Delete(call);
- Delete(membername);
- Delete(mangled);
- } else {
- if (cplus) {
- /* if a C++ director class exists, create it rather than the original class */
- if (use_director) {
- Node *parent = Swig_methodclass(n);
- int abstract = Getattr(parent, "abstracts") != 0;
- String *action = NewStringEmpty();
- String *tmp_none_comparison = Copy(none_comparison);
- String *director_call;
- String *nodirector_call;
-
- Replaceall(tmp_none_comparison, "$arg", "arg1");
-
- director_call = Swig_cppconstructor_director_call(directorname, directorparms);
- nodirector_call = Swig_cppconstructor_nodirector_call(classname, parms);
-
- if (abstract) {
- /* whether or not the abstract class has been subclassed in python,
- * create a director instance (there's no way to create a normal
- * instance). if any of the pure virtual methods haven't been
- * implemented in the target language, calls to those methods will
- * generate Swig::DirectorPureVirtualException exceptions.
- */
- String *cres = Swig_cresult(type, Swig_cresult_name(), director_call);
- Append(action, cres);
- Delete(cres);
- } else {
- /* (scottm): The code for creating a new director is now a string
- template that gets passed in via the director_ctor argument.
-
- $comparison : an 'if' comparison from none_comparison
- $director_new: Call new for director class
- $nondirector_new: Call new for non-director class
- */
- String *cres;
- Append(action, director_ctor);
- Replaceall(action, "$comparison", tmp_none_comparison);
-
- cres = Swig_cresult(type, Swig_cresult_name(), director_call);
- Replaceall(action, "$director_new", cres);
- Delete(cres);
-
- cres = Swig_cresult(type, Swig_cresult_name(), nodirector_call);
- Replaceall(action, "$nondirector_new", cres);
- Delete(cres);
- }
- Setattr(n, "wrap:action", action);
- Delete(tmp_none_comparison);
- Delete(action);
- } else {
- String *call = Swig_cppconstructor_call(classname, parms);
- String *cres = Swig_cresult(type, Swig_cresult_name(), call);
- Setattr(n, "wrap:action", cres);
- Delete(cres);
- Delete(call);
- }
- } else {
- String *call = Swig_cconstructor_call(classname);
- String *cres = Swig_cresult(type, Swig_cresult_name(), call);
- Setattr(n, "wrap:action", cres);
- Delete(cres);
- Delete(call);
- }
- }
- Setattr(n, "type", type);
- Setattr(n, "parms", parms);
- Delete(type);
- if (directorparms != parms)
- Delete(directorparms);
- Delete(parms);
- return SWIG_OK;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_DestructorToFunction()
- *
- * This function creates a C wrapper for a destructor function.
- * ----------------------------------------------------------------------------- */
-
-int Swig_DestructorToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, int cplus, int flags) {
- SwigType *type;
- Parm *p;
-
- type = NewString(classname);
- SwigType_add_pointer(type);
- p = NewParm(type, "self", n);
- Setattr(p, "self", "1");
- Setattr(p, "hidden", "1");
- Setattr(p, "wrap:disown", "1");
- Delete(type);
- type = NewString("void");
-
- if (flags & CWRAP_EXTEND) {
- String *cres;
- String *call;
- String *membername, *mangled, *code;
- membername = Swig_name_destroy(nspace, classname);
- mangled = Swig_name_mangle(membername);
- code = Getattr(n, "code");
- if (code) {
- Swig_add_extension_code(n, mangled, p, type, code, cparse_cplusplus, "self");
- }
- call = Swig_cfunction_call(mangled, p);
- cres = NewStringf("%s;", call);
- Setattr(n, "wrap:action", cres);
- Delete(membername);
- Delete(mangled);
- Delete(call);
- Delete(cres);
- } else {
- if (cplus) {
- String *call = Swig_cppdestructor_call(n);
- String *cres = NewStringf("%s", call);
- Setattr(n, "wrap:action", cres);
- Delete(call);
- Delete(cres);
- } else {
- String *call = Swig_cdestructor_call(n);
- String *cres = NewStringf("%s", call);
- Setattr(n, "wrap:action", cres);
- Delete(call);
- Delete(cres);
- }
- }
- Setattr(n, "type", type);
- Setattr(n, "parms", p);
- Delete(type);
- Delete(p);
- return SWIG_OK;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_MembersetToFunction()
- *
- * This function creates a C wrapper for setting a structure member.
- * ----------------------------------------------------------------------------- */
-
-int Swig_MembersetToFunction(Node *n, String *classname, int flags) {
- String *name;
- ParmList *parms;
- Parm *p;
- SwigType *t;
- SwigType *ty;
- SwigType *type;
- SwigType *void_type = NewString("void");
- String *self = 0;
-
- int varcref = flags & CWRAP_NATURAL_VAR;
-
- if (flags & CWRAP_SMART_POINTER) {
- self = NewString("(*this)->");
- }
- if (flags & CWRAP_ALL_PROTECTED_ACCESS) {
- self = NewStringf("darg->");
- }
-
- name = Getattr(n, "name");
- type = Getattr(n, "type");
-
- t = NewString(classname);
- SwigType_add_pointer(t);
- parms = NewParm(t, "self", n);
- Setattr(parms, "self", "1");
- Setattr(parms, "hidden","1");
- Delete(t);
-
- ty = Swig_wrapped_member_var_type(type, varcref);
- p = NewParm(ty, name, n);
- Setattr(parms, "hidden", "1");
- set_nextSibling(parms, p);
-
- /* If the type is a pointer or reference. We mark it with a special wrap:disown attribute */
- if (SwigType_check_decl(type, "p.")) {
- Setattr(p, "wrap:disown", "1");
- }
- Delete(p);
-
- if (flags & CWRAP_EXTEND) {
- String *call;
- String *cres;
- String *code = Getattr(n, "code");
-
- String *sname = Swig_name_set(0, name);
- String *membername = Swig_name_member(0, classname, sname);
- String *mangled = Swig_name_mangle(membername);
-
- if (code) {
- /* I don't think this ever gets run - WSF */
- Swig_add_extension_code(n, mangled, parms, void_type, code, cparse_cplusplus, "self");
- }
- call = Swig_cfunction_call(mangled, parms);
- cres = NewStringf("%s;", call);
- Setattr(n, "wrap:action", cres);
-
- Delete(cres);
- Delete(call);
- Delete(mangled);
- Delete(membername);
- Delete(sname);
- } else {
- String *call = Swig_cmemberset_call(name, type, self, varcref);
- String *cres = NewStringf("%s;", call);
- Setattr(n, "wrap:action", cres);
- Delete(call);
- Delete(cres);
- }
- Setattr(n, "type", void_type);
- Setattr(n, "parms", parms);
- Delete(parms);
- Delete(ty);
- Delete(void_type);
- Delete(self);
- return SWIG_OK;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_MembergetToFunction()
- *
- * This function creates a C wrapper for getting a structure member.
- * ----------------------------------------------------------------------------- */
-
-int Swig_MembergetToFunction(Node *n, String *classname, int flags) {
- String *name;
- ParmList *parms;
- SwigType *t;
- SwigType *ty;
- SwigType *type;
- String *self = 0;
-
- int varcref = flags & CWRAP_NATURAL_VAR;
-
- if (flags & CWRAP_SMART_POINTER) {
- if (Swig_storage_isstatic(n)) {
- Node *sn = Getattr(n, "cplus:staticbase");
- String *base = Getattr(sn, "name");
- self = NewStringf("%s::", base);
- } else if (flags & CWRAP_SMART_POINTER_OVERLOAD) {
- String *nclassname = SwigType_namestr(classname);
- self = NewStringf("(*(%s const *)this)->", nclassname);
- Delete(nclassname);
- } else {
- self = NewString("(*this)->");
- }
- }
- if (flags & CWRAP_ALL_PROTECTED_ACCESS) {
- self = NewStringf("darg->");
- }
-
- name = Getattr(n, "name");
- type = Getattr(n, "type");
-
- t = NewString(classname);
- SwigType_add_pointer(t);
- parms = NewParm(t, "self", n);
- Setattr(parms, "self", "1");
- Setattr(parms, "hidden","1");
- Delete(t);
-
- ty = Swig_wrapped_member_var_type(type, varcref);
- if (flags & CWRAP_EXTEND) {
- String *call;
- String *cres;
- String *code = Getattr(n, "code");
-
- String *gname = Swig_name_get(0, name);
- String *membername = Swig_name_member(0, classname, gname);
- String *mangled = Swig_name_mangle(membername);
-
- if (code) {
- /* I don't think this ever gets run - WSF */
- Swig_add_extension_code(n, mangled, parms, ty, code, cparse_cplusplus, "self");
- }
- call = Swig_cfunction_call(mangled, parms);
- cres = Swig_cresult(ty, Swig_cresult_name(), call);
- Setattr(n, "wrap:action", cres);
-
- Delete(cres);
- Delete(call);
- Delete(mangled);
- Delete(membername);
- Delete(gname);
- } else {
- String *call = Swig_cmemberget_call(name, type, self, varcref);
- String *cres = Swig_cresult(ty, Swig_cresult_name(), call);
- Setattr(n, "wrap:action", cres);
- Delete(call);
- Delete(cres);
- }
- Setattr(n, "type", ty);
- Setattr(n, "parms", parms);
- Delete(parms);
- Delete(ty);
-
- return SWIG_OK;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_VarsetToFunction()
- *
- * This function creates a C wrapper for setting a global variable or static member
- * variable.
- * ----------------------------------------------------------------------------- */
-
-int Swig_VarsetToFunction(Node *n, int flags) {
- String *name, *nname;
- ParmList *parms;
- SwigType *type, *ty;
-
- int varcref = flags & CWRAP_NATURAL_VAR;
-
- name = Getattr(n, "name");
- type = Getattr(n, "type");
- nname = SwigType_namestr(name);
- ty = Swig_wrapped_var_type(type, varcref);
- parms = NewParm(ty, name, n);
-
- if (flags & CWRAP_EXTEND) {
- String *sname = Swig_name_set(0, name);
- String *mangled = Swig_name_mangle(sname);
- String *call = Swig_cfunction_call(mangled, parms);
- String *cres = NewStringf("%s;", call);
- Setattr(n, "wrap:action", cres);
- Delete(cres);
- Delete(call);
- Delete(mangled);
- Delete(sname);
- } else {
- if (!Strstr(type, "enum $unnamed")) {
- String *pname = Swig_cparm_name(0, 0);
- String *dref = Swig_wrapped_var_deref(type, pname, varcref);
- String *call = NewStringf("%s = %s;", nname, dref);
- Setattr(n, "wrap:action", call);
- Delete(call);
- Delete(dref);
- Delete(pname);
- } else {
- String *pname = Swig_cparm_name(0, 0);
- String *call = NewStringf("if (sizeof(int) == sizeof(%s)) *(int*)(void*)&(%s) = %s;", nname, nname, pname);
- Setattr(n, "wrap:action", call);
- Delete(pname);
- Delete(call);
- }
- }
- Setattr(n, "type", "void");
- Setattr(n, "parms", parms);
- Delete(parms);
- Delete(ty);
- Delete(nname);
- return SWIG_OK;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_VargetToFunction()
- *
- * This function creates a C wrapper for getting a global variable or static member
- * variable.
- * ----------------------------------------------------------------------------- */
-
-int Swig_VargetToFunction(Node *n, int flags) {
- String *cres, *call;
- String *name;
- SwigType *type;
- SwigType *ty = 0;
-
- int varcref = flags & CWRAP_NATURAL_VAR;
-
- name = Getattr(n, "name");
- type = Getattr(n, "type");
- ty = Swig_wrapped_var_type(type, varcref);
-
- if (flags & CWRAP_EXTEND) {
- String *sname = Swig_name_get(0, name);
- String *mangled = Swig_name_mangle(sname);
- call = Swig_cfunction_call(mangled, 0);
- cres = Swig_cresult(ty, Swig_cresult_name(), call);
- Setattr(n, "wrap:action", cres);
- Delete(mangled);
- Delete(sname);
- } else {
- String *nname = 0;
- if (Equal(nodeType(n), "constant")) {
- String *rawval = Getattr(n, "rawval");
- String *value = rawval ? rawval : Getattr(n, "value");
- nname = NewStringf("(%s)", value);
- } else {
- nname = SwigType_namestr(name);
- }
- call = Swig_wrapped_var_assign(type, nname, varcref);
- cres = Swig_cresult(ty, Swig_cresult_name(), call);
- Setattr(n, "wrap:action", cres);
- Delete(nname);
- }
-
- Setattr(n, "type", ty);
- Delattr(n, "parms");
- Delete(cres);
- Delete(call);
- Delete(ty);
- return SWIG_OK;
-}
diff --git a/contrib/tools/swig/Source/Swig/deprecate.c b/contrib/tools/swig/Source/Swig/deprecate.c
deleted file mode 100644
index 5783455e59..0000000000
--- a/contrib/tools/swig/Source/Swig/deprecate.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * deprecate.c
- *
- * The functions in this file are SWIG core functions that are deprecated
- * or which do not fit in nicely with everything else. Generally this means
- * that the function and/or API needs to be changed in some future release.
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-
-/* ---------------------------------------------------------------------
- * ParmList_is_compactdefargs()
- *
- * Returns 1 if the parameter list passed in is marked for compact argument
- * handling (by the "compactdefargs" attribute). Otherwise returns 0.
- * ---------------------------------------------------------------------- */
-
-/* Discussion:
-
- "compactdefargs" is a property set by the Parser to indicate special
- handling of default arguments. This property seems to be something that
- is associated with functions and methods rather than low-level ParmList
- objects. Therefore, I don't like the fact that this special purpose
- feature is bolted onto the side of ParmList objects.
-
- Proposed solution:
-
- 1. "compactdefargs" should be a feature set on function/method nodes
- instead of ParmList objects. For example, if you have a function,
- you would check the function node to see if the parameters are
- to be handled in this way.
-
-
- Difficulties:
-
- 1. This is used by functions in cwrap.c and emit.cxx, none of which
- are passed information about the function/method node. We might
- have to change the API of those functions to make this work correctly.
- For example:
-
- int emit_num_required(ParmList *parms)
-
- might become
-
- int emit_num_required(ParmList *parms, int compactargs)
-
-*/
-
-int ParmList_is_compactdefargs(ParmList *p) {
- int compactdefargs = 0;
-
- if (p) {
- compactdefargs = Getattr(p, "compactdefargs") ? 1 : 0;
-
- /* The "compactdefargs" attribute should only be set on the first parameter in the list.
- * However, sometimes an extra parameter is inserted at the beginning of the parameter list,
- * so we check the 2nd parameter too. */
- if (!compactdefargs) {
- Parm *nextparm = nextSibling(p);
- compactdefargs = (nextparm && Getattr(nextparm, "compactdefargs")) ? 1 : 0;
- }
- }
-
- return compactdefargs;
-}
-
-/* ---------------------------------------------------------------------
- * ParmList_errorstr()
- *
- * Generate a prototype string suitable for use in error/warning messages.
- * Similar to ParmList_protostr() but is also aware of hidden parameters.
- * ---------------------------------------------------------------------- */
-
-/* Discussion. This function is used to generate error messages, but take
- into account that there might be a hidden parameter. Although this involves
- parameter lists, it really isn't a core feature of swigparm.h or parms.c.
- This is because the "hidden" attribute of parameters is added elsewhere (cwrap.c).
-
- For now, this function is placed here because it doesn't really seem to fit in
- with the parms.c interface.
-
-*/
-
-String *ParmList_errorstr(ParmList *p) {
- String *out = NewStringEmpty();
- while (p) {
- if (Getattr(p,"hidden")) {
- p = nextSibling(p);
- } else {
- String *pstr = SwigType_str(Getattr(p, "type"), 0);
- Append(out, pstr);
- p = nextSibling(p);
- if (p) {
- Append(out, ",");
- }
- Delete(pstr);
- }
- }
- return out;
-}
diff --git a/contrib/tools/swig/Source/Swig/error.c b/contrib/tools/swig/Source/Swig/error.c
deleted file mode 100644
index efd644f9a8..0000000000
--- a/contrib/tools/swig/Source/Swig/error.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * error.c
- *
- * Error handling functions. These are used to issue warnings and
- * error messages.
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-#include <stdarg.h>
-#include <ctype.h>
-
-/* -----------------------------------------------------------------------------
- * Commentary on the warning filter.
- *
- * The warning filter is a string of numbers prefaced by (-) or (+) to
- * indicate whether or not a warning message is displayed. For example:
- *
- * "-304-201-140+210+201"
- *
- * The filter string is scanned left to right and the first occurrence
- * of a warning number is used to determine printing behavior.
- *
- * The same number may appear more than once in the string. For example, in the
- * above string, "201" appears twice. This simply means that warning 201
- * was disabled after it was previously enabled. This may only be temporary
- * setting--the first number may be removed later in which case the warning
- * is reenabled.
- * ----------------------------------------------------------------------------- */
-
-#if defined(_WIN32)
-# define DEFAULT_ERROR_MSG_FORMAT EMF_MICROSOFT
-#else
-# define DEFAULT_ERROR_MSG_FORMAT EMF_STANDARD
-#endif
-static ErrorMessageFormat msg_format = DEFAULT_ERROR_MSG_FORMAT;
-static int silence = 0; /* Silent operation */
-static String *filter = 0; /* Warning filter */
-static int warnall = 0;
-static int nwarning = 0;
-static int nerrors = 0;
-
-static int init_fmt = 0;
-static char wrn_wnum_fmt[64];
-static char wrn_nnum_fmt[64];
-static char err_line_fmt[64];
-static char err_eof_fmt[64];
-static char diag_line_fmt[64];
-static char diag_eof_fmt[64];
-
-static String *format_filename(const_String_or_char_ptr filename);
-
-/* -----------------------------------------------------------------------------
- * Swig_warning()
- *
- * Issue a warning message on stderr.
- * ----------------------------------------------------------------------------- */
-
-void Swig_warning(int wnum, const_String_or_char_ptr filename, int line, const char *fmt, ...) {
- String *out;
- char *msg;
- int wrn = 1;
- va_list ap;
- if (silence)
- return;
- if (!init_fmt)
- Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT);
-
- va_start(ap, fmt);
-
- out = NewStringEmpty();
- vPrintf(out, fmt, ap);
-
- msg = Char(out);
- if (isdigit((unsigned char) *msg)) {
- unsigned long result = strtoul(msg, &msg, 10);
- if (msg != Char(out)) {
- msg++;
- wnum = result;
- }
- }
-
- /* Check in the warning filter */
- if (filter) {
- char temp[32];
- char *c;
- char *f = Char(filter);
- sprintf(temp, "%d", wnum);
- while (*f != '\0' && (c = strstr(f, temp))) {
- if (*(c - 1) == '-') {
- wrn = 0; /* Warning disabled */
- break;
- }
- if (*(c - 1) == '+') {
- wrn = 1; /* Warning enabled */
- break;
- }
- f += strlen(temp);
- }
- }
- if (warnall || wrn) {
- String *formatted_filename = format_filename(filename);
- String *full_message = NewString("");
- if (wnum) {
- Printf(full_message, wrn_wnum_fmt, formatted_filename, line, wnum);
- } else {
- Printf(full_message, wrn_nnum_fmt, formatted_filename, line);
- }
- Printf(full_message, "%s", msg);
- Printv(stderr, full_message, NIL);
- nwarning++;
- Delete(full_message);
- Delete(formatted_filename);
- }
- Delete(out);
- va_end(ap);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_error()
- *
- * Issue an error message on stderr.
- * ----------------------------------------------------------------------------- */
-
-void Swig_error(const_String_or_char_ptr filename, int line, const char *fmt, ...) {
- va_list ap;
- String *formatted_filename = NULL;
- String *full_message = NULL;
-
- if (silence)
- return;
- if (!init_fmt)
- Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT);
-
- va_start(ap, fmt);
- formatted_filename = format_filename(filename);
- full_message = NewString("");
- if (line > 0) {
- Printf(full_message, err_line_fmt, formatted_filename, line);
- } else {
- Printf(full_message, err_eof_fmt, formatted_filename);
- }
- vPrintf(full_message, fmt, ap);
- Printv(stderr, full_message, NIL);
- va_end(ap);
- nerrors++;
- Delete(full_message);
- Delete(formatted_filename);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_error_count()
- *
- * Returns number of errors received.
- * ----------------------------------------------------------------------------- */
-
-int Swig_error_count(void) {
- return nerrors;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_error_silent()
- *
- * Set silent flag
- * ----------------------------------------------------------------------------- */
-
-void Swig_error_silent(int s) {
- silence = s;
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_warnfilter()
- *
- * Takes a comma separate list of warning numbers and puts in the filter.
- * ----------------------------------------------------------------------------- */
-
-void Swig_warnfilter(const_String_or_char_ptr wlist, int add) {
- char *c;
- char *cw;
- String *s;
- if (!filter)
- filter = NewStringEmpty();
-
- s = NewString("");
- Clear(s);
- cw = Char(wlist);
- while (*cw != '\0') {
- if (*cw != ' ') {
- Putc(*cw, s);
- }
- ++cw;
- }
- c = Char(s);
- c = strtok(c, ", ");
- while (c) {
- if (isdigit((int) *c) || (*c == '+') || (*c == '-')) {
- /* Even if c is a digit, the rest of the string might not be, eg in the case of typemap
- * warnings (a bit odd really), eg: %warnfilter(SWIGWARN_TYPEMAP_CHARLEAK_MSG) */
- if (add) {
- Insert(filter, 0, c);
- if (isdigit((int) *c)) {
- Insert(filter, 0, "-");
- }
- } else {
- char *temp = (char *)Malloc(sizeof(char)*strlen(c) + 2);
- if (isdigit((int) *c)) {
- sprintf(temp, "-%s", c);
- } else {
- strcpy(temp, c);
- }
- Replace(filter, temp, "", DOH_REPLACE_FIRST);
- Free(temp);
- }
- }
- c = strtok(NULL, ", ");
- }
- Delete(s);
-}
-
-void Swig_warnall(void) {
- warnall = 1;
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_warn_count()
- *
- * Return the number of warnings
- * ----------------------------------------------------------------------------- */
-
-int Swig_warn_count(void) {
- return nwarning;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_error_msg_format()
- *
- * Set the type of error/warning message display
- * ----------------------------------------------------------------------------- */
-
-void Swig_error_msg_format(ErrorMessageFormat format) {
- const char *error = "Error";
- const char *warning = "Warning";
-
- const char *fmt_eof = 0;
- const char *fmt_line = 0;
-
- /* here 'format' could be directly a string instead of an enum, but
- by now a switch is used to translated into one. */
- switch (format) {
- case EMF_MICROSOFT:
- fmt_line = "%s(%d) ";
- fmt_eof = "%s(999999) "; /* Is there a special character for EOF? Just use a large number. */
- break;
- case EMF_STANDARD:
- default:
- fmt_line = "%s:%d";
- fmt_eof = "%s:EOF";
- }
-
- sprintf(wrn_wnum_fmt, "%s: %s %%d: ", fmt_line, warning);
- sprintf(wrn_nnum_fmt, "%s: %s: ", fmt_line, warning);
- sprintf(err_line_fmt, "%s: %s: ", fmt_line, error);
- sprintf(err_eof_fmt, "%s: %s: ", fmt_eof, error);
- sprintf(diag_line_fmt, "%s: ", fmt_line);
- sprintf(diag_eof_fmt, "%s: ", fmt_eof);
-
- msg_format = format;
- init_fmt = 1;
-}
-
-/* -----------------------------------------------------------------------------
- * format_filename()
- *
- * Remove double backslashes in Windows filename paths for display
- * ----------------------------------------------------------------------------- */
-static String *format_filename(const_String_or_char_ptr filename) {
- String *formatted_filename = NewString(filename);
-#if defined(_WIN32)
- Replaceall(formatted_filename, "\\\\", "\\");
-#endif
- return formatted_filename;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_stringify_with_location()
- *
- * Return a string representation of any DOH object with line and file location
- * information in the appropriate error message format. The string representation
- * is enclosed within [] brackets after the line and file information.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_stringify_with_location(DOH *object) {
- String *str = NewStringEmpty();
-
- if (!init_fmt)
- Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT);
-
- if (object) {
- int line = Getline(object);
- String *formatted_filename = format_filename(Getfile(object));
- if (line > 0) {
- Printf(str, diag_line_fmt, formatted_filename, line);
- } else {
- Printf(str, diag_eof_fmt, formatted_filename);
- }
- if (Len(object) == 0) {
- Printf(str, "[EMPTY]");
- } else {
- Printf(str, "[%s]", object);
- }
- Delete(formatted_filename);
- } else {
- Printf(str, "[NULL]");
- }
-
- return str;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_diagnostic()
- *
- * Issue a diagnostic message on stdout.
- * ----------------------------------------------------------------------------- */
-
-void Swig_diagnostic(const_String_or_char_ptr filename, int line, const char *fmt, ...) {
- va_list ap;
- String *formatted_filename = NULL;
-
- if (!init_fmt)
- Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT);
-
- va_start(ap, fmt);
- formatted_filename = format_filename(filename);
- if (line > 0) {
- Printf(stdout, diag_line_fmt, formatted_filename, line);
- } else {
- Printf(stdout, diag_eof_fmt, formatted_filename);
- }
- vPrintf(stdout, fmt, ap);
- va_end(ap);
- Delete(formatted_filename);
-}
-
diff --git a/contrib/tools/swig/Source/Swig/extend.c b/contrib/tools/swig/Source/Swig/extend.c
deleted file mode 100644
index 23660c0ad8..0000000000
--- a/contrib/tools/swig/Source/Swig/extend.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * extend.c
- *
- * Extensions support (%extend)
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-#include "cparse.h"
-
-static Hash *extendhash = 0; /* Hash table of added methods */
-
-/* -----------------------------------------------------------------------------
- * Swig_extend_hash()
- *
- * Access the extend hash
- * ----------------------------------------------------------------------------- */
-Hash *Swig_extend_hash(void) {
- if (!extendhash)
- extendhash = NewHash();
- return extendhash;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_extend_merge()
- *
- * Extension merge. This function is used to handle the %extend directive
- * when it appears before a class definition. To handle this, the %extend
- * actually needs to take precedence. Therefore, we will selectively nuke symbols
- * from the current symbol table, replacing them with the added methods.
- * ----------------------------------------------------------------------------- */
-
-void Swig_extend_merge(Node *cls, Node *am) {
- Node *n;
- Node *csym;
-
- n = firstChild(am);
- while (n) {
- String *symname;
- if (Strcmp(nodeType(n),"constructor") == 0) {
- symname = Getattr(n,"sym:name");
- if (symname) {
- if (Strcmp(symname,Getattr(n,"name")) == 0) {
- /* If the name and the sym:name of a constructor are the same,
- then it hasn't been renamed. However---the name of the class
- itself might have been renamed so we need to do a consistency
- check here */
- if (Getattr(cls,"sym:name")) {
- Setattr(n,"sym:name", Getattr(cls,"sym:name"));
- }
- }
- }
- }
-
- symname = Getattr(n,"sym:name");
- DohIncref(symname);
- if ((symname) && (!Getattr(n,"error"))) {
- /* Remove node from its symbol table */
- Swig_symbol_remove(n);
- csym = Swig_symbol_add(symname,n);
- if (csym != n) {
- /* Conflict with previous definition. Nuke previous definition */
- String *e = NewStringEmpty();
- String *en = NewStringEmpty();
- String *ec = NewStringEmpty();
- Printf(ec,"Identifier '%s' redefined by %%extend (ignored),",symname);
- Printf(en,"%%extend definition of '%s'.",symname);
- SWIG_WARN_NODE_BEGIN(n);
- Swig_warning(WARN_PARSE_REDEFINED,Getfile(csym),Getline(csym),"%s\n",ec);
- Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en);
- SWIG_WARN_NODE_END(n);
- Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(csym),Getline(csym),ec,
- Getfile(n),Getline(n),en);
- Setattr(csym,"error",e);
- Delete(e);
- Delete(en);
- Delete(ec);
- Swig_symbol_remove(csym); /* Remove class definition */
- Swig_symbol_add(symname,n); /* Insert extend definition */
- }
- }
- n = nextSibling(n);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_extend_append_previous()
- * ----------------------------------------------------------------------------- */
-
-void Swig_extend_append_previous(Node *cls, Node *am) {
- Node *n, *ne;
- Node *pe = 0;
- Node *ae = 0;
-
- if (!am) return;
-
- n = firstChild(am);
- while (n) {
- ne = nextSibling(n);
- set_nextSibling(n,0);
- /* typemaps and fragments need to be prepended */
- if (((Cmp(nodeType(n),"typemap") == 0) || (Cmp(nodeType(n),"fragment") == 0))) {
- if (!pe) pe = Swig_cparse_new_node("extend");
- appendChild(pe, n);
- } else {
- if (!ae) ae = Swig_cparse_new_node("extend");
- appendChild(ae, n);
- }
- n = ne;
- }
- if (pe) prependChild(cls,pe);
- if (ae) appendChild(cls,ae);
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_extend_unused_check()
- *
- * Check for unused %extend. Special case, don't report unused
- * extensions for templates
- * ----------------------------------------------------------------------------- */
-
-void Swig_extend_unused_check(void) {
- Iterator ki;
-
- if (!extendhash) return;
- for (ki = First(extendhash); ki.key; ki = Next(ki)) {
- if (!Strchr(ki.key,'<')) {
- SWIG_WARN_NODE_BEGIN(ki.item);
- Swig_warning(WARN_PARSE_EXTEND_UNDEF,Getfile(ki.item), Getline(ki.item), "%%extend defined for an undeclared class %s.\n", SwigType_namestr(ki.key));
- SWIG_WARN_NODE_END(ki.item);
- }
- }
-}
-
diff --git a/contrib/tools/swig/Source/Swig/fragment.c b/contrib/tools/swig/Source/Swig/fragment.c
deleted file mode 100644
index 03b231fa13..0000000000
--- a/contrib/tools/swig/Source/Swig/fragment.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * fragment.c
- *
- * This file manages named code fragments. Code fragments are typically
- * used to hold helper-code that may or may not be included in the wrapper
- * file (depending on what features are actually used in the interface).
- *
- * By using fragments, it's possible to greatly reduce the amount of
- * wrapper code and to generate cleaner wrapper files.
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-#include "swigwarn.h"
-#include "cparse.h"
-
-static Hash *fragments = 0;
-static Hash *looking_fragments = 0;
-static int debug = 0;
-
-
-/* -----------------------------------------------------------------------------
- * Swig_fragment_register()
- *
- * Add a fragment. Use the original Node*, so, if something needs to be
- * changed, lang.cxx doesn't need to be touched again.
- * ----------------------------------------------------------------------------- */
-
-void Swig_fragment_register(Node *fragment) {
- if (Getattr(fragment, "emitonly")) {
- Swig_fragment_emit(fragment);
- return;
- } else {
- String *name = Copy(Getattr(fragment, "value"));
- String *type = Getattr(fragment, "type");
- if (type) {
- SwigType *rtype = SwigType_typedef_resolve_all(type);
- String *mangle = Swig_string_mangle(type);
- Append(name, mangle);
- Delete(mangle);
- Delete(rtype);
- if (debug)
- Printf(stdout, "register fragment %s %s\n", name, type);
- }
- if (!fragments) {
- fragments = NewHash();
- }
- if (!Getattr(fragments, name)) {
- String *section = Copy(Getattr(fragment, "section"));
- String *ccode = Copy(Getattr(fragment, "code"));
- Hash *kwargs = Getattr(fragment, "kwargs");
- Setmeta(ccode, "section", section);
- if (kwargs) {
- Setmeta(ccode, "kwargs", kwargs);
- }
- Setfile(ccode, Getfile(fragment));
- Setline(ccode, Getline(fragment));
- /* Replace $descriptor() macros */
- Swig_cparse_replace_descriptor(ccode);
- Setattr(fragments, name, ccode);
- if (debug)
- Printf(stdout, "registering fragment %s %s\n", name, section);
- Delete(section);
- Delete(ccode);
- }
- Delete(name);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_fragment_emit()
- *
- * Emit a fragment
- * ----------------------------------------------------------------------------- */
-
-static
-char *char_index(char *str, char c) {
- while (*str && (c != *str))
- ++str;
- return (c == *str) ? str : 0;
-}
-
-void Swig_fragment_emit(Node *n) {
- String *code;
- char *pc, *tok;
- String *t;
- String *mangle = 0;
- String *name = 0;
- String *type = 0;
-
- name = Getattr(n, "value");
- if (!name) {
- name = n;
- }
-
- if (!fragments) {
- Swig_warning(WARN_FRAGMENT_NOT_FOUND, Getfile(n), Getline(n), "Fragment '%s' not found.\n", name);
- return;
- }
-
- type = Getattr(n, "type");
- if (type) {
- mangle = Swig_string_mangle(type);
- }
-
- if (debug)
- Printf(stdout, "looking fragment %s %s\n", name, type);
- t = Copy(name);
- tok = Char(t);
- pc = char_index(tok, ',');
- if (pc)
- *pc = 0;
- while (tok) {
- String *name = NewString(tok);
- if (mangle)
- Append(name, mangle);
- if (looking_fragments && Getattr(looking_fragments, name)) {
- return;
- }
- code = Getattr(fragments, name);
- if (debug)
- Printf(stdout, "looking subfragment %s\n", name);
- if (code && (Strcmp(code, "ignore") != 0)) {
- String *section = Getmeta(code, "section");
- Hash *nn = Getmeta(code, "kwargs");
- if (!looking_fragments)
- looking_fragments = NewHash();
- Setattr(looking_fragments, name, "1");
- while (nn) {
- if (Equal(Getattr(nn, "name"), "fragment")) {
- if (debug)
- Printf(stdout, "emitting fragment %s %s\n", nn, type);
- Setfile(nn, Getfile(n));
- Setline(nn, Getline(n));
- Swig_fragment_emit(nn);
- }
- nn = nextSibling(nn);
- }
- if (section) {
- File *f = Swig_filebyname(section);
- if (!f) {
- Swig_error(Getfile(code), Getline(code), "Bad section '%s' in %%fragment declaration for code fragment '%s'\n", section, name);
- } else {
- if (debug)
- Printf(stdout, "emitting subfragment %s %s\n", name, section);
- if (debug)
- Printf(f, "/* begin fragment %s */\n", name);
- Printf(f, "%s\n", code);
- if (debug)
- Printf(f, "/* end fragment %s */\n\n", name);
- Setattr(fragments, name, "ignore");
- Delattr(looking_fragments, name);
- }
- }
- } else if (!code && type) {
- SwigType *rtype = SwigType_typedef_resolve_all(type);
- if (!Equal(type, rtype)) {
- String *name = Copy(Getattr(n, "value"));
- String *mangle = Swig_string_mangle(type);
- Append(name, mangle);
- Setfile(name, Getfile(n));
- Setline(name, Getline(n));
- Swig_fragment_emit(name);
- Delete(mangle);
- Delete(name);
- }
- Delete(rtype);
- }
-
- if (!code) {
- Swig_warning(WARN_FRAGMENT_NOT_FOUND, Getfile(n), Getline(n), "Fragment '%s' not found.\n", name);
- }
- tok = pc ? pc + 1 : 0;
- if (tok) {
- pc = char_index(tok, ',');
- if (pc)
- *pc = 0;
- }
- Delete(name);
- }
- Delete(t);
-}
diff --git a/contrib/tools/swig/Source/Swig/getopt.c b/contrib/tools/swig/Source/Swig/getopt.c
deleted file mode 100644
index 7791d13f72..0000000000
--- a/contrib/tools/swig/Source/Swig/getopt.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * getopt.c
- *
- * Handles the parsing of command line options. This is particularly nasty
- * compared to other utilities given that command line options can potentially
- * be read by many different modules within SWIG. Thus, in order to make sure
- * there are no unrecognized options, each module is required to "mark"
- * the options that it uses. Afterwards, we can make a quick scan to make
- * sure there are no unmarked options.
- *
- * TODO:
- * Should have cleaner error handling in general.
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-
-static char **args;
-static int numargs;
-static int *marked;
-
-/* -----------------------------------------------------------------------------
- * Swig_init_args()
- *
- * Initialize the argument list handler.
- * ----------------------------------------------------------------------------- */
-
-void Swig_init_args(int argc, char **argv) {
- assert(argc > 0);
- assert(argv);
-
- numargs = argc;
- args = argv;
- marked = (int *) Calloc(numargs, sizeof(int));
- marked[0] = 1;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_mark_arg()
- *
- * Marks an argument as being parsed.
- * ----------------------------------------------------------------------------- */
-
-void Swig_mark_arg(int n) {
- assert(marked);
- assert((n >= 0) && (n < numargs));
- marked[n] = 1;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_check_marked()
- *
- * Checks to see if argument has been picked up.
- * ----------------------------------------------------------------------------- */
-
-int Swig_check_marked(int n) {
- assert((n >= 0) && (n < numargs));
- return marked[n];
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_check_options()
- *
- * Checkers for unprocessed command line options and errors.
- * ----------------------------------------------------------------------------- */
-
-void Swig_check_options(int check_input) {
- int error = 0;
- int i;
- int max = check_input ? numargs - 1 : numargs;
- assert(marked);
- for (i = 1; i < max; i++) {
- if (!marked[i]) {
- Printf(stderr, "swig error : Unrecognized option %s\n", args[i]);
- error = 1;
- }
- }
- if (error) {
- Printf(stderr, "Use 'swig -help' for available options.\n");
- Exit(EXIT_FAILURE);
- }
- if (check_input && marked[numargs - 1]) {
- Printf(stderr, "Must specify an input file. Use -help for available options.\n");
- Exit(EXIT_FAILURE);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_arg_error()
- *
- * Generates a generic error message and exits.
- * ----------------------------------------------------------------------------- */
-
-void Swig_arg_error(void) {
- Printf(stderr, "SWIG : Unable to parse command line options.\n");
- Printf(stderr, "Use 'swig -help' for available options.\n");
- Exit(EXIT_FAILURE);
-}
diff --git a/contrib/tools/swig/Source/Swig/include.c b/contrib/tools/swig/Source/Swig/include.c
deleted file mode 100644
index c153ac9b7a..0000000000
--- a/contrib/tools/swig/Source/Swig/include.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * include.c
- *
- * The functions in this file are used to manage files in the SWIG library.
- * General purpose functions for opening, including, and retrieving pathnames
- * are provided.
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-
-static List *directories = 0; /* List of include directories */
-static String *lastpath = 0; /* Last file that was included */
-static List *pdirectories = 0; /* List of pushed directories */
-static int dopush = 1; /* Whether to push directories */
-static int file_debug = 0;
-
-/* This functions determine whether to push/pop dirs in the preprocessor */
-void Swig_set_push_dir(int push) {
- dopush = push;
-}
-
-int Swig_get_push_dir(void) {
- return dopush;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_add_directory()
- *
- * Adds a directory to the SWIG search path.
- * ----------------------------------------------------------------------------- */
-
-List *Swig_add_directory(const_String_or_char_ptr dirname) {
- String *adirname;
- if (!directories)
- directories = NewList();
- assert(directories);
- if (dirname) {
- adirname = NewString(dirname);
- Append(directories,adirname);
- Delete(adirname);
- }
- return directories;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_push_directory()
- *
- * Inserts a directory at the front of the SWIG search path. This is used by
- * the preprocessor to grab files in the same directory as other included files.
- * ----------------------------------------------------------------------------- */
-
-void Swig_push_directory(const_String_or_char_ptr dirname) {
- String *pdirname;
- if (!Swig_get_push_dir())
- return;
- if (!pdirectories)
- pdirectories = NewList();
- assert(pdirectories);
- pdirname = NewString(dirname);
- assert(pdirname);
- Insert(pdirectories,0,pdirname);
- Delete(pdirname);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_pop_directory()
- *
- * Pops a directory off the front of the SWIG search path. This is used by
- * the preprocessor.
- * ----------------------------------------------------------------------------- */
-
-void Swig_pop_directory(void) {
- if (!Swig_get_push_dir())
- return;
- if (!pdirectories)
- return;
- Delitem(pdirectories, 0);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_last_file()
- *
- * Returns the full pathname of the last file opened.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_last_file(void) {
- assert(lastpath);
- return lastpath;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_search_path_any()
- *
- * Returns a list of the current search paths.
- * ----------------------------------------------------------------------------- */
-
-static List *Swig_search_path_any(int syspath) {
- String *filename;
- List *slist;
- int i, ilen;
-
- slist = NewList();
- assert(slist);
- filename = NewStringEmpty();
- assert(filename);
- Printf(filename, ".%s", SWIG_FILE_DELIMITER);
- Append(slist, filename);
- Delete(filename);
-
- /* If there are any pushed directories. Add them first */
- if (pdirectories) {
- ilen = Len(pdirectories);
- for (i = 0; i < ilen; i++) {
- filename = NewString(Getitem(pdirectories,i));
- Append(filename,SWIG_FILE_DELIMITER);
- Append(slist,filename);
- Delete(filename);
- }
- }
- /* Add system directories next */
- ilen = Len(directories);
- for (i = 0; i < ilen; i++) {
- filename = NewString(Getitem(directories,i));
- Append(filename,SWIG_FILE_DELIMITER);
- if (syspath) {
- /* If doing a system include, put the system directories first */
- Insert(slist,i,filename);
- } else {
- /* Otherwise, just put the system directories after the pushed directories (if any) */
- Append(slist,filename);
- }
- Delete(filename);
- }
- return slist;
-}
-
-List *Swig_search_path(void) {
- return Swig_search_path_any(0);
-}
-
-
-
-/* -----------------------------------------------------------------------------
- * Swig_open()
- *
- * open a file, optionally looking for it in the include path. Returns an open
- * FILE * on success.
- * ----------------------------------------------------------------------------- */
-
-static FILE *Swig_open_file(const_String_or_char_ptr name, int sysfile, int use_include_path) {
- FILE *f;
- String *filename;
- List *spath = 0;
- char *cname;
- int i, ilen, nbytes;
- char bom[3];
-
- if (!directories)
- directories = NewList();
- assert(directories);
-
- cname = Char(name);
- filename = NewString(cname);
- assert(filename);
- if (file_debug) {
- Printf(stdout, " Open: %s\n", filename);
- }
- f = fopen(Char(filename), "r");
- if (!f && use_include_path) {
- spath = Swig_search_path_any(sysfile);
- ilen = Len(spath);
- for (i = 0; i < ilen; i++) {
- Clear(filename);
- Printf(filename, "%s%s", Getitem(spath, i), cname);
- f = fopen(Char(filename), "r");
- if (f)
- break;
- }
- Delete(spath);
- }
- if (f) {
- Delete(lastpath);
- lastpath = filename;
-
- /* Skip the UTF-8 BOM if it's present */
- nbytes = (int)fread(bom, 1, 3, f);
- if (nbytes == 3 && bom[0] == (char)0xEF && bom[1] == (char)0xBB && bom[2] == (char)0xBF) {
- /* skip */
- } else {
- fseek(f, 0, SEEK_SET);
- }
- }
- return f;
-}
-
-/* Open a file - searching the include paths to find it */
-FILE *Swig_include_open(const_String_or_char_ptr name) {
- return Swig_open_file(name, 0, 1);
-}
-
-/* Open a file - does not use include paths to find it */
-FILE *Swig_open(const_String_or_char_ptr name) {
- return Swig_open_file(name, 0, 0);
-}
-
-
-
-/* -----------------------------------------------------------------------------
- * Swig_read_file()
- *
- * Reads data from an open FILE * and returns it as a string.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_read_file(FILE *f) {
- int len;
- char buffer[4096];
- String *str = NewStringEmpty();
-
- assert(str);
- while (fgets(buffer, 4095, f)) {
- Append(str, buffer);
- }
- len = Len(str);
- /* Add a newline if not present on last line -- the preprocessor seems to
- * rely on \n and not EOF terminating lines */
- if (len) {
- char *cstr = Char(str);
- if (cstr[len - 1] != '\n') {
- Append(str, "\n");
- }
- }
- return str;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_include()
- *
- * Opens a file and returns it as a string.
- * ----------------------------------------------------------------------------- */
-
-static String *Swig_include_any(const_String_or_char_ptr name, int sysfile) {
- FILE *f;
- String *str;
- String *file;
-
- f = Swig_open_file(name, sysfile, 1);
- if (!f)
- return 0;
- str = Swig_read_file(f);
- fclose(f);
- Seek(str, 0, SEEK_SET);
- file = Copy(Swig_last_file());
- Setfile(str, file);
- Delete(file);
- Setline(str, 1);
- return str;
-}
-
-String *Swig_include(const_String_or_char_ptr name) {
- return Swig_include_any(name, 0);
-}
-
-String *Swig_include_sys(const_String_or_char_ptr name) {
- return Swig_include_any(name, 1);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_insert_file()
- *
- * Copies the contents of a file into another file
- * ----------------------------------------------------------------------------- */
-
-int Swig_insert_file(const_String_or_char_ptr filename, File *outfile) {
- char buffer[4096];
- int nbytes;
- FILE *f = Swig_include_open(filename);
-
- if (!f)
- return -1;
- while ((nbytes = Read(f, buffer, 4096)) > 0) {
- Write(outfile, buffer, nbytes);
- }
- fclose(f);
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_register_filebyname()
- *
- * Register a "named" file with the core. Named files can become targets
- * for %insert directives and other SWIG operations. This function takes
- * the place of the f_header, f_wrapper, f_init, and other global variables
- * in SWIG1.1
- * ----------------------------------------------------------------------------- */
-
-static Hash *named_files = 0;
-
-void Swig_register_filebyname(const_String_or_char_ptr filename, File *outfile) {
- if (!named_files)
- named_files = NewHash();
- Setattr(named_files, filename, outfile);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_filebyname()
- *
- * Get a named file
- * ----------------------------------------------------------------------------- */
-
-File *Swig_filebyname(const_String_or_char_ptr filename) {
- if (!named_files)
- return 0;
- return Getattr(named_files, filename);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_file_extension()
- *
- * Returns the extension of a file
- * ----------------------------------------------------------------------------- */
-
-String *Swig_file_extension(const_String_or_char_ptr filename) {
- String *name = Swig_file_filename(filename);
- const char *c = strrchr(Char(name), '.');
- String *extension = c ? NewString(c) : NewString("");
- Delete(name);
- return extension;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_file_basename()
- *
- * Returns the filename with the extension removed.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_file_basename(const_String_or_char_ptr filename) {
- String *extension = Swig_file_extension(filename);
- String *basename = NewStringWithSize(filename, Len(filename) - Len(extension));
- Delete(extension);
- return basename;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_file_filename()
- *
- * Return the file name with any leading path stripped off
- * ----------------------------------------------------------------------------- */
-String *Swig_file_filename(const_String_or_char_ptr filename) {
- const char *delim = SWIG_FILE_DELIMITER;
- const char *c = strrchr(Char(filename), *delim);
- return c ? NewString(c + 1) : NewString(filename);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_file_dirname()
- *
- * Return the name of the directory associated with a file
- * ----------------------------------------------------------------------------- */
-String *Swig_file_dirname(const_String_or_char_ptr filename) {
- const char *delim = SWIG_FILE_DELIMITER;
- const char *c = strrchr(Char(filename), *delim);
- return c ? NewStringWithSize(filename, (int)(c - Char(filename) + 1)) : NewString("");
-}
-
-/*
- * Swig_file_debug()
- */
-void Swig_file_debug_set(void) {
- file_debug = 1;
-}
diff --git a/contrib/tools/swig/Source/Swig/misc.c b/contrib/tools/swig/Source/Swig/misc.c
deleted file mode 100644
index 7d1119c5e2..0000000000
--- a/contrib/tools/swig/Source/Swig/misc.c
+++ /dev/null
@@ -1,1569 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * misc.c
- *
- * Miscellaneous functions that don't really fit anywhere else.
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-#include <errno.h>
-#include <ctype.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#ifdef _WIN32
-#include <direct.h>
-#ifndef S_ISDIR
-#define S_ISDIR(mode) (((mode) & S_IFDIR) == S_IFDIR)
-#endif
-#endif
-
-static char *fake_version = 0;
-
-/* -----------------------------------------------------------------------------
- * Swig_copy_string()
- *
- * Duplicate a NULL-terminate string given as a char *.
- * ----------------------------------------------------------------------------- */
-
-char *Swig_copy_string(const char *s) {
- char *c = 0;
- if (s) {
- c = (char *) Malloc(strlen(s) + 1);
- strcpy(c, s);
- }
- return c;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_set_fakeversion()
- *
- * Version string override
- * ----------------------------------------------------------------------------- */
-
-void Swig_set_fakeversion(const char *version) {
- fake_version = Swig_copy_string(version);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_package_version()
- *
- * Return the package string containing the version number
- * ----------------------------------------------------------------------------- */
-
-const char *Swig_package_version(void) {
- return fake_version ? fake_version : PACKAGE_VERSION;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_package_version_hex()
- *
- * Return the package version in hex format "0xAABBCC" such as "0x040200" for 4.2.0
- * ----------------------------------------------------------------------------- */
-
-String *Swig_package_version_hex(void) {
- String *package_version = NewString(Swig_package_version());
- char *token = strtok(Char(package_version), ".");
- String *vers = NewString("SWIG_VERSION 0x");
- int count = 0;
- while (token) {
- int len = (int)strlen(token);
- assert(len == 1 || len == 2);
- Printf(vers, "%s%s", (len == 1) ? "0" : "", token);
- token = strtok(NULL, ".");
- count++;
- }
- Delete(package_version);
- assert(count == 3); /* Check version format is correct */
- return vers;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_obligatory_macros()
- *
- * Generates the SWIG_VERSION and SWIGXXX macros where XXX is the target language
- * name (must be provided uppercase).
- * ----------------------------------------------------------------------------- */
-
-void Swig_obligatory_macros(String *f_runtime, const char *language) {
- String *version_hex = Swig_package_version_hex();
- Printf(f_runtime, "\n\n");
- Printf(f_runtime, "#define %s\n", version_hex);
- Printf(f_runtime, "#define SWIG%s\n", language);
- Delete(version_hex);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_banner()
- *
- * Emits the SWIG identifying banner for the C/C++ wrapper file.
- * ----------------------------------------------------------------------------- */
-
-void Swig_banner(File *f) {
- Printf(f, "/* ----------------------------------------------------------------------------\n");
- Swig_banner_target_lang(f, " *");
- Printf(f, " * ----------------------------------------------------------------------------- */\n");
-
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_banner_target_lang()
- *
- * Emits a SWIG identifying banner in the target language
- * ----------------------------------------------------------------------------- */
-
-void Swig_banner_target_lang(File *f, const_String_or_char_ptr commentchar) {
- Printf(f, "%s This file was automatically generated by SWIG (https://www.swig.org).\n", commentchar);
- Printf(f, "%s Version %s\n", commentchar, Swig_package_version());
- Printf(f, "%s\n", commentchar);
- Printf(f, "%s Do not make changes to this file unless you know what you are doing - modify\n", commentchar);
- Printf(f, "%s the SWIG interface file instead.\n", commentchar);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_strip_c_comments()
- *
- * Return a new string with C comments stripped from the input string. NULL is
- * returned if there aren't any comments.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_strip_c_comments(const String *s) {
- const char *c = Char(s);
- const char *comment_begin = 0;
- const char *comment_end = 0;
- String *stripped = 0;
-
- while (*c) {
- if (!comment_begin && *c == '/') {
- ++c;
- if (!*c)
- break;
- if (*c == '*')
- comment_begin = c-1;
- } else if (comment_begin && !comment_end && *c == '*') {
- ++c;
- if (*c == '/') {
- comment_end = c;
- break;
- }
- }
- ++c;
- }
-
- if (comment_begin && comment_end) {
- int size = (int)(comment_begin - Char(s));
- String *stripmore = 0;
- stripped = NewStringWithSize(s, size);
- Printv(stripped, comment_end + 1, NIL);
- do {
- stripmore = Swig_strip_c_comments(stripped);
- if (stripmore) {
- Delete(stripped);
- stripped = stripmore;
- }
- } while (stripmore);
- }
- return stripped;
-}
-
-/* -----------------------------------------------------------------------------
- * is_directory()
- * ----------------------------------------------------------------------------- */
-static int is_directory(String *directory) {
- int last = Len(directory) - 1;
- int statres;
- struct stat st;
- char *dir = Char(directory);
- if (dir[last] == SWIG_FILE_DELIMITER[0]) {
- /* remove trailing slash - can cause S_ISDIR to fail on Windows, at least */
- dir[last] = 0;
- statres = stat(dir, &st);
- dir[last] = SWIG_FILE_DELIMITER[0];
- } else {
- statres = stat(dir, &st);
- }
- return (statres == 0 && S_ISDIR(st.st_mode));
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_new_subdirectory()
- *
- * Create the subdirectory only if the basedirectory already exists as a directory.
- * basedirectory can be empty to indicate current directory but not NULL.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_new_subdirectory(String *basedirectory, String *subdirectory) {
- String *error = 0;
- int current_directory = Len(basedirectory) == 0;
-
- if (current_directory || is_directory(basedirectory)) {
- Iterator it;
- String *dir = NewString(basedirectory);
- List *subdirs = Split(subdirectory, SWIG_FILE_DELIMITER[0], INT_MAX);
-
- for (it = First(subdirs); it.item; it = Next(it)) {
- int result;
- String *subdirectory = it.item;
- Printf(dir, "%s", subdirectory);
-#ifdef _WIN32
- result = _mkdir(Char(dir));
-#else
- result = mkdir(Char(dir), 0777);
-#endif
- if (result != 0 && errno != EEXIST) {
- error = NewStringf("Cannot create directory %s: %s", dir, strerror(errno));
- break;
- }
- if (!is_directory(dir)) {
- error = NewStringf("Cannot create directory %s: it may already exist but not be a directory", dir);
- break;
- }
- Printf(dir, SWIG_FILE_DELIMITER);
- }
- } else {
- error = NewStringf("Cannot create subdirectory %s under the base directory %s. Either the base does not exist as a directory or it is not readable.", subdirectory, basedirectory);
- }
- return error;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_filename_correct()
- *
- * Corrects filename paths by removing duplicate delimiters and on non-unix
- * systems use the correct delimiter across the whole name.
- * ----------------------------------------------------------------------------- */
-
-void Swig_filename_correct(String *filename) {
- int network_path = 0;
- if (Len(filename) >= 2) {
- const char *fname = Char(filename);
- if (fname[0] == '\\' && fname[1] == '\\')
- network_path = 1;
- if (fname[0] == '/' && fname[1] == '/')
- network_path = 1;
- }
-#if defined(_WIN32)
- /* accept Unix path separator on non-Unix systems */
- Replaceall(filename, "/", SWIG_FILE_DELIMITER);
-#endif
-#if defined(__CYGWIN__)
- /* accept Windows path separator in addition to Unix path separator */
- Replaceall(filename, "\\", SWIG_FILE_DELIMITER);
-#endif
- /* remove all duplicate file name delimiters */
- while (Replaceall(filename, SWIG_FILE_DELIMITER SWIG_FILE_DELIMITER, SWIG_FILE_DELIMITER)) {
- }
- /* Network paths can start with a double slash on Windows - unremove the duplicate slash we just removed */
- if (network_path)
- Insert(filename, 0, SWIG_FILE_DELIMITER);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_filename_escape()
- *
- * Escapes backslashes in filename - for Windows
- * ----------------------------------------------------------------------------- */
-
-String *Swig_filename_escape(String *filename) {
- String *adjusted_filename = Copy(filename);
- Swig_filename_correct(adjusted_filename);
-#if defined(_WIN32) /* Note not on Cygwin else filename is displayed with double '/' */
- Replaceall(adjusted_filename, "\\", "\\\\");
-#endif
- return adjusted_filename;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_filename_escape()
- *
- * Escapes spaces in filename - for Makefiles
- * ----------------------------------------------------------------------------- */
-
-String *Swig_filename_escape_space(String *filename) {
- String *adjusted_filename = Copy(filename);
- Swig_filename_correct(adjusted_filename);
- Replaceall(adjusted_filename, " ", "\\ ");
- return adjusted_filename;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_filename_unescape()
- *
- * Remove double backslash escaping in filename - for Windows
- * ----------------------------------------------------------------------------- */
-
-void Swig_filename_unescape(String *filename) {
- (void)filename;
-#if defined(_WIN32)
- Replaceall(filename, "\\\\", "\\");
-#endif
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_storage_isextern()
- *
- * Determine if the storage class specifier is extern (but not externc)
- * ----------------------------------------------------------------------------- */
-
-int Swig_storage_isextern(Node *n) {
- const String *storage = Getattr(n, "storage");
- return storage ? Strcmp(storage, "extern") == 0 || Strncmp(storage, "extern ", 7) == 0 : 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_storage_isexternc()
- *
- * Determine if the storage class specifier is externc (but not plain extern)
- * ----------------------------------------------------------------------------- */
-
-int Swig_storage_isexternc(Node *n) {
- const String *storage = Getattr(n, "storage");
- return storage ? Strcmp(storage, "externc") == 0 || Strncmp(storage, "externc ", 8) == 0 : 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_storage_isstatic_custom()
- *
- * Determine if the storage class specifier is static
- * ----------------------------------------------------------------------------- */
-
-int Swig_storage_isstatic_custom(Node *n, const_String_or_char_ptr storage_name) {
- const String *storage = Getattr(n, storage_name);
- return storage ? Strncmp(storage, "static", 6) == 0 : 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_storage_isstatic()
- *
- * Determine if the storage class specifier is static
- * ----------------------------------------------------------------------------- */
-
-int Swig_storage_isstatic(Node *n) {
- return Swig_storage_isstatic_custom(n, "storage");
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_string_escape()
- *
- * Takes a string object and produces a string with escape codes added to it.
- * Octal escaping is used.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_string_escape(String *s) {
- String *ns;
- int c;
- ns = NewStringEmpty();
-
- while ((c = Getc(s)) != EOF) {
- if (c == '\n') {
- Printf(ns, "\\n");
- } else if (c == '\r') {
- Printf(ns, "\\r");
- } else if (c == '\t') {
- Printf(ns, "\\t");
- } else if (c == '\\') {
- Printf(ns, "\\\\");
- } else if (c == '\'') {
- Printf(ns, "\\'");
- } else if (c == '\"') {
- Printf(ns, "\\\"");
- } else if (c == ' ') {
- Putc(c, ns);
- } else if (!isgraph(c)) {
- if (c < 0)
- c += UCHAR_MAX + 1;
- Printf(ns, "\\%o", c);
- } else {
- Putc(c, ns);
- }
- }
- return ns;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_string_hexescape()
- *
- * Takes a string object and produces a string with escape codes added to it.
- * Hex escaping is used.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_string_hexescape(String *s) {
- String *ns;
- int c;
- ns = NewStringEmpty();
-
- while ((c = Getc(s)) != EOF) {
- if (c == '\n') {
- Printf(ns, "\\n");
- } else if (c == '\r') {
- Printf(ns, "\\r");
- } else if (c == '\t') {
- Printf(ns, "\\t");
- } else if (c == '\\') {
- Printf(ns, "\\\\");
- } else if (c == '\'') {
- Printf(ns, "\\'");
- } else if (c == '\"') {
- Printf(ns, "\\\"");
- } else if (c == ' ') {
- Putc(c, ns);
- } else if (!isgraph(c)) {
- if (c < 0)
- c += UCHAR_MAX + 1;
- Printf(ns, "\\x%X", c);
- } else {
- Putc(c, ns);
- }
- }
- return ns;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_string_upper()
- *
- * Takes a string object and returns a copy that is uppercase
- * ----------------------------------------------------------------------------- */
-
-String *Swig_string_upper(String *s) {
- String *ns;
- int c;
- ns = NewStringEmpty();
-
- Seek(s, 0, SEEK_SET);
- while ((c = Getc(s)) != EOF) {
- Putc(toupper(c), ns);
- }
- return ns;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_string_lower()
- *
- * Takes a string object and returns a copy that is lowercase
- * ----------------------------------------------------------------------------- */
-
-String *Swig_string_lower(String *s) {
- String *ns;
- int c;
- ns = NewStringEmpty();
-
- Seek(s, 0, SEEK_SET);
- while ((c = Getc(s)) != EOF) {
- Putc(tolower(c), ns);
- }
- return ns;
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_string_title()
- *
- * Takes a string object and returns a copy that is lowercase with first letter
- * capitalized
- * ----------------------------------------------------------------------------- */
-
-String *Swig_string_title(String *s) {
- String *ns;
- int first = 1;
- int c;
- ns = NewStringEmpty();
-
- Seek(s, 0, SEEK_SET);
- while ((c = Getc(s)) != EOF) {
- Putc(first ? toupper(c) : tolower(c), ns);
- first = 0;
- }
- return ns;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_string_ccase()
- *
- * Takes a string object and returns a copy that is lowercase with the first
- * letter capitalized and the one following '_', which are removed.
- *
- * camel_case -> CamelCase
- * camelCase -> CamelCase
- * ----------------------------------------------------------------------------- */
-
-String *Swig_string_ccase(String *s) {
- String *ns;
- int first = 1;
- int c;
- ns = NewStringEmpty();
-
- Seek(s, 0, SEEK_SET);
- while ((c = Getc(s)) != EOF) {
- if (c == '_') {
- first = 1;
- continue;
- }
- Putc(first ? toupper(c) : c, ns);
- first = 0;
- }
- return ns;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_string_lccase()
- *
- * Takes a string object and returns a copy with the character after
- * each '_' capitalised, and the '_' removed. The first character is
- * also forced to lowercase.
- *
- * camel_case -> camelCase
- * CamelCase -> camelCase
- * ----------------------------------------------------------------------------- */
-
-String *Swig_string_lccase(String *s) {
- String *ns;
- int first = 1;
- int after_underscore = 0;
- int c;
- ns = NewStringEmpty();
-
- Seek(s, 0, SEEK_SET);
- while ((c = Getc(s)) != EOF) {
- if (c == '_') {
- after_underscore = 1;
- continue;
- }
- if (first) {
- Putc(tolower(c), ns);
- first = 0;
- } else {
- Putc(after_underscore ? toupper(c) : c, ns);
- }
- after_underscore = 0;
- }
- return ns;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_string_ucase()
- *
- * This is the reverse case of ccase, ie
- *
- * CamelCase -> camel_case
- * get2D -> get_2d
- * asFloat2 -> as_float2
- * ----------------------------------------------------------------------------- */
-
-String *Swig_string_ucase(String *s) {
- String *ns;
- int c;
- int lastC = 0;
- int nextC = 0;
- int underscore = 0;
- ns = NewStringEmpty();
-
- /* We insert a underscore when:
- 1. Lower case char followed by upper case char
- getFoo > get_foo; getFOo > get_foo; GETFOO > getfoo
- 2. Number preceded by char and not end of string
- get2D > get_2d; get22D > get_22d; GET2D > get_2d
- but:
- asFloat2 > as_float2
- */
-
- Seek(s, 0, SEEK_SET);
-
- while ((c = Getc(s)) != EOF) {
- nextC = Getc(s); Ungetc(nextC, s);
- if (isdigit(c) && isalpha(lastC) && nextC != EOF)
- underscore = 1;
- else if (isupper(c) && isalpha(lastC) && !isupper(lastC))
- underscore = 1;
-
- lastC = c;
-
- if (underscore) {
- Putc('_', ns);
- underscore = 0;
- }
-
- Putc(tolower(c), ns);
- }
- return ns;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_string_first_upper()
- *
- * Make the first character in the string uppercase, leave all the
- * rest the same. This is used by the Ruby module to provide backwards
- * compatibility with the old way of naming classes and constants. For
- * more info see the Ruby documentation.
- *
- * firstUpper -> FirstUpper
- * ----------------------------------------------------------------------------- */
-
-String *Swig_string_first_upper(String *s) {
- String *ns = NewStringEmpty();
- char *cs = Char(s);
- if (cs && cs[0] != 0) {
- Putc(toupper((int)cs[0]), ns);
- Append(ns, cs + 1);
- }
- return ns;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_string_first_lower()
- *
- * Make the first character in the string lowercase, leave all the
- * rest the same. This is used by the Ruby module to provide backwards
- * compatibility with the old way of naming classes and constants. For
- * more info see the Ruby documentation.
- *
- * firstLower -> FirstLower
- * ----------------------------------------------------------------------------- */
-
-String *Swig_string_first_lower(String *s) {
- String *ns = NewStringEmpty();
- char *cs = Char(s);
- if (cs && cs[0] != 0) {
- Putc(tolower((int)cs[0]), ns);
- Append(ns, cs + 1);
- }
- return ns;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_string_schemify()
- *
- * Replace underscores with dashes, to make identifiers look nice to Schemers.
- *
- * under_scores -> under-scores
- * ----------------------------------------------------------------------------- */
-
-String *Swig_string_schemify(String *s) {
- String *ns = NewString(s);
- Replaceall(ns, "_", "-");
- return ns;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_string_typecode()
- *
- * Takes a string with possible type-escapes in it and replaces them with
- * real C datatypes.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_string_typecode(String *s) {
- String *ns;
- int c;
- String *tc;
- ns = NewStringEmpty();
- while ((c = Getc(s)) != EOF) {
- if (c == '`') {
- String *str = 0;
- tc = NewStringEmpty();
- while ((c = Getc(s)) != EOF) {
- if (c == '`')
- break;
- Putc(c, tc);
- }
- str = SwigType_str(tc, 0);
- Append(ns, str);
- Delete(str);
- } else {
- Putc(c, ns);
- if (c == '\'') {
- while ((c = Getc(s)) != EOF) {
- Putc(c, ns);
- if (c == '\'')
- break;
- if (c == '\\') {
- c = Getc(s);
- Putc(c, ns);
- }
- }
- } else if (c == '\"') {
- while ((c = Getc(s)) != EOF) {
- Putc(c, ns);
- if (c == '\"')
- break;
- if (c == '\\') {
- c = Getc(s);
- Putc(c, ns);
- }
- }
- }
- }
- }
- return ns;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_string_mangle()
- *
- * Take a string and mangle it by stripping all non-valid C identifier
- * characters.
- *
- * This routine skips unnecessary blank spaces, therefore mangling
- * 'char *' and 'char*', 'std::pair<int, int >' and
- * 'std::pair<int,int>', produce the same result.
- *
- * However, note that 'long long' and 'long_long' produce different
- * mangled strings.
- *
- * The mangling method still is not 'perfect', for example std::pair and
- * std_pair return the same mangling. This is just a little better
- * than before, but it seems to be enough for most of the purposes.
- *
- * Having a perfect mangling will break some examples and code which
- * assume, for example, that A::get_value will be mangled as
- * A_get_value.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_string_mangle(const String *s) {
-#if 0
- /* old mangling, not suitable for using in macros */
- String *t = Copy(s);
- char *c = Char(t);
- while (*c) {
- if (!isalnum(*c))
- *c = '_';
- c++;
- }
- return t;
-#else
- String *result = NewStringEmpty();
- int space = 0;
- int state = 0;
- char *pc, *cb;
- String *b = Copy(s);
- if (SwigType_istemplate(b)) {
- String *st = Swig_symbol_template_deftype(b, 0);
- String *sq = Swig_symbol_type_qualify(st, 0);
- String *t = SwigType_namestr(sq);
- Delete(st);
- Delete(sq);
- Delete(b);
- b = t;
- }
- pc = cb = Char(b);
- while (*pc) {
- char c = *pc;
- if (isalnum((int) c) || (c == '_')) {
- state = 1;
- if (space && (space == state)) {
- Append(result, "_SS_");
- }
- space = 0;
- Printf(result, "%c", (int) c);
-
- } else {
- if (isspace((int) c)) {
- space = state;
- ++pc;
- continue;
- } else {
- state = 3;
- space = 0;
- }
- switch (c) {
- case '.':
- if ((cb != pc) && (*(pc - 1) == 'p')) {
- Append(result, "_");
- ++pc;
- continue;
- } else {
- c = 'f';
- }
- break;
- case ':':
- if (*(pc + 1) == ':') {
- Append(result, "_");
- ++pc;
- ++pc;
- continue;
- }
- break;
- case '*':
- c = 'm';
- break;
- case '&':
- c = 'A';
- break;
- case '<':
- c = 'l';
- break;
- case '>':
- c = 'g';
- break;
- case '=':
- c = 'e';
- break;
- case ',':
- c = 'c';
- break;
- case '(':
- c = 'p';
- break;
- case ')':
- c = 'P';
- break;
- case '[':
- c = 'b';
- break;
- case ']':
- c = 'B';
- break;
- case '^':
- c = 'x';
- break;
- case '|':
- c = 'o';
- break;
- case '~':
- c = 'n';
- break;
- case '!':
- c = 'N';
- break;
- case '%':
- c = 'M';
- break;
- case '?':
- c = 'q';
- break;
- case '+':
- c = 'a';
- break;
- case '-':
- c = 's';
- break;
- case '/':
- c = 'd';
- break;
- default:
- break;
- }
- if (isalpha((int) c)) {
- Printf(result, "_S%c_", (int) c);
- } else {
- Printf(result, "_S%02X_", (int) c);
- }
- }
- ++pc;
- }
- Delete(b);
- return result;
-#endif
-}
-
-String *Swig_string_emangle(String *s) {
- return Swig_string_mangle(s);
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_scopename_split()
- *
- * Take a qualified name like "A::B::C" and splits off the last name.
- * In this case, returns "C" as last and "A::B" as prefix.
- * Always returns non NULL for last, but prefix may be NULL if there is no prefix.
- * ----------------------------------------------------------------------------- */
-
-void Swig_scopename_split(const String *s, String **rprefix, String **rlast) {
- char *tmp = Char(s);
- char *c = tmp;
- char *cc = c;
- char *co = 0;
- if (!strstr(c, "::")) {
- *rprefix = 0;
- *rlast = Copy(s);
- }
-
- co = strstr(cc, "operator ");
- if (co) {
- if (co == cc) {
- *rprefix = 0;
- *rlast = Copy(s);
- return;
- } else {
- *rprefix = NewStringWithSize(cc, (int)(co - cc - 2));
- *rlast = NewString(co);
- return;
- }
- }
- while (*c) {
- if ((*c == ':') && (*(c + 1) == ':')) {
- cc = c;
- c += 2;
- } else {
- if (*c == '<') {
- int level = 1;
- c++;
- while (*c && level) {
- if (*c == '<')
- level++;
- if (*c == '>')
- level--;
- c++;
- }
- } else {
- c++;
- }
- }
- }
-
- if (cc != tmp) {
- *rprefix = NewStringWithSize(tmp, (int)(cc - tmp));
- *rlast = NewString(cc + 2);
- return;
- } else {
- *rprefix = 0;
- *rlast = Copy(s);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_scopename_prefix()
- *
- * Take a qualified name like "A::B::C" and return the scope name.
- * In this case, "A::B". Returns NULL if there is no base.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_scopename_prefix(const String *s) {
- char *tmp = Char(s);
- char *c = tmp;
- char *cc = c;
- char *co = 0;
- if (!strstr(c, "::"))
- return 0;
- co = strstr(cc, "operator ");
-
- if (co) {
- if (co == cc) {
- return 0;
- } else {
- String *prefix = NewStringWithSize(cc, (int)(co - cc - 2));
- return prefix;
- }
- }
- while (*c) {
- if ((*c == ':') && (*(c + 1) == ':')) {
- cc = c;
- c += 2;
- } else {
- if (*c == '<') {
- int level = 1;
- c++;
- while (*c && level) {
- if (*c == '<')
- level++;
- if (*c == '>')
- level--;
- c++;
- }
- } else {
- c++;
- }
- }
- }
-
- if (cc != tmp) {
- return NewStringWithSize(tmp, (int)(cc - tmp));
- } else {
- return 0;
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_scopename_last()
- *
- * Take a qualified name like "A::B::C" and returns the last. In this
- * case, "C".
- * ----------------------------------------------------------------------------- */
-
-String *Swig_scopename_last(const String *s) {
- char *tmp = Char(s);
- char *c = tmp;
- char *cc = c;
- char *co = 0;
- if (!strstr(c, "::"))
- return NewString(s);
-
- co = strstr(cc, "operator ");
- if (co) {
- return NewString(co);
- }
-
-
- while (*c) {
- if ((*c == ':') && (*(c + 1) == ':')) {
- c += 2;
- cc = c;
- } else {
- if (*c == '<') {
- int level = 1;
- c++;
- while (*c && level) {
- if (*c == '<')
- level++;
- if (*c == '>')
- level--;
- c++;
- }
- } else {
- c++;
- }
- }
- }
- return NewString(cc);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_scopename_first()
- *
- * Take a qualified name like "A::B::C" and returns the first scope name.
- * In this case, "A". Returns NULL if there is no base.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_scopename_first(const String *s) {
- char *tmp = Char(s);
- char *c = tmp;
- char *co = 0;
- if (!strstr(c, "::"))
- return 0;
-
- co = strstr(c, "operator ");
- if (co) {
- if (co == c) {
- return 0;
- }
- } else {
- co = c + Len(s);
- }
-
- while (*c && (c != co)) {
- if ((*c == ':') && (*(c + 1) == ':')) {
- break;
- } else {
- if (*c == '<') {
- int level = 1;
- c++;
- while (*c && level) {
- if (*c == '<')
- level++;
- if (*c == '>')
- level--;
- c++;
- }
- } else {
- c++;
- }
- }
- }
- if (*c && (c != tmp)) {
- return NewStringWithSize(tmp, (int)(c - tmp));
- } else {
- return 0;
- }
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_scopename_suffix()
- *
- * Take a qualified name like "A::B::C" and returns the suffix.
- * In this case, "B::C". Returns NULL if there is no suffix.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_scopename_suffix(const String *s) {
- char *tmp = Char(s);
- char *c = tmp;
- char *co = 0;
- if (!strstr(c, "::"))
- return 0;
-
- co = strstr(c, "operator ");
- if (co) {
- if (co == c)
- return 0;
- }
- while (*c) {
- if ((*c == ':') && (*(c + 1) == ':')) {
- break;
- } else {
- if (*c == '<') {
- int level = 1;
- c++;
- while (*c && level) {
- if (*c == '<')
- level++;
- if (*c == '>')
- level--;
- c++;
- }
- } else {
- c++;
- }
- }
- }
- if (*c && (c != tmp)) {
- return NewString(c + 2);
- } else {
- return 0;
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_scopename_tolist()
- *
- * Take a qualified scope name like "A::B::C" and convert it to a list.
- * In this case, return a list of 3 elements "A", "B", "C".
- * Returns an empty list if the input is empty.
- * ----------------------------------------------------------------------------- */
-
-List *Swig_scopename_tolist(const String *s) {
- List *scopes = NewList();
- String *name = Len(s) == 0 ? 0 : NewString(s);
-
- while (name) {
- String *last = 0;
- String *prefix = 0;
- Swig_scopename_split(name, &prefix, &last);
- Insert(scopes, 0, last);
- Delete(last);
- Delete(name);
- name = prefix;
- }
- Delete(name);
- return scopes;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_scopename_check()
- *
- * Checks to see if a name is qualified with a scope name, examples:
- * foo -> 0
- * ::foo -> 1
- * foo::bar -> 1
- * foo< ::bar > -> 0
- * ----------------------------------------------------------------------------- */
-
-int Swig_scopename_check(const String *s) {
- char *c = Char(s);
- char *co = strstr(c, "operator ");
-
- if (co) {
- if (co == c)
- return 0;
- }
- if (!strstr(c, "::"))
- return 0;
- while (*c) {
- if ((*c == ':') && (*(c + 1) == ':')) {
- return 1;
- } else {
- if (*c == '<') {
- int level = 1;
- c++;
- while (*c && level) {
- if (*c == '<')
- level++;
- if (*c == '>')
- level--;
- c++;
- }
- } else {
- c++;
- }
- }
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_string_command()
- *
- * Feature removed in SWIG 4.1.0.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_string_command(String *s) {
- Swig_error("SWIG", Getline(s), "Command encoder no longer supported - use regex encoder instead.\n");
- Exit(EXIT_FAILURE);
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_string_strip()
- *
- * Strip given prefix from identifiers
- *
- * Printf(stderr,"%(strip:[wx])s","wxHello") -> Hello
- * ----------------------------------------------------------------------------- */
-
-String *Swig_string_strip(String *s) {
- String *ns;
- if (!Len(s)) {
- ns = NewString(s);
- } else {
- const char *cs = Char(s);
- const char *ce = Strchr(cs, ']');
- if (*cs != '[' || !ce) {
- ns = NewString(s);
- } else {
- String *fmt = NewStringf("%%.%ds", ce-cs-1);
- String *prefix = NewStringf(fmt, cs+1);
- if (0 == Strncmp(ce+1, prefix, Len(prefix))) {
- ns = NewString(ce+1+Len(prefix));
- } else {
- ns = NewString(ce+1);
- }
- }
- }
- return ns;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_string_rstrip()
- *
- * Strip given suffix from identifiers
- *
- * Printf(stderr,"%(rstrip:[Cls])s","HelloCls") -> Hello
- * ----------------------------------------------------------------------------- */
-
-String *Swig_string_rstrip(String *s) {
- String *ns;
- int len = Len(s);
- if (!len) {
- ns = NewString(s);
- } else {
- const char *cs = Char(s);
- const char *ce = Strchr(cs, ']');
- if (*cs != '[' || !ce) {
- ns = NewString(s);
- } else {
- String *fmt = NewStringf("%%.%ds", ce-cs-1);
- String *suffix = NewStringf(fmt, cs+1);
- int suffix_len = Len(suffix);
- if (0 == Strncmp(cs+len-suffix_len, suffix, suffix_len)) {
- int copy_len = len-suffix_len-(int)(ce+1-cs);
- ns = NewStringWithSize(ce+1, copy_len);
- } else {
- ns = NewString(ce+1);
- }
- }
- }
- return ns;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_offset_string()
- *
- * Insert number tabs before each new line in s
- * ----------------------------------------------------------------------------- */
-
-void Swig_offset_string(String *s, int number) {
- char *res, *p, *end, *start;
- /* count a number of lines in s */
- int lines = 1;
- int len = Len(s);
- if (len == 0)
- return;
- start = strchr(Char(s), '\n');
- while (start) {
- ++lines;
- start = strchr(start + 1, '\n');
- }
- /* do not count pending new line */
- if ((Char(s))[len-1] == '\n')
- --lines;
- /* allocate a temporary storage for a padded string */
- res = (char*)Malloc(len + lines * number * 2 + 1);
- res[len + lines * number * 2] = 0;
-
- /* copy lines to res, prepending tabs to each line */
- p = res; /* output pointer */
- start = Char(s); /* start of a current line */
- end = strchr(start, '\n'); /* end of a current line */
- while (end) {
- memset(p, ' ', number*2);
- p += number*2;
- memcpy(p, start, end - start + 1);
- p += end - start + 1;
- start = end + 1;
- end = strchr(start, '\n');
- }
- /* process the last line */
- if (*start) {
- memset(p, ' ', number*2);
- p += number*2;
- strcpy(p, start);
- }
- /* replace 's' contents with 'res' */
- Clear(s);
- Append(s, res);
- Free(res);
-}
-
-
-#ifdef HAVE_PCRE
-#define PCRE2_CODE_UNIT_WIDTH 8
-#include <pcre2.h>
-
-static int split_regex_pattern_subst(String *s, String **pattern, String **subst, const char **input)
-{
- const char *pats, *pate;
- const char *subs, *sube;
-
- /* Locate the search pattern */
- const char *p = Char(s);
- if (*p++ != '/') goto err_out;
- pats = p;
- p = strchr(p, '/');
- if (!p) goto err_out;
- pate = p;
-
- /* Locate the substitution string */
- subs = ++p;
- p = strchr(p, '/');
- if (!p) goto err_out;
- sube = p;
-
- *pattern = NewStringWithSize(pats, (int)(pate - pats));
- *subst = NewStringWithSize(subs, (int)(sube - subs));
- *input = p + 1;
- return 1;
-
-err_out:
- Swig_error("SWIG", Getline(s), "Invalid regex substitution: '%s'.\n", s);
- Exit(EXIT_FAILURE);
- return 0;
-}
-
-/* This function copies len characters from src to dst, possibly applying case conversions to them: if convertCase is 1, to upper case and if it is -1, to lower
- * case. If convertNextOnly is 1, only a single character is converted (and convertCase is reset), otherwise all of them are. */
-static void copy_with_maybe_case_conversion(String *dst, const char *src, int len, int *convertCase, int convertNextOnly)
-{
- /* Deal with the trivial cases first. */
- if (!len)
- return;
-
- if (!*convertCase) {
- Write(dst, src, len);
- return;
- }
-
- /* If we must convert only the first character, do it and write the rest at once. */
- if (convertNextOnly) {
- int src_char = *src;
- Putc(*convertCase == 1 ? toupper(src_char) : tolower(src_char), dst);
- *convertCase = 0;
- if (len > 1) {
- Write(dst, src + 1, len - 1);
- }
- } else {
- /* We need to convert all characters. */
- int i;
- for (i = 0; i < len; i++, src++) {
- int src_char = *src;
- Putc(*convertCase == 1 ? toupper(src_char) : tolower(src_char), dst);
- }
- }
-}
-
-String *replace_captures(int num_captures, const char *input, String *subst, size_t captures[], String *pattern, String *s)
-{
- int convertCase = 0, convertNextOnly = 0;
- String *result = NewStringEmpty();
- const char *p = Char(subst);
-
- while (*p) {
- /* Copy part without substitutions */
- const char *q = strchr(p, '\\');
- if (!q) {
- copy_with_maybe_case_conversion(result, p, (int)strlen(p), &convertCase, convertNextOnly);
- break;
- }
- copy_with_maybe_case_conversion(result, p, (int)(q - p), &convertCase, convertNextOnly);
- p = q + 1;
-
- /* Handle substitution */
- if (*p == '\0') {
- Putc('\\', result);
- } else if (isdigit((unsigned char)*p)) {
- int group = *p++ - '0';
- if (group < num_captures) {
- int l = (int)captures[group*2], r = (int)captures[group*2 + 1];
- if (l != -1) {
- copy_with_maybe_case_conversion(result, input + l, r - l, &convertCase, convertNextOnly);
- }
- } else {
- Swig_error("SWIG", Getline(s), "PCRE capture replacement failed while matching \"%s\" using \"%s\" - request for group %d is greater than the number of captures %d.\n",
- Char(pattern), input, group, num_captures-1);
- }
- } else {
- /* Handle Perl-like case conversion escapes. */
- switch (*p) {
- case 'u':
- convertCase = 1;
- convertNextOnly = 1;
- break;
- case 'U':
- convertCase = 1;
- convertNextOnly = 0;
- break;
- case 'l':
- convertCase = -1;
- convertNextOnly = 1;
- break;
- case 'L':
- convertCase = -1;
- convertNextOnly = 0;
- break;
- case 'E':
- convertCase = 0;
- break;
- default:
- Swig_error("SWIG", Getline(s), "Unrecognized escape character '%c' in the replacement string \"%s\".\n",
- *p, Char(subst));
- }
- p++;
- }
- }
-
- return result;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_string_regex()
- *
- * Executes a regular expression substitution. For example:
- *
- * Printf(stderr,"gsl%(regex:/GSL_(.*)_/\\1/)s", "GSL_Hello_") -> gslHello
- * ----------------------------------------------------------------------------- */
-String *Swig_string_regex(String *s) {
- const int pcre_options = 0;
-
- String *res = 0;
- pcre2_code *compiled_pat = 0;
- const char *input;
- PCRE2_UCHAR pcre_error[256];
- int pcre_errornum;
- size_t pcre_errorpos;
- String *pattern = 0, *subst = 0;
- size_t *captures = 0;
- pcre2_match_data *match_data = 0;
- if (split_regex_pattern_subst(s, &pattern, &subst, &input)) {
- int rc;
-
- compiled_pat = pcre2_compile(
- (PCRE2_SPTR8)Char(pattern), PCRE2_ZERO_TERMINATED, pcre_options, &pcre_errornum, &pcre_errorpos, NULL);
- if (!compiled_pat) {
- pcre2_get_error_message (pcre_errornum, pcre_error, sizeof pcre_error);
- Swig_error("SWIG", Getline(s), "PCRE compilation failed: '%s' in '%s':%i.\n",
- pcre_error, Char(pattern), pcre_errorpos);
- Exit(EXIT_FAILURE);
- }
- match_data = pcre2_match_data_create_from_pattern (compiled_pat, NULL);
- rc = pcre2_match(compiled_pat, (PCRE2_SPTR8)input, PCRE2_ZERO_TERMINATED, 0, 0, match_data, NULL);
- captures = pcre2_get_ovector_pointer (match_data);
- if (rc >= 0) {
- res = replace_captures(rc, input, subst, captures, pattern, s);
- } else if (rc != PCRE2_ERROR_NOMATCH) {
- Swig_error("SWIG", Getline(s), "PCRE execution failed: error %d while matching \"%s\" using \"%s\".\n",
- rc, Char(pattern), input);
- Exit(EXIT_FAILURE);
- }
- }
-
- DohDelete(pattern);
- DohDelete(subst);
- pcre2_code_free(compiled_pat);
- pcre2_match_data_free(match_data);
- return res ? res : NewStringEmpty();
-}
-
-String *Swig_pcre_version(void) {
- int len = pcre2_config(PCRE2_CONFIG_VERSION, NULL);
- char *buf = Malloc(len);
- String *result;
- pcre2_config(PCRE2_CONFIG_VERSION, buf);
- result = NewStringf("PCRE2 Version: %s", buf);
- Free(buf);
- return result;
-}
-
-#else
-
-String *Swig_string_regex(String *s) {
- Swig_error("SWIG", Getline(s), "PCRE regex support not enabled in this SWIG build.\n");
- Exit(EXIT_FAILURE);
- return 0;
-}
-
-String *Swig_pcre_version(void) {
- return NewStringf("PCRE not used");
-}
-
-#endif
-
-/* ------------------------------------------------------------
- * Swig_is_generated_overload()
- * Check if the function is an automatically generated
- * overload created because a method has default parameters.
- * ------------------------------------------------------------ */
-int Swig_is_generated_overload(Node *n) {
- Node *base_method = Getattr(n, "sym:overloaded");
- Node *default_args = Getattr(n, "defaultargs");
- return ((base_method != NULL) && (default_args != NULL) && (base_method == default_args));
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_init()
- *
- * Initialize the SWIG core
- * ----------------------------------------------------------------------------- */
-
-void Swig_init(void) {
- /* Set some useful string encoding methods */
- DohEncoding("escape", Swig_string_escape);
- DohEncoding("hexescape", Swig_string_hexescape);
- DohEncoding("upper", Swig_string_upper);
- DohEncoding("lower", Swig_string_lower);
- DohEncoding("title", Swig_string_title);
- DohEncoding("ctitle", Swig_string_ccase);
- DohEncoding("lctitle", Swig_string_lccase);
- DohEncoding("utitle", Swig_string_ucase);
- DohEncoding("typecode", Swig_string_typecode);
- DohEncoding("mangle", Swig_string_emangle);
- DohEncoding("command", Swig_string_command);
- DohEncoding("schemify", Swig_string_schemify);
- DohEncoding("strip", Swig_string_strip);
- DohEncoding("rstrip", Swig_string_rstrip);
- DohEncoding("regex", Swig_string_regex);
-
- /* aliases for the case encoders */
- DohEncoding("uppercase", Swig_string_upper);
- DohEncoding("lowercase", Swig_string_lower);
- DohEncoding("camelcase", Swig_string_ccase);
- DohEncoding("lowercamelcase", Swig_string_lccase);
- DohEncoding("undercase", Swig_string_ucase);
- DohEncoding("firstuppercase", Swig_string_first_upper);
- DohEncoding("firstlowercase", Swig_string_first_lower);
-
- /* Initialize typemaps */
- Swig_typemap_init();
-
- /* Initialize symbol table */
- Swig_symbol_init();
-
- /* Initialize type system */
- SwigType_typesystem_init();
-
- /* Initialize template system */
- SwigType_template_init();
-}
diff --git a/contrib/tools/swig/Source/Swig/naming.c b/contrib/tools/swig/Source/Swig/naming.c
deleted file mode 100644
index c4613f6c62..0000000000
--- a/contrib/tools/swig/Source/Swig/naming.c
+++ /dev/null
@@ -1,1771 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * naming.c
- *
- * Functions for generating various kinds of names during code generation.
- *
- * Swig_name_register is used to register a format string for generating names.
- * The format string makes use of the following format specifiers:
- *
- * %c - class name is substituted
- * %f - function name is substituted
- * %m - member name is substituted
- * %n - namespace is substituted
- * %v - variable name is substituted
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-#include "cparse.h"
-#include <ctype.h>
-
-/* Hash table containing naming data */
-
-static Hash *naming_hash = 0;
-
-#if 0
-#define SWIG_DEBUG
-#endif
-
-/* -----------------------------------------------------------------------------
- * Swig_name_register()
- *
- * Register a new naming format.
- * ----------------------------------------------------------------------------- */
-
-void Swig_name_register(const_String_or_char_ptr method, const_String_or_char_ptr format) {
- if (!naming_hash)
- naming_hash = NewHash();
- Setattr(naming_hash, method, format);
-}
-
-void Swig_name_unregister(const_String_or_char_ptr method) {
- if (naming_hash) {
- Delattr(naming_hash, method);
- }
-}
-
-/* Return naming format for the specified method or the default format if none was explicitly registered */
-static String* get_naming_format_for(const char *method, const char *def_format) {
- String* f = naming_hash ? Getattr(naming_hash, method) : NULL;
-
- return f ? Copy(f) : NewString(def_format);
-}
-
-static int name_mangle(String *r) {
- char *c;
- int special;
- special = 0;
- Replaceall(r, "::", "_");
- c = Char(r);
- while (*c) {
- if (!isalnum((int) *c) && (*c != '_')) {
- special = 1;
- switch (*c) {
- case '+':
- *c = 'a';
- break;
- case '-':
- *c = 's';
- break;
- case '*':
- *c = 'm';
- break;
- case '/':
- *c = 'd';
- break;
- case '<':
- *c = 'l';
- break;
- case '>':
- *c = 'g';
- break;
- case '=':
- *c = 'e';
- break;
- case ',':
- *c = 'c';
- break;
- case '(':
- *c = 'p';
- break;
- case ')':
- *c = 'P';
- break;
- case '[':
- *c = 'b';
- break;
- case ']':
- *c = 'B';
- break;
- case '^':
- *c = 'x';
- break;
- case '&':
- *c = 'A';
- break;
- case '|':
- *c = 'o';
- break;
- case '~':
- *c = 'n';
- break;
- case '!':
- *c = 'N';
- break;
- case '%':
- *c = 'M';
- break;
- case '.':
- *c = 'f';
- break;
- case '?':
- *c = 'q';
- break;
- default:
- *c = '_';
- break;
- }
- }
- c++;
- }
- if (special)
- Append(r, "___");
- return special;
-}
-
-/* -----------------------------------------------------------------------------
- * replace_nspace()
- *
- * Mangles in the namespace from nspace by replacing %n in name if nspace feature required.
- * ----------------------------------------------------------------------------- */
-
-static void replace_nspace(String *name, const_String_or_char_ptr nspace) {
- if (nspace) {
- String *namspace = NewStringf("%s_", nspace);
- Replaceall(namspace, NSPACE_SEPARATOR, "_");
- Replace(name, "%n", namspace, DOH_REPLACE_ANY);
- Delete(namspace);
- } else {
- Replace(name, "%n", "", DOH_REPLACE_ANY);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_name_mangle()
- *
- * Converts all of the non-identifier characters of a string to underscores.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_name_mangle(const_String_or_char_ptr s) {
-#if 0
- String *r = NewString(s);
- name_mangle(r);
- return r;
-#else
- return Swig_string_mangle(s);
-#endif
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_name_wrapper()
- *
- * Returns the name of a wrapper function.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_name_wrapper(const_String_or_char_ptr fname) {
- String *r = get_naming_format_for("wrapper", "_wrap_%f");
-
- Replace(r, "%f", fname, DOH_REPLACE_ANY);
- name_mangle(r);
- return r;
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_name_member()
- *
- * Returns the name of a class method.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_name_member(const_String_or_char_ptr nspace, const_String_or_char_ptr classname, const_String_or_char_ptr membername) {
- String *r;
- String *rclassname;
- char *cname;
-
- rclassname = SwigType_namestr(classname);
- r = get_naming_format_for("member", "%n%c_%m");
- cname = Char(rclassname);
- if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) {
- cname = strchr(cname, ' ') + 1;
- }
- replace_nspace(r, nspace);
- Replace(r, "%c", cname, DOH_REPLACE_ANY);
- Replace(r, "%m", membername, DOH_REPLACE_ANY);
- /* name_mangle(r); */
- Delete(rclassname);
- return r;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_name_get()
- *
- * Returns the name of the accessor function used to get a variable.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_name_get(const_String_or_char_ptr nspace, const_String_or_char_ptr vname) {
- String *r = get_naming_format_for("get", "%n%v_get");
-
-#ifdef SWIG_DEBUG
- Printf(stdout, "Swig_name_get: '%s'\n", vname);
-#endif
-
- replace_nspace(r, nspace);
- Replace(r, "%v", vname, DOH_REPLACE_ANY);
- /* name_mangle(r); */
- return r;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_name_set()
- *
- * Returns the name of the accessor function used to set a variable.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_name_set(const_String_or_char_ptr nspace, const_String_or_char_ptr vname) {
- String *r = get_naming_format_for("set", "%n%v_set");
-
- replace_nspace(r, nspace);
- Replace(r, "%v", vname, DOH_REPLACE_ANY);
- /* name_mangle(r); */
- return r;
-}
-
-/* Common implementation of all Swig_name_<special-method>() functions below. */
-static String *make_full_name_for(const char *method, const char *def_format, const_String_or_char_ptr nspace, const_String_or_char_ptr classname) {
- String *r;
- String *rclassname;
- char *cname;
-
- rclassname = SwigType_namestr(classname);
- r = get_naming_format_for(method, def_format);
-
- cname = Char(rclassname);
- if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) {
- cname = strchr(cname, ' ') + 1;
- }
-
- replace_nspace(r, nspace);
- Replace(r, "%c", cname, DOH_REPLACE_ANY);
- Delete(rclassname);
- return r;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_name_construct()
- *
- * Returns the name of the accessor function used to create an object.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_name_construct(const_String_or_char_ptr nspace, const_String_or_char_ptr classname) {
- return make_full_name_for("construct", "new_%n%c", nspace, classname);
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_name_copyconstructor()
- *
- * Returns the name of the accessor function used to copy an object.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_name_copyconstructor(const_String_or_char_ptr nspace, const_String_or_char_ptr classname) {
- return make_full_name_for("copy", "copy_%n%c", nspace, classname);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_name_destroy()
- *
- * Returns the name of the accessor function used to destroy an object.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_name_destroy(const_String_or_char_ptr nspace, const_String_or_char_ptr classname) {
- return make_full_name_for("destroy", "delete_%n%c", nspace, classname);
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_name_disown()
- *
- * Returns the name of the accessor function used to disown an object.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_name_disown(const_String_or_char_ptr nspace, const_String_or_char_ptr classname) {
- return make_full_name_for("disown", "disown_%n%c", nspace, classname);
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_name_object_set()
- *
- * Sets an object associated with a name and optional declarators.
- * ----------------------------------------------------------------------------- */
-
-void Swig_name_object_set(Hash *namehash, String *name, SwigType *decl, DOH *object) {
- DOH *n;
-
-#ifdef SWIG_DEBUG
- Printf(stdout, "Swig_name_object_set: '%s', '%s'\n", name, decl);
-#endif
- n = Getattr(namehash, name);
- if (!n) {
- n = NewHash();
- Setattr(namehash, name, n);
- Delete(n);
- }
- /* Add an object based on the declarator value */
- if (!decl) {
- Setattr(n, "start", object);
- } else {
- SwigType *cd = Copy(decl);
- Setattr(n, cd, object);
- Delete(cd);
- }
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_name_object_get()
- *
- * Return an object associated with an optional class prefix, name, and
- * declarator. This function operates according to name matching rules
- * described for the %rename directive in the SWIG manual.
- * ----------------------------------------------------------------------------- */
-
-static DOH *get_object(Hash *n, String *decl) {
- DOH *rn = 0;
- if (!n)
- return 0;
- if (decl) {
- rn = Getattr(n, decl);
- } else {
- rn = Getattr(n, "start");
- }
- return rn;
-}
-
-static DOH *name_object_get(Hash *namehash, String *tname, SwigType *decl, SwigType *ncdecl) {
- DOH *rn = 0;
- Hash *n = Getattr(namehash, tname);
- if (n) {
- rn = get_object(n, decl);
- if ((!rn) && ncdecl)
- rn = get_object(n, ncdecl);
- if (!rn)
- rn = get_object(n, 0);
- }
- return rn;
-}
-
-DOH *Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType *decl) {
- String *tname = NewStringEmpty();
- DOH *rn = 0;
- char *ncdecl = 0;
-
- if (!namehash)
- return 0;
-
- /* DB: This removed to more tightly control feature/name matching */
- /* if ((decl) && (SwigType_isqualifier(decl))) {
- ncdecl = strchr(Char(decl),'.');
- ncdecl++;
- }
- */
-#ifdef SWIG_DEBUG
- Printf(stdout, "Swig_name_object_get: '%s' '%s', '%s'\n", prefix, name, decl);
-#endif
-
-
- /* Perform a class-based lookup (if class prefix supplied) */
- if (prefix) {
- if (Len(prefix)) {
- Printf(tname, "%s::%s", prefix, name);
- rn = name_object_get(namehash, tname, decl, ncdecl);
- if (!rn) {
- String *cls = Swig_scopename_last(prefix);
- if (!Equal(cls, prefix)) {
- Clear(tname);
- Printf(tname, "*::%s::%s", cls, name);
- rn = name_object_get(namehash, tname, decl, ncdecl);
- }
- Delete(cls);
- }
- /* Lookup a name within a templated-based class */
- if (!rn) {
- String *t_name = SwigType_istemplate_templateprefix(prefix);
- if (t_name) {
- Clear(tname);
- Printf(tname, "%s::%s", t_name, name);
- rn = name_object_get(namehash, tname, decl, ncdecl);
- Delete(t_name);
- }
- }
- /* Lookup a template-based name within a class */
- if (!rn) {
- String *t_name = SwigType_istemplate_templateprefix(name);
- if (t_name)
- rn = Swig_name_object_get(namehash, prefix, t_name, decl);
- Delete(t_name);
- }
- }
- /* A wildcard-based class lookup */
- if (!rn) {
- Clear(tname);
- Printf(tname, "*::%s", name);
- rn = name_object_get(namehash, tname, decl, ncdecl);
- }
- } else {
- /* Lookup in the global namespace only */
- Clear(tname);
- Printf(tname, "::%s", name);
- rn = name_object_get(namehash, tname, decl, ncdecl);
- }
- /* Catch-all */
- if (!rn) {
- rn = name_object_get(namehash, name, decl, ncdecl);
- }
- if (!rn && Swig_scopename_check(name)) {
- String *nprefix = 0;
- String *nlast = 0;
- Swig_scopename_split(name, &nprefix, &nlast);
- rn = name_object_get(namehash, nlast, decl, ncdecl);
- Delete(nlast);
- Delete(nprefix);
- }
-
- Delete(tname);
-
-#ifdef SWIG_DEBUG
- Printf(stdout, "Swig_name_object_get: found %d\n", rn ? 1 : 0);
-#endif
-
- return rn;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_name_object_inherit()
- *
- * Implements name-based inheritance scheme.
- * ----------------------------------------------------------------------------- */
-
-void Swig_name_object_inherit(Hash *namehash, String *base, String *derived) {
- Iterator ki;
- Hash *derh;
- String *bprefix;
- String *dprefix;
- char *cbprefix;
- int plen;
-
- if (!namehash)
- return;
-
- /* Temporary hash holding all the entries we add while we iterate over
- namehash itself as we can't modify the latter while iterating over it. */
- derh = NULL;
- bprefix = NewStringf("%s::", base);
- dprefix = NewStringf("%s::", derived);
- cbprefix = Char(bprefix);
- plen = (int)strlen(cbprefix);
- for (ki = First(namehash); ki.key; ki = Next(ki)) {
- char *k = Char(ki.key);
- if (strncmp(k, cbprefix, plen) == 0) {
- /* Copy, adjusting name, this element to the derived hash. */
- Iterator oi;
- String *nkey = NewStringf("%s%s", dprefix, k + plen);
- Hash *n = ki.item;
- Hash *newh;
-
- /* Don't overwrite an existing value for the derived class, if any. */
- newh = Getattr(namehash, nkey);
- if (!newh) {
- if (!derh)
- derh = NewHash();
-
- newh = NewHash();
- Setattr(derh, nkey, newh);
- Delete(newh);
- }
- for (oi = First(n); oi.key; oi = Next(oi)) {
- if (!Getattr(newh, oi.key)) {
- String *ci = Copy(oi.item);
- Setattr(newh, oi.key, ci);
- Delete(ci);
- }
- }
- Delete(nkey);
- }
- }
-
- /* Merge the contents of derived hash into the main hash. */
- if (derh) {
- for (ki = First(derh); ki.key; ki = Next(ki)) {
- Setattr(namehash, ki.key, ki.item);
- }
- }
-
- Delete(bprefix);
- Delete(dprefix);
- Delete(derh);
-}
-
-/* -----------------------------------------------------------------------------
- * merge_features()
- *
- * Given a hash, this function merges the features in the hash into the node.
- * ----------------------------------------------------------------------------- */
-
-static void merge_features(Hash *features, Node *n) {
- Iterator ki;
-
- if (!features)
- return;
- for (ki = First(features); ki.key; ki = Next(ki)) {
- String *ci = Copy(ki.item);
- Setattr(n, ki.key, ci);
- Delete(ci);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_features_get()
- *
- * Attaches any features in the features hash to the node that matches
- * the declaration, decl.
- * ----------------------------------------------------------------------------- */
-
-static void features_get(Hash *features, const String *tname, SwigType *decl, SwigType *ncdecl, Node *node) {
- Node *n = Getattr(features, tname);
-#ifdef SWIG_DEBUG
- Printf(stdout, " features_get: %s\n", tname);
-#endif
- if (n) {
- merge_features(get_object(n, 0), node);
- if (ncdecl)
- merge_features(get_object(n, ncdecl), node);
- merge_features(get_object(n, decl), node);
- }
-}
-
-void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, Node *node) {
- char *ncdecl = 0;
- String *rdecl = 0;
- String *rname = 0;
- if (!features)
- return;
-
- /* MM: This removed to more tightly control feature/name matching */
- /*
- if ((decl) && (SwigType_isqualifier(decl))) {
- ncdecl = strchr(Char(decl),'.');
- ncdecl++;
- }
- */
-
- /* very specific hack for template constructors/destructors */
- if (name && SwigType_istemplate(name)) {
- String *nodetype = nodeType(node);
- if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) {
- String *nprefix = 0;
- String *nlast = 0;
- String *tprefix;
- Swig_scopename_split(name, &nprefix, &nlast);
- tprefix = SwigType_templateprefix(nlast);
- Delete(nlast);
- if (Len(nprefix)) {
- Append(nprefix, "::");
- Append(nprefix, tprefix);
- Delete(tprefix);
- rname = nprefix;
- } else {
- rname = tprefix;
- Delete(nprefix);
- }
- rdecl = Copy(decl);
- Replaceall(rdecl, name, rname);
- decl = rdecl;
- name = rname;
- }
- }
-
-#ifdef SWIG_DEBUG
- Printf(stdout, "Swig_features_get: '%s' '%s' '%s'\n", prefix, name, decl);
-#endif
-
- /* Global features */
- features_get(features, "", 0, 0, node);
- if (name) {
- String *tname = NewStringEmpty();
- /* add features for 'root' template */
- String *dname = SwigType_istemplate_templateprefix(name);
- if (dname) {
- features_get(features, dname, decl, ncdecl, node);
- }
- /* Catch-all */
- features_get(features, name, decl, ncdecl, node);
- /* Perform a class-based lookup (if class prefix supplied) */
- if (prefix) {
- /* A class-generic feature */
- if (Len(prefix)) {
- Printf(tname, "%s::", prefix);
- features_get(features, tname, decl, ncdecl, node);
- }
- /* A wildcard-based class lookup */
- Clear(tname);
- Printf(tname, "*::%s", name);
- features_get(features, tname, decl, ncdecl, node);
- /* A specific class lookup */
- if (Len(prefix)) {
- /* A template-based class lookup */
- String *tprefix = SwigType_istemplate_templateprefix(prefix);
- if (tprefix) {
- Clear(tname);
- Printf(tname, "%s::%s", tprefix, name);
- features_get(features, tname, decl, ncdecl, node);
- }
- Clear(tname);
- Printf(tname, "%s::%s", prefix, name);
- features_get(features, tname, decl, ncdecl, node);
- Delete(tprefix);
- }
- } else {
- /* Lookup in the global namespace only */
- Clear(tname);
- Printf(tname, "::%s", name);
- features_get(features, tname, decl, ncdecl, node);
- }
- Delete(tname);
- Delete(dname);
- }
- if (name && SwigType_istemplate(name)) {
- /* add features for complete template type */
- String *dname = Swig_symbol_template_deftype(name, 0);
- if (!Equal(dname, name)) {
- Swig_features_get(features, prefix, dname, decl, node);
- }
- Delete(dname);
- }
-
- if (rname)
- Delete(rname);
- if (rdecl)
- Delete(rdecl);
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_feature_set()
- *
- * Sets a feature name and value. Also sets optional feature attributes as
- * passed in by featureattribs. Optional feature attributes are given a full name
- * concatenating the feature name plus ':' plus the attribute name.
- * ----------------------------------------------------------------------------- */
-
-void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *decl, const_String_or_char_ptr featurename, const_String_or_char_ptr value, Hash *featureattribs) {
- Hash *n;
- Hash *fhash;
-
-#ifdef SWIG_DEBUG
- Printf(stdout, "Swig_feature_set: '%s' '%s' '%s' '%s'\n", name, decl, featurename, value);
-#endif
-
- n = Getattr(features, name);
- if (!n) {
- n = NewHash();
- Setattr(features, name, n);
- Delete(n);
- }
- if (!decl) {
- fhash = Getattr(n, "start");
- if (!fhash) {
- fhash = NewHash();
- Setattr(n, "start", fhash);
- Delete(fhash);
- }
- } else {
- fhash = Getattr(n, decl);
- if (!fhash) {
- String *cdecl_ = Copy(decl);
- fhash = NewHash();
- Setattr(n, cdecl_, fhash);
- Delete(cdecl_);
- Delete(fhash);
- }
- }
- if (value) {
- Setattr(fhash, featurename, value);
- } else {
- Delattr(fhash, featurename);
- }
-
- {
- /* Add in the optional feature attributes */
- Hash *attribs = featureattribs;
- while (attribs) {
- String *attribname = Getattr(attribs, "name");
- String *featureattribname = NewStringf("%s:%s", featurename, attribname);
- if (value) {
- String *attribvalue = Getattr(attribs, "value");
- Setattr(fhash, featureattribname, attribvalue);
- } else {
- Delattr(fhash, featureattribname);
- }
- attribs = nextSibling(attribs);
- Delete(featureattribname);
- }
- }
-
- if (name && SwigType_istemplate(name)) {
- String *dname = Swig_symbol_template_deftype(name, 0);
- if (Strcmp(dname, name)) {
- Swig_feature_set(features, dname, decl, featurename, value, featureattribs);
- }
- Delete(dname);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * The rename/namewarn engine
- *
- * Code below was in parser.y for a while
- * ----------------------------------------------------------------------------- */
-
-static Hash *namewarn_hash = 0;
-static Hash *name_namewarn_hash(void) {
- if (!namewarn_hash)
- namewarn_hash = NewHash();
- return namewarn_hash;
-}
-
-static Hash *rename_hash = 0;
-static Hash *name_rename_hash(void) {
- if (!rename_hash)
- rename_hash = NewHash();
- return rename_hash;
-}
-
-static List *namewarn_list = 0;
-static List *name_namewarn_list(void) {
- if (!namewarn_list)
- namewarn_list = NewList();
- return namewarn_list;
-}
-
-static List *rename_list = 0;
-static List *name_rename_list(void) {
- if (!rename_list)
- rename_list = NewList();
- return rename_list;
-}
-
-/* -----------------------------------------------------------------------------
- * int need_name_warning(Node *n)
- *
- * Detects if a node needs name warnings
- *
- * ----------------------------------------------------------------------------- */
-
-static int need_name_warning(Node *n) {
- int need = 1;
- /*
- We don't use name warnings for:
- - class forwards, no symbol is generated at the target language.
- - template declarations, only for real instances using %template(name).
- - typedefs, have no effect at the target language.
- - using declarations and using directives, have no effect at the target language.
- */
- if (checkAttribute(n, "nodeType", "classforward")) {
- need = 0;
- } else if (checkAttribute(n, "nodeType", "using")) {
- need = 0;
- } else if (checkAttribute(n, "storage", "typedef")) {
- need = 0;
- } else if (Getattr(n, "hidden")) {
- need = 0;
- } else if (Getattr(n, "ignore")) {
- need = 0;
- } else if (Getattr(n, "templatetype")) {
- need = 0;
- } else if (GetFlag(n, "parsing_template_declaration")) {
- need = 0;
- }
- return need;
-}
-
-/* -----------------------------------------------------------------------------
- * int Swig_need_redefined_warn()
- *
- * Detects when a redefined object needs a warning
- *
- * ----------------------------------------------------------------------------- */
-
-static int nodes_are_equivalent(Node *a, Node *b, int a_inclass) {
- /* they must have the same type */
- String *ta = nodeType(a);
- String *tb = nodeType(b);
- if (!Equal(ta, tb)) {
- if (!(Equal(ta, "using") && Equal(tb, "cdecl"))) {
- return 0;
- }
- }
-
- if (Cmp(ta, "cdecl") == 0) {
- /* both cdecl case */
- /* typedef */
- String *a_storage = Getattr(a, "storage");
- String *b_storage = Getattr(b, "storage");
-
- if ((Cmp(a_storage, "typedef") == 0)
- || (Cmp(b_storage, "typedef") == 0)) {
- if (Cmp(a_storage, b_storage) == 0) {
- String *a_type = (Getattr(a, "type"));
- String *b_type = (Getattr(b, "type"));
- if (Cmp(a_type, b_type) == 0)
- return 1;
- }
- return 0;
- }
-
- /* static functions */
- if (Swig_storage_isstatic(a) || Swig_storage_isstatic(b)) {
- if (Cmp(a_storage, b_storage) != 0)
- return 0;
- }
-
- /* friend methods */
-
- if (!a_inclass || (Cmp(a_storage, "friend") == 0)) {
- /* check declaration */
-
- String *a_decl = (Getattr(a, "decl"));
- String *b_decl = (Getattr(b, "decl"));
- if (Cmp(a_decl, b_decl) == 0) {
- /* check return type */
- String *a_type = (Getattr(a, "type"));
- String *b_type = (Getattr(b, "type"));
- if (Cmp(a_type, b_type) == 0) {
- /* check parameters */
- Parm *ap = (Getattr(a, "parms"));
- Parm *bp = (Getattr(b, "parms"));
- while (ap && bp) {
- SwigType *at = Getattr(ap, "type");
- SwigType *bt = Getattr(bp, "type");
- if (Cmp(at, bt) != 0)
- return 0;
- ap = nextSibling(ap);
- bp = nextSibling(bp);
- }
- if (ap || bp) {
- return 0;
- } else {
- Node *a_template = Getattr(a, "template");
- Node *b_template = Getattr(b, "template");
- /* Not equivalent if one is a template instantiation (via %template) and the other is a non-templated function */
- if ((a_template && !b_template) || (!a_template && b_template))
- return 0;
- }
- return 1;
- }
- }
- }
- } else if (Equal(ta, "using")) {
- /* using and cdecl case */
- String *b_storage = Getattr(b, "storage");
- if (Equal(b_storage, "typedef")) {
- String *a_name = Getattr(a, "name");
- String *b_name = Getattr(b, "name");
- if (Equal(a_name, b_name))
- return 1;
- }
- } else {
- /* both %constant case */
- String *a_storage = Getattr(a, "storage");
- String *b_storage = Getattr(b, "storage");
- if ((Cmp(a_storage, "%constant") == 0)
- || (Cmp(b_storage, "%constant") == 0)) {
- if (Cmp(a_storage, b_storage) == 0) {
- String *a_type = (Getattr(a, "type"));
- String *b_type = (Getattr(b, "type"));
- if ((Cmp(a_type, b_type) == 0)
- && (Cmp(Getattr(a, "value"), Getattr(b, "value")) == 0))
- return 1;
- }
- return 0;
- }
- if (Equal(ta, "template") && Equal(tb, "template")) {
- if (Cmp(a_storage, "friend") == 0 || Cmp(b_storage, "friend") == 0)
- return 1;
- }
- }
- return 0;
-}
-
-int Swig_need_redefined_warn(Node *a, Node *b, int InClass) {
- String *a_name = Getattr(a, "name");
- String *b_name = Getattr(b, "name");
- String *a_symname = Getattr(a, "sym:name");
- String *b_symname = Getattr(b, "sym:name");
- /* always send a warning if a 'rename' is involved */
- if ((a_symname && !Equal(a_symname, a_name))
- || (b_symname && !Equal(b_symname, b_name))) {
- if (!Equal(a_name, b_name)) {
- return 1;
- }
- }
-
-
- return !nodes_are_equivalent(a, b, InClass);
-}
-
-
-/* -----------------------------------------------------------------------------
- * int Swig_need_protected(Node* n)
- *
- * Detects when we need to fully register the protected member.
- * This is basically any protected members when the allprotected mode is set.
- * Otherwise we take just the protected virtual methods and non-static methods
- * (potentially virtual methods) as well as constructors/destructors.
- * Also any "using" statements in a class may potentially be virtual.
- * ----------------------------------------------------------------------------- */
-
-int Swig_need_protected(Node *n) {
- String *nodetype = nodeType(n);
- if (checkAttribute(n, "access", "protected")) {
- if ((Equal(nodetype, "cdecl"))) {
- if (Swig_director_mode() && Swig_director_protected_mode() && Swig_all_protected_mode()) {
- return 1;
- }
- if (SwigType_isfunction(Getattr(n, "decl"))) {
- String *storage = Getattr(n, "storage");
- /* The function is declared virtual, or it has no storage. This eliminates typedef, static etc. */
- return !storage || Equal(storage, "virtual");
- }
- } else if (Equal(nodetype, "constructor") || Equal(nodetype, "destructor")) {
- return 1;
- } else if (Equal(nodetype, "using") && !Getattr(n, "namespace")) {
- return 1;
- }
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * void name_nameobj_add()
- *
- * Add nameobj (rename/namewarn)
- *
- * ----------------------------------------------------------------------------- */
-
-static List *make_attrlist(const char *ckey) {
- List *list = NewList();
- const char *cattr = strchr(ckey, '$');
- if (cattr) {
- String *nattr;
- const char *rattr = strchr(++cattr, '$');
- while (rattr) {
- nattr = NewStringWithSize(cattr, (int)(rattr - cattr));
- Append(list, nattr);
- Delete(nattr);
- cattr = rattr + 1;
- rattr = strchr(cattr, '$');
- }
- nattr = NewString(cattr);
- Append(list, nattr);
- Delete(nattr);
- } else {
- Append(list, "nodeType");
- }
- return list;
-}
-
-static void name_object_attach_keys(const char *keys[], Hash *nameobj) {
- Node *kw = nextSibling(nameobj);
- List *matchlist = 0;
- while (kw) {
- Node *next = nextSibling(kw);
- String *kname = Getattr(kw, "name");
- char *ckey = kname ? Char(kname) : 0;
- if (ckey) {
- const char **rkey;
- int isnotmatch = 0;
- int isregexmatch = 0;
- if ((strncmp(ckey, "match", 5) == 0)
- || (isnotmatch = (strncmp(ckey, "notmatch", 8) == 0))
- || (isregexmatch = (strncmp(ckey, "regexmatch", 10) == 0))
- || (isnotmatch = isregexmatch = (strncmp(ckey, "notregexmatch", 13) == 0))) {
- Hash *mi = NewHash();
- List *attrlist = make_attrlist(ckey);
- if (!matchlist)
- matchlist = NewList();
- Setattr(mi, "value", Getattr(kw, "value"));
- Setattr(mi, "attrlist", attrlist);
- if (isnotmatch)
- SetFlag(mi, "notmatch");
- if (isregexmatch)
- SetFlag(mi, "regexmatch");
- Delete(attrlist);
- Append(matchlist, mi);
- Delete(mi);
- removeNode(kw);
- } else {
- for (rkey = keys; *rkey != 0; ++rkey) {
- if (strcmp(ckey, *rkey) == 0) {
- Setattr(nameobj, *rkey, Getattr(kw, "value"));
- removeNode(kw);
- }
- }
- }
- }
- kw = next;
- }
- if (matchlist) {
- Setattr(nameobj, "matchlist", matchlist);
- Delete(matchlist);
- }
-}
-
-static void name_nameobj_add(Hash *name_hash, List *name_list, String *prefix, String *name, SwigType *decl, Hash *nameobj) {
- String *nname = 0;
- if (name && Len(name)) {
- String *target_fmt = Getattr(nameobj, "targetfmt");
- nname = prefix ? NewStringf("%s::%s", prefix, name) : NewString(name);
- if (target_fmt) {
- String *tmp = NewStringf(target_fmt, nname);
- Delete(nname);
- nname = tmp;
- }
- }
-
- if (!nname || !Len(nname) || Getattr(nameobj, "fullname") || /* any of these options trigger a 'list' nameobj */
- Getattr(nameobj, "sourcefmt") || Getattr(nameobj, "matchlist") || Getattr(nameobj, "regextarget")) {
- if (decl)
- Setattr(nameobj, "decl", decl);
- if (nname && Len(nname))
- Setattr(nameobj, "targetname", nname);
- /* put the new nameobj at the beginning of the list, such that the
- last inserted rule take precedence */
- Insert(name_list, 0, nameobj);
- } else {
- /* here we add an old 'hash' nameobj, simple and fast */
- Swig_name_object_set(name_hash, nname, decl, nameobj);
- }
- Delete(nname);
-}
-
-/* -----------------------------------------------------------------------------
- * int name_match_nameobj()
- *
- * Apply and check the nameobj's math list to the node
- *
- * ----------------------------------------------------------------------------- */
-
-static DOH *get_lattr(Node *n, List *lattr) {
- DOH *res = 0;
- int ilen = Len(lattr);
- int i;
- for (i = 0; n && (i < ilen); ++i) {
- String *nattr = Getitem(lattr, i);
- res = Getattr(n, nattr);
-#ifdef SWIG_DEBUG
- if (!res) {
- Printf(stdout, "missing %s %s %s\n", nattr, Getattr(n, "name"), Getattr(n, "member"));
- } else {
- Printf(stdout, "lattr %d %s %s\n", i, nattr, DohIsString(res) ? res : Getattr(res, "name"));
- }
-#endif
- n = res;
- }
- return res;
-}
-
-#ifdef HAVE_PCRE
-#define PCRE2_CODE_UNIT_WIDTH 8
-#include <pcre2.h>
-
-static int name_regexmatch_value(Node *n, String *pattern, String *s) {
- pcre2_code *compiled_pat;
- PCRE2_UCHAR err[256];
- int errornum;
- size_t errpos;
- int rc;
- pcre2_match_data *match_data = 0;
-
- compiled_pat = pcre2_compile((PCRE2_SPTR8)Char(pattern), PCRE2_ZERO_TERMINATED, 0, &errornum, &errpos, NULL);
- if (!compiled_pat) {
- pcre2_get_error_message (errornum, err, sizeof err);
- Swig_error("SWIG", Getline(n),
- "Invalid regex \"%s\": compilation failed at %d: %s\n",
- Char(pattern), errpos, err);
- Exit(EXIT_FAILURE);
- }
-
- match_data = pcre2_match_data_create_from_pattern (compiled_pat, NULL);
- rc = pcre2_match(compiled_pat, (PCRE2_SPTR8)Char(s), PCRE2_ZERO_TERMINATED, 0, 0, match_data, 0);
- pcre2_code_free(compiled_pat);
- pcre2_match_data_free(match_data);
-
- if (rc == PCRE2_ERROR_NOMATCH)
- return 0;
-
- if (rc < 0 ) {
- Swig_error("SWIG", Getline(n),
- "Matching \"%s\" against regex \"%s\" failed: %d\n",
- Char(s), Char(pattern), rc);
- Exit(EXIT_FAILURE);
- }
-
- return 1;
-}
-
-#else /* !HAVE_PCRE */
-
-static int name_regexmatch_value(Node *n, String *pattern, String *s) {
- (void)pattern;
- (void)s;
- Swig_error("SWIG", Getline(n),
- "PCRE regex matching is not available in this SWIG build.\n");
- Exit(EXIT_FAILURE);
- return 0;
-}
-
-#endif /* HAVE_PCRE/!HAVE_PCRE */
-
-static int name_match_value(String *mvalue, String *value) {
-#if defined(SWIG_USE_SIMPLE_MATCHOR)
- int match = 0;
- char *cvalue = Char(value);
- char *cmvalue = Char(mvalue);
- char *sep = strchr(cmvalue, '|');
- while (sep && !match) {
- match = strncmp(cvalue, cmvalue, sep - cmvalue) == 0;
-#ifdef SWIG_DEBUG
- Printf(stdout, "match_value: %s %s %d\n", cvalue, cmvalue, match);
-#endif
- cmvalue = sep + 1;
- sep = strchr(cmvalue, '|');
- }
- if (!match) {
- match = strcmp(cvalue, cmvalue) == 0;
-#ifdef SWIG_DEBUG
- Printf(stdout, "match_value: %s %s %d\n", cvalue, cmvalue, match);
-#endif
- }
- return match;
-#else
- return Equal(mvalue, value);
-#endif
-}
-
-static int name_match_nameobj(Hash *rn, Node *n) {
- int match = 1;
- List *matchlist = Getattr(rn, "matchlist");
-#ifdef SWIG_DEBUG
- Printf(stdout, "name_match_nameobj: %s\n", Getattr(n, "name"));
-#endif
- if (matchlist) {
- int ilen = Len(matchlist);
- int i;
- for (i = 0; match && (i < ilen); ++i) {
- Node *mi = Getitem(matchlist, i);
- List *lattr = Getattr(mi, "attrlist");
- String *nval = get_lattr(n, lattr);
- int notmatch = GetFlag(mi, "notmatch");
- int regexmatch = GetFlag(mi, "regexmatch");
- match = 0;
- if (nval) {
- String *kwval = Getattr(mi, "value");
- match = regexmatch ? name_regexmatch_value(n, kwval, nval)
- : name_match_value(kwval, nval);
-#ifdef SWIG_DEBUG
- Printf(stdout, "val %s %s %d %d \n", nval, kwval, match, ilen);
-#endif
- }
- if (notmatch)
- match = !match;
- }
- }
-#ifdef SWIG_DEBUG
- Printf(stdout, "name_match_nameobj: %d\n", match);
-#endif
- return match;
-}
-
-/* -----------------------------------------------------------------------------
- * Hash *name_nameobj_lget()
- *
- * Get a nameobj (rename/namewarn) from the list of filters
- *
- * ----------------------------------------------------------------------------- */
-
-static Hash *name_nameobj_lget(List *namelist, Node *n, String *prefix, String *name, String *decl) {
- Hash *res = 0;
- if (namelist) {
- int len = Len(namelist);
- int i;
- int match = 0;
- for (i = 0; !match && (i < len); i++) {
- Hash *rn = Getitem(namelist, i);
- String *rdecl = Getattr(rn, "decl");
- if (rdecl && (!decl || !Equal(rdecl, decl))) {
- continue;
- } else if (name_match_nameobj(rn, n)) {
- String *tname = Getattr(rn, "targetname");
- if (tname) {
- String *sfmt = Getattr(rn, "sourcefmt");
- String *sname = 0;
- int fullname = GetFlag(rn, "fullname");
- int regextarget = GetFlag(rn, "regextarget");
- if (sfmt) {
- if (fullname && prefix) {
- String *pname = NewStringf("%s::%s", prefix, name);
- sname = NewStringf(sfmt, pname);
- Delete(pname);
- } else {
- sname = NewStringf(sfmt, name);
- }
- } else {
- if (fullname && prefix) {
- sname = NewStringf("%s::%s", prefix, name);
- } else {
- sname = name;
- DohIncref(name);
- }
- }
- match = regextarget ? name_regexmatch_value(n, tname, sname)
- : name_match_value(tname, sname);
- Delete(sname);
- } else {
- /* Applying the renaming rule may fail if it contains a %(regex)s expression that doesn't match the given name. */
- String *sname = NewStringf(Getattr(rn, "name"), name);
- if (sname) {
- if (Len(sname))
- match = 1;
- Delete(sname);
- }
- }
- }
- if (match) {
- res = rn;
- break;
- }
- }
- }
- return res;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_name_namewarn_add
- *
- * Add a namewarn objects
- *
- * ----------------------------------------------------------------------------- */
-
-void Swig_name_namewarn_add(String *prefix, String *name, SwigType *decl, Hash *namewrn) {
- const char *namewrn_keys[] = { "rename", "error", "fullname", "sourcefmt", "targetfmt", 0 };
- name_object_attach_keys(namewrn_keys, namewrn);
- name_nameobj_add(name_namewarn_hash(), name_namewarn_list(), prefix, name, decl, namewrn);
-}
-
-/* -----------------------------------------------------------------------------
- * Hash *name_namewarn_get()
- *
- * Return the namewarn object, if there is one.
- *
- * ----------------------------------------------------------------------------- */
-
-static Hash *name_namewarn_get(Node *n, String *prefix, String *name, SwigType *decl) {
- if (!namewarn_hash && !namewarn_list)
- return 0;
- if (n) {
- /* Return in the obvious cases */
- if (!name || !need_name_warning(n)) {
- return 0;
- } else {
- String *access = Getattr(n, "access");
- int is_public = !access || Equal(access, "public");
- if (!is_public && !Swig_need_protected(n)) {
- return 0;
- }
- }
- }
- if (name) {
- /* Check to see if the name is in the hash */
- Hash *wrn = Swig_name_object_get(name_namewarn_hash(), prefix, name, decl);
- if (wrn && !name_match_nameobj(wrn, n))
- wrn = 0;
- if (!wrn) {
- wrn = name_nameobj_lget(name_namewarn_list(), n, prefix, name, decl);
- }
- if (wrn && Getattr(wrn, "error")) {
- if (n) {
- Swig_error(Getfile(n), Getline(n), "%s\n", Getattr(wrn, "name"));
- } else {
- Swig_error(cparse_file, cparse_line, "%s\n", Getattr(wrn, "name"));
- }
- }
- return wrn;
- } else {
- return 0;
- }
-}
-
-/* -----------------------------------------------------------------------------
- * String *Swig_name_warning()
- *
- * Return the name warning, if there is one.
- *
- * ----------------------------------------------------------------------------- */
-
-String *Swig_name_warning(Node *n, String *prefix, String *name, SwigType *decl) {
- Hash *wrn = name_namewarn_get(n, prefix, name, decl);
- return (name && wrn) ? Getattr(wrn, "name") : 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_name_rename_add()
- *
- * Manage the rename objects
- *
- * ----------------------------------------------------------------------------- */
-
-static void single_rename_add(String *prefix, String *name, SwigType *decl, Hash *newname) {
- name_nameobj_add(name_rename_hash(), name_rename_list(), prefix, name, decl, newname);
-}
-
-/* Add a new rename. Works much like new_feature including default argument handling. */
-void Swig_name_rename_add(String *prefix, String *name, SwigType *decl, Hash *newname, ParmList *declaratorparms) {
-
- ParmList *declparms = declaratorparms;
-
- const char *rename_keys[] = { "fullname", "sourcefmt", "targetfmt", "continue", "regextarget", 0 };
- name_object_attach_keys(rename_keys, newname);
-
- /* Add the name */
- single_rename_add(prefix, name, decl, newname);
-
- /* Add extra names if there are default parameters in the parameter list */
- if (decl) {
- int constqualifier = SwigType_isconst(decl);
- while (declparms) {
- if (ParmList_has_defaultargs(declparms)) {
-
- /* Create a parameter list for the new rename by copying all
- but the last (defaulted) parameter */
- ParmList *newparms = CopyParmListMax(declparms,ParmList_len(declparms)-1);
-
- /* Create new declaration - with the last parameter removed */
- SwigType *newdecl = Copy(decl);
- Delete(SwigType_pop_function(newdecl)); /* remove the old parameter list from newdecl */
- SwigType_add_function(newdecl, newparms);
- if (constqualifier)
- SwigType_add_qualifier(newdecl, "const");
-
- single_rename_add(prefix, name, newdecl, newname);
- declparms = newparms;
- Delete(newdecl);
- } else {
- declparms = 0;
- }
- }
- }
-}
-
-
-/* Create a name for the given node applying rename/namewarn if needed */
-static String *apply_rename(Node* n, String *newname, int fullname, String *prefix, String *name) {
- String *result = 0;
- if (newname && Len(newname)) {
- if (Strcmp(newname, "$ignore") == 0) {
- /* $ignore doesn't apply to parameters and while it's rare to explicitly write %ignore directives for them they could be caught by a wildcard ignore using
- regex match, just ignore the attempt to ignore them in this case */
- if (!Equal(nodeType(n), "parm"))
- result = Copy(newname);
- } else {
- char *cnewname = Char(newname);
- if (cnewname) {
- int destructor = name && (*(Char(name)) == '~');
- String *fmt = newname;
- /* use name as a fmt, but avoid C++ "%" and "%=" operators */
- if (Len(newname) > 1 && strchr(cnewname, '%') && !(strcmp(cnewname, "%=") == 0)) {
- if (fullname && prefix) {
- result = NewStringf(fmt, prefix, name);
- } else {
- result = NewStringf(fmt, name);
- }
- } else {
- result = Copy(newname);
- }
- if (destructor && result && (*(Char(result)) != '~')) {
- Insert(result, 0, "~");
- }
- }
- }
- }
-
- return result;
-}
-
-/* -----------------------------------------------------------------------------
- * String *Swig_name_make()
- *
- * Make a name after applying all the rename/namewarn objects
- *
- * ----------------------------------------------------------------------------- */
-
-String *Swig_name_make(Node *n, String *prefix, const_String_or_char_ptr cname, SwigType *decl, String *oldname) {
- String *nname = 0;
- String *result = 0;
- String *name = NewString(cname);
- Hash *wrn = 0;
- String *rdecl = 0;
- String *rname = 0;
-
- /* very specific hack for template constructors/destructors */
-#ifdef SWIG_DEBUG
- Printf(stdout, "Swig_name_make: looking for %s %s %s %s\n", prefix, name, decl, oldname);
-#endif
-
- if (name && n && SwigType_istemplate(name)) {
- String *nodetype = nodeType(n);
- if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) {
- String *nprefix = 0;
- String *nlast = 0;
- String *tprefix;
- Swig_scopename_split(name, &nprefix, &nlast);
- tprefix = SwigType_templateprefix(nlast);
- Delete(nlast);
- if (Len(nprefix)) {
- Append(nprefix, "::");
- Append(nprefix, tprefix);
- Delete(tprefix);
- rname = nprefix;
- } else {
- rname = tprefix;
- Delete(nprefix);
- }
- rdecl = Copy(decl);
- Replaceall(rdecl, name, rname);
-#ifdef SWIG_DEBUG
- Printf(stdout, "SWIG_name_make: use new name %s %s : %s %s\n", name, decl, rname, rdecl);
-#endif
- decl = rdecl;
- Delete(name);
- name = rname;
- }
- }
-
- if (rename_hash || rename_list || namewarn_hash || namewarn_list) {
- Hash *rn = Swig_name_object_get(name_rename_hash(), prefix, name, decl);
- if (!rn || !name_match_nameobj(rn, n)) {
- rn = name_nameobj_lget(name_rename_list(), n, prefix, name, decl);
- if (rn) {
- String *sfmt = Getattr(rn, "sourcefmt");
- int fullname = GetFlag(rn, "fullname");
- if (fullname && prefix) {
- String *sname = NewStringf("%s::%s", prefix, name);
- Delete(name);
- name = sname;
- prefix = 0;
- }
- if (sfmt) {
- String *sname = NewStringf(sfmt, name);
- Delete(name);
- name = sname;
- }
- }
- }
- if (rn) {
- String *newname = Getattr(rn, "name");
- int fullname = GetFlag(rn, "fullname");
- result = apply_rename(n, newname, fullname, prefix, name);
- }
- if (result && !Equal(result, name)) {
- /* operators in C++ allow aliases, we look for them */
- char *cresult = Char(result);
- if (cresult && (strncmp(cresult, "operator ", 9) == 0)) {
- String *nresult = Swig_name_make(n, prefix, result, decl, oldname);
- if (!Equal(nresult, result)) {
- Delete(result);
- result = nresult;
- } else {
- Delete(nresult);
- }
- }
- }
- nname = result ? result : name;
- wrn = name_namewarn_get(n, prefix, nname, decl);
- if (wrn) {
- String *rename = Getattr(wrn, "rename");
- if (rename) {
- String *msg = Getattr(wrn, "name");
- int fullname = GetFlag(wrn, "fullname");
- if (result)
- Delete(result);
- result = apply_rename(n, rename, fullname, prefix, name);
- if ((msg) && (Len(msg))) {
- if (!Getmeta(nname, "already_warned")) {
- String* suffix = 0;
- if (Strcmp(result, "$ignore") == 0) {
- suffix = NewStringf(": ignoring '%s'\n", name);
- } else if (Strcmp(result, name) != 0) {
- suffix = NewStringf(", renaming to '%s'\n", result);
- } else {
- /* No rename was performed */
- suffix = NewString("\n");
- }
- if (n) {
- /* Parameter renaming is not fully implemented. Mainly because there is no C/C++ syntax to
- * for %rename to fully qualify a function's parameter name from outside the function. Hence it
- * is not possible to implemented targeted warning suppression on one parameter in one function. */
- int suppress_parameter_rename_warning = Equal(nodeType(n), "parm");
- if (!suppress_parameter_rename_warning) {
- SWIG_WARN_NODE_BEGIN(n);
- Swig_warning(0, Getfile(n), Getline(n), "%s%s", msg, suffix);
- SWIG_WARN_NODE_END(n);
- }
- } else {
- Swig_warning(0, Getfile(name), Getline(name), "%s%s", msg, suffix);
- }
- Setmeta(nname, "already_warned", "1");
- Delete(suffix);
- }
- }
- }
- }
- }
- if (!result || !Len(result)) {
- if (result)
- Delete(result);
- if (oldname) {
- result = NewString(oldname);
- } else {
- result = NewString(cname);
- }
- }
- Delete(name);
-
-#ifdef SWIG_DEBUG
- Printf(stdout, "Swig_name_make: result '%s' '%s'\n", cname, result);
-#endif
-
- return result;
-}
-
-/* -----------------------------------------------------------------------------
- * void Swig_name_inherit()
- *
- * Inherit namewarn, rename, and feature objects
- *
- * ----------------------------------------------------------------------------- */
-
-void Swig_name_inherit(String *base, String *derived) {
- /* Printf(stdout,"base = '%s', derived = '%s'\n", base, derived); */
- Swig_name_object_inherit(name_rename_hash(), base, derived);
- Swig_name_object_inherit(name_namewarn_hash(), base, derived);
- Swig_name_object_inherit(Swig_cparse_features(), base, derived);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_inherit_base_symbols()
- * ----------------------------------------------------------------------------- */
-
-void Swig_inherit_base_symbols(List *bases) {
- if (bases) {
- Iterator s;
- for (s = First(bases); s.item; s = Next(s)) {
- Symtab *st = Getattr(s.item, "symtab");
- if (st) {
- Setfile(st, Getfile(s.item));
- Setline(st, Getline(s.item));
- Swig_symbol_inherit(st);
- }
- }
- Delete(bases);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_make_inherit_list()
- * ----------------------------------------------------------------------------- */
-
-List *Swig_make_inherit_list(String *clsname, List *names, String *Namespaceprefix) {
- int i, ilen;
- String *derived;
- List *bases = NewList();
-
- if (Namespaceprefix)
- derived = NewStringf("%s::%s", Namespaceprefix, clsname);
- else
- derived = NewString(clsname);
-
- ilen = Len(names);
- for (i = 0; i < ilen; i++) {
- String *base;
- String *n = Getitem(names, i);
- /* Try to figure out where this symbol is */
- Node *s = Swig_symbol_clookup(n, 0);
- if (s) {
- while (s && (Strcmp(nodeType(s), "class") != 0)) {
- /* Not a class. Could be a typedef though. */
- String *storage = Getattr(s, "storage");
- if (storage && (Strcmp(storage, "typedef") == 0)) {
- String *nn = Getattr(s, "type");
- s = Swig_symbol_clookup(nn, Getattr(s, "sym:symtab"));
- } else {
- break;
- }
- }
- if (s && ((Strcmp(nodeType(s), "class") == 0) || (Strcmp(nodeType(s), "template") == 0))) {
- String *q = Swig_symbol_qualified(s);
- Append(bases, s);
- if (q) {
- base = NewStringf("%s::%s", q, Getattr(s, "name"));
- Delete(q);
- } else {
- base = NewString(Getattr(s, "name"));
- }
- } else {
- base = NewString(n);
- }
- } else {
- base = NewString(n);
- }
- if (base) {
- Swig_name_inherit(base, derived);
- Delete(base);
- }
- }
- return bases;
-}
-
-
-/* -----------------------------------------------------------------------------
- * void Swig_name_str()
- *
- * Return a stringified version of a C/C++ symbol from a node.
- * The node passed in is expected to be a function, constructor, destructor or
- * variable. Some example return values:
- * "MyNameSpace::MyTemplate<MyNameSpace::ABC >::~MyTemplate"
- * "MyNameSpace::ABC::ABC"
- * "MyNameSpace::ABC::constmethod"
- * "MyNameSpace::ABC::variablename"
- *
- * ----------------------------------------------------------------------------- */
-
-String *Swig_name_str(Node *n) {
- String *qname;
- String *qualifier = Swig_symbol_qualified(n);
- String *name = Swig_scopename_last(Getattr(n, "name"));
- if (qualifier)
- qualifier = SwigType_namestr(qualifier);
-
- /* Very specific hack for template constructors/destructors */
- if (SwigType_istemplate(name)) {
- String *nodetype = nodeType(n);
- if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) {
- String *nprefix = 0;
- String *nlast = 0;
- String *tprefix;
- Swig_scopename_split(name, &nprefix, &nlast);
- tprefix = SwigType_templateprefix(nlast);
- Delete(nlast);
- Delete(nprefix);
- Delete(name);
- name = tprefix;
- }
- }
-
- qname = NewString("");
- if (qualifier && Len(qualifier) > 0)
- Printf(qname, "%s::", qualifier);
- Printf(qname, "%s", SwigType_str(name, 0));
-
- Delete(name);
- Delete(qualifier);
-
- return qname;
-}
-
-/* -----------------------------------------------------------------------------
- * void Swig_name_decl()
- *
- * Return a stringified version of a C/C++ declaration without the return type.
- * The node passed in is expected to be a function, constructor, destructor or
- * variable. Some example return values:
- * "MyNameSpace::MyTemplate<MyNameSpace::ABC >::~MyTemplate()"
- * "MyNameSpace::ABC::ABC(int,double)"
- * "MyNameSpace::ABC::constmethod(int) const"
- * "MyNameSpace::ABC::refqualifiermethod(int) const &"
- * "MyNameSpace::ABC::variablename"
- *
- * ----------------------------------------------------------------------------- */
-
-String *Swig_name_decl(Node *n) {
- String *qname;
- String *decl;
-
- qname = Swig_name_str(n);
- decl = NewStringf("%s", qname);
-
- if (!checkAttribute(n, "kind", "variable")) {
- String *d = Getattr(n, "decl");
- Printv(decl, "(", ParmList_errorstr(Getattr(n, "parms")), ")", NIL);
- if (SwigType_isfunction(d)) {
- SwigType *decl_temp = Copy(d);
- SwigType *qualifiers = SwigType_pop_function_qualifiers(decl_temp);
- if (qualifiers) {
- String *qualifiers_string = SwigType_str(qualifiers, 0);
- Printv(decl, " ", qualifiers_string, NIL);
- Delete(qualifiers_string);
- }
- Delete(decl_temp);
- }
- }
-
- Delete(qname);
-
- return decl;
-}
-
-/* -----------------------------------------------------------------------------
- * void Swig_name_fulldecl()
- *
- * Return a stringified version of a C/C++ declaration including the return type.
- * The node passed in is expected to be a function, constructor or destructor.
- * Some example return values:
- * "MyNameSpace::MyTemplate<MyNameSpace::ABC >::~MyTemplate()"
- * "MyNameSpace::ABC::ABC(int,double)"
- * "int * MyNameSpace::ABC::constmethod(int) const"
- *
- * ----------------------------------------------------------------------------- */
-
-String *Swig_name_fulldecl(Node *n) {
- String *decl = Swig_name_decl(n);
- String *type = Getattr(n, "type");
- String *nodetype = nodeType(n);
- String *fulldecl;
- /* add on the return type */
- if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) {
- fulldecl = decl;
- } else {
- String *t = SwigType_str(type, 0);
- fulldecl = NewStringf("%s %s", t, decl);
- Delete(decl);
- Delete(t);
- }
- return fulldecl;
-}
-
diff --git a/contrib/tools/swig/Source/Swig/parms.c b/contrib/tools/swig/Source/Swig/parms.c
deleted file mode 100644
index 11071ce0cd..0000000000
--- a/contrib/tools/swig/Source/Swig/parms.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * parms.c
- *
- * Parameter list class.
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-
-/* ------------------------------------------------------------------------
- * NewParm()
- *
- * Create a new parameter from datatype 'type' and name 'name' copying
- * the file and line number from the Node from_node.
- * ------------------------------------------------------------------------ */
-
-Parm *NewParm(SwigType *type, const_String_or_char_ptr name, Node *from_node) {
- Parm *p = NewParmWithoutFileLineInfo(type, name);
- Setfile(p, Getfile(from_node));
- Setline(p, Getline(from_node));
- return p;
-}
-
-/* ------------------------------------------------------------------------
- * NewParmWithoutFileLineInfo()
- *
- * Create a new parameter from datatype 'type' and name 'name' without any
- * file / line numbering information.
- * ------------------------------------------------------------------------ */
-
-Parm *NewParmWithoutFileLineInfo(SwigType *type, const_String_or_char_ptr name) {
- Parm *p = NewHash();
- set_nodeType(p, "parm");
- if (type) {
- SwigType *ntype = Copy(type);
- Setattr(p, "type", ntype);
- Delete(ntype);
- }
- Setattr(p, "name", name);
- return p;
-}
-
-/* ------------------------------------------------------------------------
- * NewParmNode()
- *
- * Create a new parameter from datatype 'type' and name and symbol table as
- * well as file and line number from the 'from_node'.
- * The resulting Parm will be similar to a Node used for typemap lookups.
- * ------------------------------------------------------------------------ */
-
-Parm *NewParmNode(SwigType *type, Node *from_node) {
- Parm *p = NewParm(type, Getattr(from_node, "name"), from_node);
- Setattr(p, "sym:symtab", Getattr(from_node, "sym:symtab"));
- return p;
-}
-
-/* ------------------------------------------------------------------------
- * CopyParm()
- * ------------------------------------------------------------------------ */
-
-Parm *CopyParm(Parm *p) {
- Parm *np = NewHash();
- Iterator ki;
- for (ki = First(p); ki.key; ki = Next(ki)) {
- if (DohIsString(ki.item)) {
- DOH *c = Copy(ki.item);
- Setattr(np,ki.key,c);
- Delete(c);
- }
- }
- Setfile(np, Getfile(p));
- Setline(np, Getline(p));
- return np;
-}
-
-/* ------------------------------------------------------------------
- * CopyParmListMax()
- * CopyParmList()
- * ------------------------------------------------------------------ */
-
-ParmList *CopyParmListMax(ParmList *p, int count) {
- Parm *np;
- Parm *pp = 0;
- Parm *fp = 0;
-
- if (!p)
- return 0;
-
- while (p) {
- if (count == 0) break;
- np = CopyParm(p);
- if (pp) {
- set_nextSibling(pp, np);
- Delete(np);
- } else {
- fp = np;
- }
- pp = np;
- p = nextSibling(p);
- count--;
- }
- return fp;
-}
-
-ParmList *CopyParmList(ParmList *p) {
- return CopyParmListMax(p,-1);
-}
-
-/* -----------------------------------------------------------------------------
- * int ParmList_numrequired(). Return number of required arguments
- * ----------------------------------------------------------------------------- */
-
-int ParmList_numrequired(ParmList *p) {
- int i = 0;
- while (p) {
- SwigType *t = Getattr(p, "type");
- String *value = Getattr(p, "value");
- if (value)
- return i;
- if (!(SwigType_type(t) == T_VOID))
- i++;
- else
- break;
- p = nextSibling(p);
- }
- return i;
-}
-
-/* -----------------------------------------------------------------------------
- * int ParmList_len()
- * ----------------------------------------------------------------------------- */
-
-int ParmList_len(ParmList *p) {
- int i = 0;
- while (p) {
- i++;
- p = nextSibling(p);
- }
- return i;
-}
-
-/* ---------------------------------------------------------------------
- * get_empty_type()
- * ---------------------------------------------------------------------- */
-
-static SwigType *get_empty_type(void) {
- return NewStringEmpty();
-}
-
-/* ---------------------------------------------------------------------
- * ParmList_str()
- *
- * Generates a string of parameters
- * ---------------------------------------------------------------------- */
-
-String *ParmList_str(ParmList *p) {
- String *out = NewStringEmpty();
- while (p) {
- String *type = Getattr(p, "type");
- String *pstr = SwigType_str(type ? type : get_empty_type(), Getattr(p, "name"));
- Append(out, pstr);
- p = nextSibling(p);
- if (p) {
- Append(out, ",");
- }
- Delete(pstr);
- }
- return out;
-}
-
-/* ---------------------------------------------------------------------
- * ParmList_str_defaultargs()
- *
- * Generates a string of parameters including default arguments
- * ---------------------------------------------------------------------- */
-
-String *ParmList_str_defaultargs(ParmList *p) {
- String *out = NewStringEmpty();
- while (p) {
- String *value = Getattr(p, "value");
- String *type = Getattr(p, "type");
- String *pstr = SwigType_str(type ? type : get_empty_type(), Getattr(p, "name"));
- Append(out, pstr);
- if (value) {
- Printf(out, "=%s", value);
- }
- p = nextSibling(p);
- if (p) {
- Append(out, ",");
- }
- Delete(pstr);
- }
- return out;
-}
-
-/* -----------------------------------------------------------------------------
- * ParmList_str_multibrackets()
- *
- * Generates a string of parameters including default arguments adding brackets
- * if more than one parameter
- * ----------------------------------------------------------------------------- */
-
-String *ParmList_str_multibrackets(ParmList *p) {
- String *out;
- String *parm_str = ParmList_str_defaultargs(p);
- if (ParmList_len(p) > 1)
- out = NewStringf("(%s)", parm_str);
- else
- out = NewStringf("%s", parm_str);
- Delete(parm_str);
- return out;
-}
-
-/* ---------------------------------------------------------------------
- * ParmList_protostr()
- *
- * Generate a prototype string.
- * ---------------------------------------------------------------------- */
-
-String *ParmList_protostr(ParmList *p) {
- String *out = NewStringEmpty();
- while (p) {
- String *type = Getattr(p, "type");
- String *pstr = SwigType_str(type ? type : get_empty_type(), 0);
- Append(out, pstr);
- p = nextSibling(p);
- if (p) {
- Append(out, ",");
- }
- Delete(pstr);
- }
- return out;
-}
-
-/* ---------------------------------------------------------------------
- * ParmList_has_defaultargs()
- *
- * Returns 1 if the parameter list passed in is has one or more default
- * arguments. Otherwise returns 0.
- * ---------------------------------------------------------------------- */
-
-int ParmList_has_defaultargs(ParmList *p) {
- while (p) {
- if (Getattr(p, "value")) {
- return 1;
- }
- p = nextSibling(p);
- }
- return 0;
-}
-
-/* ---------------------------------------------------------------------
- * ParmList_has_varargs()
- *
- * Returns 1 if the parameter list passed in has varargs.
- * Otherwise returns 0.
- * ---------------------------------------------------------------------- */
-
-int ParmList_has_varargs(ParmList *p) {
- Parm *lp = 0;
- while (p) {
- lp = p;
- p = nextSibling(p);
- }
- return lp ? SwigType_isvarargs(Getattr(lp, "type")) : 0;
-}
diff --git a/contrib/tools/swig/Source/Swig/scanner.c b/contrib/tools/swig/Source/Swig/scanner.c
deleted file mode 100644
index 9dbb353648..0000000000
--- a/contrib/tools/swig/Source/Swig/scanner.c
+++ /dev/null
@@ -1,1898 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * scanner.c
- *
- * This file implements a general purpose C/C++ compatible lexical scanner.
- * This scanner isn't intended to be plugged directly into a parser built
- * with yacc. Rather, it contains a lot of generic code that could be used
- * to easily construct yacc-compatible scanners.
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-#include <ctype.h>
-
-extern String *cparse_file;
-extern int cparse_line;
-extern int cparse_cplusplus;
-extern int cparse_start_line;
-
-struct Scanner {
- String *text; /* Current token value */
- List *scanobjs; /* Objects being scanned */
- String *str; /* Current object being scanned */
- char *idstart; /* Optional identifier start characters */
- int nexttoken; /* Next token to be returned */
- int start_line; /* Starting line of certain declarations */
- int line;
- int yylen; /* Length of text pushed into text */
- String *file;
- String *error; /* Last error message (if any) */
- int error_line; /* Error line number */
- int freeze_line; /* Suspend line number updates */
- List *brackets; /* Current level of < > brackets on each level */
-};
-
-typedef struct Locator {
- String *filename;
- int line_number;
- struct Locator *next;
-} Locator;
-static int follow_locators = 0;
-
-static void brackets_push(Scanner *);
-static void brackets_clear(Scanner *);
-
-/* -----------------------------------------------------------------------------
- * NewScanner()
- *
- * Create a new scanner object
- * ----------------------------------------------------------------------------- */
-
-Scanner *NewScanner(void) {
- Scanner *s;
- s = (Scanner *) Malloc(sizeof(Scanner));
- s->line = 1;
- s->file = 0;
- s->nexttoken = -1;
- s->start_line = 1;
- s->yylen = 0;
- s->idstart = NULL;
- s->scanobjs = NewList();
- s->text = NewStringEmpty();
- s->str = 0;
- s->error = 0;
- s->error_line = 0;
- s->freeze_line = 0;
- s->brackets = NewList();
- brackets_push(s);
- return s;
-}
-
-/* -----------------------------------------------------------------------------
- * DelScanner()
- *
- * Delete a scanner object.
- * ----------------------------------------------------------------------------- */
-
-void DelScanner(Scanner *s) {
- assert(s);
- Delete(s->scanobjs);
- Delete(s->brackets);
- Delete(s->text);
- Delete(s->file);
- Delete(s->error);
- Delete(s->str);
- Free(s->idstart);
- Free(s);
-}
-
-/* -----------------------------------------------------------------------------
- * Scanner_clear()
- *
- * Clear the contents of a scanner object.
- * ----------------------------------------------------------------------------- */
-
-void Scanner_clear(Scanner *s) {
- assert(s);
- Delete(s->str);
- Clear(s->text);
- Clear(s->scanobjs);
- brackets_clear(s);
- Delete(s->error);
- s->str = 0;
- s->error = 0;
- s->line = 1;
- s->nexttoken = -1;
- s->start_line = 0;
- s->yylen = 0;
- /* Should these be cleared too?
- s->idstart;
- s->file;
- s->error_line;
- s->freeze_line;
- */
-}
-
-/* -----------------------------------------------------------------------------
- * Scanner_push()
- *
- * Push some new text into the scanner. The scanner will start parsing this text
- * immediately before returning to the old text.
- * ----------------------------------------------------------------------------- */
-
-void Scanner_push(Scanner *s, String *txt) {
- assert(s && txt);
- Push(s->scanobjs, txt);
- if (s->str) {
- Setline(s->str,s->line);
- Delete(s->str);
- }
- s->str = txt;
- DohIncref(s->str);
- s->line = Getline(txt);
-}
-
-/* -----------------------------------------------------------------------------
- * Scanner_pushtoken()
- *
- * Push a token into the scanner. This token will be returned on the next
- * call to Scanner_token().
- * ----------------------------------------------------------------------------- */
-
-void Scanner_pushtoken(Scanner *s, int nt, const_String_or_char_ptr val) {
- assert(s);
- assert((nt >= 0) && (nt < SWIG_MAXTOKENS));
- s->nexttoken = nt;
- if ( Char(val) != Char(s->text) ) {
- Clear(s->text);
- Append(s->text,val);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Scanner_set_location()
- *
- * Set the file and line number location of the scanner.
- * ----------------------------------------------------------------------------- */
-
-void Scanner_set_location(Scanner *s, String *file, int line) {
- Setline(s->str, line);
- Setfile(s->str, file);
- s->line = line;
-}
-
-/* -----------------------------------------------------------------------------
- * Scanner_file()
- *
- * Get the current file.
- * ----------------------------------------------------------------------------- */
-
-String *Scanner_file(Scanner *s) {
- return Getfile(s->str);
-}
-
-/* -----------------------------------------------------------------------------
- * Scanner_line()
- *
- * Get the current line number
- * ----------------------------------------------------------------------------- */
-int Scanner_line(Scanner *s) {
- return s->line;
-}
-
-/* -----------------------------------------------------------------------------
- * Scanner_start_line()
- *
- * Get the line number on which the current token starts
- * ----------------------------------------------------------------------------- */
-int Scanner_start_line(Scanner *s) {
- return s->start_line;
-}
-
-/* -----------------------------------------------------------------------------
- * Scanner_idstart()
- *
- * Change the set of additional characters that can be used to start an identifier.
- * ----------------------------------------------------------------------------- */
-
-void Scanner_idstart(Scanner *s, const char *id) {
- Free(s->idstart);
- s->idstart = Swig_copy_string(id);
-}
-
-/* -----------------------------------------------------------------------------
- * nextchar()
- *
- * Returns the next character from the scanner or 0 if end of the string.
- * ----------------------------------------------------------------------------- */
-static char nextchar(Scanner *s) {
- int nc;
- if (!s->str)
- return 0;
- while ((nc = Getc(s->str)) == EOF) {
- Delete(s->str);
- s->str = 0;
- Delitem(s->scanobjs, 0);
- if (Len(s->scanobjs) == 0)
- return 0;
- s->str = Getitem(s->scanobjs, 0);
- s->line = Getline(s->str);
- DohIncref(s->str);
- }
- if ((nc == '\n') && (!s->freeze_line))
- s->line++;
- Putc(nc,s->text);
- return (char)nc;
-}
-
-/* -----------------------------------------------------------------------------
- * set_error()
- *
- * Sets error information on the scanner.
- * ----------------------------------------------------------------------------- */
-
-static void set_error(Scanner *s, int line, const_String_or_char_ptr msg) {
- s->error_line = line;
- s->error = NewString(msg);
-}
-
-/* -----------------------------------------------------------------------------
- * Scanner_errmsg()
- * Scanner_errline()
- *
- * Returns error information (if any)
- * ----------------------------------------------------------------------------- */
-
-String *Scanner_errmsg(Scanner *s) {
- return s->error;
-}
-
-int Scanner_errline(Scanner *s) {
- return s->error_line;
-}
-
-/* -----------------------------------------------------------------------------
- * freeze_line()
- *
- * Freezes the current line number.
- * ----------------------------------------------------------------------------- */
-
-static void freeze_line(Scanner *s, int val) {
- s->freeze_line = val;
-}
-
-/* -----------------------------------------------------------------------------
- * brackets_count()
- *
- * Returns the number of brackets at the current depth.
- * A syntax error with unbalanced ) brackets will result in a NULL pointer return.
- * ----------------------------------------------------------------------------- */
-static int *brackets_count(Scanner *s) {
- int *count;
- if (Len(s->brackets) > 0)
- count = (int *)Data(Getitem(s->brackets, 0));
- else
- count = 0;
- return count;
-}
-
-/* -----------------------------------------------------------------------------
- * brackets_clear()
- *
- * Resets the current depth and clears all brackets.
- * Usually called at the end of statements;
- * ----------------------------------------------------------------------------- */
-static void brackets_clear(Scanner *s) {
- Clear(s->brackets);
- brackets_push(s); /* base bracket count should always be created */
-}
-
-/* -----------------------------------------------------------------------------
- * brackets_increment()
- *
- * Increases the number of brackets at the current depth.
- * Usually called when a single '<' is found.
- * ----------------------------------------------------------------------------- */
-static void brackets_increment(Scanner *s) {
- int *count = brackets_count(s);
- if (count)
- (*count)++;
-}
-
-/* -----------------------------------------------------------------------------
- * brackets_decrement()
- *
- * Decreases the number of brackets at the current depth.
- * Usually called when a single '>' is found.
- * ----------------------------------------------------------------------------- */
-static void brackets_decrement(Scanner *s) {
- int *count = brackets_count(s);
- if (count)
- (*count)--;
-}
-
-/* -----------------------------------------------------------------------------
- * brackets_reset()
- *
- * Sets the number of '<' brackets back to zero. Called at the point where
- * it is no longer possible to have a matching closing >> pair for a template.
- * ----------------------------------------------------------------------------- */
-static void brackets_reset(Scanner *s) {
- int *count = brackets_count(s);
- if (count)
- *count = 0;
-}
-
-/* -----------------------------------------------------------------------------
- * brackets_push()
- *
- * Increases the depth of brackets.
- * Usually called when '(' is found.
- * ----------------------------------------------------------------------------- */
-static void brackets_push(Scanner *s) {
- int *newInt = (int *)Malloc(sizeof(int));
- *newInt = 0;
- Push(s->brackets, NewVoid(newInt, Free));
-}
-
-/* -----------------------------------------------------------------------------
- * brackets_pop()
- *
- * Decreases the depth of brackets.
- * Usually called when ')' is found.
- * ----------------------------------------------------------------------------- */
-static void brackets_pop(Scanner *s) {
- if (Len(s->brackets) > 0) /* protect against unbalanced ')' brackets */
- Delitem(s->brackets, 0);
-}
-
-/* -----------------------------------------------------------------------------
- * brackets_allow_shift()
- *
- * Return 1 to allow shift (>>), or 0 if (>>) should be split into (> >).
- * This is for C++11 template syntax for closing templates.
- * ----------------------------------------------------------------------------- */
-static int brackets_allow_shift(Scanner *s) {
- int *count = brackets_count(s);
- return !count || (*count <= 0);
-}
-
-/* -----------------------------------------------------------------------------
- * retract()
- *
- * Retract n characters
- * ----------------------------------------------------------------------------- */
-static void retract(Scanner *s, int n) {
- int i, l;
- char *str;
-
- str = Char(s->text);
- l = Len(s->text);
- assert(n <= l);
- for (i = 0; i < n; i++) {
- if (str[l - 1] == '\n') {
- if (!s->freeze_line) s->line--;
- }
- (void)Seek(s->str, -1, SEEK_CUR);
- Delitem(s->text, DOH_END);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * get_escape()
- *
- * Get escape sequence. Called when a backslash is found in a string
- * ----------------------------------------------------------------------------- */
-
-static void get_escape(Scanner *s) {
- int result = 0;
- int state = 0;
- int c;
-
- while (1) {
- c = nextchar(s);
- if (c == 0)
- break;
- switch (state) {
- case 0:
- if (c == 'n') {
- Delitem(s->text, DOH_END);
- Append(s->text,"\n");
- return;
- }
- if (c == 'r') {
- Delitem(s->text, DOH_END);
- Append(s->text,"\r");
- return;
- }
- if (c == 't') {
- Delitem(s->text, DOH_END);
- Append(s->text,"\t");
- return;
- }
- if (c == 'a') {
- Delitem(s->text, DOH_END);
- Append(s->text,"\a");
- return;
- }
- if (c == 'b') {
- Delitem(s->text, DOH_END);
- Append(s->text,"\b");
- return;
- }
- if (c == 'f') {
- Delitem(s->text, DOH_END);
- Append(s->text,"\f");
- return;
- }
- if (c == '\\') {
- Delitem(s->text, DOH_END);
- Append(s->text,"\\");
- return;
- }
- if (c == 'v') {
- Delitem(s->text, DOH_END);
- Append(s->text,"\v");
- return;
- }
- if (c == 'e') {
- Delitem(s->text, DOH_END);
- Append(s->text,"\033");
- return;
- }
- if (c == '\'') {
- Delitem(s->text, DOH_END);
- Append(s->text,"\'");
- return;
- }
- if (c == '\"') {
- Delitem(s->text, DOH_END);
- Append(s->text,"\"");
- return;
- }
- if (c == '\n') {
- Delitem(s->text, DOH_END);
- return;
- }
- if (isdigit(c)) {
- state = 10;
- result = (c - '0');
- Delitem(s->text, DOH_END);
- } else if (c == 'x') {
- state = 20;
- Delitem(s->text, DOH_END);
- } else {
- char tmp[3];
- tmp[0] = '\\';
- tmp[1] = (char)c;
- tmp[2] = 0;
- Delitem(s->text, DOH_END);
- Append(s->text, tmp);
- return;
- }
- break;
- case 10:
- if (!isdigit(c)) {
- retract(s,1);
- Putc((char)result,s->text);
- return;
- }
- result = (result << 3) + (c - '0');
- Delitem(s->text, DOH_END);
- break;
- case 20:
- if (!isxdigit(c)) {
- retract(s,1);
- Putc((char)result, s->text);
- return;
- }
- if (isdigit(c))
- result = (result << 4) + (c - '0');
- else
- result = (result << 4) + (10 + tolower(c) - 'a');
- Delitem(s->text, DOH_END);
- break;
- }
- }
- return;
-}
-
-/* -----------------------------------------------------------------------------
- * look()
- *
- * Return the raw value of the next token.
- * ----------------------------------------------------------------------------- */
-
-static int look(Scanner *s) {
- int state = 0;
- int c = 0;
- String *str_delimiter = 0;
-
- Clear(s->text);
- s->start_line = s->line;
- Setfile(s->text, Getfile(s->str));
-
-
- while (1) {
- switch (state) {
- case 0:
- if ((c = nextchar(s)) == 0)
- return (0);
-
- /* Process delimiters */
-
- if (c == '\n') {
- return SWIG_TOKEN_ENDLINE;
- } else if (!isspace(c)) {
- retract(s, 1);
- state = 1000;
- Clear(s->text);
- Setline(s->text, s->line);
- Setfile(s->text, Getfile(s->str));
- }
- break;
-
- case 1000:
- if ((c = nextchar(s)) == 0)
- return (0);
- if (c == '%')
- state = 4; /* Possibly a SWIG directive */
-
- /* Look for possible identifiers or unicode/delimiter strings */
- else if ((isalpha(c)) || (c == '_') ||
- (s->idstart && strchr(s->idstart, c))) {
- state = 7;
- }
-
- /* Look for single character symbols */
-
- else if (c == '(') {
- brackets_push(s);
- return SWIG_TOKEN_LPAREN;
- }
- else if (c == ')') {
- brackets_pop(s);
- return SWIG_TOKEN_RPAREN;
- }
- else if (c == ';') {
- brackets_clear(s);
- return SWIG_TOKEN_SEMI;
- }
- else if (c == ',')
- return SWIG_TOKEN_COMMA;
- else if (c == '*')
- state = 220;
- else if (c == '}')
- return SWIG_TOKEN_RBRACE;
- else if (c == '{') {
- brackets_reset(s);
- return SWIG_TOKEN_LBRACE;
- }
- else if (c == '=')
- state = 33;
- else if (c == '+')
- state = 200;
- else if (c == '-')
- state = 210;
- else if (c == '&')
- state = 31;
- else if (c == '|')
- state = 32;
- else if (c == '^')
- state = 230;
- else if (c == '<')
- state = 60;
- else if (c == '>')
- state = 61;
- else if (c == '~')
- return SWIG_TOKEN_NOT;
- else if (c == '!')
- state = 3;
- else if (c == '\\')
- return SWIG_TOKEN_BACKSLASH;
- else if (c == '@')
- return SWIG_TOKEN_AT;
- else if (c == '$')
- state = 75;
- else if (c == '#')
- return SWIG_TOKEN_POUND;
- else if (c == '?')
- return SWIG_TOKEN_QUESTION;
-
- /* Look for multi-character sequences */
-
- else if (c == '/') {
- state = 1; /* Comment (maybe) */
- s->start_line = s->line;
- }
-
- else if (c == ':')
- state = 5; /* maybe double colon */
- else if (c == '0')
- state = 83; /* An octal or hex value */
- else if (c == '\"') {
- state = 2; /* A string constant */
- s->start_line = s->line;
- Clear(s->text);
- }
- else if (c == '\'') {
- s->start_line = s->line;
- Clear(s->text);
- state = 9; /* A character constant */
- } else if (c == '`') {
- s->start_line = s->line;
- Clear(s->text);
- state = 900;
- }
-
- else if (c == '.')
- state = 100; /* Maybe a number, maybe ellipsis, just a period */
- else if (c == '[')
- state = 102; /* Maybe a bracket or a double bracket */
- else if (c == ']')
- state = 103; /* Maybe a bracket or a double bracket */
- else if (isdigit(c))
- state = 8; /* A numerical value */
- else
- state = 99; /* An error */
- break;
-
- case 1: /* Comment block */
- if ((c = nextchar(s)) == 0)
- return (0);
- if (c == '/') {
- state = 10; /* C++ style comment */
- Clear(s->text);
- Setline(s->text, Getline(s->str));
- Setfile(s->text, Getfile(s->str));
- Append(s->text, "//");
- } else if (c == '*') {
- state = 11; /* C style comment */
- Clear(s->text);
- Setline(s->text, Getline(s->str));
- Setfile(s->text, Getfile(s->str));
- Append(s->text, "/*");
- } else if (c == '=') {
- return SWIG_TOKEN_DIVEQUAL;
- } else {
- retract(s, 1);
- return SWIG_TOKEN_SLASH;
- }
- break;
- case 10: /* C++ style comment */
- if ((c = nextchar(s)) == 0) {
- Swig_error(cparse_file, cparse_start_line, "Unterminated comment\n");
- return SWIG_TOKEN_ERROR;
- }
- if (c == '\n') {
- retract(s,1);
- return SWIG_TOKEN_COMMENT;
- } else {
- state = 10;
- }
- break;
- case 11: /* C style comment block */
- if ((c = nextchar(s)) == 0) {
- Swig_error(cparse_file, cparse_start_line, "Unterminated comment\n");
- return SWIG_TOKEN_ERROR;
- }
- if (c == '*') {
- state = 12;
- } else {
- state = 11;
- }
- break;
- case 12: /* Still in C style comment */
- if ((c = nextchar(s)) == 0) {
- Swig_error(cparse_file, cparse_start_line, "Unterminated comment\n");
- return SWIG_TOKEN_ERROR;
- }
- if (c == '*') {
- state = 12;
- } else if (c == '/') {
- return SWIG_TOKEN_COMMENT;
- } else {
- state = 11;
- }
- break;
-
- case 2: /* Processing a string */
- if (!str_delimiter) {
- state=20;
- break;
- }
-
- if ((c = nextchar(s)) == 0) {
- Swig_error(cparse_file, cparse_start_line, "Unterminated string\n");
- return SWIG_TOKEN_ERROR;
- }
- else if (c == '(') {
- state = 20;
- }
- else {
- char temp[2] = { 0, 0 };
- temp[0] = c;
- Append( str_delimiter, temp );
- }
-
- break;
-
- case 20: /* Inside the string */
- if ((c = nextchar(s)) == 0) {
- Swig_error(cparse_file, cparse_start_line, "Unterminated string\n");
- return SWIG_TOKEN_ERROR;
- }
-
- if (!str_delimiter) { /* Ordinary string: "value" */
- if (c == '\"') {
- Delitem(s->text, DOH_END);
- return SWIG_TOKEN_STRING;
- } else if (c == '\\') {
- Delitem(s->text, DOH_END);
- get_escape(s);
- }
- } else { /* Custom delimiter string: R"XXXX(value)XXXX" */
- if (c==')') {
- int i=0;
- String *end_delimiter = NewStringEmpty();
- while ((c = nextchar(s)) != 0 && c!='\"') {
- char temp[2] = { 0, 0 };
- temp[0] = c;
- Append( end_delimiter, temp );
- i++;
- }
-
- if (Strcmp( str_delimiter, end_delimiter )==0) {
- int len = Len(s->text);
- Delslice(s->text, len - 2 - Len(str_delimiter), len); /* Delete ending )XXXX" */
- Delslice(s->text, 0, Len(str_delimiter) + 1); /* Delete starting XXXX( */
- Delete( end_delimiter ); /* Correct end delimiter )XXXX" occurred */
- Delete( str_delimiter );
- str_delimiter = 0;
- return SWIG_TOKEN_STRING;
- } else { /* Incorrect end delimiter occurred */
- if (c == 0) {
- Swig_error(cparse_file, cparse_start_line, "Unterminated raw string, started with R\"%s( is not terminated by )%s\"\n", str_delimiter, str_delimiter);
- return SWIG_TOKEN_ERROR;
- }
- retract( s, i );
- Delete( end_delimiter );
- }
- }
- }
-
- break;
-
- case 3: /* Maybe a not equals */
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_LNOT;
- else if (c == '=')
- return SWIG_TOKEN_NOTEQUAL;
- else {
- retract(s, 1);
- return SWIG_TOKEN_LNOT;
- }
- break;
-
- case 31: /* AND or Logical AND or ANDEQUAL */
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_AND;
- else if (c == '&')
- return SWIG_TOKEN_LAND;
- else if (c == '=')
- return SWIG_TOKEN_ANDEQUAL;
- else {
- retract(s, 1);
- return SWIG_TOKEN_AND;
- }
- break;
-
- case 32: /* OR or Logical OR */
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_OR;
- else if (c == '|')
- return SWIG_TOKEN_LOR;
- else if (c == '=')
- return SWIG_TOKEN_OREQUAL;
- else {
- retract(s, 1);
- return SWIG_TOKEN_OR;
- }
- break;
-
- case 33: /* EQUAL or EQUALTO */
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_EQUAL;
- else if (c == '=')
- return SWIG_TOKEN_EQUALTO;
- else {
- retract(s, 1);
- return SWIG_TOKEN_EQUAL;
- }
- break;
-
- case 4: /* A wrapper generator directive (maybe) */
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_PERCENT;
- if (c == '{') {
- state = 40; /* Include block */
- Clear(s->text);
- Setline(s->text, Getline(s->str));
- Setfile(s->text, Getfile(s->str));
- s->start_line = s->line;
- } else if (s->idstart && strchr(s->idstart, '%') &&
- ((isalpha(c)) || (c == '_'))) {
- state = 7;
- } else if (c == '=') {
- return SWIG_TOKEN_MODEQUAL;
- } else if (c == '}') {
- Swig_error(cparse_file, cparse_line, "Syntax error. Extraneous '%%}'\n");
- Exit(EXIT_FAILURE);
- } else {
- retract(s, 1);
- return SWIG_TOKEN_PERCENT;
- }
- break;
-
- case 40: /* Process an include block */
- if ((c = nextchar(s)) == 0) {
- Swig_error(cparse_file, cparse_start_line, "Unterminated block\n");
- return SWIG_TOKEN_ERROR;
- }
- if (c == '%')
- state = 41;
- break;
- case 41: /* Still processing include block */
- if ((c = nextchar(s)) == 0) {
- set_error(s,s->start_line,"Unterminated code block");
- return 0;
- }
- if (c == '}') {
- Delitem(s->text, DOH_END);
- Delitem(s->text, DOH_END);
- Seek(s->text,0,SEEK_SET);
- return SWIG_TOKEN_CODEBLOCK;
- } else {
- state = 40;
- }
- break;
-
- case 5: /* Maybe a double colon */
-
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_COLON;
- if (c == ':')
- state = 50;
- else {
- retract(s, 1);
- return SWIG_TOKEN_COLON;
- }
- break;
-
- case 50: /* DCOLON, DCOLONSTAR */
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_DCOLON;
- else if (c == '*')
- return SWIG_TOKEN_DCOLONSTAR;
- else {
- retract(s, 1);
- return SWIG_TOKEN_DCOLON;
- }
- break;
-
- case 60: /* shift operators */
- if ((c = nextchar(s)) == 0) {
- brackets_increment(s);
- return SWIG_TOKEN_LESSTHAN;
- }
- if (c == '<')
- state = 240;
- else if (c == '=') {
- if ((c = nextchar(s)) == 0) {
- return SWIG_TOKEN_LTEQUAL;
- } else if (c == '>' && cparse_cplusplus) { /* Spaceship operator */
- return SWIG_TOKEN_LTEQUALGT;
- } else {
- retract(s, 1);
- return SWIG_TOKEN_LTEQUAL;
- }
- } else {
- retract(s, 1);
- brackets_increment(s);
- return SWIG_TOKEN_LESSTHAN;
- }
- break;
- case 61:
- if ((c = nextchar(s)) == 0) {
- brackets_decrement(s);
- return SWIG_TOKEN_GREATERTHAN;
- }
- if (c == '>' && brackets_allow_shift(s))
- state = 250;
- else if (c == '=')
- return SWIG_TOKEN_GTEQUAL;
- else {
- retract(s, 1);
- brackets_decrement(s);
- return SWIG_TOKEN_GREATERTHAN;
- }
- break;
-
- case 7: /* Identifier or true/false or unicode/custom delimiter string */
- if (c == 'R') { /* Possibly CUSTOM DELIMITER string */
- state = 72;
- break;
- }
- else if (c == 'L') { /* Probably identifier but may be a wide string literal */
- state = 77;
- break;
- }
- else if (c != 'u' && c != 'U') { /* Definitely an identifier */
- state = 70;
- break;
- }
-
- if ((c = nextchar(s)) == 0) {
- state = 76;
- }
- else if (c == '\"') { /* Definitely u, U or L string */
- retract(s, 1);
- state = 1000;
- }
- else if (c == '\'') { /* Definitely u, U or L char */
- retract(s, 1);
- state = 77;
- }
- else if (c == 'R') { /* Possibly CUSTOM DELIMITER u, U, L string */
- state = 73;
- }
- else if (c == '8') { /* Possibly u8 string/char */
- state = 71;
- }
- else {
- retract(s, 1); /* Definitely an identifier */
- state = 70;
- }
- break;
-
- case 70: /* Identifier */
- if ((c = nextchar(s)) == 0)
- state = 76;
- else if (isalnum(c) || (c == '_') || (c == '$')) {
- state = 70;
- } else {
- retract(s, 1);
- state = 76;
- }
- break;
-
- case 71: /* Possibly u8 string/char */
- if ((c = nextchar(s)) == 0) {
- state = 76;
- }
- else if (c=='\"') {
- retract(s, 1); /* Definitely u8 string */
- state = 1000;
- }
- else if (c=='\'') {
- retract(s, 1); /* Definitely u8 char */
- state = 77;
- }
- else if (c=='R') {
- state = 74; /* Possibly CUSTOM DELIMITER u8 string */
- }
- else {
- retract(s, 2); /* Definitely an identifier. Retract 8" */
- state = 70;
- }
-
- break;
-
- case 72: /* Possibly CUSTOM DELIMITER string */
- case 73:
- case 74:
- if ((c = nextchar(s)) == 0) {
- state = 76;
- }
- else if (c=='\"') {
- retract(s, 1); /* Definitely custom delimiter u, U or L string */
- str_delimiter = NewStringEmpty();
- state = 1000;
- }
- else {
- if (state==72) {
- retract(s, 1); /* Definitely an identifier. Retract ? */
- }
- else if (state==73) {
- retract(s, 2); /* Definitely an identifier. Retract R? */
- }
- else if (state==74) {
- retract(s, 3); /* Definitely an identifier. Retract 8R? */
- }
- state = 70;
- }
-
- break;
-
- case 75: /* Special identifier $ */
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_DOLLAR;
- if (isalnum(c) || (c == '_') || (c == '*') || (c == '&')) {
- state = 70;
- } else {
- retract(s,1);
- if (Len(s->text) == 1) return SWIG_TOKEN_DOLLAR;
- state = 76;
- }
- break;
-
- case 76: /* Identifier or true/false */
- if (cparse_cplusplus) {
- if (Strcmp(s->text, "true") == 0)
- return SWIG_TOKEN_BOOL;
- else if (Strcmp(s->text, "false") == 0)
- return SWIG_TOKEN_BOOL;
- }
- return SWIG_TOKEN_ID;
- break;
-
- case 77: /*identifier or wide string literal*/
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_ID;
- else if (c == '\"') {
- s->start_line = s->line;
- Clear(s->text);
- state = 78;
- }
- else if (c == '\'') {
- s->start_line = s->line;
- Clear(s->text);
- state = 79;
- }
- else if (isalnum(c) || (c == '_') || (c == '$'))
- state = 7;
- else {
- retract(s, 1);
- return SWIG_TOKEN_ID;
- }
- break;
-
- case 78: /* Processing a wide string literal*/
- if ((c = nextchar(s)) == 0) {
- Swig_error(cparse_file, cparse_start_line, "Unterminated wide string\n");
- return SWIG_TOKEN_ERROR;
- }
- if (c == '\"') {
- Delitem(s->text, DOH_END);
- return SWIG_TOKEN_WSTRING;
- } else if (c == '\\') {
- if ((c = nextchar(s)) == 0) {
- Swig_error(cparse_file, cparse_start_line, "Unterminated wide string\n");
- return SWIG_TOKEN_ERROR;
- }
- }
- break;
-
- case 79: /* Processing a wide char literal */
- if ((c = nextchar(s)) == 0) {
- Swig_error(cparse_file, cparse_start_line, "Unterminated wide character constant\n");
- return SWIG_TOKEN_ERROR;
- }
- if (c == '\'') {
- Delitem(s->text, DOH_END);
- return (SWIG_TOKEN_WCHAR);
- } else if (c == '\\') {
- if ((c = nextchar(s)) == 0) {
- Swig_error(cparse_file, cparse_start_line, "Unterminated wide character literal\n");
- return SWIG_TOKEN_ERROR;
- }
- }
- break;
-
- case 8: /* A numerical digit */
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_INT;
- if (c == '.') {
- state = 81;
- } else if ((c == 'e') || (c == 'E')) {
- state = 82;
- } else if ((c == 'f') || (c == 'F')) {
- Delitem(s->text, DOH_END);
- return SWIG_TOKEN_FLOAT;
- } else if (isdigit(c)) {
- state = 8;
- } else if ((c == 'l') || (c == 'L')) {
- state = 87;
- } else if ((c == 'u') || (c == 'U')) {
- state = 88;
- } else {
- retract(s, 1);
- return SWIG_TOKEN_INT;
- }
- break;
- case 81: /* A floating pointer number of some sort */
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_DOUBLE;
- if (isdigit(c))
- state = 81;
- else if ((c == 'e') || (c == 'E'))
- state = 820;
- else if ((c == 'f') || (c == 'F')) {
- Delitem(s->text, DOH_END);
- return SWIG_TOKEN_FLOAT;
- } else if ((c == 'l') || (c == 'L')) {
- Delitem(s->text, DOH_END);
- return SWIG_TOKEN_DOUBLE;
- } else {
- retract(s, 1);
- return (SWIG_TOKEN_DOUBLE);
- }
- break;
- case 82:
- if ((c = nextchar(s)) == 0) {
- Swig_error(cparse_file, cparse_start_line, "Exponent does not have any digits\n");
- return SWIG_TOKEN_ERROR;
- }
- if ((isdigit(c)) || (c == '-') || (c == '+'))
- state = 86;
- else {
- retract(s, 2);
- Swig_error(cparse_file, cparse_start_line, "Exponent does not have any digits\n");
- return SWIG_TOKEN_ERROR;
- }
- break;
- case 820:
- /* Like case 82, but we've seen a decimal point. */
- if ((c = nextchar(s)) == 0) {
- Swig_error(cparse_file, cparse_start_line, "Exponent does not have any digits\n");
- return SWIG_TOKEN_ERROR;
- }
- if ((isdigit(c)) || (c == '-') || (c == '+'))
- state = 86;
- else {
- retract(s, 2);
- Swig_error(cparse_file, cparse_start_line, "Exponent does not have any digits\n");
- return SWIG_TOKEN_ERROR;
- }
- break;
- case 83:
- /* Might be a hexadecimal or octal number */
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_INT;
- if (isdigit(c))
- state = 84;
- else if ((c == 'e') || (c == 'E'))
- state = 82;
- else if ((c == 'x') || (c == 'X'))
- state = 85;
- else if ((c == 'b') || (c == 'B'))
- state = 850;
- else if (c == '.')
- state = 81;
- else if ((c == 'l') || (c == 'L')) {
- state = 87;
- } else if ((c == 'u') || (c == 'U')) {
- state = 88;
- } else {
- retract(s, 1);
- return SWIG_TOKEN_INT;
- }
- break;
- case 84:
- /* This is an octal number */
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_INT;
- if (isdigit(c))
- state = 84;
- else if (c == '.')
- state = 81;
- else if ((c == 'e') || (c == 'E'))
- state = 82;
- else if ((c == 'l') || (c == 'L')) {
- state = 87;
- } else if ((c == 'u') || (c == 'U')) {
- state = 88;
- } else {
- retract(s, 1);
- return SWIG_TOKEN_INT;
- }
- break;
- case 85:
- /* This is an hex number */
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_INT;
- if (isxdigit(c))
- state = 85;
- else if (c == '.') /* hexadecimal float */
- state = 860;
- else if ((c == 'p') || (c == 'P')) /* hexadecimal float */
- state = 820;
- else if ((c == 'l') || (c == 'L')) {
- state = 87;
- } else if ((c == 'u') || (c == 'U')) {
- state = 88;
- } else {
- retract(s, 1);
- return SWIG_TOKEN_INT;
- }
- break;
- case 850:
- /* This is a binary number */
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_INT;
- if ((c == '0') || (c == '1'))
- state = 850;
- else if ((c == 'l') || (c == 'L')) {
- state = 87;
- } else if ((c == 'u') || (c == 'U')) {
- state = 88;
- } else {
- retract(s, 1);
- return SWIG_TOKEN_INT;
- }
- break;
- case 860:
- /* hexadecimal float */
- if ((c = nextchar(s)) == 0) {
- Swig_error(cparse_file, cparse_start_line, "Hexadecimal floating literals require an exponent\n");
- return SWIG_TOKEN_ERROR;
- }
- if (isxdigit(c))
- state = 860;
- else if ((c == 'p') || (c == 'P'))
- state = 820;
- else {
- retract(s, 2);
- Swig_error(cparse_file, cparse_start_line, "Hexadecimal floating literals require an exponent\n");
- return SWIG_TOKEN_ERROR;
- }
- break;
- case 86:
- /* Rest of floating point number */
-
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_DOUBLE;
- if (isdigit(c))
- state = 86;
- else if ((c == 'f') || (c == 'F')) {
- Delitem(s->text, DOH_END);
- return SWIG_TOKEN_FLOAT;
- } else if ((c == 'l') || (c == 'L')) {
- Delitem(s->text, DOH_END);
- return SWIG_TOKEN_DOUBLE;
- } else {
- retract(s, 1);
- return SWIG_TOKEN_DOUBLE;
- }
- break;
-
- case 87:
- /* A long integer of some sort */
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_LONG;
- if ((c == 'u') || (c == 'U')) {
- return SWIG_TOKEN_ULONG;
- } else if ((c == 'l') || (c == 'L')) {
- state = 870;
- } else {
- retract(s, 1);
- return SWIG_TOKEN_LONG;
- }
- break;
-
- /* A long long integer */
-
- case 870:
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_LONGLONG;
- if ((c == 'u') || (c == 'U')) {
- return SWIG_TOKEN_ULONGLONG;
- } else {
- retract(s, 1);
- return SWIG_TOKEN_LONGLONG;
- }
-
- /* An unsigned number */
- case 88:
-
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_UINT;
- if ((c == 'l') || (c == 'L')) {
- state = 880;
- } else {
- retract(s, 1);
- return SWIG_TOKEN_UINT;
- }
- break;
-
- /* Possibly an unsigned long long or unsigned long */
- case 880:
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_ULONG;
- if ((c == 'l') || (c == 'L'))
- return SWIG_TOKEN_ULONGLONG;
- else {
- retract(s, 1);
- return SWIG_TOKEN_ULONG;
- }
-
- /* A character constant */
- case 9:
- if ((c = nextchar(s)) == 0) {
- Swig_error(cparse_file, cparse_start_line, "Unterminated character constant\n");
- return SWIG_TOKEN_ERROR;
- }
- if (c == '\'') {
- Delitem(s->text, DOH_END);
- return (SWIG_TOKEN_CHAR);
- } else if (c == '\\') {
- Delitem(s->text, DOH_END);
- get_escape(s);
- }
- break;
-
- /* A period or an ellipsis or maybe a floating point number */
-
- case 100:
- if ((c = nextchar(s)) == 0)
- return (0);
- if (isdigit(c))
- state = 81;
- else if (c == '.')
- state = 101;
- else {
- retract(s, 1);
- return SWIG_TOKEN_PERIOD;
- }
- break;
-
- /* An ellipsis */
-
- case 101:
- if ((c = nextchar(s)) == 0)
- return (0);
- if (c == '.') {
- return SWIG_TOKEN_ELLIPSIS;
- } else {
- retract(s, 2);
- return SWIG_TOKEN_PERIOD;
- }
- break;
-
- /* A left bracket or a double left bracket */
- case 102:
-
- if ((c = nextchar(s)) == 0) {
- return SWIG_TOKEN_LBRACKET;
- } else if (c == '[') {
- return SWIG_TOKEN_LLBRACKET;
- } else {
- retract(s, 1);
- return SWIG_TOKEN_LBRACKET;
- }
- break;
-
- /* a right bracket or a double right bracket */
- case 103:
- if ((c = nextchar(s)) == 0) {
- return SWIG_TOKEN_RBRACKET;
- } else if (c == ']') {
- return SWIG_TOKEN_RRBRACKET;
- } else {
- retract(s, 1);
- return SWIG_TOKEN_RBRACKET;
- }
- break;
-
- case 200: /* PLUS, PLUSPLUS, PLUSEQUAL */
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_PLUS;
- else if (c == '+')
- return SWIG_TOKEN_PLUSPLUS;
- else if (c == '=')
- return SWIG_TOKEN_PLUSEQUAL;
- else {
- retract(s, 1);
- return SWIG_TOKEN_PLUS;
- }
- break;
-
- case 210: /* MINUS, MINUSMINUS, MINUSEQUAL, ARROW */
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_MINUS;
- else if (c == '-')
- return SWIG_TOKEN_MINUSMINUS;
- else if (c == '=')
- return SWIG_TOKEN_MINUSEQUAL;
- else if (c == '>')
- state = 211;
- else {
- retract(s, 1);
- return SWIG_TOKEN_MINUS;
- }
- break;
-
- case 211: /* ARROW, ARROWSTAR */
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_ARROW;
- else if (c == '*')
- return SWIG_TOKEN_ARROWSTAR;
- else {
- retract(s, 1);
- return SWIG_TOKEN_ARROW;
- }
- break;
-
-
- case 220: /* STAR, TIMESEQUAL */
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_STAR;
- else if (c == '=')
- return SWIG_TOKEN_TIMESEQUAL;
- else {
- retract(s, 1);
- return SWIG_TOKEN_STAR;
- }
- break;
-
- case 230: /* XOR, XOREQUAL */
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_XOR;
- else if (c == '=')
- return SWIG_TOKEN_XOREQUAL;
- else {
- retract(s, 1);
- return SWIG_TOKEN_XOR;
- }
- break;
-
- case 240: /* LSHIFT, LSEQUAL */
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_LSHIFT;
- else if (c == '=')
- return SWIG_TOKEN_LSEQUAL;
- else {
- retract(s, 1);
- return SWIG_TOKEN_LSHIFT;
- }
- break;
-
- case 250: /* RSHIFT, RSEQUAL */
- if ((c = nextchar(s)) == 0)
- return SWIG_TOKEN_RSHIFT;
- else if (c == '=')
- return SWIG_TOKEN_RSEQUAL;
- else {
- retract(s, 1);
- return SWIG_TOKEN_RSHIFT;
- }
- break;
-
-
- /* An illegal character */
-
- /* Reverse string */
- case 900:
- if ((c = nextchar(s)) == 0) {
- Swig_error(cparse_file, cparse_start_line, "Unterminated character constant\n");
- return SWIG_TOKEN_ERROR;
- }
- if (c == '`') {
- Delitem(s->text, DOH_END);
- return (SWIG_TOKEN_RSTRING);
- }
- break;
-
- default:
- return SWIG_TOKEN_ILLEGAL;
- }
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Scanner_token()
- *
- * Real entry point to return the next token. Returns 0 if at end of input.
- * ----------------------------------------------------------------------------- */
-
-int Scanner_token(Scanner *s) {
- int t;
- Delete(s->error);
- if (s->nexttoken >= 0) {
- t = s->nexttoken;
- s->nexttoken = -1;
- return t;
- }
- s->start_line = 0;
- t = look(s);
- if (!s->start_line) {
- Setline(s->text,s->line);
- } else {
- Setline(s->text,s->start_line);
- }
- return t;
-}
-
-/* -----------------------------------------------------------------------------
- * Scanner_text()
- *
- * Return the lexene associated with the last returned token.
- * ----------------------------------------------------------------------------- */
-
-String *Scanner_text(Scanner *s) {
- return s->text;
-}
-
-/* -----------------------------------------------------------------------------
- * Scanner_skip_line()
- *
- * Skips to the end of a line
- * ----------------------------------------------------------------------------- */
-
-void Scanner_skip_line(Scanner *s) {
- char c;
- int done = 0;
- Clear(s->text);
- Setfile(s->text, Getfile(s->str));
- Setline(s->text, s->line);
- while (!done) {
- if ((c = nextchar(s)) == 0)
- return;
- if (c == '\\') {
- nextchar(s);
- } else if (c == '\n') {
- done = 1;
- }
- }
- return;
-}
-
-/* -----------------------------------------------------------------------------
- * Scanner_skip_balanced()
- *
- * Skips a piece of code enclosed in begin/end symbols such as '{...}' or
- * (...). Ignores symbols inside comments or strings.
- * ----------------------------------------------------------------------------- */
-
-int Scanner_skip_balanced(Scanner *s, int startchar, int endchar) {
- char c;
- int num_levels = 1;
- int state = 0;
- char temp[2] = { 0, 0 };
- String *locator = 0;
- temp[0] = (char) startchar;
- Clear(s->text);
- Setfile(s->text, Getfile(s->str));
- Setline(s->text, s->line);
-
- Append(s->text, temp);
- while (num_levels > 0) {
- if ((c = nextchar(s)) == 0) {
- Delete(locator);
- return -1;
- }
- switch (state) {
- case 0:
- if (c == startchar)
- num_levels++;
- else if (c == endchar)
- num_levels--;
- else if (c == '/')
- state = 10;
- else if (c == '\"')
- state = 20;
- else if (c == '\'')
- state = 30;
- break;
- case 10:
- if (c == '/')
- state = 11;
- else if (c == '*')
- state = 12;
- else if (c == startchar) {
- state = 0;
- num_levels++;
- }
- else
- state = 0;
- break;
- case 11:
- if (c == '\n')
- state = 0;
- else
- state = 11;
- break;
- case 12: /* first character inside C comment */
- if (c == '*')
- state = 14;
- else if (c == '@')
- state = 40;
- else
- state = 13;
- break;
- case 13:
- if (c == '*')
- state = 14;
- break;
- case 14: /* possible end of C comment */
- if (c == '*')
- state = 14;
- else if (c == '/')
- state = 0;
- else
- state = 13;
- break;
- case 20:
- if (c == '\"')
- state = 0;
- else if (c == '\\')
- state = 21;
- break;
- case 21:
- state = 20;
- break;
- case 30:
- if (c == '\'')
- state = 0;
- else if (c == '\\')
- state = 31;
- break;
- case 31:
- state = 30;
- break;
- /* 40-45 SWIG locator checks - a C comment with contents starting: @SWIG */
- case 40:
- state = (c == 'S') ? 41 : (c == '*') ? 14 : 13;
- break;
- case 41:
- state = (c == 'W') ? 42 : (c == '*') ? 14 : 13;
- break;
- case 42:
- state = (c == 'I') ? 43 : (c == '*') ? 14 : 13;
- break;
- case 43:
- state = (c == 'G') ? 44 : (c == '*') ? 14 : 13;
- if (c == 'G') {
- Delete(locator);
- locator = NewString("/*@SWIG");
- }
- break;
- case 44:
- if (c == '*')
- state = 45;
- Putc(c, locator);
- break;
- case 45: /* end of SWIG locator in C comment */
- if (c == '/') {
- state = 0;
- Putc(c, locator);
- Scanner_locator(s, locator);
- } else {
- /* malformed locator */
- state = (c == '*') ? 14 : 13;
- }
- break;
- default:
- break;
- }
- }
- Delete(locator);
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Scanner_get_raw_text_balanced()
- *
- * Returns raw text between 2 braces, does not change scanner state in any way
- * ----------------------------------------------------------------------------- */
-
-String *Scanner_get_raw_text_balanced(Scanner *s, int startchar, int endchar) {
- String *result = 0;
- char c;
- int old_line = s->line;
- String *old_text = Copy(s->text);
- long position = Tell(s->str);
-
- int num_levels = 1;
- int state = 0;
- char temp[2] = { 0, 0 };
- temp[0] = (char) startchar;
- Clear(s->text);
- Setfile(s->text, Getfile(s->str));
- Setline(s->text, s->line);
- Append(s->text, temp);
- while (num_levels > 0) {
- if ((c = nextchar(s)) == 0) {
- Clear(s->text);
- Append(s->text, old_text);
- Delete(old_text);
- s->line = old_line;
- return 0;
- }
- switch (state) {
- case 0:
- if (c == startchar)
- num_levels++;
- else if (c == endchar)
- num_levels--;
- else if (c == '/')
- state = 10;
- else if (c == '\"')
- state = 20;
- else if (c == '\'')
- state = 30;
- break;
- case 10:
- if (c == '/')
- state = 11;
- else if (c == '*')
- state = 12;
- else if (c == startchar) {
- state = 0;
- num_levels++;
- }
- else
- state = 0;
- break;
- case 11:
- if (c == '\n')
- state = 0;
- else
- state = 11;
- break;
- case 12: /* first character inside C comment */
- if (c == '*')
- state = 14;
- else
- state = 13;
- break;
- case 13:
- if (c == '*')
- state = 14;
- break;
- case 14: /* possible end of C comment */
- if (c == '*')
- state = 14;
- else if (c == '/')
- state = 0;
- else
- state = 13;
- break;
- case 20:
- if (c == '\"')
- state = 0;
- else if (c == '\\')
- state = 21;
- break;
- case 21:
- state = 20;
- break;
- case 30:
- if (c == '\'')
- state = 0;
- else if (c == '\\')
- state = 31;
- break;
- case 31:
- state = 30;
- break;
- default:
- break;
- }
- }
- Seek(s->str, position, SEEK_SET);
- result = Copy(s->text);
- Clear(s->text);
- Append(s->text, old_text);
- Delete(old_text);
- s->line = old_line;
- return result;
-}
-/* -----------------------------------------------------------------------------
- * Scanner_isoperator()
- *
- * Returns 0 or 1 depending on whether or not a token corresponds to a C/C++
- * operator.
- * ----------------------------------------------------------------------------- */
-
-int Scanner_isoperator(int tokval) {
- if (tokval >= 100) return 1;
- return 0;
-}
-
-/* ----------------------------------------------------------------------
- * locator()
- *
- * Support for locator strings. These are strings of the form
- * @SWIG:filename,line,id@ emitted by the SWIG preprocessor. They
- * are primarily used for macro line number reporting.
- * We just use the locator to mark when to activate/deactivate linecounting.
- * ---------------------------------------------------------------------- */
-
-
-void Scanner_locator(Scanner *s, String *loc) {
- static Locator *locs = 0;
- static int expanding_macro = 0;
-
- if (!follow_locators) {
- if (Equal(loc, "/*@SWIG@*/")) {
- /* End locator. */
- if (expanding_macro)
- --expanding_macro;
- } else {
- /* Begin locator. */
- ++expanding_macro;
- }
- /* Freeze line number processing in Scanner */
- freeze_line(s,expanding_macro);
- } else {
- int c;
- Locator *l;
- (void)Seek(loc, 7, SEEK_SET);
- c = Getc(loc);
- if (c == '@') {
- /* Empty locator. We pop the last location off */
- if (locs) {
- Scanner_set_location(s, locs->filename, locs->line_number);
- cparse_file = locs->filename;
- cparse_line = locs->line_number;
- l = locs->next;
- Free(locs);
- locs = l;
- }
- return;
- }
-
- /* We're going to push a new location */
- l = (Locator *) Malloc(sizeof(Locator));
- l->filename = cparse_file;
- l->line_number = cparse_line;
- l->next = locs;
- locs = l;
-
- /* Now, parse the new location out of the locator string */
- {
- String *fn = NewStringEmpty();
- /* Putc(c, fn); */
-
- while ((c = Getc(loc)) != EOF) {
- if ((c == '@') || (c == ','))
- break;
- Putc(c, fn);
- }
- cparse_file = Swig_copy_string(Char(fn));
- Clear(fn);
- cparse_line = 1;
- /* Get the line number */
- while ((c = Getc(loc)) != EOF) {
- if ((c == '@') || (c == ','))
- break;
- Putc(c, fn);
- }
- cparse_line = atoi(Char(fn));
- Clear(fn);
-
- /* Get the rest of it */
- while ((c = Getc(loc)) != EOF) {
- if (c == '@')
- break;
- Putc(c, fn);
- }
- /* Swig_diagnostic(cparse_file, cparse_line, "Scanner_set_location\n"); */
- Scanner_set_location(s, cparse_file, cparse_line);
- Delete(fn);
- }
- }
-}
-
-void Swig_cparse_follow_locators(int v) {
- follow_locators = v;
-}
-
-
diff --git a/contrib/tools/swig/Source/Swig/stype.c b/contrib/tools/swig/Source/Swig/stype.c
deleted file mode 100644
index f227778f6c..0000000000
--- a/contrib/tools/swig/Source/Swig/stype.c
+++ /dev/null
@@ -1,1422 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * stype.c
- *
- * This file provides general support for datatypes that are encoded in
- * the form of simple strings.
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-#include "cparse.h"
-#include <ctype.h>
-
-/* -----------------------------------------------------------------------------
- * Synopsis
- *
- * The purpose of this module is to provide a general purpose type representation
- * based on simple text strings.
- *
- * General idea:
- *
- * Types are represented by a base type (e.g., "int") and a collection of
- * type operators applied to the base (e.g., pointers, arrays, etc...).
- *
- * Encoding:
- *
- * Types are encoded as strings of type constructors such as follows:
- *
- * String Encoding C Example
- * --------------- ---------
- * p.p.int int **
- * a(300).a(400).int int [300][400]
- * p.q(const).char char const *
- *
- * All type constructors are denoted by a trailing '.':
- *
- * 'p.' = Pointer (*)
- * 'r.' = Reference (&)
- * 'z.' = Rvalue reference (&&)
- * 'a(n).' = Array of size n [n]
- * 'f(..,..).' = Function with arguments (args)
- * 'q(str).' = Qualifier, such as const or volatile (cv-qualifier)
- * 'm(cls).' = Pointer to member (cls::*)
- *
- * The encoding follows the order that you might describe a type in words.
- * For example "p.a(200).int" is "A pointer to array of int's" and
- * "p.q(const).char" is "a pointer to a const char".
- *
- * This representation of types is fairly convenient because ordinary string
- * operations can be used for type manipulation. For example, a type could be
- * formed by combining two strings such as the following:
- *
- * "p.p." + "a(400).int" = "p.p.a(400).int"
- *
- * Similarly, one could strip a 'const' declaration from a type doing something
- * like this:
- *
- * Replace(t,"q(const).","",DOH_REPLACE_ANY)
- *
- * More examples:
- *
- * String Encoding C++ Example
- * --------------- -----------
- * p.f(bool).r.q(const).long const long & (*)(bool)
- * m(Funcs).q(const).f(bool).long long (Funcs::*)(bool) const
- * r.q(const).m(Funcs).f(int).long long (Funcs::*const &)(int)
- * m(Funcs).z.q(const).f(bool).long long (Funcs::*)(bool) const &&
- *
- * Function decl examples:
- *
- * f(bool). long a(bool);
- * r.f(bool). long b(bool) &;
- * z.f(bool). long c(bool) &&;
- * z.q(const).f(bool). long d(bool) const &&;
- *
- * For the most part, this module tries to minimize the use of special
- * characters (*, [, <, etc...) in its type encoding. One reason for this
- * is that SWIG might be extended to encode data in formats such as XML
- * where you might want to do this:
- *
- * <function>
- * <type>p.p.int</type>
- * ...
- * </function>
- *
- * Or alternatively,
- *
- * <function type="p.p.int" ...>blah</function>
- *
- * In either case, it's probably best to avoid characters such as '&', '*', or '<'.
- *
- * Why not use C syntax? Well, C syntax is fairly complicated to parse
- * and not particularly easy to manipulate---especially for adding, deleting and
- * composing type constructors. The string representation presented here makes
- * this pretty easy.
- *
- * Why not use a bunch of nested data structures? Are you kidding? How
- * would that be easier to use than a few simple string operations?
- * ----------------------------------------------------------------------------- */
-
-
-SwigType *NewSwigType(int t) {
- switch (t) {
- case T_BOOL:
- return NewString("bool");
- break;
- case T_INT:
- return NewString("int");
- break;
- case T_UINT:
- return NewString("unsigned int");
- break;
- case T_SHORT:
- return NewString("short");
- break;
- case T_USHORT:
- return NewString("unsigned short");
- break;
- case T_LONG:
- return NewString("long");
- break;
- case T_ULONG:
- return NewString("unsigned long");
- break;
- case T_FLOAT:
- return NewString("float");
- break;
- case T_DOUBLE:
- return NewString("double");
- break;
- case T_COMPLEX:
- return NewString("_Complex");
- break;
- case T_CHAR:
- return NewString("char");
- break;
- case T_SCHAR:
- return NewString("signed char");
- break;
- case T_UCHAR:
- return NewString("unsigned char");
- break;
- case T_STRING: {
- SwigType *t = NewString("char");
- SwigType_add_qualifier(t, "const");
- SwigType_add_pointer(t);
- return t;
- break;
- }
- case T_WCHAR:
- return NewString("wchar_t");
- break;
- case T_WSTRING: {
- SwigType *t = NewString("wchar_t");
- SwigType_add_pointer(t);
- return t;
- break;
- }
- case T_LONGLONG:
- return NewString("long long");
- break;
- case T_ULONGLONG:
- return NewString("unsigned long long");
- break;
- case T_VOID:
- return NewString("void");
- break;
- case T_AUTO:
- return NewString("auto");
- break;
- default:
- break;
- }
- return NewStringEmpty();
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_push()
- *
- * Push a type constructor onto the type
- * ----------------------------------------------------------------------------- */
-
-void SwigType_push(SwigType *t, String *cons) {
- if (!cons)
- return;
- if (!Len(cons))
- return;
-
- if (Len(t)) {
- char *c = Char(cons);
- if (c[strlen(c) - 1] != '.')
- Insert(t, 0, ".");
- }
- Insert(t, 0, cons);
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_ispointer_return()
- *
- * Testing functions for querying a raw datatype
- * ----------------------------------------------------------------------------- */
-
-int SwigType_ispointer_return(const SwigType *t) {
- char *c;
- int idx;
- if (!t)
- return 0;
- c = Char(t);
- idx = (int)strlen(c) - 4;
- if (idx >= 0) {
- return (strcmp(c + idx, ").p.") == 0);
- }
- return 0;
-}
-
-int SwigType_isreference_return(const SwigType *t) {
- char *c;
- int idx;
- if (!t)
- return 0;
- c = Char(t);
- idx = (int)strlen(c) - 4;
- if (idx >= 0) {
- return (strcmp(c + idx, ").r.") == 0);
- }
- return 0;
-}
-
-int SwigType_isconst(const SwigType *t) {
- char *c;
- if (!t)
- return 0;
- c = Char(t);
- if (strncmp(c, "q(", 2) == 0) {
- String *q = SwigType_parm(t);
- if (strstr(Char(q), "const")) {
- Delete(q);
- return 1;
- }
- Delete(q);
- }
- /* Hmmm. Might be const through a typedef */
- if (SwigType_issimple(t)) {
- int ret;
- SwigType *td = SwigType_typedef_resolve(t);
- if (td) {
- ret = SwigType_isconst(td);
- Delete(td);
- return ret;
- }
- }
- return 0;
-}
-
-int SwigType_ismutable(const SwigType *t) {
- int r;
- SwigType *qt = SwigType_typedef_resolve_all(t);
- if (SwigType_isreference(qt) || SwigType_isrvalue_reference(qt) || SwigType_isarray(qt)) {
- Delete(SwigType_pop(qt));
- }
- r = SwigType_isconst(qt);
- Delete(qt);
- return r ? 0 : 1;
-}
-
-int SwigType_isenum(const SwigType *t) {
- char *c = Char(t);
- if (!t)
- return 0;
- if (strncmp(c, "enum ", 5) == 0) {
- return 1;
- }
- return 0;
-}
-
-int SwigType_issimple(const SwigType *t) {
- char *c = Char(t);
- if (!t)
- return 0;
- while (*c) {
- if (*c == '<') {
- int nest = 1;
- c++;
- while (*c && nest) {
- if (*c == '<')
- nest++;
- if (*c == '>')
- nest--;
- c++;
- }
- c--;
- }
- if (*c == '.')
- return 0;
- c++;
- }
- return 1;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_default_create()
- *
- * Create the default type for this datatype. This takes a type and strips it
- * down to a generic form first by resolving all typedefs.
- *
- * Rules:
- * Pointers: p.SWIGTYPE
- * References: r.SWIGTYPE
- * Arrays no dimension: a().SWIGTYPE
- * Arrays with dimension: a(ANY).SWIGTYPE
- * Member pointer: m(CLASS).SWIGTYPE
- * Function pointer: f(ANY).SWIGTYPE
- * Enums: enum SWIGTYPE
- * Types: SWIGTYPE
- *
- * Examples (also see SwigType_default_deduce):
- *
- * int [2][4]
- * a(2).a(4).int
- * a(ANY).a(ANY).SWIGTYPE
- *
- * struct A {};
- * typedef A *Aptr;
- * Aptr const &
- * r.q(const).Aptr
- * r.q(const).p.SWIGTYPE
- *
- * enum E {e1, e2};
- * enum E const &
- * r.q(const).enum E
- * r.q(const).enum SWIGTYPE
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_default_create(const SwigType *ty) {
- SwigType *r = 0;
- List *l;
- Iterator it;
- int numitems;
-
- if (!SwigType_isvarargs(ty)) {
- SwigType *t = SwigType_typedef_resolve_all(ty);
- r = NewStringEmpty();
- l = SwigType_split(t);
- numitems = Len(l);
-
- if (numitems >= 1) {
- String *last_subtype = Getitem(l, numitems-1);
- if (SwigType_isenum(last_subtype))
- Setitem(l, numitems-1, NewString("enum SWIGTYPE"));
- else
- Setitem(l, numitems-1, NewString("SWIGTYPE"));
- }
-
- for (it = First(l); it.item; it = Next(it)) {
- String *subtype = it.item;
- if (SwigType_isarray(subtype)) {
- if (Equal(subtype, "a()."))
- Append(r, NewString("a()."));
- else
- Append(r, NewString("a(ANY)."));
- } else if (SwigType_isfunction(subtype)) {
- Append(r, NewString("f(ANY).SWIGTYPE"));
- break;
- } else if (SwigType_ismemberpointer(subtype)) {
- Append(r, NewString("m(CLASS).SWIGTYPE"));
- break;
- } else {
- Append(r, subtype);
- }
- }
-
- Delete(l);
- Delete(t);
- }
-
- return r;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_default_deduce()
- *
- * This function implements type deduction used in the typemap matching rules
- * and is very close to the type deduction used in partial template class
- * specialization matching in that the most specialized type is always chosen.
- * SWIGTYPE is used as the generic type. The basic idea is to repeatedly call
- * this function to find a deduced type until nothing matches.
- *
- * The type t must have already been converted to the default type via a call to
- * SwigType_default_create() before calling this function.
- *
- * Example deductions (matching the examples described in SwigType_default_create),
- * where the most specialized matches are highest in the list:
- *
- * a(ANY).a(ANY).SWIGTYPE
- * a(ANY).a().SWIGTYPE
- * a(ANY).p.SWIGTYPE
- * a(ANY).SWIGTYPE
- * a().SWIGTYPE
- * p.SWIGTYPE
- * SWIGTYPE
- *
- * r.q(const).p.SWIGTYPE
- * r.q(const).SWIGTYPE
- * r.SWIGTYPE
- * SWIGTYPE
- *
- * r.q(const).enum SWIGTYPE
- * r.enum SWIGTYPE
- * r.SWIGTYPE
- * SWIGTYPE
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_default_deduce(const SwigType *t) {
- SwigType *r = NewStringEmpty();
- List *l;
- Iterator it;
- int numitems;
-
- l = SwigType_split(t);
-
- numitems = Len(l);
- if (numitems >= 1) {
- String *last_subtype = Getitem(l, numitems-1);
- int is_enum = SwigType_isenum(last_subtype);
-
- if (numitems >=2 ) {
- String *subtype = Getitem(l, numitems-2); /* last but one */
- if (SwigType_isarray(subtype)) {
- if (is_enum) {
- /* enum deduction, enum SWIGTYPE => SWIGTYPE */
- Setitem(l, numitems-1, NewString("SWIGTYPE"));
- } else {
- /* array deduction, a(ANY). => a(). => p. */
- String *deduced_subtype = 0;
- if (Strcmp(subtype, "a().") == 0) {
- deduced_subtype = NewString("p.");
- } else if (Strcmp(subtype, "a(ANY).") == 0) {
- deduced_subtype = NewString("a().");
- } else {
- assert(0);
- }
- Setitem(l, numitems-2, deduced_subtype);
- }
- } else if (SwigType_ismemberpointer(subtype)) {
- /* member pointer deduction, m(CLASS). => p. */
- Setitem(l, numitems-2, NewString("p."));
- } else if (is_enum && !SwigType_isqualifier(subtype)) {
- /* enum deduction, enum SWIGTYPE => SWIGTYPE */
- Setitem(l, numitems-1, NewString("SWIGTYPE"));
- } else {
- /* simple type deduction, eg, r.p.p. => r.p. */
- /* also function pointers eg, p.f(ANY). => p. */
- Delitem(l, numitems-2);
- }
- } else {
- if (is_enum) {
- /* enum deduction, enum SWIGTYPE => SWIGTYPE */
- Setitem(l, numitems-1, NewString("SWIGTYPE"));
- } else {
- /* delete the only item, we are done with deduction */
- Delitem(l, 0);
- }
- }
- } else {
- assert(0);
- }
-
- for (it = First(l); it.item; it = Next(it)) {
- Append(r, it.item);
- }
-
- if (Len(r) == 0) {
- Delete(r);
- r = 0;
- }
-
- Delete(l);
- return r;
-}
-
-
-/* -----------------------------------------------------------------------------
- * SwigType_namestr()
- *
- * Returns a string of the base type. Takes care of template expansions
- * ----------------------------------------------------------------------------- */
-
-String *SwigType_namestr(const SwigType *t) {
- String *r;
- String *suffix;
- List *p;
- int i, sz;
- char *d = Char(t);
- char *c = strstr(d, "<(");
-
- if (!c || !strstr(c + 2, ")>"))
- return NewString(t);
-
- r = NewStringWithSize(d, (int)(c - d));
- if (*(c - 1) == '<')
- Putc(' ', r);
- Putc('<', r);
-
- p = SwigType_parmlist(c + 1);
- sz = Len(p);
- for (i = 0; i < sz; i++) {
- String *str = SwigType_str(Getitem(p, i), 0);
- /* Avoid creating a <: token, which is the same as [ in C++ - put a space after '<'. */
- if (i == 0 && Len(str))
- Putc(' ', r);
- Append(r, str);
- if ((i + 1) < sz)
- Putc(',', r);
- Delete(str);
- }
- Putc(' ', r);
- Putc('>', r);
- suffix = SwigType_templatesuffix(t);
- if (Len(suffix) > 0) {
- String *suffix_namestr = SwigType_namestr(suffix);
- Append(r, suffix_namestr);
- Delete(suffix_namestr);
- } else {
- Append(r, suffix);
- }
- Delete(suffix);
- Delete(p);
- return r;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_str()
- *
- * Create a C string representation of a datatype.
- * ----------------------------------------------------------------------------- */
-
-String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) {
- String *result;
- String *element = 0;
- String *nextelement;
- String *forwardelement;
- SwigType *member_function_qualifiers = 0;
- List *elements;
- int nelements, i;
-
- if (id) {
- /* stringify the id expanding templates, for example when the id is a fully qualified templated class name */
- String *id_str = NewString(id); /* unfortunate copy due to current const limitations */
- result = SwigType_str(id_str, 0);
- Delete(id_str);
- } else {
- result = NewStringEmpty();
- }
-
- elements = SwigType_split(s);
- nelements = Len(elements);
-
- if (nelements > 0) {
- element = Getitem(elements, 0);
- }
- /* Now, walk the type list and start emitting */
- for (i = 0; i < nelements; i++) {
- if (i < (nelements - 1)) {
- nextelement = Getitem(elements, i + 1);
- forwardelement = nextelement;
- if (SwigType_isqualifier(nextelement)) {
- if (i < (nelements - 2))
- forwardelement = Getitem(elements, i + 2);
- }
- } else {
- nextelement = 0;
- forwardelement = 0;
- }
- if (SwigType_isqualifier(element)) {
- if (!member_function_qualifiers) {
- DOH *q = 0;
- q = SwigType_parm(element);
- Insert(result, 0, " ");
- Insert(result, 0, q);
- Delete(q);
- }
- } else if (SwigType_ispointer(element)) {
- Insert(result, 0, "*");
- if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
- Insert(result, 0, "(");
- Append(result, ")");
- }
- } else if (SwigType_ismemberpointer(element)) {
- String *q;
- q = SwigType_parm(element);
- Insert(result, 0, "::*");
- Insert(result, 0, q);
- if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
- Insert(result, 0, "(");
- Append(result, ")");
- }
- {
- String *next3elements = NewStringEmpty();
- int j;
- for (j = i + 1; j < i + 4 && j < nelements; j++) {
- Append(next3elements, Getitem(elements, j));
- }
- if (SwigType_isfunction(next3elements))
- member_function_qualifiers = SwigType_pop_function_qualifiers(next3elements);
- Delete(next3elements);
- }
- Delete(q);
- } else if (SwigType_isreference(element)) {
- if (!member_function_qualifiers)
- Insert(result, 0, "&");
- if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
- Insert(result, 0, "(");
- Append(result, ")");
- }
- } else if (SwigType_isrvalue_reference(element)) {
- if (!member_function_qualifiers)
- Insert(result, 0, "&&");
- if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
- Insert(result, 0, "(");
- Append(result, ")");
- }
- } else if (SwigType_isarray(element)) {
- DOH *size;
- Append(result, "[");
- size = SwigType_parm(element);
- Append(result, size);
- Append(result, "]");
- Delete(size);
- } else if (SwigType_isfunction(element)) {
- DOH *parms, *p;
- int j, plen;
- Append(result, "(");
- parms = SwigType_parmlist(element);
- plen = Len(parms);
- for (j = 0; j < plen; j++) {
- p = SwigType_str(Getitem(parms, j), 0);
- Append(result, p);
- if (j < (plen - 1))
- Append(result, ",");
- }
- Append(result, ")");
- if (member_function_qualifiers) {
- String *p = SwigType_str(member_function_qualifiers, 0);
- Append(result, " ");
- Append(result, p);
- Delete(p);
- Delete(member_function_qualifiers);
- member_function_qualifiers = 0;
- }
- Delete(parms);
- } else {
- if (strcmp(Char(element), "v(...)") == 0) {
- Insert(result, 0, "...");
- } else {
- String *bs = SwigType_namestr(element);
- Insert(result, 0, " ");
- Insert(result, 0, bs);
- Delete(bs);
- }
- }
- element = nextelement;
- }
- Delete(elements);
- Chop(result);
- return result;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_ltype(const SwigType *ty)
- *
- * Create a locally assignable type
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_ltype(const SwigType *s) {
- String *result;
- String *element;
- SwigType *td, *tc = 0;
- List *elements;
- int nelements, i;
- int firstarray = 1;
- int notypeconv = 0;
- int ignore_member_function_qualifiers = 0;
-
- result = NewStringEmpty();
- tc = Copy(s);
- /* Nuke all leading qualifiers */
- while (SwigType_isqualifier(tc)) {
- Delete(SwigType_pop(tc));
- }
- if (SwigType_issimple(tc)) {
- /* Resolve any typedef definitions */
- SwigType *tt = Copy(tc);
- td = 0;
- while ((td = SwigType_typedef_resolve(tt))) {
- if (td && (SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td) || SwigType_isrvalue_reference(td))) {
- /* We need to use the typedef type */
- Delete(tt);
- break;
- } else if (td) {
- Delete(tt);
- tt = td;
- }
- }
- if (td) {
- Delete(tc);
- tc = td;
- }
- }
-
- elements = SwigType_split(tc);
- nelements = Len(elements);
-
- /* Now, walk the type list and start emitting */
- for (i = 0; i < nelements; i++) {
- element = Getitem(elements, i);
- /* when we see a function, we need to preserve the following types */
- if (SwigType_isfunction(element)) {
- notypeconv = 1;
- ignore_member_function_qualifiers = 0;
- }
- if (ignore_member_function_qualifiers) {
- /* cv-qualifiers and ref-qualifiers up until the f() element have already been added */
- } else if (SwigType_isqualifier(element)) {
- /* swallow cv-qualifiers */
- } else if (SwigType_ispointer(element)) {
- Append(result, element);
- firstarray = 0;
- } else if (SwigType_ismemberpointer(element)) {
- Append(result, element);
- {
- String *next3elements = NewStringEmpty();
- int j;
- for (j = i + 1; j < i + 4 && j < nelements; j++) {
- Append(next3elements, Getitem(elements, j));
- }
- if (SwigType_isfunction(next3elements)) {
- SwigType *member_function_qualifiers = SwigType_pop_function_qualifiers(next3elements);
- /* compilers won't let us cast from a member function without qualifiers to one with qualifiers, so the qualifiers are kept in the ltype */
- if (member_function_qualifiers)
- Append(result, member_function_qualifiers);
- Delete(member_function_qualifiers);
- ignore_member_function_qualifiers = 1;
- }
- Delete(next3elements);
- }
- firstarray = 0;
- } else if (SwigType_isreference(element)) {
- if (notypeconv) {
- Append(result, element);
- } else {
- Append(result, "p.");
- }
- firstarray = 0;
- } else if (SwigType_isrvalue_reference(element)) {
- if (notypeconv) {
- Append(result, element);
- } else {
- Append(result, "p.");
- }
- firstarray = 0;
- } else if (SwigType_isarray(element) && firstarray) {
- if (notypeconv) {
- Append(result, element);
- } else {
- Append(result, "p.");
- }
- firstarray = 0;
- } else if (SwigType_isenum(element)) {
- int anonymous_enum = (Cmp(element, "enum ") == 0);
- if (notypeconv || !anonymous_enum) {
- Append(result, element);
- } else {
- Append(result, "int");
- }
- } else {
- Append(result, element);
- }
- }
- Delete(elements);
- Delete(tc);
- return result;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_lstr()
- *
- * Produces a type-string that is suitable as a lvalue in an expression.
- * That is, a type that can be freely assigned a value without violating
- * any C assignment rules.
- *
- * - Qualifiers such as 'const' and 'volatile' are stripped.
- * Except for member function cv-qualifiers and ref-qualifiers.
- * - Arrays are converted into a *single* pointer (i.e.,
- * double [][] becomes double *).
- * - References are converted into a pointer.
- * - Typedef names that refer to read-only types will be replaced
- * with an equivalent assignable version.
- * -------------------------------------------------------------------- */
-
-String *SwigType_lstr(const SwigType *s, const_String_or_char_ptr id) {
- String *result;
- SwigType *tc;
-
- tc = SwigType_ltype(s);
- result = SwigType_str(tc, id);
- Delete(tc);
- return result;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_rcaststr()
- *
- * Produces a casting string that maps the type returned by lstr() to the real
- * datatype printed by str().
- * ----------------------------------------------------------------------------- */
-
-String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) {
- String *result, *cast;
- String *element = 0;
- String *nextelement;
- String *forwardelement;
- String *member_function_qualifiers = 0;
- SwigType *td, *tc = 0;
- const SwigType *rs;
- List *elements;
- int nelements, i;
- int clear = 1;
- int firstarray = 1;
- int isreference = 0;
- int isfunction = 0;
-
- result = NewStringEmpty();
-
- if (SwigType_isconst(s)) {
- tc = Copy(s);
- Delete(SwigType_pop(tc));
- if (SwigType_ismemberpointer(tc))
- rs = s;
- else
- rs = tc;
- } else {
- rs = s;
- }
-
- if ((SwigType_isconst(rs) || SwigType_isarray(rs) || SwigType_isreference(rs) || SwigType_isrvalue_reference(rs))) {
- td = 0;
- } else {
- td = SwigType_typedef_resolve(rs);
- }
-
- if (td) {
- if ((SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td) || SwigType_isrvalue_reference(td))) {
- elements = SwigType_split(td);
- } else {
- elements = SwigType_split(rs);
- }
- Delete(td);
- } else {
- elements = SwigType_split(rs);
- }
- nelements = Len(elements);
- if (nelements > 0) {
- element = Getitem(elements, 0);
- }
- /* Now, walk the type list and start emitting */
- for (i = 0; i < nelements; i++) {
- if (i < (nelements - 1)) {
- nextelement = Getitem(elements, i + 1);
- forwardelement = nextelement;
- if (SwigType_isqualifier(nextelement)) {
- if (i < (nelements - 2))
- forwardelement = Getitem(elements, i + 2);
- }
- } else {
- nextelement = 0;
- forwardelement = 0;
- }
- if (SwigType_isqualifier(element)) {
- if (!member_function_qualifiers) {
- DOH *q = 0;
- q = SwigType_parm(element);
- Insert(result, 0, " ");
- Insert(result, 0, q);
- Delete(q);
- clear = 0;
- }
- } else if (SwigType_ispointer(element)) {
- Insert(result, 0, "*");
- if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
- Insert(result, 0, "(");
- Append(result, ")");
- }
- firstarray = 0;
- } else if (SwigType_ismemberpointer(element)) {
- String *q;
- Insert(result, 0, "::*");
- q = SwigType_parm(element);
- Insert(result, 0, q);
- if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
- Insert(result, 0, "(");
- Append(result, ")");
- }
- {
- String *next3elements = NewStringEmpty();
- int j;
- for (j = i + 1; j < i + 4 && j < nelements; j++) {
- Append(next3elements, Getitem(elements, j));
- }
- if (SwigType_isfunction(next3elements))
- member_function_qualifiers = SwigType_pop_function_qualifiers(next3elements);
- Delete(next3elements);
- }
- firstarray = 0;
- Delete(q);
- } else if (SwigType_isreference(element)) {
- if (!member_function_qualifiers) {
- Insert(result, 0, "&");
- if (!isfunction)
- isreference = 1;
- }
- if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
- Insert(result, 0, "(");
- Append(result, ")");
- }
- } else if (SwigType_isrvalue_reference(element)) {
- if (!member_function_qualifiers) {
- Insert(result, 0, "&&");
- if (!isfunction)
- isreference = 1;
- }
- if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
- Insert(result, 0, "(");
- Append(result, ")");
- }
- clear = 0;
- } else if (SwigType_isarray(element)) {
- DOH *size;
- if (firstarray && !isreference) {
- Append(result, "(*)");
- firstarray = 0;
- } else {
- Append(result, "[");
- size = SwigType_parm(element);
- Append(result, size);
- Append(result, "]");
- Delete(size);
- clear = 0;
- }
- } else if (SwigType_isfunction(element)) {
- DOH *parms, *p;
- int j, plen;
- Append(result, "(");
- parms = SwigType_parmlist(element);
- plen = Len(parms);
- for (j = 0; j < plen; j++) {
- p = SwigType_str(Getitem(parms, j), 0);
- Append(result, p);
- Delete(p);
- if (j < (plen - 1))
- Append(result, ",");
- }
- Append(result, ")");
- Delete(parms);
- if (member_function_qualifiers) {
- String *p = SwigType_str(member_function_qualifiers, 0);
- Append(result, " ");
- Append(result, p);
- Delete(p);
- Delete(member_function_qualifiers);
- member_function_qualifiers = 0;
- clear = 0;
- }
- isfunction = 1;
- } else {
- String *bs = SwigType_namestr(element);
- Insert(result, 0, " ");
- Insert(result, 0, bs);
- Delete(bs);
- }
- element = nextelement;
- }
- Delete(elements);
- if (clear) {
- cast = NewStringEmpty();
- } else {
- cast = NewStringf("(%s)", result);
- }
- if (name) {
- if (isreference) {
- Append(cast, "*");
- }
- Append(cast, name);
- }
- Delete(result);
- Delete(tc);
- return cast;
-}
-
-
-/* -----------------------------------------------------------------------------
- * SwigType_lcaststr()
- *
- * Casts a variable from the real type to the local datatype.
- * ----------------------------------------------------------------------------- */
-
-String *SwigType_lcaststr(const SwigType *s, const_String_or_char_ptr name) {
- String *result;
-
- result = NewStringEmpty();
-
- if (SwigType_isarray(s)) {
- String *lstr = SwigType_lstr(s, 0);
- Printf(result, "(%s)%s", lstr, name);
- Delete(lstr);
- } else if (SwigType_isreference(s)) {
- String *str = SwigType_str(s, 0);
- Printf(result, "(%s)", str);
- Delete(str);
- if (name)
- Append(result, name);
- } else if (SwigType_isrvalue_reference(s)) {
- String *str = SwigType_str(s, 0);
- Printf(result, "(%s)", str);
- Delete(str);
- if (name)
- Append(result, name);
- } else if (SwigType_isqualifier(s)) {
- String *lstr = SwigType_lstr(s, 0);
- Printf(result, "(%s)%s", lstr, name);
- Delete(lstr);
- } else {
- if (name)
- Append(result, name);
- }
- return result;
-}
-
-#if 0
-/* Alternative implementation for manglestr_default. Mangling is similar to the original
- except for a few subtle differences for example in templates:
- namespace foo {
- template<class T> class bar {};
- typedef int Integer;
- void test2(bar<Integer *> *x);
- }
- Mangling is more consistent and changes from
- _p_foo__barT_int_p_t to
- _p_foo__barT_p_int_t.
-*/
-static void mangle_stringcopy(String *destination, const char *source, int count) {
- while (count-- > 0) {
- char newc = '_';
- if (!(*source == '.' || *source == ':' || *source == ' '))
- newc = *source;
- /* TODO: occasionally '*' or numerics need converting to '_', eg in array dimensions and template expressions */
- Putc(newc, destination);
- source++;
- }
-}
-
-static void mangle_subtype(String *mangled, SwigType *s);
-
-/* -----------------------------------------------------------------------------
- * mangle_namestr()
- *
- * Mangles a type taking care of template expansions. Similar to SwigType_namestr().
- * The type may include a trailing '.', for example "p."
- * ----------------------------------------------------------------------------- */
-
-static void mangle_namestr(String *mangled, SwigType *t) {
- int length = Len(t);
- if (SwigType_isqualifier(t)) {
- Append(mangled, "q_");
- mangle_stringcopy(mangled, Char(t)+2, length-4);
- Append(mangled, "__");
- } else if (SwigType_ismemberpointer(t)) {
- Append(mangled, "m_");
- mangle_stringcopy(mangled, Char(t)+2, length-4);
- Append(mangled, "__");
- } else if (SwigType_isarray(t)) {
- Append(mangled, "a_");
- mangle_stringcopy(mangled, Char(t)+2, length-4);
- Append(mangled, "__");
- } else if (SwigType_isfunction(t)) {
- List *p = SwigType_parmlist(t);
- int sz = Len(p);
- int i;
- Append(mangled, "f_");
- for (i = 0; i < sz; i++) {
- mangle_subtype(mangled, Getitem(p, i));
- Putc('_', mangled);
- }
- Append(mangled, (sz > 0) ? "_" : "__");
- } else if (SwigType_isvarargs(t)) {
- Append(mangled, "___");
- } else {
- char *d = Char(t);
- char *c = strstr(d, "<(");
- if (!c || !strstr(c + 2, ")>")) {
- /* not a template type */
- mangle_stringcopy(mangled, Char(t), Len(t));
- } else {
- /* a template type */
- String *suffix;
- List *p;
- int i, sz;
- mangle_stringcopy(mangled, d, c-d);
- Putc('T', mangled);
- Putc('_', mangled);
-
- p = SwigType_parmlist(c + 1);
- sz = Len(p);
- for (i = 0; i < sz; i++) {
- mangle_subtype(mangled, Getitem(p, i));
- Putc('_', mangled);
- }
- Putc('t', mangled);
- suffix = SwigType_templatesuffix(t);
- if (Len(suffix) > 0) {
- mangle_namestr(mangled, suffix);
- } else {
- Append(mangled, suffix);
- }
- Delete(suffix);
- Delete(p);
- }
- }
-}
-
-static void mangle_subtype(String *mangled, SwigType *s) {
- List *elements;
- int nelements, i;
-
- assert(s);
- elements = SwigType_split(s);
- nelements = Len(elements);
- for (i = 0; i < nelements; i++) {
- SwigType *element = Getitem(elements, i);
- mangle_namestr(mangled, element);
- }
- Delete(elements);
-}
-
-static String *manglestr_default(const SwigType *s) {
- String *mangled = NewString("_");
- SwigType *sr = SwigType_typedef_resolve_all(s);
- SwigType *sq = SwigType_typedef_qualified(sr);
- SwigType *ss = SwigType_remove_global_scope_prefix(sq);
- SwigType *type = ss;
- SwigType *lt;
-
- if (SwigType_istemplate(ss)) {
- SwigType *ty = Swig_symbol_template_deftype(ss, 0);
- Delete(ss);
- ss = ty;
- type = ss;
- }
-
- lt = SwigType_ltype(type);
-
- Replace(lt, "struct ", "", DOH_REPLACE_ANY);
- Replace(lt, "class ", "", DOH_REPLACE_ANY);
- Replace(lt, "union ", "", DOH_REPLACE_ANY);
- Replace(lt, "enum ", "", DOH_REPLACE_ANY);
-
- mangle_subtype(mangled, lt);
-
- Delete(ss);
- Delete(sq);
- Delete(sr);
-
- return mangled;
-}
-
-#else
-
-static String *manglestr_default(const SwigType *s) {
- char *c;
- String *result = 0;
- String *base = 0;
- SwigType *lt;
- SwigType *sr = SwigType_typedef_resolve_all(s);
- SwigType *sq = SwigType_typedef_qualified(sr);
- SwigType *ss = SwigType_remove_global_scope_prefix(sq);
- SwigType *type = ss;
-
- if (SwigType_istemplate(ss)) {
- SwigType *ty = Swig_symbol_template_deftype(ss, 0);
- Delete(ss);
- ss = ty;
- type = ss;
- }
-
- lt = SwigType_ltype(type);
- result = SwigType_prefix(lt);
- base = SwigType_base(lt);
-
- c = Char(result);
- while (*c) {
- if (!isalnum((int) *c))
- *c = '_';
- c++;
- }
- if (SwigType_istemplate(base)) {
- String *b = SwigType_namestr(base);
- Delete(base);
- base = b;
- }
-
- Replace(base, "struct ", "", DOH_REPLACE_ANY); /* This might be problematic */
- Replace(base, "class ", "", DOH_REPLACE_ANY);
- Replace(base, "union ", "", DOH_REPLACE_ANY);
- Replace(base, "enum ", "", DOH_REPLACE_ANY);
-
- c = Char(base);
- while (*c) {
- if (*c == '<')
- *c = 'T';
- else if (*c == '>')
- *c = 't';
- else if (*c == '*')
- *c = 'p';
- else if (*c == '[')
- *c = 'a';
- else if (*c == ']')
- *c = 'A';
- else if (*c == '&')
- *c = 'R';
- else if (*c == '(')
- *c = 'f';
- else if (*c == ')')
- *c = 'F';
- else if (!isalnum((int) *c))
- *c = '_';
- c++;
- }
- Append(result, base);
- Insert(result, 0, "_");
- Delete(lt);
- Delete(base);
- Delete(ss);
- Delete(sq);
- Delete(sr);
- return result;
-}
-#endif
-
-String *SwigType_manglestr(const SwigType *s) {
-#if 0
- /* Debugging checks to ensure a proper SwigType is passed in and not a stringified type */
- String *angle = Strstr(s, "<");
- if (angle && Strncmp(angle, "<(", 2) != 0)
- Printf(stderr, "SwigType_manglestr error: %s\n", s);
- else if (Strstr(s, "*") || Strstr(s, "&") || Strstr(s, "["))
- Printf(stderr, "SwigType_manglestr error: %s\n", s);
-#endif
- return manglestr_default(s);
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_typename_replace()
- *
- * Replaces a typename in a type with something else. Needed for templates.
- * ----------------------------------------------------------------------------- */
-
-void SwigType_typename_replace(SwigType *t, String *pat, String *rep) {
- String *nt;
- int i, ilen;
- List *elem;
-
- if (!Strstr(t, pat))
- return;
-
- if (Equal(t, pat)) {
- Replace(t, pat, rep, DOH_REPLACE_ANY);
- return;
- }
- nt = NewStringEmpty();
- elem = SwigType_split(t);
- ilen = Len(elem);
- for (i = 0; i < ilen; i++) {
- String *e = Getitem(elem, i);
- if (SwigType_issimple(e)) {
- if (Equal(e, pat)) {
- /* Replaces a type of the form 'pat' with 'rep<args>' */
- Replace(e, pat, rep, DOH_REPLACE_ANY);
- } else if (SwigType_istemplate(e)) {
- /* Replaces a type of the form 'pat<args>' with 'rep' */
- {
- /* To match "e=TemplateTemplateT<(float)>"
- * with "pat=TemplateTemplateT"
- * we need to compare only the first part of the string e.
- */
- int len = Len(pat);
-
- /* Len(e) > len, not >= (because we expect at least a
- * character '<' following the template typename)
- */
- if (Len(e) > len) {
- String *firstPartOfType = NewStringWithSize(e, len);
- const char* e_as_char = Char(e);
-
- if (Equal(firstPartOfType, pat) && e_as_char[len] == '<') {
- String *repbase = SwigType_templateprefix(rep);
- Replace(e, pat, repbase, DOH_REPLACE_ID | DOH_REPLACE_FIRST);
- Delete(repbase);
- }
- Delete(firstPartOfType);
- }
- }
-
- {
- String *tsuffix;
- List *tparms = SwigType_parmlist(e);
- int j, jlen;
- String *nt = SwigType_templateprefix(e);
- Append(nt, "<(");
- jlen = Len(tparms);
- for (j = 0; j < jlen; j++) {
- SwigType_typename_replace(Getitem(tparms, j), pat, rep);
- Append(nt, Getitem(tparms, j));
- if (j < (jlen - 1))
- Putc(',', nt);
- }
- tsuffix = SwigType_templatesuffix(e);
- SwigType_typename_replace(tsuffix, pat, rep);
- Printf(nt, ")>%s", tsuffix);
- Delete(tsuffix);
- Clear(e);
- Append(e, nt);
- Delete(nt);
- Delete(tparms);
- }
- } else if (Swig_scopename_check(e)) {
- String *first = 0;
- String *rest = 0;
- Swig_scopename_split(e, &first, &rest);
-
- /* Swig_scopename_split doesn't handle :: prefix very well ... could do with a rework */
- if (Strncmp(rest, "::", 2) == 0) {
- String *tmp = NewString(Char(rest) + 2);
- Clear(rest);
- Printv(rest, tmp, NIL);
- Delete(tmp);
- assert(!first);
- }
-
- Clear(e);
- if (first)
- SwigType_typename_replace(first, pat, rep);
- SwigType_typename_replace(rest, pat, rep);
- Printv(e, first ? first : "", "::", rest, NIL);
- Delete(first);
- Delete(rest);
- }
- } else if (SwigType_isfunction(e)) {
- int j, jlen;
- List *fparms = SwigType_parmlist(e);
- Clear(e);
- Append(e, "f(");
- jlen = Len(fparms);
- for (j = 0; j < jlen; j++) {
- SwigType_typename_replace(Getitem(fparms, j), pat, rep);
- Append(e, Getitem(fparms, j));
- if (j < (jlen - 1))
- Putc(',', e);
- }
- Append(e, ").");
- Delete(fparms);
- } else if (SwigType_isarray(e)) {
- Replace(e, pat, rep, DOH_REPLACE_ID);
- }
- Append(nt, e);
- }
- Clear(t);
- Append(t, nt);
- Delete(nt);
- Delete(elem);
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_remove_global_scope_prefix()
- *
- * Removes the unary scope operator (::) prefix indicating global scope in all
- * components of the type
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_remove_global_scope_prefix(const SwigType *t) {
- SwigType *result;
- const char *type = Char(t);
- if (strncmp(type, "::", 2) == 0)
- type += 2;
- result = NewString(type);
- Replaceall(result, ".::", ".");
- Replaceall(result, "(::", "(");
- Replaceall(result, "enum ::", "enum ");
- return result;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_check_decl()
- *
- * Checks type declarators for a match
- * ----------------------------------------------------------------------------- */
-
-int SwigType_check_decl(const SwigType *ty, const SwigType *decl) {
- SwigType *t, *t1, *t2;
- int r;
- t = SwigType_typedef_resolve_all(ty);
- t1 = SwigType_strip_qualifiers(t);
- t2 = SwigType_prefix(t1);
- r = Equal(t2, decl);
- Delete(t);
- Delete(t1);
- Delete(t2);
- return r == 1;
-}
diff --git a/contrib/tools/swig/Source/Swig/swig.h b/contrib/tools/swig/Source/Swig/swig.h
deleted file mode 100644
index 19e61b4558..0000000000
--- a/contrib/tools/swig/Source/Swig/swig.h
+++ /dev/null
@@ -1,451 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * swig.h
- *
- * Header file for the SWIG core.
- * ----------------------------------------------------------------------------- */
-
-#ifndef SWIG_SWIG_H
-#define SWIG_SWIG_H
-
-#include "swigconfig.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "doh.h"
-
-/* Status codes */
-
-#define SWIG_OK 1
-#define SWIG_ERROR 0
-#define SWIG_NOWRAP 0
-
-/* Global macros */
-#define NSPACE_SEPARATOR "." /* Namespace separator for the nspace feature - this should be changed to a target language configurable variable */
-#define NSPACE_TODO 0 /* Languages that still need to implement and test the nspace feature use this */
-
-/* Short names for common data types */
-
- typedef DOH String;
- typedef DOH Hash;
- typedef DOH List;
- typedef DOH String_or_char;
- typedef DOH File;
- typedef DOH Parm;
- typedef DOH ParmList;
- typedef DOH Node;
- typedef DOH Symtab;
- typedef DOH Typetab;
- typedef DOH SwigType;
-
-/* --- Legacy DataType interface. These type codes are provided solely
- for backwards compatibility with older modules --- */
-
-/* --- The ordering of type values is used to determine type-promotion
- in the parser. Do not change */
-
-/* Numeric types */
-
-#define T_BOOL 1
-#define T_SCHAR 2
-#define T_UCHAR 3
-#define T_SHORT 4
-#define T_USHORT 5
-#define T_ENUM 6
-#define T_INT 7
-#define T_UINT 8
-#define T_LONG 9
-#define T_ULONG 10
-#define T_LONGLONG 11
-#define T_ULONGLONG 12
-#define T_FLOAT 20
-#define T_DOUBLE 21
-#define T_LONGDOUBLE 22
-#define T_FLTCPLX 23
-#define T_DBLCPLX 24
-#define T_NUMERIC 25
-#define T_AUTO 26
-
-#define T_COMPLEX T_DBLCPLX
-
-/* non-numeric */
-
-#define T_CHAR 29
-#define T_WCHAR 30
-#define T_USER 31
-#define T_VOID 32
-#define T_STRING 33
-#define T_POINTER 34
-#define T_REFERENCE 35
-#define T_ARRAY 36
-#define T_FUNCTION 37
-#define T_MPOINTER 38
-#define T_VARARGS 39
-#define T_RVALUE_REFERENCE 40
-#define T_WSTRING 41
-
-#define T_SYMBOL 98
-#define T_ERROR 99
-
-
-
-/* --- File interface --- */
-
-#include "swigfile.h"
-
-/* --- Command line parsing --- */
-
-#include "swigopt.h"
-
-/* --- Scanner Interface --- */
-
-#include "swigscan.h"
-
-/* --- Functions for manipulating the string-based type encoding --- */
-
- extern SwigType *NewSwigType(int typecode);
- extern SwigType *SwigType_del_element(SwigType *t);
- extern SwigType *SwigType_add_pointer(SwigType *t);
- extern SwigType *SwigType_add_memberpointer(SwigType *t, const_String_or_char_ptr qual);
- extern SwigType *SwigType_del_memberpointer(SwigType *t);
- extern SwigType *SwigType_del_pointer(SwigType *t);
- extern SwigType *SwigType_add_array(SwigType *t, const_String_or_char_ptr size);
- extern SwigType *SwigType_del_array(SwigType *t);
- extern SwigType *SwigType_pop_arrays(SwigType *t);
- extern SwigType *SwigType_add_reference(SwigType *t);
- extern SwigType *SwigType_del_reference(SwigType *t);
- extern SwigType *SwigType_add_rvalue_reference(SwigType *t);
- extern SwigType *SwigType_del_rvalue_reference(SwigType *t);
- extern SwigType *SwigType_add_qualifier(SwigType *t, const_String_or_char_ptr qual);
- extern SwigType *SwigType_del_qualifier(SwigType *t);
- extern SwigType *SwigType_add_function(SwigType *t, ParmList *parms);
- extern SwigType *SwigType_add_template(SwigType *t, ParmList *parms);
- extern SwigType *SwigType_pop_function(SwigType *t);
- extern SwigType *SwigType_pop_function_qualifiers(SwigType *t);
- extern ParmList *SwigType_function_parms(const SwigType *t, Node *file_line_node);
- extern List *SwigType_split(const SwigType *t);
- extern String *SwigType_pop(SwigType *t);
- extern void SwigType_push(SwigType *t, String *s);
- extern SwigType *SwigType_last(SwigType *t);
- extern List *SwigType_parmlist(const SwigType *p);
- extern String *SwigType_parm(const SwigType *p);
- extern String *SwigType_str(const SwigType *s, const_String_or_char_ptr id);
- extern String *SwigType_lstr(const SwigType *s, const_String_or_char_ptr id);
- extern String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr id);
- extern String *SwigType_lcaststr(const SwigType *s, const_String_or_char_ptr id);
- extern String *SwigType_manglestr(const SwigType *t);
- extern SwigType *SwigType_ltype(const SwigType *t);
- extern int SwigType_ispointer(const SwigType *t);
- extern int SwigType_ispointer_return(const SwigType *t);
- extern int SwigType_isfunctionpointer(const SwigType *t);
- extern int SwigType_ismemberpointer(const SwigType *t);
- extern int SwigType_isreference(const SwigType *t);
- extern int SwigType_isreference_return(const SwigType *t);
- extern int SwigType_isrvalue_reference(const SwigType *t);
- extern int SwigType_isarray(const SwigType *t);
- extern int SwigType_prefix_is_simple_1D_array(const SwigType *t);
- extern int SwigType_isfunction(const SwigType *t);
- extern int SwigType_isqualifier(const SwigType *t);
- extern int SwigType_isconst(const SwigType *t);
- extern int SwigType_issimple(const SwigType *t);
- extern int SwigType_ismutable(const SwigType *t);
- extern int SwigType_isvarargs(const SwigType *t);
- extern int SwigType_istemplate(const SwigType *t);
- extern int SwigType_isenum(const SwigType *t);
- extern int SwigType_check_decl(const SwigType *t, const_String_or_char_ptr decl);
- extern SwigType *SwigType_strip_qualifiers(const SwigType *t);
- extern SwigType *SwigType_strip_single_qualifier(const SwigType *t);
- extern SwigType *SwigType_functionpointer_decompose(SwigType *t);
- extern String *SwigType_base(const SwigType *t);
- extern String *SwigType_namestr(const SwigType *t);
- extern String *SwigType_templateprefix(const SwigType *t);
- extern String *SwigType_templatesuffix(const SwigType *t);
- extern String *SwigType_istemplate_templateprefix(const SwigType *t);
- extern String *SwigType_istemplate_only_templateprefix(const SwigType *t);
- extern String *SwigType_templateargs(const SwigType *t);
- extern String *SwigType_prefix(const SwigType *t);
- extern int SwigType_array_ndim(const SwigType *t);
- extern String *SwigType_array_getdim(const SwigType *t, int n);
- extern void SwigType_array_setdim(SwigType *t, int n, const_String_or_char_ptr rep);
- extern SwigType *SwigType_array_type(const SwigType *t);
- extern SwigType *SwigType_default_create(const SwigType *ty);
- extern SwigType *SwigType_default_deduce(const SwigType *t);
- extern void SwigType_typename_replace(SwigType *t, String *pat, String *rep);
- extern SwigType *SwigType_remove_global_scope_prefix(const SwigType *t);
- extern SwigType *SwigType_alttype(const SwigType *t, int ltmap);
-
-/* --- Type-system management --- */
- extern void SwigType_typesystem_init(void);
- extern int SwigType_typedef(const SwigType *type, const_String_or_char_ptr name);
- extern int SwigType_typedef_class(const_String_or_char_ptr name);
- extern int SwigType_typedef_using(const_String_or_char_ptr qname);
- extern void SwigType_inherit(String *subclass, String *baseclass, String *cast, String *conversioncode);
- extern int SwigType_issubtype(const SwigType *subtype, const SwigType *basetype);
- extern void SwigType_scope_alias(String *aliasname, Typetab *t);
- extern void SwigType_using_scope(Typetab *t);
- extern void SwigType_new_scope(const_String_or_char_ptr name);
- extern void SwigType_inherit_scope(Typetab *scope);
- extern Typetab *SwigType_pop_scope(void);
- extern Typetab *SwigType_set_scope(Typetab *h);
- extern void SwigType_print_scope(void);
- extern SwigType *SwigType_typedef_resolve(const SwigType *t);
- extern SwigType *SwigType_typedef_resolve_all(const SwigType *t);
- extern SwigType *SwigType_typedef_qualified(const SwigType *t);
- extern int SwigType_istypedef(const SwigType *t);
- extern int SwigType_isclass(const SwigType *t);
- extern void SwigType_attach_symtab(Symtab *syms);
- extern void SwigType_remember(const SwigType *t);
- extern void SwigType_remember_clientdata(const SwigType *t, const_String_or_char_ptr clientdata);
- extern void SwigType_remember_mangleddata(String *mangled, const_String_or_char_ptr clientdata);
- extern void (*SwigType_remember_trace(void (*tf) (const SwigType *, String *, String *))) (const SwigType *, String *, String *);
- extern void SwigType_emit_type_table(File *f_headers, File *f_table);
- extern int SwigType_type(const SwigType *t);
-
-/* --- Symbol table module --- */
-
- extern void Swig_symbol_print_tables(Symtab *symtab);
- extern void Swig_symbol_print_tables_summary(void);
- extern void Swig_symbol_print_symbols(void);
- extern void Swig_symbol_print_csymbols(void);
- extern void Swig_symbol_init(void);
- extern void Swig_symbol_setscopename(const_String_or_char_ptr name);
- extern String *Swig_symbol_getscopename(void);
- extern String *Swig_symbol_qualifiedscopename(Symtab *symtab);
- extern String *Swig_symbol_qualified_language_scopename(Symtab *symtab);
- extern Symtab *Swig_symbol_newscope(void);
- extern Symtab *Swig_symbol_setscope(Symtab *);
- extern Symtab *Swig_symbol_getscope(const_String_or_char_ptr symname);
- extern Symtab *Swig_symbol_global_scope(void);
- extern Symtab *Swig_symbol_current(void);
- extern Symtab *Swig_symbol_popscope(void);
- extern Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *node);
- extern void Swig_symbol_cadd(const_String_or_char_ptr symname, Node *node);
- extern Node *Swig_symbol_clookup(const_String_or_char_ptr symname, Symtab *tab);
- extern Node *Swig_symbol_clookup_check(const_String_or_char_ptr symname, Symtab *tab, int (*check) (Node *));
- extern Node *Swig_symbol_clookup_no_inherit(const_String_or_char_ptr name, Symtab *n);
- extern Symtab *Swig_symbol_cscope(const_String_or_char_ptr symname, Symtab *tab);
- extern Node *Swig_symbol_clookup_local(const_String_or_char_ptr symname, Symtab *tab);
- extern Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr symname, Symtab *tab, int (*check) (Node *));
- extern String *Swig_symbol_qualified(Node *node);
- extern Node *Swig_symbol_isoverloaded(Node *node);
- extern void Swig_symbol_remove(Node *node);
- extern void Swig_symbol_alias(const_String_or_char_ptr aliasname, Symtab *tab);
- extern void Swig_symbol_inherit(Symtab *tab);
- extern SwigType *Swig_symbol_type_qualify(const SwigType *ty, Symtab *tab);
- extern String *Swig_symbol_string_qualify(String *s, Symtab *tab);
- extern SwigType *Swig_symbol_typedef_reduce(const SwigType *ty, Symtab *tab);
-
- extern ParmList *Swig_symbol_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, Symtab *tsdecl);
- extern SwigType *Swig_symbol_template_deftype(const SwigType *type, Symtab *tscope);
- extern SwigType *Swig_symbol_template_param_eval(const SwigType *p, Symtab *symtab);
-
-/* --- Parameters and Parameter Lists --- */
-
-#include "swigparm.h"
-
-extern String *ParmList_errorstr(ParmList *);
-extern int ParmList_is_compactdefargs(ParmList *p);
-
-/* --- Parse tree support --- */
-
-#include "swigtree.h"
-
-/* -- Wrapper function Object */
-
-#include "swigwrap.h"
-
-/* --- Naming functions --- */
-
- extern void Swig_name_register(const_String_or_char_ptr method, const_String_or_char_ptr format);
- extern void Swig_name_unregister(const_String_or_char_ptr method);
- extern String *Swig_name_mangle(const_String_or_char_ptr s);
- extern String *Swig_name_wrapper(const_String_or_char_ptr fname);
- extern String *Swig_name_member(const_String_or_char_ptr nspace, const_String_or_char_ptr classname, const_String_or_char_ptr membername);
- extern String *Swig_name_get(const_String_or_char_ptr nspace, const_String_or_char_ptr vname);
- extern String *Swig_name_set(const_String_or_char_ptr nspace, const_String_or_char_ptr vname);
- extern String *Swig_name_construct(const_String_or_char_ptr nspace, const_String_or_char_ptr classname);
- extern String *Swig_name_copyconstructor(const_String_or_char_ptr nspace, const_String_or_char_ptr classname);
- extern String *Swig_name_destroy(const_String_or_char_ptr nspace, const_String_or_char_ptr classname);
- extern String *Swig_name_disown(const_String_or_char_ptr nspace, const_String_or_char_ptr classname);
-
- extern void Swig_naming_init(void);
- extern void Swig_name_namewarn_add(String *prefix, String *name, SwigType *decl, Hash *namewrn);
- extern void Swig_name_rename_add(String *prefix, String *name, SwigType *decl, Hash *namewrn, ParmList *declaratorparms);
- extern void Swig_name_inherit(String *base, String *derived);
- extern List *Swig_make_inherit_list(String *clsname, List *names, String *Namespaceprefix);
- extern void Swig_inherit_base_symbols(List *bases);
- extern int Swig_need_protected(Node *n);
- extern int Swig_need_redefined_warn(Node *a, Node *b, int InClass);
-
- extern String *Swig_name_make(Node *n, String *prefix, const_String_or_char_ptr cname, SwigType *decl, String *oldname);
- extern String *Swig_name_warning(Node *n, String *prefix, String *name, SwigType *decl);
- extern String *Swig_name_str(Node *n);
- extern String *Swig_name_decl(Node *n);
- extern String *Swig_name_fulldecl(Node *n);
-
-/* --- parameterized rename functions --- */
-
- extern void Swig_name_object_set(Hash *namehash, String *name, SwigType *decl, DOH *object);
- extern DOH *Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType *decl);
- extern void Swig_name_object_inherit(Hash *namehash, String *base, String *derived);
- extern void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, Node *n);
- extern void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *decl, const_String_or_char_ptr featurename, const_String_or_char_ptr value, Hash *featureattribs);
-
-/* --- Misc --- */
- extern char *Swig_copy_string(const char *c);
- extern void Swig_set_fakeversion(const char *version);
- extern const char *Swig_package_version(void);
- extern String *Swig_package_version_hex(void);
- extern void Swig_obligatory_macros(String *f_runtime, const char *language);
- extern void Swig_banner(File *f);
- extern void Swig_banner_target_lang(File *f, const_String_or_char_ptr commentchar);
- extern String *Swig_strip_c_comments(const String *s);
- extern String *Swig_new_subdirectory(String *basedirectory, String *subdirectory);
- extern void Swig_filename_correct(String *filename);
- extern String *Swig_filename_escape(String *filename);
- extern String *Swig_filename_escape_space(String *filename);
- extern void Swig_filename_unescape(String *filename);
- extern int Swig_storage_isextern(Node *n);
- extern int Swig_storage_isexternc(Node *n);
- extern int Swig_storage_isstatic_custom(Node *n, const_String_or_char_ptr storage);
- extern int Swig_storage_isstatic(Node *n);
- extern String *Swig_string_escape(String *s);
- extern String *Swig_string_mangle(const String *s);
- extern void Swig_scopename_split(const String *s, String **prefix, String **last);
- extern String *Swig_scopename_prefix(const String *s);
- extern String *Swig_scopename_last(const String *s);
- extern String *Swig_scopename_first(const String *s);
- extern String *Swig_scopename_suffix(const String *s);
- extern List *Swig_scopename_tolist(const String *s);
- extern int Swig_scopename_check(const String *s);
- extern String *Swig_string_lower(String *s);
- extern String *Swig_string_upper(String *s);
- extern String *Swig_string_title(String *s);
- extern void Swig_offset_string(String *s, int number);
- extern String *Swig_pcre_version(void);
- extern void Swig_init(void);
-
- extern int Swig_value_wrapper_mode(int mode);
- extern int Swig_is_generated_overload(Node *n);
-
- typedef enum { EMF_STANDARD, EMF_MICROSOFT } ErrorMessageFormat;
-
- extern void Swig_warning(int num, const_String_or_char_ptr filename, int line, const char *fmt, ...);
- extern void Swig_error(const_String_or_char_ptr filename, int line, const char *fmt, ...);
- extern int Swig_error_count(void);
- extern void Swig_error_silent(int s);
- extern void Swig_warnfilter(const_String_or_char_ptr wlist, int val);
- extern void Swig_warnall(void);
- extern int Swig_warn_count(void);
- extern void Swig_error_msg_format(ErrorMessageFormat format);
- extern void Swig_diagnostic(const_String_or_char_ptr filename, int line, const char *fmt, ...);
- extern String *Swig_stringify_with_location(DOH *object);
-
-/* --- C Wrappers --- */
- extern void Swig_cresult_name_set(const char *new_name);
- extern const char *Swig_cresult_name(void);
- extern String *Swig_cparm_name(Parm *p, int i);
- extern String *Swig_wrapped_var_type(SwigType *t, int varcref);
- extern int Swig_cargs(Wrapper *w, ParmList *l);
- extern String *Swig_cresult(SwigType *t, const_String_or_char_ptr name, const_String_or_char_ptr decl);
-
- extern String *Swig_cfunction_call(const_String_or_char_ptr name, ParmList *parms);
- extern String *Swig_cconstructor_call(const_String_or_char_ptr name);
- extern String *Swig_cppconstructor_call(const_String_or_char_ptr name, ParmList *parms);
- extern String *Swig_unref_call(Node *n);
- extern String *Swig_ref_call(Node *n, const String *lname);
- extern String *Swig_cdestructor_call(Node *n);
- extern String *Swig_cppdestructor_call(Node *n);
- extern String *Swig_cmemberset_call(const_String_or_char_ptr name, SwigType *type, String *self, int varcref);
- extern String *Swig_cmemberget_call(const_String_or_char_ptr name, SwigType *t, String *self, int varcref);
-
- extern int Swig_add_extension_code(Node *n, const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self);
- extern void Swig_replace_special_variables(Node *n, Node *parentnode, String *code);
-
-/* --- Transformations --- */
-
- extern int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, int flags, SwigType *director_type, int is_director);
- extern int Swig_ConstructorToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, String *none_comparison, String *director_ctor, int cplus, int flags, String *directorname);
- extern int Swig_DestructorToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, int cplus, int flags);
- extern int Swig_MembersetToFunction(Node *n, String *classname, int flags);
- extern int Swig_MembergetToFunction(Node *n, String *classname, int flags);
- extern int Swig_VargetToFunction(Node *n, int flags);
- extern int Swig_VarsetToFunction(Node *n, int flags);
-
-#define CWRAP_EXTEND 0x01
-#define CWRAP_SMART_POINTER 0x02
-#define CWRAP_NATURAL_VAR 0x04
-#define CWRAP_DIRECTOR_ONE_CALL 0x08
-#define CWRAP_DIRECTOR_TWO_CALLS 0x10
-#define CWRAP_ALL_PROTECTED_ACCESS 0x20
-#define CWRAP_SMART_POINTER_OVERLOAD 0x40
-
-/* --- Director Helpers --- */
- extern Node *Swig_methodclass(Node *n);
- extern int Swig_directorclass(Node *n);
- extern Node *Swig_directormap(Node *n, String *type);
-
-/* --- Legacy Typemap API (somewhat simplified, ha!) --- */
-
- extern void Swig_typemap_init(void);
- extern void Swig_typemap_register(const_String_or_char_ptr tmap_method, ParmList *pattern, const_String_or_char_ptr code, ParmList *locals, ParmList *kwargs);
- extern int Swig_typemap_copy(const_String_or_char_ptr tmap_method, ParmList *srcpattern, ParmList *pattern);
- extern void Swig_typemap_clear(const_String_or_char_ptr tmap_method, ParmList *pattern);
- extern int Swig_typemap_apply(ParmList *srcpat, ParmList *destpat);
- extern void Swig_typemap_clear_apply(ParmList *pattern);
- extern void Swig_typemap_replace_embedded_typemap(String *s, Node *file_line_node);
- extern void Swig_typemap_debug(void);
- extern void Swig_typemap_search_debug_set(void);
- extern void Swig_typemap_used_debug_set(void);
- extern void Swig_typemap_register_debug_set(void);
-
- extern String *Swig_typemap_lookup(const_String_or_char_ptr tmap_method, Node *n, const_String_or_char_ptr lname, Wrapper *f);
- extern String *Swig_typemap_lookup_out(const_String_or_char_ptr tmap_method, Node *n, const_String_or_char_ptr lname, Wrapper *f, String *actioncode);
-
- extern void Swig_typemap_attach_parms(const_String_or_char_ptr tmap_method, ParmList *parms, Wrapper *f);
-
-/* --- Code fragment support --- */
-
- extern void Swig_fragment_register(Node *fragment);
- extern void Swig_fragment_emit(String *name);
- extern void Swig_fragment_clear(String *section);
-
-/* --- Extension support --- */
-
- extern Hash *Swig_extend_hash(void);
- extern void Swig_extend_merge(Node *cls, Node *am);
- extern void Swig_extend_append_previous(Node *cls, Node *am);
- extern void Swig_extend_unused_check(void);
-
-/* hacks defined in C++ ! */
- extern int Swig_director_mode(void);
- extern int Swig_director_protected_mode(void);
- extern int Swig_all_protected_mode(void);
- extern void Wrapper_director_mode_set(int);
- extern void Wrapper_director_protected_mode_set(int);
- extern void Wrapper_all_protected_mode_set(int);
- extern void Language_replace_special_variables(String *method, String *tm, Parm *parm);
- extern void Swig_print(DOH *object, int count);
- extern void Swig_print_with_location(DOH *object, int count);
-
-/* -- template init -- */
- extern void SwigType_template_init(void);
-
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/contrib/tools/swig/Source/Swig/swigfile.h b/contrib/tools/swig/Source/Swig/swigfile.h
deleted file mode 100644
index 009599a112..0000000000
--- a/contrib/tools/swig/Source/Swig/swigfile.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * swigfile.h
- *
- * File handling functions in the SWIG core
- * ----------------------------------------------------------------------------- */
-
-extern List *Swig_add_directory(const_String_or_char_ptr dirname);
-extern void Swig_push_directory(const_String_or_char_ptr dirname);
-extern void Swig_pop_directory(void);
-extern String *Swig_last_file(void);
-extern List *Swig_search_path(void);
-extern FILE *Swig_include_open(const_String_or_char_ptr name);
-extern FILE *Swig_open(const_String_or_char_ptr name);
-extern String *Swig_read_file(FILE *f);
-extern String *Swig_include(const_String_or_char_ptr name);
-extern String *Swig_include_sys(const_String_or_char_ptr name);
-extern int Swig_insert_file(const_String_or_char_ptr name, File *outfile);
-extern void Swig_set_push_dir(int dopush);
-extern int Swig_get_push_dir(void);
-extern void Swig_register_filebyname(const_String_or_char_ptr filename, File *outfile);
-extern File *Swig_filebyname(const_String_or_char_ptr filename);
-extern String *Swig_file_extension(const_String_or_char_ptr filename);
-extern String *Swig_file_basename(const_String_or_char_ptr filename);
-extern String *Swig_file_filename(const_String_or_char_ptr filename);
-extern String *Swig_file_dirname(const_String_or_char_ptr filename);
-extern void Swig_file_debug_set(void);
-
-/* Delimiter used in accessing files and directories */
-
-#if defined(_WIN32)
-# define SWIG_FILE_DELIMITER "\\"
-#else
-# define SWIG_FILE_DELIMITER "/"
-#endif
diff --git a/contrib/tools/swig/Source/Swig/swigopt.h b/contrib/tools/swig/Source/Swig/swigopt.h
deleted file mode 100644
index 86a477b8f7..0000000000
--- a/contrib/tools/swig/Source/Swig/swigopt.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * swigopt.h
- *
- * Header file for the SWIG command line processing functions
- * ----------------------------------------------------------------------------- */
-
- extern void Swig_init_args(int argc, char **argv);
- extern void Swig_mark_arg(int n);
- extern int Swig_check_marked(int n);
- extern void Swig_check_options(int check_input);
- extern void Swig_arg_error(void);
diff --git a/contrib/tools/swig/Source/Swig/swigparm.h b/contrib/tools/swig/Source/Swig/swigparm.h
deleted file mode 100644
index 7b63546ec0..0000000000
--- a/contrib/tools/swig/Source/Swig/swigparm.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * swigparm.h
- *
- * Functions related to the handling of function/method parameters and
- * parameter lists.
- * ----------------------------------------------------------------------------- */
-
-/* Individual parameters */
-extern Parm *NewParm(SwigType *type, const_String_or_char_ptr name, Node *from_node);
-extern Parm *NewParmWithoutFileLineInfo(SwigType *type, const_String_or_char_ptr name);
-extern Parm *NewParmNode(SwigType *type, Node *from_node);
-extern Parm *CopyParm(Parm *p);
-
-/* Parameter lists */
-extern ParmList *CopyParmList(ParmList *);
-extern ParmList *CopyParmListMax(ParmList *, int count);
-extern int ParmList_len(ParmList *);
-extern int ParmList_numrequired(ParmList *);
-extern int ParmList_has_defaultargs(ParmList *p);
-extern int ParmList_has_varargs(ParmList *p);
-
-/* Output functions */
-extern String *ParmList_str(ParmList *);
-extern String *ParmList_str_defaultargs(ParmList *);
-extern String *ParmList_str_multibrackets(ParmList *);
-extern String *ParmList_protostr(ParmList *);
-
-
diff --git a/contrib/tools/swig/Source/Swig/swigscan.h b/contrib/tools/swig/Source/Swig/swigscan.h
deleted file mode 100644
index 6c9d1ff7fc..0000000000
--- a/contrib/tools/swig/Source/Swig/swigscan.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * swigscan.h
- *
- * C/C++ scanner.
- * ----------------------------------------------------------------------------- */
-
-typedef struct Scanner Scanner;
-
-extern Scanner *NewScanner(void);
-extern void DelScanner(Scanner *);
-extern void Scanner_clear(Scanner *);
-extern void Scanner_push(Scanner *, String *);
-extern void Scanner_pushtoken(Scanner *, int, const_String_or_char_ptr value);
-extern int Scanner_token(Scanner *);
-extern String *Scanner_text(Scanner *);
-extern void Scanner_skip_line(Scanner *);
-extern int Scanner_skip_balanced(Scanner *, int startchar, int endchar);
-extern String *Scanner_get_raw_text_balanced(Scanner *, int startchar, int endchar);
-extern void Scanner_set_location(Scanner *, String *file, int line);
-extern String *Scanner_file(Scanner *);
-extern int Scanner_line(Scanner *);
-extern int Scanner_start_line(Scanner *);
-extern void Scanner_idstart(Scanner *, const char *idchar);
-extern String *Scanner_errmsg(Scanner *);
-extern int Scanner_errline(Scanner *);
-extern int Scanner_isoperator(int tokval);
-extern void Scanner_locator(Scanner *, String *loc);
-
-/* Note: Tokens in range 100+ are for C/C++ operators */
-
-#define SWIG_MAXTOKENS 200
-#define SWIG_TOKEN_LPAREN 1 /* ( */
-#define SWIG_TOKEN_RPAREN 2 /* ) */
-#define SWIG_TOKEN_SEMI 3 /* ; */
-#define SWIG_TOKEN_LBRACE 4 /* { */
-#define SWIG_TOKEN_RBRACE 5 /* } */
-#define SWIG_TOKEN_LBRACKET 6 /* [ */
-#define SWIG_TOKEN_RBRACKET 7 /* ] */
-#define SWIG_TOKEN_BACKSLASH 8 /* \ */
-#define SWIG_TOKEN_ENDLINE 9 /* \n */
-#define SWIG_TOKEN_STRING 10 /* "str" */
-#define SWIG_TOKEN_POUND 11 /* # */
-#define SWIG_TOKEN_COLON 12 /* : */
-#define SWIG_TOKEN_DCOLON 13 /* :: */
-#define SWIG_TOKEN_DCOLONSTAR 14 /* ::* */
-#define SWIG_TOKEN_ID 15 /* identifier */
-#define SWIG_TOKEN_FLOAT 16 /* 3.1415F */
-#define SWIG_TOKEN_DOUBLE 17 /* 3.1415 */
-#define SWIG_TOKEN_INT 18 /* 314 */
-#define SWIG_TOKEN_UINT 19 /* 314U */
-#define SWIG_TOKEN_LONG 20 /* 314L */
-#define SWIG_TOKEN_ULONG 21 /* 314UL */
-#define SWIG_TOKEN_CHAR 22 /* 'charconst' */
-#define SWIG_TOKEN_PERIOD 23 /* . */
-#define SWIG_TOKEN_AT 24 /* @ */
-#define SWIG_TOKEN_DOLLAR 25 /* $ */
-#define SWIG_TOKEN_CODEBLOCK 26 /* %{ ... %} ... */
-#define SWIG_TOKEN_RSTRING 27 /* `charconst` */
-#define SWIG_TOKEN_LONGLONG 28 /* 314LL */
-#define SWIG_TOKEN_ULONGLONG 29 /* 314ULL */
-#define SWIG_TOKEN_QUESTION 30 /* ? */
-#define SWIG_TOKEN_COMMENT 31 /* C or C++ comment */
-#define SWIG_TOKEN_BOOL 32 /* true or false */
-#define SWIG_TOKEN_WSTRING 33 /* L"str" */
-#define SWIG_TOKEN_WCHAR 34 /* L'c' */
-#define SWIG_TOKEN_ELLIPSIS 35 /* ... */
-#define SWIG_TOKEN_LLBRACKET 36 /* [[ */
-#define SWIG_TOKEN_RRBRACKET 37 /* ]] */
-
-#define SWIG_TOKEN_ILLEGAL 99
-#define SWIG_TOKEN_ERROR -1
-
-#define SWIG_TOKEN_COMMA 101 /* , */
-#define SWIG_TOKEN_STAR 102 /* * */
-#define SWIG_TOKEN_TIMES 102 /* * */
-#define SWIG_TOKEN_EQUAL 103 /* = */
-#define SWIG_TOKEN_EQUALTO 104 /* == */
-#define SWIG_TOKEN_NOTEQUAL 105 /* != */
-#define SWIG_TOKEN_PLUS 106 /* + */
-#define SWIG_TOKEN_MINUS 107 /* - */
-#define SWIG_TOKEN_AND 108 /* & */
-#define SWIG_TOKEN_LAND 109 /* && */
-#define SWIG_TOKEN_OR 110 /* | */
-#define SWIG_TOKEN_LOR 111 /* || */
-#define SWIG_TOKEN_XOR 112 /* ^ */
-#define SWIG_TOKEN_LESSTHAN 113 /* < */
-#define SWIG_TOKEN_GREATERTHAN 114 /* > */
-#define SWIG_TOKEN_LTEQUAL 115 /* <= */
-#define SWIG_TOKEN_GTEQUAL 116 /* >= */
-#define SWIG_TOKEN_NOT 117 /* ~ */
-#define SWIG_TOKEN_LNOT 118 /* ! */
-#define SWIG_TOKEN_SLASH 119 /* / */
-#define SWIG_TOKEN_DIVIDE 119 /* / */
-#define SWIG_TOKEN_PERCENT 120 /* % */
-#define SWIG_TOKEN_MODULO 120 /* % */
-#define SWIG_TOKEN_LSHIFT 121 /* << */
-#define SWIG_TOKEN_RSHIFT 122 /* >> */
-#define SWIG_TOKEN_PLUSPLUS 123 /* ++ */
-#define SWIG_TOKEN_MINUSMINUS 124 /* -- */
-#define SWIG_TOKEN_PLUSEQUAL 125 /* += */
-#define SWIG_TOKEN_MINUSEQUAL 126 /* -= */
-#define SWIG_TOKEN_TIMESEQUAL 127 /* *= */
-#define SWIG_TOKEN_DIVEQUAL 128 /* /= */
-#define SWIG_TOKEN_ANDEQUAL 129 /* &= */
-#define SWIG_TOKEN_OREQUAL 130 /* |= */
-#define SWIG_TOKEN_XOREQUAL 131 /* ^= */
-#define SWIG_TOKEN_LSEQUAL 132 /* <<= */
-#define SWIG_TOKEN_RSEQUAL 133 /* >>= */
-#define SWIG_TOKEN_MODEQUAL 134 /* %= */
-#define SWIG_TOKEN_ARROW 135 /* -> */
-#define SWIG_TOKEN_ARROWSTAR 136 /* ->* */
-#define SWIG_TOKEN_LTEQUALGT 137 /* <=> */
diff --git a/contrib/tools/swig/Source/Swig/swigtree.h b/contrib/tools/swig/Source/Swig/swigtree.h
deleted file mode 100644
index 8d63d8fd33..0000000000
--- a/contrib/tools/swig/Source/Swig/swigtree.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * swigtree.h
- *
- * These functions are used to access and manipulate the SWIG parse tree.
- * The structure of this tree is modeled directly after XML-DOM. The attribute
- * and function names are meant to be similar.
- * ----------------------------------------------------------------------------- */
-
-/* Macros to traverse the DOM tree */
-
-#define nodeType(x) Getattr(x,"nodeType")
-#define parentNode(x) Getattr(x,"parentNode")
-#define previousSibling(x) Getattr(x,"previousSibling")
-#define nextSibling(x) Getattr(x,"nextSibling")
-#define firstChild(x) Getattr(x,"firstChild")
-#define lastChild(x) Getattr(x,"lastChild")
-
-/* Macros to set up the DOM tree (mostly used by the parser) */
-
-#define set_nodeType(x,v) Setattr(x,"nodeType",v)
-#define set_parentNode(x,v) Setattr(x,"parentNode",v)
-#define set_previousSibling(x,v) Setattr(x,"previousSibling",v)
-#define set_nextSibling(x,v) Setattr(x,"nextSibling",v)
-#define set_firstChild(x,v) Setattr(x,"firstChild",v)
-#define set_lastChild(x,v) Setattr(x,"lastChild",v)
-
-/* Utility functions */
-
-extern int checkAttribute(Node *obj, const_String_or_char_ptr name, const_String_or_char_ptr value);
-extern void appendChild(Node *node, Node *child);
-extern void prependChild(Node *node, Node *child);
-extern void removeNode(Node *node);
-extern Node *copyNode(Node *node);
-extern void appendSibling(Node *node, Node *child);
-
-/* Node restoration/restore functions */
-
-extern void Swig_require(const char *ns, Node *node, ...);
-extern void Swig_save(const char *ns, Node *node, ...);
-extern void Swig_restore(Node *node);
-
-/* Debugging of parse trees */
-
-extern void Swig_print_tags(File *obj, Node *root);
-extern void Swig_print_tree(Node *obj);
-extern void Swig_print_node(Node *obj);
-extern int Swig_print_quiet(int quiet);
diff --git a/contrib/tools/swig/Source/Swig/swigwrap.h b/contrib/tools/swig/Source/Swig/swigwrap.h
deleted file mode 100644
index b584ca495b..0000000000
--- a/contrib/tools/swig/Source/Swig/swigwrap.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * swigwrap.h
- *
- * Functions related to wrapper objects.
- * ----------------------------------------------------------------------------- */
-
-typedef struct Wrapper {
- Hash *localh;
- String *def;
- String *locals;
- String *code;
-} Wrapper;
-
-extern Wrapper *NewWrapper(void);
-extern void DelWrapper(Wrapper *w);
-extern void Wrapper_compact_print_mode_set(int flag);
-extern void Wrapper_pretty_print(String *str, File *f);
-extern void Wrapper_compact_print(String *str, File *f);
-extern void Wrapper_print(Wrapper *w, File *f);
-extern int Wrapper_add_local(Wrapper *w, const_String_or_char_ptr name, const_String_or_char_ptr decl);
-extern int Wrapper_add_localv(Wrapper *w, const_String_or_char_ptr name, ...);
-extern int Wrapper_check_local(Wrapper *w, const_String_or_char_ptr name);
-extern char *Wrapper_new_local(Wrapper *w, const_String_or_char_ptr name, const_String_or_char_ptr decl);
-extern char *Wrapper_new_localv(Wrapper *w, const_String_or_char_ptr name, ...);
diff --git a/contrib/tools/swig/Source/Swig/symbol.c b/contrib/tools/swig/Source/Swig/symbol.c
deleted file mode 100644
index 107b1caef9..0000000000
--- a/contrib/tools/swig/Source/Swig/symbol.c
+++ /dev/null
@@ -1,2128 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * symbol.c
- *
- * This file implements the SWIG symbol table. See details below.
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-#include "cparse.h"
-#include <ctype.h>
-
-/* #define SWIG_DEBUG*/
-/* -----------------------------------------------------------------------------
- * Synopsis
- *
- * This module provides symbol table management for all of SWIG. In previous
- * releases, the management of symbols was rather haphazard. This module tries
- * to correct that.
- *
- * All symbols are associated with simple identifiers. For example, here are some
- * declarations that generate symbol table entries:
- *
- * decl symbol
- * -------------- ------------
- * void foo(int); foo
- * int x; x
- * typedef int *blah; blah
- *
- * Associated with each symbol is a Hash table that can contain any set of
- * attributes that make sense for that object. For example:
- *
- * typedef int *blah; ----> "name" : 'blah'
- * "type" : 'int'
- * "decl" : 'p.'
- * "storage" : 'typedef'
- *
- * In some cases, the symbol table needs to manage overloaded entries. For instance,
- * overloaded functions. In this case, a linked list is built. The "sym:nextSibling"
- * attribute is reserved to hold a link to the next entry. For example:
- *
- * int foo(int); --> "name" : "foo" "name" : "foo"
- * int foo(int,double); "type" : "int" "type" : "int"
- * "decl" : "f(int)." "decl" : "f(int,double)."
- * ... ...
- * "sym:nextSibling" : --------> "sym:nextSibling": --------> ...
- *
- * When more than one symbol has the same name, the symbol declarator is
- * used to detect duplicates. For example, in the above case, foo(int) and
- * foo(int,double) are different because their "decl" attribute is different.
- * However, if a third declaration "foo(int)" was made, it would generate a
- * conflict (due to having a declarator that matches a previous entry).
- *
- * Structures and classes:
- *
- * C/C++ symbol tables are normally managed in a few different spaces. The
- * most visible namespace is reserved for functions, variables, typedef, enum values
- * and such. In C, a separate tag-space is reserved for 'struct name', 'class name',
- * and 'union name' declarations. In SWIG, a single namespace is used for everything
- * this means that certain incompatibilities will arise with some C programs. For instance:
- *
- * struct Foo {
- * ...
- * }
- *
- * int Foo(); // Error. Name clash. Works in C though
- *
- * Due to the unified namespace for structures, special handling is performed for
- * the following:
- *
- * typedef struct Foo {
- *
- * } Foo;
- *
- * In this case, the symbol table contains an entry for the structure itself. The
- * typedef is left out of the symbol table.
- *
- * Target language vs C:
- *
- * The symbol tables are normally managed *in the namespace of the target language*.
- * This means that name-collisions can be resolved using %rename and related
- * directives. A quirk of this is that sometimes the symbol tables need to
- * be used for C type resolution as well. To handle this, each symbol table
- * also has a C-symbol table lurking behind the scenes. This is used to locate
- * symbols in the C namespace. However, this symbol table is not used for error
- * reporting nor is it used for anything else during code generation.
- *
- * Symbol table structure:
- *
- * Symbol tables themselves are a special kind of node that is organized just like
- * a normal parse tree node. Symbol tables are organized in a tree that can be
- * traversed using the SWIG-DOM API. The following attributes names are reserved.
- *
- * name -- Name of the scope defined by the symbol table (if any)
- * This name is the C-scope name and is not affected by
- * %renaming operations
- * symtab -- Hash table mapping identifiers to nodes.
- * csymtab -- Hash table mapping C identifiers to nodes.
- *
- * Reserved attributes on symbol objects:
- *
- * When a symbol is placed in the symbol table, the following attributes
- * are set:
- *
- * sym:name -- Symbol name
- * sym:nextSibling -- Next symbol (if overloaded)
- * sym:previousSibling -- Previous symbol (if overloaded)
- * sym:symtab -- Symbol table object holding the symbol
- * sym:overloaded -- Set to the first symbol if overloaded
- *
- * These names are modeled after XML namespaces. In particular, every attribute
- * pertaining to symbol table management is prefaced by the "sym:" prefix.
- *
- * An example dump of the parse tree showing symbol table entries for the
- * following code should clarify this:
- *
- * namespace OuterNamespace {
- * namespace InnerNamespace {
- * class Class {
- * };
- * struct Struct {
- * int Var;
- * };
- * }
- * }
- *
- * +++ namespace ----------------------------------------
- * | sym:name - "OuterNamespace"
- * | symtab - 0xa064bf0
- * | sym:symtab - 0xa041690
- * | sym:overname - "__SWIG_0"
- *
- * +++ namespace ----------------------------------------
- * | sym:name - "InnerNamespace"
- * | symtab - 0xa064cc0
- * | sym:symtab - 0xa064bf0
- * | sym:overname - "__SWIG_0"
- *
- * +++ class ----------------------------------------
- * | sym:name - "Class"
- * | symtab - 0xa064d80
- * | sym:symtab - 0xa064cc0
- * | sym:overname - "__SWIG_0"
- * |
- * +++ class ----------------------------------------
- * | sym:name - "Struct"
- * | symtab - 0xa064f00
- * | sym:symtab - 0xa064cc0
- * | sym:overname - "__SWIG_0"
- *
- * +++ cdecl ----------------------------------------
- * | sym:name - "Var"
- * | sym:symtab - 0xa064f00
- * | sym:overname - "__SWIG_0"
- * |
- *
- *
- * Each class and namespace has its own scope and thus a new symbol table (sym)
- * is created. The sym attribute is only set for the first entry in the symbol
- * table. The sym:symtab entry points to the symbol table in which the symbol
- * exists, so for example, Struct is in the scope OuterNamespace::InnerNamespace
- * so sym:symtab points to this symbol table (0xa064cc0).
- *
- * ----------------------------------------------------------------------------- */
-
-static Hash *current = 0; /* The current symbol table hash */
-static Hash *ccurrent = 0; /* The current c symbol table hash */
-static Hash *current_symtab = 0; /* Current symbol table node */
-static Hash *symtabs = 0; /* Hash of all symbol tables by fully-qualified name */
-static Hash *global_scope = 0; /* Global scope */
-
-static int use_inherit = 1;
-
-/* common attribute keys, to avoid calling find_key all the times */
-
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_print_tables()
- *
- * Debug display of symbol tables
- * ----------------------------------------------------------------------------- */
-
-void Swig_symbol_print_tables(Symtab *symtab) {
- if (!symtab)
- symtab = current_symtab;
-
- Printf(stdout, "SYMBOL TABLES start =======================================\n");
- Swig_print_tree(symtab);
- Printf(stdout, "SYMBOL TABLES finish =======================================\n");
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_print_tables_summary()
- *
- * Debug summary display of all symbol tables by fully-qualified name
- * ----------------------------------------------------------------------------- */
-
-void Swig_symbol_print_tables_summary(void) {
- Printf(stdout, "SYMBOL TABLES SUMMARY start =======================================\n");
- Swig_print_node(symtabs);
- Printf(stdout, "SYMBOL TABLES SUMMARY finish =======================================\n");
-}
-
-/* -----------------------------------------------------------------------------
- * symbol_print_symbols()
- * ----------------------------------------------------------------------------- */
-
-static void symbol_print_symbols(const char *symboltabletype, const char *nextSibling) {
- Node *table = symtabs;
- Iterator ki = First(table);
- int show_pointers = 0;
- while (ki.key) {
- String *k = ki.key;
- Printf(stdout, "===================================================\n");
- Printf(stdout, "%s -\n", k);
- {
- Symtab *symtab = Getattr(Getattr(table, k), symboltabletype);
- Iterator it = First(symtab);
- while (it.key) {
- String *symname = it.key;
- Printf(stdout, " %s (%s)", symname, nodeType(it.item));
- if (show_pointers)
- Printf(stdout, " %p", it.item);
- Printf(stdout, "\n");
- {
- Node *sibling = Getattr(it.item, nextSibling);
- while (sibling) {
- Printf(stdout, " %s (%s)", symname, nodeType(sibling));
- if (show_pointers)
- Printf(stdout, " %p", sibling);
- Printf(stdout, "\n");
- sibling = Getattr(sibling, nextSibling);
- }
- }
- it = Next(it);
- }
- }
- ki = Next(ki);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_print_symbols()
- *
- * Debug display of all the target language symbols
- * ----------------------------------------------------------------------------- */
-
-void Swig_symbol_print_symbols(void) {
- Printf(stdout, "SYMBOLS start =======================================\n");
- symbol_print_symbols("symtab", "sym:nextSibling");
- Printf(stdout, "SYMBOLS finish =======================================\n");
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_print_csymbols()
- *
- * Debug display of all the C symbols
- * ----------------------------------------------------------------------------- */
-
-void Swig_symbol_print_csymbols(void) {
- Printf(stdout, "CSYMBOLS start =======================================\n");
- symbol_print_symbols("csymtab", "csym:nextSibling");
- Printf(stdout, "CSYMBOLS finish =======================================\n");
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_init()
- *
- * Create a new symbol table object
- * ----------------------------------------------------------------------------- */
-
-void Swig_symbol_init(void) {
-
- current = NewHash();
- current_symtab = NewHash();
- ccurrent = NewHash();
- set_nodeType(current_symtab, "symboltable");
- Setattr(current_symtab, "symtab", current);
- Delete(current);
- Setattr(current_symtab, "csymtab", ccurrent);
- Delete(ccurrent);
-
- /* Set the global scope */
- symtabs = NewHash();
- Setattr(symtabs, "", current_symtab);
- Delete(current_symtab);
- global_scope = current_symtab;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_setscopename()
- *
- * Set the C scopename of the current symbol table.
- * ----------------------------------------------------------------------------- */
-
-void Swig_symbol_setscopename(const_String_or_char_ptr name) {
- String *qname;
- /* assert(!Getattr(current_symtab,"name")); */
- Setattr(current_symtab, "name", name);
-
- /* Set nested scope in parent */
-
- qname = Swig_symbol_qualifiedscopename(current_symtab);
-
- /* Save a reference to this scope */
- Setattr(symtabs, qname, current_symtab);
- Delete(qname);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_getscopename()
- *
- * Get the C scopename of the current symbol table
- * ----------------------------------------------------------------------------- */
-
-String *Swig_symbol_getscopename(void) {
- return Getattr(current_symtab, "name");
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_getscope()
- *
- * Given a fully qualified C scopename, this function returns a symbol table
- * ----------------------------------------------------------------------------- */
-
-Symtab *Swig_symbol_getscope(const_String_or_char_ptr name) {
- if (!symtabs)
- return 0;
- if (Equal("::", (const_String_or_char_ptr ) name))
- name = "";
- return Getattr(symtabs, name);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_qualifiedscopename()
- *
- * Get the fully qualified C scopename of a symbol table. Note, this only pertains
- * to the C/C++ scope name. It is not affected by renaming.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_symbol_qualifiedscopename(Symtab *symtab) {
- String *result = 0;
- Hash *parent;
- String *name;
- if (!symtab)
- symtab = current_symtab;
- parent = Getattr(symtab, "parentNode");
- if (parent) {
- result = Swig_symbol_qualifiedscopename(parent);
- }
- name = Getattr(symtab, "name");
- if (name) {
- if (!result) {
- result = NewStringEmpty();
- }
- if (Len(result)) {
- Printv(result, "::", name, NIL);
- } else {
- Append(result, name);
- }
- }
- return result;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_qualified_language_scopename()
- *
- * Get the fully qualified C scopename of a symbol table but using a language
- * specific separator for the scopenames. Basically the same as
- * Swig_symbol_qualifiedscopename() but using the different separator.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_symbol_qualified_language_scopename(Symtab *n) {
- /* TODO: fix for %rename to work */
- String *result = Swig_symbol_qualifiedscopename(n);
- Replaceall(result, "::", NSPACE_SEPARATOR);
- return result;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_newscope()
- *
- * Create a new scope. Returns the newly created scope.
- * ----------------------------------------------------------------------------- */
-
-Symtab *Swig_symbol_newscope(void) {
- Hash *n;
- Hash *hsyms, *h;
-
- hsyms = NewHash();
- h = NewHash();
-
- set_nodeType(h, "symboltable");
- Setattr(h, "symtab", hsyms);
- Delete(hsyms);
- set_parentNode(h, current_symtab);
-
- n = lastChild(current_symtab);
- if (!n) {
- set_firstChild(current_symtab, h);
- } else {
- set_nextSibling(n, h);
- Delete(h);
- }
- set_lastChild(current_symtab, h);
- current = hsyms;
- ccurrent = NewHash();
- Setattr(h, "csymtab", ccurrent);
- Delete(ccurrent);
- current_symtab = h;
- return h;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_setscope()
- *
- * Set the current scope. Returns the previous current scope.
- * ----------------------------------------------------------------------------- */
-
-Symtab *Swig_symbol_setscope(Symtab *sym) {
- Symtab *ret = current_symtab;
- current_symtab = sym;
- current = Getattr(sym, "symtab");
- assert(current);
- ccurrent = Getattr(sym, "csymtab");
- assert(ccurrent);
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_popscope()
- *
- * Pop out of the current scope. Returns the popped scope and sets the
- * scope to the parent scope.
- * ----------------------------------------------------------------------------- */
-
-Symtab *Swig_symbol_popscope(void) {
- Hash *h = current_symtab;
- current_symtab = Getattr(current_symtab, "parentNode");
- assert(current_symtab);
- current = Getattr(current_symtab, "symtab");
- assert(current);
- ccurrent = Getattr(current_symtab, "csymtab");
- assert(ccurrent);
- return h;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_global_scope()
- *
- * Return the symbol table for the global scope.
- * ----------------------------------------------------------------------------- */
-
-Symtab *Swig_symbol_global_scope(void) {
- return global_scope;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_current()
- *
- * Return the current symbol table.
- * ----------------------------------------------------------------------------- */
-
-Symtab *Swig_symbol_current(void) {
- return current_symtab;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_alias()
- *
- * Makes an alias for a symbol in the global symbol table.
- * Primarily for namespace aliases such as 'namespace X = Y;'.
- * ----------------------------------------------------------------------------- */
-
-void Swig_symbol_alias(const_String_or_char_ptr aliasname, Symtab *s) {
- String *qname = Swig_symbol_qualifiedscopename(current_symtab);
- if (qname) {
- Printf(qname, "::%s", aliasname);
- } else {
- qname = NewString(aliasname);
- }
- if (!Getattr(symtabs, qname)) {
- Setattr(symtabs, qname, s);
- }
- Delete(qname);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_inherit()
- *
- * Inherit symbols from another scope. Primarily for C++ inheritance and
- * for using directives, such as 'using namespace X;'
- * but not for using declarations, such as 'using A;'.
- * ----------------------------------------------------------------------------- */
-
-void Swig_symbol_inherit(Symtab *s) {
- int i, ilen;
- List *inherit = Getattr(current_symtab, "inherit");
- if (!inherit) {
- inherit = NewList();
- Setattr(current_symtab, "inherit", inherit);
- Delete(inherit);
- }
-
- if (s == current_symtab) {
- Swig_warning(WARN_PARSE_REC_INHERITANCE, Getfile(s), Getline(s), "Recursive scope inheritance of '%s'.\n", Getattr(s, "name"));
- return;
- }
- assert(s != current_symtab);
- ilen = Len(inherit);
- for (i = 0; i < ilen; i++) {
- Node *n = Getitem(inherit, i);
- if (n == s)
- return; /* Already inherited */
- }
- Append(inherit, s);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_cadd()
- *
- * Adds a node to the C symbol table only.
- * ----------------------------------------------------------------------------- */
-
-void Swig_symbol_cadd(const_String_or_char_ptr name, Node *n) {
- Node *append = 0;
- Node *cn;
- /* There are a few options for weak symbols. A "weak" symbol
- is any symbol that can be replaced by another symbol in the C symbol
- table. An example would be a forward class declaration. A forward
- class sits in the symbol table until a real class declaration comes along.
-
- Certain symbols are marked as "sym:typename". These are important
- symbols related to the C++ type-system and take precedence in the C
- symbol table. An example might be code like this:
-
- template<class T> T foo(T x);
- int foo(int);
-
- In this case, the template is marked with "sym:typename" so that it
- stays in the C symbol table (so that it can be expanded using %template).
- */
-
- if (!name)
- return;
-
- if (SwigType_istemplate(name)) {
- String *cname = NewString(name);
- String *dname = Swig_symbol_template_deftype(cname, 0);
- if (!Equal(dname, name)) {
- Swig_symbol_cadd(dname, n);
- }
- Delete(dname);
- Delete(cname);
- }
-#ifdef SWIG_DEBUG
- Printf(stderr, "symbol_cadd %s %p\n", name, n);
-#endif
- cn = Getattr(ccurrent, name);
-
- if (cn && (Getattr(cn, "sym:typename"))) {
- /* The node in the C symbol table is a typename. Do nothing */
- /* We might append the symbol at the end */
- append = n;
- } else if (cn && (Getattr(cn, "sym:weak"))) {
- /* The node in the symbol table is weak. Replace it */
- if (checkAttribute(cn, "nodeType", "template")
- && checkAttribute(cn, "templatetype", "classforward")) {
- /* The node is a template classforward declaration, and the
- default template parameters here take precedence. */
- ParmList *pc = Getattr(cn, "templateparms");
- ParmList *pn = Getattr(n, "templateparms");
-#ifdef SWIG_DEBUG
- Printf(stderr, "found template classforward %s\n", Getattr(cn, "name"));
-#endif
- while (pc && pn) {
- String *value = Getattr(pc, "value");
- if (value) {
-#ifdef SWIG_DEBUG
- Printf(stderr, "add default template value %s %s\n", Getattr(pc, "name"), value);
-#endif
- Setattr(pn, "value", value);
- }
- pc = nextSibling(pc);
- pn = nextSibling(pn);
- }
- Setattr(n, "templateparms", Getattr(cn, "templateparms"));
- }
- Setattr(ccurrent, name, n);
-
- } else if (cn && (Getattr(n, "sym:weak"))) {
- /* The node being added is weak. Don't worry about it */
- } else if (cn && (Getattr(n, "sym:typename"))) {
- /* The node being added is a typename. We definitely add it */
- Setattr(ccurrent, name, n);
- append = cn;
- } else if (cn && (Checkattr(cn, "nodeType", "templateparm"))) {
- Swig_error(Getfile(n), Getline(n), "Declaration of '%s' shadows template parameter,\n", name);
- Swig_error(Getfile(cn), Getline(cn), "previous template parameter declaration '%s'.\n", name);
- return;
- } else if (cn) {
- append = n;
- } else if (!cn) {
- /* No conflict. Add the symbol */
- Setattr(ccurrent, name, n);
- }
-
- /* Multiple entries in the C symbol table. We append to the symbol table */
- if (append) {
- Node *fn, *pn = 0;
- cn = Getattr(ccurrent, name);
- fn = cn;
- while (fn) {
- pn = fn;
- if (fn == append) {
- /* already added. Bail */
- return;
- }
- fn = Getattr(fn, "csym:nextSibling");
- }
- if (pn) {
- Setattr(pn, "csym:nextSibling", append);
- }
- }
-
- /* Special typedef handling. When a typedef node is added to the symbol table, we
- might have to add a type alias. This would occur if the typedef mapped to another
- scope in the system. For example:
-
- class Foo {
- };
-
- typedef Foo OtherFoo;
-
- In this case, OtherFoo becomes an alias for Foo. */
-
- {
- Node *td = n;
- while (td && ((Equal(nodeType(td), "cdecl") && Checkattr(td, "storage", "typedef")) || (Equal(nodeType(td), "using") && !Getattr(n, "namespace")))) {
- SwigType *type;
- Node *td1;
- int using_not_typedef = Equal(nodeType(td), "using");
- type = Copy(Getattr(td, using_not_typedef ? "uname" : "type"));
- SwigType_push(type, Getattr(td, "decl"));
- td1 = Swig_symbol_clookup(type, 0);
-
- /* Fix pathetic case #1214313:
-
- class Foo
- {
- };
-
- typedef Foo FooBar;
-
- class CBaz
- {
- public:
- typedef FooBar Foo;
- };
-
- ie, when Foo -> FooBar -> Foo, jump one scope up when possible.
-
- */
- if (td1) {
- String *st = 0;
- String *sn = Getattr(td, "name");
- if (Equal(nodeType(td1), "cdecl") && Checkattr(td1, "storage", "typedef"))
- st = Getattr(td1, "type");
- else if (Equal(nodeType(td1), "using") && !Getattr(td1, "namespace"))
- st = Getattr(td1, "uname");
- if (st && sn && Equal(st, sn)) {
- Symtab *sc = Getattr(current_symtab, "parentNode");
- if (sc)
- td1 = Swig_symbol_clookup(type, sc);
- }
- }
-
- Delete(type);
- if (td1 == td)
- break;
- td = td1;
- if (td) {
- Symtab *st = Getattr(td, "symtab");
- if (st) {
- Swig_symbol_alias(Getattr(n, "name"), st);
- break;
- }
- }
- }
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_add()
- *
- * Adds a node to the symbol table. Returns the node itself if successfully
- * added. Otherwise, it returns the symbol table entry of the conflicting node.
- *
- * Also places the symbol in a behind-the-scenes C symbol table. This is needed
- * for namespace support, type resolution, and other issues.
- * ----------------------------------------------------------------------------- */
-
-Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n) {
- Hash *c, *cl = 0;
- SwigType *decl, *ndecl;
- String *cstorage, *nstorage;
- int nt = 0, ct = 0;
- int pn = 0;
- int u1 = 0, u2 = 0;
- String *name, *overname;
-
- /* See if the node has a name. If so, we place in the C symbol table for this
- scope. We don't worry about overloading here---the primary purpose of this
- is to record information for type/name resolution for later. Conflicts
- in C namespaces are errors, but these will be caught by the C++ compiler
- when compiling the wrapper code */
-
-
- /* There are a few options for weak symbols. A "weak" symbol
- is any symbol that can be replaced by another symbol in the C symbol
- table. An example would be a forward class declaration. A forward
- class sits in the symbol table until a real class declaration comes along.
-
- Certain symbols are marked as "sym:typename". These are important
- symbols related to the C++ type-system and take precedence in the C
- symbol table. An example might be code like this:
-
- template<class T> T foo(T x);
- int foo(int);
-
- In this case, the template is marked with "sym:typename" so that it
- stays in the C symbol table (so that it can be expanded using %template).
- */
-
- name = Getattr(n, "name");
- if (name && Len(name)) {
- Swig_symbol_cadd(name, n);
- }
-
- /* No symbol name defined. We return. */
- if (!symname) {
- Setattr(n, "sym:symtab", current_symtab);
- return n;
- }
-
- /* If node is ignored. We don't proceed any further */
- if (GetFlag(n, "feature:ignore"))
- return n;
-
- /* See if the symbol already exists in the table */
- c = Getattr(current, symname);
-
- /* Check for a weak symbol. A weak symbol is allowed to be in the
- symbol table, but is silently overwritten by other symbols. An example
- would be a forward class declaration. For instance:
-
- class Foo;
-
- In this case, "Foo" sits in the symbol table. However, the
- definition of Foo would replace the entry if it appeared later. */
-
- if (c && Getattr(c, "sym:weak")) {
- c = 0;
- }
- if (c) {
- /* There is a symbol table conflict. There are a few cases to consider here:
- (1) A conflict between a class/enum and a typedef declaration is okay.
- In this case, the symbol table entry is set to the class/enum declaration
- itself, not the typedef.
- (2) A conflict between namespaces is okay--namespaces are open
- (3) Otherwise, overloading is only allowed for functions
- (4) This special case is okay: a class template instantiated with same name as the template's name
- */
-
- /* Check for namespaces */
- String *ntype = Getattr(n, "nodeType");
- if ((Equal(ntype, Getattr(c, "nodeType"))) && ((Equal(ntype, "namespace")))) {
- Node *cl, *pcl = 0;
- cl = c;
- while (cl) {
- pcl = cl;
- cl = Getattr(cl, "sym:nextSibling");
- }
- Setattr(pcl, "sym:nextSibling", n);
- Setattr(n, "sym:symtab", current_symtab);
- Setattr(n, "sym:name", symname);
- Setattr(n, "sym:previousSibling", pcl);
- return n;
- }
-
- /* Special case: class template instantiated with same name as the template's name eg: %template(X) X<int>; */
- if (Equal(nodeType(c), "template")) {
- String *nt1 = Getattr(c, "templatetype");
- String *nt2 = nodeType(n);
- if (Equal(nt1, "class") && Equal(nt1, nt2)) {
- if (Getattr(n, "template")) {
- /* Finally check that another %template with same name doesn't already exist */
- if (!Getattr(c, "sym:nextSibling")) {
- Setattr(c, "sym:nextSibling", n);
- Setattr(n, "sym:symtab", current_symtab);
- Setattr(n, "sym:name", symname);
- Setattr(n, "sym:previousSibling", c);
- return n;
- }
- }
- }
- }
-
- if (Getattr(n, "allows_typedef"))
- nt = 1;
- if (Getattr(c, "allows_typedef"))
- ct = 1;
- if (nt || ct) {
- Node *td, *other;
- String *s;
- /* At least one of the nodes allows typedef overloading. Make sure that
- both don't--this would be a conflict */
-
- if (nt && ct)
- return c;
-
- /* Figure out which node allows the typedef */
- if (nt) {
- td = n;
- other = c;
- } else {
- td = c;
- other = n;
- }
- /* Make sure the other node is a typedef */
- s = Getattr(other, "storage");
- if (!s || (!Equal(s, "typedef")))
- return c; /* No. This is a conflict */
-
- /* Hmmm. This appears to be okay. Make sure the symbol table refers to the allow_type node */
-
- if (td != c) {
- Setattr(current, symname, td);
- Setattr(td, "sym:symtab", current_symtab);
- Setattr(td, "sym:name", symname);
- }
- return n;
- }
-
- decl = Getattr(c, "decl");
- ndecl = Getattr(n, "decl");
-
- {
- String *nt1, *nt2;
- nt1 = Getattr(n, "nodeType");
- if (Equal(nt1, "template"))
- nt1 = Getattr(n, "templatetype");
- nt2 = Getattr(c, "nodeType");
- if (Equal(nt2, "template"))
- nt2 = Getattr(c, "templatetype");
- if (Equal(nt1, "using"))
- u1 = 1;
- if (Equal(nt2, "using"))
- u2 = 1;
-
- if ((!Equal(nt1, nt2)) && !(u1 || u2))
- return c;
- }
- if (!(u1 || u2)) {
- if ((!SwigType_isfunction(decl)) || (!SwigType_isfunction(ndecl))) {
- /* Symbol table conflict */
- return c;
- }
- }
-
- /* Hmmm. Declarator seems to indicate that this is a function */
- /* Look at storage class to see if compatible */
- cstorage = Getattr(c, "storage");
- nstorage = Getattr(n, "storage");
-
- /* If either one is declared as typedef, forget it. We're hosed */
- if (Cmp(cstorage, "typedef") == 0) {
- return c;
- }
- if (Cmp(nstorage, "typedef") == 0) {
- return c;
- }
-
- /* Okay. Walk down the list of symbols and see if we get a declarator match */
- {
- String *nt = Getattr(n, "nodeType");
- int n_template = Equal(nt, "template") && Checkattr(n, "templatetype", "cdecl");
- int n_plain_cdecl = Equal(nt, "cdecl");
- Node *cn = c;
- pn = 0;
- while (cn) {
- decl = Getattr(cn, "decl");
- if (!(u1 || u2)) {
- if (Cmp(ndecl, decl) == 0) {
- /* Declarator conflict */
- /* Now check we don't have a non-templated function overloaded by a templated function with same params,
- * eg void foo(); template<typename> void foo(); */
- String *cnt = Getattr(cn, "nodeType");
- int cn_template = Equal(cnt, "template") && Checkattr(cn, "templatetype", "cdecl");
- int cn_plain_cdecl = Equal(cnt, "cdecl");
- if (!((n_template && cn_plain_cdecl) || (cn_template && n_plain_cdecl))) {
- /* found a conflict */
- return cn;
- }
- }
- }
- cl = cn;
- cn = Getattr(cn, "sym:nextSibling");
- pn++;
- }
- }
- /* Well, we made it this far. Guess we can drop the symbol in place */
- Setattr(n, "sym:symtab", current_symtab);
- Setattr(n, "sym:name", symname);
- /* Printf(stdout,"%s %p\n", Getattr(n,"sym:overname"), current_symtab); */
- assert(!Getattr(n, "sym:overname"));
- overname = NewStringf("__SWIG_%d", pn);
- Setattr(n, "sym:overname", overname);
- /*Printf(stdout,"%s %s %s\n", symname, Getattr(n,"decl"), Getattr(n,"sym:overname")); */
- Setattr(cl, "sym:nextSibling", n);
- Setattr(n, "sym:previousSibling", cl);
- Setattr(cl, "sym:overloaded", c);
- Setattr(n, "sym:overloaded", c);
- Delete(overname);
- return n;
- }
-
- /* No conflict. Just add it */
- Setattr(n, "sym:symtab", current_symtab);
- Setattr(n, "sym:name", symname);
- /* Printf(stdout,"%s\n", Getattr(n,"sym:overname")); */
- overname = NewStringf("__SWIG_%d", pn);
- Setattr(n, "sym:overname", overname);
- Delete(overname);
- /* Printf(stdout,"%s %s %s\n", symname, Getattr(n,"decl"), Getattr(n,"sym:overname")); */
- Setattr(current, symname, n);
- return n;
-}
-
-/* -----------------------------------------------------------------------------
- * symbol_lookup()
- *
- * Internal function to handle fully qualified symbol table lookups. This
- * works from the symbol table supplied in symtab and unwinds its way out
- * towards the global scope.
- *
- * This function operates in the C namespace, not the target namespace.
- *
- * The check function is an optional callback that can be used to verify a particular
- * symbol match. This is only used in some of the more exotic parts of SWIG. For instance,
- * verifying that a class hierarchy implements all pure virtual methods.
- * ----------------------------------------------------------------------------- */
-
-static Node *_symbol_lookup(const String *name, Symtab *symtab, int (*check) (Node *n)) {
- Node *n;
- List *inherit;
- Hash *sym = Getattr(symtab, "csymtab");
- if (Getmark(symtab))
- return 0;
- Setmark(symtab, 1);
-
- n = Getattr(sym, name);
-
-#ifdef SWIG_DEBUG
- Printf(stderr, "symbol_look %s %p %p %s\n", name, n, symtab, Getattr(symtab, "name"));
-#endif
-
- if (n) {
- /* if a check-function is defined. Call it to determine a match */
- if (check) {
- int c = check(n);
- if (c == 1) {
- Setmark(symtab, 0);
- return n;
- }
- if (c < 0) {
- /* Terminate the search right away */
- Setmark(symtab, 0);
- return 0;
- }
- } else {
- Setmark(symtab, 0);
- return n;
- }
- }
-
- if (!n && SwigType_istemplate(name)) {
- String *dname = 0;
- Setmark(symtab, 0);
- dname = Swig_symbol_template_deftype(name, symtab);
- if (!Equal(dname, name)) {
- n = _symbol_lookup(dname, symtab, check);
- }
- Delete(dname);
- if (n)
- return n;
- Setmark(symtab, 1);
- }
-
- inherit = Getattr(symtab, "inherit");
- if (inherit && use_inherit) {
- int i, len;
- len = Len(inherit);
- for (i = 0; i < len; i++) {
- n = _symbol_lookup(name, Getitem(inherit, i), check);
- if (n) {
- Setmark(symtab, 0);
- return n;
- }
- }
- }
-
- Setmark(symtab, 0);
- return 0;
-}
-
-static Node *symbol_lookup(const_String_or_char_ptr name, Symtab *symtab, int (*check) (Node *n)) {
- Node *n = 0;
- if (DohCheck(name)) {
- n = _symbol_lookup(name, symtab, check);
- } else {
- String *sname = NewString(name);
- n = _symbol_lookup(sname, symtab, check);
- Delete(sname);
- }
- return n;
-}
-
-
-
-/* -----------------------------------------------------------------------------
- * symbol_lookup_qualified()
- * ----------------------------------------------------------------------------- */
-
-static Node *symbol_lookup_qualified(const_String_or_char_ptr name, Symtab *symtab, const String *prefix, int local, int (*checkfunc) (Node *n)) {
- /* This is a little funky, we search by fully qualified names */
-
- if (!symtab)
- return 0;
- if (!prefix) {
- Node *n;
- String *bname = 0;
- String *prefix = 0;
- Swig_scopename_split(name, &prefix, &bname);
- n = symbol_lookup_qualified(bname, symtab, prefix, local, checkfunc);
- Delete(bname);
- Delete(prefix);
- return n;
- } else {
- Symtab *st;
- Node *n = 0;
- /* Make qualified name of current scope */
- String *qalloc = 0;
- String *qname = Swig_symbol_qualifiedscopename(symtab);
- const String *cqname;
- if (qname) {
- if (Len(qname)) {
- if (prefix && Len(prefix)) {
- Printv(qname, "::", prefix, NIL);
- }
- } else {
- Append(qname, prefix);
- }
- qalloc = qname;
- cqname = qname;
- } else {
- cqname = prefix;
- }
- st = Getattr(symtabs, cqname);
- /* Found a scope match */
- if (st) {
- if (!name) {
- if (qalloc)
- Delete(qalloc);
- return st;
- }
- n = symbol_lookup(name, st, checkfunc);
- }
- if (qalloc)
- Delete(qalloc);
-
- if (!n) {
- if (!local) {
- Node *pn = Getattr(symtab, "parentNode");
- if (pn)
- n = symbol_lookup_qualified(name, pn, prefix, local, checkfunc);
-
- /* Check inherited scopes */
- if (!n) {
- List *inherit = Getattr(symtab, "inherit");
- if (inherit && use_inherit) {
- int i, len;
- len = Len(inherit);
- for (i = 0; i < len; i++) {
- Node *prefix_node = symbol_lookup(prefix, Getitem(inherit, i), checkfunc);
- if (prefix_node) {
- Node *prefix_symtab = Getattr(prefix_node, "symtab");
- if (prefix_symtab) {
- n = symbol_lookup(name, prefix_symtab, checkfunc);
- break;
- }
- }
- }
- }
- }
- } else {
- n = 0;
- }
- }
- return n;
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_clookup()
- *
- * Look up a symbol in the symbol table. This uses the C name, not scripting
- * names. Note: If we come across a using declaration, we follow it to
- * to get the real node. Any using directives are also followed (but this is
- * implemented in symbol_lookup()).
- * ----------------------------------------------------------------------------- */
-
-Node *Swig_symbol_clookup(const_String_or_char_ptr name, Symtab *n) {
- Hash *hsym = 0;
- Node *s = 0;
-
- if (!n) {
- hsym = current_symtab;
- } else {
- if (!Checkattr(n, "nodeType", "symboltable")) {
- n = Getattr(n, "sym:symtab");
- }
- assert(n);
- if (n) {
- hsym = n;
- }
- }
-
- if (Swig_scopename_check(name)) {
- char *cname = Char(name);
- if (strncmp(cname, "::", 2) == 0) {
- String *nname = NewString(cname + 2);
- if (Swig_scopename_check(nname)) {
- s = symbol_lookup_qualified(nname, global_scope, 0, 0, 0);
- } else {
- s = symbol_lookup(nname, global_scope, 0);
- }
- Delete(nname);
- } else {
- String *prefix = Swig_scopename_prefix(name);
- if (prefix) {
- s = symbol_lookup_qualified(name, hsym, 0, 0, 0);
- Delete(prefix);
- if (!s) {
- return 0;
- }
- }
- }
- }
- if (!s) {
- while (hsym) {
- s = symbol_lookup(name, hsym, 0);
- if (s)
- break;
- hsym = Getattr(hsym, "parentNode");
- if (!hsym)
- break;
- }
- }
-
- if (!s) {
- return 0;
- }
- /* Check if s is a 'using' node */
- while (s && Checkattr(s, "nodeType", "using")) {
- String *uname = Getattr(s, "uname");
- Symtab *un = Getattr(s, "sym:symtab");
- Node *ss = (!Equal(name, uname) || (un != n)) ? Swig_symbol_clookup(uname, un) : 0; /* avoid infinity loop */
- if (!ss) {
- SWIG_WARN_NODE_BEGIN(s);
- Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(s, "uname")));
- SWIG_WARN_NODE_END(s);
- }
- s = ss;
- }
- return s;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_clookup_check()
- *
- * This function is identical to Swig_symbol_clookup() except that it
- * accepts a callback function that is invoked to determine a symbol match.
- * The purpose of this function is to support complicated algorithms that need
- * to examine multiple definitions of the same symbol that might appear in an
- * inheritance hierarchy.
- * ----------------------------------------------------------------------------- */
-
-Node *Swig_symbol_clookup_check(const_String_or_char_ptr name, Symtab *n, int (*checkfunc) (Node *n)) {
- Hash *hsym = 0;
- Node *s = 0;
-
- if (!n) {
- hsym = current_symtab;
- } else {
- if (!Checkattr(n, "nodeType", "symboltable")) {
- n = Getattr(n, "sym:symtab");
- }
- assert(n);
- if (n) {
- hsym = n;
- }
- }
-
- if (Swig_scopename_check(name)) {
- char *cname = Char(name);
- if (strncmp(cname, "::", 2) == 0) {
- String *nname = NewString(cname + 2);
- if (Swig_scopename_check(nname)) {
- s = symbol_lookup_qualified(nname, global_scope, 0, 0, checkfunc);
- } else {
- s = symbol_lookup(nname, global_scope, checkfunc);
- }
- Delete(nname);
- } else {
- String *prefix = Swig_scopename_prefix(name);
- if (prefix) {
- s = symbol_lookup_qualified(name, hsym, 0, 0, checkfunc);
- Delete(prefix);
- if (!s) {
- return 0;
- }
- }
- }
- }
- if (!s) {
- while (hsym) {
- s = symbol_lookup(name, hsym, checkfunc);
- if (s)
- break;
- hsym = Getattr(hsym, "parentNode");
- if (!hsym)
- break;
- }
- }
- if (!s) {
- return 0;
- }
- /* Check if s is a 'using' node */
- while (s && Checkattr(s, "nodeType", "using")) {
- Node *ss;
- ss = Swig_symbol_clookup(Getattr(s, "uname"), Getattr(s, "sym:symtab"));
- if (!ss && !checkfunc) {
- SWIG_WARN_NODE_BEGIN(s);
- Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(s, "uname")));
- SWIG_WARN_NODE_END(s);
- }
- s = ss;
- }
- return s;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_clookup_local()
- *
- * Same as Swig_symbol_clookup but parent nodes are not searched, that is, just
- * this symbol table is searched.
- * ----------------------------------------------------------------------------- */
-
-Node *Swig_symbol_clookup_local(const_String_or_char_ptr name, Symtab *n) {
- Hash *hsym;
- Node *s = 0;
-
- if (!n) {
- hsym = current_symtab;
- } else {
- if (!Checkattr(n, "nodeType", "symboltable")) {
- n = Getattr(n, "sym:symtab");
- }
- assert(n);
- hsym = n;
- }
-
- if (Swig_scopename_check(name)) {
- char *cname = Char(name);
- if (strncmp(cname, "::", 2) == 0) {
- String *nname = NewString(cname + 2);
- if (Swig_scopename_check(nname)) {
- s = symbol_lookup_qualified(nname, global_scope, 0, 0, 0);
- } else {
- s = symbol_lookup(nname, global_scope, 0);
- }
- Delete(nname);
- } else {
- s = symbol_lookup_qualified(name, hsym, 0, 0, 0);
- }
- }
- if (!s) {
- s = symbol_lookup(name, hsym, 0);
- }
- if (!s)
- return 0;
- /* Check if s is a 'using' node */
- while (s && Checkattr(s, "nodeType", "using")) {
- Node *ss = Swig_symbol_clookup_local(Getattr(s, "uname"), Getattr(s, "sym:symtab"));
- if (!ss) {
- SWIG_WARN_NODE_BEGIN(s);
- Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(s, "uname")));
- SWIG_WARN_NODE_END(s);
- }
- s = ss;
- }
- return s;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_clookup_local_check()
- * ----------------------------------------------------------------------------- */
-
-Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr name, Symtab *n, int (*checkfunc) (Node *)) {
- Hash *hsym;
- Node *s = 0;
-
- if (!n) {
- hsym = current_symtab;
- } else {
- if (!Checkattr(n, "nodeType", "symboltable")) {
- n = Getattr(n, "sym:symtab");
- }
- assert(n);
- hsym = n;
- }
-
- if (Swig_scopename_check(name)) {
- char *cname = Char(name);
- if (strncmp(cname, "::", 2) == 0) {
- String *nname = NewString(cname + 2);
- if (Swig_scopename_check(nname)) {
- s = symbol_lookup_qualified(nname, global_scope, 0, 0, checkfunc);
- } else {
- s = symbol_lookup(nname, global_scope, checkfunc);
- }
- Delete(nname);
- } else {
- s = symbol_lookup_qualified(name, hsym, 0, 0, checkfunc);
- }
- }
- if (!s) {
- s = symbol_lookup(name, hsym, checkfunc);
- }
- if (!s)
- return 0;
- /* Check if s is a 'using' node */
- while (s && Checkattr(s, "nodeType", "using")) {
- Node *ss = Swig_symbol_clookup_local_check(Getattr(s, "uname"), Getattr(s, "sym:symtab"), checkfunc);
- if (!ss && !checkfunc) {
- SWIG_WARN_NODE_BEGIN(s);
- Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(s, "uname")));
- SWIG_WARN_NODE_END(s);
- }
- s = ss;
- }
- return s;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_clookup_no_inherit()
- *
- * Symbol lookup like Swig_symbol_clookup but does not follow using declarations.
- * ----------------------------------------------------------------------------- */
-
-Node *Swig_symbol_clookup_no_inherit(const_String_or_char_ptr name, Symtab *n) {
- Node *s = 0;
- assert(use_inherit==1);
- use_inherit = 0;
- s = Swig_symbol_clookup(name, n);
- use_inherit = 1;
- return s;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_cscope()
- *
- * Look up a scope name.
- * ----------------------------------------------------------------------------- */
-
-Symtab *Swig_symbol_cscope(const_String_or_char_ptr name, Symtab *symtab) {
- char *cname = Char(name);
- if (strncmp(cname, "::", 2) == 0)
- return symbol_lookup_qualified(0, global_scope, name, 0, 0);
- return symbol_lookup_qualified(0, symtab, name, 0, 0);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_remove()
- *
- * Remove a symbol. If the symbol is an overloaded function and the symbol removed
- * is not the last in the list of overloaded functions, then the overloaded
- * names (sym:overname attribute) are changed to start from zero, eg __SWIG_0.
- * ----------------------------------------------------------------------------- */
-
-void Swig_symbol_remove(Node *n) {
- Symtab *symtab;
- String *symname;
- String *overname;
- Node *symprev;
- Node *symnext;
- Node *fixovername = 0;
- symtab = Getattr(n, "sym:symtab"); /* Get symbol table object */
- symtab = Getattr(symtab, "symtab"); /* Get actual hash table of symbols */
- symname = Getattr(n, "sym:name");
- symprev = Getattr(n, "sym:previousSibling");
- symnext = Getattr(n, "sym:nextSibling");
-
- /* If previous symbol, just fix the links */
- if (symprev) {
- if (symnext) {
- Setattr(symprev, "sym:nextSibling", symnext);
- fixovername = symprev; /* fix as symbol to remove is somewhere in the middle of the linked list */
- } else {
- Delattr(symprev, "sym:nextSibling");
- }
- } else {
- /* If no previous symbol, see if there is a next symbol */
- if (symnext) {
- Setattr(symtab, symname, symnext);
- fixovername = symnext; /* fix as symbol to remove is at head of linked list */
- } else {
- if (symname)
- Delattr(symtab, symname);
- }
- }
- if (symnext) {
- if (symprev) {
- Setattr(symnext, "sym:previousSibling", symprev);
- } else {
- Delattr(symnext, "sym:previousSibling");
- }
- }
- Delattr(n, "sym:symtab");
- Delattr(n, "sym:previousSibling");
- Delattr(n, "sym:nextSibling");
- Delattr(n, "csym:nextSibling");
- Delattr(n, "sym:overname");
- Delattr(n, "csym:previousSibling");
- Delattr(n, "sym:overloaded");
- n = 0;
-
- if (fixovername) {
- Node *nn = fixovername;
- Node *head = fixovername;
- int pn = 0;
-
- /* find head of linked list */
- while (nn) {
- head = nn;
- nn = Getattr(nn, "sym:previousSibling");
- }
-
- /* adjust all the sym:overname strings to start from 0 and increment by one */
- nn = head;
- while (nn) {
- assert(Getattr(nn, "sym:overname"));
- Delattr(nn, "sym:overname");
- overname = NewStringf("__SWIG_%d", pn);
- Setattr(nn, "sym:overname", overname);
- Delete(overname);
- pn++;
- nn = Getattr(nn, "sym:nextSibling");
- }
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_qualified()
- *
- * Return the qualified name of a symbol
- * ----------------------------------------------------------------------------- */
-
-String *Swig_symbol_qualified(Node *n) {
- Hash *symtab;
- if (Checkattr(n, "nodeType", "symboltable")) {
- symtab = n;
- } else {
- symtab = Getattr(n, "sym:symtab");
- }
- if (!symtab)
- return NewStringEmpty();
-#ifdef SWIG_DEBUG
- Printf(stderr, "symbol_qscope %s %p %s\n", Getattr(n, "name"), symtab, Getattr(symtab, "name"));
-#endif
- return Swig_symbol_qualifiedscopename(symtab);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_isoverloaded()
- *
- * Check if a symbol is overloaded. Returns the first symbol if so.
- * ----------------------------------------------------------------------------- */
-
-Node *Swig_symbol_isoverloaded(Node *n) {
- return Getattr(n, "sym:overloaded");
-}
-
-/* -----------------------------------------------------------------------------
- * symbol_template_qualify()
- *
- * Internal function to create a fully qualified type name for templates
- * ----------------------------------------------------------------------------- */
-
-/* This cache produces problems with OSS, don't active it */
-/* #define SWIG_TEMPLATE_QUALIFY_CACHE */
-static SwigType *symbol_template_qualify(const SwigType *e, Symtab *st) {
- String *tprefix, *tsuffix;
- SwigType *qprefix;
- String *targs;
- List *targslist;
- Node *tempn;
- Symtab *tscope;
- Iterator ti;
-#ifdef SWIG_TEMPLATE_QUALIFY_CACHE
- static Hash *qualify_cache = 0;
- String *scopetype = st ? NewStringf("%s::%s", Getattr(st, "name"), e)
- : NewStringf("%s::%s", Swig_symbol_getscopename(), e);
- if (!qualify_cache) {
- qualify_cache = NewHash();
- }
- if (scopetype) {
- String *cres = Getattr(qualify_cache, scopetype);
- if (cres) {
- Delete(scopetype);
- return Copy(cres);
- }
- }
-#endif
-
- tprefix = SwigType_templateprefix(e);
- tsuffix = SwigType_templatesuffix(e);
- qprefix = Swig_symbol_type_qualify(tprefix, st);
- targs = SwigType_templateargs(e);
- targslist = SwigType_parmlist(targs);
- tempn = Swig_symbol_clookup_local(tprefix, st);
- tscope = tempn ? Getattr(tempn, "sym:symtab") : 0;
- Append(qprefix, "<(");
- for (ti = First(targslist); ti.item;) {
- String *vparm;
- /* TODO: the logic here should be synchronised with that in SwigType_typedef_qualified() */
- /* TODO: ti.item might be a non-type parameter possibly within (), eg: (std::is_integral_v<(A)>||std::is_same_v<(A,node_t)>) */
- String *qparm = Swig_symbol_type_qualify(ti.item, st);
- if (tscope && (tscope != st)) {
- String *ty = Swig_symbol_type_qualify(qparm, tscope);
- Delete(qparm);
- qparm = ty;
- }
-
- vparm = Swig_symbol_template_param_eval(qparm, st);
- Append(qprefix, vparm);
- ti = Next(ti);
- if (ti.item) {
- Putc(',', qprefix);
- }
- Delete(qparm);
- Delete(vparm);
- }
- Append(qprefix, ")>");
- Append(qprefix, tsuffix);
- Delete(tprefix);
- Delete(tsuffix);
- Delete(targs);
- Delete(targslist);
-#ifdef SWIG_DEBUG
- Printf(stderr, "symbol_temp_qual %s %s\n", e, qprefix);
-#endif
-#ifdef SWIG_TEMPLATE_QUALIFY_CACHE
- Setattr(qualify_cache, scopetype, qprefix);
- Delete(scopetype);
-#endif
-
- return qprefix;
-}
-
-
-static int symbol_no_constructor(Node *n) {
- return !Checkattr(n, "nodeType", "constructor");
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_type_qualify()
- *
- * Create a fully qualified type name
- * Note: Does not resolve a constructor if passed in as the 'type'.
- * ----------------------------------------------------------------------------- */
-
-SwigType *Swig_symbol_type_qualify(const SwigType *t, Symtab *st) {
- List *elements;
- String *result = NewStringEmpty();
- int i, len;
- char *c = Char(t);
- if (strncmp(c, "::", 2) == 0) {
- Append(result, t);
- return result;
- }
-
- elements = SwigType_split(t);
-
- len = Len(elements);
- for (i = 0; i < len; i++) {
- String *e = Getitem(elements, i);
- if (SwigType_issimple(e)) {
- /* Note: the unary scope operator (::) is being removed from the template parameters here. */
- Node *n = Swig_symbol_clookup_check(e, st, symbol_no_constructor);
- if (n) {
- String *name = Getattr(n, "name");
- Clear(e);
- Append(e, name);
-#ifdef SWIG_DEBUG
- Printf(stderr, "symbol_qual_ei %d %s %s %p\n", i, name, e, st);
-#endif
- if (!Swig_scopename_check(name)) {
- String *qname = Swig_symbol_qualified(n);
- if (qname && Len(qname)) {
- Insert(e, 0, "::");
- Insert(e, 0, qname);
- }
-#ifdef SWIG_DEBUG
- Printf(stderr, "symbol_qual_sc %d %s %s %p\n", i, qname, e, st);
-#endif
- Delete(qname);
- }
- } else if (SwigType_istemplate(e)) {
- SwigType *ty = symbol_template_qualify(e, st);
- Clear(e);
- Append(e, ty);
- Delete(ty);
- }
- if (strncmp(Char(e), "::", 2) == 0) {
- Delitem(e, 0);
- Delitem(e, 0);
- }
- Append(result, e);
- } else if (SwigType_isfunction(e)) {
- List *parms = SwigType_parmlist(e);
- String *s = NewString("f(");
- Iterator pi = First(parms);
- while (pi.item) {
- String *pf = Swig_symbol_type_qualify(pi.item, st);
- Append(s, pf);
- pi = Next(pi);
- if (pi.item) {
- Append(s, ",");
- }
- Delete(pf);
- }
- Append(s, ").");
- Append(result, s);
- Delete(parms);
- Delete(s);
- } else {
- Append(result, e);
- }
- }
- Delete(elements);
-#ifdef SWIG_DEBUG
- Printf(stderr, "symbol_qualify %s %s %p %s\n", t, result, st, st ? Getattr(st, "name") : 0);
-#endif
-
- return result;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_template_reduce()
- * Resolves template parameter types
- * For example:
- * typedef int Int;
- * typedef Int Integer;
- * with input:
- * Foo<(Int,Integer)>
- * returns:
- * Foo<(int,int)>
- * ----------------------------------------------------------------------------- */
-
-static
-SwigType *Swig_symbol_template_reduce(SwigType *qt, Symtab *ntab) {
- Parm *p;
- String *templateargs = SwigType_templateargs(qt);
- List *parms = SwigType_parmlist(templateargs);
- Iterator pi = First(parms);
- String *tprefix = SwigType_templateprefix(qt);
- String *tsuffix = SwigType_templatesuffix(qt);
- String *qprefix = SwigType_typedef_qualified(tprefix);
- Append(qprefix, "<(");
- while ((p = pi.item)) {
- String *np;
- String *tp = Swig_symbol_typedef_reduce(p, ntab);
- String *qp = Swig_symbol_type_qualify(tp, ntab);
- Node *n = Swig_symbol_clookup(qp, ntab);
- if (n) {
- String *qual = Swig_symbol_qualified(n);
- np = Copy(Getattr(n, "name"));
- Delete(tp);
- tp = np;
- if (qual && Len(qual)) {
- Insert(np, 0, "::");
- Insert(np, 0, qual);
- }
- Delete(qual);
- } else {
- np = qp;
- }
- Append(qprefix, np);
- pi = Next(pi);
- if (pi.item) {
- Append(qprefix, ",");
- }
- Delete(qp);
- Delete(tp);
- }
- Append(qprefix, ")>");
- Append(qprefix, tsuffix);
- Delete(parms);
- Delete(tprefix);
- Delete(tsuffix);
- Delete(templateargs);
- return qprefix;
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_typedef_reduce()
- *
- * Chase a typedef through symbol tables looking for a match.
- * ----------------------------------------------------------------------------- */
-
-SwigType *Swig_symbol_typedef_reduce(const SwigType *ty, Symtab *tab) {
- SwigType *prefix, *base;
- Node *n;
- String *nt;
-
- base = SwigType_base(ty);
- prefix = SwigType_prefix(ty);
-
- n = Swig_symbol_clookup(base, tab);
- if (!n) {
- if (SwigType_istemplate(ty)) {
- SwigType *qt = Swig_symbol_template_reduce(base, tab);
- Append(prefix, qt);
- Delete(qt);
-#ifdef SWIG_DEBUG
- Printf(stderr, "symbol_reduce (a) %s %s\n", ty, prefix);
-#endif
- Delete(base);
- return prefix;
- } else {
- Delete(prefix);
-#ifdef SWIG_DEBUG
- Printf(stderr, "symbol_reduce (b) %s %s\n", ty, ty);
-#endif
- return Copy(ty);
- }
- }
- nt = Getattr(n, "nodeType");
- if (Equal(nt, "using")) {
- String *uname = Getattr(n, "uname");
- if (uname) {
- n = Swig_symbol_clookup(base, Getattr(n, "sym:symtab"));
- if (!n) {
- Delete(base);
- Delete(prefix);
-#ifdef SWIG_DEBUG
- Printf(stderr, "symbol_reduce (c) %s %s\n", ty, ty);
-#endif
- return Copy(ty);
- }
- }
- }
- if (Equal(nt, "cdecl")) {
- String *storage = Getattr(n, "storage");
- if (storage && (Equal(storage, "typedef"))) {
- SwigType *decl;
- SwigType *rt;
- SwigType *qt;
- Symtab *ntab;
- SwigType *nt = Copy(Getattr(n, "type"));
-
- /* Fix for case 'typedef struct Hello hello;' */
- {
- const char *dclass[3] = { "struct ", "union ", "class " };
- int i;
- char *c = Char(nt);
- for (i = 0; i < 3; i++) {
- if (strstr(c, dclass[i]) == c) {
- Replace(nt, dclass[i], "", DOH_REPLACE_FIRST);
- }
- }
- }
- decl = Getattr(n, "decl");
- if (decl) {
- SwigType_push(nt, decl);
- }
- SwigType_push(nt, prefix);
- Delete(base);
- Delete(prefix);
- ntab = Getattr(n, "sym:symtab");
- rt = Swig_symbol_typedef_reduce(nt, ntab);
- qt = Swig_symbol_type_qualify(rt, ntab);
- if (SwigType_istemplate(qt)) {
- SwigType *qtr = Swig_symbol_template_reduce(qt, ntab);
- Delete(qt);
- qt = qtr;
- }
- Delete(nt);
- Delete(rt);
-#ifdef SWIG_DEBUG
- Printf(stderr, "symbol_reduce (d) %s %s\n", qt, ty);
-#endif
- return qt;
- }
- }
- Delete(base);
- Delete(prefix);
-#ifdef SWIG_DEBUG
- Printf(stderr, "symbol_reduce (e) %s %s\n", ty, ty);
-#endif
- return Copy(ty);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_string_qualify()
- *
- * This function takes a string and looks for identifiers. Identifiers are
- * then qualified according to scope rules. This function is used in a number
- * of settings including expression evaluation, scoping of conversion operators,
- * and so forth.
- * ----------------------------------------------------------------------------- */
-
-String *Swig_symbol_string_qualify(String *s, Symtab *st) {
- int have_id = 0;
- String *id = NewStringEmpty();
- String *r = NewStringEmpty();
- char *c = Char(s);
- int first_char = 1;
- while (*c) {
- if (isalpha((int) *c) || (*c == '_') || (*c == ':') || (*c == '~' && first_char) || (isdigit((int) *c) && !first_char)) {
- Putc(*c, id);
- have_id = 1;
- } else {
- if (have_id) {
- String *qid = Swig_symbol_type_qualify(id, st);
- Append(r, qid);
- Clear(id);
- Delete(qid);
- have_id = 0;
- }
- Putc(*c, r);
- }
- first_char = (*c == ':');
- c++;
- }
- if (have_id) {
- String *qid = Swig_symbol_type_qualify(id, st);
- Append(r, qid);
- Delete(qid);
- }
- Delete(id);
- return r;
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_template_defargs()
- *
- * Apply default arg from generic template default args
- * Returns a parameter list which contains missing default arguments (if any)
- * Note side effects: parms will also contain the extra parameters in its list
- * (but only if non-zero).
- * ----------------------------------------------------------------------------- */
-
-
-ParmList *Swig_symbol_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, Symtab *tsdecl) {
- ParmList *expandedparms = parms;
- if (Len(parms) < Len(targs)) {
- Parm *lp = parms;
- Parm *p = lp;
- Parm *tp = targs;
- while (p && tp) {
- p = nextSibling(p);
- tp = nextSibling(tp);
- if (p)
- lp = p;
- }
- while (tp) {
- String *value = Getattr(tp, "value");
- if (value) {
- Parm *cp;
- Parm *ta = targs;
- Parm *p = parms;
- SwigType *nt = Swig_symbol_string_qualify(value, tsdecl);
- SwigType *ntq = 0;
-#ifdef SWIG_DEBUG
- Printf(stderr, "value %s %s %s\n", value, nt, tsdecl ? Getattr(tsdecl, "name") : tsdecl);
-#endif
- while (p && ta) {
- String *name = Getattr(ta, "name");
- String *pvalue = Getattr(p, "value");
- String *value = pvalue ? pvalue : Getattr(p, "type");
- String *ttq = Swig_symbol_type_qualify(value, tscope);
- /* value = SwigType_typedef_resolve_all(value); */
- Replaceid(nt, name, ttq);
- p = nextSibling(p);
- ta = nextSibling(ta);
- Delete(ttq);
- }
- ntq = Swig_symbol_type_qualify(nt, tsdecl);
- if (SwigType_istemplate(ntq)) {
- String *ty = Swig_symbol_template_deftype(ntq, tscope);
- Delete(ntq);
- ntq = ty;
- }
- cp = NewParmWithoutFileLineInfo(ntq, 0);
- if (lp) {
- set_nextSibling(lp, cp);
- Delete(cp);
- } else {
- expandedparms = cp;
- }
- lp = cp;
- tp = nextSibling(tp);
- Delete(nt);
- Delete(ntq);
- } else {
- tp = 0;
- }
- }
- }
- return expandedparms;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_symbol_template_deftype()
- *
- * Apply default args to generic template type
- * ----------------------------------------------------------------------------- */
-
-#define SWIG_TEMPLATE_DEFTYPE_CACHE
-SwigType *Swig_symbol_template_deftype(const SwigType *type, Symtab *tscope) {
- String *result = NewStringEmpty();
- List *elements = SwigType_split(type);
- int len = Len(elements);
- int i;
-#ifdef SWIG_TEMPLATE_DEFTYPE_CACHE
- static Hash *s_cache = 0;
- Hash *scope_cache;
- /* The lookup depends on the current scope and potential namespace qualification.
- Looking up x in namespace y is not the same as looking up x::y in outer scope.
- -> we use a 2-level hash: first scope and then symbol. */
- String *scope_name = tscope
- ? Swig_symbol_qualifiedscopename(tscope)
- : Swig_symbol_qualifiedscopename(current_symtab);
- String *type_name = tscope
- ? NewStringf("%s::%s", Getattr(tscope, "name"), type)
- : NewStringf("%s::%s", Swig_symbol_getscopename(), type);
- if (!scope_name) scope_name = NewString("::");
- if (!s_cache) {
- s_cache = NewHash();
- }
- scope_cache = Getattr(s_cache, scope_name);
- if (scope_cache) {
- String *cres = Getattr(scope_cache, type_name);
- if (cres) {
- Append(result, cres);
-#ifdef SWIG_DEBUG
- Printf(stderr, "cached deftype %s(%s) -> %s\n", type, scope_name, result);
-#endif
- Delete(type_name);
- Delete(scope_name);
- return result;
- }
- } else {
- scope_cache = NewHash();
- Setattr(s_cache, scope_name, scope_cache);
- Delete(scope_name);
- }
-#endif
-
-#ifdef SWIG_DEBUG
- Printf(stderr, "finding deftype %s\n", type);
-#endif
-
- for (i = 0; i < len; i++) {
- String *e = Getitem(elements, i);
- if (SwigType_isfunction(e)) {
- String *s = NewString("f(");
- List *parms = SwigType_parmlist(e);
- Iterator pi = First(parms);
- while (pi.item) {
- String *pf = SwigType_istemplate(e) ? Swig_symbol_template_deftype(pi.item, tscope)
- : Swig_symbol_type_qualify(pi.item, tscope);
- Append(s, pf);
- pi = Next(pi);
- if (pi.item) {
- Append(s, ",");
- }
- Delete(pf);
- }
- Append(s, ").");
- Append(result, s);
- Delete(s);
- Delete(parms);
- } else if (SwigType_istemplate(e)) {
- String *prefix = SwigType_prefix(e);
- String *base = SwigType_base(e);
- String *tprefix = SwigType_templateprefix(base);
- String *targs = SwigType_templateargs(base);
- String *tsuffix = SwigType_templatesuffix(base);
- ParmList *tparms = SwigType_function_parms(targs, 0);
- Node *tempn = Swig_symbol_clookup_local(tprefix, tscope);
- if (!tempn && tsuffix && Len(tsuffix)) {
- tempn = Swig_symbol_clookup(tprefix, 0);
- }
-#ifdef SWIG_DEBUG
- Printf(stderr, "deftype type %s %s %d\n", e, tprefix, (long) tempn);
-#endif
- if (tempn) {
- ParmList *tnargs = Getattr(tempn, "templateparms");
- ParmList *expandedparms;
- Parm *p;
- Symtab *tsdecl = Getattr(tempn, "sym:symtab");
-
-#ifdef SWIG_DEBUG
- Printf(stderr, "deftype type %s %s %s\n", tprefix, targs, tsuffix);
-#endif
- Append(tprefix, "<(");
- expandedparms = Swig_symbol_template_defargs(tparms, tnargs, tscope, tsdecl);
- p = expandedparms;
- tscope = tsdecl;
- while (p) {
- SwigType *ptype = Getattr(p, "type");
- SwigType *ttr = ptype ? ptype : Getattr(p, "value");
- SwigType *ttf = Swig_symbol_type_qualify(ttr, tscope);
- SwigType *ttq = Swig_symbol_template_param_eval(ttf, tscope);
-#ifdef SWIG_DEBUG
- Printf(stderr, "arg type %s\n", ttq);
-#endif
- if (SwigType_istemplate(ttq)) {
- SwigType *ttd = Swig_symbol_template_deftype(ttq, tscope);
- Delete(ttq);
- ttq = ttd;
-#ifdef SWIG_DEBUG
- Printf(stderr, "arg deftype %s\n", ttq);
-#endif
- }
- Append(tprefix, ttq);
- p = nextSibling(p);
- if (p)
- Putc(',', tprefix);
- Delete(ttf);
- Delete(ttq);
- }
- Append(tprefix, ")>");
- Append(tprefix, tsuffix);
- Append(prefix, tprefix);
-#ifdef SWIG_DEBUG
- Printf(stderr, "deftype %s %s \n", type, tprefix);
-#endif
- Append(result, prefix);
- } else {
- Append(result, e);
- }
- Delete(prefix);
- Delete(base);
- Delete(tprefix);
- Delete(tsuffix);
- Delete(targs);
- Delete(tparms);
- } else {
- Append(result, e);
- }
- }
- Delete(elements);
-#ifdef SWIG_TEMPLATE_DEFTYPE_CACHE
- Setattr(scope_cache, type_name, result);
- Delete(type_name);
-#endif
-
- return result;
-}
-
-SwigType *Swig_symbol_template_param_eval(const SwigType *p, Symtab *symtab) {
- String *value = Copy(p);
- Node *lastnode = 0;
- while (1) {
- Node *n = Swig_symbol_clookup(value, symtab);
- if (n == lastnode)
- break;
- lastnode = n;
- if (n) {
- String *nt = Getattr(n, "nodeType");
- if (Equal(nt, "enumitem")) {
- /* An enum item. Generate a fully qualified name */
- String *qn = Swig_symbol_qualified(n);
- if (qn && Len(qn)) {
- Append(qn, "::");
- Append(qn, Getattr(n, "name"));
- Delete(value);
- value = qn;
- continue;
- } else {
- Delete(qn);
- break;
- }
- } else if ((Equal(nt, "cdecl"))) {
- String *nv = Getattr(n, "value");
- if (nv) {
- Delete(value);
- value = Copy(nv);
- continue;
- }
- }
- }
- break;
- }
- return value;
-}
diff --git a/contrib/tools/swig/Source/Swig/tree.c b/contrib/tools/swig/Source/Swig/tree.c
deleted file mode 100644
index 438e8b73dc..0000000000
--- a/contrib/tools/swig/Source/Swig/tree.c
+++ /dev/null
@@ -1,426 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * tree.c
- *
- * This file provides some general purpose functions for manipulating
- * parse trees.
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-#include <stdarg.h>
-#include <assert.h>
-
-static int debug_quiet = 0;
-
-/* -----------------------------------------------------------------------------
- * Swig_print_quiet()
- *
- * Set quiet mode when printing a parse tree node
- * ----------------------------------------------------------------------------- */
-
-int Swig_print_quiet(int quiet) {
- int previous_quiet = debug_quiet;
- debug_quiet = quiet;
- return previous_quiet;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_print_tags()
- *
- * Dump the tag structure of a parse tree to standard output
- * ----------------------------------------------------------------------------- */
-
-void Swig_print_tags(DOH *obj, DOH *root) {
- DOH *croot, *newroot;
- DOH *cobj;
-
- if (!root)
- croot = NewStringEmpty();
- else
- croot = root;
-
- while (obj) {
- Swig_diagnostic(Getfile(obj), Getline(obj), "%s . %s\n", croot, nodeType(obj));
- cobj = firstChild(obj);
- if (cobj) {
- newroot = NewStringf("%s . %s", croot, nodeType(obj));
- Swig_print_tags(cobj, newroot);
- Delete(newroot);
- }
- obj = nextSibling(obj);
- }
- if (!root)
- Delete(croot);
-}
-
-static int indent_level = 0;
-
-static void print_indent(int l) {
- int i;
- for (i = 0; i < indent_level; i++) {
- fputc(' ', stdout);
- }
- if (l) {
- fputc('|', stdout);
- fputc(' ', stdout);
- }
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_print_node(Node *n)
- * ----------------------------------------------------------------------------- */
-
-void Swig_print_node(Node *obj) {
- Iterator ki;
- Node *cobj;
- List *keys = Keys(obj);
-
- print_indent(0);
- if (debug_quiet)
- Printf(stdout, "+++ %s ----------------------------------------\n", nodeType(obj));
- else
- Printf(stdout, "+++ %s - %p ----------------------------------------\n", nodeType(obj), obj);
-
- SortList(keys, 0);
- ki = First(keys);
- while (ki.item) {
- String *k = ki.item;
- DOH *value = Getattr(obj, k);
- if (Equal(k, "nodeType") || (*(Char(k)) == '$')) {
- /* Do nothing */
- } else if (debug_quiet && (Equal(k, "firstChild") || Equal(k, "lastChild") || Equal(k, "parentNode") || Equal(k, "nextSibling") ||
- Equal(k, "previousSibling") || Equal(k, "symtab") || Equal(k, "csymtab") || Equal(k, "sym:symtab") || Equal(k, "sym:nextSibling") ||
- Equal(k, "sym:previousSibling") || Equal(k, "csym:nextSibling") || Equal(k, "csym:previousSibling"))) {
- /* Do nothing */
- } else if (Equal(k, "kwargs") || Equal(k, "parms") || Equal(k, "wrap:parms") || Equal(k, "pattern") || Equal(k, "templateparms") || Equal(k, "throws")) {
- print_indent(2);
- /* Differentiate parameter lists by displaying within single quotes */
- Printf(stdout, "%-12s - \'%s\'\n", k, ParmList_str_defaultargs(value));
- } else {
- DOH *o;
- const char *trunc = "";
- print_indent(2);
- if (DohIsString(value)) {
- o = Str(value);
- if (Len(o) > 80) {
- trunc = "...";
- }
- Printf(stdout, "%-12s - \"%(escape)-0.80s%s\"\n", k, o, trunc);
- Delete(o);
- } else {
- Printf(stdout, "%-12s - %p\n", k, value);
- }
- }
- ki = Next(ki);
- }
- cobj = firstChild(obj);
- if (cobj) {
- indent_level += 6;
- Printf(stdout, "\n");
- Swig_print_tree(cobj);
- indent_level -= 6;
- } else {
- print_indent(1);
- Printf(stdout, "\n");
- }
- Delete(keys);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_print_tree()
- *
- * Dump the tree structure of a parse tree to standard output
- * ----------------------------------------------------------------------------- */
-
-void Swig_print_tree(DOH *obj) {
- while (obj) {
- Swig_print_node(obj);
- obj = nextSibling(obj);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * appendChild()
- *
- * Appends a new child to a node
- * ----------------------------------------------------------------------------- */
-
-void appendChild(Node *node, Node *chd) {
- Node *lc;
-
- if (!chd)
- return;
-
- lc = lastChild(node);
- if (!lc) {
- set_firstChild(node, chd);
- } else {
- set_nextSibling(lc, chd);
- set_previousSibling(chd, lc);
- }
- while (chd) {
- lc = chd;
- set_parentNode(chd, node);
- chd = nextSibling(chd);
- }
- set_lastChild(node, lc);
-}
-
-/* -----------------------------------------------------------------------------
- * prependChild()
- *
- * Prepends a new child to a node
- * ----------------------------------------------------------------------------- */
-
-void prependChild(Node *node, Node *chd) {
- Node *fc;
-
- if (!chd)
- return;
-
- fc = firstChild(node);
- if (fc) {
- set_nextSibling(chd, fc);
- set_previousSibling(fc, chd);
- }
- set_firstChild(node, chd);
- while (chd) {
- set_parentNode(chd, node);
- chd = nextSibling(chd);
- }
-}
-
-void appendSibling(Node *node, Node *chd) {
- Node *parent;
- Node *lc = node;
- while (nextSibling(lc))
- lc = nextSibling(lc);
- set_nextSibling(lc, chd);
- set_previousSibling(chd, lc);
- parent = parentNode(node);
- if (parent) {
- while (chd) {
- lc = chd;
- set_parentNode(chd, parent);
- chd = nextSibling(chd);
- }
- set_lastChild(parent, lc);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * removeNode()
- *
- * Removes a node from the parse tree. Detaches it from its parent's child list.
- * ----------------------------------------------------------------------------- */
-
-void removeNode(Node *n) {
- Node *parent;
- Node *prev;
- Node *next;
-
- parent = parentNode(n);
- if (!parent) return;
-
- prev = previousSibling(n);
- next = nextSibling(n);
- if (prev) {
- set_nextSibling(prev, next);
- } else {
- if (parent) {
- set_firstChild(parent, next);
- }
- }
- if (next) {
- set_previousSibling(next, prev);
- } else {
- if (parent) {
- set_lastChild(parent, prev);
- }
- }
-
- /* Delete attributes */
- Delattr(n,"parentNode");
- Delattr(n,"nextSibling");
- Delattr(n,"previousSibling");
-}
-
-/* -----------------------------------------------------------------------------
- * copyNode()
- *
- * Copies a node, but only copies simple attributes (no lists, hashes).
- * ----------------------------------------------------------------------------- */
-
-Node *copyNode(Node *n) {
- Iterator ki;
- Node *c = NewHash();
- for (ki = First(n); ki.key; ki = Next(ki)) {
- if (DohIsString(ki.item)) {
- Setattr(c, ki.key, Copy(ki.item));
- }
- }
- Setfile(c, Getfile(n));
- Setline(c, Getline(n));
- return c;
-}
-
-/* -----------------------------------------------------------------------------
- * checkAttribute()
- * ----------------------------------------------------------------------------- */
-
-int checkAttribute(Node *n, const_String_or_char_ptr name, const_String_or_char_ptr value) {
- String *v = Getattr(n, name);
- return v ? Equal(v, value) : 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_require()
- * ns - namespace for the view name for saving any attributes under
- * n - node
- * ... - list of attribute names of type char*
- *
- * An attribute is optional if it is prefixed by ?, eg "?value". All
- * non-optional attributes are checked for on node n and if any do not exist
- * SWIG exits with a fatal error.
- *
- * If the attribute name is prefixed by * or ?, eg "*value" then a copy of the
- * attribute is saved. The saved attributes will be restored on a subsequent
- * call to Swig_restore(). All the saved attributes are saved in the view
- * namespace (prefixed by ns).
- *
- * This function can be called more than once with different namespaces.
- * ----------------------------------------------------------------------------- */
-
-void Swig_require(const char *ns, Node *n, ...) {
- va_list ap;
- char *name;
- DOH *obj;
-
- va_start(ap, n);
- name = va_arg(ap, char *);
- while (name) {
- int newref = 0;
- int opt = 0;
- if (*name == '*') {
- newref = 1;
- name++;
- } else if (*name == '?') {
- newref = 1;
- opt = 1;
- name++;
- }
- obj = Getattr(n, name);
- if (!opt && !obj) {
- Swig_error(Getfile(n), Getline(n), "Fatal error (Swig_require). Missing attribute '%s' in node '%s'.\n", name, nodeType(n));
- Exit(EXIT_FAILURE);
- }
- if (!obj)
- obj = DohNone;
- if (newref) {
- /* Save a copy of the attribute */
- Setattr(n, NewStringf("%s:%s", ns, name), obj);
- }
- name = va_arg(ap, char *);
- }
- va_end(ap);
-
- /* Save the view */
- {
- String *view = Getattr(n, "view");
- if (view) {
- if (Strcmp(view, ns) != 0) {
- Setattr(n, NewStringf("%s:view", ns), view);
- Setattr(n, "view", NewString(ns));
- }
- } else {
- Setattr(n, "view", NewString(ns));
- }
- }
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_save()
- * Same as Swig_require(), but all attribute names are optional and all attributes
- * are saved, ie behaves as if all the attribute names were prefixed by ?.
- * ----------------------------------------------------------------------------- */
-
-void Swig_save(const char *ns, Node *n, ...) {
- va_list ap;
- char *name;
- DOH *obj;
-
- va_start(ap, n);
- name = va_arg(ap, char *);
- while (name) {
- if (*name == '*') {
- name++;
- } else if (*name == '?') {
- name++;
- }
- obj = Getattr(n, name);
- if (!obj)
- obj = DohNone;
-
- /* Save a copy of the attribute */
- if (Setattr(n, NewStringf("%s:%s", ns, name), obj)) {
- Printf(stderr, "Swig_save('%s','%s'): Warning, attribute '%s' was already saved.\n", ns, nodeType(n), name);
- }
- name = va_arg(ap, char *);
- }
- va_end(ap);
-
- /* Save the view */
- {
- String *view = Getattr(n, "view");
- if (view) {
- if (Strcmp(view, ns) != 0) {
- Setattr(n, NewStringf("%s:view", ns), view);
- Setattr(n, "view", NewString(ns));
- }
- } else {
- Setattr(n, "view", NewString(ns));
- }
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_restore()
- * Restores attributes saved by a previous call to Swig_require() or Swig_save().
- * ----------------------------------------------------------------------------- */
-
-void Swig_restore(Node *n) {
- String *temp;
- int len;
- List *l;
- String *ns;
- Iterator ki;
-
- ns = Getattr(n, "view");
- assert(ns);
-
- l = NewList();
-
- temp = NewStringf("%s:", ns);
- len = Len(temp);
-
- for (ki = First(n); ki.key; ki = Next(ki)) {
- if (Strncmp(temp, ki.key, len) == 0) {
- Append(l, ki.key);
- }
- }
- for (ki = First(l); ki.item; ki = Next(ki)) {
- DOH *obj = Getattr(n, ki.item);
- Setattr(n, Char(ki.item) + len, obj);
- Delattr(n, ki.item);
- }
- Delete(l);
- Delete(temp);
-}
diff --git a/contrib/tools/swig/Source/Swig/typemap.c b/contrib/tools/swig/Source/Swig/typemap.c
deleted file mode 100644
index f0dee59d9e..0000000000
--- a/contrib/tools/swig/Source/Swig/typemap.c
+++ /dev/null
@@ -1,2210 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * typemap.c
- *
- * A somewhat generalized implementation of SWIG1.1 typemaps.
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-#include "cparse.h"
-#include <ctype.h>
-
-#if 0
-#define SWIG_DEBUG
-#endif
-
-static int typemap_search_debug = 0;
-static int typemaps_used_debug = 0;
-static int typemap_register_debug = 0;
-static int in_typemap_search_multi = 0;
-
-static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper *f, Node *file_line_node);
-
-/* -----------------------------------------------------------------------------
- * Typemaps are stored in a collection of nested hash tables. Something like
- * this:
- *
- * [ type ]
- * +-------- [ name ]
- * +-------- [ name ]
- *
- * Each hash table [ type ] or [ name ] then contains references to the
- * different typemap methods. These are referenced by names such as
- * "tmap:in", "tmap:out", "tmap:argout", and so forth.
- *
- * The object corresponding to a specific typemap method has the following attributes:
- *
- * "type" - Typemap type
- * "pname" - Parameter name
- * "code" - Typemap code
- * "source" - Source directive (%apply or %typemap) for the typemap
- * "locals" - Local variables (if any)
- * "kwargs" - Typemap attributes
- *
- * Example for a typemap method named "in":
- * %typemap(in, warning="987:my warning", noblock=1) int &my_int (int tmp) "$1 = $input;"
- *
- * "type" - r.int
- * "pname" - my_int
- * "code" - $1 = $input;
- * "source" - typemap(in) int &my_int
- * "locals" - int tmp
- * "kwargs" - warning="987:my typemap warning", foo=123
- *
- * ----------------------------------------------------------------------------- */
-
-static Hash *typemaps;
-
-/* -----------------------------------------------------------------------------
- * typemap_identifier_fix()
- *
- * Create a type that can be used as a hash key lookup independent of the various
- * ways a template parameter list can be defined. This is achieved by fully
- * resolving the template parameters.
- *
- * This is a copy and modification of feature_identifier_fix in parser.y.
- * ----------------------------------------------------------------------------- */
-
-static SwigType *typemap_identifier_fix(const SwigType *s) {
- String *tp = SwigType_istemplate_templateprefix(s);
- if (tp) {
- String *ts, *ta, *tq, *tr;
- ts = SwigType_templatesuffix(s);
- ta = SwigType_templateargs(s);
- tq = Swig_symbol_type_qualify(ta, 0);
- tr = SwigType_typedef_resolve_all(ta);
- Append(tp,tr);
- Append(tp,ts);
- Delete(ts);
- Delete(ta);
- Delete(tq);
- Delete(tr);
- return tp;
- } else {
- return NewString(s);
- }
-}
-
-static Hash *get_typemap(const SwigType *type) {
- Hash *tm = 0;
- SwigType *dtype = 0;
- SwigType *hashtype;
-
- if (SwigType_istemplate(type)) {
- SwigType *rty = typemap_identifier_fix(type);
- String *ty = Swig_symbol_template_deftype(rty, 0);
- dtype = Swig_symbol_type_qualify(ty, 0);
- type = dtype;
- Delete(ty);
- }
-
- /* remove unary scope operator (::) prefix indicating global scope for looking up in the hashmap */
- hashtype = SwigType_remove_global_scope_prefix(type);
- tm = Getattr(typemaps, hashtype);
-
- Delete(dtype);
- Delete(hashtype);
-
- return tm;
-}
-
-static void set_typemap(const SwigType *type, Hash **tmhash) {
- SwigType *hashtype = 0;
- Hash *new_tm = 0;
- assert(*tmhash == 0);
- if (SwigType_istemplate(type)) {
- SwigType *rty = typemap_identifier_fix(type);
- String *ty = Swig_symbol_template_deftype(rty, 0);
- String *tyq = Swig_symbol_type_qualify(ty, 0);
- hashtype = SwigType_remove_global_scope_prefix(tyq);
- *tmhash = Getattr(typemaps, hashtype);
- Delete(rty);
- Delete(tyq);
- Delete(ty);
- } else {
- hashtype = SwigType_remove_global_scope_prefix(type);
- }
-
- if (!*tmhash) {
- /* this type has not been seen before even after resolving template parameter types */
- new_tm = NewHash();
- *tmhash = new_tm;
- }
-
- /* note that the unary scope operator (::) prefix indicating global scope has been removed from the type */
- Setattr(typemaps, hashtype, *tmhash);
-
- Delete(hashtype);
- Delete(new_tm);
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_typemap_init()
- *
- * Initialize the typemap system
- * ----------------------------------------------------------------------------- */
-
-void Swig_typemap_init(void) {
- typemaps = NewHash();
-}
-
-static String *typemap_method_name(const_String_or_char_ptr tmap_method) {
- static Hash *names = 0;
- String *s;
- /* Due to "interesting" object-identity semantics of DOH,
- we have to make sure that we only intern strings without object
- identity into the hash table.
-
- (typemap_attach_kwargs calls typemap_method_name several times with
- the "same" String *tmap_method (i.e., same object identity) but differing
- string values.)
-
- Most other callers work around this by using char* rather than
- String *.
- -- mkoeppe, Jun 17, 2003
- */
- const char *method_without_object_identity = Char(tmap_method);
- if (!names)
- names = NewHash();
- s = Getattr(names, method_without_object_identity);
- if (s)
- return s;
- s = NewStringf("tmap:%s", tmap_method);
- Setattr(names, method_without_object_identity, s);
- Delete(s);
- return s;
-}
-
-/* -----------------------------------------------------------------------------
- * typemap_register()
- *
- * Internal implementation for Swig_typemap_register()
- * ----------------------------------------------------------------------------- */
-
-static void typemap_register(const_String_or_char_ptr tmap_method, ParmList *parms, const_String_or_char_ptr code, ParmList *locals, ParmList *kwargs, String *source_directive) {
- Hash *tm;
- Hash *tm1;
- Hash *tm2;
- Parm *np;
- String *tm_method;
- SwigType *type;
- String *pname;
- if (!parms)
- return;
-
- if (typemap_register_debug) {
- Printf(stdout, "Registering - %s\n", tmap_method);
- Swig_print_node(parms);
- }
-
- tm_method = typemap_method_name(tmap_method);
-
- /* Register the first type in the parameter list */
-
- type = Getattr(parms, "type");
- pname = Getattr(parms, "name");
-
- /* See if this type has been seen before */
- tm = get_typemap(type);
- if (!tm) {
- set_typemap(type, &tm);
- }
- if (pname) {
- /* See if parameter has been seen before */
- tm1 = Getattr(tm, pname);
- if (!tm1) {
- tm1 = NewHash();
- Setattr(tm, pname, tm1);
- Delete(tm1);
- }
- tm = tm1;
- }
-
- /* Now see if this typemap method has been seen before */
- tm2 = Getattr(tm, tm_method);
- if (!tm2) {
- tm2 = NewHash();
- Setattr(tm, tm_method, tm2);
- Delete(tm2);
- }
-
- /* For a multi-argument typemap, the typemap code and information
- is really only stored in the last argument. However, to
- make this work, we perform a really neat trick using
- the typemap method name.
-
- For example, consider this typemap
-
- %typemap(in) (int foo, int *bar, char *blah[]) {
- ...
- }
-
- To store it, we look at typemaps for the following:
-
- typemap method type-name
- ----------------------------------------------
- "in" int foo
- "in-int+foo:" int *bar
- "in-int+foo:-p.int+bar: char *blah[]
-
- Notice how the typemap method name expands to encode information about
- previous arguments.
-
- */
-
- np = nextSibling(parms);
- if (np) {
- /* Make an entirely new typemap method key */
- String *multi_tmap_method = NewStringf("%s-%s+%s:", tmap_method, type, pname);
-
- /* Now reregister on the remaining arguments */
- typemap_register(multi_tmap_method, np, code, locals, kwargs, source_directive);
-
- Delete(multi_tmap_method);
- } else {
- ParmList *clocals = CopyParmList(locals);
- ParmList *ckwargs = CopyParmList(kwargs);
-
- Setfile(tm2, Getfile(code));
- Setline(tm2, Getline(code));
- Setattr(tm2, "code", code);
- Setattr(tm2, "type", type);
- Setattr(tm2, "source", source_directive);
- if (pname) {
- Setattr(tm2, "pname", pname);
- }
- Setattr(tm2, "locals", clocals);
- Setattr(tm2, "kwargs", ckwargs);
-
- Delete(clocals);
- Delete(ckwargs);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_typemap_register()
- *
- * Add a new, possibly multi-argument, typemap
- * ----------------------------------------------------------------------------- */
-
-void Swig_typemap_register(const_String_or_char_ptr tmap_method, ParmList *parms, const_String_or_char_ptr code, ParmList *locals, ParmList *kwargs) {
- String *parms_str = ParmList_str_multibrackets(parms);
- String *source_directive = NewStringf("typemap(%s) %s", tmap_method, parms_str);
-
- typemap_register(tmap_method, parms, code, locals, kwargs, source_directive);
-
- Delete(source_directive);
- Delete(parms_str);
-}
-
-/* -----------------------------------------------------------------------------
- * typemap_get()
- *
- * Retrieve typemap information.
- * ----------------------------------------------------------------------------- */
-
-static Hash *typemap_get(SwigType *type, const_String_or_char_ptr name) {
- Hash *tm, *tm1;
- tm = get_typemap(type);
- if (!tm) {
- return 0;
- }
- if ((name) && Len(name)) {
- tm1 = Getattr(tm, name);
- return tm1;
- }
- return tm;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_typemap_copy()
- *
- * Copy a typemap
- * ----------------------------------------------------------------------------- */
-
-int Swig_typemap_copy(const_String_or_char_ptr tmap_method, ParmList *srcparms, ParmList *parms) {
- Hash *tm = 0;
- String *tm_method;
- Parm *p;
- String *pname;
- SwigType *ptype;
- String *tm_methods, *multi_tmap_method;
- if (ParmList_len(parms) != ParmList_len(srcparms))
- return -1;
-
- tm_method = typemap_method_name(tmap_method);
- p = srcparms;
- tm_methods = NewString(tm_method);
- while (p) {
- ptype = Getattr(p, "type");
- pname = Getattr(p, "name");
-
- /* Lookup the type */
- tm = typemap_get(ptype, pname);
- if (!tm)
- break;
-
- tm = Getattr(tm, tm_methods);
- if (!tm)
- break;
-
- /* Got a match. Look for next typemap */
- multi_tmap_method = NewStringf("%s-%s+%s:", tm_methods, ptype, pname);
- Delete(tm_methods);
- tm_methods = multi_tmap_method;
- p = nextSibling(p);
- }
- Delete(tm_methods);
-
- if (!p && tm) {
- /* Got some kind of match */
- String *parms_str = ParmList_str_multibrackets(parms);
- String *srcparms_str = ParmList_str_multibrackets(srcparms);
- String *source_directive = NewStringf("typemap(%s) %s = %s", tmap_method, parms_str, srcparms_str);
-
- typemap_register(tmap_method, parms, Getattr(tm, "code"), Getattr(tm, "locals"), Getattr(tm, "kwargs"), source_directive);
-
- Delete(source_directive);
- Delete(srcparms_str);
- Delete(parms_str);
- return 0;
- }
-
- /* Not found */
- return -1;
-
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_typemap_clear()
- *
- * Delete a multi-argument typemap
- * ----------------------------------------------------------------------------- */
-
-void Swig_typemap_clear(const_String_or_char_ptr tmap_method, ParmList *parms) {
- SwigType *type;
- String *name;
- Parm *p;
- String *multi_tmap_method;
- Hash *tm = 0;
-
- /* This might not work */
- multi_tmap_method = NewString(tmap_method);
- p = parms;
- while (p) {
- type = Getattr(p, "type");
- name = Getattr(p, "name");
- tm = typemap_get(type, name);
- if (!tm)
- return;
- p = nextSibling(p);
- if (p)
- Printf(multi_tmap_method, "-%s+%s:", type, name);
- }
- if (tm) {
- tm = Getattr(tm, typemap_method_name(multi_tmap_method));
- if (tm) {
- Delattr(tm, "code");
- Delattr(tm, "locals");
- Delattr(tm, "kwargs");
- }
- }
- Delete(multi_tmap_method);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_typemap_apply()
- *
- * Multi-argument %apply directive. This is pretty horrible so I sure hope
- * it works.
- * ----------------------------------------------------------------------------- */
-
-static int count_args(String *s) {
- /* Count up number of arguments */
- int na = 0;
- char *c = Char(s);
- while (*c) {
- if (*c == '+')
- na++;
- c++;
- }
- return na;
-}
-
-int Swig_typemap_apply(ParmList *src, ParmList *dest) {
- String *ssig, *dsig;
- Parm *p, *np, *lastp, *dp, *lastdp = 0;
- int narg = 0;
- SwigType *type = 0, *name;
- Hash *tm, *sm;
- int match = 0;
-
- /* Printf(stdout,"apply : %s --> %s\n", ParmList_str(src), ParmList_str(dest)); */
-
- /* Create type signature of source */
- ssig = NewStringEmpty();
- dsig = NewStringEmpty();
- p = src;
- dp = dest;
- lastp = 0;
- while (p) {
- lastp = p;
- lastdp = dp;
- np = nextSibling(p);
- if (np) {
- Printf(ssig, "-%s+%s:", Getattr(p, "type"), Getattr(p, "name"));
- Printf(dsig, "-%s+%s:", Getattr(dp, "type"), Getattr(dp, "name"));
- narg++;
- }
- p = np;
- dp = nextSibling(dp);
- }
-
- /* make sure a typemap node exists for the last destination node */
- type = Getattr(lastdp, "type");
- tm = get_typemap(type);
- if (!tm) {
- set_typemap(type, &tm);
- }
- name = Getattr(lastdp, "name");
- if (name) {
- Hash *tm1 = Getattr(tm, name);
- if (!tm1) {
- tm1 = NewHash();
- Setattr(tm, NewString(name), tm1);
- Delete(tm1);
- }
- tm = tm1;
- }
-
- /* This is a little nasty. We need to go searching for all possible typemaps in the
- source and apply them to the target */
-
- type = Getattr(lastp, "type");
- name = Getattr(lastp, "name");
-
- /* See if there is a matching typemap in this scope */
- sm = typemap_get(type, name);
-
- /* if there is not matching, look for a typemap in the
- original typedef, if any, like in:
-
- typedef unsigned long size_t;
- ...
- %apply(size_t) {my_size}; ==> %apply(unsigned long) {my_size};
- */
- if (!sm) {
- SwigType *ntype = SwigType_typedef_resolve(type);
- if (ntype && (Cmp(ntype, type) != 0)) {
- sm = typemap_get(ntype, name);
- }
- Delete(ntype);
- }
-
- if (sm) {
- /* Got a typemap. Need to only merge attributes for methods that match our signature */
- Iterator ki;
- Hash *deferred_add;
- match = 1;
-
- /* Since typemap_register can modify the `sm` hash, we *cannot* call typemap_register while iterating over sm.
- * Create a temporary hash of typemaps to add immediately after. */
- deferred_add = NewHash();
- for (ki = First(sm); ki.key; ki = Next(ki)) {
- /* Check for a signature match with the source signature */
- if ((count_args(ki.key) == narg) && (Strstr(ki.key, ssig))) {
- String *oldm;
- /* A typemap we have to copy */
- String *nkey = Copy(ki.key);
- Replace(nkey, ssig, dsig, DOH_REPLACE_ANY);
-
- /* Make sure the typemap doesn't already exist in the target map */
- oldm = Getattr(tm, nkey);
- if (!oldm || (!Getattr(tm, "code"))) {
- String *code;
- Hash *sm1 = ki.item;
-
- code = Getattr(sm1, "code");
- if (code) {
- Replace(nkey, dsig, "", DOH_REPLACE_ANY);
- Replace(nkey, "tmap:", "", DOH_REPLACE_ANY);
- Setattr(deferred_add, nkey, sm1);
- }
- }
- Delete(nkey);
- }
- }
-
- /* After assembling the key/item pairs, add the resulting typemaps */
- for (ki = First(deferred_add); ki.key; ki = Next(ki)) {
- Hash *sm1 = ki.item;
- String *src_str = ParmList_str_multibrackets(src);
- String *dest_str = ParmList_str_multibrackets(dest);
- String *source_directive = NewStringf("apply %s { %s }", src_str, dest_str);
-
- typemap_register(ki.key, dest, Getattr(sm1, "code"), Getattr(sm1, "locals"), Getattr(sm1, "kwargs"), source_directive);
-
- Delete(source_directive);
- Delete(dest_str);
- Delete(src_str);
- }
- Delete(deferred_add);
- }
- Delete(ssig);
- Delete(dsig);
- return match;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_typemap_clear_apply()
- *
- * %clear directive. Clears all typemaps for a type (in the current scope only).
- * ----------------------------------------------------------------------------- */
-
-/* Multi-argument %clear directive */
-void Swig_typemap_clear_apply(Parm *parms) {
- String *tsig;
- Parm *p, *np, *lastp;
- int narg = 0;
- Hash *tm;
- String *name;
-
- /* Create a type signature of the parameters */
- tsig = NewStringEmpty();
- p = parms;
- lastp = 0;
- while (p) {
- lastp = p;
- np = nextSibling(p);
- if (np) {
- Printf(tsig, "-%s+%s:", Getattr(p, "type"), Getattr(p, "name"));
- narg++;
- }
- p = np;
- }
- tm = get_typemap(Getattr(lastp, "type"));
- if (!tm) {
- Delete(tsig);
- return;
- }
- name = Getattr(lastp, "name");
- if (name) {
- tm = Getattr(tm, name);
- }
- if (tm) {
- /* Clear typemaps that match our signature */
- Iterator ki, ki2;
- char *ctsig = Char(tsig);
- for (ki = First(tm); ki.key; ki = Next(ki)) {
- char *ckey = Char(ki.key);
- if (strncmp(ckey, "tmap:", 5) == 0) {
- int na = count_args(ki.key);
- if ((na == narg) && strstr(ckey, ctsig)) {
- Hash *h = ki.item;
- for (ki2 = First(h); ki2.key; ki2 = Next(ki2)) {
- Delattr(h, ki2.key);
- }
- }
- }
- }
- }
- Delete(tsig);
-}
-
-/* Internal function to strip array dimensions. */
-static SwigType *strip_arrays(SwigType *type) {
- SwigType *t;
- int ndim;
- int i;
- t = Copy(type);
- ndim = SwigType_array_ndim(t);
- for (i = 0; i < ndim; i++) {
- SwigType_array_setdim(t, i, "ANY");
- }
- return t;
-}
-
-static void debug_search_result_display(Node *tm) {
- if (tm)
- Printf(stdout, " Using: %%%s\n", Getattr(tm, "source"));
- else
- Printf(stdout, " None found\n");
-}
-
-/* -----------------------------------------------------------------------------
- * typemap_search_helper()
- *
- * Helper function for typemap_search to see if there is a type match in the typemap
- * tm. A match is sought in this order:
- * %typemap(tm_method) ctype cqualifiedname
- * %typemap(tm_method) ctype cname
- * %typemap(tm_method) ctype
- * ----------------------------------------------------------------------------- */
-
-static Hash *typemap_search_helper(int debug_display, Hash *tm, const String *tm_method, SwigType *ctype, const String *cqualifiedname, const String *cname, Hash **backup) {
- Hash *result = 0;
- Hash *tm1;
- if (debug_display && cqualifiedname)
- Printf(stdout, " Looking for: %s\n", SwigType_str(ctype, cqualifiedname));
- if (tm && cqualifiedname) {
- tm1 = Getattr(tm, cqualifiedname);
- if (tm1) {
- result = Getattr(tm1, tm_method); /* See if there is a type - qualified name match */
- if (result && Getattr(result, "code"))
- goto ret_result;
- if (result)
- *backup = result;
- }
- }
- if (debug_display && cname)
- Printf(stdout, " Looking for: %s\n", SwigType_str(ctype, cname));
- if (tm && cname) {
- tm1 = Getattr(tm, cname);
- if (tm1) {
- result = Getattr(tm1, tm_method); /* See if there is a type - name match */
- if (result && Getattr(result, "code"))
- goto ret_result;
- if (result)
- *backup = result;
- }
- }
- if (debug_display)
- Printf(stdout, " Looking for: %s\n", SwigType_str(ctype, 0));
- if (tm) {
- result = Getattr(tm, tm_method); /* See if there is simply a type without name match */
- if (result && Getattr(result, "code"))
- goto ret_result;
- if (result)
- *backup = result;
- }
-ret_result:
- return result;
-}
-
-/* -----------------------------------------------------------------------------
- * typemap_search()
- *
- * Search for a typemap match. This is where the typemap pattern matching rules
- * are implemented... tries to find the most specific typemap that includes a
- * 'code' attribute.
- * ----------------------------------------------------------------------------- */
-
-static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type, const_String_or_char_ptr name, const_String_or_char_ptr qualifiedname, SwigType **matchtype, Node *node) {
- Hash *result = 0;
- Hash *tm;
- Hash *backup = 0;
- SwigType *primitive = 0;
- SwigType *ctype = 0;
- SwigType *ctype_unstripped = 0;
- int isarray;
- const String *cname = 0;
- const String *cqualifiedname = 0;
- String *tm_method = typemap_method_name(tmap_method);
- int debug_display = (in_typemap_search_multi == 0) && typemap_search_debug;
-
- if ((name) && Len(name))
- cname = name;
- if ((qualifiedname) && Len(qualifiedname))
- cqualifiedname = qualifiedname;
-
- if (debug_display) {
- String *typestr = SwigType_str(type, cqualifiedname ? cqualifiedname : cname);
- Swig_diagnostic(Getfile(node), Getline(node), "Searching for a suitable '%s' typemap for: %s\n", tmap_method, typestr);
- Delete(typestr);
- }
- ctype = Copy(type);
- ctype_unstripped = Copy(ctype);
- while (ctype) {
- /* Try to get an exact type-match */
- tm = get_typemap(ctype);
- result = typemap_search_helper(debug_display, tm, tm_method, ctype, cqualifiedname, cname, &backup);
- if (result && Getattr(result, "code"))
- goto ret_result;
-
- {
- /* Look for the type reduced to just the template prefix - for templated types without the template parameter list being specified */
- SwigType *template_prefix = SwigType_istemplate_only_templateprefix(ctype);
- if (template_prefix) {
- tm = get_typemap(template_prefix);
- result = typemap_search_helper(debug_display, tm, tm_method, template_prefix, cqualifiedname, cname, &backup);
- Delete(template_prefix);
- if (result && Getattr(result, "code"))
- goto ret_result;
- }
- }
-
- /* look for [ANY] arrays */
- isarray = SwigType_isarray(ctype);
- if (isarray) {
- /* If working with arrays, strip away all of the dimensions and replace with "ANY".
- See if that generates a match */
- SwigType *noarrays = strip_arrays(ctype);
- tm = get_typemap(noarrays);
- result = typemap_search_helper(debug_display, tm, tm_method, noarrays, cqualifiedname, cname, &backup);
- Delete(noarrays);
- if (result && Getattr(result, "code"))
- goto ret_result;
- }
-
- /* No match so far - try with a qualifier stripped (strip one qualifier at a time until none remain)
- * The order of stripping in SwigType_strip_single_qualifier is used to provide some sort of consistency
- * with the default (SWIGTYPE) typemap matching rules for the first qualifier to be stripped. */
- {
- SwigType *oldctype = ctype;
- ctype = SwigType_strip_single_qualifier(oldctype);
- if (!Equal(ctype, oldctype)) {
- Delete(oldctype);
- continue;
- }
- Delete(oldctype);
- }
-
- /* Once all qualifiers are stripped try resolve a typedef */
- {
- SwigType *oldctype = ctype;
- ctype = SwigType_typedef_resolve(ctype_unstripped);
- Delete(oldctype);
- Delete(ctype_unstripped);
- ctype_unstripped = Copy(ctype);
- }
- }
-
- /* Hmmm. Well, no match seems to be found at all. See if there is some kind of default (SWIGTYPE) mapping */
-
- primitive = SwigType_default_create(type);
- while (primitive) {
- tm = get_typemap(primitive);
- result = typemap_search_helper(debug_display, tm, tm_method, primitive, cqualifiedname, cname, &backup);
- if (result && Getattr(result, "code"))
- goto ret_result;
-
- {
- SwigType *nprim = SwigType_default_deduce(primitive);
- Delete(primitive);
- primitive = nprim;
- }
- }
- if (ctype != type) {
- Delete(ctype);
- ctype = 0;
- }
- result = backup;
-
-ret_result:
- Delete(primitive);
- if (matchtype)
- *matchtype = Copy(ctype);
- Delete(ctype);
- Delete(ctype_unstripped);
- return result;
-}
-
-
-/* -----------------------------------------------------------------------------
- * typemap_search_multi()
- *
- * Search for a multi-argument typemap.
- * ----------------------------------------------------------------------------- */
-
-static Hash *typemap_search_multi(const_String_or_char_ptr tmap_method, ParmList *parms, int *nmatch) {
- SwigType *type;
- SwigType *mtype = 0;
- String *name;
- String *multi_tmap_method;
- Hash *tm;
- Hash *tm1 = 0;
-
- if (!parms) {
- *nmatch = 0;
- return 0;
- }
- type = Getattr(parms, "type");
- name = Getattr(parms, "name");
-
- /* Try to find a match on the first type */
- tm = typemap_search(tmap_method, type, name, 0, &mtype, parms);
- if (tm) {
- if (mtype && SwigType_isarray(mtype)) {
- Setattr(parms, "tmap:match", mtype);
- }
- Delete(mtype);
- multi_tmap_method = NewStringf("%s-%s+%s:", tmap_method, type, name);
- in_typemap_search_multi++;
- tm1 = typemap_search_multi(multi_tmap_method, nextSibling(parms), nmatch);
- in_typemap_search_multi--;
- if (tm1)
- tm = tm1;
- if (Getattr(tm, "code")) {
- *(nmatch) = *nmatch + 1;
- if (typemap_search_debug && tm1 && (in_typemap_search_multi == 0)) {
- Printf(stdout, " Multi-argument typemap found...\n");
- }
- } else {
- tm = 0;
- }
- Delete(multi_tmap_method);
- }
-
- if (typemap_search_debug && (in_typemap_search_multi == 0))
- debug_search_result_display(tm);
- if (typemaps_used_debug && (in_typemap_search_multi == 0) && tm) {
- String *typestr = SwigType_str(type, name);
- Swig_diagnostic(Getfile(parms), Getline(parms), "Typemap for %s (%s) : %%%s\n", typestr, tmap_method, Getattr(tm, "source"));
- assert(Getfile(parms) && Len(Getfile(parms)) > 0); /* Missing file and line numbering information */
- Delete(typestr);
- }
-
- return tm;
-}
-
-
-/* -----------------------------------------------------------------------------
- * typemap_replace_vars()
- *
- * Replaces typemap variables on a string. index is the $n variable.
- * type and pname are the type and parameter name.
- * ----------------------------------------------------------------------------- */
-
-static void replace_local_types(ParmList *p, const String *name, const String *rep) {
- SwigType *t;
- while (p) {
- t = Getattr(p, "type");
- Replace(t, name, rep, DOH_REPLACE_ANY);
- p = nextSibling(p);
- }
-}
-
-static int check_locals(ParmList *p, const char *s) {
- while (p) {
- char *c = GetChar(p, "type");
- if (strstr(c, s))
- return 1;
- p = nextSibling(p);
- }
- return 0;
-}
-
-static int typemap_replace_vars(String *s, ParmList *locals, SwigType *type, SwigType *rtype, String *pname, String *lname, int index) {
- char var[512];
- char *varname;
- SwigType *ftype;
- int bare_substitution_count = 0;
-
- Replaceall(s, "$typemap", "$TYPEMAP"); /* workaround for $type substitution below */
-
- ftype = SwigType_typedef_resolve_all(type);
-
- if (!pname)
- pname = lname;
- {
- Parm *p;
- int rep = 0;
- p = locals;
- while (p) {
- if (Strchr(Getattr(p, "type"), '$'))
- rep = 1;
- p = nextSibling(p);
- }
- if (!rep)
- locals = 0;
- }
-
- sprintf(var, "$%d_", index);
- varname = &var[strlen(var)];
-
- /* If the original datatype was an array. We're going to go through and substitute
- its array dimensions */
-
- if (SwigType_isarray(type) || SwigType_isarray(ftype)) {
- String *size;
- int ndim;
- int i;
- if (SwigType_array_ndim(type) != SwigType_array_ndim(ftype))
- type = ftype;
- ndim = SwigType_array_ndim(type);
- size = NewStringEmpty();
- for (i = 0; i < ndim; i++) {
- String *dim = SwigType_array_getdim(type, i);
- if (index == 1) {
- char t[32];
- sprintf(t, "$dim%d", i);
- Replace(s, t, dim, DOH_REPLACE_ANY);
- replace_local_types(locals, t, dim);
- }
- sprintf(varname, "dim%d", i);
- Replace(s, var, dim, DOH_REPLACE_ANY);
- replace_local_types(locals, var, dim);
- if (Len(size))
- Putc('*', size);
- Append(size, dim);
- Delete(dim);
- }
- sprintf(varname, "size");
- Replace(s, var, size, DOH_REPLACE_ANY);
- replace_local_types(locals, var, size);
- Delete(size);
- }
-
- /* Parameter name substitution */
- if (index == 1) {
- Replace(s, "$parmname", pname, DOH_REPLACE_ANY);
- }
- strcpy(varname, "name");
- Replace(s, var, pname, DOH_REPLACE_ANY);
-
- /* Type-related stuff */
- {
- SwigType *star_type, *amp_type, *base_type, *lex_type;
- SwigType *ltype, *star_ltype, *amp_ltype;
- String *mangle, *star_mangle, *amp_mangle, *base_mangle, *base_name, *base_type_str;
- String *descriptor, *star_descriptor, *amp_descriptor;
- String *ts;
- char *sc;
-
- sc = Char(s);
-
- if (strstr(sc, "type") || check_locals(locals, "type")) {
- /* Given type : $type */
- ts = SwigType_str(type, 0);
- if (index == 1) {
- Replace(s, "$type", ts, DOH_REPLACE_ANY);
- replace_local_types(locals, "$type", type);
- }
- strcpy(varname, "type");
- Replace(s, var, ts, DOH_REPLACE_ANY);
- replace_local_types(locals, var, type);
- Delete(ts);
- sc = Char(s);
- }
- if (strstr(sc, "ltype") || check_locals(locals, "ltype")) {
- /* Local type: $ltype */
- ltype = SwigType_ltype(type);
- ts = SwigType_str(ltype, 0);
- if (index == 1) {
- Replace(s, "$ltype", ts, DOH_REPLACE_ANY);
- replace_local_types(locals, "$ltype", ltype);
- }
- strcpy(varname, "ltype");
- Replace(s, var, ts, DOH_REPLACE_ANY);
- replace_local_types(locals, var, ltype);
- Delete(ts);
- Delete(ltype);
- sc = Char(s);
- }
- if (strstr(sc, "mangle") || strstr(sc, "descriptor")) {
- /* Mangled type */
-
- mangle = SwigType_manglestr(type);
- if (index == 1)
- Replace(s, "$mangle", mangle, DOH_REPLACE_ANY);
- strcpy(varname, "mangle");
- Replace(s, var, mangle, DOH_REPLACE_ANY);
-
- descriptor = NewStringf("SWIGTYPE%s", mangle);
-
- if (index == 1)
- if (Replace(s, "$descriptor", descriptor, DOH_REPLACE_ANY))
- SwigType_remember(type);
-
- strcpy(varname, "descriptor");
- if (Replace(s, var, descriptor, DOH_REPLACE_ANY))
- SwigType_remember(type);
-
- Delete(descriptor);
- Delete(mangle);
- }
-
- /* One pointer level removed */
- /* This creates variables of the form
- $*n_type
- $*n_ltype
- */
-
- if (SwigType_ispointer(ftype) || (SwigType_isarray(ftype)) || (SwigType_isreference(ftype)) || (SwigType_isrvalue_reference(ftype))) {
- if (!(SwigType_isarray(type) || SwigType_ispointer(type) || SwigType_isreference(type) || SwigType_isrvalue_reference(type))) {
- star_type = Copy(ftype);
- } else {
- star_type = Copy(type);
- }
- if (!(SwigType_isreference(star_type) || SwigType_isrvalue_reference(star_type))) {
- if (SwigType_isarray(star_type)) {
- SwigType_del_element(star_type);
- } else {
- SwigType_del_pointer(star_type);
- }
- ts = SwigType_str(star_type, 0);
- if (index == 1) {
- Replace(s, "$*type", ts, DOH_REPLACE_ANY);
- replace_local_types(locals, "$*type", star_type);
- }
- sprintf(varname, "$*%d_type", index);
- Replace(s, varname, ts, DOH_REPLACE_ANY);
- replace_local_types(locals, varname, star_type);
- Delete(ts);
- } else {
- SwigType_del_element(star_type);
- }
- star_ltype = SwigType_ltype(star_type);
- ts = SwigType_str(star_ltype, 0);
- if (index == 1) {
- Replace(s, "$*ltype", ts, DOH_REPLACE_ANY);
- replace_local_types(locals, "$*ltype", star_ltype);
- }
- sprintf(varname, "$*%d_ltype", index);
- Replace(s, varname, ts, DOH_REPLACE_ANY);
- replace_local_types(locals, varname, star_ltype);
- Delete(ts);
- Delete(star_ltype);
-
- star_mangle = SwigType_manglestr(star_type);
- if (index == 1)
- Replace(s, "$*mangle", star_mangle, DOH_REPLACE_ANY);
-
- sprintf(varname, "$*%d_mangle", index);
- Replace(s, varname, star_mangle, DOH_REPLACE_ANY);
-
- star_descriptor = NewStringf("SWIGTYPE%s", star_mangle);
- if (index == 1)
- if (Replace(s, "$*descriptor", star_descriptor, DOH_REPLACE_ANY))
- SwigType_remember(star_type);
- sprintf(varname, "$*%d_descriptor", index);
- if (Replace(s, varname, star_descriptor, DOH_REPLACE_ANY))
- SwigType_remember(star_type);
-
- Delete(star_descriptor);
- Delete(star_mangle);
- Delete(star_type);
- } else {
- /* TODO: Signal error if one of the $* substitutions is
- requested */
- }
- /* One pointer level added */
- amp_type = Copy(type);
- SwigType_add_pointer(amp_type);
- ts = SwigType_str(amp_type, 0);
- if (index == 1) {
- Replace(s, "$&type", ts, DOH_REPLACE_ANY);
- replace_local_types(locals, "$&type", amp_type);
- }
- sprintf(varname, "$&%d_type", index);
- Replace(s, varname, ts, DOH_REPLACE_ANY);
- replace_local_types(locals, varname, amp_type);
- Delete(ts);
-
- amp_ltype = SwigType_ltype(type);
- SwigType_add_pointer(amp_ltype);
- ts = SwigType_str(amp_ltype, 0);
-
- if (index == 1) {
- Replace(s, "$&ltype", ts, DOH_REPLACE_ANY);
- replace_local_types(locals, "$&ltype", amp_ltype);
- }
- sprintf(varname, "$&%d_ltype", index);
- Replace(s, varname, ts, DOH_REPLACE_ANY);
- replace_local_types(locals, varname, amp_ltype);
- Delete(ts);
- Delete(amp_ltype);
-
- amp_mangle = SwigType_manglestr(amp_type);
- if (index == 1)
- Replace(s, "$&mangle", amp_mangle, DOH_REPLACE_ANY);
- sprintf(varname, "$&%d_mangle", index);
- Replace(s, varname, amp_mangle, DOH_REPLACE_ANY);
-
- amp_descriptor = NewStringf("SWIGTYPE%s", amp_mangle);
- if (index == 1)
- if (Replace(s, "$&descriptor", amp_descriptor, DOH_REPLACE_ANY))
- SwigType_remember(amp_type);
- sprintf(varname, "$&%d_descriptor", index);
- if (Replace(s, varname, amp_descriptor, DOH_REPLACE_ANY))
- SwigType_remember(amp_type);
-
- Delete(amp_descriptor);
- Delete(amp_mangle);
- Delete(amp_type);
-
- /* Base type */
- if (SwigType_isarray(type)) {
- base_type = Copy(type);
- Delete(SwigType_pop_arrays(base_type));
- } else {
- base_type = SwigType_base(type);
- }
-
- base_type_str = SwigType_str(base_type, 0);
- base_name = SwigType_namestr(base_type_str);
- if (index == 1) {
- Replace(s, "$basetype", base_name, DOH_REPLACE_ANY);
- replace_local_types(locals, "$basetype", base_name);
- }
- strcpy(varname, "basetype");
- Replace(s, var, base_type_str, DOH_REPLACE_ANY);
- replace_local_types(locals, var, base_name);
-
- base_mangle = SwigType_manglestr(base_type);
- if (index == 1)
- Replace(s, "$basemangle", base_mangle, DOH_REPLACE_ANY);
- strcpy(varname, "basemangle");
- Replace(s, var, base_mangle, DOH_REPLACE_ANY);
- Delete(base_mangle);
- Delete(base_name);
- Delete(base_type_str);
- Delete(base_type);
-
- lex_type = SwigType_base(rtype);
- if (index == 1)
- Replace(s, "$lextype", lex_type, DOH_REPLACE_ANY);
- strcpy(varname, "lextype");
- Replace(s, var, lex_type, DOH_REPLACE_ANY);
- Delete(lex_type);
- }
-
- /* Replace any $n. with (&n)-> */
- {
- char temp[64];
- sprintf(var, "$%d.", index);
- sprintf(temp, "(&$%d)->", index);
- Replace(s, var, temp, DOH_REPLACE_ANY);
- }
-
- /* Replace the bare $n variable */
- sprintf(var, "$%d", index);
- bare_substitution_count = Replace(s, var, lname, DOH_REPLACE_NUMBER_END);
- Delete(ftype);
- return bare_substitution_count;
-}
-
-/* ------------------------------------------------------------------------
- * static typemap_locals()
- *
- * Takes a string, a parameter list and a wrapper function argument and
- * creates the local variables.
- * ------------------------------------------------------------------------ */
-
-static void typemap_locals(String *s, ParmList *l, Wrapper *f, int argnum) {
- Parm *p;
- char *new_name;
-
- p = l;
- while (p) {
- SwigType *pt = Getattr(p, "type");
- SwigType *at = SwigType_alttype(pt, 1);
- String *pn = Getattr(p, "name");
- String *value = Getattr(p, "value");
- if (at)
- pt = at;
- if (pn) {
- if (Len(pn) > 0) {
- String *str;
- int isglobal = 0;
-
- str = NewStringEmpty();
-
- if (strncmp(Char(pn), "_global_", 8) == 0) {
- isglobal = 1;
- }
-
- /* If the user gave us $type as the name of the local variable, we'll use
- the passed datatype instead */
-
- if ((argnum >= 0) && (!isglobal)) {
- Printf(str, "%s%d", pn, argnum);
- } else {
- Append(str, pn);
- }
- if (isglobal && Wrapper_check_local(f, str)) {
- p = nextSibling(p);
- Delete(str);
- if (at)
- Delete(at);
- continue;
- }
- if (value) {
- String *pstr = SwigType_str(pt, str);
- new_name = Wrapper_new_localv(f, str, pstr, "=", value, NIL);
- Delete(pstr);
- } else {
- String *pstr = SwigType_str(pt, str);
- new_name = Wrapper_new_localv(f, str, pstr, NIL);
- Delete(pstr);
- }
- if (!isglobal) {
- /* Substitute */
- Replace(s, pn, new_name, DOH_REPLACE_ID | DOH_REPLACE_NOQUOTE);
- }
- Delete(str);
- }
- }
- p = nextSibling(p);
- if (at)
- Delete(at);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * typemap_warn()
- *
- * If any warning message is attached to this parameter's "tmap:<method>:warning"
- * attribute, return the warning message (special variables will need expanding
- * before displaying the warning).
- * ----------------------------------------------------------------------------- */
-
-static String *typemap_warn(const_String_or_char_ptr tmap_method, Parm *p) {
- String *temp = NewStringf("%s:warning", tmap_method);
- String *w = Getattr(p, typemap_method_name(temp));
- Delete(temp);
- return w ? Copy(w) : 0;
-}
-
-/* -----------------------------------------------------------------------------
- * typemap_merge_fragment_kwargs()
- *
- * If multiple 'fragment' attributes are provided to a typemap, combine them by
- * concatenating with commas.
- * ----------------------------------------------------------------------------- */
-
-static void typemap_merge_fragment_kwargs(Parm *kw) {
- Parm *reattach_kw = NULL;
- Parm *prev_kw = NULL;
- Parm *next_kw = NULL;
- String *fragment = NULL;
- while (kw) {
- next_kw = nextSibling(kw);
- if (Strcmp(Getattr(kw, "name"), "fragment") == 0) {
- String *thisfragment = Getattr(kw, "value");
- String *kwtype = Getattr(kw, "type");
- if (!fragment) {
- /* First fragment found; it should remain in the list */
- fragment = thisfragment;
- prev_kw = kw;
- } else {
- /* Concatenate to previously found fragment */
- Printv(fragment, ",", thisfragment, NULL);
- reattach_kw = prev_kw;
- }
- if (kwtype) {
- String *mangle = Swig_string_mangle(kwtype);
- Append(fragment, mangle);
- Delete(mangle);
- /* Remove 'type' from kwargs so it's not duplicated later */
- Setattr(kw, "type", NULL);
- }
- } else {
- /* Not a fragment */
- if (reattach_kw) {
- /* Update linked list to remove duplicate fragment */
- DohIncref(kw);
- set_nextSibling(reattach_kw, kw);
- set_previousSibling(kw, reattach_kw);
- Delete(reattach_kw);
- reattach_kw = NULL;
- }
- prev_kw = kw;
- }
- kw = next_kw;
- }
- if (reattach_kw) {
- /* Update linked list to remove duplicate fragment */
- set_nextSibling(reattach_kw, kw);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_typemap_lookup()
- *
- * Attach one or more typemaps to a node and optionally generate the typemap contents
- * into the wrapper.
- *
- * Looks for a typemap matching the given type and name and attaches the typemap code
- * and any typemap attributes to the provided node.
- *
- * The node should contain the "type" and "name" attributes for the typemap match on.
- * input. The typemap code and typemap attribute values are attached onto the node
- * prefixed with "tmap:". For example with tmap_method="in", the typemap code can be retrieved
- * with a call to Getattr(node, "tmap:in") (this is also the string returned) and the
- * "noblock" attribute can be retrieved with a call to Getattr(node, "tmap:in:noblock").
- *
- * tmap_method - typemap method, eg "in", "out", "newfree"
- * node - the node to attach the typemap and typemap attributes to
- * lname - name of variable to substitute $1, $2 etc for
- * f - wrapper code to generate into if non null
- * actioncode - code to generate into f before the out typemap code, unless
- * the optimal attribute is set in the out typemap in which case
- * $1 in the out typemap will be replaced by the code in actioncode.
- * ----------------------------------------------------------------------------- */
-
-static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, Node *node, const_String_or_char_ptr lname, Wrapper *f, String *actioncode) {
- SwigType *type;
- SwigType *mtype = 0;
- String *pname;
- String *qpname = 0;
- String *noscope_pname = 0;
- Hash *tm = 0;
- String *s = 0;
- String *sdef = 0;
- String *warning = 0;
- ParmList *locals;
- ParmList *kw;
- char temp[256];
- String *symname;
- String *cname = 0;
- String *clname = 0;
- char *cmethod = Char(tmap_method);
- int optimal_attribute = 0;
- int optimal_substitution = 0;
- int delete_optimal_attribute = 0;
- int num_substitutions = 0;
- SwigType *matchtype = 0;
-
- type = Getattr(node, "type");
- if (!type)
- return sdef;
-
- /* Special hook (hack!). Check for the 'ref' feature and add code it contains to any 'newfree' typemap code.
- * We could choose to put this hook into a number of different typemaps, not necessarily 'newfree'...
- * Rather confusingly 'newfree' is used to release memory and the 'ref' feature is used to add in memory references - yuck! */
- if (Cmp(tmap_method, "newfree") == 0) {
- String *base = SwigType_base(type);
- Node *typenode = Swig_symbol_clookup(base, 0);
- if (typenode)
- sdef = Swig_ref_call(typenode, lname);
- Delete(base);
- }
-
- pname = Getattr(node, "name");
- noscope_pname = Copy(pname);
-
- if (pname && Getattr(node, "sym:symtab")) {
- /* Add on a qualified name search for any symbol in the symbol table, for example:
- * struct Foo {
- * int *foo(int bar) -> Foo::foo
- * };
- * Note that if node is a parameter (Parm *) then there will be no symbol table attached to the Parm *.
- */
- String *qsn;
- if (Swig_scopename_check(pname)) {
- /* sometimes pname is qualified, so we remove all the scope for the lookup */
- Delete(noscope_pname);
- noscope_pname = Swig_scopename_last(pname);
- /*
- Printf(stdout, "Removed scope: %s => %s\n", pname, noscope_pname);
- */
- }
- qsn = Swig_symbol_qualified(node);
- if (qsn && Len(qsn)) {
- qpname = NewStringf("%s::%s", qsn, noscope_pname);
- Delete(qsn);
- }
- }
-
- tm = typemap_search(tmap_method, type, noscope_pname, qpname, &mtype, node);
- if (typemap_search_debug)
- debug_search_result_display(tm);
- if (typemaps_used_debug && tm) {
- String *typestr = SwigType_str(type, qpname ? qpname : pname);
- Swig_diagnostic(Getfile(node), Getline(node), "Typemap for %s (%s) : %%%s\n", typestr, tmap_method, Getattr(tm, "source"));
- assert(Getfile(node) && Len(Getfile(node)) > 0); /* Missing file and line numbering information */
- Delete(typestr);
- }
-
- Delete(qpname);
- qpname = 0;
- Delete(noscope_pname);
- noscope_pname = 0;
-
- if (!tm)
- return sdef;
-
- s = Getattr(tm, "code");
- if (!s)
- return sdef;
-
- /* Empty typemap. No match */
- if (Cmp(s, "pass") == 0)
- return sdef;
-
- s = Copy(s); /* Make a local copy of the typemap code */
-
- /* Look in the "out" typemap for the "optimal" attribute */
- if (Cmp(cmethod, "out") == 0) {
- kw = Getattr(tm, "kwargs");
- while (kw) {
- if (Cmp(Getattr(kw, "name"), "optimal") == 0) {
- optimal_attribute = GetFlag(kw, "value");
- break;
- }
- kw = nextSibling(kw);
- }
- }
-
- if (optimal_attribute) {
- /* Note: "out" typemap is the only typemap that will have the "optimal" attribute set.
- * If f and actioncode are NULL, then the caller is just looking to attach the "out" attributes
- * ie, not use the typemap code, otherwise both f and actioncode must be non null. */
- if (actioncode) {
- const String *result_equals = NewStringf("%s = ", Swig_cresult_name());
- /* check that the code in the typemap can be used in this optimal way.
- * The code should be in the form "result = ...;\n". We need to extract
- * the "..." part. This may not be possible for various reasons, eg
- * code added by %exception. This optimal code generation is bit of a
- * hack and circumvents the normal requirement for a temporary variable
- * to hold the result returned from a wrapped function call.
- */
- if (Strncmp(actioncode, result_equals, Len(result_equals)) == 0 &&
- Strchr(actioncode, ';') == Char(actioncode) + Len(actioncode) - 2 &&
- Char(actioncode)[Len(actioncode) - 1] == '\n') {
- clname = NewStringWithSize(Char(actioncode) + Len(result_equals),
- Len(actioncode) - Len(result_equals) - 2);
- lname = clname;
- actioncode = 0;
- optimal_substitution = 1;
- } else {
- Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_IGNORED, Getfile(node), Getline(node), "Method %s usage of the optimal attribute ignored\n", Swig_name_decl(node));
- Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_IGNORED, Getfile(s), Getline(s), "in the out typemap as the following cannot be used to generate optimal code: %s\n", actioncode);
- delete_optimal_attribute = 1;
- }
- } else {
- assert(!f);
- }
- }
-
- if (actioncode) {
- assert(f);
- Append(f->code, actioncode);
- }
-
- /* emit local variables declared in typemap, eg emit declarations for aa and bb in:
- * %typemap(in) foo (int aa, int bb) "..." */
- locals = Getattr(tm, "locals");
- if (locals)
- locals = CopyParmList(locals);
-
- if (pname) {
- if (SwigType_istemplate(pname)) {
- cname = SwigType_namestr(pname);
- pname = cname;
- }
- }
- if (SwigType_istemplate((char *) lname)) {
- clname = SwigType_namestr((char *) lname);
- lname = clname;
- }
-
- matchtype = mtype && SwigType_isarray(mtype) ? mtype : type;
- num_substitutions = typemap_replace_vars(s, locals, matchtype, type, pname, (char *) lname, 1);
- if (optimal_substitution && num_substitutions > 1) {
- Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE, Getfile(node), Getline(node), "Multiple calls to %s might be generated due to\n", Swig_name_decl(node));
- Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE, Getfile(s), Getline(s), "optimal attribute usage in the out typemap.\n");
- }
-
- if (locals && f) {
- typemap_locals(s, locals, f, -1);
- }
-
- {
- ParmList *parm_sublist = NewParmWithoutFileLineInfo(type, pname);
- Setattr(parm_sublist, "lname", lname);
- replace_embedded_typemap(s, parm_sublist, f, tm);
- Delete(parm_sublist);
- }
-
- /* Attach kwargs - ie the typemap attributes */
- kw = Getattr(tm, "kwargs");
- typemap_merge_fragment_kwargs(kw);
- while (kw) {
- String *value = Copy(Getattr(kw, "value"));
- String *kwtype = Getattr(kw, "type");
- char *ckwname = Char(Getattr(kw, "name"));
- {
- /* Expand special variables in typemap attributes. */
- SwigType *ptype = Getattr(node, "type");
- String *pname = Getattr(node, "name");
- SwigType *mtype = Getattr(node, "tmap:match");
- SwigType *matchtype = mtype ? mtype : ptype;
- ParmList *parm_sublist;
- typemap_replace_vars(value, NULL, matchtype, ptype, pname, (char *)lname, 1);
-
- /* Expand special variable macros (embedded typemaps) in typemap attributes. */
- parm_sublist = NewParmWithoutFileLineInfo(ptype, pname);
- Setattr(parm_sublist, "lname", lname);
- replace_embedded_typemap(value, parm_sublist, NULL, tm);
- Delete(parm_sublist);
- }
- if (kwtype) {
- String *mangle = Swig_string_mangle(kwtype);
- Append(value, mangle);
- Delete(mangle);
- }
- sprintf(temp, "%s:%s", cmethod, ckwname);
- Setattr(node, typemap_method_name(temp), value);
- Delete(value);
- kw = nextSibling(kw);
- }
-
- if (delete_optimal_attribute)
- Delattr(node, "tmap:out:optimal");
-
- Replace(s, "$name", pname, DOH_REPLACE_ANY);
-
- symname = Getattr(node, "sym:name");
- if (symname)
- Replace(s, "$symname", symname, DOH_REPLACE_ANY);
-
- Setattr(node, typemap_method_name(tmap_method), s);
- if (locals) {
- sprintf(temp, "%s:locals", cmethod);
- Setattr(node, typemap_method_name(temp), locals);
- Delete(locals);
- }
-
- if (Checkattr(tm, "type", "SWIGTYPE")) {
- sprintf(temp, "%s:SWIGTYPE", cmethod);
- Setattr(node, typemap_method_name(temp), "1");
- }
-
- /* Print warnings, if any */
- warning = typemap_warn(cmethod, node);
- if (warning) {
- typemap_replace_vars(warning, 0, matchtype, type, pname, (char *) lname, 1);
- Replace(warning, "$name", pname, DOH_REPLACE_ANY);
- if (symname)
- Replace(warning, "$symname", symname, DOH_REPLACE_ANY);
- Swig_warning(0, Getfile(node), Getline(node), "%s\n", warning);
- Delete(warning);
- }
-
- /* Look for code fragments */
- {
- String *fragment;
- sprintf(temp, "%s:fragment", cmethod);
- fragment = Getattr(node, typemap_method_name(temp));
- if (fragment) {
- String *fname = Copy(fragment);
- Setfile(fname, Getfile(node));
- Setline(fname, Getline(node));
- Swig_fragment_emit(fname);
- Delete(fname);
- }
- }
-
- Delete(cname);
- Delete(clname);
- Delete(mtype);
- if (sdef) { /* put 'ref' and 'newfree' codes together */
- String *p = NewStringf("%s\n%s", sdef, s);
- Delete(s);
- Delete(sdef);
- s = p;
- }
- Delete(actioncode);
- return s;
-}
-
-String *Swig_typemap_lookup_out(const_String_or_char_ptr tmap_method, Node *node, const_String_or_char_ptr lname, Wrapper *f, String *actioncode) {
- assert(actioncode);
- assert(Cmp(tmap_method, "out") == 0);
- return Swig_typemap_lookup_impl(tmap_method, node, lname, f, actioncode);
-}
-
-String *Swig_typemap_lookup(const_String_or_char_ptr tmap_method, Node *node, const_String_or_char_ptr lname, Wrapper *f) {
- return Swig_typemap_lookup_impl(tmap_method, node, lname, f, 0);
-}
-
-/* -----------------------------------------------------------------------------
- * typemap_attach_kwargs()
- *
- * If this hash (tm) contains a linked list of parameters under its "kwargs"
- * attribute, add keys for each of those named keyword arguments to this
- * parameter for later use.
- * For example, attach the typemap attributes to firstp (first parameter in parameter list):
- * %typemap(in, foo="xyz") ...
- * A new attribute called "tmap:in:foo" with value "xyz" is attached to firstp.
- * Also expands special variables and special variable macros in the typemap attributes.
- * ----------------------------------------------------------------------------- */
-
-static void typemap_attach_kwargs(Hash *tm, const_String_or_char_ptr tmap_method, Parm *firstp, int nmatch) {
- String *temp = NewStringEmpty();
- Parm *kw = Getattr(tm, "kwargs");
- typemap_merge_fragment_kwargs(kw);
- while (kw) {
- String *value = Copy(Getattr(kw, "value"));
- String *type = Getattr(kw, "type");
- int i;
- Parm *p = firstp;
- /* Expand special variables */
- for (i = 0; i < nmatch; i++) {
- SwigType *type = Getattr(p, "type");
- String *pname = Getattr(p, "name");
- String *lname = Getattr(p, "lname");
- SwigType *mtype = Getattr(p, "tmap:match");
- SwigType *matchtype = mtype ? mtype : type;
- typemap_replace_vars(value, NULL, matchtype, type, pname, lname, i + 1);
- p = nextSibling(p);
- }
-
- /* Expand special variable macros (embedded typemaps).
- * Special variable are expanded first above as they might be used in the special variable macros.
- * For example: $typemap(imtype, $2_type). */
- p = firstp;
- for (i = 0; i < nmatch; i++) {
- SwigType *type = Getattr(p, "type");
- String *pname = Getattr(p, "name");
- String *lname = Getattr(p, "lname");
- ParmList *parm_sublist = NewParmWithoutFileLineInfo(type, pname);
- Setattr(parm_sublist, "lname", lname);
- replace_embedded_typemap(value, parm_sublist, NULL, tm);
- p = nextSibling(p);
- }
- if (type) {
- Hash *v = NewHash();
- Setattr(v, "type", type);
- Setattr(v, "value", value);
- Delete(value);
- value = v;
- }
- Clear(temp);
- Printf(temp, "%s:%s", tmap_method, Getattr(kw, "name"));
- Setattr(firstp, typemap_method_name(temp), value);
- Delete(value);
- kw = nextSibling(kw);
- }
- Clear(temp);
- Printf(temp, "%s:match_type", tmap_method);
- Setattr(firstp, typemap_method_name(temp), Getattr(tm, "type"));
- Delete(temp);
-}
-
-static void typemap_emit_code_fragments(const_String_or_char_ptr tmap_method, Parm *p) {
- String *temp = NewStringf("%s:fragment", tmap_method);
- String *f = Getattr(p, typemap_method_name(temp));
- if (f) {
- String *fname = Copy(f);
- Setfile(fname, Getfile(p));
- Setline(fname, Getline(p));
- Swig_fragment_emit(fname);
- Delete(fname);
- }
- Delete(temp);
-}
-
-static String *typemap_get_option(Hash *tm, const_String_or_char_ptr name) {
- Parm *kw = Getattr(tm, "kwargs");
- while (kw) {
- String *kname = Getattr(kw, "name");
- if (Equal(kname, name)) {
- return Getattr(kw, "value");
- }
- kw = nextSibling(kw);
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_typemap_attach_parms()
- *
- * Given a parameter list, this function attaches all of the typemaps and typemap
- * attributes to the parameter for each type in the parameter list.
- *
- * This function basically provides the typemap code and typemap attribute values as
- * attributes on each parameter prefixed with "tmap:". For example with tmap_method="in", the typemap
- * code can be retrieved for the first parameter with a call to Getattr(parm, "tmap:in")
- * and the "numinputs" attribute can be retrieved with a call to Getattr(parm, "tmap:in:numinputs").
- *
- * tmap_method - typemap method, eg "in", "out", "newfree"
- * parms - parameter list to attach each typemap and all typemap attributes
- * f - wrapper code to generate into if non null
- * ----------------------------------------------------------------------------- */
-
-void Swig_typemap_attach_parms(const_String_or_char_ptr tmap_method, ParmList *parms, Wrapper *f) {
- Parm *p, *firstp;
- Hash *tm;
- int nmatch = 0;
- int i;
- String *s;
- String *warning = 0;
- ParmList *locals;
- int argnum = 0;
- char temp[256];
- char *cmethod = Char(tmap_method);
- String *kwmatch = 0;
- p = parms;
-
-#ifdef SWIG_DEBUG
- Printf(stdout, "Swig_typemap_attach_parms: %s\n", tmap_method);
-#endif
-
- while (p) {
- argnum++;
- nmatch = 0;
-#ifdef SWIG_DEBUG
- Printf(stdout, "parms: %s %s %s\n", tmap_method, Getattr(p, "name"), Getattr(p, "type"));
-#endif
- tm = typemap_search_multi(tmap_method, p, &nmatch);
-#ifdef SWIG_DEBUG
- if (tm)
- Printf(stdout, "found: %s\n", tm);
-#endif
- if (!tm) {
- p = nextSibling(p);
- continue;
- }
- /*
- Check if the typemap requires to match the type of another
- typemap, for example:
-
- %typemap(in) SWIGTYPE * (int var) {...}
- %typemap(freearg,match="in") SWIGTYPE * {if (var$argnum) ...}
-
- here, the freearg typemap requires the "in" typemap to match,
- or the 'var$argnum' variable will not exist.
- */
- kwmatch = typemap_get_option(tm, "match");
- if (kwmatch) {
- String *tmname = NewStringf("tmap:%s", kwmatch);
- String *tmin = Getattr(p, tmname);
- Delete(tmname);
-#ifdef SWIG_DEBUG
- if (tm)
- Printf(stdout, "matching: %s\n", kwmatch);
-#endif
- if (tmin) {
- String *tmninp = NewStringf("tmap:%s:numinputs", kwmatch);
- String *ninp = Getattr(p, tmninp);
- Delete(tmninp);
- if (ninp && Equal(ninp, "0")) {
- p = nextSibling(p);
- continue;
- } else {
- SwigType *typetm = Getattr(tm, "type");
- String *temp = NewStringf("tmap:%s:match_type", kwmatch);
- SwigType *typein = Getattr(p, temp);
- Delete(temp);
- if (!Equal(typein, typetm)) {
- p = nextSibling(p);
- continue;
- } else {
- int nnmatch;
- Hash *tmapin = typemap_search_multi(kwmatch, p, &nnmatch);
- String *tmname = Getattr(tm, "pname");
- String *tnname = Getattr(tmapin, "pname");
- if (!(tmname && tnname && Equal(tmname, tnname)) && !(!tmname && !tnname)) {
- p = nextSibling(p);
- continue;
- }
- }
-
- }
- } else {
- p = nextSibling(p);
- continue;
- }
- }
-
- s = Getattr(tm, "code");
- if (!s) {
- p = nextSibling(p);
- continue;
- }
-#ifdef SWIG_DEBUG
- if (s)
- Printf(stdout, "code: %s\n", s);
-#endif
-
- /* Empty typemap. No match */
- if (Cmp(s, "pass") == 0) {
- p = nextSibling(p);
- continue;
- }
-
- s = Copy(s);
- locals = Getattr(tm, "locals");
- if (locals)
- locals = CopyParmList(locals);
- firstp = p;
-#ifdef SWIG_DEBUG
- Printf(stdout, "nmatch: %d\n", nmatch);
-#endif
- for (i = 0; i < nmatch; i++) {
- SwigType *type = Getattr(p, "type");
- String *pname = Getattr(p, "name");
- String *lname = Getattr(p, "lname");
- SwigType *mtype = Getattr(p, "tmap:match");
- SwigType *matchtype = mtype ? mtype : type;
-
- typemap_replace_vars(s, locals, matchtype, type, pname, lname, i + 1);
- if (mtype)
- Delattr(p, "tmap:match");
-
- if (Checkattr(tm, "type", "SWIGTYPE")) {
- sprintf(temp, "%s:SWIGTYPE", cmethod);
- Setattr(p, typemap_method_name(temp), "1");
- }
- p = nextSibling(p);
- }
-
- if (locals && f) {
- typemap_locals(s, locals, f, argnum);
- }
-
- replace_embedded_typemap(s, firstp, f, tm);
-
- /* Attach attributes to object */
-#ifdef SWIG_DEBUG
- Printf(stdout, "attach: %s %s %s\n", Getattr(firstp, "name"), typemap_method_name(tmap_method), s);
-#endif
- Setattr(firstp, typemap_method_name(tmap_method), s); /* Code object */
-
- if (locals) {
- sprintf(temp, "%s:locals", cmethod);
- Setattr(firstp, typemap_method_name(temp), locals);
- Delete(locals);
- }
-
- /* Attach a link to the next parameter. Needed for multimaps */
- sprintf(temp, "%s:next", cmethod);
- Setattr(firstp, typemap_method_name(temp), p);
-
- /* Attach kwargs */
- typemap_attach_kwargs(tm, tmap_method, firstp, nmatch);
-
- /* Replace the argument number */
- sprintf(temp, "%d", argnum);
- Replace(s, "$argnum", temp, DOH_REPLACE_ANY);
-
- /* Print warnings, if any */
- warning = typemap_warn(tmap_method, firstp);
- if (warning) {
- SwigType *type = Getattr(firstp, "type");
- String *pname = Getattr(firstp, "name");
- String *lname = Getattr(firstp, "lname");
- SwigType *mtype = Getattr(firstp, "tmap:match");
- SwigType *matchtype = mtype ? mtype : type;
- typemap_replace_vars(warning, 0, matchtype, type, pname, lname, 1);
- Replace(warning, "$argnum", temp, DOH_REPLACE_ANY);
- Swig_warning(0, Getfile(firstp), Getline(firstp), "%s\n", warning);
- Delete(warning);
- }
-
- /* Look for code fragments */
- typemap_emit_code_fragments(tmap_method, firstp);
-
- /* increase argnum to consider numinputs */
- argnum += nmatch - 1;
- Delete(s);
-#ifdef SWIG_DEBUG
- Printf(stdout, "res: %s %s %s\n", Getattr(firstp, "name"), typemap_method_name(tmap_method), Getattr(firstp, typemap_method_name(tmap_method)));
-#endif
-
- }
-#ifdef SWIG_DEBUG
- Printf(stdout, "Swig_typemap_attach_parms: end\n");
-#endif
-
-}
-
-/* Splits the arguments of an embedded typemap */
-static List *split_embedded_typemap(String *s) {
- List *args = 0;
- char *c, *start;
- int level = 0;
- int angle_level = 0;
- int leading = 1;
-
- args = NewList();
- c = strchr(Char(s), '(');
- assert(c);
- c++;
-
- start = c;
- while (*c) {
- if (*c == '\"') {
- c++;
- while (*c) {
- if (*c == '\\') {
- c++;
- } else {
- if (*c == '\"')
- break;
- }
- c++;
- }
- }
- if ((level == 0) && angle_level == 0 && ((*c == ',') || (*c == ')'))) {
- String *tmp = NewStringWithSize(start, (int)(c - start));
- Append(args, tmp);
- Delete(tmp);
- start = c + 1;
- leading = 1;
- if (*c == ')')
- break;
- c++;
- continue;
- }
- if (*c == '(')
- level++;
- if (*c == ')')
- level--;
- if (*c == '<')
- angle_level++;
- if (*c == '>')
- angle_level--;
- if (isspace((int) *c) && leading)
- start++;
- if (!isspace((int) *c))
- leading = 0;
- c++;
- }
- return args;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_typemap_replace_embedded_typemap()
- *
- * For special variable macro $typemap(...) expansion outside of typemaps.
- * Only limited usage works as most typemap special variables ($1, $input etc)
- * are not expanded correctly outside of typemaps.
- * ----------------------------------------------------------------------------- */
-
-void Swig_typemap_replace_embedded_typemap(String *s, Node *file_line_node) {
- Setfile(s, Getfile(file_line_node));
- Setline(s, Getline(file_line_node));
- Replaceall(s, "$typemap", "$TYPEMAP");
- replace_embedded_typemap(s, 0, 0, file_line_node);
-}
-
-/* -----------------------------------------------------------------------------
- * replace_embedded_typemap()
- *
- * This function replaces the special variable macro $typemap(...) with typemap
- * code. The general form of $typemap is as follows:
- *
- * $typemap(method, typelist, var1=value, var2=value, ...)
- *
- * where varx parameters are optional and undocumented; they were used in an earlier version of $typemap.
- * A search is made using the typemap matching rules of form:
- *
- * %typemap(method) typelist {...}
- *
- * and if found will substitute in the typemap contents, making appropriate variable replacements.
- *
- * For example:
- * $typemap(in, int) # simple usage matching %typemap(in) int { ... }
- * $typemap(in, int b) # simple usage matching %typemap(in) int b { ... } or above %typemap
- * $typemap(in, (Foo<int, bool> a, int b)) # multi-argument typemap matching %typemap(in) (Foo<int, bool> a, int b) {...}
- * ----------------------------------------------------------------------------- */
-
-static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper *f, Node *file_line_node) {
- char *start = 0;
- while ((start = strstr(Char(s), "$TYPEMAP("))) { /* note $typemap capitalisation to $TYPEMAP hack */
-
- /* Gather the parameters */
- char *end = 0, *c;
- int level = 0;
- String *dollar_typemap;
- int syntax_error = 1;
- c = start;
- while (*c) {
- if (*c == '(')
- level++;
- if (*c == ')') {
- level--;
- if (level == 0) {
- end = c + 1;
- break;
- }
- }
- c++;
- }
- if (end) {
- dollar_typemap = NewStringWithSize(start, (int)((end - start)));
- syntax_error = 0;
- } else {
- dollar_typemap = NewStringWithSize(start, (int)((c - start)));
- }
-
- if (!syntax_error) {
- List *l;
- String *tmap_method;
- Hash *vars;
- syntax_error = 1;
-
- /* Split apart each parameter in $typemap(...) */
- l = split_embedded_typemap(dollar_typemap);
-
- if (Len(l) >= 2) {
- ParmList *to_match_parms;
- tmap_method = Getitem(l, 0);
-
- /* the second parameter might contain multiple sub-parameters for multi-argument
- * typemap matching, so split these parameters apart */
- to_match_parms = Swig_cparse_parms(Getitem(l, 1), file_line_node);
- if (to_match_parms) {
- Parm *p = to_match_parms;
- Parm *sub_p = parm_sublist;
- String *empty_string = NewStringEmpty();
- String *lname = empty_string;
- while (p) {
- if (sub_p) {
- lname = Getattr(sub_p, "lname");
- sub_p = nextSibling(sub_p);
- }
- Setattr(p, "lname", lname);
- p = nextSibling(p);
- }
- Delete(empty_string);
- }
-
- /* process optional extra parameters - the variable replacements (undocumented) */
- vars = NewHash();
- {
- int i, ilen;
- ilen = Len(l);
- for (i = 2; i < ilen; i++) {
- String *parm = Getitem(l, i);
- char *eq = strchr(Char(parm), '=');
- char *c = Char(parm);
- if (eq && (eq - c > 0)) {
- String *name = NewStringWithSize(c, (int)(eq - c));
- String *value = NewString(eq + 1);
- Insert(name, 0, "$");
- Setattr(vars, name, value);
- } else {
- to_match_parms = 0; /* error - variable replacement parameters must be of form varname=value */
- }
- }
- }
-
- /* Perform a typemap search */
- if (to_match_parms) {
- static int already_substituting = 0;
- String *tm;
- String *attr;
- int match = 0;
-#ifdef SWIG_DEBUG
- Printf(stdout, "Swig_typemap_attach_parms: embedded\n");
-#endif
- if (already_substituting < 10) {
- char* found_colon;
- already_substituting++;
- if ((in_typemap_search_multi == 0) && typemap_search_debug) {
- String *dtypemap = NewString(dollar_typemap);
- Replaceall(dtypemap, "$TYPEMAP", "$typemap");
- Printf(stdout, " Containing: %s\n", dtypemap);
- Delete(dtypemap);
- }
- found_colon = Strchr(tmap_method, ':');
- if (found_colon) {
- /* Substitute from a keyword argument to a typemap. Avoid emitting local variables from the attached typemap by passing NULL for the file. */
- String *temp_tmap_method = NewStringWithSize(Char(tmap_method), (int)(found_colon - Char(tmap_method)));
- Swig_typemap_attach_parms(temp_tmap_method, to_match_parms, NULL);
- Delete(temp_tmap_method);
- } else {
- Swig_typemap_attach_parms(tmap_method, to_match_parms, f);
- }
- already_substituting--;
-
- /* Look for the typemap code */
- attr = NewStringf("tmap:%s", tmap_method);
- tm = Getattr(to_match_parms, attr);
- if (tm) {
- Printf(attr, "%s", ":next");
- /* fail if multi-argument lookup requested in $typemap(...) and the lookup failed */
- if (!Getattr(to_match_parms, attr)) {
- /* Replace parameter variables */
- Iterator ki;
- for (ki = First(vars); ki.key; ki = Next(ki)) {
- Replace(tm, ki.key, ki.item, DOH_REPLACE_ANY);
- }
- /* offer the target language module the chance to make special variable substitutions */
- Language_replace_special_variables(tmap_method, tm, to_match_parms);
- /* finish up - do the substitution */
- Replace(s, dollar_typemap, tm, DOH_REPLACE_ANY);
- Delete(tm);
- match = 1;
- }
- }
-
- if (!match) {
- String *dtypemap = NewString(dollar_typemap);
- Replaceall(dtypemap, "$TYPEMAP", "$typemap");
- Swig_error(Getfile(s), Getline(s), "No typemap found for %s\n", dtypemap);
- Delete(dtypemap);
- }
- Delete(attr);
- } else {
- /* Simple recursive call check to prevent infinite recursion - this strategy only allows a limited
- * number of calls by a embedded typemaps to other embedded typemaps though */
- String *dtypemap = NewString(dollar_typemap);
- Replaceall(dtypemap, "$TYPEMAP", "$typemap");
- Swig_error(Getfile(s), Getline(s), "Likely recursive $typemap calls containing %s. Use -debug-tmsearch to debug.\n", dtypemap);
- Delete(dtypemap);
- }
- syntax_error = 0;
- }
- Delete(vars);
- }
- Delete(l);
- }
-
- if (syntax_error) {
- String *dtypemap = NewString(dollar_typemap);
- Replaceall(dtypemap, "$TYPEMAP", "$typemap");
- Swig_error(Getfile(s), Getline(s), "Syntax error in: %s\n", dtypemap);
- Delete(dtypemap);
- }
- Replace(s, dollar_typemap, "<error in embedded typemap>", DOH_REPLACE_ANY);
- Delete(dollar_typemap);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_typemap_debug()
- *
- * Display all typemaps
- * ----------------------------------------------------------------------------- */
-
-void Swig_typemap_debug(void) {
- int nesting_level = 2;
- Printf(stdout, "---[ typemaps ]--------------------------------------------------------------\n");
- Swig_print(typemaps, nesting_level);
- Printf(stdout, "-----------------------------------------------------------------------------\n");
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_typemap_search_debug_set()
- *
- * Turn on typemap searching debug display
- * ----------------------------------------------------------------------------- */
-
-void Swig_typemap_search_debug_set(void) {
- typemap_search_debug = 1;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_typemap_used_debug_set()
- *
- * Turn on typemaps used debug display
- * ----------------------------------------------------------------------------- */
-
-void Swig_typemap_used_debug_set(void) {
- typemaps_used_debug = 1;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_typemap_register_debug_set()
- *
- * Turn on typemaps used debug display
- * ----------------------------------------------------------------------------- */
-
-void Swig_typemap_register_debug_set(void) {
- typemap_register_debug = 1;
-}
-
diff --git a/contrib/tools/swig/Source/Swig/typeobj.c b/contrib/tools/swig/Source/Swig/typeobj.c
deleted file mode 100644
index 8cd2e28e98..0000000000
--- a/contrib/tools/swig/Source/Swig/typeobj.c
+++ /dev/null
@@ -1,1367 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * typeobj.c
- *
- * This file provides functions for constructing, manipulating, and testing
- * type objects. Type objects are merely the raw low-level representation
- * of C++ types. They do not incorporate high-level type system features
- * like typedef, namespaces, etc.
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-#include <ctype.h>
-#include <limits.h>
-
-/* -----------------------------------------------------------------------------
- * Synopsis
- *
- * This file provides a collection of low-level functions for constructing and
- * manipulating C++ data types. In SWIG, C++ datatypes are encoded as simple
- * text strings. This representation is compact, easy to debug, and easy to read.
- *
- * General idea:
- *
- * Types are represented by a base type (e.g., "int") and a collection of
- * type operators applied to the base (e.g., pointers, arrays, etc...).
- *
- * Encoding:
- *
- * Types are encoded as strings of type constructors such as follows:
- *
- * String Encoding C Example
- * --------------- ---------
- * p.p.int int **
- * a(300).a(400).int int [300][400]
- * p.q(const).char char const *
- *
- * All type constructors are denoted by a trailing '.':
- *
- * 'p.' = Pointer (*)
- * 'r.' = Reference or ref-qualifier (&)
- * 'z.' = Rvalue reference or ref-qualifier (&&)
- * 'a(n).' = Array of size n [n]
- * 'f(..,..).' = Function with arguments (args)
- * 'q(str).' = Qualifier, such as const or volatile (cv-qualifier)
- * 'm(cls).' = Pointer to member (cls::*)
- *
- * The complete type representation for varargs is:
- * 'v(...)'
- *
- * The encoding follows the order that you might describe a type in words.
- * For example "p.a(200).int" is "A pointer to array of int's" and
- * "p.q(const).char" is "a pointer to a const char".
- *
- * This representation of types is fairly convenient because ordinary string
- * operations can be used for type manipulation. For example, a type could be
- * formed by combining two strings such as the following:
- *
- * "p.p." + "a(400).int" = "p.p.a(400).int"
- *
- * For C++, typenames may be parameterized using <(...)>. Here are some
- * examples:
- *
- * String Encoding C++ Example
- * --------------- ------------
- * p.vector<(int)> vector<int> *
- * r.foo<(int,p.double)> foo<int,double *> &
- *
- * Contents of this file:
- *
- * Most of this functions in this file pertain to the low-level manipulation
- * of type objects. There are constructor functions like this:
- *
- * SwigType_add_pointer()
- * SwigType_add_reference()
- * SwigType_add_rvalue_reference()
- * SwigType_add_array()
- *
- * These are used to build new types. There are also functions to undo these
- * operations. For example:
- *
- * SwigType_del_pointer()
- * SwigType_del_reference()
- * SwigType_del_rvalue_reference()
- * SwigType_del_array()
- *
- * In addition, there are query functions
- *
- * SwigType_ispointer()
- * SwigType_isreference()
- * SwigType_isrvalue_reference()
- * SwigType_isarray()
- *
- * Finally, there are some data extraction functions that can be used to
- * extract array dimensions, template arguments, and so forth.
- *
- * It is very important for developers to realize that the functions in this
- * module do *NOT* incorporate higher-level type system features like typedef.
- * For example, you could have C code like this:
- *
- * typedef int *intptr;
- *
- * In this case, a SwigType of type 'intptr' will be treated as a simple type and
- * functions like SwigType_ispointer() will evaluate as false. It is strongly
- * advised that developers use the TypeSys_* interface to check types in a more
- * reliable manner.
- * ----------------------------------------------------------------------------- */
-
-
-/* -----------------------------------------------------------------------------
- * NewSwigType()
- *
- * Constructs a new type object. Eventually, it would be nice for this function
- * to accept an initial value in the form a C/C++ abstract type (currently unimplemented).
- * ----------------------------------------------------------------------------- */
-
-#ifdef NEW
-SwigType *NewSwigType(const_String_or_char_ptr initial) {
- return NewString(initial);
-}
-
-#endif
-
-/* The next few functions are utility functions used in the construction and
- management of types */
-
-/* -----------------------------------------------------------------------------
- * static element_size()
- *
- * This utility function finds the size of a single type element in a type string.
- * Type elements are always delimited by periods, but may be nested with
- * parentheses. A nested element is always handled as a single item.
- *
- * Returns the integer size of the element (which can be used to extract a
- * substring, to chop the element off, or for other purposes).
- * ----------------------------------------------------------------------------- */
-
-static int element_size(char *c) {
- int nparen;
- char *s = c;
- while (*c) {
- if (*c == '.') {
- c++;
- return (int) (c - s);
- } else if (*c == '(') {
- nparen = 1;
- c++;
- while (*c) {
- if (*c == '(')
- nparen++;
- if (*c == ')') {
- nparen--;
- if (nparen == 0)
- break;
- }
- c++;
- }
- }
- if (*c)
- c++;
- }
- return (int) (c - s);
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_del_element()
- *
- * Deletes one type element from the type.
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_del_element(SwigType *t) {
- int sz = element_size(Char(t));
- Delslice(t, 0, sz);
- return t;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_pop()
- *
- * Pop one type element off the type.
- * For example:
- * t in: q(const).p.Integer
- * t out: p.Integer
- * result: q(const).
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_pop(SwigType *t) {
- SwigType *result;
- char *c;
- int sz;
-
- c = Char(t);
- if (!*c)
- return 0;
-
- sz = element_size(c);
- result = NewStringWithSize(c, sz);
- Delslice(t, 0, sz);
- c = Char(t);
- if (*c == '.') {
- Delitem(t, 0);
- }
- return result;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_last()
- *
- * Return the last element of the given (partial) type.
- * For example:
- * t: q(const).p.
- * result: p.
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_last(SwigType *t) {
- SwigType *result;
- char *c;
- char *last;
- int sz = 0;
-
- if (!t)
- return 0;
-
- /* Find the last element */
- c = Char(t);
- last = 0;
- while (*c) {
- last = c;
- sz = element_size(c);
- c = c + sz;
- if (*c == '.') {
- c++;
- sz++;
- }
- }
-
- /* Extract the last element */
- if (last) {
- result = NewStringWithSize(last, sz);
- } else {
- result = 0;
- }
-
- return result;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_parm()
- *
- * Returns the parameter of an operator as a string
- * ----------------------------------------------------------------------------- */
-
-String *SwigType_parm(const SwigType *t) {
- char *start, *c;
- int nparens = 0;
-
- c = Char(t);
- while (*c && (*c != '(') && (*c != '.'))
- c++;
- if (!*c || (*c == '.'))
- return 0;
- c++;
- start = c;
- while (*c) {
- if (*c == ')') {
- if (nparens == 0)
- break;
- nparens--;
- } else if (*c == '(') {
- nparens++;
- }
- c++;
- }
- return NewStringWithSize(start, (int) (c - start));
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_split()
- *
- * Splits a type into its component parts and returns a list of string.
- * ----------------------------------------------------------------------------- */
-
-List *SwigType_split(const SwigType *t) {
- String *item;
- List *list;
- char *c;
- int len;
-
- c = Char(t);
- list = NewList();
- while (*c) {
- len = element_size(c);
- item = NewStringWithSize(c, len);
- Append(list, item);
- Delete(item);
- c = c + len;
- if (*c == '.')
- c++;
- }
- return list;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_parmlist()
- *
- * Splits a comma separated list of parameters into its component parts
- * The input is expected to contain the parameter list within () brackets
- * Returns 0 if no argument list in the input, ie there are no round brackets ()
- * Returns an empty List if there are no parameters in the () brackets
- * For example:
- *
- * Foo(std::string,p.f().Bar<(int,double)>)
- *
- * returns 2 elements in the list:
- * std::string
- * p.f().Bar<(int,double)>
- * ----------------------------------------------------------------------------- */
-
-List *SwigType_parmlist(const String *p) {
- String *item = 0;
- List *list;
- char *c;
- char *itemstart;
- int size;
-
- assert(p);
- c = Char(p);
- while (*c && (*c != '(') && (*c != '.'))
- c++;
- if (!*c)
- return 0;
- assert(*c != '.'); /* p is expected to contain sub elements of a type */
- c++;
- list = NewList();
- itemstart = c;
- while (*c) {
- if (*c == ',') {
- size = (int) (c - itemstart);
- item = NewStringWithSize(itemstart, size);
- Append(list, item);
- Delete(item);
- itemstart = c + 1;
- } else if (*c == '(') {
- int nparens = 1;
- c++;
- while (*c) {
- if (*c == '(')
- nparens++;
- if (*c == ')') {
- nparens--;
- if (nparens == 0)
- break;
- }
- c++;
- }
- } else if (*c == ')') {
- break;
- }
- if (*c)
- c++;
- }
- size = (int) (c - itemstart);
- if (size > 0) {
- item = NewStringWithSize(itemstart, size);
- Append(list, item);
- }
- Delete(item);
- return list;
-}
-
-/* -----------------------------------------------------------------------------
- * Pointers
- *
- * SwigType_add_pointer()
- * SwigType_del_pointer()
- * SwigType_ispointer()
- *
- * Add, remove, and test if a type is a pointer. The deletion and query
- * functions take into account qualifiers (if any).
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_add_pointer(SwigType *t) {
- Insert(t, 0, "p.");
- return t;
-}
-
-SwigType *SwigType_del_pointer(SwigType *t) {
- char *c, *s;
- c = Char(t);
- s = c;
- /* Skip qualifiers, if any */
- if (strncmp(c, "q(", 2) == 0) {
- c = strchr(c, '.');
- assert(c);
- c++;
- }
- if (strncmp(c, "p.", 2)) {
- printf("Fatal error: SwigType_del_pointer applied to non-pointer.\n");
- Exit(EXIT_FAILURE);
- }
- Delslice(t, 0, (int)((c - s) + 2));
- return t;
-}
-
-int SwigType_ispointer(const SwigType *t) {
- char *c;
- if (!t)
- return 0;
- c = Char(t);
- /* Skip qualifiers, if any */
- if (strncmp(c, "q(", 2) == 0) {
- c = strchr(c, '.');
- if (!c)
- return 0;
- c++;
- }
- if (strncmp(c, "p.", 2) == 0) {
- return 1;
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * References
- *
- * SwigType_add_reference()
- * SwigType_del_reference()
- * SwigType_isreference()
- *
- * Add, remove, and test if a type is a reference. The deletion and query
- * functions take into account qualifiers (if any).
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_add_reference(SwigType *t) {
- Insert(t, 0, "r.");
- return t;
-}
-
-SwigType *SwigType_del_reference(SwigType *t) {
- char *c = Char(t);
- if (strncmp(c, "r.", 2)) {
- printf("Fatal error: SwigType_del_reference applied to non-reference.\n");
- Exit(EXIT_FAILURE);
- }
- Delslice(t, 0, 2);
- return t;
-}
-
-int SwigType_isreference(const SwigType *t) {
- char *c;
- if (!t)
- return 0;
- c = Char(t);
- if (strncmp(c, "r.", 2) == 0) {
- return 1;
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Rvalue References
- *
- * SwigType_add_rvalue_reference()
- * SwigType_del_rvalue_reference()
- * SwigType_isrvalue_reference()
- *
- * Add, remove, and test if a type is a rvalue reference. The deletion and query
- * functions take into account qualifiers (if any).
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_add_rvalue_reference(SwigType *t) {
- Insert(t, 0, "z.");
- return t;
-}
-
-SwigType *SwigType_del_rvalue_reference(SwigType *t) {
- char *c = Char(t);
- if (strncmp(c, "z.", 2)) {
- fprintf(stderr, "Fatal error: SwigType_del_rvalue_reference() applied to non-rvalue-reference.\n");
- Exit(EXIT_FAILURE);
- }
- Delslice(t, 0, 2);
- return t;
-}
-
-int SwigType_isrvalue_reference(const SwigType *t) {
- char *c;
- if (!t)
- return 0;
- c = Char(t);
- if (strncmp(c, "z.", 2) == 0) {
- return 1;
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Qualifiers
- *
- * SwigType_add_qualifier()
- * SwigType_del_qualifier()
- * SwigType_is_qualifier()
- *
- * Adds type qualifiers like "const" and "volatile". When multiple qualifiers
- * are added to a type, they are combined together into a single qualifier.
- * Repeated qualifications have no effect. Moreover, the order of qualifications
- * is alphabetical---meaning that "const volatile" and "volatile const" are
- * stored in exactly the same way as "q(const volatile)".
- * 'qual' can be a list of multiple qualifiers in any order, separated by spaces.
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_add_qualifier(SwigType *t, const_String_or_char_ptr qual) {
- List *qlist;
- String *allq, *newq;
- int i, sz;
- const char *cqprev = 0;
- const char *c = Char(t);
- const char *cqual = Char(qual);
-
- /* if 't' has no qualifiers and 'qual' is a single qualifier, simply add it */
- if ((strncmp(c, "q(", 2) != 0) && (strstr(cqual, " ") == 0)) {
- String *temp = NewStringf("q(%s).", cqual);
- Insert(t, 0, temp);
- Delete(temp);
- return t;
- }
-
- /* create string of all qualifiers */
- if (strncmp(c, "q(", 2) == 0) {
- allq = SwigType_parm(t);
- Append(allq, " ");
- SwigType_del_element(t); /* delete old qualifier list from 't' */
- } else {
- allq = NewStringEmpty();
- }
- Append(allq, qual);
-
- /* create list of all qualifiers from string */
- qlist = Split(allq, ' ', INT_MAX);
- Delete(allq);
-
- /* sort in alphabetical order */
- SortList(qlist, Strcmp);
-
- /* create new qualifier string from unique elements of list */
- sz = Len(qlist);
- newq = NewString("q(");
- for (i = 0; i < sz; ++i) {
- String *q = Getitem(qlist, i);
- const char *cq = Char(q);
- if (cqprev == 0 || strcmp(cqprev, cq) != 0) {
- if (i > 0) {
- Append(newq, " ");
- }
- Append(newq, q);
- cqprev = cq;
- }
- }
- Append(newq, ").");
- Delete(qlist);
-
- /* replace qualifier string with new one */
- Insert(t, 0, newq);
- Delete(newq);
- return t;
-}
-
-SwigType *SwigType_del_qualifier(SwigType *t) {
- char *c = Char(t);
- int check = strncmp(c, "q(", 2);
- assert(check == 0);
- (void)check;
- Delslice(t, 0, element_size(c));
- return t;
-}
-
-int SwigType_isqualifier(const SwigType *t) {
- char *c;
- if (!t)
- return 0;
- c = Char(t);
- if (strncmp(c, "q(", 2) == 0) {
- return 1;
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Function Pointers
- * ----------------------------------------------------------------------------- */
-
-int SwigType_isfunctionpointer(const SwigType *t) {
- char *c;
- if (!t)
- return 0;
- c = Char(t);
- if (strncmp(c, "p.f(", 4) == 0) {
- return 1;
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_functionpointer_decompose
- *
- * Decompose the function pointer into the parameter list and the return type
- * t - input and on completion contains the return type
- * returns the function's parameters
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_functionpointer_decompose(SwigType *t) {
- String *p;
- assert(SwigType_isfunctionpointer(t));
- p = SwigType_pop(t);
- Delete(p);
- p = SwigType_pop(t);
- return p;
-}
-
-/* -----------------------------------------------------------------------------
- * Member Pointers
- *
- * SwigType_add_memberpointer()
- * SwigType_del_memberpointer()
- * SwigType_ismemberpointer()
- *
- * Add, remove, and test for C++ pointer to members.
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_add_memberpointer(SwigType *t, const_String_or_char_ptr name) {
- String *temp = NewStringf("m(%s).", name);
- Insert(t, 0, temp);
- Delete(temp);
- return t;
-}
-
-SwigType *SwigType_del_memberpointer(SwigType *t) {
- char *c = Char(t);
- int check = strncmp(c, "m(", 2);
- assert(check == 0);
- (void)check;
- Delslice(t, 0, element_size(c));
- return t;
-}
-
-int SwigType_ismemberpointer(const SwigType *t) {
- char *c;
- if (!t)
- return 0;
- c = Char(t);
- if (strncmp(c, "m(", 2) == 0) {
- return 1;
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Arrays
- *
- * SwigType_add_array()
- * SwigType_del_array()
- * SwigType_isarray()
- *
- * Utility functions:
- *
- * SwigType_array_ndim() - Calculate number of array dimensions.
- * SwigType_array_getdim() - Get array dimension
- * SwigType_array_setdim() - Set array dimension
- * SwigType_array_type() - Return array type
- * SwigType_pop_arrays() - Remove all arrays
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_add_array(SwigType *t, const_String_or_char_ptr size) {
- String *temp = NewString("a(");
- Append(temp, size);
- Append(temp, ").");
- Insert(t, 0, temp);
- Delete(temp);
- return t;
-}
-
-SwigType *SwigType_del_array(SwigType *t) {
- char *c = Char(t);
- if (strncmp(c, "a(", 2)) {
- fprintf(stderr, "Fatal error: SwigType_del_array() applied to non-array.\n");
- Exit(EXIT_FAILURE);
- }
- Delslice(t, 0, element_size(c));
- return t;
-}
-
-int SwigType_isarray(const SwigType *t) {
- char *c;
- if (!t)
- return 0;
- c = Char(t);
- if (strncmp(c, "a(", 2) == 0) {
- return 1;
- }
- return 0;
-}
-/*
- * SwigType_prefix_is_simple_1D_array
- *
- * Determine if the type is a 1D array type that is treated as a pointer within SWIG
- * eg Foo[], Foo[3] return true, but Foo[3][3], Foo*[], Foo*[3], Foo**[] return false
- */
-int SwigType_prefix_is_simple_1D_array(const SwigType *t) {
- char *c = Char(t);
-
- if (c && (strncmp(c, "a(", 2) == 0)) {
- c = strchr(c, '.');
- if (c)
- return (*(++c) == 0);
- }
- return 0;
-}
-
-
-/* Remove all arrays */
-SwigType *SwigType_pop_arrays(SwigType *t) {
- String *ta;
- assert(SwigType_isarray(t));
- ta = NewStringEmpty();
- while (SwigType_isarray(t)) {
- SwigType *td = SwigType_pop(t);
- Append(ta, td);
- Delete(td);
- }
- return ta;
-}
-
-/* Return number of array dimensions */
-int SwigType_array_ndim(const SwigType *t) {
- int ndim = 0;
- char *c = Char(t);
-
- while (c && (strncmp(c, "a(", 2) == 0)) {
- c = strchr(c, '.');
- if (c) {
- c++;
- ndim++;
- }
- }
- return ndim;
-}
-
-/* Get nth array dimension */
-String *SwigType_array_getdim(const SwigType *t, int n) {
- char *c = Char(t);
- while (c && (strncmp(c, "a(", 2) == 0) && (n > 0)) {
- c = strchr(c, '.');
- if (c) {
- c++;
- n--;
- }
- }
- if (n == 0) {
- String *dim = SwigType_parm(c);
- if (SwigType_istemplate(dim)) {
- String *ndim = SwigType_namestr(dim);
- Delete(dim);
- dim = ndim;
- }
-
- return dim;
- }
-
- return 0;
-}
-
-/* Replace nth array dimension */
-void SwigType_array_setdim(SwigType *t, int n, const_String_or_char_ptr rep) {
- String *result = 0;
- char temp;
- char *start;
- char *c = Char(t);
-
- start = c;
- if (strncmp(c, "a(", 2)) {
- fprintf(stderr, "Fatal error: SwigType_array_type applied to non-array.\n");
- Exit(EXIT_FAILURE);
- }
-
- while (c && (strncmp(c, "a(", 2) == 0) && (n > 0)) {
- c = strchr(c, '.');
- if (c) {
- c++;
- n--;
- }
- }
- if (n == 0) {
- temp = *c;
- *c = 0;
- result = NewString(start);
- Printf(result, "a(%s)", rep);
- *c = temp;
- c = strchr(c, '.');
- Append(result, c);
- }
- Clear(t);
- Append(t, result);
- Delete(result);
-}
-
-/* Return base type of an array */
-SwigType *SwigType_array_type(const SwigType *ty) {
- SwigType *t;
- t = Copy(ty);
- while (SwigType_isarray(t)) {
- Delete(SwigType_pop(t));
- }
- return t;
-}
-
-
-/* -----------------------------------------------------------------------------
- * Functions
- *
- * SwigType_add_function()
- * SwigType_isfunction()
- * SwigType_pop_function()
- *
- * Add, remove, and test for function types.
- * ----------------------------------------------------------------------------- */
-
-/* Returns the function type, t, constructed from the parameters, parms */
-SwigType *SwigType_add_function(SwigType *t, ParmList *parms) {
- String *pstr;
- Parm *p;
-
- Insert(t, 0, ").");
- pstr = NewString("f(");
- for (p = parms; p; p = nextSibling(p)) {
- if (p != parms)
- Putc(',', pstr);
- Append(pstr, Getattr(p, "type"));
- }
- Insert(t, 0, pstr);
- Delete(pstr);
- return t;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_pop_function()
- *
- * Pop and return the function from the input type leaving the function's return
- * type, if any.
- * For example:
- * t in: q(const).f().p.
- * t out: p.
- * result: q(const).f().
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_pop_function(SwigType *t) {
- SwigType *f = 0;
- SwigType *g = 0;
- char *c = Char(t);
- if (strncmp(c, "r.", 2) == 0 || strncmp(c, "z.", 2) == 0) {
- /* Remove ref-qualifier */
- f = SwigType_pop(t);
- c = Char(t);
- }
- if (strncmp(c, "q(", 2) == 0) {
- /* Remove cv-qualifier */
- String *qual = SwigType_pop(t);
- if (f) {
- SwigType_push(qual, f);
- Delete(f);
- }
- f = qual;
- c = Char(t);
- }
- if (strncmp(c, "f(", 2)) {
- fprintf(stderr, "Fatal error. SwigType_pop_function applied to non-function.\n");
- Exit(EXIT_FAILURE);
- }
- g = SwigType_pop(t);
- if (f)
- SwigType_push(g, f);
- Delete(f);
- return g;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_pop_function_qualifiers()
- *
- * Pop and return the function qualifiers from the input type leaving the rest of
- * function declaration. Returns NULL if no qualifiers.
- * For example:
- * t in: r.q(const).f().p.
- * t out: f().p.
- * result: r.q(const)
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_pop_function_qualifiers(SwigType *t) {
- SwigType *qualifiers = 0;
- char *c = Char(t);
- if (strncmp(c, "r.", 2) == 0 || strncmp(c, "z.", 2) == 0) {
- /* Remove ref-qualifier */
- String *qual = SwigType_pop(t);
- qualifiers = qual;
- c = Char(t);
- }
- if (strncmp(c, "q(", 2) == 0) {
- /* Remove cv-qualifier */
- String *qual = SwigType_pop(t);
- if (qualifiers) {
- SwigType_push(qual, qualifiers);
- Delete(qualifiers);
- }
- qualifiers = qual;
- }
- assert(Strncmp(t, "f(", 2) == 0);
-
- return qualifiers;
-}
-
-int SwigType_isfunction(const SwigType *t) {
- char *c;
- if (!t) {
- return 0;
- }
- c = Char(t);
- if (strncmp(c, "r.", 2) == 0 || strncmp(c, "z.", 2) == 0) {
- /* Might be a function with a ref-qualifier, skip over */
- c += 2;
- if (!*c)
- return 0;
- }
- if (strncmp(c, "q(", 2) == 0) {
- /* Might be a function with a cv-qualifier, skip over */
- c = strchr(c, '.');
- if (c)
- c++;
- else
- return 0;
- }
- if (strncmp(c, "f(", 2) == 0) {
- return 1;
- }
- return 0;
-}
-
-/* Create a list of parameters from the type t, using the file_line_node Node for
- * file and line numbering for the parameters */
-ParmList *SwigType_function_parms(const SwigType *t, Node *file_line_node) {
- List *l = SwigType_parmlist(t);
- Hash *p, *pp = 0, *firstp = 0;
- Iterator o;
-
- for (o = First(l); o.item; o = Next(o)) {
- p = file_line_node ? NewParm(o.item, 0, file_line_node) : NewParmWithoutFileLineInfo(o.item, 0);
- if (!firstp)
- firstp = p;
- if (pp) {
- set_nextSibling(pp, p);
- Delete(p);
- }
- pp = p;
- }
- Delete(l);
- return firstp;
-}
-
-int SwigType_isvarargs(const SwigType *t) {
- if (Strcmp(t, "v(...)") == 0)
- return 1;
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Templates
- *
- * SwigType_add_template()
- *
- * Template handling.
- * ----------------------------------------------------------------------------- */
-
-/* -----------------------------------------------------------------------------
- * SwigType_add_template()
- *
- * Adds a template to a type. This template is encoded in the SWIG type
- * mechanism and produces a string like this:
- *
- * vector<int *> ----> "vector<(p.int)>"
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_add_template(SwigType *t, ParmList *parms) {
- Parm *p;
-
- Append(t, "<(");
- for (p = parms; p; p = nextSibling(p)) {
- String *v;
- if (Getattr(p, "default"))
- continue;
- if (p != parms)
- Append(t, ",");
- v = Getattr(p, "value");
- if (v) {
- Append(t, v);
- } else {
- Append(t, Getattr(p, "type"));
- }
- }
- Append(t, ")>");
- return t;
-}
-
-
-/* -----------------------------------------------------------------------------
- * SwigType_templateprefix()
- *
- * Returns the prefix before the first template definition.
- * Returns the type unmodified if not a template.
- * For example:
- *
- * Foo<(p.int)>::bar => Foo
- * r.q(const).Foo<(p.int)>::bar => r.q(const).Foo
- * Foo => Foo
- * ----------------------------------------------------------------------------- */
-
-String *SwigType_templateprefix(const SwigType *t) {
- const char *s = Char(t);
- const char *c = strstr(s, "<(");
- return c ? NewStringWithSize(s, (int)(c - s)) : NewString(s);
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_templatesuffix()
- *
- * Returns text after a template substitution. Used to handle scope names
- * for example:
- *
- * Foo<(p.int)>::bar
- *
- * returns "::bar"
- * ----------------------------------------------------------------------------- */
-
-String *SwigType_templatesuffix(const SwigType *t) {
- const char *c;
- c = Char(t);
- while (*c) {
- if ((*c == '<') && (*(c + 1) == '(')) {
- int nest = 1;
- c++;
- while (*c && nest) {
- if (*c == '<')
- nest++;
- if (*c == '>')
- nest--;
- c++;
- }
- return NewString(c);
- }
- c++;
- }
- return NewStringEmpty();
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_istemplate_templateprefix()
- *
- * Combines SwigType_istemplate and SwigType_templateprefix efficiently into one function.
- * Returns the prefix before the first template definition.
- * Returns NULL if not a template.
- * For example:
- *
- * Foo<(p.int)>::bar => Foo
- * r.q(const).Foo<(p.int)>::bar => r.q(const).Foo
- * Foo => NULL
- * ----------------------------------------------------------------------------- */
-
-String *SwigType_istemplate_templateprefix(const SwigType *t) {
- const char *s = Char(t);
- const char *c = strstr(s, "<(");
- return c ? NewStringWithSize(s, (int)(c - s)) : 0;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_istemplate_only_templateprefix()
- *
- * Similar to SwigType_istemplate_templateprefix() but only returns the template
- * prefix if the type is just the template and not a subtype/symbol within the template.
- * Returns NULL if not a template or is a template with a symbol within the template.
- * For example:
- *
- * Foo<(p.int)> => Foo
- * Foo<(p.int)>::bar => NULL
- * r.q(const).Foo<(p.int)> => r.q(const).Foo
- * r.q(const).Foo<(p.int)>::bar => NULL
- * Foo => NULL
- * ----------------------------------------------------------------------------- */
-
-String *SwigType_istemplate_only_templateprefix(const SwigType *t) {
- int len = Len(t);
- const char *s = Char(t);
- if (len >= 4 && strcmp(s + len - 2, ")>") == 0) {
- const char *c = strstr(s, "<(");
- return c ? NewStringWithSize(s, (int)(c - s)) : 0;
- } else {
- return 0;
- }
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_templateargs()
- *
- * Returns the template arguments
- * For example:
- *
- * Foo<(p.int)>::bar
- *
- * returns "<(p.int)>"
- * ----------------------------------------------------------------------------- */
-
-String *SwigType_templateargs(const SwigType *t) {
- const char *c;
- const char *start;
- c = Char(t);
- while (*c) {
- if ((*c == '<') && (*(c + 1) == '(')) {
- int nest = 1;
- start = c;
- c++;
- while (*c && nest) {
- if (*c == '<')
- nest++;
- if (*c == '>')
- nest--;
- c++;
- }
- return NewStringWithSize(start, (int)(c - start));
- }
- c++;
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_istemplate()
- *
- * Tests a type to see if it includes template parameters
- * ----------------------------------------------------------------------------- */
-
-int SwigType_istemplate(const SwigType *t) {
- char *ct = Char(t);
- ct = strstr(ct, "<(");
- if (ct && (strstr(ct + 2, ")>")))
- return 1;
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_base()
- *
- * This function returns the base of a type. For example, if you have a
- * type "p.p.int", the function would return "int".
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_base(const SwigType *t) {
- char *c;
- char *lastop = 0;
- c = Char(t);
-
- lastop = c;
-
- /* Search for the last type constructor separator '.' */
- while (*c) {
- if (*c == '.') {
- if (*(c + 1)) {
- lastop = c + 1;
- }
- c++;
- continue;
- }
- if (*c == '<') {
- /* Skip over template---it's part of the base name */
- int ntemp = 1;
- c++;
- while ((*c) && (ntemp > 0)) {
- if (*c == '>')
- ntemp--;
- else if (*c == '<')
- ntemp++;
- c++;
- }
- if (ntemp)
- break;
- continue;
- }
- if (*c == '(') {
- /* Skip over params */
- int nparen = 1;
- c++;
- while ((*c) && (nparen > 0)) {
- if (*c == '(')
- nparen++;
- else if (*c == ')')
- nparen--;
- c++;
- }
- if (nparen)
- break;
- continue;
- }
- c++;
- }
- return NewString(lastop);
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_prefix()
- *
- * Returns the prefix of a datatype. For example, the prefix of the
- * type "p.p.int" is "p.p.".
- * ----------------------------------------------------------------------------- */
-
-String *SwigType_prefix(const SwigType *t) {
- char *c, *d;
- String *r = 0;
-
- c = Char(t);
- d = c + strlen(c);
-
- /* Check for a type constructor */
- if ((d > c) && (*(d - 1) == '.'))
- d--;
-
- while (d > c) {
- d--;
- if (*d == '>') {
- int nest = 1;
- d--;
- while ((d > c) && (nest)) {
- if (*d == '>')
- nest++;
- if (*d == '<')
- nest--;
- d--;
- }
- }
- if (*d == ')') {
- /* Skip over params */
- int nparen = 1;
- d--;
- while ((d > c) && (nparen)) {
- if (*d == ')')
- nparen++;
- if (*d == '(')
- nparen--;
- d--;
- }
- }
-
- if (*d == '.') {
- char t = *(d + 1);
- *(d + 1) = 0;
- r = NewString(c);
- *(d + 1) = t;
- return r;
- }
- }
- return NewStringEmpty();
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_strip_qualifiers()
- *
- * Strip all qualifiers from a type and return a new type
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_strip_qualifiers(const SwigType *t) {
- static Hash *memoize_stripped = 0;
- SwigType *r;
- List *l;
- Iterator ei;
-
- if (!memoize_stripped)
- memoize_stripped = NewHash();
- r = Getattr(memoize_stripped, t);
- if (r)
- return Copy(r);
-
- l = SwigType_split(t);
- r = NewStringEmpty();
-
- for (ei = First(l); ei.item; ei = Next(ei)) {
- if (SwigType_isqualifier(ei.item))
- continue;
- Append(r, ei.item);
- }
- Delete(l);
- {
- String *key, *value;
- key = Copy(t);
- value = Copy(r);
- Setattr(memoize_stripped, key, value);
- Delete(key);
- Delete(value);
- }
- return r;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_strip_single_qualifier()
- *
- * If the type contains a qualifier, strip one qualifier and return a new type.
- * The left most qualifier is stripped first (when viewed as C source code) but
- * this is the equivalent to the right most qualifier using SwigType notation.
- * Example:
- * r.q(const).p.q(const).int => r.q(const).p.int
- * r.q(const).p.int => r.p.int
- * r.p.int => r.p.int
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_strip_single_qualifier(const SwigType *t) {
- static Hash *memoize_stripped = 0;
- SwigType *r = 0;
- List *l;
- int numitems;
-
- if (!memoize_stripped)
- memoize_stripped = NewHash();
- r = Getattr(memoize_stripped, t);
- if (r)
- return Copy(r);
-
- l = SwigType_split(t);
-
- numitems = Len(l);
- if (numitems >= 2) {
- int item;
- /* iterate backwards from last but one item */
- for (item = numitems - 2; item >= 0; --item) {
- String *subtype = Getitem(l, item);
- if (SwigType_isqualifier(subtype)) {
- Iterator it;
- Delitem(l, item);
- r = NewStringEmpty();
- for (it = First(l); it.item; it = Next(it)) {
- Append(r, it.item);
- }
- break;
- }
- }
- }
- if (!r)
- r = Copy(t);
-
- Delete(l);
- {
- String *key, *value;
- key = Copy(t);
- value = Copy(r);
- Setattr(memoize_stripped, key, value);
- Delete(key);
- Delete(value);
- }
- return r;
-}
-
diff --git a/contrib/tools/swig/Source/Swig/typesys.c b/contrib/tools/swig/Source/Swig/typesys.c
deleted file mode 100644
index 4a11790c72..0000000000
--- a/contrib/tools/swig/Source/Swig/typesys.c
+++ /dev/null
@@ -1,2309 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * typesys.c
- *
- * SWIG type system management. These functions are used to manage
- * the C++ type system including typenames, typedef, type scopes,
- * inheritance, and namespaces. Generation of support code for the
- * run-time type checker is also handled here.
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-#include "cparse.h"
-
-/* -----------------------------------------------------------------------------
- * Synopsis
- *
- * The purpose of this module is to manage type names and scoping issues related
- * to the C++ type system. The primary use is tracking typenames through typedef
- * and inheritance.
- *
- * New typenames are introduced by typedef, class, and enum declarations.
- * Each type is declared in a scope. This is either the global scope, a
- * class, or a namespace. For example:
- *
- * typedef int A; // Typename A, in global scope
- * namespace Foo {
- * typedef int A; // Typename A, in scope Foo::
- * }
- * class Bar { // Typename Bar, in global scope
- * typedef int A; // Typename A, in scope Bar::
- * }
- *
- * To manage scopes, the type system is constructed as a tree of hash tables. Each
- * hash table contains the following attributes:
- *
- * "name" - Scope name
- * "qname" - Fully qualified typename
- * "typetab" - Type table containing typenames and typedef information
- * For a given key in the typetab table, the value is a fully
- * qualified name if not pointing to itself.
- * "symtab" - Hash table of symbols defined in a scope
- * "inherit" - List of inherited scopes
- * "parent" - Parent scope
- *
- * The contents of these tables can be viewed for debugging using the -debug-typedef
- * option which calls SwigType_print_scope().
- *
- * Typedef information is stored in the "typetab" hash table. For example,
- * if you have these declarations:
- *
- * typedef int A;
- * typedef A B;
- * typedef B *C;
- *
- * typetab in scope '' contains:
- * "A" : "int"
- * "B" : "A"
- * "C" : "p.B"
- *
- * To resolve a type back to its root type, one repeatedly expands on the type base.
- * For example:
- *
- * C *[40] ---> a(40).p.C (string type representation, see stype.c)
- * ---> a(40).p.p.B (C --> p.B)
- * ---> a(40).p.p.A (B --> A)
- * ---> a(40).p.p.int (A --> int)
- *
- *
- * Using declarations are stored in the "typetab" hash table. For example,
- *
- * namespace NN {
- * struct SS {};
- * }
- * namespace N {
- * struct S {};
- * using NN::SS;
- * }
- * using N::S;
- *
- * typetab in scope '' contains:
- * "S" : "N::S"
- *
- * and typetab in scope 'N' contains:
- * "SS" : "NN::SS"
- * "S" : "S"
- *
- *
- * For inheritance, SWIG tries to resolve types back to the base class. For instance, if
- * you have this:
- *
- * class Foo {
- * public:
- * typedef int Integer;
- * };
- * struct Bar : public Foo {
- * void blah(Integer x);
- * };
- *
- * In this case typetab in scope '' contains:
- * "Foo" : "Foo"
- * "Bar" : "Bar"
- * and scope 'Foo' contains:
- * "Integer" : "int"
- * and scope 'Bar' inherits from 'Foo' but is empty (observe that blah is not a scope or typedef)
- *
- * The argument type of Bar::blah will be set to Foo::Integer.
- *
- *
- * The scope-inheritance mechanism is used to manage C++ using directives.
- *
- * namespace XX {
- * class CC {};
- * }
- * namespace X {
- * class C {};
- * using namespace XX;
- * }
- * using namespace X;
- *
- * typetab in scope '' inherits from 'X'
- * typetab in scope 'X' inherits from 'XX' and contains:
- * "C" : "C"
- * typetab in scope 'XX' contains:
- * "CC" : "CC"
- *
- *
- * The scope-inheritance mechanism is used to manage C++ namespace aliases.
- * For example, if you have this:
- *
- * namespace Foo {
- * typedef int Integer;
- * }
- *
- * namespace F = Foo;
- *
- * In this case, F is defined as a scope that "inherits" from Foo. Internally,
- * F will merely be an empty scope that points to Foo. SWIG will never
- * place new type information into a namespace alias---attempts to do so
- * will generate a warning message (in the parser) and will place information into
- * Foo instead.
- *
- *----------------------------------------------------------------------------- */
-
-static Typetab *current_scope = 0; /* Current type scope */
-static Hash *current_typetab = 0; /* Current type table */
-static Hash *current_symtab = 0; /* Current symbol table */
-static Typetab *global_scope = 0; /* The global scope */
-static Hash *scopes = 0; /* Hash table containing fully qualified scopes */
-
-/* Performance optimization */
-#define SWIG_TYPEDEF_RESOLVE_CACHE
-static Hash *typedef_resolve_cache = 0;
-static Hash *typedef_all_cache = 0;
-static Hash *typedef_qualified_cache = 0;
-
-static Typetab *SwigType_find_scope(Typetab *s, const SwigType *nameprefix);
-
-/* common attribute keys, to avoid calling find_key all the times */
-
-/*
- Enable this one if your language fully support SwigValueWrapper<T>.
-
- Leaving at '0' keeps the old swig behavior, which is not
- always safe, but is well known.
-
- Setting at '1' activates the new scheme, which is always safe but
- it requires all the typemaps to be ready for that.
-
-*/
-static int value_wrapper_mode = 0;
-int Swig_value_wrapper_mode(int mode) {
- value_wrapper_mode = mode;
- return mode;
-}
-
-
-static void flush_cache(void) {
- typedef_resolve_cache = 0;
- typedef_all_cache = 0;
- typedef_qualified_cache = 0;
-}
-
-/* Initialize the scoping system */
-
-void SwigType_typesystem_init(void) {
- if (global_scope)
- Delete(global_scope);
- if (scopes)
- Delete(scopes);
-
- current_scope = NewHash();
- global_scope = current_scope;
-
- Setattr(current_scope, "name", ""); /* No name for global scope */
- current_typetab = NewHash();
- Setattr(current_scope, "typetab", current_typetab);
-
- current_symtab = 0;
- scopes = NewHash();
- Setattr(scopes, "", current_scope);
-}
-
-
-/* -----------------------------------------------------------------------------
- * SwigType_typedef()
- *
- * Defines a new typedef in the current scope. Returns -1 if the type name is
- * already defined.
- * ----------------------------------------------------------------------------- */
-
-int SwigType_typedef(const SwigType *type, const_String_or_char_ptr name) {
- /* Printf(stdout, "typedef %s %s\n", type, name); */
- if (Getattr(current_typetab, name))
- return -1; /* Already defined */
- if (Strcmp(type, name) == 0) { /* Can't typedef a name to itself */
- return 0;
- }
-
- /* Check if 'type' is already a scope. If so, we create an alias in the type
- system for it. This is needed to make strange nested scoping problems work
- correctly. */
- {
- Typetab *t = SwigType_find_scope(current_scope, type);
- if (t) {
- SwigType_new_scope(name);
- SwigType_inherit_scope(t);
- SwigType_pop_scope();
- }
- }
- Setattr(current_typetab, name, type);
- flush_cache();
- return 0;
-}
-
-
-/* -----------------------------------------------------------------------------
- * SwigType_typedef_class()
- *
- * Defines a class in the current scope.
- * ----------------------------------------------------------------------------- */
-
-int SwigType_typedef_class(const_String_or_char_ptr name) {
- String *cname;
- /* Printf(stdout,"class : '%s'\n", name); */
- if (Getattr(current_typetab, name))
- return -1; /* Already defined */
- cname = NewString(name);
- Setmeta(cname, "class", "1");
- Setattr(current_typetab, cname, cname);
- Delete(cname);
- flush_cache();
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_scope_name()
- *
- * Returns the qualified scope name of a type table
- * ----------------------------------------------------------------------------- */
-
-String *SwigType_scope_name(Typetab *ttab) {
- String *qname = NewString(Getattr(ttab, "name"));
- ttab = Getattr(ttab, "parent");
- while (ttab) {
- String *pname = Getattr(ttab, "name");
- if (Len(pname)) {
- Insert(qname, 0, "::");
- Insert(qname, 0, pname);
- }
- ttab = Getattr(ttab, "parent");
- }
- return qname;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_new_scope()
- *
- * Creates a new scope
- * ----------------------------------------------------------------------------- */
-
-void SwigType_new_scope(const_String_or_char_ptr name) {
- Typetab *s;
- Hash *ttab;
- String *qname;
-
- if (!name) {
- name = "<unnamed>";
- }
- s = NewHash();
- Setattr(s, "name", name);
- Setattr(s, "parent", current_scope);
- ttab = NewHash();
- Setattr(s, "typetab", ttab);
-
- /* Build fully qualified name */
- qname = SwigType_scope_name(s);
-#if 1
- {
- /* TODO: only do with templates? What happens with non-templates with code below? */
- String *stripped_qname;
- stripped_qname = SwigType_remove_global_scope_prefix(qname);
- /* Use fully qualified name for hash key without unary scope prefix, qname may contain unary scope */
- Setattr(scopes, stripped_qname, s);
- Setattr(s, "qname", qname);
- /*
- Printf(stdout, "SwigType_new_scope stripped %s %s\n", qname, stripped_qname);
- */
- Delete(stripped_qname);
- }
-#else
- Printf(stdout, "SwigType_new_scope %s\n", qname);
- Setattr(scopes, qname, s);
- Setattr(s, "qname", qname);
-#endif
- Delete(qname);
-
- current_scope = s;
- current_typetab = ttab;
- current_symtab = 0;
- flush_cache();
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_inherit_scope()
- *
- * Makes the current scope inherit from another scope. This is used for both
- * C++ class inheritance, namespaces, and namespace aliases.
- * ----------------------------------------------------------------------------- */
-
-void SwigType_inherit_scope(Typetab *scope) {
- List *inherits;
- int i, len;
- inherits = Getattr(current_scope, "inherit");
- if (!inherits) {
- inherits = NewList();
- Setattr(current_scope, "inherit", inherits);
- Delete(inherits);
- }
- assert(scope != current_scope);
-
- len = Len(inherits);
- for (i = 0; i < len; i++) {
- Node *n = Getitem(inherits, i);
- if (n == scope)
- return;
- }
- Append(inherits, scope);
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_scope_alias()
- *
- * Creates a scope-alias.
- * ----------------------------------------------------------------------------- */
-
-void SwigType_scope_alias(String *aliasname, Typetab *ttab) {
- String *q;
- /* Printf(stdout,"alias: '%s' '%p'\n", aliasname, ttab); */
- q = SwigType_scope_name(current_scope);
- if (Len(q)) {
- Append(q, "::");
- }
- Append(q, aliasname);
- Setattr(scopes, q, ttab);
- flush_cache();
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_using_scope()
- *
- * Import another scope into this scope.
- * ----------------------------------------------------------------------------- */
-
-void SwigType_using_scope(Typetab *scope) {
- SwigType_inherit_scope(scope);
- {
- List *ulist;
- int i, len;
- ulist = Getattr(current_scope, "using");
- if (!ulist) {
- ulist = NewList();
- Setattr(current_scope, "using", ulist);
- Delete(ulist);
- }
- assert(scope != current_scope);
- len = Len(ulist);
- for (i = 0; i < len; i++) {
- Typetab *n = Getitem(ulist, i);
- if (n == scope)
- return;
- }
- Append(ulist, scope);
- }
- flush_cache();
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_pop_scope()
- *
- * Pop off the last scope and perform a merge operation. Returns the hash
- * table for the scope that was popped off.
- * ----------------------------------------------------------------------------- */
-
-Typetab *SwigType_pop_scope(void) {
- Typetab *t, *old = current_scope;
- t = Getattr(current_scope, "parent");
- if (!t)
- t = global_scope;
- current_scope = t;
- current_typetab = Getattr(t, "typetab");
- current_symtab = Getattr(t, "symtab");
- flush_cache();
- return old;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_set_scope()
- *
- * Set the scope. Returns the old scope.
- * ----------------------------------------------------------------------------- */
-
-Typetab *SwigType_set_scope(Typetab *t) {
- Typetab *old = current_scope;
- if (!t)
- t = global_scope;
- current_scope = t;
- current_typetab = Getattr(t, "typetab");
- current_symtab = Getattr(t, "symtab");
- flush_cache();
- return old;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_attach_symtab()
- *
- * Attaches a symbol table to a type scope
- * ----------------------------------------------------------------------------- */
-
-void SwigType_attach_symtab(Symtab *sym) {
- Setattr(current_scope, "symtab", sym);
- current_symtab = sym;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_print_scope()
- *
- * Debugging function for printing out current scope
- * ----------------------------------------------------------------------------- */
-
-void SwigType_print_scope(void) {
- Hash *ttab;
- Iterator i, j;
-
- Printf(stdout, "SCOPES start =======================================\n");
- for (i = First(scopes); i.key; i = Next(i)) {
- Printf(stdout, "-------------------------------------------------------------\n");
- ttab = Getattr(i.item, "typetab");
-
- Printf(stdout, "Type scope '%s' (%p)\n", i.key, i.item);
- {
- List *inherit = Getattr(i.item, "inherit");
- if (inherit) {
- Iterator j;
- for (j = First(inherit); j.item; j = Next(j)) {
- Printf(stdout, " Inherits from '%s' (%p)\n", Getattr(j.item, "qname"), j.item);
- }
- }
- }
- for (j = First(ttab); j.key; j = Next(j)) {
- Printf(stdout, "%40s -> %s\n", j.key, j.item);
- }
- }
- Printf(stdout, "SCOPES finish =======================================\n");
-}
-
-static Typetab *SwigType_find_scope(Typetab *s, const SwigType *nameprefix) {
- Typetab *ss;
- Typetab *s_orig = s;
- String *nnameprefix = 0;
- static int check_parent = 1;
- int is_template = 0;
-
- if (Getmark(s))
- return 0;
- Setmark(s, 1);
-
- is_template = SwigType_istemplate(nameprefix);
- if (is_template) {
- nnameprefix = SwigType_typedef_resolve_all(nameprefix);
- nameprefix = nnameprefix;
- }
-
- ss = s;
- while (ss) {
- String *full;
- String *qname = Getattr(ss, "qname");
- if (qname) {
- full = NewStringf("%s::%s", qname, nameprefix);
- } else {
- full = NewString(nameprefix);
- }
- s = Getattr(scopes, full);
- if (!s && is_template) {
- /* try look up scope with all the unary scope operators within the template parameter list removed */
- SwigType *full_stripped = SwigType_remove_global_scope_prefix(full);
- s = Getattr(scopes, full_stripped);
- Delete(full_stripped);
- }
- Delete(full);
- if (s) {
- if (nnameprefix)
- Delete(nnameprefix);
- Setmark(s_orig, 0);
- return s;
- }
- if (!s) {
- /* Check inheritance */
- List *inherit;
- inherit = Getattr(ss, "using");
- if (inherit) {
- Typetab *ttab;
- int i, len;
- len = Len(inherit);
- for (i = 0; i < len; i++) {
- int oldcp = check_parent;
- ttab = Getitem(inherit, i);
- check_parent = 0;
- s = SwigType_find_scope(ttab, nameprefix);
- check_parent = oldcp;
- if (s) {
- if (nnameprefix)
- Delete(nnameprefix);
- Setmark(s_orig, 0);
- return s;
- }
- }
- }
- }
- if (!check_parent)
- break;
- ss = Getattr(ss, "parent");
- }
- if (nnameprefix)
- Delete(nnameprefix);
- Setmark(s_orig, 0);
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * typedef_resolve()
- *
- * Resolves a typedef and returns a new type string. Returns 0 if there is no
- * typedef mapping. base is a name without qualification.
- * Internal function.
- * ----------------------------------------------------------------------------- */
-
-static Typetab *resolved_scope = 0;
-
-/* Internal function */
-
-static SwigType *_typedef_resolve(Typetab *s, String *base, int look_parent) {
- Hash *ttab;
- SwigType *type = 0;
- List *inherit;
- Typetab *parent;
-
- /* if (!s) return 0; *//* now is checked below */
- /* Printf(stdout,"Typetab %s : %s\n", Getattr(s,"name"), base); */
-
- if (!Getmark(s)) {
- Setmark(s, 1);
-
- ttab = Getattr(s, "typetab");
- type = Getattr(ttab, base);
- if (type) {
- resolved_scope = s;
- Setmark(s, 0);
- } else {
- /* Hmmm. Not found in my scope. It could be in an inherited scope */
- inherit = Getattr(s, "inherit");
- if (inherit) {
- int i, len;
- len = Len(inherit);
- for (i = 0; i < len; i++) {
- type = _typedef_resolve(Getitem(inherit, i), base, 0);
- if (type) {
- Setmark(s, 0);
- break;
- }
- }
- }
- if (!type) {
- /* Hmmm. Not found in my scope. check parent */
- if (look_parent) {
- parent = Getattr(s, "parent");
- type = parent ? _typedef_resolve(parent, base, 1) : 0;
- }
- }
- Setmark(s, 0);
- }
- }
- return type;
-}
-
-/* -----------------------------------------------------------------------------
- * template_parameters_resolve()
- *
- * For use with templates only. Attempts to resolve one template parameter.
- *
- * If one of the template parameters can be resolved, the type is returned with
- * just the one parameter resolved and the remaining parameters left as is.
- * If none of the template parameters can be resolved, zero is returned.
- * ----------------------------------------------------------------------------- */
-
-static String *template_parameters_resolve(const String *base) {
- List *tparms;
- String *suffix;
- String *type;
- int i, sz;
- int rep = 0;
- type = SwigType_templateprefix(base);
- suffix = SwigType_templatesuffix(base);
- Append(type, "<(");
- tparms = SwigType_parmlist(base);
- sz = Len(tparms);
- for (i = 0; i < sz; i++) {
- SwigType *tpr;
- SwigType *tp = Getitem(tparms, i);
- if (!rep) {
- tpr = SwigType_typedef_resolve(tp);
- } else {
- tpr = 0;
- }
- if (tpr) {
- Append(type, tpr);
- Delete(tpr);
- rep = 1;
- } else {
- Append(type, tp);
- }
- if ((i + 1) < sz)
- Append(type, ",");
- }
- if (rep) {
- Append(type, ")>");
- Append(type, suffix);
- } else {
- Delete(type);
- type = 0;
- }
- Delete(suffix);
- Delete(tparms);
- return type;
-}
-
-static SwigType *typedef_resolve(Typetab *s, String *base) {
- return _typedef_resolve(s, base, 1);
-}
-
-
-/* -----------------------------------------------------------------------------
- * SwigType_typedef_resolve()
- *
- * Given a type declaration, this function looks to reduce/resolve the type via a
- * typedef (including via C++ using declarations).
- *
- * If it is able to find a typedef, the resolved type is returned. If no typedef
- * is found NULL is returned. The type name is resolved in the current scope.
- * The type returned is not always fully qualified for the global scope, it is
- * valid for use in the current scope. If the current scope is global scope, a
- * fully qualified type should be returned.
- *
- * Some additional notes are in Doc/Manual/Extending.html.
- * ----------------------------------------------------------------------------- */
-
-/* #define SWIG_DEBUG */
-SwigType *SwigType_typedef_resolve(const SwigType *t) {
- String *base;
- String *type = 0;
- String *r = 0;
- Typetab *s;
- Hash *ttab;
- String *namebase = 0;
- String *nameprefix = 0, *rnameprefix = 0;
- int newtype = 0;
-
- resolved_scope = 0;
-
-#ifdef SWIG_TYPEDEF_RESOLVE_CACHE
- if (!typedef_resolve_cache) {
- typedef_resolve_cache = NewHash();
- }
- r = Getattr(typedef_resolve_cache, t);
- if (r) {
- resolved_scope = Getmeta(r, "scope");
- return Copy(r);
- }
-#endif
-
- base = SwigType_base(t);
-
-#ifdef SWIG_DEBUG
- Printf(stdout, "base = '%s' t='%s'\n", base, t);
-#endif
-
- if (SwigType_issimple(base)) {
- s = current_scope;
- ttab = current_typetab;
- if (strncmp(Char(base), "::", 2) == 0) {
- s = global_scope;
- ttab = Getattr(s, "typetab");
- Delitem(base, 0);
- Delitem(base, 0);
- }
- /* Do a quick check in the local scope */
- type = Getattr(ttab, base);
- if (type) {
- resolved_scope = s;
- }
- if (!type) {
- /* Didn't find in this scope. We need to do a little more searching */
- if (Swig_scopename_check(base)) {
- /* A qualified name. */
- Swig_scopename_split(base, &nameprefix, &namebase);
-#ifdef SWIG_DEBUG
- Printf(stdout, "nameprefix = '%s'\n", nameprefix);
-#endif
- if (nameprefix) {
- rnameprefix = SwigType_typedef_resolve(nameprefix);
- if(rnameprefix != NULL) {
-#ifdef SWIG_DEBUG
- Printf(stdout, "nameprefix '%s' is a typedef to '%s'\n", nameprefix, rnameprefix);
-#endif
- type = Copy(namebase);
- Insert(type, 0, "::");
- Insert(type, 0, rnameprefix);
- if (strncmp(Char(type), "::", 2) == 0) {
- Delitem(type, 0);
- Delitem(type, 0);
- }
- newtype = 1;
- } else {
- /* Name had a prefix on it. See if we can locate the proper scope for it */
- String *rnameprefix = template_parameters_resolve(nameprefix);
- nameprefix = rnameprefix ? Copy(rnameprefix) : nameprefix;
- Delete(rnameprefix);
- s = SwigType_find_scope(s, nameprefix);
-
- /* Couldn't locate a scope for the type. */
- if (!s) {
- Delete(base);
- Delete(namebase);
- Delete(nameprefix);
- r = 0;
- goto return_result;
- }
- /* Try to locate the name starting in the scope */
-#ifdef SWIG_DEBUG
- Printf(stdout, "namebase = '%s'\n", namebase);
-#endif
- type = typedef_resolve(s, namebase);
- if (type && resolved_scope) {
- /* we need to look for the resolved type, this will also
- fix the resolved_scope if 'type' and 'namebase' are
- declared in different scopes */
- String *rtype = 0;
- rtype = typedef_resolve(resolved_scope, type);
- if (rtype)
- type = rtype;
- }
-#ifdef SWIG_DEBUG
- Printf(stdout, "%s type = '%s'\n", Getattr(s, "name"), type);
-#endif
- if ((type) && (!Swig_scopename_check(type)) && resolved_scope) {
- Typetab *rtab = resolved_scope;
- String *qname = Getattr(resolved_scope, "qname");
- /* If qualified *and* the typename is defined from the resolved scope, we qualify */
- if ((qname) && typedef_resolve(resolved_scope, type)) {
- type = Copy(type);
- Insert(type, 0, "::");
- Insert(type, 0, qname);
-#ifdef SWIG_DEBUG
- Printf(stdout, "qual %s \n", type);
-#endif
- newtype = 1;
- }
- resolved_scope = rtab;
- }
- }
- } else {
- /* Name is unqualified. */
- type = typedef_resolve(s, base);
- }
- } else {
- /* Name is unqualified. */
- type = typedef_resolve(s, base);
- }
- }
-
- if (!type && SwigType_istemplate(base)) {
- String *tprefix = SwigType_templateprefix(base);
- String *rtprefix = SwigType_typedef_resolve(tprefix);
- /* We're looking for a using declaration on the template prefix to resolve the template prefix
- * in another scope. Using declaration do not have template parameters. */
- if (rtprefix && !SwigType_istemplate(rtprefix)) {
- String *tsuffix = SwigType_templatesuffix(base);
- String *targs = SwigType_templateargs(base);
- type = NewString(rtprefix);
- newtype = 1;
- Append(type, targs);
- Append(type, tsuffix);
- Delete(targs);
- Delete(tsuffix);
- Delete(rtprefix);
- }
- Delete(tprefix);
- }
-
- if (type && (Equal(base, type))) {
- if (newtype)
- Delete(type);
- Delete(base);
- Delete(namebase);
- Delete(nameprefix);
- r = 0;
- goto return_result;
- }
-
- /* If the type is a template, and no typedef was found, we need to check the
- template arguments one by one to see if they can be resolved. */
-
- if (!type && SwigType_istemplate(base)) {
- newtype = 1;
- type = template_parameters_resolve(base);
- }
- Delete(namebase);
- Delete(nameprefix);
- } else {
- if (SwigType_isfunction(base)) {
- List *parms;
- int i, sz;
- int rep = 0;
- type = NewString("f(");
- newtype = 1;
- parms = SwigType_parmlist(base);
- sz = Len(parms);
- for (i = 0; i < sz; i++) {
- SwigType *tpr;
- SwigType *tp = Getitem(parms, i);
- if (!rep) {
- tpr = SwigType_typedef_resolve(tp);
- } else {
- tpr = 0;
- }
- if (tpr) {
- Append(type, tpr);
- Delete(tpr);
- rep = 1;
- } else {
- Append(type, tp);
- }
- if ((i + 1) < sz)
- Append(type, ",");
- }
- Append(type, ").");
- Delete(parms);
- if (!rep) {
- Delete(type);
- type = 0;
- }
- } else if (SwigType_ismemberpointer(base)) {
- String *rt;
- String *mtype = SwigType_parm(base);
- rt = SwigType_typedef_resolve(mtype);
- if (rt) {
- type = NewStringf("m(%s).", rt);
- newtype = 1;
- Delete(rt);
- }
- Delete(mtype);
- } else {
- type = 0;
- }
- }
- r = SwigType_prefix(t);
- if (!type) {
- if (r && Len(r)) {
- char *cr = Char(r);
- if ((strstr(cr, "f(") || (strstr(cr, "m(")))) {
- SwigType *rt = SwigType_typedef_resolve(r);
- if (rt) {
- Delete(r);
- Append(rt, base);
- Delete(base);
- r = rt;
- goto return_result;
- }
- }
- }
- Delete(r);
- Delete(base);
- r = 0;
- goto return_result;
- }
- Delete(base);
-
- /* If 'type' is an array, then the right-most qualifier in 'r' should
- be added to 'type' after the array qualifier, so that given
- a(7).q(volatile).double myarray // typedef volatile double[7] myarray;
- the type
- q(const).myarray // const myarray
- becomes
- a(7).q(const volatile).double // const volatile double[7]
- and NOT
- q(const).a(7).q(volatile).double // non-sensical type
- */
- if (r && Len(r) && SwigType_isarray(type)) {
- List *r_elem;
- String *r_qual;
- int r_sz;
- r_elem = SwigType_split(r);
- r_sz = Len(r_elem);
- r_qual = Getitem(r_elem, r_sz-1);
- if (SwigType_isqualifier(r_qual)) {
- String *new_r;
- String *new_type;
- List *type_elem;
- String *type_qual;
- String *r_qual_arg;
- int i, type_sz;
-
- type_elem = SwigType_split(type);
- type_sz = Len(type_elem);
-
- for (i = 0; i < type_sz; ++i) {
- String *e = Getitem(type_elem, i);
- if (!SwigType_isarray(e))
- break;
- }
- type_qual = Copy(Getitem(type_elem, i));
- r_qual_arg = SwigType_parm(r_qual);
- SwigType_add_qualifier(type_qual, r_qual_arg);
- Delete(r_qual_arg);
- Setitem(type_elem, i, type_qual);
-
- new_r = NewStringEmpty();
- for (i = 0; i < r_sz-1; ++i) {
- Append(new_r, Getitem(r_elem, i));
- }
- new_type = NewStringEmpty();
- for (i = 0; i < type_sz; ++i) {
- Append(new_type, Getitem(type_elem, i));
- }
-#ifdef SWIG_DEBUG
- Printf(stdout, "r+type='%s%s' new_r+new_type='%s%s'\n", r, type, new_r, new_type);
-#endif
-
- Delete(r);
- r = new_r;
- newtype = 1;
- type = new_type;
- Delete(type_elem);
- }
- Delete(r_elem);
- }
-
- Append(r, type);
- if (newtype) {
- Delete(type);
- }
-
-return_result:
-#ifdef SWIG_TYPEDEF_RESOLVE_CACHE
- {
- String *key = NewString(t);
- if (r) {
- SwigType *r1;
- Setattr(typedef_resolve_cache, key, r);
- Setmeta(r, "scope", resolved_scope);
- r1 = Copy(r);
- Delete(r);
- r = r1;
- }
- Delete(key);
- }
-#endif
- return r;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_typedef_resolve_all()
- *
- * Fully resolve a type down to its most basic datatype
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_typedef_resolve_all(const SwigType *t) {
- SwigType *n;
- SwigType *r;
- int count = 0;
-
- /* Check to see if the typedef resolve has been done before by checking the cache */
- if (!typedef_all_cache) {
- typedef_all_cache = NewHash();
- }
- r = Getattr(typedef_all_cache, t);
- if (r) {
- return Copy(r);
- }
-
-#ifdef SWIG_DEBUG
- Printf(stdout, "SwigType_typedef_resolve_all start ... %s\n", t);
-#endif
- /* Recursively resolve the typedef */
- r = NewString(t);
- while ((n = SwigType_typedef_resolve(r))) {
- Delete(r);
- r = n;
- if (++count >= 512) {
- Swig_error(Getfile(t), Getline(t), "Recursive typedef detected resolving '%s' to '%s' to '%s' and so on...\n", SwigType_str(t, 0), SwigType_str(SwigType_typedef_resolve(t), 0), SwigType_str(SwigType_typedef_resolve(SwigType_typedef_resolve(t)), 0));
- break;
- }
- }
-
- /* Add the typedef to the cache for next time it is looked up */
- {
- String *key;
- SwigType *rr = Copy(r);
- key = NewString(t);
- Setattr(typedef_all_cache, key, rr);
- Delete(key);
- Delete(rr);
- }
-#ifdef SWIG_DEBUG
- Printf(stdout, "SwigType_typedef_resolve_all end === %s => %s\n", t, r);
-#endif
- return r;
-}
-
-
-/* -----------------------------------------------------------------------------
- * SwigType_typedef_qualified()
- *
- * Given a type declaration, this function tries to fully qualify it so that the
- * resulting type can be used in the global scope. The type name is resolved in
- * the current scope.
- *
- * It provides a fully qualified name, not necessarily a fully expanded name.
- * When a using declaration or using directive is found the type may not be fully
- * expanded, but it will be resolved and fully qualified for use in the global scope.
- *
- * This function is for looking up scopes to qualify a type. It does not resolve
- * C typedefs, it just qualifies them. See SwigType_typedef_resolve for resolving.
- *
- * If the unary scope operator (::) is used as a prefix to the type to denote global
- * scope, it is left in place.
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_typedef_qualified(const SwigType *t) {
- List *elements;
- String *result;
- int i, len;
-
- if (!typedef_qualified_cache)
- typedef_qualified_cache = NewHash();
- result = Getattr(typedef_qualified_cache, t);
- if (result) {
- String *rc = Copy(result);
- return rc;
- }
-
- result = NewStringEmpty();
- elements = SwigType_split(t);
- len = Len(elements);
- for (i = 0; i < len; i++) {
- String *ty = 0;
- String *e = Getitem(elements, i);
- if (SwigType_issimple(e)) {
- if (!SwigType_istemplate(e)) {
- String *isenum = 0;
- if (SwigType_isenum(e)) {
- isenum = NewString("enum ");
- ty = NewString(Char(e) + 5);
- e = ty;
- }
- resolved_scope = 0;
- if (typedef_resolve(current_scope, e) && resolved_scope) {
- /* resolved_scope contains the scope that actually resolved the symbol */
- String *qname = Getattr(resolved_scope, "qname");
- if (qname) {
- Insert(e, 0, "::");
- Insert(e, 0, qname);
- }
- } else {
- if (Swig_scopename_check(e)) {
- String *qlast;
- String *qname;
- Swig_scopename_split(e, &qname, &qlast);
- if (qname) {
- String *tqname = SwigType_typedef_qualified(qname);
- Clear(e);
- Printf(e, "%s::%s", tqname, qlast);
- Delete(qname);
- Delete(tqname);
- }
- Delete(qlast);
-
- /* Automatic template instantiation might go here??? */
- } else {
- /* It's a bare name. It's entirely possible, that the
- name is part of a namespace. We'll check this by unrolling
- out of the current scope */
-
- Typetab *cs = current_scope;
- if (cs) {
- Typetab *found_scope = SwigType_find_scope(cs, e);
- if (found_scope) {
- String *qs = SwigType_scope_name(found_scope);
- Clear(e);
- Append(e, qs);
- Delete(qs);
- }
- }
- }
- }
- if (isenum) {
- Insert(e, 0, isenum);
- Delete(isenum);
- }
- } else {
- /* Template. We need to qualify template parameters as well as the template itself */
- String *tprefix, *qprefix;
- String *tsuffix;
- Iterator pi;
- Parm *p;
- List *parms;
- ty = Swig_symbol_template_deftype(e, current_symtab);
- e = ty;
- parms = SwigType_parmlist(e);
- tprefix = SwigType_templateprefix(e);
- tsuffix = SwigType_templatesuffix(e);
- qprefix = SwigType_typedef_qualified(tprefix);
- Append(qprefix, "<(");
- pi = First(parms);
- while ((p = pi.item)) {
- /* TODO: the logic here should be synchronised with that in symbol_template_qualify() in symbol.c */
- String *qt = SwigType_typedef_qualified(p);
- if (Equal(qt, p)) { /* && (!Swig_scopename_check(qt))) */
- /* No change in value. It is entirely possible that the parameter is an integer value.
- If there is a symbol table associated with this scope, we're going to check for this */
-
- if (current_symtab) {
- Node *lastnode = 0;
- String *value = Copy(p);
- while (1) {
- Node *n = Swig_symbol_clookup(value, current_symtab);
- if (n == lastnode)
- break;
- lastnode = n;
- if (n) {
- char *ntype = Char(nodeType(n));
- if (strcmp(ntype, "enumitem") == 0) {
- /* An enum item. Generate a fully qualified name */
- String *qn = Swig_symbol_qualified(n);
- if (Len(qn)) {
- Append(qn, "::");
- Append(qn, Getattr(n, "name"));
- Delete(value);
- value = qn;
- continue;
- } else {
- Delete(qn);
- break;
- }
- } else if ((strcmp(ntype, "cdecl") == 0) && (Getattr(n, "value"))) {
- Delete(value);
- value = Copy(Getattr(n, "value"));
- continue;
- }
- }
- break;
- }
- Append(qprefix, value);
- Delete(value);
- } else {
- Append(qprefix, p);
- }
- } else {
- Append(qprefix, qt);
- }
- Delete(qt);
- pi = Next(pi);
- if (pi.item) {
- Append(qprefix, ",");
- }
- }
- Append(qprefix, ")>");
- Append(qprefix, tsuffix);
- Delete(tsuffix);
- Clear(e);
- Append(e, qprefix);
- Delete(tprefix);
- Delete(qprefix);
- Delete(parms);
- }
- Append(result, e);
- Delete(ty);
- } else if (SwigType_isfunction(e)) {
- List *parms = SwigType_parmlist(e);
- String *s = NewString("f(");
- Iterator pi;
- pi = First(parms);
- while (pi.item) {
- String *pq = SwigType_typedef_qualified(pi.item);
- Append(s, pq);
- Delete(pq);
- pi = Next(pi);
- if (pi.item) {
- Append(s, ",");
- }
- }
- Append(s, ").");
- Append(result, s);
- Delete(s);
- Delete(parms);
- } else if (SwigType_isarray(e)) {
- String *ndim;
- String *dim = SwigType_parm(e);
- ndim = Swig_symbol_string_qualify(dim, 0);
- Printf(result, "a(%s).", ndim);
- Delete(dim);
- Delete(ndim);
- } else {
- Append(result, e);
- }
- }
- Delete(elements);
- {
- String *key, *cresult;
- key = NewString(t);
- cresult = NewString(result);
- Setattr(typedef_qualified_cache, key, cresult);
- Delete(key);
- Delete(cresult);
- }
- return result;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_istypedef()
- *
- * Checks a typename to see if it is a typedef.
- * ----------------------------------------------------------------------------- */
-
-int SwigType_istypedef(const SwigType *t) {
- String *type;
-
- type = SwigType_typedef_resolve(t);
- if (type) {
- Delete(type);
- return 1;
- } else {
- return 0;
- }
-}
-
-
-/* -----------------------------------------------------------------------------
- * SwigType_typedef_using()
- *
- * Processes a 'using' declaration to import types from one scope into another.
- * Name is a qualified name like A::B.
- * ----------------------------------------------------------------------------- */
-
-int SwigType_typedef_using(const_String_or_char_ptr name) {
- String *base;
- String *td;
- String *prefix;
- Typetab *s;
- Typetab *tt = 0;
-
- String *defined_name = 0;
-
- /* Printf(stdout, "using %s\n", name); */
-
- if (!Swig_scopename_check(name))
- return -1; /* Not properly qualified */
- base = Swig_scopename_last(name);
-
- /* See if the base is already defined in this scope */
- if (Getattr(current_typetab, base)) {
- Delete(base);
- return -1;
- }
-
- /* See if the using name is a scope */
- /* tt = SwigType_find_scope(current_scope,name);
- Printf(stdout,"tt = %p, name = '%s'\n", tt, name); */
-
- /* We set up a typedef B --> A::B */
- Setattr(current_typetab, base, name);
-
- /* Find the scope name where the symbol is defined */
- td = SwigType_typedef_resolve(name);
- /* Printf(stdout,"td = '%s' %p\n", td, resolved_scope); */
- if (resolved_scope) {
- defined_name = Getattr(resolved_scope, "qname");
- if (defined_name) {
- defined_name = Copy(defined_name);
- Append(defined_name, "::");
- Append(defined_name, base);
- /* Printf(stdout,"defined_name = '%s'\n", defined_name); */
- tt = SwigType_find_scope(current_scope, defined_name);
- }
- }
- if (td)
- Delete(td);
-
-
- /* Figure out the scope the using directive refers to */
- {
- prefix = Swig_scopename_prefix(name);
- if (prefix) {
- s = SwigType_find_scope(current_scope, prefix);
- if (s) {
- Hash *ttab = Getattr(s, "typetab");
- if (!Getattr(ttab, base) && defined_name) {
- Setattr(ttab, base, defined_name);
- }
- }
- }
- }
-
- if (tt) {
- /* Using directive had its own scope. We need to create a new scope for it */
- SwigType_new_scope(base);
- SwigType_inherit_scope(tt);
- SwigType_pop_scope();
- }
-
- if (defined_name)
- Delete(defined_name);
- Delete(prefix);
- Delete(base);
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_isclass()
- *
- * Determines if a type defines a class or not. A class is defined by
- * its type-table entry maps to itself. Note: a pointer to a class is not
- * a class.
- * ----------------------------------------------------------------------------- */
-
-int SwigType_isclass(const SwigType *t) {
- SwigType *qty, *qtys;
- int isclass = 0;
-
- qty = SwigType_typedef_resolve_all(t);
- qtys = SwigType_strip_qualifiers(qty);
- if (SwigType_issimple(qtys)) {
- String *td = SwigType_typedef_resolve(qtys);
- if (td) {
- Delete(td);
- }
- if (resolved_scope) {
- isclass = 1;
- }
- /* Hmmm. Not a class. If a template, it might be uninstantiated */
- if (!isclass) {
- String *tp = SwigType_istemplate_templateprefix(qtys);
- if (tp && Strcmp(tp, t) != 0) {
- isclass = SwigType_isclass(tp);
- }
- Delete(tp);
- }
- }
- Delete(qty);
- Delete(qtys);
- return isclass;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_type()
- *
- * Returns an integer code describing the datatype. This is only used for
- * compatibility with SWIG1.1 language modules and is likely to go away once
- * everything is based on typemaps.
- * ----------------------------------------------------------------------------- */
-
-int SwigType_type(const SwigType *t) {
- char *c;
- /* Check for the obvious stuff */
- c = Char(t);
-
- if (strncmp(c, "p.", 2) == 0) {
- if (SwigType_type(c + 2) == T_CHAR)
- return T_STRING;
- else if (SwigType_type(c + 2) == T_WCHAR)
- return T_WSTRING;
- else
- return T_POINTER;
- }
- if (strncmp(c, "a(", 2) == 0)
- return T_ARRAY;
- if (strncmp(c, "r.", 2) == 0)
- return T_REFERENCE;
- if (strncmp(c, "z.", 2) == 0)
- return T_RVALUE_REFERENCE;
- if (strncmp(c, "m(", 2) == 0)
- return T_MPOINTER;
- if (strncmp(c, "q(", 2) == 0) {
- while (*c && (*c != '.'))
- c++;
- if (*c)
- return SwigType_type(c + 1);
- return T_ERROR;
- }
- if (strncmp(c, "f(", 2) == 0)
- return T_FUNCTION;
-
- /* Look for basic types */
- if (strcmp(c, "int") == 0)
- return T_INT;
- if (strcmp(c, "long") == 0)
- return T_LONG;
- if (strcmp(c, "short") == 0)
- return T_SHORT;
- if (strcmp(c, "unsigned") == 0)
- return T_UINT;
- if (strcmp(c, "unsigned short") == 0)
- return T_USHORT;
- if (strcmp(c, "unsigned long") == 0)
- return T_ULONG;
- if (strcmp(c, "unsigned int") == 0)
- return T_UINT;
- if (strcmp(c, "char") == 0)
- return T_CHAR;
- if (strcmp(c, "signed char") == 0)
- return T_SCHAR;
- if (strcmp(c, "unsigned char") == 0)
- return T_UCHAR;
- if (strcmp(c, "wchar_t") == 0)
- return T_WCHAR;
- if (strcmp(c, "float") == 0)
- return T_FLOAT;
- if (strcmp(c, "double") == 0)
- return T_DOUBLE;
- if (strcmp(c, "long double") == 0)
- return T_LONGDOUBLE;
- if (!cparse_cplusplus && (strcmp(c, "float _Complex") == 0))
- return T_FLTCPLX;
- if (!cparse_cplusplus && (strcmp(c, "double _Complex") == 0))
- return T_DBLCPLX;
- if (!cparse_cplusplus && (strcmp(c, "_Complex") == 0))
- return T_COMPLEX;
- if (strcmp(c, "void") == 0)
- return T_VOID;
- if (strcmp(c, "bool") == 0)
- return T_BOOL;
- if (strcmp(c, "long long") == 0)
- return T_LONGLONG;
- if (strcmp(c, "unsigned long long") == 0)
- return T_ULONGLONG;
- if (strncmp(c, "enum ", 5) == 0)
- return T_INT;
- if (strcmp(c, "auto") == 0)
- return T_AUTO;
-
- if (strcmp(c, "v(...)") == 0)
- return T_VARARGS;
- /* Hmmm. Unknown type */
- if (SwigType_istypedef(t)) {
- int r;
- SwigType *nt = SwigType_typedef_resolve(t);
- r = SwigType_type(nt);
- Delete(nt);
- return r;
- }
- return T_USER;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_alttype()
- *
- * Returns the alternative value type needed in C++ for class value
- * types. When swig is not sure about using a plain $ltype value,
- * since the class doesn't have a default constructor, or it can't be
- * assigned, you will get back 'SwigValueWrapper<type >'.
- *
- * This is the default behavior unless:
- *
- * 1.- swig detects a default_constructor and 'setallocate:default_constructor'
- * attribute.
- *
- * 2.- swig doesn't mark 'type' as non-assignable.
- *
- * 3.- the user specifies that the value wrapper is not needed by using
- * %feature("novaluewrapper") like so:
- *
- * %feature("novaluewrapper") MyOpaqueClass;
- * class MyOpaqueClass;
- *
- * The user can also force the use of the value wrapper with
- * %feature("valuewrapper").
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_alttype(const SwigType *t, int local_tmap) {
- Node *n;
- SwigType *w = 0;
- int use_wrapper = 0;
- SwigType *td = 0;
-
- if (!cparse_cplusplus)
- return 0;
-
- if (value_wrapper_mode == 0) {
- /* old partial use of SwigValueTypes, it can fail for opaque types */
- if (local_tmap)
- return 0;
- if (SwigType_isclass(t)) {
- SwigType *ftd = SwigType_typedef_resolve_all(t);
- td = SwigType_strip_qualifiers(ftd);
- Delete(ftd);
- n = Swig_symbol_clookup(td, 0);
- if (n) {
- if (GetFlag(n, "feature:valuewrapper")) {
- use_wrapper = 1;
- } else {
- if (Checkattr(n, "nodeType", "class")
- && (!Getattr(n, "allocate:default_constructor")
- || (Getattr(n, "allocate:noassign")))) {
- use_wrapper = !GetFlag(n, "feature:novaluewrapper") || GetFlag(n, "feature:nodefault");
- }
- }
- } else {
- if (SwigType_issimple(td) && SwigType_istemplate(td)) {
- use_wrapper = 1;
- }
- }
- }
- } else {
- /* safe use of SwigValueTypes, it can fail with some typemaps */
- SwigType *ftd = SwigType_typedef_resolve_all(t);
- td = SwigType_strip_qualifiers(ftd);
- Delete(ftd);
- if (SwigType_type(td) == T_USER) {
- use_wrapper = 1;
- n = Swig_symbol_clookup(td, 0);
- if (n) {
- if ((Checkattr(n, "nodeType", "class")
- && !Getattr(n, "allocate:noassign")
- && (Getattr(n, "allocate:default_constructor")))
- || (GetFlag(n, "feature:novaluewrapper"))) {
- use_wrapper = GetFlag(n, "feature:valuewrapper");
- }
- }
- }
- }
-
- if (use_wrapper) {
- /* Need a space before the type in case it starts "::" (since the <:
- * token is a digraph for [ in C++. Also need a space after the
- * type in case it ends with ">" since then we form the token ">>".
- */
- w = NewStringf("SwigValueWrapper< %s >", td);
- }
- Delete(td);
- return w;
-}
-
-/* ----------------------------------------------------------------------------
- * * * * WARNING * * * ***
- * ***
- * Don't even think about modifying anything below this line unless you ***
- * are completely on top of *EVERY* subtle aspect of the C++ type system ***
- * and you are prepared to suffer endless hours of agony trying to ***
- * debug the SWIG run-time type checker after you break it. ***
- * ------------------------------------------------------------------------- */
-
-/* -----------------------------------------------------------------------------
- * SwigType_remember()
- *
- * This function "remembers" a datatype that was used during wrapper code generation
- * so that a type-checking table can be generated later on. It is up to the language
- * modules to actually call this function--it is not done automatically.
- *
- * Type tracking is managed through two separate hash tables. The hash 'r_mangled'
- * is mapping between mangled type names (used in the target language) and
- * fully-resolved C datatypes used in the source input. The second hash 'r_resolved'
- * is the inverse mapping that maps fully-resolved C datatypes to all of the mangled
- * names in the scripting languages. For example, consider the following set of
- * typedef declarations:
- *
- * typedef double Real;
- * typedef double Float;
- * typedef double Point[3];
- *
- * Now, suppose that the types 'double *', 'Real *', 'Float *', 'double[3]', and
- * 'Point' were used in an interface file and "remembered" using this function.
- * The hash tables would look like this:
- *
- * r_mangled {
- * _p_double : [ p.double, a(3).double ]
- * _p_Real : [ p.double ]
- * _p_Float : [ p.double ]
- * _Point : [ a(3).double ]
- *
- * r_resolved {
- * p.double : [ _p_double, _p_Real, _p_Float ]
- * a(3).double : [ _p_double, _Point ]
- * }
- *
- * Together these two hash tables can be used to determine type-equivalency between
- * mangled typenames. To do this, we view the two hash tables as a large graph and
- * compute the transitive closure.
- * ----------------------------------------------------------------------------- */
-
-static Hash *r_mangled = 0; /* Hash mapping mangled types to fully resolved types */
-static Hash *r_resolved = 0; /* Hash mapping resolved types to mangled types */
-static Hash *r_ltype = 0; /* Hash mapping mangled names to their local c type */
-static Hash *r_clientdata = 0; /* Hash mapping resolved types to client data */
-static Hash *r_mangleddata = 0; /* Hash mapping mangled types to client data */
-static Hash *r_remembered = 0; /* Hash of types we remembered already */
-
-static void (*r_tracefunc) (const SwigType *t, String *mangled, String *clientdata) = 0;
-
-void SwigType_remember_mangleddata(String *mangled, const_String_or_char_ptr clientdata) {
- if (!r_mangleddata) {
- r_mangleddata = NewHash();
- }
- Setattr(r_mangleddata, mangled, clientdata);
-}
-
-
-void SwigType_remember_clientdata(const SwigType *t, const_String_or_char_ptr clientdata) {
- String *mt;
- SwigType *lt;
- Hash *h;
- SwigType *fr;
- SwigType *qr;
- String *tkey;
- String *cd;
- Hash *lthash;
-
- if (!r_mangled) {
- r_mangled = NewHash();
- r_resolved = NewHash();
- r_ltype = NewHash();
- r_clientdata = NewHash();
- r_remembered = NewHash();
- }
-
- {
- String *last;
- last = Getattr(r_remembered, t);
- if (last && (Cmp(last, clientdata) == 0))
- return;
- }
-
- tkey = Copy(t);
- cd = clientdata ? NewString(clientdata) : NewStringEmpty();
- Setattr(r_remembered, tkey, cd);
- Delete(tkey);
- Delete(cd);
-
- mt = SwigType_manglestr(t); /* Create mangled string */
-
- if (r_tracefunc) {
- (*r_tracefunc) (t, mt, (String *) clientdata);
- }
-
- if (SwigType_istypedef(t)) {
- lt = Copy(t);
- } else {
- lt = SwigType_ltype(t);
- }
-
- lthash = Getattr(r_ltype, mt);
- if (!lthash) {
- lthash = NewHash();
- Setattr(r_ltype, mt, lthash);
- }
- Setattr(lthash, lt, "1");
- Delete(lt);
-
- fr = SwigType_typedef_resolve_all(t); /* Create fully resolved type */
- qr = SwigType_typedef_qualified(fr);
- Delete(fr);
-
- /* Added to deal with possible table bug */
- fr = SwigType_strip_qualifiers(qr);
- Delete(qr);
-
- /*Printf(stdout,"t = '%s'\n", t);
- Printf(stdout,"fr= '%s'\n\n", fr); */
-
- if (t) {
- char *ct = Char(t);
- const char *lt = strchr(ct, '<');
- /* Allow for `<<` operator in constant expression for array size. */
- if (lt && lt[1] != '(' && lt[1] != '<') {
- Printf(stdout, "Bad template type passed to SwigType_remember: %s\n", t);
- assert(0);
- }
- }
-
- h = Getattr(r_mangled, mt);
- if (!h) {
- h = NewHash();
- Setattr(r_mangled, mt, h);
- Delete(h);
- }
- Setattr(h, fr, mt);
-
- h = Getattr(r_resolved, fr);
- if (!h) {
- h = NewHash();
- Setattr(r_resolved, fr, h);
- Delete(h);
- }
- Setattr(h, mt, fr);
-
- if (clientdata) {
- String *cd = Getattr(r_clientdata, fr);
- if (cd) {
- if (Strcmp(clientdata, cd) != 0) {
- Printf(stderr, "*** Internal error. Inconsistent clientdata for type '%s'\n", SwigType_str(fr, 0));
- Printf(stderr, "*** '%s' != '%s'\n", clientdata, cd);
- assert(0);
- }
- } else {
- String *cstr = NewString(clientdata);
- Setattr(r_clientdata, fr, cstr);
- Delete(cstr);
- }
- }
-
- /* If the remembered type is a reference, we also remember the pointer version.
- This is to prevent odd problems with mixing pointers and references--especially
- when different functions are using different typenames (via typedef). */
-
- if (SwigType_isreference(t)) {
- SwigType *tt = Copy(t);
- SwigType_del_reference(tt);
- SwigType_add_pointer(tt);
- SwigType_remember_clientdata(tt, clientdata);
- } else if (SwigType_isrvalue_reference(t)) {
- SwigType *tt = Copy(t);
- SwigType_del_rvalue_reference(tt);
- SwigType_add_pointer(tt);
- SwigType_remember_clientdata(tt, clientdata);
- }
-}
-
-void SwigType_remember(const SwigType *ty) {
- SwigType_remember_clientdata(ty, 0);
-}
-
-void (*SwigType_remember_trace(void (*tf) (const SwigType *, String *, String *))) (const SwigType *, String *, String *) {
- void (*o) (const SwigType *, String *, String *) = r_tracefunc;
- r_tracefunc = tf;
- return o;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_equivalent_mangle()
- *
- * Return a list of all of the mangled typenames that are equivalent to another
- * mangled name. This works as follows: For each fully qualified C datatype
- * in the r_mangled hash entry, we collect all of the mangled names from the
- * r_resolved hash and combine them together in a list (removing duplicate entries).
- * ----------------------------------------------------------------------------- */
-
-List *SwigType_equivalent_mangle(String *ms, Hash *checked, Hash *found) {
- List *l;
- Hash *h;
- Hash *ch;
- Hash *mh;
-
- if (found) {
- h = found;
- } else {
- h = NewHash();
- }
- if (checked) {
- ch = checked;
- } else {
- ch = NewHash();
- }
- if (Getattr(ch, ms))
- goto check_exit; /* Already checked this type */
- Setattr(h, ms, "1");
- Setattr(ch, ms, "1");
- mh = Getattr(r_mangled, ms);
- if (mh) {
- Iterator ki;
- ki = First(mh);
- while (ki.key) {
- Hash *rh;
- if (Getattr(ch, ki.key)) {
- ki = Next(ki);
- continue;
- }
- Setattr(ch, ki.key, "1");
- rh = Getattr(r_resolved, ki.key);
- if (rh) {
- Iterator rk;
- rk = First(rh);
- while (rk.key) {
- Setattr(h, rk.key, "1");
- SwigType_equivalent_mangle(rk.key, ch, h);
- rk = Next(rk);
- }
- }
- ki = Next(ki);
- }
- }
-check_exit:
- if (!found) {
- l = Keys(h);
- Delete(h);
- Delete(ch);
- return l;
- } else {
- return 0;
- }
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_clientdata_collect()
- *
- * Returns the clientdata field for a mangled type-string.
- * ----------------------------------------------------------------------------- */
-
-static
-String *SwigType_clientdata_collect(String *ms) {
- Hash *mh;
- String *clientdata = 0;
-
- if (r_mangleddata) {
- clientdata = Getattr(r_mangleddata, ms);
- if (clientdata)
- return clientdata;
- }
-
- mh = Getattr(r_mangled, ms);
- if (mh) {
- Iterator ki;
- ki = First(mh);
- while (ki.key) {
- clientdata = Getattr(r_clientdata, ki.key);
- if (clientdata)
- break;
- ki = Next(ki);
- }
- }
- return clientdata;
-}
-
-
-
-
-/* -----------------------------------------------------------------------------
- * SwigType_inherit()
- *
- * Record information about inheritance. We keep a hash table that keeps
- * a mapping between base classes and all of the classes that are derived
- * from them.
- *
- * subclass is a hash that maps base-classes to all of the classes derived from them.
- *
- * derived - name of derived class
- * base - name of base class
- * cast - additional casting code when casting from derived to base
- * conversioncode - if set, overrides the default code in the function when casting
- * from derived to base
- * ----------------------------------------------------------------------------- */
-
-static Hash *subclass = 0;
-static Hash *conversions = 0;
-
-void SwigType_inherit(String *derived, String *base, String *cast, String *conversioncode) {
- Hash *h;
- String *dd = 0;
- String *bb = 0;
- if (!subclass)
- subclass = NewHash();
-
- /* Printf(stdout,"'%s' --> '%s' '%s'\n", derived, base, cast); */
-
- if (SwigType_istemplate(derived)) {
- String *ty = SwigType_typedef_resolve_all(derived);
- dd = SwigType_typedef_qualified(ty);
- derived = dd;
- Delete(ty);
- }
- if (SwigType_istemplate(base)) {
- String *ty = SwigType_typedef_resolve_all(base);
- bb = SwigType_typedef_qualified(ty);
- base = bb;
- Delete(ty);
- }
-
- /* Printf(stdout,"'%s' --> '%s' '%s'\n", derived, base, cast); */
-
- h = Getattr(subclass, base);
- if (!h) {
- h = NewHash();
- Setattr(subclass, base, h);
- Delete(h);
- }
- if (!Getattr(h, derived)) {
- Hash *c = NewHash();
- if (cast)
- Setattr(c, "cast", cast);
- if (conversioncode)
- Setattr(c, "convcode", conversioncode);
- Setattr(h, derived, c);
- Delete(c);
- }
-
- Delete(dd);
- Delete(bb);
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_issubtype()
- *
- * Determines if a t1 is a subtype of t2, ie, is t1 derived from t2
- * ----------------------------------------------------------------------------- */
-
-int SwigType_issubtype(const SwigType *t1, const SwigType *t2) {
- SwigType *ft1, *ft2;
- String *b1, *b2;
- Hash *h;
- int r = 0;
-
- if (!subclass)
- return 0;
-
- ft1 = SwigType_typedef_resolve_all(t1);
- ft2 = SwigType_typedef_resolve_all(t2);
- b1 = SwigType_base(ft1);
- b2 = SwigType_base(ft2);
-
- h = Getattr(subclass, b2);
- if (h) {
- if (Getattr(h, b1)) {
- r = 1;
- }
- }
- Delete(ft1);
- Delete(ft2);
- Delete(b1);
- Delete(b2);
- /* Printf(stdout, "issubtype(%s,%s) --> %d\n", t1, t2, r); */
- return r;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_inherit_equiv()
- *
- * Modify the type table to handle C++ inheritance
- * ----------------------------------------------------------------------------- */
-
-void SwigType_inherit_equiv(File *out) {
- String *ckey;
- String *prefix, *base;
- String *mprefix, *mkey;
- Hash *sub;
- Hash *rh;
- List *rlist;
- List *r_resolved_sorted_keys;
- Iterator rk, bk, ck;
-
- if (!conversions)
- conversions = NewHash();
- if (!subclass)
- subclass = NewHash();
-
- r_resolved_sorted_keys = SortedKeys(r_resolved, Strcmp);
- rk = First(r_resolved_sorted_keys);
- while (rk.item) {
- List *sub_sorted_keys;
- /* rkey is a fully qualified type. We strip all of the type constructors off of it just to get the base */
- base = SwigType_base(rk.item);
- /* Check to see whether the base is recorded in the subclass table */
- sub = Getattr(subclass, base);
- Delete(base);
- if (!sub) {
- rk = Next(rk);
- continue;
- }
-
- /* This type has subclasses. We now need to walk through these subtypes and generate pointer conversion functions */
-
- rh = Getattr(r_resolved, rk.item);
- rlist = NewList();
- for (ck = First(rh); ck.key; ck = Next(ck)) {
- Append(rlist, ck.key);
- }
- /* Printf(stdout,"rk.item = '%s'\n", rk.item);
- Printf(stdout,"rh = %p '%s'\n", rh,rh); */
-
- sub_sorted_keys = SortedKeys(sub, Strcmp);
- bk = First(sub_sorted_keys);
- while (bk.item) {
- prefix = SwigType_prefix(rk.item);
- Append(prefix, bk.item);
- /* Printf(stdout,"set %p = '%s' : '%s'\n", rh, SwigType_manglestr(prefix),prefix); */
- mprefix = SwigType_manglestr(prefix);
- Setattr(rh, mprefix, prefix);
- mkey = SwigType_manglestr(rk.item);
- ckey = NewStringf("%s+%s", mprefix, mkey);
- if (!Getattr(conversions, ckey)) {
- String *convname = NewStringf("%sTo%s", mprefix, mkey);
- String *lkey = SwigType_lstr(rk.item, 0);
- String *lprefix = SwigType_lstr(prefix, 0);
- Hash *subhash = Getattr(sub, bk.item);
- String *convcode = Getattr(subhash, "convcode");
- if (convcode) {
- char *newmemoryused = Strstr(convcode, "newmemory"); /* see if newmemory parameter is used in order to avoid unused parameter warnings */
- String *fn = Copy(convcode);
- Replaceall(fn, "$from", "x");
- Printf(out, "static void *%s(void *x, int *%s) {", convname, newmemoryused ? "newmemory" : "SWIGUNUSEDPARM(newmemory)");
- Printf(out, "%s", fn);
- } else {
- String *cast = Getattr(subhash, "cast");
- Printf(out, "static void *%s(void *x, int *SWIGUNUSEDPARM(newmemory)) {", convname);
- Printf(out, "\n return (void *)((%s) ", lkey);
- if (cast)
- Printf(out, "%s", cast);
- Printf(out, " ((%s) x));\n", lprefix);
- }
- Printf(out, "}\n");
- Setattr(conversions, ckey, convname);
- Delete(ckey);
- Delete(lkey);
- Delete(lprefix);
-
- /* This inserts conversions for typedefs */
- {
- Hash *r = Getattr(r_resolved, prefix);
- if (r) {
- Iterator rrk;
- rrk = First(r);
- while (rrk.key) {
- Iterator rlk;
- String *rkeymangle;
-
- /* Make sure this name equivalence is not due to inheritance */
- if (Cmp(prefix, Getattr(r, rrk.key)) == 0) {
- rkeymangle = Copy(mkey);
- ckey = NewStringf("%s+%s", rrk.key, rkeymangle);
- if (!Getattr(conversions, ckey)) {
- Setattr(conversions, ckey, convname);
- }
- Delete(ckey);
- for (rlk = First(rlist); rlk.item; rlk = Next(rlk)) {
- ckey = NewStringf("%s+%s", rrk.key, rlk.item);
- Setattr(conversions, ckey, convname);
- Delete(ckey);
- }
- Delete(rkeymangle);
- /* This is needed to pick up other alternative names for the same type.
- Needed to make templates work */
- Setattr(rh, rrk.key, rrk.item);
- }
- rrk = Next(rrk);
- }
- }
- }
- Delete(convname);
- }
- Delete(prefix);
- Delete(mprefix);
- Delete(mkey);
- bk = Next(bk);
- }
- Delete(sub_sorted_keys);
- rk = Next(rk);
- Delete(rlist);
- }
- Delete(r_resolved_sorted_keys);
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_type_table()
- *
- * Generate the type-table for the type-checker.
- * ----------------------------------------------------------------------------- */
-
-void SwigType_emit_type_table(File *f_forward, File *f_table) {
- Iterator ki;
- String *types, *table, *cast, *cast_init, *cast_temp;
- Hash *imported_types;
- List *mangled_list;
- List *table_list = NewList();
- int i = 0;
-
- if (!r_mangled) {
- r_mangled = NewHash();
- r_resolved = NewHash();
- }
-
- Printf(f_table, "\n/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */\n\n");
-
- SwigType_inherit_equiv(f_table);
-
- /*#define DEBUG 1*/
-#ifdef DEBUG
- Printf(stdout, "---r_mangled---\n");
- Swig_print(r_mangled, 2);
-
- Printf(stdout, "---r_resolved---\n");
- Swig_print(r_resolved, 2);
-
- Printf(stdout, "---r_ltype---\n");
- Swig_print(r_ltype, 2);
-
- Printf(stdout, "---subclass---\n");
- Swig_print(subclass, 2);
-
- Printf(stdout, "---conversions---\n");
- Swig_print(conversions, 2);
-
- Printf(stdout, "---r_clientdata---\n");
- Swig_print(r_clientdata, 2);
-
-#endif
- table = NewStringEmpty();
- types = NewStringEmpty();
- cast = NewStringEmpty();
- cast_init = NewStringEmpty();
- imported_types = NewHash();
-
- Printf(table, "static swig_type_info *swig_type_initial[] = {\n");
- Printf(cast_init, "static swig_cast_info *swig_cast_initial[] = {\n");
-
- Printf(f_forward, "\n/* -------- TYPES TABLE (BEGIN) -------- */\n\n");
-
- mangled_list = SortedKeys(r_mangled, Strcmp);
- for (ki = First(mangled_list); ki.item; ki = Next(ki)) {
- List *el;
- Iterator ei;
- String *nt;
- String *ln;
- String *rn;
- const String *cd;
- Hash *lthash;
- Iterator ltiter;
- Hash *nthash;
- String *cast_temp_conv;
- String *resolved_lstr = 0;
- List *ntlist;
-
- cast_temp = NewStringEmpty();
- cast_temp_conv = NewStringEmpty();
-
- Printv(types, "static swig_type_info _swigt_", ki.item, " = {", NIL);
- Append(table_list, ki.item);
- Printf(cast_temp, "static swig_cast_info _swigc_%s[] = {", ki.item);
- i++;
-
- cd = SwigType_clientdata_collect(ki.item);
- if (!cd)
- cd = "0";
-
- lthash = Getattr(r_ltype, ki.item);
- nt = 0;
- nthash = NewHash();
- ltiter = First(lthash);
- while (ltiter.key) {
- SwigType *lt = ltiter.key;
- SwigType *rt = SwigType_typedef_resolve_all(lt);
- /* we save the original type and the fully resolved version */
- ln = SwigType_lstr(lt, 0);
- rn = SwigType_lstr(rt, 0);
- if (Equal(ln, rn)) {
- Setattr(nthash, ln, "1");
- } else {
- Setattr(nthash, rn, "1");
- Setattr(nthash, ln, "1");
- }
- if (!resolved_lstr) {
- resolved_lstr = Copy(rn);
- } else if (Len(rn) < Len(resolved_lstr)) {
- Delete(resolved_lstr);
- resolved_lstr = Copy(rn);
- }
- if (SwigType_istemplate(rt)) {
- String *dt = Swig_symbol_template_deftype(rt, 0);
- String *dn = SwigType_lstr(dt, 0);
- if (!Equal(dn, rn) && !Equal(dn, ln)) {
- Setattr(nthash, dn, "1");
- }
- Delete(dt);
- Delete(dn);
- }
- Delete(rt);
- Delete(rn);
- Delete(ln);
-
- ltiter = Next(ltiter);
- }
-
- /* now build nt */
- ntlist = SortedKeys(nthash, Strcmp);
- ltiter = First(ntlist);
- nt = 0;
- while (ltiter.item) {
- if (!Equal(resolved_lstr, ltiter.item)) {
- if (nt) {
- Printf(nt, "|%s", ltiter.item);
- } else {
- nt = NewString(ltiter.item);
- }
- }
- ltiter = Next(ltiter);
- }
- /* Last in list is a resolved type used by SWIG_TypePrettyName.
- * There can be more than one resolved type and the chosen one is simply the
- * shortest in length, arguably the most user friendly/readable. */
- if (nt) {
- Printf(nt, "|%s", resolved_lstr);
- } else {
- nt = NewString(resolved_lstr);
- }
- Delete(ntlist);
- Delete(nthash);
- Delete(resolved_lstr);
-
- Printf(types, "\"%s\", \"%s\", 0, 0, (void*)%s, 0};\n", ki.item, nt, cd);
-
- el = SwigType_equivalent_mangle(ki.item, 0, 0);
- SortList(el, Strcmp);
- for (ei = First(el); ei.item; ei = Next(ei)) {
- String *ckey;
- String *conv;
- ckey = NewStringf("%s+%s", ei.item, ki.item);
- conv = Getattr(conversions, ckey);
- if (conv) {
- Printf(cast_temp_conv, " {&_swigt_%s, %s, 0, 0},", ei.item, conv);
- } else {
- Printf(cast_temp, " {&_swigt_%s, 0, 0, 0},", ei.item);
- }
- Delete(ckey);
-
- if (!Getattr(r_mangled, ei.item) && !Getattr(imported_types, ei.item)) {
- Printf(types, "static swig_type_info _swigt_%s = {\"%s\", 0, 0, 0, 0, 0};\n", ei.item, ei.item);
- Append(table_list, ei.item);
-
- Printf(cast, "static swig_cast_info _swigc_%s[] = {{&_swigt_%s, 0, 0, 0},{0, 0, 0, 0}};\n", ei.item, ei.item);
- i++;
-
- Setattr(imported_types, ei.item, "1");
- }
- }
- Delete(el);
- Printf(cast, "%s%s{0, 0, 0, 0}};\n", cast_temp, cast_temp_conv);
- Delete(cast_temp_conv);
- Delete(cast_temp);
- Delete(nt);
- }
- /* print the tables in the proper order */
- SortList(table_list, Strcmp);
- i = 0;
- for (ki = First(table_list); ki.item; ki = Next(ki)) {
- Printf(f_forward, "#define SWIGTYPE%s swig_types[%d]\n", ki.item, i++);
- Printf(table, " &_swigt_%s,\n", ki.item);
- Printf(cast_init, " _swigc_%s,\n", ki.item);
- }
- if (i == 0) {
- /* empty arrays are not allowed by ISO C */
- Printf(table, " NULL\n");
- Printf(cast_init, " NULL\n");
- }
-
- Delete(table_list);
-
- Delete(mangled_list);
-
- Printf(table, "};\n");
- Printf(cast_init, "};\n");
- Printf(f_table, "%s\n", types);
- Printf(f_table, "%s\n", table);
- Printf(f_table, "%s\n", cast);
- Printf(f_table, "%s\n", cast_init);
- Printf(f_table, "\n/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */\n\n");
-
- Printf(f_forward, "static swig_type_info *swig_types[%d];\n", i + 1);
- Printf(f_forward, "static swig_module_info swig_module = {swig_types, %d, 0, 0, 0, 0};\n", i);
- Printf(f_forward, "#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)\n");
- Printf(f_forward, "#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)\n");
- Printf(f_forward, "\n/* -------- TYPES TABLE (END) -------- */\n\n");
-
- Delete(types);
- Delete(table);
- Delete(cast);
- Delete(cast_init);
- Delete(imported_types);
-}
diff --git a/contrib/tools/swig/Source/Swig/wrapfunc.c b/contrib/tools/swig/Source/Swig/wrapfunc.c
deleted file mode 100644
index 6d82372453..0000000000
--- a/contrib/tools/swig/Source/Swig/wrapfunc.c
+++ /dev/null
@@ -1,520 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * wrapfunc.c
- *
- * This file defines a object for creating wrapper functions. Primarily
- * this is used for convenience since it allows pieces of a wrapper function
- * to be created in a piecemeal manner.
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-#include <ctype.h>
-
-static int Compact_mode = 0; /* set to 0 on default */
-static int Max_line_size = 128;
-
-/* -----------------------------------------------------------------------------
- * NewWrapper()
- *
- * Create a new wrapper function object.
- * ----------------------------------------------------------------------------- */
-
-Wrapper *NewWrapper(void) {
- Wrapper *w;
- w = (Wrapper *) Malloc(sizeof(Wrapper));
- w->localh = NewHash();
- w->locals = NewStringEmpty();
- w->code = NewStringEmpty();
- w->def = NewStringEmpty();
- return w;
-}
-
-/* -----------------------------------------------------------------------------
- * DelWrapper()
- *
- * Delete a wrapper function object.
- * ----------------------------------------------------------------------------- */
-
-void DelWrapper(Wrapper *w) {
- Delete(w->localh);
- Delete(w->locals);
- Delete(w->code);
- Delete(w->def);
- Free(w);
-}
-
-/* -----------------------------------------------------------------------------
- * Wrapper_compact_print_mode_set()
- *
- * Set compact_mode.
- * ----------------------------------------------------------------------------- */
-
-void Wrapper_compact_print_mode_set(int flag) {
- Compact_mode = flag;
-}
-
-/* -----------------------------------------------------------------------------
- * Wrapper_pretty_print()
- *
- * Formats a wrapper function and fixes up the indentation.
- * ----------------------------------------------------------------------------- */
-
-void Wrapper_pretty_print(String *str, File *f) {
- String *ts;
- int level = 0;
- int c, i;
- int empty = 1;
- int indent = 2;
- int plevel = 0;
- int label = 0;
-
- ts = NewStringEmpty();
- Seek(str, 0, SEEK_SET);
- while ((c = Getc(str)) != EOF) {
- if (c == '\"') {
- Putc(c, ts);
- while ((c = Getc(str)) != EOF) {
- if (c == '\\') {
- Putc(c, ts);
- c = Getc(str);
- }
- Putc(c, ts);
- if (c == '\"')
- break;
- }
- empty = 0;
- } else if (c == '\'') {
- Putc(c, ts);
- while ((c = Getc(str)) != EOF) {
- if (c == '\\') {
- Putc(c, ts);
- c = Getc(str);
- }
- Putc(c, ts);
- if (c == '\'')
- break;
- }
- empty = 0;
- } else if (c == ':') {
- Putc(c, ts);
- if ((c = Getc(str)) == '\n') {
- if (!empty && !strchr(Char(ts), '?'))
- label = 1;
- }
- Ungetc(c, str);
- } else if (c == '(') {
- Putc(c, ts);
- plevel += indent;
- empty = 0;
- } else if (c == ')') {
- Putc(c, ts);
- plevel -= indent;
- empty = 0;
- } else if (c == '{') {
- Putc(c, ts);
- Putc('\n', ts);
- for (i = 0; i < level; i++)
- Putc(' ', f);
- Printf(f, "%s", ts);
- Clear(ts);
- level += indent;
- while ((c = Getc(str)) != EOF) {
- if (!isspace(c)) {
- Ungetc(c, str);
- break;
- }
- }
- empty = 0;
- } else if (c == '}') {
- if (!empty) {
- Putc('\n', ts);
- for (i = 0; i < level; i++)
- Putc(' ', f);
- Printf(f, "%s", ts);
- Clear(ts);
- }
- level -= indent;
- Putc(c, ts);
- empty = 0;
- } else if (c == '\n') {
- Putc(c, ts);
- empty = 0;
- if (!empty) {
- int slevel = level;
- if (label && (slevel >= indent))
- slevel -= indent;
- if ((Char(ts))[0] != '#') {
- for (i = 0; i < slevel; i++)
- Putc(' ', f);
- }
- Printf(f, "%s", ts);
- for (i = 0; i < plevel; i++)
- Putc(' ', f);
- }
- Clear(ts);
- label = 0;
- empty = 1;
- } else if (c == '/') {
- empty = 0;
- Putc(c, ts);
- c = Getc(str);
- if (c != EOF) {
- Putc(c, ts);
- if (c == '/') { /* C++ comment */
- while ((c = Getc(str)) != EOF) {
- if (c == '\n') {
- Ungetc(c, str);
- break;
- }
- Putc(c, ts);
- }
- } else if (c == '*') { /* C comment */
- int endstar = 0;
- while ((c = Getc(str)) != EOF) {
- if (endstar && c == '/') { /* end of C comment */
- Putc(c, ts);
- break;
- }
- endstar = (c == '*');
- Putc(c, ts);
- if (c == '\n') { /* multi-line C comment. Could be improved slightly. */
- for (i = 0; i < level; i++)
- Putc(' ', ts);
- }
- }
- }
- }
- } else {
- if (!empty || !isspace(c)) {
- Putc(c, ts);
- empty = 0;
- }
- }
- }
- if (!empty)
- Printf(f, "%s", ts);
- Delete(ts);
- Printf(f, "\n");
-}
-
-/* -----------------------------------------------------------------------------
- * Wrapper_compact_print()
- *
- * Formats a wrapper function and fixes up the indentation.
- * Print out in compact format, with Compact enabled.
- * ----------------------------------------------------------------------------- */
-
-void Wrapper_compact_print(String *str, File *f) {
- String *ts, *tf; /*temp string & temp file */
- int level = 0;
- int c, i;
- int empty = 1;
- int indent = 2;
-
- ts = NewStringEmpty();
- tf = NewStringEmpty();
- Seek(str, 0, SEEK_SET);
-
- while ((c = Getc(str)) != EOF) {
- if (c == '\"') { /* string 1 */
- empty = 0;
- Putc(c, ts);
- while ((c = Getc(str)) != EOF) {
- if (c == '\\') {
- Putc(c, ts);
- c = Getc(str);
- }
- Putc(c, ts);
- if (c == '\"')
- break;
- }
- } else if (c == '\'') { /* string 2 */
- empty = 0;
- Putc(c, ts);
- while ((c = Getc(str)) != EOF) {
- if (c == '\\') {
- Putc(c, ts);
- c = Getc(str);
- }
- Putc(c, ts);
- if (c == '\'')
- break;
- }
- } else if (c == '{') { /* start of {...} */
- empty = 0;
- Putc(c, ts);
- if (Len(tf) == 0) {
- for (i = 0; i < level; i++)
- Putc(' ', tf);
- } else if ((Len(tf) + Len(ts)) < Max_line_size) {
- Putc(' ', tf);
- } else {
- Putc('\n', tf);
- Printf(f, "%s", tf);
- Clear(tf);
- for (i = 0; i < level; i++)
- Putc(' ', tf);
- }
- Append(tf, ts);
- Clear(ts);
- level += indent;
- while ((c = Getc(str)) != EOF) {
- if (!isspace(c)) {
- Ungetc(c, str);
- break;
- }
- }
- } else if (c == '}') { /* end of {...} */
- empty = 0;
- if (Len(tf) == 0) {
- for (i = 0; i < level; i++)
- Putc(' ', tf);
- } else if ((Len(tf) + Len(ts)) < Max_line_size) {
- Putc(' ', tf);
- } else {
- Putc('\n', tf);
- Printf(f, "%s", tf);
- Clear(tf);
- for (i = 0; i < level; i++)
- Putc(' ', tf);
- }
- Append(tf, ts);
- Putc(c, tf);
- Clear(ts);
- level -= indent;
- } else if (c == '\n') { /* line end */
- while ((c = Getc(str)) != EOF) {
- if (!isspace(c))
- break;
- }
- if (c == '#') {
- Putc('\n', ts);
- } else if (c == '}') {
- Putc(' ', ts);
- } else if ((c != EOF) || (Len(ts) != 0)) {
- if (Len(tf) == 0) {
- for (i = 0; i < level; i++)
- Putc(' ', tf);
- } else if ((Len(tf) + Len(ts)) < Max_line_size) {
- Putc(' ', tf);
- } else {
- Putc('\n', tf);
- Printf(f, "%s", tf);
- Clear(tf);
- for (i = 0; i < level; i++)
- Putc(' ', tf);
- }
- Append(tf, ts);
- Clear(ts);
- }
- Ungetc(c, str);
-
- empty = 1;
- } else if (c == '/') { /* comment */
- empty = 0;
- c = Getc(str);
- if (c != EOF) {
- if (c == '/') { /* C++ comment */
- while ((c = Getc(str)) != EOF) {
- if (c == '\n') {
- Ungetc(c, str);
- break;
- }
- }
- } else if (c == '*') { /* C comment */
- int endstar = 0;
- while ((c = Getc(str)) != EOF) {
- if (endstar && c == '/') { /* end of C comment */
- break;
- }
- endstar = (c == '*');
- }
- } else {
- Putc('/', ts);
- Putc(c, ts);
- }
- }
- } else if (c == '#') { /* Preprocessor line */
- Putc('#', ts);
- while ((c = Getc(str)) != EOF) {
- Putc(c, ts);
- if (c == '\\') { /* Continued line of the same PP */
- c = Getc(str);
- if (c == '\n')
- Putc(c, ts);
- else
- Ungetc(c, str);
- } else if (c == '\n')
- break;
- }
- if (!empty) {
- Append(tf, "\n");
- }
- Append(tf, ts);
- Printf(f, "%s", tf);
- Clear(tf);
- Clear(ts);
- for (i = 0; i < level; i++)
- Putc(' ', tf);
- empty = 1;
- } else {
- if (!empty || !isspace(c)) {
- Putc(c, ts);
- empty = 0;
- }
- }
- }
- if (!empty) {
- Append(tf, ts);
- }
- if (Len(tf) != 0)
- Printf(f, "%s", tf);
- Delete(ts);
- Delete(tf);
- Printf(f, "\n");
-}
-
-/* -----------------------------------------------------------------------------
- * Wrapper_print()
- *
- * Print out a wrapper function. Does pretty or compact printing as well.
- * ----------------------------------------------------------------------------- */
-
-void Wrapper_print(Wrapper *w, File *f) {
- String *str;
-
- str = NewStringEmpty();
- Printf(str, "%s\n", w->def);
- Printf(str, "%s\n", w->locals);
- Printf(str, "%s\n", w->code);
- if (Compact_mode == 1)
- Wrapper_compact_print(str, f);
- else
- Wrapper_pretty_print(str, f);
-
- Delete(str);
-}
-
-/* -----------------------------------------------------------------------------
- * Wrapper_add_local()
- *
- * Adds a new local variable declaration to a function. Returns -1 if already
- * present (which may or may not be okay to the caller).
- * ----------------------------------------------------------------------------- */
-
-int Wrapper_add_local(Wrapper *w, const_String_or_char_ptr name, const_String_or_char_ptr decl) {
- /* See if the local has already been declared */
- if (Getattr(w->localh, name)) {
- return -1;
- }
- Setattr(w->localh, name, decl);
- Printf(w->locals, "%s;\n", decl);
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Wrapper_add_localv()
- *
- * Same as add_local(), but allows a NULL terminated list of strings to be
- * used as a replacement for decl. This saves the caller the trouble of having
- * to manually construct the 'decl' string before calling.
- * ----------------------------------------------------------------------------- */
-
-int Wrapper_add_localv(Wrapper *w, const_String_or_char_ptr name, ...) {
- va_list ap;
- int ret;
- String *decl;
- DOH *obj;
- decl = NewStringEmpty();
- va_start(ap, name);
-
- obj = va_arg(ap, void *);
- while (obj) {
- Append(decl, obj);
- Putc(' ', decl);
- obj = va_arg(ap, void *);
- }
- va_end(ap);
-
- ret = Wrapper_add_local(w, name, decl);
- Delete(decl);
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
- * Wrapper_check_local()
- *
- * Check to see if a local name has already been declared
- * ----------------------------------------------------------------------------- */
-
-int Wrapper_check_local(Wrapper *w, const_String_or_char_ptr name) {
- if (Getattr(w->localh, name)) {
- return 1;
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Wrapper_new_local()
- *
- * Adds a new local variable with a guarantee that a unique local name will be
- * used. Returns the name that was actually selected.
- * ----------------------------------------------------------------------------- */
-
-char *Wrapper_new_local(Wrapper *w, const_String_or_char_ptr name, const_String_or_char_ptr decl) {
- int i;
- String *nname = NewString(name);
- String *ndecl = NewString(decl);
- char *ret;
-
- i = 0;
-
- while (Wrapper_check_local(w, nname)) {
- Clear(nname);
- Printf(nname, "%s%d", name, i);
- i++;
- }
- Replace(ndecl, name, nname, DOH_REPLACE_ID);
- Setattr(w->localh, nname, ndecl);
- Printf(w->locals, "%s;\n", ndecl);
- ret = Char(nname);
- Delete(nname);
- Delete(ndecl);
- return ret; /* Note: nname should still exists in the w->localh hash */
-}
-
-
-/* -----------------------------------------------------------------------------
- * Wrapper_new_localv()
- *
- * Same as add_local(), but allows a NULL terminated list of strings to be
- * used as a replacement for decl. This saves the caller the trouble of having
- * to manually construct the 'decl' string before calling.
- * ----------------------------------------------------------------------------- */
-
-char *Wrapper_new_localv(Wrapper *w, const_String_or_char_ptr name, ...) {
- va_list ap;
- char *ret;
- String *decl;
- DOH *obj;
- decl = NewStringEmpty();
- va_start(ap, name);
-
- obj = va_arg(ap, void *);
- while (obj) {
- Append(decl, obj);
- Putc(' ', decl);
- obj = va_arg(ap, void *);
- }
- va_end(ap);
-
- ret = Wrapper_new_local(w, name, decl);
- Delete(decl);
- return ret;
-}
diff --git a/contrib/tools/swig/swig_lib.cpp b/contrib/tools/swig/swig_lib.cpp
deleted file mode 100644
index 75b98501e8..0000000000
--- a/contrib/tools/swig/swig_lib.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define _STR(a) #a
-#define STR(a) _STR(a)
-
-static const char* ArcadiaRoot() {
- const char* root = getenv("ARCADIA_ROOT_DISTBUILD");
- return root ? root : STR(ARCADIA_ROOT);
-}
-
-#ifdef _MSC_VER
-static int setenv(const char* name, const char* value, int overwrite) {
- return (overwrite || !getenv(name)) ? _putenv_s(name, value) : 0;
-}
-#endif
-
-static void InitSwigLib() {
- const char* root = ArcadiaRoot();
- const char* lib = STR(SWIG_LIB_ARCPATH);
- char* s = new char[strlen(root) + 1 + strlen(lib) + 1];
- sprintf(s, "%s/%s", root, lib);
- setenv("SWIG_LIB", s, false);
- delete[] s;
-}
-
-static int initSwigLib = (InitSwigLib(), 0);
diff --git a/contrib/tools/swig/ya.make b/contrib/tools/swig/ya.make
deleted file mode 100644
index d1d4b407c8..0000000000
--- a/contrib/tools/swig/ya.make
+++ /dev/null
@@ -1,120 +0,0 @@
-# Generated by devtools/yamaker from nixpkgs 22.11.
-
-PROGRAM(swig)
-
-LICENSE(
- Custom-swig AND
- GPL-3.0-only
-)
-
-LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-
-VERSION(4.1.1)
-
-ORIGINAL_SOURCE(https://github.com/swig/swig/archive/v4.1.1.tar.gz)
-
-PEERDIR(
- contrib/libs/pcre2
-)
-
-ADDINCL(
- contrib/libs/pcre2
- contrib/tools/swig/Source/CParse
- contrib/tools/swig/Source/DOH
- contrib/tools/swig/Source/Doxygen
- contrib/tools/swig/Source/Include
- contrib/tools/swig/Source/Modules
- contrib/tools/swig/Source/Preprocessor
- contrib/tools/swig/Source/Swig
-)
-
-NO_COMPILER_WARNINGS()
-
-NO_UTIL()
-
-CFLAGS(
- -DSWIG_LIB_ARCPATH=contrib/tools/swig/Lib
- -DHAVE_CONFIG_H
-)
-
-BISON_GEN_C()
-
-SRCS(
- Source/CParse/cscanner.c
- Source/CParse/parser.y
- Source/CParse/templ.c
- Source/CParse/util.c
- Source/DOH/base.c
- Source/DOH/file.c
- Source/DOH/fio.c
- Source/DOH/hash.c
- Source/DOH/list.c
- Source/DOH/memory.c
- Source/DOH/string.c
- Source/DOH/void.c
- Source/Doxygen/doxyentity.cxx
- Source/Doxygen/doxyparser.cxx
- Source/Doxygen/doxytranslator.cxx
- Source/Doxygen/javadoc.cxx
- Source/Doxygen/pydoc.cxx
- Source/Modules/allocate.cxx
- Source/Modules/contract.cxx
- Source/Modules/csharp.cxx
- Source/Modules/d.cxx
- Source/Modules/directors.cxx
- Source/Modules/emit.cxx
- Source/Modules/go.cxx
- Source/Modules/guile.cxx
- Source/Modules/interface.cxx
- Source/Modules/java.cxx
- Source/Modules/javascript.cxx
- Source/Modules/lang.cxx
- Source/Modules/lua.cxx
- Source/Modules/main.cxx
- Source/Modules/mzscheme.cxx
- Source/Modules/nested.cxx
- Source/Modules/ocaml.cxx
- Source/Modules/octave.cxx
- Source/Modules/overload.cxx
- Source/Modules/perl5.cxx
- Source/Modules/php.cxx
- Source/Modules/python.cxx
- Source/Modules/r.cxx
- Source/Modules/ruby.cxx
- Source/Modules/scilab.cxx
- Source/Modules/swigmain.cxx
- Source/Modules/tcl8.cxx
- Source/Modules/typepass.cxx
- Source/Modules/utils.cxx
- Source/Modules/xml.cxx
- Source/Preprocessor/cpp.c
- Source/Preprocessor/expr.c
- Source/Swig/cwrap.c
- Source/Swig/deprecate.c
- Source/Swig/error.c
- Source/Swig/extend.c
- Source/Swig/fragment.c
- Source/Swig/getopt.c
- Source/Swig/include.c
- Source/Swig/misc.c
- Source/Swig/naming.c
- Source/Swig/parms.c
- Source/Swig/scanner.c
- Source/Swig/stype.c
- Source/Swig/symbol.c
- Source/Swig/tree.c
- Source/Swig/typemap.c
- Source/Swig/typeobj.c
- Source/Swig/typesys.c
- Source/Swig/wrapfunc.c
- swig_lib.cpp
-)
-
-END()
-
-RECURSE(
- Lib/go
- Lib/java
- Lib/perl5
- Lib/python
-)
diff --git a/library/cpp/pybind/attr.h b/library/cpp/pybind/attr.h
deleted file mode 100644
index 5f25a6d73d..0000000000
--- a/library/cpp/pybind/attr.h
+++ /dev/null
@@ -1,412 +0,0 @@
-#pragma once
-
-#define PY_SSIZE_T_CLEAN
-#include <Python.h>
-#include <util/generic/string.h>
-#include <util/generic/map.h>
-#include <util/generic/set.h>
-#include <util/generic/vector.h>
-#include <util/generic/ptr.h>
-
-#include "cast.h"
-#include "exceptions.h"
-
-namespace NPyBind {
- // TBaseAttrGetter
- template <typename TObjType>
- class TBaseAttrGetter {
- public:
- virtual ~TBaseAttrGetter() {
- }
- virtual bool GetAttr(PyObject* owner, const TObjType& self, const TString& attr, PyObject*& res) const = 0;
-
- virtual bool HasAttr(PyObject* owner, const TObjType& self, const TString& attr, const TSet<TString>& hiddenNames) const {
- if (hiddenNames.find(attr) != hiddenNames.end())
- return false;
- PyObject* res = nullptr;
- if (!GetAttr(owner, self, attr, res))
- return false;
- Py_XDECREF(res);
- return true;
- }
- };
-
- template <typename TObjType>
- class TBaseAttrSetter {
- public:
- virtual ~TBaseAttrSetter() {
- }
-
- virtual bool SetAttr(PyObject* owner, TObjType& self, const TString& attr, PyObject* val) = 0;
- };
-
- template <typename TObjType>
- class TAttrGetters {
- public:
- typedef TSimpleSharedPtr<TBaseAttrGetter<TObjType>> TGetterPtr;
-
- private:
- typedef TVector<TGetterPtr> TGetterList;
- typedef TMap<TString, TGetterList> TGetterMap;
-
- const TSet<TString>& HiddenAttrNames;
- TGetterMap Getters;
-
- public:
- TAttrGetters(const TSet<TString>& hiddenNames)
- : HiddenAttrNames(hiddenNames)
- {
- }
-
- void AddGetter(const TString& attr, TGetterPtr getter) {
- Getters[attr].push_back(getter);
- }
-
- PyObject* GetAttr(PyObject* owner, const TObjType& self, const TString& attr) const {
- typename TGetterMap::const_iterator it1 = Getters.find(attr);
- if (it1 == Getters.end())
- it1 = Getters.find("");
- if (it1 == Getters.end())
- return nullptr;
- const TGetterList& lst = it1->second;
- for (typename TGetterList::const_iterator it2 = lst.begin(), end = lst.end(); it2 != end; ++it2) {
- PyObject* res = nullptr;
- if ((*it2)->GetAttr(owner, self, attr, res))
- return res;
- // IMPORTANT!
- // we have to fail GetAttr right there because we've failed because of internal python error/exception and can't continue iterating because
- // it cause subsequent exceptions during call to Py_BuildValue
- // moreover we have to preserve original exception right there
- if (PyErr_Occurred()) {
- break;
- }
- }
- return nullptr;
- }
-
- bool HasAttr(PyObject* owner, const TObjType& self, const TString& attr) const {
- typename TGetterMap::const_iterator it1 = Getters.find(attr);
- if (it1 == Getters.end())
- return false;
- const TGetterList& lst = it1->second;
- for (typename TGetterList::const_iterator it2 = lst.begin(), end = lst.end(); it2 != end; ++it2) {
- if ((*it2)->HasAttr(owner, self, attr, HiddenAttrNames))
- return true;
- }
- return false;
- }
-
- void GetAttrsDictionary(PyObject* owner, const TObjType& self, TMap<TString, PyObject*>& res) const {
- for (typename TGetterMap::const_iterator it = Getters.begin(), end = Getters.end(); it != end; ++it) {
- try {
- if (HasAttr(owner, self, it->first)) {
- auto attrPtr = GetAttr(owner, self, it->first);
- if (attrPtr) {
- res[it->first] = attrPtr;
- }
- if (PyErr_Occurred()) {
- PyErr_Clear(); // Skip python errors as well
- }
- }
- } catch (const std::exception&) {
- // ignore this field
- }
- }
- }
-
- void GetAttrsNames(PyObject* owner, const TObjType& self, TVector<TString>& resultNames) const {
- for (typename TGetterMap::const_iterator it = Getters.begin(), end = Getters.end(); it != end; ++it) {
- if (HasAttr(owner, self, it->first))
- resultNames.push_back(it->first);
- }
- }
- };
-
- template <typename TObjType>
- class TGenericAttrGetter: public TBaseAttrGetter<TObjType> {
- private:
- TString AttrName;
-
- public:
- TGenericAttrGetter(const TString& attrName)
- : AttrName(attrName)
- {
- }
-
- bool GetAttr(PyObject* obj, const TObjType&, const TString&, PyObject*& res) const override {
- auto str = NameFromString(AttrName);
- res = PyObject_GenericGetAttr(obj, str.Get());
- if (!res && !PyErr_Occurred())
- ythrow TPyErr(PyExc_AttributeError) << "Can't get generic attribute '" << AttrName << "'";
- return res;
- }
- };
-
- template <typename TObjType>
- class TAttrSetters {
- private:
- typedef TSimpleSharedPtr<TBaseAttrSetter<TObjType>> TSetterPtr;
- typedef TVector<TSetterPtr> TSetterList;
- typedef TMap<TString, TSetterList> TSetterMap;
-
- TSetterMap Setters;
-
- public:
- void AddSetter(const TString& attr, TSetterPtr setter) {
- Setters[attr].push_back(setter);
- }
-
- bool SetAttr(PyObject* owner, TObjType& self, const TString& attr, PyObject* val) {
- typename TSetterMap::const_iterator it1 = Setters.find(attr);
- if (it1 == Setters.end())
- it1 = Setters.find("");
- if (it1 == Setters.end())
- return false;
- const TSetterList& lst = it1->second;
- for (typename TSetterList::const_iterator it2 = lst.begin(), end = lst.end(); it2 != end; ++it2) {
- if ((*it2)->SetAttr(owner, self, attr, val))
- return true;
- }
- return false;
- }
-
- bool SetAttrDictionary(PyObject* owner, TObjType& self, TMap<TString, PyObject*>& dict) {
- for (TMap<TString, PyObject*>::const_iterator it = dict.begin(), end = dict.end(); it != end; ++it) {
- try {
- SetAttr(owner, self, it->first, it->second);
- } catch (std::exception&) {
- // ignore this field
- }
- }
-
- return true;
- }
- };
-
- /**
- * TMethodAttrGetter - this class maps Python attribute read to C++ method call
- */
- template <typename TObjType, typename TResult, typename TSubObject>
- class TMethodAttrGetter: public TBaseAttrGetter<TObjType> {
- private:
- typedef TResult (TSubObject::*TMethod)() const;
- TMethod Method;
-
- public:
- TMethodAttrGetter(TMethod method)
- : Method(method)
- {
- }
-
- bool GetAttr(PyObject*, const TObjType& self, const TString&, PyObject*& res) const override {
- const TSubObject* sub = dynamic_cast<const TSubObject*>(&self);
- if (sub == nullptr)
- return false;
- res = BuildPyObject((sub->*Method)());
- return (res != nullptr);
- }
- };
-
- template <typename TObjType, typename TFunctor>
- class TFunctorAttrGetter: public TBaseAttrGetter<TObjType> {
- TFunctor Functor;
- public:
- explicit TFunctorAttrGetter(TFunctor functor)
- : Functor(functor)
- {
- }
-
- bool GetAttr(PyObject*, const TObjType& self, const TString&, PyObject*& res) const override {
- res = BuildPyObject(Functor(self));
- return (res != nullptr);
- }
- };
-
-
- /**
- * TMethodAttrGetterWithCheck - this class maps Python attribute read to C++ HasAttr/GetAttr call
- * If HasAttr returns false, None is returned.
- * Otherwise GetAttr is called.
- */
- template <typename TObjType, typename TResult, typename TSubObject>
- class TMethodAttrGetterWithCheck: public TBaseAttrGetter<TObjType> {
- private:
- typedef TResult (TSubObject::*TMethod)() const;
- typedef bool (TSubObject::*TCheckerMethod)() const;
- TMethod Method;
- TCheckerMethod CheckerMethod;
-
- public:
- TMethodAttrGetterWithCheck(TMethod method, TCheckerMethod checkerMethod)
- : Method(method)
- , CheckerMethod(checkerMethod)
- {
- }
-
- bool GetAttr(PyObject*, const TObjType& self, const TString&, PyObject*& res) const override {
- const TSubObject* sub = dynamic_cast<const TSubObject*>(&self);
- if (sub == nullptr)
- return false;
- if ((sub->*CheckerMethod)())
- res = BuildPyObject((sub->*Method)());
- else {
- Py_INCREF(Py_None);
- res = Py_None;
- }
- return (res != nullptr);
- }
- };
-
- template <typename TObjType, typename TResult, typename TSubObject, typename TMapper>
- class TMethodAttrMappingGetter: public TBaseAttrGetter<TObjType> {
- private:
- typedef TResult (TSubObject::*TMethod)() const;
-
- TMethod Method;
- TMapper Mapper;
-
- public:
- TMethodAttrMappingGetter(TMethod method, TMapper mapper)
- : Method(method)
- , Mapper(mapper)
- {
- }
-
- bool GetAttr(PyObject*, const TObjType& self, const TString&, PyObject*& res) const override {
- const TSubObject* sub = dynamic_cast<const TSubObject*>(&self);
- if (sub == nullptr)
- return false;
- res = BuildPyObject(Mapper((sub->*Method)()));
- return (res != nullptr);
- }
- };
-
- template <typename TObjType, typename TResult, typename TSubObject, typename TMapper>
- TSimpleSharedPtr<TBaseAttrGetter<TObjType>>
- CreateMethodAttrMappingGetter(TResult (TSubObject::*method)() const,
- TMapper mapper) {
- return new TMethodAttrMappingGetter<TObjType, TResult, TSubObject, TMapper>(method,
- mapper);
- }
-
- template <typename TObjType, typename TResult, typename TValue, typename TSubObject>
- class TMethodAttrSetter: public TBaseAttrSetter<TObjType> {
- private:
- typedef TResult (TSubObject::*TMethod)(TValue&);
- TMethod Method;
-
- public:
- TMethodAttrSetter(TMethod method)
- : Method(method)
- {
- }
-
- virtual bool SetAttr(PyObject*, TObjType& self, const TString&, PyObject* val) {
- TSubObject* sub = dynamic_cast<TSubObject*>(&self);
- if (sub == nullptr)
- return false;
- TValue value;
- if (!FromPyObject(val, value))
- return false;
- (sub->*Method)(value);
- return true;
- }
- };
-
- template <typename TObjType, typename TValue, typename TFunctor>
- class TFunctorAttrSetter: public TBaseAttrSetter<TObjType> {
- TFunctor Functor;
- public:
- explicit TFunctorAttrSetter(TFunctor functor)
- : Functor(functor)
- {
- }
-
- bool SetAttr(PyObject*, TObjType& self, const TString&, PyObject* val) const override {
- TValue value;
- if (!FromPyObject(val, value))
- return false;
- auto res = BuildPyObject(Functor(self, value));
- return (res != nullptr);
- }
- };
- template <typename TObjType, typename TResult, typename TSubObject>
- TSimpleSharedPtr<TBaseAttrGetter<TObjType>> CreateMethodAttrGetter(TResult (TSubObject::*method)() const) {
- return new TMethodAttrGetter<TObjType, TResult, TSubObject>(method);
- }
-
- template <typename TObjType, typename TFunctor>
- TSimpleSharedPtr<TFunctorAttrGetter<TObjType, TFunctor>> CreateFunctorAttrGetter(TFunctor functor) {
- return MakeSimpleShared<TFunctorAttrGetter<TObjType, TFunctor>>(functor);
- }
-
- template <typename TObjType, typename TResult, typename TSubObject>
- TSimpleSharedPtr<TBaseAttrGetter<TObjType>> CreateMethodAttrGetterWithCheck(
- TResult (TSubObject::*method)() const,
- bool (TSubObject::*checkerMethod)() const) {
- return new TMethodAttrGetterWithCheck<TObjType, TResult, TSubObject>(method, checkerMethod);
- }
-
- template <typename TObjType, typename TResult, typename TValue, typename TSubObject>
- TSimpleSharedPtr<TBaseAttrSetter<TObjType>> CreateMethodAttrSetter(TResult (TSubObject::*method)(TValue&)) {
- return new TMethodAttrSetter<TObjType, TResult, TValue, TSubObject>(method);
- }
-
- template <typename TObjType, typename TFunctor, typename TValue>
- TSimpleSharedPtr<TFunctorAttrSetter<TObjType, TValue, TFunctor>> CreateFunctorAttrSetter(TFunctor functor) {
- return MakeSimpleShared<TFunctorAttrSetter<TObjType, TValue, TFunctor>>(functor);
- }
-
- template <typename TObjType, typename TValue, typename TSubObject>
- class TDirectAttrSetter: public TBaseAttrSetter<TObjType> {
- private:
- typedef TValue TSubObject::*TValueType;
- TValueType Value;
-
- public:
- TDirectAttrSetter(TValueType value)
- : Value(value)
- {
- }
-
- bool SetAttr(PyObject*, TObjType& self, const TString&, PyObject* val) override {
- TSubObject* sub = dynamic_cast<TSubObject*>(&self);
- if (sub == NULL)
- return false;
- if (!FromPyObject(val, sub->*Value))
- return false;
- return true;
- }
- };
-
- template <typename TObjType, typename TValue, typename TSubObject>
- TSimpleSharedPtr<TBaseAttrSetter<TObjType>> CreateAttrSetter(TValue TSubObject::*value) {
- return new TDirectAttrSetter<TObjType, TValue, TSubObject>(value);
- }
-
- template <typename TObjType, typename TValue, typename TSubObject>
- class TDirectAttrGetter: public TBaseAttrGetter<TObjType> {
- private:
- typedef TValue TSubObject::*TValueType;
- TValueType Value;
-
- public:
- TDirectAttrGetter(TValueType value)
- : Value(value)
- {
- }
-
- bool GetAttr(PyObject*, const TObjType& self, const TString&, PyObject*& res) const override {
- const TSubObject* sub = dynamic_cast<const TSubObject*>(&self);
- if (sub == nullptr)
- return false;
- res = BuildPyObject(sub->*Value);
- return (res != nullptr);
- }
- };
-
- template <typename TObjType, typename TValue, typename TSubObject>
- TSimpleSharedPtr<TBaseAttrGetter<TObjType>> CreateAttrGetter(TValue TSubObject::*value) {
- return new TDirectAttrGetter<TObjType, TValue, TSubObject>(value);
- }
-}
diff --git a/library/cpp/pybind/cast.cpp b/library/cpp/pybind/cast.cpp
deleted file mode 100644
index 60a44b0e83..0000000000
--- a/library/cpp/pybind/cast.cpp
+++ /dev/null
@@ -1,324 +0,0 @@
-#include "cast.h"
-#include <util/generic/yexception.h>
-#include <util/generic/buffer.h>
-
-namespace NPyBind {
- PyObject* GetTrueRef(bool incref) {
- if (incref)
- Py_RETURN_TRUE;
- return Py_True;
- }
-
- PyObject* GetFalseRef(bool incref) {
- if (incref)
- Py_RETURN_FALSE;
- return Py_False;
- }
-
- PyObject* BuildPyObject(int val) {
- return Py_BuildValue("i", val);
- }
-
- PyObject* BuildPyObject(unsigned int val) {
- return Py_BuildValue("I", val);
- }
-
- PyObject* BuildPyObject(long int val) {
- return Py_BuildValue("l", val);
- }
-
- PyObject* BuildPyObject(unsigned long int val) {
- return Py_BuildValue("k", val);
- }
-
-#ifdef PY_LONG_LONG
- PyObject* BuildPyObject(PY_LONG_LONG val) {
- return Py_BuildValue("L", val);
- }
-
- PyObject* BuildPyObject(unsigned PY_LONG_LONG val) {
- return Py_BuildValue("K", val);
- }
-#endif
-
- PyObject* BuildPyObject(float val) {
- return Py_BuildValue("f", val);
- }
-
- PyObject* BuildPyObject(double val) {
- return Py_BuildValue("d", val);
- }
-
- PyObject* BuildPyObject(const TStringBuf& val) {
- if (!val.IsInited())
- Py_RETURN_NONE;
-
- PyObject* stringValue = Py_BuildValue("s#", val.data(), static_cast<int>(val.length()));
- if (stringValue != nullptr) {
- return stringValue;
- }
- if (PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) {
- PyErr_Clear();
- } else {
- return nullptr;
- }
- return Py_BuildValue("y#", val.data(), static_cast<int>(val.length()));
- }
-
- PyObject* BuildPyObject(const char* val) {
- if (val == nullptr)
- Py_RETURN_NONE;
- PyObject* stringValue = Py_BuildValue("s#", val, static_cast<int>(strlen(val)));
- if (stringValue != nullptr) {
- return stringValue;
- }
- if (PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) {
- PyErr_Clear();
- } else {
- return nullptr;
- }
- return Py_BuildValue("y#", val, static_cast<int>(strlen(val)));
- }
-
- PyObject* BuildPyObject(const TWtringBuf& val) {
- if (!val.IsInited())
- Py_RETURN_NONE;
-#if PY_VERSION_HEX < 0x03030000
- TPyObjectPtr result(PyUnicode_FromUnicode(nullptr, val.size()), true);
- Py_UNICODE* buf = PyUnicode_AS_UNICODE(result.Get());
- if (buf == nullptr)
- Py_RETURN_NONE;
- for (size_t i = 0; i < val.size(); ++i) {
- buf[i] = static_cast<Py_UNICODE>(val[i]);
- }
-#else
- PyObject* unicodeValue = PyUnicode_FromKindAndData(PyUnicode_2BYTE_KIND, val.data(), val.size());
- if (unicodeValue == nullptr)
- Py_RETURN_NONE;
- TPyObjectPtr result(unicodeValue, true);
-#endif
- return result.RefGet();
- }
-
- PyObject* BuildPyObject(const TBuffer& val) {
- TPyObjectPtr res(PyList_New(val.size()), true);
- for (size_t i = 0, size = val.Size(); i < size; ++i)
- PyList_SetItem(res.Get(), i, BuildPyObject(val.Data()[i]));
- return res.RefGet();
- }
-
- PyObject* BuildPyObject(bool val) {
- if (val)
- Py_RETURN_TRUE;
- else
- Py_RETURN_FALSE;
- }
-
- PyObject* BuildPyObject(PyObject* val) {
- Py_XINCREF(val);
- return val;
- }
-
- PyObject* BuildPyObject(TPyObjectPtr ptr) {
- return ptr.RefGet();
- }
-
- /* python represents (http://docs.python.org/c-api/arg.html#Py_BuildValue)
- * char, uchar, short, ushort, int, long as PyInt
- * uint, ulong as PyInt or PyLong (if exceeds sys.maxint)
- * longlong, ulonglong as PyLong
- */
-
- template <>
- bool FromPyObject(PyObject* obj, long& res) {
- if (PyLong_Check(obj)) {
- res = PyLong_AsLong(obj);
- return true;
- }
- if (PyFloat_Check(obj)) {
- res = static_cast<long>(PyFloat_AsDouble(obj));
- return true;
- }
-#if PY_MAJOR_VERSION < 3
- res = PyInt_AsLong(obj);
-#endif
- return -1 != res || !PyErr_Occurred();
- }
-
- template <>
- bool FromPyObject(PyObject* obj, unsigned long& res) {
- long lres;
- if (!FromPyObject(obj, lres))
- return false;
- if (lres < 0)
- return false;
- res = static_cast<unsigned long long>(lres);
- return true;
- }
-
- template <>
- bool FromPyObject(PyObject* obj, int& res) {
- long lres;
- if (!FromPyObject(obj, lres))
- return false;
- res = static_cast<int>(lres);
- return true;
- }
-
- template <>
- bool FromPyObject(PyObject* obj, unsigned char& res) {
- long lres;
- if (!FromPyObject(obj, lres))
- return false;
- res = static_cast<unsigned char>(lres);
- return true;
- }
-
- template <>
- bool FromPyObject(PyObject* obj, char& res) {
- long lres;
- if (!FromPyObject(obj, lres))
- return false;
- res = static_cast<char>(lres);
- return true;
- }
-
- template <>
- bool FromPyObject(PyObject* obj, unsigned int& res) {
- unsigned long lres;
- if (!FromPyObject(obj, lres))
- return false;
- res = static_cast<unsigned int>(lres);
- return true;
- }
-
-#ifdef HAVE_LONG_LONG
- template <>
- bool FromPyObject(PyObject* obj, long long& res) {
- if (PyLong_Check(obj)) {
- res = PyLong_AsLongLong(obj);
- return -1 != res || !PyErr_Occurred();
- }
- long lres;
- if (!FromPyObject(obj, lres))
- return false;
- res = static_cast<long long>(lres);
- return true;
- }
-
- template <>
- bool FromPyObject(PyObject* obj, unsigned long long& res) {
- if (PyLong_Check(obj)) {
- res = PyLong_AsUnsignedLongLong(obj);
- return static_cast<unsigned long long>(-1) != res || !PyErr_Occurred();
- }
- long lres;
- if (!FromPyObject(obj, lres))
- return false;
- res = static_cast<unsigned long long>(lres);
- return true;
- }
-#endif
-
- template <>
- bool FromPyObject(PyObject* obj, double& res) {
- if (PyFloat_Check(obj)) {
- res = PyFloat_AsDouble(obj);
- return true;
- }
- long long lres;
- if (!FromPyObject(obj, lres))
- return false;
- res = static_cast<double>(lres);
- return true;
- }
-
- template <>
- bool FromPyObject(PyObject* obj, float& res) {
- double dres;
- if (!FromPyObject(obj, dres))
- return false;
- res = static_cast<float>(dres);
- return true;
- }
-
- template <>
- bool FromPyObject(PyObject* obj, bool& res) {
- if (!PyBool_Check(obj))
- return false;
- if (obj == Py_True)
- res = true;
- else
- res = false;
- return true;
- }
-
- template <>
- bool FromPyObject(PyObject* obj, PyObject*& res) {
- Py_XINCREF(obj);
- res = obj;
- return true;
- }
-
- template <>
- bool FromPyObject(PyObject* obj, TPyObjectPtr& res) {
- res = TPyObjectPtr(obj);
- return true;
- }
-
- static inline bool _FromPyObject(PyObject* obj, TStringBuf& res) {
- char* str;
- Py_ssize_t len;
-#if PY_MAJOR_VERSION >= 3
- if (PyUnicode_Check(obj)) {
- auto buf = PyUnicode_AsUTF8AndSize(obj, &len);
- res = TStringBuf(buf, len);
- return true;
- }
-#endif
- if (-1 == PyBytes_AsStringAndSize(obj, &str, &len) || 0 > len)
- return false;
- res = TStringBuf(str, len);
- return true;
- }
-
- bool FromPyObject(PyObject* obj, TStringBuf& res) {
- return _FromPyObject(obj, res);
- }
-
- bool FromPyObject(PyObject* obj, TString& res) {
- TStringBuf str;
- if (!_FromPyObject(obj, str))
- return false;
- res = str;
- return true;
- }
-
- bool FromPyObject(PyObject* obj, TUtf16String& res) {
- if (!PyUnicode_Check(obj))
- return false;
- auto str = TPyObjectPtr(PyUnicode_AsUTF16String(obj), true);
- if (!str)
- return false;
- constexpr auto BOM_SIZE = 2;
- size_t len = (static_cast<size_t>(PyBytes_GET_SIZE(str.Get())) - BOM_SIZE) / 2;
- res.resize(len);
- memcpy(res.begin(), PyBytes_AS_STRING(str.Get()) + BOM_SIZE, len * 2);
- return (nullptr == PyErr_Occurred());
- }
-
- bool FromPyObject(PyObject* obj, TBuffer& res) {
- if (!PyList_Check(obj))
- return false;
- size_t cnt = PyList_Size(obj);
- res.Reserve(cnt);
- for (size_t i = 0; i < cnt; ++i) {
- PyObject* item = PyList_GET_ITEM(obj, i);
- char ch = 0;
- if (!FromPyObject(item, ch))
- return false;
- res.Append(ch);
- }
- return true;
- }
-}
diff --git a/library/cpp/pybind/cast.h b/library/cpp/pybind/cast.h
deleted file mode 100644
index 1f3d7d8366..0000000000
--- a/library/cpp/pybind/cast.h
+++ /dev/null
@@ -1,373 +0,0 @@
-#pragma once
-
-#define PY_SSIZE_T_CLEAN
-#include <Python.h>
-#include <util/generic/strbuf.h>
-#include <util/generic/vector.h>
-#include <util/generic/set.h>
-#include <util/generic/yexception.h>
-#include <util/generic/hash.h>
-#include <util/generic/map.h>
-#include <util/generic/maybe.h>
-#include <utility>
-#include <initializer_list>
-#include "ptr.h"
-
-namespace NPyBind {
- PyObject* GetTrueRef(bool incref = true);
- PyObject* GetFalseRef(bool incref = true);
-
- PyObject* BuildPyObject(int val);
- PyObject* BuildPyObject(unsigned int val);
- PyObject* BuildPyObject(long int val);
- PyObject* BuildPyObject(unsigned long int val);
-#ifdef PY_LONG_LONG
- PyObject* BuildPyObject(PY_LONG_LONG val);
- PyObject* BuildPyObject(unsigned PY_LONG_LONG val);
-#endif
- PyObject* BuildPyObject(float val);
- PyObject* BuildPyObject(double val);
- PyObject* BuildPyObject(const TStringBuf& val);
- PyObject* BuildPyObject(const char* val);
- PyObject* BuildPyObject(const TWtringBuf& val);
- PyObject* BuildPyObject(const TBuffer& val);
- PyObject* BuildPyObject(bool val);
- PyObject* BuildPyObject(PyObject*);
- PyObject* BuildPyObject(TPyObjectPtr);
-
- template <typename T>
- PyObject* BuildPyObject(const TVector<T>& val);
-
- template <typename T>
- PyObject* BuildPyObject(const TSet<T>& val);
-
- template <typename TKey, typename TVal>
- PyObject* BuildPyObject(const THashMap<TKey, TVal>& val);
-
- template <typename T1, typename T2>
- PyObject* BuildPyObject(const std::pair<T1, T2>& val) {
- TPyObjectPtr first(BuildPyObject(val.first), true);
- if (!first) {
- return nullptr;
- }
- TPyObjectPtr second(BuildPyObject(val.second), true);
- if (!first || !second) {
- return nullptr;
- }
- TPyObjectPtr res(PyList_New(2), true);
- PyList_SetItem(res.Get(), 0, first.RefGet());
- PyList_SetItem(res.Get(), 1, second.RefGet());
- return res.RefGet();
- }
-
- template <typename T>
- PyObject* BuildPyObject(const TVector<T>& val) {
- TPyObjectPtr res(PyList_New(val.size()), true);
- for (size_t i = 0, size = val.size(); i < size; ++i) {
- auto pythonVal = BuildPyObject(std::move(val[i]));
- if (!pythonVal) {
- return nullptr;
- }
- PyList_SetItem(res.Get(), i, pythonVal);
- }
- return res.RefGet();
- }
-
- template <typename T>
- PyObject* BuildPyObject(TVector<T>&& val) {
- TPyObjectPtr res(PyList_New(val.size()), true);
- for (size_t i = 0, size = val.size(); i < size; ++i) {
- auto pythonVal = BuildPyObject(std::move(val[i]));
- if (!pythonVal) {
- return nullptr;
- }
- PyList_SetItem(res.Get(), i, pythonVal);
- }
- return res.RefGet();
- }
-
- template <typename T>
- PyObject* BuildPyObject(const TSet<T>& val) {
- TPyObjectPtr res(PySet_New(nullptr), true);
- for (const auto& v : val) {
- auto pythonVal = BuildPyObject(std::move(v));
- if (!pythonVal) {
- return nullptr;
- }
- PySet_Add(res.Get(), pythonVal);
- }
- return res.RefGet();
- }
-
- template <typename T>
- PyObject* BuildPyObject(const THashSet<T>& val) {
- TPyObjectPtr res(PySet_New(nullptr), true);
- for (const auto& v : val) {
- auto pythonVal = BuildPyObject(std::move(v));
- if (!pythonVal) {
- return nullptr;
- }
- PySet_Add(res.Get(), pythonVal);
- }
- return res.RefGet();
- }
-
- template <typename TKey, typename TVal>
- PyObject* BuildPyObject(const THashMap<TKey, TVal>& val) {
- TPyObjectPtr res(PyDict_New(), true);
- for (typename THashMap<TKey, TVal>::const_iterator it = val.begin(), end = val.end(); it != end; ++it) {
- auto prevOccurred = PyErr_Occurred();
- Y_UNUSED(prevOccurred);
- TPyObjectPtr k(BuildPyObject(it->first), true);
- if (!k) {
- return nullptr;
- }
- TPyObjectPtr v(BuildPyObject(it->second), true);
- if (!v) {
- return nullptr;
- }
- PyDict_SetItem(res.Get(), k.Get(), v.Get());
- }
- return res.RefGet();
- }
-
- template <typename TKey, typename TVal>
- PyObject* BuildPyObject(const TMap<TKey, TVal>& val) {
- TPyObjectPtr res(PyDict_New(), true);
- for (typename TMap<TKey, TVal>::const_iterator it = val.begin(), end = val.end(); it != end; ++it) {
- TPyObjectPtr k(BuildPyObject(it->first), true);
- if (!k) {
- return nullptr;
- }
- TPyObjectPtr v(BuildPyObject(it->second), true);
- if (!v) {
- return nullptr;
- }
- PyDict_SetItem(res.Get(), k.Get(), v.Get());
- }
- return res.RefGet();
- }
-
-
- template <typename TKey, typename TVal>
- PyObject* BuildPyObject(const TMultiMap<TKey, TVal>& val) {
- TPyObjectPtr res(PyDict_New(), true);
- TMaybe<TKey> prevKey;
- TPyObjectPtr currentEntry(PyList_New(0), true);
- for (const auto& [key, value]: val) {
- if (prevKey.Defined() && prevKey != key) {
- TPyObjectPtr pyPrevKey(BuildPyObject(*prevKey), true);
- if (!pyPrevKey) {
- return nullptr;
- }
- PyDict_SetItem(res.Get(), pyPrevKey.Get(), currentEntry.Get());
- currentEntry = TPyObjectPtr(PyList_New(0), true);
- }
- TPyObjectPtr pyValue(BuildPyObject(value), true);
- if (!pyValue) {
- return nullptr;
- }
- PyList_Append(currentEntry.Get(), pyValue.Get());
- prevKey = key;
- }
-
- if (prevKey.Defined()) {
- TPyObjectPtr pyPrevKey(BuildPyObject(*prevKey), true);
- if (!pyPrevKey) {
- return nullptr;
- }
- PyDict_SetItem(res.Get(), pyPrevKey.Get(), currentEntry.Get());
- }
- return res.RefGet();
- }
-
- template <typename T>
- PyObject* BuildPyObject(const TMaybe<T>& val) {
- if (!val.Defined())
- Py_RETURN_NONE;
- return BuildPyObject(val.GetRef());
- }
-
- template <typename T, typename C, typename D>
- PyObject* BuildPyObject(const TSharedPtr<T, C, D>& val) {
- if (!val.Get())
- Py_RETURN_NONE;
- return BuildPyObject(*val.Get());
- }
-
- template <typename T>
- bool FromPyObject(PyObject* obj, T& res);
-
- bool FromPyObject(PyObject* obj, TString& res);
- bool FromPyObject(PyObject* obj, TStringBuf& res);
- bool FromPyObject(PyObject* obj, TUtf16String& res);
- bool FromPyObject(PyObject* obj, TBuffer& res);
-
- template <typename T>
- bool FromPyObject(PyObject* obj, TMaybe<T>& res) {
- //we need to save current error before trying derserialize the value
- //because it can produce conversion errors in python that we don't need to handle
- struct TError {
- public:
- TError() {
- PyErr_Fetch(&Type, &Value, &Traceback);
- }
- ~TError() {
- PyErr_Restore(Type, Value, Traceback);
-
- }
- private:
- PyObject* Type = nullptr;
- PyObject* Value = nullptr;
- PyObject* Traceback = nullptr;
- } currentPyExcInfo;
- T val;
- if (FromPyObject(obj, val)) {
- res = val;
- return true;
- }
- if (obj == Py_None) {
- res = Nothing();
- return true;
- }
- return false;
- }
-
- template <typename T1, typename T2>
- bool FromPyObject(PyObject* obj, std::pair<T1, T2>& res) {
- PyObject* first;
- PyObject* second;
- if (PyTuple_Check(obj) && 2 == PyTuple_Size(obj)) {
- first = PyTuple_GET_ITEM(obj, 0);
- second = PyTuple_GET_ITEM(obj, 1);
- } else if (PyList_Check(obj) && 2 == PyList_Size(obj)) {
- first = PyList_GET_ITEM(obj, 0);
- second = PyList_GET_ITEM(obj, 1);
- } else {
- return false;
- }
- return FromPyObject(first, res.first) && FromPyObject(second, res.second);
- }
-
- template <typename T>
- bool FromPyObject(PyObject* obj, TVector<T>& res) {
- if (!PyList_Check(obj))
- return false;
- size_t cnt = PyList_Size(obj);
- res.resize(cnt);
- for (size_t i = 0; i < cnt; ++i) {
- PyObject* item = PyList_GET_ITEM(obj, i);
- if (!FromPyObject(item, res[i]))
- return false;
- }
- return true;
- }
-
- template <typename K, typename V>
- bool FromPyObject(PyObject* obj, THashMap<K, V>& res) {
- if (!PyDict_Check(obj))
- return false;
- TPyObjectPtr list(PyDict_Keys(obj), true);
- size_t cnt = PyList_Size(list.Get());
- for (size_t i = 0; i < cnt; ++i) {
- PyObject* key = PyList_GET_ITEM(list.Get(), i);
- PyObject* value = PyDict_GetItem(obj, key);
- K rkey;
- V rvalue;
- if (!FromPyObject(key, rkey))
- return false;
- if (!FromPyObject(value, rvalue))
- return false;
- res[rkey] = rvalue;
- }
- return true;
- }
-
- template <typename K, typename V>
- bool FromPyObject(PyObject* obj, TMap<K, V>& res) {
- if (!PyDict_Check(obj))
- return false;
- TPyObjectPtr list(PyDict_Keys(obj), true);
- size_t cnt = PyList_Size(list.Get());
- for (size_t i = 0; i < cnt; ++i) {
- PyObject* key = PyList_GET_ITEM(list.Get(), i);
- PyObject* value = PyDict_GetItem(obj, key);
- K rkey;
- V rvalue;
- if (!FromPyObject(key, rkey))
- return false;
- if (!FromPyObject(value, rvalue))
- return false;
- res[rkey] = rvalue;
- }
- return true;
- }
-
- class cast_exception: public TBadCastException {
- };
-
- template <typename T>
- T FromPyObject(PyObject* obj) {
- T res;
- if (!FromPyObject(obj, res))
- ythrow cast_exception() << "Cannot cast argument to " << TypeName<T>();
- return res;
- }
-
- template <class... Args, std::size_t... I>
- bool ExtractArgs(std::index_sequence<I...>, PyObject* args, Args&... outArgs) {
- if (!args || !PyTuple_Check(args) || PyTuple_Size(args) != sizeof...(Args))
- return false;
- bool res = true;
- (void)std::initializer_list<bool>{(res = res && NPyBind::FromPyObject(PyTuple_GET_ITEM(args, I), outArgs))...};
- return res;
- }
-
- template <class... Args>
- bool ExtractArgs(PyObject* args, Args&... outArgs) {
- return ExtractArgs(std::index_sequence_for<Args...>(), args, outArgs...);
- }
-
- template <class... Args, std::size_t... I>
- bool ExtractOptionalArgs(std::index_sequence<I...>, PyObject* args, PyObject* kwargs, const char* keywords[], Args&... outArgs) {
- PyObject* pargs[sizeof...(Args)] = {};
- static const char format[sizeof...(Args) + 2] = {'|', ((void)I, 'O')..., 0};
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, const_cast<char**>(keywords), &pargs[I]...))
- return false;
- bool res = true;
- (void)std::initializer_list<bool>{(res = res && (!pargs[I] || NPyBind::FromPyObject(pargs[I], outArgs)))...};
- return res;
- }
-
- template <class... Args>
- bool ExtractOptionalArgs(PyObject* args, PyObject* kwargs, const char* keywords[], Args&... outArgs) {
- return ExtractOptionalArgs(std::index_sequence_for<Args...>(), args, kwargs, keywords, outArgs...);
- }
-
- template <typename... Args, std::size_t... I>
- static auto GetArguments(std::index_sequence<I...>, PyObject* args) {
- Y_UNUSED(args); // gcc bug
- return std::make_tuple(FromPyObject<std::remove_cv_t<std::remove_reference_t<Args>>>(PyTuple_GetItem(args, I))...);
- }
-
- template <typename... Args>
- static auto GetArguments(PyObject* args) {
- return GetArguments<Args...>(std::index_sequence_for<Args...>(), args);
- }
-
- inline PyObject* ReturnString(TStringBuf s) {
-#if PY_MAJOR_VERSION >= 3
- return PyUnicode_FromStringAndSize(s.data(), s.size());
-#else
- return PyBytes_FromStringAndSize(s.data(), s.size());
-#endif
- }
-
- inline TPyObjectPtr ReturnBytes(TStringBuf s) {
- return TPyObjectPtr(PyBytes_FromStringAndSize(s.data(), s.size()), true);
- }
-
- inline TPyObjectPtr NameFromString(TStringBuf s) {
- return TPyObjectPtr(ReturnString(s), true);
- }
-}
diff --git a/library/cpp/pybind/embedding.cpp b/library/cpp/pybind/embedding.cpp
deleted file mode 100644
index cf8941a92a..0000000000
--- a/library/cpp/pybind/embedding.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-#define PY_SSIZE_T_CLEAN
-#include <Python.h>
-
-#include "embedding.h"
-
-#include <util/generic/ptr.h>
-#include <util/generic/yexception.h>
-
-namespace NPyBind {
-#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 8
- class TDeleteRawMem {
- public:
- template <typename T>
- static inline void Destroy(T* t) noexcept {
- PyMem_RawFree(t);
- }
- };
-
- template <typename T>
- using TRawMemHolder = THolder<T, TDeleteRawMem>;
-
- static void SetProgramName(char* name) {
- TRawMemHolder<wchar_t> wideName(Py_DecodeLocale(name, nullptr));
- Y_ENSURE(wideName);
- Py_SetProgramName(wideName.Get());
- }
-#endif
-
- TEmbedding::TEmbedding(char* argv0) {
-#if PY_MAJOR_VERSION < 3
- Py_SetProgramName(argv0);
- Py_Initialize();
-#elif PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 8
- PyStatus status;
-
- PyConfig config;
- PyConfig_InitPythonConfig(&config);
- // Disable parsing command line arguments
- config.parse_argv = 0;
-
- status = PyConfig_SetBytesString(&config, &config.program_name, argv0);
- if (PyStatus_Exception(status)) {
- PyConfig_Clear(&config);
- Py_ExitStatusException(status);
- }
-
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- PyConfig_Clear(&config);
- Py_ExitStatusException(status);
- }
-
- PyConfig_Clear(&config);
-#elif PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 8
- SetProgramName(argv0);
- Py_Initialize();
-#endif
- }
-
- TEmbedding::~TEmbedding() {
- Py_Finalize();
- }
-}
diff --git a/library/cpp/pybind/embedding.h b/library/cpp/pybind/embedding.h
deleted file mode 100644
index 18553d9f6c..0000000000
--- a/library/cpp/pybind/embedding.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-
-namespace NPyBind {
- class TEmbedding {
- public:
- TEmbedding(char* argv0);
- ~TEmbedding();
- };
-
-}
diff --git a/library/cpp/pybind/empty.cpp b/library/cpp/pybind/empty.cpp
deleted file mode 100644
index 10da997ecc..0000000000
--- a/library/cpp/pybind/empty.cpp
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "init.h"
-#include "v2.h"
diff --git a/library/cpp/pybind/exceptions.cpp b/library/cpp/pybind/exceptions.cpp
deleted file mode 100644
index db1531fc63..0000000000
--- a/library/cpp/pybind/exceptions.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-#include "exceptions.h"
-#include "cast.h"
-#include "module.h"
-#include <util/generic/algorithm.h>
-
-namespace NPyBind {
-
- namespace NPrivate {
- TPyObjectPtr CreatePyBindModule() {
- return TPyObjectPtr(TExceptionsHolder::DoInitPyBindModule(), true);
- }
- }//NPrivate
-
- TPyObjectPtr TExceptionsHolder::GetException(const TString& name) {
- if (name == "")
- return TPyObjectPtr(nullptr);
- if (!Exceptions[name].Get())
- ythrow yexception() << "Wrong base class '" << name << "'";
- return Exceptions[name];
- }
-
- TPyObjectPtr TExceptionsHolder::GetExceptions(const TVector<TString>& names) {
- TVector<TString> tmp(names.begin(), names.end());
- TVector<TString>::iterator end = std::unique(tmp.begin(), tmp.end());
- TPyObjectPtr tuple(PyTuple_New(std::distance(tmp.begin(), end)), true);
- for (size_t i = 0; i < (size_t)std::distance(tmp.begin(), end); ++i) {
- if (!Exceptions[tmp[i]].Get())
- ythrow yexception() << "Wrong base class '" << tmp[i] << "'";
- PyTuple_SetItem(tuple.Get(), i, Exceptions[tmp[i]].Get());
- }
- return tuple;
- }
-
- // def PyBindObjectReconstructor(cl, props):
- // return cl(__properties__=props)
- static PyObject* PyBindObjectReconstructor(PyObject*, PyObject* args) {
- TPyObjectPtr callable, props;
- if (!ExtractArgs(args, callable, props))
- ythrow yexception() << "Wrong method arguments";
-#if PY_MAJOR_VERSION >= 3
- TPyObjectPtr noArgs(PyTuple_New(0), true);
-#else
- TPyObjectPtr noArgs(PyList_New(0), true);
-#endif
- TPyObjectPtr kw(PyDict_New(), true);
- PyDict_SetItemString(kw.Get(), "__properties__", props.Get());
- TPyObjectPtr res(PyObject_Call(callable.Get(), noArgs.Get(), kw.Get()), true);
- return res.RefGet();
- }
-
- static PyMethodDef PyBindMethods[] = {
- {"PyBindObjectReconstructor", PyBindObjectReconstructor, METH_VARARGS, "Tech method. It's required for unpickling."},
- {nullptr, nullptr, 0, nullptr}};
-
-#if PY_MAJOR_VERSION >= 3
- static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "pybind",
- NULL,
- -1,
- PyBindMethods,
- NULL, NULL, NULL, NULL
- };
-
- static PyObject* InitPyBind() {
- return PyModule_Create(&moduledef);
- }
-#else
- static PyObject* InitPyBind() {
- return Py_InitModule("pybind", PyBindMethods);
- }
-#endif
-
- void TExceptionsHolder::DoInitPyBindModule2() {
- DoInitPyBindModule();
- }
-
- PyObject* TExceptionsHolder::DoInitPyBindModule() {
- Instance().Module = NPyBind::TPyObjectPtr(InitPyBind(), true);
- if (!Instance().Module.Get())
- return nullptr;
-
- for (TCheckersVector::const_iterator it = Instance().Checkers.begin(), end = Instance().Checkers.end(); it != end; ++it) {
- TString name = (*it)->GetName();
- if (!!name) {
- //Ref to the object should be incremented before passing to AddObject
- auto res = PyModule_AddObject(Instance().Module.Get(), name.data(), (*it)->GetException().RefGet());
- if (res < 0) {
- ythrow yexception() << "Failed to add object " << name << " to internal module pybind";
- }
- }
- }
- return Instance().Module.RefGet();
- }
-
- void TExceptionsHolder::Clear() {
- //Unfortunately in Python3 we can't retrack this object because of PyError_NewException
- //it's only the safe way to preserve GC gens in valid state during the finalization
- for (auto& ptr: Checkers) {
- if (!dynamic_cast<const TPyErrExceptionsChecker*>(ptr.Get())) { // no need to untrack standard PyExc_* exceptions from TPyErrExceptionsChecker
- if (auto exceptionPtr = ptr->GetException()) {
- PyObject_GC_UnTrack(exceptionPtr.Get());
- }
- }
- }
- Checkers.clear();
- Exceptions.clear();
- Module.Drop();
- }
-
- TExceptionsHolder::TExceptionsHolder() {
- AddException<std::exception>("yexception");
- AddException<TSystemError>("TSystemError", "yexception");
- AddException<TIoException>("TIoException", "yexception");
-
- TVector<TString> names(2);
- names[0] = "TSystemError";
- names[1] = "TIoException";
-
- AddException<TIoSystemError>("TIoSystemError", names);
- AddException<TFileError>("TFileError", "TIoSystemError");
- AddException<TBadCastException>("TBadCastException", "yexception");
-
- Checkers.push_back(new TPyErrExceptionsChecker);
-
- // XXX: In Python 2.6, PyImport_AppendInittab() function takes non-const char*, this causes
- // "ISO C++11 does not allow conversion from string literal to 'char *'" warning.
- static char pybind[] = "pybind";
-#if PY_MAJOR_VERSION >= 3
- PyImport_AppendInittab(pybind, DoInitPyBindModule);
-
- NPrivate::AddFinalizationCallBack([this]() {
- Clear();
- });
-#else
- PyImport_AppendInittab(pybind, DoInitPyBindModule2);
-#endif
- }
-
- NPyBind::TPyObjectPtr TExceptionsHolder::ToPyException(const std::exception& ex) {
- for (TCheckersVector::const_reverse_iterator it = Checkers.rbegin(), end = Checkers.rend(); it != end; ++it) {
- if ((*it)->Check(ex))
- return (*it)->GetException();
- }
- return TPyObjectPtr(nullptr);
- }
-}
diff --git a/library/cpp/pybind/exceptions.h b/library/cpp/pybind/exceptions.h
deleted file mode 100644
index 48e20995e4..0000000000
--- a/library/cpp/pybind/exceptions.h
+++ /dev/null
@@ -1,143 +0,0 @@
-#pragma once
-
-#define PY_SSIZE_T_CLEAN
-#include <Python.h>
-#include <util/generic/yexception.h>
-#include <util/generic/map.h>
-#include <util/generic/vector.h>
-#include "ptr.h"
-
-namespace NPyBind {
- // Usage:
- // ythrow TPyErr(PyExc_TypeError) << "some python type error somewhere in your C++ code";
- //
- class TPyErr: public virtual yexception {
- public:
- TPyErr(PyObject* theException = PyExc_RuntimeError)
- : Exception(theException)
- {
- }
-
- TPyObjectPtr GetException() const {
- return Exception;
- }
-
- private:
- NPyBind::TPyObjectPtr Exception;
- };
-
- //Private api for creating PyBind python module
- //Needs only for overriding pybind python module in library which imports other pybind library
- namespace NPrivate {
- TPyObjectPtr CreatePyBindModule();
- }//NPrivate
- class TExceptionsHolder {
- friend TPyObjectPtr NPrivate::CreatePyBindModule();
- private:
- TExceptionsHolder(const TExceptionsHolder&);
- TExceptionsHolder& operator=(const TExceptionsHolder&);
- TExceptionsHolder();
-
- void Clear();
- TPyObjectPtr GetException(const TString&);
- TPyObjectPtr GetExceptions(const TVector<TString>&);
- private:
- class TExceptionsChecker {
- public:
- virtual ~TExceptionsChecker() {
- }
- virtual bool Check(const std::exception& ex) const = 0;
- virtual TString GetName() const = 0;
- virtual TPyObjectPtr GetException() const = 0;
- };
-
- template <typename TExcType>
- class TConcreteExceptionsChecker: public TExceptionsChecker {
- private:
- TString Name;
- TPyObjectPtr Exception;
-
- public:
- TConcreteExceptionsChecker(const TString& name, TPyObjectPtr exception)
- : Name(name)
- , Exception(exception)
- {
- }
-
- bool Check(const std::exception& ex) const override {
- const std::exception* e = &ex;
- return dynamic_cast<const TExcType*>(e);
- }
-
- TString GetName() const override {
- return Name;
- }
-
- TPyObjectPtr GetException() const override {
- return Exception;
- }
- };
-
- class TPyErrExceptionsChecker: public TExceptionsChecker {
- private:
- mutable TPyObjectPtr Exception;
-
- public:
- TPyErrExceptionsChecker() {
- }
-
- bool Check(const std::exception& ex) const override {
- const TPyErr* err = dynamic_cast<const TPyErr*>(&ex);
- if (err) {
- Exception = err->GetException();
- }
- return err != nullptr;
- }
-
- TString GetName() const override {
- return TString();
- }
-
- TPyObjectPtr GetException() const override {
- return Exception;
- }
- };
-
- typedef TSimpleSharedPtr<TExceptionsChecker> TCheckerPtr;
- typedef TVector<TCheckerPtr> TCheckersVector;
- typedef TMap<TString, TPyObjectPtr> TExceptionsMap;
-
- TPyObjectPtr Module;
- TCheckersVector Checkers;
- TExceptionsMap Exceptions;
-
- static PyObject* DoInitPyBindModule();
- static void DoInitPyBindModule2();
-
- public:
- static TExceptionsHolder& Instance() {
- static TExceptionsHolder Holder;
- return Holder;
- }
-
- template <typename TExcType>
- void AddException(const TString& name, const TString& base = "") {
- TPyObjectPtr baseException(GetException(base));
- TString fullName = TString("pybind.") + name;
- TPyObjectPtr exception(PyErr_NewException(const_cast<char*>(fullName.c_str()), baseException.Get(), nullptr), true);
- Checkers.push_back(new TConcreteExceptionsChecker<TExcType>(name, exception));
- Exceptions[name] = exception;
- }
-
- template <typename TExcType>
- void AddException(const TString& name, const TVector<TString>& bases) {
- TPyObjectPtr baseExceptions(GetExceptions(bases));
- TString fullName = TString("pybind.") + name;
- TPyObjectPtr exception(PyErr_NewException(const_cast<char*>(fullName.c_str()), baseExceptions.Get(), nullptr), true);
- Checkers.push_back(new TConcreteExceptionsChecker<TExcType>(name, exception));
- Exceptions[name] = exception;
- }
-
- NPyBind::TPyObjectPtr ToPyException(const std::exception&);
- };
-}
diff --git a/library/cpp/pybind/init.h b/library/cpp/pybind/init.h
deleted file mode 100644
index 58874574ed..0000000000
--- a/library/cpp/pybind/init.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#pragma once
-
-#define PY_SSIZE_T_CLEAN
-#include <Python.h>
-
-#include "ptr.h"
-
-namespace NPyBind {
-#if PY_MAJOR_VERSION >= 3
-
-#define PYBIND_MODINIT(name) PyMODINIT_FUNC PyInit_##name()
-
- inline PyObject* ModInitReturn(TPyObjectPtr&& modptr) {
- return modptr.Release();
- }
-
-#else
-
-#define PYBIND_MODINIT(name) PyMODINIT_FUNC init##name()
-
- inline void ModInitReturn(TPyObjectPtr&&) {
- }
-
-#endif
-}
diff --git a/library/cpp/pybind/method.h b/library/cpp/pybind/method.h
deleted file mode 100644
index 7c1f6e90e1..0000000000
--- a/library/cpp/pybind/method.h
+++ /dev/null
@@ -1,439 +0,0 @@
-#pragma once
-
-#define PY_SSIZE_T_CLEAN
-#include <Python.h>
-#include <util/generic/string.h>
-#include <util/generic/map.h>
-#include <util/generic/set.h>
-#include <util/generic/vector.h>
-#include <util/generic/ptr.h>
-#include <util/generic/typetraits.h>
-
-#include <util/generic/function.h>
-
-#include "cast.h"
-
-namespace NPyBind {
- template <typename TObjType>
- class TBaseMethodCaller {
- public:
- virtual ~TBaseMethodCaller() {
- }
- virtual bool CallMethod(PyObject* owner, TObjType* self, PyObject* args, PyObject* kwargs, PyObject*& res) const = 0;
- virtual bool HasMethod(PyObject*, TObjType*, const TString&, const TSet<TString>&) {
- return true;
- }
- };
-
- template <typename TObjType>
- class TIsACaller;
-
- template <typename TObjType>
- class TMethodCallers {
- private:
- typedef TSimpleSharedPtr<TBaseMethodCaller<TObjType>> TCallerPtr;
- typedef TVector<TCallerPtr> TCallerList;
- typedef TMap<TString, TCallerList> TCallerMap;
-
- const TSet<TString>& HiddenAttrNames;
- TCallerMap Callers;
-
- public:
- TMethodCallers(const TSet<TString>& hiddenNames)
- : HiddenAttrNames(hiddenNames)
- {
- }
-
- void AddCaller(const TString& name, TCallerPtr caller) {
- Callers[name].push_back(caller);
- }
-
- bool HasCaller(const TString& name) const {
- return Callers.has(name);
- }
-
- PyObject* CallMethod(PyObject* owner, TObjType* self, PyObject* args, PyObject* kwargs, const TString& name) const {
- const TCallerList* lst = Callers.FindPtr(name);
- if (!lst)
- return nullptr;
- for (const auto& caller : *lst) {
- PyObject* res = nullptr;
- PyErr_Clear();
- if (caller->CallMethod(owner, self, args, kwargs, res))
- return res;
- }
- return nullptr;
- }
-
- bool HasMethod(PyObject* owner, TObjType* self, const TString& name) const {
- const TCallerList* lst = Callers.FindPtr(name);
- if (!lst)
- return false;
- for (const auto& caller : *lst) {
- if (caller->HasMethod(owner, self, name, HiddenAttrNames))
- return true;
- }
- return false;
- }
-
- void GetMethodsNames(PyObject* owner, TObjType* self, TVector<TString>& resultNames) const {
- for (const auto& it : Callers) {
- if (HasMethod(owner, self, it.first) && !HiddenAttrNames.contains(it.first))
- resultNames.push_back(it.first);
- }
- }
-
- void GetAllMethodsNames(TVector<TString>& resultNames) const {
- for (const auto& it : Callers) {
- resultNames.push_back(it.first);
- }
- }
-
- void GetPropertiesNames(PyObject*, TObjType* self, TVector<TString>& resultNames) const {
- const TCallerList* lst = Callers.FindPtr("IsA");
- if (!lst)
- return;
- for (const auto& caller : *lst) {
- TIsACaller<TObjType>* isACaller = dynamic_cast<TIsACaller<TObjType>*>(caller.Get());
- if (isACaller) {
- resultNames = isACaller->GetPropertiesNames(self);
- return;
- }
- }
- }
- };
-
- template <typename TObjType>
- class TIsACaller: public TBaseMethodCaller<TObjType> {
- private:
- class TIsAChecker {
- public:
- virtual ~TIsAChecker() {
- }
- virtual bool Check(const TObjType* obj) const = 0;
- };
-
- template <typename TConcrete>
- class TIsAConcreteChecker: public TIsAChecker {
- public:
- bool Check(const TObjType* obj) const override {
- return dynamic_cast<const TConcrete*>(obj) != nullptr;
- }
- };
-
- typedef TSimpleSharedPtr<TIsAChecker> TCheckerPtr;
- typedef TMap<TString, TCheckerPtr> TCheckersMap;
-
- TCheckersMap Checkers;
-
- bool Check(const TString& name, const TObjType* obj) const {
- const TCheckerPtr* checker = Checkers.FindPtr(name);
- if (!checker) {
- PyErr_Format(PyExc_KeyError, "unknown class name: %s", name.data());
- return false;
- }
- return (*checker)->Check(obj);
- }
-
- protected:
- TIsACaller() {
- }
-
- template <typename TConcrete>
- void AddChecker(const TString& name) {
- Checkers[name] = new TIsAConcreteChecker<TConcrete>;
- }
-
- public:
- bool CallMethod(PyObject*, TObjType* self, PyObject* args, PyObject*, PyObject*& res) const override {
- if (args == nullptr || !PyTuple_Check(args))
- return false;
- size_t cnt = PyTuple_Size(args);
- bool result = true;
- for (size_t i = 0; i < cnt; ++i) {
- result = result && Check(
-#if PY_MAJOR_VERSION >= 3
- PyUnicode_AsUTF8(
-#else
- PyString_AsString(
-#endif
- PyTuple_GetItem(args, i)), self);
- }
- if (PyErr_Occurred()) {
- return false;
- }
- res = BuildPyObject(result);
- return true;
- }
-
- TVector<TString> GetPropertiesNames(const TObjType* obj) const {
- TVector<TString> names;
-
- for (const auto& it : Checkers) {
- if (it.second->Check(obj)) {
- names.push_back(it.first);
- }
- }
-
- return names;
- }
- };
-
- template <typename TObjType>
- class TGenericMethodCaller: public TBaseMethodCaller<TObjType> {
- private:
- TString AttrName;
-
- public:
- TGenericMethodCaller(const TString& attrName)
- : AttrName(attrName)
- {
- }
-
- bool CallMethod(PyObject* obj, TObjType*, PyObject* args, PyObject*, PyObject*& res) const override {
- auto str = NameFromString(AttrName);
- PyObject* attr = PyObject_GenericGetAttr(obj, str.Get());
- if (!attr)
- ythrow yexception() << "Can't get generic attribute '" << AttrName << "'";
- res = PyObject_CallObject(attr, args);
- return res != nullptr;
- }
- };
-
-
- template <typename TObjType, typename TSubObject>
- class TSubObjectChecker: public TBaseMethodCaller<TObjType> {
- public:
- ~TSubObjectChecker() override {
- }
-
- bool HasMethod(PyObject*, TObjType* self, const TString&, const TSet<TString>&) override {
- return dynamic_cast<const TSubObject*>(self) != nullptr;
- }
- };
-
- template <typename TFunctor, typename Tuple, typename ResType, typename=std::enable_if_t<!std::is_same_v<ResType, void>>>
- void ApplyFunctor(TFunctor functor, Tuple resultArgs, PyObject*& res) {
- res = BuildPyObject(std::move(Apply(functor, resultArgs)));
- }
-
- template <typename TFunctor, typename Tuple, typename ResType, typename=std::enable_if_t<std::is_same_v<ResType, void>>, typename=void>
- void ApplyFunctor(TFunctor functor, Tuple resultArgs, PyObject*& res) {
- Py_INCREF(Py_None);
- res = Py_None;
- Apply(functor, resultArgs);
- }
-
- template <typename TObjType, typename TResType, typename... Args>
- class TFunctorCaller: public TBaseMethodCaller<TObjType> {
- using TFunctor = std::function<TResType(TObjType&,Args...)>;
- TFunctor Functor;
- public:
- explicit TFunctorCaller(TFunctor functor):
- Functor(functor){}
-
- bool CallMethod(PyObject*, TObjType* self, PyObject* args, PyObject*, PyObject*& res) const {
- auto methodArgsTuple = GetArguments<Args...>(args);
- auto resultArgs = std::tuple_cat(std::tie(*self), methodArgsTuple);
- ApplyFunctor<TFunctor, decltype(resultArgs), TResType>(Functor, resultArgs, res);
- return true;
- }
- };
-
- template <typename TObjType, typename TRealType>
- class TGetStateCaller: public TSubObjectChecker<TObjType, TRealType> {
- protected:
- TPyObjectPtr AddFromCaller(PyObject* obj, const TString& methodName) const {
- PyObject* res = PyObject_CallMethod(obj, const_cast<char*>(methodName.c_str()), const_cast<char*>(""));
- if (!res) {
- PyErr_Clear();
- return TPyObjectPtr(Py_None);
- }
- return TPyObjectPtr(res, true);
- }
-
- void GetStandartAttrsDictionary(PyObject* obj, TRealType*, TMap<TString, TPyObjectPtr>& dict) const {
- TPyObjectPtr attrsDict(PyObject_GetAttrString(obj, "__dict__"), true);
- TMap<TString, TPyObjectPtr> attrs;
- if (!FromPyObject(attrsDict.Get(), attrs))
- ythrow yexception() << "Can't get '__dict__' attribute";
- dict.insert(attrs.begin(), attrs.end());
- }
-
- virtual void GetAttrsDictionary(PyObject* obj, TRealType* self, TMap<TString, TPyObjectPtr>& dict) const = 0;
-
- public:
- bool CallMethod(PyObject* obj, TObjType* self, PyObject* args, PyObject*, PyObject*& res) const override {
- if (!ExtractArgs(args))
- ythrow yexception() << "Can't parse arguments: it should be none";
- TRealType* rself = dynamic_cast<TRealType*>(self);
- if (!rself)
- return false;
- TMap<TString, TPyObjectPtr> dict;
- GetAttrsDictionary(obj, rself, dict);
- res = BuildPyObject(dict);
- return true;
- }
- };
-
- template <typename TObjType, typename TRealType>
- class TSetStateCaller: public TSubObjectChecker<TObjType, TRealType> {
- protected:
- void SetStandartAttrsDictionary(PyObject* obj, TRealType*, TMap<TString, TPyObjectPtr>& dict) const {
- TPyObjectPtr value(BuildPyObject(dict), true);
- PyObject_SetAttrString(obj, "__dict__", value.Get());
- }
-
- virtual void SetAttrsDictionary(PyObject* obj, TRealType* self, TMap<TString, TPyObjectPtr>& dict) const = 0;
-
- public:
- bool CallMethod(PyObject* obj, TObjType* self, PyObject* args, PyObject*, PyObject*& res) const override {
- TMap<TString, TPyObjectPtr> dict;
- if (!ExtractArgs(args, dict))
- ythrow yexception() << "Can't parse arguments: it should be one dictionary";
- TRealType* rself = dynamic_cast<TRealType*>(self);
- if (!rself)
- return false;
- SetAttrsDictionary(obj, rself, dict);
- Py_INCREF(Py_None);
- res = Py_None;
- return true;
- }
- };
-
- template <typename TObjType, typename TResult, typename TSubObject, typename TMethod, typename... Args>
- class TAnyParameterMethodCaller: public TSubObjectChecker<TObjType, TSubObject> {
- private:
- TMethod Method;
-
- public:
- TAnyParameterMethodCaller(TMethod method)
- : Method(method)
- {
- }
-
- public:
- bool CallMethod(PyObject*, TObjType* self, PyObject* args, PyObject*, PyObject*& res) const override {
- TSubObject* sub = dynamic_cast<TSubObject*>(self);
- if (sub == nullptr)
- return false;
- if (args && (!PyTuple_Check(args) || PyTuple_Size(args) != TFunctionArgs<TMethod>::Length)) {
- //ythrow yexception() << "Method takes " << (size_t)(TFunctionArgs<TMethod>::Length) << " arguments, " << PyTuple_Size(args) << " provided";
- return false;
- }
-
- try {
- class Applicant {
- public:
- TResult operator()(Args... theArgs) {
- return (Sub->*Method)(theArgs...);
- }
- TSubObject* Sub;
- TMethod Method;
- };
- res = BuildPyObject(std::move(Apply(Applicant{sub, Method}, GetArguments<Args...>(args))));
- } catch (cast_exception) {
- return false;
- } catch (...) {
- if (PyExc_StopIteration == PyErr_Occurred()) {
- // NB: it's replacement for geo_boost::python::throw_error_already_set();
- return true;
- }
- PyErr_SetString(PyExc_RuntimeError, CurrentExceptionMessage().data());
- return true;
- }
-
- return true;
- }
- };
-
- template <typename TObjType, typename TSubObject, typename TMethod, typename... Args>
- class TAnyParameterMethodCaller<TObjType, void, TSubObject, TMethod, Args...>: public TSubObjectChecker<TObjType, TSubObject> {
- private:
- TMethod Method;
-
- public:
- TAnyParameterMethodCaller(TMethod method)
- : Method(method)
- {
- }
-
- public:
- bool CallMethod(PyObject*, TObjType* self, PyObject* args, PyObject*, PyObject*& res) const override {
- TSubObject* sub = dynamic_cast<TSubObject*>(self);
- if (sub == nullptr) {
- return false;
- }
- if (args && (!PyTuple_Check(args) || PyTuple_Size(args) != TFunctionArgs<TMethod>::Length)) {
- return false;
- }
-
- try {
- class Applicant {
- public:
- void operator()(Args... theArgs) {
- (Sub->*Method)(theArgs...);
- }
- TSubObject* Sub;
- TMethod Method;
- };
-
- Apply(Applicant{sub, Method}, GetArguments<Args...>(args));
-
- Py_INCREF(Py_None);
- res = Py_None;
- } catch (cast_exception) {
- return false;
- } catch (...) {
- PyErr_SetString(PyExc_RuntimeError, CurrentExceptionMessage().data());
- return true;
- }
-
- return true;
- }
- };
-
- template <typename TResult, typename TSubObject, typename... Args>
- struct TConstTraits {
- typedef TResult (TSubObject::*TMethod)(Args... args) const;
- };
-
- template <typename TResult, typename TSubObject, typename... Args>
- struct TNonConstTraits {
- typedef TResult (TSubObject::*TMethod)(Args... args);
- };
-
- template <typename TObjType, typename TResult, typename TSubObject, typename TMethod, typename... Args>
- class TConstMethodCaller: public TAnyParameterMethodCaller<TObjType, TResult, const TSubObject, typename TConstTraits<TResult, TSubObject, Args...>::TMethod, Args...> {
- public:
- TConstMethodCaller(typename TConstTraits<TResult, TSubObject, Args...>::TMethod method)
- : TAnyParameterMethodCaller<TObjType, TResult, const TSubObject, typename TConstTraits<TResult, TSubObject, Args...>::TMethod, Args...>(method)
- {
- }
- };
-
- template <typename TObjType, typename TResult, typename TSubObject, typename... Args>
- TSimpleSharedPtr<TBaseMethodCaller<TObjType>> CreateConstMethodCaller(TResult (TSubObject::*method)(Args...) const) {
- return new TConstMethodCaller<TObjType, TResult, TSubObject, TResult (TSubObject::*)(Args...) const, Args...>(method);
- }
-
- template <typename TObjType, typename TResType, typename... Args>
- TSimpleSharedPtr<TBaseMethodCaller<TObjType>> CreateFunctorCaller(std::function<TResType(TObjType&, Args...)> functor) {
- return new TFunctorCaller<TObjType, TResType, Args...>(functor);
- }
-
- template <typename TObjType, typename TResult, typename TSubObject, typename TMethod, typename... Args>
- class TMethodCaller: public TAnyParameterMethodCaller<TObjType, TResult, TSubObject, typename TNonConstTraits<TResult, TSubObject, Args...>::TMethod, Args...> {
- public:
- TMethodCaller(typename TNonConstTraits<TResult, TSubObject, Args...>::TMethod method)
- : TAnyParameterMethodCaller<TObjType, TResult, TSubObject, typename TNonConstTraits<TResult, TSubObject, Args...>::TMethod, Args...>(method)
- {
- }
- };
-
- template <typename TObjType, typename TResult, typename TSubObject, typename... Args>
- TSimpleSharedPtr<TBaseMethodCaller<TObjType>> CreateMethodCaller(TResult (TSubObject::*method)(Args...)) {
- return new TMethodCaller<TObjType, TResult, TSubObject, TResult (TSubObject::*)(Args...), Args...>(method);
- }
-
-}
diff --git a/library/cpp/pybind/module.cpp b/library/cpp/pybind/module.cpp
deleted file mode 100644
index b7b003d3b0..0000000000
--- a/library/cpp/pybind/module.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-#include "module.h"
-#include "ptr.h"
-
-#include <util/generic/adaptor.h>
-
-namespace NPyBind {
-
-#if PY_MAJOR_VERSION >= 3
- namespace NPrivate {
- struct TFinCallBacksHolder {
- static TVector<TFinalizationCallBack>& GetCallBacks() {
- static TVector<TFinalizationCallBack> res;
- return res;
- }
- };
-
- TAtExitRegistrar::TAtExitRegistrar(TPyObjectPtr module) {
- TPyObjectPtr atExitModuleName(Py_BuildValue("s", "atexit"), true);
- TPyObjectPtr atExitModule(PyImport_Import(atExitModuleName.Get()));
- Y_VERIFY(atExitModule);
- TPyObjectPtr finalizerFunc(PyObject_GetAttrString(module.Get(), "finalizer"), true);
- Y_VERIFY(finalizerFunc);
- TPyObjectPtr registerName(Py_BuildValue("s", "register"), true);
- PyObject_CallMethodObjArgs(atExitModule.Get(), registerName.Get(), finalizerFunc.Get(), nullptr);
- }
-
- TPyBindModuleRegistrar::TPyBindModuleRegistrar() {
- TPyObjectPtr modules(PySys_GetObject("modules"));
- Y_ENSURE(modules.Get());
- if (Module = NPrivate::CreatePyBindModule()) {
- Y_VERIFY(0 == PyDict_SetItemString(modules.Get(), "pybind", Module.RefGet()));
- }
- AddFinalizationCallBack([this]() {
- auto ptr = Module;
- Y_UNUSED(ptr);
- TPyObjectPtr modules(PySys_GetObject("modules"));
- Y_ENSURE(modules.Get());
- TPyObjectPtr pyBindName(Py_BuildValue("s", "pybind"));
- if (PyDict_Contains(modules.Get(), pyBindName.Get()) == 1) {
- Y_VERIFY(0==PyDict_DelItemString(modules.Get(), "pybind"));
- }
- if (Module) {
- //We have to untrack the module because some refs from him refers to gc-leaked errors
- //see exceptions.cpp fore more info
- PyObject_GC_UnTrack(Module.Get());
- Module.Drop();
- }
- });
- }
-
- void AddFinalizationCallBack(TFinalizationCallBack callback) {
- TFinCallBacksHolder::GetCallBacks().push_back(callback);
- }
-
- int FinalizeAll() {
- for (auto callback: Reversed(NPrivate::TFinCallBacksHolder::GetCallBacks())) {
- callback();
- }
- return 0;
- }
- }
-#endif
-
-
- TModuleHolder::TModuleHolder()
- : Methods(1, new TVector<TMethodDef>)
- {
-#if PY_MAJOR_VERSION >= 3
- AddModuleMethod<TModuleMethodCaller<decltype(&NPrivate::FinalizeAll), &NPrivate::FinalizeAll>::Call>("finalizer");
-#endif
- }
-}//NPyBind
diff --git a/library/cpp/pybind/module.h b/library/cpp/pybind/module.h
deleted file mode 100644
index 41dcb4dfec..0000000000
--- a/library/cpp/pybind/module.h
+++ /dev/null
@@ -1,176 +0,0 @@
-#pragma once
-
-#define PY_SSIZE_T_CLEAN
-#include <Python.h>
-#include "ptr.h"
-#include "cast.h"
-#include "exceptions.h"
-
-#include <util/generic/function.h>
-
-namespace NPyBind {
-#if PY_MAJOR_VERSION >= 3
- namespace NPrivate {
- using TFinalizationCallBack = std::function<void()>;
- void AddFinalizationCallBack(TFinalizationCallBack);
- class TAtExitRegistrar: private TNonCopyable {
- TAtExitRegistrar(TPyObjectPtr module);
- public:
- static void Instantiate(TPyObjectPtr module) {
- static TAtExitRegistrar registrar(module);
- Y_UNUSED(registrar);
- }
- };
-
- class TPyBindModuleRegistrar: private TNonCopyable {
- TPyBindModuleRegistrar();
- TPyObjectPtr Module;
- public:
- static void Instantiate() {
- static TPyBindModuleRegistrar registrar;
- Y_UNUSED(registrar);
- }
- };
- } //NPrivate
-#endif
-
- class TModuleHolder {
- private:
- TModuleHolder(const TModuleHolder&);
- TModuleHolder& operator=(const TModuleHolder&);
-
- TModuleHolder();
- private:
- typedef PyCFunction TModuleMethod;
-#if PY_MAJOR_VERSION >= 3
- typedef PyObject* (*TModuleInitFunc)();
-#else
- typedef void (*TModuleInitFunc)();
-#endif
-
- struct TMethodDef {
- TString Name;
- TModuleMethod Method;
- TString Description;
- int Flags;
-
- TMethodDef(const TString& name, TModuleMethod method, const TString& descr, int flags)
- : Name(name)
- , Method(method)
- , Description(descr)
- , Flags(flags)
- {
- }
-
- operator PyMethodDef() const {
- PyMethodDef cur = {Name.c_str(), Method, Flags, Description.c_str()};
- return cur;
- }
- };
-
- typedef TSimpleSharedPtr<TVector<TMethodDef>> TMethodDefVecPtr;
- typedef TSimpleSharedPtr<TVector<PyMethodDef>> TPyMethodDefVecPtr;
-
- TVector<TMethodDefVecPtr> Methods;
- TVector<TPyMethodDefVecPtr> Defs;
-#if PY_MAJOR_VERSION >= 3
- //because the md_name will leak otherwise
- class TPyModuleDefWithName {
- PyModuleDef Def;
- TString Name;
- public:
- explicit TPyModuleDefWithName(TString name, TPyMethodDefVecPtr moduleDefs)
- : Name(std::move(name))
- {
- Def = PyModuleDef{
- PyModuleDef_HEAD_INIT,
- Name.c_str(),
- nullptr,
- -1,
- moduleDefs->data(),
- nullptr, nullptr, nullptr, nullptr
- };
- }
- PyModuleDef* GetDefPtr() {
- return &Def;
- }
-
- };
- TVector<TSimpleSharedPtr<TPyModuleDefWithName>> ModuleDefs;
-#endif
-
- template <TModuleMethod method>
- static PyObject* MethodWrapper(PyObject* obj, PyObject* args) {
- try {
- PyObject* res = method(obj, args);
- if (!res && !PyErr_Occurred())
- ythrow yexception() << "\nModule method exited with NULL, but didn't set Error.\n Options:\n -- Return correct value or None;\n -- Set python exception;\n -- Throw c++ exception.";
- return res;
- } catch (const std::exception& ex) {
- PyErr_SetString(TExceptionsHolder::Instance().ToPyException(ex).Get(), ex.what());
- } catch (...) {
- PyErr_SetString(PyExc_RuntimeError, "Unknown error occurred while trying to call module method");
- }
- return nullptr;
- }
-
- public:
- static TModuleHolder& Instance() {
- static TModuleHolder Holder;
- return Holder;
- }
-
- void ImportModule(TPyObjectPtr module, const char* const name, TModuleInitFunc initFunc) {
- PyImport_AppendInittab(const_cast<char*>(name), initFunc);
- TPyObjectPtr importedModule(PyImport_ImportModule(name), true);
- PyModule_AddObject(module.Get(), name, importedModule.Get());
- }
-
- template <TModuleMethod method>
- void AddModuleMethod(const TString& name, const TString& descr = "") {
- Methods.back()->push_back(TMethodDef(name, MethodWrapper<method>, descr, METH_VARARGS));
- }
-
- TPyObjectPtr InitModule(const TString& name) {
- Defs.push_back(new TVector<PyMethodDef>(Methods.back()->begin(), Methods.back()->end()));
- PyMethodDef blank = {nullptr, nullptr, 0, nullptr};
- Defs.back()->push_back(blank);
-#if PY_MAJOR_VERSION >= 3
- ModuleDefs.push_back(MakeSimpleShared<TPyModuleDefWithName>(name, Defs.back()));
- TPyObjectPtr res(PyModule_Create(ModuleDefs.back()->GetDefPtr()));
- NPrivate::TAtExitRegistrar::Instantiate(res);
- NPrivate::TPyBindModuleRegistrar::Instantiate();
-#else
- TPyObjectPtr res(Py_InitModule(name.c_str(), &(Defs.back()->at(0))));
-#endif
- Methods.push_back(new TVector<TMethodDef>);
- return res;
- }
- };
-
- template <typename TMethodSignature, TMethodSignature method>
- class TModuleMethodCaller {
- private:
- template <typename TResult, typename... Args>
- struct TCaller {
- static PyObject* Call(PyObject* args) {
- return BuildPyObject(Apply(method, GetArguments<Args...>(args)));
- }
- };
-
- template <typename TResult, typename... Args>
- static PyObject* InternalCall(TResult (*)(Args...), PyObject* args) {
- return BuildPyObject(Apply(method, GetArguments<Args...>(args)));
- }
-
- public:
- static PyObject* Call(PyObject*, PyObject* args) {
- if (args && (!PyTuple_Check(args) || PyTuple_Size(args) != TFunctionArgs<TMethodSignature>::Length)) {
- ythrow yexception() << "Method takes " << (size_t)(TFunctionArgs<TMethodSignature>::Length) << " arguments, " << PyTuple_Size(args) << " provided";
- }
-
- return InternalCall(method, args);
- }
- };
-
-}
diff --git a/library/cpp/pybind/pod.cpp b/library/cpp/pybind/pod.cpp
deleted file mode 100644
index 3cf030e537..0000000000
--- a/library/cpp/pybind/pod.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include "pod.h"
-
-namespace NPyBind {
- class TPODAttrGetter: public TBaseAttrGetter<TPOD> {
- public:
- bool GetAttr(PyObject*, const TPOD& self, const TString& attr, PyObject*& res) const override {
- res = self.GetAttr(attr.c_str());
- return res != nullptr;
- }
- };
-
- TPODTraits::TPODTraits()
- : MyParent("TPOD", "simple struct")
- {
- AddGetter("", new TPODAttrGetter);
- }
-
-}
diff --git a/library/cpp/pybind/pod.h b/library/cpp/pybind/pod.h
deleted file mode 100644
index 90165fdbec..0000000000
--- a/library/cpp/pybind/pod.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#pragma once
-
-#define PY_SSIZE_T_CLEAN
-#include <Python.h>
-#include "attr.h"
-#include "typedesc.h"
-
-namespace NPyBind {
- struct TPOD {
- TPyObjectPtr Dict;
-
- TPOD()
- : Dict(PyDict_New(), true)
- {
- }
- bool SetAttr(const char* name, PyObject* value) {
- return PyDict_SetItemString(Dict.Get(), name, value) == 0;
- }
- PyObject* GetAttr(const char* name) const {
- PyObject* res = PyDict_GetItemString(Dict.Get(), name);
- Py_XINCREF(res);
- return res;
- }
- };
-
- class TPODTraits: public NPyBind::TPythonType<TPOD, TPOD, TPODTraits> {
- private:
- typedef TPythonType<TPOD, TPOD, TPODTraits> MyParent;
- friend class TPythonType<TPOD, TPOD, TPODTraits>;
- TPODTraits();
-
- public:
- static TPOD* GetObject(TPOD& obj) {
- return &obj;
- }
- };
-
- template <>
- inline bool FromPyObject<TPOD*>(PyObject* obj, TPOD*& res) {
- res = TPODTraits::CastToObject(obj);
- if (res == nullptr)
- return false;
- return true;
- }
- template <>
- inline bool FromPyObject<const TPOD*>(PyObject* obj, const TPOD*& res) {
- res = TPODTraits::CastToObject(obj);
- if (res == nullptr)
- return false;
- return true;
- }
-
-}
diff --git a/library/cpp/pybind/ptr.h b/library/cpp/pybind/ptr.h
deleted file mode 100644
index e136736690..0000000000
--- a/library/cpp/pybind/ptr.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#pragma once
-
-#define PY_SSIZE_T_CLEAN
-#include <Python.h>
-#include <util/generic/ptr.h>
-
-namespace NPyBind {
- template <class T>
- class TPythonIntrusivePtrOps {
- public:
- static inline void Ref(T* t) noexcept {
- Py_XINCREF(t);
- }
-
- static inline void UnRef(T* t) noexcept {
- Py_XDECREF(t);
- }
-
- static inline void DecRef(T* t) noexcept {
- Py_XDECREF(t);
- }
- };
-
- class TPyObjectPtr: public TIntrusivePtr<PyObject, TPythonIntrusivePtrOps<PyObject>> {
- private:
- typedef TIntrusivePtr<PyObject, TPythonIntrusivePtrOps<PyObject>> TParent;
- typedef TPythonIntrusivePtrOps<PyObject> TOps;
-
- public:
- inline TPyObjectPtr() noexcept {
- }
-
- inline explicit TPyObjectPtr(PyObject* obj) noexcept
- : TParent(obj)
- {
- }
-
- inline TPyObjectPtr(PyObject* obj, bool unref) noexcept
- : TParent(obj)
- {
- if (unref)
- TOps::UnRef(TParent::Get());
- }
-
- inline PyObject* RefGet() {
- TOps::Ref(TParent::Get());
- return TParent::Get();
- }
- };
-
-}
diff --git a/library/cpp/pybind/typeattrs.h b/library/cpp/pybind/typeattrs.h
deleted file mode 100644
index a906b9ec2b..0000000000
--- a/library/cpp/pybind/typeattrs.h
+++ /dev/null
@@ -1,368 +0,0 @@
-#pragma once
-
-#include "ptr.h"
-#include "cast.h"
-#include "attr.h"
-#include "method.h"
-
-#include <util/generic/vector.h>
-
-namespace NPyBind {
- template <typename TObject>
- class TPythonTypeAttributes {
- private:
- TAttrGetters<TObject> AttrGetters;
- TAttrSetters<TObject> AttrSetters;
- TMethodCallers<TObject> MethodCallers;
-
- class TGetAttrsNamesCaller;
- class TGetMethodsNamesCaller;
- class TGetAllNamesCaller;
- class TGetPropertiesNamesCaller;
- class TDictAttrGetter;
- class TDictAttrSetter;
- class TGetAttributeMethodCaller;
- class TSetAttrMethodCaller;
- class TGetStrReprMethodCaller;
- class TReduceMethodCaller;
- class TBaseGetStateMethodCaller;
- class TBaseSetStateMethodCaller;
-
- TPythonTypeAttributes(const TPythonTypeAttributes&);
- TPythonTypeAttributes& operator=(const TPythonTypeAttributes&);
-
- static const TSet<TString> HiddenAttrNames;
-
- typedef PyObject* (*GetAttrFunction)(PyObject*, char*);
- typedef int (*SetAttrFunction)(PyObject*, char*, PyObject*);
- GetAttrFunction GetAttr;
- SetAttrFunction SetAttr;
-
- public:
- typedef TSimpleSharedPtr<TBaseAttrGetter<TObject>> TGetterPtr;
- typedef TSimpleSharedPtr<TBaseAttrSetter<TObject>> TSetterPtr;
- typedef TSimpleSharedPtr<TBaseMethodCaller<TObject>> TCallerPtr;
-
- TPythonTypeAttributes(GetAttrFunction getAttr, SetAttrFunction setAttr)
- : AttrGetters(HiddenAttrNames)
- , MethodCallers(HiddenAttrNames)
- , GetAttr(getAttr)
- , SetAttr(setAttr)
- {
- }
-
- void InitCommonAttributes() {
- // attributes
- AddGetter("__dict__", new TDictAttrGetter(AttrGetters));
- AddSetter("__dict__", new TDictAttrSetter(AttrSetters));
-
- // methods
- AddCaller("GetAttrsNames", new TGetAttrsNamesCaller(AttrGetters));
- AddCaller("GetMethodsNames", new TGetMethodsNamesCaller(MethodCallers));
- AddCaller("GetAllNames", new TGetAllNamesCaller(AttrGetters, MethodCallers));
- AddCaller("GetPropertiesNames", new TGetPropertiesNamesCaller(MethodCallers));
- AddCaller("__getattribute__", new TGetAttributeMethodCaller(GetAttr));
- AddCaller("__setattr__", new TSetAttrMethodCaller(SetAttr));
- AddCaller("__str__", new TGetStrReprMethodCaller("__str__"));
- AddCaller("__repr__", new TGetStrReprMethodCaller("__repr__"));
- AddCaller("__reduce_ex__", new TReduceMethodCaller);
- AddCaller("__reduce__", new TReduceMethodCaller);
- AddCaller("__getstate__", new TBaseGetStateMethodCaller);
- AddCaller("__setstate__", new TBaseSetStateMethodCaller);
-
- // generics
- AddGetter("__class__", new TGenericAttrGetter<TObject>("__class__"));
- AddGetter("__doc__", new TGenericAttrGetter<TObject>("__doc__"));
- AddCaller("__sizeof__", new TGenericMethodCaller<TObject>("__sizeof__"));
- AddCaller("__hash__", new TGenericMethodCaller<TObject>("__hash__"));
- }
-
- void AddGetter(const TString& attr, TGetterPtr getter) {
- AttrGetters.AddGetter(attr, getter);
- }
-
- void AddSetter(const TString& attr, TSetterPtr setter) {
- AttrSetters.AddSetter(attr, setter);
- }
-
- void AddCaller(const TString& name, TCallerPtr caller) {
- MethodCallers.AddCaller(name, caller);
- }
-
- const TAttrGetters<TObject>& GetAttrGetters() const {
- return AttrGetters;
- }
-
- TAttrSetters<TObject>& GetAttrSetters() {
- return AttrSetters;
- }
-
- const TMethodCallers<TObject>& GetMethodCallers() const {
- return MethodCallers;
- }
-
- const TSet<TString>& GetHiddenAttrs() const {
- return HiddenAttrNames;
- }
- };
-
- template <typename TObjType>
- class TPythonTypeAttributes<TObjType>::TGetAttrsNamesCaller: public TBaseMethodCaller<TObjType> {
- private:
- const TAttrGetters<TObjType>& AttrGetters;
-
- public:
- TGetAttrsNamesCaller(const TAttrGetters<TObjType>& getters)
- : AttrGetters(getters)
- {
- }
-
- bool CallMethod(PyObject* owner, TObjType* self, PyObject* args, PyObject*, PyObject*& res) const override {
- if (!ExtractArgs(args))
- ythrow yexception() << "Could not parse args for GetAttrsNames() - it should be none";
- TVector<TString> names;
- AttrGetters.GetAttrsNames(owner, *self, names);
- res = BuildPyObject(names);
- return (res != nullptr);
- }
- };
-
- template <typename TObjType>
- class TPythonTypeAttributes<TObjType>::TGetMethodsNamesCaller: public TBaseMethodCaller<TObjType> {
- private:
- const TMethodCallers<TObjType>& MethodCallers;
-
- public:
- TGetMethodsNamesCaller(const TMethodCallers<TObjType>& callers)
- : MethodCallers(callers)
- {
- }
-
- bool CallMethod(PyObject* owner, TObjType* self, PyObject* args, PyObject*, PyObject*& res) const override {
- if (!ExtractArgs(args))
- ythrow yexception() << "Could not parse args for GetMethodsNames() - it should be none";
- TVector<TString> names;
- MethodCallers.GetMethodsNames(owner, self, names);
- res = BuildPyObject(names);
- return (res != nullptr);
- }
- };
-
- template <typename TObjType>
- class TPythonTypeAttributes<TObjType>::TGetAllNamesCaller: public TBaseMethodCaller<TObjType> {
- private:
- const TAttrGetters<TObjType>& AttrGetters;
- const TMethodCallers<TObjType>& MethodCallers;
-
- public:
- TGetAllNamesCaller(const TAttrGetters<TObjType>& getters,
- const TMethodCallers<TObjType>& callers)
- : AttrGetters(getters)
- , MethodCallers(callers)
- {
- }
-
- bool CallMethod(PyObject* owner, TObjType* self, PyObject* args, PyObject*, PyObject*& res) const override {
- if (!ExtractArgs(args))
- ythrow yexception() << "Could not parse args for GetAllNames() - it should be none";
- TVector<TString> names;
- AttrGetters.GetAttrsNames(owner, *self, names);
- MethodCallers.GetMethodsNames(owner, self, names);
- res = BuildPyObject(names);
- return (res != nullptr);
- }
- };
-
- template <typename TObjType>
- class TPythonTypeAttributes<TObjType>::TGetPropertiesNamesCaller: public TBaseMethodCaller<TObjType> {
- private:
- const TMethodCallers<TObjType>& MethodCallers;
-
- public:
- TGetPropertiesNamesCaller(const TMethodCallers<TObjType>& callers)
- : MethodCallers(callers)
- {
- }
-
- public:
- bool CallMethod(PyObject* obj, TObjType* self, PyObject* args, PyObject*, PyObject*& res) const override {
- if (!ExtractArgs(args))
- return false;
-
- TVector<TString> names;
- MethodCallers.GetPropertiesNames(obj, self, names);
- res = BuildPyObject(names);
- return (res != nullptr);
- }
- };
-
- template <typename TObjType>
- class TPythonTypeAttributes<TObjType>::TDictAttrGetter: public TBaseAttrGetter<TObjType> {
- private:
- TAttrGetters<TObjType>& AttrGetters;
-
- public:
- TDictAttrGetter(TAttrGetters<TObjType>& getters)
- : AttrGetters(getters)
- {
- }
-
- bool GetAttr(PyObject* owner, const TObjType& self, const TString&, PyObject*& res) const override {
- TMap<TString, PyObject*> dict;
- AttrGetters.GetAttrsDictionary(owner, self, dict);
- res = BuildPyObject(dict);
- return (res != nullptr);
- }
- };
-
- template <typename TObjType>
- class TPythonTypeAttributes<TObjType>::TDictAttrSetter: public TBaseAttrSetter<TObjType> {
- private:
- TAttrSetters<TObjType>& AttrSetters;
-
- public:
- TDictAttrSetter(TAttrSetters<TObjType>& setters)
- : AttrSetters(setters)
- {
- }
-
- bool SetAttr(PyObject* owner, TObjType& self, const TString&, PyObject* val) override {
- TMap<TString, PyObject*> dict;
- if (!FromPyObject(val, dict))
- ythrow yexception() << "'__dict__' should be set to dictionary";
- if (!AttrSetters.SetAttrDictionary(owner, self, dict))
- return false;
- return true;
- }
- };
-
- template <typename TObjType>
- class TPythonTypeAttributes<TObjType>::TGetAttributeMethodCaller: public TBaseMethodCaller<TObjType> {
- private:
- GetAttrFunction GetAttr;
-
- public:
- TGetAttributeMethodCaller(GetAttrFunction getAttr)
- : GetAttr(getAttr)
- {
- }
-
- bool CallMethod(PyObject* owner, TObjType*, PyObject* args, PyObject*, PyObject*& res) const override {
- TString attrName;
- if (!ExtractArgs(args, attrName))
- ythrow yexception() << "Could not parse args for '__getattribute__' - it should be one string";
- res = GetAttr(owner, const_cast<char*>(attrName.c_str()));
- if (!res)
- // Error already set
- return false;
- return true;
- }
- };
-
- template <typename TObjType>
- class TPythonTypeAttributes<TObjType>::TSetAttrMethodCaller: public TBaseMethodCaller<TObjType> {
- private:
- SetAttrFunction SetAttr;
-
- public:
- TSetAttrMethodCaller(SetAttrFunction setAttr)
- : SetAttr(setAttr)
- {
- }
-
- bool CallMethod(PyObject* owner, TObjType*, PyObject* args, PyObject*, PyObject*& res) const override {
- TString attrName;
- TPyObjectPtr value;
- if (!ExtractArgs(args, attrName, value))
- ythrow yexception() << "Could not parse args for '__setattr__' - it should be one string and value";
- Py_INCREF(Py_None);
- res = Py_None;
- if (-1 == SetAttr(owner, const_cast<char*>(attrName.c_str()), value.Get()))
- // Error already set
- return false;
- return true;
- }
- };
-
- template <typename TObjType>
- class TPythonTypeAttributes<TObjType>::TGetStrReprMethodCaller: public TBaseMethodCaller<TObjType> {
- private:
- TString MethodName;
-
- private:
- const TString GetFullName(PyObject* obj) const {
- TString module, name;
- TPyObjectPtr type(PyObject_Type(obj), true);
- if (!FromPyObject(PyObject_GetAttrString(type.Get(), "__module__"), module) || !FromPyObject(PyObject_GetAttrString(type.Get(), "__name__"), name))
- ythrow yexception() << "Could not get name of object";
- return module + "." + name;
- }
-
- public:
- TGetStrReprMethodCaller(const TString& methodName)
- : MethodName(methodName)
- {
- }
-
- bool CallMethod(PyObject* owner, TObjType*, PyObject* args, PyObject*, PyObject*& res) const override {
- if (args && !ExtractArgs(args))
- ythrow yexception() << "Could not parse args for '" << MethodName << "'";
- TString message = TString("<") + GetFullName(owner) + " object>";
- res = ReturnString(message);
- return (res != nullptr);
- }
- };
-
- template <typename TObjType>
- class TPythonTypeAttributes<TObjType>::TReduceMethodCaller: public TBaseMethodCaller<TObjType> {
- public:
- bool CallMethod(PyObject* owner, TObjType*, PyObject*, PyObject*, PyObject*& res) const override {
- TPyObjectPtr tuple(PyTuple_New(3), true);
- // First component: reconstructor
- TPyObjectPtr pybindName(BuildPyObject("pybind"), true);
- TPyObjectPtr mainModule(PyImport_Import(pybindName.Get()), true);
- TPyObjectPtr recName(BuildPyObject("PyBindObjectReconstructor"), true);
- TPyObjectPtr reconstructor(PyObject_GetAttr(mainModule.Get(), recName.Get()), true);
- // Second component: arguments to rebuild object
- TPyObjectPtr arguments(PyTuple_New(2), true);
- TPyObjectPtr cl(PyObject_GetAttrString(owner, "__class__"), true);
- PyTuple_SET_ITEM(arguments.Get(), 0, cl.RefGet());
- TPyObjectPtr props(PyObject_CallMethod(owner, const_cast<char*>("GetPropertiesNames"), nullptr), true);
- PyTuple_SET_ITEM(arguments.Get(), 1, props.RefGet());
- // Third component: state to fill new object
- TPyObjectPtr state(PyObject_CallMethod(owner, const_cast<char*>("__getstate__"), nullptr), true);
-
- PyTuple_SET_ITEM(tuple.Get(), 0, reconstructor.RefGet());
- PyTuple_SET_ITEM(tuple.Get(), 1, arguments.RefGet());
- PyTuple_SET_ITEM(tuple.Get(), 2, state.RefGet());
- res = tuple.RefGet();
- return (res != nullptr);
- }
- };
-
- template <typename TObjType>
- class TPythonTypeAttributes<TObjType>::TBaseGetStateMethodCaller: public TGetStateCaller<TObjType, TObjType> {
- public:
- void GetAttrsDictionary(PyObject* obj, TObjType* self, TMap<TString, TPyObjectPtr>& dict) const override {
- this->GetStandartAttrsDictionary(obj, self, dict);
- }
- };
-
- template <typename TObjType>
- class TPythonTypeAttributes<TObjType>::TBaseSetStateMethodCaller: public TSetStateCaller<TObjType, TObjType> {
- public:
- void SetAttrsDictionary(PyObject* obj, TObjType* self, TMap<TString, TPyObjectPtr>& dict) const override {
- this->SetStandartAttrsDictionary(obj, self, dict);
- }
- };
-
- static const char* HiddenAttrStrings[] = {
- "__dict__", "__class__", "__dir__", "__delattr__", "__doc__", "__format__", "__getattribute__", "__hash__",
- "__init__", "__new__", "__reduce__", "__reduce_ex__", "__repr__", "__setattr__", "__sizeof__", "__str__",
- "__subclasshook__", "__getstate__", "__setstate__",
- "GetAttrsNames", "GetMethodsNames", "GetAllNames", "GetPropertiesNames"};
-
- template <typename T>
- const TSet<TString> TPythonTypeAttributes<T>::HiddenAttrNames(HiddenAttrStrings, std::end(HiddenAttrStrings));
-
-}
diff --git a/library/cpp/pybind/typedesc.cpp b/library/cpp/pybind/typedesc.cpp
deleted file mode 100644
index 75f39fd126..0000000000
--- a/library/cpp/pybind/typedesc.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-#include "typedesc.h"
-
-#include <util/generic/singleton.h>
-
-static void RegisterJSONBridgeImpl() {
- PyRun_SimpleString("import json\n"
- "class PyBindEncoder(json.JSONEncoder):\n"
- " def default(self, obj):\n"
- " if isinstance(obj, bytes):\n"
- " try:\n"
- " return obj.decode()\n"
- " except UnicodeDecodeError:\n"
- " return obj.hex()\n"
- " dct = None\n"
- " if hasattr(obj, '__getstate__'):\n"
- " dct = obj.__getstate__()\n"
- " elif hasattr(obj, '__dict__'):\n"
- " dct = obj.__dict__\n"
- " if dct is None:\n"
- " return json.JSONEncoder.default(self, obj)\n"
- " if hasattr(obj, '__class__'):\n"
- " if hasattr(obj.__class__, '__name__'):\n"
- " dct['__name__'] = obj.__class__.__name__\n"
- " if hasattr(obj.__class__, '__module__'):\n"
- " dct['__module__'] = obj.__class__.__module__\n"
- " if hasattr(obj, 'GetPropertiesNames'):\n"
- " dct['__properties__'] = obj.GetPropertiesNames()\n"
- " return dct");
-
- PyRun_SimpleString("def PyBindObjectHook(dct):\n"
- " if '__name__' in dct:\n"
- " name = dct['__name__']\n"
- " module = dct['__module__']\n"
- " del dct['__name__']\n"
- " del dct['__module__']\n"
- " cls = getattr(__import__(module), name)\n"
- " if '__properties__' in dct:\n"
- " props = dct['__properties__']\n"
- " del dct['__properties__']\n"
- " if len(props) == 0:\n"
- " return dct\n"
- " instance = cls(__properties__ = props)\n"
- " else:\n"
- " instance = cls()\n"
- " if hasattr(instance, '__setstate__'):\n"
- " instance.__setstate__(dct)\n"
- " elif hasattr(instance, '__dict__'):\n"
- " instance.__dict__ = dct\n"
- " else:\n"
- " return dct\n"
- " return instance\n"
- " return dct");
-
- PyRun_SimpleString("def json_dump(*args, **kwargs):\n"
- " kwargs['cls'] = PyBindEncoder\n"
- " return json.dump(*args, **kwargs)\n"
- "def json_dumps(*args, **kwargs):\n"
- " kwargs['cls'] = PyBindEncoder\n"
- " return json.dumps(*args, **kwargs)");
-
- PyRun_SimpleString("def json_load(*args, **kwargs):\n"
- " kwargs['object_hook'] = PyBindObjectHook\n"
- " return json.load(*args, **kwargs)\n"
- "def json_loads(*args, **kwargs):\n"
- " kwargs['object_hook'] = PyBindObjectHook\n"
- " return json.loads(*args, **kwargs)");
-}
-
-namespace {
- struct TJSONBridge {
- TJSONBridge() {
- RegisterJSONBridgeImpl();
- }
- };
-}
-
-void NPyBind::RegisterJSONBridge() {
- Singleton<TJSONBridge>();
-}
diff --git a/library/cpp/pybind/typedesc.h b/library/cpp/pybind/typedesc.h
deleted file mode 100644
index 57eacb0f3a..0000000000
--- a/library/cpp/pybind/typedesc.h
+++ /dev/null
@@ -1,545 +0,0 @@
-#pragma once
-
-#define PY_SSIZE_T_CLEAN
-#include <Python.h>
-#include <structmember.h>
-
-#include "typeattrs.h"
-#include "exceptions.h"
-#include "module.h"
-
-namespace NPyBind {
- void RegisterJSONBridge();
-
- namespace NPrivate {
- template <typename>
- class TUnboundClosureHolder;
- template <typename>
- class TUnboundClosure;
- }
-
- // TTraits should be derived from TPythonType
- template <typename TObjectHolder, typename TObject, typename TTraits>
- class TPythonType {
- private:
- TPythonType(const TPythonType&);
- TPythonType& operator=(const TPythonType&);
-
- private:
- typedef typename TPythonTypeAttributes<TObject>::TGetterPtr TGetterPtr;
- typedef typename TPythonTypeAttributes<TObject>::TSetterPtr TSetterPtr;
- typedef typename TPythonTypeAttributes<TObject>::TCallerPtr TCallerPtr;
-
- struct TProxy {
- PyObject_HEAD
- TObjectHolder* Holder;
- };
-
- static PyTypeObject PyType;
- static PyMappingMethods MappingMethods;
- static PyObject* PyTypeObjPtr;
- protected:
- static PyTypeObject* GetPyTypePtr() {
- return &PyType;
- }
- private:
-
- TPythonTypeAttributes<TObject> Attributes;
-
- static int InitObject(PyObject* s, PyObject* args, PyObject* kwargs) {
- try {
- TProxy* self = reinterpret_cast<TProxy*>(s);
- auto str = NameFromString("__properties__");
- if (kwargs && PyDict_Check(kwargs) && PyDict_Contains(kwargs, str.Get())) {
- TPyObjectPtr props(PyDict_GetItem(kwargs, str.Get()));
- TVector<TString> properties;
- FromPyObject(props.Get(), properties);
- self->Holder = TTraits::DoInitPureObject(properties);
- } else {
- self->Holder = (args || kwargs) ? TTraits::DoInitObject(args, kwargs) : nullptr;
- }
- if (PyErr_Occurred())
- return -1;
- return 0;
- } catch (const std::exception& ex) {
- PyErr_SetString(TExceptionsHolder::Instance().ToPyException(ex).Get(), ex.what());
- } catch (...) {
- PyErr_SetString(PyExc_RuntimeError, "Unknown error occurred while trying to init object");
- }
- return -1;
- }
-
- static void DeallocObject(TProxy* self) {
- delete self->Holder;
- Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
- }
-
- static PyObject* GetObjectAttr(PyObject* pyObj, char* attr);
- static int SetObjectAttr(PyObject* pyObj, char* attr, PyObject* value);
- static PyObject* GetStr(PyObject*);
- static PyObject* GetRepr(PyObject*);
- static PyObject* GetIter(PyObject*);
- static PyObject* GetNext(PyObject*);
-
- // Fill class __dict__ with functions to make sure methods names will get to dir()
- void FillClassDict() const {
- TVector<TString> names;
- Attributes.GetMethodCallers().GetAllMethodsNames(names);
- for (const auto& name : names) {
- TPyObjectPtr callable = NPrivate::TUnboundClosure<TObject>::Instance().CreatePyObject(new NPrivate::TUnboundClosureHolder<TObject>(&PyType, name));
- PyDict_SetItemString(PyType.tp_dict, name.c_str(), callable.Get());
- }
- }
-
- void InitCommonAttributes() {
- static bool was = false;
- if (was)
- return;
- was = true;
- Attributes.InitCommonAttributes();
- FillClassDict();
- }
-
- protected:
- TPythonType(const char* pyTypeName, const char* typeDescr, PyTypeObject* parentType = nullptr)
- : Attributes(GetObjectAttr, SetObjectAttr)
- {
- PyType.tp_name = pyTypeName;
- PyType.tp_doc = typeDescr;
- Py_INCREF(PyTypeObjPtr);
- if (parentType) {
- Py_INCREF(parentType);
- PyType.tp_base = parentType;
- }
- PyType_Ready(&PyType);
-
- TExceptionsHolder::Instance();
- RegisterJSONBridge();
-
- }
-
- ~TPythonType() {
- }
-
- static TObjectHolder* DoInitObject(PyObject*, PyObject*) {
- return nullptr;
- }
-
- static TObjectHolder* DoInitPureObject(const TVector<TString>&) {
- return nullptr;
- }
-
- static void SetClosure(PyObject* (*call)(PyObject*, PyObject*, PyObject*)) {
- PyType.tp_call = call;
- }
-
- public:
- void AddGetter(const TString& attr, TGetterPtr getter) {
- Attributes.AddGetter(attr, getter);
- }
-
- void AddSetter(const TString& attr, TSetterPtr setter) {
- Attributes.AddSetter(attr, setter);
- }
-
- void AddCaller(const TString& name, TCallerPtr caller) {
- Attributes.AddCaller(name, caller);
- if (name == "__iter__") {
- PyType.tp_iter = GetIter;
- }
- if (name == "next") {
- PyType.tp_iternext = GetNext;
- }
- }
-
- void SetIter(getiterfunc tp_iter) {
- PyType.tp_iter = tp_iter;
- }
-
- void SetIterNext(iternextfunc tp_iternext) {
- PyType.tp_iternext = tp_iternext;
- }
-
- void SetDestructor(destructor tp_dealloc) {
- PyType.tp_dealloc = tp_dealloc;
- }
-
- void SetLengthFunction(lenfunc mp_length) {
- PyType.tp_as_mapping->mp_length = mp_length;
- }
-
- void SetSubscriptFunction(binaryfunc mp_subscript) {
- PyType.tp_as_mapping->mp_subscript = mp_subscript;
- }
-
- void SetAssSubscriptFunction(objobjargproc mp_ass_subscript) {
- PyType.tp_as_mapping->mp_ass_subscript = mp_ass_subscript;
- }
-
- typedef TObject TObjectType;
-
- static TPythonType& Instance() {
- static TTraits Traits;
- Traits.InitCommonAttributes();
- return Traits;
- }
-
- void Register(PyObject* module, const char* typeName) {
- Py_INCREF(PyTypeObjPtr);
- if (0 != PyModule_AddObject(module, typeName, PyTypeObjPtr))
- ythrow yexception() << "can't register type \"" << typeName << "\"";
- }
-
- void Register(PyObject* module, const char* objName, TObjectHolder* hld) {
- if (0 != PyModule_AddObject(module, objName, CreatePyObject(hld).RefGet()))
- ythrow yexception() << "can't register object \"" << objName << "\"";
- }
-
- void Register(TPyObjectPtr module, const TString& typeName) {
- Register(module.Get(), typeName.c_str());
- }
-
- void Register(TPyObjectPtr module, const TString& objName, TObjectHolder* hld) {
- Register(module.Get(), objName.c_str(), hld);
- }
-
- static TObjectHolder* CastToObjectHolder(PyObject* obj) {
- // Call Instance() to make sure PyTypeObjPtr is already created at this point
- Instance();
- if (!PyObject_IsInstance(obj, PyTypeObjPtr))
- return nullptr;
- TProxy* prx = reinterpret_cast<TProxy*>(obj);
- return prx ? prx->Holder : nullptr;
- }
-
- static TObject* CastToObject(PyObject* obj) {
- TObjectHolder* hld = CastToObjectHolder(obj);
- return hld ? TTraits::GetObject(*hld) : nullptr;
- }
-
- static TPyObjectPtr CreatePyObject(TObjectHolder* hld) {
- TPyObjectPtr r(_PyObject_New(&PyType), true);
- TProxy* prx = reinterpret_cast<TProxy*>(r.Get());
- if (prx)
- prx->Holder = hld;
- return r;
- }
- };
-
- template <typename TObjectHolder, typename TObject, typename TTraits>
- PyMappingMethods TPythonType<TObjectHolder, TObject, TTraits>::MappingMethods = {nullptr, nullptr, nullptr};
-
- template <typename TObjectHolder, typename TObject, typename TTraits>
- PyTypeObject TPythonType<TObjectHolder, TObject, TTraits>::PyType = {
- PyVarObject_HEAD_INIT(nullptr, 0) "", sizeof(TProxy), 0, (destructor)&DeallocObject
-#if PY_VERSION_HEX < 0x030800b4
- , nullptr, /*tp_print*/
-#endif
-#if PY_VERSION_HEX >= 0x030800b4
- , 0, /*tp_vectorcall_offset*/
-#endif
- &GetObjectAttr, &SetObjectAttr, nullptr, &GetRepr, nullptr, nullptr, &MappingMethods, nullptr, nullptr, &GetStr, nullptr, nullptr, nullptr,
- Py_TPFLAGS_DEFAULT, "", nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, 0, InitObject, PyType_GenericAlloc, PyType_GenericNew, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, 0
-#if PY_MAJOR_VERSION >= 3
- , nullptr
-#endif
-#if PY_VERSION_HEX >= 0x030800b1
- , nullptr /*tp_vectorcall*/
-#endif
-#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
- , nullptr /*tp_print*/
-#endif
-#if PY_VERSION_HEX >= 0x030C0000
- , 0 /*tp_watched*/
-#endif
- };
-
- template <typename TObjectHolder, typename TObject, typename TTraits>
- PyObject* TPythonType<TObjectHolder, TObject, TTraits>::PyTypeObjPtr =
- reinterpret_cast<PyObject*>(&TPythonType<TObjectHolder, TObject, TTraits>::PyType);
-
- namespace NPrivate {
- template <typename TObject>
- class TUnboundClosureHolder {
- private:
- THolder<PyTypeObject> Holder;
- TString Method;
-
- public:
- TUnboundClosureHolder(PyTypeObject* ptr, const TString& meth)
- : Holder(ptr)
- , Method(meth)
- {
- }
-
- PyTypeObject* GetObject() const {
- return Holder.Get();
- }
-
- const TString GetMethod() const {
- return Method;
- }
-
- PyObject* Call(PyObject* obj, PyObject* args, PyObject*) const {
- TPyObjectPtr callable(PyObject_GetAttrString(obj, Method.c_str()), true);
- if (!callable.Get())
- ythrow yexception() << "PyBind can't call method '" << Method << "'";
- TPyObjectPtr res(PyObject_CallObject(callable.Get(), args), true);
- if (!res.Get() && !PyErr_Occurred())
- ythrow yexception() << "PyBind can't call method '" << Method << "'";
- return res.RefGet();
- }
- };
-
- template <typename TObject>
- class TUnboundClosure: public NPyBind::TPythonType<TUnboundClosureHolder<TObject>, PyTypeObject, TUnboundClosure<TObject>> {
- private:
- typedef class NPyBind::TPythonType<TUnboundClosureHolder<TObject>, PyTypeObject, TUnboundClosure<TObject>> TParent;
- friend class NPyBind::TPythonType<TUnboundClosureHolder<TObject>, PyTypeObject, TUnboundClosure<TObject>>;
-
- class TReprMethodCaller: public TBaseMethodCaller<PyTypeObject> {
- public:
- bool CallMethod(PyObject* closure, PyTypeObject*, PyObject*, PyObject*, PyObject*& res) const override {
- TUnboundClosureHolder<TObject>* hld = TParent::CastToObjectHolder(closure);
- TPyObjectPtr type((PyObject*)hld->GetObject());
-
- TString nameStr;
- TPyObjectPtr name(PyObject_GetAttrString(type.Get(), "__name__"), true);
- if (!name.Get() || !FromPyObject(name.Get(), nameStr))
- ythrow yexception() << "Could not get name of object";
-
- TString methodName(hld->GetMethod());
-
- TString message = "<unbound method " + nameStr + "." + methodName + ">";
- res = ReturnString(message);
- return (res != nullptr);
- }
- };
-
- private:
- TUnboundClosure()
- : TParent("", "")
- {
- TParent::AddCaller("__repr__", new TReprMethodCaller());
- TParent::AddCaller("__str__", new TReprMethodCaller());
- TParent::SetClosure(&Call);
- }
-
- static PyObject* Call(PyObject* closure, PyObject* args, PyObject* kwargs) {
- try {
- TUnboundClosureHolder<TObject>* hld = TParent::CastToObjectHolder(closure);
- if (!hld)
- ythrow yexception() << "Can't cast object to TypeHolder";
-
- size_t size = 0;
- if (!PyTuple_Check(args) || (size = PyTuple_Size(args)) < 1)
- ythrow yexception() << "Can't parse first argument: it should be valid object";
- --size;
- TPyObjectPtr obj(PyTuple_GetItem(args, 0));
- TPyObjectPtr newArgs(PyTuple_New(size), true);
-
- for (size_t i = 0; i < size; ++i) {
- TPyObjectPtr item(PyTuple_GetItem(args, i + 1));
- PyTuple_SetItem(newArgs.Get(), i, item.RefGet());
- }
-
- return hld->Call(obj.Get(), newArgs.Get(), kwargs);
- } catch (const std::exception& ex) {
- PyErr_SetString(::NPyBind::TExceptionsHolder::Instance().ToPyException(ex).Get(), ex.what());
- } catch (...) {
- PyErr_SetString(PyExc_RuntimeError, "Unknown error occurred while trying to call method");
- }
- return nullptr;
- }
-
- static PyTypeObject* GetObject(TUnboundClosureHolder<TObject>& obj) {
- return obj.GetObject();
- }
- };
-
- template <typename TObject>
- class TBoundClosureHolder {
- private:
- TPyObjectPtr Ptr;
- TObject* Object;
- TString Method;
- const TMethodCallers<TObject>& MethodCallers;
-
- public:
- TBoundClosureHolder(PyObject* ptr, TObject* obj, const TString& meth, const TMethodCallers<TObject>& callers)
- : Ptr(ptr)
- , Object(obj)
- , Method(meth)
- , MethodCallers(callers)
- {
- }
-
- TPyObjectPtr GetObjectPtr() const {
- return Ptr;
- }
-
- TObject* GetObject() const {
- return Object;
- }
-
- const TString GetMethod() const {
- return Method;
- }
-
- PyObject* Call(PyObject* args, PyObject* kwargs) const {
- PyObject* res = MethodCallers.CallMethod(Ptr.Get(), Object, args, kwargs, Method);
- if (res == nullptr && !PyErr_Occurred())
- ythrow yexception() << "PyBind can't call method '" << Method << "'";
- return res;
- }
- };
-
- template <typename TObject>
- class TBoundClosure: public TPythonType<TBoundClosureHolder<TObject>, TObject, TBoundClosure<TObject>> {
- private:
- typedef TPythonType<TBoundClosureHolder<TObject>, TObject, TBoundClosure<TObject>> TMyParent;
- class TReprMethodCaller: public TBaseMethodCaller<TObject> {
- public:
- bool CallMethod(PyObject* closure, TObject*, PyObject*, PyObject*, PyObject*& res) const override {
- TBoundClosureHolder<TObject>* hld = TMyParent::CastToObjectHolder(closure);
- TPyObjectPtr obj(hld->GetObjectPtr());
- TPyObjectPtr type(PyObject_Type(obj.Get()), true);
-
- TString reprStr;
- TPyObjectPtr repr(PyObject_Repr(obj.Get()), true);
- if (!repr.Get() || !FromPyObject(repr.Get(), reprStr))
- ythrow yexception() << "Could not get repr of object";
-
- TString nameStr;
- TPyObjectPtr name(PyObject_GetAttrString(type.Get(), "__name__"), true);
- if (!name.Get() || !FromPyObject(name.Get(), nameStr))
- ythrow yexception() << "Could not get name of object";
-
- TString methodName(hld->GetMethod());
-
- TString message = "<bound method " + nameStr + "." + methodName + " of " + reprStr + ">";
- res = ReturnString(message);
- return (res != nullptr);
- }
- };
-
- private:
- static PyObject* Call(PyObject* closure, PyObject* args, PyObject* kwargs) {
- try {
- TBoundClosureHolder<TObject>* hld = TMyParent::CastToObjectHolder(closure);
- if (!hld)
- ythrow yexception() << "Can't cast object to ClosureHolder";
-
- return hld->Call(args, kwargs);
- } catch (const std::exception& ex) {
- PyErr_SetString(::NPyBind::TExceptionsHolder::Instance().ToPyException(ex).Get(), ex.what());
- } catch (...) {
- PyErr_SetString(PyExc_RuntimeError, "Unknown error occurred while trying to call method");
- }
- return nullptr;
- }
-
- public:
- TBoundClosure()
- : TMyParent("", "")
- {
- TMyParent::AddCaller("__repr__", new TReprMethodCaller());
- TMyParent::AddCaller("__str__", new TReprMethodCaller());
- TMyParent::SetClosure(&Call);
- }
-
- static TObject* GetObject(const TBoundClosureHolder<TObject>& closure) {
- return closure.GetObject();
- }
- };
-
- }
-
- template <typename TObjectHolder, typename TObject, typename TTraits>
- PyObject* TPythonType<TObjectHolder, TObject, TTraits>::GetObjectAttr(PyObject* pyObj, char* attr) {
- try {
- TObject* obj = CastToObject(pyObj);
- PyObject* res = obj ? Instance().Attributes.GetAttrGetters().GetAttr(pyObj, *obj, attr) : nullptr;
- if (res == nullptr && Instance().Attributes.GetMethodCallers().HasMethod(pyObj, obj, attr)) {
- TPyObjectPtr r = NPrivate::TBoundClosure<TObject>::Instance().CreatePyObject(new NPrivate::TBoundClosureHolder<TObject>(pyObj, obj, attr, Instance().Attributes.GetMethodCallers()));
- res = r.RefGet();
- }
- if (res == nullptr && !PyErr_Occurred())
- ythrow TPyErr(PyExc_AttributeError) << "PyBind can't get attribute '" << attr << "'";
- return res;
- } catch (const std::exception& ex) {
- PyErr_SetString(TExceptionsHolder::Instance().ToPyException(ex).Get(), ex.what());
- } catch (...) {
- PyErr_SetString(PyExc_RuntimeError, (TString("Unknown error occurred while trying to get attribute '") + attr + "'").c_str());
- }
- return nullptr;
- }
-
- template <typename TObjectHolder, typename TObject, typename TTraits>
- int TPythonType<TObjectHolder, TObject, TTraits>::SetObjectAttr(PyObject* pyObj, char* attr, PyObject* value) {
- try {
- TObject* obj = CastToObject(pyObj);
- bool res = obj ? Instance().Attributes.GetAttrSetters().SetAttr(pyObj, *obj, attr, value) : false;
- if (!res && !PyErr_Occurred())
- ythrow yexception() << "PyBind can't set attribute '" << attr << "'";
- return res ? 0 : -1;
- } catch (const std::exception& ex) {
- PyErr_SetString(TExceptionsHolder::Instance().ToPyException(ex).Get(), ex.what());
- } catch (...) {
- PyErr_SetString(PyExc_RuntimeError, (TString("Unknown error occurred while trying to set attribute '") + attr + "'").c_str());
- }
- return -1;
- }
-
- template <typename TObjectHolder, typename TObject, typename TTraits>
- PyObject* TPythonType<TObjectHolder, TObject, TTraits>::GetStr(PyObject* obj) {
- try {
- TObject* self = CastToObject(obj);
- return Instance().Attributes.GetMethodCallers().CallMethod(obj, self, nullptr, nullptr, "__str__");
- } catch (const std::exception& ex) {
- PyErr_SetString(TExceptionsHolder::Instance().ToPyException(ex).Get(), ex.what());
- } catch (...) {
- PyErr_SetString(PyExc_RuntimeError, (TString("Unknown error occurred while trying to call '__str__'").c_str()));
- }
- return nullptr;
- }
-
- template <typename TObjectHolder, typename TObject, typename TTraits>
- PyObject* TPythonType<TObjectHolder, TObject, TTraits>::GetIter(PyObject* obj) {
- try {
- TObject* self = CastToObject(obj);
- return Instance().Attributes.GetMethodCallers().CallMethod(obj, self, nullptr, nullptr, "__iter__");
- } catch (const std::exception& ex) {
- PyErr_SetString(TExceptionsHolder::Instance().ToPyException(ex).Get(), ex.what());
- } catch (...) {
- PyErr_SetString(PyExc_RuntimeError, (TString("Unknown error occurred while trying to call '__iter__'").c_str()));
- }
- return nullptr;
- }
-
- template <typename TObjectHolder, typename TObject, typename TTraits>
- PyObject* TPythonType<TObjectHolder, TObject, TTraits>::GetNext(PyObject* obj) {
- try {
- TObject* self = CastToObject(obj);
- return Instance().Attributes.GetMethodCallers().CallMethod(obj, self, nullptr, nullptr, "next");
- } catch (const std::exception& ex) {
- PyErr_SetString(TExceptionsHolder::Instance().ToPyException(ex).Get(), ex.what());
- } catch (...) {
- PyErr_SetString(PyExc_RuntimeError, (TString("Unknown error occurred while trying to call 'next'").c_str()));
- }
- return nullptr;
- }
-
- template <typename TObjectHolder, typename TObject, typename TTraits>
- PyObject* TPythonType<TObjectHolder, TObject, TTraits>::GetRepr(PyObject* obj) {
- try {
- TObject* self = CastToObject(obj);
- return Instance().Attributes.GetMethodCallers().CallMethod(obj, self, nullptr, nullptr, "__repr__");
- } catch (const std::exception& ex) {
- PyErr_SetString(TExceptionsHolder::Instance().ToPyException(ex).Get(), ex.what());
- } catch (...) {
- PyErr_SetString(PyExc_RuntimeError, (TString("Unknown error occurred while trying to call '__repr__'").c_str()));
- }
- return nullptr;
- }
-}
diff --git a/library/cpp/pybind/v2.cpp b/library/cpp/pybind/v2.cpp
deleted file mode 100644
index edce0be719..0000000000
--- a/library/cpp/pybind/v2.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-#include "v2.h"
-namespace NPyBind {
- namespace Detail {
- template <>
- PyTypeObject* GetParentType<void>(const TPyModuleDefinition&) {
- return nullptr;
- }
-
-
- template <bool InitEnabled>
- void UpdateClassNamesInModule(TPyModuleDefinition& M, const TString& name, PyTypeObject* pythonType) {
- if (!InitEnabled) {
- return;
- }
- M.ClassName2Type[name] = pythonType;
- }
-
- template <bool InitEnabled>
- void UpdateGetContextInModule(TPyModuleDefinition& M, const TString& name, IGetContextBase* base) {
- if (!InitEnabled) {
- return;
- }
- M.Class2ContextGetter[name] = base;
- }
-
- TPyModuleRegistry::TPyModuleRegistry() {
-#if PY_MAJOR_VERSION >= 3
- NPrivate::AddFinalizationCallBack([this]() {
- if (UnnamedModule) {
- UnnamedModule.Clear();
- }
- Name2Def.clear();
- });
-#endif
- }
- template void UpdateClassNamesInModule<false>(TPyModuleDefinition& M, const TString& name, PyTypeObject* pythonType);
- template void UpdateClassNamesInModule<true>(TPyModuleDefinition& M, const TString& name, PyTypeObject* pythonType);
-
-
- template void UpdateGetContextInModule<false>(TPyModuleDefinition& M, const TString& name, IGetContextBase* pythonType);
- template void UpdateGetContextInModule<true>(TPyModuleDefinition& M, const TString& name, IGetContextBase* pythonType);
- }//Detail
-}//NPyBind
diff --git a/library/cpp/pybind/v2.h b/library/cpp/pybind/v2.h
deleted file mode 100644
index f561d6a380..0000000000
--- a/library/cpp/pybind/v2.h
+++ /dev/null
@@ -1,514 +0,0 @@
-#pragma once
-
-#include <library/cpp/pybind/method.h>
-#include <library/cpp/pybind/typedesc.h>
-#include <library/cpp/pybind/module.h>
-#include <util/generic/hash.h>
-#include <util/generic/hash_set.h>
-#include <util/generic/string.h>
-namespace NPyBind {
-#define DEFINE_CONVERTERS_IMPL(TClass) \
- PyObject* BuildPyObject(typename TClass::TBase&& base) { \
- return TClass::BuildPyObject(std::move(base)); \
- } \
- PyObject* BuildPyObject(const typename TClass::TBase& base) { \
- return TClass::BuildPyObject(base); \
- }
-
-#define DEFINE_CONVERTERS(function) DEFINE_CONVERTERS_IMPL(TFunctionResult<decltype(function)>)
-
-#define DEFINE_TRANSFORMERS_IMPL(TClass) \
- template <> \
- bool ::NPyBind::FromPyObject<typename TClass::TBase*>(PyObject * obj, typename TClass::TBase * &res) { \
- res = TClass::CastToObject(obj); \
- return res != nullptr; \
- } \
- template <> \
- bool ::NPyBind::FromPyObject<typename TClass::TBase const*>(PyObject * obj, typename TClass::TBase const*& res) { \
- res = TClass::CastToObject(obj); \
- return res != nullptr; \
- }
-
-#define DEFINE_TRANSFORMERS(function) DEFINE_TRANSFORMERS_IMPL(TFunctionResult<decltype(function)>)
-
- namespace Detail {
- struct IGetContextBase {
- virtual ~IGetContextBase() = default;
- };
- } //Detail
- struct TPyModuleDefinition {
- static void InitModule(const TString& name);
- static TPyModuleDefinition& GetModule();
-
- TString Name;
- NPyBind::TPyObjectPtr M;
- THashMap<TString, PyTypeObject*> ClassName2Type;
- THashMap<TString, Detail::IGetContextBase*> Class2ContextGetter;
- };
-
- namespace Detail {
- // Manages modules lifecycle
- // IMPORTANT!!! Don't use it in PyBind v1 environment, it will lead to inconsistent state of v1 module
- // UnnamedModule-> new unnamed module stub, this stub become current module. In this case you can add functions to it
- // InitModuleWithName -> convert unnamed module into named one, now you can switch to it in switch, this module remains current
- // SwitchToModule switches to the particular module in registry, this module becomes current.
- class TPyModuleRegistry {
- private:
- TPyModuleRegistry();
- TPyModuleRegistry(const TPyModuleRegistry&) = delete;
- TPyModuleRegistry& operator=(TPyModuleRegistry&) = delete;
- public:
- static TPyModuleRegistry& Get() {
- static TPyModuleRegistry registry;
- return registry;
- }
- TPyModuleDefinition& GetCurrentModule() {
- if (!CurrentModule) {
- GetUnnamedModule();
- }
- return *CurrentModule;
- }
-
- TPyModuleDefinition& GetUnnamedModule() {
- if (!UnnamedModule) {
- UnnamedModule = TPyModuleDefinition();
- CurrentModule = const_cast<TPyModuleDefinition*>(UnnamedModule.Get());
- }
- return *UnnamedModule;
- }
-
- TPyModuleDefinition& InitModuleWithName(const TString& name) {
- if (!UnnamedModule) {
- GetUnnamedModule();
- }
- Name2Def[name] = *UnnamedModule;
- UnnamedModule.Clear();
- CurrentModule = &Name2Def[name];
- return *CurrentModule;
- }
-
- TPyModuleDefinition& SwitchToModuleByName(const TString& name) {
- Y_ENSURE(Name2Def.contains(name));
- Y_ENSURE(UnnamedModule.Empty());
- CurrentModule = &Name2Def[name];
- return *CurrentModule;
- }
- private:
- TPyModuleDefinition* CurrentModule = nullptr;
- TMaybe<TPyModuleDefinition> UnnamedModule;//
- THashMap<TString, TPyModuleDefinition> Name2Def;
- };
- }//Detail
-
- inline void TPyModuleDefinition::InitModule(const TString& name) {
- Detail::TPyModuleRegistry::Get().GetUnnamedModule() = TPyModuleDefinition{name, TModuleHolder::Instance().InitModule(name), {}, {}};
- Detail::TPyModuleRegistry::Get().InitModuleWithName(name);
- }
-
- inline TPyModuleDefinition& TPyModuleDefinition::GetModule() {
- return Detail::TPyModuleRegistry::Get().GetCurrentModule();
- }
-
- namespace Detail {
- template <class TPythonType>
- struct TNameCtx {
- TString ClassShortName;
- static TNameCtx& GetNameCtx() {
- static TNameCtx result;
- return result;
- }
- };
- template <class TBase>
- struct TContextImpl {
- PyTypeObject* ParentType = nullptr;
- TString ClassShortName;
- TString ClassFullName;
- TString ClassDescription;
-
-
- TVector<std::pair<TString, typename TPythonTypeAttributes<TBase>::TCallerPtr>> ListCallers;
- TVector<std::pair<TString, typename TPythonTypeAttributes<TBase>::TGetterPtr>> ListGetters;
- TVector<std::pair<TString, typename TPythonTypeAttributes<TBase>::TSetterPtr>> ListSetters;
- };
-
- template <class TObject>
- struct IGetContext: public IGetContextBase {
- virtual ~IGetContext() = default;
- virtual const TContextImpl<TObject>& GetContext() const = 0;
- };
-
- template <typename THolderClass, typename TBaseClass, bool ShouldEnable, typename=std::enable_if_t<!ShouldEnable || !std::is_default_constructible_v<TBaseClass>>>
- THolderClass* DoInitPureObject(const TVector<TString>&) {
- ythrow yexception() << "Can't create this object in pure mode from python";
- }
-
- template <typename THolderClass, typename TBaseClass, bool ShouldEnable, typename=std::enable_if_t<ShouldEnable && std::is_default_constructible_v<TBaseClass>>, typename=void>
- THolderClass* DoInitPureObject(const TVector<TString>&) {
- return new THolderClass(MakeHolder<TBaseClass>());
- }
-
- template <typename T>
- PyTypeObject* GetParentType(const TPyModuleDefinition& m) {
- auto shortName = Detail::TNameCtx<T>::GetNameCtx().ClassShortName;
- auto it = m.ClassName2Type.find(shortName);
- return (it == m.ClassName2Type.end()) ? nullptr : it->second;
- }
-
- template <>
- PyTypeObject* GetParentType<void>(const TPyModuleDefinition&);
-
- template <bool InitEnabled>
- void UpdateClassNamesInModule(TPyModuleDefinition& M, const TString& name, PyTypeObject* pythonType);
-
- template <bool InitEnabled>
- void UpdateGetContextInModule(TPyModuleDefinition& M, const TString& name, IGetContextBase* base);
- }
-
-
- template <class TParentPyClass_=void>
- struct TPyParentClassTraits {
- using TParentPyClass = TParentPyClass_;
- };
-
- template <bool InitEnabled_, class TParentPyClass_=void>
- struct TPyClassConfigTraits: public TPyParentClassTraits<TParentPyClass_> {
- constexpr static bool InitEnabled = InitEnabled_;
- constexpr static bool RawInit = false;
- };
-
- template <class TParentPyClass_=void>
- struct TPyClassRawInitConfigTraits: public TPyParentClassTraits<TParentPyClass_> {
- constexpr static bool InitEnabled = true;
- constexpr static bool RawInit = true;
- };
-
-
- template <typename TBaseClass, typename TPyClassConfigTraits, typename... ConstructorArgs>
- class TPyClass {
- public:
- using TBase = TBaseClass;
- private:
- using TThisClass = TPyClass<TBaseClass, TPyClassConfigTraits, ConstructorArgs...>;
- using TContext = Detail::TContextImpl<TBase>;
- struct THolder {
- ::THolder<TBase> Holder;
- THolder(::THolder<TBase>&& right)
- : Holder(std::move(right))
- {
- }
- THolder(TBase&& right)
- : Holder(MakeHolder<TBase>(std::move(right)))
- {
- }
- };
-
- class TSelectedTraits: public NPyBind::TPythonType<THolder, TBase, TSelectedTraits> {
- private:
- using TParent = NPyBind::TPythonType<THolder, TBase, TSelectedTraits>;
- friend TParent;
-
- public:
- TSelectedTraits()
- : TParent(TThisClass::GetContext().ClassFullName.data(), TThisClass::GetContext().ClassDescription.data(), TThisClass::GetContext().ParentType)
- {
- for (const auto& caller : TThisClass::GetContext().ListCallers) {
- TParent::AddCaller(caller.first, caller.second);
- }
-
- for (const auto& getter : TThisClass::GetContext().ListGetters) {
- TParent::AddGetter(getter.first, getter.second);
- }
-
- for (const auto& setter : TThisClass::GetContext().ListSetters) {
- TParent::AddSetter(setter.first, setter.second);
- }
- }
-
- static TBase* GetObject(const THolder& holder) {
- return holder.Holder.Get();
- }
-
- static THolder* DoInitObject(PyObject* args, PyObject* kwargs) {
- if constexpr (TPyClassConfigTraits::InitEnabled) {
- if constexpr (TPyClassConfigTraits::RawInit) {
- static_assert(sizeof...(ConstructorArgs) == 0, "Do not pass construction args if use RawInit.");
- return new THolder(::MakeHolder<TBase>(args, kwargs));
- } else {
- if (args && (!PyTuple_Check(args) || PyTuple_Size(args) != sizeof...(ConstructorArgs))) {
- ythrow yexception() << "Method takes " << sizeof...(ConstructorArgs) << " arguments, " << PyTuple_Size(args) << " provided";
- }
- ::THolder<TBaseClass> basePtr{Apply([](auto&&... unpackedArgs) {return new TBase(std::forward<decltype(unpackedArgs)>(unpackedArgs)...); }, GetArguments<ConstructorArgs...>(args))};
- return new THolder(std::move(basePtr));
- }
- } else {
- ythrow yexception() << "Can't create this object from python";
- }
- }
-
- static THolder* DoInitPureObject(const TVector<TString>& properties) {
- return Detail::DoInitPureObject<THolder, TBase, TPyClassConfigTraits::InitEnabled>(properties);
- }
-
- static TBase* CastToObject(PyObject* obj) {
- return TParent::CastToObject(obj);
- }
-
- static PyTypeObject* GetType() {
- return TParent::GetPyTypePtr();
- }
- };
-
- class TContextHolder: public Detail::IGetContext<TBaseClass> {
- public:
- static TContextHolder& GetContextHolder() {
- static TContextHolder holder;
- return holder;
- }
-
- TContext& GetContext() {
- return Context;
- }
- const TContext& GetContext() const override {
- return Context;
- }
- private:
- TContext Context;
- };
-
- template <class TDerivedClass, class TSuperClass>
- class TCallerWrapper: public TBaseMethodCaller<TDerivedClass> {
- public:
- explicit TCallerWrapper(TSimpleSharedPtr<const TBaseMethodCaller<TSuperClass>> baseCaller)
- : BaseCaller(baseCaller) {
- Y_ENSURE(BaseCaller);
- }
-
- bool CallMethod(PyObject* owner, TDerivedClass* self, PyObject* args, PyObject* kwargs, PyObject*& res) const override {
- return BaseCaller->CallMethod(owner, static_cast<TSuperClass*>(self), args, kwargs, res);
- }
-
- private:
- TSimpleSharedPtr<const TBaseMethodCaller<TSuperClass>> BaseCaller;
- };
-
- template <class TDerivedClass, class TSuperClass>
- class TSetterWrapper: public TBaseAttrSetter<TDerivedClass> {
- public:
- explicit TSetterWrapper(TSimpleSharedPtr<TBaseAttrSetter<TSuperClass>> baseSetter)
- : BaseSetter(baseSetter) {
- Y_ENSURE(BaseSetter);
- }
-
- bool SetAttr(PyObject* owner, TDerivedClass& self, const TString& attr, PyObject* val) override {
- return BaseSetter->SetAttr(owner, static_cast<TSuperClass&>(self), attr, val);
- }
-
- private:
- TSimpleSharedPtr<TBaseAttrSetter<TSuperClass>> BaseSetter;
- };
-
- template <class TDerivedClass, class TSuperClass>
- class TGetterWrapper: public TBaseAttrGetter<TDerivedClass> {
- public:
- explicit TGetterWrapper(TSimpleSharedPtr<const TBaseAttrGetter<TSuperClass>> baseGetter)
- : BaseGetter(baseGetter) {
- Y_ENSURE(BaseGetter);
- }
-
- bool GetAttr(PyObject* owner, const TDerivedClass& self, const TString& attr, PyObject*& res) const override {
- return BaseGetter->GetAttr(owner, static_cast<const TSuperClass&>(self), attr, res);
- }
-
- private:
- TSimpleSharedPtr<const TBaseAttrGetter<TSuperClass>> BaseGetter;
- };
-
- template <class TSuperClass, typename=std::enable_if_t<!std::is_same_v<TSuperClass, void>>>
- void ReloadAttrsFromBase() {
- auto shortName = Detail::TNameCtx<TSuperClass>::GetNameCtx().ClassShortName;
- if (!M.Class2ContextGetter.count(shortName)) {
- return;
- }
- auto callerBasePtr = M.Class2ContextGetter[shortName];
- if (auto getContextPtr = dynamic_cast<const Detail::IGetContext<TSuperClass>*>(callerBasePtr)) {
- auto& ctx = getContextPtr->GetContext();
- auto getUniqueNames = [](const auto& collection) {
- THashSet<TString> uniqueNames;
- for (const auto& elem : collection) {
- uniqueNames.insert(elem.first);
- }
- return uniqueNames;
- };
-
- auto uniqueCallerNames = getUniqueNames(GetContext().ListCallers);
- using TConcreteCallerWrapper = TCallerWrapper<TBaseClass, TSuperClass>;
- for (const auto& caller : ctx.ListCallers) {
- if (uniqueCallerNames.contains(caller.first)) {
- continue;
- }
- GetContext().ListCallers.push_back(std::make_pair(caller.first, MakeSimpleShared<TConcreteCallerWrapper>(caller.second)));
- }
-
- auto uniqueGettersNames = getUniqueNames(GetContext().ListGetters);
- using TConcreteGetterWrapper = TGetterWrapper<TBaseClass, TSuperClass>;
- for (const auto& getter : ctx.ListGetters) {
- if (uniqueGettersNames.contains(getter.first)) {
- continue;
- }
- GetContext().ListGetters.push_back(std::make_pair(getter.first, MakeSimpleShared<TConcreteGetterWrapper>(getter.second)));
- }
-
- auto uniqueSetterNames = getUniqueNames(GetContext().ListSetters);
- using TConcreteSetterWrapper = TSetterWrapper<TBaseClass, TSuperClass>;
- for (auto& setter : ctx.ListSetters) {
- if (uniqueSetterNames.contains(setter.first)) {
- continue;
- }
- GetContext().ListSetters.push_back(std::make_pair(setter.first, MakeSimpleShared<TConcreteSetterWrapper>(setter.second)));
- }
- }
- }
-
- template <class TSuperClass, typename=std::enable_if_t<std::is_same_v<TSuperClass, void>>, typename=void>
- void ReloadAttrsFromBase() {
- }
-
- void CompleteImpl() {
- ReloadAttrsFromBase<typename TPyClassConfigTraits::TParentPyClass>();
- TSelectedTraits::Instance().Register(M.M, GetContext().ClassShortName);
- }
-
- static TContext& GetContext() {
- return TContextHolder::GetContextHolder().GetContext();
- }
-
-
- friend struct Detail::TContextImpl<TBase>;//instead of context
- friend struct THolder;
- friend class TSelectedTraits;
-
- using TCallerFunc = std::function<bool(PyObject*, TBaseClass*, PyObject*, PyObject*, PyObject*&)>;
- class TFuncCallerWrapper: public TBaseMethodCaller<TBaseClass> {
- public:
- explicit TFuncCallerWrapper(TCallerFunc func)
- : Func(func) {
- Y_ENSURE(func);
- }
-
- bool CallMethod(PyObject* owner, TBaseClass* self, PyObject* args, PyObject* kwargs, PyObject*& res) const override {
- return Func(owner, self, args, kwargs, res);
- }
- private:
- mutable TCallerFunc Func;
- };
- public:
- TPyClass(const TString& name, const TString& descr = "")
- : M(TPyModuleDefinition::GetModule())
- {
- Detail::UpdateClassNamesInModule<TPyClassConfigTraits::InitEnabled>(M, name, TSelectedTraits::GetType());
- Detail::UpdateGetContextInModule<TPyClassConfigTraits::InitEnabled>(M, name, &TContextHolder::GetContextHolder());
-
- GetContext().ClassFullName = TString::Join(M.Name, ".", name);
- GetContext().ClassShortName = name;
- GetContext().ClassDescription = descr;
- GetContext().ParentType = Detail::GetParentType<typename TPyClassConfigTraits::TParentPyClass>(M);
- Detail::TNameCtx<TBaseClass>::GetNameCtx().ClassShortName = name;
- }
-
- template <typename TMemberFuction, typename = std::enable_if_t<std::is_member_function_pointer_v<TMemberFuction>>, typename=std::enable_if_t<!TIsPointerToConstMemberFunction<TMemberFuction>::value>>
- TThisClass& Def(const TString& name, TMemberFuction t) {
- GetContext().ListCallers.push_back(std::make_pair(name, CreateMethodCaller<TBase>(t)));
- return *this;
- }
-
- template <typename TMemberFuction, typename = std::enable_if_t<std::is_member_function_pointer_v<TMemberFuction>>, typename=std::enable_if_t<TIsPointerToConstMemberFunction<TMemberFuction>::value>, typename=void>
- TThisClass& Def(const TString& name, TMemberFuction t) {
- GetContext().ListCallers.push_back(std::make_pair(name, CreateConstMethodCaller<TBase>(t)));
- return *this;
- }
-
- template <typename TMemberObject, typename = std::enable_if_t<std::is_member_object_pointer_v<TMemberObject>>>
- TThisClass& Def(const TString& name, TMemberObject t) {
- GetContext().ListGetters.push_back(std::make_pair(name, CreateAttrGetter<TBase>(t)));
- GetContext().ListSetters.push_back(std::make_pair(name, CreateAttrSetter<TBase>(t)));
- return *this;
- }
-
- template <typename TResultType, typename... Args>
- TThisClass& DefByFunc(const TString& name, std::function<TResultType(TBaseClass&, Args...)> func) {
- GetContext().ListCallers.push_back(std::make_pair(name, CreateFunctorCaller<TBase, TResultType, Args...>(func)));
- return *this;
- }
-
- TThisClass& DefByFunc(const TString& name, TCallerFunc origFunc) {
- GetContext().ListCallers.push_back(std::make_pair(name, MakeSimpleShared<TFuncCallerWrapper>(origFunc)));
- return *this;
- }
-
- template <typename TMemberObject>
- TThisClass& DefReadonly(const TString& name, TMemberObject t, std::enable_if_t<std::is_member_object_pointer<TMemberObject>::value>* = nullptr) {
- GetContext().ListGetters.push_back(std::make_pair(name, CreateAttrGetter<TBase>(t)));
- return *this;
- }
-
-
- template <typename TMethodGetter, typename TMethodSetter, typename=std::enable_if_t<std::is_member_function_pointer_v<TMethodGetter> && std::is_member_function_pointer_v<TMethodSetter>>>
- TThisClass& AsProperty(const TString& name, TMethodGetter getter, TMethodSetter setter) {
- GetContext().ListGetters.push_back(std::make_pair(name, CreateMethodAttrGetter<TBase>(getter)));
- GetContext().ListSetters.push_back(std::make_pair(name, CreateMethodAttrSetter<TBase>(setter)));
- return *this;
- }
-
- template <typename TMethodGetter, typename TMethodSetter, typename=std::enable_if_t<!std::is_member_function_pointer_v<TMethodGetter> && !std::is_member_function_pointer_v<TMethodSetter>>>
- TThisClass& AsPropertyByFunc(const TString& name, TMethodGetter getter, TMethodSetter setter) {
- GetContext().ListGetters.push_back(std::make_pair(name, CreateFunctorAttrGetter<TBase>(getter)));
- GetContext().ListSetters.push_back(std::make_pair(name, CreateFunctorAttrSetter<TBase>(setter)));
- return *this;
- }
-
- template <typename TMethodGetter, typename=std::enable_if_t<std::is_member_function_pointer_v<TMethodGetter>>>
- TThisClass& AsProperty(const TString& name, TMethodGetter getter) {
- GetContext().ListGetters.push_back(std::make_pair(name, CreateMethodAttrGetter<TBase>(getter)));
- return *this;
- }
-
- template <typename TMethodGetter>
- TThisClass& AsPropertyByFunc(const TString& name, TMethodGetter getter) {
- GetContext().ListGetters.push_back(std::make_pair(name, CreateFunctorAttrGetter<TBase>(getter)));
- return *this;
- }
-
- TThisClass& Complete() {
- if (!Completed) {
- CompleteImpl();
- Completed = true;
- }
- return *this;
- }
-
- public:
- static PyObject* BuildPyObject(TBase&& base) {
- return NPyBind::BuildPyObject(TSelectedTraits::Instance().CreatePyObject(new THolder(std::move(base))));
- }
-
- static PyObject* BuildPyObject(const TBase& base) {
- return NPyBind::BuildPyObject(TSelectedTraits::Instance().CreatePyObject(new THolder(TBase(base)))); // WARN - copy
- }
-
- static TBase* CastToObject(PyObject* obj) {
- return TSelectedTraits::CastToObject(obj);
- }
-
- private:
- TPyModuleDefinition& M;
- bool Completed = false;
- };
-
- template <typename TFunctionSignature, TFunctionSignature function>
- void DefImpl(const TString& name, const TString& descr = "") {
- NPyBind::TModuleHolder::Instance().AddModuleMethod<TModuleMethodCaller<TFunctionSignature, function>::Call>(name, descr);
- }
-
-#define DefFunc(NAME, FUNC) NPyBind::DefImpl<decltype(FUNC), FUNC>(NAME)
-#define DefFuncDescr(NAME, FUNC, DESCR) NPyBind::DefImpl<decltype(FUNC), FUNC>(NAME, DESCR)
-};
diff --git a/library/cpp/pybind/ya.make b/library/cpp/pybind/ya.make
deleted file mode 100644
index 9b7b3413f2..0000000000
--- a/library/cpp/pybind/ya.make
+++ /dev/null
@@ -1,14 +0,0 @@
-PY23_NATIVE_LIBRARY()
-
-SRCS(
- cast.cpp
- pod.cpp
- typedesc.cpp
- module.cpp
- exceptions.cpp
- embedding.cpp
- empty.cpp
- v2.cpp
-)
-
-END()
diff --git a/library/python/archive/__init__.py b/library/python/archive/__init__.py
deleted file mode 100644
index a6e032ff4c..0000000000
--- a/library/python/archive/__init__.py
+++ /dev/null
@@ -1,266 +0,0 @@
-import errno
-import logging
-import os
-import random
-import shutil
-import stat
-import string
-import sys
-
-import six
-
-import libarchive
-import libarchive._libarchive as _libarchive
-
-from pathlib2 import PurePath
-
-logger = logging.getLogger(__name__)
-
-GZIP = "gzip"
-ZSTD = "zstd"
-
-ENCODING = "utf-8"
-
-
-class ConfigureError(Exception):
- pass
-
-
-class Level(object):
- def __init__(self, level):
- self.level = level
-
-
-class Compression(object):
- Fast = Level(1)
- Default = Level(2)
- Best = Level(3)
-
-
-def get_compression_level(filter_name, level):
- if level is None or not filter_name:
- return None
- elif isinstance(level, Level):
- level = {
- GZIP: {
- Compression.Fast: 1,
- Compression.Default: 6,
- Compression.Best: 9,
- },
- ZSTD: {
- Compression.Fast: 1,
- Compression.Default: 3,
- Compression.Best: 22,
- },
- }[filter_name][level]
- return level
-
-
-def encode(value, encoding):
- return value.encode(encoding)
-
-
-def extract_tar(tar_file_path, output_dir, strip_components=None, fail_on_duplicates=True):
- output_dir = encode(output_dir, ENCODING)
- _make_dirs(output_dir)
- with libarchive.Archive(tar_file_path, mode="rb") as tarfile:
- for e in tarfile:
- p = _strip_prefix(e.pathname, strip_components)
- if not p:
- continue
- dest = os.path.join(output_dir, encode(p, ENCODING))
- if e.pathname.endswith("/"):
- _make_dirs(dest)
- continue
-
- if strip_components and fail_on_duplicates:
- if os.path.exists(dest):
- raise Exception(
- "The file {} is duplicated because of strip_components={}".format(dest, strip_components)
- )
-
- _make_dirs(os.path.dirname(dest))
-
- if e.ishardlink():
- src = os.path.join(output_dir, _strip_prefix(e.hardlink, strip_components))
- _hardlink(src, dest)
- continue
- if e.issym():
- src = _strip_prefix(e.linkname, strip_components)
- _symlink(src, dest)
- continue
-
- with open(dest, "wb") as f:
- if hasattr(os, "fchmod"):
- os.fchmod(f.fileno(), e.mode & 0o7777)
- libarchive.call_and_check(
- _libarchive.archive_read_data_into_fd,
- tarfile._a,
- tarfile._a,
- f.fileno(),
- )
-
-
-def _strip_prefix(path, strip_components):
- if not strip_components:
- return path
- p = PurePath(path)
- stripped = str(p.relative_to(*p.parts[:strip_components]))
- return '' if stripped == '.' else stripped
-
-
-def tar(
- paths,
- output,
- compression_filter=None,
- compression_level=None,
- fixed_mtime=None,
- onerror=None,
- postprocess=None,
- dereference=False,
-):
- if isinstance(paths, six.string_types):
- paths = [paths]
-
- if isinstance(output, six.string_types):
- temp_tar_path, stream = (
- output + "." + "".join(random.sample(string.ascii_lowercase, 8)),
- None,
- )
- else:
- temp_tar_path, stream = None, output
-
- compression_level = get_compression_level(compression_filter, compression_level)
-
- try:
- if compression_filter:
- filter_name = compression_filter
- if compression_level is not None:
- filter_opts = {"compression-level": str(compression_level)}
- else:
- filter_opts = {}
- # force gzip don't store mtime of the original file being compressed (http://www.gzip.org/zlib/rfc-gzip.html#file-format)
- if fixed_mtime is not None and compression_filter == GZIP:
- filter_opts["timestamp"] = ""
- else:
- filter_name = filter_opts = None
-
- with libarchive.Archive(
- stream or temp_tar_path,
- mode="wb",
- format="gnu",
- filter=filter_name,
- filter_opts=filter_opts,
- fixed_mtime=fixed_mtime,
- ) as tarfile:
- # determine order if fixed_mtime is specified to produce stable archive
- paths = paths if fixed_mtime is None else sorted(paths)
-
- for p in paths:
- if type(p) == tuple:
- path, arcname = p
- else:
- path, arcname = p, os.path.basename(p)
-
- if os.path.isdir(path):
- for root, dirs, files in os.walk(path, followlinks=dereference):
- if fixed_mtime is None:
- entries = dirs + files
- else:
- entries = sorted(dirs) + sorted(files)
-
- reldir = os.path.relpath(root, path)
- for f in entries:
- _writepath(
- tarfile,
- os.path.join(root, f),
- os.path.normpath(os.path.join(arcname, reldir, f)),
- onerror,
- postprocess,
- dereference,
- )
- else:
- if not os.path.exists(path):
- raise OSError("Specified path doesn't exist: {}".format(path))
- _writepath(tarfile, path, arcname, onerror, postprocess, dereference)
-
- if temp_tar_path:
- os.rename(temp_tar_path, output)
- except Exception:
- if temp_tar_path and os.path.exists(temp_tar_path):
- os.remove(temp_tar_path)
- raise
-
-
-def _writepath(tarfile, src, dst, onerror, postprocess, dereference):
- def tar_writepath(src, dst):
- st = os.lstat(src)
- if stat.S_ISREG(st.st_mode) or stat.S_ISDIR(st.st_mode) or stat.S_ISLNK(st.st_mode):
- if dereference and stat.S_ISLNK(st.st_mode):
- src = os.path.realpath(src)
-
- tarfile.writepath(src, dst)
-
- if postprocess:
- postprocess(src, dst, st.st_mode)
- else:
- logger.debug("Skipping non-regular file '%s' (stat: %s)", src, st)
-
- try:
- return tar_writepath(src, dst)
- except Exception as e:
- if isinstance(e, OSError) and e.errno == errno.ENOENT:
- logger.debug(
- "Skipping missing file '%s' - looks like directory content has changed during archiving",
- src,
- )
- return
-
- if onerror:
- if onerror(src, dst, sys.exc_info()):
- return tar_writepath(src, dst)
- else:
- raise
-
-
-def check_tar(tar_file_path):
- if os.path.isfile(tar_file_path) or os.path.islink(tar_file_path):
- return libarchive.is_archive(tar_file_path)
- return False
-
-
-def _make_dirs(path):
- try:
- os.makedirs(path)
- except OSError as e:
- if e.errno != errno.EEXIST or not os.path.isdir(path):
- raise
-
-
-def _hardlink(src, dst):
- if hasattr(os, "link"):
- os.link(src, dst)
- else:
- shutil.copyfile(src, dst)
-
-
-def _symlink(src, dst):
- if hasattr(os, "symlink"):
- os.symlink(src, dst)
- else:
- # Windows specific case - we cannot copy file right now,
- # because it doesn't exist yet (and would be met later in the archive) or symlink is broken.
- # Act like tar and tarfile - skip such symlinks
- if os.path.exists(src):
- shutil.copytree(src, dst)
-
-
-def get_archive_filter_name(filename):
- filters = libarchive.get_archive_filter_names(filename)
- # https://a.yandex-team.ru/arc/trunk/arcadia/contrib/libs/libarchive/libarchive/archive_read.c?rev=5800047#L522
- assert filters[-1] == "none", filters
- if len(filters) == 1:
- return None
- if len(filters) == 2:
- return filters[0]
- raise Exception("Archive has chain of filter: {}".format(filters))
diff --git a/library/python/archive/ya.make b/library/python/archive/ya.make
deleted file mode 100644
index 5b86a45a42..0000000000
--- a/library/python/archive/ya.make
+++ /dev/null
@@ -1,19 +0,0 @@
-PY23_LIBRARY()
-
-STYLE_PYTHON()
-
-PY_SRCS(
- __init__.py
-)
-
-PEERDIR(
- contrib/python/pathlib2
- contrib/python/python-libarchive
-)
-
-END()
-
-RECURSE_FOR_TESTS(
- benchmark
- test
-)
diff --git a/library/python/cityhash/cityhash.pyx b/library/python/cityhash/cityhash.pyx
deleted file mode 100644
index 6f0046f0d7..0000000000
--- a/library/python/cityhash/cityhash.pyx
+++ /dev/null
@@ -1,75 +0,0 @@
-from libcpp.pair cimport pair
-
-cdef extern from "util/system/types.h":
- ctypedef unsigned long ui64
-
-
-cdef extern from "util/digest/city.h":
- ui64 CityHash64(const char* buf, size_t len) nogil
- pair[ui64, ui64] CityHash128(const char* buf, size_t len) nogil
- ui64 CityHash64WithSeed(const char* buf, size_t len, ui64 seed) nogil
-
-
-cdef extern from "library/python/cityhash/hash.h":
- ui64 FileCityHash128WithSeedHigh64(const char* fpath) nogil except+
- ui64 FileCityHash64(const char* fpath) nogil except+
-
-
-def hash64(content):
- cdef const char* s = content
- cdef size_t size = len(content)
- cdef ui64 res = 0
-
- if size > 128:
- with nogil:
- res = CityHash64(s, size)
- else:
- res = CityHash64(s, size)
-
- return res
-
-def hash128(content):
- cdef const char* s = content
- cdef size_t size = len(content)
- cdef pair[ui64, ui64] res = pair[ui64, ui64](0, 0)
-
- if size > 128:
- with nogil:
- res = CityHash128(s, size)
- else:
- res = CityHash128(s, size)
- return res
-
-
-def hash64seed(content, seed):
- cdef const char* s = content
- cdef size_t size = len(content)
- cdef ui64 _seed = seed;
-
- if size > 128:
- with nogil:
- res = CityHash64WithSeed(s, size, _seed)
- else:
- res = CityHash64WithSeed(s, size, _seed)
-
- return res
-
-
-def filehash64(path):
- cdef const char* p = path
- cdef ui64 res = 0
-
- with nogil:
- res = FileCityHash64(p)
-
- return res
-
-
-def filehash128high64(path):
- cdef const char* p = path
- cdef ui64 res = 0
-
- with nogil:
- res = FileCityHash128WithSeedHigh64(p)
-
- return res
diff --git a/library/python/cityhash/hash.cpp b/library/python/cityhash/hash.cpp
deleted file mode 100644
index 17bd3a75f3..0000000000
--- a/library/python/cityhash/hash.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#include "hash.h"
-
-#include <util/digest/city.h>
-#include <util/generic/string.h>
-#include <util/memory/blob.h>
-#include <util/system/file.h>
-#include <util/system/fstat.h>
-
-void ReadFile(const char* fpath, TBlob& blob) {
- TFile f(TString{fpath}, RdOnly | Seq);
- const TFileStat fs(f);
- auto size = fs.Size;
-
- if (size < (64 << 10)) {
- blob = TBlob::FromFileContent(f, 0, size);
- } else {
- blob = TBlob::FromFile(f);
- }
-}
-
-ui64 FileCityHash128WithSeedHigh64(const char* fpath) {
- TBlob blob;
- ReadFile(fpath, blob);
- const uint128 hash = CityHash128WithSeed((const char*)blob.Data(), blob.Size(), uint128(0, blob.Size()));
- return Uint128High64(hash);
-}
-
-ui64 FileCityHash64(const char* fpath) {
- TBlob blob;
- ReadFile(fpath, blob);
- return CityHash64(static_cast<const char*>(blob.Data()), blob.Size());
-}
diff --git a/library/python/cityhash/hash.h b/library/python/cityhash/hash.h
deleted file mode 100644
index 64b22ba74b..0000000000
--- a/library/python/cityhash/hash.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#pragma once
-
-#include <util/system/defaults.h>
-
-ui64 FileCityHash128WithSeedHigh64(const char* fpath);
-ui64 FileCityHash64(const char* fpath);
diff --git a/library/python/cityhash/ya.make b/library/python/cityhash/ya.make
deleted file mode 100644
index 7948e19389..0000000000
--- a/library/python/cityhash/ya.make
+++ /dev/null
@@ -1,16 +0,0 @@
-PY23_LIBRARY()
-
-SRCS(
- hash.cpp
-)
-
-PY_SRCS(
- TOP_LEVEL
- cityhash.pyx
-)
-
-END()
-
-RECURSE_FOR_TESTS(
- test
-)
diff --git a/library/python/codecs/__codecs.pyx b/library/python/codecs/__codecs.pyx
deleted file mode 100644
index 42ec37fe88..0000000000
--- a/library/python/codecs/__codecs.pyx
+++ /dev/null
@@ -1,61 +0,0 @@
-import six
-
-from libcpp cimport bool
-
-from util.generic.string cimport TString, TStringBuf
-
-
-def to_bytes(s):
- try:
- return s.encode('utf-8')
- except AttributeError:
- pass
-
- return s
-
-
-def from_bytes(s):
- if six.PY3:
- return s.decode('utf-8')
-
- return s
-
-
-cdef extern from "library/cpp/blockcodecs/codecs.h" namespace "NBlockCodecs":
- cdef cppclass ICodec:
- void Encode(TStringBuf data, TString& res) nogil
- void Decode(TStringBuf data, TString& res) nogil
-
- cdef const ICodec* Codec(const TStringBuf& name) except +
- cdef TString ListAllCodecsAsString() except +
-
-
-def dumps(name, data):
- name = to_bytes(name)
-
- cdef const ICodec* codec = Codec(TStringBuf(name, len(name)))
- cdef TString res
- cdef TStringBuf cdata = TStringBuf(data, len(data))
-
- with nogil:
- codec.Encode(cdata, res)
-
- return res.c_str()[:res.length()]
-
-
-def loads(name, data):
- name = to_bytes(name)
-
- cdef const ICodec* codec = Codec(TStringBuf(name, len(name)))
- cdef TString res
- cdef TStringBuf cdata = TStringBuf(data, len(data))
-
- with nogil:
- codec.Decode(cdata, res)
-
- return res.c_str()[:res.length()]
-
-def list_all_codecs():
- cdef TString res = ListAllCodecsAsString()
-
- return from_bytes(res.c_str()[:res.length()]).split(',')
diff --git a/library/python/codecs/__init__.py b/library/python/codecs/__init__.py
deleted file mode 100644
index b9fb00deb0..0000000000
--- a/library/python/codecs/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from __codecs import loads, dumps, list_all_codecs # noqa
diff --git a/library/python/codecs/ya.make b/library/python/codecs/ya.make
deleted file mode 100644
index f42d115d5d..0000000000
--- a/library/python/codecs/ya.make
+++ /dev/null
@@ -1,16 +0,0 @@
-PY23_LIBRARY()
-
-PEERDIR(
- library/cpp/blockcodecs
- contrib/python/six
-)
-
-PY_SRCS(
- __init__.py
-)
-
-BUILDWITH_CYTHON_CPP(__codecs.pyx)
-
-PY_REGISTER(__codecs)
-
-END()
diff --git a/library/python/compress/__init__.py b/library/python/compress/__init__.py
deleted file mode 100644
index 380ec47dca..0000000000
--- a/library/python/compress/__init__.py
+++ /dev/null
@@ -1,147 +0,0 @@
-from io import open
-
-import struct
-import json
-import os
-import logging
-
-import library.python.par_apply as lpp
-import library.python.codecs as lpc
-
-
-logger = logging.getLogger('compress')
-
-
-def list_all_codecs():
- return sorted(frozenset(lpc.list_all_codecs()))
-
-
-def find_codec(ext):
- def ext_compress(x):
- return lpc.dumps(ext, x)
-
- def ext_decompress(x):
- return lpc.loads(ext, x)
-
- ext_decompress(ext_compress(b''))
-
- return {'c': ext_compress, 'd': ext_decompress, 'n': ext}
-
-
-def codec_for(path):
- for ext in reversed(path.split('.')):
- try:
- return find_codec(ext)
- except Exception as e:
- logger.debug('in codec_for(): %s', e)
-
- raise Exception('unsupported file %s' % path)
-
-
-def compress(fr, to, codec=None, fopen=open, threads=1):
- if codec:
- codec = find_codec(codec)
- else:
- codec = codec_for(to)
-
- func = codec['c']
-
- def iter_blocks():
- with fopen(fr, 'rb') as f:
- while True:
- chunk = f.read(16 * 1024 * 1024)
-
- if chunk:
- yield chunk
- else:
- yield b''
-
- return
-
- def iter_results():
- info = {
- 'codec': codec['n'],
- }
-
- if fr:
- info['size'] = os.path.getsize(fr)
-
- yield json.dumps(info, sort_keys=True) + '\n'
-
- for c in lpp.par_apply(iter_blocks(), func, threads):
- yield c
-
- with fopen(to, 'wb') as f:
- for c in iter_results():
- logger.debug('complete %s', len(c))
- f.write(struct.pack('<I', len(c)))
-
- try:
- f.write(c)
- except TypeError:
- f.write(c.encode('utf-8'))
-
-
-def decompress(fr, to, codec=None, fopen=open, threads=1):
- def iter_chunks():
- with fopen(fr, 'rb') as f:
- cnt = 0
-
- while True:
- ll = f.read(4)
-
- if ll:
- ll = struct.unpack('<I', ll)[0]
-
- if ll:
- if ll > 100000000:
- raise Exception('broken stream')
-
- yield f.read(ll)
-
- cnt += ll
- else:
- if not cnt:
- raise Exception('empty stream')
-
- return
-
- it = iter_chunks()
- extra = []
-
- for chunk in it:
- hdr = {}
-
- try:
- hdr = json.loads(chunk)
- except Exception as e:
- logger.info('can not parse header, suspect old format: %s', e)
- extra.append(chunk)
-
- break
-
- def resolve_codec():
- if 'codec' in hdr:
- return find_codec(hdr['codec'])
-
- if codec:
- return find_codec(codec)
-
- return codec_for(fr)
-
- dc = resolve_codec()['d']
-
- def iter_all_chunks():
- for x in extra:
- yield x
-
- for x in it:
- yield x
-
- with fopen(to, 'wb') as f:
- for c in lpp.par_apply(iter_all_chunks(), dc, threads):
- if c:
- logger.debug('complete %s', len(c))
- f.write(c)
- else:
- break
diff --git a/library/python/compress/ya.make b/library/python/compress/ya.make
deleted file mode 100644
index bbf2a784e2..0000000000
--- a/library/python/compress/ya.make
+++ /dev/null
@@ -1,16 +0,0 @@
-PY23_LIBRARY()
-
-PEERDIR(
- library/python/codecs
- library/python/par_apply
-)
-
-PY_SRCS(
- __init__.py
-)
-
-END()
-
-RECURSE_FOR_TESTS(
- tests
-)
diff --git a/library/python/json/__init__.py b/library/python/json/__init__.py
deleted file mode 100644
index c6420d5e6d..0000000000
--- a/library/python/json/__init__.py
+++ /dev/null
@@ -1,44 +0,0 @@
-from library.python.json.loads import loads as _loads
-from simplejson import loads as _sj_loads
-
-
-def loads(*args, **kwargs):
- try:
- return _loads(*args, **kwargs)
- except Exception as e:
- if 'invalid syntax at token' in str(e):
- kwargs.pop('intern_keys', None)
- kwargs.pop('intern_vals', None)
- kwargs.pop('may_unicode', None)
- return _sj_loads(*args, **kwargs)
-
- raise
-
-
-from simplejson import load, dump, dumps # noqa
-
-
-def read_file(file_name, **kwargs):
- """
- Read file and return its parsed json contents.
-
- All kwargs will be proxied to `json.load` method as is.
-
- :param file_name: file with json contents
- :return: parsed json contents
- """
- with open(file_name) as f:
- return load(f, **kwargs)
-
-
-def write_file(file_name, contents, **kwargs):
- """
- Dump json data to file.
-
- All kwargs will be proxied to `json.dump` method as is.
-
- :param file_name: file to dump to
- :param contents: JSON-serializable object
- """
- with open(file_name, "w") as f:
- dump(contents, f, **kwargs)
diff --git a/library/python/json/loads.cpp b/library/python/json/loads.cpp
deleted file mode 100644
index 19cdb096ae..0000000000
--- a/library/python/json/loads.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-#include "loads.h"
-
-#include <Python.h>
-
-#include <library/cpp/json/fast_sax/parser.h>
-
-#include <util/generic/algorithm.h>
-#include <util/generic/stack.h>
-#include <util/generic/vector.h>
-#include <util/generic/ylimits.h>
-#include <util/string/ascii.h>
-
-using namespace NJson;
-
-namespace {
- enum EKind {
- Undefined,
- Array,
- Dict,
- Value,
- Key,
- };
-
- static inline TStringBuf ToStr(EKind kind) noexcept {
- switch (kind) {
- case Undefined:
- return TStringBuf("Undefined");
-
- case Array:
- return TStringBuf("Array");
-
- case Dict:
- return TStringBuf("Dict");
-
- case Value:
- return TStringBuf("Value");
-
- case Key:
- return TStringBuf("Key");
- }
-
- Y_UNREACHABLE();
- }
-
- struct TUnref {
- static inline void Destroy(PyObject* o) noexcept {
- Py_XDECREF(o);
- }
- };
-
- using TObjectPtr = TAutoPtr<PyObject, TUnref>;
-
- static inline TObjectPtr BuildBool(bool val) noexcept {
- if (val) {
- Py_RETURN_TRUE;
- }
-
- Py_RETURN_FALSE;
- }
-
- // Translate python exceptions from object-creating functions into c++ exceptions
- // Such errors are reported by returning nullptr
- // When a python error is set and C++ exception is caught by Cython wrapper,
- // Python exception is propagated, while C++ exception is discarded.
- PyObject* CheckNewObject(PyObject* obj) {
- Y_ENSURE(obj != nullptr, "got python exception");
- return obj;
- }
-
- void CheckRetcode(int retcode) {
- Y_ENSURE(retcode == 0, "got python exception");
- }
-
- static inline TObjectPtr BuildSmall(long val) {
-#if PY_VERSION_HEX >= 0x03000000
- return CheckNewObject(PyLong_FromLong(val));
-#else
- return CheckNewObject(PyInt_FromLong(val));
-#endif
- }
-
- PyObject* CreatePyString(TStringBuf str, bool intern, bool mayUnicode) {
-#if PY_VERSION_HEX >= 0x03000000
- Y_UNUSED(mayUnicode);
- PyObject* pyStr = PyUnicode_FromStringAndSize(str.data(), str.size());
- if (intern) {
- PyUnicode_InternInPlace(&pyStr);
- }
-#else
- const bool needUnicode = mayUnicode && !AllOf(str, IsAscii);
- PyObject* pyStr = needUnicode ? PyUnicode_FromStringAndSize(str.data(), str.size())
- : PyString_FromStringAndSize(str.data(), str.size());
- if (intern && !needUnicode) {
- PyString_InternInPlace(&pyStr);
- }
-#endif
- return pyStr;
- }
-
- struct TVal {
- EKind Kind = Undefined;
- TObjectPtr Val;
-
- inline TVal() noexcept
- : Kind(Undefined)
- {
- }
-
- inline TVal(EKind kind, TObjectPtr val) noexcept
- : Kind(kind)
- , Val(val)
- {
- }
- };
-
- static inline TObjectPtr NoneRef() noexcept {
- Py_RETURN_NONE;
- }
-
- struct TContext: public TJsonCallbacks {
- const bool InternKeys;
- const bool InternVals;
- const bool MayUnicode;
- TStack<TVal, TVector<TVal>> S;
-
- inline TContext(bool internKeys, bool internVals, bool mayUnicode)
- : TJsonCallbacks(true)
- , InternKeys(internKeys)
- , InternVals(internVals)
- , MayUnicode(mayUnicode)
- {
- S.emplace();
- }
-
- inline bool Consume(TObjectPtr o) {
- auto& t = S.top();
-
- if (t.Kind == Array) {
- CheckRetcode(PyList_Append(t.Val.Get(), o.Get()));
- } else if (t.Kind == Key) {
- auto key = S.top().Val;
-
- S.pop();
-
- CheckRetcode(PyDict_SetItem(S.top().Val.Get(), key.Get(), o.Get()));
- } else {
- t = TVal(Value, o);
- }
-
- return true;
- }
-
- inline TObjectPtr Pop(EKind expect) {
- auto res = S.top();
-
- S.pop();
-
- if (res.Kind != expect) {
- ythrow yexception() << "unexpected kind(expect " << ToStr(expect) << ", got " << ToStr(res.Kind) << ")";
- }
-
- return res.Val;
- }
-
- inline void Push(EKind kind, TObjectPtr object) {
- S.push(TVal(kind, object));
- }
-
- virtual bool OnNull() {
- return Consume(NoneRef());
- }
-
- virtual bool OnBoolean(bool v) {
- return Consume(BuildBool(v));
- }
-
- virtual bool OnInteger(long long v) {
- if (v >= (long long)Min<long>()) {
- return Consume(BuildSmall((long)v));
- }
-
- return Consume(CheckNewObject(PyLong_FromLongLong(v)));
- }
-
- virtual bool OnUInteger(unsigned long long v) {
- if (v <= (unsigned long long)Max<long>()) {
- return Consume(BuildSmall((long)v));
- }
-
- return Consume(CheckNewObject(PyLong_FromUnsignedLongLong(v)));
- }
-
- virtual bool OnDouble(double v) {
- return Consume(CheckNewObject(PyFloat_FromDouble(v)));
- }
-
- virtual bool OnString(const TStringBuf& v) {
- return Consume(CheckNewObject(CreatePyString(v, InternVals, MayUnicode)));
- }
-
- virtual bool OnOpenMap() {
- Push(Dict, CheckNewObject(PyDict_New()));
-
- return true;
- }
-
- virtual bool OnCloseMap() {
- return Consume(Pop(Dict));
- }
-
- virtual bool OnMapKey(const TStringBuf& k) {
- Push(Key, CheckNewObject(CreatePyString(k, InternKeys, MayUnicode)));
- return true;
- }
-
- virtual bool OnOpenArray() {
- Push(Array, CheckNewObject(PyList_New(0)));
-
- return true;
- }
-
- virtual bool OnCloseArray() {
- return Consume(Pop(Array));
- }
- };
-}
-
-PyObject* LoadJsonFromString(const char* data, size_t len, bool internKeys, bool internVals, bool mayUnicode) {
- TContext ctx(internKeys, internVals, mayUnicode);
-
- if (!len) {
- ythrow yexception() << "parse error: zero length input string";
- }
-
- if (!NJson::ReadJsonFast(TStringBuf(data, len), &ctx)) {
- ythrow yexception() << "parse error";
- }
-
- auto& s = ctx.S;
-
- if (!s || s.top().Kind != Value) {
- ythrow yexception() << "shit happen";
- }
-
- return s.top().Val.Release();
-}
diff --git a/library/python/json/loads.h b/library/python/json/loads.h
deleted file mode 100644
index 62dcdf6f21..0000000000
--- a/library/python/json/loads.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#pragma once
-
-#include <Python.h>
-
-PyObject* LoadJsonFromString(const char* data, size_t len, bool internKeys = false, bool internVals = false, bool mayUnicode = false);
diff --git a/library/python/json/loads.pyx b/library/python/json/loads.pyx
deleted file mode 100644
index 82e5c6dce7..0000000000
--- a/library/python/json/loads.pyx
+++ /dev/null
@@ -1,14 +0,0 @@
-from libcpp cimport bool
-
-cdef extern from "library/python/json/loads.h":
- object LoadJsonFromString(const char*, size_t, bool internKeys, bool internVals, bool mayUnicode) except +
-
-
-def loads(s, intern_keys = False, intern_vals = False, may_unicode = False):
- if isinstance(s, unicode):
- s = s.encode('utf-8')
-
- try:
- return LoadJsonFromString(s, len(s), intern_keys, intern_vals, may_unicode)
- except Exception as e:
- raise ValueError(str(e))
diff --git a/library/python/json/ya.make b/library/python/json/ya.make
deleted file mode 100644
index 74a82de9d8..0000000000
--- a/library/python/json/ya.make
+++ /dev/null
@@ -1,17 +0,0 @@
-PY23_LIBRARY()
-
-PEERDIR(
- contrib/python/simplejson
- library/cpp/json/fast_sax
-)
-
-PY_SRCS(
- __init__.py
- loads.pyx
-)
-
-SRCS(
- loads.cpp
-)
-
-END()
diff --git a/library/python/par_apply/__init__.py b/library/python/par_apply/__init__.py
deleted file mode 100644
index 19b89ae843..0000000000
--- a/library/python/par_apply/__init__.py
+++ /dev/null
@@ -1,114 +0,0 @@
-import sys
-import threading
-import six
-
-from six.moves import queue
-
-
-def par_apply(seq, func, thr_num, join_polling=None):
- if thr_num < 2:
- for x in seq:
- yield func(x)
-
- return
-
- in_q = queue.Queue()
- out_q = queue.Queue()
-
- def enumerate_blocks():
- n = 0
-
- for b in seq:
- yield n, [b]
- n += 1
-
- yield n, None
-
- def iter_out():
- n = 0
- d = {}
-
- while True:
- if n in d:
- r = d[n]
- del d[n]
- n += 1
-
- yield r
- else:
- res = out_q.get()
-
- d[res[0]] = res
-
- out_iter = iter_out()
-
- def wait_block():
- for x in out_iter:
- return x
-
- def iter_compressed():
- p = 0
-
- for n, b in enumerate_blocks():
- in_q.put((n, b))
-
- while n > p + (thr_num * 2):
- p, b, c = wait_block()
-
- if not b:
- return
-
- yield p, c
-
- while True:
- p, b, c = wait_block()
-
- if not b:
- return
-
- yield p, c
-
- def proc():
- while True:
- data = in_q.get()
-
- if data is None:
- return
-
- n, b = data
-
- if b:
- try:
- res = (func(b[0]), None)
- except Exception:
- res = (None, sys.exc_info())
- else:
- res = (None, None)
-
- out_q.put((n, b, res))
-
- thrs = [threading.Thread(target=proc) for i in range(0, thr_num)]
-
- for t in thrs:
- t.start()
-
- try:
- for p, c in iter_compressed():
- res, err = c
-
- if err:
- six.reraise(*err)
-
- yield res
- finally:
- for t in thrs:
- in_q.put(None)
-
- for t in thrs:
- if join_polling is not None:
- while True:
- t.join(join_polling)
- if not t.is_alive():
- break
- else:
- t.join()
diff --git a/library/python/par_apply/ya.make b/library/python/par_apply/ya.make
deleted file mode 100644
index b14592ab79..0000000000
--- a/library/python/par_apply/ya.make
+++ /dev/null
@@ -1,11 +0,0 @@
-PY23_LIBRARY()
-
-PEERDIR(
- contrib/python/six
-)
-
-PY_SRCS(
- __init__.py
-)
-
-END()
diff --git a/library/python/retry/__init__.py b/library/python/retry/__init__.py
deleted file mode 100644
index 5520a70332..0000000000
--- a/library/python/retry/__init__.py
+++ /dev/null
@@ -1,250 +0,0 @@
-import copy
-import datetime
-import functools
-import itertools
-import logging
-import random
-import time
-
-
-"""
-Retry library provides an ability to retry function calls in a configurable way.
-
-To retry a certain function call use `retry_call` function. To make function auto-retriable use `retry`
-or `retry_intrusive` decorators. Both `retry_call` and `retry` optionally accept retry configuration object
-or its fields as kwargs. The `retry_intrusive` is designed for methods and uses intrusive configuration object.
-
->>> retry_call(foo)
->>> retry_call(foo, foo_args, foo_kwargs)
->>> retry_call(foo, foo_args, foo_kwargs, conf=conf)
-
->>> @retry()
->>> def foo(...):
->>> ...
-
->>> @retry(conf)
->>> def foo(...):
->>> ...
-
->>> class Obj(object):
->>> def __init__(self):
->>> self.retry_conf = conf
->>>
->>> @retry_intrusive
->>> def foo(self, ...):
->>> ...
-
-This library differs from its alternatives:
- * `retry` contrib library lacks time-based limits, reusable configuration objects and is generally less flexible
- * `retrying` contrib library is somewhat more complex, but also lacks reusable configuration objects
-"""
-
-
-DEFAULT_SLEEP_FUNC = time.sleep
-LOGGER = logging.getLogger(__name__)
-
-
-class RetryConf(object):
- """
- Configuration object defines retry behaviour and is composed of these fields:
- * `retriable` - function that decides if an exception should trigger retrying
- * `get_delay` - function that returns a number of seconds retrier must wait before doing the next attempt
- * `max_time` - maximum `datetime.timedelta` that can pass after the first call for any retry attempt to be done
- * `max_times` - maximum number of retry attempts (note retries, not tries/calls)
- * `handle_error` - function that is called for each failed call attempt
- * `logger` - logger object to record retry warnings with
- * `sleep` - custom sleep function to use for waiting
-
- >>> RetryConf(max_time=datetime.timedelta(seconds=30), max_times=10)
-
- Empty configuration retries indefinitely on any exceptions raised.
-
- By default `DEFAULT_CONF` if used, which retries indefinitely, waiting 1 sec with 1.2 backoff between attempts, and
- also logging with built-in logger object.
-
- Configuration must be cloned before modification to create separate configuration:
-
- >>> DEFAULT_CONF.clone()
-
- There are various methods that provide convenient clone-and-modify shortcuts and "retry recipes".
- """
-
- _PROPS = {
- "retriable": lambda e: True,
- "get_delay": lambda n, raised_after, last: 0,
- "max_time": None,
- "max_times": None,
- "handle_error": None,
- "logger": None,
- "sleep": DEFAULT_SLEEP_FUNC,
- }
-
- def __init__(self, **kwargs):
- for prop, default_value in self._PROPS.items():
- setattr(self, prop, default_value)
- self._set(**kwargs)
-
- def __repr__(self):
- return repr(self.__dict__)
-
- def clone(self, **kwargs):
- """
- Clone configuration.
- """
-
- obj = copy.copy(self)
- obj._set(**kwargs)
- return obj
-
- def on(self, *errors):
- """
- Clone and retry on specific exception types (retriable shortcut):
-
- >>> conf = conf.on(MyException, MyOtherException)
- """
-
- obj = self.clone()
- obj.retriable = lambda e: isinstance(e, errors)
- return obj
-
- def waiting(self, delay=0, backoff=1.0, jitter=0, limit=None):
- """
- Clone and wait between attempts with backoff, jitter and limit (get_delay shortcut):
-
- >>> conf = conf.waiting(delay)
- >>> conf = conf.waiting(delay, backoff=2.0) # initial delay with backoff x2 on each attempt
- >>> conf = conf.waiting(delay, jitter=3) # jitter from 0 to 3 seconds
- >>> conf = conf.waiting(delay, backoff=2.0, limit=60) # delay with backoff, but not greater than a minute
-
- All these options can be combined together, of course.
- """
-
- def get_delay(n, raised_after, last):
- if n == 1:
- return delay
-
- s = last * backoff
- s += random.uniform(0, jitter)
- if limit is not None:
- s = min(s, limit)
- return s
-
- obj = self.clone()
- obj.get_delay = get_delay
- return obj
-
- def upto(self, seconds=0, **other_timedelta_kwargs):
- """
- Clone and do retry attempts only for some time (max_time shortcut):
-
- >>> conf = conf.upto(30) # retrying for 30 seconds
- >>> conf = conf.upto(hours=1, minutes=20) # retrying for 1:20
-
- Any `datetime.timedelta` kwargs can be used here.
- """
-
- obj = self.clone()
- obj.max_time = datetime.timedelta(seconds=seconds, **other_timedelta_kwargs)
- return obj
-
- def upto_retries(self, retries=0):
- """
- Set limit for retry attempts number (max_times shortcut):
-
- >>> conf = conf.upto_retries(10)
- """
-
- obj = self.clone()
- obj.max_times = retries
- return obj
-
- def _set(self, **kwargs):
- for prop, value in kwargs.items():
- if prop not in self._PROPS:
- continue
- setattr(self, prop, value)
-
-
-DEFAULT_CONF = RetryConf(logger=LOGGER).waiting(1, backoff=1.2)
-
-
-def retry_call(f, f_args=(), f_kwargs={}, conf=DEFAULT_CONF, **kwargs):
- """
- Retry function call.
-
- :param f: function to be retried
- :param f_args: target function args
- :param f_kwargs: target function kwargs
- :param conf: configuration
- """
-
- if kwargs:
- conf = conf.clone(**kwargs)
- return _retry(conf, functools.partial(f, *f_args, **f_kwargs))
-
-
-def retry(conf=DEFAULT_CONF, **kwargs):
- """
- Retrying decorator.
-
- :param conf: configuration
- """
-
- if kwargs:
- conf = conf.clone(**kwargs)
-
- def decorator(f):
- @functools.wraps(f)
- def wrapped(*f_args, **f_kwargs):
- return _retry(conf, functools.partial(f, *f_args, **f_kwargs))
-
- return wrapped
-
- return decorator
-
-
-def retry_intrusive(f):
- """
- Retrying method decorator that uses an intrusive conf (obj.retry_conf).
- """
-
- @functools.wraps(f)
- def wrapped(obj, *f_args, **f_kwargs):
- assert hasattr(obj, "retry_conf"), "Object must have retry_conf attribute for decorator to run"
- return _retry(obj.retry_conf, functools.partial(f, obj, *f_args, **f_kwargs))
-
- return wrapped
-
-
-def _retry(conf, f):
- start = datetime.datetime.now()
- delay = 0
- for n in itertools.count(1):
- try:
- return f()
- except Exception as error:
- raised_after = datetime.datetime.now() - start
- if conf.handle_error:
- conf.handle_error(error, n, raised_after)
- delay = conf.get_delay(n, raised_after, delay)
- retry_after = raised_after + datetime.timedelta(seconds=delay)
- retrying = (
- conf.retriable(error)
- and (conf.max_times is None or n <= conf.max_times)
- and (conf.max_time is None or retry_after <= conf.max_time)
- )
- if not retrying:
- raise
- if delay:
- conf.sleep(delay)
- if conf.logger:
- conf.logger.warning(
- "Retrying (try %d) after %s (%s + %s sec) on %s: %s",
- n,
- retry_after,
- raised_after,
- delay,
- error.__class__.__name__,
- error,
- exc_info=True,
- )
diff --git a/library/python/retry/ya.make b/library/python/retry/ya.make
deleted file mode 100644
index dcbf5567cd..0000000000
--- a/library/python/retry/ya.make
+++ /dev/null
@@ -1,11 +0,0 @@
-PY23_LIBRARY()
-
-STYLE_PYTHON()
-
-PY_SRCS(__init__.py)
-
-END()
-
-RECURSE_FOR_TESTS(
- tests
-)
diff --git a/library/python/testing/yatest_common/ut/test.py b/library/python/testing/yatest_common/ut/test.py
deleted file mode 100644
index bffdf1e353..0000000000
--- a/library/python/testing/yatest_common/ut/test.py
+++ /dev/null
@@ -1,17 +0,0 @@
-import os
-import tarfile
-
-import yatest.common
-
-import yalibrary.tools
-
-
-def test_jdk_from_package_equals_jdk_tool_from_yaconf_json():
- jdk_path = yatest.common.binary_path(os.path.join('build', 'platform', 'java', 'jdk', 'testing'))
- os.makedirs("extracted")
- with tarfile.open(os.path.join(jdk_path, "jdk.tar")) as tf:
- tf.extractall("extracted")
- jdk_tool_path = yalibrary.tools.toolchain_root('java', None, None)
- with open(os.path.join("extracted", "release")) as jdk_path_release:
- with open(os.path.join(jdk_tool_path, "release")) as jdk_tool_path_release:
- assert jdk_path_release.read() == jdk_tool_path_release.read()
diff --git a/library/python/testing/yatest_common/ut/ya.make b/library/python/testing/yatest_common/ut/ya.make
deleted file mode 100644
index cc56fa1b6c..0000000000
--- a/library/python/testing/yatest_common/ut/ya.make
+++ /dev/null
@@ -1,17 +0,0 @@
-PY2TEST()
-
-TEST_SRCS(test.py)
-
-PEERDIR(
- devtools/ya/yalibrary/tools
-)
-
-DEPENDS(
- build/platform/java/jdk/testing
-)
-
-REQUIREMENTS(
- network:full
-)
-
-END()
diff --git a/library/python/testing/yatest_common/ya.make b/library/python/testing/yatest_common/ya.make
index 9798bb40bb..2f5aa3bf39 100644
--- a/library/python/testing/yatest_common/ya.make
+++ b/library/python/testing/yatest_common/ya.make
@@ -36,7 +36,3 @@ IF (NOT CATBOOST_OPENSOURCE)
ENDIF()
END()
-
-RECURSE(
- ut
-)